{"version":3,"file":"babylon.js","sources":["file:///home/vsts/work/1/s/packages/dev/core/src/Misc/symbolMetadataPolyfill.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/constants.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/abstractActionManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/observable.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.constants.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/arrayTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/performanceConfigurator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/engineStore.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.scalar.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/ThinMaths/thinMath.matrix.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/typeStore.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.vector.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.color.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/action.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/actionEvent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/condition.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/logger.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/directActions.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/deepCopier.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/devTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/actionManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/directAudioActions.pure.ts","file:///home/vsts/work/1/s/node_modules/tslib/tslib.es6.js","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animationRange.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/decorators.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/decorators.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/andOrNotEvaluator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/tags.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/decorators.serialization.ts","file:///home/vsts/work/1/s/packages/dev/core/src/node.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.size.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/webRequest.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animation.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Actions/interpolateValueAction.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/runtimeAnimation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/domManagement.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/precisionDate.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animatable.core.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Bones/bone.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/retryStrategy.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/error.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/stringTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/abstractEngine.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/shaderCodeNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/shaderCodeCursor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/shaderCodeConditionNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/shaderCodeTestNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/Expressions/shaderDefineExpression.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/Expressions/Operators/shaderDefineIsDefinedOperator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/Expressions/Operators/shaderDefineOrOperator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/Expressions/Operators/shaderDefineAndOperator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/Expressions/Operators/shaderDefineArithmeticOperator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/shaderProcessor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/timingTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/halfFloat.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Buffers/bufferUtils.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/fileTools.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/instantiationTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/guid.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/tools.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/tools.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/smartArray.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/stringDictionary.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/colorTemperature.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/colorCurves.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/colorCurves.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/imageProcessingConfiguration.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/imageProcessingConfiguration.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/uniformBuffer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Buffers/dataBuffer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/shaderStore.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGL/webGLPipelineContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/thinEngine.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/effect.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/effect.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/States/depthCullingState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/States/stencilStateComposer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/States/stencilState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/States/alphaCullingState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/textureSampler.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/internalTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/abstractEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/drawWrapper.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGL/webGLShaderProcessors.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGL/webGL2ShaderProcessors.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/WebGL/webGLDataBuffer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGL/webGLHardwareTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/textureHelper.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/thinEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.dynamicBuffer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Buffers/buffer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Collisions/pickingInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/postProcessManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/floatingOriginMatrixOverrides.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/renderingGroup.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/renderingManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/sceneComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Events/pointerEvents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Events/keyboardEvents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/InputDevices/deviceEnums.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Events/deviceInputEvents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/eventFactory.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/nativeDeviceInputSystem.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/webDeviceInputSystem.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/InputDevices/deviceSource.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/internalDeviceSourceManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/DeviceInput/InputDevices/deviceSourceManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Inputs/scene.inputManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/perfCounter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.plane.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.frustum.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/uniqueIdGenerator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/lightConstants.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Inputs/pointerPickingConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/scene.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animatable.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animationPropertiesOverride.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.path.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/easing.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animationEvent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animationGroup.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animationKey.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animationGroupMask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/transformNode.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/pathCursor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animation.optimizations.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/coroutine.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Collisions/intersectionInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/boundingBox.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/boundingSphere.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/boundingInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/drawWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/subMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/mesh.vertexData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Collisions/meshCollisionData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/abstractMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.axis.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/animatorAvatar.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Animations/rootMotion.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.viewport.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.renderPass.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/camera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Loading/sceneLoaderFlags.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Compat/compatibilityOptions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/geometry.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialStencilState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/clipPlaneMaterialHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialFlags.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialHelper.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/material.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialHelper.geometryrendering.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/multiMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshLODLevel.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/mesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/instancedMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/light.ts","file:///home/vsts/work/1/s/packages/dev/core/src/assetContainer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Audio/analyser.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/audioEngineV2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/abstractSpatialAudioListener.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/components/spatialAudioAttacherComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/spatialAudioListener.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/components/spatialWebAudioUpdaterComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/audioUtils.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/components/webAudioParameterComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subProperties/spatialWebAudioListener.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/abstractAudioNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/mainAudioOut.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioMainOut.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioUnmuteUI.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioEngine.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Audio/audioEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Audio/soundTrack.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Loading/Plugins/babylonFileParser.function.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Audio/audioSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/abstractSpatialAudio.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subNodes/abstractAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subNodes/volumeAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/abstractAudioAnalyzer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subNodes/audioAnalyzerSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/audioAnalyzer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/abstractAudioOutNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/abstractSoundSource.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/abstractStereoAudio.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subNodes/stereoAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/stereoAudio.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subNodes/spatialAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subNodes/spatialWebAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subNodes/stereoWebAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subNodes/abstractAudioSubGraph.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subNodes/volumeWebAudioSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subNodes/webAudioAnalyzerSubNode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subNodes/webAudioBaseSubGraph.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subNodes/webAudioBusAndSoundSubGraph.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/subProperties/spatialAudio.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/subProperties/spatialWebAudio.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioSoundSource.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/abstractSound.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/staticSound.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/staticSoundBuffer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/abstractSoundInstance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/staticSoundInstance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioStaticSound.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/streamingSound.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/streamingSoundInstance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioStreamingSound.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Audio/sound.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Audio/weightedsound.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/abstractAudioBus.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/audioBus.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/abstractAudio/mainAudioBus.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/audioParameter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/soundState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/spatialAudioAttachmentType.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioBus.ts","file:///home/vsts/work/1/s/packages/dev/core/src/AudioV2/webAudio/webAudioMainBus.ts","file:///home/vsts/work/1/s/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/thinTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/baseTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/copyTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/texture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/rawTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Bones/skeleton.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.texture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/objectRenderer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/renderTargetTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/effectRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/postProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinPassPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/passPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/textureTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/BakedVertexAnimation/vertexAnimationBaker.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Cameras/autoRotationBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Cameras/bouncingBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Cameras/framingBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Cameras/interpolatingBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Cameras/geospatialClippingBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/attachToBoxBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/fadeInOutBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/ray.core.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/ray.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/pivotTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/planeBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRFeatureWarningRegistry.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/pointerDragBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/multiPointerScaleBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/baseSixDofDragBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/sixDofDragBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/surfaceMagnetismBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/followBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRFeaturesManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Behaviors/Meshes/handConstraintBehavior.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Bones/boneIKController.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Bones/boneLookController.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/ribbonBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/discBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/groundMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/groundBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/boxBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/tiledPlaneBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/tiledBoxBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/sphereBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/cylinderBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/torusBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/torusKnotBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/effectFallbacks.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/pushMaterial.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/vertexPullingHelper.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/shaderMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/linesMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/linesBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/polygonMesh.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/polygonBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/shapeBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/latheBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/tubeBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/polyhedronBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/icoSphereBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/decalBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/capsuleBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.isovector.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/geodesicMesh.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/geodesicBuilder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/goldbergMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/goldbergBuilder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/textBuilder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Bones/skeleton.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Buffers/storageBuffer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Buffers/buffer.align.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/BaseCameraMouseWheelInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/BaseCameraPointersInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/cameraInputsManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gamepads/gamepad.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/arcRotateCameraGamepadInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/arcRotateCameraMouseWheelInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/orbitCameraPointersInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/arcRotateCameraPointersInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/arcRotateCameraInputsManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/flyCameraKeyboardInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/flyCameraMouseInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/followCameraKeyboardMoveInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/followCameraMouseWheelInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/followCameraPointersInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraKeyboardMoveInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraMouseInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraMouseWheelInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraTouchInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/freeCameraInputsManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraDeviceOrientationInput.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraGamepadInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/virtualJoystick.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/freeCameraVirtualJoystickInput.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.vector.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/geospatialCameraPointersInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/geospatialCameraMouseWheelInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Inputs/geospatialCameraKeyboardInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/cameraMovement.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/inputMapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/targetCameraMovement.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/targetCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/freeCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/touchCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/arcRotateCameraMovement.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/arcRotateCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/deviceOrientationCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/flyCameraInputsManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/flyCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/followCameraInputsManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/followCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/universalCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/gamepadCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinAnaglyphPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/anaglyphPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/RigModes/stereoscopicAnaglyphRigMode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/anaglyphArcRotateCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/anaglyphFreeCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/anaglyphGamepadCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/anaglyphUniversalCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/stereoscopicInterlacePostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/RigModes/stereoscopicRigMode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/stereoscopicArcRotateCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/stereoscopicFreeCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/stereoscopicGamepadCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/stereoscopicUniversalCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Stereoscopic/stereoscopicScreenUniversalCamera.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/virtualJoysticksCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/VR/vrCameraMetrics.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/vrDistortionCorrectionPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/MultiviewRenderTarget.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/performanceMonitor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/engine.common.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.dom.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/engine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.multiview.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/vrMultiviewToSingleviewPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/RigModes/vrRigMode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/VR/vrDeviceOrientationArcRotateCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/VR/vrDeviceOrientationFreeCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/VR/vrDeviceOrientationGamepadCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/prePassConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialDefines.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/imageProcessingConfiguration.defines.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialPluginManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialPluginBase.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/material.detailMapConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/shaderImportLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/uv.defines.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/prepass.defines.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/imageProcessing.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/standardMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.dynamicTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/dynamicTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRLayerWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRRenderTargetTextureProvider.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRWebGLRenderTargetTextureProvider.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRWebGLLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRManagedOutputCanvas.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/native/nativeXRRenderTarget.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRGraphicsBinding.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRSessionManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gamepads/xboxGamepad.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gamepads/dualShockGamepad.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gamepads/gamepadSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gamepads/gamepadManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/VR/vrExperienceHelper.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/geospatialCameraInputsManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/Limits/geospatialLimits.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/geospatialCameraMovement.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Cameras/geospatialCamera.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Collisions/collider.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Collisions/collisionCoordinator.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.multiRender.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/multiRenderTarget.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/shadowDepthWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplatting.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Collisions/gpuPicker.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/packingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/picking.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bonesDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bakedVertexAnimationDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/instancesDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertexGlobal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/instancesVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bonesVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bakedVertexAnimation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/picking.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/packingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/picking.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bonesDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bakedVertexAnimationDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/instancesDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertexGlobal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/morphTargetsVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/instancesVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bonesVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bakedVertexAnimation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/picking.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Compute/computeEffect.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuPerfCounter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Compute/computeShader.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/Helper/boundingInfoHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/Helper/transformFeedbackBoundingHelper.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gpuTransform.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gpuTransform.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/Helper/computeShaderBoundingHelper.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/boundingInfo.compute.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/Octrees/octreeBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/Octrees/octree.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Culling/Octrees/octreeSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/hemisphericLight.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/utilityLayerRenderer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/gizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/debugLayer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/axisDragGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/axesViewer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/boneAxesViewer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/physicsJoint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/physicsImpostor.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/physicsViewer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/physicsEngine.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/castingResult.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/physicsRaycastResult.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsEngine.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/joinedPhysicsEngineComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/rayHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/skeletonViewer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphUtils.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Debug/directionalLightFrustumViewer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/codeStringParsingTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Processors/shaderCodeInliner.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativeShaderProcessors.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativeDataStream.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativePipelineContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/renderTargetWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativeRenderTargetWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativeHardwareTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativeHelpers.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Buffers/buffer.nonFloatVertexBuffers.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/nativeShaderProcessingContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Instrumentation/timeToken.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/thinNativeEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.alpha.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.alphaToCoverage.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.rawTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.readTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.cubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGL/webGLRenderTargetWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.renderTarget.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.renderTargetTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.renderTargetCube.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.vertexFormat.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/sphericalPolynomial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.prefilteredCubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.uniformBuffer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.loadingScreen.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.states.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.stencil.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.loadFile.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/textureLoaderManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.textureLoaders.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/thinEngine.scissor.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/nullEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/urlTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.cubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.timeQuery.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.query.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.alpha.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.views.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/AbstractEngine/abstractEngine.textureSelector.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.debugging.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.query.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.transformFeedback.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.videoTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.texture2DArrayImageSource.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Extensions/engine.computeShader.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/validatedNativeDataStream.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/rgbdTextureTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/dumpTools.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/environmentTextureTools.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/Native/Extensions/nativeEngine.cubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuTextureHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/thinWebGPUEngine.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuConstants.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuHardwareTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuTextureManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuCacheRenderPipeline.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.alpha.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuComputeContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuComputePipelineContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuShaderProcessor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuPipelineContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuShaderProcessingContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuShaderProcessorsGLSL.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/WebGPU/webgpuDataBuffer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuBufferManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuCacheSampler.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuCacheRenderPipelineTree.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuStencilStateComposer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuDepthCullingState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/externalTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuMaterialContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuDrawContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuCacheBindGroups.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuCacheTextureView.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuClearQuad.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuBundleList.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuQuerySet.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuTimestampQuery.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuOcclusionQuery.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuTintWASM.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuSnapshotRendering.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuExternalTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/webgpuEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.computeShader.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.cubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.debugging.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.dynamicTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.multiRender.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.query.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.rawTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.readTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/webgpuRenderTargetWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.renderTarget.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.renderTargetCube.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.renderTargetTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/WebGPU/Extensions/engine.videoTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/clearQuad.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/clearQuad.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/helperFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/fresnelFunction.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/meshUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/sceneUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/decalFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/nativeEngine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Engines/engineFactory.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Events/clipboardEvents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/CustomTypes/flowGraphInteger.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/CustomTypes/flowGraphMatrix.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/serialization.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphAssetsContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphLogger.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphConnection.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphDataConnection.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphSignalConnection.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphExecutionBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphExecutionBlockWithOutSignal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphAsyncExecutionBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/utils.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphSceneEventCoordinator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphEventBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphValidator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraph.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphRichTypes.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphHostResolver.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphCoordinator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/flowGraphBlockFactory.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphParser.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphPathConverter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphPathConverterComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphDelayRegistry.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphBranchBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphDoNBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphThrottleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphMultiGateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSwitchBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphWaitAllBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCounterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphWhileLoopBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphDebounceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphFlipFlopBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSequenceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/timer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphPauseAnimationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphInterpolationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphEasingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Physics/flowGraphApplyForceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Physics/flowGraphApplyImpulseBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Physics/flowGraphSetLinearVelocityBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Physics/flowGraphSetAngularVelocityBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Physics/flowGraphSetPhysicsMotionTypeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Audio/flowGraphPlaySoundBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Audio/flowGraphStopSoundBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Audio/flowGraphPauseSoundBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/Audio/flowGraphSetSoundVolumeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphConditionalDataBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphGetVariableBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/flowGraphSetVariableBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphTransformCoordinatesSystemBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphGetPropertyBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Execution/flowGraphSetPropertyBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphConstantBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphGetAssetBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphDataSwitchBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphIsKeyPressedBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphBinaryOperationBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphConstantOperationBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphUnaryOperationBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphTernaryOperationBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/flowGraphMath.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Transformers/flowGraphTypeToTypeBlocks.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Utils/flowGraphContextBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Utils/flowGraphCodeExecutionBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Utils/flowGraphIndexOfBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Utils/flowGraphFunctionReferenceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Physics/flowGraphGetLinearVelocityBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Physics/flowGraphGetAngularVelocityBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Physics/flowGraphGetPhysicsMassPropertiesBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Audio/flowGraphGetSoundVolumeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/Audio/flowGraphIsSoundPlayingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphSendCustomEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphPointerOutEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphPointerOverEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphPhysicsCollisionEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphSoundEndedEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphKeyboardEventBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphKeyDownEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphKeyUpEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/flowGraphBlockNames.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Types/nodeRenderGraphTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBlockConnectionPoint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Passes/pass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Passes/objectListPass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Passes/renderPass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Texture/copyToBackbufferColorTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/outputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/copyTextureToTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphRenderContext.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/textureCreationOptions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphRenderTarget.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphTextureManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraph.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Decorators/nodeDecorator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/inputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphTaskMultiRenderTarget.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Texture/clearTextureTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Textures/clearBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphConnectionPointCustomObject.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/thinDepthPeelingRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/objectRendererTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/baseObjectRendererBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/objectRendererBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/nodeRenderGraphBuildState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Misc/cullObjectsTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/cullObjectsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Misc/computeShaderTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/computeShaderBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/elbowBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Misc/executeTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/executeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/shadowLight.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/directionalLight.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/lightingVolume.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Misc/lightingVolumeTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/lightingVolumeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/resourceContainerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/thinEffectLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinBlurPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/thinGlowLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/postProcessTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/blurTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Layers/baseLayerTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Layers/glowLayerTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Layers/glowLayerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/thinHighlightLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Layers/highlightLayerTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Layers/highlightLayerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/thinSelectionOutlineLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Layers/selectionOutlineTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Layers/selectionOutlineLayerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/anaglyphTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/basePostProcessBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/baseWithPropertiesPostProcessBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/anaglyphPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinBlackAndWhitePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/blackAndWhiteTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/blackAndWhitePostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinBloomMergePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/bloomMergeTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinExtractHighlightsPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinBloomEffect.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/extractHighlightsTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/bloomTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/bloomPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/blurPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinChromaticAberrationPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/chromaticAberrationTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/chromaticAberrationPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinCircleOfConfusionPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/circleOfConfusionTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/circleOfConfusionPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinColorCorrectionPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/colorCorrectionPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinConvolutionPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/convolutionTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/convolutionPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinDepthOfFieldBlurPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinDepthOfFieldMergePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinDepthOfFieldEffect.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/depthOfFieldMergeTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/depthOfFieldBlurTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/depthOfFieldTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/depthOfFieldPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/extractHighlightsPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinFilterPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/filterTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/filterPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinFXAAPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/fxaaTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/fxaaPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinGrainPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/grainTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/grainPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinImageProcessingPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/imageProcessingTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/imageProcessingPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinMotionBlurPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/motionBlurTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/motionBlurPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshBlendingTag.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/meshBlendingBlueNoise.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinMeshBlendingPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/meshBlendingTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/meshBlendingPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/passTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/passPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSharpenPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/sharpenTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/sharpenPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinScreenSpaceCurvaturePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/screenSpaceCurvatureTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/screenSpaceCurvaturePostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSSAO2PostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSSAO2BlurPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSSAO2CombinePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/thinSSAO2RenderingPipeline.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssao2Task.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssao2BlurTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssao2RenderingPipelineTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/ssao2PostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSSRPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSSRBlurPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinSSRBlurCombinerPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/thinSSRRenderingPipeline.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssrTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssrBlurTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssrRenderingPipelineTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/ssrPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/halton2DSequence.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/taaMaterialManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinTAAPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/taaTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/taaPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinTonemapPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/tonemapTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/tonemapPostProcessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/PostProcesses/volumetricLightingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/blurPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/Shadows/shadowGeneratorSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/baseShadowGeneratorBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/depthRendererSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/depthRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/thinMinMaxReducer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/minMaxReducer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/depthReducer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/Shadows/cascadedShadowGenerator.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/shadowGeneratorTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/csmShadowGeneratorTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/csmShadowGeneratorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/geometryRendererTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/geometryRendererBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/brdfTextureTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrClearCoatConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrAnisotropicConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrSheenConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/geometryBufferRendererSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/geometryBufferRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/environmentLighting.defines.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsMaterialCompatibility.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinCustomPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Procedurals/proceduralTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/cubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/iblCdfGeneratorSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/iblCdfGenerator.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/shadowGeneratorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Rendering/utilityLayerRendererTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Rendering/utilityLayerRendererBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Teleport/teleportInBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Teleport/teleportOutBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Texture/copyToTextureTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Textures/copyTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/Texture/generateMipMapsTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Node/Blocks/Textures/generateMipmapsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/customPostProcessTask.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FrameGraph/frameGraphObjectList.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/axisScaleGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/boundingBoxGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/planeRotationGizmo.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/rotationGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/planeDragGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/positionGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/scaleGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/gizmoManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/hemisphereBuilder.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/spotLight.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/lightGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/cameraGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Gizmos/spatialAudioGizmo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/mirrorTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Background/backgroundMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Helpers/environmentHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Helpers/textureDome.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Helpers/photoDome.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRCamera.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRExperienceHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRControllerComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Loading/sceneLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/webRequest.fetch.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRAbstractMotionController.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRProfiledMotionController.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRGenericMotionController.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRMotionControllerManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRInputSource.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRAbstractFeature.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRControllerPointerSelection.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Enums/nodeMaterialBlockTargets.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterialBuildState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterialBuildStateSharedData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterialBlockConnectionPoint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterialBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Enums/nodeMaterialModes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Enums/nodeMaterialSystemValues.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Input/animatedInputBlockTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Input/inputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/screenSizeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/smartFilterFragmentOutputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/transformBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Vertex/vertexOutputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/currentScreenBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Particle/particleTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Particle/particleRampGradientBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Particle/particleBlendMultiplyBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/vectorMergerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/remapBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/baseMathBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/multiplyBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/gradients.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/boxParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/pointParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/hemisphericParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/sphereParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/cylinderParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/coneParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/meshParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/baseParticleSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/particleSystem.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/colorSplitterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/trigonometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRNearInteraction.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXREnterExitUI.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRControllerTeleportation.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/IPhysicsEnginePlugin.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRHandTracking.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsBody.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsShape.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsAggregate.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRDefaultExperience.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Helpers/sceneHelpers.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/videoTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Helpers/videoDome.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Helpers/materialConversionHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Instrumentation/engineInstrumentation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Instrumentation/sceneInstrumentation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/effectLayerSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/effectLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/glowLayer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/highlightLayer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/layerSceneComponent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Layers/layer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/helperFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clipPlaneFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/glowMapGeneration.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clipPlaneVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/glowMapGeneration.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/clipPlaneFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/clipPlaneFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/glowMapGeneration.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/clipPlaneVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/clipPlaneVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/glowMapGeneration.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/glowMapMerge.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/glowMapMerge.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/glowBlurPostProcess.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/glowMapMerge.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/glowMapMerge.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/glowBlurPostProcess.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/layer.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/layer.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/layer.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/layer.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/LensFlares/lensFlare.ts","file:///home/vsts/work/1/s/packages/dev/core/src/LensFlares/lensFlareSystemSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/LensFlares/lensFlareSystem.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lensFlare.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lensFlare.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lensFlare.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lensFlare.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bayerDitherFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowMapFragmentExtraDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowMapFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/shadowMap.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowMapVertexExtraDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowMapVertexNormalBias.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowMapVertexMetric.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/shadowMap.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/depthBoxBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowMapFragmentSoftTransparentShadow.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bayerDitherFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapFragmentExtraDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/shadowMap.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/sceneVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/meshVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/sceneUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/meshUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapVertexExtraDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapVertexNormalBias.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapVertexMetric.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/shadowMap.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/depthBoxBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowMapFragmentSoftTransparentShadow.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/pointLight.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/areaLight.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/LTC/ltcTextureTool.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/rectAreaLight.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/Clustered/clusteredLightingSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/thinInstanceMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/Clustered/clusteredLightContainer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lightProxy.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clusteredLightingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lightProxy.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lightProxy.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/clusteredLightingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lightProxy.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Lights/IES/iesLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lightingVolume.compute.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Loading/loadingScreen.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Filtering/hdrFiltering.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Filtering/hdrIrradianceFiltering.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/envCubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/HighDynamicRange/panoramaToCubemap.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/HighDynamicRange/hdr.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/hdrCubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Morph/morphTarget.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/rawTexture2DArray.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Morph/morphTargetManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Probes/reflectionProbe.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/thinSprite.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/sprite.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/spriteSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/spriteRenderer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/spriteManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/Plugins/cannonJSPlugin.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/Plugins/oimoJSPlugin.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/Plugins/ammoJSPlugin.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Loading/Plugins/babylonFileLoader.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/backgroundUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/fogVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/lightVxUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/logDepthDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/fogVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowsVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/logDepthVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/background.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/reflectionFunction.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/imageProcessingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/lightUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/ltcHelperFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/clusteredLightingCompute.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/lightsFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/shadowsFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/imageProcessingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/fogFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/intersectionFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/lightFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/logDepthFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/fogFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/background.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/backgroundVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/backgroundUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/fogVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lightVxFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lightVxUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/logDepthDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/fogVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowsVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/logDepthVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/background.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/backgroundFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/reflectionFunction.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lightFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lightUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/ltcHelperFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lightsFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/shadowsFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/fogFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/intersectionFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lightFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/logDepthFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/fogFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/background.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/fresnelParameters.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Occlusion/occlusionMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/color.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/vertexColorMixing.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/color.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/baseTexture.polynomial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrBaseSimpleMaterial.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/uvAttributeDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/mainUVVaryingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBRDFFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/prePassVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/samplerVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/harmonicsFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bumpVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/vertexPullingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/vertexPullingVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/prePassVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/uvVariableDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/samplerVertexImplementation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bumpVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/vertexColorMixing.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/pbr.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/objectIdFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/prePassDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/oitDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrFragmentExtraDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/samplerFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/samplerFragmentAlternateDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrFragmentReflectionDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrFragmentSamplersDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/textureRepetitionFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/subSurfaceScatteringFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/importanceSampling.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrHelperFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrDirectLightingSetupFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrDirectLightingFalloffFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/hdrFilteringFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockReflectance0.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrClusteredLightingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrDirectLightingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrIBLFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bumpFragmentMainFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bumpFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockAlbedoOpacity.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockReflectivity.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockAmbientOcclusion.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockAlphaFresnel.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockAnisotropic.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockReflection.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockSheen.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockClearcoat.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockIridescence.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockSubSurface.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockNormalGeometric.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/bumpFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockNormalFinal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/depthPrePass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockLightmapInit.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockGeometryInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockReflectance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockDirectLighting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockFinalLitComponents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockFinalUnlitComponents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockFinalColorComposition.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockImageProcessing.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/meshBlendTagFragmentOutput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockPrePass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/oitFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrDebug.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/pbr.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/decalVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/uvAttributeDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/mainUVVaryingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBRDFFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/prePassVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/samplerVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/harmonicsFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bumpVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/prePassVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/uvVariableDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/samplerVertexImplementation.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bumpVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/pbr.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/objectIdFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/prePassDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/oitDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/decalFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentExtraDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/samplerFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/samplerFragmentAlternateDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentReflectionDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/textureRepetitionFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/subSurfaceScatteringFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/importanceSampling.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrHelperFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrDirectLightingSetupFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrDirectLightingFalloffFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/hdrFilteringFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrDirectLightingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrIBLFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bumpFragmentMainFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bumpFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/decalFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockAlbedoOpacity.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockReflectivity.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockAmbientOcclusion.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockAlphaFresnel.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockAnisotropic.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockReflection.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockSheen.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockClearcoat.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockIridescence.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockSubSurface.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockReflectance0.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrClusteredLightingFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockNormalGeometric.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/bumpFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockNormalFinal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/depthPrePass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockLightmapInit.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockGeometryInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockReflectance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockDirectLighting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockFinalLitComponents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockFinalUnlitComponents.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockFinalColorComposition.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockImageProcessing.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockPrePass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/oitFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pbrDebug.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/pbr.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrNormalMapVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrNormalMapVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/openpbr.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrFragmentSamplersDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrNormalMapFragmentMainFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrNormalMapFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrDielectricReflectance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrConductorReflectance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrAmbientOcclusionFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrGeometryInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrIblFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrVolumeFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrNormalMapFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrBlockNormalFinal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrBaseLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrTransmissionLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrSubsurfaceLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrCoatLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrThinFilmLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrFuzzLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrAmbientOcclusionData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrBackgroundTransmission.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrDirectLightingInit.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrDirectLighting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrBlockPrePass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/openpbr.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/openpbr.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/sceneFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrFragmentSamplersDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapFragmentMainFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapFragmentFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrDielectricReflectance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrConductorReflectance.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrAmbientOcclusionFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrGeometryInfo.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrIblFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrVolumeFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrBlockNormalFinal.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrBaseLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrTransmissionLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrSubsurfaceLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrCoatLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrThinFilmLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrFuzzLayerData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrAmbientOcclusionData.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrBackgroundTransmission.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrEnvironmentLighting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrDirectLightingInit.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrDirectLighting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/openpbrBlockPrePass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/openpbr.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/shaderLanguage.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/colorGradingTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/equiRectangularCubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.interfaces.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.core.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.header.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.compression.huf.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.compression.rle.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.compression.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.configuration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.decoder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/exrTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/exrCubeTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/htmlElementTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/HTML/htmlTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/HTML/htmlInteractionManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/HTML/htmlRaycastInteractionManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/HTML/htmlInCanvasPolyfill.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/dds.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/ddsTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/envTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/ktx2decoderTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/khronosTextureContainer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/workerPool.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/khronosTextureContainer2Worker.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/khronosTextureContainer2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/ktxTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/tga.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/tgaTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/hdrTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/basis.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/basisWorker.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/basisTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Loaders/iesTextureLoader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Packer/frame.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Packer/packer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Procedurals/customProceduralTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/Procedurals/noiseProceduralTexture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/rawCubeTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/rawTexture3D.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/refractionTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/textureMerger.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/textureProcessor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/thinRenderTargetTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/procedural.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/procedural.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/hdrFiltering.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/hdrFiltering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/hdrFiltering.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/hdrFiltering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/hdrIrradianceFiltering.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/hdrIrradianceFiltering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/hdrIrradianceFiltering.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/hdrIrradianceFiltering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Enums/nodeMaterialBlockConnectionPointMode.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterialConnectionPointCustomObject.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/GaussianSplatting/gaussianBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/GaussianSplatting/splatReaderBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/imageSourceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/smartFilterTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/addBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/nodeMaterialDefault.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Vertex/bonesBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Vertex/instancesBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Vertex/lightInformationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/imageProcessingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/TBNBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/discardBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/frontFacingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/derivativeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/fragCoordBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/screenSpaceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/twirlBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/heightToNormalBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/fragDepthBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/shadowMapBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/prePassOutputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/fogBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/lightBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/textureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/reflectionTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/sceneDepthBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/depthSourceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Dual/clipPlanesBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Input/prePassTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Teleport/teleportInBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/Teleport/teleportOutBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/scaleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/clampBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/crossBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/customBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/dotBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/normalizeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/colorMergerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/vectorSplitterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/lerpBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/divideBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/subtractBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/stepBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/oneMinusBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/viewDirectionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/fresnelBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/maxBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/minBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/distanceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/lengthBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/negateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/powBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/randomNumberBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/arcTan2Block.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/smoothStepBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/reciprocalBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/replaceColorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/posterizeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/waveBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/gradientBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/nLerpBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/worleyNoise3DBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/simplexPerlin3DBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/normalBlendBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/rotate2dBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/reflectBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/refractBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/desaturateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/sheenBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/reflectionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/iridescenceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/refractionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/subSurfaceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/modBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/matrixBuilderBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/conditionalBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/cloudBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/voronoiNoiseBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/elbowBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/triPlanarBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/biPlanarBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/matrixDeterminantBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/matrixTransposeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/meshAttributeExistsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/curveBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/colorConverterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/loopBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/storageReadBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/storageWriteBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/matrixSplitterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/gaussianSplatting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/gaussianSplatting.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/gaussianSplattingFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/gaussianSplattingFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/debugBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Blocks/pannerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Node/Optimizers/nodeMaterialOptimizer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/postprocess.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/postprocess.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialPluginEvent.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/ditheredTileFadeMaterialPlugin.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/material.decalMapConfiguration.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/materialPluginFactoryExport.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GreasedLine/greasedLineMaterialDefaults.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/greasedLineTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GreasedLine/greasedLinePluginMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GreasedLine/greasedLinePluginMaterialShadersGLSL.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GreasedLine/greasedLinePluginMaterialShadersWGSL.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GreasedLine/greasedLineSimpleMaterial.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GreasedLine/greasedLineMaterialInterfaces.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gaussianSplattingDepth.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/gaussianSplattingUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gaussianSplattingDepth.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gaussianSplattingDepth.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gaussianSplattingDepth.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/defaultFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/defaultUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/fresnelFunction.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/defaultFragmentAlpha.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/default.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/defaultVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pointCloudVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/default.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/defaultUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/defaultFragmentAlpha.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/default.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/lightVxFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/default.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/greasedLine.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/greasedLine.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/greasedLine.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/greasedLine.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingCompatibility.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/imageProcessingCompatibility.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/standardMaterial.decalMap.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/PBR/pbrMaterial.decalMap.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/abstractMesh.decalMap.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.scalar.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.polar.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/ThinMaths/thinMath.matrix.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Maths/math.geospatial.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/abstractMesh.hotSpot.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Compression/dracoCompressionWorker.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Compression/dracoCodec.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Compression/dracoDecoder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Compression/dracoCompression.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Compression/meshoptCompression.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/deepMerger.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Compression/dracoEncoder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/csg.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshUVSpaceRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/trailMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshSimplificationSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshSimplification.common.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshSimplification.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/meshUtils.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/subMesh.project.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/lattice.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/lattice.material.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GreasedLine/greasedLineBaseMesh.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GreasedLine/greasedLineMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GreasedLine/greasedLineRibbonMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Builders/greasedLineBuilder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/tools.internals.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/csg2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/bitArray.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/mesh.vertexData.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/mesh.vertexData.subdivide.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Enums/nodeGeometryConnectionPointTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/nodeGeometryBlockConnectionPoint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/nodeGeometryBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryOutputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Enums/nodeGeometryContextualSources.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/nodeGeometryBuildState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryInputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/boxBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/nodeGeometry.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryOptimizeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/planeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/meshBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/icoSphereBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/sphereBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/gridBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/torusBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/cylinderBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/capsuleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/discBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/nullBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Sources/pointListBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/setPositionsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/setNormalsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/setUVsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/setColorsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/setTangentsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/mathBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/mapRangeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/conditionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/randomBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/noiseBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/mergeGeometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryCollectionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/cleanGeometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryElbowBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/computeNormalsBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/vectorConverterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/normalizeVectorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/setMaterialIDBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/latticeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryTrigonometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryTransformBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Matrices/rotationXBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Matrices/rotationYBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Matrices/rotationZBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Matrices/scalingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Matrices/alignBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Matrices/translationBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateBaseBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateLinearBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Instances/instantiateRadialBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/intFloatConverterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/debugBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryInfoBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/mappingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/matrixComposeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Teleport/teleportInBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Teleport/teleportOutBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Textures/geometryTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Textures/geometryTextureFetchBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/boundingBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/booleanGeometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryArcTan2Block.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryLerpBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryNLerpBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryStepBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometrySmoothStepBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryModBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryPowBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryClampBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryCrossBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryCurveBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryDesaturateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryPosterizeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryReplaceColorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryDistanceBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryDotBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryLengthBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryRotate2dBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryInterceptorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/geometryEaseBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/Set/aggregatorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/subdivideBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/extrudeGeometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/Node/Blocks/bevelBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingSortWorker.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingCompoundMesh.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/color.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/color.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshUVSpaceRenderer.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshUVSpaceRenderer.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshUVSpaceRendererMasker.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshUVSpaceRendererMasker.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshUVSpaceRendererFinaliser.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshUVSpaceRendererFinaliser.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshUVSpaceRenderer.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshUVSpaceRenderer.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshUVSpaceRendererMasker.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshUVSpaceRendererMasker.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshUVSpaceRendererFinaliser.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshUVSpaceRendererFinaliser.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/assetsManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/deferred.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/meshExploder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/filesInput.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/observable.extensions.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/sceneOptimizer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/sceneSerializer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lodCube.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lod.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lodCube.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lod.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/videoRecorder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/fxaaPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/screenshotTools.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/iInspectable.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/dataReader.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/minmaxRedux.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/minmaxRedux.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/subEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/dataStorage.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/particle.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/thinParticleSystem.function.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Queue/executionQueue.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/thinParticleSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/EmitterTypes/customParticleEmitter.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/attractor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/particleSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/sceneRecorder.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/trajectoryClassifier.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/reflector.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/pressureObserverWrapper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/PerformanceViewer/dynamicFloat32Array.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/PerformanceViewer/performanceViewerCollector.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/PerformanceViewer/performanceViewerCollectionStrategies.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/PerformanceViewer/performanceViewerSceneExtension.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/snapshotRenderingHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/observableCoroutine.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/areaLightsTextureTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/equirectangularCapture.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/equirectangularPanorama.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/asyncLock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Misc/lazy.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/rgbdDecode.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/rgbdEncode.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/rgbdDecode.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/rgbdEncode.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/copyTextureToTexture.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/copyTextureToTexture.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/areaLightTextureProcessing.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/areaLightTextureProcessing.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Navigation/Plugins/recastJSPlugin.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Offline/database.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/uniformBufferEffectCommonAccessor.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/webgl2ParticleSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gpuUpdateParticles.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gpuUpdateParticles.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/computeShaderParticleSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gpuUpdateParticles.compute.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/gpuParticleSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clipPlaneFragmentDeclaration2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/geometryRenderingFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gpuRenderParticles.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/clipPlaneVertexDeclaration2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gpuRenderParticles.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/particleSystemSet.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/particleHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/particleSystemComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/solidParticle.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/solidParticleSystem.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/cloudPoint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/pointsCloudSystem.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/flowMap.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/nodeParticleBlockConnectionPoint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/nodeParticleBlock.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Enums/nodeParticleContextualSources.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Enums/nodeParticleSystemSources.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/nodeParticleBuildState.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Triggers/triggerTools.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/systemBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleInputBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleSourceTextureBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updatePositionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleMathBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/emitters.functions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/boxShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/createParticleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/nodeParticleSystemSet.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleConverterBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleFloatToIntBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleGradientBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleGradientValueBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleRandomBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleLerpBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleVectorLengthBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Conditions/particleConditionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/coneShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/cylinderShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/customShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/meshShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/pointShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/setupSpriteSheetBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Emitters/sphereShapeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateAngleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/basicSpriteUpdateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateAttractorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateColorBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateDirectionBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateFlowMapBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateNoiseBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateSizeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/nodeParticleSystemSet.helper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateScaleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateAgeBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/basicPositionUpdateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/basicColorUpdateBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/updateSpriteCellIndexBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Update/alignAngleBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleTrigonometryBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleDebugBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleElbowBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Teleport/particleTeleportInBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Teleport/particleTeleportOutBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/Triggers/particleTriggerBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleLocalVariableBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleNumberMathBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleVectorMathBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleClampBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleNLerpBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleSmoothStepBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Particles/Node/Blocks/particleStepBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/particles.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/particles.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/geometryRenderingFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/particles.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/particles.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v1/physicsEngineComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsConstraint.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsMaterial.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/characterController.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/ragdoll.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/Plugins/havokPlugin.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/v2/physicsEngineComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/physicsHelper.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/proximityCastResult.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Physics/shapeCastResult.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/blackAndWhitePostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/postProcessRenderEffect.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/extractHighlightsPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/bloomMergePostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/bloomEffect.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/chromaticAberrationPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/colorCorrectionPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/convolutionPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/displayPassPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/filterPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/grainPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/highlightsPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/imageProcessingPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/motionBlurConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/motionBlurPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/meshBlendingPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/refractionPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/refraction.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/sharpenPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/postProcessRenderPipelineManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/postProcessRenderPipeline.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/chromaticAberration.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lensHighlights.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/depthOfField.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/ssao2Configuration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Materials/Textures/prePassRenderTarget.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/prePassRendererSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/prePassRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ssao.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ssaoCombine.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/screenSpaceReflectionsConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/screenSpaceReflectionPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/standard.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/screenSpaceReflections2Configuration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinFSR1UpscalePostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/thinFSR1SharpenPostProcess.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/fsr1RenderingPipeline.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ssao2.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ssao2.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ssaoCombine.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/screenSpaceRayTrace.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/screenSpaceReflection2.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/screenSpaceReflection2Blur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/screenSpaceReflection2BlurCombiner.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/screenSpaceRayTrace.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/screenSpaceReflection2.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/screenSpaceReflection2Blur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/screenSpaceReflection2BlurCombiner.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/taa.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/taa.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/ffxFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fsr1Upscale.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fsr1Sharpen.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/ffxFunctions.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fsr1Upscale.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fsr1Sharpen.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/sharpen.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/stereoscopicInterlace.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/tonemapPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/volumetricLightScatteringPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/pointCloudVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/depth.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/volumetricLightScattering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/volumetricLightScatteringPass.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/volumetricLightScatteringPass.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/volumetricLightScattering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/volumetricLightScatteringPass.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/volumetricLightScatteringPass.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/vrMultiviewToSingleview.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/screenSpaceReflection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/screenSpaceCurvaturePostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/screenSpaceCurvature.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/kernelBlurVaryingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/kernelBlurFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/kernelBlurFragment2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/kernelBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/kernelBlurVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/kernelBlur.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/kernelBlurVaryingDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/kernelBlurFragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/kernelBlurFragment2.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/kernelBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/kernelBlurVertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/kernelBlur.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/pass.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/passCube.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/pass.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/passCube.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/vrDistortionCorrection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/vrDistortionCorrection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/imageProcessing.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/imageProcessing.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/sharpen.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/grain.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/grain.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/chromaticAberration.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/depthOfFieldMerge.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/depthOfFieldMerge.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/circleOfConfusion.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/circleOfConfusion.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/bloomMerge.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/bloomMerge.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/extractHighlights.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/extractHighlights.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fxaa.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fxaa.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fxaa.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fxaa.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/blackAndWhite.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/blackAndWhite.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/anaglyph.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/anaglyph.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/convolution.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/convolution.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/colorCorrection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/colorCorrection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/motionBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/motionBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/filter.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/filter.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/highlights.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/highlights.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/displayPass.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/displayPass.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/tonemap.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/tonemap.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/boundingBoxRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/depth.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/depth.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/depth.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/depthPeelingSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/depthPeelingRenderer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/edgesRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsVoxelTracingPass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsSpatialBlurPass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsAccumulationPass.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/subSurfaceSceneComponent.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/PostProcesses/subSurfaceScatteringPostProcess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/subSurfaceConfiguration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/outlineRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderingObject.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderingObjectParticleSystem.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderingTextures.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderingTargetRenderer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderingObjectCustomParticles.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderingDepthTextureCopy.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/fluidRenderer/fluidRenderer.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingParticleDepth.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingParticleDepth.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingParticleThickness.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingParticleThickness.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingParticleDiffuse.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingParticleDiffuse.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingBilateralBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingStandardBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/fluidRenderingRender.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingParticleDepth.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingParticleDepth.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingParticleThickness.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingParticleThickness.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingParticleDiffuse.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingParticleDiffuse.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingBilateralBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingStandardBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/fluidRenderingRender.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/reflectiveShadowMap.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/GlobalIllumination/giRSM.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Rendering/GlobalIllumination/giRSMManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/bilateralBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/bilateralBlurQuality.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/rsmGlobalIllumination.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/rsmFullGlobalIllumination.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/bilateralBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/bilateralBlurQuality.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/rsmGlobalIllumination.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/rsmFullGlobalIllumination.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/mrtFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/geometry.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/geometryVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/geometryUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/geometry.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/geometry.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/geometry.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/boundingBoxRendererFragmentDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/boundingBoxRendererUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/boundingBoxRenderer.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/boundingBoxRendererVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/boundingBoxRenderer.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/boundingBoxRenderer.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/boundingBoxRenderer.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/line.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lineVertexDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/lineUboDeclaration.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/line.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/line.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/line.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/outline.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/outline.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/outline.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/outline.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/copyTexture3DLayerToTexture.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/copyTexture3DLayerToTexture.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblShadowVoxelTracing.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblShadowVoxelTracing.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblShadowDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblShadowDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblShadowSpatialBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblShadowSpatialBlur.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblShadowAccumulation.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblShadowAccumulation.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblShadowsCombine.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblShadowsCombine.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblCombineVoxelGrids.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblCombineVoxelGrids.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblGenerateVoxelMip.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblGenerateVoxelMip.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblShadowGBufferDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblShadowGBufferDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblCdfx.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblCdfx.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblCdfy.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblCdfy.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblIcdf.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblIcdf.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblCdfDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblCdfDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblScaledLuminance.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblScaledLuminance.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblDominantDirection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblDominantDirection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblVoxelGrid2dArrayDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblVoxelGrid2dArrayDebug.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblVoxelGrid.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/iblVoxelGrid.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/iblVoxelOpacityAtomicMax.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblVoxelGrid.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblVoxelGrid.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/oitBackBlend.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/oitFinal.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/oitBackBlend.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/oitFinal.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/SmartAssets/smartAssetSerializer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/SmartAssets/smartAssetManager.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/spriteMap.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/spriteMap.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/spriteMap.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Sprites/spritePackedManager.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/sprites.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/sprites.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/sprites.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/sprites.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRTypes.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRHitTestLegacy.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRAnchorSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRPlaneDetector.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRBackgroundRemover.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRControllerPhysics.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRHitTest.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRFeaturePointSystem.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRMeshDetector.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRImageTracking.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRDOMOverlay.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRControllerMovement.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRLightEstimation.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXREyeTracking.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRWalkingLocomotion.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/Layers/WebXRCompositionLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/Layers/WebXRProjectionLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRLayerRenderTargetTexture.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/webXRWebGPURenderTargetTextureProvider.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/Layers/WebXRWebGPUCompositionLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/Layers/WebXRWebGPUProjectionLayer.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRLayers.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRDepthSensing.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRSpaceWarp.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/velocity.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/velocity.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRRawCameraAccess.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRBodyTracking.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/features/WebXRTrackedSources.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRGenericHandController.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRMicrosoftMixedRealityController.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXROculusTouchMotionController.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXROculusHandController.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/motionController/webXRHTCViveMotionController.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/XR/native/nativeXRFrame.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Legacy/legacy.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/lod3D.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/lod3D.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gaussianSplatting.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gaussianSplatting.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gaussianSplatting.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gaussianSplatting.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gaussianSplattingVoxel.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gaussianSplattingVoxel.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gaussianSplattingVoxel.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/gaussianSplattingVoxel.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphPointerDownEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphPointerUpEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Event/flowGraphPointerMoveEventBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/FlowGraph/Blocks/Data/flowGraphDebugBlock.pure.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/oitFinalSimpleBlend.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/oitFinalSimpleBlend.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/selection.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/selection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/selectionOutline.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/selection.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/selection.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/selectionOutline.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/meshBlending.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/meshBlending.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/screenSpaceCurvature.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/volumetricLightingBlendVolume.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/volumetricLightingBlendVolume.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/volumetricLightingRenderVolume.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/volumetricLightingRenderVolume.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/volumetricLightingRenderVolume.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/volumetricLightingRenderVolume.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/iblCopyVoxelBufferToGrid.compute.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/noise.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/noise.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/textureMerger.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/textureMerger.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/textureProcessor.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/textureProcessor.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gpuRenderParticles.vertex.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/gpuRenderParticles.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/fibonacci.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/ShadersInclude/diffusionProfile.ts","file:///home/vsts/work/1/s/packages/dev/core/src/ShadersWGSL/subSurfaceScattering.fragment.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/fibonacci.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/ShadersInclude/diffusionProfile.ts","file:///home/vsts/work/1/s/packages/dev/core/src/Shaders/subSurfaceScattering.fragment.ts"],"sourcesContent":["/**\n * Ensures the global `Symbol.metadata` well-known symbol exists.\n *\n * The serialization decorator store keys its metadata off `Symbol.metadata`. On a runtime that\n * supports `Symbol` but does not yet expose `Symbol.metadata` natively, the symbol must be created\n * so decorated classes can attach their serialization metadata to their constructor.\n *\n * This module installs the symbol as a one-time, idempotent side effect. Import it for its side\n * effect at package entry points before any decorated class is evaluated.\n */\nfunction ApplySymbolMetadataPolyfill(): void {\n    if (typeof Symbol !== \"undefined\" && !(Symbol as any).metadata) {\n        Object.defineProperty(Symbol, \"metadata\", {\n            configurable: true,\n            writable: true,\n            value: Symbol(\"Symbol.metadata\"),\n        });\n    }\n}\n\nApplySymbolMetadataPolyfill();\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/** Defines the cross module used constants to avoid circular dependencies */\r\nexport class Constants {\r\n    /** Sampler suffix when associated with a texture name */\r\n    public static readonly AUTOSAMPLERSUFFIX = \"Sampler\";\r\n    /** Flag used to disable diagnostics for WebGPU */\r\n    public static readonly DISABLEUA = \"#define DISABLE_UNIFORMITY_ANALYSIS\";\r\n    /** Defines that alpha blending is disabled */\r\n    public static readonly ALPHA_DISABLE = 0;\r\n    /** Defines that alpha blending is COLOR=SRC_ALPHA * SRC + DEST, ALPHA=DEST_ALPHA */\r\n    public static readonly ALPHA_ADD = 1;\r\n    /**\r\n     *  Defines that alpha blending is COLOR=SRC_ALPHA * SRC + (1 - SRC_ALPHA) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA\r\n     *  Go-to for transparency. 100% alpha means source, 0% alpha means background. Glass, UI fade, smoke\r\n     */\r\n    public static readonly ALPHA_COMBINE = 2;\r\n    /**\r\n     * Defines that alpha blending is COLOR=(1 - SRC) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA\r\n     * Subtracts source from destination, leading to darker results\r\n     * */\r\n    public static readonly ALPHA_SUBTRACT = 3;\r\n    /** Defines that alpha blending is COLOR=DEST * SRC, ALPHA=SRC_ALPHA + DEST_ALPHA */\r\n    public static readonly ALPHA_MULTIPLY = 4;\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC_ALPHA * SRC + (1 - SRC) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA\r\n     * Prioritizes area with high source alpha, strongly emphasizes the source\r\n     */\r\n    public static readonly ALPHA_MAXIMIZED = 5;\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC + DEST, ALPHA=DEST_ALPHA\r\n     * Source color is added to the destination color without alpha affecting the result. Great for additive glow effects (fire, magic, lasers)\r\n     */\r\n    public static readonly ALPHA_ONEONE = 6;\r\n    /** Defines that alpha blending is COLOR=SRC + (1 - SRC_ALPHA) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA */\r\n    public static readonly ALPHA_PREMULTIPLIED = 7;\r\n    /** Defines that alpha blending is COLOR=SRC + (1 - SRC_ALPHA) * DEST, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA */\r\n    public static readonly ALPHA_PREMULTIPLIED_PORTERDUFF = 8;\r\n    /**\r\n     * Defines that alpha blending is COLOR=CST * SRC + (1 - CST) * DEST, ALPHA=CST_ALPHA * SRC + (1 - CST_ALPHA) * DEST_ALPHA\r\n     * Where CST is user-supplied color\r\n     */\r\n    public static readonly ALPHA_INTERPOLATE = 9;\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC + (1 - SRC) * DEST, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA\r\n     * Brightens, good for soft light or UI highlights (like photoshop's screen blend)\r\n     */\r\n    public static readonly ALPHA_SCREENMODE = 10;\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC + DST, ALPHA=SRC_ALPHA + DEST_ALPHA\r\n     * Straight addition of color and alpha- use when you want both source and destination colors and opacities to stack\r\n     */\r\n    public static readonly ALPHA_ONEONE_ONEONE = 11;\r\n    /**\r\n     * Defines that alpha blending is COLOR=DEST_ALPHA * SRC + DST, ALPHA=0\r\n     */\r\n    public static readonly ALPHA_ALPHATOCOLOR = 12;\r\n    /**\r\n     * Defines that alpha blending is COLOR=(1 - DEST) * SRC + (1 - SRC) * DEST, ALPHA=(1 - DEST_ALPHA) * SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA\r\n     * Result is between source and destination, used for experimental blending or styled effects\r\n     */\r\n    public static readonly ALPHA_REVERSEONEMINUS = 13;\r\n    /**\r\n     * Defines that alpha blending is ALPHA=SRC + (1 - SRC ALPHA) * DEST, ALPHA=SRC_ALPHA + (1 - SRC ALPHA) * DEST_ALPHA\r\n     * Smooths blending between source and destination, useful in layered alpha masks\r\n     */\r\n    public static readonly ALPHA_SRC_DSTONEMINUSSRCALPHA = 14;\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC + DST, ALPHA=SRC_ALPHA\r\n     * Color stacks, but only source alpha is kept\r\n     */\r\n    public static readonly ALPHA_ONEONE_ONEZERO = 15;\r\n    /**\r\n     * Defines that alpha blending is COLOR=(1 - DEST) * SRC + (1 - SRC) * DEST, ALPHA=DEST_ALPHA\r\n     * Produces inverted look (negative space), like 'exclusion' mode in photoshop\r\n     */\r\n    public static readonly ALPHA_EXCLUSION = 16;\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC_ALPHA * SRC + (1 - SRC ALPHA) * DEST, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA\r\n     * Great for layered rendering (particles, fog volumes), accumulates transparency in a more physically accurate way\r\n     */\r\n    public static readonly ALPHA_LAYER_ACCUMULATE = 17;\r\n\r\n    /**\r\n     * Defines that alpha blending is COLOR=MIN(SRC, DEST), ALPHA=MIN(SRC_ALPHA, DEST_ALPHA)\r\n     */\r\n    public static readonly ALPHA_MIN = 18;\r\n\r\n    /**\r\n     * Defines that alpha blending is COLOR=MAX(SRC, DEST), ALPHA=MAX(SRC_ALPHA, DEST_ALPHA)\r\n     */\r\n    public static readonly ALPHA_MAX = 19;\r\n\r\n    /**\r\n     * Defines that alpha blending uses dual source blending and is COLOR=SRC + SRC1 * DEST, ALPHA=DST_ALPHA\r\n     */\r\n    public static readonly ALPHA_DUAL_SRC0_ADD_SRC1xDST = 20;\r\n\r\n    /**\r\n     * Defines that alpha blending is COLOR=SRC, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA\r\n     */\r\n    public static readonly ALPHA_REPLACE_COLOR = 21;\r\n\r\n    /** Defines that alpha blending equation a SUM */\r\n    public static readonly ALPHA_EQUATION_ADD = 0;\r\n    /** Defines that alpha blending equation a SUBSTRACTION */\r\n    public static readonly ALPHA_EQUATION_SUBSTRACT = 1;\r\n    /** Defines that alpha blending equation a REVERSE SUBSTRACTION */\r\n    public static readonly ALPHA_EQUATION_REVERSE_SUBTRACT = 2;\r\n    /** Defines that alpha blending equation a MAX operation */\r\n    public static readonly ALPHA_EQUATION_MAX = 3;\r\n    /** Defines that alpha blending equation a MIN operation */\r\n    public static readonly ALPHA_EQUATION_MIN = 4;\r\n    /**\r\n     * Defines that alpha blending equation a DARKEN operation:\r\n     * It takes the min of the src and sums the alpha channels.\r\n     */\r\n    public static readonly ALPHA_EQUATION_DARKEN = 5;\r\n\r\n    /** Defines that the resource is not delayed*/\r\n    public static readonly DELAYLOADSTATE_NONE = 0;\r\n    /** Defines that the resource was successfully delay loaded */\r\n    public static readonly DELAYLOADSTATE_LOADED = 1;\r\n    /** Defines that the resource is currently delay loading */\r\n    public static readonly DELAYLOADSTATE_LOADING = 2;\r\n    /** Defines that the resource is delayed and has not started loading */\r\n    public static readonly DELAYLOADSTATE_NOTLOADED = 4;\r\n\r\n    // Depth or Stencil test Constants.\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass. i.e. Nothing will be drawn */\r\n    public static readonly NEVER = 0x0200;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */\r\n    public static readonly ALWAYS = 0x0207;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value */\r\n    public static readonly LESS = 0x0201;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value */\r\n    public static readonly EQUAL = 0x0202;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value */\r\n    public static readonly LEQUAL = 0x0203;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value */\r\n    public static readonly GREATER = 0x0204;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value */\r\n    public static readonly GEQUAL = 0x0206;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value */\r\n    public static readonly NOTEQUAL = 0x0205;\r\n\r\n    // Stencil Actions Constants.\r\n    /** Passed to stencilOperation to specify that stencil value must be kept */\r\n    public static readonly KEEP = 0x1e00;\r\n    /** Passed to stencilOperation to specify that stencil value must be zero */\r\n    public static readonly ZERO = 0x0000;\r\n    /** Passed to stencilOperation to specify that stencil value must be replaced */\r\n    public static readonly REPLACE = 0x1e01;\r\n    /** Passed to stencilOperation to specify that stencil value must be incremented */\r\n    public static readonly INCR = 0x1e02;\r\n    /** Passed to stencilOperation to specify that stencil value must be decremented */\r\n    public static readonly DECR = 0x1e03;\r\n    /** Passed to stencilOperation to specify that stencil value must be inverted */\r\n    public static readonly INVERT = 0x150a;\r\n    /** Passed to stencilOperation to specify that stencil value must be incremented with wrapping */\r\n    public static readonly INCR_WRAP = 0x8507;\r\n    /** Passed to stencilOperation to specify that stencil value must be decremented with wrapping */\r\n    public static readonly DECR_WRAP = 0x8508;\r\n\r\n    /** Texture is not repeating outside of 0..1 UVs */\r\n    public static readonly TEXTURE_CLAMP_ADDRESSMODE = 0;\r\n    /** Texture is repeating outside of 0..1 UVs */\r\n    public static readonly TEXTURE_WRAP_ADDRESSMODE = 1;\r\n    /** Texture is repeating and mirrored */\r\n    public static readonly TEXTURE_MIRROR_ADDRESSMODE = 2;\r\n\r\n    /** No texture repetition breaking — standard tiling (1 texture fetch) */\r\n    public static readonly TEXTURE_REPETITION_NONE = 0;\r\n    /** Noise-driven offset blending to break texture repetition (3 texture fetches). Based on Inigo Quilez's technique 3. */\r\n    public static readonly TEXTURE_REPETITION_NOISE_BLEND = 1;\r\n    /** Hex-tile grid with per-tile rotation and luminance-weighted blending (3 texture fetches). Based on Mikkelsen, \"Practical Real-Time Hex-Tiling\", JCGT 2022. */\r\n    public static readonly TEXTURE_REPETITION_HEX_TILING = 2;\r\n    /** Per-tile random offset and mirror to break texture repetition (4 texture fetches). Based on Inigo Quilez's technique 1. */\r\n    public static readonly TEXTURE_REPETITION_TILE_RANDOMIZATION = 3;\r\n    /** Smooth Voronoi bombing with Gaussian-weighted blending (9 texture fetches). Based on Inigo Quilez's technique 2. */\r\n    public static readonly TEXTURE_REPETITION_VORONOI_BOMBING = 4;\r\n\r\n    /** Flag to create a storage texture */\r\n    public static readonly TEXTURE_CREATIONFLAG_STORAGE = 1;\r\n\r\n    /** ALPHA */\r\n    public static readonly TEXTUREFORMAT_ALPHA = 0;\r\n    /** LUMINANCE */\r\n    public static readonly TEXTUREFORMAT_LUMINANCE = 1;\r\n    /** LUMINANCE_ALPHA */\r\n    public static readonly TEXTUREFORMAT_LUMINANCE_ALPHA = 2;\r\n    /** RGB */\r\n    public static readonly TEXTUREFORMAT_RGB = 4;\r\n    /** RGBA */\r\n    public static readonly TEXTUREFORMAT_RGBA = 5;\r\n    /** RED */\r\n    public static readonly TEXTUREFORMAT_RED = 6;\r\n    /** RED (2nd reference) */\r\n    public static readonly TEXTUREFORMAT_R = 6;\r\n    /** RED unsigned short normed to [0, 1] **/\r\n    public static readonly TEXTUREFORMAT_R16_UNORM = 0x822a;\r\n    /** RG unsigned short normed to [0, 1] **/\r\n    public static readonly TEXTUREFORMAT_RG16_UNORM = 0x822c;\r\n    /** RGB unsigned short normed to [0, 1] **/\r\n    public static readonly TEXTUREFORMAT_RGB16_UNORM = 0x8054;\r\n    /** RGBA unsigned short normed to [0, 1] **/\r\n    public static readonly TEXTUREFORMAT_RGBA16_UNORM = 0x805b;\r\n    /** RED signed short normed to [-1, 1] **/\r\n    public static readonly TEXTUREFORMAT_R16_SNORM = 0x8f98;\r\n    /** RG signed short normed to [-1, 1] **/\r\n    public static readonly TEXTUREFORMAT_RG16_SNORM = 0x8f99;\r\n    /** RGB signed short normed to [-1, 1] **/\r\n    public static readonly TEXTUREFORMAT_RGB16_SNORM = 0x8f9a;\r\n    /** RGBA signed short normed to [-1, 1] **/\r\n    public static readonly TEXTUREFORMAT_RGBA16_SNORM = 0x8f9b;\r\n    /** RG */\r\n    public static readonly TEXTUREFORMAT_RG = 7;\r\n    /** RED_INTEGER */\r\n    public static readonly TEXTUREFORMAT_RED_INTEGER = 8;\r\n    /** RED_INTEGER (2nd reference) */\r\n    public static readonly TEXTUREFORMAT_R_INTEGER = 8;\r\n    /** RG_INTEGER */\r\n    public static readonly TEXTUREFORMAT_RG_INTEGER = 9;\r\n    /** RGB_INTEGER */\r\n    public static readonly TEXTUREFORMAT_RGB_INTEGER = 10;\r\n    /** RGBA_INTEGER */\r\n    public static readonly TEXTUREFORMAT_RGBA_INTEGER = 11;\r\n    /** BGRA */\r\n    public static readonly TEXTUREFORMAT_BGRA = 12;\r\n\r\n    /** Depth 24 bits + Stencil 8 bits */\r\n    public static readonly TEXTUREFORMAT_DEPTH24_STENCIL8 = 13;\r\n    /** Depth 32 bits float */\r\n    public static readonly TEXTUREFORMAT_DEPTH32_FLOAT = 14;\r\n    /** Depth 16 bits */\r\n    public static readonly TEXTUREFORMAT_DEPTH16 = 15;\r\n    /** Depth 24 bits */\r\n    public static readonly TEXTUREFORMAT_DEPTH24 = 16;\r\n    /** Depth 24 bits unorm + Stencil 8 bits */\r\n    public static readonly TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 = 17;\r\n    /** Depth 32 bits float + Stencil 8 bits */\r\n    public static readonly TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8 = 18;\r\n    /** Stencil 8 bits */\r\n    public static readonly TEXTUREFORMAT_STENCIL8 = 19;\r\n    /** UNDEFINED */\r\n    public static readonly TEXTUREFORMAT_UNDEFINED = 0xffffffff;\r\n\r\n    /** Compressed BC7 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM = 36492;\r\n    /** Compressed BC7 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 36493;\r\n    /** Compressed BC6 unsigned float */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 36495;\r\n    /** Compressed BC6 signed float */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 36494;\r\n    /** Compressed BC3 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5 = 33779;\r\n    /** Compressed BC3 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 35919;\r\n    /** Compressed BC2 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3 = 33778;\r\n    /** Compressed BC2 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 35918;\r\n    /** Compressed BC1 (RGBA) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1 = 33777;\r\n    /** Compressed BC1 (RGB) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1 = 33776;\r\n    /** Compressed BC1 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 35917;\r\n    /** Compressed BC1 (SRGB) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT = 35916;\r\n    /** Compressed ASTC 4x4 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4 = 37808;\r\n    /** Compressed ASTC 5x4 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4 = 37809;\r\n    /** Compressed ASTC 5x5 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5 = 37810;\r\n    /** Compressed ASTC 6x5 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5 = 37811;\r\n    /** Compressed ASTC 6x6 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6 = 37812;\r\n    /** Compressed ASTC 8x5 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5 = 37813;\r\n    /** Compressed ASTC 8x6 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6 = 37814;\r\n    /** Compressed ASTC 8x8 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8 = 37815;\r\n    /** Compressed ASTC 10x5 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5 = 37816;\r\n    /** Compressed ASTC 10x6 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6 = 37817;\r\n    /** Compressed ASTC 10x8 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8 = 37818;\r\n    /** Compressed ASTC 10x10 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10 = 37819;\r\n    /** Compressed ASTC 12x10 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10 = 37820;\r\n    /** Compressed ASTC 12x12 */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12 = 37821;\r\n    /** Compressed ASTC 4x4 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 37840;\r\n    /** Compressed ASTC 5x4 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 37841;\r\n    /** Compressed ASTC 5x5 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 37842;\r\n    /** Compressed ASTC 6x5 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 37843;\r\n    /** Compressed ASTC 6x6 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 37844;\r\n    /** Compressed ASTC 8x5 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 37845;\r\n    /** Compressed ASTC 8x6 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 37846;\r\n    /** Compressed ASTC 8x8 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 37847;\r\n    /** Compressed ASTC 10x5 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 37848;\r\n    /** Compressed ASTC 10x6 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 37849;\r\n    /** Compressed ASTC 10x8 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 37850;\r\n    /** Compressed ASTC 10x10 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 37851;\r\n    /** Compressed ASTC 12x10 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 37852;\r\n    /** Compressed ASTC 12x12 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 37853;\r\n    /** Compressed ETC1 (RGB) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL = 36196;\r\n    /** Compressed ETC2 (RGB) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGB8_ETC2 = 37492;\r\n    /** Compressed ETC2 (SRGB) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2 = 37493;\r\n    /** Compressed ETC2 (RGB+A1) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37494;\r\n    /** Compressed ETC2 (SRGB+A1)*/\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37495;\r\n    /** Compressed ETC2 (RGBA) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC = 37496;\r\n    /** Compressed ETC2 (SRGB+A) */\r\n    public static readonly TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 37497;\r\n\r\n    /** UNSIGNED_BYTE */\r\n    public static readonly TEXTURETYPE_UNSIGNED_BYTE = 0;\r\n    /** @deprecated use more explicit TEXTURETYPE_UNSIGNED_BYTE instead. Use TEXTURETYPE_UNSIGNED_INTEGER for 32bits values.*/\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT = 0;\r\n    /** FLOAT */\r\n    public static readonly TEXTURETYPE_FLOAT = 1;\r\n    /** HALF_FLOAT */\r\n    public static readonly TEXTURETYPE_HALF_FLOAT = 2;\r\n    /** BYTE */\r\n    public static readonly TEXTURETYPE_BYTE = 3;\r\n    /** SHORT */\r\n    public static readonly TEXTURETYPE_SHORT = 4;\r\n    /** UNSIGNED_SHORT */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT = 5;\r\n    /** INT */\r\n    public static readonly TEXTURETYPE_INT = 6;\r\n    /** UNSIGNED_INT */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INTEGER = 7;\r\n    /** UNSIGNED_SHORT_4_4_4_4 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 = 8;\r\n    /** UNSIGNED_SHORT_5_5_5_1 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 = 9;\r\n    /** UNSIGNED_SHORT_5_6_5 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT_5_6_5 = 10;\r\n    /** UNSIGNED_INT_2_10_10_10_REV */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV = 11;\r\n    /** UNSIGNED_INT_24_8 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_24_8 = 12;\r\n    /** UNSIGNED_INT_10F_11F_11F_REV */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV = 13;\r\n    /** UNSIGNED_INT_5_9_9_9_REV */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV = 14;\r\n    /** FLOAT_32_UNSIGNED_INT_24_8_REV */\r\n    public static readonly TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV = 15;\r\n    /** UNDEFINED */\r\n    public static readonly TEXTURETYPE_UNDEFINED = 16;\r\n\r\n    /** 2D Texture target*/\r\n    public static readonly TEXTURE_2D = 3553;\r\n    /** 2D Array Texture target */\r\n    public static readonly TEXTURE_2D_ARRAY = 35866;\r\n    /** Cube Map Texture target */\r\n    public static readonly TEXTURE_CUBE_MAP = 34067;\r\n    /** Cube Map Array Texture target */\r\n    public static readonly TEXTURE_CUBE_MAP_ARRAY = 0xdeadbeef;\r\n    /** 3D Texture target */\r\n    public static readonly TEXTURE_3D = 32879;\r\n\r\n    /** nearest is mag = nearest and min = nearest and no mip */\r\n    public static readonly TEXTURE_NEAREST_SAMPLINGMODE = 1;\r\n    /** mag = nearest and min = nearest and mip = none */\r\n    public static readonly TEXTURE_NEAREST_NEAREST = 1;\r\n\r\n    /** Bilinear is mag = linear and min = linear and no mip */\r\n    public static readonly TEXTURE_BILINEAR_SAMPLINGMODE = 2;\r\n    /** mag = linear and min = linear and mip = none */\r\n    public static readonly TEXTURE_LINEAR_LINEAR = 2;\r\n\r\n    /** Trilinear is mag = linear and min = linear and mip = linear */\r\n    public static readonly TEXTURE_TRILINEAR_SAMPLINGMODE = 3;\r\n    /** Trilinear is mag = linear and min = linear and mip = linear */\r\n    public static readonly TEXTURE_LINEAR_LINEAR_MIPLINEAR = 3;\r\n\r\n    /** mag = nearest and min = nearest and mip = nearest */\r\n    public static readonly TEXTURE_NEAREST_NEAREST_MIPNEAREST = 4;\r\n    /** mag = nearest and min = linear and mip = nearest */\r\n    public static readonly TEXTURE_NEAREST_LINEAR_MIPNEAREST = 5;\r\n    /** mag = nearest and min = linear and mip = linear */\r\n    public static readonly TEXTURE_NEAREST_LINEAR_MIPLINEAR = 6;\r\n    /** mag = nearest and min = linear and mip = none */\r\n    public static readonly TEXTURE_NEAREST_LINEAR = 7;\r\n    /** nearest is mag = nearest and min = nearest and mip = linear */\r\n    public static readonly TEXTURE_NEAREST_NEAREST_MIPLINEAR = 8;\r\n    /** mag = linear and min = nearest and mip = nearest */\r\n    public static readonly TEXTURE_LINEAR_NEAREST_MIPNEAREST = 9;\r\n    /** mag = linear and min = nearest and mip = linear */\r\n    public static readonly TEXTURE_LINEAR_NEAREST_MIPLINEAR = 10;\r\n    /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n    public static readonly TEXTURE_LINEAR_LINEAR_MIPNEAREST = 11;\r\n    /** mag = linear and min = nearest and mip = none */\r\n    public static readonly TEXTURE_LINEAR_NEAREST = 12;\r\n\r\n    /** Explicit coordinates mode */\r\n    public static readonly TEXTURE_EXPLICIT_MODE = 0;\r\n    /** Spherical coordinates mode */\r\n    public static readonly TEXTURE_SPHERICAL_MODE = 1;\r\n    /** Planar coordinates mode */\r\n    public static readonly TEXTURE_PLANAR_MODE = 2;\r\n    /** Cubic coordinates mode */\r\n    public static readonly TEXTURE_CUBIC_MODE = 3;\r\n    /** Projection coordinates mode */\r\n    public static readonly TEXTURE_PROJECTION_MODE = 4;\r\n    /** Skybox coordinates mode */\r\n    public static readonly TEXTURE_SKYBOX_MODE = 5;\r\n    /** Inverse Cubic coordinates mode */\r\n    public static readonly TEXTURE_INVCUBIC_MODE = 6;\r\n    /** Equirectangular coordinates mode */\r\n    public static readonly TEXTURE_EQUIRECTANGULAR_MODE = 7;\r\n    /** Equirectangular Fixed coordinates mode */\r\n    public static readonly TEXTURE_FIXED_EQUIRECTANGULAR_MODE = 8;\r\n    /** Equirectangular Fixed Mirrored coordinates mode */\r\n    public static readonly TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE = 9;\r\n\r\n    /** Offline (baking) quality for texture filtering */\r\n    public static readonly TEXTURE_FILTERING_QUALITY_OFFLINE = 4096;\r\n\r\n    /** High quality for texture filtering */\r\n    public static readonly TEXTURE_FILTERING_QUALITY_HIGH = 64;\r\n\r\n    /** Medium quality for texture filtering */\r\n    public static readonly TEXTURE_FILTERING_QUALITY_MEDIUM = 16;\r\n\r\n    /** Low quality for texture filtering */\r\n    public static readonly TEXTURE_FILTERING_QUALITY_LOW = 8;\r\n\r\n    // Texture rescaling mode\r\n    /** Defines that texture rescaling will use a floor to find the closer power of 2 size */\r\n    public static readonly SCALEMODE_FLOOR = 1;\r\n    /** Defines that texture rescaling will look for the nearest power of 2 size */\r\n    public static readonly SCALEMODE_NEAREST = 2;\r\n    /** Defines that texture rescaling will use a ceil to find the closer power of 2 size */\r\n    public static readonly SCALEMODE_CEILING = 3;\r\n\r\n    /**\r\n     * The dirty texture flag value\r\n     */\r\n    public static readonly MATERIAL_TextureDirtyFlag = 1;\r\n    /**\r\n     * The dirty light flag value\r\n     */\r\n    public static readonly MATERIAL_LightDirtyFlag = 2;\r\n    /**\r\n     * The dirty fresnel flag value\r\n     */\r\n    public static readonly MATERIAL_FresnelDirtyFlag = 4;\r\n    /**\r\n     * The dirty attribute flag value\r\n     */\r\n    public static readonly MATERIAL_AttributesDirtyFlag = 8;\r\n    /**\r\n     * The dirty misc flag value\r\n     */\r\n    public static readonly MATERIAL_MiscDirtyFlag = 16;\r\n    /**\r\n     * The dirty prepass flag value\r\n     */\r\n    public static readonly MATERIAL_PrePassDirtyFlag = 32;\r\n    /**\r\n     * The dirty image processing flag value\r\n     */\r\n    public static readonly MATERIAL_ImageProcessingDirtyFlag = 64;\r\n    /**\r\n     * The all dirty flag value\r\n     */\r\n    public static readonly MATERIAL_AllDirtyFlag = 127;\r\n\r\n    /**\r\n     * Returns the triangle fill mode\r\n     */\r\n    public static readonly MATERIAL_TriangleFillMode = 0;\r\n    /**\r\n     * Returns the wireframe mode\r\n     */\r\n    public static readonly MATERIAL_WireFrameFillMode = 1;\r\n    /**\r\n     * Returns the point fill mode\r\n     */\r\n    public static readonly MATERIAL_PointFillMode = 2;\r\n    /**\r\n     * Returns the point list draw mode\r\n     */\r\n    public static readonly MATERIAL_PointListDrawMode = 3;\r\n    /**\r\n     * Returns the line list draw mode\r\n     */\r\n    public static readonly MATERIAL_LineListDrawMode = 4;\r\n    /**\r\n     * Returns the line loop draw mode\r\n     */\r\n    public static readonly MATERIAL_LineLoopDrawMode = 5;\r\n    /**\r\n     * Returns the line strip draw mode\r\n     */\r\n    public static readonly MATERIAL_LineStripDrawMode = 6;\r\n\r\n    /**\r\n     * Returns the triangle strip draw mode\r\n     */\r\n    public static readonly MATERIAL_TriangleStripDrawMode = 7;\r\n    /**\r\n     * Returns the triangle fan draw mode\r\n     */\r\n    public static readonly MATERIAL_TriangleFanDrawMode = 8;\r\n\r\n    /**\r\n     * Stores the clock-wise side orientation\r\n     */\r\n    public static readonly MATERIAL_ClockWiseSideOrientation = 0;\r\n    /**\r\n     * Stores the counter clock-wise side orientation\r\n     */\r\n    public static readonly MATERIAL_CounterClockWiseSideOrientation = 1;\r\n\r\n    /**\r\n     * Energy-conserving Oren Nayar diffuse model type.\r\n     */\r\n    public static readonly MATERIAL_DIFFUSE_MODEL_E_OREN_NAYAR = 0;\r\n\r\n    /**\r\n     * Burley diffuse model type.\r\n     */\r\n    public static readonly MATERIAL_DIFFUSE_MODEL_BURLEY = 1;\r\n\r\n    /**\r\n     * Lambertian diffuse model type.\r\n     */\r\n    public static readonly MATERIAL_DIFFUSE_MODEL_LAMBERT = 2;\r\n\r\n    /**\r\n     * Babylon.js version less than 8.x\r\n     * IBL Lambert + Burley diffuse model type.\r\n     */\r\n    public static readonly MATERIAL_DIFFUSE_MODEL_LEGACY = 3;\r\n\r\n    /**\r\n     * Specular lighting for dielectric materials follows the logic\r\n     * in the glTF specification and KHR_materials_specular extension.\r\n     * Specular colour is applied only at normal incidence (i.e. F0) while\r\n     * glancing angles (i.e. F90) tend towards white.\r\n     */\r\n    public static readonly MATERIAL_DIELECTRIC_SPECULAR_MODEL_GLTF = 0;\r\n\r\n    /**\r\n     * Specular lighting for dielectric materials follows the logic\r\n     * in the OpenPBR specification. Specular colour is applied to all\r\n     * dielectric reflection, not just at normal incidence (i.e. F0).\r\n     */\r\n    public static readonly MATERIAL_DIELECTRIC_SPECULAR_MODEL_OPENPBR = 1;\r\n\r\n    /**\r\n     * Specular lighting for metals follows the logic in the glTF specification.\r\n     * Base colour is applied at F0 while glancing angles tend towards white.\r\n     */\r\n    public static readonly MATERIAL_CONDUCTOR_SPECULAR_MODEL_GLTF = 0;\r\n\r\n    /**\r\n     * Specular lighting for metals follows the logic in the OpenPBR specification.\r\n     * Specular colour is applied to glancing angles using the F82 spec.\r\n     */\r\n    public static readonly MATERIAL_CONDUCTOR_SPECULAR_MODEL_OPENPBR = 1;\r\n\r\n    /**\r\n     * Nothing\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_NothingTrigger = 0;\r\n    /**\r\n     * On pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnPickTrigger = 1;\r\n    /**\r\n     * On left pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnLeftPickTrigger = 2;\r\n    /**\r\n     * On right pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnRightPickTrigger = 3;\r\n    /**\r\n     * On center pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnCenterPickTrigger = 4;\r\n    /**\r\n     * On pick down\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnPickDownTrigger = 5;\r\n    /**\r\n     * On double pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnDoublePickTrigger = 6;\r\n    /**\r\n     * On pick up\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnPickUpTrigger = 7;\r\n    /**\r\n     * On pick out.\r\n     * This trigger will only be raised if you also declared a OnPickDown\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnPickOutTrigger = 16;\r\n    /**\r\n     * On long press\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnLongPressTrigger = 8;\r\n    /**\r\n     * On pointer over\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnPointerOverTrigger = 9;\r\n    /**\r\n     * On pointer out\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnPointerOutTrigger = 10;\r\n    /**\r\n     * On every frame\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnEveryFrameTrigger = 11;\r\n    /**\r\n     * On intersection enter\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnIntersectionEnterTrigger = 12;\r\n    /**\r\n     * On intersection exit\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnIntersectionExitTrigger = 13;\r\n    /**\r\n     * On key down\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnKeyDownTrigger = 14;\r\n    /**\r\n     * On key up\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly ACTION_OnKeyUpTrigger = 15;\r\n\r\n    /**\r\n     * Billboard mode will only apply to Y axis\r\n     */\r\n    public static readonly PARTICLES_BILLBOARDMODE_Y = 2;\r\n    /**\r\n     * Billboard mode will apply to all axes\r\n     */\r\n    public static readonly PARTICLES_BILLBOARDMODE_ALL = 7;\r\n    /**\r\n     * Special billboard mode where the particle will be biilboard to the camera but rotated to align with direction\r\n     */\r\n    public static readonly PARTICLES_BILLBOARDMODE_STRETCHED = 8;\r\n    /**\r\n     * Special billboard mode where the particle will be billboard to the camera but only around the axis of the direction of particle emission\r\n     */\r\n    public static readonly PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL = 9;\r\n\r\n    /** Default culling strategy : this is an exclusion test and it's the more accurate.\r\n     *  Test order :\r\n     *  Is the bounding sphere outside the frustum ?\r\n     *  If not, are the bounding box vertices outside the frustum ?\r\n     *  It not, then the cullable object is in the frustum.\r\n     */\r\n    public static readonly MESHES_CULLINGSTRATEGY_STANDARD = 0;\r\n    /** Culling strategy : Bounding Sphere Only.\r\n     *  This is an exclusion test. It's faster than the standard strategy because the bounding box is not tested.\r\n     *  It's also less accurate than the standard because some not visible objects can still be selected.\r\n     *  Test : is the bounding sphere outside the frustum ?\r\n     *  If not, then the cullable object is in the frustum.\r\n     */\r\n    public static readonly MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY = 1;\r\n    /** Culling strategy : Optimistic Inclusion.\r\n     *  This in an inclusion test first, then the standard exclusion test.\r\n     *  This can be faster when a cullable object is expected to be almost always in the camera frustum.\r\n     *  This could also be a little slower than the standard test when the tested object center is not the frustum but one of its bounding box vertex is still inside.\r\n     *  Anyway, it's as accurate as the standard strategy.\r\n     *  Test :\r\n     *  Is the cullable object bounding sphere center in the frustum ?\r\n     *  If not, apply the default culling strategy.\r\n     */\r\n    public static readonly MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION = 2;\r\n    /** Culling strategy : Optimistic Inclusion then Bounding Sphere Only.\r\n     *  This in an inclusion test first, then the bounding sphere only exclusion test.\r\n     *  This can be the fastest test when a cullable object is expected to be almost always in the camera frustum.\r\n     *  This could also be a little slower than the BoundingSphereOnly strategy when the tested object center is not in the frustum but its bounding sphere still intersects it.\r\n     *  It's less accurate than the standard strategy and as accurate as the BoundingSphereOnly strategy.\r\n     *  Test :\r\n     *  Is the cullable object bounding sphere center in the frustum ?\r\n     *  If not, apply the Bounding Sphere Only strategy. No Bounding Box is tested here.\r\n     */\r\n    public static readonly MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY = 3;\r\n\r\n    /**\r\n     * No logging while loading\r\n     */\r\n    public static readonly SCENELOADER_NO_LOGGING = 0;\r\n    /**\r\n     * Minimal logging while loading\r\n     */\r\n    public static readonly SCENELOADER_MINIMAL_LOGGING = 1;\r\n    /**\r\n     * Summary logging while loading\r\n     */\r\n    public static readonly SCENELOADER_SUMMARY_LOGGING = 2;\r\n    /**\r\n     * Detailed logging while loading\r\n     */\r\n    public static readonly SCENELOADER_DETAILED_LOGGING = 3;\r\n\r\n    /**\r\n     * Constant used to retrieve the legacy irradiance texture index in the textures array in the prepass\r\n     * using getIndex(Constants.PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE = 0;\r\n    /**\r\n     * Constant used to retrieve the position texture index in the textures array in the prepass\r\n     * using getIndex(Constants.PREPASS_POSITION_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_POSITION_TEXTURE_TYPE = 1;\r\n    /**\r\n     * Constant used to retrieve the velocity texture index in the textures array in the prepass\r\n     * using getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_VELOCITY_TEXTURE_TYPE = 2;\r\n    /**\r\n     * Constant used to retrieve the reflectivity texture index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_REFLECTIVITY_TEXTURE_TYPE = 3;\r\n    /**\r\n     * Constant used to retrieve the lit color texture index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_COLOR_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_COLOR_TEXTURE_TYPE = 4;\r\n    /**\r\n     * Constant used to retrieve (camera view) depth index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_DEPTH_TEXTURE_TYPE = 5;\r\n    /**\r\n     * Constant used to retrieve normal index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_NORMAL_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_NORMAL_TEXTURE_TYPE = 6;\r\n    /**\r\n     * Constant used to retrieve (sqrt) albedo index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_ALBEDO_SQRT_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_ALBEDO_SQRT_TEXTURE_TYPE = 7;\r\n\r\n    /**\r\n     * Constant used to retrieve world normal index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_WORLD_NORMAL_TEXTURE_TYPE = 8;\r\n\r\n    /**\r\n     * Constant used to retrieve the local position texture index in the textures array in the prepass\r\n     * using getIndex(Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_LOCAL_POSITION_TEXTURE_TYPE = 9;\r\n\r\n    /**\r\n     * Constant used to retrieve screen-space (non-linear) depth index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE = 10;\r\n\r\n    /**\r\n     * Constant used to retrieve the velocity texture index in the textures array in the prepass\r\n     * using getIndex(Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE = 11;\r\n\r\n    /**\r\n     * Constant used to retrieve albedo index in the textures array in the prepass\r\n     * using the getIndex(Constants.PREPASS_ALBEDO_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_ALBEDO_TEXTURE_TYPE = 12;\r\n\r\n    /**\r\n     * Constant used to retrieve normalized camera view depth geometry texture\r\n     */\r\n    public static readonly PREPASS_NORMALIZED_VIEW_DEPTH_TEXTURE_TYPE = 13;\r\n\r\n    /**\r\n     * Constant used to retrieve the irradiance texture index in the textures array in the prepass\r\n     * using getIndex(Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE)\r\n     */\r\n    public static readonly PREPASS_IRRADIANCE_TEXTURE_TYPE = 14;\r\n\r\n    /**\r\n     * Constant used to retrieve the object ID texture index in geometry rendering textures.\r\n     * Object IDs are stored as 24-bit RGB values or 8-bit RED values, depending on the texture format.\r\n     */\r\n    public static readonly PREPASS_OBJECT_ID_TEXTURE_TYPE = 15;\r\n\r\n    /**\r\n     * Constant used to retrieve the packed mesh-blending tag texture index in geometry rendering textures.\r\n     */\r\n    public static readonly PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE = 16;\r\n\r\n    /** Flag to create a readable buffer (the buffer can be the source of a copy) */\r\n    public static readonly BUFFER_CREATIONFLAG_READ = 1;\r\n    /** Flag to create a writable buffer (the buffer can be the destination of a copy) */\r\n    public static readonly BUFFER_CREATIONFLAG_WRITE = 2;\r\n    /** Flag to create a readable and writable buffer */\r\n    public static readonly BUFFER_CREATIONFLAG_READWRITE = 3;\r\n    /** Flag to create a buffer suitable to be used as a uniform buffer */\r\n    public static readonly BUFFER_CREATIONFLAG_UNIFORM = 4;\r\n    /** Flag to create a buffer suitable to be used as a vertex buffer */\r\n    public static readonly BUFFER_CREATIONFLAG_VERTEX = 8;\r\n    /** Flag to create a buffer suitable to be used as an index buffer */\r\n    public static readonly BUFFER_CREATIONFLAG_INDEX = 16;\r\n    /** Flag to create a buffer suitable to be used as a storage buffer */\r\n    public static readonly BUFFER_CREATIONFLAG_STORAGE = 32;\r\n    /** Flag to create a buffer suitable to be used for indirect calls, such as `dispatchIndirect` */\r\n    public static readonly BUFFER_CREATIONFLAG_INDIRECT = 64;\r\n\r\n    /**\r\n     * Prefixes used by the engine for sub mesh draw wrappers\r\n     */\r\n\r\n    /** @internal */\r\n    public static readonly RENDERPASS_MAIN = 0;\r\n\r\n    /**\r\n     * Constant used as key code for Alt key\r\n     */\r\n    public static readonly INPUT_ALT_KEY = 18;\r\n\r\n    /**\r\n     * Constant used as key code for Ctrl key\r\n     */\r\n    public static readonly INPUT_CTRL_KEY = 17;\r\n\r\n    /**\r\n     * Constant used as key code for Meta key (Left Win, Left Cmd)\r\n     */\r\n    public static readonly INPUT_META_KEY1 = 91;\r\n\r\n    /**\r\n     * Constant used as key code for Meta key (Right Win)\r\n     */\r\n    public static readonly INPUT_META_KEY2 = 92;\r\n\r\n    /**\r\n     * Constant used as key code for Meta key (Right Win, Right Cmd)\r\n     */\r\n    public static readonly INPUT_META_KEY3 = 93;\r\n\r\n    /**\r\n     * Constant used as key code for Shift key\r\n     */\r\n    public static readonly INPUT_SHIFT_KEY = 16;\r\n\r\n    /** Standard snapshot rendering. In this mode, some form of dynamic behavior is possible (for eg, uniform buffers are still updated) */\r\n    public static readonly SNAPSHOTRENDERING_STANDARD = 0;\r\n\r\n    /** Fast snapshot rendering. In this mode, everything is static and only some limited form of dynamic behaviour is possible */\r\n    public static readonly SNAPSHOTRENDERING_FAST = 1;\r\n\r\n    /**\r\n     * This is the default projection mode used by the cameras.\r\n     * It helps recreating a feeling of perspective and better appreciate depth.\r\n     * This is the best way to simulate real life cameras.\r\n     */\r\n    public static readonly PERSPECTIVE_CAMERA = 0;\r\n    /**\r\n     * This helps creating camera with an orthographic mode.\r\n     * Orthographic is commonly used in engineering as a means to produce object specifications that communicate dimensions unambiguously, each line of 1 unit length (cm, meter..whatever) will appear to have the same length everywhere on the drawing. This allows the drafter to dimension only a subset of lines and let the reader know that other lines of that length on the drawing are also that length in reality. Every parallel line in the drawing is also parallel in the object.\r\n     */\r\n    public static readonly ORTHOGRAPHIC_CAMERA = 1;\r\n\r\n    /**\r\n     * This is the default FOV mode for perspective cameras.\r\n     * This setting aligns the upper and lower bounds of the viewport to the upper and lower bounds of the camera frustum.\r\n     */\r\n    public static readonly FOVMODE_VERTICAL_FIXED = 0;\r\n    /**\r\n     * This setting aligns the left and right bounds of the viewport to the left and right bounds of the camera frustum.\r\n     */\r\n    public static readonly FOVMODE_HORIZONTAL_FIXED = 1;\r\n\r\n    /**\r\n     * This specifies there is no need for a camera rig.\r\n     * Basically only one eye is rendered corresponding to the camera.\r\n     */\r\n    public static readonly RIG_MODE_NONE = 0;\r\n    /**\r\n     * Simulates a camera Rig with one blue eye and one red eye.\r\n     * This can be use with 3d blue and red glasses.\r\n     */\r\n    public static readonly RIG_MODE_STEREOSCOPIC_ANAGLYPH = 10;\r\n    /**\r\n     * Defines that both eyes of the camera will be rendered side by side with a parallel target.\r\n     */\r\n    public static readonly RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL = 11;\r\n    /**\r\n     * Defines that both eyes of the camera will be rendered side by side with a none parallel target.\r\n     */\r\n    public static readonly RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED = 12;\r\n    /**\r\n     * Defines that both eyes of the camera will be rendered over under each other.\r\n     */\r\n    public static readonly RIG_MODE_STEREOSCOPIC_OVERUNDER = 13;\r\n    /**\r\n     * Defines that both eyes of the camera will be rendered on successive lines interlaced for passive 3d monitors.\r\n     */\r\n    public static readonly RIG_MODE_STEREOSCOPIC_INTERLACED = 14;\r\n    /**\r\n     * Defines that both eyes of the camera should be renderered in a VR mode (carbox).\r\n     */\r\n    public static readonly RIG_MODE_VR = 20;\r\n    /**\r\n     * Custom rig mode allowing rig cameras to be populated manually with any number of cameras\r\n     */\r\n    public static readonly RIG_MODE_CUSTOM = 22;\r\n\r\n    /**\r\n     * Maximum number of uv sets supported\r\n     */\r\n    public static readonly MAX_SUPPORTED_UV_SETS = 6;\r\n\r\n    /**\r\n     * GL constants\r\n     */\r\n    /** Alpha blend equation: ADD */\r\n    public static readonly GL_ALPHA_EQUATION_ADD = 0x8006;\r\n    /** Alpha equation: MIN */\r\n    public static readonly GL_ALPHA_EQUATION_MIN = 0x8007;\r\n    /** Alpha equation: MAX */\r\n    public static readonly GL_ALPHA_EQUATION_MAX = 0x8008;\r\n    /** Alpha equation: SUBTRACT */\r\n    public static readonly GL_ALPHA_EQUATION_SUBTRACT = 0x800a;\r\n    /** Alpha equation: REVERSE_SUBTRACT */\r\n    public static readonly GL_ALPHA_EQUATION_REVERSE_SUBTRACT = 0x800b;\r\n\r\n    /** Alpha blend function: SRC */\r\n    public static readonly GL_ALPHA_FUNCTION_SRC = 0x0300;\r\n    /** Alpha blend function: ONE_MINUS_SRC */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR = 0x0301;\r\n    /** Alpha blend function: SRC_ALPHA */\r\n    public static readonly GL_ALPHA_FUNCTION_SRC_ALPHA = 0x0302;\r\n    /** Alpha blend function: ONE_MINUS_SRC_ALPHA */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA = 0x0303;\r\n    /** Alpha blend function: DST_ALPHA */\r\n    public static readonly GL_ALPHA_FUNCTION_DST_ALPHA = 0x0304;\r\n    /** Alpha blend function: ONE_MINUS_DST_ALPHA */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_DST_ALPHA = 0x0305;\r\n    /** Alpha blend function: ONE_MINUS_DST */\r\n    public static readonly GL_ALPHA_FUNCTION_DST_COLOR = 0x0306;\r\n    /** Alpha blend function: ONE_MINUS_DST */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_DST_COLOR = 0x0307;\r\n    /** Alpha blend function: SRC_ALPHA_SATURATED */\r\n    public static readonly GL_ALPHA_FUNCTION_SRC_ALPHA_SATURATED = 0x0308;\r\n    /** Alpha blend function: CONSTANT */\r\n    public static readonly GL_ALPHA_FUNCTION_CONSTANT_COLOR = 0x8001;\r\n    /** Alpha blend function: ONE_MINUS_CONSTANT */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_COLOR = 0x8002;\r\n    /** Alpha blend function: CONSTANT_ALPHA */\r\n    public static readonly GL_ALPHA_FUNCTION_CONSTANT_ALPHA = 0x8003;\r\n    /** Alpha blend function: ONE_MINUS_CONSTANT_ALPHA */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_ALPHA = 0x8004;\r\n    /** Alpha blend function: SRC1 */\r\n    public static readonly GL_ALPHA_FUNCTION_SRC1_COLOR = 0x88f9;\r\n    /** Alpha blend function: SRC1 */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_SRC1_COLOR = 0x88fa;\r\n    /** Alpha blend function: SRC1 */\r\n    public static readonly GL_ALPHA_FUNCTION_SRC1_ALPHA = 0x8589;\r\n    /** Alpha blend function: SRC1 */\r\n    public static readonly GL_ALPHA_FUNCTION_ONE_MINUS_SRC1_ALPHA = 0x88fb;\r\n\r\n    /** URL to the snippet server. Points to the public snippet server by default */\r\n    public static SnippetUrl = \"https://snippet.babylonjs.com\";\r\n\r\n    /** The fog is deactivated */\r\n    public static FOGMODE_NONE = 0;\r\n    /** The fog density is following an exponential function */\r\n    public static FOGMODE_EXP = 1;\r\n    /** The fog density is following an exponential function faster than FOGMODE_EXP */\r\n    public static FOGMODE_EXP2 = 2;\r\n    /** The fog density is following a linear function. */\r\n    public static FOGMODE_LINEAR = 3;\r\n\r\n    /**\r\n     * The byte type.\r\n     */\r\n    public static BYTE = 5120;\r\n\r\n    /**\r\n     * The unsigned byte type.\r\n     */\r\n    public static UNSIGNED_BYTE = 5121;\r\n\r\n    /**\r\n     * The short type.\r\n     */\r\n    public static SHORT = 5122;\r\n\r\n    /**\r\n     * The unsigned short type.\r\n     */\r\n    public static UNSIGNED_SHORT = 5123;\r\n\r\n    /**\r\n     * The integer type.\r\n     */\r\n    public static INT = 5124;\r\n\r\n    /**\r\n     * The unsigned integer type.\r\n     */\r\n    public static UNSIGNED_INT = 5125;\r\n\r\n    /**\r\n     * The float type.\r\n     */\r\n    public static FLOAT = 5126;\r\n\r\n    /**\r\n     * The half float type.\r\n     */\r\n    public static HALF_FLOAT = 5131;\r\n\r\n    /**\r\n     * Positions\r\n     */\r\n    public static PositionKind = \"position\";\r\n    /**\r\n     * Normals\r\n     */\r\n    public static NormalKind = \"normal\";\r\n    /**\r\n     * Tangents\r\n     */\r\n    public static TangentKind = \"tangent\";\r\n    /**\r\n     * Texture coordinates\r\n     */\r\n    public static UVKind = \"uv\";\r\n    /**\r\n     * Texture coordinates 2\r\n     */\r\n    public static UV2Kind = \"uv2\";\r\n    /**\r\n     * Texture coordinates 3\r\n     */\r\n    public static UV3Kind = \"uv3\";\r\n    /**\r\n     * Texture coordinates 4\r\n     */\r\n    public static UV4Kind = \"uv4\";\r\n    /**\r\n     * Texture coordinates 5\r\n     */\r\n    public static UV5Kind = \"uv5\";\r\n    /**\r\n     * Texture coordinates 6\r\n     */\r\n    public static UV6Kind = \"uv6\";\r\n    /**\r\n     * Colors\r\n     */\r\n    public static ColorKind = \"color\";\r\n    /**\r\n     * Instance Colors\r\n     */\r\n    public static ColorInstanceKind = \"instanceColor\";\r\n    /**\r\n     * Matrix indices (for bones)\r\n     */\r\n    public static MatricesIndicesKind = \"matricesIndices\";\r\n    /**\r\n     * Matrix weights (for bones)\r\n     */\r\n    public static MatricesWeightsKind = \"matricesWeights\";\r\n    /**\r\n     * Additional matrix indices (for bones)\r\n     */\r\n    public static MatricesIndicesExtraKind = \"matricesIndicesExtra\";\r\n    /**\r\n     * Additional matrix weights (for bones)\r\n     */\r\n    public static MatricesWeightsExtraKind = \"matricesWeightsExtra\";\r\n\r\n    // Animation type\r\n    /**\r\n     * Float animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_FLOAT = 0;\r\n    /**\r\n     * Vector3 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_VECTOR3 = 1;\r\n    /**\r\n     * Quaternion animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_QUATERNION = 2;\r\n    /**\r\n     * Matrix animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_MATRIX = 3;\r\n    /**\r\n     * Color3 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_COLOR3 = 4;\r\n    /**\r\n     * Color3 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_COLOR4 = 7;\r\n    /**\r\n     * Vector2 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_VECTOR2 = 5;\r\n    /**\r\n     * Size animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_SIZE = 6;\r\n\r\n    /**\r\n     * The default minZ value for the near plane of a frustum light\r\n     */\r\n    public static ShadowMinZ = 0;\r\n    /**\r\n     * The default maxZ value for the far plane of a frustum light\r\n     */\r\n    public static ShadowMaxZ = 10000;\r\n\r\n    /**\r\n     * Used for Selection Outline Layer sampling methods\r\n     *\r\n     * Optimized brute force 3 directional sampling\r\n     *\r\n     * This method uses 1 center sample and 3 additional samples to compute the outline mask\r\n     * It is optimized but may produce artifacts when the outline thickness is set to high values.\r\n     */\r\n    public static readonly OUTLINELAYER_SAMPLING_TRIDIRECTIONAL = 0;\r\n\r\n    /**\r\n     * Used for Selection Outline Layer sampling methods\r\n     *\r\n     * Brute force 8 directional sampling\r\n     *\r\n     * This method uses 1 center sample and 8 additional samples to compute the outline mask\r\n     * It is more precise but less optimized.\r\n     */\r\n    public static readonly OUTLINELAYER_SAMPLING_OCTADIRECTIONAL = 1;\r\n}\r\n","import { type IDisposable } from \"../scene\";\r\nimport { type IActionEvent } from \"./actionEvent\";\r\nimport { type IAction } from \"./action\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * Abstract class used to decouple action Manager from scene and meshes.\r\n * Do not instantiate.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport abstract class AbstractActionManager implements IDisposable {\r\n    /** Gets the list of active triggers */\r\n    public static Triggers: { [key: string]: number } = {};\r\n\r\n    /** Gets the cursor to use when hovering items */\r\n    public hoverCursor: string = \"\";\r\n\r\n    /** Gets the list of actions */\r\n    public actions: IAction[] = [];\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the manager is recursive meaning that it can trigger action from children\r\n     */\r\n    public isRecursive = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if this ActionManager should be disposed once the last Mesh using it is disposed\r\n     */\r\n    public disposeWhenUnowned = true;\r\n\r\n    /**\r\n     * Releases all associated resources\r\n     */\r\n    public abstract dispose(): void;\r\n\r\n    /**\r\n     * Does this action manager has pointer triggers\r\n     */\r\n    public abstract get hasPointerTriggers(): boolean;\r\n\r\n    /**\r\n     * Does this action manager has pick triggers\r\n     */\r\n    public abstract get hasPickTriggers(): boolean;\r\n\r\n    /**\r\n     * Process a specific trigger\r\n     * @param trigger defines the trigger to process\r\n     * @param evt defines the event details to be processed\r\n     */\r\n    public abstract processTrigger(trigger: number, evt?: IActionEvent): void;\r\n\r\n    /**\r\n     * Does this action manager handles actions of any of the given triggers\r\n     * @param triggers defines the triggers to be tested\r\n     * @returns a boolean indicating whether one (or more) of the triggers is handled\r\n     */\r\n    public abstract hasSpecificTriggers(triggers: number[]): boolean;\r\n\r\n    /**\r\n     * Does this action manager handles actions of any of the given triggers. This function takes two arguments for\r\n     * speed.\r\n     * @param triggerA defines the trigger to be tested\r\n     * @param triggerB defines the trigger to be tested\r\n     * @returns a boolean indicating whether one (or more) of the triggers is handled\r\n     */\r\n    public abstract hasSpecificTriggers2(triggerA: number, triggerB: number): boolean;\r\n\r\n    /**\r\n     * Does this action manager handles actions of a given trigger\r\n     * @param trigger defines the trigger to be tested\r\n     * @param parameterPredicate defines an optional predicate to filter triggers by parameter\r\n     * @returns whether the trigger is handled\r\n     */\r\n    public abstract hasSpecificTrigger(trigger: number, parameterPredicate?: (parameter: any) => boolean): boolean;\r\n\r\n    /**\r\n     * Serialize this manager to a JSON object\r\n     * @param name defines the property name to store this manager\r\n     * @returns a JSON representation of this manager\r\n     */\r\n    public abstract serialize(name: string): any;\r\n\r\n    /**\r\n     * Registers an action to this action manager\r\n     * @param action defines the action to be registered\r\n     * @returns the action amended (prepared) after registration\r\n     */\r\n    public abstract registerAction(action: IAction): Nullable<IAction>;\r\n\r\n    /**\r\n     * Unregisters an action to this action manager\r\n     * @param action defines the action to be unregistered\r\n     * @returns a boolean indicating whether the action has been unregistered\r\n     */\r\n    public abstract unregisterAction(action: IAction): boolean;\r\n\r\n    /**\r\n     * Does exist one action manager with at least one trigger\r\n     **/\r\n    public static get HasTriggers(): boolean {\r\n        for (const t in AbstractActionManager.Triggers) {\r\n            if (Object.prototype.hasOwnProperty.call(AbstractActionManager.Triggers, t)) {\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Does exist one action manager with at least one pick trigger\r\n     **/\r\n    public static get HasPickTriggers(): boolean {\r\n        for (const t in AbstractActionManager.Triggers) {\r\n            if (Object.prototype.hasOwnProperty.call(AbstractActionManager.Triggers, t)) {\r\n                const tAsInt = parseInt(t);\r\n                if (tAsInt >= Constants.ACTION_OnPickTrigger && tAsInt <= Constants.ACTION_OnPickUpTrigger) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Does exist one action manager that handles actions of a given trigger\r\n     * @param trigger defines the trigger to be tested\r\n     * @returns a boolean indicating whether the trigger is handled by at least one action manager\r\n     **/\r\n    public static HasSpecificTrigger(trigger: number): boolean {\r\n        for (const t in AbstractActionManager.Triggers) {\r\n            if (Object.prototype.hasOwnProperty.call(AbstractActionManager.Triggers, t)) {\r\n                const tAsInt = parseInt(t);\r\n                if (tAsInt === trigger) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\n\r\ndeclare const WeakRef: any;\r\n\r\nconst IsWeakRefSupported = typeof WeakRef !== \"undefined\";\r\n\r\n/**\r\n * A class serves as a medium between the observable and its observers\r\n */\r\nexport class EventState {\r\n    /**\r\n     * Create a new EventState\r\n     * @param mask defines the mask associated with this state\r\n     * @param skipNextObservers defines a flag which will instruct the observable to skip following observers when set to true\r\n     * @param target defines the original target of the state\r\n     * @param currentTarget defines the current target of the state\r\n     */\r\n    constructor(mask: number, skipNextObservers = false, target?: any, currentTarget?: any) {\r\n        this.initialize(mask, skipNextObservers, target, currentTarget);\r\n    }\r\n\r\n    /**\r\n     * Initialize the current event state\r\n     * @param mask defines the mask associated with this state\r\n     * @param skipNextObservers defines a flag which will instruct the observable to skip following observers when set to true\r\n     * @param target defines the original target of the state\r\n     * @param currentTarget defines the current target of the state\r\n     * @returns the current event state\r\n     */\r\n    public initialize(mask: number, skipNextObservers = false, target?: any, currentTarget?: any): EventState {\r\n        this.mask = mask;\r\n        this.skipNextObservers = skipNextObservers;\r\n        this.target = target;\r\n        this.currentTarget = currentTarget;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * An Observer can set this property to true to prevent subsequent observers of being notified\r\n     */\r\n    public skipNextObservers: boolean;\r\n\r\n    /**\r\n     * Get the mask value that were used to trigger the event corresponding to this EventState object\r\n     */\r\n    public mask: number;\r\n\r\n    /**\r\n     * The object that originally notified the event\r\n     */\r\n    public target?: any;\r\n\r\n    /**\r\n     * The current object in the bubbling phase\r\n     */\r\n    public currentTarget?: any;\r\n\r\n    /**\r\n     * This will be populated with the return value of the last function that was executed.\r\n     * If it is the first function in the callback chain it will be the event data.\r\n     */\r\n    public lastReturnValue?: any;\r\n\r\n    /**\r\n     * User defined information that will be sent to observers\r\n     */\r\n    public userInfo?: any;\r\n}\r\n\r\n/**\r\n * Represent an observer registered to a given IObservable object.\r\n */\r\nexport interface IObserver {\r\n    /**\r\n     * Remove the observer from its observable\r\n     * @param defer if true, the removal will be deferred to avoid callback skipping (default: false)\r\n     */\r\n    remove(defer?: boolean): void;\r\n}\r\n\r\n/**\r\n * Represent an observer registered to a given Observable object.\r\n */\r\nexport class Observer<T> implements IObserver {\r\n    /** @internal */\r\n    public _willBeUnregistered = false;\r\n    /**\r\n     * Gets or sets a property defining that the observer as to be unregistered after the next notification\r\n     */\r\n    public unregisterOnNextCall = false;\r\n\r\n    /**\r\n     * this function can be used to remove the observer from the observable.\r\n     * It will be set by the observable that the observer belongs to.\r\n     * @internal\r\n     */\r\n    public _remove: Nullable<(defer?: boolean) => void> = null;\r\n\r\n    /**\r\n     * Creates a new observer\r\n     * @param callback defines the callback to call when the observer is notified\r\n     * @param mask defines the mask of the observer (used to filter notifications)\r\n     * @param scope defines the current scope used to restore the JS context\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the callback to call when the observer is notified\r\n         */\r\n        public callback: (eventData: T, eventState: EventState) => void,\r\n        /**\r\n         * Defines the mask of the observer (used to filter notifications)\r\n         */\r\n        public mask: number,\r\n        /**\r\n         * [null] Defines the current scope used to restore the JS context\r\n         */\r\n        public scope: any = null\r\n    ) {}\r\n\r\n    /**\r\n     * Remove the observer from its observable\r\n     * This can be used instead of using the observable's remove function.\r\n     * @param defer if true, the removal will be deferred to avoid callback skipping (default: false)\r\n     */\r\n    public remove(defer = false) {\r\n        if (this._remove) {\r\n            this._remove(defer);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * An interface that defines the reader side of an Observable (receive notifications).\r\n */\r\nexport interface IReadonlyObservable<T = unknown> {\r\n    /**\r\n     * Create a new Observer with the specified callback\r\n     * @param callback the callback that will be executed for that Observer\r\n     * @param mask the mask used to filter observers\r\n     * @param insertFirst if true the callback will be inserted at the first position, hence executed before the others ones. If false (default behavior) the callback will be inserted at the last position, executed after all the others already present.\r\n     * @param scope optional scope for the callback to be called from\r\n     * @param unregisterOnFirstCall defines if the observer as to be unregistered after the next notification\r\n     * @returns the new observer created for the callback\r\n     */\r\n    add(callback: (eventData: T, eventState: EventState) => void, mask?: number, insertFirst?: boolean, scope?: unknown, unregisterOnFirstCall?: boolean): IObserver;\r\n\r\n    /**\r\n     * Create a new Observer with the specified callback and unregisters after the next notification\r\n     * @param callback the callback that will be executed for that Observer\r\n     * @returns the new observer created for the callback\r\n     */\r\n    addOnce(callback: (eventData: T, eventState: EventState) => void): IObserver;\r\n}\r\n\r\n/**\r\n * The Observable class is a simple implementation of the Observable pattern.\r\n *\r\n * There's one slight particularity though: a given Observable can notify its observer using a particular mask value, only the Observers registered with this mask value will be notified.\r\n * This enable a more fine grained execution without having to rely on multiple different Observable objects.\r\n * For instance you may have a given Observable that have four different types of notifications: Move (mask = 0x01), Stop (mask = 0x02), Turn Right (mask = 0X04), Turn Left (mask = 0X08).\r\n * A given observer can register itself with only Move and Stop (mask = 0x03), then it will only be notified when one of these two occurs and will never be for Turn Left/Right.\r\n */\r\nexport class Observable<T> implements IReadonlyObservable<T> {\r\n    private _observers = new Array<Observer<T>>();\r\n    private _numObserversMarkedAsDeleted = 0;\r\n    private _hasNotified = false;\r\n    private _lastNotifiedValue?: T;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _eventState: EventState;\r\n\r\n    private _onObserverAdded: Nullable<(observer: Observer<T>) => void>;\r\n\r\n    /**\r\n     * Create an observable from a Promise.\r\n     * @param promise a promise to observe for fulfillment.\r\n     * @param onErrorObservable an observable to notify if a promise was rejected.\r\n     * @returns the new Observable\r\n     */\r\n    public static FromPromise<T, E = Error>(promise: Promise<T>, onErrorObservable?: Observable<E>): Observable<T> {\r\n        const observable = new Observable<T>();\r\n\r\n        promise\r\n            // eslint-disable-next-line github/no-then\r\n            .then((ret: T) => {\r\n                observable.notifyObservers(ret);\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .catch((err) => {\r\n                if (onErrorObservable) {\r\n                    onErrorObservable.notifyObservers(err as E);\r\n                } else {\r\n                    throw err;\r\n                }\r\n            });\r\n\r\n        return observable;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of observers\r\n     * Note that observers that were recently deleted may still be present in the list because they are only really deleted on the next javascript tick!\r\n     */\r\n    public get observers(): Array<Observer<T>> {\r\n        return this._observers;\r\n    }\r\n\r\n    /**\r\n     * Creates a new observable\r\n     * @param onObserverAdded defines a callback to call when a new observer is added\r\n     * @param notifyIfTriggered If set to true the observable will notify when an observer was added if the observable was already triggered.\r\n     */\r\n    constructor(\r\n        onObserverAdded?: (observer: Observer<T>) => void,\r\n        /**\r\n         * [false] If set to true the observable will notify when an observer was added if the observable was already triggered.\r\n         * This is helpful to single-state observables like the scene onReady or the dispose observable.\r\n         */\r\n        public notifyIfTriggered = false\r\n    ) {\r\n        this._eventState = new EventState(0);\r\n\r\n        if (onObserverAdded) {\r\n            this._onObserverAdded = onObserverAdded;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a new Observer with the specified callback\r\n     * @param callback the callback that will be executed for that Observer\r\n     * @param mask the mask used to filter observers\r\n     * @param insertFirst if true the callback will be inserted at the first position, hence executed before the others ones. If false (default behavior) the callback will be inserted at the last position, executed after all the others already present.\r\n     * @param scope optional scope for the callback to be called from\r\n     * @param unregisterOnFirstCall defines if the observer as to be unregistered after the next notification\r\n     * @returns the new observer created for the callback\r\n     */\r\n    public add(callback?: null, mask?: number, insertFirst?: boolean, scope?: any, unregisterOnFirstCall?: boolean): null;\r\n    public add(callback: (eventData: T, eventState: EventState) => void, mask?: number, insertFirst?: boolean, scope?: any, unregisterOnFirstCall?: boolean): Observer<T>;\r\n    public add(\r\n        callback?: ((eventData: T, eventState: EventState) => void) | null,\r\n        mask?: number,\r\n        insertFirst?: boolean,\r\n        scope?: any,\r\n        unregisterOnFirstCall?: boolean\r\n    ): Nullable<Observer<T>>;\r\n    public add(\r\n        callback?: ((eventData: T, eventState: EventState) => void) | null,\r\n        mask: number = -1,\r\n        insertFirst = false,\r\n        scope: any = null,\r\n        unregisterOnFirstCall = false\r\n    ): Nullable<Observer<T>> {\r\n        if (!callback) {\r\n            return null;\r\n        }\r\n\r\n        const observer = new Observer(callback, mask, scope);\r\n        observer.unregisterOnNextCall = unregisterOnFirstCall;\r\n\r\n        if (insertFirst) {\r\n            this._observers.unshift(observer);\r\n        } else {\r\n            this._observers.push(observer);\r\n        }\r\n\r\n        if (this._onObserverAdded) {\r\n            this._onObserverAdded(observer);\r\n        }\r\n\r\n        // If the observable was already triggered and the observable is set to notify if triggered, notify the new observer\r\n        if (this._hasNotified && this.notifyIfTriggered) {\r\n            this.notifyObserver(observer, this._lastNotifiedValue as T);\r\n        }\r\n\r\n        // attach the remove function to the observer\r\n        const observableWeakRef = IsWeakRefSupported ? new WeakRef(this) : { deref: () => this };\r\n        observer._remove = (defer = false) => {\r\n            const observable = observableWeakRef.deref();\r\n            if (observable) {\r\n                defer ? observable.remove(observer) : observable._remove(observer);\r\n            }\r\n        };\r\n\r\n        return observer;\r\n    }\r\n\r\n    /**\r\n     * Create a new Observer with the specified callback and unregisters after the next notification\r\n     * @param callback the callback that will be executed for that Observer\r\n     * @returns the new observer created for the callback\r\n     */\r\n    public addOnce(callback?: null): null;\r\n    public addOnce(callback: (eventData: T, eventState: EventState) => void): Observer<T>;\r\n    public addOnce(callback?: ((eventData: T, eventState: EventState) => void) | null): Nullable<Observer<T>>;\r\n    public addOnce(callback?: ((eventData: T, eventState: EventState) => void) | null): Nullable<Observer<T>> {\r\n        return this.add(callback, undefined, undefined, undefined, true);\r\n    }\r\n\r\n    /**\r\n     * Remove an Observer from the Observable object\r\n     * @param observer the instance of the Observer to remove\r\n     * @returns false if it doesn't belong to this Observable\r\n     */\r\n    public remove(observer: Nullable<Observer<T>>): boolean {\r\n        if (!observer) {\r\n            return false;\r\n        }\r\n\r\n        observer._remove = null;\r\n        const index = this._observers.indexOf(observer);\r\n\r\n        if (index !== -1) {\r\n            this._deferUnregister(observer);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Remove a callback from the Observable object\r\n     * @param callback the callback to remove\r\n     * @param scope optional scope. If used only the callbacks with this scope will be removed\r\n     * @returns false if it doesn't belong to this Observable\r\n     */\r\n    public removeCallback(callback: (eventData: T, eventState: EventState) => void, scope?: any): boolean {\r\n        for (let index = 0; index < this._observers.length; index++) {\r\n            const observer = this._observers[index];\r\n            if (observer._willBeUnregistered) {\r\n                continue;\r\n            }\r\n            if (observer.callback === callback && (!scope || scope === observer.scope)) {\r\n                this._deferUnregister(observer);\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _deferUnregister(observer: Observer<T>): void {\r\n        if (observer._willBeUnregistered) {\r\n            return;\r\n        }\r\n        this._numObserversMarkedAsDeleted++;\r\n        observer.unregisterOnNextCall = false;\r\n        observer._willBeUnregistered = true;\r\n        setTimeout(() => {\r\n            this._remove(observer);\r\n        }, 0);\r\n    }\r\n\r\n    // This should only be called when not iterating over _observers to avoid callback skipping.\r\n    // Removes an observer from the _observer Array.\r\n    private _remove(observer: Nullable<Observer<T>>, updateCounter = true): boolean {\r\n        if (!observer) {\r\n            return false;\r\n        }\r\n\r\n        const index = this._observers.indexOf(observer);\r\n\r\n        if (index !== -1) {\r\n            if (updateCounter) {\r\n                this._numObserversMarkedAsDeleted--;\r\n            }\r\n            this._observers.splice(index, 1);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Moves the observable to the top of the observer list making it get called first when notified\r\n     * @param observer the observer to move\r\n     */\r\n    public makeObserverTopPriority(observer: Observer<T>) {\r\n        this._remove(observer, false);\r\n        this._observers.unshift(observer);\r\n    }\r\n\r\n    /**\r\n     * Moves the observable to the bottom of the observer list making it get called last when notified\r\n     * @param observer the observer to move\r\n     */\r\n    public makeObserverBottomPriority(observer: Observer<T>) {\r\n        this._remove(observer, false);\r\n        this._observers.push(observer);\r\n    }\r\n\r\n    /**\r\n     * Notify all Observers by calling their respective callback with the given data\r\n     * Will return true if all observers were executed, false if an observer set skipNextObservers to true, then prevent the subsequent ones to execute\r\n     * @param eventData defines the data to send to all observers\r\n     * @param mask defines the mask of the current notification (observers with incompatible mask (ie mask & observer.mask === 0) will not be notified)\r\n     * @param target defines the original target of the state\r\n     * @param currentTarget defines the current target of the state\r\n     * @param userInfo defines any user info to send to observers\r\n     * @returns false if the complete observer chain was not processed (because one observer set the skipNextObservers to true)\r\n     */\r\n    public notifyObservers(eventData: T, mask: number = -1, target?: any, currentTarget?: any, userInfo?: any): boolean {\r\n        // this prevents potential memory leaks - if an object is disposed but the observable doesn't get cleared.\r\n        if (this.notifyIfTriggered) {\r\n            this._hasNotified = true;\r\n            this._lastNotifiedValue = eventData;\r\n        }\r\n        if (!this._observers.length) {\r\n            return true;\r\n        }\r\n\r\n        const state = this._eventState;\r\n        state.mask = mask;\r\n        state.target = target;\r\n        state.currentTarget = currentTarget;\r\n        state.skipNextObservers = false;\r\n        state.lastReturnValue = eventData;\r\n        state.userInfo = userInfo;\r\n\r\n        for (const obs of this._observers) {\r\n            if (obs._willBeUnregistered) {\r\n                continue;\r\n            }\r\n\r\n            if (obs.mask & mask) {\r\n                if (obs.unregisterOnNextCall) {\r\n                    this._deferUnregister(obs);\r\n                }\r\n\r\n                if (obs.scope) {\r\n                    state.lastReturnValue = obs.callback.apply(obs.scope, [eventData, state]);\r\n                } else {\r\n                    state.lastReturnValue = obs.callback(eventData, state);\r\n                }\r\n            }\r\n            if (state.skipNextObservers) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Notify a specific observer\r\n     * @param observer defines the observer to notify\r\n     * @param eventData defines the data to be sent to each callback\r\n     * @param mask is used to filter observers defaults to -1\r\n     */\r\n    public notifyObserver(observer: Observer<T>, eventData: T, mask: number = -1): void {\r\n        // this prevents potential memory leaks - if an object is disposed but the observable doesn't get cleared.\r\n        if (this.notifyIfTriggered) {\r\n            this._hasNotified = true;\r\n            this._lastNotifiedValue = eventData;\r\n        }\r\n        if (observer._willBeUnregistered) {\r\n            return;\r\n        }\r\n\r\n        const state = this._eventState;\r\n        state.mask = mask;\r\n        state.skipNextObservers = false;\r\n\r\n        if (observer.unregisterOnNextCall) {\r\n            this._deferUnregister(observer);\r\n        }\r\n\r\n        observer.callback(eventData, state);\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the observable has at least one observer\r\n     * @returns true is the Observable has at least one Observer registered\r\n     */\r\n    public hasObservers(): boolean {\r\n        return this._observers.length - this._numObserversMarkedAsDeleted > 0;\r\n    }\r\n\r\n    /**\r\n     * Clear the list of observers\r\n     */\r\n    public clear(): void {\r\n        while (this._observers.length) {\r\n            const o = this._observers.pop();\r\n            if (o) {\r\n                o._remove = null;\r\n            }\r\n        }\r\n        this._onObserverAdded = null;\r\n        this._numObserversMarkedAsDeleted = 0;\r\n        this.cleanLastNotifiedState();\r\n    }\r\n\r\n    /**\r\n     * Clean the last notified state - both the internal last value and the has-notified flag\r\n     */\r\n    public cleanLastNotifiedState(): void {\r\n        this._hasNotified = false;\r\n        this._lastNotifiedValue = undefined;\r\n    }\r\n\r\n    /**\r\n     * Clone the current observable\r\n     * @returns a new observable\r\n     */\r\n    public clone(): Observable<T> {\r\n        const result = new Observable<T>();\r\n\r\n        result._observers = this._observers.slice(0);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Does this observable handles observer registered with a given mask\r\n     * @param mask defines the mask to be tested\r\n     * @returns whether or not one observer registered with the given mask is handled\r\n     **/\r\n    public hasSpecificMask(mask: number = -1): boolean {\r\n        for (const obs of this._observers) {\r\n            if (obs.mask & mask || obs.mask === mask) {\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n}\r\n","/**\r\n * Constant used to convert a value to gamma space\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const ToGammaSpace = 1 / 2.2;\r\n\r\n/**\r\n * Constant used to convert a value to linear space\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const ToLinearSpace = 2.2;\r\n\r\n/**\r\n * Constant Golden Ratio value in Babylon.js\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const PHI = (1 + Math.sqrt(5)) / 2;\r\n\r\n/**\r\n * Constant used to define the minimal number value in Babylon.js\r\n * Exported as \"let\" so advanced users can override the epsilon value in supported build targets (for example via the global BABYLON.Epsilon)\r\n * @ignorenaming\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention, prefer-const\r\nexport let Epsilon = 0.001;\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\nimport { type Nullable, type Tuple } from \"../types\";\r\n\r\n/**\r\n * Returns an array of the given size filled with elements built from the given constructor and the parameters.\r\n * @param size the number of element to construct and put in the array.\r\n * @param itemBuilder a callback responsible for creating new instance of item. Called once per array entry.\r\n * @returns a new array filled with new objects.\r\n */\r\nexport function BuildArray<T>(size: number, itemBuilder: () => T): Array<T> {\r\n    const a: T[] = [];\r\n    for (let i = 0; i < size; ++i) {\r\n        a.push(itemBuilder());\r\n    }\r\n    return a;\r\n}\r\n\r\n/**\r\n * Returns a tuple of the given size filled with elements built from the given constructor and the parameters.\r\n * @param size he number of element to construct and put in the tuple.\r\n * @param itemBuilder a callback responsible for creating new instance of item. Called once per tuple entry.\r\n * @returns a new tuple filled with new objects.\r\n */\r\nexport function BuildTuple<T, N extends number>(size: N, itemBuilder: () => T): Tuple<T, N> {\r\n    return BuildArray(size, itemBuilder) as Tuple<T, N>;\r\n}\r\n\r\n/**\r\n * Defines the callback type used when an observed array function is triggered.\r\n * @internal\r\n */\r\nexport type _ObserveCallback = (functionName: string, previousLength: number) => void;\r\n\r\n/**\r\n * Observes a function and calls the given callback when it is called.\r\n * @param object Defines the object the function to observe belongs to.\r\n * @param functionName Defines the name of the function to observe.\r\n * @param callback Defines the callback to call when the function is called.\r\n * @returns A function to call to stop observing\r\n */\r\nfunction ObserveArrayFunction(object: { [key: string]: any }, functionName: string, callback: _ObserveCallback): Nullable<() => void> {\r\n    // Finds the function to observe\r\n    const oldFunction = object[functionName];\r\n    if (typeof oldFunction !== \"function\") {\r\n        return null;\r\n    }\r\n\r\n    // Creates a new function that calls the callback and the old function\r\n    const newFunction = function () {\r\n        const previousLength = object.length;\r\n        const returnValue = newFunction.previous.apply(object, arguments);\r\n        callback(functionName, previousLength);\r\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\r\n        return returnValue;\r\n    } as any;\r\n\r\n    // Doublishly links the new function and the old function\r\n    oldFunction.next = newFunction;\r\n    newFunction.previous = oldFunction;\r\n\r\n    // Replaces the old function with the new function\r\n    object[functionName] = newFunction;\r\n\r\n    // Returns a function to disable the hook\r\n    return () => {\r\n        // Only unhook if the function is still hooked\r\n        const previous = newFunction.previous;\r\n        if (!previous) {\r\n            return;\r\n        }\r\n\r\n        // Finds the ref to the next function in the chain\r\n        const next = newFunction.next;\r\n\r\n        // If in the middle of the chain, link the previous and next functions\r\n        if (next) {\r\n            previous.next = next;\r\n            next.previous = previous;\r\n        }\r\n        // If at the end of the chain, remove the reference to the previous function\r\n        // and restore the previous function\r\n        else {\r\n            previous.next = undefined;\r\n            object[functionName] = previous;\r\n        }\r\n\r\n        // Lose reference to the previous and next functions\r\n        newFunction.next = undefined;\r\n        newFunction.previous = undefined;\r\n    };\r\n}\r\n\r\n/**\r\n * Defines the list of functions to proxy when observing an array.\r\n * The scope is currently reduced to the common functions used in the render target render list and the scene cameras.\r\n */\r\nconst observedArrayFunctions = [\"push\", \"splice\", \"pop\", \"shift\", \"unshift\"];\r\n\r\n/**\r\n * Observes an array and notifies the given observer when the array is modified.\r\n * @param array Defines the array to observe\r\n * @param callback Defines the function to call when the array is modified (in the limit of the observed array functions)\r\n * @returns A function to call to stop observing the array\r\n * @internal\r\n */\r\nexport function _ObserveArray<T>(array: T[], callback: _ObserveCallback) {\r\n    // Observes all the required array functions and stores the unhook functions\r\n    const unObserveFunctions = observedArrayFunctions.map((name) => {\r\n        return ObserveArrayFunction(array, name, callback);\r\n    });\r\n\r\n    // Returns a function that unhook all the observed functions\r\n    return () => {\r\n        for (const unObserveFunction of unObserveFunctions) {\r\n            unObserveFunction?.();\r\n        }\r\n    };\r\n}\r\n","/** @internal */\r\nexport class PerformanceConfigurator {\r\n    /** @internal */\r\n    public static MatrixUse64Bits = false;\r\n    /** @internal */\r\n    public static MatrixTrackPrecisionChange = true;\r\n    /** @internal */\r\n    public static MatrixCurrentType: any = Float32Array;\r\n    /** @internal */\r\n    public static MatrixTrackedMatrices: Array<any> | null = [];\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static SetMatrixPrecision(use64bits: boolean) {\r\n        PerformanceConfigurator.MatrixTrackPrecisionChange = false;\r\n\r\n        if (use64bits && !PerformanceConfigurator.MatrixUse64Bits) {\r\n            if (PerformanceConfigurator.MatrixTrackedMatrices) {\r\n                for (let m = 0; m < PerformanceConfigurator.MatrixTrackedMatrices.length; ++m) {\r\n                    const matrix = PerformanceConfigurator.MatrixTrackedMatrices[m];\r\n                    const values = matrix._m;\r\n\r\n                    matrix._m = new Array(16);\r\n\r\n                    for (let i = 0; i < 16; ++i) {\r\n                        matrix._m[i] = values[i];\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        PerformanceConfigurator.MatrixUse64Bits = use64bits;\r\n        PerformanceConfigurator.MatrixCurrentType = PerformanceConfigurator.MatrixUse64Bits ? Array : Float32Array;\r\n        PerformanceConfigurator.MatrixTrackedMatrices = null; // reclaim some memory, as we don't need _TrackedMatrices anymore\r\n    }\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\n\r\nimport { type AbstractEngine } from \"./abstractEngine\";\r\nimport { type Scene } from \"../scene\";\r\n\r\n/**\r\n * The engine store class is responsible to hold all the instances of Engine and Scene created\r\n * during the life time of the application.\r\n */\r\nexport class EngineStore {\r\n    /** Gets the list of created engines */\r\n    public static Instances: AbstractEngine[] = [];\r\n\r\n    /**\r\n     * Notifies when an engine was disposed.\r\n     * Mainly used for static/cache cleanup\r\n     */\r\n    public static OnEnginesDisposedObservable = new Observable<AbstractEngine>();\r\n\r\n    /** @internal */\r\n    public static _LastCreatedScene: Nullable<Scene> = null;\r\n\r\n    /**\r\n     * Gets the latest created engine\r\n     */\r\n    public static get LastCreatedEngine(): Nullable<AbstractEngine> {\r\n        if (this.Instances.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        return this.Instances[this.Instances.length - 1];\r\n    }\r\n\r\n    /**\r\n     * Gets the latest created scene\r\n     */\r\n    public static get LastCreatedScene(): Nullable<Scene> {\r\n        return this._LastCreatedScene;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a global variable indicating if fallback texture must be used when a texture cannot be loaded\r\n     */\r\n    public static UseFallbackTexture = true;\r\n\r\n    /**\r\n     * Texture content used if a texture cannot loaded\r\n     */\r\n    public static FallbackTexture = \"\";\r\n}\r\n","/**\r\n * Extract int value\r\n * @param value number value\r\n * @returns int value\r\n */\r\nexport function ExtractAsInt(value: number) {\r\n    return parseInt(value.toString().replace(/\\W/g, \"\"));\r\n}\r\n\r\n/**\r\n * Boolean : true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)\r\n * @param a number\r\n * @param b number\r\n * @param epsilon (default = 1.401298E-45)\r\n * @returns true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)\r\n */\r\nexport function WithinEpsilon(a: number, b: number, epsilon: number = 1.401298e-45): boolean {\r\n    return Math.abs(a - b) <= epsilon;\r\n}\r\n\r\n/**\r\n * Boolean : true if the number is outside a range\r\n * @param num number\r\n * @param min min value\r\n * @param max max value\r\n * @param epsilon (default = Number.EPSILON)\r\n * @returns true if the number is between min and max values\r\n */\r\nexport function OutsideRange(num: number, min: number, max: number, epsilon: number = 1.401298e-45): boolean {\r\n    return num < min - epsilon || num > max + epsilon;\r\n}\r\n\r\n/**\r\n * Returns a random float number between and min and max values\r\n * @param min min value of random\r\n * @param max max value of random\r\n * @returns random value\r\n */\r\nexport function RandomRange(min: number, max: number): number {\r\n    if (min === max) {\r\n        return min;\r\n    }\r\n    return Math.random() * (max - min) + min;\r\n}\r\n\r\n/**\r\n * Creates a new scalar with values linearly interpolated of \"amount\" between the start scalar and the end scalar.\r\n * @param start start value\r\n * @param end target value\r\n * @param amount amount to lerp between\r\n * @returns the lerped value\r\n */\r\nexport function Lerp(start: number, end: number, amount: number): number {\r\n    return start + (end - start) * amount;\r\n}\r\n\r\n/**\r\n * Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.\r\n * The parameter t is clamped to the range [0, 1]. Variables a and b are assumed to be in degrees.\r\n * @param start start value\r\n * @param end target value\r\n * @param amount amount to lerp between\r\n * @returns the lerped value\r\n */\r\nexport function LerpAngle(start: number, end: number, amount: number): number {\r\n    let num: number = Repeat(end - start, 360.0);\r\n    if (num > 180.0) {\r\n        num -= 360.0;\r\n    }\r\n    return start + num * Clamp(amount);\r\n}\r\n\r\n/**\r\n * Calculates the linear parameter t that produces the interpolant value within the range [a, b].\r\n * @param a start value\r\n * @param b target value\r\n * @param value value between a and b\r\n * @returns the inverseLerp value\r\n */\r\nexport function InverseLerp(a: number, b: number, value: number): number {\r\n    let result: number;\r\n    if (a != b) {\r\n        result = Clamp((value - a) / (b - a));\r\n    } else {\r\n        result = 0.0;\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * Returns a new scalar located for \"amount\" (float) on the Hermite spline defined by the scalars \"value1\", \"value3\", \"tangent1\", \"tangent2\".\r\n * @see http://mathworld.wolfram.com/HermitePolynomial.html\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param amount defines the amount on the interpolation spline (between 0 and 1)\r\n * @returns hermite result\r\n */\r\nexport function Hermite(value1: number, tangent1: number, value2: number, tangent2: number, amount: number): number {\r\n    const squared = amount * amount;\r\n    const cubed = amount * squared;\r\n    const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n    const part2 = -2.0 * cubed + 3.0 * squared;\r\n    const part3 = cubed - 2.0 * squared + amount;\r\n    const part4 = cubed - squared;\r\n\r\n    return value1 * part1 + value2 * part2 + tangent1 * part3 + tangent2 * part4;\r\n}\r\n\r\n/**\r\n * Returns a new scalar which is the 1st derivative of the Hermite spline defined by the scalars \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\nexport function Hermite1stDerivative(value1: number, tangent1: number, value2: number, tangent2: number, time: number): number {\r\n    const t2 = time * time;\r\n    return (t2 - time) * 6 * value1 + (3 * t2 - 4 * time + 1) * tangent1 + (-t2 + time) * 6 * value2 + (3 * t2 - 2 * time) * tangent2;\r\n}\r\n\r\n/**\r\n * Returns the value itself if it's between min and max.\r\n * Returns min if the value is lower than min.\r\n * Returns max if the value is greater than max.\r\n * @param value the value to clmap\r\n * @param min the min value to clamp to (default: 0)\r\n * @param max the max value to clamp to (default: 1)\r\n * @returns the clamped value\r\n */\r\nexport function Clamp(value: number, min = 0, max = 1): number {\r\n    return Math.min(max, Math.max(min, value));\r\n}\r\n\r\n/**\r\n * Returns the angle converted to equivalent value between -Math.PI and Math.PI radians.\r\n * @param angle The angle to normalize in radian.\r\n * @returns The converted angle.\r\n */\r\nexport function NormalizeRadians(angle: number): number {\r\n    // More precise but slower version kept for reference.\r\n    // angle = angle % Tools.TwoPi;\r\n    // angle = (angle + Tools.TwoPi) % Tools.TwoPi;\r\n\r\n    //if (angle > Math.PI) {\r\n    //\tangle -= Tools.TwoPi;\r\n    //}\r\n\r\n    angle -= Math.PI * 2 * Math.floor((angle + Math.PI) / (Math.PI * 2));\r\n\r\n    return angle;\r\n}\r\n\r\n/**\r\n * Returns a string : the upper case translation of the number i to hexadecimal.\r\n * @param i number\r\n * @returns the upper case translation of the number i to hexadecimal.\r\n */\r\nexport function ToHex(i: number): string {\r\n    const str = i.toString(16);\r\n\r\n    if (i <= 15) {\r\n        return (\"0\" + str).toUpperCase();\r\n    }\r\n\r\n    return str.toUpperCase();\r\n}\r\n\r\n/**\r\n * the floor part of a log2 value.\r\n * @param value the value to compute log2 of\r\n * @returns the log2 of value.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function ILog2(value: number): number {\r\n    if (Math.log2) {\r\n        return Math.floor(Math.log2(value));\r\n    }\r\n\r\n    if (value < 0) {\r\n        return NaN;\r\n    } else if (value === 0) {\r\n        return -Infinity;\r\n    }\r\n\r\n    let n = 0;\r\n    if (value < 1) {\r\n        while (value < 1) {\r\n            n++;\r\n            value = value * 2;\r\n        }\r\n        n = -n;\r\n    } else if (value > 1) {\r\n        while (value > 1) {\r\n            n++;\r\n            value = Math.floor(value / 2);\r\n        }\r\n    }\r\n\r\n    return n;\r\n}\r\n\r\n/**\r\n * Loops the value, so that it is never larger than length and never smaller than 0.\r\n *\r\n * This is similar to the modulo operator but it works with floating point numbers.\r\n * For example, using 3.0 for t and 2.5 for length, the result would be 0.5.\r\n * With t = 5 and length = 2.5, the result would be 0.0.\r\n * Note, however, that the behaviour is not defined for negative numbers as it is for the modulo operator\r\n * @param value the value\r\n * @param length the length\r\n * @returns the looped value\r\n */\r\nexport function Repeat(value: number, length: number): number {\r\n    return value - Math.floor(value / length) * length;\r\n}\r\n\r\n/**\r\n * Normalize the value between 0.0 and 1.0 using min and max values\r\n * @param value value to normalize\r\n * @param min max to normalize between\r\n * @param max min to normalize between\r\n * @returns the normalized value\r\n */\r\nexport function Normalize(value: number, min: number, max: number): number {\r\n    return (value - min) / (max - min);\r\n}\r\n\r\n/**\r\n * Denormalize the value from 0.0 and 1.0 using min and max values\r\n * @param normalized value to denormalize\r\n * @param min max to denormalize between\r\n * @param max min to denormalize between\r\n * @returns the denormalized value\r\n */\r\nexport function Denormalize(normalized: number, min: number, max: number): number {\r\n    return normalized * (max - min) + min;\r\n}\r\n\r\n/**\r\n * Calculates the shortest difference between two given angles given in degrees.\r\n * @param current current angle in degrees\r\n * @param target target angle in degrees\r\n * @returns the delta\r\n */\r\nexport function DeltaAngle(current: number, target: number): number {\r\n    let num: number = Repeat(target - current, 360.0);\r\n    if (num > 180.0) {\r\n        num -= 360.0;\r\n    }\r\n    return num;\r\n}\r\n\r\n/**\r\n * PingPongs the value t, so that it is never larger than length and never smaller than 0.\r\n * @param tx value\r\n * @param length length\r\n * @returns The returned value will move back and forth between 0 and length\r\n */\r\nexport function PingPong(tx: number, length: number): number {\r\n    const t: number = Repeat(tx, length * 2.0);\r\n    return length - Math.abs(t - length);\r\n}\r\n\r\n/**\r\n * Interpolates between min and max with smoothing at the limits.\r\n *\r\n * This function interpolates between min and max in a similar way to Lerp. However, the interpolation will gradually speed up\r\n * from the start and slow down toward the end. This is useful for creating natural-looking animation, fading and other transitions.\r\n * @param from from\r\n * @param to to\r\n * @param tx value\r\n * @returns the smooth stepped value\r\n */\r\nexport function SmoothStep(from: number, to: number, tx: number): number {\r\n    let t: number = Clamp(tx);\r\n    t = -2.0 * t * t * t + 3.0 * t * t;\r\n    return to * t + from * (1.0 - t);\r\n}\r\n\r\n/**\r\n * Moves a value current towards target.\r\n *\r\n * This is essentially the same as Mathf.Lerp but instead the function will ensure that the speed never exceeds maxDelta.\r\n * Negative values of maxDelta pushes the value away from target.\r\n * @param current current value\r\n * @param target target value\r\n * @param maxDelta max distance to move\r\n * @returns resulting value\r\n */\r\nexport function MoveTowards(current: number, target: number, maxDelta: number): number {\r\n    let result: number;\r\n    if (Math.abs(target - current) <= maxDelta) {\r\n        result = target;\r\n    } else {\r\n        result = current + Math.sign(target - current) * maxDelta;\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * Same as MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.\r\n *\r\n * Variables current and target are assumed to be in degrees. For optimization reasons, negative values of maxDelta\r\n *  are not supported and may cause oscillation. To push current away from a target angle, add 180 to that angle instead.\r\n * @param current current value\r\n * @param target target value\r\n * @param maxDelta max distance to move\r\n * @returns resulting angle\r\n */\r\nexport function MoveTowardsAngle(current: number, target: number, maxDelta: number): number {\r\n    const num: number = DeltaAngle(current, target);\r\n    let result: number;\r\n    if (-maxDelta < num && num < maxDelta) {\r\n        result = target;\r\n    } else {\r\n        target = current + num;\r\n        result = MoveTowards(current, target, maxDelta);\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * This function returns percentage of a number in a given range.\r\n *\r\n * RangeToPercent(40,20,60) will return 0.5 (50%)\r\n * RangeToPercent(34,0,100) will return 0.34 (34%)\r\n * @param number to convert to percentage\r\n * @param min min range\r\n * @param max max range\r\n * @returns the percentage\r\n */\r\nexport function RangeToPercent(number: number, min: number, max: number): number {\r\n    return (number - min) / (max - min);\r\n}\r\n\r\n/**\r\n * This function returns number that corresponds to the percentage in a given range.\r\n *\r\n * PercentToRange(0.34,0,100) will return 34.\r\n * @param percent to convert to number\r\n * @param min min range\r\n * @param max max range\r\n * @returns the number\r\n */\r\nexport function PercentToRange(percent: number, min: number, max: number): number {\r\n    return (max - min) * percent + min;\r\n}\r\n\r\n/**\r\n * Returns the highest common factor of two integers.\r\n * @param a first parameter\r\n * @param b second parameter\r\n * @returns HCF of a and b\r\n */\r\nexport function HighestCommonFactor(a: number, b: number): number {\r\n    const r: number = a % b;\r\n    if (r === 0) {\r\n        return b;\r\n    }\r\n    return HighestCommonFactor(b, r);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type DeepImmutable } from \"core/types\";\r\nimport { type IMatrixLike } from \"../math.like\";\r\n\r\n/** @internal */\r\nexport class MatrixManagement {\r\n    /** @internal */\r\n    static _UpdateFlagSeed = 0;\r\n}\r\n\r\nfunction SetMatrixData(\r\n    result: IMatrixLike,\r\n    m0: number,\r\n    m1: number,\r\n    m2: number,\r\n    m3: number,\r\n    m4: number,\r\n    m5: number,\r\n    m6: number,\r\n    m7: number,\r\n    m8: number,\r\n    m9: number,\r\n    m10: number,\r\n    m11: number,\r\n    m12: number,\r\n    m13: number,\r\n    m14: number,\r\n    m15: number\r\n): void {\r\n    const mat = result.asArray();\r\n    mat[0] = m0;\r\n    mat[1] = m1;\r\n    mat[2] = m2;\r\n    mat[3] = m3;\r\n    mat[4] = m4;\r\n    mat[5] = m5;\r\n    mat[6] = m6;\r\n    mat[7] = m7;\r\n    mat[8] = m8;\r\n    mat[9] = m9;\r\n    mat[10] = m10;\r\n    mat[11] = m11;\r\n    mat[12] = m12;\r\n    mat[13] = m13;\r\n    mat[14] = m14;\r\n    mat[15] = m15;\r\n\r\n    MarkAsDirty(result);\r\n}\r\n\r\n/**\r\n * Marks the given matrix as dirty\r\n * @param matrix defines the matrix to mark as dirty\r\n */\r\nexport function MarkAsDirty(matrix: IMatrixLike): void {\r\n    matrix.updateFlag = MatrixManagement._UpdateFlagSeed++;\r\n}\r\n\r\n/**\r\n * Sets the given matrix to the identity matrix\r\n * @param result defines the target matrix\r\n */\r\nexport function IdentityMatrixToRef(result: IMatrixLike): void {\r\n    SetMatrixData(result, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);\r\n}\r\n\r\n/**\r\n * Creates a new translation matrix.\r\n * @param x defines the x coordinate\r\n * @param y defines the y coordinate\r\n * @param z defines the z coordinate\r\n * @param result defines the target matrix\r\n */\r\nexport function TranslationMatrixToRef(x: number, y: number, z: number, result: IMatrixLike): void {\r\n    SetMatrixData(result, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, x, y, z, 1.0);\r\n}\r\n\r\n/**\r\n * Creates a new scaling matrix.\r\n * @param x defines the scale factor on X axis\r\n * @param y defines the scale factor on Y axis\r\n * @param z defines the scale factor on Z axis\r\n * @param result defines the target matrix\r\n */\r\nexport function ScalingMatrixToRef(x: number, y: number, z: number, result: IMatrixLike): void {\r\n    SetMatrixData(result, x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0);\r\n}\r\n\r\n/**\r\n * Multiplies two matrices and stores the result in the target array.\r\n * @param a defines the first matrix\r\n * @param b defines the second matrix\r\n * @param output defines the target array\r\n * @param offset defines the offset in the target array where to store the result (0 by default)\r\n */\r\nexport function MultiplyMatricesToArray(a: DeepImmutable<IMatrixLike>, b: DeepImmutable<IMatrixLike>, output: Float32Array | Array<number>, offset = 0): void {\r\n    const m = a.asArray();\r\n    const otherM = b.asArray();\r\n    const tm0 = m[0],\r\n        tm1 = m[1],\r\n        tm2 = m[2],\r\n        tm3 = m[3];\r\n    const tm4 = m[4],\r\n        tm5 = m[5],\r\n        tm6 = m[6],\r\n        tm7 = m[7];\r\n    const tm8 = m[8],\r\n        tm9 = m[9],\r\n        tm10 = m[10],\r\n        tm11 = m[11];\r\n    const tm12 = m[12],\r\n        tm13 = m[13],\r\n        tm14 = m[14],\r\n        tm15 = m[15];\r\n\r\n    const om0 = otherM[0],\r\n        om1 = otherM[1],\r\n        om2 = otherM[2],\r\n        om3 = otherM[3];\r\n    const om4 = otherM[4],\r\n        om5 = otherM[5],\r\n        om6 = otherM[6],\r\n        om7 = otherM[7];\r\n    const om8 = otherM[8],\r\n        om9 = otherM[9],\r\n        om10 = otherM[10],\r\n        om11 = otherM[11];\r\n    const om12 = otherM[12],\r\n        om13 = otherM[13],\r\n        om14 = otherM[14],\r\n        om15 = otherM[15];\r\n    output[offset] = tm0 * om0 + tm1 * om4 + tm2 * om8 + tm3 * om12;\r\n    output[offset + 1] = tm0 * om1 + tm1 * om5 + tm2 * om9 + tm3 * om13;\r\n    output[offset + 2] = tm0 * om2 + tm1 * om6 + tm2 * om10 + tm3 * om14;\r\n    output[offset + 3] = tm0 * om3 + tm1 * om7 + tm2 * om11 + tm3 * om15;\r\n\r\n    output[offset + 4] = tm4 * om0 + tm5 * om4 + tm6 * om8 + tm7 * om12;\r\n    output[offset + 5] = tm4 * om1 + tm5 * om5 + tm6 * om9 + tm7 * om13;\r\n    output[offset + 6] = tm4 * om2 + tm5 * om6 + tm6 * om10 + tm7 * om14;\r\n    output[offset + 7] = tm4 * om3 + tm5 * om7 + tm6 * om11 + tm7 * om15;\r\n\r\n    output[offset + 8] = tm8 * om0 + tm9 * om4 + tm10 * om8 + tm11 * om12;\r\n    output[offset + 9] = tm8 * om1 + tm9 * om5 + tm10 * om9 + tm11 * om13;\r\n    output[offset + 10] = tm8 * om2 + tm9 * om6 + tm10 * om10 + tm11 * om14;\r\n    output[offset + 11] = tm8 * om3 + tm9 * om7 + tm10 * om11 + tm11 * om15;\r\n\r\n    output[offset + 12] = tm12 * om0 + tm13 * om4 + tm14 * om8 + tm15 * om12;\r\n    output[offset + 13] = tm12 * om1 + tm13 * om5 + tm14 * om9 + tm15 * om13;\r\n    output[offset + 14] = tm12 * om2 + tm13 * om6 + tm14 * om10 + tm15 * om14;\r\n    output[offset + 15] = tm12 * om3 + tm13 * om7 + tm14 * om11 + tm15 * om15;\r\n}\r\n\r\n/**\r\n * Multiplies two matrices and stores the result in a third matrix.\r\n * @param a defines the first matrix\r\n * @param b defines the second matrix\r\n * @param result defines the target matrix\r\n * @param offset defines the offset in the target matrix where to store the result (0 by default)\r\n */\r\nexport function MultiplyMatricesToRef(a: DeepImmutable<IMatrixLike>, b: DeepImmutable<IMatrixLike>, result: IMatrixLike, offset = 0): void {\r\n    MultiplyMatricesToArray(a, b, result.asArray(), offset);\r\n    MarkAsDirty(result);\r\n}\r\n\r\n/**\r\n * Populates the given matrix with the current matrix values\r\n * @param matrix defines the source matrix\r\n * @param target defines the target matrix\r\n */\r\nexport function CopyMatrixToRef(matrix: DeepImmutable<IMatrixLike>, target: IMatrixLike) {\r\n    CopyMatrixToArray(matrix, target.asArray());\r\n    MarkAsDirty(target);\r\n}\r\n\r\n/**\r\n * Populates the given array from the starting index with the current matrix values\r\n * @param matrix defines the source matrix\r\n * @param array defines the target array\r\n * @param offset defines the offset in the target array where to start storing values\r\n */\r\nexport function CopyMatrixToArray(matrix: DeepImmutable<IMatrixLike>, array: Float32Array | Array<number>, offset: number = 0) {\r\n    const source = matrix.asArray();\r\n    array[offset] = source[0];\r\n    array[offset + 1] = source[1];\r\n    array[offset + 2] = source[2];\r\n    array[offset + 3] = source[3];\r\n    array[offset + 4] = source[4];\r\n    array[offset + 5] = source[5];\r\n    array[offset + 6] = source[6];\r\n    array[offset + 7] = source[7];\r\n    array[offset + 8] = source[8];\r\n    array[offset + 9] = source[9];\r\n    array[offset + 10] = source[10];\r\n    array[offset + 11] = source[11];\r\n    array[offset + 12] = source[12];\r\n    array[offset + 13] = source[13];\r\n    array[offset + 14] = source[14];\r\n    array[offset + 15] = source[15];\r\n}\r\n\r\n/**\r\n * Inverts the given matrix and stores the result in the target matrix\r\n * @param source defines the source matrix\r\n * @param target defines the target matrix\r\n * @returns true if the matrix was inverted successfully, false otherwise\r\n */\r\nexport function InvertMatrixToRef(source: DeepImmutable<IMatrixLike>, target: IMatrixLike) {\r\n    const result = InvertMatrixToArray(source, target.asArray());\r\n\r\n    if (result) {\r\n        MarkAsDirty(target);\r\n    }\r\n\r\n    return result;\r\n}\r\n\r\n/**\r\n * Inverts the given matrix and stores the result in the target array\r\n * @param source defines the source matrix\r\n * @param target defines the target array\r\n * @returns true if the matrix was inverted successfully, false otherwise\r\n */\r\nexport function InvertMatrixToArray(source: DeepImmutable<IMatrixLike>, target: Float32Array | Array<number>) {\r\n    // the inverse of a matrix is the transpose of cofactor matrix divided by the determinant\r\n    const m = source.asArray();\r\n    const m00 = m[0],\r\n        m01 = m[1],\r\n        m02 = m[2],\r\n        m03 = m[3];\r\n    const m10 = m[4],\r\n        m11 = m[5],\r\n        m12 = m[6],\r\n        m13 = m[7];\r\n    const m20 = m[8],\r\n        m21 = m[9],\r\n        m22 = m[10],\r\n        m23 = m[11];\r\n    const m30 = m[12],\r\n        m31 = m[13],\r\n        m32 = m[14],\r\n        m33 = m[15];\r\n\r\n    const det_22_33 = m22 * m33 - m32 * m23;\r\n    const det_21_33 = m21 * m33 - m31 * m23;\r\n    const det_21_32 = m21 * m32 - m31 * m22;\r\n    const det_20_33 = m20 * m33 - m30 * m23;\r\n    const det_20_32 = m20 * m32 - m22 * m30;\r\n    const det_20_31 = m20 * m31 - m30 * m21;\r\n\r\n    const cofact_00 = +(m11 * det_22_33 - m12 * det_21_33 + m13 * det_21_32);\r\n    const cofact_01 = -(m10 * det_22_33 - m12 * det_20_33 + m13 * det_20_32);\r\n    const cofact_02 = +(m10 * det_21_33 - m11 * det_20_33 + m13 * det_20_31);\r\n    const cofact_03 = -(m10 * det_21_32 - m11 * det_20_32 + m12 * det_20_31);\r\n\r\n    const det = m00 * cofact_00 + m01 * cofact_01 + m02 * cofact_02 + m03 * cofact_03;\r\n\r\n    if (det === 0) {\r\n        // Not invertible\r\n        return false;\r\n    }\r\n\r\n    const detInv = 1 / det;\r\n    const det_12_33 = m12 * m33 - m32 * m13;\r\n    const det_11_33 = m11 * m33 - m31 * m13;\r\n    const det_11_32 = m11 * m32 - m31 * m12;\r\n    const det_10_33 = m10 * m33 - m30 * m13;\r\n    const det_10_32 = m10 * m32 - m30 * m12;\r\n    const det_10_31 = m10 * m31 - m30 * m11;\r\n    const det_12_23 = m12 * m23 - m22 * m13;\r\n    const det_11_23 = m11 * m23 - m21 * m13;\r\n    const det_11_22 = m11 * m22 - m21 * m12;\r\n    const det_10_23 = m10 * m23 - m20 * m13;\r\n    const det_10_22 = m10 * m22 - m20 * m12;\r\n    const det_10_21 = m10 * m21 - m20 * m11;\r\n\r\n    const cofact_10 = -(m01 * det_22_33 - m02 * det_21_33 + m03 * det_21_32);\r\n    const cofact_11 = +(m00 * det_22_33 - m02 * det_20_33 + m03 * det_20_32);\r\n    const cofact_12 = -(m00 * det_21_33 - m01 * det_20_33 + m03 * det_20_31);\r\n    const cofact_13 = +(m00 * det_21_32 - m01 * det_20_32 + m02 * det_20_31);\r\n\r\n    const cofact_20 = +(m01 * det_12_33 - m02 * det_11_33 + m03 * det_11_32);\r\n    const cofact_21 = -(m00 * det_12_33 - m02 * det_10_33 + m03 * det_10_32);\r\n    const cofact_22 = +(m00 * det_11_33 - m01 * det_10_33 + m03 * det_10_31);\r\n    const cofact_23 = -(m00 * det_11_32 - m01 * det_10_32 + m02 * det_10_31);\r\n\r\n    const cofact_30 = -(m01 * det_12_23 - m02 * det_11_23 + m03 * det_11_22);\r\n    const cofact_31 = +(m00 * det_12_23 - m02 * det_10_23 + m03 * det_10_22);\r\n    const cofact_32 = -(m00 * det_11_23 - m01 * det_10_23 + m03 * det_10_21);\r\n    const cofact_33 = +(m00 * det_11_22 - m01 * det_10_22 + m02 * det_10_21);\r\n\r\n    target[0] = cofact_00 * detInv;\r\n    target[1] = cofact_10 * detInv;\r\n    target[2] = cofact_20 * detInv;\r\n    target[3] = cofact_30 * detInv;\r\n    target[4] = cofact_01 * detInv;\r\n    target[5] = cofact_11 * detInv;\r\n    target[6] = cofact_21 * detInv;\r\n    target[7] = cofact_31 * detInv;\r\n    target[8] = cofact_02 * detInv;\r\n    target[9] = cofact_12 * detInv;\r\n    target[10] = cofact_22 * detInv;\r\n    target[11] = cofact_32 * detInv;\r\n    target[12] = cofact_03 * detInv;\r\n    target[13] = cofact_13 * detInv;\r\n    target[14] = cofact_23 * detInv;\r\n    target[15] = cofact_33 * detInv;\r\n\r\n    return true;\r\n}\r\n","/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst RegisteredTypes: { [key: string]: object } = {};\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function RegisterClass(className: string, type: object) {\r\n    RegisteredTypes[className] = type;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function GetClass(fqdn: string): any {\r\n    return RegisteredTypes[fqdn];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function GetClassName(obj: any): string {\r\n    for (const key in RegisteredTypes) {\r\n        if (obj instanceof (RegisteredTypes[key] as any) && !key.includes(\"Abstract\")) {\r\n            return key;\r\n        }\r\n    }\r\n    return \"Unknown\";\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Epsilon } from \"./math.constants\";\r\nimport { type Viewport } from \"./math.viewport\";\r\nimport { type DeepImmutable, type Nullable, type FloatArray, type float, type Tuple } from \"../types\";\r\nimport { BuildTuple } from \"../Misc/arrayTools\";\r\nimport { type Plane } from \"./math.plane\";\r\nimport { PerformanceConfigurator } from \"../Engines/performanceConfigurator\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type Dimension, type Tensor, type TensorLike, type TensorStatic } from \"./tensor\";\r\nimport { type IVector2Like, type IVector3Like, type IVector4Like, type IQuaternionLike, type IMatrixLike, type IPlaneLike, type IVector3LikeInternal } from \"./math.like\";\r\nimport { Clamp, Lerp, NormalizeRadians, RandomRange, WithinEpsilon } from \"./math.scalar.functions\";\r\nimport { CopyMatrixToArray, InvertMatrixToArray, MatrixManagement, MultiplyMatricesToArray } from \"./ThinMaths/thinMath.matrix.functions\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst ExtractAsInt = (value: number) => {\r\n    return parseInt(value.toString().replace(/\\W/g, \"\"));\r\n};\r\n\r\n/**\r\n * Represents a vector of any dimension\r\n */\r\nexport interface Vector<N extends number[], I> extends Tensor<N, I> {\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    readonly dimension: Readonly<Dimension<N>>;\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    readonly rank: 1;\r\n\r\n    /**\r\n     * Gets the length of the vector\r\n     * @returns the vector length (float)\r\n     */\r\n    length(): number;\r\n\r\n    /**\r\n     * Gets the vector squared length\r\n     * @returns the vector squared length (float)\r\n     */\r\n    lengthSquared(): number;\r\n\r\n    /**\r\n     * Normalize the vector\r\n     * @returns the current updated Vector\r\n     */\r\n    normalize(): this;\r\n\r\n    /**\r\n     * Normalize the current Vector with the given input length.\r\n     * Please note that this is an in place operation.\r\n     * @param len the length of the vector\r\n     * @returns the current updated Vector\r\n     */\r\n    normalizeFromLength(len: number): this;\r\n\r\n    /**\r\n     * Normalize the current Vector to a new vector\r\n     * @returns the new Vector\r\n     */\r\n    normalizeToNew(): Vector<N, I>;\r\n\r\n    /**\r\n     * Normalize the current Vector to the reference\r\n     * @param reference define the Vector to update\r\n     * @returns the updated Vector\r\n     */\r\n    normalizeToRef<T extends I>(reference: T): T;\r\n}\r\n\r\n/**\r\n * Static side of Vector\r\n */\r\nexport interface VectorStatic<T extends Vector<any[], _I>, _I = TensorLike<T>> extends TensorStatic<T, _I> {\r\n    /**\r\n     * Checks if a given vector is inside a specific range\r\n     * @param value defines the vector to test\r\n     * @param min defines the minimum range\r\n     * @param max defines the maximum range\r\n     */\r\n    CheckExtends(value: _I, min: _I, max: _I): void;\r\n\r\n    /**\r\n     * Returns a new Vector equal to the normalized given vector\r\n     * @param vector defines the vector to normalize\r\n     * @returns a new Vector\r\n     */\r\n    Normalize(vector: DeepImmutable<T>): T;\r\n\r\n    /**\r\n     * Normalize a given vector into a second one\r\n     * @param vector defines the vector to normalize\r\n     * @param result defines the vector where to store the result\r\n     * @returns result input\r\n     */\r\n    NormalizeToRef(vector: DeepImmutable<T>, result: T): T;\r\n}\r\n\r\n/**\r\n * Class representing a vector containing 2 coordinates\r\n * Example Playground - Overview -  https://playground.babylonjs.com/#QYBWV4#9\r\n */\r\nexport class Vector2 implements Vector<Tuple<number, 2>, IVector2Like>, IVector2Like {\r\n    /**\r\n     * If the first vector is flagged with integers (as everything is 0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n     * If subsequent vectors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n     * and henceforth it will use floating-point representation for all Vector2 instances that it creates.\r\n     * But the original Vector2 instances are unchanged and has a \"deprecated map\".\r\n     * If we keep using the Vector2 instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n     */\r\n    static _V8PerformanceHack = /*#__PURE__*/ new Vector2(0.5, 0.5) as DeepImmutable<Vector2>;\r\n    private static _ZeroReadOnly = /*#__PURE__*/ Vector2.Zero() as DeepImmutable<Vector2>;\r\n\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: Readonly<[2]>;\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 1;\r\n\r\n    /**\r\n     * Creates a new Vector2 from the given x and y coordinates\r\n     * @param x defines the first coordinate\r\n     * @param y defines the second coordinate\r\n     */\r\n    constructor(\r\n        /** [0] defines the first coordinate */\r\n        public x: number = 0,\r\n        /** [0] defines the second coordinate */\r\n        public y: number = 0\r\n    ) {}\r\n\r\n    /**\r\n     * Gets a string with the Vector2 coordinates\r\n     * @returns a string with the Vector2 coordinates\r\n     */\r\n    public toString(): string {\r\n        return `{X: ${this.x} Y: ${this.y}}`;\r\n    }\r\n\r\n    /**\r\n     * Gets class name\r\n     * @returns the string \"Vector2\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Vector2\";\r\n    }\r\n\r\n    /**\r\n     * Gets current vector hash code\r\n     * @returns the Vector2 hash code as a number\r\n     */\r\n    public getHashCode(): number {\r\n        const x = ExtractAsInt(this.x);\r\n        const y = ExtractAsInt(this.y);\r\n        let hash = x;\r\n        hash = (hash * 397) ^ y;\r\n        return hash;\r\n    }\r\n\r\n    // Operators\r\n\r\n    /**\r\n     * Sets the Vector2 coordinates in the given array or Float32Array from the given index.\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#15\r\n     * @param array defines the source array\r\n     * @param index defines the offset in source array\r\n     * @returns the current Vector2\r\n     */\r\n    public toArray(array: FloatArray, index: number = 0): this {\r\n        array[index] = this.x;\r\n        array[index + 1] = this.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update the current vector from an array\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#39\r\n     * @param array defines the destination array\r\n     * @param offset defines the offset in the destination array\r\n     * @returns the current Vector2\r\n     */\r\n    public fromArray(array: FloatArray, offset: number = 0): this {\r\n        Vector2.FromArrayToRef(array, offset, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copy the current vector to an array\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#40\r\n     * @returns a new array with 2 elements: the Vector2 coordinates.\r\n     */\r\n    public asArray(): [number, number] {\r\n        return [this.x, this.y];\r\n    }\r\n\r\n    /**\r\n     * Sets the Vector2 coordinates with the given Vector2 coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#24\r\n     * @param source defines the source Vector2\r\n     * @returns the current updated Vector2\r\n     */\r\n    public copyFrom(source: DeepImmutable<IVector2Like>): this {\r\n        this.x = source.x;\r\n        this.y = source.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the Vector2 coordinates with the given floats\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#25\r\n     * @param x defines the first coordinate\r\n     * @param y defines the second coordinate\r\n     * @returns the current updated Vector2\r\n     */\r\n    public copyFromFloats(x: number, y: number): this {\r\n        this.x = x;\r\n        this.y = y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the Vector2 coordinates with the given floats\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#62\r\n     * @param x defines the first coordinate\r\n     * @param y defines the second coordinate\r\n     * @returns the current updated Vector2\r\n     */\r\n    public set(x: number, y: number): this {\r\n        return this.copyFromFloats(x, y);\r\n    }\r\n\r\n    /**\r\n     * Copies the given float to the current Vector2 coordinates\r\n     * @param v defines the x and y coordinates of the operand\r\n     * @returns the current updated Vector2\r\n     */\r\n    public setAll(v: number): this {\r\n        return this.copyFromFloats(v, v);\r\n    }\r\n\r\n    /**\r\n     * Add another vector with the current one\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#11\r\n     * @param otherVector defines the other vector\r\n     * @returns a new Vector2 set with the addition of the current Vector2 and the given one coordinates\r\n     */\r\n    public add(otherVector: DeepImmutable<IVector2Like>): Vector2 {\r\n        return new Vector2(this.x + otherVector.x, this.y + otherVector.y);\r\n    }\r\n\r\n    /**\r\n     * Sets the \"result\" coordinates with the addition of the current Vector2 and the given one coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#12\r\n     * @param otherVector defines the other vector\r\n     * @param result defines the target vector\r\n     * @returns result input\r\n     */\r\n    public addToRef<T extends IVector2Like>(otherVector: DeepImmutable<IVector2Like>, result: T): T {\r\n        result.x = this.x + otherVector.x;\r\n        result.y = this.y + otherVector.y;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Set the Vector2 coordinates by adding the given Vector2 coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#13\r\n     * @param otherVector defines the other vector\r\n     * @returns the current updated Vector2\r\n     */\r\n    public addInPlace(otherVector: DeepImmutable<IVector2Like>): this {\r\n        this.x += otherVector.x;\r\n        this.y += otherVector.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the given coordinates to the current Vector2\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @returns the current updated Vector2\r\n     */\r\n    public addInPlaceFromFloats(x: number, y: number): this {\r\n        this.x += x;\r\n        this.y += y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 by adding the current Vector2 coordinates to the given Vector3 x, y coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#14\r\n     * @param otherVector defines the other vector\r\n     * @returns a new Vector2\r\n     */\r\n    public addVector3(otherVector: IVector3Like): Vector2 {\r\n        return new Vector2(this.x + otherVector.x, this.y + otherVector.y);\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 set with the subtracted coordinates of the given one from the current Vector2\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#61\r\n     * @param otherVector defines the other vector\r\n     * @returns a new Vector2\r\n     */\r\n    public subtract(otherVector: DeepImmutable<IVector2Like>): Vector2 {\r\n        return new Vector2(this.x - otherVector.x, this.y - otherVector.y);\r\n    }\r\n\r\n    /**\r\n     * Sets the \"result\" coordinates with the subtraction of the given one from the current Vector2 coordinates.\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#63\r\n     * @param otherVector defines the other vector\r\n     * @param result defines the target vector\r\n     * @returns result input\r\n     */\r\n    public subtractToRef<T extends IVector2Like>(otherVector: DeepImmutable<IVector2Like>, result: T): T {\r\n        result.x = this.x - otherVector.x;\r\n        result.y = this.y - otherVector.y;\r\n        return result;\r\n    }\r\n    /**\r\n     * Sets the current Vector2 coordinates by subtracting from it the given one coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#88\r\n     * @param otherVector defines the other vector\r\n     * @returns the current updated Vector2\r\n     */\r\n    public subtractInPlace(otherVector: DeepImmutable<IVector2Like>): this {\r\n        this.x -= otherVector.x;\r\n        this.y -= otherVector.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Multiplies in place the current Vector2 coordinates by the given ones\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#43\r\n     * @param otherVector defines the other vector\r\n     * @returns the current updated Vector2\r\n     */\r\n    public multiplyInPlace(otherVector: DeepImmutable<IVector2Like>): this {\r\n        this.x *= otherVector.x;\r\n        this.y *= otherVector.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 set with the multiplication of the current Vector2 and the given one coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#42\r\n     * @param otherVector defines the other vector\r\n     * @returns a new Vector2\r\n     */\r\n    public multiply(otherVector: DeepImmutable<IVector2Like>): Vector2 {\r\n        return new Vector2(this.x * otherVector.x, this.y * otherVector.y);\r\n    }\r\n\r\n    /**\r\n     * Sets \"result\" coordinates with the multiplication of the current Vector2 and the given one coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#44\r\n     * @param otherVector defines the other vector\r\n     * @param result defines the target vector\r\n     * @returns result input\r\n     */\r\n    public multiplyToRef<T extends IVector2Like>(otherVector: DeepImmutable<IVector2Like>, result: T): T {\r\n        result.x = this.x * otherVector.x;\r\n        result.y = this.y * otherVector.y;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 set with the Vector2 coordinates multiplied by the given floats\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#89\r\n     * @param x defines the first coordinate\r\n     * @param y defines the second coordinate\r\n     * @returns a new Vector2\r\n     */\r\n    public multiplyByFloats(x: number, y: number): Vector2 {\r\n        return new Vector2(this.x * x, this.y * y);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 set with the Vector2 coordinates divided by the given one coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#27\r\n     * @param otherVector defines the other vector\r\n     * @returns a new Vector2\r\n     */\r\n    public divide(otherVector: DeepImmutable<IVector2Like>): Vector2 {\r\n        return new Vector2(this.x / otherVector.x, this.y / otherVector.y);\r\n    }\r\n\r\n    /**\r\n     * Sets the \"result\" coordinates with the Vector2 divided by the given one coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#30\r\n     * @param otherVector defines the other vector\r\n     * @param result defines the target vector\r\n     * @returns result input\r\n     */\r\n    public divideToRef<T extends IVector2Like>(otherVector: DeepImmutable<IVector2Like>, result: T): T {\r\n        result.x = this.x / otherVector.x;\r\n        result.y = this.y / otherVector.y;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Vector2 coordinates by the given ones\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#28\r\n     * @param otherVector defines the other vector\r\n     * @returns the current updated Vector2\r\n     */\r\n    public divideInPlace(otherVector: DeepImmutable<IVector2Like>): this {\r\n        this.x = this.x / otherVector.x;\r\n        this.y = this.y / otherVector.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector2 with the minimal coordinate values between its and the given vector ones\r\n     * @param other defines the second operand\r\n     * @returns the current updated Vector2\r\n     */\r\n    public minimizeInPlace(other: DeepImmutable<IVector2Like>): this {\r\n        return this.minimizeInPlaceFromFloats(other.x, other.y);\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector2 with the maximal coordinate values between its and the given vector ones.\r\n     * @param other defines the second operand\r\n     * @returns the current updated Vector2\r\n     */\r\n    public maximizeInPlace(other: DeepImmutable<IVector2Like>): this {\r\n        return this.maximizeInPlaceFromFloats(other.x, other.y);\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector2 with the minimal coordinate values between its and the given coordinates\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @returns the current updated Vector2\r\n     */\r\n    public minimizeInPlaceFromFloats(x: number, y: number): this {\r\n        this.x = Math.min(x, this.x);\r\n        this.y = Math.min(y, this.y);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector2 with the maximal coordinate values between its and the given coordinates.\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @returns the current updated Vector2\r\n     */\r\n    public maximizeInPlaceFromFloats(x: number, y: number): this {\r\n        this.x = Math.max(x, this.x);\r\n        this.y = Math.max(y, this.y);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 set with the subtraction of the given floats from the current Vector2 coordinates\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @returns the resulting Vector2\r\n     */\r\n    public subtractFromFloats(x: number, y: number): Vector2 {\r\n        return new Vector2(this.x - x, this.y - y);\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current Vector2 coordinates and set the given vector \"result\" with this result\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param result defines the Vector2 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public subtractFromFloatsToRef<T extends IVector2Like>(x: number, y: number, result: T): T {\r\n        result.x = this.x - x;\r\n        result.y = this.y - y;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 with current Vector2 negated coordinates\r\n     * @returns a new Vector2\r\n     */\r\n    public negate(): Vector2 {\r\n        return new Vector2(-this.x, -this.y);\r\n    }\r\n\r\n    /**\r\n     * Negate this vector in place\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#23\r\n     * @returns this\r\n     */\r\n    public negateInPlace(): this {\r\n        this.x *= -1;\r\n        this.y *= -1;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Negate the current Vector2 and stores the result in the given vector \"result\" coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#41\r\n     * @param result defines the Vector2 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public negateToRef<T extends IVector2Like>(result: T): T {\r\n        result.x = -this.x;\r\n        result.y = -this.y;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiply the Vector2 coordinates by\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#59\r\n     * @param scale defines the scaling factor\r\n     * @returns the current updated Vector2\r\n     */\r\n    public scaleInPlace(scale: number): this {\r\n        this.x *= scale;\r\n        this.y *= scale;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 scaled by \"scale\" from the current Vector2\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#52\r\n     * @param scale defines the scaling factor\r\n     * @returns a new Vector2\r\n     */\r\n    public scale(scale: number): Vector2 {\r\n        return new Vector2(this.x * scale, this.y * scale);\r\n    }\r\n\r\n    /**\r\n     * Scale the current Vector2 values by a factor to a given Vector2\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#57\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Vector2 object where to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleToRef<T extends IVector2Like>(scale: number, result: T): T {\r\n        result.x = this.x * scale;\r\n        result.y = this.y * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Scale the current Vector2 values by a factor and add the result to a given Vector2\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#58\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Vector2 object where to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleAndAddToRef<T extends IVector2Like>(scale: number, result: T): T {\r\n        result.x += this.x * scale;\r\n        result.y += this.y * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean if two vectors are equals\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#31\r\n     * @param otherVector defines the other vector\r\n     * @returns true if the given vector coordinates strictly equal the current Vector2 ones\r\n     */\r\n    public equals(otherVector: DeepImmutable<IVector2Like>): boolean {\r\n        return otherVector && this.x === otherVector.x && this.y === otherVector.y;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean if two vectors are equals (using an epsilon value)\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#32\r\n     * @param otherVector defines the other vector\r\n     * @param epsilon defines the minimal distance to consider equality\r\n     * @returns true if the given vector coordinates are close to the current ones by a distance of epsilon.\r\n     */\r\n    public equalsWithEpsilon(otherVector: DeepImmutable<IVector2Like>, epsilon: number = Epsilon): boolean {\r\n        return otherVector && WithinEpsilon(this.x, otherVector.x, epsilon) && WithinEpsilon(this.y, otherVector.y, epsilon);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the current Vector2 coordinates equals the given floats\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @returns true if both vectors are equal\r\n     */\r\n    public equalsToFloats(x: number, y: number): boolean {\r\n        return this.x === x && this.y === y;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 from current Vector2 floored values\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#35\r\n     * eg (1.2, 2.31) returns (1, 2)\r\n     * @returns a new Vector2\r\n     */\r\n    public floor(): Vector2 {\r\n        return new Vector2(Math.floor(this.x), Math.floor(this.y));\r\n    }\r\n\r\n    /**\r\n     * Gets the current Vector2's floored values and stores them in result\r\n     * @param result the Vector2 to store the result in\r\n     * @returns the result Vector2\r\n     */\r\n    public floorToRef<T extends IVector2Like>(result: T): T {\r\n        result.x = Math.floor(this.x);\r\n        result.y = Math.floor(this.y);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 from current Vector2 fractional values\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#34\r\n     * eg (1.2, 2.31) returns (0.2, 0.31)\r\n     * @returns a new Vector2\r\n     */\r\n    public fract(): Vector2 {\r\n        return new Vector2(this.x - Math.floor(this.x), this.y - Math.floor(this.y));\r\n    }\r\n\r\n    /**\r\n     * Gets the current Vector2's fractional values and stores them in result\r\n     * @param result the Vector2 to store the result in\r\n     * @returns the result Vector2\r\n     */\r\n    public fractToRef<T extends IVector2Like>(result: T): T {\r\n        result.x = this.x - Math.floor(this.x);\r\n        result.y = this.y - Math.floor(this.y);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 rotated by the given angle\r\n     * @param angle defines the rotation angle\r\n     * @returns a new Vector2\r\n     */\r\n    public rotate(angle: number): Vector2 {\r\n        return this.rotateToRef(angle, new Vector2());\r\n    }\r\n\r\n    /**\r\n     * Rotate the current vector into a given result vector\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#49\r\n     * @param angle defines the rotation angle\r\n     * @param result defines the result vector where to store the rotated vector\r\n     * @returns result input\r\n     */\r\n    public rotateToRef<T extends IVector2Like>(angle: number, result: T): T {\r\n        const cos = Math.cos(angle);\r\n        const sin = Math.sin(angle);\r\n        result.x = cos * this.x - sin * this.y;\r\n        result.y = sin * this.x + cos * this.y;\r\n        return result;\r\n    }\r\n\r\n    // Properties\r\n\r\n    /**\r\n     * Gets the length of the vector\r\n     * @returns the vector length (float)\r\n     */\r\n    public length(): number {\r\n        return Math.sqrt(this.x * this.x + this.y * this.y);\r\n    }\r\n\r\n    /**\r\n     * Gets the vector squared length\r\n     * @returns the vector squared length (float)\r\n     */\r\n    public lengthSquared(): number {\r\n        return this.x * this.x + this.y * this.y;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Normalize the vector\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#48\r\n     * @returns the current updated Vector2\r\n     */\r\n    public normalize(): this {\r\n        return this.normalizeFromLength(this.length());\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector2 with the given input length.\r\n     * Please note that this is an in place operation.\r\n     * @param len the length of the vector\r\n     * @returns the current updated Vector2\r\n     */\r\n    public normalizeFromLength(len: number): this {\r\n        if (len === 0 || len === 1.0) {\r\n            return this;\r\n        }\r\n\r\n        return this.scaleInPlace(1.0 / len);\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector2 to a new vector\r\n     * @returns the new Vector2\r\n     */\r\n    public normalizeToNew(): Vector2 {\r\n        const normalized = new Vector2();\r\n        this.normalizeToRef(normalized);\r\n        return normalized;\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector2 to the reference\r\n     * @param result define the Vector to update\r\n     * @returns the updated Vector2\r\n     */\r\n    public normalizeToRef<T extends IVector2Like>(result: T): T {\r\n        const len = this.length();\r\n        if (len === 0 || len === 1.0) {\r\n            result.x = this.x;\r\n            result.y = this.y;\r\n            return result;\r\n        }\r\n        return this.scaleToRef(1.0 / len, result);\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 copied from the Vector2\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#20\r\n     * @returns a new Vector2\r\n     */\r\n    public clone(): Vector2 {\r\n        return new Vector2(this.x, this.y);\r\n    }\r\n\r\n    /**\r\n     * Gets the dot product of the current vector and the vector \"otherVector\"\r\n     * @param otherVector defines second vector\r\n     * @returns the dot product (float)\r\n     */\r\n    public dot(otherVector: DeepImmutable<IVector2Like>): number {\r\n        return this.x * otherVector.x + this.y * otherVector.y;\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Gets a new Vector2(0, 0)\r\n     * @returns a new Vector2\r\n     */\r\n    public static Zero(): Vector2 {\r\n        return new Vector2(0, 0);\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2(1, 1)\r\n     * @returns a new Vector2\r\n     */\r\n    public static One(): Vector2 {\r\n        return new Vector2(1, 1);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @returns a Vector2 with random values between min and max\r\n     */\r\n    public static Random(min: number = 0, max: number = 1): Vector2 {\r\n        return new Vector2(RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector2 with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @param ref the ref to store the values in\r\n     * @returns the ref with random values between min and max\r\n     */\r\n    public static RandomToRef<T extends Vector2>(min: number = 0, max: number = 1, ref: T): T {\r\n        return ref.copyFromFloats(RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Gets a zero Vector2 that must not be updated\r\n     */\r\n    public static get ZeroReadOnly(): DeepImmutable<Vector2> {\r\n        return Vector2._ZeroReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 set from the given index element of the given array\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#79\r\n     * @param array defines the data source\r\n     * @param offset defines the offset in the data source\r\n     * @returns a new Vector2\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Vector2 {\r\n        return new Vector2(array[offset], array[offset + 1]);\r\n    }\r\n\r\n    /**\r\n     * Sets \"result\" from the given index element of the given array\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#80\r\n     * @param array defines the data source\r\n     * @param offset defines the offset in the data source\r\n     * @param result defines the target vector\r\n     * @returns result input\r\n     */\r\n    public static FromArrayToRef<T extends Vector2>(array: DeepImmutable<ArrayLike<number>>, offset: number, result: T): T {\r\n        result.x = array[offset];\r\n        result.y = array[offset + 1];\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the given floats.\r\n     * @param x defines the x coordinate of the source\r\n     * @param y defines the y coordinate of the source\r\n     * @param result defines the Vector2 where to store the result\r\n     * @returns the result vector\r\n     */\r\n    public static FromFloatsToRef<T extends Vector2>(x: number, y: number, result: T): T {\r\n        result.copyFromFloats(x, y);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 located for \"amount\" (float) on the CatmullRom spline defined by the given four Vector2\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#65\r\n     * @param value1 defines 1st point of control\r\n     * @param value2 defines 2nd point of control\r\n     * @param value3 defines 3rd point of control\r\n     * @param value4 defines 4th point of control\r\n     * @param amount defines the interpolation factor\r\n     * @returns a new Vector2\r\n     */\r\n    public static CatmullRom(\r\n        value1: DeepImmutable<IVector2Like>,\r\n        value2: DeepImmutable<IVector2Like>,\r\n        value3: DeepImmutable<IVector2Like>,\r\n        value4: DeepImmutable<IVector2Like>,\r\n        amount: number\r\n    ): Vector2 {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n\r\n        const x =\r\n            0.5 *\r\n            (2.0 * value2.x +\r\n                (-value1.x + value3.x) * amount +\r\n                (2.0 * value1.x - 5.0 * value2.x + 4.0 * value3.x - value4.x) * squared +\r\n                (-value1.x + 3.0 * value2.x - 3.0 * value3.x + value4.x) * cubed);\r\n\r\n        const y =\r\n            0.5 *\r\n            (2.0 * value2.y +\r\n                (-value1.y + value3.y) * amount +\r\n                (2.0 * value1.y - 5.0 * value2.y + 4.0 * value3.y - value4.y) * squared +\r\n                (-value1.y + 3.0 * value2.y - 3.0 * value3.y + value4.y) * cubed);\r\n\r\n        return new Vector2(x, y);\r\n    }\r\n\r\n    /**\r\n     * Sets reference with same the coordinates than \"value\" ones if the vector \"value\" is in the square defined by \"min\" and \"max\".\r\n     * If a coordinate of \"value\" is lower than \"min\" coordinates, the returned Vector2 is given this \"min\" coordinate.\r\n     * If a coordinate of \"value\" is greater than \"max\" coordinates, the returned Vector2 is given this \"max\" coordinate\r\n     * @param value defines the value to clamp\r\n     * @param min defines the lower limit\r\n     * @param max defines the upper limit\r\n     * @param ref the reference\r\n     * @returns the reference\r\n     */\r\n    public static ClampToRef<T extends Vector2>(value: DeepImmutable<IVector2Like>, min: DeepImmutable<IVector2Like>, max: DeepImmutable<IVector2Like>, ref: T): T {\r\n        ref.x = Clamp(value.x, min.x, max.x);\r\n        ref.y = Clamp(value.y, min.y, max.y);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 set with same the coordinates than \"value\" ones if the vector \"value\" is in the square defined by \"min\" and \"max\".\r\n     * If a coordinate of \"value\" is lower than \"min\" coordinates, the returned Vector2 is given this \"min\" coordinate.\r\n     * If a coordinate of \"value\" is greater than \"max\" coordinates, the returned Vector2 is given this \"max\" coordinate\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#76\r\n     * @param value defines the value to clamp\r\n     * @param min defines the lower limit\r\n     * @param max defines the upper limit\r\n     * @returns a new Vector2\r\n     */\r\n    public static Clamp(value: DeepImmutable<IVector2Like>, min: DeepImmutable<IVector2Like>, max: DeepImmutable<IVector2Like>): Vector2 {\r\n        const x = Clamp(value.x, min.x, max.x);\r\n        const y = Clamp(value.y, min.y, max.y);\r\n        return new Vector2(x, y);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 located for \"amount\" (float) on the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\"\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#81\r\n     * @param value1 defines the 1st control point\r\n     * @param tangent1 defines the outgoing tangent\r\n     * @param value2 defines the 2nd control point\r\n     * @param tangent2 defines the incoming tangent\r\n     * @param amount defines the interpolation factor\r\n     * @returns a new Vector2\r\n     */\r\n    public static Hermite(\r\n        value1: DeepImmutable<IVector2Like>,\r\n        tangent1: DeepImmutable<IVector2Like>,\r\n        value2: DeepImmutable<IVector2Like>,\r\n        tangent2: DeepImmutable<IVector2Like>,\r\n        amount: number\r\n    ): Vector2 {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n        const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n        const part2 = -2.0 * cubed + 3.0 * squared;\r\n        const part3 = cubed - 2.0 * squared + amount;\r\n        const part4 = cubed - squared;\r\n\r\n        const x = value1.x * part1 + value2.x * part2 + tangent1.x * part3 + tangent2.x * part4;\r\n        const y = value1.y * part1 + value2.y * part2 + tangent1.y * part3 + tangent2.y * part4;\r\n\r\n        return new Vector2(x, y);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 which is the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#82\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @returns 1st derivative\r\n     */\r\n    public static Hermite1stDerivative(\r\n        value1: DeepImmutable<IVector2Like>,\r\n        tangent1: DeepImmutable<IVector2Like>,\r\n        value2: DeepImmutable<IVector2Like>,\r\n        tangent2: DeepImmutable<IVector2Like>,\r\n        time: number\r\n    ): Vector2 {\r\n        return this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, new Vector2());\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 which is the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#83\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @param result define where the derivative will be stored\r\n     * @returns result input\r\n     */\r\n    public static Hermite1stDerivativeToRef<T extends Vector2>(\r\n        value1: DeepImmutable<IVector2Like>,\r\n        tangent1: DeepImmutable<IVector2Like>,\r\n        value2: DeepImmutable<IVector2Like>,\r\n        tangent2: DeepImmutable<IVector2Like>,\r\n        time: number,\r\n        result: T\r\n    ): T {\r\n        const t2 = time * time;\r\n\r\n        result.x = (t2 - time) * 6 * value1.x + (3 * t2 - 4 * time + 1) * tangent1.x + (-t2 + time) * 6 * value2.x + (3 * t2 - 2 * time) * tangent2.x;\r\n        result.y = (t2 - time) * 6 * value1.y + (3 * t2 - 4 * time + 1) * tangent1.y + (-t2 + time) * 6 * value2.y + (3 * t2 - 2 * time) * tangent2.y;\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 located for \"amount\" (float) on the linear interpolation between the vector \"start\" adn the vector \"end\".\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#84\r\n     * @param start defines the start vector\r\n     * @param end defines the end vector\r\n     * @param amount defines the interpolation factor\r\n     * @returns a new Vector2\r\n     */\r\n    public static Lerp(start: DeepImmutable<IVector2Like>, end: DeepImmutable<IVector2Like>, amount: number): Vector2 {\r\n        return Vector2.LerpToRef(start, end, amount, new Vector2());\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the linear interpolation from the vector \"start\" for \"amount\" to the vector \"end\"\r\n     * @param start defines the start value\r\n     * @param end defines the end value\r\n     * @param amount max defines amount between both (between 0 and 1)\r\n     * @param result defines the Vector2 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static LerpToRef(start: DeepImmutable<IVector2Like>, end: DeepImmutable<IVector2Like>, amount: number, result: Vector2): Vector2 {\r\n        result.x = start.x + (end.x - start.x) * amount;\r\n        result.y = start.y + (end.y - start.y) * amount;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets the dot product of the vector \"left\" and the vector \"right\"\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#90\r\n     * @param left defines first vector\r\n     * @param right defines second vector\r\n     * @returns the dot product (float)\r\n     */\r\n    public static Dot(left: DeepImmutable<IVector2Like>, right: DeepImmutable<IVector2Like>): number {\r\n        return left.x * right.x + left.y * right.y;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector2 equal to the normalized given vector\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#46\r\n     * @param vector defines the vector to normalize\r\n     * @returns a new Vector2\r\n     */\r\n    public static Normalize(vector: DeepImmutable<Vector2>): Vector2 {\r\n        return Vector2.NormalizeToRef(vector, new Vector2());\r\n    }\r\n\r\n    /**\r\n     * Normalize a given vector into a second one\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#50\r\n     * @param vector defines the vector to normalize\r\n     * @param result defines the vector where to store the result\r\n     * @returns result input\r\n     */\r\n    public static NormalizeToRef<T extends Vector2>(vector: DeepImmutable<Vector2>, result: T): T {\r\n        vector.normalizeToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 set with the minimal coordinate values from the \"left\" and \"right\" vectors\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#86\r\n     * @param left defines 1st vector\r\n     * @param right defines 2nd vector\r\n     * @returns a new Vector2\r\n     */\r\n    public static Minimize(left: DeepImmutable<IVector2Like>, right: DeepImmutable<IVector2Like>): Vector2 {\r\n        const x = left.x < right.x ? left.x : right.x;\r\n        const y = left.y < right.y ? left.y : right.y;\r\n        return new Vector2(x, y);\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 set with the maximal coordinate values from the \"left\" and \"right\" vectors\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#86\r\n     * @param left defines 1st vector\r\n     * @param right defines 2nd vector\r\n     * @returns a new Vector2\r\n     */\r\n    public static Maximize(left: DeepImmutable<IVector2Like>, right: DeepImmutable<IVector2Like>): Vector2 {\r\n        const x = left.x > right.x ? left.x : right.x;\r\n        const y = left.y > right.y ? left.y : right.y;\r\n        return new Vector2(x, y);\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 set with the transformed coordinates of the given vector by the given transformation matrix\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#17\r\n     * @param vector defines the vector to transform\r\n     * @param transformation defines the matrix to apply\r\n     * @returns a new Vector2\r\n     */\r\n    public static Transform(vector: DeepImmutable<IVector2Like>, transformation: DeepImmutable<Matrix>): Vector2 {\r\n        return Vector2.TransformToRef(vector, transformation, new Vector2());\r\n    }\r\n\r\n    /**\r\n     * Transforms the given vector coordinates by the given transformation matrix and stores the result in the vector \"result\" coordinates\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#19\r\n     * @param vector defines the vector to transform\r\n     * @param transformation defines the matrix to apply\r\n     * @param result defines the target vector\r\n     * @returns result input\r\n     */\r\n    public static TransformToRef<T extends Vector2>(vector: DeepImmutable<IVector2Like>, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        const m = transformation.m;\r\n        const x = vector.x * m[0] + vector.y * m[4] + m[12];\r\n        const y = vector.x * m[1] + vector.y * m[5] + m[13];\r\n        result.x = x;\r\n        result.y = y;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Determines if a given vector is included in a triangle\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#87\r\n     * @param p defines the vector to test\r\n     * @param p0 defines 1st triangle point\r\n     * @param p1 defines 2nd triangle point\r\n     * @param p2 defines 3rd triangle point\r\n     * @returns true if the point \"p\" is in the triangle defined by the vectors \"p0\", \"p1\", \"p2\"\r\n     */\r\n    public static PointInTriangle(p: DeepImmutable<IVector2Like>, p0: DeepImmutable<IVector2Like>, p1: DeepImmutable<IVector2Like>, p2: DeepImmutable<IVector2Like>): boolean {\r\n        const a = (1 / 2) * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y);\r\n        const sign = a < 0 ? -1 : 1;\r\n        const s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y) * sign;\r\n        const t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y) * sign;\r\n\r\n        return s > 0 && t > 0 && s + t < 2 * a * sign;\r\n    }\r\n\r\n    /**\r\n     * Gets the distance between the vectors \"value1\" and \"value2\"\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#71\r\n     * @param value1 defines first vector\r\n     * @param value2 defines second vector\r\n     * @returns the distance between vectors\r\n     */\r\n    public static Distance(value1: DeepImmutable<IVector2Like>, value2: DeepImmutable<IVector2Like>): number {\r\n        return Math.sqrt(Vector2.DistanceSquared(value1, value2));\r\n    }\r\n\r\n    /**\r\n     * Returns the squared distance between the vectors \"value1\" and \"value2\"\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#72\r\n     * @param value1 defines first vector\r\n     * @param value2 defines second vector\r\n     * @returns the squared distance between vectors\r\n     */\r\n    public static DistanceSquared(value1: DeepImmutable<IVector2Like>, value2: DeepImmutable<IVector2Like>): number {\r\n        const x = value1.x - value2.x;\r\n        const y = value1.y - value2.y;\r\n        return x * x + y * y;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector2 located at the center of the vectors \"value1\" and \"value2\"\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#86\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#66\r\n     * @param value1 defines first vector\r\n     * @param value2 defines second vector\r\n     * @returns a new Vector2\r\n     */\r\n    public static Center(value1: DeepImmutable<IVector2Like>, value2: DeepImmutable<IVector2Like>): Vector2 {\r\n        return Vector2.CenterToRef(value1, value2, new Vector2());\r\n    }\r\n\r\n    /**\r\n     * Gets the center of the vectors \"value1\" and \"value2\" and stores the result in the vector \"ref\"\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#66\r\n     * @param value1 defines first vector\r\n     * @param value2 defines second vector\r\n     * @param ref defines third vector\r\n     * @returns ref\r\n     */\r\n    public static CenterToRef<T extends Vector2>(value1: DeepImmutable<IVector2Like>, value2: DeepImmutable<IVector2Like>, ref: T): T {\r\n        return ref.copyFromFloats((value1.x + value2.x) / 2, (value1.y + value2.y) / 2);\r\n    }\r\n\r\n    /**\r\n     * Gets the shortest distance (float) between the point \"p\" and the segment defined by the two points \"segA\" and \"segB\".\r\n     * Example Playground https://playground.babylonjs.com/#QYBWV4#77\r\n     * @param p defines the middle point\r\n     * @param segA defines one point of the segment\r\n     * @param segB defines the other point of the segment\r\n     * @returns the shortest distance\r\n     */\r\n    public static DistanceOfPointFromSegment(p: DeepImmutable<Vector2>, segA: DeepImmutable<Vector2>, segB: DeepImmutable<Vector2>): number {\r\n        const l2 = Vector2.DistanceSquared(segA, segB);\r\n        if (l2 === 0.0) {\r\n            return Vector2.Distance(p, segA);\r\n        }\r\n        const v = segB.subtract(segA);\r\n        const t = Math.max(0, Math.min(1, Vector2.Dot(p.subtract(segA), v) / l2));\r\n        const proj = segA.add(v.multiplyByFloats(t, t));\r\n        return Vector2.Distance(p, proj);\r\n    }\r\n}\r\nVector2 satisfies TensorStatic<Vector2, IVector2Like>;\r\n\r\n/**\r\n * Class used to store (x,y,z) vector representation\r\n * A Vector3 is the main object used in 3D geometry\r\n * It can represent either the coordinates of a point the space, either a direction\r\n * Reminder: js uses a left handed forward facing system\r\n * Example Playground - Overview - https://playground.babylonjs.com/#R1F8YU\r\n */\r\nexport class Vector3 implements Vector<Tuple<number, 3>, IVector3LikeInternal>, IVector3Like {\r\n    /**\r\n     * If the first vector is flagged with integers (as everything is 0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n     * If subsequent vectors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n     * and henceforth it will use floating-point representation for all Vector3 instances that it creates.\r\n     * But the original Vector3 instances are unchanged and has a \"deprecated map\".\r\n     * If we keep using the Vector3 instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n     */\r\n    static _V8PerformanceHack = /*#__PURE__*/ new Vector3(0.5, 0.5, 0.5) as DeepImmutable<Vector3>;\r\n    private static _UpReadOnly = /*#__PURE__*/ Vector3.Up() as DeepImmutable<Vector3>;\r\n    private static _DownReadOnly = /*#__PURE__*/ Vector3.Down() as DeepImmutable<Vector3>;\r\n    private static _LeftHandedForwardReadOnly = /*#__PURE__*/ Vector3.Forward(false) as DeepImmutable<Vector3>;\r\n    private static _RightHandedForwardReadOnly = /*#__PURE__*/ Vector3.Forward(true) as DeepImmutable<Vector3>;\r\n    private static _LeftHandedBackwardReadOnly = /*#__PURE__*/ Vector3.Backward(false) as DeepImmutable<Vector3>;\r\n    private static _RightHandedBackwardReadOnly = /*#__PURE__*/ Vector3.Backward(true) as DeepImmutable<Vector3>;\r\n    private static _RightReadOnly = /*#__PURE__*/ Vector3.Right() as DeepImmutable<Vector3>;\r\n    private static _LeftReadOnly = /*#__PURE__*/ Vector3.Left() as DeepImmutable<Vector3>;\r\n    private static _ZeroReadOnly = /*#__PURE__*/ Vector3.Zero() as DeepImmutable<Vector3>;\r\n    private static _OneReadOnly = /*#__PURE__*/ Vector3.One() as DeepImmutable<Vector3>;\r\n\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: Readonly<[3]>;\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 1;\r\n\r\n    /** @internal */\r\n    public _x: number;\r\n\r\n    /** @internal */\r\n    public _y: number;\r\n\r\n    /** @internal */\r\n    public _z: number;\r\n\r\n    /** @internal */\r\n    public _isDirty = true;\r\n\r\n    /** Gets or sets the x coordinate */\r\n    public get x() {\r\n        return this._x;\r\n    }\r\n\r\n    public set x(value: number) {\r\n        this._x = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the y coordinate */\r\n    public get y() {\r\n        return this._y;\r\n    }\r\n\r\n    public set y(value: number) {\r\n        this._y = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the z coordinate */\r\n    public get z() {\r\n        return this._z;\r\n    }\r\n\r\n    public set z(value: number) {\r\n        this._z = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Vector3 object from the given x, y, z (floats) coordinates.\r\n     * @param x defines the first coordinates (on X axis)\r\n     * @param y defines the second coordinates (on Y axis)\r\n     * @param z defines the third coordinates (on Z axis)\r\n     */\r\n    constructor(x: number = 0, y: number = 0, z: number = 0) {\r\n        this._x = x;\r\n        this._y = y;\r\n        this._z = z;\r\n    }\r\n\r\n    /**\r\n     * Creates a string representation of the Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#67\r\n     * @returns a string with the Vector3 coordinates.\r\n     */\r\n    public toString(): string {\r\n        return `{X: ${this._x} Y: ${this._y} Z: ${this._z}}`;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name\r\n     * @returns the string \"Vector3\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Vector3\";\r\n    }\r\n\r\n    /**\r\n     * Creates the Vector3 hash code\r\n     * @returns a number which tends to be unique between Vector3 instances\r\n     */\r\n    public getHashCode(): number {\r\n        const x = ExtractAsInt(this._x);\r\n        const y = ExtractAsInt(this._y);\r\n        const z = ExtractAsInt(this._z);\r\n\r\n        let hash = x;\r\n        hash = (hash * 397) ^ y;\r\n        hash = (hash * 397) ^ z;\r\n        return hash;\r\n    }\r\n\r\n    // Operators\r\n\r\n    /**\r\n     * Creates an array containing three elements : the coordinates of the Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#10\r\n     * @returns a new array of numbers\r\n     */\r\n    public asArray(): Tuple<number, 3> {\r\n        return [this._x, this._y, this._z];\r\n    }\r\n\r\n    /**\r\n     * Populates the given array or Float32Array from the given index with the successive coordinates of the Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#65\r\n     * @param array defines the destination array\r\n     * @param index defines the offset in the destination array\r\n     * @returns the current Vector3\r\n     */\r\n    public toArray(array: FloatArray, index: number = 0): this {\r\n        array[index] = this._x;\r\n        array[index + 1] = this._y;\r\n        array[index + 2] = this._z;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update the current vector from an array\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#24\r\n     * @param array defines the destination array\r\n     * @param offset defines the offset in the destination array\r\n     * @returns the current Vector3\r\n     */\r\n    public fromArray(array: DeepImmutable<FloatArray>, offset: number = 0): this {\r\n        Vector3.FromArrayToRef(array, offset, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Converts the current Vector3 into a quaternion (considering that the Vector3 contains Euler angles representation of a rotation)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#66\r\n     * @returns a new Quaternion object, computed from the Vector3 coordinates\r\n     */\r\n    public toQuaternion(): Quaternion {\r\n        return Quaternion.RotationYawPitchRoll(this._y, this._x, this._z);\r\n    }\r\n\r\n    /**\r\n     * Adds the given vector to the current Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#4\r\n     * @param otherVector defines the second operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public addInPlace(otherVector: DeepImmutable<Vector3>): this {\r\n        this._x += otherVector._x;\r\n        this._y += otherVector._y;\r\n        this._z += otherVector._z;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the given coordinates to the current Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#5\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public addInPlaceFromFloats(x: number, y: number, z: number): this {\r\n        this._x += x;\r\n        this._y += y;\r\n        this._z += z;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector3, result of the addition the current Vector3 and the given vector\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#3\r\n     * @param otherVector defines the second operand\r\n     * @returns the resulting Vector3\r\n     */\r\n    public add(otherVector: DeepImmutable<IVector3LikeInternal>): Vector3 {\r\n        return new Vector3(this._x + otherVector._x, this._y + otherVector._y, this._z + otherVector._z);\r\n    }\r\n\r\n    /**\r\n     * Adds the current Vector3 to the given one and stores the result in the vector \"result\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#6\r\n     * @param otherVector defines the second operand\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public addToRef<T extends IVector3LikeInternal>(otherVector: DeepImmutable<IVector3LikeInternal>, result: T): T {\r\n        result._x = this._x + otherVector._x;\r\n        result._y = this._y + otherVector._y;\r\n        result._z = this._z + otherVector._z;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Subtract the given vector from the current Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#61\r\n     * @param otherVector defines the second operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public subtractInPlace(otherVector: DeepImmutable<IVector3LikeInternal>): this {\r\n        this._x -= otherVector._x;\r\n        this._y -= otherVector._y;\r\n        this._z -= otherVector._z;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3, result of the subtraction of the given vector from the current Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#60\r\n     * @param otherVector defines the second operand\r\n     * @returns the resulting Vector3\r\n     */\r\n    public subtract(otherVector: DeepImmutable<IVector3LikeInternal>): Vector3 {\r\n        return new Vector3(this._x - otherVector._x, this._y - otherVector._y, this._z - otherVector._z);\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given vector from the current Vector3 and stores the result in the vector \"result\".\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#63\r\n     * @param otherVector defines the second operand\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public subtractToRef<T extends IVector3LikeInternal>(otherVector: DeepImmutable<IVector3LikeInternal>, result: T): T {\r\n        return this.subtractFromFloatsToRef(otherVector._x, otherVector._y, otherVector._z, result);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the subtraction of the given floats from the current Vector3 coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#62\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the resulting Vector3\r\n     */\r\n    public subtractFromFloats(x: number, y: number, z: number): Vector3 {\r\n        return new Vector3(this._x - x, this._y - y, this._z - z);\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current Vector3 coordinates and set the given vector \"result\" with this result\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#64\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public subtractFromFloatsToRef<T extends IVector3LikeInternal>(x: number, y: number, z: number, result: T): T {\r\n        result._x = this._x - x;\r\n        result._y = this._y - y;\r\n        result._z = this._z - z;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector3 set with the current Vector3 negated coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#35\r\n     * @returns a new Vector3\r\n     */\r\n    public negate(): Vector3 {\r\n        return new Vector3(-this._x, -this._y, -this._z);\r\n    }\r\n\r\n    /**\r\n     * Negate this vector in place\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#36\r\n     * @returns this\r\n     */\r\n    public negateInPlace(): this {\r\n        this._x *= -1;\r\n        this._y *= -1;\r\n        this._z *= -1;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Negate the current Vector3 and stores the result in the given vector \"result\" coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#37\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public negateToRef<T extends IVector3LikeInternal>(result: T): T {\r\n        result._x = this._x * -1;\r\n        result._y = this._y * -1;\r\n        result._z = this._z * -1;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the Vector3 coordinates by the float \"scale\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#56\r\n     * @param scale defines the multiplier factor\r\n     * @returns the current updated Vector3\r\n     */\r\n    public scaleInPlace(scale: number): this {\r\n        this._x *= scale;\r\n        this._y *= scale;\r\n        this._z *= scale;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the current Vector3 coordinates multiplied by the float \"scale\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#53\r\n     * @param scale defines the multiplier factor\r\n     * @returns a new Vector3\r\n     */\r\n    public scale(scale: number): Vector3 {\r\n        return new Vector3(this._x * scale, this._y * scale, this._z * scale);\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current Vector3 coordinates by the float \"scale\" and stores the result in the given vector \"result\" coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#57\r\n     * @param scale defines the multiplier factor\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public scaleToRef<T extends IVector3LikeInternal>(scale: number, result: T): T {\r\n        result._x = this._x * scale;\r\n        result._y = this._y * scale;\r\n        result._z = this._z * scale;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a vector normal (perpendicular) to the current Vector3 and stores the result in the given vector\r\n     * Out of the infinite possibilities the normal chosen is the one formed by rotating the current vector\r\n     * 90 degrees about an axis which lies perpendicular to the current vector\r\n     * and its projection on the xz plane. In the case of a current vector in the xz plane\r\n     * the normal is calculated to be along the y axis.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#230\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#231\r\n     * @param result defines the Vector3 object where to store the resultant normal\r\n     * @returns the result\r\n     */\r\n    public getNormalToRef(result: Vector3): Vector3 {\r\n        /**\r\n         * Calculates the spherical coordinates of the current vector\r\n         * so saves on memory rather than importing whole Spherical Class\r\n         */\r\n        const radius: number = this.length();\r\n        let theta: number = Math.acos(this._y / radius);\r\n        const phi = Math.atan2(this._z, this._x);\r\n        //makes angle 90 degs to current vector\r\n        if (theta > Math.PI / 2) {\r\n            theta -= Math.PI / 2;\r\n        } else {\r\n            theta += Math.PI / 2;\r\n        }\r\n        //Calculates resutant normal vector from spherical coordinate of perpendicular vector\r\n        const x = radius * Math.sin(theta) * Math.cos(phi);\r\n        const y = radius * Math.cos(theta);\r\n        const z = radius * Math.sin(theta) * Math.sin(phi);\r\n        result.set(x, y, z);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Rotates the vector using the given unit quaternion and stores the new vector in result\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#9\r\n     * @param q the unit quaternion representing the rotation\r\n     * @param result the output vector\r\n     * @returns the result\r\n     */\r\n    public applyRotationQuaternionToRef<T extends Vector3>(q: Quaternion, result: T): T {\r\n        // Derived from https://raw.org/proof/vector-rotation-using-quaternions/\r\n\r\n        const vx = this._x,\r\n            vy = this._y,\r\n            vz = this._z;\r\n        const qx = q._x,\r\n            qy = q._y,\r\n            qz = q._z,\r\n            qw = q._w;\r\n\r\n        // t = 2q x v\r\n        const tx = 2 * (qy * vz - qz * vy);\r\n        const ty = 2 * (qz * vx - qx * vz);\r\n        const tz = 2 * (qx * vy - qy * vx);\r\n\r\n        // v + w t + q x t\r\n        result._x = vx + qw * tx + qy * tz - qz * ty;\r\n        result._y = vy + qw * ty + qz * tx - qx * tz;\r\n        result._z = vz + qw * tz + qx * ty - qy * tx;\r\n\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Rotates the vector in place using the given unit quaternion\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#8\r\n     * @param q the unit quaternion representing the rotation\r\n     * @returns the current updated Vector3\r\n     */\r\n    public applyRotationQuaternionInPlace(q: Quaternion): this {\r\n        return this.applyRotationQuaternionToRef(q, this);\r\n    }\r\n\r\n    /**\r\n     * Rotates the vector using the given unit quaternion and returns the new vector\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#7\r\n     * @param q the unit quaternion representing the rotation\r\n     * @returns a new Vector3\r\n     */\r\n    public applyRotationQuaternion(q: Quaternion): Vector3 {\r\n        return this.applyRotationQuaternionToRef(q, new Vector3());\r\n    }\r\n\r\n    /**\r\n     * Scale the current Vector3 values by a factor and add the result to a given Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#55\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleAndAddToRef<T extends IVector3LikeInternal>(scale: number, result: T): T {\r\n        result._x += this._x * scale;\r\n        result._y += this._y * scale;\r\n        result._z += this._z * scale;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Projects the current point Vector3 to a plane along a ray starting from a specified origin and passing through the current point Vector3.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#48\r\n     * @param plane defines the plane to project to\r\n     * @param origin defines the origin of the projection ray\r\n     * @returns the projected vector3\r\n     */\r\n    public projectOnPlane(plane: Plane, origin: Vector3): Vector3 {\r\n        return this.projectOnPlaneToRef(plane, origin, new Vector3());\r\n    }\r\n\r\n    /**\r\n     * Projects the current point Vector3 to a plane along a ray starting from a specified origin and passing through the current point Vector3.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#49\r\n     * @param plane defines the plane to project to\r\n     * @param origin defines the origin of the projection ray\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public projectOnPlaneToRef<T extends Vector3>(plane: Plane, origin: Vector3, result: T): T {\r\n        const n = plane.normal;\r\n        const d = plane.d;\r\n\r\n        const V = MathTmp.Vector3[0];\r\n\r\n        // ray direction\r\n        this.subtractToRef(origin, V);\r\n\r\n        V.normalize();\r\n\r\n        const denom = Vector3.Dot(V, n);\r\n\r\n        //When the ray is close to parallel to the plane return infinity vector\r\n        if (Math.abs(denom) < 0.0000000001) {\r\n            result.setAll(Infinity);\r\n        } else {\r\n            const t = -(Vector3.Dot(origin, n) + d) / denom;\r\n\r\n            // P = P0 + t*V\r\n            const scaledV = V.scaleInPlace(t);\r\n            origin.addToRef(scaledV, result);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the current Vector3 and the given vector coordinates are strictly equal\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#19\r\n     * @param otherVector defines the second operand\r\n     * @returns true if both vectors are equals\r\n     */\r\n    public equals(otherVector: DeepImmutable<Vector3>): boolean {\r\n        return otherVector && this._x === otherVector._x && this._y === otherVector._y && this._z === otherVector._z;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the current Vector3 and the given vector coordinates are distant less than epsilon\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#21\r\n     * @param otherVector defines the second operand\r\n     * @param epsilon defines the minimal distance to define values as equals\r\n     * @returns true if both vectors are distant less than epsilon\r\n     */\r\n    public equalsWithEpsilon(otherVector: DeepImmutable<Vector3>, epsilon: number = Epsilon): boolean {\r\n        return otherVector && WithinEpsilon(this._x, otherVector._x, epsilon) && WithinEpsilon(this._y, otherVector._y, epsilon) && WithinEpsilon(this._z, otherVector._z, epsilon);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the current Vector3 coordinates equals the given floats\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#20\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns true if both vectors are equal\r\n     */\r\n    public equalsToFloats(x: number, y: number, z: number): boolean {\r\n        return this._x === x && this._y === y && this._z === z;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current Vector3 coordinates by the given ones\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#32\r\n     * @param otherVector defines the second operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public multiplyInPlace(otherVector: DeepImmutable<IVector3LikeInternal>): this {\r\n        this._x *= otherVector._x;\r\n        this._y *= otherVector._y;\r\n        this._z *= otherVector._z;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3, result of the multiplication of the current Vector3 by the given vector\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#31\r\n     * @param otherVector defines the second operand\r\n     * @returns the new Vector3\r\n     */\r\n    public multiply(otherVector: DeepImmutable<IVector3LikeInternal>): Vector3 {\r\n        return this.multiplyByFloats(otherVector._x, otherVector._y, otherVector._z);\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current Vector3 by the given one and stores the result in the given vector \"result\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#33\r\n     * @param otherVector defines the second operand\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public multiplyToRef<T extends IVector3LikeInternal>(otherVector: DeepImmutable<IVector3LikeInternal>, result: T): T {\r\n        result._x = this._x * otherVector._x;\r\n        result._y = this._y * otherVector._y;\r\n        result._z = this._z * otherVector._z;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the result of the multiplication of the current Vector3 coordinates by the given floats\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#34\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the new Vector3\r\n     */\r\n    public multiplyByFloats(x: number, y: number, z: number): Vector3 {\r\n        return new Vector3(this._x * x, this._y * y, this._z * z);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the result of the division of the current Vector3 coordinates by the given ones\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#16\r\n     * @param otherVector defines the second operand\r\n     * @returns the new Vector3\r\n     */\r\n    public divide(otherVector: DeepImmutable<IVector3LikeInternal>): Vector3 {\r\n        return new Vector3(this._x / otherVector._x, this._y / otherVector._y, this._z / otherVector._z);\r\n    }\r\n\r\n    /**\r\n     * Divides the current Vector3 coordinates by the given ones and stores the result in the given vector \"result\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#18\r\n     * @param otherVector defines the second operand\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public divideToRef<T extends IVector3LikeInternal>(otherVector: DeepImmutable<IVector3LikeInternal>, result: T): T {\r\n        result._x = this._x / otherVector._x;\r\n        result._y = this._y / otherVector._y;\r\n        result._z = this._z / otherVector._z;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Vector3 coordinates by the given ones.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#17\r\n     * @param otherVector defines the second operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public divideInPlace(otherVector: DeepImmutable<IVector3LikeInternal>): this {\r\n        this._x = this._x / otherVector._x;\r\n        this._y = this._y / otherVector._y;\r\n        this._z = this._z / otherVector._z;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector3 with the minimal coordinate values between its and the given vector ones\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#29\r\n     * @param other defines the second operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public minimizeInPlace(other: DeepImmutable<IVector3LikeInternal>): this {\r\n        return this.minimizeInPlaceFromFloats(other._x, other._y, other._z);\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector3 with the maximal coordinate values between its and the given vector ones.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#27\r\n     * @param other defines the second operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public maximizeInPlace(other: DeepImmutable<IVector3LikeInternal>): this {\r\n        return this.maximizeInPlaceFromFloats(other._x, other._y, other._z);\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector3 with the minimal coordinate values between its and the given coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#30\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public minimizeInPlaceFromFloats(x: number, y: number, z: number): this {\r\n        if (x < this._x) {\r\n            this.x = x;\r\n        }\r\n        if (y < this._y) {\r\n            this.y = y;\r\n        }\r\n        if (z < this._z) {\r\n            this.z = z;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector3 with the maximal coordinate values between its and the given coordinates.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#28\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public maximizeInPlaceFromFloats(x: number, y: number, z: number): this {\r\n        if (x > this._x) {\r\n            this.x = x;\r\n        }\r\n        if (y > this._y) {\r\n            this.y = y;\r\n        }\r\n        if (z > this._z) {\r\n            this.z = z;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Due to float precision, scale of a mesh could be uniform but float values are off by a small fraction\r\n     * Check if is non uniform within a certain amount of decimal places to account for this\r\n     * @param epsilon the amount the values can differ\r\n     * @returns if the vector is non uniform to a certain number of decimal places\r\n     */\r\n    public isNonUniformWithinEpsilon(epsilon: number) {\r\n        const absX = Math.abs(this._x);\r\n        const absY = Math.abs(this._y);\r\n        if (!WithinEpsilon(absX, absY, epsilon)) {\r\n            return true;\r\n        }\r\n\r\n        const absZ = Math.abs(this._z);\r\n        if (!WithinEpsilon(absX, absZ, epsilon)) {\r\n            return true;\r\n        }\r\n\r\n        if (!WithinEpsilon(absY, absZ, epsilon)) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the vector is non uniform meaning x, y or z are not all the same\r\n     */\r\n    public get isNonUniform(): boolean {\r\n        const absX = Math.abs(this._x);\r\n        const absY = Math.abs(this._y);\r\n        if (absX !== absY) {\r\n            return true;\r\n        }\r\n\r\n        const absZ = Math.abs(this._z);\r\n        if (absX !== absZ) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets the current Vector3's floored values and stores them in result\r\n     * @param result the vector to store the result in\r\n     * @returns the result vector\r\n     */\r\n    public floorToRef<T extends IVector3LikeInternal>(result: T): T {\r\n        result._x = Math.floor(this._x);\r\n        result._y = Math.floor(this._y);\r\n        result._z = Math.floor(this._z);\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector3 from current Vector3 floored values\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#22\r\n     * @returns a new Vector3\r\n     */\r\n    public floor(): Vector3 {\r\n        return new Vector3(Math.floor(this._x), Math.floor(this._y), Math.floor(this._z));\r\n    }\r\n\r\n    /**\r\n     * Gets the current Vector3's fractional values and stores them in result\r\n     * @param result the vector to store the result in\r\n     * @returns the result vector\r\n     */\r\n    public fractToRef<T extends IVector3LikeInternal>(result: T): T {\r\n        result._x = this._x - Math.floor(this._x);\r\n        result._y = this._y - Math.floor(this._y);\r\n        result._z = this._z - Math.floor(this._z);\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector3 from current Vector3 fractional values\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#23\r\n     * @returns a new Vector3\r\n     */\r\n    public fract(): Vector3 {\r\n        return new Vector3(this._x - Math.floor(this._x), this._y - Math.floor(this._y), this._z - Math.floor(this._z));\r\n    }\r\n\r\n    // Properties\r\n    /**\r\n     * Gets the length of the Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#25\r\n     * @returns the length of the Vector3\r\n     */\r\n    public length(): number {\r\n        return Math.sqrt(this.lengthSquared());\r\n    }\r\n\r\n    /**\r\n     * Gets the squared length of the Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#26\r\n     * @returns squared length of the Vector3\r\n     */\r\n    public lengthSquared(): number {\r\n        return this._x * this._x + this._y * this._y + this._z * this._z;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the vector contains a zero in one of its components\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#1\r\n     */\r\n    public get hasAZeroComponent(): boolean {\r\n        return this._x * this._y * this._z === 0;\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector3.\r\n     * Please note that this is an in place operation.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#122\r\n     * @returns the current updated Vector3\r\n     */\r\n    public normalize(): this {\r\n        return this.normalizeFromLength(this.length());\r\n    }\r\n\r\n    /**\r\n     * Reorders the x y z properties of the vector in place\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#44\r\n     * @param order new ordering of the properties (eg. for vector 1,2,3 with \"ZYX\" will produce 3,2,1)\r\n     * @returns the current updated vector\r\n     */\r\n    public reorderInPlace(order: string) {\r\n        order = order.toLowerCase();\r\n        if (order === \"xyz\") {\r\n            return this;\r\n        }\r\n        const tem = MathTmp.Vector3[0].copyFrom(this);\r\n        this.x = (<any>tem)[order[0]];\r\n        this.y = (<any>tem)[order[1]];\r\n        this.z = (<any>tem)[order[2]];\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Rotates the vector around 0,0,0 by a quaternion\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#47\r\n     * @param quaternion the rotation quaternion\r\n     * @param result vector to store the result\r\n     * @returns the resulting vector\r\n     */\r\n    public rotateByQuaternionToRef<T extends Vector3>(quaternion: Quaternion, result: T): T {\r\n        quaternion.toRotationMatrix(MathTmp.Matrix[0]);\r\n        Vector3.TransformCoordinatesToRef(this, MathTmp.Matrix[0], result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Rotates a vector around a given point\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#46\r\n     * @param quaternion the rotation quaternion\r\n     * @param point the point to rotate around\r\n     * @param result vector to store the result\r\n     * @returns the resulting vector\r\n     */\r\n    public rotateByQuaternionAroundPointToRef<T extends Vector3>(quaternion: Quaternion, point: Vector3, result: T): T {\r\n        this.subtractToRef(point, MathTmp.Vector3[0]);\r\n        MathTmp.Vector3[0].rotateByQuaternionToRef(quaternion, MathTmp.Vector3[0]);\r\n        point.addToRef(MathTmp.Vector3[0], result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 as the cross product of the current vector and the \"other\" one\r\n     * The cross product is then orthogonal to both current and \"other\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#14\r\n     * @param other defines the right operand\r\n     * @returns the cross product\r\n     */\r\n    public cross(other: Vector3): Vector3 {\r\n        return Vector3.CrossToRef(this, other, new Vector3());\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector3 with the given input length.\r\n     * Please note that this is an in place operation.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#123\r\n     * @param len the length of the vector\r\n     * @returns the current updated Vector3\r\n     */\r\n    public normalizeFromLength(len: number): this {\r\n        if (len === 0 || len === 1.0) {\r\n            return this;\r\n        }\r\n\r\n        return this.scaleInPlace(1.0 / len);\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector3 to a new vector\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#124\r\n     * @returns the new Vector3\r\n     */\r\n    public normalizeToNew(): Vector3 {\r\n        return this.normalizeToRef(new Vector3());\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector3 to the reference\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#125\r\n     * @param result define the Vector3 to update\r\n     * @returns the updated Vector3\r\n     */\r\n    public normalizeToRef<T extends IVector3LikeInternal>(result: T): T {\r\n        const len = this.length();\r\n        if (len === 0 || len === 1.0) {\r\n            result._x = this._x;\r\n            result._y = this._y;\r\n            result._z = this._z;\r\n            result._isDirty = true;\r\n            return result;\r\n        }\r\n\r\n        return this.scaleToRef(1.0 / len, result);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Vector3 copied from the current Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#11\r\n     * @returns the new Vector3\r\n     */\r\n    public clone(): Vector3 {\r\n        return new Vector3(this._x, this._y, this._z);\r\n    }\r\n\r\n    /**\r\n     * Copies the given vector coordinates to the current Vector3 ones\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#12\r\n     * @param source defines the source Vector3\r\n     * @returns the current updated Vector3\r\n     */\r\n    public copyFrom(source: DeepImmutable<Vector3>): this {\r\n        return this.copyFromFloats(source._x, source._y, source._z);\r\n    }\r\n\r\n    /**\r\n     * Copies the given floats to the current Vector3 coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#13\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public copyFromFloats(x: number, y: number, z: number): this {\r\n        this._x = x;\r\n        this._y = y;\r\n        this._z = z;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copies the given floats to the current Vector3 coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#58\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public set(x: number, y: number, z: number): this {\r\n        return this.copyFromFloats(x, y, z);\r\n    }\r\n\r\n    /**\r\n     * Copies the given float to the current Vector3 coordinates\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#59\r\n     * @param v defines the x, y and z coordinates of the operand\r\n     * @returns the current updated Vector3\r\n     */\r\n    public setAll(v: number): this {\r\n        this._x = this._y = this._z = v;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Get the clip factor between two vectors\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#126\r\n     * @param vector0 defines the first operand\r\n     * @param vector1 defines the second operand\r\n     * @param axis defines the axis to use\r\n     * @param size defines the size along the axis\r\n     * @returns the clip factor\r\n     */\r\n    public static GetClipFactor(vector0: DeepImmutable<Vector3>, vector1: DeepImmutable<Vector3>, axis: DeepImmutable<Vector3>, size: number): number {\r\n        const d0 = Vector3.Dot(vector0, axis);\r\n        const d1 = Vector3.Dot(vector1, axis);\r\n\r\n        return (d0 - size) / (d0 - d1);\r\n    }\r\n\r\n    /**\r\n     * Get angle between two vectors\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#86\r\n     * @param vector0 the starting point\r\n     * @param vector1 the ending point\r\n     * @param normal direction of the normal\r\n     * @returns the angle between vector0 and vector1\r\n     */\r\n    public static GetAngleBetweenVectors(vector0: DeepImmutable<Vector3>, vector1: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>): number {\r\n        const v0: Vector3 = vector0.normalizeToRef(MathTmp.Vector3[1]);\r\n        const v1: Vector3 = vector1.normalizeToRef(MathTmp.Vector3[2]);\r\n        let dot: number = Vector3.Dot(v0, v1);\r\n        // Vectors are normalized so dot will be in [-1, 1] (aside precision issues enough to break the result which explains the below clamp)\r\n        dot = Clamp(dot, -1, 1);\r\n\r\n        const angle = Math.acos(dot);\r\n        const n = MathTmp.Vector3[3];\r\n        Vector3.CrossToRef(v0, v1, n);\r\n        if (Vector3.Dot(n, normal) > 0) {\r\n            return isNaN(angle) ? 0 : angle;\r\n        }\r\n        return isNaN(angle) ? -Math.PI : -Math.acos(dot);\r\n    }\r\n\r\n    /**\r\n     * Get angle between two vectors projected on a plane\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#87\r\n     * Expectation compute time: 0.01 ms (median) and 0.02 ms (percentile 95%)\r\n     * @param vector0 angle between vector0 and vector1\r\n     * @param vector1 angle between vector0 and vector1\r\n     * @param normal Normal of the projection plane\r\n     * @returns the angle in radians (float) between vector0 and vector1 projected on the plane with the specified normal\r\n     */\r\n    public static GetAngleBetweenVectorsOnPlane(vector0: DeepImmutable<Vector3>, vector1: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>): number {\r\n        MathTmp.Vector3[0].copyFrom(vector0);\r\n        const v0 = MathTmp.Vector3[0];\r\n        MathTmp.Vector3[1].copyFrom(vector1);\r\n        const v1 = MathTmp.Vector3[1];\r\n        MathTmp.Vector3[2].copyFrom(normal);\r\n        const vNormal = MathTmp.Vector3[2];\r\n        const right = MathTmp.Vector3[3];\r\n        const forward = MathTmp.Vector3[4];\r\n\r\n        v0.normalize();\r\n        v1.normalize();\r\n        vNormal.normalize();\r\n\r\n        Vector3.CrossToRef(vNormal, v0, right);\r\n        Vector3.CrossToRef(right, vNormal, forward);\r\n\r\n        const angle = Math.atan2(Vector3.Dot(v1, right), Vector3.Dot(v1, forward));\r\n\r\n        return NormalizeRadians(angle);\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation that aligns the roll axis (Y) to the line joining the start point to the target point and stores it in the ref Vector3\r\n     * Example PG https://playground.babylonjs.com/#R1F8YU#189\r\n     * @param start the starting point\r\n     * @param target the target point\r\n     * @param ref the vector3 to store the result\r\n     * @returns ref in the form (pitch, yaw, 0)\r\n     */\r\n    public static PitchYawRollToMoveBetweenPointsToRef<T extends Vector3>(start: Vector3, target: Vector3, ref: T): T {\r\n        const diff = TmpVectors.Vector3[0];\r\n        target.subtractToRef(start, diff);\r\n        ref._y = Math.atan2(diff.x, diff.z) || 0;\r\n        ref._x = Math.atan2(Math.sqrt(diff.x ** 2 + diff.z ** 2), diff.y) || 0;\r\n        ref._z = 0;\r\n        ref._isDirty = true;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation that aligns the roll axis (Y) to the line joining the start point to the target point\r\n     * Example PG https://playground.babylonjs.com/#R1F8YU#188\r\n     * @param start the starting point\r\n     * @param target the target point\r\n     * @returns the rotation in the form (pitch, yaw, 0)\r\n     */\r\n    public static PitchYawRollToMoveBetweenPoints(start: Vector3, target: Vector3): Vector3 {\r\n        const ref = Vector3.Zero();\r\n        return Vector3.PitchYawRollToMoveBetweenPointsToRef(start, target, ref);\r\n    }\r\n\r\n    /**\r\n     * Slerp between two vectors. See also `SmoothToRef`\r\n     * Slerp is a spherical linear interpolation\r\n     * giving a slow in and out effect\r\n     * Example Playground 1 https://playground.babylonjs.com/#R1F8YU#108\r\n     * Example Playground 2 https://playground.babylonjs.com/#R1F8YU#109\r\n     * @param vector0 Start vector\r\n     * @param vector1 End vector\r\n     * @param slerp amount (will be clamped between 0 and 1)\r\n     * @param result The slerped vector\r\n     * @returns The slerped vector\r\n     */\r\n    public static SlerpToRef<T extends Vector3 = Vector3>(vector0: Vector3, vector1: Vector3, slerp: number, result: T): T {\r\n        slerp = Clamp(slerp, 0, 1);\r\n        const vector0Dir = MathTmp.Vector3[0];\r\n        const vector1Dir = MathTmp.Vector3[1];\r\n\r\n        vector0Dir.copyFrom(vector0);\r\n        const vector0Length = vector0Dir.length();\r\n        vector0Dir.normalizeFromLength(vector0Length);\r\n\r\n        vector1Dir.copyFrom(vector1);\r\n        const vector1Length = vector1Dir.length();\r\n        vector1Dir.normalizeFromLength(vector1Length);\r\n\r\n        const dot = Vector3.Dot(vector0Dir, vector1Dir);\r\n\r\n        let scale0;\r\n        let scale1;\r\n\r\n        if (dot < 1 - Epsilon) {\r\n            const omega = Math.acos(dot);\r\n            const invSin = 1 / Math.sin(omega);\r\n            scale0 = Math.sin((1 - slerp) * omega) * invSin;\r\n            scale1 = Math.sin(slerp * omega) * invSin;\r\n        } else {\r\n            // Use linear interpolation\r\n            scale0 = 1 - slerp;\r\n            scale1 = slerp;\r\n        }\r\n\r\n        vector0Dir.scaleInPlace(scale0);\r\n        vector1Dir.scaleInPlace(scale1);\r\n        result.copyFrom(vector0Dir).addInPlace(vector1Dir);\r\n        result.scaleInPlace(Lerp(vector0Length, vector1Length, slerp));\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Smooth interpolation between two vectors using Slerp\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#110\r\n     * @param source source vector\r\n     * @param goal goal vector\r\n     * @param deltaTime current interpolation frame\r\n     * @param lerpTime total interpolation time\r\n     * @param result the smoothed vector\r\n     * @returns the smoothed vector\r\n     */\r\n    public static SmoothToRef<T extends Vector3 = Vector3>(source: Vector3, goal: Vector3, deltaTime: number, lerpTime: number, result: T): T {\r\n        Vector3.SlerpToRef(source, goal, lerpTime === 0 ? 1 : deltaTime / lerpTime, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set from the index \"offset\" of the given array\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#83\r\n     * @param array defines the source array\r\n     * @param offset defines the offset in the source array\r\n     * @returns the new Vector3\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Vector3 {\r\n        return new Vector3(array[offset], array[offset + 1], array[offset + 2]);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set from the index \"offset\" of the given Float32Array\r\n     * @param array defines the source array\r\n     * @param offset defines the offset in the source array\r\n     * @returns the new Vector3\r\n     * @deprecated Please use FromArray instead.\r\n     */\r\n    public static FromFloatArray(array: DeepImmutable<Float32Array>, offset?: number): Vector3 {\r\n        return Vector3.FromArray(array, offset);\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the element values from the index \"offset\" of the given array\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#84\r\n     * @param array defines the source array\r\n     * @param offset defines the offset in the source array\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static FromArrayToRef<T extends Vector3>(array: DeepImmutable<ArrayLike<number>>, offset: number, result: T): T {\r\n        result._x = array[offset];\r\n        result._y = array[offset + 1];\r\n        result._z = array[offset + 2];\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the element values from the index \"offset\" of the given Float32Array\r\n     * @param array defines the source array\r\n     * @param offset defines the offset in the source array\r\n     * @param result defines the Vector3 where to store the result\r\n     * @deprecated Please use FromArrayToRef instead.\r\n     * @returns result input\r\n     */\r\n    public static FromFloatArrayToRef<T extends Vector3>(array: DeepImmutable<Float32Array>, offset: number, result: T): T {\r\n        return Vector3.FromArrayToRef<T>(array, offset, result);\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the given floats.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#85\r\n     * @param x defines the x coordinate of the source\r\n     * @param y defines the y coordinate of the source\r\n     * @param z defines the z coordinate of the source\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns the result vector\r\n     */\r\n    public static FromFloatsToRef<T extends Vector3 = Vector3>(x: number, y: number, z: number, result: T): T {\r\n        result.copyFromFloats(x, y, z);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set to (0.0, 0.0, 0.0)\r\n     * @returns a new empty Vector3\r\n     */\r\n    public static Zero(): Vector3 {\r\n        return new Vector3(0.0, 0.0, 0.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector3 set to (1.0, 1.0, 1.0)\r\n     * @returns a new Vector3\r\n     */\r\n    public static One(): Vector3 {\r\n        return new Vector3(1.0, 1.0, 1.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector3 set to (0.0, 1.0, 0.0)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n     * @returns a new up Vector3\r\n     */\r\n    public static Up(): Vector3 {\r\n        return new Vector3(0.0, 1.0, 0.0);\r\n    }\r\n\r\n    /**\r\n     * Gets an up Vector3 that must not be updated\r\n     */\r\n    public static get UpReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._UpReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a down Vector3 that must not be updated\r\n     */\r\n    public static get DownReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._DownReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a right Vector3 that must not be updated\r\n     */\r\n    public static get RightReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._RightReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a left Vector3 that must not be updated\r\n     */\r\n    public static get LeftReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._LeftReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a forward Vector3 that must not be updated\r\n     */\r\n    public static get LeftHandedForwardReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._LeftHandedForwardReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a forward Vector3 that must not be updated\r\n     */\r\n    public static get RightHandedForwardReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._RightHandedForwardReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a backward Vector3 that must not be updated\r\n     */\r\n    public static get LeftHandedBackwardReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._LeftHandedBackwardReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a backward Vector3 that must not be updated\r\n     */\r\n    public static get RightHandedBackwardReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._RightHandedBackwardReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a zero Vector3 that must not be updated\r\n     */\r\n    public static get ZeroReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._ZeroReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a one Vector3 that must not be updated\r\n     */\r\n    public static get OneReadOnly(): DeepImmutable<Vector3> {\r\n        return Vector3._OneReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set to (0.0, -1.0, 0.0)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n     * @returns a new down Vector3\r\n     */\r\n    public static Down(): Vector3 {\r\n        return new Vector3(0.0, -1.0, 0.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector3 set to (0.0, 0.0, 1.0)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n     * @param rightHandedSystem is the scene right-handed (negative z)\r\n     * @returns a new forward Vector3\r\n     */\r\n    public static Forward(rightHandedSystem: boolean = false): Vector3 {\r\n        return new Vector3(0.0, 0.0, rightHandedSystem ? -1.0 : 1.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector3 set to (0.0, 0.0, -1.0)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n     * @param rightHandedSystem is the scene right-handed (negative-z)\r\n     * @returns a new Backward Vector3\r\n     */\r\n    public static Backward(rightHandedSystem: boolean = false): Vector3 {\r\n        return new Vector3(0.0, 0.0, rightHandedSystem ? 1.0 : -1.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector3 set to (1.0, 0.0, 0.0)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n     * @returns a new right Vector3\r\n     */\r\n    public static Right(): Vector3 {\r\n        return new Vector3(1.0, 0.0, 0.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector3 set to (-1.0, 0.0, 0.0)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n     * @returns a new left Vector3\r\n     */\r\n    public static Left(): Vector3 {\r\n        return new Vector3(-1.0, 0.0, 0.0);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @returns a Vector3 with random values between min and max\r\n     */\r\n    public static Random(min: number = 0, max: number = 1): Vector3 {\r\n        return new Vector3(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector3 with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @param ref the ref to store the values in\r\n     * @returns the ref with random values between min and max\r\n     */\r\n    public static RandomToRef<T extends Vector3>(min: number = 0, max: number = 1, ref: T): T {\r\n        return ref.copyFromFloats(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the result of the transformation by the given matrix of the given vector.\r\n     * This method computes transformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#111\r\n     * @param vector defines the Vector3 to transform\r\n     * @param transformation defines the transformation matrix\r\n     * @returns the transformed Vector3\r\n     */\r\n    public static TransformCoordinates(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>): Vector3 {\r\n        const result = Vector3.Zero();\r\n        Vector3.TransformCoordinatesToRef(vector, transformation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given vector\r\n     * This method computes transformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#113\r\n     * @param vector defines the Vector3 to transform\r\n     * @param transformation defines the transformation matrix\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static TransformCoordinatesToRef<T extends Vector3>(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        Vector3.TransformCoordinatesFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given floats (x, y, z)\r\n     * This method computes transformed coordinates only, not transformed direction vectors\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#115\r\n     * @param x define the x coordinate of the source vector\r\n     * @param y define the y coordinate of the source vector\r\n     * @param z define the z coordinate of the source vector\r\n     * @param transformation defines the transformation matrix\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static TransformCoordinatesFromFloatsToRef<T extends Vector3>(x: number, y: number, z: number, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        const m = transformation.m;\r\n        const rx = x * m[0] + y * m[4] + z * m[8] + m[12];\r\n        const ry = x * m[1] + y * m[5] + z * m[9] + m[13];\r\n        const rz = x * m[2] + y * m[6] + z * m[10] + m[14];\r\n        const rw = 1 / (x * m[3] + y * m[7] + z * m[11] + m[15]);\r\n\r\n        result._x = rx * rw;\r\n        result._y = ry * rw;\r\n        result._z = rz * rw;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the result of the normal transformation by the given matrix of the given vector\r\n     * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#112\r\n     * @param vector defines the Vector3 to transform\r\n     * @param transformation defines the transformation matrix\r\n     * @returns the new Vector3\r\n     */\r\n    public static TransformNormal(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>): Vector3 {\r\n        const result = Vector3.Zero();\r\n        Vector3.TransformNormalToRef(vector, transformation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given vector\r\n     * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#114\r\n     * @param vector defines the Vector3 to transform\r\n     * @param transformation defines the transformation matrix\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static TransformNormalToRef<T extends Vector3>(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        this.TransformNormalFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given floats (x, y, z)\r\n     * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#116\r\n     * @param x define the x coordinate of the source vector\r\n     * @param y define the y coordinate of the source vector\r\n     * @param z define the z coordinate of the source vector\r\n     * @param transformation defines the transformation matrix\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static TransformNormalFromFloatsToRef<T extends Vector3>(x: number, y: number, z: number, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        const m = transformation.m;\r\n        result._x = x * m[0] + y * m[4] + z * m[8];\r\n        result._y = x * m[1] + y * m[5] + z * m[9];\r\n        result._z = x * m[2] + y * m[6] + z * m[10];\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 located for \"amount\" on the CatmullRom interpolation spline defined by the vectors \"value1\", \"value2\", \"value3\", \"value4\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#69\r\n     * @param value1 defines the first control point\r\n     * @param value2 defines the second control point\r\n     * @param value3 defines the third control point\r\n     * @param value4 defines the fourth control point\r\n     * @param amount defines the amount on the spline to use\r\n     * @returns the new Vector3\r\n     */\r\n    public static CatmullRom(\r\n        value1: DeepImmutable<Vector3>,\r\n        value2: DeepImmutable<Vector3>,\r\n        value3: DeepImmutable<Vector3>,\r\n        value4: DeepImmutable<Vector3>,\r\n        amount: number\r\n    ): Vector3 {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n\r\n        const x =\r\n            0.5 *\r\n            (2.0 * value2._x +\r\n                (-value1._x + value3._x) * amount +\r\n                (2.0 * value1._x - 5.0 * value2._x + 4.0 * value3._x - value4._x) * squared +\r\n                (-value1._x + 3.0 * value2._x - 3.0 * value3._x + value4._x) * cubed);\r\n\r\n        const y =\r\n            0.5 *\r\n            (2.0 * value2._y +\r\n                (-value1._y + value3._y) * amount +\r\n                (2.0 * value1._y - 5.0 * value2._y + 4.0 * value3._y - value4._y) * squared +\r\n                (-value1._y + 3.0 * value2._y - 3.0 * value3._y + value4._y) * cubed);\r\n\r\n        const z =\r\n            0.5 *\r\n            (2.0 * value2._z +\r\n                (-value1._z + value3._z) * amount +\r\n                (2.0 * value1._z - 5.0 * value2._z + 4.0 * value3._z - value4._z) * squared +\r\n                (-value1._z + 3.0 * value2._z - 3.0 * value3._z + value4._z) * cubed);\r\n\r\n        return new Vector3(x, y, z);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n     * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n     * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#76\r\n     * @param value defines the current value\r\n     * @param min defines the lower range value\r\n     * @param max defines the upper range value\r\n     * @returns the new Vector3\r\n     */\r\n    public static Clamp(value: DeepImmutable<Vector3>, min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>): Vector3 {\r\n        const result = new Vector3();\r\n        Vector3.ClampToRef(value, min, max, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n     * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n     * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#77\r\n     * @param value defines the current value\r\n     * @param min defines the lower range value\r\n     * @param max defines the upper range value\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static ClampToRef<T extends Vector3>(value: DeepImmutable<Vector3>, min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, result: T): T {\r\n        let x = value._x;\r\n        x = x > max._x ? max._x : x;\r\n        x = x < min._x ? min._x : x;\r\n\r\n        let y = value._y;\r\n        y = y > max._y ? max._y : y;\r\n        y = y < min._y ? min._y : y;\r\n\r\n        let z = value._z;\r\n        z = z > max._z ? max._z : z;\r\n        z = z < min._z ? min._z : z;\r\n\r\n        result.copyFromFloats(x, y, z);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Checks if a given vector is inside a specific range\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#75\r\n     * @param v defines the vector to test\r\n     * @param min defines the minimum range\r\n     * @param max defines the maximum range\r\n     */\r\n    public static CheckExtends(v: Vector3, min: Vector3, max: Vector3): void {\r\n        min.minimizeInPlace(v);\r\n        max.maximizeInPlace(v);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 located for \"amount\" (float) on the Hermite interpolation spline defined by the vectors \"value1\", \"tangent1\", \"value2\", \"tangent2\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#89\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent vector\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent vector\r\n     * @param amount defines the amount on the interpolation spline (between 0 and 1)\r\n     * @returns the new Vector3\r\n     */\r\n    public static Hermite(\r\n        value1: DeepImmutable<Vector3>,\r\n        tangent1: DeepImmutable<Vector3>,\r\n        value2: DeepImmutable<Vector3>,\r\n        tangent2: DeepImmutable<Vector3>,\r\n        amount: number\r\n    ): Vector3 {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n        const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n        const part2 = -2.0 * cubed + 3.0 * squared;\r\n        const part3 = cubed - 2.0 * squared + amount;\r\n        const part4 = cubed - squared;\r\n\r\n        const x = value1._x * part1 + value2._x * part2 + tangent1._x * part3 + tangent2._x * part4;\r\n        const y = value1._y * part1 + value2._y * part2 + tangent1._y * part3 + tangent2._y * part4;\r\n        const z = value1._z * part1 + value2._z * part2 + tangent1._z * part3 + tangent2._z * part4;\r\n        return new Vector3(x, y, z);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 which is the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#90\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @returns 1st derivative\r\n     */\r\n    public static Hermite1stDerivative(\r\n        value1: DeepImmutable<Vector3>,\r\n        tangent1: DeepImmutable<Vector3>,\r\n        value2: DeepImmutable<Vector3>,\r\n        tangent2: DeepImmutable<Vector3>,\r\n        time: number\r\n    ): Vector3 {\r\n        const result = new Vector3();\r\n\r\n        this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Update a Vector3 with the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#91\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @param result define where to store the derivative\r\n     * @returns result input\r\n     */\r\n    public static Hermite1stDerivativeToRef<T extends Vector3>(\r\n        value1: DeepImmutable<Vector3>,\r\n        tangent1: DeepImmutable<Vector3>,\r\n        value2: DeepImmutable<Vector3>,\r\n        tangent2: DeepImmutable<Vector3>,\r\n        time: number,\r\n        result: T\r\n    ): T {\r\n        const t2 = time * time;\r\n\r\n        result._x = (t2 - time) * 6 * value1._x + (3 * t2 - 4 * time + 1) * tangent1._x + (-t2 + time) * 6 * value2._x + (3 * t2 - 2 * time) * tangent2._x;\r\n        result._y = (t2 - time) * 6 * value1._y + (3 * t2 - 4 * time + 1) * tangent1._y + (-t2 + time) * 6 * value2._y + (3 * t2 - 2 * time) * tangent2._y;\r\n        result._z = (t2 - time) * 6 * value1._z + (3 * t2 - 4 * time + 1) * tangent1._z + (-t2 + time) * 6 * value2._z + (3 * t2 - 2 * time) * tangent2._z;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 located for \"amount\" (float) on the linear interpolation between the vectors \"start\" and \"end\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#95\r\n     * @param start defines the start value\r\n     * @param end defines the end value\r\n     * @param amount max defines amount between both (between 0 and 1)\r\n     * @returns the new Vector3\r\n     */\r\n    public static Lerp(start: DeepImmutable<Vector3>, end: DeepImmutable<Vector3>, amount: number): Vector3 {\r\n        const result = new Vector3(0, 0, 0);\r\n        Vector3.LerpToRef(start, end, amount, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the linear interpolation from the vector \"start\" for \"amount\" to the vector \"end\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#93\r\n     * @param start defines the start value\r\n     * @param end defines the end value\r\n     * @param amount max defines amount between both (between 0 and 1)\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static LerpToRef<T extends Vector3>(start: DeepImmutable<Vector3>, end: DeepImmutable<Vector3>, amount: number, result: T): T {\r\n        result._x = start._x + (end._x - start._x) * amount;\r\n        result._y = start._y + (end._y - start._y) * amount;\r\n        result._z = start._z + (end._z - start._z) * amount;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns the dot product (float) between the vectors \"left\" and \"right\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#82\r\n     * @param left defines the left operand\r\n     * @param right defines the right operand\r\n     * @returns the dot product\r\n     */\r\n    public static Dot(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): number {\r\n        return left._x * right._x + left._y * right._y + left._z * right._z;\r\n    }\r\n\r\n    /**\r\n     * Returns the dot product (float) between the current vectors and \"otherVector\"\r\n     * @param otherVector defines the right operand\r\n     * @returns the dot product\r\n     */\r\n    public dot(otherVector: DeepImmutable<Vector3>): number {\r\n        return this._x * otherVector._x + this._y * otherVector._y + this._z * otherVector._z;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 as the cross product of the vectors \"left\" and \"right\"\r\n     * The cross product is then orthogonal to both \"left\" and \"right\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#15\r\n     * @param left defines the left operand\r\n     * @param right defines the right operand\r\n     * @returns the cross product\r\n     */\r\n    public static Cross(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): Vector3 {\r\n        const result = new Vector3();\r\n        Vector3.CrossToRef(left, right, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the cross product of \"left\" and \"right\"\r\n     * The cross product is then orthogonal to both \"left\" and \"right\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#78\r\n     * @param left defines the left operand\r\n     * @param right defines the right operand\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static CrossToRef<T extends Vector3>(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>, result: T): T {\r\n        const x = left._y * right._z - left._z * right._y;\r\n        const y = left._z * right._x - left._x * right._z;\r\n        const z = left._x * right._y - left._y * right._x;\r\n        result.copyFromFloats(x, y, z);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 as the normalization of the given vector\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#98\r\n     * @param vector defines the Vector3 to normalize\r\n     * @returns the new Vector3\r\n     */\r\n    public static Normalize(vector: DeepImmutable<Vector3>): Vector3 {\r\n        const result = Vector3.Zero();\r\n        Vector3.NormalizeToRef(vector, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the normalization of the given first vector\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#98\r\n     * @param vector defines the Vector3 to normalize\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static NormalizeToRef<T extends Vector3>(vector: DeepImmutable<Vector3>, result: T): T {\r\n        vector.normalizeToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Project a Vector3 onto screen space\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#101\r\n     * @param vector defines the Vector3 to project\r\n     * @param world defines the world matrix to use\r\n     * @param transform defines the transform (view x projection) matrix to use\r\n     * @param viewport defines the screen viewport to use\r\n     * @returns the new Vector3\r\n     */\r\n    public static Project(vector: DeepImmutable<Vector3>, world: DeepImmutable<Matrix>, transform: DeepImmutable<Matrix>, viewport: DeepImmutable<Viewport>): Vector3 {\r\n        const result = new Vector3();\r\n        Vector3.ProjectToRef(vector, world, transform, viewport, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Project a Vector3 onto screen space to reference\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#102\r\n     * @param vector defines the Vector3 to project\r\n     * @param world defines the world matrix to use\r\n     * @param transform defines the transform (view x projection) matrix to use\r\n     * @param viewport defines the screen viewport to use\r\n     * @param result the vector in which the screen space will be stored\r\n     * @returns result input\r\n     */\r\n    public static ProjectToRef<T extends Vector3>(\r\n        vector: DeepImmutable<Vector3>,\r\n        world: DeepImmutable<Matrix>,\r\n        transform: DeepImmutable<Matrix>,\r\n        viewport: DeepImmutable<Viewport>,\r\n        result: T\r\n    ): T {\r\n        const cw = viewport.width;\r\n        const ch = viewport.height;\r\n        const cx = viewport.x;\r\n        const cy = viewport.y;\r\n\r\n        const viewportMatrix = MathTmp.Matrix[1];\r\n\r\n        const isNDCHalfZRange = EngineStore.LastCreatedEngine?.isNDCHalfZRange;\r\n        const zScale = isNDCHalfZRange ? 1 : 0.5;\r\n        const zOffset = isNDCHalfZRange ? 0 : 0.5;\r\n\r\n        Matrix.FromValuesToRef(cw / 2.0, 0, 0, 0, 0, -ch / 2.0, 0, 0, 0, 0, zScale, 0, cx + cw / 2.0, ch / 2.0 + cy, zOffset, 1, viewportMatrix);\r\n\r\n        const matrix = MathTmp.Matrix[0];\r\n        world.multiplyToRef(transform, matrix);\r\n        matrix.multiplyToRef(viewportMatrix, matrix);\r\n\r\n        Vector3.TransformCoordinatesToRef(vector, matrix, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Reflects a vector off the plane defined by a normalized normal\r\n     * @param inDirection defines the vector direction\r\n     * @param normal defines the normal - Must be normalized\r\n     * @returns the resulting vector\r\n     */\r\n    public static Reflect(inDirection: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>): Vector3 {\r\n        return this.ReflectToRef(inDirection, normal, new Vector3());\r\n    }\r\n\r\n    /**\r\n     * Reflects a vector off the plane defined by a normalized normal to reference\r\n     * @param inDirection defines the vector direction\r\n     * @param normal defines the normal - Must be normalized\r\n     * @param ref defines the Vector3 where to store the result\r\n     * @returns the resulting vector\r\n     */\r\n    public static ReflectToRef<T extends Vector3>(inDirection: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>, ref: T): T {\r\n        const tmp = TmpVectors.Vector3[0];\r\n        tmp.copyFrom(normal).scaleInPlace(2 * Vector3.Dot(inDirection, normal));\r\n\r\n        return ref.copyFrom(inDirection).subtractInPlace(tmp);\r\n    }\r\n\r\n    /**\r\n     * Unproject from screen space to object space\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#121\r\n     * @param source defines the screen space Vector3 to use\r\n     * @param viewportWidth defines the current width of the viewport\r\n     * @param viewportHeight defines the current height of the viewport\r\n     * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n     * @param transform defines the transform (view x projection) matrix to use\r\n     * @returns the new Vector3\r\n     */\r\n    public static UnprojectFromTransform(\r\n        source: DeepImmutable<Vector3>,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        transform: DeepImmutable<Matrix>\r\n    ): Vector3 {\r\n        return this.Unproject(source, viewportWidth, viewportHeight, world, transform, Matrix.IdentityReadOnly);\r\n    }\r\n\r\n    /**\r\n     * Unproject from screen space to object space\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#117\r\n     * @param source defines the screen space Vector3 to use\r\n     * @param viewportWidth defines the current width of the viewport\r\n     * @param viewportHeight defines the current height of the viewport\r\n     * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n     * @param view defines the view matrix to use\r\n     * @param projection defines the projection matrix to use\r\n     * @returns the new Vector3\r\n     */\r\n    public static Unproject(\r\n        source: DeepImmutable<Vector3>,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>\r\n    ): Vector3 {\r\n        const result = new Vector3();\r\n\r\n        Vector3.UnprojectToRef(source, viewportWidth, viewportHeight, world, view, projection, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Unproject from screen space to object space\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#119\r\n     * @param source defines the screen space Vector3 to use\r\n     * @param viewportWidth defines the current width of the viewport\r\n     * @param viewportHeight defines the current height of the viewport\r\n     * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n     * @param view defines the view matrix to use\r\n     * @param projection defines the projection matrix to use\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static UnprojectToRef<T extends Vector3>(\r\n        source: DeepImmutable<Vector3>,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>,\r\n        result: T\r\n    ): T {\r\n        Vector3.UnprojectFloatsToRef(source._x, source._y, source._z, viewportWidth, viewportHeight, world, view, projection, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Unproject from screen space to object space\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#120\r\n     * @param sourceX defines the screen space x coordinate to use\r\n     * @param sourceY defines the screen space y coordinate to use\r\n     * @param sourceZ defines the screen space z coordinate to use\r\n     * @param viewportWidth defines the current width of the viewport\r\n     * @param viewportHeight defines the current height of the viewport\r\n     * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n     * @param view defines the view matrix to use\r\n     * @param projection defines the projection matrix to use\r\n     * @param result defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static UnprojectFloatsToRef<T extends Vector3>(\r\n        sourceX: float,\r\n        sourceY: float,\r\n        sourceZ: float,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>,\r\n        result: T\r\n    ): T {\r\n        const matrix = MathTmp.Matrix[0];\r\n        world.multiplyToRef(view, matrix);\r\n        matrix.multiplyToRef(projection, matrix);\r\n        matrix.invert();\r\n\r\n        const screenSource = MathTmp.Vector3[0];\r\n        screenSource.x = (sourceX / viewportWidth) * 2 - 1;\r\n        screenSource.y = -((sourceY / viewportHeight) * 2 - 1);\r\n        if (EngineStore.LastCreatedEngine?.isNDCHalfZRange) {\r\n            screenSource.z = sourceZ;\r\n        } else {\r\n            screenSource.z = 2 * sourceZ - 1.0;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesToRef(screenSource, matrix, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets the minimal coordinate values between two Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#97\r\n     * @param left defines the first operand\r\n     * @param right defines the second operand\r\n     * @returns the new Vector3\r\n     */\r\n    public static Minimize(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): Vector3 {\r\n        const min = new Vector3();\r\n        min.copyFrom(left);\r\n        min.minimizeInPlace(right);\r\n        return min;\r\n    }\r\n\r\n    /**\r\n     * Gets the maximal coordinate values between two Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#96\r\n     * @param left defines the first operand\r\n     * @param right defines the second operand\r\n     * @returns the new Vector3\r\n     */\r\n    public static Maximize(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): Vector3 {\r\n        const max = new Vector3();\r\n        max.copyFrom(left);\r\n        max.maximizeInPlace(right);\r\n        return max;\r\n    }\r\n\r\n    /**\r\n     * Returns the distance between the vectors \"value1\" and \"value2\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#81\r\n     * @param value1 defines the first operand\r\n     * @param value2 defines the second operand\r\n     * @returns the distance\r\n     */\r\n    public static Distance(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>): number {\r\n        return Math.sqrt(Vector3.DistanceSquared(value1, value2));\r\n    }\r\n\r\n    /**\r\n     * Returns the squared distance between the vectors \"value1\" and \"value2\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#80\r\n     * @param value1 defines the first operand\r\n     * @param value2 defines the second operand\r\n     * @returns the squared distance\r\n     */\r\n    public static DistanceSquared(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>): number {\r\n        const x = value1._x - value2._x;\r\n        const y = value1._y - value2._y;\r\n        const z = value1._z - value2._z;\r\n\r\n        return x * x + y * y + z * z;\r\n    }\r\n\r\n    /**\r\n     * Projects \"vector\" on the triangle determined by its extremities \"p0\", \"p1\" and \"p2\", stores the result in \"ref\"\r\n     * and returns the distance to the projected point.\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#104\r\n     * From http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.104.4264&rep=rep1&type=pdf\r\n     *\r\n     * @param vector the vector to get distance from\r\n     * @param p0 extremity of the triangle\r\n     * @param p1 extremity of the triangle\r\n     * @param p2 extremity of the triangle\r\n     * @param ref variable to store the result to\r\n     * @returns The distance between \"ref\" and \"vector\"\r\n     */\r\n    public static ProjectOnTriangleToRef(vector: DeepImmutable<Vector3>, p0: DeepImmutable<Vector3>, p1: DeepImmutable<Vector3>, p2: DeepImmutable<Vector3>, ref: Vector3): number {\r\n        const p1p0 = MathTmp.Vector3[0];\r\n        const p2p0 = MathTmp.Vector3[1];\r\n        const p2p1 = MathTmp.Vector3[2];\r\n        const normal = MathTmp.Vector3[3];\r\n        const vectorp0 = MathTmp.Vector3[4];\r\n\r\n        // Triangle vectors\r\n        p1.subtractToRef(p0, p1p0);\r\n        p2.subtractToRef(p0, p2p0);\r\n        p2.subtractToRef(p1, p2p1);\r\n\r\n        const p1p0L = p1p0.length();\r\n        const p2p0L = p2p0.length();\r\n        const p2p1L = p2p1.length();\r\n\r\n        if (p1p0L < Epsilon || p2p0L < Epsilon || p2p1L < Epsilon) {\r\n            // This is a degenerate triangle. As we assume this is part of a non-degenerate mesh,\r\n            // we will find a better intersection later.\r\n            // Let's just return one of the extremities\r\n            ref.copyFrom(p0);\r\n            return Vector3.Distance(vector, p0);\r\n        }\r\n\r\n        // Compute normal and vector to p0\r\n        vector.subtractToRef(p0, vectorp0);\r\n        Vector3.CrossToRef(p1p0, p2p0, normal);\r\n        const nl = normal.length();\r\n        if (nl < Epsilon) {\r\n            // Extremities are aligned, we are back on the case of a degenerate triangle\r\n            ref.copyFrom(p0);\r\n            return Vector3.Distance(vector, p0);\r\n        }\r\n        normal.normalizeFromLength(nl);\r\n        let l = vectorp0.length();\r\n        if (l < Epsilon) {\r\n            // Vector is p0\r\n            ref.copyFrom(p0);\r\n            return 0;\r\n        }\r\n        vectorp0.normalizeFromLength(l);\r\n\r\n        // Project to \"proj\" that lies on the triangle plane\r\n        const cosA = Vector3.Dot(normal, vectorp0);\r\n        const projVector = MathTmp.Vector3[5];\r\n        const proj = MathTmp.Vector3[6];\r\n        projVector.copyFrom(normal).scaleInPlace(-l * cosA);\r\n        proj.copyFrom(vector).addInPlace(projVector);\r\n\r\n        // Compute barycentric coordinates (v0, v1 and v2 are axis from barycenter to extremities)\r\n        const v0 = MathTmp.Vector3[4];\r\n        const v1 = MathTmp.Vector3[5];\r\n        const v2 = MathTmp.Vector3[7];\r\n        const tmp = MathTmp.Vector3[8];\r\n\r\n        v0.copyFrom(p1p0).scaleInPlace(1 / p1p0L);\r\n        tmp.copyFrom(p2p0).scaleInPlace(1 / p2p0L);\r\n        v0.addInPlace(tmp).scaleInPlace(-1);\r\n\r\n        v1.copyFrom(p1p0).scaleInPlace(-1 / p1p0L);\r\n        tmp.copyFrom(p2p1).scaleInPlace(1 / p2p1L);\r\n        v1.addInPlace(tmp).scaleInPlace(-1);\r\n\r\n        v2.copyFrom(p2p1).scaleInPlace(-1 / p2p1L);\r\n        tmp.copyFrom(p2p0).scaleInPlace(-1 / p2p0L);\r\n        v2.addInPlace(tmp).scaleInPlace(-1);\r\n\r\n        // Determines which edge of the triangle is closest to \"proj\"\r\n        const projP = MathTmp.Vector3[9];\r\n        let dot;\r\n        projP.copyFrom(proj).subtractInPlace(p0);\r\n        Vector3.CrossToRef(v0, projP, tmp);\r\n        dot = Vector3.Dot(tmp, normal);\r\n        const s0 = dot;\r\n\r\n        projP.copyFrom(proj).subtractInPlace(p1);\r\n        Vector3.CrossToRef(v1, projP, tmp);\r\n        dot = Vector3.Dot(tmp, normal);\r\n        const s1 = dot;\r\n\r\n        projP.copyFrom(proj).subtractInPlace(p2);\r\n        Vector3.CrossToRef(v2, projP, tmp);\r\n        dot = Vector3.Dot(tmp, normal);\r\n        const s2 = dot;\r\n\r\n        const edge = MathTmp.Vector3[10];\r\n        let e0, e1;\r\n        if (s0 > 0 && s1 < 0) {\r\n            edge.copyFrom(p1p0);\r\n            e0 = p0;\r\n            e1 = p1;\r\n        } else if (s1 > 0 && s2 < 0) {\r\n            edge.copyFrom(p2p1);\r\n            e0 = p1;\r\n            e1 = p2;\r\n        } else {\r\n            edge.copyFrom(p2p0).scaleInPlace(-1);\r\n            e0 = p2;\r\n            e1 = p0;\r\n        }\r\n\r\n        // Determines if \"proj\" lies inside the triangle\r\n        const tmp2 = MathTmp.Vector3[9];\r\n        const tmp3 = MathTmp.Vector3[4];\r\n        e0.subtractToRef(proj, tmp);\r\n        e1.subtractToRef(proj, tmp2);\r\n        Vector3.CrossToRef(tmp, tmp2, tmp3);\r\n        const isOutside = Vector3.Dot(tmp3, normal) < 0;\r\n\r\n        // If inside, we already found the projected point, \"proj\"\r\n        if (!isOutside) {\r\n            ref.copyFrom(proj);\r\n            return Math.abs(l * cosA);\r\n        }\r\n\r\n        // If outside, we find \"triProj\", the closest point from \"proj\" on the closest edge\r\n        const r = MathTmp.Vector3[5];\r\n        Vector3.CrossToRef(edge, tmp3, r);\r\n        r.normalize();\r\n        const e0proj = MathTmp.Vector3[9];\r\n        e0proj.copyFrom(e0).subtractInPlace(proj);\r\n        const e0projL = e0proj.length();\r\n        if (e0projL < Epsilon) {\r\n            // Proj is e0\r\n            ref.copyFrom(e0);\r\n            return Vector3.Distance(vector, e0);\r\n        }\r\n        e0proj.normalizeFromLength(e0projL);\r\n        const cosG = Vector3.Dot(r, e0proj);\r\n        const triProj = MathTmp.Vector3[7];\r\n        triProj.copyFrom(proj).addInPlace(r.scaleInPlace(e0projL * cosG));\r\n\r\n        // Now we clamp \"triProj\" so it lies between e0 and e1\r\n        tmp.copyFrom(triProj).subtractInPlace(e0);\r\n        l = edge.length();\r\n        edge.normalizeFromLength(l);\r\n        let t = Vector3.Dot(tmp, edge) / Math.max(l, Epsilon);\r\n        t = Clamp(t, 0, 1);\r\n        triProj.copyFrom(e0).addInPlace(edge.scaleInPlace(t * l));\r\n        ref.copyFrom(triProj);\r\n\r\n        return Vector3.Distance(vector, triProj);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 located at the center between \"value1\" and \"value2\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#72\r\n     * @param value1 defines the first operand\r\n     * @param value2 defines the second operand\r\n     * @returns the new Vector3\r\n     */\r\n    public static Center(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>): Vector3 {\r\n        return Vector3.CenterToRef(value1, value2, Vector3.Zero());\r\n    }\r\n\r\n    /**\r\n     * Gets the center of the vectors \"value1\" and \"value2\" and stores the result in the vector \"ref\"\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#73\r\n     * @param value1 defines first vector\r\n     * @param value2 defines second vector\r\n     * @param ref defines third vector\r\n     * @returns ref\r\n     */\r\n    public static CenterToRef<T extends Vector3>(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>, ref: T): T {\r\n        return ref.copyFromFloats((value1._x + value2._x) / 2, (value1._y + value2._y) / 2, (value1._z + value2._z) / 2);\r\n    }\r\n\r\n    /**\r\n     * Given three orthogonal normalized left-handed oriented Vector3 axis in space (target system),\r\n     * RotationFromAxis() returns the rotation Euler angles (ex : rotation.x, rotation.y, rotation.z) to apply\r\n     * to something in order to rotate it from its local system to the given target system\r\n     * Note: axis1, axis2 and axis3 are normalized during this operation\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#106\r\n     * @param axis1 defines the first axis\r\n     * @param axis2 defines the second axis\r\n     * @param axis3 defines the third axis\r\n     * @returns a new Vector3\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/target_align\r\n     */\r\n    public static RotationFromAxis(axis1: DeepImmutable<Vector3>, axis2: DeepImmutable<Vector3>, axis3: DeepImmutable<Vector3>): Vector3 {\r\n        const rotation = new Vector3();\r\n        Vector3.RotationFromAxisToRef(axis1, axis2, axis3, rotation);\r\n        return rotation;\r\n    }\r\n\r\n    /**\r\n     * The same than RotationFromAxis but updates the given ref Vector3 parameter instead of returning a new Vector3\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#107\r\n     * @param axis1 defines the first axis\r\n     * @param axis2 defines the second axis\r\n     * @param axis3 defines the third axis\r\n     * @param ref defines the Vector3 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static RotationFromAxisToRef<T extends Vector3>(axis1: DeepImmutable<Vector3>, axis2: DeepImmutable<Vector3>, axis3: DeepImmutable<Vector3>, ref: T): T {\r\n        const quat = MathTmp.Quaternion[0];\r\n        Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);\r\n        quat.toEulerAnglesToRef(ref);\r\n        return ref;\r\n    }\r\n}\r\nVector3 satisfies VectorStatic<Vector3, IVector3LikeInternal>;\r\n\r\n/**\r\n * Vector4 class created for EulerAngle class conversion to Quaternion\r\n */\r\nexport class Vector4 implements Vector<Tuple<number, 4>, IVector4Like>, IVector4Like {\r\n    /**\r\n     * If the first vector is flagged with integers (as everything is 0,0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n     * If subsequent vectors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n     * and henceforth it will use floating-point representation for all Vector4 instances that it creates.\r\n     * But the original Vector4 instances are unchanged and has a \"deprecated map\".\r\n     * If we keep using the Vector4 instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n     */\r\n    static _V8PerformanceHack = /*#__PURE__*/ new Vector4(0.5, 0.5, 0.5, 0.5) as DeepImmutable<Vector4>;\r\n    private static _ZeroReadOnly = /*#__PURE__*/ Vector4.Zero() as DeepImmutable<Vector4>;\r\n\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: Readonly<[4]>;\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 1;\r\n\r\n    /** @internal */\r\n    public _x: number;\r\n    /** @internal */\r\n    public _y: number;\r\n    /** @internal */\r\n    public _z: number;\r\n    /** @internal */\r\n    public _w: number;\r\n\r\n    /** @internal */\r\n    public _isDirty = true;\r\n\r\n    // ---------------------------------\r\n    // Getters / setters (same pattern as Vector3)\r\n    // ---------------------------------\r\n    /** Gets or sets the x coordinate */\r\n    public get x() {\r\n        return this._x;\r\n    }\r\n    public set x(value: number) {\r\n        this._x = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the y coordinate */\r\n    public get y() {\r\n        return this._y;\r\n    }\r\n    public set y(value: number) {\r\n        this._y = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the z coordinate */\r\n    public get z() {\r\n        return this._z;\r\n    }\r\n    public set z(value: number) {\r\n        this._z = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the w coordinate */\r\n    public get w() {\r\n        return this._w;\r\n    }\r\n    public set w(value: number) {\r\n        this._w = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Creates a Vector4 object from the given floats.\r\n     * @param x x value of the vector\r\n     * @param y y value of the vector\r\n     * @param z z value of the vector\r\n     * @param w w value of the vector\r\n     */\r\n    constructor(x: number = 0, y: number = 0, z: number = 0, w: number = 0) {\r\n        this._x = x;\r\n        this._y = y;\r\n        this._z = z;\r\n        this._w = w;\r\n    }\r\n\r\n    /**\r\n     * Returns the string with the Vector4 coordinates.\r\n     * @returns a string containing all the vector values\r\n     */\r\n    public toString(): string {\r\n        return `{X: ${this._x} Y: ${this._y} Z: ${this._z} W: ${this._w}}`;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"Vector4\".\r\n     * @returns \"Vector4\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Vector4\";\r\n    }\r\n\r\n    /**\r\n     * Returns the Vector4 hash code.\r\n     * @returns a unique hash code\r\n     */\r\n    public getHashCode(): number {\r\n        const x = ExtractAsInt(this._x);\r\n        const y = ExtractAsInt(this._y);\r\n        const z = ExtractAsInt(this._z);\r\n        const w = ExtractAsInt(this._w);\r\n\r\n        let hash = x;\r\n        hash = (hash * 397) ^ y;\r\n        hash = (hash * 397) ^ z;\r\n        hash = (hash * 397) ^ w;\r\n        return hash;\r\n    }\r\n\r\n    // Operators\r\n    /**\r\n     * Returns a new array populated with 4 elements : the Vector4 coordinates.\r\n     * @returns the resulting array\r\n     */\r\n    public asArray(): Tuple<number, 4> {\r\n        return [this._x, this._y, this._z, this._w];\r\n    }\r\n\r\n    /**\r\n     * Populates the given array from the given index with the Vector4 coordinates.\r\n     * @param array array to populate\r\n     * @param index index of the array to start at (default: 0)\r\n     * @returns the Vector4.\r\n     */\r\n    public toArray(array: FloatArray, index?: number): this {\r\n        if (index === undefined) {\r\n            index = 0;\r\n        }\r\n        array[index] = this._x;\r\n        array[index + 1] = this._y;\r\n        array[index + 2] = this._z;\r\n        array[index + 3] = this._w;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update the current vector from an array\r\n     * @param array defines the destination array\r\n     * @param offset defines the offset in the destination array\r\n     * @returns the current Vector3\r\n     */\r\n    public fromArray(array: FloatArray, offset: number = 0): this {\r\n        Vector4.FromArrayToRef(array, offset, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the given vector to the current Vector4.\r\n     * @param otherVector the vector to add\r\n     * @returns the updated Vector4.\r\n     */\r\n    public addInPlace(otherVector: DeepImmutable<Vector4>): this {\r\n        this.x += otherVector._x;\r\n        this.y += otherVector._y;\r\n        this.z += otherVector._z;\r\n        this.w += otherVector._w;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the given coordinates to the current Vector4\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @param w defines the w coordinate of the operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public addInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n        this.x += x;\r\n        this.y += y;\r\n        this.z += z;\r\n        this.w += w;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 as the result of the addition of the current Vector4 and the given one.\r\n     * @param otherVector the vector to add\r\n     * @returns the resulting vector\r\n     */\r\n    public add(otherVector: DeepImmutable<IVector4Like>): Vector4 {\r\n        return new Vector4(this._x + otherVector.x, this._y + otherVector.y, this._z + otherVector.z, this._w + otherVector.w);\r\n    }\r\n\r\n    /**\r\n     * Updates the given vector \"result\" with the result of the addition of the current Vector4 and the given one.\r\n     * @param otherVector the vector to add\r\n     * @param result the vector to store the result\r\n     * @returns result input\r\n     */\r\n    public addToRef<T extends IVector4Like>(otherVector: DeepImmutable<IVector4Like>, result: T): T {\r\n        result.x = this._x + otherVector.x;\r\n        result.y = this._y + otherVector.y;\r\n        result.z = this._z + otherVector.z;\r\n        result.w = this._w + otherVector.w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Subtract in place the given vector from the current Vector4.\r\n     * @param otherVector the vector to subtract\r\n     * @returns the updated Vector4.\r\n     */\r\n    public subtractInPlace(otherVector: DeepImmutable<IVector4Like>): this {\r\n        this.x -= otherVector.x;\r\n        this.y -= otherVector.y;\r\n        this.z -= otherVector.z;\r\n        this.w -= otherVector.w;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 with the result of the subtraction of the given vector from the current Vector4.\r\n     * @param otherVector the vector to add\r\n     * @returns the new vector with the result\r\n     */\r\n    public subtract(otherVector: DeepImmutable<IVector4Like>): Vector4 {\r\n        return new Vector4(this._x - otherVector.x, this._y - otherVector.y, this._z - otherVector.z, this._w - otherVector.w);\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the subtraction of the given vector from the current Vector4.\r\n     * @param otherVector the vector to subtract\r\n     * @param result the vector to store the result\r\n     * @returns result input\r\n     */\r\n    public subtractToRef<T extends IVector4Like>(otherVector: DeepImmutable<IVector4Like>, result: T): T {\r\n        result.x = this._x - otherVector.x;\r\n        result.y = this._y - otherVector.y;\r\n        result.z = this._z - otherVector.z;\r\n        result.w = this._w - otherVector.w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the result of the subtraction of the given floats from the current Vector4 coordinates.\r\n     * @param x value to subtract\r\n     * @param y value to subtract\r\n     * @param z value to subtract\r\n     * @param w value to subtract\r\n     * @returns new vector containing the result\r\n     */\r\n    public subtractFromFloats(x: number, y: number, z: number, w: number): Vector4 {\r\n        return new Vector4(this._x - x, this._y - y, this._z - z, this._w - w);\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" set with the result of the subtraction of the given floats from the current Vector4 coordinates.\r\n     * @param x value to subtract\r\n     * @param y value to subtract\r\n     * @param z value to subtract\r\n     * @param w value to subtract\r\n     * @param result the vector to store the result in\r\n     * @returns result input\r\n     */\r\n    public subtractFromFloatsToRef<T extends IVector4Like>(x: number, y: number, z: number, w: number, result: T): T {\r\n        result.x = this._x - x;\r\n        result.y = this._y - y;\r\n        result.z = this._z - z;\r\n        result.w = this._w - w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the current Vector4 negated coordinates.\r\n     * @returns a new vector with the negated values\r\n     */\r\n    public negate(): Vector4 {\r\n        return new Vector4(-this._x, -this._y, -this._z, -this._w);\r\n    }\r\n\r\n    /**\r\n     * Negate this vector in place\r\n     * @returns this\r\n     */\r\n    public negateInPlace(): this {\r\n        this.x *= -1;\r\n        this.y *= -1;\r\n        this.z *= -1;\r\n        this.w *= -1;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Negate the current Vector4 and stores the result in the given vector \"result\" coordinates\r\n     * @param result defines the Vector3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public negateToRef<T extends IVector4Like>(result: T): T {\r\n        result.x = -this._x;\r\n        result.y = -this._y;\r\n        result.z = -this._z;\r\n        result.w = -this._w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current Vector4 coordinates by scale (float).\r\n     * @param scale the number to scale with\r\n     * @returns the updated Vector4.\r\n     */\r\n    public scaleInPlace(scale: number): this {\r\n        this.x *= scale;\r\n        this.y *= scale;\r\n        this.z *= scale;\r\n        this.w *= scale;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the current Vector4 coordinates multiplied by scale (float).\r\n     * @param scale the number to scale with\r\n     * @returns a new vector with the result\r\n     */\r\n    public scale(scale: number): Vector4 {\r\n        return new Vector4(this._x * scale, this._y * scale, this._z * scale, this._w * scale);\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the current Vector4 coordinates multiplied by scale (float).\r\n     * @param scale the number to scale with\r\n     * @param result a vector to store the result in\r\n     * @returns result input\r\n     */\r\n    public scaleToRef<T extends IVector4Like>(scale: number, result: T): T {\r\n        result.x = this._x * scale;\r\n        result.y = this._y * scale;\r\n        result.z = this._z * scale;\r\n        result.w = this._w * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Scale the current Vector4 values by a factor and add the result to a given Vector4\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Vector4 object where to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleAndAddToRef<T extends IVector4Like>(scale: number, result: T): T {\r\n        result.x += this._x * scale;\r\n        result.y += this._y * scale;\r\n        result.z += this._z * scale;\r\n        result.w += this._w * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Boolean : True if the current Vector4 coordinates are stricly equal to the given ones.\r\n     * @param otherVector the vector to compare against\r\n     * @returns true if they are equal\r\n     */\r\n    public equals(otherVector: DeepImmutable<IVector4Like>): boolean {\r\n        return otherVector && this._x === otherVector.x && this._y === otherVector.y && this._z === otherVector.z && this._w === otherVector.w;\r\n    }\r\n\r\n    /**\r\n     * Boolean : True if the current Vector4 coordinates are each beneath the distance \"epsilon\" from the given vector ones.\r\n     * @param otherVector vector to compare against\r\n     * @param epsilon (Default: very small number)\r\n     * @returns true if they are equal\r\n     */\r\n    public equalsWithEpsilon(otherVector: DeepImmutable<IVector4Like>, epsilon: number = Epsilon): boolean {\r\n        return (\r\n            otherVector &&\r\n            WithinEpsilon(this._x, otherVector.x, epsilon) &&\r\n            WithinEpsilon(this._y, otherVector.y, epsilon) &&\r\n            WithinEpsilon(this._z, otherVector.z, epsilon) &&\r\n            WithinEpsilon(this._w, otherVector.w, epsilon)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Boolean : True if the given floats are strictly equal to the current Vector4 coordinates.\r\n     * @param x x value to compare against\r\n     * @param y y value to compare against\r\n     * @param z z value to compare against\r\n     * @param w w value to compare against\r\n     * @returns true if equal\r\n     */\r\n    public equalsToFloats(x: number, y: number, z: number, w: number): boolean {\r\n        return this._x === x && this._y === y && this._z === z && this._w === w;\r\n    }\r\n\r\n    /**\r\n     * Multiplies in place the current Vector4 by the given one.\r\n     * @param otherVector vector to multiple with\r\n     * @returns the updated Vector4.\r\n     */\r\n    public multiplyInPlace(otherVector: DeepImmutable<IVector4Like>): this {\r\n        this.x *= otherVector.x;\r\n        this.y *= otherVector.y;\r\n        this.z *= otherVector.z;\r\n        this.w *= otherVector.w;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the multiplication result of the current Vector4 and the given one.\r\n     * @param otherVector vector to multiple with\r\n     * @returns resulting new vector\r\n     */\r\n    public multiply(otherVector: DeepImmutable<IVector4Like>): Vector4 {\r\n        return new Vector4(this._x * otherVector.x, this._y * otherVector.y, this._z * otherVector.z, this._w * otherVector.w);\r\n    }\r\n    /**\r\n     * Updates the given vector \"result\" with the multiplication result of the current Vector4 and the given one.\r\n     * @param otherVector vector to multiple with\r\n     * @param result vector to store the result\r\n     * @returns result input\r\n     */\r\n    public multiplyToRef<T extends IVector4Like>(otherVector: DeepImmutable<IVector4Like>, result: T): T {\r\n        result.x = this._x * otherVector.x;\r\n        result.y = this._y * otherVector.y;\r\n        result.z = this._z * otherVector.z;\r\n        result.w = this._w * otherVector.w;\r\n        return result;\r\n    }\r\n    /**\r\n     * Returns a new Vector4 set with the multiplication result of the given floats and the current Vector4 coordinates.\r\n     * @param x x value multiply with\r\n     * @param y y value multiply with\r\n     * @param z z value multiply with\r\n     * @param w w value multiply with\r\n     * @returns resulting new vector\r\n     */\r\n    public multiplyByFloats(x: number, y: number, z: number, w: number): Vector4 {\r\n        return new Vector4(this._x * x, this._y * y, this._z * z, this._w * w);\r\n    }\r\n    /**\r\n     * Returns a new Vector4 set with the division result of the current Vector4 by the given one.\r\n     * @param otherVector vector to devide with\r\n     * @returns resulting new vector\r\n     */\r\n    public divide(otherVector: DeepImmutable<IVector4Like>): Vector4 {\r\n        return new Vector4(this._x / otherVector.x, this._y / otherVector.y, this._z / otherVector.z, this._w / otherVector.w);\r\n    }\r\n    /**\r\n     * Updates the given vector \"result\" with the division result of the current Vector4 by the given one.\r\n     * @param otherVector vector to devide with\r\n     * @param result vector to store the result\r\n     * @returns result input\r\n     */\r\n    public divideToRef<T extends IVector4Like>(otherVector: DeepImmutable<IVector4Like>, result: T): T {\r\n        result.x = this._x / otherVector.x;\r\n        result.y = this._y / otherVector.y;\r\n        result.z = this._z / otherVector.z;\r\n        result.w = this._w / otherVector.w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Vector3 coordinates by the given ones.\r\n     * @param otherVector vector to devide with\r\n     * @returns the updated Vector3.\r\n     */\r\n    public divideInPlace(otherVector: DeepImmutable<IVector4Like>): this {\r\n        return this.divideToRef(otherVector, this);\r\n    }\r\n\r\n    /**\r\n     * Updates the Vector4 coordinates with the minimum values between its own and the given vector ones\r\n     * @param other defines the second operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public minimizeInPlace(other: DeepImmutable<IVector4Like>): this {\r\n        if (other.x < this._x) {\r\n            this.x = other.x;\r\n        }\r\n        if (other.y < this._y) {\r\n            this.y = other.y;\r\n        }\r\n        if (other.z < this._z) {\r\n            this.z = other.z;\r\n        }\r\n        if (other.w < this._w) {\r\n            this.w = other.w;\r\n        }\r\n        return this;\r\n    }\r\n    /**\r\n     * Updates the Vector4 coordinates with the maximum values between its own and the given vector ones\r\n     * @param other defines the second operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public maximizeInPlace(other: DeepImmutable<IVector4Like>): this {\r\n        if (other.x > this._x) {\r\n            this.x = other.x;\r\n        }\r\n        if (other.y > this._y) {\r\n            this.y = other.y;\r\n        }\r\n        if (other.z > this._z) {\r\n            this.z = other.z;\r\n        }\r\n        if (other.w > this._w) {\r\n            this.w = other.w;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector4 with the minimal coordinate values between its and the given coordinates\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @param w defines the w coordinate of the operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public minimizeInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n        this.x = Math.min(x, this._x);\r\n        this.y = Math.min(y, this._y);\r\n        this.z = Math.min(z, this._z);\r\n        this.w = Math.min(w, this._w);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Vector4 with the maximal coordinate values between its and the given coordinates.\r\n     * @param x defines the x coordinate of the operand\r\n     * @param y defines the y coordinate of the operand\r\n     * @param z defines the z coordinate of the operand\r\n     * @param w defines the w coordinate of the operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public maximizeInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n        this.x = Math.max(x, this._x);\r\n        this.y = Math.max(y, this._y);\r\n        this.z = Math.max(z, this._z);\r\n        this.w = Math.max(w, this._w);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the current Vector4's floored values and stores them in result\r\n     * @param result the vector to store the result in\r\n     * @returns the result vector\r\n     */\r\n    public floorToRef<T extends IVector4Like>(result: T): T {\r\n        result.x = Math.floor(this._x);\r\n        result.y = Math.floor(this._y);\r\n        result.z = Math.floor(this._z);\r\n        result.w = Math.floor(this._w);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector4 from current Vector4 floored values\r\n     * @returns a new Vector4\r\n     */\r\n    public floor(): Vector4 {\r\n        return new Vector4(Math.floor(this._x), Math.floor(this._y), Math.floor(this._z), Math.floor(this._w));\r\n    }\r\n\r\n    /**\r\n     * Gets the current Vector4's fractional values and stores them in result\r\n     * @param result the vector to store the result in\r\n     * @returns the result vector\r\n     */\r\n    public fractToRef<T extends IVector4Like>(result: T): T {\r\n        result.x = this._x - Math.floor(this._x);\r\n        result.y = this._y - Math.floor(this._y);\r\n        result.z = this._z - Math.floor(this._z);\r\n        result.w = this._w - Math.floor(this._w);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Vector4 from current Vector4 fractional values\r\n     * @returns a new Vector4\r\n     */\r\n    public fract(): Vector4 {\r\n        return new Vector4(this._x - Math.floor(this._x), this._y - Math.floor(this._y), this._z - Math.floor(this._z), this._w - Math.floor(this._w));\r\n    }\r\n\r\n    // Properties\r\n    /**\r\n     * Returns the Vector4 length (float).\r\n     * @returns the length\r\n     */\r\n    public length(): number {\r\n        return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);\r\n    }\r\n    /**\r\n     * Returns the Vector4 squared length (float).\r\n     * @returns the length squared\r\n     */\r\n    public lengthSquared(): number {\r\n        return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Normalizes in place the Vector4.\r\n     * @returns the updated Vector4.\r\n     */\r\n    public normalize(): this {\r\n        return this.normalizeFromLength(this.length());\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector4 with the given input length.\r\n     * Please note that this is an in place operation.\r\n     * @param len the length of the vector\r\n     * @returns the current updated Vector4\r\n     */\r\n    public normalizeFromLength(len: number): this {\r\n        if (len === 0 || len === 1.0) {\r\n            return this;\r\n        }\r\n\r\n        return this.scaleInPlace(1.0 / len);\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector4 to a new vector\r\n     * @returns the new Vector4\r\n     */\r\n    public normalizeToNew(): Vector4 {\r\n        return this.normalizeToRef(new Vector4());\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Vector4 to the reference\r\n     * @param reference define the Vector4 to update\r\n     * @returns the updated Vector4\r\n     */\r\n    public normalizeToRef<T extends IVector4Like>(reference: T): T {\r\n        const len = this.length();\r\n        if (len === 0 || len === 1.0) {\r\n            reference.x = this._x;\r\n            reference.y = this._y;\r\n            reference.z = this._z;\r\n            reference.w = this._w;\r\n            return reference;\r\n        }\r\n\r\n        return this.scaleToRef(1.0 / len, reference);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 from the Vector4 (x, y, z) coordinates.\r\n     * @returns this converted to a new vector3\r\n     */\r\n    public toVector3(): Vector3 {\r\n        return new Vector3(this._x, this._y, this._z);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 copied from the current one.\r\n     * @returns the new cloned vector\r\n     */\r\n    public clone(): Vector4 {\r\n        return new Vector4(this._x, this._y, this._z, this._w);\r\n    }\r\n    /**\r\n     * Updates the current Vector4 with the given one coordinates.\r\n     * @param source the source vector to copy from\r\n     * @returns the updated Vector4.\r\n     */\r\n    public copyFrom(source: DeepImmutable<IVector4Like>): this {\r\n        this.x = source.x;\r\n        this.y = source.y;\r\n        this.z = source.z;\r\n        this.w = source.w;\r\n        return this;\r\n    }\r\n    /**\r\n     * Updates the current Vector4 coordinates with the given floats.\r\n     * @param x float to copy from\r\n     * @param y float to copy from\r\n     * @param z float to copy from\r\n     * @param w float to copy from\r\n     * @returns the updated Vector4.\r\n     */\r\n    public copyFromFloats(x: number, y: number, z: number, w: number): this {\r\n        this.x = x;\r\n        this.y = y;\r\n        this.z = z;\r\n        this.w = w;\r\n        return this;\r\n    }\r\n    /**\r\n     * Updates the current Vector4 coordinates with the given floats.\r\n     * @param x float to set from\r\n     * @param y float to set from\r\n     * @param z float to set from\r\n     * @param w float to set from\r\n     * @returns the updated Vector4.\r\n     */\r\n    public set(x: number, y: number, z: number, w: number): this {\r\n        return this.copyFromFloats(x, y, z, w);\r\n    }\r\n\r\n    /**\r\n     * Copies the given float to the current Vector4 coordinates\r\n     * @param v defines the x, y, z and w coordinates of the operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public setAll(v: number): this {\r\n        this.x = this.y = this.z = this.w = v;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the dot product (float) between the current vectors and \"otherVector\"\r\n     * @param otherVector defines the right operand\r\n     * @returns the dot product\r\n     */\r\n    public dot(otherVector: DeepImmutable<IVector4Like>): number {\r\n        return this._x * otherVector.x + this._y * otherVector.y + this._z * otherVector.z + this._w * otherVector.w;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Returns a new Vector4 set from the starting index of the given array.\r\n     * @param array the array to pull values from\r\n     * @param offset the offset into the array to start at\r\n     * @returns the new vector\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Vector4 {\r\n        if (!offset) {\r\n            offset = 0;\r\n        }\r\n        return new Vector4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);\r\n    }\r\n    /**\r\n     * Updates the given vector \"result\" from the starting index of the given array.\r\n     * @param array the array to pull values from\r\n     * @param offset the offset into the array to start at\r\n     * @param result the vector to store the result in\r\n     * @returns result input\r\n     */\r\n    public static FromArrayToRef<T extends IVector4Like>(array: DeepImmutable<ArrayLike<number>>, offset: number, result: T): T {\r\n        result.x = array[offset];\r\n        result.y = array[offset + 1];\r\n        result.z = array[offset + 2];\r\n        result.w = array[offset + 3];\r\n        return result;\r\n    }\r\n    /**\r\n     * Updates the given vector \"result\" from the starting index of the given Float32Array.\r\n     * @param array the array to pull values from\r\n     * @param offset the offset into the array to start at\r\n     * @param result the vector to store the result in\r\n     * @returns result input\r\n     */\r\n    public static FromFloatArrayToRef<T extends IVector4Like>(array: DeepImmutable<Float32Array>, offset: number, result: T): T {\r\n        Vector4.FromArrayToRef(array, offset, result);\r\n        return result;\r\n    }\r\n    /**\r\n     * Updates the given vector \"result\" coordinates from the given floats.\r\n     * @param x float to set from\r\n     * @param y float to set from\r\n     * @param z float to set from\r\n     * @param w float to set from\r\n     * @param result the vector to the floats in\r\n     * @returns result input\r\n     */\r\n    public static FromFloatsToRef<T extends IVector4Like>(x: number, y: number, z: number, w: number, result: T): T {\r\n        result.x = x;\r\n        result.y = y;\r\n        result.z = z;\r\n        result.w = w;\r\n        return result;\r\n    }\r\n    /**\r\n     * Returns a new Vector4 set to (0.0, 0.0, 0.0, 0.0)\r\n     * @returns the new vector\r\n     */\r\n    public static Zero(): Vector4 {\r\n        return new Vector4(0.0, 0.0, 0.0, 0.0);\r\n    }\r\n    /**\r\n     * Returns a new Vector4 set to (1.0, 1.0, 1.0, 1.0)\r\n     * @returns the new vector\r\n     */\r\n    public static One(): Vector4 {\r\n        return new Vector4(1.0, 1.0, 1.0, 1.0);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @returns a Vector4 with random values between min and max\r\n     */\r\n    public static Random(min: number = 0, max: number = 1): Vector4 {\r\n        return new Vector4(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector4 with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @param ref the ref to store the values in\r\n     * @returns the ref with random values between min and max\r\n     */\r\n    public static RandomToRef<T extends IVector4Like>(min: number = 0, max: number = 1, ref: T): T {\r\n        ref.x = RandomRange(min, max);\r\n        ref.y = RandomRange(min, max);\r\n        ref.z = RandomRange(min, max);\r\n        ref.w = RandomRange(min, max);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n     * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n     * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n     * @param value defines the current value\r\n     * @param min defines the lower range value\r\n     * @param max defines the upper range value\r\n     * @returns the new Vector4\r\n     */\r\n    public static Clamp(value: DeepImmutable<IVector4Like>, min: DeepImmutable<IVector4Like>, max: DeepImmutable<IVector4Like>): Vector4 {\r\n        return Vector4.ClampToRef(value, min, max, new Vector4());\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n     * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n     * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n     * @param value defines the current value\r\n     * @param min defines the lower range value\r\n     * @param max defines the upper range value\r\n     * @param result defines the Vector4 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static ClampToRef<T extends IVector4Like>(value: DeepImmutable<IVector4Like>, min: DeepImmutable<IVector4Like>, max: DeepImmutable<IVector4Like>, result: T): T {\r\n        result.x = Clamp(value.x, min.x, max.x);\r\n        result.y = Clamp(value.y, min.y, max.y);\r\n        result.z = Clamp(value.z, min.z, max.z);\r\n        result.w = Clamp(value.w, min.w, max.w);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Checks if a given vector is inside a specific range\r\n     * Example Playground https://playground.babylonjs.com/#R1F8YU#75\r\n     * @param v defines the vector to test\r\n     * @param min defines the minimum range\r\n     * @param max defines the maximum range\r\n     */\r\n    public static CheckExtends(v: IVector4Like, min: Vector4, max: Vector4): void {\r\n        min.minimizeInPlace(v);\r\n        max.maximizeInPlace(v);\r\n    }\r\n\r\n    /**\r\n     * Gets a zero Vector4 that must not be updated\r\n     */\r\n    public static get ZeroReadOnly(): DeepImmutable<Vector4> {\r\n        return Vector4._ZeroReadOnly;\r\n    }\r\n    /**\r\n     * Returns a new normalized Vector4 from the given one.\r\n     * @param vector the vector to normalize\r\n     * @returns the vector\r\n     */\r\n    public static Normalize(vector: DeepImmutable<Vector4>): Vector4 {\r\n        return Vector4.NormalizeToRef(vector, new Vector4());\r\n    }\r\n    /**\r\n     * Updates the given vector \"result\" from the normalization of the given one.\r\n     * @param vector the vector to normalize\r\n     * @param result the vector to store the result in\r\n     * @returns result input\r\n     */\r\n    public static NormalizeToRef<T extends IVector4Like>(vector: DeepImmutable<Vector4>, result: T): T {\r\n        vector.normalizeToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a vector with the minimum values from the left and right vectors\r\n     * @param left left vector to minimize\r\n     * @param right right vector to minimize\r\n     * @returns a new vector with the minimum of the left and right vector values\r\n     */\r\n    public static Minimize<T extends Vector4>(left: DeepImmutable<T>, right: DeepImmutable<Vector4>): Vector4 {\r\n        const min = new Vector4();\r\n        min.copyFrom(left);\r\n        min.minimizeInPlace(right);\r\n        return min;\r\n    }\r\n\r\n    /**\r\n     * Returns a vector with the maximum values from the left and right vectors\r\n     * @param left left vector to maximize\r\n     * @param right right vector to maximize\r\n     * @returns a new vector with the maximum of the left and right vector values\r\n     */\r\n    public static Maximize(left: DeepImmutable<IVector4Like>, right: DeepImmutable<IVector4Like>): Vector4 {\r\n        const max = new Vector4();\r\n        max.copyFrom(left);\r\n        max.maximizeInPlace(right);\r\n        return max;\r\n    }\r\n    /**\r\n     * Returns the distance (float) between the vectors \"value1\" and \"value2\".\r\n     * @param value1 value to calulate the distance between\r\n     * @param value2 value to calulate the distance between\r\n     * @returns the distance between the two vectors\r\n     */\r\n    public static Distance(value1: DeepImmutable<IVector4Like>, value2: DeepImmutable<IVector4Like>): number {\r\n        return Math.sqrt(Vector4.DistanceSquared(value1, value2));\r\n    }\r\n    /**\r\n     * Returns the squared distance (float) between the vectors \"value1\" and \"value2\".\r\n     * @param value1 value to calulate the distance between\r\n     * @param value2 value to calulate the distance between\r\n     * @returns the distance between the two vectors squared\r\n     */\r\n    public static DistanceSquared(value1: DeepImmutable<IVector4Like>, value2: DeepImmutable<IVector4Like>): number {\r\n        const x = value1.x - value2.x;\r\n        const y = value1.y - value2.y;\r\n        const z = value1.z - value2.z;\r\n        const w = value1.w - value2.w;\r\n\r\n        return x * x + y * y + z * z + w * w;\r\n    }\r\n    /**\r\n     * Returns a new Vector4 located at the center between the vectors \"value1\" and \"value2\".\r\n     * @param value1 value to calulate the center between\r\n     * @param value2 value to calulate the center between\r\n     * @returns the center between the two vectors\r\n     */\r\n    public static Center(value1: DeepImmutable<IVector4Like>, value2: DeepImmutable<IVector4Like>): Vector4 {\r\n        return Vector4.CenterToRef(value1, value2, new Vector4());\r\n    }\r\n\r\n    /**\r\n     * Gets the center of the vectors \"value1\" and \"value2\" and stores the result in the vector \"ref\"\r\n     * @param value1 defines first vector\r\n     * @param value2 defines second vector\r\n     * @param ref defines third vector\r\n     * @returns ref\r\n     */\r\n    public static CenterToRef<T extends IVector4Like>(value1: DeepImmutable<IVector4Like>, value2: DeepImmutable<IVector4Like>, ref: T): T {\r\n        ref.x = (value1.x + value2.x) / 2;\r\n        ref.y = (value1.y + value2.y) / 2;\r\n        ref.z = (value1.z + value2.z) / 2;\r\n        ref.w = (value1.w + value2.w) / 2;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the result of the transformation by the given matrix of the given vector.\r\n     * This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n     * The difference with Vector3.TransformCoordinates is that the w component is not used to divide the other coordinates but is returned in the w coordinate instead\r\n     * @param vector defines the Vector3 to transform\r\n     * @param transformation defines the transformation matrix\r\n     * @returns the transformed Vector4\r\n     */\r\n    public static TransformCoordinates(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>): Vector4 {\r\n        return Vector4.TransformCoordinatesToRef(vector, transformation, new Vector4());\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given vector\r\n     * This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n     * The difference with Vector3.TransformCoordinatesToRef is that the w component is not used to divide the other coordinates but is returned in the w coordinate instead\r\n     * @param vector defines the Vector3 to transform\r\n     * @param transformation defines the transformation matrix\r\n     * @param result defines the Vector4 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static TransformCoordinatesToRef<T extends IVector4Like>(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        Vector4.TransformCoordinatesFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given floats (x, y, z)\r\n     * This method computes tranformed coordinates only, not transformed direction vectors\r\n     * The difference with Vector3.TransformCoordinatesFromFloatsToRef is that the w component is not used to divide the other coordinates but is returned in the w coordinate instead\r\n     * @param x define the x coordinate of the source vector\r\n     * @param y define the y coordinate of the source vector\r\n     * @param z define the z coordinate of the source vector\r\n     * @param transformation defines the transformation matrix\r\n     * @param result defines the Vector4 where to store the result\r\n     * @returns result input\r\n     */\r\n    public static TransformCoordinatesFromFloatsToRef<T extends IVector4Like>(x: number, y: number, z: number, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        const m = transformation.m;\r\n        const rx = x * m[0] + y * m[4] + z * m[8] + m[12];\r\n        const ry = x * m[1] + y * m[5] + z * m[9] + m[13];\r\n        const rz = x * m[2] + y * m[6] + z * m[10] + m[14];\r\n        const rw = x * m[3] + y * m[7] + z * m[11] + m[15];\r\n\r\n        result.x = rx;\r\n        result.y = ry;\r\n        result.z = rz;\r\n        result.w = rw;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector4 set with the result of the normal transformation by the given matrix of the given vector.\r\n     * This methods computes transformed normalized direction vectors only.\r\n     * @param vector the vector to transform\r\n     * @param transformation the transformation matrix to apply\r\n     * @returns the new vector\r\n     */\r\n    public static TransformNormal(vector: DeepImmutable<IVector4Like>, transformation: DeepImmutable<Matrix>): Vector4 {\r\n        return Vector4.TransformNormalToRef(vector, transformation, new Vector4());\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given vector.\r\n     * This methods computes transformed normalized direction vectors only.\r\n     * @param vector the vector to transform\r\n     * @param transformation the transformation matrix to apply\r\n     * @param result the vector to store the result in\r\n     * @returns result input\r\n     */\r\n    public static TransformNormalToRef<T extends IVector4Like>(vector: DeepImmutable<IVector4Like>, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        const m = transformation.m;\r\n        const x = vector.x * m[0] + vector.y * m[4] + vector.z * m[8];\r\n        const y = vector.x * m[1] + vector.y * m[5] + vector.z * m[9];\r\n        const z = vector.x * m[2] + vector.y * m[6] + vector.z * m[10];\r\n        result.x = x;\r\n        result.y = y;\r\n        result.z = z;\r\n        result.w = vector.w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given floats (x, y, z, w).\r\n     * This methods computes transformed normalized direction vectors only.\r\n     * @param x value to transform\r\n     * @param y value to transform\r\n     * @param z value to transform\r\n     * @param w value to transform\r\n     * @param transformation the transformation matrix to apply\r\n     * @param result the vector to store the results in\r\n     * @returns result input\r\n     */\r\n    public static TransformNormalFromFloatsToRef<T extends IVector4Like>(x: number, y: number, z: number, w: number, transformation: DeepImmutable<Matrix>, result: T): T {\r\n        const m = transformation.m;\r\n        result.x = x * m[0] + y * m[4] + z * m[8];\r\n        result.y = x * m[1] + y * m[5] + z * m[9];\r\n        result.z = x * m[2] + y * m[6] + z * m[10];\r\n        result.w = w;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Vector4 from a Vector3\r\n     * @param source defines the source data\r\n     * @param w defines the 4th component (default is 0)\r\n     * @returns a new Vector4\r\n     */\r\n    public static FromVector3(source: Vector3, w: number = 0): Vector4 {\r\n        return new Vector4(source._x, source._y, source._z, w);\r\n    }\r\n\r\n    /**\r\n     * Returns the dot product (float) between the vectors \"left\" and \"right\"\r\n     * @param left defines the left operand\r\n     * @param right defines the right operand\r\n     * @returns the dot product\r\n     */\r\n    public static Dot(left: DeepImmutable<IVector4Like>, right: DeepImmutable<IVector4Like>): number {\r\n        return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w;\r\n    }\r\n}\r\nVector4 satisfies VectorStatic<Vector4, IVector4Like>;\r\n\r\n/**\r\n * Class used to store quaternion data\r\n * Example Playground - Overview - https://playground.babylonjs.com/#L49EJ7#100\r\n * @see https://en.wikipedia.org/wiki/Quaternion\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms\r\n */\r\nexport class Quaternion implements Tensor<Tuple<number, 4>, Quaternion>, IQuaternionLike {\r\n    /**\r\n     * If the first quaternion is flagged with integers (as everything is 0,0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n     * If subsequent quaternion are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n     * and henceforth it will use floating-point representation for all quaternion instances that it creates.\r\n     * But the original quaternion instances are unchanged and has a \"deprecated map\".\r\n     * If we keep using the quaternion instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n     */\r\n    static _V8PerformanceHack = /*#__PURE__*/ new Quaternion(0.5, 0.5, 0.5, 0.5) as DeepImmutable<Quaternion>;\r\n    /** @internal */\r\n    public _x: number;\r\n\r\n    /** @internal */\r\n    public _y: number;\r\n\r\n    /** @internal */\r\n    public _z: number;\r\n\r\n    /** @internal */\r\n    public _w: number;\r\n\r\n    /** @internal */\r\n    public _isDirty = true;\r\n\r\n    /** Gets or sets the x coordinate */\r\n    public get x() {\r\n        return this._x;\r\n    }\r\n\r\n    public set x(value: number) {\r\n        this._x = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the y coordinate */\r\n    public get y() {\r\n        return this._y;\r\n    }\r\n\r\n    public set y(value: number) {\r\n        this._y = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the z coordinate */\r\n    public get z() {\r\n        return this._z;\r\n    }\r\n\r\n    public set z(value: number) {\r\n        this._z = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /** Gets or sets the w coordinate */\r\n    public get w() {\r\n        return this._w;\r\n    }\r\n\r\n    public set w(value: number) {\r\n        this._w = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: Readonly<[4]>;\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 1;\r\n\r\n    /**\r\n     * Creates a new Quaternion from the given floats\r\n     * @param x defines the first component (0 by default)\r\n     * @param y defines the second component (0 by default)\r\n     * @param z defines the third component (0 by default)\r\n     * @param w defines the fourth component (1.0 by default)\r\n     */\r\n    constructor(x: number = 0.0, y: number = 0.0, z: number = 0.0, w: number = 1.0) {\r\n        this._x = x;\r\n        this._y = y;\r\n        this._z = z;\r\n        this._w = w;\r\n    }\r\n\r\n    /**\r\n     * Gets a string representation for the current quaternion\r\n     * @returns a string with the Quaternion coordinates\r\n     */\r\n    public toString(): string {\r\n        return `{X: ${this._x} Y: ${this._y} Z: ${this._z} W: ${this._w}}`;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the quaternion\r\n     * @returns the string \"Quaternion\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Quaternion\";\r\n    }\r\n\r\n    /**\r\n     * Gets a hash code for this quaternion\r\n     * @returns the quaternion hash code\r\n     */\r\n    public getHashCode(): number {\r\n        const x = ExtractAsInt(this._x);\r\n        const y = ExtractAsInt(this._y);\r\n        const z = ExtractAsInt(this._z);\r\n        const w = ExtractAsInt(this._w);\r\n\r\n        let hash = x;\r\n        hash = (hash * 397) ^ y;\r\n        hash = (hash * 397) ^ z;\r\n        hash = (hash * 397) ^ w;\r\n        return hash;\r\n    }\r\n\r\n    /**\r\n     * Copy the quaternion to an array\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#13\r\n     * @returns a new array populated with 4 elements from the quaternion coordinates\r\n     */\r\n    public asArray(): Tuple<number, 4> {\r\n        return [this._x, this._y, this._z, this._w];\r\n    }\r\n\r\n    /**\r\n     * Stores from the starting index in the given array the Quaternion successive values\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#59\r\n     * @param array defines the array where to store the x,y,z,w components\r\n     * @param index defines an optional index in the target array to define where to start storing values\r\n     * @returns the current Quaternion object\r\n     */\r\n    public toArray(array: FloatArray, index: number = 0): this {\r\n        array[index] = this._x;\r\n        array[index + 1] = this._y;\r\n        array[index + 2] = this._z;\r\n        array[index + 3] = this._w;\r\n        return this;\r\n    }\r\n\r\n    public fromArray(array: FloatArray, index: number = 0): this {\r\n        return Quaternion.FromArrayToRef(array, index, this);\r\n    }\r\n\r\n    /**\r\n     * Check if two quaternions are equals\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#38\r\n     * @param otherQuaternion defines the second operand\r\n     * @returns true if the current quaternion and the given one coordinates are strictly equals\r\n     */\r\n    public equals(otherQuaternion: DeepImmutable<Quaternion>): boolean {\r\n        return otherQuaternion && this._x === otherQuaternion._x && this._y === otherQuaternion._y && this._z === otherQuaternion._z && this._w === otherQuaternion._w;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean if two quaternions are equals (using an epsilon value)\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#37\r\n     * @param otherQuaternion defines the other quaternion\r\n     * @param epsilon defines the minimal distance to consider equality\r\n     * @returns true if the given quaternion coordinates are close to the current ones by a distance of epsilon.\r\n     */\r\n    public equalsWithEpsilon(otherQuaternion: DeepImmutable<Quaternion>, epsilon: number = Epsilon): boolean {\r\n        return (\r\n            otherQuaternion &&\r\n            WithinEpsilon(this._x, otherQuaternion._x, epsilon) &&\r\n            WithinEpsilon(this._y, otherQuaternion._y, epsilon) &&\r\n            WithinEpsilon(this._z, otherQuaternion._z, epsilon) &&\r\n            WithinEpsilon(this._w, otherQuaternion._w, epsilon)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean if two quaternions are equals (using an epsilon value), taking care of double cover : https://www.reedbeta.com/blog/why-quaternions-double-cover/\r\n     * @param otherQuaternion defines the other quaternion\r\n     * @param epsilon defines the minimal distance to consider equality\r\n     * @returns true if the given quaternion coordinates are close to the current ones by a distance of epsilon.\r\n     */\r\n    public isApprox(otherQuaternion: DeepImmutable<Quaternion>, epsilon: number = Epsilon): boolean {\r\n        return (\r\n            otherQuaternion &&\r\n            ((WithinEpsilon(this._x, otherQuaternion._x, epsilon) &&\r\n                WithinEpsilon(this._y, otherQuaternion._y, epsilon) &&\r\n                WithinEpsilon(this._z, otherQuaternion._z, epsilon) &&\r\n                WithinEpsilon(this._w, otherQuaternion._w, epsilon)) ||\r\n                (WithinEpsilon(this._x, -otherQuaternion._x, epsilon) &&\r\n                    WithinEpsilon(this._y, -otherQuaternion._y, epsilon) &&\r\n                    WithinEpsilon(this._z, -otherQuaternion._z, epsilon) &&\r\n                    WithinEpsilon(this._w, -otherQuaternion._w, epsilon)))\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Clone the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#12\r\n     * @returns a new quaternion copied from the current one\r\n     */\r\n    public clone(): Quaternion {\r\n        return new Quaternion(this._x, this._y, this._z, this._w);\r\n    }\r\n\r\n    /**\r\n     * Copy a quaternion to the current one\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#86\r\n     * @param other defines the other quaternion\r\n     * @returns the updated current quaternion\r\n     */\r\n    public copyFrom(other: DeepImmutable<Quaternion>): this {\r\n        this._x = other._x;\r\n        this._y = other._y;\r\n        this._z = other._z;\r\n        this._w = other._w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current quaternion with the given float coordinates\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#87\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @returns the updated current quaternion\r\n     */\r\n    public copyFromFloats(x: number, y: number, z: number, w: number): this {\r\n        this._x = x;\r\n        this._y = y;\r\n        this._z = z;\r\n        this._w = w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current quaternion from the given float coordinates\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#56\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @returns the updated current quaternion\r\n     */\r\n    public set(x: number, y: number, z: number, w: number): this {\r\n        return this.copyFromFloats(x, y, z, w);\r\n    }\r\n\r\n    /**\r\n     * Sets all the quaternion coordinates to the given value\r\n     * @param value the value to set\r\n     * @returns the current updated quaternion\r\n     */\r\n    public setAll(value: number): this {\r\n        return this.copyFromFloats(value, value, value, value);\r\n    }\r\n\r\n    /**\r\n     * Adds two quaternions\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#10\r\n     * @param other defines the second operand\r\n     * @returns a new quaternion as the addition result of the given one and the current quaternion\r\n     */\r\n    public add(other: DeepImmutable<Quaternion>): Quaternion {\r\n        return new Quaternion(this._x + other._x, this._y + other._y, this._z + other._z, this._w + other._w);\r\n    }\r\n\r\n    /**\r\n     * Add a quaternion to the current one\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#11\r\n     * @param other defines the quaternion to add\r\n     * @returns the current quaternion\r\n     */\r\n    public addInPlace(other: DeepImmutable<Quaternion>): this {\r\n        this._x += other._x;\r\n        this._y += other._y;\r\n        this._z += other._z;\r\n        this._w += other._w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    public addToRef<T extends Quaternion>(other: DeepImmutable<this>, result: T): T {\r\n        result._x = this._x + other._x;\r\n        result._y = this._y + other._y;\r\n        result._z = this._z + other._z;\r\n        result._w = this._w + other._w;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Adds in place the given floats to the current quaternion\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @returns the current updated quaternion\r\n     */\r\n    public addInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n        this._x += x;\r\n        this._y += y;\r\n        this._z += z;\r\n        this._w += w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    public subtractToRef<T extends Quaternion>(other: DeepImmutable<this>, result: T): T {\r\n        result._x = this._x - other._x;\r\n        result._y = this._y - other._y;\r\n        result._z = this._z - other._z;\r\n        result._w = this._w - other._w;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current quaternion\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @returns a new quaternion as the subtraction result\r\n     */\r\n    public subtractFromFloats(x: number, y: number, z: number, w: number): Quaternion {\r\n        return this.subtractFromFloatsToRef(x, y, z, w, new Quaternion());\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current quaternion and stores the result in the given one\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @param result defines the quaternion to store the result\r\n     * @returns result input\r\n     */\r\n    public subtractFromFloatsToRef<T extends Quaternion>(x: number, y: number, z: number, w: number, result: T): T {\r\n        result._x = this._x - x;\r\n        result._y = this._y - y;\r\n        result._z = this._z - z;\r\n        result._w = this._w - w;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Subtract two quaternions\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#57\r\n     * @param other defines the second operand\r\n     * @returns a new quaternion as the subtraction result of the given one from the current one\r\n     */\r\n    public subtract(other: DeepImmutable<this>): Quaternion {\r\n        return new Quaternion(this._x - other._x, this._y - other._y, this._z - other._z, this._w - other._w);\r\n    }\r\n\r\n    /**\r\n     * Subtract a quaternion to the current one\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#58\r\n     * @param other defines the quaternion to subtract\r\n     * @returns the current quaternion\r\n     */\r\n    public subtractInPlace(other: DeepImmutable<Quaternion>): this {\r\n        this._x -= other._x;\r\n        this._y -= other._y;\r\n        this._z -= other._z;\r\n        this._w -= other._w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current quaternion by a scale factor\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#88\r\n     * @param value defines the scale factor\r\n     * @returns a new quaternion set by multiplying the current quaternion coordinates by the float \"scale\"\r\n     */\r\n    public scale(value: number): Quaternion {\r\n        return new Quaternion(this._x * value, this._y * value, this._z * value, this._w * value);\r\n    }\r\n\r\n    /**\r\n     * Scale the current quaternion values by a factor and stores the result to a given quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#89\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Quaternion object where to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleToRef<T extends Quaternion>(scale: number, result: T): T {\r\n        result._x = this._x * scale;\r\n        result._y = this._y * scale;\r\n        result._z = this._z * scale;\r\n        result._w = this._w * scale;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiplies in place the current quaternion by a scale factor\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#90\r\n     * @param value defines the scale factor\r\n     * @returns the current modified quaternion\r\n     */\r\n    public scaleInPlace(value: number): this {\r\n        this._x *= value;\r\n        this._y *= value;\r\n        this._z *= value;\r\n        this._w *= value;\r\n        this._isDirty = true;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Scale the current quaternion values by a factor and add the result to a given quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#91\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Quaternion object where to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleAndAddToRef<T extends Quaternion>(scale: number, result: T): T {\r\n        result._x += this._x * scale;\r\n        result._y += this._y * scale;\r\n        result._z += this._z * scale;\r\n        result._w += this._w * scale;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiplies two quaternions\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#43\r\n     * @param q1 defines the second operand\r\n     * @returns a new quaternion set as the multiplication result of the current one with the given one \"q1\"\r\n     */\r\n    public multiply(q1: DeepImmutable<Quaternion>): Quaternion {\r\n        const result = new Quaternion(0, 0, 0, 1.0);\r\n        this.multiplyToRef(q1, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given \"result\" as the multiplication result of the current one with the given one \"q1\"\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#45\r\n     * @param q1 defines the second operand\r\n     * @param result defines the target quaternion\r\n     * @returns the current quaternion\r\n     */\r\n    public multiplyToRef<T extends Quaternion>(q1: DeepImmutable<Quaternion>, result: T): T {\r\n        const x = this._x * q1._w + this._y * q1._z - this._z * q1._y + this._w * q1._x;\r\n        const y = -this._x * q1._z + this._y * q1._w + this._z * q1._x + this._w * q1._y;\r\n        const z = this._x * q1._y - this._y * q1._x + this._z * q1._w + this._w * q1._z;\r\n        const w = -this._x * q1._x - this._y * q1._y - this._z * q1._z + this._w * q1._w;\r\n        result.copyFromFloats(x, y, z, w);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Updates the current quaternion with the multiplication of itself with the given one \"q1\"\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#46\r\n     * @param other defines the second operand\r\n     * @returns the currentupdated quaternion\r\n     */\r\n    public multiplyInPlace(other: DeepImmutable<Quaternion>): this {\r\n        return this.multiplyToRef(other, this);\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current quaternion coordinates by the given floats\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @returns the current updated quaternion\r\n     */\r\n    public multiplyByFloats(x: number, y: number, z: number, w: number): this {\r\n        this._x *= x;\r\n        this._y *= y;\r\n        this._z *= z;\r\n        this._w *= w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divide(_other: DeepImmutable<this>): this {\r\n        throw new ReferenceError(\"Can not divide a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divideToRef<T extends Quaternion>(_other: DeepImmutable<this>, _result: T): T {\r\n        throw new ReferenceError(\"Can not divide a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divideInPlace(_other: DeepImmutable<this>): this {\r\n        throw new ReferenceError(\"Can not divide a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public minimizeInPlace(): this {\r\n        throw new ReferenceError(\"Can not minimize a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public minimizeInPlaceFromFloats(): this {\r\n        throw new ReferenceError(\"Can not minimize a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public maximizeInPlace(): this {\r\n        throw new ReferenceError(\"Can not maximize a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public maximizeInPlaceFromFloats(): this {\r\n        throw new ReferenceError(\"Can not maximize a quaternion\");\r\n    }\r\n\r\n    public negate(): Quaternion {\r\n        return this.negateToRef(new Quaternion());\r\n    }\r\n\r\n    public negateInPlace(): this {\r\n        this._x = -this._x;\r\n        this._y = -this._y;\r\n        this._z = -this._z;\r\n        this._w = -this._w;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    public negateToRef<T extends Quaternion>(result: T): T {\r\n        result._x = -this._x;\r\n        result._y = -this._y;\r\n        result._z = -this._z;\r\n        result._w = -this._w;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Determines if the current quaternion equals the given floats\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     * @param z defines the z coordinate\r\n     * @param w defines the w coordinate\r\n     * @returns true if the quaternion coordinates match the given floats\r\n     */\r\n    public equalsToFloats(x: number, y: number, z: number, w: number): boolean {\r\n        return this._x === x && this._y === y && this._z === z && this._w === w;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public floorToRef<T extends Quaternion>(_result: T): T {\r\n        throw new ReferenceError(\"Can not floor a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public floor(): Quaternion {\r\n        throw new ReferenceError(\"Can not floor a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public fractToRef<T extends Quaternion>(_result: T): T {\r\n        throw new ReferenceError(\"Can not fract a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public fract(): Quaternion {\r\n        throw new ReferenceError(\"Can not fract a quaternion\");\r\n    }\r\n\r\n    /**\r\n     * Conjugates the current quaternion and stores the result in the given quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#81\r\n     * @param ref defines the target quaternion\r\n     * @returns result input\r\n     */\r\n    public conjugateToRef<T extends Quaternion>(ref: T): T {\r\n        ref.copyFromFloats(-this._x, -this._y, -this._z, this._w);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Conjugates in place the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#82\r\n     * @returns the current updated quaternion\r\n     */\r\n    public conjugateInPlace(): this {\r\n        this._x *= -1;\r\n        this._y *= -1;\r\n        this._z *= -1;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Conjugates (1-q) the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#83\r\n     * @returns a new quaternion\r\n     */\r\n    public conjugate(): Quaternion {\r\n        return new Quaternion(-this._x, -this._y, -this._z, this._w);\r\n    }\r\n\r\n    /**\r\n     * Returns the inverse of the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#84\r\n     * @returns a new quaternion\r\n     */\r\n    public invert(): Quaternion {\r\n        const conjugate = this.conjugate();\r\n        const lengthSquared = this.lengthSquared();\r\n        if (lengthSquared == 0 || lengthSquared == 1) {\r\n            return conjugate;\r\n        }\r\n        conjugate.scaleInPlace(1 / lengthSquared);\r\n        return conjugate;\r\n    }\r\n\r\n    /**\r\n     * Invert in place the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#85\r\n     * @returns this quaternion\r\n     */\r\n    public invertInPlace(): this {\r\n        this.conjugateInPlace();\r\n        const lengthSquared = this.lengthSquared();\r\n        if (lengthSquared == 0 || lengthSquared == 1) {\r\n            return this;\r\n        }\r\n        this.scaleInPlace(1 / lengthSquared);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets squared length of current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#29\r\n     * @returns the quaternion length (float)\r\n     */\r\n    public lengthSquared(): number {\r\n        return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\r\n    }\r\n\r\n    /**\r\n     * Gets length of current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#28\r\n     * @returns the quaternion length (float)\r\n     */\r\n    public length(): number {\r\n        return Math.sqrt(this.lengthSquared());\r\n    }\r\n\r\n    /**\r\n     * Normalize in place the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#54\r\n     * @returns the current updated quaternion\r\n     */\r\n    public normalize(): this {\r\n        return this.normalizeFromLength(this.length());\r\n    }\r\n\r\n    /**\r\n     * Normalize the current quaternion with the given input length.\r\n     * Please note that this is an in place operation.\r\n     * @param len the length of the quaternion\r\n     * @returns the current updated Quaternion\r\n     */\r\n    public normalizeFromLength(len: number): this {\r\n        if (len === 0 || len === 1.0) {\r\n            return this;\r\n        }\r\n\r\n        return this.scaleInPlace(1.0 / len);\r\n    }\r\n\r\n    /**\r\n     * Normalize a copy of the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#55\r\n     * @returns the normalized quaternion\r\n     */\r\n    public normalizeToNew(): Quaternion {\r\n        const normalized = new Quaternion(0, 0, 0, 1);\r\n        this.normalizeToRef(normalized);\r\n        return normalized;\r\n    }\r\n\r\n    /**\r\n     * Normalize the current Quaternion to the reference\r\n     * @param reference define the Quaternion to update\r\n     * @returns the updated Quaternion\r\n     */\r\n    public normalizeToRef<T extends Quaternion>(reference: T): T {\r\n        const len = this.length();\r\n        if (len === 0 || len === 1.0) {\r\n            return reference.copyFromFloats(this._x, this._y, this._z, this._w);\r\n        }\r\n\r\n        return this.scaleToRef(1.0 / len, reference);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 set with the Euler angles translated from the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#32\r\n     * @returns a new Vector3 containing the Euler angles\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/rotation_conventions\r\n     */\r\n    public toEulerAngles(): Vector3 {\r\n        const result = Vector3.Zero();\r\n        this.toEulerAnglesToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector3 \"result\" with the Euler angles translated from the current quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#31\r\n     * @param result defines the vector which will be filled with the Euler angles\r\n     * @returns result input\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/rotation_conventions\r\n     */\r\n    public toEulerAnglesToRef<T extends Vector3>(result: T): T {\r\n        const qz = this._z;\r\n        const qx = this._x;\r\n        const qy = this._y;\r\n        const qw = this._w;\r\n\r\n        const zAxisY = qy * qz - qx * qw;\r\n        const limit = 0.4999999;\r\n\r\n        if (zAxisY < -limit) {\r\n            result._y = 2 * Math.atan2(qy, qw);\r\n            result._x = Math.PI / 2;\r\n            result._z = 0;\r\n            result._isDirty = true;\r\n        } else if (zAxisY > limit) {\r\n            result._y = 2 * Math.atan2(qy, qw);\r\n            result._x = -Math.PI / 2;\r\n            result._z = 0;\r\n            result._isDirty = true;\r\n        } else {\r\n            const sqw = qw * qw;\r\n            const sqz = qz * qz;\r\n            const sqx = qx * qx;\r\n            const sqy = qy * qy;\r\n            result._z = Math.atan2(2.0 * (qx * qy + qz * qw), -sqz - sqx + sqy + sqw);\r\n            result._x = Math.asin(-2.0 * zAxisY);\r\n            result._y = Math.atan2(2.0 * (qz * qx + qy * qw), sqz - sqx - sqy + sqw);\r\n            result._isDirty = true;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given vector3 \"result\" with the Alpha, Beta, Gamma Euler angles translated from the current quaternion\r\n     * @param result defines the vector which will be filled with the Euler angles\r\n     * @returns result input\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/rotation_conventions\r\n     */\r\n    public toAlphaBetaGammaToRef<T extends Vector3>(result: T): T {\r\n        const qz = this._z;\r\n        const qx = this._x;\r\n        const qy = this._y;\r\n        const qw = this._w;\r\n\r\n        // Compute intermediate values\r\n        const sinHalfBeta = Math.sqrt(qx * qx + qy * qy);\r\n        const cosHalfBeta = Math.sqrt(qz * qz + qw * qw);\r\n\r\n        // Calculate beta\r\n        const beta = 2 * Math.atan2(sinHalfBeta, cosHalfBeta);\r\n\r\n        // Calculate gamma + alpha\r\n        const gammaPlusAlpha = 2 * Math.atan2(qz, qw);\r\n\r\n        // Calculate gamma - alpha\r\n        const gammaMinusAlpha = 2 * Math.atan2(qy, qx);\r\n\r\n        // Calculate gamma and alpha\r\n        const gamma = (gammaPlusAlpha + gammaMinusAlpha) / 2;\r\n        const alpha = (gammaPlusAlpha - gammaMinusAlpha) / 2;\r\n\r\n        result.set(alpha, beta, gamma);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Updates the given rotation matrix with the current quaternion values\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#67\r\n     * @param result defines the target matrix\r\n     * @returns the updated matrix with the rotation\r\n     */\r\n    public toRotationMatrix<T extends Matrix>(result: T): T {\r\n        Matrix.FromQuaternionToRef(this, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Updates the current quaternion from the given rotation matrix values\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#41\r\n     * @param matrix defines the source matrix\r\n     * @returns the current updated quaternion\r\n     */\r\n    public fromRotationMatrix(matrix: DeepImmutable<Matrix>): this {\r\n        Quaternion.FromRotationMatrixToRef(matrix, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the dot product (float) between the current quaternions and \"other\"\r\n     * @param other defines the right operand\r\n     * @returns the dot product\r\n     */\r\n    public dot(other: DeepImmutable<this>): number {\r\n        return this._x * other._x + this._y * other._y + this._z * other._z + this._w * other._w;\r\n    }\r\n\r\n    /**\r\n     * Converts the current quaternion to an axis angle representation\r\n     * @returns the axis and angle in radians\r\n     */\r\n    public toAxisAngle(): { axis: Vector3; angle: number } {\r\n        const axis = Vector3.Zero();\r\n        const angle = this.toAxisAngleToRef(axis);\r\n        return { axis, angle };\r\n    }\r\n\r\n    /**\r\n     * Converts the current quaternion to an axis angle representation\r\n     * @param axis defines the target axis vector\r\n     * @returns the angle in radians\r\n     */\r\n    public toAxisAngleToRef<T extends Vector3>(axis: T): number {\r\n        let angle: number;\r\n        const sinHalfAngle = Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z);\r\n        const cosHalfAngle = this._w;\r\n\r\n        if (sinHalfAngle > 0) {\r\n            angle = 2 * Math.atan2(sinHalfAngle, cosHalfAngle);\r\n            axis.set(this._x / sinHalfAngle, this._y / sinHalfAngle, this._z / sinHalfAngle);\r\n        } else {\r\n            angle = 0;\r\n            axis.set(1, 0, 0);\r\n        }\r\n\r\n        return angle;\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Creates a new quaternion from a rotation matrix\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#101\r\n     * @param matrix defines the source matrix\r\n     * @returns a new quaternion created from the given rotation matrix values\r\n     */\r\n    public static FromRotationMatrix(matrix: DeepImmutable<Matrix>): Quaternion {\r\n        const result = new Quaternion();\r\n        Quaternion.FromRotationMatrixToRef(matrix, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Updates the given quaternion with the given rotation matrix values\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#102\r\n     * @param matrix defines the source matrix\r\n     * @param result defines the target quaternion\r\n     * @returns result input\r\n     */\r\n    public static FromRotationMatrixToRef<T extends Quaternion>(matrix: DeepImmutable<Matrix>, result: T): T {\r\n        const data = matrix.m;\r\n        const m11 = data[0],\r\n            m12 = data[4],\r\n            m13 = data[8];\r\n        const m21 = data[1],\r\n            m22 = data[5],\r\n            m23 = data[9];\r\n        const m31 = data[2],\r\n            m32 = data[6],\r\n            m33 = data[10];\r\n        const trace = m11 + m22 + m33;\r\n        let s;\r\n\r\n        if (trace > 0) {\r\n            s = 0.5 / Math.sqrt(trace + 1.0);\r\n\r\n            result._w = 0.25 / s;\r\n            result._x = (m32 - m23) * s;\r\n            result._y = (m13 - m31) * s;\r\n            result._z = (m21 - m12) * s;\r\n            result._isDirty = true;\r\n        } else if (m11 > m22 && m11 > m33) {\r\n            s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\r\n\r\n            result._w = (m32 - m23) / s;\r\n            result._x = 0.25 * s;\r\n            result._y = (m12 + m21) / s;\r\n            result._z = (m13 + m31) / s;\r\n            result._isDirty = true;\r\n        } else if (m22 > m33) {\r\n            s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\r\n\r\n            result._w = (m13 - m31) / s;\r\n            result._x = (m12 + m21) / s;\r\n            result._y = 0.25 * s;\r\n            result._z = (m23 + m32) / s;\r\n            result._isDirty = true;\r\n        } else {\r\n            s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\r\n\r\n            result._w = (m21 - m12) / s;\r\n            result._x = (m13 + m31) / s;\r\n            result._y = (m23 + m32) / s;\r\n            result._z = 0.25 * s;\r\n            result._isDirty = true;\r\n        }\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns the dot product (float) between the quaternions \"left\" and \"right\"\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#61\r\n     * @param left defines the left operand\r\n     * @param right defines the right operand\r\n     * @returns the dot product\r\n     */\r\n    public static Dot(left: DeepImmutable<Quaternion>, right: DeepImmutable<Quaternion>): number {\r\n        return left._x * right._x + left._y * right._y + left._z * right._z + left._w * right._w;\r\n    }\r\n\r\n    /**\r\n     * Checks if the orientations of two rotation quaternions are close to each other\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#60\r\n     * @param quat0 defines the first quaternion to check\r\n     * @param quat1 defines the second quaternion to check\r\n     * @param epsilon defines closeness, 0 same orientation, 1 PI apart, default 0.1\r\n     * @returns true if the two quaternions are close to each other within epsilon\r\n     */\r\n    public static AreClose(quat0: DeepImmutable<Quaternion>, quat1: DeepImmutable<Quaternion>, epsilon: number = 0.1): boolean {\r\n        const dot = Quaternion.Dot(quat0, quat1);\r\n\r\n        return 1 - dot * dot <= epsilon;\r\n    }\r\n\r\n    /**\r\n     * Smooth interpolation between two quaternions using Slerp\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#93\r\n     * @param source source quaternion\r\n     * @param goal goal quaternion\r\n     * @param deltaTime current interpolation frame\r\n     * @param lerpTime total interpolation time\r\n     * @param result the smoothed quaternion\r\n     * @returns the smoothed quaternion\r\n     */\r\n    public static SmoothToRef<T extends Quaternion>(source: Quaternion, goal: Quaternion, deltaTime: number, lerpTime: number, result: T): T {\r\n        let slerp = lerpTime === 0 ? 1 : deltaTime / lerpTime;\r\n        slerp = Clamp(slerp, 0, 1);\r\n\r\n        Quaternion.SlerpToRef(source, goal, slerp, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates an empty quaternion\r\n     * @returns a new quaternion set to (0.0, 0.0, 0.0)\r\n     */\r\n    public static Zero(): Quaternion {\r\n        return new Quaternion(0.0, 0.0, 0.0, 0.0);\r\n    }\r\n\r\n    /**\r\n     * Inverse a given quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#103\r\n     * @param q defines the source quaternion\r\n     * @returns a new quaternion as the inverted current quaternion\r\n     */\r\n    public static Inverse(q: DeepImmutable<Quaternion>): Quaternion {\r\n        return new Quaternion(-q._x, -q._y, -q._z, q._w);\r\n    }\r\n\r\n    /**\r\n     * Inverse a given quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#104\r\n     * @param q defines the source quaternion\r\n     * @param result the quaternion the result will be stored in\r\n     * @returns the result quaternion\r\n     */\r\n    public static InverseToRef<T extends Quaternion>(q: Quaternion, result: T): T {\r\n        result.set(-q._x, -q._y, -q._z, q._w);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates an identity quaternion\r\n     * @returns the identity quaternion\r\n     */\r\n    public static Identity(): Quaternion {\r\n        return new Quaternion(0.0, 0.0, 0.0, 1.0);\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the given quaternion is identity\r\n     * @param quaternion defines the quaternion to check\r\n     * @returns true if the quaternion is identity\r\n     */\r\n    public static IsIdentity(quaternion: DeepImmutable<Quaternion>): boolean {\r\n        return quaternion && quaternion._x === 0 && quaternion._y === 0 && quaternion._z === 0 && quaternion._w === 1;\r\n    }\r\n\r\n    /**\r\n     * Creates a quaternion from a rotation around an axis\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#72\r\n     * @param axis defines the axis to use\r\n     * @param angle defines the angle to use\r\n     * @returns a new quaternion created from the given axis (Vector3) and angle in radians (float)\r\n     */\r\n    public static RotationAxis(axis: DeepImmutable<Vector3>, angle: number): Quaternion {\r\n        return Quaternion.RotationAxisToRef(axis, angle, new Quaternion());\r\n    }\r\n\r\n    /**\r\n     * Creates a rotation around an axis and stores it into the given quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#73\r\n     * @param axis defines the axis to use\r\n     * @param angle defines the angle to use\r\n     * @param result defines the target quaternion\r\n     * @returns the target quaternion\r\n     */\r\n    public static RotationAxisToRef<T extends Quaternion>(axis: DeepImmutable<Vector3>, angle: number, result: T): T {\r\n        result._w = Math.cos(angle / 2);\r\n        const sinByLength = Math.sin(angle / 2) / axis.length();\r\n        result._x = axis._x * sinByLength;\r\n        result._y = axis._y * sinByLength;\r\n        result._z = axis._z * sinByLength;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new quaternion from data stored into an array\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#63\r\n     * @param array defines the data source\r\n     * @param offset defines the offset in the source array where the data starts\r\n     * @returns a new quaternion\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset?: number): Quaternion {\r\n        if (!offset) {\r\n            offset = 0;\r\n        }\r\n        return new Quaternion(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);\r\n    }\r\n\r\n    /**\r\n     * Updates the given quaternion \"result\" from the starting index of the given array.\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#64\r\n     * @param array the array to pull values from\r\n     * @param offset the offset into the array to start at\r\n     * @param result the quaternion to store the result in\r\n     * @returns result input\r\n     */\r\n    public static FromArrayToRef<T extends Quaternion>(array: DeepImmutable<ArrayLike<number>>, offset: number, result: T): T {\r\n        result._x = array[offset];\r\n        result._y = array[offset + 1];\r\n        result._z = array[offset + 2];\r\n        result._w = array[offset + 3];\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given quaternion \"result\" with the given floats.\r\n     * @param x defines the x coordinate of the source\r\n     * @param y defines the y coordinate of the source\r\n     * @param z defines the z coordinate of the source\r\n     * @param w defines the w coordinate of the source\r\n     * @param result defines the quaternion where to store the result\r\n     * @returns the result quaternion\r\n     */\r\n    public static FromFloatsToRef<T extends Quaternion = Quaternion>(x: number, y: number, z: number, w: number, result: T): T {\r\n        result.copyFromFloats(x, y, z, w);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Create a quaternion from Euler rotation angles\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#33\r\n     * @param x Pitch\r\n     * @param y Yaw\r\n     * @param z Roll\r\n     * @returns the new Quaternion\r\n     */\r\n    public static FromEulerAngles(x: number, y: number, z: number): Quaternion {\r\n        const q = new Quaternion();\r\n        Quaternion.RotationYawPitchRollToRef(y, x, z, q);\r\n        return q;\r\n    }\r\n\r\n    /**\r\n     * Updates a quaternion from Euler rotation angles\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#34\r\n     * @param x Pitch\r\n     * @param y Yaw\r\n     * @param z Roll\r\n     * @param result the quaternion to store the result\r\n     * @returns the updated quaternion\r\n     */\r\n    public static FromEulerAnglesToRef<T extends Quaternion>(x: number, y: number, z: number, result: T): T {\r\n        Quaternion.RotationYawPitchRollToRef(y, x, z, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Create a quaternion from Euler rotation vector\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#35\r\n     * @param vec the Euler vector (x Pitch, y Yaw, z Roll)\r\n     * @returns the new Quaternion\r\n     */\r\n    public static FromEulerVector(vec: DeepImmutable<Vector3>): Quaternion {\r\n        const q = new Quaternion();\r\n        Quaternion.RotationYawPitchRollToRef(vec._y, vec._x, vec._z, q);\r\n        return q;\r\n    }\r\n\r\n    /**\r\n     * Updates a quaternion from Euler rotation vector\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#36\r\n     * @param vec the Euler vector (x Pitch, y Yaw, z Roll)\r\n     * @param result the quaternion to store the result\r\n     * @returns the updated quaternion\r\n     */\r\n    public static FromEulerVectorToRef<T extends Quaternion>(vec: DeepImmutable<Vector3>, result: T): T {\r\n        Quaternion.RotationYawPitchRollToRef(vec._y, vec._x, vec._z, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Updates a quaternion so that it rotates vector vecFrom to vector vecTo\r\n     * Example Playground - https://playground.babylonjs.com/#L49EJ7#70\r\n     * @param vecFrom defines the direction vector from which to rotate\r\n     * @param vecTo defines the direction vector to which to rotate\r\n     * @param result the quaternion to store the result\r\n     * @param epsilon defines the minimal dot value to define vecs as opposite. Default: `BABYLON.Epsilon`\r\n     * @returns the updated quaternion\r\n     */\r\n    public static FromUnitVectorsToRef<T extends Quaternion>(vecFrom: DeepImmutable<Vector3>, vecTo: DeepImmutable<Vector3>, result: T, epsilon = Epsilon): T {\r\n        const r = Vector3.Dot(vecFrom, vecTo) + 1;\r\n\r\n        if (r < epsilon) {\r\n            if (Math.abs(vecFrom.x) > Math.abs(vecFrom.z)) {\r\n                result.set(-vecFrom.y, vecFrom.x, 0, 0);\r\n            } else {\r\n                result.set(0, -vecFrom.z, vecFrom.y, 0);\r\n            }\r\n        } else {\r\n            Vector3.CrossToRef(vecFrom, vecTo, TmpVectors.Vector3[0]);\r\n            result.set(TmpVectors.Vector3[0].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[0].z, r);\r\n        }\r\n\r\n        return result.normalize();\r\n    }\r\n\r\n    /**\r\n     * Creates a new quaternion from the given Euler float angles (y, x, z)\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#77\r\n     * @param yaw defines the rotation around Y axis\r\n     * @param pitch defines the rotation around X axis\r\n     * @param roll defines the rotation around Z axis\r\n     * @returns the new quaternion\r\n     */\r\n    public static RotationYawPitchRoll(yaw: number, pitch: number, roll: number): Quaternion {\r\n        const q = new Quaternion();\r\n        Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, q);\r\n        return q;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation from the given Euler float angles (y, x, z) and stores it in the target quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#561\r\n     * @param yaw defines the rotation around Y axis\r\n     * @param pitch defines the rotation around X axis\r\n     * @param roll defines the rotation around Z axis\r\n     * @param result defines the target quaternion\r\n     * @returns result input\r\n     */\r\n    public static RotationYawPitchRollToRef<T extends Quaternion>(yaw: number, pitch: number, roll: number, result: T): T {\r\n        // Produces a quaternion from Euler angles in the y-x-z orientation\r\n        const halfRoll = roll * 0.5;\r\n        const halfPitch = pitch * 0.5;\r\n        const halfYaw = yaw * 0.5;\r\n\r\n        const sinRoll = Math.sin(halfRoll);\r\n        const cosRoll = Math.cos(halfRoll);\r\n        const sinPitch = Math.sin(halfPitch);\r\n        const cosPitch = Math.cos(halfPitch);\r\n        const sinYaw = Math.sin(halfYaw);\r\n        const cosYaw = Math.cos(halfYaw);\r\n\r\n        result._x = cosYaw * sinPitch * cosRoll + sinYaw * cosPitch * sinRoll;\r\n        result._y = sinYaw * cosPitch * cosRoll - cosYaw * sinPitch * sinRoll;\r\n        result._z = cosYaw * cosPitch * sinRoll - sinYaw * sinPitch * cosRoll;\r\n        result._w = cosYaw * cosPitch * cosRoll + sinYaw * sinPitch * sinRoll;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new quaternion from the given Euler float angles expressed in z-x-z orientation\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#68\r\n     * @param alpha defines the rotation around first axis\r\n     * @param beta defines the rotation around second axis\r\n     * @param gamma defines the rotation around third axis\r\n     * @returns the new quaternion\r\n     */\r\n    public static RotationAlphaBetaGamma(alpha: number, beta: number, gamma: number): Quaternion {\r\n        const result = new Quaternion();\r\n        Quaternion.RotationAlphaBetaGammaToRef(alpha, beta, gamma, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new quaternion from the given Euler float angles expressed in z-x-z orientation and stores it in the target quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#69\r\n     * @param alpha defines the rotation around first axis\r\n     * @param beta defines the rotation around second axis\r\n     * @param gamma defines the rotation around third axis\r\n     * @param result defines the target quaternion\r\n     * @returns result input\r\n     */\r\n    public static RotationAlphaBetaGammaToRef<T extends Quaternion>(alpha: number, beta: number, gamma: number, result: T): T {\r\n        // Produces a quaternion from Euler angles in the z-x-z orientation\r\n        const halfGammaPlusAlpha = (gamma + alpha) * 0.5;\r\n        const halfGammaMinusAlpha = (gamma - alpha) * 0.5;\r\n        const halfBeta = beta * 0.5;\r\n\r\n        result._x = Math.cos(halfGammaMinusAlpha) * Math.sin(halfBeta);\r\n        result._y = Math.sin(halfGammaMinusAlpha) * Math.sin(halfBeta);\r\n        result._z = Math.sin(halfGammaPlusAlpha) * Math.cos(halfBeta);\r\n        result._w = Math.cos(halfGammaPlusAlpha) * Math.cos(halfBeta);\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new quaternion containing the rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system (axis1, axis2 and axis3 are normalized during this operation)\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#75\r\n     * @param axis1 defines the first axis\r\n     * @param axis2 defines the second axis\r\n     * @param axis3 defines the third axis\r\n     * @returns the new quaternion\r\n     */\r\n    public static RotationQuaternionFromAxis(axis1: DeepImmutable<Vector3>, axis2: DeepImmutable<Vector3>, axis3: DeepImmutable<Vector3>): Quaternion {\r\n        const quat = new Quaternion(0.0, 0.0, 0.0, 0.0);\r\n        Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);\r\n        return quat;\r\n    }\r\n\r\n    /**\r\n     * Creates a rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system (axis1, axis2 and axis3 are normalized during this operation) and stores it in the target quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#76\r\n     * @param axis1 defines the first axis\r\n     * @param axis2 defines the second axis\r\n     * @param axis3 defines the third axis\r\n     * @param ref defines the target quaternion\r\n     * @returns result input\r\n     */\r\n    public static RotationQuaternionFromAxisToRef<T extends Quaternion>(axis1: DeepImmutable<Vector3>, axis2: DeepImmutable<Vector3>, axis3: DeepImmutable<Vector3>, ref: T): T {\r\n        const rotMat = MathTmp.Matrix[0];\r\n        axis1 = axis1.normalizeToRef(MathTmp.Vector3[0]);\r\n        axis2 = axis2.normalizeToRef(MathTmp.Vector3[1]);\r\n        axis3 = axis3.normalizeToRef(MathTmp.Vector3[2]);\r\n        Matrix.FromXYZAxesToRef(axis1, axis2, axis3, rotMat);\r\n        Quaternion.FromRotationMatrixToRef(rotMat, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation value to orient an object to look towards the given forward direction, the up direction being oriented like \"up\".\r\n     * This function works in left handed mode\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#96\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @returns A new quaternion oriented toward the specified forward and up.\r\n     */\r\n    public static FromLookDirectionLH(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>): Quaternion {\r\n        const quat = new Quaternion();\r\n        Quaternion.FromLookDirectionLHToRef(forward, up, quat);\r\n        return quat;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation value to orient an object to look towards the given forward direction with the up direction being oriented like \"up\", and stores it in the target quaternion.\r\n     * This function works in left handed mode\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#97\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @param ref defines the target quaternion.\r\n     * @returns result input\r\n     */\r\n    public static FromLookDirectionLHToRef<T extends Quaternion>(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>, ref: T): T {\r\n        const rotMat = MathTmp.Matrix[0];\r\n        Matrix.LookDirectionLHToRef(forward, up, rotMat);\r\n        Quaternion.FromRotationMatrixToRef(rotMat, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation value to orient an object to look towards the given forward direction, the up direction being oriented like \"up\".\r\n     * This function works in right handed mode\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#98\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @returns A new quaternion oriented toward the specified forward and up.\r\n     */\r\n    public static FromLookDirectionRH(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>): Quaternion {\r\n        const quat = new Quaternion();\r\n        Quaternion.FromLookDirectionRHToRef(forward, up, quat);\r\n        return quat;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation value to orient an object to look towards the given forward direction with the up direction being oriented like \"up\", and stores it in the target quaternion.\r\n     * This function works in right handed mode\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#105\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @param ref defines the target quaternion.\r\n     * @returns result input\r\n     */\r\n    public static FromLookDirectionRHToRef<T extends Quaternion>(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>, ref: T): T {\r\n        const rotMat = MathTmp.Matrix[0];\r\n        Matrix.LookDirectionRHToRef(forward, up, rotMat);\r\n        return Quaternion.FromRotationMatrixToRef(rotMat, ref);\r\n    }\r\n\r\n    /**\r\n     * Interpolates between two quaternions\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#79\r\n     * @param left defines first quaternion\r\n     * @param right defines second quaternion\r\n     * @param amount defines the gradient to use\r\n     * @returns the new interpolated quaternion\r\n     */\r\n    public static Slerp(left: DeepImmutable<Quaternion>, right: DeepImmutable<Quaternion>, amount: number): Quaternion {\r\n        const result = Quaternion.Identity();\r\n\r\n        Quaternion.SlerpToRef(left, right, amount, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Interpolates between two quaternions and stores it into a target quaternion\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#92\r\n     * @param left defines first quaternion\r\n     * @param right defines second quaternion\r\n     * @param amount defines the gradient to use\r\n     * @param result defines the target quaternion\r\n     * @returns result input\r\n     */\r\n    public static SlerpToRef<T extends Quaternion>(left: DeepImmutable<Quaternion>, right: DeepImmutable<Quaternion>, amount: number, result: T): T {\r\n        let num2;\r\n        let num3;\r\n        let num4 = left._x * right._x + left._y * right._y + left._z * right._z + left._w * right._w;\r\n        let flag = false;\r\n\r\n        if (num4 < 0) {\r\n            flag = true;\r\n            num4 = -num4;\r\n        }\r\n\r\n        if (num4 > 0.999999) {\r\n            num3 = 1 - amount;\r\n            num2 = flag ? -amount : amount;\r\n        } else {\r\n            const num5 = Math.acos(num4);\r\n            const num6 = 1.0 / Math.sin(num5);\r\n            num3 = Math.sin((1.0 - amount) * num5) * num6;\r\n            num2 = flag ? -Math.sin(amount * num5) * num6 : Math.sin(amount * num5) * num6;\r\n        }\r\n\r\n        result._x = num3 * left._x + num2 * right._x;\r\n        result._y = num3 * left._y + num2 * right._y;\r\n        result._z = num3 * left._z + num2 * right._z;\r\n        result._w = num3 * left._w + num2 * right._w;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Interpolate between two quaternions using Hermite interpolation\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#47\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#hermite-quaternion-spline\r\n     * @param value1 defines first quaternion\r\n     * @param tangent1 defines the incoming tangent\r\n     * @param value2 defines second quaternion\r\n     * @param tangent2 defines the outgoing tangent\r\n     * @param amount defines the target quaternion\r\n     * @returns the new interpolated quaternion\r\n     */\r\n    public static Hermite(\r\n        value1: DeepImmutable<Quaternion>,\r\n        tangent1: DeepImmutable<Quaternion>,\r\n        value2: DeepImmutable<Quaternion>,\r\n        tangent2: DeepImmutable<Quaternion>,\r\n        amount: number\r\n    ): Quaternion {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n        const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n        const part2 = -2.0 * cubed + 3.0 * squared;\r\n        const part3 = cubed - 2.0 * squared + amount;\r\n        const part4 = cubed - squared;\r\n\r\n        const x = value1._x * part1 + value2._x * part2 + tangent1._x * part3 + tangent2._x * part4;\r\n        const y = value1._y * part1 + value2._y * part2 + tangent1._y * part3 + tangent2._y * part4;\r\n        const z = value1._z * part1 + value2._z * part2 + tangent1._z * part3 + tangent2._z * part4;\r\n        const w = value1._w * part1 + value2._w * part2 + tangent1._w * part3 + tangent2._w * part4;\r\n        return new Quaternion(x, y, z, w);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Quaternion which is the 1st derivative of the Hermite spline defined by the quaternions \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#48\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @returns 1st derivative\r\n     */\r\n    public static Hermite1stDerivative(\r\n        value1: DeepImmutable<Quaternion>,\r\n        tangent1: DeepImmutable<Quaternion>,\r\n        value2: DeepImmutable<Quaternion>,\r\n        tangent2: DeepImmutable<Quaternion>,\r\n        time: number\r\n    ): Quaternion {\r\n        const result = new Quaternion();\r\n\r\n        this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Update a Quaternion with the 1st derivative of the Hermite spline defined by the quaternions \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * Example Playground https://playground.babylonjs.com/#L49EJ7#49\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @param result define where to store the derivative\r\n     * @returns result input\r\n     */\r\n    public static Hermite1stDerivativeToRef<T extends Quaternion>(\r\n        value1: DeepImmutable<Quaternion>,\r\n        tangent1: DeepImmutable<Quaternion>,\r\n        value2: DeepImmutable<Quaternion>,\r\n        tangent2: DeepImmutable<Quaternion>,\r\n        time: number,\r\n        result: T\r\n    ): T {\r\n        const t2 = time * time;\r\n\r\n        result._x = (t2 - time) * 6 * value1._x + (3 * t2 - 4 * time + 1) * tangent1._x + (-t2 + time) * 6 * value2._x + (3 * t2 - 2 * time) * tangent2._x;\r\n        result._y = (t2 - time) * 6 * value1._y + (3 * t2 - 4 * time + 1) * tangent1._y + (-t2 + time) * 6 * value2._y + (3 * t2 - 2 * time) * tangent2._y;\r\n        result._z = (t2 - time) * 6 * value1._z + (3 * t2 - 4 * time + 1) * tangent1._z + (-t2 + time) * 6 * value2._z + (3 * t2 - 2 * time) * tangent2._z;\r\n        result._w = (t2 - time) * 6 * value1._w + (3 * t2 - 4 * time + 1) * tangent1._w + (-t2 + time) * 6 * value2._w + (3 * t2 - 2 * time) * tangent2._w;\r\n        result._isDirty = true;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Quaternion as the normalization of the given Quaternion\r\n     * @param quat defines the Quaternion to normalize\r\n     * @returns the new Quaternion\r\n     */\r\n    public static Normalize(quat: DeepImmutable<Quaternion>): Quaternion {\r\n        const result = Quaternion.Zero();\r\n        Quaternion.NormalizeToRef(quat, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given Quaternion \"result\" with the normalization of the given first Quaternion\r\n     * @param quat defines the Quaternion to normalize\r\n     * @param result defines the Quaternion where to store the result\r\n     * @returns result input\r\n     */\r\n    public static NormalizeToRef<T extends Quaternion>(quat: DeepImmutable<Quaternion>, result: T): T {\r\n        quat.normalizeToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Quaternion set with the coordinates of \"value\", if the quaternion \"value\" is in the cube defined by the quaternions \"min\" and \"max\"\r\n     * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n     * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n     * @param value defines the current value\r\n     * @param min defines the lower range value\r\n     * @param max defines the upper range value\r\n     * @returns the new Quaternion\r\n     */\r\n    public static Clamp(value: DeepImmutable<Quaternion>, min: DeepImmutable<Quaternion>, max: DeepImmutable<Quaternion>): Quaternion {\r\n        const result = new Quaternion();\r\n        Quaternion.ClampToRef(value, min, max, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given quaternion \"result\" with the coordinates of \"value\", if the quaternion \"value\" is in the cube defined by the quaternions \"min\" and \"max\"\r\n     * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n     * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n     * @param value defines the current value\r\n     * @param min defines the lower range value\r\n     * @param max defines the upper range value\r\n     * @param result defines the Quaternion where to store the result\r\n     * @returns result input\r\n     */\r\n    public static ClampToRef<T extends Quaternion>(value: DeepImmutable<Quaternion>, min: DeepImmutable<Quaternion>, max: DeepImmutable<Quaternion>, result: T): T {\r\n        return result.copyFromFloats(Clamp(value.x, min.x, max.x), Clamp(value.y, min.y, max.y), Clamp(value.z, min.z, max.z), Clamp(value.w, min.w, max.w));\r\n    }\r\n\r\n    /**\r\n     * Returns a new Quaternion with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @returns a Quaternion with random values between min and max\r\n     */\r\n    public static Random(min: number = 0, max: number = 1): Quaternion {\r\n        return new Quaternion(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Sets a Quaternion with random values between min and max\r\n     * @param min the minimum random value\r\n     * @param max the maximum random value\r\n     * @param ref the ref to store the values in\r\n     * @returns the ref with random values between min and max\r\n     */\r\n    public static RandomToRef<T extends Quaternion>(min: number = 0, max: number = 1, ref: T): T {\r\n        return ref.copyFromFloats(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n    }\r\n\r\n    /**\r\n     * Do not use\r\n     * @internal\r\n     */\r\n    public static Minimize(): Quaternion {\r\n        throw new ReferenceError(\"Quaternion.Minimize does not make sense\");\r\n    }\r\n\r\n    /**\r\n     * Do not use\r\n     * @internal\r\n     */\r\n    public static Maximize(): Quaternion {\r\n        throw new ReferenceError(\"Quaternion.Maximize does not make sense\");\r\n    }\r\n\r\n    /**\r\n     * Returns the distance (float) between the quaternions \"value1\" and \"value2\".\r\n     * @param value1 value to calulate the distance between\r\n     * @param value2 value to calulate the distance between\r\n     * @returns the distance between the two quaternions\r\n     */\r\n    public static Distance(value1: DeepImmutable<Quaternion>, value2: DeepImmutable<Quaternion>): number {\r\n        return Math.sqrt(Quaternion.DistanceSquared(value1, value2));\r\n    }\r\n    /**\r\n     * Returns the squared distance (float) between the quaternions \"value1\" and \"value2\".\r\n     * @param value1 value to calulate the distance between\r\n     * @param value2 value to calulate the distance between\r\n     * @returns the distance between the two quaternions squared\r\n     */\r\n    public static DistanceSquared(value1: DeepImmutable<Quaternion>, value2: DeepImmutable<Quaternion>): number {\r\n        const x = value1.x - value2.x;\r\n        const y = value1.y - value2.y;\r\n        const z = value1.z - value2.z;\r\n        const w = value1.w - value2.w;\r\n\r\n        return x * x + y * y + z * z + w * w;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Quaternion located at the center between the quaternions \"value1\" and \"value2\".\r\n     * @param value1 value to calulate the center between\r\n     * @param value2 value to calulate the center between\r\n     * @returns the center between the two quaternions\r\n     */\r\n    public static Center(value1: DeepImmutable<Quaternion>, value2: DeepImmutable<Quaternion>): Quaternion {\r\n        return Quaternion.CenterToRef(value1, value2, Quaternion.Zero());\r\n    }\r\n\r\n    /**\r\n     * Gets the center of the quaternions \"value1\" and \"value2\" and stores the result in the quaternion \"ref\"\r\n     * @param value1 defines first quaternion\r\n     * @param value2 defines second quaternion\r\n     * @param ref defines third quaternion\r\n     * @returns ref\r\n     */\r\n    public static CenterToRef<T extends Quaternion>(value1: DeepImmutable<Quaternion>, value2: DeepImmutable<Quaternion>, ref: T): T {\r\n        return ref.copyFromFloats((value1.x + value2.x) / 2, (value1.y + value2.y) / 2, (value1.z + value2.z) / 2, (value1.w + value2.w) / 2);\r\n    }\r\n}\r\nQuaternion satisfies TensorStatic<Quaternion, Quaternion>;\r\n\r\n/**\r\n * Class used to store matrix data (4x4)\r\n * Note on matrix definitions in Babylon.js for setting values directly\r\n * rather than using one of the methods available.\r\n * Matrix size is given by rows x columns.\r\n * A Vector3 is a 1 X 3 matrix [x, y, z].\r\n *\r\n * In Babylon.js multiplying a 1 x 3 matrix by a 4 x 4 matrix\r\n * is done using BABYLON.Vector4.TransformCoordinates(Vector3, Matrix).\r\n * and extending the passed Vector3 to a Vector4, V = [x, y, z, 1].\r\n * Let M be a matrix with elements m(row, column), so that\r\n * m(2, 3) is the element in row 2 column 3 of M.\r\n *\r\n * Multiplication is of the form VM and has the resulting Vector4\r\n * VM = [xm(0, 0) + ym(1, 0) + zm(2, 0) + m(3, 0), xm(0, 1) + ym(1, 1) + zm(2, 1) + m(3, 1), xm(0, 2) + ym(1, 2) + zm(2, 2) + m(3, 2), xm(0, 3) + ym(1, 3) + zm(2, 3) + m(3, 3)].\r\n * On the web you will find many examples that use the opposite convention of MV,\r\n * in which case to make use of the examples you will need to transpose the matrix.\r\n *\r\n * Example Playground - Overview Linear Algebra - https://playground.babylonjs.com/#AV9X17\r\n * Example Playground - Overview Transformation - https://playground.babylonjs.com/#AV9X17#1\r\n * Example Playground - Overview Projection - https://playground.babylonjs.com/#AV9X17#2\r\n */\r\nexport class Matrix implements Tensor<Tuple<Tuple<number, 4>, 4>, Matrix>, IMatrixLike {\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: Readonly<[4, 4]>;\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 2;\r\n\r\n    /**\r\n     * Gets the precision of matrix computations\r\n     */\r\n    public static get Use64Bits(): boolean {\r\n        return PerformanceConfigurator.MatrixUse64Bits;\r\n    }\r\n\r\n    private static _IdentityReadOnly = /*#__PURE__*/ Matrix.Identity() as DeepImmutable<Matrix>;\r\n\r\n    private _isIdentity = false;\r\n    private _isIdentityDirty = true;\r\n    private _isIdentity3x2 = true;\r\n    private _isIdentity3x2Dirty = true;\r\n    /**\r\n     * Gets the update flag of the matrix which is an unique number for the matrix.\r\n     * It will be incremented every time the matrix data change.\r\n     * You can use it to speed the comparison between two versions of the same matrix.\r\n     */\r\n    public updateFlag: number = -1;\r\n\r\n    private readonly _m: Tuple<number, 16>;\r\n\r\n    /**\r\n     * Gets the internal data of the matrix\r\n     */\r\n    public get m(): DeepImmutable<Tuple<number, 16>> {\r\n        return this._m;\r\n    }\r\n\r\n    /**\r\n     * Update the updateFlag to indicate that the matrix has been updated\r\n     */\r\n    public markAsUpdated() {\r\n        this.updateFlag = MatrixManagement._UpdateFlagSeed++;\r\n        this._isIdentity = false;\r\n        this._isIdentity3x2 = false;\r\n        this._isIdentityDirty = true;\r\n        this._isIdentity3x2Dirty = true;\r\n    }\r\n\r\n    private _updateIdentityStatus(isIdentity: boolean, isIdentityDirty: boolean = false, isIdentity3x2: boolean = false, isIdentity3x2Dirty: boolean = true) {\r\n        this._isIdentity = isIdentity;\r\n        this._isIdentity3x2 = isIdentity || isIdentity3x2;\r\n        this._isIdentityDirty = this._isIdentity ? false : isIdentityDirty;\r\n        this._isIdentity3x2Dirty = this._isIdentity3x2 ? false : isIdentity3x2Dirty;\r\n    }\r\n\r\n    /**\r\n     * Creates an empty matrix (filled with zeros)\r\n     */\r\n    public constructor() {\r\n        if (PerformanceConfigurator.MatrixTrackPrecisionChange) {\r\n            PerformanceConfigurator.MatrixTrackedMatrices!.push(this);\r\n        }\r\n\r\n        this._m = new PerformanceConfigurator.MatrixCurrentType(16);\r\n\r\n        this.markAsUpdated();\r\n    }\r\n\r\n    // Properties\r\n\r\n    /**\r\n     * Check if the current matrix is identity\r\n     * @returns true is the matrix is the identity matrix\r\n     */\r\n    public isIdentity(): boolean {\r\n        if (this._isIdentityDirty) {\r\n            this._isIdentityDirty = false;\r\n            const m = this._m;\r\n            this._isIdentity =\r\n                m[0] === 1.0 &&\r\n                m[1] === 0.0 &&\r\n                m[2] === 0.0 &&\r\n                m[3] === 0.0 &&\r\n                m[4] === 0.0 &&\r\n                m[5] === 1.0 &&\r\n                m[6] === 0.0 &&\r\n                m[7] === 0.0 &&\r\n                m[8] === 0.0 &&\r\n                m[9] === 0.0 &&\r\n                m[10] === 1.0 &&\r\n                m[11] === 0.0 &&\r\n                m[12] === 0.0 &&\r\n                m[13] === 0.0 &&\r\n                m[14] === 0.0 &&\r\n                m[15] === 1.0;\r\n        }\r\n\r\n        return this._isIdentity;\r\n    }\r\n\r\n    /**\r\n     * Check if the current matrix is identity as a texture matrix (3x2 store in 4x4)\r\n     * @returns true is the matrix is the identity matrix\r\n     */\r\n    public isIdentityAs3x2(): boolean {\r\n        if (this._isIdentity3x2Dirty) {\r\n            this._isIdentity3x2Dirty = false;\r\n            if (this._m[0] !== 1.0 || this._m[5] !== 1.0 || this._m[15] !== 1.0) {\r\n                this._isIdentity3x2 = false;\r\n            } else if (\r\n                this._m[1] !== 0.0 ||\r\n                this._m[2] !== 0.0 ||\r\n                this._m[3] !== 0.0 ||\r\n                this._m[4] !== 0.0 ||\r\n                this._m[6] !== 0.0 ||\r\n                this._m[7] !== 0.0 ||\r\n                this._m[8] !== 0.0 ||\r\n                this._m[9] !== 0.0 ||\r\n                this._m[10] !== 0.0 ||\r\n                this._m[11] !== 0.0 ||\r\n                this._m[12] !== 0.0 ||\r\n                this._m[13] !== 0.0 ||\r\n                this._m[14] !== 0.0\r\n            ) {\r\n                this._isIdentity3x2 = false;\r\n            } else {\r\n                this._isIdentity3x2 = true;\r\n            }\r\n        }\r\n\r\n        return this._isIdentity3x2;\r\n    }\r\n\r\n    /**\r\n     * Gets the determinant of the matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#34\r\n     * @returns the matrix determinant\r\n     */\r\n    public determinant(): number {\r\n        if (this._isIdentity === true) {\r\n            return 1;\r\n        }\r\n\r\n        const m = this._m;\r\n        const m00 = m[0],\r\n            m01 = m[1],\r\n            m02 = m[2],\r\n            m03 = m[3];\r\n        const m10 = m[4],\r\n            m11 = m[5],\r\n            m12 = m[6],\r\n            m13 = m[7];\r\n        const m20 = m[8],\r\n            m21 = m[9],\r\n            m22 = m[10],\r\n            m23 = m[11];\r\n        const m30 = m[12],\r\n            m31 = m[13],\r\n            m32 = m[14],\r\n            m33 = m[15];\r\n        // https://en.wikipedia.org/wiki/Laplace_expansion\r\n        // to compute the deterrminant of a 4x4 Matrix we compute the cofactors of any row or column,\r\n        // then we multiply each Cofactor by its corresponding matrix value and sum them all to get the determinant\r\n        // Cofactor(i, j) = sign(i,j) * det(Minor(i, j))\r\n        // where\r\n        //  - sign(i,j) = (i+j) % 2 === 0 ? 1 : -1\r\n        //  - Minor(i, j) is the 3x3 matrix we get by removing row i and column j from current Matrix\r\n        //\r\n        // Here we do that for the 1st row.\r\n\r\n        const det_22_33 = m22 * m33 - m32 * m23;\r\n        const det_21_33 = m21 * m33 - m31 * m23;\r\n        const det_21_32 = m21 * m32 - m31 * m22;\r\n        const det_20_33 = m20 * m33 - m30 * m23;\r\n        const det_20_32 = m20 * m32 - m22 * m30;\r\n        const det_20_31 = m20 * m31 - m30 * m21;\r\n        const cofact_00 = +(m11 * det_22_33 - m12 * det_21_33 + m13 * det_21_32);\r\n        const cofact_01 = -(m10 * det_22_33 - m12 * det_20_33 + m13 * det_20_32);\r\n        const cofact_02 = +(m10 * det_21_33 - m11 * det_20_33 + m13 * det_20_31);\r\n        const cofact_03 = -(m10 * det_21_32 - m11 * det_20_32 + m12 * det_20_31);\r\n        return m00 * cofact_00 + m01 * cofact_01 + m02 * cofact_02 + m03 * cofact_03;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Gets a string with the Matrix values\r\n     * @returns a string with the Matrix values\r\n     */\r\n    public toString(): string {\r\n        return `{${this.m[0]}, ${this.m[1]}, ${this.m[2]}, ${this.m[3]}\\n${this.m[4]}, ${this.m[5]}, ${this.m[6]}, ${this.m[7]}\\n${this.m[8]}, ${this.m[9]}, ${this.m[10]}, ${this.m[11]}\\n${this.m[12]}, ${this.m[13]}, ${this.m[14]}, ${this.m[15]}}`;\r\n    }\r\n\r\n    /**\r\n     * Returns the matrix as a Float32Array or Array<number>\r\n     * @deprecated Use asArray\r\n     */\r\n    public toArray(): FloatArray;\r\n\r\n    /**\r\n     * Stores the matrix in a Float32Array or Array<number>\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#49\r\n     * @param array The destination array\r\n     * @param index The destination index to start ay\r\n     * @returns the matrix\r\n     */\r\n    public toArray(array: FloatArray, index: number): this;\r\n    public toArray(array: Nullable<FloatArray> = null, index: number = 0): this | FloatArray {\r\n        if (!array) {\r\n            return this._m;\r\n        }\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            array[index + i] = m[i];\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the matrix as a Float32Array or Array<number>\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#114\r\n     * @returns the matrix underlying array.\r\n     */\r\n    public asArray(): Tuple<number, 16> {\r\n        return this._m;\r\n    }\r\n\r\n    public fromArray(array: FloatArray, index: number = 0): this {\r\n        return Matrix.FromArrayToRef(array, index, this);\r\n    }\r\n\r\n    /**\r\n     * Sets all the matrix values from a float array\r\n     * @param floats the 16 float values to set\r\n     * @returns the current updated matrix\r\n     */\r\n    public copyFromFloats(...floats: Tuple<number, 16>): this {\r\n        return Matrix.FromArrayToRef(floats, 0, this);\r\n    }\r\n\r\n    /**\r\n     * Sets the matrix values\r\n     * @param values the 16 values to set\r\n     * @returns the current updated matrix\r\n     */\r\n    public set(...values: Tuple<number, 16>): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = values[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets all the matrix values to the given value\r\n     * @param value the value to set\r\n     * @returns the current updated matrix\r\n     */\r\n    public setAll(value: number): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = value;\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Inverts the current matrix in place\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#118\r\n     * @returns the current inverted matrix\r\n     */\r\n    public invert(): this {\r\n        this.invertToRef(this);\r\n        return this;\r\n    }\r\n    /**\r\n     * Sets all the matrix elements to zero\r\n     * @returns the current matrix\r\n     */\r\n    public reset(): this {\r\n        Matrix.FromValuesToRef(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, this);\r\n        this._updateIdentityStatus(false);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the current matrix with a second one\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#44\r\n     * @param other defines the matrix to add\r\n     * @returns a new matrix as the addition of the current matrix and the given one\r\n     */\r\n    public add(other: DeepImmutable<Matrix>): Matrix {\r\n        const result = new Matrix();\r\n        this.addToRef(other, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given matrix \"result\" to the addition of the current matrix and the given one\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#45\r\n     * @param other defines the matrix to add\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public addToRef<T extends Matrix>(other: DeepImmutable<Matrix>, result: T): T {\r\n        const m = this._m;\r\n        const resultM = result._m;\r\n        const otherM = other.m;\r\n        for (let index = 0; index < 16; index++) {\r\n            resultM[index] = m[index] + otherM[index];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Adds in place the given matrix to the current matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#46\r\n     * @param other defines the second operand\r\n     * @returns the current updated matrix\r\n     */\r\n    public addToSelf(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m;\r\n        const otherM = other.m;\r\n        m[0] += otherM[0];\r\n        m[1] += otherM[1];\r\n        m[2] += otherM[2];\r\n        m[3] += otherM[3];\r\n        m[4] += otherM[4];\r\n        m[5] += otherM[5];\r\n        m[6] += otherM[6];\r\n        m[7] += otherM[7];\r\n        m[8] += otherM[8];\r\n        m[9] += otherM[9];\r\n        m[10] += otherM[10];\r\n        m[11] += otherM[11];\r\n        m[12] += otherM[12];\r\n        m[13] += otherM[13];\r\n        m[14] += otherM[14];\r\n        m[15] += otherM[15];\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public addInPlace(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] += otherM[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public addInPlaceFromFloats(...floats: Tuple<number, 16>): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] += floats[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public subtract(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] -= otherM[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n    public subtractToRef<T extends Matrix>(other: DeepImmutable<Matrix>, result: T): T {\r\n        const m = this._m,\r\n            otherM = other.m,\r\n            resultM = result._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = m[i] - otherM[i];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n    public subtractInPlace(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] -= otherM[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public subtractFromFloats(...floats: Tuple<number, 16>): Matrix {\r\n        return this.subtractFromFloatsToRef(...floats, new Matrix());\r\n    }\r\n\r\n    public subtractFromFloatsToRef<T extends Matrix>(...args: [...Tuple<number, 16>, T]): T {\r\n        const result = args.pop() as T,\r\n            m = this._m,\r\n            resultM = result._m,\r\n            values = args as unknown as Tuple<number, 16>;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = m[i] - values[i];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given matrix to the current inverted Matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#119\r\n     * @param other defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public invertToRef<T extends Matrix>(other: T): T {\r\n        if (this._isIdentity === true) {\r\n            Matrix.IdentityToRef(other);\r\n            return other;\r\n        }\r\n\r\n        if (InvertMatrixToArray(this, other.asArray())) {\r\n            other.markAsUpdated();\r\n        } else {\r\n            other.copyFrom(this);\r\n        }\r\n        return other;\r\n    }\r\n\r\n    /**\r\n     * add a value at the specified position in the current Matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#47\r\n     * @param index the index of the value within the matrix. between 0 and 15.\r\n     * @param value the value to be added\r\n     * @returns the current updated matrix\r\n     */\r\n    public addAtIndex(index: number, value: number): this {\r\n        this._m[index] += value;\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * mutiply the specified position in the current Matrix by a value\r\n     * @param index the index of the value within the matrix. between 0 and 15.\r\n     * @param value the value to be added\r\n     * @returns the current updated matrix\r\n     */\r\n    public multiplyAtIndex(index: number, value: number): this {\r\n        this._m[index] *= value;\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Inserts the translation vector (using 3 floats) in the current matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#120\r\n     * @param x defines the 1st component of the translation\r\n     * @param y defines the 2nd component of the translation\r\n     * @param z defines the 3rd component of the translation\r\n     * @returns the current updated matrix\r\n     */\r\n    public setTranslationFromFloats(x: number, y: number, z: number): this {\r\n        this._m[12] = x;\r\n        this._m[13] = y;\r\n        this._m[14] = z;\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the translation vector (using 3 floats) in the current matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#20\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#48\r\n     * @param x defines the 1st component of the translation\r\n     * @param y defines the 2nd component of the translation\r\n     * @param z defines the 3rd component of the translation\r\n     * @returns the current updated matrix\r\n     */\r\n    public addTranslationFromFloats(x: number, y: number, z: number): this {\r\n        this._m[12] += x;\r\n        this._m[13] += y;\r\n        this._m[14] += z;\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Inserts the translation vector in the current matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#121\r\n     * @param vector3 defines the translation to insert\r\n     * @returns the current updated matrix\r\n     */\r\n    public setTranslation(vector3: DeepImmutable<Vector3>): this {\r\n        return this.setTranslationFromFloats(vector3._x, vector3._y, vector3._z);\r\n    }\r\n\r\n    /**\r\n     * Gets the translation value of the current matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#122\r\n     * @returns a new Vector3 as the extracted translation from the matrix\r\n     */\r\n    public getTranslation(): Vector3 {\r\n        return new Vector3(this._m[12], this._m[13], this._m[14]);\r\n    }\r\n\r\n    /**\r\n     * Fill a Vector3 with the extracted translation from the matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#123\r\n     * @param result defines the Vector3 where to store the translation\r\n     * @returns the current matrix\r\n     */\r\n    public getTranslationToRef<T extends Vector3>(result: T): T {\r\n        result.x = this._m[12];\r\n        result.y = this._m[13];\r\n        result.z = this._m[14];\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Remove rotation and scaling part from the matrix\r\n     * @returns the updated matrix\r\n     */\r\n    public removeRotationAndScaling(): this {\r\n        const m = this.m;\r\n        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, m[12], m[13], m[14], m[15], this);\r\n        this._updateIdentityStatus(m[12] === 0 && m[13] === 0 && m[14] === 0 && m[15] === 1);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copy the current matrix from the given one\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#21\r\n     * @param other defines the source matrix\r\n     * @returns the current updated matrix\r\n     */\r\n    public copyFrom(other: DeepImmutable<Matrix>): this {\r\n        other.copyToArray(this._m);\r\n        const o = other as Matrix;\r\n        this.updateFlag = o.updateFlag;\r\n        this._updateIdentityStatus(o._isIdentity, o._isIdentityDirty, o._isIdentity3x2, o._isIdentity3x2Dirty);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Populates the given array from the starting index with the current matrix values\r\n     * @param array defines the target array\r\n     * @param offset defines the offset in the target array where to start storing values\r\n     * @returns the current matrix\r\n     */\r\n    public copyToArray(array: Float32Array | Array<number>, offset: number = 0): this {\r\n        CopyMatrixToArray(this, array, offset);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Multiply two matrices\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#15\r\n     * A.multiply(B) means apply B to A so result is B x A\r\n     * @param other defines the second operand\r\n     * @returns a new matrix set with the multiplication result of the current Matrix and the given one\r\n     */\r\n    public multiply(other: DeepImmutable<Matrix>): Matrix {\r\n        const result = new Matrix();\r\n        this.multiplyToRef(other, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * This method performs component-by-component in-place multiplication, rather than true matrix multiplication.\r\n     * Use multiply or multiplyToRef for matrix multiplication.\r\n     * @param other defines the second operand\r\n     * @returns the current updated matrix\r\n     */\r\n    public multiplyInPlace(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] *= otherM[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * This method performs a component-by-component multiplication of the current matrix with the array of transmitted numbers.\r\n     * Use multiply or multiplyToRef for matrix multiplication.\r\n     * @param floats defines the array of numbers to multiply the matrix by\r\n     * @returns the current updated matrix\r\n     */\r\n    public multiplyByFloats(...floats: Tuple<number, 16>): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] *= floats[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Multiples the current matrix by the given floats and stores them in the given ref\r\n     * @param args The floats and ref\r\n     * @returns The updated ref\r\n     */\r\n    public multiplyByFloatsToRef<T extends Matrix>(...args: [...Tuple<number, 16>, T]): T {\r\n        const result = args.pop() as T,\r\n            m = this._m,\r\n            resultM = result._m,\r\n            values = args as unknown as Tuple<number, 16>;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = m[i] * values[i];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given matrix \"result\" with the multiplication result of the current Matrix and the given one\r\n     * A.multiplyToRef(B, R) means apply B to A and store in R and R = B x A\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#16\r\n     * @param other defines the second operand\r\n     * @param result defines the matrix where to store the multiplication\r\n     * @returns result input\r\n     */\r\n    public multiplyToRef<T extends Matrix>(other: DeepImmutable<Matrix>, result: T): T {\r\n        if (this._isIdentity) {\r\n            result.copyFrom(other);\r\n            return result;\r\n        }\r\n        if ((other as Matrix)._isIdentity) {\r\n            result.copyFrom(this);\r\n            return result;\r\n        }\r\n\r\n        this.multiplyToArray(other, result._m, 0);\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the Float32Array \"result\" from the given index \"offset\" with the multiplication of the current matrix and the given one\r\n     * @param other defines the second operand\r\n     * @param result defines the array where to store the multiplication\r\n     * @param offset defines the offset in the target array where to start storing values\r\n     * @returns the current matrix\r\n     */\r\n    public multiplyToArray(other: DeepImmutable<Matrix>, result: Float32Array | Array<number>, offset: number): this {\r\n        MultiplyMatricesToArray(this, other, result, offset);\r\n        return this;\r\n    }\r\n\r\n    public divide(other: DeepImmutable<Matrix>): Matrix {\r\n        return this.divideToRef(other, new Matrix());\r\n    }\r\n\r\n    public divideToRef<T extends Matrix>(other: DeepImmutable<Matrix>, result: T): T {\r\n        const m = this._m,\r\n            otherM = other.m,\r\n            resultM = result._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = m[i] / otherM[i];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    public divideInPlace(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] /= otherM[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public minimizeInPlace(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = Math.min(m[i], otherM[i]);\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public minimizeInPlaceFromFloats(...floats: Tuple<number, 16>): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = Math.min(m[i], floats[i]);\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public maximizeInPlace(other: DeepImmutable<Matrix>): this {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = Math.max(m[i], otherM[i]);\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public maximizeInPlaceFromFloats(...floats: Tuple<number, 16>): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = Math.max(m[i], floats[i]);\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public negate(): Matrix {\r\n        return this.negateToRef(new Matrix());\r\n    }\r\n\r\n    public negateInPlace(): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] = -m[i];\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    public negateToRef<T extends Matrix>(result: T): T {\r\n        const m = this._m,\r\n            resultM = result._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = -m[i];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Check equality between this matrix and a second one\r\n     * @param value defines the second matrix to compare\r\n     * @returns true is the current matrix and the given one values are strictly equal\r\n     */\r\n    public equals(value: DeepImmutable<Matrix>): boolean {\r\n        const other = value as Matrix;\r\n        if (!other) {\r\n            return false;\r\n        }\r\n\r\n        if (this._isIdentity || other._isIdentity) {\r\n            if (!this._isIdentityDirty && !other._isIdentityDirty) {\r\n                return this._isIdentity && other._isIdentity;\r\n            }\r\n        }\r\n\r\n        const m = this.m;\r\n        const om = other.m;\r\n        return (\r\n            m[0] === om[0] &&\r\n            m[1] === om[1] &&\r\n            m[2] === om[2] &&\r\n            m[3] === om[3] &&\r\n            m[4] === om[4] &&\r\n            m[5] === om[5] &&\r\n            m[6] === om[6] &&\r\n            m[7] === om[7] &&\r\n            m[8] === om[8] &&\r\n            m[9] === om[9] &&\r\n            m[10] === om[10] &&\r\n            m[11] === om[11] &&\r\n            m[12] === om[12] &&\r\n            m[13] === om[13] &&\r\n            m[14] === om[14] &&\r\n            m[15] === om[15]\r\n        );\r\n    }\r\n\r\n    public equalsWithEpsilon(other: DeepImmutable<Matrix>, epsilon: number = 0): boolean {\r\n        const m = this._m,\r\n            otherM = other.m;\r\n        for (let i = 0; i < 16; i++) {\r\n            if (!WithinEpsilon(m[i], otherM[i], epsilon)) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    public equalsToFloats(...floats: Tuple<number, 16>): boolean {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            if (m[i] != floats[i]) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    public floor(): Matrix {\r\n        return this.floorToRef(new Matrix());\r\n    }\r\n\r\n    public floorToRef<T extends Matrix>(result: T): T {\r\n        const m = this._m,\r\n            resultM = result._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = Math.floor(m[i]);\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    public fract(): Matrix {\r\n        return this.fractToRef(new Matrix());\r\n    }\r\n\r\n    public fractToRef<T extends Matrix>(result: T): T {\r\n        const m = this._m,\r\n            resultM = result._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            resultM[i] = m[i] - Math.floor(m[i]);\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Clone the current matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#18\r\n     * @returns a new matrix from the current matrix\r\n     */\r\n    public clone(): Matrix {\r\n        const matrix = new Matrix();\r\n        matrix.copyFrom(this);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Returns the name of the current matrix class\r\n     * @returns the string \"Matrix\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Matrix\";\r\n    }\r\n\r\n    /**\r\n     * Gets the hash code of the current matrix\r\n     * @returns the hash code\r\n     */\r\n    public getHashCode(): number {\r\n        let hash = ExtractAsInt(this._m[0]);\r\n        for (let i = 1; i < 16; i++) {\r\n            hash = (hash * 397) ^ ExtractAsInt(this._m[i]);\r\n        }\r\n        return hash;\r\n    }\r\n\r\n    /**\r\n     * Decomposes the current Matrix into a translation, rotation and scaling components of the provided node\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#13\r\n     * @param node the node to decompose the matrix to\r\n     * @returns true if operation was successful\r\n     */\r\n    public decomposeToTransformNode(node: TransformNode): boolean {\r\n        node.rotationQuaternion = node.rotationQuaternion || new Quaternion();\r\n        return this.decompose(node.scaling, node.rotationQuaternion, node.position);\r\n    }\r\n    /**\r\n     * Decomposes the current Matrix into a translation, rotation and scaling components\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#12\r\n     * @param scale defines the scale vector3 given as a reference to update\r\n     * @param rotation defines the rotation quaternion given as a reference to update\r\n     * @param translation defines the translation vector3 given as a reference to update\r\n     * @param preserveScalingNode Use scaling sign coming from this node. Otherwise scaling sign might change.\r\n     * @param useAbsoluteScaling Use scaling sign coming from this absoluteScaling when true or scaling otherwise.\r\n     * @returns true if operation was successful\r\n     */\r\n    public decompose(scale?: Vector3, rotation?: Quaternion, translation?: Vector3, preserveScalingNode?: TransformNode, useAbsoluteScaling: boolean = true): boolean {\r\n        if (this._isIdentity) {\r\n            if (translation) {\r\n                translation.setAll(0);\r\n            }\r\n            if (scale) {\r\n                scale.setAll(1);\r\n            }\r\n            if (rotation) {\r\n                rotation.copyFromFloats(0, 0, 0, 1);\r\n            }\r\n            return true;\r\n        }\r\n\r\n        const m = this._m;\r\n        if (translation) {\r\n            translation.copyFromFloats(m[12], m[13], m[14]);\r\n        }\r\n\r\n        scale = scale || MathTmp.Vector3[0];\r\n\r\n        scale.x = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);\r\n        scale.y = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);\r\n        scale.z = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);\r\n\r\n        if (preserveScalingNode) {\r\n            const signX = (useAbsoluteScaling ? preserveScalingNode.absoluteScaling.x : preserveScalingNode.scaling.x) < 0 ? -1 : 1;\r\n            const signY = (useAbsoluteScaling ? preserveScalingNode.absoluteScaling.y : preserveScalingNode.scaling.y) < 0 ? -1 : 1;\r\n            const signZ = (useAbsoluteScaling ? preserveScalingNode.absoluteScaling.z : preserveScalingNode.scaling.z) < 0 ? -1 : 1;\r\n\r\n            scale.x *= signX;\r\n            scale.y *= signY;\r\n            scale.z *= signZ;\r\n        } else {\r\n            if (this.determinant() <= 0) {\r\n                scale.y *= -1;\r\n            }\r\n        }\r\n\r\n        if (scale._x === 0 || scale._y === 0 || scale._z === 0) {\r\n            if (rotation) {\r\n                rotation.copyFromFloats(0.0, 0.0, 0.0, 1.0);\r\n            }\r\n            return false;\r\n        }\r\n\r\n        if (rotation) {\r\n            const sx = 1 / scale._x,\r\n                sy = 1 / scale._y,\r\n                sz = 1 / scale._z;\r\n            Matrix.FromValuesToRef(\r\n                m[0] * sx,\r\n                m[1] * sx,\r\n                m[2] * sx,\r\n                0.0,\r\n                m[4] * sy,\r\n                m[5] * sy,\r\n                m[6] * sy,\r\n                0.0,\r\n                m[8] * sz,\r\n                m[9] * sz,\r\n                m[10] * sz,\r\n                0.0,\r\n                0.0,\r\n                0.0,\r\n                0.0,\r\n                1.0,\r\n                MathTmp.Matrix[0]\r\n            );\r\n\r\n            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets specific row of the matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n     * @param index defines the number of the row to get\r\n     * @returns the index-th row of the current matrix as a new Vector4\r\n     */\r\n    public getRow(index: number): Nullable<Vector4> {\r\n        if (index < 0 || index > 3) {\r\n            return null;\r\n        }\r\n        const i = index * 4;\r\n        return new Vector4(this._m[i + 0], this._m[i + 1], this._m[i + 2], this._m[i + 3]);\r\n    }\r\n\r\n    /**\r\n     * Gets specific row of the matrix to ref\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n     * @param index defines the number of the row to get\r\n     * @param rowVector vector to store the index-th row of the current matrix\r\n     * @returns result input\r\n     */\r\n    public getRowToRef<T extends Vector4>(index: number, rowVector: T): T {\r\n        if (index >= 0 && index <= 3) {\r\n            const i = index * 4;\r\n            rowVector.x = this._m[i + 0];\r\n            rowVector.y = this._m[i + 1];\r\n            rowVector.z = this._m[i + 2];\r\n            rowVector.w = this._m[i + 3];\r\n        }\r\n        return rowVector;\r\n    }\r\n\r\n    /**\r\n     * Sets the index-th row of the current matrix to the vector4 values\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n     * @param index defines the number of the row to set\r\n     * @param row defines the target vector4\r\n     * @returns the updated current matrix\r\n     */\r\n    public setRow(index: number, row: Vector4): this {\r\n        return this.setRowFromFloats(index, row.x, row.y, row.z, row.w);\r\n    }\r\n\r\n    /**\r\n     * Compute the transpose of the matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#40\r\n     * @returns the new transposed matrix\r\n     */\r\n    public transpose(): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.TransposeToRef(this, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Compute the transpose of the matrix and store it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#41\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public transposeToRef<T extends Matrix>(result: T): T {\r\n        Matrix.TransposeToRef(this, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the index-th row of the current matrix with the given 4 x float values\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n     * @param index defines the row index\r\n     * @param x defines the x component to set\r\n     * @param y defines the y component to set\r\n     * @param z defines the z component to set\r\n     * @param w defines the w component to set\r\n     * @returns the updated current matrix\r\n     */\r\n    public setRowFromFloats(index: number, x: number, y: number, z: number, w: number): this {\r\n        if (index < 0 || index > 3) {\r\n            return this;\r\n        }\r\n        const i = index * 4;\r\n        this._m[i + 0] = x;\r\n        this._m[i + 1] = y;\r\n        this._m[i + 2] = z;\r\n        this._m[i + 3] = w;\r\n\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Compute a new matrix set with the current matrix values multiplied by scale (float)\r\n     * @param scale defines the scale factor\r\n     * @returns a new matrix\r\n     */\r\n    public scale(scale: number): Matrix {\r\n        const result = new Matrix();\r\n        this.scaleToRef(scale, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Scale the current matrix values by a factor to a given result matrix\r\n     * @param scale defines the scale factor\r\n     * @param result defines the matrix to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleToRef<T extends Matrix>(scale: number, result: T): T {\r\n        for (let index = 0; index < 16; index++) {\r\n            result._m[index] = this._m[index] * scale;\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Scale the current matrix values by a factor and add the result to a given matrix\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Matrix to store the result\r\n     * @returns result input\r\n     */\r\n    public scaleAndAddToRef<T extends Matrix>(scale: number, result: T): T {\r\n        for (let index = 0; index < 16; index++) {\r\n            result._m[index] += this._m[index] * scale;\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    public scaleInPlace(scale: number): this {\r\n        const m = this._m;\r\n        for (let i = 0; i < 16; i++) {\r\n            m[i] *= scale;\r\n        }\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Writes to the given matrix a normal matrix, computed from this one (using values from identity matrix for fourth row and column).\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#17\r\n     * @param ref matrix to store the result\r\n     * @returns the reference matrix\r\n     */\r\n    public toNormalMatrix<T extends Matrix>(ref: T): T {\r\n        const tmp = MathTmp.Matrix[0];\r\n        this.invertToRef(tmp);\r\n        tmp.transposeToRef(ref);\r\n        const m = ref._m;\r\n        Matrix.FromValuesToRef(m[0], m[1], m[2], 0.0, m[4], m[5], m[6], 0.0, m[8], m[9], m[10], 0.0, 0.0, 0.0, 0.0, 1.0, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Gets only rotation part of the current matrix\r\n     * @returns a new matrix sets to the extracted rotation matrix from the current one\r\n     */\r\n    public getRotationMatrix(): Matrix {\r\n        const result = new Matrix();\r\n        this.getRotationMatrixToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Extracts the rotation matrix from the current one and sets it as the given \"result\"\r\n     * @param result defines the target matrix to store data to\r\n     * @returns result input\r\n     */\r\n    public getRotationMatrixToRef<T extends Matrix>(result: T): T {\r\n        const scale = MathTmp.Vector3[0];\r\n        if (!this.decompose(scale)) {\r\n            Matrix.IdentityToRef(result);\r\n            return result;\r\n        }\r\n\r\n        const m = this._m;\r\n        const sx = 1 / scale._x,\r\n            sy = 1 / scale._y,\r\n            sz = 1 / scale._z;\r\n        Matrix.FromValuesToRef(m[0] * sx, m[1] * sx, m[2] * sx, 0.0, m[4] * sy, m[5] * sy, m[6] * sy, 0.0, m[8] * sz, m[9] * sz, m[10] * sz, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Toggles model matrix from being right handed to left handed in place and vice versa\r\n     * @returns the current updated matrix\r\n     */\r\n    public toggleModelMatrixHandInPlace(): this {\r\n        const m = this._m;\r\n        m[2] *= -1;\r\n        m[6] *= -1;\r\n        m[8] *= -1;\r\n        m[9] *= -1;\r\n        m[14] *= -1;\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Toggles projection matrix from being right handed to left handed in place and vice versa\r\n     * @returns the current updated matrix\r\n     */\r\n    public toggleProjectionMatrixHandInPlace(): this {\r\n        const m = this._m;\r\n        m[8] *= -1;\r\n        m[9] *= -1;\r\n        m[10] *= -1;\r\n        m[11] *= -1;\r\n        this.markAsUpdated();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Converts this projection matrix's clip-space depth range from the OpenGL/WebGL convention (NDC z in [-1, 1]) to\r\n     * the WebGPU/D3D convention (NDC z in [0, 1]) in place, by post-multiplying with the standard half-Z conversion\r\n     * matrix. This is the same conversion the perspective/orthographic builders apply internally when their\r\n     * `halfZRange` flag is set; it is exposed here for callers (e.g. the WebXR path) that receive a projection matrix\r\n     * verbatim from an external source and must range-correct it for a `isNDCHalfZRange` engine.\r\n     * @internal\r\n     * @returns the current updated matrix\r\n     */\r\n    public _convertProjectionToHalfZRangeInPlace(): this {\r\n        this.multiplyToRef(mtxConvertNDCToHalfZRange, this);\r\n        return this;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Creates a matrix from an array\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#42\r\n     * @param array defines the source array\r\n     * @param offset defines an offset in the source array\r\n     * @returns a new Matrix set from the starting index of the given array\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.FromArrayToRef(array, offset, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Copy the content of an array into a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#43\r\n     * @param array defines the source array\r\n     * @param offset defines an offset in the source array\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static FromArrayToRef<T extends Matrix>(array: DeepImmutable<ArrayLike<number>>, offset: number, result: T): T {\r\n        for (let index = 0; index < 16; index++) {\r\n            result._m[index] = array[index + offset];\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Stores an array into a matrix after having multiplied each component by a given factor\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#50\r\n     * @param array defines the source array\r\n     * @param offset defines the offset in the source array\r\n     * @param scale defines the scaling factor\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static FromFloat32ArrayToRefScaled<T extends Matrix>(array: DeepImmutable<Float32Array | Array<number>>, offset: number, scale: number, result: T): T {\r\n        result._m[0] = array[0 + offset] * scale;\r\n        result._m[1] = array[1 + offset] * scale;\r\n        result._m[2] = array[2 + offset] * scale;\r\n        result._m[3] = array[3 + offset] * scale;\r\n        result._m[4] = array[4 + offset] * scale;\r\n        result._m[5] = array[5 + offset] * scale;\r\n        result._m[6] = array[6 + offset] * scale;\r\n        result._m[7] = array[7 + offset] * scale;\r\n        result._m[8] = array[8 + offset] * scale;\r\n        result._m[9] = array[9 + offset] * scale;\r\n        result._m[10] = array[10 + offset] * scale;\r\n        result._m[11] = array[11 + offset] * scale;\r\n        result._m[12] = array[12 + offset] * scale;\r\n        result._m[13] = array[13 + offset] * scale;\r\n        result._m[14] = array[14 + offset] * scale;\r\n        result._m[15] = array[15 + offset] * scale;\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets an identity matrix that must not be updated\r\n     */\r\n    public static get IdentityReadOnly(): DeepImmutable<Matrix> {\r\n        return Matrix._IdentityReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Stores a list of values (16) inside a given matrix\r\n     * @param initialM11 defines 1st value of 1st row\r\n     * @param initialM12 defines 2nd value of 1st row\r\n     * @param initialM13 defines 3rd value of 1st row\r\n     * @param initialM14 defines 4th value of 1st row\r\n     * @param initialM21 defines 1st value of 2nd row\r\n     * @param initialM22 defines 2nd value of 2nd row\r\n     * @param initialM23 defines 3rd value of 2nd row\r\n     * @param initialM24 defines 4th value of 2nd row\r\n     * @param initialM31 defines 1st value of 3rd row\r\n     * @param initialM32 defines 2nd value of 3rd row\r\n     * @param initialM33 defines 3rd value of 3rd row\r\n     * @param initialM34 defines 4th value of 3rd row\r\n     * @param initialM41 defines 1st value of 4th row\r\n     * @param initialM42 defines 2nd value of 4th row\r\n     * @param initialM43 defines 3rd value of 4th row\r\n     * @param initialM44 defines 4th value of 4th row\r\n     * @param result defines the target matrix\r\n     */\r\n    public static FromValuesToRef(\r\n        initialM11: number,\r\n        initialM12: number,\r\n        initialM13: number,\r\n        initialM14: number,\r\n        initialM21: number,\r\n        initialM22: number,\r\n        initialM23: number,\r\n        initialM24: number,\r\n        initialM31: number,\r\n        initialM32: number,\r\n        initialM33: number,\r\n        initialM34: number,\r\n        initialM41: number,\r\n        initialM42: number,\r\n        initialM43: number,\r\n        initialM44: number,\r\n        result: Matrix\r\n    ): void {\r\n        const m = result._m;\r\n        m[0] = initialM11;\r\n        m[1] = initialM12;\r\n        m[2] = initialM13;\r\n        m[3] = initialM14;\r\n        m[4] = initialM21;\r\n        m[5] = initialM22;\r\n        m[6] = initialM23;\r\n        m[7] = initialM24;\r\n        m[8] = initialM31;\r\n        m[9] = initialM32;\r\n        m[10] = initialM33;\r\n        m[11] = initialM34;\r\n        m[12] = initialM41;\r\n        m[13] = initialM42;\r\n        m[14] = initialM43;\r\n        m[15] = initialM44;\r\n\r\n        result.markAsUpdated();\r\n    }\r\n\r\n    /**\r\n     * Creates new matrix from a list of values (16)\r\n     * @param initialM11 defines 1st value of 1st row\r\n     * @param initialM12 defines 2nd value of 1st row\r\n     * @param initialM13 defines 3rd value of 1st row\r\n     * @param initialM14 defines 4th value of 1st row\r\n     * @param initialM21 defines 1st value of 2nd row\r\n     * @param initialM22 defines 2nd value of 2nd row\r\n     * @param initialM23 defines 3rd value of 2nd row\r\n     * @param initialM24 defines 4th value of 2nd row\r\n     * @param initialM31 defines 1st value of 3rd row\r\n     * @param initialM32 defines 2nd value of 3rd row\r\n     * @param initialM33 defines 3rd value of 3rd row\r\n     * @param initialM34 defines 4th value of 3rd row\r\n     * @param initialM41 defines 1st value of 4th row\r\n     * @param initialM42 defines 2nd value of 4th row\r\n     * @param initialM43 defines 3rd value of 4th row\r\n     * @param initialM44 defines 4th value of 4th row\r\n     * @returns the new matrix\r\n     */\r\n    public static FromValues(\r\n        initialM11: number,\r\n        initialM12: number,\r\n        initialM13: number,\r\n        initialM14: number,\r\n        initialM21: number,\r\n        initialM22: number,\r\n        initialM23: number,\r\n        initialM24: number,\r\n        initialM31: number,\r\n        initialM32: number,\r\n        initialM33: number,\r\n        initialM34: number,\r\n        initialM41: number,\r\n        initialM42: number,\r\n        initialM43: number,\r\n        initialM44: number\r\n    ): Matrix {\r\n        const result = new Matrix();\r\n        const m = result._m;\r\n        m[0] = initialM11;\r\n        m[1] = initialM12;\r\n        m[2] = initialM13;\r\n        m[3] = initialM14;\r\n        m[4] = initialM21;\r\n        m[5] = initialM22;\r\n        m[6] = initialM23;\r\n        m[7] = initialM24;\r\n        m[8] = initialM31;\r\n        m[9] = initialM32;\r\n        m[10] = initialM33;\r\n        m[11] = initialM34;\r\n        m[12] = initialM41;\r\n        m[13] = initialM42;\r\n        m[14] = initialM43;\r\n        m[15] = initialM44;\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new matrix composed by merging scale (vector3), rotation (quaternion) and translation (vector3)\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#24\r\n     * @param scale defines the scale vector3\r\n     * @param rotation defines the rotation quaternion\r\n     * @param translation defines the translation vector3\r\n     * @returns a new matrix\r\n     */\r\n    public static Compose(scale: DeepImmutable<Vector3>, rotation: DeepImmutable<Quaternion>, translation: DeepImmutable<Vector3>): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.ComposeToRef(scale, rotation, translation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets a matrix to a value composed by merging scale (vector3), rotation (quaternion) and translation (vector3)\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#25\r\n     * @param scale defines the scale vector3\r\n     * @param rotation defines the rotation quaternion\r\n     * @param translation defines the translation vector3\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static ComposeToRef<T extends Matrix>(scale: DeepImmutable<Vector3>, rotation: DeepImmutable<Quaternion>, translation: DeepImmutable<Vector3>, result: T): T {\r\n        const m = result._m;\r\n        const x = rotation._x,\r\n            y = rotation._y,\r\n            z = rotation._z,\r\n            w = rotation._w;\r\n        const x2 = x + x,\r\n            y2 = y + y,\r\n            z2 = z + z;\r\n        const xx = x * x2,\r\n            xy = x * y2,\r\n            xz = x * z2;\r\n        const yy = y * y2,\r\n            yz = y * z2,\r\n            zz = z * z2;\r\n        const wx = w * x2,\r\n            wy = w * y2,\r\n            wz = w * z2;\r\n\r\n        const sx = scale._x,\r\n            sy = scale._y,\r\n            sz = scale._z;\r\n\r\n        m[0] = (1 - (yy + zz)) * sx;\r\n        m[1] = (xy + wz) * sx;\r\n        m[2] = (xz - wy) * sx;\r\n        m[3] = 0;\r\n\r\n        m[4] = (xy - wz) * sy;\r\n        m[5] = (1 - (xx + zz)) * sy;\r\n        m[6] = (yz + wx) * sy;\r\n        m[7] = 0;\r\n\r\n        m[8] = (xz + wy) * sz;\r\n        m[9] = (yz - wx) * sz;\r\n        m[10] = (1 - (xx + yy)) * sz;\r\n        m[11] = 0;\r\n\r\n        m[12] = translation._x;\r\n        m[13] = translation._y;\r\n        m[14] = translation._z;\r\n        m[15] = 1;\r\n\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new identity matrix\r\n     * @returns a new identity matrix\r\n     */\r\n    public static Identity(): Matrix {\r\n        const identity = Matrix.FromValues(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);\r\n        identity._updateIdentityStatus(true);\r\n        return identity;\r\n    }\r\n\r\n    /**\r\n     * Creates a new identity matrix and stores the result in a given matrix\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static IdentityToRef<T extends Matrix>(result: T): T {\r\n        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n        result._updateIdentityStatus(true);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new zero matrix\r\n     * @returns a new zero matrix\r\n     */\r\n    public static Zero(): Matrix {\r\n        const zero = Matrix.FromValues(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);\r\n        zero._updateIdentityStatus(false);\r\n        return zero;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the X axis\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#97\r\n     * @param angle defines the angle (in radians) to use\r\n     * @returns the new matrix\r\n     */\r\n    public static RotationX(angle: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.RotationXToRef(angle, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new matrix as the invert of a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#124\r\n     * @param source defines the source matrix\r\n     * @returns the new matrix\r\n     */\r\n    public static Invert(source: DeepImmutable<Matrix>): Matrix {\r\n        const result = new Matrix();\r\n        source.invertToRef(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the X axis and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#98\r\n     * @param angle defines the angle (in radians) to use\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static RotationXToRef<T extends Matrix>(angle: number, result: T): T {\r\n        const s = Math.sin(angle);\r\n        const c = Math.cos(angle);\r\n        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, c, s, 0.0, 0.0, -s, c, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n        result._updateIdentityStatus(c === 1 && s === 0);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the Y axis\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#99\r\n     * @param angle defines the angle (in radians) to use\r\n     * @returns the new matrix\r\n     */\r\n    public static RotationY(angle: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.RotationYToRef(angle, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the Y axis and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#100\r\n     * @param angle defines the angle (in radians) to use\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static RotationYToRef<T extends Matrix>(angle: number, result: T): T {\r\n        const s = Math.sin(angle);\r\n        const c = Math.cos(angle);\r\n        Matrix.FromValuesToRef(c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n        result._updateIdentityStatus(c === 1 && s === 0);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the Z axis\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#101\r\n     * @param angle defines the angle (in radians) to use\r\n     * @returns the new matrix\r\n     */\r\n    public static RotationZ(angle: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.RotationZToRef(angle, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the Z axis and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#102\r\n     * @param angle defines the angle (in radians) to use\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static RotationZToRef<T extends Matrix>(angle: number, result: T): T {\r\n        const s = Math.sin(angle);\r\n        const c = Math.cos(angle);\r\n        Matrix.FromValuesToRef(c, s, 0.0, 0.0, -s, c, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n        result._updateIdentityStatus(c === 1 && s === 0);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the given axis\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#96\r\n     * @param axis defines the axis to use\r\n     * @param angle defines the angle (in radians) to use\r\n     * @returns the new matrix\r\n     */\r\n    public static RotationAxis(axis: DeepImmutable<Vector3>, angle: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.RotationAxisToRef(axis, angle, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rotation matrix for \"angle\" radians around the given axis and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#94\r\n     * @param axis defines the axis to use\r\n     * @param angle defines the angle (in radians) to use\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static RotationAxisToRef<T extends Matrix>(axis: DeepImmutable<Vector3>, angle: number, result: T): T {\r\n        const s = Math.sin(-angle);\r\n        const c = Math.cos(-angle);\r\n        const c1 = 1 - c;\r\n\r\n        axis = axis.normalizeToRef(MathTmp.Vector3[0]);\r\n        const m = result._m;\r\n        m[0] = axis._x * axis._x * c1 + c;\r\n        m[1] = axis._x * axis._y * c1 - axis._z * s;\r\n        m[2] = axis._x * axis._z * c1 + axis._y * s;\r\n        m[3] = 0.0;\r\n\r\n        m[4] = axis._y * axis._x * c1 + axis._z * s;\r\n        m[5] = axis._y * axis._y * c1 + c;\r\n        m[6] = axis._y * axis._z * c1 - axis._x * s;\r\n        m[7] = 0.0;\r\n\r\n        m[8] = axis._z * axis._x * c1 - axis._y * s;\r\n        m[9] = axis._z * axis._y * c1 + axis._x * s;\r\n        m[10] = axis._z * axis._z * c1 + c;\r\n        m[11] = 0.0;\r\n\r\n        m[12] = 0.0;\r\n        m[13] = 0.0;\r\n        m[14] = 0.0;\r\n        m[15] = 1.0;\r\n\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Takes normalised vectors and returns a rotation matrix to align \"from\" with \"to\".\r\n     * Taken from http://www.iquilezles.org/www/articles/noacos/noacos.htm\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#93\r\n     * @param from defines the vector to align\r\n     * @param to defines the vector to align to\r\n     * @param result defines the target matrix\r\n     * @param useYAxisForCoplanar defines a boolean indicating that we should favor Y axis for coplanar vectors (default is false)\r\n     * @returns result input\r\n     */\r\n    public static RotationAlignToRef<T extends Matrix>(from: DeepImmutable<Vector3>, to: DeepImmutable<Vector3>, result: T, useYAxisForCoplanar = false): T {\r\n        const c = Vector3.Dot(to, from);\r\n        const m = result._m;\r\n        if (c < -1 + Epsilon) {\r\n            // from and to are colinear and opposite direction.\r\n            // compute a PI rotation on Y axis\r\n            m[0] = -1;\r\n            m[1] = 0;\r\n            m[2] = 0;\r\n            m[3] = 0;\r\n            m[4] = 0;\r\n            m[5] = useYAxisForCoplanar ? 1 : -1;\r\n            m[6] = 0;\r\n            m[7] = 0;\r\n            m[8] = 0;\r\n            m[9] = 0;\r\n            m[10] = useYAxisForCoplanar ? -1 : 1;\r\n            m[11] = 0;\r\n        } else {\r\n            const v = Vector3.Cross(to, from);\r\n            const k = 1 / (1 + c);\r\n\r\n            m[0] = v._x * v._x * k + c;\r\n            m[1] = v._y * v._x * k - v._z;\r\n            m[2] = v._z * v._x * k + v._y;\r\n            m[3] = 0;\r\n            m[4] = v._x * v._y * k + v._z;\r\n            m[5] = v._y * v._y * k + c;\r\n            m[6] = v._z * v._y * k - v._x;\r\n            m[7] = 0;\r\n            m[8] = v._x * v._z * k - v._y;\r\n            m[9] = v._y * v._z * k + v._x;\r\n            m[10] = v._z * v._z * k + c;\r\n            m[11] = 0;\r\n        }\r\n        m[12] = 0;\r\n        m[13] = 0;\r\n        m[14] = 0;\r\n        m[15] = 1;\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a rotation matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#103\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#105\r\n     * @param yaw defines the yaw angle in radians (Y axis)\r\n     * @param pitch defines the pitch angle in radians (X axis)\r\n     * @param roll defines the roll angle in radians (Z axis)\r\n     * @returns the new rotation matrix\r\n     */\r\n    public static RotationYawPitchRoll(yaw: number, pitch: number, roll: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a rotation matrix and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#104\r\n     * @param yaw defines the yaw angle in radians (Y axis)\r\n     * @param pitch defines the pitch angle in radians (X axis)\r\n     * @param roll defines the roll angle in radians (Z axis)\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static RotationYawPitchRollToRef<T extends Matrix>(yaw: number, pitch: number, roll: number, result: T): T {\r\n        Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, MathTmp.Quaternion[0]);\r\n        MathTmp.Quaternion[0].toRotationMatrix(result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a scaling matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#107\r\n     * @param x defines the scale factor on X axis\r\n     * @param y defines the scale factor on Y axis\r\n     * @param z defines the scale factor on Z axis\r\n     * @returns the new matrix\r\n     */\r\n    public static Scaling(x: number, y: number, z: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.ScalingToRef(x, y, z, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a scaling matrix and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#108\r\n     * @param x defines the scale factor on X axis\r\n     * @param y defines the scale factor on Y axis\r\n     * @param z defines the scale factor on Z axis\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static ScalingToRef<T extends Matrix>(x: number, y: number, z: number, result: T): T {\r\n        Matrix.FromValuesToRef(x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n        result._updateIdentityStatus(x === 1 && y === 1 && z === 1);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a translation matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#109\r\n     * @param x defines the translation on X axis\r\n     * @param y defines the translation on Y axis\r\n     * @param z defines the translationon Z axis\r\n     * @returns the new matrix\r\n     */\r\n    public static Translation(x: number, y: number, z: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.TranslationToRef(x, y, z, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a translation matrix and stores it in a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#110\r\n     * @param x defines the translation on X axis\r\n     * @param y defines the translation on Y axis\r\n     * @param z defines the translationon Z axis\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static TranslationToRef<T extends Matrix>(x: number, y: number, z: number, result: T): T {\r\n        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, x, y, z, 1.0, result);\r\n        result._updateIdentityStatus(x === 0 && y === 0 && z === 0);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Matrix whose values are the interpolated values for \"gradient\" (float) between the ones of the matrices \"startValue\" and \"endValue\".\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#55\r\n     * @param startValue defines the start value\r\n     * @param endValue defines the end value\r\n     * @param gradient defines the gradient factor\r\n     * @returns the new matrix\r\n     */\r\n    public static Lerp(startValue: DeepImmutable<Matrix>, endValue: DeepImmutable<Matrix>, gradient: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.LerpToRef(startValue, endValue, gradient, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Set the given matrix \"result\" as the interpolated values for \"gradient\" (float) between the ones of the matrices \"startValue\" and \"endValue\".\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#54\r\n     * @param startValue defines the start value\r\n     * @param endValue defines the end value\r\n     * @param gradient defines the gradient factor\r\n     * @param result defines the Matrix object where to store data\r\n     * @returns result input\r\n     */\r\n    public static LerpToRef<T extends Matrix>(startValue: DeepImmutable<Matrix>, endValue: DeepImmutable<Matrix>, gradient: number, result: T): T {\r\n        const resultM = result._m;\r\n        const startM = startValue.m;\r\n        const endM = endValue.m;\r\n        for (let index = 0; index < 16; index++) {\r\n            resultM[index] = startM[index] * (1.0 - gradient) + endM[index] * gradient;\r\n        }\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Builds a new matrix whose values are computed by:\r\n     * * decomposing the \"startValue\" and \"endValue\" matrices into their respective scale, rotation and translation matrices\r\n     * * interpolating for \"gradient\" (float) the values between each of these decomposed matrices between the start and the end\r\n     * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#22\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#51\r\n     * @param startValue defines the first matrix\r\n     * @param endValue defines the second matrix\r\n     * @param gradient defines the gradient between the two matrices\r\n     * @returns the new matrix\r\n     */\r\n    public static DecomposeLerp(startValue: DeepImmutable<Matrix>, endValue: DeepImmutable<Matrix>, gradient: number): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Update a matrix to values which are computed by:\r\n     * * decomposing the \"startValue\" and \"endValue\" matrices into their respective scale, rotation and translation matrices\r\n     * * interpolating for \"gradient\" (float) the values between each of these decomposed matrices between the start and the end\r\n     * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#23\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#53\r\n     * @param startValue defines the first matrix\r\n     * @param endValue defines the second matrix\r\n     * @param gradient defines the gradient between the two matrices\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static DecomposeLerpToRef<T extends Matrix>(startValue: DeepImmutable<Matrix>, endValue: DeepImmutable<Matrix>, gradient: number, result: T): T {\r\n        const startScale = MathTmp.Vector3[0];\r\n        const startRotation = MathTmp.Quaternion[0];\r\n        const startTranslation = MathTmp.Vector3[1];\r\n        startValue.decompose(startScale, startRotation, startTranslation);\r\n\r\n        const endScale = MathTmp.Vector3[2];\r\n        const endRotation = MathTmp.Quaternion[1];\r\n        const endTranslation = MathTmp.Vector3[3];\r\n        endValue.decompose(endScale, endRotation, endTranslation);\r\n\r\n        const resultScale = MathTmp.Vector3[4];\r\n        Vector3.LerpToRef(startScale, endScale, gradient, resultScale);\r\n        const resultRotation = MathTmp.Quaternion[2];\r\n        Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);\r\n\r\n        const resultTranslation = MathTmp.Vector3[5];\r\n        Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);\r\n\r\n        Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n     * This function generates a matrix suitable for a left handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#58\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#59\r\n     * @param eye defines the final position of the entity\r\n     * @param target defines where the entity should look at\r\n     * @param up defines the up vector for the entity\r\n     * @returns the new matrix\r\n     */\r\n    public static LookAtLH(eye: DeepImmutable<Vector3>, target: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.LookAtLHToRef(eye, target, up, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n     * This function generates a matrix suitable for a left handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#60\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#61\r\n     * @param eye defines the final position of the entity\r\n     * @param target defines where the entity should look at\r\n     * @param up defines the up vector for the entity\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static LookAtLHToRef(eye: DeepImmutable<Vector3>, target: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>, result: Matrix): Matrix {\r\n        const xAxis = MathTmp.Vector3[0];\r\n        const yAxis = MathTmp.Vector3[1];\r\n        const zAxis = MathTmp.Vector3[2];\r\n\r\n        // Z axis\r\n        target.subtractToRef(eye, zAxis);\r\n        zAxis.normalize();\r\n\r\n        // X axis\r\n        Vector3.CrossToRef(up, zAxis, xAxis);\r\n\r\n        const xSquareLength = xAxis.lengthSquared();\r\n        if (xSquareLength === 0) {\r\n            xAxis.x = 1.0;\r\n        } else {\r\n            xAxis.normalizeFromLength(Math.sqrt(xSquareLength));\r\n        }\r\n\r\n        // Y axis\r\n        Vector3.CrossToRef(zAxis, xAxis, yAxis);\r\n        yAxis.normalize();\r\n\r\n        // Eye angles\r\n        const ex = -Vector3.Dot(xAxis, eye);\r\n        const ey = -Vector3.Dot(yAxis, eye);\r\n        const ez = -Vector3.Dot(zAxis, eye);\r\n\r\n        Matrix.FromValuesToRef(xAxis._x, yAxis._x, zAxis._x, 0.0, xAxis._y, yAxis._y, zAxis._y, 0.0, xAxis._z, yAxis._z, zAxis._z, 0.0, ex, ey, ez, 1.0, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n     * This function generates a matrix suitable for a right handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#62\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#63\r\n     * @param eye defines the final position of the entity\r\n     * @param target defines where the entity should look at\r\n     * @param up defines the up vector for the entity\r\n     * @returns the new matrix\r\n     */\r\n    public static LookAtRH(eye: DeepImmutable<Vector3>, target: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.LookAtRHToRef(eye, target, up, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n     * This function generates a matrix suitable for a right handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#64\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#65\r\n     * @param eye defines the final position of the entity\r\n     * @param target defines where the entity should look at\r\n     * @param up defines the up vector for the entity\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static LookAtRHToRef<T extends Matrix>(eye: DeepImmutable<Vector3>, target: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>, result: T): T {\r\n        const xAxis = MathTmp.Vector3[0];\r\n        const yAxis = MathTmp.Vector3[1];\r\n        const zAxis = MathTmp.Vector3[2];\r\n\r\n        // Z axis\r\n        eye.subtractToRef(target, zAxis);\r\n        zAxis.normalize();\r\n\r\n        // X axis\r\n        Vector3.CrossToRef(up, zAxis, xAxis);\r\n\r\n        const xSquareLength = xAxis.lengthSquared();\r\n        if (xSquareLength === 0) {\r\n            xAxis.x = 1.0;\r\n        } else {\r\n            xAxis.normalizeFromLength(Math.sqrt(xSquareLength));\r\n        }\r\n\r\n        // Y axis\r\n        Vector3.CrossToRef(zAxis, xAxis, yAxis);\r\n        yAxis.normalize();\r\n\r\n        // Eye angles\r\n        const ex = -Vector3.Dot(xAxis, eye);\r\n        const ey = -Vector3.Dot(yAxis, eye);\r\n        const ez = -Vector3.Dot(zAxis, eye);\r\n\r\n        Matrix.FromValuesToRef(xAxis._x, yAxis._x, zAxis._x, 0.0, xAxis._y, yAxis._y, zAxis._y, 0.0, xAxis._z, yAxis._z, zAxis._z, 0.0, ex, ey, ez, 1.0, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n     * This function generates a matrix suitable for a left handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#66\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @returns the new matrix\r\n     */\r\n    public static LookDirectionLH(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.LookDirectionLHToRef(forward, up, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n     * This function generates a matrix suitable for a left handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#67\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static LookDirectionLHToRef<T extends Matrix>(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>, result: T): T {\r\n        const back = MathTmp.Vector3[0];\r\n        back.copyFrom(forward);\r\n        back.scaleInPlace(-1);\r\n        const left = MathTmp.Vector3[1];\r\n        Vector3.CrossToRef(up, back, left);\r\n\r\n        // Generate the rotation matrix.\r\n        Matrix.FromValuesToRef(left._x, left._y, left._z, 0.0, up._x, up._y, up._z, 0.0, back._x, back._y, back._z, 0.0, 0, 0, 0, 1.0, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n     * This function generates a matrix suitable for a right handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#68\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @returns the new matrix\r\n     */\r\n    public static LookDirectionRH(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.LookDirectionRHToRef(forward, up, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n     * This function generates a matrix suitable for a right handed coordinate system\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#69\r\n     * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n     * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static LookDirectionRHToRef<T extends Matrix>(forward: DeepImmutable<Vector3>, up: DeepImmutable<Vector3>, result: T): T {\r\n        const right = MathTmp.Vector3[2];\r\n        Vector3.CrossToRef(up, forward, right);\r\n\r\n        // Generate the rotation matrix.\r\n        Matrix.FromValuesToRef(right._x, right._y, right._z, 0.0, up._x, up._y, up._z, 0.0, forward._x, forward._y, forward._z, 0.0, 0, 0, 0, 1.0, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Create a left-handed orthographic projection matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#70\r\n     * @param width defines the viewport width\r\n     * @param height defines the viewport height\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns a new matrix as a left-handed orthographic projection matrix\r\n     */\r\n    public static OrthoLH(width: number, height: number, znear: number, zfar: number, halfZRange?: boolean): Matrix {\r\n        const matrix = new Matrix();\r\n        Matrix.OrthoLHToRef(width, height, znear, zfar, matrix, halfZRange);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Store a left-handed orthographic projection to a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#71\r\n     * @param width defines the viewport width\r\n     * @param height defines the viewport height\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param result defines the target matrix\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns result input\r\n     */\r\n    public static OrthoLHToRef<T extends Matrix>(width: number, height: number, znear: number, zfar: number, result: T, halfZRange?: boolean): T {\r\n        const n = znear;\r\n        const f = zfar;\r\n\r\n        const a = 2.0 / width;\r\n        const b = 2.0 / height;\r\n        const c = 2.0 / (f - n);\r\n        const d = -(f + n) / (f - n);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 0.0, 0.0, 0.0, d, 1.0, result);\r\n\r\n        if (halfZRange) {\r\n            result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n        }\r\n\r\n        result._updateIdentityStatus(a === 1 && b === 1 && c === 1 && d === 0);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Create a left-handed orthographic projection matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#72\r\n     * @param left defines the viewport left coordinate\r\n     * @param right defines the viewport right coordinate\r\n     * @param bottom defines the viewport bottom coordinate\r\n     * @param top defines the viewport top coordinate\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns a new matrix as a left-handed orthographic projection matrix\r\n     */\r\n    public static OrthoOffCenterLH(left: number, right: number, bottom: number, top: number, znear: number, zfar: number, halfZRange?: boolean): Matrix {\r\n        const matrix = new Matrix();\r\n        Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, matrix, halfZRange);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Stores a left-handed orthographic projection into a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#73\r\n     * @param left defines the viewport left coordinate\r\n     * @param right defines the viewport right coordinate\r\n     * @param bottom defines the viewport bottom coordinate\r\n     * @param top defines the viewport top coordinate\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param result defines the target matrix\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns result input\r\n     */\r\n    public static OrthoOffCenterLHToRef<T extends Matrix>(\r\n        left: number,\r\n        right: number,\r\n        bottom: number,\r\n        top: number,\r\n        znear: number,\r\n        zfar: number,\r\n        result: T,\r\n        halfZRange?: boolean\r\n    ): T {\r\n        const n = znear;\r\n        const f = zfar;\r\n\r\n        const a = 2.0 / (right - left);\r\n        const b = 2.0 / (top - bottom);\r\n        const c = 2.0 / (f - n);\r\n        const d = -(f + n) / (f - n);\r\n        const i0 = (left + right) / (left - right);\r\n        const i1 = (top + bottom) / (bottom - top);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 0.0, i0, i1, d, 1.0, result);\r\n\r\n        if (halfZRange) {\r\n            result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n        }\r\n\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Stores a left-handed oblique projection into a given matrix\r\n     * @param left defines the viewport left coordinate\r\n     * @param right defines the viewport right coordinate\r\n     * @param bottom defines the viewport bottom coordinate\r\n     * @param top defines the viewport top coordinate\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param length Length of the shear\r\n     * @param angle Angle (along X/Y Plane) to apply shear\r\n     * @param distance Distance from shear point\r\n     * @param result defines the target matrix\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns result input\r\n     */\r\n    public static ObliqueOffCenterLHToRef<T extends Matrix>(\r\n        left: number,\r\n        right: number,\r\n        bottom: number,\r\n        top: number,\r\n        znear: number,\r\n        zfar: number,\r\n        length: number,\r\n        angle: number,\r\n        distance: number,\r\n        result: T,\r\n        halfZRange?: boolean\r\n    ): T {\r\n        const a = -length * Math.cos(angle);\r\n        const b = -length * Math.sin(angle);\r\n\r\n        Matrix.TranslationToRef(0, 0, -distance, MathTmp.Matrix[1]);\r\n        Matrix.FromValuesToRef(1, 0, 0, 0, 0, 1, 0, 0, a, b, 1, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);\r\n        MathTmp.Matrix[1].multiplyToRef(MathTmp.Matrix[0], MathTmp.Matrix[0]);\r\n        Matrix.TranslationToRef(0, 0, distance, MathTmp.Matrix[1]);\r\n        MathTmp.Matrix[0].multiplyToRef(MathTmp.Matrix[1], MathTmp.Matrix[0]);\r\n\r\n        Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, result, halfZRange);\r\n        MathTmp.Matrix[0].multiplyToRef(result, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a right-handed orthographic projection matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#76\r\n     * @param left defines the viewport left coordinate\r\n     * @param right defines the viewport right coordinate\r\n     * @param bottom defines the viewport bottom coordinate\r\n     * @param top defines the viewport top coordinate\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns a new matrix as a right-handed orthographic projection matrix\r\n     */\r\n    public static OrthoOffCenterRH(left: number, right: number, bottom: number, top: number, znear: number, zfar: number, halfZRange?: boolean): Matrix {\r\n        const matrix = new Matrix();\r\n        Matrix.OrthoOffCenterRHToRef(left, right, bottom, top, znear, zfar, matrix, halfZRange);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Stores a right-handed orthographic projection into a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#77\r\n     * @param left defines the viewport left coordinate\r\n     * @param right defines the viewport right coordinate\r\n     * @param bottom defines the viewport bottom coordinate\r\n     * @param top defines the viewport top coordinate\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param result defines the target matrix\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns result input\r\n     */\r\n    public static OrthoOffCenterRHToRef<T extends Matrix>(\r\n        left: number,\r\n        right: number,\r\n        bottom: number,\r\n        top: number,\r\n        znear: number,\r\n        zfar: number,\r\n        result: T,\r\n        halfZRange?: boolean\r\n    ): T {\r\n        Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, result, halfZRange);\r\n        result._m[10] *= -1; // No need to call markAsUpdated as previous function already called it and let _isIdentityDirty to true\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Stores a right-handed oblique projection into a given matrix\r\n     * @param left defines the viewport left coordinate\r\n     * @param right defines the viewport right coordinate\r\n     * @param bottom defines the viewport bottom coordinate\r\n     * @param top defines the viewport top coordinate\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param length Length of the shear\r\n     * @param angle Angle (along X/Y Plane) to apply shear\r\n     * @param distance Distance from shear point\r\n     * @param result defines the target matrix\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @returns result input\r\n     */\r\n    public static ObliqueOffCenterRHToRef<T extends Matrix>(\r\n        left: number,\r\n        right: number,\r\n        bottom: number,\r\n        top: number,\r\n        znear: number,\r\n        zfar: number,\r\n        length: number,\r\n        angle: number,\r\n        distance: number,\r\n        result: T,\r\n        halfZRange?: boolean\r\n    ): T {\r\n        const a = length * Math.cos(angle);\r\n        const b = length * Math.sin(angle);\r\n\r\n        Matrix.TranslationToRef(0, 0, distance, MathTmp.Matrix[1]);\r\n        Matrix.FromValuesToRef(1, 0, 0, 0, 0, 1, 0, 0, a, b, 1, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);\r\n        MathTmp.Matrix[1].multiplyToRef(MathTmp.Matrix[0], MathTmp.Matrix[0]);\r\n        Matrix.TranslationToRef(0, 0, -distance, MathTmp.Matrix[1]);\r\n        MathTmp.Matrix[0].multiplyToRef(MathTmp.Matrix[1], MathTmp.Matrix[0]);\r\n\r\n        Matrix.OrthoOffCenterRHToRef(left, right, bottom, top, znear, zfar, result, halfZRange);\r\n        MathTmp.Matrix[0].multiplyToRef(result, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a left-handed perspective projection matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#85\r\n     * @param width defines the viewport width\r\n     * @param height defines the viewport height\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @returns a new matrix as a left-handed perspective projection matrix\r\n     */\r\n    public static PerspectiveLH(width: number, height: number, znear: number, zfar: number, halfZRange?: boolean, projectionPlaneTilt: number = 0): Matrix {\r\n        const matrix = new Matrix();\r\n\r\n        const n = znear;\r\n        const f = zfar;\r\n\r\n        const a = (2.0 * n) / width;\r\n        const b = (2.0 * n) / height;\r\n        const c = (f + n) / (f - n);\r\n        const d = (-2.0 * f * n) / (f - n);\r\n        const rot = Math.tan(projectionPlaneTilt);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, c, 1.0, 0.0, 0.0, d, 0.0, matrix);\r\n\r\n        if (halfZRange) {\r\n            matrix.multiplyToRef(mtxConvertNDCToHalfZRange, matrix);\r\n        }\r\n\r\n        matrix._updateIdentityStatus(false);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Creates a left-handed perspective projection matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#78\r\n     * @param fov defines the horizontal field of view\r\n     * @param aspect defines the aspect ratio\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n     * @returns a new matrix as a left-handed perspective projection matrix\r\n     */\r\n    public static PerspectiveFovLH(\r\n        fov: number,\r\n        aspect: number,\r\n        znear: number,\r\n        zfar: number,\r\n        halfZRange?: boolean,\r\n        projectionPlaneTilt: number = 0,\r\n        reverseDepthBufferMode: boolean = false\r\n    ): Matrix {\r\n        const matrix = new Matrix();\r\n        Matrix.PerspectiveFovLHToRef(fov, aspect, znear, zfar, matrix, true, halfZRange, projectionPlaneTilt, reverseDepthBufferMode);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Stores a left-handed perspective projection into a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#81\r\n     * @param fov defines the horizontal field of view\r\n     * @param aspect defines the aspect ratio\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n     * @param result defines the target matrix\r\n     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n     * @returns result input\r\n     */\r\n    public static PerspectiveFovLHToRef<T extends Matrix>(\r\n        fov: number,\r\n        aspect: number,\r\n        znear: number,\r\n        zfar: number,\r\n        result: T,\r\n        isVerticalFovFixed = true,\r\n        halfZRange?: boolean,\r\n        projectionPlaneTilt: number = 0,\r\n        reverseDepthBufferMode: boolean = false\r\n    ): T {\r\n        const n = znear;\r\n        const f = zfar;\r\n\r\n        const t = 1.0 / Math.tan(fov * 0.5);\r\n        const a = isVerticalFovFixed ? t / aspect : t;\r\n        const b = isVerticalFovFixed ? t : t * aspect;\r\n        const c = reverseDepthBufferMode && n === 0 ? -1 : f !== 0 ? (f + n) / (f - n) : 1;\r\n        const d = reverseDepthBufferMode && n === 0 ? 2 * f : f !== 0 ? (-2.0 * f * n) / (f - n) : -2 * n;\r\n        const rot = Math.tan(projectionPlaneTilt);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, c, 1.0, 0.0, 0.0, d, 0.0, result);\r\n\r\n        if (halfZRange) {\r\n            result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n        }\r\n\r\n        result._updateIdentityStatus(false);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Stores a left-handed perspective projection into a given matrix with depth reversed\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#89\r\n     * @param fov defines the horizontal field of view\r\n     * @param aspect defines the aspect ratio\r\n     * @param znear defines the near clip plane\r\n     * @param zfar not used as infinity is used as far clip\r\n     * @param result defines the target matrix\r\n     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @returns result input\r\n     */\r\n    public static PerspectiveFovReverseLHToRef<T extends Matrix>(\r\n        fov: number,\r\n        aspect: number,\r\n        znear: number,\r\n        zfar: number,\r\n        result: T,\r\n        isVerticalFovFixed = true,\r\n        halfZRange?: boolean,\r\n        projectionPlaneTilt: number = 0\r\n    ): T {\r\n        const t = 1.0 / Math.tan(fov * 0.5);\r\n        const a = isVerticalFovFixed ? t / aspect : t;\r\n        const b = isVerticalFovFixed ? t : t * aspect;\r\n        const rot = Math.tan(projectionPlaneTilt);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, -znear, 1.0, 0.0, 0.0, 1.0, 0.0, result);\r\n        if (halfZRange) {\r\n            result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n        }\r\n        result._updateIdentityStatus(false);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a right-handed perspective projection matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#83\r\n     * @param fov defines the horizontal field of view\r\n     * @param aspect defines the aspect ratio\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n     * @returns a new matrix as a right-handed perspective projection matrix\r\n     */\r\n    public static PerspectiveFovRH(\r\n        fov: number,\r\n        aspect: number,\r\n        znear: number,\r\n        zfar: number,\r\n        halfZRange?: boolean,\r\n        projectionPlaneTilt: number = 0,\r\n        reverseDepthBufferMode: boolean = false\r\n    ): Matrix {\r\n        const matrix = new Matrix();\r\n        Matrix.PerspectiveFovRHToRef(fov, aspect, znear, zfar, matrix, true, halfZRange, projectionPlaneTilt, reverseDepthBufferMode);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Stores a right-handed perspective projection into a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#84\r\n     * @param fov defines the horizontal field of view\r\n     * @param aspect defines the aspect ratio\r\n     * @param znear defines the near clip plane\r\n     * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n     * @param result defines the target matrix\r\n     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n     * @returns result input\r\n     */\r\n    public static PerspectiveFovRHToRef<T extends Matrix>(\r\n        fov: number,\r\n        aspect: number,\r\n        znear: number,\r\n        zfar: number,\r\n        result: T,\r\n        isVerticalFovFixed = true,\r\n        halfZRange?: boolean,\r\n        projectionPlaneTilt: number = 0,\r\n        reverseDepthBufferMode: boolean = false\r\n    ): T {\r\n        //alternatively this could be expressed as:\r\n        //    m = PerspectiveFovLHToRef\r\n        //    m[10] *= -1.0;\r\n        //    m[11] *= -1.0;\r\n\r\n        const n = znear;\r\n        const f = zfar;\r\n\r\n        const t = 1.0 / Math.tan(fov * 0.5);\r\n        const a = isVerticalFovFixed ? t / aspect : t;\r\n        const b = isVerticalFovFixed ? t : t * aspect;\r\n        const c = reverseDepthBufferMode && n === 0 ? 1 : f !== 0 ? -(f + n) / (f - n) : -1;\r\n        const d = reverseDepthBufferMode && n === 0 ? 2 * f : f !== 0 ? (-2 * f * n) / (f - n) : -2 * n;\r\n        const rot = Math.tan(projectionPlaneTilt);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, c, -1.0, 0.0, 0.0, d, 0.0, result);\r\n\r\n        if (halfZRange) {\r\n            result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n        }\r\n\r\n        result._updateIdentityStatus(false);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Stores a right-handed perspective projection into a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#90\r\n     * @param fov defines the horizontal field of view\r\n     * @param aspect defines the aspect ratio\r\n     * @param znear defines the near clip plane\r\n     * @param zfar not used as infinity is used as far clip\r\n     * @param result defines the target matrix\r\n     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n     * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n     * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n     * @returns result input\r\n     */\r\n    public static PerspectiveFovReverseRHToRef<T extends Matrix>(\r\n        fov: number,\r\n        aspect: number,\r\n        znear: number,\r\n        zfar: number,\r\n        result: T,\r\n        isVerticalFovFixed = true,\r\n        halfZRange?: boolean,\r\n        projectionPlaneTilt: number = 0\r\n    ): T {\r\n        const t = 1.0 / Math.tan(fov * 0.5);\r\n        const a = isVerticalFovFixed ? t / aspect : t;\r\n        const b = isVerticalFovFixed ? t : t * aspect;\r\n        const rot = Math.tan(projectionPlaneTilt);\r\n\r\n        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, -znear, -1.0, 0.0, 0.0, -1.0, 0.0, result);\r\n\r\n        if (halfZRange) {\r\n            result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n        }\r\n\r\n        result._updateIdentityStatus(false);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Computes a complete transformation matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#113\r\n     * @param viewport defines the viewport to use\r\n     * @param world defines the world matrix\r\n     * @param view defines the view matrix\r\n     * @param projection defines the projection matrix\r\n     * @param zmin defines the near clip plane\r\n     * @param zmax defines the far clip plane\r\n     * @returns the transformation matrix\r\n     */\r\n    public static GetFinalMatrix(\r\n        viewport: DeepImmutable<Viewport>,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>,\r\n        zmin: number,\r\n        zmax: number\r\n    ): Matrix {\r\n        const cw = viewport.width;\r\n        const ch = viewport.height;\r\n        const cx = viewport.x;\r\n        const cy = viewport.y;\r\n\r\n        const viewportMatrix = Matrix.FromValues(cw / 2.0, 0.0, 0.0, 0.0, 0.0, -ch / 2.0, 0.0, 0.0, 0.0, 0.0, zmax - zmin, 0.0, cx + cw / 2.0, ch / 2.0 + cy, zmin, 1.0);\r\n\r\n        const matrix = new Matrix();\r\n        world.multiplyToRef(view, matrix);\r\n        matrix.multiplyToRef(projection, matrix);\r\n        return matrix.multiplyToRef(viewportMatrix, matrix);\r\n    }\r\n\r\n    /**\r\n     * Extracts a 2x2 matrix from a given matrix and store the result in a Float32Array\r\n     * @param matrix defines the matrix to use\r\n     * @returns a new Float32Array array with 4 elements : the 2x2 matrix extracted from the given matrix\r\n     */\r\n    public static GetAsMatrix2x2(matrix: DeepImmutable<Matrix>): Float32Array | Array<number> {\r\n        const m = matrix.m;\r\n        const arr = [m[0], m[1], m[4], m[5]];\r\n        return PerformanceConfigurator.MatrixUse64Bits ? arr : new Float32Array(arr);\r\n    }\r\n    /**\r\n     * Extracts a 3x3 matrix from a given matrix and store the result in a Float32Array\r\n     * @param matrix defines the matrix to use\r\n     * @returns a new Float32Array array with 9 elements : the 3x3 matrix extracted from the given matrix\r\n     */\r\n    public static GetAsMatrix3x3(matrix: DeepImmutable<Matrix>): Float32Array | Array<number> {\r\n        const m = matrix.m;\r\n        const arr = [m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]];\r\n        return PerformanceConfigurator.MatrixUse64Bits ? arr : new Float32Array(arr);\r\n    }\r\n\r\n    /**\r\n     * Compute the transpose of a given matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#111\r\n     * @param matrix defines the matrix to transpose\r\n     * @returns the new matrix\r\n     */\r\n    public static Transpose(matrix: DeepImmutable<Matrix>): Matrix {\r\n        const result = new Matrix();\r\n        Matrix.TransposeToRef(matrix, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Compute the transpose of a matrix and store it in a target matrix\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#112\r\n     * @param matrix defines the matrix to transpose\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static TransposeToRef<T extends Matrix>(matrix: DeepImmutable<Matrix>, result: T): T {\r\n        const mm = matrix.m;\r\n        const rm0 = mm[0];\r\n        const rm1 = mm[4];\r\n        const rm2 = mm[8];\r\n        const rm3 = mm[12];\r\n\r\n        const rm4 = mm[1];\r\n        const rm5 = mm[5];\r\n        const rm6 = mm[9];\r\n        const rm7 = mm[13];\r\n\r\n        const rm8 = mm[2];\r\n        const rm9 = mm[6];\r\n        const rm10 = mm[10];\r\n        const rm11 = mm[14];\r\n\r\n        const rm12 = mm[3];\r\n        const rm13 = mm[7];\r\n        const rm14 = mm[11];\r\n        const rm15 = mm[15];\r\n\r\n        const rm = result._m;\r\n        rm[0] = rm0;\r\n        rm[1] = rm1;\r\n        rm[2] = rm2;\r\n        rm[3] = rm3;\r\n        rm[4] = rm4;\r\n        rm[5] = rm5;\r\n        rm[6] = rm6;\r\n        rm[7] = rm7;\r\n        rm[8] = rm8;\r\n        rm[9] = rm9;\r\n        rm[10] = rm10;\r\n        rm[11] = rm11;\r\n        rm[12] = rm12;\r\n        rm[13] = rm13;\r\n        rm[14] = rm14;\r\n        rm[15] = rm15;\r\n        result.markAsUpdated();\r\n\r\n        // identity-ness does not change when transposing\r\n        result._updateIdentityStatus((matrix as Matrix)._isIdentity, (matrix as Matrix)._isIdentityDirty);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Computes a reflection matrix from a plane\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#87\r\n     * @param plane defines the reflection plane\r\n     * @returns a new matrix\r\n     */\r\n    public static Reflection(plane: DeepImmutable<IPlaneLike>): Matrix {\r\n        const matrix = new Matrix();\r\n        Matrix.ReflectionToRef(plane, matrix);\r\n        return matrix;\r\n    }\r\n\r\n    /**\r\n     * Computes a reflection matrix from a plane\r\n     * Example Playground - https://playground.babylonjs.com/#AV9X17#88\r\n     * @param plane defines the reflection plane\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static ReflectionToRef<T extends Matrix>(plane: DeepImmutable<IPlaneLike>, result: T): T {\r\n        plane.normalize();\r\n        const x = plane.normal.x;\r\n        const y = plane.normal.y;\r\n        const z = plane.normal.z;\r\n        const temp = -2 * x;\r\n        const temp2 = -2 * y;\r\n        const temp3 = -2 * z;\r\n        Matrix.FromValuesToRef(\r\n            temp * x + 1,\r\n            temp2 * x,\r\n            temp3 * x,\r\n            0.0,\r\n            temp * y,\r\n            temp2 * y + 1,\r\n            temp3 * y,\r\n            0.0,\r\n            temp * z,\r\n            temp2 * z,\r\n            temp3 * z + 1,\r\n            0.0,\r\n            temp * plane.d,\r\n            temp2 * plane.d,\r\n            temp3 * plane.d,\r\n            1.0,\r\n            result\r\n        );\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the given matrix as a rotation matrix composed from the 3 left handed axes\r\n     * @param xaxis defines the value of the 1st axis\r\n     * @param yaxis defines the value of the 2nd axis\r\n     * @param zaxis defines the value of the 3rd axis\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static FromXYZAxesToRef<T extends Matrix>(xaxis: DeepImmutable<Vector3>, yaxis: DeepImmutable<Vector3>, zaxis: DeepImmutable<Vector3>, result: T): T {\r\n        Matrix.FromValuesToRef(xaxis._x, xaxis._y, xaxis._z, 0.0, yaxis._x, yaxis._y, yaxis._z, 0.0, zaxis._x, zaxis._y, zaxis._z, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a rotation matrix from a quaternion and stores it in a target matrix\r\n     * @param quat defines the quaternion to use\r\n     * @param result defines the target matrix\r\n     * @returns result input\r\n     */\r\n    public static FromQuaternionToRef<T extends Matrix>(quat: DeepImmutable<Quaternion>, result: T): T {\r\n        const xx = quat._x * quat._x;\r\n        const yy = quat._y * quat._y;\r\n        const zz = quat._z * quat._z;\r\n        const xy = quat._x * quat._y;\r\n        const zw = quat._z * quat._w;\r\n        const zx = quat._z * quat._x;\r\n        const yw = quat._y * quat._w;\r\n        const yz = quat._y * quat._z;\r\n        const xw = quat._x * quat._w;\r\n\r\n        result._m[0] = 1.0 - 2.0 * (yy + zz);\r\n        result._m[1] = 2.0 * (xy + zw);\r\n        result._m[2] = 2.0 * (zx - yw);\r\n        result._m[3] = 0.0;\r\n\r\n        result._m[4] = 2.0 * (xy - zw);\r\n        result._m[5] = 1.0 - 2.0 * (zz + xx);\r\n        result._m[6] = 2.0 * (yz + xw);\r\n        result._m[7] = 0.0;\r\n\r\n        result._m[8] = 2.0 * (zx + yw);\r\n        result._m[9] = 2.0 * (yz - xw);\r\n        result._m[10] = 1.0 - 2.0 * (yy + xx);\r\n        result._m[11] = 0.0;\r\n\r\n        result._m[12] = 0.0;\r\n        result._m[13] = 0.0;\r\n        result._m[14] = 0.0;\r\n        result._m[15] = 1.0;\r\n\r\n        result.markAsUpdated();\r\n        return result;\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n * Same as Tmp but not exported to keep it only for math functions to avoid conflicts\r\n */\r\nclass MathTmp {\r\n    // Temporary Vector3s\r\n    public static Vector3 = /*#__PURE__*/ BuildTuple(11, Vector3.Zero);\r\n\r\n    // Temporary Matricies\r\n    public static Matrix = /*#__PURE__*/ BuildTuple(2, Matrix.Identity);\r\n\r\n    // Temporary Quaternions\r\n    public static Quaternion = /*#__PURE__*/ BuildTuple(3, Quaternion.Zero);\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class TmpVectors {\r\n    /** 3 temp Vector2 at once should be enough */\r\n    public static Vector2 = /*#__PURE__*/ BuildTuple(3, Vector2.Zero);\r\n\r\n    /** 13 temp Vector3 at once should be enough */\r\n    public static Vector3 = /*#__PURE__*/ BuildTuple(13, Vector3.Zero);\r\n\r\n    /** 3 temp Vector4 at once should be enough */\r\n    public static Vector4 = /*#__PURE__*/ BuildTuple(3, Vector4.Zero);\r\n\r\n    /** 3 temp Quaternion at once should be enough */\r\n    public static Quaternion = /*#__PURE__*/ BuildTuple(3, Quaternion.Zero);\r\n\r\n    /** 8 temp Matrices at once should be enough */\r\n    public static Matrix = /*#__PURE__*/ BuildTuple(8, Matrix.Identity);\r\n}\r\n\r\nconst mtxConvertNDCToHalfZRange = /*#__PURE__*/ Matrix.FromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1);\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mathVector.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMathVector(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperties(Vector2.prototype, {\r\n        dimension: { value: [2] },\r\n        rank: { value: 1 },\r\n    });\r\n\r\n    Object.defineProperties(Vector3.prototype, {\r\n        dimension: { value: [3] },\r\n        rank: { value: 1 },\r\n    });\r\n\r\n    Object.defineProperties(Vector4.prototype, {\r\n        dimension: { value: [4] },\r\n        rank: { value: 1 },\r\n    });\r\n\r\n    Object.defineProperties(Quaternion.prototype, {\r\n        dimension: { value: [4] },\r\n        rank: { value: 1 },\r\n    });\r\n\r\n    Object.defineProperties(Matrix.prototype, {\r\n        dimension: { value: [4, 4] },\r\n        rank: { value: 2 },\r\n    });\r\n\r\n    RegisterClass(\"BABYLON.Vector2\", Vector2);\r\n\r\n    RegisterClass(\"BABYLON.Vector3\", Vector3);\r\n\r\n    RegisterClass(\"BABYLON.Vector4\", Vector4);\r\n\r\n    RegisterClass(\"BABYLON.Matrix\", Matrix);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { BuildArray } from \"../Misc/arrayTools\";\r\nimport { type DeepImmutable, type FloatArray, type Tuple } from \"../types\";\r\nimport { Epsilon, ToGammaSpace, ToLinearSpace } from \"./math.constants\";\r\nimport { type IColor3Like, type IColor4Like } from \"./math.like\";\r\nimport { Clamp, ToHex, WithinEpsilon } from \"./math.scalar.functions\";\r\nimport { type Tensor } from \"./tensor\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nfunction ColorChannelToLinearSpace(color: number): number {\r\n    return Math.pow(color, ToLinearSpace);\r\n}\r\n\r\nfunction ColorChannelToLinearSpaceExact(color: number): number {\r\n    if (color <= 0.04045) {\r\n        return 0.0773993808 * color;\r\n    }\r\n    return Math.pow(0.947867299 * (color + 0.055), 2.4);\r\n}\r\n\r\nfunction ColorChannelToGammaSpace(color: number): number {\r\n    return Math.pow(color, ToGammaSpace);\r\n}\r\n\r\nfunction ColorChannelToGammaSpaceExact(color: number): number {\r\n    if (color <= 0.0031308) {\r\n        return 12.92 * color;\r\n    }\r\n    return 1.055 * Math.pow(color, 0.41666) - 0.055;\r\n}\r\n\r\n/**\r\n * Class used to hold a RGB color\r\n */\r\nexport class Color3 implements Tensor<Tuple<number, 3>, IColor3Like>, IColor3Like {\r\n    /**\r\n     * If the first color is flagged with integers (as everything is 0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n     * If subsequent colors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n     * and henceforth it will use floating-point representation for all color instances that it creates.\r\n     * But the original color instances are unchanged and has a \"deprecated map\".\r\n     * If we keep using the color instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n     */\r\n    static _V8PerformanceHack = /*#__PURE__*/ new Color3(0.5, 0.5, 0.5) as DeepImmutable<Color3>;\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: [3];\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 1;\r\n\r\n    /**\r\n     * Creates a new Color3 object from red, green, blue values, all between 0 and 1\r\n     * @param r defines the red component (between 0 and 1, default is 0)\r\n     * @param g defines the green component (between 0 and 1, default is 0)\r\n     * @param b defines the blue component (between 0 and 1, default is 0)\r\n     */\r\n    constructor(\r\n        /**\r\n         * [0] Defines the red component (between 0 and 1, default is 0)\r\n         */\r\n        public r: number = 0,\r\n        /**\r\n         * [0] Defines the green component (between 0 and 1, default is 0)\r\n         */\r\n        public g: number = 0,\r\n        /**\r\n         * [0] Defines the blue component (between 0 and 1, default is 0)\r\n         */\r\n        public b: number = 0\r\n    ) {}\r\n\r\n    /**\r\n     * Creates a string with the Color3 current values\r\n     * @returns the string representation of the Color3 object\r\n     */\r\n    public toString(): string {\r\n        return \"{R: \" + this.r + \" G:\" + this.g + \" B:\" + this.b + \"}\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"Color3\"\r\n     * @returns \"Color3\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Color3\";\r\n    }\r\n\r\n    /**\r\n     * Compute the Color3 hash code\r\n     * @returns an unique number that can be used to hash Color3 objects\r\n     */\r\n    public getHashCode(): number {\r\n        let hash = (this.r * 255) | 0;\r\n        hash = (hash * 397) ^ ((this.g * 255) | 0);\r\n        hash = (hash * 397) ^ ((this.b * 255) | 0);\r\n        return hash;\r\n    }\r\n\r\n    // Operators\r\n\r\n    /**\r\n     * Stores in the given array from the given starting index the red, green, blue values as successive elements\r\n     * @param array defines the array where to store the r,g,b components\r\n     * @param index defines an optional index in the target array to define where to start storing values\r\n     * @returns the current Color3 object\r\n     */\r\n    public toArray(array: FloatArray, index: number = 0): this {\r\n        array[index] = this.r;\r\n        array[index + 1] = this.g;\r\n        array[index + 2] = this.b;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update the current color with values stored in an array from the starting index of the given array\r\n     * @param array defines the source array\r\n     * @param offset defines an offset in the source array\r\n     * @returns the current Color3 object\r\n     */\r\n    public fromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): this {\r\n        Color3.FromArrayToRef(array, offset, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color4 object from the current Color3 and the given alpha\r\n     * @param alpha defines the alpha component on the new Color4 object (default is 1)\r\n     * @returns a new Color4 object\r\n     */\r\n    public toColor4(alpha: number = 1): Color4 {\r\n        return new Color4(this.r, this.g, this.b, alpha);\r\n    }\r\n\r\n    /**\r\n     * Returns a new array populated with 3 numeric elements : red, green and blue values\r\n     * @returns the new array\r\n     */\r\n    public asArray(): Tuple<number, 3> {\r\n        return [this.r, this.g, this.b];\r\n    }\r\n\r\n    /**\r\n     * Returns the luminance value\r\n     * @returns a float value\r\n     */\r\n    public toLuminance(): number {\r\n        return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;\r\n    }\r\n\r\n    /**\r\n     * Multiply each Color3 rgb values by the given Color3 rgb values in a new Color3 object\r\n     * @param otherColor defines the second operand\r\n     * @returns the new Color3 object\r\n     */\r\n    public multiply(otherColor: DeepImmutable<IColor3Like>): Color3 {\r\n        return new Color3(this.r * otherColor.r, this.g * otherColor.g, this.b * otherColor.b);\r\n    }\r\n\r\n    /**\r\n     * Multiply the rgb values of the Color3 and the given Color3 and stores the result in the object \"result\"\r\n     * @param otherColor defines the second operand\r\n     * @param result defines the Color3 object where to store the result\r\n     * @returns the result Color3\r\n     */\r\n    public multiplyToRef<T extends IColor3Like>(otherColor: DeepImmutable<IColor3Like>, result: T): T {\r\n        result.r = this.r * otherColor.r;\r\n        result.g = this.g * otherColor.g;\r\n        result.b = this.b * otherColor.b;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current Color3 coordinates by the given ones\r\n     * @param otherColor defines the second operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public multiplyInPlace(otherColor: DeepImmutable<IColor3Like>): this {\r\n        this.r *= otherColor.r;\r\n        this.g *= otherColor.g;\r\n        this.b *= otherColor.b;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color3 set with the result of the multiplication of the current Color3 coordinates by the given floats\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @returns the new Color3\r\n     */\r\n    public multiplyByFloats(r: number, g: number, b: number): Color3 {\r\n        return new Color3(this.r * r, this.g * g, this.b * b);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divide(_other: DeepImmutable<IColor3Like>): never {\r\n        throw new ReferenceError(\"Can not divide a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divideToRef(_other: DeepImmutable<IColor3Like>, _result: IColor3Like): never {\r\n        throw new ReferenceError(\"Can not divide a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divideInPlace(_other: DeepImmutable<IColor3Like>): never {\r\n        throw new ReferenceError(\"Can not divide a color\");\r\n    }\r\n\r\n    /**\r\n     * Updates the current Color3 with the minimal coordinate values between its and the given color ones\r\n     * @param other defines the second operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public minimizeInPlace(other: DeepImmutable<IColor3Like>): this {\r\n        return this.minimizeInPlaceFromFloats(other.r, other.g, other.b);\r\n    }\r\n\r\n    /**\r\n     * Updates the current Color3 with the maximal coordinate values between its and the given color ones.\r\n     * @param other defines the second operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public maximizeInPlace(other: DeepImmutable<IColor3Like>): this {\r\n        return this.maximizeInPlaceFromFloats(other.r, other.g, other.b);\r\n    }\r\n\r\n    /**\r\n     * Updates the current Color3 with the minimal coordinate values between its and the given coordinates\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public minimizeInPlaceFromFloats(r: number, g: number, b: number): this {\r\n        this.r = Math.min(r, this.r);\r\n        this.g = Math.min(g, this.g);\r\n        this.b = Math.min(b, this.b);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Color3 with the maximal coordinate values between its and the given coordinates.\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public maximizeInPlaceFromFloats(r: number, g: number, b: number): this {\r\n        this.r = Math.max(r, this.r);\r\n        this.g = Math.max(g, this.g);\r\n        this.b = Math.max(b, this.b);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public floorToRef(_result: IColor3Like): never {\r\n        throw new ReferenceError(\"Can not floor a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public floor(): never {\r\n        throw new ReferenceError(\"Can not floor a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public fractToRef(_result: IColor3Like): never {\r\n        throw new ReferenceError(\"Can not fract a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public fract(): never {\r\n        throw new ReferenceError(\"Can not fract a color\");\r\n    }\r\n\r\n    /**\r\n     * Determines equality between Color3 objects\r\n     * @param otherColor defines the second operand\r\n     * @returns true if the rgb values are equal to the given ones\r\n     */\r\n    public equals(otherColor: DeepImmutable<IColor3Like>): boolean {\r\n        return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b;\r\n    }\r\n\r\n    /**\r\n     * Alias for equalsToFloats\r\n     * @param r red color component\r\n     * @param g green color component\r\n     * @param b blue color component\r\n     * @returns boolean\r\n     */\r\n    public equalsFloats(r: number, g: number, b: number): boolean {\r\n        return this.equalsToFloats(r, g, b);\r\n    }\r\n\r\n    /**\r\n     * Determines equality between the current Color3 object and a set of r,b,g values\r\n     * @param r defines the red component to check\r\n     * @param g defines the green component to check\r\n     * @param b defines the blue component to check\r\n     * @returns true if the rgb values are equal to the given ones\r\n     */\r\n    public equalsToFloats(r: number, g: number, b: number): boolean {\r\n        return this.r === r && this.g === g && this.b === b;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the current Color3 and the given color coordinates are distant less than epsilon\r\n     * @param otherColor defines the second operand\r\n     * @param epsilon defines the minimal distance to define values as equals\r\n     * @returns true if both colors are distant less than epsilon\r\n     */\r\n    public equalsWithEpsilon(otherColor: DeepImmutable<IColor3Like>, epsilon: number = Epsilon): boolean {\r\n        return WithinEpsilon(this.r, otherColor.r, epsilon) && WithinEpsilon(this.g, otherColor.g, epsilon) && WithinEpsilon(this.b, otherColor.b, epsilon);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public negate(): never {\r\n        throw new ReferenceError(\"Can not negate a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public negateInPlace(): never {\r\n        throw new ReferenceError(\"Can not negate a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public negateToRef(_result: IColor3Like): never {\r\n        throw new ReferenceError(\"Can not negate a color\");\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 with the current Color3 values multiplied by scale\r\n     * @param scale defines the scaling factor to apply\r\n     * @returns a new Color3 object\r\n     */\r\n    public scale(scale: number): Color3 {\r\n        return new Color3(this.r * scale, this.g * scale, this.b * scale);\r\n    }\r\n\r\n    /**\r\n     * Multiplies the Color3 values by the float \"scale\"\r\n     * @param scale defines the scaling factor to apply\r\n     * @returns the current updated Color3\r\n     */\r\n    public scaleInPlace(scale: number): this {\r\n        this.r *= scale;\r\n        this.g *= scale;\r\n        this.b *= scale;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the rgb values by scale and stores the result into \"result\"\r\n     * @param scale defines the scaling factor\r\n     * @param result defines the Color3 object where to store the result\r\n     * @returns the result Color3\r\n     */\r\n    public scaleToRef<T extends IColor3Like>(scale: number, result: T): T {\r\n        result.r = this.r * scale;\r\n        result.g = this.g * scale;\r\n        result.b = this.b * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Scale the current Color3 values by a factor and add the result to a given Color3\r\n     * @param scale defines the scale factor\r\n     * @param result defines color to store the result into\r\n     * @returns the result Color3\r\n     */\r\n    public scaleAndAddToRef<T extends IColor3Like>(scale: number, result: T): T {\r\n        result.r += this.r * scale;\r\n        result.g += this.g * scale;\r\n        result.b += this.b * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Clamps the rgb values by the min and max values and stores the result into \"result\"\r\n     * @param min defines minimum clamping value (default is 0)\r\n     * @param max defines maximum clamping value (default is 1)\r\n     * @param result defines color to store the result into\r\n     * @returns the result Color3\r\n     */\r\n    public clampToRef<T extends IColor3Like>(min: number = 0, max: number = 1, result: T): T {\r\n        result.r = Clamp(this.r, min, max);\r\n        result.g = Clamp(this.g, min, max);\r\n        result.b = Clamp(this.b, min, max);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 set with the added values of the current Color3 and of the given one\r\n     * @param otherColor defines the second operand\r\n     * @returns the new Color3\r\n     */\r\n    public add(otherColor: DeepImmutable<IColor3Like>): Color3 {\r\n        return new Color3(this.r + otherColor.r, this.g + otherColor.g, this.b + otherColor.b);\r\n    }\r\n\r\n    /**\r\n     * Adds the given color to the current Color3\r\n     * @param otherColor defines the second operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public addInPlace(otherColor: DeepImmutable<IColor3Like>): this {\r\n        this.r += otherColor.r;\r\n        this.g += otherColor.g;\r\n        this.b += otherColor.b;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the given coordinates to the current Color3\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public addInPlaceFromFloats(r: number, g: number, b: number): this {\r\n        this.r += r;\r\n        this.g += g;\r\n        this.b += b;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Stores the result of the addition of the current Color3 and given one rgb values into \"result\"\r\n     * @param otherColor defines the second operand\r\n     * @param result defines Color3 object to store the result into\r\n     * @returns the unmodified current Color3\r\n     */\r\n    public addToRef<T extends IColor3Like>(otherColor: DeepImmutable<IColor3Like>, result: T): T {\r\n        result.r = this.r + otherColor.r;\r\n        result.g = this.g + otherColor.g;\r\n        result.b = this.b + otherColor.b;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color3 set with the subtracted values of the given one from the current Color3\r\n     * @param otherColor defines the second operand\r\n     * @returns the new Color3\r\n     */\r\n    public subtract(otherColor: DeepImmutable<IColor3Like>): Color3 {\r\n        return new Color3(this.r - otherColor.r, this.g - otherColor.g, this.b - otherColor.b);\r\n    }\r\n\r\n    /**\r\n     * Stores the result of the subtraction of given one from the current Color3 rgb values into \"result\"\r\n     * @param otherColor defines the second operand\r\n     * @param result defines Color3 object to store the result into\r\n     * @returns the unmodified current Color3\r\n     */\r\n    public subtractToRef<T extends IColor3Like>(otherColor: DeepImmutable<IColor3Like>, result: T): T {\r\n        result.r = this.r - otherColor.r;\r\n        result.g = this.g - otherColor.g;\r\n        result.b = this.b - otherColor.b;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Subtract the given color from the current Color3\r\n     * @param otherColor defines the second operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public subtractInPlace(otherColor: DeepImmutable<IColor3Like>): this {\r\n        this.r -= otherColor.r;\r\n        this.g -= otherColor.g;\r\n        this.b -= otherColor.b;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color3 set with the subtraction of the given floats from the current Color3 coordinates\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @returns the resulting Color3\r\n     */\r\n    public subtractFromFloats(r: number, g: number, b: number): Color3 {\r\n        return new Color3(this.r - r, this.g - g, this.b - b);\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current Color3 coordinates and set the given color \"result\" with this result\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @param result defines the Color3 object where to store the result\r\n     * @returns the result\r\n     */\r\n    public subtractFromFloatsToRef<T extends IColor3Like>(r: number, g: number, b: number, result: T): T {\r\n        result.r = this.r - r;\r\n        result.g = this.g - g;\r\n        result.b = this.b - b;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Copy the current object\r\n     * @returns a new Color3 copied the current one\r\n     */\r\n    public clone(): Color3 {\r\n        return new Color3(this.r, this.g, this.b);\r\n    }\r\n\r\n    /**\r\n     * Copies the rgb values from the source in the current Color3\r\n     * @param source defines the source Color3 object\r\n     * @returns the updated Color3 object\r\n     */\r\n    public copyFrom(source: DeepImmutable<IColor3Like>): this {\r\n        this.r = source.r;\r\n        this.g = source.g;\r\n        this.b = source.b;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the Color3 rgb values from the given floats\r\n     * @param r defines the red component to read from\r\n     * @param g defines the green component to read from\r\n     * @param b defines the blue component to read from\r\n     * @returns the current Color3 object\r\n     */\r\n    public copyFromFloats(r: number, g: number, b: number): this {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the Color3 rgb values from the given floats\r\n     * @param r defines the red component to read from\r\n     * @param g defines the green component to read from\r\n     * @param b defines the blue component to read from\r\n     * @returns the current Color3 object\r\n     */\r\n    public set(r: number, g: number, b: number): this {\r\n        return this.copyFromFloats(r, g, b);\r\n    }\r\n\r\n    /**\r\n     * Copies the given float to the current Color3 coordinates\r\n     * @param v defines the r, g and b coordinates of the operand\r\n     * @returns the current updated Color3\r\n     */\r\n    public setAll(v: number): this {\r\n        this.r = this.g = this.b = v;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Compute the Color3 hexadecimal code as a string\r\n     * @returns a string containing the hexadecimal representation of the Color3 object\r\n     */\r\n    public toHexString(): string {\r\n        const intR = Math.round(this.r * 255);\r\n        const intG = Math.round(this.g * 255);\r\n        const intB = Math.round(this.b * 255);\r\n        return \"#\" + ToHex(intR) + ToHex(intG) + ToHex(intB);\r\n    }\r\n\r\n    /**\r\n     * Updates the Color3 rgb values from the string containing valid hexadecimal values\r\n     * @param hex defines a string containing valid hexadecimal values\r\n     * @returns the current Color3 object\r\n     */\r\n    public fromHexString(hex: string): this {\r\n        if (hex.substring(0, 1) !== \"#\" || hex.length !== 7) {\r\n            return this;\r\n        }\r\n\r\n        this.r = parseInt(hex.substring(1, 3), 16) / 255;\r\n        this.g = parseInt(hex.substring(3, 5), 16) / 255;\r\n        this.b = parseInt(hex.substring(5, 7), 16) / 255;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Converts current color in rgb space to HSV values\r\n     * @returns a new color3 representing the HSV values\r\n     */\r\n    public toHSV(): Color3 {\r\n        return this.toHSVToRef(new Color3());\r\n    }\r\n\r\n    /**\r\n     * Converts current color in rgb space to HSV values\r\n     * @param result defines the Color3 where to store the HSV values\r\n     * @returns the updated result\r\n     */\r\n    public toHSVToRef<T extends IColor3Like>(result: T): T {\r\n        const r = this.r;\r\n        const g = this.g;\r\n        const b = this.b;\r\n\r\n        const max = Math.max(r, g, b);\r\n        const min = Math.min(r, g, b);\r\n        let h = 0;\r\n        let s = 0;\r\n        const v = max;\r\n\r\n        const dm = max - min;\r\n\r\n        if (max !== 0) {\r\n            s = dm / max;\r\n        }\r\n\r\n        if (max != min) {\r\n            if (max == r) {\r\n                h = (g - b) / dm;\r\n                if (g < b) {\r\n                    h += 6;\r\n                }\r\n            } else if (max == g) {\r\n                h = (b - r) / dm + 2;\r\n            } else if (max == b) {\r\n                h = (r - g) / dm + 4;\r\n            }\r\n            h *= 60;\r\n        }\r\n\r\n        result.r = h;\r\n        result.g = s;\r\n        result.b = v;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Computes a new Color3 converted from the current one to linear space\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns a new Color3 object\r\n     */\r\n    public toLinearSpace(exact = false): Color3 {\r\n        const convertedColor = new Color3();\r\n        this.toLinearSpaceToRef(convertedColor, exact);\r\n        return convertedColor;\r\n    }\r\n\r\n    /**\r\n     * Converts the Color3 values to linear space and stores the result in \"convertedColor\"\r\n     * @param convertedColor defines the Color3 object where to store the linear space version\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns the unmodified Color3\r\n     */\r\n    public toLinearSpaceToRef(convertedColor: IColor3Like, exact = false): this {\r\n        if (exact) {\r\n            convertedColor.r = ColorChannelToLinearSpaceExact(this.r);\r\n            convertedColor.g = ColorChannelToLinearSpaceExact(this.g);\r\n            convertedColor.b = ColorChannelToLinearSpaceExact(this.b);\r\n        } else {\r\n            convertedColor.r = ColorChannelToLinearSpace(this.r);\r\n            convertedColor.g = ColorChannelToLinearSpace(this.g);\r\n            convertedColor.b = ColorChannelToLinearSpace(this.b);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Computes a new Color3 converted from the current one to gamma space\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns a new Color3 object\r\n     */\r\n    public toGammaSpace(exact = false): Color3 {\r\n        const convertedColor = new Color3();\r\n        this.toGammaSpaceToRef(convertedColor, exact);\r\n        return convertedColor;\r\n    }\r\n\r\n    /**\r\n     * Converts the Color3 values to gamma space and stores the result in \"convertedColor\"\r\n     * @param convertedColor defines the Color3 object where to store the gamma space version\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns the unmodified Color3\r\n     */\r\n    public toGammaSpaceToRef(convertedColor: IColor3Like, exact = false): this {\r\n        if (exact) {\r\n            convertedColor.r = ColorChannelToGammaSpaceExact(this.r);\r\n            convertedColor.g = ColorChannelToGammaSpaceExact(this.g);\r\n            convertedColor.b = ColorChannelToGammaSpaceExact(this.b);\r\n        } else {\r\n            convertedColor.r = ColorChannelToGammaSpace(this.r);\r\n            convertedColor.g = ColorChannelToGammaSpace(this.g);\r\n            convertedColor.b = ColorChannelToGammaSpace(this.b);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    // Statics\r\n\r\n    private static _BlackReadOnly = /*#__PURE__*/ Color3.Black() as DeepImmutable<Color3>;\r\n\r\n    /**\r\n     * Converts Hue, saturation and value to a Color3 (RGB)\r\n     * @param hue defines the hue (value between 0 and 360)\r\n     * @param saturation defines the saturation (value between 0 and 1)\r\n     * @param value defines the value (value between 0 and 1)\r\n     * @param result defines the Color3 where to store the RGB values\r\n     * @returns the updated result\r\n     */\r\n    public static HSVtoRGBToRef<T extends IColor3Like>(hue: number, saturation: number, value: number, result: T): T {\r\n        const chroma = value * saturation;\r\n        const h = hue / 60;\r\n        const x = chroma * (1 - Math.abs((h % 2) - 1));\r\n        let r = 0;\r\n        let g = 0;\r\n        let b = 0;\r\n\r\n        if (h >= 0 && h <= 1) {\r\n            r = chroma;\r\n            g = x;\r\n        } else if (h >= 1 && h <= 2) {\r\n            r = x;\r\n            g = chroma;\r\n        } else if (h >= 2 && h <= 3) {\r\n            g = chroma;\r\n            b = x;\r\n        } else if (h >= 3 && h <= 4) {\r\n            g = x;\r\n            b = chroma;\r\n        } else if (h >= 4 && h <= 5) {\r\n            r = x;\r\n            b = chroma;\r\n        } else if (h >= 5 && h <= 6) {\r\n            r = chroma;\r\n            b = x;\r\n        }\r\n\r\n        const m = value - chroma;\r\n        result.r = r + m;\r\n        result.g = g + m;\r\n        result.b = b + m;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Converts Hue, saturation and value to a new Color3 (RGB)\r\n     * @param hue defines the hue (value between 0 and 360)\r\n     * @param saturation defines the saturation (value between 0 and 1)\r\n     * @param value defines the value (value between 0 and 1)\r\n     * @returns a new Color3 object\r\n     */\r\n    public static FromHSV(hue: number, saturation: number, value: number): Color3 {\r\n        const result = new Color3(0, 0, 0);\r\n        Color3.HSVtoRGBToRef(hue, saturation, value, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 from the string containing valid hexadecimal values\r\n     * @param hex defines a string containing valid hexadecimal values\r\n     * @returns a new Color3 object\r\n     */\r\n    public static FromHexString(hex: string): Color3 {\r\n        return new Color3(0, 0, 0).fromHexString(hex);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 from the starting index of the given array\r\n     * @param array defines the source array\r\n     * @param offset defines an offset in the source array\r\n     * @returns a new Color3 object\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Color3 {\r\n        return new Color3(array[offset], array[offset + 1], array[offset + 2]);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 from the starting index element of the given array\r\n     * @param array defines the source array to read from\r\n     * @param offset defines the offset in the source array\r\n     * @param result defines the target Color3 object\r\n     */\r\n    public static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number = 0, result: Color3) {\r\n        result.r = array[offset];\r\n        result.g = array[offset + 1];\r\n        result.b = array[offset + 2];\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 from integer values (\\< 256)\r\n     * @param r defines the red component to read from (value between 0 and 255)\r\n     * @param g defines the green component to read from (value between 0 and 255)\r\n     * @param b defines the blue component to read from (value between 0 and 255)\r\n     * @returns a new Color3 object\r\n     */\r\n    public static FromInts(r: number, g: number, b: number): Color3 {\r\n        return new Color3(r / 255.0, g / 255.0, b / 255.0);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 with values linearly interpolated of \"amount\" between the start Color3 and the end Color3\r\n     * @param start defines the start Color3 value\r\n     * @param end defines the end Color3 value\r\n     * @param amount defines the gradient value between start and end\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Lerp(start: DeepImmutable<Color3>, end: DeepImmutable<Color3>, amount: number): Color3 {\r\n        const result = new Color3(0.0, 0.0, 0.0);\r\n        Color3.LerpToRef(start, end, amount, result);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 with values linearly interpolated of \"amount\" between the start Color3 and the end Color3\r\n     * @param left defines the start value\r\n     * @param right defines the end value\r\n     * @param amount defines the gradient factor\r\n     * @param result defines the Color3 object where to store the result\r\n     */\r\n    public static LerpToRef(left: DeepImmutable<Color3>, right: DeepImmutable<Color3>, amount: number, result: Color3): void {\r\n        result.r = left.r + (right.r - left.r) * amount;\r\n        result.g = left.g + (right.g - left.g) * amount;\r\n        result.b = left.b + (right.b - left.b) * amount;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color3 located for \"amount\" (float) on the Hermite interpolation spline defined by the vectors \"value1\", \"tangent1\", \"value2\", \"tangent2\"\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent Color3\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent Color3\r\n     * @param amount defines the amount on the interpolation spline (between 0 and 1)\r\n     * @returns the new Color3\r\n     */\r\n    public static Hermite(value1: DeepImmutable<Color3>, tangent1: DeepImmutable<Color3>, value2: DeepImmutable<Color3>, tangent2: DeepImmutable<Color3>, amount: number): Color3 {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n        const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n        const part2 = -2.0 * cubed + 3.0 * squared;\r\n        const part3 = cubed - 2.0 * squared + amount;\r\n        const part4 = cubed - squared;\r\n\r\n        const r = value1.r * part1 + value2.r * part2 + tangent1.r * part3 + tangent2.r * part4;\r\n        const g = value1.g * part1 + value2.g * part2 + tangent1.g * part3 + tangent2.g * part4;\r\n        const b = value1.b * part1 + value2.b * part2 + tangent1.b * part3 + tangent2.b * part4;\r\n        return new Color3(r, g, b);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color3 which is the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @returns 1st derivative\r\n     */\r\n    public static Hermite1stDerivative(\r\n        value1: DeepImmutable<Color3>,\r\n        tangent1: DeepImmutable<Color3>,\r\n        value2: DeepImmutable<Color3>,\r\n        tangent2: DeepImmutable<Color3>,\r\n        time: number\r\n    ): Color3 {\r\n        const result = Color3.Black();\r\n\r\n        this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color3 which is the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @param result define where to store the derivative\r\n     */\r\n    public static Hermite1stDerivativeToRef(\r\n        value1: DeepImmutable<Color3>,\r\n        tangent1: DeepImmutable<Color3>,\r\n        value2: DeepImmutable<Color3>,\r\n        tangent2: DeepImmutable<Color3>,\r\n        time: number,\r\n        result: Color3\r\n    ) {\r\n        const t2 = time * time;\r\n\r\n        result.r = (t2 - time) * 6 * value1.r + (3 * t2 - 4 * time + 1) * tangent1.r + (-t2 + time) * 6 * value2.r + (3 * t2 - 2 * time) * tangent2.r;\r\n        result.g = (t2 - time) * 6 * value1.g + (3 * t2 - 4 * time + 1) * tangent1.g + (-t2 + time) * 6 * value2.g + (3 * t2 - 2 * time) * tangent2.g;\r\n        result.b = (t2 - time) * 6 * value1.b + (3 * t2 - 4 * time + 1) * tangent1.b + (-t2 + time) * 6 * value2.b + (3 * t2 - 2 * time) * tangent2.b;\r\n    }\r\n\r\n    /**\r\n     * Returns a Color3 value containing a red color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Red(): Color3 {\r\n        return new Color3(1, 0, 0);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a green color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Green(): Color3 {\r\n        return new Color3(0, 1, 0);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a blue color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Blue(): Color3 {\r\n        return new Color3(0, 0, 1);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a black color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Black(): Color3 {\r\n        return new Color3(0, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * Gets a Color3 value containing a black color that must not be updated\r\n     */\r\n    public static get BlackReadOnly(): DeepImmutable<Color3> {\r\n        return Color3._BlackReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Returns a Color3 value containing a white color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static White(): Color3 {\r\n        return new Color3(1, 1, 1);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a purple color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Purple(): Color3 {\r\n        return new Color3(0.5, 0, 0.5);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a magenta color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Magenta(): Color3 {\r\n        return new Color3(1, 0, 1);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a yellow color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Yellow(): Color3 {\r\n        return new Color3(1, 1, 0);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a gray color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Gray(): Color3 {\r\n        return new Color3(0.5, 0.5, 0.5);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a teal color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Teal(): Color3 {\r\n        return new Color3(0, 1.0, 1.0);\r\n    }\r\n    /**\r\n     * Returns a Color3 value containing a random color\r\n     * @returns a new Color3 object\r\n     */\r\n    public static Random(): Color3 {\r\n        return new Color3(Math.random(), Math.random(), Math.random());\r\n    }\r\n}\r\n\r\n/**\r\n * Class used to hold a RBGA color\r\n */\r\nexport class Color4 implements Tensor<Tuple<number, 4>, IColor4Like>, IColor4Like {\r\n    /**\r\n     * If the first color is flagged with integers (as everything is 0,0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n     * If subsequent colors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n     * and henceforth it will use floating-point representation for all color instances that it creates.\r\n     * But the original color instances are unchanged and has a \"deprecated map\".\r\n     * If we keep using the color instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n     */\r\n    static _V8PerformanceHack = /*#__PURE__*/ new Color4(0.5, 0.5, 0.5, 0.5) as DeepImmutable<Color4>;\r\n    /**\r\n     * @see Tensor.dimension\r\n     */\r\n    declare public readonly dimension: [4];\r\n\r\n    /**\r\n     * @see Tensor.rank\r\n     */\r\n    declare public readonly rank: 1;\r\n\r\n    /**\r\n     * Creates a new Color4 object from red, green, blue values, all between 0 and 1\r\n     * @param r defines the red component (between 0 and 1, default is 0)\r\n     * @param g defines the green component (between 0 and 1, default is 0)\r\n     * @param b defines the blue component (between 0 and 1, default is 0)\r\n     * @param a defines the alpha component (between 0 and 1, default is 1)\r\n     */\r\n    constructor(\r\n        /**\r\n         * [0] Defines the red component (between 0 and 1, default is 0)\r\n         */\r\n        public r: number = 0,\r\n        /**\r\n         * [0] Defines the green component (between 0 and 1, default is 0)\r\n         */\r\n        public g: number = 0,\r\n        /**\r\n         * [0] Defines the blue component (between 0 and 1, default is 0)\r\n         */\r\n        public b: number = 0,\r\n        /**\r\n         * [1] Defines the alpha component (between 0 and 1, default is 1)\r\n         */\r\n        public a: number = 1\r\n    ) {}\r\n\r\n    // Operators\r\n\r\n    /**\r\n     * Creates a new array populated with 4 numeric elements : red, green, blue, alpha values\r\n     * @returns the new array\r\n     */\r\n    public asArray(): Tuple<number, 4> {\r\n        return [this.r, this.g, this.b, this.a];\r\n    }\r\n\r\n    /**\r\n     * Stores from the starting index in the given array the Color4 successive values\r\n     * @param array defines the array where to store the r,g,b components\r\n     * @param index defines an optional index in the target array to define where to start storing values\r\n     * @returns the current Color4 object\r\n     */\r\n    public toArray(array: FloatArray, index: number = 0): this {\r\n        array[index] = this.r;\r\n        array[index + 1] = this.g;\r\n        array[index + 2] = this.b;\r\n        array[index + 3] = this.a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update the current color with values stored in an array from the starting index of the given array\r\n     * @param array defines the source array\r\n     * @param offset defines an offset in the source array\r\n     * @returns the current Color4 object\r\n     */\r\n    public fromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): this {\r\n        this.r = array[offset];\r\n        this.g = array[offset + 1];\r\n        this.b = array[offset + 2];\r\n        this.a = array[offset + 3];\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Determines equality between Color4 objects\r\n     * @param otherColor defines the second operand\r\n     * @returns true if the rgba values are equal to the given ones\r\n     */\r\n    public equals(otherColor: DeepImmutable<IColor4Like>): boolean {\r\n        return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b && this.a === otherColor.a;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 set with the added values of the current Color4 and of the given one\r\n     * @param otherColor defines the second operand\r\n     * @returns a new Color4 object\r\n     */\r\n    public add(otherColor: DeepImmutable<IColor4Like>): Color4 {\r\n        return new Color4(this.r + otherColor.r, this.g + otherColor.g, this.b + otherColor.b, this.a + otherColor.a);\r\n    }\r\n\r\n    /**\r\n     * Updates the given color \"result\" with the result of the addition of the current Color4 and the given one.\r\n     * @param otherColor the color to add\r\n     * @param result the color to store the result\r\n     * @returns result input\r\n     */\r\n    public addToRef<T extends IColor4Like>(otherColor: DeepImmutable<IColor4Like>, result: T): T {\r\n        result.r = this.r + otherColor.r;\r\n        result.g = this.g + otherColor.g;\r\n        result.b = this.b + otherColor.b;\r\n        result.a = this.a + otherColor.a;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Adds in place the given Color4 values to the current Color4 object\r\n     * @param otherColor defines the second operand\r\n     * @returns the current updated Color4 object\r\n     */\r\n    public addInPlace(otherColor: DeepImmutable<IColor4Like>): this {\r\n        this.r += otherColor.r;\r\n        this.g += otherColor.g;\r\n        this.b += otherColor.b;\r\n        this.a += otherColor.a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the given coordinates to the current Color4\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @param a defines the a coordinate of the operand\r\n     * @returns the current updated Color4\r\n     */\r\n    public addInPlaceFromFloats(r: number, g: number, b: number, a: number): this {\r\n        this.r += r;\r\n        this.g += g;\r\n        this.b += b;\r\n        this.a += a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 set with the subtracted values of the given one from the current Color4\r\n     * @param otherColor defines the second operand\r\n     * @returns a new Color4 object\r\n     */\r\n    public subtract(otherColor: DeepImmutable<IColor4Like>): Color4 {\r\n        return new Color4(this.r - otherColor.r, this.g - otherColor.g, this.b - otherColor.b, this.a - otherColor.a);\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given ones from the current Color4 values and stores the results in \"result\"\r\n     * @param otherColor defines the second operand\r\n     * @param result defines the Color4 object where to store the result\r\n     * @returns the result Color4 object\r\n     */\r\n    public subtractToRef<T extends IColor4Like>(otherColor: DeepImmutable<IColor4Like>, result: T): T {\r\n        result.r = this.r - otherColor.r;\r\n        result.g = this.g - otherColor.g;\r\n        result.b = this.b - otherColor.b;\r\n        result.a = this.a - otherColor.a;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Subtract in place the given color from the current Color4.\r\n     * @param otherColor the color to subtract\r\n     * @returns the updated Color4.\r\n     */\r\n    public subtractInPlace(otherColor: DeepImmutable<IColor4Like>): this {\r\n        this.r -= otherColor.r;\r\n        this.g -= otherColor.g;\r\n        this.b -= otherColor.b;\r\n        this.a -= otherColor.a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color4 set with the result of the subtraction of the given floats from the current Color4 coordinates.\r\n     * @param r value to subtract\r\n     * @param g value to subtract\r\n     * @param b value to subtract\r\n     * @param a value to subtract\r\n     * @returns new color containing the result\r\n     */\r\n    public subtractFromFloats(r: number, g: number, b: number, a: number): Color4 {\r\n        return new Color4(this.r - r, this.g - g, this.b - b, this.a - a);\r\n    }\r\n\r\n    /**\r\n     * Sets the given color \"result\" set with the result of the subtraction of the given floats from the current Color4 coordinates.\r\n     * @param r value to subtract\r\n     * @param g value to subtract\r\n     * @param b value to subtract\r\n     * @param a value to subtract\r\n     * @param result the color to store the result in\r\n     * @returns result input\r\n     */\r\n    public subtractFromFloatsToRef<T extends IColor4Like>(r: number, g: number, b: number, a: number, result: T): T {\r\n        result.r = this.r - r;\r\n        result.g = this.g - g;\r\n        result.b = this.b - b;\r\n        result.a = this.a - a;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 with the current Color4 values multiplied by scale\r\n     * @param scale defines the scaling factor to apply\r\n     * @returns a new Color4 object\r\n     */\r\n    public scale(scale: number): Color4 {\r\n        return new Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale);\r\n    }\r\n\r\n    /**\r\n     * Multiplies the Color4 values by the float \"scale\"\r\n     * @param scale defines the scaling factor to apply\r\n     * @returns the current updated Color4\r\n     */\r\n    public scaleInPlace(scale: number): this {\r\n        this.r *= scale;\r\n        this.g *= scale;\r\n        this.b *= scale;\r\n        this.a *= scale;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the current Color4 values by scale and stores the result in \"result\"\r\n     * @param scale defines the scaling factor to apply\r\n     * @param result defines the Color4 object where to store the result\r\n     * @returns the result Color4\r\n     */\r\n    public scaleToRef<T extends IColor4Like>(scale: number, result: T): T {\r\n        result.r = this.r * scale;\r\n        result.g = this.g * scale;\r\n        result.b = this.b * scale;\r\n        result.a = this.a * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Scale the current Color4 values by a factor and add the result to a given Color4\r\n     * @param scale defines the scale factor\r\n     * @param result defines the Color4 object where to store the result\r\n     * @returns the result Color4\r\n     */\r\n    public scaleAndAddToRef<T extends IColor4Like>(scale: number, result: T): T {\r\n        result.r += this.r * scale;\r\n        result.g += this.g * scale;\r\n        result.b += this.b * scale;\r\n        result.a += this.a * scale;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Clamps the rgb values by the min and max values and stores the result into \"result\"\r\n     * @param min defines minimum clamping value (default is 0)\r\n     * @param max defines maximum clamping value (default is 1)\r\n     * @param result defines color to store the result into.\r\n     * @returns the result Color4\r\n     */\r\n    public clampToRef<T extends IColor4Like>(min: number = 0, max: number = 1, result: T): T {\r\n        result.r = Clamp(this.r, min, max);\r\n        result.g = Clamp(this.g, min, max);\r\n        result.b = Clamp(this.b, min, max);\r\n        result.a = Clamp(this.a, min, max);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiply an Color4 value by another and return a new Color4 object\r\n     * @param color defines the Color4 value to multiply by\r\n     * @returns a new Color4 object\r\n     */\r\n    public multiply(color: DeepImmutable<IColor4Like>): Color4 {\r\n        return new Color4(this.r * color.r, this.g * color.g, this.b * color.b, this.a * color.a);\r\n    }\r\n\r\n    /**\r\n     * Multiply a Color4 value by another and push the result in a reference value\r\n     * @param color defines the Color4 value to multiply by\r\n     * @param result defines the Color4 to fill the result in\r\n     * @returns the result Color4\r\n     */\r\n    public multiplyToRef<T extends IColor4Like>(color: DeepImmutable<IColor4Like>, result: T): T {\r\n        result.r = this.r * color.r;\r\n        result.g = this.g * color.g;\r\n        result.b = this.b * color.b;\r\n        result.a = this.a * color.a;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Multiplies in place the current Color4 by the given one.\r\n     * @param otherColor color to multiple with\r\n     * @returns the updated Color4.\r\n     */\r\n    public multiplyInPlace(otherColor: DeepImmutable<IColor4Like>): this {\r\n        this.r *= otherColor.r;\r\n        this.g *= otherColor.g;\r\n        this.b *= otherColor.b;\r\n        this.a *= otherColor.a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color4 set with the multiplication result of the given floats and the current Color4 coordinates.\r\n     * @param r value multiply with\r\n     * @param g value multiply with\r\n     * @param b value multiply with\r\n     * @param a value multiply with\r\n     * @returns resulting new color\r\n     */\r\n    public multiplyByFloats(r: number, g: number, b: number, a: number): Color4 {\r\n        return new Color4(this.r * r, this.g * g, this.b * b, this.a * a);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divide(_other: DeepImmutable<IColor4Like>): never {\r\n        throw new ReferenceError(\"Can not divide a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divideToRef(_other: DeepImmutable<IColor4Like>, _result: IColor4Like): never {\r\n        throw new ReferenceError(\"Can not divide a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public divideInPlace(_other: DeepImmutable<IColor4Like>): never {\r\n        throw new ReferenceError(\"Can not divide a color\");\r\n    }\r\n\r\n    /**\r\n     * Updates the Color4 coordinates with the minimum values between its own and the given color ones\r\n     * @param other defines the second operand\r\n     * @returns the current updated Color4\r\n     */\r\n    public minimizeInPlace(other: DeepImmutable<IColor4Like>): this {\r\n        this.r = Math.min(this.r, other.r);\r\n        this.g = Math.min(this.g, other.g);\r\n        this.b = Math.min(this.b, other.b);\r\n        this.a = Math.min(this.a, other.a);\r\n        return this;\r\n    }\r\n    /**\r\n     * Updates the Color4 coordinates with the maximum values between its own and the given color ones\r\n     * @param other defines the second operand\r\n     * @returns the current updated Color4\r\n     */\r\n    public maximizeInPlace(other: DeepImmutable<IColor4Like>): this {\r\n        this.r = Math.max(this.r, other.r);\r\n        this.g = Math.max(this.g, other.g);\r\n        this.b = Math.max(this.b, other.b);\r\n        this.a = Math.max(this.a, other.a);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Color4 with the minimal coordinate values between its and the given coordinates\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @param a defines the a coordinate of the operand\r\n     * @returns the current updated Color4\r\n     */\r\n    public minimizeInPlaceFromFloats(r: number, g: number, b: number, a: number): this {\r\n        this.r = Math.min(r, this.r);\r\n        this.g = Math.min(g, this.g);\r\n        this.b = Math.min(b, this.b);\r\n        this.a = Math.min(a, this.a);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Color4 with the maximal coordinate values between its and the given coordinates.\r\n     * @param r defines the r coordinate of the operand\r\n     * @param g defines the g coordinate of the operand\r\n     * @param b defines the b coordinate of the operand\r\n     * @param a defines the a coordinate of the operand\r\n     * @returns the current updated Color4\r\n     */\r\n    public maximizeInPlaceFromFloats(r: number, g: number, b: number, a: number): this {\r\n        this.r = Math.max(r, this.r);\r\n        this.g = Math.max(g, this.g);\r\n        this.b = Math.max(b, this.b);\r\n        this.a = Math.max(a, this.a);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public floorToRef(_result: IColor4Like): never {\r\n        throw new ReferenceError(\"Can not floor a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public floor(): never {\r\n        throw new ReferenceError(\"Can not floor a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public fractToRef(_result: IColor4Like): never {\r\n        throw new ReferenceError(\"Can not fract a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public fract(): never {\r\n        throw new ReferenceError(\"Can not fract a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public negate(): never {\r\n        throw new ReferenceError(\"Can not negate a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public negateInPlace(): never {\r\n        throw new ReferenceError(\"Can not negate a color\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Do not use\r\n     */\r\n    public negateToRef(_result: IColor4Like): never {\r\n        throw new ReferenceError(\"Can not negate a color\");\r\n    }\r\n\r\n    /**\r\n     * Boolean : True if the current Color4 coordinates are each beneath the distance \"epsilon\" from the given color ones.\r\n     * @param otherColor color to compare against\r\n     * @param epsilon (Default: very small number)\r\n     * @returns true if they are equal\r\n     */\r\n    public equalsWithEpsilon(otherColor: DeepImmutable<IColor4Like>, epsilon: number = Epsilon): boolean {\r\n        return (\r\n            WithinEpsilon(this.r, otherColor.r, epsilon) &&\r\n            WithinEpsilon(this.g, otherColor.g, epsilon) &&\r\n            WithinEpsilon(this.b, otherColor.b, epsilon) &&\r\n            WithinEpsilon(this.a, otherColor.a, epsilon)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Boolean : True if the given floats are strictly equal to the current Color4 coordinates.\r\n     * @param x x value to compare against\r\n     * @param y y value to compare against\r\n     * @param z z value to compare against\r\n     * @param w w value to compare against\r\n     * @returns true if equal\r\n     */\r\n    public equalsToFloats(x: number, y: number, z: number, w: number): boolean {\r\n        return this.r === x && this.g === y && this.b === z && this.a === w;\r\n    }\r\n\r\n    /**\r\n     * Creates a string with the Color4 current values\r\n     * @returns the string representation of the Color4 object\r\n     */\r\n    public toString(): string {\r\n        return \"{R: \" + this.r + \" G:\" + this.g + \" B:\" + this.b + \" A:\" + this.a + \"}\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"Color4\"\r\n     * @returns \"Color4\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Color4\";\r\n    }\r\n\r\n    /**\r\n     * Compute the Color4 hash code\r\n     * @returns an unique number that can be used to hash Color4 objects\r\n     */\r\n    public getHashCode(): number {\r\n        let hash = (this.r * 255) | 0;\r\n        hash = (hash * 397) ^ ((this.g * 255) | 0);\r\n        hash = (hash * 397) ^ ((this.b * 255) | 0);\r\n        hash = (hash * 397) ^ ((this.a * 255) | 0);\r\n        return hash;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 copied from the current one\r\n     * @returns a new Color4 object\r\n     */\r\n    public clone(): Color4 {\r\n        const result = new Color4();\r\n        return result.copyFrom(this);\r\n    }\r\n\r\n    /**\r\n     * Copies the given Color4 values into the current one\r\n     * @param source defines the source Color4 object\r\n     * @returns the current updated Color4 object\r\n     */\r\n    public copyFrom(source: DeepImmutable<IColor4Like>): this {\r\n        this.r = source.r;\r\n        this.g = source.g;\r\n        this.b = source.b;\r\n        this.a = source.a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copies the given float values into the current one\r\n     * @param r defines the red component to read from\r\n     * @param g defines the green component to read from\r\n     * @param b defines the blue component to read from\r\n     * @param a defines the alpha component to read from\r\n     * @returns the current updated Color4 object\r\n     */\r\n    public copyFromFloats(r: number, g: number, b: number, a: number): this {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n        this.a = a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copies the given float values into the current one\r\n     * @param r defines the red component to read from\r\n     * @param g defines the green component to read from\r\n     * @param b defines the blue component to read from\r\n     * @param a defines the alpha component to read from\r\n     * @returns the current updated Color4 object\r\n     */\r\n    public set(r: number, g: number, b: number, a: number): this {\r\n        return this.copyFromFloats(r, g, b, a);\r\n    }\r\n\r\n    /**\r\n     * Copies the given float to the current Vector4 coordinates\r\n     * @param v defines the r, g, b, and a coordinates of the operand\r\n     * @returns the current updated Vector4\r\n     */\r\n    public setAll(v: number): this {\r\n        this.r = this.g = this.b = this.a = v;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Compute the Color4 hexadecimal code as a string\r\n     * @param returnAsColor3 defines if the string should only contains RGB values (off by default)\r\n     * @returns a string containing the hexadecimal representation of the Color4 object\r\n     */\r\n    public toHexString(returnAsColor3 = false): string {\r\n        const intR = Math.round(this.r * 255);\r\n        const intG = Math.round(this.g * 255);\r\n        const intB = Math.round(this.b * 255);\r\n\r\n        if (returnAsColor3) {\r\n            return \"#\" + ToHex(intR) + ToHex(intG) + ToHex(intB);\r\n        }\r\n\r\n        const intA = Math.round(this.a * 255);\r\n        return \"#\" + ToHex(intR) + ToHex(intG) + ToHex(intB) + ToHex(intA);\r\n    }\r\n\r\n    /**\r\n     * Updates the Color4 rgba values from the string containing valid hexadecimal values.\r\n     *\r\n     * A valid hex string is either in the format #RRGGBB or #RRGGBBAA.\r\n     *\r\n     * When a hex string without alpha is passed, the resulting Color4 keeps\r\n     * its previous alpha value.\r\n     *\r\n     * An invalid string does not modify this object\r\n     *\r\n     * @param hex defines a string containing valid hexadecimal values\r\n     * @returns the current updated Color4 object\r\n     */\r\n    public fromHexString(hex: string): this {\r\n        if (hex.substring(0, 1) !== \"#\" || (hex.length !== 9 && hex.length !== 7)) {\r\n            return this;\r\n        }\r\n\r\n        this.r = parseInt(hex.substring(1, 3), 16) / 255;\r\n        this.g = parseInt(hex.substring(3, 5), 16) / 255;\r\n        this.b = parseInt(hex.substring(5, 7), 16) / 255;\r\n        if (hex.length === 9) {\r\n            this.a = parseInt(hex.substring(7, 9), 16) / 255;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Computes a new Color4 converted from the current one to linear space\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns a new Color4 object\r\n     */\r\n    public toLinearSpace(exact = false): Color4 {\r\n        const convertedColor = new Color4();\r\n        this.toLinearSpaceToRef(convertedColor, exact);\r\n        return convertedColor;\r\n    }\r\n\r\n    /**\r\n     * Converts the Color4 values to linear space and stores the result in \"convertedColor\"\r\n     * @param convertedColor defines the Color4 object where to store the linear space version\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns the unmodified Color4\r\n     */\r\n    public toLinearSpaceToRef(convertedColor: IColor4Like, exact = false): this {\r\n        if (exact) {\r\n            convertedColor.r = ColorChannelToLinearSpaceExact(this.r);\r\n            convertedColor.g = ColorChannelToLinearSpaceExact(this.g);\r\n            convertedColor.b = ColorChannelToLinearSpaceExact(this.b);\r\n        } else {\r\n            convertedColor.r = ColorChannelToLinearSpace(this.r);\r\n            convertedColor.g = ColorChannelToLinearSpace(this.g);\r\n            convertedColor.b = ColorChannelToLinearSpace(this.b);\r\n        }\r\n        convertedColor.a = this.a;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Computes a new Color4 converted from the current one to gamma space\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns a new Color4 object\r\n     */\r\n    public toGammaSpace(exact = false): Color4 {\r\n        const convertedColor = new Color4();\r\n        this.toGammaSpaceToRef(convertedColor, exact);\r\n        return convertedColor;\r\n    }\r\n\r\n    /**\r\n     * Converts the Color4 values to gamma space and stores the result in \"convertedColor\"\r\n     * @param convertedColor defines the Color4 object where to store the gamma space version\r\n     * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n     * @returns the unmodified Color4\r\n     */\r\n    public toGammaSpaceToRef(convertedColor: IColor4Like, exact = false): this {\r\n        if (exact) {\r\n            convertedColor.r = ColorChannelToGammaSpaceExact(this.r);\r\n            convertedColor.g = ColorChannelToGammaSpaceExact(this.g);\r\n            convertedColor.b = ColorChannelToGammaSpaceExact(this.b);\r\n        } else {\r\n            convertedColor.r = ColorChannelToGammaSpace(this.r);\r\n            convertedColor.g = ColorChannelToGammaSpace(this.g);\r\n            convertedColor.b = ColorChannelToGammaSpace(this.b);\r\n        }\r\n        convertedColor.a = this.a;\r\n        return this;\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Creates a new Color4 from the string containing valid hexadecimal values.\r\n     *\r\n     * A valid hex string is either in the format #RRGGBB or #RRGGBBAA.\r\n     *\r\n     * When a hex string without alpha is passed, the resulting Color4 has\r\n     * its alpha value set to 1.0.\r\n     *\r\n     * An invalid string results in a Color with all its channels set to 0.0,\r\n     * i.e. \"transparent black\".\r\n     *\r\n     * @param hex defines a string containing valid hexadecimal values\r\n     * @returns a new Color4 object\r\n     */\r\n    public static FromHexString(hex: string): Color4 {\r\n        if (hex.substring(0, 1) !== \"#\" || (hex.length !== 9 && hex.length !== 7)) {\r\n            return new Color4(0.0, 0.0, 0.0, 0.0);\r\n        }\r\n\r\n        return new Color4(0.0, 0.0, 0.0, 1.0).fromHexString(hex);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 object set with the linearly interpolated values of \"amount\" between the left Color4 object and the right Color4 object\r\n     * @param left defines the start value\r\n     * @param right defines the end value\r\n     * @param amount defines the gradient factor\r\n     * @returns a new Color4 object\r\n     */\r\n    public static Lerp(left: DeepImmutable<IColor4Like>, right: DeepImmutable<IColor4Like>, amount: number): Color4 {\r\n        return Color4.LerpToRef(left, right, amount, new Color4());\r\n    }\r\n\r\n    /**\r\n     * Set the given \"result\" with the linearly interpolated values of \"amount\" between the left Color4 object and the right Color4 object\r\n     * @param left defines the start value\r\n     * @param right defines the end value\r\n     * @param amount defines the gradient factor\r\n     * @param result defines the Color4 object where to store data\r\n     * @returns the updated result\r\n     */\r\n    public static LerpToRef<T extends IColor4Like>(left: DeepImmutable<IColor4Like>, right: DeepImmutable<IColor4Like>, amount: number, result: T): T {\r\n        result.r = left.r + (right.r - left.r) * amount;\r\n        result.g = left.g + (right.g - left.g) * amount;\r\n        result.b = left.b + (right.b - left.b) * amount;\r\n        result.a = left.a + (right.a - left.a) * amount;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Interpolate between two Color4 using Hermite interpolation\r\n     * @param value1 defines first Color4\r\n     * @param tangent1 defines the incoming tangent\r\n     * @param value2 defines second Color4\r\n     * @param tangent2 defines the outgoing tangent\r\n     * @param amount defines the target Color4\r\n     * @returns the new interpolated Color4\r\n     */\r\n    public static Hermite(\r\n        value1: DeepImmutable<IColor4Like>,\r\n        tangent1: DeepImmutable<IColor4Like>,\r\n        value2: DeepImmutable<IColor4Like>,\r\n        tangent2: DeepImmutable<IColor4Like>,\r\n        amount: number\r\n    ): Color4 {\r\n        const squared = amount * amount;\r\n        const cubed = amount * squared;\r\n        const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n        const part2 = -2.0 * cubed + 3.0 * squared;\r\n        const part3 = cubed - 2.0 * squared + amount;\r\n        const part4 = cubed - squared;\r\n\r\n        const r = value1.r * part1 + value2.r * part2 + tangent1.r * part3 + tangent2.r * part4;\r\n        const g = value1.g * part1 + value2.g * part2 + tangent1.g * part3 + tangent2.g * part4;\r\n        const b = value1.b * part1 + value2.b * part2 + tangent1.b * part3 + tangent2.b * part4;\r\n        const a = value1.a * part1 + value2.a * part2 + tangent1.a * part3 + tangent2.a * part4;\r\n        return new Color4(r, g, b, a);\r\n    }\r\n\r\n    /**\r\n     * Returns a new Color4 which is the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @returns 1st derivative\r\n     */\r\n    public static Hermite1stDerivative(\r\n        value1: DeepImmutable<IColor4Like>,\r\n        tangent1: DeepImmutable<IColor4Like>,\r\n        value2: DeepImmutable<IColor4Like>,\r\n        tangent2: DeepImmutable<IColor4Like>,\r\n        time: number\r\n    ): Color4 {\r\n        const result = new Color4();\r\n\r\n        this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Update a Color4 with the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n     * @param value1 defines the first control point\r\n     * @param tangent1 defines the first tangent\r\n     * @param value2 defines the second control point\r\n     * @param tangent2 defines the second tangent\r\n     * @param time define where the derivative must be done\r\n     * @param result define where to store the derivative\r\n     */\r\n    public static Hermite1stDerivativeToRef(\r\n        value1: DeepImmutable<IColor4Like>,\r\n        tangent1: DeepImmutable<IColor4Like>,\r\n        value2: DeepImmutable<IColor4Like>,\r\n        tangent2: DeepImmutable<IColor4Like>,\r\n        time: number,\r\n        result: IColor4Like\r\n    ) {\r\n        const t2 = time * time;\r\n\r\n        result.r = (t2 - time) * 6 * value1.r + (3 * t2 - 4 * time + 1) * tangent1.r + (-t2 + time) * 6 * value2.r + (3 * t2 - 2 * time) * tangent2.r;\r\n        result.g = (t2 - time) * 6 * value1.g + (3 * t2 - 4 * time + 1) * tangent1.g + (-t2 + time) * 6 * value2.g + (3 * t2 - 2 * time) * tangent2.g;\r\n        result.b = (t2 - time) * 6 * value1.b + (3 * t2 - 4 * time + 1) * tangent1.b + (-t2 + time) * 6 * value2.b + (3 * t2 - 2 * time) * tangent2.b;\r\n        result.a = (t2 - time) * 6 * value1.a + (3 * t2 - 4 * time + 1) * tangent1.a + (-t2 + time) * 6 * value2.a + (3 * t2 - 2 * time) * tangent2.a;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 from a Color3 and an alpha value\r\n     * @param color3 defines the source Color3 to read from\r\n     * @param alpha defines the alpha component (1.0 by default)\r\n     * @returns a new Color4 object\r\n     */\r\n    public static FromColor3(color3: DeepImmutable<IColor3Like>, alpha: number = 1.0): Color4 {\r\n        return new Color4(color3.r, color3.g, color3.b, alpha);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 from the starting index element of the given array\r\n     * @param array defines the source array to read from\r\n     * @param offset defines the offset in the source array\r\n     * @returns a new Color4 object\r\n     */\r\n    public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Color4 {\r\n        return new Color4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color4 from the starting index element of the given array\r\n     * @param array defines the source array to read from\r\n     * @param offset defines the offset in the source array\r\n     * @param result defines the target Color4 object\r\n     */\r\n    public static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number = 0, result: Color4) {\r\n        result.r = array[offset];\r\n        result.g = array[offset + 1];\r\n        result.b = array[offset + 2];\r\n        result.a = array[offset + 3];\r\n    }\r\n\r\n    /**\r\n     * Creates a new Color3 from integer values (less than 256)\r\n     * @param r defines the red component to read from (value between 0 and 255)\r\n     * @param g defines the green component to read from (value between 0 and 255)\r\n     * @param b defines the blue component to read from (value between 0 and 255)\r\n     * @param a defines the alpha component to read from (value between 0 and 255)\r\n     * @returns a new Color3 object\r\n     */\r\n    public static FromInts(r: number, g: number, b: number, a: number): Color4 {\r\n        return new Color4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);\r\n    }\r\n\r\n    /**\r\n     * Check the content of a given array and convert it to an array containing RGBA data\r\n     * If the original array was already containing count * 4 values then it is returned directly\r\n     * @param colors defines the array to check\r\n     * @param count defines the number of RGBA data to expect\r\n     * @returns an array containing count * 4 values (RGBA)\r\n     */\r\n    public static CheckColors4(colors: number[], count: number): number[] {\r\n        // Check if color3 was used\r\n        if (colors.length === count * 3) {\r\n            const colors4 = [];\r\n            for (let index = 0; index < colors.length; index += 3) {\r\n                const newIndex = (index / 3) * 4;\r\n                colors4[newIndex] = colors[index];\r\n                colors4[newIndex + 1] = colors[index + 1];\r\n                colors4[newIndex + 2] = colors[index + 2];\r\n                colors4[newIndex + 3] = 1.0;\r\n            }\r\n\r\n            return colors4;\r\n        }\r\n\r\n        return colors;\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class TmpColors {\r\n    public static Color3: Color3[] = /*#__PURE__*/ BuildArray(3, Color3.Black);\r\n    public static Color4: Color4[] = /*#__PURE__*/ BuildArray(3, () => new Color4(0, 0, 0, 0));\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mathColor.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMathColor(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperties(Color3.prototype, {\r\n        dimension: { value: [3] },\r\n        rank: { value: 1 },\r\n    });\r\n\r\n    Object.defineProperties(Color4.prototype, {\r\n        dimension: { value: [4] },\r\n        rank: { value: 1 },\r\n    });\r\n\r\n    RegisterClass(\"BABYLON.Color3\", Color3);\r\n\r\n    RegisterClass(\"BABYLON.Color4\", Color4);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { Vector2, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Condition } from \"./condition.pure\";\r\nimport { type AbstractActionManager } from \"./abstractActionManager\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type ActionManager } from \"./actionManager\";\r\nimport { type ActionEvent } from \"./actionEvent\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Interface used to define Action\r\n */\r\nexport interface IAction {\r\n    /**\r\n     * Trigger for the action\r\n     */\r\n    trigger: number;\r\n\r\n    /** Options of the trigger */\r\n    triggerOptions: any;\r\n\r\n    /**\r\n     * Gets the trigger parameters\r\n     * @returns the trigger parameters\r\n     */\r\n    getTriggerParameter(): any;\r\n\r\n    /**\r\n     * Internal only - executes current action event\r\n     * @internal\r\n     */\r\n    _executeCurrent(evt?: ActionEvent): void;\r\n\r\n    /**\r\n     * Serialize placeholder for child classes\r\n     * @param parent of child\r\n     * @returns the serialized object\r\n     */\r\n    serialize(parent: any): any;\r\n\r\n    /**\r\n     * Internal only\r\n     * @internal\r\n     */\r\n    _prepare(): void;\r\n\r\n    /**\r\n     * Internal only - manager for action\r\n     * @internal\r\n     */\r\n    _actionManager: Nullable<AbstractActionManager>;\r\n\r\n    /**\r\n     * Adds action to chain of actions, may be a DoNothingAction\r\n     * @param action defines the next action to execute\r\n     * @returns The action passed in\r\n     * @see https://www.babylonjs-playground.com/#1T30HR#0\r\n     */\r\n    then(action: IAction): IAction;\r\n\r\n    /**\r\n     * Internal only - Returns if the current condition allows to run the action\r\n     * @internal\r\n     */\r\n    _evaluateConditionForCurrentFrame(): boolean;\r\n}\r\n\r\n/**\r\n * The action to be carried out following a trigger\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#available-actions\r\n */\r\nexport class Action implements IAction {\r\n    /**\r\n     * Trigger for the action\r\n     */\r\n    public trigger: number;\r\n\r\n    /**\r\n     * Internal only - manager for action\r\n     * @internal\r\n     */\r\n    public _actionManager: ActionManager;\r\n\r\n    private _nextActiveAction: Action;\r\n    private _child: Action;\r\n    private _condition?: Condition;\r\n    private _triggerParameter: any;\r\n\r\n    /**\r\n     * An event triggered prior to action being executed.\r\n     */\r\n    public onBeforeExecuteObservable = new Observable<Action>();\r\n\r\n    /**\r\n     * Creates a new Action\r\n     * @param triggerOptions the trigger, with or without parameters, for the action\r\n     * @param condition an optional determinant of action\r\n     */\r\n    constructor(\r\n        /** the trigger, with or without parameters, for the action */\r\n        public triggerOptions: any,\r\n        condition?: Condition\r\n    ) {\r\n        if (triggerOptions.parameter) {\r\n            this.trigger = triggerOptions.trigger;\r\n            this._triggerParameter = triggerOptions.parameter;\r\n        } else if (triggerOptions.trigger) {\r\n            this.trigger = triggerOptions.trigger;\r\n        } else {\r\n            this.trigger = triggerOptions;\r\n        }\r\n\r\n        this._nextActiveAction = this;\r\n        this._condition = condition;\r\n    }\r\n\r\n    /**\r\n     * Internal only\r\n     * @internal\r\n     */\r\n    public _prepare(): void {}\r\n\r\n    /**\r\n     * Gets the trigger parameter\r\n     * @returns the trigger parameter\r\n     */\r\n    public getTriggerParameter(): any {\r\n        return this._triggerParameter;\r\n    }\r\n\r\n    /**\r\n     * Sets the trigger parameter\r\n     * @param value defines the new trigger parameter\r\n     */\r\n    public setTriggerParameter(value: any) {\r\n        this._triggerParameter = value;\r\n    }\r\n\r\n    /**\r\n     * Internal only - Returns if the current condition allows to run the action\r\n     * @internal\r\n     */\r\n    public _evaluateConditionForCurrentFrame(): boolean {\r\n        const condition = this._condition;\r\n        if (!condition) {\r\n            return true;\r\n        }\r\n\r\n        const currentRenderId = this._actionManager.getScene().getRenderId();\r\n\r\n        // We cache the current evaluation for the current frame\r\n        if (condition._evaluationId !== currentRenderId) {\r\n            condition._evaluationId = currentRenderId;\r\n            condition._currentResult = condition.isValid();\r\n        }\r\n\r\n        return condition._currentResult;\r\n    }\r\n\r\n    /**\r\n     * Internal only - executes current action event\r\n     * @internal\r\n     */\r\n    public _executeCurrent(evt?: ActionEvent): void {\r\n        const isConditionValid = this._evaluateConditionForCurrentFrame();\r\n        if (!isConditionValid) {\r\n            return;\r\n        }\r\n\r\n        this.onBeforeExecuteObservable.notifyObservers(this);\r\n        this._nextActiveAction.execute(evt);\r\n\r\n        this.skipToNextActiveAction();\r\n    }\r\n\r\n    /**\r\n     * Execute placeholder for child classes\r\n     * @param evt optional action event\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public execute(evt?: ActionEvent): void {}\r\n\r\n    /**\r\n     * Skips to next active action\r\n     */\r\n    public skipToNextActiveAction(): void {\r\n        if (this._nextActiveAction._child) {\r\n            if (!this._nextActiveAction._child._actionManager) {\r\n                this._nextActiveAction._child._actionManager = this._actionManager;\r\n            }\r\n\r\n            this._nextActiveAction = this._nextActiveAction._child;\r\n        } else {\r\n            this._nextActiveAction = this;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds action to chain of actions, may be a DoNothingAction\r\n     * @param action defines the next action to execute\r\n     * @returns The action passed in\r\n     * @see https://www.babylonjs-playground.com/#1T30HR#0\r\n     */\r\n    public then(action: Action): Action {\r\n        this._child = action;\r\n\r\n        action._actionManager = this._actionManager;\r\n        action._prepare();\r\n\r\n        return action;\r\n    }\r\n\r\n    /**\r\n     * Internal only\r\n     * @internal\r\n     */\r\n    public _getProperty(propertyPath: string): string {\r\n        return this._actionManager._getProperty(propertyPath);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getEffectiveTarget(target: any, propertyPath: string): any {\r\n        return this._actionManager._getEffectiveTarget(target, propertyPath);\r\n    }\r\n\r\n    /**\r\n     * Serialize placeholder for child classes\r\n     * @param parent of child\r\n     * @returns the serialized object\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public serialize(parent: any): any {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Internal only called by serialize\r\n     * @internal\r\n     */\r\n    protected _serialize(serializedAction: any, parent?: any): any {\r\n        const serializationObject: any = {\r\n            type: 1,\r\n            children: [],\r\n            name: serializedAction.name,\r\n            properties: serializedAction.properties || [],\r\n        };\r\n\r\n        // Serialize child\r\n        if (this._child) {\r\n            this._child.serialize(serializationObject);\r\n        }\r\n\r\n        // Check if \"this\" has a condition\r\n        if (this._condition) {\r\n            const serializedCondition = this._condition.serialize();\r\n            serializedCondition.children.push(serializationObject);\r\n\r\n            if (parent) {\r\n                parent.children.push(serializedCondition);\r\n            }\r\n            return serializedCondition;\r\n        }\r\n\r\n        if (parent) {\r\n            parent.children.push(serializationObject);\r\n        }\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Internal only\r\n     * @internal\r\n     */\r\n    public static _SerializeValueAsString = (value: any): string => {\r\n        if (typeof value === \"number\") {\r\n            return value.toString();\r\n        }\r\n\r\n        if (typeof value === \"boolean\") {\r\n            return value ? \"true\" : \"false\";\r\n        }\r\n\r\n        if (value instanceof Vector2) {\r\n            return value.x + \", \" + value.y;\r\n        }\r\n        if (value instanceof Vector3) {\r\n            return value.x + \", \" + value.y + \", \" + value.z;\r\n        }\r\n\r\n        if (value instanceof Color3) {\r\n            return value.r + \", \" + value.g + \", \" + value.b;\r\n        }\r\n        if (value instanceof Color4) {\r\n            return value.r + \", \" + value.g + \", \" + value.b + \", \" + value.a;\r\n        }\r\n\r\n        return value as string; // string\r\n    };\r\n\r\n    /**\r\n     * Internal only\r\n     * @internal\r\n     */\r\n    public static _GetTargetProperty = (target: Scene | Node | Material) => {\r\n        return {\r\n            name: \"target\",\r\n            targetType: (<Mesh>target)._isMesh\r\n                ? \"MeshProperties\"\r\n                : (<Light>target)._isLight\r\n                  ? \"LightProperties\"\r\n                  : (<Camera>target)._isCamera\r\n                    ? \"CameraProperties\"\r\n                    : (<Material>target)._isMaterial\r\n                      ? \"MaterialProperties\"\r\n                      : \"SceneProperties\",\r\n            value: (<Scene>target)._isScene ? \"Scene\" : (<Node>target).name,\r\n        };\r\n    };\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for action.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAction(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.Action\", Action);\r\n}\r\n","import { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Sprite } from \"../Sprites/sprite\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Vector2 } from \"../Maths/math.vector\";\r\n\r\n/**\r\n * Interface used to define ActionEvent\r\n */\r\nexport interface IActionEvent {\r\n    /** The mesh or sprite that triggered the action */\r\n    source: any;\r\n    /** The X mouse cursor position at the time of the event */\r\n    pointerX: number;\r\n    /** The Y mouse cursor position at the time of the event */\r\n    pointerY: number;\r\n    /** The mesh that is currently pointed at (can be null) */\r\n    meshUnderPointer: Nullable<AbstractMesh>;\r\n    /** the original (browser) event that triggered the ActionEvent */\r\n    sourceEvent?: any;\r\n    /** additional data for the event */\r\n    additionalData?: any;\r\n}\r\n\r\n/**\r\n * ActionEvent is the event being sent when an action is triggered.\r\n */\r\nexport class ActionEvent implements IActionEvent {\r\n    /**\r\n     * Creates a new ActionEvent\r\n     * @param source The mesh or sprite that triggered the action\r\n     * @param pointerX The X mouse cursor position at the time of the event\r\n     * @param pointerY The Y mouse cursor position at the time of the event\r\n     * @param meshUnderPointer The mesh that is currently pointed at (can be null)\r\n     * @param sourceEvent the original (browser) event that triggered the ActionEvent\r\n     * @param additionalData additional data for the event\r\n     */\r\n    constructor(\r\n        /** The mesh or sprite that triggered the action */\r\n        public source: any,\r\n        /** The X mouse cursor position at the time of the event */\r\n        public pointerX: number,\r\n        /** The Y mouse cursor position at the time of the event */\r\n        public pointerY: number,\r\n        /** The mesh that is currently pointed at (can be null) */\r\n        public meshUnderPointer: Nullable<AbstractMesh>,\r\n        /** the original (browser) event that triggered the ActionEvent */\r\n        public sourceEvent?: any,\r\n        /** additional data for the event */\r\n        public additionalData?: any\r\n    ) {}\r\n\r\n    /**\r\n     * Helper function to auto-create an ActionEvent from a source mesh.\r\n     * @param source The source mesh that triggered the event\r\n     * @param evt The original (browser) event\r\n     * @param additionalData additional data for the event\r\n     * @returns the new ActionEvent\r\n     */\r\n    public static CreateNew(source: AbstractMesh, evt?: any, additionalData?: any): ActionEvent {\r\n        const scene = source.getScene();\r\n        return new ActionEvent(source, scene.pointerX, scene.pointerY, scene.meshUnderPointer || source, evt, additionalData);\r\n    }\r\n\r\n    /**\r\n     * Helper function to auto-create an ActionEvent from a source sprite\r\n     * @param source The source sprite that triggered the event\r\n     * @param scene Scene associated with the sprite\r\n     * @param evt The original (browser) event\r\n     * @param additionalData additional data for the event\r\n     * @returns the new ActionEvent\r\n     */\r\n    public static CreateNewFromSprite(source: Sprite, scene: Scene, evt?: any, additionalData?: any): ActionEvent {\r\n        return new ActionEvent(source, scene.pointerX, scene.pointerY, scene.meshUnderPointer, evt, additionalData);\r\n    }\r\n\r\n    /**\r\n     * Helper function to auto-create an ActionEvent from a scene. If triggered by a mesh use ActionEvent.CreateNew\r\n     * @param scene the scene where the event occurred\r\n     * @param evt The original (browser) event\r\n     * @returns the new ActionEvent\r\n     */\r\n    public static CreateNewFromScene(scene: Scene, evt: any): ActionEvent {\r\n        return new ActionEvent(null, scene.pointerX, scene.pointerY, scene.meshUnderPointer, evt);\r\n    }\r\n\r\n    /**\r\n     * Helper function to auto-create an ActionEvent from a primitive\r\n     * @param prim defines the target primitive\r\n     * @param pointerPos defines the pointer position\r\n     * @param evt The original (browser) event\r\n     * @param additionalData additional data for the event\r\n     * @returns the new ActionEvent\r\n     */\r\n    public static CreateNewFromPrimitive(prim: any, pointerPos: Vector2, evt?: Event, additionalData?: any): ActionEvent {\r\n        return new ActionEvent(prim, pointerPos.x, pointerPos.y, null, evt, additionalData);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Action } from \"./action.pure\";\r\n\r\nimport { type ActionManager } from \"./actionManager\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * A Condition applied to an Action\r\n */\r\nexport class Condition {\r\n    /**\r\n     * Internal only - manager for action\r\n     * @internal\r\n     */\r\n    public _actionManager: ActionManager;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _evaluationId: number;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _currentResult: boolean;\r\n\r\n    /**\r\n     * Creates a new Condition\r\n     * @param actionManager the manager of the action the condition is applied to\r\n     */\r\n    constructor(actionManager: ActionManager) {\r\n        this._actionManager = actionManager;\r\n    }\r\n\r\n    /**\r\n     * Check if the current condition is valid\r\n     * @returns a boolean\r\n     */\r\n    public isValid(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getProperty(propertyPath: string): string {\r\n        return this._actionManager._getProperty(propertyPath);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getEffectiveTarget(target: any, propertyPath: string): any {\r\n        return this._actionManager._getEffectiveTarget(target, propertyPath);\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Serialize placeholder for child classes\r\n     * @returns the serialized object\r\n     */\r\n    public serialize(): any {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    protected _serialize(serializedCondition: any): any {\r\n        return {\r\n            type: 2, // Condition\r\n            children: [],\r\n            name: serializedCondition.name,\r\n            properties: serializedCondition.properties,\r\n        };\r\n    }\r\n}\r\n\r\n/**\r\n * Defines specific conditional operators as extensions of Condition\r\n */\r\nexport class ValueCondition extends Condition {\r\n    private static _IsEqual = 0;\r\n    private static _IsDifferent = 1;\r\n    private static _IsGreater = 2;\r\n    private static _IsLesser = 3;\r\n\r\n    /**\r\n     * returns the number for IsEqual\r\n     */\r\n    public static get IsEqual(): number {\r\n        return ValueCondition._IsEqual;\r\n    }\r\n\r\n    /**\r\n     * Returns the number for IsDifferent\r\n     */\r\n    public static get IsDifferent(): number {\r\n        return ValueCondition._IsDifferent;\r\n    }\r\n\r\n    /**\r\n     * Returns the number for IsGreater\r\n     */\r\n    public static get IsGreater(): number {\r\n        return ValueCondition._IsGreater;\r\n    }\r\n\r\n    /**\r\n     * Returns the number for IsLesser\r\n     */\r\n    public static get IsLesser(): number {\r\n        return ValueCondition._IsLesser;\r\n    }\r\n\r\n    /**\r\n     * Internal only The action manager for the condition\r\n     * @internal\r\n     */\r\n    public override _actionManager: ActionManager;\r\n\r\n    private _target: any;\r\n    private _effectiveTarget: any;\r\n    private _property: string;\r\n\r\n    /**\r\n     * Creates a new ValueCondition\r\n     * @param actionManager manager for the action the condition applies to\r\n     * @param target for the action\r\n     * @param propertyPath path to specify the property of the target the conditional operator uses\r\n     * @param value the value compared by the conditional operator against the current value of the property\r\n     * @param operator the conditional operator, default ValueCondition.IsEqual\r\n     */\r\n    constructor(\r\n        actionManager: ActionManager,\r\n        target: any,\r\n        /** path to specify the property of the target the conditional operator uses  */\r\n        public propertyPath: string,\r\n        /** the value compared by the conditional operator against the current value of the property */\r\n        public value: any,\r\n        /** [number] the conditional operator, default ValueCondition.IsEqual */\r\n        public operator: number = ValueCondition.IsEqual\r\n    ) {\r\n        super(actionManager);\r\n\r\n        this._target = target;\r\n        this._effectiveTarget = this._getEffectiveTarget(target, this.propertyPath);\r\n        this._property = this._getProperty(this.propertyPath);\r\n    }\r\n\r\n    /**\r\n     * Compares the given value with the property value for the specified conditional operator\r\n     * @returns the result of the comparison\r\n     */\r\n    public override isValid(): boolean {\r\n        switch (this.operator) {\r\n            case ValueCondition.IsGreater:\r\n                return this._effectiveTarget[this._property] > this.value;\r\n            case ValueCondition.IsLesser:\r\n                return this._effectiveTarget[this._property] < this.value;\r\n            case ValueCondition.IsEqual:\r\n            case ValueCondition.IsDifferent: {\r\n                let check: boolean;\r\n\r\n                if (this.value.equals) {\r\n                    check = this.value.equals(this._effectiveTarget[this._property]);\r\n                } else {\r\n                    check = this.value === this._effectiveTarget[this._property];\r\n                }\r\n                return this.operator === ValueCondition.IsEqual ? check : !check;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Serialize the ValueCondition into a JSON compatible object\r\n     * @returns serialization object\r\n     */\r\n    public override serialize(): any {\r\n        return this._serialize({\r\n            name: \"ValueCondition\",\r\n            properties: [\r\n                Action._GetTargetProperty(this._target),\r\n                { name: \"propertyPath\", value: this.propertyPath },\r\n                { name: \"value\", value: Action._SerializeValueAsString(this.value) },\r\n                { name: \"operator\", value: ValueCondition.GetOperatorName(this.operator) },\r\n            ],\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the name of the conditional operator for the ValueCondition\r\n     * @param operator the conditional operator\r\n     * @returns the name\r\n     */\r\n    public static GetOperatorName(operator: number): string {\r\n        switch (operator) {\r\n            case ValueCondition._IsEqual:\r\n                return \"IsEqual\";\r\n            case ValueCondition._IsDifferent:\r\n                return \"IsDifferent\";\r\n            case ValueCondition._IsGreater:\r\n                return \"IsGreater\";\r\n            case ValueCondition._IsLesser:\r\n                return \"IsLesser\";\r\n            default:\r\n                return \"\";\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Defines a predicate condition as an extension of Condition\r\n */\r\nexport class PredicateCondition extends Condition {\r\n    /**\r\n     * Internal only - manager for action\r\n     * @internal\r\n     */\r\n    public override _actionManager: ActionManager;\r\n\r\n    /**\r\n     * Creates a new PredicateCondition\r\n     * @param actionManager manager for the action the condition applies to\r\n     * @param predicate defines the predicate function used to validate the condition\r\n     */\r\n    constructor(\r\n        actionManager: ActionManager,\r\n        /** defines the predicate function used to validate the condition */\r\n        public predicate: () => boolean\r\n    ) {\r\n        super(actionManager);\r\n    }\r\n\r\n    /**\r\n     * @returns the validity of the predicate condition\r\n     */\r\n    public override isValid(): boolean {\r\n        return this.predicate();\r\n    }\r\n}\r\n\r\n/**\r\n * Defines a state condition as an extension of Condition\r\n */\r\nexport class StateCondition extends Condition {\r\n    /**\r\n     * Internal only - manager for action\r\n     * @internal\r\n     */\r\n    public override _actionManager: ActionManager;\r\n\r\n    private _target: any;\r\n\r\n    /**\r\n     * Creates a new StateCondition\r\n     * @param actionManager manager for the action the condition applies to\r\n     * @param target of the condition\r\n     * @param value to compare with target state\r\n     */\r\n    constructor(\r\n        actionManager: ActionManager,\r\n        target: any,\r\n        /** Value to compare with target state  */\r\n        public value: string\r\n    ) {\r\n        super(actionManager);\r\n\r\n        this._target = target;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current condition is met\r\n     * @returns the validity of the state\r\n     */\r\n    public override isValid(): boolean {\r\n        return this._target.state === this.value;\r\n    }\r\n\r\n    /**\r\n     * Serialize the StateCondition into a JSON compatible object\r\n     * @returns serialization object\r\n     */\r\n    public override serialize(): any {\r\n        return this._serialize({\r\n            name: \"StateCondition\",\r\n            properties: [Action._GetTargetProperty(this._target), { name: \"value\", value: this.value }],\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for condition.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCondition(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ValueCondition\", ValueCondition);\r\n    RegisterClass(\"BABYLON.PredicateCondition\", PredicateCondition);\r\n    RegisterClass(\"BABYLON.StateCondition\", StateCondition);\r\n}\r\n","/* eslint-disable no-console */\r\n/**\r\n * Logger used throughout the application to allow configuration of\r\n * the log level required for the messages.\r\n */\r\nexport class Logger {\r\n    /**\r\n     * No log\r\n     */\r\n    public static readonly NoneLogLevel = 0;\r\n    /**\r\n     * Only message logs\r\n     */\r\n    public static readonly MessageLogLevel = 1;\r\n    /**\r\n     * Only warning logs\r\n     */\r\n    public static readonly WarningLogLevel = 2;\r\n    /**\r\n     * Only error logs\r\n     */\r\n    public static readonly ErrorLogLevel = 4;\r\n    /**\r\n     * All logs\r\n     */\r\n    public static readonly AllLogLevel = 7;\r\n\r\n    /**\r\n     * Message to display when a message has been logged too many times\r\n     */\r\n    public static MessageLimitReached = \"Too many %TYPE%s (%LIMIT%), no more %TYPE%s will be reported for this message.\";\r\n\r\n    private static _LogCache = \"\";\r\n    private static _LogLimitOutputs: { [message: string]: { limit: number; current: number } } = {};\r\n    // levels according to the (binary) numbering.\r\n    private static _Levels = [\r\n        {},\r\n        { color: \"white\", logFunc: console.log, name: \"Log\" },\r\n        { color: \"orange\", logFunc: console.warn, name: \"Warn\" },\r\n        {},\r\n        { color: \"red\", logFunc: console.error, name: \"Error\" },\r\n    ];\r\n\r\n    /**\r\n     * Gets a value indicating the number of loading errors\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static errorsCount = 0;\r\n\r\n    /**\r\n     * Callback called when a new log is added\r\n     */\r\n    public static OnNewCacheEntry: (entry: string) => void;\r\n\r\n    private static _CheckLimit(message: string, limit: number): boolean {\r\n        let entry = Logger._LogLimitOutputs[message];\r\n        if (!entry) {\r\n            entry = { limit, current: 1 };\r\n            Logger._LogLimitOutputs[message] = entry;\r\n        } else {\r\n            entry.current++;\r\n        }\r\n        return entry.current <= entry.limit;\r\n    }\r\n\r\n    private static _GenerateLimitMessage(message: string, level: number = 1): void {\r\n        const entry = Logger._LogLimitOutputs[message];\r\n        if (!entry || !Logger.MessageLimitReached) {\r\n            return;\r\n        }\r\n        const type = this._Levels[level];\r\n        if (entry.current === entry.limit) {\r\n            Logger[type.name as \"Log\" | \"Warn\" | \"Error\"](Logger.MessageLimitReached.replace(/%LIMIT%/g, \"\" + entry.limit).replace(/%TYPE%/g, type.name ?? \"\"));\r\n        }\r\n    }\r\n\r\n    private static _AddLogEntry(entry: string) {\r\n        Logger._LogCache = entry + Logger._LogCache;\r\n\r\n        if (Logger.OnNewCacheEntry) {\r\n            Logger.OnNewCacheEntry(entry);\r\n        }\r\n    }\r\n\r\n    private static _FormatMessage(message: string): string {\r\n        const padStr = (i: number) => (i < 10 ? \"0\" + i : \"\" + i);\r\n\r\n        const date = new Date();\r\n        return \"[\" + padStr(date.getHours()) + \":\" + padStr(date.getMinutes()) + \":\" + padStr(date.getSeconds()) + \"]: \" + message;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private static _LogDisabled(message: string | any[], limit?: number): void {\r\n        // nothing to do\r\n    }\r\n    private static _LogEnabled(level: number = 1, message: string | any[], limit?: number): void {\r\n        // take first message if array\r\n        const msg = Array.isArray(message) ? message[0] : message;\r\n        if (limit !== undefined && !Logger._CheckLimit(msg, limit)) {\r\n            return;\r\n        }\r\n\r\n        const formattedMessage = Logger._FormatMessage(msg);\r\n        const type = this._Levels[level];\r\n        const optionals = Array.isArray(message) ? message.slice(1) : [];\r\n        type.logFunc && type.logFunc(\"BJS - \" + formattedMessage, ...optionals);\r\n\r\n        const entry = `<div style='color:${type.color}'>${formattedMessage}</div><br>`;\r\n        Logger._AddLogEntry(entry);\r\n        Logger._GenerateLimitMessage(msg, level);\r\n    }\r\n\r\n    /**\r\n     * Log a message to the console\r\n     */\r\n    public static Log: (message: string | any[], limit?: number) => void = Logger._LogEnabled.bind(Logger, Logger.MessageLogLevel);\r\n\r\n    /**\r\n     * Write a warning message to the console\r\n     */\r\n    public static Warn: (message: string | any[], limit?: number) => void = Logger._LogEnabled.bind(Logger, Logger.WarningLogLevel);\r\n\r\n    /**\r\n     * Write an error message to the console\r\n     */\r\n    public static Error: (message: string | any[], limit?: number) => void = Logger._LogEnabled.bind(Logger, Logger.ErrorLogLevel);\r\n\r\n    /**\r\n     * Gets current log cache (list of logs)\r\n     */\r\n    public static get LogCache(): string {\r\n        return Logger._LogCache;\r\n    }\r\n\r\n    /**\r\n     * Clears the log cache\r\n     */\r\n    public static ClearLogCache(): void {\r\n        Logger._LogCache = \"\";\r\n        Logger._LogLimitOutputs = {};\r\n        Logger.errorsCount = 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the current log level. This property is a bit field, allowing you to combine different levels (MessageLogLevel / WarningLogLevel / ErrorLogLevel).\r\n     * Use NoneLogLevel to disable logging and AllLogLevel for a quick way to enable all levels.\r\n     */\r\n    public static set LogLevels(level: number) {\r\n        Logger.Log = Logger._LogDisabled;\r\n        Logger.Warn = Logger._LogDisabled;\r\n        Logger.Error = Logger._LogDisabled;\r\n        const levels = [Logger.MessageLogLevel, Logger.WarningLogLevel, Logger.ErrorLogLevel];\r\n        for (const l of levels) {\r\n            if ((level & l) === l) {\r\n                const type = this._Levels[l];\r\n                Logger[type.name as \"Log\" | \"Warn\" | \"Error\"] = Logger._LogEnabled.bind(Logger, l);\r\n            }\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Action } from \"./action.pure\";\r\nimport { type Condition } from \"./condition.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { type ActionEvent } from \"./actionEvent\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This defines an action responsible to toggle a boolean once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class SwitchBooleanAction extends Action {\r\n    /**\r\n     * The path to the boolean property in the target object\r\n     */\r\n    public propertyPath: string;\r\n\r\n    private _target: any;\r\n    private _effectiveTarget: any;\r\n    private _property: string;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the object containing the boolean\r\n     * @param propertyPath defines the path to the boolean property in the target object\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, propertyPath: string, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this.propertyPath = propertyPath;\r\n        this._target = this._effectiveTarget = target;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {\r\n        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);\r\n        this._property = this._getProperty(this.propertyPath);\r\n    }\r\n\r\n    /**\r\n     * Execute the action toggle the boolean value.\r\n     */\r\n    public override execute(): void {\r\n        this._effectiveTarget[this._property] = !this._effectiveTarget[this._property];\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"SwitchBooleanAction\",\r\n                properties: [Action._GetTargetProperty(this._target), { name: \"propertyPath\", value: this.propertyPath }],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to set a the state field of the target\r\n *  to a desired value once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class SetStateAction extends Action {\r\n    /**\r\n     * The value to store in the state field.\r\n     */\r\n    public value: string;\r\n\r\n    private _target: any;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the object containing the state property\r\n     * @param value defines the value to store in the state field\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, value: string, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this.value = value;\r\n        this._target = target;\r\n    }\r\n\r\n    /**\r\n     * Execute the action and store the value on the target state property.\r\n     */\r\n    public override execute(): void {\r\n        this._target.state = this.value;\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"SetStateAction\",\r\n                properties: [Action._GetTargetProperty(this._target), { name: \"value\", value: this.value }],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to set a property of the target\r\n *  to a desired value once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class SetValueAction extends Action {\r\n    /**\r\n     * The path of the property to set in the target.\r\n     */\r\n    public propertyPath: string;\r\n\r\n    /**\r\n     * The value to set in the property\r\n     */\r\n    public value: any;\r\n\r\n    private _target: any;\r\n    private _effectiveTarget: any;\r\n    private _property: string;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the object containing the property\r\n     * @param propertyPath defines the path of the property to set in the target\r\n     * @param value defines the value to set in the property\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, propertyPath: string, value: any, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this.propertyPath = propertyPath;\r\n        this.value = value;\r\n        this._target = this._effectiveTarget = target;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {\r\n        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);\r\n        this._property = this._getProperty(this.propertyPath);\r\n    }\r\n\r\n    /**\r\n     * Execute the action and set the targeted property to the desired value.\r\n     */\r\n    public override execute(): void {\r\n        this._effectiveTarget[this._property] = this.value;\r\n\r\n        if (this._target.markAsDirty) {\r\n            this._target.markAsDirty(this._property);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"SetValueAction\",\r\n                properties: [\r\n                    Action._GetTargetProperty(this._target),\r\n                    { name: \"propertyPath\", value: this.propertyPath },\r\n                    { name: \"value\", value: Action._SerializeValueAsString(this.value) },\r\n                ],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to increment the target value\r\n *  to a desired value once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class IncrementValueAction extends Action {\r\n    /**\r\n     * The path of the property to increment in the target.\r\n     */\r\n    public propertyPath: string;\r\n\r\n    /**\r\n     * The value we should increment the property by.\r\n     */\r\n    public value: any;\r\n\r\n    private _target: any;\r\n    private _effectiveTarget: any;\r\n    private _property: string;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the object containing the property\r\n     * @param propertyPath defines the path of the property to increment in the target\r\n     * @param value defines the value value we should increment the property by\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, propertyPath: string, value: any, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this.propertyPath = propertyPath;\r\n        this.value = value;\r\n        this._target = this._effectiveTarget = target;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {\r\n        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);\r\n        this._property = this._getProperty(this.propertyPath);\r\n\r\n        if (typeof this._effectiveTarget[this._property] !== \"number\") {\r\n            Logger.Warn(\"Warning: IncrementValueAction can only be used with number values\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Execute the action and increment the target of the value amount.\r\n     */\r\n    public override execute(): void {\r\n        this._effectiveTarget[this._property] += this.value;\r\n\r\n        if (this._target.markAsDirty) {\r\n            this._target.markAsDirty(this._property);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"IncrementValueAction\",\r\n                properties: [\r\n                    Action._GetTargetProperty(this._target),\r\n                    { name: \"propertyPath\", value: this.propertyPath },\r\n                    { name: \"value\", value: Action._SerializeValueAsString(this.value) },\r\n                ],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to start an animation once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class PlayAnimationAction extends Action {\r\n    /**\r\n     * Where the animation should start (animation frame)\r\n     */\r\n    public from: number;\r\n\r\n    /**\r\n     * Where the animation should stop (animation frame)\r\n     */\r\n    public to: number;\r\n\r\n    /**\r\n     * Define if the animation should loop or stop after the first play.\r\n     */\r\n    public loop?: boolean;\r\n\r\n    private _target: any;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the target animation or animation name\r\n     * @param from defines from where the animation should start (animation frame)\r\n     * @param to defines where the animation should stop (animation frame)\r\n     * @param loop defines if the animation should loop or stop after the first play\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, from: number, to: number, loop?: boolean, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this.from = from;\r\n        this.to = to;\r\n        this.loop = loop;\r\n        this._target = target;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {}\r\n\r\n    /**\r\n     * Execute the action and play the animation.\r\n     */\r\n    public override execute(): void {\r\n        const scene = this._actionManager.getScene();\r\n        scene.beginAnimation(this._target, this.from, this.to, this.loop);\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"PlayAnimationAction\",\r\n                properties: [\r\n                    Action._GetTargetProperty(this._target),\r\n                    { name: \"from\", value: String(this.from) },\r\n                    { name: \"to\", value: String(this.to) },\r\n                    { name: \"loop\", value: Action._SerializeValueAsString(this.loop) || false },\r\n                ],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to stop an animation once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class StopAnimationAction extends Action {\r\n    private _target: any;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the target animation or animation name\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this._target = target;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {}\r\n\r\n    /**\r\n     * Execute the action and stop the animation.\r\n     */\r\n    public override execute(): void {\r\n        const scene = this._actionManager.getScene();\r\n        scene.stopAnimation(this._target);\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"StopAnimationAction\",\r\n                properties: [Action._GetTargetProperty(this._target)],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible that does nothing once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class DoNothingAction extends Action {\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any = Constants.ACTION_NothingTrigger, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n    }\r\n\r\n    /**\r\n     * Execute the action and do nothing.\r\n     */\r\n    public override execute(): void {}\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"DoNothingAction\",\r\n                properties: [],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to trigger several actions once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class CombineAction extends Action {\r\n    /**\r\n     * The list of aggregated animations to run.\r\n     */\r\n    public children: Action[];\r\n\r\n    /**\r\n     * defines if the children actions conditions should be check before execution\r\n     */\r\n    public enableChildrenConditions: boolean;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param children defines the list of aggregated animations to run\r\n     * @param condition defines the trigger related conditions\r\n     * @param enableChildrenConditions defines if the children actions conditions should be check before execution\r\n     */\r\n    constructor(triggerOptions: any, children: Action[], condition?: Condition, enableChildrenConditions = true) {\r\n        super(triggerOptions, condition);\r\n        this.children = children;\r\n        this.enableChildrenConditions = enableChildrenConditions;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {\r\n        for (let index = 0; index < this.children.length; index++) {\r\n            this.children[index]._actionManager = this._actionManager;\r\n            this.children[index]._prepare();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Execute the action and executes all the aggregated actions.\r\n     * @param evt event to execute\r\n     */\r\n    public override execute(evt: ActionEvent): void {\r\n        for (const action of this.children) {\r\n            if (!this.enableChildrenConditions || action._evaluateConditionForCurrentFrame()) {\r\n                action.execute(evt);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        const serializationObject = super._serialize(\r\n            {\r\n                name: \"CombineAction\",\r\n                properties: [],\r\n                combine: [],\r\n            },\r\n            parent\r\n        );\r\n\r\n        for (let i = 0; i < this.children.length; i++) {\r\n            serializationObject.combine.push(this.children[i].serialize(null));\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to run code (external event) once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class ExecuteCodeAction extends Action {\r\n    /**\r\n     * The callback function to run.\r\n     */\r\n    public func: (evt: ActionEvent) => void;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param func defines the callback function to run\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, func: (evt: ActionEvent) => void, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this.func = func;\r\n    }\r\n\r\n    /**\r\n     * Execute the action and run the attached code.\r\n     * @param evt event to execute\r\n     */\r\n    public override execute(evt: ActionEvent): void {\r\n        this.func(evt);\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action responsible to set the parent property of the target once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class SetParentAction extends Action {\r\n    private _parent: any;\r\n    private _target: any;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the target containing the parent property\r\n     * @param parent defines from where the animation should start (animation frame)\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, target: any, parent: any, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this._target = target;\r\n        this._parent = parent;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {}\r\n\r\n    /**\r\n     * Execute the action and set the parent property.\r\n     */\r\n    public override execute(): void {\r\n        if (this._target.parent === this._parent) {\r\n            return;\r\n        }\r\n\r\n        const invertParentWorldMatrix = this._parent.getWorldMatrix().clone();\r\n        invertParentWorldMatrix.invert();\r\n\r\n        this._target.position = Vector3.TransformCoordinates(this._target.position, invertParentWorldMatrix);\r\n\r\n        this._target.parent = this._parent;\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"SetParentAction\",\r\n                properties: [Action._GetTargetProperty(this._target), Action._GetTargetProperty(this._parent)],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for directActions.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDirectActions(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetParentAction\", SetParentAction);\r\n    RegisterClass(\"BABYLON.ExecuteCodeAction\", ExecuteCodeAction);\r\n    RegisterClass(\"BABYLON.DoNothingAction\", DoNothingAction);\r\n    RegisterClass(\"BABYLON.StopAnimationAction\", StopAnimationAction);\r\n    RegisterClass(\"BABYLON.PlayAnimationAction\", PlayAnimationAction);\r\n    RegisterClass(\"BABYLON.IncrementValueAction\", IncrementValueAction);\r\n    RegisterClass(\"BABYLON.SetValueAction\", SetValueAction);\r\n    RegisterClass(\"BABYLON.SetStateAction\", SetStateAction);\r\n    RegisterClass(\"BABYLON.SetParentAction\", SetParentAction);\r\n    RegisterClass(\"BABYLON.SwitchBooleanAction\", SwitchBooleanAction);\r\n    RegisterClass(\"BABYLON.CombineAction\", CombineAction);\r\n}\r\n","import { Logger } from \"./logger\";\r\n\r\nconst CloneValue = (source: any, destinationObject: any, shallowCopyValues: boolean) => {\r\n    if (!source) {\r\n        return null;\r\n    }\r\n\r\n    if (source.getClassName && source.getClassName() === \"Mesh\") {\r\n        return null;\r\n    }\r\n\r\n    if (source.getClassName && (source.getClassName() === \"SubMesh\" || source.getClassName() === \"PhysicsBody\")) {\r\n        return source.clone(destinationObject);\r\n    } else if (source.clone) {\r\n        return source.clone();\r\n    } else if (Array.isArray(source)) {\r\n        return source.slice();\r\n    } else if (shallowCopyValues && typeof source === \"object\") {\r\n        return { ...source };\r\n    }\r\n    return null;\r\n};\r\n\r\nfunction GetAllPropertyNames(obj: any): string[] {\r\n    const props: string[] = [];\r\n\r\n    do {\r\n        const propNames = Object.getOwnPropertyNames(obj);\r\n        for (const prop of propNames) {\r\n            if (props.indexOf(prop) === -1) {\r\n                props.push(prop);\r\n            }\r\n        }\r\n    } while ((obj = Object.getPrototypeOf(obj)));\r\n\r\n    return props;\r\n}\r\n\r\n/**\r\n * Class containing a set of static utilities functions for deep copy.\r\n */\r\nexport class DeepCopier {\r\n    /**\r\n     * Tries to copy an object by duplicating every property\r\n     * @param source defines the source object\r\n     * @param destination defines the target object\r\n     * @param doNotCopyList defines a list of properties to avoid\r\n     * @param mustCopyList defines a list of properties to copy (even if they start with _)\r\n     * @param shallowCopyValues defines wether properties referencing objects (none cloneable) must be shallow copied (false by default)\r\n     * @remarks shallowCopyValues will not instantite the copied values which makes it only usable for \"JSON objects\"\r\n     */\r\n    public static DeepCopy(source: any, destination: any, doNotCopyList?: string[], mustCopyList?: string[], shallowCopyValues = false): void {\r\n        const properties = GetAllPropertyNames(source);\r\n        for (const prop of properties) {\r\n            if (prop[0] === \"_\" && (!mustCopyList || mustCopyList.indexOf(prop) === -1)) {\r\n                continue;\r\n            }\r\n\r\n            if (prop.endsWith(\"Observable\")) {\r\n                continue;\r\n            }\r\n\r\n            if (doNotCopyList && doNotCopyList.indexOf(prop) !== -1) {\r\n                continue;\r\n            }\r\n\r\n            const sourceValue = source[prop];\r\n            const typeOfSourceValue = typeof sourceValue;\r\n\r\n            if (typeOfSourceValue === \"function\") {\r\n                continue;\r\n            }\r\n\r\n            try {\r\n                if (typeOfSourceValue === \"object\") {\r\n                    if (sourceValue instanceof Uint8Array) {\r\n                        destination[prop] = Uint8Array.from(sourceValue);\r\n                    } else if (sourceValue instanceof Array) {\r\n                        destination[prop] = [];\r\n\r\n                        if (sourceValue.length > 0) {\r\n                            if (typeof sourceValue[0] == \"object\") {\r\n                                for (let index = 0; index < sourceValue.length; index++) {\r\n                                    const clonedValue = CloneValue(sourceValue[index], destination, shallowCopyValues);\r\n\r\n                                    if (destination[prop].indexOf(clonedValue) === -1) {\r\n                                        // Test if auto inject was not done\r\n                                        destination[prop].push(clonedValue);\r\n                                    }\r\n                                }\r\n                            } else {\r\n                                destination[prop] = sourceValue.slice(0);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        destination[prop] = CloneValue(sourceValue, destination, shallowCopyValues);\r\n                    }\r\n                } else {\r\n                    destination[prop] = sourceValue;\r\n                }\r\n            } catch (e) {\r\n                // Log a warning (it could be because of a read-only property)\r\n                Logger.Warn(e.message);\r\n            }\r\n        }\r\n    }\r\n}\r\n","const WarnedMap: { [key: string]: boolean } = {};\r\n/**\r\n * @internal\r\n */\r\nexport function _WarnImport(name: string, warnOnce = false) {\r\n    if (warnOnce && WarnedMap[name]) {\r\n        return;\r\n    }\r\n    WarnedMap[name] = true;\r\n    return `${name} needs to be imported before as it contains a side-effect required by your code.`;\r\n}\r\n\r\nconst _StubWarnedMap: { [key: string]: boolean } = {};\r\nlet _MissingSideEffectWarningsEnabled = false;\r\nlet _MissingSideEffectWarningsSuppressionDepth = 0;\r\n\r\n/**\r\n * Enables or disables console warnings when generated side-effect stubs are called.\r\n * Warnings are disabled by default because internal code may probe optional augmented APIs.\r\n * @param enabled - Whether missing side-effect stub calls should emit one-time warnings.\r\n */\r\nexport function SetMissingSideEffectWarningsEnabled(enabled: boolean): void {\r\n    _MissingSideEffectWarningsEnabled = enabled;\r\n}\r\n\r\n/**\r\n * Runs a callback while missing side-effect stub warnings are suppressed.\r\n * @param callback - The callback to run with warnings suppressed.\r\n * @returns The callback result.\r\n */\r\nexport function SuppressMissingSideEffectWarnings<T>(callback: () => T): T {\r\n    _MissingSideEffectWarningsSuppressionDepth++;\r\n\r\n    try {\r\n        return callback();\r\n    } finally {\r\n        _MissingSideEffectWarningsSuppressionDepth--;\r\n    }\r\n}\r\n\r\n/**\r\n * Interface for functions that are side-effect stubs.\r\n * Used to type-safely check if a method is a stub without using `any`.\r\n * @internal\r\n */\r\nexport interface ISideEffectStub {\r\n    /** Marker property indicating this is a side-effect stub */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    __isSideEffectStub: true;\r\n}\r\n\r\n/**\r\n * Returns a stub function that acts as a placeholder for augmented methods that\r\n * require a side-effect import. The stub is tagged with `__isSideEffectStub` so\r\n * that feature-detection code can check `_IsSideEffectImplemented()` before calling.\r\n *\r\n * The stub does NOT warn by default because internal engine code frequently calls\r\n * augmented methods as feature checks (e.g., `getBoundingBoxRenderer?.()` in the\r\n * render loop). Warnings would fire every frame for features the user never requested.\r\n *\r\n * If the user actually tries to use the returned value (which is undefined), they\r\n * will get a clear TypeError at the point of use.\r\n *\r\n * @param className - The class name (for diagnostic purposes)\r\n * @param methodName - The method name (for diagnostic purposes)\r\n * @param warn - If true, emit a one-time console warning when the stub is called.\r\n *              Use this only for methods that are never called internally as feature checks.\r\n * @internal\r\n */\r\nexport function _MissingSideEffect(className: string, methodName: string, warn = false): (...args: unknown[]) => void {\r\n    const stub = function () {\r\n        if ((warn || _MissingSideEffectWarningsEnabled) && _MissingSideEffectWarningsSuppressionDepth === 0) {\r\n            const key = `${className}.${methodName}`;\r\n            if (!_StubWarnedMap[key]) {\r\n                _StubWarnedMap[key] = true;\r\n                // eslint-disable-next-line no-console\r\n                console.warn(`[Babylon.js] ${key}() requires a side-effect import. See: https://doc.babylonjs.com/setup/treeshaking`);\r\n            }\r\n        }\r\n    };\r\n    (stub as unknown as ISideEffectStub).__isSideEffectStub = true;\r\n    return stub;\r\n}\r\n\r\n/**\r\n * Checks whether a value is a side-effect stub (i.e., a placeholder function\r\n * generated by _MissingSideEffect). Use this instead of truthiness checks when\r\n * doing feature detection on methods that may be stubbed for tree-shaking.\r\n * @param fn The function/method to check\r\n * @returns true if the function is a real implementation (not a stub or undefined/null)\r\n * @internal\r\n */\r\nexport function _IsSideEffectImplemented(fn: unknown): boolean {\r\n    if (!fn) {\r\n        return false;\r\n    }\r\n    return !(fn as ISideEffectStub).__isSideEffectStub;\r\n}\r\n\r\n/**\r\n * Returns a property descriptor that acts as a placeholder for augmented properties\r\n * that require a side-effect import. The getter returns undefined (allowing pure code\r\n * to feature-detect by checking truthiness), and the setter replaces the stub with a\r\n * real data property on the instance.\r\n * @internal\r\n */\r\nexport function _MissingSideEffectProperty(className: string, propName: string): PropertyDescriptor {\r\n    return {\r\n        get() {\r\n            return undefined;\r\n        },\r\n        set(value) {\r\n            // Replace the stub with a real data property so the value is stored\r\n            Object.defineProperty(this, propName, {\r\n                value,\r\n                writable: true,\r\n                configurable: true,\r\n                enumerable: true,\r\n            });\r\n        },\r\n        configurable: true,\r\n        enumerable: true,\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Vector3, Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Condition, RegisterCondition, ValueCondition } from \"./condition.pure\";\r\nimport { type IAction, Action, RegisterAction } from \"./action.pure\";\r\nimport { DoNothingAction, RegisterDirectActions } from \"./directActions.pure\";\r\n\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IActionEvent } from \"../Actions/actionEvent\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { DeepCopier } from \"../Misc/deepCopier\";\r\nimport { GetClass } from \"../Misc/typeStore\";\r\nimport { AbstractActionManager } from \"./abstractActionManager\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { _IsSideEffectImplemented } from \"../Misc/devTools\";\r\n\r\n/**\r\n * Action Manager manages all events to be triggered on a given mesh or the global scene.\r\n * A single scene can have many Action Managers to handle predefined actions on specific meshes.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class ActionManager extends AbstractActionManager {\r\n    /**\r\n     * Nothing\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly NothingTrigger = Constants.ACTION_NothingTrigger;\r\n\r\n    /**\r\n     * On pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnPickTrigger = Constants.ACTION_OnPickTrigger;\r\n\r\n    /**\r\n     * On left pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnLeftPickTrigger = Constants.ACTION_OnLeftPickTrigger;\r\n\r\n    /**\r\n     * On right pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnRightPickTrigger = Constants.ACTION_OnRightPickTrigger;\r\n\r\n    /**\r\n     * On center pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnCenterPickTrigger = Constants.ACTION_OnCenterPickTrigger;\r\n\r\n    /**\r\n     * On pick down\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnPickDownTrigger = Constants.ACTION_OnPickDownTrigger;\r\n\r\n    /**\r\n     * On double pick\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnDoublePickTrigger = Constants.ACTION_OnDoublePickTrigger;\r\n\r\n    /**\r\n     * On pick up\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnPickUpTrigger = Constants.ACTION_OnPickUpTrigger;\r\n    /**\r\n     * On pick out.\r\n     * This trigger will only be raised if you also declared a OnPickDown\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnPickOutTrigger = Constants.ACTION_OnPickOutTrigger;\r\n\r\n    /**\r\n     * On long press\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnLongPressTrigger = Constants.ACTION_OnLongPressTrigger;\r\n\r\n    /**\r\n     * On pointer over\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnPointerOverTrigger = Constants.ACTION_OnPointerOverTrigger;\r\n\r\n    /**\r\n     * On pointer out\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnPointerOutTrigger = Constants.ACTION_OnPointerOutTrigger;\r\n\r\n    /**\r\n     * On every frame\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnEveryFrameTrigger = Constants.ACTION_OnEveryFrameTrigger;\r\n    /**\r\n     * On intersection enter\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnIntersectionEnterTrigger = Constants.ACTION_OnIntersectionEnterTrigger;\r\n\r\n    /**\r\n     * On intersection exit\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnIntersectionExitTrigger = Constants.ACTION_OnIntersectionExitTrigger;\r\n\r\n    /**\r\n     * On key down\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnKeyDownTrigger = Constants.ACTION_OnKeyDownTrigger;\r\n\r\n    /**\r\n     * On key up\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#triggers\r\n     */\r\n    public static readonly OnKeyUpTrigger = Constants.ACTION_OnKeyUpTrigger;\r\n\r\n    // Members\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Creates a new action manager\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(scene?: Nullable<Scene>) {\r\n        super();\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this._scene = scene;\r\n\r\n        scene.actionManagers.push(this);\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Releases all associated resources\r\n     */\r\n    public dispose(): void {\r\n        const sceneIndex = this._scene.actionManagers.indexOf(this);\r\n\r\n        for (let i = 0; i < this.actions.length; i++) {\r\n            const action = this.actions[i];\r\n            ActionManager.Triggers[action.trigger]--;\r\n            if (ActionManager.Triggers[action.trigger] === 0) {\r\n                delete ActionManager.Triggers[action.trigger];\r\n            }\r\n        }\r\n\r\n        this.actions.length = 0;\r\n\r\n        if (sceneIndex > -1) {\r\n            this._scene.actionManagers.splice(sceneIndex, 1);\r\n        }\r\n\r\n        const ownerMeshes = this._scene.meshes.filter((m) => m.actionManager === this);\r\n        for (const ownerMesh of ownerMeshes) {\r\n            ownerMesh.actionManager = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets hosting scene\r\n     * @returns the hosting scene\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Does this action manager handles actions of any of the given triggers\r\n     * @param triggers defines the triggers to be tested\r\n     * @returns a boolean indicating whether one (or more) of the triggers is handled\r\n     */\r\n    public hasSpecificTriggers(triggers: number[]): boolean {\r\n        for (let index = 0; index < this.actions.length; index++) {\r\n            const action = this.actions[index];\r\n\r\n            if (triggers.indexOf(action.trigger) > -1) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Does this action manager handles actions of any of the given triggers. This function takes two arguments for\r\n     * speed.\r\n     * @param triggerA defines the trigger to be tested\r\n     * @param triggerB defines the trigger to be tested\r\n     * @returns a boolean indicating whether one (or more) of the triggers is handled\r\n     */\r\n    public hasSpecificTriggers2(triggerA: number, triggerB: number): boolean {\r\n        for (let index = 0; index < this.actions.length; index++) {\r\n            const action = this.actions[index];\r\n\r\n            if (triggerA == action.trigger || triggerB == action.trigger) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Does this action manager handles actions of a given trigger\r\n     * @param trigger defines the trigger to be tested\r\n     * @param parameterPredicate defines an optional predicate to filter triggers by parameter\r\n     * @returns whether the trigger is handled\r\n     */\r\n    public hasSpecificTrigger(trigger: number, parameterPredicate?: (parameter: any) => boolean): boolean {\r\n        for (let index = 0; index < this.actions.length; index++) {\r\n            const action = this.actions[index];\r\n\r\n            if (action.trigger === trigger) {\r\n                if (parameterPredicate) {\r\n                    if (parameterPredicate(action.getTriggerParameter())) {\r\n                        return true;\r\n                    }\r\n                } else {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Does this action manager has pointer triggers\r\n     */\r\n    public get hasPointerTriggers(): boolean {\r\n        for (let index = 0; index < this.actions.length; index++) {\r\n            const action = this.actions[index];\r\n\r\n            if (action.trigger >= ActionManager.OnPickTrigger && action.trigger <= ActionManager.OnPointerOutTrigger) {\r\n                if (action._evaluateConditionForCurrentFrame()) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Does this action manager has pick triggers\r\n     */\r\n    public get hasPickTriggers(): boolean {\r\n        for (let index = 0; index < this.actions.length; index++) {\r\n            const action = this.actions[index];\r\n\r\n            if (action.trigger >= ActionManager.OnPickTrigger && action.trigger <= ActionManager.OnPickUpTrigger) {\r\n                if (action._evaluateConditionForCurrentFrame()) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Registers an action to this action manager\r\n     * @param action defines the action to be registered\r\n     * @returns the action amended (prepared) after registration\r\n     */\r\n    public registerAction(action: IAction): Nullable<IAction> {\r\n        if (action.trigger === ActionManager.OnEveryFrameTrigger) {\r\n            if (this.getScene().actionManager !== this) {\r\n                Logger.Warn(\"OnEveryFrameTrigger can only be used with scene.actionManager\");\r\n                return null;\r\n            }\r\n        }\r\n\r\n        this.actions.push(action);\r\n        this.getScene()._registeredActions++;\r\n\r\n        if (ActionManager.Triggers[action.trigger]) {\r\n            ActionManager.Triggers[action.trigger]++;\r\n        } else {\r\n            ActionManager.Triggers[action.trigger] = 1;\r\n        }\r\n\r\n        action._actionManager = this;\r\n        action._prepare();\r\n\r\n        return action;\r\n    }\r\n\r\n    /**\r\n     * Unregisters an action to this action manager\r\n     * @param action defines the action to be unregistered\r\n     * @returns a boolean indicating whether the action has been unregistered\r\n     */\r\n    public unregisterAction(action: IAction): boolean {\r\n        const index = this.actions.indexOf(action);\r\n        if (index !== -1) {\r\n            this.actions.splice(index, 1);\r\n            ActionManager.Triggers[action.trigger] -= 1;\r\n            if (ActionManager.Triggers[action.trigger] === 0) {\r\n                delete ActionManager.Triggers[action.trigger];\r\n            }\r\n            action._actionManager = null;\r\n            this.getScene()._registeredActions--;\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Process a specific trigger\r\n     * @param trigger defines the trigger to process\r\n     * @param evt defines the event details to be processed\r\n     */\r\n    public processTrigger(trigger: number, evt?: IActionEvent): void {\r\n        for (let index = 0; index < this.actions.length; index++) {\r\n            const action = this.actions[index];\r\n\r\n            if (action.trigger === trigger) {\r\n                if (evt) {\r\n                    if (trigger === ActionManager.OnKeyUpTrigger || trigger === ActionManager.OnKeyDownTrigger) {\r\n                        const parameter = action.getTriggerParameter();\r\n\r\n                        if (typeof parameter === \"function\") {\r\n                            if (!parameter(evt)) {\r\n                                continue;\r\n                            }\r\n                        } else if (parameter && parameter !== evt.sourceEvent.keyCode) {\r\n                            if (!parameter.toLowerCase) {\r\n                                continue;\r\n                            }\r\n                            const lowerCase = parameter.toLowerCase();\r\n\r\n                            if (lowerCase !== evt.sourceEvent.key) {\r\n                                const unicode = evt.sourceEvent.charCode ? evt.sourceEvent.charCode : evt.sourceEvent.keyCode;\r\n                                const actualkey = String.fromCharCode(unicode).toLowerCase();\r\n                                if (actualkey !== lowerCase) {\r\n                                    continue;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                action._executeCurrent(evt);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getEffectiveTarget(target: any, propertyPath: string): any {\r\n        const properties = propertyPath.split(\".\");\r\n\r\n        for (let index = 0; index < properties.length - 1; index++) {\r\n            target = target[properties[index]];\r\n        }\r\n\r\n        return target;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getProperty(propertyPath: string): string {\r\n        const properties = propertyPath.split(\".\");\r\n\r\n        return properties[properties.length - 1];\r\n    }\r\n\r\n    /**\r\n     * Serialize this manager to a JSON object\r\n     * @param name defines the property name to store this manager\r\n     * @returns a JSON representation of this manager\r\n     */\r\n    public serialize(name: string): any {\r\n        const root = {\r\n            children: [] as any[],\r\n            name: name,\r\n            type: 3, // Root node\r\n            properties: [] as {\r\n                name: string;\r\n                targetType: Nullable<string>;\r\n                value: string;\r\n            }[], // Empty for root but required\r\n        };\r\n\r\n        for (let i = 0; i < this.actions.length; i++) {\r\n            const triggerObject = {\r\n                type: 0, // Trigger\r\n                children: [] as any[],\r\n                name: ActionManager.GetTriggerName(this.actions[i].trigger),\r\n                properties: [] as {\r\n                    name: string;\r\n                    targetType: Nullable<string>;\r\n                    value: string;\r\n                }[],\r\n            };\r\n\r\n            const triggerOptions = this.actions[i].triggerOptions;\r\n\r\n            if (triggerOptions && typeof triggerOptions !== \"number\") {\r\n                if (triggerOptions.parameter instanceof Node) {\r\n                    triggerObject.properties.push(Action._GetTargetProperty(triggerOptions.parameter));\r\n                } else if (typeof triggerOptions.parameter === \"object\") {\r\n                    const parameter = <any>{};\r\n                    DeepCopier.DeepCopy(triggerOptions.parameter, parameter, [\"mesh\"]);\r\n\r\n                    if (triggerOptions.parameter && triggerOptions.parameter.mesh) {\r\n                        parameter._meshId = triggerOptions.parameter.mesh.id;\r\n                    }\r\n\r\n                    triggerObject.properties.push({ name: \"parameter\", targetType: null, value: parameter });\r\n                } else {\r\n                    triggerObject.properties.push({ name: \"parameter\", targetType: null, value: triggerOptions.parameter });\r\n                }\r\n            }\r\n\r\n            // Serialize child action, recursively\r\n            this.actions[i].serialize(triggerObject);\r\n\r\n            // Add serialized trigger\r\n            root.children.push(triggerObject);\r\n        }\r\n\r\n        return root;\r\n    }\r\n\r\n    /**\r\n     * Creates a new ActionManager from a JSON data\r\n     * @param parsedActions defines the JSON data to read from\r\n     * @param object defines the hosting mesh\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public static Parse(parsedActions: any, object: Nullable<AbstractMesh>, scene: Scene): void {\r\n        RegisterAction();\r\n        RegisterCondition();\r\n        RegisterDirectActions();\r\n\r\n        const actionManager = new ActionManager(scene);\r\n        if (object === null) {\r\n            scene.actionManager = actionManager;\r\n        } else {\r\n            object.actionManager = actionManager;\r\n        }\r\n\r\n        // instantiate a new object\r\n        const instantiate = (name: string, params: Array<any>): any => {\r\n            const internalClassType = GetClass(\"BABYLON.\" + name);\r\n            return internalClassType && new internalClassType(...params);\r\n        };\r\n\r\n        const parseParameter = (name: string, value: string, target: any, propertyPath: Nullable<string>): any => {\r\n            if (propertyPath === null) {\r\n                // String, boolean or float\r\n                const floatValue = parseFloat(value);\r\n\r\n                if (value === \"true\" || value === \"false\") {\r\n                    return value === \"true\";\r\n                } else {\r\n                    return isNaN(floatValue) ? value : floatValue;\r\n                }\r\n            }\r\n\r\n            const effectiveTarget = propertyPath.split(\".\");\r\n            const values = value.split(\",\");\r\n\r\n            // Get effective Target\r\n            for (let i = 0; i < effectiveTarget.length; i++) {\r\n                target = target[effectiveTarget[i]];\r\n            }\r\n\r\n            // Return appropriate value with its type\r\n            if (typeof target === \"boolean\") {\r\n                return values[0] === \"true\";\r\n            }\r\n\r\n            if (typeof target === \"string\") {\r\n                return values[0];\r\n            }\r\n\r\n            // Parameters with multiple values such as Vector3 etc.\r\n            const split: number[] = [];\r\n            for (let i = 0; i < values.length; i++) {\r\n                split.push(parseFloat(values[i]));\r\n            }\r\n\r\n            if (target instanceof Vector3) {\r\n                return Vector3.FromArray(split);\r\n            }\r\n\r\n            if (target instanceof Vector4) {\r\n                return Vector4.FromArray(split);\r\n            }\r\n\r\n            if (target instanceof Color3) {\r\n                return Color3.FromArray(split);\r\n            }\r\n\r\n            if (target instanceof Color4) {\r\n                return Color4.FromArray(split);\r\n            }\r\n\r\n            return parseFloat(values[0]);\r\n        };\r\n\r\n        // traverse graph per trigger\r\n        const traverse = (parsedAction: any, trigger: any, condition: Nullable<Condition>, action: Nullable<Action>, combineArray: Nullable<Array<Action>> = null) => {\r\n            if (parsedAction.detached) {\r\n                return;\r\n            }\r\n\r\n            const parameters: any[] = [];\r\n            let target: any = null;\r\n            let propertyPath: Nullable<string> = null;\r\n            const combine = parsedAction.combine && parsedAction.combine.length > 0;\r\n\r\n            // Parameters\r\n            if (parsedAction.type === 2) {\r\n                parameters.push(actionManager);\r\n            } else {\r\n                parameters.push(trigger);\r\n            }\r\n\r\n            if (combine) {\r\n                const actions: Action[] = [];\r\n                for (let j = 0; j < parsedAction.combine.length; j++) {\r\n                    traverse(parsedAction.combine[j], ActionManager.NothingTrigger, condition, action, actions);\r\n                }\r\n                parameters.push(actions);\r\n            } else {\r\n                for (let i = 0; i < parsedAction.properties.length; i++) {\r\n                    let value = parsedAction.properties[i].value;\r\n                    const name = parsedAction.properties[i].name;\r\n                    const targetType = parsedAction.properties[i].targetType;\r\n\r\n                    if (name === \"target\") {\r\n                        if (targetType === \"SceneProperties\") {\r\n                            value = target = scene;\r\n                        } else if (targetType === \"MaterialProperties\") {\r\n                            value = target = scene.getMaterialByName(value);\r\n                        } else {\r\n                            value = target = scene.getNodeByName(value);\r\n                        }\r\n                    } else if (name === \"parent\") {\r\n                        value = scene.getNodeByName(value);\r\n                    } else if (name === \"sound\") {\r\n                        // Can not externalize to component, so only checks for the presence off the API.\r\n                        if (_IsSideEffectImplemented(scene.getSoundByName)) {\r\n                            value = scene.getSoundByName(value);\r\n                        }\r\n                    } else if (name !== \"propertyPath\") {\r\n                        if (parsedAction.type === 2 && name === \"operator\") {\r\n                            value = (<any>ValueCondition)[value];\r\n                        } else {\r\n                            value = parseParameter(name, value, target, name === \"value\" ? propertyPath : null);\r\n                        }\r\n                    } else {\r\n                        propertyPath = value;\r\n                    }\r\n\r\n                    parameters.push(value);\r\n                }\r\n            }\r\n\r\n            if (combineArray === null) {\r\n                parameters.push(condition);\r\n            } else {\r\n                parameters.push(null);\r\n            }\r\n\r\n            // If interpolate value action\r\n            if (parsedAction.name === \"InterpolateValueAction\") {\r\n                const param = parameters[parameters.length - 2];\r\n                parameters[parameters.length - 1] = param;\r\n                parameters[parameters.length - 2] = condition;\r\n            }\r\n\r\n            // Action or condition(s) and not CombineAction\r\n            let newAction = instantiate(parsedAction.name, parameters);\r\n\r\n            if (newAction instanceof Condition && condition !== null) {\r\n                const nothing = new DoNothingAction(trigger, condition);\r\n\r\n                if (action) {\r\n                    // eslint-disable-next-line github/no-then\r\n                    action.then(nothing);\r\n                } else {\r\n                    actionManager.registerAction(nothing);\r\n                }\r\n\r\n                action = nothing;\r\n            }\r\n\r\n            if (combineArray === null) {\r\n                if (newAction instanceof Condition) {\r\n                    condition = newAction;\r\n                    newAction = action;\r\n                } else {\r\n                    condition = null;\r\n                    if (action) {\r\n                        // eslint-disable-next-line github/no-then\r\n                        action.then(newAction);\r\n                    } else {\r\n                        actionManager.registerAction(newAction);\r\n                    }\r\n                }\r\n            } else {\r\n                combineArray.push(newAction);\r\n            }\r\n\r\n            for (let i = 0; i < parsedAction.children.length; i++) {\r\n                traverse(parsedAction.children[i], trigger, condition, newAction, null);\r\n            }\r\n        };\r\n\r\n        // triggers\r\n        for (let i = 0; i < parsedActions.children.length; i++) {\r\n            let triggerParams: any;\r\n            const trigger = parsedActions.children[i];\r\n\r\n            if (trigger.properties.length > 0) {\r\n                const param = trigger.properties[0].value;\r\n                const value = trigger.properties[0].targetType === null ? param : scene.getMeshByName(param);\r\n\r\n                if (value._meshId) {\r\n                    value.mesh = scene.getMeshById(value._meshId);\r\n                }\r\n\r\n                triggerParams = { trigger: (<any>ActionManager)[trigger.name], parameter: value };\r\n            } else {\r\n                triggerParams = (<any>ActionManager)[trigger.name];\r\n            }\r\n\r\n            for (let j = 0; j < trigger.children.length; j++) {\r\n                if (!trigger.detached) {\r\n                    traverse(trigger.children[j], triggerParams, null, null);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get a trigger name by index\r\n     * @param trigger defines the trigger index\r\n     * @returns a trigger name\r\n     */\r\n    public static GetTriggerName(trigger: number): string {\r\n        switch (trigger) {\r\n            case Constants.ACTION_NothingTrigger:\r\n                return \"NothingTrigger\";\r\n            case Constants.ACTION_OnPickTrigger:\r\n                return \"OnPickTrigger\";\r\n            case Constants.ACTION_OnLeftPickTrigger:\r\n                return \"OnLeftPickTrigger\";\r\n            case Constants.ACTION_OnRightPickTrigger:\r\n                return \"OnRightPickTrigger\";\r\n            case Constants.ACTION_OnCenterPickTrigger:\r\n                return \"OnCenterPickTrigger\";\r\n            case Constants.ACTION_OnPickDownTrigger:\r\n                return \"OnPickDownTrigger\";\r\n            case Constants.ACTION_OnDoublePickTrigger:\r\n                return \"OnDoublePickTrigger\"; // start;\r\n            case Constants.ACTION_OnPickUpTrigger:\r\n                return \"OnPickUpTrigger\";\r\n            case Constants.ACTION_OnLongPressTrigger:\r\n                return \"OnLongPressTrigger\";\r\n            case Constants.ACTION_OnPointerOverTrigger:\r\n                return \"OnPointerOverTrigger\";\r\n            case Constants.ACTION_OnPointerOutTrigger:\r\n                return \"OnPointerOutTrigger\";\r\n            case Constants.ACTION_OnEveryFrameTrigger:\r\n                return \"OnEveryFrameTrigger\";\r\n            case Constants.ACTION_OnIntersectionEnterTrigger:\r\n                return \"OnIntersectionEnterTrigger\";\r\n            case Constants.ACTION_OnIntersectionExitTrigger:\r\n                return \"OnIntersectionExitTrigger\";\r\n            case Constants.ACTION_OnKeyDownTrigger:\r\n                return \"OnKeyDownTrigger\";\r\n            case Constants.ACTION_OnKeyUpTrigger:\r\n                return \"OnKeyUpTrigger\";\r\n            case Constants.ACTION_OnPickOutTrigger:\r\n                return \"OnPickOutTrigger\";\r\n            default:\r\n                return \"\";\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Action } from \"./action.pure\";\r\nimport { type Condition } from \"./condition.pure\";\r\nimport { type Sound } from \"../Audio/sound.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This defines an action helpful to play a defined sound on a triggered action.\r\n */\r\nexport class PlaySoundAction extends Action {\r\n    private _sound: Sound;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param sound defines the sound to play\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, sound: Sound, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this._sound = sound;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {}\r\n\r\n    /**\r\n     * Execute the action and play the sound.\r\n     */\r\n    public override execute(): void {\r\n        if (this._sound !== undefined) {\r\n            this._sound.play();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"PlaySoundAction\",\r\n                properties: [{ name: \"sound\", value: this._sound.name }],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * This defines an action helpful to stop a defined sound on a triggered action.\r\n */\r\nexport class StopSoundAction extends Action {\r\n    private _sound: Sound;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param sound defines the sound to stop\r\n     * @param condition defines the trigger related conditions\r\n     */\r\n    constructor(triggerOptions: any, sound: Sound, condition?: Condition) {\r\n        super(triggerOptions, condition);\r\n        this._sound = sound;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {}\r\n\r\n    /**\r\n     * Execute the action and stop the sound.\r\n     */\r\n    public override execute(): void {\r\n        if (this._sound !== undefined) {\r\n            this._sound.stop();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"StopSoundAction\",\r\n                properties: [{ name: \"sound\", value: this._sound.name }],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for directAudioActions.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDirectAudioActions(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PlaySoundAction\", PlaySoundAction);\r\n    RegisterClass(\"BABYLON.StopSoundAction\", StopSoundAction);\r\n}\r\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    if (typeof b !== \"function\" && b !== null)\r\n        throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n    function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n    var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n    var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n    var _, done = false;\r\n    for (var i = decorators.length - 1; i >= 0; i--) {\r\n        var context = {};\r\n        for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n        for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n        context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n        var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n        if (kind === \"accessor\") {\r\n            if (result === void 0) continue;\r\n            if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n            if (_ = accept(result.get)) descriptor.get = _;\r\n            if (_ = accept(result.set)) descriptor.set = _;\r\n            if (_ = accept(result.init)) initializers.unshift(_);\r\n        }\r\n        else if (_ = accept(result)) {\r\n            if (kind === \"field\") initializers.unshift(_);\r\n            else descriptor[key] = _;\r\n        }\r\n    }\r\n    if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n    done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n    var useValue = arguments.length > 2;\r\n    for (var i = 0; i < initializers.length; i++) {\r\n        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n    }\r\n    return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n    return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n    if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n    return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n    return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    var desc = Object.getOwnPropertyDescriptor(m, k);\r\n    if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n        desc = { enumerable: true, get: function() { return m[k]; } };\r\n    }\r\n    Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n        if (ar || !(i in from)) {\r\n            if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n            ar[i] = from[i];\r\n        }\r\n    }\r\n    return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n    function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n    ownKeys = Object.getOwnPropertyNames || function (o) {\r\n        var ar = [];\r\n        for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n        return ar;\r\n    };\r\n    return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n    return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n    if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n    return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n    if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n    return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n    if (value !== null && value !== void 0) {\r\n        if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n        var dispose, inner;\r\n        if (async) {\r\n            if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n            dispose = value[Symbol.asyncDispose];\r\n        }\r\n        if (dispose === void 0) {\r\n            if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n            dispose = value[Symbol.dispose];\r\n            if (async) inner = dispose;\r\n        }\r\n        if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n        env.stack.push({ value: value, dispose: dispose, async: async });\r\n    }\r\n    else if (async) {\r\n        env.stack.push({ async: true });\r\n    }\r\n    return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n    var e = new Error(message);\r\n    return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n    function fail(e) {\r\n        env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n        env.hasError = true;\r\n    }\r\n    var r, s = 0;\r\n    function next() {\r\n        while (r = env.stack.pop()) {\r\n            try {\r\n                if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n                if (r.dispose) {\r\n                    var result = r.dispose.call(r.value);\r\n                    if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n                }\r\n                else s |= 1;\r\n            }\r\n            catch (e) {\r\n                fail(e);\r\n            }\r\n        }\r\n        if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n        if (env.hasError) throw env.error;\r\n    }\r\n    return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n    if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n        return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n            return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n        });\r\n    }\r\n    return path;\r\n}\r\n\r\nexport default {\r\n    __extends: __extends,\r\n    __assign: __assign,\r\n    __rest: __rest,\r\n    __decorate: __decorate,\r\n    __param: __param,\r\n    __esDecorate: __esDecorate,\r\n    __runInitializers: __runInitializers,\r\n    __propKey: __propKey,\r\n    __setFunctionName: __setFunctionName,\r\n    __metadata: __metadata,\r\n    __awaiter: __awaiter,\r\n    __generator: __generator,\r\n    __createBinding: __createBinding,\r\n    __exportStar: __exportStar,\r\n    __values: __values,\r\n    __read: __read,\r\n    __spread: __spread,\r\n    __spreadArrays: __spreadArrays,\r\n    __spreadArray: __spreadArray,\r\n    __await: __await,\r\n    __asyncGenerator: __asyncGenerator,\r\n    __asyncDelegator: __asyncDelegator,\r\n    __asyncValues: __asyncValues,\r\n    __makeTemplateObject: __makeTemplateObject,\r\n    __importStar: __importStar,\r\n    __importDefault: __importDefault,\r\n    __classPrivateFieldGet: __classPrivateFieldGet,\r\n    __classPrivateFieldSet: __classPrivateFieldSet,\r\n    __classPrivateFieldIn: __classPrivateFieldIn,\r\n    __addDisposableResource: __addDisposableResource,\r\n    __disposeResources: __disposeResources,\r\n    __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","/**\r\n * Represents the range of an animation\r\n */\r\nexport class AnimationRange {\r\n    /**\r\n     * Initializes the range of an animation\r\n     * @param name The name of the animation range\r\n     * @param from The starting frame of the animation\r\n     * @param to The ending frame of the animation\r\n     */\r\n    constructor(\r\n        /**The name of the animation range**/\r\n        public name: string,\r\n        /**The starting frame of the animation */\r\n        public from: number,\r\n        /**The ending frame of the animation*/\r\n        public to: number\r\n    ) {}\r\n\r\n    /**\r\n     * Makes a copy of the animation range\r\n     * @returns A copy of the animation range\r\n     */\r\n    public clone(): AnimationRange {\r\n        return new AnimationRange(this.name, this.from, this.to);\r\n    }\r\n}\r\n","/**\n * Internal helpers for reading and writing decorator metadata used by serialization.\n *\n * The serialization store is attached to each class constructor via `Symbol.metadata`. The polyfill\n * required for `Symbol.metadata` lives in `symbolMetadataPolyfill.ts` and is applied at package\n * entry points.\n */\nimport { type SerializedPropertyMetadataMap } from \"./decorators.serializationUtilities\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst __bjsSerializableKey = \"__bjs_serializable__\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst _mergedStoreCache = new WeakMap<object, any>();\n\n// Universal `Object.hasOwn` equivalent. We intentionally avoid the native `Object.hasOwn` (ES2022)\n// because TypeScript does not down-level runtime APIs and some Babylon Native engines (e.g. ChakraCore)\n// do not provide it. `Object.prototype.hasOwnProperty` exists on every engine, and routing through it\n// here also stays safe for the null-prototype metadata objects created below.\nfunction HasOwn(target: object, key: PropertyKey): boolean {\n    return Object.prototype.hasOwnProperty.call(target, key);\n}\n\nfunction GetMetadataSymbol(): symbol {\n    let metadataSymbol = (Symbol as any).metadata as symbol | undefined;\n    if (!metadataSymbol) {\n        // Defensive idempotent fallback for runtimes (or import orders) where the entry-point polyfill\n        // has not yet run. Matches symbolMetadataPolyfill.ts.\n        metadataSymbol = Symbol(\"Symbol.metadata\");\n        Object.defineProperty(Symbol, \"metadata\", {\n            configurable: true,\n            writable: true,\n            value: metadataSymbol,\n        });\n    }\n    return metadataSymbol;\n}\n\n/**\n * The well-known `Symbol.metadata` symbol, resolved once at module-evaluation time.\n *\n * Reading (and thereby resolving) this symbol at module load guarantees that `Symbol.metadata`\n * exists BEFORE any decorated class which imports the decorator infrastructure evaluates its class\n * body. TypeScript's TC39 decorator emit captures `context.metadata` from `Symbol.metadata` at the\n * top of the class `static {}` block (before the decorator factory runs), so if the symbol is not\n * yet installed the metadata object is `void 0` and every metadata-based decorator throws.\n *\n * It is intentionally an exported `const` initialized from a function call: bundlers that treat this\n * module as side-effect-free may drop bare top-level calls, but they cannot drop a `const` whose\n * value is referenced by the retained decorator helpers below. The tree-shaking side-effect detector\n * likewise skips `const X = ...` initializers, so this module stays classified as pure and remains\n * importable from `.pure` modules.\n * @internal\n */\nexport const MetadataSymbol: symbol = GetMetadataSymbol();\n\n// Returns the constructor for the provided decorator/serialization target.\n// Experimental decorators pass a prototype; serialization passes an instance or a constructor.\nfunction GetConstructor(target: any): any {\n    return typeof target === \"function\" ? target : target?.constructor;\n}\n\n// Returns (creating if necessary) the metadata object owned by the given constructor.\n// The metadata's prototype mirrors the class hierarchy so merged lookups can walk it.\nfunction GetOwnMetadata(ctor: any): any {\n    if (!ctor) {\n        return undefined;\n    }\n    if (!HasOwn(ctor, MetadataSymbol)) {\n        const parent = Object.getPrototypeOf(ctor);\n        const parentMetadata = parent ? parent[MetadataSymbol] : null;\n        Object.defineProperty(ctor, MetadataSymbol, {\n            value: Object.create(parentMetadata ?? null),\n            configurable: true,\n            writable: true,\n            enumerable: false,\n        });\n    }\n    return ctor[MetadataSymbol];\n}\n\n/**\n * Returns (creating if necessary) the serialization store owned by the provided decorator metadata.\n * Used by the TC39 decorators, which receive `context.metadata` directly.\n * @internal\n */\nexport function GetDirectStoreFromMetadata(metadata: DecoratorMetadataObject): SerializedPropertyMetadataMap {\n    if (!metadata) {\n        // `metadata` is `context.metadata`, which is `void 0` when `Symbol.metadata` was not installed\n        // before the class was evaluated. Referencing `MetadataSymbol` here (a) produces an actionable\n        // error instead of a cryptic \"Cannot convert undefined to object\" and (b) keeps the module-load\n        // polyfill anchored so bundlers cannot tree-shake it away on the decorate-time serialize path.\n        throw new Error(`Decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated.`);\n    }\n    if (!HasOwn(metadata, __bjsSerializableKey)) {\n        (metadata as any)[__bjsSerializableKey] = {};\n    }\n    return (metadata as any)[__bjsSerializableKey];\n}\n\n/** @internal */\nexport function GetDirectStore(target: any): SerializedPropertyMetadataMap {\n    const metadata = GetOwnMetadata(GetConstructor(target));\n    if (!metadata) {\n        return {};\n    }\n    if (!HasOwn(metadata, __bjsSerializableKey)) {\n        metadata[__bjsSerializableKey] = {};\n    }\n    return metadata[__bjsSerializableKey];\n}\n\n/**\n * @returns the list of properties flagged as serializable\n * @param target host object\n */\nexport function GetMergedStore(target: any): SerializedPropertyMetadataMap {\n    const ctor = GetConstructor(target);\n    const metadata = ctor ? ctor[MetadataSymbol] : undefined;\n    if (!metadata) {\n        return {};\n    }\n\n    const cached = _mergedStoreCache.get(metadata);\n    if (cached) {\n        return cached;\n    }\n\n    const store: SerializedPropertyMetadataMap = {};\n    // Walk the metadata prototype chain (most derived first); parents overwrite children to match the\n    // original class-name-keyed merge order.\n    const chain: any[] = [];\n    let current: any = metadata;\n    while (current) {\n        chain.push(current);\n        current = Object.getPrototypeOf(current);\n    }\n    for (const meta of chain) {\n        if (HasOwn(meta, __bjsSerializableKey)) {\n            const initialStore = meta[__bjsSerializableKey] as SerializedPropertyMetadataMap;\n            for (const property in initialStore) {\n                store[property] = initialStore[property];\n            }\n        }\n    }\n\n    _mergedStoreCache.set(metadata, store);\n    return store;\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { GetDirectStoreFromMetadata } from \"./decorators.functions\";\r\nimport { SerializedFieldType } from \"./decorators.serializationUtilities\";\r\nimport { _WarnImport } from \"./devTools\";\r\n\r\n/**\r\n * TC39 decorator context types that serialization decorators can be applied to.\r\n * Serialization decorators can be applied to fields, getters, setters, and auto-accessors.\r\n * `metadata` can be undefined at runtime when `Symbol.metadata` is not available (e.g. tree-shaken\r\n * usage on a runtime that lacks native support and never triggered the polyfill); in that case the\r\n * serialization metadata is simply not recorded.\r\n */\r\ntype SerializableContext = { name: string | symbol; metadata: DecoratorMetadataObject | undefined };\r\n\r\nfunction generateSerializableMember(type: SerializedFieldType, sourceName?: string) {\r\n    return (_value: unknown, context: SerializableContext) => {\r\n        if (!context.metadata) {\r\n            return;\r\n        }\r\n        const propertyKey = String(context.name);\r\n        const store = GetDirectStoreFromMetadata(context.metadata);\r\n\r\n        if (!store[propertyKey]) {\r\n            store[propertyKey] = { type: type, sourceName: sourceName };\r\n        }\r\n    };\r\n}\r\n\r\nfunction generateExpandMember(setCallback: string, targetKey: Nullable<string> = null) {\r\n    return <This, V>(_value: ClassAccessorDecoratorTarget<This, V>, context: ClassAccessorDecoratorContext<This, V>): ClassAccessorDecoratorResult<This, V> => {\r\n        const key = targetKey || \"_\" + String(context.name);\r\n        return {\r\n            init(this: any, value: V) {\r\n                if (value !== undefined || !(key in this)) {\r\n                    this[key] = value;\r\n                }\r\n                return value;\r\n            },\r\n            get(this: any) {\r\n                return this[key];\r\n            },\r\n            set(this: any, value: V) {\r\n                // does this object (i.e. vector3) has an equals function? use it!\r\n                // Note - not using \"with epsilon\" here, it is expected te behave like the internal cache does.\r\n                if (typeof this[key]?.equals === \"function\") {\r\n                    if (this[key].equals(value)) {\r\n                        return;\r\n                    }\r\n                }\r\n                if (this[key] === value) {\r\n                    return;\r\n                }\r\n                this[key] = value;\r\n\r\n                this[setCallback]();\r\n            },\r\n        };\r\n    };\r\n}\r\n\r\nexport function expandToProperty(callback: string, targetKey: Nullable<string> = null) {\r\n    return generateExpandMember(callback, targetKey);\r\n}\r\n\r\nexport function serialize(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.VALUE, sourceName);\r\n}\r\n\r\nexport function serializeAsTexture(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.TEXTURE, sourceName);\r\n}\r\n\r\nexport function serializeAsColor3(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.COLOR3, sourceName);\r\n}\r\n\r\nexport function serializeAsFresnelParameters(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.FRESNEL_PARAMETERS, sourceName);\r\n}\r\n\r\nexport function serializeAsVector2(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.VECTOR2, sourceName);\r\n}\r\n\r\nexport function serializeAsVector3(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.VECTOR3, sourceName);\r\n}\r\n\r\nexport function serializeAsMeshReference(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.MESH, sourceName);\r\n}\r\n\r\nexport function serializeAsColorCurves(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.COLOR_CURVES, sourceName);\r\n}\r\n\r\nexport function serializeAsColor4(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.COLOR4, sourceName);\r\n}\r\n\r\nexport function serializeAsImageProcessingConfiguration(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.IMAGE_PROCESSING, sourceName);\r\n}\r\n\r\nexport function serializeAsQuaternion(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.QUATERNION, sourceName);\r\n}\r\n\r\nexport function serializeAsMatrix(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.MATRIX, sourceName);\r\n}\r\n\r\nexport function serializeAsVector4(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.VECTOR4, sourceName);\r\n}\r\n\r\n/**\r\n * Decorator used to define property that can be serialized as reference to a camera\r\n * @param sourceName defines the name of the property to decorate\r\n * @returns Property Decorator\r\n */\r\nexport function serializeAsCameraReference(sourceName?: string) {\r\n    return generateSerializableMember(SerializedFieldType.CAMERA, sourceName);\r\n}\r\n\r\n/** @internal */\r\ndeclare const _native: any;\r\n\r\n/**\r\n * Shared implementation for the {@link nativeOverride} decorator and its `.filter` variant.\r\n * Both flavors install a wrapper that, on first invocation, resolves the function to use once:\r\n * either the original JS function or (when running in a Babylon Native context) a native-aware\r\n * function produced by `resolveNative`. The resolved function then replaces the wrapper on the\r\n * target so subsequent calls skip this setup entirely.\r\n * @param originalMethod - The decorated JS method.\r\n * @param context - The TC39 method decorator context.\r\n * @param resolveNative - Builds the function to use when a native override is present, given the\r\n * native function and the original JS function.\r\n * @returns The wrapper function that replaces the decorated method.\r\n */\r\nfunction ApplyNativeOverride<This, Args extends any[], Return>(\r\n    originalMethod: (this: This, ...args: Args) => Return,\r\n    context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>,\r\n    resolveNative: (nativeFunc: (this: This, ...args: Args) => Return, jsFunc: (this: This, ...args: Args) => Return) => (this: This, ...args: Args) => Return\r\n): (this: This, ...args: Args) => Return {\r\n    const propertyKey = String(context.name);\r\n    let resolvedFunc: ((this: This, ...args: Args) => Return) | null = null;\r\n\r\n    const wrapper = function (this: This, ...params: Args): Return {\r\n        if (resolvedFunc === null) {\r\n            // Default to the original JS function.\r\n            resolvedFunc = originalMethod;\r\n\r\n            // Check if we are executing in a Babylon Native context and if so, check for a function override.\r\n            if (typeof _native !== \"undefined\" && _native[propertyKey]) {\r\n                resolvedFunc = resolveNative(_native[propertyKey] as (this: This, ...args: Args) => Return, originalMethod);\r\n            }\r\n\r\n            const target = (this && (context.static ? this : Object.getPrototypeOf(this))) as any;\r\n            if (target?.[propertyKey] === wrapper) {\r\n                target[propertyKey] = resolvedFunc;\r\n            }\r\n        }\r\n\r\n        return resolvedFunc.apply(this, params);\r\n    };\r\n\r\n    return wrapper;\r\n}\r\n\r\n/**\r\n * Decorator used to redirect a function to a native implementation if available.\r\n * @internal\r\n */\r\nexport function nativeOverride<This, Args extends any[], Return>(\r\n    originalMethod: (this: This, ...args: Args) => Return,\r\n    context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>\r\n): (this: This, ...args: Args) => Return {\r\n    // When a native override exists, use it directly.\r\n    return ApplyNativeOverride(originalMethod, context, (nativeFunc) => nativeFunc);\r\n}\r\n\r\n/**\r\n * Decorator factory that applies the nativeOverride decorator, but determines whether to redirect to the native implementation based on a filter function that evaluates the function arguments.\r\n * @param predicate\r\n * @example @nativeOverride.filter((arg1: string) => arg1.length > 20)\r\n *          public someMethod(arg1: string, arg2: number): string {\r\n * @internal\r\n */\r\nnativeOverride.filter = function <T extends (...params: any) => boolean>(predicate: T) {\r\n    return <This, Args extends any[], Return>(\r\n        originalMethod: (this: This, ...args: Args) => Return,\r\n        context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>\r\n    ): ((this: This, ...args: Args) => Return) => {\r\n        // When a native override exists, evaluate the predicate on each call to choose between the native and JS function.\r\n        return ApplyNativeOverride(originalMethod, context, (nativeFunc, jsFunc) => {\r\n            return function (this: This, ...args: Args): Return {\r\n                if (predicate(...(args as unknown as Parameters<T>))) {\r\n                    // The native function is invoked without a `this` binding, matching the original behavior.\r\n                    return (nativeFunc as (...args: Args) => Return)(...args);\r\n                }\r\n                return jsFunc.apply(this, args);\r\n            };\r\n        });\r\n    };\r\n};\r\n\r\n/**\r\n * Adds accessors for a material property.\r\n * Applied to an auto-accessor field. Reads/writes from a private backing field named by sourceKey (default: \"_\" + property name).\r\n * The backing field is expected to have a `.value` property.\r\n * @param setCallback - The name of the callback function to call when the property is set.\r\n * @param sourceKey - The name of the private field that stores the value (defaults to \"_\" + accessor name).\r\n * @returns An accessor decorator.\r\n */\r\nexport function addAccessorsForMaterialProperty(setCallback: string, sourceKey: Nullable<string> = null) {\r\n    return <This, V>(_value: ClassAccessorDecoratorTarget<This, V>, context: ClassAccessorDecoratorContext<This, V>): ClassAccessorDecoratorResult<This, V> => {\r\n        const key = sourceKey || \"_\" + String(context.name);\r\n        return {\r\n            get(this: any) {\r\n                return this[key]?.value;\r\n            },\r\n            set(this: any, value: V) {\r\n                // does this object (i.e. vector3) has an equals function? use it!\r\n                // Note - not using \"with epsilon\" here, it is expected te behave like the internal cache does.\r\n                if (typeof this[key]?.value?.equals === \"function\") {\r\n                    if (this[key].value.equals(value)) {\r\n                        return;\r\n                    }\r\n                }\r\n                if (this[key].value === value) {\r\n                    return;\r\n                }\r\n                this[key].value = value;\r\n\r\n                this[setCallback]();\r\n            },\r\n        };\r\n    };\r\n}\r\n","/**\r\n * Class used to evaluate queries containing `and` and `or` operators\r\n */\r\nexport class AndOrNotEvaluator {\r\n    /**\r\n     * Evaluate a query\r\n     * @param query defines the query to evaluate\r\n     * @param evaluateCallback defines the callback used to filter result\r\n     * @returns true if the query matches\r\n     */\r\n    public static Eval(query: string, evaluateCallback: (val: any) => boolean): boolean {\r\n        if (!query.match(/\\([^()]*\\)/g)) {\r\n            query = AndOrNotEvaluator._HandleParenthesisContent(query, evaluateCallback);\r\n        } else {\r\n            query = query.replace(/\\([^()]*\\)/g, (r) => {\r\n                // remove parenthesis\r\n                r = r.slice(1, r.length - 1);\r\n                return AndOrNotEvaluator._HandleParenthesisContent(r, evaluateCallback);\r\n            });\r\n        }\r\n\r\n        if (query === \"true\") {\r\n            return true;\r\n        }\r\n\r\n        if (query === \"false\") {\r\n            return false;\r\n        }\r\n\r\n        return AndOrNotEvaluator.Eval(query, evaluateCallback);\r\n    }\r\n\r\n    private static _HandleParenthesisContent(parenthesisContent: string, evaluateCallback: (val: string) => boolean): string {\r\n        evaluateCallback =\r\n            evaluateCallback ||\r\n            ((r) => {\r\n                return r === \"true\" ? true : false;\r\n            });\r\n\r\n        let result;\r\n        const or = parenthesisContent.split(\"||\");\r\n\r\n        for (const i in or) {\r\n            if (Object.prototype.hasOwnProperty.call(or, i)) {\r\n                let ori = AndOrNotEvaluator._SimplifyNegation(or[i].trim());\r\n                const and = ori.split(\"&&\");\r\n\r\n                if (and.length > 1) {\r\n                    for (let j = 0; j < and.length; ++j) {\r\n                        const andj = AndOrNotEvaluator._SimplifyNegation(and[j].trim());\r\n                        if (andj !== \"true\" && andj !== \"false\") {\r\n                            if (andj[0] === \"!\") {\r\n                                result = !evaluateCallback(andj.substring(1));\r\n                            } else {\r\n                                result = evaluateCallback(andj);\r\n                            }\r\n                        } else {\r\n                            result = andj === \"true\" ? true : false;\r\n                        }\r\n                        if (!result) {\r\n                            // no need to continue since 'false && ... && ...' will always return false\r\n                            ori = \"false\";\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (result || ori === \"true\") {\r\n                    // no need to continue since 'true || ... || ...' will always return true\r\n                    result = true;\r\n                    break;\r\n                }\r\n\r\n                // result equals false (or undefined)\r\n\r\n                if (ori !== \"true\" && ori !== \"false\") {\r\n                    if (ori[0] === \"!\") {\r\n                        result = !evaluateCallback(ori.substring(1));\r\n                    } else {\r\n                        result = evaluateCallback(ori);\r\n                    }\r\n                } else {\r\n                    result = ori === \"true\" ? true : false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // the whole parenthesis scope is replaced by 'true' or 'false'\r\n        return result ? \"true\" : \"false\";\r\n    }\r\n\r\n    private static _SimplifyNegation(booleanString: string): string {\r\n        booleanString = booleanString.replace(/^[\\s!]+/, (r) => {\r\n            // remove whitespaces\r\n            r = r.replace(/[\\s]/g, () => \"\");\r\n            return r.length % 2 ? \"!\" : \"\";\r\n        });\r\n\r\n        booleanString = booleanString.trim();\r\n\r\n        if (booleanString === \"!true\") {\r\n            booleanString = \"false\";\r\n        } else if (booleanString === \"!false\") {\r\n            booleanString = \"true\";\r\n        }\r\n\r\n        return booleanString;\r\n    }\r\n}\r\n","import { AndOrNotEvaluator } from \"./andOrNotEvaluator\";\r\n\r\n/**\r\n * Class used to store custom tags\r\n */\r\nexport class Tags {\r\n    /**\r\n     * Adds support for tags on the given object\r\n     * @param obj defines the object to use\r\n     */\r\n    public static EnableFor(obj: any): void {\r\n        obj._tags = obj._tags || {};\r\n\r\n        obj.hasTags = () => {\r\n            return Tags.HasTags(obj);\r\n        };\r\n\r\n        obj.addTags = (tagsString: string) => {\r\n            return Tags.AddTagsTo(obj, tagsString);\r\n        };\r\n\r\n        obj.removeTags = (tagsString: string) => {\r\n            return Tags.RemoveTagsFrom(obj, tagsString);\r\n        };\r\n\r\n        obj.matchesTagsQuery = (tagsQuery: string) => {\r\n            return Tags.MatchesQuery(obj, tagsQuery);\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Removes tags support\r\n     * @param obj defines the object to use\r\n     */\r\n    public static DisableFor(obj: any): void {\r\n        delete obj._tags;\r\n        delete obj.hasTags;\r\n        delete obj.addTags;\r\n        delete obj.removeTags;\r\n        delete obj.matchesTagsQuery;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the given object has tags\r\n     * @param obj defines the object to use\r\n     * @returns a boolean\r\n     */\r\n    public static HasTags(obj: any): boolean {\r\n        if (!obj._tags) {\r\n            return false;\r\n        }\r\n\r\n        const tags = obj._tags;\r\n        for (const i in tags) {\r\n            if (Object.prototype.hasOwnProperty.call(tags, i)) {\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets the tags available on a given object\r\n     * @param obj defines the object to use\r\n     * @param asString defines if the tags must be returned as a string instead of an array of strings\r\n     * @returns the tags\r\n     */\r\n    public static GetTags(obj: any, asString: boolean = true): any {\r\n        if (!obj._tags) {\r\n            return null;\r\n        }\r\n        if (asString) {\r\n            const tagsArray = [];\r\n            for (const tag in obj._tags) {\r\n                if (Object.prototype.hasOwnProperty.call(obj._tags, tag) && obj._tags[tag] === true) {\r\n                    tagsArray.push(tag);\r\n                }\r\n            }\r\n            return tagsArray.join(\" \");\r\n        } else {\r\n            return obj._tags;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds tags to an object\r\n     * @param obj defines the object to use\r\n     * @param tagsString defines the tag string. The tags 'true' and 'false' are reserved and cannot be used as tags.\r\n     * A tag cannot start with '||', '&&', and '!'. It cannot contain whitespaces\r\n     */\r\n    public static AddTagsTo(obj: any, tagsString: string): void {\r\n        if (!tagsString) {\r\n            return;\r\n        }\r\n\r\n        if (typeof tagsString !== \"string\") {\r\n            return;\r\n        }\r\n\r\n        const tags = tagsString.split(\" \");\r\n        for (const tag of tags) {\r\n            Tags._AddTagTo(obj, tag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _AddTagTo(obj: any, tag: string): void {\r\n        tag = tag.trim();\r\n\r\n        if (tag === \"\" || tag === \"true\" || tag === \"false\") {\r\n            return;\r\n        }\r\n\r\n        if (tag.match(/[\\s]/) || tag.match(/^([!]|([|]|[&]){2})/)) {\r\n            return;\r\n        }\r\n\r\n        Tags.EnableFor(obj);\r\n        obj._tags[tag] = true;\r\n    }\r\n\r\n    /**\r\n     * Removes specific tags from a specific object\r\n     * @param obj defines the object to use\r\n     * @param tagsString defines the tags to remove\r\n     */\r\n    public static RemoveTagsFrom(obj: any, tagsString: string) {\r\n        if (!Tags.HasTags(obj)) {\r\n            return;\r\n        }\r\n        const tags = tagsString.split(\" \");\r\n        for (const t in tags) {\r\n            Tags._RemoveTagFrom(obj, tags[t]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _RemoveTagFrom(obj: any, tag: string): void {\r\n        delete obj._tags[tag];\r\n    }\r\n\r\n    /**\r\n     * Defines if tags hosted on an object match a given query\r\n     * @param obj defines the object to use\r\n     * @param tagsQuery defines the tag query\r\n     * @returns a boolean\r\n     */\r\n    public static MatchesQuery(obj: any, tagsQuery: string): boolean {\r\n        if (tagsQuery === undefined) {\r\n            return true;\r\n        }\r\n\r\n        if (tagsQuery === \"\") {\r\n            return Tags.HasTags(obj);\r\n        }\r\n\r\n        return AndOrNotEvaluator.Eval(tagsQuery, (r) => Tags.HasTags(obj) && obj._tags[r]);\r\n    }\r\n}\r\n","import { type FresnelParameters } from \"../Materials/fresnelParameters\";\r\nimport { type ImageProcessingConfiguration } from \"../Materials/imageProcessingConfiguration\";\r\nimport { _WarnImport } from \"./devTools\";\r\nimport { type ColorCurves } from \"../Materials/colorCurves\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { Tags } from \"./tags\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Matrix, Quaternion, Vector2, Vector3, Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { GetMergedStore } from \"./decorators.functions\";\r\nimport { SerializedFieldType } from \"./decorators.serializationUtilities\";\r\n\r\n/** @internal */\r\nexport interface ICopySourceOptions {\r\n    /*\r\n     * if a texture is used in more than one channel (e.g diffuse and opacity),\r\n     * only clone it once and reuse it on the other channels. Default false\r\n     */\r\n    cloneTexturesOnlyOnce?: boolean;\r\n}\r\n\r\nconst CopySource = function <T>(creationFunction: () => T, source: T, instanciate: boolean, options: ICopySourceOptions = {}): T {\r\n    const destination = creationFunction();\r\n\r\n    // Tags\r\n    if (Tags && Tags.HasTags(source)) {\r\n        Tags.AddTagsTo(destination, Tags.GetTags(source, true));\r\n    }\r\n\r\n    const classStore = GetMergedStore(destination);\r\n\r\n    // Map from source texture uniqueId to destination texture\r\n    const textureMap: Record<number, any> = {};\r\n\r\n    // Properties\r\n    for (const property in classStore) {\r\n        const propertyDescriptor = classStore[property];\r\n        const sourceProperty = (<any>source)[property];\r\n        const propertyType = propertyDescriptor.type;\r\n\r\n        if (sourceProperty !== undefined && sourceProperty !== null && (property !== \"uniqueId\" || SerializationHelper.AllowLoadingUniqueId)) {\r\n            switch (propertyType) {\r\n                case SerializedFieldType.VALUE:\r\n                case SerializedFieldType.MESH:\r\n                case SerializedFieldType.IMAGE_PROCESSING:\r\n                case SerializedFieldType.CAMERA:\r\n                    if (typeof sourceProperty.slice === \"function\") {\r\n                        (<any>destination)[property] = sourceProperty.slice();\r\n                    } else {\r\n                        (<any>destination)[property] = sourceProperty;\r\n                    }\r\n                    break;\r\n                case SerializedFieldType.TEXTURE:\r\n                    if (options.cloneTexturesOnlyOnce && textureMap[sourceProperty.uniqueId]) {\r\n                        (<any>destination)[property] = textureMap[sourceProperty.uniqueId];\r\n                    } else {\r\n                        (<any>destination)[property] = instanciate || sourceProperty.isRenderTarget ? sourceProperty : sourceProperty.clone();\r\n                        textureMap[sourceProperty.uniqueId] = (<any>destination)[property];\r\n                    }\r\n                    break;\r\n                case SerializedFieldType.COLOR3:\r\n                case SerializedFieldType.FRESNEL_PARAMETERS:\r\n                case SerializedFieldType.VECTOR2:\r\n                case SerializedFieldType.VECTOR3:\r\n                case SerializedFieldType.COLOR_CURVES:\r\n                case SerializedFieldType.COLOR4:\r\n                case SerializedFieldType.QUATERNION:\r\n                case SerializedFieldType.MATRIX:\r\n                case SerializedFieldType.VECTOR4:\r\n                    (<any>destination)[property] = instanciate ? sourceProperty : sourceProperty.clone();\r\n                    break;\r\n            }\r\n        }\r\n    }\r\n\r\n    return destination;\r\n};\r\n\r\n/**\r\n * Class used to help serialization objects\r\n */\r\nexport class SerializationHelper {\r\n    /**\r\n     * Gets or sets a boolean to indicate if the UniqueId property should be serialized\r\n     */\r\n    public static AllowLoadingUniqueId = false;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _ImageProcessingConfigurationParser = (sourceProperty: any): ImageProcessingConfiguration => {\r\n        throw _WarnImport(\"ImageProcessingConfiguration\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _FresnelParametersParser = (sourceProperty: any): FresnelParameters => {\r\n        throw _WarnImport(\"FresnelParameters\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _ColorCurvesParser = (sourceProperty: any): ColorCurves => {\r\n        throw _WarnImport(\"ColorCurves\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _TextureParser = (sourceProperty: any, scene: Scene, rootUrl: string): Nullable<BaseTexture> => {\r\n        throw _WarnImport(\"Texture\");\r\n    };\r\n\r\n    /**\r\n     * Appends the serialized animations from the source animations\r\n     * @param source Source containing the animations\r\n     * @param destination Target to store the animations\r\n     */\r\n    public static AppendSerializedAnimations(source: IAnimatable, destination: any): void {\r\n        if (source.animations) {\r\n            destination.animations = [];\r\n            for (let animationIndex = 0; animationIndex < source.animations.length; animationIndex++) {\r\n                const animation = source.animations[animationIndex];\r\n\r\n                destination.animations.push(animation.serialize());\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Static function used to serialized a specific entity\r\n     * @param entity defines the entity to serialize\r\n     * @param serializationObject defines the optional target object where serialization data will be stored\r\n     * @returns a JSON compatible object representing the serialization of the entity\r\n     */\r\n    public static Serialize<T>(entity: T, serializationObject?: any): any {\r\n        if (!serializationObject) {\r\n            serializationObject = {};\r\n        }\r\n\r\n        // Tags\r\n        if (Tags) {\r\n            serializationObject.tags = Tags.GetTags(entity);\r\n        }\r\n\r\n        const serializedProperties = GetMergedStore(entity);\r\n\r\n        // Properties\r\n        for (const property in serializedProperties) {\r\n            const propertyDescriptor = serializedProperties[property];\r\n            const targetPropertyName = propertyDescriptor.sourceName || property;\r\n            const propertyType = propertyDescriptor.type;\r\n            const sourceProperty = (<any>entity)[property];\r\n\r\n            if (sourceProperty !== undefined && sourceProperty !== null && (property !== \"uniqueId\" || SerializationHelper.AllowLoadingUniqueId)) {\r\n                switch (propertyType) {\r\n                    case SerializedFieldType.VALUE:\r\n                        if (Array.isArray(sourceProperty)) {\r\n                            serializationObject[targetPropertyName] = sourceProperty.slice();\r\n                        } else {\r\n                            serializationObject[targetPropertyName] = sourceProperty;\r\n                        }\r\n                        break;\r\n                    case SerializedFieldType.TEXTURE:\r\n                        serializationObject[targetPropertyName] = sourceProperty.serialize();\r\n                        break;\r\n                    case SerializedFieldType.COLOR3:\r\n                        serializationObject[targetPropertyName] = sourceProperty.asArray();\r\n                        break;\r\n                    case SerializedFieldType.FRESNEL_PARAMETERS:\r\n                        serializationObject[targetPropertyName] = sourceProperty.serialize();\r\n                        break;\r\n                    case SerializedFieldType.VECTOR2:\r\n                        serializationObject[targetPropertyName] = sourceProperty.asArray();\r\n                        break;\r\n                    case SerializedFieldType.VECTOR3:\r\n                        serializationObject[targetPropertyName] = sourceProperty.asArray();\r\n                        break;\r\n                    case SerializedFieldType.MESH:\r\n                        serializationObject[targetPropertyName] = sourceProperty.id;\r\n                        break;\r\n                    case SerializedFieldType.COLOR_CURVES:\r\n                        serializationObject[targetPropertyName] = sourceProperty.serialize();\r\n                        break;\r\n                    case SerializedFieldType.COLOR4:\r\n                        serializationObject[targetPropertyName] = (<Color4>sourceProperty).asArray();\r\n                        break;\r\n                    case SerializedFieldType.IMAGE_PROCESSING:\r\n                        serializationObject[targetPropertyName] = (<ImageProcessingConfiguration>sourceProperty).serialize();\r\n                        break;\r\n                    case SerializedFieldType.QUATERNION:\r\n                        serializationObject[targetPropertyName] = (<Quaternion>sourceProperty).asArray();\r\n                        break;\r\n                    case SerializedFieldType.CAMERA:\r\n                        serializationObject[targetPropertyName] = (<Camera>sourceProperty).id;\r\n                        break;\r\n                    case SerializedFieldType.MATRIX:\r\n                        serializationObject[targetPropertyName] = (<Matrix>sourceProperty).asArray();\r\n                        break;\r\n                    case SerializedFieldType.VECTOR4:\r\n                        serializationObject[targetPropertyName] = (<Vector4>sourceProperty).asArray();\r\n                        break;\r\n                }\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Given a source json and a destination object in a scene, this function will parse the source and will try to apply its content to the destination object\r\n     * @param source the source json data\r\n     * @param destination the destination object\r\n     * @param scene the scene where the object is\r\n     * @param rootUrl root url to use to load assets\r\n     */\r\n    public static ParseProperties(source: any, destination: any, scene: Nullable<Scene>, rootUrl: Nullable<string>) {\r\n        if (!rootUrl) {\r\n            rootUrl = \"\";\r\n        }\r\n\r\n        const classStore = GetMergedStore(destination);\r\n\r\n        // Properties\r\n        for (const property in classStore) {\r\n            const propertyDescriptor = classStore[property];\r\n            const sourceProperty = source[propertyDescriptor.sourceName || property];\r\n            const propertyType = propertyDescriptor.type;\r\n\r\n            if (sourceProperty !== undefined && sourceProperty !== null && (property !== \"uniqueId\" || SerializationHelper.AllowLoadingUniqueId)) {\r\n                const dest = destination;\r\n                switch (propertyType) {\r\n                    case SerializedFieldType.VALUE:\r\n                        dest[property] = sourceProperty;\r\n                        break;\r\n                    case SerializedFieldType.TEXTURE:\r\n                        if (scene) {\r\n                            dest[property] = SerializationHelper._TextureParser(sourceProperty, scene, rootUrl);\r\n                        }\r\n                        break;\r\n                    case SerializedFieldType.COLOR3:\r\n                        dest[property] = Color3.FromArray(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.FRESNEL_PARAMETERS:\r\n                        dest[property] = SerializationHelper._FresnelParametersParser(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.VECTOR2:\r\n                        dest[property] = Vector2.FromArray(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.VECTOR3:\r\n                        dest[property] = Vector3.FromArray(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.MESH:\r\n                        if (scene) {\r\n                            dest[property] = scene.getLastMeshById(sourceProperty);\r\n                        }\r\n                        break;\r\n                    case SerializedFieldType.COLOR_CURVES:\r\n                        dest[property] = SerializationHelper._ColorCurvesParser(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.COLOR4:\r\n                        dest[property] = Color4.FromArray(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.IMAGE_PROCESSING:\r\n                        dest[property] = SerializationHelper._ImageProcessingConfigurationParser(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.QUATERNION:\r\n                        dest[property] = Quaternion.FromArray(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.CAMERA:\r\n                        if (scene) {\r\n                            dest[property] = scene.getCameraById(sourceProperty);\r\n                        }\r\n                        break;\r\n                    case SerializedFieldType.MATRIX:\r\n                        dest[property] = Matrix.FromArray(sourceProperty);\r\n                        break;\r\n                    case SerializedFieldType.VECTOR4:\r\n                        dest[property] = Vector4.FromArray(sourceProperty);\r\n                        break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new entity from a serialization data object\r\n     * @param creationFunction defines a function used to instanciated the new entity\r\n     * @param source defines the source serialization data\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root url for resources\r\n     * @returns a new entity\r\n     */\r\n    public static Parse<T>(creationFunction: () => T, source: any, scene: Nullable<Scene>, rootUrl: Nullable<string> = null): T {\r\n        const destination = creationFunction();\r\n\r\n        // Tags\r\n        if (Tags) {\r\n            Tags.AddTagsTo(destination, source.tags);\r\n        }\r\n\r\n        SerializationHelper.ParseProperties(source, destination, scene, rootUrl);\r\n\r\n        return destination;\r\n    }\r\n\r\n    /**\r\n     * Clones an object\r\n     * @param creationFunction defines the function used to instanciate the new object\r\n     * @param source defines the source object\r\n     * @param options defines the options to use\r\n     * @returns the cloned object\r\n     */\r\n    public static Clone<T>(creationFunction: () => T, source: T, options: ICopySourceOptions = {}): T {\r\n        return CopySource(creationFunction, source, false, options);\r\n    }\r\n\r\n    /**\r\n     * Instanciates a new object based on a source one (some data will be shared between both object)\r\n     * @param creationFunction defines the function used to instanciate the new object\r\n     * @param source defines the source object\r\n     * @returns the new object\r\n     */\r\n    public static Instanciate<T>(creationFunction: () => T, source: T): T {\r\n        return CopySource(creationFunction, source, true);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type Scene } from \"./scene\";\r\nimport { type Nullable } from \"./types\";\r\nimport { Matrix, Vector3 } from \"./Maths/math.vector.pure\";\r\nimport { type AbstractEngine } from \"./Engines/abstractEngine\";\r\nimport { type IBehaviorAware, type Behavior } from \"./Behaviors/behavior\";\r\nimport { serialize } from \"./Misc/decorators\";\r\nimport { type Observer, Observable } from \"./Misc/observable\";\r\nimport { EngineStore } from \"./Engines/engineStore\";\r\nimport { _WarnImport } from \"./Misc/devTools\";\r\nimport { type AbstractActionManager } from \"./Actions/abstractActionManager\";\r\nimport { type IInspectable } from \"./Misc/iInspectable\";\r\nimport { type IAccessibilityTag } from \"./IAccessibilityTag\";\r\nimport { type AnimationRange } from \"./Animations/animationRange\";\r\nimport { type AnimationPropertiesOverride } from \"./Animations/animationPropertiesOverride\";\r\nimport { type AbstractMesh } from \"./Meshes/abstractMesh\";\r\nimport { type Animation } from \"./Animations/animation\";\r\nimport { type Animatable } from \"./Animations/animatable.core\";\r\nimport { SerializationHelper } from \"./Misc/decorators.serialization\";\r\nimport { type IAssetContainer } from \"./IAssetContainer\";\r\n\r\n/**\r\n * Defines how a node can be built from a string name.\r\n */\r\nexport type NodeConstructor = (name: string, scene: Scene, options?: any) => () => Node;\r\n\r\n/** @internal */\r\nclass _InternalNodeDataInfo {\r\n    public _doNotSerialize = false;\r\n    public _isDisposed = false;\r\n    public _sceneRootNodesIndex = -1;\r\n    public _isEnabled = true;\r\n    public _isParentEnabled = true;\r\n    public _isReady = true;\r\n    public _onEnabledStateChangedObservable = new Observable<boolean>();\r\n    // Lazily allocated so nodes that never observe effective enabled changes pay no allocation cost.\r\n    public _onEffectiveEnabledStateChangedObservable: Nullable<Observable<boolean>> = null;\r\n    public _onClonedObservable = new Observable<Node>();\r\n    public _inheritVisibility = false;\r\n    public _isVisible = true;\r\n}\r\n\r\n/**\r\n * Node is the basic class for all scene objects (Mesh, Light, Camera.)\r\n */\r\nexport class Node implements IBehaviorAware<Node> {\r\n    protected _isDirty = false;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _AnimationRangeFactory = (_name: string, _from: number, _to: number): AnimationRange => {\r\n        throw _WarnImport(\"AnimationRange\");\r\n    };\r\n\r\n    private static _NodeConstructors: { [key: string]: any } = {};\r\n\r\n    /**\r\n     * Add a new node constructor\r\n     * @param type defines the type name of the node to construct\r\n     * @param constructorFunc defines the constructor function\r\n     */\r\n    public static AddNodeConstructor(type: string, constructorFunc: NodeConstructor) {\r\n        this._NodeConstructors[type] = constructorFunc;\r\n    }\r\n\r\n    /**\r\n     * Returns a node constructor based on type name\r\n     * @param type defines the type name\r\n     * @param name defines the new node name\r\n     * @param scene defines the hosting scene\r\n     * @param options defines optional options to transmit to constructors\r\n     * @returns the new constructor or null\r\n     */\r\n    public static Construct(type: string, name: string, scene: Scene, options?: any): Nullable<() => Node> {\r\n        const constructorFunc = this._NodeConstructors[type];\r\n\r\n        if (!constructorFunc) {\r\n            return null;\r\n        }\r\n\r\n        return constructorFunc(name, scene, options) as Nullable<() => Node>;\r\n    }\r\n\r\n    private _nodeDataStorage = new _InternalNodeDataInfo();\r\n\r\n    /**\r\n     * Gets or sets the name of the node\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * Gets or sets the id of the node\r\n     */\r\n    @serialize()\r\n    public id: string;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the node\r\n     */\r\n    @serialize()\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Gets or sets a string used to store user defined state for the node\r\n     */\r\n    @serialize()\r\n    public state = \"\";\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the node\r\n     */\r\n    @serialize()\r\n    public metadata: any = null;\r\n\r\n    /** @internal */\r\n    public _internalMetadata: any;\r\n\r\n    /**\r\n     * For internal use only. Please do not use.\r\n     */\r\n    public reservedDataStore: any = null;\r\n\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    public inspectableCustomProperties: IInspectable[];\r\n\r\n    /**\r\n     * Gets or sets the accessibility tag to describe the node for accessibility purpose.\r\n     */\r\n    public set accessibilityTag(value: Nullable<IAccessibilityTag>) {\r\n        this._accessibilityTag = value;\r\n        this.onAccessibilityTagChangedObservable.notifyObservers(value);\r\n    }\r\n\r\n    public get accessibilityTag() {\r\n        return this._accessibilityTag;\r\n    }\r\n\r\n    protected _accessibilityTag: Nullable<IAccessibilityTag> = null;\r\n\r\n    /**\r\n     * Observable fired when an accessibility tag is changed\r\n     */\r\n    public onAccessibilityTagChangedObservable = new Observable<Nullable<IAccessibilityTag>>();\r\n\r\n    /**\r\n     * Gets or sets a boolean used to define if the node must be serialized\r\n     */\r\n    public get doNotSerialize() {\r\n        if (this._nodeDataStorage._doNotSerialize) {\r\n            return true;\r\n        }\r\n\r\n        if (this._parentNode) {\r\n            return this._parentNode.doNotSerialize;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public set doNotSerialize(value: boolean) {\r\n        this._nodeDataStorage._doNotSerialize = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /**\r\n     * Gets a list of Animations associated with the node\r\n     */\r\n    public animations: Animation[] = [];\r\n    protected _ranges: { [name: string]: Nullable<AnimationRange> } = {};\r\n\r\n    /**\r\n     * Callback raised when the node is ready to be used\r\n     */\r\n    public onReady: Nullable<(node: Node) => void> = null;\r\n\r\n    /** @internal */\r\n    public _currentRenderId = -1;\r\n    private _parentUpdateId = -1;\r\n    /** @internal */\r\n    public _childUpdateId = -1;\r\n\r\n    /** @internal */\r\n    public _waitingParentId: Nullable<string> = null;\r\n    /** @internal */\r\n    public _waitingParentInstanceIndex: Nullable<string> = null;\r\n    /** @internal */\r\n    public _waitingParsedUniqueId: Nullable<number> = null;\r\n    /** @internal */\r\n    public _scene: Scene;\r\n    /** @internal */\r\n    public _cache: any = {};\r\n\r\n    protected _parentNode: Nullable<Node> = null;\r\n\r\n    /** @internal */\r\n    protected _children: Nullable<Node[]> = null;\r\n\r\n    /** @internal */\r\n    public _worldMatrix = Matrix.Identity();\r\n    /** @internal */\r\n    public _worldMatrixDeterminant = 0;\r\n    /** @internal */\r\n    public _worldMatrixDeterminantIsDirty = true;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the node has been disposed\r\n     * @returns true if the node was disposed\r\n     */\r\n    public isDisposed(): boolean {\r\n        return this._nodeDataStorage._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the parent of the node (without keeping the current position in the scene)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/parent_pivot/parent\r\n     */\r\n    public set parent(parent: Nullable<Node>) {\r\n        if (this._parentNode === parent) {\r\n            return;\r\n        }\r\n\r\n        const previousParentNode = this._parentNode;\r\n\r\n        // Remove self from list of children of parent\r\n        if (this._parentNode && this._parentNode._children !== undefined && this._parentNode._children !== null) {\r\n            const index = this._parentNode._children.indexOf(this);\r\n            if (index !== -1) {\r\n                this._parentNode._children.splice(index, 1);\r\n            }\r\n\r\n            if (!parent && !this._nodeDataStorage._isDisposed) {\r\n                this._addToSceneRootNodes();\r\n            }\r\n        }\r\n\r\n        // Store new parent\r\n        this._parentNode = parent;\r\n        this._isDirty = true;\r\n\r\n        // Add as child to new parent\r\n        if (this._parentNode) {\r\n            if (this._parentNode._children === undefined || this._parentNode._children === null) {\r\n                this._parentNode._children = new Array<Node>();\r\n            }\r\n            this._parentNode._children.push(this);\r\n\r\n            if (!previousParentNode) {\r\n                this._removeFromSceneRootNodes();\r\n            }\r\n        }\r\n\r\n        // Enabled state\r\n        this._syncParentEnabledState();\r\n    }\r\n\r\n    public get parent(): Nullable<Node> {\r\n        return this._parentNode;\r\n    }\r\n\r\n    /**\r\n     * If set to true, this node, when renderable, will only be visible if its parent(s) are also visible.\r\n     * @default false\r\n     */\r\n    public get inheritVisibility(): boolean {\r\n        return this._nodeDataStorage._inheritVisibility;\r\n    }\r\n\r\n    public set inheritVisibility(value: boolean) {\r\n        this._nodeDataStorage._inheritVisibility = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating whether this node is visible, either this node itself when it is renderable or its renderable child nodes when `inheritVisibility` is true.\r\n     * @default true\r\n     */\r\n    public get isVisible(): boolean {\r\n        if (this.inheritVisibility && this._parentNode && !this._parentNode.isVisible) {\r\n            return false;\r\n        }\r\n\r\n        return this._nodeDataStorage._isVisible;\r\n    }\r\n\r\n    public set isVisible(value: boolean) {\r\n        this._nodeDataStorage._isVisible = value;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _serializeAsParent(serializationObject: any): void {\r\n        serializationObject.parentId = this.uniqueId;\r\n    }\r\n\r\n    /** @internal */\r\n    public _addToSceneRootNodes() {\r\n        if (this._nodeDataStorage._sceneRootNodesIndex === -1) {\r\n            this._nodeDataStorage._sceneRootNodesIndex = this._scene.rootNodes.length;\r\n            this._scene.rootNodes.push(this);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _removeFromSceneRootNodes() {\r\n        if (this._nodeDataStorage._sceneRootNodesIndex !== -1) {\r\n            const rootNodes = this._scene.rootNodes;\r\n            const lastIdx = rootNodes.length - 1;\r\n            rootNodes[this._nodeDataStorage._sceneRootNodesIndex] = rootNodes[lastIdx];\r\n            rootNodes[this._nodeDataStorage._sceneRootNodesIndex]._nodeDataStorage._sceneRootNodesIndex = this._nodeDataStorage._sceneRootNodesIndex;\r\n            this._scene.rootNodes.pop();\r\n            this._nodeDataStorage._sceneRootNodesIndex = -1;\r\n        }\r\n    }\r\n\r\n    private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;\r\n\r\n    /**\r\n     * Gets or sets the animation properties override\r\n     */\r\n    public get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n        if (!this._animationPropertiesOverride) {\r\n            return this._scene.animationPropertiesOverride;\r\n        }\r\n        return this._animationPropertiesOverride;\r\n    }\r\n\r\n    public set animationPropertiesOverride(value: Nullable<AnimationPropertiesOverride>) {\r\n        this._animationPropertiesOverride = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"Node\" string\r\n     */\r\n    public getClassName(): string {\r\n        return \"Node\";\r\n    }\r\n\r\n    /** @internal */\r\n    public readonly _isNode = true;\r\n\r\n    /**\r\n     * An event triggered when the mesh is disposed\r\n     */\r\n    public onDisposeObservable = new Observable<Node>();\r\n\r\n    private _onDisposeObserver: Nullable<Observer<Node>> = null;\r\n    /**\r\n     * Sets a callback that will be raised when the node will be disposed\r\n     */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the enabled state of the node changes.\r\n     * This only reflects changes to the node's own enabled flag (as set via {@link setEnabled}), not changes inherited from an ancestor.\r\n     * Use {@link onEffectiveEnabledStateChangedObservable} to also be notified when an ancestor's enabled state changes the effective enabled state.\r\n     */\r\n    public get onEnabledStateChangedObservable(): Observable<boolean> {\r\n        return this._nodeDataStorage._onEnabledStateChangedObservable;\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the effective enabled state of the node changes, i.e. whenever the value returned by {@link isEnabled} changes.\r\n     * Unlike {@link onEnabledStateChangedObservable}, this fires for changes caused by an ancestor's enabled state as well as this node's own state.\r\n     * The observable is created on first access, so no cost is incurred for nodes that never observe it.\r\n     */\r\n    public get onEffectiveEnabledStateChangedObservable(): Observable<boolean> {\r\n        return (this._nodeDataStorage._onEffectiveEnabledStateChangedObservable ??= new Observable<boolean>());\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the node is cloned\r\n     */\r\n    public get onClonedObservable(): Observable<Node> {\r\n        return this._nodeDataStorage._onClonedObservable;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Node\r\n     * @param name the name and id to be given to this node\r\n     * @param scene the scene this node will be added to\r\n     * @param isPure indicates this Node is just a Node, and not a derived class like Mesh or Camera\r\n     */\r\n    public constructor(name: string, scene: Nullable<Scene> = null, isPure = true) {\r\n        this.name = name;\r\n        this.id = name;\r\n        this._scene = <Scene>(scene || EngineStore.LastCreatedScene);\r\n        this.uniqueId = this._scene.getUniqueId();\r\n        this._initCache();\r\n\r\n        if (isPure) {\r\n            this._addToSceneRootNodes();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the scene of the node\r\n     * @returns a scene\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets the engine of the node\r\n     * @returns a Engine\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._scene.getEngine();\r\n    }\r\n\r\n    // Behaviors\r\n    private _behaviors = new Array<Behavior<Node>>();\r\n\r\n    /**\r\n     * Attach a behavior to the node\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors\r\n     * @param behavior defines the behavior to attach\r\n     * @param attachImmediately defines that the behavior must be attached even if the scene is still loading\r\n     * @returns the current Node\r\n     */\r\n    public addBehavior(behavior: Behavior<Node>, attachImmediately = false): Node {\r\n        const index = this._behaviors.indexOf(behavior);\r\n\r\n        if (index !== -1) {\r\n            return this;\r\n        }\r\n\r\n        behavior.init();\r\n        if (this._scene.isLoading && !attachImmediately) {\r\n            // We defer the attach when the scene will be loaded\r\n            this._scene.onDataLoadedObservable.addOnce(() => {\r\n                // Make sure the behavior has not been removed.\r\n                if (this._behaviors.includes(behavior)) {\r\n                    behavior.attach(this);\r\n                }\r\n            });\r\n        } else {\r\n            behavior.attach(this);\r\n        }\r\n        this._behaviors.push(behavior);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove an attached behavior\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors\r\n     * @param behavior defines the behavior to attach\r\n     * @returns the current Node\r\n     */\r\n    public removeBehavior(behavior: Behavior<Node>): Node {\r\n        const index = this._behaviors.indexOf(behavior);\r\n\r\n        if (index === -1) {\r\n            return this;\r\n        }\r\n\r\n        // Remove the behavior from the array before calling detach so that any reentrant\r\n        // removeBehavior calls performed during detach (e.g. when a behavior owns and removes\r\n        // child behaviors of its own) operate on a consistent array and do not invalidate\r\n        // the index used for splicing here. See issue #18537.\r\n        this._behaviors.splice(index, 1);\r\n        behavior.detach();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of attached behaviors\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors\r\n     */\r\n    public get behaviors(): Behavior<Node>[] {\r\n        return this._behaviors;\r\n    }\r\n\r\n    /**\r\n     * Gets an attached behavior by name\r\n     * @param name defines the name of the behavior to look for\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors\r\n     * @returns null if behavior was not found else the requested behavior\r\n     */\r\n    public getBehaviorByName(name: string): Nullable<Behavior<Node>> {\r\n        for (const behavior of this._behaviors) {\r\n            if (behavior.name === name) {\r\n                return behavior;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Returns the latest update of the World matrix\r\n     * @returns a Matrix\r\n     */\r\n    public getWorldMatrix(): Matrix {\r\n        if (this._currentRenderId !== this._scene.getRenderId()) {\r\n            this.computeWorldMatrix();\r\n        }\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    /** @internal */\r\n    public _getWorldMatrixDeterminant(): number {\r\n        if (this._worldMatrixDeterminantIsDirty) {\r\n            this._worldMatrixDeterminantIsDirty = false;\r\n            this._worldMatrixDeterminant = this._worldMatrix.determinant();\r\n        }\r\n        return this._worldMatrixDeterminant;\r\n    }\r\n\r\n    /**\r\n     * Returns directly the latest state of the mesh World matrix.\r\n     * A Matrix is returned.\r\n     */\r\n    public get worldMatrixFromCache(): Matrix {\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    // override it in derived class if you add new variables to the cache\r\n    // and call the parent class method\r\n    /** @internal */\r\n    public _initCache() {\r\n        this._cache = {};\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public updateCache(force?: boolean): void {\r\n        if (!force && this.isSynchronized()) {\r\n            return;\r\n        }\r\n\r\n        this._updateCache();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getActionManagerForTrigger(trigger?: number, _initialCall = true): Nullable<AbstractActionManager> {\r\n        if (!this.parent) {\r\n            return null;\r\n        }\r\n\r\n        return this.parent._getActionManagerForTrigger(trigger, false);\r\n    }\r\n\r\n    // override it in derived class if you add new variables to the cache\r\n    // and call the parent class method if !ignoreParentClass\r\n    /**\r\n     * @internal\r\n     */\r\n    public _updateCache(_ignoreParentClass?: boolean): void {}\r\n\r\n    // override it in derived class if you add new variables to the cache\r\n    /** @internal */\r\n    public _isSynchronized(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _markSyncedWithParent() {\r\n        if (this._parentNode) {\r\n            this._parentUpdateId = this._parentNode._childUpdateId;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public isSynchronizedWithParent(): boolean {\r\n        if (!this._parentNode) {\r\n            return true;\r\n        }\r\n\r\n        if (this._parentNode._isDirty || this._parentUpdateId !== this._parentNode._childUpdateId) {\r\n            return false;\r\n        }\r\n\r\n        return this._parentNode.isSynchronized();\r\n    }\r\n\r\n    /** @internal */\r\n    public isSynchronized(): boolean {\r\n        if (this._parentNode && !this.isSynchronizedWithParent()) {\r\n            return false;\r\n        }\r\n\r\n        return this._isSynchronized();\r\n    }\r\n\r\n    /**\r\n     * Is this node ready to be used/rendered\r\n     * @param _completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n     * @returns true if the node is ready\r\n     */\r\n    public isReady(_completeCheck = false): boolean {\r\n        return this._nodeDataStorage._isReady;\r\n    }\r\n\r\n    /**\r\n     * Flag the  node as dirty (Forcing it to update everything)\r\n     * @param _property helps children apply precise \"dirtyfication\"\r\n     * @returns this node\r\n     */\r\n    public markAsDirty(_property?: string): Node {\r\n        this._currentRenderId = Number.MAX_VALUE;\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Is this node enabled?\r\n     * If the node has a parent, all ancestors will be checked and false will be returned if any are false (not enabled), otherwise will return true\r\n     * @param checkAncestors indicates if this method should check the ancestors. The default is to check the ancestors. If set to false, the method will return the value of this node without checking ancestors\r\n     * @returns whether this node (and its parent) is enabled\r\n     * @remarks\r\n     * To observe changes to the value returned when calling this with `checkAncestors` set to true (the default, i.e. the effective enabled state), subscribe to {@link onEffectiveEnabledStateChangedObservable}.\r\n     * To observe changes to the value returned when calling this with `checkAncestors` set to false (i.e. this node's own enabled state only), subscribe to {@link onEnabledStateChangedObservable}.\r\n     */\r\n    public isEnabled(checkAncestors: boolean = true): boolean {\r\n        if (checkAncestors === false) {\r\n            return this._nodeDataStorage._isEnabled;\r\n        }\r\n\r\n        if (!this._nodeDataStorage._isEnabled) {\r\n            return false;\r\n        }\r\n\r\n        return this._nodeDataStorage._isParentEnabled;\r\n    }\r\n\r\n    /**\r\n     * Whether the effective enabled observable exists and has at least one observer.\r\n     * Used to skip the extra work of tracking effective enabled transitions when nobody is listening.\r\n     * @returns true if the effective enabled observable exists and has at least one observer, false otherwise\r\n     */\r\n    private _hasEffectiveEnabledStateObservers(): boolean {\r\n        const observable = this._nodeDataStorage._onEffectiveEnabledStateChangedObservable;\r\n        return !!observable && observable.hasObservers();\r\n    }\r\n\r\n    /** @internal */\r\n    protected _syncParentEnabledState() {\r\n        // Only track the effective enabled transition when a listener is attached to this specific node.\r\n        // When untracked, the previous state is null to make it clear it is not a real enabled value.\r\n        const notify = this._hasEffectiveEnabledStateObservers();\r\n        const wasEnabled = notify ? this.isEnabled() : null;\r\n\r\n        this._nodeDataStorage._isParentEnabled = this._parentNode ? this._parentNode.isEnabled() : true;\r\n\r\n        if (this._children) {\r\n            for (const c of this._children) {\r\n                c._syncParentEnabledState(); // Force children to update accordingly\r\n            }\r\n        }\r\n\r\n        // An ancestor's enabled change (or a re-parent) can change this node's effective enabled state\r\n        // without its own flag changing. Notify observers of that inherited transition here. The direct\r\n        // setEnabled case is handled in setEnabled itself, so it does not double-fire from here.\r\n        if (notify) {\r\n            const isEnabled = this.isEnabled();\r\n            if (isEnabled !== wasEnabled) {\r\n                this._nodeDataStorage._onEffectiveEnabledStateChangedObservable!.notifyObservers(isEnabled);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the enabled state of this node\r\n     * @param value defines the new enabled state\r\n     */\r\n    public setEnabled(value: boolean): void {\r\n        if (this._nodeDataStorage._isEnabled === value) {\r\n            return;\r\n        }\r\n        // Capture the effective state before mutating so we can report if the current node's effective\r\n        // enabled state changed as a result of this direct change.\r\n        // When untracked, the previous state is null to make it clear it is not a real enabled value.\r\n        const notifyEffective = this._hasEffectiveEnabledStateObservers();\r\n        const wasEffectivelyEnabled = notifyEffective ? this.isEnabled() : null;\r\n\r\n        this._nodeDataStorage._isEnabled = value;\r\n        this._syncParentEnabledState();\r\n        this._nodeDataStorage._onEnabledStateChangedObservable.notifyObservers(value);\r\n\r\n        if (notifyEffective) {\r\n            const isEnabled = this.isEnabled();\r\n            if (isEnabled !== wasEffectivelyEnabled) {\r\n                this._nodeDataStorage._onEffectiveEnabledStateChangedObservable!.notifyObservers(isEnabled);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Is this node a descendant of the given node?\r\n     * The function will iterate up the hierarchy until the ancestor was found or no more parents defined\r\n     * @param ancestor defines the parent node to inspect\r\n     * @returns a boolean indicating if this node is a descendant of the given node\r\n     */\r\n    public isDescendantOf(ancestor: Node): boolean {\r\n        if (this.parent) {\r\n            if (this.parent === ancestor) {\r\n                return true;\r\n            }\r\n\r\n            return this.parent.isDescendantOf(ancestor);\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getDescendants(results: Node[], directDescendantsOnly: boolean = false, predicate?: (node: Node) => boolean): void {\r\n        if (!this._children) {\r\n            return;\r\n        }\r\n\r\n        for (let index = 0; index < this._children.length; index++) {\r\n            const item = this._children[index];\r\n\r\n            if (!predicate || predicate(item)) {\r\n                results.push(item);\r\n            }\r\n\r\n            if (!directDescendantsOnly) {\r\n                item._getDescendants(results, false, predicate);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Will return all nodes that have this node as ascendant\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @returns all children nodes of all types\r\n     */\r\n    public getDescendants<T extends Node>(directDescendantsOnly?: boolean, predicate?: (node: Node) => node is T): T[];\r\n\r\n    /**\r\n     * Will return all nodes that have this node as ascendant\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @returns all children nodes of all types\r\n     */\r\n    public getDescendants(directDescendantsOnly?: boolean, predicate?: (node: Node) => boolean): Node[];\r\n\r\n    /**\r\n     * Will return all nodes that have this node as ascendant\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @returns all children nodes of all types\r\n     */\r\n    public getDescendants(directDescendantsOnly?: boolean, predicate?: (node: Node) => boolean): Node[] {\r\n        const results: Node[] = [];\r\n\r\n        this._getDescendants(results, directDescendantsOnly, predicate);\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Get all child-meshes of this node\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: false)\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @returns an array of AbstractMesh\r\n     */\r\n    public getChildMeshes<T extends AbstractMesh>(directDescendantsOnly?: boolean, predicate?: (node: Node) => node is T): T[];\r\n\r\n    /**\r\n     * Get all child-meshes of this node\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: false)\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @returns an array of AbstractMesh\r\n     */\r\n    public getChildMeshes(directDescendantsOnly?: boolean, predicate?: (node: Node) => boolean): AbstractMesh[];\r\n\r\n    /**\r\n     * Get all child-meshes of this node\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: false)\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @returns an array of AbstractMesh\r\n     */\r\n    public getChildMeshes(directDescendantsOnly?: boolean, predicate?: (node: Node) => boolean): AbstractMesh[] {\r\n        const results: Array<AbstractMesh> = [];\r\n        this._getDescendants(results, directDescendantsOnly, (node: Node) => {\r\n            return (!predicate || predicate(node)) && (<AbstractMesh>node).cullingStrategy !== undefined;\r\n        });\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Get all direct children of this node\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: true)\r\n     * @returns an array of Node\r\n     */\r\n    public getChildren<T extends Node>(predicate?: (node: Node) => node is T, directDescendantsOnly?: boolean): T[];\r\n\r\n    /**\r\n     * Get all direct children of this node\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: true)\r\n     * @returns an array of Node\r\n     */\r\n    public getChildren(predicate?: (node: Node) => boolean, directDescendantsOnly?: boolean): Node[];\r\n\r\n    /**\r\n     * Get all direct children of this node\r\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\r\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: true)\r\n     * @returns an array of Node\r\n     */\r\n    public getChildren(predicate?: (node: Node) => boolean, directDescendantsOnly = true): Node[] {\r\n        return this.getDescendants(directDescendantsOnly, predicate);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setReady(state: boolean): void {\r\n        if (state === this._nodeDataStorage._isReady) {\r\n            return;\r\n        }\r\n\r\n        if (!state) {\r\n            this._nodeDataStorage._isReady = false;\r\n            return;\r\n        }\r\n\r\n        if (this.onReady) {\r\n            this.onReady(this);\r\n        }\r\n        this._nodeDataStorage._isReady = true;\r\n    }\r\n\r\n    /**\r\n     * Get an animation by name\r\n     * @param name defines the name of the animation to look for\r\n     * @returns null if not found else the requested animation\r\n     */\r\n    public getAnimationByName(name: string): Nullable<Animation> {\r\n        for (let i = 0; i < this.animations.length; i++) {\r\n            const animation = this.animations[i];\r\n\r\n            if (animation.name === name) {\r\n                return animation;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Creates an animation range for this node\r\n     * @param name defines the name of the range\r\n     * @param from defines the starting key\r\n     * @param to defines the end key\r\n     */\r\n    public createAnimationRange(name: string, from: number, to: number): void {\r\n        // check name not already in use\r\n        if (!this._ranges[name]) {\r\n            this._ranges[name] = Node._AnimationRangeFactory(name, from, to);\r\n            for (let i = 0, nAnimations = this.animations.length; i < nAnimations; i++) {\r\n                if (this.animations[i]) {\r\n                    this.animations[i].createRange(name, from, to);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Delete a specific animation range\r\n     * @param name defines the name of the range to delete\r\n     * @param deleteFrames defines if animation frames from the range must be deleted as well\r\n     */\r\n    public deleteAnimationRange(name: string, deleteFrames = true): void {\r\n        for (let i = 0, nAnimations = this.animations.length; i < nAnimations; i++) {\r\n            if (this.animations[i]) {\r\n                this.animations[i].deleteRange(name, deleteFrames);\r\n            }\r\n        }\r\n        this._ranges[name] = null; // said much faster than 'delete this._range[name]'\r\n    }\r\n\r\n    /**\r\n     * Get an animation range by name\r\n     * @param name defines the name of the animation range to look for\r\n     * @returns null if not found else the requested animation range\r\n     */\r\n    public getAnimationRange(name: string): Nullable<AnimationRange> {\r\n        return this._ranges[name] || null;\r\n    }\r\n\r\n    /**\r\n     * Clone the current node\r\n     * @param name Name of the new clone\r\n     * @param newParent New parent for the clone\r\n     * @param doNotCloneChildren Do not clone children hierarchy\r\n     * @returns the new transform node\r\n     */\r\n    public clone(name: string, newParent: Nullable<Node>, doNotCloneChildren?: boolean): Nullable<Node> {\r\n        const result = SerializationHelper.Clone(() => new Node(name, this.getScene()), this);\r\n\r\n        if (newParent) {\r\n            result.parent = newParent;\r\n        }\r\n\r\n        if (!doNotCloneChildren) {\r\n            // Children\r\n            const directDescendants = this.getDescendants(true);\r\n            for (let index = 0; index < directDescendants.length; index++) {\r\n                const child = directDescendants[index];\r\n\r\n                child.clone(name + \".\" + child.name, result);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of all animation ranges defined on this node\r\n     * @returns an array\r\n     */\r\n    public getAnimationRanges(): Nullable<AnimationRange>[] {\r\n        const animationRanges: Nullable<AnimationRange>[] = [];\r\n        let name: string;\r\n        for (name in this._ranges) {\r\n            animationRanges.push(this._ranges[name]);\r\n        }\r\n        return animationRanges;\r\n    }\r\n\r\n    /**\r\n     * Will start the animation sequence\r\n     * @param name defines the range frames for animation sequence\r\n     * @param loop defines if the animation should loop (false by default)\r\n     * @param speedRatio defines the speed factor in which to run the animation (1 by default)\r\n     * @param onAnimationEnd defines a function to be executed when the animation ended (undefined by default)\r\n     * @returns the object created for this animation. If range does not exist, it will return null\r\n     */\r\n    public beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): Nullable<Animatable> {\r\n        const range = this.getAnimationRange(name);\r\n\r\n        if (!range) {\r\n            return null;\r\n        }\r\n\r\n        return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);\r\n    }\r\n\r\n    /**\r\n     * Serialize animation ranges into a JSON compatible object\r\n     * @returns serialization object\r\n     */\r\n    public serializeAnimationRanges(): any {\r\n        const serializationRanges = [];\r\n        for (const name in this._ranges) {\r\n            const localRange = this._ranges[name];\r\n            if (!localRange) {\r\n                continue;\r\n            }\r\n            const range: any = {};\r\n            range.name = name;\r\n            range.from = localRange.from;\r\n            range.to = localRange.to;\r\n            serializationRanges.push(range);\r\n        }\r\n        return serializationRanges;\r\n    }\r\n\r\n    /**\r\n     * Computes the world matrix of the node\r\n     * @param _force defines if the cache version should be invalidated forcing the world matrix to be created from scratch\r\n     * @returns the world matrix\r\n     */\r\n    public computeWorldMatrix(_force?: boolean): Matrix {\r\n        if (!this._worldMatrix) {\r\n            this._worldMatrix = Matrix.Identity();\r\n        }\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    /**\r\n     * Releases resources associated with this node.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        this._nodeDataStorage._isDisposed = true;\r\n\r\n        if (!doNotRecurse) {\r\n            const nodes = this.getDescendants(true);\r\n            for (const node of nodes) {\r\n                node.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n            }\r\n        }\r\n\r\n        if (!this.parent) {\r\n            this._removeFromSceneRootNodes();\r\n        } else {\r\n            this.parent = null;\r\n        }\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n\r\n        this.onEnabledStateChangedObservable.clear();\r\n        // Access the backing field directly to avoid lazily allocating the observable during disposal.\r\n        this._nodeDataStorage._onEffectiveEnabledStateChangedObservable?.clear();\r\n        this.onClonedObservable.clear();\r\n\r\n        // Behaviors\r\n        for (const behavior of this._behaviors) {\r\n            behavior.detach();\r\n        }\r\n\r\n        this._behaviors.length = 0;\r\n\r\n        this.metadata = null;\r\n    }\r\n\r\n    /**\r\n     * Parse animation range data from a serialization object and store them into a given node\r\n     * @param node defines where to store the animation ranges\r\n     * @param parsedNode defines the serialization object to read data from\r\n     * @param _scene defines the hosting scene\r\n     */\r\n    public static ParseAnimationRanges(node: Node, parsedNode: any, _scene: Scene): void {\r\n        if (parsedNode.ranges) {\r\n            for (let index = 0; index < parsedNode.ranges.length; index++) {\r\n                const data = parsedNode.ranges[index];\r\n                node.createAnimationRange(data.name, data.from, data.to);\r\n            }\r\n        }\r\n    }\r\n    /**\r\n     * Return the minimum and maximum world vectors of the entire hierarchy under current node\r\n     * @param includeDescendants Include bounding info from descendants as well (true by default)\r\n     * @param predicate defines a callback function that can be customize to filter what meshes should be included in the list used to compute the bounding vectors\r\n     * @returns the new bounding vectors\r\n     */\r\n    public getHierarchyBoundingVectors(includeDescendants = true, predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null): { min: Vector3; max: Vector3 } {\r\n        // Ensures that all world matrix will be recomputed.\r\n        this.getScene().incrementRenderId();\r\n\r\n        this.computeWorldMatrix(true);\r\n\r\n        let min: Vector3;\r\n        let max: Vector3;\r\n\r\n        const thisAbstractMesh = this as Node as AbstractMesh;\r\n        if (thisAbstractMesh.getBoundingInfo && thisAbstractMesh.subMeshes) {\r\n            // If this is an abstract mesh get its bounding info\r\n            const boundingInfo = thisAbstractMesh.getBoundingInfo();\r\n            min = boundingInfo.boundingBox.minimumWorld.clone();\r\n            max = boundingInfo.boundingBox.maximumWorld.clone();\r\n        } else {\r\n            min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n            max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n        }\r\n\r\n        if (includeDescendants) {\r\n            const descendants = this.getDescendants(false);\r\n\r\n            for (const descendant of descendants) {\r\n                const childMesh = <AbstractMesh>descendant;\r\n                childMesh.computeWorldMatrix(true);\r\n\r\n                // Filters meshes based on custom predicate function.\r\n                if (predicate && !predicate(childMesh)) {\r\n                    continue;\r\n                }\r\n\r\n                //make sure we have the needed params to get mix and max\r\n                if (!childMesh.getBoundingInfo || childMesh.getTotalVertices() === 0) {\r\n                    continue;\r\n                }\r\n\r\n                const childBoundingInfo = childMesh.getBoundingInfo();\r\n                const boundingBox = childBoundingInfo.boundingBox;\r\n\r\n                const minBox = boundingBox.minimumWorld;\r\n                const maxBox = boundingBox.maximumWorld;\r\n\r\n                Vector3.CheckExtends(minBox, min, max);\r\n                Vector3.CheckExtends(maxBox, min, max);\r\n            }\r\n        }\r\n\r\n        return {\r\n            min: min,\r\n            max: max,\r\n        };\r\n    }\r\n}\r\n","/**\r\n * Interface for the size containing width and height\r\n */\r\nexport interface ISize {\r\n    /**\r\n     * Width\r\n     */\r\n    width: number;\r\n    /**\r\n     * Height\r\n     */\r\n    height: number;\r\n}\r\n\r\n/**\r\n * Size containing width and height\r\n */\r\nexport class Size implements ISize {\r\n    /**\r\n     * Width\r\n     */\r\n    public width: number;\r\n    /**\r\n     * Height\r\n     */\r\n    public height: number;\r\n\r\n    /**\r\n     * Creates a Size object from the given width and height (floats).\r\n     * @param width width of the new size\r\n     * @param height height of the new size\r\n     */\r\n    public constructor(width: number, height: number) {\r\n        this.width = width;\r\n        this.height = height;\r\n    }\r\n\r\n    /**\r\n     * Returns a string with the Size width and height\r\n     * @returns a string with the Size width and height\r\n     */\r\n    public toString(): string {\r\n        return `{W: ${this.width}, H: ${this.height}}`;\r\n    }\r\n    /**\r\n     * \"Size\"\r\n     * @returns the string \"Size\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Size\";\r\n    }\r\n    /**\r\n     * Returns the Size hash code.\r\n     * @returns a hash code for a unique width and height\r\n     */\r\n    public getHashCode(): number {\r\n        let hash = this.width | 0;\r\n        hash = (hash * 397) ^ (this.height | 0);\r\n        return hash;\r\n    }\r\n    /**\r\n     * Updates the current size from the given one.\r\n     * @param src the given size\r\n     */\r\n    public copyFrom(src: Size) {\r\n        this.width = src.width;\r\n        this.height = src.height;\r\n    }\r\n    /**\r\n     * Updates in place the current Size from the given floats.\r\n     * @param width width of the new size\r\n     * @param height height of the new size\r\n     * @returns the updated Size.\r\n     */\r\n    public copyFromFloats(width: number, height: number): Size {\r\n        this.width = width;\r\n        this.height = height;\r\n        return this;\r\n    }\r\n    /**\r\n     * Updates in place the current Size from the given floats.\r\n     * @param width width to set\r\n     * @param height height to set\r\n     * @returns the updated Size.\r\n     */\r\n    public set(width: number, height: number): Size {\r\n        return this.copyFromFloats(width, height);\r\n    }\r\n    /**\r\n     * Multiplies the width and height by numbers\r\n     * @param w factor to multiple the width by\r\n     * @param h factor to multiple the height by\r\n     * @returns a new Size set with the multiplication result of the current Size and the given floats.\r\n     */\r\n    public multiplyByFloats(w: number, h: number): Size {\r\n        return new Size(this.width * w, this.height * h);\r\n    }\r\n    /**\r\n     * Clones the size\r\n     * @returns a new Size copied from the given one.\r\n     */\r\n    public clone(): Size {\r\n        return new Size(this.width, this.height);\r\n    }\r\n    /**\r\n     * True if the current Size and the given one width and height are strictly equal.\r\n     * @param other the other size to compare against\r\n     * @returns True if the current Size and the given one width and height are strictly equal.\r\n     */\r\n    public equals(other: Size): boolean {\r\n        if (!other) {\r\n            return false;\r\n        }\r\n        return this.width === other.width && this.height === other.height;\r\n    }\r\n    /**\r\n     * The surface of the Size : width * height (float).\r\n     */\r\n    public get surface(): number {\r\n        return this.width * this.height;\r\n    }\r\n    /**\r\n     * Create a new size of zero\r\n     * @returns a new Size set to (0.0, 0.0)\r\n     */\r\n    public static Zero(): Size {\r\n        return new Size(0.0, 0.0);\r\n    }\r\n    /**\r\n     * Sums the width and height of two sizes\r\n     * @param otherSize size to add to this size\r\n     * @returns a new Size set as the addition result of the current Size and the given one.\r\n     */\r\n    public add(otherSize: Size): Size {\r\n        const r = new Size(this.width + otherSize.width, this.height + otherSize.height);\r\n        return r;\r\n    }\r\n    /**\r\n     * Subtracts the width and height of two\r\n     * @param otherSize size to subtract to this size\r\n     * @returns a new Size set as the subtraction result of  the given one from the current Size.\r\n     */\r\n    public subtract(otherSize: Size): Size {\r\n        const r = new Size(this.width - otherSize.width, this.height - otherSize.height);\r\n        return r;\r\n    }\r\n    /**\r\n     * Scales the width and height\r\n     * @param scale the scale to multiply the width and height by\r\n     * @returns a new Size set with the multiplication result of the current Size and the given floats.\r\n     */\r\n    public scale(scale: number): Size {\r\n        return new Size(this.width * scale, this.height * scale);\r\n    }\r\n    /**\r\n     * Creates a new Size set at the linear interpolation \"amount\" between \"start\" and \"end\"\r\n     * @param start starting size to lerp between\r\n     * @param end end size to lerp between\r\n     * @param amount amount to lerp between the start and end values\r\n     * @returns a new Size set at the linear interpolation \"amount\" between \"start\" and \"end\"\r\n     */\r\n    public static Lerp(start: Size, end: Size, amount: number): Size {\r\n        const w = start.width + (end.width - start.width) * amount;\r\n        const h = start.height + (end.height - start.height) * amount;\r\n\r\n        return new Size(w, h);\r\n    }\r\n}\r\n","import { type IWebRequest } from \"./interfaces/iWebRequest\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type INative } from \"../Engines/Native/nativeInterfaces\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const _native: INative;\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction createXMLHttpRequest(): XMLHttpRequest {\r\n    // If running in Babylon Native, then defer to the native XMLHttpRequest, which has the same public contract\r\n    if (typeof _native !== \"undefined\" && _native.XMLHttpRequest) {\r\n        return new _native.XMLHttpRequest();\r\n    } else {\r\n        return new XMLHttpRequest();\r\n    }\r\n}\r\n\r\n/**\r\n * Extended version of XMLHttpRequest with support for customizations (headers, ...)\r\n */\r\nexport class WebRequest implements IWebRequest {\r\n    private readonly _xhr = createXMLHttpRequest();\r\n\r\n    /**\r\n     * Custom HTTP Request Headers to be sent with XMLHttpRequests\r\n     * i.e. when loading files, where the server/service expects an Authorization header\r\n     */\r\n    public static CustomRequestHeaders: { [key: string]: string } = {};\r\n\r\n    /**\r\n     * Add callback functions in this array to update all the requests before they get sent to the network\r\n     */\r\n    public static CustomRequestModifiers = new Array<(request: XMLHttpRequest, url: string) => string | void>();\r\n\r\n    /**\r\n     * If set to true, requests to Babylon.js CDN requests will not be modified\r\n     */\r\n    public static SkipRequestModificationForBabylonCDN = true;\r\n\r\n    /**\r\n     * This function can be called to check if there are request modifiers for network requests\r\n     * @returns true if there are any custom requests available\r\n     */\r\n    public static get IsCustomRequestAvailable(): boolean {\r\n        return Object.keys(WebRequest.CustomRequestHeaders).length > 0 || WebRequest.CustomRequestModifiers.length > 0;\r\n    }\r\n\r\n    private static _CleanUrl(url: string): string {\r\n        url = url.replace(\"file:http:\", \"http:\");\r\n        url = url.replace(\"file:https:\", \"https:\");\r\n        return url;\r\n    }\r\n\r\n    private static _ShouldSkipRequestModifications(url: string): boolean {\r\n        return WebRequest.SkipRequestModificationForBabylonCDN && (url.includes(\"preview.babylonjs.com\") || url.includes(\"cdn.babylonjs.com\"));\r\n    }\r\n\r\n    /**\r\n     * Merges `CustomRequestHeaders` and `CustomRequestModifiers` into a plain headers record and returns the\r\n     * (possibly rewritten) URL. Can be used to apply URL and header customizations without making a network\r\n     * request (e.g. for streaming media where the download is handled by the browser natively).\r\n     * @param url - The initial URL to modify.\r\n     * @param baseHeaders - An optional set of headers to start with (e.g. from the caller's options) that modifiers can further modify.\r\n     * @returns An object containing the final URL and the merged headers after applying all modifiers and header customizations.\r\n     * @internal\r\n     */\r\n    public static _CollectCustomizations(url: string, baseHeaders: Record<string, string> = {}): { url: string; headers: Record<string, string> } {\r\n        const headers: Record<string, string> = { ...baseHeaders };\r\n\r\n        if (WebRequest._ShouldSkipRequestModifications(url)) {\r\n            return { url, headers };\r\n        }\r\n\r\n        for (const key in WebRequest.CustomRequestHeaders) {\r\n            const val = WebRequest.CustomRequestHeaders[key];\r\n            if (val) {\r\n                headers[key] = val;\r\n            }\r\n        }\r\n\r\n        // Provide a minimal proxy so modifiers can call setRequestHeader as they would on a real XHR.\r\n        const xhrProxy = {\r\n            setRequestHeader: (name: string, value: string) => {\r\n                headers[name] = value;\r\n            },\r\n        } as unknown as XMLHttpRequest;\r\n\r\n        for (const modifier of WebRequest.CustomRequestModifiers) {\r\n            if (WebRequest._ShouldSkipRequestModifications(url)) {\r\n                break;\r\n            }\r\n            const newUrl = modifier(xhrProxy, url);\r\n            if (typeof newUrl === \"string\") {\r\n                url = newUrl;\r\n            }\r\n        }\r\n\r\n        return { url, headers };\r\n    }\r\n\r\n    /**\r\n     * Performs a network request using the Fetch API when available on the platform, falling back to XMLHttpRequest.\r\n     * `WebRequest.CustomRequestHeaders` and `WebRequest.CustomRequestModifiers` are applied in both cases.\r\n     *\r\n     * For `CustomRequestModifiers`, a minimal proxy XHR is provided to each modifier so that calls to\r\n     * `setRequestHeader` on it are captured and forwarded to the underlying request. The URL returned by a\r\n     * modifier (if any) replaces the current URL before the next modifier runs.\r\n     *\r\n     * @param url - The URL to request.\r\n     * @param options - Optional request options (method, headers, body).\r\n     * @returns A Promise that resolves to a `Response`.\r\n     */\r\n    public static async FetchAsync(url: string, options: { method?: string; headers?: Record<string, string>; body?: BodyInit | null } = {}): Promise<Response> {\r\n        const method = options.method ?? \"GET\";\r\n\r\n        if (typeof fetch !== \"undefined\") {\r\n            // Use the Fetch API. Collect all customizations into a plain headers object first, since the\r\n            // Fetch API does not share the XHR instance that WebRequest.open/send work with.\r\n            const { url: resolvedUrl, headers } = WebRequest._CollectCustomizations(WebRequest._CleanUrl(url), options.headers ?? {});\r\n            return await fetch(resolvedUrl, { method, headers, body: options.body ?? undefined });\r\n        }\r\n\r\n        // Fallback: use a WebRequest instance, which handles _CleanUrl, CustomRequestModifiers and\r\n        // CustomRequestHeaders (via open()) internally — wrapping the response in a Promise<Response>.\r\n        return await new Promise<Response>((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.responseType = \"arraybuffer\";\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState === 4) {\r\n                    if (request.status >= 200 && request.status < 300) {\r\n                        const responseHeaders = typeof Headers !== \"undefined\" ? new Headers() : undefined;\r\n                        const contentType = request.getResponseHeader(\"Content-Type\");\r\n                        if (contentType && responseHeaders) {\r\n                            responseHeaders.set(\"Content-Type\", contentType);\r\n                        }\r\n                        if (typeof Response !== \"undefined\") {\r\n                            resolve(new Response(request.response as ArrayBuffer, { status: request.status, statusText: request.statusText, headers: responseHeaders }));\r\n                        } else {\r\n                            // Minimal Response-like object for environments lacking the Fetch API globals.\r\n                            resolve({\r\n                                ok: true,\r\n                                status: request.status,\r\n                                statusText: request.statusText,\r\n                                headers: { get: (name: string) => request.getResponseHeader(name) },\r\n                                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                                arrayBuffer: async () => await Promise.resolve(request.response as ArrayBuffer),\r\n                            } as unknown as Response);\r\n                        }\r\n                    } else {\r\n                        reject(new Error(`HTTP ${request.status} loading '${request.requestURL}': ${request.statusText}`));\r\n                    }\r\n                }\r\n            });\r\n            request.open(method, url, options.headers);\r\n            request.send((options.body as Document | XMLHttpRequestBodyInit | null | undefined) ?? null);\r\n        });\r\n    }\r\n\r\n    private _requestURL: string = \"\";\r\n\r\n    /**\r\n     * Returns the requested URL once open has been called\r\n     */\r\n    public get requestURL(): string {\r\n        return this._requestURL;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a function to be called when loading progress changes\r\n     */\r\n    public get onprogress(): ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null {\r\n        return this._xhr.onprogress;\r\n    }\r\n\r\n    public set onprogress(value: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null) {\r\n        this._xhr.onprogress = value;\r\n    }\r\n\r\n    /**\r\n     * Returns client's state\r\n     */\r\n    public get readyState(): number {\r\n        return this._xhr.readyState;\r\n    }\r\n\r\n    /**\r\n     * Returns client's status\r\n     */\r\n    public get status(): number {\r\n        return this._xhr.status;\r\n    }\r\n\r\n    /**\r\n     * Returns client's status as a text\r\n     */\r\n    public get statusText(): string {\r\n        return this._xhr.statusText;\r\n    }\r\n\r\n    /**\r\n     * Returns client's response\r\n     */\r\n    public get response(): any {\r\n        return this._xhr.response;\r\n    }\r\n\r\n    /**\r\n     * Returns client's response url\r\n     */\r\n    public get responseURL(): string {\r\n        return this._xhr.responseURL;\r\n    }\r\n\r\n    /**\r\n     * Returns client's response as text\r\n     */\r\n    public get responseText(): string {\r\n        return this._xhr.responseText;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the expected response type\r\n     */\r\n    public get responseType(): XMLHttpRequestResponseType {\r\n        return this._xhr.responseType;\r\n    }\r\n\r\n    public set responseType(value: XMLHttpRequestResponseType) {\r\n        this._xhr.responseType = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the timeout value in milliseconds\r\n     */\r\n    public get timeout(): number {\r\n        return this._xhr.timeout;\r\n    }\r\n\r\n    public set timeout(value: number) {\r\n        this._xhr.timeout = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public addEventListener<K extends keyof XMLHttpRequestEventMap>(\r\n        type: K,\r\n        listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any,\r\n        options?: boolean | AddEventListenerOptions\r\n    ): void;\r\n    public addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void {\r\n        this._xhr.addEventListener(type, listener, options);\r\n    }\r\n\r\n    /** @internal */\r\n    public removeEventListener<K extends keyof XMLHttpRequestEventMap>(\r\n        type: K,\r\n        listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any,\r\n        options?: boolean | EventListenerOptions\r\n    ): void;\r\n    public removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void {\r\n        this._xhr.removeEventListener(type, listener, options);\r\n    }\r\n\r\n    /**\r\n     * Cancels any network activity\r\n     */\r\n    public abort() {\r\n        this._xhr.abort();\r\n    }\r\n\r\n    /**\r\n     * Initiates the request. The optional argument provides the request body. The argument is ignored if request method is GET or HEAD\r\n     * @param body defines an optional request body\r\n     */\r\n    public send(body?: Document | XMLHttpRequestBodyInit | null): void {\r\n        this._xhr.send(body);\r\n    }\r\n\r\n    /**\r\n     * Sets the request method, request URL\r\n     * @param method defines the method to use (GET, POST, etc..)\r\n     * @param url defines the url to connect with\r\n     * @param baseHeaders optional headers to include as a base before applying CustomRequestHeaders and modifiers\r\n     */\r\n    public open(method: string, url: string, baseHeaders?: Record<string, string>): void {\r\n        const { url: modifiedUrl, headers } = WebRequest._CollectCustomizations(url, baseHeaders);\r\n\r\n        this._requestURL = WebRequest._CleanUrl(modifiedUrl);\r\n\r\n        this._xhr.open(method, this._requestURL, true);\r\n\r\n        // Apply the collected headers (CustomRequestHeaders + modifier-set headers) to the XHR.\r\n        // Must happen after open() and before send().\r\n        for (const key in headers) {\r\n            this._xhr.setRequestHeader(key, headers[key]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the value of a request header.\r\n     * @param name The name of the header whose value is to be set\r\n     * @param value The value to set as the body of the header\r\n     */\r\n    setRequestHeader(name: string, value: string): void {\r\n        this._xhr.setRequestHeader(name, value);\r\n    }\r\n\r\n    /**\r\n     * Get the string containing the text of a particular header's value.\r\n     * @param name The name of the header\r\n     * @returns The string containing the text of the given header name\r\n     */\r\n    getResponseHeader(name: string): Nullable<string> {\r\n        return this._xhr.getResponseHeader(name);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IEasingFunction, type EasingFunction } from \"./easing\";\r\nimport { Vector3, Quaternion, Vector2, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Hermite, Lerp } from \"../Maths/math.scalar.functions\";\r\nimport { type DeepImmutable, type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { AnimationKeyInterpolation, type IAnimationKey } from \"./animationKey\";\r\n\r\nimport { AnimationRange } from \"./animationRange\";\r\nimport { type AnimationEvent } from \"./animationEvent\";\r\nimport { Node } from \"../node\";\r\nimport { type IAnimatable } from \"./animatable.interface\";\r\nimport { Size } from \"../Maths/math.size\";\r\nimport { WebRequest } from \"../Misc/webRequest\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Animatable } from \"./animatable.pure\";\r\nimport { type RuntimeAnimation } from \"./runtimeAnimation\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n// Static values to help the garbage collector\r\n\r\n// Quaternion\r\nexport const _StaticOffsetValueQuaternion: DeepImmutable<Quaternion> = Object.freeze(new Quaternion(0, 0, 0, 0));\r\n\r\n// Vector3\r\nexport const _StaticOffsetValueVector3: DeepImmutable<Vector3> = Object.freeze(Vector3.Zero());\r\n\r\n// Vector2\r\nexport const _StaticOffsetValueVector2: DeepImmutable<Vector2> = Object.freeze(Vector2.Zero());\r\n\r\n// Size\r\nexport const _StaticOffsetValueSize: DeepImmutable<Size> = Object.freeze(Size.Zero());\r\n\r\n// Color3\r\nexport const _StaticOffsetValueColor3: DeepImmutable<Color3> = Object.freeze(Color3.Black());\r\n\r\n// Color4\r\nexport const _StaticOffsetValueColor4: DeepImmutable<Color4> = Object.freeze(new Color4(0, 0, 0, 0));\r\n\r\n/**\r\n * Options to be used when creating an additive animation\r\n */\r\nexport interface IMakeAnimationAdditiveOptions {\r\n    /**\r\n     * The frame that the animation should be relative to (if not provided, 0 will be used)\r\n     */\r\n    referenceFrame?: number;\r\n    /**\r\n     * The name of the animation range to convert to additive. If not provided, fromFrame / toFrame will be used\r\n     * If fromFrame / toFrame are not provided either, the whole animation will be converted to additive\r\n     */\r\n    range?: string;\r\n    /**\r\n     * If true, the original animation will be cloned and converted to additive. If false, the original animation will be converted to additive (default is false)\r\n     */\r\n    cloneOriginalAnimation?: boolean;\r\n    /**\r\n     * The name of the cloned animation if cloneOriginalAnimation is true. If not provided, use the original animation name\r\n     */\r\n    clonedAnimationName?: string;\r\n    /**\r\n     * Together with toFrame, defines the range of the animation to convert to additive. Will only be used if range is not provided\r\n     * If range and fromFrame / toFrame are not provided, the whole animation will be converted to additive\r\n     */\r\n    fromFrame?: number;\r\n    /**\r\n     * Together with fromFrame, defines the range of the animation to convert to additive.\r\n     */\r\n    toFrame?: number;\r\n    /**\r\n     * If true, the key frames will be clipped to the range specified by range or fromFrame / toFrame (default is false)\r\n     */\r\n    clipKeys?: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface _IAnimationState {\r\n    key: number;\r\n    repeatCount: number;\r\n    workValue?: any;\r\n    loopMode?: number;\r\n    offsetValue?: any;\r\n    highLimitValue?: any;\r\n}\r\n\r\nconst EvaluateAnimationState: _IAnimationState = {\r\n    key: 0,\r\n    repeatCount: 0,\r\n    loopMode: 2 /*Animation.ANIMATIONLOOPMODE_CONSTANT*/,\r\n};\r\n\r\n/**\r\n * Class used to store any kind of animation\r\n */\r\nexport class Animation {\r\n    private static _UniqueIdGenerator = 0;\r\n\r\n    /**\r\n     * Use matrix interpolation instead of using direct key value when animating matrices\r\n     */\r\n    public static AllowMatricesInterpolation = false;\r\n\r\n    /**\r\n     * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower\r\n     */\r\n    public static AllowMatrixDecomposeForInterpolation = true;\r\n\r\n    /**\r\n     * When true, starting a new animation on a property that is already being animated\r\n     * will inherit the original value from the active animation instead of snapshotting\r\n     * the current (mid-animation) value. This prevents properties (e.g. morph target\r\n     * influence) from permanently sticking at intermediate values when animations\r\n     * overlap or interrupt each other.\r\n     * @see https://playground.babylonjs.com/#6A16YD#0\r\n     */\r\n    public static InheritOriginalValueFromActiveAnimations = false;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the animation (the uniqueness is solely among other animations)\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /** Define the Url to load snippets */\r\n    public static SnippetUrl = Constants.SnippetUrl;\r\n\r\n    /** Snippet ID if the animation was created from the snippet server */\r\n    public snippetId: string;\r\n\r\n    /**\r\n     * Stores the key frames of the animation\r\n     */\r\n    private _keys: Array<IAnimationKey>;\r\n\r\n    /**\r\n     * Stores the easing function of the animation\r\n     */\r\n    private _easingFunction: Nullable<IEasingFunction> = null;\r\n\r\n    /**\r\n     * @internal Internal use only\r\n     */\r\n    public _runtimeAnimations = new Array<RuntimeAnimation>();\r\n\r\n    /**\r\n     * The set of event that will be linked to this animation\r\n     */\r\n    private _events = new Array<AnimationEvent>();\r\n\r\n    /**\r\n     * Stores an array of target property paths\r\n     */\r\n    public targetPropertyPath: string[];\r\n\r\n    /**\r\n     * Stores the blending speed of the animation\r\n     */\r\n    public blendingSpeed = 0.01;\r\n\r\n    /**\r\n     * Stores the animation ranges for the animation\r\n     */\r\n    private _ranges: { [name: string]: Nullable<AnimationRange> } = {};\r\n\r\n    /** @internal */\r\n    public _coreAnimation: Nullable<Animation> = null;\r\n\r\n    /**\r\n     * @internal Internal use\r\n     */\r\n    public static _PrepareAnimation(\r\n        name: string,\r\n        targetProperty: string,\r\n        framePerSecond: number,\r\n        totalFrame: number,\r\n        from: any,\r\n        to: any,\r\n        loopMode?: number,\r\n        easingFunction?: EasingFunction\r\n    ): Nullable<Animation> {\r\n        let dataType = undefined;\r\n\r\n        if (!isNaN(parseFloat(from)) && isFinite(from)) {\r\n            dataType = Animation.ANIMATIONTYPE_FLOAT;\r\n        } else if (from instanceof Quaternion) {\r\n            dataType = Animation.ANIMATIONTYPE_QUATERNION;\r\n        } else if (from instanceof Vector3) {\r\n            dataType = Animation.ANIMATIONTYPE_VECTOR3;\r\n        } else if (from instanceof Vector2) {\r\n            dataType = Animation.ANIMATIONTYPE_VECTOR2;\r\n        } else if (from instanceof Color3) {\r\n            dataType = Animation.ANIMATIONTYPE_COLOR3;\r\n        } else if (from instanceof Color4) {\r\n            dataType = Animation.ANIMATIONTYPE_COLOR4;\r\n        } else if (from instanceof Size) {\r\n            dataType = Animation.ANIMATIONTYPE_SIZE;\r\n        }\r\n\r\n        if (dataType == undefined) {\r\n            return null;\r\n        }\r\n\r\n        const animation = new Animation(name, targetProperty, framePerSecond, dataType, loopMode);\r\n\r\n        const keys: Array<IAnimationKey> = [\r\n            { frame: 0, value: from },\r\n            { frame: totalFrame, value: to },\r\n        ];\r\n        animation.setKeys(keys);\r\n\r\n        if (easingFunction !== undefined) {\r\n            animation.setEasingFunction(easingFunction);\r\n        }\r\n\r\n        return animation;\r\n    }\r\n\r\n    /**\r\n     * Return the array of runtime animations currently using this animation\r\n     */\r\n    public get runtimeAnimations(): RuntimeAnimation[] {\r\n        return this._runtimeAnimations;\r\n    }\r\n\r\n    /**\r\n     * Specifies if any of the runtime animations are currently running\r\n     */\r\n    public get hasRunningRuntimeAnimations(): boolean {\r\n        for (const runtimeAnimation of this._runtimeAnimations) {\r\n            if (!runtimeAnimation.isStopped()) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Initializes the animation\r\n     * @param name Name of the animation\r\n     * @param targetProperty Property to animate\r\n     * @param framePerSecond The frames per second of the animation\r\n     * @param dataType The data type of the animation\r\n     * @param loopMode The loop mode of the animation\r\n     * @param enableBlending Specifies if blending should be enabled\r\n     */\r\n    constructor(\r\n        /**Name of the animation */\r\n        public name: string,\r\n        /**Property to animate */\r\n        public targetProperty: string,\r\n        /**The frames per second of the animation */\r\n        public framePerSecond: number,\r\n        /**The data type of the animation */\r\n        public dataType: number,\r\n        /**The loop mode of the animation */\r\n        public loopMode?: number,\r\n        /**Specifies if blending should be enabled */\r\n        public enableBlending?: boolean\r\n    ) {\r\n        this.targetPropertyPath = targetProperty.split(\".\");\r\n        this.dataType = dataType;\r\n        this.loopMode = loopMode === undefined ? Animation.ANIMATIONLOOPMODE_CYCLE : loopMode;\r\n        this.uniqueId = Animation._UniqueIdGenerator++;\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Converts the animation to a string\r\n     * @param fullDetails support for multiple levels of logging within scene loading\r\n     * @returns String form of the animation\r\n     */\r\n    public toString(fullDetails?: boolean): string {\r\n        let ret = \"Name: \" + this.name + \", property: \" + this.targetProperty;\r\n        ret += \", datatype: \" + [\"Float\", \"Vector3\", \"Quaternion\", \"Matrix\", \"Color3\", \"Vector2\"][this.dataType];\r\n        ret += \", nKeys: \" + (this._keys ? this._keys.length : \"none\");\r\n        ret += \", nRanges: \" + (this._ranges ? Object.keys(this._ranges).length : \"none\");\r\n        if (fullDetails) {\r\n            ret += \", Ranges: {\";\r\n            let first = true;\r\n            for (const name in this._ranges) {\r\n                if (!first) {\r\n                    ret += \", \";\r\n                }\r\n                first = false;\r\n                ret += name;\r\n            }\r\n            ret += \"}\";\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Add an event to this animation\r\n     * @param event Event to add\r\n     */\r\n    public addEvent(event: AnimationEvent): void {\r\n        this._events.push(event);\r\n        this._events.sort((a, b) => a.frame - b.frame);\r\n    }\r\n\r\n    /**\r\n     * Remove all events found at the given frame\r\n     * @param frame The frame to remove events from\r\n     */\r\n    public removeEvents(frame: number): void {\r\n        for (let index = 0; index < this._events.length; index++) {\r\n            if (this._events[index].frame === frame) {\r\n                this._events.splice(index, 1);\r\n                index--;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Retrieves all the events from the animation\r\n     * @returns Events from the animation\r\n     */\r\n    public getEvents(): AnimationEvent[] {\r\n        return this._events;\r\n    }\r\n\r\n    /**\r\n     * Creates an animation range\r\n     * @param name Name of the animation range\r\n     * @param from Starting frame of the animation range\r\n     * @param to Ending frame of the animation\r\n     */\r\n    public createRange(name: string, from: number, to: number): void {\r\n        // check name not already in use; could happen for bones after serialized\r\n        if (!this._ranges[name]) {\r\n            this._ranges[name] = new AnimationRange(name, from, to);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Deletes an animation range by name\r\n     * @param name Name of the animation range to delete\r\n     * @param deleteFrames Specifies if the key frames for the range should also be deleted (true) or not (false)\r\n     */\r\n    public deleteRange(name: string, deleteFrames = true): void {\r\n        const range = this._ranges[name];\r\n        if (!range) {\r\n            return;\r\n        }\r\n        if (deleteFrames) {\r\n            const from = range.from;\r\n            const to = range.to;\r\n\r\n            // this loop MUST go high to low for multiple splices to work\r\n            for (let key = this._keys.length - 1; key >= 0; key--) {\r\n                if (this._keys[key].frame >= from && this._keys[key].frame <= to) {\r\n                    this._keys.splice(key, 1);\r\n                }\r\n            }\r\n        }\r\n        this._ranges[name] = null; // said much faster than 'delete this._range[name]'\r\n    }\r\n\r\n    /**\r\n     * Gets the animation range by name, or null if not defined\r\n     * @param name Name of the animation range\r\n     * @returns Nullable animation range\r\n     */\r\n    public getRange(name: string): Nullable<AnimationRange> {\r\n        return this._ranges[name];\r\n    }\r\n\r\n    /**\r\n     * Gets the key frames from the animation\r\n     * @returns The key frames of the animation\r\n     */\r\n    public getKeys(): Array<IAnimationKey> {\r\n        return this._keys;\r\n    }\r\n\r\n    /**\r\n     * Gets the highest frame of the animation\r\n     * @returns Highest frame of the animation\r\n     */\r\n    public getHighestFrame(): number {\r\n        let ret = 0;\r\n\r\n        for (let key = 0, nKeys = this._keys.length; key < nKeys; key++) {\r\n            if (ret < this._keys[key].frame) {\r\n                ret = this._keys[key].frame;\r\n            }\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Gets the easing function of the animation\r\n     * @returns Easing function of the animation\r\n     */\r\n    public getEasingFunction(): Nullable<IEasingFunction> {\r\n        return this._easingFunction;\r\n    }\r\n\r\n    /**\r\n     * Sets the easing function of the animation\r\n     * @param easingFunction A custom mathematical formula for animation\r\n     */\r\n    public setEasingFunction(easingFunction: Nullable<IEasingFunction>): void {\r\n        this._easingFunction = easingFunction;\r\n    }\r\n\r\n    /**\r\n     * Interpolates a scalar linearly\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated scalar value\r\n     */\r\n    public floatInterpolateFunction(startValue: number, endValue: number, gradient: number): number {\r\n        return Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a scalar cubically\r\n     * @param startValue Start value of the animation curve\r\n     * @param outTangent End tangent of the animation\r\n     * @param endValue End value of the animation curve\r\n     * @param inTangent Start tangent of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated scalar value\r\n     */\r\n    public floatInterpolateFunctionWithTangents(startValue: number, outTangent: number, endValue: number, inTangent: number, gradient: number): number {\r\n        return Hermite(startValue, outTangent, endValue, inTangent, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a quaternion using a spherical linear interpolation\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated quaternion value\r\n     */\r\n    public quaternionInterpolateFunction(startValue: Quaternion, endValue: Quaternion, gradient: number): Quaternion {\r\n        return Quaternion.Slerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a quaternion cubically\r\n     * @param startValue Start value of the animation curve\r\n     * @param outTangent End tangent of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param inTangent Start tangent of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated quaternion value\r\n     */\r\n    public quaternionInterpolateFunctionWithTangents(startValue: Quaternion, outTangent: Quaternion, endValue: Quaternion, inTangent: Quaternion, gradient: number): Quaternion {\r\n        return Quaternion.Hermite(startValue, outTangent, endValue, inTangent, gradient).normalize();\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Vector3 linearly\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate (value between 0 and 1)\r\n     * @returns Interpolated scalar value\r\n     */\r\n    public vector3InterpolateFunction(startValue: Vector3, endValue: Vector3, gradient: number): Vector3 {\r\n        return Vector3.Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Vector3 cubically\r\n     * @param startValue Start value of the animation curve\r\n     * @param outTangent End tangent of the animation\r\n     * @param endValue End value of the animation curve\r\n     * @param inTangent Start tangent of the animation curve\r\n     * @param gradient Scalar amount to interpolate (value between 0 and 1)\r\n     * @returns InterpolatedVector3 value\r\n     */\r\n    public vector3InterpolateFunctionWithTangents(startValue: Vector3, outTangent: Vector3, endValue: Vector3, inTangent: Vector3, gradient: number): Vector3 {\r\n        return Vector3.Hermite(startValue, outTangent, endValue, inTangent, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Vector2 linearly\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate (value between 0 and 1)\r\n     * @returns Interpolated Vector2 value\r\n     */\r\n    public vector2InterpolateFunction(startValue: Vector2, endValue: Vector2, gradient: number): Vector2 {\r\n        return Vector2.Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Vector2 cubically\r\n     * @param startValue Start value of the animation curve\r\n     * @param outTangent End tangent of the animation\r\n     * @param endValue End value of the animation curve\r\n     * @param inTangent Start tangent of the animation curve\r\n     * @param gradient Scalar amount to interpolate (value between 0 and 1)\r\n     * @returns Interpolated Vector2 value\r\n     */\r\n    public vector2InterpolateFunctionWithTangents(startValue: Vector2, outTangent: Vector2, endValue: Vector2, inTangent: Vector2, gradient: number): Vector2 {\r\n        return Vector2.Hermite(startValue, outTangent, endValue, inTangent, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a size linearly\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated Size value\r\n     */\r\n    public sizeInterpolateFunction(startValue: Size, endValue: Size, gradient: number): Size {\r\n        return Size.Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Color3 linearly\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated Color3 value\r\n     */\r\n    public color3InterpolateFunction(startValue: Color3, endValue: Color3, gradient: number): Color3 {\r\n        return Color3.Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Color3 cubically\r\n     * @param startValue Start value of the animation curve\r\n     * @param outTangent End tangent of the animation\r\n     * @param endValue End value of the animation curve\r\n     * @param inTangent Start tangent of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns interpolated value\r\n     */\r\n    public color3InterpolateFunctionWithTangents(startValue: Color3, outTangent: Color3, endValue: Color3, inTangent: Color3, gradient: number): Color3 {\r\n        return Color3.Hermite(startValue, outTangent, endValue, inTangent, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Color4 linearly\r\n     * @param startValue Start value of the animation curve\r\n     * @param endValue End value of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns Interpolated Color3 value\r\n     */\r\n    public color4InterpolateFunction(startValue: Color4, endValue: Color4, gradient: number): Color4 {\r\n        return Color4.Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Interpolates a Color4 cubically\r\n     * @param startValue Start value of the animation curve\r\n     * @param outTangent End tangent of the animation\r\n     * @param endValue End value of the animation curve\r\n     * @param inTangent Start tangent of the animation curve\r\n     * @param gradient Scalar amount to interpolate\r\n     * @returns interpolated value\r\n     */\r\n    public color4InterpolateFunctionWithTangents(startValue: Color4, outTangent: Color4, endValue: Color4, inTangent: Color4, gradient: number): Color4 {\r\n        return Color4.Hermite(startValue, outTangent, endValue, inTangent, gradient);\r\n    }\r\n\r\n    /**\r\n     * @internal Internal use only\r\n     */\r\n    public _getKeyValue(value: any): any {\r\n        if (typeof value === \"function\") {\r\n            return value();\r\n        }\r\n\r\n        return value;\r\n    }\r\n\r\n    /**\r\n     * Evaluate the animation value at a given frame\r\n     * @param currentFrame defines the frame where we want to evaluate the animation\r\n     * @returns the animation value\r\n     */\r\n    public evaluate(currentFrame: number) {\r\n        EvaluateAnimationState.key = 0;\r\n        return this._interpolate(currentFrame, EvaluateAnimationState);\r\n    }\r\n\r\n    /** @internal */\r\n    public _key: number;\r\n\r\n    /**\r\n     * @internal Internal use only\r\n     */\r\n    public _interpolate(currentFrame: number, state: _IAnimationState, searchClosestKeyOnly = false): any {\r\n        if (state.loopMode === Animation.ANIMATIONLOOPMODE_CONSTANT && state.repeatCount > 0) {\r\n            return state.highLimitValue.clone ? state.highLimitValue.clone() : state.highLimitValue;\r\n        }\r\n\r\n        const keys = this._keys;\r\n        let key: number;\r\n\r\n        if (!this._coreAnimation) {\r\n            const keysLength = keys.length;\r\n\r\n            key = state.key;\r\n\r\n            while (key >= 0 && currentFrame < keys[key].frame) {\r\n                --key;\r\n            }\r\n\r\n            while (key + 1 <= keysLength - 1 && currentFrame >= keys[key + 1].frame) {\r\n                ++key;\r\n            }\r\n\r\n            state.key = key;\r\n\r\n            if (key < 0) {\r\n                return searchClosestKeyOnly ? undefined : this._getKeyValue(keys[0].value);\r\n            } else if (key + 1 > keysLength - 1) {\r\n                return searchClosestKeyOnly ? undefined : this._getKeyValue(keys[keysLength - 1].value);\r\n            }\r\n\r\n            this._key = key;\r\n        } else {\r\n            key = this._coreAnimation._key;\r\n        }\r\n\r\n        const startKey = keys[key];\r\n        const endKey = keys[key + 1];\r\n\r\n        if (searchClosestKeyOnly && (currentFrame === startKey.frame || currentFrame === endKey.frame)) {\r\n            return undefined;\r\n        }\r\n        const startValue = this._getKeyValue(startKey.value);\r\n        const endValue = this._getKeyValue(endKey.value);\r\n        if (startKey.interpolation === AnimationKeyInterpolation.STEP) {\r\n            if (endKey.frame > currentFrame) {\r\n                return startValue;\r\n            } else {\r\n                return endValue;\r\n            }\r\n        }\r\n\r\n        const useTangent = startKey.outTangent !== undefined && endKey.inTangent !== undefined;\r\n        const frameDelta = endKey.frame - startKey.frame;\r\n\r\n        // gradient : percent of currentFrame between the frame inf and the frame sup\r\n        let gradient = (currentFrame - startKey.frame) / frameDelta;\r\n\r\n        // check for easingFunction and correction of gradient\r\n        const easingFunction = startKey.easingFunction || this.getEasingFunction();\r\n        // can also be undefined, if not provided\r\n        if (easingFunction) {\r\n            gradient = easingFunction.ease(gradient);\r\n        }\r\n\r\n        switch (this.dataType) {\r\n            // Float\r\n            case Animation.ANIMATIONTYPE_FLOAT: {\r\n                const floatValue = useTangent\r\n                    ? this.floatInterpolateFunctionWithTangents(startValue, startKey.outTangent * frameDelta, endValue, endKey.inTangent * frameDelta, gradient)\r\n                    : this.floatInterpolateFunction(startValue, endValue, gradient);\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return floatValue;\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return (state.offsetValue ?? 0) * state.repeatCount + floatValue;\r\n                }\r\n                break;\r\n            }\r\n            // Quaternion\r\n            case Animation.ANIMATIONTYPE_QUATERNION: {\r\n                const quatValue = useTangent\r\n                    ? this.quaternionInterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient)\r\n                    : this.quaternionInterpolateFunction(startValue, endValue, gradient);\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return quatValue;\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return quatValue.addInPlace((state.offsetValue || _StaticOffsetValueQuaternion).scale(state.repeatCount));\r\n                }\r\n\r\n                return quatValue;\r\n            }\r\n            // Vector3\r\n            case Animation.ANIMATIONTYPE_VECTOR3: {\r\n                const vec3Value = useTangent\r\n                    ? this.vector3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient)\r\n                    : this.vector3InterpolateFunction(startValue, endValue, gradient);\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return vec3Value;\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return vec3Value.add((state.offsetValue || _StaticOffsetValueVector3).scale(state.repeatCount));\r\n                }\r\n                break;\r\n            }\r\n            // Vector2\r\n            case Animation.ANIMATIONTYPE_VECTOR2: {\r\n                const vec2Value = useTangent\r\n                    ? this.vector2InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient)\r\n                    : this.vector2InterpolateFunction(startValue, endValue, gradient);\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return vec2Value;\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return vec2Value.add((state.offsetValue || _StaticOffsetValueVector2).scale(state.repeatCount));\r\n                }\r\n                break;\r\n            }\r\n            // Size\r\n            case Animation.ANIMATIONTYPE_SIZE: {\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return this.sizeInterpolateFunction(startValue, endValue, gradient);\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return this.sizeInterpolateFunction(startValue, endValue, gradient).add((state.offsetValue || _StaticOffsetValueSize).scale(state.repeatCount));\r\n                }\r\n                break;\r\n            }\r\n            // Color3\r\n            case Animation.ANIMATIONTYPE_COLOR3: {\r\n                const color3Value = useTangent\r\n                    ? this.color3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient)\r\n                    : this.color3InterpolateFunction(startValue, endValue, gradient);\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return color3Value;\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return color3Value.add((state.offsetValue || _StaticOffsetValueColor3).scale(state.repeatCount));\r\n                }\r\n                break;\r\n            }\r\n            // Color4\r\n            case Animation.ANIMATIONTYPE_COLOR4: {\r\n                const color4Value = useTangent\r\n                    ? this.color4InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient)\r\n                    : this.color4InterpolateFunction(startValue, endValue, gradient);\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO:\r\n                        return color4Value;\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT:\r\n                        return color4Value.add((state.offsetValue || _StaticOffsetValueColor4).scale(state.repeatCount));\r\n                }\r\n                break;\r\n            }\r\n            // Matrix\r\n            case Animation.ANIMATIONTYPE_MATRIX: {\r\n                switch (state.loopMode) {\r\n                    case Animation.ANIMATIONLOOPMODE_CYCLE:\r\n                    case Animation.ANIMATIONLOOPMODE_CONSTANT:\r\n                    case Animation.ANIMATIONLOOPMODE_YOYO: {\r\n                        if (Animation.AllowMatricesInterpolation) {\r\n                            return this.matrixInterpolateFunction(startValue, endValue, gradient, state.workValue);\r\n                        }\r\n                        return startValue;\r\n                    }\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE:\r\n                    case Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT: {\r\n                        return startValue;\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Defines the function to use to interpolate matrices\r\n     * @param startValue defines the start matrix\r\n     * @param endValue defines the end matrix\r\n     * @param gradient defines the gradient between both matrices\r\n     * @param result defines an optional target matrix where to store the interpolation\r\n     * @returns the interpolated matrix\r\n     */\r\n    public matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number, result?: Matrix): Matrix {\r\n        if (Animation.AllowMatrixDecomposeForInterpolation) {\r\n            if (result) {\r\n                Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);\r\n                return result;\r\n            }\r\n            return Matrix.DecomposeLerp(startValue, endValue, gradient);\r\n        }\r\n\r\n        if (result) {\r\n            Matrix.LerpToRef(startValue, endValue, gradient, result);\r\n            return result;\r\n        }\r\n        return Matrix.Lerp(startValue, endValue, gradient);\r\n    }\r\n\r\n    /**\r\n     * Makes a copy of the animation\r\n     * @param cloneKeys Whether to clone the keys or not (default is false, so the keys are not cloned). Note that the key array itself is always cloned (that is, a new array is created),\r\n     *  but the individual keys inside the array are only cloned if this parameter is true.\r\n     * @returns Cloned animation\r\n     */\r\n    public clone(cloneKeys = false): Animation {\r\n        const clone = new Animation(this.name, this.targetPropertyPath.join(\".\"), this.framePerSecond, this.dataType, this.loopMode);\r\n\r\n        clone.enableBlending = this.enableBlending;\r\n        clone.blendingSpeed = this.blendingSpeed;\r\n\r\n        if (this._keys) {\r\n            clone.setKeys(this._keys, false, cloneKeys);\r\n        }\r\n\r\n        if (this._ranges) {\r\n            clone._ranges = {};\r\n            for (const name in this._ranges) {\r\n                const range = this._ranges[name];\r\n                if (!range) {\r\n                    continue;\r\n                }\r\n                clone._ranges[name] = range.clone();\r\n            }\r\n        }\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Sets the key frames of the animation\r\n     * @param values The animation key frames to set\r\n     * @param dontClone Whether to clone the keys or not (default is false, so the array of keys is cloned)\r\n     * @param cloneKeys Whether to clone the individual keys inside the array or not (default is false). If true, each key object inside the array will be cloned, and the fields\r\n     *   that have a clone() method will be cloned by calling that method.\r\n     */\r\n    public setKeys(values: Array<IAnimationKey>, dontClone = false, cloneKeys = false): void {\r\n        if (!dontClone) {\r\n            this._keys = values.slice(0);\r\n            if (cloneKeys) {\r\n                for (let i = 0; i < this._keys.length; i++) {\r\n                    const key = this._keys[i];\r\n                    this._keys[i] = {\r\n                        frame: key.frame,\r\n                        value: key.value.clone ? key.value.clone() : key.value,\r\n                        inTangent: key.inTangent && key.inTangent.clone ? key.inTangent.clone() : key.inTangent,\r\n                        outTangent: key.outTangent && key.outTangent.clone ? key.outTangent.clone() : key.outTangent,\r\n                        interpolation: key.interpolation,\r\n                        lockedTangent: key.lockedTangent,\r\n                        easingFunction: key.easingFunction,\r\n                    };\r\n                }\r\n            }\r\n        } else {\r\n            this._keys = values;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a key for the frame passed as a parameter and adds it to the animation IF a key doesn't already exist for that frame\r\n     * @param frame Frame number\r\n     * @returns The key index if the key was added or the index of the pre existing key if the frame passed as parameter already has a corresponding key\r\n     */\r\n    public createKeyForFrame(frame: number) {\r\n        // Find the key corresponding to frame\r\n        EvaluateAnimationState.key = 0;\r\n        const value = this._interpolate(frame, EvaluateAnimationState, true);\r\n\r\n        if (!value) {\r\n            // A key corresponding to this frame already exists\r\n            return this._keys[EvaluateAnimationState.key].frame === frame ? EvaluateAnimationState.key : EvaluateAnimationState.key + 1;\r\n        }\r\n\r\n        // The frame is between two keys, so create a new key\r\n        const newKey: IAnimationKey = {\r\n            frame,\r\n            value: value.clone ? value.clone() : value,\r\n        };\r\n\r\n        this._keys.splice(EvaluateAnimationState.key + 1, 0, newKey);\r\n\r\n        return EvaluateAnimationState.key + 1;\r\n    }\r\n\r\n    /**\r\n     * Serializes the animation to an object\r\n     * @returns Serialized object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.property = this.targetProperty;\r\n        serializationObject.framePerSecond = this.framePerSecond;\r\n        serializationObject.dataType = this.dataType;\r\n        serializationObject.loopBehavior = this.loopMode;\r\n        serializationObject.enableBlending = this.enableBlending;\r\n        serializationObject.blendingSpeed = this.blendingSpeed;\r\n\r\n        const dataType = this.dataType;\r\n        serializationObject.keys = [];\r\n        const keys = this.getKeys();\r\n        for (let index = 0; index < keys.length; index++) {\r\n            const animationKey = keys[index];\r\n\r\n            const key: any = {};\r\n            key.frame = animationKey.frame;\r\n\r\n            switch (dataType) {\r\n                case Animation.ANIMATIONTYPE_FLOAT:\r\n                    key.values = [animationKey.value];\r\n                    if (animationKey.inTangent !== undefined) {\r\n                        key.values.push(animationKey.inTangent);\r\n                    }\r\n                    if (animationKey.outTangent !== undefined) {\r\n                        if (animationKey.inTangent === undefined) {\r\n                            key.values.push(undefined);\r\n                        }\r\n                        key.values.push(animationKey.outTangent);\r\n                    }\r\n                    if (animationKey.interpolation !== undefined) {\r\n                        if (animationKey.inTangent === undefined) {\r\n                            key.values.push(undefined);\r\n                        }\r\n                        if (animationKey.outTangent === undefined) {\r\n                            key.values.push(undefined);\r\n                        }\r\n                        key.values.push(animationKey.interpolation);\r\n                    }\r\n                    break;\r\n                case Animation.ANIMATIONTYPE_QUATERNION:\r\n                case Animation.ANIMATIONTYPE_MATRIX:\r\n                case Animation.ANIMATIONTYPE_VECTOR3:\r\n                case Animation.ANIMATIONTYPE_COLOR3:\r\n                case Animation.ANIMATIONTYPE_COLOR4:\r\n                    key.values = animationKey.value.asArray();\r\n                    if (animationKey.inTangent != undefined) {\r\n                        key.values.push(animationKey.inTangent.asArray());\r\n                    }\r\n                    if (animationKey.outTangent != undefined) {\r\n                        if (animationKey.inTangent === undefined) {\r\n                            key.values.push(undefined);\r\n                        }\r\n                        key.values.push(animationKey.outTangent.asArray());\r\n                    }\r\n                    if (animationKey.interpolation !== undefined) {\r\n                        if (animationKey.inTangent === undefined) {\r\n                            key.values.push(undefined);\r\n                        }\r\n                        if (animationKey.outTangent === undefined) {\r\n                            key.values.push(undefined);\r\n                        }\r\n                        key.values.push(animationKey.interpolation);\r\n                    }\r\n                    break;\r\n            }\r\n\r\n            serializationObject.keys.push(key);\r\n        }\r\n\r\n        serializationObject.ranges = [];\r\n        for (const name in this._ranges) {\r\n            const source = this._ranges[name];\r\n\r\n            if (!source) {\r\n                continue;\r\n            }\r\n            const range: any = {};\r\n            range.name = name;\r\n            range.from = source.from;\r\n            range.to = source.to;\r\n            serializationObject.ranges.push(range);\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Float animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_FLOAT = Constants.ANIMATIONTYPE_FLOAT;\r\n    /**\r\n     * Vector3 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_VECTOR3 = Constants.ANIMATIONTYPE_VECTOR3;\r\n    /**\r\n     * Quaternion animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_QUATERNION = Constants.ANIMATIONTYPE_QUATERNION;\r\n    /**\r\n     * Matrix animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_MATRIX = Constants.ANIMATIONTYPE_MATRIX;\r\n    /**\r\n     * Color3 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_COLOR3 = Constants.ANIMATIONTYPE_COLOR3;\r\n    /**\r\n     * Color3 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_COLOR4 = Constants.ANIMATIONTYPE_COLOR4;\r\n    /**\r\n     * Vector2 animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_VECTOR2 = Constants.ANIMATIONTYPE_VECTOR2;\r\n    /**\r\n     * Size animation type\r\n     */\r\n    public static readonly ANIMATIONTYPE_SIZE = Constants.ANIMATIONTYPE_SIZE;\r\n    /**\r\n     * Relative Loop Mode\r\n     */\r\n    public static readonly ANIMATIONLOOPMODE_RELATIVE = 0;\r\n    /**\r\n     * Cycle Loop Mode\r\n     */\r\n    public static readonly ANIMATIONLOOPMODE_CYCLE = 1;\r\n    /**\r\n     * Constant Loop Mode\r\n     */\r\n    public static readonly ANIMATIONLOOPMODE_CONSTANT = 2;\r\n    /**\r\n     * Yoyo Loop Mode\r\n     */\r\n    public static readonly ANIMATIONLOOPMODE_YOYO = 4;\r\n    /**\r\n     * Relative Loop Mode (add to current value of animated object, unlike ANIMATIONLOOPMODE_RELATIVE)\r\n     */\r\n    public static readonly ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT = 5;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _UniversalLerp(left: any, right: any, amount: number): any {\r\n        const constructor = left.constructor;\r\n        if (constructor.Lerp) {\r\n            // Lerp supported\r\n            return constructor.Lerp(left, right, amount);\r\n        } else if (constructor.Slerp) {\r\n            // Slerp supported\r\n            return constructor.Slerp(left, right, amount);\r\n        } else if (left.toFixed) {\r\n            // Number\r\n            return left * (1.0 - amount) + amount * right;\r\n        } else {\r\n            // Blending not supported\r\n            return right;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Convert the keyframes of an animation to be relative to a given reference frame.\r\n * @param sourceAnimation defines the Animation containing keyframes to convert\r\n * @param referenceFrame defines the frame that keyframes in the range will be relative to (default: 0)\r\n * @param range defines the name of the AnimationRange belonging to the Animation to convert\r\n * @param cloneOriginal defines whether or not to clone the animation and convert the clone or convert the original animation (default is false)\r\n * @param clonedName defines the name of the resulting cloned Animation if cloneOriginal is true\r\n * @returns a new Animation if cloneOriginal is true or the original Animation if cloneOriginal is false\r\n */\r\nexport function AnimationMakeAnimationAdditive(sourceAnimation: Animation, referenceFrame?: number, range?: string, cloneOriginal?: boolean, clonedName?: string): Animation;\r\n\r\n/**\r\n * Convert the keyframes of an animation to be relative to a given reference frame.\r\n * @param sourceAnimation defines the Animation containing keyframes to convert\r\n * @param options defines the options to use when converting ey keyframes\r\n * @returns a new Animation if options.cloneOriginalAnimation is true or the original Animation if options.cloneOriginalAnimation is false\r\n */\r\nexport function AnimationMakeAnimationAdditive(sourceAnimation: Animation, options?: IMakeAnimationAdditiveOptions): Animation;\r\n\r\n/** @internal */\r\nexport function AnimationMakeAnimationAdditive(\r\n    sourceAnimation: Animation,\r\n    referenceFrameOrOptions?: number | IMakeAnimationAdditiveOptions,\r\n    range?: string,\r\n    cloneOriginal = false,\r\n    clonedName?: string\r\n): Animation {\r\n    let options: IMakeAnimationAdditiveOptions;\r\n\r\n    if (typeof referenceFrameOrOptions === \"object\") {\r\n        options = referenceFrameOrOptions;\r\n    } else {\r\n        options = {\r\n            referenceFrame: referenceFrameOrOptions ?? 0,\r\n            range: range,\r\n            cloneOriginalAnimation: cloneOriginal,\r\n            clonedAnimationName: clonedName,\r\n        };\r\n    }\r\n\r\n    let animation = sourceAnimation;\r\n\r\n    if (options.cloneOriginalAnimation) {\r\n        animation = sourceAnimation.clone();\r\n        animation.name = options.clonedAnimationName || animation.name;\r\n    }\r\n\r\n    const keys = animation.getKeys();\r\n    if (!keys.length) {\r\n        return animation;\r\n    }\r\n\r\n    const referenceFrame = options.referenceFrame && options.referenceFrame >= 0 ? options.referenceFrame : 0;\r\n    let startIndex = 0;\r\n    const firstKey = keys[0];\r\n    let endIndex = keys.length - 1;\r\n    const lastKey = keys[endIndex];\r\n    const valueStore = {\r\n        referenceValue: firstKey.value,\r\n        referencePosition: TmpVectors.Vector3[0],\r\n        referenceQuaternion: TmpVectors.Quaternion[0],\r\n        referenceScaling: TmpVectors.Vector3[1],\r\n        keyPosition: TmpVectors.Vector3[2],\r\n        keyQuaternion: TmpVectors.Quaternion[1],\r\n        keyScaling: TmpVectors.Vector3[3],\r\n    };\r\n    let from = firstKey.frame;\r\n    let to = lastKey.frame;\r\n    if (options.range) {\r\n        const rangeValue = animation.getRange(options.range);\r\n\r\n        if (rangeValue) {\r\n            from = rangeValue.from;\r\n            to = rangeValue.to;\r\n        }\r\n    } else {\r\n        from = options.fromFrame ?? from;\r\n        to = options.toFrame ?? to;\r\n    }\r\n\r\n    if (from !== firstKey.frame) {\r\n        startIndex = animation.createKeyForFrame(from);\r\n    }\r\n\r\n    if (to !== lastKey.frame) {\r\n        endIndex = animation.createKeyForFrame(to);\r\n    }\r\n\r\n    const updatedKeys = animation.getKeys();\r\n\r\n    // There's only one key, so use it\r\n    if (updatedKeys.length === 1) {\r\n        const value = animation._getKeyValue(updatedKeys[0].value);\r\n        valueStore.referenceValue = value.clone ? value.clone() : value;\r\n    }\r\n\r\n    // Reference frame is before the first frame, so just use the first frame\r\n    else if (referenceFrame <= firstKey.frame) {\r\n        const value = animation._getKeyValue(firstKey.value);\r\n        valueStore.referenceValue = value.clone ? value.clone() : value;\r\n    }\r\n\r\n    // Reference frame is after the last frame, so just use the last frame\r\n    else if (referenceFrame >= lastKey.frame) {\r\n        const value = animation._getKeyValue(lastKey.value);\r\n        valueStore.referenceValue = value.clone ? value.clone() : value;\r\n    }\r\n\r\n    // Interpolate the reference value from the animation\r\n    else {\r\n        EvaluateAnimationState.key = 0;\r\n        const value = animation._interpolate(referenceFrame, EvaluateAnimationState);\r\n        valueStore.referenceValue = value.clone ? value.clone() : value;\r\n    }\r\n\r\n    // Conjugate the quaternion\r\n    if (animation.dataType === Animation.ANIMATIONTYPE_QUATERNION) {\r\n        valueStore.referenceValue.normalize().conjugateInPlace();\r\n    }\r\n\r\n    // Decompose matrix and conjugate the quaternion\r\n    else if (animation.dataType === Animation.ANIMATIONTYPE_MATRIX) {\r\n        valueStore.referenceValue.decompose(valueStore.referenceScaling, valueStore.referenceQuaternion, valueStore.referencePosition);\r\n        valueStore.referenceQuaternion.normalize().conjugateInPlace();\r\n    }\r\n\r\n    let startFrame = Number.MAX_VALUE;\r\n    const clippedKeys: Nullable<IAnimationKey[]> = options.clipKeys ? [] : null;\r\n\r\n    // Subtract the reference value from all of the key values\r\n    for (let index = startIndex; index <= endIndex; index++) {\r\n        let key = updatedKeys[index];\r\n\r\n        if (clippedKeys || options.cloneOriginalAnimation) {\r\n            key = {\r\n                frame: key.frame,\r\n                value: key.value.clone ? key.value.clone() : key.value,\r\n                inTangent: key.inTangent,\r\n                outTangent: key.outTangent,\r\n                interpolation: key.interpolation,\r\n                lockedTangent: key.lockedTangent,\r\n                easingFunction: key.easingFunction,\r\n            };\r\n            if (clippedKeys) {\r\n                if (startFrame === Number.MAX_VALUE) {\r\n                    startFrame = key.frame;\r\n                }\r\n                key.frame -= startFrame;\r\n                clippedKeys.push(key);\r\n            }\r\n        }\r\n\r\n        // If this key was duplicated to create a frame 0 key, skip it because its value has already been updated\r\n        if (index && animation.dataType !== Animation.ANIMATIONTYPE_FLOAT && key.value === firstKey.value) {\r\n            continue;\r\n        }\r\n\r\n        switch (animation.dataType) {\r\n            case Animation.ANIMATIONTYPE_MATRIX:\r\n                key.value.decompose(valueStore.keyScaling, valueStore.keyQuaternion, valueStore.keyPosition);\r\n                valueStore.keyPosition.subtractInPlace(valueStore.referencePosition);\r\n                valueStore.keyScaling.divideInPlace(valueStore.referenceScaling);\r\n                valueStore.referenceQuaternion.multiplyToRef(valueStore.keyQuaternion, valueStore.keyQuaternion);\r\n                Matrix.ComposeToRef(valueStore.keyScaling, valueStore.keyQuaternion, valueStore.keyPosition, key.value);\r\n                break;\r\n\r\n            case Animation.ANIMATIONTYPE_QUATERNION:\r\n                valueStore.referenceValue.multiplyToRef(key.value, key.value);\r\n                break;\r\n\r\n            case Animation.ANIMATIONTYPE_VECTOR2:\r\n            case Animation.ANIMATIONTYPE_VECTOR3:\r\n            case Animation.ANIMATIONTYPE_COLOR3:\r\n            case Animation.ANIMATIONTYPE_COLOR4:\r\n                key.value.subtractToRef(valueStore.referenceValue, key.value);\r\n                break;\r\n\r\n            case Animation.ANIMATIONTYPE_SIZE:\r\n                key.value.width -= valueStore.referenceValue.width;\r\n                key.value.height -= valueStore.referenceValue.height;\r\n                break;\r\n\r\n            default:\r\n                key.value -= valueStore.referenceValue;\r\n        }\r\n    }\r\n\r\n    if (clippedKeys) {\r\n        animation.setKeys(clippedKeys, true);\r\n    }\r\n\r\n    return animation;\r\n}\r\n\r\n/**\r\n * Sets up an animation\r\n * @param property The property to animate\r\n * @param animationType The animation type to apply\r\n * @param framePerSecond The frames per second of the animation\r\n * @param easingFunction The easing function used in the animation\r\n * @returns The created animation\r\n */\r\nexport function AnimationCreateAnimation(property: string, animationType: number, framePerSecond: number, easingFunction: EasingFunction): Animation {\r\n    const animation: Animation = new Animation(property + \"Animation\", property, framePerSecond, animationType, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n    animation.setEasingFunction(easingFunction);\r\n\r\n    return animation;\r\n}\r\n\r\n/**\r\n * Create and start an animation on a node\r\n * @param name defines the name of the global animation that will be run on all nodes\r\n * @param target defines the target where the animation will take place\r\n * @param targetProperty defines property to animate\r\n * @param framePerSecond defines the number of frame per second yo use\r\n * @param totalFrame defines the number of frames in total\r\n * @param from defines the initial value\r\n * @param to defines the final value\r\n * @param loopMode defines which loop mode you want to use (off by default)\r\n * @param easingFunction defines the easing function to use (linear by default)\r\n * @param onAnimationEnd defines the callback to call when animation end\r\n * @param scene defines the hosting scene\r\n * @returns the animatable created for this animation\r\n */\r\nexport function AnimationCreateAndStartAnimation(\r\n    name: string,\r\n    target: any,\r\n    targetProperty: string,\r\n    framePerSecond: number,\r\n    totalFrame: number,\r\n    from: any,\r\n    to: any,\r\n    loopMode?: number,\r\n    easingFunction?: EasingFunction,\r\n    onAnimationEnd?: () => void,\r\n    scene?: Scene\r\n): Nullable<Animatable> {\r\n    const animation = Animation._PrepareAnimation(name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction);\r\n\r\n    if (!animation) {\r\n        return null;\r\n    }\r\n\r\n    if (target.getScene) {\r\n        scene = target.getScene();\r\n    }\r\n\r\n    if (!scene) {\r\n        return null;\r\n    }\r\n\r\n    return scene.beginDirectAnimation(target, [animation], 0, totalFrame, animation.loopMode !== Animation.ANIMATIONLOOPMODE_CONSTANT, 1.0, onAnimationEnd);\r\n}\r\n\r\n/**\r\n * Create and start an animation on a node and its descendants\r\n * @param name defines the name of the global animation that will be run on all nodes\r\n * @param node defines the root node where the animation will take place\r\n * @param directDescendantsOnly if true only direct descendants will be used, if false direct and also indirect (children of children, an so on in a recursive manner) descendants will be used\r\n * @param targetProperty defines property to animate\r\n * @param framePerSecond defines the number of frame per second to use\r\n * @param totalFrame defines the number of frames in total\r\n * @param from defines the initial value\r\n * @param to defines the final value\r\n * @param loopMode defines which loop mode you want to use (off by default)\r\n * @param easingFunction defines the easing function to use (linear by default)\r\n * @param onAnimationEnd defines the callback to call when an animation ends (will be called once per node)\r\n * @returns the list of animatables created for all nodes\r\n * @example https://www.babylonjs-playground.com/#MH0VLI\r\n */\r\nexport function AnimationCreateAndStartHierarchyAnimation(\r\n    name: string,\r\n    node: Node,\r\n    directDescendantsOnly: boolean,\r\n    targetProperty: string,\r\n    framePerSecond: number,\r\n    totalFrame: number,\r\n    from: any,\r\n    to: any,\r\n    loopMode?: number,\r\n    easingFunction?: EasingFunction,\r\n    onAnimationEnd?: () => void\r\n): Nullable<Animatable[]> {\r\n    const animation = Animation._PrepareAnimation(name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction);\r\n\r\n    if (!animation) {\r\n        return null;\r\n    }\r\n\r\n    const scene = node.getScene();\r\n    return scene.beginDirectHierarchyAnimation(node, directDescendantsOnly, [animation], 0, totalFrame, animation.loopMode === 1, 1.0, onAnimationEnd);\r\n}\r\n\r\n/**\r\n * Creates a new animation, merges it with the existing animations and starts it\r\n * @param name Name of the animation\r\n * @param node Node which contains the scene that begins the animations\r\n * @param targetProperty Specifies which property to animate\r\n * @param framePerSecond The frames per second of the animation\r\n * @param totalFrame The total number of frames\r\n * @param from The frame at the beginning of the animation\r\n * @param to The frame at the end of the animation\r\n * @param loopMode Specifies the loop mode of the animation\r\n * @param easingFunction (Optional) The easing function of the animation, which allow custom mathematical formulas for animations\r\n * @param onAnimationEnd Callback to run once the animation is complete\r\n * @returns Nullable animation\r\n */\r\nexport function AnimationCreateMergeAndStartAnimation(\r\n    name: string,\r\n    node: Node,\r\n    targetProperty: string,\r\n    framePerSecond: number,\r\n    totalFrame: number,\r\n    from: any,\r\n    to: any,\r\n    loopMode?: number,\r\n    easingFunction?: EasingFunction,\r\n    onAnimationEnd?: () => void\r\n): Nullable<Animatable> {\r\n    const animation = Animation._PrepareAnimation(name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction);\r\n\r\n    if (!animation) {\r\n        return null;\r\n    }\r\n\r\n    node.animations.push(animation);\r\n\r\n    return node.getScene().beginAnimation(node, 0, totalFrame, animation.loopMode === 1, 1.0, onAnimationEnd);\r\n}\r\n\r\n/**\r\n * Transition property of an object to a target value\r\n * @param property The property to transition\r\n * @param targetValue The target value of the property\r\n * @param host The object where the property to animate belongs\r\n * @param scene Scene used to run the animation\r\n * @param frameRate Framerate (in frame/s) to use\r\n * @param transition The transition to apply\r\n * @param duration The duration of the transition (in milliseconds)\r\n * @param onAnimationEnd Callback to run once the animation is complete\r\n * @param stopCurrent Stop the current animations for this property (default: true)\r\n * @param customKeys Custom animation keys for the transition\r\n * @returns the animatable created for this transition\r\n */\r\nexport function AnimationTransitionTo(\r\n    property: string,\r\n    targetValue: any,\r\n    host: any,\r\n    scene: Scene,\r\n    frameRate: number,\r\n    transition: Animation,\r\n    duration: number,\r\n    onAnimationEnd: Nullable<() => void> = null,\r\n    stopCurrent: boolean = true,\r\n    customKeys?: IAnimationKey[]\r\n): Nullable<Animatable> {\r\n    if (duration <= 0) {\r\n        host[property] = targetValue;\r\n        if (onAnimationEnd) {\r\n            onAnimationEnd();\r\n        }\r\n        return null;\r\n    }\r\n\r\n    const endFrame: number = frameRate * (duration / 1000);\r\n\r\n    transition.setKeys(\r\n        customKeys ?? [\r\n            {\r\n                frame: 0,\r\n                value: host[property].clone ? host[property].clone() : host[property],\r\n            },\r\n            {\r\n                frame: endFrame,\r\n                value: targetValue,\r\n            },\r\n        ]\r\n    );\r\n\r\n    if (!host.animations) {\r\n        host.animations = [];\r\n    }\r\n\r\n    host.animations.push(transition);\r\n\r\n    const animatable: Animatable = scene.beginAnimation(host, 0, endFrame, false, 1.0, onAnimationEnd ?? undefined, undefined, stopCurrent);\r\n    return animatable;\r\n}\r\n\r\n/**\r\n * Appends the serialized animations from the source animations\r\n * @param source Source containing the animations\r\n * @param destination Target to store the animations\r\n */\r\nexport function AnimationAppendSerializedAnimations(source: IAnimatable, destination: any): void {\r\n    SerializationHelper.AppendSerializedAnimations(source, destination);\r\n}\r\n\r\n/**\r\n * Parses an animation object and creates an animation\r\n * @param parsedAnimation Parsed animation object\r\n * @returns Animation object\r\n */\r\nexport function AnimationParse(parsedAnimation: any): Animation {\r\n    const animation = new Animation(parsedAnimation.name, parsedAnimation.property, parsedAnimation.framePerSecond, parsedAnimation.dataType, parsedAnimation.loopBehavior);\r\n\r\n    const dataType = parsedAnimation.dataType;\r\n    const keys: Array<IAnimationKey> = [];\r\n    let data;\r\n    let index: number;\r\n\r\n    if (parsedAnimation.enableBlending) {\r\n        animation.enableBlending = parsedAnimation.enableBlending;\r\n    }\r\n\r\n    if (parsedAnimation.blendingSpeed) {\r\n        animation.blendingSpeed = parsedAnimation.blendingSpeed;\r\n    }\r\n\r\n    for (index = 0; index < parsedAnimation.keys.length; index++) {\r\n        const key = parsedAnimation.keys[index];\r\n        let inTangent: any = undefined;\r\n        let outTangent: any = undefined;\r\n        let interpolation: any = undefined;\r\n\r\n        switch (dataType) {\r\n            case Animation.ANIMATIONTYPE_FLOAT:\r\n                data = key.values[0];\r\n                if (key.values.length >= 2) {\r\n                    inTangent = key.values[1];\r\n                }\r\n                if (key.values.length >= 3) {\r\n                    outTangent = key.values[2];\r\n                }\r\n                if (key.values.length >= 4) {\r\n                    interpolation = key.values[3];\r\n                }\r\n                break;\r\n            case Animation.ANIMATIONTYPE_QUATERNION:\r\n                data = Quaternion.FromArray(key.values);\r\n                if (key.values.length >= 8) {\r\n                    const _inTangent = Quaternion.FromArray(key.values.slice(4, 8));\r\n                    if (!_inTangent.equals(Quaternion.Zero())) {\r\n                        inTangent = _inTangent;\r\n                    }\r\n                }\r\n                if (key.values.length >= 12) {\r\n                    const _outTangent = Quaternion.FromArray(key.values.slice(8, 12));\r\n                    if (!_outTangent.equals(Quaternion.Zero())) {\r\n                        outTangent = _outTangent;\r\n                    }\r\n                }\r\n                if (key.values.length >= 13) {\r\n                    interpolation = key.values[12];\r\n                }\r\n                break;\r\n            case Animation.ANIMATIONTYPE_MATRIX:\r\n                data = Matrix.FromArray(key.values);\r\n                if (key.values.length >= 17) {\r\n                    interpolation = key.values[16];\r\n                }\r\n                break;\r\n            case Animation.ANIMATIONTYPE_COLOR3:\r\n                data = Color3.FromArray(key.values);\r\n                if (key.values[3]) {\r\n                    inTangent = Color3.FromArray(key.values[3]);\r\n                }\r\n                if (key.values[4]) {\r\n                    outTangent = Color3.FromArray(key.values[4]);\r\n                }\r\n                if (key.values[5]) {\r\n                    interpolation = key.values[5];\r\n                }\r\n                break;\r\n            case Animation.ANIMATIONTYPE_COLOR4:\r\n                data = Color4.FromArray(key.values);\r\n                if (key.values[4]) {\r\n                    inTangent = Color4.FromArray(key.values[4]);\r\n                }\r\n                if (key.values[5]) {\r\n                    outTangent = Color4.FromArray(key.values[5]);\r\n                }\r\n                if (key.values[6]) {\r\n                    interpolation = key.values[6];\r\n                }\r\n                break;\r\n            case Animation.ANIMATIONTYPE_VECTOR3:\r\n            default:\r\n                data = Vector3.FromArray(key.values);\r\n                if (key.values[3]) {\r\n                    inTangent = Vector3.FromArray(key.values[3]);\r\n                }\r\n                if (key.values[4]) {\r\n                    outTangent = Vector3.FromArray(key.values[4]);\r\n                }\r\n                if (key.values[5]) {\r\n                    interpolation = key.values[5];\r\n                }\r\n                break;\r\n        }\r\n\r\n        const keyData: any = {};\r\n        keyData.frame = key.frame;\r\n        keyData.value = data;\r\n\r\n        if (inTangent != undefined) {\r\n            keyData.inTangent = inTangent;\r\n        }\r\n        if (outTangent != undefined) {\r\n            keyData.outTangent = outTangent;\r\n        }\r\n        if (interpolation != undefined) {\r\n            keyData.interpolation = interpolation;\r\n        }\r\n        keys.push(keyData);\r\n    }\r\n\r\n    animation.setKeys(keys);\r\n\r\n    if (parsedAnimation.ranges) {\r\n        for (index = 0; index < parsedAnimation.ranges.length; index++) {\r\n            data = parsedAnimation.ranges[index];\r\n            animation.createRange(data.name, data.from, data.to);\r\n        }\r\n    }\r\n\r\n    return animation;\r\n}\r\n\r\n/**\r\n * Creates a new animation or an array of animations from a snippet saved in a remote file\r\n * @param name defines the name of the animation to create (can be null or empty to use the one from the json data)\r\n * @param url defines the url to load from\r\n * @returns a promise that will resolve to the new animation or an array of animations\r\n */\r\nexport async function AnimationParseFromFileAsync(name: Nullable<string>, url: string): Promise<Animation | Array<Animation>> {\r\n    return await new Promise((resolve, reject) => {\r\n        const request = new WebRequest();\r\n        request.addEventListener(\"readystatechange\", () => {\r\n            if (request.readyState == 4) {\r\n                if (request.status == 200) {\r\n                    let serializationObject = JSON.parse(request.responseText);\r\n                    if (serializationObject.animations) {\r\n                        serializationObject = serializationObject.animations;\r\n                    }\r\n\r\n                    if (serializationObject.length) {\r\n                        const output: Animation[] = [];\r\n                        for (const serializedAnimation of serializationObject) {\r\n                            output.push(AnimationParse(serializedAnimation));\r\n                        }\r\n\r\n                        resolve(output);\r\n                    } else {\r\n                        const output = AnimationParse(serializationObject);\r\n\r\n                        if (name) {\r\n                            output.name = name;\r\n                        }\r\n\r\n                        resolve(output);\r\n                    }\r\n                } else {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(\"Unable to load the animation\");\r\n                }\r\n            }\r\n        });\r\n\r\n        request.open(\"GET\", url);\r\n        request.send();\r\n    });\r\n}\r\n\r\n/**\r\n * Creates an animation or an array of animations from a snippet saved by the Inspector\r\n * @param snippetId defines the snippet to load\r\n * @returns a promise that will resolve to the new animation or a new array of animations\r\n */\r\nexport async function AnimationParseFromSnippetAsync(this: typeof Animation | void, snippetId: string): Promise<Animation | Array<Animation>> {\r\n    const snippetUrl = this?.SnippetUrl ?? Animation.SnippetUrl;\r\n\r\n    return await new Promise((resolve, reject) => {\r\n        const request = new WebRequest();\r\n        request.addEventListener(\"readystatechange\", () => {\r\n            if (request.readyState == 4) {\r\n                if (request.status == 200) {\r\n                    const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n\r\n                    if (snippet.animations) {\r\n                        const serializationObject = JSON.parse(snippet.animations);\r\n                        const outputs: Animation[] = [];\r\n                        for (const serializedAnimation of serializationObject.animations) {\r\n                            const output = AnimationParse(serializedAnimation);\r\n                            output.snippetId = snippetId;\r\n                            outputs.push(output);\r\n                        }\r\n\r\n                        resolve(outputs);\r\n                    } else {\r\n                        const serializationObject = JSON.parse(snippet.animation);\r\n                        const output = AnimationParse(serializationObject);\r\n\r\n                        output.snippetId = snippetId;\r\n\r\n                        resolve(output);\r\n                    }\r\n                } else {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(\"Unable to load the snippet \" + snippetId);\r\n                }\r\n            }\r\n        });\r\n\r\n        request.open(\"GET\", snippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\r\n        request.send();\r\n    });\r\n}\r\n\r\n/**\r\n * Creates an animation or an array of animations from a snippet saved by the Inspector\r\n * @deprecated Please use AnimationParseFromSnippetAsync instead\r\n * @param snippetId defines the snippet to load\r\n * @returns a promise that will resolve to the new animation or a new array of animations\r\n */\r\nexport const AnimationCreateFromSnippetAsync = AnimationParseFromSnippetAsync;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for animation.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnimation(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Animation.Parse = AnimationParse;\r\n    Animation.ParseFromFileAsync = AnimationParseFromFileAsync;\r\n    Animation.ParseFromSnippetAsync = AnimationParseFromSnippetAsync;\r\n    Animation.CreateFromSnippetAsync = AnimationCreateFromSnippetAsync;\r\n    Animation.CreateAnimation = AnimationCreateAnimation;\r\n    Animation.CreateAndStartAnimation = AnimationCreateAndStartAnimation;\r\n    Animation.CreateAndStartHierarchyAnimation = AnimationCreateAndStartHierarchyAnimation;\r\n    Animation.CreateMergeAndStartAnimation = AnimationCreateMergeAndStartAnimation;\r\n    Animation.MakeAnimationAdditive = AnimationMakeAnimationAdditive;\r\n    Animation.TransitionTo = AnimationTransitionTo;\r\n    Animation.AppendSerializedAnimations = AnimationAppendSerializedAnimations;\r\n\r\n    RegisterClass(\"BABYLON.Animation\", Animation);\r\n\r\n    Node._AnimationRangeFactory = (name: string, from: number, to: number) => new AnimationRange(name, from, to);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Action } from \"./action.pure\";\r\nimport { type Condition } from \"./condition.pure\";\r\n\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { Vector3, Matrix, Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Animation } from \"../Animations/animation.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This defines an action responsible to change the value of a property\r\n * by interpolating between its current value and the newly set one once triggered.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n */\r\nexport class InterpolateValueAction extends Action {\r\n    /**\r\n     * Defines the path of the property where the value should be interpolated\r\n     */\r\n    public propertyPath: string;\r\n\r\n    /**\r\n     * Defines the target value at the end of the interpolation.\r\n     */\r\n    public value: any;\r\n\r\n    /**\r\n     * Defines the time it will take for the property to interpolate to the value.\r\n     */\r\n    public duration: number = 1000;\r\n\r\n    /**\r\n     * Defines if the other scene animations should be stopped when the action has been triggered\r\n     */\r\n    public stopOtherAnimations?: boolean;\r\n\r\n    /**\r\n     * Defines a callback raised once the interpolation animation has been done.\r\n     */\r\n    public onInterpolationDone?: () => void;\r\n\r\n    /**\r\n     * Observable triggered once the interpolation animation has been done.\r\n     */\r\n    public onInterpolationDoneObservable = new Observable<InterpolateValueAction>();\r\n\r\n    private _target: any;\r\n    private _effectiveTarget: any;\r\n    private _property: string;\r\n\r\n    /**\r\n     * Instantiate the action\r\n     * @param triggerOptions defines the trigger options\r\n     * @param target defines the object containing the value to interpolate\r\n     * @param propertyPath defines the path to the property in the target object\r\n     * @param value defines the target value at the end of the interpolation\r\n     * @param duration defines the time it will take for the property to interpolate to the value.\r\n     * @param condition defines the trigger related conditions\r\n     * @param stopOtherAnimations defines if the other scene animations should be stopped when the action has been triggered\r\n     * @param onInterpolationDone defines a callback raised once the interpolation animation has been done\r\n     */\r\n    constructor(\r\n        triggerOptions: any,\r\n        target: any,\r\n        propertyPath: string,\r\n        value: any,\r\n        duration: number = 1000,\r\n        condition?: Condition,\r\n        stopOtherAnimations?: boolean,\r\n        onInterpolationDone?: () => void\r\n    ) {\r\n        super(triggerOptions, condition);\r\n\r\n        this.propertyPath = propertyPath;\r\n        this.value = value;\r\n        this.duration = duration;\r\n        this.stopOtherAnimations = stopOtherAnimations;\r\n        this.onInterpolationDone = onInterpolationDone;\r\n        this._target = this._effectiveTarget = target;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepare(): void {\r\n        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);\r\n        this._property = this._getProperty(this.propertyPath);\r\n    }\r\n\r\n    /**\r\n     * Execute the action starts the value interpolation.\r\n     */\r\n    public override execute(): void {\r\n        const scene = this._actionManager.getScene();\r\n        const keys = [\r\n            {\r\n                frame: 0,\r\n                value: this._effectiveTarget[this._property],\r\n            },\r\n            {\r\n                frame: 100,\r\n                value: this.value,\r\n            },\r\n        ];\r\n\r\n        let dataType: number;\r\n\r\n        if (typeof this.value === \"number\") {\r\n            dataType = Animation.ANIMATIONTYPE_FLOAT;\r\n        } else if (this.value instanceof Color3) {\r\n            dataType = Animation.ANIMATIONTYPE_COLOR3;\r\n        } else if (this.value instanceof Vector3) {\r\n            dataType = Animation.ANIMATIONTYPE_VECTOR3;\r\n        } else if (this.value instanceof Matrix) {\r\n            dataType = Animation.ANIMATIONTYPE_MATRIX;\r\n        } else if (this.value instanceof Quaternion) {\r\n            dataType = Animation.ANIMATIONTYPE_QUATERNION;\r\n        } else {\r\n            Logger.Warn(\"InterpolateValueAction: Unsupported type (\" + typeof this.value + \")\");\r\n            return;\r\n        }\r\n\r\n        const animation = new Animation(\"InterpolateValueAction\", this._property, 100 * (1000.0 / this.duration), dataType, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        animation.setKeys(keys);\r\n\r\n        if (this.stopOtherAnimations) {\r\n            scene.stopAnimation(this._effectiveTarget);\r\n        }\r\n\r\n        const wrapper = () => {\r\n            this.onInterpolationDoneObservable.notifyObservers(this);\r\n            if (this.onInterpolationDone) {\r\n                this.onInterpolationDone();\r\n            }\r\n        };\r\n\r\n        scene.beginDirectAnimation(this._effectiveTarget, [animation], 0, 100, false, 1, wrapper);\r\n    }\r\n\r\n    /**\r\n     * Serializes the actions and its related information.\r\n     * @param parent defines the object to serialize in\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(parent: any): any {\r\n        return super._serialize(\r\n            {\r\n                name: \"InterpolateValueAction\",\r\n                properties: [\r\n                    Action._GetTargetProperty(this._target),\r\n                    { name: \"propertyPath\", value: this.propertyPath },\r\n                    { name: \"value\", value: Action._SerializeValueAsString(this.value) },\r\n                    { name: \"duration\", value: Action._SerializeValueAsString(this.duration) },\r\n                    { name: \"stopOtherAnimations\", value: Action._SerializeValueAsString(this.stopOtherAnimations) || false },\r\n                ],\r\n            },\r\n            parent\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for interpolateValueAction.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInterpolateValueAction(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InterpolateValueAction\", InterpolateValueAction);\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport {\r\n    type _IAnimationState,\r\n    Animation,\r\n    _StaticOffsetValueColor3,\r\n    _StaticOffsetValueColor4,\r\n    _StaticOffsetValueQuaternion,\r\n    _StaticOffsetValueSize,\r\n    _StaticOffsetValueVector2,\r\n    _StaticOffsetValueVector3,\r\n} from \"./animation.pure\";\r\nimport { type AnimationEvent } from \"./animationEvent\";\r\nimport { type Animatable } from \"./animatable\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type IAnimationKey } from \"./animationKey\";\r\n\r\n/**\r\n * @internal\r\n * A write of a runtime animation to one of its targets in an animation step, recorded as it is made.\r\n */\r\nexport interface IRuntimeAnimationWrite {\r\n    /** The runtime animation that wrote; null once the record is emptied, after its step. */\r\n    runtimeAnimation: Nullable<RuntimeAnimation>;\r\n    /** The object it wrote a property of; null once the record is emptied. */\r\n    target: any;\r\n    /** The weight it wrote with, -1 for a direct write. */\r\n    weight: number;\r\n    /** Whether it wrote additively. */\r\n    additive: boolean;\r\n    /** The factor the value it wrote was blended in with, one once the animation has blended in. */\r\n    blendingFactor: number;\r\n    /** Whether a step prologue has already held the record over; a direct write is held over one step and no more. */\r\n    carried: boolean;\r\n}\r\n\r\n/**\r\n * Defines a runtime animation\r\n */\r\nexport class RuntimeAnimation {\r\n    private _events = new Array<AnimationEvent>();\r\n\r\n    /**\r\n     * The current frame of the runtime animation\r\n     */\r\n    private _currentFrame: number = 0;\r\n\r\n    /**\r\n     * The animation used by the runtime animation\r\n     */\r\n    public _animation: Animation;\r\n\r\n    /**\r\n     * The target of the runtime animation\r\n     */\r\n    private _target: any;\r\n\r\n    /**\r\n     * The initiating animatable\r\n     */\r\n    private _host: Animatable;\r\n\r\n    /**\r\n     * The original value of the runtime animation\r\n     */\r\n    private _originalValue = new Array<any>();\r\n\r\n    /**\r\n     * The original blend value of the runtime animation\r\n     */\r\n    private _originalBlendValue: Nullable<any> = null;\r\n\r\n    /**\r\n     * The offsets cache of the runtime animation\r\n     */\r\n    private _offsetsCache: { [key: string]: any } = {};\r\n\r\n    /**\r\n     * The high limits cache of the runtime animation\r\n     */\r\n    private _highLimitsCache: { [key: string]: any } = {};\r\n\r\n    /**\r\n     * Specifies if the runtime animation has been stopped\r\n     */\r\n    private _stopped = false;\r\n\r\n    /**\r\n     * The blending factor of the runtime animation\r\n     */\r\n    private _blendingFactor = 0;\r\n\r\n    /**\r\n     * The BabylonJS scene\r\n     */\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * The current value of the runtime animation\r\n     */\r\n    private _currentValue: Nullable<any> = null;\r\n\r\n    /** @internal */\r\n    public _animationState: _IAnimationState;\r\n\r\n    /**\r\n     * The active target of the runtime animation\r\n     */\r\n    private _activeTargets: any[];\r\n    private _currentActiveTarget: Nullable<any> = null;\r\n    private _directTarget: Nullable<any> = null;\r\n\r\n    /**\r\n     * The target path of the runtime animation\r\n     */\r\n    private _targetPath: string = \"\";\r\n\r\n    /**\r\n     * The weight of the runtime animation\r\n     */\r\n    private _weight = 1.0;\r\n\r\n    /**\r\n     * The absolute frame offset of the runtime animation\r\n     */\r\n    private _absoluteFrameOffset = 0;\r\n\r\n    /**\r\n     * The previous elapsed time (since start of animation) of the runtime animation\r\n     */\r\n    private _previousElapsedTime: number = 0;\r\n\r\n    private _yoyoDirection: number = 1;\r\n\r\n    /**\r\n     * The previous absolute frame of the runtime animation (meaning, without taking into account the from/to values, only the elapsed time and the fps)\r\n     */\r\n    private _previousAbsoluteFrame: number = 0;\r\n    private _playbackFrom = 0;\r\n    private _playbackTo = 0;\r\n    private _playbackFrames = 0;\r\n    private _playbackProgress = 0;\r\n    private _playbackSyncRoot: Nullable<Animatable> = null;\r\n    private _playbackJumped = false;\r\n    private _playbackSyncMasterPlayed = 0;\r\n    private _playbackSyncMasterFrame = 0;\r\n\r\n    private _enableBlending: boolean;\r\n\r\n    private _keys: IAnimationKey[];\r\n    private _minFrame: number;\r\n    private _maxFrame: number;\r\n    private _targetIsArray = false;\r\n\r\n    /** @internal */\r\n    public _coreRuntimeAnimation: RuntimeAnimation | null = null;\r\n\r\n    /**\r\n     * Gets the current frame of the runtime animation\r\n     */\r\n    public get currentFrame(): number {\r\n        return this._currentFrame;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * The first frame of the range the animation was last evaluated over: the requested range, clamped to its keys.\r\n     */\r\n    public get _evaluatedFrom(): number {\r\n        return this._playbackFrom;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * The last frame of the range the animation was last evaluated over.\r\n     */\r\n    public get _evaluatedTo(): number {\r\n        return this._playbackTo;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * How far the pose last evaluated had played from _evaluatedFrom, in frames, unwrapped across loops: folding it into\r\n     * the range gives the frame that was evaluated, and dividing it by the range counts the whole cycles the pose has been\r\n     * through. It follows a synchronization root, swings with a yoyo loop and holds where a constant loop or a playback\r\n     * that does not loop holds its pose, so it always describes the pose that was evaluated.\r\n     */\r\n    public get _evaluatedProgress(): number {\r\n        return this._playbackProgress;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * The animatable the evaluation was clocked by, captured as it was made: the pose of a step stays that of the root\r\n     * it was synchronized with then, whatever the host has been synchronized with since.\r\n     */\r\n    public get _evaluatedSyncRoot(): Nullable<Animatable> {\r\n        return this._playbackSyncRoot;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Whether the evaluated progress jumped rather than playing on from the one before: the pose of a follower snapped\r\n     * back to the start of its range by a root whose own clock cannot carry it to the end.\r\n     */\r\n    public get _evaluatedJump(): boolean {\r\n        return this._playbackJumped;\r\n    }\r\n\r\n    /**\r\n     * Gets the weight of the runtime animation\r\n     */\r\n    public get weight(): number {\r\n        return this._weight;\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the runtime animation\r\n     */\r\n    public get currentValue(): any {\r\n        return this._currentValue;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the target path of the runtime animation\r\n     */\r\n    public get targetPath(): string {\r\n        return this._targetPath;\r\n    }\r\n\r\n    /**\r\n     * Gets the actual target of the runtime animation\r\n     */\r\n    public get target(): any {\r\n        return this._currentActiveTarget;\r\n    }\r\n\r\n    /**\r\n     * Gets the additive state of the runtime animation\r\n     */\r\n    public get isAdditive(): boolean {\r\n        return this._host && this._host.isAdditive;\r\n    }\r\n\r\n    /** @internal */\r\n    public _onLoop: () => void;\r\n\r\n    /**\r\n     * Create a new RuntimeAnimation object\r\n     * @param target defines the target of the animation\r\n     * @param animation defines the source animation object\r\n     * @param scene defines the hosting scene\r\n     * @param host defines the initiating Animatable\r\n     */\r\n    public constructor(target: any, animation: Animation, scene: Scene, host: Animatable) {\r\n        this._animation = animation;\r\n        this._target = target;\r\n        this._scene = scene;\r\n        this._host = host;\r\n        this._activeTargets = [];\r\n\r\n        animation._runtimeAnimations.push(this);\r\n\r\n        // State\r\n        this._animationState = {\r\n            key: 0,\r\n            repeatCount: 0,\r\n            loopMode: this._getCorrectLoopMode(),\r\n        };\r\n\r\n        if (this._animation.dataType === Animation.ANIMATIONTYPE_MATRIX) {\r\n            this._animationState.workValue = Matrix.Zero();\r\n        }\r\n\r\n        // Limits\r\n        this._keys = this._animation.getKeys();\r\n        this._minFrame = this._keys[0].frame;\r\n        this._maxFrame = this._keys[this._keys.length - 1].frame;\r\n\r\n        // Add a start key at frame 0 if missing\r\n        if (this._minFrame !== 0) {\r\n            const newKey = { frame: 0, value: this._keys[0].value };\r\n            this._keys.splice(0, 0, newKey);\r\n        }\r\n\r\n        // Check data\r\n        if (this._target instanceof Array) {\r\n            let index = 0;\r\n            for (const target of this._target) {\r\n                this._preparePath(target, index);\r\n                this._getOriginalValues(index);\r\n                index++;\r\n            }\r\n            this._targetIsArray = true;\r\n        } else {\r\n            this._preparePath(this._target);\r\n            this._getOriginalValues();\r\n            this._targetIsArray = false;\r\n            this._directTarget = this._activeTargets[0];\r\n        }\r\n\r\n        // Cloning events locally\r\n        const events = animation.getEvents();\r\n        if (events && events.length > 0) {\r\n            for (const e of events) {\r\n                this._events.push(e._clone());\r\n            }\r\n        }\r\n\r\n        this._enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;\r\n    }\r\n\r\n    private _preparePath(target: any, targetIndex = 0) {\r\n        const targetPropertyPath = this._animation.targetPropertyPath;\r\n\r\n        if (targetPropertyPath.length > 1) {\r\n            let property = target;\r\n            for (let index = 0; index < targetPropertyPath.length - 1; index++) {\r\n                const name = targetPropertyPath[index];\r\n                property = property[name];\r\n                if (property === undefined) {\r\n                    throw new Error(`Invalid property (${name}) in property path (${targetPropertyPath.join(\".\")})`);\r\n                }\r\n            }\r\n\r\n            this._targetPath = targetPropertyPath[targetPropertyPath.length - 1];\r\n            this._activeTargets[targetIndex] = property;\r\n        } else {\r\n            this._targetPath = targetPropertyPath[0];\r\n            this._activeTargets[targetIndex] = target;\r\n        }\r\n\r\n        if (this._activeTargets[targetIndex][this._targetPath] === undefined) {\r\n            throw new Error(`Invalid property (${this._targetPath}) in property path (${targetPropertyPath.join(\".\")})`);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the animation from the runtime animation\r\n     */\r\n    public get animation(): Animation {\r\n        return this._animation;\r\n    }\r\n\r\n    /**\r\n     * Resets the runtime animation to the beginning\r\n     * @param restoreOriginal defines whether to restore the target property to the original value\r\n     */\r\n    public reset(restoreOriginal = false): void {\r\n        if (restoreOriginal) {\r\n            if (this._target instanceof Array) {\r\n                let index = 0;\r\n                for (const target of this._target) {\r\n                    if (this._originalValue[index] !== undefined) {\r\n                        this._setValue(target, this._activeTargets[index], this._originalValue[index], -1, index);\r\n                    }\r\n                    index++;\r\n                }\r\n            } else {\r\n                if (this._originalValue[0] !== undefined) {\r\n                    this._setValue(this._target, this._directTarget, this._originalValue[0], -1, 0);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._offsetsCache = {};\r\n        this._highLimitsCache = {};\r\n        this._currentFrame = 0;\r\n        this._blendingFactor = 0;\r\n\r\n        // Events\r\n        for (let index = 0; index < this._events.length; index++) {\r\n            this._events[index].isDone = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Specifies if the runtime animation is stopped\r\n     * @returns Boolean specifying if the runtime animation is stopped\r\n     */\r\n    public isStopped(): boolean {\r\n        return this._stopped;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the runtime animation\r\n     */\r\n    public dispose(): void {\r\n        const index = this._animation.runtimeAnimations.indexOf(this);\r\n\r\n        if (index > -1) {\r\n            this._animation.runtimeAnimations.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Apply the interpolated value to the target\r\n     * @param currentValue defines the value computed by the animation\r\n     * @param weight defines the weight to apply to this value (Defaults to 1.0)\r\n     */\r\n    public setValue(currentValue: any, weight: number) {\r\n        if (this._targetIsArray) {\r\n            for (let index = 0; index < this._target.length; index++) {\r\n                const target = this._target[index];\r\n                this._setValue(target, this._activeTargets[index], currentValue, weight, index);\r\n            }\r\n            return;\r\n        }\r\n        this._setValue(this._target, this._directTarget, currentValue, weight, 0);\r\n    }\r\n\r\n    private _getOriginalValues(targetIndex = 0) {\r\n        let originalValue: any;\r\n        const target = this._activeTargets[targetIndex];\r\n\r\n        if (Animation.InheritOriginalValueFromActiveAnimations) {\r\n            // When another active animation is already driving the same target+property,\r\n            // inherit its _originalValue instead of snapshotting the live (mid-animation) value.\r\n            // This prevents the \"stuck value\" bug when overlapping animations interrupt each other.\r\n            const activeAnimatables = this._scene._activeAnimatables;\r\n            for (let animIndex = 0; animIndex < activeAnimatables.length; animIndex++) {\r\n                const runtimeAnimations = activeAnimatables[animIndex]._runtimeAnimations;\r\n                for (let rtIndex = 0; rtIndex < runtimeAnimations.length; rtIndex++) {\r\n                    const rtAnim = runtimeAnimations[rtIndex];\r\n                    if (rtAnim === this) {\r\n                        continue;\r\n                    }\r\n                    if (rtAnim._targetPath === this._targetPath) {\r\n                        for (let i = 0; i < rtAnim._activeTargets.length; i++) {\r\n                            if (rtAnim._activeTargets[i] === target && rtAnim._originalValue[i] !== undefined) {\r\n                                if (rtAnim._originalValue[i] && rtAnim._originalValue[i].clone) {\r\n                                    this._originalValue[targetIndex] = rtAnim._originalValue[i].clone();\r\n                                } else {\r\n                                    this._originalValue[targetIndex] = rtAnim._originalValue[i];\r\n                                }\r\n                                return;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (target.getLocalMatrix && this._targetPath === \"_matrix\") {\r\n            // For bones\r\n            originalValue = target.getLocalMatrix();\r\n        } else {\r\n            originalValue = target[this._targetPath];\r\n        }\r\n\r\n        if (originalValue && originalValue.clone) {\r\n            this._originalValue[targetIndex] = originalValue.clone();\r\n        } else {\r\n            this._originalValue[targetIndex] = originalValue;\r\n        }\r\n    }\r\n\r\n    private _registerTargetForLateAnimationBinding(runtimeAnimation: RuntimeAnimation, originalValue: any): void {\r\n        const target = runtimeAnimation.target;\r\n        this._scene._registeredForLateAnimationBindings.pushNoDuplicate(target);\r\n\r\n        if (!target._lateAnimationHolders) {\r\n            target._lateAnimationHolders = {};\r\n        }\r\n\r\n        if (!target._lateAnimationHolders[runtimeAnimation.targetPath]) {\r\n            target._lateAnimationHolders[runtimeAnimation.targetPath] = {\r\n                totalWeight: 0,\r\n                totalAdditiveWeight: 0,\r\n                animations: [],\r\n                additiveAnimations: [],\r\n                originalValue: originalValue,\r\n            };\r\n        }\r\n\r\n        if (runtimeAnimation.isAdditive) {\r\n            target._lateAnimationHolders[runtimeAnimation.targetPath].additiveAnimations.push(runtimeAnimation);\r\n            target._lateAnimationHolders[runtimeAnimation.targetPath].totalAdditiveWeight += runtimeAnimation.weight;\r\n        } else {\r\n            target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);\r\n            target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;\r\n        }\r\n    }\r\n\r\n    private _setValue(target: any, destination: any, currentValue: any, weight: number, targetIndex: number): void {\r\n        // Recorded as written - the target, the weight and whether additively, as the bindings take it - so what an\r\n        // animation step wrote can be read after the step from these records alone, whatever a callback did since.\r\n        const writes = this._scene._animationWrites;\r\n        const count = this._scene._animationWriteCount++;\r\n        let write = writes[count];\r\n        if (!write) {\r\n            write = writes[count] = { runtimeAnimation: this, target, weight, additive: false, blendingFactor: 1, carried: false };\r\n        }\r\n        write.runtimeAnimation = this;\r\n        write.target = target;\r\n        write.weight = weight;\r\n        write.additive = this.isAdditive;\r\n        write.carried = false;\r\n\r\n        // Set value\r\n        this._currentActiveTarget = destination;\r\n\r\n        this._weight = weight;\r\n\r\n        if (this._enableBlending && this._blendingFactor <= 1.0) {\r\n            if (!this._originalBlendValue) {\r\n                const originalValue = destination[this._targetPath];\r\n\r\n                if (originalValue.clone) {\r\n                    this._originalBlendValue = originalValue.clone();\r\n                } else {\r\n                    this._originalBlendValue = originalValue;\r\n                }\r\n            }\r\n\r\n            if (this._originalBlendValue.m) {\r\n                // Matrix\r\n                if (Animation.AllowMatrixDecomposeForInterpolation) {\r\n                    if (this._currentValue) {\r\n                        Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);\r\n                    } else {\r\n                        this._currentValue = Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);\r\n                    }\r\n                } else {\r\n                    if (this._currentValue) {\r\n                        Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);\r\n                    } else {\r\n                        this._currentValue = Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);\r\n                    }\r\n                }\r\n            } else {\r\n                this._currentValue = Animation._UniversalLerp(this._originalBlendValue, currentValue, this._blendingFactor);\r\n            }\r\n\r\n            const blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;\r\n            // The record carries the factor this very write blended in with, so what the step blended can be read\r\n            // after the step whatever a write made since has moved the animation's own factor on to.\r\n            write.blendingFactor = this._blendingFactor;\r\n            this._blendingFactor += blendingSpeed;\r\n        } else {\r\n            write.blendingFactor = 1;\r\n            if (!this._currentValue) {\r\n                if (currentValue?.clone) {\r\n                    this._currentValue = currentValue.clone();\r\n                } else {\r\n                    this._currentValue = currentValue;\r\n                }\r\n            } else if (this._currentValue.copyFrom) {\r\n                this._currentValue.copyFrom(currentValue);\r\n            } else {\r\n                this._currentValue = currentValue;\r\n            }\r\n        }\r\n\r\n        if (weight !== -1.0) {\r\n            this._registerTargetForLateAnimationBinding(this, this._originalValue[targetIndex]);\r\n        } else {\r\n            if (this._animationState.loopMode === Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT) {\r\n                if (this._currentValue.addToRef) {\r\n                    this._currentValue.addToRef(this._originalValue[targetIndex], destination[this._targetPath]);\r\n                } else {\r\n                    destination[this._targetPath] = this._originalValue[targetIndex] + this._currentValue;\r\n                }\r\n            } else {\r\n                destination[this._targetPath] = this._currentValue;\r\n            }\r\n        }\r\n\r\n        if (target.markAsDirty) {\r\n            target.markAsDirty(this._animation.targetProperty);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the loop pmode of the runtime animation\r\n     * @returns Loop Mode\r\n     */\r\n    private _getCorrectLoopMode(): number | undefined {\r\n        if (this._target && this._target.animationPropertiesOverride) {\r\n            // A morph target with no per-target override inherits the scene-level animationPropertiesOverride.\r\n            // That loop mode is meant for transform/bone animations: honoring it here would force the morph\r\n            // influence into (for example) RELATIVE mode and make it accumulate offset * repeatCount every loop.\r\n            // When the override is the inherited scene one, use the animation's own loop mode instead.\r\n            // An override set explicitly on the morph target is still respected.\r\n            const isMorphTarget = this._target.getClassName?.() === \"MorphTarget\";\r\n\r\n            // MorphTarget.animationPropertiesOverride getter inherits from the scene when no per-target override is set.\r\n\r\n            // Only bypass the override when it is truly inherited (ie. the target has no local override).\r\n\r\n            if (isMorphTarget && (this._target as any)._animationPropertiesOverride == null) {\r\n                return this._animation.loopMode;\r\n            }\r\n\r\n            return this._target.animationPropertiesOverride.loopMode as number;\r\n        }\r\n\r\n        return this._animation.loopMode;\r\n    }\r\n\r\n    /**\r\n     * Move the current animation to a given frame\r\n     * @param frame defines the frame to move to\r\n     * @param weight defines the weight to apply to the animation (-1.0 by default)\r\n     */\r\n    public goToFrame(frame: number, weight = -1): void {\r\n        const keys = this._animation.getKeys();\r\n\r\n        if (frame < keys[0].frame) {\r\n            frame = keys[0].frame;\r\n        } else if (frame > keys[keys.length - 1].frame) {\r\n            frame = keys[keys.length - 1].frame;\r\n        }\r\n\r\n        // Need to reset animation events\r\n        const events = this._events;\r\n        if (events.length) {\r\n            for (let index = 0; index < events.length; index++) {\r\n                if (!events[index].onlyOnce) {\r\n                    // reset events in the future\r\n                    events[index].isDone = events[index].frame < frame;\r\n                }\r\n            }\r\n        }\r\n\r\n        this._currentFrame = frame;\r\n        const currentValue = this._animation._interpolate(frame, this._animationState);\r\n\r\n        this.setValue(currentValue, weight);\r\n    }\r\n\r\n    /**\r\n     * @internal Internal use only\r\n     */\r\n    public _prepareForSpeedRatioChange(newSpeedRatio: number): void {\r\n        const newAbsoluteFrame = (this._previousElapsedTime * (this._animation.framePerSecond * newSpeedRatio)) / 1000.0;\r\n\r\n        this._absoluteFrameOffset = this._previousAbsoluteFrame - newAbsoluteFrame;\r\n    }\r\n\r\n    /**\r\n     * Execute the current animation\r\n     * @param elapsedTimeSinceAnimationStart defines the elapsed time (in milliseconds) since the animation was started\r\n     * @param from defines the lower frame of the animation range\r\n     * @param to defines the upper frame of the animation range\r\n     * @param loop defines if the current animation must loop\r\n     * @param speedRatio defines the current speed ratio\r\n     * @param weight defines the weight of the animation (default is -1 so no weight)\r\n     * @returns a boolean indicating if the animation is running\r\n     */\r\n    public animate(elapsedTimeSinceAnimationStart: number, from: number, to: number, loop: boolean, speedRatio: number, weight = -1.0): boolean {\r\n        const animation = this._animation;\r\n        const targetPropertyPath = animation.targetPropertyPath;\r\n        if (!targetPropertyPath || targetPropertyPath.length < 1) {\r\n            this._stopped = true;\r\n            return false;\r\n        }\r\n\r\n        let returnValue = true;\r\n        let currentFrame: number;\r\n        const events = this._events;\r\n        let frameRange: number;\r\n\r\n        if (!this._coreRuntimeAnimation) {\r\n            // Check limits\r\n            if (from < this._minFrame || from > this._maxFrame) {\r\n                from = this._minFrame;\r\n            }\r\n            if (to < this._minFrame || to > this._maxFrame) {\r\n                to = this._maxFrame;\r\n            }\r\n\r\n            frameRange = to - from;\r\n            let offsetValue: any;\r\n\r\n            // Compute the frame according to the elapsed time and the fps of the animation (\"from\" and \"to\" are not factored in!)\r\n            let absoluteFrame = (elapsedTimeSinceAnimationStart * (animation.framePerSecond * speedRatio)) / 1000.0 + this._absoluteFrameOffset;\r\n            let highLimitValue = 0;\r\n\r\n            // Apply the yoyo function if required\r\n            let yoyoLoop = false;\r\n            const yoyoMode = loop && this._animationState.loopMode === Animation.ANIMATIONLOOPMODE_YOYO;\r\n            if (yoyoMode) {\r\n                const position = (absoluteFrame - from) / frameRange;\r\n\r\n                // Apply the yoyo curve\r\n                const sin = Math.sin(position * Math.PI);\r\n                const yoyoPosition = Math.abs(sin);\r\n\r\n                // Map the yoyo position back to the range\r\n                absoluteFrame = yoyoPosition * frameRange + from;\r\n\r\n                const direction = sin >= 0 ? 1 : -1;\r\n                if (this._yoyoDirection !== direction) {\r\n                    yoyoLoop = true;\r\n                }\r\n\r\n                this._yoyoDirection = direction;\r\n            }\r\n\r\n            this._previousElapsedTime = elapsedTimeSinceAnimationStart;\r\n            this._previousAbsoluteFrame = absoluteFrame;\r\n\r\n            if (!loop && to >= from && ((absoluteFrame >= frameRange && speedRatio > 0) || (absoluteFrame <= 0 && speedRatio < 0))) {\r\n                // If we are out of range and not looping get back to caller\r\n                returnValue = false;\r\n                highLimitValue = animation.evaluate(to);\r\n            } else if (!loop && from >= to && ((absoluteFrame <= frameRange && speedRatio < 0) || (absoluteFrame >= 0 && speedRatio > 0))) {\r\n                returnValue = false;\r\n                highLimitValue = animation.evaluate(from);\r\n            } else if (this._animationState.loopMode !== Animation.ANIMATIONLOOPMODE_CYCLE) {\r\n                const keyOffset = to.toString() + from.toString();\r\n                if (!this._offsetsCache[keyOffset]) {\r\n                    this._animationState.repeatCount = 0;\r\n                    this._animationState.loopMode = Animation.ANIMATIONLOOPMODE_CYCLE; // force a specific codepath in animation._interpolate()!\r\n                    const fromValue = animation._interpolate(from, this._animationState);\r\n                    const toValue = animation._interpolate(to, this._animationState);\r\n\r\n                    this._animationState.loopMode = this._getCorrectLoopMode();\r\n                    switch (animation.dataType) {\r\n                        // Float\r\n                        case Animation.ANIMATIONTYPE_FLOAT:\r\n                            this._offsetsCache[keyOffset] = toValue - fromValue;\r\n                            break;\r\n                        // Quaternion\r\n                        case Animation.ANIMATIONTYPE_QUATERNION:\r\n                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);\r\n                            break;\r\n                        // Vector3\r\n                        case Animation.ANIMATIONTYPE_VECTOR3:\r\n                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);\r\n                            break;\r\n                        // Vector2\r\n                        case Animation.ANIMATIONTYPE_VECTOR2:\r\n                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);\r\n                            break;\r\n                        // Size\r\n                        case Animation.ANIMATIONTYPE_SIZE:\r\n                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);\r\n                            break;\r\n                        // Color3\r\n                        case Animation.ANIMATIONTYPE_COLOR3:\r\n                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);\r\n                            break;\r\n                        // Color4\r\n                        case Animation.ANIMATIONTYPE_COLOR4:\r\n                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);\r\n                            break;\r\n                        default:\r\n                            break;\r\n                    }\r\n\r\n                    this._highLimitsCache[keyOffset] = toValue;\r\n                }\r\n\r\n                highLimitValue = this._highLimitsCache[keyOffset];\r\n                offsetValue = this._offsetsCache[keyOffset];\r\n            }\r\n\r\n            if (offsetValue === undefined) {\r\n                switch (animation.dataType) {\r\n                    // Float\r\n                    case Animation.ANIMATIONTYPE_FLOAT:\r\n                        offsetValue = 0;\r\n                        break;\r\n                    // Quaternion\r\n                    case Animation.ANIMATIONTYPE_QUATERNION:\r\n                        offsetValue = _StaticOffsetValueQuaternion;\r\n                        break;\r\n                    // Vector3\r\n                    case Animation.ANIMATIONTYPE_VECTOR3:\r\n                        offsetValue = _StaticOffsetValueVector3;\r\n                        break;\r\n                    // Vector2\r\n                    case Animation.ANIMATIONTYPE_VECTOR2:\r\n                        offsetValue = _StaticOffsetValueVector2;\r\n                        break;\r\n                    // Size\r\n                    case Animation.ANIMATIONTYPE_SIZE:\r\n                        offsetValue = _StaticOffsetValueSize;\r\n                        break;\r\n                    // Color3\r\n                    case Animation.ANIMATIONTYPE_COLOR3:\r\n                        offsetValue = _StaticOffsetValueColor3;\r\n                        break;\r\n                    case Animation.ANIMATIONTYPE_COLOR4:\r\n                        offsetValue = _StaticOffsetValueColor4;\r\n                        break;\r\n                }\r\n            }\r\n\r\n            // Compute value\r\n\r\n            // The root this evaluation is clocked by, and the progress of the pose it gives, taken before any callback of\r\n            // the evaluation - a loop callback, an event - can synchronize the host with another root or move this one\r\n            const syncRoot = this._host ? this._host.syncRoot : null;\r\n            let syncFrames = this._playbackFrames;\r\n            let syncJumped = false;\r\n            if (syncRoot) {\r\n                // If we must sync with an animatable, calculate the current frame based on the frame of the root animatable\r\n                const syncRange = syncRoot.toFrame - syncRoot.fromFrame;\r\n                const masterFrame = syncRoot.masterFrame;\r\n                const hostNormalizedFrame = (masterFrame - syncRoot.fromFrame) / syncRange;\r\n                currentFrame = from + frameRange * hostNormalizedFrame;\r\n\r\n                const master = syncRoot.getAnimations()[0];\r\n                if (master && syncRange !== 0) {\r\n                    const phase = frameRange * hostNormalizedFrame;\r\n                    const masterEvaluated = master._playbackTo - master._playbackFrom;\r\n                    if (masterEvaluated !== 0 && master._playbackFrom <= syncRoot.fromFrame && master._playbackTo >= syncRoot.toFrame) {\r\n                        // The root's clock covers the range synchronized over: its whole cycles are whole cycles of the follower\r\n                        const masterCycles = Math.round((master._playbackFrames - (master._currentFrame - master._playbackFrom)) / masterEvaluated);\r\n                        syncFrames = frameRange * masterCycles + phase;\r\n                    } else {\r\n                        // Keyed shorter, the root never carries the follower to its end but snaps it back across its range,\r\n                        // which happens exactly when the root's own frame wraps: when that frame moves against the root's\r\n                        // playback. Both are the root's frames, so neither the follower's range nor the root's, whichever\r\n                        // way round each is, changes the comparison.\r\n                        syncJumped = (masterFrame - this._playbackSyncMasterFrame) * (master._playbackFrames - this._playbackSyncMasterPlayed) < 0;\r\n                        syncFrames = phase;\r\n                    }\r\n                    // A jump of the root is a jump of whatever follows it, down the chain\r\n                    syncJumped = syncJumped || master._playbackJumped;\r\n                    this._playbackSyncMasterPlayed = master._playbackFrames;\r\n                    this._playbackSyncMasterFrame = masterFrame;\r\n                }\r\n                // A root with no runtime animation reads as frame 0: the pose snaps there and holds, and so does the progress\r\n            } else {\r\n                if ((absoluteFrame > 0 && from > to) || (absoluteFrame < 0 && from < to)) {\r\n                    currentFrame = returnValue && frameRange !== 0 ? to + (absoluteFrame % frameRange) : from;\r\n                } else {\r\n                    currentFrame = returnValue && frameRange !== 0 ? from + (absoluteFrame % frameRange) : to;\r\n                }\r\n            }\r\n\r\n            // Reset event/state if looping\r\n            if ((!yoyoMode && ((speedRatio > 0 && this.currentFrame > currentFrame) || (speedRatio < 0 && this.currentFrame < currentFrame))) || (yoyoMode && yoyoLoop)) {\r\n                this._onLoop();\r\n\r\n                // Need to reset animation events\r\n                for (let index = 0; index < events.length; index++) {\r\n                    if (!events[index].onlyOnce) {\r\n                        // reset event, the animation is looping\r\n                        events[index].isDone = false;\r\n                    }\r\n                }\r\n\r\n                this._animationState.key = speedRatio > 0 ? 0 : animation.getKeys().length - 1;\r\n            }\r\n            this._currentFrame = currentFrame;\r\n            this._animationState.repeatCount = frameRange === 0 ? 0 : (absoluteFrame / frameRange) >> 0;\r\n            this._animationState.highLimitValue = highLimitValue;\r\n            this._animationState.offsetValue = offsetValue;\r\n\r\n            // The frame evaluated, unwrapped across loops, then the progress of the pose it gave\r\n            this._playbackFrom = from;\r\n            this._playbackTo = to;\r\n            this._playbackJumped = syncJumped;\r\n            this._playbackSyncRoot = syncRoot;\r\n            let frames: number;\r\n            if (syncRoot) {\r\n                frames = syncFrames;\r\n            } else if (!returnValue) {\r\n                // The end of the cycle the playback was in - however many it had been through before it stopped looping - or that cycle's start when it ran backwards\r\n                const cycles = frameRange !== 0 ? Math.floor(this._playbackFrames / frameRange) : 0;\r\n                frames = (currentFrame === to ? cycles + 1 : cycles) * frameRange;\r\n            } else if (yoyoMode) {\r\n                // At the far end of the swing the mapped frame is exactly `to`, which the fold above lands on `from`: the same pose, so the whole range\r\n                frames = currentFrame === from && absoluteFrame === to ? frameRange : currentFrame - from;\r\n            } else {\r\n                frames = absoluteFrame;\r\n            }\r\n            this._playbackFrames = frames;\r\n            // A constant loop holds its last value from its own second cycle on, whatever frame is evaluated\r\n            this._playbackProgress = this._animationState.loopMode === Animation.ANIMATIONLOOPMODE_CONSTANT && this._animationState.repeatCount > 0 ? frameRange : frames;\r\n        } else {\r\n            frameRange = to - from;\r\n            currentFrame = this._coreRuntimeAnimation.currentFrame;\r\n            this._currentFrame = currentFrame;\r\n            this._animationState.repeatCount = this._coreRuntimeAnimation._animationState.repeatCount;\r\n            this._animationState.highLimitValue = this._coreRuntimeAnimation._animationState.highLimitValue;\r\n            this._animationState.offsetValue = this._coreRuntimeAnimation._animationState.offsetValue;\r\n            this._playbackFrom = this._coreRuntimeAnimation._playbackFrom;\r\n            this._playbackTo = this._coreRuntimeAnimation._playbackTo;\r\n            this._playbackFrames = this._coreRuntimeAnimation._playbackFrames;\r\n            this._playbackProgress = this._coreRuntimeAnimation._playbackProgress;\r\n            this._playbackJumped = this._coreRuntimeAnimation._playbackJumped;\r\n            this._playbackSyncRoot = this._coreRuntimeAnimation._playbackSyncRoot;\r\n        }\r\n\r\n        const currentValue = animation._interpolate(currentFrame, this._animationState);\r\n\r\n        // Set value\r\n        this.setValue(currentValue, weight);\r\n\r\n        // Check events\r\n        if (events.length) {\r\n            for (let index = 0; index < events.length; index++) {\r\n                // Make sure current frame has passed event frame and that event frame is within the current range\r\n                // Also, handle both forward and reverse animations\r\n                if (\r\n                    (frameRange >= 0 && currentFrame >= events[index].frame && events[index].frame >= from) ||\r\n                    (frameRange < 0 && currentFrame <= events[index].frame && events[index].frame <= from)\r\n                ) {\r\n                    const event = events[index];\r\n                    if (!event.isDone) {\r\n                        // If event should be done only once, remove it.\r\n                        if (event.onlyOnce) {\r\n                            events.splice(index, 1);\r\n                            index--;\r\n                        }\r\n                        event.isDone = true;\r\n                        event.action(currentFrame);\r\n                    } // Don't do anything if the event has already been done.\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!returnValue) {\r\n            this._stopped = true;\r\n        }\r\n\r\n        return returnValue;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/**\r\n * Checks if the window object exists\r\n * @returns true if the window object exists\r\n */\r\nexport function IsWindowObjectExist(): boolean {\r\n    return typeof window !== \"undefined\";\r\n}\r\n\r\n/**\r\n * Checks if the navigator object exists\r\n * @returns true if the navigator object exists\r\n */\r\nexport function IsNavigatorAvailable(): boolean {\r\n    return typeof navigator !== \"undefined\";\r\n}\r\n\r\n/**\r\n * Check if the document object exists\r\n * @returns true if the document object exists\r\n */\r\nexport function IsDocumentAvailable(): boolean {\r\n    return typeof document !== \"undefined\";\r\n}\r\n\r\n/**\r\n * Extracts text content from a DOM element hierarchy\r\n * @param element defines the root element\r\n * @returns a string\r\n */\r\nexport function GetDOMTextContent(element: HTMLElement): string {\r\n    let result = \"\";\r\n    let child = element.firstChild;\r\n\r\n    while (child) {\r\n        if (child.nodeType === 3) {\r\n            result += child.textContent;\r\n        }\r\n        child = <any>child.nextSibling;\r\n    }\r\n\r\n    return result;\r\n}\r\n\r\n/**\r\n * Sets of helpers dealing with the DOM and some of the recurrent functions needed in\r\n * Babylon.js\r\n */\r\nexport const DomManagement = {\r\n    /**\r\n     * Checks if the window object exists\r\n     * @returns true if the window object exists\r\n     */\r\n    IsWindowObjectExist,\r\n\r\n    /**\r\n     * Checks if the navigator object exists\r\n     * @returns true if the navigator object exists\r\n     */\r\n    IsNavigatorAvailable,\r\n\r\n    /**\r\n     * Check if the document object exists\r\n     * @returns true if the document object exists\r\n     */\r\n    IsDocumentAvailable,\r\n    /**\r\n     * Extracts text content from a DOM element hierarchy\r\n     * @param element defines the root element\r\n     * @returns a string\r\n     */\r\n    GetDOMTextContent,\r\n};\r\n","import { IsWindowObjectExist } from \"./domManagement\";\r\n\r\n/**\r\n * Class containing a set of static utilities functions for precision date\r\n */\r\nexport class PrecisionDate {\r\n    /**\r\n     * Gets either window.performance.now() if supported or Date.now() else\r\n     */\r\n    public static get Now(): number {\r\n        if (IsWindowObjectExist() && window.performance && window.performance.now) {\r\n            return window.performance.now();\r\n        }\r\n\r\n        return Date.now();\r\n    }\r\n}\r\n","import { Observable } from \"core/Misc/observable\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { RuntimeAnimation } from \"./runtimeAnimation\";\r\nimport { Animation } from \"./animation.pure\";\r\nimport { PrecisionDate } from \"core/Misc/precisionDate\";\r\nimport { Matrix, Quaternion, TmpVectors, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Bone } from \"core/Bones/bone\";\r\nimport { type Node } from \"../node\";\r\n\r\n/**\r\n * Class used to store an actual running animation\r\n */\r\nexport class Animatable {\r\n    /**\r\n     * If true, the animatable will be processed even if it is considered actively paused (weight of 0 and previous weight of 0).\r\n     * This can be used to force the full processing of paused animatables in the animation engine.\r\n     * Default is false.\r\n     */\r\n    public static ProcessPausedAnimatables = false;\r\n\r\n    private _localDelayOffset: Nullable<number> = null;\r\n    private _pausedDelay: Nullable<number> = null;\r\n    private _manualJumpDelay: Nullable<number> = null;\r\n    /** @hidden */\r\n    public _runtimeAnimations = new Array<RuntimeAnimation>();\r\n    private _paused = false;\r\n    private _scene: Scene;\r\n    private _speedRatio = 1;\r\n    private _weight = -1.0;\r\n    private _previousWeight = -1.0;\r\n    private _syncRoot: Nullable<Animatable> = null;\r\n    private _frameToSyncFromJump: Nullable<number> = null;\r\n    private _goToFrame: Nullable<number> = null;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the animatable must be disposed and removed at the end of the animation.\r\n     * This will only apply for non looping animation (default is true)\r\n     */\r\n    public disposeOnEnd = true;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the animation has started\r\n     */\r\n    public animationStarted = false;\r\n\r\n    /**\r\n     * Observer raised when the animation ends\r\n     */\r\n    public onAnimationEndObservable = new Observable<Animatable>();\r\n\r\n    /**\r\n     * Observer raised when the animation loops\r\n     */\r\n    public onAnimationLoopObservable = new Observable<Animatable>();\r\n\r\n    /**\r\n     * Gets the root Animatable used to synchronize and normalize animations\r\n     */\r\n    public get syncRoot(): Nullable<Animatable> {\r\n        return this._syncRoot;\r\n    }\r\n\r\n    /**\r\n     * Gets the current frame of the first RuntimeAnimation\r\n     * Used to synchronize Animatables\r\n     */\r\n    public get masterFrame(): number {\r\n        if (this._runtimeAnimations.length === 0) {\r\n            return 0;\r\n        }\r\n\r\n        return this._runtimeAnimations[0].currentFrame;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the animatable weight (-1.0 by default meaning not weighted)\r\n     */\r\n    public get weight(): number {\r\n        return this._weight;\r\n    }\r\n\r\n    public set weight(value: number) {\r\n        if (value === -1) {\r\n            // -1 is ok and means no weight\r\n            this._weight = -1;\r\n            return;\r\n        }\r\n\r\n        // Else weight must be in [0, 1] range\r\n        this._weight = Math.min(Math.max(value, 0), 1.0);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the speed ratio to apply to the animatable (1.0 by default)\r\n     */\r\n    public get speedRatio(): number {\r\n        return this._speedRatio;\r\n    }\r\n\r\n    public set speedRatio(value: number) {\r\n        for (let index = 0; index < this._runtimeAnimations.length; index++) {\r\n            const animation = this._runtimeAnimations[index];\r\n\r\n            animation._prepareForSpeedRatioChange(value);\r\n        }\r\n        this._speedRatio = value;\r\n\r\n        // Resync _manualJumpDelay in case goToFrame was called before speedRatio was set.\r\n        if (this._goToFrame !== null) {\r\n            this.goToFrame(this._goToFrame);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the elapsed time since the animatable started in milliseconds\r\n     */\r\n    public get elapsedTime(): number {\r\n        return this._localDelayOffset === null ? 0 : this._scene._animationTime - this._localDelayOffset;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Animatable\r\n     * @param scene defines the hosting scene\r\n     * @param target defines the target object\r\n     * @param fromFrame defines the starting frame number (default is 0)\r\n     * @param toFrame defines the ending frame number (default is 100)\r\n     * @param loopAnimation defines if the animation must loop (default is false)\r\n     * @param speedRatio defines the factor to apply to animation speed (default is 1)\r\n     * @param onAnimationEnd defines a callback to call when animation ends if it is not looping\r\n     * @param animations defines a group of animation to add to the new Animatable\r\n     * @param onAnimationLoop defines a callback to call when animation loops\r\n     * @param isAdditive defines whether the animation should be evaluated additively\r\n     * @param playOrder defines the order in which this animatable should be processed in the list of active animatables (default: 0)\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        /** defines the target object */\r\n        public target: any,\r\n        /** [0] defines the starting frame number (default is 0) */\r\n        public fromFrame: number = 0,\r\n        /** [100] defines the ending frame number (default is 100) */\r\n        public toFrame: number = 100,\r\n        /** [false] defines if the animation must loop (default is false)  */\r\n        public loopAnimation: boolean = false,\r\n        speedRatio: number = 1.0,\r\n        /** defines a callback to call when animation ends if it is not looping */\r\n        public onAnimationEnd?: Nullable<() => void>,\r\n        animations?: Animation[],\r\n        /** defines a callback to call when animation loops */\r\n        public onAnimationLoop?: Nullable<() => void>,\r\n        /** [false] defines whether the animation should be evaluated additively */\r\n        public isAdditive: boolean = false,\r\n        /** [0] defines the order in which this animatable should be processed in the list of active animatables (default: 0) */\r\n        public playOrder = 0\r\n    ) {\r\n        this._scene = scene;\r\n        if (animations) {\r\n            this.appendAnimations(target, animations);\r\n        }\r\n\r\n        this._speedRatio = speedRatio;\r\n        scene._activeAnimatables.push(this);\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Synchronize and normalize current Animatable with a source Animatable\r\n     * This is useful when using animation weights and when animations are not of the same length\r\n     * @param root defines the root Animatable to synchronize with (null to stop synchronizing)\r\n     * @returns the current Animatable\r\n     */\r\n    public syncWith(root: Nullable<Animatable>): Animatable {\r\n        this._syncRoot = root;\r\n\r\n        if (root) {\r\n            // Make sure this animatable will animate after the root\r\n            const index = this._scene._activeAnimatables.indexOf(this);\r\n            if (index > -1) {\r\n                this._scene._activeAnimatables.splice(index, 1);\r\n                this._scene._activeAnimatables.push(this);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of runtime animations\r\n     * @returns an array of RuntimeAnimation\r\n     */\r\n    public getAnimations(): RuntimeAnimation[] {\r\n        return this._runtimeAnimations;\r\n    }\r\n\r\n    /**\r\n     * Adds more animations to the current animatable\r\n     * @param target defines the target of the animations\r\n     * @param animations defines the new animations to add\r\n     */\r\n    public appendAnimations(target: any, animations: Animation[]): void {\r\n        for (let index = 0; index < animations.length; index++) {\r\n            const animation = animations[index];\r\n\r\n            const newRuntimeAnimation = new RuntimeAnimation(target, animation, this._scene, this);\r\n            newRuntimeAnimation._onLoop = () => {\r\n                this.onAnimationLoopObservable.notifyObservers(this);\r\n                if (this.onAnimationLoop) {\r\n                    this.onAnimationLoop();\r\n                }\r\n            };\r\n\r\n            this._runtimeAnimations.push(newRuntimeAnimation);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the source animation for a specific property\r\n     * @param property defines the property to look for\r\n     * @returns null or the source animation for the given property\r\n     */\r\n    public getAnimationByTargetProperty(property: string): Nullable<Animation> {\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n\r\n        for (let index = 0; index < runtimeAnimations.length; index++) {\r\n            if (runtimeAnimations[index].animation.targetProperty === property) {\r\n                return runtimeAnimations[index].animation;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the runtime animation for a specific property\r\n     * @param property defines the property to look for\r\n     * @returns null or the runtime animation for the given property\r\n     */\r\n    public getRuntimeAnimationByTargetProperty(property: string): Nullable<RuntimeAnimation> {\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n\r\n        for (let index = 0; index < runtimeAnimations.length; index++) {\r\n            if (runtimeAnimations[index].animation.targetProperty === property) {\r\n                return runtimeAnimations[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Resets the animatable to its original state\r\n     */\r\n    public reset(): void {\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n\r\n        for (let index = 0; index < runtimeAnimations.length; index++) {\r\n            runtimeAnimations[index].reset(true);\r\n        }\r\n\r\n        this._localDelayOffset = null;\r\n        this._pausedDelay = null;\r\n    }\r\n\r\n    /**\r\n     * Allows the animatable to blend with current running animations\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\r\n     * @param blendingSpeed defines the blending speed to use\r\n     */\r\n    public enableBlending(blendingSpeed: number): void {\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n\r\n        for (let index = 0; index < runtimeAnimations.length; index++) {\r\n            runtimeAnimations[index].animation.enableBlending = true;\r\n            runtimeAnimations[index].animation.blendingSpeed = blendingSpeed;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disable animation blending\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\r\n     */\r\n    public disableBlending(): void {\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n\r\n        for (let index = 0; index < runtimeAnimations.length; index++) {\r\n            runtimeAnimations[index].animation.enableBlending = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Jump directly to a given frame\r\n     * @param frame defines the frame to jump to\r\n     * @param useWeight defines whether the animation weight should be applied to the image to be jumped to (false by default)\r\n     */\r\n    public goToFrame(frame: number, useWeight = false): void {\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n\r\n        if (runtimeAnimations[0]) {\r\n            const fps = runtimeAnimations[0].animation.framePerSecond;\r\n            this._frameToSyncFromJump = this._frameToSyncFromJump ?? runtimeAnimations[0].currentFrame;\r\n            const delay = this.speedRatio === 0 ? 0 : (((frame - this._frameToSyncFromJump) / fps) * 1000) / this.speedRatio;\r\n            this._manualJumpDelay = -delay;\r\n        }\r\n\r\n        for (let index = 0; index < runtimeAnimations.length; index++) {\r\n            runtimeAnimations[index].goToFrame(frame, useWeight ? this._weight : -1);\r\n        }\r\n\r\n        this._goToFrame = frame;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the animations for this animatable are paused\r\n     */\r\n    public get paused() {\r\n        return this._paused;\r\n    }\r\n\r\n    /**\r\n     * Pause the animation\r\n     */\r\n    public pause(): void {\r\n        if (this._paused) {\r\n            return;\r\n        }\r\n        this._paused = true;\r\n    }\r\n\r\n    /**\r\n     * Restart the animation\r\n     */\r\n    public restart(): void {\r\n        this._paused = false;\r\n    }\r\n\r\n    private _raiseOnAnimationEnd() {\r\n        if (this.onAnimationEnd) {\r\n            this.onAnimationEnd();\r\n        }\r\n\r\n        this.onAnimationEndObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Stop and delete the current animation\r\n     * @param animationName defines a string used to only stop some of the runtime animations instead of all\r\n     * @param targetMask a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)\r\n     * @param useGlobalSplice if true, the animatables will be removed by the caller of this function (false by default)\r\n     * @param skipOnAnimationEnd defines if the system should not raise onAnimationEnd. Default is false\r\n     */\r\n    public stop(animationName?: string, targetMask?: (target: any) => boolean, useGlobalSplice = false, skipOnAnimationEnd = false): void {\r\n        if (animationName || targetMask) {\r\n            const idx = this._scene._activeAnimatables.indexOf(this);\r\n\r\n            if (idx > -1) {\r\n                const runtimeAnimations = this._runtimeAnimations;\r\n\r\n                for (let index = runtimeAnimations.length - 1; index >= 0; index--) {\r\n                    const runtimeAnimation = runtimeAnimations[index];\r\n                    if (animationName && runtimeAnimation.animation.name != animationName) {\r\n                        continue;\r\n                    }\r\n                    if (targetMask && !targetMask(runtimeAnimation.target)) {\r\n                        continue;\r\n                    }\r\n\r\n                    runtimeAnimation.dispose();\r\n                    runtimeAnimations.splice(index, 1);\r\n                }\r\n\r\n                if (runtimeAnimations.length == 0) {\r\n                    if (!useGlobalSplice) {\r\n                        this._scene._activeAnimatables.splice(idx, 1);\r\n                    }\r\n                    if (!skipOnAnimationEnd) {\r\n                        this._raiseOnAnimationEnd();\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const index = this._scene._activeAnimatables.indexOf(this);\r\n\r\n            if (index > -1) {\r\n                if (!useGlobalSplice) {\r\n                    this._scene._activeAnimatables.splice(index, 1);\r\n                }\r\n                const runtimeAnimations = this._runtimeAnimations;\r\n\r\n                for (let index = 0; index < runtimeAnimations.length; index++) {\r\n                    runtimeAnimations[index].dispose();\r\n                }\r\n\r\n                this._runtimeAnimations.length = 0;\r\n\r\n                if (!skipOnAnimationEnd) {\r\n                    this._raiseOnAnimationEnd();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Wait asynchronously for the animation to end\r\n     * @returns a promise which will be fulfilled when the animation ends\r\n     */\r\n    public async waitAsync(): Promise<Animatable> {\r\n        return await new Promise((resolve) => {\r\n            this.onAnimationEndObservable.add(\r\n                () => {\r\n                    resolve(this);\r\n                },\r\n                undefined,\r\n                undefined,\r\n                this,\r\n                true\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _animate(delay: number): boolean {\r\n        if (this._paused) {\r\n            this.animationStarted = false;\r\n            if (this._pausedDelay === null) {\r\n                this._pausedDelay = delay;\r\n            }\r\n            return true;\r\n        }\r\n\r\n        if (this._localDelayOffset === null) {\r\n            this._localDelayOffset = delay;\r\n            this._pausedDelay = null;\r\n        } else if (this._pausedDelay !== null) {\r\n            this._localDelayOffset += delay - this._pausedDelay;\r\n            this._pausedDelay = null;\r\n        }\r\n\r\n        if (this._manualJumpDelay !== null) {\r\n            this._localDelayOffset += this.speedRatio < 0 ? -this._manualJumpDelay : this._manualJumpDelay;\r\n            this._manualJumpDelay = null;\r\n            this._frameToSyncFromJump = null;\r\n        }\r\n\r\n        this._goToFrame = null;\r\n\r\n        if (!Animatable.ProcessPausedAnimatables && this._weight === 0 && this._previousWeight === 0) {\r\n            // We consider that an animatable with a weight === 0 is \"actively\" paused\r\n            return true;\r\n        }\r\n\r\n        this._previousWeight = this._weight;\r\n\r\n        // Animating\r\n        let running = false;\r\n        const runtimeAnimations = this._runtimeAnimations;\r\n        let index: number;\r\n\r\n        for (index = 0; index < runtimeAnimations.length; index++) {\r\n            const animation = runtimeAnimations[index];\r\n            const isRunning = animation.animate(delay - this._localDelayOffset, this.fromFrame, this.toFrame, this.loopAnimation, this._speedRatio, this._weight);\r\n            running = running || isRunning;\r\n        }\r\n\r\n        this.animationStarted = running;\r\n\r\n        if (!running) {\r\n            if (this.disposeOnEnd) {\r\n                // Remove from active animatables\r\n                index = this._scene._activeAnimatables.indexOf(this);\r\n                this._scene._activeAnimatables.splice(index, 1);\r\n\r\n                // Dispose all runtime animations\r\n                for (index = 0; index < runtimeAnimations.length; index++) {\r\n                    runtimeAnimations[index].dispose();\r\n                }\r\n            }\r\n\r\n            this._raiseOnAnimationEnd();\r\n\r\n            if (this.disposeOnEnd) {\r\n                this.onAnimationEnd = null;\r\n                this.onAnimationLoop = null;\r\n                this.onAnimationLoopObservable.clear();\r\n                this.onAnimationEndObservable.clear();\r\n            }\r\n        }\r\n\r\n        return running;\r\n    }\r\n}\r\n\r\n/** @internal */\r\nfunction ProcessLateAnimationBindingsForMatrices(holder: {\r\n    totalWeight: number;\r\n    totalAdditiveWeight: number;\r\n    animations: RuntimeAnimation[];\r\n    additiveAnimations: RuntimeAnimation[];\r\n    originalValue: Matrix;\r\n}): any {\r\n    if (holder.totalWeight === 0 && holder.totalAdditiveWeight === 0) {\r\n        return holder.originalValue;\r\n    }\r\n\r\n    let normalizer = 1.0;\r\n    const finalPosition = TmpVectors.Vector3[0];\r\n    const finalScaling = TmpVectors.Vector3[1];\r\n    const finalQuaternion = TmpVectors.Quaternion[0];\r\n    let startIndex = 0;\r\n    const originalAnimation = holder.animations[0];\r\n    const originalValue = holder.originalValue;\r\n\r\n    let scale: number;\r\n    let skipOverride = false;\r\n    if (holder.totalWeight < 1.0) {\r\n        // We need to mix the original value in\r\n        scale = 1.0 - holder.totalWeight;\r\n        originalValue.decompose(finalScaling, finalQuaternion, finalPosition);\r\n    } else {\r\n        startIndex = 1;\r\n        // We need to normalize the weights\r\n        normalizer = holder.totalWeight;\r\n        scale = originalAnimation.weight / normalizer;\r\n        if (scale == 1) {\r\n            if (holder.totalAdditiveWeight) {\r\n                skipOverride = true;\r\n            } else {\r\n                return originalAnimation.currentValue;\r\n            }\r\n        }\r\n\r\n        originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);\r\n    }\r\n\r\n    // Add up the override animations\r\n    if (!skipOverride) {\r\n        finalScaling.scaleInPlace(scale);\r\n        finalPosition.scaleInPlace(scale);\r\n        finalQuaternion.scaleInPlace(scale);\r\n\r\n        for (let animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {\r\n            const runtimeAnimation = holder.animations[animIndex];\r\n            if (runtimeAnimation.weight === 0) {\r\n                continue;\r\n            }\r\n\r\n            scale = runtimeAnimation.weight / normalizer;\r\n            const currentPosition = TmpVectors.Vector3[2];\r\n            const currentScaling = TmpVectors.Vector3[3];\r\n            const currentQuaternion = TmpVectors.Quaternion[1];\r\n\r\n            runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);\r\n\r\n            currentScaling.scaleAndAddToRef(scale, finalScaling);\r\n            currentQuaternion.scaleAndAddToRef(Quaternion.Dot(finalQuaternion, currentQuaternion) > 0 ? scale : -scale, finalQuaternion);\r\n            currentPosition.scaleAndAddToRef(scale, finalPosition);\r\n        }\r\n\r\n        finalQuaternion.normalize();\r\n    }\r\n\r\n    // Add up the additive animations\r\n    for (let animIndex = 0; animIndex < holder.additiveAnimations.length; animIndex++) {\r\n        const runtimeAnimation = holder.additiveAnimations[animIndex];\r\n        if (runtimeAnimation.weight === 0) {\r\n            continue;\r\n        }\r\n\r\n        const currentPosition = TmpVectors.Vector3[2];\r\n        const currentScaling = TmpVectors.Vector3[3];\r\n        const currentQuaternion = TmpVectors.Quaternion[1];\r\n\r\n        runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);\r\n        currentScaling.multiplyToRef(finalScaling, currentScaling);\r\n        Vector3.LerpToRef(finalScaling, currentScaling, runtimeAnimation.weight, finalScaling);\r\n        finalQuaternion.multiplyToRef(currentQuaternion, currentQuaternion);\r\n        Quaternion.SlerpToRef(finalQuaternion, currentQuaternion, runtimeAnimation.weight, finalQuaternion);\r\n        currentPosition.scaleAndAddToRef(runtimeAnimation.weight, finalPosition);\r\n    }\r\n\r\n    const workValue = originalAnimation ? originalAnimation._animationState.workValue : TmpVectors.Matrix[0].clone();\r\n    Matrix.ComposeToRef(finalScaling, finalQuaternion, finalPosition, workValue);\r\n    return workValue;\r\n}\r\n\r\n/** @internal */\r\nfunction ProcessLateAnimationBindingsForQuaternions(\r\n    holder: {\r\n        totalWeight: number;\r\n        totalAdditiveWeight: number;\r\n        animations: RuntimeAnimation[];\r\n        additiveAnimations: RuntimeAnimation[];\r\n        originalValue: Quaternion;\r\n    },\r\n    refQuaternion: Quaternion\r\n): Quaternion {\r\n    if (holder.totalWeight === 0 && holder.totalAdditiveWeight === 0) {\r\n        return refQuaternion;\r\n    }\r\n\r\n    const originalAnimation = holder.animations[0];\r\n    const originalValue = holder.originalValue;\r\n    let cumulativeQuaternion = refQuaternion;\r\n\r\n    if (holder.totalWeight === 0 && holder.totalAdditiveWeight > 0) {\r\n        cumulativeQuaternion.copyFrom(originalValue);\r\n    } else if (holder.animations.length === 1) {\r\n        Quaternion.SlerpToRef(originalValue, originalAnimation.currentValue, Math.min(1.0, holder.totalWeight), cumulativeQuaternion);\r\n\r\n        if (holder.totalAdditiveWeight === 0) {\r\n            return cumulativeQuaternion;\r\n        }\r\n    } else if (holder.animations.length > 1) {\r\n        // Add up the override animations\r\n        let normalizer = 1.0;\r\n        let quaternions: Array<Quaternion>;\r\n        let weights: Array<number>;\r\n\r\n        if (holder.totalWeight < 1.0) {\r\n            const scale = 1.0 - holder.totalWeight;\r\n\r\n            quaternions = [];\r\n            weights = [];\r\n\r\n            quaternions.push(originalValue);\r\n            weights.push(scale);\r\n        } else {\r\n            if (holder.animations.length === 2) {\r\n                // Slerp as soon as we can\r\n                Quaternion.SlerpToRef(holder.animations[0].currentValue, holder.animations[1].currentValue, holder.animations[1].weight / holder.totalWeight, refQuaternion);\r\n\r\n                if (holder.totalAdditiveWeight === 0) {\r\n                    return refQuaternion;\r\n                }\r\n            }\r\n\r\n            quaternions = [];\r\n            weights = [];\r\n            normalizer = holder.totalWeight;\r\n        }\r\n\r\n        for (let animIndex = 0; animIndex < holder.animations.length; animIndex++) {\r\n            const runtimeAnimation = holder.animations[animIndex];\r\n            quaternions.push(runtimeAnimation.currentValue);\r\n            weights.push(runtimeAnimation.weight / normalizer);\r\n        }\r\n\r\n        // https://gamedev.stackexchange.com/questions/62354/method-for-interpolation-between-3-quaternions\r\n\r\n        let cumulativeAmount = 0;\r\n        for (let index = 0; index < quaternions.length;) {\r\n            if (!index) {\r\n                Quaternion.SlerpToRef(quaternions[index], quaternions[index + 1], weights[index + 1] / (weights[index] + weights[index + 1]), refQuaternion);\r\n                cumulativeQuaternion = refQuaternion;\r\n                cumulativeAmount = weights[index] + weights[index + 1];\r\n                index += 2;\r\n                continue;\r\n            }\r\n            cumulativeAmount += weights[index];\r\n            Quaternion.SlerpToRef(cumulativeQuaternion, quaternions[index], weights[index] / cumulativeAmount, cumulativeQuaternion);\r\n            index++;\r\n        }\r\n    }\r\n\r\n    // Add up the additive animations\r\n    for (let animIndex = 0; animIndex < holder.additiveAnimations.length; animIndex++) {\r\n        const runtimeAnimation = holder.additiveAnimations[animIndex];\r\n        if (runtimeAnimation.weight === 0) {\r\n            continue;\r\n        }\r\n\r\n        cumulativeQuaternion.multiplyToRef(runtimeAnimation.currentValue, TmpVectors.Quaternion[0]);\r\n        Quaternion.SlerpToRef(cumulativeQuaternion, TmpVectors.Quaternion[0], runtimeAnimation.weight, cumulativeQuaternion);\r\n    }\r\n\r\n    return cumulativeQuaternion;\r\n}\r\n\r\n/** @internal */\r\nfunction ProcessLateAnimationBindings(scene: Scene): void {\r\n    if (!scene._registeredForLateAnimationBindings.length) {\r\n        return;\r\n    }\r\n    for (let index = 0; index < scene._registeredForLateAnimationBindings.length; index++) {\r\n        const target = scene._registeredForLateAnimationBindings.data[index];\r\n\r\n        for (const path in target._lateAnimationHolders) {\r\n            const holder = target._lateAnimationHolders[path];\r\n            const originalAnimation: RuntimeAnimation = holder.animations[0];\r\n            const originalValue = holder.originalValue;\r\n            if (originalValue === undefined || originalValue === null) {\r\n                continue;\r\n            }\r\n            const matrixDecomposeMode = Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix\r\n\r\n            let finalValue: any = target[path];\r\n            if (matrixDecomposeMode) {\r\n                finalValue = ProcessLateAnimationBindingsForMatrices(holder);\r\n            } else {\r\n                const quaternionMode = originalValue.w !== undefined;\r\n                if (quaternionMode) {\r\n                    finalValue = ProcessLateAnimationBindingsForQuaternions(holder, finalValue || Quaternion.Identity());\r\n                } else {\r\n                    let startIndex = 0;\r\n                    let normalizer = 1.0;\r\n\r\n                    const originalAnimationIsLoopRelativeFromCurrent =\r\n                        originalAnimation && originalAnimation._animationState.loopMode === Animation.ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT;\r\n\r\n                    if (holder.totalWeight < 1.0) {\r\n                        // We need to mix the original value in\r\n                        if (originalAnimationIsLoopRelativeFromCurrent) {\r\n                            finalValue = originalValue.clone ? originalValue.clone() : originalValue;\r\n                        } else if (originalAnimation && originalValue.scale) {\r\n                            finalValue = originalValue.scale(1.0 - holder.totalWeight);\r\n                        } else if (originalAnimation) {\r\n                            finalValue = originalValue * (1.0 - holder.totalWeight);\r\n                        } else if (originalValue.clone) {\r\n                            finalValue = originalValue.clone();\r\n                        } else {\r\n                            finalValue = originalValue;\r\n                        }\r\n                    } else if (originalAnimation) {\r\n                        // We need to normalize the weights\r\n                        normalizer = holder.totalWeight;\r\n                        const scale = originalAnimation.weight / normalizer;\r\n                        if (scale !== 1) {\r\n                            if (originalAnimation.currentValue.scale) {\r\n                                finalValue = originalAnimation.currentValue.scale(scale);\r\n                            } else {\r\n                                finalValue = originalAnimation.currentValue * scale;\r\n                            }\r\n                        } else if ((holder.animations.length > 1 || holder.additiveAnimations.length > 0) && originalAnimation.currentValue.clone) {\r\n                            // Copied rather than aliased: the entries that follow add into finalValue, and one of them\r\n                            // may be this very animation, whose current value must not add into itself.\r\n                            finalValue = originalAnimation.currentValue.clone();\r\n                        } else {\r\n                            finalValue = originalAnimation.currentValue;\r\n                        }\r\n\r\n                        if (originalAnimationIsLoopRelativeFromCurrent) {\r\n                            if (finalValue.addToRef) {\r\n                                finalValue.addToRef(originalValue, finalValue);\r\n                            } else {\r\n                                finalValue += originalValue;\r\n                            }\r\n                        }\r\n\r\n                        startIndex = 1;\r\n                    }\r\n\r\n                    // Add up the override animations\r\n                    for (let animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {\r\n                        const runtimeAnimation = holder.animations[animIndex];\r\n                        const scale = runtimeAnimation.weight / normalizer;\r\n\r\n                        if (!scale) {\r\n                            continue;\r\n                        } else if (runtimeAnimation.currentValue.scaleAndAddToRef) {\r\n                            runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);\r\n                        } else {\r\n                            finalValue += runtimeAnimation.currentValue * scale;\r\n                        }\r\n                    }\r\n\r\n                    // Add up the additive animations\r\n                    for (let animIndex = 0; animIndex < holder.additiveAnimations.length; animIndex++) {\r\n                        const runtimeAnimation = holder.additiveAnimations[animIndex];\r\n                        const scale: number = runtimeAnimation.weight;\r\n\r\n                        if (!scale) {\r\n                            continue;\r\n                        } else if (runtimeAnimation.currentValue.scaleAndAddToRef) {\r\n                            runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);\r\n                        } else {\r\n                            finalValue += runtimeAnimation.currentValue * scale;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            target[path] = finalValue;\r\n        }\r\n\r\n        target._lateAnimationHolders = {};\r\n    }\r\n    scene._registeredForLateAnimationBindings.reset();\r\n}\r\n\r\n/** @internal */\r\nexport function RegisterTargetForLateAnimationBinding(scene: Scene, runtimeAnimation: RuntimeAnimation, originalValue: any): void {\r\n    const target = runtimeAnimation.target;\r\n    scene._registeredForLateAnimationBindings.pushNoDuplicate(target);\r\n\r\n    if (!target._lateAnimationHolders) {\r\n        target._lateAnimationHolders = {};\r\n    }\r\n\r\n    if (!target._lateAnimationHolders[runtimeAnimation.targetPath]) {\r\n        target._lateAnimationHolders[runtimeAnimation.targetPath] = {\r\n            totalWeight: 0,\r\n            totalAdditiveWeight: 0,\r\n            animations: [],\r\n            additiveAnimations: [],\r\n            originalValue: originalValue,\r\n        };\r\n    }\r\n\r\n    if (runtimeAnimation.isAdditive) {\r\n        target._lateAnimationHolders[runtimeAnimation.targetPath].additiveAnimations.push(runtimeAnimation);\r\n        target._lateAnimationHolders[runtimeAnimation.targetPath].totalAdditiveWeight += runtimeAnimation.weight;\r\n    } else {\r\n        target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);\r\n        target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;\r\n    }\r\n}\r\n\r\n/**\r\n * Initialize all the inter dependecies between the animations and Scene and Bone\r\n * @param sceneClass defines the scene prototype to use\r\n * @param boneClass defines the bone prototype to use\r\n */\r\nexport function AddAnimationExtensions(sceneClass: typeof Scene, boneClass: typeof Bone): void {\r\n    if (boneClass) {\r\n        boneClass.prototype.copyAnimationRange = function (\r\n            source: Bone,\r\n            rangeName: string,\r\n            frameOffset: number,\r\n            rescaleAsRequired = false,\r\n            skelDimensionsRatio: Nullable<Vector3> = null\r\n        ): boolean {\r\n            // all animation may be coming from a library skeleton, so may need to create animation\r\n            if (this.animations.length === 0) {\r\n                this.animations.push(new Animation(this.name, \"_matrix\", source.animations[0].framePerSecond, Animation.ANIMATIONTYPE_MATRIX, 0));\r\n                this.animations[0].setKeys([]);\r\n            }\r\n\r\n            // get animation info / verify there is such a range from the source bone\r\n            const sourceRange = source.animations[0].getRange(rangeName);\r\n            if (!sourceRange) {\r\n                return false;\r\n            }\r\n            const from = sourceRange.from;\r\n            const to = sourceRange.to;\r\n            const sourceKeys = source.animations[0].getKeys();\r\n\r\n            // rescaling prep\r\n            const sourceBoneLength = source.length;\r\n            const sourceParent = source.getParent();\r\n            const parent = this.getParent();\r\n            const parentScalingReqd = rescaleAsRequired && sourceParent && sourceBoneLength && this.length && sourceBoneLength !== this.length;\r\n            const parentRatio = parentScalingReqd && parent && sourceParent ? parent.length / sourceParent.length : 1;\r\n\r\n            const dimensionsScalingReqd =\r\n                rescaleAsRequired && !parent && skelDimensionsRatio && (skelDimensionsRatio.x !== 1 || skelDimensionsRatio.y !== 1 || skelDimensionsRatio.z !== 1);\r\n\r\n            const destKeys = this.animations[0].getKeys();\r\n\r\n            // loop vars declaration\r\n            let orig: { frame: number; value: Matrix };\r\n            let origTranslation: Vector3;\r\n            let mat: Matrix;\r\n\r\n            for (let key = 0, nKeys = sourceKeys.length; key < nKeys; key++) {\r\n                orig = sourceKeys[key];\r\n                if (orig.frame >= from && orig.frame <= to) {\r\n                    if (rescaleAsRequired) {\r\n                        mat = orig.value.clone();\r\n\r\n                        // scale based on parent ratio, when bone has parent\r\n                        if (parentScalingReqd) {\r\n                            origTranslation = mat.getTranslation();\r\n                            mat.setTranslation(origTranslation.scaleInPlace(parentRatio));\r\n\r\n                            // scale based on skeleton dimension ratio when root bone, and value is passed\r\n                        } else if (dimensionsScalingReqd && skelDimensionsRatio) {\r\n                            origTranslation = mat.getTranslation();\r\n                            mat.setTranslation(origTranslation.multiplyInPlace(skelDimensionsRatio));\r\n\r\n                            // use original when root bone, and no data for skelDimensionsRatio\r\n                        } else {\r\n                            mat = orig.value;\r\n                        }\r\n                    } else {\r\n                        mat = orig.value;\r\n                    }\r\n                    destKeys.push({ frame: orig.frame + frameOffset, value: mat });\r\n                }\r\n            }\r\n            this.animations[0].createRange(rangeName, from + frameOffset, to + frameOffset);\r\n            return true;\r\n        };\r\n    }\r\n\r\n    if (!sceneClass) {\r\n        return;\r\n    }\r\n\r\n    sceneClass.prototype._animate = function (customDeltaTime?: number): void {\r\n        // The records the last step's bindings processed have been read by now and must not outlive that step. Those\r\n        // made since - between steps, with bindings still pending - move to the front and stay.\r\n        //\r\n        // A direct write registered no binding: it is held over one step, to be read there in the order the bindings\r\n        // resolve, and released by the next. Without that bound a step that returns early - its animations disabled, or\r\n        // nothing active to animate - would hold every record it has while writes made between steps kept arriving, as\r\n        // they do from an animation group sampling a virtual timeline. A weighted write is held for as long as the\r\n        // binding it registered is pending, however many steps pass before one processes it.\r\n        const writes = this._animationWrites;\r\n        const count = this._animationWriteCount;\r\n        let kept = 0;\r\n        for (let index = this._animationStepWriteCount; index < count; index++) {\r\n            const write = writes[index];\r\n            if (write.carried && write.weight === -1) {\r\n                continue;\r\n            }\r\n            write.carried = true;\r\n            writes[index] = writes[kept];\r\n            writes[kept] = write;\r\n            kept++;\r\n        }\r\n        for (let index = kept; index < count; index++) {\r\n            const write = writes[index];\r\n            write.runtimeAnimation = null;\r\n            write.target = null;\r\n        }\r\n        this._animationWriteCount = kept;\r\n        this._animationStepWriteCount = 0;\r\n        this._animationStepEvaluated = false;\r\n        if (!this.animationsEnabled) {\r\n            return;\r\n        }\r\n\r\n        // Getting time\r\n        const now = PrecisionDate.Now;\r\n        if (!this._animationTimeLast) {\r\n            if (this._pendingData.length > 0) {\r\n                return;\r\n            }\r\n            this._animationTimeLast = now;\r\n        }\r\n\r\n        this.deltaTime = customDeltaTime !== undefined ? customDeltaTime : this.useConstantAnimationDeltaTime ? 16.0 : (now - this._animationTimeLast) * this.animationTimeScale;\r\n        this._animationTimeLast = now;\r\n\r\n        const animatables = this._activeAnimatables;\r\n        if (animatables.length === 0) {\r\n            return;\r\n        }\r\n\r\n        this._animationTime += this.deltaTime;\r\n        const animationTime = this._animationTime;\r\n        this._animationStepEvaluated = true;\r\n\r\n        for (let index = 0; index < animatables.length; index++) {\r\n            const animatable = animatables[index];\r\n\r\n            if (!animatable._animate(animationTime) && animatable.disposeOnEnd) {\r\n                index--; // Array was updated\r\n            }\r\n        }\r\n\r\n        // Late animation bindings\r\n        ProcessLateAnimationBindings(this);\r\n        this._animationStepWriteCount = this._animationWriteCount;\r\n    };\r\n\r\n    sceneClass.prototype.sortActiveAnimatables = function (): void {\r\n        this._activeAnimatables.sort((a, b) => {\r\n            return a.playOrder - b.playOrder;\r\n        });\r\n    };\r\n\r\n    sceneClass.prototype.beginWeightedAnimation = function (\r\n        target: any,\r\n        from: number,\r\n        to: number,\r\n        weight = 1.0,\r\n        loop?: boolean,\r\n        speedRatio: number = 1.0,\r\n        onAnimationEnd?: () => void,\r\n        animatable?: Animatable,\r\n        targetMask?: (target: any) => boolean,\r\n        onAnimationLoop?: () => void,\r\n        isAdditive = false\r\n    ): Animatable {\r\n        const returnedAnimatable = this.beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable, false, targetMask, onAnimationLoop, isAdditive);\r\n        returnedAnimatable.weight = weight;\r\n\r\n        return returnedAnimatable;\r\n    };\r\n\r\n    sceneClass.prototype.beginAnimation = function (\r\n        target: any,\r\n        from: number,\r\n        to: number,\r\n        loop?: boolean,\r\n        speedRatio: number = 1.0,\r\n        onAnimationEnd?: () => void,\r\n        animatable?: Animatable,\r\n        stopCurrent = true,\r\n        targetMask?: (target: any) => boolean,\r\n        onAnimationLoop?: () => void,\r\n        isAdditive = false\r\n    ): Animatable {\r\n        // get speed speedRatio, to and from, based on the sign and value(s)\r\n        if (speedRatio < 0) {\r\n            const tmp = from;\r\n            from = to;\r\n            to = tmp;\r\n            speedRatio = -speedRatio;\r\n        }\r\n        // if from > to switch speed ratio\r\n        if (from > to) {\r\n            speedRatio = -speedRatio;\r\n        }\r\n        if (stopCurrent) {\r\n            this.stopAnimation(target, undefined, targetMask);\r\n        }\r\n\r\n        if (!animatable) {\r\n            animatable = new Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd, undefined, onAnimationLoop, isAdditive);\r\n        }\r\n\r\n        const shouldRunTargetAnimations = targetMask ? targetMask(target) : true;\r\n        // Local animations\r\n        if (target.animations && shouldRunTargetAnimations) {\r\n            animatable.appendAnimations(target, target.animations);\r\n        }\r\n\r\n        // Children animations\r\n        if (target.getAnimatables) {\r\n            const animatables = target.getAnimatables();\r\n            for (let index = 0; index < animatables.length; index++) {\r\n                this.beginAnimation(animatables[index], from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask, onAnimationLoop);\r\n            }\r\n        }\r\n\r\n        animatable.reset();\r\n\r\n        return animatable;\r\n    };\r\n\r\n    sceneClass.prototype.beginHierarchyAnimation = function (\r\n        target: any,\r\n        directDescendantsOnly: boolean,\r\n        from: number,\r\n        to: number,\r\n        loop?: boolean,\r\n        speedRatio: number = 1.0,\r\n        onAnimationEnd?: () => void,\r\n        animatable?: Animatable,\r\n        stopCurrent = true,\r\n        targetMask?: (target: any) => boolean,\r\n        onAnimationLoop?: () => void,\r\n        isAdditive = false\r\n    ): Animatable[] {\r\n        const children = target.getDescendants(directDescendantsOnly);\r\n\r\n        const result = [];\r\n        result.push(this.beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask, undefined, isAdditive));\r\n        for (const child of children) {\r\n            result.push(this.beginAnimation(child, from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask, undefined, isAdditive));\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    sceneClass.prototype.beginDirectAnimation = function (\r\n        target: any,\r\n        animations: Animation[],\r\n        from: number,\r\n        to: number,\r\n        loop?: boolean,\r\n        speedRatio: number = 1.0,\r\n        onAnimationEnd?: () => void,\r\n        onAnimationLoop?: () => void,\r\n        isAdditive = false\r\n    ): Animatable {\r\n        // get speed speedRatio, to and from, based on the sign and value(s)\r\n        if (speedRatio < 0) {\r\n            const tmp = from;\r\n            from = to;\r\n            to = tmp;\r\n            speedRatio = -speedRatio;\r\n        }\r\n        // if from > to switch speed ratio\r\n        if (from > to) {\r\n            speedRatio = -speedRatio;\r\n        }\r\n        const animatable = new Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd, animations, onAnimationLoop, isAdditive);\r\n\r\n        return animatable;\r\n    };\r\n\r\n    sceneClass.prototype.beginDirectHierarchyAnimation = function (\r\n        target: Node,\r\n        directDescendantsOnly: boolean,\r\n        animations: Animation[],\r\n        from: number,\r\n        to: number,\r\n        loop?: boolean,\r\n        speedRatio?: number,\r\n        onAnimationEnd?: () => void,\r\n        onAnimationLoop?: () => void,\r\n        isAdditive = false\r\n    ): Animatable[] {\r\n        const children = target.getDescendants(directDescendantsOnly);\r\n\r\n        const result = [];\r\n        result.push(this.beginDirectAnimation(target, animations, from, to, loop, speedRatio, onAnimationEnd, onAnimationLoop, isAdditive));\r\n        for (const child of children) {\r\n            result.push(this.beginDirectAnimation(child, animations, from, to, loop, speedRatio, onAnimationEnd, onAnimationLoop, isAdditive));\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    sceneClass.prototype.getAnimatableByTarget = function (target: any): Nullable<Animatable> {\r\n        for (let index = 0; index < this._activeAnimatables.length; index++) {\r\n            if (this._activeAnimatables[index].target === target) {\r\n                return this._activeAnimatables[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    sceneClass.prototype.getAllAnimatablesByTarget = function (target: any): Array<Animatable> {\r\n        const result = [];\r\n        for (let index = 0; index < this._activeAnimatables.length; index++) {\r\n            if (this._activeAnimatables[index].target === target) {\r\n                result.push(this._activeAnimatables[index]);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    sceneClass.prototype.stopAnimation = function (target: any, animationName?: string, targetMask?: (target: any) => boolean): void {\r\n        const animatables = this.getAllAnimatablesByTarget(target);\r\n\r\n        for (const animatable of animatables) {\r\n            animatable.stop(animationName, targetMask);\r\n        }\r\n    };\r\n\r\n    sceneClass.prototype.stopAllAnimations = function (): void {\r\n        if (this._activeAnimatables) {\r\n            for (let i = 0; i < this._activeAnimatables.length; i++) {\r\n                this._activeAnimatables[i].stop(undefined, undefined, true);\r\n            }\r\n            this._activeAnimatables.length = 0;\r\n        }\r\n\r\n        for (const group of this.animationGroups) {\r\n            group.stop();\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Skeleton } from \"./skeleton\";\r\nimport { Vector3, Quaternion, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { BuildArray } from \"../Misc/arrayTools\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { Node } from \"../node\";\r\nimport { Space } from \"../Maths/math.axis\";\r\n\r\nimport { type Animation } from \"../Animations/animation.pure\";\r\nimport { type AnimationPropertiesOverride } from \"../Animations/animationPropertiesOverride\";\r\n\r\n/**\r\n * Class used to store bone information\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n */\r\nexport class Bone extends Node {\r\n    private static _TmpVecs: Vector3[] = /*#__PURE__*/ BuildArray(2, Vector3.Zero);\r\n    private static _TmpQuat = /*#__PURE__*/ Quaternion.Identity();\r\n    private static _TmpMats: Matrix[] = /*#__PURE__*/ BuildArray(5, Matrix.Identity);\r\n\r\n    /**\r\n     * Gets the list of child bones\r\n     */\r\n    public children: Bone[] = [];\r\n\r\n    /** Gets the animations associated with this bone */\r\n    public override animations: Animation[] = [];\r\n\r\n    /**\r\n     * Gets or sets bone length\r\n     */\r\n    public length: number;\r\n\r\n    /**\r\n     * @internal Internal only\r\n     * Set this value to map this bone to a different index in the transform matrices\r\n     * Set this value to -1 to exclude the bone from the transform matrices\r\n     */\r\n    public _index: Nullable<number> = null;\r\n\r\n    private _skeleton: Skeleton;\r\n    private _localMatrix: Matrix; // transformation of the bone, in local space\r\n    private _absoluteMatrix: Matrix; // transformation of the bone, in world space (relative to the skeleton root)\r\n    private _bindMatrix: Matrix; // the bind matrix, in local space\r\n    private _absoluteBindMatrix: Matrix; // the bind matrix, in world space (relative to the skeleton root)\r\n    private _absoluteInverseBindMatrix: Matrix; // the inverse of the bind matrix, in world space (relative to the skeleton root)\r\n    private _finalMatrix: Matrix; // the final matrix used to transform vertices of the mesh according to the bone, in world space (relative to the skeleton root). It is the multiplication of _absoluteInverseBindMatrix with _absoluteMatrix.\r\n    private _restMatrix: Matrix; // a matrix for the exclusive use of the end user (not used internally by the framework), in local space\r\n    private _scalingDeterminant = 1;\r\n\r\n    private _localScaling: Vector3;\r\n    private _localRotation: Quaternion;\r\n    private _localPosition: Vector3;\r\n    private _needToDecompose = true;\r\n    private _needToCompose = false;\r\n\r\n    /** @internal */\r\n    public _linkedTransformNode: Nullable<TransformNode> = null;\r\n\r\n    /** @internal */\r\n    public _waitingTransformNodeId: Nullable<string> = null;\r\n\r\n    /** @internal */\r\n    public _waitingTransformNodeUniqueId: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    get _matrix(): Matrix {\r\n        this._compose();\r\n        return this._localMatrix;\r\n    }\r\n\r\n    /** @internal */\r\n    set _matrix(value: Matrix) {\r\n        // skip if the matrices are the same\r\n        if (value.updateFlag === this._localMatrix.updateFlag && !this._needToCompose) {\r\n            return;\r\n        }\r\n\r\n        this._needToCompose = false; // in case there was a pending compose\r\n\r\n        this._localMatrix.copyFrom(value);\r\n        this._markAsDirtyAndDecompose();\r\n    }\r\n\r\n    /**\r\n     * Create a new bone\r\n     * @param name defines the bone name\r\n     * @param skeleton defines the parent skeleton\r\n     * @param parentBone defines the parent (can be null if the bone is the root)\r\n     * @param localMatrix defines the local matrix (default: identity)\r\n     * @param restMatrix defines the rest matrix (default: localMatrix)\r\n     * @param bindMatrix defines the bind matrix (default: localMatrix)\r\n     * @param index defines index of the bone in the hierarchy (default: null)\r\n     */\r\n    constructor(\r\n        /**\r\n         * defines the bone name\r\n         */\r\n        public override name: string,\r\n        skeleton: Skeleton,\r\n        parentBone: Nullable<Bone> = null,\r\n        localMatrix: Nullable<Matrix> = null,\r\n        restMatrix: Nullable<Matrix> = null,\r\n        bindMatrix: Nullable<Matrix> = null,\r\n        index: Nullable<number> = null\r\n    ) {\r\n        super(name, skeleton.getScene(), false);\r\n        this._skeleton = skeleton;\r\n        this._localMatrix = localMatrix?.clone() ?? Matrix.Identity();\r\n        this._restMatrix = restMatrix ?? this._localMatrix.clone();\r\n        this._bindMatrix = bindMatrix ?? this._localMatrix.clone();\r\n        this._index = index;\r\n\r\n        this._absoluteMatrix = new Matrix();\r\n        this._absoluteBindMatrix = new Matrix();\r\n        this._absoluteInverseBindMatrix = new Matrix();\r\n        this._finalMatrix = new Matrix();\r\n\r\n        skeleton.bones.push(this);\r\n\r\n        this.setParent(parentBone, false);\r\n\r\n        this._updateAbsoluteBindMatrices();\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"Bone\";\r\n    }\r\n\r\n    // Members\r\n\r\n    /**\r\n     * Gets the parent skeleton\r\n     * @returns a skeleton\r\n     */\r\n    public getSkeleton(): Skeleton {\r\n        return this._skeleton;\r\n    }\r\n\r\n    public override get parent(): Bone {\r\n        return this._parentNode as Bone;\r\n    }\r\n\r\n    /**\r\n     * Gets parent bone\r\n     * @returns a bone or null if the bone is the root of the bone hierarchy\r\n     */\r\n    public getParent(): Nullable<Bone> {\r\n        return this.parent;\r\n    }\r\n\r\n    /**\r\n     * Returns an array containing the children of the bone\r\n     * @returns an array containing the children of the bone (can be empty if the bone has no children)\r\n     */\r\n    public override getChildren(): Array<Bone> {\r\n        return this.children;\r\n    }\r\n\r\n    /**\r\n     * Gets the node index in matrix array generated for rendering\r\n     * @returns the node index\r\n     */\r\n    public getIndex(): number {\r\n        return this._index === null ? this.getSkeleton().bones.indexOf(this) : this._index;\r\n    }\r\n\r\n    public override set parent(newParent: Nullable<Bone>) {\r\n        this.setParent(newParent);\r\n    }\r\n\r\n    /**\r\n     * Sets the parent bone\r\n     * @param parent defines the parent (can be null if the bone is the root)\r\n     * @param updateAbsoluteBindMatrices defines if the absolute bind and absolute inverse bind matrices must be updated\r\n     */\r\n    public setParent(parent: Nullable<Bone>, updateAbsoluteBindMatrices: boolean = true): void {\r\n        if (this.parent === parent) {\r\n            return;\r\n        }\r\n\r\n        if (this.parent) {\r\n            const index = this.parent.children.indexOf(this);\r\n            if (index !== -1) {\r\n                this.parent.children.splice(index, 1);\r\n            }\r\n        }\r\n\r\n        this._parentNode = parent;\r\n\r\n        if (this.parent) {\r\n            this.parent.children.push(this);\r\n        }\r\n\r\n        if (updateAbsoluteBindMatrices) {\r\n            this._updateAbsoluteBindMatrices();\r\n        }\r\n\r\n        this.markAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets the local matrix\r\n     * @returns the local matrix\r\n     */\r\n    public getLocalMatrix(): Matrix {\r\n        this._compose();\r\n        return this._localMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the bind matrix\r\n     * @returns the bind matrix\r\n     */\r\n    public getBindMatrix(): Matrix {\r\n        return this._bindMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the bind matrix.\r\n     * @returns the bind matrix\r\n     * @deprecated Please use getBindMatrix instead\r\n     */\r\n    public getBaseMatrix(): Matrix {\r\n        return this.getBindMatrix();\r\n    }\r\n\r\n    /**\r\n     * Gets the rest matrix\r\n     * @returns the rest matrix\r\n     */\r\n    public getRestMatrix(): Matrix {\r\n        return this._restMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the rest matrix\r\n     * @returns the rest matrix\r\n     * @deprecated Please use getRestMatrix instead\r\n     */\r\n    public getRestPose(): Matrix {\r\n        return this.getRestMatrix();\r\n    }\r\n\r\n    /**\r\n     * Sets the rest matrix\r\n     * @param matrix the local-space rest matrix to set for this bone\r\n     */\r\n    public setRestMatrix(matrix: Matrix): void {\r\n        this._restMatrix.copyFrom(matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets the rest matrix\r\n     * @param matrix the local-space rest to set for this bone\r\n     * @deprecated Please use setRestMatrix instead\r\n     */\r\n    public setRestPose(matrix: Matrix): void {\r\n        this.setRestMatrix(matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the bind matrix\r\n     * @returns the bind matrix\r\n     * @deprecated Please use getBindMatrix instead\r\n     */\r\n    public getBindPose(): Matrix {\r\n        return this.getBindMatrix();\r\n    }\r\n\r\n    /**\r\n     * Sets the bind matrix\r\n     * This will trigger a recomputation of the absolute bind and absolute inverse bind matrices for this bone and its children\r\n     * Note that the local matrix will also be set with the matrix passed in parameter!\r\n     * @param matrix the local-space bind matrix to set for this bone\r\n     */\r\n    public setBindMatrix(matrix: Matrix): void {\r\n        this.updateMatrix(matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets the bind matrix\r\n     * @param matrix the local-space bind to set for this bone\r\n     * @deprecated Please use setBindMatrix instead\r\n     */\r\n    public setBindPose(matrix: Matrix): void {\r\n        this.setBindMatrix(matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix used to store the final world transformation of the bone (ie. the matrix sent to shaders)\r\n     * @returns the final world matrix\r\n     */\r\n    public getFinalMatrix(): Matrix {\r\n        return this._finalMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix used to store the final world transformation of the bone (ie. the matrix sent to shaders)\r\n     * @deprecated Please use getFinalMatrix instead\r\n     * @returns the final world matrix\r\n     */\r\n    public override getWorldMatrix(): Matrix {\r\n        return this.getFinalMatrix();\r\n    }\r\n\r\n    /**\r\n     * Sets the local matrix to the rest matrix\r\n     */\r\n    public returnToRest(): void {\r\n        if (this._linkedTransformNode) {\r\n            const localScaling = TmpVectors.Vector3[0];\r\n            const localRotation = TmpVectors.Quaternion[0];\r\n            const localPosition = TmpVectors.Vector3[1];\r\n\r\n            this.getRestMatrix().decompose(localScaling, localRotation, localPosition);\r\n\r\n            this._linkedTransformNode.position.copyFrom(localPosition);\r\n            this._linkedTransformNode.rotationQuaternion = this._linkedTransformNode.rotationQuaternion ?? Quaternion.Identity();\r\n            this._linkedTransformNode.rotationQuaternion.copyFrom(localRotation);\r\n            this._linkedTransformNode.scaling.copyFrom(localScaling);\r\n        } else {\r\n            this._matrix = this._restMatrix;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the inverse of the bind matrix, in world space (relative to the skeleton root)\r\n     * @returns the inverse bind matrix, in world space\r\n     */\r\n    public getAbsoluteInverseBindMatrix(): Matrix {\r\n        return this._absoluteInverseBindMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the inverse of the bind matrix, in world space (relative to the skeleton root)\r\n     * @returns the inverse bind matrix, in world space\r\n     * @deprecated Please use getAbsoluteInverseBindMatrix instead\r\n     */\r\n    public getInvertedAbsoluteTransform(): Matrix {\r\n        return this.getAbsoluteInverseBindMatrix();\r\n    }\r\n\r\n    /**\r\n     * Gets the bone matrix, in world space (relative to the skeleton root)\r\n     * @returns the bone matrix, in world space\r\n     */\r\n    public getAbsoluteMatrix(): Matrix {\r\n        this._skeleton.computeAbsoluteMatrices();\r\n        return this._absoluteMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the bone matrix, in world space (relative to the skeleton root)\r\n     * @returns the bone matrix, in world space\r\n     * @deprecated Please use getAbsoluteMatrix instead\r\n     */\r\n    public getAbsoluteTransform(): Matrix {\r\n        return this.getAbsoluteMatrix();\r\n    }\r\n\r\n    /**\r\n     * Links with the given transform node.\r\n     * The local matrix of this bone is overwritten by the transform of the node every frame.\r\n     * @param transformNode defines the transform node to link to\r\n     */\r\n    public linkTransformNode(transformNode: Nullable<TransformNode>): void {\r\n        if (this._linkedTransformNode) {\r\n            this._skeleton._numBonesWithLinkedTransformNode--;\r\n        }\r\n\r\n        this._linkedTransformNode = transformNode;\r\n\r\n        if (this._linkedTransformNode) {\r\n            this._skeleton._numBonesWithLinkedTransformNode++;\r\n        }\r\n    }\r\n\r\n    // Properties (matches TransformNode properties)\r\n\r\n    /**\r\n     * Gets the node used to drive the bone's transformation\r\n     * @returns a transform node or null\r\n     */\r\n    public getTransformNode() {\r\n        return this._linkedTransformNode;\r\n    }\r\n\r\n    /** Gets or sets current position (in local space) */\r\n    public get position(): Vector3 {\r\n        this._decompose();\r\n        return this._localPosition;\r\n    }\r\n\r\n    public set position(newPosition: Vector3) {\r\n        this._decompose();\r\n        this._localPosition.copyFrom(newPosition);\r\n\r\n        this._markAsDirtyAndCompose();\r\n    }\r\n\r\n    /** Gets or sets current rotation (in local space) */\r\n    public get rotation(): Vector3 {\r\n        return this.getRotation();\r\n    }\r\n\r\n    public set rotation(newRotation: Vector3) {\r\n        this.setRotation(newRotation);\r\n    }\r\n\r\n    /** Gets or sets current rotation quaternion (in local space) */\r\n    public get rotationQuaternion() {\r\n        this._decompose();\r\n        return this._localRotation;\r\n    }\r\n\r\n    public set rotationQuaternion(newRotation: Quaternion) {\r\n        this.setRotationQuaternion(newRotation);\r\n    }\r\n\r\n    /** Gets or sets current scaling (in local space) */\r\n    public get scaling(): Vector3 {\r\n        return this.getScale();\r\n    }\r\n\r\n    public set scaling(newScaling: Vector3) {\r\n        this.setScale(newScaling);\r\n    }\r\n\r\n    /**\r\n     * Gets the animation properties override\r\n     */\r\n    public override get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n        return this._skeleton.animationPropertiesOverride;\r\n    }\r\n\r\n    // Methods\r\n    private _decompose() {\r\n        if (!this._needToDecompose) {\r\n            return;\r\n        }\r\n\r\n        this._needToDecompose = false;\r\n\r\n        if (!this._localScaling) {\r\n            this._localScaling = Vector3.Zero();\r\n            this._localRotation = Quaternion.Zero();\r\n            this._localPosition = Vector3.Zero();\r\n        }\r\n        this._localMatrix.decompose(this._localScaling, this._localRotation, this._localPosition);\r\n    }\r\n\r\n    private _compose() {\r\n        if (!this._needToCompose) {\r\n            return;\r\n        }\r\n\r\n        if (!this._localScaling) {\r\n            this._needToCompose = false;\r\n            return;\r\n        }\r\n\r\n        this._needToCompose = false;\r\n        Matrix.ComposeToRef(this._localScaling, this._localRotation, this._localPosition, this._localMatrix);\r\n    }\r\n\r\n    /**\r\n     * Update the bind (and optionally the local) matrix\r\n     * @param bindMatrix defines the new matrix to set to the bind/local matrix, in local space\r\n     * @param updateAbsoluteBindMatrices defines if the absolute bind and absolute inverse bind matrices must be recomputed (default: true)\r\n     * @param updateLocalMatrix defines if the local matrix should also be updated with the matrix passed in parameter (default: true)\r\n     */\r\n    public updateMatrix(bindMatrix: Matrix, updateAbsoluteBindMatrices = true, updateLocalMatrix = true): void {\r\n        this._bindMatrix.copyFrom(bindMatrix);\r\n\r\n        if (updateAbsoluteBindMatrices) {\r\n            this._updateAbsoluteBindMatrices();\r\n        }\r\n\r\n        if (updateLocalMatrix) {\r\n            this._matrix = bindMatrix;\r\n        } else {\r\n            this.markAsDirty();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _updateAbsoluteBindMatrices(bindMatrix?: Matrix, updateChildren = true): void {\r\n        if (!bindMatrix) {\r\n            bindMatrix = this._bindMatrix;\r\n        }\r\n\r\n        if (this.parent) {\r\n            bindMatrix.multiplyToRef(this.parent._absoluteBindMatrix, this._absoluteBindMatrix);\r\n        } else {\r\n            this._absoluteBindMatrix.copyFrom(bindMatrix);\r\n        }\r\n\r\n        this._absoluteBindMatrix.invertToRef(this._absoluteInverseBindMatrix);\r\n\r\n        if (updateChildren) {\r\n            for (let index = 0; index < this.children.length; index++) {\r\n                this.children[index]._updateAbsoluteBindMatrices();\r\n            }\r\n        }\r\n\r\n        this._scalingDeterminant = this._absoluteBindMatrix.determinant() < 0 ? -1 : 1;\r\n    }\r\n\r\n    /**\r\n     * Flag the bone as dirty (Forcing it to update everything)\r\n     * @returns this bone\r\n     */\r\n    public override markAsDirty(): Bone {\r\n        this._currentRenderId++;\r\n        this._childUpdateId++;\r\n        this._skeleton._markAsDirty();\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public _markAsDirtyAndCompose() {\r\n        this.markAsDirty();\r\n        this._needToCompose = true;\r\n    }\r\n\r\n    private _markAsDirtyAndDecompose() {\r\n        this.markAsDirty();\r\n        this._needToDecompose = true;\r\n    }\r\n\r\n    private _updatePosition(vec: Vector3, space = Space.LOCAL, tNode?: TransformNode, translationMode = true): void {\r\n        const lm = this.getLocalMatrix();\r\n\r\n        if (space == Space.LOCAL) {\r\n            if (translationMode) {\r\n                lm.addAtIndex(12, vec.x);\r\n                lm.addAtIndex(13, vec.y);\r\n                lm.addAtIndex(14, vec.z);\r\n            } else {\r\n                lm.setTranslationFromFloats(vec.x, vec.y, vec.z);\r\n            }\r\n        } else {\r\n            const tmat = Bone._TmpMats[0];\r\n            const tvec = Bone._TmpVecs[0];\r\n\r\n            if (this.parent) {\r\n                tmat.copyFrom(this.parent.getAbsoluteMatrix());\r\n                if (tNode) {\r\n                    tmat.multiplyToRef(tNode.getWorldMatrix(), tmat);\r\n                }\r\n            } else {\r\n                Matrix.IdentityToRef(tmat);\r\n            }\r\n\r\n            if (translationMode) {\r\n                tmat.setTranslationFromFloats(0, 0, 0);\r\n            }\r\n            tmat.invert();\r\n            Vector3.TransformCoordinatesToRef(vec, tmat, tvec);\r\n\r\n            if (translationMode) {\r\n                lm.addAtIndex(12, tvec.x);\r\n                lm.addAtIndex(13, tvec.y);\r\n                lm.addAtIndex(14, tvec.z);\r\n            } else {\r\n                lm.setTranslationFromFloats(tvec.x, tvec.y, tvec.z);\r\n            }\r\n        }\r\n\r\n        this._markAsDirtyAndDecompose();\r\n    }\r\n\r\n    /**\r\n     * Translate the bone in local or world space\r\n     * @param vec The amount to translate the bone\r\n     * @param space The space that the translation is in (default: Space.LOCAL)\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public translate(vec: Vector3, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        this._updatePosition(vec, space, tNode, true);\r\n    }\r\n\r\n    /**\r\n     * Set the position of the bone in local or world space\r\n     * @param position The position to set the bone\r\n     * @param space The space that the position is in (default: Space.LOCAL)\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setPosition(position: Vector3, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        this._updatePosition(position, space, tNode, false);\r\n    }\r\n\r\n    /**\r\n     * Set the absolute position of the bone (world space)\r\n     * @param position The position to set the bone\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setAbsolutePosition(position: Vector3, tNode?: TransformNode) {\r\n        this.setPosition(position, Space.WORLD, tNode);\r\n    }\r\n\r\n    /**\r\n     * Scale the bone on the x, y and z axes (in local space)\r\n     * @param x The amount to scale the bone on the x axis\r\n     * @param y The amount to scale the bone on the y axis\r\n     * @param z The amount to scale the bone on the z axis\r\n     * @param scaleChildren sets this to true if children of the bone should be scaled as well (false by default)\r\n     */\r\n    public scale(x: number, y: number, z: number, scaleChildren = false): void {\r\n        const locMat = this.getLocalMatrix();\r\n\r\n        // Apply new scaling on top of current local matrix\r\n        const scaleMat = Bone._TmpMats[0];\r\n        Matrix.ScalingToRef(x, y, z, scaleMat);\r\n        scaleMat.multiplyToRef(locMat, locMat);\r\n\r\n        // Invert scaling matrix and apply the inverse to all children\r\n        scaleMat.invert();\r\n\r\n        for (const child of this.children) {\r\n            const cm = child.getLocalMatrix();\r\n            cm.multiplyToRef(scaleMat, cm);\r\n            cm.multiplyAtIndex(12, x);\r\n            cm.multiplyAtIndex(13, y);\r\n            cm.multiplyAtIndex(14, z);\r\n\r\n            child._markAsDirtyAndDecompose();\r\n        }\r\n\r\n        this._markAsDirtyAndDecompose();\r\n\r\n        if (scaleChildren) {\r\n            for (const child of this.children) {\r\n                child.scale(x, y, z, scaleChildren);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the bone scaling in local space\r\n     * @param scale defines the scaling vector\r\n     */\r\n    public setScale(scale: Vector3): void {\r\n        this._decompose();\r\n        this._localScaling.copyFrom(scale);\r\n        this._markAsDirtyAndCompose();\r\n    }\r\n\r\n    /**\r\n     * Gets the current scaling in local space\r\n     * @returns the current scaling vector\r\n     */\r\n    public getScale(): Vector3 {\r\n        this._decompose();\r\n        return this._localScaling;\r\n    }\r\n\r\n    /**\r\n     * Gets the current scaling in local space and stores it in a target vector\r\n     * @param result defines the target vector\r\n     */\r\n    public getScaleToRef(result: Vector3) {\r\n        this._decompose();\r\n        result.copyFrom(this._localScaling);\r\n    }\r\n\r\n    /**\r\n     * Set the yaw, pitch, and roll of the bone in local or world space\r\n     * @param yaw The rotation of the bone on the y axis\r\n     * @param pitch The rotation of the bone on the x axis\r\n     * @param roll The rotation of the bone on the z axis\r\n     * @param space The space that the axes of rotation are in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setYawPitchRoll(yaw: number, pitch: number, roll: number, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        if (space === Space.LOCAL) {\r\n            const quat = Bone._TmpQuat;\r\n            Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, quat);\r\n            this.setRotationQuaternion(quat, space, tNode);\r\n            return;\r\n        }\r\n\r\n        const rotMatInv = Bone._TmpMats[0];\r\n        if (!this._getAbsoluteInverseMatrixUnscaledToRef(rotMatInv, tNode)) {\r\n            return;\r\n        }\r\n\r\n        const rotMat = Bone._TmpMats[1];\r\n        Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);\r\n\r\n        rotMatInv.multiplyToRef(rotMat, rotMat);\r\n        this._rotateWithMatrix(rotMat, space, tNode);\r\n    }\r\n\r\n    /**\r\n     * Add a rotation to the bone on an axis in local or world space\r\n     * @param axis The axis to rotate the bone on\r\n     * @param amount The amount to rotate the bone\r\n     * @param space The space that the axis is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public rotate(axis: Vector3, amount: number, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        const rmat = Bone._TmpMats[0];\r\n        rmat.setTranslationFromFloats(0, 0, 0);\r\n        Matrix.RotationAxisToRef(axis, amount, rmat);\r\n        this._rotateWithMatrix(rmat, space, tNode);\r\n    }\r\n\r\n    /**\r\n     * Set the rotation of the bone to a particular axis angle in local or world space\r\n     * @param axis The axis to rotate the bone on\r\n     * @param angle The angle that the bone should be rotated to\r\n     * @param space The space that the axis is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setAxisAngle(axis: Vector3, angle: number, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        if (space === Space.LOCAL) {\r\n            const quat = Bone._TmpQuat;\r\n            Quaternion.RotationAxisToRef(axis, angle, quat);\r\n\r\n            this.setRotationQuaternion(quat, space, tNode);\r\n            return;\r\n        }\r\n\r\n        const rotMatInv = Bone._TmpMats[0];\r\n        if (!this._getAbsoluteInverseMatrixUnscaledToRef(rotMatInv, tNode)) {\r\n            return;\r\n        }\r\n\r\n        const rotMat = Bone._TmpMats[1];\r\n        Matrix.RotationAxisToRef(axis, angle, rotMat);\r\n\r\n        rotMatInv.multiplyToRef(rotMat, rotMat);\r\n        this._rotateWithMatrix(rotMat, space, tNode);\r\n    }\r\n\r\n    /**\r\n     * Set the euler rotation of the bone in local or world space\r\n     * @param rotation The euler rotation that the bone should be set to\r\n     * @param space The space that the rotation is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setRotation(rotation: Vector3, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        this.setYawPitchRoll(rotation.y, rotation.x, rotation.z, space, tNode);\r\n    }\r\n\r\n    /**\r\n     * Set the quaternion rotation of the bone in local or world space\r\n     * @param quat The quaternion rotation that the bone should be set to\r\n     * @param space The space that the rotation is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setRotationQuaternion(quat: Quaternion, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        if (space === Space.LOCAL) {\r\n            this._decompose();\r\n            this._localRotation.copyFrom(quat);\r\n\r\n            this._markAsDirtyAndCompose();\r\n\r\n            return;\r\n        }\r\n\r\n        const rotMatInv = Bone._TmpMats[0];\r\n        if (!this._getAbsoluteInverseMatrixUnscaledToRef(rotMatInv, tNode)) {\r\n            return;\r\n        }\r\n\r\n        const rotMat = Bone._TmpMats[1];\r\n        Matrix.FromQuaternionToRef(quat, rotMat);\r\n\r\n        rotMatInv.multiplyToRef(rotMat, rotMat);\r\n\r\n        this._rotateWithMatrix(rotMat, space, tNode);\r\n    }\r\n\r\n    /**\r\n     * Set the rotation matrix of the bone in local or world space\r\n     * @param rotMat The rotation matrix that the bone should be set to\r\n     * @param space The space that the rotation is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     */\r\n    public setRotationMatrix(rotMat: Matrix, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        if (space === Space.LOCAL) {\r\n            const quat = Bone._TmpQuat;\r\n            Quaternion.FromRotationMatrixToRef(rotMat, quat);\r\n            this.setRotationQuaternion(quat, space, tNode);\r\n            return;\r\n        }\r\n\r\n        const rotMatInv = Bone._TmpMats[0];\r\n        if (!this._getAbsoluteInverseMatrixUnscaledToRef(rotMatInv, tNode)) {\r\n            return;\r\n        }\r\n\r\n        const rotMat2 = Bone._TmpMats[1];\r\n        rotMat2.copyFrom(rotMat);\r\n\r\n        rotMatInv.multiplyToRef(rotMat, rotMat2);\r\n\r\n        this._rotateWithMatrix(rotMat2, space, tNode);\r\n    }\r\n\r\n    private _rotateWithMatrix(rmat: Matrix, space = Space.LOCAL, tNode?: TransformNode): void {\r\n        const lmat = this.getLocalMatrix();\r\n        const lx = lmat.m[12];\r\n        const ly = lmat.m[13];\r\n        const lz = lmat.m[14];\r\n        const parent = this.getParent();\r\n        const parentScale = Bone._TmpMats[3];\r\n        const parentScaleInv = Bone._TmpMats[4];\r\n\r\n        if (parent && space == Space.WORLD) {\r\n            if (tNode) {\r\n                parentScale.copyFrom(tNode.getWorldMatrix());\r\n                parent.getAbsoluteMatrix().multiplyToRef(parentScale, parentScale);\r\n            } else {\r\n                parentScale.copyFrom(parent.getAbsoluteMatrix());\r\n            }\r\n            parentScaleInv.copyFrom(parentScale);\r\n            parentScaleInv.invert();\r\n            lmat.multiplyToRef(parentScale, lmat);\r\n            lmat.multiplyToRef(rmat, lmat);\r\n            lmat.multiplyToRef(parentScaleInv, lmat);\r\n        } else {\r\n            if (space == Space.WORLD && tNode) {\r\n                parentScale.copyFrom(tNode.getWorldMatrix());\r\n                parentScaleInv.copyFrom(parentScale);\r\n                parentScaleInv.invert();\r\n                lmat.multiplyToRef(parentScale, lmat);\r\n                lmat.multiplyToRef(rmat, lmat);\r\n                lmat.multiplyToRef(parentScaleInv, lmat);\r\n            } else {\r\n                lmat.multiplyToRef(rmat, lmat);\r\n            }\r\n        }\r\n\r\n        lmat.setTranslationFromFloats(lx, ly, lz);\r\n\r\n        this._markAsDirtyAndDecompose();\r\n    }\r\n\r\n    private _getAbsoluteInverseMatrixUnscaledToRef(rotMatInv: Matrix, tNode?: TransformNode): boolean {\r\n        const scaleMatrix = Bone._TmpMats[2];\r\n        rotMatInv.copyFrom(this.getAbsoluteMatrix());\r\n\r\n        if (tNode) {\r\n            rotMatInv.multiplyToRef(tNode.getWorldMatrix(), rotMatInv);\r\n            Matrix.ScalingToRef(tNode.scaling.x, tNode.scaling.y, tNode.scaling.z, scaleMatrix);\r\n        } else {\r\n            Matrix.IdentityToRef(scaleMatrix);\r\n        }\r\n\r\n        rotMatInv.invert();\r\n        if (isNaN(rotMatInv.m[0])) {\r\n            // Matrix failed to invert.\r\n            // This can happen if scale is zero for example.\r\n            return false;\r\n        }\r\n\r\n        scaleMatrix.multiplyAtIndex(0, this._scalingDeterminant);\r\n        rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Get the position of the bone in local or world space\r\n     * @param space The space that the returned position is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The position of the bone\r\n     */\r\n    public getPosition(space = Space.LOCAL, tNode: Nullable<TransformNode> = null): Vector3 {\r\n        const pos = Vector3.Zero();\r\n\r\n        this.getPositionToRef(space, tNode, pos);\r\n\r\n        return pos;\r\n    }\r\n\r\n    /**\r\n     * Copy the position of the bone to a vector3 in local or world space\r\n     * @param space The space that the returned position is in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The vector3 to copy the position to\r\n     */\r\n    public getPositionToRef(space = Space.LOCAL, tNode: Nullable<TransformNode>, result: Vector3): void {\r\n        if (space == Space.LOCAL) {\r\n            const lm = this.getLocalMatrix();\r\n\r\n            result.x = lm.m[12];\r\n            result.y = lm.m[13];\r\n            result.z = lm.m[14];\r\n        } else {\r\n            const tmat = Bone._TmpMats[0].copyFrom(this.getAbsoluteMatrix());\r\n\r\n            if (tNode) {\r\n                tmat.multiplyToRef(tNode.getWorldMatrix(), tmat);\r\n            }\r\n\r\n            result.x = tmat.m[12];\r\n            result.y = tmat.m[13];\r\n            result.z = tmat.m[14];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the absolute position of the bone (world space)\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The absolute position of the bone\r\n     */\r\n    public getAbsolutePosition(tNode: Nullable<TransformNode> = null): Vector3 {\r\n        const pos = Vector3.Zero();\r\n\r\n        this.getPositionToRef(Space.WORLD, tNode, pos);\r\n\r\n        return pos;\r\n    }\r\n\r\n    /**\r\n     * Copy the absolute position of the bone (world space) to the result param\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The vector3 to copy the absolute position to\r\n     */\r\n    public getAbsolutePositionToRef(tNode: TransformNode, result: Vector3) {\r\n        this.getPositionToRef(Space.WORLD, tNode, result);\r\n    }\r\n\r\n    /**\r\n     * Compute the absolute matrices of this bone and its children\r\n     */\r\n    public computeAbsoluteMatrices(): void {\r\n        this._compose();\r\n\r\n        if (this.parent) {\r\n            this._localMatrix.multiplyToRef(this.parent._absoluteMatrix, this._absoluteMatrix);\r\n        } else {\r\n            this._absoluteMatrix.copyFrom(this._localMatrix);\r\n\r\n            const poseMatrix = this._skeleton.getPoseMatrix();\r\n\r\n            if (poseMatrix) {\r\n                this._absoluteMatrix.multiplyToRef(poseMatrix, this._absoluteMatrix);\r\n            }\r\n        }\r\n\r\n        const children = this.children;\r\n        const len = children.length;\r\n\r\n        for (let i = 0; i < len; i++) {\r\n            children[i].computeAbsoluteMatrices();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Compute the absolute matrices of this bone and its children\r\n     * @deprecated Please use computeAbsoluteMatrices instead\r\n     */\r\n    public computeAbsoluteTransforms(): void {\r\n        this.computeAbsoluteMatrices();\r\n    }\r\n\r\n    /**\r\n     * Get the world direction from an axis that is in the local space of the bone\r\n     * @param localAxis The local direction that is used to compute the world direction\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The world direction\r\n     */\r\n    public getDirection(localAxis: Vector3, tNode: Nullable<TransformNode> = null): Vector3 {\r\n        const result = Vector3.Zero();\r\n\r\n        this.getDirectionToRef(localAxis, tNode, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Copy the world direction to a vector3 from an axis that is in the local space of the bone\r\n     * @param localAxis The local direction that is used to compute the world direction\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The vector3 that the world direction will be copied to\r\n     */\r\n    public getDirectionToRef(localAxis: Vector3, tNode: Nullable<TransformNode> = null, result: Vector3): void {\r\n        const tMat = Bone._TmpMats[0].copyFrom(this.getAbsoluteMatrix());\r\n\r\n        if (tNode) {\r\n            tMat.multiplyToRef(tNode.getWorldMatrix(), tMat);\r\n        }\r\n\r\n        Vector3.TransformNormalToRef(localAxis, tMat, result);\r\n\r\n        result.normalize();\r\n    }\r\n\r\n    /**\r\n     * Get the euler rotation of the bone in local or world space\r\n     * @param space The space that the rotation should be in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The euler rotation\r\n     */\r\n    public getRotation(space = Space.LOCAL, tNode: Nullable<TransformNode> = null): Vector3 {\r\n        const result = Vector3.Zero();\r\n\r\n        this.getRotationToRef(space, tNode, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Copy the euler rotation of the bone to a vector3.  The rotation can be in either local or world space\r\n     * @param space The space that the rotation should be in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The vector3 that the rotation should be copied to\r\n     */\r\n    public getRotationToRef(space = Space.LOCAL, tNode: Nullable<TransformNode> = null, result: Vector3): void {\r\n        const quat = Bone._TmpQuat;\r\n\r\n        this.getRotationQuaternionToRef(space, tNode, quat);\r\n\r\n        quat.toEulerAnglesToRef(result);\r\n    }\r\n\r\n    /**\r\n     * Get the quaternion rotation of the bone in either local or world space\r\n     * @param space The space that the rotation should be in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The quaternion rotation\r\n     */\r\n    public getRotationQuaternion(space = Space.LOCAL, tNode: Nullable<TransformNode> = null): Quaternion {\r\n        const result = Quaternion.Identity();\r\n\r\n        this.getRotationQuaternionToRef(space, tNode, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Copy the quaternion rotation of the bone to a quaternion.  The rotation can be in either local or world space\r\n     * @param space The space that the rotation should be in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The quaternion that the rotation should be copied to\r\n     */\r\n    public getRotationQuaternionToRef(space = Space.LOCAL, tNode: Nullable<TransformNode> = null, result: Quaternion): void {\r\n        if (space == Space.LOCAL) {\r\n            this._decompose();\r\n            result.copyFrom(this._localRotation);\r\n        } else {\r\n            const mat = Bone._TmpMats[0];\r\n            const amat = this.getAbsoluteMatrix();\r\n\r\n            if (tNode) {\r\n                amat.multiplyToRef(tNode.getWorldMatrix(), mat);\r\n            } else {\r\n                mat.copyFrom(amat);\r\n            }\r\n\r\n            mat.multiplyAtIndex(0, this._scalingDeterminant);\r\n            mat.multiplyAtIndex(1, this._scalingDeterminant);\r\n            mat.multiplyAtIndex(2, this._scalingDeterminant);\r\n\r\n            mat.decompose(undefined, result, undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the rotation matrix of the bone in local or world space\r\n     * @param space The space that the rotation should be in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The rotation matrix\r\n     */\r\n    public getRotationMatrix(space = Space.LOCAL, tNode: TransformNode): Matrix {\r\n        const result = Matrix.Identity();\r\n\r\n        this.getRotationMatrixToRef(space, tNode, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Copy the rotation matrix of the bone to a matrix.  The rotation can be in either local or world space\r\n     * @param space The space that the rotation should be in\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The quaternion that the rotation should be copied to\r\n     */\r\n    public getRotationMatrixToRef(space = Space.LOCAL, tNode: TransformNode, result: Matrix): void {\r\n        if (space == Space.LOCAL) {\r\n            this.getLocalMatrix().getRotationMatrixToRef(result);\r\n        } else {\r\n            const mat = Bone._TmpMats[0];\r\n            const amat = this.getAbsoluteMatrix();\r\n\r\n            if (tNode) {\r\n                amat.multiplyToRef(tNode.getWorldMatrix(), mat);\r\n            } else {\r\n                mat.copyFrom(amat);\r\n            }\r\n\r\n            mat.multiplyAtIndex(0, this._scalingDeterminant);\r\n            mat.multiplyAtIndex(1, this._scalingDeterminant);\r\n            mat.multiplyAtIndex(2, this._scalingDeterminant);\r\n\r\n            mat.getRotationMatrixToRef(result);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the world position of a point that is in the local space of the bone\r\n     * @param position The local position\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The world position\r\n     */\r\n    public getAbsolutePositionFromLocal(position: Vector3, tNode: Nullable<TransformNode> = null): Vector3 {\r\n        const result = Vector3.Zero();\r\n\r\n        this.getAbsolutePositionFromLocalToRef(position, tNode, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Get the world position of a point that is in the local space of the bone and copy it to the result param\r\n     * @param position The local position\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The vector3 that the world position should be copied to\r\n     */\r\n    public getAbsolutePositionFromLocalToRef(position: Vector3, tNode: Nullable<TransformNode> = null, result: Vector3): void {\r\n        const tmat = Bone._TmpMats[0].copyFrom(this.getAbsoluteMatrix());\r\n\r\n        if (tNode) {\r\n            tmat.multiplyToRef(tNode.getWorldMatrix(), tmat);\r\n        }\r\n\r\n        Vector3.TransformCoordinatesToRef(position, tmat, result);\r\n    }\r\n\r\n    /**\r\n     * Get the local position of a point that is in world space\r\n     * @param position The world position\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @returns The local position\r\n     */\r\n    public getLocalPositionFromAbsolute(position: Vector3, tNode: Nullable<TransformNode> = null): Vector3 {\r\n        const result = Vector3.Zero();\r\n\r\n        this.getLocalPositionFromAbsoluteToRef(position, tNode, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Get the local position of a point that is in world space and copy it to the result param\r\n     * @param position The world position\r\n     * @param tNode A TransformNode whose world matrix is to be applied to the calculated absolute matrix. In most cases, you'll want to pass the mesh associated with the skeleton from which this bone comes. Used only when space=Space.WORLD\r\n     * @param result The vector3 that the local position should be copied to\r\n     */\r\n    public getLocalPositionFromAbsoluteToRef(position: Vector3, tNode: Nullable<TransformNode> = null, result: Vector3): void {\r\n        const tmat = Bone._TmpMats[0].copyFrom(this.getAbsoluteMatrix());\r\n\r\n        if (tNode) {\r\n            tmat.multiplyToRef(tNode.getWorldMatrix(), tmat);\r\n        }\r\n\r\n        tmat.invert();\r\n\r\n        Vector3.TransformCoordinatesToRef(position, tmat, result);\r\n    }\r\n\r\n    /**\r\n     * Set the current local matrix as the restMatrix for this bone.\r\n     */\r\n    public setCurrentPoseAsRest(): void {\r\n        this.setRestMatrix(this.getLocalMatrix());\r\n    }\r\n\r\n    /**\r\n     * Releases associated resources\r\n     */\r\n    public override dispose(): void {\r\n        this._linkedTransformNode = null;\r\n\r\n        const index = this._skeleton.bones.indexOf(this);\r\n        if (index !== -1) {\r\n            this._skeleton.bones.splice(index, 1);\r\n        }\r\n\r\n        if (this._parentNode && (this._parentNode as Bone).children) {\r\n            const children = (this._parentNode as Bone).children;\r\n            const index = children.indexOf(this);\r\n            if (index !== -1) {\r\n                children.splice(index, 1);\r\n            }\r\n        }\r\n\r\n        super.dispose();\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffect } from \"../Misc/devTools\";\r\n\r\nBone.prototype.copyAnimationRange ??= _MissingSideEffect(\"Bone\", \"copyAnimationRange\") as any;\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","import { type WebRequest } from \"./webRequest\";\r\n\r\n/**\r\n * Class used to define a retry strategy when error happens while loading assets\r\n */\r\nexport class RetryStrategy {\r\n    /**\r\n     * Function used to defines an exponential back off strategy\r\n     * @param maxRetries defines the maximum number of retries (3 by default)\r\n     * @param baseInterval defines the interval between retries\r\n     * @returns the strategy function to use\r\n     */\r\n    public static ExponentialBackoff(maxRetries = 3, baseInterval = 500) {\r\n        return (url: string, request: WebRequest, retryIndex: number): number => {\r\n            if (request.status !== 0 || retryIndex >= maxRetries || url.indexOf(\"file:\") !== -1) {\r\n                return -1;\r\n            }\r\n\r\n            return Math.pow(2, retryIndex) * baseInterval;\r\n        };\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/**\r\n * Base error. Due to limitations of typedoc-check and missing documentation\r\n * in lib.es5.d.ts, cannot extend Error directly for RuntimeError.\r\n * @ignore\r\n */\r\nexport abstract class BaseError extends Error {\r\n    // See https://stackoverflow.com/questions/12915412/how-do-i-extend-a-host-object-e-g-error-in-typescript\r\n    // and https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work\r\n\r\n    // Polyfill for Object.setPrototypeOf if necessary.\r\n    protected static _setPrototypeOf: (o: any, proto: object | null) => any =\r\n        (Object as any).setPrototypeOf ||\r\n        ((o, proto) => {\r\n            o.__proto__ = proto;\r\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-return\r\n            return o;\r\n        });\r\n}\r\n\r\n/* IMP! DO NOT CHANGE THE NUMBERING OF EXISTING ERROR CODES */\r\n/**\r\n * Error codes for BaseError\r\n */\r\nexport const ErrorCodes = {\r\n    // Mesh errors 0-999\r\n    /** Invalid or empty mesh vertex positions. */\r\n    MeshInvalidPositionsError: 0,\r\n\r\n    // Texture errors 1000-1999\r\n    /** Unsupported texture found. */\r\n    UnsupportedTextureError: 1000,\r\n\r\n    // GLTFLoader errors 2000-2999\r\n    /** Unexpected magic number found in GLTF file header. */\r\n    GLTFLoaderUnexpectedMagicError: 2000,\r\n\r\n    // SceneLoader errors 3000-3999\r\n    /** SceneLoader generic error code. Ideally wraps the inner exception. */\r\n    SceneLoaderError: 3000,\r\n\r\n    // File related errors 4000-4999\r\n    /** Load file error */\r\n    LoadFileError: 4000,\r\n    /** Request file error */\r\n    RequestFileError: 4001,\r\n    /** Read file error */\r\n    ReadFileError: 4002,\r\n} as const;\r\n\r\n/**\r\n * Error code type\r\n */\r\nexport type ErrorCodesType = (typeof ErrorCodes)[keyof typeof ErrorCodes];\r\n\r\n/**\r\n * Application runtime error\r\n */\r\nexport class RuntimeError extends BaseError {\r\n    /**\r\n     * The error code\r\n     */\r\n    public errorCode: ErrorCodesType;\r\n\r\n    /**\r\n     * The error that caused this outer error\r\n     */\r\n    public innerError?: Error;\r\n\r\n    /**\r\n     * Creates a new RuntimeError\r\n     * @param message defines the message of the error\r\n     * @param errorCode the error code\r\n     * @param innerError the error that caused the outer error\r\n     */\r\n    public constructor(message: string, errorCode: ErrorCodesType, innerError?: Error) {\r\n        super(message);\r\n\r\n        this.errorCode = errorCode;\r\n        this.innerError = innerError;\r\n\r\n        this.name = \"RuntimeError\";\r\n        BaseError._setPrototypeOf(this, RuntimeError.prototype);\r\n    }\r\n}\r\n\r\n/**\r\n * Used for flow control when an operation is aborted, such as with AbortController.\r\n */\r\nexport class AbortError extends BaseError {\r\n    public constructor(message = \"Operation aborted\") {\r\n        super(message);\r\n        this.name = \"AbortError\";\r\n        BaseError._setPrototypeOf(this, AbortError.prototype);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * Checks for a matching suffix at the end of a string (for ES5 and lower)\r\n * @param str Source string\r\n * @param suffix Suffix to search for in the source string\r\n * @returns Boolean indicating whether the suffix was found (true) or not (false)\r\n * @deprecated Please use native string function instead\r\n */\r\nexport const EndsWith = (str: string, suffix: string): boolean => {\r\n    return str.endsWith(suffix);\r\n};\r\n\r\n/**\r\n * Checks for a matching suffix at the beginning of a string (for ES5 and lower)\r\n * @param str Source string\r\n * @param suffix Suffix to search for in the source string\r\n * @returns Boolean indicating whether the suffix was found (true) or not (false)\r\n * @deprecated Please use native string function instead\r\n */\r\nexport const StartsWith = (str: string, suffix: string): boolean => {\r\n    if (!str) {\r\n        return false;\r\n    }\r\n    return str.startsWith(suffix);\r\n};\r\n\r\n/**\r\n * Decodes a buffer into a string\r\n * @param buffer The buffer to decode\r\n * @returns The decoded string\r\n */\r\nexport const Decode = (buffer: Uint8Array | Uint16Array): string => {\r\n    if (typeof TextDecoder !== \"undefined\") {\r\n        return new TextDecoder().decode(buffer);\r\n    }\r\n\r\n    let result = \"\";\r\n    for (let i = 0; i < buffer.byteLength; i++) {\r\n        result += String.fromCharCode(buffer[i]);\r\n    }\r\n\r\n    return result;\r\n};\r\n\r\nfunction JsEncodeArrayBufferToBase64(bytes: Uint8Array): string {\r\n    const keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\r\n    let output = \"\";\r\n    let chr1, chr2, chr3, enc1, enc2, enc3, enc4;\r\n    let i = 0;\r\n\r\n    while (i < bytes.length) {\r\n        chr1 = bytes[i++];\r\n        chr2 = i < bytes.length ? bytes[i++] : Number.NaN;\r\n        chr3 = i < bytes.length ? bytes[i++] : Number.NaN;\r\n\r\n        enc1 = chr1 >> 2;\r\n        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\r\n        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\r\n        enc4 = chr3 & 63;\r\n\r\n        if (isNaN(chr2)) {\r\n            enc3 = enc4 = 64;\r\n        } else if (isNaN(chr3)) {\r\n            enc4 = 64;\r\n        }\r\n        output += keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);\r\n    }\r\n\r\n    return output;\r\n}\r\n\r\nfunction JsDecodeBase64ToBinary(base64Data: string): ArrayBuffer {\r\n    const decodedString = DecodeBase64ToString(base64Data);\r\n    const bufferLength = decodedString.length;\r\n    const bufferView = new Uint8Array(new ArrayBuffer(bufferLength));\r\n\r\n    for (let i = 0; i < bufferLength; i++) {\r\n        bufferView[i] = decodedString.charCodeAt(i);\r\n    }\r\n\r\n    return bufferView.buffer;\r\n}\r\n\r\n/**\r\n * Encode a buffer to a base64 string\r\n * @param buffer defines the buffer to encode\r\n * @returns the encoded string\r\n */\r\nexport const EncodeArrayBufferToBase64 = (buffer: ArrayBuffer | ArrayBufferView): string => {\r\n    const bytes = ArrayBuffer.isView(buffer) ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) : new Uint8Array(buffer);\r\n\r\n    return typeof bytes.toBase64 === \"function\" ? bytes.toBase64() : JsEncodeArrayBufferToBase64(bytes);\r\n};\r\n\r\n/**\r\n * Converts a given base64 string as an ASCII encoded stream of data\r\n * @param base64Data The base64 encoded string to decode\r\n * @returns Decoded ASCII string\r\n */\r\nexport const DecodeBase64ToString = (base64Data: string): string => {\r\n    return atob(base64Data);\r\n};\r\n\r\n/**\r\n * Converts a given base64 string into an ArrayBuffer of raw byte data\r\n * @param base64Data The base64 encoded string to decode\r\n * @returns ArrayBuffer of byte data\r\n */\r\nexport const DecodeBase64ToBinary = (base64Data: string): ArrayBuffer => {\r\n    return typeof Uint8Array.fromBase64 === \"function\" ? Uint8Array.fromBase64(base64Data).buffer : JsDecodeBase64ToBinary(base64Data);\r\n};\r\n\r\n/**\r\n * Converts a number to string and pads with preceding zeroes until it is of specified length.\r\n * @param num the number to convert and pad\r\n * @param length the expected length of the string\r\n * @returns the padded string\r\n */\r\nexport const PadNumber = (num: number, length: number): string => {\r\n    let str = String(num);\r\n    while (str.length < length) {\r\n        str = \"0\" + str;\r\n    }\r\n    return str;\r\n};\r\n/**\r\n * Helper to manipulate strings\r\n */\r\nexport const StringTools = {\r\n    EndsWith,\r\n    StartsWith,\r\n    Decode,\r\n    EncodeArrayBufferToBase64,\r\n    DecodeBase64ToString,\r\n    DecodeBase64ToBinary,\r\n    PadNumber,\r\n};\r\n","import { IsDocumentAvailable } from \"core/Misc/domManagement\";\r\nimport { type IFileRequest } from \"core/Misc/fileRequest\";\r\nimport { type LoadFileError } from \"core/Misc/fileTools\";\r\nimport { type IWebRequest } from \"core/Misc/interfaces/iWebRequest\";\r\nimport { type WebRequest } from \"core/Misc/webRequest\";\r\nimport { type IOfflineProvider } from \"core/Offline/IOfflineProvider\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { _WarnImport } from \"core/Misc/devTools\";\r\nimport { Constants } from \"./constants\";\r\nimport { type AbstractEngine } from \"./abstractEngine\";\r\n\r\n/**\r\n * Injection seam for file/image loading. The implementations live in\r\n * `fileTools.pure` and are registered here as a side effect by `fileTools.ts`\r\n * (via `RegisterFileTools`). Keeping them behind this mutable context object —\r\n * instead of importing them directly into the always-loaded engine classes —\r\n * lets bundlers tree-shake all file-loading code out of builds that never\r\n * import the `fileTools` side effect (e.g. a minimal thin-engine build).\r\n * @internal\r\n */\r\nexport const EngineFunctionContext: {\r\n    loadFile?: (\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent) => void,\r\n        offlineProvider?: Nullable<IOfflineProvider>,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void\r\n    ) => IFileRequest;\r\n    loadImage?: (\r\n        input: string | ArrayBuffer | ArrayBufferView | Blob,\r\n        onLoad: (img: HTMLImageElement | ImageBitmap) => void,\r\n        onError: (message?: string, exception?: any) => void,\r\n        offlineProvider: Nullable<IOfflineProvider>,\r\n        mimeType?: string,\r\n        imageBitmapOptions?: ImageBitmapOptions,\r\n        engine?: Nullable<AbstractEngine>\r\n    ) => Nullable<HTMLImageElement>;\r\n} = {};\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _ConcatenateShader(source: string, defines: Nullable<string>, shaderVersion: string = \"\"): string {\r\n    return shaderVersion + (defines ? defines + \"\\n\" : \"\") + source;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _LoadFile(\r\n    url: string,\r\n    onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n    onProgress?: (data: any) => void,\r\n    offlineProvider?: Nullable<IOfflineProvider>,\r\n    useArrayBuffer?: boolean,\r\n    onError?: (request?: IWebRequest, exception?: any) => void,\r\n    injectedLoadFile?: (\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent<EventTarget>) => void,\r\n        offlineProvider?: Nullable<IOfflineProvider>,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void\r\n    ) => IFileRequest\r\n): IFileRequest {\r\n    const loadFileFn = injectedLoadFile || EngineFunctionContext.loadFile;\r\n    if (!loadFileFn) {\r\n        // The fileTools side effect was never imported, so no loader is registered.\r\n        throw _WarnImport(\"FileTools\");\r\n    }\r\n    const request = loadFileFn(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);\r\n    return request;\r\n}\r\n\r\n/**\r\n * Gets host document\r\n * @param renderingCanvas if provided, the canvas' owner document will be returned\r\n * @returns the host document object\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getHostDocument(renderingCanvas: Nullable<HTMLCanvasElement> = null): Nullable<Document> {\r\n    if (renderingCanvas && renderingCanvas.ownerDocument) {\r\n        return renderingCanvas.ownerDocument;\r\n    }\r\n\r\n    return IsDocumentAvailable() ? document : null;\r\n}\r\n\r\n/** @internal */\r\nexport function _GetGlobalDefines(\r\n    defines?: { [key: string]: string },\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    isNDCHalfZRange?: boolean,\r\n    useReverseDepthBuffer?: boolean,\r\n    useExactSrgbConversions?: boolean\r\n): string | undefined {\r\n    if (defines) {\r\n        if (isNDCHalfZRange) {\r\n            defines[\"IS_NDC_HALF_ZRANGE\"] = \"\";\r\n        } else {\r\n            delete defines[\"IS_NDC_HALF_ZRANGE\"];\r\n        }\r\n        if (useReverseDepthBuffer) {\r\n            defines[\"USE_REVERSE_DEPTHBUFFER\"] = \"\";\r\n        } else {\r\n            delete defines[\"USE_REVERSE_DEPTHBUFFER\"];\r\n        }\r\n        if (useExactSrgbConversions) {\r\n            defines[\"USE_EXACT_SRGB_CONVERSIONS\"] = \"\";\r\n        } else {\r\n            delete defines[\"USE_EXACT_SRGB_CONVERSIONS\"];\r\n        }\r\n        return;\r\n    } else {\r\n        let s = \"\";\r\n        if (isNDCHalfZRange) {\r\n            s += \"#define IS_NDC_HALF_ZRANGE\";\r\n        }\r\n        if (useReverseDepthBuffer) {\r\n            if (s) {\r\n                s += \"\\n\";\r\n            }\r\n            s += \"#define USE_REVERSE_DEPTHBUFFER\";\r\n        }\r\n        if (useExactSrgbConversions) {\r\n            if (s) {\r\n                s += \"\\n\";\r\n            }\r\n            s += \"#define USE_EXACT_SRGB_CONVERSIONS\";\r\n        }\r\n        return s;\r\n    }\r\n}\r\n\r\n/**\r\n * Allocate a typed array depending on a texture type. Optionally can copy existing data in the buffer.\r\n * @param type type of the texture\r\n * @param sizeOrDstBuffer size of the array OR an existing buffer that will be used as the destination of the copy (if copyBuffer is provided)\r\n * @param sizeInBytes true if the size of the array is given in bytes, false if it is the number of elements of the array\r\n * @param copyBuffer if provided, buffer to copy into the destination buffer (either a newly allocated buffer if sizeOrDstBuffer is a number or use sizeOrDstBuffer as the destination buffer otherwise)\r\n * @returns the allocated buffer or sizeOrDstBuffer if the latter is an ArrayBuffer\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function allocateAndCopyTypedBuffer(type: number, sizeOrDstBuffer: number | ArrayBufferLike, sizeInBytes = false, copyBuffer?: ArrayBuffer): ArrayBufferView {\r\n    switch (type) {\r\n        case Constants.TEXTURETYPE_BYTE: {\r\n            const buffer = new Int8Array(sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Int8Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n        case Constants.TEXTURETYPE_UNSIGNED_BYTE: {\r\n            const buffer = new Uint8Array(sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Uint8Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n        case Constants.TEXTURETYPE_SHORT: {\r\n            const buffer = typeof sizeOrDstBuffer !== \"number\" ? new Int16Array(sizeOrDstBuffer) : new Int16Array(sizeInBytes ? sizeOrDstBuffer / 2 : sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Int16Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n        case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n        case Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:\r\n        case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:\r\n        case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:\r\n        case Constants.TEXTURETYPE_HALF_FLOAT: {\r\n            const buffer = typeof sizeOrDstBuffer !== \"number\" ? new Uint16Array(sizeOrDstBuffer) : new Uint16Array(sizeInBytes ? sizeOrDstBuffer / 2 : sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Uint16Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n        case Constants.TEXTURETYPE_INT: {\r\n            const buffer = typeof sizeOrDstBuffer !== \"number\" ? new Int32Array(sizeOrDstBuffer) : new Int32Array(sizeInBytes ? sizeOrDstBuffer / 4 : sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Int32Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n        case Constants.TEXTURETYPE_UNSIGNED_INTEGER:\r\n        case Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:\r\n        case Constants.TEXTURETYPE_UNSIGNED_INT_24_8:\r\n        case Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:\r\n        case Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:\r\n        case Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV: {\r\n            const buffer = typeof sizeOrDstBuffer !== \"number\" ? new Uint32Array(sizeOrDstBuffer) : new Uint32Array(sizeInBytes ? sizeOrDstBuffer / 4 : sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Uint32Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n        case Constants.TEXTURETYPE_FLOAT: {\r\n            const buffer = typeof sizeOrDstBuffer !== \"number\" ? new Float32Array(sizeOrDstBuffer) : new Float32Array(sizeInBytes ? sizeOrDstBuffer / 4 : sizeOrDstBuffer);\r\n            if (copyBuffer) {\r\n                buffer.set(new Float32Array(copyBuffer));\r\n            }\r\n            return buffer;\r\n        }\r\n    }\r\n\r\n    const buffer = new Uint8Array(sizeOrDstBuffer);\r\n    if (copyBuffer) {\r\n        buffer.set(new Uint8Array(copyBuffer));\r\n    }\r\n    return buffer;\r\n}\r\n","import { type _IProcessingOptions } from \"./shaderProcessingOptions\";\r\n\r\nconst DefaultAttributeKeywordName = \"attribute\";\r\nconst DefaultVaryingKeywordName = \"varying\";\r\n\r\n/** @internal */\r\nexport class ShaderCodeNode {\r\n    line: string;\r\n    children: ShaderCodeNode[] = [];\r\n    additionalDefineKey?: string;\r\n    additionalDefineValue?: string;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    isValid(preprocessors: { [key: string]: string }): boolean {\r\n        return true;\r\n    }\r\n\r\n    process(preprocessors: { [key: string]: string }, options: _IProcessingOptions, preProcessorsFromCode: { [key: string]: string }): string {\r\n        let result = \"\";\r\n        if (this.line) {\r\n            let value: string = this.line;\r\n            const processor = options.processor;\r\n            if (processor) {\r\n                // This must be done before other replacements to avoid mistakenly changing something that was already changed.\r\n                if (processor.lineProcessor) {\r\n                    value = processor.lineProcessor(value, options.isFragment, options.processingContext);\r\n                }\r\n\r\n                const attributeKeyword = options.processor?.attributeKeywordName ?? DefaultAttributeKeywordName;\r\n                const varyingKeyword =\r\n                    options.isFragment && options.processor?.varyingFragmentKeywordName\r\n                        ? options.processor?.varyingFragmentKeywordName\r\n                        : !options.isFragment && options.processor?.varyingVertexKeywordName\r\n                          ? options.processor?.varyingVertexKeywordName\r\n                          : DefaultVaryingKeywordName;\r\n\r\n                if (!options.isFragment && processor.attributeProcessor && this.line.startsWith(attributeKeyword)) {\r\n                    value = processor.attributeProcessor(this.line, preprocessors, options.processingContext);\r\n                } else if (\r\n                    processor.varyingProcessor &&\r\n                    (processor.varyingCheck?.(this.line, options.isFragment) || (!processor.varyingCheck && this.line.startsWith(varyingKeyword)))\r\n                ) {\r\n                    value = processor.varyingProcessor(this.line, options.isFragment, preprocessors, options.processingContext);\r\n                } else if (processor.uniformProcessor && processor.uniformRegexp && processor.uniformRegexp.test(this.line)) {\r\n                    if (!options.lookForClosingBracketForUniformBuffer) {\r\n                        value = processor.uniformProcessor(this.line, options.isFragment, preprocessors, options.processingContext);\r\n                    }\r\n                } else if (processor.uniformBufferProcessor && processor.uniformBufferRegexp && processor.uniformBufferRegexp.test(this.line)) {\r\n                    if (!options.lookForClosingBracketForUniformBuffer) {\r\n                        value = processor.uniformBufferProcessor(this.line, options.isFragment, options.processingContext);\r\n                        options.lookForClosingBracketForUniformBuffer = true;\r\n                    }\r\n                } else if (processor.textureProcessor && processor.textureRegexp && processor.textureRegexp.test(this.line)) {\r\n                    value = processor.textureProcessor(this.line, options.isFragment, preprocessors, options.processingContext);\r\n                } else if ((processor.uniformProcessor || processor.uniformBufferProcessor) && this.line.startsWith(\"uniform\") && !options.lookForClosingBracketForUniformBuffer) {\r\n                    const regex = /uniform\\s+(?:(?:highp)?|(?:lowp)?)\\s*(\\S+)\\s+(\\S+)\\s*;/;\r\n\r\n                    if (regex.test(this.line)) {\r\n                        // uniform\r\n                        if (processor.uniformProcessor) {\r\n                            value = processor.uniformProcessor(this.line, options.isFragment, preprocessors, options.processingContext);\r\n                        }\r\n                    } else {\r\n                        // Uniform buffer\r\n                        if (processor.uniformBufferProcessor) {\r\n                            value = processor.uniformBufferProcessor(this.line, options.isFragment, options.processingContext);\r\n                            options.lookForClosingBracketForUniformBuffer = true;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (options.lookForClosingBracketForUniformBuffer && this.line.indexOf(\"}\") !== -1) {\r\n                    options.lookForClosingBracketForUniformBuffer = false;\r\n                    if (processor.endOfUniformBufferProcessor) {\r\n                        value = processor.endOfUniformBufferProcessor(this.line, options.isFragment, options.processingContext);\r\n                    }\r\n                }\r\n            }\r\n\r\n            result += value + \"\\n\";\r\n        }\r\n\r\n        for (const child of this.children) {\r\n            result += child.process(preprocessors, options, preProcessorsFromCode);\r\n        }\r\n\r\n        if (this.additionalDefineKey) {\r\n            preprocessors[this.additionalDefineKey] = this.additionalDefineValue || \"true\";\r\n            preProcessorsFromCode[this.additionalDefineKey] = preprocessors[this.additionalDefineKey];\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n","/** @internal */\r\nexport class ShaderCodeCursor {\r\n    private _lines: string[] = [];\r\n    lineIndex: number;\r\n\r\n    get currentLine(): string {\r\n        return this._lines[this.lineIndex];\r\n    }\r\n\r\n    get canRead(): boolean {\r\n        return this.lineIndex < this._lines.length - 1;\r\n    }\r\n\r\n    set lines(value: string[]) {\r\n        this._lines.length = 0;\r\n\r\n        for (const line of value) {\r\n            // Skip empty lines\r\n            if (!line || line === \"\\r\") {\r\n                continue;\r\n            }\r\n\r\n            // Prevent removing line break in macros.\r\n            if (line[0] === \"#\") {\r\n                this._lines.push(line);\r\n                continue;\r\n            }\r\n\r\n            // Do not split single line comments\r\n            const trimmedLine = line.trim();\r\n\r\n            if (!trimmedLine) {\r\n                continue;\r\n            }\r\n\r\n            if (trimmedLine.startsWith(\"//\")) {\r\n                this._lines.push(line);\r\n                continue;\r\n            }\r\n\r\n            // Work with semicolon in the line\r\n            const semicolonIndex = trimmedLine.indexOf(\";\");\r\n\r\n            if (semicolonIndex === -1) {\r\n                // No semicolon in the line\r\n                this._lines.push(trimmedLine);\r\n            } else if (semicolonIndex === trimmedLine.length - 1) {\r\n                // Single semicolon at the end of the line\r\n                // If trimmedLine == \";\", we must not push, to be backward compatible with the old code!\r\n                if (trimmedLine.length > 1) {\r\n                    this._lines.push(trimmedLine);\r\n                }\r\n            } else {\r\n                // Semicolon in the middle of the line\r\n                const split = line.split(\";\");\r\n\r\n                for (let index = 0; index < split.length; index++) {\r\n                    let subLine = split[index];\r\n\r\n                    if (!subLine) {\r\n                        continue;\r\n                    }\r\n\r\n                    subLine = subLine.trim();\r\n\r\n                    if (!subLine) {\r\n                        continue;\r\n                    }\r\n\r\n                    this._lines.push(subLine + (index !== split.length - 1 ? \";\" : \"\"));\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { ShaderCodeNode } from \"./shaderCodeNode\";\r\nimport { type _IProcessingOptions } from \"./shaderProcessingOptions\";\r\n\r\n/** @internal */\r\nexport class ShaderCodeConditionNode extends ShaderCodeNode {\r\n    override process(preprocessors: { [key: string]: string }, options: _IProcessingOptions, preProcessorsFromCode: { [key: string]: string }) {\r\n        for (let index = 0; index < this.children.length; index++) {\r\n            const node = this.children[index];\r\n\r\n            if (node.isValid(preprocessors)) {\r\n                return node.process(preprocessors, options, preProcessorsFromCode);\r\n            }\r\n        }\r\n\r\n        return \"\";\r\n    }\r\n}\r\n","import { ShaderCodeNode } from \"./shaderCodeNode\";\r\nimport { type ShaderDefineExpression } from \"./Expressions/shaderDefineExpression\";\r\n\r\n/** @internal */\r\nexport class ShaderCodeTestNode extends ShaderCodeNode {\r\n    public testExpression: ShaderDefineExpression;\r\n\r\n    public override isValid(preprocessors: { [key: string]: string }) {\r\n        return this.testExpression.isTrue(preprocessors);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/** @internal */\r\nexport class ShaderDefineExpression {\r\n    /**\r\n     * Cache items count limit for the InfixToPostfix cache.\r\n     * It uses to improve the performance of the shader compilation.\r\n     * For details see PR: https://github.com/BabylonJS/Babylon.js/pull/13936\r\n     */\r\n    static InfixToPostfixCacheLimitSize = 50000;\r\n\r\n    /**\r\n     * When the cache size is exceeded, a cache cleanup will be triggered\r\n     * and the cache will be reduced by the size specified\r\n     * in the InfixToPostfixCacheCleanupSize variable, removing entries\r\n     * that have not been accessed the longest.\r\n     */\r\n    static InfixToPostfixCacheCleanupSize = 25000;\r\n\r\n    protected static _InfixToPostfixCache: Map<\r\n        string,\r\n        {\r\n            accessTime: number;\r\n            result: string[];\r\n        }\r\n    > = new Map();\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public isTrue(preprocessors: { [key: string]: string }): boolean {\r\n        return true;\r\n    }\r\n\r\n    private static _OperatorPriority: { [name: string]: number } = {\r\n        \")\": 0,\r\n        \"(\": 1,\r\n        \"||\": 2,\r\n        \"&&\": 3,\r\n    };\r\n\r\n    private static _Stack = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\"];\r\n\r\n    public static postfixToInfix(postfix: string[]): string {\r\n        const stack: string[] = [];\r\n\r\n        for (const c of postfix) {\r\n            if (ShaderDefineExpression._OperatorPriority[c] === undefined) {\r\n                stack.push(c);\r\n            } else {\r\n                const v1 = stack[stack.length - 1],\r\n                    v2 = stack[stack.length - 2];\r\n\r\n                stack.length -= 2;\r\n                stack.push(`(${v2}${c}${v1})`);\r\n            }\r\n        }\r\n\r\n        return stack[stack.length - 1];\r\n    }\r\n\r\n    /**\r\n     * Converts an infix expression to a postfix expression.\r\n     *\r\n     * This method is used to transform infix expressions, which are more human-readable,\r\n     * into postfix expressions, also known as Reverse Polish Notation (RPN), that can be\r\n     * evaluated more efficiently by a computer. The conversion is based on the operator\r\n     * priority defined in _OperatorPriority.\r\n     *\r\n     * The function employs a stack-based algorithm for the conversion and caches the result\r\n     * to improve performance. The cache keeps track of each converted expression's access time\r\n     * to manage the cache size and optimize memory usage. When the cache size exceeds a specified\r\n     * limit, the least recently accessed items in the cache are deleted.\r\n     *\r\n     * The cache mechanism is particularly helpful for shader compilation, where the same infix\r\n     * expressions might be encountered repeatedly, hence the caching can speed up the process.\r\n     *\r\n     * @param infix - The infix expression to be converted.\r\n     * @returns The postfix expression as an array of strings.\r\n     */\r\n    public static infixToPostfix(infix: string): string[] {\r\n        // Is infix already in cache\r\n        const cacheItem = ShaderDefineExpression._InfixToPostfixCache.get(infix);\r\n        if (cacheItem) {\r\n            cacheItem.accessTime = Date.now();\r\n            return cacheItem.result;\r\n        }\r\n\r\n        // Is infix contain any operator\r\n        if (!infix.includes(\"&&\") && !infix.includes(\"||\") && !infix.includes(\")\") && !infix.includes(\"(\")) {\r\n            return [infix];\r\n        }\r\n\r\n        const result: string[] = [];\r\n\r\n        let stackIdx = -1;\r\n\r\n        const pushOperand = () => {\r\n            operand = operand.trim();\r\n            if (operand !== \"\") {\r\n                result.push(operand);\r\n                operand = \"\";\r\n            }\r\n        };\r\n\r\n        const push = (s: string) => {\r\n            if (stackIdx < ShaderDefineExpression._Stack.length - 1) {\r\n                ShaderDefineExpression._Stack[++stackIdx] = s;\r\n            }\r\n        };\r\n\r\n        const peek = () => ShaderDefineExpression._Stack[stackIdx];\r\n\r\n        const pop = () => (stackIdx === -1 ? \"!!INVALID EXPRESSION!!\" : ShaderDefineExpression._Stack[stackIdx--]);\r\n\r\n        let idx = 0,\r\n            operand = \"\";\r\n\r\n        while (idx < infix.length) {\r\n            const c = infix.charAt(idx),\r\n                token = idx < infix.length - 1 ? infix.substring(idx, 2 + idx) : \"\";\r\n\r\n            if (c === \"(\") {\r\n                operand = \"\";\r\n                push(c);\r\n            } else if (c === \")\") {\r\n                pushOperand();\r\n                while (stackIdx !== -1 && peek() !== \"(\") {\r\n                    result.push(pop());\r\n                }\r\n                pop();\r\n            } else if (ShaderDefineExpression._OperatorPriority[token] > 1) {\r\n                pushOperand();\r\n                while (stackIdx !== -1 && ShaderDefineExpression._OperatorPriority[peek()] >= ShaderDefineExpression._OperatorPriority[token]) {\r\n                    result.push(pop());\r\n                }\r\n                push(token);\r\n                idx++;\r\n            } else {\r\n                operand += c;\r\n            }\r\n            idx++;\r\n        }\r\n\r\n        pushOperand();\r\n\r\n        while (stackIdx !== -1) {\r\n            if (peek() === \"(\") {\r\n                pop();\r\n            } else {\r\n                result.push(pop());\r\n            }\r\n        }\r\n\r\n        // If the cache is at capacity, clear it before adding a new item\r\n        if (ShaderDefineExpression._InfixToPostfixCache.size >= ShaderDefineExpression.InfixToPostfixCacheLimitSize) {\r\n            ShaderDefineExpression.ClearCache();\r\n        }\r\n\r\n        // Add the new item to the cache, including the current time as the last access time\r\n        ShaderDefineExpression._InfixToPostfixCache.set(infix, { result, accessTime: Date.now() });\r\n\r\n        return result;\r\n    }\r\n\r\n    private static ClearCache(): void {\r\n        // Convert the cache to an array and sort by last access time\r\n        const sortedCache = Array.from(ShaderDefineExpression._InfixToPostfixCache.entries()).sort((a, b) => a[1].accessTime - b[1].accessTime);\r\n\r\n        // Remove the least recently accessed half of the cache\r\n        for (let i = 0; i < ShaderDefineExpression.InfixToPostfixCacheCleanupSize; i++) {\r\n            ShaderDefineExpression._InfixToPostfixCache.delete(sortedCache[i][0]);\r\n        }\r\n    }\r\n}\r\n","import { ShaderDefineExpression } from \"../shaderDefineExpression\";\r\n\r\n/** @internal */\r\nexport class ShaderDefineIsDefinedOperator extends ShaderDefineExpression {\r\n    public constructor(\r\n        public define: string,\r\n        public not: boolean = false\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    public override isTrue(preprocessors: { [key: string]: string }) {\r\n        let condition = preprocessors[this.define] !== undefined;\r\n\r\n        if (this.not) {\r\n            condition = !condition;\r\n        }\r\n\r\n        return condition;\r\n    }\r\n}\r\n","import { ShaderDefineExpression } from \"../shaderDefineExpression\";\r\n\r\n/** @internal */\r\nexport class ShaderDefineOrOperator extends ShaderDefineExpression {\r\n    public leftOperand: ShaderDefineExpression;\r\n    public rightOperand: ShaderDefineExpression;\r\n\r\n    public override isTrue(preprocessors: { [key: string]: string }): boolean {\r\n        return this.leftOperand.isTrue(preprocessors) || this.rightOperand.isTrue(preprocessors);\r\n    }\r\n}\r\n","import { ShaderDefineExpression } from \"../shaderDefineExpression\";\r\n\r\n/** @internal */\r\nexport class ShaderDefineAndOperator extends ShaderDefineExpression {\r\n    public leftOperand: ShaderDefineExpression;\r\n    public rightOperand: ShaderDefineExpression;\r\n\r\n    public override isTrue(preprocessors: { [key: string]: string }): boolean {\r\n        return this.leftOperand.isTrue(preprocessors) && this.rightOperand.isTrue(preprocessors);\r\n    }\r\n}\r\n","import { ShaderDefineExpression } from \"../shaderDefineExpression\";\r\n\r\n/** @internal */\r\nexport class ShaderDefineArithmeticOperator extends ShaderDefineExpression {\r\n    public constructor(\r\n        public define: string,\r\n        public operand: string,\r\n        public testValue: string\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    public override toString() {\r\n        return `${this.define} ${this.operand} ${this.testValue}`;\r\n    }\r\n\r\n    public override isTrue(preprocessors: { [key: string]: string }) {\r\n        let condition = false;\r\n\r\n        const left = parseInt(preprocessors[this.define] != undefined ? preprocessors[this.define] : this.define);\r\n        const right = parseInt(preprocessors[this.testValue] != undefined ? preprocessors[this.testValue] : this.testValue);\r\n\r\n        if (isNaN(left) || isNaN(right)) {\r\n            // We can't evaluate the expression because we can't resolve the left and/or right side\r\n            // We should not throw an error here because the code might be using a define that is not defined in the material/shader!\r\n            return false;\r\n        }\r\n\r\n        switch (this.operand) {\r\n            case \">\":\r\n                condition = left > right;\r\n                break;\r\n            case \"<\":\r\n                condition = left < right;\r\n                break;\r\n            case \"<=\":\r\n                condition = left <= right;\r\n                break;\r\n            case \">=\":\r\n                condition = left >= right;\r\n                break;\r\n            case \"==\":\r\n                condition = left === right;\r\n                break;\r\n            case \"!=\":\r\n                condition = left !== right;\r\n                break;\r\n        }\r\n\r\n        return condition;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { ShaderCodeNode } from \"./shaderCodeNode\";\r\nimport { ShaderCodeCursor } from \"./shaderCodeCursor\";\r\nimport { ShaderCodeConditionNode } from \"./shaderCodeConditionNode\";\r\nimport { ShaderCodeTestNode } from \"./shaderCodeTestNode\";\r\nimport { ShaderDefineIsDefinedOperator } from \"./Expressions/Operators/shaderDefineIsDefinedOperator\";\r\nimport { ShaderDefineOrOperator } from \"./Expressions/Operators/shaderDefineOrOperator\";\r\nimport { ShaderDefineAndOperator } from \"./Expressions/Operators/shaderDefineAndOperator\";\r\nimport { ShaderDefineExpression } from \"./Expressions/shaderDefineExpression\";\r\nimport { ShaderDefineArithmeticOperator } from \"./Expressions/Operators/shaderDefineArithmeticOperator\";\r\nimport { type _IProcessingOptions } from \"./shaderProcessingOptions\";\r\nimport { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\n\r\nimport { type WebRequest } from \"../../Misc/webRequest\";\r\nimport { type LoadFileError } from \"../../Misc/fileTools\";\r\nimport { type IOfflineProvider } from \"../../Offline/IOfflineProvider\";\r\nimport { type IFileRequest } from \"../../Misc/fileRequest\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\nimport { _GetGlobalDefines } from \"../abstractEngine.functions\";\r\nimport { type AbstractEngine } from \"../abstractEngine\";\r\n\r\nconst RegexSe = /defined\\s*?\\((.+?)\\)/g;\r\nconst RegexSeRevert = /defined\\s*?\\[(.+?)\\]/g;\r\nconst RegexShaderInclude = /#include\\s?<(.+)>(\\((.*)\\))*(\\[(.*)\\])*/g;\r\nconst RegexShaderDecl = /__decl__/;\r\nconst RegexLightX = /light\\{X\\}.(\\w*)/g;\r\nconst RegexX = /\\{X\\}/g;\r\nconst ReusableMatches: RegExpMatchArray[] = [];\r\n\r\nconst MoveCursorRegex = /(#ifdef)|(#else)|(#elif)|(#endif)|(#ifndef)|(#if)/;\r\n\r\n/** @internal */\r\nexport function Initialize(options: _IProcessingOptions): void {\r\n    if (options.processor && options.processor.initializeShaders) {\r\n        options.processor.initializeShaders(options.processingContext);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function Process(sourceCode: string, options: _IProcessingOptions, callback: (migratedCode: string, codeBeforeMigration: string) => void, engine?: AbstractEngine) {\r\n    if (options.processor?.preProcessShaderCode) {\r\n        sourceCode = options.processor.preProcessShaderCode(sourceCode, options.isFragment);\r\n    }\r\n    ProcessIncludes(sourceCode, options, (codeWithIncludes) => {\r\n        if (options.processCodeAfterIncludes) {\r\n            codeWithIncludes = options.processCodeAfterIncludes(options.isFragment ? \"fragment\" : \"vertex\", codeWithIncludes, options.defines);\r\n        }\r\n        const migratedCode = ProcessShaderConversion(codeWithIncludes, options, engine);\r\n        callback(migratedCode, codeWithIncludes);\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function PreProcess(sourceCode: string, options: _IProcessingOptions, callback: (migratedCode: string, codeBeforeMigration: string) => void, engine: AbstractEngine) {\r\n    if (options.processor?.preProcessShaderCode) {\r\n        sourceCode = options.processor.preProcessShaderCode(sourceCode, options.isFragment);\r\n    }\r\n    ProcessIncludes(sourceCode, options, (codeWithIncludes) => {\r\n        if (options.processCodeAfterIncludes) {\r\n            codeWithIncludes = options.processCodeAfterIncludes(options.isFragment ? \"fragment\" : \"vertex\", codeWithIncludes, options.defines);\r\n        }\r\n        const migratedCode = ApplyPreProcessing(codeWithIncludes, options, engine);\r\n        callback(migratedCode, codeWithIncludes);\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function Finalize(vertexCode: string, fragmentCode: string, options: _IProcessingOptions): { vertexCode: string; fragmentCode: string } {\r\n    if (!options.processor || !options.processor.finalizeShaders) {\r\n        return { vertexCode, fragmentCode };\r\n    }\r\n\r\n    return options.processor.finalizeShaders(vertexCode, fragmentCode, options.processingContext);\r\n}\r\n\r\nfunction ProcessPrecision(source: string, options: _IProcessingOptions): string {\r\n    if (options.processor?.noPrecision) {\r\n        return source;\r\n    }\r\n\r\n    const shouldUseHighPrecisionShader = options.shouldUseHighPrecisionShader;\r\n\r\n    if (source.indexOf(\"precision highp float\") === -1) {\r\n        if (!shouldUseHighPrecisionShader) {\r\n            source = \"precision mediump float;\\n\" + source;\r\n        } else {\r\n            source = \"precision highp float;\\n\" + source;\r\n        }\r\n    } else {\r\n        if (!shouldUseHighPrecisionShader) {\r\n            // Moving highp to mediump\r\n            source = source.replace(\"precision highp float\", \"precision mediump float\");\r\n        }\r\n    }\r\n\r\n    return source;\r\n}\r\n\r\nfunction ExtractOperation(expression: string) {\r\n    const regex = /defined\\((.+)\\)/;\r\n\r\n    const match = regex.exec(expression);\r\n\r\n    if (match && match.length) {\r\n        return new ShaderDefineIsDefinedOperator(match[1].trim(), expression[0] === \"!\");\r\n    }\r\n\r\n    const operators = [\"==\", \"!=\", \">=\", \"<=\", \"<\", \">\"];\r\n    let operator = \"\";\r\n    let indexOperator = 0;\r\n\r\n    for (operator of operators) {\r\n        indexOperator = expression.indexOf(operator);\r\n\r\n        if (indexOperator > -1) {\r\n            break;\r\n        }\r\n    }\r\n\r\n    if (indexOperator === -1) {\r\n        return new ShaderDefineIsDefinedOperator(expression);\r\n    }\r\n\r\n    const define = expression.substring(0, indexOperator).trim();\r\n    const value = expression.substring(indexOperator + operator.length).trim();\r\n\r\n    return new ShaderDefineArithmeticOperator(define, operator, value);\r\n}\r\n\r\nfunction BuildSubExpression(expression: string): ShaderDefineExpression {\r\n    expression = expression.replace(RegexSe, \"defined[$1]\");\r\n\r\n    const postfix = ShaderDefineExpression.infixToPostfix(expression);\r\n\r\n    const stack: (string | ShaderDefineExpression)[] = [];\r\n\r\n    for (const c of postfix) {\r\n        if (c !== \"||\" && c !== \"&&\") {\r\n            stack.push(c);\r\n        } else if (stack.length >= 2) {\r\n            let v1 = stack[stack.length - 1],\r\n                v2 = stack[stack.length - 2];\r\n\r\n            stack.length -= 2;\r\n\r\n            const operator = c == \"&&\" ? new ShaderDefineAndOperator() : new ShaderDefineOrOperator();\r\n\r\n            if (typeof v1 === \"string\") {\r\n                v1 = v1.replace(RegexSeRevert, \"defined($1)\");\r\n            }\r\n\r\n            if (typeof v2 === \"string\") {\r\n                v2 = v2.replace(RegexSeRevert, \"defined($1)\");\r\n            }\r\n\r\n            operator.leftOperand = typeof v2 === \"string\" ? ExtractOperation(v2) : v2;\r\n            operator.rightOperand = typeof v1 === \"string\" ? ExtractOperation(v1) : v1;\r\n\r\n            stack.push(operator);\r\n        }\r\n    }\r\n\r\n    let result = stack[stack.length - 1];\r\n\r\n    if (typeof result === \"string\") {\r\n        result = result.replace(RegexSeRevert, \"defined($1)\");\r\n    }\r\n\r\n    // note: stack.length !== 1 if there was an error in the parsing\r\n\r\n    return typeof result === \"string\" ? ExtractOperation(result) : result;\r\n}\r\n\r\nfunction BuildExpression(line: string, start: number): ShaderCodeTestNode {\r\n    const node = new ShaderCodeTestNode();\r\n    const command = line.substring(0, start);\r\n    let expression = line.substring(start);\r\n\r\n    expression = expression.substring(0, (expression.indexOf(\"//\") + 1 || expression.length + 1) - 1).trim();\r\n\r\n    if (command === \"#ifdef\") {\r\n        node.testExpression = new ShaderDefineIsDefinedOperator(expression);\r\n    } else if (command === \"#ifndef\") {\r\n        node.testExpression = new ShaderDefineIsDefinedOperator(expression, true);\r\n    } else {\r\n        node.testExpression = BuildSubExpression(expression);\r\n    }\r\n\r\n    return node;\r\n}\r\n\r\nfunction MoveCursorWithinIf(cursor: ShaderCodeCursor, rootNode: ShaderCodeConditionNode, ifNode: ShaderCodeNode, preProcessorsFromCode: { [key: string]: string }) {\r\n    let line: string;\r\n    while (MoveCursor(cursor, ifNode, preProcessorsFromCode)) {\r\n        line = cursor.currentLine;\r\n        const first5 = line.substring(0, 5).toLowerCase();\r\n\r\n        if (first5 === \"#else\") {\r\n            const elseNode = new ShaderCodeNode();\r\n            rootNode.children.push(elseNode);\r\n            MoveCursor(cursor, elseNode, preProcessorsFromCode);\r\n            return;\r\n        } else if (first5 === \"#elif\") {\r\n            const elifNode = BuildExpression(line, 5);\r\n\r\n            rootNode.children.push(elifNode);\r\n            ifNode = elifNode;\r\n        }\r\n    }\r\n}\r\n\r\nfunction MoveCursor(cursor: ShaderCodeCursor, rootNode: ShaderCodeNode, preProcessorsFromCode: { [key: string]: string }): boolean {\r\n    while (cursor.canRead) {\r\n        cursor.lineIndex++;\r\n        const line = cursor.currentLine;\r\n\r\n        if (line.indexOf(\"#\") >= 0) {\r\n            const matches = MoveCursorRegex.exec(line);\r\n\r\n            if (matches && matches.length) {\r\n                const keyword = matches[0];\r\n\r\n                switch (keyword) {\r\n                    case \"#ifdef\": {\r\n                        const newRootNode = new ShaderCodeConditionNode();\r\n                        rootNode.children.push(newRootNode);\r\n\r\n                        const ifNode = BuildExpression(line, 6);\r\n                        newRootNode.children.push(ifNode);\r\n                        MoveCursorWithinIf(cursor, newRootNode, ifNode, preProcessorsFromCode);\r\n                        break;\r\n                    }\r\n                    case \"#else\":\r\n                    case \"#elif\":\r\n                        return true;\r\n                    case \"#endif\":\r\n                        return false;\r\n                    case \"#ifndef\": {\r\n                        const newRootNode = new ShaderCodeConditionNode();\r\n                        rootNode.children.push(newRootNode);\r\n\r\n                        const ifNode = BuildExpression(line, 7);\r\n                        newRootNode.children.push(ifNode);\r\n                        MoveCursorWithinIf(cursor, newRootNode, ifNode, preProcessorsFromCode);\r\n                        break;\r\n                    }\r\n                    case \"#if\": {\r\n                        const newRootNode = new ShaderCodeConditionNode();\r\n                        const ifNode = BuildExpression(line, 3);\r\n                        rootNode.children.push(newRootNode);\r\n\r\n                        newRootNode.children.push(ifNode);\r\n                        MoveCursorWithinIf(cursor, newRootNode, ifNode, preProcessorsFromCode);\r\n                        break;\r\n                    }\r\n                }\r\n                continue;\r\n            }\r\n        }\r\n\r\n        const newNode = new ShaderCodeNode();\r\n        newNode.line = line;\r\n        rootNode.children.push(newNode);\r\n\r\n        // Detect additional defines\r\n        if (line[0] === \"#\" && line[1] === \"d\") {\r\n            const split = line.replace(\";\", \"\").split(\" \");\r\n            newNode.additionalDefineKey = split[1];\r\n\r\n            if (split.length === 3) {\r\n                newNode.additionalDefineValue = split[2];\r\n            }\r\n        }\r\n    }\r\n    return false;\r\n}\r\n\r\nfunction EvaluatePreProcessors(\r\n    sourceCode: string,\r\n    preprocessors: { [key: string]: string },\r\n    options: _IProcessingOptions,\r\n    preProcessorsFromCode: { [key: string]: string }\r\n): string {\r\n    const rootNode = new ShaderCodeNode();\r\n    const cursor = new ShaderCodeCursor();\r\n\r\n    cursor.lineIndex = -1;\r\n    cursor.lines = sourceCode.split(\"\\n\");\r\n\r\n    // Decompose (We keep it in 2 steps so it is easier to maintain and perf hit is insignificant)\r\n    MoveCursor(cursor, rootNode, preProcessorsFromCode);\r\n\r\n    // Recompose\r\n    return rootNode.process(preprocessors, options, preProcessorsFromCode);\r\n}\r\n\r\nfunction PreparePreProcessors(options: _IProcessingOptions, engine?: AbstractEngine): { [key: string]: string } {\r\n    const defines = options.defines;\r\n    const preprocessors: { [key: string]: string } = {};\r\n\r\n    for (const define of defines) {\r\n        const keyValue = define.replace(\"#define\", \"\").replace(\";\", \"\").trim();\r\n        const split = keyValue.split(\" \");\r\n        preprocessors[split[0]] = split.length > 1 ? split[1] : \"\";\r\n    }\r\n\r\n    if (options.processor?.shaderLanguage === ShaderLanguage.GLSL) {\r\n        preprocessors[\"GL_ES\"] = \"true\";\r\n    }\r\n    preprocessors[\"__VERSION__\"] = options.version;\r\n    preprocessors[options.platformName] = \"true\";\r\n\r\n    _GetGlobalDefines(preprocessors, engine?.isNDCHalfZRange, engine?.useReverseDepthBuffer, engine?.useExactSrgbConversions);\r\n\r\n    return preprocessors;\r\n}\r\n\r\nfunction ProcessShaderConversion(sourceCode: string, options: _IProcessingOptions, engine?: AbstractEngine): string {\r\n    let preparedSourceCode = ProcessPrecision(sourceCode, options);\r\n\r\n    if (!options.processor) {\r\n        return preparedSourceCode;\r\n    }\r\n\r\n    // Already converted\r\n    if (options.processor.shaderLanguage === ShaderLanguage.GLSL && preparedSourceCode.indexOf(\"#version 3\") !== -1) {\r\n        preparedSourceCode = preparedSourceCode.replace(\"#version 300 es\", \"\");\r\n        if (!options.processor.parseGLES3) {\r\n            return preparedSourceCode;\r\n        }\r\n    }\r\n\r\n    const defines = options.defines;\r\n\r\n    const preprocessors = PreparePreProcessors(options, engine);\r\n\r\n    // General pre processing\r\n    if (options.processor.preProcessor) {\r\n        preparedSourceCode = options.processor.preProcessor(preparedSourceCode, defines, preprocessors, options.isFragment, options.processingContext);\r\n    }\r\n\r\n    const preProcessorsFromCode: { [key: string]: string } = {};\r\n\r\n    preparedSourceCode = EvaluatePreProcessors(preparedSourceCode, preprocessors, options, preProcessorsFromCode);\r\n\r\n    // Post processing\r\n    if (options.processor.postProcessor) {\r\n        preparedSourceCode = options.processor.postProcessor(\r\n            preparedSourceCode,\r\n            defines,\r\n            options.isFragment,\r\n            options.processingContext,\r\n            engine\r\n                ? {\r\n                      drawBuffersExtensionDisabled: engine.getCaps().drawBuffersExtension ? false : true,\r\n                  }\r\n                : {},\r\n            preprocessors,\r\n            preProcessorsFromCode\r\n        );\r\n    }\r\n\r\n    // Inline functions tagged with #define inline\r\n    if (engine?._features.needShaderCodeInlining) {\r\n        preparedSourceCode = engine.inlineShaderCode(preparedSourceCode);\r\n    }\r\n\r\n    return preparedSourceCode;\r\n}\r\n\r\nfunction ApplyPreProcessing(sourceCode: string, options: _IProcessingOptions, engine: AbstractEngine): string {\r\n    let preparedSourceCode = sourceCode;\r\n\r\n    const defines = options.defines;\r\n\r\n    const preprocessors = PreparePreProcessors(options, engine);\r\n\r\n    // General pre processing\r\n    if (options.processor?.preProcessor) {\r\n        preparedSourceCode = options.processor.preProcessor(preparedSourceCode, defines, preprocessors, options.isFragment, options.processingContext);\r\n    }\r\n\r\n    const preProcessorsFromCode: { [key: string]: string } = {};\r\n\r\n    preparedSourceCode = EvaluatePreProcessors(preparedSourceCode, preprocessors, options, preProcessorsFromCode);\r\n\r\n    // Post processing\r\n    if (options.processor?.postProcessor) {\r\n        preparedSourceCode = options.processor.postProcessor(\r\n            preparedSourceCode,\r\n            defines,\r\n            options.isFragment,\r\n            options.processingContext,\r\n            engine\r\n                ? {\r\n                      drawBuffersExtensionDisabled: engine.getCaps().drawBuffersExtension ? false : true,\r\n                  }\r\n                : {},\r\n            preprocessors,\r\n            preProcessorsFromCode\r\n        );\r\n    }\r\n\r\n    // Inline functions tagged with #define inline\r\n    if (engine._features.needShaderCodeInlining) {\r\n        preparedSourceCode = engine.inlineShaderCode(preparedSourceCode);\r\n    }\r\n\r\n    return preparedSourceCode;\r\n}\r\n\r\n/** @internal */\r\nexport function ProcessIncludes(sourceCode: string, options: _IProcessingOptions, callback: (data: any) => void): void {\r\n    ReusableMatches.length = 0;\r\n    let match: RegExpMatchArray | null;\r\n    // stay back-compat to the old matchAll syntax\r\n    while ((match = RegexShaderInclude.exec(sourceCode)) !== null) {\r\n        ReusableMatches.push(match);\r\n    }\r\n\r\n    let parts = [sourceCode];\r\n\r\n    let keepProcessing = false;\r\n\r\n    for (const match of ReusableMatches) {\r\n        let includeFile = match[1];\r\n\r\n        // Uniform declaration\r\n        if (includeFile.indexOf(\"__decl__\") !== -1) {\r\n            includeFile = includeFile.replace(RegexShaderDecl, \"\");\r\n            if (options.supportsUniformBuffers) {\r\n                includeFile = includeFile.replace(\"Vertex\", \"Ubo\").replace(\"Fragment\", \"Ubo\");\r\n            }\r\n            includeFile = includeFile + \"Declaration\";\r\n        }\r\n\r\n        if (options.includesShadersStore[includeFile]) {\r\n            // Substitution\r\n            let includeContent = options.includesShadersStore[includeFile];\r\n            if (match[2]) {\r\n                const splits = match[3].split(\",\");\r\n\r\n                for (let index = 0; index < splits.length; index += 2) {\r\n                    const source = new RegExp(splits[index], \"g\");\r\n                    const dest = splits[index + 1];\r\n\r\n                    includeContent = includeContent.replace(source, dest);\r\n                }\r\n            }\r\n\r\n            if (match[4]) {\r\n                const indexString = match[5];\r\n\r\n                if (indexString.indexOf(\"..\") !== -1) {\r\n                    const indexSplits = indexString.split(\"..\");\r\n                    const minIndex = parseInt(indexSplits[0]);\r\n                    let maxIndex = parseInt(indexSplits[1]);\r\n                    let sourceIncludeContent = includeContent.slice(0);\r\n                    includeContent = \"\";\r\n\r\n                    if (isNaN(maxIndex)) {\r\n                        maxIndex = options.indexParameters[indexSplits[1]];\r\n                    }\r\n\r\n                    for (let i = minIndex; i < maxIndex; i++) {\r\n                        if (!options.supportsUniformBuffers) {\r\n                            // Ubo replacement\r\n                            sourceIncludeContent = sourceIncludeContent.replace(RegexLightX, (str: string, p1: string) => {\r\n                                return p1 + \"{X}\";\r\n                            });\r\n                        }\r\n                        includeContent += sourceIncludeContent.replace(RegexX, i.toString()) + \"\\n\";\r\n                    }\r\n                } else {\r\n                    if (!options.supportsUniformBuffers) {\r\n                        // Ubo replacement\r\n                        includeContent = includeContent.replace(RegexLightX, (str: string, p1: string) => {\r\n                            return p1 + \"{X}\";\r\n                        });\r\n                    }\r\n                    includeContent = includeContent.replace(RegexX, indexString);\r\n                }\r\n            }\r\n\r\n            // Replace\r\n            // Split all parts on match[0] and intersperse the parts with the include content\r\n            const newParts = [];\r\n            for (const part of parts) {\r\n                const splitPart = part.split(match[0]);\r\n                for (let i = 0; i < splitPart.length - 1; i++) {\r\n                    newParts.push(splitPart[i]);\r\n                    newParts.push(includeContent);\r\n                }\r\n                newParts.push(splitPart[splitPart.length - 1]);\r\n            }\r\n            parts = newParts;\r\n\r\n            keepProcessing = keepProcessing || includeContent.indexOf(\"#include<\") >= 0 || includeContent.indexOf(\"#include <\") >= 0;\r\n        } else {\r\n            const includeShaderUrl = options.shadersRepository + \"ShadersInclude/\" + includeFile + \".fx\";\r\n\r\n            _FunctionContainer.loadFile(includeShaderUrl, (fileContent) => {\r\n                options.includesShadersStore[includeFile] = fileContent as string;\r\n                ProcessIncludes(parts.join(\"\"), options, callback);\r\n            });\r\n            return;\r\n        }\r\n    }\r\n    ReusableMatches.length = 0;\r\n\r\n    const returnValue = parts.join(\"\");\r\n\r\n    if (keepProcessing) {\r\n        ProcessIncludes(returnValue.toString(), options, callback);\r\n    } else {\r\n        callback(returnValue);\r\n    }\r\n}\r\n\r\n/**\r\n * @deprecated Use direct imports from fileTools.pure instead. Kept for backwards compatibility.\r\n * @internal\r\n */\r\nexport const _FunctionContainer = {\r\n    loadFile: (\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void\r\n    ): IFileRequest => {\r\n        throw _WarnImport(\"FileTools\");\r\n    },\r\n};\r\n","let ImmediateQueue: Array<() => void> = [];\r\n\r\n/**\r\n * Class used to provide helper for timing\r\n */\r\nexport class TimingTools {\r\n    /**\r\n     * Execute a function after the current execution block\r\n     * @param action defines the action to execute after the current execution block\r\n     */\r\n    public static SetImmediate(action: () => void) {\r\n        if (ImmediateQueue.length === 0) {\r\n            setTimeout(() => {\r\n                // Execute all immediate functions\r\n                const functionsToCall = ImmediateQueue;\r\n                ImmediateQueue = [];\r\n\r\n                for (const func of functionsToCall) {\r\n                    func();\r\n                }\r\n            }, 1);\r\n        }\r\n        ImmediateQueue.push(action);\r\n    }\r\n}\r\n\r\nfunction RunWithCondition(condition: () => boolean, onSuccess: () => void, onError?: (e?: any, isTimeout?: boolean) => void) {\r\n    try {\r\n        if (condition()) {\r\n            onSuccess();\r\n            return true;\r\n        }\r\n    } catch (e) {\r\n        onError?.(e);\r\n        return true;\r\n    }\r\n    return false;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport const _RetryWithInterval = (\r\n    condition: () => boolean,\r\n    onSuccess: () => void,\r\n    onError?: (e?: any, isTimeout?: boolean) => void,\r\n    step = 16,\r\n    maxTimeout = 30000,\r\n    checkConditionOnCall: boolean = true,\r\n    additionalStringOnTimeout?: string\r\n) => {\r\n    // if checkConditionOnCall is true, we check the condition immediately. If it is true, run everything synchronously\r\n    if (checkConditionOnCall) {\r\n        // that means that one of the two happened - either the condition is true or an exception was thrown when checking the condition\r\n        if (RunWithCondition(condition, onSuccess, onError)) {\r\n            // don't schedule the interval, no reason to check it again.\r\n            return null;\r\n        }\r\n    }\r\n    const int = setInterval(() => {\r\n        if (RunWithCondition(condition, onSuccess, onError)) {\r\n            clearInterval(int);\r\n        } else {\r\n            maxTimeout -= step;\r\n            if (maxTimeout < 0) {\r\n                clearInterval(int);\r\n                onError?.(new Error(\"Operation timed out after maximum retries. \" + (additionalStringOnTimeout || \"\")), true);\r\n            }\r\n        }\r\n    }, step);\r\n    return () => clearInterval(int);\r\n};\r\n","/**\r\n * Lookup tables used for fast conversions between 32-bit floats and 16-bit (half) floats.\r\n * @see Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf\r\n */\r\ninterface IHalfFloatConversionTables {\r\n    floatView: Float32Array;\r\n    uint32View: Uint32Array;\r\n    baseTable: Uint32Array;\r\n    shiftTable: Uint32Array;\r\n    mantissaTable: Uint32Array;\r\n    exponentTable: Uint32Array;\r\n    offsetTable: Uint32Array;\r\n}\r\n\r\nlet Tables: IHalfFloatConversionTables | null = null;\r\n\r\n/**\r\n * Returns the conversion tables, building them lazily on first use.\r\n * Generation is deferred so that importing this module allocates nothing: tree-shaken code paths\r\n * that never convert a half float pay no cost, keeping the module side-effect free at import time.\r\n * @returns the shared conversion tables\r\n */\r\n// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf\r\nfunction GenerateTables(): IHalfFloatConversionTables {\r\n    if (Tables) {\r\n        return Tables;\r\n    }\r\n\r\n    const buffer = new ArrayBuffer(4);\r\n    const floatView = new Float32Array(buffer);\r\n    const uint32View = new Uint32Array(buffer);\r\n\r\n    // float32 to float16 helpers\r\n    const baseTable = new Uint32Array(512);\r\n    const shiftTable = new Uint32Array(512);\r\n\r\n    for (let i = 0; i < 256; ++i) {\r\n        const e = i - 127;\r\n\r\n        // very small number (0, -0)\r\n        if (e < -24) {\r\n            baseTable[i] = 0x0000;\r\n            baseTable[i | 0x100] = 0x8000;\r\n            shiftTable[i] = 24;\r\n            shiftTable[i | 0x100] = 24;\r\n\r\n            // small number (denorm)\r\n        } else if (e < -14) {\r\n            baseTable[i] = 0x0400 >> (-e - 14);\r\n            baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;\r\n            shiftTable[i] = -e - 1;\r\n            shiftTable[i | 0x100] = -e - 1;\r\n\r\n            // normal number\r\n        } else if (e <= 15) {\r\n            baseTable[i] = (e + 15) << 10;\r\n            baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000;\r\n            shiftTable[i] = 13;\r\n            shiftTable[i | 0x100] = 13;\r\n\r\n            // large number (Infinity, -Infinity)\r\n        } else if (e < 128) {\r\n            baseTable[i] = 0x7c00;\r\n            baseTable[i | 0x100] = 0xfc00;\r\n            shiftTable[i] = 24;\r\n            shiftTable[i | 0x100] = 24;\r\n\r\n            // stay (NaN, Infinity, -Infinity)\r\n        } else {\r\n            baseTable[i] = 0x7c00;\r\n            baseTable[i | 0x100] = 0xfc00;\r\n            shiftTable[i] = 13;\r\n            shiftTable[i | 0x100] = 13;\r\n        }\r\n    }\r\n\r\n    // float16 to float32 helpers\r\n    const mantissaTable = new Uint32Array(2048);\r\n    const exponentTable = new Uint32Array(64);\r\n    const offsetTable = new Uint32Array(64);\r\n\r\n    for (let i = 1; i < 1024; ++i) {\r\n        let m = i << 13; // zero pad mantissa bits\r\n        let e = 0; // zero exponent\r\n\r\n        // normalized\r\n        while ((m & 0x00800000) === 0) {\r\n            m <<= 1;\r\n            e -= 0x00800000; // decrement exponent\r\n        }\r\n\r\n        m &= ~0x00800000; // clear leading 1 bit\r\n        e += 0x38800000; // adjust bias\r\n\r\n        mantissaTable[i] = m | e;\r\n    }\r\n\r\n    for (let i = 1024; i < 2048; ++i) {\r\n        mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);\r\n    }\r\n\r\n    for (let i = 1; i < 31; ++i) {\r\n        exponentTable[i] = i << 23;\r\n    }\r\n\r\n    exponentTable[31] = 0x47800000;\r\n    exponentTable[32] = 0x80000000;\r\n\r\n    for (let i = 33; i < 63; ++i) {\r\n        exponentTable[i] = 0x80000000 + ((i - 32) << 23);\r\n    }\r\n\r\n    exponentTable[63] = 0xc7800000;\r\n\r\n    for (let i = 1; i < 64; ++i) {\r\n        if (i !== 32) {\r\n            offsetTable[i] = 1024;\r\n        }\r\n    }\r\n\r\n    Tables = {\r\n        floatView,\r\n        uint32View,\r\n        baseTable,\r\n        shiftTable,\r\n        mantissaTable,\r\n        exponentTable,\r\n        offsetTable,\r\n    };\r\n\r\n    return Tables;\r\n}\r\n\r\n/**\r\n * The largest finite magnitude representable by a 16-bit half-float (binary16): 65504.\r\n * Use this to clamp values into the half-float range before conversion instead of hardcoding the literal.\r\n */\r\nexport const MaxHalfFloat = 65504;\r\n\r\n/**\r\n * Converts a 32-bit float to its 16-bit half-float bit pattern.\r\n * @param value the float to convert\r\n * @returns the half-float bit pattern, in the range 0..65535\r\n */\r\nexport function ToHalfFloat(value: number): number {\r\n    // For now this truncates toward zero (drops the extra mantissa bits instead of rounding).\r\n    // TODO: replace with the native Float16Array / Math.f16round once Node 24 is the minimum version;\r\n    //       those round to nearest-even, so some results will change.\r\n    const tables = GenerateTables();\r\n\r\n    tables.floatView[0] = value;\r\n    const f = tables.uint32View[0];\r\n    const e = (f >> 23) & 0x1ff;\r\n    return tables.baseTable[e] + ((f & 0x007fffff) >> tables.shiftTable[e]);\r\n}\r\n\r\n/**\r\n * Converts a 16-bit half-float bit pattern back to a 32-bit float.\r\n * @param value the half-float bit pattern, in the range 0..65535\r\n * @returns the decoded float\r\n */\r\nexport function FromHalfFloat(value: number): number {\r\n    const tables = GenerateTables();\r\n\r\n    tables.uint32View[0] = tables.mantissaTable[tables.offsetTable[value >> 10] + (value & 0x03ff)] + tables.exponentTable[value >> 10];\r\n    return tables.floatView[0];\r\n}\r\n","import { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { FromHalfFloat, ToHalfFloat } from \"../Misc/halfFloat\";\r\nimport { type DataArray, type FloatArray, type IndicesArray, type TypedArray, type TypedArrayConstructor } from \"../types\";\r\n\r\n/**\r\n * Union of TypedArrays that can be used for vertex data.\r\n */\r\nexport type VertexDataTypedArray = Exclude<TypedArray, Float64Array | BigInt64Array | BigUint64Array>;\r\n\r\nfunction GetFloatValue(dataView: DataView, type: number, byteOffset: number, normalized: boolean): number {\r\n    switch (type) {\r\n        case Constants.BYTE: {\r\n            let value = dataView.getInt8(byteOffset);\r\n            if (normalized) {\r\n                value = Math.max(value / 127, -1);\r\n            }\r\n            return value;\r\n        }\r\n        case Constants.UNSIGNED_BYTE: {\r\n            let value = dataView.getUint8(byteOffset);\r\n            if (normalized) {\r\n                value = value / 255;\r\n            }\r\n            return value;\r\n        }\r\n        case Constants.SHORT: {\r\n            let value = dataView.getInt16(byteOffset, true);\r\n            if (normalized) {\r\n                value = Math.max(value / 32767, -1);\r\n            }\r\n            return value;\r\n        }\r\n        case Constants.UNSIGNED_SHORT: {\r\n            let value = dataView.getUint16(byteOffset, true);\r\n            if (normalized) {\r\n                value = value / 65535;\r\n            }\r\n            return value;\r\n        }\r\n        case Constants.HALF_FLOAT: {\r\n            return FromHalfFloat(dataView.getUint16(byteOffset, true));\r\n        }\r\n        case Constants.INT: {\r\n            return dataView.getInt32(byteOffset, true);\r\n        }\r\n        case Constants.UNSIGNED_INT: {\r\n            return dataView.getUint32(byteOffset, true);\r\n        }\r\n        case Constants.FLOAT: {\r\n            return dataView.getFloat32(byteOffset, true);\r\n        }\r\n        default: {\r\n            throw new Error(`Invalid component type ${type}`);\r\n        }\r\n    }\r\n}\r\n\r\nfunction SetFloatValue(dataView: DataView, type: number, byteOffset: number, normalized: boolean, value: number): void {\r\n    switch (type) {\r\n        case Constants.BYTE: {\r\n            if (normalized) {\r\n                value = Math.round(value * 127.0);\r\n            }\r\n            dataView.setInt8(byteOffset, value);\r\n            break;\r\n        }\r\n        case Constants.UNSIGNED_BYTE: {\r\n            if (normalized) {\r\n                value = Math.round(value * 255);\r\n            }\r\n            dataView.setUint8(byteOffset, value);\r\n            break;\r\n        }\r\n        case Constants.SHORT: {\r\n            if (normalized) {\r\n                value = Math.round(value * 32767);\r\n            }\r\n            dataView.setInt16(byteOffset, value, true);\r\n            break;\r\n        }\r\n        case Constants.UNSIGNED_SHORT: {\r\n            if (normalized) {\r\n                value = Math.round(value * 65535);\r\n            }\r\n            dataView.setUint16(byteOffset, value, true);\r\n            break;\r\n        }\r\n        case Constants.HALF_FLOAT: {\r\n            dataView.setUint16(byteOffset, ToHalfFloat(value), true);\r\n            break;\r\n        }\r\n        case Constants.INT: {\r\n            dataView.setInt32(byteOffset, value, true);\r\n            break;\r\n        }\r\n        case Constants.UNSIGNED_INT: {\r\n            dataView.setUint32(byteOffset, value, true);\r\n            break;\r\n        }\r\n        case Constants.FLOAT: {\r\n            dataView.setFloat32(byteOffset, value, true);\r\n            break;\r\n        }\r\n        default: {\r\n            throw new Error(`Invalid component type ${type}`);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the byte length of the given type.\r\n * @param type the type\r\n * @returns the number of bytes\r\n */\r\nexport function GetTypeByteLength(type: number): number {\r\n    switch (type) {\r\n        case Constants.BYTE:\r\n        case Constants.UNSIGNED_BYTE:\r\n            return 1;\r\n        case Constants.SHORT:\r\n        case Constants.UNSIGNED_SHORT:\r\n        case Constants.HALF_FLOAT:\r\n            return 2;\r\n        case Constants.INT:\r\n        case Constants.UNSIGNED_INT:\r\n        case Constants.FLOAT:\r\n            return 4;\r\n        default:\r\n            throw new Error(`Invalid type '${type}'`);\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the appropriate TypedArray constructor for the given component type.\r\n * @param componentType the component type\r\n * @returns the constructor object\r\n */\r\nexport function GetTypedArrayConstructor(componentType: number): TypedArrayConstructor<VertexDataTypedArray> {\r\n    switch (componentType) {\r\n        case Constants.BYTE:\r\n            return Int8Array;\r\n        case Constants.UNSIGNED_BYTE:\r\n            return Uint8Array;\r\n        case Constants.SHORT:\r\n            return Int16Array;\r\n        case Constants.UNSIGNED_SHORT:\r\n            return Uint16Array;\r\n        case Constants.HALF_FLOAT:\r\n            return Uint16Array;\r\n        case Constants.INT:\r\n            return Int32Array;\r\n        case Constants.UNSIGNED_INT:\r\n            return Uint32Array;\r\n        case Constants.FLOAT:\r\n            return Float32Array;\r\n        default:\r\n            throw new Error(`Invalid component type '${componentType}'`);\r\n    }\r\n}\r\n\r\n/**\r\n * Enumerates each value of the data array and calls the given callback.\r\n * @param data the data to enumerate\r\n * @param byteOffset the byte offset of the data\r\n * @param byteStride the byte stride of the data\r\n * @param componentCount the number of components per element\r\n * @param componentType the type of the component\r\n * @param count the number of values to enumerate\r\n * @param normalized whether the data is normalized\r\n * @param callback the callback function called for each group of component values\r\n */\r\nexport function EnumerateFloatValues(\r\n    data: DataArray,\r\n    byteOffset: number,\r\n    byteStride: number,\r\n    componentCount: number,\r\n    componentType: number,\r\n    count: number,\r\n    normalized: boolean,\r\n    callback: (values: number[], index: number) => void\r\n): void {\r\n    const oldValues = new Array<number>(componentCount);\r\n    const newValues = new Array<number>(componentCount);\r\n\r\n    if (data instanceof Array) {\r\n        let offset = byteOffset / 4;\r\n        const stride = byteStride / 4;\r\n        for (let index = 0; index < count; index += componentCount) {\r\n            for (let componentIndex = 0; componentIndex < componentCount; componentIndex++) {\r\n                oldValues[componentIndex] = newValues[componentIndex] = data[offset + componentIndex];\r\n            }\r\n\r\n            callback(newValues, index);\r\n\r\n            for (let componentIndex = 0; componentIndex < componentCount; componentIndex++) {\r\n                if (oldValues[componentIndex] !== newValues[componentIndex]) {\r\n                    data[offset + componentIndex] = newValues[componentIndex];\r\n                }\r\n            }\r\n\r\n            offset += stride;\r\n        }\r\n    } else {\r\n        const dataView = !ArrayBuffer.isView(data) ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);\r\n        const componentByteLength = GetTypeByteLength(componentType);\r\n        for (let index = 0; index < count; index += componentCount) {\r\n            for (let componentIndex = 0, componentByteOffset = byteOffset; componentIndex < componentCount; componentIndex++, componentByteOffset += componentByteLength) {\r\n                oldValues[componentIndex] = newValues[componentIndex] = GetFloatValue(dataView, componentType, componentByteOffset, normalized);\r\n            }\r\n\r\n            callback(newValues, index);\r\n\r\n            for (let componentIndex = 0, componentByteOffset = byteOffset; componentIndex < componentCount; componentIndex++, componentByteOffset += componentByteLength) {\r\n                if (oldValues[componentIndex] !== newValues[componentIndex]) {\r\n                    SetFloatValue(dataView, componentType, componentByteOffset, normalized, newValues[componentIndex]);\r\n                }\r\n            }\r\n\r\n            byteOffset += byteStride;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the given data array as a float array. Float data is constructed if the data array cannot be returned directly.\r\n * @param data the input data array\r\n * @param size the number of components\r\n * @param type the component type\r\n * @param byteOffset the byte offset of the data\r\n * @param byteStride the byte stride of the data\r\n * @param normalized whether the data is normalized\r\n * @param totalVertices number of vertices in the buffer to take into account\r\n * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n * @returns a float array containing vertex data\r\n */\r\nexport function GetFloatData(\r\n    data: DataArray,\r\n    size: number,\r\n    type: number,\r\n    byteOffset: number,\r\n    byteStride: number,\r\n    normalized: boolean,\r\n    totalVertices: number,\r\n    forceCopy?: boolean\r\n): FloatArray {\r\n    const tightlyPackedByteStride = size * GetTypeByteLength(type);\r\n    const count = totalVertices * size;\r\n\r\n    if (type !== Constants.FLOAT || byteStride !== tightlyPackedByteStride) {\r\n        const copy = new Float32Array(count);\r\n        EnumerateFloatValues(data, byteOffset, byteStride, size, type, count, normalized, (values, index) => {\r\n            for (let i = 0; i < size; i++) {\r\n                copy[index + i] = values[i];\r\n            }\r\n        });\r\n        return copy;\r\n    }\r\n\r\n    if (!(data instanceof Array || data instanceof Float32Array) || byteOffset !== 0 || data.length !== count) {\r\n        if (data instanceof Array) {\r\n            const offset = byteOffset / 4;\r\n            return data.slice(offset, offset + count);\r\n        } else if (ArrayBuffer.isView(data)) {\r\n            const offset = data.byteOffset + byteOffset;\r\n            if ((offset & 3) !== 0) {\r\n                Logger.Warn(\"Float array must be aligned to 4-bytes border\");\r\n                forceCopy = true;\r\n            }\r\n\r\n            if (forceCopy) {\r\n                return new Float32Array(data.buffer.slice(offset, offset + count * Float32Array.BYTES_PER_ELEMENT));\r\n            } else {\r\n                return new Float32Array(data.buffer, offset, count);\r\n            }\r\n        } else {\r\n            return new Float32Array(data, byteOffset, count);\r\n        }\r\n    }\r\n\r\n    if (forceCopy) {\r\n        return data.slice();\r\n    }\r\n\r\n    return data;\r\n}\r\n\r\n/**\r\n * Gets the given data array as a typed array that matches the component type. If the data cannot be used directly, a copy is made to support the new typed array.\r\n * If the data is number[], byteOffset and byteStride must be a multiple of 4, as data will be treated like a list of floats.\r\n * @param data the input data array\r\n * @param size the number of components\r\n * @param type the component type\r\n * @param byteOffset the byte offset of the data\r\n * @param byteStride the byte stride of the data\r\n * @param totalVertices number of vertices in the buffer to take into account\r\n * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n * @returns a typed array containing vertex data\r\n */\r\nexport function GetTypedArrayData(\r\n    data: DataArray,\r\n    size: number,\r\n    type: number,\r\n    byteOffset: number,\r\n    byteStride: number,\r\n    totalVertices: number,\r\n    forceCopy?: boolean\r\n): VertexDataTypedArray {\r\n    const typeByteLength = GetTypeByteLength(type);\r\n    const constructor = GetTypedArrayConstructor(type);\r\n    const count = totalVertices * size;\r\n\r\n    // Handle number[]\r\n    if (Array.isArray(data)) {\r\n        if ((byteOffset & 3) !== 0 || (byteStride & 3) !== 0) {\r\n            throw new Error(\"byteOffset and byteStride must be a multiple of 4 for number[] data.\");\r\n        }\r\n\r\n        const offset = byteOffset / 4;\r\n        const stride = byteStride / 4;\r\n\r\n        const lastIndex = offset + (totalVertices - 1) * stride + size;\r\n        if (lastIndex > data.length) {\r\n            throw new Error(\"Last accessed index is out of bounds.\");\r\n        }\r\n\r\n        if (stride < size) {\r\n            throw new Error(\"Data stride cannot be smaller than the component size.\");\r\n        }\r\n        if (stride !== size) {\r\n            const copy = new constructor(count);\r\n            EnumerateFloatValues(data, byteOffset, byteStride, size, type, count, false, (values, index) => {\r\n                for (let i = 0; i < size; i++) {\r\n                    copy[index + i] = values[i];\r\n                }\r\n            });\r\n            return copy;\r\n        }\r\n\r\n        return new constructor(data.slice(offset, offset + count));\r\n    }\r\n\r\n    // Handle ArrayBuffer and ArrayBufferView\r\n    let buffer: ArrayBufferLike;\r\n    let adjustedByteOffset = byteOffset;\r\n\r\n    if (ArrayBuffer.isView(data)) {\r\n        buffer = data.buffer;\r\n        adjustedByteOffset += data.byteOffset;\r\n    } else {\r\n        buffer = data;\r\n    }\r\n\r\n    const lastByteOffset = adjustedByteOffset + (totalVertices - 1) * byteStride + size * typeByteLength;\r\n    if (lastByteOffset > buffer.byteLength) {\r\n        throw new Error(\"Last accessed byte is out of bounds.\");\r\n    }\r\n\r\n    const tightlyPackedByteStride = size * typeByteLength;\r\n    if (byteStride < tightlyPackedByteStride) {\r\n        throw new Error(\"Byte stride cannot be smaller than the component's byte size.\");\r\n    }\r\n    if (byteStride !== tightlyPackedByteStride) {\r\n        const copy = new constructor(count);\r\n        const src = new Uint8Array(buffer, adjustedByteOffset);\r\n        const dst = new Uint8Array(copy.buffer);\r\n        const rowBytes = size * typeByteLength;\r\n        for (let v = 0, s = 0, d = 0; v < totalVertices; v++, s += byteStride, d += rowBytes) {\r\n            dst.set(src.subarray(s, s + rowBytes), d);\r\n        }\r\n        return copy;\r\n    }\r\n\r\n    if (typeByteLength !== 1 && (adjustedByteOffset & (typeByteLength - 1)) !== 0) {\r\n        Logger.Warn(\"Array must be aligned to border of element size. Data will be copied.\");\r\n        forceCopy = true;\r\n    }\r\n\r\n    if (forceCopy) {\r\n        return new constructor(buffer.slice(adjustedByteOffset, adjustedByteOffset + count * typeByteLength));\r\n    }\r\n\r\n    return new constructor(buffer, adjustedByteOffset, count);\r\n}\r\n\r\n/**\r\n * Copies the given data array to the given float array.\r\n * @param input the input data array\r\n * @param size the number of components\r\n * @param type the component type\r\n * @param byteOffset the byte offset of the data\r\n * @param byteStride the byte stride of the data\r\n * @param normalized whether the data is normalized\r\n * @param totalVertices number of vertices in the buffer to take into account\r\n * @param output the output float array\r\n */\r\nexport function CopyFloatData(\r\n    input: DataArray,\r\n    size: number,\r\n    type: number,\r\n    byteOffset: number,\r\n    byteStride: number,\r\n    normalized: boolean,\r\n    totalVertices: number,\r\n    output: Float32Array\r\n): void {\r\n    const tightlyPackedByteStride = size * GetTypeByteLength(type);\r\n    const count = totalVertices * size;\r\n\r\n    if (output.length !== count) {\r\n        throw new Error(\"Output length is not valid\");\r\n    }\r\n\r\n    if (type !== Constants.FLOAT || byteStride !== tightlyPackedByteStride) {\r\n        EnumerateFloatValues(input, byteOffset, byteStride, size, type, count, normalized, (values, index) => {\r\n            for (let i = 0; i < size; i++) {\r\n                output[index + i] = values[i];\r\n            }\r\n        });\r\n        return;\r\n    }\r\n\r\n    if (input instanceof Array) {\r\n        const offset = byteOffset / 4;\r\n        output.set(input, offset);\r\n    } else if (ArrayBuffer.isView(input)) {\r\n        const offset = input.byteOffset + byteOffset;\r\n        if ((offset & 3) !== 0) {\r\n            Logger.Warn(\"Float array must be aligned to 4-bytes border\");\r\n            output.set(new Float32Array(input.buffer.slice(offset, offset + count * Float32Array.BYTES_PER_ELEMENT)));\r\n            return;\r\n        }\r\n\r\n        const floatData = new Float32Array(input.buffer, offset, count);\r\n        output.set(floatData);\r\n    } else {\r\n        const floatData = new Float32Array(input, byteOffset, count);\r\n        output.set(floatData);\r\n    }\r\n}\r\n\r\n/**\r\n * Utility function to determine if an IndicesArray is an Uint32Array. If indices is an Array, determines whether at least one index is 32 bits.\r\n * @param indices The IndicesArray to check.\r\n * @param count The number of indices. Only used if indices is an Array.\r\n * @param start The offset to start at (default: 0). Only used if indices is an Array.\r\n * @param offset The offset to substract from the indices before testing (default: 0). Only used if indices is an Array.\r\n * @returns True if the indices use 32 bits\r\n */\r\nexport function AreIndices32Bits(indices: IndicesArray, count: number, start = 0, offset = 0): boolean {\r\n    if (Array.isArray(indices)) {\r\n        for (let index = 0; index < count; index++) {\r\n            if (indices[start + index] - offset > 65535) {\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    return indices.BYTES_PER_ELEMENT === 4;\r\n}\r\n\r\n/**\r\n * Creates a typed array suitable for GPU buffer operations, as some engines require CPU buffer sizes to be aligned to specific boundaries (e.g., 4 bytes).\r\n * The use of non-aligned arrays still works but may result in a performance penalty.\r\n * @param type The type of the array. For instance, Float32Array or Uint8Array\r\n * @param elementCount The number of elements to store in the array\r\n * @returns The aligned typed array\r\n */\r\nexport function CreateAlignedTypedArray<T extends TypedArray>(type: TypedArrayConstructor<T>, elementCount: number): T {\r\n    let byteSize = elementCount * type.BYTES_PER_ELEMENT;\r\n\r\n    if ((byteSize & 3) === 0) {\r\n        return new type(elementCount);\r\n    }\r\n\r\n    byteSize = (byteSize + 3) & ~3;\r\n\r\n    const backingBuffer = new ArrayBuffer(byteSize);\r\n\r\n    return new type(backingBuffer, 0, elementCount);\r\n}\r\n\r\n/**\r\n * Gets a BufferSource from an ArrayBufferView, ensuring that the returned ArrayBuffer is not a SharedArrayBuffer.\r\n * If the input view's buffer is a SharedArrayBuffer, a new ArrayBuffer is created and the data is copied over.\r\n * @param view The input ArrayBufferView\r\n * @returns An ArrayBuffer containing the data from the view\r\n */\r\nexport function GetBlobBufferSource(view: ArrayBufferView): BufferSource {\r\n    const buffer = view.buffer;\r\n    if (buffer instanceof ArrayBuffer) {\r\n        // Safely cast here because we know bytes is not a SharedArrayBuffer\r\n        return view as ArrayBufferView<ArrayBuffer>;\r\n    }\r\n\r\n    // We are dealing with a SharedArrayBuffer, so we need to create a new ArrayBuffer and copy the data over\r\n    const unsharedBuffer = new ArrayBuffer(view.byteLength);\r\n    const copyView = new Uint8Array(unsharedBuffer);\r\n    copyView.set(new Uint8Array(buffer, view.byteOffset, view.byteLength));\r\n    return unsharedBuffer;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebRequest } from \"./webRequest\";\r\nimport { IsWindowObjectExist } from \"./domManagement\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type IOfflineProvider } from \"../Offline/IOfflineProvider\";\r\nimport { type IFileRequest } from \"./fileRequest\";\r\nimport { Observable } from \"./observable.pure\";\r\nimport { FilesInputStore } from \"./filesInputStore\";\r\nimport { RetryStrategy } from \"./retryStrategy\";\r\nimport { BaseError, ErrorCodes, RuntimeError } from \"./error\";\r\nimport { DecodeBase64ToBinary, DecodeBase64ToString, EncodeArrayBufferToBase64 } from \"./stringTools\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { EngineFunctionContext } from \"../Engines/abstractEngine.functions\";\r\nimport { _FunctionContainer } from \"../Engines/Processors/shaderProcessor\";\r\nimport { Logger } from \"./logger\";\r\nimport { TimingTools } from \"./timingTools\";\r\nimport { GetBlobBufferSource } from \"../Buffers/bufferUtils\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unsafe-return */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\nconst Base64DataUrlRegEx = /*#__PURE__*/ new RegExp(/^data:([^,]+\\/[^,]+)?;base64,/i);\r\n\r\n/** @ignore */\r\nexport class LoadFileError extends RuntimeError {\r\n    public request?: WebRequest;\r\n    public file?: File;\r\n\r\n    /**\r\n     * Creates a new LoadFileError\r\n     * @param message defines the message of the error\r\n     * @param object defines the optional web request\r\n     */\r\n    constructor(message: string, object?: WebRequest | File) {\r\n        super(message, ErrorCodes.LoadFileError);\r\n\r\n        this.name = \"LoadFileError\";\r\n        BaseError._setPrototypeOf(this, LoadFileError.prototype);\r\n\r\n        if (object instanceof WebRequest) {\r\n            this.request = object;\r\n        } else {\r\n            this.file = object;\r\n        }\r\n    }\r\n}\r\n\r\n/** @ignore */\r\nexport class RequestFileError extends RuntimeError {\r\n    /**\r\n     * Creates a new LoadFileError\r\n     * @param message defines the message of the error\r\n     * @param request defines the optional web request\r\n     */\r\n    constructor(\r\n        message: string,\r\n        public request: WebRequest\r\n    ) {\r\n        super(message, ErrorCodes.RequestFileError);\r\n        this.name = \"RequestFileError\";\r\n        BaseError._setPrototypeOf(this, RequestFileError.prototype);\r\n    }\r\n}\r\n\r\n/** @ignore */\r\nexport class ReadFileError extends RuntimeError {\r\n    /**\r\n     * Creates a new ReadFileError\r\n     * @param message defines the message of the error\r\n     * @param file defines the optional file\r\n     */\r\n    constructor(\r\n        message: string,\r\n        public file: File\r\n    ) {\r\n        super(message, ErrorCodes.ReadFileError);\r\n        this.name = \"ReadFileError\";\r\n        BaseError._setPrototypeOf(this, ReadFileError.prototype);\r\n    }\r\n}\r\n\r\n/**\r\n * Removes unwanted characters from an url\r\n * @param url defines the url to clean\r\n * @returns the cleaned url\r\n */\r\nconst CleanUrl = (url: string): string => {\r\n    url = url.replace(/#/gm, \"%23\");\r\n    return url;\r\n};\r\n\r\n/**\r\n * @internal\r\n */\r\nexport const FileToolsOptions: {\r\n    DefaultRetryStrategy: (url: string, request: WebRequest, retryIndex: number) => number;\r\n    BaseUrl: string;\r\n    CorsBehavior: string | ((url: string | string[]) => string);\r\n    PreprocessUrl: (url: string) => string;\r\n    ScriptBaseUrl: string;\r\n    ScriptPreprocessUrl: (url: string) => string;\r\n    CleanUrl: (url: string) => string;\r\n} = {\r\n    /**\r\n     * Gets or sets the retry strategy to apply when an error happens while loading an asset.\r\n     * When defining this function, return the wait time before trying again or return -1 to\r\n     * stop retrying and error out.\r\n     */\r\n    DefaultRetryStrategy: RetryStrategy.ExponentialBackoff(),\r\n\r\n    /**\r\n     * Gets or sets the base URL to use to load assets\r\n     */\r\n    BaseUrl: \"\",\r\n\r\n    /**\r\n     * Default behaviour for cors in the application.\r\n     * It can be a string if the expected behavior is identical in the entire app.\r\n     * Or a callback to be able to set it per url or on a group of them (in case of Video source for instance)\r\n     */\r\n    CorsBehavior: \"anonymous\",\r\n\r\n    /**\r\n     * Gets or sets a function used to pre-process url before using them to load assets\r\n     * @param url\r\n     * @returns the processed url\r\n     */\r\n    PreprocessUrl: (url: string) => url,\r\n\r\n    /**\r\n     * Gets or sets the base URL to use to load scripts\r\n     * Used for both JS and WASM\r\n     */\r\n    ScriptBaseUrl: \"\",\r\n    /**\r\n     * Gets or sets a function used to pre-process script url before using them to load.\r\n     * Used for both JS and WASM\r\n     * @param url defines the url to process\r\n     * @returns the processed url\r\n     */\r\n    ScriptPreprocessUrl: (url: string) => url,\r\n\r\n    /**\r\n     * Gets or sets a function used to clean the url before using it to load assets\r\n     * @param url defines the url to clean\r\n     * @returns the cleaned url\r\n     */\r\n    CleanUrl,\r\n};\r\n\r\n/**\r\n * Sets the cors behavior on a dom element. This will add the required Tools.CorsBehavior to the element.\r\n * @param url define the url we are trying\r\n * @param element define the dom element where to configure the cors policy\r\n * @internal\r\n */\r\nexport const SetCorsBehavior = (url: string | string[], element: { crossOrigin: string | null }): void => {\r\n    if (url && url.indexOf(\"data:\") === 0) {\r\n        return;\r\n    }\r\n\r\n    if (FileToolsOptions.CorsBehavior) {\r\n        if (typeof FileToolsOptions.CorsBehavior === \"string\" || FileToolsOptions.CorsBehavior instanceof String) {\r\n            element.crossOrigin = <string>FileToolsOptions.CorsBehavior;\r\n        } else {\r\n            const result = FileToolsOptions.CorsBehavior(url);\r\n            if (result) {\r\n                element.crossOrigin = result;\r\n            }\r\n        }\r\n    }\r\n};\r\n\r\n/**\r\n * Configuration used to load images\r\n * @see https://playground.babylonjs.com/#DKMEZK#2\r\n */\r\nexport const LoadImageConfiguration: {\r\n    /**\r\n     * Use this callback if you want to provide the required size of an image before loading it.\r\n     */\r\n    getRequiredSize: Nullable<\r\n        (input: string | ArrayBuffer | ArrayBufferView | Blob) => {\r\n            width: number;\r\n            height: number;\r\n        }\r\n    >;\r\n} = {\r\n    getRequiredSize: null,\r\n};\r\n\r\n/**\r\n * Loads an image as an HTMLImageElement.\r\n * @param input url string, ArrayBuffer, or Blob to load\r\n * @param onLoad callback called when the image successfully loads\r\n * @param onError callback called when the image fails to load\r\n * @param offlineProvider offline provider for caching\r\n * @param mimeType optional mime type\r\n * @param imageBitmapOptions\r\n * @param engine the engine instance to use\r\n * @returns the HTMLImageElement of the loaded image\r\n * @internal\r\n */\r\nexport const LoadImage = (\r\n    input: string | ArrayBuffer | ArrayBufferView | Blob,\r\n    onLoad: (img: HTMLImageElement | ImageBitmap) => void,\r\n    onError: (message?: string, exception?: any) => void,\r\n    offlineProvider: Nullable<IOfflineProvider>,\r\n    mimeType: string = \"\",\r\n    imageBitmapOptions?: ImageBitmapOptions,\r\n    engine = EngineStore.LastCreatedEngine\r\n): Nullable<HTMLImageElement> => {\r\n    if (typeof HTMLImageElement === \"undefined\" && !engine?._features.forceBitmapOverHTMLImageElement) {\r\n        onError(\"LoadImage is only supported in web or BabylonNative environments.\");\r\n        return null;\r\n    }\r\n\r\n    if (engine?._features.forceBitmapOverHTMLImageElement && typeof input !== \"string\" && typeof Blob !== \"undefined\") {\r\n        let blob: Blob;\r\n\r\n        if (input instanceof Blob) {\r\n            blob = input;\r\n        } else {\r\n            const source = input instanceof ArrayBuffer ? input : GetBlobBufferSource(input);\r\n            blob = new Blob([source], { type: mimeType });\r\n        }\r\n\r\n        engine\r\n            .createImageBitmap(blob, { premultiplyAlpha: \"none\", colorSpaceConversion: \"none\", ...imageBitmapOptions })\r\n            // eslint-disable-next-line github/no-then\r\n            .then(onLoad)\r\n            // eslint-disable-next-line github/no-then\r\n            .catch((reason) => {\r\n                if (onError) {\r\n                    onError(\"Error while trying to load image: \" + input, reason);\r\n                }\r\n            });\r\n\r\n        return null;\r\n    }\r\n\r\n    let url: string;\r\n    let usingObjectURL = false;\r\n\r\n    if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {\r\n        if (typeof Blob !== \"undefined\" && typeof URL !== \"undefined\") {\r\n            let source: BufferSource;\r\n\r\n            if (input instanceof ArrayBuffer) {\r\n                source = input;\r\n            } else {\r\n                source = GetBlobBufferSource(input);\r\n            }\r\n\r\n            url = URL.createObjectURL(new Blob([source], { type: mimeType }));\r\n            usingObjectURL = true;\r\n        } else {\r\n            url = `data:${mimeType};base64,` + EncodeArrayBufferToBase64(input);\r\n        }\r\n    } else if (input instanceof Blob) {\r\n        url = URL.createObjectURL(input);\r\n        usingObjectURL = true;\r\n    } else {\r\n        url = FileToolsOptions.CleanUrl(input);\r\n        url = FileToolsOptions.PreprocessUrl(url);\r\n    }\r\n\r\n    const onErrorHandler = (exception: any) => {\r\n        if (onError) {\r\n            // eslint-disable-next-line @typescript-eslint/no-base-to-string\r\n            const inputText = url || input.toString();\r\n            onError(`Error while trying to load image: ${inputText.indexOf(\"http\") === 0 || inputText.length <= 128 ? inputText : inputText.slice(0, 128) + \"...\"}`, exception);\r\n        }\r\n    };\r\n\r\n    if (engine?._features.forceBitmapOverHTMLImageElement) {\r\n        LoadFile(\r\n            url,\r\n            (data) => {\r\n                engine\r\n                    .createImageBitmap(new Blob([data], { type: mimeType }), { premultiplyAlpha: \"none\", colorSpaceConversion: \"none\", ...imageBitmapOptions })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((imgBmp) => {\r\n                        onLoad(imgBmp);\r\n                        if (usingObjectURL) {\r\n                            URL.revokeObjectURL(url);\r\n                        }\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((reason) => {\r\n                        if (onError) {\r\n                            // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\r\n                            onError(\"Error while trying to load image: \" + input, reason);\r\n                        }\r\n                    });\r\n            },\r\n            undefined,\r\n            offlineProvider || undefined,\r\n            true,\r\n            (request, exception) => {\r\n                onErrorHandler(exception);\r\n            }\r\n        );\r\n\r\n        return null;\r\n    }\r\n\r\n    const img = new Image();\r\n    if (LoadImageConfiguration.getRequiredSize) {\r\n        const size = LoadImageConfiguration.getRequiredSize(input);\r\n        if (size.width) {\r\n            img.width = size.width;\r\n        }\r\n        if (size.height) {\r\n            img.height = size.height;\r\n        }\r\n    }\r\n    SetCorsBehavior(url, img);\r\n\r\n    const handlersList: { target: any; name: string; handler: any }[] = [];\r\n\r\n    const loadHandlersList = () => {\r\n        for (const handler of handlersList) {\r\n            handler.target.addEventListener(handler.name, handler.handler);\r\n        }\r\n    };\r\n\r\n    const unloadHandlersList = () => {\r\n        for (const handler of handlersList) {\r\n            handler.target.removeEventListener(handler.name, handler.handler);\r\n        }\r\n        handlersList.length = 0;\r\n    };\r\n\r\n    const loadHandler = () => {\r\n        unloadHandlersList();\r\n\r\n        onLoad(img);\r\n\r\n        // Must revoke the URL after calling onLoad to avoid security exceptions in\r\n        // certain scenarios (e.g. when hosted in vscode).\r\n        if (usingObjectURL && img.src) {\r\n            URL.revokeObjectURL(img.src);\r\n        }\r\n    };\r\n\r\n    const errorHandler = (err: any) => {\r\n        unloadHandlersList();\r\n\r\n        onErrorHandler(err);\r\n\r\n        if (usingObjectURL && img.src) {\r\n            URL.revokeObjectURL(img.src);\r\n        }\r\n    };\r\n\r\n    const cspHandler = (err: any) => {\r\n        if (err.blockedURI !== img.src || err.disposition === \"report\") {\r\n            return;\r\n        }\r\n\r\n        unloadHandlersList();\r\n        const cspException = new Error(`CSP violation of policy ${err.effectiveDirective} ${err.blockedURI}. Current policy is ${err.originalPolicy}`);\r\n\r\n        EngineStore.UseFallbackTexture = false;\r\n        onErrorHandler(cspException);\r\n        if (usingObjectURL && img.src) {\r\n            URL.revokeObjectURL(img.src);\r\n        }\r\n        img.src = \"\";\r\n    };\r\n\r\n    handlersList.push({ target: img, name: \"load\", handler: loadHandler });\r\n    handlersList.push({ target: img, name: \"error\", handler: errorHandler });\r\n    handlersList.push({ target: document, name: \"securitypolicyviolation\", handler: cspHandler });\r\n\r\n    loadHandlersList();\r\n\r\n    const fromBlob = url.substring(0, 5) === \"blob:\";\r\n    const fromData = url.substring(0, 5) === \"data:\";\r\n    const noOfflineSupport = () => {\r\n        if (fromBlob || fromData || !WebRequest.IsCustomRequestAvailable) {\r\n            img.src = url;\r\n        } else {\r\n            LoadFile(\r\n                url,\r\n                (data, _, contentType) => {\r\n                    const type = !mimeType && contentType ? contentType : mimeType;\r\n                    const blob = new Blob([data], { type });\r\n                    const url = URL.createObjectURL(blob);\r\n                    usingObjectURL = true;\r\n                    img.src = url;\r\n                },\r\n                undefined,\r\n                offlineProvider || undefined,\r\n                true,\r\n                (_request, exception) => {\r\n                    onErrorHandler(exception);\r\n                }\r\n            );\r\n        }\r\n    };\r\n\r\n    const loadFromOfflineSupport = () => {\r\n        if (offlineProvider) {\r\n            offlineProvider.loadImage(url, img);\r\n        }\r\n    };\r\n\r\n    if (!fromBlob && !fromData && offlineProvider && offlineProvider.enableTexturesOffline) {\r\n        offlineProvider.open(loadFromOfflineSupport, noOfflineSupport);\r\n    } else {\r\n        if (url.indexOf(\"file:\") !== -1) {\r\n            const textureName = decodeURIComponent(url.substring(5).toLowerCase());\r\n            if (FilesInputStore.FilesToLoad[textureName] && typeof URL !== \"undefined\") {\r\n                try {\r\n                    let blobURL;\r\n                    try {\r\n                        blobURL = URL.createObjectURL(FilesInputStore.FilesToLoad[textureName]);\r\n                    } catch (ex) {\r\n                        // Chrome doesn't support oneTimeOnly parameter\r\n                        blobURL = URL.createObjectURL(FilesInputStore.FilesToLoad[textureName]);\r\n                    }\r\n                    img.src = blobURL;\r\n                    usingObjectURL = true;\r\n                } catch (e) {\r\n                    img.src = \"\";\r\n                }\r\n                return img;\r\n            }\r\n        }\r\n\r\n        noOfflineSupport();\r\n    }\r\n\r\n    return img;\r\n};\r\n\r\n/**\r\n * Reads a file from a File object\r\n * @param file defines the file to load\r\n * @param onSuccess defines the callback to call when data is loaded\r\n * @param onProgress defines the callback to call during loading process\r\n * @param useArrayBuffer defines a boolean indicating that data must be returned as an ArrayBuffer\r\n * @param onError defines the callback to call when an error occurs\r\n * @returns a file request object\r\n * @internal\r\n */\r\nexport const ReadFile = (\r\n    file: File,\r\n    onSuccess: (data: any) => void,\r\n    onProgress?: (ev: ProgressEvent) => any,\r\n    useArrayBuffer?: boolean,\r\n    onError?: (error: ReadFileError) => void\r\n): IFileRequest => {\r\n    const reader = new FileReader();\r\n    const fileRequest: IFileRequest = {\r\n        onCompleteObservable: new Observable<IFileRequest>(),\r\n        abort: () => reader.abort(),\r\n    };\r\n\r\n    reader.onloadend = () => fileRequest.onCompleteObservable.notifyObservers(fileRequest);\r\n    if (onError) {\r\n        reader.onerror = () => {\r\n            onError(new ReadFileError(`Unable to read ${file.name}`, file));\r\n        };\r\n    }\r\n    reader.onload = (e) => {\r\n        //target doesn't have result from ts 1.3\r\n        onSuccess((<any>e.target)[\"result\"]);\r\n    };\r\n    if (onProgress) {\r\n        reader.onprogress = onProgress;\r\n    }\r\n    if (!useArrayBuffer) {\r\n        // Asynchronous read\r\n        reader.readAsText(file);\r\n    } else {\r\n        reader.readAsArrayBuffer(file);\r\n    }\r\n\r\n    return fileRequest;\r\n};\r\n\r\n/**\r\n * Loads a file from a url, a data url, or a file url\r\n * @param fileOrUrl file, url, data url, or file url to load\r\n * @param onSuccess callback called when the file successfully loads\r\n * @param onProgress callback called while file is loading (if the server supports this mode)\r\n * @param offlineProvider defines the offline provider for caching\r\n * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer\r\n * @param onError callback called when the file fails to load\r\n * @param onOpened\r\n * @returns a file request object\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const LoadFile = (\r\n    fileOrUrl: File | string,\r\n    onSuccess: (data: string | ArrayBuffer, responseURL?: string, contentType?: Nullable<string>) => void,\r\n    onProgress?: (ev: ProgressEvent) => void,\r\n    offlineProvider?: Nullable<IOfflineProvider>,\r\n    useArrayBuffer?: boolean,\r\n    onError?: (request?: WebRequest, exception?: LoadFileError) => void,\r\n    onOpened?: (request: WebRequest) => void\r\n): IFileRequest => {\r\n    if ((fileOrUrl as File).name) {\r\n        return ReadFile(\r\n            fileOrUrl as File,\r\n            onSuccess,\r\n            onProgress,\r\n            useArrayBuffer,\r\n            onError\r\n                ? (error: ReadFileError) => {\r\n                      onError(undefined, error);\r\n                  }\r\n                : undefined\r\n        );\r\n    }\r\n\r\n    const url = fileOrUrl as string;\r\n\r\n    // If file and file input are set\r\n    if (url.indexOf(\"file:\") !== -1) {\r\n        let fileName = decodeURIComponent(url.substring(5).toLowerCase());\r\n        if (fileName.indexOf(\"./\") === 0) {\r\n            fileName = fileName.substring(2);\r\n        }\r\n        const file = FilesInputStore.FilesToLoad[fileName];\r\n        if (file) {\r\n            return ReadFile(file, onSuccess, onProgress, useArrayBuffer, onError ? (error) => onError(undefined, new LoadFileError(error.message, error.file)) : undefined);\r\n        }\r\n    }\r\n\r\n    // For a Base64 Data URL\r\n    const { match, type } = TestBase64DataUrl(url);\r\n    if (match) {\r\n        const fileRequest: IFileRequest = {\r\n            onCompleteObservable: new Observable<IFileRequest>(),\r\n            abort: () => () => {},\r\n        };\r\n\r\n        try {\r\n            const data = useArrayBuffer ? DecodeBase64UrlToBinary(url) : DecodeBase64UrlToString(url);\r\n            onSuccess(data, undefined, type);\r\n        } catch (error) {\r\n            if (onError) {\r\n                onError(undefined, error);\r\n            } else {\r\n                Logger.Error(error.message || \"Failed to parse the Data URL\");\r\n            }\r\n        }\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            fileRequest.onCompleteObservable.notifyObservers(fileRequest);\r\n        });\r\n\r\n        return fileRequest;\r\n    }\r\n\r\n    return RequestFile(\r\n        url,\r\n        (data, request) => {\r\n            onSuccess(data, request?.responseURL, request?.getResponseHeader(\"content-type\"));\r\n        },\r\n        onProgress,\r\n        offlineProvider,\r\n        useArrayBuffer,\r\n        onError\r\n            ? (error) => {\r\n                  onError(error.request, new LoadFileError(error.message, error.request));\r\n              }\r\n            : undefined,\r\n        onOpened\r\n    );\r\n};\r\n\r\n/**\r\n * Loads a file from a url\r\n * @param url url to load\r\n * @param onSuccess callback called when the file successfully loads\r\n * @param onProgress callback called while file is loading (if the server supports this mode)\r\n * @param offlineProvider defines the offline provider for caching\r\n * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer\r\n * @param onError callback called when the file fails to load\r\n * @param onOpened callback called when the web request is opened\r\n * @returns a file request object\r\n * @internal\r\n */\r\nexport const RequestFile = (\r\n    url: string,\r\n    onSuccess?: (data: string | ArrayBuffer, request?: WebRequest) => void,\r\n    onProgress?: (event: ProgressEvent) => void,\r\n    offlineProvider?: Nullable<IOfflineProvider>,\r\n    useArrayBuffer?: boolean,\r\n    onError?: (error: RequestFileError) => void,\r\n    onOpened?: (request: WebRequest) => void\r\n): IFileRequest => {\r\n    if (offlineProvider !== null) {\r\n        offlineProvider ??= EngineStore.LastCreatedScene?.offlineProvider;\r\n    }\r\n    url = FileToolsOptions.CleanUrl(url);\r\n    url = FileToolsOptions.PreprocessUrl(url);\r\n\r\n    const loadUrl = FileToolsOptions.BaseUrl + url;\r\n\r\n    let aborted = false;\r\n    const fileRequest: IFileRequest = {\r\n        onCompleteObservable: new Observable<IFileRequest>(),\r\n        abort: () => (aborted = true),\r\n    };\r\n\r\n    const requestFile = () => {\r\n        let request: Nullable<WebRequest> = new WebRequest();\r\n        let retryHandle: Nullable<ReturnType<typeof setTimeout>> = null;\r\n        let onReadyStateChange: Nullable<() => void>;\r\n\r\n        const unbindEvents = () => {\r\n            if (!request) {\r\n                return;\r\n            }\r\n\r\n            if (onProgress) {\r\n                request.removeEventListener(\"progress\", onProgress);\r\n            }\r\n            if (onReadyStateChange) {\r\n                request.removeEventListener(\"readystatechange\", onReadyStateChange);\r\n            }\r\n            request.removeEventListener(\"loadend\", onLoadEnd!);\r\n        };\r\n\r\n        let onLoadEnd: Nullable<() => void> = () => {\r\n            unbindEvents();\r\n\r\n            fileRequest.onCompleteObservable.notifyObservers(fileRequest);\r\n            fileRequest.onCompleteObservable.clear();\r\n\r\n            onProgress = undefined;\r\n            onReadyStateChange = null;\r\n            onLoadEnd = null;\r\n            onError = undefined;\r\n            onOpened = undefined;\r\n            onSuccess = undefined;\r\n        };\r\n\r\n        fileRequest.abort = () => {\r\n            aborted = true;\r\n\r\n            if (onLoadEnd) {\r\n                onLoadEnd();\r\n            }\r\n\r\n            if (request && request.readyState !== (XMLHttpRequest.DONE || 4)) {\r\n                request.abort();\r\n            }\r\n\r\n            if (retryHandle !== null) {\r\n                clearTimeout(retryHandle);\r\n                retryHandle = null;\r\n            }\r\n\r\n            request = null;\r\n        };\r\n\r\n        const handleError = (error: any) => {\r\n            const message = error.message || \"Unknown error\";\r\n            if (onError && request) {\r\n                onError(new RequestFileError(message, request));\r\n            } else {\r\n                Logger.Error(message);\r\n            }\r\n        };\r\n\r\n        const retryLoop = (retryIndex: number) => {\r\n            if (!request) {\r\n                return;\r\n            }\r\n            request.open(\"GET\", loadUrl);\r\n\r\n            if (onOpened) {\r\n                try {\r\n                    onOpened(request);\r\n                } catch (e) {\r\n                    handleError(e);\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (useArrayBuffer) {\r\n                request.responseType = \"arraybuffer\";\r\n            }\r\n\r\n            if (onProgress) {\r\n                request.addEventListener(\"progress\", onProgress);\r\n            }\r\n\r\n            if (onLoadEnd) {\r\n                request.addEventListener(\"loadend\", onLoadEnd);\r\n            }\r\n\r\n            onReadyStateChange = () => {\r\n                if (aborted || !request) {\r\n                    return;\r\n                }\r\n\r\n                // In case of undefined state in some browsers.\r\n                if (request.readyState === (XMLHttpRequest.DONE || 4)) {\r\n                    // Some browsers have issues where onreadystatechange can be called multiple times with the same value.\r\n                    if (onReadyStateChange) {\r\n                        request.removeEventListener(\"readystatechange\", onReadyStateChange);\r\n                    }\r\n\r\n                    if ((request.status >= 200 && request.status < 300) || (request.status === 0 && (!IsWindowObjectExist() || IsFileURL()))) {\r\n                        // It's possible for the request to have a success status code but null response if the underlying\r\n                        // underlying HTTP connection was closed prematurely. See _onHttpResponseClose in xhr2.js. In this\r\n                        // case we will throw an exception if we call the onSuccess handler because \"data\" will be null\r\n                        // and that then bypasses the retry strategy.\r\n                        const data = useArrayBuffer ? request.response : request.responseText;\r\n                        if (data !== null) {\r\n                            try {\r\n                                if (onSuccess) {\r\n                                    onSuccess(data, request);\r\n                                }\r\n                            } catch (e) {\r\n                                handleError(e);\r\n                            }\r\n                            return;\r\n                        }\r\n                    }\r\n\r\n                    const retryStrategy = FileToolsOptions.DefaultRetryStrategy;\r\n                    if (retryStrategy) {\r\n                        const waitTime = retryStrategy(loadUrl, request, retryIndex);\r\n                        if (waitTime !== -1) {\r\n                            // Prevent the request from completing for retry.\r\n                            unbindEvents();\r\n\r\n                            request = new WebRequest();\r\n                            retryHandle = setTimeout(() => retryLoop(retryIndex + 1), waitTime);\r\n                            return;\r\n                        }\r\n                    }\r\n\r\n                    const error = new RequestFileError(\"Error status: \" + request.status + \" \" + request.statusText + \" - Unable to load \" + loadUrl, request);\r\n                    if (onError) {\r\n                        onError(error);\r\n                    }\r\n                }\r\n            };\r\n\r\n            request.addEventListener(\"readystatechange\", onReadyStateChange);\r\n\r\n            request.send();\r\n        };\r\n\r\n        retryLoop(0);\r\n    };\r\n\r\n    // Caching all files\r\n    if (offlineProvider && offlineProvider.enableSceneOffline && !url.startsWith(\"blob:\")) {\r\n        const noOfflineSupport = (request?: any) => {\r\n            if (request && request.status > 400) {\r\n                if (onError) {\r\n                    onError(request);\r\n                }\r\n            } else {\r\n                requestFile();\r\n            }\r\n        };\r\n\r\n        const loadFromOfflineSupport = () => {\r\n            // TODO: database needs to support aborting and should return a IFileRequest\r\n\r\n            if (offlineProvider) {\r\n                offlineProvider.loadFile(\r\n                    FileToolsOptions.BaseUrl + url,\r\n                    (data) => {\r\n                        if (!aborted && onSuccess) {\r\n                            onSuccess(data);\r\n                        }\r\n\r\n                        fileRequest.onCompleteObservable.notifyObservers(fileRequest);\r\n                    },\r\n                    onProgress\r\n                        ? (event) => {\r\n                              if (!aborted && onProgress) {\r\n                                  onProgress(event);\r\n                              }\r\n                          }\r\n                        : undefined,\r\n                    noOfflineSupport,\r\n                    useArrayBuffer\r\n                );\r\n            }\r\n        };\r\n\r\n        offlineProvider.open(loadFromOfflineSupport, noOfflineSupport);\r\n    } else {\r\n        requestFile();\r\n    }\r\n\r\n    return fileRequest;\r\n};\r\n\r\n/**\r\n * Reads the mime type from a URL, if available.\r\n * @param url\r\n * @returns\r\n */\r\nexport const GetMimeType = (url: string): string | undefined => {\r\n    const { match, type } = TestBase64DataUrl(url);\r\n    if (match) {\r\n        return type || undefined;\r\n    }\r\n\r\n    const lastDot = url.lastIndexOf(\".\");\r\n    const extension = url.substring(lastDot + 1).toLowerCase();\r\n\r\n    switch (extension) {\r\n        case \"glb\":\r\n            return \"model/gltf-binary\";\r\n        case \"bin\":\r\n            return \"application/octet-stream\";\r\n        case \"gltf\":\r\n            return \"model/gltf+json\";\r\n        case \"jpg\":\r\n        case \"jpeg\":\r\n            return \"image/jpeg\";\r\n        case \"png\":\r\n            return \"image/png\";\r\n        case \"webp\":\r\n            return \"image/webp\";\r\n        case \"ktx\":\r\n            return \"image/ktx\";\r\n        case \"ktx2\":\r\n            return \"image/ktx2\";\r\n        case \"avif\":\r\n            return \"image/avif\";\r\n        default:\r\n            return undefined;\r\n    }\r\n};\r\n\r\n/**\r\n * Checks if the loaded document was accessed via `file:`-Protocol.\r\n * @returns boolean\r\n * @internal\r\n */\r\nexport const IsFileURL = (): boolean => {\r\n    return typeof location !== \"undefined\" && location.protocol === \"file:\";\r\n};\r\n\r\n/**\r\n * Test if the given uri is a valid base64 data url\r\n * @param uri The uri to test\r\n * @returns True if the uri is a base64 data url or false otherwise\r\n * @internal\r\n */\r\nexport const IsBase64DataUrl = (uri: string): boolean => {\r\n    return Base64DataUrlRegEx.test(uri);\r\n};\r\n\r\nexport const TestBase64DataUrl = (uri: string): { match: boolean; type: string } => {\r\n    const results = Base64DataUrlRegEx.exec(uri);\r\n    if (results === null || results.length === 0) {\r\n        return { match: false, type: \"\" };\r\n    } else {\r\n        const type = results[0].replace(\"data:\", \"\").replace(\";base64,\", \"\");\r\n        return { match: true, type };\r\n    }\r\n};\r\n\r\n/**\r\n * Decode the given base64 uri.\r\n * @param uri The uri to decode\r\n * @returns The decoded base64 data.\r\n * @internal\r\n */\r\nexport function DecodeBase64UrlToBinary(uri: string): ArrayBuffer {\r\n    return DecodeBase64ToBinary(uri.split(\",\")[1]);\r\n}\r\n\r\n/**\r\n * Decode the given base64 uri into a UTF-8 encoded string.\r\n * @param uri The uri to decode\r\n * @returns The decoded base64 data.\r\n * @internal\r\n */\r\nexport const DecodeBase64UrlToString = (uri: string): string => {\r\n    return DecodeBase64ToString(uri.split(\",\")[1]);\r\n};\r\n\r\n/**\r\n * This will be executed automatically for UMD and es5.\r\n * If esm dev wants the side effects to execute they will have to run it manually\r\n * Once we build native modules those need to be exported.\r\n * @internal\r\n */\r\n\r\n// deprecated\r\n\r\n/**\r\n * FileTools defined as any.\r\n * This should not be imported or used in future releases or in any module in the framework\r\n * @internal\r\n * @deprecated import the needed function from fileTools.ts\r\n */\r\nexport let FileTools: {\r\n    DecodeBase64UrlToBinary: (uri: string) => ArrayBuffer;\r\n    DecodeBase64UrlToString: (uri: string) => string;\r\n    DefaultRetryStrategy: any;\r\n    BaseUrl: any;\r\n    CorsBehavior: any;\r\n    PreprocessUrl: any;\r\n    IsBase64DataUrl: (uri: string) => boolean;\r\n    IsFileURL: () => boolean;\r\n    LoadFile: (\r\n        fileOrUrl: string | File,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent<EventTarget>) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void,\r\n        onOpened?: (request: WebRequest) => void\r\n    ) => IFileRequest;\r\n    LoadImage: (\r\n        input: string | ArrayBuffer | Blob | ArrayBufferView,\r\n        onLoad: (img: HTMLImageElement | ImageBitmap) => void,\r\n        onError: (message?: string, exception?: any) => void,\r\n        offlineProvider: Nullable<IOfflineProvider>,\r\n        mimeType?: string,\r\n        imageBitmapOptions?: ImageBitmapOptions\r\n    ) => Nullable<HTMLImageElement>;\r\n    ReadFile: (\r\n        file: File,\r\n        onSuccess: (data: any) => void,\r\n        onProgress?: (ev: ProgressEvent<EventTarget>) => any,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: ReadFileError) => void\r\n    ) => IFileRequest;\r\n    RequestFile: (\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, request?: WebRequest) => void,\r\n        onProgress?: (event: ProgressEvent<EventTarget>) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: RequestFileError) => void,\r\n        onOpened?: (request: WebRequest) => void\r\n    ) => IFileRequest;\r\n    SetCorsBehavior: (url: string | string[], element: { crossOrigin: string | null }) => void;\r\n};\r\n/**\r\n * @internal\r\n */\r\nexport const _injectLTSFileTools = (\r\n    DecodeBase64UrlToBinary: (uri: string) => ArrayBuffer,\r\n    DecodeBase64UrlToString: (uri: string) => string,\r\n    FileToolsOptions: { DefaultRetryStrategy: any; BaseUrl: any; CorsBehavior: any; PreprocessUrl: any; CleanUrl: any },\r\n    IsBase64DataUrl: (uri: string) => boolean,\r\n    IsFileURL: () => boolean,\r\n    LoadFile: (\r\n        fileOrUrl: string | File,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent<EventTarget>) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void,\r\n        onOpened?: (request: WebRequest) => void\r\n    ) => IFileRequest,\r\n    LoadImage: (\r\n        input: string | ArrayBuffer | ArrayBufferView | Blob,\r\n        onLoad: (img: HTMLImageElement | ImageBitmap) => void,\r\n        onError: (message?: string, exception?: any) => void,\r\n        offlineProvider: Nullable<IOfflineProvider>,\r\n        mimeType?: string,\r\n        imageBitmapOptions?: ImageBitmapOptions\r\n    ) => Nullable<HTMLImageElement>,\r\n    ReadFile: (\r\n        file: File,\r\n        onSuccess: (data: any) => void,\r\n        onProgress?: (ev: ProgressEvent<EventTarget>) => any,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: ReadFileError) => void\r\n    ) => IFileRequest,\r\n    RequestFile: (\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, request?: WebRequest) => void,\r\n        onProgress?: (event: ProgressEvent<EventTarget>) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: RequestFileError) => void,\r\n        onOpened?: (request: WebRequest) => void\r\n    ) => IFileRequest,\r\n    SetCorsBehavior: (url: string | string[], element: { crossOrigin: string | null }) => void\r\n) => {\r\n    /**\r\n     * Backwards compatibility.\r\n     * @internal\r\n     * @deprecated\r\n     */\r\n    FileTools = {\r\n        DecodeBase64UrlToBinary,\r\n        DecodeBase64UrlToString,\r\n        DefaultRetryStrategy: FileToolsOptions.DefaultRetryStrategy,\r\n        BaseUrl: FileToolsOptions.BaseUrl,\r\n        CorsBehavior: FileToolsOptions.CorsBehavior,\r\n        PreprocessUrl: FileToolsOptions.PreprocessUrl,\r\n        IsBase64DataUrl,\r\n        IsFileURL,\r\n        LoadFile,\r\n        LoadImage,\r\n        ReadFile,\r\n        RequestFile,\r\n        SetCorsBehavior,\r\n    };\r\n\r\n    Object.defineProperty(FileTools, \"DefaultRetryStrategy\", {\r\n        get: function (this: null) {\r\n            return FileToolsOptions.DefaultRetryStrategy;\r\n        },\r\n        set: function (this: null, value: (url: string, request: WebRequest, retryIndex: number) => number) {\r\n            FileToolsOptions.DefaultRetryStrategy = value;\r\n        },\r\n    });\r\n\r\n    Object.defineProperty(FileTools, \"BaseUrl\", {\r\n        get: function (this: null) {\r\n            return FileToolsOptions.BaseUrl;\r\n        },\r\n        set: function (this: null, value: string) {\r\n            FileToolsOptions.BaseUrl = value;\r\n        },\r\n    });\r\n\r\n    Object.defineProperty(FileTools, \"PreprocessUrl\", {\r\n        get: function (this: null) {\r\n            return FileToolsOptions.PreprocessUrl;\r\n        },\r\n        set: function (this: null, value: (url: string) => string) {\r\n            FileToolsOptions.PreprocessUrl = value;\r\n        },\r\n    });\r\n\r\n    Object.defineProperty(FileTools, \"CorsBehavior\", {\r\n        get: function (this: null) {\r\n            return FileToolsOptions.CorsBehavior;\r\n        },\r\n        set: function (this: null, value: string | ((url: string | string[]) => string)) {\r\n            FileToolsOptions.CorsBehavior = value;\r\n        },\r\n    });\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fileTools.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFileTools(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    _injectLTSFileTools(\r\n        DecodeBase64UrlToBinary,\r\n        DecodeBase64UrlToString,\r\n        FileToolsOptions,\r\n        IsBase64DataUrl,\r\n        IsFileURL,\r\n        LoadFile,\r\n        LoadImage,\r\n        ReadFile,\r\n        RequestFile,\r\n        SetCorsBehavior\r\n    );\r\n\r\n    // Register the file/image loaders on the engine injection seam so the\r\n    // always-loaded engine classes can load files/images without importing\r\n    // fileTools directly (which would defeat tree-shaking).\r\n    EngineFunctionContext.loadFile = LoadFile;\r\n    EngineFunctionContext.loadImage = LoadImage;\r\n    _FunctionContainer.loadFile = LoadFile;\r\n}\r\n","import { Logger } from \"./logger\";\r\nimport { GetClass } from \"./typeStore\";\r\n\r\n/**\r\n * Class used to enable instantiation of objects by class name\r\n */\r\nexport class InstantiationTools {\r\n    /**\r\n     * Use this object to register external classes like custom textures or material\r\n     * to allow the loaders to instantiate them\r\n     */\r\n    public static RegisteredExternalClasses: { [key: string]: object } = {};\r\n\r\n    /**\r\n     * Tries to instantiate a new object from a given class name\r\n     * @param className defines the class name to instantiate\r\n     * @returns the new object or null if the system was not able to do the instantiation\r\n     */\r\n    public static Instantiate(className: string): any {\r\n        if (this.RegisteredExternalClasses && this.RegisteredExternalClasses[className]) {\r\n            return this.RegisteredExternalClasses[className];\r\n        }\r\n\r\n        const internalClass = GetClass(className);\r\n        if (internalClass) {\r\n            return internalClass;\r\n        }\r\n\r\n        Logger.Warn(className + \" not found, you may have missed an import.\");\r\n\r\n        const arr = className.split(\".\");\r\n\r\n        let fn: any = typeof window !== \"undefined\" ? window : typeof globalThis !== \"undefined\" ? globalThis : this;\r\n        for (let i = 0, len = arr.length; i < len; i++) {\r\n            fn = fn[arr[i]];\r\n        }\r\n\r\n        if (typeof fn !== \"function\") {\r\n            return null;\r\n        }\r\n\r\n        return fn;\r\n    }\r\n}\r\n","/**\r\n * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523\r\n * Be aware Math.random() could cause collisions, but:\r\n * \"All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide\"\r\n * @returns a pseudo random id\r\n */\r\nexport function RandomGUID(): string {\r\n    return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\r\n        const r = (Math.random() * 16) | 0,\r\n            v = c === \"x\" ? r : (r & 0x3) | 0x8;\r\n        return v.toString(16);\r\n    });\r\n}\r\n/**\r\n * Class used to manipulate GUIDs\r\n */\r\nexport const GUID = {\r\n    /**\r\n     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523\r\n     * Be aware Math.random() could cause collisions, but:\r\n     * \"All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide\"\r\n     * @returns a pseudo random id\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    RandomId: RandomGUID,\r\n};\r\n","import { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * Function indicating if a number is an exponent of 2\r\n * @param value defines the value to test\r\n * @returns true if the value is an exponent of 2\r\n */\r\nexport function IsExponentOfTwo(value: number): boolean {\r\n    let count = 1;\r\n\r\n    do {\r\n        count *= 2;\r\n    } while (count < value);\r\n\r\n    return count === value;\r\n}\r\n\r\n/**\r\n * Interpolates between a and b via alpha\r\n * @param a The lower value (returned when alpha = 0)\r\n * @param b The upper value (returned when alpha = 1)\r\n * @param alpha The interpolation-factor\r\n * @returns The mixed value\r\n */\r\nexport function Mix(a: number, b: number, alpha: number): number {\r\n    return a * (1 - alpha) + b * alpha;\r\n}\r\n\r\n/**\r\n * Find the nearest power of two.\r\n * @param x Number to start search from.\r\n * @returns Next nearest power of two.\r\n */\r\nexport function NearestPOT(x: number): number {\r\n    const c = CeilingPOT(x);\r\n    const f = FloorPOT(x);\r\n    return c - x > x - f ? f : c;\r\n}\r\n\r\n/**\r\n * Find the next highest power of two.\r\n * @param x Number to start search from.\r\n * @returns Next highest power of two.\r\n */\r\nexport function CeilingPOT(x: number): number {\r\n    x--;\r\n    x |= x >> 1;\r\n    x |= x >> 2;\r\n    x |= x >> 4;\r\n    x |= x >> 8;\r\n    x |= x >> 16;\r\n    x++;\r\n    return x;\r\n}\r\n\r\n/**\r\n * Find the next lowest power of two.\r\n * @param x Number to start search from.\r\n * @returns Next lowest power of two.\r\n */\r\nexport function FloorPOT(x: number): number {\r\n    x = x | (x >> 1);\r\n    x = x | (x >> 2);\r\n    x = x | (x >> 4);\r\n    x = x | (x >> 8);\r\n    x = x | (x >> 16);\r\n    return x - (x >> 1);\r\n}\r\n\r\n/**\r\n * Get the closest exponent of two\r\n * @param value defines the value to approximate\r\n * @param max defines the maximum value to return\r\n * @param mode defines how to define the closest value\r\n * @returns closest exponent of two of the given value\r\n */\r\nexport function GetExponentOfTwo(value: number, max: number, mode = Constants.SCALEMODE_NEAREST): number {\r\n    let pot;\r\n\r\n    switch (mode) {\r\n        case Constants.SCALEMODE_FLOOR:\r\n            pot = FloorPOT(value);\r\n            break;\r\n        case Constants.SCALEMODE_NEAREST:\r\n            pot = NearestPOT(value);\r\n            break;\r\n        case Constants.SCALEMODE_CEILING:\r\n        default:\r\n            pot = CeilingPOT(value);\r\n            break;\r\n    }\r\n\r\n    return Math.min(pot, max);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Observable } from \"./observable.pure\";\r\nimport { GetDOMTextContent, IsNavigatorAvailable, IsWindowObjectExist } from \"./domManagement\";\r\nimport { Logger } from \"./logger\";\r\nimport { DeepCopier } from \"./deepCopier\";\r\nimport { PrecisionDate } from \"./precisionDate\";\r\nimport { _WarnImport } from \"./devTools\";\r\nimport { WebRequest } from \"./webRequest\";\r\nimport { type IFileRequest } from \"./fileRequest\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport {\r\n    FileToolsOptions,\r\n    DecodeBase64UrlToBinary,\r\n    IsBase64DataUrl,\r\n    LoadFile as FileToolsLoadFile,\r\n    LoadImage as FileToolLoadImage,\r\n    ReadFile as FileToolsReadFile,\r\n    SetCorsBehavior,\r\n} from \"./fileTools.pure\";\r\nimport { type ReadFileError } from \"./fileTools\";\r\nimport { type IOfflineProvider } from \"../Offline/IOfflineProvider\";\r\nimport { TimingTools } from \"./timingTools\";\r\nimport { InstantiationTools } from \"./instantiationTools\";\r\nimport { RandomGUID } from \"./guid\";\r\nimport { type IScreenshotSize } from \"./interfaces/screenshotSize\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type IColor4Like } from \"../Maths/math.like\";\r\nimport { IsExponentOfTwo, Mix } from \"./tools.functions\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture.pure\";\r\nimport { NativeTraceLevel, type INative } from \"../Engines/Native/nativeInterfaces\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const _native: INative;\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare function importScripts(...urls: string[]): void;\r\n\r\n/**\r\n * Class containing a set of static utilities functions\r\n */\r\nexport class Tools {\r\n    /**\r\n     * Gets or sets the base URL to use to load assets\r\n     */\r\n    public static get BaseUrl() {\r\n        return FileToolsOptions.BaseUrl;\r\n    }\r\n\r\n    public static set BaseUrl(value: string) {\r\n        FileToolsOptions.BaseUrl = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the clean URL function to use to load assets\r\n     */\r\n    public static get CleanUrl() {\r\n        return FileToolsOptions.CleanUrl;\r\n    }\r\n\r\n    public static set CleanUrl(value: (url: string) => string) {\r\n        FileToolsOptions.CleanUrl = value;\r\n    }\r\n\r\n    /**\r\n     * This function checks whether a URL is absolute or not.\r\n     * It will also detect data and blob URLs\r\n     * @param url the url to check\r\n     * @returns is the url absolute or relative\r\n     */\r\n    public static IsAbsoluteUrl(url: string): boolean {\r\n        // See https://stackoverflow.com/a/38979205.\r\n\r\n        // URL is protocol-relative (= absolute)\r\n        if (url.indexOf(\"//\") === 0) {\r\n            return true;\r\n        }\r\n\r\n        // URL has no protocol (= relative)\r\n        if (url.indexOf(\"://\") === -1) {\r\n            return false;\r\n        }\r\n\r\n        // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)\r\n        if (url.indexOf(\".\") === -1) {\r\n            return false;\r\n        }\r\n\r\n        // URL does not contain a single slash (= relative)\r\n        if (url.indexOf(\"/\") === -1) {\r\n            return false;\r\n        }\r\n\r\n        // The first colon comes after the first slash (= relative)\r\n        if (url.indexOf(\":\") > url.indexOf(\"/\")) {\r\n            return false;\r\n        }\r\n\r\n        // Protocol is defined before first dot (= absolute)\r\n        if (url.indexOf(\"://\") < url.indexOf(\".\")) {\r\n            return true;\r\n        }\r\n        if (url.indexOf(\"data:\") === 0 || url.indexOf(\"blob:\") === 0) {\r\n            return true;\r\n        }\r\n\r\n        // Anything else must be relative\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Sets the base URL to use to load scripts\r\n     */\r\n    public static set ScriptBaseUrl(value: string) {\r\n        FileToolsOptions.ScriptBaseUrl = value;\r\n    }\r\n\r\n    public static get ScriptBaseUrl(): string {\r\n        return FileToolsOptions.ScriptBaseUrl;\r\n    }\r\n\r\n    /**\r\n     * The base URL to use to load assets. If empty the default base url is used.\r\n     */\r\n    public static AssetBaseUrl = \"\";\r\n\r\n    /**\r\n     * Sets both the script base URL and the assets base URL to the same value.\r\n     * Setter only!\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static set CDNBaseUrl(value: string) {\r\n        Tools.ScriptBaseUrl = value;\r\n        Tools.AssetBaseUrl = value;\r\n    }\r\n\r\n    /**\r\n     * Sets a preprocessing function to run on a source URL before importing it\r\n     * Note that this function will execute AFTER the base URL is appended to the URL\r\n     */\r\n    public static set ScriptPreprocessUrl(func: (source: string) => string) {\r\n        FileToolsOptions.ScriptPreprocessUrl = func;\r\n    }\r\n\r\n    public static get ScriptPreprocessUrl(): (source: string) => string {\r\n        return FileToolsOptions.ScriptPreprocessUrl;\r\n    }\r\n\r\n    /**\r\n     * Enable/Disable Custom HTTP Request Headers globally.\r\n     * default = false\r\n     * @see CustomRequestHeaders\r\n     */\r\n    public static UseCustomRequestHeaders = false;\r\n\r\n    /**\r\n     * Custom HTTP Request Headers to be sent with XMLHttpRequests\r\n     * i.e. when loading files, where the server/service expects an Authorization header\r\n     */\r\n    public static CustomRequestHeaders = WebRequest.CustomRequestHeaders;\r\n\r\n    /**\r\n     * Gets or sets the retry strategy to apply when an error happens while loading an asset\r\n     */\r\n    public static get DefaultRetryStrategy() {\r\n        return FileToolsOptions.DefaultRetryStrategy;\r\n    }\r\n\r\n    public static set DefaultRetryStrategy(strategy: (url: string, request: WebRequest, retryIndex: number) => number) {\r\n        FileToolsOptions.DefaultRetryStrategy = strategy;\r\n    }\r\n\r\n    /**\r\n     * Default behavior for cors in the application.\r\n     * It can be a string if the expected behavior is identical in the entire app.\r\n     * Or a callback to be able to set it per url or on a group of them (in case of Video source for instance)\r\n     */\r\n    public static get CorsBehavior(): string | ((url: string | string[]) => string) {\r\n        return FileToolsOptions.CorsBehavior;\r\n    }\r\n\r\n    public static set CorsBehavior(value: string | ((url: string | string[]) => string)) {\r\n        FileToolsOptions.CorsBehavior = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a global variable indicating if fallback texture must be used when a texture cannot be loaded\r\n     * @ignorenaming\r\n     */\r\n    public static get UseFallbackTexture() {\r\n        return EngineStore.UseFallbackTexture;\r\n    }\r\n\r\n    public static set UseFallbackTexture(value: boolean) {\r\n        EngineStore.UseFallbackTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Use this object to register external classes like custom textures or material\r\n     * to allow the loaders to instantiate them\r\n     */\r\n    public static get RegisteredExternalClasses() {\r\n        return InstantiationTools.RegisteredExternalClasses;\r\n    }\r\n\r\n    public static set RegisteredExternalClasses(classes: { [key: string]: object }) {\r\n        InstantiationTools.RegisteredExternalClasses = classes;\r\n    }\r\n\r\n    /**\r\n     * Texture content used if a texture cannot loaded\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static get fallbackTexture() {\r\n        return EngineStore.FallbackTexture;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static set fallbackTexture(value: string) {\r\n        EngineStore.FallbackTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Read the content of a byte array at a specified coordinates (taking in account wrapping)\r\n     * @param u defines the coordinate on X axis\r\n     * @param v defines the coordinate on Y axis\r\n     * @param width defines the width of the source data\r\n     * @param height defines the height of the source data\r\n     * @param pixels defines the source byte array\r\n     * @param color defines the output color\r\n     */\r\n    public static FetchToRef(u: number, v: number, width: number, height: number, pixels: Uint8Array, color: IColor4Like): void {\r\n        const wrappedU = ((Math.abs(u) * width) % width) | 0;\r\n        const wrappedV = ((Math.abs(v) * height) % height) | 0;\r\n\r\n        const position = (wrappedU + wrappedV * width) * 4;\r\n        color.r = pixels[position] / 255;\r\n        color.g = pixels[position + 1] / 255;\r\n        color.b = pixels[position + 2] / 255;\r\n        color.a = pixels[position + 3] / 255;\r\n    }\r\n\r\n    /**\r\n     * Interpolates between a and b via alpha\r\n     * @param a The lower value (returned when alpha = 0)\r\n     * @param b The upper value (returned when alpha = 1)\r\n     * @param alpha The interpolation-factor\r\n     * @returns The mixed value\r\n     */\r\n    public static Mix(a: number, b: number, alpha: number): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Tries to instantiate a new object from a given class name\r\n     * @param className defines the class name to instantiate\r\n     * @returns the new object or null if the system was not able to do the instantiation\r\n     */\r\n    public static Instantiate(className: string): any {\r\n        return InstantiationTools.Instantiate(className);\r\n    }\r\n\r\n    /**\r\n     * Polyfill for setImmediate\r\n     * @param action defines the action to execute after the current execution block\r\n     */\r\n    public static SetImmediate(action: () => void) {\r\n        TimingTools.SetImmediate(action);\r\n    }\r\n\r\n    /**\r\n     * Function indicating if a number is an exponent of 2\r\n     * @param value defines the value to test\r\n     * @returns true if the value is an exponent of 2\r\n     */\r\n    public static IsExponentOfTwo(value: number): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns the nearest 32-bit single precision float representation of a Number\r\n     * @param value A Number.  If the parameter is of a different type, it will get converted\r\n     * to a number or to NaN if it cannot be converted\r\n     * @returns number\r\n     */\r\n    public static FloatRound(value: number): number {\r\n        return Math.fround(value);\r\n    }\r\n\r\n    /**\r\n     * Extracts the filename from a path\r\n     * @param path defines the path to use\r\n     * @returns the filename\r\n     */\r\n    public static GetFilename(path: string): string {\r\n        const index = path.lastIndexOf(\"/\");\r\n        if (index < 0) {\r\n            return path;\r\n        }\r\n\r\n        return path.substring(index + 1);\r\n    }\r\n\r\n    /**\r\n     * Extracts the \"folder\" part of a path (everything before the filename).\r\n     * @param uri The URI to extract the info from\r\n     * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present\r\n     * @returns The \"folder\" part of the path\r\n     */\r\n    public static GetFolderPath(uri: string, returnUnchangedIfNoSlash = false): string {\r\n        const index = uri.lastIndexOf(\"/\");\r\n        if (index < 0) {\r\n            if (returnUnchangedIfNoSlash) {\r\n                return uri;\r\n            }\r\n            return \"\";\r\n        }\r\n\r\n        return uri.substring(0, index + 1);\r\n    }\r\n\r\n    /**\r\n     * Extracts text content from a DOM element hierarchy\r\n     * Back Compat only, please use GetDOMTextContent instead.\r\n     */\r\n    public static GetDOMTextContent = GetDOMTextContent;\r\n\r\n    /**\r\n     * Convert an angle in radians to degrees\r\n     * @param angle defines the angle to convert\r\n     * @returns the angle in degrees\r\n     */\r\n    public static ToDegrees(angle: number): number {\r\n        return (angle * 180) / Math.PI;\r\n    }\r\n\r\n    /**\r\n     * Convert an angle in degrees to radians\r\n     * @param angle defines the angle to convert\r\n     * @returns the angle in radians\r\n     */\r\n    public static ToRadians(angle: number): number {\r\n        return (angle * Math.PI) / 180;\r\n    }\r\n\r\n    /**\r\n     * Smooth angle changes (kind of low-pass filter), in particular for device orientation \"shaking\"\r\n     * Use trigonometric functions to avoid discontinuity (0/360, -180/180)\r\n     * @param previousAngle defines last angle value, in degrees\r\n     * @param newAngle defines new angle value, in degrees\r\n     * @param smoothFactor defines smoothing sensitivity; min 0: no smoothing, max 1: new data ignored\r\n     * @returns the angle in degrees\r\n     */\r\n    public static SmoothAngleChange(previousAngle: number, newAngle: number, smoothFactor = 0.9): number {\r\n        const previousAngleRad = this.ToRadians(previousAngle);\r\n        const newAngleRad = this.ToRadians(newAngle);\r\n        return this.ToDegrees(\r\n            Math.atan2(\r\n                (1 - smoothFactor) * Math.sin(newAngleRad) + smoothFactor * Math.sin(previousAngleRad),\r\n                (1 - smoothFactor) * Math.cos(newAngleRad) + smoothFactor * Math.cos(previousAngleRad)\r\n            )\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Returns an array if obj is not an array\r\n     * @param obj defines the object to evaluate as an array\r\n     * @param allowsNullUndefined defines a boolean indicating if obj is allowed to be null or undefined\r\n     * @returns either obj directly if obj is an array or a new array containing obj\r\n     */\r\n    public static MakeArray(obj: any, allowsNullUndefined?: boolean): Nullable<Array<any>> {\r\n        if (allowsNullUndefined !== true && (obj === undefined || obj == null)) {\r\n            return null;\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\r\n        return Array.isArray(obj) ? obj : [obj];\r\n    }\r\n\r\n    /**\r\n     * Gets the pointer prefix to use\r\n     * @param engine defines the engine we are finding the prefix for\r\n     * @returns \"pointer\" if touch is enabled. Else returns \"mouse\"\r\n     */\r\n    public static GetPointerPrefix(engine: AbstractEngine): string {\r\n        return IsWindowObjectExist() && !window.PointerEvent ? \"mouse\" : \"pointer\";\r\n    }\r\n\r\n    /**\r\n     * Sets the cors behavior on a dom element. This will add the required Tools.CorsBehavior to the element.\r\n     * @param url define the url we are trying\r\n     * @param element define the dom element where to configure the cors policy\r\n     * @param element.crossOrigin\r\n     */\r\n    public static SetCorsBehavior(url: string | string[], element: { crossOrigin: string | null }): void {\r\n        SetCorsBehavior(url, element);\r\n    }\r\n\r\n    /**\r\n     * Sets the referrerPolicy behavior on a dom element.\r\n     * @param referrerPolicy define the referrer policy to use\r\n     * @param element define the dom element where to configure the referrer policy\r\n     * @param element.referrerPolicy\r\n     */\r\n    public static SetReferrerPolicyBehavior(referrerPolicy: Nullable<ReferrerPolicy>, element: { referrerPolicy: string | null }): void {\r\n        element.referrerPolicy = referrerPolicy;\r\n    }\r\n\r\n    // External files\r\n\r\n    /**\r\n     * Gets or sets a function used to pre-process url before using them to load assets\r\n     */\r\n    public static get PreprocessUrl() {\r\n        return FileToolsOptions.PreprocessUrl;\r\n    }\r\n\r\n    public static set PreprocessUrl(processor: (url: string) => string) {\r\n        FileToolsOptions.PreprocessUrl = processor;\r\n    }\r\n\r\n    /**\r\n     * Loads an image as an HTMLImageElement.\r\n     * @param input url string, ArrayBuffer, or Blob to load\r\n     * @param onLoad callback called when the image successfully loads\r\n     * @param onError callback called when the image fails to load\r\n     * @param offlineProvider offline provider for caching\r\n     * @param mimeType optional mime type\r\n     * @param imageBitmapOptions optional the options to use when creating an ImageBitmap\r\n     * @returns the HTMLImageElement of the loaded image\r\n     */\r\n    public static LoadImage(\r\n        input: string | ArrayBuffer | Blob,\r\n        onLoad: (img: HTMLImageElement | ImageBitmap) => void,\r\n        onError: (message?: string, exception?: any) => void,\r\n        offlineProvider: Nullable<IOfflineProvider>,\r\n        mimeType?: string,\r\n        imageBitmapOptions?: ImageBitmapOptions\r\n    ): Nullable<HTMLImageElement> {\r\n        return FileToolLoadImage(input, onLoad, onError, offlineProvider, mimeType, imageBitmapOptions);\r\n    }\r\n\r\n    /**\r\n     * Loads a file from a url\r\n     * @param url url string, ArrayBuffer, or Blob to load\r\n     * @param onSuccess callback called when the file successfully loads\r\n     * @param onProgress callback called while file is loading (if the server supports this mode)\r\n     * @param offlineProvider defines the offline provider for caching\r\n     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer\r\n     * @param onError callback called when the file fails to load\r\n     * @returns a file request object\r\n     */\r\n    public static LoadFile(\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (data: any) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: any) => void\r\n    ): IFileRequest {\r\n        return FileToolsLoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);\r\n    }\r\n\r\n    // Note that this must come first since useArrayBuffer defaults to true below.\r\n    public static async LoadFileAsync(url: string, useArrayBuffer?: true): Promise<ArrayBuffer>;\r\n    public static async LoadFileAsync(url: string, useArrayBuffer?: false): Promise<string>;\r\n\r\n    /**\r\n     * Loads a file from a url\r\n     * @param url the file url to load\r\n     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer\r\n     * @returns a promise containing an ArrayBuffer corresponding to the loaded file\r\n     */\r\n    public static async LoadFileAsync(url: string, useArrayBuffer = true): Promise<ArrayBuffer | string> {\r\n        return await new Promise((resolve, reject) => {\r\n            FileToolsLoadFile(\r\n                url,\r\n                (data) => {\r\n                    resolve(data);\r\n                },\r\n                undefined,\r\n                undefined,\r\n                useArrayBuffer,\r\n                (request, exception) => {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(exception);\r\n                }\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static readonly _DefaultCdnUrl = \"https://cdn.babylonjs.com\";\r\n\r\n    /**\r\n     * The CDN version to use when constructing versioned CDN URLs.\r\n     * Injected at build time by the version update script.\r\n     * When set, unversioned CDN URLs will be rewritten to include this version prefix.\r\n     * @internal\r\n     */\r\n    public static _CdnVersion = \"9.28.0\";\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static readonly _DefaultAssetsUrl = \"https://assets.babylonjs.com/core\";\r\n\r\n    /**\r\n     * This function will convert asset URLs if the AssetBaseUrl parameter is set.\r\n     * Any URL with `assets.babylonjs.com/core` will be replaced with the value of AssetBaseUrl.\r\n     * @param url the URL to convert\r\n     * @returns a new URL\r\n     */\r\n    public static GetAssetUrl(url: string): string {\r\n        if (!url) {\r\n            return \"\";\r\n        }\r\n\r\n        if (Tools.AssetBaseUrl && url.startsWith(Tools._DefaultAssetsUrl)) {\r\n            // normalize the baseUrl\r\n            const baseUrl = Tools.AssetBaseUrl.endsWith(\"/\") ? Tools.AssetBaseUrl.slice(0, -1) : Tools.AssetBaseUrl;\r\n            return url.replace(Tools._DefaultAssetsUrl, baseUrl);\r\n        }\r\n\r\n        return url;\r\n    }\r\n\r\n    /**\r\n     * Get a script URL including preprocessing\r\n     * @param scriptUrl the script Url to process\r\n     * @param forceAbsoluteUrl force the script to be an absolute url (adding the current base url if necessary)\r\n     * @returns a modified URL to use\r\n     */\r\n    public static GetBabylonScriptURL(scriptUrl: Nullable<string>, forceAbsoluteUrl?: boolean): string {\r\n        if (!scriptUrl) {\r\n            return \"\";\r\n        }\r\n        if (scriptUrl.startsWith(Tools._DefaultCdnUrl)) {\r\n            if (Tools.ScriptBaseUrl) {\r\n                // if the base URL was set, and the script Url is an absolute path change the default path\r\n                // change the default host, which is https://cdn.babylonjs.com with the one defined\r\n                // make sure no trailing slash is present\r\n                const baseUrl = Tools.ScriptBaseUrl.endsWith(\"/\") ? Tools.ScriptBaseUrl.slice(0, -1) : Tools.ScriptBaseUrl;\r\n                scriptUrl = scriptUrl.replace(Tools._DefaultCdnUrl, baseUrl);\r\n            } else if (Tools._CdnVersion) {\r\n                // If a CDN version is set (injected at build time), rewrite unversioned CDN URLs to versioned ones\r\n                const versionedBase = `${Tools._DefaultCdnUrl}/v${Tools._CdnVersion}`;\r\n                // Guard against double-versioning if the URL already contains the version prefix\r\n                // (e.g. when GetBabylonScriptURL is called multiple times on the same URL)\r\n                if (!scriptUrl.startsWith(versionedBase)) {\r\n                    scriptUrl = scriptUrl.replace(Tools._DefaultCdnUrl, versionedBase);\r\n                }\r\n            }\r\n        }\r\n\r\n        // run the preprocessor\r\n        scriptUrl = Tools.ScriptPreprocessUrl(scriptUrl);\r\n\r\n        if (forceAbsoluteUrl && !Tools.IsAbsoluteUrl(scriptUrl)) {\r\n            scriptUrl = Tools.GetAbsoluteUrl(scriptUrl);\r\n        }\r\n\r\n        return scriptUrl;\r\n    }\r\n\r\n    /**\r\n     * This function is used internally by babylon components to load a script (identified by an url). When the url returns, the\r\n     * content of this file is added into a new script element, attached to the DOM (body element)\r\n     * @param scriptUrl defines the url of the script to load\r\n     * @param onSuccess defines the callback called when the script is loaded\r\n     * @param onError defines the callback to call if an error occurs\r\n     * @param scriptId defines the id of the script element\r\n     */\r\n    public static LoadBabylonScript(scriptUrl: string, onSuccess: () => void, onError?: (message?: string, exception?: any) => void, scriptId?: string) {\r\n        scriptUrl = Tools.GetBabylonScriptURL(scriptUrl);\r\n        Tools.LoadScript(scriptUrl, onSuccess, onError);\r\n    }\r\n\r\n    /**\r\n     * Load an asynchronous script (identified by an url). When the url returns, the\r\n     * content of this file is added into a new script element, attached to the DOM (body element)\r\n     * @param scriptUrl defines the url of the script to laod\r\n     * @returns a promise request object\r\n     */\r\n    public static async LoadBabylonScriptAsync(scriptUrl: string): Promise<void> {\r\n        scriptUrl = Tools.GetBabylonScriptURL(scriptUrl);\r\n        return await Tools.LoadScriptAsync(scriptUrl);\r\n    }\r\n\r\n    private static _LoadScriptNative(scriptUrl: string, onSuccess?: () => void, onError?: (message?: string, exception?: any) => void, _scriptId?: string, useModule = false) {\r\n        if (_native) {\r\n            if (useModule) {\r\n                // When useModule is set, scriptUrl is not a url at all: it is ES module\r\n                // source code that the web implementation injects into a\r\n                // <script type=\"module\"> element (see _LoadScriptWeb). Babylon Native has\r\n                // no DOM and no ES module loader, so there is nothing to inject it into.\r\n                // Without this guard the module source was handed to Tools.LoadFile as if\r\n                // it were a url, producing confusing \"Unable to open URL\" failures that\r\n                // quoted the module source back instead of naming a url.\r\n                const message = \"Loading a script as an ES module is not supported in Babylon Native\";\r\n                onError?.(message, new Error(message));\r\n                return;\r\n            }\r\n            Tools.LoadFile(\r\n                scriptUrl,\r\n                (data) => {\r\n                    try {\r\n                        Function(data as string).apply(null);\r\n                        if (onSuccess) {\r\n                            onSuccess();\r\n                        }\r\n                    } catch (exception) {\r\n                        if (onError) {\r\n                            onError(\"LoadScript Error\", exception);\r\n                        }\r\n                    }\r\n                },\r\n                undefined,\r\n                undefined,\r\n                false,\r\n                (_request, exception) => {\r\n                    if (onError) {\r\n                        onError(\"LoadScript Error\", exception);\r\n                    }\r\n                }\r\n            );\r\n        }\r\n    }\r\n\r\n    private static _LoadScriptWeb(scriptUrl: string, onSuccess?: () => void, onError?: (message?: string, exception?: any) => void, scriptId?: string, useModule = false) {\r\n        if (typeof importScripts === \"function\") {\r\n            try {\r\n                importScripts(scriptUrl);\r\n                if (onSuccess) {\r\n                    onSuccess();\r\n                }\r\n            } catch (e) {\r\n                onError?.(`Unable to load script '${scriptUrl}' in worker`, e);\r\n            }\r\n            return;\r\n        } else if (!IsWindowObjectExist()) {\r\n            onError?.(`Cannot load script '${scriptUrl}' outside of a window or a worker`);\r\n            return;\r\n        }\r\n        const head = document.getElementsByTagName(\"head\")[0];\r\n        const script = document.createElement(\"script\");\r\n        if (useModule) {\r\n            script.setAttribute(\"type\", \"module\");\r\n            script.innerText = scriptUrl;\r\n        } else {\r\n            script.setAttribute(\"type\", \"text/javascript\");\r\n            script.setAttribute(\"src\", scriptUrl);\r\n        }\r\n        if (scriptId) {\r\n            script.id = scriptId;\r\n        }\r\n\r\n        script.onload = () => {\r\n            if (onSuccess) {\r\n                onSuccess();\r\n            }\r\n        };\r\n\r\n        script.onerror = (e) => {\r\n            if (onError) {\r\n                onError(`Unable to load script '${scriptUrl}'`, e);\r\n            }\r\n        };\r\n\r\n        head.appendChild(script);\r\n    }\r\n\r\n    /**\r\n     * This function is used internally by babylon components to load a script (identified by an url). When the url returns, the\r\n     * content of this file is added into a new script element, attached to the DOM (body element)\r\n     * @param scriptUrl defines the url of the script to load\r\n     * @param onSuccess defines the callback called when the script is loaded\r\n     * @param onError defines the callback to call if an error occurs\r\n     * @param scriptId defines the id of the script element\r\n     * @param useModule defines if we should use the module strategy to load the script\r\n     */\r\n    public static LoadScript: (scriptUrl: string, onSuccess?: () => void, onError?: (message?: string, exception?: any) => void, scriptId?: string, useModule?: boolean) => void =\r\n        typeof _native === \"undefined\" ? this._LoadScriptWeb : this._LoadScriptNative;\r\n\r\n    /**\r\n     * Load an asynchronous script (identified by an url). When the url returns, the\r\n     * content of this file is added into a new script element, attached to the DOM (body element)\r\n     * @param scriptUrl defines the url of the script to load\r\n     * @param scriptId defines the id of the script element\r\n     * @returns a promise request object\r\n     */\r\n    public static async LoadScriptAsync(scriptUrl: string, scriptId?: string): Promise<void> {\r\n        return await new Promise((resolve, reject) => {\r\n            this.LoadScript(\r\n                scriptUrl,\r\n                () => {\r\n                    resolve();\r\n                },\r\n                (message, exception) => {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(exception || new Error(message));\r\n                },\r\n                scriptId\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Loads a file from a blob\r\n     * @param fileToLoad defines the blob to use\r\n     * @param callback defines the callback to call when data is loaded\r\n     * @param progressCallback defines the callback to call during loading process\r\n     * @returns a file request object\r\n     */\r\n    public static ReadFileAsDataURL(fileToLoad: Blob, callback: (data: any) => void, progressCallback: (ev: ProgressEvent) => any): IFileRequest {\r\n        const reader = new FileReader();\r\n\r\n        const request: IFileRequest = {\r\n            onCompleteObservable: new Observable<IFileRequest>(),\r\n            abort: () => reader.abort(),\r\n        };\r\n\r\n        reader.onloadend = () => {\r\n            request.onCompleteObservable.notifyObservers(request);\r\n        };\r\n\r\n        reader.onload = (e) => {\r\n            //target doesn't have result from ts 1.3\r\n            callback((<any>e.target)[\"result\"]);\r\n        };\r\n\r\n        reader.onprogress = progressCallback;\r\n\r\n        reader.readAsDataURL(fileToLoad);\r\n\r\n        return request;\r\n    }\r\n\r\n    /**\r\n     * Reads a file from a File object\r\n     * @param file defines the file to load\r\n     * @param onSuccess defines the callback to call when data is loaded\r\n     * @param onProgress defines the callback to call during loading process\r\n     * @param useArrayBuffer defines a boolean indicating that data must be returned as an ArrayBuffer\r\n     * @param onError defines the callback to call when an error occurs\r\n     * @returns a file request object\r\n     */\r\n    public static ReadFile(\r\n        file: File,\r\n        onSuccess: (data: any) => void,\r\n        onProgress?: (ev: ProgressEvent) => any,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: ReadFileError) => void\r\n    ): IFileRequest {\r\n        return FileToolsReadFile(file, onSuccess, onProgress, useArrayBuffer, onError);\r\n    }\r\n\r\n    /**\r\n     * Creates a data url from a given string content\r\n     * @param content defines the content to convert\r\n     * @returns the new data url link\r\n     */\r\n    public static FileAsURL(content: string): string {\r\n        const fileBlob = new Blob([content]);\r\n        const url = window.URL;\r\n        const link: string = url.createObjectURL(fileBlob);\r\n        return link;\r\n    }\r\n\r\n    /**\r\n     * Format the given number to a specific decimal format\r\n     * @param value defines the number to format\r\n     * @param decimals defines the number of decimals to use\r\n     * @returns the formatted string\r\n     */\r\n    public static Format(value: number, decimals = 2): string {\r\n        return value.toFixed(decimals);\r\n    }\r\n\r\n    /**\r\n     * Tries to copy an object by duplicating every property\r\n     * @param source defines the source object\r\n     * @param destination defines the target object\r\n     * @param doNotCopyList defines a list of properties to avoid\r\n     * @param mustCopyList defines a list of properties to copy (even if they start with _)\r\n     */\r\n    public static DeepCopy(source: any, destination: any, doNotCopyList?: string[], mustCopyList?: string[]): void {\r\n        DeepCopier.DeepCopy(source, destination, doNotCopyList, mustCopyList);\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the given object has no own property\r\n     * @param obj defines the object to test\r\n     * @returns true if object has no own property\r\n     */\r\n    public static IsEmpty(obj: any): boolean {\r\n        for (const i in obj) {\r\n            if (Object.prototype.hasOwnProperty.call(obj, i)) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Function used to register events at window level\r\n     * @param windowElement defines the Window object to use\r\n     * @param events defines the events to register\r\n     */\r\n    public static RegisterTopRootEvents(windowElement: Window, events: { name: string; handler: Nullable<(e: FocusEvent) => any> }[]): void {\r\n        for (let index = 0; index < events.length; index++) {\r\n            const event = events[index];\r\n            windowElement.addEventListener(event.name, <any>event.handler, false);\r\n\r\n            try {\r\n                if (window.parent) {\r\n                    window.parent.addEventListener(event.name, <any>event.handler, false);\r\n                }\r\n            } catch (e) {\r\n                // Silently fails...\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Function used to unregister events from window level\r\n     * @param windowElement defines the Window object to use\r\n     * @param events defines the events to unregister\r\n     */\r\n    public static UnregisterTopRootEvents(windowElement: Window, events: { name: string; handler: Nullable<(e: FocusEvent) => any> }[]): void {\r\n        for (let index = 0; index < events.length; index++) {\r\n            const event = events[index];\r\n            windowElement.removeEventListener(event.name, <any>event.handler);\r\n\r\n            try {\r\n                if (windowElement.parent) {\r\n                    windowElement.parent.removeEventListener(event.name, <any>event.handler);\r\n                }\r\n            } catch (e) {\r\n                // Silently fails...\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dumps the current bound framebuffer\r\n     * @param width defines the rendering width\r\n     * @param height defines the rendering height\r\n     * @param engine defines the hosting engine\r\n     * @param successCallback defines the callback triggered once the data are available\r\n     * @param mimeType defines the mime type of the result\r\n     * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @returns a void promise\r\n     */\r\n    // Should end with Async but this is a breaking change\r\n    // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/require-await, @typescript-eslint/naming-convention\r\n    public static async DumpFramebuffer(\r\n        width: number,\r\n        height: number,\r\n        engine: AbstractEngine,\r\n        successCallback?: (data: string) => void,\r\n        mimeType = \"image/png\",\r\n        fileName?: string,\r\n        quality?: number\r\n    ): Promise<void> {\r\n        throw _WarnImport(\"DumpTools\");\r\n    }\r\n\r\n    /**\r\n     * Dumps an array buffer\r\n     * @param width defines the rendering width\r\n     * @param height defines the rendering height\r\n     * @param data the data array\r\n     * @param successCallback defines the callback triggered once the data are available\r\n     * @param mimeType defines the mime type of the result\r\n     * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n     * @param invertY true to invert the picture in the Y dimension\r\n     * @param toArrayBuffer true to convert the data to an ArrayBuffer (encoded as `mimeType`) instead of a base64 string\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     */\r\n    public static DumpData(\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        successCallback?: (data: string | ArrayBuffer) => void,\r\n        mimeType = \"image/png\",\r\n        fileName?: string,\r\n        invertY = false,\r\n        toArrayBuffer = false,\r\n        quality?: number\r\n    ) {\r\n        throw _WarnImport(\"DumpTools\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Dumps an array buffer\r\n     * @param width defines the rendering width\r\n     * @param height defines the rendering height\r\n     * @param data the data array\r\n     * @param mimeType defines the mime type of the result\r\n     * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n     * @param invertY true to invert the picture in the Y dimension\r\n     * @param toArrayBuffer true to convert the data to an ArrayBuffer (encoded as `mimeType`) instead of a base64 string\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @returns a promise that resolve to the final data\r\n     */\r\n    // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/require-await\r\n    public static async DumpDataAsync(\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        mimeType = \"image/png\",\r\n        fileName?: string,\r\n        invertY = false,\r\n        toArrayBuffer = false,\r\n        quality?: number\r\n    ): Promise<string | ArrayBuffer> {\r\n        throw _WarnImport(\"DumpTools\");\r\n    }\r\n\r\n    private static _IsOffScreenCanvas(canvas: HTMLCanvasElement | OffscreenCanvas): canvas is OffscreenCanvas {\r\n        return (canvas as OffscreenCanvas).convertToBlob !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Converts the canvas data to blob.\r\n     * This acts as a polyfill for browsers not supporting the to blob function.\r\n     * @param canvas Defines the canvas to extract the data from (can be an offscreen canvas)\r\n     * @param successCallback Defines the callback triggered once the data are available\r\n     * @param mimeType Defines the mime type of the result\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     */\r\n    static ToBlob(canvas: HTMLCanvasElement | OffscreenCanvas, successCallback: (blob: Nullable<Blob>) => void, mimeType = \"image/png\", quality?: number): void {\r\n        // We need HTMLCanvasElement.toBlob for HD screenshots\r\n        if (!Tools._IsOffScreenCanvas(canvas) && !canvas.toBlob) {\r\n            //  low performance polyfill based on toDataURL (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob)\r\n            canvas.toBlob = function (callback, type, quality) {\r\n                setTimeout(() => {\r\n                    const binStr = atob(this.toDataURL(type, quality).split(\",\")[1]),\r\n                        len = binStr.length,\r\n                        arr = new Uint8Array(len);\r\n\r\n                    for (let i = 0; i < len; i++) {\r\n                        arr[i] = binStr.charCodeAt(i);\r\n                    }\r\n                    callback(new Blob([arr]));\r\n                });\r\n            };\r\n        }\r\n        if (Tools._IsOffScreenCanvas(canvas)) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            canvas\r\n                .convertToBlob({\r\n                    type: mimeType,\r\n                    quality,\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .then((blob) => successCallback(blob));\r\n        } else {\r\n            canvas.toBlob(\r\n                function (blob) {\r\n                    successCallback(blob);\r\n                },\r\n                mimeType,\r\n                quality\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Download a Blob object\r\n     * @param blob the Blob object\r\n     * @param fileName the file name to download\r\n     */\r\n    static DownloadBlob(blob: Blob, fileName?: string) {\r\n        //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.\r\n        if (\"download\" in document.createElement(\"a\")) {\r\n            if (!fileName) {\r\n                const date = new Date();\r\n                const stringDate =\r\n                    (date.getFullYear() + \"-\" + (date.getMonth() + 1)).slice(2) + \"-\" + date.getDate() + \"_\" + date.getHours() + \"-\" + (\"0\" + date.getMinutes()).slice(-2);\r\n                fileName = \"screenshot_\" + stringDate + \".png\";\r\n            }\r\n            Tools.Download(blob, fileName);\r\n        } else {\r\n            if (blob && typeof URL !== \"undefined\") {\r\n                const url = URL.createObjectURL(blob);\r\n\r\n                const newWindow = window.open(\"\");\r\n                if (!newWindow) {\r\n                    return;\r\n                }\r\n                const img = newWindow.document.createElement(\"img\");\r\n                img.onload = function () {\r\n                    // no longer need to read the blob so it's revoked\r\n                    URL.revokeObjectURL(url);\r\n                };\r\n                img.src = url;\r\n                newWindow.document.body.appendChild(img);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Encodes the canvas data to base 64, or automatically downloads the result if `fileName` is defined.\r\n     * @param canvas The canvas to get the data from, which can be an offscreen canvas.\r\n     * @param successCallback The callback which is triggered once the data is available. If `fileName` is defined, the callback will be invoked after the download occurs, and the `data` argument will be an empty string.\r\n     * @param mimeType The mime type of the result.\r\n     * @param fileName The name of the file to download. If defined, the result will automatically be downloaded. If not defined, and `successCallback` is also not defined, the result will automatically be downloaded with an auto-generated file name.\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     */\r\n    static EncodeScreenshotCanvasData(\r\n        canvas: HTMLCanvasElement | OffscreenCanvas,\r\n        successCallback?: (data: string) => void,\r\n        mimeType = \"image/png\",\r\n        fileName?: string,\r\n        quality?: number\r\n    ): void {\r\n        if (typeof fileName === \"string\" || !successCallback) {\r\n            this.ToBlob(\r\n                canvas,\r\n                function (blob) {\r\n                    if (blob) {\r\n                        Tools.DownloadBlob(blob, fileName);\r\n                    }\r\n                    if (successCallback) {\r\n                        successCallback(\"\");\r\n                    }\r\n                },\r\n                mimeType,\r\n                quality\r\n            );\r\n        } else if (successCallback) {\r\n            if (Tools._IsOffScreenCanvas(canvas)) {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n                canvas\r\n                    .convertToBlob({\r\n                        type: mimeType,\r\n                        quality,\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((blob) => {\r\n                        const reader = new FileReader();\r\n                        reader.readAsDataURL(blob);\r\n                        reader.onloadend = () => {\r\n                            const base64data = reader.result;\r\n                            successCallback(base64data as string);\r\n                        };\r\n                    });\r\n                return;\r\n            }\r\n            const base64Image = canvas.toDataURL(mimeType, quality);\r\n            successCallback(base64Image);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Downloads a blob in the browser\r\n     * @param blob defines the blob to download\r\n     * @param fileName defines the name of the downloaded file\r\n     */\r\n    public static Download(blob: Blob, fileName: string): void {\r\n        if (typeof URL === \"undefined\") {\r\n            return;\r\n        }\r\n\r\n        const url = window.URL.createObjectURL(blob);\r\n        const a = document.createElement(\"a\");\r\n        document.body.appendChild(a);\r\n        a.style.display = \"none\";\r\n        a.href = url;\r\n        a.download = fileName;\r\n        a.addEventListener(\"click\", () => {\r\n            if (a.parentElement) {\r\n                a.parentElement.removeChild(a);\r\n            }\r\n        });\r\n        a.click();\r\n        window.URL.revokeObjectURL(url);\r\n    }\r\n\r\n    /**\r\n     * Will return the right value of the noPreventDefault variable\r\n     * Needed to keep backwards compatibility to the old API.\r\n     *\r\n     * @param args arguments passed to the attachControl function\r\n     * @returns the correct value for noPreventDefault\r\n     */\r\n    public static BackCompatCameraNoPreventDefault(args: IArguments): boolean {\r\n        // is it used correctly?\r\n        if (typeof args[0] === \"boolean\") {\r\n            return args[0];\r\n        } else if (typeof args[1] === \"boolean\") {\r\n            return args[1];\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Captures a screenshot of the current rendering\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine defines the rendering engine\r\n     * @param camera defines the source camera\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param successCallback defines the callback receives a single parameter which contains the\r\n     * screenshot as a string of base64-encoded characters. This string can be assigned to the\r\n     * src parameter of an <img> to display it\r\n     * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param forceDownload force the system to download the image even if a successCallback is provided\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static CreateScreenshot(\r\n        engine: AbstractEngine,\r\n        camera: Camera,\r\n        size: IScreenshotSize | number,\r\n        successCallback?: (data: string) => void,\r\n        mimeType = \"image/png\",\r\n        forceDownload = false,\r\n        quality?: number\r\n    ): void {\r\n        throw _WarnImport(\"ScreenshotTools\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Captures a screenshot of the current rendering\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine defines the rendering engine\r\n     * @param camera defines the source camera\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n     * to the src parameter of an <img> to display it\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-restricted-syntax, @typescript-eslint/require-await\r\n    public static async CreateScreenshotAsync(engine: AbstractEngine, camera: Camera, size: IScreenshotSize | number, mimeType = \"image/png\", quality?: number): Promise<string> {\r\n        throw _WarnImport(\"ScreenshotTools\");\r\n    }\r\n\r\n    /**\r\n     * Generates an image screenshot from the specified camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine The engine to use for rendering\r\n     * @param camera The camera to use for rendering\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param successCallback The callback receives a single parameter which contains the\r\n     * screenshot as a string of base64-encoded characters. This string can be assigned to the\r\n     * src parameter of an <img> to display it\r\n     * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param samples Texture samples (default: 1)\r\n     * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n     * @param fileName A name for for the downloaded file.\r\n     * @param renderSprites Whether the sprites should be rendered or not (default: false)\r\n     * @param enableStencilBuffer Whether the stencil buffer should be enabled or not (default: false)\r\n     * @param useLayerMask if the camera's layer mask should be used to filter what should be rendered (default: true)\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @param customizeTexture An optional callback that can be used to modify the render target texture before taking the screenshot. This can be used, for instance, to enable camera post-processes before taking the screenshot.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static CreateScreenshotUsingRenderTarget(\r\n        engine: AbstractEngine,\r\n        camera: Camera,\r\n        size: IScreenshotSize | number,\r\n        successCallback?: (data: string) => void,\r\n        mimeType = \"image/png\",\r\n        samples = 1,\r\n        antialiasing = false,\r\n        fileName?: string,\r\n        renderSprites = false,\r\n        enableStencilBuffer = false,\r\n        useLayerMask = true,\r\n        quality?: number,\r\n        customizeTexture?: (texture: RenderTargetTexture) => void\r\n    ): void {\r\n        throw _WarnImport(\"ScreenshotTools\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Generates an image screenshot from the specified camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine The engine to use for rendering\r\n     * @param camera The camera to use for rendering\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param samples Texture samples (default: 1)\r\n     * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n     * @param fileName A name for for the downloaded file.\r\n     * @param renderSprites Whether the sprites should be rendered or not (default: false)\r\n     * @param enableStencilBuffer Whether the stencil buffer should be enabled or not (default: false)\r\n     * @param useLayerMask if the camera's layer mask should be used to filter what should be rendered (default: true)\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @param customizeTexture An optional callback that can be used to modify the render target texture before taking the screenshot. This can be used, for instance, to enable camera post-processes before taking the screenshot.\r\n     * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n     * to the src parameter of an <img> to display it\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-restricted-syntax, @typescript-eslint/require-await\r\n    public static async CreateScreenshotUsingRenderTargetAsync(\r\n        engine: AbstractEngine,\r\n        camera: Camera,\r\n        size: IScreenshotSize | number,\r\n        mimeType = \"image/png\",\r\n        samples = 1,\r\n        antialiasing = false,\r\n        fileName?: string,\r\n        renderSprites = false,\r\n        enableStencilBuffer = false,\r\n        useLayerMask = true,\r\n        quality?: number,\r\n        customizeTexture?: (texture: RenderTargetTexture) => void\r\n    ): Promise<string> {\r\n        throw _WarnImport(\"ScreenshotTools\");\r\n    }\r\n\r\n    /**\r\n     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523\r\n     * Be aware Math.random() could cause collisions, but:\r\n     * \"All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide\"\r\n     * @returns a pseudo random id\r\n     */\r\n    public static RandomId(): string {\r\n        return RandomGUID();\r\n    }\r\n\r\n    /**\r\n     * Test if the given uri is a base64 string\r\n     * @deprecated Please use FileTools.IsBase64DataUrl instead.\r\n     * @param uri The uri to test\r\n     * @returns True if the uri is a base64 string or false otherwise\r\n     */\r\n    public static IsBase64(uri: string): boolean {\r\n        return IsBase64DataUrl(uri);\r\n    }\r\n\r\n    /**\r\n     * Decode the given base64 uri.\r\n     * @deprecated Please use FileTools.DecodeBase64UrlToBinary instead.\r\n     * @param uri The uri to decode\r\n     * @returns The decoded base64 data.\r\n     */\r\n    public static DecodeBase64(uri: string): ArrayBuffer {\r\n        return DecodeBase64UrlToBinary(uri);\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check, jsdoc/require-param\r\n    /**\r\n     * @returns the absolute URL of a given (relative) url\r\n     */\r\n    public static GetAbsoluteUrl: (url: string) => string =\r\n        typeof document === \"object\"\r\n            ? (url) => {\r\n                  const a = document.createElement(\"a\");\r\n                  a.href = url;\r\n                  return a.href;\r\n              }\r\n            : typeof URL === \"function\" && typeof location === \"object\"\r\n              ? (url) => new URL(url, location.origin).href\r\n              : () => {\r\n                    throw new Error(\"Unable to get absolute URL. Override BABYLON.Tools.GetAbsoluteUrl to a custom implementation for the current context.\");\r\n                };\r\n\r\n    // Logs\r\n    /**\r\n     * No log\r\n     */\r\n    public static readonly NoneLogLevel = Logger.NoneLogLevel;\r\n    /**\r\n     * Only message logs\r\n     */\r\n    public static readonly MessageLogLevel = Logger.MessageLogLevel;\r\n    /**\r\n     * Only warning logs\r\n     */\r\n    public static readonly WarningLogLevel = Logger.WarningLogLevel;\r\n    /**\r\n     * Only error logs\r\n     */\r\n    public static readonly ErrorLogLevel = Logger.ErrorLogLevel;\r\n    /**\r\n     * All logs\r\n     */\r\n    public static readonly AllLogLevel = Logger.AllLogLevel;\r\n\r\n    /**\r\n     * Gets a value indicating the number of loading errors\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static get errorsCount(): number {\r\n        return Logger.errorsCount;\r\n    }\r\n\r\n    /**\r\n     * Callback called when a new log is added\r\n     */\r\n    public static OnNewCacheEntry: (entry: string) => void;\r\n\r\n    /**\r\n     * Log a message to the console\r\n     * @param message defines the message to log\r\n     */\r\n    public static Log(message: string): void {\r\n        Logger.Log(message);\r\n    }\r\n\r\n    /**\r\n     * Write a warning message to the console\r\n     * @param message defines the message to log\r\n     */\r\n    public static Warn(message: string): void {\r\n        Logger.Warn(message);\r\n    }\r\n\r\n    /**\r\n     * Write an error message to the console\r\n     * @param message defines the message to log\r\n     */\r\n    public static Error(message: string): void {\r\n        Logger.Error(message);\r\n    }\r\n\r\n    /**\r\n     * Gets current log cache (list of logs)\r\n     */\r\n    public static get LogCache(): string {\r\n        return Logger.LogCache;\r\n    }\r\n\r\n    /**\r\n     * Clears the log cache\r\n     */\r\n    public static ClearLogCache(): void {\r\n        Logger.ClearLogCache();\r\n    }\r\n\r\n    /**\r\n     * Sets the current log level (MessageLogLevel / WarningLogLevel / ErrorLogLevel)\r\n     */\r\n    public static set LogLevels(level: number) {\r\n        Logger.LogLevels = level;\r\n    }\r\n\r\n    /**\r\n     * Checks if the window object exists\r\n     * Back Compat only, please use IsWindowObjectExist instead.\r\n     */\r\n    public static IsWindowObjectExist = IsWindowObjectExist;\r\n\r\n    // Performances\r\n\r\n    /**\r\n     * No performance log\r\n     */\r\n    public static readonly PerformanceNoneLogLevel = 0;\r\n    /**\r\n     * Use user marks to log performance\r\n     */\r\n    public static readonly PerformanceUserMarkLogLevel = 1;\r\n    /**\r\n     * Log performance to the console\r\n     */\r\n    public static readonly PerformanceConsoleLogLevel = 2;\r\n\r\n    private static _Performance: Performance;\r\n\r\n    private static readonly _NativePerformanceCounterHandles = /*#__PURE__*/ new Map<string, unknown>();\r\n\r\n    /**\r\n     * Sets the current performance log level\r\n     */\r\n    public static set PerformanceLogLevel(level: number) {\r\n        if ((level & Tools.PerformanceUserMarkLogLevel) === Tools.PerformanceUserMarkLogLevel) {\r\n            if (_native?.enablePerformanceLogging) {\r\n                _native.enablePerformanceLogging(NativeTraceLevel.Mark);\r\n                Tools.StartPerformanceCounter = Tools._StartMarkNative;\r\n                Tools.EndPerformanceCounter = Tools._EndMarkNative;\r\n            } else {\r\n                Tools.StartPerformanceCounter = Tools._StartUserMark;\r\n                Tools.EndPerformanceCounter = Tools._EndUserMark;\r\n            }\r\n            return;\r\n        }\r\n\r\n        if ((level & Tools.PerformanceConsoleLogLevel) === Tools.PerformanceConsoleLogLevel) {\r\n            if (_native?.enablePerformanceLogging) {\r\n                _native.enablePerformanceLogging(NativeTraceLevel.Log);\r\n                Tools.StartPerformanceCounter = Tools._StartMarkNative;\r\n                Tools.EndPerformanceCounter = Tools._EndMarkNative;\r\n            } else {\r\n                Tools.StartPerformanceCounter = Tools._StartPerformanceConsole;\r\n                Tools.EndPerformanceCounter = Tools._EndPerformanceConsole;\r\n            }\r\n            return;\r\n        }\r\n\r\n        Tools.StartPerformanceCounter = Tools._StartPerformanceCounterDisabled;\r\n        Tools.EndPerformanceCounter = Tools._EndPerformanceCounterDisabled;\r\n        _native?.disablePerformanceLogging?.();\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private static _StartPerformanceCounterDisabled(counterName: string, condition?: boolean): void {}\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private static _EndPerformanceCounterDisabled(counterName: string, condition?: boolean): void {}\r\n\r\n    private static _StartUserMark(counterName: string, condition = true): void {\r\n        if (!Tools._Performance) {\r\n            if (!IsWindowObjectExist()) {\r\n                return;\r\n            }\r\n            Tools._Performance = window.performance;\r\n        }\r\n\r\n        if (!condition || !Tools._Performance.mark) {\r\n            return;\r\n        }\r\n        Tools._Performance.mark(counterName + \"-Begin\");\r\n    }\r\n\r\n    private static _EndUserMark(counterName: string, condition = true): void {\r\n        if (!condition || !Tools._Performance.mark) {\r\n            return;\r\n        }\r\n        Tools._Performance.mark(counterName + \"-End\");\r\n        Tools._Performance.measure(counterName, counterName + \"-Begin\", counterName + \"-End\");\r\n    }\r\n\r\n    private static _StartPerformanceConsole(counterName: string, condition = true): void {\r\n        if (!condition) {\r\n            return;\r\n        }\r\n\r\n        Tools._StartUserMark(counterName, condition);\r\n\r\n        if (console.time) {\r\n            console.time(counterName);\r\n        }\r\n    }\r\n\r\n    private static _EndPerformanceConsole(counterName: string, condition = true): void {\r\n        if (!condition) {\r\n            return;\r\n        }\r\n\r\n        Tools._EndUserMark(counterName, condition);\r\n\r\n        console.timeEnd(counterName);\r\n    }\r\n\r\n    private static _StartMarkNative(counterName: string, condition = true): void {\r\n        if (condition && _native?.startPerformanceCounter) {\r\n            if (Tools._NativePerformanceCounterHandles.has(counterName)) {\r\n                Tools.Warn(`Performance counter with name ${counterName} is already started.`);\r\n            } else {\r\n                const handle = _native.startPerformanceCounter(counterName);\r\n                Tools._NativePerformanceCounterHandles.set(counterName, handle);\r\n            }\r\n        }\r\n    }\r\n\r\n    private static _EndMarkNative(counterName: string, condition = true): void {\r\n        if (condition && _native?.endPerformanceCounter) {\r\n            const handle = Tools._NativePerformanceCounterHandles.get(counterName);\r\n            if (handle) {\r\n                _native.endPerformanceCounter(handle);\r\n                Tools._NativePerformanceCounterHandles.delete(counterName);\r\n            } else {\r\n                Tools.Warn(`Performance counter with name ${counterName} was not started.`);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Starts a performance counter\r\n     */\r\n    public static StartPerformanceCounter: (counterName: string, condition?: boolean) => void = Tools._StartPerformanceCounterDisabled;\r\n\r\n    /**\r\n     * Ends a specific performance counter\r\n     */\r\n    public static EndPerformanceCounter: (counterName: string, condition?: boolean) => void = Tools._EndPerformanceCounterDisabled;\r\n\r\n    /**\r\n     * Gets either window.performance.now() if supported or Date.now() else\r\n     */\r\n    public static get Now(): number {\r\n        return PrecisionDate.Now;\r\n    }\r\n\r\n    /**\r\n     * This method will return the name of the class used to create the instance of the given object.\r\n     * It will works only on Javascript basic data types (number, string, ...) and instance of class declared with the @className decorator.\r\n     * @param object the object to get the class name from\r\n     * @param isType defines if the object is actually a type\r\n     * @returns the name of the class, will be \"object\" for a custom data type not using the @className decorator\r\n     */\r\n    public static GetClassName(object: any, isType = false): string {\r\n        let name = null;\r\n\r\n        if (!isType && object.getClassName) {\r\n            name = object.getClassName();\r\n        } else {\r\n            if (object instanceof Object) {\r\n                const classObj = isType ? object : Object.getPrototypeOf(object);\r\n                name = classObj.constructor[\"__bjsclassName__\"];\r\n            }\r\n            if (!name) {\r\n                name = typeof object;\r\n            }\r\n        }\r\n        return name as string;\r\n    }\r\n\r\n    /**\r\n     * Gets the first element of an array satisfying a given predicate\r\n     * @param array defines the array to browse\r\n     * @param predicate defines the predicate to use\r\n     * @returns null if not found or the element\r\n     */\r\n    public static First<T>(array: Array<T>, predicate: (item: T) => boolean): Nullable<T> {\r\n        for (const el of array) {\r\n            if (predicate(el)) {\r\n                return el;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * This method will return the name of the full name of the class, including its owning module (if any).\r\n     * It will works only on Javascript basic data types (number, string, ...) and instance of class declared with the @className decorator or implementing a method getClassName():string (in which case the module won't be specified).\r\n     * @param object the object to get the class name from\r\n     * @param isType defines if the object is actually a type\r\n     * @returns a string that can have two forms: \"moduleName.className\" if module was specified when the class' Name was registered or \"className\" if there was not module specified.\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static getFullClassName(object: any, isType = false): Nullable<string> {\r\n        let className = null;\r\n        let moduleName = null;\r\n\r\n        if (!isType && object.getClassName) {\r\n            className = object.getClassName();\r\n        } else {\r\n            if (object instanceof Object) {\r\n                const classObj = isType ? object : Object.getPrototypeOf(object);\r\n                className = classObj.constructor[\"__bjsclassName__\"];\r\n                moduleName = classObj.constructor[\"__bjsmoduleName__\"];\r\n            }\r\n            if (!className) {\r\n                className = typeof object;\r\n            }\r\n        }\r\n\r\n        if (!className) {\r\n            return null;\r\n        }\r\n\r\n        return (moduleName != null ? moduleName + \".\" : \"\") + className;\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves after the given amount of time.\r\n     * @param delay Number of milliseconds to delay\r\n     * @returns Promise that resolves after the given amount of time\r\n     */\r\n    public static async DelayAsync(delay: number): Promise<void> {\r\n        await new Promise<void>((resolve) => {\r\n            setTimeout(() => {\r\n                resolve();\r\n            }, delay);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Utility function to detect if the current user agent is Safari\r\n     * @returns whether or not the current user agent is safari\r\n     */\r\n    public static IsSafari(): boolean {\r\n        if (!IsNavigatorAvailable()) {\r\n            return false;\r\n        }\r\n\r\n        return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\r\n    }\r\n}\r\n\r\n/**\r\n * Use this className as a decorator on a given class definition to add it a name and optionally its module.\r\n * You can then use the Tools.getClassName(obj) on an instance to retrieve its class name.\r\n * This method is the only way to get it done in all cases, even if the .js file declaring the class is minified\r\n * @param name The name of the class, case should be preserved\r\n * @param module The name of the Module hosting the class, optional, but strongly recommended to specify if possible. Case should be preserved.\r\n * @returns a decorator function to apply on the class definition.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function className(name: string, module?: string): (target: object) => void {\r\n    return (target: object) => {\r\n        (<any>target)[\"__bjsclassName__\"] = name;\r\n        (<any>target)[\"__bjsmoduleName__\"] = module != null ? module : null;\r\n    };\r\n}\r\n\r\n/**\r\n * An implementation of a loop for asynchronous functions.\r\n */\r\nexport class AsyncLoop {\r\n    /**\r\n     * Defines the current index of the loop.\r\n     */\r\n    public index: number;\r\n    private _done: boolean;\r\n    private _fn: (asyncLoop: AsyncLoop) => void;\r\n    private _successCallback: () => void;\r\n\r\n    /**\r\n     * Constructor.\r\n     * @param iterations the number of iterations.\r\n     * @param func the function to run each iteration\r\n     * @param successCallback the callback that will be called upon successful execution\r\n     * @param offset starting offset.\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the number of iterations for the loop\r\n         */\r\n        public iterations: number,\r\n        func: (asyncLoop: AsyncLoop) => void,\r\n        successCallback: () => void,\r\n        offset = 0\r\n    ) {\r\n        this.index = offset - 1;\r\n        this._done = false;\r\n        this._fn = func;\r\n        this._successCallback = successCallback;\r\n    }\r\n\r\n    /**\r\n     * Execute the next iteration. Must be called after the last iteration was finished.\r\n     */\r\n    public executeNext(): void {\r\n        if (!this._done) {\r\n            if (this.index + 1 < this.iterations) {\r\n                ++this.index;\r\n                this._fn(this);\r\n            } else {\r\n                this.breakLoop();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Break the loop and run the success callback.\r\n     */\r\n    public breakLoop(): void {\r\n        this._done = true;\r\n        this._successCallback();\r\n    }\r\n\r\n    /**\r\n     * Create and run an async loop.\r\n     * @param iterations the number of iterations.\r\n     * @param fn the function to run each iteration\r\n     * @param successCallback the callback that will be called upon successful execution\r\n     * @param offset starting offset.\r\n     * @returns the created async loop object\r\n     */\r\n    public static Run(iterations: number, fn: (asyncLoop: AsyncLoop) => void, successCallback: () => void, offset = 0): AsyncLoop {\r\n        const loop = new AsyncLoop(iterations, fn, successCallback, offset);\r\n\r\n        loop.executeNext();\r\n\r\n        return loop;\r\n    }\r\n\r\n    /**\r\n     * A for-loop that will run a given number of iterations synchronous and the rest async.\r\n     * @param iterations total number of iterations\r\n     * @param syncedIterations number of synchronous iterations in each async iteration.\r\n     * @param fn the function to call each iteration.\r\n     * @param callback a success call back that will be called when iterating stops.\r\n     * @param breakFunction a break condition (optional)\r\n     * @param timeout timeout settings for the setTimeout function. default - 0.\r\n     * @returns the created async loop object\r\n     */\r\n    public static SyncAsyncForLoop(\r\n        iterations: number,\r\n        syncedIterations: number,\r\n        fn: (iteration: number) => void,\r\n        callback: () => void,\r\n        breakFunction?: () => boolean,\r\n        timeout = 0\r\n    ): AsyncLoop {\r\n        return AsyncLoop.Run(\r\n            Math.ceil(iterations / syncedIterations),\r\n            (loop: AsyncLoop) => {\r\n                if (breakFunction && breakFunction()) {\r\n                    loop.breakLoop();\r\n                } else {\r\n                    setTimeout(() => {\r\n                        for (let i = 0; i < syncedIterations; ++i) {\r\n                            const iteration = loop.index * syncedIterations + i;\r\n                            if (iteration >= iterations) {\r\n                                break;\r\n                            }\r\n                            fn(iteration);\r\n                            if (breakFunction && breakFunction()) {\r\n                                loop.breakLoop();\r\n                                break;\r\n                            }\r\n                        }\r\n                        loop.executeNext();\r\n                    }, timeout);\r\n                }\r\n            },\r\n            callback\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for tools.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTools(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Tools.Mix = Mix;\r\n\r\n    Tools.IsExponentOfTwo = IsExponentOfTwo;\r\n\r\n    // Will only be define if Tools is imported freeing up some space when only engine is required\r\n    EngineStore.FallbackTexture =\r\n        \"data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBmRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAAQAAAATgAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC41AP/bAEMABAIDAwMCBAMDAwQEBAQFCQYFBQUFCwgIBgkNCw0NDQsMDA4QFBEODxMPDAwSGBITFRYXFxcOERkbGRYaFBYXFv/bAEMBBAQEBQUFCgYGChYPDA8WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFv/AABEIAQABAAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APH6KKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FCiiigD6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++gooooA+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gUKKKKAPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76CiiigD5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BQooooA+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/voKKKKAPl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FCiiigD6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++gooooA+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gUKKKKAPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76CiiigD5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BQooooA+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/voKKKKAPl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FCiiigD6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++gooooA+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gUKKKKAPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76P//Z\";\r\n}\r\n","/**\r\n * Defines an array and its length.\r\n * It can be helpful to group result from both Arrays and smart arrays in one structure.\r\n */\r\nexport interface ISmartArrayLike<T> {\r\n    /**\r\n     * The data of the array.\r\n     */\r\n    data: Array<T>;\r\n    /**\r\n     * The active length of the array.\r\n     */\r\n    length: number;\r\n}\r\n\r\n/**\r\n * Defines an GC Friendly array where the backfield array do not shrink to prevent over allocations.\r\n */\r\nexport class SmartArray<T> implements ISmartArrayLike<T> {\r\n    /**\r\n     * The full set of data from the array.\r\n     */\r\n    public data: Array<T>;\r\n\r\n    /**\r\n     * The active length of the array.\r\n     */\r\n    public length: number = 0;\r\n\r\n    protected _id: number;\r\n\r\n    /**\r\n     * Instantiates a Smart Array.\r\n     * @param capacity defines the default capacity of the array.\r\n     */\r\n    constructor(capacity: number) {\r\n        this.data = new Array(capacity);\r\n        this._id = SmartArray._GlobalId++;\r\n    }\r\n\r\n    /**\r\n     * Pushes a value at the end of the active data.\r\n     * @param value defines the object to push in the array.\r\n     */\r\n    public push(value: T): void {\r\n        this.data[this.length++] = value;\r\n\r\n        if (this.length > this.data.length) {\r\n            this.data.length *= 2;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Iterates over the active data and apply the lambda to them.\r\n     * @param func defines the action to apply on each value.\r\n     */\r\n    public forEach(func: (content: T) => void): void {\r\n        for (let index = 0; index < this.length; index++) {\r\n            func(this.data[index]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sorts the full sets of data.\r\n     * @param compareFn defines the comparison function to apply.\r\n     */\r\n    public sort(compareFn: (a: T, b: T) => number): void {\r\n        this.data.sort(compareFn);\r\n    }\r\n\r\n    /**\r\n     * Resets the active data to an empty array.\r\n     */\r\n    public reset(): void {\r\n        this.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Releases all the data from the array as well as the array.\r\n     */\r\n    public dispose(): void {\r\n        this.reset();\r\n\r\n        if (this.data) {\r\n            this.data.length = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Concats the active data with a given array.\r\n     * @param array defines the data to concatenate with.\r\n     */\r\n    public concat(array: any): void {\r\n        if (array.length === 0) {\r\n            return;\r\n        }\r\n        if (this.length + array.length > this.data.length) {\r\n            this.data.length = (this.length + array.length) * 2;\r\n        }\r\n\r\n        for (let index = 0; index < array.length; index++) {\r\n            this.data[this.length++] = (array.data || array)[index];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the position of a value in the active data.\r\n     * @param value defines the value to find the index for\r\n     * @returns the index if found in the active data otherwise -1\r\n     */\r\n    public indexOf(value: T): number {\r\n        const position = this.data.indexOf(value);\r\n\r\n        if (position >= this.length) {\r\n            return -1;\r\n        }\r\n\r\n        return position;\r\n    }\r\n\r\n    /**\r\n     * Returns whether an element is part of the active data.\r\n     * @param value defines the value to look for\r\n     * @returns true if found in the active data otherwise false\r\n     */\r\n    public contains(value: T): boolean {\r\n        return this.indexOf(value) !== -1;\r\n    }\r\n\r\n    // Statics\r\n    private static _GlobalId = 0;\r\n}\r\n\r\n/**\r\n * Defines an GC Friendly array where the backfield array do not shrink to prevent over allocations.\r\n * The data in this array can only be present once\r\n */\r\nexport class SmartArrayNoDuplicate<T> extends SmartArray<T> {\r\n    private _duplicateId = 0;\r\n\r\n    /**\r\n     * Pushes a value at the end of the active data.\r\n     * THIS DOES NOT PREVENT DUPPLICATE DATA\r\n     * @param value defines the object to push in the array.\r\n     */\r\n    public override push(value: T): void {\r\n        super.push(value);\r\n\r\n        if (!(<any>value).__smartArrayFlags) {\r\n            (<any>value).__smartArrayFlags = {};\r\n        }\r\n\r\n        (<any>value).__smartArrayFlags[this._id] = this._duplicateId;\r\n    }\r\n\r\n    /**\r\n     * Pushes a value at the end of the active data.\r\n     * If the data is already present, it won t be added again\r\n     * @param value defines the object to push in the array.\r\n     * @returns true if added false if it was already present\r\n     */\r\n    public pushNoDuplicate(value: T): boolean {\r\n        if ((<any>value).__smartArrayFlags && (<any>value).__smartArrayFlags[this._id] === this._duplicateId) {\r\n            return false;\r\n        }\r\n        this.push(value);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Resets the active data to an empty array.\r\n     */\r\n    public override reset(): void {\r\n        super.reset();\r\n        this._duplicateId++;\r\n    }\r\n\r\n    /**\r\n     * Concats the active data with a given array.\r\n     * This ensures no duplicate will be present in the result.\r\n     * @param array defines the data to concatenate with.\r\n     */\r\n    public concatWithNoDuplicate(array: any): void {\r\n        if (array.length === 0) {\r\n            return;\r\n        }\r\n        if (this.length + array.length > this.data.length) {\r\n            this.data.length = (this.length + array.length) * 2;\r\n        }\r\n\r\n        for (let index = 0; index < array.length; index++) {\r\n            const item = (array.data || array)[index];\r\n            this.pushNoDuplicate(item);\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\n\r\n/**\r\n * This class implement a typical dictionary using a string as key and the generic type T as value.\r\n * The underlying implementation relies on an associative array to ensure the best performances.\r\n * The value can be anything including 'null' but except 'undefined'\r\n */\r\nexport class StringDictionary<T> {\r\n    /**\r\n     * This will clear this dictionary and copy the content from the 'source' one.\r\n     * If the T value is a custom object, it won't be copied/cloned, the same object will be used\r\n     * @param source the dictionary to take the content from and copy to this dictionary\r\n     */\r\n    public copyFrom(source: StringDictionary<T>) {\r\n        this.clear();\r\n        source.forEach((t, v) => this.add(t, v));\r\n    }\r\n\r\n    /**\r\n     * Get a value based from its key\r\n     * @param key the given key to get the matching value from\r\n     * @returns the value if found, otherwise undefined is returned\r\n     */\r\n    public get(key: string): T | undefined {\r\n        const val = this._data[key];\r\n        if (val !== undefined) {\r\n            return val;\r\n        }\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Get a value from its key or add it if it doesn't exist.\r\n     * This method will ensure you that a given key/data will be present in the dictionary.\r\n     * @param key the given key to get the matching value from\r\n     * @param factory the factory that will create the value if the key is not present in the dictionary.\r\n     * The factory will only be invoked if there's no data for the given key.\r\n     * @returns the value corresponding to the key.\r\n     */\r\n    public getOrAddWithFactory(key: string, factory: (key: string) => T): T {\r\n        let val = this.get(key);\r\n        if (val !== undefined) {\r\n            return val;\r\n        }\r\n\r\n        val = factory(key);\r\n        if (val) {\r\n            this.add(key, val);\r\n        }\r\n\r\n        return val;\r\n    }\r\n\r\n    /**\r\n     * Get a value from its key if present in the dictionary otherwise add it\r\n     * @param key the key to get the value from\r\n     * @param val if there's no such key/value pair in the dictionary add it with this value\r\n     * @returns the value corresponding to the key\r\n     */\r\n    public getOrAdd(key: string, val: T): T {\r\n        const curVal = this.get(key);\r\n        if (curVal !== undefined) {\r\n            return curVal;\r\n        }\r\n\r\n        this.add(key, val);\r\n        return val;\r\n    }\r\n\r\n    /**\r\n     * Check if there's a given key in the dictionary\r\n     * @param key the key to check for\r\n     * @returns true if the key is present, false otherwise\r\n     */\r\n    public contains(key: string): boolean {\r\n        return this._data[key] !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Add a new key and its corresponding value\r\n     * @param key the key to add\r\n     * @param value the value corresponding to the key\r\n     * @returns true if the operation completed successfully, false if we couldn't insert the key/value because there was already this key in the dictionary\r\n     */\r\n    public add(key: string, value: T): boolean {\r\n        if (this._data[key] !== undefined) {\r\n            return false;\r\n        }\r\n        this._data[key] = value;\r\n        ++this._count;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Update a specific value associated to a key\r\n     * @param key defines the key to use\r\n     * @param value defines the value to store\r\n     * @returns true if the value was updated (or false if the key was not found)\r\n     */\r\n    public set(key: string, value: T): boolean {\r\n        if (this._data[key] === undefined) {\r\n            return false;\r\n        }\r\n        this._data[key] = value;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Get the element of the given key and remove it from the dictionary\r\n     * @param key defines the key to search\r\n     * @returns the value associated with the key or null if not found\r\n     */\r\n    public getAndRemove(key: string): Nullable<T> {\r\n        const val = this.get(key);\r\n        if (val !== undefined) {\r\n            delete this._data[key];\r\n            --this._count;\r\n            return val;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Remove a key/value from the dictionary.\r\n     * @param key the key to remove\r\n     * @returns true if the item was successfully deleted, false if no item with such key exist in the dictionary\r\n     */\r\n    public remove(key: string): boolean {\r\n        if (this.contains(key)) {\r\n            delete this._data[key];\r\n            --this._count;\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Clear the whole content of the dictionary\r\n     */\r\n    public clear() {\r\n        this._data = {};\r\n        this._count = 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current count\r\n     */\r\n    public get count() {\r\n        return this._count;\r\n    }\r\n\r\n    /**\r\n     * Execute a callback on each key/val of the dictionary.\r\n     * Note that you can remove any element in this dictionary in the callback implementation\r\n     * @param callback the callback to execute on a given key/value pair\r\n     */\r\n    public forEach(callback: (key: string, val: T) => void) {\r\n        for (const cur in this._data) {\r\n            const val = this._data[cur];\r\n            callback(cur, val);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Execute a callback on every occurrence of the dictionary until it returns a valid TRes object.\r\n     * If the callback returns null or undefined the method will iterate to the next key/value pair\r\n     * Note that you can remove any element in this dictionary in the callback implementation\r\n     * @param callback the callback to execute, if it return a valid T instanced object the enumeration will stop and the object will be returned\r\n     * @returns the first item\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public first<TRes>(callback: (key: string, val: T) => TRes) {\r\n        for (const cur in this._data) {\r\n            const val = this._data[cur];\r\n            const res = callback(cur, val);\r\n            if (res) {\r\n                return res;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private _count = 0;\r\n    private _data: { [key: string]: T } = {};\r\n}\r\n","import { Clamp } from \"./math.scalar.functions\";\nimport { Matrix, Vector2, Vector3 } from \"./math.vector.pure\";\n\n/**\n * Tabulated Planckian locus in CIE 1960 UCS (u, v) space, with the local isotherm slope `t` used to offset\n * a chromaticity along the tint axis. Source: Wyszecki &amp; Stiles, \"Color Science\", 2nd ed., 1982, pp. 227-228.\n * Each row is [mired, u, v, t].\n */\nconst PlanckianLocusTable: ReadonlyArray<readonly [number, number, number, number]> = [\n    [0, 0.18006, 0.26352, -0.24341],\n    [10, 0.18066, 0.26589, -0.25479],\n    [20, 0.18133, 0.26846, -0.26876],\n    [30, 0.18208, 0.27119, -0.28539],\n    [40, 0.18293, 0.27407, -0.3047],\n    [50, 0.18388, 0.27709, -0.32675],\n    [60, 0.18494, 0.28021, -0.35156],\n    [70, 0.18611, 0.28342, -0.37915],\n    [80, 0.1874, 0.28668, -0.40955],\n    [90, 0.1888, 0.28997, -0.44278],\n    [100, 0.19032, 0.29326, -0.47888],\n    [125, 0.19462, 0.30141, -0.58204],\n    [150, 0.19962, 0.30921, -0.70471],\n    [175, 0.20525, 0.31647, -0.84901],\n    [200, 0.21142, 0.32312, -1.0182],\n    [225, 0.21807, 0.32909, -1.2168],\n    [250, 0.22511, 0.33439, -1.4512],\n    [275, 0.23247, 0.33904, -1.7298],\n    [300, 0.2401, 0.34308, -2.0637],\n    [325, 0.24792, 0.34655, -2.4681],\n    [350, 0.25591, 0.34951, -2.9641],\n    [375, 0.264, 0.352, -3.5814],\n    [400, 0.27218, 0.35407, -4.3633],\n    [425, 0.28039, 0.35577, -5.3762],\n    [450, 0.28863, 0.35714, -6.7262],\n    [475, 0.29685, 0.35823, -8.5955],\n    [500, 0.30505, 0.35907, -11.324],\n    [525, 0.3132, 0.35968, -15.628],\n    [550, 0.32129, 0.36011, -23.325],\n    [575, 0.32931, 0.36038, -40.77],\n    [600, 0.33724, 0.36051, -116.45],\n];\n\n/**\n * The minimum correlated color temperature, in Kelvin, representable by {@link TemperatureTintToXyz} (there is no\n * upper bound: increasingly high temperatures approach mired 0, already within the tabulated range).\n */\nexport const MinTemperatureKelvin = 1e6 / PlanckianLocusTable[PlanckianLocusTable.length - 1][0];\n\n/**\n * The maximum magnitude of the tint offset accepted by {@link TemperatureTintToXyz}, in either direction.\n */\nexport const MaxTintMagnitude = 150;\n\n/**\n * Converts a correlated color temperature and tint offset into the CIE XYZ (Y = 1) coordinates of the\n * corresponding illuminant white point, using a tabulated approximation of the Planckian locus in CIE 1960 UCS\n * (u, v) space.\n * @param temperatureKelvin The correlated color temperature of the illuminant, in Kelvin\n * @param tint An offset perpendicular to the Planckian locus (the green/magenta axis), in the range\n * [-{@link MaxTintMagnitude}, {@link MaxTintMagnitude}]\n * @returns The CIE XYZ (Y = 1) coordinates of the illuminant white point\n */\nexport function TemperatureTintToXyz(temperatureKelvin: number, tint: number): Vector3 {\n    // Clamp before taking the reciprocal: a non-positive or NaN Kelvin value has no valid reciprocal-mired\n    // representation, and taking 1e6 / temperatureKelvin first (before clamping the result) would map negative\n    // inputs to the *hottest* end of the table instead of the coldest/minimum one.\n    const safeTemperatureKelvin = Number.isNaN(temperatureKelvin) ? MinTemperatureKelvin : Math.max(temperatureKelvin, MinTemperatureKelvin);\n    const mired = Clamp(1e6 / safeTemperatureKelvin, PlanckianLocusTable[0][0], PlanckianLocusTable[PlanckianLocusTable.length - 1][0]);\n\n    // Binary search for the table row pair bracketing `mired` (the table is sorted ascending by mired).\n    let low = 0;\n    let high = PlanckianLocusTable.length - 1;\n    while (high - low > 1) {\n        const mid = (low + high) >> 1;\n        if (PlanckianLocusTable[mid][0] <= mired) {\n            low = mid;\n        } else {\n            high = mid;\n        }\n    }\n    const index = low;\n\n    const [lowMired, lowU, lowV, lowT] = PlanckianLocusTable[index];\n    const [highMired, highU, highV, highT] = PlanckianLocusTable[index + 1];\n    const f = (mired - lowMired) / (highMired - lowMired);\n\n    const uv = Vector2.Lerp(new Vector2(lowU, lowV), new Vector2(highU, highV), f);\n\n    const isothermLow = Vector2.Normalize(new Vector2(1, lowT));\n    const isothermHigh = Vector2.Normalize(new Vector2(1, highT));\n    const isotherm = Vector2.Normalize(Vector2.Lerp(isothermLow, isothermHigh, f));\n\n    const clampedTint = Clamp(tint, -MaxTintMagnitude, MaxTintMagnitude);\n    uv.subtractInPlace(isotherm.scale(clampedTint / 3000));\n\n    // CIE 1960 (u, v) -> CIE xyY (Y = 1) -> CIE XYZ.\n    const denom = 2 * uv.x - 8 * uv.y + 4;\n    const x = (3 * uv.x) / denom;\n    const y = (2 * uv.y) / denom;\n\n    return new Vector3(x / y, 1, (1 - x - y) / y);\n}\n\n// `Matrix.FromArray` reads values column-major, so each 3x3 matrix below is written column-by-column, not row-by-row.\n\n/**\n * The Bradford cone-response matrix used for chromatic adaptation.\n */\n// prettier-ignore\nconst BradfordMatrix = Matrix.FromArray([\n    0.8951, -0.7502, 0.0389, 0,\n    0.2664, 1.7135, -0.0685, 0,\n    -0.1614, 0.0367, 1.0296, 0,\n    0, 0, 0, 1,\n]);\n\nconst InverseBradfordMatrix = Matrix.Invert(BradfordMatrix);\n\n/**\n * Computes a per-channel Bradford adaptation ratio, clamped to avoid extreme temperature/tint combinations\n * blowing up the resulting matrix when a cone-response component approaches zero.\n * @param destComponent The destination white's cone-response component\n * @param sourceComponent The source white's cone-response component\n * @returns The ratio to use for this channel, clamped to [0.1, 10]\n */\nfunction ClampedAdaptationRatio(destComponent: number, sourceComponent: number): number {\n    const ratio = sourceComponent > 0 ? destComponent / sourceComponent : 10;\n    return Clamp(ratio, 0.1, 10);\n}\n\n/**\n * Computes the Bradford chromatic-adaptation matrix that maps CIE XYZ values from `sourceWhiteXYZ` to `destWhiteXYZ`.\n * @param sourceWhiteXYZ The CIE XYZ (Y = 1) coordinates of the source reference white\n * @param destWhiteXYZ The CIE XYZ (Y = 1) coordinates of the destination reference white\n * @returns A matrix mapping source-referenced XYZ to destination-referenced XYZ\n */\nfunction BradfordAdapt(sourceWhiteXYZ: Vector3, destWhiteXYZ: Vector3): Matrix {\n    const sourceLMS = Vector3.TransformNormal(sourceWhiteXYZ, BradfordMatrix);\n    const destLMS = Vector3.TransformNormal(destWhiteXYZ, BradfordMatrix);\n\n    // prettier-ignore\n    const scale = Matrix.FromArray([\n        ClampedAdaptationRatio(destLMS.x, sourceLMS.x), 0, 0, 0,\n        0, ClampedAdaptationRatio(destLMS.y, sourceLMS.y), 0, 0,\n        0, 0, ClampedAdaptationRatio(destLMS.z, sourceLMS.z), 0,\n        0, 0, 0, 1,\n    ]);\n\n    // adapt = InverseBradfordMatrix * scale * BradfordMatrix, written back-to-front since `A.multiply(B)` computes `B x A`.\n    const scaledByBradford = BradfordMatrix.multiply(scale);\n    return scaledByBradford.multiply(InverseBradfordMatrix);\n}\n\n/**\n * The standard CIE Illuminant D65 white point, in CIE XYZ (Y = 1).\n */\nconst StandardD65Xyz = new Vector3(0.95047, 1.0, 1.08883);\n\n/**\n * The standard sRGB / Rec.709 linear RGB to CIE XYZ matrix, calibrated to the externally-standardized CIE\n * Illuminant D65 chromaticity - i.e. `StandardRgbToXyzD65 * (1, 1, 1) = StandardD65Xyz` exactly.\n */\n// prettier-ignore\nconst StandardRgbToXyzD65 = Matrix.FromArray([\n    0.4124564, 0.2126729, 0.0193339, 0,\n    0.3575761, 0.7151522, 0.119192, 0,\n    0.1804375, 0.072175, 0.9503041, 0,\n    0, 0, 0, 1,\n]);\n\n/**\n * The linear RGB to CIE XYZ matrix actually used by {@link GetWhiteBalanceMatrix}, recalibrated from\n * {@link StandardRgbToXyzD65} via a single Bradford adaptation step so that neutral (1, 1, 1) maps exactly onto\n * this module's own Planckian-locus approximation of 6500 K (see {@link TemperatureTintToXyz}) instead of the\n * externally-standardized CIE D65 chromaticity. Those two are close but never exactly equal, by definition: D65\n * is defined via the CIE daylight locus, a model fit to measured daylight spectra, which deliberately deviates\n * from the Planckian locus (real daylight isn't quite blackbody radiation) - no table or precision fix can close\n * that gap without distorting temperature/tint for every other illuminant.\n *\n * This is what lets `GetWhiteBalanceMatrix(6500, 0)` be exactly the identity matrix - the default \"no adjustment\"\n * temperature/tint are a true no-op - without needing to special-case that one input: the reverse adaptation is\n * applied once, here, to the matrix itself, rather than to every call's result.\n */\nconst RgbToXyzD65 = StandardRgbToXyzD65.multiply(BradfordAdapt(StandardD65Xyz, TemperatureTintToXyz(6500, 0)));\n\n/**\n * The CIE XYZ to linear RGB matrix, the inverse of {@link RgbToXyzD65}.\n */\nconst XyzToRgbD65 = Matrix.Invert(RgbToXyzD65);\n\n/**\n * The working color space's reference white, in CIE XYZ (Y = 1) - what neutral (1, 1, 1) linear RGB maps to\n * through {@link RgbToXyzD65}. Since that matrix is itself calibrated to this module's own 6500 K point (see\n * above), this is exactly `TemperatureTintToXyz(6500, 0)`. Deriving it as \"whatever (1, 1, 1) maps to\" (rather\n * than calling `TemperatureTintToXyz` a second time) keeps the invariant self-documenting: a fully white-balanced\n * neutral patch round-trips back to exactly (1, 1, 1) for any input illuminant, because the adaptation target is\n * always tied directly to whatever the working color space itself already treats as neutral.\n */\nconst ReferenceWhiteXyz = Vector3.TransformNormal(new Vector3(1, 1, 1), RgbToXyzD65);\n\n/**\n * Computes the linear RGB (sRGB / Rec.709 primaries) color-correction matrix that white-balances the given\n * illuminant, by chromatically adapting its white point (see {@link TemperatureTintToXyz}) to the working\n * color space's reference white using the Bradford transform.\n * @param temperatureKelvin The correlated color temperature of the illuminant to neutralize, in Kelvin\n * @param tint An offset perpendicular to the Planckian locus (the green/magenta axis), in the range [-150, 150]\n * @returns A column-major 3x3 matrix (9 values), ready to be bound as a `mat3` shader uniform\n */\nexport function GetWhiteBalanceMatrix(temperatureKelvin: number, tint: number): Float32Array | Array<number> {\n    const targetWhiteXYZ = TemperatureTintToXyz(temperatureKelvin, tint);\n    const adapt = BradfordAdapt(targetWhiteXYZ, ReferenceWhiteXyz);\n\n    // finalMatrix = XyzToRgbD65 * adapt * RgbToXyzD65, written back-to-front (see BradfordAdapt).\n    const adaptedFromRgb = RgbToXyzD65.multiply(adapt);\n    const finalMatrix = adaptedFromRgb.multiply(XyzToRgbD65);\n\n    // `Matrix` stores its values column-major, matching the layout GLSL/WGSL `mat3` uniforms expect,\n    // so the upper-left 3x3 block can be extracted directly with no transpose.\n    return Matrix.GetAsMatrix3x3(finalMatrix);\n}\n","/**\r\n * Prepare the list of uniforms associated with the ColorCurves effects.\r\n * @param uniformsList The list of uniforms used in the effect\r\n */\r\nexport function PrepareUniformsForColorCurves(uniformsList: string[]): void {\r\n    uniformsList.push(\"vCameraColorCurveNeutral\", \"vCameraColorCurvePositive\", \"vCameraColorCurveNegative\");\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { PrepareUniformsForColorCurves } from \"./colorCurves.functions\";\r\n\r\n/**\r\n * The color grading curves provide additional color adjustment that is applied after any color grading transform (3D LUT).\r\n * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.\r\n * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;\r\n * corresponding to low luminance, medium luminance, and high luminance areas respectively.\r\n */\r\nexport class ColorCurves {\r\n    private _dirty = true;\r\n\r\n    private _tempColor = new Color4(0, 0, 0, 0);\r\n\r\n    private _globalCurve = new Color4(0, 0, 0, 0);\r\n    private _highlightsCurve = new Color4(0, 0, 0, 0);\r\n    private _midtonesCurve = new Color4(0, 0, 0, 0);\r\n    private _shadowsCurve = new Color4(0, 0, 0, 0);\r\n\r\n    private _positiveCurve = new Color4(0, 0, 0, 0);\r\n    private _negativeCurve = new Color4(0, 0, 0, 0);\r\n\r\n    @serialize()\r\n    private _globalHue = 30;\r\n\r\n    @serialize()\r\n    private _globalDensity = 0;\r\n\r\n    @serialize()\r\n    private _globalSaturation = 0;\r\n\r\n    @serialize()\r\n    private _globalExposure = 0;\r\n\r\n    /**\r\n     * Gets the global Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public get globalHue(): number {\r\n        return this._globalHue;\r\n    }\r\n    /**\r\n     * Sets the global Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public set globalHue(value: number) {\r\n        this._globalHue = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the global Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public get globalDensity(): number {\r\n        return this._globalDensity;\r\n    }\r\n    /**\r\n     * Sets the global Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public set globalDensity(value: number) {\r\n        this._globalDensity = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the global Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public get globalSaturation(): number {\r\n        return this._globalSaturation;\r\n    }\r\n    /**\r\n     * Sets the global Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public set globalSaturation(value: number) {\r\n        this._globalSaturation = value;\r\n        this._dirty = true;\r\n    }\r\n\r\n    /**\r\n     * Gets the global Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public get globalExposure(): number {\r\n        return this._globalExposure;\r\n    }\r\n    /**\r\n     * Sets the global Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public set globalExposure(value: number) {\r\n        this._globalExposure = value;\r\n        this._dirty = true;\r\n    }\r\n\r\n    @serialize()\r\n    private _highlightsHue = 30;\r\n\r\n    @serialize()\r\n    private _highlightsDensity = 0;\r\n\r\n    @serialize()\r\n    private _highlightsSaturation = 0;\r\n\r\n    @serialize()\r\n    private _highlightsExposure = 0;\r\n\r\n    /**\r\n     * Gets the highlights Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public get highlightsHue(): number {\r\n        return this._highlightsHue;\r\n    }\r\n    /**\r\n     * Sets the highlights Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public set highlightsHue(value: number) {\r\n        this._highlightsHue = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the highlights Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public get highlightsDensity(): number {\r\n        return this._highlightsDensity;\r\n    }\r\n    /**\r\n     * Sets the highlights Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public set highlightsDensity(value: number) {\r\n        this._highlightsDensity = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the highlights Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public get highlightsSaturation(): number {\r\n        return this._highlightsSaturation;\r\n    }\r\n    /**\r\n     * Sets the highlights Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public set highlightsSaturation(value: number) {\r\n        this._highlightsSaturation = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the highlights Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public get highlightsExposure(): number {\r\n        return this._highlightsExposure;\r\n    }\r\n    /**\r\n     * Sets the highlights Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public set highlightsExposure(value: number) {\r\n        this._highlightsExposure = value;\r\n        this._dirty = true;\r\n    }\r\n\r\n    @serialize()\r\n    private _midtonesHue = 30;\r\n\r\n    @serialize()\r\n    private _midtonesDensity = 0;\r\n\r\n    @serialize()\r\n    private _midtonesSaturation = 0;\r\n\r\n    @serialize()\r\n    private _midtonesExposure = 0;\r\n\r\n    /**\r\n     * Gets the midtones Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public get midtonesHue(): number {\r\n        return this._midtonesHue;\r\n    }\r\n    /**\r\n     * Sets the midtones Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public set midtonesHue(value: number) {\r\n        this._midtonesHue = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the midtones Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public get midtonesDensity(): number {\r\n        return this._midtonesDensity;\r\n    }\r\n    /**\r\n     * Sets the midtones Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public set midtonesDensity(value: number) {\r\n        this._midtonesDensity = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the midtones Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public get midtonesSaturation(): number {\r\n        return this._midtonesSaturation;\r\n    }\r\n    /**\r\n     * Sets the midtones Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public set midtonesSaturation(value: number) {\r\n        this._midtonesSaturation = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the midtones Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public get midtonesExposure(): number {\r\n        return this._midtonesExposure;\r\n    }\r\n    /**\r\n     * Sets the midtones Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public set midtonesExposure(value: number) {\r\n        this._midtonesExposure = value;\r\n        this._dirty = true;\r\n    }\r\n\r\n    private _shadowsHue = 30;\r\n    private _shadowsDensity = 0;\r\n    private _shadowsSaturation = 0;\r\n    private _shadowsExposure = 0;\r\n\r\n    /**\r\n     * Gets the shadows Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public get shadowsHue(): number {\r\n        return this._shadowsHue;\r\n    }\r\n    /**\r\n     * Sets the shadows Hue value.\r\n     * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).\r\n     */\r\n    public set shadowsHue(value: number) {\r\n        this._shadowsHue = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the shadows Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public get shadowsDensity(): number {\r\n        return this._shadowsDensity;\r\n    }\r\n    /**\r\n     * Sets the shadows Density value.\r\n     * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.\r\n     * Values less than zero provide a filter of opposite hue.\r\n     */\r\n    public set shadowsDensity(value: number) {\r\n        this._shadowsDensity = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the shadows Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public get shadowsSaturation(): number {\r\n        return this._shadowsSaturation;\r\n    }\r\n    /**\r\n     * Sets the shadows Saturation value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.\r\n     */\r\n    public set shadowsSaturation(value: number) {\r\n        this._shadowsSaturation = value;\r\n        this._dirty = true;\r\n    }\r\n    /**\r\n     * Gets the shadows Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public get shadowsExposure(): number {\r\n        return this._shadowsExposure;\r\n    }\r\n    /**\r\n     * Sets the shadows Exposure value.\r\n     * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.\r\n     */\r\n    public set shadowsExposure(value: number) {\r\n        this._shadowsExposure = value;\r\n        this._dirty = true;\r\n    }\r\n\r\n    /**\r\n     * Returns the class name\r\n     * @returns The class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ColorCurves\";\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of uniforms associated with the ColorCurves effects.\r\n     * @param uniformsList The list of uniforms used in the effect\r\n     */\r\n    public static PrepareUniforms: (uniformsList: string[]) => void = PrepareUniformsForColorCurves;\r\n\r\n    /**\r\n     * Returns color grading data based on a hue, density, saturation and exposure value.\r\n     * @param hue\r\n     * @param density\r\n     * @param saturation The saturation.\r\n     * @param exposure The exposure.\r\n     * @param result The result data container.\r\n     */\r\n    private _getColorGradingDataToRef(hue: number, density: number, saturation: number, exposure: number, result: Color4): void {\r\n        if (hue == null) {\r\n            return;\r\n        }\r\n\r\n        hue = ColorCurves._Clamp(hue, 0, 360);\r\n        density = ColorCurves._Clamp(density, -100, 100);\r\n        saturation = ColorCurves._Clamp(saturation, -100, 100);\r\n        exposure = ColorCurves._Clamp(exposure, -100, 100);\r\n\r\n        // Remap the slider/config filter density with non-linear mapping and also scale by half\r\n        // so that the maximum filter density is only 50% control. This provides fine control\r\n        // for small values and reasonable range.\r\n        density = ColorCurves._ApplyColorGradingSliderNonlinear(density);\r\n        density *= 0.5;\r\n\r\n        exposure = ColorCurves._ApplyColorGradingSliderNonlinear(exposure);\r\n\r\n        if (density < 0) {\r\n            density *= -1;\r\n            hue = (hue + 180) % 360;\r\n        }\r\n\r\n        ColorCurves._FromHSBToRef(hue, density, 50 + 0.25 * exposure, result);\r\n        result.scaleToRef(2, result);\r\n        result.a = 1 + 0.01 * saturation;\r\n    }\r\n\r\n    /**\r\n     * Takes an input slider value and returns an adjusted value that provides extra control near the centre.\r\n     * @param value The input slider value in range [-100,100].\r\n     * @returns Adjusted value.\r\n     */\r\n    private static _ApplyColorGradingSliderNonlinear(value: number): number {\r\n        value /= 100;\r\n\r\n        let x: number = Math.abs(value);\r\n        x = Math.pow(x, 2);\r\n\r\n        if (value < 0) {\r\n            x *= -1;\r\n        }\r\n\r\n        x *= 100;\r\n\r\n        return x;\r\n    }\r\n\r\n    /**\r\n     * Returns an RGBA Color4 based on Hue, Saturation and Brightness (also referred to as value, HSV).\r\n     * @param hue The hue (H) input.\r\n     * @param saturation The saturation (S) input.\r\n     * @param brightness The brightness (B) input.\r\n     * @param result An RGBA color represented as Vector4.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private static _FromHSBToRef(hue: number, saturation: number, brightness: number, result: Color4): void {\r\n        let h: number = ColorCurves._Clamp(hue, 0, 360);\r\n        const s: number = ColorCurves._Clamp(saturation / 100, 0, 1);\r\n        const v: number = ColorCurves._Clamp(brightness / 100, 0, 1);\r\n\r\n        if (s === 0) {\r\n            result.r = v;\r\n            result.g = v;\r\n            result.b = v;\r\n        } else {\r\n            // sector 0 to 5\r\n            h /= 60;\r\n            const i = Math.floor(h);\r\n\r\n            // fractional part of h\r\n            const f = h - i;\r\n            const p = v * (1 - s);\r\n            const q = v * (1 - s * f);\r\n            const t = v * (1 - s * (1 - f));\r\n\r\n            switch (i) {\r\n                case 0:\r\n                    result.r = v;\r\n                    result.g = t;\r\n                    result.b = p;\r\n                    break;\r\n                case 1:\r\n                    result.r = q;\r\n                    result.g = v;\r\n                    result.b = p;\r\n                    break;\r\n                case 2:\r\n                    result.r = p;\r\n                    result.g = v;\r\n                    result.b = t;\r\n                    break;\r\n                case 3:\r\n                    result.r = p;\r\n                    result.g = q;\r\n                    result.b = v;\r\n                    break;\r\n                case 4:\r\n                    result.r = t;\r\n                    result.g = p;\r\n                    result.b = v;\r\n                    break;\r\n                default:\r\n                    // case 5:\r\n                    result.r = v;\r\n                    result.g = p;\r\n                    result.b = q;\r\n                    break;\r\n            }\r\n        }\r\n\r\n        result.a = 1;\r\n    }\r\n\r\n    /**\r\n     * Returns a value clamped between min and max\r\n     * @param value The value to clamp\r\n     * @param min The minimum of value\r\n     * @param max The maximum of value\r\n     * @returns The clamped value.\r\n     */\r\n    private static _Clamp(value: number, min: number, max: number): number {\r\n        return Math.min(Math.max(value, min), max);\r\n    }\r\n\r\n    /**\r\n     * Clones the current color curve instance.\r\n     * @returns The cloned curves\r\n     */\r\n    public clone(): ColorCurves {\r\n        return SerializationHelper.Clone(() => new ColorCurves(), this);\r\n    }\r\n\r\n    /**\r\n     * Serializes the current color curve instance to a json representation.\r\n     * @returns a JSON representation\r\n     */\r\n    public serialize(): any {\r\n        return SerializationHelper.Serialize(this);\r\n    }\r\n\r\n    /** @internal */\r\n    public _bind(effect: Effect, positiveUniform = \"vCameraColorCurvePositive\", neutralUniform = \"vCameraColorCurveNeutral\", negativeUniform = \"vCameraColorCurveNegative\"): void {\r\n        if (this._dirty) {\r\n            this._dirty = false;\r\n\r\n            // Fill in global info.\r\n            this._getColorGradingDataToRef(this._globalHue, this._globalDensity, this._globalSaturation, this._globalExposure, this._globalCurve);\r\n\r\n            // Compute highlights info.\r\n            this._getColorGradingDataToRef(this._highlightsHue, this._highlightsDensity, this._highlightsSaturation, this._highlightsExposure, this._tempColor);\r\n            this._tempColor.multiplyToRef(this._globalCurve, this._highlightsCurve);\r\n\r\n            // Compute midtones info.\r\n            this._getColorGradingDataToRef(this._midtonesHue, this._midtonesDensity, this._midtonesSaturation, this._midtonesExposure, this._tempColor);\r\n            this._tempColor.multiplyToRef(this._globalCurve, this._midtonesCurve);\r\n\r\n            // Compute shadows info.\r\n            this._getColorGradingDataToRef(this._shadowsHue, this._shadowsDensity, this._shadowsSaturation, this._shadowsExposure, this._tempColor);\r\n            this._tempColor.multiplyToRef(this._globalCurve, this._shadowsCurve);\r\n\r\n            // Compute deltas (neutral is midtones).\r\n            this._highlightsCurve.subtractToRef(this._midtonesCurve, this._positiveCurve);\r\n            this._midtonesCurve.subtractToRef(this._shadowsCurve, this._negativeCurve);\r\n        }\r\n\r\n        if (effect) {\r\n            effect.setFloat4(positiveUniform, this._positiveCurve.r, this._positiveCurve.g, this._positiveCurve.b, this._positiveCurve.a);\r\n            effect.setFloat4(neutralUniform, this._midtonesCurve.r, this._midtonesCurve.g, this._midtonesCurve.b, this._midtonesCurve.a);\r\n            effect.setFloat4(negativeUniform, this._negativeCurve.r, this._negativeCurve.g, this._negativeCurve.b, this._negativeCurve.a);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n\r\n/**\r\n * Parses the color curve from a json representation.\r\n * @param source the JSON source to parse\r\n * @returns The parsed curves\r\n */\r\nexport function ColorCurvesParse(source: any): ColorCurves {\r\n    return SerializationHelper.Parse(() => new ColorCurves(), source, null, null);\r\n}\r\n\r\n/**\r\n * Binds the color curves to the shader.\r\n * @param colorCurves The color curve to bind\r\n * @param effect The effect to bind to\r\n * @param positiveUniform The positive uniform shader parameter\r\n * @param neutralUniform The neutral uniform shader parameter\r\n * @param negativeUniform The negative uniform shader parameter\r\n */\r\nexport function ColorCurvesBind(\r\n    colorCurves: ColorCurves,\r\n    effect: Effect,\r\n    positiveUniform = \"vCameraColorCurvePositive\",\r\n    neutralUniform = \"vCameraColorCurveNeutral\",\r\n    negativeUniform = \"vCameraColorCurveNegative\"\r\n): void {\r\n    colorCurves._bind(effect, positiveUniform, neutralUniform, negativeUniform);\r\n}\r\n\r\n/**\r\n * Register side effects for colorCurves.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterColorCurves(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // References the dependencies.\r\n    ColorCurves.Bind = ColorCurvesBind;\r\n    ColorCurves.Parse = ColorCurvesParse;\r\n\r\n    SerializationHelper._ColorCurvesParser = ColorCurvesParse;\r\n}\r\n","import { PrepareUniformsForColorCurves } from \"./colorCurves.functions\";\r\nimport { type IImageProcessingConfigurationDefines } from \"./imageProcessingConfiguration.defines\";\r\n\r\n/**\r\n * Prepare the list of uniforms associated with the Image Processing effects.\r\n * @param uniforms The list of uniforms used in the effect\r\n * @param defines the list of defines currently in use\r\n */\r\nexport function PrepareUniformsForImageProcessing(uniforms: string[], defines: IImageProcessingConfigurationDefines): void {\r\n    if (defines.WHITEBALANCE) {\r\n        uniforms.push(\"whiteBalanceMatrix\");\r\n    }\r\n    if (defines.EXPOSURE) {\r\n        uniforms.push(\"exposureLinear\");\r\n    }\r\n    if (defines.CONTRAST) {\r\n        uniforms.push(\"contrast\");\r\n    }\r\n    if (defines.COLORGRADING) {\r\n        uniforms.push(\"colorTransformSettings\");\r\n    }\r\n    if (defines.VIGNETTE || defines.DITHER) {\r\n        uniforms.push(\"vInverseScreenSize\");\r\n    }\r\n    if (defines.VIGNETTE) {\r\n        uniforms.push(\"vignetteSettings1\");\r\n        uniforms.push(\"vignetteSettings2\");\r\n    }\r\n    if (defines.COLORCURVES) {\r\n        PrepareUniformsForColorCurves(uniforms);\r\n    }\r\n    if (defines.DITHER) {\r\n        uniforms.push(\"ditherIntensity\");\r\n    }\r\n}\r\n\r\n/**\r\n * Prepare the list of samplers associated with the Image Processing effects.\r\n * @param samplersList The list of uniforms used in the effect\r\n * @param defines the list of defines currently in use\r\n */\r\nexport function PrepareSamplersForImageProcessing(samplersList: string[], defines: IImageProcessingConfigurationDefines): void {\r\n    if (defines.COLORGRADING) {\r\n        samplersList.push(\"txColorTransform\");\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsTexture, serializeAsColorCurves, serializeAsColor4 } from \"../Misc/decorators\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { GetWhiteBalanceMatrix, MaxTintMagnitude, MinTemperatureKelvin } from \"../Maths/colorTemperature.functions\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { ColorCurves, ColorCurvesBind } from \"../Materials/colorCurves.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Mix } from \"../Misc/tools.functions\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type IImageProcessingConfigurationDefines } from \"./imageProcessingConfiguration.defines\";\r\nimport { PrepareSamplersForImageProcessing, PrepareUniformsForImageProcessing } from \"./imageProcessingConfiguration.functions\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This groups together the common properties used for image processing either in direct forward pass\r\n * or through post processing effect depending on the use of the image processing pipeline in your scene\r\n * or not.\r\n */\r\nexport class ImageProcessingConfiguration {\r\n    /**\r\n     * Default tone mapping applied in BabylonJS.\r\n     */\r\n    public static readonly TONEMAPPING_STANDARD = 0;\r\n\r\n    /**\r\n     * ACES Tone mapping (used by default in unreal and unity). This can help getting closer\r\n     * to other engines rendering to increase portability.\r\n     */\r\n    public static readonly TONEMAPPING_ACES = 1;\r\n\r\n    /**\r\n     * Neutral Tone mapping developped by the Khronos group in order to constrain\r\n     * values between 0 and 1 without shifting Hue.\r\n     */\r\n    public static readonly TONEMAPPING_KHR_PBR_NEUTRAL = 2;\r\n\r\n    /**\r\n     * Color curves setup used in the effect if colorCurvesEnabled is set to true\r\n     */\r\n    @serializeAsColorCurves()\r\n    public colorCurves: Nullable<ColorCurves> = new ColorCurves();\r\n\r\n    @serialize()\r\n    private _colorCurvesEnabled = false;\r\n    /**\r\n     * Gets whether the color curves effect is enabled.\r\n     */\r\n    public get colorCurvesEnabled(): boolean {\r\n        return this._colorCurvesEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the color curves effect is enabled.\r\n     */\r\n    public set colorCurvesEnabled(value: boolean) {\r\n        if (this._colorCurvesEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._colorCurvesEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serializeAsTexture(\"colorGradingTexture\")\r\n    private _colorGradingTexture: Nullable<BaseTexture>;\r\n    /**\r\n     * Color grading LUT texture used in the effect if colorGradingEnabled is set to true\r\n     */\r\n    public get colorGradingTexture(): Nullable<BaseTexture> {\r\n        return this._colorGradingTexture;\r\n    }\r\n    /**\r\n     * Color grading LUT texture used in the effect if colorGradingEnabled is set to true\r\n     */\r\n    public set colorGradingTexture(value: Nullable<BaseTexture>) {\r\n        if (this._colorGradingTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._colorGradingTexture = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _colorGradingEnabled = false;\r\n    /**\r\n     * Gets whether the color grading effect is enabled.\r\n     */\r\n    public get colorGradingEnabled(): boolean {\r\n        return this._colorGradingEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the color grading effect is enabled.\r\n     */\r\n    public set colorGradingEnabled(value: boolean) {\r\n        if (this._colorGradingEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._colorGradingEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _colorGradingWithGreenDepth = true;\r\n    /**\r\n     * Gets whether the color grading effect is using a green depth for the 3d Texture.\r\n     */\r\n    public get colorGradingWithGreenDepth(): boolean {\r\n        return this._colorGradingWithGreenDepth;\r\n    }\r\n    /**\r\n     * Sets whether the color grading effect is using a green depth for the 3d Texture.\r\n     */\r\n    public set colorGradingWithGreenDepth(value: boolean) {\r\n        if (this._colorGradingWithGreenDepth === value) {\r\n            return;\r\n        }\r\n\r\n        this._colorGradingWithGreenDepth = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _colorGradingBGR = true;\r\n    /**\r\n     * Gets whether the color grading texture contains BGR values.\r\n     */\r\n    public get colorGradingBGR(): boolean {\r\n        return this._colorGradingBGR;\r\n    }\r\n    /**\r\n     * Sets whether the color grading texture contains BGR values.\r\n     */\r\n    public set colorGradingBGR(value: boolean) {\r\n        if (this._colorGradingBGR === value) {\r\n            return;\r\n        }\r\n\r\n        this._colorGradingBGR = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    /** @internal */\r\n    @serialize()\r\n    public _exposure = 1.0;\r\n    /**\r\n     * Gets the Exposure used in the effect.\r\n     */\r\n    public get exposure(): number {\r\n        return this._exposure;\r\n    }\r\n    /**\r\n     * Sets the Exposure used in the effect.\r\n     */\r\n    public set exposure(value: number) {\r\n        if (this._exposure === value) {\r\n            return;\r\n        }\r\n\r\n        this._exposure = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _toneMappingEnabled = false;\r\n    /**\r\n     * Gets whether the tone mapping effect is enabled.\r\n     */\r\n    public get toneMappingEnabled(): boolean {\r\n        return this._toneMappingEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the tone mapping effect is enabled.\r\n     */\r\n    public set toneMappingEnabled(value: boolean) {\r\n        if (this._toneMappingEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._toneMappingEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _toneMappingType = ImageProcessingConfiguration.TONEMAPPING_STANDARD;\r\n    /**\r\n     * Gets the type of tone mapping effect.\r\n     */\r\n    public get toneMappingType(): number {\r\n        return this._toneMappingType;\r\n    }\r\n    /**\r\n     * Sets the type of tone mapping effect used in BabylonJS.\r\n     */\r\n    public set toneMappingType(value: number) {\r\n        if (this._toneMappingType === value) {\r\n            return;\r\n        }\r\n\r\n        this._toneMappingType = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    protected _contrast = 1.0;\r\n    /**\r\n     * Gets the contrast used in the effect.\r\n     */\r\n    public get contrast(): number {\r\n        return this._contrast;\r\n    }\r\n    /**\r\n     * Sets the contrast used in the effect.\r\n     */\r\n    public set contrast(value: number) {\r\n        if (this._contrast === value) {\r\n            return;\r\n        }\r\n\r\n        this._contrast = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _whiteBalanceEnabled = false;\r\n    /**\r\n     * Gets whether the white balance effect is enabled.\r\n     */\r\n    public get whiteBalanceEnabled(): boolean {\r\n        return this._whiteBalanceEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the white balance effect is enabled.\r\n     */\r\n    public set whiteBalanceEnabled(value: boolean) {\r\n        if (this._whiteBalanceEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._whiteBalanceEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _temperature = 6500;\r\n    /**\r\n     * Gets the correlated color temperature, in Kelvin, of the illuminant to neutralize when whiteBalanceEnabled\r\n     * is set to true - i.e. the light the scene is assumed to have been lit with, not a \"warm\"/\"cool\" creative\r\n     * adjustment. Lower values (e.g. ~2000-3500 K) correspond to warm/orange sources such as tungsten or candle\r\n     * light; higher values (e.g. ~7000-10000 K) correspond to cool/blue sources such as shade or overcast sky.\r\n     * Clamped to the tabulated range (roughly 1667 K and above) - the getter reflects the clamped value. Default is 6500.\r\n     */\r\n    public get temperature(): number {\r\n        return this._temperature;\r\n    }\r\n    /**\r\n     * Sets the correlated color temperature, in Kelvin, of the illuminant to neutralize when whiteBalanceEnabled\r\n     * is set to true - i.e. the light the scene is assumed to have been lit with, not a \"warm\"/\"cool\" creative\r\n     * adjustment. Lower values (e.g. ~2000-3500 K) correspond to warm/orange sources such as tungsten or candle\r\n     * light; higher values (e.g. ~7000-10000 K) correspond to cool/blue sources such as shade or overcast sky.\r\n     * Clamped to the tabulated range (roughly 1667 K and above) - the getter reflects the clamped value. Default is 6500.\r\n     */\r\n    public set temperature(value: number) {\r\n        value = Number.isNaN(value) ? MinTemperatureKelvin : Math.max(value, MinTemperatureKelvin);\r\n\r\n        if (this._temperature === value) {\r\n            return;\r\n        }\r\n\r\n        this._temperature = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _tint = 0;\r\n    /**\r\n     * Gets the white balance tint offset used in the effect if whiteBalanceEnabled is set to true, on the\r\n     * green/magenta axis perpendicular to temperature - e.g. to correct for illuminants (such as some\r\n     * fluorescent lights) that a color temperature alone can't fully neutralize. Positive values shift the\r\n     * corrected image toward magenta (compensating a green-tinted illuminant); negative values shift it toward\r\n     * green (compensating a magenta-tinted illuminant). Clamped to [-150, 150] - the getter reflects the clamped value. Default is 0 (no tint offset).\r\n     */\r\n    public get tint(): number {\r\n        return this._tint;\r\n    }\r\n    /**\r\n     * Sets the white balance tint offset used in the effect if whiteBalanceEnabled is set to true, on the\r\n     * green/magenta axis perpendicular to temperature - e.g. to correct for illuminants (such as some\r\n     * fluorescent lights) that a color temperature alone can't fully neutralize. Positive values shift the\r\n     * corrected image toward magenta (compensating a green-tinted illuminant); negative values shift it toward\r\n     * green (compensating a magenta-tinted illuminant). Clamped to [-150, 150] - the getter reflects the clamped value. Default is 0 (no tint offset).\r\n     */\r\n    public set tint(value: number) {\r\n        value = Clamp(value, -MaxTintMagnitude, MaxTintMagnitude);\r\n\r\n        if (this._tint === value) {\r\n            return;\r\n        }\r\n\r\n        this._tint = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    private _whiteBalanceMatrix: Nullable<Float32Array | Array<number>> = null;\r\n    private _whiteBalanceMatrixTemperature: Nullable<number> = null;\r\n    private _whiteBalanceMatrixTint: Nullable<number> = null;\r\n\r\n    /**\r\n     * Returns the white balance matrix for the current temperature/tint, computing it on first use and\r\n     * recomputing it if either value has changed since it was last computed. Deliberately lazy: white balance is\r\n     * disabled by default, and every `ImageProcessingConfiguration` instance (created per scene, per material,\r\n     * per post process) would otherwise pay this matrix's construction cost even when never enabled. Checking\r\n     * here (rather than eagerly refreshing from the temperature/tint setters) also means paths that set the\r\n     * private backing fields directly - such as SerializationHelper.Clone/Parse, which assign serialized\r\n     * properties without going through their setters - still end up with a matrix that matches the current\r\n     * temperature/tint.\r\n     * @returns the column-major white balance matrix for the current temperature/tint\r\n     */\r\n    private _getWhiteBalanceMatrix(): Float32Array | Array<number> {\r\n        if (this._whiteBalanceMatrix === null || this._whiteBalanceMatrixTemperature !== this._temperature || this._whiteBalanceMatrixTint !== this._tint) {\r\n            this._whiteBalanceMatrixTemperature = this._temperature;\r\n            this._whiteBalanceMatrixTint = this._tint;\r\n            this._whiteBalanceMatrix = GetWhiteBalanceMatrix(this._temperature, this._tint);\r\n        }\r\n        return this._whiteBalanceMatrix;\r\n    }\r\n\r\n    /**\r\n     * Vignette stretch size.\r\n     */\r\n    @serialize()\r\n    public vignetteStretch = 0;\r\n\r\n    /**\r\n     * Vignette center X Offset.\r\n     */\r\n    @serialize()\r\n    public vignetteCenterX = 0;\r\n\r\n    /**\r\n     * Vignette center Y Offset.\r\n     */\r\n    @serialize()\r\n    public vignetteCenterY = 0;\r\n\r\n    /**\r\n     * Back Compat: Vignette center Y Offset.\r\n     * @deprecated use vignetteCenterY instead\r\n     */\r\n    public get vignetteCentreY(): number {\r\n        return this.vignetteCenterY;\r\n    }\r\n    public set vignetteCentreY(value: number) {\r\n        this.vignetteCenterY = value;\r\n    }\r\n\r\n    /**\r\n     * Back Compat: Vignette center X Offset.\r\n     * @deprecated use vignetteCenterX instead\r\n     */\r\n    public get vignetteCentreX(): number {\r\n        return this.vignetteCenterX;\r\n    }\r\n    public set vignetteCentreX(value: number) {\r\n        this.vignetteCenterX = value;\r\n    }\r\n\r\n    /**\r\n     * Vignette weight or intensity of the vignette effect.\r\n     */\r\n    @serialize()\r\n    public vignetteWeight = 1.5;\r\n\r\n    /**\r\n     * Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)\r\n     * if vignetteEnabled is set to true.\r\n     */\r\n    @serializeAsColor4()\r\n    public vignetteColor: Color4 = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * Camera field of view used by the Vignette effect.\r\n     */\r\n    @serialize()\r\n    public vignetteCameraFov = 0.5;\r\n\r\n    @serialize()\r\n    private _vignetteBlendMode = ImageProcessingConfiguration.VIGNETTEMODE_MULTIPLY;\r\n    /**\r\n     * Gets the vignette blend mode allowing different kind of effect.\r\n     */\r\n    public get vignetteBlendMode(): number {\r\n        return this._vignetteBlendMode;\r\n    }\r\n    /**\r\n     * Sets the vignette blend mode allowing different kind of effect.\r\n     */\r\n    public set vignetteBlendMode(value: number) {\r\n        if (this._vignetteBlendMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._vignetteBlendMode = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _vignetteEnabled = false;\r\n    /**\r\n     * Gets whether the vignette effect is enabled.\r\n     */\r\n    public get vignetteEnabled(): boolean {\r\n        return this._vignetteEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the vignette effect is enabled.\r\n     */\r\n    public set vignetteEnabled(value: boolean) {\r\n        if (this._vignetteEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._vignetteEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _ditheringEnabled = false;\r\n    /**\r\n     * Gets whether the dithering effect is enabled.\r\n     * The dithering effect can be used to reduce banding.\r\n     */\r\n    public get ditheringEnabled(): boolean {\r\n        return this._ditheringEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the dithering effect is enabled.\r\n     * The dithering effect can be used to reduce banding.\r\n     */\r\n    public set ditheringEnabled(value: boolean) {\r\n        if (this._ditheringEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ditheringEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _ditheringIntensity = 1.0 / 255.0;\r\n    /**\r\n     * Gets the dithering intensity. 0 is no dithering. Default is 1.0 / 255.0.\r\n     */\r\n    public get ditheringIntensity(): number {\r\n        return this._ditheringIntensity;\r\n    }\r\n    /**\r\n     * Sets the dithering intensity. 0 is no dithering. Default is 1.0 / 255.0.\r\n     */\r\n    public set ditheringIntensity(value: number) {\r\n        if (this._ditheringIntensity === value) {\r\n            return;\r\n        }\r\n\r\n        this._ditheringIntensity = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    /** @internal */\r\n    @serialize()\r\n    public _skipFinalColorClamp = false;\r\n    /**\r\n     * If apply by post process is set to true, setting this to true will skip the final color clamp step in the fragment shader\r\n     * Applies to PBR materials.\r\n     */\r\n    public get skipFinalColorClamp(): boolean {\r\n        return this._skipFinalColorClamp;\r\n    }\r\n    /**\r\n     * If apply by post process is set to true, setting this to true will skip the final color clamp step in the fragment shader\r\n     * Applies to PBR materials.\r\n     */\r\n    public set skipFinalColorClamp(value: boolean) {\r\n        if (this._skipFinalColorClamp === value) {\r\n            return;\r\n        }\r\n\r\n        this._skipFinalColorClamp = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    /** @internal */\r\n    @serialize()\r\n    public _applyByPostProcess = false;\r\n    /**\r\n     * Gets whether the image processing is applied through a post process or not.\r\n     */\r\n    public get applyByPostProcess(): boolean {\r\n        return this._applyByPostProcess;\r\n    }\r\n    /**\r\n     * Sets whether the image processing is applied through a post process or not.\r\n     */\r\n    public set applyByPostProcess(value: boolean) {\r\n        if (this._applyByPostProcess === value) {\r\n            return;\r\n        }\r\n\r\n        this._applyByPostProcess = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    @serialize()\r\n    private _isEnabled = true;\r\n    /**\r\n     * Gets whether the image processing is enabled or not.\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the image processing is enabled or not.\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        if (this._isEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._isEnabled = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    /**\r\n     * Width of the output texture used in the post process. If not provided, uses the width of the screen.\r\n     */\r\n    @serialize()\r\n    public outputTextureWidth = 0;\r\n\r\n    /**\r\n     * Height of the output texture used in the post process. If not provided, uses the height of the screen.\r\n     */\r\n    @serialize()\r\n    public outputTextureHeight = 0;\r\n\r\n    /**\r\n     * An event triggered when the configuration changes and requires Shader to Update some parameters.\r\n     */\r\n    public onUpdateParameters = new Observable<ImageProcessingConfiguration>();\r\n\r\n    /**\r\n     * Method called each time the image processing information changes requires to recompile the effect.\r\n     */\r\n    protected _updateParameters(): void {\r\n        this.onUpdateParameters.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name.\r\n     * @returns \"ImageProcessingConfiguration\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"ImageProcessingConfiguration\";\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of uniforms associated with the Image Processing effects.\r\n     * @param uniforms The list of uniforms used in the effect\r\n     * @param defines the list of defines currently in use\r\n     */\r\n    public static PrepareUniforms: (uniforms: string[], defines: IImageProcessingConfigurationDefines) => void = PrepareUniformsForImageProcessing;\r\n\r\n    /**\r\n     * Prepare the list of samplers associated with the Image Processing effects.\r\n     * @param samplersList The list of uniforms used in the effect\r\n     * @param defines the list of defines currently in use\r\n     */\r\n    public static PrepareSamplers: (samplersList: string[], defines: IImageProcessingConfigurationDefines) => void = PrepareSamplersForImageProcessing;\r\n\r\n    /**\r\n     * Prepare the list of defines associated to the shader.\r\n     * @param defines the list of defines to complete\r\n     * @param forPostProcess Define if we are currently in post process mode or not\r\n     */\r\n    public prepareDefines(defines: IImageProcessingConfigurationDefines, forPostProcess = false): void {\r\n        if (forPostProcess !== this.applyByPostProcess || !this._isEnabled) {\r\n            defines.WHITEBALANCE = false;\r\n            defines.VIGNETTE = false;\r\n            defines.TONEMAPPING = 0;\r\n            defines.CONTRAST = false;\r\n            defines.EXPOSURE = false;\r\n            defines.COLORCURVES = false;\r\n            defines.COLORGRADING = false;\r\n            defines.COLORGRADING3D = false;\r\n            defines.DITHER = false;\r\n            defines.IMAGEPROCESSING = false;\r\n            defines.SKIPFINALCOLORCLAMP = this.skipFinalColorClamp;\r\n            defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess && this._isEnabled;\r\n            return;\r\n        }\r\n\r\n        defines.WHITEBALANCE = this._whiteBalanceEnabled;\r\n        defines.VIGNETTE = this.vignetteEnabled;\r\n        defines.VIGNETTEBLENDMODEMULTIPLY = this.vignetteBlendMode === ImageProcessingConfiguration._VIGNETTEMODE_MULTIPLY;\r\n        defines.VIGNETTEBLENDMODEOPAQUE = !defines.VIGNETTEBLENDMODEMULTIPLY;\r\n\r\n        if (!this._toneMappingEnabled) {\r\n            defines.TONEMAPPING = 0;\r\n        } else {\r\n            switch (this._toneMappingType) {\r\n                case ImageProcessingConfiguration.TONEMAPPING_KHR_PBR_NEUTRAL:\r\n                    defines.TONEMAPPING = 3;\r\n                    break;\r\n                case ImageProcessingConfiguration.TONEMAPPING_ACES:\r\n                    defines.TONEMAPPING = 2;\r\n                    break;\r\n                default:\r\n                    defines.TONEMAPPING = 1;\r\n                    break;\r\n            }\r\n        }\r\n\r\n        defines.CONTRAST = this.contrast !== 1.0;\r\n        defines.EXPOSURE = this.exposure !== 1.0;\r\n        defines.COLORCURVES = this.colorCurvesEnabled && !!this.colorCurves;\r\n        defines.COLORGRADING = this.colorGradingEnabled && !!this.colorGradingTexture;\r\n        if (defines.COLORGRADING) {\r\n            defines.COLORGRADING3D = this.colorGradingTexture!.is3D;\r\n        } else {\r\n            defines.COLORGRADING3D = false;\r\n        }\r\n        defines.SAMPLER3DGREENDEPTH = this.colorGradingWithGreenDepth;\r\n        defines.SAMPLER3DBGRMAP = this.colorGradingBGR;\r\n        defines.DITHER = this._ditheringEnabled;\r\n        defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;\r\n        defines.SKIPFINALCOLORCLAMP = this.skipFinalColorClamp;\r\n        defines.IMAGEPROCESSING =\r\n            defines.WHITEBALANCE ||\r\n            defines.VIGNETTE ||\r\n            !!defines.TONEMAPPING ||\r\n            defines.CONTRAST ||\r\n            defines.EXPOSURE ||\r\n            defines.COLORCURVES ||\r\n            defines.COLORGRADING ||\r\n            defines.DITHER;\r\n    }\r\n\r\n    /**\r\n     * Returns true if all the image processing information are ready.\r\n     * @returns True if ready, otherwise, false\r\n     */\r\n    public isReady() {\r\n        // Color Grading texture can not be none blocking.\r\n        return !this.colorGradingEnabled || !this.colorGradingTexture || this.colorGradingTexture.isReady();\r\n    }\r\n\r\n    /**\r\n     * Binds the image processing to the shader.\r\n     * @param effect The effect to bind to\r\n     * @param overrideAspectRatio Override the aspect ratio of the effect\r\n     */\r\n    public bind(effect: Effect, overrideAspectRatio?: number): void {\r\n        // White Balance\r\n        if (this._whiteBalanceEnabled) {\r\n            effect.setMatrix3x3(\"whiteBalanceMatrix\", this._getWhiteBalanceMatrix());\r\n        }\r\n\r\n        // Color Curves\r\n        if (this._colorCurvesEnabled && this.colorCurves) {\r\n            ColorCurvesBind(this.colorCurves, effect);\r\n        }\r\n\r\n        // Vignette and dither handled together due to common uniform.\r\n        if (this._vignetteEnabled || this._ditheringEnabled) {\r\n            const inverseWidth = 1 / (this.outputTextureWidth || effect.getEngine().getRenderWidth());\r\n            const inverseHeight = 1 / (this.outputTextureHeight || effect.getEngine().getRenderHeight());\r\n            effect.setFloat2(\"vInverseScreenSize\", inverseWidth, inverseHeight);\r\n\r\n            if (this._ditheringEnabled) {\r\n                effect.setFloat(\"ditherIntensity\", 0.5 * this._ditheringIntensity);\r\n            }\r\n\r\n            if (this._vignetteEnabled) {\r\n                const aspectRatio = overrideAspectRatio != null ? overrideAspectRatio : inverseHeight / inverseWidth;\r\n\r\n                let vignetteScaleY = Math.tan(this.vignetteCameraFov * 0.5);\r\n                let vignetteScaleX = vignetteScaleY * aspectRatio;\r\n\r\n                const vignetteScaleGeometricMean = Math.sqrt(vignetteScaleX * vignetteScaleY);\r\n                vignetteScaleX = Mix(vignetteScaleX, vignetteScaleGeometricMean, this.vignetteStretch);\r\n                vignetteScaleY = Mix(vignetteScaleY, vignetteScaleGeometricMean, this.vignetteStretch);\r\n\r\n                effect.setFloat4(\"vignetteSettings1\", vignetteScaleX, vignetteScaleY, -vignetteScaleX * this.vignetteCenterX, -vignetteScaleY * this.vignetteCenterY);\r\n\r\n                const vignettePower = -2.0 * this.vignetteWeight;\r\n                effect.setFloat4(\"vignetteSettings2\", this.vignetteColor.r, this.vignetteColor.g, this.vignetteColor.b, vignettePower);\r\n            }\r\n        }\r\n\r\n        // Exposure\r\n        effect.setFloat(\"exposureLinear\", this.exposure);\r\n\r\n        // Contrast\r\n        effect.setFloat(\"contrast\", this.contrast);\r\n\r\n        // Color transform settings\r\n        if (this.colorGradingTexture) {\r\n            effect.setTexture(\"txColorTransform\", this.colorGradingTexture);\r\n            const textureSize = this.colorGradingTexture.getSize().height;\r\n\r\n            effect.setFloat4(\r\n                \"colorTransformSettings\",\r\n                (textureSize - 1) / textureSize, // textureScale\r\n                0.5 / textureSize, // textureOffset\r\n                textureSize, // textureSize\r\n                this.colorGradingTexture.level // weight\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clones the current image processing instance.\r\n     * @returns The cloned image processing\r\n     */\r\n    public clone(): ImageProcessingConfiguration {\r\n        return SerializationHelper.Clone(() => new ImageProcessingConfiguration(), this);\r\n    }\r\n\r\n    /**\r\n     * Serializes the current image processing instance to a json representation.\r\n     * @returns a JSON representation\r\n     */\r\n    public serialize(): any {\r\n        return SerializationHelper.Serialize(this);\r\n    }\r\n\r\n    // Static constants associated to the image processing.\r\n    private static _VIGNETTEMODE_MULTIPLY = 0;\r\n    private static _VIGNETTEMODE_OPAQUE = 1;\r\n\r\n    /**\r\n     * Used to apply the vignette as a mix with the pixel color.\r\n     */\r\n    public static get VIGNETTEMODE_MULTIPLY(): number {\r\n        return this._VIGNETTEMODE_MULTIPLY;\r\n    }\r\n\r\n    /**\r\n     * Used to apply the vignette as a replacement of the pixel color.\r\n     */\r\n    public static get VIGNETTEMODE_OPAQUE(): number {\r\n        return this._VIGNETTEMODE_OPAQUE;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n\r\n/**\r\n * Parses the image processing from a json representation.\r\n * @param source the JSON source to parse\r\n * @returns The parsed image processing\r\n */\r\nexport function ImageProcessingConfigurationParse(source: any): ImageProcessingConfiguration {\r\n    const parsed = SerializationHelper.Parse(() => new ImageProcessingConfiguration(), source, null, null);\r\n    // Backward compatibility\r\n    if (source.vignetteCentreX !== undefined) {\r\n        parsed.vignetteCenterX = source.vignetteCentreX;\r\n    }\r\n    if (source.vignetteCentreY !== undefined) {\r\n        parsed.vignetteCenterY = source.vignetteCentreY;\r\n    }\r\n\r\n    return parsed;\r\n}\r\n\r\n/**\r\n * Register side effects for imageProcessingConfiguration.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterImageProcessingConfiguration(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // References the dependencies.\r\n    ImageProcessingConfiguration.Parse = ImageProcessingConfigurationParse;\r\n\r\n    SerializationHelper._ImageProcessingConfigurationParser = ImageProcessingConfigurationParse;\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.ImageProcessingConfiguration\", ImageProcessingConfiguration);\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type Nullable, type FloatArray } from \"../types\";\r\nimport { type IMatrixLike, type IVector3Like, type IVector4Like, type IColor3Like, type IColor4Like } from \"../Maths/math.like\";\r\nimport { type Effect } from \"./effect\";\r\nimport { type ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type InternalTexture } from \"./Textures/internalTexture\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type WebGPUDrawContext } from \"../Engines/WebGPU/webgpuDrawContext\";\r\n\r\n/**\r\n * Uniform buffer objects.\r\n *\r\n * Handles blocks of uniform on the GPU.\r\n *\r\n * If WebGL 2 is not available, this class falls back on traditional setUniformXXX calls.\r\n *\r\n * For more information, please refer to :\r\n * https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object\r\n */\r\nexport class UniformBuffer {\r\n    private _engine: AbstractEngine;\r\n    private _buffer: Nullable<DataBuffer>;\r\n    private _buffers: Array<[DataBuffer, Float32Array | undefined]>;\r\n    private _bufferIndex: number;\r\n    private _bufferUpdatedLastFrame: boolean;\r\n    private _createBufferOnWrite: boolean;\r\n    private _data: number[];\r\n    private _bufferData: Float32Array;\r\n    private _dynamic: boolean;\r\n    private _uniformLocations: { [key: string]: number };\r\n    private _uniformSizes: { [key: string]: number };\r\n    private _uniformArraySizes: { [key: string]: { strideSize: number; arraySize: number } };\r\n    private _uniformNames: string[] = [];\r\n    private _uniformLocationPointer: number;\r\n    private _needSync: boolean;\r\n    private _noUBO: boolean;\r\n    private _currentEffect: Effect;\r\n    private _currentEffectName: string;\r\n    private _name: string;\r\n    private _currentFrameId: number;\r\n    private _trackUBOsInFrame: boolean;\r\n    // Owner-keyed slots (trackUBOsInFrame only): draw context -> index in _buffers, last frame each slot was flushed in,\r\n    // number of live owners, and slots no longer owned (released by a disposed context, or created for a same-frame overflow)\r\n    private _slotByOwner: WeakMap<WebGPUDrawContext, number>;\r\n    // Reverse registrations hold the backlink arrays, not their draw contexts. This allows\r\n    // eager reciprocal teardown without making the weak owner keys strongly reachable.\r\n    private _ownerListsBySlot: Map<number, UniformBuffer[]>;\r\n    private _slotFrameId: number[];\r\n    private _ownerCount: number;\r\n    private _freeSlots: number[];\r\n    // Generation of the staging data (_bufferData): bumped on every write that changes it. Each owner-keyed slot\r\n    // remembers the generation it was last flushed with, so a draw whose values did not change since that flush\r\n    // costs one integer compare instead of a full compare of the block against the slot's shadow.\r\n    private _dataGeneration: number;\r\n    private _slotGeneration: number[];\r\n\r\n    // Pool for avoiding memory leaks\r\n    private static _MAX_UNIFORM_SIZE = 256;\r\n    private static _TempBuffer = new Float32Array(UniformBuffer._MAX_UNIFORM_SIZE);\r\n    private static _TempBufferInt32View = new Int32Array(UniformBuffer._TempBuffer.buffer);\r\n    private static _TempBufferUInt32View = new Uint32Array(UniformBuffer._TempBuffer.buffer);\r\n\r\n    /**\r\n     * Lambda to Update a 3x3 Matrix in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateMatrix3x3: (name: string, matrix: Float32Array) => void;\r\n\r\n    /**\r\n     * Lambda to Update a 2x2 Matrix in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateMatrix2x2: (name: string, matrix: Float32Array) => void;\r\n\r\n    /**\r\n     * Lambda to Update a single float in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateFloat: (name: string, x: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec2 of float in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateFloat2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec3 of float in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateFloat3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec4 of float in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateFloat4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update an array of float in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateFloatArray: (name: string, array: Float32Array, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update an array of number in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateArray: (name: string, array: number[]) => void;\r\n\r\n    /**\r\n     * Lambda to Update an array of number in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateIntArray: (name: string, array: Int32Array) => void;\r\n\r\n    /**\r\n     * Lambda to Update an array of number in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateUIntArray: (name: string, array: Uint32Array) => void;\r\n\r\n    /**\r\n     * Lambda to Update a 4x4 Matrix in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateMatrix: (name: string, mat: IMatrixLike) => void;\r\n\r\n    /**\r\n     * Lambda to Update an array of 4x4 Matrix in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateMatrices: (name: string, mat: Float32Array) => void;\r\n\r\n    /**\r\n     * Lambda to Update vec3 of float from a Vector in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateVector3: (name: string, vector: IVector3Like) => void;\r\n\r\n    /**\r\n     * Lambda to Update vec4 of float from a Vector in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateVector4: (name: string, vector: IVector4Like) => void;\r\n\r\n    /**\r\n     * Lambda to Update vec3 of float from a Color in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateColor3: (name: string, color: IColor3Like, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update vec4 of float from a Color in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateColor4: (name: string, color: IColor3Like, alpha: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update vec4 of float from a Color in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateDirectColor4: (name: string, color: IColor4Like, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a int a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateInt: (name: string, x: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec2 of int in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateInt2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec3 of int in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateInt3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec4 of int in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateInt4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a unsigned int a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateUInt: (name: string, x: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec2 of unsigned int in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateUInt2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec3 of unsigned int in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateUInt3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Lambda to Update a vec4 of unsigned int in a uniform buffer.\r\n     * This is dynamic to allow compat with webgl 1 and 2.\r\n     * You will need to pass the name of the uniform as well as the value.\r\n     */\r\n    public updateUInt4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n    /**\r\n     * Instantiates a new Uniform buffer objects.\r\n     *\r\n     * Handles blocks of uniform on the GPU.\r\n     *\r\n     * If WebGL 2 is not available, this class falls back on traditional setUniformXXX calls.\r\n     *\r\n     * For more information, please refer to :\r\n     * @see https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object\r\n     * @param engine Define the engine the buffer is associated with\r\n     * @param data Define the data contained in the buffer\r\n     * @param dynamic Define if the buffer is updatable\r\n     * @param name to assign to the buffer (debugging purpose)\r\n     * @param forceNoUniformBuffer define that this object must not rely on UBO objects\r\n     * @param trackUBOsInFrame define if the UBOs should be tracked in the frame (default: undefined - will use the value from Engine._features.trackUbosInFrame)\r\n     */\r\n    constructor(engine: AbstractEngine, data?: number[], dynamic = false, name?: string, forceNoUniformBuffer = false, trackUBOsInFrame?: boolean) {\r\n        this._engine = engine;\r\n        this._noUBO = !engine.supportsUniformBuffers || forceNoUniformBuffer;\r\n        this._dynamic = dynamic;\r\n        this._name = name ?? \"no-name\";\r\n\r\n        this._data = data || [];\r\n\r\n        this._uniformLocations = {};\r\n        this._uniformSizes = {};\r\n        this._uniformArraySizes = {};\r\n        this._uniformLocationPointer = 0;\r\n        this._needSync = false;\r\n        this._dataGeneration = 0;\r\n        this._trackUBOsInFrame = false;\r\n\r\n        if ((trackUBOsInFrame === undefined && this._engine._features.trackUbosInFrame) || trackUBOsInFrame === true) {\r\n            this._buffers = [];\r\n            this._bufferIndex = -1;\r\n            this._bufferUpdatedLastFrame = false;\r\n            this._createBufferOnWrite = false;\r\n            this._currentFrameId = 0;\r\n            this._trackUBOsInFrame = true;\r\n            this._resetOwnerSlots();\r\n        }\r\n\r\n        if (this._noUBO) {\r\n            this.updateMatrix3x3 = this._updateMatrix3x3ForEffect;\r\n            this.updateMatrix2x2 = this._updateMatrix2x2ForEffect;\r\n            this.updateFloat = this._updateFloatForEffect;\r\n            this.updateFloat2 = this._updateFloat2ForEffect;\r\n            this.updateFloat3 = this._updateFloat3ForEffect;\r\n            this.updateFloat4 = this._updateFloat4ForEffect;\r\n            this.updateFloatArray = this._updateFloatArrayForEffect;\r\n            this.updateArray = this._updateArrayForEffect;\r\n            this.updateIntArray = this._updateIntArrayForEffect;\r\n            this.updateUIntArray = this._updateUIntArrayForEffect;\r\n            this.updateMatrix = this._updateMatrixForEffect;\r\n            this.updateMatrices = this._updateMatricesForEffect;\r\n            this.updateVector3 = this._updateVector3ForEffect;\r\n            this.updateVector4 = this._updateVector4ForEffect;\r\n            this.updateColor3 = this._updateColor3ForEffect;\r\n            this.updateColor4 = this._updateColor4ForEffect;\r\n            this.updateDirectColor4 = this._updateDirectColor4ForEffect;\r\n            this.updateInt = this._updateIntForEffect;\r\n            this.updateInt2 = this._updateInt2ForEffect;\r\n            this.updateInt3 = this._updateInt3ForEffect;\r\n            this.updateInt4 = this._updateInt4ForEffect;\r\n            this.updateUInt = this._updateUIntForEffect;\r\n            this.updateUInt2 = this._updateUInt2ForEffect;\r\n            this.updateUInt3 = this._updateUInt3ForEffect;\r\n            this.updateUInt4 = this._updateUInt4ForEffect;\r\n        } else {\r\n            this._engine._uniformBuffers.push(this);\r\n\r\n            this.updateMatrix3x3 = this._updateMatrix3x3ForUniform;\r\n            this.updateMatrix2x2 = this._updateMatrix2x2ForUniform;\r\n            this.updateFloat = this._updateFloatForUniform;\r\n            this.updateFloat2 = this._updateFloat2ForUniform;\r\n            this.updateFloat3 = this._updateFloat3ForUniform;\r\n            this.updateFloat4 = this._updateFloat4ForUniform;\r\n            this.updateFloatArray = this._updateFloatArrayForUniform;\r\n            this.updateArray = this._updateArrayForUniform;\r\n            this.updateIntArray = this._updateIntArrayForUniform;\r\n            this.updateUIntArray = this._updateUIntArrayForUniform;\r\n            this.updateMatrix = this._updateMatrixForUniform;\r\n            this.updateMatrices = this._updateMatricesForUniform;\r\n            this.updateVector3 = this._updateVector3ForUniform;\r\n            this.updateVector4 = this._updateVector4ForUniform;\r\n            this.updateColor3 = this._updateColor3ForUniform;\r\n            this.updateColor4 = this._updateColor4ForUniform;\r\n            this.updateDirectColor4 = this._updateDirectColor4ForUniform;\r\n            this.updateInt = this._updateIntForUniform;\r\n            this.updateInt2 = this._updateInt2ForUniform;\r\n            this.updateInt3 = this._updateInt3ForUniform;\r\n            this.updateInt4 = this._updateInt4ForUniform;\r\n            this.updateUInt = this._updateUIntForUniform;\r\n            this.updateUInt2 = this._updateUInt2ForUniform;\r\n            this.updateUInt3 = this._updateUInt3ForUniform;\r\n            this.updateUInt4 = this._updateUInt4ForUniform;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates if the buffer is using the WebGL2 UBO implementation,\r\n     * or just falling back on setUniformXXX calls.\r\n     */\r\n    public get useUbo(): boolean {\r\n        return !this._noUBO;\r\n    }\r\n\r\n    /**\r\n     * Indicates if the WebGL underlying uniform buffer is in sync\r\n     * with the javascript cache data.\r\n     */\r\n    public get isSync(): boolean {\r\n        return !this._needSync;\r\n    }\r\n\r\n    /**\r\n     * Indicates if the WebGL underlying uniform buffer is dynamic.\r\n     * Also, a dynamic UniformBuffer will disable cache verification and always\r\n     * update the underlying WebGL uniform buffer to the GPU.\r\n     * @returns if Dynamic, otherwise false\r\n     */\r\n    public isDynamic(): boolean {\r\n        return this._dynamic;\r\n    }\r\n\r\n    /**\r\n     * The data cache on JS side.\r\n     * @returns the underlying data as a float array\r\n     */\r\n    public getData(): Float32Array {\r\n        return this._bufferData;\r\n    }\r\n\r\n    /**\r\n     * The underlying WebGL Uniform buffer.\r\n     * @returns the webgl buffer\r\n     */\r\n    public getBuffer(): Nullable<DataBuffer> {\r\n        return this._buffer;\r\n    }\r\n\r\n    /**\r\n     * The names of the uniforms in the buffer.\r\n     * @returns an array of uniform names\r\n     */\r\n    public getUniformNames(): string[] {\r\n        return this._uniformNames;\r\n    }\r\n\r\n    /**\r\n     * std140 layout specifies how to align data within an UBO structure.\r\n     * See https://khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159\r\n     * for specs.\r\n     * @param size\r\n     */\r\n    private _fillAlignment(size: number) {\r\n        // This code has been simplified because we only use floats, vectors of 1, 2, 3, 4 components\r\n        // and 4x4 matrices\r\n        // TODO : change if other types are used\r\n\r\n        let alignment;\r\n        if (size <= 2) {\r\n            alignment = size;\r\n        } else {\r\n            alignment = 4;\r\n        }\r\n\r\n        if (this._uniformLocationPointer % alignment !== 0) {\r\n            const oldPointer = this._uniformLocationPointer;\r\n            this._uniformLocationPointer += alignment - (this._uniformLocationPointer % alignment);\r\n            const diff = this._uniformLocationPointer - oldPointer;\r\n\r\n            for (let i = 0; i < diff; i++) {\r\n                this._data.push(0);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds an uniform in the buffer.\r\n     * Warning : the subsequents calls of this function must be in the same order as declared in the shader\r\n     * for the layout to be correct ! The addUniform function only handles types like float, vec2, vec3, vec4, mat4,\r\n     * meaning size=1,2,3,4 or 16. It does not handle struct types.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param size Data size, or data directly.\r\n     * @param arraySize The number of elements in the array, 0 if not an array.\r\n     */\r\n    public addUniform(name: string, size: number | number[], arraySize = 0) {\r\n        if (arraySize > 0 && typeof size === \"number\") {\r\n            // Keep track of stride for `updateFloatArray`\r\n            this._uniformArraySizes[name] = { strideSize: size, arraySize };\r\n        }\r\n\r\n        if (this._uniformLocations[name] !== undefined) {\r\n            // Already existing uniform\r\n            return;\r\n        }\r\n\r\n        this._uniformNames.push(name);\r\n\r\n        if (this._noUBO) {\r\n            return;\r\n        }\r\n\r\n        // This function must be called in the order of the shader layout !\r\n        // size can be the size of the uniform, or data directly\r\n        let data;\r\n\r\n        // std140 FTW...\r\n        if (arraySize > 0) {\r\n            if (size instanceof Array) {\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"addUniform should not be use with Array in UBO: \" + name;\r\n            }\r\n\r\n            this._fillAlignment(4);\r\n\r\n            if (size == 16) {\r\n                size = size * arraySize;\r\n            } else {\r\n                const perElementPadding = 4 - size;\r\n                const totalPadding = perElementPadding * arraySize;\r\n                size = size * arraySize + totalPadding;\r\n            }\r\n\r\n            data = [];\r\n            // Fill with zeros\r\n            for (let i = 0; i < size; i++) {\r\n                data.push(0);\r\n            }\r\n        } else {\r\n            if (size instanceof Array) {\r\n                data = size;\r\n                size = data.length;\r\n            } else {\r\n                data = [];\r\n\r\n                // Fill with zeros\r\n                for (let i = 0; i < size; i++) {\r\n                    data.push(0);\r\n                }\r\n            }\r\n            this._fillAlignment(size);\r\n        }\r\n\r\n        this._uniformSizes[name] = size;\r\n        this._uniformLocations[name] = this._uniformLocationPointer;\r\n        this._uniformLocationPointer += size;\r\n\r\n        for (let i = 0; i < size; i++) {\r\n            this._data.push(data[i]);\r\n        }\r\n\r\n        this._needSync = true;\r\n    }\r\n\r\n    /**\r\n     * Adds a Matrix 4x4 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param mat A 4x4 matrix.\r\n     */\r\n    public addMatrix(name: string, mat: IMatrixLike) {\r\n        this.addUniform(name, Array.prototype.slice.call(mat.asArray()));\r\n    }\r\n\r\n    /**\r\n     * Adds a vec2 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param x Define the x component value of the vec2\r\n     * @param y Define the y component value of the vec2\r\n     */\r\n    public addFloat2(name: string, x: number, y: number) {\r\n        const temp = [x, y];\r\n        this.addUniform(name, temp);\r\n    }\r\n\r\n    /**\r\n     * Adds a vec3 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param x Define the x component value of the vec3\r\n     * @param y Define the y component value of the vec3\r\n     * @param z Define the z component value of the vec3\r\n     */\r\n    public addFloat3(name: string, x: number, y: number, z: number) {\r\n        const temp = [x, y, z];\r\n        this.addUniform(name, temp);\r\n    }\r\n\r\n    /**\r\n     * Adds a vec3 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param color Define the vec3 from a Color\r\n     */\r\n    public addColor3(name: string, color: IColor3Like) {\r\n        const temp = [color.r, color.g, color.b];\r\n        this.addUniform(name, temp);\r\n    }\r\n\r\n    /**\r\n     * Adds a vec4 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param color Define the rgb components from a Color\r\n     * @param alpha Define the a component of the vec4\r\n     */\r\n    public addColor4(name: string, color: IColor3Like, alpha: number) {\r\n        const temp = [color.r, color.g, color.b, alpha];\r\n        this.addUniform(name, temp);\r\n    }\r\n\r\n    /**\r\n     * Adds a vec3 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     * @param vector Define the vec3 components from a Vector\r\n     */\r\n    public addVector3(name: string, vector: IVector3Like) {\r\n        const temp = [vector.x, vector.y, vector.z];\r\n        this.addUniform(name, temp);\r\n    }\r\n\r\n    /**\r\n     * Adds a Matrix 3x3 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     */\r\n    public addMatrix3x3(name: string) {\r\n        this.addUniform(name, 12);\r\n    }\r\n\r\n    /**\r\n     * Adds a Matrix 2x2 to the uniform buffer.\r\n     * @param name Name of the uniform, as used in the uniform block in the shader.\r\n     */\r\n    public addMatrix2x2(name: string) {\r\n        this.addUniform(name, 8);\r\n    }\r\n\r\n    /**\r\n     * Effectively creates the WebGL Uniform Buffer, once layout is completed with `addUniform`.\r\n     */\r\n    public create(): void {\r\n        if (this._noUBO) {\r\n            return;\r\n        }\r\n        if (this._buffer) {\r\n            return; // nothing to do\r\n        }\r\n\r\n        // See spec, alignment must be filled as a vec4\r\n        this._fillAlignment(4);\r\n        this._bufferData = new Float32Array(this._data);\r\n        this._dataGeneration++;\r\n\r\n        this._rebuild();\r\n\r\n        this._needSync = true;\r\n    }\r\n\r\n    // The result of this method is used for debugging purpose, as part of the buffer name\r\n    // It is meant to more easily know what this buffer is about when debugging\r\n    // Some buffers can have a lot of uniforms (several dozens), so the method only returns the first 10 of them\r\n    // (should be enough to understand what the buffer is for)\r\n    private _getNamesDebug() {\r\n        const names = [];\r\n        let i = 0;\r\n        for (const name in this._uniformLocations) {\r\n            names.push(name);\r\n            if (++i === 10) {\r\n                break;\r\n            }\r\n        }\r\n        return names.join(\",\");\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        if (this._noUBO || !this._bufferData) {\r\n            return;\r\n        }\r\n\r\n        if (this._dynamic) {\r\n            this._buffer = this._engine.createDynamicUniformBuffer(this._bufferData, this._name + \"_UniformList:\" + this._getNamesDebug());\r\n        } else {\r\n            this._buffer = this._engine.createUniformBuffer(this._bufferData, this._name + \"_UniformList:\" + this._getNamesDebug());\r\n        }\r\n\r\n        if (this._trackUBOsInFrame) {\r\n            this._buffers.push([this._buffer, this._engine._features.checkUbosContentBeforeUpload ? this._bufferData.slice() : undefined]);\r\n            this._bufferIndex = this._buffers.length - 1;\r\n            this._createBufferOnWrite = false;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuildAfterContextLost(): void {\r\n        if (this._trackUBOsInFrame) {\r\n            this._buffers = [];\r\n            this._currentFrameId = 0;\r\n            this._resetOwnerSlots();\r\n        }\r\n        this._rebuild();\r\n    }\r\n\r\n    private _resetOwnerSlots(): void {\r\n        if (this._ownerListsBySlot) {\r\n            for (const list of this._ownerListsBySlot.values()) {\r\n                this._removeOwnerBacklink(list);\r\n            }\r\n        }\r\n        this._ownerListsBySlot = new Map();\r\n        this._slotByOwner = new WeakMap();\r\n        this._slotFrameId = [];\r\n        this._ownerCount = 0;\r\n        this._freeSlots = [];\r\n        this._slotGeneration = [];\r\n    }\r\n\r\n    /** @internal */\r\n    public get _numBuffers(): number {\r\n        return this._buffers.length;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _indexBuffer(): number {\r\n        return this._bufferIndex;\r\n    }\r\n\r\n    /** Gets or sets the name of this buffer */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    /** Gets the current effect */\r\n    public get currentEffect(): Nullable<Effect> {\r\n        return this._currentEffect;\r\n    }\r\n\r\n    private _buffersEqual(buf1: Float32Array, buf2: Float32Array): boolean {\r\n        for (let i = 0; i < buf1.length; ++i) {\r\n            if (buf1[i] !== buf2[i]) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private _copyBuffer(src: Float32Array, dst: Float32Array): void {\r\n        for (let i = 0; i < src.length; ++i) {\r\n            dst[i] = src[i];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the WebGL Uniform Buffer on the GPU.\r\n     * If the `dynamic` flag is set to true, no cache comparison is done.\r\n     * Otherwise, the buffer will be updated only if the cache differs.\r\n     */\r\n    public update(): void {\r\n        if (this._noUBO) {\r\n            return;\r\n        }\r\n\r\n        this.bindUniformBuffer();\r\n\r\n        if (!this._buffer) {\r\n            this.create();\r\n            return;\r\n        }\r\n\r\n        if (!this._dynamic && !this._needSync) {\r\n            this._createBufferOnWrite = this._trackUBOsInFrame;\r\n            return;\r\n        }\r\n\r\n        if (this._buffers && this._buffers.length > 1 && this._buffers[this._bufferIndex][1]) {\r\n            if (this._buffersEqual(this._bufferData, this._buffers[this._bufferIndex][1]!)) {\r\n                this._needSync = false;\r\n                this._createBufferOnWrite = this._trackUBOsInFrame;\r\n                return;\r\n            } else {\r\n                this._copyBuffer(this._bufferData, this._buffers[this._bufferIndex][1]!);\r\n            }\r\n        }\r\n\r\n        this._bufferUpdatedLastFrame = true;\r\n\r\n        this._engine.updateUniformBuffer(this._buffer, this._bufferData);\r\n\r\n        this._needSync = false;\r\n        this._createBufferOnWrite = this._trackUBOsInFrame;\r\n    }\r\n\r\n    /**\r\n     * Flushes the current uniform values into the GPU buffer owned by the draw context.\r\n     * Invariant: `_buffers[i][1]` (the CPU shadow) always holds what the GPU buffer of slot i contains.\r\n     * @param owner the draw context on behalf of which the update is done\r\n     * @internal\r\n     */\r\n    public _updateOwnerKeyed(owner: WebGPUDrawContext): void {\r\n        if (this._noUBO || !this._trackUBOsInFrame) {\r\n            this.update();\r\n            return;\r\n        }\r\n        if (!this._buffer) {\r\n            this.create(); // _rebuild pushes slot 0, created from _bufferData, with a shadow copy of it\r\n        }\r\n\r\n        this._checkNewFrame();\r\n\r\n        let idx = this._slotByOwner.get(owner);\r\n        if (idx === undefined) {\r\n            if (this._ownerCount === 0 && this._buffers.length === 1 && this._freeSlots.length === 0) {\r\n                // the slot create() made and nobody has owned yet: hand it to the first owner instead of leaving it unused.\r\n                // (Once an owner has released it, it is in _freeSlots and must be taken from there, or two owners could share it.)\r\n                idx = 0;\r\n            } else {\r\n                idx = this._takeFreeSlot(true);\r\n            }\r\n            this._slotByOwner.set(owner, idx);\r\n            this._ownerCount++;\r\n            if (!owner._uniformBuffersWithOwnedSlot) {\r\n                owner._uniformBuffersWithOwnedSlot = [];\r\n            }\r\n            owner._uniformBuffersWithOwnedSlot.push(this);\r\n            this._ownerListsBySlot.set(idx, owner._uniformBuffersWithOwnedSlot);\r\n        }\r\n\r\n        if (this._slotGeneration[idx] === this._dataGeneration) {\r\n            // The slot was last flushed with exactly the current data and nothing has been written since: nothing to\r\n            // compare, nothing to upload, and no same-frame conflict is possible either (same bytes).\r\n            this._bufferIndex = idx;\r\n            this._buffer = this._buffers[idx][0];\r\n            this.bindUniformBuffer();\r\n            this._slotFrameId[idx] = this._currentFrameId;\r\n            this._needSync = false;\r\n            this._createBufferOnWrite = false;\r\n            return;\r\n        }\r\n\r\n        const owned = this._buffers[idx][1];\r\n        if (this._slotFrameId[idx] === this._currentFrameId && owned && !this._buffersEqual(this._bufferData, owned)) {\r\n            // The same context flushes a second time in the same frame with different values: the GPU has not consumed the\r\n            // first values yet, so they must not be overwritten. Use a slot nobody owns for this flush.\r\n            idx = this._takeFreeSlot(false);\r\n        }\r\n\r\n        this._bufferIndex = idx;\r\n        this._buffer = this._buffers[idx][0];\r\n        this.bindUniformBuffer();\r\n\r\n        const shadow = this._buffers[idx][1];\r\n        if (!shadow || !this._buffersEqual(this._bufferData, shadow)) {\r\n            if (shadow) {\r\n                this._copyBuffer(this._bufferData, shadow);\r\n            }\r\n            this._bufferUpdatedLastFrame = true;\r\n            this._engine.updateUniformBuffer(this._buffer, this._bufferData);\r\n        }\r\n\r\n        this._slotFrameId[idx] = this._currentFrameId;\r\n        this._slotGeneration[idx] = this._dataGeneration;\r\n        this._needSync = false;\r\n        this._createBufferOnWrite = false; // slots are keyed on the owner, the updateXXX methods must never switch buffer\r\n    }\r\n\r\n    /**\r\n     * Gets a slot that is not owned by any draw context and has not been flushed in the current frame, creating one if needed.\r\n     * @param takeOwnership true to remove the slot from the free list (it is going to be owned by a context)\r\n     * @returns the slot index\r\n     */\r\n    private _takeFreeSlot(takeOwnership: boolean): number {\r\n        for (let i = 0; i < this._freeSlots.length; ++i) {\r\n            const idx = this._freeSlots[i];\r\n            if (this._slotFrameId[idx] !== this._currentFrameId) {\r\n                if (takeOwnership) {\r\n                    this._freeSlots[i] = this._freeSlots[this._freeSlots.length - 1];\r\n                    this._freeSlots.pop();\r\n                }\r\n                return idx;\r\n            }\r\n        }\r\n\r\n        this._rebuild();\r\n        const idx = this._buffers.length - 1;\r\n        if (!takeOwnership) {\r\n            this._freeSlots.push(idx);\r\n        }\r\n        return idx;\r\n    }\r\n\r\n    /**\r\n     * Releases the slot owned by a draw context (called when the context is disposed), so that another context can reuse it.\r\n     * @param owner the draw context\r\n     * @internal\r\n     */\r\n    public _releaseOwnerSlot(owner: WebGPUDrawContext): void {\r\n        const idx = this._slotByOwner?.get(owner);\r\n        if (idx === undefined) {\r\n            return;\r\n        }\r\n        this._slotByOwner.delete(owner);\r\n        const list = this._ownerListsBySlot.get(idx);\r\n        if (list) {\r\n            this._removeOwnerBacklink(list);\r\n            this._ownerListsBySlot.delete(idx);\r\n        }\r\n        this._ownerCount--;\r\n        // Keep _slotFrameId: a draw encoded earlier this frame may still need these bytes.\r\n        this._freeSlots.push(idx);\r\n    }\r\n\r\n    private _removeOwnerBacklink(list: UniformBuffer[]): void {\r\n        const index = list.indexOf(this);\r\n        if (index !== -1) {\r\n            list[index] = list[list.length - 1];\r\n            list.pop();\r\n        }\r\n    }\r\n\r\n    private _createNewBuffer() {\r\n        if (this._bufferIndex + 1 < this._buffers.length) {\r\n            this._bufferIndex++;\r\n            this._buffer = this._buffers[this._bufferIndex][0];\r\n            this._createBufferOnWrite = false;\r\n            this._needSync = true;\r\n        } else {\r\n            this._rebuild();\r\n        }\r\n    }\r\n\r\n    private _checkNewFrame(): void {\r\n        if (this._trackUBOsInFrame && this._currentFrameId !== this._engine.frameId) {\r\n            this._currentFrameId = this._engine.frameId;\r\n            this._createBufferOnWrite = false;\r\n            if (this._buffers && this._buffers.length > 0) {\r\n                if (this._buffers.length === 1) {\r\n                    this._needSync = !this._bufferUpdatedLastFrame;\r\n                } else {\r\n                    this._needSync = this._bufferIndex !== 0;\r\n                }\r\n                this._bufferIndex = 0;\r\n                this._buffer = this._buffers[this._bufferIndex][0];\r\n            } else {\r\n                this._bufferIndex = -1;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the value of an uniform. The `update` method must be called afterwards to make it effective in the GPU.\r\n     * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.\r\n     * @param data Define the flattened data\r\n     * @param size Define the size of the data.\r\n     */\r\n    public updateUniform(uniformName: string, data: FloatArray, size: number) {\r\n        this._checkNewFrame();\r\n\r\n        let location = this._uniformLocations[uniformName];\r\n        if (location === undefined) {\r\n            if (this._buffer) {\r\n                // Cannot add an uniform if the buffer is already created\r\n                Logger.Error(\"Cannot add an uniform after UBO has been created. uniformName=\" + uniformName);\r\n                return;\r\n            }\r\n            this.addUniform(uniformName, size);\r\n            location = this._uniformLocations[uniformName];\r\n        }\r\n\r\n        if (!this._buffer) {\r\n            this.create();\r\n        }\r\n\r\n        if (!this._dynamic) {\r\n            // Cache for static uniform buffers\r\n            let changed = false;\r\n\r\n            for (let i = 0; i < size; i++) {\r\n                // We are checking the matrix cache before calling updateUniform so we do not need to check it here\r\n                // Hence the test for size === 16 to simply commit the matrix values\r\n                if ((size === 16 && !this._engine._features.uniformBufferHardCheckMatrix) || this._bufferData[location + i] !== Math.fround(data[i])) {\r\n                    changed = true;\r\n                    if (this._createBufferOnWrite) {\r\n                        this._createNewBuffer();\r\n                    }\r\n                    this._bufferData[location + i] = data[i];\r\n                }\r\n            }\r\n\r\n            this._needSync = this._needSync || changed;\r\n            if (changed) {\r\n                this._dataGeneration++;\r\n            }\r\n        } else {\r\n            // No cache for dynamic\r\n            for (let i = 0; i < size; i++) {\r\n                this._bufferData[location + i] = data[i];\r\n            }\r\n            this._dataGeneration++;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the value of an uniform. The `update` method must be called afterwards to make it effective in the GPU.\r\n     * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.\r\n     * @param data Define the flattened data\r\n     * @param size Define the size of the data.\r\n     */\r\n    public updateUniformArray(uniformName: string, data: FloatArray, size: number) {\r\n        this._checkNewFrame();\r\n\r\n        const location = this._uniformLocations[uniformName];\r\n        if (location === undefined) {\r\n            Logger.Error(\"Cannot add an uniform Array dynamically. Please, add it using addUniform and make sure that uniform buffers are supported by the current engine.\");\r\n            return;\r\n        }\r\n\r\n        if (!this._buffer) {\r\n            this.create();\r\n        }\r\n\r\n        const arraySizes = this._uniformArraySizes[uniformName];\r\n\r\n        if (!this._dynamic) {\r\n            // Cache for static uniform buffers\r\n            let changed = false;\r\n            let countToFour = 0;\r\n            let baseStride = 0;\r\n            for (let i = 0; i < size; i++) {\r\n                if (this._bufferData[location + baseStride * 4 + countToFour] !== Tools.FloatRound(data[i])) {\r\n                    changed = true;\r\n                    if (this._createBufferOnWrite) {\r\n                        this._createNewBuffer();\r\n                    }\r\n                    this._bufferData[location + baseStride * 4 + countToFour] = data[i];\r\n                }\r\n                countToFour++;\r\n                if (countToFour === arraySizes.strideSize) {\r\n                    for (; countToFour < 4; countToFour++) {\r\n                        this._bufferData[location + baseStride * 4 + countToFour] = 0;\r\n                    }\r\n                    countToFour = 0;\r\n                    baseStride++;\r\n                }\r\n            }\r\n\r\n            this._needSync = this._needSync || changed;\r\n            if (changed) {\r\n                this._dataGeneration++;\r\n            }\r\n        } else {\r\n            // No cache for dynamic\r\n            for (let i = 0; i < size; i++) {\r\n                this._bufferData[location + i] = data[i];\r\n            }\r\n            this._dataGeneration++;\r\n        }\r\n    }\r\n\r\n    // Matrix cache\r\n    private _valueCache: { [key: string]: number } = {};\r\n    private _cacheMatrix(name: string, matrix: IMatrixLike): boolean {\r\n        this._checkNewFrame();\r\n\r\n        const cache = this._valueCache[name];\r\n        const flag = matrix.updateFlag;\r\n        if (cache !== undefined && cache === flag) {\r\n            return false;\r\n        }\r\n\r\n        this._valueCache[name] = flag;\r\n        return true;\r\n    }\r\n\r\n    // Update methods\r\n\r\n    private _updateMatrix3x3ForUniform(name: string, matrix: Float32Array): void {\r\n        // To match std140, matrix must be realigned\r\n        for (let i = 0; i < 3; i++) {\r\n            UniformBuffer._TempBuffer[i * 4] = matrix[i * 3];\r\n            UniformBuffer._TempBuffer[i * 4 + 1] = matrix[i * 3 + 1];\r\n            UniformBuffer._TempBuffer[i * 4 + 2] = matrix[i * 3 + 2];\r\n            UniformBuffer._TempBuffer[i * 4 + 3] = 0.0;\r\n        }\r\n\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 12);\r\n    }\r\n\r\n    private _updateMatrix3x3ForEffect(name: string, matrix: Float32Array): void {\r\n        this._currentEffect.setMatrix3x3(name, matrix);\r\n    }\r\n\r\n    private _updateMatrix2x2ForEffect(name: string, matrix: Float32Array): void {\r\n        this._currentEffect.setMatrix2x2(name, matrix);\r\n    }\r\n\r\n    private _updateMatrix2x2ForUniform(name: string, matrix: Float32Array): void {\r\n        // To match std140, matrix must be realigned\r\n        for (let i = 0; i < 2; i++) {\r\n            UniformBuffer._TempBuffer[i * 4] = matrix[i * 2];\r\n            UniformBuffer._TempBuffer[i * 4 + 1] = matrix[i * 2 + 1];\r\n            UniformBuffer._TempBuffer[i * 4 + 2] = 0.0;\r\n            UniformBuffer._TempBuffer[i * 4 + 3] = 0.0;\r\n        }\r\n\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 8);\r\n    }\r\n\r\n    private _updateFloatForEffect(name: string, x: number, suffix = \"\") {\r\n        this._currentEffect.setFloat(name + suffix, x);\r\n    }\r\n\r\n    private _updateFloatForUniform(name: string, x: number) {\r\n        UniformBuffer._TempBuffer[0] = x;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 1);\r\n    }\r\n\r\n    private _updateFloat2ForEffect(name: string, x: number, y: number, suffix = \"\") {\r\n        this._currentEffect.setFloat2(name + suffix, x, y);\r\n    }\r\n\r\n    private _updateFloat2ForUniform(name: string, x: number, y: number) {\r\n        UniformBuffer._TempBuffer[0] = x;\r\n        UniformBuffer._TempBuffer[1] = y;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 2);\r\n    }\r\n\r\n    private _updateFloat3ForEffect(name: string, x: number, y: number, z: number, suffix = \"\") {\r\n        this._currentEffect.setFloat3(name + suffix, x, y, z);\r\n    }\r\n\r\n    private _updateFloat3ForUniform(name: string, x: number, y: number, z: number) {\r\n        UniformBuffer._TempBuffer[0] = x;\r\n        UniformBuffer._TempBuffer[1] = y;\r\n        UniformBuffer._TempBuffer[2] = z;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n    }\r\n\r\n    private _updateFloat4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = \"\") {\r\n        this._currentEffect.setFloat4(name + suffix, x, y, z, w);\r\n    }\r\n\r\n    private _updateFloat4ForUniform(name: string, x: number, y: number, z: number, w: number) {\r\n        UniformBuffer._TempBuffer[0] = x;\r\n        UniformBuffer._TempBuffer[1] = y;\r\n        UniformBuffer._TempBuffer[2] = z;\r\n        UniformBuffer._TempBuffer[3] = w;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n    }\r\n\r\n    private _updateFloatArrayForEffect(name: string, array: Float32Array, suffix = \"\") {\r\n        switch (this._uniformArraySizes[name]?.strideSize) {\r\n            case 2:\r\n                this._currentEffect.setFloatArray2(name + suffix, array);\r\n                break;\r\n            case 3:\r\n                this._currentEffect.setFloatArray3(name + suffix, array);\r\n                break;\r\n            case 4:\r\n                this._currentEffect.setFloatArray4(name + suffix, array);\r\n                break;\r\n            default:\r\n                this._currentEffect.setFloatArray(name + suffix, array);\r\n                break;\r\n        }\r\n    }\r\n\r\n    private _updateFloatArrayForUniform(name: string, array: Float32Array) {\r\n        this.updateUniformArray(name, array, array.length);\r\n    }\r\n\r\n    private _updateArrayForEffect(name: string, array: number[]) {\r\n        this._currentEffect.setArray(name, array);\r\n    }\r\n\r\n    private _updateArrayForUniform(name: string, array: number[]) {\r\n        this.updateUniformArray(name, array, array.length);\r\n    }\r\n\r\n    private _updateIntArrayForEffect(name: string, array: Int32Array) {\r\n        this._currentEffect.setIntArray(name, array);\r\n    }\r\n\r\n    private _updateIntArrayForUniform(name: string, array: Int32Array) {\r\n        UniformBuffer._TempBufferInt32View.set(array);\r\n        this.updateUniformArray(name, UniformBuffer._TempBuffer, array.length);\r\n    }\r\n\r\n    private _updateUIntArrayForEffect(name: string, array: Uint32Array) {\r\n        this._currentEffect.setUIntArray(name, array);\r\n    }\r\n\r\n    private _updateUIntArrayForUniform(name: string, array: Uint32Array) {\r\n        UniformBuffer._TempBufferUInt32View.set(array);\r\n        this.updateUniformArray(name, UniformBuffer._TempBuffer, array.length);\r\n    }\r\n\r\n    private _updateMatrixForEffect(name: string, mat: IMatrixLike) {\r\n        this._currentEffect.setMatrix(name, mat);\r\n    }\r\n\r\n    private _updateMatrixForUniform(name: string, mat: IMatrixLike) {\r\n        if (this._cacheMatrix(name, mat)) {\r\n            this.updateUniform(name, <any>mat.asArray(), 16);\r\n        }\r\n    }\r\n\r\n    private _updateMatricesForEffect(name: string, mat: Float32Array) {\r\n        this._currentEffect.setMatrices(name, mat);\r\n    }\r\n\r\n    private _updateMatricesForUniform(name: string, mat: Float32Array) {\r\n        this.updateUniform(name, mat, mat.length);\r\n    }\r\n\r\n    private _updateVector3ForEffect(name: string, vector: IVector3Like) {\r\n        this._currentEffect.setVector3(name, vector);\r\n    }\r\n\r\n    private _updateVector3ForUniform(name: string, vector: IVector3Like) {\r\n        UniformBuffer._TempBuffer[0] = vector.x;\r\n        UniformBuffer._TempBuffer[1] = vector.y;\r\n        UniformBuffer._TempBuffer[2] = vector.z;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n    }\r\n\r\n    private _updateVector4ForEffect(name: string, vector: IVector4Like) {\r\n        this._currentEffect.setVector4(name, vector);\r\n    }\r\n\r\n    private _updateVector4ForUniform(name: string, vector: IVector4Like) {\r\n        UniformBuffer._TempBuffer[0] = vector.x;\r\n        UniformBuffer._TempBuffer[1] = vector.y;\r\n        UniformBuffer._TempBuffer[2] = vector.z;\r\n        UniformBuffer._TempBuffer[3] = vector.w;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n    }\r\n\r\n    private _updateColor3ForEffect(name: string, color: IColor3Like, suffix = \"\") {\r\n        this._currentEffect.setColor3(name + suffix, color);\r\n    }\r\n\r\n    private _updateColor3ForUniform(name: string, color: IColor3Like) {\r\n        UniformBuffer._TempBuffer[0] = color.r;\r\n        UniformBuffer._TempBuffer[1] = color.g;\r\n        UniformBuffer._TempBuffer[2] = color.b;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n    }\r\n\r\n    private _updateColor4ForEffect(name: string, color: IColor3Like, alpha: number, suffix = \"\") {\r\n        this._currentEffect.setColor4(name + suffix, color, alpha);\r\n    }\r\n\r\n    private _updateDirectColor4ForEffect(name: string, color: IColor4Like, suffix = \"\") {\r\n        this._currentEffect.setDirectColor4(name + suffix, color);\r\n    }\r\n\r\n    private _updateColor4ForUniform(name: string, color: IColor3Like, alpha: number) {\r\n        UniformBuffer._TempBuffer[0] = color.r;\r\n        UniformBuffer._TempBuffer[1] = color.g;\r\n        UniformBuffer._TempBuffer[2] = color.b;\r\n        UniformBuffer._TempBuffer[3] = alpha;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n    }\r\n\r\n    private _updateDirectColor4ForUniform(name: string, color: IColor4Like) {\r\n        UniformBuffer._TempBuffer[0] = color.r;\r\n        UniformBuffer._TempBuffer[1] = color.g;\r\n        UniformBuffer._TempBuffer[2] = color.b;\r\n        UniformBuffer._TempBuffer[3] = color.a;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n    }\r\n\r\n    private _updateIntForEffect(name: string, x: number, suffix = \"\") {\r\n        this._currentEffect.setInt(name + suffix, x);\r\n    }\r\n\r\n    private _updateIntForUniform(name: string, x: number) {\r\n        UniformBuffer._TempBufferInt32View[0] = x;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 1);\r\n    }\r\n\r\n    private _updateInt2ForEffect(name: string, x: number, y: number, suffix = \"\") {\r\n        this._currentEffect.setInt2(name + suffix, x, y);\r\n    }\r\n\r\n    private _updateInt2ForUniform(name: string, x: number, y: number) {\r\n        UniformBuffer._TempBufferInt32View[0] = x;\r\n        UniformBuffer._TempBufferInt32View[1] = y;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 2);\r\n    }\r\n\r\n    private _updateInt3ForEffect(name: string, x: number, y: number, z: number, suffix = \"\") {\r\n        this._currentEffect.setInt3(name + suffix, x, y, z);\r\n    }\r\n\r\n    private _updateInt3ForUniform(name: string, x: number, y: number, z: number) {\r\n        UniformBuffer._TempBufferInt32View[0] = x;\r\n        UniformBuffer._TempBufferInt32View[1] = y;\r\n        UniformBuffer._TempBufferInt32View[2] = z;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n    }\r\n\r\n    private _updateInt4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = \"\") {\r\n        this._currentEffect.setInt4(name + suffix, x, y, z, w);\r\n    }\r\n\r\n    private _updateInt4ForUniform(name: string, x: number, y: number, z: number, w: number) {\r\n        UniformBuffer._TempBufferInt32View[0] = x;\r\n        UniformBuffer._TempBufferInt32View[1] = y;\r\n        UniformBuffer._TempBufferInt32View[2] = z;\r\n        UniformBuffer._TempBufferInt32View[3] = w;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n    }\r\n\r\n    private _updateUIntForEffect(name: string, x: number, suffix = \"\") {\r\n        this._currentEffect.setUInt(name + suffix, x);\r\n    }\r\n\r\n    private _updateUIntForUniform(name: string, x: number) {\r\n        UniformBuffer._TempBufferUInt32View[0] = x;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 1);\r\n    }\r\n\r\n    private _updateUInt2ForEffect(name: string, x: number, y: number, suffix = \"\") {\r\n        this._currentEffect.setUInt2(name + suffix, x, y);\r\n    }\r\n\r\n    private _updateUInt2ForUniform(name: string, x: number, y: number) {\r\n        UniformBuffer._TempBufferUInt32View[0] = x;\r\n        UniformBuffer._TempBufferUInt32View[1] = y;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 2);\r\n    }\r\n\r\n    private _updateUInt3ForEffect(name: string, x: number, y: number, z: number, suffix = \"\") {\r\n        this._currentEffect.setUInt3(name + suffix, x, y, z);\r\n    }\r\n\r\n    private _updateUInt3ForUniform(name: string, x: number, y: number, z: number) {\r\n        UniformBuffer._TempBufferUInt32View[0] = x;\r\n        UniformBuffer._TempBufferUInt32View[1] = y;\r\n        UniformBuffer._TempBufferUInt32View[2] = z;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n    }\r\n\r\n    private _updateUInt4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = \"\") {\r\n        this._currentEffect.setUInt4(name + suffix, x, y, z, w);\r\n    }\r\n\r\n    private _updateUInt4ForUniform(name: string, x: number, y: number, z: number, w: number) {\r\n        UniformBuffer._TempBufferUInt32View[0] = x;\r\n        UniformBuffer._TempBufferUInt32View[1] = y;\r\n        UniformBuffer._TempBufferUInt32View[2] = z;\r\n        UniformBuffer._TempBufferUInt32View[3] = w;\r\n        this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n    }\r\n\r\n    /**\r\n     * Sets a sampler uniform on the effect.\r\n     * @param name Define the name of the sampler.\r\n     * @param texture Define the texture to set in the sampler\r\n     */\r\n    public setTexture(name: string, texture: Nullable<ThinTexture>) {\r\n        this._currentEffect.setTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Sets an array of sampler uniforms on the effect.\r\n     * @param name Define the name of uniform.\r\n     * @param textures Define the textures to set in the array of samplers\r\n     */\r\n    public setTextureArray(name: string, textures: ThinTexture[]) {\r\n        this._currentEffect.setTextureArray(name, textures);\r\n    }\r\n    /**\r\n     * Sets a sampler uniform on the effect.\r\n     * @param name Define the name of the sampler.\r\n     * @param texture Define the (internal) texture to set in the sampler\r\n     */\r\n    public bindTexture(name: string, texture: Nullable<InternalTexture>) {\r\n        this._currentEffect._bindTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Directly updates the value of the uniform in the cache AND on the GPU.\r\n     * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.\r\n     * @param data Define the flattened data\r\n     */\r\n    public updateUniformDirectly(uniformName: string, data: FloatArray) {\r\n        this.updateUniform(uniformName, data, data.length);\r\n\r\n        this.update();\r\n    }\r\n\r\n    /**\r\n     * Associates an effect to this uniform buffer\r\n     * @param effect Define the effect to associate the buffer to\r\n     * @param name Name of the uniform block in the shader.\r\n     */\r\n    public bindToEffect(effect: Effect, name: string): void {\r\n        this._currentEffect = effect;\r\n        this._currentEffectName = name;\r\n    }\r\n\r\n    /**\r\n     * Binds the current (GPU) buffer to the effect\r\n     */\r\n    public bindUniformBuffer(): void {\r\n        if (!this._noUBO && this._buffer && this._currentEffect) {\r\n            this._currentEffect.bindUniformBuffer(this._buffer, this._currentEffectName);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dissociates the current effect from this uniform buffer\r\n     */\r\n    public unbindEffect(): void {\r\n        this._currentEffect = undefined as any;\r\n        this._currentEffectName = undefined as any;\r\n    }\r\n\r\n    /**\r\n     * Sets the current state of the class (_bufferIndex, _buffer) to point to the data buffer passed in parameter if this buffer is one of the buffers handled by the class (meaning if it can be found in the _buffers array)\r\n     * This method is meant to be able to update a buffer at any time: just call setDataBuffer to set the class in the right state, call some updateXXX methods and then call udpate() => that will update the GPU buffer on the graphic card\r\n     * @param dataBuffer buffer to look for\r\n     * @returns true if the buffer has been found and the class internal state points to it, else false\r\n     */\r\n    public setDataBuffer(dataBuffer: DataBuffer): boolean {\r\n        if (!this._buffers) {\r\n            return this._buffer === dataBuffer;\r\n        }\r\n\r\n        for (let b = 0; b < this._buffers.length; ++b) {\r\n            const buffer = this._buffers[b];\r\n            if (buffer[0] === dataBuffer) {\r\n                this._bufferIndex = b;\r\n                this._buffer = dataBuffer;\r\n                this._createBufferOnWrite = false;\r\n                this._currentEffect = undefined as any;\r\n                // Note that if _buffers.length == 1, we don't copy _bufferData into _buffers[_bufferIndex][1] (see the update() method), and _bufferData already contains the right data\r\n                if (this._buffers.length > 1 && this._buffers[b][1]) {\r\n                    this._bufferData.set(this._buffers[b][1]!);\r\n                    this._dataGeneration++;\r\n                }\r\n                this._valueCache = {};\r\n                // The following line prevents the current buffer (_buffer / _bufferIndex) from being updated during subsequent calls to updateXXX() due to a call to _checkNewFrame()\r\n                // If we called setDataBuffer, it means that we want to update the buffer we just defined and not another one (_checkNewFrame() can modify the current buffer).\r\n                this._currentFrameId = this._engine.frameId;\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the uniform buffer has a uniform with the given name.\r\n     * @param name Name of the uniform to check\r\n     * @returns True if the uniform exists, false otherwise.\r\n     */\r\n    public has(name: string): boolean {\r\n        return this._uniformLocations[name] !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Disposes the uniform buffer.\r\n     */\r\n    public dispose(): void {\r\n        if (this._noUBO) {\r\n            return;\r\n        }\r\n\r\n        const uniformBuffers = this._engine._uniformBuffers;\r\n        const index = uniformBuffers.indexOf(this);\r\n\r\n        if (index !== -1) {\r\n            uniformBuffers[index] = uniformBuffers[uniformBuffers.length - 1];\r\n            uniformBuffers.pop();\r\n        }\r\n\r\n        if (this._trackUBOsInFrame && this._buffers) {\r\n            this._resetOwnerSlots();\r\n            for (let i = 0; i < this._buffers.length; ++i) {\r\n                const buffer = this._buffers[i][0];\r\n                this._engine._releaseBuffer(buffer);\r\n            }\r\n            this._buffers = [];\r\n            this._buffer = null;\r\n            this._bufferIndex = -1;\r\n        } else if (this._buffer && this._engine._releaseBuffer(this._buffer)) {\r\n            this._buffer = null;\r\n        }\r\n    }\r\n}\r\n","/**\r\n * Class used to store gfx data (like WebGLBuffer)\r\n */\r\nexport class DataBuffer {\r\n    private static _Counter = 0;\r\n\r\n    /**\r\n     * Gets or sets the number of objects referencing this buffer\r\n     */\r\n    public references: number = 0;\r\n    /** Gets or sets the size of the underlying buffer */\r\n    public capacity: number = 0;\r\n    /**\r\n     * Gets or sets a boolean indicating if the buffer contains 32bits indices\r\n     */\r\n    public is32Bits: boolean = false;\r\n\r\n    /**\r\n     * Gets the underlying buffer\r\n     */\r\n    public get underlyingResource(): any {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the unique id of this buffer\r\n     */\r\n    public readonly uniqueId: number;\r\n\r\n    /**\r\n     * Constructs the buffer\r\n     */\r\n    constructor() {\r\n        this.uniqueId = DataBuffer._Counter++;\r\n    }\r\n}\r\n","import { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\n\r\n/**\r\n * Defines the shader related stores and directory\r\n */\r\nexport class ShaderStore {\r\n    /**\r\n     * Gets or sets the relative url used to load shaders if using the engine in non-minified mode\r\n     */\r\n    public static ShadersRepository = \"src/Shaders/\";\r\n    /**\r\n     * Store of each shader (The can be looked up using effect.key)\r\n     */\r\n    public static ShadersStore: { [key: string]: string } = {};\r\n    /**\r\n     * Store of each included file for a shader (The can be looked up using effect.key)\r\n     */\r\n    public static IncludesShadersStore: { [key: string]: string } = {};\r\n\r\n    /**\r\n     * Gets or sets the relative url used to load shaders (WGSL) if using the engine in non-minified mode\r\n     */\r\n    public static ShadersRepositoryWGSL = \"src/ShadersWGSL/\";\r\n    /**\r\n     * Store of each shader  (WGSL)\r\n     */\r\n    public static ShadersStoreWGSL: { [key: string]: string } = {};\r\n    /**\r\n     * Store of each included file for a shader (WGSL)\r\n     */\r\n    public static IncludesShadersStoreWGSL: { [key: string]: string } = {};\r\n\r\n    /**\r\n     * Gets the shaders repository path for a given shader language\r\n     * @param shaderLanguage the shader language\r\n     * @returns the path to the shaders repository\r\n     */\r\n    public static GetShadersRepository(shaderLanguage = ShaderLanguage.GLSL): string {\r\n        return shaderLanguage === ShaderLanguage.GLSL ? ShaderStore.ShadersRepository : ShaderStore.ShadersRepositoryWGSL;\r\n    }\r\n\r\n    /**\r\n     * Gets the shaders store of a given shader language\r\n     * @param shaderLanguage the shader language\r\n     * @returns the shaders store\r\n     */\r\n    public static GetShadersStore(shaderLanguage = ShaderLanguage.GLSL): { [key: string]: string } {\r\n        return shaderLanguage === ShaderLanguage.GLSL ? ShaderStore.ShadersStore : ShaderStore.ShadersStoreWGSL;\r\n    }\r\n\r\n    /**\r\n     * Gets the include shaders store of a given shader language\r\n     * @param shaderLanguage the shader language\r\n     * @returns the include shaders store\r\n     */\r\n    public static GetIncludesShadersStore(shaderLanguage = ShaderLanguage.GLSL): { [key: string]: string } {\r\n        return shaderLanguage === ShaderLanguage.GLSL ? ShaderStore.IncludesShadersStore : ShaderStore.IncludesShadersStoreWGSL;\r\n    }\r\n}\r\n","import { type IPipelineContext } from \"../IPipelineContext\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Effect } from \"../../Materials/effect\";\r\nimport { type IMatrixLike, type IVector2Like, type IVector3Like, type IVector4Like, type IColor3Like, type IColor4Like, type IQuaternionLike } from \"../../Maths/math.like\";\r\nimport { type ThinEngine } from \"../thinEngine\";\r\nimport { type AbstractEngine } from \"../abstractEngine\";\r\n\r\n/** @internal */\r\nexport class WebGLPipelineContext implements IPipelineContext {\r\n    private _valueCache: { [key: string]: any } = {};\r\n    private _uniforms: { [key: string]: Nullable<WebGLUniformLocation> };\r\n\r\n    public engine: ThinEngine;\r\n    public program: Nullable<WebGLProgram>;\r\n    public context?: WebGLRenderingContext;\r\n    public vertexShader?: WebGLShader;\r\n    public fragmentShader?: WebGLShader;\r\n    public isParallelCompiled: boolean;\r\n    public onCompiled?: () => void;\r\n    public transformFeedback?: WebGLTransformFeedback | null;\r\n\r\n    public vertexCompilationError: Nullable<string> = null;\r\n    public fragmentCompilationError: Nullable<string> = null;\r\n    public programLinkError: Nullable<string> = null;\r\n    public programValidationError: Nullable<string> = null;\r\n\r\n    /** @internal */\r\n    public _isDisposed = false;\r\n\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public get isAsync() {\r\n        return this.isParallelCompiled;\r\n    }\r\n\r\n    public get isReady(): boolean {\r\n        if (this.program) {\r\n            if (this.isParallelCompiled) {\r\n                return this.engine._isRenderingStateCompiled(this);\r\n            }\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public _handlesSpectorRebuildCallback(onCompiled: (program: WebGLProgram) => void): void {\r\n        if (onCompiled && this.program) {\r\n            onCompiled(this.program);\r\n        }\r\n    }\r\n\r\n    public setEngine(engine: AbstractEngine): void {\r\n        this.engine = engine as ThinEngine;\r\n    }\r\n\r\n    public _fillEffectInformation(\r\n        effect: Effect,\r\n        uniformBuffersNames: { [key: string]: number },\r\n        uniformsNames: string[],\r\n        uniforms: { [key: string]: Nullable<WebGLUniformLocation> },\r\n        samplerList: string[],\r\n        samplers: { [key: string]: number },\r\n        attributesNames: string[],\r\n        attributes: number[]\r\n    ) {\r\n        const engine = this.engine;\r\n        if (engine.supportsUniformBuffers) {\r\n            for (const name in uniformBuffersNames) {\r\n                effect.bindUniformBlock(name, uniformBuffersNames[name]);\r\n            }\r\n        }\r\n\r\n        const effectAvailableUniforms = this.engine.getUniforms(this, uniformsNames);\r\n        effectAvailableUniforms.forEach((uniform, index) => {\r\n            uniforms[uniformsNames[index]] = uniform;\r\n        });\r\n        this._uniforms = uniforms;\r\n\r\n        let index: number;\r\n        for (index = 0; index < samplerList.length; index++) {\r\n            const sampler = effect.getUniform(samplerList[index]);\r\n            if (sampler == null) {\r\n                samplerList.splice(index, 1);\r\n                index--;\r\n            }\r\n        }\r\n\r\n        samplerList.forEach((name, index) => {\r\n            samplers[name] = index;\r\n        });\r\n\r\n        for (const attr of engine.getAttributes(this, attributesNames)) {\r\n            attributes.push(attr);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources.\r\n     **/\r\n    public dispose() {\r\n        this._uniforms = {};\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheMatrix(uniformName: string, matrix: IMatrixLike): boolean {\r\n        const cache = this._valueCache[uniformName];\r\n        const flag = matrix.updateFlag;\r\n        if (cache !== undefined && cache === flag) {\r\n            return false;\r\n        }\r\n\r\n        this._valueCache[uniformName] = flag;\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheFloat2(uniformName: string, x: number, y: number): boolean {\r\n        let cache = this._valueCache[uniformName];\r\n        if (!cache || cache.length !== 2) {\r\n            cache = [x, y];\r\n            this._valueCache[uniformName] = cache;\r\n            return true;\r\n        }\r\n\r\n        let changed = false;\r\n        if (cache[0] !== x) {\r\n            cache[0] = x;\r\n            changed = true;\r\n        }\r\n        if (cache[1] !== y) {\r\n            cache[1] = y;\r\n            changed = true;\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheFloat3(uniformName: string, x: number, y: number, z: number): boolean {\r\n        let cache = this._valueCache[uniformName];\r\n        if (!cache || cache.length !== 3) {\r\n            cache = [x, y, z];\r\n            this._valueCache[uniformName] = cache;\r\n            return true;\r\n        }\r\n\r\n        let changed = false;\r\n        if (cache[0] !== x) {\r\n            cache[0] = x;\r\n            changed = true;\r\n        }\r\n        if (cache[1] !== y) {\r\n            cache[1] = y;\r\n            changed = true;\r\n        }\r\n        if (cache[2] !== z) {\r\n            cache[2] = z;\r\n            changed = true;\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheFloat4(uniformName: string, x: number, y: number, z: number, w: number): boolean {\r\n        let cache = this._valueCache[uniformName];\r\n        if (!cache || cache.length !== 4) {\r\n            cache = [x, y, z, w];\r\n            this._valueCache[uniformName] = cache;\r\n            return true;\r\n        }\r\n\r\n        let changed = false;\r\n        if (cache[0] !== x) {\r\n            cache[0] = x;\r\n            changed = true;\r\n        }\r\n        if (cache[1] !== y) {\r\n            cache[1] = y;\r\n            changed = true;\r\n        }\r\n        if (cache[2] !== z) {\r\n            cache[2] = z;\r\n            changed = true;\r\n        }\r\n        if (cache[3] !== w) {\r\n            cache[3] = w;\r\n            changed = true;\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * Sets an integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     */\r\n    public setInt(uniformName: string, value: number): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === value) {\r\n            return;\r\n        }\r\n\r\n        if (this.engine.setInt(this._uniforms[uniformName], value)) {\r\n            this._valueCache[uniformName] = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a int2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int2.\r\n     * @param y Second int in int2.\r\n     */\r\n    public setInt2(uniformName: string, x: number, y: number): void {\r\n        if (this._cacheFloat2(uniformName, x, y)) {\r\n            if (!this.engine.setInt2(this._uniforms[uniformName], x, y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a int3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int3.\r\n     * @param y Second int in int3.\r\n     * @param z Third int in int3.\r\n     */\r\n    public setInt3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (this._cacheFloat3(uniformName, x, y, z)) {\r\n            if (!this.engine.setInt3(this._uniforms[uniformName], x, y, z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a int4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int4.\r\n     * @param y Second int in int4.\r\n     * @param z Third int in int4.\r\n     * @param w Fourth int in int4.\r\n     */\r\n    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (this._cacheFloat4(uniformName, x, y, z, w)) {\r\n            if (!this.engine.setInt4(this._uniforms[uniformName], x, y, z, w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setIntArray(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray2(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setIntArray2(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray3(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setIntArray3(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray4(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setIntArray4(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     */\r\n    public setUInt(uniformName: string, value: number): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === value) {\r\n            return;\r\n        }\r\n\r\n        if (this.engine.setUInt(this._uniforms[uniformName], value)) {\r\n            this._valueCache[uniformName] = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int2 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint2.\r\n     * @param y Second unsigned int in uint2.\r\n     */\r\n    public setUInt2(uniformName: string, x: number, y: number): void {\r\n        if (this._cacheFloat2(uniformName, x, y)) {\r\n            if (!this.engine.setUInt2(this._uniforms[uniformName], x, y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int3 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint3.\r\n     * @param y Second unsigned int in uint3.\r\n     * @param z Third unsigned int in uint3.\r\n     */\r\n    public setUInt3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (this._cacheFloat3(uniformName, x, y, z)) {\r\n            if (!this.engine.setUInt3(this._uniforms[uniformName], x, y, z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int4 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint4.\r\n     * @param y Second unsigned int in uint4.\r\n     * @param z Third unsigned int in uint4.\r\n     * @param w Fourth unsigned int in uint4.\r\n     */\r\n    public setUInt4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (this._cacheFloat4(uniformName, x, y, z, w)) {\r\n            if (!this.engine.setUInt4(this._uniforms[uniformName], x, y, z, w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setUIntArray(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray2(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setUIntArray2(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray3(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setUIntArray3(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray4(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setUIntArray4(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setArray(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray2(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setArray2(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray3(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setArray3(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray4(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setArray4(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets matrices on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrices matrices to be set.\r\n     */\r\n    public setMatrices(uniformName: string, matrices: Float32Array): void {\r\n        if (!matrices) {\r\n            return;\r\n        }\r\n\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setMatrices(this._uniforms[uniformName], matrices);\r\n    }\r\n\r\n    /**\r\n     * Sets matrix on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix(uniformName: string, matrix: IMatrixLike): void {\r\n        if (this._cacheMatrix(uniformName, matrix)) {\r\n            if (!this.engine.setMatrices(this._uniforms[uniformName], matrix.asArray())) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a 3x3 matrix on a uniform variable. (Specified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix3x3(uniformName: string, matrix: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setMatrix3x3(this._uniforms[uniformName], matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a 2x2 matrix on a uniform variable. (Specified as [1,2,3,4] will result in [1,2][3,4] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix2x2(uniformName: string, matrix: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this.engine.setMatrix2x2(this._uniforms[uniformName], matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a float on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value value to be set.\r\n     */\r\n    public setFloat(uniformName: string, value: number): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === value) {\r\n            return;\r\n        }\r\n\r\n        if (this.engine.setFloat(this._uniforms[uniformName], value)) {\r\n            this._valueCache[uniformName] = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector2 vector2 to be set.\r\n     */\r\n    public setVector2(uniformName: string, vector2: IVector2Like): void {\r\n        if (this._cacheFloat2(uniformName, vector2.x, vector2.y)) {\r\n            if (!this.engine.setFloat2(this._uniforms[uniformName], vector2.x, vector2.y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a float2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float2.\r\n     * @param y Second float in float2.\r\n     */\r\n    public setFloat2(uniformName: string, x: number, y: number): void {\r\n        if (this._cacheFloat2(uniformName, x, y)) {\r\n            if (!this.engine.setFloat2(this._uniforms[uniformName], x, y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector3 Value to be set.\r\n     */\r\n    public setVector3(uniformName: string, vector3: IVector3Like): void {\r\n        if (this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z)) {\r\n            if (!this.engine.setFloat3(this._uniforms[uniformName], vector3.x, vector3.y, vector3.z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a float3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float3.\r\n     * @param y Second float in float3.\r\n     * @param z Third float in float3.\r\n     */\r\n    public setFloat3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (this._cacheFloat3(uniformName, x, y, z)) {\r\n            if (!this.engine.setFloat3(this._uniforms[uniformName], x, y, z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector4 Value to be set.\r\n     */\r\n    public setVector4(uniformName: string, vector4: IVector4Like): void {\r\n        if (this._cacheFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w)) {\r\n            if (!this.engine.setFloat4(this._uniforms[uniformName], vector4.x, vector4.y, vector4.z, vector4.w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Quaternion on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param quaternion Value to be set.\r\n     */\r\n    public setQuaternion(uniformName: string, quaternion: IQuaternionLike): void {\r\n        if (this._cacheFloat4(uniformName, quaternion.x, quaternion.y, quaternion.z, quaternion.w)) {\r\n            if (!this.engine.setFloat4(this._uniforms[uniformName], quaternion.x, quaternion.y, quaternion.z, quaternion.w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a float4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float4.\r\n     * @param y Second float in float4.\r\n     * @param z Third float in float4.\r\n     * @param w Fourth float in float4.\r\n     */\r\n    public setFloat4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (this._cacheFloat4(uniformName, x, y, z, w)) {\r\n            if (!this.engine.setFloat4(this._uniforms[uniformName], x, y, z, w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Color3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     */\r\n    public setColor3(uniformName: string, color3: IColor3Like): void {\r\n        if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {\r\n            if (!this.engine.setFloat3(this._uniforms[uniformName], color3.r, color3.g, color3.b)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     * @param alpha Alpha value to be set.\r\n     */\r\n    public setColor4(uniformName: string, color3: IColor3Like, alpha: number): void {\r\n        if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {\r\n            if (!this.engine.setFloat4(this._uniforms[uniformName], color3.r, color3.g, color3.b, alpha)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable\r\n     * @param uniformName defines the name of the variable\r\n     * @param color4 defines the value to be set\r\n     */\r\n    public setDirectColor4(uniformName: string, color4: IColor4Like): void {\r\n        if (this._cacheFloat4(uniformName, color4.r, color4.g, color4.b, color4.a)) {\r\n            if (!this.engine.setFloat4(this._uniforms[uniformName], color4.r, color4.g, color4.b, color4.a)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    public _getVertexShaderCode(): string | null {\r\n        return this.vertexShader ? this.engine._getShaderSource(this.vertexShader) : null;\r\n    }\r\n\r\n    public _getFragmentShaderCode(): string | null {\r\n        return this.fragmentShader ? this.engine._getShaderSource(this.fragmentShader) : null;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { type _IShaderProcessingContext } from \"./Processors/shaderProcessingOptions\";\r\nimport { WebGLPipelineContext } from \"./WebGL/webGLPipelineContext\";\r\nimport { type _LoadFile, _ConcatenateShader } from \"./abstractEngine.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface IThinEngineStateObject {\r\n    _contextWasLost?: boolean;\r\n    validateShaderPrograms?: boolean;\r\n    _webGLVersion: number;\r\n    parallelShaderCompile?: { COMPLETION_STATUS_KHR: number };\r\n    disableParallelShaderCompile?: boolean;\r\n    _context?: WebGLContext;\r\n    _createShaderProgramInjection?: typeof _createShaderProgram;\r\n    createRawShaderProgramInjection?: typeof createRawShaderProgram;\r\n    createShaderProgramInjection?: typeof createShaderProgram;\r\n    loadFileInjection?: typeof _LoadFile;\r\n    cachedPipelines: { [name: string]: IPipelineContext };\r\n}\r\n\r\nconst StateObject: WeakMap<WebGLContext, IThinEngineStateObject> = new WeakMap();\r\n\r\n/**\r\n * This will be used in cases where the engine doesn't have a context (like the nullengine)\r\n */\r\nconst SingleStateObject: IThinEngineStateObject = {\r\n    _webGLVersion: 2,\r\n    cachedPipelines: {},\r\n};\r\n\r\n/**\r\n * get or create a state object for the given context\r\n * Note - Used in WebGL only at the moment.\r\n * @param context The context to get the state object from\r\n * @returns the state object\r\n * @internal\r\n */\r\nexport function getStateObject(context: WebGLContext): IThinEngineStateObject {\r\n    let state = StateObject.get(context);\r\n    if (!state) {\r\n        if (!context) {\r\n            return SingleStateObject;\r\n        }\r\n        state = {\r\n            // use feature detection. instanceof returns false. This only exists on WebGL2 context\r\n            _webGLVersion: (context as WebGL2RenderingContext).TEXTURE_BINDING_3D ? 2 : 1,\r\n            _context: context,\r\n            // when using the function without an engine we need to set it to enable parallel compilation\r\n            parallelShaderCompile: context.getExtension(\"KHR_parallel_shader_compile\") || undefined,\r\n            cachedPipelines: {},\r\n        };\r\n        StateObject.set(context, state);\r\n    }\r\n    return state;\r\n}\r\n/**\r\n * Remove the state object that belongs to the specific context\r\n * @param context the context that is being\r\n */\r\nexport function deleteStateObject(context: WebGLContext): void {\r\n    StateObject.delete(context);\r\n}\r\n\r\nexport type WebGLContext = WebGLRenderingContext | WebGL2RenderingContext;\r\n/**\r\n * Directly creates a webGL program\r\n * @param pipelineContext  defines the pipeline context to attach to\r\n * @param vertexCode defines the vertex shader code to use\r\n * @param fragmentCode defines the fragment shader code to use\r\n * @param context defines the webGL context to use (if not set, the current one will be used)\r\n * @param transformFeedbackVaryings defines the list of transform feedback varyings to use\r\n * @param _createShaderProgramInjection defines an optional injection to use to create the shader program\r\n * @returns the new webGL program\r\n */\r\nexport function createRawShaderProgram(\r\n    pipelineContext: IPipelineContext,\r\n    vertexCode: string,\r\n    fragmentCode: string,\r\n    context: WebGLContext,\r\n    transformFeedbackVaryings: Nullable<string[]>,\r\n    _createShaderProgramInjection?: typeof _createShaderProgram\r\n): WebGLProgram {\r\n    const stateObject = getStateObject(context);\r\n    if (!_createShaderProgramInjection) {\r\n        _createShaderProgramInjection = stateObject._createShaderProgramInjection ?? _createShaderProgram;\r\n    }\r\n\r\n    const vertexShader = CompileRawShader(vertexCode, \"vertex\", context, stateObject._contextWasLost);\r\n    const fragmentShader = CompileRawShader(fragmentCode, \"fragment\", context, stateObject._contextWasLost);\r\n\r\n    return _createShaderProgramInjection(\r\n        pipelineContext as WebGLPipelineContext,\r\n        vertexShader,\r\n        fragmentShader,\r\n        context,\r\n        transformFeedbackVaryings,\r\n        stateObject.validateShaderPrograms\r\n    );\r\n}\r\n\r\n/**\r\n * Creates a webGL program\r\n * @param pipelineContext  defines the pipeline context to attach to\r\n * @param vertexCode  defines the vertex shader code to use\r\n * @param fragmentCode defines the fragment shader code to use\r\n * @param defines defines the string containing the defines to use to compile the shaders\r\n * @param context defines the webGL context to use (if not set, the current one will be used)\r\n * @param transformFeedbackVaryings defines the list of transform feedback varyings to use\r\n * @param _createShaderProgramInjection defines an optional injection to use to create the shader program\r\n * @returns the new webGL program\r\n */\r\nexport function createShaderProgram(\r\n    pipelineContext: IPipelineContext,\r\n    vertexCode: string,\r\n    fragmentCode: string,\r\n    defines: Nullable<string>,\r\n    context: WebGLContext,\r\n    transformFeedbackVaryings: Nullable<string[]> = null,\r\n    _createShaderProgramInjection?: typeof _createShaderProgram\r\n): WebGLProgram {\r\n    const stateObject = getStateObject(context);\r\n    if (!_createShaderProgramInjection) {\r\n        _createShaderProgramInjection = stateObject._createShaderProgramInjection ?? _createShaderProgram;\r\n    }\r\n    const shaderVersion = stateObject._webGLVersion > 1 ? \"#version 300 es\\n#define WEBGL2 \\n\" : \"\";\r\n    const vertexShader = CompileShader(vertexCode, \"vertex\", defines, shaderVersion, context, stateObject._contextWasLost);\r\n    const fragmentShader = CompileShader(fragmentCode, \"fragment\", defines, shaderVersion, context, stateObject._contextWasLost);\r\n\r\n    return _createShaderProgramInjection(\r\n        pipelineContext as WebGLPipelineContext,\r\n        vertexShader,\r\n        fragmentShader,\r\n        context,\r\n        transformFeedbackVaryings,\r\n        stateObject.validateShaderPrograms\r\n    );\r\n}\r\n\r\n/**\r\n * Creates a new pipeline context. Note, make sure to attach an engine instance to the created context\r\n * @param context defines the webGL context to use (if not set, the current one will be used)\r\n * @param _shaderProcessingContext defines the shader processing context used during the processing if available\r\n * @returns the new pipeline\r\n */\r\nexport function createPipelineContext(context: WebGLContext, _shaderProcessingContext: Nullable<_IShaderProcessingContext>): IPipelineContext {\r\n    const pipelineContext = new WebGLPipelineContext();\r\n    const stateObject = getStateObject(context);\r\n    if (stateObject.parallelShaderCompile && !stateObject.disableParallelShaderCompile) {\r\n        pipelineContext.isParallelCompiled = true;\r\n    }\r\n    pipelineContext.context = stateObject._context;\r\n    return pipelineContext;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _createShaderProgram(\r\n    pipelineContext: WebGLPipelineContext,\r\n    vertexShader: WebGLShader,\r\n    fragmentShader: WebGLShader,\r\n    context: WebGLContext,\r\n    _transformFeedbackVaryings: Nullable<string[]> = null,\r\n    validateShaderPrograms?: boolean\r\n): WebGLProgram {\r\n    const shaderProgram = context.createProgram();\r\n    pipelineContext.program = shaderProgram;\r\n\r\n    if (!shaderProgram) {\r\n        throw new Error(\"Unable to create program\");\r\n    }\r\n\r\n    context.attachShader(shaderProgram, vertexShader);\r\n    context.attachShader(shaderProgram, fragmentShader);\r\n\r\n    context.linkProgram(shaderProgram);\r\n\r\n    pipelineContext.context = context;\r\n    pipelineContext.vertexShader = vertexShader;\r\n    pipelineContext.fragmentShader = fragmentShader;\r\n\r\n    if (!pipelineContext.isParallelCompiled) {\r\n        _finalizePipelineContext(pipelineContext, context, validateShaderPrograms);\r\n    }\r\n\r\n    return shaderProgram;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _isRenderingStateCompiled(pipelineContext: IPipelineContext, gl: WebGLContext, validateShaderPrograms?: boolean): boolean {\r\n    const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n    if (webGLPipelineContext._isDisposed) {\r\n        return false;\r\n    }\r\n    const stateObject = getStateObject(gl);\r\n    if (stateObject && stateObject.parallelShaderCompile && stateObject.parallelShaderCompile.COMPLETION_STATUS_KHR && webGLPipelineContext.program) {\r\n        if (gl.getProgramParameter(webGLPipelineContext.program, stateObject.parallelShaderCompile.COMPLETION_STATUS_KHR)) {\r\n            _finalizePipelineContext(webGLPipelineContext, gl, validateShaderPrograms);\r\n            return true;\r\n        }\r\n    }\r\n\r\n    return false;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _finalizePipelineContext(pipelineContext: WebGLPipelineContext, gl: WebGLContext, validateShaderPrograms?: boolean) {\r\n    const context = pipelineContext.context!;\r\n    const vertexShader = pipelineContext.vertexShader!;\r\n    const fragmentShader = pipelineContext.fragmentShader!;\r\n    const program = pipelineContext.program!;\r\n\r\n    const linked = context.getProgramParameter(program, context.LINK_STATUS);\r\n    if (!linked) {\r\n        // Get more info\r\n        // Vertex\r\n        if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\r\n            const log = gl.getShaderInfoLog(vertexShader);\r\n            if (log) {\r\n                pipelineContext.vertexCompilationError = log;\r\n                throw new Error(\"VERTEX SHADER \" + log);\r\n            }\r\n        }\r\n\r\n        // Fragment\r\n        if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\r\n            const log = gl.getShaderInfoLog(fragmentShader);\r\n            if (log) {\r\n                pipelineContext.fragmentCompilationError = log;\r\n                throw new Error(\"FRAGMENT SHADER \" + log);\r\n            }\r\n        }\r\n\r\n        const error = context.getProgramInfoLog(program);\r\n        if (error) {\r\n            pipelineContext.programLinkError = error;\r\n            throw new Error(error);\r\n        }\r\n    }\r\n\r\n    if (/*this.*/ validateShaderPrograms) {\r\n        context.validateProgram(program);\r\n        const validated = context.getProgramParameter(program, context.VALIDATE_STATUS);\r\n\r\n        if (!validated) {\r\n            const error = context.getProgramInfoLog(program);\r\n            if (error) {\r\n                pipelineContext.programValidationError = error;\r\n                throw new Error(error);\r\n            }\r\n        }\r\n    }\r\n\r\n    context.deleteShader(vertexShader);\r\n    context.deleteShader(fragmentShader);\r\n\r\n    pipelineContext.vertexShader = undefined;\r\n    pipelineContext.fragmentShader = undefined;\r\n\r\n    if (pipelineContext.onCompiled) {\r\n        pipelineContext.onCompiled();\r\n        pipelineContext.onCompiled = undefined;\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _preparePipelineContext(\r\n    pipelineContext: IPipelineContext,\r\n    vertexSourceCode: string,\r\n    fragmentSourceCode: string,\r\n    createAsRaw: boolean,\r\n    _rawVertexSourceCode: string,\r\n    _rawFragmentSourceCode: string,\r\n    rebuildRebind: any,\r\n    defines: Nullable<string>,\r\n    transformFeedbackVaryings: Nullable<string[]>,\r\n    _key: string = \"\",\r\n    onReady: () => void,\r\n    createRawShaderProgramInjection?: typeof createRawShaderProgram,\r\n    createShaderProgramInjection?: typeof createShaderProgram\r\n) {\r\n    const stateObject = getStateObject((pipelineContext as WebGLPipelineContext).context!);\r\n    if (!createRawShaderProgramInjection) {\r\n        createRawShaderProgramInjection = stateObject.createRawShaderProgramInjection ?? createRawShaderProgram;\r\n    }\r\n    if (!createShaderProgramInjection) {\r\n        createShaderProgramInjection = stateObject.createShaderProgramInjection ?? createShaderProgram;\r\n    }\r\n    const webGLRenderingState = pipelineContext as WebGLPipelineContext;\r\n\r\n    if (createAsRaw) {\r\n        webGLRenderingState.program = createRawShaderProgramInjection(\r\n            webGLRenderingState,\r\n            vertexSourceCode,\r\n            fragmentSourceCode,\r\n            webGLRenderingState.context!,\r\n            transformFeedbackVaryings\r\n        );\r\n    } else {\r\n        webGLRenderingState.program = createShaderProgramInjection(\r\n            webGLRenderingState,\r\n            vertexSourceCode,\r\n            fragmentSourceCode,\r\n            defines,\r\n            webGLRenderingState.context!,\r\n            transformFeedbackVaryings\r\n        );\r\n    }\r\n    webGLRenderingState.program.__SPECTOR_rebuildProgram = rebuildRebind;\r\n\r\n    onReady();\r\n}\r\n\r\nfunction CompileShader(source: string, type: string, defines: Nullable<string>, shaderVersion: string, gl: WebGLContext, _contextWasLost?: boolean): WebGLShader {\r\n    return CompileRawShader(_ConcatenateShader(source, defines, shaderVersion), type, gl, _contextWasLost);\r\n}\r\n\r\nfunction CompileRawShader(source: string, type: string, gl: WebGLContext, _contextWasLost?: boolean): WebGLShader {\r\n    const shader = gl.createShader(type === \"vertex\" ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER);\r\n\r\n    if (!shader) {\r\n        let error: GLenum = gl.NO_ERROR;\r\n        let tempError: GLenum;\r\n        while ((tempError = gl.getError()) !== gl.NO_ERROR) {\r\n            error = tempError;\r\n        }\r\n\r\n        throw new Error(\r\n            `Something went wrong while creating a gl ${type} shader object. gl error=${error}, gl isContextLost=${gl.isContextLost()}, _contextWasLost=${_contextWasLost}`\r\n        );\r\n    }\r\n\r\n    gl.shaderSource(shader, source);\r\n    gl.compileShader(shader);\r\n\r\n    return shader;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _setProgram(program: Nullable<WebGLProgram>, gl: WebGLContext): void {\r\n    gl.useProgram(program);\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: (pipelineContext?: IPipelineContext) => void) {\r\n    const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n\r\n    if (!webGLPipelineContext.isParallelCompiled) {\r\n        action(pipelineContext);\r\n        return;\r\n    }\r\n\r\n    const oldHandler = webGLPipelineContext.onCompiled;\r\n\r\n    webGLPipelineContext.onCompiled = () => {\r\n        oldHandler?.();\r\n        action(pipelineContext);\r\n    };\r\n}\r\n","import { type _IProcessingOptions, type ShaderCustomProcessingFunction, type _IShaderProcessingContext } from \"core/Engines/Processors/shaderProcessingOptions\";\r\nimport { GetDOMTextContent, IsWindowObjectExist } from \"core/Misc/domManagement\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { type WebGLContext, getStateObject } from \"core/Engines/thinEngine.functions\";\r\nimport { ShaderStore } from \"core/Engines/shaderStore\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type Effect, type IShaderPath } from \"./effect\";\r\nimport { type IPipelineContext } from \"core/Engines/IPipelineContext\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Finalize, Initialize, Process } from \"core/Engines/Processors/shaderProcessor\";\r\nimport { _LoadFile } from \"core/Engines/abstractEngine.functions\";\r\nimport { type WebGLPipelineContext } from \"core/Engines/WebGL/webGLPipelineContext\";\r\n\r\n/**\r\n * Options to be used when creating a pipeline\r\n */\r\nexport interface IPipelineGenerationOptions {\r\n    /**\r\n     * The definition of the shader content.\r\n     * Can be either a unified name, name per vertex and frament or the shader code content itself\r\n     */\r\n    shaderNameOrContent: string | IShaderPath;\r\n    /**\r\n     * Unique key to identify the pipeline.\r\n     * Note that though not mandatory, it's recommended to provide a key to be able to use the automated pipeline loading system.\r\n     */\r\n    key?: string;\r\n    /**\r\n     * The list of defines to be used in the shader\r\n     */\r\n    defines?: string[];\r\n\r\n    /**\r\n     * If true, the global defines will be added to the defines array\r\n     */\r\n    addGlobalDefines?: boolean;\r\n    /**\r\n     * The shader language.\r\n     * Defaults to the language suiting the platform name (GLSL for WEBGL2, WGSL for WEBGPU)\r\n     */\r\n    shaderLanguage?: ShaderLanguage;\r\n\r\n    /**\r\n     * The name of the platform to be used when processing the shader\r\n     * defaults to WEBGL2\r\n     */\r\n    platformName?: string /* \"WEBGL2\" | \"WEBGL1\" | \"WEBGPU\" */;\r\n\r\n    /**\r\n     * extend the processing options when running code processing\r\n     */\r\n    extendedProcessingOptions?: Partial<_IProcessingOptions>;\r\n\r\n    /**\r\n     * extend the pipeline generation options\r\n     */\r\n    extendedCreatePipelineOptions?: Partial<ICreateAndPreparePipelineContextOptions>;\r\n\r\n    /**\r\n     * If true, generating a new pipeline will return when the pipeline is ready to be used\r\n     */\r\n    waitForIsReady?: boolean;\r\n\r\n    /**\r\n     * If true, the pipeline will be created synchronously, even if parallel shader compilation is available\r\n     */\r\n    disableParallelCompilation?: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface ICreateAndPreparePipelineContextOptions {\r\n    parallelShaderCompile?: { COMPLETION_STATUS_KHR: number };\r\n    shaderProcessingContext: Nullable<_IShaderProcessingContext>;\r\n    existingPipelineContext?: Nullable<IPipelineContext>;\r\n    name?: string;\r\n    rebuildRebind?: (vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (pipelineContext: IPipelineContext) => void, onError: (message: string) => void) => void;\r\n    onRenderingStateCompiled?: (pipelineContext?: IPipelineContext) => void;\r\n    context?: WebGL2RenderingContext | WebGLRenderingContext;\r\n    // preparePipeline options\r\n    createAsRaw?: boolean;\r\n    vertex: string;\r\n    fragment: string;\r\n    defines: Nullable<string>;\r\n    transformFeedbackVaryings: Nullable<string[]>;\r\n    disableParallelCompilation?: boolean;\r\n}\r\n\r\n/**\r\n * Get a cached pipeline context\r\n * @param name the pipeline name\r\n * @param context the context to be used when creating the pipeline\r\n * @returns the cached pipeline context if it exists\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getCachedPipeline(name: string, context: WebGLContext): IPipelineContext | undefined {\r\n    const stateObject = getStateObject(context);\r\n    return stateObject.cachedPipelines[name];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function resetCachedPipeline(pipeline: IPipelineContext): void {\r\n    const name = pipeline._name;\r\n    const context = (pipeline as WebGLPipelineContext).context;\r\n    if (name && context) {\r\n        const stateObject = getStateObject(context);\r\n        const cachedPipeline = stateObject.cachedPipelines[name];\r\n        cachedPipeline?.dispose();\r\n        delete stateObject.cachedPipelines[name];\r\n    }\r\n}\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function _ProcessShaderCode(\r\n    processorOptions: _IProcessingOptions,\r\n    baseName: any,\r\n    processFinalCode?: Nullable<ShaderCustomProcessingFunction>,\r\n    onFinalCodeReady?: (vertexCode: string, fragmentCode: string) => void,\r\n    shaderLanguage?: ShaderLanguage,\r\n    engine?: AbstractEngine,\r\n    effectContext?: Effect\r\n) {\r\n    let vertexSource: string | HTMLElement | IShaderPath;\r\n    let fragmentSource: string | HTMLElement | IShaderPath;\r\n\r\n    // const baseName = this.name;\r\n    const hostDocument = IsWindowObjectExist() ? engine?.getHostDocument() : null;\r\n\r\n    if (typeof baseName === \"string\") {\r\n        vertexSource = baseName;\r\n    } else if (typeof baseName.vertexSource === \"string\") {\r\n        vertexSource = \"source:\" + baseName.vertexSource;\r\n    } else if (typeof baseName.vertexElement === \"string\") {\r\n        vertexSource = hostDocument?.getElementById(baseName.vertexElement) || baseName.vertexElement;\r\n    } else {\r\n        vertexSource = baseName.vertex || baseName;\r\n    }\r\n    if (typeof baseName === \"string\") {\r\n        fragmentSource = baseName;\r\n    } else if (typeof baseName.fragmentSource === \"string\") {\r\n        fragmentSource = \"source:\" + baseName.fragmentSource;\r\n    } else if (typeof baseName.fragmentElement === \"string\") {\r\n        fragmentSource = hostDocument?.getElementById(baseName.fragmentElement) || baseName.fragmentElement;\r\n    } else {\r\n        fragmentSource = baseName.fragment || baseName;\r\n    }\r\n\r\n    // Important:\r\n    //   The vertex shader must be compiled before the fragment shader, as processing the fragment shader may require information from the vertex shader.\r\n    //   Also, they should be processed in the same JS tick because the shader processor is a singleton and stores information about the current processing in its internal state.\r\n    //   Processing the vertex and fragment shaders in different ticks may cause issues as the internal state may be overridden by another shader being processed in between.\r\n    // This means that the shaders must be processed in sequence and synchronously, but the loading of the shader code can be done in parallel\r\n    // as long as we wait for both shaders to be loaded before starting the processing.\r\n    const shaderCodes: [string | undefined, string | undefined] = [undefined, undefined];\r\n    const shadersLoaded = () => {\r\n        if (shaderCodes[0] && shaderCodes[1]) {\r\n            const [vertexCode, fragmentCode] = shaderCodes;\r\n            Initialize(processorOptions);\r\n            Process(\r\n                vertexCode,\r\n                processorOptions,\r\n                (migratedVertexCode, codeBeforeMigration) => {\r\n                    if (effectContext) {\r\n                        effectContext._vertexSourceCodeBeforeMigration = codeBeforeMigration;\r\n                    }\r\n                    if (processFinalCode) {\r\n                        migratedVertexCode = processFinalCode(\"vertex\", migratedVertexCode);\r\n                    }\r\n                    processorOptions.isFragment = true;\r\n                    Process(\r\n                        fragmentCode,\r\n                        processorOptions,\r\n                        (migratedFragmentCode: string, codeBeforeMigration: string) => {\r\n                            if (effectContext) {\r\n                                effectContext._fragmentSourceCodeBeforeMigration = codeBeforeMigration;\r\n                            }\r\n                            if (processFinalCode) {\r\n                                migratedFragmentCode = processFinalCode(\"fragment\", migratedFragmentCode);\r\n                            }\r\n                            const finalShaders = Finalize(migratedVertexCode, migratedFragmentCode, processorOptions);\r\n                            processorOptions = null as any;\r\n                            const finalCode = UseFinalCode(finalShaders.vertexCode, finalShaders.fragmentCode, baseName, shaderLanguage);\r\n                            onFinalCodeReady?.(finalCode.vertexSourceCode, finalCode.fragmentSourceCode);\r\n                        },\r\n                        engine\r\n                    );\r\n                },\r\n                engine\r\n            );\r\n        }\r\n    };\r\n    LoadShader(\r\n        vertexSource,\r\n        \"Vertex\",\r\n        \"\",\r\n        (vertexCode) => {\r\n            if (effectContext) {\r\n                effectContext._rawVertexSourceCode = vertexCode;\r\n            }\r\n            shaderCodes[0] = vertexCode;\r\n            shadersLoaded();\r\n        },\r\n        shaderLanguage\r\n    );\r\n    LoadShader(\r\n        fragmentSource,\r\n        \"Fragment\",\r\n        \"Pixel\",\r\n        (fragmentCode) => {\r\n            if (effectContext) {\r\n                effectContext._rawFragmentSourceCode = fragmentCode;\r\n            }\r\n            shaderCodes[1] = fragmentCode;\r\n            shadersLoaded();\r\n        },\r\n        shaderLanguage\r\n    );\r\n}\r\n\r\nfunction LoadShader(shader: any, key: string, optionalKey: string, callback: (data: any) => void, shaderLanguage?: ShaderLanguage, _loadFileInjection?: typeof _LoadFile) {\r\n    if (typeof HTMLElement !== \"undefined\") {\r\n        // DOM element ?\r\n        if (shader instanceof HTMLElement) {\r\n            const shaderCode = GetDOMTextContent(shader);\r\n            callback(shaderCode);\r\n            return;\r\n        }\r\n    }\r\n\r\n    // Direct source ?\r\n    if (shader.substring(0, 7) === \"source:\") {\r\n        callback(shader.substring(7));\r\n        return;\r\n    }\r\n\r\n    // Base64 encoded ?\r\n    if (shader.substring(0, 7) === \"base64:\") {\r\n        const shaderBinary = window.atob(shader.substring(7));\r\n        callback(shaderBinary);\r\n        return;\r\n    }\r\n\r\n    const shaderStore = ShaderStore.GetShadersStore(shaderLanguage);\r\n\r\n    // Is in local store ?\r\n    if (shaderStore[shader + key + \"Shader\"]) {\r\n        callback(shaderStore[shader + key + \"Shader\"]);\r\n        return;\r\n    }\r\n\r\n    if (optionalKey && shaderStore[shader + optionalKey + \"Shader\"]) {\r\n        callback(shaderStore[shader + optionalKey + \"Shader\"]);\r\n        return;\r\n    }\r\n\r\n    let shaderUrl;\r\n\r\n    if (shader[0] === \".\" || shader[0] === \"/\" || shader.indexOf(\"http\") > -1) {\r\n        shaderUrl = shader;\r\n    } else {\r\n        shaderUrl = ShaderStore.GetShadersRepository(shaderLanguage) + shader;\r\n    }\r\n    _loadFileInjection = _loadFileInjection || _LoadFile;\r\n    if (!_loadFileInjection) {\r\n        // we got to this point and loadFile was not injected - throw an error\r\n        throw new Error(\"loadFileInjection is not defined\");\r\n    }\r\n    // Vertex shader\r\n    _loadFileInjection(shaderUrl + \".\" + key.toLowerCase() + \".fx\", callback);\r\n}\r\n\r\nfunction UseFinalCode(migratedVertexCode: string, migratedFragmentCode: string, baseName: any, shaderLanguage?: ShaderLanguage) {\r\n    if (baseName) {\r\n        const vertex = baseName.vertexElement || baseName.vertex || baseName.spectorName || baseName;\r\n        const fragment = baseName.fragmentElement || baseName.fragment || baseName.spectorName || baseName;\r\n\r\n        return {\r\n            vertexSourceCode: (shaderLanguage === ShaderLanguage.WGSL ? \"//\" : \"\") + \"#define SHADER_NAME vertex:\" + vertex + \"\\n\" + migratedVertexCode,\r\n            fragmentSourceCode: (shaderLanguage === ShaderLanguage.WGSL ? \"//\" : \"\") + \"#define SHADER_NAME fragment:\" + fragment + \"\\n\" + migratedFragmentCode,\r\n        };\r\n    } else {\r\n        return {\r\n            vertexSourceCode: migratedVertexCode,\r\n            fragmentSourceCode: migratedFragmentCode,\r\n        };\r\n    }\r\n}\r\n\r\n/**\r\n * Creates and prepares a pipeline context\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const createAndPreparePipelineContext = (\r\n    options: ICreateAndPreparePipelineContextOptions,\r\n    createPipelineContext: typeof AbstractEngine.prototype.createPipelineContext,\r\n    _preparePipelineContext: typeof AbstractEngine.prototype._preparePipelineContextAsync,\r\n    _executeWhenRenderingStateIsCompiled: typeof AbstractEngine.prototype._executeWhenRenderingStateIsCompiled\r\n): IPipelineContext => {\r\n    try {\r\n        const stateObject = options.context ? getStateObject(options.context) : null;\r\n        if (stateObject) {\r\n            // will not remove the reference to parallelShaderPrecompile, but will prevent it from being used in the next shader compilation\r\n            stateObject.disableParallelShaderCompile = options.disableParallelCompilation;\r\n        }\r\n        const pipelineContext: IPipelineContext = options.existingPipelineContext || createPipelineContext(options.shaderProcessingContext);\r\n        pipelineContext._name = options.name;\r\n        if (options.name && stateObject) {\r\n            stateObject.cachedPipelines[options.name] = pipelineContext;\r\n        }\r\n\r\n        // Flagged as async as we may need to delay load some processing tools\r\n        // This does not break anything as the execution is waiting for _executeWhenRenderingStateIsCompiled\r\n        _preparePipelineContext(\r\n            pipelineContext,\r\n            options.vertex,\r\n            options.fragment,\r\n            !!options.createAsRaw,\r\n            \"\",\r\n            \"\",\r\n            options.rebuildRebind,\r\n            options.defines,\r\n            options.transformFeedbackVaryings,\r\n            \"\",\r\n            () => {\r\n                _executeWhenRenderingStateIsCompiled(pipelineContext, () => {\r\n                    options.onRenderingStateCompiled?.(pipelineContext);\r\n                });\r\n            }\r\n        );\r\n\r\n        return pipelineContext;\r\n    } catch (e) {\r\n        Logger.Error(\"Error compiling effect\");\r\n        throw e;\r\n    }\r\n};\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { type FloatArray, type Nullable } from \"../types\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type IDisposable } from \"../scene.pure\";\r\nimport { type IPipelineContext } from \"../Engines/IPipelineContext\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type IShaderProcessor } from \"../Engines/Processors/iShaderProcessor\";\r\nimport { type _IProcessingOptions, type ShaderCustomProcessingFunction, type _IShaderProcessingContext } from \"../Engines/Processors/shaderProcessingOptions\";\r\nimport { type IMatrixLike, type IVector2Like, type IVector3Like, type IVector4Like, type IColor3Like, type IColor4Like, type IQuaternionLike } from \"../Maths/math.like\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type IEffectFallbacks } from \"./iEffectFallbacks\";\r\nimport { ShaderStore as EngineShaderStore } from \"../Engines/shaderStore\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { type IPipelineGenerationOptions, _ProcessShaderCode, getCachedPipeline, createAndPreparePipelineContext, resetCachedPipeline } from \"./effect.functions\";\r\nimport { _RetryWithInterval } from \"core/Misc/timingTools\";\r\n\r\n/**\r\n * Defines the route to the shader code. The priority is as follows:\r\n *  * object: `{ vertexSource: \"vertex shader code string\", fragmentSource: \"fragment shader code string\" }` for directly passing the shader code\r\n *  * object: `{ vertexElement: \"vertexShaderCode\", fragmentElement: \"fragmentShaderCode\" }`, used with shader code in script tags\r\n *  * object: `{ vertex: \"custom\", fragment: \"custom\" }`, used with `Effect.ShadersStore[\"customVertexShader\"]` and `Effect.ShadersStore[\"customFragmentShader\"]`\r\n *  * string: `\"./COMMON_NAME\"`, used with external files COMMON_NAME.vertex.fx and COMMON_NAME.fragment.fx in index.html folder.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type IShaderPath = {\r\n    // Should not have `I` prefix as it is a type and not an interface\r\n    /**\r\n     * Directly pass the shader code\r\n     */\r\n    vertexSource?: string;\r\n    /**\r\n     * Directly pass the shader code\r\n     */\r\n    fragmentSource?: string;\r\n    /**\r\n     * Used with Effect.ShadersStore. If the `vertex` is set to `\"custom`, then\r\n     * Babylon.js will read from Effect.ShadersStore[\"customVertexShader\"]\r\n     */\r\n    vertex?: string;\r\n    /**\r\n     * Used with Effect.ShadersStore. If the `fragment` is set to `\"custom`, then\r\n     * Babylon.js will read from Effect.ShadersStore[\"customFragmentShader\"]\r\n     */\r\n    fragment?: string;\r\n    /**\r\n     * Used with shader code in script tags\r\n     */\r\n    vertexElement?: string;\r\n    /**\r\n     * Used with shader code in script tags\r\n     */\r\n    fragmentElement?: string;\r\n    /**\r\n     * Defines the name appearing in spector when framgent/vertex...source are being used\r\n     */\r\n    spectorName?: string;\r\n};\r\n\r\n/**\r\n * Options to be used when creating an effect.\r\n */\r\nexport interface IEffectCreationOptions {\r\n    /**\r\n     * Attributes that will be used in the shader.\r\n     */\r\n    attributes: string[];\r\n    /**\r\n     * Uniform variable names that will be set in the shader.\r\n     */\r\n    uniformsNames: string[];\r\n    /**\r\n     * Uniform buffer variable names that will be set in the shader.\r\n     */\r\n    uniformBuffersNames?: string[];\r\n    /**\r\n     * Sampler texture variable names that will be set in the shader.\r\n     */\r\n    samplers: string[];\r\n    /**\r\n     * Define statements that will be set in the shader.\r\n     */\r\n    defines: any;\r\n    /**\r\n     * Possible fallbacks for this effect to improve performance when needed.\r\n     */\r\n    fallbacks: Nullable<IEffectFallbacks>;\r\n    /**\r\n     * Callback that will be called when the shader is compiled.\r\n     */\r\n    onCompiled: Nullable<(effect: Effect) => void>;\r\n    /**\r\n     * Callback that will be called if an error occurs during shader compilation.\r\n     */\r\n    onError: Nullable<(effect: Effect, errors: string) => void>;\r\n    /**\r\n     * Parameters to be used with Babylons include syntax to iterate over an array (eg. \\{lights: 10\\})\r\n     */\r\n    indexParameters?: any;\r\n    /**\r\n     * Max number of lights that can be used in the shader.\r\n     */\r\n    maxSimultaneousLights?: number;\r\n    /**\r\n     * See https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/transformFeedbackVaryings\r\n     */\r\n    transformFeedbackVaryings?: Nullable<string[]>;\r\n    /**\r\n     * If provided, will be called two times with the vertex and fragment code so that this code can be updated before it is compiled by the GPU\r\n     */\r\n    processFinalCode?: Nullable<ShaderCustomProcessingFunction>;\r\n    /**\r\n     * If provided, will be called two times with the vertex and fragment code so that this code can be updated after the #include have been processed\r\n     */\r\n    processCodeAfterIncludes?: Nullable<ShaderCustomProcessingFunction>;\r\n    /**\r\n     * Is this effect rendering to several color attachments ?\r\n     */\r\n    multiTarget?: boolean;\r\n    /**\r\n     * The language the shader is written in (default: GLSL)\r\n     */\r\n    shaderLanguage?: ShaderLanguage;\r\n\r\n    /**\r\n     * Provide an existing pipeline context to avoid creating a new one\r\n     */\r\n    existingPipelineContext?: IPipelineContext;\r\n    /**\r\n     * Additional async code to run before preparing the effect\r\n     */\r\n    extraInitializationsAsync?: () => Promise<void>;\r\n\r\n    /**\r\n     * If set to true the shader will not be compiles asynchronously, even if the engine allows it.\r\n     */\r\n    disableParallelShaderCompilation?: boolean;\r\n}\r\n\r\n/**\r\n * Effect containing vertex and fragment shader that can be executed on an object.\r\n */\r\nexport class Effect implements IDisposable {\r\n    /**\r\n     * Gets or sets the relative url used to load shaders if using the engine in non-minified mode\r\n     */\r\n    public static get ShadersRepository(): string {\r\n        return EngineShaderStore.ShadersRepository;\r\n    }\r\n    public static set ShadersRepository(repo: string) {\r\n        EngineShaderStore.ShadersRepository = repo;\r\n    }\r\n    /**\r\n     * Enable logging of the shader code when a compilation error occurs\r\n     */\r\n    public static LogShaderCodeOnCompilationError = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that effect ref counting is disabled\r\n     * If true, the effect will persist in memory until engine is disposed\r\n     */\r\n    public static PersistentMode: boolean = false;\r\n\r\n    /**\r\n     * Use this with caution\r\n     * See ClearCodeCache function comments\r\n     */\r\n    public static AutomaticallyClearCodeCache = false;\r\n\r\n    /**\r\n     * Name of the effect.\r\n     */\r\n    public name: IShaderPath | string;\r\n    /**\r\n     * String container all the define statements that should be set on the shader.\r\n     */\r\n    public defines: string = \"\";\r\n    /**\r\n     * Callback that will be called when the shader is compiled.\r\n     */\r\n    public onCompiled: Nullable<(effect: Effect) => void> = null;\r\n    /**\r\n     * Callback that will be called if an error occurs during shader compilation.\r\n     */\r\n    public onError: Nullable<(effect: Effect, errors: string) => void> = null;\r\n    /**\r\n     * Callback that will be called when effect is bound.\r\n     */\r\n    public onBind: Nullable<(effect: Effect) => void> = null;\r\n    /**\r\n     * Unique ID of the effect.\r\n     */\r\n    public uniqueId = 0;\r\n    /**\r\n     * Observable that will be called when the shader is compiled.\r\n     * It is recommended to use executeWhenCompile() or to make sure that scene.isReady() is called to get this observable raised.\r\n     */\r\n    public onCompileObservable = new Observable<Effect>();\r\n    /**\r\n     * Observable that will be called if an error occurs during shader compilation.\r\n     */\r\n    public onErrorObservable = new Observable<Effect>();\r\n\r\n    /** @internal */\r\n    public _onBindObservable: Nullable<Observable<Effect>> = null;\r\n\r\n    private _isDisposed = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the effect was already disposed\r\n     */\r\n    public get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /** @internal */\r\n    public _refCount = 1;\r\n\r\n    /**\r\n     * Observable that will be called when effect is bound.\r\n     */\r\n    public get onBindObservable(): Observable<Effect> {\r\n        if (!this._onBindObservable) {\r\n            this._onBindObservable = new Observable<Effect>();\r\n        }\r\n\r\n        return this._onBindObservable;\r\n    }\r\n\r\n    /** @internal */\r\n    public _bonesComputationForcedToCPU = false;\r\n    /** @internal */\r\n    public _uniformBuffersNames: { [key: string]: number } = {};\r\n    /** @internal */\r\n    public _samplerList: string[];\r\n    /** @internal */\r\n    public _multiTarget: boolean = false;\r\n\r\n    private static _UniqueIdSeed = 0;\r\n    /** @internal */\r\n    public _engine: AbstractEngine;\r\n    private _uniformBuffersNamesList: string[];\r\n    private _uniformsNames: string[];\r\n    /** @internal */\r\n    public _samplers: { [key: string]: number } = {};\r\n    private _isReady = false;\r\n    private _compilationError = \"\";\r\n    private _allFallbacksProcessed = false;\r\n    private _attributesNames: string[];\r\n    private _attributes: number[];\r\n    private _attributeLocationByName: { [name: string]: number };\r\n    /** @internal */\r\n    public _uniforms: { [key: string]: Nullable<WebGLUniformLocation> } = {};\r\n    /**\r\n     * Key for the effect.\r\n     * @internal\r\n     */\r\n    public _key: string = \"\";\r\n    private _indexParameters: any;\r\n    private _fallbacks: Nullable<IEffectFallbacks> = null;\r\n    private _vertexSourceCodeOverride: string = \"\";\r\n    private _fragmentSourceCodeOverride: string = \"\";\r\n    private _transformFeedbackVaryings: Nullable<string[]> = null;\r\n    private _shaderLanguage: ShaderLanguage;\r\n    private _disableParallelShaderCompilation: boolean = false;\r\n    /**\r\n     * Compiled shader to webGL program.\r\n     * @internal\r\n     */\r\n    public _pipelineContext: Nullable<IPipelineContext> = null;\r\n    /** @internal */\r\n    public _vertexSourceCode: string = \"\";\r\n    /** @internal */\r\n    public _fragmentSourceCode: string = \"\";\r\n\r\n    /** @internal */\r\n    public _vertexSourceCodeBeforeMigration: string = \"\";\r\n    /** @internal */\r\n    public _fragmentSourceCodeBeforeMigration: string = \"\";\r\n\r\n    /** @internal */\r\n    public _rawVertexSourceCode: string = \"\";\r\n    /** @internal */\r\n    public _rawFragmentSourceCode: string = \"\";\r\n\r\n    private static _BaseCache: { [key: number]: DataBuffer } = {};\r\n    private _processingContext: Nullable<_IShaderProcessingContext>;\r\n\r\n    private _processCodeAfterIncludes: ShaderCustomProcessingFunction | undefined = undefined;\r\n    private _processFinalCode: Nullable<ShaderCustomProcessingFunction> = null;\r\n\r\n    private _onReleaseEffectsObserver: Nullable<Observer<AbstractEngine>> = null;\r\n\r\n    /**\r\n     * Gets the shader language type used to write vertex and fragment source code.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Instantiates an effect.\r\n     * An effect can be used to create/manage/execute vertex and fragment shaders.\r\n     * @param baseName Name of the effect.\r\n     * @param attributesNamesOrOptions List of attribute names that will be passed to the shader or set of all options to create the effect.\r\n     * @param uniformsNamesOrEngine List of uniform variable names that will be passed to the shader or the engine that will be used to render effect.\r\n     * @param samplers List of sampler variables that will be passed to the shader.\r\n     * @param engine Engine to be used to render the effect\r\n     * @param defines Define statements to be added to the shader.\r\n     * @param fallbacks Possible fallbacks for this effect to improve performance when needed.\r\n     * @param onCompiled Callback that will be called when the shader is compiled.\r\n     * @param onError Callback that will be called if an error occurs during shader compilation.\r\n     * @param indexParameters Parameters to be used with Babylons include syntax to iterate over an array (eg. \\{lights: 10\\})\r\n     * @param key Effect Key identifying uniquely compiled shader variants\r\n     * @param shaderLanguage the language the shader is written in (default: GLSL)\r\n     * @param extraInitializationsAsync additional async code to run before preparing the effect\r\n     */\r\n    constructor(\r\n        baseName: IShaderPath | string,\r\n        attributesNamesOrOptions: string[] | IEffectCreationOptions,\r\n        uniformsNamesOrEngine: string[] | AbstractEngine,\r\n        samplers: Nullable<string[]> = null,\r\n        engine?: AbstractEngine,\r\n        defines: Nullable<string> = null,\r\n        fallbacks: Nullable<IEffectFallbacks> = null,\r\n        onCompiled: Nullable<(effect: Effect) => void> = null,\r\n        onError: Nullable<(effect: Effect, errors: string) => void> = null,\r\n        indexParameters?: any,\r\n        key: string = \"\",\r\n        shaderLanguage = ShaderLanguage.GLSL,\r\n        extraInitializationsAsync?: () => Promise<void>\r\n    ) {\r\n        this.name = baseName;\r\n        this._key = key;\r\n        const pipelineName = this._key.replace(/\\r/g, \"\").replace(/\\n/g, \"|\");\r\n        let cachedPipeline: IPipelineContext | undefined = undefined;\r\n\r\n        if ((<IEffectCreationOptions>attributesNamesOrOptions).attributes) {\r\n            const options = <IEffectCreationOptions>attributesNamesOrOptions;\r\n            this._engine = <AbstractEngine>uniformsNamesOrEngine;\r\n\r\n            this._attributesNames = options.attributes;\r\n            this._uniformsNames = options.uniformsNames.concat(options.samplers);\r\n            this._samplerList = options.samplers.slice();\r\n            this.defines = options.defines;\r\n            this.onError = options.onError;\r\n            this.onCompiled = options.onCompiled;\r\n            this._fallbacks = options.fallbacks;\r\n            this._indexParameters = options.indexParameters;\r\n            this._transformFeedbackVaryings = options.transformFeedbackVaryings || null;\r\n            this._multiTarget = !!options.multiTarget;\r\n            this._shaderLanguage = options.shaderLanguage ?? ShaderLanguage.GLSL;\r\n            this._disableParallelShaderCompilation = !!options.disableParallelShaderCompilation;\r\n\r\n            if (options.uniformBuffersNames) {\r\n                this._uniformBuffersNamesList = options.uniformBuffersNames.slice();\r\n                for (let i = 0; i < options.uniformBuffersNames.length; i++) {\r\n                    this._uniformBuffersNames[options.uniformBuffersNames[i]] = i;\r\n                }\r\n            }\r\n\r\n            this._processFinalCode = options.processFinalCode ?? null;\r\n            this._processCodeAfterIncludes = options.processCodeAfterIncludes ?? undefined;\r\n            extraInitializationsAsync = options.extraInitializationsAsync;\r\n\r\n            cachedPipeline = options.existingPipelineContext;\r\n        } else {\r\n            this._engine = <AbstractEngine>engine;\r\n            this.defines = defines == null ? \"\" : defines;\r\n            this._uniformsNames = (<string[]>uniformsNamesOrEngine).concat(<string[]>samplers);\r\n            this._samplerList = samplers ? samplers.slice() : [];\r\n            this._attributesNames = <string[]>attributesNamesOrOptions;\r\n            this._uniformBuffersNamesList = [];\r\n            this._shaderLanguage = shaderLanguage;\r\n\r\n            this.onError = onError;\r\n            this.onCompiled = onCompiled;\r\n\r\n            this._indexParameters = indexParameters;\r\n            this._fallbacks = fallbacks;\r\n        }\r\n\r\n        // Use the cache if we can. For now, WebGL2 only.\r\n        if (this._engine.shaderPlatformName === \"WEBGL2\") {\r\n            cachedPipeline = getCachedPipeline(pipelineName, (this._engine as any)._gl) ?? cachedPipeline;\r\n        }\r\n\r\n        this._attributeLocationByName = {};\r\n\r\n        this.uniqueId = Effect._UniqueIdSeed++;\r\n        if (!cachedPipeline) {\r\n            // eslint-disable-next-line github/no-then\r\n            void this._processShaderCodeAsync(null, false, null, extraInitializationsAsync).catch((error) => {\r\n                const message = error?.message ?? String(error);\r\n                const asyncError = new Error(`Effect async shader preparation failed for \"${String(this.name)}\": ${message}`);\r\n                if (error && typeof error.stack === \"string\") {\r\n                    asyncError.stack = `${asyncError.message}\\nCaused by: ${error.stack}`;\r\n                }\r\n                this._processCompilationErrors(asyncError);\r\n            });\r\n        } else {\r\n            this._pipelineContext = cachedPipeline;\r\n            this._pipelineContext.setEngine(this._engine);\r\n            this._onRenderingStateCompiled(this._pipelineContext);\r\n            // rebuildRebind for spector\r\n            if ((this._pipelineContext as any).program) {\r\n                (this._pipelineContext as any).program.__SPECTOR_rebuildProgram = this._rebuildProgram.bind(this);\r\n            }\r\n        }\r\n\r\n        this._onReleaseEffectsObserver = this._engine.onReleaseEffectsObservable.addOnce(() => {\r\n            this._onReleaseEffectsObserver = null;\r\n            if (this.isDisposed) {\r\n                return;\r\n            }\r\n\r\n            this.dispose(true);\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public async _processShaderCodeAsync(\r\n        shaderProcessor: Nullable<IShaderProcessor> = null,\r\n        keepExistingPipelineContext = false,\r\n        shaderProcessingContext: Nullable<_IShaderProcessingContext> = null,\r\n        extraInitializationsAsync?: () => Promise<void>\r\n    ) {\r\n        if (extraInitializationsAsync) {\r\n            await extraInitializationsAsync();\r\n        }\r\n\r\n        this._processingContext = shaderProcessingContext || this._engine._getShaderProcessingContext(this._shaderLanguage, false);\r\n\r\n        const processorOptions: _IProcessingOptions = {\r\n            defines: this.defines.split(\"\\n\"),\r\n            indexParameters: this._indexParameters,\r\n            isFragment: false,\r\n            shouldUseHighPrecisionShader: this._engine._shouldUseHighPrecisionShader,\r\n            processor: shaderProcessor ?? this._engine._getShaderProcessor(this._shaderLanguage),\r\n            supportsUniformBuffers: this._engine.supportsUniformBuffers,\r\n            shadersRepository: EngineShaderStore.GetShadersRepository(this._shaderLanguage),\r\n            includesShadersStore: EngineShaderStore.GetIncludesShadersStore(this._shaderLanguage),\r\n            version: (this._engine.version * 100).toString(),\r\n            platformName: this._engine.shaderPlatformName,\r\n            processingContext: this._processingContext,\r\n            isNDCHalfZRange: this._engine.isNDCHalfZRange,\r\n            useReverseDepthBuffer: this._engine.useReverseDepthBuffer,\r\n            processCodeAfterIncludes: this._processCodeAfterIncludes,\r\n        };\r\n\r\n        _ProcessShaderCode(\r\n            processorOptions,\r\n            this.name,\r\n            this._processFinalCode,\r\n            (migratedVertexCode, migratedFragmentCode) => {\r\n                this._vertexSourceCode = migratedVertexCode;\r\n                this._fragmentSourceCode = migratedFragmentCode;\r\n                this._prepareEffect(keepExistingPipelineContext);\r\n            },\r\n            this._shaderLanguage,\r\n            this._engine,\r\n            this\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Unique key for this effect\r\n     */\r\n    public get key(): string {\r\n        return this._key;\r\n    }\r\n\r\n    /**\r\n     * If the effect has been compiled and prepared.\r\n     * @returns if the effect is compiled and prepared.\r\n     */\r\n    public isReady(): boolean {\r\n        try {\r\n            return this._isReadyInternal();\r\n        } catch {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    private _isReadyInternal(): boolean {\r\n        if (this._engine.isDisposed) {\r\n            // Engine is disposed, we return true to prevent looping over the setTimeout call in _checkIsReady\r\n            return true;\r\n        }\r\n        if (this._isReady) {\r\n            return true;\r\n        }\r\n        if (this._pipelineContext) {\r\n            return this._pipelineContext.isReady;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * The engine the effect was initialized with.\r\n     * @returns the engine.\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * The pipeline context for this effect\r\n     * @returns the associated pipeline context\r\n     */\r\n    public getPipelineContext(): Nullable<IPipelineContext> {\r\n        return this._pipelineContext;\r\n    }\r\n\r\n    /**\r\n     * The set of names of attribute variables for the shader.\r\n     * @returns An array of attribute names.\r\n     */\r\n    public getAttributesNames(): string[] {\r\n        return this._attributesNames;\r\n    }\r\n\r\n    /**\r\n     * Returns the attribute at the given index.\r\n     * @param index The index of the attribute.\r\n     * @returns The location of the attribute.\r\n     */\r\n    public getAttributeLocation(index: number): number {\r\n        return this._attributes[index];\r\n    }\r\n\r\n    /**\r\n     * Returns the attribute based on the name of the variable.\r\n     * @param name of the attribute to look up.\r\n     * @returns the attribute location.\r\n     */\r\n    public getAttributeLocationByName(name: string): number {\r\n        return this._attributeLocationByName[name];\r\n    }\r\n\r\n    /**\r\n     * The number of attributes.\r\n     * @returns the number of attributes.\r\n     */\r\n    public getAttributesCount(): number {\r\n        return this._attributes.length;\r\n    }\r\n\r\n    /**\r\n     * Gets the index of a uniform variable.\r\n     * @param uniformName of the uniform to look up.\r\n     * @returns the index.\r\n     */\r\n    public getUniformIndex(uniformName: string): number {\r\n        return this._uniformsNames.indexOf(uniformName);\r\n    }\r\n\r\n    /**\r\n     * Returns the attribute based on the name of the variable.\r\n     * @param uniformName of the uniform to look up.\r\n     * @returns the location of the uniform.\r\n     */\r\n    public getUniform(uniformName: string): Nullable<WebGLUniformLocation> {\r\n        return this._uniforms[uniformName];\r\n    }\r\n\r\n    /**\r\n     * Returns an array of sampler variable names\r\n     * @returns The array of sampler variable names.\r\n     */\r\n    public getSamplers(): string[] {\r\n        return this._samplerList;\r\n    }\r\n\r\n    /**\r\n     * Returns an array of uniform variable names\r\n     * @returns The array of uniform variable names.\r\n     */\r\n    public getUniformNames(): string[] {\r\n        return this._uniformsNames;\r\n    }\r\n\r\n    /**\r\n     * Returns an array of uniform buffer variable names\r\n     * @returns The array of uniform buffer variable names.\r\n     */\r\n    public getUniformBuffersNames(): string[] {\r\n        return this._uniformBuffersNamesList;\r\n    }\r\n\r\n    /**\r\n     * Returns the index parameters used to create the effect\r\n     * @returns The index parameters object\r\n     */\r\n    public getIndexParameters(): any {\r\n        return this._indexParameters;\r\n    }\r\n\r\n    /**\r\n     * The error from the last compilation.\r\n     * @returns the error string.\r\n     */\r\n    public getCompilationError(): string {\r\n        return this._compilationError;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that all fallbacks were used during compilation\r\n     * @returns true if all fallbacks were used\r\n     */\r\n    public allFallbacksProcessed(): boolean {\r\n        return this._allFallbacksProcessed;\r\n    }\r\n\r\n    /**\r\n     * Wait until compilation before fulfilling.\r\n     * @returns a promise to wait for completion.\r\n     */\r\n    public async whenCompiledAsync(): Promise<Effect> {\r\n        return await new Promise((resolve) => {\r\n            this.executeWhenCompiled(resolve);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds a callback to the onCompiled observable and call the callback immediately if already ready.\r\n     * @param func The callback to be used.\r\n     */\r\n    public executeWhenCompiled(func: (effect: Effect) => void): void {\r\n        if (this.isReady()) {\r\n            func(this);\r\n            return;\r\n        }\r\n\r\n        this.onCompileObservable.add((effect) => {\r\n            func(effect);\r\n        });\r\n\r\n        if (!this._pipelineContext || this._pipelineContext.isAsync) {\r\n            this._checkIsReady(null);\r\n        }\r\n    }\r\n\r\n    private _checkIsReady(previousPipelineContext: Nullable<IPipelineContext>) {\r\n        _RetryWithInterval(\r\n            () => {\r\n                return this._isReadyInternal() || this._isDisposed;\r\n            },\r\n            () => {\r\n                // no-op - done in the _isReadyInternal call\r\n            },\r\n            (e) => {\r\n                this._processCompilationErrors(e, previousPipelineContext);\r\n            },\r\n            16,\r\n            120000,\r\n            true,\r\n            ` - Effect: ${typeof this.name === \"string\" ? this.name : this.key}`\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex shader source code of this effect\r\n     * This is the final source code that will be compiled, after all the processing has been done (pre-processing applied, code injection/replacement, etc)\r\n     */\r\n    public get vertexSourceCode(): string {\r\n        return this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride\r\n            ? this._vertexSourceCodeOverride\r\n            : (this._pipelineContext?._getVertexShaderCode() ?? this._vertexSourceCode);\r\n    }\r\n\r\n    /**\r\n     * Gets the fragment shader source code of this effect\r\n     * This is the final source code that will be compiled, after all the processing has been done (pre-processing applied, code injection/replacement, etc)\r\n     */\r\n    public get fragmentSourceCode(): string {\r\n        return this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride\r\n            ? this._fragmentSourceCodeOverride\r\n            : (this._pipelineContext?._getFragmentShaderCode() ?? this._fragmentSourceCode);\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex shader source code before migration.\r\n     * This is the source code after the include directives have been replaced by their contents but before the code is migrated, i.e. before ShaderProcess._ProcessShaderConversion is executed.\r\n     * This method is, among other things, responsible for parsing #if/#define directives as well as converting GLES2 syntax to GLES3 (in the case of WebGL).\r\n     */\r\n    public get vertexSourceCodeBeforeMigration(): string {\r\n        return this._vertexSourceCodeBeforeMigration;\r\n    }\r\n\r\n    /**\r\n     * Gets the fragment shader source code before migration.\r\n     * This is the source code after the include directives have been replaced by their contents but before the code is migrated, i.e. before ShaderProcess._ProcessShaderConversion is executed.\r\n     * This method is, among other things, responsible for parsing #if/#define directives as well as converting GLES2 syntax to GLES3 (in the case of WebGL).\r\n     */\r\n    public get fragmentSourceCodeBeforeMigration(): string {\r\n        return this._fragmentSourceCodeBeforeMigration;\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex shader source code before it has been modified by any processing\r\n     */\r\n    public get rawVertexSourceCode(): string {\r\n        return this._rawVertexSourceCode;\r\n    }\r\n\r\n    /**\r\n     * Gets the fragment shader source code before it has been modified by any processing\r\n     */\r\n    public get rawFragmentSourceCode(): string {\r\n        return this._rawFragmentSourceCode;\r\n    }\r\n\r\n    /**\r\n     * Gets the pipeline generation options for this effect.\r\n     * @returns the pipeline generation options for this effect\r\n     */\r\n    public getPipelineGenerationOptions(): IPipelineGenerationOptions {\r\n        return {\r\n            platformName: this._engine.shaderPlatformName,\r\n            shaderLanguage: this._shaderLanguage,\r\n            shaderNameOrContent: this.name,\r\n            key: this._key,\r\n            defines: this.defines.split(\"\\n\"),\r\n            addGlobalDefines: false,\r\n            extendedProcessingOptions: {\r\n                indexParameters: this._indexParameters,\r\n                isNDCHalfZRange: this._engine.isNDCHalfZRange,\r\n                useReverseDepthBuffer: this._engine.useReverseDepthBuffer,\r\n                supportsUniformBuffers: this._engine.supportsUniformBuffers,\r\n            },\r\n            extendedCreatePipelineOptions: {\r\n                transformFeedbackVaryings: this._transformFeedbackVaryings,\r\n                createAsRaw: !!(this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride),\r\n            },\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Recompiles the webGL program\r\n     * @param vertexSourceCode The source code for the vertex shader.\r\n     * @param fragmentSourceCode The source code for the fragment shader.\r\n     * @param onCompiled Callback called when completed.\r\n     * @param onError Callback called on error.\r\n     * @internal\r\n     */\r\n    public _rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (pipelineContext: IPipelineContext) => void, onError: (message: string) => void) {\r\n        this._isReady = false;\r\n\r\n        this._vertexSourceCodeOverride = vertexSourceCode;\r\n        this._fragmentSourceCodeOverride = fragmentSourceCode;\r\n        this.onError = (effect, error) => {\r\n            if (onError) {\r\n                onError(error);\r\n            }\r\n        };\r\n        this.onCompiled = () => {\r\n            const scenes = this.getEngine().scenes;\r\n            if (scenes) {\r\n                for (let i = 0; i < scenes.length; i++) {\r\n                    scenes[i].markAllMaterialsAsDirty(Constants.MATERIAL_AllDirtyFlag);\r\n                }\r\n            }\r\n\r\n            this._pipelineContext!._handlesSpectorRebuildCallback?.(onCompiled);\r\n        };\r\n        this._fallbacks = null;\r\n        this._prepareEffect();\r\n    }\r\n\r\n    private _onRenderingStateCompiled(pipelineContext: IPipelineContext) {\r\n        this._pipelineContext = pipelineContext;\r\n        this._pipelineContext.setEngine(this._engine);\r\n        this._attributes = [];\r\n        this._pipelineContext._fillEffectInformation(\r\n            this,\r\n            this._uniformBuffersNames,\r\n            this._uniformsNames,\r\n            this._uniforms,\r\n            this._samplerList,\r\n            this._samplers,\r\n            this._attributesNames,\r\n            this._attributes\r\n        );\r\n\r\n        // Caches attribute locations.\r\n        if (this._attributesNames) {\r\n            for (let i = 0; i < this._attributesNames.length; i++) {\r\n                const name = this._attributesNames[i];\r\n                this._attributeLocationByName[name] = this._attributes[i];\r\n            }\r\n        }\r\n\r\n        this._engine.bindSamplers(this);\r\n\r\n        this._compilationError = \"\";\r\n        this._isReady = true;\r\n        if (this.onCompiled) {\r\n            this.onCompiled(this);\r\n        }\r\n        this.onCompileObservable.notifyObservers(this);\r\n        this.onCompileObservable.clear();\r\n\r\n        // Unbind mesh reference in fallbacks\r\n        if (this._fallbacks) {\r\n            this._fallbacks.unBindMesh();\r\n        }\r\n\r\n        if (Effect.AutomaticallyClearCodeCache) {\r\n            this.clearCodeCache();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepares the effect\r\n     * @internal\r\n     */\r\n    public _prepareEffect(keepExistingPipelineContext = false) {\r\n        const previousPipelineContext = this._pipelineContext;\r\n\r\n        this._isReady = false;\r\n\r\n        try {\r\n            const overrides = !!(this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride);\r\n            const defines = overrides ? null : this.defines;\r\n            const vertex = overrides ? this._vertexSourceCodeOverride : this._vertexSourceCode;\r\n            const fragment = overrides ? this._fragmentSourceCodeOverride : this._fragmentSourceCode;\r\n            const engine = this._engine;\r\n            this._pipelineContext = createAndPreparePipelineContext(\r\n                {\r\n                    existingPipelineContext: keepExistingPipelineContext ? previousPipelineContext : null,\r\n                    vertex,\r\n                    fragment,\r\n                    context: engine.shaderPlatformName === \"WEBGL2\" || engine.shaderPlatformName === \"WEBGL1\" ? (engine as any)._gl : undefined,\r\n                    rebuildRebind: (\r\n                        vertexSourceCode: string,\r\n                        fragmentSourceCode: string,\r\n                        onCompiled: (pipelineContext: IPipelineContext) => void,\r\n                        onError: (message: string) => void\r\n                    ) => this._rebuildProgram(vertexSourceCode, fragmentSourceCode, onCompiled, onError),\r\n                    defines,\r\n                    transformFeedbackVaryings: this._transformFeedbackVaryings,\r\n                    name: this._key.replace(/\\r/g, \"\").replace(/\\n/g, \"|\"),\r\n                    createAsRaw: overrides,\r\n                    disableParallelCompilation: this._disableParallelShaderCompilation,\r\n                    shaderProcessingContext: this._processingContext,\r\n                    onRenderingStateCompiled: (pipelineContext) => {\r\n                        if (previousPipelineContext && !keepExistingPipelineContext) {\r\n                            this._engine._deletePipelineContext(previousPipelineContext);\r\n                        }\r\n                        if (pipelineContext) {\r\n                            this._onRenderingStateCompiled(pipelineContext);\r\n                        }\r\n                    },\r\n                },\r\n                this._engine.createPipelineContext.bind(this._engine),\r\n                this._engine._preparePipelineContextAsync.bind(this._engine),\r\n                this._engine._executeWhenRenderingStateIsCompiled.bind(this._engine)\r\n            );\r\n\r\n            if (this._pipelineContext.isAsync) {\r\n                this._checkIsReady(previousPipelineContext);\r\n            }\r\n        } catch (e) {\r\n            this._processCompilationErrors(e, previousPipelineContext);\r\n        }\r\n    }\r\n\r\n    private _getShaderCodeAndErrorLine(code: Nullable<string>, error: Nullable<string>, isFragment: boolean): [Nullable<string>, Nullable<string>] {\r\n        const regexp = isFragment ? /FRAGMENT SHADER ERROR: 0:(\\d+?):/ : /VERTEX SHADER ERROR: 0:(\\d+?):/;\r\n\r\n        let errorLine = null;\r\n\r\n        if (error && code) {\r\n            const res = error.match(regexp);\r\n            if (res && res.length === 2) {\r\n                const lineNumber = parseInt(res[1]);\r\n                const lines = code.split(\"\\n\", -1);\r\n                if (lines.length >= lineNumber) {\r\n                    errorLine = `Offending line [${lineNumber}] in ${isFragment ? \"fragment\" : \"vertex\"} code: ${lines[lineNumber - 1]}`;\r\n                }\r\n            }\r\n        }\r\n\r\n        return [code, errorLine];\r\n    }\r\n\r\n    private _processCompilationErrors(e: any, previousPipelineContext: Nullable<IPipelineContext> = null) {\r\n        this._compilationError = typeof e?.stack === \"string\" ? e.stack : (e?.message ?? String(e));\r\n        const attributesNames = this._attributesNames;\r\n        const fallbacks = this._fallbacks;\r\n\r\n        // Let's go through fallbacks then\r\n        Logger.Error(\"Unable to compile effect:\");\r\n        Logger.Error(`Uniforms: ${this._uniformsNames.join(\" \")}`);\r\n        Logger.Error(`Attributes: ${attributesNames.join(\" \")}`);\r\n        Logger.Error(\"Defines:\\n\" + this.defines);\r\n        if (Effect.LogShaderCodeOnCompilationError) {\r\n            let lineErrorVertex = null,\r\n                lineErrorFragment = null;\r\n            let code: Nullable<string>;\r\n            if (this._pipelineContext?._getVertexShaderCode()) {\r\n                [code, lineErrorVertex] = this._getShaderCodeAndErrorLine(this._pipelineContext._getVertexShaderCode(), this._compilationError, false);\r\n                if (code) {\r\n                    Logger.Error(\"Vertex code:\");\r\n                    Logger.Error(code);\r\n                }\r\n            }\r\n            if (this._pipelineContext?._getFragmentShaderCode()) {\r\n                [code, lineErrorFragment] = this._getShaderCodeAndErrorLine(this._pipelineContext?._getFragmentShaderCode(), this._compilationError, true);\r\n                if (code) {\r\n                    Logger.Error(\"Fragment code:\");\r\n                    Logger.Error(code);\r\n                }\r\n            }\r\n            if (lineErrorVertex) {\r\n                Logger.Error(lineErrorVertex);\r\n            }\r\n            if (lineErrorFragment) {\r\n                Logger.Error(lineErrorFragment);\r\n            }\r\n        }\r\n        Logger.Error(\"Error: \" + this._compilationError);\r\n\r\n        const notifyErrors = () => {\r\n            if (this.onError) {\r\n                this.onError(this, this._compilationError);\r\n            }\r\n            this.onErrorObservable.notifyObservers(this);\r\n            this._engine.onEffectErrorObservable.notifyObservers({ effect: this, errors: this._compilationError });\r\n        };\r\n\r\n        // In case a previous compilation was successful, we need to restore the previous pipeline context\r\n        if (previousPipelineContext) {\r\n            this._pipelineContext = previousPipelineContext;\r\n            this._isReady = true;\r\n            notifyErrors();\r\n        }\r\n\r\n        // Lets try to compile fallbacks as long as we have some.\r\n        if (fallbacks) {\r\n            this._pipelineContext = null;\r\n            if (fallbacks.hasMoreFallbacks) {\r\n                this._allFallbacksProcessed = false;\r\n                Logger.Error(\"Trying next fallback.\");\r\n                this.defines = fallbacks.reduce(this.defines, this);\r\n                this._prepareEffect();\r\n            } else {\r\n                // Sorry we did everything we can\r\n                this._allFallbacksProcessed = true;\r\n                notifyErrors();\r\n                this.onErrorObservable.clear();\r\n\r\n                // Unbind mesh reference in fallbacks\r\n                if (this._fallbacks) {\r\n                    this._fallbacks.unBindMesh();\r\n                }\r\n            }\r\n        } else {\r\n            this._allFallbacksProcessed = true;\r\n\r\n            // In case of error, without any prior successful compilation, let s notify observers\r\n            if (!previousPipelineContext) {\r\n                notifyErrors();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if the effect is supported. (Must be called after compilation)\r\n     */\r\n    public get isSupported(): boolean {\r\n        return this._compilationError === \"\";\r\n    }\r\n\r\n    /**\r\n     * Binds a texture to the engine to be used as output of the shader.\r\n     * @param channel Name of the output variable.\r\n     * @param texture Texture to bind.\r\n     * @internal\r\n     */\r\n    public _bindTexture(channel: string, texture: Nullable<InternalTexture>): void {\r\n        this._engine._bindTexture(this._samplers[channel], texture, channel);\r\n    }\r\n\r\n    /**\r\n     * Sets a texture on the engine to be used in the shader.\r\n     * @param channel Name of the sampler variable.\r\n     * @param texture Texture to set.\r\n     */\r\n    public setTexture(channel: string, texture: Nullable<ThinTexture>): void {\r\n        this._engine.setTexture(this._samplers[channel], this._uniforms[channel], texture, channel);\r\n    }\r\n\r\n    /**\r\n     * Sets an array of textures on the engine to be used in the shader.\r\n     * @param channel Name of the variable.\r\n     * @param textures Textures to set.\r\n     */\r\n    public setTextureArray(channel: string, textures: ThinTexture[]): void {\r\n        const exName = channel + \"Ex\";\r\n        if (this._samplerList.indexOf(exName + \"0\") === -1) {\r\n            const initialPos = this._samplerList.indexOf(channel);\r\n            for (let index = 1; index < textures.length; index++) {\r\n                const currentExName = exName + (index - 1).toString();\r\n                this._samplerList.splice(initialPos + index, 0, currentExName);\r\n            }\r\n\r\n            // Reset every channels\r\n            let channelIndex = 0;\r\n            for (const key of this._samplerList) {\r\n                this._samplers[key] = channelIndex;\r\n                channelIndex += 1;\r\n            }\r\n        }\r\n\r\n        this._engine.setTextureArray(this._samplers[channel], this._uniforms[channel], textures, channel);\r\n    }\r\n\r\n    /**\r\n     * Binds a buffer to a uniform.\r\n     * @param buffer Buffer to bind.\r\n     * @param name Name of the uniform variable to bind to.\r\n     */\r\n    public bindUniformBuffer(buffer: DataBuffer, name: string): void {\r\n        const bufferName = this._uniformBuffersNames[name];\r\n        if (bufferName === undefined || (Effect._BaseCache[bufferName] === buffer && this._engine._features.useUBOBindingCache)) {\r\n            return;\r\n        }\r\n        Effect._BaseCache[bufferName] = buffer;\r\n        this._engine.bindUniformBufferBase(buffer, bufferName, name);\r\n    }\r\n\r\n    /**\r\n     * Binds block to a uniform.\r\n     * @param blockName Name of the block to bind.\r\n     * @param index Index to bind.\r\n     */\r\n    public bindUniformBlock(blockName: string, index: number): void {\r\n        this._engine.bindUniformBlock(this._pipelineContext!, blockName, index);\r\n    }\r\n\r\n    /**\r\n     * Sets an integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setInt(uniformName: string, value: number): Effect {\r\n        this._pipelineContext!.setInt(uniformName, value);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int2 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int2.\r\n     * @param y Second int in int2.\r\n     * @returns this effect.\r\n     */\r\n    public setInt2(uniformName: string, x: number, y: number): Effect {\r\n        this._pipelineContext!.setInt2(uniformName, x, y);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int3 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int3.\r\n     * @param y Second int in int3.\r\n     * @param z Third int in int3.\r\n     * @returns this effect.\r\n     */\r\n    public setInt3(uniformName: string, x: number, y: number, z: number): Effect {\r\n        this._pipelineContext!.setInt3(uniformName, x, y, z);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int4 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int4.\r\n     * @param y Second int in int4.\r\n     * @param z Third int in int4.\r\n     * @param w Fourth int in int4.\r\n     * @returns this effect.\r\n     */\r\n    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): Effect {\r\n        this._pipelineContext!.setInt4(uniformName, x, y, z, w);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setIntArray(uniformName: string, array: Int32Array): Effect {\r\n        this._pipelineContext!.setIntArray(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setIntArray2(uniformName: string, array: Int32Array): Effect {\r\n        this._pipelineContext!.setIntArray2(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setIntArray3(uniformName: string, array: Int32Array): Effect {\r\n        this._pipelineContext!.setIntArray3(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setIntArray4(uniformName: string, array: Int32Array): Effect {\r\n        this._pipelineContext!.setIntArray4(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setUInt(uniformName: string, value: number): Effect {\r\n        this._pipelineContext!.setUInt(uniformName, value);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int2 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint2.\r\n     * @param y Second unsigned int in uint2.\r\n     * @returns this effect.\r\n     */\r\n    public setUInt2(uniformName: string, x: number, y: number): Effect {\r\n        this._pipelineContext!.setUInt2(uniformName, x, y);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int3 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint3.\r\n     * @param y Second unsigned int in uint3.\r\n     * @param z Third unsigned int in uint3.\r\n     * @returns this effect.\r\n     */\r\n    public setUInt3(uniformName: string, x: number, y: number, z: number): Effect {\r\n        this._pipelineContext!.setUInt3(uniformName, x, y, z);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int4 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint4.\r\n     * @param y Second unsigned int in uint4.\r\n     * @param z Third unsigned int in uint4.\r\n     * @param w Fourth unsigned int in uint4.\r\n     * @returns this effect.\r\n     */\r\n    public setUInt4(uniformName: string, x: number, y: number, z: number, w: number): Effect {\r\n        this._pipelineContext!.setUInt4(uniformName, x, y, z, w);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setUIntArray(uniformName: string, array: Uint32Array): Effect {\r\n        this._pipelineContext!.setUIntArray(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setUIntArray2(uniformName: string, array: Uint32Array): Effect {\r\n        this._pipelineContext!.setUIntArray2(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setUIntArray3(uniformName: string, array: Uint32Array): Effect {\r\n        this._pipelineContext!.setUIntArray3(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setUIntArray4(uniformName: string, array: Uint32Array): Effect {\r\n        this._pipelineContext!.setUIntArray4(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an float array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setFloatArray(uniformName: string, array: FloatArray): Effect {\r\n        this._pipelineContext!.setArray(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an float array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setFloatArray2(uniformName: string, array: FloatArray): Effect {\r\n        this._pipelineContext!.setArray2(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an float array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setFloatArray3(uniformName: string, array: FloatArray): Effect {\r\n        this._pipelineContext!.setArray3(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an float array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setFloatArray4(uniformName: string, array: FloatArray): Effect {\r\n        this._pipelineContext!.setArray4(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setArray(uniformName: string, array: number[]): Effect {\r\n        this._pipelineContext!.setArray(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setArray2(uniformName: string, array: number[]): Effect {\r\n        this._pipelineContext!.setArray2(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setArray3(uniformName: string, array: number[]): Effect {\r\n        this._pipelineContext!.setArray3(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setArray4(uniformName: string, array: number[]): Effect {\r\n        this._pipelineContext!.setArray4(uniformName, array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets matrices on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrices matrices to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setMatrices(uniformName: string, matrices: Float32Array | Array<number>): Effect {\r\n        this._pipelineContext!.setMatrices(uniformName, matrices as Float32Array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets matrix on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setMatrix(uniformName: string, matrix: IMatrixLike): Effect {\r\n        this._pipelineContext!.setMatrix(uniformName, matrix);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a 3x3 matrix on a uniform variable. (Specified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setMatrix3x3(uniformName: string, matrix: Float32Array | Array<number>): Effect {\r\n        // the cast is ok because it is gl.uniformMatrix3fv() which is called at the end, and this function accepts Float32Array and Array<number>\r\n        this._pipelineContext!.setMatrix3x3(uniformName, matrix as Float32Array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a 2x2 matrix on a uniform variable. (Specified as [1,2,3,4] will result in [1,2][3,4] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setMatrix2x2(uniformName: string, matrix: Float32Array | Array<number>): Effect {\r\n        // the cast is ok because it is gl.uniformMatrix3fv() which is called at the end, and this function accepts Float32Array and Array<number>\r\n        this._pipelineContext!.setMatrix2x2(uniformName, matrix as Float32Array);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a float on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setFloat(uniformName: string, value: number): Effect {\r\n        this._pipelineContext!.setFloat(uniformName, value);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a boolean on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param bool value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setBool(uniformName: string, bool: boolean): Effect {\r\n        this._pipelineContext!.setInt(uniformName, bool ? 1 : 0);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector2 vector2 to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setVector2(uniformName: string, vector2: IVector2Like): Effect {\r\n        this._pipelineContext!.setVector2(uniformName, vector2);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a float2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float2.\r\n     * @param y Second float in float2.\r\n     * @returns this effect.\r\n     */\r\n    public setFloat2(uniformName: string, x: number, y: number): Effect {\r\n        this._pipelineContext!.setFloat2(uniformName, x, y);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector3 Value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setVector3(uniformName: string, vector3: IVector3Like): Effect {\r\n        this._pipelineContext!.setVector3(uniformName, vector3);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a float3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float3.\r\n     * @param y Second float in float3.\r\n     * @param z Third float in float3.\r\n     * @returns this effect.\r\n     */\r\n    public setFloat3(uniformName: string, x: number, y: number, z: number): Effect {\r\n        this._pipelineContext!.setFloat3(uniformName, x, y, z);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector4 Value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setVector4(uniformName: string, vector4: IVector4Like): Effect {\r\n        this._pipelineContext!.setVector4(uniformName, vector4);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Quaternion on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param quaternion Value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setQuaternion(uniformName: string, quaternion: IQuaternionLike): Effect {\r\n        this._pipelineContext!.setQuaternion(uniformName, quaternion);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a float4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float4.\r\n     * @param y Second float in float4.\r\n     * @param z Third float in float4.\r\n     * @param w Fourth float in float4.\r\n     * @returns this effect.\r\n     */\r\n    public setFloat4(uniformName: string, x: number, y: number, z: number, w: number): Effect {\r\n        this._pipelineContext!.setFloat4(uniformName, x, y, z, w);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Color3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setColor3(uniformName: string, color3: IColor3Like): Effect {\r\n        this._pipelineContext!.setColor3(uniformName, color3);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     * @param alpha Alpha value to be set.\r\n     * @returns this effect.\r\n     */\r\n    public setColor4(uniformName: string, color3: IColor3Like, alpha: number): Effect {\r\n        this._pipelineContext!.setColor4(uniformName, color3, alpha);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable\r\n     * @param uniformName defines the name of the variable\r\n     * @param color4 defines the value to be set\r\n     * @returns this effect.\r\n     */\r\n    public setDirectColor4(uniformName: string, color4: IColor4Like): Effect {\r\n        this._pipelineContext!.setDirectColor4(uniformName, color4);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Use this wisely: It will remove the cached code from this effect\r\n     * It is probably ok to call it if you are not using ShadowDepthWrapper or if everything is already up and running\r\n     * DO NOT CALL IT if you want to have support for context lost recovery\r\n     */\r\n    public clearCodeCache() {\r\n        this._vertexSourceCode = \"\";\r\n        this._fragmentSourceCode = \"\";\r\n        this._fragmentSourceCodeBeforeMigration = \"\";\r\n        this._vertexSourceCodeBeforeMigration = \"\";\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources.\r\n     * @param force specifies if the effect must be released no matter what\r\n     **/\r\n    public dispose(force = false) {\r\n        if (force) {\r\n            this._refCount = 0;\r\n        } else {\r\n            if (Effect.PersistentMode) {\r\n                return;\r\n            }\r\n            this._refCount--;\r\n        }\r\n\r\n        if (this._refCount > 0 || this._isDisposed) {\r\n            // Others are still using the effect or the effect was already disposed\r\n            return;\r\n        }\r\n\r\n        if (this._onReleaseEffectsObserver) {\r\n            this._engine.onReleaseEffectsObservable.remove(this._onReleaseEffectsObserver);\r\n            this._onReleaseEffectsObserver = null;\r\n        }\r\n\r\n        if (this._pipelineContext) {\r\n            resetCachedPipeline(this._pipelineContext);\r\n        }\r\n        this._engine._releaseEffect(this);\r\n\r\n        this.clearCodeCache();\r\n\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    /**\r\n     * This function will add a new shader to the shader store\r\n     * @param name the name of the shader\r\n     * @param pixelShader optional pixel shader content\r\n     * @param vertexShader optional vertex shader content\r\n     * @param shaderLanguage the language the shader is written in (default: GLSL)\r\n     */\r\n    public static RegisterShader(name: string, pixelShader?: string, vertexShader?: string, shaderLanguage = ShaderLanguage.GLSL) {\r\n        if (pixelShader) {\r\n            EngineShaderStore.GetShadersStore(shaderLanguage)[`${name}PixelShader`] = pixelShader;\r\n        }\r\n\r\n        if (vertexShader) {\r\n            EngineShaderStore.GetShadersStore(shaderLanguage)[`${name}VertexShader`] = vertexShader;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Store of each shader (The can be looked up using effect.key)\r\n     */\r\n    public static ShadersStore: { [key: string]: string } = EngineShaderStore.ShadersStore;\r\n    /**\r\n     * Store of each included file for a shader (The can be looked up using effect.key)\r\n     */\r\n    public static IncludesShadersStore: { [key: string]: string } = EngineShaderStore.IncludesShadersStore;\r\n\r\n    /**\r\n     * Resets the cache of effects.\r\n     */\r\n    public static ResetCache() {\r\n        Effect._BaseCache = {};\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class DepthCullingState {\r\n    protected _isDepthTestDirty = false;\r\n    protected _isDepthMaskDirty = false;\r\n    protected _isDepthFuncDirty = false;\r\n    protected _isCullFaceDirty = false;\r\n    protected _isCullDirty = false;\r\n    protected _isZOffsetDirty = false;\r\n    protected _isFrontFaceDirty = false;\r\n\r\n    protected _depthTest: boolean;\r\n    protected _depthMask: boolean;\r\n    protected _depthFunc: Nullable<number>;\r\n    protected _cull: Nullable<boolean>;\r\n    protected _cullFace: Nullable<number>;\r\n    protected _zOffset: number;\r\n    protected _zOffsetUnits: number;\r\n    protected _frontFace: Nullable<number>;\r\n\r\n    /**\r\n     * Initializes the state.\r\n     * @param reset\r\n     */\r\n    public constructor(reset = true) {\r\n        if (reset) {\r\n            this.reset();\r\n        }\r\n    }\r\n\r\n    public get isDirty(): boolean {\r\n        return (\r\n            this._isDepthFuncDirty ||\r\n            this._isDepthTestDirty ||\r\n            this._isDepthMaskDirty ||\r\n            this._isCullFaceDirty ||\r\n            this._isCullDirty ||\r\n            this._isZOffsetDirty ||\r\n            this._isFrontFaceDirty\r\n        );\r\n    }\r\n\r\n    public get zOffset(): number {\r\n        return this._zOffset;\r\n    }\r\n\r\n    public set zOffset(value: number) {\r\n        if (this._zOffset === value) {\r\n            return;\r\n        }\r\n\r\n        this._zOffset = value;\r\n        this._isZOffsetDirty = true;\r\n    }\r\n\r\n    public get zOffsetUnits(): number {\r\n        return this._zOffsetUnits;\r\n    }\r\n\r\n    public set zOffsetUnits(value: number) {\r\n        if (this._zOffsetUnits === value) {\r\n            return;\r\n        }\r\n\r\n        this._zOffsetUnits = value;\r\n        this._isZOffsetDirty = true;\r\n    }\r\n\r\n    public get cullFace(): Nullable<number> {\r\n        return this._cullFace;\r\n    }\r\n\r\n    public set cullFace(value: Nullable<number>) {\r\n        if (this._cullFace === value) {\r\n            return;\r\n        }\r\n\r\n        this._cullFace = value;\r\n        this._isCullFaceDirty = true;\r\n    }\r\n\r\n    public get cull(): Nullable<boolean> {\r\n        return this._cull;\r\n    }\r\n\r\n    public set cull(value: Nullable<boolean>) {\r\n        if (this._cull === value) {\r\n            return;\r\n        }\r\n\r\n        this._cull = value;\r\n        this._isCullDirty = true;\r\n    }\r\n\r\n    public get depthFunc(): Nullable<number> {\r\n        return this._depthFunc;\r\n    }\r\n\r\n    public set depthFunc(value: Nullable<number>) {\r\n        if (this._depthFunc === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthFunc = value;\r\n        this._isDepthFuncDirty = true;\r\n    }\r\n\r\n    public get depthMask(): boolean {\r\n        return this._depthMask;\r\n    }\r\n\r\n    public set depthMask(value: boolean) {\r\n        if (this._depthMask === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthMask = value;\r\n        this._isDepthMaskDirty = true;\r\n    }\r\n\r\n    public get depthTest(): boolean {\r\n        return this._depthTest;\r\n    }\r\n\r\n    public set depthTest(value: boolean) {\r\n        if (this._depthTest === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthTest = value;\r\n        this._isDepthTestDirty = true;\r\n    }\r\n\r\n    public get frontFace(): Nullable<number> {\r\n        return this._frontFace;\r\n    }\r\n\r\n    public set frontFace(value: Nullable<number>) {\r\n        if (this._frontFace === value) {\r\n            return;\r\n        }\r\n\r\n        this._frontFace = value;\r\n        this._isFrontFaceDirty = true;\r\n    }\r\n\r\n    public reset() {\r\n        this._depthMask = true;\r\n        this._depthTest = true;\r\n        this._depthFunc = null;\r\n        this._cullFace = null;\r\n        this._cull = null;\r\n        this._zOffset = 0;\r\n        this._zOffsetUnits = 0;\r\n        this._frontFace = null;\r\n\r\n        this._isDepthTestDirty = true;\r\n        this._isDepthMaskDirty = true;\r\n        this._isDepthFuncDirty = false;\r\n        this._isCullFaceDirty = false;\r\n        this._isCullDirty = false;\r\n        this._isZOffsetDirty = true;\r\n        this._isFrontFaceDirty = false;\r\n    }\r\n\r\n    public apply(gl: WebGLRenderingContext) {\r\n        if (!this.isDirty) {\r\n            return;\r\n        }\r\n\r\n        // Cull\r\n        if (this._isCullDirty) {\r\n            if (this.cull) {\r\n                gl.enable(gl.CULL_FACE);\r\n            } else {\r\n                gl.disable(gl.CULL_FACE);\r\n            }\r\n\r\n            this._isCullDirty = false;\r\n        }\r\n\r\n        // Cull face\r\n        if (this._isCullFaceDirty) {\r\n            gl.cullFace(<number>this.cullFace);\r\n            this._isCullFaceDirty = false;\r\n        }\r\n\r\n        // Depth mask\r\n        if (this._isDepthMaskDirty) {\r\n            gl.depthMask(this.depthMask);\r\n            this._isDepthMaskDirty = false;\r\n        }\r\n\r\n        // Depth test\r\n        if (this._isDepthTestDirty) {\r\n            if (this.depthTest) {\r\n                gl.enable(gl.DEPTH_TEST);\r\n            } else {\r\n                gl.disable(gl.DEPTH_TEST);\r\n            }\r\n            this._isDepthTestDirty = false;\r\n        }\r\n\r\n        // Depth func\r\n        if (this._isDepthFuncDirty) {\r\n            gl.depthFunc(<number>this.depthFunc);\r\n            this._isDepthFuncDirty = false;\r\n        }\r\n\r\n        // zOffset\r\n        if (this._isZOffsetDirty) {\r\n            if (this.zOffset || this.zOffsetUnits) {\r\n                gl.enable(gl.POLYGON_OFFSET_FILL);\r\n                gl.polygonOffset(this.zOffset, this.zOffsetUnits);\r\n            } else {\r\n                gl.disable(gl.POLYGON_OFFSET_FILL);\r\n            }\r\n\r\n            this._isZOffsetDirty = false;\r\n        }\r\n\r\n        // Front face\r\n        if (this._isFrontFaceDirty) {\r\n            gl.frontFace(<number>this.frontFace);\r\n            this._isFrontFaceDirty = false;\r\n        }\r\n    }\r\n}\r\n","import { type IStencilState } from \"./IStencilState\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class StencilStateComposer {\r\n    protected _isStencilTestDirty = false;\r\n    protected _isStencilMaskDirty = false;\r\n    protected _isStencilFuncDirty = false;\r\n    protected _isStencilOpDirty = false;\r\n\r\n    protected _enabled: boolean;\r\n\r\n    protected _mask: number;\r\n\r\n    protected _func: number;\r\n    protected _funcRef: number;\r\n    protected _funcMask: number;\r\n\r\n    protected _opStencilFail: number;\r\n    protected _opDepthFail: number;\r\n    protected _opStencilDepthPass: number;\r\n\r\n    protected _backFunc: number;\r\n    protected _backOpStencilFail: number;\r\n    protected _backOpDepthFail: number;\r\n    protected _backOpStencilDepthPass: number;\r\n\r\n    public stencilGlobal: IStencilState;\r\n    public stencilMaterial: IStencilState | undefined;\r\n\r\n    public useStencilGlobalOnly = false;\r\n\r\n    public get isDirty(): boolean {\r\n        return this._isStencilTestDirty || this._isStencilMaskDirty || this._isStencilFuncDirty || this._isStencilOpDirty;\r\n    }\r\n\r\n    public get func(): number {\r\n        return this._func;\r\n    }\r\n\r\n    public set func(value: number) {\r\n        if (this._func === value) {\r\n            return;\r\n        }\r\n\r\n        this._func = value;\r\n        this._isStencilFuncDirty = true;\r\n    }\r\n\r\n    public get backFunc(): number {\r\n        return this._func;\r\n    }\r\n\r\n    public set backFunc(value: number) {\r\n        if (this._backFunc === value) {\r\n            return;\r\n        }\r\n\r\n        this._backFunc = value;\r\n        this._isStencilFuncDirty = true;\r\n    }\r\n\r\n    public get funcRef(): number {\r\n        return this._funcRef;\r\n    }\r\n\r\n    public set funcRef(value: number) {\r\n        if (this._funcRef === value) {\r\n            return;\r\n        }\r\n\r\n        this._funcRef = value;\r\n        this._isStencilFuncDirty = true;\r\n    }\r\n\r\n    public get funcMask(): number {\r\n        return this._funcMask;\r\n    }\r\n\r\n    public set funcMask(value: number) {\r\n        if (this._funcMask === value) {\r\n            return;\r\n        }\r\n\r\n        this._funcMask = value;\r\n        this._isStencilFuncDirty = true;\r\n    }\r\n\r\n    public get opStencilFail(): number {\r\n        return this._opStencilFail;\r\n    }\r\n\r\n    public set opStencilFail(value: number) {\r\n        if (this._opStencilFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._opStencilFail = value;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public get opDepthFail(): number {\r\n        return this._opDepthFail;\r\n    }\r\n\r\n    public set opDepthFail(value: number) {\r\n        if (this._opDepthFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._opDepthFail = value;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public get opStencilDepthPass(): number {\r\n        return this._opStencilDepthPass;\r\n    }\r\n\r\n    public set opStencilDepthPass(value: number) {\r\n        if (this._opStencilDepthPass === value) {\r\n            return;\r\n        }\r\n\r\n        this._opStencilDepthPass = value;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public get backOpStencilFail(): number {\r\n        return this._backOpStencilFail;\r\n    }\r\n\r\n    public set backOpStencilFail(value: number) {\r\n        if (this._backOpStencilFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._backOpStencilFail = value;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public get backOpDepthFail(): number {\r\n        return this._backOpDepthFail;\r\n    }\r\n\r\n    public set backOpDepthFail(value: number) {\r\n        if (this._backOpDepthFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._backOpDepthFail = value;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public get backOpStencilDepthPass(): number {\r\n        return this._backOpStencilDepthPass;\r\n    }\r\n\r\n    public set backOpStencilDepthPass(value: number) {\r\n        if (this._backOpStencilDepthPass === value) {\r\n            return;\r\n        }\r\n\r\n        this._backOpStencilDepthPass = value;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public get mask(): number {\r\n        return this._mask;\r\n    }\r\n\r\n    public set mask(value: number) {\r\n        if (this._mask === value) {\r\n            return;\r\n        }\r\n\r\n        this._mask = value;\r\n        this._isStencilMaskDirty = true;\r\n    }\r\n\r\n    public get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public set enabled(value: boolean) {\r\n        if (this._enabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._enabled = value;\r\n        this._isStencilTestDirty = true;\r\n    }\r\n\r\n    public constructor(reset = true) {\r\n        if (reset) {\r\n            this.reset();\r\n        }\r\n    }\r\n\r\n    public reset() {\r\n        this.stencilMaterial = undefined;\r\n\r\n        this.stencilGlobal?.reset();\r\n\r\n        this._isStencilTestDirty = true;\r\n        this._isStencilMaskDirty = true;\r\n        this._isStencilFuncDirty = true;\r\n        this._isStencilOpDirty = true;\r\n    }\r\n\r\n    public apply(gl?: WebGLRenderingContext) {\r\n        if (!gl) {\r\n            return;\r\n        }\r\n\r\n        const stencilMaterialEnabled = !this.useStencilGlobalOnly && !!this.stencilMaterial?.enabled;\r\n\r\n        this.enabled = stencilMaterialEnabled ? this.stencilMaterial!.enabled : this.stencilGlobal.enabled;\r\n        this.func = stencilMaterialEnabled ? this.stencilMaterial!.func : this.stencilGlobal.func;\r\n        this.backFunc = stencilMaterialEnabled ? this.stencilMaterial!.backFunc : this.stencilGlobal.backFunc;\r\n        this.funcRef = stencilMaterialEnabled ? this.stencilMaterial!.funcRef : this.stencilGlobal.funcRef;\r\n        this.funcMask = stencilMaterialEnabled ? this.stencilMaterial!.funcMask : this.stencilGlobal.funcMask;\r\n        this.opStencilFail = stencilMaterialEnabled ? this.stencilMaterial!.opStencilFail : this.stencilGlobal.opStencilFail;\r\n        this.opDepthFail = stencilMaterialEnabled ? this.stencilMaterial!.opDepthFail : this.stencilGlobal.opDepthFail;\r\n        this.opStencilDepthPass = stencilMaterialEnabled ? this.stencilMaterial!.opStencilDepthPass : this.stencilGlobal.opStencilDepthPass;\r\n        this.backOpStencilFail = stencilMaterialEnabled ? this.stencilMaterial!.backOpStencilFail : this.stencilGlobal.backOpStencilFail;\r\n        this.backOpDepthFail = stencilMaterialEnabled ? this.stencilMaterial!.backOpDepthFail : this.stencilGlobal.backOpDepthFail;\r\n        this.backOpStencilDepthPass = stencilMaterialEnabled ? this.stencilMaterial!.backOpStencilDepthPass : this.stencilGlobal.backOpStencilDepthPass;\r\n        this.mask = stencilMaterialEnabled ? this.stencilMaterial!.mask : this.stencilGlobal.mask;\r\n\r\n        if (!this.isDirty) {\r\n            return;\r\n        }\r\n\r\n        // Stencil test\r\n        if (this._isStencilTestDirty) {\r\n            if (this.enabled) {\r\n                gl.enable(gl.STENCIL_TEST);\r\n            } else {\r\n                gl.disable(gl.STENCIL_TEST);\r\n            }\r\n            this._isStencilTestDirty = false;\r\n        }\r\n\r\n        // Stencil mask\r\n        if (this._isStencilMaskDirty) {\r\n            gl.stencilMask(this.mask);\r\n            this._isStencilMaskDirty = false;\r\n        }\r\n\r\n        // Stencil func\r\n        if (this._isStencilFuncDirty) {\r\n            gl.stencilFuncSeparate(gl.FRONT, this.func, this.funcRef, this.funcMask);\r\n            gl.stencilFuncSeparate(gl.BACK, this.backFunc, this.funcRef, this.funcMask);\r\n            this._isStencilFuncDirty = false;\r\n        }\r\n\r\n        // Stencil op\r\n        if (this._isStencilOpDirty) {\r\n            gl.stencilOpSeparate(gl.FRONT, this.opStencilFail, this.opDepthFail, this.opStencilDepthPass);\r\n            gl.stencilOpSeparate(gl.BACK, this.backOpStencilFail, this.backOpDepthFail, this.backOpStencilDepthPass);\r\n            this._isStencilOpDirty = false;\r\n        }\r\n    }\r\n}\r\n","import { Constants } from \"../Engines/constants\";\r\nimport { type IStencilState } from \"./IStencilState\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class StencilState implements IStencilState {\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */\r\n    public static readonly ALWAYS = Constants.ALWAYS;\r\n    /** Passed to stencilOperation to specify that stencil value must be kept */\r\n    public static readonly KEEP = Constants.KEEP;\r\n    /** Passed to stencilOperation to specify that stencil value must be replaced */\r\n    public static readonly REPLACE = Constants.REPLACE;\r\n\r\n    public constructor() {\r\n        this.reset();\r\n    }\r\n\r\n    public reset() {\r\n        this.enabled = false;\r\n        this.mask = 0xff;\r\n\r\n        this.funcRef = 1;\r\n        this.funcMask = 0xff;\r\n\r\n        this.func = StencilState.ALWAYS;\r\n        this.opStencilFail = StencilState.KEEP;\r\n        this.opDepthFail = StencilState.KEEP;\r\n        this.opStencilDepthPass = StencilState.REPLACE;\r\n\r\n        this.backFunc = StencilState.ALWAYS;\r\n        this.backOpStencilFail = StencilState.KEEP;\r\n        this.backOpDepthFail = StencilState.KEEP;\r\n        this.backOpStencilDepthPass = StencilState.REPLACE;\r\n    }\r\n\r\n    public func: number;\r\n    public get stencilFunc(): number {\r\n        return this.func;\r\n    }\r\n\r\n    public set stencilFunc(value: number) {\r\n        this.func = value;\r\n    }\r\n\r\n    public backFunc: number;\r\n    public get stencilBackFunc(): number {\r\n        return this.backFunc;\r\n    }\r\n\r\n    public set stencilBackFunc(value: number) {\r\n        this.backFunc = value;\r\n    }\r\n\r\n    public funcRef: number;\r\n    public get stencilFuncRef(): number {\r\n        return this.funcRef;\r\n    }\r\n\r\n    public set stencilFuncRef(value: number) {\r\n        this.funcRef = value;\r\n    }\r\n\r\n    public funcMask: number;\r\n    public get stencilFuncMask(): number {\r\n        return this.funcMask;\r\n    }\r\n\r\n    public set stencilFuncMask(value: number) {\r\n        this.funcMask = value;\r\n    }\r\n\r\n    public opStencilFail: number;\r\n    public get stencilOpStencilFail(): number {\r\n        return this.opStencilFail;\r\n    }\r\n\r\n    public set stencilOpStencilFail(value: number) {\r\n        this.opStencilFail = value;\r\n    }\r\n\r\n    public opDepthFail: number;\r\n    public get stencilOpDepthFail(): number {\r\n        return this.opDepthFail;\r\n    }\r\n\r\n    public set stencilOpDepthFail(value: number) {\r\n        this.opDepthFail = value;\r\n    }\r\n\r\n    public opStencilDepthPass: number;\r\n    public get stencilOpStencilDepthPass(): number {\r\n        return this.opStencilDepthPass;\r\n    }\r\n\r\n    public set stencilOpStencilDepthPass(value: number) {\r\n        this.opStencilDepthPass = value;\r\n    }\r\n\r\n    public backOpStencilFail: number;\r\n    public get stencilBackOpStencilFail(): number {\r\n        return this.backOpStencilFail;\r\n    }\r\n\r\n    public set stencilBackOpStencilFail(value: number) {\r\n        this.backOpStencilFail = value;\r\n    }\r\n\r\n    public backOpDepthFail: number;\r\n    public get stencilBackOpDepthFail(): number {\r\n        return this.backOpDepthFail;\r\n    }\r\n\r\n    public set stencilBackOpDepthFail(value: number) {\r\n        this.backOpDepthFail = value;\r\n    }\r\n\r\n    public backOpStencilDepthPass: number;\r\n    public get stencilBackOpStencilDepthPass(): number {\r\n        return this.backOpStencilDepthPass;\r\n    }\r\n\r\n    public set stencilBackOpStencilDepthPass(value: number) {\r\n        this.backOpStencilDepthPass = value;\r\n    }\r\n\r\n    public mask: number;\r\n    public get stencilMask(): number {\r\n        return this.mask;\r\n    }\r\n\r\n    public set stencilMask(value: number) {\r\n        this.mask = value;\r\n    }\r\n\r\n    public enabled: boolean;\r\n    public get stencilTest(): boolean {\r\n        return this.enabled;\r\n    }\r\n\r\n    public set stencilTest(value: boolean) {\r\n        this.enabled = value;\r\n    }\r\n}\r\n","import { Constants } from \"core/Engines/constants\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class AlphaState {\r\n    public _blendFunctionParameters = new Array<Nullable<number>>(4 * 8);\r\n    public _blendEquationParameters = new Array<Nullable<number>>(2 * 8);\r\n    public _blendConstants = new Array<Nullable<number>>(4);\r\n    public _isBlendConstantsDirty = false;\r\n\r\n    public _alphaBlend = Array(8).fill(false);\r\n    public _numTargetEnabled = 0;\r\n\r\n    private _isAlphaBlendDirty = false;\r\n    private _isBlendFunctionParametersDirty = false;\r\n    private _isBlendEquationParametersDirty = false;\r\n    private _blendDisabledTargetsMask = 0;\r\n    private _numTargets = 1;\r\n\r\n    /**\r\n     * Initializes the state.\r\n     * @param _supportBlendParametersPerTarget - Whether blend parameters per target is supported\r\n     */\r\n    public constructor(private _supportBlendParametersPerTarget: boolean) {\r\n        this.reset();\r\n    }\r\n\r\n    public get isDirty(): boolean {\r\n        return this._isAlphaBlendDirty || this._isBlendFunctionParametersDirty || this._isBlendEquationParametersDirty;\r\n    }\r\n\r\n    public get alphaBlend(): boolean {\r\n        return this._numTargetEnabled > 0;\r\n    }\r\n\r\n    public set alphaBlend(value: boolean) {\r\n        this.setAlphaBlend(value);\r\n    }\r\n\r\n    public setAlphaBlend(value: boolean, targetIndex: number = 0): void {\r\n        if (this._alphaBlend[targetIndex] === value) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this._numTargetEnabled++;\r\n        } else {\r\n            this._numTargetEnabled--;\r\n        }\r\n\r\n        this._alphaBlend[targetIndex] = value;\r\n        this._isAlphaBlendDirty = true;\r\n    }\r\n\r\n    public setAlphaBlendConstants(r: number, g: number, b: number, a: number): void {\r\n        if (this._blendConstants[0] === r && this._blendConstants[1] === g && this._blendConstants[2] === b && this._blendConstants[3] === a) {\r\n            return;\r\n        }\r\n\r\n        this._blendConstants[0] = r;\r\n        this._blendConstants[1] = g;\r\n        this._blendConstants[2] = b;\r\n        this._blendConstants[3] = a;\r\n\r\n        this._isBlendConstantsDirty = true;\r\n    }\r\n\r\n    public setAlphaBlendFunctionParameters(srcRGBFactor: number, dstRGBFactor: number, srcAlphaFactor: number, dstAlphaFactor: number, targetIndex: number = 0): void {\r\n        const offset = targetIndex * 4;\r\n\r\n        if (\r\n            this._blendFunctionParameters[offset + 0] === srcRGBFactor &&\r\n            this._blendFunctionParameters[offset + 1] === dstRGBFactor &&\r\n            this._blendFunctionParameters[offset + 2] === srcAlphaFactor &&\r\n            this._blendFunctionParameters[offset + 3] === dstAlphaFactor\r\n        ) {\r\n            return;\r\n        }\r\n\r\n        this._blendFunctionParameters[offset + 0] = srcRGBFactor;\r\n        this._blendFunctionParameters[offset + 1] = dstRGBFactor;\r\n        this._blendFunctionParameters[offset + 2] = srcAlphaFactor;\r\n        this._blendFunctionParameters[offset + 3] = dstAlphaFactor;\r\n\r\n        this._isBlendFunctionParametersDirty = true;\r\n    }\r\n\r\n    public setAlphaEquationParameters(rgbEquation: number, alphaEquation: number, targetIndex: number = 0): void {\r\n        const offset = targetIndex * 2;\r\n\r\n        if (this._blendEquationParameters[offset + 0] === rgbEquation && this._blendEquationParameters[offset + 1] === alphaEquation) {\r\n            return;\r\n        }\r\n\r\n        this._blendEquationParameters[offset + 0] = rgbEquation;\r\n        this._blendEquationParameters[offset + 1] = alphaEquation;\r\n\r\n        this._isBlendEquationParametersDirty = true;\r\n    }\r\n\r\n    public reset() {\r\n        this._alphaBlend.fill(false);\r\n        this._numTargetEnabled = 0;\r\n        this._blendFunctionParameters.fill(null);\r\n        this._blendEquationParameters.fill(null);\r\n\r\n        this._blendConstants[0] = null;\r\n        this._blendConstants[1] = null;\r\n        this._blendConstants[2] = null;\r\n        this._blendConstants[3] = null;\r\n\r\n        this._isAlphaBlendDirty = true;\r\n        this._isBlendFunctionParametersDirty = false;\r\n        this._isBlendEquationParametersDirty = false;\r\n        this._isBlendConstantsDirty = false;\r\n        this._blendDisabledTargetsMask = 0;\r\n        this._numTargets = 1;\r\n    }\r\n\r\n    public apply(gl: WebGLRenderingContext, numTargets: number = 1, blendDisabledTargetsMask = 0): void {\r\n        if (this._numTargets !== numTargets) {\r\n            this._numTargets = numTargets;\r\n            this._isAlphaBlendDirty = true;\r\n        }\r\n        if (this._blendDisabledTargetsMask !== blendDisabledTargetsMask) {\r\n            this._blendDisabledTargetsMask = blendDisabledTargetsMask;\r\n            this._isAlphaBlendDirty = true;\r\n        }\r\n\r\n        if (!this.isDirty) {\r\n            return;\r\n        }\r\n\r\n        // Constants\r\n        if (this._isBlendConstantsDirty) {\r\n            gl.blendColor(<number>this._blendConstants[0], <number>this._blendConstants[1], <number>this._blendConstants[2], <number>this._blendConstants[3]);\r\n            this._isBlendConstantsDirty = false;\r\n        }\r\n\r\n        if (numTargets === 1 || !this._supportBlendParametersPerTarget) {\r\n            // Single target or no support for per-target parameters\r\n            if (this._isAlphaBlendDirty) {\r\n                if (numTargets > 1 && blendDisabledTargetsMask !== 0 && this.alphaBlend) {\r\n                    throw new Error(\"AlphaState: blending with integer MRT attachments requires per-target blend parameters\");\r\n                }\r\n                if (this._alphaBlend[0] && (blendDisabledTargetsMask & 1) === 0) {\r\n                    gl.enable(gl.BLEND);\r\n                } else {\r\n                    gl.disable(gl.BLEND);\r\n                }\r\n                this._isAlphaBlendDirty = false;\r\n            }\r\n\r\n            if (this._isBlendFunctionParametersDirty) {\r\n                gl.blendFuncSeparate(\r\n                    <number>this._blendFunctionParameters[0],\r\n                    <number>this._blendFunctionParameters[1],\r\n                    <number>this._blendFunctionParameters[2],\r\n                    <number>this._blendFunctionParameters[3]\r\n                );\r\n                this._isBlendFunctionParametersDirty = false;\r\n            }\r\n\r\n            if (this._isBlendEquationParametersDirty) {\r\n                gl.blendEquationSeparate(<number>this._blendEquationParameters[0], <number>this._blendEquationParameters[1]);\r\n                this._isBlendEquationParametersDirty = false;\r\n            }\r\n            return;\r\n        }\r\n\r\n        // Multi-target\r\n        const gl2 = gl as WebGL2RenderingContext;\r\n\r\n        // Alpha blend\r\n        if (this._isAlphaBlendDirty) {\r\n            for (let i = 0; i < numTargets; i++) {\r\n                const index = i < this._numTargetEnabled ? i : 0;\r\n                if (this._alphaBlend[index] && (blendDisabledTargetsMask & (1 << i)) === 0) {\r\n                    gl2.enableIndexed(gl.BLEND, i);\r\n                } else {\r\n                    gl2.disableIndexed(gl.BLEND, i);\r\n                }\r\n            }\r\n\r\n            this._isAlphaBlendDirty = false;\r\n        }\r\n\r\n        // Alpha function\r\n        if (this._isBlendFunctionParametersDirty) {\r\n            for (let i = 0; i < numTargets; i++) {\r\n                const offset = i < this._numTargetEnabled ? i * 4 : 0;\r\n                gl2.blendFuncSeparateIndexed(\r\n                    i,\r\n                    <number>this._blendFunctionParameters[offset + 0],\r\n                    <number>this._blendFunctionParameters[offset + 1],\r\n                    <number>this._blendFunctionParameters[offset + 2],\r\n                    <number>this._blendFunctionParameters[offset + 3]\r\n                );\r\n            }\r\n            this._isBlendFunctionParametersDirty = false;\r\n        }\r\n\r\n        // Alpha equation\r\n        if (this._isBlendEquationParametersDirty) {\r\n            for (let i = 0; i < numTargets; i++) {\r\n                const offset = i < this._numTargetEnabled ? i * 2 : 0;\r\n                gl2.blendEquationSeparateIndexed(i, <number>this._blendEquationParameters[offset + 0], <number>this._blendEquationParameters[offset + 1]);\r\n            }\r\n            this._isBlendEquationParametersDirty = false;\r\n        }\r\n    }\r\n\r\n    public setAlphaMode(mode: number, targetIndex: number) {\r\n        let equation = Constants.GL_ALPHA_EQUATION_ADD;\r\n\r\n        switch (mode) {\r\n            case Constants.ALPHA_DISABLE:\r\n                break;\r\n            case Constants.ALPHA_PREMULTIPLIED:\r\n                this.setAlphaBlendFunctionParameters(1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, 1, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_PREMULTIPLIED_PORTERDUFF:\r\n                this.setAlphaBlendFunctionParameters(1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, 1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_COMBINE:\r\n                this.setAlphaBlendFunctionParameters(Constants.GL_ALPHA_FUNCTION_SRC_ALPHA, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, 1, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_ONEONE:\r\n                this.setAlphaBlendFunctionParameters(1, 1, 0, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_ADD:\r\n                this.setAlphaBlendFunctionParameters(Constants.GL_ALPHA_FUNCTION_SRC_ALPHA, 1, 0, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_SUBTRACT:\r\n                this.setAlphaBlendFunctionParameters(0, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR, 1, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_MULTIPLY:\r\n                this.setAlphaBlendFunctionParameters(Constants.GL_ALPHA_FUNCTION_DST_COLOR, 0, 1, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_MAXIMIZED:\r\n                this.setAlphaBlendFunctionParameters(Constants.GL_ALPHA_FUNCTION_SRC_ALPHA, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR, 1, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_INTERPOLATE:\r\n                this.setAlphaBlendFunctionParameters(\r\n                    Constants.GL_ALPHA_FUNCTION_CONSTANT_COLOR,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_COLOR,\r\n                    Constants.GL_ALPHA_FUNCTION_CONSTANT_ALPHA,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_ALPHA,\r\n                    targetIndex\r\n                );\r\n                break;\r\n            case Constants.ALPHA_SCREENMODE:\r\n                this.setAlphaBlendFunctionParameters(1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR, 1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_ONEONE_ONEONE:\r\n                this.setAlphaBlendFunctionParameters(1, 1, 1, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_ALPHATOCOLOR:\r\n                this.setAlphaBlendFunctionParameters(Constants.GL_ALPHA_FUNCTION_DST_ALPHA, 1, 0, 0, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_REVERSEONEMINUS:\r\n                this.setAlphaBlendFunctionParameters(\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_DST_COLOR,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_DST_ALPHA,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA,\r\n                    targetIndex\r\n                );\r\n                break;\r\n            case Constants.ALPHA_SRC_DSTONEMINUSSRCALPHA:\r\n                this.setAlphaBlendFunctionParameters(1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, 1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_ONEONE_ONEZERO:\r\n                this.setAlphaBlendFunctionParameters(1, 1, 1, 0, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_EXCLUSION:\r\n                this.setAlphaBlendFunctionParameters(Constants.GL_ALPHA_FUNCTION_ONE_MINUS_DST_COLOR, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR, 0, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_LAYER_ACCUMULATE:\r\n                // Same as ALPHA_COMBINE but accumulates (1 - alpha) values in the alpha channel for a later readout in order independant transparency\r\n                this.setAlphaBlendFunctionParameters(\r\n                    Constants.GL_ALPHA_FUNCTION_SRC_ALPHA,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA,\r\n                    1,\r\n                    Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA,\r\n                    targetIndex\r\n                );\r\n                break;\r\n            case Constants.ALPHA_MIN:\r\n                this.setAlphaBlendFunctionParameters(1, 1, 1, 1, targetIndex);\r\n                equation = Constants.GL_ALPHA_EQUATION_MIN;\r\n                break;\r\n            case Constants.ALPHA_MAX:\r\n                this.setAlphaBlendFunctionParameters(1, 1, 1, 1, targetIndex);\r\n                equation = Constants.GL_ALPHA_EQUATION_MAX;\r\n                break;\r\n            case Constants.ALPHA_DUAL_SRC0_ADD_SRC1xDST:\r\n                this.setAlphaBlendFunctionParameters(1, Constants.GL_ALPHA_FUNCTION_SRC1_COLOR, 0, 1, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_REPLACE_COLOR:\r\n                this.setAlphaBlendFunctionParameters(1, 0, 1, Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA, targetIndex);\r\n                break;\r\n        }\r\n\r\n        this.setAlphaEquationParameters(equation, equation, targetIndex);\r\n    }\r\n}\r\n","import { Constants } from \"../../Engines/constants\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Class used to store a texture sampler data\r\n */\r\nexport class TextureSampler {\r\n    /**\r\n     * Gets the sampling mode of the texture\r\n     */\r\n    public samplingMode: number = -1;\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    public get wrapU() {\r\n        return this._cachedWrapU;\r\n    }\r\n\r\n    public set wrapU(value: Nullable<number>) {\r\n        this._cachedWrapU = value;\r\n    }\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    public get wrapV() {\r\n        return this._cachedWrapV;\r\n    }\r\n\r\n    public set wrapV(value: Nullable<number>) {\r\n        this._cachedWrapV = value;\r\n    }\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    public get wrapR() {\r\n        return this._cachedWrapR;\r\n    }\r\n\r\n    public set wrapR(value: Nullable<number>) {\r\n        this._cachedWrapR = value;\r\n    }\r\n\r\n    /**\r\n     * With compliant hardware and browser (supporting anisotropic filtering)\r\n     * this defines the level of anisotropic filtering in the texture.\r\n     * The higher the better but the slower.\r\n     */\r\n    public get anisotropicFilteringLevel() {\r\n        return this._cachedAnisotropicFilteringLevel;\r\n    }\r\n\r\n    public set anisotropicFilteringLevel(value: Nullable<number>) {\r\n        this._cachedAnisotropicFilteringLevel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the comparison function (Constants.LESS, Constants.EQUAL, etc). Set 0 to not use a comparison function\r\n     */\r\n    public get comparisonFunction() {\r\n        return this._comparisonFunction;\r\n    }\r\n\r\n    public set comparisonFunction(value: number) {\r\n        this._comparisonFunction = value;\r\n    }\r\n\r\n    protected _useMipMaps: Nullable<boolean> = true;\r\n    /**\r\n     * Indicates to use the mip maps (if available on the texture).\r\n     * Thanks to this flag, you can instruct the sampler to not sample the mipmaps even if they exist (and if the sampling mode is set to a value that normally samples the mipmaps!)\r\n     */\r\n    public get useMipMaps() {\r\n        return this._useMipMaps;\r\n    }\r\n\r\n    public set useMipMaps(value: Nullable<boolean>) {\r\n        this._useMipMaps = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public _cachedWrapU: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    public _cachedWrapV: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    public _cachedWrapR: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    public _cachedAnisotropicFilteringLevel: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    public _comparisonFunction: number = 0;\r\n\r\n    /**\r\n     * General label used for debugging or storing a name.\r\n     */\r\n    public label?: string;\r\n\r\n    /**\r\n     * Creates a Sampler instance\r\n     */\r\n    constructor() {}\r\n\r\n    /**\r\n     * Sets all the parameters of the sampler\r\n     * @param wrapU u address mode (default: TEXTURE_WRAP_ADDRESSMODE)\r\n     * @param wrapV v address mode (default: TEXTURE_WRAP_ADDRESSMODE)\r\n     * @param wrapR r address mode (default: TEXTURE_WRAP_ADDRESSMODE)\r\n     * @param anisotropicFilteringLevel anisotropic level (default: 1)\r\n     * @param samplingMode sampling mode (default: Constants.TEXTURE_BILINEAR_SAMPLINGMODE)\r\n     * @param comparisonFunction comparison function (default: 0 - no comparison function)\r\n     * @returns the current sampler instance\r\n     */\r\n    public setParameters(\r\n        wrapU = Constants.TEXTURE_WRAP_ADDRESSMODE,\r\n        wrapV = Constants.TEXTURE_WRAP_ADDRESSMODE,\r\n        wrapR = Constants.TEXTURE_WRAP_ADDRESSMODE,\r\n        anisotropicFilteringLevel = 1,\r\n        samplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n        comparisonFunction = 0\r\n    ): TextureSampler {\r\n        this._cachedWrapU = wrapU;\r\n        this._cachedWrapV = wrapV;\r\n        this._cachedWrapR = wrapR;\r\n        this._cachedAnisotropicFilteringLevel = anisotropicFilteringLevel;\r\n        this.samplingMode = samplingMode;\r\n        this._comparisonFunction = comparisonFunction;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Compares this sampler with another one\r\n     * @param other sampler to compare with\r\n     * @returns true if the samplers have the same parametres, else false\r\n     */\r\n    public compareSampler(other: TextureSampler): boolean {\r\n        return (\r\n            this._cachedWrapU === other._cachedWrapU &&\r\n            this._cachedWrapV === other._cachedWrapV &&\r\n            this._cachedWrapR === other._cachedWrapR &&\r\n            this._cachedAnisotropicFilteringLevel === other._cachedAnisotropicFilteringLevel &&\r\n            this.samplingMode === other.samplingMode &&\r\n            this._comparisonFunction === other._comparisonFunction &&\r\n            this._useMipMaps === other._useMipMaps\r\n        );\r\n    }\r\n}\r\n","import { Observable } from \"../../Misc/observable\";\r\nimport { type ImageSource, type Nullable, type int } from \"../../types\";\r\nimport { type ICanvas, type ICanvasRenderingContext } from \"../../Engines/ICanvas\";\r\nimport { type IHardwareTextureWrapper } from \"./hardwareTextureWrapper\";\r\nimport { TextureSampler } from \"./textureSampler\";\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type SphericalPolynomial } from \"../../Maths/sphericalPolynomial\";\r\n\r\n/**\r\n * Defines the source of the internal texture\r\n */\r\nexport const enum InternalTextureSource {\r\n    /**\r\n     * The source of the texture data is unknown\r\n     */\r\n    Unknown,\r\n    /**\r\n     * Texture data comes from an URL\r\n     */\r\n    Url,\r\n    /**\r\n     * Texture data is only used for temporary storage\r\n     */\r\n    Temp,\r\n    /**\r\n     * Texture data comes from raw data (ArrayBuffer)\r\n     */\r\n    Raw,\r\n    /**\r\n     * Texture content is dynamic (video or dynamic texture)\r\n     */\r\n    Dynamic,\r\n    /**\r\n     * Texture content is generated by rendering to it\r\n     */\r\n    RenderTarget,\r\n    /**\r\n     * Texture content is part of a multi render target process\r\n     */\r\n    MultiRenderTarget,\r\n    /**\r\n     * Texture data comes from a cube data file\r\n     */\r\n    Cube,\r\n    /**\r\n     * Texture data comes from a raw cube data\r\n     */\r\n    CubeRaw,\r\n    /**\r\n     * Texture data come from a prefiltered cube data file\r\n     */\r\n    CubePrefiltered,\r\n    /**\r\n     * Texture content is raw 3D data\r\n     */\r\n    Raw3D,\r\n    /**\r\n     * Texture content is raw 2D array data\r\n     */\r\n    Raw2DArray,\r\n    /**\r\n     * Texture content is a depth/stencil texture\r\n     */\r\n    DepthStencil,\r\n    /**\r\n     * Texture data comes from a raw cube data encoded with RGBD\r\n     */\r\n    CubeRawRGBD,\r\n    /**\r\n     * Texture content is a depth texture\r\n     */\r\n    Depth,\r\n    /**\r\n     * Texture wraps an externally created graphics resource (WebGL handle, GPUTexture,\r\n     * native handle, etc.) supplied via wrap{WebGL,Native,WebGPU}Texture. On dispose,\r\n     * the wrapped resource is released along with the InternalTexture just like any\r\n     * other source. Consumers can repoint the wrapper at a fresh external handle\r\n     * (e.g., after context-loss / device-loss restore) via\r\n     * updateWrapped{WebGL,Native,WebGPU}Texture without losing references held by\r\n     * materials, render-target wrappers, particle systems, etc.\r\n     */\r\n    External,\r\n}\r\n\r\n/**\r\n * Class used to store data associated with WebGL texture data for the engine\r\n * This class should not be used directly\r\n */\r\nexport class InternalTexture extends TextureSampler {\r\n    /**\r\n     * Defines if the texture is ready\r\n     */\r\n    public isReady: boolean = false;\r\n    /**\r\n     * Defines if the texture is a cube texture\r\n     */\r\n    public isCube: boolean = false;\r\n    /**\r\n     * Defines if the texture contains 3D data\r\n     */\r\n    public is3D: boolean = false;\r\n    /**\r\n     * Defines if the texture contains 2D array data\r\n     */\r\n    public is2DArray: boolean = false;\r\n    /**\r\n     * Defines if the texture contains multiview data\r\n     */\r\n    public isMultiview: boolean = false;\r\n    /**\r\n     * Gets the URL used to load this texture\r\n     */\r\n    public url: string = \"\";\r\n    /** @internal */\r\n    public _originalUrl: string; // not empty only if different from url\r\n    /**\r\n     * Gets a boolean indicating if the texture needs mipmaps generation\r\n     */\r\n    public generateMipMaps: boolean = false;\r\n\r\n    protected override _useMipMaps: Nullable<boolean> = null;\r\n    /**\r\n     * Indicates to use the mip maps (if available on the texture).\r\n     * Thanks to this flag, you can instruct the sampler to not sample the mipmaps even if they exist (and if the sampling mode is set to a value that normally samples the mipmaps!)\r\n     * If useMipMaps is null, the value of generateMipMaps is returned by the getter (for backward compatibility)\r\n     */\r\n    public override get useMipMaps() {\r\n        return this._useMipMaps === null ? this.generateMipMaps : this._useMipMaps;\r\n    }\r\n    public override set useMipMaps(value: Nullable<boolean>) {\r\n        this._useMipMaps = value;\r\n    }\r\n    /**\r\n     * Gets the number of mip levels for this texture.\r\n     * Note: This property has the correct value only if the texture was created through\r\n     * `createRawTexture` or `createRawTexture2DArray`.\r\n     */\r\n    public mipLevelCount: number = 1;\r\n    /**\r\n     * Gets the number of samples used by the texture (WebGL2+ only)\r\n     */\r\n    public samples: number = 0;\r\n    /**\r\n     * Gets the type of the texture (int, float...)\r\n     */\r\n    public type: number = -1;\r\n    /**\r\n     * Gets the format of the texture (RGB, RGBA...)\r\n     */\r\n    public format: number = -1;\r\n    /**\r\n     * Observable called when the texture is loaded\r\n     */\r\n    public onLoadedObservable = new Observable<InternalTexture>();\r\n    /**\r\n     * Observable called when the texture load is raising an error\r\n     */\r\n    public onErrorObservable = new Observable<Partial<{ message: string; exception: any }>>();\r\n    /**\r\n     * If this callback is defined it will be called instead of the default _rebuild function\r\n     */\r\n    public onRebuildCallback: Nullable<\r\n        (internalTexture: InternalTexture) => {\r\n            proxy: Nullable<InternalTexture | Promise<InternalTexture>>;\r\n            isReady: boolean;\r\n            isAsync: boolean;\r\n        }\r\n    > = null;\r\n    /**\r\n     * Gets the width of the texture\r\n     */\r\n    public width: number = 0;\r\n    /**\r\n     * Gets the height of the texture\r\n     */\r\n    public height: number = 0;\r\n    /**\r\n     * Gets the depth of the texture\r\n     */\r\n    public depth: number = 0;\r\n    /**\r\n     * Gets the initial width of the texture (It could be rescaled if the current system does not support non power of two textures)\r\n     */\r\n    public baseWidth: number = 0;\r\n    /**\r\n     * Gets the initial height of the texture (It could be rescaled if the current system does not support non power of two textures)\r\n     */\r\n    public baseHeight: number = 0;\r\n    /**\r\n     * Gets the initial depth of the texture (It could be rescaled if the current system does not support non power of two textures)\r\n     */\r\n    public baseDepth: number = 0;\r\n    /**\r\n     * Gets a boolean indicating if the texture is inverted on Y axis\r\n     */\r\n    public invertY: boolean = false;\r\n\r\n    // Private\r\n    /** @internal */\r\n    public _invertVScale = false;\r\n    /** @internal */\r\n    public _associatedChannel = -1;\r\n    /** @internal */\r\n    public _source = InternalTextureSource.Unknown;\r\n    /** @internal */\r\n    public _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null;\r\n    /** @internal */\r\n    public _bufferView: Nullable<ArrayBufferView> = null;\r\n    /** @internal */\r\n    public _bufferViewArray: Nullable<ArrayBufferView[]> = null;\r\n    /** @internal */\r\n    public _bufferViewArrayArray: Nullable<ArrayBufferView[][]> = null;\r\n    /** @internal */\r\n    public _size: number = 0;\r\n    /** @internal */\r\n    public _extension: string = \"\";\r\n    /** @internal */\r\n    public _files: Nullable<string[]> = null;\r\n    /** @internal */\r\n    public _workingCanvas: Nullable<ICanvas> = null;\r\n    /** @internal */\r\n    public _workingContext: Nullable<ICanvasRenderingContext> = null;\r\n    /** @internal */\r\n    public _cachedCoordinatesMode: Nullable<number> = null;\r\n    /** @internal */\r\n    public _isDisabled: boolean = false;\r\n    /** @internal */\r\n    public _compression: Nullable<string> = null;\r\n    /** @internal */\r\n    public _sphericalPolynomial: Nullable<SphericalPolynomial> = null;\r\n    /** @internal */\r\n    public _sphericalPolynomialPromise: Nullable<Promise<SphericalPolynomial>> = null;\r\n    /** @internal */\r\n    public _sphericalPolynomialComputed = false;\r\n    /** @internal */\r\n    public _lodGenerationScale: number = 0;\r\n    /** @internal */\r\n    public _lodGenerationOffset: number = 0;\r\n    /** @internal */\r\n    public _useSRGBBuffer: boolean = false;\r\n    /** @internal */\r\n    public _creationFlags: number = 0;\r\n    /** @internal */\r\n    public _originalFormat?: number;\r\n\r\n    // The following three fields helps sharing generated fixed LODs for texture filtering\r\n    // In environment not supporting the textureLOD extension like EDGE. They are for internal use only.\r\n    // They are at the level of the gl texture to benefit from the cache.\r\n    /** @internal */\r\n    public _lodTextureHigh: Nullable<BaseTexture> = null;\r\n    /** @internal */\r\n    public _lodTextureMid: Nullable<BaseTexture> = null;\r\n    /** @internal */\r\n    public _lodTextureLow: Nullable<BaseTexture> = null;\r\n    /** @internal */\r\n    public _isRGBD: boolean = false;\r\n\r\n    /** @internal */\r\n    public _linearSpecularLOD: boolean = false;\r\n    /** @internal */\r\n    public _irradianceTexture: Nullable<BaseTexture> = null;\r\n\r\n    /** @internal */\r\n    public _hardwareTexture: Nullable<IHardwareTextureWrapper> = null;\r\n\r\n    /** @internal */\r\n    public _maxLodLevel: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    public _references: number = 1;\r\n\r\n    /** @internal */\r\n    public _gammaSpace: Nullable<boolean> = null;\r\n\r\n    /** @internal */\r\n    public _premulAlpha = false;\r\n\r\n    /** @internal */\r\n    public _dynamicTextureSource: Nullable<ImageSource> = null;\r\n\r\n    /** @internal */\r\n    public _autoMSAAManagement = false;\r\n\r\n    private _engine: AbstractEngine;\r\n    private _uniqueId: number;\r\n\r\n    /** @internal */\r\n    public static _Counter = 0;\r\n\r\n    /** Gets the unique id of the internal texture */\r\n    public get uniqueId() {\r\n        return this._uniqueId;\r\n    }\r\n\r\n    /** @internal */\r\n    public _setUniqueId(id: number) {\r\n        this._uniqueId = id;\r\n    }\r\n\r\n    /**\r\n     * Gets the Engine the texture belongs to.\r\n     * @returns The babylon engine\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * Gets the data source type of the texture\r\n     */\r\n    public get source(): InternalTextureSource {\r\n        return this._source;\r\n    }\r\n\r\n    /**\r\n     * Creates a new InternalTexture\r\n     * @param engine defines the engine to use\r\n     * @param source defines the type of data that will be used\r\n     * @param delayAllocation if the texture allocation should be delayed (default: false)\r\n     */\r\n    constructor(engine: AbstractEngine, source: InternalTextureSource, delayAllocation = false) {\r\n        super();\r\n\r\n        this._engine = engine;\r\n        this._source = source;\r\n        this._uniqueId = InternalTexture._Counter++;\r\n\r\n        if (!delayAllocation) {\r\n            this._hardwareTexture = engine._createHardwareTexture();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Increments the number of references (ie. the number of Texture that point to it)\r\n     */\r\n    public incrementReferences(): void {\r\n        this._references++;\r\n    }\r\n\r\n    /**\r\n     * Change the size of the texture (not the size of the content)\r\n     * @param width defines the new width\r\n     * @param height defines the new height\r\n     * @param depth defines the new depth (1 by default)\r\n     */\r\n    public updateSize(width: int, height: int, depth: int = 1): void {\r\n        this._engine.updateTextureDimensions(this, width, height, depth);\r\n\r\n        this.width = width;\r\n        this.height = height;\r\n        this.depth = depth;\r\n\r\n        this.baseWidth = width;\r\n        this.baseHeight = height;\r\n        this.baseDepth = depth;\r\n\r\n        this._size = width * height * depth;\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        this.isReady = false;\r\n        this._cachedCoordinatesMode = null;\r\n        this._cachedWrapU = null;\r\n        this._cachedWrapV = null;\r\n        this._cachedWrapR = null;\r\n        this._cachedAnisotropicFilteringLevel = null;\r\n        if (this.onRebuildCallback) {\r\n            const data = this.onRebuildCallback(this);\r\n            const swapAndSetIsReady = (proxyInternalTexture: InternalTexture) => {\r\n                proxyInternalTexture._swapAndDie(this, false);\r\n                this.isReady = data.isReady;\r\n            };\r\n            if (data.isAsync) {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                (data.proxy as Promise<InternalTexture>).then(swapAndSetIsReady);\r\n            } else {\r\n                swapAndSetIsReady(data.proxy as InternalTexture);\r\n            }\r\n            return;\r\n        }\r\n\r\n        let proxy: InternalTexture;\r\n        switch (this.source) {\r\n            case InternalTextureSource.Temp:\r\n                break;\r\n\r\n            case InternalTextureSource.Url:\r\n                proxy = this._engine.createTexture(\r\n                    this._originalUrl ?? this.url,\r\n                    !this.generateMipMaps,\r\n                    this.invertY,\r\n                    null,\r\n                    this.samplingMode,\r\n                    // Do not use Proxy here as it could be fully synchronous\r\n                    // and proxy would be undefined.\r\n                    (temp) => {\r\n                        temp._swapAndDie(this, false);\r\n                        this.isReady = true;\r\n                    },\r\n                    null,\r\n                    this._buffer,\r\n                    undefined,\r\n                    this.format,\r\n                    this._extension,\r\n                    undefined,\r\n                    undefined,\r\n                    undefined,\r\n                    this._useSRGBBuffer\r\n                );\r\n                return;\r\n\r\n            case InternalTextureSource.Raw:\r\n                proxy = this._engine.createRawTexture(\r\n                    this._bufferView,\r\n                    this.baseWidth,\r\n                    this.baseHeight,\r\n                    this.format,\r\n                    this.generateMipMaps,\r\n                    this.invertY,\r\n                    this.samplingMode,\r\n                    this._compression,\r\n                    this.type,\r\n                    this._creationFlags,\r\n                    this._useSRGBBuffer,\r\n                    this.mipLevelCount\r\n                );\r\n                proxy._swapAndDie(this, false);\r\n\r\n                if (this._bufferViewArray) {\r\n                    for (let mipLevel = 0; mipLevel < this._bufferViewArray.length; mipLevel++) {\r\n                        const mipData = this._bufferViewArray[mipLevel];\r\n                        if (mipData) {\r\n                            this._engine.updateRawTexture(this, mipData, this.format, this.invertY, this._compression, this.type, this._useSRGBBuffer, mipLevel);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                this.isReady = true;\r\n                break;\r\n\r\n            case InternalTextureSource.Raw3D:\r\n                proxy = this._engine.createRawTexture3D(\r\n                    this._bufferView,\r\n                    this.baseWidth,\r\n                    this.baseHeight,\r\n                    this.baseDepth,\r\n                    this.format,\r\n                    this.generateMipMaps,\r\n                    this.invertY,\r\n                    this.samplingMode,\r\n                    this._compression,\r\n                    this.type\r\n                );\r\n                proxy._swapAndDie(this, false);\r\n\r\n                this.isReady = true;\r\n                break;\r\n\r\n            case InternalTextureSource.Raw2DArray:\r\n                proxy = this._engine.createRawTexture2DArray(\r\n                    this._bufferView,\r\n                    this.baseWidth,\r\n                    this.baseHeight,\r\n                    this.baseDepth,\r\n                    this.format,\r\n                    this.generateMipMaps,\r\n                    this.invertY,\r\n                    this.samplingMode,\r\n                    this._compression,\r\n                    this.type,\r\n                    this._creationFlags,\r\n                    this.mipLevelCount\r\n                );\r\n                proxy._swapAndDie(this, false);\r\n\r\n                if (this._bufferViewArray) {\r\n                    for (let mipLevel = 0; mipLevel < this._bufferViewArray.length; mipLevel++) {\r\n                        const mipData = this._bufferViewArray[mipLevel];\r\n                        if (mipData) {\r\n                            this._engine.updateRawTexture2DArray(this, mipData, this.format, this.invertY, this._compression, this.type, mipLevel);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                this.isReady = true;\r\n                break;\r\n\r\n            case InternalTextureSource.Dynamic:\r\n                proxy = this._engine.createDynamicTexture(this.baseWidth, this.baseHeight, this.generateMipMaps, this.samplingMode);\r\n                proxy._swapAndDie(this, false);\r\n                if (this._dynamicTextureSource) {\r\n                    this._engine.updateDynamicTexture(this, this._dynamicTextureSource, this.invertY, this._premulAlpha, this.format, true);\r\n                }\r\n\r\n                // The engine will make sure to update content so no need to flag it as isReady = true\r\n                break;\r\n\r\n            case InternalTextureSource.Cube:\r\n                proxy = this._engine.createCubeTexture(\r\n                    this.url,\r\n                    null,\r\n                    this._files,\r\n                    !this.generateMipMaps,\r\n                    () => {\r\n                        proxy._swapAndDie(this, false);\r\n                        this.isReady = true;\r\n                    },\r\n                    null,\r\n                    this.format,\r\n                    this._extension,\r\n                    false,\r\n                    0,\r\n                    0,\r\n                    null,\r\n                    undefined,\r\n                    this._useSRGBBuffer,\r\n                    ArrayBuffer.isView(this._buffer) ? this._buffer : null\r\n                );\r\n                return;\r\n\r\n            case InternalTextureSource.CubeRaw:\r\n                proxy = this._engine.createRawCubeTexture(\r\n                    this._bufferViewArray,\r\n                    this.width,\r\n                    this._originalFormat ?? this.format,\r\n                    this.type,\r\n                    this.generateMipMaps,\r\n                    this.invertY,\r\n                    this.samplingMode,\r\n                    this._compression\r\n                );\r\n                proxy._swapAndDie(this, false);\r\n                this.isReady = true;\r\n                break;\r\n\r\n            case InternalTextureSource.CubeRawRGBD:\r\n                // This case is being handeled by the environment texture tools and is not a part of the rebuild process.\r\n                // To use CubeRawRGBD use updateRGBDAsync on the cube texture.\r\n                return;\r\n\r\n            case InternalTextureSource.CubePrefiltered:\r\n                proxy = this._engine.createPrefilteredCubeTexture(\r\n                    this.url,\r\n                    null,\r\n                    this._lodGenerationScale,\r\n                    this._lodGenerationOffset,\r\n                    (proxy) => {\r\n                        if (proxy) {\r\n                            proxy._swapAndDie(this, false);\r\n                        }\r\n                        this.isReady = true;\r\n                    },\r\n                    null,\r\n                    this.format,\r\n                    this._extension,\r\n                    undefined,\r\n                    ArrayBuffer.isView(this._buffer) ? this._buffer : null\r\n                );\r\n                proxy._sphericalPolynomial = this._sphericalPolynomial;\r\n                return;\r\n\r\n            case InternalTextureSource.DepthStencil:\r\n            case InternalTextureSource.Depth: {\r\n                // Will be handled at the RenderTargetWrapper level\r\n                break;\r\n            }\r\n\r\n            case InternalTextureSource.External: {\r\n                // The underlying resource is owned by the host application; Babylon cannot rebuild it.\r\n                // The host re-supplies a fresh handle via updateWrappedWebGLTexture / updateWrappedNativeTexture /\r\n                // updateWrappedWebGPUTexture from its onContextRestoredObservable handler.\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _swapAndDie(target: InternalTexture, swapAll = true): void {\r\n        // TODO what about refcount on target?\r\n\r\n        this._hardwareTexture?.setUsage(target._source, this.generateMipMaps, this.is2DArray, this.isCube, this.is3D, this.width, this.height, this.depth);\r\n\r\n        target._hardwareTexture = this._hardwareTexture;\r\n        // Refresh the target's uniqueId so that caches keyed by uniqueId (e.g. the\r\n        // WebGPU global bind-group cache) see the hardware texture as a new resource\r\n        // and rebuild GPU bind groups referencing it. Without this, callers that swap\r\n        // a raw GPU texture for a prefiltered one (e.g. HDR/PMREM prefiltering) would\r\n        // continue to receive stale GPUBindGroups that hold views over the now-destroyed\r\n        // source GPU texture, causing \"Destroyed texture used in a submit\" errors.\r\n        target._setUniqueId(InternalTexture._Counter++);\r\n        if (swapAll) {\r\n            target._isRGBD = this._isRGBD;\r\n        }\r\n\r\n        if (this._lodTextureHigh) {\r\n            if (target._lodTextureHigh) {\r\n                target._lodTextureHigh.dispose();\r\n            }\r\n            target._lodTextureHigh = this._lodTextureHigh;\r\n        }\r\n\r\n        if (this._lodTextureMid) {\r\n            if (target._lodTextureMid) {\r\n                target._lodTextureMid.dispose();\r\n            }\r\n            target._lodTextureMid = this._lodTextureMid;\r\n        }\r\n\r\n        if (this._lodTextureLow) {\r\n            if (target._lodTextureLow) {\r\n                target._lodTextureLow.dispose();\r\n            }\r\n            target._lodTextureLow = this._lodTextureLow;\r\n        }\r\n\r\n        if (this._irradianceTexture) {\r\n            if (target._irradianceTexture) {\r\n                target._irradianceTexture.dispose();\r\n            }\r\n            target._irradianceTexture = this._irradianceTexture;\r\n        }\r\n\r\n        const cache = this._engine.getLoadedTexturesCache();\r\n        let index = cache.indexOf(this);\r\n        if (index !== -1) {\r\n            cache.splice(index, 1);\r\n        }\r\n\r\n        index = cache.indexOf(target);\r\n        if (index === -1) {\r\n            cache.push(target);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the current allocated resources\r\n     */\r\n    public dispose(): void {\r\n        this._references--;\r\n        if (this._references === 0) {\r\n            this.onLoadedObservable.clear();\r\n            this.onErrorObservable.clear();\r\n            this._engine._releaseTexture(this);\r\n            this._hardwareTexture = null;\r\n            this._dynamicTextureSource = null;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { type DataArray, type FloatArray, type IndicesArray, type Nullable } from \"../types\";\r\nimport { type PerfCounter } from \"../Misc/perfCounter\";\r\nimport { type PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type IColor4Like, type IViewportLike } from \"../Maths/math.like\";\r\nimport { type ICanvas, type IImage, type IPath2D } from \"./ICanvas\";\r\nimport { type IHardwareTextureWrapper } from \"../Materials/Textures/hardwareTextureWrapper\";\r\nimport { type EngineCapabilities } from \"./engineCapabilities\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { type IShaderProcessor } from \"./Processors/iShaderProcessor\";\r\nimport { type ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { type IAudioEngineOptions } from \"../Audio/Interfaces/IAudioEngineOptions\";\r\nimport { type EngineFeatures } from \"./engineFeatures\";\r\nimport { type UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { type StorageBuffer } from \"../Buffers/storageBuffer\";\r\nimport { type IEffectCreationOptions, type IShaderPath, Effect } from \"../Materials/effect.pure\";\r\nimport { type IOfflineProvider } from \"../Offline/IOfflineProvider\";\r\nimport { type IWebRequest } from \"../Misc/interfaces/iWebRequest\";\r\nimport { type IFileRequest } from \"../Misc/fileRequest\";\r\nimport { type Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type LoadFileError } from \"../Misc/fileTools.pure\";\r\nimport { type _IShaderProcessingContext } from \"./Processors/shaderProcessingOptions\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { type ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { type InternalTextureCreationOptions, type TextureSize } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { type EffectFallbacks } from \"../Materials/effectFallbacks\";\r\nimport { type IMaterialContext } from \"./IMaterialContext\";\r\nimport { type IStencilStateProperties, type IStencilState } from \"../States/IStencilState\";\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { type IDrawContext } from \"./IDrawContext\";\r\nimport { type VertexBuffer } from \"../Meshes/buffer\";\r\nimport { type IAudioEngine } from \"../Audio/Interfaces/IAudioEngine\";\r\nimport { type WebRequest } from \"core/Misc/webRequest\";\r\nimport { type PerformanceMonitor } from \"core/Misc/performanceMonitor\";\r\nimport { type ILoadingScreen } from \"../Loading/loadingScreen.pure\";\r\nimport { EngineStore } from \"./engineStore\";\r\nimport { type ICustomAnimationFrameRequester } from \"../Misc/customAnimationFrameRequester\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { PerformanceConfigurator } from \"./performanceConfigurator\";\r\nimport { PrecisionDate } from \"../Misc/precisionDate\";\r\nimport { DepthCullingState } from \"../States/depthCullingState\";\r\nimport { StencilStateComposer } from \"../States/stencilStateComposer\";\r\nimport { StencilState } from \"../States/stencilState\";\r\nimport { AlphaState } from \"../States/alphaCullingState\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { IsDocumentAvailable, IsNavigatorAvailable, IsWindowObjectExist } from \"../Misc/domManagement\";\r\nimport { Constants } from \"./constants\";\r\nimport { EngineFunctionContext, _LoadFile } from \"./abstractEngine.functions\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { type IInternalTextureLoader } from \"../Materials/Textures/Loaders/internalTextureLoader\";\r\n\r\n/**\r\n * Defines the interface used by objects working like Scene\r\n * @internal\r\n */\r\nexport interface ISceneLike {\r\n    /** Add pending data  (to load) */\r\n    addPendingData(data: any): void;\r\n    /** Remove pending data */\r\n    removePendingData(data: any): void;\r\n    /** Offline provider */\r\n    offlineProvider: IOfflineProvider;\r\n}\r\n\r\n/**\r\n * Queue a new function into the requested animation frame pool (ie. this function will be executed by the browser (or the javascript engine) for the next frame)\r\n * @param func - the function to be called\r\n * @param requester - the object that will request the next frame. Falls back to window.\r\n * @returns frame number\r\n */\r\nexport function QueueNewFrame(func: () => void, requester?: any): number {\r\n    // Note that there is kind of a typing issue here, as `setTimeout` might return something else than a number (NodeJs returns a NodeJS.Timeout object).\r\n    // Also if the global `requestAnimationFrame`'s returnType is number, `requester.requestPostAnimationFrame` and `requester.requestAnimationFrame` types\r\n    // are `any`.\r\n\r\n    if (requester) {\r\n        const { requestAnimationFrame } = requester as { requestAnimationFrame: (callback: FrameRequestCallback) => number };\r\n        if (typeof requestAnimationFrame === \"function\") {\r\n            return requestAnimationFrame(func);\r\n        }\r\n    }\r\n\r\n    if (!IsWindowObjectExist()) {\r\n        if (typeof requestAnimationFrame === \"function\") {\r\n            return requestAnimationFrame(func);\r\n        }\r\n    } else {\r\n        const { requestAnimationFrame } = (requester || window) as { requestAnimationFrame: (callback: FrameRequestCallback) => number };\r\n        if (typeof requestAnimationFrame === \"function\") {\r\n            return requestAnimationFrame(func);\r\n        }\r\n    }\r\n\r\n    // fallback to the global `setTimeout`.\r\n    // In most cases (aka in the browser), `window` is the global object, so instead of calling `window.setTimeout` we could call the global `setTimeout`.\r\n    return setTimeout(func, 16) as unknown as number;\r\n}\r\n\r\n/** Interface defining initialization parameters for AbstractEngine class */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface AbstractEngineOptions {\r\n    /**\r\n     * Defines if the engine should no exceed a specified device ratio\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio\r\n     */\r\n    limitDeviceRatio?: number;\r\n    /**\r\n     * Defines if webaudio should be initialized as well\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n     */\r\n    audioEngine?: boolean;\r\n    /**\r\n     * Specifies options for the audio engine\r\n     */\r\n    audioEngineOptions?: IAudioEngineOptions;\r\n\r\n    /**\r\n     * Defines if animations should run using a deterministic lock step\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     */\r\n    deterministicLockstep?: boolean;\r\n    /** Defines the maximum steps to use with deterministic lock step mode */\r\n    lockstepMaxSteps?: number;\r\n    /** Defines the seconds between each deterministic lock step */\r\n    timeStep?: number;\r\n    /**\r\n     * Defines that engine should ignore context lost events\r\n     * If this event happens when this parameter is true, you will have to reload the page to restore rendering\r\n     */\r\n    doNotHandleContextLost?: boolean;\r\n    /**\r\n     * Defines that engine should ignore modifying touch action attribute and style\r\n     * If not handle, you might need to set it up on your side for expected touch devices behavior.\r\n     */\r\n    doNotHandleTouchAction?: boolean;\r\n\r\n    /**\r\n     * Make the matrix computations to be performed in 64 bits instead of 32 bits. False by default.\r\n     * Note that setting useLargeWorldRendering will also set high precision matrices\r\n     */\r\n    useHighPrecisionMatrix?: boolean;\r\n\r\n    /**\r\n     * LargeWorldRendering helps avoid floating point imprecision of rendering large worlds by\r\n     * 1. Forcing highPrecisionMatrices (matrix computations in 64 bits instead of 32)\r\n     * 2. Enabling floatingOriginMode in all scenes -- offsetting position-related uniform and attribute values before passing to shader so that active camera is centered at origin and world is offset by active camera position\r\n     *\r\n     * NOTE that if this mode is set during engineCreation, all scenes will have floatingOrigin offset and you do not need to send floatingOriginMode option to each scene creation.\r\n     * If you'd like to have only specific scenes using the offset logic, you can set the flag on those scenes directly -- however, to achieve proper large world rendering, you must also set the useHighPrecisionMatrix option on engine.\r\n     */\r\n    readonly useLargeWorldRendering?: boolean;\r\n\r\n    /**\r\n     * Defines whether to adapt to the device's viewport characteristics (default: false)\r\n     */\r\n    adaptToDeviceRatio?: boolean;\r\n\r\n    /**\r\n     * Defines whether MSAA is enabled on the canvas.\r\n     */\r\n    antialias?: boolean;\r\n\r\n    /**\r\n     * Defines whether the stencil buffer should be enabled.\r\n     */\r\n    stencil?: boolean;\r\n\r\n    /**\r\n     * Defines whether the canvas should be created in \"premultiplied\" mode (if false, the canvas is created in the \"opaque\" mode) (true by default)\r\n     */\r\n    premultipliedAlpha?: boolean;\r\n    /**\r\n     * True if the more expensive but exact conversions should be used for transforming colors to and from linear space within shaders.\r\n     * Otherwise, the default is to use a cheaper approximation.\r\n     */\r\n    useExactSrgbConversions?: boolean;\r\n\r\n    /**\r\n     * Defines the tab index to set on the rendering canvas (default: 1).\r\n     * Any value >= 0 makes the canvas focusable so it can capture keyboard events and places it in the\r\n     * document's sequential tab order (0 follows DOM order, a positive value forces an explicit order).\r\n     * Use -1 to keep the canvas focusable programmatically (via focus()) while excluding it from the tab order.\r\n     */\r\n    canvasTabIndex?: number;\r\n}\r\n\r\n/**\r\n * Information about the current host\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface HostInformation {\r\n    /**\r\n     * Defines if the current host is a mobile\r\n     */\r\n    isMobile: boolean;\r\n}\r\n\r\nexport type PrepareTextureProcessFunction = (\r\n    width: number,\r\n    height: number,\r\n    img: HTMLImageElement | ImageBitmap | { width: number; height: number },\r\n    extension: string,\r\n    texture: InternalTexture,\r\n    continuationCallback: () => void\r\n) => boolean;\r\n\r\nexport type PrepareTextureFunction = (\r\n    texture: InternalTexture,\r\n    extension: string,\r\n    scene: Nullable<ISceneLike>,\r\n    img: HTMLImageElement | ImageBitmap | { width: number; height: number },\r\n    invertY: boolean,\r\n    noMipmap: boolean,\r\n    isCompressed: boolean,\r\n    processFunction: PrepareTextureProcessFunction,\r\n    samplingMode: number\r\n) => void;\r\n\r\n/**\r\n * The parent class for specialized engines (WebGL, WebGPU)\r\n */\r\nexport abstract class AbstractEngine {\r\n    // States\r\n    /** @internal */\r\n    protected _colorWrite = true;\r\n    /** @internal */\r\n    protected _colorWriteChanged = true;\r\n    /** @internal */\r\n    public _depthCullingState = new DepthCullingState();\r\n    /** @internal */\r\n    protected _stencilStateComposer = new StencilStateComposer();\r\n    /** @internal */\r\n    public _stencilState = new StencilState();\r\n    /** @internal */\r\n    public _alphaState = new AlphaState(false);\r\n    /** @internal */\r\n    public _alphaMode = Array(8).fill(-1);\r\n    /** @internal */\r\n    public _alphaEquation = Array(8).fill(-1);\r\n\r\n    protected _activeRequests: IFileRequest[] = [];\r\n\r\n    /** @internal */\r\n    public _badOS = false;\r\n    /** @internal */\r\n    public _badDesktopOS = false;\r\n    /** @internal */\r\n    public _videoTextureSupported: boolean;\r\n\r\n    protected _compatibilityMode = true;\r\n    /** @internal */\r\n    public _pointerLockRequested: boolean;\r\n    /** @internal */\r\n    public _loadingScreen: ILoadingScreen;\r\n    /** @internal */\r\n    public _renderingCanvas: Nullable<HTMLCanvasElement>;\r\n    /** @internal */\r\n    public _internalTexturesCache = new Array<InternalTexture>();\r\n    protected _currentEffect: Nullable<Effect>;\r\n    /** @internal */\r\n    protected _cachedVertexBuffers: any;\r\n    /** @internal */\r\n    protected _cachedIndexBuffer: Nullable<DataBuffer>;\r\n    /** @internal */\r\n    protected _cachedEffectForVertexBuffers: Nullable<Effect>;\r\n    /** @internal */\r\n    public _currentRenderTarget: Nullable<RenderTargetWrapper> = null;\r\n    /** @internal */\r\n    public _caps: EngineCapabilities;\r\n    /** @internal */\r\n    protected _cachedViewport: Nullable<IViewportLike>;\r\n    /** @internal */\r\n    public _currentDrawContext: IDrawContext;\r\n    /** @internal */\r\n    public _currentMaterialContext: IMaterialContext;\r\n\r\n    /** @internal */\r\n    protected _boundTexturesCache: { [key: string]: Nullable<InternalTexture> } = {};\r\n    /** @internal */\r\n    protected _activeChannel = 0;\r\n    /** @internal */\r\n    protected _currentTextureChannel = -1;\r\n    /** @internal */\r\n    protected _viewportCached = { x: 0, y: 0, z: 0, w: 0 };\r\n\r\n    /** @internal */\r\n    protected _isWebGPU: boolean = false;\r\n\r\n    /** @internal */\r\n    public _enableGPUDebugMarkers: boolean = false;\r\n\r\n    // Focus\r\n    /** @internal */\r\n    public _onFocus: () => void;\r\n    /** @internal */\r\n    public _onBlur: () => void;\r\n    /** @internal */\r\n    public _onCanvasPointerOut: (event: PointerEvent) => void;\r\n    /** @internal */\r\n    public _onCanvasBlur: () => void;\r\n    /** @internal */\r\n    public _onCanvasFocus: () => void;\r\n    /** @internal */\r\n    public _onCanvasContextMenu: (evt: Event) => void;\r\n    /** @internal */\r\n    public _onFullscreenChange: () => void;\r\n\r\n    /**\r\n     * Observable event triggered each time the canvas loses focus\r\n     */\r\n    public onCanvasBlurObservable = new Observable<AbstractEngine>();\r\n    /**\r\n     * Observable event triggered each time the canvas gains focus\r\n     */\r\n    public onCanvasFocusObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Event raised when a new scene is created\r\n     */\r\n    public onNewSceneAddedObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * Observable event triggered each time the rendering canvas is resized\r\n     */\r\n    public onResizeObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Observable event triggered each time the canvas receives pointerout event\r\n     */\r\n    public onCanvasPointerOutObservable = new Observable<PointerEvent>();\r\n\r\n    /**\r\n     * Observable event triggered each time an effect compilation fails\r\n     */\r\n    public onEffectErrorObservable = new Observable<{ effect: Effect; errors: string }>();\r\n\r\n    /**\r\n     * Turn this value on if you want to pause FPS computation when in background\r\n     */\r\n    public disablePerformanceMonitorInBackground = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that vertex array object must be disabled even if they are supported\r\n     */\r\n    public disableVertexArrayObjects = false;\r\n\r\n    /** @internal */\r\n    protected _frameId = 0;\r\n    /**\r\n     * Gets the current frame id\r\n     */\r\n    public get frameId(): number {\r\n        return this._frameId;\r\n    }\r\n    /**\r\n     * Gets a boolean indicating if the engine runs in WebGPU or not.\r\n     */\r\n    public get isWebGPU(): boolean {\r\n        return this._isWebGPU;\r\n    }\r\n\r\n    protected _shaderProcessor: Nullable<IShaderProcessor>;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getShaderProcessor(_shaderLanguage: ShaderLanguage): Nullable<IShaderProcessor> {\r\n        return this._shaderProcessor;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _resetAlphaMode(): void {\r\n        this._alphaMode.fill(-1);\r\n        this._alphaEquation.fill(-1);\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if all created effects are ready\r\n     * @returns true if all effects are ready\r\n     */\r\n    public abstract areAllEffectsReady(): boolean;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _setTexture(channel: number, texture: Nullable<ThinTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean, name?: string): boolean;\r\n\r\n    /**\r\n     * Sets a texture to the according uniform.\r\n     * @param channel The texture channel\r\n     * @param unused unused parameter\r\n     * @param texture The texture to apply\r\n     * @param name The name of the uniform in the effect\r\n     */\r\n    public abstract setTexture(channel: number, unused: Nullable<WebGLUniformLocation>, texture: Nullable<ThinTexture>, name: string): void;\r\n\r\n    /**\r\n     * Binds an effect to the webGL context\r\n     * @param effect defines the effect to bind\r\n     */\r\n    public abstract bindSamplers(effect: Effect): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _bindTexture(channel: number, texture: Nullable<InternalTexture>, name: string): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _deletePipelineContext(pipelineContext: IPipelineContext): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _preparePipelineContextAsync(\r\n        pipelineContext: IPipelineContext,\r\n        vertexSourceCode: string,\r\n        fragmentSourceCode: string,\r\n        createAsRaw: boolean,\r\n        rawVertexSourceCode: string,\r\n        rawFragmentSourceCode: string,\r\n        rebuildRebind: any,\r\n        defines: Nullable<string>,\r\n        transformFeedbackVaryings: Nullable<string[]>,\r\n        key: string,\r\n        onReady: () => void\r\n    ): void;\r\n\r\n    /** @internal */\r\n    protected _shaderPlatformName: string;\r\n    /**\r\n     * Gets the shader platform name used by the effects.\r\n     */\r\n    public get shaderPlatformName(): string {\r\n        return this._shaderPlatformName;\r\n    }\r\n\r\n    /**\r\n     * Gets information about the current host\r\n     */\r\n    public hostInformation: HostInformation = {\r\n        isMobile: false,\r\n    };\r\n\r\n    /**\r\n     * Gets a boolean indicating if the engine is currently rendering in fullscreen mode\r\n     */\r\n    public isFullscreen = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean to enable/disable IndexedDB support and avoid XHR on .manifest\r\n     **/\r\n    public enableOfflineSupport = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean to enable/disable checking manifest if IndexedDB support is enabled (js will always consider the database is up to date)\r\n     **/\r\n    public disableManifestCheck = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean to enable/disable the context menu (right-click) from appearing on the main canvas\r\n     */\r\n    public disableContextMenu: boolean = true;\r\n\r\n    /**\r\n     * Gets or sets the current render pass id\r\n     */\r\n    public currentRenderPassId = Constants.RENDERPASS_MAIN;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the pointer is currently locked\r\n     */\r\n    public isPointerLock = false;\r\n\r\n    /**\r\n     * Gets the list of created postprocesses\r\n     */\r\n    public postProcesses: PostProcess[] = [];\r\n\r\n    /** Gets or sets the tab index to set to the rendering canvas. Any value >= 0 makes the canvas focusable to capture keyboard events and adds it to the tab order; use -1 to keep it focusable programmatically but out of the tab order */\r\n    public canvasTabIndex = 1;\r\n\r\n    /** @internal */\r\n    protected _onContextLost: (evt: Event) => void;\r\n    /** @internal */\r\n    protected _onContextRestored: (evt: Event) => void;\r\n    /** @internal */\r\n    protected _contextWasLost = false;\r\n\r\n    private _emptyTexture: Nullable<InternalTexture>;\r\n    private _emptyCubeTexture: Nullable<InternalTexture>;\r\n    private _emptyTexture3D: Nullable<InternalTexture>;\r\n    private _emptyTexture2DArray: Nullable<InternalTexture>;\r\n\r\n    protected _clearEmptyResources(): void {\r\n        this._emptyTexture = null;\r\n        this._emptyCubeTexture = null;\r\n        this._emptyTexture3D = null;\r\n        this._emptyTexture2DArray = null;\r\n    }\r\n\r\n    /**\r\n     * Force the engine to wipe all caches\r\n     * @param bruteForce defines a boolean to force clearing ALL caches\r\n     */\r\n    public abstract wipeCaches(bruteForce?: boolean): void;\r\n\r\n    private _useReverseDepthBuffer = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if depth buffer should be reverse, going from far to near.\r\n     * This can provide greater z depth for distant objects.\r\n     */\r\n    public get useReverseDepthBuffer(): boolean {\r\n        return this._useReverseDepthBuffer;\r\n    }\r\n\r\n    public set useReverseDepthBuffer(useReverse) {\r\n        if (useReverse === this._useReverseDepthBuffer) {\r\n            return;\r\n        }\r\n\r\n        this._useReverseDepthBuffer = useReverse;\r\n\r\n        if (useReverse) {\r\n            this._depthCullingState.depthFunc = Constants.GEQUAL;\r\n        } else {\r\n            this._depthCullingState.depthFunc = Constants.LEQUAL;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enable or disable color writing\r\n     * @param enable defines the state to set\r\n     */\r\n    public setColorWrite(enable: boolean): void {\r\n        if (enable !== this._colorWrite) {\r\n            this._colorWriteChanged = true;\r\n            this._colorWrite = enable;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if color writing is enabled\r\n     * @returns the current color writing state\r\n     */\r\n    public getColorWrite(): boolean {\r\n        return this._colorWrite;\r\n    }\r\n\r\n    /**\r\n     * Gets the depth culling state manager\r\n     */\r\n    public get depthCullingState(): DepthCullingState {\r\n        return this._depthCullingState;\r\n    }\r\n\r\n    /**\r\n     * Gets the alpha state manager\r\n     */\r\n    public get alphaState(): AlphaState {\r\n        return this._alphaState;\r\n    }\r\n\r\n    /**\r\n     * Gets the stencil state manager\r\n     */\r\n    public get stencilState(): StencilState {\r\n        return this._stencilState;\r\n    }\r\n\r\n    /**\r\n     * Gets the stencil state composer\r\n     */\r\n    public get stencilStateComposer(): StencilStateComposer {\r\n        return this._stencilStateComposer;\r\n    }\r\n\r\n    /**\r\n     * Indicates if the z range in NDC space is 0..1 (value: true) or -1..1 (value: false)\r\n     */\r\n    public readonly isNDCHalfZRange: boolean = false;\r\n\r\n    /**\r\n     * Indicates that the origin of the texture/framebuffer space is the bottom left corner. If false, the origin is top left\r\n     */\r\n    public readonly hasOriginBottomLeft: boolean = true;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the exact sRGB conversions or faster approximations are used for converting to and from linear space.\r\n     */\r\n    public readonly useExactSrgbConversions: boolean;\r\n\r\n    /** @internal */\r\n    public _getGlobalDefines(defines?: { [key: string]: string }): string | undefined {\r\n        if (defines) {\r\n            if (this.isNDCHalfZRange) {\r\n                defines[\"IS_NDC_HALF_ZRANGE\"] = \"\";\r\n            } else {\r\n                delete defines[\"IS_NDC_HALF_ZRANGE\"];\r\n            }\r\n            if (this.useReverseDepthBuffer) {\r\n                defines[\"USE_REVERSE_DEPTHBUFFER\"] = \"\";\r\n            } else {\r\n                delete defines[\"USE_REVERSE_DEPTHBUFFER\"];\r\n            }\r\n            if (this.useExactSrgbConversions) {\r\n                defines[\"USE_EXACT_SRGB_CONVERSIONS\"] = \"\";\r\n            } else {\r\n                delete defines[\"USE_EXACT_SRGB_CONVERSIONS\"];\r\n            }\r\n            return;\r\n        } else {\r\n            let s = \"\";\r\n            if (this.isNDCHalfZRange) {\r\n                s += \"#define IS_NDC_HALF_ZRANGE\";\r\n            }\r\n            if (this.useReverseDepthBuffer) {\r\n                if (s) {\r\n                    s += \"\\n\";\r\n                }\r\n                s += \"#define USE_REVERSE_DEPTHBUFFER\";\r\n            }\r\n            if (this.useExactSrgbConversions) {\r\n                if (s) {\r\n                    s += \"\\n\";\r\n                }\r\n                s += \"#define USE_EXACT_SRGB_CONVERSIONS\";\r\n            }\r\n            return s;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _renderTargetWrapperCache = new Array<RenderTargetWrapper>();\r\n    /** @internal */\r\n    protected _compiledEffects: { [key: string]: Effect } = {};\r\n\r\n    private _rebuildInternalTextures(): void {\r\n        const currentState = this._internalTexturesCache.slice(); // Do a copy because the rebuild will add proxies\r\n\r\n        for (const internalTexture of currentState) {\r\n            internalTexture._rebuild();\r\n        }\r\n    }\r\n\r\n    private _rebuildRenderTargetWrappers(): void {\r\n        const currentState = this._renderTargetWrapperCache.slice(); // Do a copy because the rebuild will add proxies\r\n\r\n        for (const renderTargetWrapper of currentState) {\r\n            // Wrapped textures (source === External) are host-owned; their format is opaque to Babylon, so we can't\r\n            // rebuild them. The host re-supplies a fresh handle via updateWrappedWebGLTexture /\r\n            // updateWrappedNativeTexture / updateWrappedWebGPUTexture from its onContextRestoredObservable handler.\r\n            // Scan all attachments for the multi-RT case (rtWrapper.texture only returns _textures[0]).\r\n            if (renderTargetWrapper.textures?.some((t) => t.source === InternalTextureSource.External)) {\r\n                continue;\r\n            }\r\n            renderTargetWrapper._rebuild();\r\n        }\r\n    }\r\n\r\n    private _rebuildEffects(): void {\r\n        for (const key in this._compiledEffects) {\r\n            const effect = this._compiledEffects[key];\r\n\r\n            effect._pipelineContext = null; // because _prepareEffect will try to dispose this pipeline before recreating it and that would lead to webgl errors\r\n            effect._prepareEffect();\r\n        }\r\n\r\n        Effect.ResetCache();\r\n    }\r\n\r\n    protected _rebuildGraphicsResources(): void {\r\n        // Ensure webgl and engine states are matching\r\n        this.wipeCaches(true);\r\n\r\n        // Rebuild effects\r\n        this._rebuildEffects();\r\n        this._rebuildComputeEffects?.();\r\n\r\n        // Note:\r\n        //  The call to _rebuildBuffers must be made before the call to _rebuildInternalTextures because in the process of _rebuildBuffers the buffers used by the post process managers will be rebuilt\r\n        //  and we may need to use the post process manager of the scene during _rebuildInternalTextures (in WebGL1, non-POT textures are rescaled using a post process + post process manager of the scene)\r\n\r\n        // Rebuild buffers\r\n        this._rebuildBuffers();\r\n        // Rebuild textures\r\n        this._rebuildInternalTextures();\r\n        // Rebuild textures\r\n        this._rebuildTextures();\r\n        // Rebuild textures\r\n        this._rebuildRenderTargetWrappers();\r\n\r\n        // Reset engine states after all the buffer/textures/... have been rebuilt\r\n        this.wipeCaches(true);\r\n    }\r\n\r\n    protected _flagContextRestored(): void {\r\n        Logger.Warn(this.name + \" context successfully restored.\");\r\n        this.onContextRestoredObservable.notifyObservers(this);\r\n        this._contextWasLost = false;\r\n    }\r\n\r\n    protected _restoreEngineAfterContextLost(initEngine: () => void): void {\r\n        // Adding a timeout to avoid race condition at browser level\r\n        setTimeout(() => {\r\n            this._clearEmptyResources();\r\n\r\n            const depthTest = this._depthCullingState.depthTest; // backup those values because the call to initEngine / wipeCaches will reset them\r\n            const depthFunc = this._depthCullingState.depthFunc;\r\n            const depthMask = this._depthCullingState.depthMask;\r\n            const stencilTest = this._stencilState.stencilTest;\r\n\r\n            // Rebuild context\r\n            initEngine();\r\n            this._rebuildGraphicsResources();\r\n\r\n            this._depthCullingState.depthTest = depthTest;\r\n            this._depthCullingState.depthFunc = depthFunc;\r\n            this._depthCullingState.depthMask = depthMask;\r\n            this._stencilState.stencilTest = stencilTest;\r\n\r\n            this._flagContextRestored();\r\n        }, 0);\r\n    }\r\n\r\n    /** @internal */\r\n    protected _isDisposed = false;\r\n\r\n    /** Gets a boolean indicating if the engine was disposed */\r\n    public get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of created scenes\r\n     */\r\n    public scenes: Scene[] = [];\r\n\r\n    /** @internal */\r\n    public _virtualScenes = new Array<Scene>();\r\n\r\n    /** @internal */\r\n    public _features: EngineFeatures;\r\n\r\n    /**\r\n     * Enables or disables the snapshot rendering mode\r\n     * Note that the WebGL engine does not support snapshot rendering so setting the value won't have any effect for this engine\r\n     */\r\n    public get snapshotRendering(): boolean {\r\n        return false;\r\n    }\r\n\r\n    public set snapshotRendering(activate) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the snapshot rendering mode\r\n     */\r\n    public get snapshotRenderingMode(): number {\r\n        return Constants.SNAPSHOTRENDERING_STANDARD;\r\n    }\r\n\r\n    public set snapshotRenderingMode(mode: number) {}\r\n\r\n    /**\r\n     * Observable event triggered before each texture is initialized\r\n     */\r\n    public onBeforeTextureInitObservable = new Observable<Texture>();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the engine must keep rendering even if the window is not in foreground\r\n     */\r\n    public renderEvenInBackground = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that cache can be kept between frames\r\n     */\r\n    public preventCacheWipeBetweenFrames = false;\r\n\r\n    /**\r\n     * Returns the string \"AbstractEngine\"\r\n     * @returns \"AbstractEngine\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"AbstractEngine\";\r\n    }\r\n\r\n    /**\r\n     * Gets the default empty texture\r\n     */\r\n    public get emptyTexture(): InternalTexture {\r\n        if (!this._emptyTexture) {\r\n            this._emptyTexture = this.createRawTexture(new Uint8Array(4), 1, 1, Constants.TEXTUREFORMAT_RGBA, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n        }\r\n\r\n        return this._emptyTexture;\r\n    }\r\n\r\n    /**\r\n     * Gets the default empty 3D texture\r\n     */\r\n    public get emptyTexture3D(): InternalTexture {\r\n        if (!this._emptyTexture3D) {\r\n            this._emptyTexture3D = this.createRawTexture3D(new Uint8Array(4), 1, 1, 1, Constants.TEXTUREFORMAT_RGBA, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n        }\r\n\r\n        return this._emptyTexture3D;\r\n    }\r\n\r\n    /**\r\n     * Gets the default empty 2D array texture\r\n     */\r\n    public get emptyTexture2DArray(): InternalTexture {\r\n        if (!this._emptyTexture2DArray) {\r\n            this._emptyTexture2DArray = this.createRawTexture2DArray(\r\n                new Uint8Array(4),\r\n                1,\r\n                1,\r\n                1,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                false,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE\r\n            );\r\n        }\r\n\r\n        return this._emptyTexture2DArray;\r\n    }\r\n\r\n    /**\r\n     * Gets the default empty cube texture\r\n     */\r\n    public get emptyCubeTexture(): InternalTexture {\r\n        if (!this._emptyCubeTexture) {\r\n            const faceData = new Uint8Array(4);\r\n            const cubeData = [faceData, faceData, faceData, faceData, faceData, faceData];\r\n            this._emptyCubeTexture = this.createRawCubeTexture(\r\n                cubeData,\r\n                1,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                false,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE\r\n            );\r\n        }\r\n\r\n        return this._emptyCubeTexture;\r\n    }\r\n\r\n    /** @internal */\r\n    public _frameHandler: number = 0;\r\n\r\n    /** @internal */\r\n    protected _activeRenderLoops = new Array<() => void>();\r\n\r\n    /**\r\n     * If set, will be used to request the next animation frame for the render loop\r\n     */\r\n    public customAnimationFrameRequester: Nullable<ICustomAnimationFrameRequester> = null;\r\n\r\n    protected _framebufferDimensionsObject: Nullable<{ framebufferWidth: number; framebufferHeight: number }>;\r\n\r\n    /**\r\n     * sets the object from which width and height will be taken from when getting render width and height\r\n     * @param dimensions the framebuffer width and height that will be used.\r\n     */\r\n    public set framebufferDimensionsObject(dimensions: Nullable<{ framebufferWidth: number; framebufferHeight: number }>) {\r\n        this._framebufferDimensionsObject = dimensions;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of current active render loop functions\r\n     * @returns a read only array with the current render loop functions\r\n     */\r\n    public get activeRenderLoops(): ReadonlyArray<() => void> {\r\n        return this._activeRenderLoops;\r\n    }\r\n\r\n    /**\r\n     * stop executing a render loop function and remove it from the execution array\r\n     * @param renderFunction defines the function to be removed. If not provided all functions will be removed.\r\n     */\r\n    public stopRenderLoop(renderFunction?: () => void): void {\r\n        if (!renderFunction) {\r\n            this._activeRenderLoops.length = 0;\r\n            this._cancelFrame();\r\n            return;\r\n        }\r\n\r\n        const index = this._activeRenderLoops.indexOf(renderFunction);\r\n\r\n        if (index >= 0) {\r\n            this._activeRenderLoops.splice(index, 1);\r\n            if (this._activeRenderLoops.length == 0) {\r\n                this._cancelFrame();\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _cancelFrame() {\r\n        if (this.customAnimationFrameRequester) {\r\n            if (this._frameHandler !== 0) {\r\n                this._frameHandler = 0;\r\n                const { cancelAnimationFrame } = this.customAnimationFrameRequester;\r\n                if (cancelAnimationFrame) {\r\n                    cancelAnimationFrame(this.customAnimationFrameRequester.requestID);\r\n                }\r\n                delete this.customAnimationFrameRequester.requestID;\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (this._frameHandler !== 0) {\r\n            const handlerToCancel = this._frameHandler;\r\n            this._frameHandler = 0;\r\n\r\n            if (!IsWindowObjectExist()) {\r\n                if (typeof cancelAnimationFrame === \"function\") {\r\n                    return cancelAnimationFrame(handlerToCancel);\r\n                }\r\n            } else {\r\n                const { cancelAnimationFrame } = this.getHostWindow() || window;\r\n                if (typeof cancelAnimationFrame === \"function\") {\r\n                    return cancelAnimationFrame(handlerToCancel);\r\n                }\r\n            }\r\n            return clearTimeout(handlerToCancel);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _windowIsBackground = false;\r\n\r\n    /**\r\n     * Begin a new frame\r\n     */\r\n    public beginFrame(): void {\r\n        this.onBeginFrameObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * End the current frame\r\n     */\r\n    public endFrame(): void {\r\n        this._frameId++;\r\n\r\n        this.onEndFrameObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the performance monitor attached to this engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n     */\r\n    public abstract get performanceMonitor(): PerformanceMonitor;\r\n\r\n    /** @internal */\r\n    public _boundRenderFunction: any = (timestamp: number) => this._renderLoop(timestamp);\r\n\r\n    protected _maxFPS: number | undefined;\r\n    protected _minFrameTime: number;\r\n    protected _lastFrameTime: number = 0;\r\n    protected _renderAccumulator: number = 0;\r\n\r\n    /**\r\n     * Skip frame rendering but keep the frame heartbeat (begin/end frame).\r\n     * This is useful if you need all the plumbing but not the rendering work.\r\n     * (for instance when capturing a screenshot where you do not want to mix rendering to the screen and to the screenshot)\r\n     */\r\n    public skipFrameRender = false;\r\n\r\n    /** Gets or sets max frame per second allowed. Will return undefined if not capped */\r\n    public get maxFPS(): number | undefined {\r\n        return this._maxFPS;\r\n    }\r\n\r\n    public set maxFPS(value: number | undefined) {\r\n        this._maxFPS = value;\r\n\r\n        if (value === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (value <= 0) {\r\n            this._minFrameTime = Number.MAX_VALUE;\r\n            return;\r\n        }\r\n\r\n        this._minFrameTime = 1000 / value;\r\n    }\r\n\r\n    protected _isOverFrameTime(timestamp?: number): boolean {\r\n        if (!timestamp || this._maxFPS === undefined) {\r\n            return false;\r\n        }\r\n\r\n        const elapsedTime = timestamp - this._lastFrameTime;\r\n        this._lastFrameTime = timestamp;\r\n\r\n        this._renderAccumulator += elapsedTime;\r\n\r\n        if (this._renderAccumulator < this._minFrameTime) {\r\n            return true;\r\n        }\r\n\r\n        this._renderAccumulator -= this._minFrameTime;\r\n\r\n        if (this._renderAccumulator > this._minFrameTime) {\r\n            this._renderAccumulator = this._minFrameTime;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    protected _processFrame(timestamp?: number) {\r\n        this._frameHandler = 0;\r\n\r\n        if (!this._contextWasLost && !this._isOverFrameTime(timestamp)) {\r\n            let shouldRender = true;\r\n            if (this.isDisposed || (!this.renderEvenInBackground && this._windowIsBackground)) {\r\n                shouldRender = false;\r\n            }\r\n\r\n            if (shouldRender) {\r\n                // Start new frame\r\n                this.beginFrame();\r\n\r\n                // Child canvases\r\n                if (!this.skipFrameRender && !this._renderViews()) {\r\n                    // Main frame\r\n                    this._renderFrame();\r\n                }\r\n\r\n                // Present\r\n                this.endFrame();\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _renderLoop(timestamp?: number): void {\r\n        this._processFrame(timestamp);\r\n\r\n        // The first condition prevents queuing another frame if we no longer have active render loops (e.g., if\r\n        // `stopRenderLoop` is called mid frame). The second condition prevents queuing another frame if one has\r\n        // already been queued (e.g., if `stopRenderLoop` and `runRenderLoop` is called mid frame).\r\n        if (this._activeRenderLoops.length > 0 && this._frameHandler === 0) {\r\n            this._queueNewFrameForRenderLoop();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _renderFrame() {\r\n        for (let index = 0; index < this._activeRenderLoops.length; index++) {\r\n            const renderFunction = this._activeRenderLoops[index];\r\n\r\n            renderFunction();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _renderViews() {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Can be used to override the current requestAnimationFrame requester.\r\n     * @internal\r\n     */\r\n    protected _queueNewFrame(bindedRenderFunction: any, requester?: any): number {\r\n        return QueueNewFrame(bindedRenderFunction, requester);\r\n    }\r\n\r\n    protected _queueNewFrameForRenderLoop(): void {\r\n        if (this.customAnimationFrameRequester) {\r\n            this.customAnimationFrameRequester.requestID = this._queueNewFrame(\r\n                this.customAnimationFrameRequester.renderFunction || this._boundRenderFunction,\r\n                this.customAnimationFrameRequester\r\n            );\r\n            this._frameHandler = this.customAnimationFrameRequester.requestID;\r\n        } else {\r\n            this._frameHandler = this._queueNewFrame(this._boundRenderFunction, this.getHostWindow());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Register and execute a render loop. The engine can have more than one render function\r\n     * @param renderFunction defines the function to continuously execute\r\n     */\r\n    public runRenderLoop(renderFunction: () => void): void {\r\n        if (this._activeRenderLoops.indexOf(renderFunction) !== -1) {\r\n            return;\r\n        }\r\n\r\n        this._activeRenderLoops.push(renderFunction);\r\n\r\n        // On the first added function, start the render loop.\r\n        if (this._activeRenderLoops.length === 1 && this._frameHandler === 0) {\r\n            this._queueNewFrameForRenderLoop();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if depth testing is enabled\r\n     * @returns the current state\r\n     */\r\n    public getDepthBuffer(): boolean {\r\n        return this._depthCullingState.depthTest;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable depth buffering\r\n     * @param enable defines the state to set\r\n     */\r\n    public setDepthBuffer(enable: boolean): void {\r\n        this._depthCullingState.depthTest = enable;\r\n    }\r\n\r\n    /**\r\n     * Set the z offset Factor to apply to current rendering\r\n     * @param value defines the offset to apply\r\n     */\r\n    public setZOffset(value: number): void {\r\n        this._depthCullingState.zOffset = this.useReverseDepthBuffer ? -value : value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the zOffset Factor\r\n     * @returns the current zOffset Factor state\r\n     */\r\n    public getZOffset(): number {\r\n        const zOffset = this._depthCullingState.zOffset;\r\n        return this.useReverseDepthBuffer ? -zOffset : zOffset;\r\n    }\r\n\r\n    /**\r\n     * Set the z offset Units to apply to current rendering\r\n     * @param value defines the offset to apply\r\n     */\r\n    public setZOffsetUnits(value: number): void {\r\n        this._depthCullingState.zOffsetUnits = this.useReverseDepthBuffer ? -value : value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the zOffset Units\r\n     * @returns the current zOffset Units state\r\n     */\r\n    public getZOffsetUnits(): number {\r\n        const zOffsetUnits = this._depthCullingState.zOffsetUnits;\r\n        return this.useReverseDepthBuffer ? -zOffsetUnits : zOffsetUnits;\r\n    }\r\n\r\n    /**\r\n     * Gets host window\r\n     * @returns the host window object\r\n     */\r\n    public getHostWindow(): Nullable<Window> {\r\n        if (!IsWindowObjectExist()) {\r\n            return null;\r\n        }\r\n\r\n        if (this._renderingCanvas && this._renderingCanvas.ownerDocument && this._renderingCanvas.ownerDocument.defaultView) {\r\n            return this._renderingCanvas.ownerDocument.defaultView;\r\n        }\r\n\r\n        return window;\r\n    }\r\n\r\n    /**\r\n     * (WebGPU only) True (default) to be in compatibility mode, meaning rendering all existing scenes without artifacts (same rendering than WebGL).\r\n     * Setting the property to false will improve performances but may not work in some scenes if some precautions are not taken.\r\n     * See https://doc.babylonjs.com/setup/support/webGPU/webGPUOptimization/webGPUNonCompatibilityMode for more details\r\n     */\r\n    public get compatibilityMode() {\r\n        return this._compatibilityMode;\r\n    }\r\n\r\n    public set compatibilityMode(mode: boolean) {\r\n        // not supported in WebGL\r\n        this._compatibilityMode = true;\r\n    }\r\n\r\n    /**\r\n     * Observable raised when the engine is about to compile a shader\r\n     */\r\n    public onBeforeShaderCompilationObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Observable raised when the engine has just compiled a shader\r\n     */\r\n    public onAfterShaderCompilationObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Observable raised when the engine begins a new frame\r\n     */\r\n    public onBeginFrameObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Observable raised when the engine ends the current frame (requires a render loop, e.g. 'engine.runRenderLoop(...)')\r\n     */\r\n    public onEndFrameObservable = new Observable<AbstractEngine>();\r\n\r\n    protected _rebuildTextures(): void {\r\n        for (const scene of this.scenes) {\r\n            scene._rebuildTextures();\r\n        }\r\n\r\n        for (const scene of this._virtualScenes) {\r\n            scene._rebuildTextures();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _getRGBABufferInternalSizedFormat(type: number, format?: number, useSRGBBuffer?: boolean): number;\r\n\r\n    /** @internal */\r\n    public abstract _getUnpackAlignement(): number;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _uploadCompressedDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        internalFormat: number,\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        faceIndex: number,\r\n        lod?: number\r\n    ): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, forTextureDataUpdate?: boolean, force?: boolean): boolean;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _uploadDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        imageData: ArrayBufferView,\r\n        faceIndex?: number,\r\n        lod?: number,\r\n        babylonInternalFormat?: number,\r\n        useTextureWidthAndHeight?: boolean\r\n    ): void;\r\n\r\n    /** @internal */\r\n    public abstract _unpackFlipY(value: boolean): void;\r\n\r\n    /**\r\n     * Reads pixels from the current frame buffer. Please note that this function can be slow\r\n     * @param x defines the x coordinate of the rectangle where pixels must be read\r\n     * @param y defines the y coordinate of the rectangle where pixels must be read\r\n     * @param width defines the width of the rectangle where pixels must be read\r\n     * @param height defines the height of the rectangle where pixels must be read\r\n     * @param hasAlpha defines whether the output should have alpha or not (defaults to true)\r\n     * @param flushRenderer true to flush the renderer from the pending commands before reading the pixels\r\n     * @returns a ArrayBufferView promise (Uint8Array) containing RGBA colors\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public abstract readPixels(x: number, y: number, width: number, height: number, hasAlpha?: boolean, flushRenderer?: boolean): Promise<ArrayBufferView>;\r\n\r\n    /**\r\n     * Generates mipmaps for a texture\r\n     * @param texture The texture to generate the mipmaps for\r\n     */\r\n    public abstract generateMipmaps(texture: InternalTexture): void;\r\n\r\n    /**\r\n     * Force a flush (ie. a flush of all waiting commands)\r\n     */\r\n    public abstract flushFramebuffer(): void;\r\n\r\n    /** @internal */\r\n    public abstract _currentFrameBufferIsDefaultFrameBuffer(): boolean;\r\n\r\n    /**\r\n     * Creates an internal texture without binding it to a framebuffer\r\n     * @internal\r\n     * @param size defines the size of the texture\r\n     * @param options defines the options used to create the texture\r\n     * @param delayGPUTextureCreation true to delay the texture creation the first time it is really needed. false to create it right away\r\n     * @param source source type of the texture\r\n     * @returns a new internal texture\r\n     */\r\n    public abstract _createInternalTexture(\r\n        size: TextureSize,\r\n        options: boolean | InternalTextureCreationOptions,\r\n        delayGPUTextureCreation?: boolean,\r\n        source?: InternalTextureSource\r\n    ): InternalTexture;\r\n\r\n    /** @internal */\r\n    public abstract applyStates(): void;\r\n\r\n    /**\r\n     * Binds the frame buffer to the specified texture.\r\n     * @param texture The render target wrapper to render to\r\n     * @param faceIndex The face of the texture to render to in case of cube texture\r\n     * @param requiredWidth The width of the target to render to\r\n     * @param requiredHeight The height of the target to render to\r\n     * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true\r\n     * @param lodLevel defines the lod level to bind to the frame buffer\r\n     * @param layer defines the 2d array index to bind to frame buffer to\r\n     */\r\n    public abstract bindFramebuffer(\r\n        texture: RenderTargetWrapper,\r\n        faceIndex?: number,\r\n        requiredWidth?: number,\r\n        requiredHeight?: number,\r\n        forceFullscreenViewport?: boolean,\r\n        lodLevel?: number,\r\n        layer?: number\r\n    ): void;\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param texture defines the texture to update\r\n     * @param wrapU defines the texture wrap mode of the u coordinates\r\n     * @param wrapV defines the texture wrap mode of the v coordinates\r\n     * @param wrapR defines the texture wrap mode of the r coordinates\r\n     */\r\n    public abstract updateTextureWrappingMode(texture: InternalTexture, wrapU: Nullable<number>, wrapV?: Nullable<number>, wrapR?: Nullable<number>): void;\r\n\r\n    /**\r\n     * Unbind the current render target and bind the default framebuffer\r\n     * @param unbindOnly defines a boolean indicating that the function should only unbind the current render target without binding the default framebuffer\r\n     */\r\n    public abstract restoreDefaultFramebuffer(unbindOnly?: boolean): void;\r\n\r\n    /**\r\n     * Draw a list of indexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public abstract drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void;\r\n\r\n    /**\r\n     * Unbind the current render target texture from the webGL context\r\n     * @param texture defines the render target wrapper to unbind\r\n     * @param disableGenerateMipMaps defines a boolean indicating that mipmaps must not be generated\r\n     * @param onBeforeUnbind defines a function which will be called before the effective unbind\r\n     */\r\n    public abstract unBindFramebuffer(texture: RenderTargetWrapper, disableGenerateMipMaps?: boolean, onBeforeUnbind?: () => void): void;\r\n\r\n    /**\r\n     * Generates mipmaps for the texture of the (single) render target\r\n     * @param texture The render target containing the texture to generate the mipmaps for\r\n     */\r\n    public abstract generateMipMapsFramebuffer(texture: RenderTargetWrapper): void;\r\n\r\n    /**\r\n     * Resolves the MSAA texture of the (single) render target into its non-MSAA version.\r\n     * Note that if \"texture\" is not a MSAA render target, no resolve is performed.\r\n     * @param texture The render target texture containing the MSAA texture to resolve\r\n     */\r\n    public abstract resolveFramebuffer(texture: RenderTargetWrapper): void;\r\n\r\n    /**Gets driver info if available */\r\n    public abstract extractDriverInfo(): string;\r\n\r\n    /**\r\n     * Bind a list of vertex buffers to the webGL context\r\n     * @param vertexBuffers defines the list of vertex buffers to bind\r\n     * @param indexBuffer defines the index buffer to bind\r\n     * @param effect defines the effect associated with the vertex buffers\r\n     * @param overrideVertexBuffers defines optional list of avertex buffers that overrides the entries in vertexBuffers\r\n     */\r\n    public abstract bindBuffers(\r\n        vertexBuffers: { [key: string]: Nullable<VertexBuffer> },\r\n        indexBuffer: Nullable<DataBuffer>,\r\n        effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseRenderTargetWrapper(rtWrapper: RenderTargetWrapper): void {\r\n        const index = this._renderTargetWrapperCache.indexOf(rtWrapper);\r\n        if (index !== -1) {\r\n            this._renderTargetWrapperCache.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Activates an effect, making it the current one (i.e. the one used for rendering)\r\n     * @param effect defines the effect to activate\r\n     */\r\n    public abstract enableEffect(effect: Nullable<Effect | DrawWrapper>): void;\r\n\r\n    /**\r\n     * Sets the type of faces to cull\r\n     * @param cullBackFaces true to cull back faces, false to cull front faces (if culling is enabled)\r\n     * @param force defines if states must be applied even if cache is up to date\r\n     */\r\n    public abstract setStateCullFaceType(cullBackFaces?: boolean, force?: boolean): void;\r\n\r\n    /**\r\n     * Set various states to the webGL context\r\n     * @param culling defines culling state: true to enable culling, false to disable it\r\n     * @param zOffset defines the value to apply to zOffset (0 by default)\r\n     * @param force defines if states must be applied even if cache is up to date\r\n     * @param reverseSide defines if culling must be reversed (CCW if false, CW if true)\r\n     * @param cullBackFaces true to cull back faces, false to cull front faces (if culling is enabled)\r\n     * @param stencil stencil states to set\r\n     * @param zOffsetUnits defines the value to apply to zOffsetUnits (0 by default)\r\n     */\r\n    public abstract setState(\r\n        culling: boolean,\r\n        zOffset?: number,\r\n        force?: boolean,\r\n        reverseSide?: boolean,\r\n        cullBackFaces?: boolean,\r\n        stencil?: IStencilState | IStencilStateProperties,\r\n        zOffsetUnits?: number\r\n    ): void;\r\n\r\n    /**\r\n     * Creates a new material context\r\n     * @returns the new context\r\n     */\r\n    public abstract createMaterialContext(): IMaterialContext | undefined;\r\n\r\n    /**\r\n     * Creates a new draw context\r\n     * @returns the new context\r\n     */\r\n    public abstract createDrawContext(): IDrawContext | undefined;\r\n\r\n    /**\r\n     * Create a new effect (used to store vertex/fragment shaders)\r\n     * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)\r\n     * @param attributesNamesOrOptions defines either a list of attribute names or an IEffectCreationOptions object\r\n     * @param uniformsNamesOrEngine defines either a list of uniform names or the engine to use\r\n     * @param samplers defines an array of string used to represent textures\r\n     * @param defines defines the string containing the defines to use to compile the shaders\r\n     * @param fallbacks defines the list of potential fallbacks to use if shader compilation fails\r\n     * @param onCompiled defines a function to call when the effect creation is successful\r\n     * @param onError defines a function to call when the effect creation has failed\r\n     * @param indexParameters defines an object containing the index values to use to compile shaders (like the maximum number of simultaneous lights)\r\n     * @param shaderLanguage the language the shader is written in (default: GLSL)\r\n     * @param extraInitializationsAsync additional async code to run before preparing the effect\r\n     * @returns the new Effect\r\n     */\r\n    public abstract createEffect(\r\n        baseName: string | (IShaderPath & { vertexToken?: string; fragmentToken?: string }),\r\n        attributesNamesOrOptions: string[] | IEffectCreationOptions,\r\n        uniformsNamesOrEngine: string[] | AbstractEngine,\r\n        samplers?: string[],\r\n        defines?: string,\r\n        fallbacks?: EffectFallbacks,\r\n        onCompiled?: Nullable<(effect: Effect) => void>,\r\n        onError?: Nullable<(effect: Effect, errors: string) => void>,\r\n        indexParameters?: any,\r\n        shaderLanguage?: ShaderLanguage,\r\n        extraInitializationsAsync?: () => Promise<void>\r\n    ): Effect;\r\n\r\n    /**\r\n     * Clear the current render buffer or the current render target (if any is set up)\r\n     * @param color defines the color to use\r\n     * @param backBuffer defines if the back buffer must be cleared\r\n     * @param depth defines if the depth buffer must be cleared\r\n     * @param stencil defines if the stencil buffer must be cleared\r\n     * @param stencilClearValue defines the value to use to clear the stencil buffer\r\n     */\r\n    public abstract clear(color: Nullable<IColor4Like>, backBuffer: boolean, depth: boolean, stencil?: boolean, stencilClearValue?: number): void;\r\n\r\n    /**\r\n     * Gets a boolean indicating that only power of 2 textures are supported\r\n     * Please note that you can still use non power of 2 textures but in this case the engine will forcefully convert them\r\n     */\r\n    public abstract get needPOTTextures(): boolean;\r\n\r\n    /**\r\n     * Creates a new index buffer\r\n     * @param indices defines the content of the index buffer\r\n     * @param _updatable defines if the index buffer must be updatable\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     * @returns a new buffer\r\n     */\r\n    public abstract createIndexBuffer(indices: IndicesArray, _updatable?: boolean, label?: string): DataBuffer;\r\n\r\n    /**\r\n     * Draw a list of unindexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public abstract drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void;\r\n\r\n    /**\r\n     * Force the engine to release all cached effects.\r\n     * This means that next effect compilation will have to be done completely even if a similar effect was already compiled\r\n     */\r\n    public abstract releaseEffects(): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _viewport(x: number, y: number, width: number, height: number): void;\r\n\r\n    /**\r\n     * Gets the current viewport\r\n     */\r\n    public get currentViewport(): Nullable<IViewportLike> {\r\n        return this._cachedViewport;\r\n    }\r\n\r\n    /**\r\n     * Set the WebGL's viewport\r\n     * @param viewport defines the viewport element to be used\r\n     * @param requiredWidth defines the width required for rendering. If not provided the rendering canvas' width is used\r\n     * @param requiredHeight defines the height required for rendering. If not provided the rendering canvas' height is used\r\n     */\r\n    public setViewport(viewport: IViewportLike, requiredWidth?: number, requiredHeight?: number): void {\r\n        const width = requiredWidth || this.getRenderWidth();\r\n        const height = requiredHeight || this.getRenderHeight();\r\n        const x = viewport.x || 0;\r\n        const y = viewport.y || 0;\r\n\r\n        this._cachedViewport = viewport;\r\n\r\n        this._viewport(x * width, y * height, width * viewport.width, height * viewport.height);\r\n    }\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param samplingMode defines the required sampling mode\r\n     * @param texture defines the texture to update\r\n     * @param generateMipMaps defines whether to generate mipmaps for the texture\r\n     */\r\n    public abstract updateTextureSamplingMode(samplingMode: number, texture: InternalTexture, generateMipMaps?: boolean): void;\r\n\r\n    /**\r\n     * Sets an array of texture to the webGL context\r\n     * @param channel defines the channel where the texture array must be set\r\n     * @param uniform defines the associated uniform location\r\n     * @param textures defines the array of textures to bind\r\n     * @param name name of the channel\r\n     */\r\n    public abstract setTextureArray(channel: number, uniform: Nullable<WebGLUniformLocation>, textures: ThinTexture[], name: string): void;\r\n\r\n    /** @internal */\r\n    public _transformTextureUrl: Nullable<(url: string) => string> = null;\r\n\r\n    /**\r\n     * Unbind all instance attributes\r\n     */\r\n    public abstract unbindInstanceAttributes(): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _getUseSRGBBuffer(useSRGBBuffer: boolean, noMipmap: boolean): boolean;\r\n\r\n    /**\r\n     * Create an image to use with canvas\r\n     * @returns IImage interface\r\n     */\r\n    public createCanvasImage(): IImage {\r\n        return document.createElement(\"img\");\r\n    }\r\n\r\n    /**\r\n     * Create a 2D path to use with canvas\r\n     * @returns IPath2D interface\r\n     * @param d SVG path string\r\n     */\r\n    public createCanvasPath2D(d?: string): IPath2D {\r\n        return new Path2D(d);\r\n    }\r\n\r\n    /**\r\n     * Returns a string describing the current engine\r\n     */\r\n    public get description(): string {\r\n        let description = this.name + this.version;\r\n\r\n        if (this._caps.parallelShaderCompile) {\r\n            description += \" - Parallel shader compilation\";\r\n        }\r\n\r\n        return description;\r\n    }\r\n\r\n    protected _createTextureBase(\r\n        url: Nullable<string>,\r\n        noMipmap: boolean,\r\n        invertY: boolean,\r\n        scene: Nullable<ISceneLike>,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<(texture: InternalTexture) => void> = null,\r\n        onError: Nullable<(message: string, exception: any) => void> = null,\r\n        prepareTexture: PrepareTextureFunction,\r\n        prepareTextureProcess: PrepareTextureProcessFunction,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        format: Nullable<number> = null,\r\n        forcedExtension: Nullable<string> = null,\r\n        mimeType?: string,\r\n        loaderOptions?: any,\r\n        useSRGBBuffer?: boolean\r\n    ): InternalTexture {\r\n        url = url || \"\";\r\n        const fromData = url.substring(0, 5) === \"data:\";\r\n        const fromBlob = url.substring(0, 5) === \"blob:\";\r\n        const isBase64 = fromData && url.indexOf(\";base64,\") !== -1;\r\n\r\n        const texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Url);\r\n\r\n        if (texture !== fallback) {\r\n            texture.label = url.substring(0, 60); // default label, can be overriden by the caller\r\n        }\r\n\r\n        const originalUrl = url;\r\n        if (this._transformTextureUrl && !isBase64 && !fallback && !buffer) {\r\n            url = this._transformTextureUrl(url);\r\n        }\r\n\r\n        if (originalUrl !== url) {\r\n            texture._originalUrl = originalUrl;\r\n        }\r\n\r\n        // establish the file extension, if possible\r\n        const lastDot = url.lastIndexOf(\".\");\r\n        let extension = forcedExtension ? forcedExtension : lastDot > -1 ? url.substring(lastDot).toLowerCase() : \"\";\r\n\r\n        // Remove query string\r\n        const queryStringIndex = extension.indexOf(\"?\");\r\n\r\n        if (queryStringIndex > -1) {\r\n            extension = extension.split(\"?\")[0];\r\n        }\r\n\r\n        const loaderPromise = AbstractEngine.GetCompatibleTextureLoader(extension, mimeType);\r\n\r\n        if (scene) {\r\n            scene.addPendingData(texture);\r\n        }\r\n        texture.url = url;\r\n        texture.generateMipMaps = !noMipmap;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture._useSRGBBuffer = this._getUseSRGBBuffer(!!useSRGBBuffer, noMipmap);\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            // Keep a link to the buffer only if we plan to handle context lost\r\n            texture._buffer = buffer;\r\n        }\r\n\r\n        let onLoadObserver: Nullable<Observer<InternalTexture>> = null;\r\n        if (onLoad && !fallback) {\r\n            onLoadObserver = texture.onLoadedObservable.add(onLoad);\r\n        }\r\n\r\n        if (!fallback) {\r\n            this._internalTexturesCache.push(texture);\r\n        }\r\n\r\n        const onInternalError = (message?: string, exception?: any) => {\r\n            if (scene) {\r\n                scene.removePendingData(texture);\r\n            }\r\n\r\n            if (url === originalUrl) {\r\n                if (onLoadObserver) {\r\n                    texture.onLoadedObservable.remove(onLoadObserver);\r\n                }\r\n\r\n                if (EngineStore.UseFallbackTexture && url !== EngineStore.FallbackTexture) {\r\n                    this._createTextureBase(\r\n                        EngineStore.FallbackTexture,\r\n                        noMipmap,\r\n                        texture.invertY,\r\n                        scene,\r\n                        samplingMode,\r\n                        null,\r\n                        onError,\r\n                        prepareTexture,\r\n                        prepareTextureProcess,\r\n                        buffer,\r\n                        texture\r\n                    );\r\n                }\r\n\r\n                message = (message || \"Unknown error\") + (EngineStore.UseFallbackTexture ? \" - Fallback texture was used\" : \"\");\r\n                texture.onErrorObservable.notifyObservers({ message, exception });\r\n                if (onError) {\r\n                    onError(message, exception);\r\n                }\r\n            } else {\r\n                // fall back to the original url if the transformed url fails to load\r\n                Logger.Warn(`Failed to load ${url}, falling back to ${originalUrl}`);\r\n                this._createTextureBase(\r\n                    originalUrl,\r\n                    noMipmap,\r\n                    texture.invertY,\r\n                    scene,\r\n                    samplingMode,\r\n                    onLoad,\r\n                    onError,\r\n                    prepareTexture,\r\n                    prepareTextureProcess,\r\n                    buffer,\r\n                    texture,\r\n                    format,\r\n                    forcedExtension,\r\n                    mimeType,\r\n                    loaderOptions,\r\n                    useSRGBBuffer\r\n                );\r\n            }\r\n        };\r\n\r\n        // processing for non-image formats\r\n        if (loaderPromise) {\r\n            const callbackAsync = async (data: ArrayBufferView) => {\r\n                const loader = await loaderPromise;\r\n                loader.loadData(\r\n                    data,\r\n                    texture,\r\n                    (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, loadFailed) => {\r\n                        if (loadFailed) {\r\n                            onInternalError(\"TextureLoader failed to load data\");\r\n                        } else {\r\n                            prepareTexture(\r\n                                texture,\r\n                                extension,\r\n                                scene,\r\n                                { width, height },\r\n                                texture.invertY,\r\n                                !loadMipmap,\r\n                                isCompressed,\r\n                                () => {\r\n                                    done();\r\n                                    return false;\r\n                                },\r\n                                samplingMode\r\n                            );\r\n                        }\r\n                    },\r\n                    loaderOptions\r\n                );\r\n            };\r\n\r\n            if (!buffer) {\r\n                this._loadFile(\r\n                    url,\r\n                    async (data) => {\r\n                        try {\r\n                            await callbackAsync(new Uint8Array(data as ArrayBuffer));\r\n                        } catch (reason) {\r\n                            onInternalError(\"Failed to parse texture data\", reason);\r\n                        }\r\n                    },\r\n                    undefined,\r\n                    scene ? scene.offlineProvider : undefined,\r\n                    true,\r\n                    (request?: IWebRequest, exception?: any) => {\r\n                        onInternalError(\"Unable to load \" + (request ? request.responseURL : url, exception));\r\n                    }\r\n                );\r\n            } else {\r\n                const processBufferAsync = async (data: ArrayBufferView) => {\r\n                    try {\r\n                        await callbackAsync(data);\r\n                    } catch (reason) {\r\n                        onInternalError(\"Failed to parse texture data\", reason);\r\n                    }\r\n                };\r\n                if (buffer instanceof ArrayBuffer) {\r\n                    void processBufferAsync(new Uint8Array(buffer));\r\n                } else if (ArrayBuffer.isView(buffer)) {\r\n                    void processBufferAsync(buffer);\r\n                } else {\r\n                    if (onError) {\r\n                        onError(\"Unable to load: only ArrayBuffer or ArrayBufferView is supported\", null);\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const onload = (img: HTMLImageElement | ImageBitmap) => {\r\n                if (fromBlob && !this._doNotHandleContextLost) {\r\n                    // We need to store the image if we need to rebuild the texture\r\n                    // in case of a webgl context lost\r\n                    texture._buffer = img;\r\n                }\r\n\r\n                prepareTexture(texture, extension, scene, img, texture.invertY, noMipmap, false, prepareTextureProcess, samplingMode);\r\n            };\r\n            // According to the WebGL spec section 6.10, ImageBitmaps must be inverted on creation.\r\n            // So, we pass imageOrientation to _FileToolsLoadImage() as it may create an ImageBitmap.\r\n\r\n            if (!fromData || isBase64) {\r\n                if (buffer && (typeof (<HTMLImageElement>buffer).decoding === \"string\" || (<ImageBitmap>buffer).close)) {\r\n                    onload(<HTMLImageElement>buffer);\r\n                } else {\r\n                    AbstractEngine._FileToolsLoadImage(\r\n                        url || \"\",\r\n                        onload,\r\n                        onInternalError,\r\n                        scene ? scene.offlineProvider : null,\r\n                        mimeType,\r\n                        texture.invertY && this._features.needsInvertingBitmap ? { imageOrientation: \"flipY\" } : undefined,\r\n                        this\r\n                    );\r\n                }\r\n            } else if (typeof buffer === \"string\" || buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer) || buffer instanceof Blob) {\r\n                AbstractEngine._FileToolsLoadImage(\r\n                    buffer,\r\n                    onload,\r\n                    onInternalError,\r\n                    scene ? scene.offlineProvider : null,\r\n                    mimeType,\r\n                    texture.invertY && this._features.needsInvertingBitmap ? { imageOrientation: \"flipY\" } : undefined,\r\n                    this\r\n                );\r\n            } else if (buffer) {\r\n                onload(buffer);\r\n            }\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Creates a new pipeline context\r\n     * @param shaderProcessingContext defines the shader processing context used during the processing if available\r\n     * @returns the new pipeline\r\n     */\r\n    public abstract createPipelineContext(shaderProcessingContext: Nullable<_IShaderProcessingContext>): IPipelineContext;\r\n\r\n    /**\r\n     * Inline functions in shader code that are marked to be inlined\r\n     * @param code code to inline\r\n     * @returns inlined code\r\n     */\r\n    public abstract inlineShaderCode(code: string): string;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the engine supports uniform buffers\r\n     */\r\n    public abstract get supportsUniformBuffers(): boolean;\r\n\r\n    /**\r\n     * Returns the version of the engine\r\n     */\r\n    public abstract get version(): number;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _releaseEffect(effect: Effect): void;\r\n\r\n    /**\r\n     * Bind a buffer to the current draw context\r\n     * @param buffer defines the buffer to bind\r\n     * @param _location not used in WebGPU\r\n     * @param name Name of the uniform variable to bind\r\n     */\r\n    public abstract bindUniformBufferBase(buffer: DataBuffer, _location: number, name: string): void;\r\n\r\n    /**\r\n     * Bind a specific block at a given index in a specific shader program\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param blockName defines the block name\r\n     * @param index defines the index where to bind the block\r\n     */\r\n    public abstract bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;\r\n\r\n    /** @internal */\r\n    public _uniformBuffers = new Array<UniformBuffer>();\r\n    /** @internal */\r\n    public _storageBuffers = new Array<StorageBuffer>();\r\n    protected _rebuildBuffers(): void {\r\n        // Uniforms\r\n        for (const uniformBuffer of this._uniformBuffers) {\r\n            uniformBuffer._rebuildAfterContextLost();\r\n        }\r\n    }\r\n\r\n    protected _highPrecisionShadersAllowed = true;\r\n    /** @internal */\r\n    public get _shouldUseHighPrecisionShader(): boolean {\r\n        return !!(this._caps.highPrecisionShaderSupported && this._highPrecisionShadersAllowed);\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _getShaderProcessingContext(shaderLanguage: ShaderLanguage, pureMode: boolean): Nullable<_IShaderProcessingContext>;\r\n\r\n    /**\r\n     * Gets host document\r\n     * @returns the host document object\r\n     */\r\n    public getHostDocument(): Nullable<Document> {\r\n        if (this._renderingCanvas && this._renderingCanvas.ownerDocument) {\r\n            return this._renderingCanvas.ownerDocument;\r\n        }\r\n\r\n        return IsDocumentAvailable() ? document : null;\r\n    }\r\n\r\n    // Lost context\r\n    /**\r\n     * Observable signaled when a context lost event is raised\r\n     */\r\n    public onContextLostObservable = new Observable<AbstractEngine>();\r\n    /**\r\n     * Observable signaled when a context restored event is raised\r\n     */\r\n    public onContextRestoredObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Gets the list of loaded textures\r\n     * @returns an array containing all loaded textures\r\n     */\r\n    public getLoadedTexturesCache(): InternalTexture[] {\r\n        return this._internalTexturesCache;\r\n    }\r\n\r\n    /**\r\n     * Clears the list of texture accessible through engine.\r\n     * This can help preventing texture load conflict due to name collision.\r\n     */\r\n    public clearInternalTexturesCache() {\r\n        this._internalTexturesCache.length = 0;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _releaseTexture(texture: InternalTexture): void;\r\n\r\n    /**\r\n     * Gets the object containing all engine capabilities\r\n     * @returns the EngineCapabilities object\r\n     */\r\n    public getCaps(): EngineCapabilities {\r\n        return this._caps;\r\n    }\r\n\r\n    /**\r\n     * Reset the texture cache to empty state\r\n     */\r\n    public resetTextureCache() {\r\n        for (const key in this._boundTexturesCache) {\r\n            if (!Object.prototype.hasOwnProperty.call(this._boundTexturesCache, key)) {\r\n                continue;\r\n            }\r\n            this._boundTexturesCache[key] = null;\r\n        }\r\n\r\n        this._currentTextureChannel = -1;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _name = \"\";\r\n\r\n    /**\r\n     * Gets or sets the name of the engine\r\n     */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    /**\r\n     * Returns the current npm package of the sdk\r\n     */\r\n    // Not mixed with Version for tooling purpose.\r\n    public static get NpmPackage(): string {\r\n        return \"babylonjs@9.28.0\";\r\n    }\r\n\r\n    /**\r\n     * Returns the current version of the framework\r\n     */\r\n    public static get Version(): string {\r\n        return \"9.28.0\";\r\n    }\r\n\r\n    /**\r\n     * The time (in milliseconds elapsed since the current page has been loaded) when the engine was initialized\r\n     */\r\n    public readonly startTime: number;\r\n\r\n    /** @internal */\r\n    protected _audioContext: Nullable<AudioContext>;\r\n    /** @internal */\r\n    protected _audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode>;\r\n    /**\r\n     * Gets the HTML canvas attached with the current webGL context\r\n     * @returns a HTML canvas\r\n     */\r\n    public getRenderingCanvas(): Nullable<HTMLCanvasElement> {\r\n        return this._renderingCanvas;\r\n    }\r\n\r\n    /**\r\n     * Gets the audio context specified in engine initialization options\r\n     * @deprecated please use AudioEngineV2 instead\r\n     * @returns an Audio Context\r\n     */\r\n    public getAudioContext(): Nullable<AudioContext> {\r\n        return this._audioContext;\r\n    }\r\n\r\n    /**\r\n     * Gets the audio destination specified in engine initialization options\r\n     * @deprecated please use AudioEngineV2 instead\r\n     * @returns an audio destination node\r\n     */\r\n    public getAudioDestination(): Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode> {\r\n        return this._audioDestination;\r\n    }\r\n\r\n    /**\r\n     * Defines whether the engine has been created with the premultipliedAlpha option on or not.\r\n     */\r\n    public premultipliedAlpha: boolean = true;\r\n\r\n    /**\r\n     * If set to true zooming in and out in the browser will rescale the hardware-scaling correctly.\r\n     */\r\n    public adaptToDeviceRatio: boolean = false;\r\n\r\n    /** @internal */\r\n    protected _lastDevicePixelRatio: number = 1.0;\r\n\r\n    /** @internal */\r\n    public _hardwareScalingLevel: number;\r\n\r\n    /**\r\n     * Defines the hardware scaling level.\r\n     * By default the hardware scaling level is computed from the window device ratio.\r\n     * if level = 1 then the engine will render at the exact resolution of the canvas. If level = 0.5 then the engine will render at twice the size of the canvas.\r\n     * @param level defines the level to use\r\n     */\r\n    public setHardwareScalingLevel(level: number): void {\r\n        this._hardwareScalingLevel = level;\r\n        this.resize();\r\n    }\r\n\r\n    /**\r\n     * Gets the current hardware scaling level.\r\n     * By default the hardware scaling level is computed from the window device ratio.\r\n     * if level = 1 then the engine will render at the exact resolution of the canvas. If level = 0.5 then the engine will render at twice the size of the canvas.\r\n     * @returns a number indicating the current hardware scaling level\r\n     */\r\n    public getHardwareScalingLevel(): number {\r\n        return this._hardwareScalingLevel;\r\n    }\r\n\r\n    /** @internal */\r\n    public _doNotHandleContextLost = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if resources should be retained to be able to handle context lost events\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#handling-webgl-context-lost\r\n     */\r\n    public get doNotHandleContextLost(): boolean {\r\n        return this._doNotHandleContextLost;\r\n    }\r\n\r\n    public set doNotHandleContextLost(value: boolean) {\r\n        this._doNotHandleContextLost = value;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _isStencilEnable: boolean;\r\n\r\n    /**\r\n     * Returns true if the stencil buffer has been enabled through the creation option of the context.\r\n     */\r\n    public get isStencilEnable(): boolean {\r\n        return this._isStencilEnable;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _creationOptions: AbstractEngineOptions;\r\n\r\n    /**\r\n     * Gets the options used for engine creation\r\n     * NOTE that modifying the object after engine creation will have no effect\r\n     * @returns EngineOptions object\r\n     */\r\n    public getCreationOptions() {\r\n        return this._creationOptions;\r\n    }\r\n\r\n    /**\r\n     * Creates a new engine\r\n     * @param antialias defines whether anti-aliasing should be enabled. If undefined, it means that the underlying engine is free to enable it or not\r\n     * @param options defines further options to be sent to the creation context\r\n     * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)\r\n     */\r\n    constructor(antialias: boolean | undefined, options: AbstractEngineOptions, adaptToDeviceRatio?: boolean) {\r\n        EngineStore.Instances.push(this);\r\n        this.startTime = PrecisionDate.Now;\r\n\r\n        this._stencilStateComposer.stencilGlobal = this._stencilState;\r\n\r\n        // LargeWorldRendering set to true will set high precision matrix, regardless of useHighPrecisionMatrix value\r\n        // It will also set all scenes to use floatingOriginMode upon their creation\r\n        PerformanceConfigurator.SetMatrixPrecision(!!options.useLargeWorldRendering || !!options.useHighPrecisionMatrix);\r\n\r\n        if (IsNavigatorAvailable() && navigator.userAgent) {\r\n            // Detect if we are running on a faulty buggy OS.\r\n            this._badOS = /iPad/i.test(navigator.userAgent) || /iPhone/i.test(navigator.userAgent);\r\n\r\n            // Detect if we are running on a faulty buggy desktop OS.\r\n            this._badDesktopOS = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\r\n        }\r\n\r\n        options.antialias = antialias ?? options.antialias;\r\n        options.deterministicLockstep = options.deterministicLockstep ?? false;\r\n        options.lockstepMaxSteps = options.lockstepMaxSteps ?? 4;\r\n        options.timeStep = options.timeStep ?? 1 / 60;\r\n        options.stencil = options.stencil ?? true;\r\n\r\n        this._audioContext = options.audioEngineOptions?.audioContext ?? null;\r\n        this._audioDestination = options.audioEngineOptions?.audioDestination ?? null;\r\n        this.premultipliedAlpha = options.premultipliedAlpha ?? true;\r\n        this._doNotHandleContextLost = !!options.doNotHandleContextLost;\r\n        this._isStencilEnable = options.stencil ? true : false;\r\n        this.useExactSrgbConversions = options.useExactSrgbConversions ?? false;\r\n        this.canvasTabIndex = options.canvasTabIndex ?? this.canvasTabIndex;\r\n\r\n        const devicePixelRatio = IsWindowObjectExist() ? window.devicePixelRatio || 1.0 : 1.0;\r\n\r\n        const limitDeviceRatio = options.limitDeviceRatio || devicePixelRatio;\r\n        // Viewport\r\n        adaptToDeviceRatio = adaptToDeviceRatio || options.adaptToDeviceRatio || false;\r\n        // Save this off for use in resize().\r\n        this.adaptToDeviceRatio = adaptToDeviceRatio;\r\n        this._hardwareScalingLevel = adaptToDeviceRatio ? 1.0 / Math.min(limitDeviceRatio, devicePixelRatio) : 1.0;\r\n        this._lastDevicePixelRatio = devicePixelRatio;\r\n\r\n        this._creationOptions = options;\r\n    }\r\n\r\n    /**\r\n     * Resize the view according to the canvas' size\r\n     * @param forceSetSize true to force setting the sizes of the underlying canvas\r\n     */\r\n    public resize(forceSetSize = false): void {\r\n        let width: number;\r\n        let height: number;\r\n\r\n        // Re-query hardware scaling level to handle zoomed-in resizing.\r\n        if (this.adaptToDeviceRatio) {\r\n            const devicePixelRatio = IsWindowObjectExist() ? window.devicePixelRatio || 1.0 : 1.0;\r\n            const changeRatio = this._lastDevicePixelRatio / devicePixelRatio;\r\n            this._lastDevicePixelRatio = devicePixelRatio;\r\n            this._hardwareScalingLevel *= changeRatio;\r\n        }\r\n\r\n        if (IsWindowObjectExist() && IsDocumentAvailable()) {\r\n            // make sure it is a Node object, and is a part of the document.\r\n            if (this._renderingCanvas) {\r\n                const boundingRect = this._renderingCanvas.getBoundingClientRect?.();\r\n                width = this._renderingCanvas.clientWidth || boundingRect?.width || this._renderingCanvas.width * this._hardwareScalingLevel || 100;\r\n                height = this._renderingCanvas.clientHeight || boundingRect?.height || this._renderingCanvas.height * this._hardwareScalingLevel || 100;\r\n            } else {\r\n                width = window.innerWidth;\r\n                height = window.innerHeight;\r\n            }\r\n        } else {\r\n            width = this._renderingCanvas ? this._renderingCanvas.width : 100;\r\n            height = this._renderingCanvas ? this._renderingCanvas.height : 100;\r\n        }\r\n\r\n        this.setSize(width / this._hardwareScalingLevel, height / this._hardwareScalingLevel, forceSetSize);\r\n    }\r\n\r\n    /**\r\n     * Force a specific size of the canvas\r\n     * @param width defines the new canvas' width\r\n     * @param height defines the new canvas' height\r\n     * @param forceSetSize true to force setting the sizes of the underlying canvas\r\n     * @returns true if the size was changed\r\n     */\r\n    public setSize(width: number, height: number, forceSetSize = false): boolean {\r\n        if (!this._renderingCanvas) {\r\n            return false;\r\n        }\r\n\r\n        width = width | 0;\r\n        height = height | 0;\r\n\r\n        if (!forceSetSize && this._renderingCanvas.width === width && this._renderingCanvas.height === height) {\r\n            return false;\r\n        }\r\n\r\n        this._renderingCanvas.width = width;\r\n        this._renderingCanvas.height = height;\r\n\r\n        if (this.scenes) {\r\n            for (let index = 0; index < this.scenes.length; index++) {\r\n                const scene = this.scenes[index];\r\n\r\n                for (let camIndex = 0; camIndex < scene.cameras.length; camIndex++) {\r\n                    const cam = scene.cameras[camIndex];\r\n\r\n                    cam._currentRenderId = 0;\r\n                }\r\n            }\r\n\r\n            if (this.onResizeObservable.hasObservers()) {\r\n                this.onResizeObservable.notifyObservers(this);\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public abstract _releaseBuffer(buffer: DataBuffer): boolean;\r\n\r\n    /**\r\n     * Create a dynamic uniform buffer\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     * @param elements defines the content of the uniform buffer\r\n     * @param label defines a name for the buffer (for debugging purpose)\r\n     * @returns the webGL uniform buffer\r\n     */\r\n    public abstract createDynamicUniformBuffer(elements: FloatArray, label?: string): DataBuffer;\r\n\r\n    /**\r\n     * Create an uniform buffer\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     * @param elements defines the content of the uniform buffer\r\n     * @param label defines a name for the buffer (for debugging purpose)\r\n     * @returns the webGL uniform buffer\r\n     */\r\n    public abstract createUniformBuffer(elements: FloatArray, label?: string): DataBuffer;\r\n\r\n    /**\r\n     * Update an existing uniform buffer\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     * @param uniformBuffer defines the target uniform buffer\r\n     * @param elements defines the content to update\r\n     * @param offset defines the offset in the uniform buffer where update should start\r\n     * @param count defines the size of the data to update\r\n     */\r\n    public abstract updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void;\r\n\r\n    /**\r\n     * Creates a dynamic vertex buffer\r\n     * @param data the data for the dynamic vertex buffer\r\n     * @param _label defines the label of the buffer (for debug purpose)\r\n     * @returns the new WebGL dynamic buffer\r\n     */\r\n    public abstract createDynamicVertexBuffer(data: DataArray | number, _label?: string): DataBuffer;\r\n\r\n    /**\r\n     * Creates a vertex buffer\r\n     * @param data the data or size for the vertex buffer\r\n     * @param _updatable whether the buffer should be created as updatable\r\n     * @param _label defines the label of the buffer (for debug purpose)\r\n     * @returns the new WebGL static buffer\r\n     */\r\n    public abstract createVertexBuffer(data: DataArray | number, _updatable?: boolean, _label?: string): DataBuffer;\r\n\r\n    /**\r\n     * Update the dimensions of a texture\r\n     * @param texture texture to update\r\n     * @param width new width of the texture\r\n     * @param height new height of the texture\r\n     * @param depth new depth of the texture\r\n     */\r\n    public abstract updateTextureDimensions(texture: InternalTexture, width: number, height: number, depth: number): void;\r\n\r\n    /**\r\n     * Usually called from Texture.ts.\r\n     * Passed information to create a WebGLTexture\r\n     * @param url defines a value which contains one of the following:\r\n     * * A conventional http URL, e.g. 'http://...' or 'file://...'\r\n     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'\r\n     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'\r\n     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file\r\n     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)\r\n     * @param scene needed for loading to the correct scene\r\n     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)\r\n     * @param onLoad optional callback to be called upon successful completion\r\n     * @param onError optional callback to be called upon failure\r\n     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob\r\n     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities\r\n     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @param mimeType defines an optional mime type\r\n     * @param loaderOptions options to be passed to the loader\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns a InternalTexture for assignment back into BABYLON.Texture\r\n     */\r\n    public abstract createTexture(\r\n        url: Nullable<string>,\r\n        noMipmap: boolean,\r\n        invertY: boolean,\r\n        scene: Nullable<ISceneLike>,\r\n        samplingMode?: number,\r\n        onLoad?: Nullable<(texture: InternalTexture) => void>,\r\n        onError?: Nullable<(message: string, exception: any) => void>,\r\n        buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap>,\r\n        fallback?: Nullable<InternalTexture>,\r\n        format?: Nullable<number>,\r\n        forcedExtension?: Nullable<string>,\r\n        mimeType?: string,\r\n        loaderOptions?: any,\r\n        creationFlags?: number,\r\n        useSRGBBuffer?: boolean\r\n    ): InternalTexture;\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a raw texture\r\n     * @param data defines the data to store in the texture\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @param format defines the format of the data\r\n     * @param generateMipMaps defines if the engine should generate the mip levels\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)\r\n     * @param compression defines the compression used (null by default)\r\n     * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_BYTE by default)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @param mipLevelCount defines the number of mip levels to allocate for the texture\r\n     * @returns the raw texture inside an InternalTexture\r\n     */\r\n    public createRawTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression?: Nullable<string>,\r\n        type?: number,\r\n        creationFlags?: number,\r\n        useSRGBBuffer?: boolean,\r\n        mipLevelCount?: number\r\n    ): InternalTexture {\r\n        throw _WarnImport(\"engine.rawTexture\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a new raw cube texture\r\n     * @param data defines the array of data to use to create each face\r\n     * @param size defines the size of the textures\r\n     * @param format defines the format of the data\r\n     * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_BYTE)\r\n     * @param generateMipMaps  defines if the engine should generate the mip levels\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)\r\n     * @param compression defines the compression used (null by default)\r\n     * @returns the cube texture as an InternalTexture\r\n     */\r\n    public createRawCubeTexture(\r\n        data: Nullable<ArrayBufferView[]>,\r\n        size: number,\r\n        format: number,\r\n        type: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression?: Nullable<string>\r\n    ): InternalTexture {\r\n        throw _WarnImport(\"engine.rawTexture\");\r\n    }\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a new raw 3D texture\r\n     * @param data defines the data used to create the texture\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @param depth defines the depth of the texture\r\n     * @param format defines the format of the texture\r\n     * @param generateMipMaps defines if the engine must generate mip levels\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)\r\n     * @param compression defines the compressed used (can be null)\r\n     * @param textureType defines the compressed used (can be null)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @returns a new raw 3D texture (stored in an InternalTexture)\r\n     */\r\n    public createRawTexture3D(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression?: Nullable<string>,\r\n        textureType?: number,\r\n        creationFlags?: number\r\n    ): InternalTexture {\r\n        throw _WarnImport(\"engine.rawTexture\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a new raw 2D array texture\r\n     * @param data defines the data used to create the texture\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @param depth defines the number of layers of the texture\r\n     * @param format defines the format of the texture\r\n     * @param generateMipMaps defines if the engine must generate mip levels\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)\r\n     * @param compression defines the compressed used (can be null)\r\n     * @param textureType defines the compressed used (can be null)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param mipLevelCount defines the number of mip levels to allocate for the texture\r\n     * @returns a new raw 2D array texture (stored in an InternalTexture)\r\n     */\r\n    public createRawTexture2DArray(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression?: Nullable<string>,\r\n        textureType?: number,\r\n        creationFlags?: number,\r\n        mipLevelCount?: number\r\n    ): InternalTexture {\r\n        throw _WarnImport(\"engine.rawTexture\");\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if back faces must be culled. If false, front faces are culled instead (true by default)\r\n     * If non null, this takes precedence over the value from the material\r\n     */\r\n    public cullBackFaces: Nullable<boolean> = null;\r\n\r\n    /**\r\n     * Gets the current render width\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render width\r\n     */\r\n    public abstract getRenderWidth(useScreen?: boolean): number;\r\n\r\n    /**\r\n     * Gets the current render height\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render height\r\n     */\r\n    public abstract getRenderHeight(useScreen?: boolean): number;\r\n\r\n    /**\r\n     * Shared initialization across engines types.\r\n     * @param canvas The canvas associated with this instance of the engine.\r\n     */\r\n    protected _sharedInit(canvas: HTMLCanvasElement) {\r\n        this._renderingCanvas = canvas;\r\n    }\r\n\r\n    private _checkForMobile: () => void;\r\n\r\n    protected _setupMobileChecks(): void {\r\n        if (!(navigator && navigator.userAgent)) {\r\n            return;\r\n        }\r\n\r\n        // Function to check if running on mobile device\r\n        this._checkForMobile = () => {\r\n            const currentUa = navigator.userAgent;\r\n            this.hostInformation.isMobile =\r\n                currentUa.indexOf(\"Mobile\") !== -1 ||\r\n                // Needed for iOS 13+ detection on iPad (inspired by solution from https://stackoverflow.com/questions/9038625/detect-if-device-is-ios)\r\n                (currentUa.indexOf(\"Mac\") !== -1 && IsDocumentAvailable() && \"ontouchend\" in document);\r\n        };\r\n\r\n        // Set initial isMobile value\r\n        this._checkForMobile();\r\n\r\n        // Set up event listener to check when window is resized (used to get emulator activation to work properly)\r\n        if (IsWindowObjectExist()) {\r\n            window.addEventListener(\"resize\", this._checkForMobile);\r\n        }\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    /** @internal */\r\n    public static _RenderPassIdCounter = 0;\r\n\r\n    /** @internal */\r\n    public _renderPassNames: string[] = [\"main\"];\r\n\r\n    /** @internal */\r\n    public _onReleaseRenderPassObservable: Nullable<Observable<number>> = null;\r\n\r\n    /** @internal */\r\n    public abstract _createHardwareTexture(): IHardwareTextureWrapper;\r\n\r\n    /**\r\n     * creates and returns a new video element\r\n     * @param constraints video constraints\r\n     * @returns video element\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public createVideoElement(constraints: MediaTrackConstraints): any {\r\n        return document.createElement(\"video\");\r\n    }\r\n\r\n    // FPS\r\n    protected _fps = 60;\r\n    protected _deltaTime = 0;\r\n\r\n    /** @internal */\r\n    public _drawCalls: PerfCounter;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _reportDrawCall(numDrawCalls = 1) {\r\n        this._drawCalls?.addCount(numDrawCalls, false);\r\n    }\r\n    /**\r\n     * Gets the current framerate\r\n     * @returns a number representing the framerate\r\n     */\r\n    public getFps(): number {\r\n        return this._fps;\r\n    }\r\n\r\n    /**\r\n     * Gets the time spent between current and previous frame\r\n     * @returns a number representing the delta time in ms\r\n     */\r\n    public getDeltaTime(): number {\r\n        return this._deltaTime;\r\n    }\r\n\r\n    // Deterministic lockstepMaxSteps\r\n    /** @internal */\r\n    public _deterministicLockstep: boolean = false;\r\n    /** @internal */\r\n    public _lockstepMaxSteps: number = 4;\r\n    /** @internal */\r\n    public _timeStep: number = 1 / 60;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the engine is running in deterministic lock step mode\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @returns true if engine is in deterministic lock step mode\r\n     */\r\n    public isDeterministicLockStep(): boolean {\r\n        return this._deterministicLockstep;\r\n    }\r\n\r\n    /**\r\n     * Gets the max steps when engine is running in deterministic lock step\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @returns the max steps\r\n     */\r\n    public getLockstepMaxSteps(): number {\r\n        return this._lockstepMaxSteps;\r\n    }\r\n\r\n    /**\r\n     * Returns the time in ms between steps when using deterministic lock step.\r\n     * @returns time step in (ms)\r\n     */\r\n    public getTimeStep(): number {\r\n        return this._timeStep * 1000;\r\n    }\r\n\r\n    /**\r\n     * Engine abstraction for loading and creating an image bitmap from a given source string.\r\n     * @param imageSource source to load the image from.\r\n     * @param options An object that sets options for the image's extraction.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public _createImageBitmapFromSource(imageSource: string, options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n        throw new Error(\"createImageBitmapFromSource is not implemented\");\r\n    }\r\n\r\n    /**\r\n     * Engine abstraction for createImageBitmap\r\n     * @param image source for image\r\n     * @param options An object that sets options for the image's extraction.\r\n     * @returns ImageBitmap\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n        return createImageBitmap(image, options);\r\n    }\r\n\r\n    /**\r\n     * Resize an image and returns the image data as an uint8array\r\n     * @param image image to resize\r\n     * @param bufferWidth destination buffer width\r\n     * @param bufferHeight destination buffer height\r\n     */\r\n    public resizeImageBitmap(image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n        throw new Error(\"resizeImageBitmap is not implemented\");\r\n    }\r\n\r\n    /**\r\n     * Get the current error code of the webGL context\r\n     * @returns the error code\r\n     */\r\n    public abstract getError(): number;\r\n\r\n    /**\r\n     * Get Font size information\r\n     * @param font font name\r\n     */\r\n    public getFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n        throw new Error(\"getFontOffset is not implemented\");\r\n    }\r\n\r\n    protected static _CreateCanvas(width: number, height: number): ICanvas {\r\n        if (typeof document === \"undefined\") {\r\n            return <ICanvas>(<any>new OffscreenCanvas(width, height));\r\n        }\r\n        const canvas = <ICanvas>(<any>document.createElement(\"canvas\"));\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        return canvas;\r\n    }\r\n\r\n    /**\r\n     * Create a canvas. This method is overridden by other engines\r\n     * @param width width\r\n     * @param height height\r\n     * @returns ICanvas interface\r\n     */\r\n    public createCanvas(width: number, height: number): ICanvas {\r\n        return AbstractEngine._CreateCanvas(width, height);\r\n    }\r\n\r\n    /**\r\n     * Loads an image as an HTMLImageElement.\r\n     * @param input url string, ArrayBuffer, or Blob to load\r\n     * @param onLoad callback called when the image successfully loads\r\n     * @param onError callback called when the image fails to load\r\n     * @param offlineProvider offline provider for caching\r\n     * @param mimeType optional mime type\r\n     * @param imageBitmapOptions optional the options to use when creating an ImageBitmap\r\n     * @param engine the engine instance to use\r\n     * @returns the HTMLImageElement of the loaded image\r\n     * @internal\r\n     */\r\n    public static _FileToolsLoadImage(\r\n        input: string | ArrayBuffer | ArrayBufferView | Blob,\r\n        onLoad: (img: HTMLImageElement | ImageBitmap) => void,\r\n        onError: (message?: string, exception?: any) => void,\r\n        offlineProvider: Nullable<IOfflineProvider>,\r\n        mimeType?: string,\r\n        imageBitmapOptions?: ImageBitmapOptions,\r\n        engine?: AbstractEngine\r\n    ): Nullable<HTMLImageElement> {\r\n        if (!EngineFunctionContext.loadImage) {\r\n            // The fileTools side effect was never imported, so no loader is registered.\r\n            throw _WarnImport(\"FileTools\");\r\n        }\r\n        return EngineFunctionContext.loadImage(input, onLoad, onError, offlineProvider, mimeType, imageBitmapOptions, engine);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _loadFile(\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (data: any) => void,\r\n        offlineProvider?: Nullable<IOfflineProvider>,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: IWebRequest, exception?: any) => void\r\n    ): IFileRequest {\r\n        const request = _LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);\r\n        this._activeRequests.push(request);\r\n        request.onCompleteObservable.add(() => {\r\n            const index = this._activeRequests.indexOf(request);\r\n            if (index !== -1) {\r\n                this._activeRequests.splice(index, 1);\r\n            }\r\n        });\r\n        return request;\r\n    }\r\n\r\n    /**\r\n     * Loads a file from a url\r\n     * @param url url to load\r\n     * @param onSuccess callback called when the file successfully loads\r\n     * @param onProgress callback called while file is loading (if the server supports this mode)\r\n     * @param offlineProvider defines the offline provider for caching\r\n     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer\r\n     * @param onError callback called when the file fails to load\r\n     * @returns a file request object\r\n     * @internal\r\n     */\r\n    public static _FileToolsLoadFile(\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent) => void,\r\n        offlineProvider?: IOfflineProvider,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void\r\n    ): IFileRequest {\r\n        if (EngineFunctionContext.loadFile) {\r\n            return EngineFunctionContext.loadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);\r\n        }\r\n        // The fileTools side effect was never imported, so no loader is registered.\r\n        throw _WarnImport(\"FileTools\");\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the engine is disposed.\r\n     */\r\n    public readonly onDisposeObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * An event triggered when a global cleanup of all effects is required\r\n     */\r\n    public readonly onReleaseEffectsObservable = new Observable<AbstractEngine>();\r\n\r\n    /**\r\n     * Dispose and release all associated resources\r\n     */\r\n    public dispose(): void {\r\n        this.releaseEffects();\r\n\r\n        this._isDisposed = true;\r\n        this.stopRenderLoop();\r\n\r\n        // Empty texture\r\n        if (this._emptyTexture) {\r\n            this._releaseTexture(this._emptyTexture);\r\n            this._emptyTexture = null;\r\n        }\r\n        if (this._emptyCubeTexture) {\r\n            this._releaseTexture(this._emptyCubeTexture);\r\n            this._emptyCubeTexture = null;\r\n        }\r\n\r\n        this._renderingCanvas = null;\r\n\r\n        // Clear observables\r\n        if (this.onBeforeTextureInitObservable) {\r\n            this.onBeforeTextureInitObservable.clear();\r\n        }\r\n\r\n        // Release postProcesses\r\n        while (this.postProcesses.length) {\r\n            this.postProcesses[0].dispose();\r\n        }\r\n\r\n        // Release scenes\r\n        while (this.scenes.length) {\r\n            this.scenes[0].dispose();\r\n        }\r\n\r\n        while (this._virtualScenes.length) {\r\n            this._virtualScenes[0].dispose();\r\n        }\r\n\r\n        // Release effects\r\n        this.releaseComputeEffects?.();\r\n\r\n        Effect.ResetCache();\r\n\r\n        // Abort active requests\r\n        for (const request of this._activeRequests) {\r\n            request.abort();\r\n        }\r\n\r\n        this._boundRenderFunction = null;\r\n\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n\r\n        this.onResizeObservable.clear();\r\n        this.onCanvasBlurObservable.clear();\r\n        this.onCanvasFocusObservable.clear();\r\n        this.onCanvasPointerOutObservable.clear();\r\n        this.onNewSceneAddedObservable.clear();\r\n        this.onEffectErrorObservable.clear();\r\n\r\n        if (IsWindowObjectExist()) {\r\n            window.removeEventListener(\"resize\", this._checkForMobile);\r\n        }\r\n\r\n        // Remove from Instances\r\n        const index = EngineStore.Instances.indexOf(this);\r\n\r\n        if (index >= 0) {\r\n            EngineStore.Instances.splice(index, 1);\r\n        }\r\n\r\n        // no more engines left in the engine store? Notify!\r\n        if (!EngineStore.Instances.length) {\r\n            EngineStore.OnEnginesDisposedObservable.notifyObservers(this);\r\n            EngineStore.OnEnginesDisposedObservable.clear();\r\n        }\r\n\r\n        // Observables\r\n        this.onBeginFrameObservable.clear();\r\n        this.onEndFrameObservable.clear();\r\n        this._onReleaseRenderPassObservable?.clear();\r\n        this._onReleaseRenderPassObservable = null;\r\n    }\r\n\r\n    /**\r\n     * Method called to create the default rescale post process on each engine.\r\n     */\r\n    public static _RescalePostProcessFactory: Nullable<(engine: AbstractEngine) => PostProcess> = null;\r\n\r\n    /**\r\n     * Method called to create the default loading screen.\r\n     * This can be overridden in your own app.\r\n     * @param canvas The rendering canvas element\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static DefaultLoadingScreenFactory(canvas: HTMLCanvasElement): ILoadingScreen {\r\n        throw _WarnImport(\"LoadingScreen\");\r\n    }\r\n\r\n    /**\r\n     * Gets the audio engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n     * @deprecated please use AudioEngineV2 instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static audioEngine: Nullable<IAudioEngine>;\r\n\r\n    /**\r\n     * Default AudioEngine factory responsible of creating the Audio Engine.\r\n     * By default, this will create a BabylonJS Audio Engine if the workload has been embedded.\r\n     * @deprecated please use AudioEngineV2 instead\r\n     */\r\n    public static AudioEngineFactory: (\r\n        hostElement: Nullable<HTMLElement>,\r\n        audioContext: Nullable<AudioContext>,\r\n        audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode>\r\n    ) => IAudioEngine;\r\n\r\n    /**\r\n     * Default offline support factory responsible of creating a tool used to store data locally.\r\n     * By default, this will create a Database object if the workload has been embedded.\r\n     */\r\n    public static OfflineProviderFactory: (urlToScene: string, callbackManifestChecked: (checked: boolean) => any, disableManifestCheck: boolean) => IOfflineProvider;\r\n\r\n    /**\r\n     * Will flag all materials in all scenes in all engines as dirty to trigger new shader compilation\r\n     * @param flag defines which part of the materials must be marked as dirty\r\n     * @param predicate defines a predicate used to filter which materials should be affected\r\n     */\r\n    public static MarkAllMaterialsAsDirty(flag: number, predicate?: (mat: Material) => boolean): void {\r\n        for (let engineIndex = 0; engineIndex < EngineStore.Instances.length; engineIndex++) {\r\n            const engine = EngineStore.Instances[engineIndex];\r\n\r\n            for (let sceneIndex = 0; sceneIndex < engine.scenes.length; sceneIndex++) {\r\n                engine.scenes[sceneIndex].markAllMaterialsAsDirty(flag, predicate);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Updatable statics so stick with vars here\r\n\r\n    /**\r\n     * Gets or sets the epsilon value used by collision engine\r\n     */\r\n    public static CollisionsEpsilon = 0.001;\r\n\r\n    /**\r\n     * Queue a new function into the requested animation frame pool (ie. this function will be executed by the browser (or the javascript engine) for the next frame)\r\n     * @param func - the function to be called\r\n     * @param requester - the object that will request the next frame. Falls back to window.\r\n     * @returns frame number\r\n     */\r\n    public static QueueNewFrame: (func: () => void, requester?: any) => number = QueueNewFrame;\r\n\r\n    /**\r\n     * @internal\r\n     * Function used to get the correct texture loader for a specific extension.\r\n     * @param extension defines the file extension of the file being loaded\r\n     * @param mimeType defines the optional mime type of the file being loaded\r\n     * @returns the IInternalTextureLoader or null if it wasn't found\r\n     */\r\n    public static GetCompatibleTextureLoader(_extension: string, _mimeType?: string): Nullable<Promise<IInternalTextureLoader>> {\r\n        return null;\r\n    }\r\n}\r\n","import { type DrawWrapper } from \"./drawWrapper\";\r\nimport { type Effect } from \"./effect\";\r\n\r\n/**\r\n * Detect if the effect is a DrawWrapper\r\n * @param effect defines the entity to test\r\n * @returns if the entity is a DrawWrapper\r\n */\r\nexport function IsWrapper(effect: Effect | DrawWrapper): effect is DrawWrapper {\r\n    return (effect as Effect).getPipelineContext === undefined;\r\n}\r\n","import { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IShaderProcessor } from \"../Processors/iShaderProcessor\";\r\nimport { type _IShaderProcessingContext } from \"../Processors/shaderProcessingOptions\";\r\n\r\n/** @internal */\r\nexport class WebGLShaderProcessor implements IShaderProcessor {\r\n    public shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    public postProcessor(\r\n        code: string,\r\n        defines: string[],\r\n        isFragment: boolean,\r\n        processingContext: Nullable<_IShaderProcessingContext>,\r\n        parameters: { [key: string]: number | string | boolean | undefined }\r\n    ) {\r\n        // Remove extensions\r\n        if (parameters.drawBuffersExtensionDisabled) {\r\n            // even if enclosed in #if/#endif, IE11 does parse the #extension declaration, so we need to remove it altogether\r\n            const regex = /#extension.+GL_EXT_draw_buffers.+(enable|require)/g;\r\n            code = code.replace(regex, \"\");\r\n        }\r\n\r\n        return code;\r\n    }\r\n}\r\n","import { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\nimport { type IShaderProcessor } from \"../Processors/iShaderProcessor\";\r\n\r\nconst VaryingRegex = /(flat\\s)?\\s*varying\\s*.*/;\r\n\r\n/** @internal */\r\nexport class WebGL2ShaderProcessor implements IShaderProcessor {\r\n    public shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    public attributeProcessor(attribute: string) {\r\n        return attribute.replace(\"attribute\", \"in\");\r\n    }\r\n\r\n    public varyingCheck(varying: string, _isFragment: boolean) {\r\n        return VaryingRegex.test(varying);\r\n    }\r\n\r\n    public varyingProcessor(varying: string, isFragment: boolean) {\r\n        return varying.replace(\"varying\", isFragment ? \"in\" : \"out\");\r\n    }\r\n\r\n    public postProcessor(code: string, defines: string[], isFragment: boolean) {\r\n        const hasDrawBuffersExtension = code.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;\r\n\r\n        // Remove extensions\r\n        const regex = /#extension.+(GL_OVR_multiview2|GL_OES_standard_derivatives|GL_EXT_shader_texture_lod|GL_EXT_frag_depth|GL_EXT_draw_buffers).+(enable|require)/g;\r\n        code = code.replace(regex, \"\");\r\n\r\n        // Replace instructions\r\n        code = code.replace(/texture2D\\s*\\(/g, \"texture(\");\r\n        if (isFragment) {\r\n            const hasOutput = code.search(/layout *\\(location *= *0\\) *out/g) !== -1;\r\n            const hasDualSourceBlending = defines.indexOf(\"#define DUAL_SOURCE_BLENDING\") !== -1;\r\n            const outputDeclaration = hasDualSourceBlending\r\n                ? \"layout(location = 0, index = 0) out vec4 glFragColor;\\nlayout(location = 0, index = 1) out vec4 glFragColor2;\\n\"\r\n                : \"layout(location = 0) out vec4 glFragColor;\\n\";\r\n\r\n            if (hasDualSourceBlending) {\r\n                code = \"#extension GL_EXT_blend_func_extended : require\\n\" + code;\r\n            }\r\n            code = code.replace(/texture2DLodEXT\\s*\\(/g, \"textureLod(\");\r\n            code = code.replace(/textureCubeLodEXT\\s*\\(/g, \"textureLod(\");\r\n            code = code.replace(/textureCube\\s*\\(/g, \"texture(\");\r\n            code = code.replace(/gl_FragDepthEXT/g, \"gl_FragDepth\");\r\n            code = code.replace(/gl_FragColor/g, \"glFragColor\");\r\n            code = code.replace(/gl_FragData/g, \"glFragData\");\r\n            code = code.replace(/void\\s+?main\\s*\\(/g, (hasDrawBuffersExtension || hasOutput ? \"\" : outputDeclaration) + \"void main(\");\r\n        } else {\r\n            if (defines.indexOf(\"#define VERTEXOUTPUT_INVARIANT\") >= 0) {\r\n                code = \"invariant gl_Position;\\n\" + code;\r\n            }\r\n            const hasMultiviewExtension = defines.indexOf(\"#define MULTIVIEW\") !== -1;\r\n            if (hasMultiviewExtension) {\r\n                return \"#extension GL_OVR_multiview2 : require\\nlayout (num_views = 2) in;\\n\" + code;\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n}\r\n","import { DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/** @internal */\r\nexport class WebGLDataBuffer extends DataBuffer {\r\n    private _buffer: Nullable<WebGLBuffer>;\r\n\r\n    /** @internal */\r\n    public constructor(resource: WebGLBuffer) {\r\n        super();\r\n        this._buffer = resource;\r\n    }\r\n\r\n    /** @internal */\r\n    public override get underlyingResource(): any {\r\n        return this._buffer;\r\n    }\r\n}\r\n","import { type IHardwareTextureWrapper } from \"../../Materials/Textures/hardwareTextureWrapper\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/** @internal */\r\nexport class WebGLHardwareTexture implements IHardwareTextureWrapper {\r\n    private _webGLTexture: WebGLTexture;\r\n    private _context: WebGLRenderingContext;\r\n\r\n    // There can be multiple buffers for a single WebGL texture because different layers of a 2DArrayTexture / 3DTexture\r\n    // or different faces of a cube texture can be bound to different render targets at the same time.\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _MSAARenderBuffers: Nullable<WebGLRenderbuffer[]> = null;\r\n\r\n    // Set to true once GPU memory has been allocated for the texture (used only for compressed textures with mipmaps).\r\n    public memoryAllocated?: boolean;\r\n\r\n    public get underlyingResource(): Nullable<WebGLTexture> {\r\n        return this._webGLTexture;\r\n    }\r\n\r\n    constructor(existingTexture: Nullable<WebGLTexture> = null, context: WebGLRenderingContext) {\r\n        this._context = context;\r\n        if (!existingTexture) {\r\n            existingTexture = context.createTexture();\r\n            if (!existingTexture) {\r\n                throw new Error(\"Unable to create webGL texture\");\r\n            }\r\n        }\r\n        this.set(existingTexture);\r\n    }\r\n\r\n    public setUsage(): void {}\r\n\r\n    public set(hardwareTexture: WebGLTexture) {\r\n        this._webGLTexture = hardwareTexture;\r\n    }\r\n\r\n    public reset() {\r\n        this._webGLTexture = null as any;\r\n        this._MSAARenderBuffers = null;\r\n    }\r\n\r\n    public addMSAARenderBuffer(buffer: WebGLRenderbuffer) {\r\n        if (!this._MSAARenderBuffers) {\r\n            this._MSAARenderBuffers = [];\r\n        }\r\n        this._MSAARenderBuffers.push(buffer);\r\n    }\r\n\r\n    public releaseMSAARenderBuffers() {\r\n        if (this._MSAARenderBuffers) {\r\n            for (const buffer of this._MSAARenderBuffers) {\r\n                this._context.deleteRenderbuffer(buffer);\r\n            }\r\n            this._MSAARenderBuffers = null;\r\n        }\r\n    }\r\n\r\n    public getMSAARenderBuffer(index = 0) {\r\n        return this._MSAARenderBuffers?.[index] ?? null;\r\n    }\r\n\r\n    public release() {\r\n        this.releaseMSAARenderBuffers();\r\n\r\n        if (this._webGLTexture) {\r\n            this._context.deleteTexture(this._webGLTexture);\r\n        }\r\n        this.reset();\r\n    }\r\n}\r\n","import { Constants } from \"core/Engines/constants\";\r\n\r\n/**\r\n * Checks if a given format is a depth texture format\r\n * @param format Format to check\r\n * @returns True if the format is a depth texture format\r\n */\r\nexport function IsDepthTexture(format: number): boolean {\r\n    return (\r\n        format === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH32_FLOAT ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH16 ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH24 ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8 ||\r\n        format === Constants.TEXTUREFORMAT_STENCIL8\r\n    );\r\n}\r\n\r\n/**\r\n * Checks if a given format stores integer color components.\r\n * @param format Format to check\r\n * @returns True if the format is an integer color format\r\n * @internal\r\n */\r\nexport function IsIntegerTextureFormat(format: number): boolean {\r\n    return (\r\n        format === Constants.TEXTUREFORMAT_RED_INTEGER ||\r\n        format === Constants.TEXTUREFORMAT_RG_INTEGER ||\r\n        format === Constants.TEXTUREFORMAT_RGB_INTEGER ||\r\n        format === Constants.TEXTUREFORMAT_RGBA_INTEGER\r\n    );\r\n}\r\n\r\n/**\r\n * Checks whether an integer texture type stores unsigned values.\r\n * @param type Texture type to check\r\n * @returns True for unsigned scalar and packed integer texture types\r\n * @internal\r\n */\r\nexport function IsUnsignedIntegerTextureType(type: number): boolean {\r\n    return (\r\n        type === Constants.TEXTURETYPE_UNSIGNED_BYTE ||\r\n        type === Constants.TEXTURETYPE_UNSIGNED_SHORT ||\r\n        type === Constants.TEXTURETYPE_UNSIGNED_INTEGER ||\r\n        type === Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV\r\n    );\r\n}\r\n\r\n/**\r\n * Gets the type of a depth texture for a given format\r\n * @param format Format of the texture\r\n * @returns The type of the depth texture\r\n */\r\nexport function GetTypeForDepthTexture(format: number): number {\r\n    switch (format) {\r\n        case Constants.TEXTUREFORMAT_DEPTH24_STENCIL8:\r\n        case Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8:\r\n        case Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8:\r\n        case Constants.TEXTUREFORMAT_DEPTH32_FLOAT:\r\n        case Constants.TEXTUREFORMAT_DEPTH24:\r\n            return Constants.TEXTURETYPE_FLOAT;\r\n        case Constants.TEXTUREFORMAT_DEPTH16:\r\n            return Constants.TEXTURETYPE_UNSIGNED_SHORT;\r\n        case Constants.TEXTUREFORMAT_STENCIL8:\r\n            return Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    }\r\n\r\n    return Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n}\r\n\r\n/**\r\n * Checks if a given format has a stencil aspect\r\n * @param format Format to check\r\n * @returns True if the format has a stencil aspect\r\n */\r\nexport function HasStencilAspect(format: number): boolean {\r\n    return (\r\n        format === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 ||\r\n        format === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8 ||\r\n        format === Constants.TEXTUREFORMAT_STENCIL8\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type IEffectCreationOptions, type IShaderPath, Effect } from \"../Materials/effect.pure\";\r\nimport { type _IShaderProcessingContext } from \"./Processors/shaderProcessingOptions\";\r\nimport { type Nullable, type DataArray, type IndicesArray, type FloatArray, type DeepImmutable } from \"../types\";\r\nimport { type IColor4Like } from \"../Maths/math.like\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { type WebGLPipelineContext } from \"./WebGL/webGLPipelineContext\";\r\nimport { type VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type InstancingAttributeInfo } from \"./instancingAttributeInfo\";\r\nimport { type ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { type IEffectFallbacks } from \"../Materials/iEffectFallbacks\";\r\nimport { type IHardwareTextureWrapper } from \"../Materials/Textures/hardwareTextureWrapper\";\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { type IMaterialContext } from \"./IMaterialContext\";\r\nimport { type IDrawContext } from \"./IDrawContext\";\r\nimport { type ICanvas, type ICanvasRenderingContext } from \"./ICanvas\";\r\nimport { type IStencilState } from \"../States/IStencilState\";\r\nimport { type InternalTextureCreationOptions, type TextureSize } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { type RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { type WebGLRenderTargetWrapper } from \"./WebGL/webGLRenderTargetWrapper\";\r\nimport { type VideoTexture } from \"../Materials/Textures/videoTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport {\r\n    createPipelineContext,\r\n    createRawShaderProgram,\r\n    createShaderProgram,\r\n    _finalizePipelineContext,\r\n    _preparePipelineContext,\r\n    _setProgram,\r\n    _executeWhenRenderingStateIsCompiled,\r\n    getStateObject,\r\n    _createShaderProgram,\r\n    deleteStateObject,\r\n    _isRenderingStateCompiled,\r\n} from \"./thinEngine.functions\";\r\n\r\nimport { type AbstractEngineOptions, type ISceneLike, type PrepareTextureFunction, type PrepareTextureProcessFunction, AbstractEngine } from \"./abstractEngine.pure\";\r\nimport { type PerformanceMonitor } from \"../Misc/performanceMonitor\";\r\nimport { IsWrapper } from \"../Materials/drawWrapper.functions\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { IsWindowObjectExist } from \"../Misc/domManagement\";\r\nimport { WebGLShaderProcessor } from \"./WebGL/webGLShaderProcessors\";\r\nimport { WebGL2ShaderProcessor } from \"./WebGL/webGL2ShaderProcessors\";\r\nimport { WebGLDataBuffer } from \"../Meshes/WebGL/webGLDataBuffer\";\r\nimport { GetExponentOfTwo } from \"../Misc/tools.functions\";\r\nimport { Constants } from \"./constants\";\r\nimport { WebGLHardwareTexture } from \"./WebGL/webGLHardwareTexture\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { _ConcatenateShader, _GetGlobalDefines } from \"./abstractEngine.functions\";\r\nimport { resetCachedPipeline } from \"core/Materials/effect.functions\";\r\nimport { HasStencilAspect, IsDepthTexture, IsIntegerTextureFormat, IsUnsignedIntegerTextureType } from \"core/Materials/Textures/textureHelper.functions\";\r\nimport { AlphaState } from \"../States/alphaCullingState\";\r\n\r\n/**\r\n * Keeps track of all the buffer info used in engine.\r\n */\r\nclass BufferPointer {\r\n    public active: boolean;\r\n    public index: number;\r\n    public size: number;\r\n    public type: number;\r\n    public normalized: boolean;\r\n    public stride: number;\r\n    public offset: number;\r\n    public buffer: WebGLBuffer;\r\n}\r\n\r\n/** Interface defining initialization parameters for Engine class */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface EngineOptions extends AbstractEngineOptions, WebGLContextAttributes {\r\n    /**\r\n     * Defines if webgl2 should be turned off even if supported\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2\r\n     */\r\n    disableWebGL2Support?: boolean;\r\n\r\n    /**\r\n     * Defines that engine should compile shaders with high precision floats (if supported). True by default\r\n     */\r\n    useHighPrecisionFloats?: boolean;\r\n    /**\r\n     * Make the canvas XR Compatible for XR sessions\r\n     */\r\n    xrCompatible?: boolean;\r\n\r\n    /**\r\n     * Will prevent the system from falling back to software implementation if a hardware device cannot be created\r\n     */\r\n    failIfMajorPerformanceCaveat?: boolean;\r\n\r\n    /**\r\n     * If sRGB buffer support is not set during construction, use this value to force a specific state\r\n     * This was originally added to mitigate an issue when processing textures in chrome/edge/firefox.\r\n     * The browser issue has since been fixed. This option remains for backward compatibility.\r\n     * This will not influence NativeEngine and WebGPUEngine which set the behavior to true during construction.\r\n     */\r\n    forceSRGBBufferSupportState?: boolean;\r\n\r\n    /**\r\n     * Defines if the gl context should be released.\r\n     * It's false by default for backward compatibility, but you should probably pass true (see https://registry.khronos.org/webgl/extensions/WEBGL_lose_context/)\r\n     */\r\n    loseContextOnDispose?: boolean;\r\n}\r\n\r\n/**\r\n * The base engine class (root of all engines)\r\n */\r\nexport class ThinEngine extends AbstractEngine {\r\n    private static _TempClearColorUint32 = /*#__PURE__*/ new Uint32Array(4);\r\n    private static _TempClearColorInt32 = /*#__PURE__*/ new Int32Array(4);\r\n    private static _TempClearColorFloat32 = /*#__PURE__*/ new Float32Array(4);\r\n\r\n    /** Use this array to turn off some WebGL2 features on known buggy browsers version */\r\n    public static ExceptionList = [\r\n        { key: \"Chrome/63.0\", capture: \"63\\\\.0\\\\.3239\\\\.(\\\\d+)\", captureConstraint: 108, targets: [\"uniformBuffer\"] },\r\n        { key: \"Firefox/58\", capture: null, captureConstraint: null, targets: [\"uniformBuffer\"] },\r\n        { key: \"Firefox/59\", capture: null, captureConstraint: null, targets: [\"uniformBuffer\"] },\r\n        { key: \"Chrome/72.+?Mobile\", capture: null, captureConstraint: null, targets: [\"vao\"] },\r\n        { key: \"Chrome/73.+?Mobile\", capture: null, captureConstraint: null, targets: [\"vao\"] },\r\n        { key: \"Chrome/74.+?Mobile\", capture: null, captureConstraint: null, targets: [\"vao\"] },\r\n        { key: \"Mac OS.+Chrome/71\", capture: null, captureConstraint: null, targets: [\"vao\"] },\r\n        { key: \"Mac OS.+Chrome/72\", capture: null, captureConstraint: null, targets: [\"vao\"] },\r\n        { key: \"Mac OS.+Chrome\", capture: null, captureConstraint: null, targets: [\"uniformBuffer\"] },\r\n        { key: \"Chrome/12\\\\d\\\\..+?Mobile\", capture: null, captureConstraint: null, targets: [\"uniformBuffer\"] },\r\n        // desktop osx safari 15.4\r\n        { key: \".*AppleWebKit.*(15.4).*Safari\", capture: null, captureConstraint: null, targets: [\"antialias\", \"maxMSAASamples\"] },\r\n        // mobile browsers using safari 15.4 on ios\r\n        { key: \".*(15.4).*AppleWebKit.*Safari\", capture: null, captureConstraint: null, targets: [\"antialias\", \"maxMSAASamples\"] },\r\n    ];\r\n\r\n    /** @internal */\r\n    protected override _name = \"WebGL\";\r\n\r\n    /**\r\n     * Gets or sets the name of the engine\r\n     */\r\n    public override get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    /**\r\n     * Returns the version of the engine\r\n     */\r\n    public get version(): number {\r\n        return this._webGLVersion;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the relative url used to load shaders if using the engine in non-minified mode\r\n     */\r\n    public static get ShadersRepository(): string {\r\n        return Effect.ShadersRepository;\r\n    }\r\n    public static set ShadersRepository(value: string) {\r\n        Effect.ShadersRepository = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean that indicates if textures must be forced to power of 2 size even if not required\r\n     */\r\n    public forcePOTTextures = false;\r\n\r\n    /** Gets or sets a boolean indicating if the engine should validate programs after compilation */\r\n    public validateShaderPrograms = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that uniform buffers must be disabled even if they are supported\r\n     */\r\n    public disableUniformBuffers = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the engine supports uniform buffers\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     */\r\n    public get supportsUniformBuffers(): boolean {\r\n        return this.webGLVersion > 1 && !this.disableUniformBuffers;\r\n    }\r\n\r\n    // Private Members\r\n\r\n    /** @internal */\r\n    public _gl: WebGL2RenderingContext;\r\n    /** @internal */\r\n    public _webGLVersion = 1.0;\r\n    /** @internal */\r\n    public _integerMRTAttachmentsMask = 0;\r\n\r\n    /** @internal */\r\n    public _glSRGBExtensionValues: {\r\n        SRGB: typeof WebGL2RenderingContext.SRGB;\r\n        SRGB8: typeof WebGL2RenderingContext.SRGB8 | EXT_sRGB[\"SRGB_ALPHA_EXT\"];\r\n        SRGB8_ALPHA8: typeof WebGL2RenderingContext.SRGB8_ALPHA8 | EXT_sRGB[\"SRGB_ALPHA_EXT\"];\r\n    };\r\n\r\n    /**\r\n     * Gets a boolean indicating that only power of 2 textures are supported\r\n     * Please note that you can still use non power of 2 textures but in this case the engine will forcefully convert them\r\n     */\r\n    public get needPOTTextures(): boolean {\r\n        return this._webGLVersion < 2 || this.forcePOTTextures;\r\n    }\r\n\r\n    private _glVersion: string;\r\n    private _glRenderer: string;\r\n    private _glVendor: string;\r\n\r\n    // Cache\r\n\r\n    /** @internal */\r\n    protected _currentProgram: Nullable<WebGLProgram>;\r\n    private _vertexAttribArraysEnabled: boolean[] = [];\r\n    private _cachedVertexArrayObject: Nullable<WebGLVertexArrayObject>;\r\n\r\n    private _uintIndicesCurrentlySet = false;\r\n    protected _currentBoundBuffer = new Array<Nullable<DataBuffer>>();\r\n    /** @internal */\r\n    public _currentFramebuffer: Nullable<WebGLFramebuffer> = null;\r\n    /** @internal */\r\n    public _dummyFramebuffer: Nullable<WebGLFramebuffer> = null;\r\n    private _currentBufferPointers = new Array<BufferPointer>();\r\n    private _currentInstanceLocations = new Array<number>();\r\n    private _currentInstanceBuffers = new Array<DataBuffer>();\r\n    private _textureUnits: Int32Array;\r\n\r\n    /** @internal */\r\n    public _workingCanvas: Nullable<ICanvas>;\r\n    /** @internal */\r\n    public _workingContext: Nullable<ICanvasRenderingContext>;\r\n\r\n    private _vaoRecordInProgress = false;\r\n    private _mustWipeVertexAttributes = false;\r\n\r\n    private _nextFreeTextureSlots = new Array<number>();\r\n    private _maxSimultaneousTextures = 0;\r\n    private _maxMSAASamplesOverride: Nullable<number> = null;\r\n\r\n    protected get _supportsHardwareTextureRescaling() {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Creates a new snapshot at the next frame using the current snapshotRenderingMode\r\n     */\r\n    public snapshotRenderingReset(): void {\r\n        this.snapshotRendering = false;\r\n    }\r\n\r\n    /**\r\n     * Creates a new engine\r\n     * @param canvasOrContext defines the canvas or WebGL context to use for rendering. If you provide a WebGL context, Babylon.js will not hook events on the canvas (like pointers, keyboards, etc...) so no event observables will be available. This is mostly used when Babylon.js is used as a plugin on a system which already used the WebGL context\r\n     * @param antialias defines whether anti-aliasing should be enabled (default value is \"undefined\", meaning that the browser may or may not enable it)\r\n     * @param options defines further options to be sent to the getContext() function\r\n     * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)\r\n     */\r\n    constructor(\r\n        canvasOrContext: Nullable<HTMLCanvasElement | OffscreenCanvas | WebGLRenderingContext | WebGL2RenderingContext>,\r\n        antialias?: boolean,\r\n        options?: EngineOptions,\r\n        adaptToDeviceRatio?: boolean\r\n    ) {\r\n        options = options || {};\r\n        super(antialias ?? options.antialias, options, adaptToDeviceRatio);\r\n\r\n        if (!canvasOrContext) {\r\n            return;\r\n        }\r\n\r\n        let canvas: Nullable<HTMLCanvasElement>;\r\n        if ((canvasOrContext as any).getContext) {\r\n            canvas = <HTMLCanvasElement>canvasOrContext;\r\n\r\n            if (options.preserveDrawingBuffer === undefined) {\r\n                options.preserveDrawingBuffer = false;\r\n            }\r\n\r\n            if (options.xrCompatible === undefined) {\r\n                options.xrCompatible = false;\r\n            }\r\n\r\n            // Exceptions\r\n            if (navigator && navigator.userAgent) {\r\n                this._setupMobileChecks();\r\n\r\n                const ua = navigator.userAgent;\r\n                for (const exception of ThinEngine.ExceptionList) {\r\n                    const key = exception.key;\r\n                    const targets = exception.targets;\r\n                    const check = new RegExp(key);\r\n\r\n                    if (check.test(ua)) {\r\n                        if (exception.capture && exception.captureConstraint) {\r\n                            const capture = exception.capture;\r\n                            const constraint = exception.captureConstraint;\r\n\r\n                            const regex = new RegExp(capture);\r\n                            const matches = regex.exec(ua);\r\n\r\n                            if (matches && matches.length > 0) {\r\n                                const capturedValue = parseInt(matches[matches.length - 1]);\r\n                                if (capturedValue >= constraint) {\r\n                                    continue;\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        for (const target of targets) {\r\n                            switch (target) {\r\n                                case \"uniformBuffer\":\r\n                                    this.disableUniformBuffers = true;\r\n                                    break;\r\n                                case \"vao\":\r\n                                    this.disableVertexArrayObjects = true;\r\n                                    break;\r\n                                case \"antialias\":\r\n                                    options.antialias = false;\r\n                                    break;\r\n                                case \"maxMSAASamples\":\r\n                                    this._maxMSAASamplesOverride = 1;\r\n                                    break;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Context lost\r\n            if (!this._doNotHandleContextLost) {\r\n                this._onContextLost = (evt: Event) => {\r\n                    evt.preventDefault();\r\n                    this._contextWasLost = true;\r\n                    deleteStateObject(this._gl);\r\n                    Logger.Warn(\"WebGL context lost.\");\r\n\r\n                    this.onContextLostObservable.notifyObservers(this);\r\n                };\r\n\r\n                this._onContextRestored = () => {\r\n                    this._restoreEngineAfterContextLost(() => this._initGLContext());\r\n                };\r\n\r\n                canvas.addEventListener(\"webglcontextrestored\", this._onContextRestored, false);\r\n\r\n                options.powerPreference = options.powerPreference || \"high-performance\";\r\n            } else {\r\n                this._onContextLost = () => {\r\n                    deleteStateObject(this._gl);\r\n                };\r\n            }\r\n\r\n            canvas.addEventListener(\"webglcontextlost\", this._onContextLost, false);\r\n\r\n            if (this._badDesktopOS) {\r\n                options.xrCompatible = false;\r\n            }\r\n\r\n            // GL\r\n            if (!options.disableWebGL2Support) {\r\n                try {\r\n                    this._gl = <any>(canvas.getContext(\"webgl2\", options) || canvas.getContext(\"experimental-webgl2\", options));\r\n                    if (this._gl) {\r\n                        this._webGLVersion = 2.0;\r\n                        this._shaderPlatformName = \"WEBGL2\";\r\n\r\n                        // Prevent weird browsers to lie (yeah that happens!)\r\n                        if (!this._gl.deleteQuery) {\r\n                            this._webGLVersion = 1.0;\r\n                            this._shaderPlatformName = \"WEBGL1\";\r\n                        }\r\n                    }\r\n                } catch (e) {\r\n                    // Do nothing\r\n                }\r\n            }\r\n\r\n            if (!this._gl) {\r\n                if (!canvas) {\r\n                    throw new Error(\"The provided canvas is null or undefined.\");\r\n                }\r\n                try {\r\n                    this._gl = <WebGL2RenderingContext>(canvas.getContext(\"webgl\", options) || canvas.getContext(\"experimental-webgl\", options));\r\n                } catch (e) {\r\n                    throw new Error(\"WebGL not supported\", { cause: e });\r\n                }\r\n            }\r\n\r\n            if (!this._gl) {\r\n                throw new Error(\"WebGL not supported\");\r\n            }\r\n        } else {\r\n            this._gl = <WebGL2RenderingContext>canvasOrContext;\r\n            canvas = this._gl.canvas as HTMLCanvasElement;\r\n\r\n            if ((this._gl as any).renderbufferStorageMultisample) {\r\n                this._webGLVersion = 2.0;\r\n                this._shaderPlatformName = \"WEBGL2\";\r\n            } else {\r\n                this._shaderPlatformName = \"WEBGL1\";\r\n            }\r\n\r\n            const attributes = this._gl.getContextAttributes();\r\n            if (attributes) {\r\n                options.stencil = attributes.stencil;\r\n            }\r\n        }\r\n\r\n        this._sharedInit(canvas);\r\n\r\n        // Ensures a consistent color space unpacking of textures cross browser.\r\n        this._gl.pixelStorei(this._gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, this._gl.NONE);\r\n\r\n        if (options.useHighPrecisionFloats !== undefined) {\r\n            this._highPrecisionShadersAllowed = options.useHighPrecisionFloats;\r\n        }\r\n\r\n        this.resize();\r\n\r\n        this._initGLContext();\r\n        this._initFeatures();\r\n\r\n        // Prepare buffer pointers\r\n        for (let i = 0; i < this._caps.maxVertexAttribs; i++) {\r\n            this._currentBufferPointers[i] = new BufferPointer();\r\n        }\r\n\r\n        // Shader processor\r\n        this._shaderProcessor = this.webGLVersion > 1 ? new WebGL2ShaderProcessor() : new WebGLShaderProcessor();\r\n\r\n        // Starting with iOS 14, we can trust the browser\r\n        // let matches = navigator.userAgent.match(/Version\\/(\\d+)/);\r\n\r\n        // if (matches && matches.length === 2) {\r\n        //     if (parseInt(matches[1]) >= 14) {\r\n        //         this._badOS = false;\r\n        //     }\r\n        // }\r\n\r\n        const versionToLog = `Babylon.js v${ThinEngine.Version}`;\r\n        Logger.Log(versionToLog + ` - ${this.description}`);\r\n\r\n        // Check setAttribute in case of workers\r\n        if (this._renderingCanvas && this._renderingCanvas.setAttribute) {\r\n            this._renderingCanvas.setAttribute(\"data-engine\", versionToLog);\r\n        }\r\n        const stateObject = getStateObject(this._gl);\r\n        // update state object with the current engine state\r\n        stateObject.validateShaderPrograms = this.validateShaderPrograms;\r\n        stateObject.parallelShaderCompile = this._caps.parallelShaderCompile;\r\n    }\r\n\r\n    protected override _clearEmptyResources(): void {\r\n        this._dummyFramebuffer = null;\r\n        super._clearEmptyResources();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getShaderProcessingContext(shaderLanguage: ShaderLanguage): Nullable<_IShaderProcessingContext> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if all created effects are ready\r\n     * @returns true if all effects are ready\r\n     */\r\n    public areAllEffectsReady(): boolean {\r\n        for (const key in this._compiledEffects) {\r\n            const effect = this._compiledEffects[key];\r\n\r\n            if (!effect.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    protected _initGLContext(): void {\r\n        // Caps\r\n        this._caps = {\r\n            maxTexturesImageUnits: this._gl.getParameter(this._gl.MAX_TEXTURE_IMAGE_UNITS),\r\n            maxCombinedTexturesImageUnits: this._gl.getParameter(this._gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),\r\n            maxVertexTextureImageUnits: this._gl.getParameter(this._gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS),\r\n            maxTextureSize: this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE),\r\n            maxSamples: this._webGLVersion > 1 ? this._gl.getParameter(this._gl.MAX_SAMPLES) : 1,\r\n            maxCubemapTextureSize: this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE),\r\n            maxRenderTextureSize: this._gl.getParameter(this._gl.MAX_RENDERBUFFER_SIZE),\r\n            maxVertexAttribs: this._gl.getParameter(this._gl.MAX_VERTEX_ATTRIBS),\r\n            maxVaryingVectors: this._gl.getParameter(this._gl.MAX_VARYING_VECTORS),\r\n            maxFragmentUniformVectors: this._gl.getParameter(this._gl.MAX_FRAGMENT_UNIFORM_VECTORS),\r\n            maxVertexUniformVectors: this._gl.getParameter(this._gl.MAX_VERTEX_UNIFORM_VECTORS),\r\n            shaderFloatPrecision: 0,\r\n            parallelShaderCompile: this._gl.getExtension(\"KHR_parallel_shader_compile\") || undefined,\r\n            standardDerivatives: this._webGLVersion > 1 || this._gl.getExtension(\"OES_standard_derivatives\") !== null,\r\n            maxAnisotropy: 1,\r\n            astc: this._gl.getExtension(\"WEBGL_compressed_texture_astc\") || this._gl.getExtension(\"WEBKIT_WEBGL_compressed_texture_astc\"),\r\n            bptc: this._gl.getExtension(\"EXT_texture_compression_bptc\") || this._gl.getExtension(\"WEBKIT_EXT_texture_compression_bptc\"),\r\n            s3tc: this._gl.getExtension(\"WEBGL_compressed_texture_s3tc\") || this._gl.getExtension(\"WEBKIT_WEBGL_compressed_texture_s3tc\"),\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            s3tc_srgb: this._gl.getExtension(\"WEBGL_compressed_texture_s3tc_srgb\") || this._gl.getExtension(\"WEBKIT_WEBGL_compressed_texture_s3tc_srgb\"),\r\n            pvrtc: this._gl.getExtension(\"WEBGL_compressed_texture_pvrtc\") || this._gl.getExtension(\"WEBKIT_WEBGL_compressed_texture_pvrtc\"),\r\n            etc1: this._gl.getExtension(\"WEBGL_compressed_texture_etc1\") || this._gl.getExtension(\"WEBKIT_WEBGL_compressed_texture_etc1\"),\r\n            etc2:\r\n                this._gl.getExtension(\"WEBGL_compressed_texture_etc\") ||\r\n                this._gl.getExtension(\"WEBKIT_WEBGL_compressed_texture_etc\") ||\r\n                this._gl.getExtension(\"WEBGL_compressed_texture_es3_0\"), // also a requirement of OpenGL ES 3\r\n            textureAnisotropicFilterExtension:\r\n                this._gl.getExtension(\"EXT_texture_filter_anisotropic\") ||\r\n                this._gl.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\") ||\r\n                this._gl.getExtension(\"MOZ_EXT_texture_filter_anisotropic\"),\r\n            uintIndices: this._webGLVersion > 1 || this._gl.getExtension(\"OES_element_index_uint\") !== null,\r\n            fragmentDepthSupported: this._webGLVersion > 1 || this._gl.getExtension(\"EXT_frag_depth\") !== null,\r\n            highPrecisionShaderSupported: false,\r\n            timerQuery: this._gl.getExtension(\"EXT_disjoint_timer_query_webgl2\") || this._gl.getExtension(\"EXT_disjoint_timer_query\"),\r\n            supportOcclusionQuery: this._webGLVersion > 1,\r\n            canUseTimestampForTimerQuery: false,\r\n            drawBuffersExtension: false,\r\n            maxMSAASamples: 1,\r\n            colorBufferFloat: !!(this._webGLVersion > 1 && this._gl.getExtension(\"EXT_color_buffer_float\")),\r\n            blendFloat: this._gl.getExtension(\"EXT_float_blend\") !== null,\r\n            supportFloatTexturesResolve: false,\r\n            rg11b10ufColorRenderable: false,\r\n            colorBufferHalfFloat: !!(this._webGLVersion > 1 && this._gl.getExtension(\"EXT_color_buffer_half_float\")),\r\n            textureFloat: this._webGLVersion > 1 || this._gl.getExtension(\"OES_texture_float\") ? true : false,\r\n            textureHalfFloat: this._webGLVersion > 1 || this._gl.getExtension(\"OES_texture_half_float\") ? true : false,\r\n            textureHalfFloatRender: false,\r\n            textureFloatLinearFiltering: false,\r\n            textureFloatRender: false,\r\n            textureHalfFloatLinearFiltering: false,\r\n            vertexArrayObject: false,\r\n            instancedArrays: false,\r\n            textureLOD: this._webGLVersion > 1 || this._gl.getExtension(\"EXT_shader_texture_lod\") ? true : false,\r\n            texelFetch: this._webGLVersion !== 1,\r\n            blendMinMax: false,\r\n            multiview: this._gl.getExtension(\"OVR_multiview2\"),\r\n            oculusMultiview: this._gl.getExtension(\"OCULUS_multiview\"),\r\n            depthTextureExtension: false,\r\n            canUseGLInstanceID: this._webGLVersion > 1,\r\n            canUseGLVertexID: this._webGLVersion > 1,\r\n            supportComputeShaders: false,\r\n            supportSRGBBuffers: false,\r\n            supportTransformFeedbacks: this._webGLVersion > 1,\r\n            textureMaxLevel: this._webGLVersion > 1,\r\n            texture2DArrayMaxLayerCount: this._webGLVersion > 1 ? this._gl.getParameter(this._gl.MAX_ARRAY_TEXTURE_LAYERS) : 128,\r\n            disableMorphTargetTexture: false,\r\n            textureNorm16: this._gl.getExtension(\"EXT_texture_norm16\") ? true : false,\r\n            blendParametersPerTarget: false,\r\n            dualSourceBlending: false,\r\n            supportReadWriteStorageTextures: false,\r\n        };\r\n\r\n        this._caps.supportFloatTexturesResolve = this._caps.colorBufferFloat;\r\n        this._caps.rg11b10ufColorRenderable = this._caps.colorBufferFloat;\r\n\r\n        // Infos\r\n        this._glVersion = this._gl.getParameter(this._gl.VERSION);\r\n\r\n        const rendererInfo: any = this._gl.getExtension(\"WEBGL_debug_renderer_info\");\r\n        if (rendererInfo != null) {\r\n            this._glRenderer = this._gl.getParameter(rendererInfo.UNMASKED_RENDERER_WEBGL);\r\n            this._glVendor = this._gl.getParameter(rendererInfo.UNMASKED_VENDOR_WEBGL);\r\n        }\r\n\r\n        if (!this._glVendor) {\r\n            this._glVendor = this._gl.getParameter(this._gl.VENDOR) || \"Unknown vendor\";\r\n        }\r\n\r\n        if (!this._glRenderer) {\r\n            this._glRenderer = this._gl.getParameter(this._gl.RENDERER) || \"Unknown renderer\";\r\n        }\r\n\r\n        // Constants\r\n        if (this._gl.HALF_FLOAT_OES !== 0x8d61) {\r\n            this._gl.HALF_FLOAT_OES = 0x8d61; // Half floating-point type (16-bit).\r\n        }\r\n        if (this._gl.RGBA16F !== 0x881a) {\r\n            this._gl.RGBA16F = 0x881a; // RGBA 16-bit floating-point color-renderable internal sized format.\r\n        }\r\n        if (this._gl.RGBA32F !== 0x8814) {\r\n            this._gl.RGBA32F = 0x8814; // RGBA 32-bit floating-point color-renderable internal sized format.\r\n        }\r\n        if (this._gl.DEPTH24_STENCIL8 !== 35056) {\r\n            this._gl.DEPTH24_STENCIL8 = 35056;\r\n        }\r\n\r\n        // Extensions\r\n        if (this._caps.timerQuery) {\r\n            if (this._webGLVersion === 1) {\r\n                this._gl.getQuery = (<any>this._caps.timerQuery).getQueryEXT.bind(this._caps.timerQuery);\r\n            }\r\n            // WebGLQuery casted to number to avoid TS error\r\n            this._caps.canUseTimestampForTimerQuery = ((this._gl.getQuery(this._caps.timerQuery.TIMESTAMP_EXT, this._caps.timerQuery.QUERY_COUNTER_BITS_EXT) as number) ?? 0) > 0;\r\n        }\r\n\r\n        this._caps.maxAnisotropy = this._caps.textureAnisotropicFilterExtension\r\n            ? this._gl.getParameter(this._caps.textureAnisotropicFilterExtension.MAX_TEXTURE_MAX_ANISOTROPY_EXT)\r\n            : 0;\r\n        this._caps.textureFloatLinearFiltering = this._caps.textureFloat && this._gl.getExtension(\"OES_texture_float_linear\") ? true : false;\r\n        this._caps.textureFloatRender = this._caps.textureFloat && this._canRenderToFloatFramebuffer() ? true : false;\r\n        this._caps.textureHalfFloatLinearFiltering =\r\n            this._webGLVersion > 1 || (this._caps.textureHalfFloat && this._gl.getExtension(\"OES_texture_half_float_linear\")) ? true : false;\r\n\r\n        if (this._caps.textureNorm16) {\r\n            this._gl.R16_EXT = 0x822a;\r\n            this._gl.RG16_EXT = 0x822c;\r\n            this._gl.RGB16_EXT = 0x8054;\r\n            this._gl.RGBA16_EXT = 0x805b;\r\n            this._gl.R16_SNORM_EXT = 0x8f98;\r\n            this._gl.RG16_SNORM_EXT = 0x8f99;\r\n            this._gl.RGB16_SNORM_EXT = 0x8f9a;\r\n            this._gl.RGBA16_SNORM_EXT = 0x8f9b;\r\n        }\r\n\r\n        const oesDrawBuffersIndexed = this._gl.getExtension(\"OES_draw_buffers_indexed\");\r\n        this._caps.blendParametersPerTarget = oesDrawBuffersIndexed ? true : false;\r\n\r\n        this._alphaState = new AlphaState(this._caps.blendParametersPerTarget);\r\n\r\n        if (oesDrawBuffersIndexed) {\r\n            this._gl.blendEquationSeparateIndexed = oesDrawBuffersIndexed.blendEquationSeparateiOES.bind(oesDrawBuffersIndexed);\r\n            this._gl.blendEquationIndexed = oesDrawBuffersIndexed.blendEquationiOES.bind(oesDrawBuffersIndexed);\r\n            this._gl.blendFuncSeparateIndexed = oesDrawBuffersIndexed.blendFuncSeparateiOES.bind(oesDrawBuffersIndexed);\r\n            this._gl.blendFuncIndexed = oesDrawBuffersIndexed.blendFunciOES.bind(oesDrawBuffersIndexed);\r\n            this._gl.colorMaskIndexed = oesDrawBuffersIndexed.colorMaskiOES.bind(oesDrawBuffersIndexed);\r\n            this._gl.disableIndexed = oesDrawBuffersIndexed.disableiOES.bind(oesDrawBuffersIndexed);\r\n            this._gl.enableIndexed = oesDrawBuffersIndexed.enableiOES.bind(oesDrawBuffersIndexed);\r\n        }\r\n\r\n        this._caps.dualSourceBlending = this._gl.getExtension(\"WEBGL_blend_func_extended\") ? true : false;\r\n\r\n        // Compressed formats\r\n        if (this._caps.astc) {\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = this._caps.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;\r\n        }\r\n        if (this._caps.bptc) {\r\n            this._gl.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT = this._caps.bptc.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT;\r\n        }\r\n        if (this._caps.s3tc_srgb) {\r\n            this._gl.COMPRESSED_SRGB_S3TC_DXT1_EXT = this._caps.s3tc_srgb.COMPRESSED_SRGB_S3TC_DXT1_EXT;\r\n            this._gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = this._caps.s3tc_srgb.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;\r\n            this._gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = this._caps.s3tc_srgb.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;\r\n        }\r\n        if (this._caps.etc2) {\r\n            this._gl.COMPRESSED_SRGB8_ETC2 = this._caps.etc2.COMPRESSED_SRGB8_ETC2;\r\n            this._gl.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = this._caps.etc2.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;\r\n        }\r\n\r\n        // Checks if some of the format renders first to allow the use of webgl inspector.\r\n        if (this._webGLVersion > 1) {\r\n            if (this._gl.HALF_FLOAT_OES !== 0x140b) {\r\n                this._gl.HALF_FLOAT_OES = 0x140b;\r\n            }\r\n        }\r\n        this._caps.textureHalfFloatRender = this._caps.textureHalfFloat && this._canRenderToHalfFloatFramebuffer();\r\n        // Draw buffers\r\n        if (this._webGLVersion > 1) {\r\n            this._caps.drawBuffersExtension = true;\r\n            this._caps.maxMSAASamples = this._maxMSAASamplesOverride !== null ? this._maxMSAASamplesOverride : this._gl.getParameter(this._gl.MAX_SAMPLES);\r\n            this._caps.maxDrawBuffers = this._gl.getParameter(this._gl.MAX_DRAW_BUFFERS);\r\n        } else {\r\n            const drawBuffersExtension = this._gl.getExtension(\"WEBGL_draw_buffers\");\r\n\r\n            if (drawBuffersExtension !== null) {\r\n                this._caps.drawBuffersExtension = true;\r\n                this._gl.drawBuffers = drawBuffersExtension.drawBuffersWEBGL.bind(drawBuffersExtension);\r\n                this._caps.maxDrawBuffers = this._gl.getParameter(drawBuffersExtension.MAX_DRAW_BUFFERS_WEBGL);\r\n                (this._gl.DRAW_FRAMEBUFFER as any) = this._gl.FRAMEBUFFER;\r\n\r\n                for (let i = 0; i < 16; i++) {\r\n                    (<any>this._gl)[\"COLOR_ATTACHMENT\" + i + \"_WEBGL\"] = (<any>drawBuffersExtension)[\"COLOR_ATTACHMENT\" + i + \"_WEBGL\"];\r\n                }\r\n            }\r\n        }\r\n\r\n        // Depth Texture\r\n        if (this._webGLVersion > 1) {\r\n            this._caps.depthTextureExtension = true;\r\n        } else {\r\n            const depthTextureExtension = this._gl.getExtension(\"WEBGL_depth_texture\");\r\n\r\n            if (depthTextureExtension != null) {\r\n                this._caps.depthTextureExtension = true;\r\n                this._gl.UNSIGNED_INT_24_8 = depthTextureExtension.UNSIGNED_INT_24_8_WEBGL;\r\n            }\r\n        }\r\n\r\n        // Vertex array object\r\n        if (this.disableVertexArrayObjects) {\r\n            this._caps.vertexArrayObject = false;\r\n        } else if (this._webGLVersion > 1) {\r\n            this._caps.vertexArrayObject = true;\r\n        } else {\r\n            const vertexArrayObjectExtension = this._gl.getExtension(\"OES_vertex_array_object\");\r\n\r\n            if (vertexArrayObjectExtension != null) {\r\n                this._caps.vertexArrayObject = true;\r\n                this._gl.createVertexArray = vertexArrayObjectExtension.createVertexArrayOES.bind(vertexArrayObjectExtension);\r\n                this._gl.bindVertexArray = vertexArrayObjectExtension.bindVertexArrayOES.bind(vertexArrayObjectExtension);\r\n                this._gl.deleteVertexArray = vertexArrayObjectExtension.deleteVertexArrayOES.bind(vertexArrayObjectExtension);\r\n            }\r\n        }\r\n\r\n        // Instances count\r\n        if (this._webGLVersion > 1) {\r\n            this._caps.instancedArrays = true;\r\n        } else {\r\n            const instanceExtension = <ANGLE_instanced_arrays>this._gl.getExtension(\"ANGLE_instanced_arrays\");\r\n\r\n            if (instanceExtension != null) {\r\n                this._caps.instancedArrays = true;\r\n                this._gl.drawArraysInstanced = instanceExtension.drawArraysInstancedANGLE.bind(instanceExtension);\r\n                this._gl.drawElementsInstanced = instanceExtension.drawElementsInstancedANGLE.bind(instanceExtension);\r\n                this._gl.vertexAttribDivisor = instanceExtension.vertexAttribDivisorANGLE.bind(instanceExtension);\r\n            } else {\r\n                this._caps.instancedArrays = false;\r\n            }\r\n        }\r\n\r\n        if (this._gl.getShaderPrecisionFormat) {\r\n            const vertexhighp = this._gl.getShaderPrecisionFormat(this._gl.VERTEX_SHADER, this._gl.HIGH_FLOAT);\r\n            const fragmenthighp = this._gl.getShaderPrecisionFormat(this._gl.FRAGMENT_SHADER, this._gl.HIGH_FLOAT);\r\n\r\n            if (vertexhighp && fragmenthighp) {\r\n                this._caps.highPrecisionShaderSupported = vertexhighp.precision !== 0 && fragmenthighp.precision !== 0;\r\n                this._caps.shaderFloatPrecision = Math.min(vertexhighp.precision, fragmenthighp.precision);\r\n            }\r\n            // This will check both the capability and the `useHighPrecisionFloats` option\r\n            if (!this._shouldUseHighPrecisionShader) {\r\n                const vertexmedp = this._gl.getShaderPrecisionFormat(this._gl.VERTEX_SHADER, this._gl.MEDIUM_FLOAT);\r\n                const fragmentmedp = this._gl.getShaderPrecisionFormat(this._gl.FRAGMENT_SHADER, this._gl.MEDIUM_FLOAT);\r\n                if (vertexmedp && fragmentmedp) {\r\n                    this._caps.shaderFloatPrecision = Math.min(vertexmedp.precision, fragmentmedp.precision);\r\n                }\r\n            }\r\n            if (this._caps.shaderFloatPrecision < 10) {\r\n                // WebGL spec requires mediump precision to atleast be 10\r\n                this._caps.shaderFloatPrecision = 10;\r\n            }\r\n        }\r\n\r\n        if (this._webGLVersion > 1) {\r\n            this._caps.blendMinMax = true;\r\n        } else {\r\n            const blendMinMaxExtension = this._gl.getExtension(\"EXT_blend_minmax\");\r\n            if (blendMinMaxExtension != null) {\r\n                this._caps.blendMinMax = true;\r\n                this._gl.MAX = blendMinMaxExtension.MAX_EXT as typeof WebGL2RenderingContext.MAX;\r\n                this._gl.MIN = blendMinMaxExtension.MIN_EXT as typeof WebGL2RenderingContext.MIN;\r\n            }\r\n        }\r\n\r\n        // sRGB buffers\r\n        // only run this if not already set to true (in the constructor, for example)\r\n        if (!this._caps.supportSRGBBuffers) {\r\n            if (this._webGLVersion > 1) {\r\n                this._caps.supportSRGBBuffers = true;\r\n                this._glSRGBExtensionValues = {\r\n                    SRGB: WebGL2RenderingContext.SRGB,\r\n                    SRGB8: WebGL2RenderingContext.SRGB8,\r\n                    SRGB8_ALPHA8: WebGL2RenderingContext.SRGB8_ALPHA8,\r\n                };\r\n            } else {\r\n                const sRGBExtension = this._gl.getExtension(\"EXT_sRGB\");\r\n\r\n                if (sRGBExtension != null) {\r\n                    this._caps.supportSRGBBuffers = true;\r\n                    this._glSRGBExtensionValues = {\r\n                        SRGB: sRGBExtension.SRGB_EXT as typeof WebGL2RenderingContext.SRGB,\r\n                        SRGB8: sRGBExtension.SRGB_ALPHA_EXT as typeof WebGL2RenderingContext.SRGB8 | EXT_sRGB[\"SRGB_ALPHA_EXT\"],\r\n                        SRGB8_ALPHA8: sRGBExtension.SRGB_ALPHA_EXT as typeof WebGL2RenderingContext.SRGB8_ALPHA8,\r\n                    };\r\n                }\r\n            }\r\n            // take into account the forced state that was provided in options\r\n            if (this._creationOptions) {\r\n                const forceSRGBBufferSupportState = (this._creationOptions as EngineOptions).forceSRGBBufferSupportState;\r\n                if (forceSRGBBufferSupportState !== undefined) {\r\n                    this._caps.supportSRGBBuffers = this._caps.supportSRGBBuffers && forceSRGBBufferSupportState;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Depth buffer\r\n        this._depthCullingState.depthTest = true;\r\n        this._depthCullingState.depthFunc = this._gl.LEQUAL;\r\n        this._depthCullingState.depthMask = true;\r\n\r\n        // Texture maps\r\n        this._maxSimultaneousTextures = this._caps.maxCombinedTexturesImageUnits;\r\n        for (let slot = 0; slot < this._maxSimultaneousTextures; slot++) {\r\n            this._nextFreeTextureSlots.push(slot);\r\n        }\r\n\r\n        if (this._glRenderer === \"Mali-G72\") {\r\n            // Overcome a bug when using a texture to store morph targets on Mali-G72\r\n            this._caps.disableMorphTargetTexture = true;\r\n        }\r\n    }\r\n\r\n    protected _initFeatures(): void {\r\n        this._features = {\r\n            forceBitmapOverHTMLImageElement: typeof HTMLImageElement === \"undefined\",\r\n            supportRenderAndCopyToLodForFloatTextures: this._webGLVersion !== 1,\r\n            supportDepthStencilTexture: this._webGLVersion !== 1,\r\n            supportShadowSamplers: this._webGLVersion !== 1,\r\n            uniformBufferHardCheckMatrix: false,\r\n            allowTexturePrefiltering: this._webGLVersion !== 1,\r\n            trackUbosInFrame: false,\r\n            checkUbosContentBeforeUpload: false,\r\n            supportCSM: this._webGLVersion !== 1,\r\n            basisNeedsPOT: this._webGLVersion === 1,\r\n            support3DTextures: this._webGLVersion !== 1,\r\n            needTypeSuffixInShaderConstants: this._webGLVersion !== 1,\r\n            supportMSAA: this._webGLVersion !== 1,\r\n            supportSSAO2: this._webGLVersion !== 1,\r\n            supportIBLShadows: this._webGLVersion !== 1,\r\n            supportExtendedTextureFormats: this._webGLVersion !== 1,\r\n            supportSwitchCaseInShader: this._webGLVersion !== 1,\r\n            supportSyncTextureRead: true,\r\n            needsInvertingBitmap: true,\r\n            useUBOBindingCache: true,\r\n            needShaderCodeInlining: false,\r\n            needToAlwaysBindUniformBuffers: false,\r\n            supportRenderPasses: false,\r\n            supportSpriteInstancing: true,\r\n            forceVertexBufferStrideAndOffsetMultiple4Bytes: false,\r\n            _checkNonFloatVertexBuffersDontRecreatePipelineContext: false,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets version of the current webGL context\r\n     * Keep it for back compat - use version instead\r\n     */\r\n    public get webGLVersion(): number {\r\n        return this._webGLVersion;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"Engine\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ThinEngine\";\r\n    }\r\n\r\n    /** @internal */\r\n    public _prepareWorkingCanvas(): void {\r\n        if (this._workingCanvas) {\r\n            return;\r\n        }\r\n\r\n        this._workingCanvas = this.createCanvas(1, 1);\r\n        const context = this._workingCanvas.getContext(\"2d\");\r\n\r\n        if (context) {\r\n            this._workingContext = context;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets an object containing information about the current engine context\r\n     * @returns an object containing the vendor, the renderer and the version of the current engine context\r\n     */\r\n    public getInfo() {\r\n        return this.getGlInfo();\r\n    }\r\n\r\n    /**\r\n     * Gets an object containing information about the current webGL context\r\n     * @returns an object containing the vendor, the renderer and the version of the current webGL context\r\n     */\r\n    public getGlInfo() {\r\n        return {\r\n            vendor: this._glVendor,\r\n            renderer: this._glRenderer,\r\n            version: this._glVersion,\r\n        };\r\n    }\r\n\r\n    /**Gets driver info if available */\r\n    public extractDriverInfo() {\r\n        const glInfo = this.getGlInfo();\r\n        if (glInfo && glInfo.renderer) {\r\n            return glInfo.renderer;\r\n        }\r\n\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * Gets the current render width\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render width\r\n     */\r\n    public getRenderWidth(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.width;\r\n        }\r\n\r\n        return this._framebufferDimensionsObject ? this._framebufferDimensionsObject.framebufferWidth : this._gl.drawingBufferWidth;\r\n    }\r\n\r\n    /**\r\n     * Gets the current render height\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render height\r\n     */\r\n    public getRenderHeight(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.height;\r\n        }\r\n\r\n        return this._framebufferDimensionsObject ? this._framebufferDimensionsObject.framebufferHeight : this._gl.drawingBufferHeight;\r\n    }\r\n\r\n    /**\r\n     * Clear the current render buffer or the current render target (if any is set up)\r\n     * @param color defines the color to use\r\n     * @param backBuffer defines if the back buffer must be cleared\r\n     * @param depth defines if the depth buffer must be cleared\r\n     * @param stencil defines if the stencil buffer must be cleared\r\n     * @param stencilClearValue defines the value to use to clear the stencil buffer (default is 0)\r\n     */\r\n    public clear(color: Nullable<IColor4Like>, backBuffer: boolean, depth: boolean, stencil: boolean = false, stencilClearValue = 0): void {\r\n        const useStencilGlobalOnly = this.stencilStateComposer.useStencilGlobalOnly;\r\n        this.stencilStateComposer.useStencilGlobalOnly = true; // make sure the stencil mask is coming from the global stencil and not from a material (effect) which would currently be in effect\r\n\r\n        this.applyStates();\r\n\r\n        this.stencilStateComposer.useStencilGlobalOnly = useStencilGlobalOnly;\r\n\r\n        let mode = 0;\r\n        if (backBuffer && color) {\r\n            let setBackBufferColor = true;\r\n            if (this._currentRenderTarget) {\r\n                const textureFormat = this._currentRenderTarget.texture?.format;\r\n                if (textureFormat !== undefined && IsIntegerTextureFormat(textureFormat)) {\r\n                    const textureType = this._currentRenderTarget.texture?.type;\r\n                    if (textureType !== undefined && IsUnsignedIntegerTextureType(textureType)) {\r\n                        ThinEngine._TempClearColorUint32[0] = color.r * 255;\r\n                        ThinEngine._TempClearColorUint32[1] = color.g * 255;\r\n                        ThinEngine._TempClearColorUint32[2] = color.b * 255;\r\n                        ThinEngine._TempClearColorUint32[3] = color.a * 255;\r\n                        this._gl.clearBufferuiv(this._gl.COLOR, 0, ThinEngine._TempClearColorUint32);\r\n                        setBackBufferColor = false;\r\n                    } else {\r\n                        ThinEngine._TempClearColorInt32[0] = color.r * 255;\r\n                        ThinEngine._TempClearColorInt32[1] = color.g * 255;\r\n                        ThinEngine._TempClearColorInt32[2] = color.b * 255;\r\n                        ThinEngine._TempClearColorInt32[3] = color.a * 255;\r\n                        this._gl.clearBufferiv(this._gl.COLOR, 0, ThinEngine._TempClearColorInt32);\r\n                        setBackBufferColor = false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (setBackBufferColor) {\r\n                this._gl.clearColor(color.r, color.g, color.b, color.a !== undefined ? color.a : 1.0);\r\n                mode |= this._gl.COLOR_BUFFER_BIT;\r\n            }\r\n        }\r\n\r\n        if (depth) {\r\n            if (this.useReverseDepthBuffer) {\r\n                this._depthCullingState.depthFunc = this._gl.GEQUAL;\r\n                this._gl.clearDepth(0.0);\r\n            } else {\r\n                this._gl.clearDepth(1.0);\r\n            }\r\n            mode |= this._gl.DEPTH_BUFFER_BIT;\r\n        }\r\n        if (stencil) {\r\n            this._gl.clearStencil(stencilClearValue);\r\n            mode |= this._gl.STENCIL_BUFFER_BIT;\r\n        }\r\n        this._gl.clear(mode);\r\n    }\r\n\r\n    /**\r\n     * Clears one color attachment using the operation required by its texture format.\r\n     * @param attachmentIndex The color attachment index.\r\n     * @param color The clear value.\r\n     * @param format The texture format.\r\n     * @param type The texture type.\r\n     * @internal\r\n     */\r\n    public _clearColorAttachment(attachmentIndex: number, color: IColor4Like, format: number, type: number): void {\r\n        if (IsIntegerTextureFormat(format)) {\r\n            const unsigned = IsUnsignedIntegerTextureType(type);\r\n            const values = unsigned ? ThinEngine._TempClearColorUint32 : ThinEngine._TempClearColorInt32;\r\n\r\n            values[0] = color.r;\r\n            values[1] = color.g;\r\n            values[2] = color.b;\r\n            values[3] = color.a;\r\n            if (unsigned) {\r\n                this._gl.clearBufferuiv(this._gl.COLOR, attachmentIndex, values as Uint32Array);\r\n            } else {\r\n                this._gl.clearBufferiv(this._gl.COLOR, attachmentIndex, values as Int32Array);\r\n            }\r\n            return;\r\n        }\r\n\r\n        ThinEngine._TempClearColorFloat32[0] = color.r;\r\n        ThinEngine._TempClearColorFloat32[1] = color.g;\r\n        ThinEngine._TempClearColorFloat32[2] = color.b;\r\n        ThinEngine._TempClearColorFloat32[3] = color.a;\r\n        this._gl.clearBufferfv(this._gl.COLOR, attachmentIndex, ThinEngine._TempClearColorFloat32);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _viewport(x: number, y: number, width: number, height: number): void {\r\n        if (x !== this._viewportCached.x || y !== this._viewportCached.y || width !== this._viewportCached.z || height !== this._viewportCached.w) {\r\n            this._viewportCached.x = x;\r\n            this._viewportCached.y = y;\r\n            this._viewportCached.z = width;\r\n            this._viewportCached.w = height;\r\n\r\n            this._gl.viewport(x, y, width, height);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * End the current frame\r\n     */\r\n    public override endFrame(): void {\r\n        super.endFrame();\r\n        // Force a flush in case we are using a bad OS.\r\n        if (this._badOS) {\r\n            this.flushFramebuffer();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the performance monitor attached to this engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n     */\r\n    public get performanceMonitor(): PerformanceMonitor {\r\n        throw new Error(\"Not Supported by ThinEngine\");\r\n    }\r\n\r\n    /**\r\n     * Binds the frame buffer to the specified texture.\r\n     * @param rtWrapper The render target wrapper to render to\r\n     * @param faceIndex The face of the texture to render to in case of cube texture and if the render target wrapper is not a multi render target\r\n     * @param requiredWidth The width of the target to render to\r\n     * @param requiredHeight The height of the target to render to\r\n     * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true\r\n     * @param lodLevel Defines the lod level to bind to the frame buffer\r\n     * @param layer Defines the 2d array index to bind to the frame buffer if the render target wrapper is not a multi render target\r\n     */\r\n    public bindFramebuffer(\r\n        rtWrapper: RenderTargetWrapper,\r\n        faceIndex: number = 0,\r\n        requiredWidth?: number,\r\n        requiredHeight?: number,\r\n        forceFullscreenViewport?: boolean,\r\n        lodLevel = 0,\r\n        layer = 0\r\n    ): void {\r\n        const webglRtWrapper = rtWrapper as WebGLRenderTargetWrapper;\r\n\r\n        if (this._currentRenderTarget) {\r\n            this._resolveAndGenerateMipMapsFramebuffer(this._currentRenderTarget);\r\n        }\r\n        this._currentRenderTarget = rtWrapper;\r\n        this._integerMRTAttachmentsMask = !rtWrapper.isMulti && rtWrapper.texture && IsIntegerTextureFormat(rtWrapper.texture.format) ? 1 : 0;\r\n        this._bindUnboundFramebuffer(webglRtWrapper._framebuffer);\r\n\r\n        const gl = this._gl;\r\n        if (!rtWrapper.isMulti) {\r\n            if (rtWrapper.is2DArray || rtWrapper.is3D) {\r\n                gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, rtWrapper.texture!._hardwareTexture?.underlyingResource, lodLevel, layer);\r\n                webglRtWrapper._currentLOD = lodLevel;\r\n            } else if (rtWrapper.isCube) {\r\n                gl.framebufferTexture2D(\r\n                    gl.FRAMEBUFFER,\r\n                    gl.COLOR_ATTACHMENT0,\r\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex,\r\n                    rtWrapper.texture!._hardwareTexture?.underlyingResource,\r\n                    lodLevel\r\n                );\r\n            } else if (webglRtWrapper._currentLOD !== lodLevel) {\r\n                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, rtWrapper.texture!._hardwareTexture?.underlyingResource, lodLevel);\r\n                webglRtWrapper._currentLOD = lodLevel;\r\n            }\r\n        }\r\n\r\n        const depthStencilTexture = rtWrapper._depthStencilTexture;\r\n        if (depthStencilTexture) {\r\n            if (rtWrapper.is3D) {\r\n                if (\r\n                    rtWrapper.texture!.width !== depthStencilTexture.width ||\r\n                    rtWrapper.texture!.height !== depthStencilTexture.height ||\r\n                    rtWrapper.texture!.depth !== depthStencilTexture.depth\r\n                ) {\r\n                    Logger.Warn(\"Depth/Stencil attachment for 3D target must have same dimensions as color attachment\");\r\n                }\r\n            }\r\n            const attachment = rtWrapper._depthStencilTextureWithStencil ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;\r\n            if (rtWrapper.is2DArray || rtWrapper.is3D) {\r\n                gl.framebufferTextureLayer(gl.FRAMEBUFFER, attachment, depthStencilTexture._hardwareTexture?.underlyingResource, lodLevel, layer);\r\n            } else if (rtWrapper.isCube) {\r\n                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, depthStencilTexture._hardwareTexture?.underlyingResource, lodLevel);\r\n            } else {\r\n                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, depthStencilTexture._hardwareTexture?.underlyingResource, lodLevel);\r\n            }\r\n        }\r\n\r\n        if (webglRtWrapper._MSAAFramebuffer) {\r\n            this._bindUnboundFramebuffer(webglRtWrapper._MSAAFramebuffer);\r\n        }\r\n\r\n        if (this._cachedViewport && !forceFullscreenViewport) {\r\n            this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);\r\n        } else {\r\n            if (!requiredWidth) {\r\n                requiredWidth = rtWrapper.width;\r\n                if (lodLevel) {\r\n                    requiredWidth = requiredWidth / Math.pow(2, lodLevel);\r\n                }\r\n            }\r\n            if (!requiredHeight) {\r\n                requiredHeight = rtWrapper.height;\r\n                if (lodLevel) {\r\n                    requiredHeight = requiredHeight / Math.pow(2, lodLevel);\r\n                }\r\n            }\r\n\r\n            this._viewport(0, 0, requiredWidth, requiredHeight);\r\n        }\r\n\r\n        this.wipeCaches();\r\n    }\r\n\r\n    public override setStateCullFaceType(cullBackFaces?: boolean, force?: boolean): void {\r\n        const cullFace = (this.cullBackFaces ?? cullBackFaces ?? true) ? this._gl.BACK : this._gl.FRONT;\r\n        if (this._depthCullingState.cullFace !== cullFace || force) {\r\n            this._depthCullingState.cullFace = cullFace;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set various states to the webGL context\r\n     * @param culling defines culling state: true to enable culling, false to disable it\r\n     * @param zOffset defines the value to apply to zOffset (0 by default)\r\n     * @param force defines if states must be applied even if cache is up to date\r\n     * @param reverseSide defines if culling must be reversed (CCW if false, CW if true)\r\n     * @param cullBackFaces true to cull back faces, false to cull front faces (if culling is enabled)\r\n     * @param stencil stencil states to set\r\n     * @param zOffsetUnits defines the value to apply to zOffsetUnits (0 by default)\r\n     */\r\n    public setState(culling: boolean, zOffset: number = 0, force?: boolean, reverseSide = false, cullBackFaces?: boolean, stencil?: IStencilState, zOffsetUnits: number = 0): void {\r\n        // Culling\r\n        if (this._depthCullingState.cull !== culling || force) {\r\n            this._depthCullingState.cull = culling;\r\n        }\r\n\r\n        // Cull face\r\n        this.setStateCullFaceType(cullBackFaces, force);\r\n\r\n        // Z offset\r\n        this.setZOffset(zOffset);\r\n        this.setZOffsetUnits(zOffsetUnits);\r\n\r\n        // Front face\r\n        const frontFace = reverseSide ? this._gl.CW : this._gl.CCW;\r\n        if (this._depthCullingState.frontFace !== frontFace || force) {\r\n            this._depthCullingState.frontFace = frontFace;\r\n        }\r\n\r\n        this._stencilStateComposer.stencilMaterial = stencil;\r\n    }\r\n\r\n    private _resolveAndGenerateMipMapsFramebuffer(texture: RenderTargetWrapper, disableGenerateMipMaps = false): void {\r\n        const webglRtWrapper = texture as WebGLRenderTargetWrapper;\r\n\r\n        if (!webglRtWrapper.disableAutomaticMSAAResolve) {\r\n            if (texture.isMulti) {\r\n                this.resolveMultiFramebuffer(texture);\r\n            } else {\r\n                this.resolveFramebuffer(texture);\r\n            }\r\n        }\r\n\r\n        if (!disableGenerateMipMaps) {\r\n            if (texture.isMulti) {\r\n                this.generateMipMapsMultiFramebuffer(texture);\r\n            } else {\r\n                this.generateMipMapsFramebuffer(texture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindUnboundFramebuffer(framebuffer: Nullable<WebGLFramebuffer>) {\r\n        if (this._currentFramebuffer !== framebuffer) {\r\n            this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, framebuffer);\r\n            this._currentFramebuffer = framebuffer;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _currentFrameBufferIsDefaultFrameBuffer() {\r\n        return this._currentFramebuffer === null;\r\n    }\r\n\r\n    /**\r\n     * Generates the mipmaps for a texture\r\n     * @param texture texture to generate the mipmaps for\r\n     */\r\n    public generateMipmaps(texture: InternalTexture): void {\r\n        const target = this._getTextureTarget(texture);\r\n        this._bindTextureDirectly(target, texture, true);\r\n        this._gl.generateMipmap(target);\r\n        this._bindTextureDirectly(target, null);\r\n    }\r\n\r\n    /**\r\n     * Unbind the current render target texture from the webGL context\r\n     * @param texture defines the render target wrapper to unbind\r\n     * @param disableGenerateMipMaps defines a boolean indicating that mipmaps must not be generated\r\n     * @param onBeforeUnbind defines a function which will be called before the effective unbind\r\n     */\r\n    public unBindFramebuffer(texture: RenderTargetWrapper, disableGenerateMipMaps?: boolean, onBeforeUnbind?: () => void): void {\r\n        const webglRtWrapper = texture as WebGLRenderTargetWrapper;\r\n\r\n        this._currentRenderTarget = null;\r\n        this._integerMRTAttachmentsMask = 0;\r\n        this._resolveAndGenerateMipMapsFramebuffer(texture, disableGenerateMipMaps);\r\n\r\n        if (onBeforeUnbind) {\r\n            if (webglRtWrapper._MSAAFramebuffer) {\r\n                // Bind the correct framebuffer\r\n                this._bindUnboundFramebuffer(webglRtWrapper._framebuffer);\r\n            }\r\n            onBeforeUnbind();\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(null);\r\n    }\r\n\r\n    /**\r\n     * Generates mipmaps for the texture of the (single) render target\r\n     * @param texture The render target containing the texture to generate the mipmaps for\r\n     */\r\n    public generateMipMapsFramebuffer(texture: RenderTargetWrapper): void {\r\n        if (!texture.isMulti && texture.texture?.generateMipMaps && !texture.isCube) {\r\n            this.generateMipmaps(texture.texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resolves the MSAA texture of the (single) render target into its non-MSAA version.\r\n     * Note that if \"texture\" is not a MSAA render target, no resolve is performed.\r\n     * @param texture  The render target texture containing the MSAA textures to resolve\r\n     */\r\n    public resolveFramebuffer(texture: RenderTargetWrapper): void {\r\n        const rtWrapper = texture as WebGLRenderTargetWrapper;\r\n        const gl = this._gl;\r\n\r\n        if (!rtWrapper._MSAAFramebuffer || rtWrapper.isMulti) {\r\n            return;\r\n        }\r\n\r\n        let bufferBits = rtWrapper.resolveMSAAColors ? gl.COLOR_BUFFER_BIT : 0;\r\n        bufferBits |= rtWrapper._generateDepthBuffer && rtWrapper.resolveMSAADepth ? gl.DEPTH_BUFFER_BIT : 0;\r\n        bufferBits |= rtWrapper._generateStencilBuffer && rtWrapper.resolveMSAAStencil ? gl.STENCIL_BUFFER_BIT : 0;\r\n\r\n        gl.bindFramebuffer(gl.READ_FRAMEBUFFER, rtWrapper._MSAAFramebuffer);\r\n        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, rtWrapper._framebuffer);\r\n        gl.blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width, texture.height, bufferBits, gl.NEAREST);\r\n    }\r\n\r\n    /**\r\n     * Force a webGL flush (ie. a flush of all waiting webGL commands)\r\n     */\r\n    public flushFramebuffer(): void {\r\n        this._gl.flush();\r\n    }\r\n\r\n    /**\r\n     * Unbind the current render target and bind the default framebuffer\r\n     */\r\n    public restoreDefaultFramebuffer(): void {\r\n        if (this._currentRenderTarget) {\r\n            this.unBindFramebuffer(this._currentRenderTarget);\r\n        } else {\r\n            this._bindUnboundFramebuffer(null);\r\n        }\r\n        if (this._cachedViewport) {\r\n            this.setViewport(this._cachedViewport);\r\n        }\r\n\r\n        this.wipeCaches();\r\n    }\r\n\r\n    // VBOs\r\n\r\n    /** @internal */\r\n    protected _resetVertexBufferBinding(): void {\r\n        this.bindArrayBuffer(null);\r\n        this._cachedVertexBuffers = null;\r\n    }\r\n\r\n    /**\r\n     * Creates a vertex buffer\r\n     * @param data the data or size for the vertex buffer\r\n     * @param _updatable whether the buffer should be created as updatable\r\n     * @param _label defines the label of the buffer (for debug purpose)\r\n     * @returns the new WebGL static buffer\r\n     */\r\n    public createVertexBuffer(data: DataArray | number, _updatable?: boolean, _label?: string): DataBuffer {\r\n        return this._createVertexBuffer(data, this._gl.STATIC_DRAW);\r\n    }\r\n\r\n    private _createVertexBuffer(data: DataArray | number, usage: number): DataBuffer {\r\n        const vbo = this._gl.createBuffer();\r\n\r\n        if (!vbo) {\r\n            throw new Error(\"Unable to create vertex buffer\");\r\n        }\r\n\r\n        const dataBuffer = new WebGLDataBuffer(vbo);\r\n        this.bindArrayBuffer(dataBuffer);\r\n\r\n        if (typeof data !== \"number\") {\r\n            if (data instanceof Array) {\r\n                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), usage);\r\n                dataBuffer.capacity = data.length * 4;\r\n            } else {\r\n                this._gl.bufferData(this._gl.ARRAY_BUFFER, <ArrayBuffer>data, usage);\r\n                dataBuffer.capacity = data.byteLength;\r\n            }\r\n        } else {\r\n            this._gl.bufferData(this._gl.ARRAY_BUFFER, new Uint8Array(data), usage);\r\n            dataBuffer.capacity = data;\r\n        }\r\n\r\n        this._resetVertexBufferBinding();\r\n\r\n        dataBuffer.references = 1;\r\n        return dataBuffer;\r\n    }\r\n\r\n    /**\r\n     * Creates a dynamic vertex buffer\r\n     * @param data the data for the dynamic vertex buffer\r\n     * @param _label defines the label of the buffer (for debug purpose)\r\n     * @returns the new WebGL dynamic buffer\r\n     */\r\n    public createDynamicVertexBuffer(data: DataArray | number, _label?: string): DataBuffer {\r\n        return this._createVertexBuffer(data, this._gl.DYNAMIC_DRAW);\r\n    }\r\n\r\n    protected _resetIndexBufferBinding(): void {\r\n        this.bindIndexBuffer(null);\r\n        this._cachedIndexBuffer = null;\r\n    }\r\n\r\n    /**\r\n     * Creates a new index buffer\r\n     * @param indices defines the content of the index buffer\r\n     * @param updatable defines if the index buffer must be updatable\r\n     * @param _label defines the label of the buffer (for debug purpose)\r\n     * @returns a new webGL buffer\r\n     */\r\n    public createIndexBuffer(indices: IndicesArray, updatable?: boolean, _label?: string): DataBuffer {\r\n        const vbo = this._gl.createBuffer();\r\n        const dataBuffer = new WebGLDataBuffer(vbo);\r\n\r\n        if (!vbo) {\r\n            throw new Error(\"Unable to create index buffer\");\r\n        }\r\n\r\n        this.bindIndexBuffer(dataBuffer);\r\n\r\n        const data = this._normalizeIndexData(indices);\r\n        this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, data, updatable ? this._gl.DYNAMIC_DRAW : this._gl.STATIC_DRAW);\r\n        this._resetIndexBufferBinding();\r\n        dataBuffer.references = 1;\r\n        dataBuffer.is32Bits = data.BYTES_PER_ELEMENT === 4;\r\n        return dataBuffer;\r\n    }\r\n\r\n    protected _normalizeIndexData(indices: IndicesArray): Uint16Array | Uint32Array {\r\n        const bytesPerElement = (indices as Exclude<IndicesArray, number[]>).BYTES_PER_ELEMENT;\r\n        if (bytesPerElement === 2) {\r\n            return indices as Uint16Array;\r\n        }\r\n\r\n        // Check 32 bit support\r\n        if (this._caps.uintIndices) {\r\n            if (indices instanceof Uint32Array) {\r\n                return indices;\r\n            } else {\r\n                // number[] or Int32Array, check if 32 bit is necessary\r\n                for (let index = 0; index < indices.length; index++) {\r\n                    if (indices[index] >= 65535) {\r\n                        return new Uint32Array(indices);\r\n                    }\r\n                }\r\n\r\n                return new Uint16Array(indices);\r\n            }\r\n        }\r\n\r\n        // No 32 bit support, force conversion to 16 bit (values greater 16 bit are lost)\r\n        return new Uint16Array(indices);\r\n    }\r\n\r\n    /**\r\n     * Bind a webGL buffer to the webGL context\r\n     * @param buffer defines the buffer to bind\r\n     */\r\n    public bindArrayBuffer(buffer: Nullable<DataBuffer>): void {\r\n        if (!this._vaoRecordInProgress) {\r\n            this._unbindVertexArrayObject();\r\n        }\r\n        this._bindBuffer(buffer, this._gl.ARRAY_BUFFER);\r\n    }\r\n\r\n    /**\r\n     * Bind a specific block at a given index in a specific shader program\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param blockName defines the block name\r\n     * @param index defines the index where to bind the block\r\n     */\r\n    public bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void {\r\n        const program = (pipelineContext as WebGLPipelineContext).program!;\r\n\r\n        const uniformLocation = this._gl.getUniformBlockIndex(program, blockName);\r\n\r\n        this._gl.uniformBlockBinding(program, uniformLocation, index);\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected bindIndexBuffer(buffer: Nullable<DataBuffer>): void {\r\n        if (!this._vaoRecordInProgress) {\r\n            this._unbindVertexArrayObject();\r\n        }\r\n        this._bindBuffer(buffer, this._gl.ELEMENT_ARRAY_BUFFER);\r\n    }\r\n\r\n    private _bindBuffer(buffer: Nullable<DataBuffer>, target: number): void {\r\n        if (this._vaoRecordInProgress || this._currentBoundBuffer[target] !== buffer) {\r\n            this._gl.bindBuffer(target, buffer ? buffer.underlyingResource : null);\r\n            this._currentBoundBuffer[target] = buffer;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * update the bound buffer with the given data\r\n     * @param data defines the data to update\r\n     */\r\n    public updateArrayBuffer(data: Float32Array): void {\r\n        this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);\r\n    }\r\n\r\n    private _vertexAttribPointer(buffer: DataBuffer, indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number): void {\r\n        const pointer = this._currentBufferPointers[indx];\r\n        if (!pointer) {\r\n            return;\r\n        }\r\n\r\n        let changed = false;\r\n        if (!pointer.active) {\r\n            changed = true;\r\n            pointer.active = true;\r\n            pointer.index = indx;\r\n            pointer.size = size;\r\n            pointer.type = type;\r\n            pointer.normalized = normalized;\r\n            pointer.stride = stride;\r\n            pointer.offset = offset;\r\n            pointer.buffer = buffer;\r\n        } else {\r\n            if (pointer.buffer !== buffer) {\r\n                pointer.buffer = buffer;\r\n                changed = true;\r\n            }\r\n            if (pointer.size !== size) {\r\n                pointer.size = size;\r\n                changed = true;\r\n            }\r\n            if (pointer.type !== type) {\r\n                pointer.type = type;\r\n                changed = true;\r\n            }\r\n            if (pointer.normalized !== normalized) {\r\n                pointer.normalized = normalized;\r\n                changed = true;\r\n            }\r\n            if (pointer.stride !== stride) {\r\n                pointer.stride = stride;\r\n                changed = true;\r\n            }\r\n            if (pointer.offset !== offset) {\r\n                pointer.offset = offset;\r\n                changed = true;\r\n            }\r\n        }\r\n\r\n        if (changed || this._vaoRecordInProgress) {\r\n            this.bindArrayBuffer(buffer);\r\n            if (type === this._gl.UNSIGNED_INT || type === this._gl.INT) {\r\n                this._gl.vertexAttribIPointer(indx, size, type, stride, offset);\r\n            } else {\r\n                this._gl.vertexAttribPointer(indx, size, type, normalized, stride, offset);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindIndexBufferWithCache(indexBuffer: Nullable<DataBuffer>): void {\r\n        if (indexBuffer == null) {\r\n            return;\r\n        }\r\n        if (this._cachedIndexBuffer !== indexBuffer) {\r\n            this._cachedIndexBuffer = indexBuffer;\r\n            this.bindIndexBuffer(indexBuffer);\r\n            this._uintIndicesCurrentlySet = indexBuffer.is32Bits;\r\n        }\r\n    }\r\n\r\n    private _bindVertexBuffersAttributes(\r\n        vertexBuffers: { [key: string]: Nullable<VertexBuffer> },\r\n        effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): void {\r\n        const attributes = effect.getAttributesNames();\r\n\r\n        if (!this._vaoRecordInProgress) {\r\n            this._unbindVertexArrayObject();\r\n        }\r\n\r\n        this.unbindAllAttributes();\r\n\r\n        for (let index = 0; index < attributes.length; index++) {\r\n            const order = effect.getAttributeLocation(index);\r\n\r\n            if (order >= 0) {\r\n                const ai = attributes[index];\r\n                let vertexBuffer: Nullable<VertexBuffer> = null;\r\n\r\n                if (overrideVertexBuffers) {\r\n                    vertexBuffer = overrideVertexBuffers[ai];\r\n                }\r\n\r\n                if (!vertexBuffer) {\r\n                    vertexBuffer = vertexBuffers[ai];\r\n                }\r\n\r\n                if (!vertexBuffer) {\r\n                    continue;\r\n                }\r\n\r\n                this._gl.enableVertexAttribArray(order);\r\n                if (!this._vaoRecordInProgress) {\r\n                    this._vertexAttribArraysEnabled[order] = true;\r\n                }\r\n\r\n                const buffer = vertexBuffer.getBuffer();\r\n                if (buffer) {\r\n                    this._vertexAttribPointer(buffer, order, vertexBuffer.getSize(), vertexBuffer.type, vertexBuffer.normalized, vertexBuffer.byteStride, vertexBuffer.byteOffset);\r\n\r\n                    if (vertexBuffer.getIsInstanced()) {\r\n                        this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());\r\n                        if (!this._vaoRecordInProgress) {\r\n                            this._currentInstanceLocations.push(order);\r\n                            this._currentInstanceBuffers.push(buffer);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Records a vertex array object\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#vertex-array-objects\r\n     * @param vertexBuffers defines the list of vertex buffers to store\r\n     * @param indexBuffer defines the index buffer to store\r\n     * @param effect defines the effect to store\r\n     * @param overrideVertexBuffers defines optional list of avertex buffers that overrides the entries in vertexBuffers\r\n     * @returns the new vertex array object\r\n     */\r\n    public recordVertexArrayObject(\r\n        vertexBuffers: { [key: string]: VertexBuffer },\r\n        indexBuffer: Nullable<DataBuffer>,\r\n        effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): WebGLVertexArrayObject {\r\n        const vao = this._gl.createVertexArray();\r\n\r\n        if (!vao) {\r\n            throw new Error(\"Unable to create VAO\");\r\n        }\r\n\r\n        this._vaoRecordInProgress = true;\r\n\r\n        this._gl.bindVertexArray(vao);\r\n\r\n        this._mustWipeVertexAttributes = true;\r\n        this._bindVertexBuffersAttributes(vertexBuffers, effect, overrideVertexBuffers);\r\n\r\n        this.bindIndexBuffer(indexBuffer);\r\n\r\n        this._vaoRecordInProgress = false;\r\n        this._gl.bindVertexArray(null);\r\n\r\n        return vao;\r\n    }\r\n\r\n    /**\r\n     * Bind a specific vertex array object\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#vertex-array-objects\r\n     * @param vertexArrayObject defines the vertex array object to bind\r\n     * @param indexBuffer defines the index buffer to bind\r\n     */\r\n    public bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<DataBuffer>): void {\r\n        if (this._cachedVertexArrayObject !== vertexArrayObject) {\r\n            this._cachedVertexArrayObject = vertexArrayObject;\r\n\r\n            this._gl.bindVertexArray(vertexArrayObject);\r\n            this._cachedVertexBuffers = null;\r\n            this._cachedIndexBuffer = null;\r\n\r\n            this._uintIndicesCurrentlySet = indexBuffer != null && indexBuffer.is32Bits;\r\n            this._mustWipeVertexAttributes = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind webGl buffers directly to the webGL context\r\n     * @param vertexBuffer defines the vertex buffer to bind\r\n     * @param indexBuffer defines the index buffer to bind\r\n     * @param vertexDeclaration defines the vertex declaration to use with the vertex buffer\r\n     * @param vertexStrideSize defines the vertex stride of the vertex buffer\r\n     * @param effect defines the effect associated with the vertex buffer\r\n     */\r\n    public bindBuffersDirectly(vertexBuffer: DataBuffer, indexBuffer: DataBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void {\r\n        if (this._cachedVertexBuffers !== vertexBuffer || this._cachedEffectForVertexBuffers !== effect) {\r\n            this._cachedVertexBuffers = vertexBuffer;\r\n            this._cachedEffectForVertexBuffers = effect;\r\n\r\n            const attributesCount = effect.getAttributesCount();\r\n\r\n            this._unbindVertexArrayObject();\r\n            this.unbindAllAttributes();\r\n\r\n            let offset = 0;\r\n            for (let index = 0; index < attributesCount; index++) {\r\n                if (index < vertexDeclaration.length) {\r\n                    const order = effect.getAttributeLocation(index);\r\n\r\n                    if (order >= 0) {\r\n                        this._gl.enableVertexAttribArray(order);\r\n                        this._vertexAttribArraysEnabled[order] = true;\r\n                        this._vertexAttribPointer(vertexBuffer, order, vertexDeclaration[index], this._gl.FLOAT, false, vertexStrideSize, offset);\r\n                    }\r\n\r\n                    offset += vertexDeclaration[index] * 4;\r\n                }\r\n            }\r\n        }\r\n\r\n        this._bindIndexBufferWithCache(indexBuffer);\r\n    }\r\n\r\n    private _unbindVertexArrayObject(): void {\r\n        if (!this._cachedVertexArrayObject) {\r\n            return;\r\n        }\r\n\r\n        this._cachedVertexArrayObject = null;\r\n        this._gl.bindVertexArray(null);\r\n    }\r\n\r\n    /**\r\n     * Bind a list of vertex buffers to the webGL context\r\n     * @param vertexBuffers defines the list of vertex buffers to bind\r\n     * @param indexBuffer defines the index buffer to bind\r\n     * @param effect defines the effect associated with the vertex buffers\r\n     * @param overrideVertexBuffers defines optional list of avertex buffers that overrides the entries in vertexBuffers\r\n     */\r\n    public bindBuffers(\r\n        vertexBuffers: { [key: string]: Nullable<VertexBuffer> },\r\n        indexBuffer: Nullable<DataBuffer>,\r\n        effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): void {\r\n        if (this._cachedVertexBuffers !== vertexBuffers || this._cachedEffectForVertexBuffers !== effect) {\r\n            this._cachedVertexBuffers = vertexBuffers;\r\n            this._cachedEffectForVertexBuffers = effect;\r\n\r\n            this._bindVertexBuffersAttributes(vertexBuffers, effect, overrideVertexBuffers);\r\n        }\r\n\r\n        this._bindIndexBufferWithCache(indexBuffer);\r\n    }\r\n\r\n    /**\r\n     * Unbind all instance attributes\r\n     */\r\n    public unbindInstanceAttributes() {\r\n        let boundBuffer;\r\n        for (let i = 0, ul = this._currentInstanceLocations.length; i < ul; i++) {\r\n            const instancesBuffer = this._currentInstanceBuffers[i];\r\n            if (boundBuffer != instancesBuffer && instancesBuffer.references) {\r\n                boundBuffer = instancesBuffer;\r\n                this.bindArrayBuffer(instancesBuffer);\r\n            }\r\n            const offsetLocation = this._currentInstanceLocations[i];\r\n            this._gl.vertexAttribDivisor(offsetLocation, 0);\r\n        }\r\n        this._currentInstanceBuffers.length = 0;\r\n        this._currentInstanceLocations.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Release and free the memory of a vertex array object\r\n     * @param vao defines the vertex array object to delete\r\n     */\r\n    public releaseVertexArrayObject(vao: WebGLVertexArrayObject) {\r\n        this._gl.deleteVertexArray(vao);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseBuffer(buffer: DataBuffer): boolean {\r\n        buffer.references--;\r\n\r\n        if (buffer.references === 0) {\r\n            this._deleteBuffer(buffer);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    protected _deleteBuffer(buffer: DataBuffer): void {\r\n        this._gl.deleteBuffer(buffer.underlyingResource);\r\n    }\r\n\r\n    /**\r\n     * Update the content of a webGL buffer used with instantiation and bind it to the webGL context\r\n     * @param instancesBuffer defines the webGL buffer to update and bind\r\n     * @param data defines the data to store in the buffer\r\n     * @param offsetLocations defines the offsets or attributes information used to determine where data must be stored in the buffer\r\n     */\r\n    public updateAndBindInstancesBuffer(instancesBuffer: DataBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void {\r\n        this.bindArrayBuffer(instancesBuffer);\r\n        if (data) {\r\n            this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);\r\n        }\r\n\r\n        if ((<any>offsetLocations[0]).index !== undefined) {\r\n            this.bindInstancesBuffer(instancesBuffer, offsetLocations as any, true);\r\n        } else {\r\n            for (let index = 0; index < 4; index++) {\r\n                const offsetLocation = <number>offsetLocations[index];\r\n\r\n                if (!this._vertexAttribArraysEnabled[offsetLocation]) {\r\n                    this._gl.enableVertexAttribArray(offsetLocation);\r\n                    this._vertexAttribArraysEnabled[offsetLocation] = true;\r\n                }\r\n\r\n                this._vertexAttribPointer(instancesBuffer, offsetLocation, 4, this._gl.FLOAT, false, 64, index * 16);\r\n                this._gl.vertexAttribDivisor(offsetLocation, 1);\r\n                this._currentInstanceLocations.push(offsetLocation);\r\n                this._currentInstanceBuffers.push(instancesBuffer);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind the content of a webGL buffer used with instantiation\r\n     * @param instancesBuffer defines the webGL buffer to bind\r\n     * @param attributesInfo defines the offsets or attributes information used to determine where data must be stored in the buffer\r\n     * @param computeStride defines Whether to compute the strides from the info or use the default 0\r\n     */\r\n    public bindInstancesBuffer(instancesBuffer: DataBuffer, attributesInfo: InstancingAttributeInfo[], computeStride = true): void {\r\n        this.bindArrayBuffer(instancesBuffer);\r\n\r\n        let stride = 0;\r\n        if (computeStride) {\r\n            for (let i = 0; i < attributesInfo.length; i++) {\r\n                const ai = attributesInfo[i];\r\n                stride += ai.attributeSize * 4;\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < attributesInfo.length; i++) {\r\n            const ai = attributesInfo[i];\r\n            if (ai.index === undefined) {\r\n                ai.index = this._currentEffect!.getAttributeLocationByName(ai.attributeName);\r\n            }\r\n\r\n            if (ai.index < 0) {\r\n                continue;\r\n            }\r\n\r\n            if (!this._vertexAttribArraysEnabled[ai.index]) {\r\n                this._gl.enableVertexAttribArray(ai.index);\r\n                this._vertexAttribArraysEnabled[ai.index] = true;\r\n            }\r\n\r\n            this._vertexAttribPointer(instancesBuffer, ai.index, ai.attributeSize, ai.attributeType || this._gl.FLOAT, ai.normalized || false, stride, ai.offset);\r\n            this._gl.vertexAttribDivisor(ai.index, ai.divisor === undefined ? 1 : ai.divisor);\r\n            this._currentInstanceLocations.push(ai.index);\r\n            this._currentInstanceBuffers.push(instancesBuffer);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disable the instance attribute corresponding to the name in parameter\r\n     * @param name defines the name of the attribute to disable\r\n     */\r\n    public disableInstanceAttributeByName(name: string) {\r\n        if (!this._currentEffect) {\r\n            return;\r\n        }\r\n\r\n        const attributeLocation = this._currentEffect.getAttributeLocationByName(name);\r\n        this.disableInstanceAttribute(attributeLocation);\r\n    }\r\n\r\n    /**\r\n     * Disable the instance attribute corresponding to the location in parameter\r\n     * @param attributeLocation defines the attribute location of the attribute to disable\r\n     */\r\n    public disableInstanceAttribute(attributeLocation: number) {\r\n        let shouldClean = false;\r\n        let index: number;\r\n        while ((index = this._currentInstanceLocations.indexOf(attributeLocation)) !== -1) {\r\n            this._currentInstanceLocations.splice(index, 1);\r\n            this._currentInstanceBuffers.splice(index, 1);\r\n\r\n            shouldClean = true;\r\n        }\r\n\r\n        if (shouldClean) {\r\n            this._gl.vertexAttribDivisor(attributeLocation, 0);\r\n            this.disableAttributeByIndex(attributeLocation);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disable the attribute corresponding to the location in parameter\r\n     * @param attributeLocation defines the attribute location of the attribute to disable\r\n     */\r\n    public disableAttributeByIndex(attributeLocation: number) {\r\n        this._gl.disableVertexAttribArray(attributeLocation);\r\n        this._vertexAttribArraysEnabled[attributeLocation] = false;\r\n        this._currentBufferPointers[attributeLocation].active = false;\r\n    }\r\n\r\n    /**\r\n     * Send a draw order\r\n     * @param useTriangles defines if triangles must be used to draw (else wireframe will be used)\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public draw(useTriangles: boolean, indexStart: number, indexCount: number, instancesCount?: number): void {\r\n        this.drawElementsType(useTriangles ? Constants.MATERIAL_TriangleFillMode : Constants.MATERIAL_WireFrameFillMode, indexStart, indexCount, instancesCount);\r\n    }\r\n\r\n    /**\r\n     * Draw a list of points\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public drawPointClouds(verticesStart: number, verticesCount: number, instancesCount?: number): void {\r\n        this.drawArraysType(Constants.MATERIAL_PointFillMode, verticesStart, verticesCount, instancesCount);\r\n    }\r\n\r\n    /**\r\n     * Draw a list of unindexed primitives\r\n     * @param useTriangles defines if triangles must be used to draw (else wireframe will be used)\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public drawUnIndexed(useTriangles: boolean, verticesStart: number, verticesCount: number, instancesCount?: number): void {\r\n        this.drawArraysType(useTriangles ? Constants.MATERIAL_TriangleFillMode : Constants.MATERIAL_WireFrameFillMode, verticesStart, verticesCount, instancesCount);\r\n    }\r\n\r\n    /**\r\n     * Draw a list of indexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void {\r\n        // Apply states\r\n        this.applyStates();\r\n\r\n        this._reportDrawCall();\r\n\r\n        // Render\r\n\r\n        const drawMode = this._drawMode(fillMode);\r\n        const indexFormat = this._uintIndicesCurrentlySet ? this._gl.UNSIGNED_INT : this._gl.UNSIGNED_SHORT;\r\n        const mult = this._uintIndicesCurrentlySet ? 4 : 2;\r\n        if (instancesCount) {\r\n            this._gl.drawElementsInstanced(drawMode, indexCount, indexFormat, indexStart * mult, instancesCount);\r\n        } else {\r\n            this._gl.drawElements(drawMode, indexCount, indexFormat, indexStart * mult);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Draw a list of unindexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void {\r\n        // Apply states\r\n        this.applyStates();\r\n\r\n        this._reportDrawCall();\r\n\r\n        const drawMode = this._drawMode(fillMode);\r\n        if (instancesCount) {\r\n            this._gl.drawArraysInstanced(drawMode, verticesStart, verticesCount, instancesCount);\r\n        } else {\r\n            this._gl.drawArrays(drawMode, verticesStart, verticesCount);\r\n        }\r\n    }\r\n\r\n    private _drawMode(fillMode: number): number {\r\n        switch (fillMode) {\r\n            // Triangle views\r\n            case Constants.MATERIAL_TriangleFillMode:\r\n                return this._gl.TRIANGLES;\r\n            case Constants.MATERIAL_PointFillMode:\r\n                return this._gl.POINTS;\r\n            case Constants.MATERIAL_WireFrameFillMode:\r\n                return this._gl.LINES;\r\n            // Draw modes\r\n            case Constants.MATERIAL_PointListDrawMode:\r\n                return this._gl.POINTS;\r\n            case Constants.MATERIAL_LineListDrawMode:\r\n                return this._gl.LINES;\r\n            case Constants.MATERIAL_LineLoopDrawMode:\r\n                return this._gl.LINE_LOOP;\r\n            case Constants.MATERIAL_LineStripDrawMode:\r\n                return this._gl.LINE_STRIP;\r\n            case Constants.MATERIAL_TriangleStripDrawMode:\r\n                return this._gl.TRIANGLE_STRIP;\r\n            case Constants.MATERIAL_TriangleFanDrawMode:\r\n                return this._gl.TRIANGLE_FAN;\r\n            default:\r\n                return this._gl.TRIANGLES;\r\n        }\r\n    }\r\n\r\n    // Shaders\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseEffect(effect: Effect): void {\r\n        if (this._compiledEffects[effect._key]) {\r\n            delete this._compiledEffects[effect._key];\r\n        }\r\n        const pipelineContext = effect.getPipelineContext();\r\n        if (pipelineContext) {\r\n            this._deletePipelineContext(pipelineContext);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _deletePipelineContext(pipelineContext: IPipelineContext): void {\r\n        const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n        if (webGLPipelineContext && webGLPipelineContext.program) {\r\n            webGLPipelineContext.program.__SPECTOR_rebuildProgram = null;\r\n            resetCachedPipeline(webGLPipelineContext);\r\n            if (this._gl) {\r\n                if (this._currentProgram === webGLPipelineContext.program) {\r\n                    this._setProgram(null);\r\n                }\r\n                this._gl.deleteProgram(webGLPipelineContext.program);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _getGlobalDefines(defines?: { [key: string]: string }): string | undefined {\r\n        return _GetGlobalDefines(defines, this.isNDCHalfZRange, this.useReverseDepthBuffer, this.useExactSrgbConversions);\r\n    }\r\n\r\n    /**\r\n     * Create a new effect (used to store vertex/fragment shaders)\r\n     * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)\r\n     * @param attributesNamesOrOptions defines either a list of attribute names or an IEffectCreationOptions object\r\n     * @param uniformsNamesOrEngine defines either a list of uniform names or the engine to use\r\n     * @param samplers defines an array of string used to represent textures\r\n     * @param defines defines the string containing the defines to use to compile the shaders\r\n     * @param fallbacks defines the list of potential fallbacks to use if shader compilation fails\r\n     * @param onCompiled defines a function to call when the effect creation is successful\r\n     * @param onError defines a function to call when the effect creation has failed\r\n     * @param indexParameters defines an object containing the index values to use to compile shaders (like the maximum number of simultaneous lights)\r\n     * @param shaderLanguage the language the shader is written in (default: GLSL)\r\n     * @param extraInitializationsAsync additional async code to run before preparing the effect\r\n     * @returns the new Effect\r\n     */\r\n    public createEffect(\r\n        baseName: string | (IShaderPath & { vertexToken?: string; fragmentToken?: string }),\r\n        attributesNamesOrOptions: string[] | IEffectCreationOptions,\r\n        uniformsNamesOrEngine: string[] | ThinEngine,\r\n        samplers?: string[],\r\n        defines?: string,\r\n        fallbacks?: IEffectFallbacks,\r\n        onCompiled?: Nullable<(effect: Effect) => void>,\r\n        onError?: Nullable<(effect: Effect, errors: string) => void>,\r\n        indexParameters?: any,\r\n        shaderLanguage = ShaderLanguage.GLSL,\r\n        extraInitializationsAsync?: () => Promise<void>\r\n    ): Effect {\r\n        const vertex = typeof baseName === \"string\" ? baseName : baseName.vertexToken || baseName.vertexSource || baseName.vertexElement || baseName.vertex;\r\n        const fragment = typeof baseName === \"string\" ? baseName : baseName.fragmentToken || baseName.fragmentSource || baseName.fragmentElement || baseName.fragment;\r\n        const globalDefines = this._getGlobalDefines()!;\r\n\r\n        const isOptions = (attributesNamesOrOptions as IEffectCreationOptions).attributes !== undefined;\r\n\r\n        let fullDefines = defines ?? (<IEffectCreationOptions>attributesNamesOrOptions).defines ?? \"\";\r\n\r\n        if (globalDefines) {\r\n            fullDefines += globalDefines;\r\n        }\r\n\r\n        const name = vertex + \"+\" + fragment + \"@\" + fullDefines;\r\n        if (this._compiledEffects[name]) {\r\n            const compiledEffect = this._compiledEffects[name];\r\n            if (onCompiled && compiledEffect.isReady()) {\r\n                onCompiled(compiledEffect);\r\n            }\r\n            compiledEffect._refCount++;\r\n            return compiledEffect;\r\n        }\r\n        if (this._gl) {\r\n            getStateObject(this._gl);\r\n        }\r\n        const effect = new Effect(\r\n            baseName,\r\n            attributesNamesOrOptions,\r\n            isOptions ? this : uniformsNamesOrEngine,\r\n            samplers,\r\n            this,\r\n            defines,\r\n            fallbacks,\r\n            onCompiled,\r\n            onError,\r\n            indexParameters,\r\n            name,\r\n            (<IEffectCreationOptions>attributesNamesOrOptions).shaderLanguage ?? shaderLanguage,\r\n            (<IEffectCreationOptions>attributesNamesOrOptions).extraInitializationsAsync ?? extraInitializationsAsync\r\n        );\r\n        this._compiledEffects[name] = effect;\r\n\r\n        return effect;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected static _ConcatenateShader = _ConcatenateShader;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getShaderSource(shader: WebGLShader): Nullable<string> {\r\n        return this._gl.getShaderSource(shader);\r\n    }\r\n\r\n    /**\r\n     * Directly creates a webGL program\r\n     * @param pipelineContext  defines the pipeline context to attach to\r\n     * @param vertexCode defines the vertex shader code to use\r\n     * @param fragmentCode defines the fragment shader code to use\r\n     * @param context defines the webGL context to use (if not set, the current one will be used)\r\n     * @param transformFeedbackVaryings defines the list of transform feedback varyings to use\r\n     * @returns the new webGL program\r\n     */\r\n    public createRawShaderProgram(\r\n        pipelineContext: IPipelineContext,\r\n        vertexCode: string,\r\n        fragmentCode: string,\r\n        context?: WebGLRenderingContext,\r\n        transformFeedbackVaryings: Nullable<string[]> = null\r\n    ): WebGLProgram {\r\n        const stateObject = getStateObject(this._gl);\r\n        stateObject._contextWasLost = this._contextWasLost;\r\n        stateObject.validateShaderPrograms = this.validateShaderPrograms;\r\n        return createRawShaderProgram(pipelineContext, vertexCode, fragmentCode, context || this._gl, transformFeedbackVaryings);\r\n    }\r\n\r\n    /**\r\n     * Creates a webGL program\r\n     * @param pipelineContext  defines the pipeline context to attach to\r\n     * @param vertexCode  defines the vertex shader code to use\r\n     * @param fragmentCode defines the fragment shader code to use\r\n     * @param defines defines the string containing the defines to use to compile the shaders\r\n     * @param context defines the webGL context to use (if not set, the current one will be used)\r\n     * @param transformFeedbackVaryings defines the list of transform feedback varyings to use\r\n     * @returns the new webGL program\r\n     */\r\n    public createShaderProgram(\r\n        pipelineContext: IPipelineContext,\r\n        vertexCode: string,\r\n        fragmentCode: string,\r\n        defines: Nullable<string>,\r\n        context?: WebGLRenderingContext,\r\n        transformFeedbackVaryings: Nullable<string[]> = null\r\n    ): WebGLProgram {\r\n        const stateObject = getStateObject(this._gl);\r\n        // assure the state object is correct\r\n        stateObject._contextWasLost = this._contextWasLost;\r\n        stateObject.validateShaderPrograms = this.validateShaderPrograms;\r\n        return createShaderProgram(pipelineContext, vertexCode, fragmentCode, defines, context || this._gl, transformFeedbackVaryings);\r\n    }\r\n\r\n    /**\r\n     * Inline functions in shader code that are marked to be inlined\r\n     * @param code code to inline\r\n     * @returns inlined code\r\n     */\r\n    public inlineShaderCode(code: string): string {\r\n        // no inlining needed in the WebGL engine\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Creates a new pipeline context\r\n     * @param shaderProcessingContext defines the shader processing context used during the processing if available\r\n     * @returns the new pipeline\r\n     */\r\n    public createPipelineContext(shaderProcessingContext: Nullable<_IShaderProcessingContext>): IPipelineContext {\r\n        if (this._gl) {\r\n            const stateObject = getStateObject(this._gl);\r\n            stateObject.parallelShaderCompile = this._caps.parallelShaderCompile;\r\n        }\r\n        const context = createPipelineContext(this._gl, shaderProcessingContext) as WebGLPipelineContext;\r\n        context.engine = this;\r\n        return context;\r\n    }\r\n\r\n    /**\r\n     * Creates a new material context\r\n     * @returns the new context\r\n     */\r\n    public createMaterialContext(): IMaterialContext | undefined {\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Creates a new draw context\r\n     * @returns the new context\r\n     */\r\n    public createDrawContext(): IDrawContext | undefined {\r\n        return undefined;\r\n    }\r\n\r\n    protected _finalizePipelineContext(pipelineContext: WebGLPipelineContext) {\r\n        return _finalizePipelineContext(pipelineContext, this._gl, this.validateShaderPrograms);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // named async but not actually an async function\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public _preparePipelineContextAsync(\r\n        pipelineContext: IPipelineContext,\r\n        vertexSourceCode: string,\r\n        fragmentSourceCode: string,\r\n        createAsRaw: boolean,\r\n        rawVertexSourceCode: string,\r\n        rawFragmentSourceCode: string,\r\n        rebuildRebind: any,\r\n        defines: Nullable<string>,\r\n        transformFeedbackVaryings: Nullable<string[]>,\r\n        key: string,\r\n        onReady: () => void\r\n    ) {\r\n        const stateObject = getStateObject(this._gl);\r\n        stateObject._contextWasLost = this._contextWasLost;\r\n        stateObject.validateShaderPrograms = this.validateShaderPrograms;\r\n        stateObject._createShaderProgramInjection = this._createShaderProgram.bind(this);\r\n        stateObject.createRawShaderProgramInjection = this.createRawShaderProgram.bind(this);\r\n        stateObject.createShaderProgramInjection = this.createShaderProgram.bind(this);\r\n        stateObject.loadFileInjection = this._loadFile.bind(this);\r\n        return _preparePipelineContext(\r\n            pipelineContext as WebGLPipelineContext,\r\n            vertexSourceCode,\r\n            fragmentSourceCode,\r\n            createAsRaw,\r\n            rawVertexSourceCode,\r\n            rawFragmentSourceCode,\r\n            rebuildRebind,\r\n            defines,\r\n            transformFeedbackVaryings,\r\n            key,\r\n            onReady\r\n        );\r\n    }\r\n\r\n    protected _createShaderProgram(\r\n        pipelineContext: WebGLPipelineContext,\r\n        vertexShader: WebGLShader,\r\n        fragmentShader: WebGLShader,\r\n        context: WebGLRenderingContext,\r\n        transformFeedbackVaryings: Nullable<string[]> = null\r\n    ): WebGLProgram {\r\n        return _createShaderProgram(pipelineContext, vertexShader, fragmentShader, context, transformFeedbackVaryings);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _isRenderingStateCompiled(pipelineContext: IPipelineContext): boolean {\r\n        if (this._isDisposed) {\r\n            return false;\r\n        }\r\n        return _isRenderingStateCompiled(pipelineContext, this._gl, this.validateShaderPrograms);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void) {\r\n        _executeWhenRenderingStateIsCompiled(pipelineContext as WebGLPipelineContext, action);\r\n    }\r\n\r\n    /**\r\n     * Gets the list of webGL uniform locations associated with a specific program based on a list of uniform names\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param uniformsNames defines the list of uniform names\r\n     * @returns an array of webGL uniform locations\r\n     */\r\n    public getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[] {\r\n        const results = new Array<Nullable<WebGLUniformLocation>>();\r\n        const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n\r\n        for (let index = 0; index < uniformsNames.length; index++) {\r\n            results.push(this._gl.getUniformLocation(webGLPipelineContext.program!, uniformsNames[index]));\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of active attributes for a given webGL program\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param attributesNames defines the list of attribute names to get\r\n     * @returns an array of indices indicating the offset of each attribute\r\n     */\r\n    public getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[] {\r\n        const results = [];\r\n        const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n\r\n        for (let index = 0; index < attributesNames.length; index++) {\r\n            try {\r\n                results.push(this._gl.getAttribLocation(webGLPipelineContext.program!, attributesNames[index]));\r\n            } catch (e) {\r\n                results.push(-1);\r\n            }\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Activates an effect, making it the current one (ie. the one used for rendering)\r\n     * @param effect defines the effect to activate\r\n     */\r\n    public enableEffect(effect: Nullable<Effect | DrawWrapper>): void {\r\n        effect = effect !== null && IsWrapper(effect) ? effect.effect : effect; // get only the effect, we don't need a Wrapper in the WebGL engine\r\n\r\n        if (!effect || effect === this._currentEffect) {\r\n            return;\r\n        }\r\n\r\n        this._stencilStateComposer.stencilMaterial = undefined;\r\n\r\n        // Use program\r\n        this.bindSamplers(effect);\r\n\r\n        this._currentEffect = effect;\r\n\r\n        if (effect.onBind) {\r\n            effect.onBind(effect);\r\n        }\r\n        if (effect._onBindObservable) {\r\n            effect._onBindObservable.notifyObservers(effect);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a number (int)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param value defines the int number to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setInt(uniform: Nullable<WebGLUniformLocation>, value: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform1i(uniform, value);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a int2\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setInt2(uniform: Nullable<WebGLUniformLocation>, x: number, y: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform2i(uniform, x, y);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a int3\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setInt3(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform3i(uniform, x, y, z);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a int4\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @param w defines the 4th component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setInt4(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number, w: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform4i(uniform, x, y, z, w);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setIntArray(uniform: Nullable<WebGLUniformLocation>, array: Int32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform1iv(uniform, array);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32 (stored as vec2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setIntArray2(uniform: Nullable<WebGLUniformLocation>, array: Int32Array): boolean {\r\n        if (!uniform || array.length % 2 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform2iv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32 (stored as vec3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setIntArray3(uniform: Nullable<WebGLUniformLocation>, array: Int32Array): boolean {\r\n        if (!uniform || array.length % 3 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform3iv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32 (stored as vec4)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setIntArray4(uniform: Nullable<WebGLUniformLocation>, array: Int32Array): boolean {\r\n        if (!uniform || array.length % 4 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform4iv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a number (unsigned int)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param value defines the unsigned int number to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setUInt(uniform: Nullable<WebGLUniformLocation>, value: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform1ui(uniform, value);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a unsigned int2\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setUInt2(uniform: Nullable<WebGLUniformLocation>, x: number, y: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform2ui(uniform, x, y);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a unsigned int3\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setUInt3(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform3ui(uniform, x, y, z);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a unsigned int4\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @param w defines the 4th component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setUInt4(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number, w: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform4ui(uniform, x, y, z, w);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of unsigned int32\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of unsigned int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setUIntArray(uniform: Nullable<WebGLUniformLocation>, array: Uint32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform1uiv(uniform, array);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of unsigned int32 (stored as vec2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of unsigned int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setUIntArray2(uniform: Nullable<WebGLUniformLocation>, array: Uint32Array): boolean {\r\n        if (!uniform || array.length % 2 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform2uiv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of unsigned int32 (stored as vec3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of unsigned int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setUIntArray3(uniform: Nullable<WebGLUniformLocation>, array: Uint32Array): boolean {\r\n        if (!uniform || array.length % 3 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform3uiv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of unsigned int32 (stored as vec4)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of unsigned int32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setUIntArray4(uniform: Nullable<WebGLUniformLocation>, array: Uint32Array): boolean {\r\n        if (!uniform || array.length % 4 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform4uiv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setArray(uniform: Nullable<WebGLUniformLocation>, array: FloatArray): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        if (array.length < 1) {\r\n            return false;\r\n        }\r\n        this._gl.uniform1fv(uniform, array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number (stored as vec2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setArray2(uniform: Nullable<WebGLUniformLocation>, array: FloatArray): boolean {\r\n        if (!uniform || array.length % 2 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform2fv(uniform, <any>array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number (stored as vec3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setArray3(uniform: Nullable<WebGLUniformLocation>, array: FloatArray): boolean {\r\n        if (!uniform || array.length % 3 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform3fv(uniform, <any>array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number (stored as vec4)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setArray4(uniform: Nullable<WebGLUniformLocation>, array: FloatArray): boolean {\r\n        if (!uniform || array.length % 4 !== 0) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform4fv(uniform, <any>array);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of float32 (stored as matrices)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param matrices defines the array of float32 to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setMatrices(uniform: Nullable<WebGLUniformLocation>, matrices: DeepImmutable<FloatArray>): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniformMatrix4fv(uniform, false, matrices as Float32List);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a matrix (3x3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param matrix defines the Float32Array representing the 3x3 matrix to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setMatrix3x3(uniform: Nullable<WebGLUniformLocation>, matrix: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniformMatrix3fv(uniform, false, matrix);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a matrix (2x2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param matrix defines the Float32Array representing the 2x2 matrix to store\r\n     * @returns true if the value was set\r\n     */\r\n    public setMatrix2x2(uniform: Nullable<WebGLUniformLocation>, matrix: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniformMatrix2fv(uniform, false, matrix);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a number (float)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param value defines the float number to store\r\n     * @returns true if the value was transferred\r\n     */\r\n    public setFloat(uniform: Nullable<WebGLUniformLocation>, value: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform1f(uniform, value);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a vec2\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setFloat2(uniform: Nullable<WebGLUniformLocation>, x: number, y: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform2f(uniform, x, y);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a vec3\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setFloat3(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform3f(uniform, x, y, z);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a vec4\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @param w defines the 4th component of the value\r\n     * @returns true if the value was set\r\n     */\r\n    public setFloat4(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number, w: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._gl.uniform4f(uniform, x, y, z, w);\r\n\r\n        return true;\r\n    }\r\n\r\n    // States\r\n\r\n    /** @internal */\r\n    public _applyColorWriteState(): void {\r\n        if (this._colorWriteChanged) {\r\n            this._colorWriteChanged = false;\r\n            const enable = this._colorWrite;\r\n            this._gl.colorMask(enable, enable, enable, enable);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Apply all cached states (depth, culling, stencil and alpha)\r\n     */\r\n    public applyStates() {\r\n        this._depthCullingState.apply(this._gl);\r\n        this._stencilStateComposer.apply(this._gl);\r\n        this._alphaState.apply(\r\n            this._gl,\r\n            this._currentRenderTarget && this._currentRenderTarget.textures ? this._currentRenderTarget.textures.length : 1,\r\n            this._integerMRTAttachmentsMask\r\n        );\r\n        this._applyColorWriteState();\r\n    }\r\n\r\n    // Textures\r\n\r\n    /**\r\n     * Force the entire cache to be cleared\r\n     * You should not have to use this function unless your engine needs to share the webGL context with another engine\r\n     * @param bruteForce defines a boolean to force clearing ALL caches (including stencil, detoh and alpha states)\r\n     */\r\n    public wipeCaches(bruteForce?: boolean): void {\r\n        if (this.preventCacheWipeBetweenFrames && !bruteForce) {\r\n            return;\r\n        }\r\n        this._currentEffect = null;\r\n        this._viewportCached.x = 0;\r\n        this._viewportCached.y = 0;\r\n        this._viewportCached.z = 0;\r\n        this._viewportCached.w = 0;\r\n\r\n        // Done before in case we clean the attributes\r\n        this._unbindVertexArrayObject();\r\n\r\n        if (bruteForce) {\r\n            this._currentProgram = null;\r\n            this.resetTextureCache();\r\n\r\n            this._stencilStateComposer.reset();\r\n\r\n            this._depthCullingState.reset();\r\n            this._depthCullingState.depthFunc = this._gl.LEQUAL;\r\n\r\n            this._alphaState.reset();\r\n            this._resetAlphaMode();\r\n\r\n            this._colorWrite = true;\r\n            this._colorWriteChanged = true;\r\n\r\n            this._unpackFlipYCached = null;\r\n\r\n            this._gl.pixelStorei(this._gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, this._gl.NONE);\r\n            this._gl.pixelStorei(this._gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\r\n\r\n            this._mustWipeVertexAttributes = true;\r\n            this.unbindAllAttributes();\r\n        }\r\n\r\n        this._resetVertexBufferBinding();\r\n        this._cachedIndexBuffer = null;\r\n        this._cachedEffectForVertexBuffers = null;\r\n        this.bindIndexBuffer(null);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getSamplingParameters(samplingMode: number, generateMipMaps: boolean): { min: number; mag: number; hasMipMaps: boolean } {\r\n        const gl = this._gl;\r\n        let magFilter: GLenum = gl.NEAREST;\r\n        let minFilter: GLenum = gl.NEAREST;\r\n        let hasMipMaps = false;\r\n\r\n        switch (samplingMode) {\r\n            case Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST:\r\n                magFilter = gl.LINEAR;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.LINEAR_MIPMAP_NEAREST;\r\n                } else {\r\n                    minFilter = gl.LINEAR;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR:\r\n                magFilter = gl.LINEAR;\r\n                hasMipMaps = true;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.LINEAR_MIPMAP_LINEAR;\r\n                } else {\r\n                    minFilter = gl.LINEAR;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR:\r\n                hasMipMaps = true;\r\n                magFilter = gl.NEAREST;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.NEAREST_MIPMAP_LINEAR;\r\n                } else {\r\n                    minFilter = gl.NEAREST;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST:\r\n                magFilter = gl.NEAREST;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.NEAREST_MIPMAP_NEAREST;\r\n                } else {\r\n                    minFilter = gl.NEAREST;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST:\r\n                magFilter = gl.NEAREST;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.LINEAR_MIPMAP_NEAREST;\r\n                } else {\r\n                    minFilter = gl.LINEAR;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR:\r\n                hasMipMaps = true;\r\n                magFilter = gl.NEAREST;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.LINEAR_MIPMAP_LINEAR;\r\n                } else {\r\n                    minFilter = gl.LINEAR;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_LINEAR:\r\n                magFilter = gl.NEAREST;\r\n                minFilter = gl.LINEAR;\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_NEAREST:\r\n                magFilter = gl.NEAREST;\r\n                minFilter = gl.NEAREST;\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST:\r\n                magFilter = gl.LINEAR;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.NEAREST_MIPMAP_NEAREST;\r\n                } else {\r\n                    minFilter = gl.NEAREST;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR:\r\n                hasMipMaps = true;\r\n                magFilter = gl.LINEAR;\r\n                if (generateMipMaps) {\r\n                    minFilter = gl.NEAREST_MIPMAP_LINEAR;\r\n                } else {\r\n                    minFilter = gl.NEAREST;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_LINEAR:\r\n                magFilter = gl.LINEAR;\r\n                minFilter = gl.LINEAR;\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_NEAREST:\r\n                magFilter = gl.LINEAR;\r\n                minFilter = gl.NEAREST;\r\n                break;\r\n        }\r\n\r\n        return {\r\n            min: minFilter,\r\n            mag: magFilter,\r\n            hasMipMaps: hasMipMaps,\r\n        };\r\n    }\r\n\r\n    /** @internal */\r\n    protected _createTexture(): WebGLTexture {\r\n        const texture = this._gl.createTexture();\r\n\r\n        if (!texture) {\r\n            throw new Error(\"Unable to create texture\");\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    /** @internal */\r\n    public _createHardwareTexture(): IHardwareTextureWrapper {\r\n        return new WebGLHardwareTexture(this._createTexture(), this._gl);\r\n    }\r\n\r\n    /**\r\n     * Creates an internal texture without binding it to a framebuffer\r\n     * @internal\r\n     * @param size defines the size of the texture\r\n     * @param options defines the options used to create the texture\r\n     * @param delayGPUTextureCreation true to delay the texture creation the first time it is really needed. false to create it right away\r\n     * @param source source type of the texture\r\n     * @returns a new internal texture\r\n     */\r\n    public _createInternalTexture(\r\n        size: TextureSize,\r\n        options: boolean | InternalTextureCreationOptions,\r\n        delayGPUTextureCreation = true,\r\n        source = InternalTextureSource.Unknown\r\n    ): InternalTexture {\r\n        let generateMipMaps: boolean;\r\n        let createMipMaps = false;\r\n        let type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        let samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n        let format = Constants.TEXTUREFORMAT_RGBA;\r\n        let useSRGBBuffer = false;\r\n        let samples = 1;\r\n        let label: string | undefined;\r\n        let createMSAATexture = false;\r\n        let comparisonFunction = 0;\r\n        let isCube = false;\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            generateMipMaps = !!options.generateMipMaps;\r\n            createMipMaps = !!options.createMipMaps;\r\n            type = options.type === undefined ? Constants.TEXTURETYPE_UNSIGNED_BYTE : options.type;\r\n            samplingMode = options.samplingMode === undefined ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;\r\n            format = options.format === undefined ? Constants.TEXTUREFORMAT_RGBA : options.format;\r\n            useSRGBBuffer = options.useSRGBBuffer === undefined ? false : options.useSRGBBuffer;\r\n            samples = options.samples ?? 1;\r\n            label = options.label;\r\n            createMSAATexture = !!options.createMSAATexture;\r\n            comparisonFunction = options.comparisonFunction || 0;\r\n            isCube = !!options.isCube;\r\n        } else {\r\n            generateMipMaps = !!options;\r\n        }\r\n\r\n        useSRGBBuffer &&= this._caps.supportSRGBBuffers && (this.webGLVersion > 1 || this.isWebGPU);\r\n\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n            type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            Logger.Warn(\"Float textures are not supported. Type forced to TEXTURETYPE_UNSIGNED_BYTE\");\r\n        }\r\n\r\n        const isDepthTexture = IsDepthTexture(format);\r\n        const hasStencil = HasStencilAspect(format);\r\n\r\n        const gl = this._gl;\r\n        const texture = new InternalTexture(this, source);\r\n        const width = (<{ width: number; height: number; depth?: number; layers?: number }>size).width || <number>size;\r\n        const height = (<{ width: number; height: number; depth?: number; layers?: number }>size).height || <number>size;\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>size).depth || 0;\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>size).layers || 0;\r\n        const filters = this._getSamplingParameters(samplingMode, (generateMipMaps || createMipMaps) && !isDepthTexture);\r\n        const target = layers !== 0 ? gl.TEXTURE_2D_ARRAY : depth !== 0 ? gl.TEXTURE_3D : isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\r\n        const sizedFormat = isDepthTexture\r\n            ? this._getInternalFormatFromDepthTextureFormat(format, true, hasStencil)\r\n            : this._getRGBABufferInternalSizedFormat(type, format, useSRGBBuffer);\r\n        const internalFormat = isDepthTexture ? (hasStencil ? gl.DEPTH_STENCIL : gl.DEPTH_COMPONENT) : this._getInternalFormat(format);\r\n        const textureType = isDepthTexture ? this._getWebGLTextureTypeFromDepthTextureFormat(format) : this._getWebGLTextureType(type);\r\n\r\n        // Bind\r\n        this._bindTextureDirectly(target, texture);\r\n\r\n        if (layers !== 0) {\r\n            texture.is2DArray = true;\r\n            gl.texImage3D(target, 0, sizedFormat, width, height, layers, 0, internalFormat, textureType, null);\r\n        } else if (depth !== 0) {\r\n            texture.is3D = true;\r\n            gl.texImage3D(target, 0, sizedFormat, width, height, depth, 0, internalFormat, textureType, null);\r\n        } else if (isCube) {\r\n            texture.isCube = true;\r\n            for (let face = 0; face < 6; face++) {\r\n                gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, sizedFormat, width, height, 0, internalFormat, textureType, null);\r\n            }\r\n        } else {\r\n            gl.texImage2D(target, 0, sizedFormat, width, height, 0, internalFormat, textureType, null);\r\n        }\r\n\r\n        gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, filters.mag);\r\n        gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, filters.min);\r\n        gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n        gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n        if (isDepthTexture && this.webGLVersion > 1) {\r\n            if (comparisonFunction === 0) {\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_FUNC, Constants.LEQUAL);\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.NONE);\r\n            } else {\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);\r\n            }\r\n        }\r\n\r\n        // MipMaps\r\n        if (generateMipMaps || createMipMaps) {\r\n            this._gl.generateMipmap(target);\r\n        }\r\n\r\n        this._bindTextureDirectly(target, null);\r\n\r\n        texture._useSRGBBuffer = useSRGBBuffer;\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.depth = layers || depth;\r\n        texture.isReady = true;\r\n        texture.samples = samples;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.type = type;\r\n        texture.format = format;\r\n        texture.label = label;\r\n        texture.comparisonFunction = comparisonFunction;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        if (createMSAATexture) {\r\n            let renderBuffer: Nullable<WebGLRenderbuffer>;\r\n\r\n            if (IsDepthTexture(texture.format)) {\r\n                renderBuffer = this._setupFramebufferDepthAttachments(\r\n                    HasStencilAspect(texture.format),\r\n                    texture.format !== Constants.TEXTUREFORMAT_STENCIL8,\r\n                    texture.width,\r\n                    texture.height,\r\n                    samples,\r\n                    texture.format,\r\n                    true\r\n                );\r\n            } else {\r\n                renderBuffer = this._createRenderBuffer(\r\n                    texture.width,\r\n                    texture.height,\r\n                    samples,\r\n                    -1 /* not used */,\r\n                    this._getRGBABufferInternalSizedFormat(texture.type, texture.format, texture._useSRGBBuffer),\r\n                    -1 /* attachment */\r\n                );\r\n            }\r\n\r\n            if (!renderBuffer) {\r\n                throw new Error(\"Unable to create render buffer\");\r\n            }\r\n\r\n            texture._autoMSAAManagement = true;\r\n\r\n            let hardwareTexture = texture._hardwareTexture as Nullable<WebGLHardwareTexture>;\r\n            if (!hardwareTexture) {\r\n                hardwareTexture = texture._hardwareTexture = this._createHardwareTexture() as WebGLHardwareTexture;\r\n            }\r\n\r\n            hardwareTexture.addMSAARenderBuffer(renderBuffer);\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getUseSRGBBuffer(useSRGBBuffer: boolean, noMipmap: boolean): boolean {\r\n        // Generating mipmaps for sRGB textures is not supported in WebGL1 so we must disable the support if mipmaps is enabled\r\n        return useSRGBBuffer && this._caps.supportSRGBBuffers && (this.webGLVersion > 1 || noMipmap);\r\n    }\r\n\r\n    /**\r\n     * Usually called from Texture.ts.\r\n     * Passed information to create a WebGLTexture\r\n     * @param url defines a value which contains one of the following:\r\n     * * A conventional http URL, e.g. 'http://...' or 'file://...'\r\n     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'\r\n     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'\r\n     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file\r\n     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)\r\n     * @param scene needed for loading to the correct scene\r\n     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)\r\n     * @param onLoad optional callback to be called upon successful completion\r\n     * @param onError optional callback to be called upon failure\r\n     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob\r\n     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities\r\n     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @param mimeType defines an optional mime type\r\n     * @param loaderOptions options to be passed to the loader\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns a InternalTexture for assignment back into BABYLON.Texture\r\n     */\r\n    public createTexture(\r\n        url: Nullable<string>,\r\n        noMipmap: boolean,\r\n        invertY: boolean,\r\n        scene: Nullable<ISceneLike>,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<(texture: InternalTexture) => void> = null,\r\n        onError: Nullable<(message: string, exception: any) => void> = null,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        format: Nullable<number> = null,\r\n        forcedExtension: Nullable<string> = null,\r\n        mimeType?: string,\r\n        loaderOptions?: any,\r\n        creationFlags?: number,\r\n        useSRGBBuffer?: boolean\r\n    ): InternalTexture {\r\n        return this._createTextureBase(\r\n            url,\r\n            noMipmap,\r\n            invertY,\r\n            scene,\r\n            samplingMode,\r\n            onLoad,\r\n            onError,\r\n            (...args: Parameters<PrepareTextureFunction>) => this._prepareWebGLTexture(...args, format),\r\n            (potWidth, potHeight, img, extension, texture, continuationCallback) => {\r\n                const gl = this._gl;\r\n                const isPot = img.width === potWidth && img.height === potHeight;\r\n\r\n                texture._creationFlags = creationFlags ?? 0;\r\n\r\n                const tip = this._getTexImageParametersForCreateTexture(texture.format, texture._useSRGBBuffer);\r\n                if (isPot) {\r\n                    gl.texImage2D(gl.TEXTURE_2D, 0, tip.internalFormat, tip.format, tip.type, img as any);\r\n                    return false;\r\n                }\r\n\r\n                const maxTextureSize = this._caps.maxTextureSize;\r\n\r\n                if (img.width > maxTextureSize || img.height > maxTextureSize || !this._supportsHardwareTextureRescaling) {\r\n                    this._prepareWorkingCanvas();\r\n                    if (!this._workingCanvas || !this._workingContext) {\r\n                        return false;\r\n                    }\r\n\r\n                    this._workingCanvas.width = potWidth;\r\n                    this._workingCanvas.height = potHeight;\r\n\r\n                    this._workingContext.drawImage(img as any, 0, 0, img.width, img.height, 0, 0, potWidth, potHeight);\r\n                    gl.texImage2D(gl.TEXTURE_2D, 0, tip.internalFormat, tip.format, tip.type, this._workingCanvas as TexImageSource);\r\n\r\n                    texture.width = potWidth;\r\n                    texture.height = potHeight;\r\n\r\n                    return false;\r\n                } else {\r\n                    // Using shaders when possible to rescale because canvas.drawImage is lossy\r\n                    const source = new InternalTexture(this, InternalTextureSource.Temp);\r\n                    this._bindTextureDirectly(gl.TEXTURE_2D, source, true);\r\n                    gl.texImage2D(gl.TEXTURE_2D, 0, tip.internalFormat, tip.format, tip.type, img as any);\r\n\r\n                    this._rescaleTexture(source, texture, scene, tip.format, () => {\r\n                        this._releaseTexture(source);\r\n                        this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);\r\n\r\n                        continuationCallback();\r\n                    });\r\n                }\r\n\r\n                return true;\r\n            },\r\n            buffer,\r\n            fallback,\r\n            format,\r\n            forcedExtension,\r\n            mimeType,\r\n            loaderOptions,\r\n            useSRGBBuffer\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Calls to the GL texImage2D and texImage3D functions require three arguments describing the pixel format of the texture.\r\n     * createTexture derives these from the babylonFormat and useSRGBBuffer arguments and also the file extension of the URL it's working with.\r\n     * This function encapsulates that derivation for easy unit testing.\r\n     * @param babylonFormat Babylon's format enum, as specified in ITextureCreationOptions.\r\n     * @param fileExtension The file extension including the dot, e.g. .jpg.\r\n     * @param useSRGBBuffer Use SRGB not linear.\r\n     * @returns The options to pass to texImage2D or texImage3D calls.\r\n     * @internal\r\n     */\r\n    public _getTexImageParametersForCreateTexture(babylonFormat: number, useSRGBBuffer: boolean): TexImageParameters {\r\n        let format: number, internalFormat: number;\r\n        if (this.webGLVersion === 1) {\r\n            // In WebGL 1, format and internalFormat must be the same and taken from a limited set of values, see https://docs.gl/es2/glTexImage2D.\r\n            // The SRGB extension (https://developer.mozilla.org/en-US/docs/Web/API/EXT_sRGB) adds some extra values, hence passing useSRGBBuffer\r\n            // to getInternalFormat.\r\n            format = this._getInternalFormat(babylonFormat, useSRGBBuffer);\r\n            internalFormat = format;\r\n        } else {\r\n            // In WebGL 2, format has a wider range of values and internal format can be one of the sized formats, see\r\n            // https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml.\r\n            // SRGB is included in the sized format and should not be passed in \"format\", hence always passing useSRGBBuffer as false.\r\n            format = this._getInternalFormat(babylonFormat, false);\r\n            internalFormat = this._getRGBABufferInternalSizedFormat(Constants.TEXTURETYPE_UNSIGNED_BYTE, babylonFormat, useSRGBBuffer);\r\n        }\r\n\r\n        return {\r\n            internalFormat,\r\n            format,\r\n            type: this._gl.UNSIGNED_BYTE,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _rescaleTexture(source: InternalTexture, destination: InternalTexture, scene: Nullable<any>, internalFormat: number, onComplete: () => void): void {}\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _unpackFlipYCached: Nullable<boolean> = null;\r\n\r\n    /**\r\n     * In case you are sharing the context with other applications, it might\r\n     * be interested to not cache the unpack flip y state to ensure a consistent\r\n     * value would be set.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public enableUnpackFlipYCached = true;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _unpackFlipY(value: boolean): void {\r\n        if (this._unpackFlipYCached !== value) {\r\n            this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, value ? 1 : 0);\r\n\r\n            if (this.enableUnpackFlipYCached) {\r\n                this._unpackFlipYCached = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _getUnpackAlignement(): number {\r\n        return this._gl.getParameter(this._gl.UNPACK_ALIGNMENT) as number;\r\n    }\r\n\r\n    /** @internal */\r\n    public _getTextureTarget(texture: InternalTexture): number {\r\n        if (texture.isCube) {\r\n            return this._gl.TEXTURE_CUBE_MAP;\r\n        } else if (texture.is3D) {\r\n            return this._gl.TEXTURE_3D;\r\n        } else if (texture.is2DArray || texture.isMultiview) {\r\n            return this._gl.TEXTURE_2D_ARRAY;\r\n        }\r\n        return this._gl.TEXTURE_2D;\r\n    }\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param samplingMode defines the required sampling mode\r\n     * @param texture defines the texture to update\r\n     * @param generateMipMaps defines whether to generate mipmaps for the texture\r\n     */\r\n    public updateTextureSamplingMode(samplingMode: number, texture: InternalTexture, generateMipMaps: boolean = false): void {\r\n        const target = this._getTextureTarget(texture);\r\n        const filters = this._getSamplingParameters(samplingMode, texture.useMipMaps || generateMipMaps);\r\n\r\n        this._setTextureParameterInteger(target, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);\r\n        this._setTextureParameterInteger(target, this._gl.TEXTURE_MIN_FILTER, filters.min);\r\n\r\n        if (generateMipMaps && filters.hasMipMaps) {\r\n            texture.generateMipMaps = true;\r\n            this._gl.generateMipmap(target);\r\n        }\r\n\r\n        this._bindTextureDirectly(target, null);\r\n\r\n        texture.samplingMode = samplingMode;\r\n    }\r\n\r\n    /**\r\n     * Update the dimensions of a texture\r\n     * @param texture texture to update\r\n     * @param width new width of the texture\r\n     * @param height new height of the texture\r\n     * @param depth new depth of the texture\r\n     */\r\n    public updateTextureDimensions(texture: InternalTexture, width: number, height: number, depth: number = 1): void {}\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param texture defines the texture to update\r\n     * @param wrapU defines the texture wrap mode of the u coordinates\r\n     * @param wrapV defines the texture wrap mode of the v coordinates\r\n     * @param wrapR defines the texture wrap mode of the r coordinates\r\n     */\r\n    public updateTextureWrappingMode(texture: InternalTexture, wrapU: Nullable<number>, wrapV: Nullable<number> = null, wrapR: Nullable<number> = null): void {\r\n        const target = this._getTextureTarget(texture);\r\n\r\n        if (wrapU !== null) {\r\n            this._setTextureParameterInteger(target, this._gl.TEXTURE_WRAP_S, this._getTextureWrapMode(wrapU), texture);\r\n            texture._cachedWrapU = wrapU;\r\n        }\r\n        if (wrapV !== null) {\r\n            this._setTextureParameterInteger(target, this._gl.TEXTURE_WRAP_T, this._getTextureWrapMode(wrapV), texture);\r\n            texture._cachedWrapV = wrapV;\r\n        }\r\n        if ((texture.is2DArray || texture.is3D) && wrapR !== null) {\r\n            this._setTextureParameterInteger(target, this._gl.TEXTURE_WRAP_R, this._getTextureWrapMode(wrapR), texture);\r\n            texture._cachedWrapR = wrapR;\r\n        }\r\n\r\n        this._bindTextureDirectly(target, null);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadCompressedDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        internalFormat: number,\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        faceIndex: number = 0,\r\n        lod: number = 0\r\n    ) {\r\n        const gl = this._gl;\r\n\r\n        let target: GLenum = gl.TEXTURE_2D;\r\n        if (texture.isCube) {\r\n            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;\r\n        }\r\n\r\n        if (texture._useSRGBBuffer) {\r\n            switch (internalFormat) {\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n                    // Note, if using ETC1 and sRGB is requested, this will use ETC2 if available.\r\n                    if (this._caps.etc2) {\r\n                        internalFormat = gl.COMPRESSED_SRGB8_ETC2;\r\n                    } else {\r\n                        texture._useSRGBBuffer = false;\r\n                    }\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n                    if (this._caps.etc2) {\r\n                        internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;\r\n                    } else {\r\n                        texture._useSRGBBuffer = false;\r\n                    }\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n                    internalFormat = gl.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12:\r\n                    internalFormat = gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n                    if (this._caps.s3tc_srgb) {\r\n                        internalFormat = gl.COMPRESSED_SRGB_S3TC_DXT1_EXT;\r\n                    } else {\r\n                        // S3TC sRGB extension not supported\r\n                        texture._useSRGBBuffer = false;\r\n                    }\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n                    if (this._caps.s3tc_srgb) {\r\n                        internalFormat = gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;\r\n                    } else {\r\n                        // S3TC sRGB extension not supported\r\n                        texture._useSRGBBuffer = false;\r\n                    }\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n                    if (this._caps.s3tc_srgb) {\r\n                        internalFormat = gl.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;\r\n                    } else {\r\n                        // S3TC sRGB extension not supported\r\n                        texture._useSRGBBuffer = false;\r\n                    }\r\n                    break;\r\n                default:\r\n                    // We don't support a sRGB format corresponding to internalFormat, so revert to non sRGB format\r\n                    texture._useSRGBBuffer = false;\r\n                    break;\r\n            }\r\n        }\r\n\r\n        if (texture.generateMipMaps) {\r\n            const webGLHardwareTexture = texture._hardwareTexture as WebGLHardwareTexture;\r\n            if (!webGLHardwareTexture.memoryAllocated) {\r\n                gl.texStorage2D(\r\n                    texture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D,\r\n                    Math.floor(Math.log2(Math.max(width, height))) + 1,\r\n                    internalFormat,\r\n                    texture.width,\r\n                    texture.height\r\n                );\r\n                webGLHardwareTexture.memoryAllocated = true;\r\n            }\r\n            this._gl.compressedTexSubImage2D(target, lod, 0, 0, width, height, internalFormat, data);\r\n        } else {\r\n            this._gl.compressedTexImage2D(target, lod, internalFormat, width, height, 0, <DataView>data);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        imageData: ArrayBufferView,\r\n        faceIndex: number = 0,\r\n        lod: number = 0,\r\n        babylonInternalFormat?: number,\r\n        useTextureWidthAndHeight = false\r\n    ): void {\r\n        const gl = this._gl;\r\n\r\n        const textureType = this._getWebGLTextureType(texture.type);\r\n        const format = this._getInternalFormat(texture.format);\r\n        const internalFormat =\r\n            babylonInternalFormat === undefined\r\n                ? this._getRGBABufferInternalSizedFormat(texture.type, texture.format, texture._useSRGBBuffer)\r\n                : this._getInternalFormat(babylonInternalFormat, texture._useSRGBBuffer);\r\n\r\n        this._unpackFlipY(texture.invertY);\r\n\r\n        let target: GLenum = gl.TEXTURE_2D;\r\n        if (texture.isCube) {\r\n            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;\r\n        }\r\n\r\n        const lodMaxWidth = Math.round(Math.log(texture.width) * Math.LOG2E);\r\n        const lodMaxHeight = Math.round(Math.log(texture.height) * Math.LOG2E);\r\n        const width = useTextureWidthAndHeight ? texture.width : Math.pow(2, Math.max(lodMaxWidth - lod, 0));\r\n        const height = useTextureWidthAndHeight ? texture.height : Math.pow(2, Math.max(lodMaxHeight - lod, 0));\r\n\r\n        gl.texImage2D(target, lod, internalFormat, width, height, 0, format, textureType, imageData);\r\n    }\r\n\r\n    /**\r\n     * Update a portion of an internal texture\r\n     * @param texture defines the texture to update\r\n     * @param imageData defines the data to store into the texture\r\n     * @param xOffset defines the x coordinates of the update rectangle\r\n     * @param yOffset defines the y coordinates of the update rectangle\r\n     * @param width defines the width of the update rectangle\r\n     * @param height defines the height of the update rectangle\r\n     * @param faceIndex defines the face index if texture is a cube (0 by default)\r\n     * @param lod defines the lod level to update (0 by default)\r\n     * @param generateMipMaps defines whether to generate mipmaps or not\r\n     */\r\n    public updateTextureData(\r\n        texture: InternalTexture,\r\n        imageData: ArrayBufferView,\r\n        xOffset: number,\r\n        yOffset: number,\r\n        width: number,\r\n        height: number,\r\n        faceIndex: number = 0,\r\n        lod: number = 0,\r\n        generateMipMaps = false\r\n    ): void {\r\n        const gl = this._gl;\r\n\r\n        const textureType = this._getWebGLTextureType(texture.type);\r\n        const format = this._getInternalFormat(texture.format);\r\n\r\n        this._unpackFlipY(texture.invertY);\r\n\r\n        let targetForBinding: GLenum = gl.TEXTURE_2D;\r\n        let target: GLenum = gl.TEXTURE_2D;\r\n        if (texture.isCube) {\r\n            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;\r\n            targetForBinding = gl.TEXTURE_CUBE_MAP;\r\n        }\r\n\r\n        this._bindTextureDirectly(targetForBinding, texture, true);\r\n\r\n        gl.texSubImage2D(target, lod, xOffset, yOffset, width, height, format, textureType, imageData);\r\n\r\n        if (generateMipMaps) {\r\n            this._gl.generateMipmap(target);\r\n        }\r\n\r\n        this._bindTextureDirectly(targetForBinding, null);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {\r\n        const gl = this._gl;\r\n        const bindTarget = texture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\r\n\r\n        this._bindTextureDirectly(bindTarget, texture, true);\r\n\r\n        this._uploadDataToTextureDirectly(texture, imageData, faceIndex, lod);\r\n\r\n        this._bindTextureDirectly(bindTarget, null, true);\r\n    }\r\n\r\n    protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<ISceneLike>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void {\r\n        const gl = this._gl;\r\n        if (!gl) {\r\n            return;\r\n        }\r\n\r\n        const filters = this._getSamplingParameters(samplingMode, !noMipmap);\r\n\r\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filters.mag);\r\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filters.min);\r\n\r\n        if (!noMipmap && !isCompressed) {\r\n            gl.generateMipmap(gl.TEXTURE_2D);\r\n        }\r\n\r\n        this._bindTextureDirectly(gl.TEXTURE_2D, null);\r\n\r\n        // this.resetTextureCache();\r\n        if (scene) {\r\n            scene.removePendingData(texture);\r\n        }\r\n\r\n        texture.onLoadedObservable.notifyObservers(texture);\r\n        texture.onLoadedObservable.clear();\r\n    }\r\n\r\n    private _prepareWebGLTexture(\r\n        texture: InternalTexture,\r\n        extension: string,\r\n        scene: Nullable<ISceneLike>,\r\n        img: HTMLImageElement | ImageBitmap | { width: number; height: number },\r\n        invertY: boolean,\r\n        noMipmap: boolean,\r\n        isCompressed: boolean,\r\n        processFunction: PrepareTextureProcessFunction,\r\n        samplingMode: number,\r\n        format: Nullable<number>\r\n    ): void {\r\n        const maxTextureSize = this.getCaps().maxTextureSize;\r\n        const potWidth = Math.min(maxTextureSize, this.needPOTTextures ? GetExponentOfTwo(img.width, maxTextureSize) : img.width);\r\n        const potHeight = Math.min(maxTextureSize, this.needPOTTextures ? GetExponentOfTwo(img.height, maxTextureSize) : img.height);\r\n\r\n        const gl = this._gl;\r\n        if (!gl) {\r\n            return;\r\n        }\r\n\r\n        if (!texture._hardwareTexture) {\r\n            //  this.resetTextureCache();\r\n            if (scene) {\r\n                scene.removePendingData(texture);\r\n            }\r\n\r\n            return;\r\n        }\r\n\r\n        this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);\r\n        this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);\r\n\r\n        texture.baseWidth = img.width;\r\n        texture.baseHeight = img.height;\r\n        texture.width = potWidth;\r\n        texture.height = potHeight;\r\n        texture.isReady = true;\r\n        texture.type = texture.type !== -1 ? texture.type : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        texture.format =\r\n            texture.format !== -1 ? texture.format : (format ?? (extension === \".jpg\" && !texture._useSRGBBuffer ? Constants.TEXTUREFORMAT_RGB : Constants.TEXTUREFORMAT_RGBA));\r\n\r\n        if (\r\n            processFunction(potWidth, potHeight, img, extension, texture, () => {\r\n                this._prepareWebGLTextureContinuation(texture, scene, noMipmap, isCompressed, samplingMode);\r\n            })\r\n        ) {\r\n            // Returning as texture needs extra async steps\r\n            return;\r\n        }\r\n\r\n        this._prepareWebGLTextureContinuation(texture, scene, noMipmap, isCompressed, samplingMode);\r\n    }\r\n\r\n    public _getInternalFormatFromDepthTextureFormat(textureFormat: number, hasDepth: boolean, hasStencil: boolean): number {\r\n        const gl = this._gl;\r\n\r\n        if (!hasDepth) {\r\n            return gl.STENCIL_INDEX8;\r\n        }\r\n\r\n        const format: GLenum = hasStencil ? gl.DEPTH_STENCIL : gl.DEPTH_COMPONENT;\r\n        let internalFormat = format;\r\n        if (this.webGLVersion > 1) {\r\n            if (textureFormat === Constants.TEXTUREFORMAT_DEPTH16) {\r\n                internalFormat = gl.DEPTH_COMPONENT16;\r\n            } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH24) {\r\n                internalFormat = gl.DEPTH_COMPONENT24;\r\n            } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 || textureFormat === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8) {\r\n                internalFormat = hasStencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24;\r\n            } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH32_FLOAT) {\r\n                internalFormat = gl.DEPTH_COMPONENT32F;\r\n            } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8) {\r\n                internalFormat = hasStencil ? gl.DEPTH32F_STENCIL8 : gl.DEPTH_COMPONENT32F;\r\n            }\r\n        } else {\r\n            internalFormat = gl.DEPTH_COMPONENT16;\r\n        }\r\n\r\n        return internalFormat;\r\n    }\r\n\r\n    public _getWebGLTextureTypeFromDepthTextureFormat(textureFormat: number): GLenum {\r\n        const gl = this._gl;\r\n\r\n        let type: GLenum = gl.UNSIGNED_INT;\r\n        if (textureFormat === Constants.TEXTUREFORMAT_DEPTH16) {\r\n            type = gl.UNSIGNED_SHORT;\r\n        } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 || textureFormat === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8) {\r\n            type = gl.UNSIGNED_INT_24_8;\r\n        } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH32_FLOAT) {\r\n            type = gl.FLOAT;\r\n        } else if (textureFormat === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8) {\r\n            type = gl.FLOAT_32_UNSIGNED_INT_24_8_REV;\r\n        } else if (textureFormat === Constants.TEXTUREFORMAT_STENCIL8) {\r\n            type = gl.UNSIGNED_BYTE;\r\n        }\r\n\r\n        return type;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setupFramebufferDepthAttachments(\r\n        generateStencilBuffer: boolean,\r\n        generateDepthBuffer: boolean,\r\n        width: number,\r\n        height: number,\r\n        samples = 1,\r\n        depthTextureFormat?: number,\r\n        dontBindRenderBufferToFrameBuffer = false\r\n    ): Nullable<WebGLRenderbuffer> {\r\n        const gl = this._gl;\r\n\r\n        depthTextureFormat = depthTextureFormat ?? (generateStencilBuffer ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT);\r\n\r\n        const internalFormat = this._getInternalFormatFromDepthTextureFormat(depthTextureFormat, generateDepthBuffer, generateStencilBuffer);\r\n\r\n        // Create the depth/stencil buffer\r\n        if (generateStencilBuffer && generateDepthBuffer) {\r\n            return this._createRenderBuffer(width, height, samples, gl.DEPTH_STENCIL, internalFormat, dontBindRenderBufferToFrameBuffer ? -1 : gl.DEPTH_STENCIL_ATTACHMENT);\r\n        }\r\n        if (generateDepthBuffer) {\r\n            return this._createRenderBuffer(width, height, samples, internalFormat, internalFormat, dontBindRenderBufferToFrameBuffer ? -1 : gl.DEPTH_ATTACHMENT);\r\n        }\r\n        if (generateStencilBuffer) {\r\n            return this._createRenderBuffer(width, height, samples, internalFormat, internalFormat, dontBindRenderBufferToFrameBuffer ? -1 : gl.STENCIL_ATTACHMENT);\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _createRenderBuffer(\r\n        width: number,\r\n        height: number,\r\n        samples: number,\r\n        internalFormat: number,\r\n        msInternalFormat: number,\r\n        attachment: number,\r\n        unbindBuffer = true\r\n    ): Nullable<WebGLRenderbuffer> {\r\n        const gl = this._gl;\r\n        const renderBuffer = gl.createRenderbuffer();\r\n        return this._updateRenderBuffer(renderBuffer, width, height, samples, internalFormat, msInternalFormat, attachment, unbindBuffer);\r\n    }\r\n\r\n    public _updateRenderBuffer(\r\n        renderBuffer: Nullable<WebGLRenderbuffer>,\r\n        width: number,\r\n        height: number,\r\n        samples: number,\r\n        internalFormat: number,\r\n        msInternalFormat: number,\r\n        attachment: number,\r\n        unbindBuffer = true\r\n    ): Nullable<WebGLRenderbuffer> {\r\n        const gl = this._gl;\r\n\r\n        gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);\r\n\r\n        if (samples > 1 && gl.renderbufferStorageMultisample) {\r\n            gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, msInternalFormat, width, height);\r\n        } else {\r\n            gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, width, height);\r\n        }\r\n\r\n        if (attachment !== -1) {\r\n            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderBuffer);\r\n        }\r\n\r\n        if (unbindBuffer) {\r\n            gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n        }\r\n\r\n        return renderBuffer;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseTexture(texture: InternalTexture): void {\r\n        this._deleteTexture(texture._hardwareTexture as Nullable<WebGLHardwareTexture>);\r\n\r\n        // Unbind channels\r\n        this.unbindAllTextures();\r\n\r\n        const index = this._internalTexturesCache.indexOf(texture);\r\n        if (index !== -1) {\r\n            this._internalTexturesCache.splice(index, 1);\r\n        }\r\n\r\n        // Integrated fixed lod samplers.\r\n        if (texture._lodTextureHigh) {\r\n            texture._lodTextureHigh.dispose();\r\n        }\r\n        if (texture._lodTextureMid) {\r\n            texture._lodTextureMid.dispose();\r\n        }\r\n        if (texture._lodTextureLow) {\r\n            texture._lodTextureLow.dispose();\r\n        }\r\n\r\n        // Integrated irradiance map.\r\n        if (texture._irradianceTexture) {\r\n            texture._irradianceTexture.dispose();\r\n        }\r\n    }\r\n\r\n    protected _deleteTexture(texture: Nullable<WebGLHardwareTexture>): void {\r\n        texture?.release();\r\n    }\r\n\r\n    protected _setProgram(program: Nullable<WebGLProgram>): void {\r\n        if (this._currentProgram !== program) {\r\n            _setProgram(program, this._gl);\r\n            this._currentProgram = program;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _boundUniforms: { [key: number]: WebGLUniformLocation } = {};\r\n\r\n    /**\r\n     * Binds an effect to the webGL context\r\n     * @param effect defines the effect to bind\r\n     */\r\n    public bindSamplers(effect: Effect): void {\r\n        const webGLPipelineContext = effect.getPipelineContext() as WebGLPipelineContext;\r\n        this._setProgram(webGLPipelineContext.program);\r\n        const samplers = effect.getSamplers();\r\n        for (let index = 0; index < samplers.length; index++) {\r\n            const uniform = effect.getUniform(samplers[index]);\r\n\r\n            if (uniform) {\r\n                this._boundUniforms[index] = uniform;\r\n            }\r\n        }\r\n        this._currentEffect = null;\r\n    }\r\n\r\n    private _activateCurrentTexture() {\r\n        if (this._currentTextureChannel !== this._activeChannel) {\r\n            this._gl.activeTexture(this._gl.TEXTURE0 + this._activeChannel);\r\n            this._currentTextureChannel = this._activeChannel;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, forTextureDataUpdate = false, force = false): boolean {\r\n        let wasPreviouslyBound = false;\r\n        const isTextureForRendering = texture && texture._associatedChannel > -1;\r\n        if (forTextureDataUpdate && isTextureForRendering) {\r\n            this._activeChannel = texture._associatedChannel;\r\n        }\r\n\r\n        const currentTextureBound = this._boundTexturesCache[this._activeChannel];\r\n\r\n        if (currentTextureBound !== texture || force) {\r\n            this._activateCurrentTexture();\r\n\r\n            if (texture && texture.isMultiview) {\r\n                //this._gl.bindTexture(target, texture ? texture._colorTextureArray : null);\r\n                Logger.Error([\"_bindTextureDirectly called with a multiview texture!\", target, texture]);\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"_bindTextureDirectly called with a multiview texture!\";\r\n            } else {\r\n                this._gl.bindTexture(target, texture?._hardwareTexture?.underlyingResource ?? null);\r\n            }\r\n\r\n            this._boundTexturesCache[this._activeChannel] = texture;\r\n\r\n            if (texture) {\r\n                texture._associatedChannel = this._activeChannel;\r\n            }\r\n        } else if (forTextureDataUpdate) {\r\n            wasPreviouslyBound = true;\r\n            this._activateCurrentTexture();\r\n        }\r\n\r\n        if (isTextureForRendering && !forTextureDataUpdate) {\r\n            this._bindSamplerUniformToChannel(texture._associatedChannel, this._activeChannel);\r\n        }\r\n\r\n        return wasPreviouslyBound;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindTexture(channel: number, texture: Nullable<InternalTexture>, name: string): void {\r\n        if (channel === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (texture) {\r\n            texture._associatedChannel = channel;\r\n        }\r\n\r\n        this._activeChannel = channel;\r\n        const target = texture ? this._getTextureTarget(texture) : this._gl.TEXTURE_2D;\r\n        this._bindTextureDirectly(target, texture);\r\n    }\r\n\r\n    /**\r\n     * Unbind all textures from the webGL context\r\n     */\r\n    public unbindAllTextures(): void {\r\n        for (let channel = 0; channel < this._maxSimultaneousTextures; channel++) {\r\n            this._activeChannel = channel;\r\n            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);\r\n            if (this.webGLVersion > 1) {\r\n                this._bindTextureDirectly(this._gl.TEXTURE_3D, null);\r\n                this._bindTextureDirectly(this._gl.TEXTURE_2D_ARRAY, null);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a texture to the according uniform.\r\n     * @param channel The texture channel\r\n     * @param uniform The uniform to set\r\n     * @param texture The texture to apply\r\n     * @param name The name of the uniform in the effect\r\n     */\r\n    public setTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<ThinTexture>, name: string): void {\r\n        if (channel === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (uniform) {\r\n            this._boundUniforms[channel] = uniform;\r\n        }\r\n\r\n        this._setTexture(channel, texture);\r\n    }\r\n\r\n    private _bindSamplerUniformToChannel(sourceSlot: number, destination: number) {\r\n        const uniform = this._boundUniforms[sourceSlot];\r\n        if (!uniform || uniform._currentState === destination) {\r\n            return;\r\n        }\r\n        this._gl.uniform1i(uniform, destination);\r\n        uniform._currentState = destination;\r\n    }\r\n\r\n    private _getTextureWrapMode(mode: number): number {\r\n        switch (mode) {\r\n            case Constants.TEXTURE_WRAP_ADDRESSMODE:\r\n                return this._gl.REPEAT;\r\n            case Constants.TEXTURE_CLAMP_ADDRESSMODE:\r\n                return this._gl.CLAMP_TO_EDGE;\r\n            case Constants.TEXTURE_MIRROR_ADDRESSMODE:\r\n                return this._gl.MIRRORED_REPEAT;\r\n        }\r\n        return this._gl.REPEAT;\r\n    }\r\n\r\n    public override _setTexture(channel: number, texture: Nullable<ThinTexture>, isPartOfTextureArray = false, depthStencilTexture = false, name = \"\"): boolean {\r\n        // Not ready?\r\n        if (!texture) {\r\n            if (this._boundTexturesCache[channel] != null) {\r\n                this._activeChannel = channel;\r\n                this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n                this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);\r\n                if (this.webGLVersion > 1) {\r\n                    this._bindTextureDirectly(this._gl.TEXTURE_3D, null);\r\n                    this._bindTextureDirectly(this._gl.TEXTURE_2D_ARRAY, null);\r\n                }\r\n            }\r\n            return false;\r\n        }\r\n\r\n        // Video\r\n        if ((<VideoTexture>texture).video) {\r\n            this._activeChannel = channel;\r\n            const videoInternalTexture = (<VideoTexture>texture).getInternalTexture();\r\n            if (videoInternalTexture) {\r\n                videoInternalTexture._associatedChannel = channel;\r\n            }\r\n            (<VideoTexture>texture).update();\r\n        } else if (texture.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            // Delay loading\r\n            texture.delayLoad();\r\n            return false;\r\n        }\r\n\r\n        let internalTexture: InternalTexture;\r\n        if (depthStencilTexture) {\r\n            internalTexture = (<RenderTargetTexture>texture).depthStencilTexture!;\r\n        } else if (texture.isReady()) {\r\n            internalTexture = <InternalTexture>texture.getInternalTexture();\r\n        } else if (texture.isCube) {\r\n            internalTexture = this.emptyCubeTexture;\r\n        } else if (texture.is3D) {\r\n            internalTexture = this.emptyTexture3D;\r\n        } else if (texture.is2DArray) {\r\n            internalTexture = this.emptyTexture2DArray;\r\n        } else {\r\n            internalTexture = this.emptyTexture;\r\n        }\r\n\r\n        if (!isPartOfTextureArray && internalTexture) {\r\n            internalTexture._associatedChannel = channel;\r\n        }\r\n\r\n        let needToBind = true;\r\n        if (this._boundTexturesCache[channel] === internalTexture) {\r\n            if (!isPartOfTextureArray) {\r\n                this._bindSamplerUniformToChannel(internalTexture._associatedChannel, channel);\r\n            }\r\n\r\n            needToBind = false;\r\n        }\r\n\r\n        this._activeChannel = channel;\r\n        const target = this._getTextureTarget(internalTexture);\r\n        if (needToBind) {\r\n            this._bindTextureDirectly(target, internalTexture, isPartOfTextureArray);\r\n        }\r\n\r\n        if (internalTexture && !internalTexture.isMultiview) {\r\n            // CUBIC_MODE and SKYBOX_MODE both require CLAMP_TO_EDGE.  All other modes use REPEAT.\r\n            if (internalTexture.isCube && internalTexture._cachedCoordinatesMode !== texture.coordinatesMode) {\r\n                internalTexture._cachedCoordinatesMode = texture.coordinatesMode;\r\n\r\n                const textureWrapMode =\r\n                    texture.coordinatesMode !== Constants.TEXTURE_CUBIC_MODE && texture.coordinatesMode !== Constants.TEXTURE_SKYBOX_MODE\r\n                        ? Constants.TEXTURE_WRAP_ADDRESSMODE\r\n                        : Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                texture.wrapU = textureWrapMode;\r\n                texture.wrapV = textureWrapMode;\r\n            }\r\n\r\n            if (internalTexture._cachedWrapU !== texture.wrapU) {\r\n                internalTexture._cachedWrapU = texture.wrapU;\r\n                this._setTextureParameterInteger(target, this._gl.TEXTURE_WRAP_S, this._getTextureWrapMode(texture.wrapU), internalTexture);\r\n            }\r\n\r\n            if (internalTexture._cachedWrapV !== texture.wrapV) {\r\n                internalTexture._cachedWrapV = texture.wrapV;\r\n                this._setTextureParameterInteger(target, this._gl.TEXTURE_WRAP_T, this._getTextureWrapMode(texture.wrapV), internalTexture);\r\n            }\r\n\r\n            if (internalTexture.is3D && internalTexture._cachedWrapR !== texture.wrapR) {\r\n                internalTexture._cachedWrapR = texture.wrapR;\r\n                this._setTextureParameterInteger(target, this._gl.TEXTURE_WRAP_R, this._getTextureWrapMode(texture.wrapR), internalTexture);\r\n            }\r\n\r\n            this._setAnisotropicLevel(target, internalTexture, texture.anisotropicFilteringLevel);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Sets an array of texture to the webGL context\r\n     * @param channel defines the channel where the texture array must be set\r\n     * @param uniform defines the associated uniform location\r\n     * @param textures defines the array of textures to bind\r\n     * @param name name of the channel\r\n     */\r\n    public setTextureArray(channel: number, uniform: Nullable<WebGLUniformLocation>, textures: ThinTexture[], name: string): void {\r\n        if (channel === undefined || !uniform) {\r\n            return;\r\n        }\r\n\r\n        if (!this._textureUnits || this._textureUnits.length !== textures.length) {\r\n            this._textureUnits = new Int32Array(textures.length);\r\n        }\r\n        for (let i = 0; i < textures.length; i++) {\r\n            const texture = textures[i].getInternalTexture();\r\n\r\n            if (texture) {\r\n                this._textureUnits[i] = channel + i;\r\n                texture._associatedChannel = channel + i;\r\n            } else {\r\n                this._textureUnits[i] = -1;\r\n            }\r\n        }\r\n        this._gl.uniform1iv(uniform, this._textureUnits);\r\n\r\n        for (let index = 0; index < textures.length; index++) {\r\n            this._setTexture(this._textureUnits[index], textures[index], true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setAnisotropicLevel(target: number, internalTexture: InternalTexture, anisotropicFilteringLevel: number) {\r\n        const anisotropicFilterExtension = this._caps.textureAnisotropicFilterExtension;\r\n        if (\r\n            internalTexture.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST &&\r\n            internalTexture.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR &&\r\n            internalTexture.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR\r\n        ) {\r\n            anisotropicFilteringLevel = 1; // Forcing the anisotropic to 1 because else webgl will force filters to linear\r\n        }\r\n\r\n        if (anisotropicFilterExtension && internalTexture._cachedAnisotropicFilteringLevel !== anisotropicFilteringLevel) {\r\n            this._setTextureParameterFloat(\r\n                target,\r\n                anisotropicFilterExtension.TEXTURE_MAX_ANISOTROPY_EXT,\r\n                Math.min(anisotropicFilteringLevel, this._caps.maxAnisotropy),\r\n                internalTexture\r\n            );\r\n            internalTexture._cachedAnisotropicFilteringLevel = anisotropicFilteringLevel;\r\n        }\r\n    }\r\n\r\n    private _setTextureParameterFloat(target: number, parameter: number, value: number, texture: InternalTexture): void {\r\n        this._bindTextureDirectly(target, texture, true, true);\r\n        this._gl.texParameterf(target, parameter, value);\r\n    }\r\n\r\n    private _setTextureParameterInteger(target: number, parameter: number, value: number, texture?: InternalTexture) {\r\n        if (texture) {\r\n            this._bindTextureDirectly(target, texture, true, true);\r\n        }\r\n        this._gl.texParameteri(target, parameter, value);\r\n    }\r\n\r\n    /**\r\n     * Unbind all vertex attributes from the webGL context\r\n     */\r\n    public unbindAllAttributes() {\r\n        if (this._mustWipeVertexAttributes) {\r\n            this._mustWipeVertexAttributes = false;\r\n\r\n            for (let i = 0; i < this._caps.maxVertexAttribs; i++) {\r\n                this.disableAttributeByIndex(i);\r\n            }\r\n            return;\r\n        }\r\n\r\n        for (let i = 0, ul = this._vertexAttribArraysEnabled.length; i < ul; i++) {\r\n            if (i >= this._caps.maxVertexAttribs || !this._vertexAttribArraysEnabled[i]) {\r\n                continue;\r\n            }\r\n\r\n            this.disableAttributeByIndex(i);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Force the engine to release all cached effects. This means that next effect compilation will have to be done completely even if a similar effect was already compiled\r\n     */\r\n    public releaseEffects() {\r\n        this._compiledEffects = {};\r\n        this.onReleaseEffectsObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Dispose and release all associated resources\r\n     */\r\n    public override dispose(): void {\r\n        // Events\r\n        if (IsWindowObjectExist()) {\r\n            if (this._renderingCanvas) {\r\n                this._renderingCanvas.removeEventListener(\"webglcontextlost\", this._onContextLost);\r\n\r\n                if (this._onContextRestored) {\r\n                    this._renderingCanvas.removeEventListener(\"webglcontextrestored\", this._onContextRestored);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Should not be moved up of renderingCanvas will be null.\r\n        super.dispose();\r\n\r\n        if (this._dummyFramebuffer) {\r\n            this._gl.deleteFramebuffer(this._dummyFramebuffer);\r\n        }\r\n\r\n        // Unbind\r\n        this.unbindAllAttributes();\r\n        this._boundUniforms = {};\r\n\r\n        this._workingCanvas = null;\r\n        this._workingContext = null;\r\n        this._currentBufferPointers.length = 0;\r\n        this._currentProgram = null;\r\n\r\n        if ((this._creationOptions as EngineOptions).loseContextOnDispose) {\r\n            this._gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\r\n        }\r\n        // clear the state object\r\n        deleteStateObject(this._gl);\r\n    }\r\n\r\n    /**\r\n     * Attach a new callback raised when context lost event is fired\r\n     * @param callback defines the callback to call\r\n     */\r\n    public attachContextLostEvent(callback: (event: WebGLContextEvent) => void): void {\r\n        if (this._renderingCanvas) {\r\n            this._renderingCanvas.addEventListener(\"webglcontextlost\", <any>callback, false);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attach a new callback raised when context restored event is fired\r\n     * @param callback defines the callback to call\r\n     */\r\n    public attachContextRestoredEvent(callback: (event: WebGLContextEvent) => void): void {\r\n        if (this._renderingCanvas) {\r\n            this._renderingCanvas.addEventListener(\"webglcontextrestored\", <any>callback, false);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the current error code of the webGL context\r\n     * @returns the error code\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getError\r\n     */\r\n    public getError(): number {\r\n        return this._gl.getError();\r\n    }\r\n\r\n    private _canRenderToFloatFramebuffer(): boolean {\r\n        if (this._webGLVersion > 1) {\r\n            return this._caps.colorBufferFloat;\r\n        }\r\n        return this._canRenderToFramebuffer(Constants.TEXTURETYPE_FLOAT);\r\n    }\r\n\r\n    private _canRenderToHalfFloatFramebuffer(): boolean {\r\n        if (this._webGLVersion > 1) {\r\n            return this._caps.colorBufferFloat;\r\n        }\r\n        return this._canRenderToFramebuffer(Constants.TEXTURETYPE_HALF_FLOAT);\r\n    }\r\n\r\n    // Thank you : http://stackoverflow.com/questions/28827511/webgl-ios-render-to-floating-point-texture\r\n    private _canRenderToFramebuffer(type: number): boolean {\r\n        const gl = this._gl;\r\n\r\n        //clear existing errors\r\n        // eslint-disable-next-line no-empty\r\n        while (gl.getError() !== gl.NO_ERROR) {}\r\n\r\n        let successful = true;\r\n\r\n        const texture = gl.createTexture();\r\n        gl.bindTexture(gl.TEXTURE_2D, texture);\r\n        gl.texImage2D(gl.TEXTURE_2D, 0, this._getRGBABufferInternalSizedFormat(type), 1, 1, 0, gl.RGBA, this._getWebGLTextureType(type), null);\r\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n\r\n        const fb = gl.createFramebuffer();\r\n        gl.bindFramebuffer(gl.FRAMEBUFFER, fb);\r\n        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n        const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\r\n\r\n        successful = successful && status === gl.FRAMEBUFFER_COMPLETE;\r\n        successful = successful && gl.getError() === gl.NO_ERROR;\r\n\r\n        //try render by clearing frame buffer's color buffer\r\n        if (successful) {\r\n            gl.clear(gl.COLOR_BUFFER_BIT);\r\n            successful = successful && gl.getError() === gl.NO_ERROR;\r\n        }\r\n\r\n        //try reading from frame to ensure render occurs (just creating the FBO is not sufficient to determine if rendering is supported)\r\n        if (successful) {\r\n            //in practice it's sufficient to just read from the backbuffer rather than handle potentially issues reading from the texture\r\n            gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n            const readFormat = gl.RGBA;\r\n            const readType = gl.UNSIGNED_BYTE;\r\n            const buffer = new Uint8Array(4);\r\n            gl.readPixels(0, 0, 1, 1, readFormat, readType, buffer);\r\n            successful = successful && gl.getError() === gl.NO_ERROR;\r\n        }\r\n\r\n        //clean up\r\n        gl.deleteTexture(texture);\r\n        gl.deleteFramebuffer(fb);\r\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n\r\n        //clear accumulated errors\r\n        // eslint-disable-next-line no-empty\r\n        while (!successful && gl.getError() !== gl.NO_ERROR) {}\r\n\r\n        return successful;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getWebGLTextureType(type: number): number {\r\n        if (this._webGLVersion === 1) {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_FLOAT:\r\n                    return this._gl.FLOAT;\r\n                case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                    return this._gl.HALF_FLOAT_OES;\r\n                case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                    return this._gl.UNSIGNED_BYTE;\r\n                case Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:\r\n                    return this._gl.UNSIGNED_SHORT_4_4_4_4;\r\n                case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:\r\n                    return this._gl.UNSIGNED_SHORT_5_5_5_1;\r\n                case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:\r\n                    return this._gl.UNSIGNED_SHORT_5_6_5;\r\n            }\r\n            return this._gl.UNSIGNED_BYTE;\r\n        }\r\n\r\n        switch (type) {\r\n            case Constants.TEXTURETYPE_BYTE:\r\n                return this._gl.BYTE;\r\n            case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                return this._gl.UNSIGNED_BYTE;\r\n            case Constants.TEXTURETYPE_SHORT:\r\n                return this._gl.SHORT;\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                return this._gl.UNSIGNED_SHORT;\r\n            case Constants.TEXTURETYPE_INT:\r\n                return this._gl.INT;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INTEGER: // Refers to UNSIGNED_INT\r\n                return this._gl.UNSIGNED_INT;\r\n            case Constants.TEXTURETYPE_FLOAT:\r\n                return this._gl.FLOAT;\r\n            case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                return this._gl.HALF_FLOAT;\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:\r\n                return this._gl.UNSIGNED_SHORT_4_4_4_4;\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:\r\n                return this._gl.UNSIGNED_SHORT_5_5_5_1;\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:\r\n                return this._gl.UNSIGNED_SHORT_5_6_5;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:\r\n                return this._gl.UNSIGNED_INT_2_10_10_10_REV;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_24_8:\r\n                return this._gl.UNSIGNED_INT_24_8;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:\r\n                return this._gl.UNSIGNED_INT_10F_11F_11F_REV;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:\r\n                return this._gl.UNSIGNED_INT_5_9_9_9_REV;\r\n            case Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV:\r\n                return this._gl.FLOAT_32_UNSIGNED_INT_24_8_REV;\r\n        }\r\n\r\n        return this._gl.UNSIGNED_BYTE;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getInternalFormat(format: number, useSRGBBuffer = false): number {\r\n        let internalFormat: GLenum = useSRGBBuffer ? this._glSRGBExtensionValues.SRGB8_ALPHA8 : this._gl.RGBA;\r\n\r\n        switch (format) {\r\n            case Constants.TEXTUREFORMAT_ALPHA:\r\n                internalFormat = this._gl.ALPHA;\r\n                break;\r\n            case Constants.TEXTUREFORMAT_LUMINANCE:\r\n                internalFormat = this._gl.LUMINANCE;\r\n                break;\r\n            case Constants.TEXTUREFORMAT_LUMINANCE_ALPHA:\r\n                internalFormat = this._gl.LUMINANCE_ALPHA;\r\n                break;\r\n            case Constants.TEXTUREFORMAT_RED:\r\n            case Constants.TEXTUREFORMAT_R16_UNORM:\r\n            case Constants.TEXTUREFORMAT_R16_SNORM:\r\n                internalFormat = this._gl.RED;\r\n                break;\r\n            case Constants.TEXTUREFORMAT_RG:\r\n            case Constants.TEXTUREFORMAT_RG16_UNORM:\r\n            case Constants.TEXTUREFORMAT_RG16_SNORM:\r\n                internalFormat = this._gl.RG;\r\n                break;\r\n            case Constants.TEXTUREFORMAT_RGB:\r\n            case Constants.TEXTUREFORMAT_RGB16_UNORM:\r\n            case Constants.TEXTUREFORMAT_RGB16_SNORM:\r\n                internalFormat = useSRGBBuffer ? this._glSRGBExtensionValues.SRGB : this._gl.RGB;\r\n                break;\r\n            case Constants.TEXTUREFORMAT_RGBA:\r\n            case Constants.TEXTUREFORMAT_RGBA16_UNORM:\r\n            case Constants.TEXTUREFORMAT_RGBA16_SNORM:\r\n                internalFormat = useSRGBBuffer ? this._glSRGBExtensionValues.SRGB8_ALPHA8 : this._gl.RGBA;\r\n                break;\r\n        }\r\n\r\n        if (this._webGLVersion > 1) {\r\n            switch (format) {\r\n                case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                    internalFormat = this._gl.RED_INTEGER;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                    internalFormat = this._gl.RG_INTEGER;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                    internalFormat = this._gl.RGB_INTEGER;\r\n                    break;\r\n                case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                    internalFormat = this._gl.RGBA_INTEGER;\r\n                    break;\r\n            }\r\n        }\r\n\r\n        return internalFormat;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getRGBABufferInternalSizedFormat(type: number, format?: number, useSRGBBuffer = false): number {\r\n        if (this._webGLVersion === 1) {\r\n            if (format !== undefined) {\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_ALPHA:\r\n                        return this._gl.ALPHA;\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE:\r\n                        return this._gl.LUMINANCE;\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE_ALPHA:\r\n                        return this._gl.LUMINANCE_ALPHA;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return useSRGBBuffer ? this._glSRGBExtensionValues.SRGB : this._gl.RGB;\r\n                }\r\n            }\r\n            return this._gl.RGBA;\r\n        }\r\n\r\n        switch (type) {\r\n            case Constants.TEXTURETYPE_BYTE:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return this._gl.R8_SNORM;\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return this._gl.RG8_SNORM;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return this._gl.RGB8_SNORM;\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return this._gl.R8I;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return this._gl.RG8I;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return this._gl.RGB8I;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGBA8I;\r\n                    default:\r\n                        return this._gl.RGBA8_SNORM;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return this._gl.R8;\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return this._gl.RG8;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return useSRGBBuffer ? this._glSRGBExtensionValues.SRGB8 : this._gl.RGB8; // By default. Other possibilities are RGB565, SRGB8.\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return useSRGBBuffer ? this._glSRGBExtensionValues.SRGB8_ALPHA8 : this._gl.RGBA8; // By default. Other possibilities are RGB5_A1, RGBA4, SRGB8_ALPHA8.\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return this._gl.R8UI;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return this._gl.RG8UI;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return this._gl.RGB8UI;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGBA8UI;\r\n                    case Constants.TEXTUREFORMAT_ALPHA:\r\n                        return this._gl.ALPHA;\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE:\r\n                        return this._gl.LUMINANCE;\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE_ALPHA:\r\n                        return this._gl.LUMINANCE_ALPHA;\r\n                    default:\r\n                        return this._gl.RGBA8;\r\n                }\r\n            case Constants.TEXTURETYPE_SHORT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return this._gl.R16I;\r\n                    case Constants.TEXTUREFORMAT_R16_SNORM:\r\n                        return this._gl.R16_SNORM_EXT;\r\n                    case Constants.TEXTUREFORMAT_RG16_SNORM:\r\n                        return this._gl.RG16_SNORM_EXT;\r\n                    case Constants.TEXTUREFORMAT_RGB16_SNORM:\r\n                        return this._gl.RGB16_SNORM_EXT;\r\n                    case Constants.TEXTUREFORMAT_RGBA16_SNORM:\r\n                        return this._gl.RGBA16_SNORM_EXT;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return this._gl.RG16I;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return this._gl.RGB16I;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGBA16I;\r\n                    default:\r\n                        return this._gl.RGBA16I;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return this._gl.R16UI;\r\n                    case Constants.TEXTUREFORMAT_R16_UNORM:\r\n                        return this._gl.R16_EXT;\r\n                    case Constants.TEXTUREFORMAT_RG16_UNORM:\r\n                        return this._gl.RG16_EXT;\r\n                    case Constants.TEXTUREFORMAT_RGB16_UNORM:\r\n                        return this._gl.RGB16_EXT;\r\n                    case Constants.TEXTUREFORMAT_RGBA16_UNORM:\r\n                        return this._gl.RGBA16_EXT;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return this._gl.RG16UI;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return this._gl.RGB16UI;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGBA16UI;\r\n                    default:\r\n                        return this._gl.RGBA16UI;\r\n                }\r\n            case Constants.TEXTURETYPE_INT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return this._gl.R32I;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return this._gl.RG32I;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return this._gl.RGB32I;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGBA32I;\r\n                    default:\r\n                        return this._gl.RGBA32I;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_INTEGER: // Refers to UNSIGNED_INT\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return this._gl.R32UI;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return this._gl.RG32UI;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return this._gl.RGB32UI;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGBA32UI;\r\n                    default:\r\n                        return this._gl.RGBA32UI;\r\n                }\r\n            case Constants.TEXTURETYPE_FLOAT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return this._gl.R32F; // By default. Other possibility is R16F.\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return this._gl.RG32F; // By default. Other possibility is RG16F.\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return this._gl.RGB32F; // By default. Other possibilities are RGB16F, R11F_G11F_B10F, RGB9_E5.\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return this._gl.RGBA32F; // By default. Other possibility is RGBA16F.\r\n                    default:\r\n                        return this._gl.RGBA32F;\r\n                }\r\n            case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return this._gl.R16F;\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return this._gl.RG16F;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return this._gl.RGB16F; // By default. Other possibilities are R11F_G11F_B10F, RGB9_E5.\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return this._gl.RGBA16F;\r\n                    default:\r\n                        return this._gl.RGBA16F;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:\r\n                return this._gl.RGB565;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:\r\n                return this._gl.R11F_G11F_B10F;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:\r\n                return this._gl.RGB9_E5;\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:\r\n                return this._gl.RGBA4;\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:\r\n                return this._gl.RGB5_A1;\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return this._gl.RGB10_A2; // By default. Other possibility is RGB5_A1.\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return this._gl.RGB10_A2UI;\r\n                    default:\r\n                        return this._gl.RGB10_A2;\r\n                }\r\n        }\r\n\r\n        return useSRGBBuffer ? this._glSRGBExtensionValues.SRGB8_ALPHA8 : this._gl.RGBA8;\r\n    }\r\n\r\n    /**\r\n     * Reads pixels from the current frame buffer. Please note that this function can be slow\r\n     * @param x defines the x coordinate of the rectangle where pixels must be read\r\n     * @param y defines the y coordinate of the rectangle where pixels must be read\r\n     * @param width defines the width of the rectangle where pixels must be read\r\n     * @param height defines the height of the rectangle where pixels must be read\r\n     * @param hasAlpha defines whether the output should have alpha or not (defaults to true)\r\n     * @param flushRenderer true to flush the renderer from the pending commands before reading the pixels\r\n     * @param data defines the data to fill with the read pixels (if not provided, a new one will be created)\r\n     * @returns a ArrayBufferView promise (Uint8Array) containing RGBA colors\r\n     */\r\n    // Async function, not named Async and not marked as async to avoid breaking changes\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public readPixels(x: number, y: number, width: number, height: number, hasAlpha = true, flushRenderer = true, data: Nullable<Uint8Array> = null): Promise<ArrayBufferView> {\r\n        const numChannels = hasAlpha ? 4 : 3;\r\n        const format = hasAlpha ? this._gl.RGBA : this._gl.RGB;\r\n\r\n        const dataLength = width * height * numChannels;\r\n        if (!data) {\r\n            data = new Uint8Array(dataLength);\r\n        } else if (data.length < dataLength) {\r\n            Logger.Error(`Data buffer is too small to store the read pixels (${data.length} should be more than ${dataLength})`);\r\n            return Promise.resolve(data);\r\n        }\r\n\r\n        if (flushRenderer) {\r\n            this.flushFramebuffer();\r\n        }\r\n        this._gl.readPixels(x, y, width, height, format, this._gl.UNSIGNED_BYTE, data);\r\n        return Promise.resolve(data);\r\n    }\r\n\r\n    // Statics\r\n\r\n    private static _IsSupported: Nullable<boolean> = null;\r\n    private static _HasMajorPerformanceCaveat: Nullable<boolean> = null;\r\n\r\n    /**\r\n     * Gets a Promise<boolean> indicating if the engine can be instantiated (ie. if a webGL context can be found)\r\n     */\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public static get IsSupportedAsync(): Promise<boolean> {\r\n        return Promise.resolve(this.isSupported());\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the engine can be instantiated (ie. if a webGL context can be found)\r\n     */\r\n    public static get IsSupported(): boolean {\r\n        return this.isSupported(); // Backward compat\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the engine can be instantiated (ie. if a webGL context can be found)\r\n     * @returns true if the engine can be created\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static isSupported(): boolean {\r\n        if (this._HasMajorPerformanceCaveat !== null) {\r\n            return !this._HasMajorPerformanceCaveat; // We know it is performant so WebGL is supported\r\n        }\r\n\r\n        if (this._IsSupported === null) {\r\n            try {\r\n                const tempcanvas = AbstractEngine._CreateCanvas(1, 1);\r\n                const gl = tempcanvas.getContext(\"webgl\") || (tempcanvas as any).getContext(\"experimental-webgl\");\r\n\r\n                this._IsSupported = gl != null && !!globalThis.WebGLRenderingContext;\r\n            } catch (e) {\r\n                this._IsSupported = false;\r\n            }\r\n        }\r\n\r\n        return this._IsSupported;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the engine can be instantiated on a performant device (ie. if a webGL context can be found and it does not use a slow implementation)\r\n     */\r\n    public static get HasMajorPerformanceCaveat(): boolean {\r\n        if (this._HasMajorPerformanceCaveat === null) {\r\n            try {\r\n                const tempcanvas = AbstractEngine._CreateCanvas(1, 1);\r\n                const gl =\r\n                    tempcanvas.getContext(\"webgl\", { failIfMajorPerformanceCaveat: true }) ||\r\n                    (tempcanvas as any).getContext(\"experimental-webgl\", { failIfMajorPerformanceCaveat: true });\r\n\r\n                this._HasMajorPerformanceCaveat = !gl;\r\n            } catch (e) {\r\n                this._HasMajorPerformanceCaveat = false;\r\n            }\r\n        }\r\n\r\n        return this._HasMajorPerformanceCaveat;\r\n    }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ninterface TexImageParameters {\r\n    internalFormat: number;\r\n    format: number;\r\n    type: number;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { type IndicesArray, type DataArray } from \"../../types\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for engineDynamicBuffer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEngineDynamicBuffer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    ThinEngine.prototype.updateDynamicIndexBuffer = function (this: ThinEngine, indexBuffer: DataBuffer, indices: IndicesArray, offset: number = 0): void {\r\n        // Force cache update\r\n        this._currentBoundBuffer[this._gl.ELEMENT_ARRAY_BUFFER] = null;\r\n        this.bindIndexBuffer(indexBuffer);\r\n\r\n        let view: ArrayBufferView;\r\n        if (indexBuffer.is32Bits) {\r\n            // anything else than Uint32Array needs to be converted to Uint32Array\r\n            view = indices instanceof Uint32Array ? indices : new Uint32Array(indices);\r\n        } else {\r\n            // anything else than Uint16Array needs to be converted to Uint16Array\r\n            view = indices instanceof Uint16Array ? indices : new Uint16Array(indices);\r\n        }\r\n\r\n        this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, view, this._gl.DYNAMIC_DRAW);\r\n\r\n        this._resetIndexBufferBinding();\r\n    };\r\n\r\n    ThinEngine.prototype.updateDynamicVertexBuffer = function (this: ThinEngine, vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void {\r\n        this.bindArrayBuffer(vertexBuffer);\r\n\r\n        if (byteOffset === undefined) {\r\n            byteOffset = 0;\r\n        }\r\n\r\n        const dataLength = (data as ArrayBuffer).byteLength || (data as number[]).length;\r\n\r\n        if (byteLength === undefined || (byteLength >= dataLength && byteOffset === 0)) {\r\n            if (data instanceof Array) {\r\n                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data));\r\n            } else {\r\n                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);\r\n            }\r\n        } else {\r\n            if (data instanceof Array) {\r\n                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data).subarray(0, byteLength / 4));\r\n            } else {\r\n                if (ArrayBuffer.isView(data)) {\r\n                    data = new Uint8Array(data.buffer, data.byteOffset, byteLength);\r\n                } else {\r\n                    data = new Uint8Array(data, 0, byteLength);\r\n                }\r\n\r\n                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);\r\n            }\r\n        }\r\n\r\n        this._resetVertexBufferBinding();\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type DataArray, type FloatArray } from \"../types\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { DataBuffer } from \"./dataBuffer\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EnumerateFloatValues, GetFloatData, GetTypeByteLength } from \"./bufferUtils\";\r\nimport { RegisterEngineDynamicBuffer } from \"../Engines/Extensions/engine.dynamicBuffer.pure\";\r\n\r\n/**\r\n * Class used to store data that will be store in GPU memory\r\n */\r\nexport class Buffer {\r\n    private _engine: AbstractEngine;\r\n    private _buffer: Nullable<DataBuffer>;\r\n    /** @internal */\r\n    public _data: Nullable<DataArray>;\r\n    private _updatable: boolean;\r\n    private _instanced: boolean;\r\n    private _divisor: number;\r\n    private _isAlreadyOwned = false;\r\n    private _isDisposed = false;\r\n    private _label?: string;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the Buffer is disposed\r\n     */\r\n    public get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Gets the byte stride.\r\n     */\r\n    public readonly byteStride: number;\r\n\r\n    /**\r\n     * Constructor\r\n     * @param engine the engine\r\n     * @param data the data to use for this buffer\r\n     * @param updatable whether the data is updatable\r\n     * @param stride the stride (optional)\r\n     * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)\r\n     * @param instanced whether the buffer is instanced (optional)\r\n     * @param useBytes set to true if the stride in in bytes (optional)\r\n     * @param divisor sets an optional divisor for instances (1 by default)\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     */\r\n    constructor(\r\n        engine: AbstractEngine,\r\n        data: DataArray | DataBuffer,\r\n        updatable: boolean,\r\n        stride = 0,\r\n        postponeInternalCreation = false,\r\n        instanced = false,\r\n        useBytes = false,\r\n        divisor?: number,\r\n        label?: string\r\n    ) {\r\n        RegisterEngineDynamicBuffer();\r\n        if (engine && (engine as unknown as Mesh).getScene) {\r\n            // old versions of VertexBuffer accepted 'mesh' instead of 'engine'\r\n            this._engine = (engine as unknown as Mesh).getScene().getEngine();\r\n        } else {\r\n            this._engine = engine;\r\n        }\r\n\r\n        this._updatable = updatable;\r\n        this._instanced = instanced;\r\n        this._divisor = divisor || 1;\r\n        this._label = label;\r\n\r\n        if (data instanceof DataBuffer) {\r\n            this._data = null;\r\n            this._buffer = data;\r\n        } else {\r\n            this._data = data;\r\n            this._buffer = null;\r\n        }\r\n\r\n        this.byteStride = useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT;\r\n\r\n        if (!postponeInternalCreation) {\r\n            // by default\r\n            this.create();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a new VertexBuffer based on the current buffer\r\n     * @param kind defines the vertex buffer kind (position, normal, etc.)\r\n     * @param offset defines offset in the buffer (0 by default)\r\n     * @param size defines the size in floats of attributes (position is 3 for instance)\r\n     * @param stride defines the stride size in floats in the buffer (the offset to apply to reach next value when data is interleaved)\r\n     * @param instanced defines if the vertex buffer contains indexed data\r\n     * @param useBytes defines if the offset and stride are in bytes     *\r\n     * @param divisor sets an optional divisor for instances (1 by default)\r\n     * @returns the new vertex buffer\r\n     */\r\n    public createVertexBuffer(kind: string, offset: number, size: number, stride?: number, instanced?: boolean, useBytes = false, divisor?: number): VertexBuffer {\r\n        const byteOffset = useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT;\r\n        const byteStride = stride ? (useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT) : this.byteStride;\r\n\r\n        // a lot of these parameters are ignored as they are overridden by the buffer\r\n        return new VertexBuffer(\r\n            this._engine,\r\n            this,\r\n            kind,\r\n            this._updatable,\r\n            true,\r\n            byteStride,\r\n            instanced === undefined ? this._instanced : instanced,\r\n            byteOffset,\r\n            size,\r\n            undefined,\r\n            undefined,\r\n            true,\r\n            this._divisor || divisor\r\n        );\r\n    }\r\n\r\n    // Properties\r\n\r\n    /**\r\n     * Gets a boolean indicating if the Buffer is updatable?\r\n     * @returns true if the buffer is updatable\r\n     */\r\n    public isUpdatable(): boolean {\r\n        return this._updatable;\r\n    }\r\n\r\n    /**\r\n     * Gets current buffer's data\r\n     * @returns a DataArray or null\r\n     */\r\n    public getData(): Nullable<DataArray> {\r\n        return this._data;\r\n    }\r\n\r\n    /**\r\n     * Gets underlying native buffer\r\n     * @returns underlying native buffer\r\n     */\r\n    public getBuffer(): Nullable<DataBuffer> {\r\n        return this._buffer;\r\n    }\r\n\r\n    /**\r\n     * Gets the stride in float32 units (i.e. byte stride / 4).\r\n     * May not be an integer if the byte stride is not divisible by 4.\r\n     * @returns the stride in float32 units\r\n     * @deprecated Please use byteStride instead.\r\n     */\r\n    public getStrideSize(): number {\r\n        return this.byteStride / Float32Array.BYTES_PER_ELEMENT;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Store data into the buffer. Creates the buffer if not used already.\r\n     * If the buffer was already used, it will be updated only if it is updatable, otherwise it will do nothing.\r\n     * @param data defines the data to store\r\n     */\r\n    public create(data: Nullable<DataArray> = null): void {\r\n        if (!data && this._buffer) {\r\n            return; // nothing to do\r\n        }\r\n\r\n        data = data || this._data;\r\n\r\n        if (!data) {\r\n            return;\r\n        }\r\n\r\n        if (!this._buffer) {\r\n            // create buffer\r\n            if (this._updatable) {\r\n                this._buffer = this._engine.createDynamicVertexBuffer(data, this._label);\r\n                this._data = data;\r\n            } else {\r\n                this._buffer = this._engine.createVertexBuffer(data, undefined, this._label);\r\n            }\r\n        } else if (this._updatable) {\r\n            // update buffer\r\n            this._engine.updateDynamicVertexBuffer(this._buffer, data);\r\n            this._data = data;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        if (!this._data) {\r\n            if (!this._buffer) {\r\n                // Buffer was not yet created, nothing to do\r\n                return;\r\n            }\r\n            if (this._buffer.capacity > 0) {\r\n                // We can at least recreate the buffer with the right size, even if we don't have the data\r\n                if (this._updatable) {\r\n                    this._buffer = this._engine.createDynamicVertexBuffer(this._buffer.capacity, this._label);\r\n                } else {\r\n                    this._buffer = this._engine.createVertexBuffer(this._buffer.capacity, undefined, this._label);\r\n                }\r\n                return;\r\n            }\r\n            Logger.Warn(`Missing data for buffer \"${this._label}\" ${this._buffer ? \"(uniqueId: \" + this._buffer.uniqueId + \")\" : \"\"}. Buffer reconstruction failed.`);\r\n            this._buffer = null;\r\n        } else {\r\n            this._buffer = null;\r\n            this.create(this._data);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update current buffer data\r\n     * @param data defines the data to store\r\n     */\r\n    public update(data: DataArray): void {\r\n        this.create(data);\r\n    }\r\n\r\n    /**\r\n     * Updates the data directly.\r\n     * @param data the new data\r\n     * @param offset the new offset\r\n     * @param vertexCount the vertex count (optional)\r\n     * @param useBytes set to true if the offset is in bytes\r\n     */\r\n    public updateDirectly(data: DataArray, offset: number, vertexCount?: number, useBytes: boolean = false): void {\r\n        if (!this._buffer) {\r\n            return;\r\n        }\r\n\r\n        if (this._updatable) {\r\n            // update buffer\r\n            this._engine.updateDynamicVertexBuffer(\r\n                this._buffer,\r\n                data,\r\n                useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT,\r\n                vertexCount ? vertexCount * this.byteStride : undefined\r\n            );\r\n            if (offset === 0 && vertexCount === undefined) {\r\n                // Keep the data if we easily can\r\n                this._data = data;\r\n            } else {\r\n                this._data = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _increaseReferences() {\r\n        if (!this._buffer) {\r\n            return;\r\n        }\r\n\r\n        if (!this._isAlreadyOwned) {\r\n            this._isAlreadyOwned = true;\r\n            return;\r\n        }\r\n\r\n        this._buffer.references++;\r\n    }\r\n\r\n    /**\r\n     * Release all resources\r\n     */\r\n    public dispose(): void {\r\n        if (!this._buffer) {\r\n            return;\r\n        }\r\n\r\n        // The data buffer has an internal counter as this buffer can be used by several VertexBuffer objects\r\n        // This means that we only flag it as disposed when all references are released (when _releaseBuffer will return true)\r\n        if (this._engine._releaseBuffer(this._buffer)) {\r\n            this._isDisposed = true;\r\n            this._data = null;\r\n            this._buffer = null;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Options to be used when creating a vertex buffer\r\n */\r\nexport interface IVertexBufferOptions {\r\n    /**\r\n     * whether the data is updatable (default: false)\r\n     */\r\n    updatable?: boolean;\r\n    /**\r\n     * whether to postpone creating the internal WebGL buffer (default: false)\r\n     */\r\n    postponeInternalCreation?: boolean;\r\n    /**\r\n     * the stride (will be automatically computed from the kind parameter if not specified)\r\n     */\r\n    stride?: number;\r\n    /**\r\n     * whether the buffer is instanced (default: false)\r\n     */\r\n    instanced?: boolean;\r\n    /**\r\n     * the offset of the data (default: 0)\r\n     */\r\n    offset?: number;\r\n    /**\r\n     * the number of components (will be automatically computed from the kind parameter if not specified)\r\n     */\r\n    size?: number;\r\n    /**\r\n     * the type of the component (will be deduce from the data parameter if not specified)\r\n     */\r\n    type?: number;\r\n    /**\r\n     * whether the data contains normalized data (default: false)\r\n     */\r\n    normalized?: boolean;\r\n    /**\r\n     * set to true if stride and offset are in bytes (default: false)\r\n     */\r\n    useBytes?: boolean;\r\n    /**\r\n     * defines the instance divisor to use (default: 1, only used if instanced is true)\r\n     */\r\n    divisor?: number;\r\n    /**\r\n     * defines if the buffer should be released when the vertex buffer is disposed (default: false)\r\n     */\r\n    takeBufferOwnership?: boolean;\r\n    /**\r\n     * label to use for this vertex buffer (debugging purpose)\r\n     */\r\n    label?: string;\r\n}\r\n\r\n/**\r\n * Specialized buffer used to store vertex data\r\n */\r\nexport class VertexBuffer {\r\n    private static _Counter = 0;\r\n\r\n    /** @internal */\r\n    public _buffer: Buffer;\r\n    /** @internal */\r\n    public _validOffsetRange: boolean; // used internally by the engine\r\n    private _kind: string;\r\n    private _size: number;\r\n    /** @internal */\r\n    public _ownsBuffer: boolean;\r\n    private _instanced: boolean;\r\n    private _instanceDivisor: number;\r\n    /** @internal */\r\n    public _isDisposed = false;\r\n    /** @internal */\r\n    public _label?: string;\r\n\r\n    /**\r\n     * The byte type.\r\n     */\r\n    public static readonly BYTE = Constants.BYTE;\r\n\r\n    /**\r\n     * The unsigned byte type.\r\n     */\r\n    public static readonly UNSIGNED_BYTE = Constants.UNSIGNED_BYTE;\r\n\r\n    /**\r\n     * The short type.\r\n     */\r\n    public static readonly SHORT = Constants.SHORT;\r\n\r\n    /**\r\n     * The unsigned short type.\r\n     */\r\n    public static readonly UNSIGNED_SHORT = Constants.UNSIGNED_SHORT;\r\n\r\n    /**\r\n     * The integer type.\r\n     * Note: supported as a vertex attribute type only on the WebGL and WebGPU engines, not on Babylon Native.\r\n     */\r\n    public static readonly INT = Constants.INT;\r\n\r\n    /**\r\n     * The unsigned integer type.\r\n     * Note: supported as a vertex attribute type only on the WebGL and WebGPU engines, not on Babylon Native.\r\n     */\r\n    public static readonly UNSIGNED_INT = Constants.UNSIGNED_INT;\r\n\r\n    /**\r\n     * The float type.\r\n     */\r\n    public static readonly FLOAT = Constants.FLOAT;\r\n\r\n    /**\r\n     * The half float type.\r\n     * Note: supported as a vertex attribute type only on the WebGL and WebGPU engines, not on Babylon Native.\r\n     */\r\n    public static readonly HALF_FLOAT = Constants.HALF_FLOAT;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the Buffer is disposed\r\n     */\r\n    public get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the instance divisor when in instanced mode\r\n     */\r\n    public get instanceDivisor(): number {\r\n        return this._instanceDivisor;\r\n    }\r\n\r\n    public set instanceDivisor(value: number) {\r\n        const isInstanced = value != 0;\r\n        this._instanceDivisor = value;\r\n\r\n        if (isInstanced !== this._instanced) {\r\n            this._instanced = isInstanced;\r\n            this._computeHashCode();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the byte stride.\r\n     */\r\n    public readonly byteStride: number;\r\n\r\n    /**\r\n     * Gets the byte offset.\r\n     */\r\n    public readonly byteOffset: number;\r\n\r\n    /**\r\n     * Gets whether integer data values should be normalized into a certain range when being casted to a float.\r\n     */\r\n    public readonly normalized: boolean;\r\n\r\n    /**\r\n     * Gets the data type of each component in the array.\r\n     */\r\n    public readonly type: number;\r\n\r\n    /**\r\n     * Gets the unique id of this vertex buffer\r\n     */\r\n    public readonly uniqueId: number;\r\n\r\n    /**\r\n     * Gets a hash code representing the format (type, normalized, size, instanced, stride) of this buffer\r\n     * All buffers with the same format will have the same hash code\r\n     */\r\n    public readonly hashCode: number;\r\n\r\n    /**\r\n     * Gets the engine associated with the buffer\r\n     */\r\n    public readonly engine: AbstractEngine;\r\n\r\n    /**\r\n     * Gets the max possible amount of vertices stored within the current vertex buffer.\r\n     * We do not have the end offset or count so this will be too big for concatenated vertex buffers.\r\n     * @internal\r\n     */\r\n    public get _maxVerticesCount() {\r\n        const data = this.getData();\r\n        if (!data) {\r\n            return 0;\r\n        }\r\n\r\n        if (Array.isArray(data)) {\r\n            // data is a regular number[] with float values\r\n            return data.length / (this.byteStride / 4) - this.byteOffset / 4;\r\n        }\r\n\r\n        return (data.byteLength - this.byteOffset) / this.byteStride;\r\n    }\r\n\r\n    /**\r\n     * Constructor\r\n     * @param engine the engine\r\n     * @param data the data to use for this vertex buffer\r\n     * @param kind the vertex buffer kind\r\n     * @param updatable whether the data is updatable\r\n     * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)\r\n     * @param stride the stride (optional)\r\n     * @param instanced whether the buffer is instanced (optional)\r\n     * @param offset the offset of the data (optional)\r\n     * @param size the number of components (optional)\r\n     * @param type the type of the component (optional)\r\n     * @param normalized whether the data contains normalized data (optional)\r\n     * @param useBytes set to true if stride and offset are in bytes (optional)\r\n     * @param divisor defines the instance divisor to use (1 by default)\r\n     * @param takeBufferOwnership defines if the buffer should be released when the vertex buffer is disposed\r\n     */\r\n    constructor(\r\n        engine: AbstractEngine,\r\n        data: DataArray | Buffer | DataBuffer,\r\n        kind: string,\r\n        updatable: boolean,\r\n        postponeInternalCreation?: boolean,\r\n        stride?: number,\r\n        instanced?: boolean,\r\n        offset?: number,\r\n        size?: number,\r\n        type?: number,\r\n        normalized?: boolean,\r\n        useBytes?: boolean,\r\n        divisor?: number,\r\n        takeBufferOwnership?: boolean\r\n    );\r\n\r\n    /**\r\n     * Constructor\r\n     * @param engine the engine\r\n     * @param data the data to use for this vertex buffer\r\n     * @param kind the vertex buffer kind\r\n     * @param options defines the rest of the options used to create the buffer\r\n     */\r\n    constructor(engine: AbstractEngine, data: DataArray | Buffer | DataBuffer, kind: string, options?: IVertexBufferOptions);\r\n\r\n    /** @internal */\r\n    constructor(\r\n        engine: AbstractEngine,\r\n        data: DataArray | Buffer | DataBuffer,\r\n        kind: string,\r\n        updatableOrOptions?: boolean | IVertexBufferOptions,\r\n        postponeInternalCreation?: boolean,\r\n        stride?: number,\r\n        instanced?: boolean,\r\n        offset?: number,\r\n        size?: number,\r\n        type?: number,\r\n        normalized = false,\r\n        useBytes = false,\r\n        divisor = 1,\r\n        takeBufferOwnership = false\r\n    ) {\r\n        let updatable: boolean;\r\n\r\n        this.engine = engine;\r\n\r\n        if (typeof updatableOrOptions === \"object\" && updatableOrOptions !== null) {\r\n            updatable = updatableOrOptions.updatable ?? false;\r\n            postponeInternalCreation = updatableOrOptions.postponeInternalCreation;\r\n            stride = updatableOrOptions.stride;\r\n            instanced = updatableOrOptions.instanced;\r\n            offset = updatableOrOptions.offset;\r\n            size = updatableOrOptions.size;\r\n            type = updatableOrOptions.type;\r\n            normalized = updatableOrOptions.normalized ?? false;\r\n            useBytes = updatableOrOptions.useBytes ?? false;\r\n            divisor = updatableOrOptions.divisor ?? 1;\r\n            takeBufferOwnership = updatableOrOptions.takeBufferOwnership ?? false;\r\n            this._label = updatableOrOptions.label;\r\n        } else {\r\n            updatable = !!updatableOrOptions;\r\n        }\r\n\r\n        if (data instanceof Buffer) {\r\n            this._buffer = data;\r\n            this._ownsBuffer = takeBufferOwnership;\r\n        } else {\r\n            this._buffer = new Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes, divisor, this._label);\r\n            this._ownsBuffer = true;\r\n        }\r\n\r\n        this.uniqueId = VertexBuffer._Counter++;\r\n        this._kind = kind;\r\n\r\n        if (type === undefined) {\r\n            const vertexData = this.getData();\r\n            this.type = vertexData ? VertexBufferGetDataType(vertexData) : VertexBuffer.FLOAT;\r\n        } else {\r\n            this.type = type;\r\n        }\r\n\r\n        const typeByteLength = GetTypeByteLength(this.type);\r\n\r\n        if (useBytes) {\r\n            this._size = size || (stride ? stride / typeByteLength : VertexBufferDeduceStride(kind));\r\n            this.byteStride = stride || this._buffer.byteStride || this._size * typeByteLength;\r\n            this.byteOffset = offset || 0;\r\n        } else {\r\n            this._size = size || stride || VertexBufferDeduceStride(kind);\r\n            this.byteStride = stride ? stride * typeByteLength : this._buffer.byteStride || this._size * typeByteLength;\r\n            this.byteOffset = (offset || 0) * typeByteLength;\r\n        }\r\n\r\n        this.normalized = normalized;\r\n\r\n        this._instanced = instanced !== undefined ? instanced : false;\r\n        this._instanceDivisor = instanced ? divisor : 0;\r\n\r\n        this._alignBuffer();\r\n        this._computeHashCode();\r\n    }\r\n\r\n    private static _GetTypeHashIndex(type: number): number {\r\n        switch (type) {\r\n            case VertexBuffer.BYTE:\r\n                return 0;\r\n            case VertexBuffer.UNSIGNED_BYTE:\r\n                return 1;\r\n            case VertexBuffer.SHORT:\r\n                return 2;\r\n            case VertexBuffer.UNSIGNED_SHORT:\r\n                return 3;\r\n            case VertexBuffer.INT:\r\n                return 4;\r\n            case VertexBuffer.UNSIGNED_INT:\r\n                return 5;\r\n            case VertexBuffer.FLOAT:\r\n                return 6;\r\n            case VertexBuffer.HALF_FLOAT:\r\n                return 7;\r\n            default:\r\n                throw new Error(`Invalid vertex buffer type '${type}'`);\r\n        }\r\n    }\r\n\r\n    private _computeHashCode(): void {\r\n        // note: cast to any because the property is declared readonly\r\n        (this.hashCode as any) =\r\n            (VertexBuffer._GetTypeHashIndex(this.type) << 0) +\r\n            ((this.normalized ? 1 : 0) << 3) +\r\n            ((this._size - 1) << 4) +\r\n            ((this._instanced ? 1 : 0) << 6) +\r\n            /* keep 5 bits free */\r\n            (this.byteStride << 12);\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        this._buffer?._rebuild();\r\n    }\r\n\r\n    /**\r\n     * Returns the kind of the VertexBuffer (string)\r\n     * @returns a string\r\n     */\r\n    public getKind(): string {\r\n        return this._kind;\r\n    }\r\n\r\n    // Properties\r\n\r\n    /**\r\n     * Gets a boolean indicating if the VertexBuffer is updatable?\r\n     * @returns true if the buffer is updatable\r\n     */\r\n    public isUpdatable(): boolean {\r\n        return this._buffer.isUpdatable();\r\n    }\r\n\r\n    /**\r\n     * Gets the raw data from the underlying buffer.\r\n     * Note: The data may include more than just this vertex buffer's values.\r\n     * @returns the buffer data as a DataArray, or null.\r\n     */\r\n    public getData(): Nullable<DataArray> {\r\n        return this._buffer.getData();\r\n    }\r\n\r\n    /**\r\n     * Gets this vertex buffer's data as a float array. Float data is constructed if the vertex buffer data cannot be returned directly.\r\n     * @param totalVertices number of vertices in the buffer to take into account\r\n     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n     * @returns a float array containing vertex data\r\n     */\r\n    public getFloatData(totalVertices: number, forceCopy?: boolean): Nullable<FloatArray> {\r\n        const data = this.getData();\r\n        if (!data) {\r\n            return null;\r\n        }\r\n\r\n        return GetFloatData(data, this._size, this.type, this.byteOffset, this.byteStride, this.normalized, totalVertices, forceCopy);\r\n    }\r\n\r\n    /**\r\n     * Gets underlying native buffer\r\n     * @returns underlying native buffer\r\n     */\r\n    public getBuffer(): Nullable<DataBuffer> {\r\n        return this._buffer.getBuffer();\r\n    }\r\n\r\n    /**\r\n     * Gets the Buffer instance that wraps the native GPU buffer\r\n     * @returns the wrapper buffer\r\n     */\r\n    public getWrapperBuffer(): Buffer {\r\n        return this._buffer;\r\n    }\r\n\r\n    /**\r\n     * Gets the stride in float32 units (i.e. byte stride / 4).\r\n     * May not be an integer if the byte stride is not divisible by 4.\r\n     * @returns the stride in float32 units\r\n     * @deprecated Please use byteStride instead.\r\n     */\r\n    public getStrideSize(): number {\r\n        return this.byteStride / GetTypeByteLength(this.type);\r\n    }\r\n\r\n    /**\r\n     * Returns the offset as a multiple of the type byte length.\r\n     * @returns the offset in bytes\r\n     * @deprecated Please use byteOffset instead.\r\n     */\r\n    public getOffset(): number {\r\n        return this.byteOffset / GetTypeByteLength(this.type);\r\n    }\r\n\r\n    /**\r\n     * Returns the number of components or the byte size per vertex attribute\r\n     * @param sizeInBytes If true, returns the size in bytes or else the size in number of components of the vertex attribute (default: false)\r\n     * @returns the number of components\r\n     */\r\n    public getSize(sizeInBytes = false): number {\r\n        return sizeInBytes ? this._size * GetTypeByteLength(this.type) : this._size;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating is the internal buffer of the VertexBuffer is instanced\r\n     * @returns true if this buffer is instanced\r\n     */\r\n    public getIsInstanced(): boolean {\r\n        return this._instanced;\r\n    }\r\n\r\n    /**\r\n     * Returns the instancing divisor, zero for non-instanced (integer).\r\n     * @returns a number\r\n     */\r\n    public getInstanceDivisor(): number {\r\n        return this._instanceDivisor;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Store data into the buffer. If the buffer was already used it will be either recreated or updated depending on isUpdatable property\r\n     * @param data defines the data to store\r\n     */\r\n    public create(data?: DataArray): void {\r\n        this._buffer.create(data);\r\n        this._alignBuffer();\r\n    }\r\n\r\n    /**\r\n     * Updates the underlying buffer according to the passed numeric array or Float32Array.\r\n     * This function will create a new buffer if the current one is not updatable\r\n     * @param data defines the data to store\r\n     */\r\n    public update(data: DataArray): void {\r\n        this._buffer.update(data);\r\n        this._alignBuffer();\r\n    }\r\n\r\n    /**\r\n     * Updates directly the underlying WebGLBuffer according to the passed numeric array or Float32Array.\r\n     * Returns the directly updated WebGLBuffer.\r\n     * @param data the new data\r\n     * @param offset the new offset\r\n     * @param useBytes set to true if the offset is in bytes\r\n     */\r\n    public updateDirectly(data: DataArray, offset: number, useBytes: boolean = false): void {\r\n        this._buffer.updateDirectly(data, offset, undefined, useBytes);\r\n        this._alignBuffer();\r\n    }\r\n\r\n    /**\r\n     * Disposes the VertexBuffer and the underlying WebGLBuffer.\r\n     */\r\n    public dispose(): void {\r\n        if (this._ownsBuffer) {\r\n            this._buffer.dispose();\r\n        }\r\n\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    /**\r\n     * Enumerates each value of this vertex buffer as numbers.\r\n     * @param count the number of values to enumerate\r\n     * @param callback the callback function called for each value\r\n     */\r\n    public forEach(count: number, callback: (value: number, index: number) => void): void {\r\n        EnumerateFloatValues(this._buffer.getData()!, this.byteOffset, this.byteStride, this._size, this.type, count, this.normalized, (values, index) => {\r\n            for (let i = 0; i < this._size; i++) {\r\n                callback(values[i], index + i);\r\n            }\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public _alignBuffer() {}\r\n\r\n    // Enums\r\n    /**\r\n     * Positions\r\n     */\r\n    public static readonly PositionKind = Constants.PositionKind;\r\n    /**\r\n     * Normals\r\n     */\r\n    public static readonly NormalKind = Constants.NormalKind;\r\n    /**\r\n     * Tangents\r\n     */\r\n    public static readonly TangentKind = Constants.TangentKind;\r\n    /**\r\n     * Texture coordinates\r\n     */\r\n    public static readonly UVKind = Constants.UVKind;\r\n    /**\r\n     * Texture coordinates 2\r\n     */\r\n    public static readonly UV2Kind = Constants.UV2Kind;\r\n    /**\r\n     * Texture coordinates 3\r\n     */\r\n    public static readonly UV3Kind = Constants.UV3Kind;\r\n    /**\r\n     * Texture coordinates 4\r\n     */\r\n    public static readonly UV4Kind = Constants.UV4Kind;\r\n    /**\r\n     * Texture coordinates 5\r\n     */\r\n    public static readonly UV5Kind = Constants.UV5Kind;\r\n    /**\r\n     * Texture coordinates 6\r\n     */\r\n    public static readonly UV6Kind = Constants.UV6Kind;\r\n    /**\r\n     * Colors\r\n     */\r\n    public static readonly ColorKind = Constants.ColorKind;\r\n    /**\r\n     * Instance Colors\r\n     */\r\n    public static readonly ColorInstanceKind = Constants.ColorInstanceKind;\r\n    /**\r\n     * Matrix indices (for bones)\r\n     */\r\n    public static readonly MatricesIndicesKind = Constants.MatricesIndicesKind;\r\n    /**\r\n     * Matrix weights (for bones)\r\n     */\r\n    public static readonly MatricesWeightsKind = Constants.MatricesWeightsKind;\r\n    /**\r\n     * Additional matrix indices (for bones)\r\n     */\r\n    public static readonly MatricesIndicesExtraKind = Constants.MatricesIndicesExtraKind;\r\n    /**\r\n     * Additional matrix weights (for bones)\r\n     */\r\n    public static readonly MatricesWeightsExtraKind = Constants.MatricesWeightsExtraKind;\r\n}\r\n\r\n/**\r\n * Deduces the stride given a kind.\r\n * @param kind The kind string to deduce\r\n * @returns The deduced stride\r\n */\r\nexport function VertexBufferDeduceStride(kind: string): number {\r\n    switch (kind) {\r\n        case VertexBuffer.UVKind:\r\n        case VertexBuffer.UV2Kind:\r\n        case VertexBuffer.UV3Kind:\r\n        case VertexBuffer.UV4Kind:\r\n        case VertexBuffer.UV5Kind:\r\n        case VertexBuffer.UV6Kind:\r\n            return 2;\r\n        case VertexBuffer.NormalKind:\r\n        case VertexBuffer.PositionKind:\r\n            return 3;\r\n        case VertexBuffer.ColorKind:\r\n        case VertexBuffer.ColorInstanceKind:\r\n        case VertexBuffer.MatricesIndicesKind:\r\n        case VertexBuffer.MatricesIndicesExtraKind:\r\n        case VertexBuffer.MatricesWeightsKind:\r\n        case VertexBuffer.MatricesWeightsExtraKind:\r\n        case VertexBuffer.TangentKind:\r\n            return 4;\r\n        default:\r\n            throw new Error(\"Invalid kind '\" + kind + \"'\");\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the vertex buffer type of the given data array.\r\n * @param data the data array\r\n * @returns the vertex buffer type\r\n */\r\nexport function VertexBufferGetDataType(data: DataArray): number {\r\n    if (data instanceof Int8Array) {\r\n        return VertexBuffer.BYTE;\r\n    } else if (data instanceof Uint8Array) {\r\n        return VertexBuffer.UNSIGNED_BYTE;\r\n    } else if (data instanceof Int16Array) {\r\n        return VertexBuffer.SHORT;\r\n    } else if (data instanceof Uint16Array) {\r\n        return VertexBuffer.UNSIGNED_SHORT;\r\n    } else if (data instanceof Int32Array) {\r\n        return VertexBuffer.INT;\r\n    } else if (data instanceof Uint32Array) {\r\n        return VertexBuffer.UNSIGNED_INT;\r\n    } else {\r\n        return VertexBuffer.FLOAT;\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the byte length of the given type.\r\n * @param type the type\r\n * @returns the number of bytes\r\n * @deprecated Use `getTypeByteLength` from `bufferUtils` instead\r\n */\r\nexport function VertexBufferGetTypeByteLength(type: number): number {\r\n    return GetTypeByteLength(type);\r\n}\r\n\r\n/**\r\n * Enumerates each value of the given parameters as numbers.\r\n * @param data the data to enumerate\r\n * @param byteOffset the byte offset of the data\r\n * @param byteStride the byte stride of the data\r\n * @param componentCount the number of components per element\r\n * @param componentType the type of the component\r\n * @param count the number of values to enumerate\r\n * @param normalized whether the data is normalized\r\n * @param callback the callback function called for each value\r\n * @deprecated Use `EnumerateFloatValues` from `bufferUtils` instead\r\n */\r\nexport function VertexBufferForEach(\r\n    data: DataArray,\r\n    byteOffset: number,\r\n    byteStride: number,\r\n    componentCount: number,\r\n    componentType: number,\r\n    count: number,\r\n    normalized: boolean,\r\n    callback: (value: number, index: number) => void\r\n): void {\r\n    EnumerateFloatValues(data, byteOffset, byteStride, componentCount, componentType, count, normalized, (values, index) => {\r\n        for (let componentIndex = 0; componentIndex < componentCount; componentIndex++) {\r\n            callback(values[componentIndex], index + componentIndex);\r\n        }\r\n    });\r\n}\r\n\r\n/**\r\n * Gets the given data array as a float array. Float data is constructed if the data array cannot be returned directly.\r\n * @param data the input data array\r\n * @param size the number of components\r\n * @param type the component type\r\n * @param byteOffset the byte offset of the data\r\n * @param byteStride the byte stride of the data\r\n * @param normalized whether the data is normalized\r\n * @param totalVertices number of vertices in the buffer to take into account\r\n * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n * @returns a float array containing vertex data\r\n * @deprecated Use `GetFloatData` from `bufferUtils` instead\r\n */\r\nexport function VertexBufferGetFloatData(\r\n    data: DataArray,\r\n    size: number,\r\n    type: number,\r\n    byteOffset: number,\r\n    byteStride: number,\r\n    normalized: boolean,\r\n    totalVertices: number,\r\n    forceCopy?: boolean\r\n): FloatArray {\r\n    return GetFloatData(data, size, type, byteOffset, byteStride, normalized, totalVertices, forceCopy);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for VertexBuffer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVertexBuffer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexBuffer.DeduceStride = VertexBufferDeduceStride;\r\n    VertexBuffer.GetDataType = VertexBufferGetDataType;\r\n    VertexBuffer.GetTypeByteLength = VertexBufferGetTypeByteLength;\r\n    VertexBuffer.ForEach = VertexBufferForEach;\r\n    VertexBuffer.GetFloatData = VertexBufferGetFloatData;\r\n}\r\n","import { type Nullable, type FloatArray } from \"../types\";\r\nimport { Matrix, Vector3, Vector2, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type Sprite } from \"../Sprites/sprite\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\n\r\nimport { type Ray } from \"../Culling/ray\";\r\n\r\n/**\r\n * Information about the result of picking within a scene\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions\r\n */\r\nexport class PickingInfo {\r\n    /**\r\n     * If the pick collided with an object\r\n     */\r\n    public hit = false;\r\n    /**\r\n     * Distance away where the pick collided\r\n     */\r\n    public distance = 0;\r\n    /**\r\n     * The location of pick collision\r\n     */\r\n    public pickedPoint: Nullable<Vector3> = null;\r\n    /**\r\n     * The mesh corresponding the pick collision\r\n     */\r\n    public pickedMesh: Nullable<AbstractMesh> = null;\r\n    /** (See getTextureCoordinates) The barycentric U coordinate that is used when calculating the texture coordinates of the collision.*/\r\n    public bu = 0;\r\n    /** (See getTextureCoordinates) The barycentric V coordinate that is used when calculating the texture coordinates of the collision.*/\r\n    public bv = 0;\r\n    /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */\r\n    public faceId = -1;\r\n    /** The index of the face on the subMesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */\r\n    public subMeshFaceId = -1;\r\n    /** Id of the submesh that was picked */\r\n    public subMeshId = 0;\r\n    /** If a sprite was picked, this will be the sprite the pick collided with */\r\n    public pickedSprite: Nullable<Sprite> = null;\r\n    /** If we are picking a mesh with thin instance, this will give you the picked thin instance */\r\n    public thinInstanceIndex = -1;\r\n    /**\r\n     * The ray that was used to perform the picking.\r\n     */\r\n    public ray: Nullable<Ray> = null;\r\n    /**\r\n     * If a mesh was used to do the picking (eg. 6dof controller) as a \"near interaction\", this will be populated.\r\n     */\r\n    public originMesh: Nullable<AbstractMesh> = null;\r\n    /**\r\n     * The aim-space transform of the input used for picking, if it is an XR input source.\r\n     */\r\n    public aimTransform: Nullable<TransformNode> = null;\r\n    /**\r\n     * The grip-space transform of the input used for picking, if it is an XR input source.\r\n     * Some XR sources, such as input coming from head mounted displays, do not have this.\r\n     */\r\n    public gripTransform: Nullable<TransformNode> = null;\r\n\r\n    /**\r\n     * Gets the normal corresponding to the face the pick collided with\r\n     * @param useWorldCoordinates If the resulting normal should be relative to the world (default: false)\r\n     * @param useVerticesNormals If the vertices normals should be used to calculate the normal instead of the normal map (default: true)\r\n     * @returns The normal corresponding to the face the pick collided with\r\n     * @remarks Note that the returned normal will always point towards the picking ray.\r\n     */\r\n    public getNormal(useWorldCoordinates = false, useVerticesNormals = true): Nullable<Vector3> {\r\n        if (!this.pickedMesh || (useVerticesNormals && !this.pickedMesh.isVerticesDataPresent(VertexBuffer.NormalKind))) {\r\n            return null;\r\n        }\r\n\r\n        let indices = this.pickedMesh.getIndices();\r\n\r\n        if (indices?.length === 0) {\r\n            indices = null;\r\n        }\r\n\r\n        let result: Vector3;\r\n\r\n        const tmp0 = TmpVectors.Vector3[0];\r\n        const tmp1 = TmpVectors.Vector3[1];\r\n        const tmp2 = TmpVectors.Vector3[2];\r\n\r\n        if (useVerticesNormals) {\r\n            const normals = <FloatArray>this.pickedMesh.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n            let normal0 = indices\r\n                ? Vector3.FromArrayToRef(normals, indices[this.faceId * 3] * 3, tmp0)\r\n                : tmp0.copyFromFloats(normals[this.faceId * 3 * 3], normals[this.faceId * 3 * 3 + 1], normals[this.faceId * 3 * 3 + 2]);\r\n            let normal1 = indices\r\n                ? Vector3.FromArrayToRef(normals, indices[this.faceId * 3 + 1] * 3, tmp1)\r\n                : tmp1.copyFromFloats(normals[(this.faceId * 3 + 1) * 3], normals[(this.faceId * 3 + 1) * 3 + 1], normals[(this.faceId * 3 + 1) * 3 + 2]);\r\n            let normal2 = indices\r\n                ? Vector3.FromArrayToRef(normals, indices[this.faceId * 3 + 2] * 3, tmp2)\r\n                : tmp2.copyFromFloats(normals[(this.faceId * 3 + 2) * 3], normals[(this.faceId * 3 + 2) * 3 + 1], normals[(this.faceId * 3 + 2) * 3 + 2]);\r\n\r\n            normal0 = normal0.scale(this.bu);\r\n            normal1 = normal1.scale(this.bv);\r\n            normal2 = normal2.scale(1.0 - this.bu - this.bv);\r\n\r\n            result = new Vector3(normal0.x + normal1.x + normal2.x, normal0.y + normal1.y + normal2.y, normal0.z + normal1.z + normal2.z);\r\n        } else {\r\n            const positions = <FloatArray>this.pickedMesh.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n            const vertex1 = indices\r\n                ? Vector3.FromArrayToRef(positions, indices[this.faceId * 3] * 3, tmp0)\r\n                : tmp0.copyFromFloats(positions[this.faceId * 3 * 3], positions[this.faceId * 3 * 3 + 1], positions[this.faceId * 3 * 3 + 2]);\r\n            const vertex2 = indices\r\n                ? Vector3.FromArrayToRef(positions, indices[this.faceId * 3 + 1] * 3, tmp1)\r\n                : tmp1.copyFromFloats(positions[(this.faceId * 3 + 1) * 3], positions[(this.faceId * 3 + 1) * 3 + 1], positions[(this.faceId * 3 + 1) * 3 + 2]);\r\n            const vertex3 = indices\r\n                ? Vector3.FromArrayToRef(positions, indices[this.faceId * 3 + 2] * 3, tmp2)\r\n                : tmp2.copyFromFloats(positions[(this.faceId * 3 + 2) * 3], positions[(this.faceId * 3 + 2) * 3 + 1], positions[(this.faceId * 3 + 2) * 3 + 2]);\r\n\r\n            const p1p2 = vertex1.subtract(vertex2);\r\n            const p3p2 = vertex3.subtract(vertex2);\r\n\r\n            result = Vector3.Cross(p1p2, p3p2);\r\n        }\r\n\r\n        const transformNormalToWorld = (pickedMesh: AbstractMesh, n: Vector3) => {\r\n            if (this.thinInstanceIndex !== -1) {\r\n                const thinMatrixData = (pickedMesh as Mesh)._thinInstanceDataStorage.matrixData;\r\n                const index = this.thinInstanceIndex << 4;\r\n\r\n                if (thinMatrixData && thinMatrixData.length > index) {\r\n                    const tm = TmpVectors.Matrix[0];\r\n                    Matrix.FromArrayToRef(thinMatrixData, index, tm);\r\n                    Vector3.TransformNormalToRef(n, tm, n);\r\n                }\r\n            }\r\n\r\n            let wm = pickedMesh.getWorldMatrix();\r\n\r\n            if (pickedMesh.nonUniformScaling) {\r\n                TmpVectors.Matrix[0].copyFrom(wm);\r\n                wm = TmpVectors.Matrix[0];\r\n                wm.setTranslationFromFloats(0, 0, 0);\r\n                wm.invert();\r\n                wm.transposeToRef(TmpVectors.Matrix[1]);\r\n\r\n                wm = TmpVectors.Matrix[1];\r\n            }\r\n\r\n            Vector3.TransformNormalToRef(n, wm, n);\r\n        };\r\n\r\n        if (useWorldCoordinates) {\r\n            transformNormalToWorld(this.pickedMesh, result);\r\n        }\r\n\r\n        if (this.ray) {\r\n            const normalForDirectionChecking = TmpVectors.Vector3[0].copyFrom(result);\r\n\r\n            if (!useWorldCoordinates) {\r\n                // the normal has not been transformed to world space as part as the normal processing, so we must do it now\r\n                transformNormalToWorld(this.pickedMesh, normalForDirectionChecking);\r\n            }\r\n\r\n            // Flip the normal if the picking ray is in the same direction.\r\n            if (Vector3.Dot(normalForDirectionChecking, this.ray.direction) > 0) {\r\n                result.negateInPlace();\r\n            }\r\n        }\r\n\r\n        result.normalize();\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets the texture coordinates of where the pick occurred\r\n     * @param uvSet The UV set to use to calculate the texture coordinates (default: VertexBuffer.UVKind)\r\n     * @returns The vector containing the coordinates of the texture\r\n     */\r\n    public getTextureCoordinates(uvSet = VertexBuffer.UVKind): Nullable<Vector2> {\r\n        if (!this.pickedMesh || !this.pickedMesh.isVerticesDataPresent(uvSet)) {\r\n            return null;\r\n        }\r\n\r\n        const indices = this.pickedMesh.getIndices();\r\n        if (!indices) {\r\n            return null;\r\n        }\r\n\r\n        const uvs = this.pickedMesh.getVerticesData(uvSet);\r\n        if (!uvs) {\r\n            return null;\r\n        }\r\n\r\n        let uv0 = Vector2.FromArray(uvs, indices[this.faceId * 3] * 2);\r\n        let uv1 = Vector2.FromArray(uvs, indices[this.faceId * 3 + 1] * 2);\r\n        let uv2 = Vector2.FromArray(uvs, indices[this.faceId * 3 + 2] * 2);\r\n\r\n        uv0 = uv0.scale(this.bu);\r\n        uv1 = uv1.scale(this.bv);\r\n        uv2 = uv2.scale(1.0 - this.bu - this.bv);\r\n\r\n        return new Vector2(uv0.x + uv1.x + uv2.x, uv0.y + uv1.y + uv2.y);\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type PostProcess } from \"./postProcess\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type Scene } from \"../scene\";\r\n\r\n/**\r\n * PostProcessManager is used to manage one or more post processes or post process pipelines\r\n * See https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses\r\n */\r\nexport class PostProcessManager {\r\n    private _scene: Scene;\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private readonly _activePostProcesses: PostProcess[] = [];\r\n\r\n    /**\r\n     * Creates a new instance PostProcess\r\n     * @param scene The scene that the post process is associated with.\r\n     */\r\n    constructor(scene: Scene) {\r\n        this._scene = scene;\r\n    }\r\n\r\n    private _prepareBuffers(): void {\r\n        if (this._vertexBuffers[VertexBuffer.PositionKind]) {\r\n            return;\r\n        }\r\n\r\n        // VBO\r\n        const vertices = [];\r\n        vertices.push(1, 1);\r\n        vertices.push(-1, 1);\r\n        vertices.push(-1, -1);\r\n        vertices.push(1, -1);\r\n\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._scene.getEngine(), vertices, VertexBuffer.PositionKind, false, false, 2);\r\n\r\n        this._buildIndexBuffer();\r\n    }\r\n\r\n    private _buildIndexBuffer(): void {\r\n        // Indices\r\n        const indices = [];\r\n        indices.push(0);\r\n        indices.push(1);\r\n        indices.push(2);\r\n\r\n        indices.push(0);\r\n        indices.push(2);\r\n        indices.push(3);\r\n\r\n        this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);\r\n    }\r\n\r\n    private _getActivePostProcesses(source: Nullable<PostProcess>[]): PostProcess[] {\r\n        const activePostProcesses = this._activePostProcesses;\r\n        activePostProcesses.length = 0;\r\n\r\n        for (let index = 0; index < source.length; index++) {\r\n            const postProcess = source[index];\r\n            if (postProcess) {\r\n                activePostProcesses.push(postProcess);\r\n            }\r\n        }\r\n\r\n        return activePostProcesses;\r\n    }\r\n\r\n    /**\r\n     * Observable raised before post processes are rendered.\r\n     */\r\n    public onBeforeRenderObservable = new Observable<PostProcessManager>();\r\n\r\n    /**\r\n     * Rebuilds the vertex buffers of the manager.\r\n     * @internal\r\n     */\r\n    public _rebuild(): void {\r\n        const vb = this._vertexBuffers[VertexBuffer.PositionKind];\r\n\r\n        if (!vb) {\r\n            return;\r\n        }\r\n        vb._rebuild();\r\n        this._buildIndexBuffer();\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Prepares a frame to be run through a post process.\r\n     * @param sourceTexture The input texture to the post processes. (default: null)\r\n     * @param postProcesses An array of post processes to be run. (default: null)\r\n     * @returns True if the post processes were able to be run.\r\n     * @internal\r\n     */\r\n    public _prepareFrame(sourceTexture: Nullable<InternalTexture> = null, postProcesses: Nullable<PostProcess[]> = null): boolean {\r\n        const camera = this._scene.activeCamera;\r\n        if (!camera) {\r\n            return false;\r\n        }\r\n\r\n        postProcesses = postProcesses || this._getActivePostProcesses(camera._postProcesses);\r\n\r\n        if (!postProcesses || postProcesses.length === 0 || !this._scene.postProcessesEnabled) {\r\n            return false;\r\n        }\r\n\r\n        postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Manually render a set of post processes to a texture.\r\n     * Please note, the frame buffer won't be unbound after the call in case you have more render to do.\r\n     * @param postProcesses An array of post processes to be run.\r\n     * @param targetTexture The render target wrapper to render to.\r\n     * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight\r\n     * @param faceIndex defines the face to render to if a cubemap is defined as the target\r\n     * @param lodLevel defines which lod of the texture to render to\r\n     * @param doNotBindFrambuffer If set to true, assumes that the framebuffer has been bound previously\r\n     * @param numPostsProcesses The number of post processes to render. Defaults to the length of the postProcesses array.\r\n     */\r\n    public directRender(\r\n        postProcesses: PostProcess[],\r\n        targetTexture: Nullable<RenderTargetWrapper> = null,\r\n        forceFullscreenViewport = false,\r\n        faceIndex = 0,\r\n        lodLevel = 0,\r\n        doNotBindFrambuffer = false,\r\n        numPostsProcesses = postProcesses.length\r\n    ): void {\r\n        const engine = this._scene.getEngine();\r\n\r\n        for (let index = 0; index < numPostsProcesses; index++) {\r\n            if (index < postProcesses.length - 1) {\r\n                postProcesses[index + 1].activate(this._scene.activeCamera || this._scene, targetTexture?.texture);\r\n            } else {\r\n                if (targetTexture) {\r\n                    engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport, lodLevel);\r\n                } else if (!doNotBindFrambuffer) {\r\n                    engine.restoreDefaultFramebuffer();\r\n                }\r\n                engine._debugInsertMarker?.(`post process ${postProcesses[index].name} output`);\r\n            }\r\n\r\n            const pp = postProcesses[index];\r\n            const effect = pp.apply();\r\n\r\n            if (effect) {\r\n                pp.onBeforeRenderObservable.notifyObservers(effect);\r\n\r\n                // VBOs\r\n                this._prepareBuffers();\r\n                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);\r\n\r\n                // Draw order\r\n                engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, 6);\r\n\r\n                pp.onAfterRenderObservable.notifyObservers(effect);\r\n            }\r\n        }\r\n\r\n        // Restore depth buffer\r\n        engine.setDepthBuffer(true);\r\n        engine.setDepthWrite(true);\r\n    }\r\n\r\n    /**\r\n     * Finalize the result of the output of the postprocesses.\r\n     * @param doNotPresent If true the result will not be displayed to the screen.\r\n     * @param targetTexture The render target wrapper to render to.\r\n     * @param faceIndex The index of the face to bind the target texture to.\r\n     * @param postProcesses The array of post processes to render.\r\n     * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)\r\n     * @internal\r\n     */\r\n    public _finalizeFrame(\r\n        doNotPresent?: boolean,\r\n        targetTexture?: RenderTargetWrapper,\r\n        faceIndex?: number,\r\n        postProcesses?: Array<PostProcess>,\r\n        forceFullscreenViewport = false\r\n    ): void {\r\n        const camera = this._scene.activeCamera;\r\n\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        this.onBeforeRenderObservable.notifyObservers(this);\r\n\r\n        postProcesses = postProcesses || this._getActivePostProcesses(camera._postProcesses);\r\n        if (postProcesses.length === 0 || !this._scene.postProcessesEnabled) {\r\n            return;\r\n        }\r\n        const engine = this._scene.getEngine();\r\n\r\n        for (let index = 0, len = postProcesses.length; index < len; index++) {\r\n            const pp = postProcesses[index];\r\n\r\n            if (index < len - 1) {\r\n                pp._outputTexture = postProcesses[index + 1].activate(camera, targetTexture?.texture);\r\n            } else {\r\n                if (targetTexture) {\r\n                    engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport);\r\n                    pp._outputTexture = targetTexture;\r\n                } else {\r\n                    engine.restoreDefaultFramebuffer();\r\n                    pp._outputTexture = null;\r\n                }\r\n                engine._debugInsertMarker?.(`post process ${postProcesses[index].name} output`);\r\n            }\r\n\r\n            if (doNotPresent) {\r\n                break;\r\n            }\r\n\r\n            const effect = pp.apply();\r\n\r\n            if (effect) {\r\n                pp.onBeforeRenderObservable.notifyObservers(effect);\r\n\r\n                // VBOs\r\n                this._prepareBuffers();\r\n                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);\r\n\r\n                // Draw order\r\n                engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, 6);\r\n\r\n                pp.onAfterRenderObservable.notifyObservers(effect);\r\n            }\r\n        }\r\n\r\n        // Restore states\r\n        engine.setDepthBuffer(true);\r\n        engine.setDepthWrite(true);\r\n        engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n    }\r\n\r\n    /**\r\n     * Disposes of the post process manager.\r\n     */\r\n    public dispose(): void {\r\n        const buffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (buffer) {\r\n            buffer.dispose();\r\n            this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this._scene.getEngine()._releaseBuffer(this._indexBuffer);\r\n            this._indexBuffer = null;\r\n        }\r\n    }\r\n}\r\n","import { Effect } from \"../Materials/effect\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type IMatrixLike, type IVector3Like } from \"../Maths/math.like\";\r\nimport { InvertMatrixToRef, MultiplyMatricesToRef } from \"../Maths/ThinMaths/thinMath.matrix.functions\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type DeepImmutable } from \"../types\";\r\nimport { UniformBuffer } from \"./uniformBuffer\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\n\r\nconst TempFinalMat: Matrix = new Matrix();\r\nconst TempMat1: Matrix = new Matrix();\r\nconst TempMat2: Matrix = new Matrix();\r\n\r\n/**\r\n * When rendering, each scene will reset this to ensure the correct floating origin offset is when overriding the below functions\r\n */\r\nexport const FloatingOriginCurrentScene = {\r\n    getScene: () => undefined as Scene | undefined,\r\n    eyeAtCamera: true, // When true, we can assume viewMatrix translation is at origin. Otherwise, we must do full offset calculations\r\n};\r\n\r\nfunction OffsetWorldToRef(offset: IVector3Like, world: DeepImmutable<IMatrixLike>, ref: Matrix): DeepImmutable<IMatrixLike> {\r\n    const refArray = ref.asArray();\r\n    const worldArray = world.asArray();\r\n    for (let i = 0; i < 16; i++) {\r\n        refArray[i] = worldArray[i];\r\n    }\r\n    refArray[12] -= offset.x;\r\n    refArray[13] -= offset.y;\r\n    refArray[14] -= offset.z;\r\n    ref.markAsUpdated();\r\n    return ref;\r\n}\r\n\r\nfunction GetFullOffsetView(offset: IVector3Like, viewMatrix: DeepImmutable<IMatrixLike>, ref: IMatrixLike) {\r\n    InvertMatrixToRef(viewMatrix, TempMat1); // TempMat1 = light world matrix (inverse of view)\r\n    OffsetWorldToRef(offset, TempMat1, TempMat2); // TempMat2 = offset light world matrix\r\n    InvertMatrixToRef(TempMat2, ref); // TempMat1 = offset view matrix\r\n    return ref;\r\n}\r\n\r\nexport function OffsetViewToRef(offset: IVector3Like, view: DeepImmutable<IMatrixLike>, ref: Matrix): DeepImmutable<IMatrixLike> {\r\n    // When eye is not at camera, we cannot assume the translation of view matrix is at origin, so we perform full offset calculation\r\n    if (!FloatingOriginCurrentScene.eyeAtCamera) {\r\n        return GetFullOffsetView(offset, view, ref);\r\n    }\r\n    const refArray = ref.asArray();\r\n    const viewArray = view.asArray();\r\n    for (let i = 0; i < 16; i++) {\r\n        refArray[i] = viewArray[i];\r\n    }\r\n    refArray[12] = 0;\r\n    refArray[13] = 0;\r\n    refArray[14] = 0;\r\n    ref.markAsUpdated();\r\n    return ref;\r\n}\r\n\r\nfunction OffsetViewProjectionToRef(offset: IVector3Like, view: DeepImmutable<IMatrixLike>, projection: DeepImmutable<IMatrixLike>, ref: Matrix): DeepImmutable<IMatrixLike> {\r\n    MultiplyMatricesToRef(OffsetViewToRef(offset, view, ref), projection, ref);\r\n    return ref;\r\n}\r\n\r\nexport function OffsetClipPlaneToRef(offset: Vector3, plane: Plane, ref: Plane): Plane {\r\n    // Original clipplane is using equation normal.dot(p) + d = 0\r\n    // Assume we have p' = p - offset, that means normal.dot(p') + d' = 0\r\n    // So to get the offset plane,\r\n    // normal.dot(p' + offset) + d = 0\r\n    // normal.dot(p') + normal.dot(offset) + d = 0\r\n    // -d' + normal.dot(offset) + d = 0\r\n    // d' = d + normal.dot(offset)\r\n    ref.normal.copyFrom(plane.normal);\r\n    ref.d = plane.d + Vector3.Dot(plane.normal, offset);\r\n    return ref;\r\n}\r\n\r\nexport function GetOffsetTransformMatrices(\r\n    offset: IVector3Like,\r\n    viewMatrices: Array<Matrix>,\r\n    projectionMatrices: Array<Matrix>,\r\n    length: number,\r\n    resultArray: Float32Array\r\n): Float32Array {\r\n    for (let cascadeIndex = 0; cascadeIndex < length; ++cascadeIndex) {\r\n        GetFullOffsetViewProjectionToRef(offset, viewMatrices[cascadeIndex], projectionMatrices[cascadeIndex], TempMat1);\r\n        TempMat1.copyToArray(resultArray, cascadeIndex * 16);\r\n    }\r\n    return resultArray;\r\n}\r\n\r\nfunction OffsetWorldViewToRef(offset: IVector3Like, worldView: DeepImmutable<IMatrixLike>, view: DeepImmutable<IMatrixLike>, ref: Matrix): DeepImmutable<IMatrixLike> {\r\n    // ( world * view ) * inverse ( view ) = world\r\n    InvertMatrixToRef(view, TempMat1); // TempMat1 = inverseView\r\n    MultiplyMatricesToRef(worldView, TempMat1, TempMat2); // TempMat2 = world, TempMat1 can be reused\r\n\r\n    // ( offsetWorld * offsetView ) = offsetWorldView\r\n    OffsetWorldToRef(offset, TempMat2, TempMat1); // TempMat1 = offsetWorld\r\n    OffsetViewToRef(offset, view, TempMat2); // TempMat2 = offsetView\r\n    MultiplyMatricesToRef(TempMat1, TempMat2, ref);\r\n\r\n    return ref;\r\n}\r\n\r\nexport function GetFullOffsetViewProjectionToRef(\r\n    offset: IVector3Like,\r\n    viewMatrix: DeepImmutable<IMatrixLike>,\r\n    projectionMatrix: DeepImmutable<IMatrixLike>,\r\n    ref: IMatrixLike\r\n): DeepImmutable<IMatrixLike> {\r\n    GetFullOffsetView(offset, viewMatrix, TempMat2);\r\n    MultiplyMatricesToRef(TempMat2, projectionMatrix, ref);\r\n    return ref;\r\n}\r\n\r\nfunction OffsetWorldViewProjectionToRef(\r\n    offset: IVector3Like,\r\n    worldViewProjection: DeepImmutable<IMatrixLike>,\r\n    viewProjection: DeepImmutable<IMatrixLike>,\r\n    view: DeepImmutable<IMatrixLike>,\r\n    projection: DeepImmutable<IMatrixLike>,\r\n    ref: IMatrixLike\r\n): DeepImmutable<IMatrixLike> {\r\n    // ( world * view * projection ) * inverse(projection) * inverse(view) = world\r\n    // ( world * view * projection ) * inverse (view * projection) = world\r\n    InvertMatrixToRef(viewProjection, TempMat1); // TempMat1 = inverse (view * projection)\r\n    MultiplyMatricesToRef(worldViewProjection, TempMat1, TempMat2); // TempMat2 = world, TempMat1 can be reused\r\n\r\n    // ( offsetWorld * offsetViewProjection)  = offsetWorldViewProjection\r\n    OffsetWorldToRef(offset, TempMat2, TempMat1); // TempMat1 = offsetWorld\r\n    OffsetViewProjectionToRef(offset, view, projection, TempMat2); // TempMat2 = offsetViewProjection\r\n    MultiplyMatricesToRef(TempMat1, TempMat2, ref);\r\n\r\n    return ref;\r\n}\r\n\r\nfunction GetOffsetMatrix(uniformName: string, mat: IMatrixLike): IMatrixLike {\r\n    const scene = FloatingOriginCurrentScene.getScene();\r\n    // Early out for scenes that don't have floatingOriginMode enabled\r\n    // Effect.setMatrix will call pipelineContext.setMatrix. In WebGPU, this will in turn call ubo.updateMatrix. To avoid double offset, early out if mat is TempFinalMat\r\n    if (!scene || TempFinalMat === mat) {\r\n        return mat;\r\n    }\r\n    TempFinalMat.updateFlag = mat.updateFlag;\r\n    const offset = scene.floatingOriginOffset;\r\n    switch (uniformName) {\r\n        case \"world\":\r\n            return OffsetWorldToRef(offset, mat, TempFinalMat);\r\n        case \"view\":\r\n            return OffsetViewToRef(offset, mat, TempFinalMat);\r\n        case \"worldView\":\r\n            return OffsetWorldViewToRef(offset, mat, scene.getViewMatrix(), TempFinalMat);\r\n        case \"viewProjection\":\r\n            return OffsetViewProjectionToRef(offset, scene.getViewMatrix(), scene.getProjectionMatrix(), TempFinalMat);\r\n        case \"worldViewProjection\":\r\n            return OffsetWorldViewProjectionToRef(offset, mat, scene.getTransformMatrix(), scene.getViewMatrix(), scene.getProjectionMatrix(), TempFinalMat);\r\n        default:\r\n            // Node material blocks uniforms are formatted u_BlockName, with trailing numbers if there are multiple blocks of the same name\r\n            // Check u_ first so that we can early out for non-node material uniforms\r\n            if (uniformName.startsWith(\"u_\")) {\r\n                const lowercaseUniformName = uniformName.toLowerCase();\r\n                if (lowercaseUniformName.startsWith(\"u_worldviewprojection\")) {\r\n                    return OffsetWorldViewProjectionToRef(offset, mat, scene.getTransformMatrix(), scene.getViewMatrix(), scene.getProjectionMatrix(), TempFinalMat);\r\n                }\r\n                if (lowercaseUniformName.startsWith(\"u_viewprojection\")) {\r\n                    return OffsetViewProjectionToRef(offset, scene.getViewMatrix(), scene.getProjectionMatrix(), TempFinalMat);\r\n                }\r\n                if (lowercaseUniformName.startsWith(\"u_worldview\")) {\r\n                    return OffsetWorldViewToRef(offset, mat, scene.getViewMatrix(), TempFinalMat);\r\n                }\r\n                if (lowercaseUniformName.startsWith(\"u_world\")) {\r\n                    return OffsetWorldToRef(offset, mat, TempFinalMat);\r\n                }\r\n                if (lowercaseUniformName.startsWith(\"u_view\")) {\r\n                    return OffsetViewToRef(offset, mat, TempFinalMat);\r\n                }\r\n            }\r\n            return mat;\r\n    }\r\n}\r\n\r\n// ---- Overriding the prototypes of effect and uniformBuffer's setMatrix functions ----\r\nconst UniformBufferInternal = UniformBuffer as any;\r\nconst EffectInternal = Effect as any;\r\nconst OriginalUpdateMatrixForUniform = UniformBufferInternal.prototype._updateMatrixForUniform;\r\nconst OriginalSetMatrix = Effect.prototype.setMatrix;\r\n\r\nexport function ResetMatrixFunctions() {\r\n    Effect.prototype.setMatrix = OriginalSetMatrix;\r\n    EffectInternal._setMatrixOverride = undefined;\r\n    UniformBufferInternal.prototype._updateMatrixForUniform = OriginalUpdateMatrixForUniform;\r\n    UniformBufferInternal.prototype._updateMatrixForUniformOverride = undefined;\r\n}\r\n\r\nexport function OverrideMatrixFunctions() {\r\n    EffectInternal.prototype._setMatrixOverride = OriginalSetMatrix;\r\n    EffectInternal.prototype.setMatrix = function (uniformName: string, matrix: IMatrixLike) {\r\n        this._setMatrixOverride(uniformName, GetOffsetMatrix(uniformName, matrix));\r\n        return this;\r\n    };\r\n    UniformBufferInternal.prototype._updateMatrixForUniformOverride = OriginalUpdateMatrixForUniform;\r\n    UniformBufferInternal.prototype._updateMatrixForUniform = function (uniformName: string, matrix: IMatrixLike) {\r\n        this._updateMatrixForUniformOverride(uniformName, GetOffsetMatrix(uniformName, matrix));\r\n    };\r\n}\r\n","import { SmartArray, SmartArrayNoDuplicate } from \"../Misc/smartArray\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Nullable, type DeepImmutable } from \"../types\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport { type IEdgesRenderer } from \"./edgesRenderer\";\r\nimport { type ISpriteManager } from \"../Sprites/spriteManager\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Material } from \"../Materials/material\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\n\r\n/**\r\n * This represents the object necessary to create a rendering group.\r\n * This is exclusively used and created by the rendering manager.\r\n * To modify the behavior, you use the available helpers in your scene or meshes.\r\n * @internal\r\n */\r\nexport class RenderingGroup {\r\n    private static _ZeroVector: DeepImmutable<Vector3> = Vector3.Zero();\r\n    private _scene: Scene;\r\n    private _opaqueSubMeshes = new SmartArray<SubMesh>(256);\r\n    /** @internal */\r\n    public _transparentSubMeshes = new SmartArray<SubMesh>(256);\r\n    private _alphaTestSubMeshes = new SmartArray<SubMesh>(256);\r\n    private _depthOnlySubMeshes = new SmartArray<SubMesh>(256);\r\n    private _particleSystems = new SmartArray<IParticleSystem>(256);\r\n    private _spriteManagers = new SmartArray<ISpriteManager>(256);\r\n\r\n    private _opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;\r\n    private _alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;\r\n    private _transparentSortCompareFn: (a: SubMesh, b: SubMesh) => number;\r\n\r\n    private _renderOpaque: (subMeshes: SmartArray<SubMesh>) => void;\r\n    private _renderAlphaTest: (subMeshes: SmartArray<SubMesh>) => void;\r\n    /** @internal */\r\n    public _renderTransparent: (subMeshes: SmartArray<SubMesh>) => void;\r\n\r\n    /** @internal */\r\n    public _empty = true;\r\n\r\n    /** @internal */\r\n    public _edgesRenderers = new SmartArrayNoDuplicate<IEdgesRenderer>(16);\r\n\r\n    public onBeforeTransparentRendering: () => void;\r\n\r\n    public disableDepthPrePass = false;\r\n\r\n    /**\r\n     * Set the opaque sort comparison function.\r\n     * If null the sub meshes will be render in the order they were created\r\n     */\r\n    public set opaqueSortCompareFn(value: Nullable<(a: SubMesh, b: SubMesh) => number>) {\r\n        if (value) {\r\n            this._opaqueSortCompareFn = value;\r\n        } else {\r\n            this._opaqueSortCompareFn = RenderingGroup.PainterSortCompare;\r\n        }\r\n        this._renderOpaque = this._renderOpaqueSorted;\r\n    }\r\n\r\n    /**\r\n     * Set the alpha test sort comparison function.\r\n     * If null the sub meshes will be render in the order they were created\r\n     */\r\n    public set alphaTestSortCompareFn(value: Nullable<(a: SubMesh, b: SubMesh) => number>) {\r\n        if (value) {\r\n            this._alphaTestSortCompareFn = value;\r\n        } else {\r\n            this._alphaTestSortCompareFn = RenderingGroup.PainterSortCompare;\r\n        }\r\n        this._renderAlphaTest = this._renderAlphaTestSorted;\r\n    }\r\n\r\n    /**\r\n     * Set the transparent sort comparison function.\r\n     * If null the sub meshes will be render in the order they were created\r\n     */\r\n    public set transparentSortCompareFn(value: Nullable<(a: SubMesh, b: SubMesh) => number>) {\r\n        if (value) {\r\n            this._transparentSortCompareFn = value;\r\n        } else {\r\n            this._transparentSortCompareFn = RenderingGroup.defaultTransparentSortCompare;\r\n        }\r\n        this._renderTransparent = this._renderTransparentSorted;\r\n    }\r\n\r\n    /**\r\n     * Creates a new rendering group.\r\n     * @param index The rendering group index\r\n     * @param scene\r\n     * @param opaqueSortCompareFn The opaque sort comparison function. If null no order is applied\r\n     * @param alphaTestSortCompareFn The alpha test sort comparison function. If null no order is applied\r\n     * @param transparentSortCompareFn The transparent sort comparison function. If null back to front + alpha index sort is applied\r\n     */\r\n    constructor(\r\n        public index: number,\r\n        scene: Scene,\r\n        opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n    ) {\r\n        this._scene = scene;\r\n\r\n        this.opaqueSortCompareFn = opaqueSortCompareFn;\r\n        this.alphaTestSortCompareFn = alphaTestSortCompareFn;\r\n        this.transparentSortCompareFn = transparentSortCompareFn;\r\n    }\r\n\r\n    /**\r\n     * Render all the sub meshes contained in the group.\r\n     * @param customRenderFunction Used to override the default render behaviour of the group.\r\n     * @param renderSprites\r\n     * @param renderParticles\r\n     * @param activeMeshes\r\n     * @param renderDepthOnlyMeshes\r\n     * @param renderOpaqueMeshes\r\n     * @param renderAlphaTestMeshes\r\n     * @param renderTransparentMeshes\r\n     * @param customRenderTransparentSubMeshes\r\n     */\r\n    public render(\r\n        customRenderFunction: Nullable<\r\n            (\r\n                opaqueSubMeshes: SmartArray<SubMesh>,\r\n                transparentSubMeshes: SmartArray<SubMesh>,\r\n                alphaTestSubMeshes: SmartArray<SubMesh>,\r\n                depthOnlySubMeshes: SmartArray<SubMesh>\r\n            ) => void\r\n        >,\r\n        renderSprites: boolean,\r\n        renderParticles: boolean,\r\n        activeMeshes: Nullable<AbstractMesh[]>,\r\n        renderDepthOnlyMeshes: boolean = true,\r\n        renderOpaqueMeshes: boolean = true,\r\n        renderAlphaTestMeshes: boolean = true,\r\n        renderTransparentMeshes: boolean = true,\r\n        customRenderTransparentSubMeshes?: (transparentSubMeshes: SmartArray<SubMesh>, renderingGroup?: RenderingGroup) => void\r\n    ): void {\r\n        if (customRenderFunction) {\r\n            customRenderFunction(this._opaqueSubMeshes, this._alphaTestSubMeshes, this._transparentSubMeshes, this._depthOnlySubMeshes);\r\n            return;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        // Depth only\r\n        if (renderDepthOnlyMeshes && this._depthOnlySubMeshes.length !== 0) {\r\n            engine.setColorWrite(false);\r\n            this._renderAlphaTest(this._depthOnlySubMeshes);\r\n            engine.setColorWrite(true);\r\n        }\r\n\r\n        // Opaque\r\n        if (renderOpaqueMeshes && this._opaqueSubMeshes.length !== 0) {\r\n            this._renderOpaque(this._opaqueSubMeshes);\r\n        }\r\n\r\n        // Alpha test\r\n        if (renderAlphaTestMeshes && this._alphaTestSubMeshes.length !== 0) {\r\n            this._renderAlphaTest(this._alphaTestSubMeshes);\r\n        }\r\n\r\n        const stencilState = engine.getStencilBuffer();\r\n        engine.setStencilBuffer(false);\r\n\r\n        // Sprites\r\n        if (renderSprites) {\r\n            this._renderSprites();\r\n        }\r\n\r\n        // Particles\r\n        if (renderParticles) {\r\n            this._renderParticles(activeMeshes);\r\n        }\r\n\r\n        if (this.onBeforeTransparentRendering) {\r\n            this.onBeforeTransparentRendering();\r\n        }\r\n\r\n        // Transparent\r\n        if (renderTransparentMeshes && (customRenderTransparentSubMeshes || this._transparentSubMeshes.length !== 0 || this._scene.useOrderIndependentTransparency)) {\r\n            engine.setStencilBuffer(stencilState);\r\n            if (customRenderTransparentSubMeshes) {\r\n                customRenderTransparentSubMeshes(this._transparentSubMeshes, this);\r\n            } else {\r\n                if (this._scene.useOrderIndependentTransparency) {\r\n                    const excludedMeshes = this._scene.depthPeelingRenderer!.render(this._transparentSubMeshes);\r\n                    if (excludedMeshes.length) {\r\n                        // Render leftover meshes that could not be processed by depth peeling\r\n                        this._renderTransparent(excludedMeshes);\r\n                    }\r\n                } else {\r\n                    this._renderTransparent(this._transparentSubMeshes);\r\n                }\r\n            }\r\n            engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        }\r\n\r\n        // Set back stencil to false in case it changes before the edge renderer.\r\n        engine.setStencilBuffer(false);\r\n\r\n        // Edges\r\n        if (renderOpaqueMeshes && this._edgesRenderers.length) {\r\n            for (let edgesRendererIndex = 0; edgesRendererIndex < this._edgesRenderers.length; edgesRendererIndex++) {\r\n                this._edgesRenderers.data[edgesRendererIndex].render();\r\n            }\r\n\r\n            engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        }\r\n\r\n        // Restore Stencil state.\r\n        engine.setStencilBuffer(stencilState);\r\n    }\r\n\r\n    /**\r\n     * Renders the opaque submeshes in the order from the opaqueSortCompareFn.\r\n     * @param subMeshes The submeshes to render\r\n     */\r\n    private _renderOpaqueSorted(subMeshes: SmartArray<SubMesh>): void {\r\n        RenderingGroup._RenderSorted(subMeshes, this._opaqueSortCompareFn, this._scene.activeCamera, false, this.disableDepthPrePass);\r\n    }\r\n\r\n    /**\r\n     * Renders the opaque submeshes in the order from the alphatestSortCompareFn.\r\n     * @param subMeshes The submeshes to render\r\n     */\r\n    private _renderAlphaTestSorted(subMeshes: SmartArray<SubMesh>): void {\r\n        RenderingGroup._RenderSorted(subMeshes, this._alphaTestSortCompareFn, this._scene.activeCamera, false, this.disableDepthPrePass);\r\n    }\r\n\r\n    /**\r\n     * Renders the opaque submeshes in the order from the transparentSortCompareFn.\r\n     * @param subMeshes The submeshes to render\r\n     */\r\n    private _renderTransparentSorted(subMeshes: SmartArray<SubMesh>): void {\r\n        RenderingGroup._RenderSorted(subMeshes, this._transparentSortCompareFn, this._scene.activeCamera, true, this.disableDepthPrePass);\r\n    }\r\n\r\n    /**\r\n     * Renders the submeshes in a specified order.\r\n     * @param subMeshes The submeshes to sort before render\r\n     * @param sortCompareFn The comparison function use to sort\r\n     * @param camera The camera position use to preprocess the submeshes to help sorting\r\n     * @param transparent Specifies to activate blending if true\r\n     * @param disableDepthPrePass Specifies to disable depth pre-pass if true (default: false)\r\n     */\r\n    private static _RenderSorted(\r\n        subMeshes: SmartArray<SubMesh>,\r\n        sortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>,\r\n        camera: Nullable<Camera>,\r\n        transparent: boolean,\r\n        disableDepthPrePass?: boolean\r\n    ): void {\r\n        let subIndex = 0;\r\n        let subMesh: SubMesh;\r\n        const cameraPosition = camera ? camera.globalPosition : RenderingGroup._ZeroVector;\r\n\r\n        if (transparent) {\r\n            for (; subIndex < subMeshes.length; subIndex++) {\r\n                subMesh = subMeshes.data[subIndex];\r\n                subMesh._alphaIndex = subMesh.getMesh().alphaIndex;\r\n                subMesh._distanceToCamera = Vector3.Distance(subMesh.getBoundingInfo().boundingSphere.centerWorld, cameraPosition);\r\n            }\r\n        }\r\n\r\n        const sortedArray = subMeshes.length === subMeshes.data.length ? subMeshes.data : subMeshes.data.slice(0, subMeshes.length);\r\n\r\n        if (sortCompareFn) {\r\n            sortedArray.sort(sortCompareFn);\r\n        }\r\n\r\n        const scene = sortedArray[0].getMesh().getScene();\r\n        for (subIndex = 0; subIndex < sortedArray.length; subIndex++) {\r\n            subMesh = sortedArray[subIndex];\r\n\r\n            if (scene._activeMeshesFrozenButKeepClipping && !subMesh.isInFrustum(scene._frustumPlanes)) {\r\n                continue;\r\n            }\r\n\r\n            if (transparent) {\r\n                const material = subMesh.getMaterial();\r\n\r\n                if (material && material.needDepthPrePass && !disableDepthPrePass) {\r\n                    const engine = material.getScene().getEngine();\r\n                    engine.setColorWrite(false);\r\n                    engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n                    subMesh.render(false);\r\n                    engine.setColorWrite(true);\r\n                }\r\n            }\r\n\r\n            subMesh.render(transparent);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n     * are rendered back to front if in the same alpha index.\r\n     *\r\n     * @param a The first submesh\r\n     * @param b The second submesh\r\n     * @returns The result of the comparison\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static defaultTransparentSortCompare(a: SubMesh, b: SubMesh): number {\r\n        // Alpha index first\r\n        if (a._alphaIndex > b._alphaIndex) {\r\n            return 1;\r\n        }\r\n        if (a._alphaIndex < b._alphaIndex) {\r\n            return -1;\r\n        }\r\n\r\n        // Then distance to camera\r\n        return RenderingGroup.backToFrontSortCompare(a, b);\r\n    }\r\n\r\n    /**\r\n     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n     * are rendered back to front.\r\n     *\r\n     * @param a The first submesh\r\n     * @param b The second submesh\r\n     * @returns The result of the comparison\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static backToFrontSortCompare(a: SubMesh, b: SubMesh): number {\r\n        // Then distance to camera\r\n        if (a._distanceToCamera < b._distanceToCamera) {\r\n            return 1;\r\n        }\r\n        if (a._distanceToCamera > b._distanceToCamera) {\r\n            return -1;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n     * are rendered front to back (prevent overdraw).\r\n     *\r\n     * @param a The first submesh\r\n     * @param b The second submesh\r\n     * @returns The result of the comparison\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static frontToBackSortCompare(a: SubMesh, b: SubMesh): number {\r\n        // Then distance to camera\r\n        if (a._distanceToCamera < b._distanceToCamera) {\r\n            return -1;\r\n        }\r\n        if (a._distanceToCamera > b._distanceToCamera) {\r\n            return 1;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n     * are grouped by material then geometry.\r\n     *\r\n     * @param a The first submesh\r\n     * @param b The second submesh\r\n     * @returns The result of the comparison\r\n     */\r\n    public static PainterSortCompare(a: SubMesh, b: SubMesh): number {\r\n        const meshA = a.getMesh();\r\n        const meshB = b.getMesh();\r\n\r\n        if (meshA.material && meshB.material) {\r\n            return meshA.material.uniqueId - meshB.material.uniqueId;\r\n        }\r\n\r\n        return meshA.uniqueId - meshB.uniqueId;\r\n    }\r\n\r\n    /**\r\n     * Resets the different lists of submeshes to prepare a new frame.\r\n     */\r\n    public prepare(): void {\r\n        this._opaqueSubMeshes.reset();\r\n        this._transparentSubMeshes.reset();\r\n        this._alphaTestSubMeshes.reset();\r\n        this._depthOnlySubMeshes.reset();\r\n        this._particleSystems.reset();\r\n        this.prepareSprites();\r\n        this._edgesRenderers.reset();\r\n        this._empty = true;\r\n    }\r\n\r\n    /**\r\n     * Resets the different lists of sprites to prepare a new frame.\r\n     */\r\n    public prepareSprites(): void {\r\n        this._spriteManagers.reset();\r\n    }\r\n\r\n    public dispose(): void {\r\n        this._opaqueSubMeshes.dispose();\r\n        this._transparentSubMeshes.dispose();\r\n        this._alphaTestSubMeshes.dispose();\r\n        this._depthOnlySubMeshes.dispose();\r\n        this._particleSystems.dispose();\r\n        this._spriteManagers.dispose();\r\n        this._edgesRenderers.dispose();\r\n    }\r\n\r\n    /**\r\n     * Inserts the submesh in its correct queue depending on its material.\r\n     * @param subMesh The submesh to dispatch\r\n     * @param [mesh] Optional reference to the submeshes's mesh. Provide if you have an exiting reference to improve performance.\r\n     * @param [material] Optional reference to the submeshes's material. Provide if you have an exiting reference to improve performance.\r\n     */\r\n    public dispatch(subMesh: SubMesh, mesh?: AbstractMesh, material?: Nullable<Material>): void {\r\n        // Get mesh and materials if not provided\r\n        if (mesh === undefined) {\r\n            mesh = subMesh.getMesh();\r\n        }\r\n        if (material === undefined) {\r\n            material = subMesh.getMaterial();\r\n        }\r\n\r\n        if (material === null || material === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (material.needAlphaBlendingForMesh(mesh)) {\r\n            // Transparent\r\n            this._transparentSubMeshes.push(subMesh);\r\n        } else if (material.needAlphaTestingForMesh(mesh)) {\r\n            // Alpha test\r\n            if (material.needDepthPrePass && !this.disableDepthPrePass) {\r\n                this._depthOnlySubMeshes.push(subMesh);\r\n            }\r\n\r\n            this._alphaTestSubMeshes.push(subMesh);\r\n        } else {\r\n            if (material.needDepthPrePass && !this.disableDepthPrePass) {\r\n                this._depthOnlySubMeshes.push(subMesh);\r\n            }\r\n\r\n            this._opaqueSubMeshes.push(subMesh); // Opaque\r\n        }\r\n\r\n        mesh._renderingGroup = this;\r\n\r\n        if (mesh._edgesRenderer && mesh.isEnabled() && mesh.isVisible && mesh._edgesRenderer.isEnabled) {\r\n            this._edgesRenderers.pushNoDuplicate(mesh._edgesRenderer);\r\n        }\r\n\r\n        this._empty = false;\r\n    }\r\n\r\n    public dispatchSprites(spriteManager: ISpriteManager) {\r\n        this._spriteManagers.push(spriteManager);\r\n        this._empty = false;\r\n    }\r\n\r\n    public dispatchParticles(particleSystem: IParticleSystem) {\r\n        this._particleSystems.push(particleSystem);\r\n        this._empty = false;\r\n    }\r\n\r\n    private _renderParticles(activeMeshes: Nullable<AbstractMesh[]>): void {\r\n        if (this._particleSystems.length === 0) {\r\n            return;\r\n        }\r\n\r\n        // Particles\r\n        const activeCamera = this._scene.activeCamera;\r\n        this._scene.onBeforeParticlesRenderingObservable.notifyObservers(this._scene);\r\n        for (let particleIndex = 0; particleIndex < this._particleSystems.length; particleIndex++) {\r\n            const particleSystem = this._particleSystems.data[particleIndex];\r\n\r\n            if ((activeCamera && activeCamera.layerMask & particleSystem.layerMask) === 0) {\r\n                continue;\r\n            }\r\n\r\n            const emitter: any = particleSystem.emitter;\r\n            if (!emitter.position || !activeMeshes || activeMeshes.indexOf(emitter) !== -1) {\r\n                this._scene._activeParticles.addCount(particleSystem.render(), false);\r\n            }\r\n        }\r\n        this._scene.onAfterParticlesRenderingObservable.notifyObservers(this._scene);\r\n    }\r\n\r\n    private _renderSprites(): void {\r\n        if (!this._scene.spritesEnabled || this._spriteManagers.length === 0) {\r\n            return;\r\n        }\r\n\r\n        // Sprites\r\n        const activeCamera = this._scene.activeCamera;\r\n        this._scene.onBeforeSpritesRenderingObservable.notifyObservers(this._scene);\r\n        for (let id = 0; id < this._spriteManagers.length; id++) {\r\n            const spriteManager = this._spriteManagers.data[id];\r\n\r\n            if ((activeCamera && activeCamera.layerMask & spriteManager.layerMask) !== 0) {\r\n                spriteManager.render();\r\n            }\r\n        }\r\n        this._scene.onAfterSpritesRenderingObservable.notifyObservers(this._scene);\r\n    }\r\n}\r\n","import { type Immutable, type Nullable } from \"../types\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\nimport { type ISpriteManager } from \"../Sprites/spriteManager\";\r\nimport { type IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport { RenderingGroup } from \"./renderingGroup\";\r\n\r\nimport { type Scene } from \"../scene\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type Material } from \"../Materials/material\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * Interface describing the different options available in the rendering manager\r\n * regarding Auto Clear between groups.\r\n */\r\nexport interface IRenderingManagerAutoClearSetup {\r\n    /**\r\n     * Defines whether or not autoclear is enable.\r\n     */\r\n    autoClear: boolean;\r\n    /**\r\n     * Defines whether or not to autoclear the depth buffer.\r\n     */\r\n    depth: boolean;\r\n    /**\r\n     * Defines whether or not to autoclear the stencil buffer.\r\n     */\r\n    stencil: boolean;\r\n}\r\n\r\n/**\r\n * This class is used by the onRenderingGroupObservable\r\n */\r\nexport class RenderingGroupInfo {\r\n    /**\r\n     * The Scene that being rendered\r\n     */\r\n    scene: Scene;\r\n\r\n    /**\r\n     * The camera currently used for the rendering pass\r\n     */\r\n    camera: Nullable<Camera>;\r\n\r\n    /**\r\n     * The ID of the renderingGroup being processed\r\n     */\r\n    renderingGroupId: number;\r\n\r\n    /**\r\n     * The rendering manager\r\n     */\r\n    renderingManager: RenderingManager;\r\n}\r\n\r\n/**\r\n * This is the manager responsible of all the rendering for meshes sprites and particles.\r\n * It is enable to manage the different groups as well as the different necessary sort functions.\r\n * This should not be used directly aside of the few static configurations\r\n */\r\nexport class RenderingManager {\r\n    /**\r\n     * The max id used for rendering groups (not included)\r\n     */\r\n    public static MAX_RENDERINGGROUPS = 4;\r\n\r\n    /**\r\n     * The min id used for rendering groups (included)\r\n     */\r\n    public static MIN_RENDERINGGROUPS = 0;\r\n\r\n    /**\r\n     * Used to globally prevent autoclearing scenes.\r\n     */\r\n    public static AUTOCLEAR = true;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _useSceneAutoClearSetup = false;\r\n\r\n    private _disableDepthPrePass = false;\r\n    /**\r\n     * Specifies to disable depth pre-pass if true (default: false)\r\n     */\r\n    public get disableDepthPrePass() {\r\n        return this._disableDepthPrePass;\r\n    }\r\n\r\n    public set disableDepthPrePass(value: boolean) {\r\n        this._disableDepthPrePass = value;\r\n        for (const group of this._renderingGroups) {\r\n            group.disableDepthPrePass = value;\r\n        }\r\n    }\r\n\r\n    private _scene: Scene;\r\n    private _renderingGroups = new Array<RenderingGroup>();\r\n    private _depthStencilBufferAlreadyCleaned: boolean;\r\n\r\n    private _autoClearDepthStencil: { [id: number]: IRenderingManagerAutoClearSetup } = {};\r\n    private _customOpaqueSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {};\r\n    private _customAlphaTestSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {};\r\n    private _customTransparentSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {};\r\n    private _renderingGroupInfo: Nullable<RenderingGroupInfo> = new RenderingGroupInfo();\r\n\r\n    private _maintainStateBetweenFrames = false;\r\n    /**\r\n     * Gets or sets a boolean indicating that the manager will not reset between frames.\r\n     * This means that if a mesh becomes invisible or transparent it will not be visible until this boolean is set to false again.\r\n     * By default, the rendering manager will dispatch all active meshes per frame (moving them to the transparent, opaque or alpha testing lists).\r\n     * By turning this property on, you will accelerate the rendering by keeping all these lists unchanged between frames.\r\n     */\r\n    public get maintainStateBetweenFrames() {\r\n        return this._maintainStateBetweenFrames;\r\n    }\r\n\r\n    public set maintainStateBetweenFrames(value: boolean) {\r\n        if (value === this._maintainStateBetweenFrames) {\r\n            return;\r\n        }\r\n\r\n        this._maintainStateBetweenFrames = value;\r\n        if (!this._maintainStateBetweenFrames) {\r\n            this.restoreDispachedFlags();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Restore wasDispatched flags on the lists of elements to render.\r\n     */\r\n    public restoreDispachedFlags() {\r\n        for (const mesh of this._scene.meshes) {\r\n            if (mesh.subMeshes) {\r\n                for (const subMesh of mesh.subMeshes) {\r\n                    subMesh._wasDispatched = false;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._scene.spriteManagers) {\r\n            for (const spriteManager of this._scene.spriteManagers) {\r\n                spriteManager._wasDispatched = false;\r\n            }\r\n        }\r\n\r\n        for (const particleSystem of this._scene.particleSystems) {\r\n            particleSystem._wasDispatched = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new rendering group for a particular scene\r\n     * @param scene Defines the scene the groups belongs to\r\n     */\r\n    constructor(scene: Scene) {\r\n        this._scene = scene;\r\n\r\n        for (let i = RenderingManager.MIN_RENDERINGGROUPS; i < RenderingManager.MAX_RENDERINGGROUPS; i++) {\r\n            this._autoClearDepthStencil[i] = { autoClear: true, depth: true, stencil: true };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns the list of rendering groups managed by the manager.\r\n     */\r\n    public get renderingGroups(): Immutable<RenderingGroup[]> {\r\n        return this._renderingGroups;\r\n    }\r\n\r\n    /**\r\n     * @returns the rendering group with the specified id.\r\n     * @param id the id of the rendering group (0 by default)\r\n     */\r\n    public getRenderingGroup(id: number): RenderingGroup {\r\n        const renderingGroupId = id || 0;\r\n\r\n        this._prepareRenderingGroup(renderingGroupId);\r\n\r\n        return this._renderingGroups[renderingGroupId];\r\n    }\r\n\r\n    private _clearDepthStencilBuffer(depth = true, stencil = true): void {\r\n        if (this._depthStencilBufferAlreadyCleaned) {\r\n            return;\r\n        }\r\n\r\n        this._scene.getEngine().clear(null, false, depth, stencil);\r\n        this._depthStencilBufferAlreadyCleaned = true;\r\n    }\r\n\r\n    /**\r\n     * Renders the entire managed groups. This is used by the scene or the different render targets.\r\n     * @internal\r\n     */\r\n    public render(\r\n        customRenderFunction: Nullable<\r\n            (\r\n                opaqueSubMeshes: SmartArray<SubMesh>,\r\n                transparentSubMeshes: SmartArray<SubMesh>,\r\n                alphaTestSubMeshes: SmartArray<SubMesh>,\r\n                depthOnlySubMeshes: SmartArray<SubMesh>\r\n            ) => void\r\n        >,\r\n        activeMeshes: Nullable<AbstractMesh[]>,\r\n        renderParticles: boolean,\r\n        renderSprites: boolean,\r\n        renderDepthOnlyMeshes: boolean = true,\r\n        renderOpaqueMeshes: boolean = true,\r\n        renderAlphaTestMeshes: boolean = true,\r\n        renderTransparentMeshes: boolean = true,\r\n        customRenderTransparentSubMeshes?: (transparentSubMeshes: SmartArray<SubMesh>, renderingGroup?: RenderingGroup) => void,\r\n        spriteManagers?: Nullable<ISpriteManager[]>\r\n    ): void {\r\n        // Update the observable context (not null as it only goes away on dispose)\r\n        const info = this._renderingGroupInfo!;\r\n        info.scene = this._scene;\r\n        info.camera = this._scene.activeCamera;\r\n        info.renderingManager = this;\r\n\r\n        // Dispatch sprites\r\n        const spriteManagersToRender = spriteManagers ?? this._scene.spriteManagers;\r\n        if (spriteManagersToRender && renderSprites) {\r\n            for (let index = 0; index < spriteManagersToRender.length; index++) {\r\n                const manager = spriteManagersToRender[index];\r\n                this.dispatchSprites(manager);\r\n            }\r\n        }\r\n\r\n        // Render\r\n        for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n            this._depthStencilBufferAlreadyCleaned = index === RenderingManager.MIN_RENDERINGGROUPS;\r\n            const renderingGroup = this._renderingGroups[index];\r\n            if (!renderingGroup || renderingGroup._empty) {\r\n                continue;\r\n            }\r\n\r\n            const renderingGroupMask = 1 << index;\r\n            info.renderingGroupId = index;\r\n\r\n            // Before Observable\r\n            this._scene.onBeforeRenderingGroupObservable.notifyObservers(info, renderingGroupMask);\r\n\r\n            // Clear depth/stencil if needed\r\n            if (RenderingManager.AUTOCLEAR) {\r\n                const autoClear = this._useSceneAutoClearSetup ? this._scene.getAutoClearDepthStencilSetup(index) : this._autoClearDepthStencil[index];\r\n\r\n                if (autoClear && autoClear.autoClear) {\r\n                    this._clearDepthStencilBuffer(autoClear.depth, autoClear.stencil);\r\n                }\r\n            }\r\n\r\n            // Render\r\n            for (const step of this._scene._beforeRenderingGroupDrawStage) {\r\n                step.action(index);\r\n            }\r\n            renderingGroup.render(\r\n                customRenderFunction,\r\n                renderSprites,\r\n                renderParticles,\r\n                activeMeshes,\r\n                renderDepthOnlyMeshes,\r\n                renderOpaqueMeshes,\r\n                renderAlphaTestMeshes,\r\n                renderTransparentMeshes,\r\n                customRenderTransparentSubMeshes\r\n            );\r\n            for (const step of this._scene._afterRenderingGroupDrawStage) {\r\n                step.action(index);\r\n            }\r\n\r\n            // After Observable\r\n            this._scene.onAfterRenderingGroupObservable.notifyObservers(info, renderingGroupMask);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the different information of the group to prepare a new frame\r\n     * @internal\r\n     */\r\n    public reset(): void {\r\n        if (this.maintainStateBetweenFrames) {\r\n            return;\r\n        }\r\n\r\n        for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n            const renderingGroup = this._renderingGroups[index];\r\n            if (renderingGroup) {\r\n                renderingGroup.prepare();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the sprites information of the group to prepare a new frame\r\n     * @internal\r\n     */\r\n    public resetSprites(): void {\r\n        if (this.maintainStateBetweenFrames) {\r\n            return;\r\n        }\r\n\r\n        for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n            const renderingGroup = this._renderingGroups[index];\r\n            if (renderingGroup) {\r\n                renderingGroup.prepareSprites();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose and release the group and its associated resources.\r\n     * @internal\r\n     */\r\n    public dispose(): void {\r\n        this.freeRenderingGroups();\r\n        this._renderingGroups.length = 0;\r\n        this._renderingGroupInfo = null;\r\n    }\r\n\r\n    /**\r\n     * Clear the info related to rendering groups preventing retention points during dispose.\r\n     */\r\n    public freeRenderingGroups(): void {\r\n        for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n            const renderingGroup = this._renderingGroups[index];\r\n            if (renderingGroup) {\r\n                renderingGroup.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _prepareRenderingGroup(renderingGroupId: number): void {\r\n        if (this._renderingGroups[renderingGroupId] === undefined) {\r\n            this._renderingGroups[renderingGroupId] = new RenderingGroup(\r\n                renderingGroupId,\r\n                this._scene,\r\n                this._customOpaqueSortCompareFn[renderingGroupId],\r\n                this._customAlphaTestSortCompareFn[renderingGroupId],\r\n                this._customTransparentSortCompareFn[renderingGroupId]\r\n            );\r\n            this._renderingGroups[renderingGroupId].disableDepthPrePass = this._disableDepthPrePass;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add a sprite manager to the rendering manager in order to render it this frame.\r\n     * @param spriteManager Define the sprite manager to render\r\n     */\r\n    public dispatchSprites(spriteManager: ISpriteManager) {\r\n        if (this.maintainStateBetweenFrames && spriteManager._wasDispatched) {\r\n            return;\r\n        }\r\n        spriteManager._wasDispatched = true;\r\n        this.getRenderingGroup(spriteManager.renderingGroupId).dispatchSprites(spriteManager);\r\n    }\r\n\r\n    /**\r\n     * Add a particle system to the rendering manager in order to render it this frame.\r\n     * @param particleSystem Define the particle system to render\r\n     */\r\n    public dispatchParticles(particleSystem: IParticleSystem) {\r\n        if (this.maintainStateBetweenFrames && particleSystem._wasDispatched) {\r\n            return;\r\n        }\r\n        particleSystem._wasDispatched = true;\r\n        this.getRenderingGroup(particleSystem.renderingGroupId).dispatchParticles(particleSystem);\r\n    }\r\n\r\n    /**\r\n     * Add a submesh to the manager in order to render it this frame\r\n     * @param subMesh The submesh to dispatch\r\n     * @param mesh Optional reference to the submeshes's mesh. Provide if you have an exiting reference to improve performance.\r\n     * @param material Optional reference to the submeshes's material. Provide if you have an exiting reference to improve performance.\r\n     */\r\n    public dispatch(subMesh: SubMesh, mesh?: AbstractMesh, material?: Nullable<Material>): void {\r\n        if (mesh === undefined) {\r\n            mesh = subMesh.getMesh();\r\n        }\r\n        if (this.maintainStateBetweenFrames && subMesh._wasDispatched) {\r\n            return;\r\n        }\r\n        subMesh._wasDispatched = true;\r\n        this.getRenderingGroup(mesh.renderingGroupId).dispatch(subMesh, mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n     * This allowed control for front to back rendering or reversely depending of the special needs.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n     * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n     */\r\n    public setRenderingOrder(\r\n        renderingGroupId: number,\r\n        opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n    ) {\r\n        this._customOpaqueSortCompareFn[renderingGroupId] = opaqueSortCompareFn;\r\n        this._customAlphaTestSortCompareFn[renderingGroupId] = alphaTestSortCompareFn;\r\n        this._customTransparentSortCompareFn[renderingGroupId] = transparentSortCompareFn;\r\n\r\n        if (this._renderingGroups[renderingGroupId]) {\r\n            const group = this._renderingGroups[renderingGroupId];\r\n            group.opaqueSortCompareFn = this._customOpaqueSortCompareFn[renderingGroupId];\r\n            group.alphaTestSortCompareFn = this._customAlphaTestSortCompareFn[renderingGroupId];\r\n            group.transparentSortCompareFn = this._customTransparentSortCompareFn[renderingGroupId];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n     * @param depth Automatically clears depth between groups if true and autoClear is true.\r\n     * @param stencil Automatically clears stencil between groups if true and autoClear is true.\r\n     */\r\n    public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean, depth = true, stencil = true): void {\r\n        this._autoClearDepthStencil[renderingGroupId] = {\r\n            autoClear: autoClearDepthStencil,\r\n            depth: depth,\r\n            stencil: stencil,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the current auto clear configuration for one rendering group of the rendering\r\n     * manager.\r\n     * @param index the rendering group index to get the information for\r\n     * @returns The auto clear setup for the requested rendering group\r\n     */\r\n    public getAutoClearDepthStencilSetup(index: number): IRenderingManagerAutoClearSetup {\r\n        return this._autoClearDepthStencil[index];\r\n    }\r\n}\r\n","import { type Scene } from \"./scene\";\r\nimport { type SmartArrayNoDuplicate } from \"./Misc/smartArray\";\r\nimport { type Nullable } from \"./types\";\r\nimport { type PickingInfo } from \"./Collisions/pickingInfo\";\r\nimport { type IPointerEvent } from \"./Events/deviceInputEvents\";\r\n\r\nimport { type Mesh } from \"./Meshes/mesh\";\r\nimport { type Effect } from \"./Materials/effect\";\r\nimport { type Camera } from \"./Cameras/camera\";\r\nimport { type AbstractMesh } from \"./Meshes/abstractMesh\";\r\nimport { type SubMesh } from \"./Meshes/subMesh\";\r\nimport { type RenderTargetTexture } from \"./Materials/Textures/renderTargetTexture\";\r\nimport { type IAssetContainer } from \"./IAssetContainer\";\r\n\r\n/**\r\n * Groups all the scene component constants in one place to ease maintenance.\r\n * @internal\r\n */\r\nexport class SceneComponentConstants {\r\n    public static readonly NAME_EFFECTLAYER = \"EffectLayer\";\r\n    public static readonly NAME_LAYER = \"Layer\";\r\n    public static readonly NAME_LENSFLARESYSTEM = \"LensFlareSystem\";\r\n    public static readonly NAME_BOUNDINGBOXRENDERER = \"BoundingBoxRenderer\";\r\n    public static readonly NAME_PARTICLESYSTEM = \"ParticleSystem\";\r\n    public static readonly NAME_GAMEPAD = \"Gamepad\";\r\n    public static readonly NAME_SIMPLIFICATIONQUEUE = \"SimplificationQueue\";\r\n    public static readonly NAME_GEOMETRYBUFFERRENDERER = \"GeometryBufferRenderer\";\r\n    public static readonly NAME_PREPASSRENDERER = \"PrePassRenderer\";\r\n    public static readonly NAME_DEPTHRENDERER = \"DepthRenderer\";\r\n    public static readonly NAME_DEPTHPEELINGRENDERER = \"DepthPeelingRenderer\";\r\n    public static readonly NAME_POSTPROCESSRENDERPIPELINEMANAGER = \"PostProcessRenderPipelineManager\";\r\n    public static readonly NAME_SPRITE = \"Sprite\";\r\n    public static readonly NAME_SUBSURFACE = \"SubSurface\";\r\n    public static readonly NAME_OUTLINERENDERER = \"Outline\";\r\n    public static readonly NAME_PROCEDURALTEXTURE = \"ProceduralTexture\";\r\n    public static readonly NAME_SHADOWGENERATOR = \"ShadowGenerator\";\r\n    public static readonly NAME_OCTREE = \"Octree\";\r\n    public static readonly NAME_PHYSICSENGINE = \"PhysicsEngine\";\r\n    public static readonly NAME_AUDIO = \"Audio\";\r\n    public static readonly NAME_FLUIDRENDERER = \"FluidRenderer\";\r\n    public static readonly NAME_IBLCDFGENERATOR = \"iblCDFGenerator\";\r\n    public static readonly NAME_CLUSTEREDLIGHTING = \"ClusteredLighting\";\r\n\r\n    public static readonly STEP_ISREADYFORMESH_EFFECTLAYER = 0;\r\n    public static readonly STEP_ISREADYFORMESH_DEPTHRENDERER = 1;\r\n\r\n    public static readonly STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER = 0;\r\n\r\n    public static readonly STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER = 0;\r\n\r\n    public static readonly STEP_PREACTIVEMESH_BOUNDINGBOXRENDERER = 0;\r\n\r\n    public static readonly STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;\r\n\r\n    public static readonly STEP_BEFORECAMERADRAW_PREPASS = 0;\r\n    public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 1;\r\n    public static readonly STEP_BEFORECAMERADRAW_LAYER = 2;\r\n\r\n    public static readonly STEP_BEFORERENDERTARGETDRAW_PREPASS = 0;\r\n    public static readonly STEP_BEFORERENDERTARGETDRAW_LAYER = 1;\r\n\r\n    public static readonly STEP_BEFORERENDERINGMESH_PREPASS = 0;\r\n    public static readonly STEP_BEFORERENDERINGMESH_OUTLINE = 1;\r\n\r\n    public static readonly STEP_AFTERRENDERINGMESH_PREPASS = 0;\r\n    public static readonly STEP_AFTERRENDERINGMESH_OUTLINE = 1;\r\n\r\n    public static readonly STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;\r\n    public static readonly STEP_AFTERRENDERINGGROUPDRAW_BOUNDINGBOXRENDERER = 1;\r\n\r\n    public static readonly STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;\r\n\r\n    public static readonly STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;\r\n    public static readonly STEP_BEFORECLEAR_PREPASS = 1;\r\n\r\n    public static readonly STEP_BEFORERENDERTARGETCLEAR_PREPASS = 0;\r\n\r\n    public static readonly STEP_AFTERRENDERTARGETDRAW_PREPASS = 0;\r\n    public static readonly STEP_AFTERRENDERTARGETDRAW_LAYER = 1;\r\n\r\n    public static readonly STEP_AFTERCAMERADRAW_PREPASS = 0;\r\n    public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER = 1;\r\n    public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 2;\r\n    public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 3;\r\n    public static readonly STEP_AFTERCAMERADRAW_LAYER = 4;\r\n    public static readonly STEP_AFTERCAMERADRAW_FLUIDRENDERER = 5;\r\n\r\n    public static readonly STEP_AFTERCAMERAPOSTPROCESS_LAYER = 0;\r\n\r\n    public static readonly STEP_AFTERRENDERTARGETPOSTPROCESS_LAYER = 0;\r\n\r\n    public static readonly STEP_AFTERRENDER_AUDIO = 0;\r\n\r\n    public static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER = 0;\r\n    public static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER = 1;\r\n    public static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR = 2;\r\n    public static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER = 3;\r\n\r\n    public static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER = 0;\r\n    public static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_FLUIDRENDERER = 1;\r\n    public static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_CLUSTEREDLIGHTING = 2;\r\n\r\n    public static readonly STEP_POINTERMOVE_SPRITE = 0;\r\n    public static readonly STEP_POINTERDOWN_SPRITE = 0;\r\n    public static readonly STEP_POINTERUP_SPRITE = 0;\r\n}\r\n\r\n/**\r\n * This represents a scene component.\r\n *\r\n * This is used to decouple the dependency the scene is having on the different workloads like\r\n * layers, post processes...\r\n */\r\nexport interface ISceneComponent {\r\n    /**\r\n     * The name of the component. Each component must have a unique name.\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    scene: Scene;\r\n\r\n    /**\r\n     * Register the component to one instance of a scene.\r\n     */\r\n    register(): void;\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    rebuild(): void;\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    dispose(): void;\r\n}\r\n\r\n/**\r\n * This represents a SERIALIZABLE scene component.\r\n *\r\n * This extends Scene Component to add Serialization methods on top.\r\n */\r\nexport interface ISceneSerializableComponent extends ISceneComponent {\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     * @param container the container holding the elements\r\n     */\r\n    addFromContainer(container: IAssetContainer): void;\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     * @param container contains the elements to remove\r\n     * @param dispose if the removed element should be disposed (default: false)\r\n     */\r\n    removeFromContainer(container: IAssetContainer, dispose?: boolean): void;\r\n\r\n    /**\r\n     * Serializes the component data to the specified json object\r\n     * @param serializationObject The object to serialize to\r\n     */\r\n    serialize(serializationObject: any): void;\r\n}\r\n\r\n/**\r\n * Strong typing of a Mesh related stage step action\r\n */\r\nexport type MeshStageAction = (mesh: AbstractMesh, hardwareInstancedRendering: boolean) => boolean;\r\n\r\n/**\r\n * Strong typing of a Evaluate Sub Mesh related stage step action\r\n */\r\nexport type EvaluateSubMeshStageAction = (mesh: AbstractMesh, subMesh: SubMesh) => void;\r\n\r\n/**\r\n * Strong typing of a pre active Mesh related stage step action\r\n */\r\nexport type PreActiveMeshStageAction = (mesh: AbstractMesh) => void;\r\n\r\n/**\r\n * Strong typing of a Camera related stage step action\r\n */\r\nexport type CameraStageAction = (camera: Camera) => void;\r\n\r\n/**\r\n * Strong typing of a Camera Frame buffer related stage step action\r\n */\r\nexport type CameraStageFrameBufferAction = (camera: Camera) => boolean;\r\n\r\n/**\r\n * Strong typing of a Render Target related stage step action\r\n */\r\nexport type RenderTargetStageAction = (renderTarget: RenderTargetTexture, faceIndex?: number, layer?: number) => void;\r\n\r\n/**\r\n * Strong typing of a RenderingGroup related stage step action\r\n */\r\nexport type RenderingGroupStageAction = (renderingGroupId: number) => void;\r\n\r\n/**\r\n * Strong typing of a Mesh Render related stage step action\r\n */\r\nexport type RenderingMeshStageAction = (mesh: Mesh, subMesh: SubMesh, batch: any, effect: Nullable<Effect>) => void;\r\n\r\n/**\r\n * Strong typing of a simple stage step action\r\n */\r\nexport type SimpleStageAction = () => void;\r\n\r\n/**\r\n * Strong typing of a render target action.\r\n */\r\nexport type RenderTargetsStageAction = (renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>) => void;\r\n\r\n/**\r\n * Strong typing of a pointer move action.\r\n */\r\nexport type PointerMoveStageAction = (\r\n    unTranslatedPointerX: number,\r\n    unTranslatedPointerY: number,\r\n    pickResult: Nullable<PickingInfo>,\r\n    isMeshPicked: boolean,\r\n    element: Nullable<HTMLElement>\r\n) => Nullable<PickingInfo>;\r\n\r\n/**\r\n * Strong typing of a pointer up/down action.\r\n */\r\nexport type PointerUpDownStageAction = (\r\n    unTranslatedPointerX: number,\r\n    unTranslatedPointerY: number,\r\n    pickResult: Nullable<PickingInfo>,\r\n    evt: IPointerEvent,\r\n    doubleClick: boolean\r\n) => Nullable<PickingInfo>;\r\n\r\n/**\r\n * Representation of a stage in the scene (Basically a list of ordered steps)\r\n * @internal\r\n */\r\nexport class Stage<T extends Function> extends Array<{ index: number; component: ISceneComponent; action: T }> {\r\n    /**\r\n     * Hide ctor from the rest of the world.\r\n     * @param items The items to add.\r\n     */\r\n    private constructor(items?: { index: number; component: ISceneComponent; action: T }[]) {\r\n        super(...(<any>items));\r\n    }\r\n\r\n    /**\r\n     * Creates a new Stage.\r\n     * @returns A new instance of a Stage\r\n     */\r\n    static Create<T extends Function>(): Stage<T> {\r\n        return Object.create(Stage.prototype) as Stage<T>;\r\n    }\r\n\r\n    /**\r\n     * Registers a step in an ordered way in the targeted stage.\r\n     * @param index Defines the position to register the step in\r\n     * @param component Defines the component attached to the step\r\n     * @param action Defines the action to launch during the step\r\n     */\r\n    public registerStep(index: number, component: ISceneComponent, action: T): void {\r\n        let i = 0;\r\n        let maxIndex: number;\r\n        for (; i < this.length; i++) {\r\n            const step = this[i];\r\n            maxIndex = step.index;\r\n            if (index < maxIndex) {\r\n                break;\r\n            }\r\n        }\r\n        this.splice(i, 0, { index, component, action: action.bind(component) });\r\n    }\r\n\r\n    /**\r\n     * Clears all the steps from the stage.\r\n     */\r\n    public clear(): void {\r\n        this.length = 0;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type IMouseEvent, type IPointerEvent } from \"./deviceInputEvents\";\r\nimport { type InputManager } from \"../Inputs/scene.inputManager\";\r\n\r\nimport { type Ray } from \"../Culling/ray\";\r\n\r\n/**\r\n * Gather the list of pointer event types as constants.\r\n */\r\nexport class PointerEventTypes {\r\n    /**\r\n     * The pointerdown event is fired when a pointer becomes active. For mouse, it is fired when the device transitions from no buttons depressed to at least one button depressed. For touch, it is fired when physical contact is made with the digitizer. For pen, it is fired when the stylus makes physical contact with the digitizer.\r\n     */\r\n    public static readonly POINTERDOWN = 0x01;\r\n    /**\r\n     * The pointerup event is fired when a pointer is no longer active.\r\n     */\r\n    public static readonly POINTERUP = 0x02;\r\n    /**\r\n     * The pointermove event is fired when a pointer changes coordinates.\r\n     */\r\n    public static readonly POINTERMOVE = 0x04;\r\n    /**\r\n     * The pointerwheel event is fired when a mouse wheel has been rotated.\r\n     */\r\n    public static readonly POINTERWHEEL = 0x08;\r\n    /**\r\n     * The pointerpick event is fired when a mesh or sprite has been picked by the pointer.\r\n     */\r\n    public static readonly POINTERPICK = 0x10;\r\n    /**\r\n     * The pointertap event is fired when a the object has been touched and released without drag.\r\n     */\r\n    public static readonly POINTERTAP = 0x20;\r\n    /**\r\n     * The pointerdoubletap event is fired when a the object has been touched and released twice without drag.\r\n     */\r\n    public static readonly POINTERDOUBLETAP = 0x40;\r\n}\r\n\r\n/**\r\n * Base class of pointer info types.\r\n */\r\nexport class PointerInfoBase {\r\n    /**\r\n     * Instantiates the base class of pointers info.\r\n     * @param type Defines the type of event (PointerEventTypes)\r\n     * @param event Defines the related dom event\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the type of event (PointerEventTypes)\r\n         */\r\n        public type: number,\r\n        /**\r\n         * Defines the related dom event\r\n         */\r\n        public event: IMouseEvent\r\n    ) {}\r\n}\r\n\r\n/**\r\n * This class is used to store pointer related info for the onPrePointerObservable event.\r\n * Set the skipOnPointerObservable property to true if you want the engine to stop any process after this event is triggered, even not calling onPointerObservable\r\n */\r\nexport class PointerInfoPre extends PointerInfoBase {\r\n    /**\r\n     * Ray from a pointer if available (eg. 6dof controller)\r\n     */\r\n    public ray: Nullable<Ray> = null;\r\n\r\n    /**\r\n     * Defines picking info coming from a near interaction (proximity instead of ray-based picking)\r\n     */\r\n    public nearInteractionPickingInfo: Nullable<PickingInfo>;\r\n\r\n    /**\r\n     * The original picking info that was used to trigger the pointer event\r\n     */\r\n    public originalPickingInfo: Nullable<PickingInfo> = null;\r\n\r\n    /**\r\n     * Defines the local position of the pointer on the canvas.\r\n     */\r\n    public localPosition: Vector2;\r\n\r\n    /**\r\n     * Defines whether the engine should skip the next OnPointerObservable associated to this pre.\r\n     */\r\n    public skipOnPointerObservable: boolean;\r\n\r\n    /**\r\n     * Instantiates a PointerInfoPre to store pointer related info to the onPrePointerObservable event.\r\n     * @param type Defines the type of event (PointerEventTypes)\r\n     * @param event Defines the related dom event\r\n     * @param localX Defines the local x coordinates of the pointer when the event occured\r\n     * @param localY Defines the local y coordinates of the pointer when the event occured\r\n     */\r\n    constructor(type: number, event: IMouseEvent, localX: number, localY: number) {\r\n        super(type, event);\r\n        this.skipOnPointerObservable = false;\r\n        this.localPosition = new Vector2(localX, localY);\r\n    }\r\n}\r\n\r\n/**\r\n * This type contains all the data related to a pointer event in Babylon.js.\r\n * The event member is an instance of PointerEvent for all types except PointerWheel and is of type MouseWheelEvent when type equals PointerWheel. The different event types can be found in the PointerEventTypes class.\r\n */\r\nexport class PointerInfo extends PointerInfoBase {\r\n    private _pickInfo: Nullable<PickingInfo>;\r\n    private _inputManager: Nullable<InputManager>;\r\n\r\n    /**\r\n     * Defines the picking info associated with this PointerInfo object (if applicable)\r\n     */\r\n    public get pickInfo(): Nullable<PickingInfo> {\r\n        if (!this._pickInfo) {\r\n            this._generatePickInfo();\r\n        }\r\n\r\n        return this._pickInfo;\r\n    }\r\n    /**\r\n     * Instantiates a PointerInfo to store pointer related info to the onPointerObservable event.\r\n     * @param type Defines the type of event (PointerEventTypes)\r\n     * @param event Defines the related dom event\r\n     * @param pickInfo Defines the picking info associated to the info (if any)\r\n     * @param inputManager Defines the InputManager to use if there is no pickInfo\r\n     */\r\n    constructor(type: number, event: IMouseEvent, pickInfo: Nullable<PickingInfo>, inputManager: Nullable<InputManager> = null) {\r\n        super(type, event);\r\n        this._pickInfo = pickInfo;\r\n        this._inputManager = inputManager;\r\n    }\r\n\r\n    /**\r\n     * Generates the picking info if needed\r\n     */\r\n    /** @internal */\r\n    public _generatePickInfo(): void {\r\n        if (this._inputManager) {\r\n            this._pickInfo = this._inputManager._pickMove(this.event as IPointerEvent);\r\n            this._inputManager._setRayOnPointerInfo(this._pickInfo, this.event);\r\n            this._inputManager = null;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Data relating to a touch event on the screen.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PointerTouch {\r\n    /**\r\n     * X coordinate of touch.\r\n     */\r\n    x: number;\r\n    /**\r\n     * Y coordinate of touch.\r\n     */\r\n    y: number;\r\n    /**\r\n     * Id of touch. Unique for each finger.\r\n     */\r\n    pointerId: number;\r\n    /**\r\n     * Event type passed from DOM.\r\n     */\r\n    type: any;\r\n    /**\r\n     * The touch event's associated button ID (0: left, 1: middle, 2: right, etc.)\r\n     */\r\n    button?: number;\r\n}\r\n","import { type IKeyboardEvent } from \"./deviceInputEvents\";\r\n\r\n/**\r\n * Gather the list of keyboard event types as constants.\r\n */\r\nexport class KeyboardEventTypes {\r\n    /**\r\n     * The keydown event is fired when a key becomes active (pressed).\r\n     */\r\n    public static readonly KEYDOWN = 0x01;\r\n    /**\r\n     * The keyup event is fired when a key has been released.\r\n     */\r\n    public static readonly KEYUP = 0x02;\r\n}\r\n\r\n/**\r\n * This class is used to store keyboard related info for the onKeyboardObservable event.\r\n */\r\nexport class KeyboardInfo {\r\n    /**\r\n     * Instantiates a new keyboard info.\r\n     * This class is used to store keyboard related info for the onKeyboardObservable event.\r\n     * @param type Defines the type of event (KeyboardEventTypes)\r\n     * @param event Defines the related dom event\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the type of event (KeyboardEventTypes)\r\n         */\r\n        public type: number,\r\n        /**\r\n         * Defines the related dom event\r\n         */\r\n        public event: IKeyboardEvent\r\n    ) {}\r\n}\r\n\r\n/**\r\n * This class is used to store keyboard related info for the onPreKeyboardObservable event.\r\n * Set the skipOnKeyboardObservable property to true if you want the engine to stop any process after this event is triggered, even not calling onKeyboardObservable\r\n */\r\nexport class KeyboardInfoPre extends KeyboardInfo {\r\n    /**\r\n     * Defines whether the engine should skip the next onKeyboardObservable associated to this pre.\r\n     */\r\n    public skipOnKeyboardObservable: boolean;\r\n\r\n    /**\r\n     * Defines whether the engine should skip the next onKeyboardObservable associated to this pre.\r\n     * @deprecated use skipOnKeyboardObservable property instead\r\n     */\r\n    public get skipOnPointerObservable() {\r\n        return this.skipOnKeyboardObservable;\r\n    }\r\n    public set skipOnPointerObservable(value) {\r\n        this.skipOnKeyboardObservable = value;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new keyboard pre info.\r\n     * This class is used to store keyboard related info for the onPreKeyboardObservable event.\r\n     * @param type Defines the type of event (KeyboardEventTypes)\r\n     * @param event Defines the related dom event\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the type of event (KeyboardEventTypes)\r\n         */\r\n        public override type: number,\r\n        /**\r\n         * Defines the related dom event\r\n         */\r\n        public override event: IKeyboardEvent\r\n    ) {\r\n        super(type, event);\r\n        this.skipOnKeyboardObservable = false;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/**\r\n * Enum for Device Types\r\n */\r\nexport enum DeviceType {\r\n    /** Generic */\r\n    Generic = 0,\r\n    /** Keyboard */\r\n    Keyboard = 1,\r\n    /** Mouse */\r\n    Mouse = 2,\r\n    /** Touch Pointers */\r\n    Touch = 3,\r\n    /** PS4 Dual Shock */\r\n    DualShock = 4,\r\n    /** Xbox */\r\n    Xbox = 5,\r\n    /** Switch Controller */\r\n    Switch = 6,\r\n    /** PS5 DualSense */\r\n    DualSense = 7,\r\n}\r\n\r\n// Device Enums\r\n/**\r\n * Enum for All Pointers (Touch/Mouse)\r\n */\r\nexport enum PointerInput {\r\n    /** Horizontal Axis (Not used in events/observables; only in polling) */\r\n    Horizontal = 0,\r\n    /** Vertical Axis (Not used in events/observables; only in polling) */\r\n    Vertical = 1,\r\n    /** Left Click or Touch */\r\n    LeftClick = 2,\r\n    /** Middle Click */\r\n    MiddleClick = 3,\r\n    /** Right Click */\r\n    RightClick = 4,\r\n    /** Browser Back */\r\n    BrowserBack = 5,\r\n    /** Browser Forward */\r\n    BrowserForward = 6,\r\n    /** Mouse Wheel X */\r\n    MouseWheelX = 7,\r\n    /** Mouse Wheel Y */\r\n    MouseWheelY = 8,\r\n    /** Mouse Wheel Z */\r\n    MouseWheelZ = 9,\r\n    /** Used in events/observables to identify if x/y changes occurred */\r\n    Move = 12,\r\n}\r\n\r\n/** @internal */\r\nexport const enum NativePointerInput {\r\n    /** Horizontal Axis */\r\n    Horizontal = PointerInput.Horizontal,\r\n    /** Vertical Axis */\r\n    Vertical = 1,\r\n    /** Left Click or Touch */\r\n    LeftClick = 2,\r\n    /** Middle Click */\r\n    MiddleClick = 3,\r\n    /** Right Click */\r\n    RightClick = 4,\r\n    /** Browser Back */\r\n    BrowserBack = 5,\r\n    /** Browser Forward */\r\n    BrowserForward = 6,\r\n    /** Mouse Wheel X */\r\n    MouseWheelX = 7,\r\n    /** Mouse Wheel Y */\r\n    MouseWheelY = 8,\r\n    /** Mouse Wheel Z */\r\n    MouseWheelZ = 9,\r\n    /** Delta X */\r\n    DeltaHorizontal = 10,\r\n    /** Delta Y */\r\n    DeltaVertical = 11,\r\n}\r\n\r\n/**\r\n * Enum for Dual Shock Gamepad\r\n */\r\nexport const enum DualShockInput {\r\n    /** Cross */\r\n    Cross = 0,\r\n    /** Circle */\r\n    Circle = 1,\r\n    /** Square */\r\n    Square = 2,\r\n    /** Triangle */\r\n    Triangle = 3,\r\n    /** L1 */\r\n    L1 = 4,\r\n    /** R1 */\r\n    R1 = 5,\r\n    /** L2 */\r\n    L2 = 6,\r\n    /** R2 */\r\n    R2 = 7,\r\n    /** Share */\r\n    Share = 8,\r\n    /** Options */\r\n    Options = 9,\r\n    /** L3 */\r\n    L3 = 10,\r\n    /** R3 */\r\n    R3 = 11,\r\n    /** DPadUp */\r\n    DPadUp = 12,\r\n    /** DPadDown */\r\n    DPadDown = 13,\r\n    /** DPadLeft */\r\n    DPadLeft = 14,\r\n    /** DRight */\r\n    DPadRight = 15,\r\n    /** Home */\r\n    Home = 16,\r\n    /** TouchPad */\r\n    TouchPad = 17,\r\n    /** LStickXAxis */\r\n    LStickXAxis = 18,\r\n    /** LStickYAxis */\r\n    LStickYAxis = 19,\r\n    /** RStickXAxis */\r\n    RStickXAxis = 20,\r\n    /** RStickYAxis */\r\n    RStickYAxis = 21,\r\n}\r\n\r\n/**\r\n * Enum for Dual Sense Gamepad\r\n */\r\nexport const enum DualSenseInput {\r\n    /** Cross */\r\n    Cross = 0,\r\n    /** Circle */\r\n    Circle = 1,\r\n    /** Square */\r\n    Square = 2,\r\n    /** Triangle */\r\n    Triangle = 3,\r\n    /** L1 */\r\n    L1 = 4,\r\n    /** R1 */\r\n    R1 = 5,\r\n    /** L2 */\r\n    L2 = 6,\r\n    /** R2 */\r\n    R2 = 7,\r\n    /** Create */\r\n    Create = 8,\r\n    /** Options */\r\n    Options = 9,\r\n    /** L3 */\r\n    L3 = 10,\r\n    /** R3 */\r\n    R3 = 11,\r\n    /** DPadUp */\r\n    DPadUp = 12,\r\n    /** DPadDown */\r\n    DPadDown = 13,\r\n    /** DPadLeft */\r\n    DPadLeft = 14,\r\n    /** DRight */\r\n    DPadRight = 15,\r\n    /** Home */\r\n    Home = 16,\r\n    /** TouchPad */\r\n    TouchPad = 17,\r\n    /** LStickXAxis */\r\n    LStickXAxis = 18,\r\n    /** LStickYAxis */\r\n    LStickYAxis = 19,\r\n    /** RStickXAxis */\r\n    RStickXAxis = 20,\r\n    /** RStickYAxis */\r\n    RStickYAxis = 21,\r\n}\r\n\r\n/**\r\n * Enum for Xbox Gamepad\r\n */\r\nexport const enum XboxInput {\r\n    /** A */\r\n    A = 0,\r\n    /** B */\r\n    B = 1,\r\n    /** X */\r\n    X = 2,\r\n    /** Y */\r\n    Y = 3,\r\n    /** LB */\r\n    LB = 4,\r\n    /** RB */\r\n    RB = 5,\r\n    /** LT */\r\n    LT = 6,\r\n    /** RT */\r\n    RT = 7,\r\n    /** Back */\r\n    Back = 8,\r\n    /** Start */\r\n    Start = 9,\r\n    /** LS */\r\n    LS = 10,\r\n    /** RS */\r\n    RS = 11,\r\n    /** DPadUp */\r\n    DPadUp = 12,\r\n    /** DPadDown */\r\n    DPadDown = 13,\r\n    /** DPadLeft */\r\n    DPadLeft = 14,\r\n    /** DRight */\r\n    DPadRight = 15,\r\n    /** Home */\r\n    Home = 16,\r\n    /** LStickXAxis */\r\n    LStickXAxis = 17,\r\n    /** LStickYAxis */\r\n    LStickYAxis = 18,\r\n    /** RStickXAxis */\r\n    RStickXAxis = 19,\r\n    /** RStickYAxis */\r\n    RStickYAxis = 20,\r\n}\r\n\r\n/**\r\n * Enum for Switch (Pro/JoyCon L+R) Gamepad\r\n */\r\nexport const enum SwitchInput {\r\n    /** B */\r\n    B = 0,\r\n    /** A */\r\n    A = 1,\r\n    /** Y */\r\n    Y = 2,\r\n    /** X */\r\n    X = 3,\r\n    /** L */\r\n    L = 4,\r\n    /** R */\r\n    R = 5,\r\n    /** ZL */\r\n    ZL = 6,\r\n    /** ZR */\r\n    ZR = 7,\r\n    /** Minus */\r\n    Minus = 8,\r\n    /** Plus */\r\n    Plus = 9,\r\n    /** LS */\r\n    LS = 10,\r\n    /** RS */\r\n    RS = 11,\r\n    /** DPadUp */\r\n    DPadUp = 12,\r\n    /** DPadDown */\r\n    DPadDown = 13,\r\n    /** DPadLeft */\r\n    DPadLeft = 14,\r\n    /** DRight */\r\n    DPadRight = 15,\r\n    /** Home */\r\n    Home = 16,\r\n    /** Capture */\r\n    Capture = 17,\r\n    /** LStickXAxis */\r\n    LStickXAxis = 18,\r\n    /** LStickYAxis */\r\n    LStickYAxis = 19,\r\n    /** RStickXAxis */\r\n    RStickXAxis = 20,\r\n    /** RStickYAxis */\r\n    RStickYAxis = 21,\r\n}\r\n","import { type PointerInput } from \"../DeviceInput/InputDevices/deviceEnums\";\r\n\r\n/**\r\n * Event Types\r\n */\r\nexport const enum DeviceInputEventType {\r\n    // Pointers\r\n    /** PointerMove */\r\n    PointerMove,\r\n    /** PointerDown */\r\n    PointerDown,\r\n    /** PointerUp */\r\n    PointerUp,\r\n}\r\n\r\n/**\r\n * Native friendly interface for Event Object\r\n */\r\nexport interface IUIEvent {\r\n    /**\r\n     * Input array index\r\n     */\r\n    inputIndex: number;\r\n\r\n    /**\r\n     * Current target for an event\r\n     */\r\n    currentTarget?: any;\r\n\r\n    /**\r\n     * Alias for target\r\n     * @deprecated Use target instead\r\n     */\r\n    srcElement?: any;\r\n\r\n    /**\r\n     * Type of event\r\n     */\r\n    type: string;\r\n\r\n    /**\r\n     * Reference to object where object was dispatched\r\n     */\r\n    target: any;\r\n\r\n    /**\r\n     * Tells user agent what to do when not explicitly handled\r\n     */\r\n    preventDefault: () => void;\r\n}\r\n\r\n/**\r\n * Native friendly interface for KeyboardEvent Object\r\n */\r\nexport interface IKeyboardEvent extends IUIEvent {\r\n    /**\r\n     * Status of Alt key being pressed\r\n     */\r\n    altKey: boolean;\r\n\r\n    /**\r\n     * Unicode value of character pressed\r\n     * @deprecated Required for event, use keyCode instead.\r\n     */\r\n    charCode?: number;\r\n\r\n    /**\r\n     * Code for key based on layout\r\n     */\r\n    code: string;\r\n\r\n    /**\r\n     * Status of Ctrl key being pressed\r\n     */\r\n    ctrlKey: boolean;\r\n\r\n    /**\r\n     * String representation of key\r\n     */\r\n    key: string;\r\n    /**\r\n     * ASCII value of key\r\n     * @deprecated Used with DeviceSourceManager\r\n     */\r\n    keyCode: number;\r\n\r\n    /**\r\n     * Status of Meta key (eg. Windows key) being pressed\r\n     */\r\n    metaKey: boolean;\r\n\r\n    /**\r\n     * Status of Shift key being pressed\r\n     */\r\n    shiftKey: boolean;\r\n\r\n    /**\r\n     * Whether this key event was generated by an auto-repeat\r\n     * (the user is holding the key down).\r\n     */\r\n    repeat?: boolean;\r\n}\r\n\r\n/**\r\n * Native friendly interface for MouseEvent Object\r\n */\r\nexport interface IMouseEvent extends IUIEvent {\r\n    /**\r\n     * Subset of possible PointerInput values for events, excluding ones that CANNOT be in events organically\r\n     */\r\n    inputIndex: Exclude<PointerInput, PointerInput.Horizontal | PointerInput.Vertical>;\r\n\r\n    /**\r\n     * Status of Alt key being pressed\r\n     */\r\n    altKey: boolean;\r\n\r\n    /**\r\n     * Value of single mouse button pressed\r\n     */\r\n    button: number;\r\n\r\n    /**\r\n     * Value of all mouse buttons pressed\r\n     */\r\n    buttons: number;\r\n\r\n    /**\r\n     * Current X coordinate\r\n     */\r\n    clientX: number;\r\n\r\n    /**\r\n     * Current Y coordinate\r\n     */\r\n    clientY: number;\r\n\r\n    /**\r\n     * Status of Ctrl key being pressed\r\n     */\r\n    ctrlKey: boolean;\r\n\r\n    /**\r\n     * Provides current click count\r\n     */\r\n    detail?: number;\r\n\r\n    /**\r\n     * Status of Meta key (eg. Windows key) being pressed\r\n     */\r\n    metaKey: boolean;\r\n\r\n    /**\r\n     * Delta of movement on X axis\r\n     */\r\n    movementX: number;\r\n\r\n    /**\r\n     * Delta of movement on Y axis\r\n     */\r\n    movementY: number;\r\n\r\n    /**\r\n     * Delta of movement on X axis\r\n     * @deprecated Use 'movementX' instead\r\n     */\r\n    mozMovementX?: number;\r\n\r\n    /**\r\n     * Delta of movement on Y axis\r\n     * @deprecated Use 'movementY' instead\r\n     */\r\n    mozMovementY?: number;\r\n\r\n    /**\r\n     * Delta of movement on X axis\r\n     * @deprecated Use 'movementX' instead\r\n     */\r\n    msMovementX?: number;\r\n\r\n    /**\r\n     * Delta of movement on Y axis\r\n     * @deprecated Use 'movementY' instead\r\n     */\r\n    msMovementY?: number;\r\n\r\n    /**\r\n     * Current coordinate of X within container\r\n     */\r\n    offsetX: number;\r\n\r\n    /**\r\n     * Current coordinate of Y within container\r\n     */\r\n    offsetY: number;\r\n\r\n    /**\r\n     * Horizontal coordinate of event\r\n     */\r\n    pageX: number;\r\n\r\n    /**\r\n     * Vertical coordinate of event\r\n     */\r\n    pageY: number;\r\n\r\n    /**\r\n     * Status of Shift key being pressed\r\n     */\r\n    shiftKey: boolean;\r\n\r\n    /**\r\n     * Delta of movement on X axis\r\n     * @deprecated Use 'movementX' instead\r\n     */\r\n    webkitMovementX?: number;\r\n\r\n    /**\r\n     * Delta of movement on Y axis\r\n     * @deprecated Use 'movementY' instead\r\n     */\r\n    webkitMovementY?: number;\r\n\r\n    /**\r\n     * Alias of clientX\r\n     */\r\n    x: number;\r\n\r\n    /**\r\n     * Alias of clientY\r\n     */\r\n    y: number;\r\n}\r\n\r\n/**\r\n * Native friendly interface for PointerEvent Object\r\n */\r\nexport interface IPointerEvent extends IMouseEvent {\r\n    /**\r\n     * Subset of possible PointerInput values for events, excluding ones that CANNOT be in events organically and mouse wheel values\r\n     */\r\n    inputIndex: Exclude<PointerInput, PointerInput.Horizontal | PointerInput.Vertical | PointerInput.MouseWheelX | PointerInput.MouseWheelY | PointerInput.MouseWheelZ>;\r\n\r\n    /**\r\n     * Pointer Event ID\r\n     */\r\n    pointerId: number;\r\n\r\n    /**\r\n     * Type of pointer\r\n     */\r\n    pointerType: string;\r\n}\r\n\r\n/**\r\n * Native friendly interface for WheelEvent Object\r\n */\r\nexport interface IWheelEvent extends IMouseEvent {\r\n    /**\r\n     * Subset of possible PointerInput values for events that can only be used with mouse wheel\r\n     */\r\n    inputIndex: PointerInput.MouseWheelX | PointerInput.MouseWheelY | PointerInput.MouseWheelZ;\r\n\r\n    /**\r\n     * Units for delta value\r\n     */\r\n    deltaMode: number;\r\n\r\n    /**\r\n     * Horizontal scroll delta\r\n     */\r\n    deltaX: number;\r\n\r\n    /**\r\n     * Vertical scroll delta\r\n     */\r\n    deltaY: number;\r\n\r\n    /**\r\n     * Z-Axis scroll delta\r\n     */\r\n    deltaZ: number;\r\n\r\n    /**\r\n     * WheelDelta (From MouseWheel Event)\r\n     * @deprecated\r\n     */\r\n    wheelDelta?: number;\r\n}\r\n\r\n/**\r\n * Constants used for Events\r\n */\r\nexport class EventConstants {\r\n    /**\r\n     * Pixel delta for Wheel Events (Default)\r\n     */\r\n    public static DOM_DELTA_PIXEL = 0x00;\r\n\r\n    /**\r\n     * Line delta for Wheel Events\r\n     */\r\n    public static DOM_DELTA_LINE = 0x01;\r\n\r\n    /**\r\n     * Page delta for Wheel Events\r\n     */\r\n    public static DOM_DELTA_PAGE = 0x02;\r\n}\r\n","import { Constants } from \"../Engines/constants\";\r\nimport { type IUIEvent, EventConstants } from \"../Events/deviceInputEvents\";\r\nimport { type Nullable } from \"../types\";\r\nimport { DeviceType, NativePointerInput, PointerInput } from \"./InputDevices/deviceEnums\";\r\nimport { type IDeviceInputSystem } from \"./inputInterfaces\";\r\n\r\n/**\r\n * Class to wrap DeviceInputSystem data into an event object\r\n */\r\nexport class DeviceEventFactory {\r\n    /**\r\n     * Create device input events based on provided type and slot\r\n     *\r\n     * @param deviceType Type of device\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     * @param currentState Current value for given input\r\n     * @param deviceInputSystem Reference to DeviceInputSystem\r\n     * @param elementToAttachTo HTMLElement to reference as target for inputs\r\n     * @param pointerId PointerId to use for pointer events\r\n     * @returns IUIEvent object\r\n     */\r\n    public static CreateDeviceEvent(\r\n        deviceType: DeviceType,\r\n        deviceSlot: number,\r\n        inputIndex: number,\r\n        currentState: Nullable<number>,\r\n        deviceInputSystem: IDeviceInputSystem,\r\n        elementToAttachTo?: any,\r\n        pointerId?: number\r\n    ): IUIEvent {\r\n        switch (deviceType) {\r\n            case DeviceType.Keyboard:\r\n                return this._CreateKeyboardEvent(inputIndex, currentState, deviceInputSystem, elementToAttachTo);\r\n            case DeviceType.Mouse:\r\n                if (inputIndex === PointerInput.MouseWheelX || inputIndex === PointerInput.MouseWheelY || inputIndex === PointerInput.MouseWheelZ) {\r\n                    return this._CreateWheelEvent(deviceType, deviceSlot, inputIndex, currentState, deviceInputSystem, elementToAttachTo);\r\n                }\r\n            // eslint-disable-next-line no-fallthrough\r\n            case DeviceType.Touch:\r\n                return this._CreatePointerEvent(deviceType, deviceSlot, inputIndex, currentState, deviceInputSystem, elementToAttachTo, pointerId);\r\n            default:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw `Unable to generate event for device ${DeviceType[deviceType]}`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates pointer event\r\n     *\r\n     * @param deviceType Type of device\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     * @param currentState Current value for given input\r\n     * @param deviceInputSystem Reference to DeviceInputSystem\r\n     * @param elementToAttachTo HTMLElement to reference as target for inputs\r\n     * @param pointerId PointerId to use for pointer events\r\n     * @returns IUIEvent object (Pointer)\r\n     */\r\n    private static _CreatePointerEvent(\r\n        deviceType: DeviceType,\r\n        deviceSlot: number,\r\n        inputIndex: number,\r\n        currentState: Nullable<number>,\r\n        deviceInputSystem: IDeviceInputSystem,\r\n        elementToAttachTo?: any,\r\n        pointerId?: number\r\n    ): any {\r\n        const evt = this._CreateMouseEvent(deviceType, deviceSlot, inputIndex, currentState, deviceInputSystem, elementToAttachTo);\r\n\r\n        if (deviceType === DeviceType.Mouse) {\r\n            evt.deviceType = DeviceType.Mouse;\r\n            evt.pointerId = 1;\r\n            evt.pointerType = \"mouse\";\r\n        } else {\r\n            evt.deviceType = DeviceType.Touch;\r\n            evt.pointerId = pointerId ?? deviceSlot;\r\n            evt.pointerType = \"touch\";\r\n        }\r\n\r\n        let buttons = 0;\r\n\r\n        // Populate buttons property with current state of all mouse buttons\r\n        // Uses values found on: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons\r\n        buttons += deviceInputSystem.pollInput(deviceType, deviceSlot, PointerInput.LeftClick);\r\n        buttons += deviceInputSystem.pollInput(deviceType, deviceSlot, PointerInput.RightClick) * 2;\r\n        buttons += deviceInputSystem.pollInput(deviceType, deviceSlot, PointerInput.MiddleClick) * 4;\r\n        evt.buttons = buttons;\r\n\r\n        if (inputIndex === PointerInput.Move) {\r\n            evt.type = \"pointermove\";\r\n        } else if (inputIndex >= PointerInput.LeftClick && inputIndex <= PointerInput.RightClick) {\r\n            evt.type = currentState === 1 ? \"pointerdown\" : \"pointerup\";\r\n            evt.button = inputIndex - 2;\r\n        }\r\n\r\n        return evt;\r\n    }\r\n\r\n    /**\r\n     * Create Mouse Wheel Event\r\n     * @param deviceType Type of device\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     * @param currentState Current value for given input\r\n     * @param deviceInputSystem Reference to DeviceInputSystem\r\n     * @param elementToAttachTo HTMLElement to reference as target for inputs\r\n     * @returns IUIEvent object (Wheel)\r\n     */\r\n    private static _CreateWheelEvent(\r\n        deviceType: DeviceType,\r\n        deviceSlot: number,\r\n        inputIndex: number,\r\n        currentState: Nullable<number>,\r\n        deviceInputSystem: IDeviceInputSystem,\r\n        elementToAttachTo: any\r\n    ): any {\r\n        const evt = this._CreateMouseEvent(deviceType, deviceSlot, inputIndex, currentState, deviceInputSystem, elementToAttachTo);\r\n\r\n        // While WheelEvents don't generally have a pointerId, we used to add one in the InputManager\r\n        // This line has been added to make the InputManager more platform-agnostic\r\n        // Similar code exists in the WebDeviceInputSystem to handle browser created events\r\n        evt.pointerId = 1;\r\n        evt.type = \"wheel\";\r\n        evt.deltaMode = EventConstants.DOM_DELTA_PIXEL;\r\n        evt.deltaX = 0;\r\n        evt.deltaY = 0;\r\n        evt.deltaZ = 0;\r\n\r\n        switch (inputIndex) {\r\n            case PointerInput.MouseWheelX:\r\n                evt.deltaX = currentState;\r\n                break;\r\n            case PointerInput.MouseWheelY:\r\n                evt.deltaY = currentState;\r\n                break;\r\n            case PointerInput.MouseWheelZ:\r\n                evt.deltaZ = currentState;\r\n                break;\r\n        }\r\n\r\n        return evt;\r\n    }\r\n\r\n    /**\r\n     * Create Mouse Event\r\n     * @param deviceType Type of device\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     * @param currentState Current value for given input\r\n     * @param deviceInputSystem Reference to DeviceInputSystem\r\n     * @param elementToAttachTo HTMLElement to reference as target for inputs\r\n     * @returns IUIEvent object (Mouse)\r\n     */\r\n    private static _CreateMouseEvent(\r\n        deviceType: DeviceType,\r\n        deviceSlot: number,\r\n        inputIndex: number,\r\n        currentState: Nullable<number>,\r\n        deviceInputSystem: IDeviceInputSystem,\r\n        elementToAttachTo?: any\r\n    ): any {\r\n        const evt = this._CreateEvent(elementToAttachTo);\r\n        const pointerX = deviceInputSystem.pollInput(deviceType, deviceSlot, PointerInput.Horizontal);\r\n        const pointerY = deviceInputSystem.pollInput(deviceType, deviceSlot, PointerInput.Vertical);\r\n\r\n        // Handle offsets/deltas based on existence of HTMLElement\r\n        if (elementToAttachTo) {\r\n            evt.movementX = 0;\r\n            evt.movementY = 0;\r\n            evt.offsetX = evt.movementX - elementToAttachTo.getBoundingClientRect().x;\r\n            evt.offsetY = evt.movementY - elementToAttachTo.getBoundingClientRect().y;\r\n        } else {\r\n            evt.movementX = deviceInputSystem.pollInput(deviceType, deviceSlot, NativePointerInput.DeltaHorizontal); // DeltaHorizontal\r\n            evt.movementY = deviceInputSystem.pollInput(deviceType, deviceSlot, NativePointerInput.DeltaVertical); // DeltaVertical\r\n            evt.offsetX = 0;\r\n            evt.offsetY = 0;\r\n        }\r\n        this._CheckNonCharacterKeys(evt, deviceInputSystem);\r\n\r\n        evt.clientX = pointerX;\r\n        evt.clientY = pointerY;\r\n        evt.x = pointerX;\r\n        evt.y = pointerY;\r\n\r\n        evt.deviceType = deviceType;\r\n        evt.deviceSlot = deviceSlot;\r\n        evt.inputIndex = inputIndex;\r\n\r\n        return evt;\r\n    }\r\n\r\n    /**\r\n     * Create Keyboard Event\r\n     * @param inputIndex Id of input to be checked\r\n     * @param currentState Current value for given input\r\n     * @param deviceInputSystem Reference to DeviceInputSystem\r\n     * @param elementToAttachTo HTMLElement to reference as target for inputs\r\n     * @returns IEvent object (Keyboard)\r\n     */\r\n    private static _CreateKeyboardEvent(inputIndex: number, currentState: Nullable<number>, deviceInputSystem: IDeviceInputSystem, elementToAttachTo?: any): any {\r\n        const evt = this._CreateEvent(elementToAttachTo);\r\n        this._CheckNonCharacterKeys(evt, deviceInputSystem);\r\n        evt.deviceType = DeviceType.Keyboard;\r\n        evt.deviceSlot = 0;\r\n        evt.inputIndex = inputIndex;\r\n\r\n        evt.type = currentState === 1 ? \"keydown\" : \"keyup\";\r\n        evt.key = String.fromCharCode(inputIndex);\r\n        evt.keyCode = inputIndex;\r\n\r\n        return evt;\r\n    }\r\n\r\n    /**\r\n     * Add parameters for non-character keys (Ctrl, Alt, Meta, Shift)\r\n     * @param evt Event object to add parameters to\r\n     * @param deviceInputSystem DeviceInputSystem to pull values from\r\n     */\r\n    private static _CheckNonCharacterKeys(evt: any, deviceInputSystem: IDeviceInputSystem): void {\r\n        const isKeyboardActive = deviceInputSystem.isDeviceAvailable(DeviceType.Keyboard);\r\n        const altKey = isKeyboardActive && deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_ALT_KEY) === 1;\r\n        const ctrlKey = isKeyboardActive && deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_CTRL_KEY) === 1;\r\n        const metaKey =\r\n            isKeyboardActive &&\r\n            (deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_META_KEY1) === 1 ||\r\n                deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_META_KEY2) === 1 ||\r\n                deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_META_KEY3) === 1);\r\n        const shiftKey = isKeyboardActive && deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_SHIFT_KEY) === 1;\r\n\r\n        evt.altKey = altKey;\r\n        evt.ctrlKey = ctrlKey;\r\n        evt.metaKey = metaKey;\r\n        evt.shiftKey = shiftKey;\r\n    }\r\n\r\n    /**\r\n     * Create base event object\r\n     * @param elementToAttachTo Value to use as event target\r\n     * @returns\r\n     */\r\n    private static _CreateEvent(elementToAttachTo: any): any {\r\n        const evt: { [k: string]: any } = {};\r\n        evt.preventDefault = () => {};\r\n        evt.target = elementToAttachTo;\r\n\r\n        return evt;\r\n    }\r\n}\r\n","import { type INative } from \"../Engines/Native/nativeInterfaces\";\r\nimport { type IUIEvent } from \"../Events/deviceInputEvents\";\r\nimport { DeviceEventFactory } from \"./eventFactory\";\r\nimport { DeviceType } from \"./InputDevices/deviceEnums\";\r\nimport { type IDeviceInputSystem } from \"./inputInterfaces\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const _native: INative;\r\n\r\n/** @internal */\r\nexport class NativeDeviceInputSystem implements IDeviceInputSystem {\r\n    private readonly _nativeInput: IDeviceInputSystem;\r\n\r\n    public constructor(\r\n        onDeviceConnected: (deviceType: DeviceType, deviceSlot: number) => void,\r\n        onDeviceDisconnected: (deviceType: DeviceType, deviceSlot: number) => void,\r\n        onInputChanged: (deviceType: DeviceType, deviceSlot: number, eventData: IUIEvent) => void\r\n    ) {\r\n        this._nativeInput = _native.DeviceInputSystem\r\n            ? new _native.DeviceInputSystem(onDeviceConnected, onDeviceDisconnected, (deviceType, deviceSlot, inputIndex, currentState) => {\r\n                  const evt = DeviceEventFactory.CreateDeviceEvent(deviceType, deviceSlot, inputIndex, currentState, this);\r\n\r\n                  onInputChanged(deviceType, deviceSlot, evt);\r\n              })\r\n            : this._createDummyNativeInput();\r\n    }\r\n\r\n    // Public functions\r\n    /**\r\n     * Checks for current device input value, given an id and input index. Throws exception if requested device not initialized.\r\n     * @param deviceType Enum specifying device type\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     * @returns Current value of input\r\n     */\r\n    public pollInput(deviceType: DeviceType, deviceSlot: number, inputIndex: number): number {\r\n        return this._nativeInput.pollInput(deviceType, deviceSlot, inputIndex);\r\n    }\r\n\r\n    /**\r\n     * Check for a specific device in the DeviceInputSystem\r\n     * @param deviceType Type of device to check for\r\n     * @returns bool with status of device's existence\r\n     */\r\n    public isDeviceAvailable(deviceType: DeviceType): boolean {\r\n        //TODO: FIx native side first\r\n        return deviceType === DeviceType.Mouse || deviceType === DeviceType.Touch;\r\n    }\r\n\r\n    /**\r\n     * Dispose of all the observables\r\n     */\r\n    public dispose(): void {\r\n        this._nativeInput.dispose();\r\n    }\r\n\r\n    /**\r\n     * For versions of BabylonNative that don't have the NativeInput plugin initialized, create a dummy version\r\n     * @returns Object with dummy functions\r\n     */\r\n    private _createDummyNativeInput() {\r\n        const nativeInput = {\r\n            pollInput: () => {\r\n                return 0;\r\n            },\r\n            isDeviceAvailable: () => {\r\n                return false;\r\n            },\r\n            dispose: () => {},\r\n        };\r\n\r\n        return nativeInput;\r\n    }\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type IPointerEvent, type IUIEvent } from \"../Events/deviceInputEvents\";\r\nimport { IsNavigatorAvailable } from \"../Misc/domManagement\";\r\nimport { type Observer } from \"../Misc/observable\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { DeviceEventFactory } from \"./eventFactory\";\r\nimport { DeviceType, PointerInput } from \"./InputDevices/deviceEnums\";\r\nimport { type IDeviceInputSystem } from \"./inputInterfaces\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst MAX_KEYCODES = 255;\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst MAX_POINTER_INPUTS = Object.keys(PointerInput).length / 2;\r\n\r\n/** @internal */\r\nexport class WebDeviceInputSystem implements IDeviceInputSystem {\r\n    // Private Members\r\n    private _inputs: Array<{ [deviceSlot: number]: Array<number> }> = [];\r\n    private _gamepads: Array<DeviceType>;\r\n    private _keyboardActive: boolean = false;\r\n    private _pointerActive: boolean = false;\r\n    private _elementToAttachTo: HTMLElement;\r\n    private _metaKeys: Array<number>;\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _usingSafari: boolean = Tools.IsSafari();\r\n    // Found solution for determining if MacOS is being used here:\r\n    // https://stackoverflow.com/questions/10527983/best-way-to-detect-mac-os-x-or-windows-computers-with-javascript-or-jquery\r\n    private readonly _usingMacOs: boolean = IsNavigatorAvailable() && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);\r\n\r\n    private _onDeviceConnected: (deviceType: DeviceType, deviceSlot: number) => void;\r\n    private _onDeviceDisconnected: (deviceType: DeviceType, deviceSlot: number) => void;\r\n    private _onInputChanged: (deviceType: DeviceType, deviceSlot: number, eventData: IUIEvent) => void;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _keyboardDownEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _keyboardUpEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _keyboardBlurEvent = (evt: any) => {};\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerMoveEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerDownEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerUpEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerCancelEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerCancelTouch = (pointerId: number) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerLeaveEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerWheelEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerBlurEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _pointerMacOsChromeOutEvent = (evt: any) => {};\r\n    private _wheelEventName: string;\r\n    private _eventsAttached: boolean = false;\r\n\r\n    private _mouseId = -1;\r\n    private readonly _isUsingFirefox = IsNavigatorAvailable() && navigator.userAgent && navigator.userAgent.indexOf(\"Firefox\") !== -1;\r\n    private readonly _isUsingChromium = IsNavigatorAvailable() && navigator.userAgent && navigator.userAgent.indexOf(\"Chrome\") !== -1;\r\n\r\n    // Array to store active Pointer ID values; prevents issues with negative pointerIds\r\n    private _activeTouchIds: Array<number>;\r\n    private _maxTouchPoints: number = 0;\r\n\r\n    private _pointerInputClearObserver: Nullable<Observer<AbstractEngine>> = null;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _gamepadConnectedEvent = (evt: any) => {};\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _gamepadDisconnectedEvent = (evt: any) => {};\r\n\r\n    private _eventPrefix: string;\r\n\r\n    /**\r\n     * Constructor for the WebDeviceInputSystem\r\n     * @param engine Engine to reference\r\n     * @param onDeviceConnected Callback to execute when device is connected\r\n     * @param onDeviceDisconnected Callback to execute when device is disconnected\r\n     * @param onInputChanged Callback to execute when input changes on device\r\n     */\r\n    constructor(\r\n        engine: AbstractEngine,\r\n        onDeviceConnected: (deviceType: DeviceType, deviceSlot: number) => void,\r\n        onDeviceDisconnected: (deviceType: DeviceType, deviceSlot: number) => void,\r\n        onInputChanged: (deviceType: DeviceType, deviceSlot: number, eventData: IUIEvent) => void\r\n    ) {\r\n        this._eventPrefix = Tools.GetPointerPrefix(engine);\r\n        this._engine = engine;\r\n\r\n        this._onDeviceConnected = onDeviceConnected;\r\n        this._onDeviceDisconnected = onDeviceDisconnected;\r\n        this._onInputChanged = onInputChanged;\r\n\r\n        // If we need a pointerId, set one for future use\r\n        this._mouseId = this._isUsingFirefox ? 0 : 1;\r\n\r\n        this._enableEvents();\r\n\r\n        if (this._usingMacOs) {\r\n            this._metaKeys = [];\r\n        }\r\n\r\n        // Set callback to enable event handler switching when inputElement changes\r\n        if (!this._engine._onEngineViewChanged) {\r\n            this._engine._onEngineViewChanged = () => {\r\n                this._enableEvents();\r\n            };\r\n        }\r\n    }\r\n\r\n    // Public functions\r\n    /**\r\n     * Checks for current device input value, given an id and input index. Throws exception if requested device not initialized.\r\n     * @param deviceType Enum specifying device type\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     * @returns Current value of input\r\n     */\r\n    public pollInput(deviceType: DeviceType, deviceSlot: number, inputIndex: number): number {\r\n        const device = this._inputs[deviceType][deviceSlot];\r\n\r\n        if (!device) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw `Unable to find device ${DeviceType[deviceType]}`;\r\n        }\r\n\r\n        if (deviceType >= DeviceType.DualShock && deviceType <= DeviceType.DualSense) {\r\n            this._updateDevice(deviceType, deviceSlot, inputIndex);\r\n        }\r\n\r\n        const currentValue = device[inputIndex];\r\n        if (currentValue === undefined) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw `Unable to find input ${inputIndex} for device ${DeviceType[deviceType]} in slot ${deviceSlot}`;\r\n        }\r\n\r\n        if (inputIndex === PointerInput.Move) {\r\n            Tools.Warn(`Unable to provide information for PointerInput.Move.  Try using PointerInput.Horizontal or PointerInput.Vertical for move data.`);\r\n        }\r\n\r\n        return currentValue;\r\n    }\r\n\r\n    /**\r\n     * Check for a specific device in the DeviceInputSystem\r\n     * @param deviceType Type of device to check for\r\n     * @returns bool with status of device's existence\r\n     */\r\n    public isDeviceAvailable(deviceType: DeviceType): boolean {\r\n        return this._inputs[deviceType] !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Dispose of all the eventlisteners\r\n     */\r\n    public dispose(): void {\r\n        // Callbacks\r\n        this._onDeviceConnected = () => {};\r\n        this._onDeviceDisconnected = () => {};\r\n        this._onInputChanged = () => {};\r\n        delete this._engine._onEngineViewChanged;\r\n\r\n        if (this._elementToAttachTo) {\r\n            this._disableEvents();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enable listening for user input events\r\n     */\r\n    private _enableEvents(): void {\r\n        const inputElement = this?._engine.getInputElement();\r\n        if (inputElement && (!this._eventsAttached || this._elementToAttachTo !== inputElement)) {\r\n            // Remove events before adding to avoid double events or simultaneous events on multiple canvases\r\n            this._disableEvents();\r\n\r\n            // If the inputs array has already been created, zero it out to before setting up events\r\n            if (this._inputs) {\r\n                for (const inputs of this._inputs) {\r\n                    if (inputs) {\r\n                        for (const deviceSlotKey in inputs) {\r\n                            const deviceSlot = +deviceSlotKey;\r\n                            const device = inputs[deviceSlot];\r\n                            if (device) {\r\n                                for (let inputIndex = 0; inputIndex < device.length; inputIndex++) {\r\n                                    device[inputIndex] = 0;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this._elementToAttachTo = inputElement;\r\n            // Set tab index for the inputElement to the engine's canvasTabIndex, if and only if the element's tab index is -1\r\n            this._elementToAttachTo.tabIndex = this._elementToAttachTo.tabIndex !== -1 ? this._elementToAttachTo.tabIndex : this._engine.canvasTabIndex;\r\n            this._handleKeyActions();\r\n            this._handlePointerActions();\r\n            this._handleGamepadActions();\r\n            this._eventsAttached = true;\r\n\r\n            // Check for devices that are already connected but aren't registered. Currently, only checks for gamepads and mouse\r\n            this._checkForConnectedDevices();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disable listening for user input events\r\n     */\r\n    private _disableEvents(): void {\r\n        if (this._elementToAttachTo) {\r\n            // Blur Events\r\n            this._elementToAttachTo.removeEventListener(\"blur\", this._keyboardBlurEvent);\r\n            this._elementToAttachTo.removeEventListener(\"blur\", this._pointerBlurEvent);\r\n\r\n            // Keyboard Events\r\n            this._elementToAttachTo.removeEventListener(\"keydown\", this._keyboardDownEvent);\r\n            this._elementToAttachTo.removeEventListener(\"keyup\", this._keyboardUpEvent);\r\n\r\n            // Pointer Events\r\n            this._elementToAttachTo.removeEventListener(this._eventPrefix + \"move\", this._pointerMoveEvent);\r\n            this._elementToAttachTo.removeEventListener(this._eventPrefix + \"down\", this._pointerDownEvent);\r\n            this._elementToAttachTo.removeEventListener(this._eventPrefix + \"up\", this._pointerUpEvent);\r\n            this._elementToAttachTo.removeEventListener(this._eventPrefix + \"cancel\", this._pointerCancelEvent);\r\n            this._elementToAttachTo.removeEventListener(this._eventPrefix + \"leave\", this._pointerLeaveEvent);\r\n            this._elementToAttachTo.removeEventListener(this._wheelEventName, this._pointerWheelEvent);\r\n            if (this._usingMacOs && this._isUsingChromium) {\r\n                this._elementToAttachTo.removeEventListener(\"lostpointercapture\", this._pointerMacOsChromeOutEvent);\r\n            }\r\n\r\n            // Gamepad Events\r\n            window.removeEventListener(\"gamepadconnected\", this._gamepadConnectedEvent);\r\n            window.removeEventListener(\"gamepaddisconnected\", this._gamepadDisconnectedEvent);\r\n        }\r\n\r\n        if (this._pointerInputClearObserver) {\r\n            this._engine.onEndFrameObservable.remove(this._pointerInputClearObserver);\r\n        }\r\n\r\n        this._eventsAttached = false;\r\n    }\r\n\r\n    /**\r\n     * Checks for existing connections to devices and register them, if necessary\r\n     * Currently handles gamepads and mouse\r\n     */\r\n    private _checkForConnectedDevices(): void {\r\n        if (navigator.getGamepads) {\r\n            const gamepads = navigator.getGamepads();\r\n\r\n            for (const gamepad of gamepads) {\r\n                if (gamepad) {\r\n                    this._addGamePad(gamepad);\r\n                }\r\n            }\r\n        }\r\n\r\n        // If the device in use has mouse capabilities, pre-register mouse\r\n        if (typeof matchMedia === \"function\" && matchMedia(\"(pointer:fine)\").matches) {\r\n            // This will provide a dummy value for the cursor position and is expected to be overridden when the first mouse event happens.\r\n            // There isn't any good way to get the current position outside of a pointer event so that's why this was done.\r\n            this._addPointerDevice(DeviceType.Mouse, 0, 0, 0);\r\n        }\r\n    }\r\n\r\n    // Private functions\r\n    /**\r\n     * Add a gamepad to the DeviceInputSystem\r\n     * @param gamepad A single DOM Gamepad object\r\n     */\r\n    private _addGamePad(gamepad: any): void {\r\n        const deviceType = this._getGamepadDeviceType(gamepad.id);\r\n        const deviceSlot = gamepad.index;\r\n\r\n        this._gamepads = this._gamepads || new Array<DeviceType>(gamepad.index + 1);\r\n        this._registerDevice(deviceType, deviceSlot, gamepad.buttons.length + gamepad.axes.length);\r\n\r\n        this._gamepads[deviceSlot] = deviceType;\r\n    }\r\n\r\n    /**\r\n     * Add pointer device to DeviceInputSystem\r\n     * @param deviceType Type of Pointer to add\r\n     * @param deviceSlot Pointer ID (0 for mouse, pointerId for Touch)\r\n     * @param currentX Current X at point of adding\r\n     * @param currentY Current Y at point of adding\r\n     */\r\n    private _addPointerDevice(deviceType: DeviceType, deviceSlot: number, currentX: number, currentY: number): void {\r\n        if (!this._pointerActive) {\r\n            this._pointerActive = true;\r\n        }\r\n        this._registerDevice(deviceType, deviceSlot, MAX_POINTER_INPUTS);\r\n        const pointer = this._inputs[deviceType][deviceSlot]; /* initialize our pointer position immediately after registration */\r\n        pointer[0] = currentX;\r\n        pointer[1] = currentY;\r\n    }\r\n\r\n    /**\r\n     * Add device and inputs to device array\r\n     * @param deviceType Enum specifying device type\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param numberOfInputs Number of input entries to create for given device\r\n     */\r\n    private _registerDevice(deviceType: DeviceType, deviceSlot: number, numberOfInputs: number): void {\r\n        if (deviceSlot === undefined) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw `Unable to register device ${DeviceType[deviceType]} to undefined slot.`;\r\n        }\r\n\r\n        if (!this._inputs[deviceType]) {\r\n            this._inputs[deviceType] = {};\r\n        }\r\n\r\n        if (!this._inputs[deviceType][deviceSlot]) {\r\n            const device = new Array<number>(numberOfInputs);\r\n\r\n            device.fill(0);\r\n\r\n            this._inputs[deviceType][deviceSlot] = device;\r\n            this._onDeviceConnected(deviceType, deviceSlot);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Given a specific device name, remove that device from the device map\r\n     * @param deviceType Enum specifying device type\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     */\r\n    private _unregisterDevice(deviceType: DeviceType, deviceSlot: number): void {\r\n        if (this._inputs[deviceType][deviceSlot]) {\r\n            delete this._inputs[deviceType][deviceSlot];\r\n            this._onDeviceDisconnected(deviceType, deviceSlot);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Handle all actions that come from keyboard interaction\r\n     */\r\n    private _handleKeyActions(): void {\r\n        this._keyboardDownEvent = (evt) => {\r\n            if (!this._keyboardActive) {\r\n                this._keyboardActive = true;\r\n                this._registerDevice(DeviceType.Keyboard, 0, MAX_KEYCODES);\r\n            }\r\n\r\n            const kbKey = this._inputs[DeviceType.Keyboard][0];\r\n            if (kbKey) {\r\n                kbKey[evt.keyCode] = 1;\r\n\r\n                const deviceEvent = evt as IUIEvent;\r\n                deviceEvent.inputIndex = evt.keyCode;\r\n\r\n                if (this._usingMacOs && evt.metaKey && evt.key !== \"Meta\") {\r\n                    if (!this._metaKeys.includes(evt.keyCode)) {\r\n                        this._metaKeys.push(evt.keyCode);\r\n                    }\r\n                }\r\n\r\n                this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\r\n            }\r\n        };\r\n\r\n        this._keyboardUpEvent = (evt) => {\r\n            if (!this._keyboardActive) {\r\n                this._keyboardActive = true;\r\n                this._registerDevice(DeviceType.Keyboard, 0, MAX_KEYCODES);\r\n            }\r\n\r\n            const kbKey = this._inputs[DeviceType.Keyboard][0];\r\n            if (kbKey) {\r\n                kbKey[evt.keyCode] = 0;\r\n\r\n                const deviceEvent = evt as IUIEvent;\r\n                deviceEvent.inputIndex = evt.keyCode;\r\n\r\n                if (this._usingMacOs && evt.key === \"Meta\" && this._metaKeys.length > 0) {\r\n                    for (const keyCode of this._metaKeys) {\r\n                        const deviceEvent: IUIEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Keyboard, 0, keyCode, 0, this, this._elementToAttachTo);\r\n                        kbKey[keyCode] = 0;\r\n                        this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\r\n                    }\r\n                    this._metaKeys.splice(0, this._metaKeys.length);\r\n                }\r\n\r\n                this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\r\n            }\r\n        };\r\n\r\n        this._keyboardBlurEvent = () => {\r\n            if (this._keyboardActive) {\r\n                const kbKey = this._inputs[DeviceType.Keyboard][0];\r\n\r\n                for (let i = 0; i < kbKey.length; i++) {\r\n                    if (kbKey[i] !== 0) {\r\n                        kbKey[i] = 0;\r\n\r\n                        const deviceEvent: IUIEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Keyboard, 0, i, 0, this, this._elementToAttachTo);\r\n\r\n                        this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\r\n                    }\r\n                }\r\n                if (this._usingMacOs) {\r\n                    this._metaKeys.splice(0, this._metaKeys.length);\r\n                }\r\n            }\r\n        };\r\n\r\n        this._elementToAttachTo.addEventListener(\"keydown\", this._keyboardDownEvent);\r\n        this._elementToAttachTo.addEventListener(\"keyup\", this._keyboardUpEvent);\r\n        this._elementToAttachTo.addEventListener(\"blur\", this._keyboardBlurEvent);\r\n    }\r\n\r\n    /**\r\n     * Handle all actions that come from pointer interaction\r\n     */\r\n    private _handlePointerActions(): void {\r\n        // If maxTouchPoints is defined, use that value.  Otherwise, allow for a minimum for supported gestures like pinch\r\n        this._maxTouchPoints = (IsNavigatorAvailable() && navigator.maxTouchPoints) || 2;\r\n        if (!this._activeTouchIds) {\r\n            this._activeTouchIds = new Array<number>(this._maxTouchPoints);\r\n        }\r\n\r\n        for (let i = 0; i < this._maxTouchPoints; i++) {\r\n            this._activeTouchIds[i] = -1;\r\n        }\r\n\r\n        this._pointerMoveEvent = (evt) => {\r\n            const deviceType = this._getPointerType(evt);\r\n            let deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);\r\n\r\n            // In the event that we're getting pointermove events from touch inputs that we aren't tracking,\r\n            // look for an available slot and retroactively connect it.\r\n            if (deviceType === DeviceType.Touch && deviceSlot === -1) {\r\n                // Ignore hover-only touch pointers, which may never receive a pointerup event.\r\n                if (evt.buttons === 0) {\r\n                    return;\r\n                }\r\n\r\n                const idx = this._activeTouchIds.indexOf(-1);\r\n\r\n                if (idx >= 0) {\r\n                    deviceSlot = idx;\r\n                    this._activeTouchIds[idx] = evt.pointerId;\r\n                    // Because this is a \"new\" input, inform the connected callback\r\n                    this._onDeviceConnected(deviceType, deviceSlot);\r\n                } else {\r\n                    // We can't find an open slot to store new pointer so just return (can only support max number of touches)\r\n                    Tools.Warn(`Max number of touches exceeded.  Ignoring touches in excess of ${this._maxTouchPoints}`);\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (!this._inputs[deviceType]) {\r\n                this._inputs[deviceType] = {};\r\n            }\r\n\r\n            if (!this._inputs[deviceType][deviceSlot]) {\r\n                this._addPointerDevice(deviceType, deviceSlot, evt.clientX, evt.clientY);\r\n            }\r\n\r\n            const pointer = this._inputs[deviceType][deviceSlot];\r\n            if (pointer) {\r\n                const deviceEvent = evt as IPointerEvent;\r\n                deviceEvent.inputIndex = PointerInput.Move;\r\n\r\n                pointer[PointerInput.Horizontal] = evt.clientX;\r\n                pointer[PointerInput.Vertical] = evt.clientY;\r\n\r\n                // For touches that aren't started with a down, we need to set the button state to 1\r\n                if (deviceType === DeviceType.Touch && pointer[PointerInput.LeftClick] === 0) {\r\n                    pointer[PointerInput.LeftClick] = 1;\r\n                }\r\n\r\n                if (evt.pointerId === undefined) {\r\n                    evt.pointerId = this._mouseId;\r\n                }\r\n\r\n                this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n\r\n                // Lets Propagate the event for move with same position.\r\n                if (!this._usingSafari && evt.button !== -1) {\r\n                    deviceEvent.inputIndex = evt.button + 2;\r\n                    pointer[evt.button + 2] = pointer[evt.button + 2] ? 0 : 1; // Reverse state of button if evt.button has value\r\n                    this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n                }\r\n            }\r\n        };\r\n\r\n        this._pointerDownEvent = (evt) => {\r\n            const deviceType = this._getPointerType(evt);\r\n            let deviceSlot = deviceType === DeviceType.Mouse ? 0 : evt.pointerId;\r\n\r\n            if (deviceType === DeviceType.Touch) {\r\n                // See if this pointerId is already using an existing slot\r\n                // (possible on some devices which raise the pointerMove event before the pointerDown event, e.g. when using a pen)\r\n                let idx = this._activeTouchIds.indexOf(evt.pointerId);\r\n                if (idx === -1) {\r\n                    // If the pointerId wasn't already using a slot, find an open one\r\n                    idx = this._activeTouchIds.indexOf(-1);\r\n                }\r\n\r\n                if (idx >= 0) {\r\n                    deviceSlot = idx;\r\n                    this._activeTouchIds[idx] = evt.pointerId;\r\n                } else {\r\n                    // We can't find an open slot to store new pointer so just return (can only support max number of touches)\r\n                    Tools.Warn(`Max number of touches exceeded.  Ignoring touches in excess of ${this._maxTouchPoints}`);\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (!this._inputs[deviceType]) {\r\n                this._inputs[deviceType] = {};\r\n            }\r\n\r\n            if (!this._inputs[deviceType][deviceSlot]) {\r\n                this._addPointerDevice(deviceType, deviceSlot, evt.clientX, evt.clientY);\r\n            } else if (deviceType === DeviceType.Touch) {\r\n                this._onDeviceConnected(deviceType, deviceSlot);\r\n            }\r\n\r\n            const pointer = this._inputs[deviceType][deviceSlot];\r\n            if (pointer) {\r\n                const previousHorizontal = pointer[PointerInput.Horizontal];\r\n                const previousVertical = pointer[PointerInput.Vertical];\r\n\r\n                if (deviceType === DeviceType.Mouse) {\r\n                    // Mouse; Set pointerId if undefined\r\n                    if (evt.pointerId === undefined) {\r\n                        evt.pointerId = this._mouseId;\r\n                    }\r\n\r\n                    if (!document.pointerLockElement) {\r\n                        try {\r\n                            this._elementToAttachTo.setPointerCapture(this._mouseId);\r\n                        } catch (e) {\r\n                            // DO NOTHING\r\n                        }\r\n                    }\r\n                } else {\r\n                    // Touch; Since touches are dynamically assigned, only set capture if we have an id\r\n                    if (evt.pointerId && !document.pointerLockElement) {\r\n                        try {\r\n                            this._elementToAttachTo.setPointerCapture(evt.pointerId);\r\n                        } catch (e) {\r\n                            // DO NOTHING\r\n                        }\r\n                    }\r\n                }\r\n\r\n                pointer[PointerInput.Horizontal] = evt.clientX;\r\n                pointer[PointerInput.Vertical] = evt.clientY;\r\n                pointer[evt.button + 2] = 1;\r\n\r\n                const deviceEvent = evt as IUIEvent;\r\n\r\n                // NOTE: The +2 used here to is because PointerInput has the same value progression for its mouse buttons as PointerEvent.button\r\n                // However, we have our X and Y values front-loaded to group together the touch inputs but not break this progression\r\n                // EG. ([X, Y, Left-click], Middle-click, etc...)\r\n                deviceEvent.inputIndex = evt.button + 2;\r\n\r\n                this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n\r\n                if (previousHorizontal !== evt.clientX || previousVertical !== evt.clientY) {\r\n                    deviceEvent.inputIndex = PointerInput.Move;\r\n                    this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n                }\r\n            }\r\n        };\r\n\r\n        this._pointerUpEvent = (evt) => {\r\n            const deviceType = this._getPointerType(evt);\r\n            const deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);\r\n\r\n            if (deviceType === DeviceType.Touch) {\r\n                // If we're getting a pointerup event for a touch that isn't active, just return.\r\n                if (deviceSlot === -1) {\r\n                    return;\r\n                } else {\r\n                    this._activeTouchIds[deviceSlot] = -1;\r\n                }\r\n            }\r\n\r\n            const pointer = this._inputs[deviceType]?.[deviceSlot];\r\n            let button = evt.button;\r\n            let shouldProcessPointerUp = pointer && pointer[button + 2] !== 0;\r\n\r\n            // Workaround for an issue in Firefox on MacOS only where the browser allows the user to change left button\r\n            // actions into right button actions by holding down control. If the user starts a drag with the control button\r\n            // down, then lifts control, then releases the mouse, we'll get mismatched up and down events (the down will be\r\n            // the right button, and the up will be the left button). In that specific case, where we get an up from a button\r\n            // which didn't have a corresponding down, and we are in Firefox on MacOS, we should process the up event as if it\r\n            // was from the other button.\r\n            // Ideally this would be fixed in Firefox so that if you start a drag with the control button down, then the button\r\n            // passed along to both pointer down and up would be the right button regardless of the order in which control and the\r\n            // mouse button were released.\r\n            // If Firefox makes a fix to ensure this is the case, this workaround can be removed.\r\n            // Relevant forum thread: https://forum.babylonjs.com/t/camera-pan-getting-stuck-in-firefox/57158\r\n            if (!shouldProcessPointerUp && this._isUsingFirefox && this._usingMacOs && pointer) {\r\n                // Try the other button (left or right button)\r\n                button = button === 2 ? 0 : 2;\r\n\r\n                shouldProcessPointerUp = pointer[button + 2] !== 0;\r\n            }\r\n\r\n            if (shouldProcessPointerUp) {\r\n                const previousHorizontal = pointer[PointerInput.Horizontal];\r\n                const previousVertical = pointer[PointerInput.Vertical];\r\n\r\n                pointer[PointerInput.Horizontal] = evt.clientX;\r\n                pointer[PointerInput.Vertical] = evt.clientY;\r\n                pointer[button + 2] = 0;\r\n\r\n                const deviceEvent = evt as IUIEvent;\r\n\r\n                if (evt.pointerId === undefined) {\r\n                    evt.pointerId = this._mouseId;\r\n                }\r\n\r\n                if (previousHorizontal !== evt.clientX || previousVertical !== evt.clientY) {\r\n                    deviceEvent.inputIndex = PointerInput.Move;\r\n                    this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n                }\r\n\r\n                // NOTE: The +2 used here to is because PointerInput has the same value progression for its mouse buttons as PointerEvent.button\r\n                // However, we have our X and Y values front-loaded to group together the touch inputs but not break this progression\r\n                // EG. ([X, Y, Left-click], Middle-click, etc...)\r\n                deviceEvent.inputIndex = button + 2;\r\n\r\n                if (deviceType === DeviceType.Mouse && this._mouseId >= 0 && this._elementToAttachTo.hasPointerCapture?.(this._mouseId)) {\r\n                    this._elementToAttachTo.releasePointerCapture(this._mouseId);\r\n                } else if (evt.pointerId && this._elementToAttachTo.hasPointerCapture?.(evt.pointerId)) {\r\n                    this._elementToAttachTo.releasePointerCapture(evt.pointerId);\r\n                }\r\n\r\n                this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n\r\n                if (deviceType === DeviceType.Touch) {\r\n                    this._onDeviceDisconnected(deviceType, deviceSlot);\r\n                }\r\n            }\r\n        };\r\n\r\n        this._pointerCancelTouch = (pointerId: number) => {\r\n            const deviceSlot = this._activeTouchIds.indexOf(pointerId);\r\n\r\n            // If we're getting a pointercancel event for a touch that isn't active, just return\r\n            if (deviceSlot === -1) {\r\n                return;\r\n            }\r\n\r\n            if (this._elementToAttachTo.hasPointerCapture?.(pointerId)) {\r\n                this._elementToAttachTo.releasePointerCapture(pointerId);\r\n            }\r\n\r\n            this._inputs[DeviceType.Touch][deviceSlot][PointerInput.LeftClick] = 0;\r\n\r\n            const deviceEvent: IUIEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Touch, deviceSlot, PointerInput.LeftClick, 0, this, this._elementToAttachTo, pointerId);\r\n\r\n            this._onInputChanged(DeviceType.Touch, deviceSlot, deviceEvent);\r\n\r\n            this._activeTouchIds[deviceSlot] = -1;\r\n            this._onDeviceDisconnected(DeviceType.Touch, deviceSlot);\r\n        };\r\n\r\n        this._pointerCancelEvent = (evt) => {\r\n            if (evt.pointerType === \"mouse\") {\r\n                const pointer = this._inputs[DeviceType.Mouse][0];\r\n\r\n                if (this._mouseId >= 0 && this._elementToAttachTo.hasPointerCapture?.(this._mouseId)) {\r\n                    this._elementToAttachTo.releasePointerCapture(this._mouseId);\r\n                }\r\n\r\n                for (let inputIndex = PointerInput.LeftClick; inputIndex <= PointerInput.BrowserForward; inputIndex++) {\r\n                    if (pointer[inputIndex] === 1) {\r\n                        pointer[inputIndex] = 0;\r\n\r\n                        const deviceEvent: IUIEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Mouse, 0, inputIndex, 0, this, this._elementToAttachTo);\r\n\r\n                        this._onInputChanged(DeviceType.Mouse, 0, deviceEvent);\r\n                    }\r\n                }\r\n            } else {\r\n                this._pointerCancelTouch(evt.pointerId);\r\n            }\r\n        };\r\n\r\n        this._pointerLeaveEvent = (evt) => {\r\n            if (evt.pointerType === \"pen\") {\r\n                // If a pen leaves the hover range detectible by the hardware this event is raised and we need to cancel the operation\r\n                // Note that pen operations are treated as touch operations\r\n                this._pointerCancelTouch(evt.pointerId);\r\n            }\r\n        };\r\n\r\n        // Set Wheel Event Name, code originally from scene.inputManager\r\n        this._wheelEventName =\r\n            \"onwheel\" in document.createElement(\"div\")\r\n                ? \"wheel\" // Modern browsers support \"wheel\"\r\n                : (<any>document).onmousewheel !== undefined\r\n                  ? \"mousewheel\" // Webkit and IE support at least \"mousewheel\"\r\n                  : \"DOMMouseScroll\"; // let's assume that remaining browsers are older Firefox\r\n\r\n        // Code originally in scene.inputManager.ts\r\n        // Chrome reports warning in console if wheel listener doesn't set an explicit passive option.\r\n        // IE11 only supports captureEvent:boolean, not options:object, and it defaults to false.\r\n        // Feature detection technique copied from: https://github.com/github/eventlistener-polyfill (MIT license)\r\n        let passiveSupported = false;\r\n        const noop = function () {};\r\n\r\n        try {\r\n            const options = Object.defineProperty({}, \"passive\", {\r\n                get: function () {\r\n                    passiveSupported = true;\r\n                },\r\n            });\r\n\r\n            this._elementToAttachTo.addEventListener(\"test\", noop, options);\r\n            this._elementToAttachTo.removeEventListener(\"test\", noop, options);\r\n        } catch (e) {\r\n            /* */\r\n        }\r\n\r\n        this._pointerBlurEvent = () => {\r\n            // Handle mouse buttons\r\n            if (this.isDeviceAvailable(DeviceType.Mouse)) {\r\n                const pointer = this._inputs[DeviceType.Mouse][0];\r\n\r\n                if (this._mouseId >= 0 && this._elementToAttachTo.hasPointerCapture?.(this._mouseId)) {\r\n                    this._elementToAttachTo.releasePointerCapture(this._mouseId);\r\n                }\r\n\r\n                for (let inputIndex = PointerInput.LeftClick; inputIndex <= PointerInput.BrowserForward; inputIndex++) {\r\n                    if (pointer[inputIndex] === 1) {\r\n                        pointer[inputIndex] = 0;\r\n\r\n                        const deviceEvent: IUIEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Mouse, 0, inputIndex, 0, this, this._elementToAttachTo);\r\n\r\n                        this._onInputChanged(DeviceType.Mouse, 0, deviceEvent);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Handle Active Touches\r\n            if (this.isDeviceAvailable(DeviceType.Touch)) {\r\n                const pointer = this._inputs[DeviceType.Touch];\r\n\r\n                for (let deviceSlot = 0; deviceSlot < this._activeTouchIds.length; deviceSlot++) {\r\n                    const pointerId = this._activeTouchIds[deviceSlot];\r\n\r\n                    if (this._elementToAttachTo.hasPointerCapture?.(pointerId)) {\r\n                        this._elementToAttachTo.releasePointerCapture(pointerId);\r\n                    }\r\n\r\n                    if (pointerId !== -1 && pointer[deviceSlot]?.[PointerInput.LeftClick] === 1) {\r\n                        pointer[deviceSlot][PointerInput.LeftClick] = 0;\r\n\r\n                        const deviceEvent: IUIEvent = DeviceEventFactory.CreateDeviceEvent(\r\n                            DeviceType.Touch,\r\n                            deviceSlot,\r\n                            PointerInput.LeftClick,\r\n                            0,\r\n                            this,\r\n                            this._elementToAttachTo,\r\n                            pointerId\r\n                        );\r\n\r\n                        this._onInputChanged(DeviceType.Touch, deviceSlot, deviceEvent);\r\n\r\n                        this._activeTouchIds[deviceSlot] = -1;\r\n                        this._onDeviceDisconnected(DeviceType.Touch, deviceSlot);\r\n                    }\r\n                }\r\n            }\r\n        };\r\n\r\n        this._pointerWheelEvent = (evt) => {\r\n            const deviceType = DeviceType.Mouse;\r\n            const deviceSlot = 0;\r\n\r\n            if (!this._inputs[deviceType]) {\r\n                this._inputs[deviceType] = [];\r\n            }\r\n\r\n            if (!this._inputs[deviceType][deviceSlot]) {\r\n                this._pointerActive = true;\r\n                this._registerDevice(deviceType, deviceSlot, MAX_POINTER_INPUTS);\r\n            }\r\n\r\n            const pointer = this._inputs[deviceType][deviceSlot];\r\n            if (pointer) {\r\n                pointer[PointerInput.MouseWheelX] = evt.deltaX || 0;\r\n                pointer[PointerInput.MouseWheelY] = evt.deltaY || evt.wheelDelta || 0;\r\n                pointer[PointerInput.MouseWheelZ] = evt.deltaZ || 0;\r\n\r\n                const deviceEvent = evt as IUIEvent;\r\n                // By default, there is no pointerId for mouse wheel events so we'll add one here\r\n                // This logic was originally in the InputManager but was added here to make the\r\n                // InputManager more platform-agnostic\r\n                if (evt.pointerId === undefined) {\r\n                    evt.pointerId = this._mouseId;\r\n                }\r\n\r\n                if (pointer[PointerInput.MouseWheelX] !== 0) {\r\n                    deviceEvent.inputIndex = PointerInput.MouseWheelX;\r\n                    this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n                }\r\n                if (pointer[PointerInput.MouseWheelY] !== 0) {\r\n                    deviceEvent.inputIndex = PointerInput.MouseWheelY;\r\n                    this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n                }\r\n                if (pointer[PointerInput.MouseWheelZ] !== 0) {\r\n                    deviceEvent.inputIndex = PointerInput.MouseWheelZ;\r\n                    this._onInputChanged(deviceType, deviceSlot, deviceEvent);\r\n                }\r\n            }\r\n        };\r\n\r\n        // Workaround for MacOS Chromium Browsers for lost pointer capture bug\r\n        if (this._usingMacOs && this._isUsingChromium) {\r\n            this._pointerMacOsChromeOutEvent = (evt) => {\r\n                if (evt.buttons > 1) {\r\n                    this._pointerCancelEvent(evt);\r\n                }\r\n            };\r\n            this._elementToAttachTo.addEventListener(\"lostpointercapture\", this._pointerMacOsChromeOutEvent);\r\n        }\r\n\r\n        this._elementToAttachTo.addEventListener(this._eventPrefix + \"move\", this._pointerMoveEvent);\r\n        this._elementToAttachTo.addEventListener(this._eventPrefix + \"down\", this._pointerDownEvent);\r\n        this._elementToAttachTo.addEventListener(this._eventPrefix + \"up\", this._pointerUpEvent);\r\n        this._elementToAttachTo.addEventListener(this._eventPrefix + \"cancel\", this._pointerCancelEvent);\r\n        this._elementToAttachTo.addEventListener(this._eventPrefix + \"leave\", this._pointerLeaveEvent);\r\n        this._elementToAttachTo.addEventListener(\"blur\", this._pointerBlurEvent);\r\n        this._elementToAttachTo.addEventListener(this._wheelEventName, this._pointerWheelEvent, passiveSupported ? { passive: false } : false);\r\n\r\n        // Since there's no up or down event for mouse wheel or delta x/y, clear mouse values at end of frame\r\n        this._pointerInputClearObserver = this._engine.onEndFrameObservable.add(() => {\r\n            if (this.isDeviceAvailable(DeviceType.Mouse)) {\r\n                const pointer = this._inputs[DeviceType.Mouse][0];\r\n                pointer[PointerInput.MouseWheelX] = 0;\r\n                pointer[PointerInput.MouseWheelY] = 0;\r\n                pointer[PointerInput.MouseWheelZ] = 0;\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Handle all actions that come from gamepad interaction\r\n     */\r\n    private _handleGamepadActions(): void {\r\n        this._gamepadConnectedEvent = (evt: any) => {\r\n            this._addGamePad(evt.gamepad);\r\n        };\r\n\r\n        this._gamepadDisconnectedEvent = (evt: any) => {\r\n            if (this._gamepads) {\r\n                const deviceType = this._getGamepadDeviceType(evt.gamepad.id);\r\n                const deviceSlot = evt.gamepad.index;\r\n\r\n                this._unregisterDevice(deviceType, deviceSlot);\r\n                delete this._gamepads[deviceSlot];\r\n            }\r\n        };\r\n\r\n        window.addEventListener(\"gamepadconnected\", this._gamepadConnectedEvent);\r\n        window.addEventListener(\"gamepaddisconnected\", this._gamepadDisconnectedEvent);\r\n    }\r\n\r\n    /**\r\n     * Update all non-event based devices with each frame\r\n     * @param deviceType Enum specifying device type\r\n     * @param deviceSlot \"Slot\" or index that device is referenced in\r\n     * @param inputIndex Id of input to be checked\r\n     */\r\n    private _updateDevice(deviceType: DeviceType, deviceSlot: number, inputIndex: number): void {\r\n        // Gamepads\r\n        const gp = navigator.getGamepads()[deviceSlot];\r\n\r\n        if (gp && deviceType === this._gamepads[deviceSlot]) {\r\n            const device = this._inputs[deviceType][deviceSlot];\r\n\r\n            if (inputIndex >= gp.buttons.length) {\r\n                device[inputIndex] = gp.axes[inputIndex - gp.buttons.length].valueOf();\r\n            } else {\r\n                device[inputIndex] = gp.buttons[inputIndex].value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets DeviceType from the device name\r\n     * @param deviceName Name of Device from DeviceInputSystem\r\n     * @returns DeviceType enum value\r\n     */\r\n    private _getGamepadDeviceType(deviceName: string): DeviceType {\r\n        if (deviceName.indexOf(\"054c\") !== -1) {\r\n            // DualShock 4 Gamepad\r\n            return deviceName.indexOf(\"0ce6\") !== -1 ? DeviceType.DualSense : DeviceType.DualShock;\r\n        } else if (\r\n            deviceName.indexOf(\"Xbox One\") !== -1 ||\r\n            deviceName.search(\"Xbox 360\") !== -1 ||\r\n            deviceName.search(\"xinput\") !== -1 ||\r\n            // Microsoft vendor id covers Xbox Series/One/Elite controllers reported with various names\r\n            // (e.g. \"Xbox Wireless Controller (... Vendor: 045e Product: 0b13)\"). Excludes the\r\n            // Surface Dock Extender, which also reports vendor 045e. Mirrors GamepadManager.\r\n            (deviceName.indexOf(\"045e\") !== -1 && deviceName.indexOf(\"Surface Dock\") === -1)\r\n        ) {\r\n            // Xbox Gamepad\r\n            return DeviceType.Xbox;\r\n        } else if (deviceName.indexOf(\"057e\") !== -1) {\r\n            // Switch Gamepad\r\n            return DeviceType.Switch;\r\n        }\r\n\r\n        return DeviceType.Generic;\r\n    }\r\n\r\n    /**\r\n     * Get DeviceType from a given pointer/mouse/touch event.\r\n     * @param evt PointerEvent to evaluate\r\n     * @returns DeviceType interpreted from event\r\n     */\r\n    private _getPointerType(evt: any): DeviceType {\r\n        let deviceType = DeviceType.Mouse;\r\n\r\n        if (evt.pointerType === \"touch\" || evt.pointerType === \"pen\" || evt.touches) {\r\n            deviceType = DeviceType.Touch;\r\n        }\r\n\r\n        return deviceType;\r\n    }\r\n}\r\n","import { type DeviceType } from \"./deviceEnums\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { type DeviceInput } from \"./deviceTypes\";\r\nimport { type IDeviceInputSystem } from \"../inputInterfaces\";\r\nimport { type IKeyboardEvent, type IPointerEvent, type IWheelEvent } from \"../../Events/deviceInputEvents\";\r\n\r\n/**\r\n * Subset of DeviceInput that only handles pointers and keyboard\r\n */\r\nexport type DeviceSourceEvent<T extends DeviceType> = T extends DeviceType.Keyboard\r\n    ? IKeyboardEvent\r\n    : T extends DeviceType.Mouse\r\n      ? IWheelEvent | IPointerEvent\r\n      : T extends DeviceType.Touch\r\n        ? IPointerEvent\r\n        : never;\r\n\r\n/**\r\n * Class that handles all input for a specific device\r\n */\r\nexport class DeviceSource<T extends DeviceType> {\r\n    // Public Members\r\n    /**\r\n     * Observable to handle device input changes per device\r\n     */\r\n    public readonly onInputChangedObservable = new Observable<DeviceSourceEvent<T>>();\r\n\r\n    // Private Members\r\n    private readonly _deviceInputSystem: IDeviceInputSystem;\r\n\r\n    /**\r\n     * Default Constructor\r\n     * @param deviceInputSystem - Reference to DeviceInputSystem\r\n     * @param deviceType - Type of device\r\n     * @param deviceSlot - \"Slot\" or index that device is referenced in\r\n     */\r\n    constructor(\r\n        deviceInputSystem: IDeviceInputSystem,\r\n        /** Type of device */\r\n        public readonly deviceType: T,\r\n        /** [0] \"Slot\" or index that device is referenced in */\r\n        public readonly deviceSlot: number = 0\r\n    ) {\r\n        this._deviceInputSystem = deviceInputSystem;\r\n    }\r\n\r\n    /**\r\n     * Get input for specific input\r\n     * @param inputIndex - index of specific input on device\r\n     * @returns Input value from DeviceInputSystem\r\n     */\r\n    public getInput(inputIndex: DeviceInput<T>): number {\r\n        return this._deviceInputSystem.pollInput(this.deviceType, this.deviceSlot, inputIndex);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IDisposable } from \"../scene.pure\";\r\nimport { DeviceType } from \"./InputDevices/deviceEnums\";\r\nimport { type Observable } from \"../Misc/observable.pure\";\r\nimport { type IDeviceInputSystem } from \"./inputInterfaces\";\r\nimport { NativeDeviceInputSystem } from \"./nativeDeviceInputSystem\";\r\nimport { WebDeviceInputSystem } from \"./webDeviceInputSystem\";\r\nimport { DeviceSource } from \"./InputDevices/deviceSource\";\r\nimport { type INative } from \"../Engines/Native/nativeInterfaces\";\r\nimport { type IUIEvent } from \"../Events/deviceInputEvents\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\n\r\ntype Distribute<T> = T extends DeviceType ? DeviceSource<T> : never;\r\n\r\nexport type DeviceSourceType = Distribute<DeviceType>;\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const _native: INative;\r\n\r\n/** @internal */\r\nexport interface IObservableManager {\r\n    onDeviceConnectedObservable: Observable<DeviceSourceType>;\r\n    onDeviceDisconnectedObservable: Observable<DeviceSourceType>;\r\n\r\n    // Functions\r\n    _onInputChanged(deviceType: DeviceType, deviceSlot: number, eventData: IUIEvent): void;\r\n    _addDevice(deviceSource: DeviceSource<DeviceType>): void;\r\n    _removeDevice(deviceType: DeviceType, deviceSlot: number): void;\r\n}\r\n\r\n/** @internal */\r\nexport class InternalDeviceSourceManager implements IDisposable {\r\n    // Public Members\r\n    public readonly _deviceInputSystem: IDeviceInputSystem;\r\n\r\n    // Private Members\r\n    // This is a master list of all device type/slot combos\r\n    private readonly _devices: Array<Array<number>>;\r\n\r\n    private readonly _registeredManagers = new Array<IObservableManager>();\r\n\r\n    public _refCount = 0;\r\n\r\n    public constructor(engine: AbstractEngine) {\r\n        const numberOfDeviceTypes = Object.keys(DeviceType).length / 2;\r\n        this._devices = new Array<Array<number>>(numberOfDeviceTypes);\r\n\r\n        const onDeviceConnected = (deviceType: DeviceType, deviceSlot: number) => {\r\n            if (!this._devices[deviceType]) {\r\n                this._devices[deviceType] = new Array<number>();\r\n            }\r\n\r\n            if (!this._devices[deviceType][deviceSlot]) {\r\n                this._devices[deviceType][deviceSlot] = deviceSlot;\r\n            }\r\n            for (const manager of this._registeredManagers) {\r\n                const deviceSource = new DeviceSource(this._deviceInputSystem, deviceType, deviceSlot);\r\n                manager._addDevice(deviceSource);\r\n            }\r\n        };\r\n\r\n        const onDeviceDisconnected = (deviceType: DeviceType, deviceSlot: number) => {\r\n            if (this._devices[deviceType]?.[deviceSlot]) {\r\n                delete this._devices[deviceType][deviceSlot];\r\n            }\r\n            for (const manager of this._registeredManagers) {\r\n                manager._removeDevice(deviceType, deviceSlot);\r\n            }\r\n        };\r\n\r\n        const onInputChanged = (deviceType: DeviceType, deviceSlot: number, eventData: IUIEvent) => {\r\n            if (eventData) {\r\n                for (const manager of this._registeredManagers) {\r\n                    manager._onInputChanged(deviceType, deviceSlot, eventData);\r\n                }\r\n            }\r\n        };\r\n\r\n        if (typeof _native !== \"undefined\") {\r\n            this._deviceInputSystem = new NativeDeviceInputSystem(onDeviceConnected, onDeviceDisconnected, onInputChanged);\r\n        } else {\r\n            this._deviceInputSystem = new WebDeviceInputSystem(engine, onDeviceConnected, onDeviceDisconnected, onInputChanged);\r\n        }\r\n    }\r\n\r\n    // Public Functions\r\n    public readonly registerManager = (manager: IObservableManager): void => {\r\n        for (let deviceType = 0; deviceType < this._devices.length; deviceType++) {\r\n            const device = this._devices[deviceType];\r\n            for (const deviceSlotKey in device) {\r\n                const deviceSlot = +deviceSlotKey;\r\n                manager._addDevice(new DeviceSource(this._deviceInputSystem, deviceType, deviceSlot));\r\n            }\r\n        }\r\n        this._registeredManagers.push(manager);\r\n    };\r\n\r\n    public readonly unregisterManager = (manager: IObservableManager): void => {\r\n        const idx = this._registeredManagers.indexOf(manager);\r\n\r\n        if (idx > -1) {\r\n            this._registeredManagers.splice(idx, 1);\r\n        }\r\n    };\r\n\r\n    public dispose(): void {\r\n        this._deviceInputSystem.dispose();\r\n    }\r\n}\r\n","import { DeviceType } from \"./deviceEnums\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { type DeviceSource } from \"./deviceSource\";\r\nimport { type IObservableManager, type DeviceSourceType, InternalDeviceSourceManager } from \"../internalDeviceSourceManager\";\r\nimport { type IDisposable } from \"../../scene\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type IKeyboardEvent, type IPointerEvent, type IUIEvent, type IWheelEvent } from \"../../Events/deviceInputEvents\";\r\n\r\n/**\r\n * Class to keep track of devices\r\n */\r\nexport class DeviceSourceManager implements IDisposable, IObservableManager {\r\n    // Public Members\r\n    /**\r\n     * Observable to be triggered when after a device is connected, any new observers added will be triggered against already connected devices\r\n     */\r\n    public readonly onDeviceConnectedObservable: Observable<DeviceSourceType>;\r\n\r\n    /**\r\n     * Observable to be triggered when after a device is disconnected\r\n     */\r\n    public readonly onDeviceDisconnectedObservable: Observable<DeviceSourceType>;\r\n\r\n    // Private Members\r\n    private _engine: AbstractEngine;\r\n    private _onDisposeObserver: Nullable<Observer<AbstractEngine>>;\r\n    private readonly _devices: Array<Array<DeviceSource<DeviceType>>>;\r\n    private readonly _firstDevice: Array<number>;\r\n\r\n    // Public Functions\r\n    /**\r\n     * Gets a DeviceSource, given a type and slot\r\n     * @param deviceType - Type of Device\r\n     * @param deviceSlot - Slot or ID of device\r\n     * @returns DeviceSource\r\n     */\r\n    public getDeviceSource<T extends DeviceType>(deviceType: T, deviceSlot?: number): Nullable<DeviceSource<T>> {\r\n        if (deviceSlot === undefined) {\r\n            if (this._firstDevice[deviceType] === undefined) {\r\n                return null;\r\n            }\r\n\r\n            deviceSlot = this._firstDevice[deviceType];\r\n        }\r\n\r\n        if (!this._devices[deviceType] || this._devices[deviceType][deviceSlot] === undefined) {\r\n            return null;\r\n        }\r\n\r\n        return this._devices[deviceType][deviceSlot] as DeviceSource<T>;\r\n    }\r\n    /**\r\n     * Gets an array of DeviceSource objects for a given device type\r\n     * @param deviceType - Type of Device\r\n     * @returns All available DeviceSources of a given type\r\n     */\r\n    public getDeviceSources<T extends DeviceType>(deviceType: T): ReadonlyArray<DeviceSource<T>> {\r\n        // If device type hasn't had any devices connected yet, return empty array.\r\n        if (!this._devices[deviceType]) {\r\n            return [];\r\n        }\r\n        return this._devices[deviceType].filter((source) => {\r\n            return !!source;\r\n        }) as Array<DeviceSource<T>>;\r\n    }\r\n\r\n    /**\r\n     * Default constructor\r\n     * @param engine - Used to get canvas (if applicable)\r\n     */\r\n    constructor(engine: AbstractEngine) {\r\n        const numberOfDeviceTypes = Object.keys(DeviceType).length / 2;\r\n        this._devices = new Array(numberOfDeviceTypes);\r\n        this._firstDevice = new Array(numberOfDeviceTypes);\r\n        this._engine = engine;\r\n\r\n        if (!this._engine._deviceSourceManager) {\r\n            this._engine._deviceSourceManager = new InternalDeviceSourceManager(engine);\r\n        }\r\n        this._engine._deviceSourceManager._refCount++;\r\n\r\n        // Observables\r\n        this.onDeviceConnectedObservable = new Observable((observer) => {\r\n            for (const devices of this._devices) {\r\n                if (devices) {\r\n                    for (const device of devices) {\r\n                        if (device) {\r\n                            this.onDeviceConnectedObservable.notifyObserver(observer, device as DeviceSourceType);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        });\r\n        this.onDeviceDisconnectedObservable = new Observable();\r\n\r\n        this._engine._deviceSourceManager.registerManager(this);\r\n\r\n        this._onDisposeObserver = engine.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Dispose of DeviceSourceManager\r\n     */\r\n    public dispose(): void {\r\n        // Null out observable refs\r\n        this.onDeviceConnectedObservable.clear();\r\n        this.onDeviceDisconnectedObservable.clear();\r\n\r\n        if (this._engine._deviceSourceManager) {\r\n            this._engine._deviceSourceManager.unregisterManager(this);\r\n            if (--this._engine._deviceSourceManager._refCount < 1) {\r\n                this._engine._deviceSourceManager.dispose();\r\n                delete this._engine._deviceSourceManager;\r\n            }\r\n        }\r\n        this._engine.onDisposeObservable.remove(this._onDisposeObserver);\r\n    }\r\n\r\n    // Hidden Functions\r\n    /**\r\n     * @param deviceSource - Source to add\r\n     * @internal\r\n     */\r\n    public _addDevice(deviceSource: DeviceSourceType): void {\r\n        if (!this._devices[deviceSource.deviceType]) {\r\n            this._devices[deviceSource.deviceType] = [];\r\n        }\r\n\r\n        if (!this._devices[deviceSource.deviceType][deviceSource.deviceSlot]) {\r\n            this._devices[deviceSource.deviceType][deviceSource.deviceSlot] = deviceSource;\r\n            this._updateFirstDevices(deviceSource.deviceType);\r\n        }\r\n\r\n        this.onDeviceConnectedObservable.notifyObservers(deviceSource);\r\n    }\r\n\r\n    /**\r\n     * @param deviceType - DeviceType\r\n     * @param deviceSlot - DeviceSlot\r\n     * @internal\r\n     */\r\n    public _removeDevice(deviceType: DeviceType, deviceSlot: number): void {\r\n        const deviceSource = this._devices[deviceType]?.[deviceSlot]; // Grab local reference to use before removing from devices\r\n        this.onDeviceDisconnectedObservable.notifyObservers(deviceSource as DeviceSourceType);\r\n        if (this._devices[deviceType]?.[deviceSlot]) {\r\n            delete this._devices[deviceType][deviceSlot];\r\n        }\r\n        // Even if we don't delete a device, we should still check for the first device as things may have gotten out of sync.\r\n        this._updateFirstDevices(deviceType);\r\n    }\r\n\r\n    /**\r\n     * @param deviceType - DeviceType\r\n     * @param deviceSlot - DeviceSlot\r\n     * @param eventData - Event\r\n     * @internal\r\n     */\r\n    public _onInputChanged<T extends DeviceType>(deviceType: T, deviceSlot: number, eventData: IUIEvent): void {\r\n        this._devices[deviceType]?.[deviceSlot]?.onInputChangedObservable.notifyObservers(eventData as IKeyboardEvent | IWheelEvent | IPointerEvent);\r\n    }\r\n\r\n    // Private Functions\r\n    private _updateFirstDevices(type: DeviceType): void {\r\n        switch (type) {\r\n            case DeviceType.Keyboard:\r\n            case DeviceType.Mouse:\r\n                this._firstDevice[type] = 0;\r\n                break;\r\n            case DeviceType.Touch:\r\n            case DeviceType.DualSense:\r\n            case DeviceType.DualShock:\r\n            case DeviceType.Xbox:\r\n            case DeviceType.Switch:\r\n            case DeviceType.Generic: {\r\n                delete this._firstDevice[type];\r\n                // eslint-disable-next-line no-case-declarations\r\n                const devices = this._devices[type];\r\n                if (devices) {\r\n                    for (let i = 0; i < devices.length; i++) {\r\n                        if (devices[i]) {\r\n                            this._firstDevice[type] = i;\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type EventState, type Observable, type Observer } from \"../Misc/observable\";\r\nimport { PointerInfoPre, PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type Nullable } from \"../types\";\r\nimport { AbstractActionManager } from \"../Actions/abstractActionManager\";\r\nimport { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { Vector2, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { ActionEvent } from \"../Actions/actionEvent\";\r\nimport { KeyboardEventTypes, KeyboardInfoPre, KeyboardInfo } from \"../Events/keyboardEvents\";\r\nimport { DeviceType, PointerInput } from \"../DeviceInput/InputDevices/deviceEnums\";\r\nimport { type IKeyboardEvent, type IMouseEvent, type IPointerEvent } from \"../Events/deviceInputEvents\";\r\nimport { DeviceSourceManager } from \"../DeviceInput/InputDevices/deviceSourceManager\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\nimport { type Scene } from \"../scene\";\r\nimport { _ImportHelper } from \"core/import.helper\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nclass _ClickInfo {\r\n    private _singleClick = false;\r\n    private _doubleClick = false;\r\n    private _hasSwiped = false;\r\n    private _ignore = false;\r\n\r\n    public get singleClick(): boolean {\r\n        return this._singleClick;\r\n    }\r\n    public get doubleClick(): boolean {\r\n        return this._doubleClick;\r\n    }\r\n    public get hasSwiped(): boolean {\r\n        return this._hasSwiped;\r\n    }\r\n    public get ignore(): boolean {\r\n        return this._ignore;\r\n    }\r\n\r\n    public set singleClick(b: boolean) {\r\n        this._singleClick = b;\r\n    }\r\n    public set doubleClick(b: boolean) {\r\n        this._doubleClick = b;\r\n    }\r\n    public set hasSwiped(b: boolean) {\r\n        this._hasSwiped = b;\r\n    }\r\n    public set ignore(b: boolean) {\r\n        this._ignore = b;\r\n    }\r\n}\r\n\r\n/** @internal */\r\ninterface _IClickEvent {\r\n    clickInfo: _ClickInfo;\r\n    evt: IPointerEvent;\r\n    timeoutId: number;\r\n}\r\n\r\n/**\r\n * Class used to manage all inputs for the scene.\r\n */\r\nexport class InputManager {\r\n    /** The distance in pixel that you have to move to prevent some events */\r\n    public static DragMovementThreshold = 10; // in pixels\r\n    /** Time in milliseconds to wait to raise long press events if button is still pressed */\r\n    public static LongPressDelay = 500; // in milliseconds\r\n    /** Time in milliseconds with two consecutive clicks will be considered as a double click */\r\n    public static DoubleClickDelay = 300; // in milliseconds\r\n    /**\r\n     * This flag will modify the behavior so that, when true, a click will happen if and only if\r\n     * another click DOES NOT happen within the DoubleClickDelay time frame.  If another click does\r\n     * happen within that time frame, the first click will not fire an event and and a double click will occur.\r\n     */\r\n    public static ExclusiveDoubleClickMode = false;\r\n\r\n    /** This is a defensive check to not allow control attachment prior to an already active one. If already attached, previous control is unattached before attaching the new one. */\r\n    private _alreadyAttached = false;\r\n    private _alreadyAttachedTo: Nullable<HTMLElement>;\r\n\r\n    // Pointers\r\n    private _onPointerMove: (evt: IMouseEvent) => void;\r\n    private _onPointerDown: (evt: IPointerEvent) => void;\r\n    private _onPointerUp: (evt: IPointerEvent) => void;\r\n\r\n    private _initClickEvent: (\r\n        obs1: Observable<PointerInfoPre>,\r\n        obs2: Observable<PointerInfo>,\r\n        evt: IPointerEvent,\r\n        cb: (clickInfo: _ClickInfo, pickResult: Nullable<PickingInfo>) => void\r\n    ) => void;\r\n    private _initActionManager: (act: Nullable<AbstractActionManager>, clickInfo: _ClickInfo) => Nullable<AbstractActionManager>;\r\n    private _delayedSimpleClick: (btn: number, clickInfo: _ClickInfo, cb: (clickInfo: _ClickInfo, pickResult: Nullable<PickingInfo>) => void) => void;\r\n    private _meshPickProceed = false;\r\n\r\n    private _previousButtonPressed: number;\r\n    private _currentPickResult: Nullable<PickingInfo> = null;\r\n    private _previousPickResult: Nullable<PickingInfo> = null;\r\n\r\n    private _activePointerIds: Array<number> = new Array<number>();\r\n    /** Tracks the count of used slots in _activePointerIds for perf */\r\n    private _activePointerIdsCount: number = 0;\r\n\r\n    private _doubleClickOccured = false;\r\n    private _isSwiping: boolean = false;\r\n    private _swipeButtonPressed: number = -1;\r\n    private _skipPointerTap: boolean = false;\r\n    private _isMultiTouchGesture: boolean = false;\r\n\r\n    private _pointerOverMesh: Nullable<AbstractMesh>;\r\n\r\n    private _pickedDownMesh: Nullable<AbstractMesh>;\r\n    private _pickedUpMesh: Nullable<AbstractMesh>;\r\n\r\n    private _pointerX: number = 0;\r\n    private _pointerY: number = 0;\r\n    private _unTranslatedPointerX: number;\r\n    private _unTranslatedPointerY: number;\r\n    private _startingPointerPosition = new Vector2(0, 0);\r\n    private _previousStartingPointerPosition = new Vector2(0, 0);\r\n    private _startingPointerTime = 0;\r\n    private _previousStartingPointerTime = 0;\r\n    private _pointerCaptures: { [pointerId: number]: boolean } = {};\r\n    private _meshUnderPointerId: { [pointerId: number]: Nullable<AbstractMesh> } = {};\r\n    private _movePointerInfo: Nullable<PointerInfo> = null;\r\n    private _latestPointerMoveEvents = new Map<number, { event: IPointerEvent; pointerX: number; pointerY: number; unTranslatedPointerX: number; unTranslatedPointerY: number }>();\r\n    private _cameraObserverCount = 0;\r\n    private _delayedClicks: Array<Nullable<_IClickEvent>> = [null, null, null, null, null];\r\n\r\n    // Keyboard\r\n    private _onKeyDown: (evt: IKeyboardEvent) => void;\r\n    private _onKeyUp: (evt: IKeyboardEvent) => void;\r\n\r\n    private _scene: Scene;\r\n    private _deviceSourceManager: Nullable<DeviceSourceManager> = null;\r\n\r\n    // origin MouseEvent\r\n    _originMouseEvent: IMouseEvent;\r\n    /**\r\n     * Creates a new InputManager\r\n     * @param scene - defines the hosting scene\r\n     */\r\n    constructor(scene?: Scene) {\r\n        this._scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh that is currently under the pointer\r\n     * @returns Mesh that the pointer is pointer is hovering over\r\n     */\r\n    public get meshUnderPointer(): Nullable<AbstractMesh> {\r\n        if (this._movePointerInfo) {\r\n            // Because _pointerOverMesh is populated as part of _pickMove, we need to force a pick to update it.\r\n            // Calling _pickMove calls _setCursorAndPointerOverMesh which calls setPointerOverMesh\r\n            this._movePointerInfo._generatePickInfo();\r\n            // Once we have what we need, we can clear _movePointerInfo because we don't need it anymore\r\n            this._movePointerInfo = null;\r\n        }\r\n        return this._pointerOverMesh;\r\n    }\r\n\r\n    /**\r\n     * When using more than one pointer (for example in XR) you can get the mesh under the specific pointer\r\n     * @param pointerId - the pointer id to use\r\n     * @returns The mesh under this pointer id or null if not found\r\n     */\r\n    public getMeshUnderPointerByPointerId(pointerId: number): Nullable<AbstractMesh> {\r\n        return this._meshUnderPointerId[pointerId] || null;\r\n    }\r\n\r\n    /**\r\n     * Gets the pointer coordinates in 2D without any translation (ie. straight out of the pointer event)\r\n     * @returns Vector with X/Y values directly from pointer event\r\n     */\r\n    public get unTranslatedPointer(): Vector2 {\r\n        return new Vector2(this._unTranslatedPointerX, this._unTranslatedPointerY);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current on-screen X position of the pointer\r\n     * @returns Translated X with respect to screen\r\n     */\r\n    public get pointerX(): number {\r\n        return this._pointerX;\r\n    }\r\n\r\n    public set pointerX(value: number) {\r\n        this._pointerX = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current on-screen Y position of the pointer\r\n     * @returns Translated Y with respect to screen\r\n     */\r\n    public get pointerY(): number {\r\n        return this._pointerY;\r\n    }\r\n\r\n    public set pointerY(value: number) {\r\n        this._pointerY = value;\r\n    }\r\n\r\n    private _updatePointerPosition(evt: IPointerEvent): void {\r\n        const canvasRect = this._scene.getEngine().getInputElementClientRect();\r\n\r\n        if (!canvasRect) {\r\n            return;\r\n        }\r\n\r\n        this._pointerX = evt.clientX - canvasRect.left;\r\n        this._pointerY = evt.clientY - canvasRect.top;\r\n\r\n        this._unTranslatedPointerX = this._pointerX;\r\n        this._unTranslatedPointerY = this._pointerY;\r\n    }\r\n\r\n    private _processPointerMove(pickResult: Nullable<PickingInfo>, evt: IPointerEvent) {\r\n        const scene = this._scene;\r\n        const engine = scene.getEngine();\r\n        const canvas = engine.getInputElement();\r\n\r\n        if (canvas) {\r\n            canvas.tabIndex = engine.canvasTabIndex;\r\n\r\n            // Restore pointer\r\n            if (!scene.doNotHandleCursors) {\r\n                canvas.style.cursor = scene.defaultCursor;\r\n            }\r\n        }\r\n\r\n        this._setCursorAndPointerOverMesh(pickResult, evt, scene);\r\n\r\n        for (const step of scene._pointerMoveStage) {\r\n            // If _pointerMoveState is defined, we have an active spriteManager and can't use Lazy Picking\r\n            // Therefore, we need to force a pick to update the pickResult\r\n            pickResult = pickResult || this._pickMove(evt);\r\n            const isMeshPicked = pickResult?.pickedMesh ? true : false;\r\n            pickResult = step.action(this._unTranslatedPointerX, this._unTranslatedPointerY, pickResult, isMeshPicked, canvas);\r\n        }\r\n\r\n        const type = evt.inputIndex >= PointerInput.MouseWheelX && evt.inputIndex <= PointerInput.MouseWheelZ ? PointerEventTypes.POINTERWHEEL : PointerEventTypes.POINTERMOVE;\r\n\r\n        if (scene.onPointerMove) {\r\n            // Because of lazy picking, we need to force a pick to update the pickResult\r\n            pickResult = pickResult || this._pickMove(evt);\r\n            scene.onPointerMove(evt, pickResult, type);\r\n        }\r\n\r\n        let pointerInfo: PointerInfo;\r\n        if (pickResult) {\r\n            pointerInfo = new PointerInfo(type, evt, pickResult);\r\n            this._setRayOnPointerInfo(pickResult, evt);\r\n        } else {\r\n            pointerInfo = new PointerInfo(type, evt, null, this);\r\n            this._movePointerInfo = pointerInfo;\r\n        }\r\n\r\n        if (scene.onPointerObservable.hasObservers()) {\r\n            scene.onPointerObservable.notifyObservers(pointerInfo, type);\r\n        }\r\n    }\r\n\r\n    // Pointers handling\r\n    /** @internal */\r\n    public _setRayOnPointerInfo(pickInfo: Nullable<PickingInfo>, event: IMouseEvent) {\r\n        const scene = this._scene;\r\n        if (pickInfo && _ImportHelper._IsPickingAvailable) {\r\n            if (!pickInfo.ray) {\r\n                pickInfo.ray = scene.createPickingRay(event.offsetX, event.offsetY, Matrix.Identity(), scene.activeCamera);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _addCameraPointerObserver(observer: (p: PointerInfo, s: EventState) => void, mask?: number): Nullable<Observer<PointerInfo>> {\r\n        this._cameraObserverCount++;\r\n        return this._scene.onPointerObservable.add(observer, mask);\r\n    }\r\n\r\n    /** @internal */\r\n    public _removeCameraPointerObserver(observer: Observer<PointerInfo>): boolean {\r\n        this._cameraObserverCount--;\r\n        return this._scene.onPointerObservable.remove(observer);\r\n    }\r\n\r\n    private _checkForPicking(): boolean {\r\n        return !!(this._scene.onPointerObservable.observers.length > this._cameraObserverCount || this._scene.onPointerPick);\r\n    }\r\n\r\n    private _checkPrePointerObservable(pickResult: Nullable<PickingInfo>, evt: IPointerEvent, type: number) {\r\n        const scene = this._scene;\r\n        const pi = new PointerInfoPre(type, evt, this._unTranslatedPointerX, this._unTranslatedPointerY);\r\n        if (pickResult) {\r\n            pi.originalPickingInfo = pickResult;\r\n            pi.ray = pickResult.ray;\r\n            if (evt.pointerType === \"xr-near\" && pickResult.originMesh) {\r\n                pi.nearInteractionPickingInfo = pickResult;\r\n            }\r\n        }\r\n\r\n        scene.onPrePointerObservable.notifyObservers(pi, type);\r\n        if (pi.skipOnPointerObservable) {\r\n            return true;\r\n        } else {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _pickMove(evt: IPointerEvent): PickingInfo {\r\n        const scene = this._scene;\r\n        const pickResult = scene.pick(\r\n            this._unTranslatedPointerX,\r\n            this._unTranslatedPointerY,\r\n            scene.pointerMovePredicate,\r\n            scene.pointerMoveFastCheck,\r\n            scene.cameraToUseForPointers,\r\n            scene.pointerMoveTrianglePredicate\r\n        );\r\n\r\n        this._setCursorAndPointerOverMesh(pickResult, evt, scene);\r\n\r\n        return pickResult;\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateMeshUnderPointer(): void {\r\n        const scene = this._scene;\r\n        if (\r\n            !scene.constantlyUpdateMeshUnderPointer ||\r\n            this._latestPointerMoveEvents.size === 0 ||\r\n            scene.skipPointerMovePicking ||\r\n            (!scene.cameraToUseForPointers && !scene.activeCamera)\r\n        ) {\r\n            return;\r\n        }\r\n        this._ensurePointerMovePredicate();\r\n        const pointerX = this._pointerX;\r\n        const pointerY = this._pointerY;\r\n        const unTranslatedPointerX = this._unTranslatedPointerX;\r\n        const unTranslatedPointerY = this._unTranslatedPointerY;\r\n        for (const pointer of this._latestPointerMoveEvents.values()) {\r\n            this._pointerX = pointer.pointerX;\r\n            this._pointerY = pointer.pointerY;\r\n            this._unTranslatedPointerX = pointer.unTranslatedPointerX;\r\n            this._unTranslatedPointerY = pointer.unTranslatedPointerY;\r\n            this._pickMove(pointer.event);\r\n        }\r\n        this._pointerX = pointerX;\r\n        this._pointerY = pointerY;\r\n        this._unTranslatedPointerX = unTranslatedPointerX;\r\n        this._unTranslatedPointerY = unTranslatedPointerY;\r\n    }\r\n\r\n    private _ensurePointerMovePredicate(): void {\r\n        const scene = this._scene;\r\n        if (!scene.pointerMovePredicate) {\r\n            scene.pointerMovePredicate = (mesh: AbstractMesh): boolean =>\r\n                (mesh._isPointerMovePickable ?? mesh.isPickable) &&\r\n                mesh.isVisible &&\r\n                mesh.isReady() &&\r\n                mesh.isEnabled() &&\r\n                (mesh.enablePointerMoveEvents || scene.constantlyUpdateMeshUnderPointer || mesh._getActionManagerForTrigger() !== null) &&\r\n                (!scene.cameraToUseForPointers || (scene.cameraToUseForPointers.layerMask & mesh.layerMask) !== 0);\r\n        }\r\n    }\r\n\r\n    private _setCursorAndPointerOverMesh(pickResult: Nullable<PickingInfo>, evt: IPointerEvent, scene: Scene) {\r\n        const engine = scene.getEngine();\r\n        const canvas = engine.getInputElement();\r\n\r\n        if (pickResult?.pickedMesh) {\r\n            this.setPointerOverMesh(pickResult.pickedMesh, evt.pointerId, pickResult, evt);\r\n\r\n            if (!scene.doNotHandleCursors && canvas && this._pointerOverMesh) {\r\n                const actionManager = this._pointerOverMesh._getActionManagerForTrigger();\r\n                if (actionManager && actionManager.hasPointerTriggers) {\r\n                    canvas.style.cursor = actionManager.hoverCursor || scene.hoverCursor;\r\n                }\r\n            }\r\n        } else {\r\n            this.setPointerOverMesh(null, evt.pointerId, pickResult, evt);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Use this method to simulate a pointer move on a mesh\r\n     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay\r\n     * @param pickResult - pickingInfo of the object wished to simulate pointer event on\r\n     * @param pointerEventInit - pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)\r\n     */\r\n    public simulatePointerMove(pickResult: PickingInfo, pointerEventInit?: PointerEventInit): void {\r\n        const evt = new PointerEvent(\"pointermove\", pointerEventInit);\r\n        evt.inputIndex = PointerInput.Move;\r\n\r\n        if (this._checkPrePointerObservable(pickResult, evt, PointerEventTypes.POINTERMOVE)) {\r\n            return;\r\n        }\r\n        this._processPointerMove(pickResult, evt);\r\n    }\r\n\r\n    /**\r\n     * Use this method to simulate a pointer down on a mesh\r\n     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay\r\n     * @param pickResult - pickingInfo of the object wished to simulate pointer event on\r\n     * @param pointerEventInit - pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)\r\n     */\r\n    public simulatePointerDown(pickResult: PickingInfo, pointerEventInit?: PointerEventInit): void {\r\n        const evt = new PointerEvent(\"pointerdown\", pointerEventInit);\r\n        evt.inputIndex = evt.button + 2;\r\n\r\n        if (this._checkPrePointerObservable(pickResult, evt, PointerEventTypes.POINTERDOWN)) {\r\n            return;\r\n        }\r\n\r\n        this._processPointerDown(pickResult, evt);\r\n    }\r\n\r\n    private _processPointerDown(pickResult: Nullable<PickingInfo>, evt: IPointerEvent): void {\r\n        const scene = this._scene;\r\n        if (pickResult?.pickedMesh) {\r\n            this._pickedDownMesh = pickResult.pickedMesh;\r\n            const actionManager = pickResult.pickedMesh._getActionManagerForTrigger();\r\n            if (actionManager) {\r\n                if (actionManager.hasPickTriggers) {\r\n                    actionManager.processTrigger(\r\n                        Constants.ACTION_OnPickDownTrigger,\r\n                        new ActionEvent(pickResult.pickedMesh, scene.pointerX, scene.pointerY, pickResult.pickedMesh, evt, pickResult)\r\n                    );\r\n                    switch (evt.button) {\r\n                        case 0:\r\n                            actionManager.processTrigger(\r\n                                Constants.ACTION_OnLeftPickTrigger,\r\n                                new ActionEvent(pickResult.pickedMesh, scene.pointerX, scene.pointerY, pickResult.pickedMesh, evt, pickResult)\r\n                            );\r\n                            break;\r\n                        case 1:\r\n                            actionManager.processTrigger(\r\n                                Constants.ACTION_OnCenterPickTrigger,\r\n                                new ActionEvent(pickResult.pickedMesh, scene.pointerX, scene.pointerY, pickResult.pickedMesh, evt, pickResult)\r\n                            );\r\n                            break;\r\n                        case 2:\r\n                            actionManager.processTrigger(\r\n                                Constants.ACTION_OnRightPickTrigger,\r\n                                new ActionEvent(pickResult.pickedMesh, scene.pointerX, scene.pointerY, pickResult.pickedMesh, evt, pickResult)\r\n                            );\r\n                            break;\r\n                    }\r\n                }\r\n\r\n                if (actionManager.hasSpecificTrigger(Constants.ACTION_OnLongPressTrigger)) {\r\n                    window.setTimeout(() => {\r\n                        const pickResult = scene.pick(\r\n                            this._unTranslatedPointerX,\r\n                            this._unTranslatedPointerY,\r\n                            (mesh: AbstractMesh): boolean =>\r\n                                <boolean>(\r\n                                    (mesh.isPickable &&\r\n                                        mesh.isVisible &&\r\n                                        mesh.isReady() &&\r\n                                        mesh.actionManager &&\r\n                                        mesh.actionManager.hasSpecificTrigger(Constants.ACTION_OnLongPressTrigger) &&\r\n                                        mesh === this._pickedDownMesh)\r\n                                ),\r\n                            false,\r\n                            scene.cameraToUseForPointers\r\n                        );\r\n\r\n                        if (pickResult?.pickedMesh && actionManager) {\r\n                            if (this._activePointerIdsCount !== 0 && Date.now() - this._startingPointerTime > InputManager.LongPressDelay && !this._isPointerSwiping()) {\r\n                                this._startingPointerTime = 0;\r\n                                actionManager.processTrigger(Constants.ACTION_OnLongPressTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));\r\n                            }\r\n                        }\r\n                    }, InputManager.LongPressDelay);\r\n                }\r\n            }\r\n        } else {\r\n            for (const step of scene._pointerDownStage) {\r\n                pickResult = step.action(this._unTranslatedPointerX, this._unTranslatedPointerY, pickResult, evt, false);\r\n            }\r\n        }\r\n\r\n        let pointerInfo: PointerInfo;\r\n        const type = PointerEventTypes.POINTERDOWN;\r\n\r\n        if (pickResult) {\r\n            if (scene.onPointerDown) {\r\n                scene.onPointerDown(evt, pickResult, type);\r\n            }\r\n\r\n            pointerInfo = new PointerInfo(type, evt, pickResult);\r\n            this._setRayOnPointerInfo(pickResult, evt);\r\n        } else {\r\n            pointerInfo = new PointerInfo(type, evt, null, this);\r\n        }\r\n\r\n        if (scene.onPointerObservable.hasObservers()) {\r\n            scene.onPointerObservable.notifyObservers(pointerInfo, type);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * @internals Boolean if delta for pointer exceeds drag movement threshold\r\n     */\r\n    public _isPointerSwiping(): boolean {\r\n        return this._isSwiping;\r\n    }\r\n\r\n    /**\r\n     * Use this method to simulate a pointer up on a mesh\r\n     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay\r\n     * @param pickResult - pickingInfo of the object wished to simulate pointer event on\r\n     * @param pointerEventInit - pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)\r\n     * @param doubleTap - indicates that the pointer up event should be considered as part of a double click (false by default)\r\n     */\r\n    public simulatePointerUp(pickResult: PickingInfo, pointerEventInit?: PointerEventInit, doubleTap?: boolean): void {\r\n        const evt = new PointerEvent(\"pointerup\", pointerEventInit);\r\n        evt.inputIndex = PointerInput.Move;\r\n        const clickInfo = new _ClickInfo();\r\n\r\n        if (doubleTap) {\r\n            clickInfo.doubleClick = true;\r\n        } else {\r\n            clickInfo.singleClick = true;\r\n        }\r\n\r\n        if (this._checkPrePointerObservable(pickResult, evt, PointerEventTypes.POINTERUP)) {\r\n            return;\r\n        }\r\n\r\n        this._processPointerUp(pickResult, evt, clickInfo);\r\n    }\r\n\r\n    private _processPointerUp(pickResult: Nullable<PickingInfo>, evt: IPointerEvent, clickInfo: _ClickInfo): void {\r\n        const scene = this._scene;\r\n        if (pickResult?.pickedMesh) {\r\n            this._pickedUpMesh = pickResult.pickedMesh;\r\n            if (this._pickedDownMesh === this._pickedUpMesh) {\r\n                if (scene.onPointerPick) {\r\n                    scene.onPointerPick(evt, pickResult);\r\n                }\r\n                if (clickInfo.singleClick && !clickInfo.ignore && scene.onPointerObservable.observers.length > this._cameraObserverCount) {\r\n                    const type = PointerEventTypes.POINTERPICK;\r\n                    const pi = new PointerInfo(type, evt, pickResult);\r\n                    this._setRayOnPointerInfo(pickResult, evt);\r\n                    scene.onPointerObservable.notifyObservers(pi, type);\r\n                }\r\n            }\r\n            const actionManager = pickResult.pickedMesh._getActionManagerForTrigger();\r\n            if (actionManager && !clickInfo.ignore) {\r\n                actionManager.processTrigger(Constants.ACTION_OnPickUpTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt, pickResult));\r\n\r\n                if (!clickInfo.hasSwiped && clickInfo.singleClick) {\r\n                    actionManager.processTrigger(Constants.ACTION_OnPickTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt, pickResult));\r\n                }\r\n\r\n                const doubleClickActionManager = pickResult.pickedMesh._getActionManagerForTrigger(Constants.ACTION_OnDoublePickTrigger);\r\n                if (clickInfo.doubleClick && doubleClickActionManager) {\r\n                    doubleClickActionManager.processTrigger(Constants.ACTION_OnDoublePickTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt, pickResult));\r\n                }\r\n            }\r\n        } else {\r\n            if (!clickInfo.ignore) {\r\n                for (const step of scene._pointerUpStage) {\r\n                    pickResult = step.action(this._unTranslatedPointerX, this._unTranslatedPointerY, pickResult, evt, clickInfo.doubleClick);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._pickedDownMesh && this._pickedDownMesh !== this._pickedUpMesh) {\r\n            const pickedDownActionManager = this._pickedDownMesh._getActionManagerForTrigger(Constants.ACTION_OnPickOutTrigger);\r\n            if (pickedDownActionManager) {\r\n                pickedDownActionManager.processTrigger(Constants.ACTION_OnPickOutTrigger, ActionEvent.CreateNew(this._pickedDownMesh, evt));\r\n            }\r\n        }\r\n\r\n        if (!clickInfo.ignore) {\r\n            const pi = new PointerInfo(PointerEventTypes.POINTERUP, evt, pickResult);\r\n            // Set ray on picking info.  Note that this info will also be reused for the tap notification.\r\n            this._setRayOnPointerInfo(pickResult, evt);\r\n            scene.onPointerObservable.notifyObservers(pi, PointerEventTypes.POINTERUP);\r\n\r\n            if (scene.onPointerUp) {\r\n                scene.onPointerUp(evt, pickResult, PointerEventTypes.POINTERUP);\r\n            }\r\n\r\n            if (!clickInfo.hasSwiped && !this._skipPointerTap && !this._isMultiTouchGesture) {\r\n                let type = 0;\r\n                if (clickInfo.singleClick) {\r\n                    type = PointerEventTypes.POINTERTAP;\r\n                } else if (clickInfo.doubleClick) {\r\n                    type = PointerEventTypes.POINTERDOUBLETAP;\r\n                }\r\n\r\n                if (type) {\r\n                    const pi = new PointerInfo(type, evt, pickResult);\r\n                    if (scene.onPointerObservable.hasObservers() && scene.onPointerObservable.hasSpecificMask(type)) {\r\n                        scene.onPointerObservable.notifyObservers(pi, type);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current pointer event is captured (meaning that the scene has already handled the pointer down)\r\n     * @param pointerId - defines the pointer id to use in a multi-touch scenario (0 by default)\r\n     * @returns true if the pointer was captured\r\n     */\r\n    public isPointerCaptured(pointerId = 0): boolean {\r\n        return this._pointerCaptures[pointerId];\r\n    }\r\n\r\n    /**\r\n     * Attach events to the canvas (To handle actionManagers triggers and raise onPointerMove, onPointerDown and onPointerUp\r\n     * @param attachUp - defines if you want to attach events to pointerup\r\n     * @param attachDown - defines if you want to attach events to pointerdown\r\n     * @param attachMove - defines if you want to attach events to pointermove\r\n     * @param elementToAttachTo - defines the target DOM element to attach to (will use the canvas by default)\r\n     */\r\n    public attachControl(attachUp = true, attachDown = true, attachMove = true, elementToAttachTo: Nullable<HTMLElement> = null): void {\r\n        const scene = this._scene;\r\n        const engine = scene.getEngine();\r\n\r\n        if (!elementToAttachTo) {\r\n            elementToAttachTo = engine.getInputElement();\r\n        }\r\n\r\n        if (this._alreadyAttached) {\r\n            this.detachControl();\r\n        }\r\n\r\n        if (elementToAttachTo) {\r\n            this._alreadyAttachedTo = elementToAttachTo;\r\n        }\r\n        this._deviceSourceManager = new DeviceSourceManager(engine);\r\n\r\n        // Because this is only called from _initClickEvent, which is called in _onPointerUp, we'll use the pointerUpPredicate for the pick call\r\n        this._initActionManager = (act: Nullable<AbstractActionManager>): Nullable<AbstractActionManager> => {\r\n            if (!this._meshPickProceed) {\r\n                const pickResult =\r\n                    scene.skipPointerUpPicking || (scene._registeredActions === 0 && !this._checkForPicking() && !scene.onPointerUp)\r\n                        ? null\r\n                        : scene.pick(\r\n                              this._unTranslatedPointerX,\r\n                              this._unTranslatedPointerY,\r\n                              scene.pointerUpPredicate,\r\n                              scene.pointerUpFastCheck,\r\n                              scene.cameraToUseForPointers,\r\n                              scene.pointerUpTrianglePredicate\r\n                          );\r\n                this._currentPickResult = pickResult;\r\n                if (pickResult) {\r\n                    act = pickResult.hit && pickResult.pickedMesh ? pickResult.pickedMesh._getActionManagerForTrigger() : null;\r\n                }\r\n                this._meshPickProceed = true;\r\n            }\r\n            return act;\r\n        };\r\n\r\n        this._delayedSimpleClick = (btn: number, clickInfo: _ClickInfo, cb: (clickInfo: _ClickInfo, pickResult: Nullable<PickingInfo>) => void) => {\r\n            // double click delay is over and that no double click has been raised since, or the 2 consecutive keys pressed are different\r\n            if ((Date.now() - this._previousStartingPointerTime > InputManager.DoubleClickDelay && !this._doubleClickOccured) || btn !== this._previousButtonPressed) {\r\n                this._doubleClickOccured = false;\r\n                clickInfo.singleClick = true;\r\n                clickInfo.ignore = false;\r\n\r\n                // If we have a delayed click, we need to resolve the TAP event\r\n                if (this._delayedClicks[btn]) {\r\n                    const evt = this._delayedClicks[btn].evt;\r\n                    const type = PointerEventTypes.POINTERTAP;\r\n                    const pi = new PointerInfo(type, evt, this._currentPickResult);\r\n                    if (scene.onPointerObservable.hasObservers() && scene.onPointerObservable.hasSpecificMask(type)) {\r\n                        scene.onPointerObservable.notifyObservers(pi, type);\r\n                    }\r\n\r\n                    // Clear the delayed click\r\n                    this._delayedClicks[btn] = null;\r\n                }\r\n            }\r\n        };\r\n\r\n        this._initClickEvent = (\r\n            obs1: Observable<PointerInfoPre>,\r\n            obs2: Observable<PointerInfo>,\r\n            evt: IPointerEvent,\r\n            cb: (clickInfo: _ClickInfo, pickResult: Nullable<PickingInfo>) => void\r\n        ): void => {\r\n            const clickInfo = new _ClickInfo();\r\n            this._currentPickResult = null;\r\n            let act: Nullable<AbstractActionManager> = null;\r\n\r\n            let checkPicking =\r\n                obs1.hasSpecificMask(PointerEventTypes.POINTERPICK) ||\r\n                obs2.hasSpecificMask(PointerEventTypes.POINTERPICK) ||\r\n                obs1.hasSpecificMask(PointerEventTypes.POINTERTAP) ||\r\n                obs2.hasSpecificMask(PointerEventTypes.POINTERTAP) ||\r\n                obs1.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP) ||\r\n                obs2.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP);\r\n            if (!checkPicking && AbstractActionManager) {\r\n                act = this._initActionManager(act, clickInfo);\r\n                if (act) {\r\n                    checkPicking = act.hasPickTriggers;\r\n                }\r\n            }\r\n\r\n            let needToIgnoreNext = false;\r\n\r\n            // Never pick if this is a multi-touch gesture (e.g. pinch)\r\n            checkPicking = checkPicking && !this._isMultiTouchGesture;\r\n\r\n            if (checkPicking) {\r\n                const btn = evt.button;\r\n                clickInfo.hasSwiped = this._isPointerSwiping();\r\n\r\n                if (!clickInfo.hasSwiped) {\r\n                    let checkSingleClickImmediately = !InputManager.ExclusiveDoubleClickMode;\r\n\r\n                    if (!checkSingleClickImmediately) {\r\n                        checkSingleClickImmediately = !obs1.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP) && !obs2.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP);\r\n\r\n                        if (checkSingleClickImmediately && !AbstractActionManager.HasSpecificTrigger(Constants.ACTION_OnDoublePickTrigger)) {\r\n                            act = this._initActionManager(act, clickInfo);\r\n                            if (act) {\r\n                                checkSingleClickImmediately = !act.hasSpecificTrigger(Constants.ACTION_OnDoublePickTrigger);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (checkSingleClickImmediately) {\r\n                        // single click detected if double click delay is over or two different successive keys pressed without exclusive double click or no double click required\r\n                        if (Date.now() - this._previousStartingPointerTime > InputManager.DoubleClickDelay || btn !== this._previousButtonPressed) {\r\n                            clickInfo.singleClick = true;\r\n                            cb(clickInfo, this._currentPickResult);\r\n                            needToIgnoreNext = true;\r\n                        }\r\n                    }\r\n                    // at least one double click is required to be check and exclusive double click is enabled\r\n                    else {\r\n                        // Queue up a delayed click, just in case this isn't a double click\r\n                        // It should be noted that while this delayed event happens\r\n                        // because of user input, it shouldn't be considered as a direct,\r\n                        // timing-dependent result of that input.  It's meant to just fire the TAP event\r\n                        const delayedClick = {\r\n                            evt: evt,\r\n                            clickInfo: clickInfo,\r\n                            timeoutId: window.setTimeout(this._delayedSimpleClick.bind(this, btn, clickInfo, cb), InputManager.DoubleClickDelay),\r\n                        };\r\n\r\n                        this._delayedClicks[btn] = delayedClick;\r\n                    }\r\n\r\n                    let checkDoubleClick = obs1.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP) || obs2.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP);\r\n                    if (!checkDoubleClick && AbstractActionManager.HasSpecificTrigger(Constants.ACTION_OnDoublePickTrigger)) {\r\n                        act = this._initActionManager(act, clickInfo);\r\n                        if (act) {\r\n                            checkDoubleClick = act.hasSpecificTrigger(Constants.ACTION_OnDoublePickTrigger);\r\n                        }\r\n                    }\r\n                    if (checkDoubleClick) {\r\n                        // two successive keys pressed are equal, double click delay is not over and double click has not just occurred\r\n                        if (btn === this._previousButtonPressed && Date.now() - this._previousStartingPointerTime < InputManager.DoubleClickDelay && !this._doubleClickOccured) {\r\n                            // pointer has not moved for 2 clicks, it's a double click\r\n                            if (!clickInfo.hasSwiped && !this._isPointerSwiping()) {\r\n                                this._previousStartingPointerTime = 0;\r\n                                this._doubleClickOccured = true;\r\n                                clickInfo.doubleClick = true;\r\n                                clickInfo.ignore = false;\r\n                                // If we have a pending click, we need to cancel it\r\n                                if (InputManager.ExclusiveDoubleClickMode && this._delayedClicks[btn]) {\r\n                                    clearTimeout(this._delayedClicks[btn]?.timeoutId);\r\n                                    this._delayedClicks[btn] = null;\r\n                                }\r\n\r\n                                cb(clickInfo, this._currentPickResult);\r\n                            }\r\n                            // if the two successive clicks are too far, it's just two simple clicks\r\n                            else {\r\n                                this._doubleClickOccured = false;\r\n                                this._previousStartingPointerTime = this._startingPointerTime;\r\n                                this._previousStartingPointerPosition.x = this._startingPointerPosition.x;\r\n                                this._previousStartingPointerPosition.y = this._startingPointerPosition.y;\r\n                                this._previousButtonPressed = btn;\r\n                                if (InputManager.ExclusiveDoubleClickMode) {\r\n                                    // If we have a delayed click, we need to cancel it\r\n                                    if (this._delayedClicks[btn]) {\r\n                                        clearTimeout(this._delayedClicks[btn]?.timeoutId);\r\n                                        this._delayedClicks[btn] = null;\r\n                                    }\r\n                                    cb(clickInfo, this._previousPickResult);\r\n                                } else {\r\n                                    cb(clickInfo, this._currentPickResult);\r\n                                }\r\n                            }\r\n                            needToIgnoreNext = true;\r\n                        }\r\n                        // just the first click of the double has been raised\r\n                        else {\r\n                            this._doubleClickOccured = false;\r\n                            this._previousStartingPointerTime = this._startingPointerTime;\r\n                            this._previousStartingPointerPosition.x = this._startingPointerPosition.x;\r\n                            this._previousStartingPointerPosition.y = this._startingPointerPosition.y;\r\n                            this._previousButtonPressed = btn!;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Even if ExclusiveDoubleClickMode is true, we need to always handle\r\n            // up events at time of execution, unless we're explicitly ignoring them.\r\n            if (!needToIgnoreNext) {\r\n                cb(clickInfo, this._currentPickResult);\r\n            }\r\n        };\r\n\r\n        this._onPointerMove = (evt: IMouseEvent) => {\r\n            this._updatePointerPosition(evt as IPointerEvent);\r\n            this._latestPointerMoveEvents.set((evt as IPointerEvent).pointerId, {\r\n                event: evt as IPointerEvent,\r\n                pointerX: this._pointerX,\r\n                pointerY: this._pointerY,\r\n                unTranslatedPointerX: this._unTranslatedPointerX,\r\n                unTranslatedPointerY: this._unTranslatedPointerY,\r\n            });\r\n\r\n            // Check if pointer leaves DragMovementThreshold range to determine if swipe is occurring\r\n            if (!this._isSwiping && this._swipeButtonPressed !== -1) {\r\n                this._isSwiping =\r\n                    Math.abs(this._startingPointerPosition.x - this._pointerX) > InputManager.DragMovementThreshold ||\r\n                    Math.abs(this._startingPointerPosition.y - this._pointerY) > InputManager.DragMovementThreshold;\r\n            }\r\n\r\n            // Because there's a race condition between pointermove and pointerlockchange events, we need to\r\n            // verify that the pointer is still locked after each pointermove event.\r\n            if (engine.isPointerLock) {\r\n                engine._verifyPointerLock();\r\n            }\r\n\r\n            // PreObservable support\r\n            if (\r\n                this._checkPrePointerObservable(\r\n                    null,\r\n                    evt as IPointerEvent,\r\n                    evt.inputIndex >= PointerInput.MouseWheelX && evt.inputIndex <= PointerInput.MouseWheelZ ? PointerEventTypes.POINTERWHEEL : PointerEventTypes.POINTERMOVE\r\n                )\r\n            ) {\r\n                return;\r\n            }\r\n\r\n            if (!scene.cameraToUseForPointers && !scene.activeCamera) {\r\n                return;\r\n            }\r\n\r\n            if (scene.skipPointerMovePicking) {\r\n                this._processPointerMove(new PickingInfo(), evt as IPointerEvent);\r\n                return;\r\n            }\r\n\r\n            this._ensurePointerMovePredicate();\r\n\r\n            const pickResult = scene._registeredActions > 0 || scene.constantlyUpdateMeshUnderPointer ? this._pickMove(evt as IPointerEvent) : null;\r\n            this._processPointerMove(pickResult, evt as IPointerEvent);\r\n        };\r\n\r\n        this._onPointerDown = (evt: IPointerEvent) => {\r\n            const freeIndex = this._activePointerIds.indexOf(-1);\r\n            if (freeIndex === -1) {\r\n                this._activePointerIds.push(evt.pointerId);\r\n            } else {\r\n                this._activePointerIds[freeIndex] = evt.pointerId;\r\n            }\r\n            this._activePointerIdsCount++;\r\n            this._pickedDownMesh = null;\r\n            this._meshPickProceed = false;\r\n\r\n            // If ExclusiveDoubleClickMode is true, we need to resolve any pending delayed clicks\r\n            if (InputManager.ExclusiveDoubleClickMode) {\r\n                for (let i = 0; i < this._delayedClicks.length; i++) {\r\n                    if (this._delayedClicks[i]) {\r\n                        // If the button that was pressed is the same as the one that was released,\r\n                        // just clear the timer.  This will be resolved in the up event.\r\n                        if (evt.button === i) {\r\n                            clearTimeout(this._delayedClicks[i]?.timeoutId);\r\n                        } else {\r\n                            // Otherwise, we need to resolve the click\r\n                            const clickInfo = this._delayedClicks[i]!.clickInfo;\r\n                            this._doubleClickOccured = false;\r\n                            clickInfo.singleClick = true;\r\n                            clickInfo.ignore = false;\r\n\r\n                            const prevEvt = this._delayedClicks[i]!.evt;\r\n                            const type = PointerEventTypes.POINTERTAP;\r\n                            const pi = new PointerInfo(type, prevEvt, this._currentPickResult);\r\n                            if (scene.onPointerObservable.hasObservers() && scene.onPointerObservable.hasSpecificMask(type)) {\r\n                                scene.onPointerObservable.notifyObservers(pi, type);\r\n                            }\r\n\r\n                            // Clear the delayed click\r\n                            this._delayedClicks[i] = null;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this._updatePointerPosition(evt);\r\n\r\n            if (this._swipeButtonPressed === -1) {\r\n                this._swipeButtonPressed = evt.button;\r\n            }\r\n\r\n            if (scene.preventDefaultOnPointerDown && elementToAttachTo) {\r\n                evt.preventDefault();\r\n                elementToAttachTo.focus();\r\n            }\r\n\r\n            this._startingPointerPosition.x = this._pointerX;\r\n            this._startingPointerPosition.y = this._pointerY;\r\n            this._startingPointerTime = Date.now();\r\n\r\n            // PreObservable support\r\n            if (this._checkPrePointerObservable(null, evt, PointerEventTypes.POINTERDOWN)) {\r\n                return;\r\n            }\r\n\r\n            if (!scene.cameraToUseForPointers && !scene.activeCamera) {\r\n                return;\r\n            }\r\n\r\n            this._pointerCaptures[evt.pointerId] = true;\r\n\r\n            if (!scene.pointerDownPredicate) {\r\n                scene.pointerDownPredicate = (mesh: AbstractMesh): boolean => {\r\n                    return (\r\n                        mesh.isPickable &&\r\n                        mesh.isVisible &&\r\n                        mesh.isReady() &&\r\n                        mesh.isEnabled() &&\r\n                        (!scene.cameraToUseForPointers || (scene.cameraToUseForPointers.layerMask & mesh.layerMask) !== 0)\r\n                    );\r\n                };\r\n            }\r\n\r\n            // Meshes\r\n            this._pickedDownMesh = null;\r\n            let pickResult;\r\n            if (scene.skipPointerDownPicking || (scene._registeredActions === 0 && !this._checkForPicking() && !scene.onPointerDown)) {\r\n                pickResult = new PickingInfo();\r\n            } else {\r\n                pickResult = scene.pick(\r\n                    this._unTranslatedPointerX,\r\n                    this._unTranslatedPointerY,\r\n                    scene.pointerDownPredicate,\r\n                    scene.pointerDownFastCheck,\r\n                    scene.cameraToUseForPointers,\r\n                    scene.pointerDownTrianglePredicate\r\n                );\r\n            }\r\n\r\n            this._processPointerDown(pickResult, evt);\r\n        };\r\n\r\n        this._onPointerUp = (evt: IPointerEvent) => {\r\n            const pointerIdIndex = this._activePointerIds.indexOf(evt.pointerId);\r\n            if (pointerIdIndex === -1) {\r\n                // We are attaching the pointer up to windows because of a bug in FF\r\n                // If this pointerId is not paired with an _onPointerDown call, ignore it\r\n                return;\r\n            }\r\n\r\n            this._activePointerIds[pointerIdIndex] = -1;\r\n            this._activePointerIdsCount--;\r\n            if (evt.pointerType === \"touch\") {\r\n                this._latestPointerMoveEvents.delete(evt.pointerId);\r\n            }\r\n            this._pickedUpMesh = null;\r\n            this._meshPickProceed = false;\r\n\r\n            this._updatePointerPosition(evt);\r\n\r\n            if (scene.preventDefaultOnPointerUp && elementToAttachTo) {\r\n                evt.preventDefault();\r\n                elementToAttachTo.focus();\r\n            }\r\n\r\n            this._initClickEvent(scene.onPrePointerObservable, scene.onPointerObservable, evt, (clickInfo: _ClickInfo, pickResult: Nullable<PickingInfo>) => {\r\n                // PreObservable support\r\n                if (scene.onPrePointerObservable.hasObservers()) {\r\n                    this._skipPointerTap = false;\r\n                    if (!clickInfo.ignore) {\r\n                        if (this._checkPrePointerObservable(null, evt, PointerEventTypes.POINTERUP)) {\r\n                            // If we're skipping the next observable, we need to reset the swipe state before returning\r\n                            if (this._swipeButtonPressed === evt.button) {\r\n                                this._isSwiping = false;\r\n                                this._swipeButtonPressed = -1;\r\n                            }\r\n\r\n                            // If we're going to skip the POINTERUP, we need to reset the pointer capture\r\n                            if (evt.buttons === 0) {\r\n                                this._pointerCaptures[evt.pointerId] = false;\r\n                            }\r\n\r\n                            return;\r\n                        }\r\n                        if (!clickInfo.hasSwiped) {\r\n                            if (clickInfo.singleClick && scene.onPrePointerObservable.hasSpecificMask(PointerEventTypes.POINTERTAP)) {\r\n                                if (this._checkPrePointerObservable(null, evt, PointerEventTypes.POINTERTAP)) {\r\n                                    this._skipPointerTap = true;\r\n                                }\r\n                            }\r\n                            if (clickInfo.doubleClick && scene.onPrePointerObservable.hasSpecificMask(PointerEventTypes.POINTERDOUBLETAP)) {\r\n                                if (this._checkPrePointerObservable(null, evt, PointerEventTypes.POINTERDOUBLETAP)) {\r\n                                    this._skipPointerTap = true;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // There should be a pointer captured at this point so if there isn't we should reset and return\r\n                if (!this._pointerCaptures[evt.pointerId]) {\r\n                    if (this._swipeButtonPressed === evt.button) {\r\n                        this._isSwiping = false;\r\n                        this._swipeButtonPressed = -1;\r\n                    }\r\n                    return;\r\n                }\r\n\r\n                // Only release capture if all buttons are released\r\n                if (evt.buttons === 0) {\r\n                    this._pointerCaptures[evt.pointerId] = false;\r\n                }\r\n                if (!scene.cameraToUseForPointers && !scene.activeCamera) {\r\n                    return;\r\n                }\r\n\r\n                if (!scene.pointerUpPredicate) {\r\n                    scene.pointerUpPredicate = (mesh: AbstractMesh): boolean => {\r\n                        return (\r\n                            mesh.isPickable &&\r\n                            mesh.isVisible &&\r\n                            mesh.isReady() &&\r\n                            mesh.isEnabled() &&\r\n                            (!scene.cameraToUseForPointers || (scene.cameraToUseForPointers.layerMask & mesh.layerMask) !== 0)\r\n                        );\r\n                    };\r\n                }\r\n\r\n                // Meshes\r\n                if (!this._meshPickProceed && ((AbstractActionManager && AbstractActionManager.HasTriggers) || this._checkForPicking() || scene.onPointerUp)) {\r\n                    this._initActionManager(null, clickInfo);\r\n                }\r\n                if (!pickResult) {\r\n                    pickResult = this._currentPickResult;\r\n                }\r\n\r\n                this._processPointerUp(pickResult, evt, clickInfo);\r\n\r\n                this._previousPickResult = this._currentPickResult;\r\n\r\n                if (this._swipeButtonPressed === evt.button) {\r\n                    this._isSwiping = false;\r\n                    this._swipeButtonPressed = -1;\r\n                }\r\n            });\r\n        };\r\n\r\n        this._onKeyDown = (evt: IKeyboardEvent) => {\r\n            const type = KeyboardEventTypes.KEYDOWN;\r\n            if (scene.onPreKeyboardObservable.hasObservers()) {\r\n                const pi = new KeyboardInfoPre(type, evt);\r\n                scene.onPreKeyboardObservable.notifyObservers(pi, type);\r\n                if (pi.skipOnKeyboardObservable) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (scene.onKeyboardObservable.hasObservers()) {\r\n                const pi = new KeyboardInfo(type, evt);\r\n                scene.onKeyboardObservable.notifyObservers(pi, type);\r\n            }\r\n\r\n            if (scene.actionManager) {\r\n                scene.actionManager.processTrigger(Constants.ACTION_OnKeyDownTrigger, ActionEvent.CreateNewFromScene(scene, evt));\r\n            }\r\n        };\r\n\r\n        this._onKeyUp = (evt: IKeyboardEvent) => {\r\n            const type = KeyboardEventTypes.KEYUP;\r\n            if (scene.onPreKeyboardObservable.hasObservers()) {\r\n                const pi = new KeyboardInfoPre(type, evt);\r\n                scene.onPreKeyboardObservable.notifyObservers(pi, type);\r\n                if (pi.skipOnKeyboardObservable) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (scene.onKeyboardObservable.hasObservers()) {\r\n                const pi = new KeyboardInfo(type, evt);\r\n                scene.onKeyboardObservable.notifyObservers(pi, type);\r\n            }\r\n\r\n            if (scene.actionManager) {\r\n                scene.actionManager.processTrigger(Constants.ACTION_OnKeyUpTrigger, ActionEvent.CreateNewFromScene(scene, evt));\r\n            }\r\n        };\r\n\r\n        // If a device connects that we can handle, wire up the observable\r\n        this._deviceSourceManager.onDeviceConnectedObservable.add((deviceSource) => {\r\n            if (deviceSource.deviceType === DeviceType.Mouse) {\r\n                deviceSource.onInputChangedObservable.add((eventData) => {\r\n                    this._originMouseEvent = eventData;\r\n                    if (\r\n                        eventData.inputIndex === PointerInput.LeftClick ||\r\n                        eventData.inputIndex === PointerInput.MiddleClick ||\r\n                        eventData.inputIndex === PointerInput.RightClick ||\r\n                        eventData.inputIndex === PointerInput.BrowserBack ||\r\n                        eventData.inputIndex === PointerInput.BrowserForward\r\n                    ) {\r\n                        if (attachDown && deviceSource.getInput(eventData.inputIndex) === 1) {\r\n                            this._onPointerDown(eventData);\r\n                        } else if (attachUp && deviceSource.getInput(eventData.inputIndex) === 0) {\r\n                            this._onPointerUp(eventData);\r\n                        }\r\n                    } else if (attachMove) {\r\n                        if (eventData.inputIndex === PointerInput.Move) {\r\n                            this._onPointerMove(eventData);\r\n                        } else if (\r\n                            eventData.inputIndex === PointerInput.MouseWheelX ||\r\n                            eventData.inputIndex === PointerInput.MouseWheelY ||\r\n                            eventData.inputIndex === PointerInput.MouseWheelZ\r\n                        ) {\r\n                            this._onPointerMove(eventData);\r\n                        }\r\n                    }\r\n                });\r\n            } else if (deviceSource.deviceType === DeviceType.Touch) {\r\n                deviceSource.onInputChangedObservable.add((eventData) => {\r\n                    if (eventData.inputIndex === PointerInput.LeftClick) {\r\n                        if (attachDown && deviceSource.getInput(eventData.inputIndex) === 1) {\r\n                            this._onPointerDown(eventData);\r\n                            if (this._activePointerIdsCount > 1) {\r\n                                this._isMultiTouchGesture = true;\r\n                            }\r\n                        } else if (attachUp && deviceSource.getInput(eventData.inputIndex) === 0) {\r\n                            this._onPointerUp(eventData);\r\n                            if (this._activePointerIdsCount === 0) {\r\n                                this._isMultiTouchGesture = false;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (attachMove && eventData.inputIndex === PointerInput.Move) {\r\n                        this._onPointerMove(eventData);\r\n                    }\r\n                });\r\n            } else if (deviceSource.deviceType === DeviceType.Keyboard) {\r\n                deviceSource.onInputChangedObservable.add((eventData) => {\r\n                    if (eventData.type === \"keydown\") {\r\n                        this._onKeyDown(eventData);\r\n                    } else if (eventData.type === \"keyup\") {\r\n                        this._onKeyUp(eventData);\r\n                    }\r\n                });\r\n            }\r\n        });\r\n\r\n        this._alreadyAttached = true;\r\n    }\r\n\r\n    /**\r\n     * Detaches all event handlers\r\n     */\r\n    public detachControl() {\r\n        if (this._alreadyAttached) {\r\n            this._deviceSourceManager!.dispose();\r\n            this._deviceSourceManager = null;\r\n\r\n            // Cursor\r\n            if (this._alreadyAttachedTo && !this._scene.doNotHandleCursors) {\r\n                this._alreadyAttachedTo.style.cursor = this._scene.defaultCursor;\r\n            }\r\n\r\n            this._alreadyAttached = false;\r\n            this._alreadyAttachedTo = null;\r\n            this._latestPointerMoveEvents.clear();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the value of meshUnderPointer for a given pointerId\r\n     * @param mesh - defines the mesh to use\r\n     * @param pointerId - optional pointer id when using more than one pointer. Defaults to 0\r\n     * @param pickResult - optional pickingInfo data used to find mesh\r\n     * @param evt - optional pointer event\r\n     */\r\n    public setPointerOverMesh(mesh: Nullable<AbstractMesh>, pointerId: number = 0, pickResult?: Nullable<PickingInfo>, evt?: IPointerEvent): void {\r\n        if (this._meshUnderPointerId[pointerId] === mesh && (!mesh || !mesh._internalAbstractMeshDataInfo._pointerOverDisableMeshTesting)) {\r\n            return;\r\n        }\r\n\r\n        const underPointerMesh = this._meshUnderPointerId[pointerId];\r\n\r\n        let actionManager: Nullable<AbstractActionManager>;\r\n        if (underPointerMesh) {\r\n            actionManager = underPointerMesh._getActionManagerForTrigger(Constants.ACTION_OnPointerOutTrigger);\r\n            if (actionManager) {\r\n                actionManager.processTrigger(Constants.ACTION_OnPointerOutTrigger, new ActionEvent(underPointerMesh, this._pointerX, this._pointerY, mesh, evt, { pointerId }));\r\n            }\r\n        }\r\n\r\n        if (mesh) {\r\n            this._meshUnderPointerId[pointerId] = mesh;\r\n            this._pointerOverMesh = mesh;\r\n\r\n            actionManager = mesh._getActionManagerForTrigger(Constants.ACTION_OnPointerOverTrigger);\r\n            if (actionManager) {\r\n                actionManager.processTrigger(Constants.ACTION_OnPointerOverTrigger, new ActionEvent(mesh, this._pointerX, this._pointerY, mesh, evt, { pointerId, pickResult }));\r\n            }\r\n        } else {\r\n            delete this._meshUnderPointerId[pointerId];\r\n            this._pointerOverMesh = null;\r\n        }\r\n        // if we reached this point, meshUnderPointerId has been updated. We need to notify observers that are registered.\r\n        if (this._scene.onMeshUnderPointerUpdatedObservable.hasObservers()) {\r\n            this._scene.onMeshUnderPointerUpdatedObservable.notifyObservers({\r\n                mesh,\r\n                pointerId,\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh under the pointer\r\n     * @returns a Mesh or null if no mesh is under the pointer\r\n     */\r\n    public getPointerOverMesh(): Nullable<AbstractMesh> {\r\n        return this.meshUnderPointer;\r\n    }\r\n\r\n    /**\r\n     * @param mesh - Mesh to invalidate\r\n     * @internal\r\n     */\r\n    public _invalidateMesh(mesh: AbstractMesh) {\r\n        if (this._pointerOverMesh === mesh) {\r\n            this._pointerOverMesh = null;\r\n        }\r\n        if (this._pickedDownMesh === mesh) {\r\n            this._pickedDownMesh = null;\r\n        }\r\n        if (this._pickedUpMesh === mesh) {\r\n            this._pickedUpMesh = null;\r\n        }\r\n        for (const pointerId in this._meshUnderPointerId) {\r\n            if (this._meshUnderPointerId[pointerId] === mesh) {\r\n                delete this._meshUnderPointerId[pointerId];\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { PrecisionDate } from \"./precisionDate\";\r\n\r\n/**\r\n * This class is used to track a performance counter which is number based.\r\n * The user has access to many properties which give statistics of different nature.\r\n *\r\n * The implementer can track two kinds of Performance Counter: time and count.\r\n * For time you can optionally call fetchNewFrame() to notify the start of a new frame to monitor, then call beginMonitoring() to start and endMonitoring() to record the lapsed time. endMonitoring takes a newFrame parameter for you to specify if the monitored time should be set for a new frame or accumulated to the current frame being monitored.\r\n * For count you first have to call fetchNewFrame() to notify the start of a new frame to monitor, then call addCount() how many time required to increment the count value you monitor.\r\n */\r\nexport class PerfCounter {\r\n    /**\r\n     * Gets or sets a global boolean to turn on and off all the counters\r\n     */\r\n    public static Enabled = true;\r\n\r\n    /**\r\n     * Returns the smallest value ever\r\n     */\r\n    public get min(): number {\r\n        return this._min;\r\n    }\r\n\r\n    /**\r\n     * Returns the biggest value ever\r\n     */\r\n    public get max(): number {\r\n        return this._max;\r\n    }\r\n\r\n    /**\r\n     * Returns the average value since the performance counter is running\r\n     */\r\n    public get average(): number {\r\n        return this._average;\r\n    }\r\n\r\n    /**\r\n     * Returns the average value of the last second the counter was monitored\r\n     */\r\n    public get lastSecAverage(): number {\r\n        return this._lastSecAverage;\r\n    }\r\n\r\n    /**\r\n     * Returns the current value\r\n     */\r\n    public get current(): number {\r\n        return this._current;\r\n    }\r\n\r\n    /**\r\n     * Gets the accumulated total\r\n     */\r\n    public get total(): number {\r\n        return this._totalAccumulated;\r\n    }\r\n\r\n    /**\r\n     * Gets the total value count\r\n     */\r\n    public get count(): number {\r\n        return this._totalValueCount;\r\n    }\r\n\r\n    /**\r\n     * Creates a new counter\r\n     */\r\n    constructor() {\r\n        this._startMonitoringTime = 0;\r\n        this._min = 0;\r\n        this._max = 0;\r\n        this._hasResult = false;\r\n        this._hasCurrentValue = false;\r\n        this._average = 0;\r\n        this._lastSecAverage = 0;\r\n        this._current = 0;\r\n        this._totalValueCount = 0;\r\n        this._totalAccumulated = 0;\r\n        this._lastSecAccumulated = 0;\r\n        this._lastSecTime = 0;\r\n        this._lastSecValueCount = 0;\r\n    }\r\n\r\n    /**\r\n     * Call this method to start monitoring a new frame.\r\n     * This scenario is typically used when you accumulate monitoring time many times for a single frame, you call this method at the start of the frame, then beginMonitoring to start recording and endMonitoring(false) to accumulated the recorded time to the PerfCounter or addCount() to accumulate a monitored count.\r\n     */\r\n    public fetchNewFrame() {\r\n        this._totalValueCount++;\r\n        this._current = 0;\r\n        this._hasCurrentValue = PerfCounter.Enabled;\r\n        this._lastSecValueCount++;\r\n    }\r\n\r\n    /**\r\n     * Call this method to monitor a count of something (e.g. mesh drawn in viewport count)\r\n     * @param newCount the count value to add to the monitored count\r\n     * @param fetchResult true when it's the last time in the frame you add to the counter and you wish to update the statistics properties (min/max/average), false if you only want to update statistics.\r\n     */\r\n    public addCount(newCount: number, fetchResult: boolean) {\r\n        if (!PerfCounter.Enabled) {\r\n            return;\r\n        }\r\n        this._current += newCount;\r\n        this._hasCurrentValue = true;\r\n        if (fetchResult) {\r\n            this._fetchResult();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Start monitoring this performance counter\r\n     */\r\n    public beginMonitoring() {\r\n        if (!PerfCounter.Enabled) {\r\n            return;\r\n        }\r\n        this._startMonitoringTime = PrecisionDate.Now;\r\n    }\r\n\r\n    /**\r\n     * Compute the time lapsed since the previous beginMonitoring() call.\r\n     * @param newFrame true by default to fetch the result and monitor a new frame, if false the time monitored will be added to the current frame counter\r\n     */\r\n    public endMonitoring(newFrame: boolean = true) {\r\n        if (!PerfCounter.Enabled) {\r\n            return;\r\n        }\r\n\r\n        if (newFrame) {\r\n            this.fetchNewFrame();\r\n        }\r\n\r\n        const currentTime = PrecisionDate.Now;\r\n        this._current = currentTime - this._startMonitoringTime;\r\n        this._hasCurrentValue = true;\r\n\r\n        if (newFrame) {\r\n            this._fetchResult();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Call this method to end the monitoring of a frame.\r\n     * This scenario is typically used when you accumulate monitoring time many times for a single frame, you call this method at the end of the frame, after beginMonitoring to start recording and endMonitoring(false) to accumulated the recorded time to the PerfCounter or addCount() to accumulate a monitored count.\r\n     */\r\n    public endFrame() {\r\n        this._fetchResult();\r\n    }\r\n\r\n    /** @internal */\r\n    public _fetchResult() {\r\n        if (!this._hasCurrentValue) {\r\n            return;\r\n        }\r\n        this._totalAccumulated += this._current;\r\n        this._lastSecAccumulated += this._current;\r\n\r\n        // Min/Max update\r\n        if (this._hasResult) {\r\n            this._min = Math.min(this._min, this._current);\r\n            this._max = Math.max(this._max, this._current);\r\n        } else {\r\n            this._min = this._current;\r\n            this._max = this._current;\r\n            this._hasResult = true;\r\n        }\r\n        this._average = this._totalAccumulated / this._totalValueCount;\r\n\r\n        // Reset last sec?\r\n        const now = PrecisionDate.Now;\r\n        if (now - this._lastSecTime > 1000) {\r\n            this._lastSecAverage = this._lastSecAccumulated / this._lastSecValueCount;\r\n            this._lastSecTime = now;\r\n            this._lastSecAccumulated = 0;\r\n            this._lastSecValueCount = 0;\r\n        }\r\n    }\r\n\r\n    private _startMonitoringTime: number;\r\n    private _min: number;\r\n    private _max: number;\r\n    private _hasResult: boolean;\r\n    private _hasCurrentValue: boolean;\r\n    private _average: number;\r\n    private _current: number;\r\n    private _totalValueCount: number;\r\n    private _totalAccumulated: number;\r\n    private _lastSecAverage: number;\r\n    private _lastSecAccumulated: number;\r\n    private _lastSecTime: number;\r\n    private _lastSecValueCount: number;\r\n}\r\n","import { type DeepImmutable } from \"../types\";\r\nimport { Vector3, Matrix } from \"./math.vector.pure\";\r\nimport { type IPlaneLike } from \"./math.like\";\r\n\r\n/**\r\n * Represents a plane by the equation ax + by + cz + d = 0\r\n */\r\nexport class Plane implements IPlaneLike {\r\n    private static _TmpMatrix = Matrix.Identity();\r\n\r\n    /**\r\n     * Normal of the plane (a,b,c)\r\n     */\r\n    public normal: Vector3;\r\n    /**\r\n     * d component of the plane\r\n     */\r\n    public d: number;\r\n    /**\r\n     * Creates a Plane object according to the given floats a, b, c, d and the plane equation : ax + by + cz + d = 0\r\n     * @param a a component of the plane\r\n     * @param b b component of the plane\r\n     * @param c c component of the plane\r\n     * @param d d component of the plane\r\n     */\r\n    constructor(a: number, b: number, c: number, d: number) {\r\n        this.normal = new Vector3(a, b, c);\r\n        this.d = d;\r\n    }\r\n\r\n    /**\r\n     * @returns the plane coordinates as a new array of 4 elements [a, b, c, d].\r\n     */\r\n    public asArray(): number[] {\r\n        return [this.normal.x, this.normal.y, this.normal.z, this.d];\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * @returns a new plane copied from the current Plane.\r\n     */\r\n    public clone(): Plane {\r\n        return new Plane(this.normal.x, this.normal.y, this.normal.z, this.d);\r\n    }\r\n    /**\r\n     * @returns the string \"Plane\".\r\n     */\r\n    public getClassName(): string {\r\n        return \"Plane\";\r\n    }\r\n    /**\r\n     * @returns the Plane hash code.\r\n     */\r\n    public getHashCode(): number {\r\n        let hash = this.normal.getHashCode();\r\n        hash = (hash * 397) ^ (this.d | 0);\r\n        return hash;\r\n    }\r\n    /**\r\n     * Normalize the current Plane in place.\r\n     * @returns the updated Plane.\r\n     */\r\n    public normalize(): Plane {\r\n        const norm = Math.sqrt(this.normal.x * this.normal.x + this.normal.y * this.normal.y + this.normal.z * this.normal.z);\r\n        let magnitude = 0.0;\r\n\r\n        if (norm !== 0) {\r\n            magnitude = 1.0 / norm;\r\n        }\r\n        this.normal.x *= magnitude;\r\n        this.normal.y *= magnitude;\r\n        this.normal.z *= magnitude;\r\n        this.d *= magnitude;\r\n        return this;\r\n    }\r\n    /**\r\n     * Applies a transformation the plane and returns the result\r\n     * @param transformation the transformation matrix to be applied to the plane\r\n     * @returns a new Plane as the result of the transformation of the current Plane by the given matrix.\r\n     */\r\n    public transform(transformation: DeepImmutable<Matrix>): Plane {\r\n        const invertedMatrix = Plane._TmpMatrix;\r\n        transformation.invertToRef(invertedMatrix);\r\n        const m = invertedMatrix.m;\r\n        const x = this.normal.x;\r\n        const y = this.normal.y;\r\n        const z = this.normal.z;\r\n        const d = this.d;\r\n\r\n        const normalX = x * m[0] + y * m[1] + z * m[2] + d * m[3];\r\n        const normalY = x * m[4] + y * m[5] + z * m[6] + d * m[7];\r\n        const normalZ = x * m[8] + y * m[9] + z * m[10] + d * m[11];\r\n        const finalD = x * m[12] + y * m[13] + z * m[14] + d * m[15];\r\n\r\n        return new Plane(normalX, normalY, normalZ, finalD);\r\n    }\r\n\r\n    /**\r\n     * Compute the dot product between the point and the plane normal\r\n     * @param point point to calculate the dot product with\r\n     * @returns the dot product (float) of the point coordinates and the plane normal.\r\n     */\r\n    public dotCoordinate(point: DeepImmutable<Vector3>): number {\r\n        return this.normal.x * point.x + this.normal.y * point.y + this.normal.z * point.z + this.d;\r\n    }\r\n\r\n    /**\r\n     * Updates the current Plane from the plane defined by the three given points.\r\n     * @param point1 one of the points used to construct the plane\r\n     * @param point2 one of the points used to construct the plane\r\n     * @param point3 one of the points used to construct the plane\r\n     * @returns the updated Plane.\r\n     */\r\n    public copyFromPoints(point1: DeepImmutable<Vector3>, point2: DeepImmutable<Vector3>, point3: DeepImmutable<Vector3>): Plane {\r\n        const x1 = point2.x - point1.x;\r\n        const y1 = point2.y - point1.y;\r\n        const z1 = point2.z - point1.z;\r\n        const x2 = point3.x - point1.x;\r\n        const y2 = point3.y - point1.y;\r\n        const z2 = point3.z - point1.z;\r\n        const yz = y1 * z2 - z1 * y2;\r\n        const xz = z1 * x2 - x1 * z2;\r\n        const xy = x1 * y2 - y1 * x2;\r\n        const pyth = Math.sqrt(yz * yz + xz * xz + xy * xy);\r\n        let invPyth;\r\n\r\n        if (pyth !== 0) {\r\n            invPyth = 1.0 / pyth;\r\n        } else {\r\n            invPyth = 0.0;\r\n        }\r\n\r\n        this.normal.x = yz * invPyth;\r\n        this.normal.y = xz * invPyth;\r\n        this.normal.z = xy * invPyth;\r\n        this.d = -(this.normal.x * point1.x + this.normal.y * point1.y + this.normal.z * point1.z);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Checks if the plane is facing a given direction (meaning if the plane's normal is pointing in the opposite direction of the given vector).\r\n     * Note that for this function to work as expected you should make sure that:\r\n     *   - direction and the plane normal are normalized\r\n     *   - epsilon is a number just bigger than -1, something like -0.99 for eg\r\n     * @param direction the direction to check if the plane is facing\r\n     * @param epsilon value the dot product is compared against (returns true if dot <= epsilon)\r\n     * @returns True if the plane is facing the given direction\r\n     */\r\n    public isFrontFacingTo(direction: DeepImmutable<Vector3>, epsilon: number): boolean {\r\n        const dot = Vector3.Dot(this.normal, direction);\r\n        return dot <= epsilon;\r\n    }\r\n\r\n    /**\r\n     * Calculates the distance to a point\r\n     * @param point point to calculate distance to\r\n     * @returns the signed distance (float) from the given point to the Plane.\r\n     */\r\n    public signedDistanceTo(point: DeepImmutable<Vector3>): number {\r\n        return Vector3.Dot(point, this.normal) + this.d;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Creates a plane from an  array\r\n     * @param array the array to create a plane from\r\n     * @returns a new Plane from the given array.\r\n     */\r\n    static FromArray(array: DeepImmutable<ArrayLike<number>>): Plane {\r\n        return new Plane(array[0], array[1], array[2], array[3]);\r\n    }\r\n    /**\r\n     * Creates a plane from three points\r\n     * @param point1 point used to create the plane\r\n     * @param point2 point used to create the plane\r\n     * @param point3 point used to create the plane\r\n     * @returns a new Plane defined by the three given points.\r\n     */\r\n    static FromPoints(point1: DeepImmutable<Vector3>, point2: DeepImmutable<Vector3>, point3: DeepImmutable<Vector3>): Plane {\r\n        const result = new Plane(0.0, 0.0, 0.0, 0.0);\r\n        result.copyFromPoints(point1, point2, point3);\r\n        return result;\r\n    }\r\n    /**\r\n     * Creates a plane from an origin point and a normal\r\n     * @param origin origin of the plane to be constructed\r\n     * @param normal normal of the plane to be constructed\r\n     * @returns a new Plane the normal vector to this plane at the given origin point.\r\n     */\r\n    static FromPositionAndNormal(origin: DeepImmutable<Vector3>, normal: Vector3): Plane {\r\n        const plane = new Plane(0.0, 0.0, 0.0, 0.0);\r\n        return this.FromPositionAndNormalToRef(origin, normal, plane);\r\n    }\r\n\r\n    /**\r\n     * Updates the given Plane \"result\" from an origin point and a normal.\r\n     * @param origin origin of the plane to be constructed\r\n     * @param normal the normalized normals of the plane to be constructed\r\n     * @param result defines the Plane where to store the result\r\n     * @returns result input\r\n     */\r\n    static FromPositionAndNormalToRef<T extends Plane>(origin: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>, result: T): T {\r\n        result.normal.copyFrom(normal);\r\n        result.normal.normalize();\r\n        result.d = -origin.dot(result.normal);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Calculates the distance from a plane and a point\r\n     * @param origin origin of the plane to be constructed\r\n     * @param normal normal of the plane to be constructed\r\n     * @param point point to calculate distance to\r\n     * @returns the signed distance between the plane defined by the normal vector at the \"origin\"\" point and the given other point.\r\n     */\r\n    static SignedDistanceToPlaneFromPositionAndNormal(origin: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>, point: DeepImmutable<Vector3>): number {\r\n        const d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z);\r\n        return Vector3.Dot(point, normal) + d;\r\n    }\r\n}\r\n","import { type Matrix, type Vector3 } from \"./math.vector\";\r\nimport { type DeepImmutable } from \"../types\";\r\nimport { Plane } from \"./math.plane\";\r\n\r\n/**\r\n * Represents a camera frustum\r\n */\r\nexport class Frustum {\r\n    /**\r\n     * Gets the planes representing the frustum\r\n     * @param transform matrix to be applied to the returned planes\r\n     * @returns a new array of 6 Frustum planes computed by the given transformation matrix.\r\n     */\r\n    public static GetPlanes(transform: DeepImmutable<Matrix>): Plane[] {\r\n        const frustumPlanes = [];\r\n        for (let index = 0; index < 6; index++) {\r\n            frustumPlanes.push(new Plane(0.0, 0.0, 0.0, 0.0));\r\n        }\r\n        Frustum.GetPlanesToRef(transform, frustumPlanes);\r\n        return frustumPlanes;\r\n    }\r\n\r\n    /**\r\n     * Gets the near frustum plane transformed by the transform matrix\r\n     * @param transform transformation matrix to be applied to the resulting frustum plane\r\n     * @param frustumPlane the resulting frustum plane\r\n     */\r\n    public static GetNearPlaneToRef(transform: DeepImmutable<Matrix>, frustumPlane: Plane): void {\r\n        const m = transform.m;\r\n        frustumPlane.normal.x = m[3] + m[2];\r\n        frustumPlane.normal.y = m[7] + m[6];\r\n        frustumPlane.normal.z = m[11] + m[10];\r\n        frustumPlane.d = m[15] + m[14];\r\n        frustumPlane.normalize();\r\n    }\r\n\r\n    /**\r\n     * Gets the far frustum plane transformed by the transform matrix\r\n     * @param transform transformation matrix to be applied to the resulting frustum plane\r\n     * @param frustumPlane the resulting frustum plane\r\n     */\r\n    public static GetFarPlaneToRef(transform: DeepImmutable<Matrix>, frustumPlane: Plane): void {\r\n        const m = transform.m;\r\n        frustumPlane.normal.x = m[3] - m[2];\r\n        frustumPlane.normal.y = m[7] - m[6];\r\n        frustumPlane.normal.z = m[11] - m[10];\r\n        frustumPlane.d = m[15] - m[14];\r\n        frustumPlane.normalize();\r\n    }\r\n\r\n    /**\r\n     * Gets the left frustum plane transformed by the transform matrix\r\n     * @param transform transformation matrix to be applied to the resulting frustum plane\r\n     * @param frustumPlane the resulting frustum plane\r\n     */\r\n    public static GetLeftPlaneToRef(transform: DeepImmutable<Matrix>, frustumPlane: Plane): void {\r\n        const m = transform.m;\r\n        frustumPlane.normal.x = m[3] + m[0];\r\n        frustumPlane.normal.y = m[7] + m[4];\r\n        frustumPlane.normal.z = m[11] + m[8];\r\n        frustumPlane.d = m[15] + m[12];\r\n        frustumPlane.normalize();\r\n    }\r\n\r\n    /**\r\n     * Gets the right frustum plane transformed by the transform matrix\r\n     * @param transform transformation matrix to be applied to the resulting frustum plane\r\n     * @param frustumPlane the resulting frustum plane\r\n     */\r\n    public static GetRightPlaneToRef(transform: DeepImmutable<Matrix>, frustumPlane: Plane): void {\r\n        const m = transform.m;\r\n        frustumPlane.normal.x = m[3] - m[0];\r\n        frustumPlane.normal.y = m[7] - m[4];\r\n        frustumPlane.normal.z = m[11] - m[8];\r\n        frustumPlane.d = m[15] - m[12];\r\n        frustumPlane.normalize();\r\n    }\r\n\r\n    /**\r\n     * Gets the top frustum plane transformed by the transform matrix\r\n     * @param transform transformation matrix to be applied to the resulting frustum plane\r\n     * @param frustumPlane the resulting frustum plane\r\n     */\r\n    public static GetTopPlaneToRef(transform: DeepImmutable<Matrix>, frustumPlane: Plane): void {\r\n        const m = transform.m;\r\n        frustumPlane.normal.x = m[3] - m[1];\r\n        frustumPlane.normal.y = m[7] - m[5];\r\n        frustumPlane.normal.z = m[11] - m[9];\r\n        frustumPlane.d = m[15] - m[13];\r\n        frustumPlane.normalize();\r\n    }\r\n\r\n    /**\r\n     * Gets the bottom frustum plane transformed by the transform matrix\r\n     * @param transform transformation matrix to be applied to the resulting frustum plane\r\n     * @param frustumPlane the resulting frustum plane\r\n     */\r\n    public static GetBottomPlaneToRef(transform: DeepImmutable<Matrix>, frustumPlane: Plane): void {\r\n        const m = transform.m;\r\n        frustumPlane.normal.x = m[3] + m[1];\r\n        frustumPlane.normal.y = m[7] + m[5];\r\n        frustumPlane.normal.z = m[11] + m[9];\r\n        frustumPlane.d = m[15] + m[13];\r\n        frustumPlane.normalize();\r\n    }\r\n\r\n    /**\r\n     * Sets the given array \"frustumPlanes\" with the 6 Frustum planes computed by the given transformation matrix.\r\n     * @param transform transformation matrix to be applied to the resulting frustum planes\r\n     * @param frustumPlanes the resulting frustum planes\r\n     */\r\n    public static GetPlanesToRef(transform: DeepImmutable<Matrix>, frustumPlanes: Plane[]): void {\r\n        // Near\r\n        Frustum.GetNearPlaneToRef(transform, frustumPlanes[0]);\r\n\r\n        // Far\r\n        Frustum.GetFarPlaneToRef(transform, frustumPlanes[1]);\r\n\r\n        // Left\r\n        Frustum.GetLeftPlaneToRef(transform, frustumPlanes[2]);\r\n\r\n        // Right\r\n        Frustum.GetRightPlaneToRef(transform, frustumPlanes[3]);\r\n\r\n        // Top\r\n        Frustum.GetTopPlaneToRef(transform, frustumPlanes[4]);\r\n\r\n        // Bottom\r\n        Frustum.GetBottomPlaneToRef(transform, frustumPlanes[5]);\r\n    }\r\n\r\n    /**\r\n     * Tests if a point is located between the frustum planes.\r\n     * @param point defines the point to test\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if the point is located between the frustum planes\r\n     */\r\n    public static IsPointInFrustum(point: Vector3, frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        for (let i = 0; i < 6; i++) {\r\n            if (frustumPlanes[i].dotCoordinate(point) < 0) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n}\r\n","/**\r\n * Helper class used to generate session unique ID\r\n */\r\nexport class UniqueIdGenerator {\r\n    // Statics\r\n    private static _UniqueIdCounter = 1;\r\n\r\n    /**\r\n     * Gets an unique (relatively to the current scene) Id\r\n     */\r\n    public static get UniqueId() {\r\n        const result = this._UniqueIdCounter;\r\n        this._UniqueIdCounter++;\r\n        return result;\r\n    }\r\n}\r\n","/** Defines the cross module constantsused by lights to avoid circular dependencies */\r\nexport class LightConstants {\r\n    /**\r\n     * Falloff Default: light is falling off following the material specification:\r\n     * standard material is using standard falloff whereas pbr material can request special falloff per materials.\r\n     */\r\n    public static readonly FALLOFF_DEFAULT = 0;\r\n\r\n    /**\r\n     * Falloff Physical: light is falling off following the inverse squared distance law.\r\n     */\r\n    public static readonly FALLOFF_PHYSICAL = 1;\r\n\r\n    /**\r\n     * Falloff gltf: light is falling off as described in the gltf moving to PBR document\r\n     * to enhance interoperability with other engines.\r\n     */\r\n    public static readonly FALLOFF_GLTF = 2;\r\n\r\n    /**\r\n     * Falloff Standard: light is falling off like in the standard material\r\n     * to enhance interoperability with other materials.\r\n     */\r\n    public static readonly FALLOFF_STANDARD = 3;\r\n\r\n    //lightmapMode Consts\r\n    /**\r\n     * If every light affecting the material is in this lightmapMode,\r\n     * material.lightmapTexture adds or multiplies\r\n     * (depends on material.useLightmapAsShadowmap)\r\n     * after every other light calculations.\r\n     */\r\n    public static readonly LIGHTMAP_DEFAULT = 0;\r\n    /**\r\n     * material.lightmapTexture as only diffuse lighting from this light\r\n     * adds only specular lighting from this light\r\n     * adds dynamic shadows\r\n     */\r\n    public static readonly LIGHTMAP_SPECULAR = 1;\r\n    /**\r\n     * material.lightmapTexture as only lighting\r\n     * no light calculation from this light\r\n     * only adds dynamic shadows from this light\r\n     */\r\n    public static readonly LIGHTMAP_SHADOWSONLY = 2;\r\n\r\n    // Intensity Mode Consts\r\n    /**\r\n     * Each light type uses the default quantity according to its type:\r\n     *      point/spot lights use luminous intensity\r\n     *      directional lights use illuminance\r\n     */\r\n    public static readonly INTENSITYMODE_AUTOMATIC = 0;\r\n    /**\r\n     * lumen (lm)\r\n     */\r\n    public static readonly INTENSITYMODE_LUMINOUSPOWER = 1;\r\n    /**\r\n     * candela (lm/sr)\r\n     */\r\n    public static readonly INTENSITYMODE_LUMINOUSINTENSITY = 2;\r\n    /**\r\n     * lux (lm/m^2)\r\n     */\r\n    public static readonly INTENSITYMODE_ILLUMINANCE = 3;\r\n    /**\r\n     * nit (cd/m^2)\r\n     */\r\n    public static readonly INTENSITYMODE_LUMINANCE = 4;\r\n\r\n    // Light types ids const.\r\n    /**\r\n     * Light type const id of the point light.\r\n     */\r\n    public static readonly LIGHTTYPEID_POINTLIGHT = 0;\r\n    /**\r\n     * Light type const id of the directional light.\r\n     */\r\n    public static readonly LIGHTTYPEID_DIRECTIONALLIGHT = 1;\r\n    /**\r\n     * Light type const id of the spot light.\r\n     */\r\n    public static readonly LIGHTTYPEID_SPOTLIGHT = 2;\r\n    /**\r\n     * Light type const id of the hemispheric light.\r\n     */\r\n    public static readonly LIGHTTYPEID_HEMISPHERICLIGHT = 3;\r\n\r\n    /**\r\n     * Light type const id of the area light.\r\n     */\r\n    public static readonly LIGHTTYPEID_RECT_AREALIGHT = 4;\r\n\r\n    /**\r\n     * Light type const id of the clustered light.\r\n     */\r\n    public static readonly LIGHTTYPEID_CLUSTERED_CONTAINER = 5;\r\n\r\n    /**\r\n     * Sort function to order lights for rendering.\r\n     * @param a First Light object to compare to second.\r\n     * @param b Second Light object to compare first.\r\n     * @returns -1 to reduce's a's index relative to be, 0 for no change, 1 to increase a's index relative to b.\r\n     */\r\n    public static CompareLightsPriority(a: ISortableLight, b: ISortableLight): number {\r\n        //shadow-casting lights have priority over non-shadow-casting lights\r\n        //the renderPriority is a secondary sort criterion\r\n        if (a.shadowEnabled !== b.shadowEnabled) {\r\n            return (b.shadowEnabled ? 1 : 0) - (a.shadowEnabled ? 1 : 0);\r\n        }\r\n        return b.renderPriority - a.renderPriority;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines the common interface of sortable lights\r\n */\r\nexport interface ISortableLight {\r\n    /**\r\n     * Gets or sets whether or not the shadows are enabled for this light. This can help turning off/on shadow without detaching\r\n     * the current shadow generator.\r\n     */\r\n    shadowEnabled: boolean;\r\n    /**\r\n     * Defines the rendering priority of the lights. It can help in case of fallback or number of lights\r\n     * exceeding the number allowed of the materials.\r\n     */\r\n    renderPriority: number;\r\n}\r\n","import { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * Class used to store configuration data associated with pointer picking\r\n */\r\nexport class PointerPickingConfiguration {\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer down event\r\n     */\r\n    public pointerDownPredicate: (Mesh: AbstractMesh) => boolean;\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer up event\r\n     */\r\n    public pointerUpPredicate: (Mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer move event\r\n     */\r\n    public pointerMovePredicate: (Mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer down event\r\n     */\r\n    public pointerDownFastCheck = false;\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer up event\r\n     */\r\n    public pointerUpFastCheck = false;\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer move event\r\n     */\r\n    public pointerMoveFastCheck = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer move event occurs.\r\n     */\r\n    public skipPointerMovePicking = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer down event occurs.\r\n     */\r\n    public skipPointerDownPicking = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer up event occurs.  Off by default.\r\n     */\r\n    public skipPointerUpPicking = false;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type Nullable } from \"./types\";\r\nimport { Tools } from \"./Misc/tools.pure\";\r\nimport { TimingTools, _RetryWithInterval } from \"./Misc/timingTools\";\r\nimport { type IAnimatable } from \"./Animations/animatable.interface\";\r\nimport { PrecisionDate } from \"./Misc/precisionDate\";\r\nimport { type Observer, Observable } from \"./Misc/observable.pure\";\r\nimport { type ISmartArrayLike, SmartArrayNoDuplicate, SmartArray } from \"./Misc/smartArray\";\r\nimport { StringDictionary } from \"./Misc/stringDictionary\";\r\nimport { Tags } from \"./Misc/tags\";\r\nimport { type Vector2, Vector3, Vector4, Matrix } from \"./Maths/math.vector.pure\";\r\nimport { type IParticleSystem } from \"./Particles/IParticleSystem\";\r\nimport { ImageProcessingConfiguration } from \"./Materials/imageProcessingConfiguration.pure\";\r\nimport { UniformBuffer } from \"./Materials/uniformBuffer\";\r\nimport { PickingInfo } from \"./Collisions/pickingInfo\";\r\nimport { type ICollisionCoordinator } from \"./Collisions/collisionCoordinator.pure\";\r\nimport { type PointerEventTypes, type PointerInfoPre, type PointerInfo } from \"./Events/pointerEvents\";\r\nimport { type KeyboardInfoPre, type KeyboardInfo } from \"./Events/keyboardEvents\";\r\nimport { ActionEvent } from \"./Actions/actionEvent\";\r\nimport { PostProcessManager } from \"./PostProcesses/postProcessManager\";\r\nimport { type IOfflineProvider } from \"./Offline/IOfflineProvider\";\r\nimport { FloatingOriginCurrentScene, OverrideMatrixFunctions, ResetMatrixFunctions } from \"./Materials/floatingOriginMatrixOverrides\";\r\nimport { type RenderingGroupInfo, type IRenderingManagerAutoClearSetup, RenderingManager } from \"./Rendering/renderingManager\";\r\nimport {\r\n    type ISceneComponent,\r\n    type ISceneSerializableComponent,\r\n    type SimpleStageAction,\r\n    type RenderTargetsStageAction,\r\n    type RenderTargetStageAction,\r\n    type MeshStageAction,\r\n    type EvaluateSubMeshStageAction,\r\n    type PreActiveMeshStageAction,\r\n    type CameraStageAction,\r\n    type RenderingGroupStageAction,\r\n    type RenderingMeshStageAction,\r\n    type PointerMoveStageAction,\r\n    type PointerUpDownStageAction,\r\n    type CameraStageFrameBufferAction,\r\n    Stage,\r\n} from \"./sceneComponent\";\r\nimport { Constants } from \"./Engines/constants\";\r\nimport { IsWindowObjectExist } from \"./Misc/domManagement\";\r\nimport { EngineStore } from \"./Engines/engineStore\";\r\nimport { type AbstractActionManager } from \"./Actions/abstractActionManager\";\r\nimport { _WarnImport, _IsSideEffectImplemented, _MissingSideEffect, _MissingSideEffectProperty } from \"./Misc/devTools\";\r\nimport { type WebRequest } from \"./Misc/webRequest\";\r\nimport { InputManager } from \"./Inputs/scene.inputManager\";\r\nimport { PerfCounter } from \"./Misc/perfCounter\";\r\nimport { type IFileRequest } from \"./Misc/fileRequest\";\r\nimport { Color4, Color3 } from \"./Maths/math.color.pure\";\r\nimport { type Plane } from \"./Maths/math.plane\";\r\nimport { Frustum } from \"./Maths/math.frustum\";\r\nimport { UniqueIdGenerator } from \"./Misc/uniqueIdGenerator\";\r\nimport { type LoadFileError, type RequestFileError, type ReadFileError, ReadFile, RequestFile, LoadFile } from \"./Misc/fileTools.pure\";\r\nimport { type IClipPlanesHolder } from \"./Misc/interfaces/iClipPlanesHolder\";\r\nimport { type IPointerEvent } from \"./Events/deviceInputEvents\";\r\nimport { LightConstants } from \"./Lights/lightConstants\";\r\nimport { _ObserveArray } from \"./Misc/arrayTools\";\r\nimport { type IAction } from \"./Actions/action.pure\";\r\nimport { type AnimationPropertiesOverride } from \"./Animations/animationPropertiesOverride\";\r\nimport { type AnimationGroup } from \"./Animations/animationGroup.pure\";\r\nimport { type Skeleton } from \"./Bones/skeleton\";\r\nimport { type Bone } from \"./Bones/bone.pure\";\r\nimport { type Camera } from \"./Cameras/camera.pure\";\r\nimport { type Collider } from \"./Collisions/collider\";\r\nimport { type Ray, type MeshPredicate, type TrianglePickingPredicate } from \"./Culling/ray.core\";\r\nimport { type Light } from \"./Lights/light\";\r\nimport { type PerformanceViewerCollector } from \"./Misc/PerformanceViewer/performanceViewerCollector\";\r\nimport { type MorphTarget } from \"./Morph/morphTarget\";\r\nimport { type MorphTargetManager } from \"./Morph/morphTargetManager\";\r\nimport { type PostProcess } from \"./PostProcesses/postProcess.pure\";\r\nimport { type Material } from \"./Materials/material.pure\";\r\nimport { type BaseTexture } from \"./Materials/Textures/baseTexture.pure\";\r\nimport { type Geometry } from \"./Meshes/geometry\";\r\nimport { type TransformNode } from \"./Meshes/transformNode.pure\";\r\nimport { type AbstractMesh } from \"./Meshes/abstractMesh.pure\";\r\nimport { type MultiMaterial } from \"./Materials/multiMaterial.pure\";\r\nimport { type Effect } from \"./Materials/effect.pure\";\r\nimport { type RenderTargetTexture } from \"./Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Mesh } from \"./Meshes/mesh.pure\";\r\nimport { type SubMesh } from \"./Meshes/subMesh.pure\";\r\nimport { type Node } from \"./node\";\r\nimport { type Animation } from \"./Animations/animation.pure\";\r\nimport { type Animatable } from \"./Animations/animatable.core\";\r\nimport { type IRuntimeAnimationWrite } from \"./Animations/runtimeAnimation\";\r\nimport { type Texture } from \"./Materials/Textures/texture.pure\";\r\nimport { PointerPickingConfiguration } from \"./Inputs/pointerPickingConfiguration\";\r\nimport { Logger } from \"./Misc/logger\";\r\nimport { type AbstractEngine } from \"./Engines/abstractEngine.pure\";\r\nimport { type FrameGraph } from \"./FrameGraph/frameGraph\";\r\nimport { type IAssetContainer } from \"./IAssetContainer\";\r\n\r\nimport { type EffectLayer } from \"./Layers/effectLayer\";\r\nimport { type Sound } from \"./Audio/sound.pure\";\r\nimport { type Layer } from \"./Layers/layer\";\r\nimport { type LensFlareSystem } from \"./LensFlares/lensFlareSystem\";\r\nimport { type ProceduralTexture } from \"./Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type FrameGraphObjectRendererTask } from \"./FrameGraph/Tasks/Rendering/objectRendererTask\";\r\nimport { type ObjectRenderer } from \"./Rendering/objectRenderer\";\r\nimport { type BoundingBoxRenderer } from \"./Rendering/boundingBoxRenderer.pure\";\r\nimport { type BoundingBox } from \"./Culling/boundingBox\";\r\nimport { RegisterClass } from \"./Misc/typeStore\";\r\n\r\n/**\r\n * Options for creating a scene uniform buffer\r\n */\r\nexport interface ICreateSceneUboOptions {\r\n    /** Define if the UBOs should be tracked in the frame (default: undefined - will use the value from Engine._features.trackUbosInFrame) */\r\n    trackUBOsInFrame?: boolean;\r\n    /** When true, always creates a mono (non-multiview) UBO, bypassing any multiview override */\r\n    forceMono?: boolean;\r\n}\r\n\r\n/**\r\n * Define an interface for all classes that will hold resources\r\n */\r\nexport interface IDisposable {\r\n    /**\r\n     * Releases all held resources\r\n     */\r\n    dispose(): void;\r\n}\r\n\r\n// Defining Temps for the file to avoid misuse of shared TmpVectors\r\nconst TempVect1 = /*#__PURE__*/ new Vector4();\r\nconst TempVect2 = /*#__PURE__*/ new Vector4();\r\n\r\n/** Interface defining initialization parameters for Scene class */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SceneOptions {\r\n    /**\r\n     * Defines that scene should keep up-to-date a map of geometry to enable fast look-up by uniqueId\r\n     * It will improve performance when the number of geometries becomes important.\r\n     */\r\n    useGeometryUniqueIdsMap?: boolean;\r\n\r\n    /**\r\n     * Defines that each material of the scene should keep up-to-date a map of referencing meshes for fast disposing\r\n     * It will improve performance when the number of mesh becomes important, but might consume a bit more memory\r\n     */\r\n    useMaterialMeshMap?: boolean;\r\n\r\n    /**\r\n     * Defines that each mesh of the scene should keep up-to-date a map of referencing cloned meshes for fast disposing\r\n     * It will improve performance when the number of mesh becomes important, but might consume a bit more memory\r\n     */\r\n    useClonedMeshMap?: boolean;\r\n\r\n    /**\r\n     * When enabled, the scene can handle large world coordinate rendering without jittering caused by floating point imprecision on the GPU.\r\n     * This mode offsets matrices and position-related attribute values before passing to shaders, centering camera at origin and offsetting other scene objects by camera active position.\r\n     *\r\n     * IMPORTANT: Only use this scene-level option if you intend to enable floating origin on a per-scene basis. Must use in conjunction with engine creation option 'useHighPrecisionMatrix' to fix CPU-side floating point imprecision.\r\n     * HOWEVER if you want largeWorldRendering on ALL scenes, set the useLargeWorldRendering flag on the engine instead of this scene-level flag. Doing so will automatically set useHighPrecisionMatrix on the engine as well.\r\n     */\r\n    useFloatingOrigin?: boolean;\r\n\r\n    /** Defines if the creation of the scene should impact the engine (Eg. UtilityLayer's scene) */\r\n    virtual?: boolean;\r\n\r\n    /**\r\n     * Defines the default layerMask used when creating cameras in the scene (default: 0x0fffffff)\r\n     */\r\n    defaultCameraLayerMask?: number;\r\n\r\n    /**\r\n     * Defines the default layerMask used when creating renderable objects in the scene (default: 0x0fffffff)\r\n     */\r\n    defaultRenderableLayerMask?: number;\r\n}\r\n\r\n/**\r\n * Define how the scene should favor performance over ease of use\r\n */\r\nexport const enum ScenePerformancePriority {\r\n    /** Default mode. No change. Performance will be treated as less important than backward compatibility */\r\n    BackwardCompatible,\r\n    /** Some performance options will be turned on trying to strike a balance between perf and ease of use */\r\n    Intermediate,\r\n    /** Performance will be top priority */\r\n    Aggressive,\r\n}\r\n\r\n/**\r\n * Represents a scene to be rendered by the engine.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene\r\n */\r\nexport class Scene implements IAnimatable, IClipPlanesHolder, IAssetContainer {\r\n    /** The fog is deactivated */\r\n    public static readonly FOGMODE_NONE = Constants.FOGMODE_NONE;\r\n    /** The fog density is following an exponential function */\r\n    public static readonly FOGMODE_EXP = Constants.FOGMODE_EXP;\r\n    /** The fog density is following an exponential function faster than FOGMODE_EXP */\r\n    public static readonly FOGMODE_EXP2 = Constants.FOGMODE_EXP2;\r\n    /** The fog density is following a linear function. */\r\n    public static readonly FOGMODE_LINEAR = Constants.FOGMODE_LINEAR;\r\n\r\n    /**\r\n     * Gets or sets the minimum deltatime when deterministic lock step is enabled\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     */\r\n    public static MinDeltaTime = 1.0;\r\n    /**\r\n     * Gets or sets the maximum deltatime when deterministic lock step is enabled\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     */\r\n    public static MaxDeltaTime = 1000.0;\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Factory used to create the default material.\r\n     * @param scene The scene to create the material for\r\n     * @returns The default material\r\n     */\r\n    public static DefaultMaterialFactory(scene: Scene): Material {\r\n        throw _WarnImport(\"StandardMaterial\");\r\n    }\r\n\r\n    private static readonly _OriginalDefaultMaterialFactory = Scene.DefaultMaterialFactory;\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Factory used to create the a collision coordinator.\r\n     * @returns The collision coordinator\r\n     */\r\n    public static CollisionCoordinatorFactory(): ICollisionCoordinator {\r\n        throw _WarnImport(\"DefaultCollisionCoordinator\");\r\n    }\r\n\r\n    // Members\r\n\r\n    /** @internal */\r\n    public _tempPickingRay: Nullable<Ray>;\r\n\r\n    /** @internal */\r\n    public _cachedRayForTransform: Ray;\r\n\r\n    /** @internal */\r\n    public _pickWithRayInverseMatrix: Matrix;\r\n\r\n    /** @internal */\r\n    public _inputManager = new InputManager(this);\r\n\r\n    /** Define this parameter if you are using multiple cameras and you want to specify which one should be used for pointer position */\r\n    public cameraToUseForPointers: Nullable<Camera> = null;\r\n\r\n    /** @internal */\r\n    public readonly _isScene = true;\r\n\r\n    /** @internal */\r\n    public _blockEntityCollection = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean that indicates if the scene must clear the render buffer before rendering a frame\r\n     */\r\n    public autoClear = true;\r\n    /**\r\n     * Gets or sets a boolean that indicates if the scene must clear the depth and stencil buffers before rendering a frame\r\n     */\r\n    public autoClearDepthAndStencil = true;\r\n\r\n    private _clearColor: Color4 = new Color4(0.2, 0.2, 0.3, 1.0);\r\n\r\n    /**\r\n     * Observable triggered when the performance priority is changed\r\n     */\r\n    public onClearColorChangedObservable = new Observable<Color4>();\r\n\r\n    /**\r\n     * Defines the color used to clear the render buffer (Default is (0.2, 0.2, 0.3, 1.0))\r\n     */\r\n    public get clearColor(): Color4 {\r\n        return this._clearColor;\r\n    }\r\n\r\n    public set clearColor(value: Color4) {\r\n        if (value !== this._clearColor) {\r\n            this._clearColor = value;\r\n            this.onClearColorChangedObservable.notifyObservers(this._clearColor);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the color used to simulate the ambient color (Default is (0, 0, 0))\r\n     */\r\n    public ambientColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * This is use to store the default BRDF lookup for PBR materials in your scene.\r\n     * It should only be one of the following (if not the default embedded one):\r\n     * * For uncorrelated BRDF (pbr.brdf.useEnergyConservation = false and pbr.brdf.useSmithVisibilityHeightCorrelated = false) : https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds\r\n     * * For correlated BRDF (pbr.brdf.useEnergyConservation = false and pbr.brdf.useSmithVisibilityHeightCorrelated = true) : https://assets.babylonjs.com/environments/correlatedBRDF.dds\r\n     * * For correlated multi scattering BRDF (pbr.brdf.useEnergyConservation = true and pbr.brdf.useSmithVisibilityHeightCorrelated = true) : https://assets.babylonjs.com/environments/correlatedMSBRDF.dds\r\n     * The material properties need to be setup according to the type of texture in use.\r\n     */\r\n    public environmentBRDFTexture: BaseTexture;\r\n\r\n    /**\r\n     * This stores the brdf lookup for the fuzz layer of PBR materials in your scene.\r\n     */\r\n    public environmentFuzzBRDFTexture: BaseTexture;\r\n\r\n    /**\r\n     * Intensity of the environment (i.e. all indirect lighting) in all pbr material.\r\n     * This dims or reinforces the indirect lighting overall (reflection and diffuse).\r\n     * As in the majority of the scene they are the same (exception for multi room and so on),\r\n     * this is easier to reference from here than from all the materials.\r\n     * Note that this is more of a debugging parameter and is not physically accurate.\r\n     * If you want to modify the intensity of the IBL texture, you should update iblIntensity instead.\r\n     */\r\n    public environmentIntensity: number = 1;\r\n\r\n    /**\r\n     * Overall intensity of the IBL texture.\r\n     * This value is multiplied with the reflectionTexture.level value to calculate the final IBL intensity.\r\n     */\r\n    public iblIntensity = 1;\r\n\r\n    /** @internal */\r\n    protected _imageProcessingConfiguration: ImageProcessingConfiguration;\r\n    /**\r\n     * Default image processing configuration used either in the rendering\r\n     * Forward main pass or through the imageProcessingPostProcess if present.\r\n     * As in the majority of the scene they are the same (exception for multi camera),\r\n     * this is easier to reference from here than from all the materials and post process.\r\n     *\r\n     * No setter as we it is a shared configuration, you can set the values instead.\r\n     */\r\n    public get imageProcessingConfiguration(): ImageProcessingConfiguration {\r\n        return this._imageProcessingConfiguration;\r\n    }\r\n\r\n    private _performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n\r\n    /**\r\n     * Observable triggered when the performance priority is changed\r\n     */\r\n    public onScenePerformancePriorityChangedObservable = new Observable<ScenePerformancePriority>();\r\n    /**\r\n     * Gets or sets a value indicating how to treat performance relatively to ease of use and backward compatibility\r\n     */\r\n    public get performancePriority() {\r\n        return this._performancePriority;\r\n    }\r\n\r\n    public set performancePriority(value) {\r\n        if (value === this._performancePriority) {\r\n            return;\r\n        }\r\n\r\n        this._performancePriority = value;\r\n\r\n        switch (value) {\r\n            case ScenePerformancePriority.BackwardCompatible:\r\n                this.skipFrustumClipping = false;\r\n                this._renderingManager.maintainStateBetweenFrames = false;\r\n                this.skipPointerMovePicking = false;\r\n                this.autoClear = true;\r\n                break;\r\n            case ScenePerformancePriority.Intermediate:\r\n                this.skipFrustumClipping = false;\r\n                this._renderingManager.maintainStateBetweenFrames = false;\r\n                this.skipPointerMovePicking = true;\r\n                this.autoClear = false;\r\n                break;\r\n            case ScenePerformancePriority.Aggressive:\r\n                this.skipFrustumClipping = true;\r\n                this._renderingManager.maintainStateBetweenFrames = true;\r\n                this.skipPointerMovePicking = true;\r\n                this.autoClear = false;\r\n                break;\r\n        }\r\n\r\n        this.onScenePerformancePriorityChangedObservable.notifyObservers(value);\r\n    }\r\n\r\n    private _forceWireframe = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if all rendering must be done in wireframe\r\n     */\r\n    public set forceWireframe(value: boolean) {\r\n        if (this._forceWireframe === value) {\r\n            return;\r\n        }\r\n        this._forceWireframe = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_MiscDirtyFlag);\r\n    }\r\n    public get forceWireframe(): boolean {\r\n        return this._forceWireframe;\r\n    }\r\n\r\n    private _skipFrustumClipping = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if we should skip the frustum clipping part of the active meshes selection\r\n     */\r\n    public set skipFrustumClipping(value: boolean) {\r\n        if (this._skipFrustumClipping === value) {\r\n            return;\r\n        }\r\n        this._skipFrustumClipping = value;\r\n    }\r\n    public get skipFrustumClipping(): boolean {\r\n        return this._skipFrustumClipping;\r\n    }\r\n\r\n    private _forcePointsCloud = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if all rendering must be done in point cloud\r\n     */\r\n    public set forcePointsCloud(value: boolean) {\r\n        if (this._forcePointsCloud === value) {\r\n            return;\r\n        }\r\n        this._forcePointsCloud = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_MiscDirtyFlag);\r\n    }\r\n    public get forcePointsCloud(): boolean {\r\n        return this._forcePointsCloud;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 1\r\n     */\r\n    public clipPlane: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 2\r\n     */\r\n    public clipPlane2: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 3\r\n     */\r\n    public clipPlane3: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 4\r\n     */\r\n    public clipPlane4: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 5\r\n     */\r\n    public clipPlane5: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 6\r\n     */\r\n    public clipPlane6: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets the list of root nodes (ie. nodes with no parent)\r\n     */\r\n    public rootNodes: Node[] = [];\r\n\r\n    /** All of the cameras added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n     */\r\n    public cameras: Camera[] = [];\r\n\r\n    /**\r\n     * All of the lights added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     */\r\n    public lights: Light[] = [];\r\n\r\n    /**\r\n     * All of the (abstract) meshes added to this scene\r\n     */\r\n    public meshes: AbstractMesh[] = [];\r\n\r\n    /**\r\n     * The list of skeletons added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n     */\r\n    public skeletons: Skeleton[] = [];\r\n\r\n    /**\r\n     * All of the particle systems added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro\r\n     */\r\n    public particleSystems: IParticleSystem[] = [];\r\n\r\n    /**\r\n     * Gets the current delta time used by animation engine\r\n     */\r\n    deltaTime: number;\r\n\r\n    /**\r\n     * Gets a list of Animations associated with the scene\r\n     */\r\n    public animations: Animation[] = [];\r\n\r\n    /**\r\n     * All of the animation groups added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/groupAnimations\r\n     */\r\n    public animationGroups: AnimationGroup[] = [];\r\n\r\n    /**\r\n     * All of the multi-materials added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials\r\n     */\r\n    public multiMaterials: MultiMaterial[] = [];\r\n\r\n    /**\r\n     * All of the materials added to this scene\r\n     * In the context of a Scene, it is not supposed to be modified manually.\r\n     * Any addition or removal should be done using the addMaterial and removeMaterial Scene methods.\r\n     * Note also that the order of the Material within the array is not significant and might change.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction\r\n     */\r\n    public materials: Material[] = [];\r\n\r\n    /**\r\n     * The list of morph target managers added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph\r\n     */\r\n    public morphTargetManagers: MorphTargetManager[] = [];\r\n\r\n    /**\r\n     * The list of geometries used in the scene.\r\n     */\r\n    public geometries: Geometry[] = [];\r\n\r\n    /**\r\n     * All of the transform nodes added to this scene\r\n     * In the context of a Scene, it is not supposed to be modified manually.\r\n     * Any addition or removal should be done using the addTransformNode and removeTransformNode Scene methods.\r\n     * Note also that the order of the TransformNode within the array is not significant and might change.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/parent_pivot/transform_node\r\n     */\r\n    public transformNodes: TransformNode[] = [];\r\n\r\n    /**\r\n     * ActionManagers available on the scene.\r\n     */\r\n    public actionManagers: AbstractActionManager[] = [];\r\n\r\n    /**\r\n     * Object renderers available on the scene.\r\n     */\r\n    public objectRenderers: ObjectRenderer[] = [];\r\n\r\n    /**\r\n     * Textures to keep.\r\n     */\r\n    public textures: BaseTexture[] = [];\r\n\r\n    /** @internal */\r\n    protected _environmentTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Texture used in all pbr material as the reflection texture.\r\n     * As in the majority of the scene they are the same (exception for multi room and so on),\r\n     * this is easier to reference from here than from all the materials.\r\n     */\r\n    public get environmentTexture(): Nullable<BaseTexture> {\r\n        return this._environmentTexture;\r\n    }\r\n    /**\r\n     * Texture used in all pbr material as the reflection texture.\r\n     * As in the majority of the scene they are the same (exception for multi room and so on),\r\n     * this is easier to set here than in all the materials.\r\n     */\r\n    public set environmentTexture(value: Nullable<BaseTexture>) {\r\n        if (this._environmentTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._environmentTexture = value;\r\n        this.onEnvironmentTextureChangedObservable.notifyObservers(value);\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * The list of postprocesses added to the scene\r\n     */\r\n    public postProcesses: PostProcess[] = [];\r\n\r\n    /**\r\n     * The list of effect layers (highlights/glow) added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/highlightLayer\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/glowLayer\r\n     */\r\n    public effectLayers: Array<EffectLayer> = [];\r\n\r\n    /**\r\n     * The list of sounds used in the scene.\r\n     * @deprecated please use AudioEngineV2 instead\r\n     */\r\n    public sounds: Nullable<Array<Sound>> = null;\r\n\r\n    /**\r\n     * The list of layers (background and foreground) of the scene\r\n     */\r\n    public layers: Array<Layer> = [];\r\n\r\n    /**\r\n     * The list of lens flare system added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n     */\r\n    public lensFlareSystems: Array<LensFlareSystem> = [];\r\n\r\n    /**\r\n     * The list of procedural textures added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/proceduralTextures\r\n     */\r\n    public proceduralTextures: Array<ProceduralTexture> = [];\r\n\r\n    /**\r\n     * @returns all meshes, lights, cameras, transformNodes and bones\r\n     */\r\n    public getNodes(): Array<Node> {\r\n        let nodes: Node[] = [];\r\n        nodes = nodes.concat(this.meshes);\r\n        nodes = nodes.concat(this.lights);\r\n        nodes = nodes.concat(this.cameras);\r\n        nodes = nodes.concat(this.transformNodes); // dummies\r\n        for (const skeleton of this.skeletons) {\r\n            nodes = nodes.concat(skeleton.bones);\r\n        }\r\n        return nodes;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if animations are enabled\r\n     */\r\n    public animationsEnabled = true;\r\n\r\n    private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;\r\n\r\n    /**\r\n     * Gets or sets the animation properties override\r\n     */\r\n    public get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n        return this._animationPropertiesOverride;\r\n    }\r\n\r\n    public set animationPropertiesOverride(value: Nullable<AnimationPropertiesOverride>) {\r\n        this._animationPropertiesOverride = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if a constant deltatime has to be used\r\n     * This is mostly useful for testing purposes when you do not want the animations to scale with the framerate\r\n     */\r\n    public useConstantAnimationDeltaTime = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if the scene must keep the meshUnderPointer property updated\r\n     * Please note that it requires to run a ray cast through the scene on every frame\r\n     */\r\n    public constantlyUpdateMeshUnderPointer = false;\r\n\r\n    /**\r\n     * Defines the HTML cursor to use when hovering over interactive elements\r\n     */\r\n    public hoverCursor = \"pointer\";\r\n    /**\r\n     * Defines the HTML default cursor to use (empty by default)\r\n     */\r\n    public defaultCursor: string = \"\";\r\n    /**\r\n     * Defines whether cursors are handled by the scene.\r\n     */\r\n    public doNotHandleCursors = false;\r\n    /**\r\n     * This is used to call preventDefault() on pointer down\r\n     * in order to block unwanted artifacts like system double clicks\r\n     */\r\n    public preventDefaultOnPointerDown = true;\r\n\r\n    /**\r\n     * This is used to call preventDefault() on pointer up\r\n     * in order to block unwanted artifacts like system double clicks\r\n     */\r\n    public preventDefaultOnPointerUp = true;\r\n\r\n    // Metadata\r\n    /**\r\n     * Gets or sets user defined metadata\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /**\r\n     * For internal use only. Please do not use.\r\n     */\r\n    public reservedDataStore: any = null;\r\n\r\n    /**\r\n     * Gets the name of the plugin used to load this scene (null by default)\r\n     */\r\n    public loadingPluginName: string;\r\n\r\n    /**\r\n     * Use this array to add regular expressions used to disable offline support for specific urls\r\n     */\r\n    public disableOfflineSupportExceptionRules: RegExp[] = [];\r\n\r\n    /**\r\n     * An event triggered when the scene is disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<Scene>();\r\n\r\n    private _onDisposeObserver: Nullable<Observer<Scene>> = null;\r\n    /** Sets a function to be executed when this scene is disposed. */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered before rendering the scene (right after animations and physics)\r\n     */\r\n    public onBeforeRenderObservable = new Observable<Scene>();\r\n\r\n    private _onBeforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n    /** Sets a function to be executed before rendering this scene */\r\n    public set beforeRender(callback: Nullable<() => void>) {\r\n        if (this._onBeforeRenderObserver) {\r\n            this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n        }\r\n        if (callback) {\r\n            this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * An event triggered after rendering the scene\r\n     */\r\n    public onAfterRenderObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered after rendering the scene for an active camera (When scene.render is called this will be called after each camera)\r\n     * This is triggered for each \"sub\" camera in a Camera Rig unlike onAfterCameraRenderObservable\r\n     */\r\n    public onAfterRenderCameraObservable = new Observable<Camera>();\r\n\r\n    private _onAfterRenderObserver: Nullable<Observer<Scene>> = null;\r\n    /** Sets a function to be executed after rendering this scene */\r\n    public set afterRender(callback: Nullable<() => void>) {\r\n        if (this._onAfterRenderObserver) {\r\n            this.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n        }\r\n\r\n        if (callback) {\r\n            this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * An event triggered before animating the scene\r\n     */\r\n    public onBeforeAnimationsObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered after animations processing\r\n     */\r\n    public onAfterAnimationsObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered before draw calls are ready to be sent\r\n     */\r\n    public onBeforeDrawPhaseObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered after draw calls have been sent\r\n     */\r\n    public onAfterDrawPhaseObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when the scene is ready\r\n     */\r\n    public onReadyObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered before rendering a camera\r\n     */\r\n    public onBeforeCameraRenderObservable = new Observable<Camera>();\r\n\r\n    private _onBeforeCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n    /** Sets a function to be executed before rendering a camera*/\r\n    public set beforeCameraRender(callback: () => void) {\r\n        if (this._onBeforeCameraRenderObserver) {\r\n            this.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);\r\n        }\r\n\r\n        this._onBeforeCameraRenderObserver = this.onBeforeCameraRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered after rendering a camera\r\n     * This is triggered for the full rig Camera only unlike onAfterRenderCameraObservable\r\n     */\r\n    public onAfterCameraRenderObservable = new Observable<Camera>();\r\n\r\n    private _onAfterCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n    /** Sets a function to be executed after rendering a camera*/\r\n    public set afterCameraRender(callback: () => void) {\r\n        if (this._onAfterCameraRenderObserver) {\r\n            this.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);\r\n        }\r\n        this._onAfterCameraRenderObserver = this.onAfterCameraRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when active meshes evaluation is about to start\r\n     */\r\n    public onBeforeActiveMeshesEvaluationObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when active meshes evaluation is done\r\n     */\r\n    public onAfterActiveMeshesEvaluationObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when particles rendering is about to start\r\n     * Note: This event can be trigger more than once per frame (because particles can be rendered by render target textures as well)\r\n     */\r\n    public onBeforeParticlesRenderingObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when particles rendering is done\r\n     * Note: This event can be trigger more than once per frame (because particles can be rendered by render target textures as well)\r\n     */\r\n    public onAfterParticlesRenderingObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when SceneLoader.Append or SceneLoader.Load or SceneLoader.ImportMesh were successfully executed\r\n     */\r\n    public onDataLoadedObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when a camera is created\r\n     */\r\n    public onNewCameraAddedObservable = new Observable<Camera>();\r\n\r\n    /**\r\n     * An event triggered when a camera is removed\r\n     */\r\n    public onCameraRemovedObservable = new Observable<Camera>();\r\n\r\n    /**\r\n     * An event triggered when a light is created\r\n     */\r\n    public onNewLightAddedObservable = new Observable<Light>();\r\n\r\n    /**\r\n     * An event triggered when a light is removed\r\n     */\r\n    public onLightRemovedObservable = new Observable<Light>();\r\n\r\n    /**\r\n     * An event triggered when a geometry is created\r\n     */\r\n    public onNewGeometryAddedObservable = new Observable<Geometry>();\r\n\r\n    /**\r\n     * An event triggered when a geometry is removed\r\n     */\r\n    public onGeometryRemovedObservable = new Observable<Geometry>();\r\n\r\n    /**\r\n     * An event triggered when a transform node is created\r\n     */\r\n    public onNewTransformNodeAddedObservable = new Observable<TransformNode>();\r\n\r\n    /**\r\n     * An event triggered when a transform node is removed\r\n     */\r\n    public onTransformNodeRemovedObservable = new Observable<TransformNode>();\r\n\r\n    /**\r\n     * An event triggered when a mesh is created\r\n     */\r\n    public onNewMeshAddedObservable = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * An event triggered when a mesh is removed\r\n     */\r\n    public onMeshRemovedObservable = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * An event triggered when a skeleton is created\r\n     */\r\n    public onNewSkeletonAddedObservable = new Observable<Skeleton>();\r\n\r\n    /**\r\n     * An event triggered when a skeleton is removed\r\n     */\r\n    public onSkeletonRemovedObservable = new Observable<Skeleton>();\r\n\r\n    /**\r\n     * An event triggered when a particle system is created\r\n     */\r\n    public onNewParticleSystemAddedObservable = new Observable<IParticleSystem>();\r\n\r\n    /**\r\n     * An event triggered when a particle system is removed\r\n     */\r\n    public onParticleSystemRemovedObservable = new Observable<IParticleSystem>();\r\n\r\n    /**\r\n     * An event triggered when an animation group is created\r\n     */\r\n    public onNewAnimationGroupAddedObservable = new Observable<AnimationGroup>();\r\n\r\n    /**\r\n     * An event triggered when an animation group is removed\r\n     */\r\n    public onAnimationGroupRemovedObservable = new Observable<AnimationGroup>();\r\n\r\n    /**\r\n     * An event triggered when a material is created\r\n     */\r\n    public onNewMaterialAddedObservable = new Observable<Material>();\r\n\r\n    /**\r\n     * An event triggered when a multi material is created\r\n     */\r\n    public onNewMultiMaterialAddedObservable = new Observable<MultiMaterial>();\r\n\r\n    /**\r\n     * An event triggered when a material is removed\r\n     */\r\n    public onMaterialRemovedObservable = new Observable<Material>();\r\n\r\n    /**\r\n     * An event triggered when a multi material is removed\r\n     */\r\n    public onMultiMaterialRemovedObservable = new Observable<MultiMaterial>();\r\n\r\n    /**\r\n     * An event triggered when a texture is created\r\n     */\r\n    public onNewTextureAddedObservable = new Observable<BaseTexture>();\r\n\r\n    /**\r\n     * An event triggered when a texture is removed\r\n     */\r\n    public onTextureRemovedObservable = new Observable<BaseTexture>();\r\n\r\n    /**\r\n     * An event triggered when a frame graph is created\r\n     */\r\n    public onNewFrameGraphAddedObservable = new Observable<FrameGraph>();\r\n\r\n    /**\r\n     * An event triggered when a frame graph is removed\r\n     */\r\n    public onFrameGraphRemovedObservable = new Observable<FrameGraph>();\r\n\r\n    /**\r\n     * An event triggered when an object renderer is created\r\n     */\r\n    public onNewObjectRendererAddedObservable = new Observable<ObjectRenderer>();\r\n\r\n    /**\r\n     * An event triggered when an object renderer is removed\r\n     */\r\n    public onObjectRendererRemovedObservable = new Observable<ObjectRenderer>();\r\n\r\n    /**\r\n     * An event triggered when a post process is created\r\n     */\r\n    public onNewPostProcessAddedObservable = new Observable<PostProcess>();\r\n\r\n    /**\r\n     * An event triggered when a post process is removed\r\n     */\r\n    public onPostProcessRemovedObservable = new Observable<PostProcess>();\r\n\r\n    /**\r\n     * An event triggered when an effect layer is created\r\n     */\r\n    public onNewEffectLayerAddedObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when an effect layer is removed\r\n     */\r\n    public onEffectLayerRemovedObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when render targets are about to be rendered\r\n     * Can happen multiple times per frame.\r\n     */\r\n    public onBeforeRenderTargetsRenderObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when render targets were rendered.\r\n     * Can happen multiple times per frame.\r\n     */\r\n    public onAfterRenderTargetsRenderObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered before calculating deterministic simulation step\r\n     */\r\n    public onBeforeStepObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered after calculating deterministic simulation step\r\n     */\r\n    public onAfterStepObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when the activeCamera property is updated\r\n     */\r\n    public onActiveCameraChanged = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when the activeCameras property is updated\r\n     */\r\n    public onActiveCamerasChanged = new Observable<Scene>();\r\n\r\n    /**\r\n     * This Observable will be triggered before rendering each renderingGroup of each rendered camera.\r\n     * The RenderingGroupInfo class contains all the information about the context in which the observable is called\r\n     * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)\r\n     */\r\n    public onBeforeRenderingGroupObservable = new Observable<RenderingGroupInfo>();\r\n\r\n    /**\r\n     * This Observable will be triggered after rendering each renderingGroup of each rendered camera.\r\n     * The RenderingGroupInfo class contains all the information about the context in which the observable is called\r\n     * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)\r\n     */\r\n    public onAfterRenderingGroupObservable = new Observable<RenderingGroupInfo>();\r\n\r\n    /**\r\n     * This Observable will when a mesh has been imported into the scene.\r\n     */\r\n    public onMeshImportedObservable = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * This Observable will when an animation file has been imported into the scene.\r\n     */\r\n    public onAnimationFileImportedObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * An event triggered when the environmentTexture is changed.\r\n     */\r\n    public onEnvironmentTextureChangedObservable = new Observable<Nullable<BaseTexture>>();\r\n\r\n    /**\r\n     * An event triggered when the state of mesh under pointer, for a specific pointerId, changes.\r\n     */\r\n    public onMeshUnderPointerUpdatedObservable = new Observable<{ mesh: Nullable<AbstractMesh>; pointerId: number }>();\r\n\r\n    /**\r\n     * Gets or sets a user defined funtion to select LOD from a mesh and a camera.\r\n     * By default this function is undefined and Babylon.js will select LOD based on distance to camera\r\n     */\r\n    public customLODSelector: (mesh: AbstractMesh, camera: Camera) => Nullable<AbstractMesh>;\r\n\r\n    // Animations\r\n\r\n    /** @internal */\r\n    public _registeredForLateAnimationBindings = new SmartArrayNoDuplicate<any>(256);\r\n\r\n    // Pointers\r\n    private _pointerPickingConfiguration = new PointerPickingConfiguration();\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer down event\r\n     */\r\n    public get pointerDownPredicate() {\r\n        return this._pointerPickingConfiguration.pointerDownPredicate;\r\n    }\r\n\r\n    public set pointerDownPredicate(value) {\r\n        this._pointerPickingConfiguration.pointerDownPredicate = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer up event\r\n     */\r\n    public get pointerUpPredicate() {\r\n        return this._pointerPickingConfiguration.pointerUpPredicate;\r\n    }\r\n\r\n    public set pointerUpPredicate(value) {\r\n        this._pointerPickingConfiguration.pointerUpPredicate = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer move event\r\n     */\r\n    public get pointerMovePredicate() {\r\n        return this._pointerPickingConfiguration.pointerMovePredicate;\r\n    }\r\n\r\n    public set pointerMovePredicate(value) {\r\n        this._pointerPickingConfiguration.pointerMovePredicate = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer down event\r\n     */\r\n    public get pointerDownFastCheck() {\r\n        return this._pointerPickingConfiguration.pointerDownFastCheck;\r\n    }\r\n\r\n    public set pointerDownFastCheck(value) {\r\n        this._pointerPickingConfiguration.pointerDownFastCheck = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer up event\r\n     */\r\n    public get pointerUpFastCheck() {\r\n        return this._pointerPickingConfiguration.pointerUpFastCheck;\r\n    }\r\n\r\n    public set pointerUpFastCheck(value) {\r\n        this._pointerPickingConfiguration.pointerUpFastCheck = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate meshes for a pointer move event\r\n     */\r\n    public get pointerMoveFastCheck() {\r\n        return this._pointerPickingConfiguration.pointerMoveFastCheck;\r\n    }\r\n\r\n    public set pointerMoveFastCheck(value) {\r\n        this._pointerPickingConfiguration.pointerMoveFastCheck = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer move event occurs.\r\n     */\r\n    public get skipPointerMovePicking() {\r\n        return this._pointerPickingConfiguration.skipPointerMovePicking;\r\n    }\r\n\r\n    public set skipPointerMovePicking(value) {\r\n        this._pointerPickingConfiguration.skipPointerMovePicking = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer down event occurs.\r\n     */\r\n    public get skipPointerDownPicking() {\r\n        return this._pointerPickingConfiguration.skipPointerDownPicking;\r\n    }\r\n\r\n    public set skipPointerDownPicking(value) {\r\n        this._pointerPickingConfiguration.skipPointerDownPicking = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer up event occurs.  Off by default.\r\n     */\r\n    public get skipPointerUpPicking() {\r\n        return this._pointerPickingConfiguration.skipPointerUpPicking;\r\n    }\r\n\r\n    public set skipPointerUpPicking(value) {\r\n        this._pointerPickingConfiguration.skipPointerUpPicking = value;\r\n    }\r\n\r\n    /** Callback called when a pointer move is detected */\r\n    public onPointerMove?: (evt: IPointerEvent, pickInfo: PickingInfo, type: PointerEventTypes) => void;\r\n    /** Callback called when a pointer down is detected  */\r\n    public onPointerDown?: (evt: IPointerEvent, pickInfo: PickingInfo, type: PointerEventTypes) => void;\r\n    /** Callback called when a pointer up is detected  */\r\n    public onPointerUp?: (evt: IPointerEvent, pickInfo: Nullable<PickingInfo>, type: PointerEventTypes) => void;\r\n    /** Callback called when a pointer pick is detected */\r\n    public onPointerPick?: (evt: IPointerEvent, pickInfo: PickingInfo) => void;\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate faces for a pointer move event\r\n     */\r\n    public pointerMoveTrianglePredicate: ((p0: Vector3, p1: Vector3, p2: Vector3, ray: Ray) => boolean) | undefined;\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate faces for a pointer down event\r\n     */\r\n    public pointerDownTrianglePredicate: ((p0: Vector3, p1: Vector3, p2: Vector3, ray: Ray) => boolean) | undefined;\r\n\r\n    /**\r\n     * Gets or sets a predicate used to select candidate faces for a pointer up event\r\n     */\r\n    public pointerUpTrianglePredicate: ((p0: Vector3, p1: Vector3, p2: Vector3, ray: Ray) => boolean) | undefined;\r\n\r\n    /**\r\n     * This observable event is triggered when any ponter event is triggered. It is registered during Scene.attachControl() and it is called BEFORE the 3D engine process anything (mesh/sprite picking for instance).\r\n     * You have the possibility to skip the process and the call to onPointerObservable by setting PointerInfoPre.skipOnPointerObservable to true\r\n     */\r\n    public onPrePointerObservable = new Observable<PointerInfoPre>();\r\n\r\n    /**\r\n     * Observable event triggered each time an input event is received from the rendering canvas\r\n     */\r\n    public onPointerObservable = new Observable<PointerInfo>();\r\n\r\n    /**\r\n     * Gets the pointer coordinates without any translation (ie. straight out of the pointer event)\r\n     */\r\n    public get unTranslatedPointer(): Vector2 {\r\n        return this._inputManager.unTranslatedPointer;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the distance in pixel that you have to move to prevent some events. Default is 10 pixels\r\n     */\r\n    public static get DragMovementThreshold() {\r\n        return InputManager.DragMovementThreshold;\r\n    }\r\n\r\n    public static set DragMovementThreshold(value: number) {\r\n        InputManager.DragMovementThreshold = value;\r\n    }\r\n\r\n    /**\r\n     * Time in milliseconds to wait to raise long press events if button is still pressed. Default is 500 ms\r\n     */\r\n    public static get LongPressDelay() {\r\n        return InputManager.LongPressDelay;\r\n    }\r\n\r\n    public static set LongPressDelay(value: number) {\r\n        InputManager.LongPressDelay = value;\r\n    }\r\n\r\n    /**\r\n     * Time in milliseconds to wait to raise long press events if button is still pressed. Default is 300 ms\r\n     */\r\n    public static get DoubleClickDelay() {\r\n        return InputManager.DoubleClickDelay;\r\n    }\r\n\r\n    public static set DoubleClickDelay(value: number) {\r\n        InputManager.DoubleClickDelay = value;\r\n    }\r\n\r\n    /** If you need to check double click without raising a single click at first click, enable this flag */\r\n    public static get ExclusiveDoubleClickMode() {\r\n        return InputManager.ExclusiveDoubleClickMode;\r\n    }\r\n\r\n    public static set ExclusiveDoubleClickMode(value: boolean) {\r\n        InputManager.ExclusiveDoubleClickMode = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current eye position in order of forcedViewPosition, activeCamera world position, Vector3.ZeroReadOnly\r\n     */\r\n    private get _eyePosition(): Vector3 {\r\n        return this._forcedViewPosition ?? this.activeCamera?.globalPosition ?? Vector3.ZeroReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Bind the current view position to an effect.\r\n     * @param effect The effect to be bound\r\n     * @param variableName name of the shader variable that will hold the eye position\r\n     * @param isVector3 true to indicates that variableName is a Vector3 and not a Vector4\r\n     * @returns the computed eye position in a temp vector, caller can copy values as needed\r\n     */\r\n    public bindEyePosition(effect: Nullable<Effect>, variableName = \"vEyePosition\", isVector3 = false): Vector4 {\r\n        const eyePosition = this._eyePosition;\r\n        const invertNormal = this.useRightHandedSystem === (this._mirroredCameraPosition != null);\r\n\r\n        const offset = this.floatingOriginOffset;\r\n        const eyePos = TempVect1.set(eyePosition.x, eyePosition.y, eyePosition.z, invertNormal ? -1 : 1);\r\n        const offsetEyePos = eyePos.subtractFromFloatsToRef(offset.x, offset.y, offset.z, 0, TempVect2);\r\n\r\n        if (effect) {\r\n            if (isVector3) {\r\n                effect.setFloat3(variableName, offsetEyePos.x, offsetEyePos.y, offsetEyePos.z);\r\n            } else {\r\n                effect.setVector4(variableName, offsetEyePos);\r\n            }\r\n        }\r\n\r\n        // Return the non-offset position\r\n        return eyePos;\r\n    }\r\n\r\n    /**\r\n     * Update the scene ubo before it can be used in rendering processing\r\n     * @returns the scene UniformBuffer\r\n     */\r\n    public finalizeSceneUbo(): UniformBuffer {\r\n        const ubo = this.getSceneUniformBuffer();\r\n        const eyePosition = this.bindEyePosition(null);\r\n\r\n        const offset = this.floatingOriginOffset;\r\n        ubo.updateFloat4(\"vEyePosition\", eyePosition.x - offset.x, eyePosition.y - offset.y, eyePosition.z - offset.z, eyePosition.w);\r\n\r\n        ubo.update();\r\n\r\n        return ubo;\r\n    }\r\n\r\n    // Mirror\r\n    /** @internal */\r\n    public _mirroredCameraPosition: Nullable<Vector3>;\r\n\r\n    // Keyboard\r\n\r\n    /**\r\n     * This observable event is triggered when any keyboard event si raised and registered during Scene.attachControl()\r\n     * You have the possibility to skip the process and the call to onKeyboardObservable by setting KeyboardInfoPre.skipOnPointerObservable to true\r\n     */\r\n    public onPreKeyboardObservable = new Observable<KeyboardInfoPre>();\r\n\r\n    /**\r\n     * Observable event triggered each time an keyboard event is received from the hosting window\r\n     */\r\n    public onKeyboardObservable = new Observable<KeyboardInfo>();\r\n\r\n    // Coordinates system\r\n\r\n    private _useRightHandedSystem = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if the scene must use right-handed coordinates system\r\n     */\r\n    public set useRightHandedSystem(value: boolean) {\r\n        if (this._useRightHandedSystem === value) {\r\n            return;\r\n        }\r\n        this._useRightHandedSystem = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_MiscDirtyFlag);\r\n    }\r\n    public get useRightHandedSystem(): boolean {\r\n        return this._useRightHandedSystem;\r\n    }\r\n\r\n    // Deterministic lockstep\r\n    private _timeAccumulator: number = 0;\r\n    private _currentStepId: number = 0;\r\n    private _currentInternalStep: number = 0;\r\n\r\n    /**\r\n     * Sets the step Id used by deterministic lock step\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @param newStepId defines the step Id\r\n     */\r\n    public setStepId(newStepId: number): void {\r\n        this._currentStepId = newStepId;\r\n    }\r\n\r\n    /**\r\n     * Gets the step Id used by deterministic lock step\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @returns the step Id\r\n     */\r\n    public getStepId(): number {\r\n        return this._currentStepId;\r\n    }\r\n\r\n    /**\r\n     * Gets the internal step used by deterministic lock step\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @returns the internal step\r\n     */\r\n    public getInternalStep(): number {\r\n        return this._currentInternalStep;\r\n    }\r\n\r\n    // Fog\r\n\r\n    private _fogEnabled = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if fog is enabled on this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog\r\n     * (Default is true)\r\n     */\r\n    public set fogEnabled(value: boolean) {\r\n        if (this._fogEnabled === value) {\r\n            return;\r\n        }\r\n        this._fogEnabled = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_MiscDirtyFlag);\r\n    }\r\n    public get fogEnabled(): boolean {\r\n        return this._fogEnabled;\r\n    }\r\n\r\n    private _fogMode = Scene.FOGMODE_NONE;\r\n    /**\r\n     * Gets or sets the fog mode to use\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog\r\n     * | mode | value |\r\n     * | --- | --- |\r\n     * | FOGMODE_NONE | 0 |\r\n     * | FOGMODE_EXP | 1 |\r\n     * | FOGMODE_EXP2 | 2 |\r\n     * | FOGMODE_LINEAR | 3 |\r\n     */\r\n    public set fogMode(value: number) {\r\n        if (this._fogMode === value) {\r\n            return;\r\n        }\r\n        this._fogMode = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_MiscDirtyFlag);\r\n    }\r\n    public get fogMode(): number {\r\n        return this._fogMode;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the fog color to use\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog\r\n     * (Default is Color3(0.2, 0.2, 0.3))\r\n     */\r\n    public fogColor = new Color3(0.2, 0.2, 0.3);\r\n    /**\r\n     * Gets or sets the fog density to use\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog\r\n     * (Default is 0.1)\r\n     */\r\n    public fogDensity = 0.1;\r\n    /**\r\n     * Gets or sets the fog start distance to use\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog\r\n     * (Default is 0)\r\n     */\r\n    public fogStart = 0;\r\n    /**\r\n     * Gets or sets the fog end distance to use\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog\r\n     * (Default is 1000)\r\n     */\r\n    public fogEnd = 1000.0;\r\n\r\n    /**\r\n     * Flag indicating that the frame buffer binding is handled by another component\r\n     */\r\n    public get prePass(): boolean {\r\n        return !!this.prePassRenderer && this.prePassRenderer.defaultRT.enabled;\r\n    }\r\n\r\n    /**\r\n     * Flag indicating if we need to store previous matrices when rendering\r\n     */\r\n    public needsPreviousWorldMatrices = false;\r\n\r\n    // Lights\r\n    private _shadowsEnabled = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if shadows are enabled on this scene\r\n     */\r\n    public set shadowsEnabled(value: boolean) {\r\n        if (this._shadowsEnabled === value) {\r\n            return;\r\n        }\r\n        this._shadowsEnabled = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_LightDirtyFlag);\r\n    }\r\n    public get shadowsEnabled(): boolean {\r\n        return this._shadowsEnabled;\r\n    }\r\n\r\n    private _lightsEnabled = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if lights are enabled on this scene\r\n     */\r\n    public set lightsEnabled(value: boolean) {\r\n        if (this._lightsEnabled === value) {\r\n            return;\r\n        }\r\n        this._lightsEnabled = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_LightDirtyFlag);\r\n    }\r\n\r\n    public get lightsEnabled(): boolean {\r\n        return this._lightsEnabled;\r\n    }\r\n\r\n    private _activeCameras: Nullable<Camera[]>;\r\n    private _unObserveActiveCameras: Nullable<() => void> = null;\r\n\r\n    /** All of the active cameras added to this scene. */\r\n    public get activeCameras(): Nullable<Camera[]> {\r\n        return this._activeCameras;\r\n    }\r\n\r\n    public set activeCameras(cameras: Nullable<Camera[]>) {\r\n        if (this._unObserveActiveCameras) {\r\n            this._unObserveActiveCameras();\r\n            this._unObserveActiveCameras = null;\r\n        }\r\n\r\n        if (cameras) {\r\n            this._unObserveActiveCameras = _ObserveArray(cameras, () => {\r\n                this.onActiveCamerasChanged.notifyObservers(this);\r\n            });\r\n        }\r\n\r\n        this._activeCameras = cameras;\r\n    }\r\n\r\n    /** @internal */\r\n    public _activeCamera: Nullable<Camera>;\r\n    /** Gets or sets the current active camera */\r\n    public get activeCamera(): Nullable<Camera> {\r\n        return this._activeCamera;\r\n    }\r\n\r\n    public set activeCamera(value: Nullable<Camera>) {\r\n        if (value === this._activeCamera) {\r\n            return;\r\n        }\r\n\r\n        this._activeCamera = value;\r\n        this.onActiveCameraChanged.notifyObservers(this);\r\n    }\r\n\r\n    /** @internal */\r\n    public get _hasDefaultMaterial() {\r\n        return Scene.DefaultMaterialFactory !== Scene._OriginalDefaultMaterialFactory;\r\n    }\r\n\r\n    private _defaultMaterial: Material;\r\n\r\n    /** The default material used on meshes when no material is affected */\r\n    public get defaultMaterial(): Material {\r\n        if (!this._defaultMaterial) {\r\n            this._defaultMaterial = Scene.DefaultMaterialFactory(this);\r\n        }\r\n\r\n        return this._defaultMaterial;\r\n    }\r\n\r\n    /** The default material used on meshes when no material is affected */\r\n    public set defaultMaterial(value: Material) {\r\n        this._defaultMaterial = value;\r\n    }\r\n\r\n    // Textures\r\n    private _texturesEnabled = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if textures are enabled on this scene\r\n     */\r\n    public set texturesEnabled(value: boolean) {\r\n        if (this._texturesEnabled === value) {\r\n            return;\r\n        }\r\n        this._texturesEnabled = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    public get texturesEnabled(): boolean {\r\n        return this._texturesEnabled;\r\n    }\r\n\r\n    private _frameGraph: Nullable<FrameGraph> = null;\r\n    private _currentCustomRenderFunction?: (updateCameras: boolean, ignoreAnimations: boolean) => void;\r\n    /**\r\n     * Gets or sets the frame graph used to render the scene. If set, the scene will use the frame graph to render the scene instead of the default render loop.\r\n     */\r\n    public get frameGraph() {\r\n        return this._frameGraph;\r\n    }\r\n\r\n    public set frameGraph(value: Nullable<FrameGraph>) {\r\n        if (this._frameGraph) {\r\n            this._frameGraph = value;\r\n            if (!value) {\r\n                this.customRenderFunction = this._currentCustomRenderFunction;\r\n            }\r\n            return;\r\n        }\r\n\r\n        this._frameGraph = value;\r\n        if (value) {\r\n            this._currentCustomRenderFunction = this.customRenderFunction;\r\n            this.customRenderFunction = this._renderWithFrameGraph;\r\n            this.activeCamera = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * List of frame graphs associated with the scene\r\n     */\r\n    public frameGraphs: FrameGraph[] = [];\r\n\r\n    // Physics\r\n    /**\r\n     * Gets or sets a boolean indicating if physic engines are enabled on this scene\r\n     */\r\n    public physicsEnabled = true;\r\n\r\n    // Particles\r\n    /**\r\n     * Gets or sets a boolean indicating if particles are enabled on this scene\r\n     */\r\n    public particlesEnabled = true;\r\n\r\n    // Sprites\r\n    /**\r\n     * Gets or sets a boolean indicating if sprites are enabled on this scene\r\n     */\r\n    public spritesEnabled = true;\r\n\r\n    // Skeletons\r\n    private _skeletonsEnabled = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if skeletons are enabled on this scene\r\n     */\r\n    public set skeletonsEnabled(value: boolean) {\r\n        if (this._skeletonsEnabled === value) {\r\n            return;\r\n        }\r\n        this._skeletonsEnabled = value;\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_AttributesDirtyFlag);\r\n    }\r\n\r\n    public get skeletonsEnabled(): boolean {\r\n        return this._skeletonsEnabled;\r\n    }\r\n\r\n    // Lens flares\r\n    /**\r\n     * Gets or sets a boolean indicating if lens flares are enabled on this scene\r\n     */\r\n    public lensFlaresEnabled = true;\r\n\r\n    // Collisions\r\n    /**\r\n     * Gets or sets a boolean indicating if collisions are enabled on this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     */\r\n    public collisionsEnabled = true;\r\n\r\n    private _collisionCoordinator: ICollisionCoordinator;\r\n\r\n    /** @internal */\r\n    public get collisionCoordinator(): ICollisionCoordinator {\r\n        if (!this._collisionCoordinator) {\r\n            this._collisionCoordinator = Scene.CollisionCoordinatorFactory();\r\n            this._collisionCoordinator.init(this);\r\n        }\r\n\r\n        return this._collisionCoordinator;\r\n    }\r\n\r\n    /**\r\n     * Defines the gravity applied to this scene (used only for collisions)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     */\r\n    public gravity = new Vector3(0, -9.807, 0);\r\n\r\n    // Postprocesses\r\n    /**\r\n     * Gets or sets a boolean indicating if postprocesses are enabled on this scene\r\n     */\r\n    public postProcessesEnabled = true;\r\n    /**\r\n     * Gets the current postprocess manager\r\n     */\r\n    public postProcessManager: PostProcessManager;\r\n\r\n    // Customs render targets\r\n    /**\r\n     * Gets or sets a boolean indicating if render targets are enabled on this scene\r\n     */\r\n    public renderTargetsEnabled = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if next render targets must be dumped as image for debugging purposes\r\n     * We recommend not using it and instead rely on Spector.js: http://spector.babylonjs.com\r\n     */\r\n    public dumpNextRenderTargets = false;\r\n    /**\r\n     * The list of user defined render targets added to the scene\r\n     */\r\n    public customRenderTargets: RenderTargetTexture[] = [];\r\n\r\n    /**\r\n     * Defines if texture loading must be delayed\r\n     * If true, textures will only be loaded when they need to be rendered\r\n     */\r\n    public useDelayedTextureLoading: boolean;\r\n\r\n    /**\r\n     * Gets the list of meshes imported to the scene through SceneLoader\r\n     */\r\n    public importedMeshesFiles: string[] = [];\r\n\r\n    // Probes\r\n    /**\r\n     * Gets or sets a boolean indicating if probes are enabled on this scene\r\n     */\r\n    public probesEnabled = true;\r\n\r\n    // Offline support\r\n    /**\r\n     * Gets or sets the current offline provider to use to store scene data\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimizeCached\r\n     */\r\n    public offlineProvider: IOfflineProvider;\r\n\r\n    /**\r\n     * Gets or sets the action manager associated with the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n     */\r\n    public actionManager: AbstractActionManager;\r\n\r\n    private _meshesForIntersections = new SmartArrayNoDuplicate<AbstractMesh>(256);\r\n\r\n    // Procedural textures\r\n    /**\r\n     * Gets or sets a boolean indicating if procedural textures are enabled on this scene\r\n     */\r\n    public proceduralTexturesEnabled = true;\r\n\r\n    // Private\r\n    private _engine: AbstractEngine;\r\n\r\n    // Performance counters\r\n    private _totalVertices = new PerfCounter();\r\n    /** @internal */\r\n    public _activeIndices = new PerfCounter();\r\n    /** @internal */\r\n    public _activeParticles = new PerfCounter();\r\n    /** @internal */\r\n    public _activeBones = new PerfCounter();\r\n\r\n    private _animationRatio: number;\r\n\r\n    /** @internal */\r\n    public _animationTimeLast: number;\r\n\r\n    /** @internal */\r\n    public _animationTime: number = 0;\r\n\r\n    /**\r\n     * Gets or sets a general scale for animation speed\r\n     * @see https://www.babylonjs-playground.com/#IBU2W7#3\r\n     */\r\n    public animationTimeScale: number = 1;\r\n\r\n    /** @internal */\r\n    public _cachedMaterial: Nullable<Material>;\r\n    /** @internal */\r\n    public _cachedEffect: Nullable<Effect>;\r\n    /** @internal */\r\n    public _cachedVisibility: Nullable<number>;\r\n\r\n    private _renderId = 0;\r\n    private _frameId = 0;\r\n    private _renderingMeshEvaluationDepth = 0;\r\n    private _executeWhenReadyTimeoutId: Nullable<ReturnType<typeof setTimeout>> = null;\r\n    /** @internal */\r\n    public _intermediateRendering = false;\r\n    private _defaultFrameBufferCleared = false;\r\n\r\n    private _viewUpdateFlag = -1;\r\n    private _projectionUpdateFlag = -1;\r\n\r\n    /** @internal */\r\n    public _toBeDisposed = new Array<Nullable<IDisposable>>(256);\r\n    private _activeRequests = new Array<IFileRequest>();\r\n    private _delayedFileRequests: Nullable<Map<string, Promise<string | ArrayBuffer>>> = null;\r\n\r\n    /** @internal */\r\n    public _pendingData = [] as any[];\r\n    private _isDisposed = false;\r\n    /**\r\n     * @internal\r\n     * Set to true once scene disposal has begun (it stays true afterwards). Used so that resources released during\r\n     * teardown (e.g. mesh effects) are freed immediately instead of being deferred to the next frame, which may never\r\n     * happen once rendering stops.\r\n     */\r\n    public _isDisposing = false;\r\n    private _isReadyChecks: { isReady(): boolean }[] = [];\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that all submeshes of active meshes must be rendered\r\n     * Use this boolean to avoid computing frustum clipping on submeshes (This could help when you are CPU bound)\r\n     */\r\n    public dispatchAllSubMeshesOfActiveMeshes: boolean = false;\r\n    private _activeMeshes = new SmartArray<AbstractMesh>(256);\r\n    private _processedMaterials = new SmartArray<Material>(256);\r\n    private _renderTargets = new SmartArrayNoDuplicate<RenderTargetTexture>(256);\r\n    private _materialsRenderTargets = new SmartArrayNoDuplicate<RenderTargetTexture>(256);\r\n    /** @internal */\r\n    public _activeParticleSystems = new SmartArray<IParticleSystem>(256);\r\n    private _activeSkeletons = new SmartArrayNoDuplicate<Skeleton>(32);\r\n    private _softwareSkinnedMeshes = new SmartArrayNoDuplicate<Mesh>(32);\r\n\r\n    private _renderingManager: RenderingManager;\r\n\r\n    /**\r\n     * Gets the scene's rendering manager\r\n     */\r\n    public get renderingManager(): RenderingManager {\r\n        return this._renderingManager;\r\n    }\r\n\r\n    /** @internal */\r\n    public _activeAnimatables = new Array<Animatable>();\r\n    /**\r\n     * @internal\r\n     * The writes of the runtime animations since the last animation step's bindings were processed - between steps\r\n     * and in the current or last step - in the order they were made: the first _animationWriteCount entries, the rest\r\n     * being reused. What the animations wrote, kept whatever became of them since, for as long as the bindings they\r\n     * registered are pending or just processed.\r\n     */\r\n    public _animationWrites = new Array<IRuntimeAnimationWrite>();\r\n    /** @internal How many of _animationWrites are in use. */\r\n    public _animationWriteCount = 0;\r\n    /** @internal How many of them, at the front, the last animation step's bindings processed; the next step lets them go. */\r\n    public _animationStepWriteCount = 0;\r\n    /** @internal Whether the current or last animation step evaluated the active animatables, which none does while animations are disabled. */\r\n    public _animationStepEvaluated = false;\r\n\r\n    private _transformMatrix = Matrix.Zero();\r\n    private _sceneUbo: UniformBuffer;\r\n\r\n    /** @internal */\r\n    public _viewMatrix: Matrix;\r\n    /** @internal */\r\n    public _projectionMatrix: Matrix;\r\n    /** @internal */\r\n    public _inverseProjectionMatrix: Matrix;\r\n    /** @internal */\r\n    public _forcedViewPosition: Nullable<Vector3>;\r\n\r\n    /** @internal */\r\n    public _frustumPlanes: Plane[];\r\n    /**\r\n     * Gets the list of frustum planes (built from the active camera)\r\n     */\r\n    public get frustumPlanes(): Plane[] {\r\n        return this._frustumPlanes;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if lights must be sorted by priority (off by default)\r\n     * This is useful if there are more lights that the maximum simulteanous authorized\r\n     */\r\n    public requireLightSorting = false;\r\n\r\n    /** @internal */\r\n    public readonly useMaterialMeshMap: boolean;\r\n    /** @internal */\r\n    public readonly useClonedMeshMap: boolean;\r\n\r\n    private _externalData: StringDictionary<object>;\r\n    private _uid: Nullable<string>;\r\n\r\n    /**\r\n     * Gets or sets the default layerMask used for cameras created in this scene.\r\n     */\r\n    public defaultCameraLayerMask: number;\r\n\r\n    /**\r\n     * Gets or sets the default layerMask used for renderable objects created in this scene.\r\n     */\r\n    public defaultRenderableLayerMask: number;\r\n\r\n    /**\r\n     * @internal\r\n     * Backing store of defined scene components.\r\n     */\r\n    public _components: ISceneComponent[] = [];\r\n\r\n    /**\r\n     * @internal\r\n     * Backing store of defined scene components.\r\n     */\r\n    public _serializableComponents: ISceneSerializableComponent[] = [];\r\n\r\n    /**\r\n     * List of components to register on the next registration step.\r\n     */\r\n    private _transientComponents: ISceneComponent[] = [];\r\n\r\n    /**\r\n     * Registers the transient components if needed.\r\n     */\r\n    private _registerTransientComponents(): void {\r\n        // Register components that have been associated lately to the scene.\r\n        if (this._transientComponents.length > 0) {\r\n            for (const component of this._transientComponents) {\r\n                component.register();\r\n            }\r\n            this._transientComponents.length = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Add a component to the scene.\r\n     * Note that the ccomponent could be registered on th next frame if this is called after\r\n     * the register component stage.\r\n     * @param component Defines the component to add to the scene\r\n     */\r\n    public _addComponent(component: ISceneComponent) {\r\n        this._components.push(component);\r\n        this._transientComponents.push(component);\r\n\r\n        const serializableComponent = component as any;\r\n        if (serializableComponent.addFromContainer && serializableComponent.serialize) {\r\n            this._serializableComponents.push(serializableComponent);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Gets a component from the scene.\r\n     * @param name defines the name of the component to retrieve\r\n     * @returns the component or null if not present\r\n     */\r\n    public _getComponent(name: string): Nullable<ISceneComponent> {\r\n        for (const component of this._components) {\r\n            if (component.name === name) {\r\n                return component;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening before camera updates.\r\n     */\r\n    public _beforeCameraUpdateStage = Stage.Create<SimpleStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening before clear the canvas.\r\n     */\r\n    public _beforeClearStage = Stage.Create<SimpleStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening before clear the canvas.\r\n     */\r\n    public _beforeRenderTargetClearStage = Stage.Create<RenderTargetStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions when collecting render targets for the frame.\r\n     */\r\n    public _gatherRenderTargetsStage = Stage.Create<RenderTargetsStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening for one camera in the frame.\r\n     */\r\n    public _gatherActiveCameraRenderTargetsStage = Stage.Create<RenderTargetsStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening during the per mesh ready checks.\r\n     */\r\n    public _isReadyForMeshStage = Stage.Create<MeshStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening before evaluate active mesh checks.\r\n     */\r\n    public _beforeEvaluateActiveMeshStage = Stage.Create<SimpleStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening during the evaluate sub mesh checks.\r\n     */\r\n    public _evaluateSubMeshStage = Stage.Create<EvaluateSubMeshStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening during the active mesh stage.\r\n     */\r\n    public _preActiveMeshStage = Stage.Create<PreActiveMeshStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening during the per camera render target step.\r\n     */\r\n    public _cameraDrawRenderTargetStage = Stage.Create<CameraStageFrameBufferAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just before the active camera is drawing.\r\n     */\r\n    public _beforeCameraDrawStage = Stage.Create<CameraStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just before a render target is drawing.\r\n     */\r\n    public _beforeRenderTargetDrawStage = Stage.Create<RenderTargetStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just before a rendering group is drawing.\r\n     */\r\n    public _beforeRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just before a mesh is drawing.\r\n     */\r\n    public _beforeRenderingMeshStage = Stage.Create<RenderingMeshStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just after a mesh has been drawn.\r\n     */\r\n    public _afterRenderingMeshStage = Stage.Create<RenderingMeshStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just after a rendering group has been drawn.\r\n     */\r\n    public _afterRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just after the active camera has been drawn.\r\n     */\r\n    public _afterCameraDrawStage = Stage.Create<CameraStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just after the post processing\r\n     */\r\n    public _afterCameraPostProcessStage = Stage.Create<CameraStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just after a render target has been drawn.\r\n     */\r\n    public _afterRenderTargetDrawStage = Stage.Create<RenderTargetStageAction>();\r\n    /**\r\n     * Defines the actions happening just after the post processing on a render target\r\n     */\r\n    public _afterRenderTargetPostProcessStage = Stage.Create<RenderTargetStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening just after rendering all cameras and computing intersections.\r\n     */\r\n    public _afterRenderStage = Stage.Create<SimpleStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening when a pointer move event happens.\r\n     */\r\n    public _pointerMoveStage = Stage.Create<PointerMoveStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening when a pointer down event happens.\r\n     */\r\n    public _pointerDownStage = Stage.Create<PointerUpDownStageAction>();\r\n    /**\r\n     * @internal\r\n     * Defines the actions happening when a pointer up event happens.\r\n     */\r\n    public _pointerUpStage = Stage.Create<PointerUpDownStageAction>();\r\n\r\n    /**\r\n     * an optional map from Geometry Id to Geometry index in the 'geometries' array\r\n     */\r\n    private _geometriesByUniqueId: Nullable<{ [uniqueId: string]: number | undefined }> = null;\r\n\r\n    private _uniqueId = 0;\r\n\r\n    /**\r\n     * Gets the unique id of the scene\r\n     */\r\n    public get uniqueId() {\r\n        return this._uniqueId;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Scene\r\n     * @param engine defines the engine to use to render this scene\r\n     * @param options defines the scene options\r\n     */\r\n    constructor(engine: AbstractEngine, options?: SceneOptions) {\r\n        this.activeCameras = [] as Camera[];\r\n\r\n        this._uniqueId = this.getUniqueId();\r\n\r\n        const fullOptions = {\r\n            useGeometryUniqueIdsMap: true,\r\n            useMaterialMeshMap: true,\r\n            useClonedMeshMap: true,\r\n            virtual: false,\r\n            defaultCameraLayerMask: 0x0fffffff,\r\n            defaultRenderableLayerMask: 0x0fffffff,\r\n            ...options,\r\n        };\r\n\r\n        // Scene Default Layer Masks\r\n        this.defaultCameraLayerMask = fullOptions.defaultCameraLayerMask;\r\n        this.defaultRenderableLayerMask = fullOptions.defaultRenderableLayerMask;\r\n\r\n        engine = this._engine = engine || EngineStore.LastCreatedEngine;\r\n        if (fullOptions.virtual) {\r\n            engine._virtualScenes.push(this);\r\n        } else {\r\n            EngineStore._LastCreatedScene = this;\r\n            engine.scenes.push(this);\r\n        }\r\n\r\n        if (engine.getCreationOptions().useLargeWorldRendering || options?.useFloatingOrigin) {\r\n            OverrideMatrixFunctions();\r\n            this._floatingOriginScene = this;\r\n            FloatingOriginCurrentScene.getScene = this._getFloatingOriginScene;\r\n        }\r\n\r\n        this._uid = null;\r\n\r\n        this._renderingManager = new RenderingManager(this);\r\n\r\n        if (PostProcessManager) {\r\n            this.postProcessManager = new PostProcessManager(this);\r\n        }\r\n\r\n        if (IsWindowObjectExist()) {\r\n            this.attachControl();\r\n        }\r\n\r\n        // Uniform Buffer\r\n        this._createUbo();\r\n\r\n        // Default Image processing definition\r\n        if (ImageProcessingConfiguration) {\r\n            this._imageProcessingConfiguration = new ImageProcessingConfiguration();\r\n        }\r\n\r\n        this.setDefaultCandidateProviders();\r\n\r\n        if (fullOptions.useGeometryUniqueIdsMap) {\r\n            this._geometriesByUniqueId = {};\r\n        }\r\n\r\n        this.useMaterialMeshMap = fullOptions.useMaterialMeshMap;\r\n        this.useClonedMeshMap = fullOptions.useClonedMeshMap;\r\n\r\n        if (!options || !options.virtual) {\r\n            engine.onNewSceneAddedObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"Scene\" string\r\n     */\r\n    public getClassName(): string {\r\n        return \"Scene\";\r\n    }\r\n\r\n    private _defaultMeshCandidates: ISmartArrayLike<AbstractMesh> = {\r\n        data: [],\r\n        length: 0,\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getDefaultMeshCandidates(): ISmartArrayLike<AbstractMesh> {\r\n        this._defaultMeshCandidates.data = this.meshes;\r\n        this._defaultMeshCandidates.length = this.meshes.length;\r\n        return this._defaultMeshCandidates;\r\n    }\r\n\r\n    private _defaultSubMeshCandidates: ISmartArrayLike<SubMesh> = {\r\n        data: [],\r\n        length: 0,\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getDefaultSubMeshCandidates(mesh: AbstractMesh): ISmartArrayLike<SubMesh> {\r\n        this._defaultSubMeshCandidates.data = mesh.subMeshes;\r\n        this._defaultSubMeshCandidates.length = mesh.subMeshes.length;\r\n        return this._defaultSubMeshCandidates;\r\n    }\r\n\r\n    /**\r\n     * Sets the default candidate providers for the scene.\r\n     * This sets the getActiveMeshCandidates, getActiveSubMeshCandidates, getIntersectingSubMeshCandidates\r\n     * and getCollidingSubMeshCandidates to their default function\r\n     */\r\n    public setDefaultCandidateProviders(): void {\r\n        this.getActiveMeshCandidates = () => this._getDefaultMeshCandidates();\r\n        this.getActiveSubMeshCandidates = (mesh: AbstractMesh) => this._getDefaultSubMeshCandidates(mesh);\r\n        this.getIntersectingSubMeshCandidates = (mesh: AbstractMesh, localRay: Ray) => this._getDefaultSubMeshCandidates(mesh);\r\n        this.getCollidingSubMeshCandidates = (mesh: AbstractMesh, collider: Collider) => this._getDefaultSubMeshCandidates(mesh);\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh that is currently under the pointer\r\n     */\r\n    public get meshUnderPointer(): Nullable<AbstractMesh> {\r\n        return this._inputManager.meshUnderPointer;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current on-screen X position of the pointer\r\n     */\r\n    public get pointerX(): number {\r\n        return this._inputManager.pointerX;\r\n    }\r\n\r\n    public set pointerX(value: number) {\r\n        this._inputManager.pointerX = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current on-screen Y position of the pointer\r\n     */\r\n    public get pointerY(): number {\r\n        return this._inputManager.pointerY;\r\n    }\r\n\r\n    public set pointerY(value: number) {\r\n        this._inputManager.pointerY = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the cached material (ie. the latest rendered one)\r\n     * @returns the cached material\r\n     */\r\n    public getCachedMaterial(): Nullable<Material> {\r\n        return this._cachedMaterial;\r\n    }\r\n\r\n    /**\r\n     * Gets the cached effect (ie. the latest rendered one)\r\n     * @returns the cached effect\r\n     */\r\n    public getCachedEffect(): Nullable<Effect> {\r\n        return this._cachedEffect;\r\n    }\r\n\r\n    /**\r\n     * Gets the cached visibility state (ie. the latest rendered one)\r\n     * @returns the cached visibility state\r\n     */\r\n    public getCachedVisibility(): Nullable<number> {\r\n        return this._cachedVisibility;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current material / effect / visibility must be bind again\r\n     * @param material defines the current material\r\n     * @param effect defines the current effect\r\n     * @param visibility defines the current visibility state\r\n     * @returns true if one parameter is not cached\r\n     */\r\n    public isCachedMaterialInvalid(material: Material, effect: Effect, visibility: number = 1) {\r\n        return this._cachedEffect !== effect || this._cachedMaterial !== material || this._cachedVisibility !== visibility;\r\n    }\r\n\r\n    /**\r\n     * Gets the engine associated with the scene\r\n     * @returns an Engine\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * Gets the total number of vertices rendered per frame\r\n     * @returns the total number of vertices rendered per frame\r\n     */\r\n    public getTotalVertices(): number {\r\n        return this._totalVertices.current;\r\n    }\r\n\r\n    /**\r\n     * Gets the performance counter for total vertices\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#instrumentation\r\n     */\r\n    public get totalVerticesPerfCounter(): PerfCounter {\r\n        return this._totalVertices;\r\n    }\r\n\r\n    /**\r\n     * Gets the total number of active indices rendered per frame (You can deduce the number of rendered triangles by dividing this number by 3)\r\n     * @returns the total number of active indices rendered per frame\r\n     */\r\n    public getActiveIndices(): number {\r\n        return this._activeIndices.current;\r\n    }\r\n\r\n    /**\r\n     * Gets the performance counter for active indices\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#instrumentation\r\n     */\r\n    public get totalActiveIndicesPerfCounter(): PerfCounter {\r\n        return this._activeIndices;\r\n    }\r\n\r\n    /**\r\n     * Gets the total number of active particles rendered per frame\r\n     * @returns the total number of active particles rendered per frame\r\n     */\r\n    public getActiveParticles(): number {\r\n        return this._activeParticles.current;\r\n    }\r\n\r\n    /**\r\n     * Gets the performance counter for active particles\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#instrumentation\r\n     */\r\n    public get activeParticlesPerfCounter(): PerfCounter {\r\n        return this._activeParticles;\r\n    }\r\n\r\n    /**\r\n     * Gets the total number of active bones rendered per frame\r\n     * @returns the total number of active bones rendered per frame\r\n     */\r\n    public getActiveBones(): number {\r\n        return this._activeBones.current;\r\n    }\r\n\r\n    /**\r\n     * Gets the performance counter for active bones\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#instrumentation\r\n     */\r\n    public get activeBonesPerfCounter(): PerfCounter {\r\n        return this._activeBones;\r\n    }\r\n\r\n    /**\r\n     * Gets the array of active meshes\r\n     * @returns an array of AbstractMesh\r\n     */\r\n    public getActiveMeshes(): SmartArray<AbstractMesh> {\r\n        return this._activeMeshes;\r\n    }\r\n\r\n    /**\r\n     * Gets the animation ratio (which is 1.0 is the scene renders at 60fps and 2 if the scene renders at 30fps, etc.)\r\n     * @returns a number\r\n     */\r\n    public getAnimationRatio(): number {\r\n        return this._animationRatio !== undefined ? this._animationRatio : 1;\r\n    }\r\n\r\n    /**\r\n     * Gets an unique Id for the current render phase\r\n     * @returns a number\r\n     */\r\n    public getRenderId(): number {\r\n        return this._renderId;\r\n    }\r\n\r\n    /**\r\n     * Gets an unique Id for the current frame\r\n     * @returns a number\r\n     */\r\n    public getFrameId(): number {\r\n        return this._frameId;\r\n    }\r\n\r\n    /** Call this function if you want to manually increment the render Id*/\r\n    public incrementRenderId(): void {\r\n        this._renderId++;\r\n    }\r\n\r\n    private _createUbo(): void {\r\n        this.setSceneUniformBuffer(this.createSceneUniformBuffer());\r\n    }\r\n\r\n    /**\r\n     * Use this method to simulate a pointer move on a mesh\r\n     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay\r\n     * @param pickResult pickingInfo of the object wished to simulate pointer event on\r\n     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)\r\n     * @returns the current scene\r\n     */\r\n    public simulatePointerMove(pickResult: PickingInfo, pointerEventInit?: PointerEventInit): Scene {\r\n        this._inputManager.simulatePointerMove(pickResult, pointerEventInit);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Use this method to simulate a pointer down on a mesh\r\n     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay\r\n     * @param pickResult pickingInfo of the object wished to simulate pointer event on\r\n     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)\r\n     * @returns the current scene\r\n     */\r\n    public simulatePointerDown(pickResult: PickingInfo, pointerEventInit?: PointerEventInit): Scene {\r\n        this._inputManager.simulatePointerDown(pickResult, pointerEventInit);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Use this method to simulate a pointer up on a mesh\r\n     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay\r\n     * @param pickResult pickingInfo of the object wished to simulate pointer event on\r\n     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)\r\n     * @param doubleTap indicates that the pointer up event should be considered as part of a double click (false by default)\r\n     * @returns the current scene\r\n     */\r\n    public simulatePointerUp(pickResult: PickingInfo, pointerEventInit?: PointerEventInit, doubleTap?: boolean): Scene {\r\n        this._inputManager.simulatePointerUp(pickResult, pointerEventInit, doubleTap);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current pointer event is captured (meaning that the scene has already handled the pointer down)\r\n     * @param pointerId defines the pointer id to use in a multi-touch scenario (0 by default)\r\n     * @returns true if the pointer was captured\r\n     */\r\n    public isPointerCaptured(pointerId = 0): boolean {\r\n        return this._inputManager.isPointerCaptured(pointerId);\r\n    }\r\n\r\n    /**\r\n     * Attach events to the canvas (To handle actionManagers triggers and raise onPointerMove, onPointerDown and onPointerUp\r\n     * @param attachUp defines if you want to attach events to pointerup\r\n     * @param attachDown defines if you want to attach events to pointerdown\r\n     * @param attachMove defines if you want to attach events to pointermove\r\n     */\r\n    public attachControl(attachUp = true, attachDown = true, attachMove = true): void {\r\n        this._inputManager.attachControl(attachUp, attachDown, attachMove);\r\n    }\r\n\r\n    /** Detaches all event handlers*/\r\n    public detachControl() {\r\n        this._inputManager.detachControl();\r\n    }\r\n\r\n    /**\r\n     * This function will check if the scene can be rendered (textures are loaded, shaders are compiled)\r\n     * Delay loaded resources are not taking in account\r\n     * @param checkRenderTargets true to also check that the meshes rendered as part of a render target are ready (default: true)\r\n     * @returns true if all required resources are ready\r\n     */\r\n    public isReady(checkRenderTargets = true): boolean {\r\n        if (this._isDisposed) {\r\n            return false;\r\n        }\r\n\r\n        let index: number;\r\n        const engine = this.getEngine();\r\n\r\n        const currentRenderPassId = engine.currentRenderPassId;\r\n\r\n        engine.currentRenderPassId = this.activeCamera?.renderPassId ?? currentRenderPassId;\r\n\r\n        let isReady = true;\r\n\r\n        // Pending data\r\n        if (this._pendingData.length > 0) {\r\n            isReady = false;\r\n        }\r\n\r\n        // Ensures that the pre-pass renderer is enabled if it is to be enabled.\r\n        this.prePassRenderer?.update();\r\n\r\n        // OIT\r\n        if (this.useOrderIndependentTransparency && this.depthPeelingRenderer) {\r\n            isReady &&= this.depthPeelingRenderer.isReady();\r\n        }\r\n\r\n        // Meshes\r\n        if (checkRenderTargets) {\r\n            this._processedMaterials.reset();\r\n            this._materialsRenderTargets.reset();\r\n        }\r\n\r\n        for (index = 0; index < this.meshes.length; index++) {\r\n            const mesh = this.meshes[index];\r\n\r\n            if (!mesh.subMeshes || mesh.subMeshes.length === 0) {\r\n                continue;\r\n            }\r\n\r\n            // Do not stop at the first encountered \"unready\" object as we want to ensure\r\n            // all materials are starting off their compilation in parallel.\r\n            if (!mesh.isReady(true)) {\r\n                isReady = false;\r\n                continue;\r\n            }\r\n\r\n            const hardwareInstancedRendering =\r\n                mesh.hasThinInstances ||\r\n                mesh.getClassName() === \"InstancedMesh\" ||\r\n                mesh.getClassName() === \"InstancedLinesMesh\" ||\r\n                (engine.getCaps().instancedArrays && (<Mesh>mesh).instances.length > 0);\r\n            // Is Ready For Mesh\r\n            for (const step of this._isReadyForMeshStage) {\r\n                if (!step.action(mesh, hardwareInstancedRendering)) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n\r\n            if (!checkRenderTargets) {\r\n                continue;\r\n            }\r\n\r\n            const mat = mesh.material || this.defaultMaterial;\r\n            if (mat) {\r\n                if (mat._storeEffectOnSubMeshes) {\r\n                    for (const subMesh of mesh.subMeshes) {\r\n                        const material = subMesh.getMaterial();\r\n                        if (material && material.hasRenderTargetTextures && material.getRenderTargetTextures != null) {\r\n                            if (this._processedMaterials.indexOf(material) === -1) {\r\n                                this._processedMaterials.push(material);\r\n\r\n                                this._materialsRenderTargets.concatWithNoDuplicate(material.getRenderTargetTextures());\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (mat.hasRenderTargetTextures && mat.getRenderTargetTextures != null) {\r\n                        if (this._processedMaterials.indexOf(mat) === -1) {\r\n                            this._processedMaterials.push(mat);\r\n\r\n                            this._materialsRenderTargets.concatWithNoDuplicate(mat.getRenderTargetTextures());\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Render targets\r\n        if (checkRenderTargets) {\r\n            for (index = 0; index < this._materialsRenderTargets.length; ++index) {\r\n                const rtt = this._materialsRenderTargets.data[index];\r\n                if (!rtt.isReadyForRendering()) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n\r\n            for (index = 0; index < this.customRenderTargets.length; ++index) {\r\n                const rtt = this.customRenderTargets[index];\r\n                if (!rtt.isReadyForRendering()) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Geometries\r\n        for (index = 0; index < this.geometries.length; index++) {\r\n            const geometry = this.geometries[index];\r\n\r\n            if (geometry.delayLoadState === Constants.DELAYLOADSTATE_LOADING) {\r\n                isReady = false;\r\n            }\r\n        }\r\n\r\n        // Post-processes\r\n        if (this.activeCameras && this.activeCameras.length > 0) {\r\n            for (const camera of this.activeCameras) {\r\n                if (!camera.isReady(true)) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n        } else if (this.activeCamera) {\r\n            if (!this.activeCamera.isReady(true)) {\r\n                isReady = false;\r\n            }\r\n        }\r\n\r\n        // Particles\r\n        for (const particleSystem of this.particleSystems) {\r\n            if (!particleSystem.isReady()) {\r\n                isReady = false;\r\n            }\r\n        }\r\n\r\n        // Procedural textures\r\n        if (this.proceduralTexturesEnabled) {\r\n            for (const proceduralTexture of this.proceduralTextures) {\r\n                if (!proceduralTexture.isReady()) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Layers\r\n        if (this.layers) {\r\n            for (const layer of this.layers) {\r\n                if (!layer.isReady()) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Effect layers\r\n        if (this.effectLayers) {\r\n            for (const effectLayer of this.effectLayers) {\r\n                if (!effectLayer.isLayerReady()) {\r\n                    isReady = false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // isReady() checks for externally specified objects.\r\n        for (const check of this._isReadyChecks) {\r\n            if (!check.isReady()) {\r\n                isReady = false;\r\n            }\r\n        }\r\n\r\n        // Effects\r\n        if (!engine.areAllEffectsReady()) {\r\n            isReady = false;\r\n        }\r\n\r\n        engine.currentRenderPassId = currentRenderPassId;\r\n\r\n        return isReady;\r\n    }\r\n\r\n    /** Resets all cached information relative to material (including effect and visibility) */\r\n    public resetCachedMaterial(): void {\r\n        this._cachedMaterial = null;\r\n        this._cachedEffect = null;\r\n        this._cachedVisibility = null;\r\n    }\r\n\r\n    /**\r\n     * Registers a function to be called before every frame render\r\n     * @param func defines the function to register\r\n     */\r\n    public registerBeforeRender(func: () => void): void {\r\n        this.onBeforeRenderObservable.add(func);\r\n    }\r\n\r\n    /**\r\n     * Unregisters a function called before every frame render\r\n     * @param func defines the function to unregister\r\n     */\r\n    public unregisterBeforeRender(func: () => void): void {\r\n        this.onBeforeRenderObservable.removeCallback(func);\r\n    }\r\n\r\n    /**\r\n     * Registers a function to be called after every frame render\r\n     * @param func defines the function to register\r\n     */\r\n    public registerAfterRender(func: () => void): void {\r\n        this.onAfterRenderObservable.add(func);\r\n    }\r\n\r\n    /**\r\n     * Unregisters a function called after every frame render\r\n     * @param func defines the function to unregister\r\n     */\r\n    public unregisterAfterRender(func: () => void): void {\r\n        this.onAfterRenderObservable.removeCallback(func);\r\n    }\r\n\r\n    private _executeOnceBeforeRender(func: () => void): void {\r\n        const execFunc = () => {\r\n            func();\r\n            setTimeout(() => {\r\n                this.unregisterBeforeRender(execFunc);\r\n            });\r\n        };\r\n        this.registerBeforeRender(execFunc);\r\n    }\r\n\r\n    /**\r\n     * The provided function will run before render once and will be disposed afterwards.\r\n     * A timeout delay can be provided so that the function will be executed in N ms.\r\n     * The timeout is using the browser's native setTimeout so time percision cannot be guaranteed.\r\n     * @param func The function to be executed.\r\n     * @param timeout optional delay in ms\r\n     */\r\n    public executeOnceBeforeRender(func: () => void, timeout?: number): void {\r\n        if (timeout !== undefined) {\r\n            setTimeout(() => {\r\n                this._executeOnceBeforeRender(func);\r\n            }, timeout);\r\n        } else {\r\n            this._executeOnceBeforeRender(func);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This function can help adding any object to the list of data awaited to be ready in order to check for a complete scene loading.\r\n     * @param data defines the object to wait for\r\n     */\r\n    public addPendingData(data: any): void {\r\n        this._pendingData.push(data);\r\n    }\r\n\r\n    /**\r\n     * Remove a pending data from the loading list which has previously been added with addPendingData.\r\n     * @param data defines the object to remove from the pending list\r\n     */\r\n    public removePendingData(data: any): void {\r\n        const wasLoading = this.isLoading;\r\n        const index = this._pendingData.indexOf(data);\r\n\r\n        if (index !== -1) {\r\n            this._pendingData.splice(index, 1);\r\n        }\r\n\r\n        if (wasLoading && !this.isLoading) {\r\n            this.onDataLoadedObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the number of items waiting to be loaded\r\n     * @returns the number of items waiting to be loaded\r\n     */\r\n    public getWaitingItemsCount(): number {\r\n        return this._pendingData.length;\r\n    }\r\n\r\n    /**\r\n     * Returns a boolean indicating if the scene is still loading data\r\n     */\r\n    public get isLoading(): boolean {\r\n        return this._pendingData.length > 0;\r\n    }\r\n\r\n    /**\r\n     * Registers an object whose {@link isReady} method will be checked during {@link Scene.isReady}.\r\n     * Call {@link removeIsReadyCheck} to remove the object.\r\n     * @param isReadyCheck defines the object to add.\r\n     */\r\n    public addIsReadyCheck(isReadyCheck: { isReady(): boolean }): void {\r\n        if (this._isReadyChecks.indexOf(isReadyCheck) === -1) {\r\n            this._isReadyChecks.push(isReadyCheck);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes an object previously registered with {@link addIsReadyCheck}.\r\n     * @param isReadyCheck defines the object to remove.\r\n     */\r\n    public removeIsReadyCheck(isReadyCheck: { isReady(): boolean }): void {\r\n        const index = this._isReadyChecks.indexOf(isReadyCheck);\r\n        if (index !== -1) {\r\n            this._isReadyChecks.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Registers a function to be executed when the scene is ready\r\n     * @param func - the function to be executed\r\n     * @param checkRenderTargets true to also check that the meshes rendered as part of a render target are ready (default: false)\r\n     */\r\n    public executeWhenReady(func: () => void, checkRenderTargets = false): void {\r\n        this.onReadyObservable.addOnce(func);\r\n\r\n        if (this._executeWhenReadyTimeoutId !== null) {\r\n            return;\r\n        }\r\n\r\n        this._checkIsReady(checkRenderTargets);\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves when the scene is ready\r\n     * @param checkRenderTargets true to also check that the meshes rendered as part of a render target are ready (default: false)\r\n     * @returns A promise that resolves when the scene is ready\r\n     */\r\n    public async whenReadyAsync(checkRenderTargets = false): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            this.executeWhenReady(() => {\r\n                resolve();\r\n            }, checkRenderTargets);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the scene ready checks has timed out.\r\n     */\r\n    public onReadyTimeoutObservable = new Observable<Scene>();\r\n\r\n    /**\r\n     * Duration in milliseconds to wait before triggering the onReadyTimeoutObservable event.\r\n     */\r\n    public onReadyTimeoutDuration = 2 * 60 * 1000; // 2 minutes by default\r\n\r\n    private _timeoutChecksStartTime: number = 0;\r\n\r\n    private _clearReadynessChecksData() {\r\n        this._timeoutChecksStartTime = 0;\r\n        this.onReadyTimeoutObservable.clear();\r\n\r\n        this.onReadyObservable.clear();\r\n        this._executeWhenReadyTimeoutId = null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _checkIsReady(checkRenderTargets = false) {\r\n        this._registerTransientComponents();\r\n\r\n        // Starts counting time from the first check for timeout purposes\r\n        if (this._timeoutChecksStartTime === 0) {\r\n            this._timeoutChecksStartTime = PrecisionDate.Now;\r\n        }\r\n        // Check for timeout\r\n        else if (this.onReadyTimeoutDuration > 0 && PrecisionDate.Now - this._timeoutChecksStartTime > this.onReadyTimeoutDuration) {\r\n            this.onReadyTimeoutObservable.notifyObservers(this);\r\n            this._clearReadynessChecksData();\r\n            return;\r\n        }\r\n\r\n        // Check for readyness\r\n        if (this.isReady(checkRenderTargets)) {\r\n            this.onReadyObservable.notifyObservers(this);\r\n            this._clearReadynessChecksData();\r\n            return;\r\n        }\r\n\r\n        // Clean up if the scene was disposed in the meantime\r\n        if (this._isDisposed) {\r\n            this._clearReadynessChecksData();\r\n            return;\r\n        }\r\n\r\n        this._executeWhenReadyTimeoutId = setTimeout(() => {\r\n            // Ensure materials effects are checked outside render loops\r\n            this.incrementRenderId();\r\n            this._checkIsReady(checkRenderTargets);\r\n        }, 100);\r\n    }\r\n\r\n    /**\r\n     * Gets all animatable attached to the scene\r\n     */\r\n    public get animatables(): Animatable[] {\r\n        return this._activeAnimatables;\r\n    }\r\n\r\n    /**\r\n     * Resets the last animation time frame.\r\n     * Useful to override when animations start running when loading a scene for the first time.\r\n     */\r\n    public resetLastAnimationTimeFrame(): void {\r\n        this._animationTimeLast = PrecisionDate.Now;\r\n    }\r\n\r\n    // Matrix\r\n\r\n    /**\r\n     * Gets the current view matrix\r\n     * @returns a Matrix\r\n     */\r\n    public getViewMatrix(): Matrix {\r\n        return this._viewMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the current projection matrix\r\n     * @returns a Matrix\r\n     */\r\n    public getProjectionMatrix(): Matrix {\r\n        return this._projectionMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the current inverse projection matrix\r\n     * @returns a Matrix\r\n     */\r\n    public getInverseProjectionMatrix(): Matrix {\r\n        return this._inverseProjectionMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the current transform matrix\r\n     * @returns a Matrix made of View * Projection\r\n     */\r\n    public getTransformMatrix(): Matrix {\r\n        return this._transformMatrix;\r\n    }\r\n\r\n    /**\r\n     * Sets the current transform matrix\r\n     * @param viewL defines the View matrix to use\r\n     * @param projectionL defines the Projection matrix to use\r\n     * @param viewR defines the right View matrix to use (if provided)\r\n     * @param projectionR defines the right Projection matrix to use (if provided)\r\n     */\r\n    public setTransformMatrix(viewL: Matrix, projectionL: Matrix, viewR?: Matrix, projectionR?: Matrix): void {\r\n        // Toggle the multiview flag based on whether stereo matrices are provided.\r\n        // The multiview UBO itself is kept alive for the XR session lifetime to avoid per-frame GPU alloc/dealloc.\r\n        this._multiviewSceneUboIsActive = !!(viewR && projectionR && this._multiviewSceneUbo);\r\n        if (this._viewUpdateFlag === viewL.updateFlag && this._projectionUpdateFlag === projectionL.updateFlag) {\r\n            return;\r\n        }\r\n\r\n        this._viewUpdateFlag = viewL.updateFlag;\r\n        this._projectionUpdateFlag = projectionL.updateFlag;\r\n        this._viewMatrix = viewL;\r\n        this._projectionMatrix = projectionL;\r\n        if (!this._inverseProjectionMatrix) {\r\n            this._inverseProjectionMatrix = new Matrix();\r\n        }\r\n        this._projectionMatrix.invertToRef(this._inverseProjectionMatrix);\r\n\r\n        this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);\r\n\r\n        // Update frustum\r\n        if (!this._frustumPlanes) {\r\n            this._frustumPlanes = Frustum.GetPlanes(this._transformMatrix);\r\n        } else {\r\n            Frustum.GetPlanesToRef(this._transformMatrix, this._frustumPlanes);\r\n        }\r\n\r\n        if (this._multiviewSceneUboIsActive && this._multiviewSceneUbo!.useUbo) {\r\n            this._updateMultiviewUbo(viewR, projectionR);\r\n        } else if (this._sceneUbo.useUbo) {\r\n            this._sceneUbo.updateMatrix(\"viewProjection\", this._transformMatrix);\r\n            this._sceneUbo.updateMatrix(\"view\", this._viewMatrix);\r\n            this._sceneUbo.updateMatrix(\"projection\", this._projectionMatrix);\r\n            this._sceneUbo.updateMatrix(\"inverseProjection\", this._inverseProjectionMatrix);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the uniform buffer used to store scene data\r\n     * @returns a UniformBuffer\r\n     */\r\n    public getSceneUniformBuffer(): UniformBuffer {\r\n        return this._multiviewSceneUboIsActive && this._multiviewSceneUbo ? this._multiviewSceneUbo : this._sceneUbo;\r\n    }\r\n\r\n    /**\r\n     * Creates a scene UBO\r\n     * @param name name of the uniform buffer (optional, for debugging purpose only)\r\n     * @param trackUBOsInFrame define if the UBOs should be tracked in the frame (default: undefined - will use the value from Engine._features.trackUbosInFrame)\r\n     * @returns a new ubo\r\n     */\r\n    public createSceneUniformBuffer(name?: string, trackUBOsInFrame?: boolean): UniformBuffer;\r\n    /**\r\n     * Creates a scene UBO\r\n     * @param name name of the uniform buffer (optional, for debugging purpose only)\r\n     * @param options options for creating the scene uniform buffer\r\n     * @returns a new ubo\r\n     */\r\n    public createSceneUniformBuffer(name?: string, options?: ICreateSceneUboOptions): UniformBuffer;\r\n    public createSceneUniformBuffer(name?: string, trackUBOsInFrameOrOptions?: boolean | ICreateSceneUboOptions): UniformBuffer {\r\n        const trackUBOsInFrame = typeof trackUBOsInFrameOrOptions === \"boolean\" ? trackUBOsInFrameOrOptions : trackUBOsInFrameOrOptions?.trackUBOsInFrame;\r\n        const sceneUbo = new UniformBuffer(this._engine, undefined, false, name ?? \"scene\", undefined, trackUBOsInFrame);\r\n        sceneUbo.addUniform(\"viewProjection\", 16);\r\n        sceneUbo.addUniform(\"view\", 16);\r\n        sceneUbo.addUniform(\"projection\", 16);\r\n        sceneUbo.addUniform(\"vEyePosition\", 4);\r\n        sceneUbo.addUniform(\"inverseProjection\", 16);\r\n        return sceneUbo;\r\n    }\r\n\r\n    /**\r\n     * Sets the scene ubo\r\n     * @param ubo the ubo to set for the scene\r\n     */\r\n    public setSceneUniformBuffer(ubo: UniformBuffer): void {\r\n        this._sceneUbo = ubo;\r\n        this._viewUpdateFlag = -1;\r\n        this._projectionUpdateFlag = -1;\r\n    }\r\n\r\n    private _floatingOriginScene: Scene | undefined = undefined;\r\n    /**\r\n     * True if floatingOriginMode was passed to engine or this scene creation otions.\r\n     * This mode avoids floating point imprecision in huge coordinate system by offsetting uniform values before passing to shader, centering camera at origin and displacing rest of scene by camera position\r\n     */\r\n    public get floatingOriginMode(): boolean {\r\n        return this._floatingOriginScene !== undefined;\r\n    }\r\n\r\n    /**\r\n     * When floatingOriginMode is enabled, offset is equal to the eye position. Default to ZeroReadonly when mode is disabled.\r\n     */\r\n    public get floatingOriginOffset(): Vector3 {\r\n        return this.floatingOriginMode ? this._eyePosition : Vector3.ZeroReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets an unique (relatively to the current scene) Id\r\n     * @returns an unique number for the scene\r\n     */\r\n    public getUniqueId() {\r\n        return UniqueIdGenerator.UniqueId;\r\n    }\r\n\r\n    /**\r\n     * Add a mesh to the list of scene's meshes\r\n     * @param newMesh defines the mesh to add\r\n     * @param recursive if all child meshes should also be added to the scene\r\n     */\r\n    public addMesh(newMesh: AbstractMesh, recursive = false) {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n\r\n        this.meshes.push(newMesh);\r\n\r\n        newMesh._resyncLightSources();\r\n\r\n        if (!newMesh.parent) {\r\n            newMesh._addToSceneRootNodes();\r\n        }\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewMeshAddedObservable.notifyObservers(newMesh);\r\n        });\r\n\r\n        if (recursive) {\r\n            const children = newMesh.getChildMeshes();\r\n\r\n            for (const m of children) {\r\n                this.addMesh(m);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh for the list of scene's meshes\r\n     * @param toRemove defines the mesh to remove\r\n     * @param recursive if all child meshes should also be removed from the scene\r\n     * @returns the index where the mesh was in the mesh list\r\n     */\r\n    public removeMesh(toRemove: AbstractMesh, recursive = false): number {\r\n        const index = this.meshes.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            // Remove from the scene if the mesh found\r\n\r\n            this.meshes.splice(index, 1);\r\n\r\n            if (!toRemove.parent) {\r\n                toRemove._removeFromSceneRootNodes();\r\n            }\r\n        }\r\n\r\n        this._inputManager._invalidateMesh(toRemove);\r\n\r\n        this.onMeshRemovedObservable.notifyObservers(toRemove);\r\n        if (recursive) {\r\n            const children = toRemove.getChildMeshes();\r\n            for (const m of children) {\r\n                this.removeMesh(m);\r\n            }\r\n        }\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Add a transform node to the list of scene's transform nodes\r\n     * @param newTransformNode defines the transform node to add\r\n     */\r\n    public addTransformNode(newTransformNode: TransformNode) {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n\r\n        if (newTransformNode.getScene() === this && newTransformNode._indexInSceneTransformNodesArray !== -1) {\r\n            // Already there?\r\n            return;\r\n        }\r\n\r\n        newTransformNode._indexInSceneTransformNodesArray = this.transformNodes.length;\r\n        this.transformNodes.push(newTransformNode);\r\n\r\n        if (!newTransformNode.parent) {\r\n            newTransformNode._addToSceneRootNodes();\r\n        }\r\n\r\n        this.onNewTransformNodeAddedObservable.notifyObservers(newTransformNode);\r\n    }\r\n\r\n    /**\r\n     * Remove a transform node for the list of scene's transform nodes\r\n     * @param toRemove defines the transform node to remove\r\n     * @returns the index where the transform node was in the transform node list\r\n     */\r\n    public removeTransformNode(toRemove: TransformNode): number {\r\n        const index = toRemove._indexInSceneTransformNodesArray;\r\n        if (index !== -1) {\r\n            if (index !== this.transformNodes.length - 1) {\r\n                const lastNode = this.transformNodes[this.transformNodes.length - 1];\r\n                this.transformNodes[index] = lastNode;\r\n                lastNode._indexInSceneTransformNodesArray = index;\r\n            }\r\n\r\n            toRemove._indexInSceneTransformNodesArray = -1;\r\n            this.transformNodes.pop();\r\n            if (!toRemove.parent) {\r\n                toRemove._removeFromSceneRootNodes();\r\n            }\r\n        }\r\n\r\n        this.onTransformNodeRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Remove a skeleton for the list of scene's skeletons\r\n     * @param toRemove defines the skeleton to remove\r\n     * @returns the index where the skeleton was in the skeleton list\r\n     */\r\n    public removeSkeleton(toRemove: Skeleton): number {\r\n        const index = this.skeletons.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            // Remove from the scene if found\r\n            this.skeletons.splice(index, 1);\r\n            this.onSkeletonRemovedObservable.notifyObservers(toRemove);\r\n\r\n            // Clean active container\r\n            this._executeActiveContainerCleanup(this._activeSkeletons);\r\n        }\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Remove a morph target for the list of scene's morph targets\r\n     * @param toRemove defines the morph target to remove\r\n     * @returns the index where the morph target was in the morph target list\r\n     */\r\n    public removeMorphTargetManager(toRemove: MorphTargetManager): number {\r\n        const index = this.morphTargetManagers.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            // Remove from the scene if found\r\n            this.morphTargetManagers.splice(index, 1);\r\n        }\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Remove a light for the list of scene's lights\r\n     * @param toRemove defines the light to remove\r\n     * @returns the index where the light was in the light list\r\n     */\r\n    public removeLight(toRemove: Light): number {\r\n        const index = this.lights.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            // Remove from meshes\r\n            for (const mesh of this.meshes) {\r\n                mesh._removeLightSource(toRemove, false);\r\n            }\r\n\r\n            // Remove from the scene if mesh found\r\n            this.lights.splice(index, 1);\r\n            this.sortLightsByPriority();\r\n\r\n            if (!toRemove.parent) {\r\n                toRemove._removeFromSceneRootNodes();\r\n            }\r\n\r\n            this.onLightRemovedObservable.notifyObservers(toRemove);\r\n        }\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Remove a camera for the list of scene's cameras\r\n     * @param toRemove defines the camera to remove\r\n     * @returns the index where the camera was in the camera list\r\n     */\r\n    public removeCamera(toRemove: Camera): number {\r\n        const index = this.cameras.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            // Remove from the scene if mesh found\r\n            this.cameras.splice(index, 1);\r\n            if (!toRemove.parent) {\r\n                toRemove._removeFromSceneRootNodes();\r\n            }\r\n        }\r\n        // Remove from activeCameras\r\n        if (this.activeCameras) {\r\n            const index2 = this.activeCameras.indexOf(toRemove);\r\n            if (index2 !== -1) {\r\n                // Remove from the scene if mesh found\r\n                this.activeCameras.splice(index2, 1);\r\n            }\r\n        }\r\n        // Reset the activeCamera\r\n        if (this.activeCamera === toRemove) {\r\n            if (this.cameras.length > 0) {\r\n                this.activeCamera = this.cameras[0];\r\n            } else {\r\n                this.activeCamera = null;\r\n            }\r\n        }\r\n        this.onCameraRemovedObservable.notifyObservers(toRemove);\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Remove a particle system for the list of scene's particle systems\r\n     * @param toRemove defines the particle system to remove\r\n     * @returns the index where the particle system was in the particle system list\r\n     */\r\n    public removeParticleSystem(toRemove: IParticleSystem): number {\r\n        const index = this.particleSystems.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.particleSystems.splice(index, 1);\r\n\r\n            // Clean active container\r\n            this._executeActiveContainerCleanup(this._activeParticleSystems);\r\n        }\r\n        this.onParticleSystemRemovedObservable.notifyObservers(toRemove);\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Remove a animation for the list of scene's animations\r\n     * @param toRemove defines the animation to remove\r\n     * @returns the index where the animation was in the animation list\r\n     */\r\n    public removeAnimation(toRemove: Animation): number {\r\n        const index = this.animations.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.animations.splice(index, 1);\r\n        }\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Will stop the animation of the given target\r\n     * @param target - the target\r\n     * @param animationName - the name of the animation to stop (all animations will be stopped if both this and targetMask are empty)\r\n     * @param targetMask - a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)\r\n     */\r\n    public stopAnimation(target: any, animationName?: string, targetMask?: (target: any) => boolean): void {\r\n        // Do nothing as code will be provided by animation component\r\n    }\r\n\r\n    /**\r\n     * Removes the given animation group from this scene.\r\n     * @param toRemove The animation group to remove\r\n     * @returns The index of the removed animation group\r\n     */\r\n    public removeAnimationGroup(toRemove: AnimationGroup): number {\r\n        const index = this.animationGroups.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.animationGroups.splice(index, 1);\r\n        }\r\n        this.onAnimationGroupRemovedObservable.notifyObservers(toRemove);\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given multi-material from this scene.\r\n     * @param toRemove The multi-material to remove\r\n     * @returns The index of the removed multi-material\r\n     */\r\n    public removeMultiMaterial(toRemove: MultiMaterial): number {\r\n        const index = this.multiMaterials.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.multiMaterials.splice(index, 1);\r\n        }\r\n\r\n        this.onMultiMaterialRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given material from this scene.\r\n     * @param toRemove The material to remove\r\n     * @returns The index of the removed material\r\n     */\r\n    public removeMaterial(toRemove: Material): number {\r\n        const index = toRemove._indexInSceneMaterialArray;\r\n        if (index !== -1 && index < this.materials.length) {\r\n            if (index !== this.materials.length - 1) {\r\n                const lastMaterial = this.materials[this.materials.length - 1];\r\n                this.materials[index] = lastMaterial;\r\n                lastMaterial._indexInSceneMaterialArray = index;\r\n            }\r\n\r\n            toRemove._indexInSceneMaterialArray = -1;\r\n            this.materials.pop();\r\n        }\r\n\r\n        this.onMaterialRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given action manager from this scene.\r\n     * @deprecated\r\n     * @param toRemove The action manager to remove\r\n     * @returns The index of the removed action manager\r\n     */\r\n    public removeActionManager(toRemove: AbstractActionManager): number {\r\n        const index = this.actionManagers.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.actionManagers.splice(index, 1);\r\n        }\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given texture from this scene.\r\n     * @param toRemove The texture to remove\r\n     * @returns The index of the removed texture\r\n     */\r\n    public removeTexture(toRemove: BaseTexture): number {\r\n        const index = this.textures.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.textures.splice(index, 1);\r\n        }\r\n        this.onTextureRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given frame graph from this scene.\r\n     * @param toRemove The frame graph to remove\r\n     * @returns The index of the removed frame graph\r\n     */\r\n    public removeFrameGraph(toRemove: FrameGraph): number {\r\n        const index = this.frameGraphs.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.frameGraphs.splice(index, 1);\r\n        }\r\n        this.onFrameGraphRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given object renderer from this scene.\r\n     * @param toRemove The object renderer to remove\r\n     * @returns The index of the removed object renderer\r\n     */\r\n    public removeObjectRenderer(toRemove: ObjectRenderer): number {\r\n        const index = this.objectRenderers.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.objectRenderers.splice(index, 1);\r\n        }\r\n        this.onObjectRendererRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given post-process from this scene.\r\n     * @param toRemove The post-process to remove\r\n     * @returns The index of the removed post-process\r\n     */\r\n    public removePostProcess(toRemove: PostProcess): number {\r\n        const index = this.postProcesses.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.postProcesses.splice(index, 1);\r\n        }\r\n        this.onPostProcessRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Removes the given layer from this scene.\r\n     * @param toRemove The layer to remove\r\n     * @returns The index of the removed layer\r\n     */\r\n    public removeEffectLayer(toRemove: EffectLayer): number {\r\n        const index = this.effectLayers.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.effectLayers.splice(index, 1);\r\n        }\r\n        this.onEffectLayerRemovedObservable.notifyObservers(toRemove);\r\n\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * Adds the given light to this scene\r\n     * @param newLight The light to add\r\n     */\r\n    public addLight(newLight: Light): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.lights.push(newLight);\r\n        this.sortLightsByPriority();\r\n\r\n        if (!newLight.parent) {\r\n            newLight._addToSceneRootNodes();\r\n        }\r\n\r\n        // Add light to all meshes (To support if the light is removed and then re-added)\r\n        for (const mesh of this.meshes) {\r\n            if (mesh.lightSources.indexOf(newLight) === -1) {\r\n                mesh.lightSources.push(newLight);\r\n                mesh._resyncLightSources();\r\n            }\r\n        }\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewLightAddedObservable.notifyObservers(newLight);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Sorts the list list based on light priorities\r\n     */\r\n    public sortLightsByPriority(): void {\r\n        if (this.requireLightSorting) {\r\n            this.lights.sort(LightConstants.CompareLightsPriority);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the given camera to this scene\r\n     * @param newCamera The camera to add\r\n     */\r\n    public addCamera(newCamera: Camera): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n\r\n        this.cameras.push(newCamera);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewCameraAddedObservable.notifyObservers(newCamera);\r\n        });\r\n\r\n        if (!newCamera.parent) {\r\n            newCamera._addToSceneRootNodes();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the given skeleton to this scene\r\n     * @param newSkeleton The skeleton to add\r\n     */\r\n    public addSkeleton(newSkeleton: Skeleton): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.skeletons.push(newSkeleton);\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewSkeletonAddedObservable.notifyObservers(newSkeleton);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given particle system to this scene\r\n     * @param newParticleSystem The particle system to add\r\n     */\r\n    public addParticleSystem(newParticleSystem: IParticleSystem): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.particleSystems.push(newParticleSystem);\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewParticleSystemAddedObservable.notifyObservers(newParticleSystem);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given animation to this scene\r\n     * @param newAnimation The animation to add\r\n     */\r\n    public addAnimation(newAnimation: Animation): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.animations.push(newAnimation);\r\n    }\r\n\r\n    /**\r\n     * Adds the given animation group to this scene.\r\n     * @param newAnimationGroup The animation group to add\r\n     */\r\n    public addAnimationGroup(newAnimationGroup: AnimationGroup): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.animationGroups.push(newAnimationGroup);\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewAnimationGroupAddedObservable.notifyObservers(newAnimationGroup);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given multi-material to this scene\r\n     * @param newMultiMaterial The multi-material to add\r\n     */\r\n    public addMultiMaterial(newMultiMaterial: MultiMaterial): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.multiMaterials.push(newMultiMaterial);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewMultiMaterialAddedObservable.notifyObservers(newMultiMaterial);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given material to this scene\r\n     * @param newMaterial The material to add\r\n     */\r\n    public addMaterial(newMaterial: Material): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n\r\n        if (newMaterial.getScene() === this && newMaterial._indexInSceneMaterialArray !== -1) {\r\n            // Already there??\r\n            return;\r\n        }\r\n\r\n        newMaterial._indexInSceneMaterialArray = this.materials.length;\r\n        this.materials.push(newMaterial);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewMaterialAddedObservable.notifyObservers(newMaterial);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given morph target to this scene\r\n     * @param newMorphTargetManager The morph target to add\r\n     */\r\n    public addMorphTargetManager(newMorphTargetManager: MorphTargetManager): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.morphTargetManagers.push(newMorphTargetManager);\r\n    }\r\n\r\n    /**\r\n     * Adds the given geometry to this scene\r\n     * @param newGeometry The geometry to add\r\n     */\r\n    public addGeometry(newGeometry: Geometry): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n\r\n        if (this._geometriesByUniqueId) {\r\n            this._geometriesByUniqueId[newGeometry.uniqueId] = this.geometries.length;\r\n        }\r\n\r\n        this.geometries.push(newGeometry);\r\n    }\r\n\r\n    /**\r\n     * Adds the given action manager to this scene\r\n     * @deprecated\r\n     * @param newActionManager The action manager to add\r\n     */\r\n    public addActionManager(newActionManager: AbstractActionManager): void {\r\n        this.actionManagers.push(newActionManager);\r\n    }\r\n\r\n    /**\r\n     * Adds the given texture to this scene.\r\n     * @param newTexture The texture to add\r\n     */\r\n    public addTexture(newTexture: BaseTexture): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.textures.push(newTexture);\r\n        this.onNewTextureAddedObservable.notifyObservers(newTexture);\r\n    }\r\n\r\n    /**\r\n     * Adds the given frame graph to this scene.\r\n     * @param newFrameGraph The frame graph to add\r\n     */\r\n    public addFrameGraph(newFrameGraph: FrameGraph): void {\r\n        this.frameGraphs.push(newFrameGraph);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewFrameGraphAddedObservable.notifyObservers(newFrameGraph);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given object renderer to this scene.\r\n     * @param objectRenderer The object renderer to add\r\n     */\r\n    public addObjectRenderer(objectRenderer: ObjectRenderer): void {\r\n        this.objectRenderers.push(objectRenderer);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewObjectRendererAddedObservable.notifyObservers(objectRenderer);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given post process to this scene.\r\n     * @param newPostProcess The post process to add\r\n     */\r\n    public addPostProcess(newPostProcess: PostProcess): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.postProcesses.push(newPostProcess);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewPostProcessAddedObservable.notifyObservers(newPostProcess);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds the given effect layer to this scene.\r\n     * @param newEffectLayer The effect layer to add\r\n     */\r\n    public addEffectLayer(newEffectLayer: EffectLayer): void {\r\n        if (this._blockEntityCollection) {\r\n            return;\r\n        }\r\n        this.effectLayers.push(newEffectLayer);\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewEffectLayerAddedObservable.notifyObservers(newEffectLayer);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Switch active camera\r\n     * @param newCamera defines the new active camera\r\n     * @param attachControl defines if attachControl must be called for the new active camera (default: true)\r\n     */\r\n    public switchActiveCamera(newCamera: Camera, attachControl = true): void {\r\n        const canvas = this._engine.getInputElement();\r\n\r\n        if (!canvas) {\r\n            return;\r\n        }\r\n\r\n        if (this.activeCamera) {\r\n            this.activeCamera.detachControl();\r\n        }\r\n        this.activeCamera = newCamera;\r\n        if (attachControl) {\r\n            newCamera.attachControl();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * sets the active camera of the scene using its Id\r\n     * @param id defines the camera's Id\r\n     * @returns the new active camera or null if none found.\r\n     */\r\n    public setActiveCameraById(id: string): Nullable<Camera> {\r\n        const camera = this.getCameraById(id);\r\n\r\n        if (camera) {\r\n            this.activeCamera = camera;\r\n            return camera;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * sets the active camera of the scene using its name\r\n     * @param name defines the camera's name\r\n     * @returns the new active camera or null if none found.\r\n     */\r\n    public setActiveCameraByName(name: string): Nullable<Camera> {\r\n        const camera = this.getCameraByName(name);\r\n\r\n        if (camera) {\r\n            this.activeCamera = camera;\r\n            return camera;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * get an animation group using its name\r\n     * @param name defines the material's name\r\n     * @returns the animation group or null if none found.\r\n     */\r\n    public getAnimationGroupByName(name: string): Nullable<AnimationGroup> {\r\n        for (let index = 0; index < this.animationGroups.length; index++) {\r\n            if (this.animationGroups[index].name === name) {\r\n                return this.animationGroups[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    private _getMaterial(allowMultiMaterials: boolean, predicate: (m: Material) => boolean): Nullable<Material> {\r\n        for (let index = 0; index < this.materials.length; index++) {\r\n            const material = this.materials[index];\r\n            if (predicate(material)) {\r\n                return material;\r\n            }\r\n        }\r\n        if (allowMultiMaterials) {\r\n            for (let index = 0; index < this.multiMaterials.length; index++) {\r\n                const material = this.multiMaterials[index];\r\n                if (predicate(material)) {\r\n                    return material;\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Get a material using its unique id\r\n     * @param uniqueId defines the material's unique id\r\n     * @param allowMultiMaterials determines whether multimaterials should be considered\r\n     * @returns the material or null if none found.\r\n     * @deprecated Please use getMaterialByUniqueId instead.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public getMaterialByUniqueID(uniqueId: number, allowMultiMaterials: boolean = false): Nullable<Material> {\r\n        return this.getMaterialByUniqueId(uniqueId, allowMultiMaterials);\r\n    }\r\n\r\n    /**\r\n     * Get a material using its unique id\r\n     * @param uniqueId defines the material's unique id\r\n     * @param allowMultiMaterials determines whether multimaterials should be considered\r\n     * @returns the material or null if none found.\r\n     */\r\n    public getMaterialByUniqueId(uniqueId: number, allowMultiMaterials: boolean = false): Nullable<Material> {\r\n        return this._getMaterial(allowMultiMaterials, (m) => m.uniqueId === uniqueId);\r\n    }\r\n\r\n    /**\r\n     * get a material using its id\r\n     * @param id defines the material's Id\r\n     * @param allowMultiMaterials determines whether multimaterials should be considered\r\n     * @returns the material or null if none found.\r\n     */\r\n    public getMaterialById(id: string, allowMultiMaterials: boolean = false): Nullable<Material> {\r\n        return this._getMaterial(allowMultiMaterials, (m) => m.id === id);\r\n    }\r\n\r\n    /**\r\n     * Gets a material using its name\r\n     * @param name defines the material's name\r\n     * @param allowMultiMaterials determines whether multimaterials should be considered\r\n     * @returns the material or null if none found.\r\n     */\r\n    public getMaterialByName(name: string, allowMultiMaterials: boolean = false): Nullable<Material> {\r\n        return this._getMaterial(allowMultiMaterials, (m) => m.name === name);\r\n    }\r\n\r\n    /**\r\n     * Gets a last added material using a given id\r\n     * @param id defines the material's id\r\n     * @param allowMultiMaterials determines whether multimaterials should be considered\r\n     * @returns the last material with the given id or null if none found.\r\n     */\r\n    public getLastMaterialById(id: string, allowMultiMaterials: boolean = false): Nullable<Material> {\r\n        for (let index = this.materials.length - 1; index >= 0; index--) {\r\n            if (this.materials[index].id === id) {\r\n                return this.materials[index];\r\n            }\r\n        }\r\n        if (allowMultiMaterials) {\r\n            for (let index = this.multiMaterials.length - 1; index >= 0; index--) {\r\n                if (this.multiMaterials[index].id === id) {\r\n                    return this.multiMaterials[index];\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Get a texture using its unique id\r\n     * @param uniqueId defines the texture's unique id\r\n     * @returns the texture or null if none found.\r\n     */\r\n    public getTextureByUniqueId(uniqueId: number): Nullable<BaseTexture> {\r\n        for (let index = 0; index < this.textures.length; index++) {\r\n            if (this.textures[index].uniqueId === uniqueId) {\r\n                return this.textures[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a texture using its name\r\n     * @param name defines the texture's name\r\n     * @returns the texture or null if none found.\r\n     */\r\n    public getTextureByName(name: string): Nullable<BaseTexture> {\r\n        for (let index = 0; index < this.textures.length; index++) {\r\n            if (this.textures[index].name === name) {\r\n                return this.textures[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a camera using its Id\r\n     * @param id defines the Id to look for\r\n     * @returns the camera or null if not found\r\n     */\r\n    public getCameraById(id: string): Nullable<Camera> {\r\n        for (let index = 0; index < this.cameras.length; index++) {\r\n            if (this.cameras[index].id === id) {\r\n                return this.cameras[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a camera using its unique Id\r\n     * @param uniqueId defines the unique Id to look for\r\n     * @returns the camera or null if not found\r\n     */\r\n    public getCameraByUniqueId(uniqueId: number): Nullable<Camera> {\r\n        for (let index = 0; index < this.cameras.length; index++) {\r\n            if (this.cameras[index].uniqueId === uniqueId) {\r\n                return this.cameras[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a camera using its name\r\n     * @param name defines the camera's name\r\n     * @returns the camera or null if none found.\r\n     */\r\n    public getCameraByName(name: string): Nullable<Camera> {\r\n        for (let index = 0; index < this.cameras.length; index++) {\r\n            if (this.cameras[index].name === name) {\r\n                return this.cameras[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a bone using its Id\r\n     * @param id defines the bone's Id\r\n     * @returns the bone or null if not found\r\n     */\r\n    public getBoneById(id: string): Nullable<Bone> {\r\n        for (let skeletonIndex = 0; skeletonIndex < this.skeletons.length; skeletonIndex++) {\r\n            const skeleton = this.skeletons[skeletonIndex];\r\n            for (let boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {\r\n                if (skeleton.bones[boneIndex].id === id) {\r\n                    return skeleton.bones[boneIndex];\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a bone using its id\r\n     * @param name defines the bone's name\r\n     * @returns the bone or null if not found\r\n     */\r\n    public getBoneByName(name: string): Nullable<Bone> {\r\n        for (let skeletonIndex = 0; skeletonIndex < this.skeletons.length; skeletonIndex++) {\r\n            const skeleton = this.skeletons[skeletonIndex];\r\n            for (let boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {\r\n                if (skeleton.bones[boneIndex].name === name) {\r\n                    return skeleton.bones[boneIndex];\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a light node using its name\r\n     * @param name defines the light's name\r\n     * @returns the light or null if none found.\r\n     */\r\n    public getLightByName(name: string): Nullable<Light> {\r\n        for (let index = 0; index < this.lights.length; index++) {\r\n            if (this.lights[index].name === name) {\r\n                return this.lights[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a light node using its Id\r\n     * @param id defines the light's Id\r\n     * @returns the light or null if none found.\r\n     */\r\n    public getLightById(id: string): Nullable<Light> {\r\n        for (let index = 0; index < this.lights.length; index++) {\r\n            if (this.lights[index].id === id) {\r\n                return this.lights[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a light node using its scene-generated unique Id\r\n     * @param uniqueId defines the light's unique Id\r\n     * @returns the light or null if none found.\r\n     */\r\n    public getLightByUniqueId(uniqueId: number): Nullable<Light> {\r\n        for (let index = 0; index < this.lights.length; index++) {\r\n            if (this.lights[index].uniqueId === uniqueId) {\r\n                return this.lights[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a particle system by Id\r\n     * @param id defines the particle system Id\r\n     * @returns the corresponding system or null if none found\r\n     */\r\n    public getParticleSystemById(id: string): Nullable<IParticleSystem> {\r\n        for (let index = 0; index < this.particleSystems.length; index++) {\r\n            if (this.particleSystems[index].id === id) {\r\n                return this.particleSystems[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a geometry using its Id\r\n     * @param id defines the geometry's Id\r\n     * @returns the geometry or null if none found.\r\n     */\r\n    public getGeometryById(id: string): Nullable<Geometry> {\r\n        for (let index = 0; index < this.geometries.length; index++) {\r\n            if (this.geometries[index].id === id) {\r\n                return this.geometries[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    private _getGeometryByUniqueId(uniqueId: number): Nullable<Geometry> {\r\n        if (this._geometriesByUniqueId) {\r\n            const index = this._geometriesByUniqueId[uniqueId];\r\n            if (index !== undefined) {\r\n                return this.geometries[index];\r\n            }\r\n        } else {\r\n            for (let index = 0; index < this.geometries.length; index++) {\r\n                if (this.geometries[index].uniqueId === uniqueId) {\r\n                    return this.geometries[index];\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a frame graph using its name\r\n     * @param name defines the frame graph's name\r\n     * @returns the frame graph or null if none found.\r\n     */\r\n    public getFrameGraphByName(name: string): Nullable<FrameGraph> {\r\n        for (let index = 0; index < this.frameGraphs.length; index++) {\r\n            if (this.frameGraphs[index].name === name) {\r\n                return this.frameGraphs[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Add a new geometry to this scene\r\n     * @param geometry defines the geometry to be added to the scene.\r\n     * @param force defines if the geometry must be pushed even if a geometry with this id already exists\r\n     * @returns a boolean defining if the geometry was added or not\r\n     */\r\n    public pushGeometry(geometry: Geometry, force?: boolean): boolean {\r\n        if (!force && this._getGeometryByUniqueId(geometry.uniqueId)) {\r\n            return false;\r\n        }\r\n\r\n        this.addGeometry(geometry);\r\n\r\n        TimingTools.SetImmediate(() => {\r\n            this.onNewGeometryAddedObservable.notifyObservers(geometry);\r\n        });\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Removes an existing geometry\r\n     * @param geometry defines the geometry to be removed from the scene\r\n     * @returns a boolean defining if the geometry was removed or not\r\n     */\r\n    public removeGeometry(geometry: Geometry): boolean {\r\n        let index;\r\n        if (this._geometriesByUniqueId) {\r\n            index = this._geometriesByUniqueId[geometry.uniqueId];\r\n            if (index === undefined) {\r\n                return false;\r\n            }\r\n        } else {\r\n            index = this.geometries.indexOf(geometry);\r\n            if (index < 0) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (index !== this.geometries.length - 1) {\r\n            const lastGeometry = this.geometries[this.geometries.length - 1];\r\n            if (lastGeometry) {\r\n                this.geometries[index] = lastGeometry;\r\n                if (this._geometriesByUniqueId) {\r\n                    this._geometriesByUniqueId[lastGeometry.uniqueId] = index;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._geometriesByUniqueId) {\r\n            this._geometriesByUniqueId[geometry.uniqueId] = undefined;\r\n        }\r\n\r\n        this.geometries.pop();\r\n\r\n        this.onGeometryRemovedObservable.notifyObservers(geometry);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of geometries attached to the scene\r\n     * @returns an array of Geometry\r\n     */\r\n    public getGeometries(): Geometry[] {\r\n        return this.geometries;\r\n    }\r\n\r\n    /**\r\n     * Gets the first added mesh found of a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the mesh found or null if not found at all\r\n     */\r\n    public getMeshById(id: string): Nullable<AbstractMesh> {\r\n        for (let index = 0; index < this.meshes.length; index++) {\r\n            if (this.meshes[index].id === id) {\r\n                return this.meshes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a list of meshes using their Id\r\n     * @param id defines the Id to search for\r\n     * @returns a list of meshes\r\n     */\r\n    public getMeshesById(id: string): Array<AbstractMesh> {\r\n        return this.meshes.filter(function (m) {\r\n            return m.id === id;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the first added transform node found of a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found transform node or null if not found at all.\r\n     */\r\n    public getTransformNodeById(id: string): Nullable<TransformNode> {\r\n        for (let index = 0; index < this.transformNodes.length; index++) {\r\n            if (this.transformNodes[index].id === id) {\r\n                return this.transformNodes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a transform node with its auto-generated unique Id\r\n     * @param uniqueId defines the unique Id to search for\r\n     * @returns the found transform node or null if not found at all.\r\n     */\r\n    public getTransformNodeByUniqueId(uniqueId: number): Nullable<TransformNode> {\r\n        for (let index = 0; index < this.transformNodes.length; index++) {\r\n            if (this.transformNodes[index].uniqueId === uniqueId) {\r\n                return this.transformNodes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a list of transform nodes using their Id\r\n     * @param id defines the Id to search for\r\n     * @returns a list of transform nodes\r\n     */\r\n    public getTransformNodesById(id: string): Array<TransformNode> {\r\n        return this.transformNodes.filter(function (m) {\r\n            return m.id === id;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets a mesh with its auto-generated unique Id\r\n     * @param uniqueId defines the unique Id to search for\r\n     * @returns the found mesh or null if not found at all.\r\n     */\r\n    public getMeshByUniqueId(uniqueId: number): Nullable<AbstractMesh> {\r\n        for (let index = 0; index < this.meshes.length; index++) {\r\n            if (this.meshes[index].uniqueId === uniqueId) {\r\n                return this.meshes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a the last added mesh using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found mesh or null if not found at all.\r\n     */\r\n    public getLastMeshById(id: string): Nullable<AbstractMesh> {\r\n        for (let index = this.meshes.length - 1; index >= 0; index--) {\r\n            if (this.meshes[index].id === id) {\r\n                return this.meshes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a the last transform node using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found mesh or null if not found at all.\r\n     */\r\n    public getLastTransformNodeById(id: string): Nullable<TransformNode> {\r\n        for (let index = this.transformNodes.length - 1; index >= 0; index--) {\r\n            if (this.transformNodes[index].id === id) {\r\n                return this.transformNodes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a the last added node (Mesh, Camera, Light, Bone) using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found node or null if not found at all\r\n     */\r\n    public getLastEntryById(id: string): Nullable<Node> {\r\n        let index: number;\r\n        for (index = this.meshes.length - 1; index >= 0; index--) {\r\n            if (this.meshes[index].id === id) {\r\n                return this.meshes[index];\r\n            }\r\n        }\r\n\r\n        for (index = this.transformNodes.length - 1; index >= 0; index--) {\r\n            if (this.transformNodes[index].id === id) {\r\n                return this.transformNodes[index];\r\n            }\r\n        }\r\n\r\n        for (index = this.cameras.length - 1; index >= 0; index--) {\r\n            if (this.cameras[index].id === id) {\r\n                return this.cameras[index];\r\n            }\r\n        }\r\n\r\n        for (index = this.lights.length - 1; index >= 0; index--) {\r\n            if (this.lights[index].id === id) {\r\n                return this.lights[index];\r\n            }\r\n        }\r\n\r\n        for (index = this.skeletons.length - 1; index >= 0; index--) {\r\n            const skeleton = this.skeletons[index];\r\n            for (let boneIndex = skeleton.bones.length - 1; boneIndex >= 0; boneIndex--) {\r\n                if (skeleton.bones[boneIndex].id === id) {\r\n                    return skeleton.bones[boneIndex];\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a node (Mesh, Camera, Light, Bone) using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found node or null if not found at all\r\n     */\r\n    public getNodeById(id: string): Nullable<Node> {\r\n        const mesh = this.getMeshById(id);\r\n        if (mesh) {\r\n            return mesh;\r\n        }\r\n\r\n        const transformNode = this.getTransformNodeById(id);\r\n        if (transformNode) {\r\n            return transformNode;\r\n        }\r\n\r\n        const light = this.getLightById(id);\r\n        if (light) {\r\n            return light;\r\n        }\r\n\r\n        const camera = this.getCameraById(id);\r\n        if (camera) {\r\n            return camera;\r\n        }\r\n\r\n        const bone = this.getBoneById(id);\r\n        if (bone) {\r\n            return bone;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a node (Mesh, Camera, Light) using a given name\r\n     * @param name defines the name to search for\r\n     * @returns the found node or null if not found at all.\r\n     */\r\n    public getNodeByName(name: string): Nullable<Node> {\r\n        const mesh = this.getMeshByName(name);\r\n        if (mesh) {\r\n            return mesh;\r\n        }\r\n\r\n        const transformNode = this.getTransformNodeByName(name);\r\n        if (transformNode) {\r\n            return transformNode;\r\n        }\r\n\r\n        const light = this.getLightByName(name);\r\n        if (light) {\r\n            return light;\r\n        }\r\n\r\n        const camera = this.getCameraByName(name);\r\n        if (camera) {\r\n            return camera;\r\n        }\r\n\r\n        const bone = this.getBoneByName(name);\r\n        if (bone) {\r\n            return bone;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a mesh using a given name\r\n     * @param name defines the name to search for\r\n     * @returns the found mesh or null if not found at all.\r\n     */\r\n    public getMeshByName(name: string): Nullable<AbstractMesh> {\r\n        for (let index = 0; index < this.meshes.length; index++) {\r\n            if (this.meshes[index].name === name) {\r\n                return this.meshes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a transform node using a given name\r\n     * @param name defines the name to search for\r\n     * @returns the found transform node or null if not found at all.\r\n     */\r\n    public getTransformNodeByName(name: string): Nullable<TransformNode> {\r\n        for (let index = 0; index < this.transformNodes.length; index++) {\r\n            if (this.transformNodes[index].name === name) {\r\n                return this.transformNodes[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a skeleton using a given Id (if many are found, this function will pick the last one)\r\n     * @param id defines the Id to search for\r\n     * @returns the found skeleton or null if not found at all.\r\n     */\r\n    public getLastSkeletonById(id: string): Nullable<Skeleton> {\r\n        for (let index = this.skeletons.length - 1; index >= 0; index--) {\r\n            if (this.skeletons[index].id === id) {\r\n                return this.skeletons[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a skeleton using a given auto generated unique id\r\n     * @param  uniqueId defines the unique id to search for\r\n     * @returns the found skeleton or null if not found at all.\r\n     */\r\n    public getSkeletonByUniqueId(uniqueId: number): Nullable<Skeleton> {\r\n        for (let index = 0; index < this.skeletons.length; index++) {\r\n            if (this.skeletons[index].uniqueId === uniqueId) {\r\n                return this.skeletons[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a skeleton using a given id (if many are found, this function will pick the first one)\r\n     * @param id defines the id to search for\r\n     * @returns the found skeleton or null if not found at all.\r\n     */\r\n    public getSkeletonById(id: string): Nullable<Skeleton> {\r\n        for (let index = 0; index < this.skeletons.length; index++) {\r\n            if (this.skeletons[index].id === id) {\r\n                return this.skeletons[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a skeleton using a given name\r\n     * @param name defines the name to search for\r\n     * @returns the found skeleton or null if not found at all.\r\n     */\r\n    public getSkeletonByName(name: string): Nullable<Skeleton> {\r\n        for (let index = 0; index < this.skeletons.length; index++) {\r\n            if (this.skeletons[index].name === name) {\r\n                return this.skeletons[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a morph target manager  using a given id (if many are found, this function will pick the last one)\r\n     * @param id defines the id to search for\r\n     * @returns the found morph target manager or null if not found at all.\r\n     */\r\n    public getMorphTargetManagerById(id: number): Nullable<MorphTargetManager> {\r\n        for (let index = 0; index < this.morphTargetManagers.length; index++) {\r\n            if (this.morphTargetManagers[index].uniqueId === id) {\r\n                return this.morphTargetManagers[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a morph target using a given id (if many are found, this function will pick the first one)\r\n     * @param id defines the id to search for\r\n     * @returns the found morph target or null if not found at all.\r\n     */\r\n    public getMorphTargetById(id: string): Nullable<MorphTarget> {\r\n        for (let managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {\r\n            const morphTargetManager = this.morphTargetManagers[managerIndex];\r\n            for (let index = 0; index < morphTargetManager.numTargets; ++index) {\r\n                const target = morphTargetManager.getTarget(index);\r\n                if (target.id === id) {\r\n                    return target;\r\n                }\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a morph target using a given name (if many are found, this function will pick the first one)\r\n     * @param name defines the name to search for\r\n     * @returns the found morph target or null if not found at all.\r\n     */\r\n    public getMorphTargetByName(name: string): Nullable<MorphTarget> {\r\n        for (let managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {\r\n            const morphTargetManager = this.morphTargetManagers[managerIndex];\r\n            for (let index = 0; index < morphTargetManager.numTargets; ++index) {\r\n                const target = morphTargetManager.getTarget(index);\r\n                if (target.name === name) {\r\n                    return target;\r\n                }\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a post process using a given name (if many are found, this function will pick the first one)\r\n     * @param name defines the name to search for\r\n     * @returns the found post process or null if not found at all.\r\n     */\r\n    public getPostProcessByName(name: string): Nullable<PostProcess> {\r\n        for (let postProcessIndex = 0; postProcessIndex < this.postProcesses.length; ++postProcessIndex) {\r\n            const postProcess = this.postProcesses[postProcessIndex];\r\n            if (postProcess.name === name) {\r\n                return postProcess;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the given mesh is active\r\n     * @param mesh defines the mesh to look for\r\n     * @returns true if the mesh is in the active list\r\n     */\r\n    public isActiveMesh(mesh: AbstractMesh): boolean {\r\n        return this._activeMeshes.indexOf(mesh) !== -1;\r\n    }\r\n\r\n    /**\r\n     * Return a unique id as a string which can serve as an identifier for the scene\r\n     */\r\n    public get uid(): string {\r\n        if (!this._uid) {\r\n            this._uid = Tools.RandomId();\r\n        }\r\n        return this._uid;\r\n    }\r\n\r\n    /**\r\n     * Add an externally attached data from its key.\r\n     * This method call will fail and return false, if such key already exists.\r\n     * If you don't care and just want to get the data no matter what, use the more convenient getOrAddExternalDataWithFactory() method.\r\n     * @param key the unique key that identifies the data\r\n     * @param data the data object to associate to the key for this Engine instance\r\n     * @returns true if no such key were already present and the data was added successfully, false otherwise\r\n     */\r\n    public addExternalData<T extends object>(key: string, data: T): boolean {\r\n        if (!this._externalData) {\r\n            this._externalData = new StringDictionary<object>();\r\n        }\r\n        return this._externalData.add(key, data);\r\n    }\r\n\r\n    /**\r\n     * Get an externally attached data from its key\r\n     * @param key the unique key that identifies the data\r\n     * @returns the associated data, if present (can be null), or undefined if not present\r\n     */\r\n    public getExternalData<T>(key: string): Nullable<T> {\r\n        if (!this._externalData) {\r\n            return null;\r\n        }\r\n        return <T>this._externalData.get(key);\r\n    }\r\n\r\n    /**\r\n     * Get an externally attached data from its key, create it using a factory if it's not already present\r\n     * @param key the unique key that identifies the data\r\n     * @param factory the factory that will be called to create the instance if and only if it doesn't exists\r\n     * @returns the associated data, can be null if the factory returned null.\r\n     */\r\n    public getOrAddExternalDataWithFactory<T extends object>(key: string, factory: (k: string) => T): T {\r\n        if (!this._externalData) {\r\n            this._externalData = new StringDictionary<object>();\r\n        }\r\n        return <T>this._externalData.getOrAddWithFactory(key, factory);\r\n    }\r\n\r\n    /**\r\n     * Remove an externally attached data from the Engine instance\r\n     * @param key the unique key that identifies the data\r\n     * @returns true if the data was successfully removed, false if it doesn't exist\r\n     */\r\n    public removeExternalData(key: string): boolean {\r\n        return this._externalData.remove(key);\r\n    }\r\n\r\n    private _evaluateSubMesh(subMesh: SubMesh, mesh: AbstractMesh, initialMesh: AbstractMesh, forcePush: boolean): void {\r\n        if (forcePush || subMesh.isInFrustum(this._frustumPlanes)) {\r\n            for (const step of this._evaluateSubMeshStage) {\r\n                step.action(mesh, subMesh);\r\n            }\r\n\r\n            const material = subMesh.getMaterial();\r\n            if (material !== null && material !== undefined) {\r\n                // Render targets\r\n                if (material.hasRenderTargetTextures && material.getRenderTargetTextures != null) {\r\n                    if (this._processedMaterials.indexOf(material) === -1) {\r\n                        this._processedMaterials.push(material);\r\n\r\n                        this._materialsRenderTargets.concatWithNoDuplicate(material.getRenderTargetTextures());\r\n                    }\r\n                }\r\n\r\n                // Dispatch\r\n                this._renderingManager.dispatch(subMesh, mesh, material);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the processed materials smart array preventing retention point in material dispose.\r\n     */\r\n    public freeProcessedMaterials(): void {\r\n        this._processedMaterials.dispose();\r\n    }\r\n\r\n    private _preventFreeActiveMeshesAndRenderingGroups = false;\r\n\r\n    /** Gets or sets a boolean blocking all the calls to freeActiveMeshes and freeRenderingGroups\r\n     * It can be used in order to prevent going through methods freeRenderingGroups and freeActiveMeshes several times to improve performance\r\n     * when disposing several meshes in a row or a hierarchy of meshes.\r\n     * When used, it is the responsibility of the user to blockfreeActiveMeshesAndRenderingGroups back to false.\r\n     */\r\n    public get blockfreeActiveMeshesAndRenderingGroups(): boolean {\r\n        return this._preventFreeActiveMeshesAndRenderingGroups;\r\n    }\r\n\r\n    public set blockfreeActiveMeshesAndRenderingGroups(value: boolean) {\r\n        if (this._preventFreeActiveMeshesAndRenderingGroups === value) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this.freeActiveMeshes();\r\n            this.freeRenderingGroups();\r\n        }\r\n\r\n        this._preventFreeActiveMeshesAndRenderingGroups = value;\r\n    }\r\n\r\n    /**\r\n     * Clear the active meshes smart array preventing retention point in mesh dispose.\r\n     */\r\n    public freeActiveMeshes(): void {\r\n        if (this.blockfreeActiveMeshesAndRenderingGroups) {\r\n            return;\r\n        }\r\n\r\n        this._activeMeshes.dispose();\r\n        if (this.activeCamera && this.activeCamera._activeMeshes) {\r\n            this.activeCamera._activeMeshes.dispose();\r\n        }\r\n        if (this.activeCameras) {\r\n            for (let i = 0; i < this.activeCameras.length; i++) {\r\n                const activeCamera = this.activeCameras[i];\r\n                if (activeCamera && activeCamera._activeMeshes) {\r\n                    activeCamera._activeMeshes.dispose();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the info related to rendering groups preventing retention points during dispose.\r\n     */\r\n    public freeRenderingGroups(): void {\r\n        if (this.blockfreeActiveMeshesAndRenderingGroups) {\r\n            return;\r\n        }\r\n\r\n        if (this._renderingManager) {\r\n            this._renderingManager.freeRenderingGroups();\r\n        }\r\n        if (this.textures) {\r\n            for (let i = 0; i < this.textures.length; i++) {\r\n                const texture = this.textures[i];\r\n                if (texture && (<RenderTargetTexture>texture).renderList) {\r\n                    (<RenderTargetTexture>texture).freeRenderingGroups();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _isInIntermediateRendering(): boolean {\r\n        return this._intermediateRendering;\r\n    }\r\n\r\n    /** @internal */\r\n    public _isInRenderingMeshEvaluation(): boolean {\r\n        return this._renderingMeshEvaluationDepth > 0;\r\n    }\r\n\r\n    /**\r\n     * Lambda returning the list of potentially active meshes.\r\n     */\r\n    public getActiveMeshCandidates: () => ISmartArrayLike<AbstractMesh>;\r\n\r\n    /**\r\n     * Lambda returning the list of potentially active sub meshes.\r\n     */\r\n    public getActiveSubMeshCandidates: (mesh: AbstractMesh) => ISmartArrayLike<SubMesh>;\r\n\r\n    /**\r\n     * Lambda returning the list of potentially intersecting sub meshes.\r\n     */\r\n    public getIntersectingSubMeshCandidates: (mesh: AbstractMesh, localRay: Ray) => ISmartArrayLike<SubMesh>;\r\n\r\n    /**\r\n     * Lambda returning the list of potentially colliding sub meshes.\r\n     */\r\n    public getCollidingSubMeshCandidates: (mesh: AbstractMesh, collider: Collider) => ISmartArrayLike<SubMesh>;\r\n\r\n    /** @internal */\r\n    public _activeMeshesFrozen = false;\r\n    /** @internal */\r\n    public _activeMeshesFrozenButKeepClipping = false;\r\n    private _skipEvaluateActiveMeshesCompletely = false;\r\n    private _freezeActiveMeshesCancel: Nullable<() => void> = null;\r\n\r\n    /**\r\n     * Use this function to stop evaluating active meshes. The current list will be keep alive between frames\r\n     * @param skipEvaluateActiveMeshes defines an optional boolean indicating that the evaluate active meshes step must be completely skipped\r\n     * @param onSuccess optional success callback\r\n     * @param onError optional error callback\r\n     * @param freezeMeshes defines if meshes should be frozen (true by default)\r\n     * @param keepFrustumCulling defines if you want to keep running the frustum clipping (false by default)\r\n     * @returns the current scene\r\n     */\r\n    public freezeActiveMeshes(\r\n        skipEvaluateActiveMeshes = false,\r\n        onSuccess?: () => void,\r\n        onError?: (message: string) => void,\r\n        freezeMeshes = true,\r\n        keepFrustumCulling = false\r\n    ): Scene {\r\n        if (this.frameGraph) {\r\n            // Executes the frame graph once to be sure the culling tasks (if any) are executed and generate the right culled lists\r\n            // (it's possible freezeActiveMeshes is called before the frame graph has been executed for the first time)\r\n            this._renderWithFrameGraph(true, false, true);\r\n\r\n            // Freeze all active meshes of all object renderers in the graph\r\n            const objectRendererTasks = this.frameGraph.getTasksByClassName<FrameGraphObjectRendererTask>([\"FrameGraphObjectRendererTask\", \"FrameGraphGeometryRendererTask\"]);\r\n            for (const task of objectRendererTasks) {\r\n                task.objectRenderer._freezeActiveMeshes(freezeMeshes);\r\n            }\r\n\r\n            // Wait for all object renderers to finish freezing\r\n            this._freezeActiveMeshesCancel = _RetryWithInterval(\r\n                () => {\r\n                    let ok = true;\r\n                    let notCancelled = true;\r\n                    for (const task of objectRendererTasks) {\r\n                        ok &&= task.objectRenderer._isFrozen;\r\n                        notCancelled &&= task.objectRenderer._freezeActiveMeshesCancel !== null;\r\n                    }\r\n                    if (ok) {\r\n                        return true;\r\n                    } else if (!notCancelled) {\r\n                        // At least one object renderer cancelled freezing meshes because of an error\r\n                        // Throws an error that will be caught by _RetryWithInterval.onError\r\n                        throw new Error(\"Freezing active meshes was cancelled\");\r\n                    }\r\n                    return false;\r\n                },\r\n                () => {\r\n                    // All meshes of all object renderers could be frozen correctly\r\n                    this._freezeActiveMeshesCancel = null;\r\n                    this._activeMeshesFrozen = true;\r\n                    this._activeMeshesFrozenButKeepClipping = keepFrustumCulling;\r\n                    this._skipEvaluateActiveMeshesCompletely = skipEvaluateActiveMeshes;\r\n\r\n                    onSuccess?.();\r\n                },\r\n                (err, isTimeout) => {\r\n                    // An error occurred => not all meshes could be frozen\r\n                    // Unfreezes all meshes so that we remain in a valid state\r\n                    this._freezeActiveMeshesCancel = null;\r\n                    this.unfreezeActiveMeshes();\r\n                    if (!isTimeout) {\r\n                        const errMsg = \"Scene: An unexpected error occurred while trying to freeze active meshes.\";\r\n                        if (onError) {\r\n                            onError(errMsg);\r\n                        } else {\r\n                            Logger.Error(errMsg);\r\n                            if (err) {\r\n                                Logger.Error(err);\r\n                                if (err.stack) {\r\n                                    Logger.Error(err.stack);\r\n                                }\r\n                            }\r\n                        }\r\n                    } else {\r\n                        const errMsg = \"Scene: Timeout while waiting for meshes to be frozen.\";\r\n                        if (onError) {\r\n                            onError(errMsg);\r\n                        } else {\r\n                            Logger.Error(errMsg);\r\n                            if (err) {\r\n                                Logger.Error(err);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            );\r\n\r\n            return this;\r\n        }\r\n\r\n        this.executeWhenReady(() => {\r\n            if (!this.activeCamera) {\r\n                if (onError) {\r\n                    onError(\"No active camera found\");\r\n                }\r\n                return;\r\n            }\r\n\r\n            if (!this._frustumPlanes) {\r\n                this.updateTransformMatrix();\r\n            }\r\n\r\n            this._evaluateActiveMeshes();\r\n            this._activeMeshesFrozen = true;\r\n            this._activeMeshesFrozenButKeepClipping = keepFrustumCulling;\r\n            this._skipEvaluateActiveMeshesCompletely = skipEvaluateActiveMeshes;\r\n\r\n            if (freezeMeshes) {\r\n                for (let index = 0; index < this._activeMeshes.length; index++) {\r\n                    this._activeMeshes.data[index]._freeze();\r\n                }\r\n            }\r\n            if (onSuccess) {\r\n                onSuccess();\r\n            }\r\n        });\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Use this function to restart evaluating active meshes on every frame\r\n     * @returns the current scene\r\n     */\r\n    public unfreezeActiveMeshes(): Scene {\r\n        for (let index = 0; index < this.meshes.length; index++) {\r\n            const mesh = this.meshes[index];\r\n            if (mesh._internalAbstractMeshDataInfo) {\r\n                mesh._internalAbstractMeshDataInfo._isActive = false;\r\n            }\r\n        }\r\n\r\n        this._freezeActiveMeshesCancel?.();\r\n        this._freezeActiveMeshesCancel = null;\r\n\r\n        if (this.frameGraph) {\r\n            const objectRendererTasks = this.frameGraph.getTasksByClassName<FrameGraphObjectRendererTask>([\"FrameGraphObjectRendererTask\", \"FrameGraphGeometryRendererTask\"]);\r\n            for (const task of objectRendererTasks) {\r\n                task.objectRenderer._unfreezeActiveMeshes();\r\n            }\r\n        } else {\r\n            for (let index = 0; index < this._activeMeshes.length; index++) {\r\n                this._activeMeshes.data[index]._unFreeze();\r\n            }\r\n        }\r\n\r\n        this._activeMeshesFrozen = false;\r\n        return this;\r\n    }\r\n\r\n    private _executeActiveContainerCleanup(container: SmartArray<any>) {\r\n        const isInFastMode = this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n\r\n        if (!isInFastMode && this._activeMeshesFrozen && this._activeMeshes.length) {\r\n            return; // Do not execute in frozen mode\r\n        }\r\n\r\n        // We need to ensure we are not in the rendering loop\r\n        this.onBeforeRenderObservable.addOnce(() => container.dispose());\r\n    }\r\n\r\n    private _evaluateActiveMeshes(): void {\r\n        if (this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\r\n            if (this._activeMeshes.length > 0) {\r\n                this.activeCamera?._activeMeshes.reset();\r\n                this._activeMeshes.reset();\r\n                this._renderingManager.reset();\r\n                this._processedMaterials.reset();\r\n                this._activeParticleSystems.reset();\r\n                this._activeSkeletons.reset();\r\n                this._softwareSkinnedMeshes.reset();\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (this._activeMeshesFrozen && this._activeMeshes.length) {\r\n            if (!this._skipEvaluateActiveMeshesCompletely) {\r\n                const len = this._activeMeshes.length;\r\n                for (let i = 0; i < len; i++) {\r\n                    const mesh = this._activeMeshes.data[i];\r\n                    mesh.computeWorldMatrix();\r\n                }\r\n            }\r\n\r\n            if (this._activeParticleSystems) {\r\n                const psLength = this._activeParticleSystems.length;\r\n                for (let i = 0; i < psLength; i++) {\r\n                    this._activeParticleSystems.data[i].animate();\r\n                }\r\n            }\r\n\r\n            this._renderingManager.resetSprites();\r\n\r\n            return;\r\n        }\r\n\r\n        if (!this.activeCamera) {\r\n            return;\r\n        }\r\n\r\n        this.onBeforeActiveMeshesEvaluationObservable.notifyObservers(this);\r\n\r\n        this.activeCamera._activeMeshes.reset();\r\n        this._activeMeshes.reset();\r\n        this._renderingManager.reset();\r\n        this._processedMaterials.reset();\r\n        this._activeParticleSystems.reset();\r\n        this._activeSkeletons.reset();\r\n        this._softwareSkinnedMeshes.reset();\r\n        this._materialsRenderTargets.reset();\r\n\r\n        for (const step of this._beforeEvaluateActiveMeshStage) {\r\n            step.action();\r\n        }\r\n\r\n        // Determine mesh candidates\r\n        const meshes = this.getActiveMeshCandidates();\r\n\r\n        // Check each mesh\r\n        const len = meshes.length;\r\n        for (let i = 0; i < len; i++) {\r\n            const mesh = meshes.data[i];\r\n            let currentLOD = mesh._internalAbstractMeshDataInfo._currentLOD.get(this.activeCamera);\r\n            if (currentLOD) {\r\n                currentLOD[1] = -1;\r\n            } else {\r\n                currentLOD = [mesh, -1];\r\n                mesh._internalAbstractMeshDataInfo._currentLOD.set(this.activeCamera, currentLOD);\r\n            }\r\n            if (mesh.isBlocked) {\r\n                continue;\r\n            }\r\n\r\n            this._totalVertices.addCount(mesh.getTotalVertices(), false);\r\n\r\n            if (!mesh.isReady() || !mesh.isEnabled() || mesh.scaling.hasAZeroComponent) {\r\n                continue;\r\n            }\r\n\r\n            mesh.computeWorldMatrix();\r\n\r\n            // Intersections\r\n            if (mesh.actionManager && mesh.actionManager.hasSpecificTriggers2(Constants.ACTION_OnIntersectionEnterTrigger, Constants.ACTION_OnIntersectionExitTrigger)) {\r\n                this._meshesForIntersections.pushNoDuplicate(mesh);\r\n            }\r\n\r\n            // Switch to current LOD\r\n            let meshToRender = this.customLODSelector ? this.customLODSelector(mesh, this.activeCamera) : mesh.getLOD(this.activeCamera);\r\n            currentLOD[0] = meshToRender;\r\n            currentLOD[1] = this._frameId;\r\n            if (meshToRender === undefined || meshToRender === null) {\r\n                continue;\r\n            }\r\n\r\n            // Compute world matrix if LOD is billboard\r\n            if (meshToRender !== mesh && meshToRender.billboardMode !== 0) {\r\n                meshToRender.computeWorldMatrix();\r\n            }\r\n\r\n            mesh._preActivate();\r\n\r\n            if (\r\n                mesh.isVisible &&\r\n                mesh.visibility > 0 &&\r\n                (mesh.layerMask & this.activeCamera.layerMask) !== 0 &&\r\n                (this._skipFrustumClipping || mesh.alwaysSelectAsActiveMesh || mesh.isInFrustum(this._frustumPlanes))\r\n            ) {\r\n                this._activeMeshes.push(mesh);\r\n                this.activeCamera._activeMeshes.push(mesh);\r\n\r\n                if (meshToRender !== mesh) {\r\n                    meshToRender._activate(this._renderId, false);\r\n                }\r\n\r\n                for (const step of this._preActiveMeshStage) {\r\n                    step.action(mesh);\r\n                }\r\n\r\n                if (mesh._activate(this._renderId, false)) {\r\n                    if (!mesh.isAnInstance) {\r\n                        meshToRender._internalAbstractMeshDataInfo._onlyForInstances = false;\r\n                    } else {\r\n                        if (mesh._internalAbstractMeshDataInfo._actAsRegularMesh) {\r\n                            meshToRender = mesh;\r\n                        }\r\n                    }\r\n                    meshToRender._internalAbstractMeshDataInfo._isActive = true;\r\n                    this._activeMesh(mesh, meshToRender);\r\n                }\r\n\r\n                mesh._postActivate();\r\n            }\r\n        }\r\n\r\n        this.onAfterActiveMeshesEvaluationObservable.notifyObservers(this);\r\n\r\n        // Particle systems\r\n        if (this.particlesEnabled) {\r\n            this.onBeforeParticlesRenderingObservable.notifyObservers(this);\r\n            for (let particleIndex = 0; particleIndex < this.particleSystems.length; particleIndex++) {\r\n                const particleSystem = this.particleSystems[particleIndex];\r\n\r\n                if (!particleSystem.isStarted() || !particleSystem.emitter) {\r\n                    continue;\r\n                }\r\n\r\n                const emitter = <any>particleSystem.emitter;\r\n                if (!emitter.position || emitter.isEnabled()) {\r\n                    this._activeParticleSystems.push(particleSystem);\r\n                    particleSystem.animate();\r\n                    this._renderingManager.dispatchParticles(particleSystem);\r\n                }\r\n            }\r\n            this.onAfterParticlesRenderingObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _prepareSkeleton(mesh: AbstractMesh): void {\r\n        if (!this._skeletonsEnabled || !mesh.skeleton) {\r\n            return;\r\n        }\r\n\r\n        if (this._activeSkeletons.pushNoDuplicate(mesh.skeleton)) {\r\n            mesh.skeleton.prepare();\r\n            this._activeBones.addCount(mesh.skeleton.bones.length, false);\r\n        }\r\n\r\n        if (!mesh.computeBonesUsingShaders) {\r\n            if (this._softwareSkinnedMeshes.pushNoDuplicate(<Mesh>mesh) && this.frameGraph) {\r\n                (<Mesh>mesh).applySkeleton(mesh.skeleton);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _activeMesh(sourceMesh: AbstractMesh, mesh: AbstractMesh): void {\r\n        this._prepareSkeleton(mesh);\r\n\r\n        let forcePush = sourceMesh.hasInstances || sourceMesh.isAnInstance || this.dispatchAllSubMeshesOfActiveMeshes || this._skipFrustumClipping || mesh.alwaysSelectAsActiveMesh;\r\n\r\n        if (mesh && mesh.subMeshes && mesh.subMeshes.length > 0) {\r\n            const subMeshes = this.getActiveSubMeshCandidates(mesh);\r\n            const len = subMeshes.length;\r\n            forcePush = forcePush || len === 1;\r\n            for (let i = 0; i < len; i++) {\r\n                const subMesh = subMeshes.data[i];\r\n                this._evaluateSubMesh(subMesh, mesh, sourceMesh, forcePush);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the transform matrix to update from the current active camera\r\n     * @param force defines a boolean used to force the update even if cache is up to date\r\n     */\r\n    public updateTransformMatrix(force?: boolean): void {\r\n        const activeCamera = this.activeCamera;\r\n        if (!activeCamera) {\r\n            return;\r\n        }\r\n\r\n        if (activeCamera._renderingMultiview) {\r\n            const leftCamera = activeCamera._rigCameras[0];\r\n            const rightCamera = activeCamera._rigCameras[1];\r\n            this.setTransformMatrix(leftCamera.getViewMatrix(), leftCamera.getProjectionMatrix(force), rightCamera.getViewMatrix(), rightCamera.getProjectionMatrix(force));\r\n        } else {\r\n            this.setTransformMatrix(activeCamera.getViewMatrix(), activeCamera.getProjectionMatrix(force));\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _useCurrentFrameBuffer = false;\r\n\r\n    private _bindFrameBuffer(camera: Nullable<Camera>, clear = true) {\r\n        if (!this._useCurrentFrameBuffer) {\r\n            if (camera && camera._multiviewTexture) {\r\n                camera._multiviewTexture._bindFrameBuffer();\r\n            } else if (camera && camera.outputRenderTarget) {\r\n                camera.outputRenderTarget._bindFrameBuffer();\r\n            } else {\r\n                if (!this._engine._currentFrameBufferIsDefaultFrameBuffer()) {\r\n                    this._engine.restoreDefaultFramebuffer();\r\n                }\r\n            }\r\n        }\r\n        if (clear) {\r\n            this._clearFrameBuffer(camera);\r\n        }\r\n    }\r\n\r\n    private _clearFrameBuffer(camera: Nullable<Camera>) {\r\n        // we assume the framebuffer currently bound is the right one\r\n        if (camera && camera._multiviewTexture) {\r\n            // no clearing\r\n        } else if (camera && camera.outputRenderTarget && !camera._renderingMultiview) {\r\n            const rtt = camera.outputRenderTarget;\r\n            if (rtt.onClearObservable.hasObservers()) {\r\n                rtt.onClearObservable.notifyObservers(this._engine);\r\n            } else if (!rtt.skipInitialClear && !camera.isRightCamera) {\r\n                if (this.autoClear) {\r\n                    this._engine.clear(rtt.clearColor || this._clearColor, !rtt._cleared, true, true);\r\n                }\r\n                rtt._cleared = true;\r\n            }\r\n        } else {\r\n            if (!this._defaultFrameBufferCleared) {\r\n                this._defaultFrameBufferCleared = true;\r\n                this._clear();\r\n            } else {\r\n                this._engine.clear(null, false, true, true);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _allowPostProcessClearColor = true;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _renderForCamera(camera: Camera, rigParent?: Camera, bindFrameBuffer = true): void {\r\n        if (camera && camera._skipRendering) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._engine;\r\n\r\n        // Use _activeCamera instead of activeCamera to avoid onActiveCameraChanged\r\n        this._activeCamera = camera;\r\n\r\n        if (!this.activeCamera) {\r\n            throw new Error(\"Active camera not set\");\r\n        }\r\n\r\n        // Viewport\r\n        engine.setViewport(this.activeCamera.viewport);\r\n\r\n        // Camera\r\n        this.resetCachedMaterial();\r\n        this._renderId++;\r\n\r\n        if (!this.prePass && bindFrameBuffer) {\r\n            let skipInitialClear = true;\r\n            if (camera._renderingMultiview && camera.outputRenderTarget) {\r\n                skipInitialClear = camera.outputRenderTarget.skipInitialClear;\r\n                if (this.autoClear) {\r\n                    this._defaultFrameBufferCleared = false;\r\n                    camera.outputRenderTarget.skipInitialClear = false;\r\n                }\r\n            }\r\n            this._bindFrameBuffer(this._activeCamera);\r\n            if (camera._renderingMultiview && camera.outputRenderTarget) {\r\n                camera.outputRenderTarget.skipInitialClear = skipInitialClear;\r\n            }\r\n        }\r\n\r\n        this.updateTransformMatrix();\r\n\r\n        this.onBeforeCameraRenderObservable.notifyObservers(this.activeCamera);\r\n\r\n        // Set the render pass id before evaluating active meshes so that instance registration in WebGPU (which is per render pass id) uses the correct pass id\r\n        this._engine.currentRenderPassId = camera.outputRenderTarget?.renderPassId ?? camera.renderPassId ?? Constants.RENDERPASS_MAIN;\r\n\r\n        // Meshes\r\n        this._evaluateActiveMeshes();\r\n\r\n        // Software skinning\r\n        for (let softwareSkinnedMeshIndex = 0; softwareSkinnedMeshIndex < this._softwareSkinnedMeshes.length; softwareSkinnedMeshIndex++) {\r\n            const mesh = this._softwareSkinnedMeshes.data[softwareSkinnedMeshIndex];\r\n\r\n            mesh.applySkeleton(<Skeleton>mesh.skeleton);\r\n        }\r\n\r\n        // Render targets\r\n        this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);\r\n\r\n        this._renderTargets.concatWithNoDuplicate(this._materialsRenderTargets);\r\n\r\n        if (camera.customRenderTargets && camera.customRenderTargets.length > 0) {\r\n            this._renderTargets.concatWithNoDuplicate(camera.customRenderTargets);\r\n        }\r\n\r\n        if (rigParent && rigParent.customRenderTargets && rigParent.customRenderTargets.length > 0) {\r\n            this._renderTargets.concatWithNoDuplicate(rigParent.customRenderTargets);\r\n        }\r\n\r\n        if (this.environmentTexture && this.environmentTexture.isRenderTarget) {\r\n            this._renderTargets.pushNoDuplicate(this.environmentTexture as RenderTargetTexture);\r\n        }\r\n\r\n        // Collects render targets from external components.\r\n        for (const step of this._gatherActiveCameraRenderTargetsStage) {\r\n            step.action(this._renderTargets);\r\n        }\r\n\r\n        let needRebind = false;\r\n        if (this.renderTargetsEnabled) {\r\n            this._intermediateRendering = true;\r\n\r\n            let currentBoundingBoxMeshList: Array<BoundingBox> | undefined;\r\n\r\n            if (this._renderTargets.length > 0) {\r\n                Tools.StartPerformanceCounter(\"Render targets\", this._renderTargets.length > 0);\r\n\r\n                // The cast to \"any\" is to avoid an error in ES6 in case you don't import boundingBoxRenderer\r\n                const boundingBoxRenderer = (this as any).getBoundingBoxRenderer?.() as Nullable<BoundingBoxRenderer>;\r\n\r\n                for (let renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {\r\n                    const renderTarget = this._renderTargets.data[renderIndex];\r\n                    if (renderTarget._shouldRender()) {\r\n                        this._renderId++;\r\n                        const hasSpecialRenderTargetCamera = renderTarget.activeCamera && renderTarget.activeCamera !== this.activeCamera;\r\n                        if (boundingBoxRenderer && !currentBoundingBoxMeshList) {\r\n                            // Saves the current bounding box mesh list (potentially built by the call to _evaluateActiveMeshes above), which will be reset/updated when processing this target\r\n                            currentBoundingBoxMeshList = boundingBoxRenderer.renderList.length > 0 ? boundingBoxRenderer.renderList.data.slice() : [];\r\n                            currentBoundingBoxMeshList.length = boundingBoxRenderer.renderList.length;\r\n                        }\r\n                        renderTarget.render(<boolean>hasSpecialRenderTargetCamera, this.dumpNextRenderTargets);\r\n                        needRebind = true;\r\n                    }\r\n                }\r\n\r\n                if (boundingBoxRenderer && currentBoundingBoxMeshList) {\r\n                    boundingBoxRenderer.renderList.data = currentBoundingBoxMeshList;\r\n                    boundingBoxRenderer.renderList.length = currentBoundingBoxMeshList.length;\r\n                }\r\n\r\n                Tools.EndPerformanceCounter(\"Render targets\", this._renderTargets.length > 0);\r\n\r\n                this._renderId++;\r\n            }\r\n\r\n            if (this._cameraDrawRenderTargetStage.length > 0) {\r\n                // The cast to \"any\" is to avoid an error in ES6 in case you don't import boundingBoxRenderer\r\n                const boundingBoxRenderer = (this as any).getBoundingBoxRenderer?.() as Nullable<BoundingBoxRenderer>;\r\n\r\n                if (boundingBoxRenderer && !currentBoundingBoxMeshList) {\r\n                    // Saves the current bounding box mesh list (potentially built by the call to _evaluateActiveMeshes above), which can be reset/updated during the loop below\r\n                    currentBoundingBoxMeshList = boundingBoxRenderer.renderList.length > 0 ? boundingBoxRenderer.renderList.data.slice() : [];\r\n                    currentBoundingBoxMeshList.length = boundingBoxRenderer.renderList.length;\r\n                }\r\n\r\n                for (const step of this._cameraDrawRenderTargetStage) {\r\n                    // effect layer call object renderer in this step so bounding box render list must be restored\r\n                    needRebind = step.action(this.activeCamera) || needRebind;\r\n                }\r\n\r\n                if (boundingBoxRenderer && currentBoundingBoxMeshList) {\r\n                    boundingBoxRenderer.renderList.data = currentBoundingBoxMeshList;\r\n                    boundingBoxRenderer.renderList.length = currentBoundingBoxMeshList.length;\r\n                }\r\n            }\r\n\r\n            this._intermediateRendering = false;\r\n        }\r\n\r\n        // Restore framebuffer after rendering to targets\r\n        if (needRebind && !this.prePass) {\r\n            this._bindFrameBuffer(this._activeCamera, false);\r\n            this.updateTransformMatrix();\r\n        }\r\n\r\n        this.onAfterRenderTargetsRenderObservable.notifyObservers(this);\r\n\r\n        // Prepare Frame\r\n        if (this.postProcessManager && !camera._multiviewTexture && !this.prePass) {\r\n            this.postProcessManager._prepareFrame();\r\n        }\r\n\r\n        // Before Camera Draw\r\n        for (const step of this._beforeCameraDrawStage) {\r\n            step.action(this.activeCamera);\r\n        }\r\n\r\n        // Render\r\n        this.onBeforeDrawPhaseObservable.notifyObservers(this);\r\n\r\n        const fastSnapshotMode = engine.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n        if (fastSnapshotMode) {\r\n            this.finalizeSceneUbo();\r\n        }\r\n        this._renderingManager.render(null, null, true, !fastSnapshotMode);\r\n        this.onAfterDrawPhaseObservable.notifyObservers(this);\r\n\r\n        // After Camera Draw\r\n        for (const step of this._afterCameraDrawStage) {\r\n            step.action(this.activeCamera);\r\n        }\r\n\r\n        // Finalize frame\r\n        if (this.postProcessManager && !camera._multiviewTexture) {\r\n            // if the camera has an output render target, render the post process to the render target\r\n            const texture = camera.outputRenderTarget ? camera.outputRenderTarget.renderTarget! : undefined;\r\n            this.postProcessManager._finalizeFrame(camera.isIntermediate, texture);\r\n        }\r\n\r\n        // After post process\r\n        for (const step of this._afterCameraPostProcessStage) {\r\n            step.action(this.activeCamera);\r\n        }\r\n\r\n        // Reset some special arrays\r\n        this._renderTargets.reset();\r\n\r\n        this.onAfterCameraRenderObservable.notifyObservers(this.activeCamera);\r\n    }\r\n\r\n    private _processSubCameras(camera: Camera, bindFrameBuffer = true): void {\r\n        if (camera.cameraRigMode === Constants.RIG_MODE_NONE || camera._renderingMultiview) {\r\n            if (camera._renderingMultiview && !this._multiviewSceneUbo) {\r\n                this._createMultiviewUbo();\r\n            }\r\n            this._renderForCamera(camera, undefined, bindFrameBuffer);\r\n            this.onAfterRenderCameraObservable.notifyObservers(camera);\r\n            return;\r\n        }\r\n\r\n        if (camera._useMultiviewToSingleView) {\r\n            this._renderMultiviewToSingleView(camera);\r\n        } else {\r\n            // rig cameras\r\n            this.onBeforeCameraRenderObservable.notifyObservers(camera);\r\n            for (let index = 0; index < camera._rigCameras.length; index++) {\r\n                this._renderForCamera(camera._rigCameras[index], camera);\r\n            }\r\n        }\r\n\r\n        // Use _activeCamera instead of activeCamera to avoid onActiveCameraChanged\r\n        this._activeCamera = camera;\r\n        this.updateTransformMatrix();\r\n        this.onAfterRenderCameraObservable.notifyObservers(camera);\r\n    }\r\n\r\n    private _checkIntersections(): void {\r\n        for (let index = 0; index < this._meshesForIntersections.length; index++) {\r\n            const sourceMesh = this._meshesForIntersections.data[index];\r\n\r\n            if (!sourceMesh.actionManager) {\r\n                continue;\r\n            }\r\n\r\n            for (let actionIndex = 0; sourceMesh.actionManager && actionIndex < sourceMesh.actionManager.actions.length; actionIndex++) {\r\n                const action: IAction = sourceMesh.actionManager.actions[actionIndex];\r\n\r\n                if (action.trigger === Constants.ACTION_OnIntersectionEnterTrigger || action.trigger === Constants.ACTION_OnIntersectionExitTrigger) {\r\n                    const parameters = action.getTriggerParameter();\r\n                    const otherMesh = parameters.mesh ? parameters.mesh : parameters;\r\n\r\n                    const areIntersecting = otherMesh.intersectsMesh(sourceMesh, parameters.usePreciseIntersection);\r\n                    const currentIntersectionInProgress = sourceMesh._intersectionsInProgress.indexOf(otherMesh);\r\n\r\n                    if (areIntersecting && currentIntersectionInProgress === -1) {\r\n                        if (action.trigger === Constants.ACTION_OnIntersectionEnterTrigger) {\r\n                            action._executeCurrent(ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));\r\n                            sourceMesh._intersectionsInProgress.push(otherMesh);\r\n                        } else if (action.trigger === Constants.ACTION_OnIntersectionExitTrigger) {\r\n                            sourceMesh._intersectionsInProgress.push(otherMesh);\r\n                        }\r\n                    } else if (!areIntersecting && currentIntersectionInProgress > -1) {\r\n                        //They intersected, and now they don't.\r\n\r\n                        //is this trigger an exit trigger? execute an event.\r\n                        if (action.trigger === Constants.ACTION_OnIntersectionExitTrigger) {\r\n                            action._executeCurrent(ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));\r\n                        }\r\n\r\n                        //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.\r\n                        if (\r\n                            !sourceMesh.actionManager.hasSpecificTrigger(Constants.ACTION_OnIntersectionExitTrigger, (parameter) => {\r\n                                const parameterMesh = parameter.mesh ? parameter.mesh : parameter;\r\n                                return otherMesh === parameterMesh;\r\n                            }) ||\r\n                            action.trigger === Constants.ACTION_OnIntersectionExitTrigger\r\n                        ) {\r\n                            sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _advancePhysicsEngineStep(step: number) {\r\n        // Do nothing. Code will be replaced if physics engine component is referenced\r\n    }\r\n\r\n    /**\r\n     * User updatable function that will return a deterministic frame time when engine is in deterministic lock step mode\r\n     * @returns the frame time\r\n     */\r\n    public getDeterministicFrameTime: () => number = () => {\r\n        return this._engine.getTimeStep();\r\n    };\r\n\r\n    /** @internal */\r\n    public _animate(customDeltaTime?: number): void {\r\n        // Nothing to do as long as Animatable have not been imported.\r\n    }\r\n\r\n    /** Execute all animations (for a frame) */\r\n    public animate() {\r\n        if (this._engine.isDeterministicLockStep()) {\r\n            let deltaTime = Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime)) + this._timeAccumulator;\r\n\r\n            const defaultFrameTime = this._engine.getTimeStep();\r\n            const defaultFPS = 1000.0 / defaultFrameTime / 1000.0;\r\n\r\n            let stepsTaken = 0;\r\n\r\n            const maxSubSteps = this._engine.getLockstepMaxSteps();\r\n\r\n            let internalSteps = Math.floor(deltaTime / defaultFrameTime);\r\n            internalSteps = Math.min(internalSteps, maxSubSteps);\r\n\r\n            while (deltaTime > 0 && stepsTaken < internalSteps) {\r\n                this.onBeforeStepObservable.notifyObservers(this);\r\n\r\n                // Animations\r\n                this._animationRatio = defaultFrameTime * defaultFPS;\r\n                this._animate(defaultFrameTime);\r\n                this.onAfterAnimationsObservable.notifyObservers(this);\r\n\r\n                // Physics\r\n                if (this.physicsEnabled) {\r\n                    this._advancePhysicsEngineStep(defaultFrameTime);\r\n                }\r\n\r\n                this.onAfterStepObservable.notifyObservers(this);\r\n                this._currentStepId++;\r\n\r\n                stepsTaken++;\r\n                deltaTime -= defaultFrameTime;\r\n            }\r\n\r\n            this._timeAccumulator = deltaTime < 0 ? 0 : deltaTime;\r\n        } else {\r\n            // Animations\r\n            const deltaTime = this.useConstantAnimationDeltaTime ? 16 : Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime));\r\n            this._animationRatio = deltaTime * (60.0 / 1000.0);\r\n            this._animate();\r\n            this.onAfterAnimationsObservable.notifyObservers(this);\r\n\r\n            // Physics\r\n            if (this.physicsEnabled) {\r\n                this._advancePhysicsEngineStep(deltaTime);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _clear(): void {\r\n        if (this.autoClearDepthAndStencil || this.autoClear) {\r\n            this._engine.clear(this._clearColor, this.autoClear || this.forceWireframe || this.forcePointsCloud, this.autoClearDepthAndStencil, this.autoClearDepthAndStencil);\r\n        }\r\n    }\r\n\r\n    private _checkCameraRenderTarget(camera: Nullable<Camera>) {\r\n        if (camera?.outputRenderTarget && !camera?.isRigCamera) {\r\n            camera.outputRenderTarget._cleared = false;\r\n        }\r\n        if (camera?.rigCameras?.length) {\r\n            for (let i = 0; i < camera.rigCameras.length; ++i) {\r\n                const rtt = camera.rigCameras[i].outputRenderTarget;\r\n                if (rtt) {\r\n                    rtt._cleared = false;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the draw wrappers cache of all meshes\r\n     * @param passId If provided, releases only the draw wrapper corresponding to this render pass id\r\n     */\r\n    public resetDrawCache(passId?: number): void {\r\n        if (!this.meshes) {\r\n            return;\r\n        }\r\n\r\n        for (const mesh of this.meshes) {\r\n            mesh.resetDrawCache(passId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If this function is defined it will take precedence over the standard render() function.\r\n     */\r\n    public customRenderFunction?: (updateCameras: boolean, ignoreAnimations: boolean) => void;\r\n\r\n    private _renderWithFrameGraph(updateCameras = true, _ignoreAnimations = false, forceUpdateWorldMatrix = false): void {\r\n        this.activeCamera = null;\r\n        this.activeCameras = null;\r\n\r\n        // Update Cameras\r\n        if (updateCameras) {\r\n            for (const camera of this.cameras) {\r\n                camera.update();\r\n                if (camera.cameraRigMode !== Constants.RIG_MODE_NONE) {\r\n                    // rig cameras\r\n                    for (let index = 0; index < camera._rigCameras.length; index++) {\r\n                        camera._rigCameras[index].update();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this.onBeforeRenderObservable.notifyObservers(this);\r\n\r\n        this._renderingMeshEvaluationDepth++;\r\n        try {\r\n            this._renderWithFrameGraphAfterBeforeRender(forceUpdateWorldMatrix);\r\n        } finally {\r\n            this._renderingMeshEvaluationDepth--;\r\n        }\r\n    }\r\n\r\n    private _renderWithFrameGraphAfterBeforeRender(forceUpdateWorldMatrix: boolean): void {\r\n        // Customs render targets\r\n        this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);\r\n\r\n        this._renderTargets.reset();\r\n\r\n        const currentActiveCamera = this._frameGraph?.findMainCamera() ?? null;\r\n        if (this.renderTargetsEnabled) {\r\n            if (this.environmentTexture && this.environmentTexture.isRenderTarget) {\r\n                this._renderTargets.pushNoDuplicate(this.environmentTexture as RenderTargetTexture);\r\n            }\r\n\r\n            this._renderTargets.concatWithNoDuplicate(this.customRenderTargets);\r\n\r\n            Tools.StartPerformanceCounter(\"Custom render targets\", this._renderTargets.length > 0);\r\n            for (let customIndex = 0; customIndex < this._renderTargets.length; customIndex++) {\r\n                const renderTarget = this._renderTargets.data[customIndex];\r\n                const activeCamera = renderTarget.activeCamera || currentActiveCamera;\r\n\r\n                this._renderRenderTarget(renderTarget, activeCamera, true, this.dumpNextRenderTargets);\r\n            }\r\n            Tools.EndPerformanceCounter(\"Custom render targets\", this._renderTargets.length > 0);\r\n            this._renderId++;\r\n        }\r\n\r\n        this.onAfterRenderTargetsRenderObservable.notifyObservers(this);\r\n\r\n        // We must keep these steps because the procedural texture component relies on them.\r\n        for (const step of this._beforeClearStage) {\r\n            step.action();\r\n        }\r\n\r\n        // Process meshes\r\n        if (this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\r\n            this._activeParticleSystems.reset();\r\n            this._activeSkeletons.reset();\r\n            this._softwareSkinnedMeshes.reset();\r\n        } else {\r\n            const meshes = this.getActiveMeshCandidates();\r\n            const len = meshes.length;\r\n\r\n            if (!this._activeMeshesFrozen) {\r\n                // Meshes are not frozen\r\n                this._activeParticleSystems.reset();\r\n                this._activeSkeletons.reset();\r\n                this._softwareSkinnedMeshes.reset();\r\n\r\n                for (let i = 0; i < len; i++) {\r\n                    const mesh = meshes.data[i];\r\n\r\n                    mesh._internalAbstractMeshDataInfo._wasActiveLastFrame = false;\r\n\r\n                    if (mesh.isBlocked) {\r\n                        continue;\r\n                    }\r\n\r\n                    this._totalVertices.addCount(mesh.getTotalVertices(), false);\r\n\r\n                    if (!mesh.isReady() || !mesh.isEnabled() || mesh.scaling.hasAZeroComponent) {\r\n                        continue;\r\n                    }\r\n\r\n                    mesh.computeWorldMatrix(forceUpdateWorldMatrix);\r\n\r\n                    if (mesh.actionManager && mesh.actionManager.hasSpecificTriggers2(Constants.ACTION_OnIntersectionEnterTrigger, Constants.ACTION_OnIntersectionExitTrigger)) {\r\n                        this._meshesForIntersections.pushNoDuplicate(mesh);\r\n                    }\r\n                }\r\n\r\n                // Animate Particle systems\r\n                if (this.particlesEnabled) {\r\n                    for (let particleIndex = 0; particleIndex < this.particleSystems.length; particleIndex++) {\r\n                        const particleSystem = this.particleSystems[particleIndex];\r\n\r\n                        if (!particleSystem.isStarted() || !particleSystem.emitter) {\r\n                            continue;\r\n                        }\r\n\r\n                        const emitter = <any>particleSystem.emitter;\r\n                        if (!emitter.position || emitter.isEnabled()) {\r\n                            this._activeParticleSystems.push(particleSystem);\r\n                            particleSystem.animate();\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n                // Meshes are frozen\r\n                if (!this._skipEvaluateActiveMeshesCompletely) {\r\n                    for (let i = 0; i < len; i++) {\r\n                        const mesh = meshes.data[i];\r\n\r\n                        if (mesh._internalAbstractMeshDataInfo._wasActiveLastFrame) {\r\n                            mesh.computeWorldMatrix();\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this.particlesEnabled) {\r\n                    const psLength = this._activeParticleSystems.length;\r\n                    for (let i = 0; i < psLength; i++) {\r\n                        this._activeParticleSystems.data[i].animate();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Render the graph\r\n        this.frameGraph?.execute();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _renderRenderTarget(renderTarget: RenderTargetTexture, activeCamera: Nullable<Camera>, useCameraPostProcess = false, dumpForDebug = false) {\r\n        this._intermediateRendering = true;\r\n        if (renderTarget._shouldRender()) {\r\n            this._renderId++;\r\n\r\n            this.activeCamera = activeCamera;\r\n\r\n            if (!this.activeCamera) {\r\n                throw new Error(\"Active camera not set\");\r\n            }\r\n\r\n            // Viewport\r\n            this._engine.setViewport(this.activeCamera.viewport);\r\n\r\n            // Camera\r\n            this.updateTransformMatrix();\r\n\r\n            renderTarget.render(useCameraPostProcess, dumpForDebug);\r\n        }\r\n        this._intermediateRendering = false;\r\n    }\r\n\r\n    private _getFloatingOriginScene = (): Scene | undefined => {\r\n        return this._floatingOriginScene;\r\n    };\r\n    /**\r\n     * Render the scene\r\n     * @param updateCameras defines a boolean indicating if cameras must update according to their inputs (true by default)\r\n     * @param ignoreAnimations defines a boolean indicating if animations should not be executed (false by default)\r\n     */\r\n    public render(updateCameras = true, ignoreAnimations = false): void {\r\n        if (this.isDisposed) {\r\n            return;\r\n        }\r\n\r\n        const renderingMeshEvaluationDepth = this._renderingMeshEvaluationDepth;\r\n        try {\r\n            this._renderFrame(updateCameras, ignoreAnimations);\r\n        } finally {\r\n            this._renderingMeshEvaluationDepth = renderingMeshEvaluationDepth;\r\n        }\r\n    }\r\n\r\n    private _renderFrame(updateCameras: boolean, ignoreAnimations: boolean): void {\r\n        if (this.onReadyObservable.hasObservers() && this._executeWhenReadyTimeoutId === null) {\r\n            this._checkIsReady();\r\n        }\r\n\r\n        // Ensures that the floatingOriginOffset is grabbed from the correct scene\r\n        FloatingOriginCurrentScene.getScene = this._getFloatingOriginScene;\r\n\r\n        this._frameId++;\r\n        this._defaultFrameBufferCleared = false;\r\n        this._checkCameraRenderTarget(this.activeCamera);\r\n        if (this.activeCameras?.length) {\r\n            for (const c of this.activeCameras) {\r\n                this._checkCameraRenderTarget(c);\r\n            }\r\n        }\r\n\r\n        // Register components that have been associated lately to the scene.\r\n        this._registerTransientComponents();\r\n\r\n        this._activeParticles.fetchNewFrame();\r\n        this._totalVertices.fetchNewFrame();\r\n        this._activeIndices.fetchNewFrame();\r\n        this._activeBones.fetchNewFrame();\r\n        this._meshesForIntersections.reset();\r\n        this.resetCachedMaterial();\r\n\r\n        this.onBeforeAnimationsObservable.notifyObservers(this);\r\n\r\n        // Actions\r\n        if (this.actionManager) {\r\n            this.actionManager.processTrigger(Constants.ACTION_OnEveryFrameTrigger);\r\n        }\r\n\r\n        // Animations\r\n        if (!ignoreAnimations) {\r\n            this.animate();\r\n        }\r\n\r\n        // Before camera update steps\r\n        for (const step of this._beforeCameraUpdateStage) {\r\n            step.action();\r\n        }\r\n\r\n        // Update Cameras\r\n        if (updateCameras) {\r\n            if (this.activeCameras && this.activeCameras.length > 0) {\r\n                for (let cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {\r\n                    const camera = this.activeCameras[cameraIndex];\r\n                    camera.update();\r\n                    if (camera.cameraRigMode !== Constants.RIG_MODE_NONE) {\r\n                        // rig cameras\r\n                        for (let index = 0; index < camera._rigCameras.length; index++) {\r\n                            camera._rigCameras[index].update();\r\n                        }\r\n                    }\r\n                }\r\n            } else if (this.activeCamera) {\r\n                this.activeCamera.update();\r\n                if (this.activeCamera.cameraRigMode !== Constants.RIG_MODE_NONE) {\r\n                    // rig cameras\r\n                    for (let index = 0; index < this.activeCamera._rigCameras.length; index++) {\r\n                        this.activeCamera._rigCameras[index].update();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Custom render function?\r\n        if (this.customRenderFunction) {\r\n            this._renderId++;\r\n            this._engine.currentRenderPassId = Constants.RENDERPASS_MAIN;\r\n            this._renderingMeshEvaluationDepth++;\r\n\r\n            this.customRenderFunction(updateCameras, ignoreAnimations);\r\n        } else {\r\n            // Before render\r\n            this.onBeforeRenderObservable.notifyObservers(this);\r\n            this._renderingMeshEvaluationDepth++;\r\n\r\n            // Customs render targets\r\n            this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);\r\n\r\n            const currentActiveCamera = this.activeCameras?.length ? this.activeCameras[0] : this.activeCamera;\r\n            if (this.renderTargetsEnabled) {\r\n                Tools.StartPerformanceCounter(\"Custom render targets\", this.customRenderTargets.length > 0);\r\n                for (let customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {\r\n                    const renderTarget = this.customRenderTargets[customIndex];\r\n                    const activeCamera = renderTarget.activeCamera || this.activeCamera;\r\n\r\n                    this._renderRenderTarget(renderTarget, activeCamera, currentActiveCamera !== activeCamera, this.dumpNextRenderTargets);\r\n                }\r\n                Tools.EndPerformanceCounter(\"Custom render targets\", this.customRenderTargets.length > 0);\r\n                this._renderId++;\r\n            }\r\n\r\n            this._engine.currentRenderPassId = currentActiveCamera?.renderPassId ?? Constants.RENDERPASS_MAIN;\r\n\r\n            // Restore back buffer\r\n            this.activeCamera = currentActiveCamera;\r\n            if (this._activeCamera && this._activeCamera.cameraRigMode !== Constants.RIG_MODE_CUSTOM && !this.prePass) {\r\n                this._bindFrameBuffer(this._activeCamera, false);\r\n            }\r\n            this.onAfterRenderTargetsRenderObservable.notifyObservers(this);\r\n\r\n            for (const step of this._beforeClearStage) {\r\n                step.action();\r\n            }\r\n\r\n            // Clear\r\n            this._clearFrameBuffer(this.activeCamera);\r\n\r\n            // Collects render targets from external components.\r\n            for (const step of this._gatherRenderTargetsStage) {\r\n                step.action(this._renderTargets);\r\n            }\r\n\r\n            // Multi-cameras?\r\n            if (this.activeCameras && this.activeCameras.length > 0) {\r\n                for (let cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {\r\n                    this._processSubCameras(this.activeCameras[cameraIndex], cameraIndex > 0);\r\n                }\r\n            } else {\r\n                if (!this.activeCamera) {\r\n                    throw new Error(\"No camera defined\");\r\n                }\r\n\r\n                this._processSubCameras(this.activeCamera, !!this.activeCamera.outputRenderTarget);\r\n            }\r\n        }\r\n\r\n        this._inputManager._updateMeshUnderPointer();\r\n\r\n        // Intersection checks\r\n        this._checkIntersections();\r\n\r\n        // Executes the after render stage actions.\r\n        for (const step of this._afterRenderStage) {\r\n            step.action();\r\n        }\r\n\r\n        // After render\r\n        if (this.afterRender) {\r\n            this.afterRender();\r\n        }\r\n\r\n        this.onAfterRenderObservable.notifyObservers(this);\r\n\r\n        // Cleaning\r\n        if (this._toBeDisposed.length) {\r\n            for (let index = 0; index < this._toBeDisposed.length; index++) {\r\n                const data = this._toBeDisposed[index];\r\n                if (data) {\r\n                    data.dispose();\r\n                }\r\n            }\r\n\r\n            this._toBeDisposed.length = 0;\r\n        }\r\n\r\n        if (this.dumpNextRenderTargets) {\r\n            this.dumpNextRenderTargets = false;\r\n        }\r\n\r\n        this._activeBones.addCount(0, true);\r\n        this._activeIndices.addCount(0, true);\r\n        this._activeParticles.addCount(0, true);\r\n\r\n        this._engine.restoreDefaultFramebuffer();\r\n    }\r\n\r\n    /**\r\n     * Freeze all materials\r\n     * A frozen material will not be updatable but should be faster to render\r\n     * Note: multimaterials will not be frozen, but their submaterials will\r\n     */\r\n    public freezeMaterials(): void {\r\n        for (let i = 0; i < this.materials.length; i++) {\r\n            this.materials[i].freeze();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Unfreeze all materials\r\n     * A frozen material will not be updatable but should be faster to render\r\n     */\r\n    public unfreezeMaterials(): void {\r\n        for (let i = 0; i < this.materials.length; i++) {\r\n            this.materials[i].unfreeze();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases all held resources\r\n     */\r\n    public dispose(): void {\r\n        if (this.isDisposed) {\r\n            return;\r\n        }\r\n\r\n        this._isDisposing = true;\r\n\r\n        this.beforeRender = null;\r\n        this.afterRender = null;\r\n        this.metadata = null;\r\n\r\n        this.skeletons.length = 0;\r\n        this.morphTargetManagers.length = 0;\r\n        this._transientComponents.length = 0;\r\n        this._isReadyForMeshStage.clear();\r\n        this._beforeEvaluateActiveMeshStage.clear();\r\n        this._evaluateSubMeshStage.clear();\r\n        this._preActiveMeshStage.clear();\r\n        this._cameraDrawRenderTargetStage.clear();\r\n        this._beforeCameraDrawStage.clear();\r\n        this._beforeRenderTargetDrawStage.clear();\r\n        this._beforeRenderingGroupDrawStage.clear();\r\n        this._beforeRenderingMeshStage.clear();\r\n        this._afterRenderingMeshStage.clear();\r\n        this._afterRenderingGroupDrawStage.clear();\r\n        this._afterCameraDrawStage.clear();\r\n        this._afterRenderTargetDrawStage.clear();\r\n        this._afterRenderStage.clear();\r\n        this._beforeCameraUpdateStage.clear();\r\n        this._beforeClearStage.clear();\r\n        this._gatherRenderTargetsStage.clear();\r\n        this._gatherActiveCameraRenderTargetsStage.clear();\r\n        this._pointerMoveStage.clear();\r\n        this._pointerDownStage.clear();\r\n        this._pointerUpStage.clear();\r\n        this._isReadyChecks.length = 0;\r\n\r\n        this.importedMeshesFiles = [] as string[];\r\n\r\n        if (this._activeAnimatables && _IsSideEffectImplemented(this.stopAllAnimations)) {\r\n            // Ensures that no animatable notifies a callback that could start a new animation group, constantly adding new animatables to the active list...\r\n            for (const animatable of this._activeAnimatables) {\r\n                animatable.onAnimationEndObservable.clear();\r\n                animatable.onAnimationEnd = null;\r\n            }\r\n            this.stopAllAnimations();\r\n        }\r\n\r\n        this.resetCachedMaterial();\r\n\r\n        // Smart arrays\r\n        if (this.activeCamera) {\r\n            this.activeCamera._activeMeshes.dispose();\r\n            this.activeCamera = null;\r\n        }\r\n        this.activeCameras = null;\r\n\r\n        this._activeMeshes.dispose();\r\n        this._renderingManager.dispose();\r\n        this._processedMaterials.dispose();\r\n        this._activeParticleSystems.dispose();\r\n        this._activeSkeletons.dispose();\r\n        this._softwareSkinnedMeshes.dispose();\r\n        this._renderTargets.dispose();\r\n        this._materialsRenderTargets.dispose();\r\n        this._registeredForLateAnimationBindings.dispose();\r\n        this._animationWrites.length = 0;\r\n        this._animationWriteCount = 0;\r\n        this._animationStepWriteCount = 0;\r\n        this._meshesForIntersections.dispose();\r\n        this._toBeDisposed.length = 0;\r\n\r\n        // Abort active requests\r\n        const activeRequests = this._activeRequests.slice();\r\n        for (const request of activeRequests) {\r\n            request.abort();\r\n        }\r\n        this._activeRequests.length = 0;\r\n\r\n        // Events\r\n        try {\r\n            this.onDisposeObservable.notifyObservers(this);\r\n        } catch (e) {\r\n            Logger.Error(\"An error occurred while calling onDisposeObservable!\", e);\r\n        }\r\n\r\n        this.detachControl();\r\n\r\n        // Detach cameras\r\n        const canvas = this._engine.getInputElement?.();\r\n\r\n        if (canvas) {\r\n            for (let index = 0; index < this.cameras.length; index++) {\r\n                this.cameras[index].detachControl();\r\n            }\r\n        }\r\n\r\n        // Release animation groups\r\n        this._disposeList(this.animationGroups);\r\n\r\n        // Release lights\r\n        this._disposeList(this.lights);\r\n\r\n        // Release materials\r\n        if (this._defaultMaterial) {\r\n            this._defaultMaterial.dispose();\r\n        }\r\n        this._disposeList(this.multiMaterials);\r\n        this._disposeList(this.materials);\r\n\r\n        // Release meshes\r\n        this._disposeList(this.meshes, (item) => item.dispose(true));\r\n        this._disposeList(this.transformNodes, (item) => item.dispose(true));\r\n\r\n        // Release cameras\r\n        const cameras = this.cameras;\r\n        this._disposeList(cameras);\r\n\r\n        // Release particles\r\n        this._disposeList(this.particleSystems);\r\n\r\n        // Release postProcesses\r\n        this._disposeList(this.postProcesses);\r\n\r\n        // Release textures\r\n        this._disposeList(this.textures);\r\n\r\n        // Release morph targets\r\n        this._disposeList(this.morphTargetManagers);\r\n\r\n        // Release frame graphs\r\n        this._disposeList(this.frameGraphs);\r\n\r\n        // Release UBO\r\n        this._sceneUbo.dispose();\r\n\r\n        if (this._multiviewSceneUbo) {\r\n            this._multiviewSceneUbo.dispose();\r\n        }\r\n\r\n        // Post-processes\r\n        this.postProcessManager.dispose();\r\n\r\n        // Components\r\n        this._disposeList(this._components);\r\n\r\n        // Remove from engine\r\n        let index = this._engine.scenes.indexOf(this);\r\n\r\n        if (index > -1) {\r\n            this._engine.scenes.splice(index, 1);\r\n        }\r\n\r\n        this._floatingOriginScene = undefined;\r\n        if (this._engine.scenes.length === 0) {\r\n            // If this is the last scene to be disposed, reset matrix overrides\r\n            // Cannot reset from within engine class due floatingOriginMatrixOverrides file import side effects\r\n            ResetMatrixFunctions();\r\n        }\r\n\r\n        if (EngineStore._LastCreatedScene === this) {\r\n            EngineStore._LastCreatedScene = null;\r\n            let engineIndex = EngineStore.Instances.length - 1;\r\n            while (engineIndex >= 0) {\r\n                const engine = EngineStore.Instances[engineIndex];\r\n                if (engine.scenes.length > 0) {\r\n                    EngineStore._LastCreatedScene = engine.scenes[this._engine.scenes.length - 1];\r\n                    break;\r\n                }\r\n                engineIndex--;\r\n            }\r\n        }\r\n\r\n        index = this._engine._virtualScenes.indexOf(this);\r\n\r\n        if (index > -1) {\r\n            this._engine._virtualScenes.splice(index, 1);\r\n        }\r\n\r\n        this._engine.wipeCaches(true);\r\n        this.onDisposeObservable.clear();\r\n        this.onBeforeRenderObservable.clear();\r\n        this.onAfterRenderObservable.clear();\r\n        this.onBeforeRenderTargetsRenderObservable.clear();\r\n        this.onAfterRenderTargetsRenderObservable.clear();\r\n        this.onAfterStepObservable.clear();\r\n        this.onBeforeStepObservable.clear();\r\n        this.onBeforeActiveMeshesEvaluationObservable.clear();\r\n        this.onAfterActiveMeshesEvaluationObservable.clear();\r\n        this.onBeforeParticlesRenderingObservable.clear();\r\n        this.onAfterParticlesRenderingObservable.clear();\r\n        this.onBeforeDrawPhaseObservable.clear();\r\n        this.onAfterDrawPhaseObservable.clear();\r\n        this.onBeforeAnimationsObservable.clear();\r\n        this.onAfterAnimationsObservable.clear();\r\n        this.onDataLoadedObservable.clear();\r\n        this.onBeforeRenderingGroupObservable.clear();\r\n        this.onAfterRenderingGroupObservable.clear();\r\n        this.onMeshImportedObservable.clear();\r\n        this.onBeforeCameraRenderObservable.clear();\r\n        this.onAfterCameraRenderObservable.clear();\r\n        this.onAfterRenderCameraObservable.clear();\r\n        this.onReadyObservable.clear();\r\n        this.onNewCameraAddedObservable.clear();\r\n        this.onCameraRemovedObservable.clear();\r\n        this.onNewLightAddedObservable.clear();\r\n        this.onLightRemovedObservable.clear();\r\n        this.onNewGeometryAddedObservable.clear();\r\n        this.onGeometryRemovedObservable.clear();\r\n        this.onNewTransformNodeAddedObservable.clear();\r\n        this.onTransformNodeRemovedObservable.clear();\r\n        this.onNewMeshAddedObservable.clear();\r\n        this.onMeshRemovedObservable.clear();\r\n        this.onNewSkeletonAddedObservable.clear();\r\n        this.onSkeletonRemovedObservable.clear();\r\n        this.onNewMaterialAddedObservable.clear();\r\n        this.onNewMultiMaterialAddedObservable.clear();\r\n        this.onMaterialRemovedObservable.clear();\r\n        this.onMultiMaterialRemovedObservable.clear();\r\n        this.onNewTextureAddedObservable.clear();\r\n        this.onTextureRemovedObservable.clear();\r\n        this.onNewFrameGraphAddedObservable.clear();\r\n        this.onFrameGraphRemovedObservable.clear();\r\n        this.onNewObjectRendererAddedObservable.clear();\r\n        this.onObjectRendererRemovedObservable.clear();\r\n        this.onPrePointerObservable.clear();\r\n        this.onPointerObservable.clear();\r\n        this.onPreKeyboardObservable.clear();\r\n        this.onKeyboardObservable.clear();\r\n        this.onActiveCameraChanged.clear();\r\n        this.onScenePerformancePriorityChangedObservable.clear();\r\n        this.onClearColorChangedObservable.clear();\r\n        this.onEnvironmentTextureChangedObservable.clear();\r\n        this.onMeshUnderPointerUpdatedObservable.clear();\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    private _disposeList<T extends IDisposable>(items: T[], callback?: (item: T) => void): void {\r\n        const itemsCopy = items.slice(0);\r\n        callback = callback ?? ((item) => item.dispose());\r\n        for (const item of itemsCopy) {\r\n            callback(item);\r\n        }\r\n        items.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Gets if the scene is already disposed\r\n     */\r\n    public get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Call this function to reduce memory footprint of the scene.\r\n     * Vertex buffers will not store CPU data anymore (this will prevent picking, collisions or physics to work correctly)\r\n     */\r\n    public clearCachedVertexData(): void {\r\n        for (let meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {\r\n            const mesh = this.meshes[meshIndex];\r\n            const geometry = (<Mesh>mesh).geometry;\r\n\r\n            if (geometry) {\r\n                geometry.clearCachedData();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This function will remove the local cached buffer data from texture.\r\n     * It will save memory but will prevent the texture from being rebuilt\r\n     */\r\n    public cleanCachedTextureBuffer(): void {\r\n        for (const baseTexture of this.textures) {\r\n            const buffer = (<Texture>baseTexture)._buffer;\r\n\r\n            if (buffer) {\r\n                (<Texture>baseTexture)._buffer = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the world extend vectors with an optional filter\r\n     *\r\n     * @param filterPredicate the predicate - which meshes should be included when calculating the world size\r\n     * @returns {{ min: Vector3; max: Vector3 }} min and max vectors\r\n     */\r\n    public getWorldExtends(filterPredicate?: (mesh: AbstractMesh) => boolean): { min: Vector3; max: Vector3 } {\r\n        const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n        filterPredicate = filterPredicate || (() => true);\r\n        const meshes = this.meshes.filter(filterPredicate);\r\n        for (const mesh of meshes) {\r\n            mesh.computeWorldMatrix(true);\r\n\r\n            if (!mesh.subMeshes || mesh.subMeshes.length === 0 || mesh.infiniteDistance) {\r\n                continue;\r\n            }\r\n\r\n            const boundingInfo = mesh.getBoundingInfo();\r\n\r\n            const minBox = boundingInfo.boundingBox.minimumWorld;\r\n            const maxBox = boundingInfo.boundingBox.maximumWorld;\r\n\r\n            Vector3.CheckExtends(minBox, min, max);\r\n            Vector3.CheckExtends(maxBox, min, max);\r\n        }\r\n\r\n        return min.x === Number.MAX_VALUE\r\n            ? { min: Vector3.Zero(), max: Vector3.Zero() }\r\n            : {\r\n                  min: min,\r\n                  max: max,\r\n              };\r\n    }\r\n\r\n    // Picking\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a ray that can be used to pick in the scene\r\n     * @param x defines the x coordinate of the origin (on-screen)\r\n     * @param y defines the y coordinate of the origin (on-screen)\r\n     * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\r\n     * @param camera defines the camera to use for the picking\r\n     * @param cameraViewSpace defines if picking will be done in view space (false by default)\r\n     * @returns a Ray\r\n     */\r\n    public createPickingRay(x: number, y: number, world: Nullable<Matrix>, camera: Nullable<Camera>, cameraViewSpace = false): Ray {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a ray that can be used to pick in the scene\r\n     * @param x defines the x coordinate of the origin (on-screen)\r\n     * @param y defines the y coordinate of the origin (on-screen)\r\n     * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\r\n     * @param result defines the ray where to store the picking ray\r\n     * @param camera defines the camera to use for the picking\r\n     * @param cameraViewSpace defines if picking will be done in view space (false by default)\r\n     * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\r\n     * @returns the current scene\r\n     */\r\n    public createPickingRayToRef(\r\n        x: number,\r\n        y: number,\r\n        world: Nullable<Matrix>,\r\n        result: Ray,\r\n        camera: Nullable<Camera>,\r\n        cameraViewSpace = false,\r\n        enableDistantPicking = false\r\n    ): Scene {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a ray that can be used to pick in the scene\r\n     * @param x defines the x coordinate of the origin (on-screen)\r\n     * @param y defines the y coordinate of the origin (on-screen)\r\n     * @param camera defines the camera to use for the picking\r\n     * @returns a Ray\r\n     */\r\n    public createPickingRayInCameraSpace(x: number, y: number, camera?: Camera): Ray {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Creates a ray that can be used to pick in the scene\r\n     * @param x defines the x coordinate of the origin (on-screen)\r\n     * @param y defines the y coordinate of the origin (on-screen)\r\n     * @param result defines the ray where to store the picking ray\r\n     * @param camera defines the camera to use for the picking\r\n     * @returns the current scene\r\n     */\r\n    public createPickingRayInCameraSpaceToRef(x: number, y: number, result: Ray, camera?: Camera): Scene {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    /** @internal */\r\n    public _registeredActions: number = 0;\r\n\r\n    /** Launch a ray to try to pick a mesh in the scene\r\n     * @param x position on screen\r\n     * @param y position on screen\r\n     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @returns a PickingInfo\r\n     */\r\n    public pick(x: number, y: number, predicate?: MeshPredicate, fastCheck?: boolean, camera?: Nullable<Camera>, trianglePredicate?: TrianglePickingPredicate): PickingInfo {\r\n        const warn = _WarnImport(\"Ray\", true);\r\n        if (warn) {\r\n            Logger.Warn(warn);\r\n        }\r\n        // Dummy info if picking as not been imported\r\n        return new PickingInfo();\r\n    }\r\n\r\n    /** Launch a ray to try to pick a mesh in the scene using only bounding information of the main mesh (not using submeshes)\r\n     * @param x position on screen\r\n     * @param y position on screen\r\n     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\r\n     * @returns a PickingInfo (Please note that some info will not be set like distance, bv, bu and everything that cannot be capture by only using bounding infos)\r\n     */\r\n    public pickWithBoundingInfo(x: number, y: number, predicate?: MeshPredicate, fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {\r\n        const warn = _WarnImport(\"Ray\", true);\r\n        if (warn) {\r\n            Logger.Warn(warn);\r\n        }\r\n        // Dummy info if picking as not been imported\r\n        return new PickingInfo();\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Use the given ray to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\r\n     * irrespective of orientation.\r\n     * @param ray The ray to use to pick meshes\r\n     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must have isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @returns a PickingInfo\r\n     */\r\n    public pickWithRay(ray: Ray, predicate?: MeshPredicate, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Launch a ray to try to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\r\n     * irrespective of orientation.\r\n     * @param x X position on screen\r\n     * @param y Y position on screen\r\n     * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n     * @param camera camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @returns an array of PickingInfo\r\n     */\r\n    public multiPick(x: number, y: number, predicate?: MeshPredicate, camera?: Camera, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Launch a ray to try to pick a mesh in the scene\r\n     * @param ray Ray to use\r\n     * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @returns an array of PickingInfo\r\n     */\r\n    public multiPickWithRay(ray: Ray, predicate?: MeshPredicate, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {\r\n        throw _WarnImport(\"Ray\");\r\n    }\r\n\r\n    /**\r\n     * Force the value of meshUnderPointer\r\n     * @param mesh defines the mesh to use\r\n     * @param pointerId optional pointer id when using more than one pointer\r\n     * @param pickResult optional pickingInfo data used to find mesh\r\n     */\r\n    public setPointerOverMesh(mesh: Nullable<AbstractMesh>, pointerId?: number, pickResult?: Nullable<PickingInfo>): void {\r\n        this._inputManager.setPointerOverMesh(mesh, pointerId, pickResult);\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh under the pointer\r\n     * @returns a Mesh or null if no mesh is under the pointer\r\n     */\r\n    public getPointerOverMesh(): Nullable<AbstractMesh> {\r\n        return this._inputManager.getPointerOverMesh();\r\n    }\r\n\r\n    // Misc.\r\n    /** @internal */\r\n    public _rebuildGeometries(): void {\r\n        for (const geometry of this.geometries) {\r\n            geometry._rebuild();\r\n        }\r\n\r\n        for (const mesh of this.meshes) {\r\n            mesh._rebuild();\r\n        }\r\n\r\n        if (this.postProcessManager) {\r\n            this.postProcessManager._rebuild();\r\n        }\r\n\r\n        for (const component of this._components) {\r\n            component.rebuild();\r\n        }\r\n\r\n        for (const system of this.particleSystems) {\r\n            system.rebuild();\r\n        }\r\n\r\n        if (this.spriteManagers) {\r\n            for (const spriteMgr of this.spriteManagers) {\r\n                spriteMgr.rebuild();\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuildTextures(): void {\r\n        for (const texture of this.textures) {\r\n            texture._rebuild(true);\r\n        }\r\n\r\n        this.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Get from a list of objects by tags\r\n     * @param list the list of objects to use\r\n     * @param tagsQuery the query to use\r\n     * @param filter a predicate to filter for tags\r\n     * @returns\r\n     */\r\n    private _getByTags<T>(list: T[], tagsQuery: string, filter?: (item: T) => boolean): T[] {\r\n        if (tagsQuery === undefined) {\r\n            // returns the complete list (could be done with Tags.MatchesQuery but no need to have a for-loop here)\r\n            return list;\r\n        }\r\n\r\n        const listByTags = [];\r\n\r\n        for (const i in list) {\r\n            const item = list[i];\r\n            if (Tags && Tags.MatchesQuery(item, tagsQuery) && (!filter || filter(item))) {\r\n                listByTags.push(item);\r\n            }\r\n        }\r\n\r\n        return listByTags;\r\n    }\r\n\r\n    /**\r\n     * Get a list of meshes by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Mesh\r\n     */\r\n    public getMeshesByTags(tagsQuery: string, filter?: (mesh: AbstractMesh) => boolean): AbstractMesh[] {\r\n        return this._getByTags(this.meshes, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Get a list of cameras by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Camera\r\n     */\r\n    public getCamerasByTags(tagsQuery: string, filter?: (camera: Camera) => boolean): Camera[] {\r\n        return this._getByTags(this.cameras, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Get a list of lights by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Light\r\n     */\r\n    public getLightsByTags(tagsQuery: string, filter?: (light: Light) => boolean): Light[] {\r\n        return this._getByTags(this.lights, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Get a list of materials by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Material\r\n     */\r\n    public getMaterialByTags(tagsQuery: string, filter?: (material: Material) => boolean): Material[] {\r\n        return this._getByTags(this.materials, tagsQuery, filter).concat(this._getByTags(this.multiMaterials, tagsQuery, filter));\r\n    }\r\n\r\n    /**\r\n     * Get a list of transform nodes by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of TransformNode\r\n     */\r\n    public getTransformNodesByTags(tagsQuery: string, filter?: (transform: TransformNode) => boolean): TransformNode[] {\r\n        return this._getByTags(this.transformNodes, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n     * This allowed control for front to back rendering or reversly depending of the special needs.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n     * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n     */\r\n    public setRenderingOrder(\r\n        renderingGroupId: number,\r\n        opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n    ): void {\r\n        this._renderingManager.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n     * @param depth Automatically clears depth between groups if true and autoClear is true.\r\n     * @param stencil Automatically clears stencil between groups if true and autoClear is true.\r\n     */\r\n    public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean, depth = true, stencil = true): void {\r\n        this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil, depth, stencil);\r\n    }\r\n\r\n    /**\r\n     * Gets the current auto clear configuration for one rendering group of the rendering\r\n     * manager.\r\n     * @param index the rendering group index to get the information for\r\n     * @returns The auto clear setup for the requested rendering group\r\n     */\r\n    public getAutoClearDepthStencilSetup(index: number): IRenderingManagerAutoClearSetup {\r\n        return this._renderingManager.getAutoClearDepthStencilSetup(index);\r\n    }\r\n\r\n    private _blockMaterialDirtyMechanism = false;\r\n\r\n    /** @internal */\r\n    public _forceBlockMaterialDirtyMechanism(value: boolean) {\r\n        this._blockMaterialDirtyMechanism = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean blocking all the calls to markAllMaterialsAsDirty (ie. the materials won't be updated if they are out of sync) */\r\n    public get blockMaterialDirtyMechanism(): boolean {\r\n        return this._blockMaterialDirtyMechanism;\r\n    }\r\n\r\n    public set blockMaterialDirtyMechanism(value: boolean) {\r\n        if (this._blockMaterialDirtyMechanism === value) {\r\n            return;\r\n        }\r\n\r\n        this._blockMaterialDirtyMechanism = value;\r\n\r\n        if (!value) {\r\n            // Do a complete update\r\n            this.markAllMaterialsAsDirty(Constants.MATERIAL_AllDirtyFlag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Will flag all materials as dirty to trigger new shader compilation\r\n     * @param flag defines the flag used to specify which material part must be marked as dirty\r\n     * @param predicate If not null, it will be used to specify if a material has to be marked as dirty\r\n     */\r\n    public markAllMaterialsAsDirty(flag: number, predicate?: (mat: Material) => boolean): void {\r\n        if (this._blockMaterialDirtyMechanism) {\r\n            return;\r\n        }\r\n\r\n        for (const material of this.materials) {\r\n            if (predicate && !predicate(material)) {\r\n                continue;\r\n            }\r\n            material.markAsDirty(flag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _loadFile(\r\n        fileOrUrl: File | string,\r\n        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,\r\n        onProgress?: (ev: ProgressEvent) => void,\r\n        useOfflineSupport?: boolean,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void,\r\n        onOpened?: (request: WebRequest) => void\r\n    ): IFileRequest {\r\n        const request = LoadFile(fileOrUrl, onSuccess, onProgress, useOfflineSupport ? this.offlineProvider : undefined, useArrayBuffer, onError, onOpened);\r\n        this._activeRequests.push(request);\r\n        request.onCompleteObservable.add((request) => {\r\n            this._activeRequests.splice(this._activeRequests.indexOf(request), 1);\r\n        });\r\n        return request;\r\n    }\r\n\r\n    public async _loadFileAsync(\r\n        fileOrUrl: File | string,\r\n        onProgress?: (data: any) => void,\r\n        useOfflineSupport?: boolean,\r\n        useArrayBuffer?: false,\r\n        onOpened?: (request: WebRequest) => void\r\n    ): Promise<string>;\r\n\r\n    public async _loadFileAsync(\r\n        fileOrUrl: File | string,\r\n        onProgress?: (data: any) => void,\r\n        useOfflineSupport?: boolean,\r\n        useArrayBuffer?: true,\r\n        onOpened?: (request: WebRequest) => void\r\n    ): Promise<ArrayBuffer>;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public async _loadFileAsync(\r\n        fileOrUrl: File | string,\r\n        onProgress?: (data: any) => void,\r\n        useOfflineSupport?: boolean,\r\n        useArrayBuffer?: boolean,\r\n        onOpened?: (request: WebRequest) => void\r\n    ): Promise<string | ArrayBuffer> {\r\n        return await new Promise((resolve, reject) => {\r\n            this._loadFile(\r\n                fileOrUrl,\r\n                (data) => {\r\n                    resolve(data);\r\n                },\r\n                onProgress,\r\n                useOfflineSupport,\r\n                useArrayBuffer,\r\n                (request, exception) => {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(exception);\r\n                },\r\n                onOpened\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Loads a delay-loading file (e.g. a `.babylonbinarymeshdata` geometry file), coalescing concurrent\r\n     * requests for the same url so the file is only fetched once even when many meshes or geometries share it.\r\n     * The same loaded data is resolved to every caller that requested it while the request was in flight.\r\n     * @param url defines the url of the file to load\r\n     * @param useArrayBuffer defines whether the file must be loaded as an ArrayBuffer (binary) or a string\r\n     * @param useOfflineSupport defines whether the offline provider should be used when available\r\n     * @returns a promise that resolves with the loaded data (shared across coalesced callers)\r\n     * @internal\r\n     */\r\n    public async _loadDelayedFileAsync(url: string, useArrayBuffer: boolean, useOfflineSupport: boolean): Promise<string | ArrayBuffer> {\r\n        if (!this._delayedFileRequests) {\r\n            this._delayedFileRequests = new Map<string, Promise<string | ArrayBuffer>>();\r\n        }\r\n\r\n        // The same url can be requested both as binary and as string, so the cache key must include the data type.\r\n        const key = `${url}|${useArrayBuffer ? \"binary\" : \"string\"}`;\r\n\r\n        let request = this._delayedFileRequests.get(key);\r\n        if (!request) {\r\n            // Branch on the literal type so the correct _loadFileAsync overload is selected without an unsafe cast.\r\n            request = useArrayBuffer ? this._loadFileAsync(url, undefined, useOfflineSupport, true) : this._loadFileAsync(url, undefined, useOfflineSupport, false);\r\n\r\n            // Only coalesce while the request is in flight: remove it once settled so later loads can re-fetch.\r\n            const requestToClear = request;\r\n            void (async () => {\r\n                try {\r\n                    await requestToClear;\r\n                } catch {\r\n                    // The failure is surfaced to the awaiting callers; here we only need to clear the in-flight entry.\r\n                }\r\n                this._delayedFileRequests?.delete(key);\r\n            })();\r\n\r\n            this._delayedFileRequests.set(key, request);\r\n        }\r\n\r\n        return await request;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _requestFile(\r\n        url: string,\r\n        onSuccess: (data: string | ArrayBuffer, request?: WebRequest) => void,\r\n        onProgress?: (ev: ProgressEvent) => void,\r\n        useOfflineSupport?: boolean,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: RequestFileError) => void,\r\n        onOpened?: (request: WebRequest) => void\r\n    ): IFileRequest {\r\n        const request = RequestFile(url, onSuccess, onProgress, useOfflineSupport ? this.offlineProvider : undefined, useArrayBuffer, onError, onOpened);\r\n        this._activeRequests.push(request);\r\n        request.onCompleteObservable.add((request) => {\r\n            this._activeRequests.splice(this._activeRequests.indexOf(request), 1);\r\n        });\r\n        return request;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public async _requestFileAsync(\r\n        url: string,\r\n        onProgress?: (ev: ProgressEvent) => void,\r\n        useOfflineSupport?: boolean,\r\n        useArrayBuffer?: boolean,\r\n        onOpened?: (request: WebRequest) => void\r\n    ): Promise<string | ArrayBuffer> {\r\n        return await new Promise((resolve, reject) => {\r\n            this._requestFile(\r\n                url,\r\n                (data) => {\r\n                    resolve(data);\r\n                },\r\n                onProgress,\r\n                useOfflineSupport,\r\n                useArrayBuffer,\r\n                (error) => {\r\n                    reject(error);\r\n                },\r\n                onOpened\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _readFile(\r\n        file: File,\r\n        onSuccess: (data: string | ArrayBuffer) => void,\r\n        onProgress?: (ev: ProgressEvent) => any,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (error: ReadFileError) => void\r\n    ): IFileRequest {\r\n        const request = ReadFile(file, onSuccess, onProgress, useArrayBuffer, onError);\r\n        this._activeRequests.push(request);\r\n        request.onCompleteObservable.add((request) => {\r\n            this._activeRequests.splice(this._activeRequests.indexOf(request), 1);\r\n        });\r\n        return request;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public async _readFileAsync(file: File, onProgress?: (ev: ProgressEvent) => any, useArrayBuffer?: boolean): Promise<string | ArrayBuffer> {\r\n        return await new Promise((resolve, reject) => {\r\n            this._readFile(\r\n                file,\r\n                (data) => {\r\n                    resolve(data);\r\n                },\r\n                onProgress,\r\n                useArrayBuffer,\r\n                (error) => {\r\n                    reject(error);\r\n                }\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Internal perfCollector instance used for sharing between inspector and playground.\r\n     * Marked as protected to allow sharing between prototype extensions, but disallow access at toplevel.\r\n     */\r\n    protected _perfCollector: Nullable<PerformanceViewerCollector> = null;\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * This method gets the performance collector belonging to the scene, which is generally shared with the inspector.\r\n     * @returns the perf collector belonging to the scene.\r\n     */\r\n    public getPerfCollector(): PerformanceViewerCollector {\r\n        throw _WarnImport(\"performanceViewerSceneExtension\");\r\n    }\r\n\r\n    // deprecated\r\n\r\n    /**\r\n     * Sets the active camera of the scene using its Id\r\n     * @param id defines the camera's Id\r\n     * @returns the new active camera or null if none found.\r\n     * @deprecated Please use setActiveCameraById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    setActiveCameraByID(id: string): Nullable<Camera> {\r\n        return this.setActiveCameraById(id);\r\n    }\r\n    /**\r\n     * Get a material using its id\r\n     * @param id defines the material's Id\r\n     * @returns the material or null if none found.\r\n     * @deprecated Please use getMaterialById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getMaterialByID(id: string): Nullable<Material> {\r\n        return this.getMaterialById(id);\r\n    }\r\n    /**\r\n     * Gets a the last added material using a given id\r\n     * @param id defines the material's Id\r\n     * @returns the last material with the given id or null if none found.\r\n     * @deprecated Please use getLastMaterialById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getLastMaterialByID(id: string): Nullable<Material> {\r\n        return this.getLastMaterialById(id);\r\n    }\r\n\r\n    /**\r\n     * Get a texture using its unique id\r\n     * @param uniqueId defines the texture's unique id\r\n     * @returns the texture or null if none found.\r\n     * @deprecated Please use getTextureByUniqueId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getTextureByUniqueID(uniqueId: number): Nullable<BaseTexture> {\r\n        return this.getTextureByUniqueId(uniqueId);\r\n    }\r\n    /**\r\n     * Gets a camera using its Id\r\n     * @param id defines the Id to look for\r\n     * @returns the camera or null if not found\r\n     * @deprecated Please use getCameraById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getCameraByID(id: string): Nullable<Camera> {\r\n        return this.getCameraById(id);\r\n    }\r\n    /**\r\n     * Gets a camera using its unique Id\r\n     * @param uniqueId defines the unique Id to look for\r\n     * @returns the camera or null if not found\r\n     * @deprecated Please use getCameraByUniqueId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getCameraByUniqueID(uniqueId: number): Nullable<Camera> {\r\n        return this.getCameraByUniqueId(uniqueId);\r\n    }\r\n    /**\r\n     * Gets a bone using its Id\r\n     * @param id defines the bone's Id\r\n     * @returns the bone or null if not found\r\n     * @deprecated Please use getBoneById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getBoneByID(id: string): Nullable<Bone> {\r\n        return this.getBoneById(id);\r\n    }\r\n    /**\r\n     * Gets a light node using its Id\r\n     * @param id defines the light's Id\r\n     * @returns the light or null if none found.\r\n     * @deprecated Please use getLightById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getLightByID(id: string): Nullable<Light> {\r\n        return this.getLightById(id);\r\n    }\r\n    /**\r\n     * Gets a light node using its scene-generated unique Id\r\n     * @param uniqueId defines the light's unique Id\r\n     * @returns the light or null if none found.\r\n     * @deprecated Please use getLightByUniqueId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getLightByUniqueID(uniqueId: number): Nullable<Light> {\r\n        return this.getLightByUniqueId(uniqueId);\r\n    }\r\n    /**\r\n     * Gets a particle system by Id\r\n     * @param id defines the particle system Id\r\n     * @returns the corresponding system or null if none found\r\n     * @deprecated Please use getParticleSystemById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getParticleSystemByID(id: string): Nullable<IParticleSystem> {\r\n        return this.getParticleSystemById(id);\r\n    }\r\n    /**\r\n     * Gets a geometry using its Id\r\n     * @param id defines the geometry's Id\r\n     * @returns the geometry or null if none found.\r\n     * @deprecated Please use getGeometryById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getGeometryByID(id: string): Nullable<Geometry> {\r\n        return this.getGeometryById(id);\r\n    }\r\n    /**\r\n     * Gets the first added mesh found of a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the mesh found or null if not found at all\r\n     * @deprecated Please use getMeshById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getMeshByID(id: string): Nullable<AbstractMesh> {\r\n        return this.getMeshById(id);\r\n    }\r\n    /**\r\n     * Gets a mesh with its auto-generated unique Id\r\n     * @param uniqueId defines the unique Id to search for\r\n     * @returns the found mesh or null if not found at all.\r\n     * @deprecated Please use getMeshByUniqueId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getMeshByUniqueID(uniqueId: number): Nullable<AbstractMesh> {\r\n        return this.getMeshByUniqueId(uniqueId);\r\n    }\r\n    /**\r\n     * Gets a the last added mesh using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found mesh or null if not found at all.\r\n     * @deprecated Please use getLastMeshById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getLastMeshByID(id: string): Nullable<AbstractMesh> {\r\n        return this.getLastMeshById(id);\r\n    }\r\n    /**\r\n     * Gets a list of meshes using their Id\r\n     * @param id defines the Id to search for\r\n     * @returns a list of meshes\r\n     * @deprecated Please use getMeshesById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getMeshesByID(id: string): Array<AbstractMesh> {\r\n        return this.getMeshesById(id);\r\n    }\r\n    /**\r\n     * Gets the first added transform node found of a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found transform node or null if not found at all.\r\n     * @deprecated Please use getTransformNodeById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getTransformNodeByID(id: string): Nullable<TransformNode> {\r\n        return this.getTransformNodeById(id);\r\n    }\r\n    /**\r\n     * Gets a transform node with its auto-generated unique Id\r\n     * @param uniqueId defines the unique Id to search for\r\n     * @returns the found transform node or null if not found at all.\r\n     * @deprecated Please use getTransformNodeByUniqueId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getTransformNodeByUniqueID(uniqueId: number): Nullable<TransformNode> {\r\n        return this.getTransformNodeByUniqueId(uniqueId);\r\n    }\r\n    /**\r\n     * Gets a list of transform nodes using their Id\r\n     * @param id defines the Id to search for\r\n     * @returns a list of transform nodes\r\n     * @deprecated Please use getTransformNodesById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getTransformNodesByID(id: string): Array<TransformNode> {\r\n        return this.getTransformNodesById(id);\r\n    }\r\n    /**\r\n     * Gets a node (Mesh, Camera, Light) using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found node or null if not found at all\r\n     * @deprecated Please use getNodeById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getNodeByID(id: string): Nullable<Node> {\r\n        return this.getNodeById(id);\r\n    }\r\n    /**\r\n     * Gets a the last added node (Mesh, Camera, Light) using a given Id\r\n     * @param id defines the Id to search for\r\n     * @returns the found node or null if not found at all\r\n     * @deprecated Please use getLastEntryById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getLastEntryByID(id: string): Nullable<Node> {\r\n        return this.getLastEntryById(id);\r\n    }\r\n    /**\r\n     * Gets a skeleton using a given Id (if many are found, this function will pick the last one)\r\n     * @param id defines the Id to search for\r\n     * @returns the found skeleton or null if not found at all.\r\n     * @deprecated Please use getLastSkeletonById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    getLastSkeletonByID(id: string): Nullable<Skeleton> {\r\n        return this.getLastSkeletonById(id);\r\n    }\r\n}\r\n\r\n// Register Class Name\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for scene.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScene(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.Scene\", Scene);\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\n\r\nScene.prototype.sortActiveAnimatables ??= _MissingSideEffect(\"Scene\", \"sortActiveAnimatables\") as any;\r\nScene.prototype.beginWeightedAnimation ??= _MissingSideEffect(\"Scene\", \"beginWeightedAnimation\") as any;\r\nScene.prototype.beginAnimation ??= _MissingSideEffect(\"Scene\", \"beginAnimation\") as any;\r\nScene.prototype.beginHierarchyAnimation ??= _MissingSideEffect(\"Scene\", \"beginHierarchyAnimation\") as any;\r\nScene.prototype.beginDirectAnimation ??= _MissingSideEffect(\"Scene\", \"beginDirectAnimation\") as any;\r\nScene.prototype.beginDirectHierarchyAnimation ??= _MissingSideEffect(\"Scene\", \"beginDirectHierarchyAnimation\") as any;\r\nScene.prototype.getAnimatableByTarget ??= _MissingSideEffect(\"Scene\", \"getAnimatableByTarget\") as any;\r\nScene.prototype.getAllAnimatablesByTarget ??= _MissingSideEffect(\"Scene\", \"getAllAnimatablesByTarget\") as any;\r\nScene.prototype.stopAllAnimations ??= _MissingSideEffect(\"Scene\", \"stopAllAnimations\") as any;\r\nScene.prototype.getSoundByName ??= _MissingSideEffect(\"Scene\", \"getSoundByName\") as any;\r\nScene.prototype.createOrUpdateSelectionOctree ??= _MissingSideEffect(\"Scene\", \"createOrUpdateSelectionOctree\") as any;\r\nScene.prototype.createDefaultLight ??= _MissingSideEffect(\"Scene\", \"createDefaultLight\") as any;\r\nScene.prototype.createDefaultCamera ??= _MissingSideEffect(\"Scene\", \"createDefaultCamera\") as any;\r\nScene.prototype.createDefaultCameraOrLight ??= _MissingSideEffect(\"Scene\", \"createDefaultCameraOrLight\") as any;\r\nScene.prototype.createDefaultSkybox ??= _MissingSideEffect(\"Scene\", \"createDefaultSkybox\") as any;\r\nScene.prototype.createDefaultEnvironment ??= _MissingSideEffect(\"Scene\", \"createDefaultEnvironment\") as any;\r\nScene.prototype.createDefaultVRExperience ??= _MissingSideEffect(\"Scene\", \"createDefaultVRExperience\") as any;\r\nScene.prototype.createDefaultXRExperienceAsync ??= _MissingSideEffect(\"Scene\", \"createDefaultXRExperienceAsync\") as any;\r\nScene.prototype.getGlowLayerByName ??= _MissingSideEffect(\"Scene\", \"getGlowLayerByName\") as any;\r\nScene.prototype.getHighlightLayerByName ??= _MissingSideEffect(\"Scene\", \"getHighlightLayerByName\") as any;\r\nScene.prototype.getSelectionOutlineLayerByName ??= _MissingSideEffect(\"Scene\", \"getSelectionOutlineLayerByName\") as any;\r\nScene.prototype.removeLensFlareSystem ??= _MissingSideEffect(\"Scene\", \"removeLensFlareSystem\") as any;\r\nScene.prototype.addLensFlareSystem ??= _MissingSideEffect(\"Scene\", \"addLensFlareSystem\") as any;\r\nScene.prototype.getLensFlareSystemByName ??= _MissingSideEffect(\"Scene\", \"getLensFlareSystemByName\") as any;\r\nScene.prototype.getLensFlareSystemByID ??= _MissingSideEffect(\"Scene\", \"getLensFlareSystemByID\") as any;\r\nScene.prototype.getLensFlareSystemById ??= _MissingSideEffect(\"Scene\", \"getLensFlareSystemById\") as any;\r\nScene.prototype.getPhysicsEngine ??= _MissingSideEffect(\"Scene\", \"getPhysicsEngine\") as any;\r\nScene.prototype.enablePhysics ??= _MissingSideEffect(\"Scene\", \"enablePhysics\") as any;\r\nScene.prototype.disablePhysicsEngine ??= _MissingSideEffect(\"Scene\", \"disablePhysicsEngine\") as any;\r\nScene.prototype.isPhysicsEnabled ??= _MissingSideEffect(\"Scene\", \"isPhysicsEnabled\") as any;\r\nScene.prototype.deleteCompoundImpostor ??= _MissingSideEffect(\"Scene\", \"deleteCompoundImpostor\") as any;\r\nScene.prototype.removeReflectionProbe ??= _MissingSideEffect(\"Scene\", \"removeReflectionProbe\") as any;\r\nScene.prototype.addReflectionProbe ??= _MissingSideEffect(\"Scene\", \"addReflectionProbe\") as any;\r\nScene.prototype.getBoundingBoxRenderer ??= _MissingSideEffect(\"Scene\", \"getBoundingBoxRenderer\") as any;\r\nScene.prototype.enableDepthRenderer ??= _MissingSideEffect(\"Scene\", \"enableDepthRenderer\") as any;\r\nScene.prototype.disableDepthRenderer ??= _MissingSideEffect(\"Scene\", \"disableDepthRenderer\") as any;\r\nScene.prototype.enableFluidRenderer ??= _MissingSideEffect(\"Scene\", \"enableFluidRenderer\") as any;\r\nScene.prototype.disableFluidRenderer ??= _MissingSideEffect(\"Scene\", \"disableFluidRenderer\") as any;\r\nScene.prototype.enableGeometryBufferRenderer ??= _MissingSideEffect(\"Scene\", \"enableGeometryBufferRenderer\") as any;\r\nScene.prototype.disableGeometryBufferRenderer ??= _MissingSideEffect(\"Scene\", \"disableGeometryBufferRenderer\") as any;\r\nScene.prototype.enableIblCdfGenerator ??= _MissingSideEffect(\"Scene\", \"enableIblCdfGenerator\") as any;\r\nScene.prototype.disableIblCdfGenerator ??= _MissingSideEffect(\"Scene\", \"disableIblCdfGenerator\") as any;\r\nScene.prototype.getOutlineRenderer ??= _MissingSideEffect(\"Scene\", \"getOutlineRenderer\") as any;\r\nScene.prototype.enablePrePassRenderer ??= _MissingSideEffect(\"Scene\", \"enablePrePassRenderer\") as any;\r\nScene.prototype.disablePrePassRenderer ??= _MissingSideEffect(\"Scene\", \"disablePrePassRenderer\") as any;\r\nScene.prototype.enableSubSurfaceForPrePass ??= _MissingSideEffect(\"Scene\", \"enableSubSurfaceForPrePass\") as any;\r\nScene.prototype.disableSubSurfaceForPrePass ??= _MissingSideEffect(\"Scene\", \"disableSubSurfaceForPrePass\") as any;\r\nScene.prototype.pickSprite ??= _MissingSideEffect(\"Scene\", \"pickSprite\") as any;\r\nScene.prototype.pickSpriteWithRay ??= _MissingSideEffect(\"Scene\", \"pickSpriteWithRay\") as any;\r\nScene.prototype.multiPickSprite ??= _MissingSideEffect(\"Scene\", \"multiPickSprite\") as any;\r\nScene.prototype.multiPickSpriteWithRay ??= _MissingSideEffect(\"Scene\", \"multiPickSpriteWithRay\") as any;\r\nScene.prototype.setPointerOverSprite ??= _MissingSideEffect(\"Scene\", \"setPointerOverSprite\") as any;\r\nScene.prototype.getPointerOverSprite ??= _MissingSideEffect(\"Scene\", \"getPointerOverSprite\") as any;\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"mainSoundTrack\")) {\r\n    Object.defineProperty(Scene.prototype, \"mainSoundTrack\", _MissingSideEffectProperty(\"Scene\", \"mainSoundTrack\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"soundTracks\")) {\r\n    Object.defineProperty(Scene.prototype, \"soundTracks\", _MissingSideEffectProperty(\"Scene\", \"soundTracks\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"audioEnabled\")) {\r\n    Object.defineProperty(Scene.prototype, \"audioEnabled\", _MissingSideEffectProperty(\"Scene\", \"audioEnabled\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"headphone\")) {\r\n    Object.defineProperty(Scene.prototype, \"headphone\", _MissingSideEffectProperty(\"Scene\", \"headphone\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"audioListenerPositionProvider\")) {\r\n    Object.defineProperty(Scene.prototype, \"audioListenerPositionProvider\", _MissingSideEffectProperty(\"Scene\", \"audioListenerPositionProvider\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"audioListenerRotationProvider\")) {\r\n    Object.defineProperty(Scene.prototype, \"audioListenerRotationProvider\", _MissingSideEffectProperty(\"Scene\", \"audioListenerRotationProvider\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"audioPositioningRefreshRate\")) {\r\n    Object.defineProperty(Scene.prototype, \"audioPositioningRefreshRate\", _MissingSideEffectProperty(\"Scene\", \"audioPositioningRefreshRate\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"selectionOctree\")) {\r\n    Object.defineProperty(Scene.prototype, \"selectionOctree\", _MissingSideEffectProperty(\"Scene\", \"selectionOctree\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"debugLayer\")) {\r\n    Object.defineProperty(Scene.prototype, \"debugLayer\", _MissingSideEffectProperty(\"Scene\", \"debugLayer\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"gamepadManager\")) {\r\n    Object.defineProperty(Scene.prototype, \"gamepadManager\", _MissingSideEffectProperty(\"Scene\", \"gamepadManager\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"simplificationQueue\")) {\r\n    Object.defineProperty(Scene.prototype, \"simplificationQueue\", _MissingSideEffectProperty(\"Scene\", \"simplificationQueue\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"onBeforePhysicsObservable\")) {\r\n    Object.defineProperty(Scene.prototype, \"onBeforePhysicsObservable\", _MissingSideEffectProperty(\"Scene\", \"onBeforePhysicsObservable\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"onAfterPhysicsObservable\")) {\r\n    Object.defineProperty(Scene.prototype, \"onAfterPhysicsObservable\", _MissingSideEffectProperty(\"Scene\", \"onAfterPhysicsObservable\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"reflectionProbes\")) {\r\n    Object.defineProperty(Scene.prototype, \"reflectionProbes\", _MissingSideEffectProperty(\"Scene\", \"reflectionProbes\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"forceShowBoundingBoxes\")) {\r\n    Object.defineProperty(Scene.prototype, \"forceShowBoundingBoxes\", _MissingSideEffectProperty(\"Scene\", \"forceShowBoundingBoxes\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"depthPeelingRenderer\")) {\r\n    Object.defineProperty(Scene.prototype, \"depthPeelingRenderer\", _MissingSideEffectProperty(\"Scene\", \"depthPeelingRenderer\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"useOrderIndependentTransparency\")) {\r\n    Object.defineProperty(Scene.prototype, \"useOrderIndependentTransparency\", _MissingSideEffectProperty(\"Scene\", \"useOrderIndependentTransparency\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"fluidRenderer\")) {\r\n    Object.defineProperty(Scene.prototype, \"fluidRenderer\", _MissingSideEffectProperty(\"Scene\", \"fluidRenderer\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"geometryBufferRenderer\")) {\r\n    Object.defineProperty(Scene.prototype, \"geometryBufferRenderer\", _MissingSideEffectProperty(\"Scene\", \"geometryBufferRenderer\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"iblCdfGenerator\")) {\r\n    Object.defineProperty(Scene.prototype, \"iblCdfGenerator\", _MissingSideEffectProperty(\"Scene\", \"iblCdfGenerator\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"prePassRenderer\")) {\r\n    Object.defineProperty(Scene.prototype, \"prePassRenderer\", _MissingSideEffectProperty(\"Scene\", \"prePassRenderer\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"subSurfaceConfiguration\")) {\r\n    Object.defineProperty(Scene.prototype, \"subSurfaceConfiguration\", _MissingSideEffectProperty(\"Scene\", \"subSurfaceConfiguration\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"spriteManagers\")) {\r\n    Object.defineProperty(Scene.prototype, \"spriteManagers\", _MissingSideEffectProperty(\"Scene\", \"spriteManagers\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"onBeforeSpritesRenderingObservable\")) {\r\n    Object.defineProperty(Scene.prototype, \"onBeforeSpritesRenderingObservable\", _MissingSideEffectProperty(\"Scene\", \"onBeforeSpritesRenderingObservable\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Scene.prototype, \"onAfterSpritesRenderingObservable\")) {\r\n    Object.defineProperty(Scene.prototype, \"onAfterSpritesRenderingObservable\", _MissingSideEffectProperty(\"Scene\", \"onAfterSpritesRenderingObservable\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { AddAnimationExtensions } from \"./animatable.core\";\r\nimport { Bone } from \"../Bones/bone.pure\";\r\nimport { Scene } from \"../scene.pure\";\r\n\r\nexport * from \"./animatable.core\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for animatable.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnimatable(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Connect everything!\r\n    AddAnimationExtensions(Scene, Bone);\r\n}\r\n","import { Animation } from \"../Animations/animation.pure\";\r\n\r\n/**\r\n * Class used to override all child animations of a given target\r\n */\r\nexport class AnimationPropertiesOverride {\r\n    /**\r\n     * Gets or sets a value indicating if animation blending must be used\r\n     */\r\n    public enableBlending = false;\r\n\r\n    /**\r\n     * Gets or sets the blending speed to use when enableBlending is true\r\n     */\r\n    public blendingSpeed = 0.01;\r\n\r\n    /**\r\n     * Gets or sets the default loop mode to use\r\n     */\r\n    public loopMode = Animation.ANIMATIONLOOPMODE_CYCLE;\r\n}\r\n","import { type DeepImmutable, type Nullable } from \"../types\";\r\nimport { Clamp, WithinEpsilon } from \"./math.scalar.functions\";\r\nimport { Vector2, Vector3, Quaternion, Matrix, type Vector4 } from \"./math.vector.pure\";\r\nimport { Epsilon } from \"./math.constants\";\r\n\r\n/**\r\n * Defines potential orientation for back face culling\r\n */\r\nexport const enum Orientation {\r\n    /**\r\n     * Clockwise\r\n     */\r\n    CW = 0,\r\n    /** Counter clockwise */\r\n    CCW = 1,\r\n}\r\n\r\n/** Class used to represent a Bezier curve */\r\nexport class BezierCurve {\r\n    /**\r\n     * Returns the cubic Bezier interpolated value (float) at \"t\" (float) from the given x1, y1, x2, y2 floats\r\n     * @param t defines the time\r\n     * @param x1 defines the left coordinate on X axis\r\n     * @param y1 defines the left coordinate on Y axis\r\n     * @param x2 defines the right coordinate on X axis\r\n     * @param y2 defines the right coordinate on Y axis\r\n     * @returns the interpolated value\r\n     */\r\n    public static Interpolate(t: number, x1: number, y1: number, x2: number, y2: number): number {\r\n        if (t === 0) {\r\n            return 0;\r\n        }\r\n        // Extract X (which is equal to time here)\r\n        const f0 = 1 - 3 * x2 + 3 * x1;\r\n        const f1 = 3 * x2 - 6 * x1;\r\n        const f2 = 3 * x1;\r\n\r\n        let refinedT = t;\r\n        for (let i = 0; i < 5; i++) {\r\n            const refinedT2 = refinedT * refinedT;\r\n            const refinedT3 = refinedT2 * refinedT;\r\n\r\n            const x = f0 * refinedT3 + f1 * refinedT2 + f2 * refinedT;\r\n            const slope = 1.0 / (3.0 * f0 * refinedT2 + 2.0 * f1 * refinedT + f2);\r\n            refinedT -= (x - t) * slope;\r\n            refinedT = Math.min(1, Math.max(0, refinedT));\r\n        }\r\n\r\n        // Resolve cubic bezier for the given x\r\n        return 3 * Math.pow(1 - refinedT, 2) * refinedT * y1 + 3 * (1 - refinedT) * Math.pow(refinedT, 2) * y2 + Math.pow(refinedT, 3);\r\n    }\r\n}\r\n\r\n/**\r\n * Defines angle representation\r\n */\r\nexport class Angle {\r\n    private _radians: number;\r\n\r\n    /**\r\n     * Creates an Angle object of \"radians\" radians (float).\r\n     * @param radians the angle in radians\r\n     */\r\n    constructor(radians: number) {\r\n        this._radians = radians;\r\n        if (this._radians < 0.0) {\r\n            this._radians += 2.0 * Math.PI;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get value in degrees\r\n     * @returns the Angle value in degrees (float)\r\n     */\r\n    public degrees() {\r\n        return (this._radians * 180.0) / Math.PI;\r\n    }\r\n\r\n    /**\r\n     * Get value in radians\r\n     * @returns the Angle value in radians (float)\r\n     */\r\n    public radians() {\r\n        return this._radians;\r\n    }\r\n\r\n    /**\r\n     * Gets a new Angle object with a value of the angle (in radians) between the line connecting the two points and the x-axis\r\n     * @param a defines first point as the origin\r\n     * @param b defines point\r\n     * @returns a new Angle\r\n     */\r\n    public static BetweenTwoPoints(a: DeepImmutable<Vector2>, b: DeepImmutable<Vector2>): Angle {\r\n        const delta = b.subtract(a);\r\n        const theta = Math.atan2(delta.y, delta.x);\r\n        return new Angle(theta);\r\n    }\r\n\r\n    /**\r\n     * Gets the angle between the two vectors\r\n     * @param a defines first vector\r\n     * @param b defines vector\r\n     * @returns Returns an new Angle between 0 and PI\r\n     */\r\n    public static BetweenTwoVectors<Vec extends Vector2 | Vector3 | Vector4>(a: DeepImmutable<Vec>, b: DeepImmutable<Vec>): Angle {\r\n        let product = a.lengthSquared() * b.lengthSquared();\r\n        if (product === 0) {\r\n            return new Angle(Math.PI / 2);\r\n        }\r\n        product = Math.sqrt(product);\r\n        let cosVal = a.dot(b as any) / product;\r\n        cosVal = Clamp(cosVal, -1, 1);\r\n        const angle = Math.acos(cosVal);\r\n        return new Angle(angle);\r\n    }\r\n\r\n    /**\r\n     * Gets a new Angle object from the given float in radians\r\n     * @param radians defines the angle value in radians\r\n     * @returns a new Angle\r\n     */\r\n    public static FromRadians(radians: number): Angle {\r\n        return new Angle(radians);\r\n    }\r\n    /**\r\n     * Gets a new Angle object from the given float in degrees\r\n     * @param degrees defines the angle value in degrees\r\n     * @returns a new Angle\r\n     */\r\n    public static FromDegrees(degrees: number): Angle {\r\n        return new Angle((degrees * Math.PI) / 180.0);\r\n    }\r\n}\r\n\r\n/**\r\n * This represents an arc in a 2d space.\r\n */\r\nexport class Arc2 {\r\n    /**\r\n     * Defines the center point of the arc.\r\n     */\r\n    public centerPoint: Vector2;\r\n    /**\r\n     * Defines the radius of the arc.\r\n     */\r\n    public radius: number;\r\n    /**\r\n     * Defines the angle of the arc (from mid point to end point).\r\n     */\r\n    public angle: Angle;\r\n    /**\r\n     * Defines the start angle of the arc (from start point to middle point).\r\n     */\r\n    public startAngle: Angle;\r\n    /**\r\n     * Defines the orientation of the arc (clock wise/counter clock wise).\r\n     */\r\n    public orientation: Orientation;\r\n\r\n    /**\r\n     * Creates an Arc object from the three given points : start, middle and end.\r\n     * @param startPoint Defines the start point of the arc\r\n     * @param midPoint Defines the middle point of the arc\r\n     * @param endPoint Defines the end point of the arc\r\n     */\r\n    constructor(\r\n        /** Defines the start point of the arc */\r\n        public startPoint: Vector2,\r\n        /** Defines the mid point of the arc */\r\n        public midPoint: Vector2,\r\n        /** Defines the end point of the arc */\r\n        public endPoint: Vector2\r\n    ) {\r\n        const temp = Math.pow(midPoint.x, 2) + Math.pow(midPoint.y, 2);\r\n        const startToMid = (Math.pow(startPoint.x, 2) + Math.pow(startPoint.y, 2) - temp) / 2;\r\n        const midToEnd = (temp - Math.pow(endPoint.x, 2) - Math.pow(endPoint.y, 2)) / 2;\r\n        const det = (startPoint.x - midPoint.x) * (midPoint.y - endPoint.y) - (midPoint.x - endPoint.x) * (startPoint.y - midPoint.y);\r\n\r\n        this.centerPoint = new Vector2(\r\n            (startToMid * (midPoint.y - endPoint.y) - midToEnd * (startPoint.y - midPoint.y)) / det,\r\n            ((startPoint.x - midPoint.x) * midToEnd - (midPoint.x - endPoint.x) * startToMid) / det\r\n        );\r\n\r\n        this.radius = this.centerPoint.subtract(this.startPoint).length();\r\n\r\n        this.startAngle = Angle.BetweenTwoPoints(this.centerPoint, this.startPoint);\r\n\r\n        const a1 = this.startAngle.degrees();\r\n        let a2 = Angle.BetweenTwoPoints(this.centerPoint, this.midPoint).degrees();\r\n        let a3 = Angle.BetweenTwoPoints(this.centerPoint, this.endPoint).degrees();\r\n\r\n        // angles correction\r\n        if (a2 - a1 > +180.0) {\r\n            a2 -= 360.0;\r\n        }\r\n        if (a2 - a1 < -180.0) {\r\n            a2 += 360.0;\r\n        }\r\n        if (a3 - a2 > +180.0) {\r\n            a3 -= 360.0;\r\n        }\r\n        if (a3 - a2 < -180.0) {\r\n            a3 += 360.0;\r\n        }\r\n\r\n        this.orientation = a2 - a1 < 0 ? Orientation.CW : Orientation.CCW;\r\n        this.angle = Angle.FromDegrees(this.orientation === Orientation.CW ? a1 - a3 : a3 - a1);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a 2D path made up of multiple 2D points\r\n */\r\nexport class Path2 {\r\n    private _points = new Array<Vector2>();\r\n    private _length = 0.0;\r\n\r\n    /**\r\n     * If the path start and end point are the same\r\n     */\r\n    public closed = false;\r\n\r\n    /**\r\n     * Creates a Path2 object from the starting 2D coordinates x and y.\r\n     * @param x the starting points x value\r\n     * @param y the starting points y value\r\n     */\r\n    constructor(x: number, y: number) {\r\n        this._points.push(new Vector2(x, y));\r\n    }\r\n\r\n    /**\r\n     * Adds a new segment until the given coordinates (x, y) to the current Path2.\r\n     * @param x the added points x value\r\n     * @param y the added points y value\r\n     * @returns the updated Path2.\r\n     */\r\n    public addLineTo(x: number, y: number): Path2 {\r\n        if (this.closed) {\r\n            return this;\r\n        }\r\n        const newPoint = new Vector2(x, y);\r\n        const previousPoint = this._points[this._points.length - 1];\r\n        this._points.push(newPoint);\r\n        this._length += newPoint.subtract(previousPoint).length();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds _numberOfSegments_ segments according to the arc definition (middle point coordinates, end point coordinates, the arc start point being the current Path2 last point) to the current Path2.\r\n     * @param midX middle point x value\r\n     * @param midY middle point y value\r\n     * @param endX end point x value\r\n     * @param endY end point y value\r\n     * @param numberOfSegments (default: 36)\r\n     * @returns the updated Path2.\r\n     */\r\n    public addArcTo(midX: number, midY: number, endX: number, endY: number, numberOfSegments = 36): Path2 {\r\n        if (this.closed) {\r\n            return this;\r\n        }\r\n        const startPoint = this._points[this._points.length - 1];\r\n        const midPoint = new Vector2(midX, midY);\r\n        const endPoint = new Vector2(endX, endY);\r\n\r\n        const arc = new Arc2(startPoint, midPoint, endPoint);\r\n\r\n        let increment = arc.angle.radians() / numberOfSegments;\r\n        if (arc.orientation === Orientation.CW) {\r\n            increment *= -1;\r\n        }\r\n        let currentAngle = arc.startAngle.radians() + increment;\r\n\r\n        for (let i = 0; i < numberOfSegments; i++) {\r\n            const x = Math.cos(currentAngle) * arc.radius + arc.centerPoint.x;\r\n            const y = Math.sin(currentAngle) * arc.radius + arc.centerPoint.y;\r\n            this.addLineTo(x, y);\r\n            currentAngle += increment;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds _numberOfSegments_ segments according to the quadratic curve definition to the current Path2.\r\n     * @param controlX control point x value\r\n     * @param controlY control point y value\r\n     * @param endX end point x value\r\n     * @param endY end point y value\r\n     * @param numberOfSegments (default: 36)\r\n     * @returns the updated Path2.\r\n     */\r\n    public addQuadraticCurveTo(controlX: number, controlY: number, endX: number, endY: number, numberOfSegments = 36): Path2 {\r\n        if (this.closed) {\r\n            return this;\r\n        }\r\n\r\n        const equation = (t: number, val0: number, val1: number, val2: number) => {\r\n            const res = (1.0 - t) * (1.0 - t) * val0 + 2.0 * t * (1.0 - t) * val1 + t * t * val2;\r\n            return res;\r\n        };\r\n        const startPoint = this._points[this._points.length - 1];\r\n        for (let i = 0; i <= numberOfSegments; i++) {\r\n            const step = i / numberOfSegments;\r\n            const x = equation(step, startPoint.x, controlX, endX);\r\n            const y = equation(step, startPoint.y, controlY, endY);\r\n            this.addLineTo(x, y);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds _numberOfSegments_ segments according to the bezier curve definition to the current Path2.\r\n     * @param originTangentX tangent vector at the origin point x value\r\n     * @param originTangentY tangent vector at the origin point y value\r\n     * @param destinationTangentX tangent vector at the destination point x value\r\n     * @param destinationTangentY tangent vector at the destination point y value\r\n     * @param endX end point x value\r\n     * @param endY end point y value\r\n     * @param numberOfSegments (default: 36)\r\n     * @returns the updated Path2.\r\n     */\r\n    public addBezierCurveTo(\r\n        originTangentX: number,\r\n        originTangentY: number,\r\n        destinationTangentX: number,\r\n        destinationTangentY: number,\r\n        endX: number,\r\n        endY: number,\r\n        numberOfSegments = 36\r\n    ): Path2 {\r\n        if (this.closed) {\r\n            return this;\r\n        }\r\n\r\n        const equation = (t: number, val0: number, val1: number, val2: number, val3: number) => {\r\n            const res = (1.0 - t) * (1.0 - t) * (1.0 - t) * val0 + 3.0 * t * (1.0 - t) * (1.0 - t) * val1 + 3.0 * t * t * (1.0 - t) * val2 + t * t * t * val3;\r\n            return res;\r\n        };\r\n        const startPoint = this._points[this._points.length - 1];\r\n        for (let i = 0; i <= numberOfSegments; i++) {\r\n            const step = i / numberOfSegments;\r\n            const x = equation(step, startPoint.x, originTangentX, destinationTangentX, endX);\r\n            const y = equation(step, startPoint.y, originTangentY, destinationTangentY, endY);\r\n            this.addLineTo(x, y);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Defines if a given point is inside the polygon defines by the path\r\n     * @param point defines the point to test\r\n     * @returns true if the point is inside\r\n     */\r\n    public isPointInside(point: Vector2) {\r\n        let isInside = false;\r\n        const count = this._points.length;\r\n        for (let p = count - 1, q = 0; q < count; p = q++) {\r\n            let edgeLow = this._points[p];\r\n            let edgeHigh = this._points[q];\r\n\r\n            let edgeDx = edgeHigh.x - edgeLow.x;\r\n            let edgeDy = edgeHigh.y - edgeLow.y;\r\n\r\n            if (Math.abs(edgeDy) > Number.EPSILON) {\r\n                // Not parallel\r\n                if (edgeDy < 0) {\r\n                    edgeLow = this._points[q];\r\n                    edgeDx = -edgeDx;\r\n                    edgeHigh = this._points[p];\r\n                    edgeDy = -edgeDy;\r\n                }\r\n\r\n                if (point.y < edgeLow.y || point.y > edgeHigh.y) {\r\n                    continue;\r\n                }\r\n\r\n                if (point.y === edgeLow.y && point.x === edgeLow.x) {\r\n                    return true;\r\n                } else {\r\n                    const perpEdge = edgeDy * (point.x - edgeLow.x) - edgeDx * (point.y - edgeLow.y);\r\n                    if (perpEdge === 0) {\r\n                        return true;\r\n                    }\r\n                    if (perpEdge < 0) {\r\n                        continue;\r\n                    }\r\n                    isInside = !isInside;\r\n                }\r\n            } else {\r\n                // parallel or collinear\r\n                if (point.y !== edgeLow.y) {\r\n                    continue;\r\n                }\r\n\r\n                if ((edgeHigh.x <= point.x && point.x <= edgeLow.x) || (edgeLow.x <= point.x && point.x <= edgeHigh.x)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return isInside;\r\n    }\r\n\r\n    /**\r\n     * Closes the Path2.\r\n     * @returns the Path2.\r\n     */\r\n    public close(): Path2 {\r\n        this.closed = true;\r\n        return this;\r\n    }\r\n    /**\r\n     * Gets the sum of the distance between each sequential point in the path\r\n     * @returns the Path2 total length (float).\r\n     */\r\n    public length(): number {\r\n        let result = this._length;\r\n\r\n        if (this.closed) {\r\n            const lastPoint = this._points[this._points.length - 1];\r\n            const firstPoint = this._points[0];\r\n            result += firstPoint.subtract(lastPoint).length();\r\n        }\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Gets the area of the polygon defined by the path\r\n     * @returns area value\r\n     */\r\n    public area(): number {\r\n        const n = this._points.length;\r\n        let value = 0.0;\r\n\r\n        for (let p = n - 1, q = 0; q < n; p = q++) {\r\n            value += this._points[p].x * this._points[q].y - this._points[q].x * this._points[p].y;\r\n        }\r\n\r\n        return value * 0.5;\r\n    }\r\n\r\n    /**\r\n     * Gets the points which construct the path\r\n     * @returns the Path2 internal array of points.\r\n     */\r\n    public getPoints(): Vector2[] {\r\n        return this._points;\r\n    }\r\n\r\n    /**\r\n     * Retrieves the point at the distance aways from the starting point\r\n     * @param normalizedLengthPosition the length along the path to retrieve the point from\r\n     * @returns a new Vector2 located at a percentage of the Path2 total length on this path.\r\n     */\r\n    public getPointAtLengthPosition(normalizedLengthPosition: number): Vector2 {\r\n        if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {\r\n            return Vector2.Zero();\r\n        }\r\n\r\n        const lengthPosition = normalizedLengthPosition * this.length();\r\n\r\n        let previousOffset = 0;\r\n        for (let i = 0; i < this._points.length; i++) {\r\n            const j = (i + 1) % this._points.length;\r\n\r\n            const a = this._points[i];\r\n            const b = this._points[j];\r\n            const bToA = b.subtract(a);\r\n\r\n            const nextOffset = bToA.length() + previousOffset;\r\n            if (lengthPosition >= previousOffset && lengthPosition <= nextOffset) {\r\n                const dir = bToA.normalize();\r\n                const localOffset = lengthPosition - previousOffset;\r\n\r\n                return new Vector2(a.x + dir.x * localOffset, a.y + dir.y * localOffset);\r\n            }\r\n            previousOffset = nextOffset;\r\n        }\r\n\r\n        return Vector2.Zero();\r\n    }\r\n\r\n    /**\r\n     * Creates a new path starting from an x and y position\r\n     * @param x starting x value\r\n     * @param y starting y value\r\n     * @returns a new Path2 starting at the coordinates (x, y).\r\n     */\r\n    public static StartingAt(x: number, y: number): Path2 {\r\n        return new Path2(x, y);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a 3D path made up of multiple 3D points\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/path3D\r\n */\r\nexport class Path3D {\r\n    private _curve = new Array<Vector3>();\r\n    private _distances = new Array<number>();\r\n    private _tangents = new Array<Vector3>();\r\n    private _normals = new Array<Vector3>();\r\n    private _binormals = new Array<Vector3>();\r\n    private _raw: boolean;\r\n    private _alignTangentsWithPath: boolean;\r\n\r\n    // holds interpolated point data\r\n    private readonly _pointAtData = {\r\n        id: 0,\r\n        point: Vector3.Zero(),\r\n        previousPointArrayIndex: 0,\r\n\r\n        position: 0,\r\n        subPosition: 0,\r\n\r\n        interpolateReady: false,\r\n        interpolationMatrix: Matrix.Identity(),\r\n    };\r\n\r\n    /**\r\n     * new Path3D(path, normal, raw)\r\n     * Creates a Path3D. A Path3D is a logical math object, so not a mesh.\r\n     * please read the description in the tutorial : https://doc.babylonjs.com/features/featuresDeepDive/mesh/path3D\r\n     * @param path an array of Vector3, the curve axis of the Path3D\r\n     * @param firstNormal (options) Vector3, the first wanted normal to the curve. Ex (0, 1, 0) for a vertical normal.\r\n     * @param raw (optional, default false) : boolean, if true the returned Path3D isn't normalized. Useful to depict path acceleration or speed.\r\n     * @param alignTangentsWithPath (optional, default false) : boolean, if true the tangents will be aligned with the path.\r\n     */\r\n    constructor(\r\n        /**\r\n         * an array of Vector3, the curve axis of the Path3D\r\n         */\r\n        public path: Vector3[],\r\n        firstNormal: Nullable<Vector3> = null,\r\n        raw?: boolean,\r\n        alignTangentsWithPath = false\r\n    ) {\r\n        for (let p = 0; p < path.length; p++) {\r\n            this._curve[p] = path[p].clone(); // hard copy\r\n        }\r\n        this._raw = raw || false;\r\n        this._alignTangentsWithPath = alignTangentsWithPath;\r\n        this._compute(firstNormal, alignTangentsWithPath);\r\n    }\r\n\r\n    /**\r\n     * Returns the Path3D array of successive Vector3 designing its curve.\r\n     * @returns the Path3D array of successive Vector3 designing its curve.\r\n     */\r\n    public getCurve(): Vector3[] {\r\n        return this._curve;\r\n    }\r\n\r\n    /**\r\n     * Returns the Path3D array of successive Vector3 designing its curve.\r\n     * @returns the Path3D array of successive Vector3 designing its curve.\r\n     */\r\n    public getPoints(): Vector3[] {\r\n        return this._curve;\r\n    }\r\n\r\n    /**\r\n     * @returns the computed length (float) of the path.\r\n     */\r\n    public length() {\r\n        return this._distances[this._distances.length - 1];\r\n    }\r\n\r\n    /**\r\n     * Returns an array populated with tangent vectors on each Path3D curve point.\r\n     * @returns an array populated with tangent vectors on each Path3D curve point.\r\n     */\r\n    public getTangents(): Vector3[] {\r\n        return this._tangents;\r\n    }\r\n\r\n    /**\r\n     * Returns an array populated with normal vectors on each Path3D curve point.\r\n     * @returns an array populated with normal vectors on each Path3D curve point.\r\n     */\r\n    public getNormals(): Vector3[] {\r\n        return this._normals;\r\n    }\r\n\r\n    /**\r\n     * Returns an array populated with binormal vectors on each Path3D curve point.\r\n     * @returns an array populated with binormal vectors on each Path3D curve point.\r\n     */\r\n    public getBinormals(): Vector3[] {\r\n        return this._binormals;\r\n    }\r\n\r\n    /**\r\n     * Returns an array populated with distances (float) of the i-th point from the first curve point.\r\n     * @returns an array populated with distances (float) of the i-th point from the first curve point.\r\n     */\r\n    public getDistances(): number[] {\r\n        return this._distances;\r\n    }\r\n\r\n    /**\r\n     * Returns an interpolated point along this path\r\n     * @param position the position of the point along this path, from 0.0 to 1.0\r\n     * @returns a new Vector3 as the point\r\n     */\r\n    public getPointAt(position: number): Vector3 {\r\n        return this._updatePointAtData(position).point;\r\n    }\r\n\r\n    /**\r\n     * Returns the tangent vector of an interpolated Path3D curve point at the specified position along this path.\r\n     * @param position the position of the point along this path, from 0.0 to 1.0\r\n     * @param interpolated (optional, default false) : boolean, if true returns an interpolated tangent instead of the tangent of the previous path point.\r\n     * @returns a tangent vector corresponding to the interpolated Path3D curve point, if not interpolated, the tangent is taken from the precomputed tangents array.\r\n     */\r\n    public getTangentAt(position: number, interpolated = false): Vector3 {\r\n        this._updatePointAtData(position, interpolated);\r\n        return interpolated ? Vector3.TransformCoordinates(Vector3.Forward(), this._pointAtData.interpolationMatrix) : this._tangents[this._pointAtData.previousPointArrayIndex];\r\n    }\r\n\r\n    /**\r\n     * Returns the tangent vector of an interpolated Path3D curve point at the specified position along this path.\r\n     * @param position the position of the point along this path, from 0.0 to 1.0\r\n     * @param interpolated (optional, default false) : boolean, if true returns an interpolated normal instead of the normal of the previous path point.\r\n     * @returns a normal vector corresponding to the interpolated Path3D curve point, if not interpolated, the normal is taken from the precomputed normals array.\r\n     */\r\n    public getNormalAt(position: number, interpolated = false): Vector3 {\r\n        this._updatePointAtData(position, interpolated);\r\n        return interpolated ? Vector3.TransformCoordinates(Vector3.Right(), this._pointAtData.interpolationMatrix) : this._normals[this._pointAtData.previousPointArrayIndex];\r\n    }\r\n\r\n    /**\r\n     * Returns the binormal vector of an interpolated Path3D curve point at the specified position along this path.\r\n     * @param position the position of the point along this path, from 0.0 to 1.0\r\n     * @param interpolated (optional, default false) : boolean, if true returns an interpolated binormal instead of the binormal of the previous path point.\r\n     * @returns a binormal vector corresponding to the interpolated Path3D curve point, if not interpolated, the binormal is taken from the precomputed binormals array.\r\n     */\r\n    public getBinormalAt(position: number, interpolated = false): Vector3 {\r\n        this._updatePointAtData(position, interpolated);\r\n        return interpolated ? Vector3.TransformCoordinates(Vector3.UpReadOnly, this._pointAtData.interpolationMatrix) : this._binormals[this._pointAtData.previousPointArrayIndex];\r\n    }\r\n\r\n    /**\r\n     * Returns the distance (float) of an interpolated Path3D curve point at the specified position along this path.\r\n     * @param position the position of the point along this path, from 0.0 to 1.0\r\n     * @returns the distance of the interpolated Path3D curve point at the specified position along this path.\r\n     */\r\n    public getDistanceAt(position: number): number {\r\n        return this.length() * position;\r\n    }\r\n\r\n    /**\r\n     * Returns the array index of the previous point of an interpolated point along this path\r\n     * @param position the position of the point to interpolate along this path, from 0.0 to 1.0\r\n     * @returns the array index\r\n     */\r\n    public getPreviousPointIndexAt(position: number) {\r\n        this._updatePointAtData(position);\r\n        return this._pointAtData.previousPointArrayIndex;\r\n    }\r\n\r\n    /**\r\n     * Returns the position of an interpolated point relative to the two path points it lies between, from 0.0 (point A) to 1.0 (point B)\r\n     * @param position the position of the point to interpolate along this path, from 0.0 to 1.0\r\n     * @returns the sub position\r\n     */\r\n    public getSubPositionAt(position: number) {\r\n        this._updatePointAtData(position);\r\n        return this._pointAtData.subPosition;\r\n    }\r\n\r\n    /**\r\n     * Returns the position of the closest virtual point on this path to an arbitrary Vector3, from 0.0 to 1.0\r\n     * @param target the vector of which to get the closest position to\r\n     * @returns the position of the closest virtual point on this path to the target vector\r\n     */\r\n    public getClosestPositionTo(target: Vector3) {\r\n        let smallestDistance = Number.MAX_VALUE;\r\n        let closestPosition = 0.0;\r\n        for (let i = 0; i < this._curve.length - 1; i++) {\r\n            const point = this._curve[i + 0];\r\n            const tangent = this._curve[i + 1].subtract(point).normalize();\r\n            const subLength = this._distances[i + 1] - this._distances[i + 0];\r\n            const subPosition = Math.min((Math.max(Vector3.Dot(tangent, target.subtract(point).normalize()), 0.0) * Vector3.Distance(point, target)) / subLength, 1.0);\r\n            const distance = Vector3.Distance(point.add(tangent.scale(subPosition * subLength)), target);\r\n\r\n            if (distance < smallestDistance) {\r\n                smallestDistance = distance;\r\n                closestPosition = (this._distances[i + 0] + subLength * subPosition) / this.length();\r\n            }\r\n        }\r\n        return closestPosition;\r\n    }\r\n\r\n    /**\r\n     * Returns a sub path (slice) of this path\r\n     * @param start the position of the fist path point, from 0.0 to 1.0, or a negative value, which will get wrapped around from the end of the path to 0.0 to 1.0 values\r\n     * @param end the position of the last path point, from 0.0 to 1.0, or a negative value, which will get wrapped around from the end of the path to 0.0 to 1.0 values\r\n     * @returns a sub path (slice) of this path\r\n     */\r\n    public slice(start: number = 0.0, end: number = 1.0) {\r\n        if (start < 0.0) {\r\n            start = 1 - ((start * -1.0) % 1.0);\r\n        }\r\n        if (end < 0.0) {\r\n            end = 1 - ((end * -1.0) % 1.0);\r\n        }\r\n        if (start > end) {\r\n            const _start = start;\r\n            start = end;\r\n            end = _start;\r\n        }\r\n        const curvePoints = this.getCurve();\r\n\r\n        const startPoint = this.getPointAt(start);\r\n        let startIndex = this.getPreviousPointIndexAt(start);\r\n\r\n        const endPoint = this.getPointAt(end);\r\n        const endIndex = this.getPreviousPointIndexAt(end) + 1;\r\n\r\n        const slicePoints: Vector3[] = [];\r\n        if (start !== 0.0) {\r\n            startIndex++;\r\n            slicePoints.push(startPoint);\r\n        }\r\n\r\n        slicePoints.push(...curvePoints.slice(startIndex, endIndex));\r\n        if (end !== 1.0 || start === 1.0) {\r\n            slicePoints.push(endPoint);\r\n        }\r\n        return new Path3D(slicePoints, this.getNormalAt(start), this._raw, this._alignTangentsWithPath);\r\n    }\r\n\r\n    /**\r\n     * Forces the Path3D tangent, normal, binormal and distance recomputation.\r\n     * @param path path which all values are copied into the curves points\r\n     * @param firstNormal which should be projected onto the curve\r\n     * @param alignTangentsWithPath (optional, default false) : boolean, if true the tangents will be aligned with the path\r\n     * @returns the same object updated.\r\n     */\r\n    public update(path: Vector3[], firstNormal: Nullable<Vector3> = null, alignTangentsWithPath = false): Path3D {\r\n        for (let p = 0; p < path.length; p++) {\r\n            this._curve[p].x = path[p].x;\r\n            this._curve[p].y = path[p].y;\r\n            this._curve[p].z = path[p].z;\r\n        }\r\n        this._compute(firstNormal, alignTangentsWithPath);\r\n        return this;\r\n    }\r\n\r\n    // private function compute() : computes tangents, normals and binormals\r\n    private _compute(firstNormal: Nullable<Vector3>, alignTangentsWithPath = false): void {\r\n        const l = this._curve.length;\r\n\r\n        if (l < 2) {\r\n            return;\r\n        }\r\n\r\n        // first and last tangents\r\n        this._tangents[0] = this._getFirstNonNullVector(0);\r\n        if (!this._raw) {\r\n            this._tangents[0].normalize();\r\n        }\r\n        this._tangents[l - 1] = this._curve[l - 1].subtract(this._curve[l - 2]);\r\n        if (!this._raw) {\r\n            this._tangents[l - 1].normalize();\r\n        }\r\n\r\n        // normals and binormals at first point : arbitrary vector with _normalVector()\r\n        const tg0 = this._tangents[0];\r\n        const pp0 = this._normalVector(tg0, firstNormal);\r\n        this._normals[0] = pp0;\r\n        if (!this._raw) {\r\n            this._normals[0].normalize();\r\n        }\r\n        this._binormals[0] = Vector3.Cross(tg0, this._normals[0]);\r\n        if (!this._raw) {\r\n            this._binormals[0].normalize();\r\n        }\r\n        this._distances[0] = 0.0;\r\n\r\n        // normals and binormals : next points\r\n        let prev: Vector3; // previous vector (segment)\r\n        let cur: Vector3; // current vector (segment)\r\n        let curTang: Vector3; // current tangent\r\n        // previous normal\r\n        let prevNor: Vector3; // previous normal\r\n        let prevBinor: Vector3; // previous binormal\r\n\r\n        for (let i = 1; i < l; i++) {\r\n            // tangents\r\n            prev = this._getLastNonNullVector(i);\r\n            if (i < l - 1) {\r\n                cur = this._getFirstNonNullVector(i);\r\n                this._tangents[i] = alignTangentsWithPath ? cur : prev.add(cur);\r\n                this._tangents[i].normalize();\r\n            }\r\n            this._distances[i] = this._distances[i - 1] + this._curve[i].subtract(this._curve[i - 1]).length();\r\n\r\n            // normals and binormals\r\n            // http://www.cs.cmu.edu/afs/andrew/scs/cs/15-462/web/old/asst2camera.html\r\n            curTang = this._tangents[i];\r\n            prevBinor = this._binormals[i - 1];\r\n            this._normals[i] = Vector3.Cross(prevBinor, curTang);\r\n            if (!this._raw) {\r\n                if (this._normals[i].length() === 0) {\r\n                    prevNor = this._normals[i - 1];\r\n                    this._normals[i] = prevNor.clone();\r\n                } else {\r\n                    this._normals[i].normalize();\r\n                }\r\n            }\r\n            this._binormals[i] = Vector3.Cross(curTang, this._normals[i]);\r\n            if (!this._raw) {\r\n                this._binormals[i].normalize();\r\n            }\r\n        }\r\n        this._pointAtData.id = NaN;\r\n    }\r\n\r\n    // private function getFirstNonNullVector(index)\r\n    // returns the first non null vector from index : curve[index + N].subtract(curve[index])\r\n    private _getFirstNonNullVector(index: number): Vector3 {\r\n        let i = 1;\r\n        let nNVector: Vector3 = this._curve[index + i].subtract(this._curve[index]);\r\n        while (nNVector.length() === 0 && index + i + 1 < this._curve.length) {\r\n            i++;\r\n            nNVector = this._curve[index + i].subtract(this._curve[index]);\r\n        }\r\n        return nNVector;\r\n    }\r\n\r\n    // private function getLastNonNullVector(index)\r\n    // returns the last non null vector from index : curve[index].subtract(curve[index - N])\r\n    private _getLastNonNullVector(index: number): Vector3 {\r\n        let i = 1;\r\n        let nLVector: Vector3 = this._curve[index].subtract(this._curve[index - i]);\r\n        while (nLVector.length() === 0 && index > i) {\r\n            i++;\r\n            nLVector = this._curve[index].subtract(this._curve[index - i]);\r\n        }\r\n        return nLVector;\r\n    }\r\n\r\n    // private function normalVector(v0, vt, va) :\r\n    // returns an arbitrary point in the plane defined by the point v0 and the vector vt orthogonal to this plane\r\n    // if va is passed, it returns the va projection on the plane orthogonal to vt at the point v0\r\n    private _normalVector(vt: Vector3, va: Nullable<Vector3>): Vector3 {\r\n        let normal0: Vector3;\r\n        let tgl = vt.length();\r\n        if (tgl === 0.0) {\r\n            tgl = 1.0;\r\n        }\r\n\r\n        if (va === undefined || va === null) {\r\n            let point: Vector3;\r\n            if (!WithinEpsilon(Math.abs(vt.y) / tgl, 1.0, Epsilon)) {\r\n                // search for a point in the plane\r\n                point = new Vector3(0.0, -1.0, 0.0);\r\n            } else if (!WithinEpsilon(Math.abs(vt.x) / tgl, 1.0, Epsilon)) {\r\n                point = new Vector3(1.0, 0.0, 0.0);\r\n            } else if (!WithinEpsilon(Math.abs(vt.z) / tgl, 1.0, Epsilon)) {\r\n                point = new Vector3(0.0, 0.0, 1.0);\r\n            } else {\r\n                point = Vector3.Zero();\r\n            }\r\n            normal0 = Vector3.Cross(vt, point);\r\n        } else {\r\n            normal0 = Vector3.Cross(vt, va);\r\n            Vector3.CrossToRef(normal0, vt, normal0);\r\n        }\r\n        normal0.normalize();\r\n        return normal0;\r\n    }\r\n\r\n    /**\r\n     * Updates the point at data for an interpolated point along this curve\r\n     * @param position the position of the point along this curve, from 0.0 to 1.0\r\n     * @param interpolateTNB\r\n     * @interpolateTNB whether to compute the interpolated tangent, normal and binormal\r\n     * @returns the (updated) point at data\r\n     */\r\n    private _updatePointAtData(position: number, interpolateTNB: boolean = false) {\r\n        // set an id for caching the result\r\n        if (this._pointAtData.id === position) {\r\n            if (!this._pointAtData.interpolateReady) {\r\n                this._updateInterpolationMatrix();\r\n            }\r\n            return this._pointAtData;\r\n        } else {\r\n            this._pointAtData.id = position;\r\n        }\r\n        const curvePoints = this.getPoints();\r\n\r\n        // clamp position between 0.0 and 1.0\r\n        if (position <= 0.0) {\r\n            return this._setPointAtData(0.0, 0.0, curvePoints[0], 0, interpolateTNB);\r\n        } else if (position >= 1.0) {\r\n            return this._setPointAtData(1.0, 1.0, curvePoints[curvePoints.length - 1], curvePoints.length - 1, interpolateTNB);\r\n        }\r\n\r\n        let previousPoint: Vector3 = curvePoints[0];\r\n        let currentPoint: Vector3;\r\n        let currentLength = 0.0;\r\n        const targetLength = position * this.length();\r\n\r\n        for (let i = 1; i < curvePoints.length; i++) {\r\n            currentPoint = curvePoints[i];\r\n            const distance = Vector3.Distance(previousPoint, currentPoint);\r\n            currentLength += distance;\r\n            if (currentLength === targetLength) {\r\n                return this._setPointAtData(position, 1.0, currentPoint, i, interpolateTNB);\r\n            } else if (currentLength > targetLength) {\r\n                const toLength = currentLength - targetLength;\r\n                const diff = toLength / distance;\r\n                const dir = previousPoint.subtract(currentPoint);\r\n                const point = currentPoint.add(dir.scaleInPlace(diff));\r\n                return this._setPointAtData(position, 1 - diff, point, i - 1, interpolateTNB);\r\n            }\r\n            previousPoint = currentPoint;\r\n        }\r\n        return this._pointAtData;\r\n    }\r\n\r\n    /**\r\n     * Updates the point at data from the specified parameters\r\n     * @param position where along the path the interpolated point is, from 0.0 to 1.0\r\n     * @param subPosition\r\n     * @param point the interpolated point\r\n     * @param parentIndex the index of an existing curve point that is on, or else positionally the first behind, the interpolated point\r\n     * @param interpolateTNB whether to compute the interpolated tangent, normal and binormal\r\n     * @returns the (updated) point at data\r\n     */\r\n    private _setPointAtData(position: number, subPosition: number, point: Vector3, parentIndex: number, interpolateTNB: boolean) {\r\n        this._pointAtData.point = point;\r\n        this._pointAtData.position = position;\r\n        this._pointAtData.subPosition = subPosition;\r\n        this._pointAtData.previousPointArrayIndex = parentIndex;\r\n        this._pointAtData.interpolateReady = interpolateTNB;\r\n\r\n        if (interpolateTNB) {\r\n            this._updateInterpolationMatrix();\r\n        }\r\n        return this._pointAtData;\r\n    }\r\n\r\n    /**\r\n     * Updates the point at interpolation matrix for the tangents, normals and binormals\r\n     */\r\n    private _updateInterpolationMatrix() {\r\n        this._pointAtData.interpolationMatrix = Matrix.Identity();\r\n        const parentIndex = this._pointAtData.previousPointArrayIndex;\r\n\r\n        if (parentIndex !== this._tangents.length - 1) {\r\n            const index = parentIndex + 1;\r\n\r\n            const tangentFrom = this._tangents[parentIndex].clone();\r\n            const normalFrom = this._normals[parentIndex].clone();\r\n            const binormalFrom = this._binormals[parentIndex].clone();\r\n\r\n            const tangentTo = this._tangents[index].clone();\r\n            const normalTo = this._normals[index].clone();\r\n            const binormalTo = this._binormals[index].clone();\r\n\r\n            const quatFrom = Quaternion.RotationQuaternionFromAxis(normalFrom, binormalFrom, tangentFrom);\r\n            const quatTo = Quaternion.RotationQuaternionFromAxis(normalTo, binormalTo, tangentTo);\r\n            const quatAt = Quaternion.Slerp(quatFrom, quatTo, this._pointAtData.subPosition);\r\n\r\n            quatAt.toRotationMatrix(this._pointAtData.interpolationMatrix);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * A Curve3 object is a logical object, so not a mesh, to handle curves in the 3D geometric space.\r\n * A Curve3 is designed from a series of successive Vector3.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves\r\n */\r\nexport class Curve3 {\r\n    private _points: Vector3[];\r\n    private _length: number = 0.0;\r\n\r\n    /**\r\n     * Returns a Curve3 object along a Quadratic Bezier curve : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#quadratic-bezier-curve\r\n     * @param v0 (Vector3) the origin point of the Quadratic Bezier\r\n     * @param v1 (Vector3) the control point\r\n     * @param v2 (Vector3) the end point of the Quadratic Bezier\r\n     * @param nbPoints (integer) the wanted number of points in the curve\r\n     * @returns the created Curve3\r\n     */\r\n    public static CreateQuadraticBezier(v0: DeepImmutable<Vector3>, v1: DeepImmutable<Vector3>, v2: DeepImmutable<Vector3>, nbPoints: number): Curve3 {\r\n        nbPoints = nbPoints > 2 ? nbPoints : 3;\r\n        const bez: Vector3[] = [];\r\n        const equation = (t: number, val0: number, val1: number, val2: number) => {\r\n            const res = (1.0 - t) * (1.0 - t) * val0 + 2.0 * t * (1.0 - t) * val1 + t * t * val2;\r\n            return res;\r\n        };\r\n        for (let i = 0; i <= nbPoints; i++) {\r\n            bez.push(new Vector3(equation(i / nbPoints, v0.x, v1.x, v2.x), equation(i / nbPoints, v0.y, v1.y, v2.y), equation(i / nbPoints, v0.z, v1.z, v2.z)));\r\n        }\r\n        return new Curve3(bez);\r\n    }\r\n\r\n    /**\r\n     * Returns a Curve3 object along a Cubic Bezier curve : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#cubic-bezier-curve\r\n     * @param v0 (Vector3) the origin point of the Cubic Bezier\r\n     * @param v1 (Vector3) the first control point\r\n     * @param v2 (Vector3) the second control point\r\n     * @param v3 (Vector3) the end point of the Cubic Bezier\r\n     * @param nbPoints (integer) the wanted number of points in the curve\r\n     * @returns the created Curve3\r\n     */\r\n    public static CreateCubicBezier(v0: DeepImmutable<Vector3>, v1: DeepImmutable<Vector3>, v2: DeepImmutable<Vector3>, v3: DeepImmutable<Vector3>, nbPoints: number): Curve3 {\r\n        nbPoints = nbPoints > 3 ? nbPoints : 4;\r\n        const bez: Vector3[] = [];\r\n        const equation = (t: number, val0: number, val1: number, val2: number, val3: number) => {\r\n            const res = (1.0 - t) * (1.0 - t) * (1.0 - t) * val0 + 3.0 * t * (1.0 - t) * (1.0 - t) * val1 + 3.0 * t * t * (1.0 - t) * val2 + t * t * t * val3;\r\n            return res;\r\n        };\r\n        for (let i = 0; i <= nbPoints; i++) {\r\n            bez.push(new Vector3(equation(i / nbPoints, v0.x, v1.x, v2.x, v3.x), equation(i / nbPoints, v0.y, v1.y, v2.y, v3.y), equation(i / nbPoints, v0.z, v1.z, v2.z, v3.z)));\r\n        }\r\n        return new Curve3(bez);\r\n    }\r\n\r\n    /**\r\n     * Returns a Curve3 object along a Hermite Spline curve : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#hermite-spline\r\n     * @param p1 (Vector3) the origin point of the Hermite Spline\r\n     * @param t1 (Vector3) the tangent vector at the origin point\r\n     * @param p2 (Vector3) the end point of the Hermite Spline\r\n     * @param t2 (Vector3) the tangent vector at the end point\r\n     * @param nSeg (integer) the number of curve segments or nSeg + 1 points in the array\r\n     * @returns the created Curve3\r\n     */\r\n    public static CreateHermiteSpline(p1: DeepImmutable<Vector3>, t1: DeepImmutable<Vector3>, p2: DeepImmutable<Vector3>, t2: DeepImmutable<Vector3>, nSeg: number): Curve3 {\r\n        const hermite: Vector3[] = [];\r\n        const step = 1.0 / nSeg;\r\n        for (let i = 0; i <= nSeg; i++) {\r\n            hermite.push(Vector3.Hermite(p1, t1, p2, t2, i * step));\r\n        }\r\n        return new Curve3(hermite);\r\n    }\r\n\r\n    /**\r\n     * Returns a Curve3 object along a CatmullRom Spline curve :\r\n     * @param points (array of Vector3) the points the spline must pass through. At least, four points required\r\n     * @param nbPoints (integer) the wanted number of points between each curve control points\r\n     * @param closed (boolean) optional with default false, when true forms a closed loop from the points\r\n     * @returns the created Curve3\r\n     */\r\n    public static CreateCatmullRomSpline(points: DeepImmutable<Vector3[]>, nbPoints: number, closed?: boolean): Curve3 {\r\n        const catmullRom: Vector3[] = [];\r\n        const step = 1.0 / nbPoints;\r\n        let amount = 0.0;\r\n        if (closed) {\r\n            const pointsCount = points.length;\r\n            for (let i = 0; i < pointsCount; i++) {\r\n                amount = 0;\r\n                for (let c = 0; c < nbPoints; c++) {\r\n                    catmullRom.push(\r\n                        Vector3.CatmullRom(points[i % pointsCount], points[(i + 1) % pointsCount], points[(i + 2) % pointsCount], points[(i + 3) % pointsCount], amount)\r\n                    );\r\n                    amount += step;\r\n                }\r\n            }\r\n            catmullRom.push(catmullRom[0]);\r\n        } else {\r\n            const totalPoints: Vector3[] = [];\r\n            totalPoints.push(points[0].clone());\r\n            totalPoints.push(...points);\r\n            totalPoints.push(points[points.length - 1].clone());\r\n            let i = 0;\r\n            for (; i < totalPoints.length - 3; i++) {\r\n                amount = 0;\r\n                for (let c = 0; c < nbPoints; c++) {\r\n                    catmullRom.push(Vector3.CatmullRom(totalPoints[i], totalPoints[i + 1], totalPoints[i + 2], totalPoints[i + 3], amount));\r\n                    amount += step;\r\n                }\r\n            }\r\n            i--;\r\n            catmullRom.push(Vector3.CatmullRom(totalPoints[i], totalPoints[i + 1], totalPoints[i + 2], totalPoints[i + 3], amount));\r\n        }\r\n        return new Curve3(catmullRom);\r\n    }\r\n\r\n    /**\r\n     * Returns a Curve3 object along an arc through three vector3 points:\r\n     * The three points should not be colinear. When they are the Curve3 is empty.\r\n     * @param first (Vector3) the first point the arc must pass through.\r\n     * @param second (Vector3) the second point the arc must pass through.\r\n     * @param third (Vector3) the third point the arc must pass through.\r\n     * @param steps (number) the larger the number of steps the more detailed the arc.\r\n     * @param closed (boolean) optional with default false, when true forms the chord from the first and third point\r\n     * @param fullCircle Circle (boolean) optional with default false, when true forms the complete circle through the three points\r\n     * @returns the created Curve3\r\n     */\r\n    public static ArcThru3Points(first: Vector3, second: Vector3, third: Vector3, steps: number = 32, closed: boolean = false, fullCircle: boolean = false): Curve3 {\r\n        const arc: Vector3[] = [];\r\n        const vec1 = second.subtract(first);\r\n        const vec2 = third.subtract(second);\r\n        const vec3 = first.subtract(third);\r\n        const zAxis = Vector3.Cross(vec1, vec2);\r\n        const len4 = zAxis.length();\r\n        if (len4 < Math.pow(10, -8)) {\r\n            return new Curve3(arc); // colinear points arc is empty\r\n        }\r\n        const len1Sq = vec1.lengthSquared();\r\n        const len2Sq = vec2.lengthSquared();\r\n        const len3Sq = vec3.lengthSquared();\r\n        const len4Sq = zAxis.lengthSquared();\r\n        const len1 = vec1.length();\r\n        const len2 = vec2.length();\r\n        const len3 = vec3.length();\r\n        const radius = (0.5 * len1 * len2 * len3) / len4;\r\n        const dot1 = Vector3.Dot(vec1, vec3);\r\n        const dot2 = Vector3.Dot(vec1, vec2);\r\n        const dot3 = Vector3.Dot(vec2, vec3);\r\n        const a = (-0.5 * len2Sq * dot1) / len4Sq;\r\n        const b = (-0.5 * len3Sq * dot2) / len4Sq;\r\n        const c = (-0.5 * len1Sq * dot3) / len4Sq;\r\n        const center = first.scale(a).add(second.scale(b)).add(third.scale(c));\r\n        const radiusVec = first.subtract(center);\r\n        const xAxis = radiusVec.normalize();\r\n        const yAxis = Vector3.Cross(zAxis, xAxis).normalize();\r\n        if (fullCircle) {\r\n            const dStep = (2 * Math.PI) / steps;\r\n            for (let theta = 0; theta <= 2 * Math.PI; theta += dStep) {\r\n                arc.push(center.add(xAxis.scale(radius * Math.cos(theta)).add(yAxis.scale(radius * Math.sin(theta)))));\r\n            }\r\n            arc.push(first);\r\n        } else {\r\n            const dStep = 1 / steps;\r\n            let theta = 0;\r\n            let point: Vector3;\r\n            do {\r\n                point = center.add(xAxis.scale(radius * Math.cos(theta)).add(yAxis.scale(radius * Math.sin(theta))));\r\n                arc.push(point);\r\n                theta += dStep;\r\n            } while (!point.equalsWithEpsilon(third, radius * dStep * 1.1));\r\n            arc.push(third);\r\n            if (closed) {\r\n                arc.push(first);\r\n            }\r\n        }\r\n        return new Curve3(arc);\r\n    }\r\n\r\n    /**\r\n     * A Curve3 object is a logical object, so not a mesh, to handle curves in the 3D geometric space.\r\n     * A Curve3 is designed from a series of successive Vector3.\r\n     * Tuto : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#curve3-object\r\n     * @param points points which make up the curve\r\n     */\r\n    constructor(points: Vector3[]) {\r\n        this._points = points;\r\n        this._length = this._computeLength(points);\r\n    }\r\n\r\n    /**\r\n     * @returns the Curve3 stored array of successive Vector3\r\n     */\r\n    public getPoints() {\r\n        return this._points;\r\n    }\r\n\r\n    /**\r\n     * @returns the computed length (float) of the curve.\r\n     */\r\n    public length() {\r\n        return this._length;\r\n    }\r\n\r\n    /**\r\n     * Returns a new instance of Curve3 object : var curve = curveA.continue(curveB);\r\n     * This new Curve3 is built by translating and sticking the curveB at the end of the curveA.\r\n     * curveA and curveB keep unchanged.\r\n     * @param curve the curve to continue from this curve\r\n     * @returns the newly constructed curve\r\n     */\r\n    public continue(curve: DeepImmutable<Curve3>): Curve3 {\r\n        const lastPoint = this._points[this._points.length - 1];\r\n        const continuedPoints = this._points.slice();\r\n        const curvePoints = curve.getPoints();\r\n        for (let i = 1; i < curvePoints.length; i++) {\r\n            continuedPoints.push(curvePoints[i].subtract(curvePoints[0]).add(lastPoint));\r\n        }\r\n        const continuedCurve = new Curve3(continuedPoints);\r\n        return continuedCurve;\r\n    }\r\n\r\n    private _computeLength(path: DeepImmutable<Vector3[]>): number {\r\n        let l = 0;\r\n        for (let i = 1; i < path.length; i++) {\r\n            l += path[i].subtract(path[i - 1]).length();\r\n        }\r\n        return l;\r\n    }\r\n}\r\n","import { BezierCurve } from \"../Maths/math.path\";\r\n\r\n/**\r\n * This represents the main contract an easing function should follow.\r\n * Easing functions are used throughout the animation system.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport interface IEasingFunction {\r\n    /**\r\n     * Given an input gradient between 0 and 1, this returns the corresponding value\r\n     * of the easing function.\r\n     * The link below provides some of the most common examples of easing functions.\r\n     * @see https://easings.net/\r\n     * @param gradient Defines the value between 0 and 1 we want the easing value for\r\n     * @returns the corresponding value on the curve defined by the easing function\r\n     */\r\n    ease(gradient: number): number;\r\n}\r\n\r\n/**\r\n * Base class used for every default easing function.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Interpolation follows the mathematical formula associated with the easing function.\r\n     */\r\n    public static readonly EASINGMODE_EASEIN = 0;\r\n\r\n    /**\r\n     * Interpolation follows 100% interpolation minus the output of the formula associated with the easing function.\r\n     */\r\n    public static readonly EASINGMODE_EASEOUT = 1;\r\n\r\n    /**\r\n     * Interpolation uses EaseIn for the first half of the animation and EaseOut for the second half.\r\n     */\r\n    public static readonly EASINGMODE_EASEINOUT = 2;\r\n\r\n    private _easingMode = EasingFunction.EASINGMODE_EASEIN;\r\n\r\n    /**\r\n     * Sets the easing mode of the current function.\r\n     * @param easingMode Defines the willing mode (EASINGMODE_EASEIN, EASINGMODE_EASEOUT or EASINGMODE_EASEINOUT)\r\n     */\r\n    public setEasingMode(easingMode: number) {\r\n        const n = Math.min(Math.max(easingMode, 0), 2);\r\n        this._easingMode = n;\r\n    }\r\n    /**\r\n     * Gets the current easing mode.\r\n     * @returns the easing mode\r\n     */\r\n    public getEasingMode(): number {\r\n        return this._easingMode;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public easeInCore(gradient: number): number {\r\n        throw new Error(\"You must implement this method\");\r\n    }\r\n\r\n    /**\r\n     * Given an input gradient between 0 and 1, this returns the corresponding value\r\n     * of the easing function.\r\n     * @param gradient Defines the value between 0 and 1 we want the easing value for\r\n     * @returns the corresponding value on the curve defined by the easing function\r\n     */\r\n    public ease(gradient: number): number {\r\n        switch (this._easingMode) {\r\n            case EasingFunction.EASINGMODE_EASEIN:\r\n                return this.easeInCore(gradient);\r\n            case EasingFunction.EASINGMODE_EASEOUT:\r\n                return 1 - this.easeInCore(1 - gradient);\r\n        }\r\n\r\n        if (gradient >= 0.5) {\r\n            return (1 - this.easeInCore((1 - gradient) * 2)) * 0.5 + 0.5;\r\n        }\r\n\r\n        return this.easeInCore(gradient * 2) * 0.5;\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a circle shape (see link below).\r\n * @see https://easings.net/#easeInCirc\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class CircleEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        gradient = Math.max(0, Math.min(1, gradient));\r\n        return 1.0 - Math.sqrt(1.0 - gradient * gradient);\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a ease back shape (see link below).\r\n * @see https://easings.net/#easeInBack\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class BackEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Instantiates a back ease easing\r\n     * @see https://easings.net/#easeInBack\r\n     * @param amplitude Defines the amplitude of the function\r\n     */\r\n    constructor(\r\n        /** [1] Defines the amplitude of the function */\r\n        public amplitude: number = 1\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        const num = Math.max(0, this.amplitude);\r\n        return Math.pow(gradient, 3.0) - gradient * num * Math.sin(3.1415926535897931 * gradient);\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a bouncing shape (see link below).\r\n * @see https://easings.net/#easeInBounce\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class BounceEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Instantiates a bounce easing\r\n     * @see https://easings.net/#easeInBounce\r\n     * @param bounces Defines the number of bounces\r\n     * @param bounciness Defines the amplitude of the bounce\r\n     */\r\n    constructor(\r\n        /** [3] Defines the number of bounces */\r\n        public bounces: number = 3,\r\n        /** [2] Defines the amplitude of the bounce */\r\n        public bounciness: number = 2\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        const y = Math.max(0.0, this.bounces);\r\n        let bounciness = this.bounciness;\r\n        if (bounciness <= 1.0) {\r\n            bounciness = 1.001;\r\n        }\r\n        const num9 = Math.pow(bounciness, y);\r\n        const num5 = 1.0 - bounciness;\r\n        const num4 = (1.0 - num9) / num5 + num9 * 0.5;\r\n        const num15 = gradient * num4;\r\n        const num65 = Math.log(-num15 * (1.0 - bounciness) + 1.0) / Math.log(bounciness);\r\n        const num3 = Math.floor(num65);\r\n        const num13 = num3 + 1.0;\r\n        const num8 = (1.0 - Math.pow(bounciness, num3)) / (num5 * num4);\r\n        const num12 = (1.0 - Math.pow(bounciness, num13)) / (num5 * num4);\r\n        const num7 = (num8 + num12) * 0.5;\r\n        const num6 = gradient - num7;\r\n        const num2 = num7 - num8;\r\n        return (-Math.pow(1.0 / bounciness, y - num3) / (num2 * num2)) * (num6 - num2) * (num6 + num2);\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a power of 3 shape (see link below).\r\n * @see https://easings.net/#easeInCubic\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class CubicEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        return gradient * gradient * gradient;\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with an elastic shape (see link below).\r\n * @see https://easings.net/#easeInElastic\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class ElasticEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Instantiates an elastic easing function\r\n     * @see https://easings.net/#easeInElastic\r\n     * @param oscillations Defines the number of oscillations\r\n     * @param springiness Defines the amplitude of the oscillations\r\n     */\r\n    constructor(\r\n        /** [3] Defines the number of oscillations*/\r\n        public oscillations: number = 3,\r\n        /** [3] Defines the amplitude of the oscillations*/\r\n        public springiness: number = 3\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        let num2;\r\n        const num3 = Math.max(0.0, this.oscillations);\r\n        const num = Math.max(0.0, this.springiness);\r\n\r\n        if (num === 0) {\r\n            num2 = gradient;\r\n        } else {\r\n            num2 = (Math.exp(num * gradient) - 1.0) / (Math.exp(num) - 1.0);\r\n        }\r\n        return num2 * Math.sin((6.2831853071795862 * num3 + 1.5707963267948966) * gradient);\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with an exponential shape (see link below).\r\n * @see https://easings.net/#easeInExpo\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class ExponentialEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Instantiates an exponential easing function\r\n     * @see https://easings.net/#easeInExpo\r\n     * @param exponent Defines the exponent of the function\r\n     */\r\n    constructor(\r\n        /** [3] Defines the exponent of the function */\r\n        public exponent: number = 2\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        if (this.exponent <= 0) {\r\n            return gradient;\r\n        }\r\n\r\n        return (Math.exp(this.exponent * gradient) - 1.0) / (Math.exp(this.exponent) - 1.0);\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a power shape (see link below).\r\n * @see https://easings.net/#easeInQuad\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class PowerEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Instantiates an power base easing function\r\n     * @see https://easings.net/#easeInQuad\r\n     * @param power Defines the power of the function\r\n     */\r\n    constructor(\r\n        /** [2] Defines the power of the function */\r\n        public power: number = 2\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        const y = Math.max(0.0, this.power);\r\n        return Math.pow(gradient, y);\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a power of 2 shape (see link below).\r\n * @see https://easings.net/#easeInQuad\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class QuadraticEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        return gradient * gradient;\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a power of 4 shape (see link below).\r\n * @see https://easings.net/#easeInQuart\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class QuarticEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        return gradient * gradient * gradient * gradient;\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a power of 5 shape (see link below).\r\n * @see https://easings.net/#easeInQuint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class QuinticEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        return gradient * gradient * gradient * gradient * gradient;\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a sin shape (see link below).\r\n * @see https://easings.net/#easeInSine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class SineEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        return 1.0 - Math.sin(1.5707963267948966 * (1.0 - gradient));\r\n    }\r\n}\r\n\r\n/**\r\n * Easing function with a bezier shape (see link below).\r\n * @see http://cubic-bezier.com/#.17,.67,.83,.67\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions\r\n */\r\nexport class BezierCurveEase extends EasingFunction implements IEasingFunction {\r\n    /**\r\n     * Instantiates a bezier function\r\n     * @see http://cubic-bezier.com/#.17,.67,.83,.67\r\n     * @param x1 Defines the x component of the start tangent in the bezier curve\r\n     * @param y1 Defines the y component of the start tangent in the bezier curve\r\n     * @param x2 Defines the x component of the end tangent in the bezier curve\r\n     * @param y2 Defines the y component of the end tangent in the bezier curve\r\n     */\r\n    constructor(\r\n        /** [0] Defines the x component of the start tangent in the bezier curve */\r\n        public x1: number = 0,\r\n        /** [0] Defines the y component of the start tangent in the bezier curve */\r\n        public y1: number = 0,\r\n        /** [1] Defines the x component of the end tangent in the bezier curve */\r\n        public x2: number = 1,\r\n        /** [1] Defines the y component of the end tangent in the bezier curve */\r\n        public y2: number = 1\r\n    ) {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override easeInCore(gradient: number): number {\r\n        return BezierCurve.Interpolate(gradient, this.x1, this.y1, this.x2, this.y2);\r\n    }\r\n}\r\n","/**\r\n * Composed of a frame, and an action function\r\n */\r\nexport class AnimationEvent {\r\n    /**\r\n     * Specifies if the animation event is done\r\n     */\r\n    public isDone: boolean = false;\r\n\r\n    /**\r\n     * Initializes the animation event\r\n     * @param frame The frame for which the event is triggered\r\n     * @param action The event to perform when triggered\r\n     * @param onlyOnce Specifies if the event should be triggered only once\r\n     */\r\n    constructor(\r\n        /** The frame for which the event is triggered **/\r\n        public frame: number,\r\n        /** The event to perform when triggered **/\r\n        public action: (currentFrame: number) => void,\r\n        /** Specifies if the event should be triggered only once**/\r\n        public onlyOnce?: boolean\r\n    ) {}\r\n\r\n    /** @internal */\r\n    public _clone(): AnimationEvent {\r\n        return new AnimationEvent(this.frame, this.action, this.onlyOnce);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Animatable } from \"./animatable.core\";\r\nimport { RegisterAnimatable } from \"./animatable.pure\";\r\nimport { type Animation, AnimationMakeAnimationAdditive, AnimationParse, type IMakeAnimationAdditiveOptions } from \"./animation.pure\";\r\nimport { type IAnimationKey } from \"./animationKey\";\r\n\r\nimport { type Scene, type IDisposable } from \"../scene.pure\";\r\nimport { Observable, type Observer } from \"../Misc/observable.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\nimport { Tags } from \"../Misc/tags\";\r\nimport { type AnimationGroupMask } from \"./animationGroupMask\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { UniqueIdGenerator } from \"core/Misc/uniqueIdGenerator\";\r\n\r\n/**\r\n * This class defines the direct association between an animation and a target\r\n */\r\nexport class TargetedAnimation {\r\n    /**\r\n     * Animation to perform\r\n     */\r\n    public animation: Animation;\r\n\r\n    /**\r\n     * Target to animate\r\n     */\r\n    public target: any;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the targeted animation\r\n     */\r\n    public readonly uniqueId = UniqueIdGenerator.UniqueId;\r\n\r\n    /**\r\n     * Returns the string \"TargetedAnimation\"\r\n     * @returns \"TargetedAnimation\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"TargetedAnimation\";\r\n    }\r\n\r\n    /**\r\n     * Creates a new targeted animation\r\n     * @param parent The animation group to which the animation belongs\r\n     */\r\n    constructor(public readonly parent: AnimationGroup) {}\r\n\r\n    /**\r\n     * Serialize the object\r\n     * @returns the JSON object representing the current entity\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.animation = this.animation.serialize();\r\n        serializationObject.targetId = this.target.id;\r\n        serializationObject.targetUniqueId = this.target.uniqueId;\r\n\r\n        return serializationObject;\r\n    }\r\n}\r\n\r\n/**\r\n * Options to be used when creating an additive group animation\r\n */\r\nexport interface IMakeAnimationGroupAdditiveOptions extends IMakeAnimationAdditiveOptions {\r\n    /**\r\n     * Defines if the animation group should be cloned or not (default is false)\r\n     */\r\n    cloneOriginalAnimationGroup?: boolean;\r\n    /**\r\n     * The name of the cloned animation group if cloneOriginalAnimationGroup is true\r\n     */\r\n    clonedAnimationGroupName?: string;\r\n}\r\n\r\n/**\r\n * Use this class to create coordinated animations on multiple targets\r\n */\r\nexport class AnimationGroup implements IDisposable {\r\n    private _scene: Scene;\r\n\r\n    private _targetedAnimations = new Array<TargetedAnimation>();\r\n    private _animatables = new Array<Animatable>();\r\n    private _from = Number.MAX_VALUE;\r\n    private _to = -Number.MAX_VALUE;\r\n    private _isStarted: boolean;\r\n    private _isPaused: boolean;\r\n    private _speedRatio = 1;\r\n    private _loopAnimation = false;\r\n    private _virtualFrame = 0;\r\n    private _virtualFrameStart = 0;\r\n    private _virtualFrameStartTime = 0;\r\n    private _virtualFrameRate = 60;\r\n    private _virtualFrameDirection = 1;\r\n    private _virtualFrameInitial = 0;\r\n    private _virtualFrameEnd = 0;\r\n    private _virtualSamplingObserver: Nullable<Observer<Scene>> = null;\r\n    private _usesVirtualSampling = false;\r\n    private _retainedCurrentFrame = 0;\r\n    private _isStopping = false;\r\n    private _isAdditive = false;\r\n    private _weight = -1;\r\n    private _playOrder = 0;\r\n    private _enableBlending: Nullable<boolean> = null;\r\n    private _blendingSpeed: Nullable<number> = null;\r\n    private _numActiveAnimatables = 0;\r\n    private _shouldStart = true;\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the node\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * This observable will notify when one animation have ended\r\n     */\r\n    public onAnimationEndObservable = new Observable<TargetedAnimation>();\r\n\r\n    /**\r\n     * Observer raised when one animation loops\r\n     */\r\n    public onAnimationLoopObservable = new Observable<TargetedAnimation>();\r\n\r\n    /**\r\n     * Observer raised when all animations have looped\r\n     */\r\n    public onAnimationGroupLoopObservable = new Observable<AnimationGroup>();\r\n\r\n    /**\r\n     * This observable will notify when all animations have ended.\r\n     */\r\n    public onAnimationGroupEndObservable = new Observable<AnimationGroup>();\r\n\r\n    /**\r\n     * This observable will notify when all animations have paused.\r\n     */\r\n    public onAnimationGroupPauseObservable = new Observable<AnimationGroup>();\r\n\r\n    /**\r\n     * This observable will notify when all animations are playing.\r\n     */\r\n    public onAnimationGroupPlayObservable = new Observable<AnimationGroup>();\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the node\r\n     */\r\n    public metadata: any = null;\r\n\r\n    private _mask: Nullable<AnimationGroupMask> = null;\r\n\r\n    /**\r\n     * Gets or sets the mask associated with this animation group. This mask is used to filter which objects should be animated.\r\n     */\r\n    public get mask() {\r\n        return this._mask;\r\n    }\r\n\r\n    public set mask(value: Nullable<AnimationGroupMask>) {\r\n        if (this._mask === value) {\r\n            return;\r\n        }\r\n\r\n        this._mask = value;\r\n\r\n        this.syncWithMask(true);\r\n    }\r\n\r\n    /**\r\n     * Makes sure that the animations are either played or stopped according to the animation group mask.\r\n     * Note however that the call won't have any effect if the animation group has not been started yet.\r\n     * @param forceUpdate If true, forces to loop over the animatables even if no mask is defined (used internally, you shouldn't need to use it). Default: false.\r\n     */\r\n    public syncWithMask(forceUpdate = false) {\r\n        if (!this.mask && !forceUpdate) {\r\n            this._numActiveAnimatables = this._targetedAnimations.length;\r\n            return;\r\n        }\r\n\r\n        this._numActiveAnimatables = 0;\r\n\r\n        for (let i = 0; i < this._animatables.length; ++i) {\r\n            const animatable = this._animatables[i];\r\n\r\n            if (!this.mask || this.mask.disabled || this.mask.retainsTarget(animatable.target.name)) {\r\n                this._numActiveAnimatables++;\r\n                if (animatable.paused) {\r\n                    animatable.restart();\r\n                }\r\n            } else {\r\n                if (!animatable.paused) {\r\n                    animatable.pause();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all animations for the targets not retained by the animation group mask.\r\n     * Use this function if you know you won't need those animations anymore and if you want to free memory.\r\n     */\r\n    public removeUnmaskedAnimations() {\r\n        if (!this.mask || this.mask.disabled) {\r\n            return;\r\n        }\r\n\r\n        // Removes all animatables (in case the animation group has already been started)\r\n        for (let i = 0; i < this._animatables.length; ++i) {\r\n            const animatable = this._animatables[i];\r\n\r\n            if (!this.mask.retainsTarget(animatable.target.name)) {\r\n                animatable.stop();\r\n                this._animatables.splice(i, 1);\r\n                --i;\r\n            }\r\n        }\r\n\r\n        // Removes the targeted animations\r\n        for (let index = 0; index < this._targetedAnimations.length; index++) {\r\n            const targetedAnimation = this._targetedAnimations[index];\r\n\r\n            if (!this.mask.retainsTarget(targetedAnimation.target.name)) {\r\n                this._targetedAnimations.splice(index, 1);\r\n                --index;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the first frame\r\n     */\r\n    public get from(): number {\r\n        return this._from;\r\n    }\r\n\r\n    public set from(value: number) {\r\n        if (this._from === value) {\r\n            return;\r\n        }\r\n\r\n        this._from = value;\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.fromFrame = this._from;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the last frame\r\n     */\r\n    public get to(): number {\r\n        return this._to;\r\n    }\r\n\r\n    public set to(value: number) {\r\n        if (this._to === value) {\r\n            return;\r\n        }\r\n\r\n        this._to = value;\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.toFrame = this._to;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Define if the animations are started\r\n     */\r\n    public get isStarted(): boolean {\r\n        return this._isStarted;\r\n    }\r\n\r\n    /**\r\n     * Gets a value indicating that the current group is playing\r\n     */\r\n    public get isPlaying(): boolean {\r\n        return this._isStarted && !this._isPaused;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the speed ratio to use for all animations\r\n     */\r\n    public get speedRatio(): number {\r\n        return this._speedRatio;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the speed ratio to use for all animations\r\n     */\r\n    public set speedRatio(value: number) {\r\n        if (this._speedRatio === value) {\r\n            return;\r\n        }\r\n\r\n        if (this._animatables[0]) {\r\n            this._retainedCurrentFrame = this._animatables[0].masterFrame;\r\n        }\r\n        this._updateVirtualFrame();\r\n        this._speedRatio = value;\r\n        this._virtualFrameStart = this._virtualFrame;\r\n        this._virtualFrameStartTime = this._scene._animationTime;\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.speedRatio = this._speedRatio;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets if all animations should loop or not\r\n     */\r\n    public get loopAnimation(): boolean {\r\n        return this._loopAnimation;\r\n    }\r\n\r\n    public set loopAnimation(value: boolean) {\r\n        if (this._loopAnimation === value) {\r\n            return;\r\n        }\r\n\r\n        this._loopAnimation = value;\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.loopAnimation = this._loopAnimation;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets if all animations should be evaluated additively\r\n     */\r\n    public get isAdditive(): boolean {\r\n        return this._isAdditive;\r\n    }\r\n\r\n    public set isAdditive(value: boolean) {\r\n        if (this._isAdditive === value) {\r\n            return;\r\n        }\r\n\r\n        this._isAdditive = value;\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.isAdditive = this._isAdditive;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the weight to apply to all animations of the group\r\n     */\r\n    public get weight(): number {\r\n        return this._weight;\r\n    }\r\n\r\n    public set weight(value: number) {\r\n        if (this._weight === value) {\r\n            return;\r\n        }\r\n\r\n        this._weight = value;\r\n        this.setWeightForAllAnimatables(this._weight);\r\n    }\r\n\r\n    /**\r\n     * Gets the targeted animations for this animation group\r\n     */\r\n    public get targetedAnimations(): Array<TargetedAnimation> {\r\n        return this._targetedAnimations;\r\n    }\r\n\r\n    /**\r\n     * returning the list of animatables controlled by this animation group.\r\n     */\r\n    public get animatables(): Array<Animatable> {\r\n        return this._animatables;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of target animations\r\n     */\r\n    public get children() {\r\n        return this._targetedAnimations;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the order of play of the animation group (default: 0)\r\n     */\r\n    public get playOrder() {\r\n        return this._playOrder;\r\n    }\r\n\r\n    public set playOrder(value: number) {\r\n        if (this._playOrder === value) {\r\n            return;\r\n        }\r\n\r\n        this._playOrder = value;\r\n\r\n        if (this._animatables.length > 0) {\r\n            for (let i = 0; i < this._animatables.length; i++) {\r\n                this._animatables[i].playOrder = this._playOrder;\r\n            }\r\n\r\n            this._scene.sortActiveAnimatables();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Allows the animations of the animation group to blend with current running animations\r\n     * Note that a null value means that each animation will use their own existing blending configuration (Animation.enableBlending)\r\n     */\r\n    public get enableBlending() {\r\n        return this._enableBlending;\r\n    }\r\n\r\n    public set enableBlending(value: Nullable<boolean>) {\r\n        if (this._enableBlending === value) {\r\n            return;\r\n        }\r\n\r\n        this._enableBlending = value;\r\n\r\n        if (value !== null) {\r\n            for (let i = 0; i < this._targetedAnimations.length; ++i) {\r\n                this._targetedAnimations[i].animation.enableBlending = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the animation blending speed\r\n     * Note that a null value means that each animation will use their own existing blending configuration (Animation.blendingSpeed)\r\n     */\r\n    public get blendingSpeed() {\r\n        return this._blendingSpeed;\r\n    }\r\n\r\n    public set blendingSpeed(value: Nullable<number>) {\r\n        if (this._blendingSpeed === value) {\r\n            return;\r\n        }\r\n\r\n        this._blendingSpeed = value;\r\n\r\n        if (value !== null) {\r\n            for (let i = 0; i < this._targetedAnimations.length; ++i) {\r\n                this._targetedAnimations[i].animation.blendingSpeed = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the length (in seconds) of the animation group\r\n     * This function assumes that all animations are played at the same framePerSecond speed!\r\n     * Note: you can only call this method after you've added at least one targeted animation!\r\n     * @param from Starting frame range (default is AnimationGroup.from)\r\n     * @param to Ending frame range (default is AnimationGroup.to)\r\n     * @returns The length in seconds\r\n     */\r\n    public getLength(from?: number, to?: number): number {\r\n        from = from ?? this._from;\r\n        to = to ?? this._to;\r\n\r\n        const fps = this.targetedAnimations[0].animation.framePerSecond * this._speedRatio;\r\n\r\n        return (to - from) / fps;\r\n    }\r\n\r\n    /**\r\n     * Gets the scene the animation group belongs to\r\n     * @returns The scene the animation group belongs to\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new Animation Group.\r\n     * This helps managing several animations at once.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/groupAnimations\r\n     * @param name Defines the name of the group\r\n     * @param scene Defines the scene the group belongs to\r\n     * @param weight Defines the weight to use for animations in the group (-1.0 by default, meaning \"no weight\")\r\n     * @param playOrder Defines the order of play of the animation group (default is 0)\r\n     */\r\n    public constructor(\r\n        /** The name of the animation group */\r\n        public name: string,\r\n        scene: Nullable<Scene> = null,\r\n        weight = -1,\r\n        playOrder = 0\r\n    ) {\r\n        this._scene = scene || EngineStore.LastCreatedScene!;\r\n        this._weight = weight;\r\n        this._playOrder = playOrder;\r\n        this.uniqueId = this._scene.getUniqueId();\r\n\r\n        RegisterAnimatable();\r\n\r\n        this._scene.addAnimationGroup(this);\r\n    }\r\n\r\n    /**\r\n     * Add an animation (with its target) in the group\r\n     * @param animation defines the animation we want to add\r\n     * @param target defines the target of the animation\r\n     * @returns the TargetedAnimation object\r\n     */\r\n    public addTargetedAnimation(animation: Animation, target: any): TargetedAnimation {\r\n        const targetedAnimation = new TargetedAnimation(this);\r\n        targetedAnimation.animation = animation;\r\n        targetedAnimation.target = target;\r\n\r\n        const keys = animation.getKeys();\r\n        if (this._from > keys[0].frame) {\r\n            this._from = keys[0].frame;\r\n        }\r\n\r\n        if (this._to < keys[keys.length - 1].frame) {\r\n            this._to = keys[keys.length - 1].frame;\r\n        }\r\n\r\n        if (this._enableBlending !== null) {\r\n            animation.enableBlending = this._enableBlending;\r\n        }\r\n\r\n        if (this._blendingSpeed !== null) {\r\n            animation.blendingSpeed = this._blendingSpeed;\r\n        }\r\n\r\n        this._targetedAnimations.push(targetedAnimation);\r\n        this._shouldStart = true;\r\n\r\n        return targetedAnimation;\r\n    }\r\n\r\n    /**\r\n     * Remove an animation from the group\r\n     * @param animation defines the animation we want to remove\r\n     */\r\n    public removeTargetedAnimation(animation: Animation) {\r\n        for (let index = this._targetedAnimations.length - 1; index > -1; index--) {\r\n            const targetedAnimation = this._targetedAnimations[index];\r\n            if (targetedAnimation.animation === animation) {\r\n                this._targetedAnimations.splice(index, 1);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame\r\n     * It can add constant keys at begin or end\r\n     * @param beginFrame defines the new begin frame for all animations or the smallest begin frame of all animations if null (defaults to null)\r\n     * @param endFrame defines the new end frame for all animations or the largest end frame of all animations if null (defaults to null)\r\n     * @returns the animation group\r\n     */\r\n    public normalize(beginFrame: Nullable<number> = null, endFrame: Nullable<number> = null): AnimationGroup {\r\n        if (beginFrame == null) {\r\n            beginFrame = this._from;\r\n        }\r\n        if (endFrame == null) {\r\n            endFrame = this._to;\r\n        }\r\n\r\n        for (let index = 0; index < this._targetedAnimations.length; index++) {\r\n            const targetedAnimation = this._targetedAnimations[index];\r\n            const keys = targetedAnimation.animation.getKeys();\r\n            const startKey = keys[0];\r\n            const endKey = keys[keys.length - 1];\r\n\r\n            if (startKey.frame > beginFrame) {\r\n                const newKey: IAnimationKey = {\r\n                    frame: beginFrame,\r\n                    value: startKey.value,\r\n                    inTangent: startKey.inTangent,\r\n                    outTangent: startKey.outTangent,\r\n                    interpolation: startKey.interpolation,\r\n                };\r\n                keys.splice(0, 0, newKey);\r\n            }\r\n\r\n            if (endKey.frame < endFrame) {\r\n                const newKey: IAnimationKey = {\r\n                    frame: endFrame,\r\n                    value: endKey.value,\r\n                    inTangent: endKey.inTangent,\r\n                    outTangent: endKey.outTangent,\r\n                    interpolation: endKey.interpolation,\r\n                };\r\n                keys.push(newKey);\r\n            }\r\n        }\r\n\r\n        this._from = beginFrame;\r\n        this._to = endFrame;\r\n\r\n        return this;\r\n    }\r\n\r\n    private _animationLoopCount: number;\r\n    private _animationLoopFlags: boolean[] = [];\r\n\r\n    private _processLoop(animatable: Animatable, targetedAnimation: TargetedAnimation, index: number) {\r\n        animatable.onAnimationLoop = () => {\r\n            this.onAnimationLoopObservable.notifyObservers(targetedAnimation);\r\n\r\n            if (this._animationLoopFlags[index]) {\r\n                return;\r\n            }\r\n\r\n            this._animationLoopFlags[index] = true;\r\n\r\n            this._animationLoopCount++;\r\n            if (this._animationLoopCount === this._numActiveAnimatables) {\r\n                this.onAnimationGroupLoopObservable.notifyObservers(this);\r\n                this._animationLoopCount = 0;\r\n                this._animationLoopFlags.length = 0;\r\n            }\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Start all animations on given targets\r\n     * @param loop defines if animations must loop\r\n     * @param speedRatio defines the ratio to apply to animation speed (1 by default)\r\n     * @param from defines the from key (optional)\r\n     * @param to defines the to key (optional)\r\n     * @param isAdditive defines the additive state for the resulting animatables (optional)\r\n     * @returns the current animation group\r\n     */\r\n    public start(loop = false, speedRatio = 1, from?: number, to?: number, isAdditive?: boolean): AnimationGroup {\r\n        return this._start(loop, speedRatio, from, to, isAdditive, false);\r\n    }\r\n\r\n    /**\r\n     * Starts all animations using an unbounded requested timeline mapped to the animation's\r\n     * effective keyframe range.\r\n     * @param loop defines if animations must loop\r\n     * @param speedRatio defines the ratio to apply to animation speed\r\n     * @param from defines the requested start frame\r\n     * @param to defines the requested end frame\r\n     * @param isAdditive defines the additive state for the resulting animatables\r\n     * @returns the current animation group\r\n     */\r\n    public startWithVirtualTimeline(loop = false, speedRatio = 1, from?: number, to?: number, isAdditive?: boolean): AnimationGroup {\r\n        return this._start(loop, speedRatio, from, to, isAdditive, true);\r\n    }\r\n\r\n    private _start(\r\n        loop: boolean,\r\n        speedRatio: number,\r\n        from: number | undefined,\r\n        to: number | undefined,\r\n        isAdditive: boolean | undefined,\r\n        useVirtualTimeline: boolean\r\n    ): AnimationGroup {\r\n        if (this._isStarted || this._targetedAnimations.length === 0) {\r\n            return this;\r\n        }\r\n\r\n        this._loopAnimation = loop;\r\n        const effectiveFrom = from ?? this._from;\r\n        const effectiveTo = to ?? this._to;\r\n        this._virtualFrame = effectiveFrom;\r\n        this._virtualFrameStart = effectiveFrom;\r\n        this._virtualFrameStartTime = this._scene._animationTime;\r\n        this._virtualFrameRate = this._targetedAnimations[0]?.animation.framePerSecond ?? 60;\r\n        this._virtualFrameDirection = effectiveTo < effectiveFrom ? -1 : 1;\r\n        this._virtualFrameInitial = effectiveFrom;\r\n        this._virtualFrameEnd = effectiveTo;\r\n        const effectiveSamplingFrom = useVirtualTimeline ? this._mapVirtualFrame(effectiveFrom) : effectiveFrom;\r\n        const effectiveSamplingTo = useVirtualTimeline\r\n            ? Number.isFinite(effectiveTo)\r\n                ? this._mapVirtualFrame(effectiveTo)\r\n                : effectiveTo < effectiveFrom\r\n                  ? 0\r\n                  : this._to\r\n            : effectiveTo;\r\n        this._retainedCurrentFrame = effectiveSamplingFrom;\r\n        this._usesVirtualSampling = useVirtualTimeline && (effectiveSamplingFrom !== effectiveFrom || effectiveSamplingTo !== effectiveTo);\r\n        const samplingFrom = this._usesVirtualSampling ? (this._virtualFrameDirection > 0 ? 0 : this._to) : effectiveSamplingFrom;\r\n        const samplingTo = this._usesVirtualSampling ? (this._virtualFrameDirection > 0 ? this._to : 0) : effectiveSamplingTo;\r\n\r\n        this._shouldStart = false;\r\n        this._animationLoopCount = 0;\r\n        this._animationLoopFlags.length = 0;\r\n\r\n        for (let index = 0; index < this._targetedAnimations.length; index++) {\r\n            const targetedAnimation = this._targetedAnimations[index];\r\n            const animatable = this._scene.beginDirectAnimation(\r\n                targetedAnimation.target,\r\n                [targetedAnimation.animation],\r\n                samplingFrom,\r\n                samplingTo,\r\n                this._usesVirtualSampling || loop,\r\n                speedRatio,\r\n                undefined,\r\n                undefined,\r\n                isAdditive !== undefined ? isAdditive : this._isAdditive\r\n            );\r\n            animatable.weight = this._weight;\r\n            animatable.playOrder = this._playOrder;\r\n            animatable.onAnimationEnd = () => {\r\n                this.onAnimationEndObservable.notifyObservers(targetedAnimation);\r\n                this._checkAnimationGroupEnded(animatable);\r\n            };\r\n\r\n            this._processLoop(animatable, targetedAnimation, index);\r\n            this._animatables.push(animatable);\r\n            if (this._usesVirtualSampling && this._isTargetRetainedByMask(animatable.target)) {\r\n                animatable.goToFrame(effectiveSamplingFrom);\r\n            }\r\n        }\r\n\r\n        this.syncWithMask();\r\n\r\n        this._scene.sortActiveAnimatables();\r\n\r\n        this._speedRatio = speedRatio;\r\n\r\n        this._isStarted = true;\r\n        this._isPaused = false;\r\n\r\n        if (this._usesVirtualSampling) {\r\n            this._virtualSamplingObserver = this._scene.onAfterAnimationsObservable.add(() => {\r\n                this._sampleVirtualTimeline();\r\n            });\r\n        }\r\n\r\n        this.onAnimationGroupPlayObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Pause all animations\r\n     * @returns the animation group\r\n     */\r\n    public pause(): AnimationGroup {\r\n        if (!this._isStarted) {\r\n            return this;\r\n        }\r\n\r\n        this._updateVirtualFrame();\r\n        this._isPaused = true;\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.pause();\r\n        }\r\n\r\n        this.onAnimationGroupPauseObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Play all animations to initial state\r\n     * This function will start() the animations if they were not started or will restart() them if they were paused\r\n     * @param loop defines if animations must loop\r\n     * @returns the animation group\r\n     */\r\n    public play(loop?: boolean): AnimationGroup {\r\n        // only if there are animatable available\r\n        if (this.isStarted && this._animatables.length && !this._shouldStart) {\r\n            if (loop !== undefined) {\r\n                this.loopAnimation = loop;\r\n            }\r\n            this.restart();\r\n        } else {\r\n            this.stop();\r\n            this.start(loop, this._speedRatio);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Reset all animations to initial state\r\n     * @returns the animation group\r\n     */\r\n    public reset(): AnimationGroup {\r\n        if (!this._isStarted) {\r\n            this.play();\r\n            this.goToFrame(0);\r\n            this.stop(true);\r\n            return this;\r\n        }\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.reset();\r\n        }\r\n        this._virtualFrame = this._usesVirtualSampling ? this._virtualFrameInitial : (this._animatables[0]?.fromFrame ?? 0);\r\n        this._virtualFrameStart = this._virtualFrame;\r\n        this._virtualFrameStartTime = this._scene._animationTime;\r\n        if (this._usesVirtualSampling) {\r\n            this._retainedCurrentFrame = this._mapVirtualFrame(this._virtualFrame);\r\n            this._goToFrameWithMask(this._retainedCurrentFrame);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Restart animations from after pausing it\r\n     * @returns the animation group\r\n     */\r\n    public restart(): AnimationGroup {\r\n        if (!this._isStarted) {\r\n            return this;\r\n        }\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.restart();\r\n        }\r\n\r\n        this.syncWithMask();\r\n\r\n        this._virtualFrameStart = this._virtualFrame;\r\n        this._virtualFrameStartTime = this._scene._animationTime;\r\n        this._isPaused = false;\r\n\r\n        this.onAnimationGroupPlayObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Stop all animations\r\n     * @param skipOnAnimationEnd defines if the system should not raise onAnimationEnd. Default is false\r\n     * @returns the animation group\r\n     */\r\n    public stop(skipOnAnimationEnd = false): AnimationGroup {\r\n        if (!this._isStarted) {\r\n            return this;\r\n        }\r\n\r\n        if (this._animatables[0]) {\r\n            this._retainedCurrentFrame = this._animatables[0].masterFrame;\r\n        }\r\n        this._updateVirtualFrame();\r\n        this._removeVirtualSamplingObserver();\r\n        this._isStopping = true;\r\n        const list = this._animatables.slice();\r\n        for (let index = 0; index < list.length; index++) {\r\n            list[index].stop(undefined, undefined, true, skipOnAnimationEnd);\r\n        }\r\n\r\n        // We will take care of removing all stopped animatables\r\n        let curIndex = 0;\r\n        for (let index = 0; index < this._scene._activeAnimatables.length; index++) {\r\n            const animatable = this._scene._activeAnimatables[index];\r\n            if (animatable._runtimeAnimations.length > 0) {\r\n                this._scene._activeAnimatables[curIndex++] = animatable;\r\n            } else if (skipOnAnimationEnd) {\r\n                // We normally rely on the onAnimationEnd callback (assigned in the start function) to be notified when an animatable\r\n                // ends and should be removed from the active animatables array. However, if the animatable is stopped with the skipOnAnimationEnd\r\n                // flag set to true, then we need to explicitly remove it from the active animatables array.\r\n                this._checkAnimationGroupEnded(animatable, skipOnAnimationEnd);\r\n            }\r\n        }\r\n        this._scene._activeAnimatables.length = curIndex;\r\n\r\n        this._isStarted = false;\r\n        this._isStopping = false;\r\n        this._usesVirtualSampling = false;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set animation weight for all animatables\r\n     *\r\n     * @since 6.12.4\r\n     *  You can pass the weight to the AnimationGroup constructor, or use the weight property to set it after the group has been created,\r\n     *  making it easier to define the overall animation weight than calling setWeightForAllAnimatables() after the animation group has been started\r\n     * @param weight defines the weight to use\r\n     * @returns the animationGroup\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-weights\r\n     */\r\n    public setWeightForAllAnimatables(weight: number): AnimationGroup {\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.weight = weight;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Synchronize and normalize all animatables with a source animatable\r\n     * @param root defines the root animatable to synchronize with (null to stop synchronizing)\r\n     * @returns the animationGroup\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-weights\r\n     */\r\n    public syncAllAnimationsWith(root: Nullable<Animatable>): AnimationGroup {\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.syncWith(root);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Goes to a specific frame in this animation group. Note that the animation group must be in playing or paused status\r\n     * @param frame the frame number to go to\r\n     * @param useWeight defines whether the animation weight should be applied to the image to be jumped to (false by default)\r\n     * @returns the animationGroup\r\n     */\r\n    public goToFrame(frame: number, useWeight = false): AnimationGroup {\r\n        if (!this._isStarted) {\r\n            return this;\r\n        }\r\n\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            animatable.goToFrame(frame, useWeight);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Helper to get the current frame. This returns 0 when the AnimationGroup is\r\n     * not running and might be inaccurate when animations use different frames.\r\n     * @returns current animation frame.\r\n     */\r\n    public getCurrentFrame(): number {\r\n        return this.animatables[0]?.masterFrame || 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the last effective frame, retaining it after the group stops.\r\n     * @returns current or retained effective animation frame\r\n     */\r\n    public getRetainedCurrentFrame(): number {\r\n        if (this.animatables[0]) {\r\n            this._retainedCurrentFrame = this.animatables[0].masterFrame;\r\n        }\r\n        return this._retainedCurrentFrame;\r\n    }\r\n\r\n    /**\r\n     * Gets the current frame on the unbounded timeline requested by the caller.\r\n     * Unlike {@link getCurrentFrame}, this value is not clamped or wrapped by the\r\n     * animation's keyframe range and is retained after the group stops.\r\n     * @returns the current virtual animation frame\r\n     */\r\n    public getVirtualCurrentFrame(): number {\r\n        this._updateVirtualFrame();\r\n        return this._virtualFrame;\r\n    }\r\n\r\n    /**\r\n     * Returns whether the virtual timeline crossed the requested frame.\r\n     * @param frame virtual frame to test\r\n     * @returns true when the frame was reached in the playback direction\r\n     */\r\n    public isVirtualFrameReached(frame: number): boolean {\r\n        const current = this.getVirtualCurrentFrame();\r\n        return this._virtualFrameDirection > 0 ? current >= frame : current <= frame;\r\n    }\r\n\r\n    /**\r\n     * Returns whether a frame is inside the requested start/end interval.\r\n     * The end frame is excluded because natural completion takes precedence.\r\n     * @param frame virtual frame to test\r\n     * @returns true when a scheduled stop may occur at the frame\r\n     */\r\n    public isValidVirtualStopFrame(frame: number): boolean {\r\n        return this._virtualFrameDirection > 0\r\n            ? frame >= this._virtualFrameInitial && frame < this._virtualFrameEnd\r\n            : frame <= this._virtualFrameInitial && frame > this._virtualFrameEnd;\r\n    }\r\n\r\n    /**\r\n     * Snaps both retained playheads to an exact virtual timeline position.\r\n     * @param frame virtual frame to retain\r\n     */\r\n    public setVirtualCurrentFrame(frame: number): void {\r\n        this._virtualFrame = frame;\r\n        this._virtualFrameStart = frame;\r\n        this._virtualFrameStartTime = this._scene._animationTime;\r\n        this._retainedCurrentFrame = this._mapVirtualFrame(frame);\r\n        this._goToFrameWithMask(this._retainedCurrentFrame);\r\n    }\r\n\r\n    private _updateVirtualFrame(): void {\r\n        if (!this._isStarted || this._isPaused) {\r\n            return;\r\n        }\r\n        const elapsedSeconds = (this._scene._animationTime - this._virtualFrameStartTime) / 1000;\r\n        this._virtualFrame = this._virtualFrameStart + elapsedSeconds * this._virtualFrameRate * this._speedRatio * this._virtualFrameDirection;\r\n    }\r\n\r\n    private _sampleVirtualTimeline(): void {\r\n        this._updateVirtualFrame();\r\n        const reachedEnd =\r\n            !this._loopAnimation &&\r\n            Number.isFinite(this._virtualFrameEnd) &&\r\n            (this._virtualFrameDirection > 0 ? this._virtualFrame >= this._virtualFrameEnd : this._virtualFrame <= this._virtualFrameEnd);\r\n        if (reachedEnd) {\r\n            this.setVirtualCurrentFrame(this._virtualFrameEnd);\r\n            this._removeVirtualSamplingObserver();\r\n            this.stop();\r\n            return;\r\n        }\r\n\r\n        this._retainedCurrentFrame = this._mapVirtualFrame(this._virtualFrame);\r\n        this._goToFrameWithMask(this._retainedCurrentFrame);\r\n    }\r\n\r\n    private _goToFrameWithMask(frame: number): void {\r\n        for (let index = 0; index < this._animatables.length; index++) {\r\n            const animatable = this._animatables[index];\r\n            if (this._isTargetRetainedByMask(animatable.target)) {\r\n                animatable.goToFrame(frame);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _isTargetRetainedByMask(target: any): boolean {\r\n        return !this._mask || this._mask.disabled || this._mask.retainsTarget(target.name);\r\n    }\r\n\r\n    private _removeVirtualSamplingObserver(): void {\r\n        if (this._virtualSamplingObserver) {\r\n            this._scene.onAfterAnimationsObservable.remove(this._virtualSamplingObserver);\r\n            this._virtualSamplingObserver = null;\r\n        }\r\n    }\r\n\r\n    private _mapVirtualFrame(frame: number): number {\r\n        const maximum = this._to;\r\n        if (maximum === 0) {\r\n            return 0;\r\n        }\r\n        if (!Number.isFinite(frame) || !Number.isFinite(maximum) || maximum < 0) {\r\n            return frame;\r\n        }\r\n        const iteration = frame > 0 ? Math.ceil((frame - maximum) / maximum) : Math.floor(frame / maximum);\r\n        return frame - iteration * maximum;\r\n    }\r\n\r\n    /**\r\n     * Dispose all associated resources\r\n     */\r\n    public dispose(): void {\r\n        if (this.isStarted) {\r\n            this.stop();\r\n        }\r\n        this._targetedAnimations.length = 0;\r\n        this._animatables.length = 0;\r\n\r\n        // Remove from scene\r\n        this._scene.removeAnimationGroup(this);\r\n\r\n        if (this._parentContainer) {\r\n            const index = this._parentContainer.animationGroups.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.animationGroups.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        this.onAnimationEndObservable.clear();\r\n        this.onAnimationGroupEndObservable.clear();\r\n        this.onAnimationGroupPauseObservable.clear();\r\n        this.onAnimationGroupPlayObservable.clear();\r\n        this.onAnimationLoopObservable.clear();\r\n        this.onAnimationGroupLoopObservable.clear();\r\n    }\r\n\r\n    private _checkAnimationGroupEnded(animatable: Animatable, skipOnAnimationEnd = false) {\r\n        this._updateVirtualFrame();\r\n        if (!skipOnAnimationEnd && !this._isStopping) {\r\n            this._retainedCurrentFrame = animatable.masterFrame;\r\n        }\r\n        // animatable should be taken out of the array\r\n        const idx = this._animatables.indexOf(animatable);\r\n        if (idx > -1) {\r\n            this._animatables.splice(idx, 1);\r\n        }\r\n\r\n        // all animatables were removed? animation group ended!\r\n        if (this._animatables.length === this._targetedAnimations.length - this._numActiveAnimatables) {\r\n            if (!skipOnAnimationEnd && !this._isStopping && Number.isFinite(this._virtualFrameEnd)) {\r\n                this._virtualFrame = this._virtualFrameEnd;\r\n                this._retainedCurrentFrame = this._mapVirtualFrame(this._virtualFrameEnd);\r\n            }\r\n            this._isStarted = false;\r\n            if (!skipOnAnimationEnd) {\r\n                this.onAnimationGroupEndObservable.notifyObservers(this);\r\n            }\r\n            this._animatables.length = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the current animation group and returns a copy\r\n     * @param newName defines the name of the new group\r\n     * @param targetConverter defines an optional function used to convert current animation targets to new ones\r\n     * @param cloneAnimations defines if the animations should be cloned or referenced\r\n     * @param cloneAnimationKeys defines if the animation keys should be cloned when cloning animations (false by default). No effect if cloneAnimations is false\r\n     * @returns the new animation group\r\n     */\r\n    public clone(newName: string, targetConverter?: (oldTarget: any) => any, cloneAnimations = false, cloneAnimationKeys = false): AnimationGroup {\r\n        const newGroup = new AnimationGroup(newName || this.name, this._scene, this._weight, this._playOrder);\r\n\r\n        newGroup._from = this.from;\r\n        newGroup._to = this.to;\r\n        newGroup._speedRatio = this.speedRatio;\r\n        newGroup._loopAnimation = this.loopAnimation;\r\n        newGroup._isAdditive = this.isAdditive;\r\n        newGroup._enableBlending = this.enableBlending;\r\n        newGroup._blendingSpeed = this.blendingSpeed;\r\n        newGroup.metadata = this.metadata;\r\n        newGroup.mask = this.mask;\r\n\r\n        for (const targetAnimation of this._targetedAnimations) {\r\n            newGroup.addTargetedAnimation(\r\n                cloneAnimations ? targetAnimation.animation.clone(cloneAnimationKeys) : targetAnimation.animation,\r\n                targetConverter ? targetConverter(targetAnimation.target) : targetAnimation.target\r\n            );\r\n        }\r\n\r\n        return newGroup;\r\n    }\r\n\r\n    /**\r\n     * Serializes the animationGroup to an object\r\n     * @returns Serialized object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.from = this.from;\r\n        serializationObject.to = this.to;\r\n        serializationObject.speedRatio = this.speedRatio;\r\n        serializationObject.loopAnimation = this.loopAnimation;\r\n        serializationObject.isAdditive = this.isAdditive;\r\n        serializationObject.weight = this.weight;\r\n        serializationObject.playOrder = this.playOrder;\r\n        serializationObject.enableBlending = this.enableBlending;\r\n        serializationObject.blendingSpeed = this.blendingSpeed;\r\n\r\n        serializationObject.targetedAnimations = [];\r\n        for (let targetedAnimationIndex = 0; targetedAnimationIndex < this.targetedAnimations.length; targetedAnimationIndex++) {\r\n            const targetedAnimation = this.targetedAnimations[targetedAnimationIndex];\r\n            serializationObject.targetedAnimations[targetedAnimationIndex] = targetedAnimation.serialize();\r\n        }\r\n\r\n        if (Tags && Tags.HasTags(this)) {\r\n            serializationObject.tags = Tags.GetTags(this);\r\n        }\r\n\r\n        // Metadata\r\n        if (this.metadata) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"AnimationGroup\"\r\n     * @returns \"AnimationGroup\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"AnimationGroup\";\r\n    }\r\n\r\n    /**\r\n     * Creates a detailed string about the object\r\n     * @param fullDetails defines if the output string will support multiple levels of logging within scene loading\r\n     * @returns a string representing the object\r\n     */\r\n    public toString(fullDetails?: boolean): string {\r\n        let ret = \"Name: \" + this.name;\r\n        ret += \", type: \" + this.getClassName();\r\n        if (fullDetails) {\r\n            ret += \", from: \" + this._from;\r\n            ret += \", to: \" + this._to;\r\n            ret += \", isStarted: \" + this._isStarted;\r\n            ret += \", speedRatio: \" + this._speedRatio;\r\n            ret += \", targetedAnimations length: \" + this._targetedAnimations.length;\r\n            ret += \", animatables length: \" + this._animatables.length;\r\n        }\r\n        return ret;\r\n    }\r\n}\r\n\r\n/**\r\n * Merge the array of animation groups into a new animation group\r\n * @param animationGroups List of animation groups to merge\r\n * @param disposeSource If true, animation groups will be disposed after being merged (default: true)\r\n * @param normalize If true, animation groups will be normalized before being merged, so that all animations have the same \"from\" and \"to\" frame (default: false)\r\n * @param weight Weight for the new animation group. If not provided, it will inherit the weight from the first animation group of the array\r\n * @returns The new animation group or null if no animation groups were passed\r\n */\r\nexport function AnimationGroupMergeAnimationGroups(animationGroups: Array<AnimationGroup>, disposeSource = true, normalize = false, weight?: number): Nullable<AnimationGroup> {\r\n    if (animationGroups.length === 0) {\r\n        return null;\r\n    }\r\n\r\n    weight = weight ?? animationGroups[0].weight;\r\n\r\n    let beginFrame = Number.MAX_VALUE;\r\n    let endFrame = -Number.MAX_VALUE;\r\n\r\n    if (normalize) {\r\n        for (const animationGroup of animationGroups) {\r\n            if (animationGroup.from < beginFrame) {\r\n                beginFrame = animationGroup.from;\r\n            }\r\n\r\n            if (animationGroup.to > endFrame) {\r\n                endFrame = animationGroup.to;\r\n            }\r\n        }\r\n    }\r\n\r\n    const mergedAnimationGroup = new AnimationGroup(animationGroups[0].name + \"_merged\", animationGroups[0].getScene(), weight);\r\n\r\n    for (const animationGroup of animationGroups) {\r\n        if (normalize) {\r\n            animationGroup.normalize(beginFrame, endFrame);\r\n        }\r\n\r\n        for (const targetedAnimation of animationGroup.targetedAnimations) {\r\n            mergedAnimationGroup.addTargetedAnimation(targetedAnimation.animation, targetedAnimation.target);\r\n        }\r\n\r\n        if (disposeSource) {\r\n            animationGroup.dispose();\r\n        }\r\n    }\r\n\r\n    return mergedAnimationGroup;\r\n}\r\n\r\n/**\r\n * Returns a new AnimationGroup object parsed from the source provided.\r\n * @param parsedAnimationGroup defines the source\r\n * @param scene defines the scene that will receive the animationGroup\r\n * @param targetLookup a callback that will be used instead of the default lookup\r\n * @returns a new AnimationGroup\r\n */\r\nexport function AnimationGroupParse(parsedAnimationGroup: any, scene: Scene, targetLookup?: (parsedTargetAnimation: any) => any): AnimationGroup {\r\n    const animationGroup = new AnimationGroup(parsedAnimationGroup.name, scene, parsedAnimationGroup.weight, parsedAnimationGroup.playOrder);\r\n    const animationGroupInternal = animationGroup as any;\r\n    for (let i = 0; i < parsedAnimationGroup.targetedAnimations.length; i++) {\r\n        const targetedAnimation = parsedAnimationGroup.targetedAnimations[i];\r\n        const animation = AnimationParse(targetedAnimation.animation);\r\n\r\n        const target = targetLookup\r\n            ? targetLookup(targetedAnimation)\r\n            : targetedAnimation.animation.property === \"influence\"\r\n              ? scene.getMorphTargetById(targetedAnimation.targetId)\r\n              : scene.getNodeById(targetedAnimation.targetId);\r\n\r\n        if (target) {\r\n            animationGroup.addTargetedAnimation(animation, target);\r\n        }\r\n    }\r\n\r\n    if (Tags) {\r\n        Tags.AddTagsTo(animationGroup, parsedAnimationGroup.tags);\r\n    }\r\n\r\n    if (parsedAnimationGroup.from !== null && parsedAnimationGroup.to !== null) {\r\n        animationGroup.normalize(parsedAnimationGroup.from, parsedAnimationGroup.to);\r\n    }\r\n\r\n    if (parsedAnimationGroup.speedRatio !== undefined) {\r\n        animationGroupInternal._speedRatio = parsedAnimationGroup.speedRatio;\r\n    }\r\n    if (parsedAnimationGroup.loopAnimation !== undefined) {\r\n        animationGroupInternal._loopAnimation = parsedAnimationGroup.loopAnimation;\r\n    }\r\n\r\n    if (parsedAnimationGroup.isAdditive !== undefined) {\r\n        animationGroupInternal._isAdditive = parsedAnimationGroup.isAdditive;\r\n    }\r\n\r\n    if (parsedAnimationGroup.weight !== undefined) {\r\n        animationGroupInternal._weight = parsedAnimationGroup.weight;\r\n    }\r\n\r\n    if (parsedAnimationGroup.playOrder !== undefined) {\r\n        animationGroupInternal._playOrder = parsedAnimationGroup.playOrder;\r\n    }\r\n\r\n    if (parsedAnimationGroup.enableBlending !== undefined) {\r\n        animationGroupInternal._enableBlending = parsedAnimationGroup.enableBlending;\r\n    }\r\n\r\n    if (parsedAnimationGroup.blendingSpeed !== undefined) {\r\n        animationGroupInternal._blendingSpeed = parsedAnimationGroup.blendingSpeed;\r\n    }\r\n\r\n    if (parsedAnimationGroup.metadata !== undefined) {\r\n        animationGroup.metadata = parsedAnimationGroup.metadata;\r\n    }\r\n\r\n    return animationGroup;\r\n}\r\n\r\n/**\r\n * Convert the keyframes for all animations belonging to the group to be relative to a given reference frame.\r\n * @param sourceAnimationGroup defines the AnimationGroup containing animations to convert\r\n * @param referenceFrame defines the frame that keyframes in the range will be relative to (default: 0)\r\n * @param range defines the name of the AnimationRange belonging to the animations in the group to convert\r\n * @param cloneOriginal defines whether or not to clone the group and convert the clone or convert the original group (default is false)\r\n * @param clonedName defines the name of the resulting cloned AnimationGroup if cloneOriginal is true\r\n * @returns a new AnimationGroup if cloneOriginal is true or the original AnimationGroup if cloneOriginal is false\r\n */\r\nexport function AnimationGroupMakeAnimationAdditive(\r\n    sourceAnimationGroup: AnimationGroup,\r\n    referenceFrame: number,\r\n    range?: string,\r\n    cloneOriginal?: boolean,\r\n    clonedName?: string\r\n): AnimationGroup;\r\n\r\n/**\r\n * Convert the keyframes for all animations belonging to the group to be relative to a given reference frame.\r\n * @param sourceAnimationGroup defines the AnimationGroup containing animations to convert\r\n * @param options defines the options to use when converting keyframes\r\n * @returns a new AnimationGroup if options.cloneOriginalAnimationGroup is true or the original AnimationGroup if options.cloneOriginalAnimationGroup is false\r\n */\r\nexport function AnimationGroupMakeAnimationAdditive(sourceAnimationGroup: AnimationGroup, options?: IMakeAnimationGroupAdditiveOptions): AnimationGroup;\r\n\r\n/** @internal */\r\nexport function AnimationGroupMakeAnimationAdditive(\r\n    sourceAnimationGroup: AnimationGroup,\r\n    referenceFrameOrOptions?: number | IMakeAnimationGroupAdditiveOptions,\r\n    range?: string,\r\n    cloneOriginal = false,\r\n    clonedName?: string\r\n): AnimationGroup {\r\n    let options: IMakeAnimationGroupAdditiveOptions;\r\n\r\n    if (typeof referenceFrameOrOptions === \"object\") {\r\n        options = referenceFrameOrOptions;\r\n    } else {\r\n        options = {\r\n            referenceFrame: referenceFrameOrOptions,\r\n            range: range,\r\n            cloneOriginalAnimationGroup: cloneOriginal,\r\n            clonedAnimationName: clonedName,\r\n        };\r\n    }\r\n\r\n    let animationGroup = sourceAnimationGroup;\r\n    if (options.cloneOriginalAnimationGroup) {\r\n        animationGroup = sourceAnimationGroup.clone(options.clonedAnimationGroupName || animationGroup.name);\r\n    }\r\n\r\n    const targetedAnimations = animationGroup.targetedAnimations;\r\n    for (let index = 0; index < targetedAnimations.length; index++) {\r\n        const targetedAnimation = targetedAnimations[index];\r\n        targetedAnimation.animation = AnimationMakeAnimationAdditive(targetedAnimation.animation, options);\r\n    }\r\n\r\n    animationGroup.isAdditive = true;\r\n\r\n    if (options.clipKeys) {\r\n        // We need to recalculate the from/to frames for the animation group because some keys may have been removed\r\n        let from = Number.MAX_VALUE;\r\n        let to = -Number.MAX_VALUE;\r\n\r\n        const targetedAnimations = animationGroup.targetedAnimations;\r\n        for (let index = 0; index < targetedAnimations.length; index++) {\r\n            const targetedAnimation = targetedAnimations[index];\r\n            const animation = targetedAnimation.animation;\r\n            const keys = animation.getKeys();\r\n\r\n            if (from > keys[0].frame) {\r\n                from = keys[0].frame;\r\n            }\r\n\r\n            if (to < keys[keys.length - 1].frame) {\r\n                to = keys[keys.length - 1].frame;\r\n            }\r\n        }\r\n\r\n        const animationGroupInternal = animationGroup as any;\r\n        animationGroupInternal._from = from;\r\n        animationGroupInternal._to = to;\r\n    }\r\n\r\n    return animationGroup;\r\n}\r\n\r\n/**\r\n * Creates a new animation, keeping only the keys that are inside a given key range\r\n * @param sourceAnimationGroup defines the animation group on which to operate\r\n * @param fromKey defines the lower bound of the range\r\n * @param toKey defines the upper bound of the range\r\n * @param name defines the name of the new animation group. If not provided, use the same name as animationGroup\r\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\r\n * @returns a new animation group stripped from all the keys outside the given range\r\n */\r\nexport function AnimationGroupClipKeys(sourceAnimationGroup: AnimationGroup, fromKey: number, toKey: number, name?: string, dontCloneAnimations?: boolean): AnimationGroup {\r\n    const animationGroup = sourceAnimationGroup.clone(name || sourceAnimationGroup.name);\r\n\r\n    return AnimationGroupClipKeysInPlace(animationGroup, fromKey, toKey, dontCloneAnimations);\r\n}\r\n\r\n/**\r\n * Updates an existing animation, keeping only the keys that are inside a given key range\r\n * @param animationGroup defines the animation group on which to operate\r\n * @param fromKey defines the lower bound of the range\r\n * @param toKey defines the upper bound of the range\r\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\r\n * @returns the animationGroup stripped from all the keys outside the given range\r\n */\r\nexport function AnimationGroupClipKeysInPlace(animationGroup: AnimationGroup, fromKey: number, toKey: number, dontCloneAnimations?: boolean): AnimationGroup {\r\n    return AnimationGroupClipInPlace(animationGroup, fromKey, toKey, dontCloneAnimations, false);\r\n}\r\n\r\n/**\r\n * Creates a new animation, keeping only the frames that are inside a given frame range\r\n * @param sourceAnimationGroup defines the animation group on which to operate\r\n * @param fromFrame defines the lower bound of the range\r\n * @param toFrame defines the upper bound of the range\r\n * @param name defines the name of the new animation group. If not provided, use the same name as animationGroup\r\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the frames. Default is false, so animations will be cloned\r\n * @returns a new animation group stripped from all the frames outside the given range\r\n */\r\nexport function AnimationGroupClipFrames(sourceAnimationGroup: AnimationGroup, fromFrame: number, toFrame: number, name?: string, dontCloneAnimations?: boolean): AnimationGroup {\r\n    const animationGroup = sourceAnimationGroup.clone(name || sourceAnimationGroup.name);\r\n\r\n    return AnimationGroupClipFramesInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations);\r\n}\r\n\r\n/**\r\n * Updates an existing animation, keeping only the frames that are inside a given frame range\r\n * @param animationGroup defines the animation group on which to operate\r\n * @param fromFrame defines the lower bound of the range\r\n * @param toFrame defines the upper bound of the range\r\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the frames. Default is false, so animations will be cloned\r\n * @returns the animationGroup stripped from all the frames outside the given range\r\n */\r\nexport function AnimationGroupClipFramesInPlace(animationGroup: AnimationGroup, fromFrame: number, toFrame: number, dontCloneAnimations?: boolean): AnimationGroup {\r\n    return AnimationGroupClipInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations, true);\r\n}\r\n\r\n/**\r\n * Updates an existing animation, keeping only the keys that are inside a given key or frame range\r\n * @param animationGroup defines the animation group on which to operate\r\n * @param start defines the lower bound of the range\r\n * @param end defines the upper bound of the range\r\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\r\n * @param useFrame defines if the range is defined by frame numbers or key indices (default is false which means use key indices)\r\n * @returns the animationGroup stripped from all the keys outside the given range\r\n */\r\nexport function AnimationGroupClipInPlace(animationGroup: AnimationGroup, start: number, end: number, dontCloneAnimations?: boolean, useFrame = false): AnimationGroup {\r\n    let from = Number.MAX_VALUE;\r\n    let to = -Number.MAX_VALUE;\r\n\r\n    const targetedAnimations = animationGroup.targetedAnimations;\r\n    for (let index = 0; index < targetedAnimations.length; index++) {\r\n        const targetedAnimation = targetedAnimations[index];\r\n        const animation = dontCloneAnimations ? targetedAnimation.animation : targetedAnimation.animation.clone();\r\n\r\n        if (useFrame) {\r\n            // Make sure we have keys corresponding to the bounds of the frame range\r\n            animation.createKeyForFrame(start);\r\n            animation.createKeyForFrame(end);\r\n        }\r\n\r\n        const keys = animation.getKeys();\r\n        const newKeys: IAnimationKey[] = [];\r\n\r\n        let startFrame = Number.MAX_VALUE;\r\n        for (let k = 0; k < keys.length; k++) {\r\n            const key = keys[k];\r\n            if ((!useFrame && k >= start && k <= end) || (useFrame && key.frame >= start && key.frame <= end)) {\r\n                const newKey: IAnimationKey = {\r\n                    frame: key.frame,\r\n                    value: key.value.clone ? key.value.clone() : key.value,\r\n                    inTangent: key.inTangent,\r\n                    outTangent: key.outTangent,\r\n                    interpolation: key.interpolation,\r\n                    lockedTangent: key.lockedTangent,\r\n                };\r\n                if (startFrame === Number.MAX_VALUE) {\r\n                    startFrame = newKey.frame;\r\n                }\r\n                newKey.frame -= startFrame;\r\n                newKeys.push(newKey);\r\n            }\r\n        }\r\n\r\n        if (newKeys.length === 0) {\r\n            targetedAnimations.splice(index, 1);\r\n            index--;\r\n            continue;\r\n        }\r\n\r\n        if (from > newKeys[0].frame) {\r\n            from = newKeys[0].frame;\r\n        }\r\n\r\n        if (to < newKeys[newKeys.length - 1].frame) {\r\n            to = newKeys[newKeys.length - 1].frame;\r\n        }\r\n\r\n        animation.setKeys(newKeys, true);\r\n        targetedAnimation.animation = animation; // in case the animation has been cloned\r\n    }\r\n\r\n    const animationGroupInternal = animationGroup as any;\r\n    animationGroupInternal._from = from;\r\n    animationGroupInternal._to = to;\r\n\r\n    return animationGroup;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for AnimationGroup.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnimationGroup(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AnimationGroup.MergeAnimationGroups = AnimationGroupMergeAnimationGroups;\r\n    AnimationGroup.Parse = AnimationGroupParse;\r\n    AnimationGroup.MakeAnimationAdditive = AnimationGroupMakeAnimationAdditive;\r\n    AnimationGroup.ClipKeys = AnimationGroupClipKeys;\r\n    AnimationGroup.ClipKeysInPlace = AnimationGroupClipKeysInPlace;\r\n    AnimationGroup.ClipFrames = AnimationGroupClipFrames;\r\n    AnimationGroup.ClipFramesInPlace = AnimationGroupClipFramesInPlace;\r\n    AnimationGroup.ClipInPlace = AnimationGroupClipInPlace;\r\n}\r\n","import { type IEasingFunction } from \"./easing\";\r\n\r\n/**\r\n * Defines an interface which represents an animation key frame\r\n */\r\nexport interface IAnimationKey {\r\n    /**\r\n     * Frame of the key frame\r\n     */\r\n    frame: number;\r\n    /**\r\n     * Value at the specifies key frame\r\n     */\r\n    value: any;\r\n    /**\r\n     * The input tangent for the cubic hermite spline\r\n     */\r\n    inTangent?: any;\r\n    /**\r\n     * The output tangent for the cubic hermite spline\r\n     */\r\n    outTangent?: any;\r\n    /**\r\n     * The animation interpolation type\r\n     */\r\n    interpolation?: AnimationKeyInterpolation;\r\n    /**\r\n     * Property defined by UI tools to link (or not ) the tangents\r\n     */\r\n    lockedTangent?: boolean;\r\n    /**\r\n     * The easing function associated with the key frame (optional). If not defined, the easing function defined at the animation level (if any) will be used instead\r\n     */\r\n    easingFunction?: IEasingFunction;\r\n}\r\n\r\n/**\r\n * Enum for the animation key frame interpolation type\r\n */\r\nexport const enum AnimationKeyInterpolation {\r\n    /**\r\n     * Use tangents to interpolate between start and end values.\r\n     */\r\n    NONE = 0,\r\n    /**\r\n     * Do not interpolate between keys and use the start key value only. Tangents are ignored\r\n     */\r\n    STEP = 1,\r\n}\r\n","/**\r\n * Enum used to define the mode for an animation group mask\r\n */\r\nexport const enum AnimationGroupMaskMode {\r\n    /**\r\n     * The mask defines the animatable target names that should be included\r\n     */\r\n    Include = 0,\r\n    /**\r\n     * The mask defines the animatable target names in a \"exclude\" mode: all animatable targets will be animated except the ones defined in the mask\r\n     */\r\n    Exclude = 1,\r\n}\r\n\r\n/**\r\n * Defines a mask used to filter animation targets.\r\n * If you apply a mask to an animation group (see the AnimationGroup.mask property), only the animations whose target names match the mask will play.\r\n * Note that a target is defined by its name (string). This means that the same mask can be used for several animation groups, provided that their targets are named in the same way.\r\n */\r\nexport class AnimationGroupMask {\r\n    /**\r\n     * The set of target names included in the mask. If mode is AnimationGroupMaskMode.Exclude, the targets in this set will be excluded from the mask instead.\r\n     */\r\n    private _targetNames: Set<string>;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mask is disabled (default is false)\r\n     */\r\n    public disabled = false;\r\n\r\n    /**\r\n     * Creates a new mask\r\n     * @param names The list of target names to add to the mask (optional)\r\n     * @param mode Defines the mode for the mask (default: AnimationGroupMaskMode.Include)\r\n     */\r\n    constructor(\r\n        names?: string[],\r\n        /**\r\n         * [0] Defines the mode for the mask\r\n         */\r\n        public mode: AnimationGroupMaskMode = AnimationGroupMaskMode.Include\r\n    ) {\r\n        this._targetNames = new Set<string>();\r\n        if (names) {\r\n            this.addTargetName(names);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds one or several target names to the mask\r\n     * @param name The name(s) to add to the mask\r\n     */\r\n    public addTargetName(name: string | string[]): void {\r\n        if (Array.isArray(name)) {\r\n            for (const n of name) {\r\n                this._targetNames.add(n);\r\n            }\r\n            return;\r\n        }\r\n\r\n        this._targetNames.add(name);\r\n    }\r\n\r\n    /**\r\n     * Removes one or several target names from the mask\r\n     * @param name The name(s) to remove from the mask\r\n     */\r\n    public removeTargetName(name: string | string[]): void {\r\n        if (Array.isArray(name)) {\r\n            for (const n of name) {\r\n                this._targetNames.delete(n);\r\n            }\r\n            return;\r\n        }\r\n\r\n        this._targetNames.delete(name);\r\n    }\r\n\r\n    /**\r\n     * Checks if the mask includes a target name.\r\n     * This method is intended to know if a given target name is included in the mask, not if the name is actually retained by the mask (see retainsTarget() instead).\r\n     * @param name The name to check with the mask\r\n     * @returns True if the mask includes the name, false otherwise\r\n     */\r\n    public hasTarget(name: string): boolean {\r\n        return this._targetNames.has(name);\r\n    }\r\n\r\n    /**\r\n     * Checks if the mask retains a target name.\r\n     * Note that in the \"Exclude\" mode, this will return false if the mask includes the name, and true otherwise!\r\n     * This method is intended to know if a given target name is retained by the mask, not if the name is in the list of target names.\r\n     * @param name The name to check with the mask\r\n     * @returns True if the mask retains the name, false otherwise\r\n     */\r\n    public retainsTarget(name: string): boolean {\r\n        return this._targetNames.has(name) === (this.mode === AnimationGroupMaskMode.Include);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type DeepImmutable, type Nullable } from \"../types\";\nimport { serialize, serializeAsVector3, serializeAsQuaternion } from \"../Misc/decorators\";\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\nimport { Observable } from \"../Misc/observable.pure\";\n\nimport { type Camera } from \"../Cameras/camera.pure\";\nimport { type Scene } from \"../scene.pure\";\nimport { Quaternion, Matrix, Vector3, TmpVectors } from \"../Maths/math.vector.pure\";\nimport { Node } from \"../node\";\nimport { type Bone } from \"../Bones/bone.pure\";\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\nimport { Space } from \"../Maths/math.axis\";\nimport { GetClass } from \"../Misc/typeStore\";\n\n/**\n * A TransformNode is an object that is not rendered but can be used as a center of transformation. This can decrease memory usage and increase rendering speed compared to using an empty mesh as a parent and is less complicated than using a pivot matrix.\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/parent_pivot/transform_node\n */\nexport class TransformNode extends Node {\n    // Statics\n    /**\n     * Object will not rotate to face the camera\n     */\n    public static BILLBOARDMODE_NONE = 0;\n    /**\n     * Object will rotate to face the camera but only on the x axis\n     */\n    public static BILLBOARDMODE_X = 1;\n    /**\n     * Object will rotate to face the camera but only on the y axis\n     */\n    public static BILLBOARDMODE_Y = 2;\n    /**\n     * Object will rotate to face the camera but only on the z axis\n     */\n    public static BILLBOARDMODE_Z = 4;\n    /**\n     * Object will rotate to face the camera\n     */\n    public static BILLBOARDMODE_ALL = 7;\n    /**\n     * Object will rotate to face the camera's position instead of orientation\n     */\n    public static BILLBOARDMODE_USE_POSITION = 128;\n    /**\n     * Child transform with Billboard flags should or should not apply parent rotation (default if off)\n     */\n    public static BillboardUseParentOrientation: boolean = false;\n\n    private static _TmpRotation = /*#__PURE__*/ Quaternion.Zero();\n    private static _TmpScaling = /*#__PURE__*/ Vector3.Zero();\n    private static _TmpTranslation = /*#__PURE__*/ Vector3.Zero();\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    private static _TmpRHRestore = /*#__PURE__*/ Matrix.Scaling(1, 1, -1);\n\n    private _forward = new Vector3(0, 0, 1);\n    private _up = new Vector3(0, 1, 0);\n    private _right = new Vector3(1, 0, 0);\n\n    // Properties\n    @serializeAsVector3(\"position\")\n    private _position = Vector3.Zero();\n\n    @serializeAsVector3(\"rotation\")\n    private _rotation = Vector3.Zero();\n\n    @serializeAsQuaternion(\"rotationQuaternion\")\n    private _rotationQuaternion: Nullable<Quaternion> = null;\n\n    @serializeAsVector3(\"scaling\")\n    protected _scaling = Vector3.One();\n    private _transformToBoneReferal: Nullable<TransformNode> = null;\n    private _currentParentWhenAttachingToBone: Nullable<Node>;\n    private _isAbsoluteSynced = false;\n\n    @serialize(\"billboardMode\")\n    private _billboardMode = TransformNode.BILLBOARDMODE_NONE;\n\n    /**\n     * Gets or sets the billboard mode. Default is 0.\n     *\n     * | Value | Type | Description |\n     * | --- | --- | --- |\n     * | 0 | BILLBOARDMODE_NONE |  |\n     * | 1 | BILLBOARDMODE_X |  |\n     * | 2 | BILLBOARDMODE_Y |  |\n     * | 4 | BILLBOARDMODE_Z |  |\n     * | 7 | BILLBOARDMODE_ALL |  |\n     *\n     */\n    public get billboardMode() {\n        return this._billboardMode;\n    }\n\n    public set billboardMode(value: number) {\n        if (this._billboardMode === value) {\n            return;\n        }\n        this._billboardMode = value;\n        this._cache.useBillboardPosition = (this._billboardMode & TransformNode.BILLBOARDMODE_USE_POSITION) !== 0;\n    }\n\n    /**\n     * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube\n     */\n    @serialize()\n    public scalingDeterminant = 1;\n\n    @serialize(\"infiniteDistance\")\n    private _infiniteDistance = false;\n\n    /**\n     * Gets or sets the distance of the object to max, often used by skybox\n     */\n    public get infiniteDistance() {\n        return this._infiniteDistance;\n    }\n\n    public set infiniteDistance(value: boolean) {\n        if (this._infiniteDistance === value) {\n            return;\n        }\n\n        this._infiniteDistance = value;\n    }\n\n    /**\n     * Gets or sets a boolean indicating that non uniform scaling (when at least one component is different from others) should be ignored.\n     * By default the system will update normals to compensate\n     */\n    @serialize()\n    public ignoreNonUniformScaling = false;\n\n    /**\n     * Gets or sets a boolean indicating that even if rotationQuaternion is defined, you can keep updating rotation property and Babylon.js will just mix both\n     */\n    @serialize()\n    public reIntegrateRotationIntoRotationQuaternion = false;\n\n    // Cache\n    /** @internal */\n    public _poseMatrix: Nullable<Matrix> = null;\n    /** @internal */\n    public _localMatrix = Matrix.Zero();\n\n    private _usePivotMatrix = false;\n    private _absolutePosition = Vector3.Zero();\n    private _absoluteScaling = Vector3.Zero();\n    private _absoluteRotationQuaternion = Quaternion.Identity();\n    private _pivotMatrix = Matrix.Identity();\n    private _pivotMatrixInverse: Matrix;\n    /** @internal */\n    public _postMultiplyPivotMatrix = false;\n\n    protected _isWorldMatrixFrozen = false;\n\n    /**\n     * @internal\n     * Set by .babylon parsers to defer freezeWorldMatrix() until parent links are resolved.\n     * Declared (not initialized) to avoid pushing every TransformNode/Mesh instance into V8 dictionary mode.\n     */\n    declare public _waitingFreezeWorldMatrix?: Nullable<boolean>;\n\n    /** @internal */\n    public _indexInSceneTransformNodesArray = -1;\n\n    /**\n     * An event triggered after the world matrix is updated\n     */\n    public onAfterWorldMatrixUpdateObservable = new Observable<TransformNode>();\n\n    /** @internal */\n    constructor(name: string, scene: Nullable<Scene> = null, isPure = true) {\n        super(name, scene, false);\n\n        if (isPure) {\n            this.getScene().addTransformNode(this);\n        }\n    }\n\n    /**\n     * Gets a string identifying the name of the class\n     * @returns \"TransformNode\" string\n     */\n    public override getClassName(): string {\n        return \"TransformNode\";\n    }\n\n    /**\n     * Gets or set the node position (default is (0.0, 0.0, 0.0))\n     */\n    public get position(): Vector3 {\n        return this._position;\n    }\n\n    public set position(newPosition: Vector3) {\n        this._position = newPosition;\n        this._markAsDirtyInternal();\n    }\n\n    /**\n     * return true if a pivot has been set\n     * @returns true if a pivot matrix is used\n     */\n    public isUsingPivotMatrix(): boolean {\n        return this._usePivotMatrix;\n    }\n\n    /**\n     * @returns true if pivot matrix must be cancelled in the world matrix. When this parameter is set to true (default), the inverse of the pivot matrix is also applied at the end to cancel the transformation effect.\n     */\n    public isUsingPostMultiplyPivotMatrix(): boolean {\n        return this._postMultiplyPivotMatrix;\n    }\n\n    /**\n     * Gets or sets the rotation property : a Vector3 defining the rotation value in radians around each local axis X, Y, Z  (default is (0.0, 0.0, 0.0)).\n     * If rotation quaternion is set, this Vector3 will be ignored and copy from the quaternion\n     */\n    public get rotation(): Vector3 {\n        return this._rotation;\n    }\n\n    public set rotation(newRotation: Vector3) {\n        this._rotation = newRotation;\n        this._rotationQuaternion = null;\n        this._markAsDirtyInternal();\n    }\n\n    /**\n     * Gets or sets the scaling property : a Vector3 defining the node scaling along each local axis X, Y, Z (default is (1.0, 1.0, 1.0)).\n     */\n    public get scaling(): Vector3 {\n        return this._scaling;\n    }\n\n    public set scaling(newScaling: Vector3) {\n        this._scaling = newScaling;\n        this._markAsDirtyInternal();\n    }\n\n    /**\n     * Gets or sets the rotation Quaternion property : this a Quaternion object defining the node rotation by using a unit quaternion (undefined by default, but can be null).\n     * If set, only the rotationQuaternion is then used to compute the node rotation (ie. node.rotation will be ignored)\n     */\n    public get rotationQuaternion(): Nullable<Quaternion> {\n        return this._rotationQuaternion;\n    }\n\n    public set rotationQuaternion(quaternion: Nullable<Quaternion>) {\n        this._rotationQuaternion = quaternion;\n        //reset the rotation vector.\n        if (quaternion) {\n            this._rotation.setAll(0.0);\n        }\n        this._markAsDirtyInternal();\n    }\n\n    /**\n     * Allow user to specify custom mechanism for mark as dirty\n     */\n    public customMarkAsDirty: () => void;\n\n    private _markAsDirtyInternal(): void {\n        if (this._isDirty) {\n            return;\n        }\n        this._isDirty = true;\n\n        if (this.customMarkAsDirty) {\n            this.customMarkAsDirty();\n        }\n    }\n\n    /**\n     * The forward direction of that transform in world space.\n     */\n    public get forward(): Vector3 {\n        Vector3.TransformNormalFromFloatsToRef(0, 0, this.getScene().useRightHandedSystem ? -1.0 : 1.0, this.getWorldMatrix(), this._forward);\n        return this._forward.normalize();\n    }\n\n    /**\n     * The up direction of that transform in world space.\n     */\n    public get up(): Vector3 {\n        Vector3.TransformNormalFromFloatsToRef(0, 1, 0, this.getWorldMatrix(), this._up);\n        return this._up.normalize();\n    }\n\n    /**\n     * The right direction of that transform in world space.\n     */\n    public get right(): Vector3 {\n        Vector3.TransformNormalFromFloatsToRef(this.getScene().useRightHandedSystem ? -1.0 : 1.0, 0, 0, this.getWorldMatrix(), this._right);\n        return this._right.normalize();\n    }\n\n    /**\n     * Copies the parameter passed Matrix into the mesh Pose matrix.\n     * @param matrix the matrix to copy the pose from\n     * @returns this TransformNode.\n     */\n    public updatePoseMatrix(matrix: Matrix): TransformNode {\n        if (!this._poseMatrix) {\n            this._poseMatrix = matrix.clone();\n            return this;\n        }\n        this._poseMatrix.copyFrom(matrix);\n        return this;\n    }\n\n    /**\n     * Returns the mesh Pose matrix.\n     * @returns the pose matrix\n     */\n    public getPoseMatrix(): Matrix {\n        if (!this._poseMatrix) {\n            this._poseMatrix = Matrix.Identity();\n        }\n        return this._poseMatrix;\n    }\n\n    /** @internal */\n    public override _isSynchronized(): boolean {\n        const cache = this._cache;\n\n        if (this._billboardMode !== cache.billboardMode || this._billboardMode !== TransformNode.BILLBOARDMODE_NONE) {\n            return false;\n        }\n\n        if (cache.pivotMatrixUpdated) {\n            return false;\n        }\n\n        if (this._infiniteDistance) {\n            return false;\n        }\n\n        if (this._position._isDirty) {\n            return false;\n        }\n\n        if (this._scaling._isDirty) {\n            return false;\n        }\n\n        if ((this._rotationQuaternion && this._rotationQuaternion._isDirty) || this._rotation._isDirty) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /** @internal */\n    public override _initCache() {\n        super._initCache();\n\n        const cache = this._cache;\n        cache.localMatrixUpdated = false;\n        cache.billboardMode = -1;\n        cache.infiniteDistance = false;\n        cache.useBillboardPosition = false;\n    }\n\n    /**\n     * Returns the current mesh absolute position.\n     * Returns a Vector3.\n     */\n    public get absolutePosition(): Vector3 {\n        return this.getAbsolutePosition();\n    }\n\n    /**\n     * Returns the current mesh absolute scaling.\n     * Returns a Vector3.\n     */\n    public get absoluteScaling(): Vector3 {\n        this._syncAbsoluteScalingAndRotation();\n        return this._absoluteScaling;\n    }\n\n    /**\n     * Returns the current mesh absolute rotation.\n     * Returns a Quaternion.\n     */\n    public get absoluteRotationQuaternion(): Quaternion {\n        this._syncAbsoluteScalingAndRotation();\n        return this._absoluteRotationQuaternion;\n    }\n\n    /**\n     * Sets a new matrix to apply before all other transformation\n     * @param matrix defines the transform matrix\n     * @returns the current TransformNode\n     */\n    public setPreTransformMatrix(matrix: Matrix): TransformNode {\n        return this.setPivotMatrix(matrix, false);\n    }\n\n    /**\n     * Sets a new pivot matrix to the current node\n     * @param matrix defines the new pivot matrix to use\n     * @param postMultiplyPivotMatrix defines if the pivot matrix must be cancelled in the world matrix. When this parameter is set to true (default), the inverse of the pivot matrix is also applied at the end to cancel the transformation effect\n     * @returns the current TransformNode\n     */\n    public setPivotMatrix(matrix: DeepImmutable<Matrix>, postMultiplyPivotMatrix = true): TransformNode {\n        this._pivotMatrix.copyFrom(matrix);\n        this._usePivotMatrix = !this._pivotMatrix.isIdentity();\n\n        this._cache.pivotMatrixUpdated = true;\n        this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;\n\n        if (this._postMultiplyPivotMatrix) {\n            if (!this._pivotMatrixInverse) {\n                this._pivotMatrixInverse = Matrix.Invert(this._pivotMatrix);\n            } else {\n                this._pivotMatrix.invertToRef(this._pivotMatrixInverse);\n            }\n        }\n\n        return this;\n    }\n\n    /**\n     * Returns the mesh pivot matrix.\n     * Default : Identity.\n     * @returns the matrix\n     */\n    public getPivotMatrix(): Matrix {\n        return this._pivotMatrix;\n    }\n\n    /**\n     * Instantiate (when possible) or clone that node with its hierarchy\n     * @param newParent defines the new parent to use for the instance (or clone)\n     * @param options defines options to configure how copy is done\n     * @param onNewNodeCreated defines an option callback to call when a clone or an instance is created\n     * @returns an instance (or a clone) of the current node with its hierarchy\n     */\n    public instantiateHierarchy(\n        newParent: Nullable<TransformNode> = null,\n        options?: {\n            doNotInstantiate: boolean | ((node: TransformNode) => boolean);\n        },\n        onNewNodeCreated?: (source: TransformNode, clone: TransformNode) => void\n    ): Nullable<TransformNode> {\n        const clone = this.clone(\"Clone of \" + (this.name || this.id), newParent || this.parent, true);\n\n        if (clone) {\n            if (onNewNodeCreated) {\n                onNewNodeCreated(this, clone);\n            }\n        }\n\n        for (const child of this.getChildTransformNodes(true)) {\n            child.instantiateHierarchy(clone, options, onNewNodeCreated);\n        }\n\n        return clone;\n    }\n\n    /**\n     * Prevents the World matrix to be computed any longer.\n     * Please note that the \"moral\" contract is that the world matrix is not going to be updated anymore. It is up to the developer to force updates.\n     * You trade flexibility for performance. If you want to update it, you have to unfreeze it first.\n     * @param newWorldMatrix defines an optional matrix to use as world matrix\n     * @param decompose defines whether to decompose the given newWorldMatrix or directly assign\n     * @returns the TransformNode.\n     */\n    public freezeWorldMatrix(newWorldMatrix: Nullable<Matrix> = null, decompose = false): TransformNode {\n        if (newWorldMatrix) {\n            if (decompose) {\n                this._rotation.setAll(0);\n                this._rotationQuaternion = this._rotationQuaternion || Quaternion.Identity();\n                newWorldMatrix.decompose(this._scaling, this._rotationQuaternion, this._position);\n                this.computeWorldMatrix(true);\n            } else {\n                this._worldMatrix = newWorldMatrix;\n                this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);\n                this._afterComputeWorldMatrix();\n            }\n        } else {\n            this._isWorldMatrixFrozen = false; // no guarantee world is not already frozen, switch off temporarily\n            this.computeWorldMatrix(true);\n        }\n        this._isDirty = false;\n        this._isWorldMatrixFrozen = true;\n        return this;\n    }\n\n    /**\n     * Allows back the World matrix computation.\n     * @returns the TransformNode.\n     */\n    public unfreezeWorldMatrix() {\n        this._isWorldMatrixFrozen = false;\n        this.computeWorldMatrix(true);\n        return this;\n    }\n\n    /**\n     * True if the World matrix has been frozen.\n     */\n    public get isWorldMatrixFrozen(): boolean {\n        return this._isWorldMatrixFrozen;\n    }\n\n    /**\n     * Returns the mesh absolute position in the World.\n     * @returns a Vector3.\n     */\n    public getAbsolutePosition(): Vector3 {\n        this.computeWorldMatrix();\n        return this._absolutePosition;\n    }\n\n    /**\n     * Sets the mesh absolute position in the World from a Vector3 or an Array(3).\n     * @param absolutePosition the absolute position to set\n     * @returns the TransformNode.\n     */\n    public setAbsolutePosition(absolutePosition: Vector3): TransformNode {\n        if (!absolutePosition) {\n            return this;\n        }\n        let absolutePositionX;\n        let absolutePositionY;\n        let absolutePositionZ;\n        if (absolutePosition.x === undefined) {\n            if (arguments.length < 3) {\n                return this;\n            }\n            absolutePositionX = arguments[0];\n            absolutePositionY = arguments[1];\n            absolutePositionZ = arguments[2];\n        } else {\n            absolutePositionX = absolutePosition.x;\n            absolutePositionY = absolutePosition.y;\n            absolutePositionZ = absolutePosition.z;\n        }\n        if (this.parent) {\n            const invertParentWorldMatrix = TmpVectors.Matrix[0];\n            this.parent.getWorldMatrix().invertToRef(invertParentWorldMatrix);\n            Vector3.TransformCoordinatesFromFloatsToRef(absolutePositionX, absolutePositionY, absolutePositionZ, invertParentWorldMatrix, this.position);\n        } else {\n            this.position.x = absolutePositionX;\n            this.position.y = absolutePositionY;\n            this.position.z = absolutePositionZ;\n        }\n\n        this._absolutePosition.copyFrom(absolutePosition);\n        return this;\n    }\n\n    /**\n     * Sets the mesh position in its local space.\n     * @param vector3 the position to set in localspace\n     * @returns the TransformNode.\n     */\n    public setPositionWithLocalVector(vector3: Vector3): TransformNode {\n        this.computeWorldMatrix();\n        this.position = Vector3.TransformNormal(vector3, this._localMatrix);\n        return this;\n    }\n\n    /**\n     * Returns the mesh position in the local space from the current World matrix values.\n     * @returns a new Vector3.\n     */\n    public getPositionExpressedInLocalSpace(): Vector3 {\n        this.computeWorldMatrix();\n        const invLocalWorldMatrix = TmpVectors.Matrix[0];\n        this._localMatrix.invertToRef(invLocalWorldMatrix);\n        return Vector3.TransformNormal(this.position, invLocalWorldMatrix);\n    }\n\n    /**\n     * Translates the mesh along the passed Vector3 in its local space.\n     * @param vector3 the distance to translate in localspace\n     * @returns the TransformNode.\n     */\n    public locallyTranslate(vector3: Vector3): TransformNode {\n        this.computeWorldMatrix(true);\n        this.position = Vector3.TransformCoordinates(vector3, this._localMatrix);\n        return this;\n    }\n\n    private static _LookAtVectorCache = /*#__PURE__*/ new Vector3(0, 0, 0);\n\n    /**\n     * Orients a mesh towards a target point. Mesh must be drawn facing user.\n     * @param targetPoint the position (must be in same space as current mesh) to look at\n     * @param yawCor optional yaw (y-axis) correction in radians\n     * @param pitchCor optional pitch (x-axis) correction in radians\n     * @param rollCor optional roll (z-axis) correction in radians\n     * @param space the chosen space of the target\n     * @returns the TransformNode.\n     */\n    public lookAt(targetPoint: Vector3, yawCor: number = 0, pitchCor: number = 0, rollCor: number = 0, space: Space = Space.LOCAL): TransformNode {\n        const dv = TransformNode._LookAtVectorCache;\n        const pos = space === Space.LOCAL ? this.position : this.getAbsolutePosition();\n        targetPoint.subtractToRef(pos, dv);\n        this.setDirection(dv, yawCor, pitchCor, rollCor);\n\n        // Correct for parent's rotation offset\n        if (space === Space.WORLD && this.parent) {\n            if (this.rotationQuaternion) {\n                // Get local rotation matrix of the looking object\n                const rotationMatrix = TmpVectors.Matrix[0];\n                this.rotationQuaternion.toRotationMatrix(rotationMatrix);\n\n                // Offset rotation by parent's inverted rotation matrix to correct in world space\n                const parentRotationMatrix = TmpVectors.Matrix[1];\n                this.parent.getWorldMatrix().getRotationMatrixToRef(parentRotationMatrix);\n                parentRotationMatrix.invert();\n                rotationMatrix.multiplyToRef(parentRotationMatrix, rotationMatrix);\n                this.rotationQuaternion.fromRotationMatrix(rotationMatrix);\n            } else {\n                // Get local rotation matrix of the looking object\n                const quaternionRotation = TmpVectors.Quaternion[0];\n                Quaternion.FromEulerVectorToRef(this.rotation, quaternionRotation);\n                const rotationMatrix = TmpVectors.Matrix[0];\n                quaternionRotation.toRotationMatrix(rotationMatrix);\n\n                // Offset rotation by parent's inverted rotation matrix to correct in world space\n                const parentRotationMatrix = TmpVectors.Matrix[1];\n                this.parent.getWorldMatrix().getRotationMatrixToRef(parentRotationMatrix);\n                parentRotationMatrix.invert();\n                rotationMatrix.multiplyToRef(parentRotationMatrix, rotationMatrix);\n                quaternionRotation.fromRotationMatrix(rotationMatrix);\n                quaternionRotation.toEulerAnglesToRef(this.rotation);\n            }\n        }\n\n        return this;\n    }\n\n    /**\n     * Returns a new Vector3 that is the localAxis, expressed in the mesh local space, rotated like the mesh.\n     * This Vector3 is expressed in the World space.\n     * @param localAxis axis to rotate\n     * @returns a new Vector3 that is the localAxis, expressed in the mesh local space, rotated like the mesh.\n     */\n    public getDirection(localAxis: Vector3): Vector3 {\n        const result = Vector3.Zero();\n\n        this.getDirectionToRef(localAxis, result);\n\n        return result;\n    }\n\n    /**\n     * Sets the Vector3 \"result\" as the rotated Vector3 \"localAxis\" in the same rotation than the mesh.\n     * localAxis is expressed in the mesh local space.\n     * result is computed in the World space from the mesh World matrix.\n     * @param localAxis axis to rotate\n     * @param result the resulting transformnode\n     * @returns this TransformNode.\n     */\n    public getDirectionToRef(localAxis: Vector3, result: Vector3): TransformNode {\n        Vector3.TransformNormalToRef(localAxis, this.getWorldMatrix(), result);\n        return this;\n    }\n\n    /**\n     * Sets this transform node rotation to the given local axis.\n     * @param localAxis the axis in local space\n     * @param yawCor optional yaw (y-axis) correction in radians\n     * @param pitchCor optional pitch (x-axis) correction in radians\n     * @param rollCor optional roll (z-axis) correction in radians\n     * @returns this TransformNode\n     */\n    public setDirection(localAxis: Vector3, yawCor: number = 0, pitchCor: number = 0, rollCor: number = 0): TransformNode {\n        const yaw = -Math.atan2(localAxis.z, localAxis.x) + Math.PI / 2;\n        const len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);\n        const pitch = -Math.atan2(localAxis.y, len);\n        if (this.rotationQuaternion) {\n            Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);\n        } else {\n            this.rotation.x = pitch + pitchCor;\n            this.rotation.y = yaw + yawCor;\n            this.rotation.z = rollCor;\n        }\n        return this;\n    }\n\n    /**\n     * Sets a new pivot point to the current node\n     * @param point defines the new pivot point to use\n     * @param space defines if the point is in world or local space (local by default)\n     * @returns the current TransformNode\n     */\n    public setPivotPoint(point: Vector3, space: Space = Space.LOCAL): TransformNode {\n        if (this.getScene().getRenderId() == 0) {\n            this.computeWorldMatrix(true);\n        }\n\n        const wm = this.getWorldMatrix();\n\n        if (space == Space.WORLD) {\n            const tmat = TmpVectors.Matrix[0];\n            wm.invertToRef(tmat);\n            point = Vector3.TransformCoordinates(point, tmat);\n        }\n\n        return this.setPivotMatrix(Matrix.Translation(-point.x, -point.y, -point.z), true);\n    }\n\n    /**\n     * Returns a new Vector3 set with the mesh pivot point coordinates in the local space.\n     * @returns the pivot point\n     */\n    public getPivotPoint(): Vector3 {\n        const point = Vector3.Zero();\n        this.getPivotPointToRef(point);\n        return point;\n    }\n\n    /**\n     * Sets the passed Vector3 \"result\" with the coordinates of the mesh pivot point in the local space.\n     * @param result the vector3 to store the result\n     * @returns this TransformNode.\n     */\n    public getPivotPointToRef(result: Vector3): TransformNode {\n        result.x = -this._pivotMatrix.m[12];\n        result.y = -this._pivotMatrix.m[13];\n        result.z = -this._pivotMatrix.m[14];\n        return this;\n    }\n\n    /**\n     * Returns a new Vector3 set with the mesh pivot point World coordinates.\n     * @returns a new Vector3 set with the mesh pivot point World coordinates.\n     */\n    public getAbsolutePivotPoint(): Vector3 {\n        const point = Vector3.Zero();\n        this.getAbsolutePivotPointToRef(point);\n        return point;\n    }\n\n    /**\n     * Sets the Vector3 \"result\" coordinates with the mesh pivot point World coordinates.\n     * @param result vector3 to store the result\n     * @returns this TransformNode.\n     */\n    public getAbsolutePivotPointToRef(result: Vector3): TransformNode {\n        this.getPivotPointToRef(result);\n        Vector3.TransformCoordinatesToRef(result, this.getWorldMatrix(), result);\n        return this;\n    }\n\n    /**\n     * Flag the transform node as dirty (Forcing it to update everything)\n     * @param property if set to \"rotation\" the objects rotationQuaternion will be set to null\n     * @returns this  node\n     */\n    public override markAsDirty(property?: string): Node {\n        if (this._isDirty) {\n            return this;\n        }\n\n        // We need to explicitly update the children\n        // as the scene.evaluateActiveMeshes will not poll the transform nodes\n        if (this._children) {\n            for (const child of this._children) {\n                child.markAsDirty(property);\n            }\n        }\n        return super.markAsDirty(property);\n    }\n\n    /**\n     * Defines the passed node as the parent of the current node.\n     * The node will remain exactly where it is and its position / rotation will be updated accordingly.\n     * If you don't want to preserve the current rotation / position, assign the parent through parent accessor.\n     * Note that if the mesh has a pivot matrix / point defined it will be applied after the parent was updated.\n     * In that case the node will not remain in the same space as it is, as the pivot will be applied.\n     * To avoid this, you can set updatePivot to true and the pivot will be updated to identity\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/parent_pivot/parent\n     * @param node the node ot set as the parent\n     * @param preserveScalingSign if true, keep scaling sign of child. Otherwise, scaling sign might change.\n     * @param updatePivot if true, update the pivot matrix to keep the node in the same space as before\n     * @returns this TransformNode.\n     */\n    public setParent(node: Nullable<Node>, preserveScalingSign: boolean = false, updatePivot = false): TransformNode {\n        if (!node && !this.parent) {\n            return this;\n        }\n\n        const quatRotation = TmpVectors.Quaternion[0];\n        const position = TmpVectors.Vector3[0];\n        const scale = TmpVectors.Vector3[1];\n        const invParentMatrix = TmpVectors.Matrix[1];\n        Matrix.IdentityToRef(invParentMatrix);\n        const composedMatrix = TmpVectors.Matrix[0];\n        this.computeWorldMatrix(true);\n\n        let currentRotation = this.rotationQuaternion;\n        if (!currentRotation) {\n            currentRotation = TransformNode._TmpRotation;\n            Quaternion.RotationYawPitchRollToRef(this._rotation.y, this._rotation.x, this._rotation.z, currentRotation);\n        }\n\n        // current global transformation without pivot\n        Matrix.ComposeToRef(this.scaling, currentRotation, this.position, composedMatrix);\n        if (this.parent) {\n            composedMatrix.multiplyToRef(this.parent.computeWorldMatrix(true), composedMatrix);\n        }\n\n        // is a node was set, calculate the difference between this and the node\n        if (node) {\n            node.computeWorldMatrix(true).invertToRef(invParentMatrix);\n            composedMatrix.multiplyToRef(invParentMatrix, composedMatrix);\n        }\n        composedMatrix.decompose(scale, quatRotation, position, preserveScalingSign ? this : undefined);\n\n        if (this.rotationQuaternion) {\n            this.rotationQuaternion.copyFrom(quatRotation);\n        } else {\n            quatRotation.toEulerAnglesToRef(this.rotation);\n        }\n\n        this.scaling.copyFrom(scale);\n        this.position.copyFrom(position);\n\n        this.parent = node;\n\n        if (updatePivot) {\n            this.setPivotMatrix(Matrix.Identity());\n        }\n\n        return this;\n    }\n\n    /**\n     * Adds the passed mesh as a child to the current mesh.\n     * The node will remain exactly where it is and its position / rotation will be updated accordingly.\n     * This method is equivalent to calling setParent().\n     * @param mesh defines the child mesh\n     * @param preserveScalingSign if true, keep scaling sign of child. Otherwise, scaling sign might change.\n     * @returns the current mesh\n     */\n    public addChild(mesh: TransformNode, preserveScalingSign: boolean = false): this {\n        mesh.setParent(this, preserveScalingSign);\n        return this;\n    }\n\n    /**\n     * Removes the passed mesh from the current mesh children list\n     * @param mesh defines the child mesh\n     * @param preserveScalingSign if true, keep scaling sign of child. Otherwise, scaling sign might change.\n     * @returns the current mesh\n     */\n    public removeChild(mesh: TransformNode, preserveScalingSign: boolean = false): this {\n        if (mesh.parent !== this) {\n            return this;\n        }\n        mesh.setParent(null, preserveScalingSign);\n        return this;\n    }\n\n    private _nonUniformScaling = false;\n    /**\n     * True if the scaling property of this object is non uniform eg. (1,2,1)\n     */\n    public get nonUniformScaling(): boolean {\n        return this._nonUniformScaling;\n    }\n\n    /**\n     * @internal\n     */\n    public _updateNonUniformScalingState(value: boolean): boolean {\n        if (this._nonUniformScaling === value) {\n            return false;\n        }\n\n        this._nonUniformScaling = value;\n        return true;\n    }\n\n    /**\n     * Attach the current TransformNode to another TransformNode associated with a bone\n     * @param bone Bone affecting the TransformNode\n     * @param affectedTransformNode TransformNode associated with the bone\n     * @returns this object\n     */\n    public attachToBone(bone: Bone, affectedTransformNode: TransformNode): TransformNode {\n        this._currentParentWhenAttachingToBone = this.parent;\n        this._transformToBoneReferal = affectedTransformNode;\n        this.parent = bone;\n\n        bone.getSkeleton().prepare(true); // make sure bone.getFinalMatrix() is up to date\n\n        if (bone.getFinalMatrix().determinant() < 0) {\n            this.scalingDeterminant *= -1;\n        }\n        return this;\n    }\n\n    /**\n     * Detach the transform node if its associated with a bone\n     * @param resetToPreviousParent Indicates if the parent that was in effect when attachToBone was called should be set back or if we should set parent to null instead (defaults to the latter)\n     * @returns this object\n     */\n    public detachFromBone(resetToPreviousParent = false): TransformNode {\n        if (!this.parent) {\n            if (resetToPreviousParent) {\n                this.parent = this._currentParentWhenAttachingToBone;\n            }\n            return this;\n        }\n\n        if (this.parent.getWorldMatrix().determinant() < 0) {\n            this.scalingDeterminant *= -1;\n        }\n        this._transformToBoneReferal = null;\n        if (resetToPreviousParent) {\n            this.parent = this._currentParentWhenAttachingToBone;\n        } else {\n            this.parent = null;\n        }\n        return this;\n    }\n\n    private static _RotationAxisCache = /*#__PURE__*/ new Quaternion();\n    /**\n     * Rotates the mesh around the axis vector for the passed angle (amount) expressed in radians, in the given space.\n     * space (default LOCAL) can be either Space.LOCAL, either Space.WORLD.\n     * Note that the property `rotationQuaternion` is then automatically updated and the property `rotation` is set to (0,0,0) and no longer used.\n     * The passed axis is also normalized.\n     * @param axis the axis to rotate around\n     * @param amount the amount to rotate in radians\n     * @param space Space to rotate in (Default: local)\n     * @returns the TransformNode.\n     */\n    public rotate(axis: Vector3, amount: number, space?: Space): TransformNode {\n        axis.normalize();\n        if (!this.rotationQuaternion) {\n            this.rotationQuaternion = this.rotation.toQuaternion();\n            this.rotation.setAll(0);\n        }\n        let rotationQuaternion: Quaternion;\n        if (!space || (space as any) === Space.LOCAL) {\n            rotationQuaternion = Quaternion.RotationAxisToRef(axis, amount, TransformNode._RotationAxisCache);\n            this.rotationQuaternion.multiplyToRef(rotationQuaternion, this.rotationQuaternion);\n        } else {\n            if (this.parent) {\n                const parentWorldMatrix = this.parent.getWorldMatrix();\n                const invertParentWorldMatrix = TmpVectors.Matrix[0];\n                parentWorldMatrix.invertToRef(invertParentWorldMatrix);\n                axis = Vector3.TransformNormal(axis, invertParentWorldMatrix);\n\n                if (parentWorldMatrix.determinant() < 0) {\n                    amount *= -1;\n                }\n            }\n            rotationQuaternion = Quaternion.RotationAxisToRef(axis, amount, TransformNode._RotationAxisCache);\n            rotationQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);\n        }\n        return this;\n    }\n\n    /**\n     * Rotates the mesh around the axis vector for the passed angle (amount) expressed in radians, in world space.\n     * Note that the property `rotationQuaternion` is then automatically updated and the property `rotation` is set to (0,0,0) and no longer used.\n     * The passed axis is also normalized. .\n     * Method is based on http://www.euclideanspace.com/maths/geometry/affine/aroundPoint/index.htm\n     * @param point the point to rotate around\n     * @param axis the axis to rotate around\n     * @param amount the amount to rotate in radians\n     * @returns the TransformNode\n     */\n    public rotateAround(point: Vector3, axis: Vector3, amount: number): TransformNode {\n        axis.normalize();\n        if (!this.rotationQuaternion) {\n            this.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);\n            this.rotation.setAll(0);\n        }\n\n        const tmpVector = TmpVectors.Vector3[0];\n        const finalScale = TmpVectors.Vector3[1];\n        const finalTranslation = TmpVectors.Vector3[2];\n\n        const finalRotation = TmpVectors.Quaternion[0];\n\n        const translationMatrix = TmpVectors.Matrix[0]; // T\n        const translationMatrixInv = TmpVectors.Matrix[1]; // T'\n        const rotationMatrix = TmpVectors.Matrix[2]; // R\n        const finalMatrix = TmpVectors.Matrix[3]; // T' x R x T\n\n        point.subtractToRef(this.position, tmpVector);\n        Matrix.TranslationToRef(tmpVector.x, tmpVector.y, tmpVector.z, translationMatrix); // T\n        Matrix.TranslationToRef(-tmpVector.x, -tmpVector.y, -tmpVector.z, translationMatrixInv); // T'\n        Matrix.RotationAxisToRef(axis, amount, rotationMatrix); // R\n\n        translationMatrixInv.multiplyToRef(rotationMatrix, finalMatrix); // T' x R\n        finalMatrix.multiplyToRef(translationMatrix, finalMatrix); // T' x R x T\n\n        finalMatrix.decompose(finalScale, finalRotation, finalTranslation);\n\n        this.position.addInPlace(finalTranslation);\n        finalRotation.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);\n\n        return this;\n    }\n\n    /**\n     * Translates the mesh along the axis vector for the passed distance in the given space.\n     * space (default LOCAL) can be either Space.LOCAL, either Space.WORLD.\n     * @param axis the axis to translate in\n     * @param distance the distance to translate\n     * @param space Space to rotate in (Default: local)\n     * @returns the TransformNode.\n     */\n    public translate(axis: Vector3, distance: number, space?: Space): TransformNode {\n        const displacementVector = axis.scale(distance);\n        if (!space || (space as any) === Space.LOCAL) {\n            const tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);\n            this.setPositionWithLocalVector(tempV3);\n        } else {\n            this.setAbsolutePosition(this.getAbsolutePosition().add(displacementVector));\n        }\n        return this;\n    }\n\n    /**\n     * Adds a rotation step to the mesh current rotation.\n     * x, y, z are Euler angles expressed in radians.\n     * This methods updates the current mesh rotation, either mesh.rotation, either mesh.rotationQuaternion if it's set.\n     * This means this rotation is made in the mesh local space only.\n     * It's useful to set a custom rotation order different from the BJS standard one YXZ.\n     * Example : this rotates the mesh first around its local X axis, then around its local Z axis, finally around its local Y axis.\n     * ```javascript\n     * mesh.addRotation(x1, 0, 0).addRotation(0, 0, z2).addRotation(0, 0, y3);\n     * ```\n     * Note that `addRotation()` accumulates the passed rotation values to the current ones and computes the .rotation or .rotationQuaternion updated values.\n     * Under the hood, only quaternions are used. So it's a little faster is you use .rotationQuaternion because it doesn't need to translate them back to Euler angles.\n     * @param x Rotation to add\n     * @param y Rotation to add\n     * @param z Rotation to add\n     * @returns the TransformNode.\n     */\n    public addRotation(x: number, y: number, z: number): TransformNode {\n        let rotationQuaternion;\n        if (this.rotationQuaternion) {\n            rotationQuaternion = this.rotationQuaternion;\n        } else {\n            rotationQuaternion = TmpVectors.Quaternion[1];\n            Quaternion.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, rotationQuaternion);\n        }\n        const accumulation = TmpVectors.Quaternion[0];\n        Quaternion.RotationYawPitchRollToRef(y, x, z, accumulation);\n        rotationQuaternion.multiplyInPlace(accumulation);\n        if (!this.rotationQuaternion) {\n            rotationQuaternion.toEulerAnglesToRef(this.rotation);\n        }\n        return this;\n    }\n\n    /**\n     * @internal\n     */\n    protected _getEffectiveParent(): Nullable<Node> {\n        return this.parent;\n    }\n\n    /**\n     * Returns whether the transform node world matrix computation needs the camera information to be computed.\n     * This is the case when the node is a billboard or has an infinite distance for instance.\n     * @returns true if the world matrix computation needs the camera information to be computed\n     */\n    public isWorldMatrixCameraDependent(): boolean {\n        return (this._infiniteDistance && !this.parent) || this._billboardMode !== TransformNode.BILLBOARDMODE_NONE;\n    }\n\n    /**\n     * Computes the world matrix of the node\n     * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch\n     * @param camera defines the camera used if different from the scene active camera (This is used with modes like Billboard or infinite distance)\n     * @returns the world matrix\n     */\n    public override computeWorldMatrix(force: boolean = false, camera: Nullable<Camera> = null): Matrix {\n        if (this._isWorldMatrixFrozen && !this._isDirty) {\n            return this._worldMatrix;\n        }\n\n        const currentRenderId = this.getScene().getRenderId();\n        if (!this._isDirty && !force && (this._currentRenderId === currentRenderId || this.isSynchronized())) {\n            this._currentRenderId = currentRenderId;\n            return this._worldMatrix;\n        }\n\n        camera = camera || this.getScene().activeCamera;\n\n        this._updateCache();\n        const cache = this._cache;\n        cache.pivotMatrixUpdated = false;\n        cache.billboardMode = this.billboardMode;\n        cache.infiniteDistance = this.infiniteDistance;\n        cache.parent = this._parentNode;\n\n        this._currentRenderId = currentRenderId;\n        this._childUpdateId += 1;\n        this._isDirty = false;\n        this._position._isDirty = false;\n        this._rotation._isDirty = false;\n        this._scaling._isDirty = false;\n        const parent = this._getEffectiveParent();\n\n        // Scaling\n        const scaling: Vector3 = TransformNode._TmpScaling;\n        let translation: Vector3 = this._position;\n\n        // Translation\n        if (this._infiniteDistance) {\n            if (!this.parent && camera) {\n                const cameraWorldMatrix = camera.getWorldMatrix();\n                const m = cameraWorldMatrix.m;\n\n                translation = TransformNode._TmpTranslation;\n                translation.copyFromFloats(this._position.x + m[12], this._position.y + m[13], this._position.z + m[14]);\n            }\n        }\n\n        // Scaling\n        scaling.copyFromFloats(this._scaling.x * this.scalingDeterminant, this._scaling.y * this.scalingDeterminant, this._scaling.z * this.scalingDeterminant);\n\n        // Rotation\n        let rotation: Quaternion;\n        if (this._rotationQuaternion) {\n            this._rotationQuaternion._isDirty = false;\n            rotation = this._rotationQuaternion;\n            if (this.reIntegrateRotationIntoRotationQuaternion) {\n                const len = this.rotation.lengthSquared();\n                if (len) {\n                    this._rotationQuaternion.multiplyInPlace(Quaternion.RotationYawPitchRoll(this._rotation.y, this._rotation.x, this._rotation.z));\n                    this._rotation.copyFromFloats(0, 0, 0);\n                }\n            }\n        } else {\n            rotation = TransformNode._TmpRotation;\n            Quaternion.RotationYawPitchRollToRef(this._rotation.y, this._rotation.x, this._rotation.z, rotation);\n        }\n\n        // Compose\n        if (this._usePivotMatrix) {\n            const scaleMatrix = TmpVectors.Matrix[1];\n            Matrix.ScalingToRef(scaling.x, scaling.y, scaling.z, scaleMatrix);\n\n            // Rotation\n            const rotationMatrix = TmpVectors.Matrix[0];\n            rotation.toRotationMatrix(rotationMatrix);\n\n            // Composing transformations\n            this._pivotMatrix.multiplyToRef(scaleMatrix, TmpVectors.Matrix[4]);\n            TmpVectors.Matrix[4].multiplyToRef(rotationMatrix, this._localMatrix);\n\n            // Post multiply inverse of pivotMatrix\n            if (this._postMultiplyPivotMatrix) {\n                this._localMatrix.multiplyToRef(this._pivotMatrixInverse, this._localMatrix);\n            }\n\n            this._localMatrix.addTranslationFromFloats(translation.x, translation.y, translation.z);\n        } else {\n            Matrix.ComposeToRef(scaling, rotation, translation, this._localMatrix);\n        }\n\n        // Parent\n        if (parent && parent.getWorldMatrix) {\n            if (force) {\n                parent.computeWorldMatrix(force);\n            }\n            if (this.billboardMode) {\n                if (this._transformToBoneReferal) {\n                    const bone = this.parent as Bone;\n                    bone.getSkeleton().prepare();\n                    bone.getFinalMatrix().multiplyToRef(this._transformToBoneReferal.getWorldMatrix(), TmpVectors.Matrix[7]);\n                } else {\n                    TmpVectors.Matrix[7].copyFrom(parent.getWorldMatrix());\n                }\n\n                // Extract scaling and translation from parent\n                const translation = TmpVectors.Vector3[5];\n                const scale = TmpVectors.Vector3[6];\n                const orientation = TmpVectors.Quaternion[0];\n                TmpVectors.Matrix[7].decompose(scale, orientation, translation);\n                Matrix.ScalingToRef(scale.x, scale.y, scale.z, TmpVectors.Matrix[7]);\n                TmpVectors.Matrix[7].setTranslation(translation);\n\n                if (TransformNode.BillboardUseParentOrientation) {\n                    // set localMatrix translation to be transformed against parent's orientation.\n                    this._position.applyRotationQuaternionToRef(orientation, translation);\n                    this._localMatrix.setTranslation(translation);\n                }\n\n                this._localMatrix.multiplyToRef(TmpVectors.Matrix[7], this._worldMatrix);\n            } else {\n                if (this._transformToBoneReferal) {\n                    const bone = this.parent as Bone;\n                    bone.getSkeleton().prepare();\n                    this._localMatrix.multiplyToRef(bone.getFinalMatrix(), TmpVectors.Matrix[6]);\n                    TmpVectors.Matrix[6].multiplyToRef(this._transformToBoneReferal.getWorldMatrix(), this._worldMatrix);\n                } else {\n                    this._localMatrix.multiplyToRef(parent.getWorldMatrix(), this._worldMatrix);\n                }\n            }\n            this._markSyncedWithParent();\n        } else {\n            this._worldMatrix.copyFrom(this._localMatrix);\n        }\n\n        if (camera && this.billboardMode) {\n            // Billboarding based on camera orientation (testing PG:http://www.babylonjs-playground.com/#UJEIL#13)\n            if (!cache.useBillboardPosition) {\n                const storedTranslation = TmpVectors.Vector3[0];\n                this._worldMatrix.getTranslationToRef(storedTranslation); // Save translation\n\n                // Get camera view matrix\n                TmpVectors.Matrix[1].copyFrom(camera.getViewMatrix());\n\n                const isRH = this.getScene().useRightHandedSystem;\n\n                if (isRH) {\n                    // This operation is necessary to cancel out the scaling component of the matrix without decomposing it.\n                    // It's a trick to extract only the rotation part.\n                    TmpVectors.Matrix[1].multiplyToRef(TransformNode._TmpRHRestore, TmpVectors.Matrix[1]);\n                }\n\n                // This will cancel the camera rotation\n                TmpVectors.Matrix[1].setTranslationFromFloats(0, 0, 0);\n                TmpVectors.Matrix[1].invertToRef(TmpVectors.Matrix[0]);\n\n                if ((this.billboardMode & TransformNode.BILLBOARDMODE_ALL) !== TransformNode.BILLBOARDMODE_ALL) {\n                    TmpVectors.Matrix[0].decompose(undefined, TmpVectors.Quaternion[0], undefined);\n                    const eulerAngles = TmpVectors.Vector3[1];\n                    TmpVectors.Quaternion[0].toEulerAnglesToRef(eulerAngles);\n\n                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {\n                        eulerAngles.x = 0;\n                    }\n\n                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {\n                        eulerAngles.y = 0;\n                    }\n\n                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {\n                        eulerAngles.z = 0;\n                    }\n\n                    if (isRH) {\n                        eulerAngles.y += Math.PI; // Yaw correction\n                    }\n\n                    Matrix.RotationYawPitchRollToRef(eulerAngles.y, eulerAngles.x, eulerAngles.z, TmpVectors.Matrix[0]);\n                }\n                this._worldMatrix.setTranslationFromFloats(0, 0, 0);\n                this._worldMatrix.multiplyToRef(TmpVectors.Matrix[0], this._worldMatrix);\n\n                // Restore translation\n                this._worldMatrix.setTranslation(TmpVectors.Vector3[0]);\n            }\n            // Billboarding based on camera position\n            else {\n                const storedTranslation = TmpVectors.Vector3[0];\n                // Save translation\n                this._worldMatrix.getTranslationToRef(storedTranslation);\n\n                // Compute camera position in local space\n                const cameraPosition = camera.globalPosition;\n                this._worldMatrix.invertToRef(TmpVectors.Matrix[1]);\n                const camInObjSpace = TmpVectors.Vector3[1];\n                Vector3.TransformCoordinatesToRef(cameraPosition, TmpVectors.Matrix[1], camInObjSpace);\n                camInObjSpace.normalize();\n\n                // Find the lookAt info in local space\n                const yaw = -Math.atan2(camInObjSpace.z, camInObjSpace.x) + Math.PI / 2;\n                const len = Math.sqrt(camInObjSpace.x * camInObjSpace.x + camInObjSpace.z * camInObjSpace.z);\n                const pitch = -Math.atan2(camInObjSpace.y, len);\n                Quaternion.RotationYawPitchRollToRef(yaw, pitch, 0, TmpVectors.Quaternion[0]);\n\n                if ((this.billboardMode & TransformNode.BILLBOARDMODE_ALL) !== TransformNode.BILLBOARDMODE_ALL) {\n                    const eulerAngles = TmpVectors.Vector3[1];\n                    TmpVectors.Quaternion[0].toEulerAnglesToRef(eulerAngles);\n\n                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {\n                        eulerAngles.x = 0;\n                    }\n\n                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {\n                        eulerAngles.y = 0;\n                    }\n\n                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {\n                        eulerAngles.z = 0;\n                    }\n\n                    Matrix.RotationYawPitchRollToRef(eulerAngles.y, eulerAngles.x, eulerAngles.z, TmpVectors.Matrix[0]);\n                } else {\n                    Matrix.FromQuaternionToRef(TmpVectors.Quaternion[0], TmpVectors.Matrix[0]);\n                }\n\n                // Cancel translation\n                this._worldMatrix.setTranslationFromFloats(0, 0, 0);\n\n                // Rotate according to lookat (diff from local to lookat)\n                this._worldMatrix.multiplyToRef(TmpVectors.Matrix[0], this._worldMatrix);\n\n                // Restore translation\n                this._worldMatrix.setTranslation(TmpVectors.Vector3[0]);\n            }\n        }\n\n        // Normal matrix\n        if (!this.ignoreNonUniformScaling) {\n            if (this._scaling.isNonUniformWithinEpsilon(0.000001)) {\n                this._updateNonUniformScalingState(true);\n            } else if (parent && (<TransformNode>parent)._nonUniformScaling) {\n                this._updateNonUniformScalingState((<TransformNode>parent)._nonUniformScaling);\n            } else {\n                this._updateNonUniformScalingState(false);\n            }\n        } else {\n            this._updateNonUniformScalingState(false);\n        }\n\n        this._afterComputeWorldMatrix();\n\n        // Absolute position\n        this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);\n        this._isAbsoluteSynced = false;\n\n        // Callbacks\n        this.onAfterWorldMatrixUpdateObservable.notifyObservers(this);\n\n        if (!this._poseMatrix) {\n            this._poseMatrix = Matrix.Invert(this._worldMatrix);\n        }\n\n        // Cache the determinant\n        this._worldMatrixDeterminantIsDirty = true;\n\n        return this._worldMatrix;\n    }\n\n    /**\n     * Resets this nodeTransform's local matrix to Matrix.Identity().\n     * @param independentOfChildren indicates if all child nodeTransform's world-space transform should be preserved.\n     */\n    public resetLocalMatrix(independentOfChildren: boolean = true): void {\n        this.computeWorldMatrix();\n        if (independentOfChildren) {\n            const children = this.getChildren();\n            for (let i = 0; i < children.length; ++i) {\n                const child = children[i] as TransformNode;\n                if (child) {\n                    child.computeWorldMatrix();\n                    const bakedMatrix = TmpVectors.Matrix[0];\n                    child._localMatrix.multiplyToRef(this._localMatrix, bakedMatrix);\n                    const tmpRotationQuaternion = TmpVectors.Quaternion[0];\n                    bakedMatrix.decompose(child.scaling, tmpRotationQuaternion, child.position);\n                    if (child.rotationQuaternion) {\n                        child.rotationQuaternion.copyFrom(tmpRotationQuaternion);\n                    } else {\n                        tmpRotationQuaternion.toEulerAnglesToRef(child.rotation);\n                    }\n                }\n            }\n        }\n        this.scaling.copyFromFloats(1, 1, 1);\n        this.position.copyFromFloats(0, 0, 0);\n        this.rotation.copyFromFloats(0, 0, 0);\n\n        //only if quaternion is already set\n        if (this.rotationQuaternion) {\n            this.rotationQuaternion = Quaternion.Identity();\n        }\n        this._worldMatrix = Matrix.Identity();\n    }\n\n    protected _afterComputeWorldMatrix(): void {}\n\n    /**\n     * If you'd like to be called back after the mesh position, rotation or scaling has been updated.\n     * @param func callback function to add\n     *\n     * @returns the TransformNode.\n     */\n    public registerAfterWorldMatrixUpdate(func: (mesh: TransformNode) => void): TransformNode {\n        this.onAfterWorldMatrixUpdateObservable.add(func);\n        return this;\n    }\n\n    /**\n     * Removes a registered callback function.\n     * @param func callback function to remove\n     * @returns the TransformNode.\n     */\n    public unregisterAfterWorldMatrixUpdate(func: (mesh: TransformNode) => void): TransformNode {\n        this.onAfterWorldMatrixUpdateObservable.removeCallback(func);\n        return this;\n    }\n\n    /**\n     * Gets the position of the current mesh in camera space\n     * @param camera defines the camera to use\n     * @returns a position\n     */\n    public getPositionInCameraSpace(camera: Nullable<Camera> = null): Vector3 {\n        if (!camera) {\n            camera = <Camera>this.getScene().activeCamera;\n        }\n\n        return Vector3.TransformCoordinates(this.getAbsolutePosition(), camera.getViewMatrix());\n    }\n\n    /**\n     * Returns the distance from the mesh to the active camera\n     * @param camera defines the camera to use\n     * @returns the distance\n     */\n    public getDistanceToCamera(camera: Nullable<Camera> = null): number {\n        if (!camera) {\n            camera = <Camera>this.getScene().activeCamera;\n        }\n        return this.getAbsolutePosition().subtract(camera.globalPosition).length();\n    }\n\n    /**\n     * Clone the current transform node\n     * @param name Name of the new clone\n     * @param newParent New parent for the clone\n     * @param doNotCloneChildren Do not clone children hierarchy\n     * @returns the new transform node\n     */\n    public override clone(name: string, newParent: Nullable<Node>, doNotCloneChildren?: boolean): Nullable<TransformNode> {\n        const result = SerializationHelper.Clone(() => new TransformNode(name, this.getScene()), this);\n\n        result.name = name;\n        result.id = name;\n\n        if (newParent) {\n            result.parent = newParent;\n        }\n\n        if (!doNotCloneChildren) {\n            // Children\n            const directDescendants = this.getDescendants(true);\n            for (let index = 0; index < directDescendants.length; index++) {\n                const child = directDescendants[index];\n\n                if ((<any>child).clone) {\n                    (<any>child).clone(name + \".\" + child.name, result);\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Serializes the objects information.\n     * @param currentSerializationObject defines the object to serialize in\n     * @returns the serialized object\n     */\n    public serialize(currentSerializationObject?: any): any {\n        const serializationObject = SerializationHelper.Serialize(this, currentSerializationObject);\n        serializationObject.type = this.getClassName();\n        serializationObject.uniqueId = this.uniqueId;\n\n        // Parent\n        if (this.parent) {\n            this.parent._serializeAsParent(serializationObject);\n        }\n\n        serializationObject.localMatrix = this.getPivotMatrix().asArray();\n\n        serializationObject.isEnabled = this.isEnabled();\n\n        if (this._isWorldMatrixFrozen) {\n            serializationObject.freezeWorldMatrix = true;\n        }\n\n        // Animations\n        SerializationHelper.AppendSerializedAnimations(this, serializationObject);\n        serializationObject.ranges = this.serializeAnimationRanges();\n\n        return serializationObject;\n    }\n\n    /**\n     * Get all child-transformNodes of this node\n     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered\n     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored\n     * @returns an array of TransformNode\n     */\n    public getChildTransformNodes(directDescendantsOnly?: boolean, predicate?: (node: Node) => boolean): TransformNode[] {\n        const results: Array<TransformNode> = [];\n        this._getDescendants(results, directDescendantsOnly, (node: Node) => {\n            return (!predicate || predicate(node)) && node instanceof TransformNode;\n        });\n        return results;\n    }\n\n    /**\n     * Releases resources associated with this transform node.\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\n     */\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\n        // Animations\n        this.getScene().stopAnimation(this);\n\n        // Remove from scene\n        this.getScene().removeTransformNode(this);\n\n        if (this._parentContainer) {\n            const index = this._parentContainer.transformNodes.indexOf(this);\n            if (index > -1) {\n                this._parentContainer.transformNodes.splice(index, 1);\n            }\n            this._parentContainer = null;\n        }\n\n        this.onAfterWorldMatrixUpdateObservable.clear();\n\n        if (doNotRecurse) {\n            const transformNodes = this.getChildTransformNodes(true);\n            for (const transformNode of transformNodes) {\n                transformNode.parent = null;\n                transformNode.computeWorldMatrix(true);\n            }\n        }\n\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\n    }\n\n    /**\n     * Uniformly scales the mesh to fit inside of a unit cube (1 X 1 X 1 units)\n     * @param includeDescendants Use the hierarchy's bounding box instead of the mesh's bounding box. Default is false\n     * @param ignoreRotation ignore rotation when computing the scale (ie. object will be axis aligned). Default is false\n     * @param predicate predicate that is passed in to getHierarchyBoundingVectors when selecting which object should be included when scaling\n     * @returns the current mesh\n     */\n    public normalizeToUnitCube(includeDescendants = true, ignoreRotation = false, predicate?: Nullable<(node: AbstractMesh) => boolean>): TransformNode {\n        let storedRotation: Nullable<Vector3> = null;\n        let storedRotationQuaternion: Nullable<Quaternion> = null;\n\n        if (ignoreRotation) {\n            if (this.rotationQuaternion) {\n                storedRotationQuaternion = this.rotationQuaternion.clone();\n                this.rotationQuaternion.copyFromFloats(0, 0, 0, 1);\n            } else if (this.rotation) {\n                storedRotation = this.rotation.clone();\n                this.rotation.copyFromFloats(0, 0, 0);\n            }\n        }\n\n        const boundingVectors = this.getHierarchyBoundingVectors(includeDescendants, predicate);\n        const sizeVec = boundingVectors.max.subtract(boundingVectors.min);\n        const maxDimension = Math.max(sizeVec.x, sizeVec.y, sizeVec.z);\n\n        if (maxDimension === 0) {\n            return this;\n        }\n\n        const scale = 1 / maxDimension;\n\n        this.scaling.scaleInPlace(scale);\n\n        if (ignoreRotation) {\n            if (this.rotationQuaternion && storedRotationQuaternion) {\n                this.rotationQuaternion.copyFrom(storedRotationQuaternion);\n            } else if (this.rotation && storedRotation) {\n                this.rotation.copyFrom(storedRotation);\n            }\n        }\n\n        return this;\n    }\n\n    private _syncAbsoluteScalingAndRotation(): void {\n        if (!this._isAbsoluteSynced) {\n            this._worldMatrix.decompose(this._absoluteScaling, this._absoluteRotationQuaternion);\n            this._isAbsoluteSynced = true;\n        }\n    }\n}\n\n/**\n * Returns a new TransformNode object parsed from the source provided.\n * @param parsedTransformNode is the source.\n * @param scene the scene the object belongs to\n * @param rootUrl is a string, it's the root URL to prefix the `delayLoadingFile` property with\n * @returns a new TransformNode object parsed from the source provided.\n */\nexport function TransformNodeParse(parsedTransformNode: any, scene: Scene, rootUrl: string): TransformNode {\n    const transformNode = SerializationHelper.Parse(() => new TransformNode(parsedTransformNode.name, scene), parsedTransformNode, scene, rootUrl);\n\n    if (parsedTransformNode.localMatrix) {\n        transformNode.setPreTransformMatrix(Matrix.FromArray(parsedTransformNode.localMatrix));\n    } else if (parsedTransformNode.pivotMatrix) {\n        transformNode.setPivotMatrix(Matrix.FromArray(parsedTransformNode.pivotMatrix));\n    }\n\n    transformNode.setEnabled(parsedTransformNode.isEnabled);\n\n    transformNode._waitingParsedUniqueId = parsedTransformNode.uniqueId;\n\n    // Parent\n    if (parsedTransformNode.parentId !== undefined) {\n        transformNode._waitingParentId = parsedTransformNode.parentId;\n    }\n\n    if (parsedTransformNode.parentInstanceIndex !== undefined) {\n        transformNode._waitingParentInstanceIndex = parsedTransformNode.parentInstanceIndex;\n    }\n\n    if (parsedTransformNode.freezeWorldMatrix) {\n        transformNode._waitingFreezeWorldMatrix = parsedTransformNode.freezeWorldMatrix;\n    }\n\n    // Animations\n    if (parsedTransformNode.animations) {\n        for (let animationIndex = 0; animationIndex < parsedTransformNode.animations.length; animationIndex++) {\n            const parsedAnimation = parsedTransformNode.animations[animationIndex];\n            const internalClass = GetClass(\"BABYLON.Animation\");\n            if (internalClass) {\n                transformNode.animations.push(internalClass.Parse(parsedAnimation));\n            }\n        }\n        Node.ParseAnimationRanges(transformNode, parsedTransformNode, scene);\n    }\n\n    if (parsedTransformNode.autoAnimate) {\n        scene.beginAnimation(\n            transformNode,\n            parsedTransformNode.autoAnimateFrom,\n            parsedTransformNode.autoAnimateTo,\n            parsedTransformNode.autoAnimateLoop,\n            parsedTransformNode.autoAnimateSpeed || 1.0\n        );\n    }\n\n    return transformNode;\n}\n\nlet _TransformNodeRegistered = false;\nexport function RegisterTransformNode(): void {\n    if (_TransformNodeRegistered) {\n        return;\n    }\n    _TransformNodeRegistered = true;\n    TransformNode.Parse = TransformNodeParse;\n}\n\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\nimport { _MissingSideEffect, _MissingSideEffectProperty } from \"../Misc/devTools\";\n\nTransformNode.prototype.getPhysicsBody ??= _MissingSideEffect(\"TransformNode\", \"getPhysicsBody\") as any;\nTransformNode.prototype.applyImpulse ??= _MissingSideEffect(\"TransformNode\", \"applyImpulse\") as any;\nTransformNode.prototype.applyAngularImpulse ??= _MissingSideEffect(\"TransformNode\", \"applyAngularImpulse\") as any;\nTransformNode.prototype.applyTorque ??= _MissingSideEffect(\"TransformNode\", \"applyTorque\") as any;\nif (!Object.getOwnPropertyDescriptor(TransformNode.prototype, \"physicsBody\")) {\n    Object.defineProperty(TransformNode.prototype, \"physicsBody\", _MissingSideEffectProperty(\"TransformNode\", \"physicsBody\"));\n}\n// #endregion GENERATED_SIDE_EFFECT_STUBS\n","import { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Path2 } from \"../Maths/math.path\";\r\n\r\n/**\r\n * A cursor which tracks a point on a path\r\n */\r\nexport class PathCursor {\r\n    /**\r\n     * Stores path cursor callbacks for when an onchange event is triggered\r\n     */\r\n    private _onchange = new Array<(cursor: PathCursor) => void>();\r\n\r\n    /**\r\n     * The value of the path cursor\r\n     */\r\n    value: number = 0;\r\n\r\n    /**\r\n     * The animation array of the path cursor\r\n     */\r\n    animations = [] as Animation[];\r\n\r\n    /**\r\n     * Initializes the path cursor\r\n     * @param _path The path to track\r\n     */\r\n    constructor(private _path: Path2) {}\r\n\r\n    /**\r\n     * Gets the cursor point on the path\r\n     * @returns A point on the path cursor at the cursor location\r\n     */\r\n    public getPoint(): Vector3 {\r\n        const point = this._path.getPointAtLengthPosition(this.value);\r\n        return new Vector3(point.x, 0, point.y);\r\n    }\r\n\r\n    /**\r\n     * Moves the cursor ahead by the step amount\r\n     * @param step The amount to move the cursor forward\r\n     * @returns This path cursor\r\n     */\r\n    public moveAhead(step: number = 0.002): PathCursor {\r\n        this.move(step);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Moves the cursor behind by the step amount\r\n     * @param step The amount to move the cursor back\r\n     * @returns This path cursor\r\n     */\r\n    public moveBack(step: number = 0.002): PathCursor {\r\n        this.move(-step);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Moves the cursor by the step amount\r\n     * If the step amount is greater than one, an exception is thrown\r\n     * @param step The amount to move the cursor\r\n     * @returns This path cursor\r\n     */\r\n    public move(step: number): PathCursor {\r\n        if (Math.abs(step) > 1) {\r\n            throw new Error(\"step size should be less than 1.\");\r\n        }\r\n\r\n        this.value += step;\r\n        this._ensureLimits();\r\n        this._raiseOnChange();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Ensures that the value is limited between zero and one\r\n     * @returns This path cursor\r\n     */\r\n    private _ensureLimits(): PathCursor {\r\n        while (this.value > 1) {\r\n            this.value -= 1;\r\n        }\r\n        while (this.value < 0) {\r\n            this.value += 1;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Runs onchange callbacks on change (used by the animation engine)\r\n     * @returns This path cursor\r\n     */\r\n    private _raiseOnChange(): PathCursor {\r\n        for (const f of this._onchange) {\r\n            f(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Executes a function on change\r\n     * @param f A path cursor onchange callback\r\n     * @returns This path cursor\r\n     */\r\n    public onchange(f: (cursor: PathCursor) => void): PathCursor {\r\n        this._onchange.push(f);\r\n\r\n        return this;\r\n    }\r\n}\r\n","import { type Scene } from \"core/scene\";\r\n\r\n/**\r\n * Interface used to define the optimization options for animations\r\n */\r\nexport type AnimationOptimization =\r\n    | {\r\n          /**\r\n           * Do not merge runtime animations\r\n           * @defaultValue true\r\n           */\r\n          mergeRuntimeAnimations: false;\r\n      }\r\n    | {\r\n          /**\r\n           * All runtime animations will be merged into the first animatable\r\n           * @defaultValue true\r\n           */\r\n          mergeRuntimeAnimations: true;\r\n          /**\r\n           * If true, all keyframes evaluation will be merged from the first runtime animation\r\n           * You need to turn on `mergeRuntimeAnimations` for this to work\r\n           * @defaultValue false\r\n           */\r\n          mergeKeyFrames: boolean;\r\n      };\r\n\r\n/**\r\n * This is a destructive optimization that merges all animatables into the first one.\r\n * That animatable will also host all the runtime animations.\r\n * We expect that all the animatables are on the same timeframe (same start, end, loop, etc..)\r\n * @param scene defines the scene to optimize\r\n * @param options defines the optimization options\r\n */\r\nexport function OptimizeAnimations(scene: Scene, options: Partial<AnimationOptimization> = {}) {\r\n    const mergeRuntimeAnimations = options.mergeRuntimeAnimations ?? true;\r\n    const mergeKeyFrames = options.mergeRuntimeAnimations === true ? (options.mergeKeyFrames ?? false) : false;\r\n\r\n    // We will go through all the current animatables and merge them\r\n    const animatables = scene.animatables;\r\n\r\n    if (animatables.length === 0) {\r\n        return;\r\n    }\r\n\r\n    const mainAnimatable = animatables[0];\r\n\r\n    for (let i = 1; i < animatables.length; i++) {\r\n        const animatable = animatables[i];\r\n\r\n        // Merge the current animatable with the main one\r\n        mainAnimatable._runtimeAnimations.push(...animatable._runtimeAnimations);\r\n    }\r\n\r\n    if (mergeRuntimeAnimations && mainAnimatable._runtimeAnimations.length > 1) {\r\n        // Make sure only one runtime animation is driving the beat\r\n        const mainRuntimeAnimation = mainAnimatable._runtimeAnimations[0];\r\n        for (let i = 1; i < mainAnimatable._runtimeAnimations.length; i++) {\r\n            const runtimeAnimation = mainAnimatable._runtimeAnimations[i];\r\n            runtimeAnimation._coreRuntimeAnimation = mainRuntimeAnimation;\r\n        }\r\n    }\r\n\r\n    if (mergeKeyFrames && mainAnimatable._runtimeAnimations.length > 1) {\r\n        // Merge the keyframes from all the runtime animations into the first one\r\n        const mainAnimation = mainAnimatable._runtimeAnimations[0]._animation;\r\n        for (let i = 1; i < mainAnimatable._runtimeAnimations.length; i++) {\r\n            const runtimeAnimation = mainAnimatable._runtimeAnimations[i];\r\n            const animation = runtimeAnimation._animation;\r\n            animation._coreAnimation = mainAnimation;\r\n        }\r\n    }\r\n\r\n    scene._activeAnimatables = [mainAnimatable];\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n// \"Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed.\"\r\n// https://en.wikipedia.org/wiki/Coroutine\r\n\r\n// In this implementation, coroutines are typically created via generator functions (function* with yield statements).\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*\r\n\r\n// In this implementation, the generator function (possibly parameterized) is referred to as a coroutine factory, and the returned iterator is referred to as the coroutine.\r\n// Technically yielding generator functions are not required - anything that implements the contract of Coroutine<T> can be run as a coroutine.\r\n\r\n// The coroutine is started with the first call to next on the iterator, it is suspended with yield statements, and it is resumed with additional calls to next on the iterator.\r\n// To create an object satisfying the Coroutine<T> contract with a generator function, it must not yield values, but rather only void via a plain \"yield;\" statement.\r\n// Coroutines can call other coroutines via:\r\n// 1. yield* someOtherCoroutine(); // If the called coroutine does not return a value\r\n// 2. const result = yield* someOtherCoroutine(); // If the called coroutine returns a value\r\n\r\n// Coroutines are run with the runCoroutine function, which takes a Coroutine<T>, a CoroutineScheduler<T>, and a success and error callback.\r\n// A scheduler is responsible for scheduling the next step of a coroutine, either synchronously or asynchronously.\r\n\r\n/**\r\n * A Coroutine<T> is the intersection of:\r\n * 1. An Iterator that yields void, returns a T, and is not passed values with calls to next.\r\n * 2. An IterableIterator of void (since it only yields void).\r\n */\r\ntype CoroutineBase<TStep, TReturn> = Iterator<TStep, TReturn, void> & IterableIterator<TStep>;\r\n/** @internal */\r\nexport type Coroutine<T> = CoroutineBase<void, T>;\r\n/** @internal */\r\nexport type AsyncCoroutine<T> = CoroutineBase<void | Promise<void>, T>;\r\n\r\n// A CoroutineStep<T> represents a single step of a coroutine, and is an IteratorResult as returned from Coroutine<T>.next().\r\n/** @internal */\r\nexport type CoroutineStep<T> = IteratorResult<void, T>;\r\n\r\n// A CoroutineScheduler<T> is responsible for scheduling the call to Coroutine<T>.next and invokes the success or error callback after next is called.\r\n/** @internal */\r\nexport type CoroutineScheduler<T> = (coroutine: AsyncCoroutine<T>, onStep: (stepResult: CoroutineStep<T>) => void, onError: (stepError: any) => void) => void;\r\n\r\n// The inline scheduler simply steps the coroutine synchronously. This is useful for running a coroutine synchronously, and also as a helper function for other schedulers.\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function inlineScheduler<T>(coroutine: AsyncCoroutine<T>, onStep: (stepResult: CoroutineStep<T>) => void, onError: (stepError: any) => void) {\r\n    try {\r\n        const step = coroutine.next();\r\n\r\n        if (step.done) {\r\n            onStep(step);\r\n        } else if (!step.value) {\r\n            // NOTE: The properties of step have been narrowed, but the type of step itself is not narrowed, so the cast below is the most type safe way to deal with this without instantiating a new object to hold the values.\r\n            onStep(step as { done: typeof step.done; value: typeof step.value });\r\n        } else {\r\n            // eslint-disable-next-line github/no-then\r\n            step.value.then(() => {\r\n                step.value = undefined;\r\n                onStep(step as { done: typeof step.done; value: typeof step.value });\r\n            }, onError);\r\n        }\r\n    } catch (error) {\r\n        onError(error);\r\n    }\r\n}\r\n\r\n// The yielding scheduler steps the coroutine synchronously until the specified time interval has elapsed, then yields control so other operations can be performed.\r\n// A single instance of a yielding scheduler could be shared across multiple coroutines to yield when their collective work exceeds the threshold.\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function createYieldingScheduler<T>(yieldAfterMS = 25) {\r\n    let startTime: number | undefined;\r\n    return (coroutine: AsyncCoroutine<T>, onStep: (stepResult: CoroutineStep<T>) => void, onError: (stepError: any) => void) => {\r\n        const currentTime = performance.now();\r\n\r\n        if (startTime === undefined || currentTime - startTime > yieldAfterMS) {\r\n            // If this is the first coroutine step, or if the time interval has elapsed, record a new start time, and schedule the coroutine step to happen later, effectively yielding control of the execution context.\r\n            startTime = currentTime;\r\n            setTimeout(() => {\r\n                inlineScheduler(coroutine, onStep, onError);\r\n            }, 0);\r\n        } else {\r\n            // Otherwise it is not time to yield yet, so step the coroutine synchronously.\r\n            inlineScheduler(coroutine, onStep, onError);\r\n        }\r\n    };\r\n}\r\n\r\n// Runs the specified coroutine with the specified scheduler. The success or error callback will be invoked when the coroutine finishes.\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function runCoroutine<T>(\r\n    coroutine: AsyncCoroutine<T>,\r\n    scheduler: CoroutineScheduler<T>,\r\n    onSuccess: (result: T) => void,\r\n    onError: (error: any) => void,\r\n    abortSignal?: AbortSignal\r\n) {\r\n    const resume = () => {\r\n        let reschedule: boolean | undefined;\r\n\r\n        const onStep = (stepResult: CoroutineStep<T>) => {\r\n            if (stepResult.done) {\r\n                // If the coroutine is done, report success.\r\n                onSuccess(stepResult.value);\r\n            } else {\r\n                // If the coroutine is not done, resume the coroutine (via the scheduler).\r\n                if (reschedule === undefined) {\r\n                    // If reschedule is undefined at this point, then the coroutine must have stepped synchronously, so just flag another loop iteration.\r\n                    reschedule = true;\r\n                } else {\r\n                    // If reschedule is defined at this point, then the coroutine must have stepped asynchronously, so call resume to restart the step loop.\r\n                    resume();\r\n                }\r\n            }\r\n        };\r\n\r\n        do {\r\n            reschedule = undefined;\r\n\r\n            if (!abortSignal || !abortSignal.aborted) {\r\n                scheduler(coroutine, onStep, onError);\r\n            } else {\r\n                onError(new Error(\"Aborted\"));\r\n            }\r\n\r\n            if (reschedule === undefined) {\r\n                // If reschedule is undefined at this point, then the coroutine must have stepped asynchronously, so stop looping and let the coroutine be resumed later.\r\n                reschedule = false;\r\n            }\r\n        } while (reschedule);\r\n    };\r\n\r\n    resume();\r\n}\r\n\r\n// Runs the specified coroutine synchronously.\r\n/**\r\n * @internal\r\n */\r\nexport function runCoroutineSync<T>(coroutine: Coroutine<T>, abortSignal?: AbortSignal): T {\r\n    // Run the coroutine with the inline scheduler, storing the returned value, or re-throwing the error (since the error callback will be called synchronously by the inline scheduler).\r\n    let result: T | undefined;\r\n    runCoroutine(\r\n        coroutine,\r\n        inlineScheduler,\r\n        (r: T) => (result = r),\r\n        (e: any) => {\r\n            throw e;\r\n        },\r\n        abortSignal\r\n    );\r\n\r\n    // Synchronously return the result of the coroutine.\r\n    return result!;\r\n}\r\n\r\n// Runs the specified coroutine asynchronously with the specified scheduler.\r\n/**\r\n * @internal\r\n */\r\nexport async function runCoroutineAsync<T>(coroutine: AsyncCoroutine<T>, scheduler: CoroutineScheduler<T>, abortSignal?: AbortSignal): Promise<T> {\r\n    // Run the coroutine with a yielding scheduler, resolving or rejecting the result promise when the coroutine finishes.\r\n    return await new Promise((resolve, reject) => {\r\n        runCoroutine(coroutine, scheduler, resolve, reject, abortSignal);\r\n    });\r\n}\r\n\r\n/**\r\n * Given a function that returns a Coroutine<T>, produce a function with the same parameters that returns a T.\r\n * The returned function runs the coroutine synchronously.\r\n * @param coroutineFactory A function that returns a Coroutine<T>.\r\n * @param abortSignal\r\n * @returns A function that runs the coroutine synchronously.\r\n * @internal\r\n */\r\nexport function makeSyncFunction<TParams extends unknown[], TReturn>(\r\n    coroutineFactory: (...params: TParams) => Coroutine<TReturn>,\r\n    abortSignal?: AbortSignal\r\n): (...params: TParams) => TReturn {\r\n    return (...params: TParams) => {\r\n        // Run the coroutine synchronously.\r\n        return runCoroutineSync(coroutineFactory(...params), abortSignal);\r\n    };\r\n}\r\n\r\n/**\r\n * Given a function that returns a Coroutine<T>, product a function with the same parameters that returns a Promise<T>.\r\n * The returned function runs the coroutine asynchronously, yield control of the execution context occasionally to enable a more responsive experience.\r\n * @param coroutineFactory A function that returns a Coroutine<T>.\r\n * @param scheduler\r\n * @param abortSignal\r\n * @returns A function that runs the coroutine asynchronously.\r\n * @internal\r\n */\r\nexport function makeAsyncFunction<TParams extends unknown[], TReturn>(\r\n    coroutineFactory: (...params: TParams) => AsyncCoroutine<TReturn>,\r\n    scheduler: CoroutineScheduler<TReturn>,\r\n    abortSignal?: AbortSignal\r\n): (...params: TParams) => Promise<TReturn> {\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    return (...params: TParams) => {\r\n        // Run the coroutine asynchronously.\r\n        return runCoroutineAsync(coroutineFactory(...params), scheduler, abortSignal);\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class IntersectionInfo {\r\n    public faceId = 0;\r\n    public subMeshId = 0;\r\n    public _internalSubMeshId = 0;\r\n\r\n    constructor(\r\n        public bu: Nullable<number>,\r\n        public bv: Nullable<number>,\r\n        public distance: number\r\n    ) {}\r\n}\r\n","import { type DeepImmutable, type Nullable } from \"../types\";\r\nimport { BuildArray } from \"../Misc/arrayTools\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type BoundingSphere } from \"../Culling/boundingSphere\";\r\n\r\nimport { type ICullable } from \"./boundingInfo\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\n\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\n\r\n/**\r\n * Class used to store bounding box information\r\n */\r\nexport class BoundingBox implements ICullable {\r\n    /**\r\n     * Gets the 8 vectors representing the bounding box in local space\r\n     */\r\n    public readonly vectors: Vector3[] = BuildArray(8, Vector3.Zero);\r\n    /**\r\n     * Gets the center of the bounding box in local space\r\n     */\r\n    public readonly center: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets the center of the bounding box in world space\r\n     */\r\n    public readonly centerWorld: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets half the size of the extent in local space. Multiply by 2 to obtain the full size of the box!\r\n     */\r\n    public readonly extendSize: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets half the size of the extent in world space. Multiply by 2 to obtain the full size of the box!\r\n     */\r\n    public readonly extendSizeWorld: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets the OBB (object bounding box) directions\r\n     */\r\n    public readonly directions: Vector3[] = BuildArray(3, Vector3.Zero);\r\n    /**\r\n     * Gets the 8 vectors representing the bounding box in world space\r\n     */\r\n    public readonly vectorsWorld: Vector3[] = BuildArray(8, Vector3.Zero);\r\n    /**\r\n     * Gets the minimum vector in world space\r\n     */\r\n    public readonly minimumWorld: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets the maximum vector in world space\r\n     */\r\n    public readonly maximumWorld: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets the minimum vector in local space\r\n     */\r\n    public readonly minimum: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Gets the maximum vector in local space\r\n     */\r\n    public readonly maximum: Vector3 = Vector3.Zero();\r\n\r\n    private _worldMatrix: DeepImmutable<Matrix>;\r\n    private static readonly _TmpVector3 = BuildArray(3, Vector3.Zero);\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _tag: number;\r\n\r\n    /** @internal */\r\n    public _drawWrapperFront: Nullable<DrawWrapper> = null;\r\n    /** @internal */\r\n    public _drawWrapperBack: Nullable<DrawWrapper> = null;\r\n\r\n    /**\r\n     * Creates a new bounding box\r\n     * @param min defines the minimum vector (in local space)\r\n     * @param max defines the maximum vector (in local space)\r\n     * @param worldMatrix defines the new world matrix\r\n     */\r\n    constructor(min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        this.reConstruct(min, max, worldMatrix);\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Recreates the entire bounding box from scratch as if we call the constructor in place\r\n     * @param min defines the new minimum vector (in local space)\r\n     * @param max defines the new maximum vector (in local space)\r\n     * @param worldMatrix defines the new world matrix\r\n     */\r\n    public reConstruct(min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        const minX = min.x,\r\n            minY = min.y,\r\n            minZ = min.z,\r\n            maxX = max.x,\r\n            maxY = max.y,\r\n            maxZ = max.z;\r\n        const vectors = this.vectors;\r\n\r\n        this.minimum.copyFromFloats(minX, minY, minZ);\r\n        this.maximum.copyFromFloats(maxX, maxY, maxZ);\r\n        vectors[0].copyFromFloats(minX, minY, minZ);\r\n        vectors[1].copyFromFloats(maxX, maxY, maxZ);\r\n        vectors[2].copyFromFloats(maxX, minY, minZ);\r\n        vectors[3].copyFromFloats(minX, maxY, minZ);\r\n        vectors[4].copyFromFloats(minX, minY, maxZ);\r\n        vectors[5].copyFromFloats(maxX, maxY, minZ);\r\n        vectors[6].copyFromFloats(minX, maxY, maxZ);\r\n        vectors[7].copyFromFloats(maxX, minY, maxZ);\r\n\r\n        // OBB\r\n        max.addToRef(min, this.center).scaleInPlace(0.5);\r\n        max.subtractToRef(min, this.extendSize).scaleInPlace(0.5);\r\n\r\n        this._worldMatrix = worldMatrix || Matrix.IdentityReadOnly;\r\n\r\n        this._update(this._worldMatrix);\r\n    }\r\n\r\n    /**\r\n     * Scale the current bounding box by applying a scale factor\r\n     * @param factor defines the scale factor to apply\r\n     * @returns the current bounding box\r\n     */\r\n    public scale(factor: number): BoundingBox {\r\n        const tmpVectors = BoundingBox._TmpVector3;\r\n        const diff = this.maximum.subtractToRef(this.minimum, tmpVectors[0]);\r\n        const len = diff.length();\r\n        diff.normalizeFromLength(len);\r\n        const distance = len * factor;\r\n        const newRadius = diff.scaleInPlace(distance * 0.5);\r\n\r\n        const min = this.center.subtractToRef(newRadius, tmpVectors[1]);\r\n        const max = this.center.addToRef(newRadius, tmpVectors[2]);\r\n\r\n        this.reConstruct(min, max, this._worldMatrix);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the world matrix of the bounding box\r\n     * @returns a matrix\r\n     */\r\n    public getWorldMatrix(): DeepImmutable<Matrix> {\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _update(world: DeepImmutable<Matrix>): void {\r\n        const minWorld = this.minimumWorld;\r\n        const maxWorld = this.maximumWorld;\r\n        const directions = this.directions;\r\n        const vectorsWorld = this.vectorsWorld;\r\n        const vectors = this.vectors;\r\n\r\n        if (!world.isIdentity()) {\r\n            minWorld.setAll(Number.MAX_VALUE);\r\n            maxWorld.setAll(-Number.MAX_VALUE);\r\n\r\n            for (let index = 0; index < 8; ++index) {\r\n                const v = vectorsWorld[index];\r\n                Vector3.TransformCoordinatesToRef(vectors[index], world, v);\r\n                minWorld.minimizeInPlace(v);\r\n                maxWorld.maximizeInPlace(v);\r\n            }\r\n\r\n            // Extend\r\n            maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);\r\n            maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);\r\n        } else {\r\n            minWorld.copyFrom(this.minimum);\r\n            maxWorld.copyFrom(this.maximum);\r\n            for (let index = 0; index < 8; ++index) {\r\n                vectorsWorld[index].copyFrom(vectors[index]);\r\n            }\r\n\r\n            // Extend\r\n            this.extendSizeWorld.copyFrom(this.extendSize);\r\n            this.centerWorld.copyFrom(this.center);\r\n        }\r\n\r\n        Vector3.FromArrayToRef(world.m, 0, directions[0]);\r\n        Vector3.FromArrayToRef(world.m, 4, directions[1]);\r\n        Vector3.FromArrayToRef(world.m, 8, directions[2]);\r\n\r\n        this._worldMatrix = world;\r\n    }\r\n\r\n    /**\r\n     * Tests if the bounding box is intersecting the frustum planes\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if there is an intersection\r\n     */\r\n    public isInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        return BoundingBox.IsInFrustum(this.vectorsWorld, frustumPlanes);\r\n    }\r\n\r\n    /**\r\n     * Tests if the bounding box is entirely inside the frustum planes\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if there is an inclusion\r\n     */\r\n    public isCompletelyInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        return BoundingBox.IsCompletelyInFrustum(this.vectorsWorld, frustumPlanes);\r\n    }\r\n\r\n    /**\r\n     * Tests if a point is inside the bounding box\r\n     * @param point defines the point to test\r\n     * @returns true if the point is inside the bounding box\r\n     */\r\n    public intersectsPoint(point: DeepImmutable<Vector3>): boolean {\r\n        const min = this.minimumWorld;\r\n        const max = this.maximumWorld;\r\n        const minX = min.x,\r\n            minY = min.y,\r\n            minZ = min.z,\r\n            maxX = max.x,\r\n            maxY = max.y,\r\n            maxZ = max.z;\r\n        const pointX = point.x,\r\n            pointY = point.y,\r\n            pointZ = point.z;\r\n        const delta = -Epsilon;\r\n\r\n        if (maxX - pointX < delta || delta > pointX - minX) {\r\n            return false;\r\n        }\r\n\r\n        if (maxY - pointY < delta || delta > pointY - minY) {\r\n            return false;\r\n        }\r\n\r\n        if (maxZ - pointZ < delta || delta > pointZ - minZ) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Tests if the bounding box intersects with a bounding sphere\r\n     * @param sphere defines the sphere to test\r\n     * @returns true if there is an intersection\r\n     */\r\n    public intersectsSphere(sphere: DeepImmutable<BoundingSphere>): boolean {\r\n        return BoundingBox.IntersectsSphere(this.minimumWorld, this.maximumWorld, sphere.centerWorld, sphere.radiusWorld);\r\n    }\r\n\r\n    /**\r\n     * Tests if the bounding box intersects with a box defined by a min and max vectors\r\n     * @param min defines the min vector to use\r\n     * @param max defines the max vector to use\r\n     * @returns true if there is an intersection\r\n     */\r\n    public intersectsMinMax(min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>): boolean {\r\n        const myMin = this.minimumWorld;\r\n        const myMax = this.maximumWorld;\r\n        const myMinX = myMin.x,\r\n            myMinY = myMin.y,\r\n            myMinZ = myMin.z,\r\n            myMaxX = myMax.x,\r\n            myMaxY = myMax.y,\r\n            myMaxZ = myMax.z;\r\n        const minX = min.x,\r\n            minY = min.y,\r\n            minZ = min.z,\r\n            maxX = max.x,\r\n            maxY = max.y,\r\n            maxZ = max.z;\r\n        if (myMaxX < minX || myMinX > maxX) {\r\n            return false;\r\n        }\r\n\r\n        if (myMaxY < minY || myMinY > maxY) {\r\n            return false;\r\n        }\r\n\r\n        if (myMaxZ < minZ || myMinZ > maxZ) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources of the class\r\n     */\r\n    public dispose(): void {\r\n        this._drawWrapperFront?.dispose();\r\n        this._drawWrapperBack?.dispose();\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Tests if two bounding boxes are intersections\r\n     * @param box0 defines the first box to test\r\n     * @param box1 defines the second box to test\r\n     * @returns true if there is an intersection\r\n     */\r\n    public static Intersects(box0: DeepImmutable<BoundingBox>, box1: DeepImmutable<BoundingBox>): boolean {\r\n        return box0.intersectsMinMax(box1.minimumWorld, box1.maximumWorld);\r\n    }\r\n\r\n    /**\r\n     * Tests if a bounding box defines by a min/max vectors intersects a sphere\r\n     * @param minPoint defines the minimum vector of the bounding box\r\n     * @param maxPoint defines the maximum vector of the bounding box\r\n     * @param sphereCenter defines the sphere center\r\n     * @param sphereRadius defines the sphere radius\r\n     * @returns true if there is an intersection\r\n     */\r\n    public static IntersectsSphere(minPoint: DeepImmutable<Vector3>, maxPoint: DeepImmutable<Vector3>, sphereCenter: DeepImmutable<Vector3>, sphereRadius: number): boolean {\r\n        const vector = BoundingBox._TmpVector3[0];\r\n        Vector3.ClampToRef(sphereCenter, minPoint, maxPoint, vector);\r\n        const num = Vector3.DistanceSquared(sphereCenter, vector);\r\n        return num <= sphereRadius * sphereRadius;\r\n    }\r\n\r\n    /**\r\n     * Tests if a bounding box defined with 8 vectors is entirely inside frustum planes\r\n     * @param boundingVectors defines an array of 8 vectors representing a bounding box\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if there is an inclusion\r\n     */\r\n    public static IsCompletelyInFrustum(boundingVectors: Array<DeepImmutable<Vector3>>, frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        for (let p = 0; p < 6; ++p) {\r\n            const frustumPlane = frustumPlanes[p];\r\n            for (let i = 0; i < 8; ++i) {\r\n                if (frustumPlane.dotCoordinate(boundingVectors[i]) < 0) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Tests if a bounding box defined with 8 vectors intersects frustum planes\r\n     * @param boundingVectors defines an array of 8 vectors representing a bounding box\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if there is an intersection\r\n     */\r\n    public static IsInFrustum(boundingVectors: Array<DeepImmutable<Vector3>>, frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        for (let p = 0; p < 6; ++p) {\r\n            let canReturnFalse = true;\r\n            const frustumPlane = frustumPlanes[p];\r\n            for (let i = 0; i < 8; ++i) {\r\n                if (frustumPlane.dotCoordinate(boundingVectors[i]) >= 0) {\r\n                    canReturnFalse = false;\r\n                    break;\r\n                }\r\n            }\r\n            if (canReturnFalse) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n}\r\n","import { type DeepImmutable } from \"../types\";\r\nimport { BuildArray } from \"../Misc/arrayTools\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\n\r\n/**\r\n * Class used to store bounding sphere information\r\n */\r\nexport class BoundingSphere {\r\n    /**\r\n     * Gets the center of the bounding sphere in local space\r\n     */\r\n    public readonly center = Vector3.Zero();\r\n    /**\r\n     * Radius of the bounding sphere in local space\r\n     */\r\n    public radius: number;\r\n    /**\r\n     * Gets the center of the bounding sphere in world space\r\n     */\r\n    public readonly centerWorld = Vector3.Zero();\r\n    /**\r\n     * Radius of the bounding sphere in world space\r\n     */\r\n    public radiusWorld: number;\r\n    /**\r\n     * Gets the minimum vector in local space\r\n     */\r\n    public readonly minimum = Vector3.Zero();\r\n    /**\r\n     * Gets the maximum vector in local space\r\n     */\r\n    public readonly maximum = Vector3.Zero();\r\n\r\n    private _worldMatrix: DeepImmutable<Matrix>;\r\n    private static readonly _TmpVector3 = BuildArray(3, Vector3.Zero);\r\n\r\n    /**\r\n     * Creates a new bounding sphere\r\n     * @param min defines the minimum vector (in local space)\r\n     * @param max defines the maximum vector (in local space)\r\n     * @param worldMatrix defines the new world matrix\r\n     */\r\n    constructor(min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        this.reConstruct(min, max, worldMatrix);\r\n    }\r\n\r\n    /**\r\n     * Recreates the entire bounding sphere from scratch as if we call the constructor in place\r\n     * @param min defines the new minimum vector (in local space)\r\n     * @param max defines the new maximum vector (in local space)\r\n     * @param worldMatrix defines the new world matrix\r\n     */\r\n    public reConstruct(min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        this.minimum.copyFrom(min);\r\n        this.maximum.copyFrom(max);\r\n\r\n        const distance = Vector3.Distance(min, max);\r\n\r\n        max.addToRef(min, this.center).scaleInPlace(0.5);\r\n        this.radius = distance * 0.5;\r\n\r\n        this._update(worldMatrix || Matrix.IdentityReadOnly);\r\n    }\r\n\r\n    /**\r\n     * Scale the current bounding sphere by applying a scale factor\r\n     * @param factor defines the scale factor to apply\r\n     * @returns the current bounding box\r\n     */\r\n    public scale(factor: number): BoundingSphere {\r\n        const tmpVectors = BoundingSphere._TmpVector3;\r\n        const diff = this.maximum.subtractToRef(this.minimum, tmpVectors[0]);\r\n        const len = diff.length();\r\n        diff.normalizeFromLength(len);\r\n        const distance = len * factor;\r\n        const newRadius = diff.scaleInPlace(distance * 0.5);\r\n\r\n        const min = this.center.subtractToRef(newRadius, tmpVectors[1]);\r\n        const max = this.center.addToRef(newRadius, tmpVectors[2]);\r\n\r\n        this.reConstruct(min, max, this._worldMatrix);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the world matrix of the bounding box\r\n     * @returns a matrix\r\n     */\r\n    public getWorldMatrix(): DeepImmutable<Matrix> {\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * @internal\r\n     */\r\n    public _update(worldMatrix: DeepImmutable<Matrix>): void {\r\n        if (!worldMatrix.isIdentity()) {\r\n            Vector3.TransformCoordinatesToRef(this.center, worldMatrix, this.centerWorld);\r\n            const tempVector = BoundingSphere._TmpVector3[0];\r\n            Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, worldMatrix, tempVector);\r\n            this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;\r\n        } else {\r\n            this.centerWorld.copyFrom(this.center);\r\n            this.radiusWorld = this.radius;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Tests if the bounding sphere is intersecting the frustum planes\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if there is an intersection\r\n     */\r\n    public isInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        const center = this.centerWorld;\r\n        const radius = this.radiusWorld;\r\n        for (let i = 0; i < 6; i++) {\r\n            if (frustumPlanes[i].dotCoordinate(center) <= -radius) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Tests if the bounding sphere center is in between the frustum planes.\r\n     * Used for optimistic fast inclusion.\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @returns true if the sphere center is in between the frustum planes\r\n     */\r\n    public isCenterInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        const center = this.centerWorld;\r\n        for (let i = 0; i < 6; i++) {\r\n            if (frustumPlanes[i].dotCoordinate(center) < 0) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Tests if a point is inside the bounding sphere\r\n     * @param point defines the point to test\r\n     * @returns true if the point is inside the bounding sphere\r\n     */\r\n    public intersectsPoint(point: DeepImmutable<Vector3>): boolean {\r\n        const squareDistance = Vector3.DistanceSquared(this.centerWorld, point);\r\n        if (this.radiusWorld * this.radiusWorld < squareDistance) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Checks if two sphere intersect\r\n     * @param sphere0 sphere 0\r\n     * @param sphere1 sphere 1\r\n     * @returns true if the spheres intersect\r\n     */\r\n    public static Intersects(sphere0: DeepImmutable<BoundingSphere>, sphere1: DeepImmutable<BoundingSphere>): boolean {\r\n        const squareDistance = Vector3.DistanceSquared(sphere0.centerWorld, sphere1.centerWorld);\r\n        const radiusSum = sphere0.radiusWorld + sphere1.radiusWorld;\r\n\r\n        if (radiusSum * radiusSum < squareDistance) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Creates a sphere from a center and a radius\r\n     * @param center The center\r\n     * @param radius radius\r\n     * @param matrix Optional worldMatrix\r\n     * @returns The sphere\r\n     */\r\n    public static CreateFromCenterAndRadius(center: DeepImmutable<Vector3>, radius: number, matrix?: DeepImmutable<Matrix>): BoundingSphere {\r\n        this._TmpVector3[0].copyFrom(center);\r\n        this._TmpVector3[1].copyFromFloats(0, 0, radius);\r\n        this._TmpVector3[2].copyFrom(center);\r\n        this._TmpVector3[0].addInPlace(this._TmpVector3[1]);\r\n        this._TmpVector3[2].subtractInPlace(this._TmpVector3[1]);\r\n\r\n        const sphere = new BoundingSphere(this._TmpVector3[0], this._TmpVector3[2]);\r\n\r\n        if (matrix) {\r\n            sphere._worldMatrix = matrix;\r\n        } else {\r\n            sphere._worldMatrix = Matrix.Identity();\r\n        }\r\n\r\n        return sphere;\r\n    }\r\n}\r\n","import { type DeepImmutable } from \"../types\";\r\nimport { BuildArray } from \"../Misc/arrayTools\";\r\nimport { type Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { BoundingBox } from \"./boundingBox\";\r\nimport { BoundingSphere } from \"./boundingSphere\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\n\r\nimport { type Collider } from \"../Collisions/collider\";\r\n\r\nconst _Result0 = { min: 0, max: 0 };\r\nconst _Result1 = { min: 0, max: 0 };\r\nconst ComputeBoxExtents = (axis: DeepImmutable<Vector3>, box: DeepImmutable<BoundingBox>, result: { min: number; max: number }) => {\r\n    const p = Vector3.Dot(box.centerWorld, axis);\r\n\r\n    const r0 = Math.abs(Vector3.Dot(box.directions[0], axis)) * box.extendSize.x;\r\n    const r1 = Math.abs(Vector3.Dot(box.directions[1], axis)) * box.extendSize.y;\r\n    const r2 = Math.abs(Vector3.Dot(box.directions[2], axis)) * box.extendSize.z;\r\n\r\n    const r = r0 + r1 + r2;\r\n    result.min = p - r;\r\n    result.max = p + r;\r\n};\r\n\r\nconst AxisOverlap = (axis: DeepImmutable<Vector3>, box0: DeepImmutable<BoundingBox>, box1: DeepImmutable<BoundingBox>): boolean => {\r\n    ComputeBoxExtents(axis, box0, _Result0);\r\n    ComputeBoxExtents(axis, box1, _Result1);\r\n    return !(_Result0.min > _Result1.max || _Result1.min > _Result0.max);\r\n};\r\n\r\n/**\r\n * Interface for cullable objects\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction#back-face-culling\r\n */\r\nexport interface ICullable {\r\n    /**\r\n     * Checks if the object or part of the object is in the frustum\r\n     * @param frustumPlanes Camera near/planes\r\n     * @returns true if the object is in frustum otherwise false\r\n     */\r\n    isInFrustum(frustumPlanes: Plane[]): boolean;\r\n    /**\r\n     * Checks if a cullable object (mesh...) is in the camera frustum\r\n     * Unlike isInFrustum this checks the full bounding box\r\n     * @param frustumPlanes Camera near/planes\r\n     * @returns true if the object is in frustum otherwise false\r\n     */\r\n    isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;\r\n}\r\n\r\n/**\r\n * Info for a bounding data of a mesh\r\n */\r\nexport class BoundingInfo implements ICullable {\r\n    /**\r\n     * Bounding box for the mesh\r\n     */\r\n    public readonly boundingBox: BoundingBox;\r\n    /**\r\n     * Bounding sphere for the mesh\r\n     */\r\n    public readonly boundingSphere: BoundingSphere;\r\n\r\n    private _isLocked = false;\r\n\r\n    private static readonly _TmpVector3 = BuildArray(2, Vector3.Zero);\r\n\r\n    /**\r\n     * Constructs bounding info\r\n     * @param minimum min vector of the bounding box/sphere\r\n     * @param maximum max vector of the bounding box/sphere\r\n     * @param worldMatrix defines the new world matrix\r\n     */\r\n    constructor(minimum: DeepImmutable<Vector3>, maximum: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        this.boundingBox = new BoundingBox(minimum, maximum, worldMatrix);\r\n        this.boundingSphere = new BoundingSphere(minimum, maximum, worldMatrix);\r\n    }\r\n\r\n    /**\r\n     * Recreates the entire bounding info from scratch as if we call the constructor in place\r\n     * @param min defines the new minimum vector (in local space)\r\n     * @param max defines the new maximum vector (in local space)\r\n     * @param worldMatrix defines the new world matrix\r\n     */\r\n    public reConstruct(min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        this.boundingBox.reConstruct(min, max, worldMatrix);\r\n        this.boundingSphere.reConstruct(min, max, worldMatrix);\r\n    }\r\n\r\n    /**\r\n     * min vector of the bounding box/sphere\r\n     */\r\n    public get minimum(): Vector3 {\r\n        return this.boundingBox.minimum;\r\n    }\r\n\r\n    /**\r\n     * max vector of the bounding box/sphere\r\n     */\r\n    public get maximum(): Vector3 {\r\n        return this.boundingBox.maximum;\r\n    }\r\n\r\n    /**\r\n     * If the info is locked and won't be updated to avoid perf overhead\r\n     */\r\n    public get isLocked(): boolean {\r\n        return this._isLocked;\r\n    }\r\n\r\n    public set isLocked(value: boolean) {\r\n        this._isLocked = value;\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Updates the bounding sphere and box\r\n     * @param world world matrix to be used to update\r\n     */\r\n    public update(world: DeepImmutable<Matrix>) {\r\n        if (this._isLocked) {\r\n            return;\r\n        }\r\n        this.boundingBox._update(world);\r\n        this.boundingSphere._update(world);\r\n    }\r\n\r\n    /**\r\n     * Recreate the bounding info to be centered around a specific point given a specific extend.\r\n     * @param center New center of the bounding info\r\n     * @param extend New extend of the bounding info\r\n     * @returns the current bounding info\r\n     */\r\n    public centerOn(center: DeepImmutable<Vector3>, extend: DeepImmutable<Vector3>): BoundingInfo {\r\n        const minimum = BoundingInfo._TmpVector3[0].copyFrom(center).subtractInPlace(extend);\r\n        const maximum = BoundingInfo._TmpVector3[1].copyFrom(center).addInPlace(extend);\r\n\r\n        this.boundingBox.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());\r\n        this.boundingSphere.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Grows the bounding info to include the given point.\r\n     * @param point The point that will be included in the current bounding info (in local space)\r\n     * @returns the current bounding info\r\n     */\r\n    public encapsulate(point: Vector3): BoundingInfo {\r\n        const minimum = Vector3.Minimize(this.minimum, point);\r\n        const maximum = Vector3.Maximize(this.maximum, point);\r\n        this.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Grows the bounding info to encapsulate the given bounding info.\r\n     * @param toEncapsulate The bounding info that will be encapsulated in the current bounding info\r\n     * @returns the current bounding info\r\n     */\r\n    public encapsulateBoundingInfo(toEncapsulate: BoundingInfo): BoundingInfo {\r\n        const invw = TmpVectors.Matrix[0];\r\n        this.boundingBox.getWorldMatrix().invertToRef(invw);\r\n\r\n        const v = TmpVectors.Vector3[0];\r\n\r\n        Vector3.TransformCoordinatesToRef(toEncapsulate.boundingBox.minimumWorld, invw, v);\r\n        this.encapsulate(v);\r\n\r\n        Vector3.TransformCoordinatesToRef(toEncapsulate.boundingBox.maximumWorld, invw, v);\r\n        this.encapsulate(v);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Scale the current bounding info by applying a scale factor\r\n     * @param factor defines the scale factor to apply\r\n     * @returns the current bounding info\r\n     */\r\n    public scale(factor: number): BoundingInfo {\r\n        this.boundingBox.scale(factor);\r\n        this.boundingSphere.scale(factor);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns `true` if the bounding info is within the frustum defined by the passed array of planes.\r\n     * @param frustumPlanes defines the frustum to test\r\n     * @param strategy defines the strategy to use for the culling (default is BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD)\r\n     * The different strategies available are:\r\n     * * BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD most accurate but slower @see https://doc.babylonjs.com/typedoc/classes/BABYLON.AbstractMesh#CULLINGSTRATEGY_STANDARD\r\n     * * BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY faster but less accurate @see https://doc.babylonjs.com/typedoc/classes/BABYLON.AbstractMesh#CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY\r\n     * * BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION can be faster if always visible @see https://doc.babylonjs.com/typedoc/classes/BABYLON.AbstractMesh#CULLINGSTRATEGY_OPTIMISTIC_INCLUSION\r\n     * * BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY can be faster if always visible @see https://doc.babylonjs.com/typedoc/classes/BABYLON.AbstractMesh#CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY\r\n     * @returns true if the bounding info is in the frustum planes\r\n     */\r\n    public isInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>, strategy: number = Constants.MESHES_CULLINGSTRATEGY_STANDARD): boolean {\r\n        const inclusionTest =\r\n            strategy === Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION || strategy === Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY;\r\n        if (inclusionTest) {\r\n            if (this.boundingSphere.isCenterInFrustum(frustumPlanes)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (!this.boundingSphere.isInFrustum(frustumPlanes)) {\r\n            return false;\r\n        }\r\n\r\n        const bSphereOnlyTest =\r\n            strategy === Constants.MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY || strategy === Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY;\r\n        if (bSphereOnlyTest) {\r\n            return true;\r\n        }\r\n\r\n        return this.boundingBox.isInFrustum(frustumPlanes);\r\n    }\r\n\r\n    /**\r\n     * Gets the world distance between the min and max points of the bounding box\r\n     */\r\n    public get diagonalLength(): number {\r\n        const boundingBox = this.boundingBox;\r\n        const diag = boundingBox.maximumWorld.subtractToRef(boundingBox.minimumWorld, BoundingInfo._TmpVector3[0]);\r\n        return diag.length();\r\n    }\r\n\r\n    /**\r\n     * Checks if a cullable object (mesh...) is in the camera frustum\r\n     * Unlike isInFrustum this checks the full bounding box\r\n     * @param frustumPlanes Camera near/planes\r\n     * @returns true if the object is in frustum otherwise false\r\n     */\r\n    public isCompletelyInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {\r\n        return this.boundingBox.isCompletelyInFrustum(frustumPlanes);\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public _checkCollision(collider: Collider): boolean {\r\n        return collider._canDoCollision(this.boundingSphere.centerWorld, this.boundingSphere.radiusWorld, this.boundingBox.minimumWorld, this.boundingBox.maximumWorld);\r\n    }\r\n\r\n    /**\r\n     * Checks if a point is inside the bounding box and bounding sphere or the mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/mesh_intersect\r\n     * @param point the point to check intersection with\r\n     * @returns if the point intersects\r\n     */\r\n    public intersectsPoint(point: DeepImmutable<Vector3>): boolean {\r\n        if (!this.boundingSphere.centerWorld) {\r\n            return false;\r\n        }\r\n\r\n        if (!this.boundingSphere.intersectsPoint(point)) {\r\n            return false;\r\n        }\r\n\r\n        if (!this.boundingBox.intersectsPoint(point)) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Checks if another bounding info intersects the bounding box and bounding sphere or the mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/mesh_intersect\r\n     * @param boundingInfo the bounding info to check intersection with\r\n     * @param precise if the intersection should be done using OBB\r\n     * @returns if the bounding info intersects\r\n     */\r\n    public intersects(boundingInfo: DeepImmutable<BoundingInfo>, precise: boolean): boolean {\r\n        if (!BoundingSphere.Intersects(this.boundingSphere, boundingInfo.boundingSphere)) {\r\n            return false;\r\n        }\r\n\r\n        if (!BoundingBox.Intersects(this.boundingBox, boundingInfo.boundingBox)) {\r\n            return false;\r\n        }\r\n\r\n        if (!precise) {\r\n            return true;\r\n        }\r\n\r\n        const box0 = this.boundingBox;\r\n        const box1 = boundingInfo.boundingBox;\r\n\r\n        if (!AxisOverlap(box0.directions[0], box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(box0.directions[1], box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(box0.directions[2], box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(box1.directions[0], box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(box1.directions[1], box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(box1.directions[2], box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[0], box1.directions[0]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[0], box1.directions[1]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[0], box1.directions[2]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[1], box1.directions[0]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[1], box1.directions[1]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[1], box1.directions[2]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[2], box1.directions[0]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[2], box1.directions[1]), box0, box1)) {\r\n            return false;\r\n        }\r\n        if (!AxisOverlap(Vector3.Cross(box0.directions[2], box1.directions[2]), box0, box1)) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n}\r\n","import { type FloatArray, type Nullable, type IndicesArray } from \"../types\";\r\nimport { type Vector2, Vector3 } from \"./math.vector.pure\";\r\nimport { nativeOverride } from \"../Misc/decorators\";\r\n\r\n// This helper class is only here so we can apply the nativeOverride decorator to functions.\r\nclass MathHelpers {\r\n    @nativeOverride.filter((...args: Parameters<typeof MathHelpers.extractMinAndMaxIndexed>) => !Array.isArray(args[0]) && !Array.isArray(args[1]))\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static extractMinAndMaxIndexed(positions: FloatArray, indices: IndicesArray, indexStart: number, indexCount: number, minimum: Vector3, maximum: Vector3): void {\r\n        for (let index = indexStart; index < indexStart + indexCount; index++) {\r\n            const offset = indices[index] * 3;\r\n            const x = positions[offset];\r\n            const y = positions[offset + 1];\r\n            const z = positions[offset + 2];\r\n            minimum.minimizeInPlaceFromFloats(x, y, z);\r\n            maximum.maximizeInPlaceFromFloats(x, y, z);\r\n        }\r\n    }\r\n\r\n    @nativeOverride.filter((...args: Parameters<typeof MathHelpers.extractMinAndMax>) => !Array.isArray(args[0]))\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static extractMinAndMax(positions: FloatArray, start: number, count: number, stride: number, minimum: Vector3, maximum: Vector3): void {\r\n        for (let index = start, offset = start * stride; index < start + count; index++, offset += stride) {\r\n            const x = positions[offset];\r\n            const y = positions[offset + 1];\r\n            const z = positions[offset + 2];\r\n            minimum.minimizeInPlaceFromFloats(x, y, z);\r\n            maximum.maximizeInPlaceFromFloats(x, y, z);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Extracts minimum and maximum values from a list of indexed positions\r\n * @param positions defines the positions to use\r\n * @param indices defines the indices to the positions\r\n * @param indexStart defines the start index\r\n * @param indexCount defines the end index\r\n * @param bias defines bias value to add to the result\r\n * @returns minimum and maximum values\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function extractMinAndMaxIndexed(\r\n    positions: FloatArray,\r\n    indices: IndicesArray,\r\n    indexStart: number,\r\n    indexCount: number,\r\n    bias: Nullable<Vector2> = null\r\n): { minimum: Vector3; maximum: Vector3 } {\r\n    const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n    const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n    MathHelpers.extractMinAndMaxIndexed(positions, indices, indexStart, indexCount, minimum, maximum);\r\n\r\n    if (bias) {\r\n        minimum.x -= minimum.x * bias.x + bias.y;\r\n        minimum.y -= minimum.y * bias.x + bias.y;\r\n        minimum.z -= minimum.z * bias.x + bias.y;\r\n        maximum.x += maximum.x * bias.x + bias.y;\r\n        maximum.y += maximum.y * bias.x + bias.y;\r\n        maximum.z += maximum.z * bias.x + bias.y;\r\n    }\r\n\r\n    return {\r\n        minimum: minimum,\r\n        maximum: maximum,\r\n    };\r\n}\r\n\r\n/**\r\n * Extracts minimum and maximum values from a list of positions\r\n * @param positions defines the positions to use\r\n * @param start defines the start index in the positions array\r\n * @param count defines the number of positions to handle\r\n * @param bias defines bias value to add to the result\r\n * @param stride defines the stride size to use (distance between two positions in the positions array)\r\n * @returns minimum and maximum values\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function extractMinAndMax(positions: FloatArray, start: number, count: number, bias: Nullable<Vector2> = null, stride?: number): { minimum: Vector3; maximum: Vector3 } {\r\n    const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n    const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n    if (!stride) {\r\n        stride = 3;\r\n    }\r\n\r\n    MathHelpers.extractMinAndMax(positions, start, count, stride, minimum, maximum);\r\n\r\n    if (bias) {\r\n        minimum.x -= minimum.x * bias.x + bias.y;\r\n        minimum.y -= minimum.y * bias.x + bias.y;\r\n        minimum.z -= minimum.z * bias.x + bias.y;\r\n        maximum.x += maximum.x * bias.x + bias.y;\r\n        maximum.y += maximum.y * bias.x + bias.y;\r\n        maximum.z += maximum.z * bias.x + bias.y;\r\n    }\r\n\r\n    return {\r\n        minimum: minimum,\r\n        maximum: maximum,\r\n    };\r\n}\r\n\r\n/**\r\n * Flip flipped faces\r\n * @param positions defines the positions to use\r\n * @param indices defines the indices to use and update\r\n */\r\nexport function FixFlippedFaces(positions: FloatArray, indices: IndicesArray): void {\r\n    const boundingInfo = extractMinAndMax(positions, 0, positions.length / 3);\r\n\r\n    const inside = boundingInfo.maximum.subtract(boundingInfo.minimum).scale(0.5).add(boundingInfo.minimum);\r\n    const tmpVectorA = new Vector3();\r\n    const tmpVectorB = new Vector3();\r\n    const tmpVectorC = new Vector3();\r\n    const tmpVectorAB = new Vector3();\r\n    const tmpVectorAC = new Vector3();\r\n    const tmpVectorNormal = new Vector3();\r\n    const tmpVectorAvgNormal = new Vector3();\r\n\r\n    // Clean indices\r\n    for (let index = 0; index < indices.length; index += 3) {\r\n        const a = indices[index];\r\n        const b = indices[index + 1];\r\n        const c = indices[index + 2];\r\n\r\n        // Evaluate face normal\r\n        tmpVectorA.fromArray(positions, a * 3);\r\n        tmpVectorB.fromArray(positions, b * 3);\r\n        tmpVectorC.fromArray(positions, c * 3);\r\n\r\n        tmpVectorB.subtractToRef(tmpVectorA, tmpVectorAB);\r\n        tmpVectorC.subtractToRef(tmpVectorA, tmpVectorAC);\r\n\r\n        Vector3.CrossToRef(tmpVectorAB, tmpVectorAC, tmpVectorNormal);\r\n\r\n        tmpVectorNormal.normalize();\r\n\r\n        // Calculate normal from face center to the inside of the geometry\r\n        const avgX = tmpVectorA.x + tmpVectorB.x + tmpVectorC.x;\r\n        const avgY = tmpVectorA.y + tmpVectorB.y + tmpVectorC.y;\r\n        const avgZ = tmpVectorA.z + tmpVectorB.z + tmpVectorC.z;\r\n\r\n        tmpVectorAvgNormal.set(avgX / 3, avgY / 3, avgZ / 3);\r\n        tmpVectorAvgNormal.subtractInPlace(inside);\r\n        tmpVectorAvgNormal.normalize();\r\n\r\n        if (Vector3.Dot(tmpVectorNormal, tmpVectorAvgNormal) >= 0) {\r\n            // Flip!\r\n            indices[index] = c;\r\n            indices[index + 2] = a;\r\n        }\r\n    }\r\n}\r\n","import { type IDrawContext } from \"../Engines/IDrawContext\";\r\nimport { type IMaterialContext } from \"../Engines/IMaterialContext\";\r\nimport { type Nullable } from \"../types\";\r\n\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type Effect } from \"./effect\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { TimingTools } from \"core/Misc/timingTools\";\r\n\r\n/**\r\n * Wrapper for an effect and its associated material context and draw context.\r\n * This class is meant to encapsulate the effect and its related contexts, allowing for easier management of rendering states.\r\n */\r\nexport class DrawWrapper {\r\n    /**\r\n     * The effect associated with this wrapper.\r\n     */\r\n    public effect: Nullable<Effect>;\r\n    /**\r\n     * The defines associated with this wrapper.\r\n     */\r\n    public defines: Nullable<string | MaterialDefines>;\r\n    /**\r\n     * The material context associated with this wrapper.\r\n     */\r\n    public materialContext?: IMaterialContext;\r\n    /**\r\n     * The draw context associated with this wrapper.\r\n     */\r\n    public drawContext?: IDrawContext;\r\n\r\n    /**\r\n     * @internal\r\n     * Specifies if the effect was previously ready\r\n     */\r\n    public _wasPreviouslyReady = false;\r\n\r\n    /**\r\n     * @internal\r\n     * Forces the code from bindForSubMesh to be fully run the next time it is called\r\n     */\r\n    public _forceRebindOnNextCall = true;\r\n\r\n    /**\r\n     * @internal\r\n     * Specifies if the effect was previously using instances\r\n     */\r\n    public _wasPreviouslyUsingInstances: Nullable<boolean> = null;\r\n\r\n    /**\r\n     * Retrieves the effect from a DrawWrapper or Effect instance.\r\n     * @param effect The effect or DrawWrapper instance to retrieve the effect from.\r\n     * @returns The effect associated with the given instance, or null if not found.\r\n     */\r\n    public static GetEffect(effect: Effect | DrawWrapper): Nullable<Effect> {\r\n        return (effect as Effect).getPipelineContext === undefined ? (effect as DrawWrapper).effect : (effect as Effect);\r\n    }\r\n\r\n    /**\r\n     * Creates a new DrawWrapper instance.\r\n     * Note that drawContext is always created (but may end up being undefined if the engine doesn't need draw contexts), but materialContext is optional.\r\n     * @param engine The engine to create the draw wrapper for.\r\n     * @param createMaterialContext If true, creates a material context for this wrapper (default is true).\r\n     */\r\n    constructor(engine: AbstractEngine, createMaterialContext = true) {\r\n        this.effect = null;\r\n        this.defines = null;\r\n        this.drawContext = engine.createDrawContext();\r\n        if (createMaterialContext) {\r\n            this.materialContext = engine.createMaterialContext();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the effect and its associated defines for this wrapper.\r\n     * @param effect The effect to associate with this wrapper.\r\n     * @param defines The defines to associate with this wrapper.\r\n     * @param resetContext If true, resets the draw context (default is true).\r\n     */\r\n    public setEffect(effect: Nullable<Effect>, defines?: Nullable<string | MaterialDefines>, resetContext = true): void {\r\n        if (!resetContext && this.effect !== effect) {\r\n            this.drawContext?._releaseUniformBufferSlots?.();\r\n        }\r\n        this.effect = effect;\r\n        if (defines !== undefined) {\r\n            this.defines = defines;\r\n        }\r\n        if (resetContext) {\r\n            this.drawContext?.reset();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the effect wrapper and its resources\r\n     * @param immediate if the effect should be disposed immediately or on the next frame.\r\n     * If dispose() is not called during a scene or engine dispose, we want to delay the dispose of the underlying effect. Mostly to give a chance to user code to reuse the effect in some way.\r\n     */\r\n    public dispose(immediate = false): void {\r\n        if (this.effect) {\r\n            const effect = this.effect;\r\n            if (immediate) {\r\n                effect.dispose();\r\n            } else {\r\n                TimingTools.SetImmediate(() => {\r\n                    effect.getEngine().onEndFrameObservable.addOnce(() => {\r\n                        effect.dispose();\r\n                    });\r\n                });\r\n            }\r\n            this.effect = null;\r\n        }\r\n        this.drawContext?.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type IndicesArray, type DeepImmutable, type FloatArray } from \"../types\";\r\nimport { type Matrix, type Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { IntersectionInfo } from \"../Collisions/intersectionInfo\";\r\nimport { type ICullable, BoundingInfo } from \"../Culling/boundingInfo\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { extractMinAndMaxIndexed } from \"../Maths/math.functions\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { type IMaterialContext } from \"../Engines/IMaterialContext\";\r\n\r\nimport { type Collider } from \"../Collisions/collider\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { type MaterialDefines } from \"../Materials/materialDefines\";\r\nimport { type MultiMaterial } from \"../Materials/multiMaterial.pure\";\r\nimport { type AbstractMesh } from \"./abstractMesh.pure\";\r\nimport { type Mesh } from \"./mesh.pure\";\r\nimport { type Ray, type TrianglePickingPredicate } from \"../Culling/ray.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n\r\n/**\r\n * Defines a subdivision inside a mesh\r\n */\r\nexport class SubMesh implements ICullable {\r\n    private _engine: AbstractEngine;\r\n    /** @internal */\r\n    public _drawWrappers: Array<DrawWrapper>; // index in this array = pass id\r\n    private _mainDrawWrapperOverride: Nullable<DrawWrapper> = null;\r\n\r\n    /**\r\n     * Gets material defines used by the effect associated to the sub mesh\r\n     */\r\n    public get materialDefines(): Nullable<MaterialDefines> {\r\n        const defines = this._mainDrawWrapperOverride ? this._mainDrawWrapperOverride.defines : this._getDrawWrapper()?.defines;\r\n        return typeof defines === \"string\" ? null : (defines as Nullable<MaterialDefines>);\r\n    }\r\n\r\n    /**\r\n     * Sets material defines used by the effect associated to the sub mesh\r\n     */\r\n    public set materialDefines(defines: Nullable<MaterialDefines>) {\r\n        const drawWrapper = this._mainDrawWrapperOverride ?? this._getDrawWrapper(undefined, true)!;\r\n        drawWrapper.defines = defines;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getDrawWrapper(passId?: number, createIfNotExisting = false): DrawWrapper | undefined {\r\n        passId = passId ?? this._engine.currentRenderPassId;\r\n        let drawWrapper = this._drawWrappers[passId];\r\n        if (!drawWrapper && createIfNotExisting) {\r\n            this._drawWrappers[passId] = drawWrapper = new DrawWrapper(this._mesh.getScene().getEngine());\r\n        }\r\n        return drawWrapper;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _removeDrawWrapper(passId: number, disposeWrapper = true, immediate = false): void {\r\n        if (disposeWrapper) {\r\n            this._drawWrappers[passId]?.dispose(immediate);\r\n        }\r\n        this._drawWrappers[passId] = undefined as any;\r\n    }\r\n\r\n    /**\r\n     * Gets associated (main) effect (possibly the effect override if defined)\r\n     */\r\n    public get effect(): Nullable<Effect> {\r\n        return this._mainDrawWrapperOverride ? this._mainDrawWrapperOverride.effect : (this._getDrawWrapper()?.effect ?? null);\r\n    }\r\n\r\n    /** @internal */\r\n    public get _drawWrapper(): DrawWrapper {\r\n        return this._mainDrawWrapperOverride ?? this._getDrawWrapper(undefined, true)!;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _drawWrapperOverride(): Nullable<DrawWrapper> {\r\n        return this._mainDrawWrapperOverride;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setMainDrawWrapperOverride(wrapper: Nullable<DrawWrapper>): void {\r\n        this._mainDrawWrapperOverride = wrapper;\r\n    }\r\n\r\n    /**\r\n     * Sets associated effect (effect used to render this submesh)\r\n     * @param effect defines the effect to associate with\r\n     * @param defines defines the set of defines used to compile this effect\r\n     * @param materialContext material context associated to the effect\r\n     * @param resetContext true to reset the draw context\r\n     */\r\n    public setEffect(effect: Nullable<Effect>, defines: Nullable<string | MaterialDefines> = null, materialContext?: IMaterialContext, resetContext = true) {\r\n        const drawWrapper = this._drawWrapper;\r\n        drawWrapper.setEffect(effect, defines, resetContext);\r\n        if (materialContext !== undefined) {\r\n            drawWrapper.materialContext = materialContext;\r\n        }\r\n        if (!effect) {\r\n            drawWrapper.defines = null;\r\n            drawWrapper.materialContext = undefined;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the draw wrappers cache\r\n     * @param passId If provided, releases only the draw wrapper corresponding to this render pass id\r\n     * @param immediate If true, the draw wrapper will dispose the effect immediately (false by default)\r\n     */\r\n    public resetDrawCache(passId?: number, immediate = false): void {\r\n        if (this._drawWrappers) {\r\n            if (passId !== undefined) {\r\n                this._removeDrawWrapper(passId, true, immediate);\r\n                return;\r\n            } else {\r\n                for (const drawWrapper of this._drawWrappers) {\r\n                    drawWrapper?.dispose(immediate);\r\n                }\r\n            }\r\n        }\r\n        this._drawWrappers = [];\r\n    }\r\n\r\n    /** @internal */\r\n    public _linesIndexCount: number = 0;\r\n    private _mesh: AbstractMesh;\r\n    private _renderingMesh: Mesh;\r\n    private _boundingInfo: BoundingInfo;\r\n    private _linesIndexBuffer: Nullable<DataBuffer> = null;\r\n    /** @internal */\r\n    public _lastColliderWorldVertices: Nullable<Vector3[]> = null;\r\n    /** @internal */\r\n    public _trianglePlanes: Plane[];\r\n    /** @internal */\r\n    public _lastColliderTransformMatrix: Nullable<Matrix> = null;\r\n    /** @internal */\r\n    public _wasDispatched = false;\r\n\r\n    /** @internal */\r\n    public _renderId = 0;\r\n    /** @internal */\r\n    public _alphaIndex: number = 0;\r\n    /** @internal */\r\n    public _distanceToCamera: number = 0;\r\n    /** @internal */\r\n    public _id: number;\r\n\r\n    private _currentMaterial: Nullable<Material> = null;\r\n\r\n    /**\r\n     * Add a new submesh to a mesh\r\n     * @param materialIndex defines the material index to use\r\n     * @param verticesStart defines vertex index start\r\n     * @param verticesCount defines vertices count\r\n     * @param indexStart defines index start\r\n     * @param indexCount defines indices count\r\n     * @param mesh defines the parent mesh\r\n     * @param renderingMesh defines an optional rendering mesh\r\n     * @param createBoundingBox defines if bounding box should be created for this submesh\r\n     * @returns the new submesh\r\n     */\r\n    public static AddToMesh(\r\n        materialIndex: number,\r\n        verticesStart: number,\r\n        verticesCount: number,\r\n        indexStart: number,\r\n        indexCount: number,\r\n        mesh: AbstractMesh,\r\n        renderingMesh?: Mesh,\r\n        createBoundingBox: boolean = true\r\n    ): SubMesh {\r\n        return new SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh, renderingMesh, createBoundingBox);\r\n    }\r\n\r\n    /**\r\n     * Creates a new submesh\r\n     * @param materialIndex defines the material index to use\r\n     * @param verticesStart defines vertex index start\r\n     * @param verticesCount defines vertices count\r\n     * @param indexStart defines index start\r\n     * @param indexCount defines indices count\r\n     * @param mesh defines the parent mesh\r\n     * @param renderingMesh defines an optional rendering mesh\r\n     * @param createBoundingBox defines if bounding box should be created for this submesh\r\n     * @param addToMesh defines a boolean indicating that the submesh must be added to the mesh.subMeshes array (true by default)\r\n     */\r\n    constructor(\r\n        /** the material index to use */\r\n        public materialIndex: number,\r\n        /** vertex index start */\r\n        public verticesStart: number,\r\n        /** vertices count */\r\n        public verticesCount: number,\r\n        /** index start */\r\n        public indexStart: number,\r\n        /** indices count */\r\n        public indexCount: number,\r\n        mesh: AbstractMesh,\r\n        renderingMesh?: Mesh,\r\n        createBoundingBox: boolean = true,\r\n        addToMesh = true\r\n    ) {\r\n        this._mesh = mesh;\r\n        this._renderingMesh = renderingMesh || <Mesh>mesh;\r\n        if (addToMesh) {\r\n            mesh.subMeshes.push(this);\r\n        }\r\n\r\n        this._engine = this._mesh.getScene().getEngine();\r\n        this.resetDrawCache();\r\n        this._trianglePlanes = [];\r\n\r\n        this._id = mesh.subMeshes.length - 1;\r\n\r\n        if (createBoundingBox) {\r\n            this.refreshBoundingInfo();\r\n            mesh.computeWorldMatrix(true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns true if this submesh covers the entire parent mesh\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get IsGlobal(): boolean {\r\n        return this.verticesStart === 0 && this.verticesCount === this._mesh.getTotalVertices() && this.indexStart === 0 && this.indexCount === this._mesh.getTotalIndices();\r\n    }\r\n\r\n    /**\r\n     * Returns the submesh BoundingInfo object\r\n     * @returns current bounding info (or mesh's one if the submesh is global)\r\n     */\r\n    public getBoundingInfo(): BoundingInfo {\r\n        if (this.IsGlobal || this._mesh.hasThinInstances) {\r\n            return this._mesh.getBoundingInfo();\r\n        }\r\n\r\n        return this._boundingInfo;\r\n    }\r\n\r\n    /**\r\n     * Sets the submesh BoundingInfo\r\n     * @param boundingInfo defines the new bounding info to use\r\n     * @returns the SubMesh\r\n     */\r\n    public setBoundingInfo(boundingInfo: BoundingInfo): SubMesh {\r\n        this._boundingInfo = boundingInfo;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the mesh of the current submesh\r\n     * @returns the parent mesh\r\n     */\r\n    public getMesh(): AbstractMesh {\r\n        return this._mesh;\r\n    }\r\n\r\n    /**\r\n     * Returns the rendering mesh of the submesh\r\n     * @returns the rendering mesh (could be different from parent mesh)\r\n     */\r\n    public getRenderingMesh(): Mesh {\r\n        return this._renderingMesh;\r\n    }\r\n\r\n    /**\r\n     * Returns the replacement mesh of the submesh\r\n     * @returns the replacement mesh (could be different from parent mesh)\r\n     */\r\n    public getReplacementMesh(): Nullable<AbstractMesh> {\r\n        return this._mesh._internalAbstractMeshDataInfo._actAsRegularMesh ? this._mesh : null;\r\n    }\r\n\r\n    /**\r\n     * Returns the effective mesh of the submesh\r\n     * @returns the effective mesh (could be different from parent mesh)\r\n     */\r\n    public getEffectiveMesh(): AbstractMesh {\r\n        const replacementMesh = this._mesh._internalAbstractMeshDataInfo._actAsRegularMesh ? this._mesh : null;\r\n\r\n        return replacementMesh ? replacementMesh : this._renderingMesh;\r\n    }\r\n\r\n    /**\r\n     * Returns the submesh material\r\n     * @param getDefaultMaterial Defines whether or not to get the default material if nothing has been defined.\r\n     * @returns null or the current material\r\n     */\r\n    public getMaterial(getDefaultMaterial = true): Nullable<Material> {\r\n        const rootMaterial = this._renderingMesh.getMaterialForRenderPass(this._engine.currentRenderPassId) ?? this._renderingMesh.material;\r\n\r\n        if (!rootMaterial) {\r\n            return getDefaultMaterial && this._mesh.getScene()._hasDefaultMaterial ? this._mesh.getScene().defaultMaterial : null;\r\n        } else if (this._isMultiMaterial(rootMaterial)) {\r\n            const effectiveMaterial = rootMaterial.getSubMaterial(this.materialIndex);\r\n\r\n            if (this._currentMaterial !== effectiveMaterial) {\r\n                this._currentMaterial = effectiveMaterial;\r\n                this.resetDrawCache();\r\n            }\r\n\r\n            return effectiveMaterial;\r\n        }\r\n\r\n        return rootMaterial;\r\n    }\r\n\r\n    private _isMultiMaterial(material: Material): material is MultiMaterial {\r\n        return (material as MultiMaterial).getSubMaterial !== undefined;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Sets a new updated BoundingInfo object to the submesh\r\n     * @param data defines an optional position array to use to determine the bounding info\r\n     * @returns the SubMesh\r\n     */\r\n    public refreshBoundingInfo(data: Nullable<FloatArray> = null): SubMesh {\r\n        this._lastColliderWorldVertices = null;\r\n\r\n        if (this.IsGlobal || !this._renderingMesh || !this._renderingMesh.geometry) {\r\n            return this;\r\n        }\r\n\r\n        if (!data) {\r\n            data = this._renderingMesh.getVerticesData(VertexBuffer.PositionKind);\r\n        }\r\n\r\n        if (!data) {\r\n            this._boundingInfo = this._mesh.getBoundingInfo();\r\n            return this;\r\n        }\r\n\r\n        const indices = <IndicesArray>this._renderingMesh.getIndices();\r\n        let extend: { minimum: Vector3; maximum: Vector3 };\r\n\r\n        //is this the only submesh?\r\n        if (this.indexStart === 0 && this.indexCount === indices.length) {\r\n            const boundingInfo = this._renderingMesh.getBoundingInfo();\r\n\r\n            //the rendering mesh's bounding info can be used, it is the standard submesh for all indices.\r\n            extend = { minimum: boundingInfo.minimum.clone(), maximum: boundingInfo.maximum.clone() };\r\n        } else {\r\n            extend = extractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);\r\n        }\r\n\r\n        if (this._boundingInfo) {\r\n            this._boundingInfo.reConstruct(extend.minimum, extend.maximum);\r\n        } else {\r\n            this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _checkCollision(collider: Collider): boolean {\r\n        const boundingInfo = this.getBoundingInfo();\r\n\r\n        return boundingInfo._checkCollision(collider);\r\n    }\r\n\r\n    /**\r\n     * Updates the submesh BoundingInfo\r\n     * @param world defines the world matrix to use to update the bounding info\r\n     * @returns the submesh\r\n     */\r\n    public updateBoundingInfo(world: DeepImmutable<Matrix>): SubMesh {\r\n        let boundingInfo = this.getBoundingInfo();\r\n\r\n        if (!boundingInfo) {\r\n            this.refreshBoundingInfo();\r\n            boundingInfo = this.getBoundingInfo();\r\n        }\r\n        if (boundingInfo) {\r\n            boundingInfo.update(world);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * True is the submesh bounding box intersects the frustum defined by the passed array of planes.\r\n     * @param frustumPlanes defines the frustum planes\r\n     * @returns true if the submesh is intersecting with the frustum\r\n     */\r\n    public isInFrustum(frustumPlanes: Plane[]): boolean {\r\n        const boundingInfo = this.getBoundingInfo();\r\n\r\n        if (!boundingInfo) {\r\n            return false;\r\n        }\r\n        return boundingInfo.isInFrustum(frustumPlanes, this._mesh.cullingStrategy);\r\n    }\r\n\r\n    /**\r\n     * True is the submesh bounding box is completely inside the frustum defined by the passed array of planes\r\n     * @param frustumPlanes defines the frustum planes\r\n     * @returns true if the submesh is inside the frustum\r\n     */\r\n    public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {\r\n        const boundingInfo = this.getBoundingInfo();\r\n\r\n        if (!boundingInfo) {\r\n            return false;\r\n        }\r\n        return boundingInfo.isCompletelyInFrustum(frustumPlanes);\r\n    }\r\n\r\n    /**\r\n     * Renders the submesh\r\n     * @param enableAlphaMode defines if alpha needs to be used\r\n     * @returns the submesh\r\n     */\r\n    public render(enableAlphaMode: boolean): SubMesh {\r\n        this._renderingMesh.render(this, enableAlphaMode, this._mesh._internalAbstractMeshDataInfo._actAsRegularMesh ? this._mesh : undefined);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getLinesIndexBuffer(indices: IndicesArray, engine: AbstractEngine): DataBuffer {\r\n        if (!this._linesIndexBuffer) {\r\n            const adjustedIndexCount = Math.floor(this.indexCount / 3) * 6;\r\n            const shouldUseUint32 = this.verticesStart + this.verticesCount > 65535;\r\n            const linesIndices = shouldUseUint32 ? new Uint32Array(adjustedIndexCount) : new Uint16Array(adjustedIndexCount);\r\n\r\n            let offset = 0;\r\n            if (indices.length === 0) {\r\n                // Unindexed mesh\r\n                for (let index = this.indexStart; index < this.indexStart + this.indexCount; index += 3) {\r\n                    linesIndices[offset++] = index;\r\n                    linesIndices[offset++] = index + 1;\r\n                    linesIndices[offset++] = index + 1;\r\n                    linesIndices[offset++] = index + 2;\r\n                    linesIndices[offset++] = index + 2;\r\n                    linesIndices[offset++] = index;\r\n                }\r\n            } else {\r\n                for (let index = this.indexStart; index < this.indexStart + this.indexCount; index += 3) {\r\n                    linesIndices[offset++] = indices[index];\r\n                    linesIndices[offset++] = indices[index + 1];\r\n                    linesIndices[offset++] = indices[index + 1];\r\n                    linesIndices[offset++] = indices[index + 2];\r\n                    linesIndices[offset++] = indices[index + 2];\r\n                    linesIndices[offset++] = indices[index];\r\n                }\r\n            }\r\n\r\n            this._linesIndexBuffer = engine.createIndexBuffer(linesIndices);\r\n            this._linesIndexCount = linesIndices.length;\r\n        }\r\n        return this._linesIndexBuffer;\r\n    }\r\n\r\n    /**\r\n     * Checks if the submesh intersects with a ray\r\n     * @param ray defines the ray to test\r\n     * @returns true is the passed ray intersects the submesh bounding box\r\n     */\r\n    public canIntersects(ray: Ray): boolean {\r\n        const boundingInfo = this.getBoundingInfo();\r\n\r\n        if (!boundingInfo) {\r\n            return false;\r\n        }\r\n        return ray.intersectsBox(boundingInfo.boundingBox);\r\n    }\r\n\r\n    /**\r\n     * Intersects current submesh with a ray\r\n     * @param ray defines the ray to test\r\n     * @param positions defines mesh's positions array\r\n     * @param indices defines mesh's indices array\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @returns intersection info or null if no intersection\r\n     */\r\n    public intersects(ray: Ray, positions: Vector3[], indices: IndicesArray, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<IntersectionInfo> {\r\n        const material = this.getMaterial();\r\n        if (!material) {\r\n            return null;\r\n        }\r\n        let step = 3;\r\n        let checkStopper = false;\r\n\r\n        switch (material.fillMode) {\r\n            case Constants.MATERIAL_PointListDrawMode:\r\n            case Constants.MATERIAL_LineLoopDrawMode:\r\n            case Constants.MATERIAL_LineStripDrawMode:\r\n            case Constants.MATERIAL_TriangleFanDrawMode:\r\n                return null;\r\n            case Constants.MATERIAL_TriangleStripDrawMode:\r\n                step = 1;\r\n                checkStopper = true;\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n\r\n        // LineMesh first as it's also a Mesh...\r\n        if (material.fillMode === Constants.MATERIAL_LineListDrawMode) {\r\n            // Check if mesh is unindexed\r\n            if (!indices.length) {\r\n                return this._intersectUnIndexedLines(ray, positions, indices, (this._mesh as any).intersectionThreshold, fastCheck);\r\n            }\r\n            return this._intersectLines(ray, positions, indices, (this._mesh as any).intersectionThreshold, fastCheck);\r\n        } else {\r\n            // Check if mesh is unindexed\r\n            if (!indices.length && this._mesh._unIndexed) {\r\n                return this._intersectUnIndexedTriangles(ray, positions, indices, fastCheck, trianglePredicate);\r\n            }\r\n\r\n            return this._intersectTriangles(ray, positions, indices, step, checkStopper, fastCheck, trianglePredicate);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    private _intersectLines(ray: Ray, positions: Vector3[], indices: IndicesArray, intersectionThreshold: number, fastCheck?: boolean): Nullable<IntersectionInfo> {\r\n        let intersectInfo: Nullable<IntersectionInfo> = null;\r\n\r\n        // Line test\r\n        for (let index = this.indexStart; index < this.indexStart + this.indexCount; index += 2) {\r\n            const p0 = positions[indices[index]];\r\n            const p1 = positions[indices[index + 1]];\r\n\r\n            const length = ray.intersectionSegment(p0, p1, intersectionThreshold);\r\n            if (length < 0) {\r\n                continue;\r\n            }\r\n\r\n            if (fastCheck || !intersectInfo || length < intersectInfo.distance) {\r\n                intersectInfo = new IntersectionInfo(null, null, length);\r\n                intersectInfo.faceId = index / 2;\r\n                if (fastCheck) {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        return intersectInfo;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    private _intersectUnIndexedLines(ray: Ray, positions: Vector3[], indices: IndicesArray, intersectionThreshold: number, fastCheck?: boolean): Nullable<IntersectionInfo> {\r\n        let intersectInfo: Nullable<IntersectionInfo> = null;\r\n\r\n        // Line test\r\n        for (let index = this.verticesStart; index < this.verticesStart + this.verticesCount; index += 2) {\r\n            const p0 = positions[index];\r\n            const p1 = positions[index + 1];\r\n\r\n            const length = ray.intersectionSegment(p0, p1, intersectionThreshold);\r\n            if (length < 0) {\r\n                continue;\r\n            }\r\n\r\n            if (fastCheck || !intersectInfo || length < intersectInfo.distance) {\r\n                intersectInfo = new IntersectionInfo(null, null, length);\r\n                intersectInfo.faceId = index / 2;\r\n                if (fastCheck) {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        return intersectInfo;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    private _intersectTriangles(\r\n        ray: Ray,\r\n        positions: Vector3[],\r\n        indices: IndicesArray,\r\n        step: number,\r\n        checkStopper: boolean,\r\n        fastCheck?: boolean,\r\n        trianglePredicate?: TrianglePickingPredicate\r\n    ): Nullable<IntersectionInfo> {\r\n        let intersectInfo: Nullable<IntersectionInfo> = null;\r\n\r\n        // Triangles test\r\n        let faceId = -1;\r\n        for (let index = this.indexStart; index < this.indexStart + this.indexCount - (3 - step); index += step) {\r\n            faceId++;\r\n            const indexA = indices[index];\r\n            const indexB = indices[index + 1];\r\n            const indexC = indices[index + 2];\r\n\r\n            if (checkStopper && indexC === 0xffffffff) {\r\n                index += 2;\r\n                continue;\r\n            }\r\n\r\n            const p0 = positions[indexA];\r\n            const p1 = positions[indexB];\r\n            const p2 = positions[indexC];\r\n\r\n            // stay defensive and don't check against undefined positions.\r\n            if (!p0 || !p1 || !p2) {\r\n                continue;\r\n            }\r\n\r\n            if (trianglePredicate && !trianglePredicate(p0, p1, p2, ray, indexA, indexB, indexC)) {\r\n                continue;\r\n            }\r\n\r\n            const currentIntersectInfo = ray.intersectsTriangle(p0, p1, p2);\r\n\r\n            if (currentIntersectInfo) {\r\n                if (currentIntersectInfo.distance < 0) {\r\n                    continue;\r\n                }\r\n\r\n                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {\r\n                    intersectInfo = currentIntersectInfo;\r\n                    intersectInfo.faceId = faceId;\r\n\r\n                    if (fastCheck) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return intersectInfo;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    private _intersectUnIndexedTriangles(\r\n        ray: Ray,\r\n        positions: Vector3[],\r\n        indices: IndicesArray,\r\n        fastCheck?: boolean,\r\n        trianglePredicate?: TrianglePickingPredicate\r\n    ): Nullable<IntersectionInfo> {\r\n        let intersectInfo: Nullable<IntersectionInfo> = null;\r\n        // Triangles test\r\n        for (let index = this.verticesStart; index < this.verticesStart + this.verticesCount; index += 3) {\r\n            const p0 = positions[index];\r\n            const p1 = positions[index + 1];\r\n            const p2 = positions[index + 2];\r\n\r\n            if (trianglePredicate && !trianglePredicate(p0, p1, p2, ray, -1, -1, -1)) {\r\n                continue;\r\n            }\r\n\r\n            const currentIntersectInfo = ray.intersectsTriangle(p0, p1, p2);\r\n\r\n            if (currentIntersectInfo) {\r\n                if (currentIntersectInfo.distance < 0) {\r\n                    continue;\r\n                }\r\n\r\n                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {\r\n                    intersectInfo = currentIntersectInfo;\r\n                    intersectInfo.faceId = index / 3;\r\n\r\n                    if (fastCheck) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return intersectInfo;\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        if (this._linesIndexBuffer) {\r\n            this._linesIndexBuffer = null;\r\n        }\r\n    }\r\n\r\n    // Clone\r\n    /**\r\n     * Creates a new submesh from the passed mesh\r\n     * @param newMesh defines the new hosting mesh\r\n     * @param newRenderingMesh defines an optional rendering mesh\r\n     * @returns the new submesh\r\n     */\r\n    public clone(newMesh: AbstractMesh, newRenderingMesh?: Mesh): SubMesh {\r\n        const result = new SubMesh(this.materialIndex, this.verticesStart, this.verticesCount, this.indexStart, this.indexCount, newMesh, newRenderingMesh, false);\r\n\r\n        if (!this.IsGlobal) {\r\n            const boundingInfo = this.getBoundingInfo();\r\n\r\n            if (!boundingInfo) {\r\n                return result;\r\n            }\r\n\r\n            result._boundingInfo = new BoundingInfo(boundingInfo.minimum, boundingInfo.maximum);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    // Dispose\r\n\r\n    /**\r\n     * Release associated resources\r\n     * @param immediate If true, the effect will be disposed immediately (false by default)\r\n     */\r\n    public dispose(immediate = false): void {\r\n        if (this._linesIndexBuffer) {\r\n            this._mesh.getScene().getEngine()._releaseBuffer(this._linesIndexBuffer);\r\n            this._linesIndexBuffer = null;\r\n        }\r\n\r\n        // Remove from mesh\r\n        const index = this._mesh.subMeshes.indexOf(this);\r\n        this._mesh.subMeshes.splice(index, 1);\r\n\r\n        this.resetDrawCache(undefined, immediate);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name\r\n     * @returns the string \"SubMesh\".\r\n     */\r\n    public getClassName(): string {\r\n        return \"SubMesh\";\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Creates a new submesh from indices data\r\n     * @param materialIndex the index of the main mesh material\r\n     * @param startIndex the index where to start the copy in the mesh indices array\r\n     * @param indexCount the number of indices to copy then from the startIndex\r\n     * @param mesh the main mesh to create the submesh from\r\n     * @param renderingMesh the optional rendering mesh\r\n     * @param createBoundingBox defines if bounding box should be created for this submesh\r\n     * @returns a new submesh\r\n     */\r\n    public static CreateFromIndices(\r\n        materialIndex: number,\r\n        startIndex: number,\r\n        indexCount: number,\r\n        mesh: AbstractMesh,\r\n        renderingMesh?: Mesh,\r\n        createBoundingBox: boolean = true\r\n    ): SubMesh {\r\n        let minVertexIndex = Number.MAX_VALUE;\r\n        let maxVertexIndex = -Number.MAX_VALUE;\r\n\r\n        const whatWillRender = renderingMesh || mesh;\r\n        const indices = whatWillRender.getIndices()!;\r\n\r\n        for (let index = startIndex; index < startIndex + indexCount; index++) {\r\n            const vertexIndex = indices[index];\r\n\r\n            if (vertexIndex < minVertexIndex) {\r\n                minVertexIndex = vertexIndex;\r\n            }\r\n            if (vertexIndex > maxVertexIndex) {\r\n                maxVertexIndex = vertexIndex;\r\n            }\r\n        }\r\n\r\n        return new SubMesh(materialIndex, minVertexIndex, maxVertexIndex - minVertexIndex + 1, startIndex, indexCount, mesh, renderingMesh, createBoundingBox);\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffect } from \"../Misc/devTools\";\r\n\r\nSubMesh.prototype.projectToRef ??= _MissingSideEffect(\"SubMesh\", \"projectToRef\") as any;\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/* eslint-disable jsdoc/require-returns-check */\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type Nullable, type FloatArray, type IndicesArray, type DeepImmutable } from \"../types\";\r\nimport { type Matrix, type Vector2, Vector3, Vector4, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer, VertexBufferDeduceStride } from \"../Buffers/buffer.pure\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { type Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { nativeOverride } from \"../Misc/decorators\";\r\nimport { type Coroutine, makeSyncFunction, runCoroutineSync } from \"../Misc/coroutine\";\r\nimport { type ICreateCapsuleOptions } from \"./Builders/capsuleBuilder\";\r\nimport { RuntimeError, ErrorCodes } from \"../Misc/error\";\r\n\r\nimport { type Geometry } from \"../Meshes/geometry\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { SubMesh } from \"./subMesh\";\r\n\r\n/**\r\n * Define an interface for all classes that will get and set the data on vertices\r\n */\r\nexport interface IGetSetVerticesData {\r\n    /**\r\n     * Gets a boolean indicating if specific vertex data is present\r\n     * @param kind defines the vertex data kind to use\r\n     * @returns true is data kind is present\r\n     */\r\n    isVerticesDataPresent(kind: string): boolean;\r\n    /**\r\n     * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes\r\n     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n     * @returns a float array containing vertex data\r\n     */\r\n    getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray>;\r\n    /**\r\n     * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.\r\n     * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.\r\n     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n     * @returns the indices array or an empty array if the mesh has no geometry\r\n     */\r\n    getIndices(copyWhenShared?: boolean, forceCopy?: boolean): Nullable<IndicesArray>;\r\n    /**\r\n     * Set specific vertex data\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param data defines the vertex data to use\r\n     * @param updatable defines if the vertex must be flagged as updatable (false as default)\r\n     * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified\r\n     */\r\n    setVerticesData(kind: string, data: FloatArray, updatable: boolean, stride?: number): void;\r\n    /**\r\n     * Update a specific associated vertex buffer\r\n     * @param kind defines which buffer to write to (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param data defines the data source\r\n     * @param updateExtends defines if extends info of the mesh must be updated (can be null). This is mostly useful for \"position\" kind\r\n     * @param makeItUnique defines if the geometry associated with the mesh must be cloned to make the change only for this mesh (and not all meshes associated with the same geometry)\r\n     */\r\n    updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): void;\r\n    /**\r\n     * Creates a new index buffer\r\n     * @param indices defines the indices to store in the index buffer\r\n     * @param totalVertices defines the total number of vertices (could be null)\r\n     * @param updatable defines if the index buffer must be flagged as updatable (false by default)\r\n     */\r\n    setIndices(indices: IndicesArray, totalVertices: Nullable<number>, updatable?: boolean): void;\r\n}\r\n\r\n/** Class used to attach material info to sub section of a vertex data class */\r\nexport class VertexDataMaterialInfo {\r\n    /** Defines the material index to use */\r\n    public materialIndex: number;\r\n    /** Defines vertex index start*/\r\n    public verticesStart: number;\r\n    /** Defines vertices count */\r\n    public verticesCount: number;\r\n    /** Defines index start */\r\n    public indexStart: number;\r\n    /** Defines indices count */\r\n    public indexCount: number;\r\n}\r\n\r\n/**\r\n * Interface used to define a object like a vertex data structure\r\n */\r\nexport interface IVertexDataLike {\r\n    /**\r\n     * An array of the x, y, z position of each vertex  [...., x, y, z, .....]\r\n     */\r\n    positions: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of the x, y, z normal vector of each vertex  [...., x, y, z, .....]\r\n     */\r\n    normals?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of the x, y, z, w tangent vector of each vertex  [...., x, y, z, w, .....]\r\n     */\r\n    tangents?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    uvs?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A second array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    uvs2?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A third array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    uvs3?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A fourth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    uvs4?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A fifth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    uvs5?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A sixth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    uvs6?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of the r, g, b, a, color of each vertex  [...., r, g, b, a, .....]\r\n     */\r\n    colors?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array containing the list of indices to the array of matrices produced by bones, each vertex have up to 4 indices (8 if the matricesIndicesExtra is set).\r\n     */\r\n    matricesIndices?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array containing the list of weights defining the weight of each indexed matrix in the final computation\r\n     */\r\n    matricesWeights?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array extending the number of possible indices\r\n     */\r\n    matricesIndicesExtra?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array extending the number of possible weights when the number of indices is extended\r\n     */\r\n    matricesWeightsExtra?: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of i, j, k the three vertex indices required for each triangular facet  [...., i, j, k .....]\r\n     */\r\n    indices?: Nullable<IndicesArray>;\r\n}\r\n\r\n/**\r\n * This class contains the various kinds of data on every vertex of a mesh used in determining its shape and appearance\r\n */\r\nexport class VertexData implements IVertexDataLike {\r\n    /**\r\n     * Mesh side orientation : usually the external or front surface\r\n     */\r\n    public static readonly FRONTSIDE = 0;\r\n    /**\r\n     * Mesh side orientation : usually the internal or back surface\r\n     */\r\n    public static readonly BACKSIDE = 1;\r\n    /**\r\n     * Mesh side orientation : both internal and external or front and back surfaces\r\n     */\r\n    public static readonly DOUBLESIDE = 2;\r\n    /**\r\n     * Mesh side orientation : by default, `FRONTSIDE`\r\n     */\r\n    public static readonly DEFAULTSIDE = 0;\r\n\r\n    private static _UniqueIdGenerator = 0;\r\n\r\n    /**\r\n     * An array of the x, y, z position of each vertex  [...., x, y, z, .....]\r\n     */\r\n    public positions: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of the x, y, z normal vector of each vertex  [...., x, y, z, .....]\r\n     */\r\n    public normals: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of the x, y, z, w tangent vector of each vertex  [...., x, y, z, w, .....]\r\n     */\r\n    public tangents: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    public uvs: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A second array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    public uvs2: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A third array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    public uvs3: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A fourth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    public uvs4: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A fifth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    public uvs5: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * A sixth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]\r\n     */\r\n    public uvs6: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of the r, g, b, a, color of each vertex  [...., r, g, b, a, .....]\r\n     */\r\n    public colors: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array containing the list of indices to the array of matrices produced by bones, each vertex have up to 4 indices (8 if the matricesIndicesExtra is set).\r\n     */\r\n    public matricesIndices: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array containing the list of weights defining the weight of each indexed matrix in the final computation\r\n     */\r\n    public matricesWeights: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array extending the number of possible indices\r\n     */\r\n    public matricesIndicesExtra: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array extending the number of possible weights when the number of indices is extended\r\n     */\r\n    public matricesWeightsExtra: Nullable<FloatArray>;\r\n\r\n    /**\r\n     * An array of i, j, k the three vertex indices required for each triangular facet  [...., i, j, k .....]\r\n     */\r\n    public indices: Nullable<IndicesArray>;\r\n\r\n    /**\r\n     * An array defining material association for sub sections of the vertex data\r\n     */\r\n    public materialInfos: Nullable<Array<VertexDataMaterialInfo>>;\r\n\r\n    /**\r\n     * Gets the unique ID of this vertex Data\r\n     */\r\n    public uniqueId = 0;\r\n\r\n    /**\r\n     * Metadata used to store contextual values\r\n     */\r\n    public metadata: any = {};\r\n\r\n    /**\r\n     * Gets or sets a value indicating that the mesh must be flagged with hasVertexAlpha = true\r\n     */\r\n    public hasVertexAlpha: boolean;\r\n\r\n    /**\r\n     * Creates a new VertexData\r\n     */\r\n    public constructor() {\r\n        this.uniqueId = VertexData._UniqueIdGenerator;\r\n        VertexData._UniqueIdGenerator++;\r\n    }\r\n\r\n    /**\r\n     * Uses the passed data array to set the set the values for the specified kind of data\r\n     * @param data a linear array of floating numbers\r\n     * @param kind the type of data that is being set, eg positions, colors etc\r\n     */\r\n    public set(data: FloatArray, kind: string) {\r\n        if (!data.length) {\r\n            Logger.Warn(`Setting vertex data kind '${kind}' with an empty array`);\r\n        }\r\n\r\n        switch (kind) {\r\n            case VertexBuffer.PositionKind:\r\n                this.positions = data;\r\n                break;\r\n            case VertexBuffer.NormalKind:\r\n                this.normals = data;\r\n                break;\r\n            case VertexBuffer.TangentKind:\r\n                this.tangents = data;\r\n                break;\r\n            case VertexBuffer.UVKind:\r\n                this.uvs = data;\r\n                break;\r\n            case VertexBuffer.UV2Kind:\r\n                this.uvs2 = data;\r\n                break;\r\n            case VertexBuffer.UV3Kind:\r\n                this.uvs3 = data;\r\n                break;\r\n            case VertexBuffer.UV4Kind:\r\n                this.uvs4 = data;\r\n                break;\r\n            case VertexBuffer.UV5Kind:\r\n                this.uvs5 = data;\r\n                break;\r\n            case VertexBuffer.UV6Kind:\r\n                this.uvs6 = data;\r\n                break;\r\n            case VertexBuffer.ColorKind:\r\n                this.colors = data;\r\n                break;\r\n            case VertexBuffer.MatricesIndicesKind:\r\n                this.matricesIndices = data;\r\n                break;\r\n            case VertexBuffer.MatricesWeightsKind:\r\n                this.matricesWeights = data;\r\n                break;\r\n            case VertexBuffer.MatricesIndicesExtraKind:\r\n                this.matricesIndicesExtra = data;\r\n                break;\r\n            case VertexBuffer.MatricesWeightsExtraKind:\r\n                this.matricesWeightsExtra = data;\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Associates the vertexData to the passed Mesh.\r\n     * Sets it as updatable or not (default `false`)\r\n     * @param mesh the mesh the vertexData is applied to\r\n     * @param updatable when used and having the value true allows new data to update the vertexData\r\n     * @returns the VertexData\r\n     */\r\n    public applyToMesh(mesh: Mesh, updatable?: boolean): VertexData {\r\n        this._applyTo(mesh, updatable, false);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Associates the vertexData to the passed Geometry.\r\n     * Sets it as updatable or not (default `false`)\r\n     * @param geometry the geometry the vertexData is applied to\r\n     * @param updatable when used and having the value true allows new data to update the vertexData\r\n     * @returns VertexData\r\n     */\r\n    public applyToGeometry(geometry: Geometry, updatable?: boolean): VertexData {\r\n        this._applyTo(geometry, updatable, false);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the associated mesh\r\n     * @param mesh the mesh to be updated\r\n     * @returns VertexData\r\n     */\r\n    public updateMesh(mesh: Mesh): VertexData {\r\n        this._update(mesh);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the associated geometry\r\n     * @param geometry the geometry to be updated\r\n     * @returns VertexData.\r\n     */\r\n    public updateGeometry(geometry: Geometry): VertexData {\r\n        this._update(geometry);\r\n        return this;\r\n    }\r\n\r\n    private readonly _applyTo = makeSyncFunction(this._applyToCoroutine.bind(this));\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public *_applyToCoroutine(meshOrGeometry: IGetSetVerticesData, updatable: boolean = false, isAsync: boolean): Coroutine<VertexData> {\r\n        if (this.positions) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.PositionKind, this.positions, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.normals) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.NormalKind, this.normals, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.tangents) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.TangentKind, this.tangents, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.uvs) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.UVKind, this.uvs, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.uvs2) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.UV2Kind, this.uvs2, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.uvs3) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.UV3Kind, this.uvs3, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.uvs4) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.UV4Kind, this.uvs4, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.uvs5) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.UV5Kind, this.uvs5, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.uvs6) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.UV6Kind, this.uvs6, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.colors) {\r\n            const stride = this.positions && this.colors.length === this.positions.length ? 3 : 4;\r\n            meshOrGeometry.setVerticesData(VertexBuffer.ColorKind, this.colors, updatable, stride);\r\n            if (this.hasVertexAlpha && (meshOrGeometry as any).hasVertexAlpha !== undefined) {\r\n                (meshOrGeometry as any).hasVertexAlpha = true;\r\n            }\r\n\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.matricesIndices) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.MatricesIndicesKind, this.matricesIndices, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.matricesWeights) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.matricesIndicesExtra) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.matricesWeightsExtra) {\r\n            meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        if (this.indices) {\r\n            meshOrGeometry.setIndices(this.indices, null, updatable);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        } else {\r\n            meshOrGeometry.setIndices([], null);\r\n        }\r\n\r\n        if ((meshOrGeometry as Mesh).subMeshes && this.materialInfos && this.materialInfos.length > 1) {\r\n            const mesh = meshOrGeometry as Mesh;\r\n            mesh.subMeshes = [];\r\n            for (const matInfo of this.materialInfos) {\r\n                new SubMesh(matInfo.materialIndex, matInfo.verticesStart, matInfo.verticesCount, matInfo.indexStart, matInfo.indexCount, mesh);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    private _update(meshOrGeometry: IGetSetVerticesData, updateExtends?: boolean, makeItUnique?: boolean): VertexData {\r\n        if (this.positions) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.PositionKind, this.positions, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.normals) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.NormalKind, this.normals, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.tangents) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.TangentKind, this.tangents, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.uvs) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.UVKind, this.uvs, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.uvs2) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.UV2Kind, this.uvs2, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.uvs3) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.UV3Kind, this.uvs3, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.uvs4) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.UV4Kind, this.uvs4, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.uvs5) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.UV5Kind, this.uvs5, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.uvs6) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.UV6Kind, this.uvs6, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.colors) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.ColorKind, this.colors, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.matricesIndices) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.MatricesIndicesKind, this.matricesIndices, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.matricesWeights) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.matricesIndicesExtra) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.matricesWeightsExtra) {\r\n            meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);\r\n        }\r\n\r\n        if (this.indices) {\r\n            meshOrGeometry.setIndices(this.indices, null);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    @nativeOverride.filter((...args: Parameters<typeof VertexData._TransformVector3Coordinates>) => !Array.isArray(args[0]))\r\n    private static _TransformVector3Coordinates(coordinates: FloatArray, transformation: DeepImmutable<Matrix>, offset = 0, length = coordinates.length) {\r\n        const coordinate = TmpVectors.Vector3[0];\r\n        const transformedCoordinate = TmpVectors.Vector3[1];\r\n        for (let index = offset; index < offset + length; index += 3) {\r\n            Vector3.FromArrayToRef(coordinates, index, coordinate);\r\n            Vector3.TransformCoordinatesToRef(coordinate, transformation, transformedCoordinate);\r\n            coordinates[index] = transformedCoordinate.x;\r\n            coordinates[index + 1] = transformedCoordinate.y;\r\n            coordinates[index + 2] = transformedCoordinate.z;\r\n        }\r\n    }\r\n\r\n    @nativeOverride.filter((...args: Parameters<typeof VertexData._TransformVector3Normals>) => !Array.isArray(args[0]))\r\n    private static _TransformVector3Normals(normals: FloatArray, transformation: DeepImmutable<Matrix>, offset = 0, length = normals.length) {\r\n        const normal = TmpVectors.Vector3[0];\r\n        const transformedNormal = TmpVectors.Vector3[1];\r\n        for (let index = offset; index < offset + length; index += 3) {\r\n            Vector3.FromArrayToRef(normals, index, normal);\r\n            Vector3.TransformNormalToRef(normal, transformation, transformedNormal);\r\n            normals[index] = transformedNormal.x;\r\n            normals[index + 1] = transformedNormal.y;\r\n            normals[index + 2] = transformedNormal.z;\r\n        }\r\n    }\r\n\r\n    @nativeOverride.filter((...args: Parameters<typeof VertexData._TransformVector4Normals>) => !Array.isArray(args[0]))\r\n    private static _TransformVector4Normals(normals: FloatArray, transformation: DeepImmutable<Matrix>, offset = 0, length = normals.length) {\r\n        const normal = TmpVectors.Vector4[0];\r\n        const transformedNormal = TmpVectors.Vector4[1];\r\n        for (let index = offset; index < offset + length; index += 4) {\r\n            Vector4.FromArrayToRef(normals, index, normal);\r\n            Vector4.TransformNormalToRef(normal, transformation, transformedNormal);\r\n            normals[index] = transformedNormal.x;\r\n            normals[index + 1] = transformedNormal.y;\r\n            normals[index + 2] = transformedNormal.z;\r\n            normals[index + 3] = transformedNormal.w;\r\n        }\r\n    }\r\n\r\n    @nativeOverride.filter((...args: Parameters<typeof VertexData._FlipFaces>) => !Array.isArray(args[0]))\r\n    private static _FlipFaces(indices: IndicesArray, offset = 0, length = indices.length) {\r\n        for (let index = offset; index < offset + length; index += 3) {\r\n            const tmp = indices[index + 1];\r\n            indices[index + 1] = indices[index + 2];\r\n            indices[index + 2] = tmp;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Transforms each position and each normal of the vertexData according to the passed Matrix\r\n     * @param matrix the transforming matrix\r\n     * @returns the VertexData\r\n     */\r\n    public transform(matrix: Matrix): VertexData {\r\n        const flip = matrix.determinant() < 0;\r\n        if (this.positions) {\r\n            VertexData._TransformVector3Coordinates(this.positions, matrix);\r\n        }\r\n\r\n        if (this.normals) {\r\n            VertexData._TransformVector3Normals(this.normals, matrix);\r\n        }\r\n\r\n        if (this.tangents) {\r\n            VertexData._TransformVector4Normals(this.tangents, matrix);\r\n        }\r\n\r\n        if (flip && this.indices) {\r\n            VertexData._FlipFaces(this.indices);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Generates an array of vertex data where each vertex data only has one material info\r\n     * @returns An array of VertexData\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public splitBasedOnMaterialID() {\r\n        if (!this.materialInfos || this.materialInfos.length < 2) {\r\n            return [this];\r\n        }\r\n\r\n        const result: VertexData[] = [];\r\n        for (const materialInfo of this.materialInfos) {\r\n            const vertexData = new VertexData();\r\n\r\n            if (this.positions) {\r\n                vertexData.positions = this.positions.slice(materialInfo.verticesStart * 3, (materialInfo.verticesCount + materialInfo.verticesStart) * 3);\r\n            }\r\n\r\n            if (this.normals) {\r\n                vertexData.normals = this.normals.slice(materialInfo.verticesStart * 3, (materialInfo.verticesCount + materialInfo.verticesStart) * 3);\r\n            }\r\n\r\n            if (this.tangents) {\r\n                vertexData.tangents = this.tangents.slice(materialInfo.verticesStart * 4, (materialInfo.verticesCount + materialInfo.verticesStart) * 4);\r\n            }\r\n\r\n            if (this.colors) {\r\n                vertexData.colors = this.colors.slice(materialInfo.verticesStart * 4, (materialInfo.verticesCount + materialInfo.verticesStart) * 4);\r\n            }\r\n\r\n            if (this.uvs) {\r\n                vertexData.uvs = this.uvs.slice(materialInfo.verticesStart * 2, (materialInfo.verticesCount + materialInfo.verticesStart) * 2);\r\n            }\r\n\r\n            if (this.uvs2) {\r\n                vertexData.uvs2 = this.uvs2.slice(materialInfo.verticesStart * 2, (materialInfo.verticesCount + materialInfo.verticesStart) * 2);\r\n            }\r\n\r\n            if (this.uvs3) {\r\n                vertexData.uvs3 = this.uvs3.slice(materialInfo.verticesStart * 2, (materialInfo.verticesCount + materialInfo.verticesStart) * 2);\r\n            }\r\n\r\n            if (this.uvs4) {\r\n                vertexData.uvs4 = this.uvs4.slice(materialInfo.verticesStart * 2, (materialInfo.verticesCount + materialInfo.verticesStart) * 2);\r\n            }\r\n\r\n            if (this.uvs5) {\r\n                vertexData.uvs5 = this.uvs5.slice(materialInfo.verticesStart * 2, (materialInfo.verticesCount + materialInfo.verticesStart) * 2);\r\n            }\r\n\r\n            if (this.uvs6) {\r\n                vertexData.uvs6 = this.uvs6.slice(materialInfo.verticesStart * 2, (materialInfo.verticesCount + materialInfo.verticesStart) * 2);\r\n            }\r\n\r\n            if (this.matricesIndices) {\r\n                vertexData.matricesIndices = this.matricesIndices.slice(materialInfo.verticesStart * 4, (materialInfo.verticesCount + materialInfo.verticesStart) * 4);\r\n            }\r\n\r\n            if (this.matricesIndicesExtra) {\r\n                vertexData.matricesIndicesExtra = this.matricesIndicesExtra.slice(materialInfo.verticesStart * 4, (materialInfo.verticesCount + materialInfo.verticesStart) * 4);\r\n            }\r\n\r\n            if (this.matricesWeights) {\r\n                vertexData.matricesWeights = this.matricesWeights.slice(materialInfo.verticesStart * 4, (materialInfo.verticesCount + materialInfo.verticesStart) * 4);\r\n            }\r\n\r\n            if (this.matricesWeightsExtra) {\r\n                vertexData.matricesWeightsExtra = this.matricesWeightsExtra.slice(materialInfo.verticesStart * 4, (materialInfo.verticesCount + materialInfo.verticesStart) * 4);\r\n            }\r\n\r\n            if (this.indices) {\r\n                vertexData.indices = [];\r\n                for (let index = materialInfo.indexStart; index < materialInfo.indexStart + materialInfo.indexCount; index++) {\r\n                    vertexData.indices.push(this.indices[index] - materialInfo.verticesStart);\r\n                }\r\n            }\r\n\r\n            const newMaterialInfo = new VertexDataMaterialInfo();\r\n            newMaterialInfo.indexStart = 0;\r\n            newMaterialInfo.indexCount = vertexData.indices ? vertexData.indices.length : 0;\r\n            newMaterialInfo.materialIndex = materialInfo.materialIndex;\r\n            newMaterialInfo.verticesStart = 0;\r\n            newMaterialInfo.verticesCount = (vertexData.positions ? vertexData.positions.length : 0) / 3;\r\n            vertexData.materialInfos = [newMaterialInfo];\r\n\r\n            result.push(vertexData);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Merges the passed VertexData into the current one\r\n     * @param others the VertexData to be merged into the current one\r\n     * @param use32BitsIndices defines a boolean indicating if indices must be store in a 32 bits array\r\n     * @param forceCloneIndices defines a boolean indicating if indices are forced to be cloned\r\n     * @param mergeMaterialIds defines a boolean indicating if we need to merge the material infos\r\n     * @param enableCompletion defines a boolean indicating if the vertex data should be completed to be compatible\r\n     * @returns the modified VertexData\r\n     */\r\n    public merge(others: VertexData | VertexData[], use32BitsIndices = false, forceCloneIndices = false, mergeMaterialIds = false, enableCompletion = false) {\r\n        const vertexDatas: { vertexData: VertexData; transform?: Matrix }[] = Array.isArray(others)\r\n            ? others.map((other) => {\r\n                  return { vertexData: other };\r\n              })\r\n            : [{ vertexData: others }];\r\n        return runCoroutineSync(this._mergeCoroutine(undefined, vertexDatas, use32BitsIndices, false, forceCloneIndices, mergeMaterialIds, enableCompletion));\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public *_mergeCoroutine(\r\n        transform: Matrix | undefined,\r\n        vertexDatas: { vertexData: VertexData; transform?: Matrix }[],\r\n        use32BitsIndices = false,\r\n        isAsync: boolean,\r\n        forceCloneIndices: boolean,\r\n        mergeMaterialIds = false,\r\n        enableCompletion = false\r\n    ): Coroutine<VertexData> {\r\n        this._validate();\r\n\r\n        let others = vertexDatas.map((vertexData) => vertexData.vertexData);\r\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n        let root: VertexData = this;\r\n\r\n        if (enableCompletion) {\r\n            // First let's make sure we have the max set of attributes on the main vertex data\r\n            for (const other of others) {\r\n                if (!other) {\r\n                    continue;\r\n                }\r\n\r\n                other._validate();\r\n\r\n                if (!this.normals && other.normals) {\r\n                    this.normals = new Float32Array(this.positions!.length);\r\n                }\r\n\r\n                if (!this.tangents && other.tangents) {\r\n                    this.tangents = new Float32Array((this.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (!this.uvs && other.uvs) {\r\n                    this.uvs = new Float32Array((this.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (!this.uvs2 && other.uvs2) {\r\n                    this.uvs2 = new Float32Array((this.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (!this.uvs3 && other.uvs3) {\r\n                    this.uvs3 = new Float32Array((this.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (!this.uvs4 && other.uvs4) {\r\n                    this.uvs4 = new Float32Array((this.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (!this.uvs5 && other.uvs5) {\r\n                    this.uvs5 = new Float32Array((this.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (!this.uvs6 && other.uvs6) {\r\n                    this.uvs6 = new Float32Array((this.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (!this.colors && other.colors) {\r\n                    this.colors = new Float32Array((this.positions!.length / 3) * 4);\r\n                    this.colors.fill(1); // Set to white by default\r\n                }\r\n\r\n                if (!this.matricesIndices && other.matricesIndices) {\r\n                    this.matricesIndices = new Float32Array((this.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (!this.matricesWeights && other.matricesWeights) {\r\n                    this.matricesWeights = new Float32Array((this.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (!this.matricesIndicesExtra && other.matricesIndicesExtra) {\r\n                    this.matricesIndicesExtra = new Float32Array((this.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (!this.matricesWeightsExtra && other.matricesWeightsExtra) {\r\n                    this.matricesWeightsExtra = new Float32Array((this.positions!.length / 3) * 4);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const other of others) {\r\n            if (!other) {\r\n                continue;\r\n            }\r\n\r\n            if (!enableCompletion) {\r\n                other._validate();\r\n                if (\r\n                    !this.normals !== !other.normals ||\r\n                    !this.tangents !== !other.tangents ||\r\n                    !this.uvs !== !other.uvs ||\r\n                    !this.uvs2 !== !other.uvs2 ||\r\n                    !this.uvs3 !== !other.uvs3 ||\r\n                    !this.uvs4 !== !other.uvs4 ||\r\n                    !this.uvs5 !== !other.uvs5 ||\r\n                    !this.uvs6 !== !other.uvs6 ||\r\n                    !this.colors !== !other.colors ||\r\n                    !this.matricesIndices !== !other.matricesIndices ||\r\n                    !this.matricesWeights !== !other.matricesWeights ||\r\n                    !this.matricesIndicesExtra !== !other.matricesIndicesExtra ||\r\n                    !this.matricesWeightsExtra !== !other.matricesWeightsExtra\r\n                ) {\r\n                    throw new Error(\"Cannot merge vertex data that do not have the same set of attributes\");\r\n                }\r\n            } else {\r\n                // Align the others with main set of attributes\r\n                if (this.normals && !other.normals) {\r\n                    other.normals = new Float32Array(other.positions!.length);\r\n                }\r\n\r\n                if (this.tangents && !other.tangents) {\r\n                    other.tangents = new Float32Array((other.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (this.uvs && !other.uvs) {\r\n                    other.uvs = new Float32Array((other.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (this.uvs2 && !other.uvs2) {\r\n                    other.uvs2 = new Float32Array((other.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (this.uvs3 && !other.uvs3) {\r\n                    other.uvs3 = new Float32Array((other.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (this.uvs4 && !other.uvs4) {\r\n                    other.uvs4 = new Float32Array((other.positions!.length / 3) * 2);\r\n                }\r\n                if (this.uvs5 && !other.uvs5) {\r\n                    other.uvs5 = new Float32Array((other.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (this.uvs6 && !other.uvs6) {\r\n                    other.uvs6 = new Float32Array((other.positions!.length / 3) * 2);\r\n                }\r\n\r\n                if (this.colors && !other.colors) {\r\n                    other.colors = new Float32Array((other.positions!.length / 3) * 4);\r\n                    other.colors.fill(1); // Set to white by default\r\n                }\r\n\r\n                if (this.matricesIndices && !other.matricesIndices) {\r\n                    other.matricesIndices = new Float32Array((other.positions!.length / 3) * 4);\r\n                }\r\n                if (this.matricesWeights && !other.matricesWeights) {\r\n                    other.matricesWeights = new Float32Array((other.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (this.matricesIndicesExtra && !other.matricesIndicesExtra) {\r\n                    other.matricesIndicesExtra = new Float32Array((other.positions!.length / 3) * 4);\r\n                }\r\n\r\n                if (this.matricesWeightsExtra && !other.matricesWeightsExtra) {\r\n                    other.matricesWeightsExtra = new Float32Array((other.positions!.length / 3) * 4);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (mergeMaterialIds) {\r\n            // Merge material infos\r\n            let materialIndex: number;\r\n            let indexOffset = 0;\r\n            let vertexOffset = 0;\r\n            const materialInfos: VertexDataMaterialInfo[] = [];\r\n            let currentMaterialInfo: Nullable<VertexDataMaterialInfo> = null;\r\n            const vertexDataList: { vertexData: VertexData; transform?: Matrix }[] = [];\r\n\r\n            // We need to split vertexData with more than one materialInfo\r\n            for (const split of this.splitBasedOnMaterialID()) {\r\n                vertexDataList.push({ vertexData: split, transform: transform });\r\n            }\r\n\r\n            for (const data of vertexDatas) {\r\n                if (!data.vertexData) {\r\n                    continue;\r\n                }\r\n                for (const split of data.vertexData.splitBasedOnMaterialID()) {\r\n                    vertexDataList.push({ vertexData: split, transform: data.transform });\r\n                }\r\n            }\r\n\r\n            // Sort by material IDs\r\n            vertexDataList.sort((a, b) => {\r\n                const matInfoA = a.vertexData.materialInfos ? a.vertexData.materialInfos[0].materialIndex : 0;\r\n                const matInfoB = b.vertexData.materialInfos ? b.vertexData.materialInfos[0].materialIndex : 0;\r\n\r\n                if (matInfoA > matInfoB) {\r\n                    return 1;\r\n                }\r\n\r\n                if (matInfoA === matInfoB) {\r\n                    return 0;\r\n                }\r\n\r\n                return -1;\r\n            });\r\n\r\n            // Build the new material info\r\n            for (const vertexDataSource of vertexDataList) {\r\n                const vertexData = vertexDataSource.vertexData;\r\n                if (vertexData.materialInfos) {\r\n                    materialIndex = vertexData.materialInfos[0].materialIndex;\r\n                } else {\r\n                    materialIndex = 0;\r\n                }\r\n                if (currentMaterialInfo && currentMaterialInfo.materialIndex === materialIndex) {\r\n                    currentMaterialInfo.indexCount += vertexData.indices!.length;\r\n                    currentMaterialInfo.verticesCount += vertexData.positions!.length / 3;\r\n                } else {\r\n                    const materialInfo = new VertexDataMaterialInfo();\r\n                    materialInfo.materialIndex = materialIndex;\r\n                    materialInfo.indexStart = indexOffset;\r\n                    materialInfo.indexCount = vertexData.indices!.length;\r\n                    materialInfo.verticesStart = vertexOffset;\r\n                    materialInfo.verticesCount = vertexData.positions!.length / 3;\r\n\r\n                    materialInfos.push(materialInfo);\r\n                    currentMaterialInfo = materialInfo;\r\n                }\r\n                indexOffset += vertexData.indices!.length;\r\n                vertexOffset += vertexData.positions!.length / 3;\r\n            }\r\n            // Extract sorted values\r\n            const first = vertexDataList.splice(0, 1)[0];\r\n            root = first.vertexData;\r\n            transform = first.transform;\r\n            others = vertexDataList.map((v) => v.vertexData);\r\n            vertexDatas = vertexDataList;\r\n\r\n            this.materialInfos = materialInfos;\r\n        }\r\n\r\n        // Merge geometries\r\n        const totalIndices = others.reduce((indexSum, vertexData) => indexSum + (vertexData.indices?.length ?? 0), root.indices?.length ?? 0);\r\n        const sliceIndices = forceCloneIndices || others.some((vertexData) => vertexData.indices === root.indices);\r\n        let indices = sliceIndices ? root.indices?.slice() : root.indices;\r\n        if (totalIndices > 0) {\r\n            let indicesOffset = indices?.length ?? 0;\r\n\r\n            if (!indices) {\r\n                indices = new Array<number>(totalIndices);\r\n            }\r\n\r\n            if (indices.length !== totalIndices) {\r\n                if (Array.isArray(indices)) {\r\n                    indices.length = totalIndices;\r\n                } else {\r\n                    const temp = use32BitsIndices || indices instanceof Uint32Array ? new Uint32Array(totalIndices) : new Uint16Array(totalIndices);\r\n                    temp.set(indices);\r\n                    indices = temp;\r\n                }\r\n\r\n                if (transform && transform.determinant() < 0) {\r\n                    VertexData._FlipFaces(indices, 0, indicesOffset);\r\n                }\r\n            }\r\n\r\n            let positionsOffset = root.positions ? root.positions.length / 3 : 0;\r\n            for (const { vertexData: other, transform } of vertexDatas) {\r\n                if (other.indices) {\r\n                    for (let index = 0; index < other.indices.length; index++) {\r\n                        indices[indicesOffset + index] = other.indices[index] + positionsOffset;\r\n                    }\r\n\r\n                    if (transform && transform.determinant() < 0) {\r\n                        VertexData._FlipFaces(indices, indicesOffset, other.indices.length);\r\n                    }\r\n\r\n                    // The call to _validate already checked for positions\r\n                    positionsOffset += other.positions!.length / 3;\r\n                    indicesOffset += other.indices.length;\r\n\r\n                    if (isAsync) {\r\n                        yield;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this.indices = indices!;\r\n\r\n        this.positions = VertexData._MergeElement(\r\n            VertexBuffer.PositionKind,\r\n            root.positions,\r\n            transform,\r\n            vertexDatas.map((other) => [other.vertexData.positions, other.transform])\r\n        );\r\n        if (isAsync) {\r\n            yield;\r\n        }\r\n        if (root.normals) {\r\n            this.normals = VertexData._MergeElement(\r\n                VertexBuffer.NormalKind,\r\n                root.normals,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.normals, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.tangents) {\r\n            this.tangents = VertexData._MergeElement(\r\n                VertexBuffer.TangentKind,\r\n                root.tangents,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.tangents, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.uvs) {\r\n            this.uvs = VertexData._MergeElement(\r\n                VertexBuffer.UVKind,\r\n                root.uvs,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.uvs, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.uvs2) {\r\n            this.uvs2 = VertexData._MergeElement(\r\n                VertexBuffer.UV2Kind,\r\n                root.uvs2,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.uvs2, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.uvs3) {\r\n            this.uvs3 = VertexData._MergeElement(\r\n                VertexBuffer.UV3Kind,\r\n                root.uvs3,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.uvs3, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.uvs4) {\r\n            this.uvs4 = VertexData._MergeElement(\r\n                VertexBuffer.UV4Kind,\r\n                root.uvs4,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.uvs4, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.uvs5) {\r\n            this.uvs5 = VertexData._MergeElement(\r\n                VertexBuffer.UV5Kind,\r\n                root.uvs5,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.uvs5, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.uvs6) {\r\n            this.uvs6 = VertexData._MergeElement(\r\n                VertexBuffer.UV6Kind,\r\n                root.uvs6,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.uvs6, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.colors) {\r\n            this.colors = VertexData._MergeElement(\r\n                VertexBuffer.ColorKind,\r\n                root.colors,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.colors, other.transform])\r\n            );\r\n            if (root.hasVertexAlpha !== undefined || vertexDatas.some((other) => other.vertexData.hasVertexAlpha !== undefined)) {\r\n                this.hasVertexAlpha = root.hasVertexAlpha || vertexDatas.some((other) => other.vertexData.hasVertexAlpha);\r\n            }\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.matricesIndices) {\r\n            this.matricesIndices = VertexData._MergeElement(\r\n                VertexBuffer.MatricesIndicesKind,\r\n                root.matricesIndices,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.matricesIndices, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.matricesWeights) {\r\n            this.matricesWeights = VertexData._MergeElement(\r\n                VertexBuffer.MatricesWeightsKind,\r\n                root.matricesWeights,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.matricesWeights, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.matricesIndicesExtra) {\r\n            this.matricesIndicesExtra = VertexData._MergeElement(\r\n                VertexBuffer.MatricesIndicesExtraKind,\r\n                root.matricesIndicesExtra,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.matricesIndicesExtra, other.transform])\r\n            );\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n        if (root.matricesWeightsExtra) {\r\n            this.matricesWeightsExtra = VertexData._MergeElement(\r\n                VertexBuffer.MatricesWeightsExtraKind,\r\n                root.matricesWeightsExtra,\r\n                transform,\r\n                vertexDatas.map((other) => [other.vertexData.matricesWeightsExtra, other.transform])\r\n            );\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    private static _MergeElement(\r\n        kind: string,\r\n        source: Nullable<FloatArray>,\r\n        transform: Matrix | undefined,\r\n        others: readonly (readonly [element: Nullable<FloatArray>, transform?: Matrix])[]\r\n    ): Nullable<FloatArray> {\r\n        const nonNullOthers = others.filter((other): other is [element: FloatArray, transform?: Matrix] => other[0] !== null && other[0] !== undefined);\r\n\r\n        // If there is no source to copy and no other non-null sources then skip this element.\r\n        if (!source && nonNullOthers.length == 0) {\r\n            return source;\r\n        }\r\n\r\n        if (!source) {\r\n            return this._MergeElement(kind, nonNullOthers[0][0], nonNullOthers[0][1], nonNullOthers.slice(1));\r\n        }\r\n\r\n        const len = nonNullOthers.reduce((sumLen, elements) => sumLen + elements[0].length, source.length);\r\n\r\n        const transformRange =\r\n            kind === VertexBuffer.PositionKind\r\n                ? VertexData._TransformVector3Coordinates\r\n                : kind === VertexBuffer.NormalKind\r\n                  ? VertexData._TransformVector3Normals\r\n                  : kind === VertexBuffer.TangentKind\r\n                    ? VertexData._TransformVector4Normals\r\n                    : () => {};\r\n\r\n        if (source instanceof Float32Array) {\r\n            // use non-loop method when the source is Float32Array\r\n            const ret32 = new Float32Array(len);\r\n            ret32.set(source);\r\n            transform && transformRange(ret32, transform, 0, source.length);\r\n\r\n            let offset = source.length;\r\n            for (const [vertexData, transform] of nonNullOthers) {\r\n                ret32.set(vertexData, offset);\r\n                transform && transformRange(ret32, transform, offset, vertexData.length);\r\n                offset += vertexData.length;\r\n            }\r\n            return ret32;\r\n        } else {\r\n            // don't use concat as it is super slow, just loop for other cases\r\n            const ret = new Array<number>(len);\r\n            for (let i = 0; i < source.length; i++) {\r\n                ret[i] = source[i];\r\n            }\r\n            transform && transformRange(ret, transform, 0, source.length);\r\n\r\n            let offset = source.length;\r\n            for (const [vertexData, transform] of nonNullOthers) {\r\n                for (let i = 0; i < vertexData.length; i++) {\r\n                    ret[offset + i] = vertexData[i];\r\n                }\r\n                transform && transformRange(ret, transform, offset, vertexData.length);\r\n                offset += vertexData.length;\r\n            }\r\n            return ret;\r\n        }\r\n    }\r\n\r\n    private _validate(): void {\r\n        if (!this.positions) {\r\n            throw new RuntimeError(\"Positions are required\", ErrorCodes.MeshInvalidPositionsError);\r\n        }\r\n\r\n        const getElementCount = (kind: string, values: FloatArray) => {\r\n            const stride = VertexBufferDeduceStride(kind);\r\n            if (values.length % stride !== 0) {\r\n                throw new Error(\"The \" + kind + \"s array count must be a multiple of \" + stride);\r\n            }\r\n\r\n            return values.length / stride;\r\n        };\r\n\r\n        const positionsElementCount = getElementCount(VertexBuffer.PositionKind, this.positions);\r\n\r\n        const validateElementCount = (kind: string, values: FloatArray) => {\r\n            const elementCount = getElementCount(kind, values);\r\n            if (elementCount !== positionsElementCount) {\r\n                throw new Error(\"The \" + kind + \"s element count (\" + elementCount + \") does not match the positions count (\" + positionsElementCount + \")\");\r\n            }\r\n        };\r\n\r\n        if (this.normals) {\r\n            validateElementCount(VertexBuffer.NormalKind, this.normals);\r\n        }\r\n        if (this.tangents) {\r\n            validateElementCount(VertexBuffer.TangentKind, this.tangents);\r\n        }\r\n        if (this.uvs) {\r\n            validateElementCount(VertexBuffer.UVKind, this.uvs);\r\n        }\r\n        if (this.uvs2) {\r\n            validateElementCount(VertexBuffer.UV2Kind, this.uvs2);\r\n        }\r\n        if (this.uvs3) {\r\n            validateElementCount(VertexBuffer.UV3Kind, this.uvs3);\r\n        }\r\n        if (this.uvs4) {\r\n            validateElementCount(VertexBuffer.UV4Kind, this.uvs4);\r\n        }\r\n        if (this.uvs5) {\r\n            validateElementCount(VertexBuffer.UV5Kind, this.uvs5);\r\n        }\r\n        if (this.uvs6) {\r\n            validateElementCount(VertexBuffer.UV6Kind, this.uvs6);\r\n        }\r\n        if (this.colors) {\r\n            validateElementCount(VertexBuffer.ColorKind, this.colors);\r\n        }\r\n        if (this.matricesIndices) {\r\n            validateElementCount(VertexBuffer.MatricesIndicesKind, this.matricesIndices);\r\n        }\r\n        if (this.matricesWeights) {\r\n            validateElementCount(VertexBuffer.MatricesWeightsKind, this.matricesWeights);\r\n        }\r\n        if (this.matricesIndicesExtra) {\r\n            validateElementCount(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra);\r\n        }\r\n        if (this.matricesWeightsExtra) {\r\n            validateElementCount(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the current vertex data\r\n     * @returns a copy of the current data\r\n     */\r\n    public clone() {\r\n        const serializationObject = this.serialize();\r\n        return VertexData.Parse(serializationObject);\r\n    }\r\n\r\n    /**\r\n     * Serializes the VertexData\r\n     * @returns a serialized object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        if (this.positions) {\r\n            serializationObject.positions = Array.from(this.positions);\r\n        }\r\n\r\n        if (this.normals) {\r\n            serializationObject.normals = Array.from(this.normals);\r\n        }\r\n\r\n        if (this.tangents) {\r\n            serializationObject.tangents = Array.from(this.tangents);\r\n        }\r\n\r\n        if (this.uvs) {\r\n            serializationObject.uvs = Array.from(this.uvs);\r\n        }\r\n\r\n        if (this.uvs2) {\r\n            serializationObject.uvs2 = Array.from(this.uvs2);\r\n        }\r\n\r\n        if (this.uvs3) {\r\n            serializationObject.uvs3 = Array.from(this.uvs3);\r\n        }\r\n\r\n        if (this.uvs4) {\r\n            serializationObject.uvs4 = Array.from(this.uvs4);\r\n        }\r\n\r\n        if (this.uvs5) {\r\n            serializationObject.uvs5 = Array.from(this.uvs5);\r\n        }\r\n\r\n        if (this.uvs6) {\r\n            serializationObject.uvs6 = Array.from(this.uvs6);\r\n        }\r\n\r\n        if (this.colors) {\r\n            serializationObject.colors = Array.from(this.colors);\r\n            serializationObject.hasVertexAlpha = this.hasVertexAlpha;\r\n        }\r\n\r\n        if (this.matricesIndices) {\r\n            serializationObject.matricesIndices = Array.from(this.matricesIndices);\r\n            serializationObject.matricesIndicesExpanded = true;\r\n        }\r\n\r\n        if (this.matricesWeights) {\r\n            serializationObject.matricesWeights = Array.from(this.matricesWeights);\r\n        }\r\n\r\n        if (this.matricesIndicesExtra) {\r\n            serializationObject.matricesIndicesExtra = Array.from(this.matricesIndicesExtra);\r\n            serializationObject.matricesIndicesExtraExpanded = true;\r\n        }\r\n\r\n        if (this.matricesWeightsExtra) {\r\n            serializationObject.matricesWeightsExtra = Array.from(this.matricesWeightsExtra);\r\n        }\r\n\r\n        serializationObject.indices = this.indices ? Array.from(this.indices as number[]) : [];\r\n\r\n        if (this.materialInfos) {\r\n            serializationObject.materialInfos = [];\r\n            for (const materialInfo of this.materialInfos) {\r\n                const materialInfoSerializationObject = {\r\n                    indexStart: materialInfo.indexStart,\r\n                    indexCount: materialInfo.indexCount,\r\n                    materialIndex: materialInfo.materialIndex,\r\n                    verticesStart: materialInfo.verticesStart,\r\n                    verticesCount: materialInfo.verticesCount,\r\n                };\r\n                serializationObject.materialInfos.push(materialInfoSerializationObject);\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Extracts the vertexData from a mesh\r\n     * @param mesh the mesh from which to extract the VertexData\r\n     * @param copyWhenShared defines if the VertexData must be cloned when shared between multiple meshes, optional, default false\r\n     * @param forceCopy indicating that the VertexData must be cloned, optional, default false\r\n     * @returns the object VertexData associated to the passed mesh\r\n     */\r\n    public static ExtractFromMesh(mesh: Mesh, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {\r\n        return VertexData._ExtractFrom(mesh, copyWhenShared, forceCopy);\r\n    }\r\n\r\n    /**\r\n     * Extracts the vertexData from the geometry\r\n     * @param geometry the geometry from which to extract the VertexData\r\n     * @param copyWhenShared defines if the VertexData must be cloned when the geometry is shared between multiple meshes, optional, default false\r\n     * @param forceCopy indicating that the VertexData must be cloned, optional, default false\r\n     * @returns the object VertexData associated to the passed mesh\r\n     */\r\n    public static ExtractFromGeometry(geometry: Geometry, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {\r\n        return VertexData._ExtractFrom(geometry, copyWhenShared, forceCopy);\r\n    }\r\n\r\n    private static _ExtractFrom(meshOrGeometry: IGetSetVerticesData, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {\r\n        const result = new VertexData();\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.PositionKind)) {\r\n            result.positions = meshOrGeometry.getVerticesData(VertexBuffer.PositionKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            result.normals = meshOrGeometry.getVerticesData(VertexBuffer.NormalKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n            result.tangents = meshOrGeometry.getVerticesData(VertexBuffer.TangentKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n            result.uvs = meshOrGeometry.getVerticesData(VertexBuffer.UVKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n            result.uvs2 = meshOrGeometry.getVerticesData(VertexBuffer.UV2Kind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV3Kind)) {\r\n            result.uvs3 = meshOrGeometry.getVerticesData(VertexBuffer.UV3Kind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV4Kind)) {\r\n            result.uvs4 = meshOrGeometry.getVerticesData(VertexBuffer.UV4Kind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV5Kind)) {\r\n            result.uvs5 = meshOrGeometry.getVerticesData(VertexBuffer.UV5Kind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV6Kind)) {\r\n            result.uvs6 = meshOrGeometry.getVerticesData(VertexBuffer.UV6Kind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.ColorKind)) {\r\n            const geometry = (meshOrGeometry as Mesh).geometry || (meshOrGeometry as Geometry);\r\n            const vertexBuffer = geometry.getVertexBuffer(VertexBuffer.ColorKind)!;\r\n            const colors = geometry.getVerticesData(VertexBuffer.ColorKind, copyWhenShared, forceCopy)!;\r\n            if (vertexBuffer.getSize() === 3) {\r\n                const newColors = new Float32Array((colors.length * 4) / 3);\r\n                for (let i = 0, j = 0; i < colors.length; i += 3, j += 4) {\r\n                    newColors[j] = colors[i];\r\n                    newColors[j + 1] = colors[i + 1];\r\n                    newColors[j + 2] = colors[i + 2];\r\n                    newColors[j + 3] = 1;\r\n                }\r\n                result.colors = newColors;\r\n            } else if (vertexBuffer.getSize() === 4) {\r\n                result.colors = colors;\r\n            } else {\r\n                throw new Error(`Unexpected number of color components: ${vertexBuffer.getSize()}`);\r\n            }\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesIndicesKind)) {\r\n            result.matricesIndices = meshOrGeometry.getVerticesData(VertexBuffer.MatricesIndicesKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind)) {\r\n            result.matricesWeights = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesIndicesExtraKind)) {\r\n            result.matricesIndicesExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesIndicesExtraKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesWeightsExtraKind)) {\r\n            result.matricesWeightsExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsExtraKind, copyWhenShared, forceCopy);\r\n        }\r\n\r\n        result.indices = meshOrGeometry.getIndices(copyWhenShared, forceCopy);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a Ribbon\r\n     * @param options an object used to set the following optional parameters for the ribbon, required but can be empty\r\n     * * pathArray array of paths, each of which an array of successive Vector3\r\n     * * closeArray creates a seam between the first and the last paths of the pathArray, optional, default false\r\n     * * closePath creates a seam between the first and the last points of each path of the path array, optional, default false\r\n     * * offset a positive integer, only used when pathArray contains a single path (offset = 10 means the point 1 is joined to the point 11), default rounded half size of the pathArray length\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * * invertUV swaps in the U and V coordinates when applying a texture, optional, default false\r\n     * * uvs a linear array, of length 2 * number of vertices, of custom UV values, optional\r\n     * * colors a linear array, of length 4 * number of vertices, of custom color values, optional\r\n     * @returns the VertexData of the ribbon\r\n     * @deprecated use CreateRibbonVertexData instead\r\n     */\r\n    public static CreateRibbon(options: {\r\n        pathArray: Vector3[][];\r\n        closeArray?: boolean;\r\n        closePath?: boolean;\r\n        offset?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        invertUV?: boolean;\r\n        uvs?: Vector2[];\r\n        colors?: Color4[];\r\n    }): VertexData {\r\n        throw _WarnImport(\"ribbonBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a box\r\n     * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n     * * size sets the width, height and depth of the box to the value of size, optional default 1\r\n     * * width sets the width (x direction) of the box, overwrites the width set by size, optional, default size\r\n     * * height sets the height (y direction) of the box, overwrites the height set by size, optional, default size\r\n     * * depth sets the depth (z direction) of the box, overwrites the depth set by size, optional, default size\r\n     * * faceUV an array of 6 Vector4 elements used to set different images to each box side\r\n     * * faceColors an array of 6 Color3 elements used to set different colors to each box side\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the box\r\n     * @deprecated Please use CreateBoxVertexData from the BoxBuilder file instead\r\n     */\r\n    public static CreateBox(options: {\r\n        size?: number;\r\n        width?: number;\r\n        height?: number;\r\n        depth?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"boxBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a tiled box\r\n     * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n     * - `pattern` sets the pattern\r\n     * - `width` sets the width\r\n     * - `height` sets the height\r\n     * - `depth` sets the depth\r\n     * - `tileSize` sets the tile size\r\n     * - `tileWidth` sets the tile width\r\n     * - `tileHeight` sets the tile height\r\n     * - `alignHorizontal` sets the horizontal alignment\r\n     * - `alignVertical` sets the vertical alignment\r\n     * - `faceUV` an array of 6 Vector4 elements used to set different images to each box side\r\n     * - `faceColors` an array of 6 Color3 elements used to set different colors to each box side\r\n     * - `sideOrientation` optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * @returns the VertexData of the box\r\n     * @deprecated Please use CreateTiledBoxVertexData instead\r\n     */\r\n    public static CreateTiledBox(options: {\r\n        pattern?: number;\r\n        width?: number;\r\n        height?: number;\r\n        depth?: number;\r\n        tileSize?: number;\r\n        tileWidth?: number;\r\n        tileHeight?: number;\r\n        alignHorizontal?: number;\r\n        alignVertical?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        sideOrientation?: number;\r\n    }): VertexData {\r\n        throw _WarnImport(\"tiledBoxBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a tiled plane\r\n     * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n     * * pattern a limited pattern arrangement depending on the number\r\n     * * tileSize sets the width, height and depth of the tile to the value of size, optional default 1\r\n     * * tileWidth sets the width (x direction) of the tile, overwrites the width set by size, optional, default size\r\n     * * tileHeight sets the height (y direction) of the tile, overwrites the height set by size, optional, default size\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the tiled plane\r\n     * @deprecated use CreateTiledPlaneVertexData instead\r\n     */\r\n    public static CreateTiledPlane(options: {\r\n        pattern?: number;\r\n        tileSize?: number;\r\n        tileWidth?: number;\r\n        tileHeight?: number;\r\n        size?: number;\r\n        width?: number;\r\n        height?: number;\r\n        alignHorizontal?: number;\r\n        alignVertical?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"tiledPlaneBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for an ellipsoid, defaults to a sphere\r\n     * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n     * * segments sets the number of horizontal strips optional, default 32\r\n     * * diameter sets the axes dimensions, diameterX, diameterY and diameterZ to the value of diameter, optional default 1\r\n     * * diameterX sets the diameterX (x direction) of the ellipsoid, overwrites the diameterX set by diameter, optional, default diameter\r\n     * * diameterY sets the diameterY (y direction) of the ellipsoid, overwrites the diameterY set by diameter, optional, default diameter\r\n     * * diameterZ sets the diameterZ (z direction) of the ellipsoid, overwrites the diameterZ set by diameter, optional, default diameter\r\n     * * arc a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the circumference (latitude) given by the arc value, optional, default 1\r\n     * * slice a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the height (latitude) given by the arc value, optional, default 1\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the ellipsoid\r\n     * @deprecated use CreateSphereVertexData instead\r\n     */\r\n    public static CreateSphere(options: {\r\n        segments?: number;\r\n        diameter?: number;\r\n        diameterX?: number;\r\n        diameterY?: number;\r\n        diameterZ?: number;\r\n        arc?: number;\r\n        slice?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"sphereBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a cylinder, cone or prism\r\n     * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n     * * height sets the height (y direction) of the cylinder, optional, default 2\r\n     * * diameterTop sets the diameter of the top of the cone, overwrites diameter,  optional, default diameter\r\n     * * diameterBottom sets the diameter of the bottom of the cone, overwrites diameter,  optional, default diameter\r\n     * * diameter sets the diameter of the top and bottom of the cone, optional default 1\r\n     * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24\r\n     * * `subdivisions` the number of rings along the cylinder height, optional, default 1\r\n     * * arc a number from 0 to 1, to create an unclosed cylinder based on the fraction of the circumference given by the arc value, optional, default 1\r\n     * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n     * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n     * * hasRings when true makes each subdivision independently treated as a face for faceUV and faceColors, optional, default false\r\n     * * enclose when true closes an open cylinder by adding extra flat faces between the height axis and vertical edges, think cut cake\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the cylinder, cone or prism\r\n     * @deprecated please use CreateCylinderVertexData instead\r\n     */\r\n    public static CreateCylinder(options: {\r\n        height?: number;\r\n        diameterTop?: number;\r\n        diameterBottom?: number;\r\n        diameter?: number;\r\n        tessellation?: number;\r\n        subdivisions?: number;\r\n        arc?: number;\r\n        faceColors?: Color4[];\r\n        faceUV?: Vector4[];\r\n        hasRings?: boolean;\r\n        enclose?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"cylinderBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a torus\r\n     * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n     * * diameter the diameter of the torus, optional default 1\r\n     * * thickness the diameter of the tube forming the torus, optional default 0.5\r\n     * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the torus\r\n     * @deprecated use CreateTorusVertexData instead\r\n     */\r\n    public static CreateTorus(options: {\r\n        diameter?: number;\r\n        thickness?: number;\r\n        tessellation?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"torusBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData of the LineSystem\r\n     * @param options an object used to set the following optional parameters for the LineSystem, required but can be empty\r\n     *  - lines an array of lines, each line being an array of successive Vector3\r\n     *  - colors an array of line colors, each of the line colors being an array of successive Color4, one per line point\r\n     * @returns the VertexData of the LineSystem\r\n     * @deprecated use CreateLineSystemVertexData instead\r\n     */\r\n    public static CreateLineSystem(options: { lines: Vector3[][]; colors?: Nullable<Color4[][]> }): VertexData {\r\n        throw _WarnImport(\"linesBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Create the VertexData for a DashedLines\r\n     * @param options an object used to set the following optional parameters for the DashedLines, required but can be empty\r\n     *  - points an array successive Vector3\r\n     *  - dashSize the size of the dashes relative to the dash number, optional, default 3\r\n     *  - gapSize the size of the gap between two successive dashes relative to the dash number, optional, default 1\r\n     *  - dashNb the intended total number of dashes, optional, default 200\r\n     * @returns the VertexData for the DashedLines\r\n     * @deprecated use CreateDashedLinesVertexData instead\r\n     */\r\n    public static CreateDashedLines(options: { points: Vector3[]; dashSize?: number; gapSize?: number; dashNb?: number }): VertexData {\r\n        throw _WarnImport(\"linesBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a Ground\r\n     * @param options an object used to set the following optional parameters for the Ground, required but can be empty\r\n     *  - width the width (x direction) of the ground, optional, default 1\r\n     *  - height the height (z direction) of the ground, optional, default 1\r\n     *  - subdivisions the number of subdivisions per side, optional, default 1\r\n     * @returns the VertexData of the Ground\r\n     * @deprecated Please use CreateGroundVertexData instead\r\n     */\r\n    public static CreateGround(options: { width?: number; height?: number; subdivisions?: number; subdivisionsX?: number; subdivisionsY?: number }): VertexData {\r\n        throw _WarnImport(\"groundBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a TiledGround by subdividing the ground into tiles\r\n     * @param options an object used to set the following optional parameters for the Ground, required but can be empty\r\n     * * xmin the ground minimum X coordinate, optional, default -1\r\n     * * zmin the ground minimum Z coordinate, optional, default -1\r\n     * * xmax the ground maximum X coordinate, optional, default 1\r\n     * * zmax the ground maximum Z coordinate, optional, default 1\r\n     * * subdivisions a javascript object `\\{w: positive integer, h: positive integer\\}`, `w` and `h` are the numbers of subdivisions on the ground width and height creating 'tiles', default `\\{w: 6, h: 6\\}`\r\n     * * precision a javascript object `\\{w: positive integer, h: positive integer\\}`, `w` and `h` are the numbers of subdivisions on the tile width and height, default `\\{w: 2, h: 2\\}`\r\n     * @returns the VertexData of the TiledGround\r\n     * @deprecated use CreateTiledGroundVertexData instead\r\n     */\r\n    public static CreateTiledGround(options: {\r\n        xmin: number;\r\n        zmin: number;\r\n        xmax: number;\r\n        zmax: number;\r\n        subdivisions?: { w: number; h: number };\r\n        precision?: { w: number; h: number };\r\n    }): VertexData {\r\n        throw _WarnImport(\"groundBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData of the Ground designed from a heightmap\r\n     * @param options an object used to set the following parameters for the Ground, required and provided by CreateGroundFromHeightMap\r\n     * * width the width (x direction) of the ground\r\n     * * height the height (z direction) of the ground\r\n     * * subdivisions the number of subdivisions per side\r\n     * * minHeight the minimum altitude on the ground, optional, default 0\r\n     * * maxHeight the maximum altitude on the ground, optional default 1\r\n     * * colorFilter the filter to apply to the image pixel colors to compute the height, optional Color3, default (0.3, 0.59, 0.11)\r\n     * * buffer the array holding the image color data\r\n     * * bufferWidth the width of image\r\n     * * bufferHeight the height of image\r\n     * * alphaFilter Remove any data where the alpha channel is below this value, defaults 0 (all data visible)\r\n     * @returns the VertexData of the Ground designed from a heightmap\r\n     * @deprecated use CreateGroundFromHeightMapVertexData instead\r\n     */\r\n    public static CreateGroundFromHeightMap(options: {\r\n        width: number;\r\n        height: number;\r\n        subdivisions: number;\r\n        minHeight: number;\r\n        maxHeight: number;\r\n        colorFilter: Color3;\r\n        buffer: Uint8Array;\r\n        bufferWidth: number;\r\n        bufferHeight: number;\r\n        alphaFilter: number;\r\n    }): VertexData {\r\n        throw _WarnImport(\"groundBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a Plane\r\n     * @param options an object used to set the following optional parameters for the plane, required but can be empty\r\n     * * size sets the width and height of the plane to the value of size, optional default 1\r\n     * * width sets the width (x direction) of the plane, overwrites the width set by size, optional, default size\r\n     * * height sets the height (y direction) of the plane, overwrites the height set by size, optional, default size\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the box\r\n     * @deprecated use CreatePlaneVertexData instead\r\n     */\r\n    public static CreatePlane(options: { size?: number; width?: number; height?: number; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4 }): VertexData {\r\n        throw _WarnImport(\"planeBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData of the Disc or regular Polygon\r\n     * @param options an object used to set the following optional parameters for the disc, required but can be empty\r\n     * * radius the radius of the disc, optional default 0.5\r\n     * * tessellation the number of polygon sides, optional, default 64\r\n     * * arc a number from 0 to 1, to create an unclosed polygon based on the fraction of the circumference given by the arc value, optional, default 1\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the box\r\n     * @deprecated use CreateDiscVertexData instead\r\n     */\r\n    public static CreateDisc(options: { radius?: number; tessellation?: number; arc?: number; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4 }): VertexData {\r\n        throw _WarnImport(\"discBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for an irregular Polygon in the XoZ plane using a mesh built by polygonTriangulation.build()\r\n     * All parameters are provided by CreatePolygon as needed\r\n     * @param polygon a mesh built from polygonTriangulation.build()\r\n     * @param sideOrientation takes the values Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * @param fUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n     * @param fColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n     * @param frontUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * @param backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @param wrap a boolean, default false, when true and fUVs used texture is wrapped around all sides, when false texture is applied side\r\n     * @returns the VertexData of the Polygon\r\n     * @deprecated use CreatePolygonVertexData instead\r\n     */\r\n    public static CreatePolygon(polygon: Mesh, sideOrientation: number, fUV?: Vector4[], fColors?: Color4[], frontUVs?: Vector4, backUVs?: Vector4, wrap?: boolean): VertexData {\r\n        throw _WarnImport(\"polygonBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData of the IcoSphere\r\n     * @param options an object used to set the following optional parameters for the IcoSphere, required but can be empty\r\n     * * radius the radius of the IcoSphere, optional default 1\r\n     * * radiusX allows stretching in the x direction, optional, default radius\r\n     * * radiusY allows stretching in the y direction, optional, default radius\r\n     * * radiusZ allows stretching in the z direction, optional, default radius\r\n     * * flat when true creates a flat shaded mesh, optional, default true\r\n     * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the IcoSphere\r\n     * @deprecated use CreateIcoSphereVertexData instead\r\n     */\r\n    public static CreateIcoSphere(options: {\r\n        radius?: number;\r\n        radiusX?: number;\r\n        radiusY?: number;\r\n        radiusZ?: number;\r\n        flat?: boolean;\r\n        subdivisions?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"icoSphereBuilder\");\r\n    }\r\n\r\n    // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html\r\n    /**\r\n     * Creates the VertexData for a Polyhedron\r\n     * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty\r\n     * * type provided types are:\r\n     *  * 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)\r\n     *  * 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)\r\n     * * size the size of the IcoSphere, optional default 1\r\n     * * sizeX allows stretching in the x direction, optional, default size\r\n     * * sizeY allows stretching in the y direction, optional, default size\r\n     * * sizeZ allows stretching in the z direction, optional, default size\r\n     * * custom a number that overwrites the type to create from an extended set of polyhedron from https://www.babylonjs-playground.com/#21QRSK#15 with minimised editor\r\n     * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n     * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n     * * flat when true creates a flat shaded mesh, optional, default true\r\n     * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the Polyhedron\r\n     * @deprecated use CreatePolyhedronVertexData instead\r\n     */\r\n    public static CreatePolyhedron(options: {\r\n        type?: number;\r\n        size?: number;\r\n        sizeX?: number;\r\n        sizeY?: number;\r\n        sizeZ?: number;\r\n        custom?: any;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        flat?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"polyhedronBuilder\");\r\n    }\r\n\r\n    /**\r\n     * Creates the VertexData for a Capsule, inspired from https://github.com/maximeq/three-js-capsule-geometry/blob/master/src/CapsuleBufferGeometry.js\r\n     * @param options an object used to set the following optional parameters for the capsule, required but can be empty\r\n     * @returns the VertexData of the Capsule\r\n     * @deprecated Please use CreateCapsuleVertexData from the capsuleBuilder file instead\r\n     */\r\n    public static CreateCapsule(\r\n        options: ICreateCapsuleOptions = {\r\n            orientation: Vector3.Up(),\r\n            subdivisions: 2,\r\n            tessellation: 16,\r\n            height: 1,\r\n            radius: 0.25,\r\n            capSubdivisions: 6,\r\n        }\r\n    ): VertexData {\r\n        throw _WarnImport(\"capsuleBuilder\");\r\n    }\r\n\r\n    // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473\r\n    /**\r\n     * Creates the VertexData for a TorusKnot\r\n     * @param options an object used to set the following optional parameters for the TorusKnot, required but can be empty\r\n     * * radius the radius of the torus knot, optional, default 2\r\n     * * tube the thickness of the tube, optional, default 0.5\r\n     * * radialSegments the number of sides on each tube segments, optional, default 32\r\n     * * tubularSegments the number of tubes to decompose the knot into, optional, default 32\r\n     * * p the number of windings around the z axis, optional,  default 2\r\n     * * q the number of windings around the x axis, optional,  default 3\r\n     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n     * @returns the VertexData of the Torus Knot\r\n     * @deprecated use CreateTorusKnotVertexData instead\r\n     */\r\n    public static CreateTorusKnot(options: {\r\n        radius?: number;\r\n        tube?: number;\r\n        radialSegments?: number;\r\n        tubularSegments?: number;\r\n        p?: number;\r\n        q?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    }): VertexData {\r\n        throw _WarnImport(\"torusKnotBuilder\");\r\n    }\r\n\r\n    // Tools\r\n\r\n    /**\r\n     * Compute normals for given positions and indices\r\n     * @param positions an array of vertex positions, [...., x, y, z, ......]\r\n     * @param indices an array of indices in groups of three for each triangular facet, [...., i, j, k, ......]\r\n     * @param normals an array of vertex normals, [...., x, y, z, ......]\r\n     * @param options an object used to set the following optional parameters for the TorusKnot, optional\r\n     * * facetNormals : optional array of facet normals (vector3)\r\n     * * facetPositions : optional array of facet positions (vector3)\r\n     * * facetPartitioning : optional partitioning array. facetPositions is required for facetPartitioning computation\r\n     * * ratio : optional partitioning ratio / bounding box, required for facetPartitioning computation\r\n     * * bInfo : optional bounding info, required for facetPartitioning computation\r\n     * * bbSize : optional bounding box size data, required for facetPartitioning computation\r\n     * * subDiv : optional partitioning data about subdivisions on  each axis (int), required for facetPartitioning computation\r\n     * * useRightHandedSystem: optional boolean to for right handed system computation\r\n     * * depthSort : optional boolean to enable the facet depth sort computation\r\n     * * distanceTo : optional Vector3 to compute the facet depth from this location\r\n     * * depthSortedFacets : optional array of depthSortedFacets to store the facet distances from the reference location\r\n     */\r\n    public static ComputeNormals(\r\n        positions: any,\r\n        indices: any,\r\n        normals: any,\r\n        options?: {\r\n            facetNormals?: any;\r\n            facetPositions?: any;\r\n            facetPartitioning?: any;\r\n            ratio?: number;\r\n            bInfo?: any;\r\n            bbSize?: Vector3;\r\n            subDiv?: any;\r\n            useRightHandedSystem?: boolean;\r\n            depthSort?: boolean;\r\n            distanceTo?: Vector3;\r\n            depthSortedFacets?: any;\r\n        }\r\n    ): void {\r\n        // temporary scalar variables\r\n        let index: number; // facet index\r\n        let p1p2x: number; // p1p2 vector x coordinate\r\n        let p1p2y: number; // p1p2 vector y coordinate\r\n        let p1p2z: number; // p1p2 vector z coordinate\r\n        let p3p2x: number; // p3p2 vector x coordinate\r\n        let p3p2y: number; // p3p2 vector y coordinate\r\n        let p3p2z: number; // p3p2 vector z coordinate\r\n        let faceNormalx: number; // facet normal x coordinate\r\n        let faceNormaly: number; // facet normal y coordinate\r\n        let faceNormalz: number; // facet normal z coordinate\r\n        let length: number; // facet normal length before normalization\r\n        let v1x: number; // vector1 x index in the positions array\r\n        let v1y: number; // vector1 y index in the positions array\r\n        let v1z: number; // vector1 z index in the positions array\r\n        let v2x: number; // vector2 x index in the positions array\r\n        let v2y: number; // vector2 y index in the positions array\r\n        let v2z: number; // vector2 z index in the positions array\r\n        let v3x: number; // vector3 x index in the positions array\r\n        let v3y: number; // vector3 y index in the positions array\r\n        let v3z: number; // vector3 z index in the positions array\r\n        let computeFacetNormals = false;\r\n        let computeFacetPositions = false;\r\n        let computeFacetPartitioning = false;\r\n        let computeDepthSort = false;\r\n        let faceNormalSign = 1;\r\n        let ratio = 0;\r\n        let distanceTo: Nullable<Vector3> = null;\r\n        if (options) {\r\n            computeFacetNormals = options.facetNormals ? true : false;\r\n            computeFacetPositions = options.facetPositions ? true : false;\r\n            computeFacetPartitioning = options.facetPartitioning ? true : false;\r\n            faceNormalSign = options.useRightHandedSystem === true ? -1 : 1;\r\n            ratio = options.ratio || 0;\r\n            computeDepthSort = options.depthSort ? true : false;\r\n            distanceTo = <Vector3>options.distanceTo;\r\n            if (computeDepthSort) {\r\n                if (distanceTo === undefined) {\r\n                    distanceTo = Vector3.Zero();\r\n                }\r\n            }\r\n        }\r\n\r\n        // facetPartitioning reinit if needed\r\n        let xSubRatio = 0;\r\n        let ySubRatio = 0;\r\n        let zSubRatio = 0;\r\n        let subSq = 0;\r\n        if (computeFacetPartitioning && options && options.bbSize) {\r\n            //let bbSizeMax = options.bbSize.x > options.bbSize.y ? options.bbSize.x : options.bbSize.y;\r\n            //bbSizeMax = bbSizeMax > options.bbSize.z ? bbSizeMax : options.bbSize.z;\r\n            xSubRatio = (options.subDiv.X * ratio) / options.bbSize.x;\r\n            ySubRatio = (options.subDiv.Y * ratio) / options.bbSize.y;\r\n            zSubRatio = (options.subDiv.Z * ratio) / options.bbSize.z;\r\n            subSq = options.subDiv.max * options.subDiv.max;\r\n            options.facetPartitioning.length = 0;\r\n        }\r\n\r\n        // reset the normals\r\n        for (index = 0; index < positions.length; index++) {\r\n            normals[index] = 0.0;\r\n        }\r\n\r\n        // Loop : 1 indice triplet = 1 facet\r\n        const nbFaces = (indices.length / 3) | 0;\r\n        for (index = 0; index < nbFaces; index++) {\r\n            // get the indexes of the coordinates of each vertex of the facet\r\n            v1x = indices[index * 3] * 3;\r\n            v1y = v1x + 1;\r\n            v1z = v1x + 2;\r\n            v2x = indices[index * 3 + 1] * 3;\r\n            v2y = v2x + 1;\r\n            v2z = v2x + 2;\r\n            v3x = indices[index * 3 + 2] * 3;\r\n            v3y = v3x + 1;\r\n            v3z = v3x + 2;\r\n\r\n            p1p2x = positions[v1x] - positions[v2x]; // compute two vectors per facet : p1p2 and p3p2\r\n            p1p2y = positions[v1y] - positions[v2y];\r\n            p1p2z = positions[v1z] - positions[v2z];\r\n\r\n            p3p2x = positions[v3x] - positions[v2x];\r\n            p3p2y = positions[v3y] - positions[v2y];\r\n            p3p2z = positions[v3z] - positions[v2z];\r\n\r\n            // compute the face normal with the cross product\r\n            faceNormalx = faceNormalSign * (p1p2y * p3p2z - p1p2z * p3p2y);\r\n            faceNormaly = faceNormalSign * (p1p2z * p3p2x - p1p2x * p3p2z);\r\n            faceNormalz = faceNormalSign * (p1p2x * p3p2y - p1p2y * p3p2x);\r\n            // normalize this normal and store it in the array facetData\r\n            length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);\r\n            length = length === 0 ? 1.0 : length;\r\n            faceNormalx /= length;\r\n            faceNormaly /= length;\r\n            faceNormalz /= length;\r\n\r\n            if (computeFacetNormals && options) {\r\n                options.facetNormals[index].x = faceNormalx;\r\n                options.facetNormals[index].y = faceNormaly;\r\n                options.facetNormals[index].z = faceNormalz;\r\n            }\r\n\r\n            if (computeFacetPositions && options) {\r\n                // compute and the facet barycenter coordinates in the array facetPositions\r\n                options.facetPositions[index].x = (positions[v1x] + positions[v2x] + positions[v3x]) / 3.0;\r\n                options.facetPositions[index].y = (positions[v1y] + positions[v2y] + positions[v3y]) / 3.0;\r\n                options.facetPositions[index].z = (positions[v1z] + positions[v2z] + positions[v3z]) / 3.0;\r\n            }\r\n\r\n            if (computeFacetPartitioning && options) {\r\n                // store the facet indexes in arrays in the main facetPartitioning array :\r\n                // compute each facet vertex (+ facet barycenter) index in the partiniong array\r\n                const ox = Math.floor((options.facetPositions[index].x - options.bInfo.minimum.x * ratio) * xSubRatio);\r\n                const oy = Math.floor((options.facetPositions[index].y - options.bInfo.minimum.y * ratio) * ySubRatio);\r\n                const oz = Math.floor((options.facetPositions[index].z - options.bInfo.minimum.z * ratio) * zSubRatio);\r\n                const b1x = Math.floor((positions[v1x] - options.bInfo.minimum.x * ratio) * xSubRatio);\r\n                const b1y = Math.floor((positions[v1y] - options.bInfo.minimum.y * ratio) * ySubRatio);\r\n                const b1z = Math.floor((positions[v1z] - options.bInfo.minimum.z * ratio) * zSubRatio);\r\n                const b2x = Math.floor((positions[v2x] - options.bInfo.minimum.x * ratio) * xSubRatio);\r\n                const b2y = Math.floor((positions[v2y] - options.bInfo.minimum.y * ratio) * ySubRatio);\r\n                const b2z = Math.floor((positions[v2z] - options.bInfo.minimum.z * ratio) * zSubRatio);\r\n                const b3x = Math.floor((positions[v3x] - options.bInfo.minimum.x * ratio) * xSubRatio);\r\n                const b3y = Math.floor((positions[v3y] - options.bInfo.minimum.y * ratio) * ySubRatio);\r\n                const b3z = Math.floor((positions[v3z] - options.bInfo.minimum.z * ratio) * zSubRatio);\r\n\r\n                const blockIdxV1 = b1x + options.subDiv.max * b1y + subSq * b1z;\r\n                const blockIdxV2 = b2x + options.subDiv.max * b2y + subSq * b2z;\r\n                const blockIdxV3 = b3x + options.subDiv.max * b3y + subSq * b3z;\r\n                const blockIdxV4 = ox + options.subDiv.max * oy + subSq * oz;\r\n\r\n                options.facetPartitioning[blockIdxV4] = options.facetPartitioning[blockIdxV4] ? options.facetPartitioning[blockIdxV4] : [];\r\n                options.facetPartitioning[blockIdxV1] = options.facetPartitioning[blockIdxV1] ? options.facetPartitioning[blockIdxV1] : [];\r\n                options.facetPartitioning[blockIdxV2] = options.facetPartitioning[blockIdxV2] ? options.facetPartitioning[blockIdxV2] : [];\r\n                options.facetPartitioning[blockIdxV3] = options.facetPartitioning[blockIdxV3] ? options.facetPartitioning[blockIdxV3] : [];\r\n\r\n                // push each facet index in each block containing the vertex\r\n                options.facetPartitioning[blockIdxV1].push(index);\r\n                if (blockIdxV2 != blockIdxV1) {\r\n                    options.facetPartitioning[blockIdxV2].push(index);\r\n                }\r\n                if (!(blockIdxV3 == blockIdxV2 || blockIdxV3 == blockIdxV1)) {\r\n                    options.facetPartitioning[blockIdxV3].push(index);\r\n                }\r\n                if (!(blockIdxV4 == blockIdxV1 || blockIdxV4 == blockIdxV2 || blockIdxV4 == blockIdxV3)) {\r\n                    options.facetPartitioning[blockIdxV4].push(index);\r\n                }\r\n            }\r\n\r\n            if (computeDepthSort && options && options.facetPositions) {\r\n                const dsf = options.depthSortedFacets[index];\r\n                dsf.ind = index * 3;\r\n                dsf.sqDistance = Vector3.DistanceSquared(options.facetPositions[index], distanceTo!);\r\n            }\r\n\r\n            // compute the normals anyway\r\n            normals[v1x] += faceNormalx; // accumulate all the normals per face\r\n            normals[v1y] += faceNormaly;\r\n            normals[v1z] += faceNormalz;\r\n            normals[v2x] += faceNormalx;\r\n            normals[v2y] += faceNormaly;\r\n            normals[v2z] += faceNormalz;\r\n            normals[v3x] += faceNormalx;\r\n            normals[v3y] += faceNormaly;\r\n            normals[v3z] += faceNormalz;\r\n        }\r\n        // last normalization of each normal\r\n        for (index = 0; index < normals.length / 3; index++) {\r\n            faceNormalx = normals[index * 3];\r\n            faceNormaly = normals[index * 3 + 1];\r\n            faceNormalz = normals[index * 3 + 2];\r\n\r\n            length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);\r\n            length = length === 0 ? 1.0 : length;\r\n            faceNormalx /= length;\r\n            faceNormaly /= length;\r\n            faceNormalz /= length;\r\n\r\n            normals[index * 3] = faceNormalx;\r\n            normals[index * 3 + 1] = faceNormaly;\r\n            normals[index * 3 + 2] = faceNormalz;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _ComputeSides(\r\n        sideOrientation: number,\r\n        positions: FloatArray,\r\n        indices: FloatArray | IndicesArray,\r\n        normals: FloatArray,\r\n        uvs: FloatArray,\r\n        frontUVs?: Vector4,\r\n        backUVs?: Vector4\r\n    ) {\r\n        const li: number = indices.length;\r\n        const ln: number = normals.length;\r\n        let i: number;\r\n        let n: number;\r\n        sideOrientation = sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n        switch (sideOrientation) {\r\n            case VertexData.FRONTSIDE:\r\n                // nothing changed\r\n                break;\r\n\r\n            case VertexData.BACKSIDE:\r\n                // indices\r\n                for (i = 0; i < li; i += 3) {\r\n                    const tmp = indices[i];\r\n                    indices[i] = indices[i + 2];\r\n                    indices[i + 2] = tmp;\r\n                }\r\n                // normals\r\n                for (n = 0; n < ln; n++) {\r\n                    normals[n] = -normals[n];\r\n                }\r\n                break;\r\n\r\n            case VertexData.DOUBLESIDE: {\r\n                // positions\r\n                const lp: number = positions.length;\r\n                const l: number = lp / 3;\r\n                for (let p = 0; p < lp; p++) {\r\n                    positions[lp + p] = positions[p];\r\n                }\r\n                // indices\r\n                for (i = 0; i < li; i += 3) {\r\n                    indices[i + li] = indices[i + 2] + l;\r\n                    indices[i + 1 + li] = indices[i + 1] + l;\r\n                    indices[i + 2 + li] = indices[i] + l;\r\n                }\r\n                // normals\r\n                for (n = 0; n < ln; n++) {\r\n                    normals[ln + n] = -normals[n];\r\n                }\r\n\r\n                // uvs\r\n                const lu: number = uvs.length;\r\n                let u: number;\r\n                for (u = 0; u < lu; u++) {\r\n                    uvs[u + lu] = uvs[u];\r\n                }\r\n                frontUVs = frontUVs ? frontUVs : new Vector4(0.0, 0.0, 1.0, 1.0);\r\n                backUVs = backUVs ? backUVs : new Vector4(0.0, 0.0, 1.0, 1.0);\r\n                u = 0;\r\n                for (i = 0; i < lu / 2; i++) {\r\n                    uvs[u] = frontUVs.x + (frontUVs.z - frontUVs.x) * uvs[u];\r\n                    uvs[u + 1] = frontUVs.y + (frontUVs.w - frontUVs.y) * uvs[u + 1];\r\n                    uvs[u + lu] = backUVs.x + (backUVs.z - backUVs.x) * uvs[u + lu];\r\n                    uvs[u + lu + 1] = backUVs.y + (backUVs.w - backUVs.y) * uvs[u + lu + 1];\r\n                    u += 2;\r\n                }\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a VertexData from serialized data\r\n     * @param parsedVertexData the parsed data from an imported file\r\n     * @returns a VertexData\r\n     */\r\n    public static Parse(parsedVertexData: any) {\r\n        const vertexData = new VertexData();\r\n\r\n        // positions\r\n        const positions = parsedVertexData.positions;\r\n        if (positions) {\r\n            vertexData.set(positions, VertexBuffer.PositionKind);\r\n        }\r\n\r\n        // normals\r\n        const normals = parsedVertexData.normals;\r\n        if (normals) {\r\n            vertexData.set(normals, VertexBuffer.NormalKind);\r\n        }\r\n\r\n        // tangents\r\n        const tangents = parsedVertexData.tangents;\r\n        if (tangents) {\r\n            vertexData.set(tangents, VertexBuffer.TangentKind);\r\n        }\r\n\r\n        // uvs\r\n        const uvs = parsedVertexData.uvs;\r\n        if (uvs) {\r\n            vertexData.set(uvs, VertexBuffer.UVKind);\r\n        }\r\n\r\n        // uv2s\r\n        const uvs2 = parsedVertexData.uvs2;\r\n        if (uvs2) {\r\n            vertexData.set(uvs2, VertexBuffer.UV2Kind);\r\n        }\r\n\r\n        // uv3s\r\n        const uvs3 = parsedVertexData.uvs3;\r\n        if (uvs3) {\r\n            vertexData.set(uvs3, VertexBuffer.UV3Kind);\r\n        }\r\n\r\n        // uv4s\r\n        const uvs4 = parsedVertexData.uvs4;\r\n        if (uvs4) {\r\n            vertexData.set(uvs4, VertexBuffer.UV4Kind);\r\n        }\r\n\r\n        // uv5s\r\n        const uvs5 = parsedVertexData.uvs5;\r\n        if (uvs5) {\r\n            vertexData.set(uvs5, VertexBuffer.UV5Kind);\r\n        }\r\n\r\n        // uv6s\r\n        const uvs6 = parsedVertexData.uvs6;\r\n        if (uvs6) {\r\n            vertexData.set(uvs6, VertexBuffer.UV6Kind);\r\n        }\r\n\r\n        // colors\r\n        const colors = parsedVertexData.colors;\r\n        if (colors) {\r\n            vertexData.set(Color4.CheckColors4(colors, positions.length / 3), VertexBuffer.ColorKind);\r\n            if (parsedVertexData.hasVertexAlpha !== undefined) {\r\n                vertexData.hasVertexAlpha = parsedVertexData.hasVertexAlpha;\r\n            }\r\n        }\r\n\r\n        // matricesIndices\r\n        const matricesIndices = parsedVertexData.matricesIndices;\r\n        if (matricesIndices) {\r\n            vertexData.set(matricesIndices, VertexBuffer.MatricesIndicesKind);\r\n        }\r\n\r\n        // matricesWeights\r\n        const matricesWeights = parsedVertexData.matricesWeights;\r\n        if (matricesWeights) {\r\n            vertexData.set(matricesWeights, VertexBuffer.MatricesWeightsKind);\r\n        }\r\n\r\n        // indices\r\n        const indices = parsedVertexData.indices;\r\n        if (indices) {\r\n            vertexData.indices = indices;\r\n        }\r\n\r\n        // MaterialInfos\r\n        const materialInfos = parsedVertexData.materialInfos;\r\n        if (materialInfos) {\r\n            vertexData.materialInfos = [];\r\n            for (const materialInfoFromJSON of materialInfos) {\r\n                const materialInfo = new VertexDataMaterialInfo();\r\n                materialInfo.indexCount = materialInfoFromJSON.indexCount;\r\n                materialInfo.indexStart = materialInfoFromJSON.indexStart;\r\n                materialInfo.verticesCount = materialInfoFromJSON.verticesCount;\r\n                materialInfo.verticesStart = materialInfoFromJSON.verticesStart;\r\n                materialInfo.materialIndex = materialInfoFromJSON.materialIndex;\r\n                vertexData.materialInfos.push(materialInfo);\r\n            }\r\n        }\r\n\r\n        return vertexData;\r\n    }\r\n\r\n    /**\r\n     * Applies VertexData created from the imported parameters to the geometry\r\n     * @param parsedVertexData the parsed data from an imported file\r\n     * @param geometry the geometry to apply the VertexData to\r\n     */\r\n    public static ImportVertexData(parsedVertexData: any, geometry: Geometry) {\r\n        const vertexData = VertexData.Parse(parsedVertexData);\r\n\r\n        geometry.setAllVerticesData(vertexData, parsedVertexData.updatable);\r\n    }\r\n}\r\n","import { type Collider } from \"./collider\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer } from \"../Misc/observable\";\r\n\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _MeshCollisionData {\r\n    public _checkCollisions = false;\r\n    public _collisionMask = -1;\r\n    public _collisionGroup = -1;\r\n    public _surroundingMeshes: Nullable<AbstractMesh[]> = null;\r\n    public _collider: Nullable<Collider> = null;\r\n    public _oldPositionForCollisions = new Vector3(0, 0, 0);\r\n    public _diffPositionForCollisions = new Vector3(0, 0, 0);\r\n    public _onCollideObserver: Nullable<Observer<AbstractMesh>>;\r\n    public _onCollisionPositionChangeObserver: Nullable<Observer<Vector3>>;\r\n    public _collisionResponse = true;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { type Nullable, type FloatArray, type IndicesArray, type DeepImmutable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Scene, type IDisposable, ScenePerformancePriority } from \"../scene.pure\";\r\nimport { type Vector2, type Vector4, Quaternion, Matrix, Vector3, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type IGetSetVerticesData, VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type IntersectionInfo } from \"../Collisions/intersectionInfo\";\r\nimport { type ICullable, BoundingInfo } from \"../Culling/boundingInfo\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { type MaterialDefines } from \"../Materials/materialDefines\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { type Skeleton } from \"../Bones/skeleton\";\r\nimport { type MorphTargetManager } from \"../Morph/morphTargetManager\";\r\nimport { type IBakedVertexAnimationManager } from \"../BakedVertexAnimation/bakedVertexAnimationManager\";\r\nimport { type IEdgesRenderer, type IEdgesRendererOptions } from \"../Rendering/edgesRenderer.pure\";\r\nimport { type SolidParticle } from \"../Particles/solidParticle\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type AbstractActionManager } from \"../Actions/abstractActionManager\";\r\nimport { UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { _MeshCollisionData } from \"../Collisions/meshCollisionData\";\r\nimport { _WarnImport, _MissingSideEffect, _MissingSideEffectProperty } from \"../Misc/devTools\";\r\nimport { FromHalfFloat } from \"../Misc/halfFloat\";\r\nimport { type RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { extractMinAndMax } from \"../Maths/math.functions\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\nimport { Axis } from \"../Maths/math.axis\";\r\nimport { type IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\nimport { type Ray, type TrianglePickingPredicate } from \"../Culling/ray.pure\";\r\nimport { type Collider } from \"../Collisions/collider\";\r\nimport { type RenderingGroup } from \"../Rendering/renderingGroup\";\r\nimport { type MorphTarget } from \"../Morph/morphTarget\";\r\nimport { type Geometry } from \"./geometry\";\r\nimport { nativeOverride } from \"../Misc/decorators\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nfunction ApplyMorph(data: FloatArray, kind: string, morphTargetManager: MorphTargetManager): void {\r\n    let getTargetData: Nullable<(target: MorphTarget) => Nullable<FloatArray>>;\r\n    switch (kind) {\r\n        case VertexBuffer.PositionKind:\r\n            getTargetData = (target) => target.getPositions();\r\n            break;\r\n        case VertexBuffer.NormalKind:\r\n            getTargetData = (target) => target.getNormals();\r\n            break;\r\n        case VertexBuffer.TangentKind:\r\n            getTargetData = (target) => target.getTangents();\r\n            break;\r\n        case VertexBuffer.UVKind:\r\n            getTargetData = (target) => target.getUVs();\r\n            break;\r\n        case VertexBuffer.UV2Kind:\r\n            getTargetData = (target) => target.getUV2s();\r\n            break;\r\n        case VertexBuffer.ColorKind:\r\n            getTargetData = (target) => target.getColors();\r\n            break;\r\n        default:\r\n            return;\r\n    }\r\n\r\n    for (let index = 0; index < data.length; index++) {\r\n        let value = data[index];\r\n        for (let targetCount = 0; targetCount < morphTargetManager.numTargets; targetCount++) {\r\n            const target = morphTargetManager.getTarget(targetCount);\r\n            const influence = target.influence;\r\n            if (influence !== 0) {\r\n                const targetData = getTargetData(target);\r\n                if (targetData) {\r\n                    value += (targetData[index] - data[index]) * influence;\r\n                }\r\n            }\r\n        }\r\n        data[index] = value;\r\n    }\r\n}\r\n\r\nfunction ApplySkeleton(\r\n    data: FloatArray,\r\n    kind: string,\r\n    skeletonMatrices: Float32Array,\r\n    matricesIndicesData: FloatArray,\r\n    matricesWeightsData: FloatArray,\r\n    matricesIndicesExtraData: Nullable<FloatArray>,\r\n    matricesWeightsExtraData: Nullable<FloatArray>\r\n): void {\r\n    const tempVector = TmpVectors.Vector3[0];\r\n    const finalMatrix = TmpVectors.Matrix[0];\r\n    const tempMatrix = TmpVectors.Matrix[1];\r\n\r\n    const transformFromFloatsToRef = kind === VertexBuffer.NormalKind ? Vector3.TransformNormalFromFloatsToRef : Vector3.TransformCoordinatesFromFloatsToRef;\r\n\r\n    for (let index = 0, matWeightIdx = 0; index < data.length; index += 3, matWeightIdx += 4) {\r\n        finalMatrix.reset();\r\n\r\n        let inf: number;\r\n        let weight: number;\r\n        for (inf = 0; inf < 4; inf++) {\r\n            weight = matricesWeightsData[matWeightIdx + inf];\r\n            if (weight > 0) {\r\n                Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[matWeightIdx + inf] * 16), weight, tempMatrix);\r\n                finalMatrix.addToSelf(tempMatrix);\r\n            }\r\n        }\r\n        if (matricesIndicesExtraData && matricesWeightsExtraData) {\r\n            for (inf = 0; inf < 4; inf++) {\r\n                weight = matricesWeightsExtraData[matWeightIdx + inf];\r\n                if (weight > 0) {\r\n                    Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[matWeightIdx + inf] * 16), weight, tempMatrix);\r\n                    finalMatrix.addToSelf(tempMatrix);\r\n                }\r\n            }\r\n        }\r\n\r\n        transformFromFloatsToRef(data[index], data[index + 1], data[index + 2], finalMatrix, tempVector);\r\n        tempVector.toArray(data, index);\r\n    }\r\n}\r\n\r\nfunction BakedVertexAnimationModulo(value: number, divisor: number): number {\r\n    return value - Math.floor(value / divisor) * divisor;\r\n}\r\n\r\nfunction GetBakedVertexAnimationFrame(animationSettings: DeepImmutable<Vector4>, time: number): number {\r\n    const totalFrames = animationSettings.y - animationSettings.x + 1;\r\n    const normalizedTime = (time * animationSettings.w) / totalFrames;\r\n    const frameCorrection = normalizedTime < 1 ? 0 : 1;\r\n    const numOfFrames = totalFrames - frameCorrection;\r\n\r\n    let frameNum = BakedVertexAnimationModulo(normalizedTime - Math.floor(normalizedTime), 1) * numOfFrames;\r\n    frameNum = BakedVertexAnimationModulo(frameNum + animationSettings.z, numOfFrames);\r\n    return Math.floor(frameNum) + animationSettings.x + frameCorrection;\r\n}\r\n\r\nfunction ReadBakedVertexAnimationMatrixToRef(data: Float32Array | Uint16Array, offset: number, matrix: Matrix): void {\r\n    if (data instanceof Float32Array) {\r\n        Matrix.FromArrayToRef(data, offset, matrix);\r\n        return;\r\n    }\r\n\r\n    matrix.copyFromFloats(\r\n        FromHalfFloat(data[offset]),\r\n        FromHalfFloat(data[offset + 1]),\r\n        FromHalfFloat(data[offset + 2]),\r\n        FromHalfFloat(data[offset + 3]),\r\n        FromHalfFloat(data[offset + 4]),\r\n        FromHalfFloat(data[offset + 5]),\r\n        FromHalfFloat(data[offset + 6]),\r\n        FromHalfFloat(data[offset + 7]),\r\n        FromHalfFloat(data[offset + 8]),\r\n        FromHalfFloat(data[offset + 9]),\r\n        FromHalfFloat(data[offset + 10]),\r\n        FromHalfFloat(data[offset + 11]),\r\n        FromHalfFloat(data[offset + 12]),\r\n        FromHalfFloat(data[offset + 13]),\r\n        FromHalfFloat(data[offset + 14]),\r\n        FromHalfFloat(data[offset + 15])\r\n    );\r\n}\r\n\r\nfunction ApplyBakedVertexAnimation(\r\n    data: FloatArray,\r\n    kind: string,\r\n    bakedVertexAnimationManager: IBakedVertexAnimationManager,\r\n    animationSettings: DeepImmutable<Vector4>,\r\n    matricesIndicesData: FloatArray,\r\n    matricesWeightsData: FloatArray,\r\n    matricesIndicesExtraData: Nullable<FloatArray>,\r\n    matricesWeightsExtraData: Nullable<FloatArray>,\r\n    numBoneInfluencers: number\r\n): boolean {\r\n    const texture = bakedVertexAnimationManager.texture;\r\n    const internalTexture = texture?.getInternalTexture();\r\n    const textureData = internalTexture?._bufferView;\r\n\r\n    if (!(textureData instanceof Float32Array) && !(textureData instanceof Uint16Array)) {\r\n        Logger.Warn(\"Baked vertex animation bounding info requires CPU-readable Float32Array or Uint16Array texture data.\", 1);\r\n        return false;\r\n    }\r\n\r\n    const textureSize = texture!.getSize();\r\n    const frame = GetBakedVertexAnimationFrame(animationSettings, bakedVertexAnimationManager.time);\r\n    if (!isFinite(frame) || frame < 0 || frame >= textureSize.height) {\r\n        Logger.Warn(\"Baked vertex animation bounding info could not be refreshed because the computed frame is outside the texture.\", 1);\r\n        return false;\r\n    }\r\n\r\n    const tempVector = TmpVectors.Vector3[0];\r\n    const finalMatrix = TmpVectors.Matrix[0];\r\n    const tempMatrix = TmpVectors.Matrix[1];\r\n    const textureFrameOffset = frame * textureSize.width * 4;\r\n    const transformFromFloatsToRef = kind === VertexBuffer.NormalKind ? Vector3.TransformNormalFromFloatsToRef : Vector3.TransformCoordinatesFromFloatsToRef;\r\n\r\n    for (let index = 0, matWeightIdx = 0; index < data.length; index += 3, matWeightIdx += 4) {\r\n        finalMatrix.reset();\r\n\r\n        let inf: number;\r\n        let weight: number;\r\n        for (inf = 0; inf < 4 && inf < numBoneInfluencers; inf++) {\r\n            weight = matricesWeightsData[matWeightIdx + inf];\r\n            if (weight > 0) {\r\n                ReadBakedVertexAnimationMatrixToRef(textureData, textureFrameOffset + Math.floor(matricesIndicesData[matWeightIdx + inf]) * 16, tempMatrix);\r\n                tempMatrix.scaleAndAddToRef(weight, finalMatrix);\r\n            }\r\n        }\r\n        if (matricesIndicesExtraData && matricesWeightsExtraData) {\r\n            for (inf = 0; inf < 4 && inf + 4 < numBoneInfluencers; inf++) {\r\n                weight = matricesWeightsExtraData[matWeightIdx + inf];\r\n                if (weight > 0) {\r\n                    ReadBakedVertexAnimationMatrixToRef(textureData, textureFrameOffset + Math.floor(matricesIndicesExtraData[matWeightIdx + inf]) * 16, tempMatrix);\r\n                    tempMatrix.scaleAndAddToRef(weight, finalMatrix);\r\n                }\r\n            }\r\n        }\r\n\r\n        transformFromFloatsToRef(data[index], data[index + 1], data[index + 2], finalMatrix, tempVector);\r\n        tempVector.toArray(data, index);\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\n/**\r\n * Opaque cache when computing data about a mesh\r\n */\r\nexport interface IMeshDataCache {\r\n    /** @internal */\r\n    _outputData?: Float32Array;\r\n\r\n    /** @internal */\r\n    _vertexData?: { [kind: string]: Float32Array };\r\n}\r\n\r\n/**\r\n * Options when computing data about a mesh\r\n */\r\nexport interface IMeshDataOptions {\r\n    /** Apply skeleton when computing the bounding info. Defaults to false. */\r\n    applySkeleton?: boolean;\r\n\r\n    /** Apply morph when computing the bounding info. Defaults to false. */\r\n    applyMorph?: boolean;\r\n\r\n    /** Apply baked vertex animation when computing data. Defaults to false. */\r\n    applyBakedVertexAnimation?: boolean;\r\n\r\n    /** Baked vertex animation settings to use instead of the manager's animationParameters. */\r\n    bakedVertexAnimationSettings?: DeepImmutable<Vector4>;\r\n\r\n    /** Update the cached positions stored as a Vector3 array. Defaults to true. */\r\n    updatePositionsArray?: boolean;\r\n\r\n    /**\r\n     * Cache to avoid redundant allocations and computations when computing the bounding info multiple times. Pass in\r\n     * an initial empty object and continue with subsequent calls using the same object. Caching is disabled by default.\r\n     */\r\n    cache?: IMeshDataCache;\r\n}\r\n\r\n/** @internal */\r\nclass _FacetDataStorage {\r\n    // facetData private properties\r\n    public facetPositions: Vector3[]; // facet local positions\r\n    public facetNormals: Vector3[]; // facet local normals\r\n    public facetPartitioning: number[][]; // partitioning array of facet index arrays\r\n    public facetNb: number = 0; // facet number\r\n    public partitioningSubdivisions: number = 10; // number of subdivisions per axis in the partitioning space\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public partitioningBBoxRatio: number = 1.01; // the partitioning array space is by default 1% bigger than the bounding box\r\n    public facetDataEnabled: boolean = false; // is the facet data feature enabled on this mesh ?\r\n    public facetParameters: any = {}; // keep a reference to the object parameters to avoid memory re-allocation\r\n    public bbSize: Vector3 = Vector3.Zero(); // bbox size approximated for facet data\r\n    public subDiv = {\r\n        // actual number of subdivisions per axis for ComputeNormals()\r\n        max: 1,\r\n        X: 1,\r\n        Y: 1,\r\n        Z: 1,\r\n    };\r\n\r\n    /** @internal */\r\n    public facetDepthSort: boolean = false; // is the facet depth sort to be computed\r\n    public facetDepthSortEnabled: boolean = false; // is the facet depth sort initialized\r\n    public depthSortedIndices: IndicesArray; // copy of the indices array to store them once sorted\r\n    public depthSortedFacets: { ind: number; sqDistance: number }[]; // array of depth sorted facets\r\n    public facetDepthSortFunction: (f1: { ind: number; sqDistance: number }, f2: { ind: number; sqDistance: number }) => number; // facet depth sort function\r\n    public facetDepthSortFrom: Vector3; // location where to depth sort from\r\n    public facetDepthSortOrigin: Vector3; // same as facetDepthSortFrom but expressed in the mesh local space\r\n\r\n    public invertedMatrix: Matrix; // Inverted world matrix.\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\nclass _InternalAbstractMeshDataInfo {\r\n    public _hasVertexAlpha = false;\r\n    public _useVertexColors = true;\r\n    public _numBoneInfluencers = 4;\r\n    public _applyFog = true;\r\n    public _receiveShadows = false;\r\n    public _facetData = new _FacetDataStorage();\r\n    public _visibility = 1.0;\r\n    public _skeleton: Nullable<Skeleton> = null;\r\n    public _layerMask: number = 0x0fffffff;\r\n    public _computeBonesUsingShaders = true;\r\n    public _isActive = false;\r\n    public _onlyForInstances = false;\r\n    public _isActiveIntermediate = false;\r\n    public _onlyForInstancesIntermediate = false;\r\n    public _actAsRegularMesh = false;\r\n    public _currentLOD: Map<Camera, [Nullable<AbstractMesh>, number]> = new Map();\r\n    public _collisionRetryCount: number = 3;\r\n    public _morphTargetManager: Nullable<MorphTargetManager> = null;\r\n    public _renderingGroupId = 0;\r\n    public _meshBlendingTag = 0;\r\n    public _bakedVertexAnimationManager: Nullable<IBakedVertexAnimationManager> = null;\r\n    public _material: Nullable<Material> = null;\r\n    public _materialForRenderPass: Array<Material | undefined>; // map a render pass id (index in the array) to a Material\r\n    public _positions: Nullable<Vector3[]> = null;\r\n    public _pointerOverDisableMeshTesting: boolean = false;\r\n    // Collisions\r\n    public _meshCollisionData = new _MeshCollisionData();\r\n    public _enableDistantPicking = false;\r\n    /** @internal\r\n     * Bounding info that is unnafected by the addition of thin instances\r\n     */\r\n    public _rawBoundingInfo: Nullable<BoundingInfo> = null;\r\n    /** @internal\r\n     * This value will indicate us that at some point, the mesh was specifically used with the opposite winding order\r\n     * We use that as a clue to force the material to sideOrientation = null\r\n     */\r\n    public _sideOrientationHint = false;\r\n    /**\r\n     * Used in frame graph mode only, to know which meshes to update when in frozen mode\r\n     */\r\n    public _wasActiveLastFrame = false;\r\n}\r\n\r\n/**\r\n * Class used to store all common mesh properties\r\n */\r\nexport abstract class AbstractMesh extends TransformNode implements IDisposable, ICullable, IGetSetVerticesData {\r\n    /** No occlusion */\r\n    public static OCCLUSION_TYPE_NONE = 0;\r\n    /** Occlusion set to optimistic */\r\n    public static OCCLUSION_TYPE_OPTIMISTIC = 1;\r\n    /** Occlusion set to strict */\r\n    public static OCCLUSION_TYPE_STRICT = 2;\r\n    /** Use an accurate occlusion algorithm */\r\n    public static OCCLUSION_ALGORITHM_TYPE_ACCURATE = 0;\r\n    /** Use a conservative occlusion algorithm */\r\n    public static OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE = 1;\r\n\r\n    /** Default culling strategy : this is an exclusion test and it's the more accurate.\r\n     *  Test order :\r\n     *  Is the bounding sphere outside the frustum ?\r\n     *  If not, are the bounding box vertices outside the frustum ?\r\n     *  It not, then the cullable object is in the frustum.\r\n     */\r\n    public static readonly CULLINGSTRATEGY_STANDARD = Constants.MESHES_CULLINGSTRATEGY_STANDARD;\r\n    /** Culling strategy : Bounding Sphere Only.\r\n     *  This is an exclusion test. It's faster than the standard strategy because the bounding box is not tested.\r\n     *  It's also less accurate than the standard because some not visible objects can still be selected.\r\n     *  Test : is the bounding sphere outside the frustum ?\r\n     *  If not, then the cullable object is in the frustum.\r\n     */\r\n    public static readonly CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY = Constants.MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;\r\n    /** Culling strategy : Optimistic Inclusion.\r\n     *  This in an inclusion test first, then the standard exclusion test.\r\n     *  This can be faster when a cullable object is expected to be almost always in the camera frustum.\r\n     *  This could also be a little slower than the standard test when the tested object center is not the frustum but one of its bounding box vertex is still inside.\r\n     *  Anyway, it's as accurate as the standard strategy.\r\n     *  Test :\r\n     *  Is the cullable object bounding sphere center in the frustum ?\r\n     *  If not, apply the default culling strategy.\r\n     */\r\n    public static readonly CULLINGSTRATEGY_OPTIMISTIC_INCLUSION = Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION;\r\n    /** Culling strategy : Optimistic Inclusion then Bounding Sphere Only.\r\n     *  This in an inclusion test first, then the bounding sphere only exclusion test.\r\n     *  This can be the fastest test when a cullable object is expected to be almost always in the camera frustum.\r\n     *  This could also be a little slower than the BoundingSphereOnly strategy when the tested object center is not in the frustum but its bounding sphere still intersects it.\r\n     *  It's less accurate than the standard strategy and as accurate as the BoundingSphereOnly strategy.\r\n     *  Test :\r\n     *  Is the cullable object bounding sphere center in the frustum ?\r\n     *  If not, apply the Bounding Sphere Only strategy. No Bounding Box is tested here.\r\n     */\r\n    public static readonly CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY = Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY;\r\n\r\n    /**\r\n     * No billboard\r\n     */\r\n    public static override get BILLBOARDMODE_NONE(): number {\r\n        return TransformNode.BILLBOARDMODE_NONE;\r\n    }\r\n\r\n    /** Billboard on X axis */\r\n    public static override get BILLBOARDMODE_X(): number {\r\n        return TransformNode.BILLBOARDMODE_X;\r\n    }\r\n\r\n    /** Billboard on Y axis */\r\n    public static override get BILLBOARDMODE_Y(): number {\r\n        return TransformNode.BILLBOARDMODE_Y;\r\n    }\r\n\r\n    /** Billboard on Z axis */\r\n    public static override get BILLBOARDMODE_Z(): number {\r\n        return TransformNode.BILLBOARDMODE_Z;\r\n    }\r\n\r\n    /** Billboard on all axes */\r\n    public static override get BILLBOARDMODE_ALL(): number {\r\n        return TransformNode.BILLBOARDMODE_ALL;\r\n    }\r\n\r\n    /** Billboard on using position instead of orientation */\r\n    public static override get BILLBOARDMODE_USE_POSITION(): number {\r\n        return TransformNode.BILLBOARDMODE_USE_POSITION;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the default value for isPickable for newly created meshes.\r\n     * When set to false, all meshes created after the change will not be pickable by default.\r\n     * Individual meshes can still override this by setting their own isPickable property.\r\n     */\r\n    public static DefaultIsPickable = true;\r\n\r\n    // Internal data\r\n    /** @internal */\r\n    public _internalAbstractMeshDataInfo = new _InternalAbstractMeshDataInfo();\r\n\r\n    /** @internal */\r\n    public _waitingMaterialId: Nullable<string> = null;\r\n\r\n    /** @internal */\r\n    public _waitingMorphTargetManagerId: Nullable<number> = null;\r\n\r\n    /** @internal */\r\n    public _waitingSkeletonId: Nullable<string> = null;\r\n\r\n    /** @internal */\r\n    public _waitingSkeletonUniqueId: Nullable<number> = null;\r\n\r\n    /**\r\n     * The culling strategy to use to check whether the mesh must be rendered or not.\r\n     * This value can be changed at any time and will be used on the next render mesh selection.\r\n     * The possible values are :\r\n     * - AbstractMesh.CULLINGSTRATEGY_STANDARD\r\n     * - AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY\r\n     * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION\r\n     * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY\r\n     * Please read each static variable documentation to get details about the culling process.\r\n     * */\r\n    public cullingStrategy = AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;\r\n\r\n    /**\r\n     * Gets the number of facets in the mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData#what-is-a-mesh-facet\r\n     */\r\n    public get facetNb(): number {\r\n        return this._internalAbstractMeshDataInfo._facetData.facetNb;\r\n    }\r\n    /**\r\n     * Gets or set the number (integer) of subdivisions per axis in the partitioning space\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData#tweaking-the-partitioning\r\n     */\r\n    public get partitioningSubdivisions(): number {\r\n        return this._internalAbstractMeshDataInfo._facetData.partitioningSubdivisions;\r\n    }\r\n    public set partitioningSubdivisions(nb: number) {\r\n        this._internalAbstractMeshDataInfo._facetData.partitioningSubdivisions = nb;\r\n    }\r\n    /**\r\n     * The ratio (float) to apply to the bounding box size to set to the partitioning space.\r\n     * Ex : 1.01 (default) the partitioning space is 1% bigger than the bounding box\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData#tweaking-the-partitioning\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get partitioningBBoxRatio(): number {\r\n        return this._internalAbstractMeshDataInfo._facetData.partitioningBBoxRatio;\r\n    }\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set partitioningBBoxRatio(ratio: number) {\r\n        this._internalAbstractMeshDataInfo._facetData.partitioningBBoxRatio = ratio;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the facets must be depth sorted on next call to `updateFacetData()`.\r\n     * Works only for updatable meshes.\r\n     * Doesn't work with multi-materials\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData#facet-depth-sort\r\n     */\r\n    public get mustDepthSortFacets(): boolean {\r\n        return this._internalAbstractMeshDataInfo._facetData.facetDepthSort;\r\n    }\r\n    public set mustDepthSortFacets(sort: boolean) {\r\n        this._internalAbstractMeshDataInfo._facetData.facetDepthSort = sort;\r\n    }\r\n\r\n    /**\r\n     * The location (Vector3) where the facet depth sort must be computed from.\r\n     * By default, the active camera position.\r\n     * Used only when facet depth sort is enabled\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData#facet-depth-sort\r\n     */\r\n    public get facetDepthSortFrom(): Vector3 {\r\n        return this._internalAbstractMeshDataInfo._facetData.facetDepthSortFrom;\r\n    }\r\n    public set facetDepthSortFrom(location: Vector3) {\r\n        this._internalAbstractMeshDataInfo._facetData.facetDepthSortFrom = location;\r\n    }\r\n\r\n    /** number of collision detection tries. Change this value if not all collisions are detected and handled properly */\r\n    public get collisionRetryCount(): number {\r\n        return this._internalAbstractMeshDataInfo._collisionRetryCount;\r\n    }\r\n    public set collisionRetryCount(retryCount: number) {\r\n        this._internalAbstractMeshDataInfo._collisionRetryCount = retryCount;\r\n    }\r\n    /**\r\n     * gets a boolean indicating if facetData is enabled\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData#what-is-a-mesh-facet\r\n     */\r\n    public get isFacetDataEnabled(): boolean {\r\n        return this._internalAbstractMeshDataInfo._facetData.facetDataEnabled;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the morph target manager\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/morphTargets\r\n     */\r\n    public get morphTargetManager(): Nullable<MorphTargetManager> {\r\n        return this._internalAbstractMeshDataInfo._morphTargetManager;\r\n    }\r\n\r\n    public set morphTargetManager(value: Nullable<MorphTargetManager>) {\r\n        if (this._internalAbstractMeshDataInfo._morphTargetManager === value) {\r\n            return;\r\n        }\r\n        this._internalAbstractMeshDataInfo._morphTargetManager = value;\r\n        this._syncGeometryWithMorphTargetManager();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the baked vertex animation manager\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/baked_texture_animations\r\n     */\r\n    public get bakedVertexAnimationManager(): Nullable<IBakedVertexAnimationManager> {\r\n        return this._internalAbstractMeshDataInfo._bakedVertexAnimationManager;\r\n    }\r\n\r\n    public set bakedVertexAnimationManager(value: Nullable<IBakedVertexAnimationManager>) {\r\n        if (this._internalAbstractMeshDataInfo._bakedVertexAnimationManager === value) {\r\n            return;\r\n        }\r\n        this._internalAbstractMeshDataInfo._bakedVertexAnimationManager = value;\r\n        this._markSubMeshesAsAttributesDirty();\r\n    }\r\n\r\n    /** @internal */\r\n    public _syncGeometryWithMorphTargetManager(): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateNonUniformScalingState(value: boolean): boolean {\r\n        if (!super._updateNonUniformScalingState(value)) {\r\n            return false;\r\n        }\r\n        this._markSubMeshesAsMiscDirty();\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public get rawBoundingInfo(): Nullable<BoundingInfo> {\r\n        return this._internalAbstractMeshDataInfo._rawBoundingInfo;\r\n    }\r\n    public set rawBoundingInfo(boundingInfo: Nullable<BoundingInfo>) {\r\n        this._internalAbstractMeshDataInfo._rawBoundingInfo = boundingInfo;\r\n    }\r\n\r\n    // Events\r\n\r\n    /**\r\n     * An event triggered when this mesh collides with another one\r\n     */\r\n    public onCollideObservable = new Observable<AbstractMesh>();\r\n\r\n    /** Set a function to call when this mesh collides with another one */\r\n    public set onCollide(callback: (collidedMesh?: AbstractMesh) => void) {\r\n        if (this._internalAbstractMeshDataInfo._meshCollisionData._onCollideObserver) {\r\n            this.onCollideObservable.remove(this._internalAbstractMeshDataInfo._meshCollisionData._onCollideObserver);\r\n        }\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._onCollideObserver = this.onCollideObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the collision's position changes\r\n     */\r\n    public onCollisionPositionChangeObservable = new Observable<Vector3>();\r\n\r\n    /** Set a function to call when the collision's position changes */\r\n    public set onCollisionPositionChange(callback: () => void) {\r\n        if (this._internalAbstractMeshDataInfo._meshCollisionData._onCollisionPositionChangeObserver) {\r\n            this.onCollisionPositionChangeObservable.remove(this._internalAbstractMeshDataInfo._meshCollisionData._onCollisionPositionChangeObserver);\r\n        }\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._onCollisionPositionChangeObserver = this.onCollisionPositionChangeObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when material is changed\r\n     */\r\n    public onMaterialChangedObservable = new Observable<AbstractMesh>();\r\n\r\n    // Properties\r\n\r\n    /**\r\n     * Gets or sets the orientation for POV movement & rotation\r\n     */\r\n    public definedFacingForward = true;\r\n\r\n    /** @internal */\r\n    public _occlusionQuery: Nullable<WebGLQuery | number> = null;\r\n\r\n    /** @internal */\r\n    public _renderingGroup: Nullable<RenderingGroup> = null;\r\n\r\n    /**\r\n     * Gets or sets mesh visibility between 0 and 1 (default is 1)\r\n     */\r\n    public get visibility(): number {\r\n        return this._internalAbstractMeshDataInfo._visibility;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets mesh visibility between 0 and 1 (default is 1)\r\n     */\r\n    public set visibility(value: number) {\r\n        if (this._internalAbstractMeshDataInfo._visibility === value) {\r\n            return;\r\n        }\r\n\r\n        const oldValue = this._internalAbstractMeshDataInfo._visibility;\r\n\r\n        this._internalAbstractMeshDataInfo._visibility = value;\r\n\r\n        if ((oldValue === 1 && value !== 1) || (oldValue !== 1 && value === 1)) {\r\n            this._markSubMeshesAsDirty((defines) => {\r\n                defines.markAsMiscDirty();\r\n                defines.markAsPrePassDirty();\r\n            });\r\n        }\r\n    }\r\n\r\n    /** Gets or sets the alpha index used to sort transparent meshes\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering#alpha-index\r\n     */\r\n    public alphaIndex = Number.MAX_VALUE;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mesh can be picked (by scene.pick for instance or through actions).\r\n     * Default value is determined by {@link AbstractMesh.DefaultIsPickable} (true unless changed).\r\n     */\r\n    public isPickable = AbstractMesh.DefaultIsPickable;\r\n\r\n    /**\r\n     * Whether this mesh participates in pointer-move ray picking.\r\n     * @internal\r\n     */\r\n    public _isPointerMovePickable: boolean | undefined;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mesh can be near picked (touched by the XR controller or hands). Default is false\r\n     */\r\n    public isNearPickable = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mesh can be grabbed. Default is false.\r\n     * Setting this to true, while using the XR near interaction feature, will trigger a pointer event when the mesh is grabbed.\r\n     * Grabbing means that the controller is using the squeeze or main trigger button to grab the mesh.\r\n     * This is different from nearPickable which only triggers the event when the mesh is touched by the controller\r\n     */\r\n    public isNearGrabbable = false;\r\n\r\n    /** Gets or sets a boolean indicating that bounding boxes of subMeshes must be rendered as well (false by default) */\r\n    public showSubMeshesBoundingBox = false;\r\n\r\n    /** Gets or sets a boolean indicating if the mesh must be considered as a ray blocker for lens flares (false by default)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n     */\r\n    public isBlocker = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)\r\n     */\r\n    public enablePointerMoveEvents = false;\r\n\r\n    /**\r\n     * Gets or sets the property which disables the test that is checking that the mesh under the pointer is the same than the previous time we tested for it (default: false).\r\n     * Set this property to true if you want thin instances picking to be reported accurately when moving over the mesh.\r\n     * Note that setting this property to true will incur some performance penalties when dealing with pointer events for this mesh so use it sparingly.\r\n     */\r\n    public get pointerOverDisableMeshTesting() {\r\n        return this._internalAbstractMeshDataInfo._pointerOverDisableMeshTesting;\r\n    }\r\n\r\n    public set pointerOverDisableMeshTesting(disable: boolean) {\r\n        this._internalAbstractMeshDataInfo._pointerOverDisableMeshTesting = disable;\r\n    }\r\n\r\n    /**\r\n     * Specifies the rendering group id for this mesh (0 by default)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering#rendering-groups\r\n     */\r\n    public get renderingGroupId() {\r\n        return this._internalAbstractMeshDataInfo._renderingGroupId;\r\n    }\r\n\r\n    public set renderingGroupId(value: number) {\r\n        this._internalAbstractMeshDataInfo._renderingGroupId = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the packed mesh-blending tag for this mesh.\r\n     *\r\n     * Group ID occupies bits 0..5 and radius class occupies bits 6..7. Use PackMeshBlendingTag\r\n     * to construct the value. Group 0 disables blending; valid participating groups are 1..63.\r\n     * Meshes in the same nonzero group are treated as one logical surface and do not blend together.\r\n     * This visual-only property does not alter geometry, collision queries, depth, normals, or shadows.\r\n     */\r\n    public get meshBlendingTag(): number {\r\n        return this._internalAbstractMeshDataInfo._meshBlendingTag;\r\n    }\r\n\r\n    public set meshBlendingTag(value: number) {\r\n        if (!Number.isInteger(value) || value < 0 || value > 0xff || (value !== 0 && (value & 0x3f) === 0)) {\r\n            throw new RangeError(\"Mesh-blending tag must be 0 or contain a group ID between 1 and 63.\");\r\n        }\r\n        this._internalAbstractMeshDataInfo._meshBlendingTag = value;\r\n    }\r\n\r\n    /** Gets or sets current material */\r\n    public get material(): Nullable<Material> {\r\n        return this._internalAbstractMeshDataInfo._material;\r\n    }\r\n    public set material(value: Nullable<Material>) {\r\n        this._setMaterial(value);\r\n    }\r\n\r\n    /** @internal */\r\n    protected _setMaterial(value: Nullable<Material>) {\r\n        if (this._internalAbstractMeshDataInfo._material === value) {\r\n            return;\r\n        }\r\n\r\n        // remove from material mesh map id needed\r\n        if (this._internalAbstractMeshDataInfo._material && this._internalAbstractMeshDataInfo._material.meshMap) {\r\n            this._internalAbstractMeshDataInfo._material.meshMap[this.uniqueId] = undefined;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._material = value;\r\n\r\n        if (value && value.meshMap) {\r\n            value.meshMap[this.uniqueId] = this;\r\n        }\r\n\r\n        if (this.onMaterialChangedObservable.hasObservers()) {\r\n            this.onMaterialChangedObservable.notifyObservers(this);\r\n        }\r\n\r\n        if (!this.subMeshes) {\r\n            return;\r\n        }\r\n\r\n        this.resetDrawCache(undefined, value == null);\r\n        this._unBindEffect();\r\n    }\r\n\r\n    /**\r\n     * Gets the material used to render the mesh in a specific render pass\r\n     * @param renderPassId render pass id\r\n     * @returns material used for the render pass. If no specific material is used for this render pass, undefined is returned (meaning mesh.material is used for this pass)\r\n     */\r\n    public getMaterialForRenderPass(renderPassId: number): Material | undefined {\r\n        return this._internalAbstractMeshDataInfo._materialForRenderPass?.[renderPassId];\r\n    }\r\n\r\n    /**\r\n     * Sets the material to be used to render the mesh in a specific render pass\r\n     * @param renderPassId render pass id\r\n     * @param material material to use for this render pass. If undefined is passed, no specific material will be used for this render pass but the regular material will be used instead (mesh.material)\r\n     */\r\n    public setMaterialForRenderPass(renderPassId: number, material?: Material): void {\r\n        this.resetDrawCache(renderPassId);\r\n        if (!this._internalAbstractMeshDataInfo._materialForRenderPass) {\r\n            this._internalAbstractMeshDataInfo._materialForRenderPass = [];\r\n        }\r\n        const currentMaterial = this._internalAbstractMeshDataInfo._materialForRenderPass[renderPassId];\r\n        if (currentMaterial?.meshMap?.[this.uniqueId]) {\r\n            currentMaterial.meshMap[this.uniqueId] = undefined;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._materialForRenderPass[renderPassId] = material;\r\n        if (material && material.meshMap) {\r\n            material.meshMap[this.uniqueId] = this;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this mesh can receive realtime shadows\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/lights/shadows\r\n     */\r\n    public get receiveShadows(): boolean {\r\n        return this._internalAbstractMeshDataInfo._receiveShadows;\r\n    }\r\n    public set receiveShadows(value: boolean) {\r\n        if (this._internalAbstractMeshDataInfo._receiveShadows === value) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._receiveShadows = value;\r\n        this._markSubMeshesAsLightDirty();\r\n    }\r\n\r\n    /** Defines color to use when rendering outline */\r\n    public outlineColor = Color3.Red();\r\n    /** Define width to use when rendering outline */\r\n    public outlineWidth = 0.02;\r\n\r\n    /** Defines color to use when rendering overlay */\r\n    public overlayColor = Color3.Red();\r\n    /** Defines alpha to use when rendering overlay */\r\n    public overlayAlpha = 0.5;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this mesh needs to use vertex alpha data to render.\r\n     * This property is misnamed and should be `useVertexAlpha`. Note that the mesh will be rendered\r\n     * with alpha blending when this flag is set even if vertex alpha data is missing from the geometry.\r\n     */\r\n    public get hasVertexAlpha(): boolean {\r\n        return this._internalAbstractMeshDataInfo._hasVertexAlpha;\r\n    }\r\n    public set hasVertexAlpha(value: boolean) {\r\n        if (this._internalAbstractMeshDataInfo._hasVertexAlpha === value) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._hasVertexAlpha = value;\r\n        this._markSubMeshesAsAttributesDirty();\r\n        this._markSubMeshesAsMiscDirty();\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that this mesh needs to use vertex color data to render (if this kind of vertex data is available in the geometry) */\r\n    public get useVertexColors(): boolean {\r\n        return this._internalAbstractMeshDataInfo._useVertexColors;\r\n    }\r\n    public set useVertexColors(value: boolean) {\r\n        if (this._internalAbstractMeshDataInfo._useVertexColors === value) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._useVertexColors = value;\r\n        this._markSubMeshesAsAttributesDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that bone animations must be computed by the GPU (true by default)\r\n     */\r\n    public get computeBonesUsingShaders(): boolean {\r\n        return this._internalAbstractMeshDataInfo._computeBonesUsingShaders;\r\n    }\r\n    public set computeBonesUsingShaders(value: boolean) {\r\n        if (this._internalAbstractMeshDataInfo._computeBonesUsingShaders === value) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._computeBonesUsingShaders = value;\r\n        this._markSubMeshesAsAttributesDirty();\r\n    }\r\n\r\n    /** Gets or sets the number of allowed bone influences per vertex (4 by default) */\r\n    public get numBoneInfluencers(): number {\r\n        return this._internalAbstractMeshDataInfo._numBoneInfluencers;\r\n    }\r\n    public set numBoneInfluencers(value: number) {\r\n        if (this._internalAbstractMeshDataInfo._numBoneInfluencers === value) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._numBoneInfluencers = value;\r\n        this._markSubMeshesAsAttributesDirty();\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that this mesh will allow fog to be rendered on it (true by default) */\r\n    public get applyFog(): boolean {\r\n        return this._internalAbstractMeshDataInfo._applyFog;\r\n    }\r\n    public set applyFog(value: boolean) {\r\n        if (this._internalAbstractMeshDataInfo._applyFog === value) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._applyFog = value;\r\n        this._markSubMeshesAsMiscDirty();\r\n    }\r\n\r\n    /** When enabled, decompose picking matrices for better precision with large values for mesh position and scling */\r\n    public get enableDistantPicking(): boolean {\r\n        return this._internalAbstractMeshDataInfo._enableDistantPicking;\r\n    }\r\n    public set enableDistantPicking(value: boolean) {\r\n        this._internalAbstractMeshDataInfo._enableDistantPicking = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that internal octree (if available) can be used to boost submeshes selection (true by default) */\r\n    public useOctreeForRenderingSelection = true;\r\n    /** Gets or sets a boolean indicating that internal octree (if available) can be used to boost submeshes picking (true by default) */\r\n    public useOctreeForPicking = true;\r\n    /** Gets or sets a boolean indicating that internal octree (if available) can be used to boost submeshes collision (true by default) */\r\n    public useOctreeForCollisions = true;\r\n    /**\r\n     * Gets or sets the current layer mask (default is 0x0FFFFFFF)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/layerMasksAndMultiCam\r\n     */\r\n    public get layerMask(): number {\r\n        return this._internalAbstractMeshDataInfo._layerMask;\r\n    }\r\n\r\n    public set layerMask(value: number) {\r\n        if (value === this._internalAbstractMeshDataInfo._layerMask) {\r\n            return;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._layerMask = value;\r\n        this._resyncLightSources();\r\n    }\r\n\r\n    /**\r\n     * True if the mesh must be rendered in any case (this will shortcut the frustum clipping phase)\r\n     */\r\n    public alwaysSelectAsActiveMesh = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the bounding info does not need to be kept in sync (for performance reason)\r\n     */\r\n    public doNotSyncBoundingInfo = false;\r\n\r\n    /**\r\n     * Gets or sets the current action manager\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions\r\n     */\r\n    public actionManager: Nullable<AbstractActionManager> = null;\r\n\r\n    /**\r\n     * Gets or sets the ellipsoid used to impersonate this mesh when using collision engine (default is (0.5, 1, 0.5))\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     */\r\n    public ellipsoid = new Vector3(0.5, 1, 0.5);\r\n    /**\r\n     * Gets or sets the ellipsoid offset used to impersonate this mesh when using collision engine (default is (0, 0, 0))\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     */\r\n    public ellipsoidOffset = new Vector3(0, 0, 0);\r\n\r\n    /**\r\n     * Gets or sets a collision mask used to mask collisions (default is -1).\r\n     * A collision between A and B will happen if A.collisionGroup & b.collisionMask !== 0\r\n     */\r\n    public get collisionMask(): number {\r\n        return this._internalAbstractMeshDataInfo._meshCollisionData._collisionMask;\r\n    }\r\n\r\n    public set collisionMask(mask: number) {\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._collisionMask = !isNaN(mask) ? mask : -1;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a collision response flag (default is true).\r\n     * when collisionResponse is false, events are still triggered but colliding entity has no response\r\n     * This helps creating trigger volume when user wants collision feedback events but not position/velocity\r\n     * to respond to the collision.\r\n     */\r\n    public get collisionResponse(): boolean {\r\n        return this._internalAbstractMeshDataInfo._meshCollisionData._collisionResponse;\r\n    }\r\n\r\n    public set collisionResponse(response: boolean) {\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._collisionResponse = response;\r\n    }\r\n    /**\r\n     * Gets or sets the current collision group mask (-1 by default).\r\n     * A collision between A and B will happen if A.collisionGroup & b.collisionMask !== 0\r\n     */\r\n    public get collisionGroup(): number {\r\n        return this._internalAbstractMeshDataInfo._meshCollisionData._collisionGroup;\r\n    }\r\n\r\n    public set collisionGroup(mask: number) {\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._collisionGroup = !isNaN(mask) ? mask : -1;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets current surrounding meshes (null by default).\r\n     *\r\n     * By default collision detection is tested against every mesh in the scene.\r\n     * It is possible to set surroundingMeshes to a defined list of meshes and then only these specified\r\n     * meshes will be tested for the collision.\r\n     *\r\n     * Note: if set to an empty array no collision will happen when this mesh is moved.\r\n     */\r\n    public get surroundingMeshes(): Nullable<AbstractMesh[]> {\r\n        return this._internalAbstractMeshDataInfo._meshCollisionData._surroundingMeshes;\r\n    }\r\n\r\n    public set surroundingMeshes(meshes: Nullable<AbstractMesh[]>) {\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._surroundingMeshes = meshes;\r\n    }\r\n\r\n    // Edges\r\n    /**\r\n     * Defines edge width used when edgesRenderer is enabled\r\n     * @see https://www.babylonjs-playground.com/#10OJSG#13\r\n     */\r\n    public edgesWidth = 1;\r\n    /**\r\n     * Defines edge color used when edgesRenderer is enabled\r\n     * @see https://www.babylonjs-playground.com/#10OJSG#13\r\n     */\r\n    public edgesColor = new Color4(1, 0, 0, 1);\r\n    /** @internal */\r\n    public _edgesRenderer: Nullable<IEdgesRenderer> = null;\r\n\r\n    /** @internal */\r\n    public _masterMesh: Nullable<AbstractMesh> = null;\r\n    protected _boundingInfo: Nullable<BoundingInfo> = null;\r\n    protected _boundingInfoIsDirty = true;\r\n    /** @internal */\r\n    public _renderId = 0;\r\n\r\n    /**\r\n     * Gets or sets the list of subMeshes\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials\r\n     */\r\n    public subMeshes: SubMesh[];\r\n\r\n    /** @internal */\r\n    public _intersectionsInProgress = new Array<AbstractMesh>();\r\n\r\n    /** @internal */\r\n    public _unIndexed = false;\r\n\r\n    /** @internal */\r\n    public _lightSources = new Array<Light>();\r\n\r\n    /** Gets the list of lights affecting that mesh */\r\n    public get lightSources(): Light[] {\r\n        return this._lightSources;\r\n    }\r\n\r\n    /** @internal */\r\n    public abstract get _positions(): Nullable<Vector3[]>;\r\n\r\n    // Loading properties\r\n    /** @internal */\r\n    public _waitingData: {\r\n        lods: Nullable<any>;\r\n        actions: Nullable<any>;\r\n        freezeWorldMatrix: Nullable<boolean>;\r\n    } = {\r\n        lods: null,\r\n        actions: null,\r\n        freezeWorldMatrix: null,\r\n    };\r\n\r\n    /** @internal */\r\n    public _bonesTransformMatrices: Nullable<Float32Array> = null;\r\n\r\n    /** @internal */\r\n    public _transformMatrixTexture: Nullable<RawTexture> = null;\r\n\r\n    /**\r\n     * Gets or sets a skeleton to apply skinning transformations\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n     */\r\n    public set skeleton(value: Nullable<Skeleton>) {\r\n        const skeleton = this._internalAbstractMeshDataInfo._skeleton;\r\n        if (skeleton && skeleton.needInitialSkinMatrix) {\r\n            skeleton._unregisterMeshWithPoseMatrix(this);\r\n        }\r\n\r\n        if (value && value.needInitialSkinMatrix) {\r\n            value._registerMeshWithPoseMatrix(this);\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._skeleton = value;\r\n\r\n        if (!this._internalAbstractMeshDataInfo._skeleton) {\r\n            this._bonesTransformMatrices = null;\r\n        }\r\n\r\n        this._markSubMeshesAsAttributesDirty();\r\n    }\r\n\r\n    public get skeleton(): Nullable<Skeleton> {\r\n        return this._internalAbstractMeshDataInfo._skeleton;\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the mesh is rebuilt.\r\n     */\r\n    public onRebuildObservable = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * The current mesh uniform buffer.\r\n     * @internal Internal use only.\r\n     */\r\n    public _uniformBuffer: UniformBuffer;\r\n\r\n    // Constructor\r\n\r\n    /**\r\n     * Creates a new AbstractMesh\r\n     * @param name defines the name of the mesh\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, scene: Nullable<Scene> = null) {\r\n        super(name, scene, false);\r\n\r\n        scene = this.getScene();\r\n        this.layerMask = scene.defaultRenderableLayerMask;\r\n        scene.addMesh(this);\r\n\r\n        this._resyncLightSources();\r\n\r\n        // Mesh Uniform Buffer.\r\n        this._uniformBuffer = new UniformBuffer(this.getScene().getEngine(), undefined, undefined, name, !this.getScene().getEngine().isWebGPU);\r\n        this._buildUniformLayout();\r\n\r\n        switch (scene.performancePriority) {\r\n            case ScenePerformancePriority.Aggressive:\r\n                this.doNotSyncBoundingInfo = true;\r\n            // eslint-disable-next-line no-fallthrough\r\n            case ScenePerformancePriority.Intermediate:\r\n                this.alwaysSelectAsActiveMesh = true;\r\n                this.isPickable = false;\r\n                break;\r\n        }\r\n    }\r\n\r\n    protected _buildUniformLayout(): void {\r\n        this._uniformBuffer.addUniform(\"world\", 16);\r\n        this._uniformBuffer.addUniform(\"visibility\", 1);\r\n        this._uniformBuffer.create();\r\n    }\r\n\r\n    /**\r\n     * Transfer the mesh values to its UBO.\r\n     * @param world The world matrix associated with the mesh\r\n     */\r\n    public transferToEffect(world: Matrix): void {\r\n        const ubo = this._uniformBuffer;\r\n\r\n        ubo.updateMatrix(\"world\", world);\r\n        ubo.updateFloat(\"visibility\", this._internalAbstractMeshDataInfo._visibility);\r\n\r\n        ubo.update();\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh uniform buffer.\r\n     * @returns the uniform buffer of the mesh.\r\n     */\r\n    public getMeshUniformBuffer(): UniformBuffer {\r\n        return this._uniformBuffer;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _isGaussianSplatting(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"AbstractMesh\"\r\n     * @returns \"AbstractMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"AbstractMesh\";\r\n    }\r\n\r\n    /**\r\n     * Gets a string representation of the current mesh\r\n     * @param fullDetails defines a boolean indicating if full details must be included\r\n     * @returns a string representation of the current mesh\r\n     */\r\n    public override toString(fullDetails?: boolean): string {\r\n        let ret = \"Name: \" + this.name + \", isInstance: \" + (this.getClassName() === \"InstancedMesh\" ? \"YES\" : \"NO\");\r\n        ret += \", # of submeshes: \" + (this.subMeshes ? this.subMeshes.length : 0);\r\n\r\n        const skeleton = this._internalAbstractMeshDataInfo._skeleton;\r\n        if (skeleton) {\r\n            ret += \", skeleton: \" + skeleton.name;\r\n        }\r\n        if (fullDetails) {\r\n            ret += \", billboard mode: \" + [\"NONE\", \"X\", \"Y\", null, \"Z\", null, null, \"ALL\"][this.billboardMode];\r\n            ret += \", freeze wrld mat: \" + (this._isWorldMatrixFrozen || this._waitingData.freezeWorldMatrix ? \"YES\" : \"NO\");\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    protected override _getEffectiveParent(): Nullable<Node> {\r\n        if (this._masterMesh && this.billboardMode !== TransformNode.BILLBOARDMODE_NONE) {\r\n            return this._masterMesh;\r\n        }\r\n\r\n        return super._getEffectiveParent();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _getActionManagerForTrigger(trigger?: number, initialCall = true): Nullable<AbstractActionManager> {\r\n        if (this.actionManager && (initialCall || this.actionManager.isRecursive)) {\r\n            if (trigger) {\r\n                if (this.actionManager.hasSpecificTrigger(trigger)) {\r\n                    return this.actionManager;\r\n                }\r\n            } else {\r\n                return this.actionManager;\r\n            }\r\n        }\r\n\r\n        if (!this.parent) {\r\n            return null;\r\n        }\r\n\r\n        return this.parent._getActionManagerForTrigger(trigger, false);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseRenderPassId(_id: number): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _rebuild(dispose = false): void {\r\n        this.onRebuildObservable.notifyObservers(this);\r\n\r\n        if (this._occlusionQuery !== null) {\r\n            this._occlusionQuery = null;\r\n        }\r\n\r\n        if (!this.subMeshes) {\r\n            return;\r\n        }\r\n\r\n        for (const subMesh of this.subMeshes) {\r\n            subMesh._rebuild();\r\n        }\r\n\r\n        this.resetDrawCache();\r\n    }\r\n\r\n    /** @internal */\r\n    public _resyncLightSources(): void {\r\n        this._lightSources.length = 0;\r\n\r\n        for (const light of this.getScene().lights) {\r\n            if (!light.isEnabled()) {\r\n                continue;\r\n            }\r\n\r\n            if (light.canAffectMesh(this)) {\r\n                this._lightSources.push(light);\r\n            }\r\n        }\r\n\r\n        this._markSubMeshesAsLightDirty();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _resyncLightSource(light: Light): void {\r\n        const isIn = light.isEnabled() && light.canAffectMesh(this);\r\n\r\n        const index = this._lightSources.indexOf(light);\r\n        let removed = false;\r\n        if (index === -1) {\r\n            if (!isIn) {\r\n                return;\r\n            }\r\n            this._lightSources.push(light);\r\n        } else {\r\n            if (isIn) {\r\n                return;\r\n            }\r\n            removed = true;\r\n            this._lightSources.splice(index, 1);\r\n        }\r\n\r\n        this._markSubMeshesAsLightDirty(removed);\r\n    }\r\n\r\n    /** @internal */\r\n    public _unBindEffect() {\r\n        for (const subMesh of this.subMeshes) {\r\n            subMesh.setEffect(null);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _removeLightSource(light: Light, dispose: boolean): void {\r\n        const index = this._lightSources.indexOf(light);\r\n\r\n        if (index === -1) {\r\n            return;\r\n        }\r\n        this._lightSources.splice(index, 1);\r\n\r\n        this._markSubMeshesAsLightDirty(dispose);\r\n    }\r\n\r\n    private _markSubMeshesAsDirty(func: (defines: MaterialDefines) => void) {\r\n        if (!this.subMeshes) {\r\n            return;\r\n        }\r\n\r\n        for (const subMesh of this.subMeshes) {\r\n            for (let i = 0; i < subMesh._drawWrappers.length; ++i) {\r\n                const drawWrapper = subMesh._drawWrappers[i];\r\n                if (!drawWrapper || !drawWrapper.defines || !(drawWrapper.defines as MaterialDefines).markAllAsDirty) {\r\n                    continue;\r\n                }\r\n                func(drawWrapper.defines as MaterialDefines);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _markSubMeshesAsLightDirty(dispose: boolean = false) {\r\n        this._markSubMeshesAsDirty((defines) => defines.markAsLightDirty(dispose));\r\n    }\r\n\r\n    /** @internal */\r\n    public _markSubMeshesAsAttributesDirty() {\r\n        this._markSubMeshesAsDirty((defines) => defines.markAsAttributesDirty());\r\n    }\r\n\r\n    /** @internal */\r\n    public _markSubMeshesAsMiscDirty() {\r\n        this._markSubMeshesAsDirty((defines) => defines.markAsMiscDirty());\r\n    }\r\n\r\n    /**\r\n     * Flag the AbstractMesh as dirty (Forcing it to update everything)\r\n     * @param property if set to \"rotation\" the objects rotationQuaternion will be set to null\r\n     * @returns this AbstractMesh\r\n     */\r\n    public override markAsDirty(property?: string): AbstractMesh {\r\n        this._currentRenderId = Number.MAX_VALUE;\r\n        super.markAsDirty(property);\r\n        this._isDirty = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Resets the draw wrappers cache for all submeshes of this abstract mesh\r\n     * @param passId If provided, releases only the draw wrapper corresponding to this render pass id\r\n     * @param immediate If true, the effect will be released immediately, otherwise it will be released at the next frame\r\n     */\r\n    public resetDrawCache(passId?: number, immediate = false): void {\r\n        if (!this.subMeshes) {\r\n            return;\r\n        }\r\n\r\n        for (const subMesh of this.subMeshes) {\r\n            subMesh.resetDrawCache(passId, immediate);\r\n        }\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Returns true if the mesh is blocked. Implemented by child classes\r\n     */\r\n    public get isBlocked(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns the mesh itself by default. Implemented by child classes\r\n     * @param camera defines the camera to use to pick the right LOD level\r\n     * @returns the currentAbstractMesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public getLOD(camera: Camera): Nullable<AbstractMesh> {\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * The mesh's internal Geometry object. Implemented by child classes.\r\n     */\r\n    public abstract get geometry(): Nullable<Geometry>;\r\n\r\n    /**\r\n     * Returns 0 by default. Implemented by child classes\r\n     * @returns an integer\r\n     */\r\n    public getTotalVertices(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Returns a positive integer : the total number of indices in this mesh geometry.\r\n     * @returns the number of indices or zero if the mesh has no geometry.\r\n     */\r\n    public getTotalIndices(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Returns null by default. Implemented by child classes\r\n     * @returns null\r\n     */\r\n    public getIndices(): Nullable<IndicesArray> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Returns the array of the requested vertex data kind. Implemented by child classes\r\n     * @param kind defines the vertex data kind to use\r\n     * @returns null\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public getVerticesData(kind: string): Nullable<FloatArray> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Copies the requested vertex data kind into the given vertex data map. Float data is constructed if the map doesn't have the data.\r\n     * @param kind defines the vertex data kind to use\r\n     * @param vertexData defines the map that stores the resulting data\r\n     */\r\n    public abstract copyVerticesData(kind: string, vertexData: { [kind: string]: Float32Array }): void;\r\n\r\n    /**\r\n     * Returns the mesh VertexBuffer object from the requested `kind`\r\n     * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.NormalKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param bypassInstanceData defines a boolean indicating that the function should not take into account the instance data (applies only if the mesh has instances). Default: false\r\n     * @returns a FloatArray or null if the mesh has no vertex buffer for this kind.\r\n     */\r\n    public abstract getVertexBuffer(kind: string, bypassInstanceData?: boolean): Nullable<VertexBuffer>;\r\n\r\n    /**\r\n     * Sets the vertex data of the mesh geometry for the requested `kind`.\r\n     * If the mesh has no geometry, a new Geometry object is set to the mesh and then passed this vertex data.\r\n     * Note that a new underlying VertexBuffer object is created each call.\r\n     * If the `kind` is the `PositionKind`, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.\r\n     * @param kind defines vertex data kind:\r\n     * * VertexBuffer.PositionKind\r\n     * * VertexBuffer.UVKind\r\n     * * VertexBuffer.UV2Kind\r\n     * * VertexBuffer.UV3Kind\r\n     * * VertexBuffer.UV4Kind\r\n     * * VertexBuffer.UV5Kind\r\n     * * VertexBuffer.UV6Kind\r\n     * * VertexBuffer.ColorKind\r\n     * * VertexBuffer.MatricesIndicesKind\r\n     * * VertexBuffer.MatricesIndicesExtraKind\r\n     * * VertexBuffer.MatricesWeightsKind\r\n     * * VertexBuffer.MatricesWeightsExtraKind\r\n     * @param data defines the data source\r\n     * @param updatable defines if the data must be flagged as updatable (or static)\r\n     * @param stride defines the vertex stride (size of an entire vertex). Can be null and in this case will be deduced from vertex data kind\r\n     * @returns the current mesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public setVerticesData(kind: string, data: FloatArray, updatable?: boolean, stride?: number): AbstractMesh {\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the existing vertex data of the mesh geometry for the requested `kind`.\r\n     * If the mesh has no geometry, it is simply returned as it is.\r\n     * @param kind defines vertex data kind:\r\n     * * VertexBuffer.PositionKind\r\n     * * VertexBuffer.UVKind\r\n     * * VertexBuffer.UV2Kind\r\n     * * VertexBuffer.UV3Kind\r\n     * * VertexBuffer.UV4Kind\r\n     * * VertexBuffer.UV5Kind\r\n     * * VertexBuffer.UV6Kind\r\n     * * VertexBuffer.ColorKind\r\n     * * VertexBuffer.MatricesIndicesKind\r\n     * * VertexBuffer.MatricesIndicesExtraKind\r\n     * * VertexBuffer.MatricesWeightsKind\r\n     * * VertexBuffer.MatricesWeightsExtraKind\r\n     * @param data defines the data source\r\n     * @param updateExtends If `kind` is `PositionKind` and if `updateExtends` is true, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed\r\n     * @param makeItUnique If true, a new global geometry is created from this data and is set to the mesh\r\n     * @returns the current mesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): AbstractMesh {\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh indices,\r\n     * If the mesh has no geometry, a new Geometry object is created and set to the mesh.\r\n     * @param indices Expects an array populated with integers or a typed array (Int32Array, Uint32Array, Uint16Array)\r\n     * @param totalVertices Defines the total number of vertices\r\n     * @returns the current mesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public setIndices(indices: IndicesArray, totalVertices: Nullable<number>): AbstractMesh {\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if specific vertex data is present\r\n     * @param kind defines the vertex data kind to use\r\n     * @returns true is data kind is present\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public isVerticesDataPresent(kind: string): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns the mesh BoundingInfo object or creates a new one and returns if it was undefined.\r\n     * Note that it returns a shallow bounding of the mesh (i.e. it does not include children).\r\n     * However, if the mesh contains thin instances, it will be expanded to include them. If you want the \"raw\" bounding data instead, then use `getRawBoundingInfo()`.\r\n     * To get the full bounding of all children, call `getHierarchyBoundingVectors` instead.\r\n     * @returns a BoundingInfo\r\n     */\r\n    public getBoundingInfo(): BoundingInfo {\r\n        if (this._masterMesh) {\r\n            return this._masterMesh.getBoundingInfo();\r\n        }\r\n\r\n        if (this._boundingInfoIsDirty) {\r\n            this._boundingInfoIsDirty = false;\r\n            // this._boundingInfo is being created if undefined\r\n            this._updateBoundingInfo();\r\n        }\r\n        // cannot be null.\r\n        return this._boundingInfo!;\r\n    }\r\n\r\n    /**\r\n     * Returns the bounding info unnafected by instance data.\r\n     * @returns the bounding info of the mesh unaffected by instance data.\r\n     */\r\n    public getRawBoundingInfo() {\r\n        return this.rawBoundingInfo ?? this.getBoundingInfo();\r\n    }\r\n\r\n    /**\r\n     * Overwrite the current bounding info\r\n     * @param boundingInfo defines the new bounding info\r\n     * @returns the current mesh\r\n     */\r\n    public setBoundingInfo(boundingInfo: BoundingInfo): AbstractMesh {\r\n        this._boundingInfo = boundingInfo;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns true if there is already a bounding info\r\n     */\r\n    public get hasBoundingInfo(): boolean {\r\n        return this._boundingInfo !== null;\r\n    }\r\n\r\n    /**\r\n     * Creates a new bounding info for the mesh\r\n     * @param minimum min vector of the bounding box/sphere\r\n     * @param maximum max vector of the bounding box/sphere\r\n     * @param worldMatrix defines the new world matrix\r\n     * @returns the new bounding info\r\n     */\r\n    public buildBoundingInfo(minimum: DeepImmutable<Vector3>, maximum: DeepImmutable<Vector3>, worldMatrix?: DeepImmutable<Matrix>) {\r\n        this._boundingInfo = new BoundingInfo(minimum, maximum, worldMatrix);\r\n        return this._boundingInfo;\r\n    }\r\n\r\n    /**\r\n     * Uniformly scales the mesh to fit inside of a unit cube (1 X 1 X 1 units)\r\n     * @param includeDescendants Use the hierarchy's bounding box instead of the mesh's bounding box. Default is false\r\n     * @param ignoreRotation ignore rotation when computing the scale (ie. object will be axis aligned). Default is false\r\n     * @param predicate predicate that is passed in to getHierarchyBoundingVectors when selecting which object should be included when scaling\r\n     * @returns the current mesh\r\n     */\r\n    public override normalizeToUnitCube(includeDescendants = true, ignoreRotation = false, predicate?: Nullable<(node: AbstractMesh) => boolean>): AbstractMesh {\r\n        return <AbstractMesh>super.normalizeToUnitCube(includeDescendants, ignoreRotation, predicate);\r\n    }\r\n\r\n    /** Gets a boolean indicating if this mesh has skinning data and an attached skeleton */\r\n    public get useBones(): boolean {\r\n        return <boolean>(\r\n            (this.skeleton &&\r\n                this.getScene().skeletonsEnabled &&\r\n                this.isVerticesDataPresent(VertexBuffer.MatricesIndicesKind) &&\r\n                this.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind))\r\n        );\r\n    }\r\n\r\n    /** @internal */\r\n    public _preActivate(): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _preActivateForIntermediateRendering(renderId: number): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _activate(renderId: number, intermediateRendering: boolean): boolean {\r\n        this._renderId = renderId;\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _postActivate(): void {\r\n        // Do nothing\r\n    }\r\n\r\n    /** @internal */\r\n    public _freeze() {\r\n        // Do nothing\r\n    }\r\n\r\n    /** @internal */\r\n    public _unFreeze() {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Gets the current world matrix\r\n     * @returns a Matrix\r\n     */\r\n    public override getWorldMatrix(): Matrix {\r\n        if (this._masterMesh && this.billboardMode === TransformNode.BILLBOARDMODE_NONE) {\r\n            return this._masterMesh.getWorldMatrix();\r\n        }\r\n\r\n        return super.getWorldMatrix();\r\n    }\r\n\r\n    /** @internal */\r\n    public override _getWorldMatrixDeterminant(): number {\r\n        if (this._masterMesh) {\r\n            return this._masterMesh._getWorldMatrixDeterminant();\r\n        }\r\n\r\n        return super._getWorldMatrixDeterminant();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this mesh is an instance or a regular mesh\r\n     */\r\n    public get isAnInstance(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this mesh has instances\r\n     */\r\n    public get hasInstances(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this mesh has thin instances\r\n     */\r\n    public get hasThinInstances(): boolean {\r\n        return false;\r\n    }\r\n\r\n    // ================================== Point of View Movement =================================\r\n\r\n    /**\r\n     * Perform relative position change from the point of view of behind the front of the mesh.\r\n     * This is performed taking into account the meshes current rotation, so you do not have to care.\r\n     * Supports definition of mesh facing forward or backward {@link definedFacingForwardSearch | See definedFacingForwardSearch }.\r\n     * @param amountRight defines the distance on the right axis\r\n     * @param amountUp defines the distance on the up axis\r\n     * @param amountForward defines the distance on the forward axis\r\n     * @returns the current mesh\r\n     */\r\n    public movePOV(amountRight: number, amountUp: number, amountForward: number): AbstractMesh {\r\n        this.position.addInPlace(this.calcMovePOV(amountRight, amountUp, amountForward));\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Calculate relative position change from the point of view of behind the front of the mesh.\r\n     * This is performed taking into account the meshes current rotation, so you do not have to care.\r\n     * Supports definition of mesh facing forward or backward {@link definedFacingForwardSearch | See definedFacingForwardSearch }.\r\n     * @param amountRight defines the distance on the right axis\r\n     * @param amountUp defines the distance on the up axis\r\n     * @param amountForward defines the distance on the forward axis\r\n     * @returns the new displacement vector\r\n     */\r\n    public calcMovePOV(amountRight: number, amountUp: number, amountForward: number): Vector3 {\r\n        const rotMatrix = new Matrix();\r\n        const rotQuaternion = this.rotationQuaternion ? this.rotationQuaternion : Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);\r\n        rotQuaternion.toRotationMatrix(rotMatrix);\r\n\r\n        const translationDelta = Vector3.Zero();\r\n        const defForwardMult = this.definedFacingForward ? -1 : 1;\r\n        Vector3.TransformCoordinatesFromFloatsToRef(amountRight * defForwardMult, amountUp, amountForward * defForwardMult, rotMatrix, translationDelta);\r\n        return translationDelta;\r\n    }\r\n    // ================================== Point of View Rotation =================================\r\n    /**\r\n     * Perform relative rotation change from the point of view of behind the front of the mesh.\r\n     * Supports definition of mesh facing forward or backward {@link definedFacingForwardSearch | See definedFacingForwardSearch }.\r\n     * @param flipBack defines the flip\r\n     * @param twirlClockwise defines the twirl\r\n     * @param tiltRight defines the tilt\r\n     * @returns the current mesh\r\n     */\r\n    public rotatePOV(flipBack: number, twirlClockwise: number, tiltRight: number): AbstractMesh {\r\n        this.rotation.addInPlace(this.calcRotatePOV(flipBack, twirlClockwise, tiltRight));\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Calculate relative rotation change from the point of view of behind the front of the mesh.\r\n     * Supports definition of mesh facing forward or backward {@link definedFacingForwardSearch | See definedFacingForwardSearch }.\r\n     * @param flipBack defines the flip\r\n     * @param twirlClockwise defines the twirl\r\n     * @param tiltRight defines the tilt\r\n     * @returns the new rotation vector\r\n     */\r\n    public calcRotatePOV(flipBack: number, twirlClockwise: number, tiltRight: number): Vector3 {\r\n        const defForwardMult = this.definedFacingForward ? 1 : -1;\r\n        return new Vector3(flipBack * defForwardMult, twirlClockwise, tiltRight * defForwardMult);\r\n    }\r\n\r\n    /**\r\n     * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.\r\n     * This means the mesh underlying bounding box and sphere are recomputed.\r\n     * @param options defines a set of options for computing the bounding info\r\n     * @returns the current mesh\r\n     */\r\n    public abstract refreshBoundingInfo(options: IMeshDataOptions): AbstractMesh;\r\n\r\n    /**\r\n     * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.\r\n     * This means the mesh underlying bounding box and sphere are recomputed.\r\n     * @param applySkeletonOrOptions defines whether to apply the skeleton before computing the bounding info or a set of options\r\n     * @param applyMorph defines whether to apply the morph target before computing the bounding info\r\n     * @returns the current mesh\r\n     */\r\n    public abstract refreshBoundingInfo(applySkeletonOrOptions: boolean | IMeshDataOptions, applyMorph: boolean): AbstractMesh;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _refreshBoundingInfo(data: Nullable<FloatArray>, bias: Nullable<Vector2>): void {\r\n        if (data) {\r\n            const extend = extractMinAndMax(data, 0, this.getTotalVertices(), bias);\r\n            if (this._boundingInfo) {\r\n                this._boundingInfo.reConstruct(extend.minimum, extend.maximum);\r\n            } else {\r\n                this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);\r\n            }\r\n        }\r\n\r\n        if (this.subMeshes) {\r\n            for (let index = 0; index < this.subMeshes.length; index++) {\r\n                this.subMeshes[index].refreshBoundingInfo(data);\r\n            }\r\n        }\r\n\r\n        this._updateBoundingInfo();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _refreshBoundingInfoDirect(extend: { minimum: Vector3; maximum: Vector3 }): void {\r\n        if (this._boundingInfo) {\r\n            this._boundingInfo.reConstruct(extend.minimum, extend.maximum);\r\n        } else {\r\n            this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);\r\n        }\r\n\r\n        if (this.subMeshes) {\r\n            for (let index = 0; index < this.subMeshes.length; index++) {\r\n                this.subMeshes[index].refreshBoundingInfo(null);\r\n            }\r\n        }\r\n\r\n        this._updateBoundingInfo();\r\n    }\r\n\r\n    // This function is only here so we can apply the nativeOverride decorator.\r\n    @nativeOverride.filter(\r\n        (...args: Parameters<typeof AbstractMesh._ApplySkeleton>) =>\r\n            !Array.isArray(args[0]) && !Array.isArray(args[3]) && !Array.isArray(args[4]) && !Array.isArray(args[5]) && !Array.isArray(args[6])\r\n    )\r\n    private static _ApplySkeleton(\r\n        data: FloatArray,\r\n        kind: string,\r\n        skeletonMatrices: Float32Array,\r\n        matricesIndicesData: FloatArray,\r\n        matricesWeightsData: FloatArray,\r\n        matricesIndicesExtraData: Nullable<FloatArray>,\r\n        matricesWeightsExtraData: Nullable<FloatArray>\r\n    ): void {\r\n        ApplySkeleton(data, kind, skeletonMatrices, matricesIndicesData, matricesWeightsData, matricesIndicesExtraData, matricesWeightsExtraData);\r\n    }\r\n\r\n    /** @internal */\r\n    public _getData(options: IMeshDataOptions, data: Nullable<FloatArray>, kind: string = VertexBuffer.PositionKind): Nullable<FloatArray> {\r\n        const cache = options.cache;\r\n\r\n        const getVertexData = (kind: string): Nullable<FloatArray> => {\r\n            if (cache) {\r\n                const vertexData = (cache._vertexData ||= {});\r\n                if (!vertexData[kind]) {\r\n                    this.copyVerticesData(kind, vertexData);\r\n                }\r\n                return vertexData[kind];\r\n            }\r\n\r\n            return this.getVerticesData(kind);\r\n        };\r\n\r\n        data ||= getVertexData(kind);\r\n        if (!data) {\r\n            return null;\r\n        }\r\n\r\n        if (cache) {\r\n            if (cache._outputData) {\r\n                cache._outputData.set(data);\r\n            } else {\r\n                cache._outputData = new Float32Array(data);\r\n            }\r\n\r\n            data = cache._outputData;\r\n        } else if (\r\n            (options.applyMorph && this.morphTargetManager) ||\r\n            (options.applySkeleton && this.skeleton) ||\r\n            (options.applyBakedVertexAnimation && this.bakedVertexAnimationManager?.isEnabled)\r\n        ) {\r\n            data = data.slice();\r\n        }\r\n\r\n        if (options.applyMorph && this.morphTargetManager) {\r\n            ApplyMorph(data, kind, this.morphTargetManager);\r\n        }\r\n\r\n        const bakedVertexAnimationManager = this.bakedVertexAnimationManager;\r\n        let bakedVertexAnimationApplied = false;\r\n        if (options.applyBakedVertexAnimation && bakedVertexAnimationManager?.isEnabled) {\r\n            const matricesIndicesData = getVertexData(VertexBuffer.MatricesIndicesKind);\r\n            const matricesWeightsData = getVertexData(VertexBuffer.MatricesWeightsKind);\r\n            if (matricesWeightsData && matricesIndicesData) {\r\n                const needExtras = this.numBoneInfluencers > 4;\r\n                const matricesIndicesExtraData = needExtras ? getVertexData(VertexBuffer.MatricesIndicesExtraKind) : null;\r\n                const matricesWeightsExtraData = needExtras ? getVertexData(VertexBuffer.MatricesWeightsExtraKind) : null;\r\n                bakedVertexAnimationApplied = ApplyBakedVertexAnimation(\r\n                    data,\r\n                    kind,\r\n                    bakedVertexAnimationManager,\r\n                    options.bakedVertexAnimationSettings ?? bakedVertexAnimationManager.animationParameters,\r\n                    matricesIndicesData,\r\n                    matricesWeightsData,\r\n                    matricesIndicesExtraData,\r\n                    matricesWeightsExtraData,\r\n                    this.numBoneInfluencers\r\n                );\r\n            }\r\n        }\r\n\r\n        if (!bakedVertexAnimationApplied && options.applySkeleton && this.skeleton) {\r\n            const matricesIndicesData = getVertexData(VertexBuffer.MatricesIndicesKind);\r\n            const matricesWeightsData = getVertexData(VertexBuffer.MatricesWeightsKind);\r\n            if (matricesWeightsData && matricesIndicesData) {\r\n                const needExtras = this.numBoneInfluencers > 4;\r\n                const matricesIndicesExtraData = needExtras ? getVertexData(VertexBuffer.MatricesIndicesExtraKind) : null;\r\n                const matricesWeightsExtraData = needExtras ? getVertexData(VertexBuffer.MatricesWeightsExtraKind) : null;\r\n                const skeletonMatrices = this.skeleton.getTransformMatrices(this);\r\n                AbstractMesh._ApplySkeleton(data, kind, skeletonMatrices, matricesIndicesData, matricesWeightsData, matricesIndicesExtraData, matricesWeightsExtraData);\r\n            }\r\n        }\r\n\r\n        if (options.updatePositionsArray !== false && kind === VertexBuffer.PositionKind) {\r\n            const positions = this._internalAbstractMeshDataInfo._positions || [];\r\n            const previousLength = positions.length;\r\n            positions.length = data.length / 3;\r\n            if (previousLength < positions.length) {\r\n                for (let positionIndex = previousLength; positionIndex < positions.length; positionIndex++) {\r\n                    positions[positionIndex] = new Vector3();\r\n                }\r\n            }\r\n\r\n            for (let positionIndex = 0, dataIndex = 0; positionIndex < positions.length; positionIndex++, dataIndex += 3) {\r\n                positions[positionIndex].copyFromFloats(data[dataIndex], data[dataIndex + 1], data[dataIndex + 2]);\r\n            }\r\n\r\n            this._internalAbstractMeshDataInfo._positions = positions;\r\n        }\r\n\r\n        return data;\r\n    }\r\n\r\n    /**\r\n     * Get the normals vertex data and optionally apply skeleton and morphing.\r\n     * @param applySkeleton defines whether to apply the skeleton\r\n     * @param applyMorph  defines whether to apply the morph target\r\n     * @returns the normals data\r\n     */\r\n    public getNormalsData(applySkeleton = false, applyMorph = false): Nullable<FloatArray> {\r\n        return this._getData({ applySkeleton, applyMorph, updatePositionsArray: false }, null, VertexBuffer.NormalKind);\r\n    }\r\n\r\n    /**\r\n     * Get the position vertex data and optionally apply skeleton and morphing.\r\n     * @param applySkeleton defines whether to apply the skeleton\r\n     * @param applyMorph  defines whether to apply the morph target\r\n     * @param data defines the position data to apply the skeleton and morph to\r\n     * @returns the position data\r\n     */\r\n    public getPositionData(applySkeleton: boolean = false, applyMorph: boolean = false, data: Nullable<FloatArray> = null): Nullable<FloatArray> {\r\n        return this._getData({ applySkeleton, applyMorph, updatePositionsArray: false }, data, VertexBuffer.PositionKind);\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateBoundingInfo(): AbstractMesh {\r\n        if (this._boundingInfo) {\r\n            this._boundingInfo.update(this.worldMatrixFromCache);\r\n        } else {\r\n            this._boundingInfo = new BoundingInfo(Vector3.Zero(), Vector3.Zero(), this.worldMatrixFromCache);\r\n        }\r\n        this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _updateSubMeshesBoundingInfo(matrix: DeepImmutable<Matrix>): AbstractMesh {\r\n        if (!this.subMeshes) {\r\n            return this;\r\n        }\r\n        const count = this.subMeshes.length;\r\n        for (let subIndex = 0; subIndex < count; subIndex++) {\r\n            const subMesh = this.subMeshes[subIndex];\r\n            if (count > 1 || !subMesh.IsGlobal) {\r\n                subMesh.updateBoundingInfo(matrix);\r\n            }\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    protected override _afterComputeWorldMatrix(): void {\r\n        if (this.doNotSyncBoundingInfo) {\r\n            return;\r\n        }\r\n        // Bounding info\r\n        this._boundingInfoIsDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Returns `true` if the mesh is within the frustum defined by the passed array of planes.\r\n     * A mesh is in the frustum if its bounding box intersects the frustum\r\n     * @param frustumPlanes defines the frustum to test\r\n     * @returns true if the mesh is in the frustum planes\r\n     */\r\n    public isInFrustum(frustumPlanes: Plane[]): boolean {\r\n        return this.getBoundingInfo().isInFrustum(frustumPlanes, this.cullingStrategy);\r\n    }\r\n\r\n    /**\r\n     * Returns `true` if the mesh is completely in the frustum defined be the passed array of planes.\r\n     * A mesh is completely in the frustum if its bounding box it completely inside the frustum.\r\n     * @param frustumPlanes defines the frustum to test\r\n     * @returns true if the mesh is completely in the frustum planes\r\n     */\r\n    public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {\r\n        return this.getBoundingInfo().isCompletelyInFrustum(frustumPlanes);\r\n    }\r\n\r\n    /**\r\n     * True if the mesh intersects another mesh or a SolidParticle object\r\n     * @param mesh defines a target mesh or SolidParticle to test\r\n     * @param precise Unless the parameter `precise` is set to `true` the intersection is computed according to Axis Aligned Bounding Boxes (AABB), else according to OBB (Oriented BBoxes)\r\n     * @param includeDescendants Can be set to true to test if the mesh defined in parameters intersects with the current mesh or any child meshes\r\n     * @returns true if there is an intersection\r\n     */\r\n    public intersectsMesh(mesh: AbstractMesh | SolidParticle, precise: boolean = false, includeDescendants?: boolean): boolean {\r\n        const boundingInfo = this.getBoundingInfo();\r\n        const otherBoundingInfo = mesh.getBoundingInfo();\r\n\r\n        if (boundingInfo.intersects(otherBoundingInfo, precise)) {\r\n            return true;\r\n        }\r\n\r\n        if (includeDescendants) {\r\n            for (const child of this.getChildMeshes()) {\r\n                if (child.intersectsMesh(mesh, precise, true)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the passed point (Vector3) is inside the mesh bounding box\r\n     * @param point defines the point to test\r\n     * @returns true if there is an intersection\r\n     */\r\n    public intersectsPoint(point: Vector3): boolean {\r\n        return this.getBoundingInfo().intersectsPoint(point);\r\n    }\r\n\r\n    // Collisions\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this mesh can be used in the collision engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     */\r\n    public get checkCollisions(): boolean {\r\n        return this._internalAbstractMeshDataInfo._meshCollisionData._checkCollisions;\r\n    }\r\n\r\n    public set checkCollisions(collisionEnabled: boolean) {\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._checkCollisions = collisionEnabled;\r\n    }\r\n\r\n    /**\r\n     * Gets Collider object used to compute collisions (not physics)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     */\r\n    public get collider(): Nullable<Collider> {\r\n        return this._internalAbstractMeshDataInfo._meshCollisionData._collider;\r\n    }\r\n\r\n    /**\r\n     * Move the mesh using collision engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions\r\n     * @param displacement defines the requested displacement vector\r\n     * @param slideOnCollide If true, the mesh will slide along a collider's surface.  If false, it will stop moving at the first collision. (true by default)\r\n     * @returns the current mesh\r\n     */\r\n    public moveWithCollisions(displacement: Vector3, slideOnCollide: boolean = true): AbstractMesh {\r\n        const globalPosition = this.getAbsolutePosition();\r\n\r\n        globalPosition.addToRef(this.ellipsoidOffset, this._internalAbstractMeshDataInfo._meshCollisionData._oldPositionForCollisions);\r\n        const coordinator = this.getScene().collisionCoordinator;\r\n\r\n        if (!this._internalAbstractMeshDataInfo._meshCollisionData._collider) {\r\n            this._internalAbstractMeshDataInfo._meshCollisionData._collider = coordinator.createCollider();\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._meshCollisionData._collider._radius = this.ellipsoid;\r\n\r\n        coordinator.getNewPosition(\r\n            this._internalAbstractMeshDataInfo._meshCollisionData._oldPositionForCollisions,\r\n            displacement,\r\n            this._internalAbstractMeshDataInfo._meshCollisionData._collider,\r\n            this.collisionRetryCount,\r\n            this,\r\n            this._onCollisionPositionChange,\r\n            this.uniqueId,\r\n            slideOnCollide\r\n        );\r\n        return this;\r\n    }\r\n\r\n    private _onCollisionPositionChange = (collisionId: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh> = null) => {\r\n        newPosition.subtractToRef(\r\n            this._internalAbstractMeshDataInfo._meshCollisionData._oldPositionForCollisions,\r\n            this._internalAbstractMeshDataInfo._meshCollisionData._diffPositionForCollisions\r\n        );\r\n\r\n        if (this._internalAbstractMeshDataInfo._meshCollisionData._diffPositionForCollisions.length() > AbstractEngine.CollisionsEpsilon) {\r\n            this.position.addInPlace(this._internalAbstractMeshDataInfo._meshCollisionData._diffPositionForCollisions);\r\n        }\r\n\r\n        if (collidedMesh) {\r\n            this.onCollideObservable.notifyObservers(collidedMesh);\r\n        }\r\n\r\n        this.onCollisionPositionChangeObservable.notifyObservers(this.position);\r\n    };\r\n\r\n    // Collisions\r\n    /**\r\n     * @internal\r\n     */\r\n    public _collideForSubMesh(subMesh: SubMesh, transformMatrix: Matrix, collider: Collider): AbstractMesh {\r\n        this._generatePointsArray();\r\n\r\n        if (!this._positions) {\r\n            return this;\r\n        }\r\n\r\n        // Transformation\r\n        if (!subMesh._lastColliderWorldVertices || !subMesh._lastColliderTransformMatrix!.equals(transformMatrix)) {\r\n            subMesh._lastColliderTransformMatrix = transformMatrix.clone();\r\n            subMesh._lastColliderWorldVertices = [];\r\n            subMesh._trianglePlanes = [];\r\n            const start = subMesh.verticesStart;\r\n            const end = subMesh.verticesStart + subMesh.verticesCount;\r\n            for (let i = start; i < end; i++) {\r\n                subMesh._lastColliderWorldVertices.push(Vector3.TransformCoordinates(this._positions[i], transformMatrix));\r\n            }\r\n        }\r\n\r\n        // Collide\r\n        collider._collide(\r\n            subMesh._trianglePlanes,\r\n            subMesh._lastColliderWorldVertices,\r\n            <IndicesArray>this.getIndices(),\r\n            subMesh.indexStart,\r\n            subMesh.indexStart + subMesh.indexCount,\r\n            subMesh.verticesStart,\r\n            !!subMesh.getMaterial(),\r\n            this,\r\n            this._shouldConvertRHS(),\r\n            subMesh.getMaterial()?.fillMode === Constants.MATERIAL_TriangleStripDrawMode\r\n        );\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _processCollisionsForSubMeshes(collider: Collider, transformMatrix: Matrix): AbstractMesh {\r\n        const subMeshes = this._scene.getCollidingSubMeshCandidates(this, collider);\r\n        const len = subMeshes.length;\r\n\r\n        for (let index = 0; index < len; index++) {\r\n            const subMesh = subMeshes.data[index];\r\n\r\n            // Bounding test\r\n            if (len > 1 && !subMesh._checkCollision(collider)) {\r\n                continue;\r\n            }\r\n\r\n            this._collideForSubMesh(subMesh, transformMatrix, collider);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public _shouldConvertRHS() {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _checkCollision(collider: Collider): AbstractMesh {\r\n        // Bounding box test\r\n        if (!this.getBoundingInfo()._checkCollision(collider)) {\r\n            return this;\r\n        }\r\n\r\n        // Transformation matrix\r\n        const collisionsScalingMatrix = TmpVectors.Matrix[0];\r\n        const collisionsTransformMatrix = TmpVectors.Matrix[1];\r\n        Matrix.ScalingToRef(1.0 / collider._radius.x, 1.0 / collider._radius.y, 1.0 / collider._radius.z, collisionsScalingMatrix);\r\n        this.worldMatrixFromCache.multiplyToRef(collisionsScalingMatrix, collisionsTransformMatrix);\r\n        this._processCollisionsForSubMeshes(collider, collisionsTransformMatrix);\r\n        return this;\r\n    }\r\n\r\n    // Picking\r\n    /** @internal */\r\n    public _generatePointsArray(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the passed Ray intersects with the mesh. A mesh triangle can be picked both from its front and back sides,\r\n     * irrespective of orientation.\r\n     * @param ray defines the ray to use. It should be in the mesh's LOCAL coordinate space.\r\n     * @param fastCheck defines if fast mode (but less precise) must be used (false by default)\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)\r\n     * @param worldToUse defines the world matrix to use to get the world coordinate of the intersection point\r\n     * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n     * @returns the picking info\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/mesh_intersect\r\n     */\r\n    public intersects(\r\n        ray: Ray,\r\n        fastCheck?: boolean,\r\n        trianglePredicate?: TrianglePickingPredicate,\r\n        onlyBoundingInfo = false,\r\n        worldToUse?: Matrix,\r\n        skipBoundingInfo = false\r\n    ): PickingInfo {\r\n        const pickingInfo = new PickingInfo();\r\n        const className = this.getClassName();\r\n        const intersectionThreshold = className === \"InstancedLinesMesh\" || className === \"LinesMesh\" || className === \"GreasedLineMesh\" ? (this as any).intersectionThreshold : 0;\r\n        const boundingInfo = this.getBoundingInfo();\r\n        if (!this.subMeshes) {\r\n            return pickingInfo;\r\n        }\r\n        if (\r\n            !skipBoundingInfo &&\r\n            (!ray.intersectsSphere(boundingInfo.boundingSphere, intersectionThreshold) || !ray.intersectsBox(boundingInfo.boundingBox, intersectionThreshold))\r\n        ) {\r\n            return pickingInfo;\r\n        }\r\n\r\n        if (onlyBoundingInfo) {\r\n            pickingInfo.hit = skipBoundingInfo ? false : true;\r\n            pickingInfo.pickedMesh = skipBoundingInfo ? null : this;\r\n            pickingInfo.distance = skipBoundingInfo ? 0 : Vector3.Distance(ray.origin, boundingInfo.boundingSphere.center);\r\n            pickingInfo.subMeshId = 0;\r\n            return pickingInfo;\r\n        }\r\n\r\n        if (!this._generatePointsArray()) {\r\n            return pickingInfo;\r\n        }\r\n\r\n        let intersectInfo: Nullable<IntersectionInfo> = null;\r\n\r\n        const subMeshes = this._scene.getIntersectingSubMeshCandidates(this, ray);\r\n        const len: number = subMeshes.length;\r\n\r\n        // Check if all submeshes are using a material that don't allow picking (point/lines rendering)\r\n        // if no submesh can be picked that way, then fallback to BBox picking\r\n        let anySubmeshSupportIntersect = false;\r\n        for (let index = 0; index < len; index++) {\r\n            const subMesh = subMeshes.data[index];\r\n            const material = subMesh.getMaterial();\r\n            if (!material) {\r\n                continue;\r\n            }\r\n            if (\r\n                material.fillMode == Constants.MATERIAL_TriangleStripDrawMode ||\r\n                material.fillMode == Constants.MATERIAL_TriangleFillMode ||\r\n                material.fillMode == Constants.MATERIAL_WireFrameFillMode ||\r\n                material.fillMode == Constants.MATERIAL_PointFillMode ||\r\n                material.fillMode == Constants.MATERIAL_LineListDrawMode\r\n            ) {\r\n                anySubmeshSupportIntersect = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        // no sub mesh support intersection, fallback to BBox that has already be done\r\n        if (!anySubmeshSupportIntersect) {\r\n            pickingInfo.hit = true;\r\n            pickingInfo.pickedMesh = this;\r\n            pickingInfo.distance = Vector3.Distance(ray.origin, boundingInfo.boundingSphere.center);\r\n            pickingInfo.subMeshId = -1;\r\n            return pickingInfo;\r\n        }\r\n\r\n        // at least 1 submesh supports intersection, keep going\r\n        for (let index = 0; index < len; index++) {\r\n            const subMesh = subMeshes.data[index];\r\n\r\n            // Bounding test\r\n            if (len > 1 && !skipBoundingInfo && !subMesh.canIntersects(ray)) {\r\n                continue;\r\n            }\r\n\r\n            const currentIntersectInfo = subMesh.intersects(ray, <Vector3[]>this._positions, <IndicesArray>this.getIndices(), fastCheck, trianglePredicate);\r\n\r\n            if (currentIntersectInfo) {\r\n                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {\r\n                    intersectInfo = currentIntersectInfo;\r\n                    intersectInfo.subMeshId = subMesh._id;\r\n                    intersectInfo._internalSubMeshId = index;\r\n\r\n                    if (fastCheck) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (intersectInfo) {\r\n            // Get picked point\r\n            const world = worldToUse ?? this.getWorldMatrix();\r\n            const worldOrigin = TmpVectors.Vector3[0];\r\n            const direction = TmpVectors.Vector3[1];\r\n            Vector3.TransformCoordinatesToRef(ray.origin, world, worldOrigin);\r\n            ray.direction.scaleToRef(intersectInfo.distance, direction);\r\n            const worldDirection = Vector3.TransformNormal(direction, world);\r\n            const pickedPoint = worldDirection.addInPlace(worldOrigin);\r\n\r\n            // Return result\r\n            pickingInfo.hit = true;\r\n            pickingInfo.distance = Vector3.Distance(worldOrigin, pickedPoint);\r\n            pickingInfo.pickedPoint = pickedPoint;\r\n            pickingInfo.pickedMesh = this;\r\n            pickingInfo.bu = intersectInfo.bu || 0;\r\n            pickingInfo.bv = intersectInfo.bv || 0;\r\n            pickingInfo.subMeshFaceId = intersectInfo.faceId;\r\n            pickingInfo.faceId = intersectInfo.faceId + subMeshes.data[intersectInfo._internalSubMeshId].indexStart / (this.getClassName().indexOf(\"LinesMesh\") !== -1 ? 2 : 3);\r\n            pickingInfo.subMeshId = intersectInfo.subMeshId;\r\n            return pickingInfo;\r\n        }\r\n\r\n        return pickingInfo;\r\n    }\r\n\r\n    /**\r\n     * Clones the current mesh\r\n     * @param name defines the mesh name\r\n     * @param newParent defines the new mesh parent\r\n     * @param doNotCloneChildren defines a boolean indicating that children must not be cloned (false by default)\r\n     * @returns the new mesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public override clone(name: string, newParent: Nullable<Node>, doNotCloneChildren?: boolean): Nullable<AbstractMesh> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Disposes all the submeshes of the current mesh\r\n     * @param immediate should dispose the effects immediately or not\r\n     * @returns the current mesh\r\n     */\r\n    public releaseSubMeshes(immediate = false): AbstractMesh {\r\n        if (this.subMeshes) {\r\n            while (this.subMeshes.length) {\r\n                this.subMeshes[0].dispose(immediate);\r\n            }\r\n        } else {\r\n            this.subMeshes = [] as SubMesh[];\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Releases resources associated with this abstract mesh.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        let index: number;\r\n\r\n        const scene = this.getScene();\r\n\r\n        // mesh map release.\r\n        if (this._scene.useMaterialMeshMap) {\r\n            // remove from material mesh map id needed\r\n            if (this._internalAbstractMeshDataInfo._material && this._internalAbstractMeshDataInfo._material.meshMap) {\r\n                this._internalAbstractMeshDataInfo._material.meshMap[this.uniqueId] = undefined;\r\n            }\r\n        }\r\n\r\n        // Smart Array Retainers.\r\n        scene.freeActiveMeshes();\r\n        scene.freeRenderingGroups();\r\n        if (scene.renderingManager.maintainStateBetweenFrames) {\r\n            scene.renderingManager.restoreDispachedFlags();\r\n        }\r\n\r\n        // Action manager\r\n        if (this.actionManager !== undefined && this.actionManager !== null) {\r\n            // If we are the only mesh using the action manager, dispose of the action manager too unless it has opted out from that behavior\r\n            if (this.actionManager.disposeWhenUnowned && !this._scene.meshes.some((m) => m !== this && m.actionManager === this.actionManager)) {\r\n                this.actionManager.dispose();\r\n            }\r\n            this.actionManager = null;\r\n        }\r\n\r\n        // Skeleton\r\n        this._internalAbstractMeshDataInfo._skeleton = null;\r\n\r\n        if (this._transformMatrixTexture) {\r\n            this._transformMatrixTexture.dispose();\r\n            this._transformMatrixTexture = null;\r\n        }\r\n\r\n        // Intersections in progress\r\n        for (index = 0; index < this._intersectionsInProgress.length; index++) {\r\n            const other = this._intersectionsInProgress[index];\r\n\r\n            const pos = other._intersectionsInProgress.indexOf(this);\r\n            other._intersectionsInProgress.splice(pos, 1);\r\n        }\r\n\r\n        this._intersectionsInProgress.length = 0;\r\n\r\n        // Lights\r\n        const lights = scene.lights;\r\n\r\n        for (const light of lights) {\r\n            let meshIndex = light.includedOnlyMeshes.indexOf(this);\r\n\r\n            if (meshIndex !== -1) {\r\n                light.includedOnlyMeshes.splice(meshIndex, 1);\r\n            }\r\n\r\n            meshIndex = light.excludedMeshes.indexOf(this);\r\n\r\n            if (meshIndex !== -1) {\r\n                light.excludedMeshes.splice(meshIndex, 1);\r\n            }\r\n\r\n            // Shadow generators\r\n            const generators = light.getShadowGenerators();\r\n            if (generators) {\r\n                const iterator = generators.values();\r\n                for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                    const generator = key.value;\r\n                    const shadowMap = generator.getShadowMap();\r\n\r\n                    if (shadowMap && shadowMap.renderList) {\r\n                        meshIndex = shadowMap.renderList.indexOf(this);\r\n\r\n                        if (meshIndex !== -1) {\r\n                            shadowMap.renderList.splice(meshIndex, 1);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // SubMeshes\r\n        // Defer the effect release to the next frame so that a mesh recreated in the same tick with the same\r\n        // (or a cloned) material can reuse the still-cached compiled effect instead of triggering a recompile\r\n        // (which would skip a frame and cause a visible flash). During scene teardown we release immediately,\r\n        // since there may be no further frame to run the deferred disposal.\r\n        this.releaseSubMeshes(scene._isDisposing);\r\n\r\n        // Query\r\n        const engine = scene.getEngine();\r\n        if (this._occlusionQuery !== null) {\r\n            this.isOcclusionQueryInProgress = false;\r\n            engine.deleteQuery(this._occlusionQuery);\r\n            this._occlusionQuery = null;\r\n        }\r\n\r\n        // Engine\r\n        engine.wipeCaches();\r\n\r\n        // Remove from scene\r\n        scene.removeMesh(this);\r\n\r\n        if (this._parentContainer) {\r\n            const index = this._parentContainer.meshes.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.meshes.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        if (disposeMaterialAndTextures) {\r\n            if (this.material) {\r\n                if (this.material.getClassName() === \"MultiMaterial\") {\r\n                    this.material.dispose(false, true, true);\r\n                } else {\r\n                    this.material.dispose(false, true);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!doNotRecurse) {\r\n            // Particles\r\n            for (index = 0; index < scene.particleSystems.length; index++) {\r\n                if (scene.particleSystems[index].emitter === this) {\r\n                    scene.particleSystems[index].dispose();\r\n                    index--;\r\n                }\r\n            }\r\n        }\r\n\r\n        // facet data\r\n        if (this._internalAbstractMeshDataInfo._facetData.facetDataEnabled) {\r\n            this.disableFacetData();\r\n        }\r\n\r\n        this._uniformBuffer.dispose();\r\n\r\n        this.onAfterWorldMatrixUpdateObservable.clear();\r\n        this.onCollideObservable.clear();\r\n        this.onCollisionPositionChangeObservable.clear();\r\n        this.onRebuildObservable.clear();\r\n\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n\r\n    // Facet data\r\n    /** @internal */\r\n    private _initFacetData(): AbstractMesh {\r\n        const data = this._internalAbstractMeshDataInfo._facetData;\r\n        if (!data.facetNormals) {\r\n            data.facetNormals = [] as Vector3[];\r\n        }\r\n        if (!data.facetPositions) {\r\n            data.facetPositions = [] as Vector3[];\r\n        }\r\n        if (!data.facetPartitioning) {\r\n            data.facetPartitioning = new Array<number[]>();\r\n        }\r\n        data.facetNb = ((<IndicesArray>this.getIndices()).length / 3) | 0;\r\n        data.partitioningSubdivisions = data.partitioningSubdivisions ? data.partitioningSubdivisions : 10; // default nb of partitioning subdivisions = 10\r\n        data.partitioningBBoxRatio = data.partitioningBBoxRatio ? data.partitioningBBoxRatio : 1.01; // default ratio 1.01 = the partitioning is 1% bigger than the bounding box\r\n        for (let f = 0; f < data.facetNb; f++) {\r\n            data.facetNormals[f] = Vector3.Zero();\r\n            data.facetPositions[f] = Vector3.Zero();\r\n        }\r\n        data.facetDataEnabled = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the mesh facetData arrays and the internal partitioning when the mesh is morphed or updated.\r\n     * This method can be called within the render loop.\r\n     * You don't need to call this method by yourself in the render loop when you update/morph a mesh with the methods CreateXXX() as they automatically manage this computation\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public updateFacetData(): AbstractMesh {\r\n        const data = this._internalAbstractMeshDataInfo._facetData;\r\n        if (!data.facetDataEnabled) {\r\n            this._initFacetData();\r\n        }\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n        const indices = this.getIndices();\r\n        const normals = this.getVerticesData(VertexBuffer.NormalKind)?.slice();\r\n        const bInfo = this.getBoundingInfo();\r\n\r\n        if (data.facetDepthSort && !data.facetDepthSortEnabled) {\r\n            // init arrays, matrix and sort function on first call\r\n            data.facetDepthSortEnabled = true;\r\n            if (indices instanceof Uint16Array) {\r\n                data.depthSortedIndices = new Uint16Array(indices);\r\n            } else if (indices instanceof Uint32Array) {\r\n                data.depthSortedIndices = new Uint32Array(indices);\r\n            } else {\r\n                let needs32bits = false;\r\n                for (let i = 0; i < indices!.length; i++) {\r\n                    if (indices![i] > 65535) {\r\n                        needs32bits = true;\r\n                        break;\r\n                    }\r\n                }\r\n                if (needs32bits) {\r\n                    data.depthSortedIndices = new Uint32Array(indices!);\r\n                } else {\r\n                    data.depthSortedIndices = new Uint16Array(indices!);\r\n                }\r\n            }\r\n            data.facetDepthSortFunction = function (f1, f2) {\r\n                return f2.sqDistance - f1.sqDistance;\r\n            };\r\n            if (!data.facetDepthSortFrom) {\r\n                const camera = this.getScene().activeCamera;\r\n                data.facetDepthSortFrom = camera ? camera.position : Vector3.Zero();\r\n            }\r\n            data.depthSortedFacets = [];\r\n            for (let f = 0; f < data.facetNb; f++) {\r\n                const depthSortedFacet = { ind: f * 3, sqDistance: 0.0 };\r\n                data.depthSortedFacets.push(depthSortedFacet);\r\n            }\r\n            data.invertedMatrix = Matrix.Identity();\r\n            data.facetDepthSortOrigin = Vector3.Zero();\r\n        }\r\n\r\n        data.bbSize.x = bInfo.maximum.x - bInfo.minimum.x > Epsilon ? bInfo.maximum.x - bInfo.minimum.x : Epsilon;\r\n        data.bbSize.y = bInfo.maximum.y - bInfo.minimum.y > Epsilon ? bInfo.maximum.y - bInfo.minimum.y : Epsilon;\r\n        data.bbSize.z = bInfo.maximum.z - bInfo.minimum.z > Epsilon ? bInfo.maximum.z - bInfo.minimum.z : Epsilon;\r\n        let bbSizeMax = data.bbSize.x > data.bbSize.y ? data.bbSize.x : data.bbSize.y;\r\n        bbSizeMax = bbSizeMax > data.bbSize.z ? bbSizeMax : data.bbSize.z;\r\n        data.subDiv.max = data.partitioningSubdivisions;\r\n        data.subDiv.X = Math.floor((data.subDiv.max * data.bbSize.x) / bbSizeMax); // adjust the number of subdivisions per axis\r\n        data.subDiv.Y = Math.floor((data.subDiv.max * data.bbSize.y) / bbSizeMax); // according to each bbox size per axis\r\n        data.subDiv.Z = Math.floor((data.subDiv.max * data.bbSize.z) / bbSizeMax);\r\n        data.subDiv.X = data.subDiv.X < 1 ? 1 : data.subDiv.X; // at least one subdivision\r\n        data.subDiv.Y = data.subDiv.Y < 1 ? 1 : data.subDiv.Y;\r\n        data.subDiv.Z = data.subDiv.Z < 1 ? 1 : data.subDiv.Z;\r\n        // set the parameters for ComputeNormals()\r\n        data.facetParameters.facetNormals = this.getFacetLocalNormals();\r\n        data.facetParameters.facetPositions = this.getFacetLocalPositions();\r\n        data.facetParameters.facetPartitioning = this.getFacetLocalPartitioning();\r\n        data.facetParameters.bInfo = bInfo;\r\n        data.facetParameters.bbSize = data.bbSize;\r\n        data.facetParameters.subDiv = data.subDiv;\r\n        data.facetParameters.ratio = this.partitioningBBoxRatio;\r\n        data.facetParameters.depthSort = data.facetDepthSort;\r\n        if (data.facetDepthSort && data.facetDepthSortEnabled) {\r\n            this.computeWorldMatrix(true);\r\n            this._worldMatrix.invertToRef(data.invertedMatrix);\r\n            Vector3.TransformCoordinatesToRef(data.facetDepthSortFrom, data.invertedMatrix, data.facetDepthSortOrigin);\r\n            data.facetParameters.distanceTo = data.facetDepthSortOrigin;\r\n        }\r\n        data.facetParameters.depthSortedFacets = data.depthSortedFacets;\r\n        if (normals) {\r\n            VertexData.ComputeNormals(positions, indices, normals, data.facetParameters);\r\n        }\r\n\r\n        if (data.facetDepthSort && data.facetDepthSortEnabled) {\r\n            data.depthSortedFacets.sort(data.facetDepthSortFunction);\r\n            const l = (data.depthSortedIndices.length / 3) | 0;\r\n            for (let f = 0; f < l; f++) {\r\n                const sind = data.depthSortedFacets[f].ind;\r\n                data.depthSortedIndices[f * 3] = indices![sind];\r\n                data.depthSortedIndices[f * 3 + 1] = indices![sind + 1];\r\n                data.depthSortedIndices[f * 3 + 2] = indices![sind + 2];\r\n            }\r\n            this.updateIndices(data.depthSortedIndices, undefined, true);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the facetLocalNormals array.\r\n     * The normals are expressed in the mesh local spac\r\n     * @returns an array of Vector3\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetLocalNormals(): Vector3[] {\r\n        const facetData = this._internalAbstractMeshDataInfo._facetData;\r\n        if (!facetData.facetNormals) {\r\n            this.updateFacetData();\r\n        }\r\n        return facetData.facetNormals;\r\n    }\r\n\r\n    /**\r\n     * Returns the facetLocalPositions array.\r\n     * The facet positions are expressed in the mesh local space\r\n     * @returns an array of Vector3\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetLocalPositions(): Vector3[] {\r\n        const facetData = this._internalAbstractMeshDataInfo._facetData;\r\n        if (!facetData.facetPositions) {\r\n            this.updateFacetData();\r\n        }\r\n        return facetData.facetPositions;\r\n    }\r\n\r\n    /**\r\n     * Returns the facetLocalPartitioning array\r\n     * @returns an array of array of numbers\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetLocalPartitioning(): number[][] {\r\n        const facetData = this._internalAbstractMeshDataInfo._facetData;\r\n\r\n        if (!facetData.facetPartitioning) {\r\n            this.updateFacetData();\r\n        }\r\n        return facetData.facetPartitioning;\r\n    }\r\n\r\n    /**\r\n     * Returns the i-th facet position in the world system.\r\n     * This method allocates a new Vector3 per call\r\n     * @param i defines the facet index\r\n     * @returns a new Vector3\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetPosition(i: number): Vector3 {\r\n        const pos = Vector3.Zero();\r\n        this.getFacetPositionToRef(i, pos);\r\n        return pos;\r\n    }\r\n\r\n    /**\r\n     * Sets the reference Vector3 with the i-th facet position in the world system\r\n     * @param i defines the facet index\r\n     * @param ref defines the target vector\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetPositionToRef(i: number, ref: Vector3): AbstractMesh {\r\n        const localPos = this.getFacetLocalPositions()[i];\r\n        const world = this.getWorldMatrix();\r\n        Vector3.TransformCoordinatesToRef(localPos, world, ref);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the i-th facet normal in the world system.\r\n     * This method allocates a new Vector3 per call\r\n     * @param i defines the facet index\r\n     * @returns a new Vector3\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetNormal(i: number): Vector3 {\r\n        const norm = Vector3.Zero();\r\n        this.getFacetNormalToRef(i, norm);\r\n        return norm;\r\n    }\r\n\r\n    /**\r\n     * Sets the reference Vector3 with the i-th facet normal in the world system\r\n     * @param i defines the facet index\r\n     * @param ref defines the target vector\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetNormalToRef(i: number, ref: Vector3) {\r\n        const localNorm = this.getFacetLocalNormals()[i];\r\n        Vector3.TransformNormalToRef(localNorm, this.getWorldMatrix(), ref);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the facets (in an array) in the same partitioning block than the one the passed coordinates are located (expressed in the mesh local system)\r\n     * @param x defines x coordinate\r\n     * @param y defines y coordinate\r\n     * @param z defines z coordinate\r\n     * @returns the array of facet indexes\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetsAtLocalCoordinates(x: number, y: number, z: number): Nullable<number[]> {\r\n        const bInfo = this.getBoundingInfo();\r\n        const data = this._internalAbstractMeshDataInfo._facetData;\r\n\r\n        const ox = Math.floor(((x - bInfo.minimum.x * data.partitioningBBoxRatio) * data.subDiv.X * data.partitioningBBoxRatio) / data.bbSize.x);\r\n        const oy = Math.floor(((y - bInfo.minimum.y * data.partitioningBBoxRatio) * data.subDiv.Y * data.partitioningBBoxRatio) / data.bbSize.y);\r\n        const oz = Math.floor(((z - bInfo.minimum.z * data.partitioningBBoxRatio) * data.subDiv.Z * data.partitioningBBoxRatio) / data.bbSize.z);\r\n        if (ox < 0 || ox > data.subDiv.max || oy < 0 || oy > data.subDiv.max || oz < 0 || oz > data.subDiv.max) {\r\n            return null;\r\n        }\r\n        return data.facetPartitioning[ox + data.subDiv.max * oy + data.subDiv.max * data.subDiv.max * oz];\r\n    }\r\n\r\n    /**\r\n     * Returns the closest mesh facet index at (x,y,z) World coordinates, null if not found\r\n     * @param x defines x coordinate\r\n     * @param y defines y coordinate\r\n     * @param z defines z coordinate\r\n     * @param projected sets as the (x,y,z) world projection on the facet\r\n     * @param checkFace if true (default false), only the facet \"facing\" to (x,y,z) or only the ones \"turning their backs\", according to the parameter \"facing\" are returned\r\n     * @param facing if facing and checkFace are true, only the facet \"facing\" to (x, y, z) are returned : positive dot (x, y, z) * facet position. If facing si false and checkFace is true, only the facet \"turning their backs\" to (x, y, z) are returned : negative dot (x, y, z) * facet position\r\n     * @returns the face index if found (or null instead)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getClosestFacetAtCoordinates(x: number, y: number, z: number, projected?: Vector3, checkFace: boolean = false, facing: boolean = true): Nullable<number> {\r\n        const world = this.getWorldMatrix();\r\n        const invMat = TmpVectors.Matrix[5];\r\n        world.invertToRef(invMat);\r\n        const invVect = TmpVectors.Vector3[8];\r\n        Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, invMat, invVect); // transform (x,y,z) to coordinates in the mesh local space\r\n        const closest = this.getClosestFacetAtLocalCoordinates(invVect.x, invVect.y, invVect.z, projected, checkFace, facing);\r\n        if (projected) {\r\n            // transform the local computed projected vector to world coordinates\r\n            Vector3.TransformCoordinatesFromFloatsToRef(projected.x, projected.y, projected.z, world, projected);\r\n        }\r\n        return closest;\r\n    }\r\n\r\n    /**\r\n     * Returns the closest mesh facet index at (x,y,z) local coordinates, null if not found\r\n     * @param x defines x coordinate\r\n     * @param y defines y coordinate\r\n     * @param z defines z coordinate\r\n     * @param projected sets as the (x,y,z) local projection on the facet\r\n     * @param checkFace if true (default false), only the facet \"facing\" to (x,y,z) or only the ones \"turning their backs\", according to the parameter \"facing\" are returned\r\n     * @param facing if facing and checkFace are true, only the facet \"facing\" to (x, y, z) are returned : positive dot (x, y, z) * facet position. If facing si false and checkFace is true, only the facet \"turning their backs\" to (x, y, z) are returned : negative dot (x, y, z) * facet position\r\n     * @returns the face index if found (or null instead)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getClosestFacetAtLocalCoordinates(x: number, y: number, z: number, projected?: Vector3, checkFace: boolean = false, facing: boolean = true): Nullable<number> {\r\n        let closest = null;\r\n        let tmpx: number;\r\n        let tmpy: number;\r\n        let tmpz: number;\r\n        let d: number; // tmp dot facet normal * facet position\r\n        let t0: number;\r\n        let projx: number;\r\n        let projy: number;\r\n        let projz: number;\r\n        // Get all the facets in the same partitioning block than (x, y, z)\r\n        const facetPositions = this.getFacetLocalPositions();\r\n        const facetNormals = this.getFacetLocalNormals();\r\n        const facetsInBlock = this.getFacetsAtLocalCoordinates(x, y, z);\r\n        if (!facetsInBlock) {\r\n            return null;\r\n        }\r\n        // Get the closest facet to (x, y, z)\r\n        let shortest = Number.MAX_VALUE; // init distance vars\r\n        let tmpDistance: number;\r\n        let fib; // current facet in the block\r\n        let norm; // current facet normal\r\n        let p0; // current facet barycenter position\r\n        // loop on all the facets in the current partitioning block\r\n        for (let idx = 0; idx < facetsInBlock.length; idx++) {\r\n            fib = facetsInBlock[idx];\r\n            norm = facetNormals[fib];\r\n            p0 = facetPositions[fib];\r\n\r\n            d = (x - p0.x) * norm.x + (y - p0.y) * norm.y + (z - p0.z) * norm.z;\r\n            if (!checkFace || (checkFace && facing && d >= 0.0) || (checkFace && !facing && d <= 0.0)) {\r\n                // compute (x,y,z) projection on the facet = (projx, projy, projz)\r\n                d = norm.x * p0.x + norm.y * p0.y + norm.z * p0.z;\r\n                t0 = -(norm.x * x + norm.y * y + norm.z * z - d) / (norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);\r\n                projx = x + norm.x * t0;\r\n                projy = y + norm.y * t0;\r\n                projz = z + norm.z * t0;\r\n\r\n                tmpx = projx - x;\r\n                tmpy = projy - y;\r\n                tmpz = projz - z;\r\n                tmpDistance = tmpx * tmpx + tmpy * tmpy + tmpz * tmpz; // compute length between (x, y, z) and its projection on the facet\r\n                if (tmpDistance < shortest) {\r\n                    // just keep the closest facet to (x, y, z)\r\n                    shortest = tmpDistance;\r\n                    closest = fib;\r\n                    if (projected) {\r\n                        projected.x = projx;\r\n                        projected.y = projy;\r\n                        projected.z = projz;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return closest;\r\n    }\r\n\r\n    /**\r\n     * Returns the object \"parameter\" set with all the expected parameters for facetData computation by ComputeNormals()\r\n     * @returns the parameters\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public getFacetDataParameters(): any {\r\n        return this._internalAbstractMeshDataInfo._facetData.facetParameters;\r\n    }\r\n\r\n    /**\r\n     * Disables the feature FacetData and frees the related memory\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/facetData\r\n     */\r\n    public disableFacetData(): AbstractMesh {\r\n        const facetData = this._internalAbstractMeshDataInfo._facetData;\r\n        if (facetData.facetDataEnabled) {\r\n            facetData.facetDataEnabled = false;\r\n            facetData.facetPositions = [] as Vector3[];\r\n            facetData.facetNormals = [] as Vector3[];\r\n            facetData.facetPartitioning = new Array<number[]>();\r\n            facetData.facetParameters = {};\r\n            facetData.depthSortedIndices = new Uint32Array(0);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Updates the AbstractMesh indices array\r\n     * @param indices defines the data source\r\n     * @param offset defines the offset in the index buffer where to store the new data (can be null)\r\n     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)\r\n     * @returns the current mesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public updateIndices(indices: IndicesArray, offset?: number, gpuMemoryOnly = false): AbstractMesh {\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates new normals data for the mesh\r\n     * @param updatable defines if the normal vertex buffer must be flagged as updatable\r\n     * @returns the current mesh\r\n     */\r\n    public createNormals(updatable: boolean): AbstractMesh {\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n        const indices = this.getIndices();\r\n        let normals: FloatArray;\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            normals = <FloatArray>this.getVerticesData(VertexBuffer.NormalKind);\r\n        } else {\r\n            normals = [];\r\n        }\r\n\r\n        VertexData.ComputeNormals(positions, indices, normals, { useRightHandedSystem: this.getScene().useRightHandedSystem });\r\n        this.setVerticesData(VertexBuffer.NormalKind, normals, updatable);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Optimize the indices order so that we keep the faces with similar indices together\r\n     * @returns the current mesh\r\n     */\r\n    public async optimizeIndicesAsync(): Promise<AbstractMesh> {\r\n        const indices = this.getIndices();\r\n\r\n        if (!indices) {\r\n            return this;\r\n        }\r\n\r\n        const { OptimizeIndices } = await import(\"./mesh.vertexData.functions\");\r\n\r\n        OptimizeIndices(indices);\r\n\r\n        this.setIndices(indices, this.getTotalVertices());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Align the mesh with a normal\r\n     * @param normal defines the normal to use\r\n     * @param upDirection can be used to redefined the up vector to use (will use the (0, 1, 0) by default)\r\n     * @returns the current mesh\r\n     */\r\n    public alignWithNormal(normal: Vector3, upDirection?: Vector3): AbstractMesh {\r\n        if (!upDirection) {\r\n            upDirection = Axis.Y;\r\n        }\r\n\r\n        const axisX = TmpVectors.Vector3[0];\r\n        const axisZ = TmpVectors.Vector3[1];\r\n        Vector3.CrossToRef(upDirection, normal, axisZ);\r\n        Vector3.CrossToRef(normal, axisZ, axisX);\r\n\r\n        if (this.rotationQuaternion) {\r\n            Quaternion.RotationQuaternionFromAxisToRef(axisX, normal, axisZ, this.rotationQuaternion);\r\n        } else {\r\n            Vector3.RotationFromAxisToRef(axisX, normal, axisZ, this.rotation);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public _checkOcclusionQuery(_checkOnly = false): boolean {\r\n        // Will be replaced by correct code if Occlusion queries are referenced\r\n        return false;\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Disables the mesh edge rendering mode\r\n     * @returns the currentAbstractMesh\r\n     */\r\n    disableEdgesRendering(): AbstractMesh {\r\n        throw _WarnImport(\"EdgesRenderer\");\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Enables the edge rendering mode on the mesh.\r\n     * This mode makes the mesh edges visible\r\n     * @param epsilon defines the maximal distance between two angles to detect a face\r\n     * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces\r\n     * @param options options to the edge renderer\r\n     * @returns the currentAbstractMesh\r\n     * @see https://www.babylonjs-playground.com/#19O9TU#0\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean, options?: IEdgesRendererOptions): AbstractMesh {\r\n        throw _WarnImport(\"EdgesRenderer\");\r\n    }\r\n\r\n    /**\r\n     * This function returns all of the particle systems in the scene that use the mesh as an emitter.\r\n     * @returns an array of particle systems in the scene that use the mesh as an emitter\r\n     */\r\n    public getConnectedParticleSystems(): IParticleSystem[] {\r\n        return this._scene.particleSystems.filter((particleSystem) => particleSystem.emitter === this);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AbstractMesh\", AbstractMesh);\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\n\r\nAbstractMesh.prototype.createOrUpdateSubmeshesOctree ??= _MissingSideEffect(\"AbstractMesh\", \"createOrUpdateSubmeshesOctree\") as any;\r\nAbstractMesh.prototype.getPhysicsImpostor ??= _MissingSideEffect(\"AbstractMesh\", \"getPhysicsImpostor\") as any;\r\nAbstractMesh.prototype.setPhysicsLinkWith ??= _MissingSideEffect(\"AbstractMesh\", \"setPhysicsLinkWith\") as any;\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"occlusionRetryCount\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionRetryCount\", _MissingSideEffectProperty(\"AbstractMesh\", \"occlusionRetryCount\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"occlusionType\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionType\", _MissingSideEffectProperty(\"AbstractMesh\", \"occlusionType\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"occlusionQueryAlgorithmType\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionQueryAlgorithmType\", _MissingSideEffectProperty(\"AbstractMesh\", \"occlusionQueryAlgorithmType\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"isOccluded\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"isOccluded\", _MissingSideEffectProperty(\"AbstractMesh\", \"isOccluded\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"isOcclusionQueryInProgress\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"isOcclusionQueryInProgress\", _MissingSideEffectProperty(\"AbstractMesh\", \"isOcclusionQueryInProgress\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"forceRenderingWhenOccluded\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"forceRenderingWhenOccluded\", _MissingSideEffectProperty(\"AbstractMesh\", \"forceRenderingWhenOccluded\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"occlusionForRenderPassId\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionForRenderPassId\", _MissingSideEffectProperty(\"AbstractMesh\", \"occlusionForRenderPassId\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"decalMap\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"decalMap\", _MissingSideEffectProperty(\"AbstractMesh\", \"decalMap\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"instancedBuffers\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"instancedBuffers\", _MissingSideEffectProperty(\"AbstractMesh\", \"instancedBuffers\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"physicsImpostor\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"physicsImpostor\", _MissingSideEffectProperty(\"AbstractMesh\", \"physicsImpostor\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"showBoundingBox\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"showBoundingBox\", _MissingSideEffectProperty(\"AbstractMesh\", \"showBoundingBox\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"edgesRenderer\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"edgesRenderer\", _MissingSideEffectProperty(\"AbstractMesh\", \"edgesRenderer\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"renderOutline\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"renderOutline\", _MissingSideEffectProperty(\"AbstractMesh\", \"renderOutline\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(AbstractMesh.prototype, \"renderOverlay\")) {\r\n    Object.defineProperty(AbstractMesh.prototype, \"renderOverlay\", _MissingSideEffectProperty(\"AbstractMesh\", \"renderOverlay\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","import { Vector3 } from \"./math.vector.pure\";\r\n\r\n/** Defines supported spaces */\r\nexport const enum Space {\r\n    /** Local (object) space */\r\n    LOCAL = 0,\r\n    /** World space */\r\n    WORLD = 1,\r\n    /** Bone space */\r\n    BONE = 2,\r\n}\r\n\r\n/** Defines the 3 main axes */\r\nexport class Axis {\r\n    /** X axis */\r\n    public static X: Vector3 = new Vector3(1.0, 0.0, 0.0);\r\n    /** Y axis */\r\n    public static Y: Vector3 = new Vector3(0.0, 1.0, 0.0);\r\n    /** Z axis */\r\n    public static Z: Vector3 = new Vector3(0.0, 0.0, 1.0);\r\n}\r\n\r\n/**\r\n * Defines cartesian components.\r\n */\r\nexport const enum Coordinate {\r\n    /** X axis */\r\n    X,\r\n    /** Y axis */\r\n    Y,\r\n    /** Z axis */\r\n    Z,\r\n}\r\n","import {\r\n    type MorphTargetManager,\r\n    type Immutable,\r\n    type Bone,\r\n    type Nullable,\r\n    type MorphTarget,\r\n    type AnimationGroup,\r\n    type Animation,\r\n    type Node,\r\n    type Skeleton,\r\n    type TargetedAnimation,\r\n    type DeepImmutableObject,\r\n} from \"core/index\";\r\nimport { Vector3, Quaternion, TmpVectors, Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\n\r\n/**\r\n * Options for retargeting an animation group to an avatar.\r\n */\r\nexport interface IRetargetOptions {\r\n    /**\r\n     * The name to assign to the (cloned) retargeted animation group.\r\n     * If not specified, the same name as the original animation group will be used.\r\n     */\r\n    animationGroupName?: string;\r\n\r\n    /**\r\n     * If true, the retargeted animations will be fixed to correct common issues like orthogonal quaternions.\r\n     * Default is false.\r\n     */\r\n    fixAnimations?: boolean;\r\n\r\n    /**\r\n     * If true, the parent hierarchy of bones and transform nodes will be checked during retargeting.\r\n     * Animations will be removed if the hierarchies don't match.\r\n     * Default is false.\r\n     */\r\n    checkHierarchy?: boolean;\r\n\r\n    /**\r\n     * If true, the frame values in the animation keyframes will be adjusted during retargeting to account for differences\r\n     * between the source and target bone transforms.\r\n     * Default is true.\r\n     */\r\n    retargetAnimationKeys?: boolean;\r\n\r\n    /**\r\n     * If true, scales and adjusts the root position animation to account for size differences between the source and target avatars.\r\n     * This helps maintain the relative motion of the character when retargeting between avatars of different proportions.\r\n     * Default is true.\r\n     */\r\n    fixRootPosition?: boolean;\r\n\r\n    /**\r\n     * If true, adjusts the root position animation to correct for ground reference height differences between the source and target avatars.\r\n     * This ensures that the animated character maintains proper contact with the ground during retargeting.\r\n     * Requires groundReferenceNodeName to be specified to determine the ground reference point in the source animation.\r\n     * Default is false.\r\n     */\r\n    fixGroundReference?: boolean;\r\n\r\n    /**\r\n     * If true, adjusts the ground reference dynamically during retargeting. fixGroundReference must be true for this to work.\r\n     * When enabled, the system will continuously adjust the ground reference point throughout the retargeting process to make sure it's the lowest point of the character.\r\n     * This allows for more accurate ground contact correction, especially in animations where groundReferenceNodeName is not always the lowest point (e.g., walking, running).\r\n     * Default is false.\r\n     */\r\n    fixGroundReferenceDynamicRefNode?: boolean;\r\n\r\n    /**\r\n     * The name of the root transform node in the source animation group (typically \"Hips\" or similar).\r\n     * If not specified, the system will attempt to automatically find the first bone without a parent.\r\n     * This bone is used as a reference point for fixing root position during retargeting.\r\n     * It's also used by the ground reference fixing processing.\r\n     */\r\n    rootNodeName?: string;\r\n\r\n    /**\r\n     * The name of the transform node in the source animation group used as a ground reference point (typically a foot bone like \"LeftFoot\" or \"RightFoot\").\r\n     * This bone is used to determine the vertical offset needed to maintain proper ground contact during retargeting.\r\n     * Required when fixGroundReference or fixRootPosition is enabled.\r\n     */\r\n    groundReferenceNodeName?: string;\r\n\r\n    /**\r\n     * Specifies which axis represents the vertical/up direction in the animation space.\r\n     * Use \"X\", \"Y\", or \"Z\" to explicitly set the vertical axis, or \"\" (empty string) / undefined to auto-detect.\r\n     * If not specified or empty, the system will automatically determine the vertical axis based on the difference\r\n     * between the root node and ground reference node positions.\r\n     * Default is undefined (auto-detect).\r\n     */\r\n    groundReferenceVerticalAxis?: \"\" | \"X\" | \"Y\" | \"Z\";\r\n\r\n    /**\r\n     * A map for renaming nodes during retargeting when the source transform node hierarchy and target skeleton use different naming conventions.\r\n     * The map keys are the original node names from the source animation group, and the values are the corresponding\r\n     * node names in the target skeleton. This is useful when bone names don't match between avatars.\r\n     */\r\n    mapNodeNames?: Map<string, string>;\r\n}\r\n\r\ntype TransformNodeNameToNode = Map<string, { node: TransformNode; initialTransformations: { position: Vector3; scaling: Vector3; quaternion?: Quaternion; rotation: Vector3 } }>;\r\n\r\ntype AvatarSkeletonStates = {\r\n    transformNodeStates: Map<TransformNode, { position: Vector3; scaling: Vector3; quaternion?: Quaternion; rotation: Vector3 }>;\r\n    boneMatrices: Map<Bone, Matrix>;\r\n};\r\n\r\n/**\r\n * Represents an animator avatar that manages meshes, skeletons and morph target managers for a hierarchical transform node and mesh structure.\r\n * This class is used to group and manage animation-related resources (meshes, skeletons and morph targets) associated with a root transform node and its descendants.\r\n */\r\nexport class AnimatorAvatar {\r\n    /**\r\n     * List of meshes found in the hierarchy of the root node. Only meshes with at least one vertex are included.\r\n     */\r\n    public meshes: AbstractMesh[];\r\n\r\n    /**\r\n     * Set of skeletons found in the mesh hierarchy.\r\n     */\r\n    public skeletons: Set<Skeleton>;\r\n\r\n    /**\r\n     * Set of morph target managers found in the mesh hierarchy.\r\n     * Each morph target manager is configured with the appropriate mesh name and influencer count.\r\n     */\r\n    public morphTargetManagers: Set<MorphTargetManager>;\r\n\r\n    private _mapMorphTargetNameToMorphTarget: Map<string, MorphTarget>;\r\n    /**\r\n     * Map of morph target names to their corresponding MorphTarget instances.\r\n     * The keys are constructed using the format \"meshName_morphTargetName\".\r\n     */\r\n    public get mapMorphTargetNameToMorphTarget(): Immutable<Map<string, MorphTarget>> {\r\n        if (!this._mapMorphTargetNameToMorphTarget) {\r\n            this._buildMorphTargetMap();\r\n        }\r\n        return this._mapMorphTargetNameToMorphTarget;\r\n    }\r\n\r\n    /**\r\n     * Indicates whether to show warnings during retargeting operations.\r\n     */\r\n    public showWarnings = true;\r\n\r\n    /**\r\n     * Creates an instance of AnimatorAvatar.\r\n     * @param name - The name to assign to this avatar and its root node\r\n     * @param rootNode - The root node of the avatar hierarchy. This node and its descendants will be scanned for meshes, skeletons and morph target managers. If not provided, you are expected to manually manage meshes, skeletons and morph target managers.\r\n     * @param _disposeResources - Indicates whether to dispose of resources (meshes, skeletons, morph target managers, root node and descendants + materials and textures) when the avatar is disposed (true by default)\r\n     * @param setAvatarName - Indicates whether to set the name of the root node to the avatar name. Default is true. Set this to false if you don't want the root node to be renamed, or if you want to set it to a different name after creating the avatar.\r\n     */\r\n    constructor(\r\n        public readonly name: string,\r\n        public readonly rootNode?: TransformNode,\r\n        private _disposeResources = true,\r\n        setAvatarName = true\r\n    ) {\r\n        this.meshes = [];\r\n        this.skeletons = new Set<Skeleton>();\r\n        this.morphTargetManagers = new Set<MorphTargetManager>();\r\n\r\n        if (!rootNode) {\r\n            return;\r\n        }\r\n\r\n        if (setAvatarName) {\r\n            rootNode.name = name;\r\n        }\r\n\r\n        if (rootNode instanceof AbstractMesh && rootNode.getTotalVertices() > 0) {\r\n            this._collectMesh(rootNode);\r\n        }\r\n\r\n        rootNode.getChildMeshes(false).forEach((mesh) => {\r\n            if (mesh.getTotalVertices() > 0) {\r\n                this._collectMesh(mesh);\r\n            }\r\n        });\r\n    }\r\n\r\n    private _collectMesh(mesh: AbstractMesh) {\r\n        this.meshes.push(mesh);\r\n\r\n        if (mesh.skeleton) {\r\n            this.skeletons.add(mesh.skeleton);\r\n        }\r\n\r\n        if (mesh.morphTargetManager) {\r\n            mesh.morphTargetManager.meshName = mesh.name;\r\n            mesh.morphTargetManager.numMaxInfluencers = mesh.morphTargetManager.numTargets;\r\n\r\n            this.morphTargetManagers.add(mesh.morphTargetManager);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Finds a bone in the avatar's skeletons by its linked transform node or the name of the linked transform node.\r\n     * @param nameOrTransformNode The linked transform node or the name of the linked transform node\r\n     * @returns The found bone or null if not found\r\n     */\r\n    public findBoneByTransformNode(nameOrTransformNode: string | TransformNode): Nullable<Bone> {\r\n        const isName = !this._isTransformNode(nameOrTransformNode);\r\n        const iterator = this.skeletons.keys();\r\n\r\n        let bone: Nullable<Bone>;\r\n\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const skeleton = key.value;\r\n\r\n            if (isName) {\r\n                bone = skeleton.findBoneFromLinkedTransformNodeName(nameOrTransformNode);\r\n            } else {\r\n                bone = skeleton.findBoneFromLinkedTransformNode(nameOrTransformNode);\r\n            }\r\n\r\n            if (bone) {\r\n                return bone;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Finds a bone in the avatar's skeletons by its name.\r\n     * @param name The name of the bone\r\n     * @returns The found bone or null if not found\r\n     */\r\n    public findBoneByName(name: string): Nullable<Bone> {\r\n        const iterator = this.skeletons.keys();\r\n\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const skeleton = key.value;\r\n            const index = skeleton.getBoneIndexByName(name);\r\n\r\n            if (index !== -1) {\r\n                return skeleton.bones[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Make sures that the animation group passed as the first parameter will animate the bones in the skeleton(s) / the morphs in the morph target manager(s) of the avatar.\r\n     * Retargeting is based on the names of the targets (TransformNode or MorphTarget) in the animation and the names of the bones in the skeleton / morph targets in the morph target manager.\r\n     * Note that you can use the mapNodeNames option to specify a mapping between source transform node names and target bone names in case they are different.\r\n     * If no bones with the same name as a target (TransformNode) of a targeted animation are found, the targeted animation is removed from the animation group.\r\n     * Same for morph targets.\r\n     * Note that for the time being, we only support a source animation group which animates transform nodes, not bones!\r\n     * That's typically the case when the source animation group is created from a glTF file, as glTF animations always target transform nodes.\r\n     * @param sourceAnimationGroup The animation group to retarget\r\n     * @param options Options for retargeting the animation group (optional)\r\n     * @returns The retargeted (new) animation group\r\n     */\r\n    public retargetAnimationGroup(sourceAnimationGroup: AnimationGroup, options?: IRetargetOptions): AnimationGroup {\r\n        const localOptions: IRetargetOptions = {\r\n            animationGroupName: sourceAnimationGroup.name,\r\n            fixAnimations: false,\r\n            checkHierarchy: false,\r\n            retargetAnimationKeys: true,\r\n            fixGroundReference: false,\r\n            fixGroundReferenceDynamicRefNode: false,\r\n            fixRootPosition: true,\r\n            ...options,\r\n        };\r\n\r\n        // Capture the avatar's current bone state so we can restore it before returning.\r\n        // _computeBoneWorldMatrices() (called next) returns the skeletons to rest, and the\r\n        // optional _fixRootPosition / _fixGroundReference helpers further drive the bones via\r\n        // an internal play / goToFrame loop. Without restoring afterwards, any animation\r\n        // already playing on the avatar gets clobbered (typically visible as a snap to the\r\n        // rest pose the moment that animation is later stopped). The restore is wrapped in\r\n        // a try/finally so the avatar is also reset if the body throws.\r\n        const avatarSkeletonStates = this._captureAvatarSkeletonStates();\r\n\r\n        try {\r\n            // Make sure that all world matrices are up to date, both in the bone hierarchy and in the animation transform node hierarchy\r\n            this._computeBoneWorldMatrices();\r\n\r\n            const mapNodeNames = localOptions.mapNodeNames ?? new Map();\r\n            const lstSourceTransformNodes = new Set<TransformNode>();\r\n            const sourceTransformNodeNameToNode: TransformNodeNameToNode = new Map();\r\n\r\n            for (let i = 0; i < sourceAnimationGroup.targetedAnimations.length; ++i) {\r\n                const ta = sourceAnimationGroup.targetedAnimations[i];\r\n                if (ta.target.getClassName?.() === \"TransformNode\" && !lstSourceTransformNodes.has(ta.target)) {\r\n                    const tn = ta.target as TransformNode;\r\n\r\n                    lstSourceTransformNodes.add(tn);\r\n\r\n                    sourceTransformNodeNameToNode.set(mapNodeNames.get(tn.name) ?? tn.name, {\r\n                        node: tn,\r\n                        initialTransformations: {\r\n                            position: tn.position.clone(),\r\n                            scaling: tn.scaling.clone(),\r\n                            quaternion: tn.rotationQuaternion?.clone(),\r\n                            rotation: tn.rotation.clone(),\r\n                        },\r\n                    });\r\n\r\n                    if (!tn.rotationQuaternion) {\r\n                        tn.rotationQuaternion = Quaternion.FromEulerAngles(tn.rotation.x, tn.rotation.y, tn.rotation.z);\r\n                        tn.rotation.setAll(0);\r\n                    }\r\n                }\r\n            }\r\n\r\n            lstSourceTransformNodes.forEach((node) => {\r\n                node.computeWorldMatrix(true);\r\n            });\r\n\r\n            // Clone the source animation and retarget it\r\n            const animationGroup = sourceAnimationGroup.clone(localOptions.animationGroupName!, undefined, true, true);\r\n\r\n            const mapTransformNodeToRootNode: Map<TransformNode, Node> = new Map<TransformNode, Node>();\r\n            const lstAnims = new Set<Animation>();\r\n\r\n            for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n                const ta = animationGroup.targetedAnimations[i];\r\n                const animation = ta.animation;\r\n\r\n                if (lstAnims.has(animation)) {\r\n                    if (this.showWarnings) {\r\n                        Logger.Warn(\r\n                            `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': animation '${animation.name}' is used multiple times in the same animation group: duplicated animations are not supported, the retargeted animation may not work as expected.`\r\n                        );\r\n                    }\r\n                }\r\n\r\n                lstAnims.add(animation);\r\n\r\n                switch (animation.targetProperty) {\r\n                    case \"influence\": {\r\n                        if (!this._retargetMorphTarget(ta, animationGroup.name)) {\r\n                            animationGroup.targetedAnimations.splice(i, 1);\r\n                            i--;\r\n                        }\r\n                        break;\r\n                    }\r\n                    case \"position\":\r\n                    case \"rotationQuaternion\":\r\n                    case \"scaling\": {\r\n                        if (ta.target.getClassName?.() !== \"TransformNode\") {\r\n                            break;\r\n                        }\r\n\r\n                        const sourceTransformNode = ta.target as TransformNode;\r\n                        const sourceTransformNodeName = mapNodeNames.get(sourceTransformNode.name) ?? sourceTransformNode.name;\r\n                        let targetBone = this.findBoneByTransformNode(sourceTransformNodeName);\r\n\r\n                        if (!targetBone) {\r\n                            targetBone = this.findBoneByName(sourceTransformNodeName);\r\n                        }\r\n\r\n                        if (!targetBone) {\r\n                            if (this.showWarnings) {\r\n                                Logger.Warn(\r\n                                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': \"${sourceTransformNodeName}\" bone not found in any skeleton of avatar: animation removed.`\r\n                                );\r\n                            }\r\n                            animationGroup.targetedAnimations.splice(i, 1);\r\n                            i--;\r\n                            break;\r\n                        }\r\n\r\n                        if (\r\n                            !this._retargetTransformNodeToBone(\r\n                                ta,\r\n                                sourceTransformNode,\r\n                                targetBone,\r\n                                animationGroup.name,\r\n                                mapTransformNodeToRootNode,\r\n                                mapNodeNames,\r\n                                !!localOptions.checkHierarchy\r\n                            )\r\n                        ) {\r\n                            animationGroup.targetedAnimations.splice(i, 1);\r\n                            i--;\r\n                        } else if (localOptions.retargetAnimationKeys) {\r\n                            this._retargetAnimationKeys(ta.animation, sourceTransformNode, targetBone);\r\n                        }\r\n\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (localOptions.fixAnimations) {\r\n                this._fixAnimationGroup(animationGroup);\r\n            }\r\n\r\n            if (localOptions.fixGroundReference || localOptions.fixRootPosition) {\r\n                const msg =\r\n                    localOptions.fixGroundReference && localOptions.fixRootPosition\r\n                        ? \"Ground reference and root position fixing processes skipped.\"\r\n                        : localOptions.fixGroundReference\r\n                          ? \"Ground reference fixing process skipped.\"\r\n                          : \"Root position fixing process skipped.\";\r\n\r\n                const res = this._findVerticalAxis(\r\n                    msg,\r\n                    animationGroup,\r\n                    mapNodeNames.get(localOptions.rootNodeName) ?? localOptions.rootNodeName,\r\n                    sourceTransformNodeNameToNode,\r\n                    mapNodeNames.get(localOptions.groundReferenceNodeName) ?? localOptions.groundReferenceNodeName,\r\n                    localOptions.groundReferenceVerticalAxis\r\n                );\r\n\r\n                if (res) {\r\n                    const {\r\n                        verticalAxis,\r\n                        sourceRootTransformNode,\r\n                        targetRootTransformNodeOrBone,\r\n                        targetRootPositionAnimation,\r\n                        sourceGroundReferenceTransformNode,\r\n                        targetGroundReferenceTransformNodeOrBone,\r\n                        proportionRatio,\r\n                    } = res;\r\n\r\n                    if (localOptions.fixRootPosition) {\r\n                        this._fixRootPosition(\r\n                            sourceAnimationGroup,\r\n                            animationGroup,\r\n                            sourceRootTransformNode,\r\n                            targetRootTransformNodeOrBone,\r\n                            targetRootPositionAnimation,\r\n                            proportionRatio\r\n                        );\r\n                        this._resetStates(sourceTransformNodeNameToNode);\r\n                    }\r\n\r\n                    const fixGroundReferenceDynamicRefNode = !!localOptions.fixGroundReferenceDynamicRefNode;\r\n\r\n                    if (localOptions.fixGroundReference) {\r\n                        this._fixGroundReference(\r\n                            sourceAnimationGroup,\r\n                            animationGroup,\r\n                            verticalAxis,\r\n                            targetRootTransformNodeOrBone,\r\n                            targetRootPositionAnimation,\r\n                            sourceGroundReferenceTransformNode,\r\n                            targetGroundReferenceTransformNodeOrBone,\r\n                            lstSourceTransformNodes,\r\n                            mapNodeNames,\r\n                            fixGroundReferenceDynamicRefNode\r\n                        );\r\n                        this._resetStates(sourceTransformNodeNameToNode);\r\n                    } else if (fixGroundReferenceDynamicRefNode) {\r\n                        if (this.showWarnings) {\r\n                            Logger.Warn(\r\n                                `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': fixGroundReferenceDynamicRefNode option is set to true but fixGroundReference is false: dynamic ground reference node fixing process skipped.`\r\n                            );\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return animationGroup;\r\n        } finally {\r\n            // Restore the avatar's bones to their pre-call state. The internal helpers above\r\n            // (_computeBoneWorldMatrices and, when enabled, _fixRootPosition / _fixGroundReference)\r\n            // overwrite the bone transforms; without restoring, any animation already driving the\r\n            // avatar appears clobbered (visible as a snap to rest pose the moment that animation\r\n            // is later stopped). Running in finally also makes sure we restore on exception.\r\n            this._restoreAvatarSkeletonStates(avatarSkeletonStates);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the avatar and releases all associated resources.\r\n     * This will dispose all skeletons, morph target managers, and the root mesh with its descendants (including materials and textures).\r\n     * If disposeResources was set to false in the constructor, this method does nothing.\r\n     */\r\n    public dispose(): void {\r\n        if (!this._disposeResources) {\r\n            return;\r\n        }\r\n\r\n        const iterator = this.skeletons.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            key.value.dispose();\r\n        }\r\n\r\n        const iterator2 = this.morphTargetManagers.keys();\r\n        for (let key = iterator2.next(); key.done !== true; key = iterator2.next()) {\r\n            key.value.dispose();\r\n        }\r\n\r\n        this.rootNode?.dispose(false, true);\r\n    }\r\n\r\n    private _computeBoneWorldMatrices() {\r\n        this.skeletons.forEach((skeleton) => {\r\n            skeleton.returnToRest();\r\n            skeleton.prepare(true);\r\n\r\n            skeleton.bones.forEach((bone) => {\r\n                bone._linkedTransformNode?.computeWorldMatrix(true);\r\n            });\r\n        });\r\n    }\r\n\r\n    private _isTransformNode(nameOrTransformNode: string | TransformNode): nameOrTransformNode is TransformNode {\r\n        return typeof nameOrTransformNode !== \"string\";\r\n    }\r\n\r\n    private _buildMorphTargetMap(): void {\r\n        this._mapMorphTargetNameToMorphTarget = new Map<string, MorphTarget>();\r\n\r\n        this.morphTargetManagers.forEach((manager) => {\r\n            const numTargets = manager.numTargets;\r\n\r\n            for (let t = 0; t < numTargets; ++t) {\r\n                const target = manager.getTarget(t);\r\n                const key = manager.meshName + \"_\" + target.name;\r\n\r\n                this._mapMorphTargetNameToMorphTarget.set(key, target);\r\n            }\r\n        });\r\n    }\r\n\r\n    private _retargetMorphTarget(ta: TargetedAnimation, animationGroupName: string) {\r\n        const morphTarget = ta.target as MorphTarget;\r\n        const key = morphTarget.morphTargetManager?.meshName + \"_\" + morphTarget.name;\r\n\r\n        if (!this.mapMorphTargetNameToMorphTarget.has(key)) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroupName}': \"${morphTarget.name}\" morph target not found in morph target manager of mesh \"${morphTarget.morphTargetManager?.meshName}\": animation removed`\r\n                );\r\n            }\r\n            return false;\r\n        }\r\n\r\n        ta.target = this.mapMorphTargetNameToMorphTarget.get(key)!;\r\n\r\n        return true;\r\n    }\r\n\r\n    private _retargetTransformNodeToBone(\r\n        ta: TargetedAnimation,\r\n        sourceTransformNode: TransformNode,\r\n        targetBone: Bone,\r\n        animationGroupName: string,\r\n        mapTransformNodeToRootNode: Map<TransformNode, Node>,\r\n        mapNodeNames: Map<string, string>,\r\n        checkHierarchy: boolean\r\n    ) {\r\n        if (checkHierarchy) {\r\n            let rootNode = mapTransformNodeToRootNode.get(sourceTransformNode);\r\n\r\n            if (!rootNode) {\r\n                rootNode = this._getRootNode(sourceTransformNode);\r\n                mapTransformNodeToRootNode.set(sourceTransformNode, rootNode);\r\n            }\r\n\r\n            if (!this._checkParentHierarchy(targetBone, rootNode!, mapNodeNames)) {\r\n                if (this.showWarnings) {\r\n                    Logger.Warn(\r\n                        `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroupName}': parent hierarchy mismatch between bone \"${targetBone._linkedTransformNode?.name ?? targetBone.name}\" and transform node \"${sourceTransformNode.name}\": animation removed`\r\n                    );\r\n                }\r\n                return false;\r\n            }\r\n        }\r\n\r\n        ta.target = targetBone._linkedTransformNode ?? targetBone;\r\n\r\n        return true;\r\n    }\r\n\r\n    private _retargetAnimationKeys(animation: Animation, sourceTransformNode: TransformNode, targetBone: Bone) {\r\n        const keys = animation.getKeys();\r\n        const targetTransformNode = targetBone._linkedTransformNode;\r\n\r\n        let targetWorldMatrix: Matrix;\r\n        let targetParentWorldMatrix: DeepImmutableObject<Matrix>;\r\n\r\n        if (targetTransformNode) {\r\n            targetWorldMatrix = targetTransformNode.getWorldMatrix();\r\n            targetParentWorldMatrix = targetTransformNode.parent ? targetTransformNode.parent.getWorldMatrix() : Matrix.IdentityReadOnly;\r\n        } else {\r\n            targetWorldMatrix = targetBone.getFinalMatrix();\r\n            targetParentWorldMatrix = targetBone.parent ? targetBone.parent.getFinalMatrix() : Matrix.IdentityReadOnly;\r\n        }\r\n\r\n        const targetParentInverseWorldMatrix = targetParentWorldMatrix.invertToRef(TmpVectors.Matrix[0]);\r\n\r\n        const sourceInverseWorld = sourceTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[1]);\r\n        const sourceParentWorld = sourceTransformNode.parent ? sourceTransformNode.parent.getWorldMatrix() : Matrix.IdentityReadOnly;\r\n\r\n        switch (animation.targetProperty) {\r\n            case \"rotationQuaternion\": {\r\n                for (const key of keys) {\r\n                    const quaternion = key.value as Quaternion;\r\n\r\n                    const localMat = Matrix.ComposeToRef(sourceTransformNode.scaling, quaternion, sourceTransformNode.position, TmpVectors.Matrix[2]);\r\n\r\n                    sourceInverseWorld.multiplyToRef(localMat, localMat).multiplyToRef(sourceParentWorld, localMat);\r\n                    targetWorldMatrix.multiplyToRef(localMat, localMat).multiplyToRef(targetParentInverseWorldMatrix, localMat).decompose(undefined, quaternion, undefined);\r\n                }\r\n                break;\r\n            }\r\n            case \"position\": {\r\n                for (const key of keys) {\r\n                    const position = key.value as Vector3;\r\n\r\n                    const localMat = Matrix.ComposeToRef(sourceTransformNode.scaling, sourceTransformNode.rotationQuaternion!, position, TmpVectors.Matrix[2]);\r\n\r\n                    sourceInverseWorld.multiplyToRef(localMat, localMat).multiplyToRef(sourceParentWorld, localMat);\r\n                    targetWorldMatrix.multiplyToRef(localMat, localMat).multiplyToRef(targetParentInverseWorldMatrix, localMat).decompose(undefined, undefined, position);\r\n                }\r\n                break;\r\n            }\r\n            case \"scaling\": {\r\n                for (const key of keys) {\r\n                    const scaling = key.value as Vector3;\r\n\r\n                    const localMat = Matrix.ComposeToRef(scaling, sourceTransformNode.rotationQuaternion!, sourceTransformNode.position, TmpVectors.Matrix[2]);\r\n\r\n                    sourceInverseWorld.multiplyToRef(localMat, localMat).multiplyToRef(sourceParentWorld, localMat);\r\n                    targetWorldMatrix.multiplyToRef(localMat, localMat).multiplyToRef(targetParentInverseWorldMatrix, localMat).decompose(scaling, undefined, undefined);\r\n                }\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This method corrects quaternion animations when two consecutive quaternions are orthogonal to each other. When this happens, in 99.99% of\r\n     * cases it's an error in the animation data, as two consecutive rotations should normally be close to each other and not have a large gap.\r\n     * The fix is to copy the first quaternion into the second.\r\n     * @param animationGroup The animation group to fix\r\n     * @internal\r\n     */\r\n    private _fixAnimationGroup(animationGroup: AnimationGroup) {\r\n        for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n            const ta = animationGroup.targetedAnimations[i];\r\n\r\n            switch (ta.animation.targetProperty) {\r\n                case \"rotationQuaternion\": {\r\n                    const keys = ta.animation.getKeys();\r\n\r\n                    for (let j = 0; j < keys.length - 1; ++j) {\r\n                        const curQuat = keys[j].value as Quaternion;\r\n                        const nextQuat = keys[j + 1].value as Quaternion;\r\n\r\n                        if (Math.abs(Quaternion.Dot(curQuat, nextQuat)) < 0.001) {\r\n                            keys[j + 1].value = curQuat.clone();\r\n                            j += 1;\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getRootNode(node: Node): Node {\r\n        let current: Node = node;\r\n\r\n        while (current.parent) {\r\n            current = current.parent;\r\n        }\r\n\r\n        return current;\r\n    }\r\n\r\n    /**\r\n     * Checks whether the parent hierarchy of a bone matches that of a given transform node. Checks are performed by name.\r\n     * It works by first finding the transform node in the descendants of the root transform node that matches the bone's linked transform node.\r\n     * Then it traverses up the hierarchy of both the bone and the transform node, comparing their names at each level.\r\n     * @param bone The bone to check\r\n     * @param rootTransformNode The root transform node to check against\r\n     * @returns True if the hierarchies match, false otherwise\r\n     * @internal\r\n     */\r\n    private _checkParentHierarchy(bone: Bone, rootTransformNode: Node, mapNodeNames: Map<string, string>) {\r\n        const children = rootTransformNode.getDescendants(false, (node) => (mapNodeNames.get(node.name) ?? node.name) === (bone._linkedTransformNode?.name ?? bone.name));\r\n        if (!children || children.length !== 1) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', CheckParentHierarchy: unable to find a corresponding transform node to bone name \"${bone._linkedTransformNode?.name ?? bone.name}\" in the source animation.`\r\n                );\r\n            }\r\n            return false;\r\n        }\r\n\r\n        let transformNode: Nullable<Node> = children[0];\r\n\r\n        while (bone) {\r\n            const name = mapNodeNames.get(transformNode?.name ?? \"\") ?? transformNode?.name;\r\n            const boneName = bone._linkedTransformNode?.name ?? bone.name;\r\n            if (boneName !== name) {\r\n                if (this.showWarnings) {\r\n                    Logger.Warn(`RetargetAnimationGroup - Avatar '${this.name}', CheckParentHierarchy: bone name \"${boneName}\" is different from transform node name \"${name}\".`);\r\n                }\r\n                return false;\r\n            }\r\n\r\n            bone = bone.parent;\r\n            transformNode = transformNode!.parent;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _getRootNodeName(rootNodeName: string | undefined, transformNodeNameToNode: TransformNodeNameToNode) {\r\n        if (rootNodeName) {\r\n            return rootNodeName;\r\n        }\r\n\r\n        // Look for the first bone that doesn't have a parent\r\n        const iterator = this.skeletons.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const skeleton = key.value;\r\n\r\n            for (const bone of skeleton.bones) {\r\n                if (!bone.parent) {\r\n                    // Make sure there's a transform node with that name in the source animation\r\n                    if (transformNodeNameToNode.get(bone.name)) {\r\n                        return bone.name;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return;\r\n    }\r\n\r\n    private _findVerticalAxis(\r\n        msg: string,\r\n        animationGroup: AnimationGroup,\r\n        remappedRootNodeName: string | undefined,\r\n        sourceTransformNodeNameToNode: TransformNodeNameToNode,\r\n        remappedGroundReferenceNodeName?: string,\r\n        groundReferenceVerticalAxis?: string\r\n    ) {\r\n        if (!remappedGroundReferenceNodeName) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': you must provide the name of the ground reference node (option parameter \"groundReferenceNodeName\"). ${msg}`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        remappedRootNodeName = this._getRootNodeName(remappedRootNodeName, sourceTransformNodeNameToNode);\r\n\r\n        if (!remappedRootNodeName) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': unable to find a suitable root node in the source animation. You should provide its name through the \"rootNodeName\" optional parameter. ${msg}`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        const sourceRootTransformNode = sourceTransformNodeNameToNode.get(remappedRootNodeName)?.node;\r\n        const sourceGroundReferenceTransformNode = sourceTransformNodeNameToNode.get(remappedGroundReferenceNodeName)?.node;\r\n\r\n        if (!sourceRootTransformNode) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': unable to find the transform node corresponding to \"${remappedRootNodeName}\" in the source animation. This transform node either doesn't exist or is not animated. ${msg}`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        if (!sourceGroundReferenceTransformNode) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': unable to find the transform node corresponding to \"${remappedGroundReferenceNodeName}\" in the source animation. This transform node either doesn't exist or is not animated. ${msg}`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        // Look for the position animation + target node of the root node name (generally the hips) in the retargeted animation\r\n        let targetRootPositionAnimation: Animation | undefined;\r\n        let targetRootTransformNodeOrBone: TransformNode | Bone | undefined;\r\n\r\n        for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n            const ta = animationGroup.targetedAnimations[i];\r\n            const target = ta.target;\r\n            const animation = ta.animation;\r\n\r\n            if (target.name === remappedRootNodeName && animation.targetProperty === \"position\") {\r\n                targetRootPositionAnimation = animation;\r\n                targetRootTransformNodeOrBone = ta.target;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (!targetRootPositionAnimation || !targetRootTransformNodeOrBone) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': unable to find a \"position\" animation for the node \"${remappedRootNodeName}\". ${msg}`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        let targetGroundReferenceTransformNodeOrBone: Nullable<TransformNode | Bone>;\r\n\r\n        if (targetRootTransformNodeOrBone instanceof TransformNode) {\r\n            targetGroundReferenceTransformNodeOrBone = this.findBoneByTransformNode(remappedGroundReferenceNodeName)?._linkedTransformNode!;\r\n        } else {\r\n            targetGroundReferenceTransformNodeOrBone = this.findBoneByName(remappedGroundReferenceNodeName);\r\n        }\r\n\r\n        if (!targetGroundReferenceTransformNodeOrBone) {\r\n            if (this.showWarnings) {\r\n                Logger.Warn(\r\n                    `RetargetAnimationGroup - Avatar '${this.name}', AnimationGroup '${animationGroup.name}': unable to find the bone/transform node corresponding with name \"${remappedGroundReferenceNodeName}\" in the avatar skeleton. Ensure that this bone exists. ${msg}`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        sourceRootTransformNode.computeWorldMatrix(true);\r\n        sourceGroundReferenceTransformNode.computeWorldMatrix(true);\r\n\r\n        // Determine the vertical axis\r\n        const sourceRootGroundReferenceDiff = sourceRootTransformNode.getAbsolutePosition().subtract(sourceGroundReferenceTransformNode.getAbsolutePosition());\r\n\r\n        let verticalAxis = 0;\r\n\r\n        if (groundReferenceVerticalAxis) {\r\n            switch (groundReferenceVerticalAxis) {\r\n                case \"Y\":\r\n                    verticalAxis = 1;\r\n                    break;\r\n                case \"Z\":\r\n                    verticalAxis = 2;\r\n                    break;\r\n            }\r\n        } else {\r\n            // No axis provided: assume the vertical axis is the one with the larger difference between the reference and the ground reference transform nodes\r\n            const absX = Math.abs(sourceRootGroundReferenceDiff.x);\r\n            const absY = Math.abs(sourceRootGroundReferenceDiff.y);\r\n            const absZ = Math.abs(sourceRootGroundReferenceDiff.z);\r\n            if (absY > absX && absY >= absZ) {\r\n                verticalAxis = 1;\r\n            } else if (absZ > absX && absZ > absY) {\r\n                verticalAxis = 2;\r\n            }\r\n        }\r\n\r\n        const targetRootGroundReferenceDiff = targetRootTransformNodeOrBone.getAbsolutePosition().subtract(targetGroundReferenceTransformNodeOrBone.getAbsolutePosition());\r\n\r\n        const sourceDiff = verticalAxis === 0 ? sourceRootGroundReferenceDiff.x : verticalAxis === 1 ? sourceRootGroundReferenceDiff.y : sourceRootGroundReferenceDiff.z;\r\n        const targetDiff = verticalAxis === 0 ? targetRootGroundReferenceDiff.x : verticalAxis === 1 ? targetRootGroundReferenceDiff.y : targetRootGroundReferenceDiff.z;\r\n\r\n        return {\r\n            verticalAxis,\r\n            sourceRootTransformNode,\r\n            sourceGroundReferenceTransformNode,\r\n            targetRootTransformNodeOrBone,\r\n            targetRootPositionAnimation,\r\n            targetGroundReferenceTransformNodeOrBone,\r\n            proportionRatio: sourceDiff !== 0 ? targetDiff / sourceDiff : 1.0,\r\n        };\r\n    }\r\n\r\n    private _captureAvatarSkeletonStates(): AvatarSkeletonStates {\r\n        const transformNodeStates = new Map<TransformNode, { position: Vector3; scaling: Vector3; quaternion?: Quaternion; rotation: Vector3 }>();\r\n        const boneMatrices = new Map<Bone, Matrix>();\r\n\r\n        this.skeletons.forEach((skeleton) => {\r\n            for (const bone of skeleton.bones) {\r\n                const linkedNode = bone._linkedTransformNode;\r\n                if (linkedNode) {\r\n                    transformNodeStates.set(linkedNode, {\r\n                        position: linkedNode.position.clone(),\r\n                        scaling: linkedNode.scaling.clone(),\r\n                        quaternion: linkedNode.rotationQuaternion?.clone(),\r\n                        rotation: linkedNode.rotation.clone(),\r\n                    });\r\n                } else {\r\n                    boneMatrices.set(bone, bone.getLocalMatrix().clone());\r\n                }\r\n            }\r\n        });\r\n\r\n        return { transformNodeStates, boneMatrices };\r\n    }\r\n\r\n    private _restoreAvatarSkeletonStates(states: AvatarSkeletonStates): void {\r\n        states.transformNodeStates.forEach((data, node) => {\r\n            node.position.copyFrom(data.position);\r\n            node.scaling.copyFrom(data.scaling);\r\n            if (data.quaternion) {\r\n                // Snapshot was using a quaternion: ensure the node still has one and restore it.\r\n                // _computeBoneWorldMatrices() can null/replace it via Bone.returnToRest, so we can't\r\n                // assume node.rotationQuaternion is the same instance (or non-null) we captured.\r\n                if (node.rotationQuaternion) {\r\n                    node.rotationQuaternion.copyFrom(data.quaternion);\r\n                } else {\r\n                    node.rotationQuaternion = data.quaternion.clone();\r\n                }\r\n            } else {\r\n                // Snapshot was using Euler rotation: clear any quaternion that may have been\r\n                // assigned in the meantime (Babylon ignores rotation when rotationQuaternion is set).\r\n                node.rotationQuaternion = null;\r\n                node.rotation.copyFrom(data.rotation);\r\n            }\r\n            node.computeWorldMatrix(true);\r\n        });\r\n\r\n        states.boneMatrices.forEach((matrix, bone) => {\r\n            bone._matrix = matrix;\r\n        });\r\n\r\n        // Re-prepare each skeleton so the restored bone state takes effect immediately\r\n        // rather than being left as stale world/final matrices until the next frame.\r\n        this.skeletons.forEach((skeleton) => skeleton.prepare(true));\r\n    }\r\n\r\n    private _resetStates(sourceTransformNodeNameToNode: TransformNodeNameToNode) {\r\n        this.skeletons.forEach((skeleton) => skeleton.returnToRest());\r\n        sourceTransformNodeNameToNode.forEach((data) => {\r\n            const { node, initialTransformations } = data;\r\n            node.position.copyFrom(initialTransformations.position);\r\n            node.scaling.copyFrom(initialTransformations.scaling);\r\n            if (initialTransformations.quaternion) {\r\n                node.rotationQuaternion!.copyFrom(initialTransformations.quaternion);\r\n            } else {\r\n                node.rotation.copyFrom(initialTransformations.rotation);\r\n            }\r\n            node.computeWorldMatrix(true);\r\n        });\r\n    }\r\n\r\n    private _fixRootPosition(\r\n        sourceAnimationGroup: AnimationGroup,\r\n        animationGroup: AnimationGroup,\r\n        sourceRootTransformNode: TransformNode,\r\n        targetRootTransformNodeOrBone: TransformNode | Bone,\r\n        targetRootPositionAnimation: Animation,\r\n        proportionRatio: number\r\n    ) {\r\n        const targetNodeInverseParentWorldMatrix =\r\n            targetRootTransformNodeOrBone instanceof TransformNode\r\n                ? (targetRootTransformNodeOrBone.parent?.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]) ?? Matrix.IdentityReadOnly)\r\n                : (targetRootTransformNodeOrBone.parent?.getFinalMatrix().invertToRef(TmpVectors.Matrix[0]) ?? Matrix.IdentityReadOnly);\r\n\r\n        sourceRootTransformNode.computeWorldMatrix(true);\r\n        targetRootTransformNodeOrBone.computeWorldMatrix(true);\r\n\r\n        const sourceWorldPosition = sourceRootTransformNode.absolutePosition.clone();\r\n        const targetWorldPosition = targetRootTransformNodeOrBone.getAbsolutePosition().clone();\r\n\r\n        sourceAnimationGroup.play(false);\r\n        animationGroup.play(false);\r\n\r\n        // Loop over the position animation of the root transform node\r\n        for (const key of targetRootPositionAnimation.getKeys()) {\r\n            const frame = key.frame;\r\n\r\n            // Advance the source and retargeted animations to this frame\r\n            sourceAnimationGroup.goToFrame(frame);\r\n            sourceAnimationGroup.pause();\r\n\r\n            animationGroup.goToFrame(frame);\r\n            animationGroup.pause();\r\n\r\n            sourceRootTransformNode.computeWorldMatrix(true);\r\n\r\n            const offset = sourceRootTransformNode.absolutePosition.subtractToRef(sourceWorldPosition, TmpVectors.Vector3[0]);\r\n\r\n            offset.scaleInPlace(proportionRatio);\r\n            offset.addInPlace(targetWorldPosition);\r\n\r\n            Vector3.TransformNormalToRef(offset, targetNodeInverseParentWorldMatrix, key.value);\r\n        }\r\n\r\n        sourceAnimationGroup.stop();\r\n        animationGroup.stop();\r\n    }\r\n\r\n    private _fixGroundReference(\r\n        sourceAnimationGroup: AnimationGroup,\r\n        animationGroup: AnimationGroup,\r\n        verticalAxis: number,\r\n        targetRootTransformNodeOrBone: TransformNode | Bone,\r\n        targetRootPositionAnimation: Animation,\r\n        sourceGroundReferenceTransformNode: TransformNode,\r\n        targetGroundReferenceTransformNodeOrBone: TransformNode | Bone,\r\n        sourceListTransformNodes: Set<TransformNode>,\r\n        mapNodeNames: Map<string, string>,\r\n        fixGroundReferenceDynamicRefNode: boolean\r\n    ) {\r\n        const targetNodeInverseParentWorldMatrix =\r\n            targetRootTransformNodeOrBone instanceof TransformNode\r\n                ? (targetRootTransformNodeOrBone.parent?.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]) ?? Matrix.IdentityReadOnly)\r\n                : (targetRootTransformNodeOrBone.parent?.getFinalMatrix().invertToRef(TmpVectors.Matrix[0]) ?? Matrix.IdentityReadOnly);\r\n\r\n        sourceAnimationGroup.play(false);\r\n        animationGroup.play(false);\r\n\r\n        // Loop over the position animation of the root transform node\r\n        for (const key of targetRootPositionAnimation.getKeys()) {\r\n            const frame = key.frame;\r\n\r\n            // Advance the source and retargeted animations to this frame\r\n            sourceAnimationGroup.goToFrame(frame);\r\n            sourceAnimationGroup.pause();\r\n\r\n            animationGroup.goToFrame(frame);\r\n            animationGroup.pause();\r\n\r\n            sourceGroundReferenceTransformNode.computeWorldMatrix(true);\r\n            targetGroundReferenceTransformNodeOrBone.computeWorldMatrix(true);\r\n\r\n            // Calculate the offset to apply to the root position in the target to have the ground reference at the same height in the source and target animations\r\n            const diffGroundReferences = targetGroundReferenceTransformNodeOrBone\r\n                .getAbsolutePosition()\r\n                .subtractToRef(sourceGroundReferenceTransformNode.absolutePosition, TmpVectors.Vector3[0]);\r\n\r\n            let groundReferenceOffset = verticalAxis === 0 ? diffGroundReferences.x : verticalAxis === 1 ? diffGroundReferences.y : diffGroundReferences.z;\r\n\r\n            if (fixGroundReferenceDynamicRefNode) {\r\n                // Try to find a bone in this frame that has a greater offset than the ground reference, to use it instead of the ground reference.\r\n                const targetRootToGroundReferenceDiff = targetRootTransformNodeOrBone\r\n                    .getAbsolutePosition()\r\n                    .subtractToRef(targetGroundReferenceTransformNodeOrBone.getAbsolutePosition(), TmpVectors.Vector3[0]);\r\n\r\n                const targetRootToGroundReferenceOffset =\r\n                    verticalAxis === 0 ? targetRootToGroundReferenceDiff.x : verticalAxis === 1 ? targetRootToGroundReferenceDiff.y : targetRootToGroundReferenceDiff.z;\r\n\r\n                const iterator = sourceListTransformNodes.keys();\r\n\r\n                for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                    const sourceTransformNode = key.value;\r\n                    if (sourceTransformNode === sourceGroundReferenceTransformNode) {\r\n                        continue;\r\n                    }\r\n\r\n                    const targetNodeName = mapNodeNames.get(sourceTransformNode.name) ?? sourceTransformNode.name;\r\n\r\n                    let targetBone = this.findBoneByTransformNode(targetNodeName);\r\n                    if (!targetBone) {\r\n                        targetBone = this.findBoneByName(targetNodeName);\r\n                    }\r\n                    if (!targetBone) {\r\n                        continue;\r\n                    }\r\n\r\n                    sourceTransformNode.computeWorldMatrix();\r\n                    targetBone.computeWorldMatrix();\r\n\r\n                    const targetBoneWorldPosition = targetBone._linkedTransformNode?.getAbsolutePosition() ?? targetBone.getAbsolutePosition();\r\n                    const targetRootToBoneDiff = targetRootTransformNodeOrBone.getAbsolutePosition().subtractToRef(targetBoneWorldPosition, TmpVectors.Vector3[0]);\r\n                    const rootToBoneOffset = verticalAxis === 0 ? targetRootToBoneDiff.x : verticalAxis === 1 ? targetRootToBoneDiff.y : targetRootToBoneDiff.z;\r\n\r\n                    if (Math.abs(rootToBoneOffset) > Math.abs(targetRootToGroundReferenceOffset) && Math.sign(rootToBoneOffset) === Math.sign(targetRootToGroundReferenceOffset)) {\r\n                        const diff = targetBoneWorldPosition.subtractToRef(sourceTransformNode.getAbsolutePosition(), TmpVectors.Vector3[0]);\r\n                        const offset = verticalAxis === 0 ? diff.x : verticalAxis === 1 ? diff.y : diff.z;\r\n\r\n                        groundReferenceOffset = offset;\r\n                    }\r\n                }\r\n            }\r\n\r\n            const localOffset = Vector3.TransformNormalToRef(\r\n                new Vector3(verticalAxis === 0 ? groundReferenceOffset : 0, verticalAxis === 1 ? groundReferenceOffset : 0, verticalAxis === 2 ? groundReferenceOffset : 0),\r\n                targetNodeInverseParentWorldMatrix,\r\n                TmpVectors.Vector3[1]\r\n            );\r\n\r\n            key.value.subtractInPlace(localOffset);\r\n        }\r\n\r\n        sourceAnimationGroup.stop();\r\n        animationGroup.stop();\r\n    }\r\n}\r\n","import {\n    type Animatable,\n    type AnimationGroup,\n    type Bone,\n    type IAnimationKey,\n    type IDisposable,\n    type Node,\n    type Nullable,\n    type Observer,\n    type RuntimeAnimation,\n    type Scene,\n} from \"core/index\";\nimport { Animation } from \"./animation.pure\";\nimport { Matrix, Quaternion, TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\nimport { Observable } from \"../Misc/observable.pure\";\nimport { Logger } from \"../Misc/logger\";\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\n\n/**\n * Where the travel of a {@link RootMotionClip} comes from.\n */\nexport const enum RootMotionSource {\n    /**\n     * No motion was found: the clip neither moves its root nor walks its contact nodes.\n     */\n    None = 0,\n    /**\n     * The root node's own animation - the clip's ground truth. Its travel (and turning, when extracted) is left out of\n     * the in-place animation group and applied to the character node instead.\n     */\n    Root = 1,\n    /**\n     * Deduced from the contact nodes (usually the feet) of an in-place clip: whatever a planted contact gives up in\n     * character space, the character travels. The travel is not in the clip, so nothing is left out of it.\n     */\n    FootContact = 2,\n}\n\n/**\n * Options for {@link RootMotionClip}.\n */\nexport interface IRootMotionClipOptions {\n    /**\n     * The root node, usually the hips or a dedicated root bone, whose own travel is tried first. A bone is resolved to\n     * its linked transform node. Defaults to the position-animated node with the most animated descendants in the group.\n     * A node the group does not animate is accepted as the base of the animated hierarchy: the travel then comes from\n     * the contact nodes under it, and {@link RootMotionSource.Root} cannot be forced.\n     */\n    rootNode?: TransformNode | Bone;\n    /**\n     * The node that receives the motion and whose local space the motion is measured in. Defaults to the topmost\n     * ancestor of the root node (the \"__root__\" node of a glTF asset). The group must not animate its position or\n     * rotation, since the motion applied to it would be overwritten.\n     */\n    characterNode?: TransformNode;\n    /**\n     * The nodes that touch the ground, used when the root does not travel. A bone is resolved to its linked\n     * transform node. Defaults to the leaf nodes under the root that come closest to the ground during the clip.\n     */\n    contactNodes?: Array<TransformNode | Bone>;\n    /**\n     * Forces the source of the travel instead of trying {@link RootMotionSource.Root} first and falling back to\n     * {@link RootMotionSource.FootContact}.\n     */\n    source?: RootMotionSource;\n    /**\n     * Whether the root's turning about the up axis is extracted and applied to the character. By default it is when\n     * a cycle leaves the character facing at least {@link IRootMotionClipOptions.minimumTurn} away from where it\n     * started, so a walk's hip twist - or a dance that spins round to face the front again - stays in the pose while a\n     * turning clip turns the character.\n     */\n    extractRotation?: boolean;\n    /**\n     * How densely the clip is sampled during analysis. Default is 60 samples per second of animation.\n     */\n    samplesPerSecond?: number;\n    /**\n     * Travel below this share of the character's height over a cycle is treated as the clip standing still: root\n     * sway rather than root motion. Default is 0.1.\n     */\n    minimumTravel?: number;\n    /**\n     * Turning below this angle over a cycle, in radians, is treated as twist rather than a turn. Default is 10 degrees.\n     */\n    minimumTurn?: number;\n    /**\n     * A straight clip whose direction of travel is within this angle of a character space axis, in radians, travels\n     * along that axis; 0 keeps the measured direction. Ignored when lateral motion is extracted.\n     *\n     * By default a root clip keeps its direction (0): its travel is authored or captured, and a deliberate veer is data.\n     * Travel deduced from contacts snaps within 10 degrees: an in-place clip is meant to travel straight, and the\n     * deduced direction is an estimate - Xbot's run deduces 3.5 degrees off straight from feet that slide 1 degree off.\n     */\n    directionSnapAngle?: number;\n    /**\n     * When false (the default) only the travel along the clip's direction of travel is extracted, leaving the\n     * side-to-side sway of the root in the animation. Set to true to extract all horizontal motion, for strafing\n     * clips. Turning clips always extract all horizontal motion, since their direction of travel changes.\n     */\n    extractLateralMotion?: boolean;\n    /**\n     * The up axis in character space. Default is +Y.\n     */\n    upAxis?: Vector3;\n    /**\n     * The name of the in-place animation group. Defaults to the source group's name followed by \" (in place)\".\n     */\n    name?: string;\n    /**\n     * Whether every animation is cloned into the in-place animation group. By default (false) only the root channels\n     * the extraction rewrites are cloned, and the animations it leaves untouched are shared with the source group, as\n     * {@link AnimationGroup.clone} shares them. Set it to true before changing the in-place group's animations in place\n     * - with {@link AnimationGroup.MakeAnimationAdditive} or {@link AnimationGroup.normalize} for example - so the\n     * source group's animations are not changed with them.\n     */\n    cloneAnimations?: boolean;\n}\n\ninterface INodeChannels {\n    position?: Animation;\n    rotationQuaternion?: Animation;\n    rotation?: Animation;\n    scaling?: Animation;\n}\n\n/**\n * What the animation mixer wrote to a root channel in the last animation step - the writes its late bindings read,\n * those made after them belonging to the step that follows - gathered for every clip that follows that channel.\n */\ninterface IChannelWriters {\n    /** The property of the channel. */\n    property: string;\n    /** The weights of the weighted animatables writing the channel, additive ones aside. */\n    total: number;\n    /** Whether any weighted animatable writes the channel. */\n    weighted: boolean;\n    /** The last runtime animation writing the channel unweighted, whose value is the pose unless a weighted one replaces it. */\n    lastDirect: Nullable<RuntimeAnimation>;\n    /** The writes to the channel this step, in order: the runtime animation of each, which may write more than once. */\n    current: RuntimeAnimation[];\n    /** The weight of each write, -1 for a direct one. */\n    currentWeights: number[];\n    /** Whether each write was additive. */\n    currentAdditive: boolean[];\n    /** The factor each write blended in with, one once the animation writing it has blended in. */\n    currentBlending: number[];\n}\n\n/**\n * The channel of a node to run a clip's motion on: the one of its position, rotation and scaling channels preferred by\n * {@link ClockBeats}.\n * @param channels defines the node's channels\n * @param fromFrame defines the first frame of the range played\n * @param toFrame defines the last frame of the range played\n * @returns the channel and the frames its keys span\n */\nfunction ClockChannel(channels: INodeChannels, fromFrame: number, toFrame: number): IClockCandidate {\n    let best: Nullable<IClockCandidate> = null;\n    for (const animation of [channels.position, channels.rotationQuaternion, channels.rotation, channels.scaling]) {\n        if (!animation) {\n            continue;\n        }\n        const keys = animation.getKeys();\n        const first = keys.length ? keys[0].frame : 0;\n        const last = keys.length ? keys[keys.length - 1].frame : 0;\n        const candidate = { animation, span: last - first, covers: last > first && first <= fromFrame && last >= toFrame };\n        if (!best || ClockBeats(candidate, best)) {\n            best = candidate;\n        }\n    }\n    return best!;\n}\n\n/** A channel a clip's motion could run on. */\ninterface IClockCandidate {\n    /** The channel. */\n    animation: Animation;\n    /** The frames its keys span. */\n    span: number;\n    /** Whether its keys cover the range played. */\n    covers: boolean;\n}\n\n/**\n * Whether one channel is to run a clip's motion rather than another: one whose keys cover the range played before one\n * whose keys do not; among channels that cover it a position channel first, the channel the mixer weighs linearly, then\n * the widest; among channels that do not, the widest, since a channel keyed shorter clamps the analysis to its keys,\n * then a position channel.\n * @param candidate defines the channel considered\n * @param other defines the channel preferred so far\n * @returns whether the channel considered is preferred\n */\nfunction ClockBeats(candidate: IClockCandidate, other: IClockCandidate): boolean {\n    if (candidate.covers !== other.covers) {\n        return candidate.covers;\n    }\n    const position = candidate.animation.targetProperty === \"position\";\n    const otherPosition = other.animation.targetProperty === \"position\";\n    if (candidate.covers && position !== otherPosition) {\n        return position;\n    }\n    if (candidate.span !== other.span) {\n        return candidate.span > other.span;\n    }\n    return position && !otherPosition;\n}\n\n/** Contact candidates must come this close to the lowest one during the clip, as a share of the character's height. */\nconst ContactHeightBand = 0.1;\n/** A contact counts as on the ground within this share of the character's height above its own lowest point. */\nconst PlantedHeightBand = 0.05;\n/** Values per sample in the motion track: translation x, y, z and the turn about the up axis. */\nconst TrackStride = 4;\n/**\n * Deduced travel counts only if its steps mostly head the same way: net travel over the length of the path stepped.\n * Walks and runs measure 0.99 and more; a dance or an idle that shuffles about on the spot measures under 0.3.\n */\nconst MinimumStraightness = 0.8;\n/** Default snap of a direction of travel deduced from contacts, in radians. */\nconst DeducedDirectionSnapAngle = Math.PI / 18;\n/** Frame step for the numeric tangents of rewritten cubic spline keys. */\nconst TangentDelta = 1e-3;\n/** The root motion of each scene, updating the scene's controllers in one pass after animations. */\nconst SceneRootMotions = new WeakMap<Scene, SceneRootMotion>();\n\n/**\n * The root motion of an animation group: how far the clip carries the character over a cycle, and how far it turns it,\n * so that the character can be moved by it and its feet stay planted instead of skating.\n *\n * The clip is analyzed once, when the RootMotionClip is created, without playing the group or changing it:\n * 1. The root node's own animation is tried first, as the ground truth. If the root ends a cycle a meaningful distance\n *    from where it started, that travel is the root motion. Turning is read from the root the same way.\n * 2. Otherwise the clip is treated as an in-place cycle and the travel is deduced from its contact nodes: a planted\n *    contact stays put in the world, so in character space it moves opposite to the character, and whatever it gives\n *    up the character gains. The direction of travel falls out of the same measurement, so the forward axis of\n *    the rig does not have to be known.\n *\n * The source group is never changed. The clip owns {@link RootMotionClip.animationGroup}, a clone of the source in\n * which the root's travel and turning are left out, so it plays and loops in place: play that group, and give the clip\n * to the {@link RootMotionController} of the character so the motion is applied to the character node instead.\n *\n * ```ts\n * const walk = new RootMotionClip(walkGroup);\n * const controller = new RootMotionController(walk.characterNode, [walk]);\n * walk.animationGroup.start(true);\n * ```\n *\n * The in-place group is a group of the scene, not of the source's asset container, so dispose the clip when it is done\n * with; disposing the container does not. To play a clip additively, build it from the source as it is and make the\n * in-place group additive: `AnimationGroup.MakeAnimationAdditive(clip.animationGroup, { referenceFrame: 0 })`, with\n * {@link IRootMotionClipOptions.cloneAnimations} set so the source keeps its keys.\n */\nexport class RootMotionClip implements IDisposable {\n    /**\n     * @internal\n     * The node of the clip's clock: the channel whose runtime animation the controller reads the evaluated progress\n     * from and turns into motion. It is the root node, or the first animated transform node when the group animates\n     * no position.\n     */\n    public _clockNode: Nullable<TransformNode> = null;\n    /** @internal The property of the clock's channel. */\n    public _clockProperty = \"position\";\n    /** @internal The very channel of the in-place group the analysis ran on, which another of the same property must not be taken for. */\n    public _clockAnimation: Nullable<Animation> = null;\n    /** @internal The runtime animation of the clock the controller followed last. */\n    public _clockRuntime: Nullable<RuntimeAnimation> = null;\n    /** @internal The animatable of the clock the controller followed last. */\n    public _clockAnimatable: Nullable<Animatable> = null;\n    /** @internal The animatable the last search for the clock found. */\n    public _foundAnimatable: Nullable<Animatable> = null;\n    /** @internal The animatable the clock's playback was synchronized with last, and the runtime animation of that root. */\n    public _syncRoot: Nullable<Animatable> = null;\n    /** @internal The runtime animation the clock was synchronized with last. */\n    public _syncRuntime: Nullable<RuntimeAnimation> = null;\n    /** @internal The progress of the clock the controller consumed last. */\n    public _lastProgress: Nullable<number> = null;\n    /** @internal Whether the clock has been left unevaluated at a weight of zero since the progress consumed last. */\n    public _parked = false;\n    /** @internal The clock's runtime animation at the last reset, whose evaluation of then is not where the playback carries on from. */\n    public _staleRuntime: Nullable<RuntimeAnimation> = null;\n    /** @internal Its progress then. */\n    public _staleProgress: Nullable<number> = null;\n    /** @internal What the mixer wrote to the clock's channel this frame. */\n    public _writers: Nullable<IChannelWriters> = null;\n    /** @internal The controller the clip belongs to. */\n    public _controller: Nullable<RootMotionController> = null;\n\n    private readonly _sourceGroup: AnimationGroup;\n    private readonly _group: AnimationGroup;\n    private readonly _characterNode: TransformNode;\n    private readonly _upAxis: Vector3;\n    private readonly _extractLateral: boolean;\n    private readonly _directionSnapAngle: number | undefined;\n    /** Sideways travel over a cycle left in the root's keys after snapping the direction, removed without being applied. */\n    private readonly _lateralDrift = Vector3.Zero();\n    private readonly _channels = new Map<Node, INodeChannels>();\n    private _source = RootMotionSource.None;\n    private _rootNode: Nullable<TransformNode> = null;\n    private _contactNodes: TransformNode[] = [];\n    private readonly _travelDirection = new Vector3(0, 0, 1);\n    private readonly _cycleOffset = Vector3.Zero();\n    private _cycleRotation = 0;\n    private _turns = false;\n    private _duration = 0;\n    private _characterHeight = 0;\n    private _fromFrame = 0;\n    private _toFrame = 0;\n    private _sampleCount = 1;\n    private _track = new Float32Array(2 * TrackStride);\n    /** Whether the root's own travel is left out of the in-place group - not so for a clip that only turns on the spot. */\n    private _removesRootTravel = false;\n    /** Whether the motion is a turn about the root's starting point: a clip that only turns on the spot. */\n    private _pivots = false;\n    /** The root's position before the clip, when the in-place group animates a position the source leaves alone. */\n    private _restoredPosition: Nullable<Vector3> = null;\n    private _clockIndex = -1;\n    private _sampleBlend = 0;\n    private readonly _lastOffset = Vector3.Zero();\n    private readonly _rangeStart = Vector3.Zero();\n    private readonly _rangeCycle = Vector3.Zero();\n    private readonly _cyclesOffset = Vector3.Zero();\n    private readonly _planarStep = Vector3.Zero();\n    private readonly _yawQuaternion = new Quaternion();\n    private readonly _yawMatrix = new Matrix();\n\n    /**\n     * The animation group the clip was analyzed from. It is never changed.\n     */\n    public get sourceAnimationGroup(): AnimationGroup {\n        return this._sourceGroup;\n    }\n\n    /**\n     * The in-place animation group to play: a clone of the source with the root motion left out of the root's keys.\n     * Animations the extraction does not rewrite are shared with the source unless the clip was created with\n     * {@link IRootMotionClipOptions.cloneAnimations}. It belongs to the scene, and is disposed with the clip.\n     */\n    public get animationGroup(): AnimationGroup {\n        return this._group;\n    }\n\n    /**\n     * The controller the clip was added to, if any.\n     */\n    public get controller(): Nullable<RootMotionController> {\n        return this._controller;\n    }\n\n    /**\n     * Where the travel comes from. {@link RootMotionSource.None} when no motion was found.\n     */\n    public get source(): RootMotionSource {\n        return this._source;\n    }\n\n    /**\n     * The root node the clip was analyzed with, or null when the group animates no position. It carries the motion\n     * only when {@link RootMotionClip.source} is {@link RootMotionSource.Root}.\n     */\n    public get rootNode(): Nullable<TransformNode> {\n        return this._rootNode;\n    }\n\n    /**\n     * The node the motion is measured in the local space of, and that a controller moves.\n     */\n    public get characterNode(): TransformNode {\n        return this._characterNode;\n    }\n\n    /**\n     * The contact nodes used to deduce the travel. Empty unless the source is {@link RootMotionSource.FootContact}.\n     */\n    public get contactNodes(): ReadonlyArray<TransformNode> {\n        return this._contactNodes;\n    }\n\n    /**\n     * The up axis in character space (unit length).\n     */\n    public get upAxis(): Vector3 {\n        return this._upAxis;\n    }\n\n    /**\n     * The first frame of the range the clip is analyzed over: the group's range, with a bound outside the clock\n     * channel's keys replaced by that channel's first or last key, as playback does.\n     */\n    public get fromFrame(): number {\n        return this._fromFrame;\n    }\n\n    /**\n     * The last frame of the range the clip is analyzed over.\n     */\n    public get toFrame(): number {\n        return this._toFrame;\n    }\n\n    /**\n     * The direction the clip travels in over a cycle, in character space (unit length).\n     */\n    public get travelDirection(): Vector3 {\n        return this._travelDirection;\n    }\n\n    /**\n     * The travel covered by one cycle of the clip, in character space.\n     */\n    public get cycleOffset(): Vector3 {\n        return this._cycleOffset;\n    }\n\n    /**\n     * The distance covered by one cycle of the clip along the direction of travel, in character space units.\n     */\n    public get cycleDistance(): number {\n        return Vector3.Dot(this._cycleOffset, this._travelDirection);\n    }\n\n    /**\n     * The turn covered by one cycle of the clip about the up axis, in radians. Zero unless rotation is extracted.\n     */\n    public get cycleRotation(): number {\n        return this._cycleRotation;\n    }\n\n    /**\n     * Whether the root's turning is extracted and applied to the character.\n     */\n    public get extractsRotation(): boolean {\n        return this._turns;\n    }\n\n    /**\n     * The length of one cycle of the clip in seconds, at a speed ratio of 1.\n     */\n    public get duration(): number {\n        return this._duration;\n    }\n\n    /**\n     * The speed the clip implies at a speed ratio of 1, in character space units per second.\n     */\n    public get averageSpeed(): number {\n        return this._duration > 0 ? this.cycleDistance / this._duration : 0;\n    }\n\n    /**\n     * The vertical extent of the animated hierarchy at the first frame, in character space units. Thresholds are\n     * relative to it.\n     */\n    public get characterHeight(): number {\n        return this._characterHeight;\n    }\n\n    /**\n     * Analyzes an animation group and builds the in-place animation group to play instead of it.\n     * @param animationGroup defines the animation group to extract the root motion of; it is not changed\n     * @param options defines how the root motion is extracted\n     * @throws when the group has nothing to analyze, is additive, or animates the character node itself\n     */\n    public constructor(animationGroup: AnimationGroup, options: IRootMotionClipOptions = {}) {\n        this._sourceGroup = animationGroup;\n        this._upAxis = (options.upAxis ?? Vector3.UpReadOnly).normalizeToNew();\n        this._extractLateral = !!options.extractLateralMotion;\n        this._directionSnapAngle = options.directionSnapAngle;\n        const name = options.name ?? `${animationGroup.name} (in place)`;\n\n        if (animationGroup.isAdditive) {\n            throw new Error(\n                `RootMotionClip: animation group \"${animationGroup.name}\" is additive. Build the clip from the group it was made additive from, then make the clip's in-place group additive.`\n            );\n        }\n        const targetedAnimations = animationGroup.targetedAnimations;\n        if (!targetedAnimations.length) {\n            throw new Error(`RootMotionClip: animation group \"${animationGroup.name}\" has no animations.`);\n        }\n        for (const targetedAnimation of targetedAnimations) {\n            const target = targetedAnimation.target;\n            const property = targetedAnimation.animation.targetProperty;\n            if (!(target instanceof TransformNode)) {\n                continue;\n            }\n            if (property === \"position\" || property === \"rotationQuaternion\" || property === \"rotation\" || property === \"scaling\") {\n                let channels = this._channels.get(target);\n                if (!channels) {\n                    channels = {};\n                    this._channels.set(target, channels);\n                }\n                channels[property] = targetedAnimation.animation;\n            }\n        }\n\n        // The character node is where the motion goes; an animation of its position or rotation, or of a part of them,\n        // would overwrite it every frame.\n        const refuseAnimatedReceiver = (node: TransformNode) => {\n            if (\n                targetedAnimations.some(\n                    (targetedAnimation) => targetedAnimation.target === node && /^(position|rotationQuaternion|rotation)(\\.|$)/.test(targetedAnimation.animation.targetProperty)\n                )\n            ) {\n                throw new Error(\n                    `RootMotionClip: animation group \"${animationGroup.name}\" animates the character node \"${node.name}\", which is to receive the motion. Parent the character under a node the group does not animate, or pass such an ancestor as characterNode.`\n                );\n            }\n        };\n        if (options.characterNode) {\n            refuseAnimatedReceiver(options.characterNode);\n        }\n        this._rootNode = options.rootNode ? this._resolveNode(options.rootNode) : this._findRootNode();\n        const anchor = this._rootNode ?? this._firstAnimatedNode();\n        if (!anchor) {\n            throw new Error(`RootMotionClip: animation group \"${animationGroup.name}\" does not animate any transform node.`);\n        }\n        let character = options.characterNode ?? null;\n        if (!character || character === anchor || !anchor.isDescendantOf(character)) {\n            if (character) {\n                Logger.Warn(`RootMotionClip: the character node \"${character.name}\" is not an ancestor of the root node \"${anchor.name}\"; using the topmost ancestor instead.`);\n            }\n            character = this._topmostAncestor(anchor);\n        }\n        if (character === anchor) {\n            throw new Error(`RootMotionClip: the root node \"${anchor.name}\" has no parent to carry its motion. Parent the character under a node of its own.`);\n        }\n        refuseAnimatedReceiver(character);\n        this._characterNode = character;\n\n        // The motion runs on the root's own animation - its frame rate, its range and at runtime its playback - rather than\n        // whichever track happens to be first in the group, which could be a morph target at another frame rate: the\n        // channel of the root that covers the range played, since one keyed shorter would clamp the analysis to its own\n        // keys. A root the group does not animate, passed as the base of the hierarchy, runs on such a channel of an\n        // animated descendant: a position channel before any other, the channel the mixer weighs linearly, and the\n        // widest among those.\n        const playedFrom = animationGroup.from;\n        const playedTo = animationGroup.to;\n        let clockNode: Nullable<TransformNode> = null;\n        let clock: Nullable<Animation> = null;\n        const anchorChannels = this._channels.get(anchor);\n        const anchorClock = anchorChannels ? ClockChannel(anchorChannels, playedFrom, playedTo) : null;\n        if (anchorClock && anchorClock.span > 0) {\n            clockNode = anchor;\n            clock = anchorClock.animation;\n        } else {\n            // The root has nothing to run on - it is not animated at all, or only by channels of a single key - so the\n            // clip runs on a channel of the hierarchy under it, itself as the last resort, chosen across those nodes by\n            // the same preference as among the channels of one.\n            let best: Nullable<IClockCandidate> = null;\n            for (const [node, channels] of this._channels) {\n                if (node !== anchor && !node.isDescendantOf(anchor)) {\n                    continue;\n                }\n                const candidate = ClockChannel(channels, playedFrom, playedTo);\n                if (!best || ClockBeats(candidate, best)) {\n                    best = candidate;\n                    clockNode = node as TransformNode;\n                    clock = candidate.animation;\n                }\n            }\n        }\n        if (!clockNode || !clock) {\n            throw new Error(`RootMotionClip: animation group \"${animationGroup.name}\" animates neither the root node \"${anchor.name}\" nor any node under it.`);\n        }\n        this._clockNode = clockNode;\n        this._clockProperty = clock.targetProperty;\n        // The group's range clamped to the clock's keys, the way playback clamps it: another track may run longer.\n        const keys = clock.getKeys();\n        const firstKey = keys[0].frame;\n        const lastKey = keys[keys.length - 1].frame;\n        this._fromFrame = animationGroup.from < firstKey || animationGroup.from > lastKey ? firstKey : animationGroup.from;\n        this._toFrame = animationGroup.to < firstKey || animationGroup.to > lastKey ? lastKey : animationGroup.to;\n        const framePerSecond = clock.framePerSecond;\n        this._duration = framePerSecond > 0 ? (this._toFrame - this._fromFrame) / framePerSecond : 0;\n        this._sampleCount = Math.max(2, Math.ceil(this._duration * (options.samplesPerSecond ?? 60)));\n\n        this._characterHeight = this._measureHeight(this._rootNode ?? this._characterNode);\n        const scale = this._characterHeight > 0 ? this._characterHeight : 1;\n        const minimumTravel = (options.minimumTravel ?? 0.1) * scale;\n        const minimumTurn = options.minimumTurn ?? Math.PI / 18;\n        const source = options.source;\n        const root = this._rootNode;\n        const rootChannels = root ? this._channels.get(root) : undefined;\n        const samples = this._sampleCount;\n\n        // Turning is only ever in the root's own rotation.\n        let yaw: Nullable<Float32Array> = null;\n        if (root && options.extractRotation !== false && (rootChannels?.rotationQuaternion || rootChannels?.rotation)) {\n            const measured = this._measureRootYaw();\n            // By the turn a loop leaves the character facing: a dance that spins twice ends facing the way it began and\n            // loops seamlessly as it is, while a 90 degree turn has to carry the character round.\n            if (options.extractRotation === true || Math.abs(WrapAngle(measured[samples])) >= minimumTurn) {\n                yaw = measured;\n            }\n        }\n        this._turns = !!yaw;\n\n        if (source === RootMotionSource.Root && !rootChannels?.position) {\n            throw new Error(\n                `RootMotionClip: the root node \"${root!.name}\" has no position animation to take the travel from. Omit the source to deduce it from the contact nodes, or pass another rootNode.`\n            );\n        }\n        let translation: Nullable<Float32Array> = null;\n        if ((source === undefined || source === RootMotionSource.Root) && root && rootChannels?.position) {\n            translation = this._measureRootTravel(yaw, minimumTravel, source === RootMotionSource.Root);\n            if (translation) {\n                this._source = RootMotionSource.Root;\n                this._removesRootTravel = true;\n            }\n        }\n        if (!translation && (source === undefined || source === RootMotionSource.FootContact)) {\n            translation = this._measureContactTravel(yaw, options.contactNodes, minimumTravel, source === RootMotionSource.FootContact);\n            if (translation) {\n                this._source = RootMotionSource.FootContact;\n            }\n        }\n        if (!translation && yaw) {\n            // Turning on the spot: the root keeps its travel, sway included; only the turn is taken out.\n            translation = new Float32Array((samples + 1) * 3);\n            this._source = RootMotionSource.Root;\n        }\n        if (translation && yaw && !this._removesRootTravel) {\n            // A turn that is not in the root's travel turns the character about the root's starting point, so a root off\n            // the character's axis stays where the clip has it, in place from one cycle to the next.\n            const start = this._positionInCharacter(root!, this._fromFrame, new Vector3());\n            const pivot = new Vector3();\n            for (let i = 0; i <= samples; i++) {\n                this._rootTravelAt(start, start, yaw[i], true, pivot);\n                translation[i * 3] += pivot.x;\n                translation[i * 3 + 1] += pivot.y;\n                translation[i * 3 + 2] += pivot.z;\n            }\n            this._pivots = true;\n        }\n        if (translation) {\n            this._track = new Float32Array((samples + 1) * TrackStride);\n            for (let i = 0; i <= samples; i++) {\n                this._track[i * TrackStride] = translation[i * 3];\n                this._track[i * TrackStride + 1] = translation[i * 3 + 1];\n                this._track[i * TrackStride + 2] = translation[i * 3 + 2];\n                this._track[i * TrackStride + 3] = yaw ? yaw[i] : 0;\n            }\n            this._cycleOffset.fromArray(translation, samples * 3);\n            this._cycleRotation = yaw ? yaw[samples] : 0;\n        } else {\n            this._turns = false;\n            this._travelDirection.set(0, 0, 1);\n            this._lateralDrift.setAll(0);\n        }\n\n        this._group = this._buildInPlaceGroup(name, !!options.cloneAnimations);\n        // The very channel of the in-place group the motion runs on - the last of that node and property, as the\n        // analysis took it - so that another channel of the same property is not followed in its place.\n        for (const targetedAnimation of this._group.targetedAnimations) {\n            if (targetedAnimation.target === this._clockNode && targetedAnimation.animation.targetProperty === this._clockProperty) {\n                this._clockAnimation = targetedAnimation.animation;\n            }\n        }\n    }\n\n    /**\n     * Gets the travel reached at a frame of the clip, relative to its first frame, in character space.\n     * @param frame defines the frame to sample\n     * @param result defines the vector receiving the travel\n     * @returns the result vector\n     */\n    public getOffsetAtFrame(frame: number, result: Vector3): Vector3 {\n        const a = this._sampleAt(frame) * TrackStride;\n        const b = a + TrackStride;\n        const blend = this._sampleBlend;\n        const track = this._track;\n        return result.set(track[a] + (track[b] - track[a]) * blend, track[a + 1] + (track[b + 1] - track[a + 1]) * blend, track[a + 2] + (track[b + 2] - track[a + 2]) * blend);\n    }\n\n    /**\n     * Gets the turn reached at a frame of the clip about the up axis, relative to its first frame, in radians.\n     * @param frame defines the frame to sample\n     * @returns the turn in radians\n     */\n    public getRotationAtFrame(frame: number): number {\n        const a = this._sampleAt(frame) * TrackStride + 3;\n        return this._track[a] + (this._track[a + TrackStride] - this._track[a]) * this._sampleBlend;\n    }\n\n    /**\n     * Removes the clip from its controller and disposes the in-place animation group. The source group is untouched.\n     * When the in-place group animates the root's position although the source does not (a root that only turns), the\n     * root's position is put back to what it was when the clip was created.\n     */\n    public dispose(): void {\n        this._controller?.removeClip(this);\n        this._group.dispose();\n        if (this._restoredPosition && this._rootNode) {\n            this._rootNode.position = this._restoredPosition.clone();\n        }\n    }\n\n    /**\n     * @internal\n     * Finds the runtime animation of the clock in the in-place group's current playback, leaving its animatable in\n     * _foundAnimatable.\n     * @returns the runtime animation once it has been evaluated, or null when the group is not playing the clock\n     */\n    public _findClock(): Nullable<RuntimeAnimation> {\n        const animatables = this._group.animatables;\n        const cached = this._clockAnimatable;\n        if (cached && this._clockRuntime && animatables[this._clockIndex] === cached) {\n            this._foundAnimatable = cached;\n            return this._clockRuntime;\n        }\n        for (let i = 0; i < animatables.length; i++) {\n            const animatable = animatables[i];\n            if (animatable.target !== this._clockNode) {\n                continue;\n            }\n            const runtimes = animatable.getAnimations();\n            for (let j = 0; j < runtimes.length; j++) {\n                const runtime = runtimes[j];\n                if (runtime.target && (this._clockAnimation ? runtime.animation === this._clockAnimation : runtime.animation.targetProperty === this._clockProperty)) {\n                    this._foundAnimatable = animatable;\n                    this._clockIndex = i;\n                    return runtime;\n                }\n            }\n        }\n        this._foundAnimatable = null;\n        return null;\n    }\n\n    /**\n     * @internal\n     * Forgets the playback the controller was following.\n     */\n    public _forgetPlayback(): void {\n        this._clockRuntime = null;\n        this._clockAnimatable = null;\n        this._syncRoot = null;\n        this._syncRuntime = null;\n        this._lastProgress = null;\n        this._parked = false;\n        this._staleRuntime = null;\n        this._staleProgress = null;\n    }\n\n    /**\n     * @internal\n     * The motion between two progresses of a playback over a range, as a turn and then a translation in the character\n     * space of the earlier progress. Progress is unwrapped: whole cycles are in it, however many passed.\n     * @param from defines the first frame of the played range\n     * @param to defines the last frame of the played range\n     * @param lastProgress defines the earlier progress, in frames from the first frame\n     * @param progress defines the later progress, in frames from the first frame\n     * @param result defines the vector receiving the translation\n     * @returns the turn in radians\n     */\n    public _motionBetween(from: number, to: number, lastProgress: number, progress: number, result: Vector3): number {\n        const range = to - from;\n        if (range === 0 || (this._source === RootMotionSource.None && !this._turns)) {\n            result.setAll(0);\n            return 0;\n        }\n        const lastCycle = Math.floor(lastProgress / range);\n        const cycle = Math.floor(progress / range);\n        const lastFrame = from + lastProgress - lastCycle * range;\n        const frame = from + progress - cycle * range;\n        const cycles = cycle - lastCycle;\n\n        // The motion within the played range, relative to its start - a range played on its own loops by its own stride,\n        // not the whole clip's.\n        const startYaw = this.getRotationAtFrame(from);\n        const startOffset = this.getOffsetAtFrame(from, this._rangeStart);\n        const lastYaw = this._motionInRange(lastFrame, startYaw, startOffset, this._lastOffset);\n        let yaw = this._motionInRange(frame, startYaw, startOffset, result);\n\n        if (cycles !== 0) {\n            // Whole cycles passed: now = cycle^cycles, then the motion within the range.\n            const stepYaw = this._motionInRange(to, startYaw, startOffset, this._rangeCycle);\n            const cyclesYaw = this._cyclePower(cycles, this._rangeCycle, stepYaw, this._cyclesOffset);\n            this._rotateAboutUp(result, cyclesYaw, result).addInPlace(this._cyclesOffset);\n            yaw += cyclesYaw;\n        }\n\n        // Relative to where the character was: undo the turn it had already made.\n        this._rotateAboutUp(result.subtractInPlace(this._lastOffset), -lastYaw, result);\n        return yaw - lastYaw;\n    }\n\n    /**\n     * The motion at a frame relative to the motion at the start of the played range.\n     * @param frame defines the frame\n     * @param startYaw defines the turn at the start of the range\n     * @param startOffset defines the travel at the start of the range\n     * @param result defines the vector receiving the travel\n     * @returns the turn\n     */\n    private _motionInRange(frame: number, startYaw: number, startOffset: Vector3, result: Vector3): number {\n        this._rotateAboutUp(this.getOffsetAtFrame(frame, result).subtractInPlace(startOffset), -startYaw, result);\n        return this.getRotationAtFrame(frame) - startYaw;\n    }\n\n    /**\n     * A whole number of cycles of a planar motion - a turn about the up axis and then a translation - in closed form,\n     * for any number of cycles, forwards or back: the sum of the horizontal translation turned 0, 1, ... n-1 times is\n     * the translation turned (n - 1) / 2 times, sin(n * turn / 2) / sin(turn / 2) times as long, and n times the\n     * translation when there is no turn. The vertical part adds up. Nothing here is a matter of precision: no series\n     * is summed and no small angle is divided by.\n     * @param cycles defines the number of cycles, negative to go back\n     * @param step defines the translation of one cycle\n     * @param stepYaw defines the turn of one cycle\n     * @param result defines the vector receiving the translation of all the cycles\n     * @returns the turn of all the cycles\n     */\n    private _cyclePower(cycles: number, step: Vector3, stepYaw: number, result: Vector3): number {\n        // The turn only matters modulo a revolution; wrapped, whole revolutions read as no turn at all.\n        const turn = WrapAngle(stepYaw);\n        const halfSine = Math.sin(turn / 2);\n        const length = halfSine === 0 ? cycles : Math.sin((cycles * turn) / 2) / halfSine;\n        const up = this._upAxis;\n        const rise = Vector3.Dot(step, up) * cycles;\n        this._rotateAboutUp(this._horizontal(step, this._planarStep), ((cycles - 1) * turn) / 2, result).scaleInPlace(length);\n        result.addInPlace(up.scale(rise));\n        return cycles * stepYaw;\n    }\n\n    private _measureRootYaw(): Float32Array {\n        const root = this._rootNode!;\n        const samples = this._sampleCount;\n        const reference = this._rotationInCharacter(root, this._fromFrame, new Quaternion());\n        reference.conjugateInPlace();\n        const rotation = new Quaternion();\n        const yaw = new Float32Array(samples + 1);\n        let previous = 0;\n        for (let i = 0; i <= samples; i++) {\n            const wrapped = this._twist(this._rotationInCharacter(root, this._frameAt(i), rotation), reference);\n            // Unwrap, so a clip that turns past half a revolution keeps counting instead of jumping back.\n            previous = i === 0 ? wrapped : previous + WrapAngle(wrapped - WrapAngle(previous));\n            yaw[i] = previous;\n        }\n        return yaw;\n    }\n\n    private _measureRootTravel(yaw: Nullable<Float32Array>, minimumTravel: number, forced: boolean): Nullable<Float32Array> {\n        const root = this._rootNode!;\n        const samples = this._sampleCount;\n        const positions: Vector3[] = [];\n        for (let i = 0; i <= samples; i++) {\n            positions.push(this._positionInCharacter(root, this._frameAt(i), new Vector3()));\n        }\n\n        const start = positions[0];\n        // Net travel over the cycle, not how far the root strays: an in-place loop returns to where it started however\n        // much its hips surge and sway (a lurching walk can surge a fifth of the character's height), while a clip that\n        // really travels ends a stride or more away. A clip that travels and comes back, like a circle, reads as in place,\n        // which is safe: its feet do not slide either, so nothing is applied twice.\n        const net = this._horizontal(positions[samples].subtract(start), new Vector3());\n        if (!forced && net.length() < minimumTravel) {\n            return null;\n        }\n        if (net.lengthSquared() > 0) {\n            this._travelDirection.copyFrom(net).normalize();\n        }\n        if (!yaw && !this._extractLateral) {\n            this._snapTravelDirection(0);\n            // Whatever the root still drifts sideways of a snapped direction over a cycle would stay in the pose and pop\n            // back at every loop, so it is removed from the keys too, evenly over the cycle - but not applied.\n            this._horizontal(net, this._lateralDrift).subtractInPlace(this._travelDirection.scale(Vector3.Dot(net, this._travelDirection)));\n        }\n\n        const translation = new Float32Array((samples + 1) * 3);\n        const offset = new Vector3();\n        for (let i = 0; i <= samples; i++) {\n            this._rootTravelAt(positions[i], start, yaw ? yaw[i] : 0, !!yaw, offset).toArray(translation, i * 3);\n        }\n        return translation;\n    }\n\n    /**\n     * The travel removed from the root at a pose, so that the in-place root keeps the start position (turning) or its\n     * sway (straight).\n     * @param position defines the root position in character space\n     * @param start defines the root position in character space at the first frame\n     * @param yaw defines the turn at this pose\n     * @param turning defines whether turning is extracted\n     * @param result defines the vector receiving the travel\n     * @returns the result vector\n     */\n    private _rootTravelAt(position: Vector3, start: Vector3, yaw: number, turning: boolean, result: Vector3): Vector3 {\n        if (turning) {\n            // Every horizontal move, since the direction of travel is turning with the character.\n            const pivot = this._rotateAboutUp(this._horizontal(start, TmpVectors.Vector3[3]), yaw, TmpVectors.Vector3[3]);\n            return this._horizontal(position, result).subtractInPlace(pivot);\n        }\n        return this._project(position.subtractToRef(start, result), result);\n    }\n\n    private _measureContactTravel(\n        yaw: Nullable<Float32Array>,\n        explicitContacts: Array<TransformNode | Bone> | undefined,\n        minimumTravel: number,\n        forced: boolean\n    ): Nullable<Float32Array> {\n        const samples = this._sampleCount;\n        const up = this._upAxis;\n        let contacts: TransformNode[];\n        if (explicitContacts) {\n            contacts = explicitContacts.map((node) => this._resolveNode(node)).filter((node): node is TransformNode => !!node);\n        } else {\n            const base = this._rootNode ?? this._characterNode;\n            contacts = base.getDescendants(false, IsJoint).filter((node) => !node.getChildren(IsJoint, true).length) as TransformNode[];\n        }\n        if (!contacts.length) {\n            return null;\n        }\n\n        // Every candidate across the whole clip: a run starts with a foot in the air, so one frame cannot tell which\n        // nodes ever reach the ground.\n        const positions = contacts.map(() => [] as Vector3[]);\n        const lowest = contacts.map(() => Number.POSITIVE_INFINITY);\n        for (let i = 0; i <= samples; i++) {\n            const frame = this._frameAt(i);\n            for (let c = 0; c < contacts.length; c++) {\n                const position = this._positionInCharacter(contacts[c], frame, new Vector3());\n                positions[c].push(position);\n                lowest[c] = Math.min(lowest[c], Vector3.Dot(position, up));\n            }\n        }\n        if (!explicitContacts) {\n            const ground = Math.min(...lowest);\n            const kept = contacts.map((_, c) => lowest[c] <= ground + ContactHeightBand * this._characterHeight);\n            contacts = contacts.filter((_, c) => kept[c]);\n            const keptPositions = positions.filter((_, c) => kept[c]);\n            const keptLowest = lowest.filter((_, c) => kept[c]);\n            positions.length = 0;\n            positions.push(...keptPositions);\n            lowest.length = 0;\n            lowest.push(...keptLowest);\n        }\n\n        // A planted contact does not move in the world, so in character space it moves at exactly the opposite of the\n        // character's own velocity - and that velocity changes smoothly. A swinging contact sweeps forwards, even while\n        // touching down, when it can already be the lowest; a contact of a clip whose root carries the travel stands\n        // still. So each interval takes the contact on the ground whose step is closest to the ground speed of the\n        // interval before, starting from the clip's average ground speed measured with the slowest contact on the\n        // ground. With no contact on the ground - the flight of a run - the ground speed carries on.\n        // Steps are compared with the turn so far undone, so a turning path keeps a steady ground speed.\n        const tolerance = PlantedHeightBand * this._characterHeight;\n        const step = new Vector3();\n        const unturned = new Vector3();\n        const reference = new Vector3();\n        const translation = new Float32Array((samples + 1) * 3);\n        const travelled = Vector3.Zero();\n        const heading = Vector3.Zero();\n        let pathLength = 0;\n        const walk = (tracking: boolean) => {\n            const previous = reference.clone();\n            const sum = Vector3.Zero();\n            let grounded = 0;\n            travelled.setAll(0);\n            heading.setAll(0);\n            pathLength = 0;\n            for (let i = 1; i <= samples; i++) {\n                const turn = yaw ? yaw[i] : 0;\n                let best = Number.POSITIVE_INFINITY;\n                const chosen = new Vector3();\n                for (let c = 0; c < contacts.length; c++) {\n                    const before = positions[c][i - 1];\n                    const after = positions[c][i];\n                    if (Vector3.Dot(before, up) > lowest[c] + tolerance || Vector3.Dot(after, up) > lowest[c] + tolerance) {\n                        continue;\n                    }\n                    this._rotateAboutUp(this._horizontal(before.subtractToRef(after, step), step), -turn, unturned);\n                    const score = tracking ? Vector3.DistanceSquared(unturned, previous) : unturned.lengthSquared();\n                    if (score < best) {\n                        best = score;\n                        chosen.copyFrom(unturned);\n                    }\n                }\n                if (best === Number.POSITIVE_INFINITY) {\n                    chosen.copyFrom(previous);\n                } else {\n                    sum.addInPlace(chosen);\n                    grounded++;\n                }\n                if (tracking) {\n                    previous.copyFrom(chosen);\n                }\n                heading.addInPlace(chosen);\n                pathLength += chosen.length();\n                travelled.addInPlace(this._rotateAboutUp(chosen, turn, step)).toArray(translation, i * 3);\n            }\n            if (!tracking && grounded > 0) {\n                reference.copyFrom(sum).scaleInPlace(1 / grounded);\n            }\n        };\n        walk(false);\n        walk(true);\n        const straightness = pathLength > 0 ? heading.length() / pathLength : 0;\n\n        if (travelled.lengthSquared() > 0) {\n            this._travelDirection.copyFrom(travelled).normalize();\n        }\n        const distance = Vector3.Dot(travelled, this._travelDirection);\n        if (!forced && (distance < minimumTravel || straightness < MinimumStraightness)) {\n            return null;\n        }\n        if (!yaw) {\n            // Straight: only the travel along the direction, like the root path.\n            if (!this._extractLateral) {\n                this._snapTravelDirection(DeducedDirectionSnapAngle);\n            }\n            for (let i = 0; i <= samples; i++) {\n                step.fromArray(translation, i * 3);\n                this._travelDirection.scaleToRef(Vector3.Dot(step, this._travelDirection), step).toArray(translation, i * 3);\n            }\n        }\n        this._contactNodes = contacts;\n        return translation;\n    }\n\n    /**\n     * Clones the source group into the in-place group. When the root motion is in the root's keys, the root's channels\n     * are cloned with the motion left out: each key's pose, in character space, has the motion at its frame undone. The\n     * motion is the root's travel for a {@link RootMotionSource.Root} clip, plus the turn when rotation is extracted.\n     * Everything is computed from the source keys, which are not touched.\n     * @param name defines the name of the in-place group\n     * @param cloneAnimations defines whether every animation is cloned rather than only the rewritten root channels\n     * @returns the in-place group\n     */\n    private _buildInPlaceGroup(name: string, cloneAnimations: boolean): AnimationGroup {\n        const group = this._sourceGroup.clone(name);\n        // Cloning widens the range to the keys again; the in-place group plays what the source plays.\n        group.from = this._sourceGroup.from;\n        group.to = this._sourceGroup.to;\n        if (cloneAnimations) {\n            for (const targetedAnimation of group.targetedAnimations) {\n                targetedAnimation.animation = CloneAnimation(targetedAnimation.animation, true);\n            }\n        }\n        const root = this._rootNode;\n        if (!root || (!this._removesRootTravel && !this._turns)) {\n            return group;\n        }\n\n        const channels = this._channels.get(root)!;\n        const parent = root.parent;\n        const removesTravel = this._removesRootTravel;\n        const range = Math.max(this._toFrame - this._fromFrame, 1e-6);\n        const start = this._positionInCharacter(root, this._fromFrame, new Vector3());\n        const reference = this._rotationInCharacter(root, this._fromFrame, new Quaternion());\n        reference.conjugateInPlace();\n\n        const motionMatrix = new Matrix();\n        const rootMatrix = new Matrix();\n        const parentMatrix = new Matrix();\n        const localMatrix = new Matrix();\n        const yawQuaternion = new Quaternion();\n        const scratchPosition = new Vector3();\n        const scratchRotation = new Quaternion();\n        const travel = new Vector3();\n\n        // The in-place local transform of the root at any frame, from the source keys.\n        const inPlaceAt = (frame: number, position: Vector3, rotation: Quaternion) => {\n            this._matrixToCharacter(root, frame, rootMatrix);\n            this._matrixToCharacter(parent, frame, parentMatrix);\n            let yaw = 0;\n            if (this._turns) {\n                // Exact at this frame; the track only settles which whole turn the angle is on.\n                const wrapped = this._twist(this._rotationInCharacter(root, frame, scratchRotation), reference);\n                const tracked = this.getRotationAtFrame(frame);\n                yaw = wrapped + Math.round((tracked - wrapped) / (2 * Math.PI)) * 2 * Math.PI;\n            }\n            if (removesTravel) {\n                rootMatrix.getTranslationToRef(scratchPosition);\n                this._rootTravelAt(scratchPosition, start, yaw, this._turns, travel);\n                if (!this._turns) {\n                    travel.addInPlace(this._lateralDrift.scale(Math.min(1, Math.max(0, (frame - this._fromFrame) / range))));\n                }\n            } else if (this._pivots) {\n                this._rootTravelAt(start, start, yaw, true, travel);\n            } else {\n                travel.setAll(0);\n            }\n            // The motion maps the in-place pose onto the clip's pose: turn, then travel.\n            Matrix.FromQuaternionToRef(Quaternion.RotationAxisToRef(this._upAxis, yaw, yawQuaternion), motionMatrix);\n            motionMatrix.setTranslation(travel);\n            motionMatrix.invertToRef(motionMatrix);\n            rootMatrix.multiplyToRef(motionMatrix, localMatrix);\n            parentMatrix.invertToRef(parentMatrix);\n            localMatrix.multiplyToRef(parentMatrix, localMatrix);\n            localMatrix.decompose(undefined, rotation, position);\n        };\n\n        const position = new Vector3();\n        const rotation = new Quaternion();\n        const before = { position: new Vector3(), rotation: new Quaternion() };\n        const after = { position: new Vector3(), rotation: new Quaternion() };\n\n        // The keys of a channel with the motion left out, at the frames of the source keys.\n        const inPlaceKeys = (sourceKeys: IAnimationKey[], kind: \"position\" | \"rotationQuaternion\" | \"rotation\"): IAnimationKey[] => {\n            const keys: IAnimationKey[] = [];\n            let previousRotation: Nullable<Quaternion> = null;\n            let previousEuler: Nullable<Vector3> = null;\n            for (const key of sourceKeys) {\n                inPlaceAt(key.frame, position, rotation);\n                let value: any;\n                if (kind === \"position\") {\n                    value = position.clone();\n                } else {\n                    // Stay in the same hemisphere as the previous key, so interpolation does not take the long way round.\n                    if (previousRotation && Quaternion.Dot(previousRotation, rotation) < 0) {\n                        rotation.scaleInPlace(-1);\n                    }\n                    previousRotation = rotation.clone();\n                    if (kind === \"rotationQuaternion\") {\n                        value = previousRotation;\n                    } else {\n                        // Each angle continues from the previous key, so interpolation does not swing the long way round\n                        // where the conversion from a quaternion jumps between +PI and -PI.\n                        const euler = previousRotation.toEulerAngles();\n                        if (previousEuler) {\n                            euler.x += Math.round((previousEuler.x - euler.x) / (2 * Math.PI)) * 2 * Math.PI;\n                            euler.y += Math.round((previousEuler.y - euler.y) / (2 * Math.PI)) * 2 * Math.PI;\n                            euler.z += Math.round((previousEuler.z - euler.z) / (2 * Math.PI)) * 2 * Math.PI;\n                        }\n                        previousEuler = euler;\n                        value = euler;\n                    }\n                }\n\n                // Cubic spline tangents follow the rewritten curve. Straight travel is a linear removal, so the key's own\n                // tangent is transformed exactly; a turn is not, so the tangents are measured from the curve either side.\n                const tangent = (original: any, direction: number): any => {\n                    if (!original) {\n                        return original;\n                    }\n                    if (kind === \"position\" && !this._turns) {\n                        this._matrixToCharacter(parent, key.frame, parentMatrix);\n                        const inCharacter = Vector3.TransformNormal(original, parentMatrix);\n                        const removed = removesTravel ? this._project(inCharacter.clone(), new Vector3()).addInPlace(this._lateralDrift.scale(1 / range)) : Vector3.Zero();\n                        parentMatrix.invertToRef(parentMatrix);\n                        return original.subtract(Vector3.TransformNormal(removed, parentMatrix));\n                    }\n                    inPlaceAt(key.frame - TangentDelta, before.position, before.rotation);\n                    inPlaceAt(key.frame + TangentDelta, after.position, after.rotation);\n                    const low = direction < 0 ? before : { position, rotation };\n                    const high = direction < 0 ? { position, rotation } : after;\n                    if (kind === \"position\") {\n                        return high.position.subtract(low.position).scaleInPlace(1 / TangentDelta);\n                    }\n                    if (Quaternion.Dot(low.rotation, high.rotation) < 0) {\n                        high.rotation.scaleInPlace(-1);\n                    }\n                    const rate = high.rotation.subtract(low.rotation).scaleInPlace(1 / TangentDelta);\n                    return kind === \"rotationQuaternion\"\n                        ? rate\n                        : high.rotation\n                              .toEulerAngles()\n                              .subtract(low.rotation.toEulerAngles())\n                              .scaleInPlace(1 / TangentDelta);\n                };\n\n                keys.push({\n                    frame: key.frame,\n                    value,\n                    inTangent: tangent(key.inTangent, -1),\n                    outTangent: tangent(key.outTangent, 1),\n                    interpolation: key.interpolation,\n                    lockedTangent: key.lockedTangent,\n                    easingFunction: key.easingFunction,\n                });\n            }\n            return keys;\n        };\n\n        // A rewritten channel replaces the source's in the in-place group; the source animation is not touched.\n        const replace = (source: Animation, kind: \"position\" | \"rotationQuaternion\" | \"rotation\"): void => {\n            const animation = CloneAnimation(source);\n            animation.setKeys(inPlaceKeys(source.getKeys(), kind), true);\n            // By animation and target both: the same animation may drive other nodes earlier in the group.\n            const index = this._sourceGroup.targetedAnimations.findIndex((targetedAnimation) => targetedAnimation.animation === source && targetedAnimation.target === root);\n            group.targetedAnimations[index].animation = animation;\n        };\n\n        if (channels.position) {\n            replace(channels.position, \"position\");\n        } else {\n            // A root that only turns gets a position channel of its own, holding it at its starting point while the\n            // character turns about that point. It is the clip's clock, the channel the mixer weighs every clip of the\n            // character on, and it keeps the root in place when another clip animates the position. Its keys are as\n            // dense as the analysis: an animated ancestor between the root and the character makes the position vary.\n            const rotationChannel = (channels.rotationQuaternion ?? channels.rotation)!;\n            const staticKeys: IAnimationKey[] = [];\n            for (let i = 0; i <= this._sampleCount; i++) {\n                staticKeys.push({ frame: this._frameAt(i), value: root.position });\n            }\n            const animation = new Animation(`${root.name} position`, \"position\", rotationChannel.framePerSecond, Animation.ANIMATIONTYPE_VECTOR3, rotationChannel.loopMode);\n            animation.enableBlending = rotationChannel.enableBlending;\n            animation.blendingSpeed = rotationChannel.blendingSpeed;\n            animation.setKeys(inPlaceKeys(staticKeys, \"position\"), true);\n            group.addTargetedAnimation(animation, root);\n            this._restoredPosition = root.position.clone();\n            this._clockProperty = \"position\";\n        }\n        if (this._turns) {\n            if (channels.rotationQuaternion) {\n                replace(channels.rotationQuaternion, \"rotationQuaternion\");\n            } else if (channels.rotation) {\n                replace(channels.rotation, \"rotation\");\n            }\n        }\n        return group;\n    }\n\n    private _findRootNode(): Nullable<TransformNode> {\n        const nodes = Array.from(this._channels.keys());\n        let best: Nullable<TransformNode> = null;\n        let bestCount = -1;\n        for (const [node, channels] of this._channels) {\n            if (!channels.position) {\n                continue;\n            }\n            const count = nodes.filter((other) => other !== node && other.isDescendantOf(node)).length;\n            if (count > bestCount || (count === bestCount && best && best.isDescendantOf(node))) {\n                best = node as TransformNode;\n                bestCount = count;\n            }\n        }\n        return best;\n    }\n\n    private _measureHeight(base: TransformNode): number {\n        const position = new Vector3();\n        let lowest = Number.POSITIVE_INFINITY;\n        let highest = Number.NEGATIVE_INFINITY;\n        for (const node of [base, ...(base.getDescendants(false, IsJoint) as TransformNode[])]) {\n            const height = Vector3.Dot(this._positionInCharacter(node, this._fromFrame, position), this._upAxis);\n            lowest = Math.min(lowest, height);\n            highest = Math.max(highest, height);\n        }\n        return highest - lowest;\n    }\n\n    /**\n     * The track sample before a frame; the blend towards the next one is left in _sampleBlend.\n     * @param frame defines the frame\n     * @returns the sample index\n     */\n    private _sampleAt(frame: number): number {\n        const range = this._toFrame - this._fromFrame;\n        const samples = this._sampleCount;\n        if (range <= 0 || (this._source === RootMotionSource.None && !this._turns)) {\n            this._sampleBlend = 0;\n            return 0;\n        }\n        const exact = Math.min(samples, Math.max(0, ((frame - this._fromFrame) / range) * samples));\n        const index = Math.min(samples - 1, Math.floor(exact));\n        this._sampleBlend = exact - index;\n        return index;\n    }\n\n    private _frameAt(sample: number): number {\n        return this._fromFrame + ((this._toFrame - this._fromFrame) * sample) / this._sampleCount;\n    }\n\n    private _horizontal(vector: Vector3, result: Vector3): Vector3 {\n        const up = this._upAxis;\n        const height = Vector3.Dot(vector, up);\n        return result.set(vector.x - up.x * height, vector.y - up.y * height, vector.z - up.z * height);\n    }\n\n    private _project(vector: Vector3, result: Vector3): Vector3 {\n        this._horizontal(vector, result);\n        if (!this._extractLateral) {\n            this._travelDirection.scaleToRef(Vector3.Dot(result, this._travelDirection), result);\n        }\n        return result;\n    }\n\n    /**\n     * Snaps the direction of travel onto the nearest horizontal character space axis within the snap angle.\n     * @param defaultAngle defines the snap angle when none was given in the options\n     */\n    private _snapTravelDirection(defaultAngle: number): void {\n        const angle = this._directionSnapAngle ?? defaultAngle;\n        if (angle <= 0) {\n            return;\n        }\n        const up = this._upAxis;\n        const axis = new Vector3();\n        let best: Nullable<Vector3> = null;\n        let bestDot = Math.cos(angle);\n        for (const candidate of [Vector3.RightReadOnly, Vector3.UpReadOnly, Vector3.Forward(false)]) {\n            if (Math.abs(Vector3.Dot(candidate, up)) > 0.5) {\n                continue;\n            }\n            this._horizontal(candidate, axis).normalize();\n            for (const sign of [1, -1]) {\n                const dot = sign * Vector3.Dot(axis, this._travelDirection);\n                if (dot >= bestDot) {\n                    bestDot = dot;\n                    best = axis.scale(sign);\n                }\n            }\n        }\n        if (best) {\n            this._travelDirection.copyFrom(best);\n        }\n    }\n\n    private _rotateAboutUp(vector: Vector3, angle: number, result: Vector3): Vector3 {\n        if (angle === 0) {\n            return result.copyFrom(vector);\n        }\n        Matrix.FromQuaternionToRef(Quaternion.RotationAxisToRef(this._upAxis, angle, this._yawQuaternion), this._yawMatrix);\n        return Vector3.TransformNormalToRef(vector, this._yawMatrix, result);\n    }\n\n    /**\n     * The turn about the up axis from a reference orientation to a rotation, both in character space: the angle of the\n     * rotation about the up axis that best matches the change of orientation. Unlike the twist of a swing-twist split,\n     * it stays well defined while the root pitches and rolls - a dancer's hips tilting through the vertical made the\n     * twist jump by half turns.\n     * @param rotation defines the rotation\n     * @param referenceConjugate defines the conjugate of the reference rotation\n     * @returns the angle in radians, between -PI and PI\n     */\n    private _twist(rotation: Quaternion, referenceConjugate: Quaternion): number {\n        const delta = Matrix.FromQuaternionToRef(rotation.multiplyToRef(referenceConjugate, TmpVectors.Quaternion[1]), TmpVectors.Matrix[2]);\n        const up = this._upAxis;\n        // Two horizontal axes, right-handed with up the way +X, +Z are with +Y.\n        const first = this._horizontal(Math.abs(up.x) < 0.9 ? Vector3.RightReadOnly : Vector3.Forward(false), TmpVectors.Vector3[5]).normalize();\n        const second = Vector3.CrossToRef(first, up, TmpVectors.Vector3[6]);\n        const turnedFirst = Vector3.TransformNormalToRef(first, delta, TmpVectors.Vector3[7]);\n        const turnedSecond = Vector3.TransformNormalToRef(second, delta, TmpVectors.Vector3[8]);\n        return WrapAngle(Math.atan2(Vector3.Dot(turnedSecond, first) - Vector3.Dot(turnedFirst, second), Vector3.Dot(turnedFirst, first) + Vector3.Dot(turnedSecond, second)));\n    }\n\n    private _positionInCharacter(node: TransformNode, frame: number, result: Vector3): Vector3 {\n        const matrix = this._matrixToCharacter(node, frame, TmpVectors.Matrix[1]);\n        return result.set(matrix.m[12], matrix.m[13], matrix.m[14]);\n    }\n\n    private _rotationInCharacter(node: TransformNode, frame: number, result: Quaternion): Quaternion {\n        this._matrixToCharacter(node, frame, TmpVectors.Matrix[1]).decompose(undefined, result);\n        return result;\n    }\n\n    /**\n     * Composes a node's transform into character space at a frame of the clip, from the evaluated keys of animated\n     * nodes and the current transform of the others. Nothing is played or written.\n     * @param node defines the node, or null for the character space itself\n     * @param frame defines the frame to evaluate\n     * @param result defines the matrix receiving the transform\n     * @returns the result matrix\n     */\n    private _matrixToCharacter(node: Nullable<Node>, frame: number, result: Matrix): Matrix {\n        Matrix.IdentityToRef(result);\n        const local = TmpVectors.Matrix[0];\n        let current = node;\n        while (current && current !== this._characterNode) {\n            if (current instanceof TransformNode) {\n                this._localMatrix(current, frame, local);\n                result.multiplyToRef(local, result);\n            }\n            current = current.parent;\n        }\n        return result;\n    }\n\n    private _localMatrix(node: TransformNode, frame: number, result: Matrix): Matrix {\n        const channels = this._channels.get(node);\n        const scaling: Vector3 = channels?.scaling ? channels.scaling.evaluate(frame) : node.scaling;\n        const position: Vector3 = channels?.position ? channels.position.evaluate(frame) : node.position;\n        let rotation: Quaternion;\n        if (channels?.rotationQuaternion) {\n            rotation = channels.rotationQuaternion.evaluate(frame);\n        } else if (channels?.rotation) {\n            rotation = Quaternion.FromEulerVectorToRef(channels.rotation.evaluate(frame), TmpVectors.Quaternion[0]);\n        } else {\n            rotation = node.rotationQuaternion ?? Quaternion.FromEulerVectorToRef(node.rotation, TmpVectors.Quaternion[0]);\n        }\n        return Matrix.ComposeToRef(scaling, rotation, position, result);\n    }\n\n    private _resolveNode(node: TransformNode | Bone): Nullable<TransformNode> {\n        if (node instanceof TransformNode) {\n            return node;\n        }\n        const linked = node.getTransformNode();\n        if (!linked) {\n            throw new Error(`RootMotionClip: bone \"${node.name}\" has no linked transform node; pass the transform node the bone drives instead.`);\n        }\n        return linked;\n    }\n\n    private _firstAnimatedNode(): Nullable<TransformNode> {\n        for (const node of this._channels.keys()) {\n            return node as TransformNode;\n        }\n        return null;\n    }\n\n    private _topmostAncestor(node: TransformNode): TransformNode {\n        let top = node;\n        let current = node.parent;\n        while (current) {\n            if (current instanceof TransformNode) {\n                top = current;\n            }\n            current = current.parent;\n        }\n        return top;\n    }\n}\n\n/**\n * Moves and turns a character node by the root motion of the clips playing on it, once per animation step - from the\n * scene's onAfterAnimationsObservable, so after animations are evaluated and before the world matrices are computed.\n *\n * The motion of each clip follows the playback of its in-place group's root animation: the progress of the pose it\n * evaluated, so pausing, speed ratio changes, looping in every loop mode, forwards and backwards, playing a range,\n * synchronizing with another animatable and running to the end all move the character exactly as far as the pose went.\n * Clips playing together are blended the way the animation mixer blends their root pose: weighted animation groups\n * contribute their share, normalized once their weights add up to more than one, additive groups add theirs on top,\n * an unweighted group contributes its whole pose only while no weighted group animates the root (among unweighted\n * groups the last to write wins), and a group blending in contributes as much as it is blended in, so the character\n * moves with the blended pose whatever the clips do. The turn is blended as a weighted sum of the clips' turns.\n *\n * ```ts\n * const controller = new RootMotionController(character, [walk, run]);\n * walk.animationGroup.start(true);\n * run.animationGroup.start(true);\n * walk.animationGroup.weight = 0.3;\n * run.animationGroup.weight = 0.7;\n * ```\n */\nexport class RootMotionController implements IDisposable {\n    /**\n     * Gets or sets whether the motion is applied to the character node every frame. Set it to false to consume\n     * {@link RootMotionController.deltaPosition} and {@link RootMotionController.deltaRotation} yourself, for example\n     * to drive a physics character controller.\n     */\n    public applyToCharacter = true;\n\n    /**\n     * Notified every animation step the clips produce motion, after {@link RootMotionController.deltaPosition} and\n     * {@link RootMotionController.deltaRotation} are updated.\n     */\n    public readonly onRootMotionObservable = new Observable<RootMotionController>();\n\n    private readonly _characterNode: TransformNode;\n    private readonly _clips: RootMotionClip[] = [];\n    private readonly _sceneRootMotion: SceneRootMotion;\n    private _upAxis: Nullable<Vector3> = null;\n    private readonly _deltaPosition = Vector3.Zero();\n    private _deltaRotation = 0;\n    private readonly _frameDelta = Vector3.Zero();\n    private _frameYaw = 0;\n    private readonly _clipDelta = Vector3.Zero();\n\n    /**\n     * The node the motion is applied to.\n     */\n    public get characterNode(): TransformNode {\n        return this._characterNode;\n    }\n\n    /**\n     * The clips whose motion moves the character.\n     */\n    public get clips(): ReadonlyArray<RootMotionClip> {\n        return this._clips;\n    }\n\n    /**\n     * The travel of the last animation step, in world space; applied to the character unless\n     * {@link RootMotionController.applyToCharacter} is false.\n     */\n    public get deltaPosition(): Vector3 {\n        return this._deltaPosition;\n    }\n\n    /**\n     * The turn of the last animation step about the up axis, in radians; applied to the character unless\n     * {@link RootMotionController.applyToCharacter} is false.\n     */\n    public get deltaRotation(): number {\n        return this._deltaRotation;\n    }\n\n    /**\n     * Creates a controller for a character node.\n     * @param characterNode defines the node to move: the character node of the clips\n     * @param clips defines the clips to add\n     */\n    public constructor(characterNode: TransformNode, clips: RootMotionClip[] = []) {\n        this._characterNode = characterNode;\n        this._sceneRootMotion = SceneRootMotion.Get(characterNode.getScene());\n        this._sceneRootMotion.add(this);\n        for (const clip of clips) {\n            this.addClip(clip);\n        }\n    }\n\n    /**\n     * Adds a clip, so the character moves while its in-place group plays.\n     * @param clip defines the clip; its character node must be the controller's\n     * @throws when the clip belongs to another controller, moves another node, or has another up axis than the clips\n     * already added\n     */\n    public addClip(clip: RootMotionClip): void {\n        if (clip._controller === this) {\n            return;\n        }\n        if (clip._controller) {\n            throw new Error(`RootMotionController: clip \"${clip.animationGroup.name}\" already belongs to another controller.`);\n        }\n        if (clip.characterNode !== this._characterNode) {\n            throw new Error(\n                `RootMotionController: clip \"${clip.animationGroup.name}\" moves \"${clip.characterNode.name}\", not \"${this._characterNode.name}\". Pass the controller's node as the clip's characterNode.`\n            );\n        }\n        if (this._upAxis && !this._upAxis.equalsWithEpsilon(clip.upAxis)) {\n            throw new Error(`RootMotionController: clip \"${clip.animationGroup.name}\" has another up axis than the clips already added.`);\n        }\n        this._upAxis = this._upAxis ?? clip.upAxis.clone();\n        clip._controller = this;\n        clip._forgetPlayback();\n        this._clips.push(clip);\n        this._sceneRootMotion.refresh();\n    }\n\n    /**\n     * Removes a clip. Its in-place group keeps playing, in place.\n     * @param clip defines the clip\n     */\n    public removeClip(clip: RootMotionClip): void {\n        const index = this._clips.indexOf(clip);\n        if (index < 0) {\n            return;\n        }\n        this._clips.splice(index, 1);\n        clip._controller = null;\n        clip._writers = null;\n        clip._forgetPlayback();\n        if (!this._clips.length) {\n            this._upAxis = null;\n        }\n        this._sceneRootMotion.refresh();\n    }\n\n    /**\n     * Forgets where the playbacks were last measured. Call after jumping a group with goToFrame or resetting it, so the\n     * jump is not read as motion. Starting a group again needs no reset.\n     */\n    public reset(): void {\n        for (const clip of this._clips) {\n            // Reset from an animation event, after the clock wrote the step: that evaluation predates the jump, and the\n            // next one is the first to say where the playback carries on from.\n            const runtime = clip._clockRuntime;\n            clip._forgetPlayback();\n            clip._staleRuntime = runtime;\n            clip._staleProgress = runtime ? runtime._evaluatedProgress : null;\n        }\n        this._deltaPosition.setAll(0);\n        this._deltaRotation = 0;\n    }\n\n    /**\n     * Stops applying the motion and lets the clips go. The clips and their groups are not disposed.\n     */\n    public dispose(): void {\n        for (const clip of this._clips) {\n            clip._controller = null;\n            clip._writers = null;\n            clip._forgetPlayback();\n        }\n        this._clips.length = 0;\n        this._upAxis = null;\n        this._sceneRootMotion.remove(this);\n        this.onRootMotionObservable.clear();\n    }\n\n    /**\n     * @internal\n     * Applies the motion of this frame, once the mixer's writers of the clips' channels are gathered.\n     * @param animated defines whether the scene animated this step at all; when it did not, nothing moved and nothing\n     * is read into the clips' playbacks\n     */\n    public _update(animated: boolean): void {\n        const delta = this._frameDelta.setAll(0);\n        this._frameYaw = 0;\n        let moved = false;\n\n        for (const clip of animated ? this._clips : []) {\n            const writers = clip._writers;\n            const previous = clip._clockRuntime;\n            const found = clip._findClock();\n            if (found !== previous) {\n                // A runtime animation belongs to one playback. The previous playback's last evaluation is still to be\n                // consumed if it wrote this step - it ran to its end, or a callback stopped it after it wrote - weighed\n                // among the writers of this step like any other. One that did not write this step is forgotten: its\n                // last evaluation was consumed in the step it wrote.\n                if (previous && writers && clip._lastProgress !== null && !clip._parked && writers.current.indexOf(previous) >= 0) {\n                    moved = this._accumulate(clip, previous, clip._lastProgress, previous._evaluatedProgress) || moved;\n                }\n                clip._clockRuntime = found;\n                clip._clockAnimatable = found ? clip._foundAnimatable : null;\n                clip._syncRuntime = null;\n                clip._lastProgress = null;\n                clip._parked = false;\n            }\n            if (!found || !writers) {\n                continue;\n            }\n            const animatable = clip._clockAnimatable!;\n            if (writers.current.indexOf(found) < 0) {\n                // Did not write this step. Paused, its clock stands still too, and carries on from here when it resumes.\n                // Parked at a weight of zero, the scene skips it while its clock runs on: it starts again from wherever\n                // it resumes. Passed over for any other reason - by the scene's loop after a callback removed the\n                // animatable before it, or restarted after being passed over as paused - its next evaluation catches up,\n                // and the character with it.\n                if (!animatable.paused && animatable.weight === 0) {\n                    clip._parked = true;\n                }\n                continue;\n            }\n            if (clip._parked) {\n                clip._parked = false;\n                clip._lastProgress = null;\n            }\n            // The root the evaluation was actually clocked by, as it was made: a callback of this very step may have\n            // synchronized the group afterwards, and this step's pose is still the one the old clock gave.\n            const syncRoot = found._evaluatedSyncRoot;\n            const syncRuntime = syncRoot ? (syncRoot.getAnimations()[0] ?? null) : null;\n            if (syncRoot !== clip._syncRoot || syncRuntime !== clip._syncRuntime || found._evaluatedJump) {\n                // Synchronized with another root, no longer synchronized at all and back on its own clock, or snapped\n                // back by a root that cannot carry it to its end: the pose jumps, which is not travel.\n                clip._syncRoot = syncRoot;\n                clip._syncRuntime = syncRuntime;\n                clip._lastProgress = null;\n            }\n            // The first evaluation of a playback only establishes where it began - unless the playback was reset since\n            // that evaluation, by a callback in this step, in which case the next one does.\n            const progress = found._evaluatedProgress;\n            const lastProgress = clip._lastProgress;\n            if (lastProgress === null && found === clip._staleRuntime && progress === clip._staleProgress) {\n                continue;\n            }\n            clip._staleRuntime = null;\n            clip._staleProgress = null;\n            clip._lastProgress = progress;\n            if (lastProgress !== null && progress !== lastProgress) {\n                moved = this._accumulate(clip, found, lastProgress, progress) || moved;\n            }\n        }\n\n        if (!moved) {\n            this._deltaPosition.setAll(0);\n            this._deltaRotation = 0;\n            return;\n        }\n        const deltaYaw = this._frameYaw;\n        this._deltaRotation = deltaYaw;\n\n        const character = this._characterNode;\n        const up = this._upAxis!;\n        // Into the character's parent space through its own local rotation and scaling, not its world matrix: world\n        // matrices are cached per render, so with fixed animation steps every step after the first in a frame would read\n        // the facing from before the previous step's turn.\n        const rotation = character.rotationQuaternion ?? Quaternion.FromEulerVectorToRef(character.rotation, TmpVectors.Quaternion[2]);\n        Matrix.ComposeToRef(character.scaling, rotation, Vector3.ZeroReadOnly, TmpVectors.Matrix[3]);\n        const parentDelta = Vector3.TransformNormalToRef(delta, TmpVectors.Matrix[3], TmpVectors.Vector3[4]);\n        const parent = character.parent;\n        if (parent) {\n            // Computed now, not read from the cache: with several animation steps in a render the parent may have moved.\n            Vector3.TransformNormalToRef(parentDelta, parent.computeWorldMatrix(true), this._deltaPosition);\n        } else {\n            this._deltaPosition.copyFrom(parentDelta);\n        }\n\n        if (this.applyToCharacter) {\n            // Assigned rather than changed in place, so the node is marked dirty and renders where it now is.\n            character.position = character.position.addInPlace(parentDelta);\n            if (deltaYaw !== 0) {\n                // The turn happens in character space, before the character's own scaling. A mirroring scale (the\n                // handedness flip on a glTF __root__) reverses the sense of a turn once it is past that scaling.\n                const scaling = character.scaling;\n                const mirrored = scaling.x * scaling.y * scaling.z * (up.x * up.x * scaling.x + up.y * up.y * scaling.y + up.z * up.z * scaling.z) < 0;\n                if (!character.rotationQuaternion) {\n                    character.rotationQuaternion = Quaternion.FromEulerVector(character.rotation);\n                }\n                const turned = character.rotationQuaternion;\n                turned.multiplyToRef(Quaternion.RotationAxisToRef(up, mirrored ? -deltaYaw : deltaYaw, TmpVectors.Quaternion[2]), turned);\n                character.rotationQuaternion = turned;\n            }\n        }\n\n        if (this.onRootMotionObservable.hasObservers()) {\n            this.onRootMotionObservable.notifyObservers(this);\n        }\n    }\n\n    /**\n     * Adds a clip's motion between two progresses of a playback into this frame's motion, weighted the way the mixer\n     * weighs the pose of the playback.\n     * @param clip defines the clip\n     * @param runtime defines the runtime animation of the clip's clock\n     * @param lastProgress defines the progress consumed before\n     * @param progress defines the progress to consume\n     * @returns whether anything was added\n     */\n    private _accumulate(clip: RootMotionClip, runtime: RuntimeAnimation, lastProgress: number, progress: number): boolean {\n        if ((clip.source === RootMotionSource.None && !clip.extractsRotation) || !clip._writers) {\n            return false;\n        }\n        const weight = this._effectiveWeight(clip._writers, runtime);\n        if (weight === 0) {\n            return false;\n        }\n        const yaw = clip._motionBetween(runtime._evaluatedFrom, runtime._evaluatedTo, lastProgress, progress, this._clipDelta);\n        this._frameDelta.addInPlace(this._clipDelta.scaleInPlace(weight));\n        this._frameYaw += yaw * weight;\n        return true;\n    }\n\n    /**\n     * The share of a playback in the pose the mixer wrote to its channel this step, following the late animation\n     * bindings of the scene: an unweighted animatable writes directly and the last one wins, unless a weighted animatable\n     * also animates the channel, in which case the weighted ones replace it - normalized once their weights add up to\n     * more than one - and additive ones add their weight on top. A playback that ran to its end this step is among the\n     * writers like any other, from its place in the order they wrote; one that did not write this step has no share;\n     * one that wrote more than once - re-evaluated by an animation event, say - has the share of all its writes, as the\n     * bindings add them up. A playback still blending in wrote that much of its pose, so the share follows the factor\n     * its last write blended in with, taken from the record of that write rather than from the animation, whose own\n     * factor a write made since the step may have moved on.\n     * @param writers defines what the mixer wrote to the clip's channel this step\n     * @param runtime defines the runtime animation of the clip's clock\n     * @returns the share, between 0 and 1\n     */\n    private _effectiveWeight(writers: IChannelWriters, runtime: RuntimeAnimation): number {\n        const runtimes = writers.current;\n        let overrides = 0;\n        let additives = 0;\n        let direct = false;\n        let weight = 0;\n        let blending = 1;\n        for (let i = 0; i < runtimes.length; i++) {\n            if (runtimes[i] !== runtime) {\n                continue;\n            }\n            // The bindings hold one entry per write, added up from the weights as written, but each entry is read with\n            // the weight the runtime animation carries when the bindings are processed: that of its last write.\n            weight = writers.currentWeights[i];\n            blending = writers.currentBlending[i];\n            if (weight < 0) {\n                direct = true;\n            } else if (writers.currentAdditive[i]) {\n                additives++;\n            } else {\n                overrides++;\n            }\n        }\n        let share = (overrides / Math.max(1, writers.total) + additives) * weight;\n        if (direct && !writers.weighted && writers.lastDirect === runtime) {\n            share += 1;\n        }\n        return share * blending;\n    }\n}\n\n/**\n * The root motion controllers of a scene. After the scene's animations, one pass over the writes of the step - the\n * runtime animations that wrote, in that order, with the weights they wrote with, recorded as they did - gathers what\n * the mixer wrote to every channel a clip follows, then each controller applies its frame.\n */\nclass SceneRootMotion {\n    private readonly _scene: Scene;\n    private readonly _controllers: RootMotionController[] = [];\n    private readonly _writers: IChannelWriters[] = [];\n    private readonly _writersByNode = new Map<TransformNode, IChannelWriters[]>();\n    private _observer: Nullable<Observer<Scene>>;\n\n    /**\n     * Gets the root motion of a scene, creating it if needed.\n     * @param scene defines the scene\n     * @returns the root motion of the scene\n     */\n    public static Get(scene: Scene): SceneRootMotion {\n        let sceneRootMotion = SceneRootMotions.get(scene);\n        if (!sceneRootMotion) {\n            sceneRootMotion = new SceneRootMotion(scene);\n            SceneRootMotions.set(scene, sceneRootMotion);\n        }\n        return sceneRootMotion;\n    }\n\n    private constructor(scene: Scene) {\n        this._scene = scene;\n        this._observer = scene.onAfterAnimationsObservable.add(() => this._update());\n    }\n\n    /**\n     * Adds a controller, updated after those added before.\n     * @param controller defines the controller\n     */\n    public add(controller: RootMotionController): void {\n        this._controllers.push(controller);\n        this.refresh();\n    }\n\n    /**\n     * Removes a controller. The scene's root motion goes with its last controller.\n     * @param controller defines the controller\n     */\n    public remove(controller: RootMotionController): void {\n        const index = this._controllers.indexOf(controller);\n        if (index >= 0) {\n            this._controllers.splice(index, 1);\n        }\n        this.refresh();\n        if (!this._controllers.length) {\n            this._observer?.remove();\n            this._observer = null;\n            SceneRootMotions.delete(this._scene);\n        }\n    }\n\n    /**\n     * Gathers the channels the controllers' clips follow, once the clips of a controller change.\n     */\n    public refresh(): void {\n        this._writers.length = 0;\n        this._writersByNode.clear();\n        for (const controller of this._controllers) {\n            for (const clip of controller.clips) {\n                const node = clip._clockNode;\n                if (!node) {\n                    clip._writers = null;\n                    continue;\n                }\n                let entries = this._writersByNode.get(node);\n                if (!entries) {\n                    entries = [];\n                    this._writersByNode.set(node, entries);\n                }\n                let entry = entries.find((candidate) => candidate.property === clip._clockProperty);\n                if (!entry) {\n                    entry = {\n                        property: clip._clockProperty,\n                        total: 0,\n                        weighted: false,\n                        lastDirect: null,\n                        current: [],\n                        currentWeights: [],\n                        currentAdditive: [],\n                        currentBlending: [],\n                    };\n                    entries.push(entry);\n                    this._writers.push(entry);\n                }\n                clip._writers = entry;\n            }\n        }\n    }\n\n    private _update(): void {\n        // A step the scene did not evaluate - its animations disabled when it began - wrote nothing and moved nothing,\n        // and the clips' playbacks stand where they are: unlike a playback parked at a weight of zero, which an\n        // evaluated step skips while its clock runs on. Whether the step evaluated is recorded by the step itself: a\n        // callback may disable the animations after the step's writes, and the step still completes.\n        const scene = this._scene;\n        const animated = scene._animationStepEvaluated;\n        const writers = this._writers;\n        for (let i = 0; i < writers.length; i++) {\n            const entry = writers[i];\n            entry.total = 0;\n            entry.weighted = false;\n            entry.lastDirect = null;\n            entry.current.length = 0;\n            entry.currentWeights.length = 0;\n            entry.currentAdditive.length = 0;\n            entry.currentBlending.length = 0;\n        }\n        // What the mixer wrote this step: every write of a runtime animation to a target, in order, with the weight and\n        // the mode it was made with, recorded as it was made rather than read back afterwards - one whose playback ran\n        // to its end has left the active animatables, one stopped by a callback in the same step has lost its runtime\n        // animations, one turned additive since was bound as it wrote, and an animation of several targets wrote each\n        // of them. A paused animatable, one not started yet and one parked at a weight of zero wrote nothing.\n        //\n        // Only the writes the step's late bindings read: those of the step itself, up to the point the bindings were\n        // processed. A write made after them - by an observer of this very notification, such as the one an animation\n        // group started on a virtual timeline samples from, or by a callback between steps - reached no binding of this\n        // step, so it says nothing about the pose the step blended. The scene holds such a write over to the front of\n        // the next step's records, where it is read in its place: before that step's writes, which is where it stands\n        // in the order the bindings resolve. Reading it here instead would make the frame's motion depend on whether\n        // the controller was constructed before or after the observer that made it.\n        const writes = scene._animationWrites;\n        const count = animated ? scene._animationStepWriteCount : 0;\n        for (let i = 0; i < count; i++) {\n            const write = writes[i];\n            const entries = this._writersByNode.get(write.target);\n            if (!entries) {\n                continue;\n            }\n            const runtime = write.runtimeAnimation!;\n            const weight = write.weight;\n            for (let k = 0; k < entries.length; k++) {\n                const entry = entries[k];\n                if (entry.property !== runtime.targetPath) {\n                    continue;\n                }\n                entry.current.push(runtime);\n                entry.currentWeights.push(weight);\n                entry.currentAdditive.push(write.additive);\n                entry.currentBlending.push(write.blendingFactor);\n                if (weight < 0) {\n                    // Direct writers overwrite one another in order, so the last one is the pose.\n                    entry.lastDirect = runtime;\n                } else {\n                    entry.weighted = true;\n                    if (!write.additive) {\n                        entry.total += weight;\n                    }\n                }\n            }\n        }\n        for (let i = 0; i < this._controllers.length; i++) {\n            this._controllers[i]._update(animated);\n        }\n    }\n}\n\n/**\n * Clones an animation as {@link Animation.clone} does, keeping the easing function and events with it.\n * @param source defines the animation to clone\n * @param cloneKeys defines whether the keys and their values are cloned too, rather than shared until replaced\n * @returns the clone\n */\nfunction CloneAnimation(source: Animation, cloneKeys = false): Animation {\n    const animation = source.clone(cloneKeys);\n    const easingFunction = source.getEasingFunction();\n    if (easingFunction) {\n        animation.setEasingFunction(easingFunction);\n    }\n    for (const event of source.getEvents()) {\n        animation.addEvent(event);\n    }\n    return animation;\n}\n\nfunction IsJoint(node: Node): node is TransformNode {\n    return node instanceof TransformNode && !(node instanceof AbstractMesh);\n}\n\nfunction WrapAngle(angle: number): number {\n    return angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI));\n}\n","import { type IViewportLike } from \"./math.like\";\r\n\r\n/**\r\n * Class used to represent a viewport on screen\r\n */\r\nexport class Viewport implements IViewportLike {\r\n    /**\r\n     * Creates a Viewport object located at (x, y) and sized (width, height)\r\n     * @param x defines viewport left coordinate\r\n     * @param y defines viewport top coordinate\r\n     * @param width defines the viewport width\r\n     * @param height defines the viewport height\r\n     */\r\n    constructor(\r\n        /** viewport left coordinate */\r\n        public x: number,\r\n        /** viewport top coordinate */\r\n        public y: number,\r\n        /**viewport width */\r\n        public width: number,\r\n        /** viewport height */\r\n        public height: number\r\n    ) {}\r\n\r\n    /**\r\n     * Creates a new viewport using absolute sizing (from 0-> width, 0-> height instead of 0->1)\r\n     * @param renderWidth defines the rendering width\r\n     * @param renderHeight defines the rendering height\r\n     * @returns a new Viewport\r\n     */\r\n    public toGlobal(renderWidth: number, renderHeight: number): Viewport {\r\n        return new Viewport(this.x * renderWidth, this.y * renderHeight, this.width * renderWidth, this.height * renderHeight);\r\n    }\r\n\r\n    /**\r\n     * Stores absolute viewport value into a target viewport (from 0-> width, 0-> height instead of 0->1)\r\n     * @param renderWidth defines the rendering width\r\n     * @param renderHeight defines the rendering height\r\n     * @param ref defines the target viewport\r\n     * @returns the current viewport\r\n     */\r\n    public toGlobalToRef(renderWidth: number, renderHeight: number, ref: Viewport): Viewport {\r\n        ref.x = this.x * renderWidth;\r\n        ref.y = this.y * renderHeight;\r\n        ref.width = this.width * renderWidth;\r\n        ref.height = this.height * renderHeight;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Viewport copied from the current one\r\n     * @returns a new Viewport\r\n     */\r\n    public clone(): Viewport {\r\n        return new Viewport(this.x, this.y, this.width, this.height);\r\n    }\r\n}\r\n","import { AbstractEngine } from \"../abstractEngine.pure\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineRenderPass.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineRenderPass(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.getRenderPassNames = function (): string[] {\r\n        return this._renderPassNames;\r\n    };\r\n\r\n    AbstractEngine.prototype.getCurrentRenderPassName = function (): string {\r\n        return this._renderPassNames[this.currentRenderPassId];\r\n    };\r\n\r\n    AbstractEngine.prototype.createRenderPassId = function (name?: string): number {\r\n        // Note: render pass id == 0 is always for the main render pass\r\n        const id = ++AbstractEngine._RenderPassIdCounter;\r\n        this._renderPassNames[id] = name ?? \"NONAME\";\r\n        return id;\r\n    };\r\n\r\n    AbstractEngine.prototype.releaseRenderPassId = function (id: number): void {\r\n        this._renderPassNames[id] = undefined as any;\r\n\r\n        for (let s = 0; s < this.scenes.length; ++s) {\r\n            const scene = this.scenes[s];\r\n            for (let m = 0; m < scene.meshes.length; ++m) {\r\n                const mesh = scene.meshes[m];\r\n                mesh._releaseRenderPassId(id);\r\n                if (mesh.subMeshes) {\r\n                    for (let b = 0; b < mesh.subMeshes.length; ++b) {\r\n                        const subMesh = mesh.subMeshes[b];\r\n                        subMesh._removeDrawWrapper(id);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        this._onReleaseRenderPassObservable?.notifyObservers(id);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { serialize, serializeAsVector3 } from \"../Misc/decorators\";\nimport { SmartArray } from \"../Misc/smartArray\";\nimport { Observable } from \"../Misc/observable.pure\";\nimport { type DeepImmutable, type Nullable } from \"../types\";\nimport { type CameraInputsManager } from \"./cameraInputsManager\";\nimport { type Scene } from \"../scene.pure\";\nimport { Matrix, Vector3, Quaternion } from \"../Maths/math.vector.pure\";\nimport { Node } from \"../node\";\nimport { type Mesh } from \"../Meshes/mesh.pure\";\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\nimport { type ICullable } from \"../Culling/boundingInfo\";\nimport { Logger } from \"../Misc/logger\";\nimport { GetClass } from \"../Misc/typeStore\";\nimport { _WarnImport } from \"../Misc/devTools\";\nimport { Viewport } from \"../Maths/math.viewport\";\nimport { Frustum } from \"../Maths/math.frustum\";\nimport { type Plane } from \"../Maths/math.plane\";\nimport { Constants } from \"../Engines/constants\";\nimport { RegisterAbstractEngineRenderPass } from \"../Engines/AbstractEngine/abstractEngine.renderPass.pure\";\n\nimport { type PostProcess } from \"../PostProcesses/postProcess.pure\";\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\nimport { type FreeCamera } from \"./freeCamera.pure\";\nimport { type TargetCamera } from \"./targetCamera.pure\";\nimport { type Ray } from \"../Culling/ray.pure\";\nimport { type ArcRotateCamera } from \"./arcRotateCamera.pure\";\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\n\n/**\n * Oblique projection values\n */\nexport interface IObliqueParams {\n    /** The angle of the plane */\n    angle: number;\n    /** The length of the plane */\n    length: number;\n    /** The offset of the plane */\n    offset: number;\n}\n\n/**\n * This is the base class of all the camera used in the application.\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\n */\nexport class Camera extends Node {\n    /**\n     * @internal\n     */\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    public static _CreateDefaultParsedCamera = (name: string, scene: Scene): Camera => {\n        throw _WarnImport(\"UniversalCamera\");\n    };\n\n    /**\n     * This is the default projection mode used by the cameras.\n     * It helps recreating a feeling of perspective and better appreciate depth.\n     * This is the best way to simulate real life cameras.\n     */\n    public static readonly PERSPECTIVE_CAMERA = Constants.PERSPECTIVE_CAMERA;\n    /**\n     * This helps creating camera with an orthographic mode.\n     * Orthographic is commonly used in engineering as a means to produce object specifications that communicate dimensions unambiguously, each line of 1 unit length (cm, meter..whatever) will appear to have the same length everywhere on the drawing. This allows the drafter to dimension only a subset of lines and let the reader know that other lines of that length on the drawing are also that length in reality. Every parallel line in the drawing is also parallel in the object.\n     */\n    public static readonly ORTHOGRAPHIC_CAMERA = Constants.ORTHOGRAPHIC_CAMERA;\n\n    /**\n     * This is the default FOV mode for perspective cameras.\n     * This setting aligns the upper and lower bounds of the viewport to the upper and lower bounds of the camera frustum.\n     */\n    public static readonly FOVMODE_VERTICAL_FIXED = Constants.FOVMODE_VERTICAL_FIXED;\n    /**\n     * This setting aligns the left and right bounds of the viewport to the left and right bounds of the camera frustum.\n     */\n    public static readonly FOVMODE_HORIZONTAL_FIXED = Constants.FOVMODE_HORIZONTAL_FIXED;\n\n    /**\n     * This specifies there is no need for a camera rig.\n     * Basically only one eye is rendered corresponding to the camera.\n     */\n    public static readonly RIG_MODE_NONE = Constants.RIG_MODE_NONE;\n    /**\n     * Simulates a camera Rig with one blue eye and one red eye.\n     * This can be use with 3d blue and red glasses.\n     */\n    public static readonly RIG_MODE_STEREOSCOPIC_ANAGLYPH = Constants.RIG_MODE_STEREOSCOPIC_ANAGLYPH;\n    /**\n     * Defines that both eyes of the camera will be rendered side by side with a parallel target.\n     */\n    public static readonly RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL = Constants.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL;\n    /**\n     * Defines that both eyes of the camera will be rendered side by side with a none parallel target.\n     */\n    public static readonly RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED = Constants.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;\n    /**\n     * Defines that both eyes of the camera will be rendered over under each other.\n     */\n    public static readonly RIG_MODE_STEREOSCOPIC_OVERUNDER = Constants.RIG_MODE_STEREOSCOPIC_OVERUNDER;\n    /**\n     * Defines that both eyes of the camera will be rendered on successive lines interlaced for passive 3d monitors.\n     */\n    public static readonly RIG_MODE_STEREOSCOPIC_INTERLACED = Constants.RIG_MODE_STEREOSCOPIC_INTERLACED;\n    /**\n     * Defines that both eyes of the camera should be renderered in a VR mode (carbox).\n     */\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    public static readonly RIG_MODE_VR = Constants.RIG_MODE_VR;\n    /**\n     * Custom rig mode allowing rig cameras to be populated manually with any number of cameras\n     */\n    public static readonly RIG_MODE_CUSTOM = Constants.RIG_MODE_CUSTOM;\n\n    /**\n     * Defines if by default attaching controls should prevent the default javascript event to continue.\n     */\n    public static ForceAttachControlToAlwaysPreventDefault = false;\n\n    /**\n     * Define the input manager associated with the camera.\n     */\n    public inputs: CameraInputsManager<Camera>;\n\n    /** @internal */\n    @serializeAsVector3(\"position\")\n    public _position = Vector3.Zero();\n\n    /**\n     * Define the current local position of the camera in the scene\n     */\n    public get position(): Vector3 {\n        return this._position;\n    }\n\n    public set position(newPosition: Vector3) {\n        this._position = newPosition;\n    }\n\n    @serializeAsVector3(\"upVector\")\n    protected _upVector = Vector3.Up();\n\n    /**\n     * The vector the camera should consider as up.\n     * (default is Vector3(0, 1, 0) aka Vector3.Up())\n     */\n    public set upVector(vec: Vector3) {\n        this._upVector = vec;\n    }\n\n    public get upVector() {\n        return this._upVector;\n    }\n\n    /**\n     * Object containing oblique projection values (only used with ORTHOGRAPHIC_CAMERA)\n     */\n    public oblique: Nullable<IObliqueParams> = null;\n\n    /**\n     * The screen area in scene units squared\n     */\n    public get screenArea(): number {\n        let x: number;\n        let y: number;\n        if (this.mode === Camera.PERSPECTIVE_CAMERA) {\n            if (this.fovMode === Camera.FOVMODE_VERTICAL_FIXED) {\n                y = this.minZ * 2 * Math.tan(this.fov / 2);\n                x = this.getEngine().getAspectRatio(this) * y;\n            } else {\n                x = this.minZ * 2 * Math.tan(this.fov / 2);\n                y = x / this.getEngine().getAspectRatio(this);\n            }\n        } else {\n            const halfWidth = this.getEngine().getRenderWidth() / 2.0;\n            const halfHeight = this.getEngine().getRenderHeight() / 2.0;\n\n            x = (this.orthoRight ?? halfWidth) - (this.orthoLeft ?? -halfWidth);\n            y = (this.orthoTop ?? halfHeight) - (this.orthoBottom ?? -halfHeight);\n        }\n\n        return x * y;\n    }\n\n    private _orthoLeft: Nullable<number> = null;\n\n    /**\n     * Define the current limit on the left side for an orthographic camera\n     * In scene unit\n     */\n    public set orthoLeft(value: Nullable<number>) {\n        this._orthoLeft = value;\n\n        for (const rigCamera of this._rigCameras) {\n            rigCamera.orthoLeft = value;\n        }\n    }\n\n    @serialize()\n    public get orthoLeft(): Nullable<number> {\n        return this._orthoLeft;\n    }\n\n    private _orthoRight: Nullable<number> = null;\n\n    /**\n     * Define the current limit on the right side for an orthographic camera\n     * In scene unit\n     */\n    public set orthoRight(value: Nullable<number>) {\n        this._orthoRight = value;\n\n        for (const rigCamera of this._rigCameras) {\n            rigCamera.orthoRight = value;\n        }\n    }\n\n    @serialize()\n    public get orthoRight(): Nullable<number> {\n        return this._orthoRight;\n    }\n\n    private _orthoBottom: Nullable<number> = null;\n\n    /**\n     * Define the current limit on the bottom side for an orthographic camera\n     * In scene unit\n     */\n    public set orthoBottom(value: Nullable<number>) {\n        this._orthoBottom = value;\n\n        for (const rigCamera of this._rigCameras) {\n            rigCamera.orthoBottom = value;\n        }\n    }\n\n    @serialize()\n    public get orthoBottom(): Nullable<number> {\n        return this._orthoBottom;\n    }\n\n    private _orthoTop: Nullable<number> = null;\n\n    /**\n     * Define the current limit on the top side for an orthographic camera\n     * In scene unit\n     */\n    public set orthoTop(value: Nullable<number>) {\n        this._orthoTop = value;\n\n        for (const rigCamera of this._rigCameras) {\n            rigCamera.orthoTop = value;\n        }\n    }\n\n    @serialize()\n    public get orthoTop(): Nullable<number> {\n        return this._orthoTop;\n    }\n\n    /**\n     * Field Of View is set in Radians. (default is 0.8)\n     */\n    @serialize()\n    public fov = 0.8;\n\n    /**\n     * Sets the camera's field of view in radians based on the focal length and sensor size.\n     * @param value the focal length of the camera in mm.\n     * @param sensorSize the sensor width size of the camera in mm. (default is 36mm, which is a full frame sensor)\n     */\n    public setFocalLength(value: number, sensorSize: number = 36) {\n        this.fov = 2 * Math.atan(sensorSize / (2 * value));\n    }\n\n    /**\n     * Projection plane tilt around the X axis (horizontal), set in Radians. (default is 0)\n     * Can be used to make vertical lines in world space actually vertical on the screen.\n     * See https://forum.babylonjs.com/t/add-vertical-shift-to-3ds-max-exporter-babylon-cameras/17480\n     */\n    @serialize()\n    public projectionPlaneTilt = 0;\n\n    /**\n     * Define the minimum distance the camera can see from.\n     * This is important to note that the depth buffer are not infinite and the closer it starts\n     * the more your scene might encounter depth fighting issue.\n     */\n    @serialize()\n    public minZ = 1;\n\n    /**\n     * Define the maximum distance the camera can see to.  (default is 10000)\n     * This is important to note that the depth buffer are not infinite and the further it end\n     * the more your scene might encounter depth fighting issue.\n     */\n    @serialize()\n    public maxZ = 10000.0;\n\n    /**\n     * Define the default inertia of the camera.\n     * This helps giving a smooth feeling to the camera movement.\n     */\n    @serialize()\n    public get inertia(): number {\n        return this._baseInertia;\n    }\n\n    public set inertia(value: number) {\n        this._baseInertia = value;\n    }\n\n    private _baseInertia = 0.9;\n\n    private _mode = Camera.PERSPECTIVE_CAMERA;\n\n    /**\n     * Define the mode of the camera (Camera.PERSPECTIVE_CAMERA or Camera.ORTHOGRAPHIC_CAMERA)\n     */\n    set mode(mode: number) {\n        this._mode = mode;\n\n        // Pass the mode down to the rig cameras\n        for (const rigCamera of this._rigCameras) {\n            rigCamera.mode = mode;\n        }\n    }\n\n    @serialize()\n    get mode(): number {\n        return this._mode;\n    }\n\n    /**\n     * Define whether the camera is intermediate.\n     * This is useful to not present the output directly to the screen in case of rig without post process for instance\n     */\n    public isIntermediate = false;\n\n    /**\n     * Define the viewport of the camera.\n     * This correspond to the portion of the screen the camera will render to in normalized 0 to 1 unit.\n     */\n    public viewport = new Viewport(0, 0, 1.0, 1.0);\n\n    /**\n     * Restricts the camera to viewing objects with the same layerMask.\n     * A camera with a layerMask of 1 will render mesh.layerMask & camera.layerMask!== 0\n     */\n    @serialize()\n    public layerMask: number = 0x0fffffff;\n\n    /**\n     * fovMode sets the camera frustum bounds to the viewport bounds. (default is FOVMODE_VERTICAL_FIXED)\n     */\n    @serialize()\n    public fovMode: number = Camera.FOVMODE_VERTICAL_FIXED;\n\n    /**\n     * Rig mode of the camera.\n     * This is useful to create the camera with two \"eyes\" instead of one to create VR or stereoscopic scenes.\n     * This is normally controlled byt the camera themselves as internal use.\n     */\n    @serialize()\n    public cameraRigMode = Camera.RIG_MODE_NONE;\n\n    /**\n     * Defines the distance between both \"eyes\" in case of a RIG\n     */\n    @serialize()\n    public interaxialDistance: number;\n\n    /**\n     * Defines if stereoscopic rendering is done side by side or over under.\n     */\n    @serialize()\n    public isStereoscopicSideBySide: boolean;\n\n    /**\n     * Ignores camera maxZ when computing the projection matrix (ie. use 0 instead of maxZ), meaning objects won't be culled by the far plane\n     */\n    @serialize()\n    public ignoreCameraMaxZ = false;\n\n    /**\n     * Defines the list of custom render target which are rendered to and then used as the input to this camera's render. Eg. display another camera view on a TV in the main scene\n     * This is pretty helpful if you wish to make a camera render to a texture you could reuse somewhere\n     * else in the scene. (Eg. security camera)\n     *\n     * To change the final output target of the camera, camera.outputRenderTarget should be used instead (eg. webXR renders to a render target corresponding to an HMD)\n     */\n    public customRenderTargets: RenderTargetTexture[] = [];\n    /**\n     * When set, the camera will render to this render target instead of the default canvas\n     *\n     * If the desire is to use the output of a camera as a texture in the scene consider using camera.customRenderTargets instead\n     */\n    public outputRenderTarget: Nullable<RenderTargetTexture> = null;\n\n    /**\n     * Observable triggered when the camera view matrix has changed.\n     * Beware of reentrance! Some methods like Camera.getViewMatrix and Camera.getWorldMatrix can trigger the onViewMatrixChangedObservable\n     * observable, so using them inside an observer will require additional logic to avoid a stack overflow error.\n     */\n    public onViewMatrixChangedObservable = new Observable<Camera>();\n    /**\n     * Observable triggered when the camera Projection matrix has changed.\n     */\n    public onProjectionMatrixChangedObservable = new Observable<Camera>();\n    /**\n     * Observable triggered when the inputs have been processed.\n     */\n    public onAfterCheckInputsObservable = new Observable<Camera>();\n    /**\n     * Observable triggered when reset has been called and applied to the camera.\n     */\n    public onRestoreStateObservable = new Observable<Camera>();\n\n    /**\n     * Is this camera a part of a rig system?\n     */\n    public isRigCamera: boolean = false;\n\n    /**\n     * If isRigCamera set to true this will be set with the parent camera.\n     * The parent camera is not (!) necessarily the .parent of this camera (like in the case of XR)\n     */\n    public rigParent?: Camera;\n\n    /**\n     * Render pass id used by the camera to render into the main framebuffer\n     */\n    public renderPassId: number;\n\n    private _hasMoved = false;\n\n    /**\n     * Gets a flag indicating that the camera has moved in some way since the last call to Camera.update()\n     */\n    public get hasMoved() {\n        return this._hasMoved;\n    }\n\n    /** @internal */\n    public _cameraRigParams: any;\n    /** @internal */\n    public _rigCameras = new Array<Camera>();\n    /** @internal */\n    public _rigPostProcess: Nullable<PostProcess>;\n\n    /** @internal */\n    public _skipRendering = false;\n\n    /** @internal */\n    public _projectionMatrix = new Matrix();\n\n    /** @internal */\n    public _postProcesses = new Array<Nullable<PostProcess>>();\n\n    /** @internal */\n    public _activeMeshes = new SmartArray<AbstractMesh>(256);\n\n    protected _globalPosition = Vector3.Zero();\n\n    /** @internal */\n    public _computedViewMatrix = Matrix.Identity();\n    private _doNotComputeProjectionMatrix = false;\n    private _transformMatrix = Matrix.Zero();\n    /** @internal */\n    public _frustumPlanes: Plane[];\n    private _refreshFrustumPlanes = true;\n    private _storedFov: number;\n    private _stateStored: boolean;\n    private _absoluteRotation: Quaternion = Quaternion.Identity();\n\n    /**\n     * Instantiates a new camera object.\n     * This should not be used directly but through the inherited cameras: ArcRotate, Free...\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\n     * @param name Defines the name of the camera in the scene\n     * @param position Defines the position of the camera\n     * @param scene Defines the scene the camera belongs too\n     * @param setActiveOnSceneIfNoneActive Defines if the camera should be set as active after creation if no other camera have been defined in the scene\n     */\n    constructor(name: string, position: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive = true) {\n        RegisterAbstractEngineRenderPass();\n        super(name, scene, false);\n\n        this.layerMask = this.getScene().defaultCameraLayerMask;\n        this.getScene().addCamera(this);\n\n        if (setActiveOnSceneIfNoneActive && !this.getScene().activeCamera) {\n            this.getScene().activeCamera = this;\n        }\n\n        this.position = position;\n        this.renderPassId = this.getScene().getEngine().createRenderPassId(`Camera ${name}`);\n    }\n\n    /**\n     * Store current camera state (fov, position, etc..)\n     * @returns the camera\n     */\n    public storeState(): Camera {\n        this._stateStored = true;\n        this._storedFov = this.fov;\n\n        return this;\n    }\n\n    /**\n     * Returns true if a state has been stored by calling storeState method.\n     * @returns true if state has been stored.\n     */\n    public hasStateStored(): boolean {\n        return !!this._stateStored;\n    }\n    /**\n     * Restores the camera state values if it has been stored. You must call storeState() first\n     * @returns true if restored and false otherwise\n     */\n    protected _restoreStateValues(): boolean {\n        if (!this._stateStored) {\n            return false;\n        }\n\n        this.fov = this._storedFov;\n\n        return true;\n    }\n\n    /**\n     * Restored camera state. You must call storeState() first.\n     * @returns true if restored and false otherwise\n     */\n    public restoreState(): boolean {\n        if (this._restoreStateValues()) {\n            this.onRestoreStateObservable.notifyObservers(this);\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Gets the class name of the camera.\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return \"Camera\";\n    }\n\n    /** @internal */\n    public readonly _isCamera = true;\n\n    /**\n     * Gets a string representation of the camera useful for debug purpose.\n     * @param fullDetails Defines that a more verbose level of logging is required\n     * @returns the string representation\n     */\n    public override toString(fullDetails?: boolean): string {\n        let ret = \"Name: \" + this.name;\n        ret += \", type: \" + this.getClassName();\n        if (this.animations) {\n            for (let i = 0; i < this.animations.length; i++) {\n                ret += \", animation[0]: \" + this.animations[i].toString(fullDetails);\n            }\n        }\n        return ret;\n    }\n\n    /**\n     * Automatically tilts the projection plane, using `projectionPlaneTilt`, to correct the perspective effect on vertical lines.\n     */\n    public applyVerticalCorrection() {\n        const rot = this.absoluteRotation.toEulerAngles();\n\n        this.projectionPlaneTilt = this._scene.useRightHandedSystem ? -rot.x : rot.x;\n    }\n\n    /**\n     * Gets the current world space position of the camera.\n     */\n    public get globalPosition(): Vector3 {\n        return this._globalPosition;\n    }\n\n    /**\n     * Gets the list of active meshes this frame (meshes no culled or excluded by lod s in the frame)\n     * @returns the active meshe list\n     */\n    public getActiveMeshes(): SmartArray<AbstractMesh> {\n        return this._activeMeshes;\n    }\n\n    /**\n     * Check whether a mesh is part of the current active mesh list of the camera\n     * @param mesh Defines the mesh to check\n     * @returns true if active, false otherwise\n     */\n    public isActiveMesh(mesh: Mesh): boolean {\n        return this._activeMeshes.indexOf(mesh) !== -1;\n    }\n\n    /**\n     * Is this camera ready to be used/rendered\n     * @param completeCheck defines if a complete check (including post processes) has to be done (false by default)\n     * @returns true if the camera is ready\n     */\n    public override isReady(completeCheck = false): boolean {\n        if (completeCheck) {\n            for (const pp of this._postProcesses) {\n                if (pp && !pp.isReady()) {\n                    return false;\n                }\n            }\n        }\n        return super.isReady(completeCheck);\n    }\n\n    /** @internal */\n    public override _initCache() {\n        super._initCache();\n\n        this._cache.position = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\n        this._cache.upVector = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\n\n        this._cache.mode = undefined;\n        this._cache.minZ = undefined;\n        this._cache.maxZ = undefined;\n\n        this._cache.fov = undefined;\n        this._cache.fovMode = undefined;\n        this._cache.aspectRatio = undefined;\n\n        this._cache.orthoLeft = undefined;\n        this._cache.orthoRight = undefined;\n        this._cache.orthoBottom = undefined;\n        this._cache.orthoTop = undefined;\n        this._cache.obliqueAngle = undefined;\n        this._cache.obliqueLength = undefined;\n        this._cache.obliqueOffset = undefined;\n        this._cache.renderWidth = undefined;\n        this._cache.renderHeight = undefined;\n    }\n\n    /**\n     * @internal\n     */\n    public override _updateCache(ignoreParentClass?: boolean): void {\n        if (!ignoreParentClass) {\n            super._updateCache();\n        }\n\n        this._cache.position.copyFrom(this.position);\n        this._cache.upVector.copyFrom(this.upVector);\n    }\n\n    /** @internal */\n    public override _isSynchronized(): boolean {\n        return this._isSynchronizedViewMatrix() && this._isSynchronizedProjectionMatrix();\n    }\n\n    /** @internal */\n    public _isSynchronizedViewMatrix(): boolean {\n        if (!super._isSynchronized()) {\n            return false;\n        }\n\n        return this._cache.position.equals(this.position) && this._cache.upVector.equals(this.upVector) && this.isSynchronizedWithParent();\n    }\n\n    /** @internal */\n    public _isSynchronizedProjectionMatrix(): boolean {\n        const maxZ = this.ignoreCameraMaxZ ? 0 : this.maxZ;\n\n        let isSynchronized = this._cache.mode === this.mode && this._cache.minZ === this.minZ && this._cache.maxZ === maxZ;\n\n        if (!isSynchronized) {\n            return false;\n        }\n\n        const engine = this.getEngine();\n\n        if (this.mode === Camera.PERSPECTIVE_CAMERA) {\n            isSynchronized =\n                this._cache.fov === this.fov &&\n                this._cache.fovMode === this.fovMode &&\n                this._cache.aspectRatio === engine.getAspectRatio(this) &&\n                this._cache.projectionPlaneTilt === this.projectionPlaneTilt;\n        } else {\n            isSynchronized =\n                this._cache.orthoLeft === this.orthoLeft &&\n                this._cache.orthoRight === this.orthoRight &&\n                this._cache.orthoBottom === this.orthoBottom &&\n                this._cache.orthoTop === this.orthoTop &&\n                this._cache.renderWidth === engine.getRenderWidth() &&\n                this._cache.renderHeight === engine.getRenderHeight();\n\n            if (this.oblique) {\n                isSynchronized =\n                    isSynchronized &&\n                    this._cache.obliqueAngle === this.oblique.angle &&\n                    this._cache.obliqueLength === this.oblique.length &&\n                    this._cache.obliqueOffset === this.oblique.offset;\n            }\n        }\n\n        return isSynchronized;\n    }\n\n    /**\n     * Attach the input controls to a specific dom element to get the input from.\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\n     */\n    public attachControl(noPreventDefault?: boolean): void;\n    /**\n     * Attach the input controls to a specific dom element to get the input from.\n     * @param ignored defines an ignored parameter kept for backward compatibility.\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\n     * BACK COMPAT SIGNATURE ONLY.\n     */\n    public attachControl(ignored: any, noPreventDefault?: boolean): void;\n    /**\n     * Attach the input controls to a specific dom element to get the input from.\n     * This function is here because typescript removes the typing of the last function.\n     * @param _ignored defines an ignored parameter kept for backward compatibility.\n     * @param _noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\n     */\n    public attachControl(_ignored?: any, _noPreventDefault?: boolean): void {}\n\n    /**\n     * Detach the current controls from the specified dom element.\n     */\n    public detachControl(): void;\n    /**\n     * Detach the current controls from the specified dom element.\n     * @param ignored defines an ignored parameter kept for backward compatibility.\n     */\n    public detachControl(ignored?: any): void;\n    /**\n     * Detach the current controls from the specified dom element.\n     * This function is here because typescript removes the typing of the last function.\n     * @param _ignored defines an ignored parameter kept for backward compatibility.\n     */\n    public detachControl(_ignored?: any): void {}\n\n    /**\n     * Update the camera state according to the different inputs gathered during the frame.\n     */\n    public update(): void {\n        this._hasMoved = false;\n        this._checkInputs();\n        if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {\n            this._updateRigCameras();\n        }\n\n        // Attempt to update the camera's view and projection matrices.\n        // This call is being made because these matrices are no longer being updated\n        // as a part of the picking ray process (in addition to scene.render).\n        this.getViewMatrix();\n        this.getProjectionMatrix();\n    }\n\n    /** @internal */\n    public _checkInputs(): void {\n        this.onAfterCheckInputsObservable.notifyObservers(this);\n    }\n\n    /** @internal */\n    public get rigCameras(): Camera[] {\n        return this._rigCameras;\n    }\n\n    /**\n     * Gets the post process used by the rig cameras\n     */\n    public get rigPostProcess(): Nullable<PostProcess> {\n        return this._rigPostProcess;\n    }\n\n    /**\n     * Internal, gets the first post process.\n     * @returns the first post process to be run on this camera.\n     */\n    public _getFirstPostProcess(): Nullable<PostProcess> {\n        for (let ppIndex = 0; ppIndex < this._postProcesses.length; ppIndex++) {\n            if (this._postProcesses[ppIndex] !== null) {\n                return this._postProcesses[ppIndex];\n            }\n        }\n        return null;\n    }\n\n    private _cascadePostProcessesToRigCams(): void {\n        // invalidate framebuffer\n        const firstPostProcess = this._getFirstPostProcess();\n        if (firstPostProcess) {\n            firstPostProcess.markTextureDirty();\n        }\n\n        // glue the rigPostProcess to the end of the user postprocesses & assign to each sub-camera\n        for (let i = 0, len = this._rigCameras.length; i < len; i++) {\n            const cam = this._rigCameras[i];\n            const rigPostProcess = cam._rigPostProcess;\n\n            // for VR rig, there does not have to be a post process\n            if (rigPostProcess) {\n                const isPass = rigPostProcess.getEffectName() === \"pass\";\n                if (isPass) {\n                    // any rig which has a PassPostProcess for rig[0], cannot be isIntermediate when there are also user postProcesses\n                    cam.isIntermediate = this._postProcesses.length === 0;\n                }\n                cam._postProcesses = this._postProcesses.slice(0).concat(rigPostProcess);\n                rigPostProcess.markTextureDirty();\n            } else {\n                cam._postProcesses = this._postProcesses.slice(0);\n            }\n        }\n    }\n\n    /**\n     * Attach a post process to the camera.\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#attach-postprocess\n     * @param postProcess The post process to attach to the camera\n     * @param insertAt The position of the post process in case several of them are in use in the scene\n     * @returns the position the post process has been inserted at\n     */\n    public attachPostProcess(postProcess: PostProcess, insertAt: Nullable<number> = null): number {\n        if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {\n            Logger.Error(\"You're trying to reuse a post process not defined as reusable.\");\n            return 0;\n        }\n\n        if (insertAt == null || insertAt < 0) {\n            this._postProcesses.push(postProcess);\n        } else if (this._postProcesses[insertAt] === null) {\n            this._postProcesses[insertAt] = postProcess;\n        } else {\n            this._postProcesses.splice(insertAt, 0, postProcess);\n        }\n        this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated\n\n        // Update prePass\n        if (this._scene.prePassRenderer) {\n            this._scene.prePassRenderer.markAsDirty();\n        }\n\n        return this._postProcesses.indexOf(postProcess);\n    }\n\n    /**\n     * Detach a post process to the camera.\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#attach-postprocess\n     * @param postProcess The post process to detach from the camera\n     */\n    public detachPostProcess(postProcess: PostProcess): void {\n        const idx = this._postProcesses.indexOf(postProcess);\n        if (idx !== -1) {\n            this._postProcesses[idx] = null;\n        }\n\n        // Update prePass\n        if (this._scene.prePassRenderer) {\n            this._scene.prePassRenderer.markAsDirty();\n        }\n\n        this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated\n    }\n\n    /**\n     * Gets the current world matrix of the camera\n     * @returns the world matrix\n     */\n    public override getWorldMatrix(): Matrix {\n        if (this._isSynchronizedViewMatrix()) {\n            return this._worldMatrix;\n        }\n\n        // Getting the view matrix will also compute the world matrix.\n        this.getViewMatrix();\n\n        return this._worldMatrix;\n    }\n\n    /** @internal */\n    public _getViewMatrix(): Matrix {\n        return Matrix.Identity();\n    }\n\n    /**\n     * Gets the current view matrix of the camera.\n     * @param force forces the camera to recompute the matrix without looking at the cached state\n     * @returns the view matrix\n     */\n    public getViewMatrix(force?: boolean): Matrix {\n        if (!force && this._isSynchronizedViewMatrix()) {\n            return this._computedViewMatrix;\n        }\n\n        this._hasMoved = true;\n\n        this.updateCache();\n        this._computedViewMatrix = this._getViewMatrix();\n\n        this._currentRenderId = this.getScene().getRenderId();\n        this._childUpdateId++;\n\n        this._refreshFrustumPlanes = true;\n\n        if (this._cameraRigParams && this._cameraRigParams.vrPreViewMatrix) {\n            this._computedViewMatrix.multiplyToRef(this._cameraRigParams.vrPreViewMatrix, this._computedViewMatrix);\n        }\n\n        // Notify parent camera if rig camera is changed\n        if (this.parent && (this.parent as Camera).onViewMatrixChangedObservable) {\n            (this.parent as Camera).onViewMatrixChangedObservable.notifyObservers(this.parent as Camera);\n        }\n\n        this.onViewMatrixChangedObservable.notifyObservers(this);\n\n        this._computedViewMatrix.invertToRef(this._worldMatrix);\n        this._worldMatrix.getTranslationToRef(this._globalPosition);\n\n        return this._computedViewMatrix;\n    }\n\n    /**\n     * Freeze the projection matrix.\n     * It will prevent the cache check of the camera projection compute and can speed up perf\n     * if no parameter of the camera are meant to change\n     * @param projection Defines manually a projection if necessary\n     */\n    public freezeProjectionMatrix(projection?: Matrix): void {\n        this._doNotComputeProjectionMatrix = true;\n        if (projection !== undefined) {\n            this._projectionMatrix = projection;\n        }\n    }\n\n    /**\n     * Unfreeze the projection matrix if it has previously been freezed by freezeProjectionMatrix.\n     */\n    public unfreezeProjectionMatrix(): void {\n        this._doNotComputeProjectionMatrix = false;\n    }\n\n    /**\n     * Gets the current projection matrix of the camera.\n     * @param force forces the camera to recompute the matrix without looking at the cached state\n     * @returns the projection matrix\n     */\n    public getProjectionMatrix(force?: boolean): Matrix {\n        if (this._doNotComputeProjectionMatrix || (!force && this._isSynchronizedProjectionMatrix())) {\n            return this._projectionMatrix;\n        }\n\n        const maxZ = this.ignoreCameraMaxZ ? 0 : this.maxZ;\n\n        // Cache\n        this._cache.mode = this.mode;\n        this._cache.minZ = this.minZ;\n        this._cache.maxZ = maxZ;\n\n        // Matrix\n        this._refreshFrustumPlanes = true;\n\n        const engine = this.getEngine();\n        const scene = this.getScene();\n        const reverseDepth = engine.useReverseDepthBuffer;\n        if (this.mode === Camera.PERSPECTIVE_CAMERA) {\n            this._cache.fov = this.fov;\n            this._cache.fovMode = this.fovMode;\n            this._cache.aspectRatio = engine.getAspectRatio(this);\n            this._cache.projectionPlaneTilt = this.projectionPlaneTilt;\n\n            if (this.minZ <= 0) {\n                this.minZ = 0.1;\n            }\n\n            let getProjectionMatrix: (\n                fov: number,\n                aspect: number,\n                znear: number,\n                zfar: number,\n                result: Matrix,\n                isVerticalFovFixed: boolean,\n                halfZRange: boolean,\n                projectionPlaneTilt: number,\n                reverseDepthBufferMode: boolean\n            ) => void;\n            if (scene.useRightHandedSystem) {\n                getProjectionMatrix = Matrix.PerspectiveFovRHToRef;\n            } else {\n                getProjectionMatrix = Matrix.PerspectiveFovLHToRef;\n            }\n\n            getProjectionMatrix(\n                this.fov,\n                engine.getAspectRatio(this),\n                reverseDepth ? maxZ : this.minZ,\n                reverseDepth ? this.minZ : maxZ,\n                this._projectionMatrix,\n                this.fovMode === Camera.FOVMODE_VERTICAL_FIXED,\n                engine.isNDCHalfZRange,\n                this.projectionPlaneTilt,\n                reverseDepth\n            );\n        } else {\n            const halfWidth = engine.getRenderWidth() / 2.0;\n            const halfHeight = engine.getRenderHeight() / 2.0;\n            if (scene.useRightHandedSystem) {\n                if (this.oblique) {\n                    Matrix.ObliqueOffCenterRHToRef(\n                        this.orthoLeft ?? -halfWidth,\n                        this.orthoRight ?? halfWidth,\n                        this.orthoBottom ?? -halfHeight,\n                        this.orthoTop ?? halfHeight,\n                        reverseDepth ? maxZ : this.minZ,\n                        reverseDepth ? this.minZ : maxZ,\n                        this.oblique.length,\n                        this.oblique.angle,\n                        this._computeObliqueDistance(this.oblique.offset),\n                        this._projectionMatrix,\n                        engine.isNDCHalfZRange\n                    );\n                } else {\n                    Matrix.OrthoOffCenterRHToRef(\n                        this.orthoLeft ?? -halfWidth,\n                        this.orthoRight ?? halfWidth,\n                        this.orthoBottom ?? -halfHeight,\n                        this.orthoTop ?? halfHeight,\n                        reverseDepth ? maxZ : this.minZ,\n                        reverseDepth ? this.minZ : maxZ,\n                        this._projectionMatrix,\n                        engine.isNDCHalfZRange\n                    );\n                }\n            } else {\n                if (this.oblique) {\n                    Matrix.ObliqueOffCenterLHToRef(\n                        this.orthoLeft ?? -halfWidth,\n                        this.orthoRight ?? halfWidth,\n                        this.orthoBottom ?? -halfHeight,\n                        this.orthoTop ?? halfHeight,\n                        reverseDepth ? maxZ : this.minZ,\n                        reverseDepth ? this.minZ : maxZ,\n                        this.oblique.length,\n                        this.oblique.angle,\n                        this._computeObliqueDistance(this.oblique.offset),\n                        this._projectionMatrix,\n                        engine.isNDCHalfZRange\n                    );\n                } else {\n                    Matrix.OrthoOffCenterLHToRef(\n                        this.orthoLeft ?? -halfWidth,\n                        this.orthoRight ?? halfWidth,\n                        this.orthoBottom ?? -halfHeight,\n                        this.orthoTop ?? halfHeight,\n                        reverseDepth ? maxZ : this.minZ,\n                        reverseDepth ? this.minZ : maxZ,\n                        this._projectionMatrix,\n                        engine.isNDCHalfZRange\n                    );\n                }\n            }\n\n            this._cache.orthoLeft = this.orthoLeft;\n            this._cache.orthoRight = this.orthoRight;\n            this._cache.orthoBottom = this.orthoBottom;\n            this._cache.orthoTop = this.orthoTop;\n            this._cache.obliqueAngle = this.oblique?.angle;\n            this._cache.obliqueLength = this.oblique?.length;\n            this._cache.obliqueOffset = this.oblique?.offset;\n            this._cache.renderWidth = engine.getRenderWidth();\n            this._cache.renderHeight = engine.getRenderHeight();\n        }\n\n        this.onProjectionMatrixChangedObservable.notifyObservers(this);\n\n        return this._projectionMatrix;\n    }\n\n    /**\n     * Gets the transformation matrix (ie. the multiplication of view by projection matrices)\n     * @returns a Matrix\n     */\n    public getTransformationMatrix(): Matrix {\n        this._computedViewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);\n        return this._transformMatrix;\n    }\n\n    private _computeObliqueDistance(offset: number): number {\n        const arcRotateCamera = this as Camera as ArcRotateCamera;\n        const targetCamera = this as Camera as TargetCamera;\n        return (arcRotateCamera.radius || (targetCamera.target ? Vector3.Distance(this.position, targetCamera.target) : this.position.length())) + offset;\n    }\n\n    /** @internal */\n    public _updateFrustumPlanes(): void {\n        if (!this._refreshFrustumPlanes) {\n            return;\n        }\n\n        this.getTransformationMatrix();\n\n        if (!this._frustumPlanes) {\n            this._frustumPlanes = Frustum.GetPlanes(this._transformMatrix);\n        } else {\n            Frustum.GetPlanesToRef(this._transformMatrix, this._frustumPlanes);\n        }\n\n        this._refreshFrustumPlanes = false;\n    }\n\n    /**\n     * Checks if a cullable object (mesh...) is in the camera frustum\n     * This checks the bounding box center. See isCompletelyInFrustum for a full bounding check\n     * @param target The object to check\n     * @param checkRigCameras If the rig cameras should be checked (eg. with VR camera both eyes should be checked) (Default: false)\n     * @returns true if the object is in frustum otherwise false\n     */\n    public isInFrustum(target: ICullable, checkRigCameras = false): boolean {\n        this._updateFrustumPlanes();\n\n        if (checkRigCameras && this.rigCameras.length > 0) {\n            let result = false;\n            for (const cam of this.rigCameras) {\n                cam._updateFrustumPlanes();\n                result = result || target.isInFrustum(cam._frustumPlanes);\n            }\n            return result;\n        } else {\n            return target.isInFrustum(this._frustumPlanes);\n        }\n    }\n\n    /**\n     * Checks if a cullable object (mesh...) is in the camera frustum\n     * Unlike isInFrustum this checks the full bounding box\n     * @param target The object to check\n     * @returns true if the object is in frustum otherwise false\n     */\n    public isCompletelyInFrustum(target: ICullable): boolean {\n        this._updateFrustumPlanes();\n\n        return target.isCompletelyInFrustum(this._frustumPlanes);\n    }\n\n    // eslint-disable-next-line jsdoc/require-returns-check\n    /**\n     * Gets a ray in the forward direction from the camera.\n     * @param length Defines the length of the ray to create\n     * @param transform Defines the transform to apply to the ray, by default the world matrix is used to create a world space ray\n     * @param origin Defines the start point of the ray which defaults to the camera position\n     * @returns the forward ray\n     */\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    public getForwardRay(length = 100, transform?: Matrix, origin?: Vector3): Ray {\n        throw _WarnImport(\"Ray\");\n    }\n\n    // eslint-disable-next-line jsdoc/require-returns-check\n    /**\n     * Gets a ray in the forward direction from the camera.\n     * @param refRay the ray to (re)use when setting the values\n     * @param length Defines the length of the ray to create\n     * @param transform Defines the transform to apply to the ray, by default the world matrix is used to create a world space ray\n     * @param origin Defines the start point of the ray which defaults to the camera position\n     * @returns the forward ray\n     */\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    public getForwardRayToRef(refRay: Ray, length = 100, transform?: Matrix, origin?: Vector3): Ray {\n        throw _WarnImport(\"Ray\");\n    }\n\n    /**\n     * Releases resources associated with this node.\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\n     */\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\n        // Observables\n        this.onViewMatrixChangedObservable.clear();\n        this.onProjectionMatrixChangedObservable.clear();\n        this.onAfterCheckInputsObservable.clear();\n        this.onRestoreStateObservable.clear();\n\n        // Inputs\n        if (this.inputs) {\n            this.inputs.clear();\n        }\n\n        // Animations\n        this.getScene().stopAnimation(this);\n\n        // Remove from scene\n        this.getScene().removeCamera(this);\n        while (this._rigCameras.length > 0) {\n            const camera = this._rigCameras.pop();\n            if (camera) {\n                camera.dispose();\n            }\n        }\n\n        if (this._parentContainer) {\n            const index = this._parentContainer.cameras.indexOf(this);\n            if (index > -1) {\n                this._parentContainer.cameras.splice(index, 1);\n            }\n            this._parentContainer = null;\n        }\n\n        // Postprocesses\n        if (this._rigPostProcess) {\n            this._rigPostProcess.dispose(this);\n            this._rigPostProcess = null;\n            this._postProcesses.length = 0;\n        } else if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {\n            this._rigPostProcess = null;\n            this._postProcesses.length = 0;\n        } else {\n            let i = this._postProcesses.length;\n            while (--i >= 0) {\n                const postProcess = this._postProcesses[i];\n                if (postProcess) {\n                    postProcess.dispose(this);\n                }\n            }\n        }\n\n        // Render targets\n        let i = this.customRenderTargets.length;\n        while (--i >= 0) {\n            this.customRenderTargets[i].dispose();\n        }\n        this.customRenderTargets.length = 0;\n\n        // Active Meshes\n        this._activeMeshes.dispose();\n\n        this.getScene().getEngine().releaseRenderPassId(this.renderPassId);\n\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\n    }\n\n    /** @internal */\n    public _isLeftCamera = false;\n    /**\n     * Gets the left camera of a rig setup in case of Rigged Camera\n     */\n    public get isLeftCamera(): boolean {\n        return this._isLeftCamera;\n    }\n\n    /** @internal */\n    public _isRightCamera = false;\n    /**\n     * Gets the right camera of a rig setup in case of Rigged Camera\n     */\n    public get isRightCamera(): boolean {\n        return this._isRightCamera;\n    }\n\n    /**\n     * Gets the left camera of a rig setup in case of Rigged Camera\n     */\n    public get leftCamera(): Nullable<FreeCamera> {\n        if (this._rigCameras.length < 1) {\n            return null;\n        }\n        return <FreeCamera>this._rigCameras[0];\n    }\n\n    /**\n     * Gets the right camera of a rig setup in case of Rigged Camera\n     */\n    public get rightCamera(): Nullable<FreeCamera> {\n        if (this._rigCameras.length < 2) {\n            return null;\n        }\n        return <FreeCamera>this._rigCameras[1];\n    }\n\n    /**\n     * Gets the left camera target of a rig setup in case of Rigged Camera\n     * @returns the target position\n     */\n    public getLeftTarget(): Nullable<Vector3> {\n        if (this._rigCameras.length < 1) {\n            return null;\n        }\n        return (<TargetCamera>this._rigCameras[0]).getTarget();\n    }\n\n    /**\n     * Gets the right camera target of a rig setup in case of Rigged Camera\n     * @returns the target position\n     */\n    public getRightTarget(): Nullable<Vector3> {\n        if (this._rigCameras.length < 2) {\n            return null;\n        }\n        return (<TargetCamera>this._rigCameras[1]).getTarget();\n    }\n\n    /**\n     * @internal\n     */\n    public setCameraRigMode(mode: number, rigParams: any): void {\n        if (this.cameraRigMode === mode) {\n            return;\n        }\n\n        while (this._rigCameras.length > 0) {\n            const camera = this._rigCameras.pop();\n\n            if (camera) {\n                camera.dispose();\n            }\n        }\n        this.cameraRigMode = mode;\n        this._cameraRigParams = {};\n        //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target,\n        //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced\n        this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;\n        this._cameraRigParams.stereoHalfAngle = (this._cameraRigParams.interaxialDistance / 0.0637) * (Math.PI / 180);\n\n        // create the rig cameras, unless none\n        if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {\n            const leftCamera = this.createRigCamera(this.name + \"_L\", 0);\n            if (leftCamera) {\n                leftCamera._isLeftCamera = true;\n            }\n            const rightCamera = this.createRigCamera(this.name + \"_R\", 1);\n            if (rightCamera) {\n                rightCamera._isRightCamera = true;\n            }\n            if (leftCamera && rightCamera) {\n                this._rigCameras.push(leftCamera);\n                this._rigCameras.push(rightCamera);\n            }\n        }\n\n        this._setRigMode(rigParams);\n\n        this._cascadePostProcessesToRigCams();\n        this.update();\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    protected _setRigMode(rigParams: any) {\n        // no-op\n    }\n\n    /** @internal */\n    public _getVRProjectionMatrix(): Matrix {\n        Matrix.PerspectiveFovLHToRef(\n            this._cameraRigParams.vrMetrics.aspectRatioFov,\n            this._cameraRigParams.vrMetrics.aspectRatio,\n            this.minZ,\n            this.ignoreCameraMaxZ ? 0 : this.maxZ,\n            this._cameraRigParams.vrWorkMatrix,\n            true,\n            this.getEngine().isNDCHalfZRange\n        );\n        this._cameraRigParams.vrWorkMatrix.multiplyToRef(this._cameraRigParams.vrHMatrix, this._projectionMatrix);\n        return this._projectionMatrix;\n    }\n\n    /**\n     * @internal\n     */\n    public setCameraRigParameter(name: string, value: any) {\n        if (!this._cameraRigParams) {\n            this._cameraRigParams = {};\n        }\n        this._cameraRigParams[name] = value;\n        //provisionnally:\n        if (name === \"interaxialDistance\") {\n            this._cameraRigParams.stereoHalfAngle = (value / 0.0637) * (Math.PI / 180);\n        }\n    }\n\n    /**\n     * needs to be overridden by children so sub has required properties to be copied\n     * @internal\n     */\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    public createRigCamera(name: string, cameraIndex: number): Nullable<Camera> {\n        return null;\n    }\n\n    /**\n     * May need to be overridden by children\n     * @internal\n     */\n    public _updateRigCameras() {\n        for (let i = 0; i < this._rigCameras.length; i++) {\n            this._rigCameras[i].minZ = this.minZ;\n            this._rigCameras[i].maxZ = this.ignoreCameraMaxZ ? 0 : this.maxZ;\n            this._rigCameras[i].fov = this.fov;\n            this._rigCameras[i].upVector.copyFrom(this.upVector);\n        }\n\n        // only update viewport when ANAGLYPH\n        if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {\n            this._rigCameras[0].viewport = this._rigCameras[1].viewport = this.viewport;\n        }\n    }\n\n    /** @internal */\n    public _setupInputs() {}\n\n    /**\n     * Serialiaze the camera setup to a json representation\n     * @returns the JSON representation\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n        serializationObject.uniqueId = this.uniqueId;\n\n        // Type\n        serializationObject.type = this.getClassName();\n\n        // Parent\n        if (this.parent) {\n            this.parent._serializeAsParent(serializationObject);\n        }\n\n        if (this.inputs) {\n            this.inputs.serialize(serializationObject);\n        }\n        // Animations\n        SerializationHelper.AppendSerializedAnimations(this, serializationObject);\n        serializationObject.ranges = this.serializeAnimationRanges();\n\n        serializationObject.isEnabled = this.isEnabled();\n\n        return serializationObject;\n    }\n\n    /**\n     * Clones the current camera.\n     * @param name The cloned camera name\n     * @param newParent The cloned camera's new parent (none by default)\n     * @returns the cloned camera\n     */\n    public override clone(name: string, newParent: Nullable<Node> = null): Camera {\n        const camera = SerializationHelper.Clone(\n            Camera.GetConstructorFromName(this.getClassName(), name, this.getScene(), this.interaxialDistance, this.isStereoscopicSideBySide),\n            this\n        );\n        camera.name = name;\n        camera.parent = newParent;\n\n        this.onClonedObservable.notifyObservers(camera);\n\n        return camera;\n    }\n\n    /**\n     * Gets the direction of the camera relative to a given local axis.\n     * @param localAxis Defines the reference axis to provide a relative direction.\n     * @returns the direction\n     */\n    public getDirection(localAxis: DeepImmutable<Vector3>): Vector3 {\n        const result = Vector3.Zero();\n\n        this.getDirectionToRef(localAxis, result);\n\n        return result;\n    }\n\n    /**\n     * Returns the current camera absolute rotation\n     */\n    public get absoluteRotation(): Quaternion {\n        this.getWorldMatrix().decompose(undefined, this._absoluteRotation);\n\n        return this._absoluteRotation;\n    }\n\n    /**\n     * Gets the direction of the camera relative to a given local axis into a passed vector.\n     * @param localAxis Defines the reference axis to provide a relative direction.\n     * @param result Defines the vector to store the result in\n     */\n    public getDirectionToRef(localAxis: DeepImmutable<Vector3>, result: Vector3): void {\n        Vector3.TransformNormalToRef(localAxis, this.getWorldMatrix(), result);\n    }\n\n    /**\n     * Gets a camera constructor for a given camera type\n     * @param type The type of the camera to construct (should be equal to one of the camera class name)\n     * @param name The name of the camera the result will be able to instantiate\n     * @param scene The scene the result will construct the camera in\n     * @param interaxial_distance In case of stereoscopic setup, the distance between both eyes\n     * @param isStereoscopicSideBySide In case of stereoscopic setup, should the sereo be side b side\n     * @returns a factory method to construct the camera\n     */\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    static GetConstructorFromName(type: string, name: string, scene: Scene, interaxial_distance: number = 0, isStereoscopicSideBySide: boolean = true): () => Camera {\n        const constructorFunc = Node.Construct(type, name, scene, {\n            interaxial_distance: interaxial_distance,\n            isStereoscopicSideBySide: isStereoscopicSideBySide,\n        });\n\n        if (constructorFunc) {\n            return <() => Camera>constructorFunc;\n        }\n\n        // Default to universal camera\n        return () => Camera._CreateDefaultParsedCamera(name, scene);\n    }\n\n    /**\n     * Compute the world  matrix of the camera.\n     * @returns the camera world matrix\n     */\n    public override computeWorldMatrix(): Matrix {\n        return this.getWorldMatrix();\n    }\n\n    /** @internal */\n    public _calculateHandednessMultiplier(): number {\n        let handednessMultiplier = this.getScene().useRightHandedSystem ? -1 : 1;\n        if (this.parent && this.parent._getWorldMatrixDeterminant() < 0) {\n            handednessMultiplier *= -1;\n        }\n\n        return handednessMultiplier;\n    }\n}\n\n/**\n * Parse a JSON and creates the camera from the parsed information\n * @param parsedCamera The JSON to parse\n * @param scene The scene to instantiate the camera in\n * @returns the newly constructed camera\n */\nexport function CameraParse(parsedCamera: any, scene: Scene): Camera {\n    const type = parsedCamera.type;\n    const construct = Camera.GetConstructorFromName(type, parsedCamera.name, scene, parsedCamera.interaxial_distance, parsedCamera.isStereoscopicSideBySide);\n\n    const camera = SerializationHelper.Parse(construct, parsedCamera, scene);\n\n    // Parent\n    if (parsedCamera.parentId !== undefined) {\n        camera._waitingParentId = parsedCamera.parentId;\n    }\n\n    // Parent instance index\n    if (parsedCamera.parentInstanceIndex !== undefined) {\n        camera._waitingParentInstanceIndex = parsedCamera.parentInstanceIndex;\n    }\n\n    //If camera has an input manager, let it parse inputs settings\n    if (camera.inputs) {\n        camera.inputs.parse(parsedCamera);\n\n        camera._setupInputs();\n    }\n\n    if (parsedCamera.upVector) {\n        camera.upVector = Vector3.FromArray(parsedCamera.upVector); // need to force the upVector\n    }\n\n    if ((<any>camera).setPosition) {\n        // need to force position\n        camera.position.copyFromFloats(0, 0, 0);\n        (<any>camera).setPosition(Vector3.FromArray(parsedCamera.position));\n    }\n\n    // Target\n    if (parsedCamera.target) {\n        if ((<any>camera).setTarget) {\n            (<any>camera).setTarget(Vector3.FromArray(parsedCamera.target));\n        }\n    }\n\n    // Apply 3d rig, when found\n    if (parsedCamera.cameraRigMode) {\n        const rigParams = parsedCamera.interaxial_distance ? { interaxialDistance: parsedCamera.interaxial_distance } : {};\n        camera.setCameraRigMode(parsedCamera.cameraRigMode, rigParams);\n    }\n\n    // Animations\n    if (parsedCamera.animations) {\n        for (let animationIndex = 0; animationIndex < parsedCamera.animations.length; animationIndex++) {\n            const parsedAnimation = parsedCamera.animations[animationIndex];\n            const internalClass = GetClass(\"BABYLON.Animation\");\n            if (internalClass) {\n                camera.animations.push(internalClass.Parse(parsedAnimation));\n            }\n        }\n        Node.ParseAnimationRanges(camera, parsedCamera, scene);\n    }\n\n    if (parsedCamera.autoAnimate) {\n        scene.beginAnimation(camera, parsedCamera.autoAnimateFrom, parsedCamera.autoAnimateTo, parsedCamera.autoAnimateLoop, parsedCamera.autoAnimateSpeed || 1.0);\n    }\n\n    // Check if isEnabled is defined to be back compatible with prior serialized versions.\n    if (parsedCamera.isEnabled !== undefined) {\n        camera.setEnabled(parsedCamera.isEnabled);\n    }\n\n    return camera;\n}\n\nlet _CameraRegistered = false;\nexport function RegisterCamera(): void {\n    if (_CameraRegistered) {\n        return;\n    }\n    _CameraRegistered = true;\n    Camera.Parse = CameraParse;\n}\n","import { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * Class used to represent data loading progression\r\n */\r\nexport class SceneLoaderFlags {\r\n    // Flags\r\n    private static _ForceFullSceneLoadingForIncremental = false;\r\n    private static _ShowLoadingScreen = true;\r\n    private static _CleanBoneMatrixWeights = false;\r\n    private static _LoggingLevel = Constants.SCENELOADER_NO_LOGGING;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if entire scene must be loaded even if scene contains incremental data\r\n     */\r\n    public static get ForceFullSceneLoadingForIncremental() {\r\n        return SceneLoaderFlags._ForceFullSceneLoadingForIncremental;\r\n    }\r\n\r\n    public static set ForceFullSceneLoadingForIncremental(value: boolean) {\r\n        SceneLoaderFlags._ForceFullSceneLoadingForIncremental = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if loading screen must be displayed while loading a scene\r\n     */\r\n    public static get ShowLoadingScreen(): boolean {\r\n        return SceneLoaderFlags._ShowLoadingScreen;\r\n    }\r\n\r\n    public static set ShowLoadingScreen(value: boolean) {\r\n        SceneLoaderFlags._ShowLoadingScreen = value;\r\n    }\r\n\r\n    /**\r\n     * Defines the current logging level (while loading the scene)\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static get loggingLevel(): number {\r\n        return SceneLoaderFlags._LoggingLevel;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static set loggingLevel(value: number) {\r\n        SceneLoaderFlags._LoggingLevel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or set a boolean indicating if matrix weights must be cleaned upon loading\r\n     */\r\n    public static get CleanBoneMatrixWeights(): boolean {\r\n        return SceneLoaderFlags._CleanBoneMatrixWeights;\r\n    }\r\n\r\n    public static set CleanBoneMatrixWeights(value: boolean) {\r\n        SceneLoaderFlags._CleanBoneMatrixWeights = value;\r\n    }\r\n}\r\n","/**\r\n * Defines if the system should use OpenGL convention for UVs when creating geometry or loading .babylon files (false by default)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport let useOpenGLOrientationForUV = false;\r\n\r\n/**\r\n * Sets whether to use OpenGL convention for UVs\r\n * @param value the new value\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function setOpenGLOrientationForUV(value: boolean) {\r\n    useOpenGLOrientationForUV = value;\r\n}\r\n\r\n/**\r\n * Options used to control default behaviors regarding compatibility support\r\n * @deprecated please use named exports\r\n */\r\nexport const CompatibilityOptions = {\r\n    /* eslint-disable @typescript-eslint/naming-convention */\r\n    get UseOpenGLOrientationForUV() {\r\n        return useOpenGLOrientationForUV;\r\n    },\r\n    set UseOpenGLOrientationForUV(value) {\r\n        useOpenGLOrientationForUV = value;\r\n    },\r\n    /* eslint-enable @typescript-eslint/naming-convention */\r\n};\r\n","import { type Nullable, type FloatArray, type DataArray, type IndicesArray } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Vector2, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type IGetSetVerticesData, VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { VertexBuffer, type Buffer } from \"../Buffers/buffer.pure\";\r\nimport { SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { SceneLoaderFlags } from \"../Loading/sceneLoaderFlags\";\r\nimport { BoundingInfo } from \"../Culling/boundingInfo\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Tags } from \"../Misc/tags\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { extractMinAndMax } from \"../Maths/math.functions\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { useOpenGLOrientationForUV } from \"../Compat/compatibilityOptions\";\r\n\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine\";\r\nimport { CopyFloatData, GetTypedArrayData } from \"../Buffers/bufferUtils\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\n\r\n/**\r\n * Class used to store geometry data (vertex buffers + index buffer)\r\n */\r\nexport class Geometry implements IGetSetVerticesData {\r\n    // Members\r\n    /**\r\n     * Gets or sets the ID of the geometry\r\n     */\r\n    public id: string;\r\n    /**\r\n     * Gets or sets the unique ID of the geometry\r\n     */\r\n    public uniqueId: number;\r\n    /**\r\n     * Gets the delay loading state of the geometry (none by default which means not delayed)\r\n     */\r\n    public delayLoadState = Constants.DELAYLOADSTATE_NONE;\r\n    /**\r\n     * Gets the file containing the data to load when running in delay load state\r\n     */\r\n    public delayLoadingFile: Nullable<string>;\r\n    /**\r\n     * Callback called when the geometry is updated\r\n     */\r\n    public onGeometryUpdated: (geometry: Geometry, kind?: string) => void;\r\n\r\n    // Private\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n    private _meshes: Mesh[];\r\n    private _totalVertices = 0;\r\n    private _totalIndices?: number;\r\n    /** @internal */\r\n    public _loadedUniqueId: string;\r\n    /** @internal */\r\n    public _indices: IndicesArray;\r\n    /** @internal */\r\n    public _vertexBuffers: { [key: string]: VertexBuffer };\r\n    private _isDisposed = false;\r\n    private _extend: { minimum: Vector3; maximum: Vector3 } = {\r\n        minimum: new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE),\r\n        maximum: new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE),\r\n    };\r\n    private _boundingBias: Vector2;\r\n    /** @internal */\r\n    public _delayInfo: Array<string>;\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _indexBufferIsUpdatable = false;\r\n    /** @internal */\r\n    public _boundingInfo: Nullable<BoundingInfo>;\r\n    /** @internal */\r\n    public _delayLoadingFunction: Nullable<(any: any, geometry: Geometry) => void>;\r\n    /** @internal */\r\n    public _softwareSkinningFrameId: number;\r\n    private _vertexArrayObjects: { [key: string]: WebGLVertexArrayObject };\r\n    private _updatable: boolean;\r\n\r\n    // Cache\r\n    /** @internal */\r\n    public _positions: Nullable<Vector3[]>;\r\n    private _positionsCache: Vector3[] = [];\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /**\r\n     *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y\r\n     */\r\n    public get boundingBias(): Vector2 {\r\n        return this._boundingBias;\r\n    }\r\n\r\n    /**\r\n     *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y\r\n     */\r\n    public set boundingBias(value: Vector2) {\r\n        if (this._boundingBias) {\r\n            this._boundingBias.copyFrom(value);\r\n        } else {\r\n            this._boundingBias = value.clone();\r\n        }\r\n\r\n        this._updateBoundingInfo(true, null);\r\n    }\r\n\r\n    /**\r\n     * Static function used to attach a new empty geometry to a mesh\r\n     * @param mesh defines the mesh to attach the geometry to\r\n     * @returns the new Geometry\r\n     */\r\n    public static CreateGeometryForMesh(mesh: Mesh): Geometry {\r\n        const geometry = new Geometry(Geometry.RandomId(), mesh.getScene());\r\n\r\n        geometry.applyToMesh(mesh);\r\n\r\n        return geometry;\r\n    }\r\n\r\n    /** Get the list of meshes using this geometry */\r\n    public get meshes(): Mesh[] {\r\n        return this._meshes;\r\n    }\r\n\r\n    /**\r\n     * If set to true (false by default), the bounding info applied to the meshes sharing this geometry will be the bounding info defined at the class level\r\n     * and won't be computed based on the vertex positions (which is what we get when useBoundingInfoFromGeometry = false)\r\n     */\r\n    public useBoundingInfoFromGeometry = false;\r\n\r\n    /**\r\n     * Creates a new geometry\r\n     * @param id defines the unique ID\r\n     * @param scene defines the hosting scene\r\n     * @param vertexData defines the VertexData used to get geometry data\r\n     * @param updatable defines if geometry must be updatable (false by default)\r\n     * @param mesh defines the mesh that will be associated with the geometry\r\n     * @param totalVertices defines the total number of vertices (optional)\r\n     */\r\n    constructor(id: string, scene?: Scene, vertexData?: VertexData, updatable: boolean = false, mesh: Nullable<Mesh> = null, totalVertices: Nullable<number> = null) {\r\n        this._scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n        this.id = id;\r\n        this.uniqueId = this._scene.getUniqueId();\r\n        this._engine = this._scene.getEngine();\r\n        this._meshes = [];\r\n        //Init vertex buffer cache\r\n        this._vertexBuffers = {};\r\n        this._indices = [];\r\n        this._updatable = updatable;\r\n\r\n        if (totalVertices !== null) {\r\n            this._totalVertices = totalVertices;\r\n        }\r\n\r\n        // vertexData\r\n        if (vertexData) {\r\n            this.setAllVerticesData(vertexData, updatable);\r\n        } else if (totalVertices === null) {\r\n            this._totalVertices = 0;\r\n        }\r\n\r\n        if (this._engine.getCaps().vertexArrayObject) {\r\n            this._vertexArrayObjects = {};\r\n        }\r\n\r\n        // applyToMesh\r\n        if (mesh) {\r\n            this.applyToMesh(mesh);\r\n            mesh.computeWorldMatrix(true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the current extend of the geometry\r\n     */\r\n    public get extend(): { minimum: Vector3; maximum: Vector3 } {\r\n        return this._extend;\r\n    }\r\n\r\n    /**\r\n     * Gets the hosting scene\r\n     * @returns the hosting Scene\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets the hosting engine\r\n     * @returns the hosting Engine\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * Defines if the geometry is ready to use\r\n     * @returns true if the geometry is ready to be used\r\n     */\r\n    public isReady(): boolean {\r\n        return this.delayLoadState === Constants.DELAYLOADSTATE_LOADED || this.delayLoadState === Constants.DELAYLOADSTATE_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets a value indicating that the geometry should not be serialized\r\n     */\r\n    public get doNotSerialize(): boolean {\r\n        for (let index = 0; index < this._meshes.length; index++) {\r\n            if (!this._meshes[index].doNotSerialize) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        if (this._vertexArrayObjects) {\r\n            this._vertexArrayObjects = {};\r\n        }\r\n\r\n        // Index buffer\r\n        if (this._meshes.length !== 0 && this._indices) {\r\n            this._indexBuffer = this._engine.createIndexBuffer(this._indices, this._updatable, \"Geometry_\" + this.id + \"_IndexBuffer\");\r\n        }\r\n\r\n        // Vertex buffers\r\n        const buffers = new Set<Buffer>();\r\n        for (const key in this._vertexBuffers) {\r\n            buffers.add(this._vertexBuffers[key].getWrapperBuffer());\r\n        }\r\n\r\n        buffers.forEach((buffer) => {\r\n            buffer._rebuild();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Affects all geometry data in one call\r\n     * @param vertexData defines the geometry data\r\n     * @param updatable defines if the geometry must be flagged as updatable (false as default)\r\n     */\r\n    public setAllVerticesData(vertexData: VertexData, updatable?: boolean): void {\r\n        vertexData.applyToGeometry(this, updatable);\r\n        this._notifyUpdate();\r\n    }\r\n\r\n    /**\r\n     * Set specific vertex data\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param data defines the vertex data to use\r\n     * @param updatable defines if the vertex must be flagged as updatable (false as default)\r\n     * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified\r\n     */\r\n    public setVerticesData(kind: string, data: FloatArray, updatable: boolean = false, stride?: number): void {\r\n        if (updatable && Array.isArray(data)) {\r\n            // to avoid converting to Float32Array at each draw call in engine.updateDynamicVertexBuffer, we make the conversion a single time here\r\n            data = new Float32Array(data);\r\n        }\r\n        const buffer = new VertexBuffer(this._engine, data, kind, {\r\n            updatable,\r\n            postponeInternalCreation: this._meshes.length === 0,\r\n            stride,\r\n            label: \"Geometry_\" + this.id + \"_\" + kind,\r\n        });\r\n        this.setVerticesBuffer(buffer);\r\n    }\r\n\r\n    /**\r\n     * Removes a specific vertex data\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     */\r\n    public removeVerticesData(kind: string) {\r\n        if (this._vertexBuffers[kind]) {\r\n            this._vertexBuffers[kind].dispose();\r\n            delete this._vertexBuffers[kind];\r\n        }\r\n\r\n        if (this._vertexArrayObjects) {\r\n            this._disposeVertexArrayObjects();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data\r\n     * @param buffer defines the vertex buffer to use\r\n     * @param totalVertices defines the total number of vertices for position kind (could be null)\r\n     * @param disposeExistingBuffer disposes the existing buffer, if any (default: true)\r\n     */\r\n    public setVerticesBuffer(buffer: VertexBuffer, totalVertices: Nullable<number> = null, disposeExistingBuffer = true): void {\r\n        const kind = buffer.getKind();\r\n        if (this._vertexBuffers[kind] && disposeExistingBuffer) {\r\n            this._vertexBuffers[kind].dispose();\r\n        }\r\n\r\n        if (buffer._buffer && buffer._ownsBuffer) {\r\n            buffer._buffer._increaseReferences();\r\n        }\r\n\r\n        this._vertexBuffers[kind] = buffer;\r\n        const meshes = this._meshes;\r\n        const numOfMeshes = meshes.length;\r\n\r\n        if (kind === VertexBuffer.PositionKind) {\r\n            this._totalVertices = totalVertices ?? buffer._maxVerticesCount;\r\n\r\n            this._updateExtend(this.useBoundingInfoFromGeometry && this._boundingInfo ? null : buffer.getFloatData(this._totalVertices));\r\n            this._resetPointsArrayCache();\r\n\r\n            // this._extend can be empty if buffer.getFloatData(this._totalVertices) returned null\r\n            const minimum = (this._extend && this._extend.minimum) || new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n            const maximum = (this._extend && this._extend.maximum) || new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n\r\n            for (let index = 0; index < numOfMeshes; index++) {\r\n                const mesh = meshes[index];\r\n                mesh.buildBoundingInfo(minimum, maximum);\r\n                mesh._createGlobalSubMesh(mesh.isUnIndexed);\r\n                mesh.computeWorldMatrix(true);\r\n                mesh.synchronizeInstances();\r\n            }\r\n        }\r\n\r\n        this._notifyUpdate(kind);\r\n    }\r\n\r\n    /**\r\n     * Update a specific vertex buffer\r\n     * This function will directly update the underlying DataBuffer according to the passed numeric array or Float32Array\r\n     * It will do nothing if the buffer is not updatable\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param data defines the data to use\r\n     * @param offset defines the offset in the target buffer where to store the data\r\n     * @param useBytes set to true if the offset is in bytes\r\n     */\r\n    public updateVerticesDataDirectly(kind: string, data: DataArray, offset: number, useBytes: boolean = false): void {\r\n        const vertexBuffer = this.getVertexBuffer(kind);\r\n\r\n        if (!vertexBuffer) {\r\n            return;\r\n        }\r\n\r\n        vertexBuffer.updateDirectly(data, offset, useBytes);\r\n        this._notifyUpdate(kind);\r\n    }\r\n\r\n    /**\r\n     * Update a specific vertex buffer\r\n     * This function will create a new buffer if the current one is not updatable\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param data defines the data to use\r\n     * @param updateExtends defines if the geometry extends must be recomputed (false by default)\r\n     */\r\n    public updateVerticesData(kind: string, data: FloatArray, updateExtends: boolean = false): void {\r\n        const vertexBuffer = this.getVertexBuffer(kind);\r\n\r\n        if (!vertexBuffer) {\r\n            return;\r\n        }\r\n\r\n        vertexBuffer.update(data);\r\n\r\n        if (kind === VertexBuffer.PositionKind) {\r\n            this._updateBoundingInfo(updateExtends, data);\r\n        }\r\n        this._notifyUpdate(kind);\r\n    }\r\n\r\n    private _updateBoundingInfo(updateExtends: boolean, data: Nullable<FloatArray>) {\r\n        if (updateExtends) {\r\n            this._updateExtend(data);\r\n        }\r\n\r\n        this._resetPointsArrayCache();\r\n\r\n        if (updateExtends) {\r\n            const meshes = this._meshes;\r\n            for (const mesh of meshes) {\r\n                if (mesh.hasBoundingInfo) {\r\n                    mesh.getBoundingInfo().reConstruct(this._extend.minimum, this._extend.maximum);\r\n                } else {\r\n                    mesh.buildBoundingInfo(this._extend.minimum, this._extend.maximum);\r\n                }\r\n\r\n                const subMeshes = mesh.subMeshes;\r\n                for (const subMesh of subMeshes) {\r\n                    subMesh.refreshBoundingInfo();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bind(\r\n        effect: Nullable<Effect>,\r\n        indexToBind?: Nullable<DataBuffer>,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> },\r\n        overrideVertexArrayObjects?: { [key: string]: WebGLVertexArrayObject }\r\n    ): void {\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        if (indexToBind === undefined) {\r\n            indexToBind = this._indexBuffer;\r\n        }\r\n        const vbs = this.getVertexBuffers();\r\n\r\n        if (!vbs) {\r\n            return;\r\n        }\r\n\r\n        if (indexToBind != this._indexBuffer || (!this._vertexArrayObjects && !overrideVertexArrayObjects)) {\r\n            this._engine.bindBuffers(vbs, indexToBind, effect, overrideVertexBuffers);\r\n            return;\r\n        }\r\n\r\n        const vaos = overrideVertexArrayObjects ? overrideVertexArrayObjects : this._vertexArrayObjects;\r\n        const engine = this._engine as ThinEngine;\r\n\r\n        // Using VAO\r\n        if (!vaos[effect.key]) {\r\n            vaos[effect.key] = engine.recordVertexArrayObject(vbs, indexToBind, effect, overrideVertexBuffers);\r\n        }\r\n\r\n        engine.bindVertexArrayObject(vaos[effect.key], indexToBind);\r\n    }\r\n\r\n    /**\r\n     * Gets total number of vertices\r\n     * @returns the total number of vertices\r\n     */\r\n    public getTotalVertices(): number {\r\n        if (!this.isReady()) {\r\n            return 0;\r\n        }\r\n\r\n        return this._totalVertices;\r\n    }\r\n\r\n    /**\r\n     * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes\r\n     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n     * @returns a float array containing vertex data\r\n     */\r\n    public getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray> {\r\n        const vertexBuffer = this.getVertexBuffer(kind);\r\n        if (!vertexBuffer) {\r\n            return null;\r\n        }\r\n\r\n        return vertexBuffer.getFloatData(this._totalVertices, forceCopy || (copyWhenShared && this._meshes.length !== 1));\r\n    }\r\n\r\n    /**\r\n     * Copies the requested vertex data kind into the given vertex data map. Float data is constructed if the map doesn't have the data.\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @param vertexData defines the map that stores the resulting data\r\n     */\r\n    public copyVerticesData(kind: string, vertexData: { [kind: string]: Float32Array }): void {\r\n        const vertexBuffer = this.getVertexBuffer(kind);\r\n        if (!vertexBuffer) {\r\n            return;\r\n        }\r\n\r\n        vertexData[kind] ||= new Float32Array(this._totalVertices * vertexBuffer.getSize());\r\n        const data = vertexBuffer.getData();\r\n        if (data) {\r\n            CopyFloatData(\r\n                data,\r\n                vertexBuffer.getSize(),\r\n                vertexBuffer.type,\r\n                vertexBuffer.byteOffset,\r\n                vertexBuffer.byteStride,\r\n                vertexBuffer.normalized,\r\n                this._totalVertices,\r\n                vertexData[kind]\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a boolean defining if the vertex data for the requested `kind` is updatable\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @returns true if the vertex buffer with the specified kind is updatable\r\n     */\r\n    public isVertexBufferUpdatable(kind: string): boolean {\r\n        const vb = this._vertexBuffers[kind];\r\n\r\n        if (!vb) {\r\n            return false;\r\n        }\r\n\r\n        return vb.isUpdatable();\r\n    }\r\n\r\n    /**\r\n     * Gets a specific vertex buffer\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @returns a VertexBuffer\r\n     */\r\n    public getVertexBuffer(kind: string): Nullable<VertexBuffer> {\r\n        if (!this.isReady()) {\r\n            return null;\r\n        }\r\n        return this._vertexBuffers[kind];\r\n    }\r\n\r\n    /**\r\n     * Returns all vertex buffers\r\n     * @returns an object holding all vertex buffers indexed by kind\r\n     */\r\n    public getVertexBuffers(): Nullable<{ [key: string]: VertexBuffer }> {\r\n        if (!this.isReady()) {\r\n            return null;\r\n        }\r\n        return this._vertexBuffers;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if specific vertex buffer is present\r\n     * @param kind defines the data kind (Position, normal, etc...)\r\n     * @returns true if data is present\r\n     */\r\n    public isVerticesDataPresent(kind: string): boolean {\r\n        if (!this._vertexBuffers) {\r\n            if (this._delayInfo) {\r\n                return this._delayInfo.indexOf(kind) !== -1;\r\n            }\r\n            return false;\r\n        }\r\n        return this._vertexBuffers[kind] !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Gets a list of all attached data kinds (Position, normal, etc...)\r\n     * @returns a list of string containing all kinds\r\n     */\r\n    public getVerticesDataKinds(): string[] {\r\n        const result = [];\r\n        let kind;\r\n        if (!this._vertexBuffers && this._delayInfo) {\r\n            for (kind in this._delayInfo) {\r\n                result.push(kind);\r\n            }\r\n        } else {\r\n            for (kind in this._vertexBuffers) {\r\n                result.push(kind);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Update index buffer\r\n     * @param indices defines the indices to store in the index buffer\r\n     * @param offset defines the offset in the target buffer where to store the data\r\n     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)\r\n     */\r\n    public updateIndices(indices: IndicesArray, offset?: number, gpuMemoryOnly = false): void {\r\n        if (!this._indexBuffer) {\r\n            return;\r\n        }\r\n\r\n        if (!this._indexBufferIsUpdatable) {\r\n            this.setIndices(indices, null, true);\r\n        } else {\r\n            const needToUpdateSubMeshes = indices.length !== this._indices.length;\r\n\r\n            if (!gpuMemoryOnly) {\r\n                this._indices = indices.slice();\r\n            }\r\n            this._engine.updateDynamicIndexBuffer(this._indexBuffer, indices, offset);\r\n            if (needToUpdateSubMeshes) {\r\n                for (const mesh of this._meshes) {\r\n                    mesh._createGlobalSubMesh(true);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the index buffer for this geometry.\r\n     * @param indexBuffer Defines the index buffer to use for this geometry\r\n     * @param totalVertices Defines the total number of vertices used by the buffer\r\n     * @param totalIndices Defines the total number of indices in the index buffer\r\n     * @param is32Bits Defines if the indices are 32 bits. If null (default), the value is guessed from the number of vertices\r\n     */\r\n    public setIndexBuffer(indexBuffer: DataBuffer, totalVertices: number, totalIndices: number, is32Bits: Nullable<boolean> = null): void {\r\n        this._indices = [];\r\n        this._indexBufferIsUpdatable = false;\r\n        this._indexBuffer = indexBuffer;\r\n        this._totalVertices = totalVertices;\r\n        this._totalIndices = totalIndices;\r\n\r\n        if (is32Bits === null) {\r\n            indexBuffer.is32Bits = totalVertices > 65535;\r\n        } else {\r\n            indexBuffer.is32Bits = is32Bits;\r\n        }\r\n\r\n        for (const mesh of this._meshes) {\r\n            mesh._createGlobalSubMesh(true);\r\n            mesh.synchronizeInstances();\r\n        }\r\n\r\n        this._notifyUpdate();\r\n    }\r\n\r\n    /**\r\n     * Creates a new index buffer\r\n     * @param indices defines the indices to store in the index buffer\r\n     * @param totalVertices defines the total number of vertices (could be null)\r\n     * @param updatable defines if the index buffer must be flagged as updatable (false by default)\r\n     * @param dontForceSubMeshRecreation defines a boolean indicating that we don't want to force the recreation of sub-meshes if we don't have to (false by default)\r\n     */\r\n    public setIndices(indices: IndicesArray, totalVertices: Nullable<number> = null, updatable: boolean = false, dontForceSubMeshRecreation = false): void {\r\n        if (this._indexBuffer) {\r\n            this._engine._releaseBuffer(this._indexBuffer);\r\n        }\r\n\r\n        this._indices = indices;\r\n        this._indexBufferIsUpdatable = updatable;\r\n        if (this._meshes.length !== 0 && this._indices) {\r\n            this._indexBuffer = this._engine.createIndexBuffer(this._indices, updatable, \"Geometry_\" + this.id + \"_IndexBuffer\");\r\n        }\r\n\r\n        if (totalVertices != undefined) {\r\n            // including null and undefined\r\n            this._totalVertices = totalVertices;\r\n        }\r\n\r\n        for (const mesh of this._meshes) {\r\n            mesh._createGlobalSubMesh(!dontForceSubMeshRecreation);\r\n            mesh.synchronizeInstances();\r\n        }\r\n\r\n        this._notifyUpdate();\r\n    }\r\n\r\n    /**\r\n     * Return the total number of indices\r\n     * @returns the total number of indices\r\n     */\r\n    public getTotalIndices(): number {\r\n        if (!this.isReady()) {\r\n            return 0;\r\n        }\r\n        return this._totalIndices !== undefined ? this._totalIndices : this._indices.length;\r\n    }\r\n\r\n    /**\r\n     * Gets the index buffer array\r\n     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes\r\n     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n     * @returns the index buffer array\r\n     */\r\n    public getIndices(copyWhenShared?: boolean, forceCopy?: boolean): Nullable<IndicesArray> {\r\n        if (!this.isReady()) {\r\n            return null;\r\n        }\r\n        const orig = this._indices;\r\n        if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {\r\n            return orig;\r\n        } else {\r\n            return orig.slice();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the index buffer\r\n     * @returns the index buffer\r\n     */\r\n    public getIndexBuffer(): Nullable<DataBuffer> {\r\n        if (!this.isReady()) {\r\n            return null;\r\n        }\r\n        return this._indexBuffer;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseVertexArrayObject(effect: Nullable<Effect> = null) {\r\n        if (!effect || !this._vertexArrayObjects) {\r\n            return;\r\n        }\r\n\r\n        if (this._vertexArrayObjects[effect.key]) {\r\n            (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObjects[effect.key]);\r\n            delete this._vertexArrayObjects[effect.key];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release the associated resources for a specific mesh\r\n     * @param mesh defines the source mesh\r\n     * @param shouldDispose defines if the geometry must be disposed if there is no more mesh pointing to it\r\n     */\r\n    public releaseForMesh(mesh: Mesh, shouldDispose?: boolean): void {\r\n        const meshes = this._meshes;\r\n        const index = meshes.indexOf(mesh);\r\n\r\n        if (index === -1) {\r\n            return;\r\n        }\r\n\r\n        meshes.splice(index, 1);\r\n\r\n        if (this._vertexArrayObjects) {\r\n            mesh._invalidateInstanceVertexArrayObject();\r\n        }\r\n\r\n        mesh._geometry = null;\r\n\r\n        if (meshes.length === 0 && shouldDispose) {\r\n            this.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Apply current geometry to a given mesh\r\n     * @param mesh defines the mesh to apply geometry to\r\n     */\r\n    public applyToMesh(mesh: Mesh): void {\r\n        if (mesh._geometry === this) {\r\n            return;\r\n        }\r\n\r\n        const previousGeometry = mesh._geometry;\r\n        if (previousGeometry) {\r\n            previousGeometry.releaseForMesh(mesh);\r\n        }\r\n\r\n        if (this._vertexArrayObjects) {\r\n            mesh._invalidateInstanceVertexArrayObject();\r\n        }\r\n\r\n        const meshes = this._meshes;\r\n\r\n        // must be done before setting vertexBuffers because of mesh._createGlobalSubMesh()\r\n        mesh._geometry = this;\r\n        mesh._internalAbstractMeshDataInfo._positions = null;\r\n\r\n        this._scene.pushGeometry(this);\r\n\r\n        meshes.push(mesh);\r\n\r\n        if (this.isReady()) {\r\n            this._applyToMesh(mesh);\r\n        } else if (this._boundingInfo) {\r\n            mesh.setBoundingInfo(this._boundingInfo);\r\n        }\r\n    }\r\n\r\n    private _updateExtend(data: Nullable<FloatArray> = null) {\r\n        if (this.useBoundingInfoFromGeometry && this._boundingInfo) {\r\n            this._extend = {\r\n                minimum: this._boundingInfo.minimum.clone(),\r\n                maximum: this._boundingInfo.maximum.clone(),\r\n            };\r\n        } else {\r\n            if (!data) {\r\n                data = this.getVerticesData(VertexBuffer.PositionKind)!;\r\n                // This can happen if the buffer comes from a Hardware Buffer where\r\n                // The data have not been uploaded by Babylon. (ex: Compute Shaders and Storage Buffers)\r\n                if (!data) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            this._extend = extractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);\r\n        }\r\n    }\r\n\r\n    private _applyToMesh(mesh: Mesh): void {\r\n        // vertexBuffers\r\n        for (const kind in this._vertexBuffers) {\r\n            const vertexBuffer = this._vertexBuffers[kind];\r\n            if (!vertexBuffer._buffer.getBuffer()) {\r\n                vertexBuffer.create();\r\n            }\r\n\r\n            if (kind === VertexBuffer.PositionKind) {\r\n                if (!this._extend) {\r\n                    this._updateExtend();\r\n                }\r\n                mesh.buildBoundingInfo(this._extend.minimum, this._extend.maximum);\r\n\r\n                mesh._createGlobalSubMesh(mesh.isUnIndexed);\r\n\r\n                //bounding info was just created again, world matrix should be applied again.\r\n                mesh._updateBoundingInfo();\r\n            }\r\n        }\r\n\r\n        // indexBuffer\r\n        if (!this._indexBuffer && this._indices && this._indices.length > 0) {\r\n            this._indexBuffer = this._engine.createIndexBuffer(this._indices, this._updatable, \"Geometry_\" + this.id + \"_IndexBuffer\");\r\n        }\r\n\r\n        // morphTargets\r\n        mesh._syncGeometryWithMorphTargetManager();\r\n\r\n        // instances\r\n        mesh.synchronizeInstances();\r\n    }\r\n\r\n    private _notifyUpdate(kind?: string) {\r\n        if (this.onGeometryUpdated) {\r\n            this.onGeometryUpdated(this, kind);\r\n        }\r\n\r\n        if (this._vertexArrayObjects) {\r\n            this._disposeVertexArrayObjects();\r\n        }\r\n\r\n        for (const mesh of this._meshes) {\r\n            mesh._markSubMeshesAsAttributesDirty();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Load the geometry if it was flagged as delay loaded\r\n     * @param scene defines the hosting scene\r\n     * @param onLoaded defines a callback called when the geometry is loaded\r\n     */\r\n    public load(scene: Scene, onLoaded?: () => void): void {\r\n        if (this.delayLoadState === Constants.DELAYLOADSTATE_LOADING) {\r\n            return;\r\n        }\r\n\r\n        if (this.isReady()) {\r\n            if (onLoaded) {\r\n                onLoaded();\r\n            }\r\n            return;\r\n        }\r\n\r\n        this.delayLoadState = Constants.DELAYLOADSTATE_LOADING;\r\n\r\n        this._queueLoad(scene, onLoaded);\r\n    }\r\n\r\n    private _queueLoad(scene: Scene, onLoaded?: () => void): void {\r\n        if (!this.delayLoadingFile) {\r\n            return;\r\n        }\r\n\r\n        scene.addPendingData(this);\r\n        void (async () => {\r\n            try {\r\n                const data = await scene._loadDelayedFileAsync(this.delayLoadingFile!, false, true);\r\n\r\n                if (!this._delayLoadingFunction) {\r\n                    // The geometry was disposed while the load was in flight; still release the pending data so the scene can become ready.\r\n                    scene.removePendingData(this);\r\n                    return;\r\n                }\r\n\r\n                this._delayLoadingFunction(JSON.parse(data as string), this);\r\n\r\n                this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\r\n                this._delayInfo = [];\r\n\r\n                scene.removePendingData(this);\r\n\r\n                const meshes = this._meshes;\r\n                const numOfMeshes = meshes.length;\r\n                for (let index = 0; index < numOfMeshes; index++) {\r\n                    this._applyToMesh(meshes[index]);\r\n                }\r\n\r\n                if (onLoaded) {\r\n                    onLoaded();\r\n                }\r\n            } catch (error) {\r\n                // Remove the pending data so the scene can still become ready.\r\n                // The state is intentionally left as LOADING so a persistently failing file is not re-fetched every frame.\r\n                scene.removePendingData(this);\r\n                // Don't log when the scene is being disposed: in-flight requests are aborted as part of normal teardown.\r\n                if (!scene.isDisposed) {\r\n                    Logger.Error(`Unable to delay load geometry \"${this.id}\" from \"${this.delayLoadingFile}\": ${error}`);\r\n                }\r\n            }\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * Invert the geometry to move from a right handed system to a left handed one.\r\n     */\r\n    public toLeftHanded(): void {\r\n        // Flip faces\r\n        const tIndices = this.getIndices(false);\r\n        if (tIndices != null && tIndices.length > 0) {\r\n            for (let i = 0; i < tIndices.length; i += 3) {\r\n                const tTemp = tIndices[i + 0];\r\n                tIndices[i + 0] = tIndices[i + 2];\r\n                tIndices[i + 2] = tTemp;\r\n            }\r\n            this.setIndices(tIndices);\r\n        }\r\n\r\n        // Negate position.z\r\n        const tPositions = this.getVerticesData(VertexBuffer.PositionKind, false);\r\n        if (tPositions != null && tPositions.length > 0) {\r\n            for (let i = 0; i < tPositions.length; i += 3) {\r\n                tPositions[i + 2] = -tPositions[i + 2];\r\n            }\r\n            this.setVerticesData(VertexBuffer.PositionKind, tPositions, false);\r\n        }\r\n\r\n        // Negate normal.z\r\n        const tNormals = this.getVerticesData(VertexBuffer.NormalKind, false);\r\n        if (tNormals != null && tNormals.length > 0) {\r\n            for (let i = 0; i < tNormals.length; i += 3) {\r\n                tNormals[i + 2] = -tNormals[i + 2];\r\n            }\r\n            this.setVerticesData(VertexBuffer.NormalKind, tNormals, false);\r\n        }\r\n    }\r\n\r\n    // Cache\r\n    /** @internal */\r\n    public _resetPointsArrayCache(): void {\r\n        this._positions = null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _generatePointsArray(): boolean {\r\n        if (this._positions) {\r\n            return true;\r\n        }\r\n\r\n        const data = this.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        if (!data || data.length === 0) {\r\n            return false;\r\n        }\r\n\r\n        for (let index = this._positionsCache.length * 3, arrayIdx = this._positionsCache.length; index < data.length; index += 3, ++arrayIdx) {\r\n            this._positionsCache[arrayIdx] = Vector3.FromArray(data, index);\r\n        }\r\n\r\n        for (let index = 0, arrayIdx = 0; index < data.length; index += 3, ++arrayIdx) {\r\n            this._positionsCache[arrayIdx].set(data[0 + index], data[1 + index], data[2 + index]);\r\n        }\r\n\r\n        // just in case the number of positions was reduced, splice the array\r\n        this._positionsCache.length = data.length / 3;\r\n\r\n        this._positions = this._positionsCache;\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets a value indicating if the geometry is disposed\r\n     * @returns true if the geometry was disposed\r\n     */\r\n    public isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    private _disposeVertexArrayObjects(): void {\r\n        if (this._vertexArrayObjects) {\r\n            for (const kind in this._vertexArrayObjects) {\r\n                (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObjects[kind]);\r\n            }\r\n            this._vertexArrayObjects = {}; // Will trigger a rebuild of the VAO if supported\r\n\r\n            const meshes = this._meshes;\r\n            const numOfMeshes = meshes.length;\r\n            for (let index = 0; index < numOfMeshes; index++) {\r\n                meshes[index]._invalidateInstanceVertexArrayObject();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Free all associated resources\r\n     */\r\n    public dispose(): void {\r\n        const meshes = this._meshes;\r\n        const numOfMeshes = meshes.length;\r\n        let index: number;\r\n        for (index = 0; index < numOfMeshes; index++) {\r\n            this.releaseForMesh(meshes[index]);\r\n        }\r\n        this._meshes.length = 0;\r\n\r\n        this._disposeVertexArrayObjects();\r\n\r\n        for (const kind in this._vertexBuffers) {\r\n            this._vertexBuffers[kind].dispose();\r\n        }\r\n        this._vertexBuffers = {};\r\n        this._totalVertices = 0;\r\n\r\n        if (this._indexBuffer) {\r\n            this._engine._releaseBuffer(this._indexBuffer);\r\n        }\r\n        this._indexBuffer = null;\r\n        this._indices = [];\r\n\r\n        this.delayLoadState = Constants.DELAYLOADSTATE_NONE;\r\n        this.delayLoadingFile = null;\r\n        this._delayLoadingFunction = null;\r\n        this._delayInfo = [];\r\n\r\n        this._boundingInfo = null;\r\n\r\n        this._scene.removeGeometry(this);\r\n        if (this._parentContainer) {\r\n            const index = this._parentContainer.geometries.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.geometries.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    /**\r\n     * Clone the current geometry into a new geometry\r\n     * @param id defines the unique ID of the new geometry\r\n     * @returns a new geometry object\r\n     */\r\n    public copy(id: string): Geometry {\r\n        const geometry = new Geometry(id, this._scene);\r\n\r\n        const indices = this.getIndices(undefined, true);\r\n        if (indices) {\r\n            geometry.setIndices(indices);\r\n        }\r\n\r\n        let updatable = false;\r\n        let kind;\r\n        for (kind in this._vertexBuffers) {\r\n            const vb = this.getVertexBuffer(kind)!;\r\n            const bufferData = vb.getData();\r\n            if (!bufferData) {\r\n                continue;\r\n            }\r\n\r\n            const isUpdatable = vb.isUpdatable();\r\n            const size = vb.getSize();\r\n            const { type, byteOffset, byteStride, normalized } = vb;\r\n            updatable = updatable || isUpdatable;\r\n\r\n            let numElements = this._totalVertices;\r\n            if (vb.getIsInstanced()) {\r\n                // Do our best with the data we have to find a number of instances when the vertex buffer is instanced...\r\n                let bufferDataByteSize: number;\r\n                if (bufferData instanceof Array) {\r\n                    bufferDataByteSize = bufferData.length * 4;\r\n                } else {\r\n                    bufferDataByteSize = bufferData.byteLength;\r\n                }\r\n                numElements = bufferDataByteSize / byteStride;\r\n            }\r\n            const copy = GetTypedArrayData(bufferData, size, type, byteOffset, byteStride, numElements, true);\r\n            const newVb = new VertexBuffer(this._engine, copy, kind, {\r\n                updatable: isUpdatable,\r\n                useBytes: false,\r\n                stride: size, // Copy is tightly-packed, so stride = size\r\n                size: size, // Component size stays the same\r\n                offset: 0, // Copy starts at beginning of its own buffer\r\n                type: type,\r\n                normalized: normalized,\r\n                takeBufferOwnership: true,\r\n                instanced: vb.getIsInstanced(),\r\n            });\r\n\r\n            geometry.setVerticesBuffer(newVb, numElements);\r\n        }\r\n\r\n        geometry._updatable = updatable;\r\n\r\n        geometry.delayLoadState = this.delayLoadState;\r\n        geometry.delayLoadingFile = this.delayLoadingFile;\r\n        geometry._delayLoadingFunction = this._delayLoadingFunction;\r\n\r\n        for (kind in this._delayInfo) {\r\n            geometry._delayInfo = geometry._delayInfo || [];\r\n            geometry._delayInfo.push(kind);\r\n        }\r\n\r\n        // Bounding info\r\n        geometry._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);\r\n\r\n        return geometry;\r\n    }\r\n\r\n    /**\r\n     * Serialize the current geometry info (and not the vertices data) into a JSON object\r\n     * @returns a JSON representation of the current geometry data (without the vertices data)\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.id = this.id;\r\n        serializationObject.uniqueId = this.uniqueId;\r\n        serializationObject.updatable = this._updatable;\r\n\r\n        if (Tags && Tags.HasTags(this)) {\r\n            serializationObject.tags = Tags.GetTags(this);\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    private _toNumberArray(origin: Nullable<Float32Array | IndicesArray>): number[] {\r\n        if (Array.isArray(origin)) {\r\n            return origin;\r\n        } else {\r\n            return Array.prototype.slice.call(origin);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release any memory retained by the cached data on the Geometry.\r\n     *\r\n     * Call this function to reduce memory footprint of the mesh.\r\n     * Vertex buffers will not store CPU data anymore (this will prevent picking, collisions or physics to work correctly)\r\n     */\r\n    public clearCachedData(): void {\r\n        this._totalIndices = this._indices.length; // save the current value so that getTotalIndices can still work\r\n        this._indices = [];\r\n        this._resetPointsArrayCache();\r\n\r\n        for (const vbName in this._vertexBuffers) {\r\n            if (!Object.prototype.hasOwnProperty.call(this._vertexBuffers, vbName)) {\r\n                continue;\r\n            }\r\n            this._vertexBuffers[vbName]._buffer._data = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serialize all vertices data into a JSON object\r\n     * @returns a JSON representation of the current geometry data\r\n     */\r\n    public serializeVerticeData(): any {\r\n        const serializationObject = this.serialize();\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.PositionKind)) {\r\n            serializationObject.positions = this._toNumberArray(this.getVerticesData(VertexBuffer.PositionKind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.PositionKind)) {\r\n                serializationObject.positionsUpdatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            serializationObject.normals = this._toNumberArray(this.getVerticesData(VertexBuffer.NormalKind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.NormalKind)) {\r\n                serializationObject.normalsUpdatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n            serializationObject.tangents = this._toNumberArray(this.getVerticesData(VertexBuffer.TangentKind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.TangentKind)) {\r\n                serializationObject.tangentsUpdatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n            serializationObject.uvs = this._toNumberArray(this.getVerticesData(VertexBuffer.UVKind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.UVKind)) {\r\n                serializationObject.uvsUpdatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n            serializationObject.uvs2 = this._toNumberArray(this.getVerticesData(VertexBuffer.UV2Kind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.UV2Kind)) {\r\n                serializationObject.uvs2Updatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.UV3Kind)) {\r\n            serializationObject.uvs3 = this._toNumberArray(this.getVerticesData(VertexBuffer.UV3Kind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.UV3Kind)) {\r\n                serializationObject.uvs3Updatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.UV4Kind)) {\r\n            serializationObject.uvs4 = this._toNumberArray(this.getVerticesData(VertexBuffer.UV4Kind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.UV4Kind)) {\r\n                serializationObject.uvs4Updatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.UV5Kind)) {\r\n            serializationObject.uvs5 = this._toNumberArray(this.getVerticesData(VertexBuffer.UV5Kind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.UV5Kind)) {\r\n                serializationObject.uvs5Updatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.UV6Kind)) {\r\n            serializationObject.uvs6 = this._toNumberArray(this.getVerticesData(VertexBuffer.UV6Kind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.UV6Kind)) {\r\n                serializationObject.uvs6Updatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.ColorKind)) {\r\n            serializationObject.colors = this._toNumberArray(this.getVerticesData(VertexBuffer.ColorKind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.ColorKind)) {\r\n                serializationObject.colorsUpdatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.MatricesIndicesKind)) {\r\n            serializationObject.matricesIndices = this._toNumberArray(this.getVerticesData(VertexBuffer.MatricesIndicesKind));\r\n            serializationObject.matricesIndicesExpanded = true;\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.MatricesIndicesKind)) {\r\n                serializationObject.matricesIndicesUpdatable = true;\r\n            }\r\n        }\r\n\r\n        if (this.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind)) {\r\n            serializationObject.matricesWeights = this._toNumberArray(this.getVerticesData(VertexBuffer.MatricesWeightsKind));\r\n            if (this.isVertexBufferUpdatable(VertexBuffer.MatricesWeightsKind)) {\r\n                serializationObject.matricesWeightsUpdatable = true;\r\n            }\r\n        }\r\n\r\n        serializationObject.indices = this._toNumberArray(this.getIndices());\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Extracts a clone of a mesh geometry\r\n     * @param mesh defines the source mesh\r\n     * @param id defines the unique ID of the new geometry object\r\n     * @returns the new geometry object\r\n     */\r\n    public static ExtractFromMesh(mesh: Mesh, id: string): Nullable<Geometry> {\r\n        const geometry = mesh._geometry;\r\n\r\n        if (!geometry) {\r\n            return null;\r\n        }\r\n\r\n        return geometry.copy(id);\r\n    }\r\n\r\n    /**\r\n     * You should now use Tools.RandomId(), this method is still here for legacy reasons.\r\n     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523\r\n     * Be aware Math.random() could cause collisions, but:\r\n     * \"All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide\"\r\n     * @returns a string containing a new GUID\r\n     */\r\n    public static RandomId(): string {\r\n        return Tools.RandomId();\r\n    }\r\n\r\n    private static _GetGeometryByLoadedUniqueId(uniqueId: string, scene: Scene) {\r\n        for (let index = 0; index < scene.geometries.length; index++) {\r\n            if (scene.geometries[index]._loadedUniqueId === uniqueId) {\r\n                return scene.geometries[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _ImportGeometry(parsedGeometry: any, mesh: Mesh): void {\r\n        const scene = mesh.getScene();\r\n\r\n        // Geometry\r\n        const geometryUniqueId = parsedGeometry.geometryUniqueId;\r\n        const geometryId = parsedGeometry.geometryId;\r\n        if (geometryUniqueId || geometryId) {\r\n            const geometry = geometryUniqueId ? this._GetGeometryByLoadedUniqueId(geometryUniqueId, scene) : scene.getGeometryById(geometryId);\r\n            if (geometry) {\r\n                geometry.applyToMesh(mesh);\r\n            }\r\n        } else if (parsedGeometry instanceof ArrayBuffer) {\r\n            const binaryInfo = mesh._binaryInfo;\r\n\r\n            if (binaryInfo.positionsAttrDesc && binaryInfo.positionsAttrDesc.count > 0) {\r\n                const positionsData = new Float32Array(parsedGeometry, binaryInfo.positionsAttrDesc.offset, binaryInfo.positionsAttrDesc.count);\r\n                mesh.setVerticesData(VertexBuffer.PositionKind, positionsData, false);\r\n            }\r\n\r\n            if (binaryInfo.normalsAttrDesc && binaryInfo.normalsAttrDesc.count > 0) {\r\n                const normalsData = new Float32Array(parsedGeometry, binaryInfo.normalsAttrDesc.offset, binaryInfo.normalsAttrDesc.count);\r\n                mesh.setVerticesData(VertexBuffer.NormalKind, normalsData, false);\r\n            }\r\n\r\n            if (binaryInfo.tangetsAttrDesc && binaryInfo.tangetsAttrDesc.count > 0) {\r\n                const tangentsData = new Float32Array(parsedGeometry, binaryInfo.tangetsAttrDesc.offset, binaryInfo.tangetsAttrDesc.count);\r\n                mesh.setVerticesData(VertexBuffer.TangentKind, tangentsData, false);\r\n            }\r\n\r\n            if (binaryInfo.uvsAttrDesc && binaryInfo.uvsAttrDesc.count > 0) {\r\n                const uvsData = new Float32Array(parsedGeometry, binaryInfo.uvsAttrDesc.offset, binaryInfo.uvsAttrDesc.count);\r\n                if (useOpenGLOrientationForUV) {\r\n                    for (let index = 1; index < uvsData.length; index += 2) {\r\n                        uvsData[index] = 1 - uvsData[index];\r\n                    }\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.UVKind, uvsData, false);\r\n            }\r\n\r\n            if (binaryInfo.uvs2AttrDesc && binaryInfo.uvs2AttrDesc.count > 0) {\r\n                const uvs2Data = new Float32Array(parsedGeometry, binaryInfo.uvs2AttrDesc.offset, binaryInfo.uvs2AttrDesc.count);\r\n                if (useOpenGLOrientationForUV) {\r\n                    for (let index = 1; index < uvs2Data.length; index += 2) {\r\n                        uvs2Data[index] = 1 - uvs2Data[index];\r\n                    }\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.UV2Kind, uvs2Data, false);\r\n            }\r\n\r\n            if (binaryInfo.uvs3AttrDesc && binaryInfo.uvs3AttrDesc.count > 0) {\r\n                const uvs3Data = new Float32Array(parsedGeometry, binaryInfo.uvs3AttrDesc.offset, binaryInfo.uvs3AttrDesc.count);\r\n                if (useOpenGLOrientationForUV) {\r\n                    for (let index = 1; index < uvs3Data.length; index += 2) {\r\n                        uvs3Data[index] = 1 - uvs3Data[index];\r\n                    }\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.UV3Kind, uvs3Data, false);\r\n            }\r\n\r\n            if (binaryInfo.uvs4AttrDesc && binaryInfo.uvs4AttrDesc.count > 0) {\r\n                const uvs4Data = new Float32Array(parsedGeometry, binaryInfo.uvs4AttrDesc.offset, binaryInfo.uvs4AttrDesc.count);\r\n                if (useOpenGLOrientationForUV) {\r\n                    for (let index = 1; index < uvs4Data.length; index += 2) {\r\n                        uvs4Data[index] = 1 - uvs4Data[index];\r\n                    }\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.UV4Kind, uvs4Data, false);\r\n            }\r\n\r\n            if (binaryInfo.uvs5AttrDesc && binaryInfo.uvs5AttrDesc.count > 0) {\r\n                const uvs5Data = new Float32Array(parsedGeometry, binaryInfo.uvs5AttrDesc.offset, binaryInfo.uvs5AttrDesc.count);\r\n                if (useOpenGLOrientationForUV) {\r\n                    for (let index = 1; index < uvs5Data.length; index += 2) {\r\n                        uvs5Data[index] = 1 - uvs5Data[index];\r\n                    }\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.UV5Kind, uvs5Data, false);\r\n            }\r\n\r\n            if (binaryInfo.uvs6AttrDesc && binaryInfo.uvs6AttrDesc.count > 0) {\r\n                const uvs6Data = new Float32Array(parsedGeometry, binaryInfo.uvs6AttrDesc.offset, binaryInfo.uvs6AttrDesc.count);\r\n                if (useOpenGLOrientationForUV) {\r\n                    for (let index = 1; index < uvs6Data.length; index += 2) {\r\n                        uvs6Data[index] = 1 - uvs6Data[index];\r\n                    }\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.UV6Kind, uvs6Data, false);\r\n            }\r\n\r\n            if (binaryInfo.colorsAttrDesc && binaryInfo.colorsAttrDesc.count > 0) {\r\n                const colorsData = new Float32Array(parsedGeometry, binaryInfo.colorsAttrDesc.offset, binaryInfo.colorsAttrDesc.count);\r\n                mesh.setVerticesData(VertexBuffer.ColorKind, colorsData, false, binaryInfo.colorsAttrDesc.stride);\r\n            }\r\n\r\n            if (binaryInfo.matricesIndicesAttrDesc && binaryInfo.matricesIndicesAttrDesc.count > 0) {\r\n                const matricesIndicesData = new Int32Array(parsedGeometry, binaryInfo.matricesIndicesAttrDesc.offset, binaryInfo.matricesIndicesAttrDesc.count);\r\n                const floatIndices = [];\r\n                for (let i = 0; i < matricesIndicesData.length; i++) {\r\n                    const index = matricesIndicesData[i];\r\n                    floatIndices.push(index & 0x000000ff);\r\n                    floatIndices.push((index & 0x0000ff00) >> 8);\r\n                    floatIndices.push((index & 0x00ff0000) >> 16);\r\n                    floatIndices.push((index >> 24) & 0xff); // & 0xFF to convert to v + 256 if v < 0\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, floatIndices, false);\r\n            }\r\n\r\n            if (binaryInfo.matricesIndicesExtraAttrDesc && binaryInfo.matricesIndicesExtraAttrDesc.count > 0) {\r\n                const matricesIndicesData = new Int32Array(parsedGeometry, binaryInfo.matricesIndicesExtraAttrDesc.offset, binaryInfo.matricesIndicesExtraAttrDesc.count);\r\n                const floatIndices = [];\r\n                for (let i = 0; i < matricesIndicesData.length; i++) {\r\n                    const index = matricesIndicesData[i];\r\n                    floatIndices.push(index & 0x000000ff);\r\n                    floatIndices.push((index & 0x0000ff00) >> 8);\r\n                    floatIndices.push((index & 0x00ff0000) >> 16);\r\n                    floatIndices.push((index >> 24) & 0xff); // & 0xFF to convert to v + 256 if v < 0\r\n                }\r\n                mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, floatIndices, false);\r\n            }\r\n\r\n            if (binaryInfo.matricesWeightsAttrDesc && binaryInfo.matricesWeightsAttrDesc.count > 0) {\r\n                const matricesWeightsData = new Float32Array(parsedGeometry, binaryInfo.matricesWeightsAttrDesc.offset, binaryInfo.matricesWeightsAttrDesc.count);\r\n                mesh.setVerticesData(VertexBuffer.MatricesWeightsKind, matricesWeightsData, false);\r\n            }\r\n\r\n            if (binaryInfo.indicesAttrDesc && binaryInfo.indicesAttrDesc.count > 0) {\r\n                const indicesData = new Int32Array(parsedGeometry, binaryInfo.indicesAttrDesc.offset, binaryInfo.indicesAttrDesc.count);\r\n                mesh.setIndices(indicesData, null);\r\n            }\r\n\r\n            if (binaryInfo.subMeshesAttrDesc && binaryInfo.subMeshesAttrDesc.count > 0) {\r\n                const subMeshesData = new Int32Array(parsedGeometry, binaryInfo.subMeshesAttrDesc.offset, binaryInfo.subMeshesAttrDesc.count * 5);\r\n\r\n                mesh.subMeshes = [];\r\n                for (let i = 0; i < binaryInfo.subMeshesAttrDesc.count; i++) {\r\n                    const materialIndex = subMeshesData[i * 5 + 0];\r\n                    const verticesStart = subMeshesData[i * 5 + 1];\r\n                    const verticesCount = subMeshesData[i * 5 + 2];\r\n                    const indexStart = subMeshesData[i * 5 + 3];\r\n                    const indexCount = subMeshesData[i * 5 + 4];\r\n\r\n                    SubMesh.AddToMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, <AbstractMesh>mesh);\r\n                }\r\n            }\r\n        } else if (parsedGeometry.positions && parsedGeometry.normals && parsedGeometry.indices) {\r\n            mesh.setVerticesData(VertexBuffer.PositionKind, parsedGeometry.positions, parsedGeometry.positions._updatable || parsedGeometry.positionsUpdatable);\r\n\r\n            mesh.setVerticesData(VertexBuffer.NormalKind, parsedGeometry.normals, parsedGeometry.normals._updatable || parsedGeometry.normalsUpdatable);\r\n\r\n            if (parsedGeometry.tangents) {\r\n                mesh.setVerticesData(VertexBuffer.TangentKind, parsedGeometry.tangents, parsedGeometry.tangents._updatable || parsedGeometry.tangentsUpdatable);\r\n            }\r\n\r\n            if (parsedGeometry.uvs) {\r\n                mesh.setVerticesData(VertexBuffer.UVKind, parsedGeometry.uvs, parsedGeometry.uvs._updatable || parsedGeometry.uvsUpdatable);\r\n            }\r\n\r\n            if (parsedGeometry.uvs2) {\r\n                mesh.setVerticesData(VertexBuffer.UV2Kind, parsedGeometry.uvs2, parsedGeometry.uvs2._updatable || parsedGeometry.uvs2Updatable);\r\n            }\r\n\r\n            if (parsedGeometry.uvs3) {\r\n                mesh.setVerticesData(VertexBuffer.UV3Kind, parsedGeometry.uvs3, parsedGeometry.uvs3._updatable || parsedGeometry.uvs3Updatable);\r\n            }\r\n\r\n            if (parsedGeometry.uvs4) {\r\n                mesh.setVerticesData(VertexBuffer.UV4Kind, parsedGeometry.uvs4, parsedGeometry.uvs4._updatable || parsedGeometry.uvs4Updatable);\r\n            }\r\n\r\n            if (parsedGeometry.uvs5) {\r\n                mesh.setVerticesData(VertexBuffer.UV5Kind, parsedGeometry.uvs5, parsedGeometry.uvs5._updatable || parsedGeometry.uvs5Updatable);\r\n            }\r\n\r\n            if (parsedGeometry.uvs6) {\r\n                mesh.setVerticesData(VertexBuffer.UV6Kind, parsedGeometry.uvs6, parsedGeometry.uvs6._updatable || parsedGeometry.uvs6Updatable);\r\n            }\r\n\r\n            if (parsedGeometry.colors) {\r\n                mesh.setVerticesData(VertexBuffer.ColorKind, Color4.CheckColors4(parsedGeometry.colors, parsedGeometry.positions.length / 3), parsedGeometry.colors._updatable);\r\n            }\r\n\r\n            if (parsedGeometry.matricesIndices) {\r\n                if (!parsedGeometry.matricesIndices._isExpanded && !parsedGeometry.matricesIndicesExpanded) {\r\n                    const floatIndices = [];\r\n\r\n                    for (let i = 0; i < parsedGeometry.matricesIndices.length; i++) {\r\n                        const matricesIndex = parsedGeometry.matricesIndices[i];\r\n\r\n                        floatIndices.push(matricesIndex & 0x000000ff);\r\n                        floatIndices.push((matricesIndex & 0x0000ff00) >> 8);\r\n                        floatIndices.push((matricesIndex & 0x00ff0000) >> 16);\r\n                        floatIndices.push((matricesIndex >> 24) & 0xff); // & 0xFF to convert to v + 256 if v < 0\r\n                    }\r\n\r\n                    mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, floatIndices, parsedGeometry.matricesIndices._updatable || parsedGeometry.matricesIndicesUpdatable);\r\n                } else {\r\n                    delete parsedGeometry.matricesIndices._isExpanded;\r\n                    delete parsedGeometry.matricesIndicesExpanded;\r\n                    mesh.setVerticesData(\r\n                        VertexBuffer.MatricesIndicesKind,\r\n                        parsedGeometry.matricesIndices,\r\n                        parsedGeometry.matricesIndices._updatable || parsedGeometry.matricesIndicesUpdatable\r\n                    );\r\n                }\r\n            }\r\n\r\n            if (parsedGeometry.matricesIndicesExtra) {\r\n                if (!(parsedGeometry.matricesIndicesExtraExpanded || parsedGeometry.matricesIndicesExtra._isExpanded)) {\r\n                    const floatIndices = [];\r\n\r\n                    for (let i = 0; i < parsedGeometry.matricesIndicesExtra.length; i++) {\r\n                        const matricesIndex = parsedGeometry.matricesIndicesExtra[i];\r\n\r\n                        floatIndices.push(matricesIndex & 0x000000ff);\r\n                        floatIndices.push((matricesIndex & 0x0000ff00) >> 8);\r\n                        floatIndices.push((matricesIndex & 0x00ff0000) >> 16);\r\n                        floatIndices.push((matricesIndex >> 24) & 0xff); // & 0xFF to convert to v + 256 if v < 0\r\n                    }\r\n\r\n                    mesh.setVerticesData(\r\n                        VertexBuffer.MatricesIndicesExtraKind,\r\n                        floatIndices,\r\n                        parsedGeometry.matricesIndicesExtra._updatable || parsedGeometry.matricesIndicesExtraUpdatable\r\n                    );\r\n                } else {\r\n                    delete parsedGeometry.matricesIndices._isExpanded;\r\n                    delete parsedGeometry.matricesIndicesExtraExpanded;\r\n                    mesh.setVerticesData(\r\n                        VertexBuffer.MatricesIndicesExtraKind,\r\n                        parsedGeometry.matricesIndicesExtra,\r\n                        parsedGeometry.matricesIndicesExtra._updatable || parsedGeometry.matricesIndicesExtraUpdatable\r\n                    );\r\n                }\r\n            }\r\n\r\n            if (parsedGeometry.matricesWeights) {\r\n                Geometry._CleanMatricesWeights(parsedGeometry, mesh);\r\n                mesh.setVerticesData(VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, parsedGeometry.matricesWeights._updatable);\r\n            }\r\n\r\n            if (parsedGeometry.matricesWeightsExtra) {\r\n                mesh.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, parsedGeometry.matricesWeights._updatable);\r\n            }\r\n\r\n            mesh.setIndices(parsedGeometry.indices, null);\r\n        }\r\n\r\n        // SubMeshes\r\n        if (parsedGeometry.subMeshes) {\r\n            mesh.subMeshes = [];\r\n            for (let subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {\r\n                const parsedSubMesh = parsedGeometry.subMeshes[subIndex];\r\n\r\n                SubMesh.AddToMesh(\r\n                    parsedSubMesh.materialIndex,\r\n                    parsedSubMesh.verticesStart,\r\n                    parsedSubMesh.verticesCount,\r\n                    parsedSubMesh.indexStart,\r\n                    parsedSubMesh.indexCount,\r\n                    <AbstractMesh>mesh\r\n                );\r\n            }\r\n        }\r\n\r\n        // Flat shading\r\n        if (mesh._shouldGenerateFlatShading) {\r\n            mesh.convertToFlatShadedMesh();\r\n            mesh._shouldGenerateFlatShading = false;\r\n        }\r\n\r\n        // Update\r\n        mesh.computeWorldMatrix(true);\r\n\r\n        scene.onMeshImportedObservable.notifyObservers(<AbstractMesh>mesh);\r\n    }\r\n\r\n    private static _CleanMatricesWeights(parsedGeometry: any, mesh: Mesh): void {\r\n        const epsilon: number = 1e-3;\r\n        if (!SceneLoaderFlags.CleanBoneMatrixWeights) {\r\n            return;\r\n        }\r\n        let noInfluenceBoneIndex: number;\r\n        if (parsedGeometry.skeletonId > -1) {\r\n            const skeleton = mesh.getScene().getLastSkeletonById(parsedGeometry.skeletonId);\r\n\r\n            if (!skeleton) {\r\n                return;\r\n            }\r\n            noInfluenceBoneIndex = skeleton.bones.length;\r\n        } else {\r\n            return;\r\n        }\r\n        const matricesIndices = <FloatArray>mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);\r\n        const matricesIndicesExtra = <FloatArray>mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind);\r\n        const matricesWeights = parsedGeometry.matricesWeights;\r\n        const matricesWeightsExtra = parsedGeometry.matricesWeightsExtra;\r\n        const influencers = parsedGeometry.numBoneInfluencer;\r\n        const size = matricesWeights.length;\r\n\r\n        for (let i = 0; i < size; i += 4) {\r\n            let weight = 0.0;\r\n            let firstZeroWeight = -1;\r\n            for (let j = 0; j < 4; j++) {\r\n                const w = matricesWeights[i + j];\r\n                weight += w;\r\n                if (w < epsilon && firstZeroWeight < 0) {\r\n                    firstZeroWeight = j;\r\n                }\r\n            }\r\n            if (matricesWeightsExtra) {\r\n                for (let j = 0; j < 4; j++) {\r\n                    const w = matricesWeightsExtra[i + j];\r\n                    weight += w;\r\n                    if (w < epsilon && firstZeroWeight < 0) {\r\n                        firstZeroWeight = j + 4;\r\n                    }\r\n                }\r\n            }\r\n            if (firstZeroWeight < 0 || firstZeroWeight > influencers - 1) {\r\n                firstZeroWeight = influencers - 1;\r\n            }\r\n            if (weight > epsilon) {\r\n                const mweight = 1.0 / weight;\r\n                for (let j = 0; j < 4; j++) {\r\n                    matricesWeights[i + j] *= mweight;\r\n                }\r\n                if (matricesWeightsExtra) {\r\n                    for (let j = 0; j < 4; j++) {\r\n                        matricesWeightsExtra[i + j] *= mweight;\r\n                    }\r\n                }\r\n            } else {\r\n                if (firstZeroWeight >= 4) {\r\n                    matricesWeightsExtra[i + firstZeroWeight - 4] = 1.0 - weight;\r\n                    matricesIndicesExtra[i + firstZeroWeight - 4] = noInfluenceBoneIndex;\r\n                } else {\r\n                    matricesWeights[i + firstZeroWeight] = 1.0 - weight;\r\n                    matricesIndices[i + firstZeroWeight] = noInfluenceBoneIndex;\r\n                }\r\n            }\r\n        }\r\n\r\n        mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, matricesIndices);\r\n        if (parsedGeometry.matricesWeightsExtra) {\r\n            mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, matricesIndicesExtra);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a new geometry from persisted data (Using .babylon file format)\r\n     * @param parsedVertexData defines the persisted data\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root url to use to load assets (like delayed data)\r\n     * @returns the new geometry object\r\n     */\r\n    public static Parse(parsedVertexData: any, scene: Scene, rootUrl: string): Nullable<Geometry> {\r\n        const geometry = new Geometry(parsedVertexData.id, scene, undefined, parsedVertexData.updatable);\r\n        geometry._loadedUniqueId = parsedVertexData.uniqueId;\r\n\r\n        if (Tags) {\r\n            Tags.AddTagsTo(geometry, parsedVertexData.tags);\r\n        }\r\n\r\n        if (parsedVertexData.delayLoadingFile) {\r\n            geometry.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n            geometry.delayLoadingFile = rootUrl + parsedVertexData.delayLoadingFile;\r\n            geometry._boundingInfo = new BoundingInfo(Vector3.FromArray(parsedVertexData.boundingBoxMinimum), Vector3.FromArray(parsedVertexData.boundingBoxMaximum));\r\n\r\n            geometry._delayInfo = [];\r\n            if (parsedVertexData.hasUVs) {\r\n                geometry._delayInfo.push(VertexBuffer.UVKind);\r\n            }\r\n\r\n            if (parsedVertexData.hasUVs2) {\r\n                geometry._delayInfo.push(VertexBuffer.UV2Kind);\r\n            }\r\n\r\n            if (parsedVertexData.hasUVs3) {\r\n                geometry._delayInfo.push(VertexBuffer.UV3Kind);\r\n            }\r\n\r\n            if (parsedVertexData.hasUVs4) {\r\n                geometry._delayInfo.push(VertexBuffer.UV4Kind);\r\n            }\r\n\r\n            if (parsedVertexData.hasUVs5) {\r\n                geometry._delayInfo.push(VertexBuffer.UV5Kind);\r\n            }\r\n\r\n            if (parsedVertexData.hasUVs6) {\r\n                geometry._delayInfo.push(VertexBuffer.UV6Kind);\r\n            }\r\n\r\n            if (parsedVertexData.hasColors) {\r\n                geometry._delayInfo.push(VertexBuffer.ColorKind);\r\n            }\r\n\r\n            if (parsedVertexData.hasMatricesIndices) {\r\n                geometry._delayInfo.push(VertexBuffer.MatricesIndicesKind);\r\n            }\r\n\r\n            if (parsedVertexData.hasMatricesWeights) {\r\n                geometry._delayInfo.push(VertexBuffer.MatricesWeightsKind);\r\n            }\r\n\r\n            geometry._delayLoadingFunction = VertexData.ImportVertexData;\r\n        } else {\r\n            VertexData.ImportVertexData(parsedVertexData, geometry);\r\n        }\r\n\r\n        scene.pushGeometry(geometry, true);\r\n\r\n        return geometry;\r\n    }\r\n}\r\n","import { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { type IStencilState } from \"../States/IStencilState\";\r\n\r\nimport { type Scene } from \"../scene\";\r\n\r\n/**\r\n * Class that holds the different stencil states of a material\r\n * Usage example: https://playground.babylonjs.com/#CW5PRI#10\r\n */\r\nexport class MaterialStencilState implements IStencilState {\r\n    /**\r\n     * Creates a material stencil state instance\r\n     */\r\n    public constructor() {\r\n        this.reset();\r\n    }\r\n\r\n    /**\r\n     * Resets all the stencil states to default values\r\n     */\r\n    public reset() {\r\n        this.enabled = false;\r\n        this.mask = 0xff;\r\n\r\n        this.funcRef = 1;\r\n        this.funcMask = 0xff;\r\n\r\n        this.func = Constants.ALWAYS;\r\n        this.opStencilFail = Constants.KEEP;\r\n        this.opDepthFail = Constants.KEEP;\r\n        this.opStencilDepthPass = Constants.REPLACE;\r\n\r\n        this.backFunc = Constants.ALWAYS;\r\n        this.backOpStencilFail = Constants.KEEP;\r\n        this.backOpDepthFail = Constants.KEEP;\r\n        this.backOpStencilDepthPass = Constants.REPLACE;\r\n    }\r\n\r\n    private _func: number;\r\n    /**\r\n     * Gets or sets the stencil function\r\n     */\r\n    @serialize()\r\n    public get func(): number {\r\n        return this._func;\r\n    }\r\n\r\n    public set func(value: number) {\r\n        this._func = value;\r\n    }\r\n\r\n    private _backFunc: number;\r\n    /**\r\n     * Gets or sets the stencil back function\r\n     */\r\n    @serialize()\r\n    public get backFunc(): number {\r\n        return this._backFunc;\r\n    }\r\n\r\n    public set backFunc(value: number) {\r\n        this._backFunc = value;\r\n    }\r\n\r\n    private _funcRef: number;\r\n    /**\r\n     * Gets or sets the stencil function reference\r\n     */\r\n    @serialize()\r\n    public get funcRef(): number {\r\n        return this._funcRef;\r\n    }\r\n\r\n    public set funcRef(value: number) {\r\n        this._funcRef = value;\r\n    }\r\n\r\n    private _funcMask: number;\r\n    /**\r\n     * Gets or sets the stencil function mask\r\n     */\r\n    @serialize()\r\n    public get funcMask(): number {\r\n        return this._funcMask;\r\n    }\r\n\r\n    public set funcMask(value: number) {\r\n        this._funcMask = value;\r\n    }\r\n\r\n    private _opStencilFail: number;\r\n    /**\r\n     * Gets or sets the operation when the stencil test fails\r\n     */\r\n    @serialize()\r\n    public get opStencilFail(): number {\r\n        return this._opStencilFail;\r\n    }\r\n\r\n    public set opStencilFail(value: number) {\r\n        this._opStencilFail = value;\r\n    }\r\n\r\n    private _opDepthFail: number;\r\n    /**\r\n     * Gets or sets the operation when the depth test fails\r\n     */\r\n    @serialize()\r\n    public get opDepthFail(): number {\r\n        return this._opDepthFail;\r\n    }\r\n\r\n    public set opDepthFail(value: number) {\r\n        this._opDepthFail = value;\r\n    }\r\n\r\n    private _opStencilDepthPass: number;\r\n    /**\r\n     * Gets or sets the operation when the stencil+depth test succeeds\r\n     */\r\n    @serialize()\r\n    public get opStencilDepthPass(): number {\r\n        return this._opStencilDepthPass;\r\n    }\r\n\r\n    public set opStencilDepthPass(value: number) {\r\n        this._opStencilDepthPass = value;\r\n    }\r\n\r\n    private _backOpStencilFail: number;\r\n    /**\r\n     * Gets or sets the operation when the back stencil test fails\r\n     */\r\n    @serialize()\r\n    public get backOpStencilFail(): number {\r\n        return this._backOpStencilFail;\r\n    }\r\n\r\n    public set backOpStencilFail(value: number) {\r\n        this._backOpStencilFail = value;\r\n    }\r\n\r\n    private _backOpDepthFail: number;\r\n    /**\r\n     * Gets or sets the operation when the back depth test fails\r\n     */\r\n    @serialize()\r\n    public get backOpDepthFail(): number {\r\n        return this._backOpDepthFail;\r\n    }\r\n\r\n    public set backOpDepthFail(value: number) {\r\n        this._backOpDepthFail = value;\r\n    }\r\n\r\n    private _backOpStencilDepthPass: number;\r\n    /**\r\n     * Gets or sets the operation when the back stencil+depth test succeeds\r\n     */\r\n    @serialize()\r\n    public get backOpStencilDepthPass(): number {\r\n        return this._backOpStencilDepthPass;\r\n    }\r\n\r\n    public set backOpStencilDepthPass(value: number) {\r\n        this._backOpStencilDepthPass = value;\r\n    }\r\n\r\n    private _mask: number;\r\n    /**\r\n     * Gets or sets the stencil mask\r\n     */\r\n    @serialize()\r\n    public get mask(): number {\r\n        return this._mask;\r\n    }\r\n\r\n    public set mask(value: number) {\r\n        this._mask = value;\r\n    }\r\n\r\n    private _enabled: boolean;\r\n    /**\r\n     * Enables or disables the stencil test\r\n     */\r\n    @serialize()\r\n    public get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public set enabled(value: boolean) {\r\n        this._enabled = value;\r\n    }\r\n\r\n    /**\r\n     * Get the current class name, useful for serialization or dynamic coding.\r\n     * @returns \"MaterialStencilState\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"MaterialStencilState\";\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current configuration into another one.\r\n     * @param stencilState defines stencil state where to copy the info\r\n     */\r\n    public copyTo(stencilState: MaterialStencilState): void {\r\n        SerializationHelper.Clone(() => stencilState, this);\r\n    }\r\n\r\n    /**\r\n     * Serializes this stencil configuration.\r\n     * @returns - An object with the serialized config.\r\n     */\r\n    public serialize(): any {\r\n        return SerializationHelper.Serialize(this);\r\n    }\r\n\r\n    /**\r\n     * Parses a stencil state configuration from a serialized object.\r\n     * @param source - Serialized object.\r\n     * @param scene Defines the scene we are parsing for\r\n     * @param rootUrl Defines the rootUrl to load from\r\n     */\r\n    public parse(source: any, scene: Scene, rootUrl: string): void {\r\n        SerializationHelper.Parse(() => this, source, scene, rootUrl);\r\n    }\r\n}\r\n","import { type Effect } from \"./effect\";\r\nimport { type IClipPlanesHolder } from \"../Misc/interfaces/iClipPlanesHolder\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\nimport { FloatingOriginCurrentScene } from \"./floatingOriginMatrixOverrides\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\n\r\n/** @internal */\r\nexport function AddClipPlaneUniforms(uniforms: string[]): void {\r\n    if (uniforms.indexOf(\"vClipPlane\") === -1) {\r\n        uniforms.push(\"vClipPlane\");\r\n    }\r\n    if (uniforms.indexOf(\"vClipPlane2\") === -1) {\r\n        uniforms.push(\"vClipPlane2\");\r\n    }\r\n    if (uniforms.indexOf(\"vClipPlane3\") === -1) {\r\n        uniforms.push(\"vClipPlane3\");\r\n    }\r\n    if (uniforms.indexOf(\"vClipPlane4\") === -1) {\r\n        uniforms.push(\"vClipPlane4\");\r\n    }\r\n    if (uniforms.indexOf(\"vClipPlane5\") === -1) {\r\n        uniforms.push(\"vClipPlane5\");\r\n    }\r\n    if (uniforms.indexOf(\"vClipPlane6\") === -1) {\r\n        uniforms.push(\"vClipPlane6\");\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function PrepareStringDefinesForClipPlanes(primaryHolder: IClipPlanesHolder, secondaryHolder: IClipPlanesHolder, defines: string[]): void {\r\n    const clipPlane = !!(primaryHolder.clipPlane ?? secondaryHolder.clipPlane);\r\n    const clipPlane2 = !!(primaryHolder.clipPlane2 ?? secondaryHolder.clipPlane2);\r\n    const clipPlane3 = !!(primaryHolder.clipPlane3 ?? secondaryHolder.clipPlane3);\r\n    const clipPlane4 = !!(primaryHolder.clipPlane4 ?? secondaryHolder.clipPlane4);\r\n    const clipPlane5 = !!(primaryHolder.clipPlane5 ?? secondaryHolder.clipPlane5);\r\n    const clipPlane6 = !!(primaryHolder.clipPlane6 ?? secondaryHolder.clipPlane6);\r\n\r\n    if (clipPlane) {\r\n        defines.push(\"#define CLIPPLANE\");\r\n    }\r\n    if (clipPlane2) {\r\n        defines.push(\"#define CLIPPLANE2\");\r\n    }\r\n    if (clipPlane3) {\r\n        defines.push(\"#define CLIPPLANE3\");\r\n    }\r\n    if (clipPlane4) {\r\n        defines.push(\"#define CLIPPLANE4\");\r\n    }\r\n    if (clipPlane5) {\r\n        defines.push(\"#define CLIPPLANE5\");\r\n    }\r\n    if (clipPlane6) {\r\n        defines.push(\"#define CLIPPLANE6\");\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function PrepareDefinesForClipPlanes(primaryHolder: IClipPlanesHolder, secondaryHolder: IClipPlanesHolder, defines: Record<string, any>): boolean {\r\n    let changed = false;\r\n\r\n    const clipPlane = !!(primaryHolder.clipPlane ?? secondaryHolder.clipPlane);\r\n    const clipPlane2 = !!(primaryHolder.clipPlane2 ?? secondaryHolder.clipPlane2);\r\n    const clipPlane3 = !!(primaryHolder.clipPlane3 ?? secondaryHolder.clipPlane3);\r\n    const clipPlane4 = !!(primaryHolder.clipPlane4 ?? secondaryHolder.clipPlane4);\r\n    const clipPlane5 = !!(primaryHolder.clipPlane5 ?? secondaryHolder.clipPlane5);\r\n    const clipPlane6 = !!(primaryHolder.clipPlane6 ?? secondaryHolder.clipPlane6);\r\n\r\n    // Do not factorize this code, it breaks browsers optimizations.\r\n    if (defines[\"CLIPPLANE\"] !== clipPlane) {\r\n        defines[\"CLIPPLANE\"] = clipPlane;\r\n        changed = true;\r\n    }\r\n    if (defines[\"CLIPPLANE2\"] !== clipPlane2) {\r\n        defines[\"CLIPPLANE2\"] = clipPlane2;\r\n        changed = true;\r\n    }\r\n    if (defines[\"CLIPPLANE3\"] !== clipPlane3) {\r\n        defines[\"CLIPPLANE3\"] = clipPlane3;\r\n        changed = true;\r\n    }\r\n    if (defines[\"CLIPPLANE4\"] !== clipPlane4) {\r\n        defines[\"CLIPPLANE4\"] = clipPlane4;\r\n        changed = true;\r\n    }\r\n    if (defines[\"CLIPPLANE5\"] !== clipPlane5) {\r\n        defines[\"CLIPPLANE5\"] = clipPlane5;\r\n        changed = true;\r\n    }\r\n    if (defines[\"CLIPPLANE6\"] !== clipPlane6) {\r\n        defines[\"CLIPPLANE6\"] = clipPlane6;\r\n        changed = true;\r\n    }\r\n\r\n    return changed;\r\n}\r\n\r\n/** @internal */\r\nexport function BindClipPlane(effect: Effect, primaryHolder: IClipPlanesHolder, secondaryHolder: IClipPlanesHolder): void {\r\n    let clipPlane = primaryHolder.clipPlane ?? secondaryHolder.clipPlane;\r\n    SetClipPlane(effect, \"vClipPlane\", clipPlane);\r\n    clipPlane = primaryHolder.clipPlane2 ?? secondaryHolder.clipPlane2;\r\n    SetClipPlane(effect, \"vClipPlane2\", clipPlane);\r\n    clipPlane = primaryHolder.clipPlane3 ?? secondaryHolder.clipPlane3;\r\n    SetClipPlane(effect, \"vClipPlane3\", clipPlane);\r\n    clipPlane = primaryHolder.clipPlane4 ?? secondaryHolder.clipPlane4;\r\n    SetClipPlane(effect, \"vClipPlane4\", clipPlane);\r\n    clipPlane = primaryHolder.clipPlane5 ?? secondaryHolder.clipPlane5;\r\n    SetClipPlane(effect, \"vClipPlane5\", clipPlane);\r\n    clipPlane = primaryHolder.clipPlane6 ?? secondaryHolder.clipPlane6;\r\n    SetClipPlane(effect, \"vClipPlane6\", clipPlane);\r\n}\r\n\r\nfunction SetClipPlane(effect: Effect, uniformName: string, clipPlane: Nullable<Plane>): void {\r\n    if (clipPlane) {\r\n        // Original clipplane is using equation normal.dot(p) + d = 0\r\n        // Assume we have p' = p - offset, that means normal.dot(p') + d' = 0\r\n        // So to get the offset plane,\r\n        // normal.dot(p' + offset) + d = 0\r\n        // normal.dot(p') + normal.dot(offset) + d = 0\r\n        // -d' + normal.dot(offset) + d = 0\r\n        // d' = d + normal.dot(offset)\r\n        const offset = FloatingOriginCurrentScene.getScene()?.floatingOriginOffset || Vector3.ZeroReadOnly;\r\n        effect.setFloat4(uniformName, clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d + Vector3.Dot(clipPlane.normal, offset));\r\n    }\r\n}\r\n","import { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * This groups all the flags used to control the materials channel.\r\n */\r\nexport class MaterialFlags {\r\n    // Flags used to enable or disable a type of texture for all Standard Materials\r\n    private static _DiffuseTextureEnabled = true;\r\n    /**\r\n     * Are diffuse textures enabled in the application.\r\n     */\r\n    public static get DiffuseTextureEnabled(): boolean {\r\n        return this._DiffuseTextureEnabled;\r\n    }\r\n    public static set DiffuseTextureEnabled(value: boolean) {\r\n        if (this._DiffuseTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._DiffuseTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _BaseWeightTextureEnabled = true;\r\n    /**\r\n     * Is the OpenPBR Base Weight texture enabled in the application.\r\n     */\r\n    public static get BaseWeightTextureEnabled(): boolean {\r\n        return this._BaseWeightTextureEnabled;\r\n    }\r\n    public static set BaseWeightTextureEnabled(value: boolean) {\r\n        if (this._BaseWeightTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._BaseWeightTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _BaseDiffuseRoughnessTextureEnabled = true;\r\n    /**\r\n     * Is the OpenPBR Base Diffuse Roughness texture enabled in the application.\r\n     */\r\n    public static get BaseDiffuseRoughnessTextureEnabled(): boolean {\r\n        return this._BaseDiffuseRoughnessTextureEnabled;\r\n    }\r\n    public static set BaseDiffuseRoughnessTextureEnabled(value: boolean) {\r\n        if (this._BaseDiffuseRoughnessTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._BaseDiffuseRoughnessTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _DetailTextureEnabled = true;\r\n    /**\r\n     * Are detail textures enabled in the application.\r\n     */\r\n    public static get DetailTextureEnabled(): boolean {\r\n        return this._DetailTextureEnabled;\r\n    }\r\n    public static set DetailTextureEnabled(value: boolean) {\r\n        if (this._DetailTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._DetailTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _DecalMapEnabled = true;\r\n    /**\r\n     * Are decal maps enabled in the application.\r\n     */\r\n    public static get DecalMapEnabled(): boolean {\r\n        return this._DecalMapEnabled;\r\n    }\r\n    public static set DecalMapEnabled(value: boolean) {\r\n        if (this._DecalMapEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._DecalMapEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _AmbientTextureEnabled = true;\r\n    /**\r\n     * Are ambient textures enabled in the application.\r\n     */\r\n    public static get AmbientTextureEnabled(): boolean {\r\n        return this._AmbientTextureEnabled;\r\n    }\r\n    public static set AmbientTextureEnabled(value: boolean) {\r\n        if (this._AmbientTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._AmbientTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _OpacityTextureEnabled = true;\r\n    /**\r\n     * Are opacity textures enabled in the application.\r\n     */\r\n    public static get OpacityTextureEnabled(): boolean {\r\n        return this._OpacityTextureEnabled;\r\n    }\r\n    public static set OpacityTextureEnabled(value: boolean) {\r\n        if (this._OpacityTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._OpacityTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _ReflectionTextureEnabled = true;\r\n    /**\r\n     * Are reflection textures enabled in the application.\r\n     */\r\n    public static get ReflectionTextureEnabled(): boolean {\r\n        return this._ReflectionTextureEnabled;\r\n    }\r\n    public static set ReflectionTextureEnabled(value: boolean) {\r\n        if (this._ReflectionTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ReflectionTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _EmissiveTextureEnabled = true;\r\n    /**\r\n     * Are emissive textures enabled in the application.\r\n     */\r\n    public static get EmissiveTextureEnabled(): boolean {\r\n        return this._EmissiveTextureEnabled;\r\n    }\r\n    public static set EmissiveTextureEnabled(value: boolean) {\r\n        if (this._EmissiveTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._EmissiveTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _SpecularTextureEnabled = true;\r\n    /**\r\n     * Are specular textures enabled in the application.\r\n     */\r\n    public static get SpecularTextureEnabled(): boolean {\r\n        return this._SpecularTextureEnabled;\r\n    }\r\n    public static set SpecularTextureEnabled(value: boolean) {\r\n        if (this._SpecularTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._SpecularTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _BumpTextureEnabled = true;\r\n    /**\r\n     * Are bump textures enabled in the application.\r\n     */\r\n    public static get BumpTextureEnabled(): boolean {\r\n        return this._BumpTextureEnabled;\r\n    }\r\n    public static set BumpTextureEnabled(value: boolean) {\r\n        if (this._BumpTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._BumpTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _LightmapTextureEnabled = true;\r\n    /**\r\n     * Are lightmap textures enabled in the application.\r\n     */\r\n    public static get LightmapTextureEnabled(): boolean {\r\n        return this._LightmapTextureEnabled;\r\n    }\r\n    public static set LightmapTextureEnabled(value: boolean) {\r\n        if (this._LightmapTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._LightmapTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _RefractionTextureEnabled = true;\r\n    /**\r\n     * Are refraction textures enabled in the application.\r\n     */\r\n    public static get RefractionTextureEnabled(): boolean {\r\n        return this._RefractionTextureEnabled;\r\n    }\r\n    public static set RefractionTextureEnabled(value: boolean) {\r\n        if (this._RefractionTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._RefractionTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _ColorGradingTextureEnabled = true;\r\n    /**\r\n     * Are color grading textures enabled in the application.\r\n     */\r\n    public static get ColorGradingTextureEnabled(): boolean {\r\n        return this._ColorGradingTextureEnabled;\r\n    }\r\n    public static set ColorGradingTextureEnabled(value: boolean) {\r\n        if (this._ColorGradingTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ColorGradingTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _FresnelEnabled = true;\r\n    /**\r\n     * Are fresnels enabled in the application.\r\n     */\r\n    public static get FresnelEnabled(): boolean {\r\n        return this._FresnelEnabled;\r\n    }\r\n    public static set FresnelEnabled(value: boolean) {\r\n        if (this._FresnelEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._FresnelEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_FresnelDirtyFlag);\r\n    }\r\n\r\n    private static _ClearCoatTextureEnabled = true;\r\n    /**\r\n     * Are clear coat textures enabled in the application.\r\n     */\r\n    public static get ClearCoatTextureEnabled(): boolean {\r\n        return this._ClearCoatTextureEnabled;\r\n    }\r\n    public static set ClearCoatTextureEnabled(value: boolean) {\r\n        if (this._ClearCoatTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ClearCoatTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _ClearCoatBumpTextureEnabled = true;\r\n    /**\r\n     * Are clear coat bump textures enabled in the application.\r\n     */\r\n    public static get ClearCoatBumpTextureEnabled(): boolean {\r\n        return this._ClearCoatBumpTextureEnabled;\r\n    }\r\n    public static set ClearCoatBumpTextureEnabled(value: boolean) {\r\n        if (this._ClearCoatBumpTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ClearCoatBumpTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _ClearCoatTintTextureEnabled = true;\r\n    /**\r\n     * Are clear coat tint textures enabled in the application.\r\n     */\r\n    public static get ClearCoatTintTextureEnabled(): boolean {\r\n        return this._ClearCoatTintTextureEnabled;\r\n    }\r\n    public static set ClearCoatTintTextureEnabled(value: boolean) {\r\n        if (this._ClearCoatTintTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ClearCoatTintTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _SheenTextureEnabled = true;\r\n    /**\r\n     * Are sheen textures enabled in the application.\r\n     */\r\n    public static get SheenTextureEnabled(): boolean {\r\n        return this._SheenTextureEnabled;\r\n    }\r\n    public static set SheenTextureEnabled(value: boolean) {\r\n        if (this._SheenTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._SheenTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _AnisotropicTextureEnabled = true;\r\n    /**\r\n     * Are anisotropic textures enabled in the application.\r\n     */\r\n    public static get AnisotropicTextureEnabled(): boolean {\r\n        return this._AnisotropicTextureEnabled;\r\n    }\r\n    public static set AnisotropicTextureEnabled(value: boolean) {\r\n        if (this._AnisotropicTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._AnisotropicTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _ThicknessTextureEnabled = true;\r\n    /**\r\n     * Are thickness textures enabled in the application.\r\n     */\r\n    public static get ThicknessTextureEnabled(): boolean {\r\n        return this._ThicknessTextureEnabled;\r\n    }\r\n    public static set ThicknessTextureEnabled(value: boolean) {\r\n        if (this._ThicknessTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._ThicknessTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _RefractionIntensityTextureEnabled = true;\r\n    /**\r\n     * Are refraction intensity textures enabled in the application.\r\n     */\r\n    public static get RefractionIntensityTextureEnabled(): boolean {\r\n        return this._ThicknessTextureEnabled;\r\n    }\r\n    public static set RefractionIntensityTextureEnabled(value: boolean) {\r\n        if (this._RefractionIntensityTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._RefractionIntensityTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _TranslucencyIntensityTextureEnabled = true;\r\n    /**\r\n     * Are translucency intensity textures enabled in the application.\r\n     */\r\n    public static get TranslucencyIntensityTextureEnabled(): boolean {\r\n        return this._TranslucencyIntensityTextureEnabled;\r\n    }\r\n    public static set TranslucencyIntensityTextureEnabled(value: boolean) {\r\n        if (this._TranslucencyIntensityTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._TranslucencyIntensityTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _TranslucencyColorTextureEnabled = true;\r\n    /**\r\n     * Are translucency tint textures enabled in the application.\r\n     */\r\n    public static get TranslucencyColorTextureEnabled(): boolean {\r\n        return this._TranslucencyColorTextureEnabled;\r\n    }\r\n    public static set TranslucencyColorTextureEnabled(value: boolean) {\r\n        if (this._TranslucencyColorTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._TranslucencyColorTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private static _IridescenceTextureEnabled = true;\r\n    /**\r\n     * Are translucency intensity textures enabled in the application.\r\n     */\r\n    public static get IridescenceTextureEnabled(): boolean {\r\n        return this._IridescenceTextureEnabled;\r\n    }\r\n    public static set IridescenceTextureEnabled(value: boolean) {\r\n        if (this._IridescenceTextureEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._IridescenceTextureEnabled = value;\r\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Effect, type IEffectCreationOptions } from \"./effect\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type BaseTexture } from \"./Textures/baseTexture\";\r\nimport { type PrePassConfiguration } from \"./prePassConfiguration\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { type EffectFallbacks } from \"./effectFallbacks\";\r\nimport { LightConstants } from \"../Lights/lightConstants\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type Material } from \"./material\";\r\nimport { type Nullable } from \"../types\";\r\nimport { PrepareDefinesForClipPlanes } from \"./clipPlaneMaterialHelper\";\r\nimport { type MorphTargetManager } from \"../Morph/morphTargetManager\";\r\nimport { type IColor3Like } from \"core/Maths/math.like\";\r\nimport { MaterialFlags } from \"./materialFlags\";\r\nimport { type CubeTexture } from \"./Textures/cubeTexture\";\r\nimport { type Color3 } from \"core/Maths/math.color\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\n\r\n/**\r\n * Binds the logarithmic depth information from the scene to the effect for the given defines.\r\n * @param defines The generated defines used in the effect\r\n * @param effect The effect we are binding the data to\r\n * @param scene The scene we are willing to render with logarithmic scale for\r\n */\r\nexport function BindLogDepth(defines: any, effect: Effect, scene: Scene): void {\r\n    if (!defines || defines[\"LOGARITHMICDEPTH\"] || (defines.indexOf && defines.indexOf(\"LOGARITHMICDEPTH\") >= 0)) {\r\n        const camera = scene.activeCamera as Camera;\r\n        if (camera.mode === Constants.ORTHOGRAPHIC_CAMERA) {\r\n            Logger.Error(\"Logarithmic depth is not compatible with orthographic cameras!\", 20);\r\n        }\r\n        effect.setFloat(\"logarithmicDepthConstant\", 2.0 / (Math.log(camera.maxZ + 1.0) / Math.LN2));\r\n    }\r\n}\r\n\r\n// Temps\r\nconst TempFogColor: IColor3Like = { r: 0, g: 0, b: 0 };\r\nconst TmpMorphInfluencers = {\r\n    NUM_MORPH_INFLUENCERS: 0,\r\n    NORMAL: false,\r\n    TANGENT: false,\r\n    UV: false,\r\n    UV2: false,\r\n    COLOR: false,\r\n};\r\n\r\n/**\r\n * Binds the fog information from the scene to the effect for the given mesh.\r\n * @param scene The scene the lights belongs to\r\n * @param mesh The mesh we are binding the information to render\r\n * @param effect The effect we are binding the data to\r\n * @param linearSpace Defines if the fog effect is applied in linear space\r\n */\r\nexport function BindFogParameters(scene: Scene, mesh?: AbstractMesh, effect?: Effect, linearSpace = false): void {\r\n    if (effect && scene.fogEnabled && (!mesh || mesh.applyFog) && scene.fogMode !== Constants.FOGMODE_NONE) {\r\n        effect.setFloat4(\"vFogInfos\", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);\r\n        // Convert fog color to linear space if used in a linear space computed shader.\r\n        if (linearSpace) {\r\n            scene.fogColor.toLinearSpaceToRef(TempFogColor, scene.getEngine().useExactSrgbConversions);\r\n            effect.setColor3(\"vFogColor\", TempFogColor);\r\n        } else {\r\n            effect.setColor3(\"vFogColor\", scene.fogColor);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Prepares the list of attributes and defines required for morph targets.\r\n * @param morphTargetManager The manager for the morph targets\r\n * @param defines The current list of defines\r\n * @param attribs The current list of attributes\r\n * @param mesh The mesh to prepare the defines and attributes for\r\n * @param usePositionMorph Whether the position morph target is used\r\n * @param useNormalMorph Whether the normal morph target is used\r\n * @param useTangentMorph Whether the tangent morph target is used\r\n * @param useUVMorph Whether the UV morph target is used\r\n * @param useUV2Morph Whether the UV2 morph target is used\r\n * @param useColorMorph Whether the color morph target is used\r\n * @returns The maxSimultaneousMorphTargets for the effect\r\n */\r\nexport function PrepareDefinesAndAttributesForMorphTargets(\r\n    morphTargetManager: MorphTargetManager,\r\n    defines: string[],\r\n    attribs: string[],\r\n    mesh: AbstractMesh,\r\n    usePositionMorph: boolean,\r\n    useNormalMorph: boolean,\r\n    useTangentMorph: boolean,\r\n    useUVMorph: boolean,\r\n    useUV2Morph: boolean,\r\n    useColorMorph: boolean\r\n): number {\r\n    const numMorphInfluencers = morphTargetManager.numMaxInfluencers || morphTargetManager.numInfluencers;\r\n    if (numMorphInfluencers <= 0) {\r\n        return 0;\r\n    }\r\n\r\n    defines.push(\"#define MORPHTARGETS\");\r\n\r\n    if (morphTargetManager.hasPositions) {\r\n        defines.push(\"#define MORPHTARGETTEXTURE_HASPOSITIONS\");\r\n    }\r\n    if (morphTargetManager.hasNormals) {\r\n        defines.push(\"#define MORPHTARGETTEXTURE_HASNORMALS\");\r\n    }\r\n    if (morphTargetManager.hasTangents) {\r\n        defines.push(\"#define MORPHTARGETTEXTURE_HASTANGENTS\");\r\n    }\r\n    if (morphTargetManager.hasUVs) {\r\n        defines.push(\"#define MORPHTARGETTEXTURE_HASUVS\");\r\n    }\r\n    if (morphTargetManager.hasUV2s) {\r\n        defines.push(\"#define MORPHTARGETTEXTURE_HASUV2S\");\r\n    }\r\n    if (morphTargetManager.hasColors) {\r\n        defines.push(\"#define MORPHTARGETTEXTURE_HASCOLORS\");\r\n    }\r\n\r\n    if (morphTargetManager.supportsPositions && usePositionMorph) {\r\n        defines.push(\"#define MORPHTARGETS_POSITION\");\r\n    }\r\n    if (morphTargetManager.supportsNormals && useNormalMorph) {\r\n        defines.push(\"#define MORPHTARGETS_NORMAL\");\r\n    }\r\n    if (morphTargetManager.supportsTangents && useTangentMorph) {\r\n        defines.push(\"#define MORPHTARGETS_TANGENT\");\r\n    }\r\n    if (morphTargetManager.supportsUVs && useUVMorph) {\r\n        defines.push(\"#define MORPHTARGETS_UV\");\r\n    }\r\n    if (morphTargetManager.supportsUV2s && useUV2Morph) {\r\n        defines.push(\"#define MORPHTARGETS_UV2\");\r\n    }\r\n    if (morphTargetManager.supportsColors && useColorMorph) {\r\n        defines.push(\"#define MORPHTARGETS_COLOR\");\r\n    }\r\n\r\n    defines.push(\"#define NUM_MORPH_INFLUENCERS \" + numMorphInfluencers);\r\n\r\n    if (morphTargetManager.isUsingTextureForTargets) {\r\n        defines.push(\"#define MORPHTARGETS_TEXTURE\");\r\n    }\r\n\r\n    TmpMorphInfluencers.NUM_MORPH_INFLUENCERS = numMorphInfluencers;\r\n    TmpMorphInfluencers.NORMAL = useNormalMorph;\r\n    TmpMorphInfluencers.TANGENT = useTangentMorph;\r\n    TmpMorphInfluencers.UV = useUVMorph;\r\n    TmpMorphInfluencers.UV2 = useUV2Morph;\r\n    TmpMorphInfluencers.COLOR = useColorMorph;\r\n\r\n    PrepareAttributesForMorphTargets(attribs, mesh, TmpMorphInfluencers, usePositionMorph);\r\n    return numMorphInfluencers;\r\n}\r\n\r\n/**\r\n * Prepares the list of attributes required for morph targets according to the effect defines.\r\n * @param attribs The current list of supported attribs\r\n * @param mesh The mesh to prepare the morph targets attributes for\r\n * @param influencers The number of influencers\r\n */\r\nexport function PrepareAttributesForMorphTargetsInfluencers(attribs: string[], mesh: AbstractMesh, influencers: number): void {\r\n    TmpMorphInfluencers.NUM_MORPH_INFLUENCERS = influencers;\r\n    TmpMorphInfluencers.NORMAL = false;\r\n    TmpMorphInfluencers.TANGENT = false;\r\n    TmpMorphInfluencers.UV = false;\r\n    TmpMorphInfluencers.UV2 = false;\r\n    TmpMorphInfluencers.COLOR = false;\r\n    PrepareAttributesForMorphTargets(attribs, mesh, TmpMorphInfluencers, true);\r\n}\r\n\r\n/**\r\n * Prepares the list of attributes required for morph targets according to the effect defines.\r\n * @param attribs The current list of supported attribs\r\n * @param mesh The mesh to prepare the morph targets attributes for\r\n * @param defines The current Defines of the effect\r\n * @param usePositionMorph Whether the position morph target is used\r\n */\r\nexport function PrepareAttributesForMorphTargets(attribs: string[], mesh: AbstractMesh, defines: any, usePositionMorph = true): void {\r\n    const influencers = defines[\"NUM_MORPH_INFLUENCERS\"];\r\n\r\n    if (influencers > 0 && EngineStore.LastCreatedEngine) {\r\n        const maxAttributesCount = EngineStore.LastCreatedEngine.getCaps().maxVertexAttribs;\r\n        const manager = (mesh as Mesh).morphTargetManager;\r\n        if (manager?.isUsingTextureForTargets) {\r\n            return;\r\n        }\r\n        const position = manager && manager.supportsPositions && usePositionMorph;\r\n        const normal = manager && manager.supportsNormals && defines[\"NORMAL\"];\r\n        const tangent = manager && manager.supportsTangents && defines[\"TANGENT\"];\r\n        const uv = manager && manager.supportsUVs && defines[\"UV1\"];\r\n        const uv2 = manager && manager.supportsUV2s && defines[\"UV2\"];\r\n        const color = manager && manager.supportsColors && defines[\"VERTEXCOLOR\"];\r\n        for (let index = 0; index < influencers; index++) {\r\n            if (position) {\r\n                attribs.push(Constants.PositionKind + index);\r\n            }\r\n\r\n            if (normal) {\r\n                attribs.push(Constants.NormalKind + index);\r\n            }\r\n\r\n            if (tangent) {\r\n                attribs.push(Constants.TangentKind + index);\r\n            }\r\n\r\n            if (uv) {\r\n                attribs.push(Constants.UVKind + \"_\" + index);\r\n            }\r\n\r\n            if (uv2) {\r\n                attribs.push(Constants.UV2Kind + \"_\" + index);\r\n            }\r\n\r\n            if (color) {\r\n                attribs.push(Constants.ColorKind + index);\r\n            }\r\n\r\n            if (attribs.length > maxAttributesCount) {\r\n                Logger.Error(\"Cannot add more vertex attributes for mesh \" + mesh.name);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Add the list of attributes required for instances to the attribs array.\r\n * @param attribs The current list of supported attribs\r\n * @param needsPreviousMatrices If the shader needs previous matrices\r\n */\r\nexport function PushAttributesForInstances(attribs: string[], needsPreviousMatrices: boolean = false): void {\r\n    attribs.push(\"world0\");\r\n    attribs.push(\"world1\");\r\n    attribs.push(\"world2\");\r\n    attribs.push(\"world3\");\r\n    if (needsPreviousMatrices) {\r\n        attribs.push(\"previousWorld0\");\r\n        attribs.push(\"previousWorld1\");\r\n        attribs.push(\"previousWorld2\");\r\n        attribs.push(\"previousWorld3\");\r\n    }\r\n}\r\n\r\n/**\r\n * Binds the morph targets information from the mesh to the effect.\r\n * @param abstractMesh The mesh we are binding the information to render\r\n * @param effect The effect we are binding the data to\r\n */\r\nexport function BindMorphTargetParameters(abstractMesh: AbstractMesh, effect: Effect): void {\r\n    const manager = (<Mesh>abstractMesh).morphTargetManager;\r\n    if (!abstractMesh || !manager) {\r\n        return;\r\n    }\r\n\r\n    effect.setFloatArray(\"morphTargetInfluences\", manager.influences);\r\n}\r\n\r\n/**\r\n * Binds the scene's uniform buffer to the effect.\r\n * @param effect defines the effect to bind to the scene uniform buffer\r\n * @param sceneUbo defines the uniform buffer storing scene data\r\n */\r\nexport function BindSceneUniformBuffer(effect: Effect, sceneUbo: UniformBuffer): void {\r\n    sceneUbo.bindToEffect(effect, \"Scene\");\r\n}\r\n\r\n/**\r\n * Update parameters for IBL\r\n * @param scene The scene\r\n * @param defines The list of shader defines for the material\r\n * @param ubo The uniform buffer to update\r\n * @param reflectionColor The color to use for the reflection\r\n * @param reflectionTexture The IBL texture\r\n * @param realTimeFiltering Whether realtime filtering of IBL texture is being used\r\n * @param supportTextureInfo Whether the texture info is supported\r\n * @param supportLocalProjection Whether local projection is supported\r\n * @param usePBR Whether PBR is being used\r\n * @param supportSH Whether spherical harmonics are supported\r\n * @param useColor Whether to use the reflection color\r\n * @param reflectionBlur The level of blur of the reflection\r\n */\r\nexport function BindIBLParameters(\r\n    scene: Scene,\r\n    defines: any,\r\n    ubo: UniformBuffer,\r\n    reflectionColor: Color3,\r\n    reflectionTexture: Nullable<BaseTexture> = null,\r\n    realTimeFiltering: boolean = false,\r\n    supportTextureInfo: boolean = false,\r\n    supportLocalProjection: boolean = false,\r\n    usePBR: boolean = false,\r\n    supportSH: boolean = false,\r\n    useColor: boolean = false,\r\n    reflectionBlur: number = 0\r\n): void {\r\n    if (scene.texturesEnabled) {\r\n        if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n            ubo.updateMatrix(\"reflectionMatrix\", reflectionTexture.getReflectionTextureMatrix());\r\n            ubo.updateFloat2(\"vReflectionInfos\", reflectionTexture.level * scene.iblIntensity, reflectionBlur);\r\n\r\n            if (supportLocalProjection && (<any>reflectionTexture).boundingBoxSize) {\r\n                const cubeTexture = <CubeTexture>reflectionTexture;\r\n\r\n                ubo.updateVector3(\"vReflectionPosition\", cubeTexture.boundingBoxPosition);\r\n                ubo.updateVector3(\"vReflectionSize\", cubeTexture.boundingBoxSize);\r\n            }\r\n\r\n            if (realTimeFiltering) {\r\n                const width = reflectionTexture.getSize().width;\r\n                ubo.updateFloat2(\"vReflectionFilteringInfo\", width, Math.log2(width));\r\n            }\r\n\r\n            if (supportSH && !defines.USEIRRADIANCEMAP) {\r\n                const polynomials = reflectionTexture.sphericalPolynomial;\r\n                if (defines.USESPHERICALFROMREFLECTIONMAP && polynomials) {\r\n                    if (defines.SPHERICAL_HARMONICS) {\r\n                        const preScaledHarmonics = polynomials.preScaledHarmonics;\r\n                        ubo.updateVector3(\"vSphericalL00\", preScaledHarmonics.l00);\r\n                        ubo.updateVector3(\"vSphericalL1_1\", preScaledHarmonics.l1_1);\r\n                        ubo.updateVector3(\"vSphericalL10\", preScaledHarmonics.l10);\r\n                        ubo.updateVector3(\"vSphericalL11\", preScaledHarmonics.l11);\r\n                        ubo.updateVector3(\"vSphericalL2_2\", preScaledHarmonics.l2_2);\r\n                        ubo.updateVector3(\"vSphericalL2_1\", preScaledHarmonics.l2_1);\r\n                        ubo.updateVector3(\"vSphericalL20\", preScaledHarmonics.l20);\r\n                        ubo.updateVector3(\"vSphericalL21\", preScaledHarmonics.l21);\r\n                        ubo.updateVector3(\"vSphericalL22\", preScaledHarmonics.l22);\r\n                    } else {\r\n                        ubo.updateFloat3(\"vSphericalX\", polynomials.x.x, polynomials.x.y, polynomials.x.z);\r\n                        ubo.updateFloat3(\"vSphericalY\", polynomials.y.x, polynomials.y.y, polynomials.y.z);\r\n                        ubo.updateFloat3(\"vSphericalZ\", polynomials.z.x, polynomials.z.y, polynomials.z.z);\r\n                        ubo.updateFloat3(\"vSphericalXX_ZZ\", polynomials.xx.x - polynomials.zz.x, polynomials.xx.y - polynomials.zz.y, polynomials.xx.z - polynomials.zz.z);\r\n                        ubo.updateFloat3(\"vSphericalYY_ZZ\", polynomials.yy.x - polynomials.zz.x, polynomials.yy.y - polynomials.zz.y, polynomials.yy.z - polynomials.zz.z);\r\n                        ubo.updateFloat3(\"vSphericalZZ\", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z);\r\n                        ubo.updateFloat3(\"vSphericalXY\", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z);\r\n                        ubo.updateFloat3(\"vSphericalYZ\", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z);\r\n                        ubo.updateFloat3(\"vSphericalZX\", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);\r\n                    }\r\n                }\r\n            } else if (usePBR) {\r\n                // If we're using an irradiance map with a dominant direction assigned, set it.\r\n                if (defines.USEIRRADIANCEMAP && defines.USE_IRRADIANCE_DOMINANT_DIRECTION && reflectionTexture.irradianceTexture) {\r\n                    ubo.updateVector3(\"vReflectionDominantDirection\", reflectionTexture.irradianceTexture!._dominantDirection!);\r\n                }\r\n            }\r\n\r\n            if (supportTextureInfo) {\r\n                ubo.updateFloat3(\"vReflectionMicrosurfaceInfos\", reflectionTexture.getSize().width, reflectionTexture.lodGenerationScale, reflectionTexture.lodGenerationOffset);\r\n            }\r\n        }\r\n    }\r\n    if (useColor) {\r\n        ubo.updateColor3(\"vReflectionColor\", reflectionColor);\r\n    }\r\n}\r\n\r\n/**\r\n * Update parameters for IBL\r\n * @param scene The scene\r\n * @param defines The list of shader defines for the material\r\n * @param ubo The uniform buffer to update\r\n * @param reflectionTexture The IBL texture\r\n * @param realTimeFiltering Whether realtime filtering of IBL texture is being used\r\n */\r\nexport function BindIBLSamplers(scene: Scene, defines: any, ubo: UniformBuffer, reflectionTexture: Nullable<BaseTexture> = null, realTimeFiltering: boolean = false): void {\r\n    if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n        if (defines.LODBASEDMICROSFURACE) {\r\n            ubo.setTexture(\"reflectionSampler\", reflectionTexture);\r\n        } else {\r\n            ubo.setTexture(\"reflectionSampler\", reflectionTexture._lodTextureMid || reflectionTexture);\r\n            ubo.setTexture(\"reflectionSamplerLow\", reflectionTexture._lodTextureLow || reflectionTexture);\r\n            ubo.setTexture(\"reflectionSamplerHigh\", reflectionTexture._lodTextureHigh || reflectionTexture);\r\n        }\r\n\r\n        if (defines.USEIRRADIANCEMAP) {\r\n            ubo.setTexture(\"irradianceSampler\", reflectionTexture.irradianceTexture);\r\n        }\r\n\r\n        //if realtime filtering and using CDF maps, set them.\r\n        const cdfGenerator = scene.iblCdfGenerator;\r\n        if (realTimeFiltering && cdfGenerator) {\r\n            ubo.setTexture(\"icdfSampler\", cdfGenerator.getIcdfTexture());\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Helps preparing the defines values about the UVs in used in the effect.\r\n * UVs are shared as much as we can across channels in the shaders.\r\n * @param texture The texture we are preparing the UVs for\r\n * @param defines The defines to update\r\n * @param key The channel key \"diffuse\", \"specular\"... used in the shader\r\n */\r\nexport function PrepareDefinesForMergedUV(texture: BaseTexture, defines: any, key: string): void {\r\n    defines._needUVs = true;\r\n    defines[key] = true;\r\n    if (texture.optimizeUVAllocation && texture.getTextureMatrix().isIdentityAs3x2()) {\r\n        defines[key + \"DIRECTUV\"] = texture.coordinatesIndex + 1;\r\n        defines[\"MAINUV\" + (texture.coordinatesIndex + 1)] = true;\r\n    } else {\r\n        defines[key + \"DIRECTUV\"] = 0;\r\n    }\r\n}\r\n\r\n/**\r\n * Binds a texture matrix value to its corresponding uniform\r\n * @param texture The texture to bind the matrix for\r\n * @param uniformBuffer The uniform buffer receiving the data\r\n * @param key The channel key \"diffuse\", \"specular\"... used in the shader\r\n */\r\nexport function BindTextureMatrix(texture: BaseTexture, uniformBuffer: UniformBuffer, key: string): void {\r\n    const matrix = texture.getTextureMatrix();\r\n\r\n    uniformBuffer.updateMatrix(key + \"Matrix\", matrix);\r\n}\r\n\r\n/**\r\n * Prepares the list of attributes required for baked vertex animations according to the effect defines.\r\n * @param attribs The current list of supported attribs\r\n * @param mesh The mesh to prepare for baked vertex animations\r\n * @param defines The current Defines of the effect\r\n */\r\nexport function PrepareAttributesForBakedVertexAnimation(attribs: string[], mesh: AbstractMesh, defines: any): void {\r\n    const enabled = defines[\"BAKED_VERTEX_ANIMATION_TEXTURE\"] && defines[\"INSTANCES\"];\r\n\r\n    if (enabled) {\r\n        attribs.push(\"bakedVertexAnimationSettingsInstanced\");\r\n    }\r\n}\r\n\r\n// Copies the bones transformation matrices into the target array and returns the target's reference\r\nfunction CopyBonesTransformationMatrices(source: Float32Array, target: Float32Array): Float32Array {\r\n    target.set(source);\r\n\r\n    return target;\r\n}\r\n\r\n/**\r\n * Binds the bones information from the mesh to the effect.\r\n * @param mesh The mesh we are binding the information to render\r\n * @param effect The effect we are binding the data to\r\n * @param prePassConfiguration Configuration for the prepass, in case prepass is activated\r\n */\r\nexport function BindBonesParameters(mesh?: AbstractMesh, effect?: Effect, prePassConfiguration?: PrePassConfiguration): void {\r\n    if (!effect || !mesh) {\r\n        return;\r\n    }\r\n    if (mesh.computeBonesUsingShaders && effect._bonesComputationForcedToCPU) {\r\n        mesh.computeBonesUsingShaders = false;\r\n    }\r\n\r\n    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n        const skeleton = mesh.skeleton;\r\n\r\n        if (skeleton.isUsingTextureForMatrices && effect.getUniformIndex(\"boneTextureInfo\") > -1) {\r\n            const boneTexture = skeleton.getTransformMatrixTexture(mesh);\r\n            effect.setTexture(\"boneSampler\", boneTexture);\r\n            effect.setFloat2(\"boneTextureInfo\", skeleton._textureWidth, skeleton._textureHeight);\r\n        } else {\r\n            const matrices = skeleton.getTransformMatrices(mesh);\r\n\r\n            if (matrices) {\r\n                effect.setMatrices(\"mBones\", matrices);\r\n                if (prePassConfiguration && mesh.getScene().prePassRenderer && mesh.getScene().prePassRenderer!.getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE)) {\r\n                    if (!prePassConfiguration.previousBones[mesh.uniqueId]) {\r\n                        prePassConfiguration.previousBones[mesh.uniqueId] = matrices.slice();\r\n                    }\r\n                    effect.setMatrices(\"mPreviousBones\", prePassConfiguration.previousBones[mesh.uniqueId]);\r\n                    CopyBonesTransformationMatrices(matrices, prePassConfiguration.previousBones[mesh.uniqueId]);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Binds the light information to the effect.\r\n * @param light The light containing the generator\r\n * @param effect The effect we are binding the data to\r\n * @param lightIndex The light index in the effect used to render\r\n */\r\nexport function BindLightProperties(light: Light, effect: Effect, lightIndex: number): void {\r\n    light.transferToEffect(effect, lightIndex + \"\");\r\n}\r\n\r\n/**\r\n * Binds the lights information from the scene to the effect for the given mesh.\r\n * @param light Light to bind\r\n * @param lightIndex Light index\r\n * @param scene The scene where the light belongs to\r\n * @param effect The effect we are binding the data to\r\n * @param useSpecular Defines if specular is supported\r\n * @param receiveShadows Defines if the effect (mesh) we bind the light for receives shadows\r\n */\r\nexport function BindLight(light: Light, lightIndex: number, scene: Scene, effect: Effect, useSpecular: boolean, receiveShadows = true): void {\r\n    light._bindLight(lightIndex, scene, effect, useSpecular, receiveShadows);\r\n}\r\n\r\n/**\r\n * Uniform buffers the vertex stage binds in addition to the per-light ones: Scene, Mesh, Material and\r\n * LeftOver. Used to work out how many lights still fit within the device's per-stage uniform buffer limit.\r\n *\r\n * LeftOver is the buffer WebGPU's shader processor synthesises for uniforms declared outside of a uniform\r\n * block; it is given both vertex and fragment visibility as soon as any such uniform exists in either stage,\r\n * which is the case for virtually every material (per-light shadow matrices, logarithmicDepthConstant,\r\n * vClipPlane and so on).\r\n * It is counted unconditionally: reserving one buffer too many merely costs a light in the rare shader that\r\n * has no leftover uniforms, whereas reserving one too few brings back the black screen this guards against.\r\n */\r\nconst _NonLightVertexUniformBufferCount = 4;\r\n\r\n/** Light counts already warned about, per engine, so the warning is emitted once. */\r\nconst _LightBudgetWarnedEngines = new WeakMap<AbstractEngine, Set<number>>();\r\n\r\n/**\r\n * Returns the number of simultaneous lights the engine can actually render, which may be lower than the\r\n * requested maximum.\r\n *\r\n * Engines that declare one uniform buffer per light in the vertex shader (WebGPU, through\r\n * lightVxUboDeclaration) are bounded by maxUniformBuffersPerShaderStage: past that limit every pipeline\r\n * creation is rejected by the WebGPU validator and nothing renders at all, with only a CreateBindGroupLayout\r\n * validation error to go on. maxUniformBuffersPerShaderStage is 12 both as the WebGPU spec default and as\r\n * the maximum a D3D12 adapter reports, so it cannot be raised through requiredLimits either.\r\n * @param scene The scene that will be rendered\r\n * @param maxSimultaneousLights The requested maximum number of simultaneous lights\r\n * @returns The number of simultaneous lights supported, clamped to the engine's capabilities\r\n */\r\nexport function GetSupportedSimultaneousLights(scene: Scene, maxSimultaneousLights: number): number {\r\n    const maxUniformBuffersPerShaderStage = scene.getEngine().getCaps().maxUniformBuffersPerShaderStage;\r\n\r\n    // Engines that do not report the limit (WebGL, native) do not enforce it: leave the count untouched.\r\n    // Tested against null rather than for truthiness so that a limit of 0, however unlikely, still clamps.\r\n    if (maxUniformBuffersPerShaderStage == null) {\r\n        return maxSimultaneousLights;\r\n    }\r\n\r\n    // Keep at least one light: a scene lit by a single light is far more useful than an unlit one, and it\r\n    // matches what the device can do even with an unusually low reported limit.\r\n    const supported = Math.max(maxUniformBuffersPerShaderStage - _NonLightVertexUniformBufferCount, 1);\r\n\r\n    return Math.min(maxSimultaneousLights, supported);\r\n}\r\n\r\nfunction WarnAboutClampedLights(engine: AbstractEngine, requested: number, supported: number, lightsInUse: number): void {\r\n    let warned = _LightBudgetWarnedEngines.get(engine);\r\n    if (!warned) {\r\n        warned = new Set<number>();\r\n        _LightBudgetWarnedEngines.set(engine, warned);\r\n    }\r\n    if (warned.has(lightsInUse)) {\r\n        return;\r\n    }\r\n    warned.add(lightsInUse);\r\n\r\n    // Report the lights actually affecting the mesh, not maxSimultaneousLights: the per-light uniform buffers\r\n    // are declared per light in use, so a very high cap on a mesh with fewer lights would overstate the cost.\r\n    Logger.Warn(\r\n        `maxSimultaneousLights is ${requested} but this engine supports at most ${supported} simultaneous lights. ` +\r\n            `Each light declares its own uniform buffer in the vertex shader, so the ${lightsInUse} lights affecting this mesh plus ` +\r\n            `the scene, mesh, material and leftover buffers would need ${lightsInUse + _NonLightVertexUniformBufferCount} uniform buffers, over ` +\r\n            `the device limit of ${engine.getCaps().maxUniformBuffersPerShaderStage} per shader stage. The light count has been clamped ` +\r\n            `to ${supported}, so the extra lights will not contribute to the render. Set maxSimultaneousLights to ${supported} or less ` +\r\n            `to silence this warning.`\r\n    );\r\n}\r\n\r\n/**\r\n * Binds the lights information from the scene to the effect for the given mesh.\r\n * @param scene The scene the lights belongs to\r\n * @param mesh The mesh we are binding the information to render\r\n * @param effect The effect we are binding the data to\r\n * @param defines The generated defines for the effect\r\n * @param maxSimultaneousLights The maximum number of light that can be bound to the effect\r\n */\r\nexport function BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: any, maxSimultaneousLights = 4): void {\r\n    const len = Math.min(mesh.lightSources.length, maxSimultaneousLights);\r\n\r\n    for (let i = 0; i < len; i++) {\r\n        const light = mesh.lightSources[i];\r\n        BindLight(light, i, scene, effect, typeof defines === \"boolean\" ? defines : defines[\"SPECULARTERM\"], mesh.receiveShadows);\r\n    }\r\n}\r\n\r\n/**\r\n * Prepares the list of attributes required for bones according to the effect defines.\r\n * @param attribs The current list of supported attribs\r\n * @param mesh The mesh to prepare the bones attributes for\r\n * @param defines The current Defines of the effect\r\n * @param fallbacks The current effect fallback strategy\r\n */\r\nexport function PrepareAttributesForBones(attribs: string[], mesh: AbstractMesh, defines: any, fallbacks: EffectFallbacks): void {\r\n    if (defines[\"NUM_BONE_INFLUENCERS\"] > 0) {\r\n        fallbacks.addCPUSkinningFallback(0, mesh);\r\n\r\n        attribs.push(Constants.MatricesIndicesKind);\r\n        attribs.push(Constants.MatricesWeightsKind);\r\n        if (defines[\"NUM_BONE_INFLUENCERS\"] > 4) {\r\n            attribs.push(Constants.MatricesIndicesExtraKind);\r\n            attribs.push(Constants.MatricesWeightsExtraKind);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Check and prepare the list of attributes required for instances according to the effect defines.\r\n * @param attribs The current list of supported attribs\r\n * @param defines The current MaterialDefines of the effect\r\n */\r\nexport function PrepareAttributesForInstances(attribs: string[], defines: MaterialDefines): void {\r\n    if (defines[\"INSTANCES\"] || defines[\"THIN_INSTANCES\"]) {\r\n        PushAttributesForInstances(attribs, !!defines[\"PREPASS_VELOCITY\"]);\r\n    }\r\n\r\n    if (defines.INSTANCESCOLOR) {\r\n        attribs.push(Constants.ColorInstanceKind);\r\n    }\r\n}\r\n\r\n/**\r\n * This helps decreasing rank by rank the shadow quality (0 being the highest rank and quality)\r\n * @param defines The defines to update while falling back\r\n * @param fallbacks The authorized effect fallbacks\r\n * @param maxSimultaneousLights The maximum number of lights allowed\r\n * @param rank the current rank of the Effect\r\n * @returns The newly affected rank\r\n */\r\nexport function HandleFallbacksForShadows(defines: any, fallbacks: EffectFallbacks, maxSimultaneousLights = 4, rank = 0): number {\r\n    let lightFallbackRank = 0;\r\n    for (let lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {\r\n        if (!defines[\"LIGHT\" + lightIndex]) {\r\n            break;\r\n        }\r\n\r\n        if (lightIndex > 0) {\r\n            lightFallbackRank = rank + lightIndex;\r\n            fallbacks.addFallback(lightFallbackRank, \"LIGHT\" + lightIndex);\r\n        }\r\n\r\n        if (!defines[\"SHADOWS\"]) {\r\n            if (defines[\"SHADOW\" + lightIndex]) {\r\n                fallbacks.addFallback(rank, \"SHADOW\" + lightIndex);\r\n            }\r\n\r\n            if (defines[\"SHADOWPCF\" + lightIndex]) {\r\n                fallbacks.addFallback(rank, \"SHADOWPCF\" + lightIndex);\r\n            }\r\n\r\n            if (defines[\"SHADOWPCSS\" + lightIndex]) {\r\n                fallbacks.addFallback(rank, \"SHADOWPCSS\" + lightIndex);\r\n            }\r\n\r\n            if (defines[\"SHADOWPOISSON\" + lightIndex]) {\r\n                fallbacks.addFallback(rank, \"SHADOWPOISSON\" + lightIndex);\r\n            }\r\n\r\n            if (defines[\"SHADOWESM\" + lightIndex]) {\r\n                fallbacks.addFallback(rank, \"SHADOWESM\" + lightIndex);\r\n            }\r\n\r\n            if (defines[\"SHADOWCLOSEESM\" + lightIndex]) {\r\n                fallbacks.addFallback(rank, \"SHADOWCLOSEESM\" + lightIndex);\r\n            }\r\n        }\r\n    }\r\n    return lightFallbackRank;\r\n}\r\n\r\n/**\r\n * Gets the current status of the fog (should it be enabled?)\r\n * @param mesh defines the mesh to evaluate for fog support\r\n * @param scene defines the hosting scene\r\n * @returns true if fog must be enabled\r\n */\r\nexport function GetFogState(mesh: AbstractMesh, scene: Scene) {\r\n    return scene.fogEnabled && mesh.applyFog && scene.fogMode !== Constants.FOGMODE_NONE;\r\n}\r\n\r\n/**\r\n * Helper used to prepare the list of defines associated with misc. values for shader compilation\r\n * @param mesh defines the current mesh\r\n * @param scene defines the current scene\r\n * @param useLogarithmicDepth defines if logarithmic depth has to be turned on\r\n * @param pointsCloud defines if point cloud rendering has to be turned on\r\n * @param fogEnabled defines if fog has to be turned on\r\n * @param alphaTest defines if alpha testing has to be turned on\r\n * @param defines defines the current list of defines\r\n * @param applyDecalAfterDetail Defines if the decal is applied after or before the detail\r\n * @param useVertexPulling Defines if vertex pulling is used\r\n * @param renderingMesh The mesh used for rendering\r\n * @param setVertexOutputInvariant Defines if the vertex output should be invariant\r\n */\r\nexport function PrepareDefinesForMisc(\r\n    mesh: AbstractMesh,\r\n    scene: Scene,\r\n    useLogarithmicDepth: boolean,\r\n    pointsCloud: boolean,\r\n    fogEnabled: boolean,\r\n    alphaTest: boolean,\r\n    defines: any,\r\n    applyDecalAfterDetail: boolean = false,\r\n    useVertexPulling: boolean = false,\r\n    renderingMesh?: AbstractMesh,\r\n    setVertexOutputInvariant?: boolean\r\n): void {\r\n    if (defines._areMiscDirty) {\r\n        defines[\"LOGARITHMICDEPTH\"] = useLogarithmicDepth;\r\n        defines[\"POINTSIZE\"] = pointsCloud;\r\n        defines[\"FOG\"] = fogEnabled && GetFogState(mesh, scene);\r\n        defines[\"NONUNIFORMSCALING\"] = mesh.nonUniformScaling;\r\n        defines[\"ALPHATEST\"] = alphaTest;\r\n        defines[\"DECAL_AFTER_DETAIL\"] = applyDecalAfterDetail;\r\n        defines[\"USE_VERTEX_PULLING\"] = useVertexPulling;\r\n        defines[\"RIGHT_HANDED\"] = scene.useRightHandedSystem;\r\n\r\n        const indexBuffer = renderingMesh?.geometry?.getIndexBuffer();\r\n        const isUnIndexed = renderingMesh ? (renderingMesh as any).isUnIndexed : false;\r\n\r\n        defines[\"VERTEX_PULLING_USE_INDEX_BUFFER\"] = !!indexBuffer && !isUnIndexed;\r\n        defines[\"VERTEX_PULLING_INDEX_BUFFER_32BITS\"] = indexBuffer && !isUnIndexed ? indexBuffer.is32Bits : false;\r\n\r\n        defines[\"VERTEXOUTPUT_INVARIANT\"] = !!setVertexOutputInvariant;\r\n    }\r\n}\r\n\r\n/**\r\n * Checks whether the texture resources used by the lights that will affect the given mesh are ready.\r\n * This mirrors the light iteration performed by {@link PrepareDefinesForLights} and {@link BindLights}:\r\n * it only considers lights that can affect the mesh (already filtered into `mesh.lightSources`)\r\n * and respects the material's `maxSimultaneousLights` cap and the `disableLighting` flag.\r\n * @param scene The scene the mesh belongs to\r\n * @param mesh The mesh to check\r\n * @param maxSimultaneousLights The material's max simultaneous lights cap\r\n * @param disableLighting Whether lighting is disabled for the material\r\n * @returns true if all affecting lights report their textures are ready\r\n */\r\nexport function AreLightsTexturesReady(scene: Scene, mesh: AbstractMesh, maxSimultaneousLights: number, disableLighting = false): boolean {\r\n    if (!scene.lightsEnabled || disableLighting) {\r\n        return true;\r\n    }\r\n    const lights = mesh.lightSources;\r\n    const count = Math.min(lights.length, maxSimultaneousLights);\r\n    for (let i = 0; i < count; i++) {\r\n        if (!lights[i].areLightTexturesReady()) {\r\n            return false;\r\n        }\r\n    }\r\n    return true;\r\n}\r\n\r\n/**\r\n * Prepares the defines related to the light information passed in parameter\r\n * @param scene The scene we are intending to draw\r\n * @param mesh The mesh the effect is compiling for\r\n * @param defines The defines to update\r\n * @param specularSupported Specifies whether specular is supported or not (override lights data)\r\n * @param maxSimultaneousLights Specifies how manuy lights can be added to the effect at max\r\n * @param disableLighting Specifies whether the lighting is disabled (override scene and light)\r\n * @returns true if normals will be required for the rest of the effect\r\n */\r\nexport function PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: any, specularSupported: boolean, maxSimultaneousLights = 4, disableLighting = false): boolean {\r\n    if (!defines._areLightsDirty) {\r\n        return defines._needNormals;\r\n    }\r\n\r\n    // Some engines cannot render as many lights as requested (see GetSupportedSimultaneousLights). Clamp the\r\n    // count so the scene renders with fewer lights, rather than failing pipeline creation and rendering nothing.\r\n    const requestedSimultaneousLights = maxSimultaneousLights;\r\n    maxSimultaneousLights = GetSupportedSimultaneousLights(scene, maxSimultaneousLights);\r\n\r\n    let lightIndex = 0;\r\n    const state = {\r\n        needNormals: defines._needNormals, // prevents overriding previous reflection or other needs for normals\r\n        needRebuild: false,\r\n        lightmapMode: false,\r\n        shadowEnabled: false,\r\n        specularEnabled: false,\r\n    };\r\n\r\n    if (scene.lightsEnabled && !disableLighting) {\r\n        // Only worth telling the user about the clamp when lights are actually being dropped because of it:\r\n        // the per-light uniform buffers are declared per light in use, not per maxSimultaneousLights.\r\n        if (mesh.lightSources.length > maxSimultaneousLights && maxSimultaneousLights < requestedSimultaneousLights) {\r\n            WarnAboutClampedLights(scene.getEngine(), requestedSimultaneousLights, maxSimultaneousLights, Math.min(mesh.lightSources.length, requestedSimultaneousLights));\r\n        }\r\n\r\n        for (const light of mesh.lightSources) {\r\n            PrepareDefinesForLight(scene, mesh, light, lightIndex, defines, specularSupported, state);\r\n\r\n            lightIndex++;\r\n            if (lightIndex === maxSimultaneousLights) {\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    defines[\"SPECULARTERM\"] = state.specularEnabled;\r\n    defines[\"SHADOWS\"] = state.shadowEnabled;\r\n\r\n    // Resetting all other lights if any\r\n    const maxLightCount = Math.max(maxSimultaneousLights, defines[\"MAXLIGHTCOUNT\"] || 0);\r\n\r\n    for (let index = lightIndex; index < maxLightCount; index++) {\r\n        if (defines[\"LIGHT\" + index] !== undefined) {\r\n            defines[\"LIGHT\" + index] = false;\r\n            defines[\"HEMILIGHT\" + index] = false;\r\n            defines[\"POINTLIGHT\" + index] = false;\r\n            defines[\"DIRLIGHT\" + index] = false;\r\n            defines[\"SPOTLIGHT\" + index] = false;\r\n            defines[\"AREALIGHT\" + index] = false;\r\n            defines[\"CLUSTLIGHT\" + index] = false;\r\n            defines[\"SHADOW\" + index] = false;\r\n            defines[\"SHADOWCSM\" + index] = false;\r\n            defines[\"SHADOWCSMDEBUG\" + index] = false;\r\n            defines[\"SHADOWCSMNUM_CASCADES\" + index] = false;\r\n            defines[\"SHADOWCSMUSESHADOWMAXZ\" + index] = false;\r\n            defines[\"SHADOWCSMNOBLEND\" + index] = false;\r\n            defines[\"SHADOWCSM_RIGHTHANDED\" + index] = false;\r\n            defines[\"SHADOWPCF\" + index] = false;\r\n            defines[\"SHADOWPCSS\" + index] = false;\r\n            defines[\"SHADOWPOISSON\" + index] = false;\r\n            defines[\"SHADOWESM\" + index] = false;\r\n            defines[\"SHADOWCLOSEESM\" + index] = false;\r\n            defines[\"SHADOWCUBE\" + index] = false;\r\n            defines[\"SHADOWLOWQUALITY\" + index] = false;\r\n            defines[\"SHADOWMEDIUMQUALITY\" + index] = false;\r\n        }\r\n    }\r\n    defines[\"LIGHTCOUNT\"] = lightIndex;\r\n    defines[\"MAXLIGHTCOUNT\"] = maxSimultaneousLights;\r\n\r\n    const caps = scene.getEngine().getCaps();\r\n\r\n    if (defines[\"SHADOWFLOAT\"] === undefined) {\r\n        state.needRebuild = true;\r\n    }\r\n\r\n    defines[\"SHADOWFLOAT\"] =\r\n        state.shadowEnabled && ((caps.textureFloatRender && caps.textureFloatLinearFiltering) || (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering));\r\n    defines[\"LIGHTMAPEXCLUDED\"] = state.lightmapMode;\r\n\r\n    if (state.needRebuild) {\r\n        defines.rebuild();\r\n    }\r\n\r\n    return state.needNormals;\r\n}\r\n\r\n/**\r\n * Prepare defines relating to IBL logic.\r\n * @param scene The scene\r\n * @param reflectionTexture The texture to use for IBL\r\n * @param defines The defines to update\r\n * @param realTimeFiltering Whether realtime filting of IBL texture is being used\r\n * @param realTimeFilteringQuality The quality of realtime filtering\r\n * @param forceSHInVertex Whether the SH are handled in the vertex shader\r\n * @returns true if the defines were updated\r\n */\r\nexport function PrepareDefinesForIBL(\r\n    scene: Scene,\r\n    reflectionTexture: Nullable<BaseTexture>,\r\n    defines: any,\r\n    realTimeFiltering: boolean = false,\r\n    realTimeFilteringQuality: number = Constants.TEXTURE_FILTERING_QUALITY_LOW,\r\n    forceSHInVertex: boolean = false\r\n): boolean {\r\n    if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n        if (!reflectionTexture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n        defines._needNormals = true;\r\n        defines.REFLECTION = true;\r\n        defines.GAMMAREFLECTION = reflectionTexture.gammaSpace;\r\n        defines.RGBDREFLECTION = reflectionTexture.isRGBD;\r\n        defines.LODINREFLECTIONALPHA = reflectionTexture.lodLevelInAlpha;\r\n        defines.LINEARSPECULARREFLECTION = reflectionTexture.linearSpecularLOD;\r\n        defines.USEIRRADIANCEMAP = false;\r\n        defines.LODBASEDMICROSFURACE = scene.getEngine().getCaps().textureLOD;\r\n\r\n        const engine = scene.getEngine();\r\n        if (realTimeFiltering && realTimeFilteringQuality > 0) {\r\n            defines.NUM_SAMPLES = \"\" + realTimeFilteringQuality;\r\n            if (engine._features.needTypeSuffixInShaderConstants) {\r\n                defines.NUM_SAMPLES = defines.NUM_SAMPLES + \"u\";\r\n            }\r\n\r\n            defines.REALTIME_FILTERING = true;\r\n            if (scene.iblCdfGenerator) {\r\n                defines.IBL_CDF_FILTERING = true;\r\n            }\r\n        } else {\r\n            defines.REALTIME_FILTERING = false;\r\n        }\r\n\r\n        defines.INVERTCUBICMAP = reflectionTexture.coordinatesMode === Constants.TEXTURE_INVCUBIC_MODE;\r\n        defines.REFLECTIONMAP_3D = reflectionTexture.isCube;\r\n        defines.REFLECTIONMAP_OPPOSITEZ = defines.REFLECTIONMAP_3D && scene.useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ;\r\n\r\n        defines.REFLECTIONMAP_CUBIC = false;\r\n        defines.REFLECTIONMAP_EXPLICIT = false;\r\n        defines.REFLECTIONMAP_PLANAR = false;\r\n        defines.REFLECTIONMAP_PROJECTION = false;\r\n        defines.REFLECTIONMAP_SKYBOX = false;\r\n        defines.REFLECTIONMAP_SPHERICAL = false;\r\n        defines.REFLECTIONMAP_EQUIRECTANGULAR = false;\r\n        defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;\r\n        defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;\r\n\r\n        switch (reflectionTexture.coordinatesMode) {\r\n            case Constants.TEXTURE_EXPLICIT_MODE:\r\n                defines.REFLECTIONMAP_EXPLICIT = true;\r\n                break;\r\n            case Constants.TEXTURE_PLANAR_MODE:\r\n                defines.REFLECTIONMAP_PLANAR = true;\r\n                break;\r\n            case Constants.TEXTURE_PROJECTION_MODE:\r\n                defines.REFLECTIONMAP_PROJECTION = true;\r\n                break;\r\n            case Constants.TEXTURE_SKYBOX_MODE:\r\n                defines.REFLECTIONMAP_SKYBOX = true;\r\n                break;\r\n            case Constants.TEXTURE_SPHERICAL_MODE:\r\n                defines.REFLECTIONMAP_SPHERICAL = true;\r\n                break;\r\n            case Constants.TEXTURE_EQUIRECTANGULAR_MODE:\r\n                defines.REFLECTIONMAP_EQUIRECTANGULAR = true;\r\n                break;\r\n            case Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE:\r\n                defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;\r\n                break;\r\n            case Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE:\r\n                defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = true;\r\n                break;\r\n            case Constants.TEXTURE_CUBIC_MODE:\r\n            case Constants.TEXTURE_INVCUBIC_MODE:\r\n            default:\r\n                defines.REFLECTIONMAP_CUBIC = true;\r\n                defines.USE_LOCAL_REFLECTIONMAP_CUBIC = (<any>reflectionTexture).boundingBoxSize ? true : false;\r\n                break;\r\n        }\r\n\r\n        if (reflectionTexture.coordinatesMode !== Constants.TEXTURE_SKYBOX_MODE) {\r\n            if (reflectionTexture.irradianceTexture) {\r\n                defines.USEIRRADIANCEMAP = true;\r\n                defines.USESPHERICALFROMREFLECTIONMAP = false;\r\n                defines.USESPHERICALINVERTEX = false;\r\n                if (reflectionTexture.irradianceTexture._dominantDirection) {\r\n                    defines.USE_IRRADIANCE_DOMINANT_DIRECTION = true;\r\n                } else {\r\n                    defines.USE_IRRADIANCE_DOMINANT_DIRECTION = false;\r\n                }\r\n            }\r\n            // Assume using spherical polynomial if the reflection texture is a cube map\r\n            else if (reflectionTexture.isCube) {\r\n                defines.USESPHERICALFROMREFLECTIONMAP = true;\r\n                defines.USEIRRADIANCEMAP = false;\r\n                defines.USE_IRRADIANCE_DOMINANT_DIRECTION = false;\r\n                defines.USESPHERICALINVERTEX = forceSHInVertex;\r\n            }\r\n        }\r\n    } else {\r\n        defines.REFLECTION = false;\r\n        defines.REFLECTIONMAP_3D = false;\r\n        defines.REFLECTIONMAP_SPHERICAL = false;\r\n        defines.REFLECTIONMAP_PLANAR = false;\r\n        defines.REFLECTIONMAP_CUBIC = false;\r\n        defines.USE_LOCAL_REFLECTIONMAP_CUBIC = false;\r\n        defines.REFLECTIONMAP_PROJECTION = false;\r\n        defines.REFLECTIONMAP_SKYBOX = false;\r\n        defines.REFLECTIONMAP_EXPLICIT = false;\r\n        defines.REFLECTIONMAP_EQUIRECTANGULAR = false;\r\n        defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;\r\n        defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;\r\n        defines.INVERTCUBICMAP = false;\r\n        defines.USESPHERICALFROMREFLECTIONMAP = false;\r\n        defines.USEIRRADIANCEMAP = false;\r\n        defines.USE_IRRADIANCE_DOMINANT_DIRECTION = false;\r\n        defines.USESPHERICALINVERTEX = false;\r\n        defines.REFLECTIONMAP_OPPOSITEZ = false;\r\n        defines.LODINREFLECTIONALPHA = false;\r\n        defines.GAMMAREFLECTION = false;\r\n        defines.RGBDREFLECTION = false;\r\n        defines.LINEARSPECULARREFLECTION = false;\r\n    }\r\n    return true;\r\n}\r\n\r\n/**\r\n * Prepares the defines related to the light information passed in parameter\r\n * @param scene The scene we are intending to draw\r\n * @param mesh The mesh the effect is compiling for\r\n * @param light The light the effect is compiling for\r\n * @param lightIndex The index of the light\r\n * @param defines The defines to update\r\n * @param specularSupported Specifies whether specular is supported or not (override lights data)\r\n * @param state Defines the current state regarding what is needed (normals, etc...)\r\n * @param state.needNormals\r\n * @param state.needRebuild\r\n * @param state.shadowEnabled\r\n * @param state.specularEnabled\r\n * @param state.lightmapMode\r\n */\r\nexport function PrepareDefinesForLight(\r\n    scene: Scene,\r\n    mesh: AbstractMesh,\r\n    light: Light,\r\n    lightIndex: number,\r\n    defines: any,\r\n    specularSupported: boolean,\r\n    state: {\r\n        needNormals: boolean;\r\n        needRebuild: boolean;\r\n        shadowEnabled: boolean;\r\n        specularEnabled: boolean;\r\n        lightmapMode: boolean;\r\n    }\r\n) {\r\n    state.needNormals = true;\r\n\r\n    if (defines[\"LIGHT\" + lightIndex] === undefined) {\r\n        state.needRebuild = true;\r\n    }\r\n\r\n    defines[\"LIGHT\" + lightIndex] = true;\r\n\r\n    defines[\"SPOTLIGHT\" + lightIndex] = false;\r\n    defines[\"HEMILIGHT\" + lightIndex] = false;\r\n    defines[\"POINTLIGHT\" + lightIndex] = false;\r\n    defines[\"DIRLIGHT\" + lightIndex] = false;\r\n    defines[\"AREALIGHT\" + lightIndex] = false;\r\n    defines[\"CLUSTLIGHT\" + lightIndex] = false;\r\n\r\n    light.prepareLightSpecificDefines(defines, lightIndex);\r\n\r\n    // FallOff.\r\n    defines[\"LIGHT_FALLOFF_PHYSICAL\" + lightIndex] = false;\r\n    defines[\"LIGHT_FALLOFF_GLTF\" + lightIndex] = false;\r\n    defines[\"LIGHT_FALLOFF_STANDARD\" + lightIndex] = false;\r\n\r\n    switch (light.falloffType) {\r\n        case LightConstants.FALLOFF_GLTF:\r\n            defines[\"LIGHT_FALLOFF_GLTF\" + lightIndex] = true;\r\n            break;\r\n        case LightConstants.FALLOFF_PHYSICAL:\r\n            defines[\"LIGHT_FALLOFF_PHYSICAL\" + lightIndex] = true;\r\n            break;\r\n        case LightConstants.FALLOFF_STANDARD:\r\n            defines[\"LIGHT_FALLOFF_STANDARD\" + lightIndex] = true;\r\n            break;\r\n    }\r\n\r\n    // Specular\r\n    if (specularSupported && !light.specular.equalsFloats(0, 0, 0)) {\r\n        state.specularEnabled = true;\r\n    }\r\n\r\n    // Shadows\r\n    defines[\"SHADOW\" + lightIndex] = false;\r\n    defines[\"SHADOWCSM\" + lightIndex] = false;\r\n    defines[\"SHADOWCSMDEBUG\" + lightIndex] = false;\r\n    defines[\"SHADOWCSMNUM_CASCADES\" + lightIndex] = false;\r\n    defines[\"SHADOWCSMUSESHADOWMAXZ\" + lightIndex] = false;\r\n    defines[\"SHADOWCSMNOBLEND\" + lightIndex] = false;\r\n    defines[\"SHADOWCSM_RIGHTHANDED\" + lightIndex] = false;\r\n    defines[\"SHADOWPCF\" + lightIndex] = false;\r\n    defines[\"SHADOWPCSS\" + lightIndex] = false;\r\n    defines[\"SHADOWPOISSON\" + lightIndex] = false;\r\n    defines[\"SHADOWESM\" + lightIndex] = false;\r\n    defines[\"SHADOWCLOSEESM\" + lightIndex] = false;\r\n    defines[\"SHADOWCUBE\" + lightIndex] = false;\r\n    defines[\"SHADOWLOWQUALITY\" + lightIndex] = false;\r\n    defines[\"SHADOWMEDIUMQUALITY\" + lightIndex] = false;\r\n\r\n    if (mesh && mesh.receiveShadows && scene.shadowsEnabled && light.shadowEnabled) {\r\n        const shadowGenerator = light.getShadowGenerator(scene.activeCamera) ?? light.getShadowGenerator();\r\n        if (shadowGenerator) {\r\n            const shadowMap = shadowGenerator.getShadowMap();\r\n            if (shadowMap) {\r\n                if (shadowMap.renderList && shadowMap.renderList.length > 0) {\r\n                    state.shadowEnabled = true;\r\n                    shadowGenerator.prepareDefines(defines, lightIndex);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    if (light.lightmapMode != LightConstants.LIGHTMAP_DEFAULT) {\r\n        state.lightmapMode = true;\r\n        defines[\"LIGHTMAPEXCLUDED\" + lightIndex] = true;\r\n        defines[\"LIGHTMAPNOSPECULAR\" + lightIndex] = light.lightmapMode == LightConstants.LIGHTMAP_SHADOWSONLY;\r\n    } else {\r\n        defines[\"LIGHTMAPEXCLUDED\" + lightIndex] = false;\r\n        defines[\"LIGHTMAPNOSPECULAR\" + lightIndex] = false;\r\n    }\r\n}\r\n\r\n/**\r\n * Helper used to prepare the list of defines associated with frame values for shader compilation\r\n * @param scene defines the current scene\r\n * @param engine defines the current engine\r\n * @param material defines the material we are compiling the shader for\r\n * @param defines specifies the list of active defines\r\n * @param useInstances defines if instances have to be turned on\r\n * @param useClipPlane defines if clip plane have to be turned on\r\n * @param useThinInstances defines if thin instances have to be turned on\r\n */\r\nexport function PrepareDefinesForFrameBoundValues(\r\n    scene: Scene,\r\n    engine: AbstractEngine,\r\n    material: Material,\r\n    defines: any,\r\n    useInstances: boolean,\r\n    useClipPlane: Nullable<boolean> = null,\r\n    useThinInstances: boolean = false\r\n): void {\r\n    let changed = PrepareDefinesForCamera(scene, defines);\r\n\r\n    if (useClipPlane !== false) {\r\n        changed = PrepareDefinesForClipPlanes(material, scene, defines);\r\n    }\r\n\r\n    if (defines[\"DEPTHPREPASS\"] !== !engine.getColorWrite()) {\r\n        defines[\"DEPTHPREPASS\"] = !defines[\"DEPTHPREPASS\"];\r\n        changed = true;\r\n    }\r\n\r\n    if (defines[\"INSTANCES\"] !== useInstances) {\r\n        defines[\"INSTANCES\"] = useInstances;\r\n        changed = true;\r\n    }\r\n\r\n    if (defines[\"THIN_INSTANCES\"] !== useThinInstances) {\r\n        defines[\"THIN_INSTANCES\"] = useThinInstances;\r\n        changed = true;\r\n    }\r\n\r\n    if (changed) {\r\n        defines.markAsUnprocessed();\r\n    }\r\n}\r\n\r\n// Sizing the bone-uniform budget reserves room for the rest of the vertex stage (base uniforms +\r\n// plugins + clip planes), mirroring GetGaussianSplattingMaxPartCount's reserve. Multiview duplicates\r\n// the per-eye view/projection, so it reserves more.\r\nconst _BoneUniformBaseReserve = 40;\r\nconst _BoneUniformMultiviewReserve = 64;\r\n// PrepareDefinesForBones is on the defines-evaluation hot path, so the budget diagnostic only\r\n// re-evaluates when its inputs change for a skeleton: the WeakMap stores the last-seen signature\r\n// (bone count + multiview bit) and the steady-state cost is one lookup plus an integer compare.\r\nconst _BoneUniformBudgetCheckedSignature = new WeakMap<object, number>();\r\n// The diagnostic logs once PER SKELETON: its message varies by skeleton/bone-count/caps/multiview,\r\n// so Logger's per-message limit would not dedupe it. Weak collections let disposed skeletons be GC'd.\r\nconst _BoneUniformBudgetWarnedSkeletons = new WeakSet<object>();\r\n\r\n/**\r\n * Prepares the defines for bones\r\n * @param mesh The mesh containing the geometry data we will draw\r\n * @param defines The defines to update\r\n */\r\nexport function PrepareDefinesForBones(mesh: AbstractMesh, defines: any) {\r\n    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n        defines[\"NUM_BONE_INFLUENCERS\"] = mesh.numBoneInfluencers;\r\n\r\n        const materialSupportsBoneTexture = defines[\"BONETEXTURE\"] !== undefined;\r\n\r\n        if (mesh.skeleton.isUsingTextureForMatrices && materialSupportsBoneTexture) {\r\n            defines[\"BONETEXTURE\"] = true;\r\n        } else {\r\n            defines[\"BonesPerMesh\"] = mesh.skeleton.bones.length + 1;\r\n            defines[\"BONETEXTURE\"] = materialSupportsBoneTexture ? false : undefined;\r\n\r\n            const scene = mesh.getScene();\r\n            const prePassRenderer = scene.prePassRenderer;\r\n            if (prePassRenderer && prePassRenderer.enabled) {\r\n                const nonExcluded = prePassRenderer.excludedSkinnedMesh.indexOf(mesh) === -1;\r\n                defines[\"BONES_VELOCITY_ENABLED\"] = nonExcluded;\r\n            }\r\n\r\n            // Bones stored as vertex uniforms cost one mat4 (4 vectors) each, drawn from the same\r\n            // maxVertexUniformVectors budget as the rest of the vertex stage. Some drivers fail SILENTLY\r\n            // when a program exceeds that budget — the skinned mesh just never renders, with no error or\r\n            // warning (see Babylon's \"A Mysterious Case of Skinned Mesh Disappearances\"). Multiview is the\r\n            // common trigger: it duplicates per-eye matrices and adds driver overhead, shrinking the\r\n            // practical budget below what the device reports.\r\n            //\r\n            // Hot-path note: everything below the signature gate runs only when the inputs change for\r\n            // this skeleton (bone count or MULTIVIEW — already set on the defines by\r\n            // PrepareDefinesForFrameBoundValues, which materials run before the attributes/bones\r\n            // prepare). Steady-state cost: one WeakMap lookup and an integer compare.\r\n            const isMultiview = defines[\"MULTIVIEW\"] === true;\r\n            const signature = defines[\"BonesPerMesh\"] * 2 + (isMultiview ? 1 : 0);\r\n            if (_BoneUniformBudgetCheckedSignature.get(mesh.skeleton) !== signature) {\r\n                _BoneUniformBudgetCheckedSignature.set(mesh.skeleton, signature);\r\n                const maxVertexUniformVectors = scene.getEngine().getCaps().maxVertexUniformVectors;\r\n                if (maxVertexUniformVectors && !_BoneUniformBudgetWarnedSkeletons.has(mesh.skeleton)) {\r\n                    const boneUniformVectors = defines[\"BonesPerMesh\"] * 4;\r\n                    const reservedVertexUniforms = isMultiview ? _BoneUniformMultiviewReserve : _BoneUniformBaseReserve;\r\n                    const available = Math.max(maxVertexUniformVectors - reservedVertexUniforms, 0);\r\n                    // Overflow the budget outright, or — under multiview, where the practical budget is\r\n                    // smaller than reported — merely dominate it (bones alone are a third or more of nominal).\r\n                    if (boneUniformVectors > available || (isMultiview && boneUniformVectors * 3 > maxVertexUniformVectors)) {\r\n                        _BoneUniformBudgetWarnedSkeletons.add(mesh.skeleton);\r\n                        Logger.Warn(\r\n                            `Skeleton \"${mesh.skeleton.name}\": ${mesh.skeleton.bones.length} bones stored as vertex uniforms use ` +\r\n                                `${boneUniformVectors} of ~${available} usable uniform vectors${isMultiview ? \" (multiview)\" : \"\"} on a ` +\r\n                                `device reporting ${maxVertexUniformVectors}. This can exceed the GPU vertex-uniform limit and make the ` +\r\n                                `mesh silently fail to render. Set skeleton.useTextureToStoreBoneMatrices = true to store bone matrices in a texture.`\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    } else {\r\n        defines[\"NUM_BONE_INFLUENCERS\"] = 0;\r\n        defines[\"BonesPerMesh\"] = 0;\r\n        if (defines[\"BONETEXTURE\"] !== undefined) {\r\n            defines[\"BONETEXTURE\"] = false;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Prepares the defines for morph targets\r\n * @param mesh The mesh containing the geometry data we will draw\r\n * @param defines The defines to update\r\n */\r\nexport function PrepareDefinesForMorphTargets(mesh: AbstractMesh, defines: any) {\r\n    const manager = (<Mesh>mesh).morphTargetManager;\r\n    if (manager) {\r\n        defines[\"MORPHTARGETS_UV\"] = manager.supportsUVs && defines[\"UV1\"];\r\n        defines[\"MORPHTARGETS_UV2\"] = manager.supportsUV2s && defines[\"UV2\"];\r\n        defines[\"MORPHTARGETS_TANGENT\"] = manager.supportsTangents && defines[\"TANGENT\"];\r\n        defines[\"MORPHTARGETS_NORMAL\"] = manager.supportsNormals && defines[\"NORMAL\"];\r\n        defines[\"MORPHTARGETS_POSITION\"] = manager.supportsPositions;\r\n        defines[\"MORPHTARGETS_COLOR\"] = manager.supportsColors;\r\n\r\n        defines[\"MORPHTARGETTEXTURE_HASUVS\"] = manager.hasUVs;\r\n        defines[\"MORPHTARGETTEXTURE_HASUV2S\"] = manager.hasUV2s;\r\n        defines[\"MORPHTARGETTEXTURE_HASTANGENTS\"] = manager.hasTangents;\r\n        defines[\"MORPHTARGETTEXTURE_HASNORMALS\"] = manager.hasNormals;\r\n        defines[\"MORPHTARGETTEXTURE_HASPOSITIONS\"] = manager.hasPositions;\r\n        defines[\"MORPHTARGETTEXTURE_HASCOLORS\"] = manager.hasColors;\r\n\r\n        defines[\"NUM_MORPH_INFLUENCERS\"] = manager.numMaxInfluencers || manager.numInfluencers;\r\n        defines[\"MORPHTARGETS\"] = defines[\"NUM_MORPH_INFLUENCERS\"] > 0;\r\n\r\n        defines[\"MORPHTARGETS_TEXTURE\"] = manager.isUsingTextureForTargets;\r\n    } else {\r\n        defines[\"MORPHTARGETS_UV\"] = false;\r\n        defines[\"MORPHTARGETS_UV2\"] = false;\r\n        defines[\"MORPHTARGETS_TANGENT\"] = false;\r\n        defines[\"MORPHTARGETS_NORMAL\"] = false;\r\n        defines[\"MORPHTARGETS_POSITION\"] = false;\r\n        defines[\"MORPHTARGETS_COLOR\"] = false;\r\n\r\n        defines[\"MORPHTARGETTEXTURE_HASUVS\"] = false;\r\n        defines[\"MORPHTARGETTEXTURE_HASUV2S\"] = false;\r\n        defines[\"MORPHTARGETTEXTURE_HASTANGENTS\"] = false;\r\n        defines[\"MORPHTARGETTEXTURE_HASNORMALS\"] = false;\r\n        defines[\"MORPHTARGETTEXTURE_HASPOSITIONS\"] = false;\r\n        defines[\"MORPHTARGETTEXTURE_HAS_COLORS\"] = false;\r\n\r\n        defines[\"MORPHTARGETS\"] = false;\r\n        defines[\"NUM_MORPH_INFLUENCERS\"] = 0;\r\n    }\r\n}\r\n\r\n/**\r\n * Prepares the defines for baked vertex animation\r\n * @param mesh The mesh containing the geometry data we will draw\r\n * @param defines The defines to update\r\n */\r\nexport function PrepareDefinesForBakedVertexAnimation(mesh: AbstractMesh, defines: any) {\r\n    const manager = (<Mesh>mesh).bakedVertexAnimationManager;\r\n    defines[\"BAKED_VERTEX_ANIMATION_TEXTURE\"] = manager && manager.isEnabled ? true : false;\r\n}\r\n\r\n/**\r\n * Prepares the defines used in the shader depending on the attributes data available in the mesh\r\n * @param mesh The mesh containing the geometry data we will draw\r\n * @param defines The defines to update\r\n * @param useVertexColor Precise whether vertex colors should be used or not (override mesh info)\r\n * @param useBones Precise whether bones should be used or not (override mesh info)\r\n * @param useMorphTargets Precise whether morph targets should be used or not (override mesh info)\r\n * @param useVertexAlpha Precise whether vertex alpha should be used or not (override mesh info)\r\n * @param useBakedVertexAnimation Precise whether baked vertex animation should be used or not (override mesh info)\r\n * @returns false if defines are considered not dirty and have not been checked\r\n */\r\nexport function PrepareDefinesForAttributes(\r\n    mesh: AbstractMesh,\r\n    defines: any,\r\n    useVertexColor: boolean,\r\n    useBones: boolean,\r\n    useMorphTargets = false,\r\n    useVertexAlpha = true,\r\n    useBakedVertexAnimation = true\r\n): boolean {\r\n    if (!defines._areAttributesDirty && defines._needNormals === defines._normals && defines._needUVs === defines._uvs) {\r\n        return false;\r\n    }\r\n\r\n    defines._normals = defines._needNormals;\r\n    defines._uvs = defines._needUVs;\r\n\r\n    defines[\"NORMAL\"] = defines._needNormals && mesh.isVerticesDataPresent(Constants.NormalKind);\r\n\r\n    if (defines._needNormals && mesh.isVerticesDataPresent(Constants.TangentKind)) {\r\n        defines[\"TANGENT\"] = true;\r\n    }\r\n\r\n    for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n        defines[\"UV\" + i] = defines._needUVs ? mesh.isVerticesDataPresent(`uv${i === 1 ? \"\" : i}`) : false;\r\n    }\r\n\r\n    if (useVertexColor) {\r\n        const hasVertexColors = mesh.useVertexColors && mesh.isVerticesDataPresent(Constants.ColorKind);\r\n        defines[\"VERTEXCOLOR\"] = hasVertexColors;\r\n        defines[\"VERTEXALPHA\"] = mesh.hasVertexAlpha && hasVertexColors && useVertexAlpha;\r\n    }\r\n\r\n    if (mesh.isVerticesDataPresent(Constants.ColorInstanceKind) && (mesh.hasInstances || mesh.hasThinInstances)) {\r\n        defines[\"INSTANCESCOLOR\"] = true;\r\n    }\r\n\r\n    if (useBones) {\r\n        PrepareDefinesForBones(mesh, defines);\r\n    }\r\n\r\n    if (useMorphTargets) {\r\n        PrepareDefinesForMorphTargets(mesh, defines);\r\n    }\r\n\r\n    if (useBakedVertexAnimation) {\r\n        PrepareDefinesForBakedVertexAnimation(mesh, defines);\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\n/**\r\n * Prepares the defines related to multiview\r\n * @param scene The scene we are intending to draw\r\n * @param defines The defines to update\r\n */\r\nexport function PrepareDefinesForMultiview(scene: Scene, defines: any) {\r\n    if (scene.activeCamera) {\r\n        const previousMultiview = defines.MULTIVIEW;\r\n        defines.MULTIVIEW = scene.activeCamera.outputRenderTarget !== null && scene.activeCamera.outputRenderTarget.getViewCount() > 1;\r\n        if (defines.MULTIVIEW != previousMultiview) {\r\n            defines.markAsUnprocessed();\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Prepares the defines related to order independant transparency\r\n * @param scene The scene we are intending to draw\r\n * @param defines The defines to update\r\n * @param needAlphaBlending Determines if the material needs alpha blending\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function PrepareDefinesForOIT(scene: Scene, defines: any, needAlphaBlending: boolean) {\r\n    const previousDefine = defines.ORDER_INDEPENDENT_TRANSPARENCY;\r\n    const previousDefine16Bits = defines.ORDER_INDEPENDENT_TRANSPARENCY_16BITS;\r\n\r\n    defines.ORDER_INDEPENDENT_TRANSPARENCY = scene.useOrderIndependentTransparency && needAlphaBlending;\r\n    defines.ORDER_INDEPENDENT_TRANSPARENCY_16BITS = !scene.getEngine().getCaps().textureFloatLinearFiltering;\r\n\r\n    if (previousDefine !== defines.ORDER_INDEPENDENT_TRANSPARENCY || previousDefine16Bits !== defines.ORDER_INDEPENDENT_TRANSPARENCY_16BITS) {\r\n        defines.markAsUnprocessed();\r\n    }\r\n}\r\n\r\n/**\r\n * Prepares the defines related to the prepass\r\n * @param scene The scene we are intending to draw\r\n * @param defines The defines to update\r\n * @param canRenderToMRT Indicates if this material renders to several textures in the prepass\r\n */\r\nexport function PrepareDefinesForPrePass(scene: Scene, defines: any, canRenderToMRT: boolean) {\r\n    const previousPrePass = defines.PREPASS;\r\n\r\n    if (!defines._arePrePassDirty) {\r\n        return;\r\n    }\r\n\r\n    const texturesList = [\r\n        {\r\n            type: Constants.PREPASS_POSITION_TEXTURE_TYPE,\r\n            define: \"PREPASS_POSITION\",\r\n            index: \"PREPASS_POSITION_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE,\r\n            define: \"PREPASS_LOCAL_POSITION\",\r\n            index: \"PREPASS_LOCAL_POSITION_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,\r\n            define: \"PREPASS_VELOCITY\",\r\n            index: \"PREPASS_VELOCITY_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE,\r\n            define: \"PREPASS_VELOCITY_LINEAR\",\r\n            index: \"PREPASS_VELOCITY_LINEAR_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,\r\n            define: \"PREPASS_REFLECTIVITY\",\r\n            index: \"PREPASS_REFLECTIVITY_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE,\r\n            define: \"PREPASS_IRRADIANCE_LEGACY\",\r\n            index: \"PREPASS_IRRADIANCE_LEGACY_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_ALBEDO_SQRT_TEXTURE_TYPE,\r\n            define: \"PREPASS_ALBEDO_SQRT\",\r\n            index: \"PREPASS_ALBEDO_SQRT_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_DEPTH_TEXTURE_TYPE,\r\n            define: \"PREPASS_DEPTH\",\r\n            index: \"PREPASS_DEPTH_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE,\r\n            define: \"PREPASS_SCREENSPACE_DEPTH\",\r\n            index: \"PREPASS_SCREENSPACE_DEPTH_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_NORMAL_TEXTURE_TYPE,\r\n            define: \"PREPASS_NORMAL\",\r\n            index: \"PREPASS_NORMAL_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE,\r\n            define: \"PREPASS_WORLD_NORMAL\",\r\n            index: \"PREPASS_WORLD_NORMAL_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE,\r\n            define: \"PREPASS_IRRADIANCE\",\r\n            index: \"PREPASS_IRRADIANCE_INDEX\",\r\n        },\r\n    ];\r\n\r\n    if (scene.prePassRenderer && scene.prePassRenderer.enabled && canRenderToMRT) {\r\n        defines.PREPASS = true;\r\n        defines.SCENE_MRT_COUNT = scene.prePassRenderer.mrtCount;\r\n        defines.PREPASS_NORMAL_WORLDSPACE = scene.prePassRenderer.generateNormalsInWorldSpace;\r\n        defines.PREPASS_COLOR = true;\r\n        defines.PREPASS_COLOR_INDEX = 0;\r\n\r\n        for (let i = 0; i < texturesList.length; i++) {\r\n            const index = scene.prePassRenderer.getIndex(texturesList[i].type);\r\n            if (index !== -1) {\r\n                defines[texturesList[i].define] = true;\r\n                defines[texturesList[i].index] = index;\r\n            } else {\r\n                defines[texturesList[i].define] = false;\r\n            }\r\n        }\r\n    } else {\r\n        defines.PREPASS = false;\r\n        for (let i = 0; i < texturesList.length; i++) {\r\n            defines[texturesList[i].define] = false;\r\n        }\r\n    }\r\n\r\n    if (defines.PREPASS != previousPrePass) {\r\n        defines.markAsUnprocessed();\r\n        defines.markAsImageProcessingDirty();\r\n    }\r\n}\r\n\r\n/**\r\n * Helper used to prepare the defines relative to the active camera\r\n * @param scene defines the current scene\r\n * @param defines specifies the list of active defines\r\n * @returns true if the defines have been updated, else false\r\n */\r\nexport function PrepareDefinesForCamera(scene: Scene, defines: any): boolean {\r\n    let changed = false;\r\n\r\n    if (scene.activeCamera) {\r\n        const wasOrtho = defines[\"CAMERA_ORTHOGRAPHIC\"] ? 1 : 0;\r\n        const wasPersp = defines[\"CAMERA_PERSPECTIVE\"] ? 1 : 0;\r\n        const isOrtho = scene.activeCamera.mode === Constants.ORTHOGRAPHIC_CAMERA ? 1 : 0;\r\n        const isPersp = scene.activeCamera.mode === Constants.PERSPECTIVE_CAMERA ? 1 : 0;\r\n\r\n        if (wasOrtho ^ isOrtho || wasPersp ^ isPersp) {\r\n            defines[\"CAMERA_ORTHOGRAPHIC\"] = isOrtho === 1;\r\n            defines[\"CAMERA_PERSPECTIVE\"] = isPersp === 1;\r\n            changed = true;\r\n        }\r\n    }\r\n\r\n    return changed;\r\n}\r\n\r\n/**\r\n * Prepares the uniforms and samplers list to be used in the effect (for a specific light)\r\n * @param lightIndex defines the light index\r\n * @param uniformsList The uniform list\r\n * @param samplersList The sampler list\r\n * @param projectedLightTexture defines if projected texture must be used\r\n * @param uniformBuffersList defines an optional list of uniform buffers\r\n * @param updateOnlyBuffersList True to only update the uniformBuffersList array\r\n * @param iesLightTexture defines if IES texture must be used\r\n * @param clusteredLightTextures defines if the clustered light textures must be used\r\n * @param rectAreaLightTexture defines if rect area light is using a emission texture.\r\n * @param clusteredLightStorageBuffer defines if the clustered light tile mask uses a storage buffer instead of a texture\r\n */\r\nexport function PrepareUniformsAndSamplersForLight(\r\n    lightIndex: number,\r\n    uniformsList: string[],\r\n    samplersList: string[],\r\n    projectedLightTexture?: any,\r\n    uniformBuffersList: Nullable<string[]> = null,\r\n    updateOnlyBuffersList = false,\r\n    iesLightTexture = false,\r\n    clusteredLightTextures = false,\r\n    rectAreaLightTexture = false,\r\n    clusteredLightStorageBuffer = false\r\n) {\r\n    if (uniformBuffersList) {\r\n        uniformBuffersList.push(\"Light\" + lightIndex);\r\n    }\r\n\r\n    if (updateOnlyBuffersList) {\r\n        return;\r\n    }\r\n\r\n    uniformsList.push(\r\n        \"vLightData\" + lightIndex,\r\n        \"vLightDiffuse\" + lightIndex,\r\n        \"vLightSpecular\" + lightIndex,\r\n        \"vLightDirection\" + lightIndex,\r\n        \"vLightWidth\" + lightIndex,\r\n        \"vLightHeight\" + lightIndex,\r\n        \"vLightFalloff\" + lightIndex,\r\n        \"vLightGround\" + lightIndex,\r\n        \"vSliceData\" + lightIndex,\r\n        \"vSliceRanges\" + lightIndex,\r\n        \"lightMatrix\" + lightIndex,\r\n        \"shadowsInfo\" + lightIndex,\r\n        \"depthValues\" + lightIndex\r\n    );\r\n\r\n    samplersList.push(\"shadowTexture\" + lightIndex);\r\n    samplersList.push(\"depthTexture\" + lightIndex);\r\n\r\n    uniformsList.push(\r\n        \"viewFrustumZ\" + lightIndex,\r\n        \"cascadeBlendFactor\" + lightIndex,\r\n        \"lightSizeUVCorrection\" + lightIndex,\r\n        \"depthCorrection\" + lightIndex,\r\n        \"penumbraDarkness\" + lightIndex,\r\n        \"frustumLengths\" + lightIndex\r\n    );\r\n\r\n    if (projectedLightTexture) {\r\n        samplersList.push(\"projectionLightTexture\" + lightIndex);\r\n        uniformsList.push(\"textureProjectionMatrix\" + lightIndex);\r\n    }\r\n    if (iesLightTexture) {\r\n        samplersList.push(\"iesLightTexture\" + lightIndex);\r\n    }\r\n    if (rectAreaLightTexture) {\r\n        samplersList.push(\"rectAreaLightEmissionTexture\" + lightIndex);\r\n    }\r\n    if (clusteredLightTextures) {\r\n        samplersList.push(\"lightDataTexture\" + lightIndex);\r\n        if (!clusteredLightStorageBuffer) {\r\n            samplersList.push(\"tileMaskTexture\" + lightIndex);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Append uniforms and samplers related to IBL to the provided lists\r\n * @param uniformsList The list of uniforms to append to\r\n * @param samplersList The list of samplers to append to\r\n * @param useSH Whether to include spherical harmonics uniforms\r\n */\r\nexport function PrepareUniformsAndSamplersForIBL(uniformsList: string[], samplersList: string[], useSH: boolean): void {\r\n    const iblUniforms = [\r\n        \"vReflectionMicrosurfaceInfos\",\r\n        \"vReflectionDominantDirection\",\r\n        \"reflectionMatrix\",\r\n        \"vReflectionInfos\",\r\n        \"vReflectionPosition\",\r\n        \"vReflectionSize\",\r\n        \"vReflectionColor\",\r\n        \"vReflectionFilteringInfo\",\r\n    ];\r\n    if (useSH) {\r\n        iblUniforms.push(\r\n            \"vSphericalX\",\r\n            \"vSphericalY\",\r\n            \"vSphericalZ\",\r\n            \"vSphericalXX_ZZ\",\r\n            \"vSphericalYY_ZZ\",\r\n            \"vSphericalZZ\",\r\n            \"vSphericalXY\",\r\n            \"vSphericalYZ\",\r\n            \"vSphericalZX\",\r\n            \"vSphericalL00\",\r\n            \"vSphericalL1_1\",\r\n            \"vSphericalL10\",\r\n            \"vSphericalL11\",\r\n            \"vSphericalL2_2\",\r\n            \"vSphericalL2_1\",\r\n            \"vSphericalL20\",\r\n            \"vSphericalL21\",\r\n            \"vSphericalL22\"\r\n        );\r\n    }\r\n    uniformsList.push(...iblUniforms);\r\n\r\n    const iblSamplers = [\"reflectionSampler\", \"reflectionSamplerLow\", \"reflectionSamplerHigh\", \"irradianceSampler\", \"icdfSampler\"];\r\n    samplersList.push(...iblSamplers);\r\n}\r\n\r\n/**\r\n * Prepares the uniforms and samplers list to be used in the effect\r\n * @param uniformsListOrOptions The uniform names to prepare or an EffectCreationOptions containing the list and extra information\r\n * @param samplersList The sampler list\r\n * @param defines The defines helping in the list generation\r\n * @param maxSimultaneousLights The maximum number of simultaneous light allowed in the effect\r\n */\r\nexport function PrepareUniformsAndSamplersList(uniformsListOrOptions: string[] | IEffectCreationOptions, samplersList?: string[], defines?: any, maxSimultaneousLights = 4): void {\r\n    let uniformsList: string[];\r\n    let uniformBuffersList: string[] | undefined;\r\n    let shaderLanguage: Nullable<ShaderLanguage> = null;\r\n\r\n    if ((<IEffectCreationOptions>uniformsListOrOptions).uniformsNames) {\r\n        const options = <IEffectCreationOptions>uniformsListOrOptions;\r\n        uniformsList = options.uniformsNames;\r\n        uniformBuffersList = options.uniformBuffersNames;\r\n        samplersList = options.samplers;\r\n        defines = options.defines;\r\n        maxSimultaneousLights = options.maxSimultaneousLights || 0;\r\n        shaderLanguage = options.shaderLanguage ?? null;\r\n    } else {\r\n        uniformsList = <string[]>uniformsListOrOptions;\r\n        if (!samplersList) {\r\n            samplersList = [];\r\n        }\r\n    }\r\n\r\n    for (let lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {\r\n        if (!defines[\"LIGHT\" + lightIndex]) {\r\n            break;\r\n        }\r\n        PrepareUniformsAndSamplersForLight(\r\n            lightIndex,\r\n            uniformsList,\r\n            samplersList,\r\n            defines[\"PROJECTEDLIGHTTEXTURE\" + lightIndex],\r\n            uniformBuffersList,\r\n            false,\r\n            defines[\"IESLIGHTTEXTURE\" + lightIndex],\r\n            defines[\"CLUSTLIGHT\" + lightIndex],\r\n            defines[\"RECTAREALIGHTEMISSIONTEXTURE\" + lightIndex],\r\n            shaderLanguage === ShaderLanguage.WGSL\r\n        );\r\n    }\r\n\r\n    if (defines[\"NUM_MORPH_INFLUENCERS\"]) {\r\n        uniformsList.push(\"morphTargetInfluences\");\r\n        uniformsList.push(\"morphTargetCount\");\r\n    }\r\n\r\n    if (defines[\"BAKED_VERTEX_ANIMATION_TEXTURE\"]) {\r\n        uniformsList.push(\"bakedVertexAnimationSettings\");\r\n        uniformsList.push(\"bakedVertexAnimationTextureSizeInverted\");\r\n        uniformsList.push(\"bakedVertexAnimationTime\");\r\n        samplersList.push(\"bakedVertexAnimationTexture\");\r\n    }\r\n}\r\n\r\n/**\r\n *\r\n * @param ubo Add uniforms to UBO\r\n * @param supportTextureInfo Add uniforms for texture info if true\r\n * @param supportLocalProjection Add uniforms for local projection if true\r\n * @param usePBR Add uniforms for IBL if true\r\n * @param supportSH Add uniforms for spherical harmonics if true\r\n * @param useColor Add uniforms for reflection color if true\r\n */\r\nexport function PrepareUniformLayoutForIBL(\r\n    ubo: UniformBuffer,\r\n    supportTextureInfo: boolean = false,\r\n    supportLocalProjection: boolean = false,\r\n    usePBR: boolean = false,\r\n    supportSH: boolean = false,\r\n    useColor: boolean = false\r\n): void {\r\n    ubo.addUniform(\"vReflectionInfos\", 2);\r\n    ubo.addUniform(\"reflectionMatrix\", 16);\r\n    if (supportTextureInfo) {\r\n        ubo.addUniform(\"vReflectionMicrosurfaceInfos\", 3);\r\n    }\r\n\r\n    if (supportLocalProjection) {\r\n        ubo.addUniform(\"vReflectionPosition\", 3);\r\n        ubo.addUniform(\"vReflectionSize\", 3);\r\n    }\r\n\r\n    if (usePBR) {\r\n        ubo.addUniform(\"vReflectionFilteringInfo\", 2);\r\n        ubo.addUniform(\"vReflectionDominantDirection\", 3);\r\n    }\r\n\r\n    if (useColor) {\r\n        ubo.addUniform(\"vReflectionColor\", 3);\r\n    }\r\n\r\n    if (supportSH) {\r\n        ubo.addUniform(\"vSphericalL00\", 3);\r\n        ubo.addUniform(\"vSphericalL1_1\", 3);\r\n        ubo.addUniform(\"vSphericalL10\", 3);\r\n        ubo.addUniform(\"vSphericalL11\", 3);\r\n        ubo.addUniform(\"vSphericalL2_2\", 3);\r\n        ubo.addUniform(\"vSphericalL2_1\", 3);\r\n        ubo.addUniform(\"vSphericalL20\", 3);\r\n        ubo.addUniform(\"vSphericalL21\", 3);\r\n        ubo.addUniform(\"vSphericalL22\", 3);\r\n\r\n        ubo.addUniform(\"vSphericalX\", 3);\r\n        ubo.addUniform(\"vSphericalY\", 3);\r\n        ubo.addUniform(\"vSphericalZ\", 3);\r\n        ubo.addUniform(\"vSphericalXX_ZZ\", 3);\r\n        ubo.addUniform(\"vSphericalYY_ZZ\", 3);\r\n        ubo.addUniform(\"vSphericalZZ\", 3);\r\n        ubo.addUniform(\"vSphericalXY\", 3);\r\n        ubo.addUniform(\"vSphericalYZ\", 3);\r\n        ubo.addUniform(\"vSphericalZX\", 3);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { type Immutable, type Nullable } from \"../types\";\r\nimport { type Matrix } from \"../Maths/math.vector.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { UniformBuffer } from \"./uniformBuffer\";\r\nimport { type Effect } from \"./effect.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type IInspectable } from \"../Misc/iInspectable\";\r\nimport { Plane } from \"../Maths/math.plane\";\r\nimport { type ShadowDepthWrapper } from \"./shadowDepthWrapper\";\r\nimport { type IMaterialContext } from \"../Engines/IMaterialContext\";\r\nimport { DrawWrapper } from \"./drawWrapper\";\r\nimport { MaterialStencilState } from \"./materialStencilState\";\r\nimport { ScenePerformancePriority, type Scene } from \"../scene.pure\";\r\nimport {\r\n    type MaterialPluginDisposed,\r\n    type MaterialPluginIsReadyForSubMesh,\r\n    type MaterialPluginGetDefineNames,\r\n    type MaterialPluginBindForSubMesh,\r\n    type MaterialPluginGetActiveTextures,\r\n    type MaterialPluginHasTexture,\r\n    type MaterialPluginGetAnimatables,\r\n    type MaterialPluginPrepareDefines,\r\n    type MaterialPluginPrepareEffect,\r\n    type MaterialPluginPrepareUniformBuffer,\r\n    type MaterialPluginCreated,\r\n    type MaterialPluginFillRenderTargetTextures,\r\n    type MaterialPluginHasRenderTargetTextures,\r\n    type MaterialPluginHardBindForSubMesh,\r\n    MaterialPluginEvent,\r\n} from \"./materialPluginEvent\";\r\nimport { type ShaderCustomProcessingFunction } from \"../Engines/Processors/shaderProcessingOptions\";\r\nimport { type IClipPlanesHolder } from \"../Misc/interfaces/iClipPlanesHolder\";\r\n\r\nimport { type PrePassRenderer } from \"../Rendering/prePassRenderer.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Animation } from \"../Animations/animation.pure\";\r\nimport { type InstancedMesh } from \"../Meshes/instancedMesh.pure\";\r\nimport { BindSceneUniformBuffer } from \"./materialHelper.functions\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { IsWrapper } from \"./drawWrapper.functions\";\r\n\r\ndeclare let BABYLON: any;\r\n\r\n/**\r\n * Options for compiling materials.\r\n */\r\nexport interface IMaterialCompilationOptions {\r\n    /**\r\n     * Defines whether clip planes are enabled.\r\n     */\r\n    clipPlane: boolean;\r\n\r\n    /**\r\n     * Defines whether instances are enabled.\r\n     */\r\n    useInstances: boolean;\r\n}\r\n\r\n/**\r\n * Options passed when calling customShaderNameResolve\r\n */\r\nexport interface ICustomShaderNameResolveOptions {\r\n    /**\r\n     * If provided, will be called two times with the vertex and fragment code so that this code can be updated before it is compiled by the GPU\r\n     */\r\n    processFinalCode?: Nullable<ShaderCustomProcessingFunction>;\r\n}\r\n\r\n/**\r\n * Base class for the main features of a material in Babylon.js\r\n */\r\nexport class Material implements IAnimatable, IClipPlanesHolder {\r\n    /**\r\n     * Returns the triangle fill mode\r\n     */\r\n    public static readonly TriangleFillMode = Constants.MATERIAL_TriangleFillMode;\r\n    /**\r\n     * Returns the wireframe mode\r\n     */\r\n    public static readonly WireFrameFillMode = Constants.MATERIAL_WireFrameFillMode;\r\n    /**\r\n     * Returns the point fill mode\r\n     */\r\n    public static readonly PointFillMode = Constants.MATERIAL_PointFillMode;\r\n    /**\r\n     * Returns the point list draw mode\r\n     */\r\n    public static readonly PointListDrawMode = Constants.MATERIAL_PointListDrawMode;\r\n    /**\r\n     * Returns the line list draw mode\r\n     */\r\n    public static readonly LineListDrawMode = Constants.MATERIAL_LineListDrawMode;\r\n    /**\r\n     * Returns the line loop draw mode\r\n     */\r\n    public static readonly LineLoopDrawMode = Constants.MATERIAL_LineLoopDrawMode;\r\n    /**\r\n     * Returns the line strip draw mode\r\n     */\r\n    public static readonly LineStripDrawMode = Constants.MATERIAL_LineStripDrawMode;\r\n    /**\r\n     * Returns the triangle strip draw mode\r\n     */\r\n    public static readonly TriangleStripDrawMode = Constants.MATERIAL_TriangleStripDrawMode;\r\n    /**\r\n     * Returns the triangle fan draw mode\r\n     */\r\n    public static readonly TriangleFanDrawMode = Constants.MATERIAL_TriangleFanDrawMode;\r\n\r\n    /**\r\n     * Stores the clock-wise side orientation\r\n     */\r\n    public static readonly ClockWiseSideOrientation = Constants.MATERIAL_ClockWiseSideOrientation;\r\n\r\n    /**\r\n     * Stores the counter clock-wise side orientation\r\n     */\r\n    public static readonly CounterClockWiseSideOrientation = Constants.MATERIAL_CounterClockWiseSideOrientation;\r\n\r\n    /**\r\n     * The dirty image processing flag value\r\n     */\r\n    public static readonly ImageProcessingDirtyFlag = Constants.MATERIAL_ImageProcessingDirtyFlag;\r\n\r\n    /**\r\n     * The dirty texture flag value\r\n     */\r\n    public static readonly TextureDirtyFlag = Constants.MATERIAL_TextureDirtyFlag;\r\n\r\n    /**\r\n     * The dirty light flag value\r\n     */\r\n    public static readonly LightDirtyFlag = Constants.MATERIAL_LightDirtyFlag;\r\n\r\n    /**\r\n     * The dirty fresnel flag value\r\n     */\r\n    public static readonly FresnelDirtyFlag = Constants.MATERIAL_FresnelDirtyFlag;\r\n\r\n    /**\r\n     * The dirty attribute flag value\r\n     */\r\n    public static readonly AttributesDirtyFlag = Constants.MATERIAL_AttributesDirtyFlag;\r\n\r\n    /**\r\n     * The dirty misc flag value\r\n     */\r\n    public static readonly MiscDirtyFlag = Constants.MATERIAL_MiscDirtyFlag;\r\n\r\n    /**\r\n     * The dirty prepass flag value\r\n     */\r\n    public static readonly PrePassDirtyFlag = Constants.MATERIAL_PrePassDirtyFlag;\r\n\r\n    /**\r\n     * The all dirty flag value\r\n     */\r\n    public static readonly AllDirtyFlag = Constants.MATERIAL_AllDirtyFlag;\r\n\r\n    /**\r\n     * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.\r\n     */\r\n    public static readonly MATERIAL_OPAQUE = 0;\r\n\r\n    /**\r\n     * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.\r\n     */\r\n    public static readonly MATERIAL_ALPHATEST = 1;\r\n\r\n    /**\r\n     * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.\r\n     */\r\n    public static readonly MATERIAL_ALPHABLEND = 2;\r\n\r\n    /**\r\n     * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.\r\n     * They are also discarded below the alpha cutoff threshold to improve performances.\r\n     */\r\n    public static readonly MATERIAL_ALPHATESTANDBLEND = 3;\r\n\r\n    /**\r\n     * The Whiteout method is used to blend normals.\r\n     * Details of the algorithm can be found here: https://blog.selfshadow.com/publications/blending-in-detail/\r\n     */\r\n    public static readonly MATERIAL_NORMALBLENDMETHOD_WHITEOUT = 0;\r\n\r\n    /**\r\n     * The Reoriented Normal Mapping method is used to blend normals.\r\n     * Details of the algorithm can be found here: https://blog.selfshadow.com/publications/blending-in-detail/\r\n     */\r\n    public static readonly MATERIAL_NORMALBLENDMETHOD_RNM = 1;\r\n\r\n    /**\r\n     * PBRMaterialLightFalloff Physical: light is falling off following the inverse squared distance law.\r\n     */\r\n    public static readonly LIGHTFALLOFF_PHYSICAL = 0;\r\n\r\n    /**\r\n     * PBRMaterialLightFalloff gltf: light is falling off as described in the gltf moving to PBR document\r\n     * to enhance interoperability with other engines.\r\n     */\r\n    public static readonly LIGHTFALLOFF_GLTF = 1;\r\n\r\n    /**\r\n     * PBRMaterialLightFalloff Standard: light is falling off like in the standard material\r\n     * to enhance interoperability with other materials.\r\n     */\r\n    public static readonly LIGHTFALLOFF_STANDARD = 2;\r\n\r\n    /**\r\n     * Event observable which raises global events common to all materials (like MaterialPluginEvent.Created)\r\n     */\r\n    public static OnEventObservable = /*#__PURE__*/ new Observable<Material>();\r\n\r\n    /**\r\n     * If true, all materials will have their vertex output set to invariant (see the vertexOutputInvariant property).\r\n     */\r\n    public static ForceVertexOutputInvariant = false;\r\n\r\n    /**\r\n     * Custom callback helping to override the default shader used in the material.\r\n     */\r\n    public customShaderNameResolve: (\r\n        shaderName: string,\r\n        uniforms: string[],\r\n        uniformBuffers: string[],\r\n        samplers: string[],\r\n        defines: MaterialDefines | string[],\r\n        attributes?: string[],\r\n        options?: ICustomShaderNameResolveOptions\r\n    ) => string;\r\n\r\n    /**\r\n     * Custom shadow depth material to use for shadow rendering instead of the in-built one\r\n     */\r\n    public shadowDepthWrapper: Nullable<ShadowDepthWrapper> = null;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the material is allowed (if supported) to do shader hot swapping.\r\n     * This means that the material can keep using a previous shader while a new one is being compiled.\r\n     * This is mostly used when shader parallel compilation is supported (true by default)\r\n     */\r\n    public allowShaderHotSwapping = true;\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    protected _forceGLSL = false;\r\n\r\n    protected _useVertexPulling = false;\r\n    /**\r\n     * Tells the engine to draw geometry using vertex pulling instead of index drawing. This will automatically\r\n     * set the vertex buffers as storage buffers and make them accessible to the vertex shader (WebGPU only).\r\n     */\r\n    public get useVertexPulling() {\r\n        return this._useVertexPulling;\r\n    }\r\n\r\n    public set useVertexPulling(value: boolean) {\r\n        if (this._useVertexPulling === value) {\r\n            return;\r\n        }\r\n\r\n        this._useVertexPulling = value;\r\n        this.markAsDirty(Material.MiscDirtyFlag);\r\n    }\r\n\r\n    /** @internal */\r\n    public get _supportGlowLayer() {\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public set _glowModeEnabled(value: boolean) {\r\n        // Do nothing here\r\n    }\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * The ID of the material\r\n     */\r\n    @serialize()\r\n    public id: string;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the material\r\n     */\r\n    @serialize()\r\n    public uniqueId: number;\r\n\r\n    /** @internal */\r\n    public _loadedUniqueId: string;\r\n\r\n    /**\r\n     * The name of the material\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * Gets or sets user defined metadata\r\n     */\r\n    @serialize()\r\n    public metadata: any = null;\r\n\r\n    /** @internal */\r\n    public _internalMetadata: any;\r\n\r\n    /**\r\n     * For internal use only. Please do not use.\r\n     */\r\n    public reservedDataStore: any = null;\r\n\r\n    /**\r\n     * Specifies if the ready state should be checked on each call\r\n     */\r\n    @serialize()\r\n    public checkReadyOnEveryCall = false;\r\n\r\n    /**\r\n     * Specifies if the ready state should be checked once\r\n     */\r\n    @serialize()\r\n    public checkReadyOnlyOnce = false;\r\n\r\n    /**\r\n     * The state of the material\r\n     */\r\n    @serialize()\r\n    public state = \"\";\r\n\r\n    /**\r\n     * If the material can be rendered to several textures with MRT extension\r\n     */\r\n    public get canRenderToMRT(): boolean {\r\n        // By default, shaders are not compatible with MRTs\r\n        // Base classes should override that if their shader supports MRT\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * The alpha value of the material\r\n     */\r\n    @serialize(\"alpha\")\r\n    protected _alpha = 1.0;\r\n\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    public inspectableCustomProperties: IInspectable[];\r\n\r\n    /**\r\n     * Sets the alpha value of the material\r\n     */\r\n    public set alpha(value: number) {\r\n        if (this._alpha === value) {\r\n            return;\r\n        }\r\n\r\n        const oldValue = this._alpha;\r\n        this._alpha = value;\r\n\r\n        // Only call dirty when there is a state change (no alpha / alpha)\r\n        if (oldValue === 1 || value === 1) {\r\n            this.markAsDirty(Material.MiscDirtyFlag + Material.PrePassDirtyFlag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the alpha value of the material\r\n     */\r\n    public get alpha(): number {\r\n        return this._alpha;\r\n    }\r\n\r\n    /**\r\n     * Specifies if back face culling is enabled\r\n     */\r\n    @serialize(\"backFaceCulling\")\r\n    protected _backFaceCulling = true;\r\n\r\n    /**\r\n     * Sets the culling state (true to enable culling, false to disable)\r\n     */\r\n    public set backFaceCulling(value: boolean) {\r\n        if (this._backFaceCulling === value) {\r\n            return;\r\n        }\r\n        this._backFaceCulling = value;\r\n        this.markAsDirty(Material.TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Gets the culling state\r\n     */\r\n    public get backFaceCulling(): boolean {\r\n        return this._backFaceCulling;\r\n    }\r\n\r\n    @serialize(\"textureRepetitionMode\")\r\n    protected _textureRepetitionMode = Constants.TEXTURE_REPETITION_NONE;\r\n\r\n    /**\r\n     * Sets the texture repetition breaking mode.\r\n     * Use one of the Constants.TEXTURE_REPETITION_* values to break visible texture tiling patterns.\r\n     * Ordered by cost: NONE (1 fetch), NOISE_BLEND (3), HEX_TILING (3), TILE_RANDOMIZATION (4), VORONOI_BOMBING (9).\r\n     * Not supported on WebGL1 — the mode will be forced to NONE.\r\n     * @see https://iquilezles.org/articles/texturerepetition/\r\n     * @see https://jcgt.org/published/0011/03/05/\r\n     */\r\n    public set textureRepetitionMode(value: number) {\r\n        const clamped = Math.max(Constants.TEXTURE_REPETITION_NONE, Math.min(value | 0, Constants.TEXTURE_REPETITION_VORONOI_BOMBING));\r\n        if (this._textureRepetitionMode === clamped) {\r\n            return;\r\n        }\r\n        this._textureRepetitionMode = clamped;\r\n        this.markAsDirty(Material.TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Gets the texture repetition breaking mode.\r\n     * @see https://iquilezles.org/articles/texturerepetition/\r\n     */\r\n    public get textureRepetitionMode(): number {\r\n        return this._textureRepetitionMode;\r\n    }\r\n\r\n    /**\r\n     * Parameters for the hex tiling texture repetition mode (TEXTURE_REPETITION_HEX_TILING).\r\n     * x = rotation strength (0..1, default 1.0) — how much each hex tile is rotated.\r\n     * y = fall-off contrast (0..1, default 0.6) — how much luminance affects blending weight at tile borders.\r\n     * z = exponent (1..20, default 7.0) — controls the sharpness of weight falloff between tiles.\r\n     * w = contrast (0..1, default 0.5) — boost blending contrast via Gain3 (0.5 = neutral, &gt;0.5 = higher contrast).\r\n     * @see https://jcgt.org/published/0011/03/05/\r\n     */\r\n    @serialize(\"textureRepetitionHexTilingParams\")\r\n    public textureRepetitionHexTilingParams = [1.0, 0.6, 7.0, 0.5];\r\n\r\n    /**\r\n     * Specifies if back or front faces should be culled (when culling is enabled)\r\n     */\r\n    @serialize(\"cullBackFaces\")\r\n    protected _cullBackFaces = true;\r\n\r\n    /**\r\n     * Sets the type of faces that should be culled (true for back faces, false for front faces)\r\n     */\r\n    public set cullBackFaces(value: boolean) {\r\n        if (this._cullBackFaces === value) {\r\n            return;\r\n        }\r\n        this._cullBackFaces = value;\r\n        this.markAsDirty(Material.TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Gets the type of faces that should be culled\r\n     */\r\n    public get cullBackFaces(): boolean {\r\n        return this._cullBackFaces;\r\n    }\r\n\r\n    private _blockDirtyMechanism = false;\r\n\r\n    /**\r\n     * Block the dirty-mechanism for this specific material\r\n     * When set to false after being true the material will be marked as dirty.\r\n     */\r\n    public get blockDirtyMechanism(): boolean {\r\n        return this._blockDirtyMechanism;\r\n    }\r\n\r\n    public set blockDirtyMechanism(value: boolean) {\r\n        if (this._blockDirtyMechanism === value) {\r\n            return;\r\n        }\r\n\r\n        this._blockDirtyMechanism = value;\r\n\r\n        if (!value) {\r\n            this.markDirty();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This allows you to modify the material without marking it as dirty after every change.\r\n     * This function should be used if you need to make more than one dirty-enabling change to the material - adding a texture, setting a new fill mode and so on.\r\n     * The callback will pass the material as an argument, so you can make your changes to it.\r\n     * @param callback the callback to be executed that will update the material\r\n     */\r\n    public atomicMaterialsUpdate(callback: (material: this) => void): void {\r\n        this.blockDirtyMechanism = true;\r\n        try {\r\n            callback(this);\r\n        } finally {\r\n            this.blockDirtyMechanism = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stores the value for side orientation\r\n     */\r\n    @serialize()\r\n    public sideOrientation: Nullable<number> = null;\r\n\r\n    /**\r\n     * Callback triggered when the material is compiled\r\n     */\r\n    public onCompiled: Nullable<(effect: Effect) => void> = null;\r\n\r\n    /**\r\n     * Callback triggered when an error occurs\r\n     */\r\n    public onError: Nullable<(effect: Effect, errors: string) => void> = null;\r\n\r\n    /**\r\n     * Callback triggered to get the render target textures\r\n     */\r\n    public getRenderTargetTextures: Nullable<() => SmartArray<RenderTargetTexture>> = null;\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     */\r\n    public get hasRenderTargetTextures(): boolean {\r\n        this._eventInfo.hasRenderTargetTextures = false;\r\n        this._callbackPluginEventHasRenderTargetTextures(this._eventInfo);\r\n        return this._eventInfo.hasRenderTargetTextures;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material should be serialized\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _storeEffectOnSubMeshes = false;\r\n\r\n    /**\r\n     * Stores the animations for the material\r\n     */\r\n    public animations: Nullable<Array<Animation>> = null;\r\n\r\n    /**\r\n     * An event triggered when the material is disposed\r\n     */\r\n    public onDisposeObservable = new Observable<Material>();\r\n\r\n    /**\r\n     * An observer which watches for dispose events\r\n     */\r\n    private _onDisposeObserver: Nullable<Observer<Material>> = null;\r\n    private _onUnBindObservable: Nullable<Observable<Material>> = null;\r\n\r\n    /**\r\n     * Called during a dispose event\r\n     */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    private _onBindObservable: Nullable<Observable<AbstractMesh>>;\r\n\r\n    /**\r\n     * An event triggered when the material is bound\r\n     */\r\n    public get onBindObservable(): Observable<AbstractMesh> {\r\n        if (!this._onBindObservable) {\r\n            this._onBindObservable = new Observable<AbstractMesh>();\r\n        }\r\n\r\n        return this._onBindObservable;\r\n    }\r\n\r\n    /**\r\n     * An observer which watches for bind events\r\n     */\r\n    private _onBindObserver: Nullable<Observer<AbstractMesh>> = null;\r\n\r\n    /**\r\n     * Called during a bind event\r\n     */\r\n    public set onBind(callback: (Mesh: AbstractMesh) => void) {\r\n        if (this._onBindObserver) {\r\n            this.onBindObservable.remove(this._onBindObserver);\r\n        }\r\n        this._onBindObserver = this.onBindObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the material is unbound\r\n     */\r\n    public get onUnBindObservable(): Observable<Material> {\r\n        if (!this._onUnBindObservable) {\r\n            this._onUnBindObservable = new Observable<Material>();\r\n        }\r\n\r\n        return this._onUnBindObservable;\r\n    }\r\n\r\n    protected _onEffectCreatedObservable: Nullable<Observable<{ effect: Effect; subMesh: Nullable<SubMesh> }>>;\r\n\r\n    /**\r\n     * An event triggered when the effect is (re)created\r\n     */\r\n    public get onEffectCreatedObservable(): Observable<{ effect: Effect; subMesh: Nullable<SubMesh> }> {\r\n        if (!this._onEffectCreatedObservable) {\r\n            this._onEffectCreatedObservable = new Observable<{ effect: Effect; subMesh: Nullable<SubMesh> }>();\r\n        }\r\n\r\n        return this._onEffectCreatedObservable;\r\n    }\r\n\r\n    /**\r\n     * Stores the value of the alpha mode\r\n     */\r\n    @serialize()\r\n    private _alphaMode: number[] = [Constants.ALPHA_COMBINE];\r\n\r\n    /**\r\n     * Sets the value of the alpha mode.\r\n     *\r\n     * | Value | Type | Description |\r\n     * | --- | --- | --- |\r\n     * | 0 | ALPHA_DISABLE |  |\r\n     * | 1 | ALPHA_ADD | Defines that alpha blending is COLOR=SRC_ALPHA * SRC + DEST, ALPHA=DEST_ALPHA |\r\n     * | 2 | ALPHA_COMBINE | Defines that alpha blending is COLOR=SRC_ALPHA * SRC + (1 - SRC_ALPHA) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA |\r\n     * | 3 | ALPHA_SUBTRACT | Defines that alpha blending is COLOR=(1 - SRC) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA |\r\n     * | 4 | ALPHA_MULTIPLY | Defines that alpha blending is COLOR=DEST * SRC, ALPHA=SRC_ALPHA + DEST_ALPHA |\r\n     * | 5 | ALPHA_MAXIMIZED | Defines that alpha blending is COLOR=SRC_ALPHA * SRC + (1 - SRC) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA |\r\n     * | 6 | ALPHA_ONEONE | Defines that alpha blending is COLOR=SRC + DEST, ALPHA=DEST_ALPHA |\r\n     * | 7 | ALPHA_PREMULTIPLIED | Defines that alpha blending is COLOR=SRC + (1 - SRC_ALPHA) * DEST, ALPHA=SRC_ALPHA + DEST_ALPHA |\r\n     * | 8 | ALPHA_PREMULTIPLIED_PORTERDUFF | Defines that alpha blending is COLOR=SRC + (1 - SRC_ALPHA) * DEST, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA |\r\n     * | 9 | ALPHA_INTERPOLATE | Defines that alpha blending is COLOR=CST * SRC + (1 - CST) * DEST, ALPHA=CST_ALPHA * SRC + (1 - CST_ALPHA) * DEST_ALPHA |\r\n     * | 10 | ALPHA_SCREENMODE | Defines that alpha blending is COLOR=SRC + (1 - SRC) * DEST, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA |\r\n     * | 11 | ALPHA_ONEONE_ONEONE | Defines that alpha blending is COLOR=SRC + DST, ALPHA=SRC_ALPHA + DEST_ALPHA |\r\n     * | 12 | ALPHA_ALPHATOCOLOR | Defines that alpha blending is COLOR=DEST_ALPHA * SRC + DST, ALPHA=0 |\r\n     * | 13 | ALPHA_REVERSEONEMINUS | Defines that alpha blending is COLOR=(1 - DEST) * SRC + (1 - SRC) * DEST, ALPHA=(1 - DEST_ALPHA) * SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA |\r\n     * | 14 | ALPHA_SRC_DSTONEMINUSSRCALPHA | Defines that alpha blending is ALPHA=SRC + (1 - SRC ALPHA) * DEST, ALPHA=SRC_ALPHA + (1 - SRC ALPHA) * DEST_ALPHA |\r\n     * | 15 | ALPHA_ONEONE_ONEZERO | Defines that alpha blending is COLOR=SRC + DST, ALPHA=SRC_ALPHA |\r\n     * | 16 | ALPHA_EXCLUSION | Defines that alpha blending is COLOR=(1 - DEST) * SRC + (1 - SRC) * DEST, ALPHA=DEST_ALPHA |\r\n     * | 17 | ALPHA_LAYER_ACCUMULATE | Defines that alpha blending is COLOR=SRC_ALPHA * SRC + (1 - SRC ALPHA) * DEST, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA |\r\n     * | 18 | ALPHA_MIN | Defines that alpha blending is COLOR=MIN(SRC, DEST), ALPHA=MIN(SRC_ALPHA, DEST_ALPHA) |\r\n     * | 19 | ALPHA_MAX | Defines that alpha blending is COLOR=MAX(SRC, DEST), ALPHA=MAX(SRC_ALPHA, DEST_ALPHA) |\r\n     * | 20 | ALPHA_DUAL_SRC0_ADD_SRC1xDST | Defines that alpha blending uses dual source blending and is COLOR=SRC + SRC1 * DEST, ALPHA=DST_ALPHA |\r\n     * | 21 | ALPHA_REPLACE_COLOR | Defines that alpha blending is COLOR=SRC, ALPHA=SRC_ALPHA + (1 - SRC_ALPHA) * DEST_ALPHA |\r\n     *\r\n     */\r\n    public set alphaMode(value: number) {\r\n        if (this._alphaMode[0] === value) {\r\n            return;\r\n        }\r\n        this._alphaMode[0] = value;\r\n        this.markAsDirty(Material.TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the alpha mode\r\n     */\r\n    public get alphaMode(): number {\r\n        return this._alphaMode[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the list of alpha modes (length greater than 1 for multi-targets)\r\n     */\r\n    public get alphaModes(): Immutable<number[]> {\r\n        return this._alphaMode;\r\n    }\r\n\r\n    /**\r\n     * Sets the value of the alpha mode for a specific target index.\r\n     * @param value The alpha mode value to set.\r\n     * @param targetIndex The index of the target to set the alpha mode for. Defaults to 0.\r\n     */\r\n    public setAlphaMode(value: number, targetIndex: number = 0): void {\r\n        if (this._alphaMode[targetIndex] === value) {\r\n            return;\r\n        }\r\n        this._alphaMode[targetIndex] = value;\r\n        this.markAsDirty(Material.TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Stores the state of the need depth pre-pass value\r\n     */\r\n    @serialize()\r\n    private _needDepthPrePass = false;\r\n\r\n    /**\r\n     * Sets the need depth pre-pass value\r\n     */\r\n    public set needDepthPrePass(value: boolean) {\r\n        if (this._needDepthPrePass === value) {\r\n            return;\r\n        }\r\n        this._needDepthPrePass = value;\r\n        if (this._needDepthPrePass) {\r\n            this.checkReadyOnEveryCall = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the depth pre-pass value\r\n     */\r\n    public get needDepthPrePass(): boolean {\r\n        return this._needDepthPrePass;\r\n    }\r\n\r\n    /**\r\n     * Can this material render to prepass\r\n     */\r\n    public get isPrePassCapable(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Specifies if depth writing should be disabled\r\n     */\r\n    @serialize()\r\n    public disableDepthWrite = false;\r\n\r\n    /**\r\n     * Specifies if color writing should be disabled\r\n     */\r\n    @serialize()\r\n    public disableColorWrite = false;\r\n\r\n    /**\r\n     * Specifies if depth writing should be forced\r\n     */\r\n    @serialize()\r\n    public forceDepthWrite = false;\r\n\r\n    /**\r\n     * Specifies the depth function that should be used. 0 means the default engine function\r\n     */\r\n    @serialize()\r\n    public depthFunction = 0;\r\n\r\n    /**\r\n     * Specifies if there should be a separate pass for culling\r\n     */\r\n    @serialize()\r\n    public separateCullingPass = false;\r\n\r\n    /**\r\n     * Stores the state specifying if fog should be enabled\r\n     */\r\n    @serialize(\"fogEnabled\")\r\n    private _fogEnabled = true;\r\n\r\n    /**\r\n     * Sets the state for enabling fog\r\n     */\r\n    public set fogEnabled(value: boolean) {\r\n        if (this._fogEnabled === value) {\r\n            return;\r\n        }\r\n        this._fogEnabled = value;\r\n        this.markAsDirty(Material.MiscDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the fog enabled state\r\n     */\r\n    public get fogEnabled(): boolean {\r\n        return this._fogEnabled;\r\n    }\r\n\r\n    /**\r\n     * Stores the size of points\r\n     */\r\n    @serialize()\r\n    public pointSize = 1.0;\r\n\r\n    /**\r\n     * Stores the z offset Factor value\r\n     */\r\n    @serialize()\r\n    public zOffset = 0;\r\n\r\n    /**\r\n     * Stores the z offset Units value\r\n     */\r\n    @serialize()\r\n    public zOffsetUnits = 0;\r\n\r\n    public get wireframe(): boolean {\r\n        switch (this._fillMode) {\r\n            case Material.WireFrameFillMode:\r\n            case Material.LineListDrawMode:\r\n            case Material.LineLoopDrawMode:\r\n            case Material.LineStripDrawMode:\r\n                return true;\r\n        }\r\n\r\n        return this._scene.forceWireframe;\r\n    }\r\n\r\n    /**\r\n     * Sets the state of wireframe mode\r\n     */\r\n    public set wireframe(value: boolean) {\r\n        this.fillMode = value ? Material.WireFrameFillMode : Material.TriangleFillMode;\r\n    }\r\n\r\n    /**\r\n     * Gets the value specifying if point clouds are enabled\r\n     */\r\n    @serialize()\r\n    public get pointsCloud(): boolean {\r\n        switch (this._fillMode) {\r\n            case Material.PointFillMode:\r\n            case Material.PointListDrawMode:\r\n                return true;\r\n        }\r\n\r\n        return this._scene.forcePointsCloud;\r\n    }\r\n\r\n    /**\r\n     * Sets the state of point cloud mode\r\n     */\r\n    public set pointsCloud(value: boolean) {\r\n        this.fillMode = value ? Material.PointFillMode : Material.TriangleFillMode;\r\n    }\r\n\r\n    /**\r\n     * Gets the material fill mode\r\n     */\r\n    @serialize()\r\n    public get fillMode(): number {\r\n        return this._fillMode;\r\n    }\r\n\r\n    /**\r\n     * Sets the material fill mode\r\n     */\r\n    public set fillMode(value: number) {\r\n        if (this._fillMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._fillMode = value;\r\n        this.markAsDirty(Material.MiscDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 1\r\n     */\r\n    public clipPlane: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 2\r\n     */\r\n    public clipPlane2: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 3\r\n     */\r\n    public clipPlane3: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 4\r\n     */\r\n    public clipPlane4: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 5\r\n     */\r\n    public clipPlane5: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 6\r\n     */\r\n    public clipPlane6: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gives access to the stencil properties of the material\r\n     */\r\n    public readonly stencil = new MaterialStencilState();\r\n\r\n    protected _useLogarithmicDepth: boolean;\r\n\r\n    /**\r\n     * In case the depth buffer does not allow enough depth precision for your scene (might be the case in large scenes)\r\n     * You can try switching to logarithmic depth.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/logarithmicDepthBuffer\r\n     */\r\n    @serialize()\r\n    public get useLogarithmicDepth(): boolean {\r\n        return this._useLogarithmicDepth;\r\n    }\r\n\r\n    public set useLogarithmicDepth(value: boolean) {\r\n        const fragmentDepthSupported = this.getScene().getEngine().getCaps().fragmentDepthSupported;\r\n\r\n        if (value && !fragmentDepthSupported) {\r\n            Logger.Warn(\"Logarithmic depth has been requested for a material on a device that doesn't support it.\");\r\n        }\r\n\r\n        this._useLogarithmicDepth = value && fragmentDepthSupported;\r\n\r\n        this._markAllSubMeshesAsMiscDirty();\r\n    }\r\n\r\n    @serialize()\r\n    protected _isVertexOutputInvariant = Material.ForceVertexOutputInvariant;\r\n    /**\r\n     * Gets or sets the vertex output invariant state\r\n     * Setting this property to true will force the shader compiler to disable some optimization to make sure the vertex output is always calculated\r\n     * the same way across different compilation units.\r\n     * You may need to enable this option if you are seeing some depth artifacts when using a depth pre-pass, for e.g.\r\n     * Note that this may have an impact on performance, so leave this option disabled if not needed.\r\n     */\r\n    public get isVertexOutputInvariant(): boolean {\r\n        return this._isVertexOutputInvariant;\r\n    }\r\n\r\n    public set isVertexOutputInvariant(value: boolean) {\r\n        if (this._isVertexOutputInvariant === value) {\r\n            return;\r\n        }\r\n\r\n        this._isVertexOutputInvariant = value;\r\n        this._markAllSubMeshesAsMiscDirty();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Stores the effects for the material\r\n     */\r\n    public _materialContext: IMaterialContext | undefined;\r\n\r\n    protected _drawWrapper: DrawWrapper;\r\n    /** @internal */\r\n    public _getDrawWrapper(): DrawWrapper {\r\n        return this._drawWrapper;\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setDrawWrapper(drawWrapper: DrawWrapper) {\r\n        this._drawWrapper = drawWrapper;\r\n    }\r\n\r\n    /**\r\n     * Specifies if uniform buffers should be used\r\n     */\r\n    private _useUBO: boolean = false;\r\n\r\n    /**\r\n     * Stores a reference to the scene\r\n     */\r\n    private _scene: Scene;\r\n    protected _needToBindSceneUbo: boolean;\r\n\r\n    /**\r\n     * Stores the fill mode state\r\n     */\r\n    private _fillMode = Material.TriangleFillMode;\r\n\r\n    /**\r\n     * Specifies if the depth write state should be cached\r\n     */\r\n    private _cachedDepthWriteState: boolean = false;\r\n\r\n    /**\r\n     * Specifies if the color write state should be cached\r\n     */\r\n    private _cachedColorWriteState: boolean = false;\r\n\r\n    /**\r\n     * Specifies if the depth function state should be cached\r\n     */\r\n    private _cachedDepthFunctionState: number = 0;\r\n\r\n    /**\r\n     * Stores the uniform buffer\r\n     * @internal\r\n     */\r\n    public _uniformBuffer: UniformBuffer;\r\n\r\n    /** @internal */\r\n    public _indexInSceneMaterialArray = -1;\r\n\r\n    /** @internal */\r\n    public meshMap: Nullable<{ [id: string]: AbstractMesh | undefined }> = null;\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /** @internal */\r\n    public _dirtyCallbacks: { [code: number]: () => void };\r\n\r\n    /** @internal */\r\n    public _uniformBufferLayoutBuilt = false;\r\n\r\n    protected _eventInfo: MaterialPluginCreated &\r\n        MaterialPluginDisposed &\r\n        MaterialPluginHasTexture &\r\n        MaterialPluginIsReadyForSubMesh &\r\n        MaterialPluginGetDefineNames &\r\n        MaterialPluginPrepareEffect &\r\n        MaterialPluginPrepareDefines &\r\n        MaterialPluginPrepareUniformBuffer &\r\n        MaterialPluginBindForSubMesh &\r\n        MaterialPluginGetAnimatables &\r\n        MaterialPluginGetActiveTextures &\r\n        MaterialPluginFillRenderTargetTextures &\r\n        MaterialPluginHasRenderTargetTextures &\r\n        MaterialPluginHardBindForSubMesh = {} as any; // will be initialized before each event notification\r\n\r\n    /** @internal */\r\n    public _callbackPluginEventGeneric: (\r\n        id: number,\r\n        info:\r\n            | MaterialPluginGetActiveTextures\r\n            | MaterialPluginGetAnimatables\r\n            | MaterialPluginHasTexture\r\n            | MaterialPluginDisposed\r\n            | MaterialPluginGetDefineNames\r\n            | MaterialPluginPrepareEffect\r\n            | MaterialPluginPrepareUniformBuffer\r\n    ) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventIsReadyForSubMesh: (eventData: MaterialPluginIsReadyForSubMesh) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventPrepareDefines: (eventData: MaterialPluginPrepareDefines) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventPrepareDefinesBeforeAttributes: (eventData: MaterialPluginPrepareDefines) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventHardBindForSubMesh: (eventData: MaterialPluginHardBindForSubMesh) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventBindForSubMesh: (eventData: MaterialPluginBindForSubMesh) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventHasRenderTargetTextures: (eventData: MaterialPluginHasRenderTargetTextures) => void = () => void 0;\r\n    /** @internal */\r\n    public _callbackPluginEventFillRenderTargetTextures: (eventData: MaterialPluginFillRenderTargetTextures) => void = () => void 0;\r\n\r\n    /**\r\n     * Creates a material instance\r\n     * @param name defines the name of the material\r\n     * @param scene defines the scene to reference\r\n     * @param doNotAdd specifies if the material should be added to the scene\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(name: string, scene?: Nullable<Scene>, doNotAdd?: boolean, forceGLSL = false) {\r\n        this.name = name;\r\n        const setScene = scene || EngineStore.LastCreatedScene;\r\n        if (!setScene) {\r\n            return;\r\n        }\r\n        this._scene = setScene;\r\n        this._dirtyCallbacks = {};\r\n        this._forceGLSL = forceGLSL;\r\n\r\n        this._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag] = this._markAllSubMeshesAsTexturesDirty.bind(this);\r\n        this._dirtyCallbacks[Constants.MATERIAL_LightDirtyFlag] = this._markAllSubMeshesAsLightsDirty.bind(this);\r\n        this._dirtyCallbacks[Constants.MATERIAL_FresnelDirtyFlag] = this._markAllSubMeshesAsFresnelDirty.bind(this);\r\n        this._dirtyCallbacks[Constants.MATERIAL_AttributesDirtyFlag] = this._markAllSubMeshesAsAttributesDirty.bind(this);\r\n        this._dirtyCallbacks[Constants.MATERIAL_MiscDirtyFlag] = this._markAllSubMeshesAsMiscDirty.bind(this);\r\n        this._dirtyCallbacks[Constants.MATERIAL_PrePassDirtyFlag] = this._markAllSubMeshesAsPrePassDirty.bind(this);\r\n        this._dirtyCallbacks[Constants.MATERIAL_AllDirtyFlag] = this._markAllSubMeshesAsAllDirty.bind(this);\r\n\r\n        this.id = name || Tools.RandomId();\r\n        this.uniqueId = this._scene.getUniqueId();\r\n        this._materialContext = this._scene.getEngine().createMaterialContext();\r\n        this._drawWrapper = new DrawWrapper(this._scene.getEngine(), false);\r\n        this._drawWrapper.materialContext = this._materialContext;\r\n\r\n        this._uniformBuffer = new UniformBuffer(this._scene.getEngine(), undefined, undefined, name);\r\n        this._useUBO = this.getScene().getEngine().supportsUniformBuffers;\r\n\r\n        this._createUniformBuffer();\r\n\r\n        if (!doNotAdd) {\r\n            this._scene.addMaterial(this);\r\n        }\r\n\r\n        if (this._scene.useMaterialMeshMap) {\r\n            this.meshMap = {};\r\n        }\r\n\r\n        Material.OnEventObservable.notifyObservers(this, MaterialPluginEvent.Created);\r\n    }\r\n\r\n    /** @internal */\r\n    public _createUniformBuffer() {\r\n        const engine = this.getScene().getEngine();\r\n\r\n        this._uniformBuffer?.dispose();\r\n\r\n        if (engine.isWebGPU && !this._forceGLSL) {\r\n            // Switch main UBO to non UBO to connect to leftovers UBO in webgpu\r\n            this._uniformBuffer = new UniformBuffer(engine, undefined, undefined, this.name, true);\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        } else {\r\n            this._uniformBuffer = new UniformBuffer(this._scene.getEngine(), undefined, undefined, this.name);\r\n        }\r\n\r\n        this._uniformBufferLayoutBuilt = false;\r\n    }\r\n\r\n    /**\r\n     * Returns a string representation of the current material\r\n     * @param fullDetails defines a boolean indicating which levels of logging is desired\r\n     * @returns a string with material information\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public toString(fullDetails?: boolean): string {\r\n        const ret = \"Name: \" + this.name;\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the material\r\n     * @returns a string with the class name of the material\r\n     */\r\n    public getClassName(): string {\r\n        return \"Material\";\r\n    }\r\n\r\n    /** @internal */\r\n    public get _isMaterial() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Specifies if updates for the material been locked\r\n     */\r\n    public get isFrozen(): boolean {\r\n        return this.checkReadyOnlyOnce;\r\n    }\r\n\r\n    /**\r\n     * Locks updates for the material.\r\n     *\r\n     * Note: while a material is frozen, the scene can still rebind it at least\r\n     * once per camera render (and again whenever another material was bound in\r\n     * between). What can be skipped while the frozen material stays cached are\r\n     * per-mesh updates performed during a rebind.\r\n     *\r\n     * This includes per-mesh morph target influences. If the same frozen\r\n     * material is shared across several meshes that each have different\r\n     * per-mesh morph influences, only the mesh that triggers the rebind updates\r\n     * those values. Other meshes rendered afterward with the same cached frozen\r\n     * material may reuse stale influences and render with the wrong values.\r\n     *\r\n     * For that scenario either keep the material unfrozen, clone the material\r\n     * per mesh and freeze each clone, or `unfreeze()` before changing\r\n     * influences and `freeze()` again afterwards.\r\n     */\r\n    public freeze(): void {\r\n        this.markDirty();\r\n        this.checkReadyOnlyOnce = true;\r\n    }\r\n\r\n    /**\r\n     * Unlocks updates for the material\r\n     */\r\n    public unfreeze(): void {\r\n        this.markDirty();\r\n        this.checkReadyOnlyOnce = false;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material is ready to be used\r\n     * @param mesh defines the mesh to check\r\n     * @param useInstances specifies if instances should be used\r\n     * @returns a boolean indicating if the material is ready to be used\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Specifies that the submesh is ready to be used\r\n     * @param mesh defines the mesh to check\r\n     * @param subMesh defines which submesh to check\r\n     * @param useInstances specifies that instances should be used\r\n     * @returns a boolean indicating that the submesh is ready or not\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {\r\n        const defines = subMesh.materialDefines;\r\n        if (!defines) {\r\n            return false;\r\n        }\r\n\r\n        this._eventInfo.isReadyForSubMesh = true;\r\n        this._eventInfo.defines = defines;\r\n        this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);\r\n\r\n        return this._eventInfo.isReadyForSubMesh;\r\n    }\r\n\r\n    /**\r\n     * Returns the material effect\r\n     * @returns the effect associated with the material\r\n     */\r\n    public getEffect(): Nullable<Effect> {\r\n        return this._drawWrapper.effect;\r\n    }\r\n\r\n    /**\r\n     * Returns the current scene\r\n     * @returns a Scene\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /** @internal */\r\n    public _getEffectiveOrientation(mesh: Mesh): number {\r\n        return this.sideOrientation !== null ? this.sideOrientation : mesh.sideOrientation;\r\n    }\r\n\r\n    /**\r\n     * The transparency mode of the material.\r\n     */\r\n    protected _transparencyMode: Nullable<number> = null;\r\n\r\n    /**\r\n     * Gets the current transparency mode.\r\n     */\r\n    @serialize()\r\n    public get transparencyMode(): Nullable<number> {\r\n        return this._transparencyMode;\r\n    }\r\n\r\n    /**\r\n     * Sets the transparency mode of the material.\r\n     *\r\n     * | Value | Type                                | Description |\r\n     * | ----- | ----------------------------------- | ----------- |\r\n     * | 0     | OPAQUE                              |             |\r\n     * | 1     | ALPHATEST                           |             |\r\n     * | 2     | ALPHABLEND                          |             |\r\n     * | 3     | ALPHATESTANDBLEND                   |             |\r\n     *\r\n     */\r\n    public set transparencyMode(value: Nullable<number>) {\r\n        if (this._transparencyMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._transparencyMode = value;\r\n\r\n        this._markAllSubMeshesAsTexturesAndMiscDirty();\r\n    }\r\n\r\n    protected get _hasTransparencyMode(): boolean {\r\n        return this._transparencyMode != null;\r\n    }\r\n\r\n    protected get _transparencyModeIsBlend(): boolean {\r\n        return this._transparencyMode === Material.MATERIAL_ALPHABLEND || this._transparencyMode === Material.MATERIAL_ALPHATESTANDBLEND;\r\n    }\r\n\r\n    protected get _transparencyModeIsTest(): boolean {\r\n        return this._transparencyMode === Material.MATERIAL_ALPHATEST || this._transparencyMode === Material.MATERIAL_ALPHATESTANDBLEND;\r\n    }\r\n\r\n    /**\r\n     * Returns true if alpha blending should be disabled.\r\n     */\r\n    protected get _disableAlphaBlending(): boolean {\r\n        return this._transparencyMode === Material.MATERIAL_OPAQUE || this._transparencyMode === Material.MATERIAL_ALPHATEST;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not this material should be rendered in alpha blend mode.\r\n     * @returns a boolean specifying if alpha blending is needed\r\n     * @deprecated Please use needAlphaBlendingForMesh instead\r\n     */\r\n    public needAlphaBlending(): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsBlend;\r\n        }\r\n\r\n        if (this._disableAlphaBlending) {\r\n            return false;\r\n        }\r\n\r\n        return this.alpha < 1.0;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the mesh will require alpha blending\r\n     * @param mesh defines the mesh to check\r\n     * @returns a boolean specifying if alpha blending is needed for the mesh\r\n     */\r\n    public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsBlend;\r\n        }\r\n\r\n        if (mesh.visibility < 1.0) {\r\n            return true;\r\n        }\r\n\r\n        if (this._disableAlphaBlending) {\r\n            return false;\r\n        }\r\n\r\n        return mesh.hasVertexAlpha || this.needAlphaBlending();\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not this material should be rendered in alpha test mode.\r\n     * @returns a boolean specifying if an alpha test is needed.\r\n     * @deprecated Please use needAlphaTestingForMesh instead\r\n     */\r\n    public needAlphaTesting(): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsTest;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Specifies if material alpha testing should be turned on for the mesh\r\n     * @param mesh defines the mesh to check\r\n     * @returns a boolean specifying if alpha testing should be turned on for the mesh\r\n     */\r\n    public needAlphaTestingForMesh(mesh: AbstractMesh): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsTest;\r\n        }\r\n\r\n        return !this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting();\r\n    }\r\n\r\n    /**\r\n     * Gets the texture used for the alpha test\r\n     * @returns the texture to use for alpha testing\r\n     */\r\n    public getAlphaTestTexture(): Nullable<BaseTexture> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Marks the material to indicate that it needs to be re-calculated\r\n     * @param forceMaterialDirty - Forces the material to be marked as dirty for all components (same as this.markAsDirty(Material.AllDirtyFlag)). You should use this flag if the material is frozen and you want to force a recompilation.\r\n     */\r\n    public markDirty(forceMaterialDirty = false): void {\r\n        const meshes = this.getScene().meshes;\r\n        for (const mesh of meshes) {\r\n            if (!mesh.subMeshes) {\r\n                continue;\r\n            }\r\n            for (const subMesh of mesh.subMeshes) {\r\n                if (subMesh.getMaterial() !== this) {\r\n                    continue;\r\n                }\r\n\r\n                for (const drawWrapper of subMesh._drawWrappers) {\r\n                    if (!drawWrapper) {\r\n                        continue;\r\n                    }\r\n                    if (this._materialContext === drawWrapper.materialContext) {\r\n                        drawWrapper._wasPreviouslyReady = false;\r\n                        drawWrapper._wasPreviouslyUsingInstances = null;\r\n                        drawWrapper._forceRebindOnNextCall = forceMaterialDirty;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (forceMaterialDirty) {\r\n            this.markAsDirty(Material.AllDirtyFlag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _preBind(effect?: Effect | DrawWrapper, overrideOrientation: Nullable<number> = null): boolean {\r\n        const engine = this._scene.getEngine();\r\n\r\n        const orientation = overrideOrientation == null ? this.sideOrientation : overrideOrientation;\r\n        const reverse = orientation === Material.ClockWiseSideOrientation;\r\n\r\n        const effectiveDrawWrapper = effect ? effect : this._getDrawWrapper();\r\n\r\n        if (IsWrapper(effectiveDrawWrapper) && effectiveDrawWrapper.materialContext) {\r\n            effectiveDrawWrapper.materialContext.useVertexPulling = this.useVertexPulling;\r\n        }\r\n\r\n        engine.enableEffect(effectiveDrawWrapper);\r\n        engine.setState(\r\n            this.backFaceCulling,\r\n            this.zOffset,\r\n            false,\r\n            reverse,\r\n            this._scene._mirroredCameraPosition ? !this.cullBackFaces : this.cullBackFaces,\r\n            this.stencil,\r\n            this.zOffsetUnits\r\n        );\r\n\r\n        return reverse;\r\n    }\r\n\r\n    /**\r\n     * Binds the material to the mesh\r\n     * @param world defines the world transformation matrix\r\n     * @param mesh defines the mesh to bind the material to\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public bind(world: Matrix, mesh?: Mesh): void {}\r\n\r\n    /**\r\n     * Initializes the uniform buffer layout for the shader.\r\n     */\r\n    public buildUniformLayout(): void {\r\n        const ubo = this._uniformBuffer;\r\n\r\n        this._eventInfo.ubo = ubo;\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.PrepareUniformBuffer, this._eventInfo);\r\n\r\n        ubo.create();\r\n\r\n        this._uniformBufferLayoutBuilt = true;\r\n    }\r\n\r\n    /**\r\n     * Binds the submesh to the material\r\n     * @param world defines the world transformation matrix\r\n     * @param mesh defines the mesh containing the submesh\r\n     * @param subMesh defines the submesh to bind the material to\r\n     */\r\n    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\r\n        const drawWrapper = subMesh._drawWrapper;\r\n\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventBindForSubMesh(this._eventInfo);\r\n        drawWrapper._forceRebindOnNextCall = false;\r\n    }\r\n\r\n    /**\r\n     * Binds the world matrix to the material\r\n     * @param world defines the world transformation matrix\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public bindOnlyWorldMatrix(world: Matrix): void {}\r\n\r\n    /**\r\n     * Binds the view matrix to the effect\r\n     * @param effect defines the effect to bind the view matrix to\r\n     */\r\n    public bindView(effect: Effect): void {\r\n        if (!this._useUBO) {\r\n            effect.setMatrix(\"view\", this.getScene().getViewMatrix());\r\n        } else {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the view projection and projection matrices to the effect\r\n     * @param effect defines the effect to bind the view projection and projection matrices to\r\n     */\r\n    public bindViewProjection(effect: Effect): void {\r\n        if (!this._useUBO) {\r\n            effect.setMatrix(\"viewProjection\", this.getScene().getTransformMatrix());\r\n            effect.setMatrix(\"projection\", this.getScene().getProjectionMatrix());\r\n            effect.setMatrix(\"inverseProjection\", this.getScene().getInverseProjectionMatrix());\r\n        } else {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the view matrix to the effect\r\n     * @param effect defines the effect to bind the view matrix to\r\n     * @param variableName name of the shader variable that will hold the eye position\r\n     */\r\n    public bindEyePosition(effect: Effect, variableName?: string): void {\r\n        if (!this._useUBO) {\r\n            this._scene.bindEyePosition(effect, variableName);\r\n        } else {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Processes to execute after binding the material to a mesh\r\n     * @param mesh defines the rendered mesh\r\n     * @param effect defines the effect used to bind the material\r\n     * @param _subMesh defines the subMesh that the material has been bound for\r\n     */\r\n    protected _afterBind(mesh?: AbstractMesh, effect: Nullable<Effect> = null, _subMesh?: SubMesh): void {\r\n        this._scene._cachedMaterial = this;\r\n        if (this._needToBindSceneUbo) {\r\n            if (effect) {\r\n                this._needToBindSceneUbo = false;\r\n                BindSceneUniformBuffer(effect, this.getScene().getSceneUniformBuffer());\r\n                this._scene.finalizeSceneUbo();\r\n            }\r\n        }\r\n        if (mesh) {\r\n            this._scene._cachedVisibility = mesh.visibility;\r\n        } else {\r\n            this._scene._cachedVisibility = 1;\r\n        }\r\n\r\n        if (this._onBindObservable && mesh) {\r\n            this._onBindObservable.notifyObservers(mesh);\r\n        }\r\n\r\n        if (this.disableDepthWrite) {\r\n            const engine = this._scene.getEngine();\r\n            this._cachedDepthWriteState = engine.getDepthWrite();\r\n            engine.setDepthWrite(false);\r\n        }\r\n\r\n        if (this.disableColorWrite) {\r\n            const engine = this._scene.getEngine();\r\n            this._cachedColorWriteState = engine.getColorWrite();\r\n            engine.setColorWrite(false);\r\n        }\r\n\r\n        if (this.depthFunction !== 0) {\r\n            const engine = this._scene.getEngine();\r\n            this._cachedDepthFunctionState = engine.getDepthFunction() || 0;\r\n            engine.setDepthFunction(this.depthFunction);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Unbinds the material from the mesh\r\n     */\r\n    public unbind(): void {\r\n        this._scene.getSceneUniformBuffer().unbindEffect();\r\n\r\n        if (this._onUnBindObservable) {\r\n            this._onUnBindObservable.notifyObservers(this);\r\n        }\r\n\r\n        if (this.depthFunction !== 0) {\r\n            const engine = this._scene.getEngine();\r\n            engine.setDepthFunction(this._cachedDepthFunctionState);\r\n        }\r\n\r\n        if (this.disableDepthWrite) {\r\n            const engine = this._scene.getEngine();\r\n            engine.setDepthWrite(this._cachedDepthWriteState);\r\n        }\r\n\r\n        if (this.disableColorWrite) {\r\n            const engine = this._scene.getEngine();\r\n            engine.setColorWrite(this._cachedColorWriteState);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the animatable textures.\r\n     * @returns - Array of animatable textures.\r\n     */\r\n    public getAnimatables(): IAnimatable[] {\r\n        this._eventInfo.animatables = [];\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.GetAnimatables, this._eventInfo);\r\n        return this._eventInfo.animatables;\r\n    }\r\n\r\n    /**\r\n     * Gets the active textures from the material\r\n     * @returns an array of textures\r\n     */\r\n    public getActiveTextures(): BaseTexture[] {\r\n        this._eventInfo.activeTextures = [];\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.GetActiveTextures, this._eventInfo);\r\n        return this._eventInfo.activeTextures;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material uses a texture\r\n     * @param texture defines the texture to check against the material\r\n     * @returns a boolean specifying if the material uses the texture\r\n     */\r\n    public hasTexture(texture: BaseTexture): boolean {\r\n        this._eventInfo.hasTexture = false;\r\n        this._eventInfo.texture = texture;\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.HasTexture, this._eventInfo);\r\n        return this._eventInfo.hasTexture;\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the material, and gives it a new name\r\n     * @param name defines the new name for the duplicated material\r\n     * @returns the cloned material\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public clone(name: string): Nullable<Material> {\r\n        return null;\r\n    }\r\n\r\n    protected _clonePlugins(targetMaterial: Material, rootUrl: string) {\r\n        const serializationObject: any = {};\r\n\r\n        // Create plugins in targetMaterial in case they don't exist\r\n        this._serializePlugins(serializationObject);\r\n\r\n        Material._ParsePlugins(serializationObject, targetMaterial, this._scene, rootUrl);\r\n\r\n        // Copy the properties of the current plugins to the cloned material's plugins\r\n        if (this.pluginManager) {\r\n            for (const plugin of this.pluginManager._plugins) {\r\n                const targetPlugin = targetMaterial.pluginManager!.getPlugin(plugin.name);\r\n                if (targetPlugin) {\r\n                    plugin.copyTo(targetPlugin);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the meshes bound to the material\r\n     * @returns an array of meshes bound to the material\r\n     */\r\n    public getBindedMeshes(): AbstractMesh[] {\r\n        if (this.meshMap) {\r\n            const result: AbstractMesh[] = [];\r\n            for (const meshId in this.meshMap) {\r\n                const mesh = this.meshMap[meshId];\r\n                if (mesh) {\r\n                    result.push(mesh);\r\n                }\r\n            }\r\n            return result;\r\n        } else {\r\n            const meshes = this._scene.meshes;\r\n            return meshes.filter((mesh) => mesh.material === this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Force shader compilation\r\n     * @param mesh defines the mesh associated with this material\r\n     * @param onCompiled defines a function to execute once the material is compiled\r\n     * @param options defines the options to configure the compilation\r\n     * @param onError defines a function to execute if the material fails compiling\r\n     */\r\n    public forceCompilation(\r\n        mesh: AbstractMesh,\r\n        onCompiled?: (material: Material) => void,\r\n        options?: Partial<IMaterialCompilationOptions>,\r\n        onError?: (reason: string) => void\r\n    ): void {\r\n        const localOptions = {\r\n            clipPlane: false,\r\n            useInstances: false,\r\n            ...options,\r\n        };\r\n\r\n        const scene = this.getScene();\r\n        const currentHotSwapingState = this.allowShaderHotSwapping;\r\n        this.allowShaderHotSwapping = false; // Turned off to let us evaluate the real compilation state\r\n\r\n        const checkReady = () => {\r\n            if (!this._scene || !this._scene.getEngine()) {\r\n                return;\r\n            }\r\n\r\n            const clipPlaneState = scene.clipPlane;\r\n\r\n            if (localOptions.clipPlane) {\r\n                scene.clipPlane = new Plane(0, 0, 0, 1);\r\n            }\r\n\r\n            if (this._storeEffectOnSubMeshes) {\r\n                let allDone = true,\r\n                    lastError = null;\r\n                if (mesh.subMeshes) {\r\n                    const tempSubMesh = new SubMesh(0, 0, 0, 0, 0, mesh, undefined, false, false);\r\n                    if (tempSubMesh.materialDefines) {\r\n                        tempSubMesh.materialDefines._renderId = -1;\r\n                    }\r\n                    if (!this.isReadyForSubMesh(mesh, tempSubMesh, localOptions.useInstances)) {\r\n                        if (tempSubMesh.effect && tempSubMesh.effect.getCompilationError() && tempSubMesh.effect.allFallbacksProcessed()) {\r\n                            lastError = tempSubMesh.effect.getCompilationError();\r\n                        } else {\r\n                            allDone = false;\r\n                            setTimeout(checkReady, 16);\r\n                        }\r\n                    }\r\n                }\r\n                if (allDone) {\r\n                    this.allowShaderHotSwapping = currentHotSwapingState;\r\n                    if (lastError) {\r\n                        if (onError) {\r\n                            onError(lastError);\r\n                        }\r\n                    }\r\n                    if (onCompiled) {\r\n                        onCompiled(this);\r\n                    }\r\n                }\r\n            } else {\r\n                if (this.isReady()) {\r\n                    this.allowShaderHotSwapping = currentHotSwapingState;\r\n                    if (onCompiled) {\r\n                        onCompiled(this);\r\n                    }\r\n                } else {\r\n                    setTimeout(checkReady, 16);\r\n                }\r\n            }\r\n\r\n            if (localOptions.clipPlane) {\r\n                scene.clipPlane = clipPlaneState;\r\n            }\r\n        };\r\n\r\n        checkReady();\r\n    }\r\n\r\n    /**\r\n     * Force shader compilation\r\n     * @param mesh defines the mesh that will use this material\r\n     * @param options defines additional options for compiling the shaders\r\n     * @returns a promise that resolves when the compilation completes\r\n     */\r\n    public async forceCompilationAsync(mesh: AbstractMesh, options?: Partial<IMaterialCompilationOptions>): Promise<void> {\r\n        return await new Promise((resolve, reject) => {\r\n            this.forceCompilation(\r\n                mesh,\r\n                () => {\r\n                    resolve();\r\n                },\r\n                options,\r\n                (reason) => {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(reason);\r\n                }\r\n            );\r\n        });\r\n    }\r\n\r\n    private static readonly _AllDirtyCallBack = (defines: MaterialDefines) => defines.markAllAsDirty();\r\n    private static readonly _ImageProcessingDirtyCallBack = (defines: MaterialDefines) => defines.markAsImageProcessingDirty();\r\n    private static readonly _TextureDirtyCallBack = (defines: MaterialDefines) => defines.markAsTexturesDirty();\r\n    private static readonly _FresnelDirtyCallBack = (defines: MaterialDefines) => defines.markAsFresnelDirty();\r\n    private static readonly _MiscDirtyCallBack = (defines: MaterialDefines) => defines.markAsMiscDirty();\r\n    private static readonly _PrePassDirtyCallBack = (defines: MaterialDefines) => defines.markAsPrePassDirty();\r\n    private static readonly _LightsDirtyCallBack = (defines: MaterialDefines) => defines.markAsLightDirty();\r\n    private static readonly _AttributeDirtyCallBack = (defines: MaterialDefines) => defines.markAsAttributesDirty();\r\n\r\n    private static _FresnelAndMiscDirtyCallBack = (defines: MaterialDefines) => {\r\n        Material._FresnelDirtyCallBack(defines);\r\n        Material._MiscDirtyCallBack(defines);\r\n    };\r\n\r\n    private static _TextureAndMiscDirtyCallBack = (defines: MaterialDefines) => {\r\n        Material._TextureDirtyCallBack(defines);\r\n        Material._MiscDirtyCallBack(defines);\r\n    };\r\n\r\n    private static readonly _DirtyCallbackArray: Array<(defines: MaterialDefines) => void> = [];\r\n    private static readonly _RunDirtyCallBacks = (defines: MaterialDefines) => {\r\n        for (const cb of Material._DirtyCallbackArray) {\r\n            cb(defines);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Marks a define in the material to indicate that it needs to be re-computed\r\n     * @param flag defines a flag used to determine which parts of the material have to be marked as dirty\r\n     */\r\n    public markAsDirty(flag: number): void {\r\n        if (this.getScene().blockMaterialDirtyMechanism || this._blockDirtyMechanism) {\r\n            return;\r\n        }\r\n\r\n        Material._DirtyCallbackArray.length = 0;\r\n\r\n        if (flag & Material.ImageProcessingDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._ImageProcessingDirtyCallBack);\r\n        }\r\n\r\n        if (flag & Material.TextureDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._TextureDirtyCallBack);\r\n        }\r\n\r\n        if (flag & Material.LightDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._LightsDirtyCallBack);\r\n        }\r\n\r\n        if (flag & Material.FresnelDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._FresnelDirtyCallBack);\r\n        }\r\n\r\n        if (flag & Material.AttributesDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._AttributeDirtyCallBack);\r\n        }\r\n\r\n        if (flag & Material.MiscDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._MiscDirtyCallBack);\r\n        }\r\n\r\n        if (flag & Material.PrePassDirtyFlag) {\r\n            Material._DirtyCallbackArray.push(Material._PrePassDirtyCallBack);\r\n        }\r\n\r\n        if (Material._DirtyCallbackArray.length) {\r\n            this._markAllSubMeshesAsDirty(Material._RunDirtyCallBacks);\r\n        }\r\n\r\n        this.getScene().resetCachedMaterial();\r\n    }\r\n\r\n    /**\r\n     * Resets the draw wrappers cache for all submeshes that are using this material\r\n     */\r\n    public resetDrawCache(): void {\r\n        const meshes = this.getScene().meshes;\r\n        for (const mesh of meshes) {\r\n            if (!mesh.subMeshes) {\r\n                continue;\r\n            }\r\n            for (const subMesh of mesh.subMeshes) {\r\n                if (subMesh.getMaterial() !== this) {\r\n                    continue;\r\n                }\r\n\r\n                subMesh.resetDrawCache();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Marks all submeshes of a material to indicate that their material defines need to be re-calculated\r\n     * @param func defines a function which checks material defines against the submeshes\r\n     */\r\n    protected _markAllSubMeshesAsDirty(func: (defines: MaterialDefines) => void) {\r\n        const scene = this.getScene();\r\n        if (scene.blockMaterialDirtyMechanism || this._blockDirtyMechanism) {\r\n            return;\r\n        }\r\n\r\n        const meshes = scene.meshes;\r\n        for (const mesh of meshes) {\r\n            if (!mesh.subMeshes) {\r\n                continue;\r\n            }\r\n            for (const subMesh of mesh.subMeshes) {\r\n                // We want to skip the submeshes which are not using this material or which have not yet rendered at least once\r\n                const material = subMesh.getMaterial() || (scene._hasDefaultMaterial ? scene.defaultMaterial : null);\r\n                if (material !== this) {\r\n                    continue;\r\n                }\r\n\r\n                for (const drawWrapper of subMesh._drawWrappers) {\r\n                    if (!drawWrapper || !drawWrapper.defines || !(drawWrapper.defines as MaterialDefines).markAllAsDirty) {\r\n                        continue;\r\n                    }\r\n                    if (this._materialContext === drawWrapper.materialContext) {\r\n                        func(drawWrapper.defines as MaterialDefines);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates that the scene should check if the rendering now needs a prepass\r\n     */\r\n    protected _markScenePrePassDirty() {\r\n        if (this.getScene().blockMaterialDirtyMechanism || this._blockDirtyMechanism) {\r\n            return;\r\n        }\r\n\r\n        const prePassRenderer = this.getScene().enablePrePassRenderer();\r\n        if (prePassRenderer) {\r\n            prePassRenderer.markAsDirty();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates that we need to re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsAllDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._AllDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that image processing needs to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsImageProcessingDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._ImageProcessingDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that textures need to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsTexturesDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._TextureDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that fresnel needs to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsFresnelDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._FresnelDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that fresnel and misc need to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsFresnelAndMiscDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._FresnelAndMiscDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that lights need to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsLightsDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._LightsDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that attributes need to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsAttributesDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._AttributeDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that misc needs to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsMiscDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._MiscDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that prepass needs to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsPrePassDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._PrePassDirtyCallBack);\r\n    }\r\n\r\n    /**\r\n     * Indicates that textures and misc need to be re-calculated for all submeshes\r\n     */\r\n    protected _markAllSubMeshesAsTexturesAndMiscDirty() {\r\n        this._markAllSubMeshesAsDirty(Material._TextureAndMiscDirtyCallBack);\r\n    }\r\n\r\n    protected _checkScenePerformancePriority() {\r\n        if (this._scene.performancePriority !== ScenePerformancePriority.BackwardCompatible) {\r\n            this.checkReadyOnlyOnce = true;\r\n            // re-set the flag when the perf priority changes\r\n            const observer = this._scene.onScenePerformancePriorityChangedObservable.addOnce(() => {\r\n                this.checkReadyOnlyOnce = false;\r\n            });\r\n            // if this material is disposed before the scene is disposed, cleanup the observer\r\n            this.onDisposeObservable.add(() => {\r\n                this._scene.onScenePerformancePriorityChangedObservable.remove(observer);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the required values to the prepass renderer.\r\n     * @param prePassRenderer defines the prepass renderer to setup.\r\n     * @returns true if the pre pass is needed.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {\r\n        // Do Nothing by default\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Disposes the material\r\n     * @param _forceDisposeEffect kept for backward compat. We reference count the effect now.\r\n     * @param forceDisposeTextures specifies if textures should be forcefully disposed\r\n     * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh\r\n     */\r\n    public dispose(_forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, notBoundToMesh?: boolean): void {\r\n        const scene = this.getScene();\r\n        // Animations\r\n        scene.stopAnimation(this);\r\n        scene.freeProcessedMaterials();\r\n\r\n        // Remove from scene\r\n        scene.removeMaterial(this);\r\n\r\n        this._eventInfo.forceDisposeTextures = forceDisposeTextures;\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.Disposed, this._eventInfo);\r\n\r\n        if (this._parentContainer) {\r\n            const index = this._parentContainer.materials.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.materials.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        if (notBoundToMesh !== true) {\r\n            // Remove from meshes\r\n            if (this.meshMap) {\r\n                for (const meshId in this.meshMap) {\r\n                    const mesh = this.meshMap[meshId];\r\n                    this._disposeMeshResources(mesh);\r\n                }\r\n            } else {\r\n                const meshes = scene.meshes;\r\n                for (const mesh of meshes) {\r\n                    this._disposeMeshResources(mesh);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._uniformBuffer.dispose();\r\n\r\n        // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect\r\n        if (this._drawWrapper.effect) {\r\n            if (!this._storeEffectOnSubMeshes) {\r\n                this._drawWrapper.effect.dispose();\r\n            }\r\n\r\n            this._drawWrapper.effect = null;\r\n        }\r\n\r\n        this.metadata = null;\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n\r\n        this.onDisposeObservable.clear();\r\n        if (this._onBindObservable) {\r\n            this._onBindObservable.clear();\r\n        }\r\n\r\n        if (this._onUnBindObservable) {\r\n            this._onUnBindObservable.clear();\r\n        }\r\n\r\n        if (this._onEffectCreatedObservable) {\r\n            this._onEffectCreatedObservable.clear();\r\n        }\r\n\r\n        if (this._eventInfo) {\r\n            this._eventInfo = {} as any;\r\n        }\r\n    }\r\n\r\n    private _disposeMeshResources(mesh: AbstractMesh | undefined) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const geometry = (<Mesh>mesh).geometry;\r\n        const materialForRenderPass = mesh._internalAbstractMeshDataInfo._materialForRenderPass;\r\n        if (this._storeEffectOnSubMeshes) {\r\n            if (mesh.subMeshes && materialForRenderPass) {\r\n                for (const subMesh of mesh.subMeshes) {\r\n                    const drawWrappers = subMesh._drawWrappers;\r\n                    for (let renderPassIndex = 0; renderPassIndex < drawWrappers.length; renderPassIndex++) {\r\n                        const effect = drawWrappers[renderPassIndex]?.effect;\r\n                        if (!effect) {\r\n                            continue;\r\n                        }\r\n                        const material = materialForRenderPass[renderPassIndex];\r\n                        if (material === this) {\r\n                            geometry?._releaseVertexArrayObject(effect);\r\n                            subMesh._removeDrawWrapper(renderPassIndex, true, true);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            geometry?._releaseVertexArrayObject(this._drawWrapper.effect);\r\n        }\r\n\r\n        if (mesh.material === this && !(mesh as InstancedMesh).sourceMesh) {\r\n            mesh.material = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this material\r\n     * @returns the serialized material object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n\r\n        serializationObject.stencil = this.stencil.serialize();\r\n        serializationObject.uniqueId = this.uniqueId;\r\n\r\n        this._serializePlugins(serializationObject);\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    protected _serializePlugins(serializationObject: any) {\r\n        serializationObject.plugins = {};\r\n\r\n        if (this.pluginManager) {\r\n            for (const plugin of this.pluginManager._plugins) {\r\n                if (!plugin.doNotSerialize) {\r\n                    serializationObject.plugins[plugin.getClassName()] = plugin.serialize();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Parses the alpha mode from the material data to parse\r\n     * @param parsedMaterial defines the material data to parse\r\n     * @param material defines the material to update\r\n     */\r\n    public static ParseAlphaMode(parsedMaterial: any, material: Material) {\r\n        if (parsedMaterial._alphaMode !== undefined) {\r\n            material._alphaMode = Array.isArray(parsedMaterial._alphaMode) ? [...parsedMaterial._alphaMode] : [parsedMaterial._alphaMode];\r\n        } else if (parsedMaterial.alphaMode !== undefined) {\r\n            material._alphaMode = Array.isArray(parsedMaterial.alphaMode) ? [...parsedMaterial.alphaMode] : [parsedMaterial.alphaMode];\r\n        } else {\r\n            material._alphaMode = [Constants.ALPHA_COMBINE];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a material from parsed material data\r\n     * @param parsedMaterial defines parsed material data\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures\r\n     * @returns a new material\r\n     */\r\n    public static Parse(parsedMaterial: any, scene: Scene, rootUrl: string): Nullable<Material> {\r\n        if (!parsedMaterial.customType) {\r\n            parsedMaterial.customType = \"BABYLON.StandardMaterial\";\r\n        } else if (parsedMaterial.customType === \"BABYLON.PBRMaterial\" && parsedMaterial.overloadedAlbedo) {\r\n            parsedMaterial.customType = \"BABYLON.LegacyPBRMaterial\";\r\n            if (!BABYLON.LegacyPBRMaterial) {\r\n                Logger.Error(\"Your scene is trying to load a legacy version of the PBRMaterial, please, include it from the materials library.\");\r\n                return null;\r\n            }\r\n        }\r\n\r\n        const materialType = Tools.Instantiate(parsedMaterial.customType);\r\n        const material = materialType.Parse(parsedMaterial, scene, rootUrl);\r\n        material._loadedUniqueId = parsedMaterial.uniqueId;\r\n\r\n        Material.ParseAlphaMode(parsedMaterial, material);\r\n\r\n        return material;\r\n    }\r\n\r\n    protected static _ParsePlugins(serializationObject: any, material: Material, scene: Scene, rootUrl: string) {\r\n        if (!serializationObject.plugins) {\r\n            return;\r\n        }\r\n\r\n        for (const pluginClassName in serializationObject.plugins) {\r\n            const pluginData = serializationObject.plugins[pluginClassName];\r\n\r\n            let plugin = material.pluginManager?.getPlugin(pluginData.name);\r\n\r\n            if (!plugin) {\r\n                const pluginClassType = Tools.Instantiate(\"BABYLON.\" + pluginClassName);\r\n                if (pluginClassType) {\r\n                    plugin = new pluginClassType(material);\r\n                }\r\n            }\r\n\r\n            plugin?.parse(pluginData, scene, rootUrl);\r\n        }\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffectProperty } from \"../Misc/devTools\";\r\n\r\nif (!Object.getOwnPropertyDescriptor(Material.prototype, \"pluginManager\")) {\r\n    Object.defineProperty(Material.prototype, \"pluginManager\", _MissingSideEffectProperty(\"Material\", \"pluginManager\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","import { type MaterialDefines, type Effect, type Mesh, type AbstractMesh, type Material, type AbstractEngine } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Matrix } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * Provides the object ID written by geometry rendering for a mesh.\r\n *\r\n * IDs must be unsigned integers supported by the object ID texture format. ID 0 is reserved for background or excluded meshes.\r\n * RGBA textures support IDs up to 0xFFFFFF, while RED textures support IDs up to 0xFF.\r\n * Instances and thin instances use the source mesh ID, and this callback receives the source mesh for instanced draws.\r\n * This callback runs in the render hot path and may be called multiple times for the same mesh in a frame.\r\n * It should avoid allocations and return a consistent value for a mesh during a render.\r\n */\r\nexport type GeometryRenderingObjectIdProvider = (mesh: AbstractMesh) => number;\r\n\r\n/**\r\n * Provides the packed mesh-blending tag written by geometry rendering for a mesh.\r\n *\r\n * Tags must be 0 or contain a group ID between 1 and 63 in their low six bits. Tag 0 disables mesh blending.\r\n * Instances and thin instances use the source mesh tag. This callback receives the source mesh for instanced draws.\r\n * It runs in the render hot path and should avoid allocations and return a consistent value during a render.\r\n */\r\nexport type GeometryRenderingMeshBlendTagProvider = (mesh: AbstractMesh) => number;\r\n\r\n/** @internal */\r\nexport function _GetGeometryRenderingObjectId(mesh: AbstractMesh, provider: GeometryRenderingObjectIdProvider, maxObjectId = 0xffffff): number {\r\n    const objectId = provider(mesh);\r\n\r\n    if (!Number.isInteger(objectId) || objectId < 0 || objectId > maxObjectId) {\r\n        throw new Error(`Invalid geometry object ID ${objectId} for mesh \"${mesh.name}\". Object IDs must be integers between 0 and 0x${maxObjectId.toString(16).toUpperCase()}.`);\r\n    }\r\n\r\n    return objectId;\r\n}\r\n\r\n/** @internal */\r\nexport function _GetGeometryRenderingMeshBlendTag(mesh: AbstractMesh, provider: GeometryRenderingMeshBlendTagProvider): number {\r\n    const tag = provider(mesh);\r\n\r\n    if (!Number.isInteger(tag) || tag < 0 || tag > 0xff || (tag !== 0 && (tag & 0x3f) === 0)) {\r\n        throw new Error(`Invalid geometry mesh-blending tag ${tag} for mesh \"${mesh.name}\". Tags must be 0 or contain a group ID between 1 and 63.`);\r\n    }\r\n\r\n    return tag;\r\n}\r\n\r\n/**\r\n * Type of clear operation to perform on a geometry texture.\r\n */\r\nexport const enum GeometryRenderingTextureClearType {\r\n    /**\r\n     * Clear the texture with zero.\r\n     */\r\n    Zero = 0,\r\n\r\n    /**\r\n     * Clear the texture with one.\r\n     */\r\n    One = 1,\r\n\r\n    /**\r\n     * Clear the texture with the maximum view Z value.\r\n     */\r\n    MaxViewZ = 2,\r\n\r\n    /**\r\n     * Do not clear the texture.\r\n     */\r\n    NoClear = 3,\r\n}\r\n\r\n/**\r\n * Configuration for geometry rendering.\r\n * A configuration is created for each rendering pass a geometry rendering is used in.\r\n */\r\nexport type GeometryRenderingConfiguration = {\r\n    /** @internal */\r\n    _attachments?: number[];\r\n\r\n    /** @internal */\r\n    _colorAttachments?: number[];\r\n\r\n    /** @internal */\r\n    _mrtCount?: number;\r\n\r\n    /** @internal */\r\n    _defines?: string;\r\n\r\n    /** @internal */\r\n    _currentWorldMatrices?: { [index: number]: Matrix };\r\n\r\n    /** @internal */\r\n    _worldMatrixFrameIds?: { [index: number]: number };\r\n\r\n    /**\r\n     * Defines used for the geometry rendering.\r\n     */\r\n    defines: { [name: string]: number };\r\n\r\n    /**\r\n     * Previous world matrices for meshes.\r\n     */\r\n    previousWorldMatrices: { [index: number]: Matrix };\r\n\r\n    /**\r\n     * Previous view projection matrix.\r\n     */\r\n    previousViewProjection: Matrix;\r\n\r\n    /**\r\n     * Current view projection matrix.\r\n     */\r\n    currentViewProjection: Matrix;\r\n\r\n    /**\r\n     * Previous bones for skinned meshes.\r\n     */\r\n    previousBones: { [index: number]: Float32Array };\r\n\r\n    /**\r\n     * Last frame id the configuration was updated.\r\n     */\r\n    lastUpdateFrameId: number;\r\n\r\n    /**\r\n     * List of excluded skinned meshes.\r\n     */\r\n    excludedSkinnedMesh: AbstractMesh[];\r\n\r\n    /**\r\n     * Whether to reverse culling for the geometry rendering (meaning, if back faces should be culled, front faces are culled instead, and the other way around).\r\n     */\r\n    reverseCulling: boolean;\r\n\r\n    /**\r\n     * Provides the object ID written for each rendered mesh.\r\n     */\r\n    objectIdProvider?: GeometryRenderingObjectIdProvider;\r\n\r\n    /**\r\n     * Whether the object ID texture uses the RED format.\r\n     */\r\n    objectIdIsRedFormat: boolean;\r\n\r\n    /**\r\n     * Provides the packed mesh-blending tag written for each rendered mesh.\r\n     */\r\n    meshBlendTagProvider?: GeometryRenderingMeshBlendTagProvider;\r\n};\r\n\r\n/**\r\n * Helper class to manage geometry rendering.\r\n */\r\nexport class MaterialHelperGeometryRendering {\r\n    /**\r\n     * Descriptions of the geometry textures.\r\n     */\r\n    public static readonly GeometryTextureDescriptions = [\r\n        {\r\n            type: Constants.PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE,\r\n            name: \"IrradianceLegacy\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_IRRADIANCE_LEGACY\",\r\n            defineIndex: \"PREPASS_IRRADIANCE_LEGACY_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_POSITION_TEXTURE_TYPE,\r\n            name: \"WorldPosition\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_POSITION\",\r\n            defineIndex: \"PREPASS_POSITION_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,\r\n            name: \"Velocity\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_VELOCITY\",\r\n            defineIndex: \"PREPASS_VELOCITY_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,\r\n            name: \"Reflectivity\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_REFLECTIVITY\",\r\n            defineIndex: \"PREPASS_REFLECTIVITY_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_DEPTH_TEXTURE_TYPE,\r\n            name: \"ViewDepth\",\r\n            clearType: GeometryRenderingTextureClearType.MaxViewZ,\r\n            define: \"PREPASS_DEPTH\",\r\n            defineIndex: \"PREPASS_DEPTH_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_NORMAL_TEXTURE_TYPE,\r\n            name: \"ViewNormal\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_NORMAL\",\r\n            defineIndex: \"PREPASS_NORMAL_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_ALBEDO_SQRT_TEXTURE_TYPE,\r\n            name: \"AlbedoSqrt\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_ALBEDO_SQRT\",\r\n            defineIndex: \"PREPASS_ALBEDO_SQRT_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE,\r\n            name: \"WorldNormal\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_WORLD_NORMAL\",\r\n            defineIndex: \"PREPASS_WORLD_NORMAL_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE,\r\n            name: \"LocalPosition\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_LOCAL_POSITION\",\r\n            defineIndex: \"PREPASS_LOCAL_POSITION_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE,\r\n            name: \"ScreenDepth\",\r\n            clearType: GeometryRenderingTextureClearType.One,\r\n            define: \"PREPASS_SCREENSPACE_DEPTH\",\r\n            defineIndex: \"PREPASS_SCREENSPACE_DEPTH_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE,\r\n            name: \"LinearVelocity\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_VELOCITY_LINEAR\",\r\n            defineIndex: \"PREPASS_VELOCITY_LINEAR_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_ALBEDO_TEXTURE_TYPE,\r\n            name: \"Albedo\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_ALBEDO\",\r\n            defineIndex: \"PREPASS_ALBEDO_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_NORMALIZED_VIEW_DEPTH_TEXTURE_TYPE,\r\n            name: \"NormalizedViewDepth\",\r\n            clearType: GeometryRenderingTextureClearType.One,\r\n            define: \"PREPASS_NORMALIZED_VIEW_DEPTH\",\r\n            defineIndex: \"PREPASS_NORMALIZED_VIEW_DEPTH_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_COLOR_TEXTURE_TYPE,\r\n            name: \"Color\",\r\n            clearType: GeometryRenderingTextureClearType.NoClear,\r\n            define: \"PREPASS_COLOR\",\r\n            defineIndex: \"PREPASS_COLOR_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE,\r\n            name: \"Irradiance\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_IRRADIANCE\",\r\n            defineIndex: \"PREPASS_IRRADIANCE_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_OBJECT_ID_TEXTURE_TYPE,\r\n            name: \"ObjectId\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_OBJECT_ID\",\r\n            defineIndex: \"PREPASS_OBJECT_ID_INDEX\",\r\n        },\r\n        {\r\n            type: Constants.PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE,\r\n            name: \"MeshBlendTag\",\r\n            clearType: GeometryRenderingTextureClearType.Zero,\r\n            define: \"PREPASS_MESH_BLEND_TAG\",\r\n            defineIndex: \"PREPASS_MESH_BLEND_TAG_INDEX\",\r\n        },\r\n    ];\r\n\r\n    private static _Configurations: { [renderPassId: number]: GeometryRenderingConfiguration } = {};\r\n\r\n    /**\r\n     * Creates a new geometry rendering configuration.\r\n     * @param renderPassId Render pass id the configuration is created for.\r\n     * @returns The created configuration.\r\n     */\r\n    public static CreateConfiguration(renderPassId: number) {\r\n        MaterialHelperGeometryRendering._Configurations[renderPassId] = {\r\n            defines: {},\r\n            previousWorldMatrices: {},\r\n            previousViewProjection: Matrix.Zero(),\r\n            currentViewProjection: Matrix.Zero(),\r\n            previousBones: {},\r\n            lastUpdateFrameId: -1,\r\n            excludedSkinnedMesh: [],\r\n            reverseCulling: false,\r\n            objectIdIsRedFormat: false,\r\n        };\r\n        return MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n    }\r\n\r\n    /**\r\n     * Deletes a geometry rendering configuration.\r\n     * @param renderPassId The render pass id of the configuration to delete.\r\n     */\r\n    public static DeleteConfiguration(renderPassId: number) {\r\n        delete MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n    }\r\n\r\n    /**\r\n     * Gets a geometry rendering configuration.\r\n     * @param renderPassId The render pass id of the configuration to get.\r\n     * @returns The configuration.\r\n     */\r\n    public static GetConfiguration(renderPassId: number): GeometryRenderingConfiguration {\r\n        return MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n    }\r\n\r\n    /** @internal */\r\n    public static _PrepareConfiguration(renderPassId: number, attachments: number[], colorAttachments: number[]): void {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n        configuration._attachments = attachments;\r\n        configuration._colorAttachments = colorAttachments;\r\n        configuration._mrtCount = attachments.length;\r\n\r\n        let defines = \"#define PREPASS\\n\";\r\n        for (const description of MaterialHelperGeometryRendering.GeometryTextureDescriptions) {\r\n            const index = configuration.defines[description.defineIndex];\r\n            if (index !== undefined) {\r\n                defines += `#define ${description.define}\\n#define ${description.defineIndex} ${index}\\n`;\r\n            }\r\n        }\r\n        if (configuration.objectIdIsRedFormat) {\r\n            defines += \"#define PREPASS_OBJECT_ID_R8\\n\";\r\n        }\r\n        configuration._defines = defines + `#define SCENE_MRT_COUNT ${attachments.length}\\n`;\r\n    }\r\n\r\n    /** @internal */\r\n    public static _PrepareStringDefines(renderPassId: number, defines: string[]): boolean {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n        if (!configuration?._defines) {\r\n            return false;\r\n        }\r\n        defines.push(configuration._defines);\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public static _BindAttachmentsForEffect(engine: AbstractEngine, effect: Pick<Effect, \"_multiTarget\">): boolean {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[engine.currentRenderPassId];\r\n        if (!configuration?._attachments) {\r\n            return true;\r\n        }\r\n        engine.bindAttachments(effect._multiTarget ? configuration._attachments : configuration._colorAttachments!);\r\n        return effect._multiTarget || configuration.defines[\"PREPASS_COLOR_INDEX\"] !== undefined;\r\n    }\r\n\r\n    /** @internal */\r\n    public static _RestoreAttachments(engine: AbstractEngine): void {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[engine.currentRenderPassId];\r\n        if (configuration?._colorAttachments) {\r\n            engine.bindAttachments(configuration._colorAttachments);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public static _BindColorAttachments(engine: AbstractEngine): boolean {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[engine.currentRenderPassId];\r\n        if (!configuration?._colorAttachments) {\r\n            return true;\r\n        }\r\n        engine.bindAttachments(configuration._colorAttachments);\r\n        return configuration.defines[\"PREPASS_COLOR_INDEX\"] !== undefined;\r\n    }\r\n\r\n    /** @internal */\r\n    public static _IsColorAttachmentEnabled(engine: AbstractEngine): boolean {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[engine.currentRenderPassId];\r\n        return !configuration?._colorAttachments || configuration.defines[\"PREPASS_COLOR_INDEX\"] !== undefined;\r\n    }\r\n\r\n    /** @internal */\r\n    public static _BindZeroAlphaDiscard(engine: AbstractEngine, effect: Effect): void {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[engine.currentRenderPassId];\r\n        if (!configuration) {\r\n            return;\r\n        }\r\n        const alphaMode = engine.getAlphaMode();\r\n        const discard =\r\n            configuration.defines[\"PREPASS_COLOR_INDEX\"] === undefined ||\r\n            alphaMode === Constants.ALPHA_COMBINE ||\r\n            alphaMode === Constants.ALPHA_ADD ||\r\n            alphaMode === Constants.ALPHA_LAYER_ACCUMULATE;\r\n        effect.setFloat(\"geometryZeroAlphaDiscard\", discard ? 1 : 0);\r\n    }\r\n\r\n    /**\r\n     * Adds uniforms and samplers for geometry rendering.\r\n     * @param uniforms The array of uniforms to add to.\r\n     * @param _samplers The array of samplers to add to.\r\n     */\r\n    public static AddUniformsAndSamplers(uniforms: string[], _samplers: string[]) {\r\n        uniforms.push(\"previousWorld\", \"previousViewProjection\", \"mPreviousBones\", \"objectId\", \"meshBlendTag\");\r\n    }\r\n\r\n    /**\r\n     * Marks a list of meshes as dirty for geometry rendering.\r\n     * @param renderPassId The render pass id the meshes are marked as dirty for.\r\n     * @param meshes The list of meshes to mark as dirty.\r\n     */\r\n    public static MarkAsDirty(renderPassId: number, meshes: AbstractMesh[]) {\r\n        for (const mesh of meshes) {\r\n            if (!mesh.subMeshes) {\r\n                continue;\r\n            }\r\n\r\n            for (const subMesh of mesh.subMeshes) {\r\n                subMesh._removeDrawWrapper(renderPassId);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepares defines for geometry rendering.\r\n     * @param renderPassId The render pass id the defines are prepared for.\r\n     * @param mesh The mesh the defines are prepared for.\r\n     * @param defines The defines to update according to the geometry rendering configuration.\r\n     */\r\n    public static PrepareDefines(renderPassId: number, mesh: AbstractMesh, defines: MaterialDefines) {\r\n        if (!defines._arePrePassDirty) {\r\n            return;\r\n        }\r\n\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n        if (!configuration) {\r\n            return;\r\n        }\r\n\r\n        defines[\"PREPASS\"] = true;\r\n\r\n        let numMRT = 0;\r\n\r\n        for (let i = 0; i < MaterialHelperGeometryRendering.GeometryTextureDescriptions.length; i++) {\r\n            const geometryTextureDescription = MaterialHelperGeometryRendering.GeometryTextureDescriptions[i];\r\n            const defineName = geometryTextureDescription.define;\r\n            const defineIndex = geometryTextureDescription.defineIndex;\r\n            const index = configuration.defines[defineIndex];\r\n\r\n            if (index !== undefined) {\r\n                defines[defineName] = true;\r\n                defines[defineIndex] = index;\r\n                numMRT++;\r\n            } else {\r\n                defines[defineName] = false;\r\n                delete defines[defineIndex];\r\n            }\r\n        }\r\n\r\n        defines[\"PREPASS_OBJECT_ID_R8\"] = configuration.objectIdIsRedFormat;\r\n        defines[\"SCENE_MRT_COUNT\"] = configuration._mrtCount ?? numMRT;\r\n\r\n        defines[\"BONES_VELOCITY_ENABLED\"] =\r\n            mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton && !mesh.skeleton.isUsingTextureForMatrices && configuration.excludedSkinnedMesh.indexOf(mesh) === -1;\r\n    }\r\n\r\n    /**\r\n     * Binds geometry rendering data for a mesh.\r\n     * @param renderPassId The render pass id the geometry rendering data is bound for.\r\n     * @param effect The effect to bind the geometry rendering data to.\r\n     * @param mesh The mesh to bind the geometry rendering data for.\r\n     * @param world The world matrix of the mesh.\r\n     * @param material The material of the mesh.\r\n     */\r\n    public static Bind(renderPassId: number, effect: Effect, mesh: Mesh, world: Matrix, material: Material) {\r\n        const configuration = MaterialHelperGeometryRendering._Configurations[renderPassId];\r\n        if (!configuration) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        if (configuration.reverseCulling) {\r\n            engine.setStateCullFaceType(scene._mirroredCameraPosition ? material.cullBackFaces : !material.cullBackFaces);\r\n        }\r\n\r\n        if (configuration.defines[\"PREPASS_OBJECT_ID_INDEX\"] !== undefined) {\r\n            const maxObjectId = configuration.objectIdIsRedFormat ? 0xff : 0xffffff;\r\n            let objectId = mesh.uniqueId;\r\n            if (configuration.objectIdProvider) {\r\n                objectId = _GetGeometryRenderingObjectId(mesh, configuration.objectIdProvider, maxObjectId);\r\n            } else if (objectId > maxObjectId) {\r\n                throw new Error(\r\n                    `Invalid geometry object ID ${objectId} for mesh \"${mesh.name}\". Object IDs must be integers between 0 and 0x${maxObjectId.toString(16).toUpperCase()}.`\r\n                );\r\n            }\r\n            effect.setFloat(\"objectId\", objectId);\r\n        }\r\n\r\n        if (configuration.defines[\"PREPASS_MESH_BLEND_TAG_INDEX\"] !== undefined) {\r\n            const meshBlendTag = configuration.meshBlendTagProvider ? _GetGeometryRenderingMeshBlendTag(mesh, configuration.meshBlendTagProvider) : mesh.meshBlendingTag;\r\n            effect.setInt(\"meshBlendTag\", meshBlendTag);\r\n        }\r\n\r\n        if (configuration.defines[\"PREPASS_VELOCITY_INDEX\"] !== undefined || configuration.defines[\"PREPASS_VELOCITY_LINEAR_INDEX\"] !== undefined) {\r\n            const currentWorldMatrices = (configuration._currentWorldMatrices ??= {});\r\n            const worldMatrixFrameIds = (configuration._worldMatrixFrameIds ??= {});\r\n            if (!currentWorldMatrices[mesh.uniqueId]) {\r\n                currentWorldMatrices[mesh.uniqueId] = world.clone();\r\n                configuration.previousWorldMatrices[mesh.uniqueId] = world.clone();\r\n            }\r\n            if (worldMatrixFrameIds[mesh.uniqueId] !== engine.frameId) {\r\n                configuration.previousWorldMatrices[mesh.uniqueId].copyFrom(currentWorldMatrices[mesh.uniqueId]);\r\n                worldMatrixFrameIds[mesh.uniqueId] = engine.frameId;\r\n            }\r\n            currentWorldMatrices[mesh.uniqueId].copyFrom(world);\r\n\r\n            if (configuration.lastUpdateFrameId === -1) {\r\n                configuration.lastUpdateFrameId = engine.frameId;\r\n                configuration.previousViewProjection.copyFrom(scene.getTransformMatrix());\r\n                configuration.currentViewProjection.copyFrom(scene.getTransformMatrix());\r\n            } else if (configuration.currentViewProjection.updateFlag !== scene.getTransformMatrix().updateFlag) {\r\n                // First update of the prepass configuration for this rendering pass\r\n                configuration.lastUpdateFrameId = engine.frameId;\r\n                configuration.previousViewProjection.copyFrom(configuration.currentViewProjection);\r\n                configuration.currentViewProjection.copyFrom(scene.getTransformMatrix());\r\n            } else if (configuration.lastUpdateFrameId !== engine.frameId) {\r\n                // The scene transformation did not change from the previous frame (so no camera motion), we must update previousViewProjection accordingly\r\n                configuration.lastUpdateFrameId = engine.frameId;\r\n                configuration.previousViewProjection.copyFrom(configuration.currentViewProjection);\r\n            }\r\n\r\n            effect.setMatrix(\"previousWorld\", configuration.previousWorldMatrices[mesh.uniqueId]);\r\n            effect.setMatrix(\"previousViewProjection\", configuration.previousViewProjection);\r\n\r\n            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n                const skeleton = mesh.skeleton;\r\n\r\n                if (!skeleton.isUsingTextureForMatrices || effect.getUniformIndex(\"boneTextureInfo\") === -1) {\r\n                    const matrices = skeleton.getTransformMatrices(mesh);\r\n\r\n                    if (matrices) {\r\n                        if (!configuration.previousBones[mesh.uniqueId]) {\r\n                            configuration.previousBones[mesh.uniqueId] = matrices.slice();\r\n                        }\r\n                        effect.setMatrices(\"mPreviousBones\", configuration.previousBones[mesh.uniqueId]);\r\n                        configuration.previousBones[mesh.uniqueId].set(matrices);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../types\";\nimport { type Scene } from \"../scene.pure\";\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\nimport { Material } from \"../Materials/material.pure\";\nimport { Tags } from \"../Misc/tags\";\nimport { RegisterClass } from \"../Misc/typeStore\";\n\n/**\n * A multi-material is used to apply different materials to different parts of the same object without the need of\n * separate meshes. This can be use to improve performances.\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials\n */\nexport class MultiMaterial extends Material {\n    private _subMaterials: Nullable<Material>[];\n    /** @internal */\n    public _waitingSubMaterialsUniqueIds: string[] = [];\n\n    /**\n     * Gets or Sets the list of Materials used within the multi material.\n     * They need to be ordered according to the submeshes order in the associated mesh\n     */\n    public get subMaterials(): Nullable<Material>[] {\n        return this._subMaterials;\n    }\n\n    public set subMaterials(value: Nullable<Material>[]) {\n        this._subMaterials = value;\n        this._hookArray(value);\n    }\n\n    /**\n     * Function used to align with Node.getChildren()\n     * @returns the list of Materials used within the multi material\n     */\n    public getChildren(): Nullable<Material>[] {\n        return this.subMaterials;\n    }\n\n    /**\n     * Instantiates a new Multi Material\n     * A multi-material is used to apply different materials to different parts of the same object without the need of\n     * separate meshes. This can be use to improve performances.\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials\n     * @param name Define the name in the scene\n     * @param scene Define the scene the material belongs to\n     */\n    constructor(name: string, scene?: Scene) {\n        super(name, scene, true);\n\n        this.getScene().addMultiMaterial(this);\n\n        this.subMaterials = [] as Material[];\n\n        this._storeEffectOnSubMeshes = true; // multimaterial is considered like a push material\n    }\n\n    private _hookArray(array: Nullable<Material>[]): void {\n        const oldPush = array.push;\n        array.push = (...items: Nullable<Material>[]) => {\n            const result = oldPush.apply(array, items);\n\n            this._markAllSubMeshesAsTexturesDirty();\n\n            return result;\n        };\n\n        const oldSplice = array.splice;\n        array.splice = (index: number, deleteCount?: number) => {\n            const deleted = oldSplice.call(array, index, deleteCount ?? array.length);\n\n            this._markAllSubMeshesAsTexturesDirty();\n\n            return deleted;\n        };\n    }\n\n    /**\n     * Get one of the submaterial by its index in the submaterials array\n     * @param index The index to look the sub material at\n     * @returns The Material if the index has been defined\n     */\n    public getSubMaterial(index: number): Nullable<Material> {\n        if (index < 0 || index >= this.subMaterials.length) {\n            return this.getScene().defaultMaterial;\n        }\n\n        return this.subMaterials[index];\n    }\n\n    /**\n     * Get the list of active textures for the whole sub materials list.\n     * @returns All the textures that will be used during the rendering\n     */\n    public override getActiveTextures(): BaseTexture[] {\n        return super.getActiveTextures().concat(\n            ...this.subMaterials.map((subMaterial) => {\n                if (subMaterial) {\n                    return subMaterial.getActiveTextures();\n                } else {\n                    return [];\n                }\n            })\n        );\n    }\n\n    /**\n     * Specifies if any sub-materials of this multi-material use a given texture.\n     * @param texture Defines the texture to check against this multi-material's sub-materials.\n     * @returns A boolean specifying if any sub-material of this multi-material uses the texture.\n     */\n    public override hasTexture(texture: BaseTexture): boolean {\n        if (super.hasTexture(texture)) {\n            return true;\n        }\n\n        for (let i = 0; i < this.subMaterials.length; i++) {\n            if (this.subMaterials[i]?.hasTexture(texture)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Gets the current class name of the material e.g. \"MultiMaterial\"\n     * Mainly use in serialization.\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return \"MultiMaterial\";\n    }\n\n    /**\n     * Checks if the material is ready to render the requested sub mesh\n     * @param mesh Define the mesh the submesh belongs to\n     * @param subMesh Define the sub mesh to look readiness for\n     * @param useInstances Define whether or not the material is used with instances\n     * @returns true if ready, otherwise false\n     */\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {\n        for (let index = 0; index < this.subMaterials.length; index++) {\n            const subMaterial = this.subMaterials[index];\n            if (subMaterial) {\n                if (subMaterial._storeEffectOnSubMeshes) {\n                    if (!subMaterial.isReadyForSubMesh(mesh, subMesh, useInstances)) {\n                        return false;\n                    }\n                    continue;\n                }\n\n                if (!subMaterial.isReady(mesh)) {\n                    return false;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Clones the current material and its related sub materials\n     * @param name Define the name of the newly cloned material\n     * @param cloneChildren Define if submaterial will be cloned or shared with the parent instance\n     * @returns the cloned material\n     */\n    public override clone(name: string, cloneChildren?: boolean): MultiMaterial {\n        const newMultiMaterial = new MultiMaterial(name, this.getScene());\n\n        for (let index = 0; index < this.subMaterials.length; index++) {\n            let subMaterial: Nullable<Material>;\n            const current = this.subMaterials[index];\n            if (cloneChildren && current) {\n                subMaterial = current.clone(name + \"-\" + current.name);\n            } else {\n                subMaterial = this.subMaterials[index];\n            }\n            newMultiMaterial.subMaterials.push(subMaterial);\n        }\n\n        return newMultiMaterial;\n    }\n\n    /**\n     * Serializes the materials into a JSON representation.\n     * @returns the JSON representation\n     */\n    public override serialize(): any {\n        const serializationObject: any = {};\n\n        serializationObject.name = this.name;\n        serializationObject.id = this.id;\n        serializationObject.uniqueId = this.uniqueId;\n        if (Tags) {\n            serializationObject.tags = Tags.GetTags(this);\n        }\n        serializationObject.materialsUniqueIds = [];\n        serializationObject.materials = [];\n\n        for (let matIndex = 0; matIndex < this.subMaterials.length; matIndex++) {\n            const subMat = this.subMaterials[matIndex];\n\n            if (subMat) {\n                serializationObject.materialsUniqueIds.push(subMat.uniqueId);\n                serializationObject.materials.push(subMat.id);\n            } else {\n                serializationObject.materialsUniqueIds.push(null);\n                serializationObject.materials.push(null);\n            }\n        }\n\n        return serializationObject;\n    }\n\n    /**\n     * Dispose the material and release its associated resources\n     * @param forceDisposeEffect Define if we want to force disposing the associated effect (if false the shader is not released and could be reuse later on)\n     * @param forceDisposeTextures Define if we want to force disposing the associated textures (if false, they will not be disposed and can still be use elsewhere in the app)\n     * @param forceDisposeChildren Define if we want to force disposing the associated submaterials (if false, they will not be disposed and can still be use elsewhere in the app)\n     */\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, forceDisposeChildren?: boolean): void {\n        const scene = this.getScene();\n        if (!scene) {\n            return;\n        }\n\n        if (forceDisposeChildren) {\n            for (let index = 0; index < this.subMaterials.length; index++) {\n                const subMaterial = this.subMaterials[index];\n                if (subMaterial) {\n                    subMaterial.dispose(forceDisposeEffect, forceDisposeTextures);\n                }\n            }\n        }\n\n        const index = scene.multiMaterials.indexOf(this);\n        if (index >= 0) {\n            scene.multiMaterials.splice(index, 1);\n        }\n\n        super.dispose(forceDisposeEffect, forceDisposeTextures);\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Creates a MultiMaterial from parsed MultiMaterial data.\n * @param parsedMultiMaterial defines parsed MultiMaterial data.\n * @param scene defines the hosting scene\n * @returns a new MultiMaterial\n */\nexport function MultiMaterialParseMultiMaterial(parsedMultiMaterial: any, scene: Scene): MultiMaterial {\n    const multiMaterial = new MultiMaterial(parsedMultiMaterial.name, scene);\n\n    multiMaterial.id = parsedMultiMaterial.id;\n    multiMaterial._loadedUniqueId = parsedMultiMaterial.uniqueId;\n\n    if (Tags) {\n        Tags.AddTagsTo(multiMaterial, parsedMultiMaterial.tags);\n    }\n\n    if (parsedMultiMaterial.materialsUniqueIds) {\n        multiMaterial._waitingSubMaterialsUniqueIds = parsedMultiMaterial.materialsUniqueIds;\n    } else {\n        for (const subMatId of parsedMultiMaterial.materials) {\n            multiMaterial.subMaterials.push(scene.getLastMaterialById(subMatId));\n        }\n    }\n\n    return multiMaterial;\n}\n\n/**\n * Register side effects for multiMaterial.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterMultiMaterial(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    MultiMaterial.ParseMultiMaterial = MultiMaterialParseMultiMaterial;\n\n    RegisterClass(\"BABYLON.MultiMaterial\", MultiMaterial);\n}\n","import { type Mesh } from \"./mesh\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * Class used to represent a specific level of detail of a mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD\r\n */\r\nexport class MeshLODLevel {\r\n    /**\r\n     * Creates a new LOD level\r\n     * @param distanceOrScreenCoverage defines either the distance or the screen coverage where this level should start being displayed\r\n     * @param mesh defines the mesh to use to render this level\r\n     */\r\n    constructor(\r\n        /** Either distance from the center of the object to show this level or the screen coverage if `useLODScreenCoverage` is set to `true` on the mesh*/\r\n        public distanceOrScreenCoverage: number,\r\n        /** Defines the mesh to use to render this level */\r\n        public mesh: Nullable<Mesh>\r\n    ) {}\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable jsdoc/require-returns-check */\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { AsyncLoop } from \"../Misc/tools.pure\";\r\nimport { LoadImage } from \"../Misc/fileTools.pure\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { DeepCopier } from \"../Misc/deepCopier\";\r\nimport { Tags } from \"../Misc/tags\";\r\nimport { type Coroutine, runCoroutineSync, runCoroutineAsync, createYieldingScheduler } from \"../Misc/coroutine\";\r\nimport { type Nullable, type FloatArray, type IndicesArray, type DeepImmutable } from \"../types\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { type Scene, ScenePerformancePriority } from \"../scene.pure\";\r\nimport { type Vector4, Quaternion, Matrix, Vector3, Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Color4, Color3 } from \"../Maths/math.color.pure\";\r\nimport { Node } from \"../node\";\r\nimport { VertexBuffer, Buffer } from \"../Buffers/buffer.pure\";\r\nimport { type IGetSetVerticesData, VertexData } from \"./mesh.vertexData\";\r\n\r\nimport { Geometry } from \"./geometry\";\r\nimport { type IMeshDataOptions, AbstractMesh } from \"./abstractMesh.pure\";\r\nimport { SubMesh } from \"./subMesh.pure\";\r\nimport { type BoundingSphere } from \"../Culling/boundingSphere\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { MaterialHelperGeometryRendering } from \"../Materials/materialHelper.geometryrendering\";\r\nimport { MultiMaterial } from \"../Materials/multiMaterial.pure\";\r\nimport { SceneLoaderFlags } from \"../Loading/sceneLoaderFlags\";\r\nimport { type Skeleton } from \"../Bones/skeleton\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { GetClass, RegisterClass } from \"../Misc/typeStore\";\r\nimport { _WarnImport, _IsSideEffectImplemented, _MissingSideEffect, _MissingSideEffectProperty } from \"../Misc/devTools\";\r\nimport { SceneComponentConstants } from \"../sceneComponent\";\r\nimport { MeshLODLevel } from \"./meshLODLevel\";\r\nimport { type Path3D } from \"../Maths/math.path\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\nimport { type TransformNode } from \"./transformNode.pure\";\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { type PhysicsEngine as PhysicsEngineV1 } from \"../Physics/v1/physicsEngine\";\r\n\r\nimport { type GoldbergMesh } from \"./goldbergMesh.pure\";\r\nimport { type InstancedMesh } from \"./instancedMesh.pure\";\r\nimport { type IPhysicsEnabledObject, type PhysicsImpostor } from \"../Physics/v1/physicsImpostor.pure\";\r\nimport { type ICreateCapsuleOptions } from \"./Builders/capsuleBuilder.pure\";\r\nimport { type LinesMesh } from \"./linesMesh.pure\";\r\nimport { type GroundMesh } from \"./groundMesh.pure\";\r\nimport { type DataBuffer } from \"core/Buffers/dataBuffer\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class _CreationDataStorage {\r\n    /** @internal */\r\n    public closePath?: boolean;\r\n    /** @internal */\r\n    public closeArray?: boolean;\r\n    /** @internal */\r\n    public idx: number[];\r\n    /** @internal */\r\n    public dashSize: number;\r\n    /** @internal */\r\n    public gapSize: number;\r\n    /** @internal */\r\n    public path3D: Path3D;\r\n    /** @internal */\r\n    public pathArray: Vector3[][];\r\n    /** @internal */\r\n    public arc: number;\r\n    /** @internal */\r\n    public radius: number;\r\n    /** @internal */\r\n    public cap: number;\r\n    /** @internal */\r\n    public tessellation: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\ninterface IInstanceDataStorageRenderPassVisibleInstances {\r\n    defaultRenderId: number;\r\n    selfDefaultRenderId: number;\r\n    intermediateDefaultRenderId: number;\r\n    [renderId: number]: Nullable<Array<InstancedMesh>>;\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\nclass _InstanceDataStorageRenderPass {\r\n    /** @internal */\r\n    public visibleInstances: Nullable<IInstanceDataStorageRenderPassVisibleInstances>;\r\n    /** @internal */\r\n    public batchCache = new _InstancesBatch(this);\r\n    /** @internal */\r\n    public batchCacheReplacementModeInFrozenMode = new _InstancesBatch(this);\r\n    /** @internal */\r\n    public instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances\r\n    /** @internal */\r\n    public instancesBuffer: Nullable<Buffer>;\r\n    /** @internal */\r\n    public instancesPreviousBuffer: Nullable<Buffer>;\r\n    /** @internal */\r\n    public instancesData: Float32Array;\r\n    /** @internal */\r\n    public instancesPreviousData: Float32Array;\r\n    /** @internal */\r\n    public previousBatch: Nullable<_InstancesBatch>;\r\n    /** @internal */\r\n    public previousRenderId: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\nclass _InstanceDataStorage {\r\n    /** @internal */\r\n    public renderPasses: { [id: number]: _InstanceDataStorageRenderPass } = {};\r\n    /** @internal */\r\n    public dataStorageRenderPass: _InstanceDataStorageRenderPass; // used over renderPasses when useMonoDataStorageRenderPass is true\r\n    /** @internal */\r\n    public useMonoDataStorageRenderPass: boolean;\r\n    /** @internal */\r\n    public overridenInstanceCount: number;\r\n    /** @internal */\r\n    public isFrozen: boolean;\r\n    /** @internal */\r\n    public forceMatrixUpdates: boolean;\r\n    /** @internal */\r\n    public hardwareInstancedRendering: boolean;\r\n    /** @internal */\r\n    public manualUpdate: boolean;\r\n    /** @internal */\r\n    public previousManualUpdate: boolean;\r\n    /** @internal */\r\n    public masterMeshPreviousWorldMatrix: Nullable<Matrix>;\r\n    /** @internal */\r\n    public engine: AbstractEngine;\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class _InstancesBatch {\r\n    /** @internal */\r\n    public mustReturn = false;\r\n\r\n    /** @internal */\r\n    public visibleInstances = new Array<Nullable<Array<InstancedMesh>>>();\r\n\r\n    /** @internal */\r\n    public renderSelf: boolean[] = [];\r\n\r\n    /** @internal */\r\n    public hardwareInstancedRendering: boolean[] = [];\r\n\r\n    /** @internal */\r\n    constructor(public parent: _InstanceDataStorageRenderPass) {}\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\nclass _ThinInstanceDataStorage {\r\n    /** @internal */\r\n    public instancesCount: number = 0;\r\n    /** @internal */\r\n    public matrixBuffer: Nullable<Buffer> = null;\r\n    /** @internal */\r\n    public previousMatrixBuffer: Nullable<Buffer> = null;\r\n    /** @internal */\r\n    public matrixBufferSize = 32 * 16; // let's start with a maximum of 32 thin instances\r\n    /** @internal */\r\n    public matrixData: Nullable<Float32Array> = null;\r\n    /** @internal */\r\n    public previousMatrixData: Nullable<Float32Array>;\r\n    /** @internal */\r\n    public boundingVectors: Array<Vector3> = [];\r\n    /** @internal */\r\n    public worldMatrices: Nullable<Matrix[]> = null;\r\n    /** @internal */\r\n    public masterMeshPreviousWorldMatrix: Nullable<Matrix>;\r\n}\r\n\r\n/**\r\n * @internal\r\n **/\r\nclass _InternalMeshDataInfo {\r\n    // Events\r\n    public _onBeforeRenderObservable: Nullable<Observable<Mesh>>;\r\n    public _onBeforeBindObservable: Nullable<Observable<Mesh>>;\r\n    public _onAfterRenderObservable: Nullable<Observable<Mesh>>;\r\n    public _onBeforeDrawObservable: Nullable<Observable<Mesh>>;\r\n    public _onBetweenPassObservable: Nullable<Observable<SubMesh>>;\r\n\r\n    public _areNormalsFrozen: boolean = false; // Will be used by ribbons mainly\r\n    public _sourcePositions: Nullable<Float32Array>; // Will be used to save original positions when using software skinning\r\n    public _sourceNormals: Nullable<Float32Array>; // Will be used to save original normals when using software skinning\r\n\r\n    // Will be used to save a source mesh reference, If any\r\n    public _source: Nullable<Mesh> = null;\r\n    // Will be used to for fast cloned mesh lookup\r\n    public meshMap: Nullable<{ [id: string]: Mesh | undefined }> = null;\r\n\r\n    public _preActivateId: number = -1;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public _LODLevels = new Array<MeshLODLevel>();\r\n    /** Alternative definition of LOD level, using screen coverage instead of distance */\r\n    public _useLODScreenCoverage: boolean = false;\r\n    public _checkReadinessObserver: Nullable<Observer<Scene>>;\r\n\r\n    public _onMeshReadyObserverAdded: (observer: Observer<Mesh>) => void;\r\n\r\n    public _effectiveMaterial: Nullable<Material> = null;\r\n\r\n    public _forcedInstanceCount: number = 0;\r\n\r\n    public _overrideRenderingFillMode: Nullable<number> = null;\r\n\r\n    public _sideOrientation: number;\r\n\r\n    public _effectiveSideOrientation: number;\r\n}\r\n\r\n/**\r\n * Options used to clone a mesh\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface MeshCloneOptions {\r\n    /** The parent of the mesh, if it has one */\r\n    parent?: Nullable<Node>;\r\n\r\n    /** Skips cloning child meshes of source (default: false. When false, achieved by calling a clone(), also passing False. This will make creation of children, recursive. */\r\n    doNotCloneChildren?: boolean;\r\n\r\n    /** Includes cloning mesh physics impostor (default: true) */\r\n    clonePhysicsImpostor?: boolean;\r\n\r\n    /** Includes cloning thin instances (default: false) */\r\n    cloneThinInstances?: boolean;\r\n}\r\n\r\n/**\r\n * Options used to create a mesh\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface MeshCreationOptions extends MeshCloneOptions {\r\n    /** An optional Mesh from which the new mesh will be cloned from (geometry will be shared) */\r\n    source?: Nullable<Mesh>;\r\n}\r\n\r\nconst MeshCreationOptions: MeshCreationOptions = {\r\n    source: null,\r\n    parent: null,\r\n    doNotCloneChildren: false,\r\n    clonePhysicsImpostor: true,\r\n    cloneThinInstances: false,\r\n};\r\n\r\n/**\r\n * Class used to represent renderable models\r\n */\r\nexport class Mesh extends AbstractMesh implements IGetSetVerticesData {\r\n    // Consts\r\n\r\n    /**\r\n     * Mesh side orientation : usually the external or front surface\r\n     */\r\n    public static readonly FRONTSIDE = VertexData.FRONTSIDE;\r\n\r\n    /**\r\n     * Mesh side orientation : usually the internal or back surface\r\n     */\r\n    public static readonly BACKSIDE = VertexData.BACKSIDE;\r\n    /**\r\n     * Mesh side orientation : both internal and external or front and back surfaces\r\n     */\r\n    public static readonly DOUBLESIDE = VertexData.DOUBLESIDE;\r\n    /**\r\n     * Mesh side orientation : by default, `FRONTSIDE`\r\n     */\r\n    public static readonly DEFAULTSIDE = VertexData.DEFAULTSIDE;\r\n    /**\r\n     * Mesh cap setting : no cap\r\n     */\r\n    public static readonly NO_CAP = 0;\r\n    /**\r\n     * Mesh cap setting : one cap at the beginning of the mesh\r\n     */\r\n    public static readonly CAP_START = 1;\r\n    /**\r\n     * Mesh cap setting : one cap at the end of the mesh\r\n     */\r\n    public static readonly CAP_END = 2;\r\n    /**\r\n     * Mesh cap setting : two caps, one at the beginning  and one at the end of the mesh\r\n     */\r\n    public static readonly CAP_ALL = 3;\r\n    /**\r\n     * Mesh pattern setting : no flip or rotate\r\n     */\r\n    public static readonly NO_FLIP = 0;\r\n    /**\r\n     * Mesh pattern setting : flip (reflect in y axis) alternate tiles on each row or column\r\n     */\r\n    public static readonly FLIP_TILE = 1;\r\n    /**\r\n     * Mesh pattern setting : rotate (180degs) alternate tiles on each row or column\r\n     */\r\n    public static readonly ROTATE_TILE = 2;\r\n    /**\r\n     * Mesh pattern setting : flip (reflect in y axis) all tiles on alternate rows\r\n     */\r\n    public static readonly FLIP_ROW = 3;\r\n    /**\r\n     * Mesh pattern setting : rotate (180degs) all tiles on alternate rows\r\n     */\r\n    public static readonly ROTATE_ROW = 4;\r\n    /**\r\n     * Mesh pattern setting : flip and rotate alternate tiles on each row or column\r\n     */\r\n    public static readonly FLIP_N_ROTATE_TILE = 5;\r\n    /**\r\n     * Mesh pattern setting : rotate pattern and rotate\r\n     */\r\n    public static readonly FLIP_N_ROTATE_ROW = 6;\r\n    /**\r\n     * Mesh tile positioning : part tiles same on left/right or top/bottom\r\n     */\r\n    public static readonly CENTER = 0;\r\n    /**\r\n     * Mesh tile positioning : part tiles on left\r\n     */\r\n    public static readonly LEFT = 1;\r\n    /**\r\n     * Mesh tile positioning : part tiles on right\r\n     */\r\n    public static readonly RIGHT = 2;\r\n    /**\r\n     * Mesh tile positioning : part tiles on top\r\n     */\r\n    public static readonly TOP = 3;\r\n    /**\r\n     * Mesh tile positioning : part tiles on bottom\r\n     */\r\n    public static readonly BOTTOM = 4;\r\n\r\n    /**\r\n     * Indicates that the instanced meshes should be sorted from back to front before rendering if their material is transparent\r\n     */\r\n    public static INSTANCEDMESH_SORT_TRANSPARENT = false;\r\n\r\n    /**\r\n     * Gets the default side orientation.\r\n     * @param orientation the orientation to value to attempt to get\r\n     * @returns the default orientation\r\n     * @internal\r\n     */\r\n    public static _GetDefaultSideOrientation(orientation?: number): number {\r\n        return orientation || Mesh.FRONTSIDE; // works as Mesh.FRONTSIDE is 0\r\n    }\r\n\r\n    // Internal data\r\n    private _internalMeshDataInfo = new _InternalMeshDataInfo();\r\n\r\n    /**\r\n     * Determines if the LOD levels are intended to be calculated using screen coverage (surface area ratio) instead of distance.\r\n     */\r\n    public get useLODScreenCoverage() {\r\n        return this._internalMeshDataInfo._useLODScreenCoverage;\r\n    }\r\n\r\n    public set useLODScreenCoverage(value: boolean) {\r\n        this._internalMeshDataInfo._useLODScreenCoverage = value;\r\n        this._sortLODLevels();\r\n    }\r\n\r\n    /**\r\n     * Will notify when the mesh is completely ready, including materials.\r\n     * Observers added to this observable will be removed once triggered\r\n     */\r\n    public onMeshReadyObservable: Observable<Mesh>;\r\n\r\n    /** {@inheritDoc} */\r\n    public override get computeBonesUsingShaders(): boolean {\r\n        return this._internalAbstractMeshDataInfo._computeBonesUsingShaders;\r\n    }\r\n    /** {@inheritDoc} */\r\n    public override set computeBonesUsingShaders(value: boolean) {\r\n        if (this._internalAbstractMeshDataInfo._computeBonesUsingShaders === value) {\r\n            return;\r\n        }\r\n\r\n        if (value && this._internalMeshDataInfo._sourcePositions) {\r\n            // switch from software to GPU computation: we need to reset the vertex and normal buffers that have been updated by the software process\r\n            this.setVerticesData(VertexBuffer.PositionKind, this._internalMeshDataInfo._sourcePositions, true);\r\n            if (this._internalMeshDataInfo._sourceNormals) {\r\n                this.setVerticesData(VertexBuffer.NormalKind, this._internalMeshDataInfo._sourceNormals, true);\r\n            }\r\n\r\n            this._internalMeshDataInfo._sourcePositions = null;\r\n            this._internalMeshDataInfo._sourceNormals = null;\r\n        }\r\n\r\n        this._internalAbstractMeshDataInfo._computeBonesUsingShaders = value;\r\n        this._markSubMeshesAsAttributesDirty();\r\n    }\r\n\r\n    /**\r\n     * An event triggered before rendering the mesh\r\n     */\r\n    public get onBeforeRenderObservable(): Observable<Mesh> {\r\n        if (!this._internalMeshDataInfo._onBeforeRenderObservable) {\r\n            this._internalMeshDataInfo._onBeforeRenderObservable = new Observable<Mesh>();\r\n        }\r\n\r\n        return this._internalMeshDataInfo._onBeforeRenderObservable;\r\n    }\r\n\r\n    /**\r\n     * An event triggered before binding the mesh\r\n     */\r\n    public get onBeforeBindObservable(): Observable<Mesh> {\r\n        if (!this._internalMeshDataInfo._onBeforeBindObservable) {\r\n            this._internalMeshDataInfo._onBeforeBindObservable = new Observable<Mesh>();\r\n        }\r\n\r\n        return this._internalMeshDataInfo._onBeforeBindObservable;\r\n    }\r\n\r\n    /**\r\n     * An event triggered after rendering the mesh\r\n     */\r\n    public get onAfterRenderObservable(): Observable<Mesh> {\r\n        if (!this._internalMeshDataInfo._onAfterRenderObservable) {\r\n            this._internalMeshDataInfo._onAfterRenderObservable = new Observable<Mesh>();\r\n        }\r\n\r\n        return this._internalMeshDataInfo._onAfterRenderObservable;\r\n    }\r\n\r\n    /**\r\n     * An event triggeredbetween rendering pass when using separateCullingPass = true\r\n     */\r\n    public get onBetweenPassObservable(): Observable<SubMesh> {\r\n        if (!this._internalMeshDataInfo._onBetweenPassObservable) {\r\n            this._internalMeshDataInfo._onBetweenPassObservable = new Observable<SubMesh>();\r\n        }\r\n\r\n        return this._internalMeshDataInfo._onBetweenPassObservable;\r\n    }\r\n\r\n    /**\r\n     * An event triggered before drawing the mesh\r\n     */\r\n    public get onBeforeDrawObservable(): Observable<Mesh> {\r\n        if (!this._internalMeshDataInfo._onBeforeDrawObservable) {\r\n            this._internalMeshDataInfo._onBeforeDrawObservable = new Observable<Mesh>();\r\n        }\r\n\r\n        return this._internalMeshDataInfo._onBeforeDrawObservable;\r\n    }\r\n\r\n    private _onBeforeDrawObserver: Nullable<Observer<Mesh>>;\r\n\r\n    /**\r\n     * Sets a callback to call before drawing the mesh. It is recommended to use onBeforeDrawObservable instead\r\n     */\r\n    public set onBeforeDraw(callback: () => void) {\r\n        if (this._onBeforeDrawObserver) {\r\n            this.onBeforeDrawObservable.remove(this._onBeforeDrawObserver);\r\n        }\r\n        this._onBeforeDrawObserver = this.onBeforeDrawObservable.add(callback);\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get hasInstances(): boolean {\r\n        return this.instances.length > 0;\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get hasThinInstances(): boolean {\r\n        return (this.forcedInstanceCount || this._thinInstanceDataStorage.instancesCount || 0) > 0;\r\n    }\r\n\r\n    // Members\r\n\r\n    /**\r\n     * Gets the delay loading state of the mesh (when delay loading is turned on)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/incrementalLoading\r\n     */\r\n    public delayLoadState = Constants.DELAYLOADSTATE_NONE;\r\n\r\n    /**\r\n     * Gets the list of instances created from this mesh\r\n     * it is not supposed to be modified manually.\r\n     * Note also that the order of the InstancedMesh wihin the array is not significant and might change.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances\r\n     */\r\n    public instances: InstancedMesh[] = [];\r\n\r\n    /**\r\n     * Gets the file containing delay loading data for this mesh\r\n     */\r\n    public delayLoadingFile: string;\r\n\r\n    /** @internal */\r\n    public _binaryInfo: any;\r\n\r\n    /**\r\n     * User defined function used to change how LOD level selection is done\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD\r\n     */\r\n    public onLODLevelSelection: (distance: number, mesh: Mesh, selectedLevel: Nullable<Mesh>) => void;\r\n\r\n    // Private\r\n    /** @internal */\r\n    public _creationDataStorage: Nullable<_CreationDataStorage> = null;\r\n\r\n    /** @internal */\r\n    public _geometry: Nullable<Geometry> = null;\r\n    /** @internal */\r\n    public _delayInfo: Array<string>;\r\n    /** @internal */\r\n    public _delayLoadingFunction: (any: any, mesh: Mesh) => void;\r\n\r\n    /**\r\n     * Gets or sets the forced number of instances to display.\r\n     * If 0 (default value), the number of instances is not forced and depends on the draw type\r\n     * (regular / instance / thin instances mesh)\r\n     */\r\n    public get forcedInstanceCount(): number {\r\n        return this._internalMeshDataInfo._forcedInstanceCount;\r\n    }\r\n\r\n    public set forcedInstanceCount(count: number) {\r\n        this._internalMeshDataInfo._forcedInstanceCount = count;\r\n    }\r\n\r\n    /** @internal */\r\n    public _instanceDataStorage: _InstanceDataStorage;\r\n\r\n    /** @internal */\r\n    public _thinInstanceDataStorage = new _ThinInstanceDataStorage();\r\n\r\n    /** @internal */\r\n    public _shouldGenerateFlatShading: boolean = false;\r\n\r\n    // Use by builder only to know what orientation were the mesh build in.\r\n    /** @internal */\r\n    public _originalBuilderSideOrientation: number = Mesh.DEFAULTSIDE;\r\n\r\n    /**\r\n     * Use this property to change the original side orientation defined at construction time\r\n     * Material.sideOrientation will override this value if set\r\n     * User will still be able to change the material sideOrientation afterwards if they really need it\r\n     */\r\n    public get sideOrientation(): number {\r\n        return this._internalMeshDataInfo._sideOrientation;\r\n    }\r\n\r\n    public set sideOrientation(value: number) {\r\n        this._internalMeshDataInfo._sideOrientation = value;\r\n\r\n        this._internalAbstractMeshDataInfo._sideOrientationHint =\r\n            (this._scene.useRightHandedSystem && value === Constants.MATERIAL_CounterClockWiseSideOrientation) ||\r\n            (!this._scene.useRightHandedSystem && value === Constants.MATERIAL_ClockWiseSideOrientation);\r\n    }\r\n\r\n    /** @internal */\r\n    public get _effectiveSideOrientation(): number {\r\n        return this._internalMeshDataInfo._effectiveSideOrientation;\r\n    }\r\n\r\n    /**\r\n     * @deprecated Please use sideOrientation instead.\r\n     * @see https://doc.babylonjs.com/breaking-changes#7110\r\n     */\r\n    public get overrideMaterialSideOrientation() {\r\n        return this.sideOrientation;\r\n    }\r\n\r\n    public set overrideMaterialSideOrientation(value: number) {\r\n        this.sideOrientation = value;\r\n        if (this.material) {\r\n            this.material.sideOrientation = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Use this property to override the Material's fillMode value\r\n     */\r\n    public get overrideRenderingFillMode(): Nullable<number> {\r\n        return this._internalMeshDataInfo._overrideRenderingFillMode;\r\n    }\r\n\r\n    public set overrideRenderingFillMode(fillMode: Nullable<number>) {\r\n        this._internalMeshDataInfo._overrideRenderingFillMode = fillMode;\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get material(): Nullable<Material> {\r\n        return this._internalAbstractMeshDataInfo._material;\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override set material(value: Nullable<Material>) {\r\n        if (value && ((this.material && this.material.sideOrientation === null) || this._internalAbstractMeshDataInfo._sideOrientationHint)) {\r\n            value.sideOrientation = null;\r\n        }\r\n        this._setMaterial(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating whether to render ignoring the active camera's max z setting. (false by default)\r\n     * You should not mix meshes that have this property set to true with meshes that have it set to false if they all write\r\n     * to the depth buffer, because the z-values are not comparable in the two cases and you will get rendering artifacts if you do.\r\n     * You can set the property to true for meshes that do not write to the depth buffer, or set the same value (either false or true) otherwise.\r\n     * Note this will reduce performance when set to true.\r\n     */\r\n    public ignoreCameraMaxZ = false;\r\n\r\n    /**\r\n     * Gets the source mesh (the one used to clone this one from)\r\n     */\r\n    public get source(): Nullable<Mesh> {\r\n        return this._internalMeshDataInfo._source;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of clones of this mesh\r\n     * The scene must have been constructed with useClonedMeshMap=true for this to work!\r\n     * Note that useClonedMeshMap=true is the default setting\r\n     */\r\n    public get cloneMeshMap(): Nullable<{ [id: string]: Mesh | undefined }> {\r\n        return this._internalMeshDataInfo.meshMap;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this mesh does not use index buffer\r\n     */\r\n    public get isUnIndexed(): boolean {\r\n        return this._unIndexed;\r\n    }\r\n\r\n    public set isUnIndexed(value: boolean) {\r\n        if (this._unIndexed !== value) {\r\n            this._unIndexed = value;\r\n            this._markSubMeshesAsAttributesDirty();\r\n        }\r\n    }\r\n\r\n    /** Gets the array buffer used to store the instanced buffer used for instances' world matrices */\r\n    public get worldMatrixInstancedBuffer(): Float32Array {\r\n        const instanceDataStorage = this._instanceDataStorage.useMonoDataStorageRenderPass\r\n            ? this._instanceDataStorage.dataStorageRenderPass\r\n            : this._instanceDataStorage.renderPasses[this._instanceDataStorage.engine.currentRenderPassId];\r\n        return instanceDataStorage ? instanceDataStorage.instancesData : (undefined as any);\r\n    }\r\n\r\n    /** Gets the array buffer used to store the instanced buffer used for instances' previous world matrices */\r\n    public get previousWorldMatrixInstancedBuffer(): Float32Array {\r\n        const instanceDataStorage = this._instanceDataStorage.useMonoDataStorageRenderPass\r\n            ? this._instanceDataStorage.dataStorageRenderPass\r\n            : this._instanceDataStorage.renderPasses[this._instanceDataStorage.engine.currentRenderPassId];\r\n        return instanceDataStorage ? instanceDataStorage.instancesPreviousData : (undefined as any);\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that the update of the instance buffer of the world matrices is manual */\r\n    public get manualUpdateOfWorldMatrixInstancedBuffer() {\r\n        return this._instanceDataStorage.manualUpdate;\r\n    }\r\n\r\n    public set manualUpdateOfWorldMatrixInstancedBuffer(value: boolean) {\r\n        this._instanceDataStorage.manualUpdate = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that the update of the instance buffer of the world matrices is manual */\r\n    public get manualUpdateOfPreviousWorldMatrixInstancedBuffer() {\r\n        return this._instanceDataStorage.previousManualUpdate;\r\n    }\r\n\r\n    public set manualUpdateOfPreviousWorldMatrixInstancedBuffer(value: boolean) {\r\n        this._instanceDataStorage.previousManualUpdate = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that the update of the instance buffer of the world matrices must be performed in all cases (and notably even in frozen mode) */\r\n    public get forceWorldMatrixInstancedBufferUpdate() {\r\n        return this._instanceDataStorage.forceMatrixUpdates;\r\n    }\r\n\r\n    public set forceWorldMatrixInstancedBufferUpdate(value: boolean) {\r\n        this._instanceDataStorage.forceMatrixUpdates = value;\r\n    }\r\n\r\n    protected _copySource(source: Mesh, doNotCloneChildren?: boolean, clonePhysicsImpostor: boolean = true, cloneThinInstances: boolean = false): void {\r\n        const scene = this.getScene();\r\n        // Geometry\r\n        if (source._geometry) {\r\n            source._geometry.applyToMesh(this);\r\n        }\r\n\r\n        // Deep copy\r\n        DeepCopier.DeepCopy(\r\n            source,\r\n            this,\r\n            [\r\n                \"name\",\r\n                \"material\",\r\n                \"skeleton\",\r\n                \"instances\",\r\n                \"parent\",\r\n                \"uniqueId\",\r\n                \"source\",\r\n                \"metadata\",\r\n                \"morphTargetManager\",\r\n                \"hasInstances\",\r\n                \"worldMatrixInstancedBuffer\",\r\n                \"previousWorldMatrixInstancedBuffer\",\r\n                \"hasLODLevels\",\r\n                \"geometry\",\r\n                \"isBlocked\",\r\n                \"areNormalsFrozen\",\r\n                \"facetNb\",\r\n                \"isFacetDataEnabled\",\r\n                \"lightSources\",\r\n                \"useBones\",\r\n                \"isAnInstance\",\r\n                \"collider\",\r\n                \"edgesRenderer\",\r\n                \"forward\",\r\n                \"up\",\r\n                \"right\",\r\n                \"absolutePosition\",\r\n                \"absoluteScaling\",\r\n                \"absoluteRotationQuaternion\",\r\n                \"isWorldMatrixFrozen\",\r\n                \"nonUniformScaling\",\r\n                \"behaviors\",\r\n                \"worldMatrixFromCache\",\r\n                \"hasThinInstances\",\r\n                \"cloneMeshMap\",\r\n                \"hasBoundingInfo\",\r\n                \"physicsBody\",\r\n                \"physicsImpostor\",\r\n            ],\r\n            [\"_poseMatrix\"]\r\n        );\r\n\r\n        // Source mesh\r\n        this._internalMeshDataInfo._source = source;\r\n        if (scene.useClonedMeshMap) {\r\n            if (!source._internalMeshDataInfo.meshMap) {\r\n                source._internalMeshDataInfo.meshMap = {};\r\n            }\r\n            source._internalMeshDataInfo.meshMap[this.uniqueId] = this;\r\n        }\r\n\r\n        // Construction Params\r\n        // Clone parameters allowing mesh to be updated in case of parametric shapes.\r\n        this._originalBuilderSideOrientation = source._originalBuilderSideOrientation;\r\n        this._creationDataStorage = source._creationDataStorage;\r\n\r\n        // Animation ranges\r\n        if (source._ranges) {\r\n            const ranges = source._ranges;\r\n            for (const name in ranges) {\r\n                if (!Object.prototype.hasOwnProperty.call(ranges, name)) {\r\n                    continue;\r\n                }\r\n\r\n                if (!ranges[name]) {\r\n                    continue;\r\n                }\r\n\r\n                this.createAnimationRange(name, ranges[name].from, ranges[name].to);\r\n            }\r\n        }\r\n\r\n        // Metadata\r\n        if (source.metadata && source.metadata.clone) {\r\n            this.metadata = source.metadata.clone();\r\n        } else {\r\n            this.metadata = source.metadata;\r\n        }\r\n        this._internalMetadata = source._internalMetadata;\r\n        this.meshBlendingTag = source.meshBlendingTag;\r\n\r\n        // Tags\r\n        if (Tags && Tags.HasTags(source)) {\r\n            Tags.AddTagsTo(this, Tags.GetTags(source, true));\r\n        }\r\n\r\n        // Enabled. We shouldn't need to check the source's ancestors, as this mesh\r\n        // will have the same ones.\r\n        this.setEnabled(source.isEnabled(false));\r\n\r\n        // Parent\r\n        this.parent = source.parent;\r\n\r\n        // Pivot\r\n        this.setPivotMatrix(source.getPivotMatrix(), this._postMultiplyPivotMatrix);\r\n\r\n        this.id = this.name + \".\" + source.id;\r\n\r\n        // Material\r\n        this.material = source.material;\r\n\r\n        if (!doNotCloneChildren) {\r\n            // Children\r\n            const directDescendants = source.getDescendants(true);\r\n            for (let index = 0; index < directDescendants.length; index++) {\r\n                const child = directDescendants[index];\r\n\r\n                if ((<any>child)._isMesh) {\r\n                    MeshCreationOptions.parent = this;\r\n                    MeshCreationOptions.doNotCloneChildren = doNotCloneChildren;\r\n                    MeshCreationOptions.clonePhysicsImpostor = clonePhysicsImpostor;\r\n                    MeshCreationOptions.cloneThinInstances = cloneThinInstances;\r\n                    (<Mesh>child).clone(this.name + \".\" + child.name, MeshCreationOptions);\r\n                } else if ((<any>child).clone) {\r\n                    (<any>child).clone(this.name + \".\" + child.name, this);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Morphs\r\n        if (source.morphTargetManager) {\r\n            this.morphTargetManager = source.morphTargetManager;\r\n        }\r\n\r\n        // Physics clone\r\n        if (_IsSideEffectImplemented(scene.getPhysicsEngine)) {\r\n            const physicsEngine = scene.getPhysicsEngine();\r\n            if (clonePhysicsImpostor && physicsEngine) {\r\n                if (physicsEngine.getPluginVersion() === 1) {\r\n                    const impostor = (physicsEngine as PhysicsEngineV1).getImpostorForPhysicsObject(source);\r\n                    if (impostor) {\r\n                        this.physicsImpostor = impostor.clone(this);\r\n                    }\r\n                } else if (physicsEngine.getPluginVersion() === 2) {\r\n                    if (source.physicsBody) {\r\n                        source.physicsBody.clone(this);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Particles\r\n        for (let index = 0; index < scene.particleSystems.length; index++) {\r\n            const system = scene.particleSystems[index];\r\n\r\n            if (system.emitter === source) {\r\n                system.clone(system.name, this);\r\n            }\r\n        }\r\n\r\n        // Skeleton\r\n        this.skeleton = source.skeleton;\r\n\r\n        // Thin instances\r\n        if (cloneThinInstances) {\r\n            if (source._thinInstanceDataStorage.matrixData) {\r\n                this.thinInstanceSetBuffer(\r\n                    \"matrix\",\r\n                    new Float32Array(source._thinInstanceDataStorage.matrixData),\r\n                    16,\r\n                    !source._thinInstanceDataStorage.matrixBuffer!.isUpdatable()\r\n                );\r\n                this._thinInstanceDataStorage.matrixBufferSize = source._thinInstanceDataStorage.matrixBufferSize;\r\n                this._thinInstanceDataStorage.instancesCount = source._thinInstanceDataStorage.instancesCount;\r\n            } else {\r\n                this._thinInstanceDataStorage.matrixBufferSize = source._thinInstanceDataStorage.matrixBufferSize;\r\n            }\r\n\r\n            if (source._userThinInstanceBuffersStorage) {\r\n                const userThinInstance = source._userThinInstanceBuffersStorage;\r\n                for (const kind in userThinInstance.data) {\r\n                    this.thinInstanceSetBuffer(\r\n                        kind,\r\n                        new Float32Array(userThinInstance.data[kind]),\r\n                        userThinInstance.strides[kind],\r\n                        !userThinInstance.vertexBuffers?.[kind]?.isUpdatable()\r\n                    );\r\n                    this._userThinInstanceBuffersStorage.sizes[kind] = userThinInstance.sizes[kind];\r\n                }\r\n            }\r\n        }\r\n\r\n        this.refreshBoundingInfo(true, true);\r\n        this.computeWorldMatrix(true);\r\n    }\r\n\r\n    /**\r\n     * Constructor\r\n     * @param name The value used by scene.getMeshByName() to do a lookup.\r\n     * @param scene The scene to add this mesh to.\r\n     * @param options Options used to create the mesh\r\n     */\r\n    constructor(name: string, scene?: Nullable<Scene>, options?: MeshCreationOptions);\r\n\r\n    /**\r\n     * Constructor\r\n     * @param name The value used by scene.getMeshByName() to do a lookup.\r\n     * @param scene The scene to add this mesh to.\r\n     * @param parent The parent of this mesh, if it has one\r\n     * @param source An optional Mesh from which geometry is shared, cloned.\r\n     * @param doNotCloneChildren When cloning, skip cloning child meshes of source, default False.\r\n     *                  When false, achieved by calling a clone(), also passing False.\r\n     *                  This will make creation of children, recursive.\r\n     * @param clonePhysicsImpostor When cloning, include cloning mesh physics impostor, default True.\r\n     */\r\n    constructor(name: string, scene?: Nullable<Scene>, parent?: Nullable<Node>, source?: Nullable<Mesh>, doNotCloneChildren?: boolean, clonePhysicsImpostor?: boolean);\r\n\r\n    /** @internal */\r\n    constructor(\r\n        name: string,\r\n        scene: Nullable<Scene> = null,\r\n        parentOrOptions: Nullable<Node> | MeshCreationOptions = null,\r\n        source: Nullable<Mesh> = null,\r\n        doNotCloneChildren?: boolean,\r\n        clonePhysicsImpostor: boolean = true\r\n    ) {\r\n        super(name, scene);\r\n\r\n        scene = this.getScene();\r\n\r\n        this._instanceDataStorage = new _InstanceDataStorage();\r\n        this._instanceDataStorage.engine = scene.getEngine();\r\n        this._instanceDataStorage.useMonoDataStorageRenderPass = !this._instanceDataStorage.engine.isWebGPU;\r\n        if (this._instanceDataStorage.useMonoDataStorageRenderPass) {\r\n            this._instanceDataStorage.dataStorageRenderPass = new _InstanceDataStorageRenderPass();\r\n        }\r\n\r\n        if (this._scene.useRightHandedSystem) {\r\n            this.sideOrientation = Constants.MATERIAL_ClockWiseSideOrientation;\r\n        } else {\r\n            this.sideOrientation = Constants.MATERIAL_CounterClockWiseSideOrientation;\r\n        }\r\n\r\n        this._onBeforeDraw = (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => {\r\n            if (isInstance && effectiveMaterial) {\r\n                if (this._uniformBuffer) {\r\n                    this.transferToEffect(world);\r\n                } else {\r\n                    effectiveMaterial.bindOnlyWorldMatrix(world);\r\n                }\r\n            }\r\n        };\r\n\r\n        let parent: Nullable<Node>;\r\n        let cloneThinInstances = false;\r\n\r\n        if (parentOrOptions && (parentOrOptions as Node)._addToSceneRootNodes === undefined) {\r\n            const options = parentOrOptions as MeshCreationOptions;\r\n\r\n            parent = options.parent ?? null;\r\n            source = options.source ?? null;\r\n            doNotCloneChildren = options.doNotCloneChildren ?? false;\r\n            clonePhysicsImpostor = options.clonePhysicsImpostor ?? true;\r\n            cloneThinInstances = options.cloneThinInstances ?? false;\r\n        } else {\r\n            parent = parentOrOptions as Nullable<Node>;\r\n        }\r\n\r\n        if (source) {\r\n            this._copySource(source, doNotCloneChildren, clonePhysicsImpostor, cloneThinInstances);\r\n        }\r\n\r\n        // Parent\r\n        if (parent !== null) {\r\n            this.parent = parent;\r\n        }\r\n\r\n        this._instanceDataStorage.hardwareInstancedRendering = this.getEngine().getCaps().instancedArrays;\r\n\r\n        this._internalMeshDataInfo._onMeshReadyObserverAdded = (observer: Observer<Mesh>) => {\r\n            // only notify once! then unregister the observer\r\n            observer.unregisterOnNextCall = true;\r\n            if (this.isReady(true)) {\r\n                this.onMeshReadyObservable.notifyObservers(this);\r\n            } else {\r\n                if (!this._internalMeshDataInfo._checkReadinessObserver) {\r\n                    this._internalMeshDataInfo._checkReadinessObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n                        // check for complete readiness\r\n                        if (this.isReady(true)) {\r\n                            this._scene.onBeforeRenderObservable.remove(this._internalMeshDataInfo._checkReadinessObserver);\r\n                            this._internalMeshDataInfo._checkReadinessObserver = null;\r\n                            this.onMeshReadyObservable.notifyObservers(this);\r\n                        }\r\n                    });\r\n                }\r\n            }\r\n        };\r\n\r\n        this.onMeshReadyObservable = new Observable(this._internalMeshDataInfo._onMeshReadyObserverAdded);\r\n\r\n        if (source) {\r\n            source.onClonedObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiate (when possible) or clone that node with its hierarchy\r\n     * @param newParent defines the new parent to use for the instance (or clone)\r\n     * @param options defines options to configure how copy is done\r\n     * @param onNewNodeCreated defines an option callback to call when a clone or an instance is created\r\n     * @returns an instance (or a clone) of the current node with its hierarchy\r\n     */\r\n    public override instantiateHierarchy(\r\n        newParent: Nullable<TransformNode> = null,\r\n        options?: { doNotInstantiate: boolean | ((node: TransformNode) => boolean) },\r\n        onNewNodeCreated?: (source: TransformNode, clone: TransformNode) => void\r\n    ): Nullable<TransformNode> {\r\n        const instance =\r\n            this.getTotalVertices() === 0 || (options && options.doNotInstantiate && (options.doNotInstantiate === true || options.doNotInstantiate(this)))\r\n                ? this.clone(\"Clone of \" + (this.name || this.id), newParent || this.parent, true)\r\n                : this.createInstance(\"instance of \" + (this.name || this.id));\r\n\r\n        instance.parent = newParent || this.parent;\r\n        instance.position = this.position.clone();\r\n        instance.scaling = this.scaling.clone();\r\n        if (this.rotationQuaternion) {\r\n            instance.rotationQuaternion = this.rotationQuaternion.clone();\r\n        } else {\r\n            instance.rotation = this.rotation.clone();\r\n        }\r\n\r\n        if (onNewNodeCreated) {\r\n            onNewNodeCreated(this, instance);\r\n        }\r\n\r\n        for (const child of this.getChildTransformNodes(true)) {\r\n            // instancedMesh should have a different sourced mesh\r\n            if (child.getClassName() === \"InstancedMesh\" && instance.getClassName() === \"Mesh\" && (child as InstancedMesh).sourceMesh === this) {\r\n                (child as InstancedMesh).instantiateHierarchy(\r\n                    instance,\r\n                    {\r\n                        doNotInstantiate: (options && options.doNotInstantiate) || false,\r\n                        newSourcedMesh: instance as Mesh,\r\n                    },\r\n                    onNewNodeCreated\r\n                );\r\n            } else {\r\n                child.instantiateHierarchy(instance, options, onNewNodeCreated);\r\n            }\r\n        }\r\n\r\n        return instance;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name\r\n     * @returns the string \"Mesh\".\r\n     */\r\n    public override getClassName(): string {\r\n        return \"Mesh\";\r\n    }\r\n\r\n    /** @internal */\r\n    public get _isMesh() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns a description of this mesh\r\n     * @param fullDetails define if full details about this mesh must be used\r\n     * @returns a descriptive string representing this mesh\r\n     */\r\n    public override toString(fullDetails?: boolean): string {\r\n        let ret = super.toString(fullDetails);\r\n        ret += \", n vertices: \" + this.getTotalVertices();\r\n        ret += \", parent: \" + (this._waitingParentId ? this._waitingParentId : this.parent ? this.parent.name : \"NONE\");\r\n\r\n        if (this.animations) {\r\n            for (let i = 0; i < this.animations.length; i++) {\r\n                ret += \", animation[0]: \" + this.animations[i].toString(fullDetails);\r\n            }\r\n        }\r\n\r\n        if (fullDetails) {\r\n            if (this._geometry) {\r\n                const ib = this.getIndices();\r\n                const vb = this.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n                if (vb && ib) {\r\n                    ret += \", flat shading: \" + (vb.length / 3 === ib.length ? \"YES\" : \"NO\");\r\n                }\r\n            } else {\r\n                ret += \", flat shading: UNKNOWN\";\r\n            }\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _unBindEffect() {\r\n        super._unBindEffect();\r\n\r\n        for (const instance of this.instances) {\r\n            instance._unBindEffect();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this mesh has LOD\r\n     */\r\n    public get hasLODLevels(): boolean {\r\n        return this._internalMeshDataInfo._LODLevels.length > 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of MeshLODLevel associated with the current mesh\r\n     * @returns an array of MeshLODLevel\r\n     */\r\n    public getLODLevels(): MeshLODLevel[] {\r\n        return this._internalMeshDataInfo._LODLevels;\r\n    }\r\n\r\n    private _sortLODLevels(): void {\r\n        const sortingOrderFactor = this._internalMeshDataInfo._useLODScreenCoverage ? -1 : 1;\r\n        this._internalMeshDataInfo._LODLevels.sort((a, b) => {\r\n            if (a.distanceOrScreenCoverage < b.distanceOrScreenCoverage) {\r\n                return sortingOrderFactor;\r\n            }\r\n            if (a.distanceOrScreenCoverage > b.distanceOrScreenCoverage) {\r\n                return -sortingOrderFactor;\r\n            }\r\n\r\n            return 0;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Add a mesh as LOD level triggered at the given distance.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD\r\n     * @param distanceOrScreenCoverage Either distance from the center of the object to show this level or the screen coverage if `useScreenCoverage` is set to `true`.\r\n     * If screen coverage, value is a fraction of the screen's total surface, between 0 and 1.\r\n     * Example Playground for distance https://playground.babylonjs.com/#QE7KM#197\r\n     * Example Playground for screen coverage https://playground.babylonjs.com/#QE7KM#196\r\n     * @param mesh The mesh to be added as LOD level (can be null)\r\n     * @returns This mesh (for chaining)\r\n     */\r\n    public addLODLevel(distanceOrScreenCoverage: number, mesh: Nullable<Mesh>): Mesh {\r\n        if (mesh && mesh._masterMesh) {\r\n            Logger.Warn(\"You cannot use a mesh as LOD level twice\");\r\n            return this;\r\n        }\r\n\r\n        const level = new MeshLODLevel(distanceOrScreenCoverage, mesh);\r\n        this._internalMeshDataInfo._LODLevels.push(level);\r\n\r\n        if (mesh) {\r\n            mesh._masterMesh = this;\r\n        }\r\n\r\n        this._sortLODLevels();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the LOD level mesh at the passed distance or null if not found.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD\r\n     * @param distance The distance from the center of the object to show this level\r\n     * @returns a Mesh or `null`\r\n     */\r\n    public getLODLevelAtDistance(distance: number): Nullable<Mesh> {\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n        for (let index = 0; index < internalDataInfo._LODLevels.length; index++) {\r\n            const level = internalDataInfo._LODLevels[index];\r\n\r\n            if (level.distanceOrScreenCoverage === distance) {\r\n                return level.mesh;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the LOD array\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD\r\n     * @param mesh defines the mesh to be removed\r\n     * @returns This mesh (for chaining)\r\n     */\r\n    public removeLODLevel(mesh: Nullable<Mesh>): Mesh {\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n        for (let index = 0; index < internalDataInfo._LODLevels.length; index++) {\r\n            if (internalDataInfo._LODLevels[index].mesh === mesh) {\r\n                internalDataInfo._LODLevels.splice(index, 1);\r\n                if (mesh) {\r\n                    mesh._masterMesh = null;\r\n                }\r\n            }\r\n        }\r\n\r\n        this._sortLODLevels();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns the registered LOD mesh distant from the parameter `camera` position if any, else returns the current mesh.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/LOD\r\n     * @param camera defines the camera to use to compute distance\r\n     * @param boundingSphere defines a custom bounding sphere to use instead of the one from this mesh\r\n     * @returns This mesh (for chaining)\r\n     */\r\n    public override getLOD(camera: Camera, boundingSphere?: BoundingSphere): Nullable<AbstractMesh> {\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n        if (!internalDataInfo._LODLevels || internalDataInfo._LODLevels.length === 0) {\r\n            return this;\r\n        }\r\n\r\n        const bSphere = boundingSphere || this.getBoundingInfo().boundingSphere;\r\n\r\n        const distanceToCamera = camera.mode === Camera.ORTHOGRAPHIC_CAMERA ? camera.minZ : bSphere.centerWorld.subtract(camera.globalPosition).length();\r\n        let compareValue = distanceToCamera;\r\n        let compareSign = 1;\r\n\r\n        if (internalDataInfo._useLODScreenCoverage) {\r\n            const screenArea = camera.screenArea;\r\n            let meshArea = (bSphere.radiusWorld * camera.minZ) / distanceToCamera;\r\n            meshArea = meshArea * meshArea * Math.PI;\r\n            compareValue = meshArea / screenArea;\r\n            compareSign = -1;\r\n        }\r\n\r\n        if (compareSign * internalDataInfo._LODLevels[internalDataInfo._LODLevels.length - 1].distanceOrScreenCoverage > compareSign * compareValue) {\r\n            if (this.onLODLevelSelection) {\r\n                this.onLODLevelSelection(compareValue, this, this);\r\n            }\r\n            return this;\r\n        }\r\n\r\n        for (let index = 0; index < internalDataInfo._LODLevels.length; index++) {\r\n            const level = internalDataInfo._LODLevels[index];\r\n\r\n            if (compareSign * level.distanceOrScreenCoverage < compareSign * compareValue) {\r\n                if (level.mesh) {\r\n                    if (level.mesh.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n                        level.mesh._checkDelayState();\r\n                        return this;\r\n                    }\r\n\r\n                    if (level.mesh.delayLoadState === Constants.DELAYLOADSTATE_LOADING) {\r\n                        return this;\r\n                    }\r\n\r\n                    level.mesh._preActivate();\r\n                    level.mesh._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n                }\r\n\r\n                if (this.onLODLevelSelection) {\r\n                    this.onLODLevelSelection(compareValue, this, level.mesh);\r\n                }\r\n\r\n                return level.mesh;\r\n            }\r\n        }\r\n\r\n        if (this.onLODLevelSelection) {\r\n            this.onLODLevelSelection(compareValue, this, this);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh internal Geometry object\r\n     */\r\n    public override get geometry(): Nullable<Geometry> {\r\n        return this._geometry;\r\n    }\r\n\r\n    /**\r\n     * Returns the total number of vertices within the mesh geometry or zero if the mesh has no geometry.\r\n     * @returns the total number of vertices\r\n     */\r\n    public override getTotalVertices(): number {\r\n        if (this._geometry === null || this._geometry === undefined) {\r\n            return 0;\r\n        }\r\n        return this._geometry.getTotalVertices();\r\n    }\r\n\r\n    /**\r\n     * Returns the content of an associated vertex buffer\r\n     * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param copyWhenShared defines a boolean indicating that if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one\r\n     * @param forceCopy defines a boolean forcing the copy of the buffer no matter what the value of copyWhenShared is\r\n     * @param bypassInstanceData defines a boolean indicating that the function should not take into account the instance data (applies only if the mesh has instances). Default: false\r\n     * @returns a FloatArray or null if the mesh has no geometry or no vertex buffer for this kind.\r\n     */\r\n    public override getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean, bypassInstanceData?: boolean): Nullable<FloatArray> {\r\n        if (!this._geometry) {\r\n            return null;\r\n        }\r\n        let data = bypassInstanceData\r\n            ? undefined\r\n            : this._userInstancedBuffersStorage?.vertexBuffers[kind]?.getFloatData(\r\n                  this.instances.length + 1, // +1 because the master mesh is not included in the instances array\r\n                  forceCopy || (copyWhenShared && this._geometry.meshes.length !== 1)\r\n              );\r\n        if (!data) {\r\n            data = this._geometry.getVerticesData(kind, copyWhenShared, forceCopy);\r\n        }\r\n        return data;\r\n    }\r\n\r\n    /**\r\n     * Copies the requested vertex data kind into the given vertex data map. Float data is constructed if the map doesn't have the data.\r\n     * @param kind defines the vertex data kind to use\r\n     * @param vertexData defines the map that stores the resulting data\r\n     */\r\n    public override copyVerticesData(kind: string, vertexData: { [kind: string]: Float32Array }): void {\r\n        if (this._geometry) {\r\n            this._geometry.copyVerticesData(kind, vertexData);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the mesh VertexBuffer object from the requested `kind`\r\n     * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.NormalKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param bypassInstanceData defines a boolean indicating that the function should not take into account the instance data (applies only if the mesh has instances). Default: false\r\n     * @returns a FloatArray or null if the mesh has no vertex buffer for this kind.\r\n     */\r\n    public override getVertexBuffer(kind: string, bypassInstanceData?: boolean): Nullable<VertexBuffer> {\r\n        if (!this._geometry) {\r\n            return null;\r\n        }\r\n\r\n        return (bypassInstanceData ? undefined : this._userInstancedBuffersStorage?.vertexBuffers[kind]) ?? this._geometry.getVertexBuffer(kind);\r\n    }\r\n\r\n    /**\r\n     * Tests if a specific vertex buffer is associated with this mesh\r\n     * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.NormalKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param bypassInstanceData defines a boolean indicating that the function should not take into account the instance data (applies only if the mesh has instances). Default: false\r\n     * @returns a boolean\r\n     */\r\n    public override isVerticesDataPresent(kind: string, bypassInstanceData?: boolean): boolean {\r\n        if (!this._geometry) {\r\n            if (this._delayInfo) {\r\n                return this._delayInfo.indexOf(kind) !== -1;\r\n            }\r\n            return false;\r\n        }\r\n        return (!bypassInstanceData && this._userInstancedBuffersStorage?.vertexBuffers[kind] !== undefined) || this._geometry.isVerticesDataPresent(kind);\r\n    }\r\n\r\n    /**\r\n     * Returns a boolean defining if the vertex data for the requested `kind` is updatable.\r\n     * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param bypassInstanceData defines a boolean indicating that the function should not take into account the instance data (applies only if the mesh has instances). Default: false\r\n     * @returns a boolean\r\n     */\r\n    public isVertexBufferUpdatable(kind: string, bypassInstanceData?: boolean): boolean {\r\n        if (!this._geometry) {\r\n            if (this._delayInfo) {\r\n                return this._delayInfo.indexOf(kind) !== -1;\r\n            }\r\n            return false;\r\n        }\r\n        if (!bypassInstanceData) {\r\n            const buffer = this._userInstancedBuffersStorage?.vertexBuffers[kind];\r\n            if (buffer) {\r\n                return buffer.isUpdatable();\r\n            }\r\n        }\r\n        return this._geometry.isVertexBufferUpdatable(kind);\r\n    }\r\n\r\n    /**\r\n     * Returns a string which contains the list of existing `kinds` of Vertex Data associated with this mesh.\r\n     * @param bypassInstanceData defines a boolean indicating that the function should not take into account the instance data (applies only if the mesh has instances). Default: false\r\n     * @returns an array of strings\r\n     */\r\n    public getVerticesDataKinds(bypassInstanceData?: boolean): string[] {\r\n        if (!this._geometry) {\r\n            const result: string[] = [];\r\n            if (this._delayInfo) {\r\n                for (const kind of this._delayInfo) {\r\n                    result.push(kind);\r\n                }\r\n            }\r\n            return result;\r\n        }\r\n        const kinds = this._geometry.getVerticesDataKinds();\r\n        if (!bypassInstanceData && this._userInstancedBuffersStorage) {\r\n            for (const kind in this._userInstancedBuffersStorage.vertexBuffers) {\r\n                if (kinds.indexOf(kind) === -1) {\r\n                    kinds.push(kind);\r\n                }\r\n            }\r\n        }\r\n        return kinds;\r\n    }\r\n\r\n    /**\r\n     * Returns a positive integer : the total number of indices in this mesh geometry.\r\n     * @returns the number of indices or zero if the mesh has no geometry.\r\n     */\r\n    public override getTotalIndices(): number {\r\n        if (!this._geometry) {\r\n            return 0;\r\n        }\r\n        return this._geometry.getTotalIndices();\r\n    }\r\n\r\n    /**\r\n     * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.\r\n     * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.\r\n     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it\r\n     * @returns the indices array or an empty array if the mesh has no geometry\r\n     */\r\n    public override getIndices(copyWhenShared?: boolean, forceCopy?: boolean): Nullable<IndicesArray> {\r\n        if (!this._geometry) {\r\n            return [];\r\n        }\r\n        return this._geometry.getIndices(copyWhenShared, forceCopy);\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get isBlocked(): boolean {\r\n        return this._masterMesh !== null && this._masterMesh !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Determine if the current mesh is ready to be rendered\r\n     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n     * @param forceInstanceSupport will check if the mesh will be ready when used with instances (false by default)\r\n     * @returns true if all associated assets are ready (material, textures, shaders)\r\n     */\r\n    public override isReady(completeCheck = false, forceInstanceSupport = false): boolean {\r\n        if (this.delayLoadState === Constants.DELAYLOADSTATE_LOADING) {\r\n            return false;\r\n        }\r\n\r\n        if (!super.isReady(completeCheck)) {\r\n            return false;\r\n        }\r\n\r\n        if (!this.subMeshes || this.subMeshes.length === 0) {\r\n            return true;\r\n        }\r\n\r\n        if (!completeCheck) {\r\n            return true;\r\n        }\r\n\r\n        const engine = this.getEngine();\r\n        const scene = this.getScene();\r\n        const hardwareInstancedRendering = forceInstanceSupport || (engine.getCaps().instancedArrays && (this.instances.length > 0 || this.hasThinInstances));\r\n\r\n        this.computeWorldMatrix();\r\n\r\n        const mat = this.material || scene.defaultMaterial;\r\n        if (mat) {\r\n            if (mat._storeEffectOnSubMeshes) {\r\n                for (const subMesh of this.subMeshes) {\r\n                    const effectiveMaterial = subMesh.getMaterial();\r\n                    if (effectiveMaterial) {\r\n                        if (effectiveMaterial._storeEffectOnSubMeshes) {\r\n                            if (!effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {\r\n                                return false;\r\n                            }\r\n                        } else {\r\n                            if (!effectiveMaterial.isReady(this, hardwareInstancedRendering)) {\r\n                                return false;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n                if (!mat.isReady(this, hardwareInstancedRendering)) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Shadows\r\n        const currentRenderPassId = engine.currentRenderPassId;\r\n        for (const light of this.lightSources) {\r\n            const generators = light.getShadowGenerators();\r\n\r\n            if (!generators) {\r\n                continue;\r\n            }\r\n\r\n            const iterator = generators.values();\r\n            for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                const generator = key.value;\r\n                if (generator && (!generator.getShadowMap()?.renderList || (generator.getShadowMap()?.renderList && generator.getShadowMap()?.renderList?.indexOf(this) !== -1))) {\r\n                    const shadowMap = generator.getShadowMap()!;\r\n                    const renderPassIds = shadowMap.renderPassIds ?? [engine.currentRenderPassId];\r\n                    for (let p = 0; p < renderPassIds.length; ++p) {\r\n                        engine.currentRenderPassId = renderPassIds[p];\r\n                        for (const subMesh of this.subMeshes) {\r\n                            if (!generator.isReady(subMesh, hardwareInstancedRendering, subMesh.getMaterial()?.needAlphaBlendingForMesh(this) ?? false)) {\r\n                                engine.currentRenderPassId = currentRenderPassId;\r\n                                return false;\r\n                            }\r\n                        }\r\n                    }\r\n                    engine.currentRenderPassId = currentRenderPassId;\r\n                }\r\n            }\r\n        }\r\n\r\n        // LOD\r\n        for (const lod of this._internalMeshDataInfo._LODLevels) {\r\n            if (lod.mesh && !lod.mesh.isReady(hardwareInstancedRendering)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the normals aren't to be recomputed on next mesh `positions` array update. This property is pertinent only for updatable parametric shapes.\r\n     */\r\n    public get areNormalsFrozen(): boolean {\r\n        return this._internalMeshDataInfo._areNormalsFrozen;\r\n    }\r\n\r\n    /**\r\n     * This function affects parametric shapes on vertex position update only : ribbons, tubes, etc. It has no effect at all on other shapes. It prevents the mesh normals from being recomputed on next `positions` array update.\r\n     * @returns the current mesh\r\n     */\r\n    public freezeNormals(): Mesh {\r\n        this._internalMeshDataInfo._areNormalsFrozen = true;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * This function affects parametric shapes on vertex position update only : ribbons, tubes, etc. It has no effect at all on other shapes. It reactivates the mesh normals computation if it was previously frozen\r\n     * @returns the current mesh\r\n     */\r\n    public unfreezeNormals(): Mesh {\r\n        this._internalMeshDataInfo._areNormalsFrozen = false;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets a value overriding the instance count. Only applicable when custom instanced InterleavedVertexBuffer are used rather than InstancedMeshs\r\n     */\r\n    public set overridenInstanceCount(count: number) {\r\n        this._instanceDataStorage.overridenInstanceCount = count;\r\n    }\r\n\r\n    /** @internal */\r\n    public _getInstanceDataStorage(): _InstanceDataStorageRenderPass {\r\n        if (this._instanceDataStorage.useMonoDataStorageRenderPass) {\r\n            return this._instanceDataStorage.dataStorageRenderPass;\r\n        }\r\n\r\n        const renderPassId = this._instanceDataStorage.engine.currentRenderPassId;\r\n\r\n        let instanceDataStorage = this._instanceDataStorage.renderPasses[renderPassId];\r\n        if (!instanceDataStorage) {\r\n            instanceDataStorage = new _InstanceDataStorageRenderPass();\r\n            this._instanceDataStorage.renderPasses[renderPassId] = instanceDataStorage;\r\n        }\r\n\r\n        return instanceDataStorage;\r\n    }\r\n\r\n    // Methods\r\n    /** @internal */\r\n    public override _preActivate(): Mesh {\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n        const sceneRenderId = this.getScene().getRenderId();\r\n        if (internalDataInfo._preActivateId === sceneRenderId) {\r\n            return this;\r\n        }\r\n\r\n        internalDataInfo._preActivateId = sceneRenderId;\r\n        if (this._instanceDataStorage.useMonoDataStorageRenderPass) {\r\n            this._instanceDataStorage.dataStorageRenderPass.visibleInstances = null;\r\n        } else {\r\n            this._getInstanceDataStorage().visibleInstances = null;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _preActivateForIntermediateRendering(renderId: number): Mesh {\r\n        const instanceDataStorage = this._instanceDataStorage.useMonoDataStorageRenderPass ? this._instanceDataStorage.dataStorageRenderPass : this._getInstanceDataStorage();\r\n        if (instanceDataStorage.visibleInstances) {\r\n            instanceDataStorage.visibleInstances.intermediateDefaultRenderId = renderId;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _registerInstanceForRenderId(instance: InstancedMesh, renderId: number): Mesh {\r\n        const instanceDataStorage = this._instanceDataStorage.useMonoDataStorageRenderPass ? this._instanceDataStorage.dataStorageRenderPass : this._getInstanceDataStorage();\r\n        if (!instanceDataStorage.visibleInstances) {\r\n            instanceDataStorage.visibleInstances = {\r\n                defaultRenderId: renderId,\r\n                selfDefaultRenderId: this._renderId,\r\n                intermediateDefaultRenderId: -1,\r\n            };\r\n        }\r\n\r\n        if (!instanceDataStorage.visibleInstances[renderId]) {\r\n            if (instanceDataStorage.previousRenderId !== undefined && (!this._instanceDataStorage.useMonoDataStorageRenderPass || this._instanceDataStorage.isFrozen)) {\r\n                delete instanceDataStorage.visibleInstances[instanceDataStorage.previousRenderId];\r\n            }\r\n            instanceDataStorage.previousRenderId = renderId;\r\n            instanceDataStorage.visibleInstances[renderId] = new Array<InstancedMesh>();\r\n        }\r\n\r\n        instanceDataStorage.visibleInstances[renderId].push(instance);\r\n        return this;\r\n    }\r\n\r\n    protected override _afterComputeWorldMatrix(): void {\r\n        super._afterComputeWorldMatrix();\r\n\r\n        if (!this.hasThinInstances) {\r\n            return;\r\n        }\r\n\r\n        if (!this.doNotSyncBoundingInfo) {\r\n            this.thinInstanceRefreshBoundingInfo(false);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _postActivate(): void {\r\n        if (this.edgesShareWithInstances && this.edgesRenderer && this.edgesRenderer.isEnabled && this._renderingGroup) {\r\n            this._renderingGroup._edgesRenderers.pushNoDuplicate(this.edgesRenderer);\r\n            this.edgesRenderer.customInstances.push(this.getWorldMatrix());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.\r\n     * This means the mesh underlying bounding box and sphere are recomputed.\r\n     * @param applySkeletonOrOptions defines whether to apply the skeleton before computing the bounding info or a set of options\r\n     * @param applyMorph defines whether to apply the morph target before computing the bounding info\r\n     * @returns the current mesh\r\n     */\r\n    public override refreshBoundingInfo(applySkeletonOrOptions: boolean | IMeshDataOptions = false, applyMorph: boolean = false): Mesh {\r\n        if (this.hasBoundingInfo && this.getBoundingInfo().isLocked) {\r\n            return this;\r\n        }\r\n\r\n        let options: IMeshDataOptions;\r\n        if (typeof applySkeletonOrOptions === \"object\") {\r\n            options = applySkeletonOrOptions;\r\n        } else {\r\n            options = {\r\n                applySkeleton: applySkeletonOrOptions,\r\n                applyMorph: applyMorph,\r\n            };\r\n        }\r\n\r\n        const bias = this.geometry ? this.geometry.boundingBias : null;\r\n        this._refreshBoundingInfo(this._getData(options, null, VertexBuffer.PositionKind), bias);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _createGlobalSubMesh(force: boolean): Nullable<SubMesh> {\r\n        const totalVertices = this.getTotalVertices();\r\n        if (!totalVertices || !this.getIndices()) {\r\n            return null;\r\n        }\r\n\r\n        // Check if we need to recreate the submeshes\r\n        if (this.subMeshes && this.subMeshes.length > 0) {\r\n            const ib = this.getIndices();\r\n\r\n            if (!ib) {\r\n                return null;\r\n            }\r\n\r\n            const totalIndices = ib.length;\r\n            let needToRecreate = false;\r\n\r\n            if (force) {\r\n                needToRecreate = true;\r\n            } else {\r\n                for (const submesh of this.subMeshes) {\r\n                    if (submesh.indexStart + submesh.indexCount > totalIndices) {\r\n                        needToRecreate = true;\r\n                        break;\r\n                    }\r\n\r\n                    if (submesh.verticesStart + submesh.verticesCount > totalVertices) {\r\n                        needToRecreate = true;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (!needToRecreate) {\r\n                return this.subMeshes[0];\r\n            }\r\n        }\r\n\r\n        this.releaseSubMeshes();\r\n        return new SubMesh(0, 0, totalVertices, 0, this.getTotalIndices() || (this.isUnIndexed ? totalVertices : 0), this); // getTotalIndices() can be zero if the mesh is unindexed\r\n    }\r\n\r\n    /**\r\n     * This function will subdivide the mesh into multiple submeshes\r\n     * @param count defines the expected number of submeshes\r\n     */\r\n    public subdivide(count: number): void {\r\n        if (count < 1) {\r\n            return;\r\n        }\r\n\r\n        const totalIndices = this.getTotalIndices();\r\n        let subdivisionSize = (totalIndices / count) | 0;\r\n        let offset = 0;\r\n\r\n        // Ensure that subdivisionSize is a multiple of 3\r\n        while (subdivisionSize % 3 !== 0) {\r\n            subdivisionSize++;\r\n        }\r\n\r\n        this.releaseSubMeshes();\r\n        for (let index = 0; index < count; index++) {\r\n            if (offset >= totalIndices) {\r\n                break;\r\n            }\r\n\r\n            SubMesh.CreateFromIndices(0, offset, offset + subdivisionSize >= totalIndices ? totalIndices - offset : subdivisionSize, this, undefined, false);\r\n\r\n            offset += subdivisionSize;\r\n        }\r\n\r\n        this.refreshBoundingInfo();\r\n        this.synchronizeInstances();\r\n    }\r\n\r\n    /**\r\n     * Copy a FloatArray into a specific associated vertex buffer\r\n     * @param kind defines which buffer to write to (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param data defines the data source\r\n     * @param updatable defines if the updated vertex buffer must be flagged as updatable\r\n     * @param stride defines the data stride size (can be null)\r\n     * @returns the current mesh\r\n     */\r\n    public override setVerticesData(kind: string, data: FloatArray, updatable: boolean = false, stride?: number): AbstractMesh {\r\n        if (!this._geometry) {\r\n            const vertexData = new VertexData();\r\n            vertexData.set(data, kind);\r\n\r\n            const scene = this.getScene();\r\n\r\n            new Geometry(Geometry.RandomId(), scene, vertexData, updatable, this);\r\n        } else {\r\n            this._geometry.setVerticesData(kind, data, updatable, stride);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Delete a vertex buffer associated with this mesh\r\n     * @param kind defines which buffer to delete (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     */\r\n    public removeVerticesData(kind: string) {\r\n        if (!this._geometry) {\r\n            return;\r\n        }\r\n\r\n        this._geometry.removeVerticesData(kind);\r\n    }\r\n\r\n    /**\r\n     * Flags an associated vertex buffer as updatable\r\n     * @param kind defines which buffer to use (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param updatable defines if the updated vertex buffer must be flagged as updatable\r\n     */\r\n    public markVerticesDataAsUpdatable(kind: string, updatable = true) {\r\n        const vb = this.getVertexBuffer(kind);\r\n\r\n        if (!vb || vb.isUpdatable() === updatable) {\r\n            return;\r\n        }\r\n\r\n        this.setVerticesData(kind, <FloatArray>this.getVerticesData(kind), updatable);\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh global Vertex Buffer\r\n     * @param buffer defines the buffer to use\r\n     * @param disposeExistingBuffer disposes the existing buffer, if any (default: true)\r\n     * @param totalVertices defines the total number of vertices for position kind (could be null)\r\n     * @returns the current mesh\r\n     */\r\n    public setVerticesBuffer(buffer: VertexBuffer, disposeExistingBuffer = true, totalVertices: Nullable<number> = null): Mesh {\r\n        if (!this._geometry) {\r\n            this._geometry = Geometry.CreateGeometryForMesh(this);\r\n        }\r\n\r\n        this._geometry.setVerticesBuffer(buffer, totalVertices, disposeExistingBuffer);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update a specific associated vertex buffer\r\n     * @param kind defines which buffer to write to (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @param data defines the data source\r\n     * @param updateExtends defines if extends info of the mesh must be updated (can be null). This is mostly useful for \"position\" kind\r\n     * @param makeItUnique defines if the geometry associated with the mesh must be cloned to make the change only for this mesh (and not all meshes associated with the same geometry)\r\n     * @returns the current mesh\r\n     */\r\n    public override updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): AbstractMesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n        if (!makeItUnique) {\r\n            this._geometry.updateVerticesData(kind, data, updateExtends);\r\n        } else {\r\n            this.makeGeometryUnique();\r\n            this.updateVerticesData(kind, data, updateExtends, false);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * This method updates the vertex positions of an updatable mesh according to the `positionFunction` returned values.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#other-shapes-updatemeshpositions\r\n     * @param positionFunction is a simple JS function what is passed the mesh `positions` array. It doesn't need to return anything\r\n     * @param computeNormals is a boolean (default true) to enable/disable the mesh normal recomputation after the vertex position update\r\n     * @returns the current mesh\r\n     */\r\n    public updateMeshPositions(positionFunction: (data: FloatArray) => void, computeNormals: boolean = true): Mesh {\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n        if (!positions) {\r\n            return this;\r\n        }\r\n\r\n        positionFunction(positions);\r\n        this.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);\r\n\r\n        if (computeNormals) {\r\n            const indices = this.getIndices();\r\n            const normals = this.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n            if (!normals) {\r\n                return this;\r\n            }\r\n\r\n            VertexData.ComputeNormals(positions, indices, normals);\r\n            this.updateVerticesData(VertexBuffer.NormalKind, normals, false, false);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates a un-shared specific occurence of the geometry for the mesh.\r\n     * @returns the current mesh\r\n     */\r\n    public makeGeometryUnique(): Mesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n\r\n        if (this._geometry.meshes.length === 1) {\r\n            return this;\r\n        }\r\n\r\n        const oldGeometry = this._geometry;\r\n        const geometry = this._geometry.copy(Geometry.RandomId());\r\n        oldGeometry.releaseForMesh(this, true);\r\n        geometry.applyToMesh(this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the index buffer of this mesh.\r\n     * @param indexBuffer Defines the index buffer to use for this mesh\r\n     * @param totalVertices Defines the total number of vertices used by the buffer\r\n     * @param totalIndices Defines the total number of indices in the index buffer\r\n     * @param is32Bits Defines if the indices are 32 bits. If null (default), the value is guessed from the number of vertices\r\n     */\r\n    public setIndexBuffer(indexBuffer: DataBuffer, totalVertices: number, totalIndices: number, is32Bits: Nullable<boolean> = null): void {\r\n        let geometry = this._geometry;\r\n        if (!geometry) {\r\n            geometry = new Geometry(Geometry.RandomId(), this.getScene(), undefined, undefined, this);\r\n        }\r\n        geometry.setIndexBuffer(indexBuffer, totalVertices, totalIndices, is32Bits);\r\n    }\r\n\r\n    /**\r\n     * Set the index buffer of this mesh\r\n     * @param indices defines the source data\r\n     * @param totalVertices defines the total number of vertices referenced by this index data (can be null)\r\n     * @param updatable defines if the updated index buffer must be flagged as updatable (default is false)\r\n     * @param dontForceSubMeshRecreation defines a boolean indicating that we don't want to force the recreation of sub-meshes if we don't have to (false by default)\r\n     * @returns the current mesh\r\n     */\r\n    public override setIndices(indices: IndicesArray, totalVertices: Nullable<number> = null, updatable: boolean = false, dontForceSubMeshRecreation = false): AbstractMesh {\r\n        if (!this._geometry) {\r\n            const vertexData = new VertexData();\r\n            vertexData.indices = indices;\r\n\r\n            const scene = this.getScene();\r\n\r\n            new Geometry(Geometry.RandomId(), scene, vertexData, updatable, this, totalVertices);\r\n        } else {\r\n            this._geometry.setIndices(indices, totalVertices, updatable, dontForceSubMeshRecreation);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update the current index buffer\r\n     * @param indices defines the source data\r\n     * @param offset defines the offset in the index buffer where to store the new data (can be null)\r\n     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)\r\n     * @returns the current mesh\r\n     */\r\n    public override updateIndices(indices: IndicesArray, offset?: number, gpuMemoryOnly = false): AbstractMesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n\r\n        this._geometry.updateIndices(indices, offset, gpuMemoryOnly);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Invert the geometry to move from a right handed system to a left handed one.\r\n     * @returns the current mesh\r\n     */\r\n    public toLeftHanded(): Mesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n        this._geometry.toLeftHanded();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bind(subMesh: SubMesh, effect: Effect, fillMode: number, allowInstancedRendering = true): Mesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n\r\n        const engine = this.getScene().getEngine();\r\n\r\n        // Wireframe\r\n        let indexToBind;\r\n        if (this._unIndexed) {\r\n            switch (this._getRenderingFillMode(fillMode)) {\r\n                case Material.WireFrameFillMode:\r\n                    indexToBind = subMesh._getLinesIndexBuffer(<IndicesArray>this.getIndices(), engine);\r\n                    break;\r\n                default:\r\n                    indexToBind = null;\r\n                    break;\r\n            }\r\n        } else {\r\n            switch (this._getRenderingFillMode(fillMode)) {\r\n                case Material.PointFillMode:\r\n                    indexToBind = null;\r\n                    break;\r\n                case Material.WireFrameFillMode:\r\n                    indexToBind = subMesh._getLinesIndexBuffer(<IndicesArray>this.getIndices(), engine);\r\n                    break;\r\n                default:\r\n                case Material.TriangleFillMode:\r\n                    indexToBind = this._geometry.getIndexBuffer();\r\n                    break;\r\n            }\r\n        }\r\n\r\n        return this._bindDirect(effect, indexToBind, allowInstancedRendering);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindDirect(effect: Effect, indexToBind: Nullable<DataBuffer>, allowInstancedRendering = true): Mesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n\r\n        // Morph targets\r\n        if (this.morphTargetManager && this.morphTargetManager.isUsingTextureForTargets) {\r\n            this.morphTargetManager._bind(effect);\r\n        }\r\n\r\n        // VBOs\r\n        if (!allowInstancedRendering || !this._userInstancedBuffersStorage || this.hasThinInstances) {\r\n            this._geometry._bind(effect, indexToBind);\r\n        } else {\r\n            if (\r\n                !this._instanceDataStorage.useMonoDataStorageRenderPass &&\r\n                this._userInstancedBuffersStorage.renderPasses &&\r\n                this._userInstancedBuffersStorage.renderPasses[this._instanceDataStorage.engine.currentRenderPassId]\r\n            ) {\r\n                const vertexBuffers = this._userInstancedBuffersStorage.renderPasses[this._instanceDataStorage.engine.currentRenderPassId];\r\n                for (const kind in vertexBuffers) {\r\n                    this._userInstancedBuffersStorage.vertexBuffers[kind] = vertexBuffers[kind];\r\n                }\r\n            }\r\n            this._geometry._bind(effect, indexToBind, this._userInstancedBuffersStorage.vertexBuffers, this._userInstancedBuffersStorage.vertexArrayObjects);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _draw(subMesh: SubMesh, fillMode: number, instancesCount?: number): Mesh {\r\n        if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {\r\n            return this;\r\n        }\r\n\r\n        if (this._internalMeshDataInfo._onBeforeDrawObservable) {\r\n            this._internalMeshDataInfo._onBeforeDrawObservable.notifyObservers(this);\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n        const currentMaterialContext = engine._currentMaterialContext;\r\n        const useVertexPulling = currentMaterialContext && currentMaterialContext.useVertexPulling;\r\n\r\n        if ((this._unIndexed && fillMode !== Material.WireFrameFillMode) || fillMode == Material.PointFillMode) {\r\n            // or triangles as points\r\n            engine.drawArraysType(fillMode, subMesh.verticesStart, subMesh.verticesCount, this.forcedInstanceCount || instancesCount);\r\n        } else if (fillMode == Material.WireFrameFillMode) {\r\n            // Triangles as wireframe\r\n            engine.drawElementsType(fillMode, 0, subMesh._linesIndexCount, this.forcedInstanceCount || instancesCount);\r\n        } else if (useVertexPulling) {\r\n            // We're rendering the number of indices in the index buffer but the vertex shader is handling the data itself.\r\n            engine.drawArraysType(fillMode, subMesh.indexStart, subMesh.indexCount, this.forcedInstanceCount || instancesCount);\r\n        } else {\r\n            engine.drawElementsType(fillMode, subMesh.indexStart, subMesh.indexCount, this.forcedInstanceCount || instancesCount);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Registers for this mesh a javascript function called just before the rendering process\r\n     * @param func defines the function to call before rendering this mesh\r\n     * @returns the current mesh\r\n     */\r\n    public registerBeforeRender(func: (mesh: AbstractMesh) => void): Mesh {\r\n        this.onBeforeRenderObservable.add(func);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disposes a previously registered javascript function called before the rendering\r\n     * @param func defines the function to remove\r\n     * @returns the current mesh\r\n     */\r\n    public unregisterBeforeRender(func: (mesh: AbstractMesh) => void): Mesh {\r\n        this.onBeforeRenderObservable.removeCallback(func);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Registers for this mesh a javascript function called just after the rendering is complete\r\n     * @param func defines the function to call after rendering this mesh\r\n     * @returns the current mesh\r\n     */\r\n    public registerAfterRender(func: (mesh: AbstractMesh) => void): Mesh {\r\n        this.onAfterRenderObservable.add(func);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disposes a previously registered javascript function called after the rendering.\r\n     * @param func defines the function to remove\r\n     * @returns the current mesh\r\n     */\r\n    public unregisterAfterRender(func: (mesh: AbstractMesh) => void): Mesh {\r\n        this.onAfterRenderObservable.removeCallback(func);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getInstancesRenderList(subMeshId: number, isReplacementMode: boolean = false): _InstancesBatch {\r\n        const instanceDataStorage = this._instanceDataStorage.useMonoDataStorageRenderPass ? this._instanceDataStorage.dataStorageRenderPass : this._getInstanceDataStorage();\r\n        if (this._instanceDataStorage.isFrozen) {\r\n            if (isReplacementMode) {\r\n                instanceDataStorage.batchCacheReplacementModeInFrozenMode.hardwareInstancedRendering[subMeshId] = false;\r\n                instanceDataStorage.batchCacheReplacementModeInFrozenMode.renderSelf[subMeshId] = true;\r\n                return instanceDataStorage.batchCacheReplacementModeInFrozenMode;\r\n            }\r\n            if (instanceDataStorage.previousBatch) {\r\n                return instanceDataStorage.previousBatch;\r\n            }\r\n        }\r\n        const scene = this.getScene();\r\n        const isInIntermediateRendering = scene._isInIntermediateRendering();\r\n        const onlyForInstances = isInIntermediateRendering\r\n            ? this._internalAbstractMeshDataInfo._onlyForInstancesIntermediate\r\n            : this._internalAbstractMeshDataInfo._onlyForInstances;\r\n        const batchCache = instanceDataStorage.batchCache;\r\n        batchCache.mustReturn = false;\r\n        batchCache.renderSelf[subMeshId] = isReplacementMode || (!onlyForInstances && this.isEnabled() && this.isVisible);\r\n        batchCache.visibleInstances[subMeshId] = null;\r\n\r\n        if (instanceDataStorage.visibleInstances && !isReplacementMode) {\r\n            const visibleInstances = instanceDataStorage.visibleInstances;\r\n            const currentRenderId = scene.getRenderId();\r\n            const defaultRenderId = isInIntermediateRendering ? visibleInstances.intermediateDefaultRenderId : visibleInstances.defaultRenderId;\r\n            batchCache.visibleInstances[subMeshId] = visibleInstances[currentRenderId];\r\n\r\n            if (!batchCache.visibleInstances[subMeshId] && defaultRenderId) {\r\n                batchCache.visibleInstances[subMeshId] = visibleInstances[defaultRenderId];\r\n            }\r\n        }\r\n        batchCache.hardwareInstancedRendering[subMeshId] =\r\n            !isReplacementMode &&\r\n            this._instanceDataStorage.hardwareInstancedRendering &&\r\n            batchCache.visibleInstances[subMeshId] !== null &&\r\n            batchCache.visibleInstances[subMeshId] !== undefined;\r\n        instanceDataStorage.previousBatch = batchCache;\r\n\r\n        return batchCache;\r\n    }\r\n\r\n    /**\r\n     * This method will also draw the instances if fillMode and effect are passed\r\n     * @internal\r\n     */\r\n    public _updateInstancedBuffers(subMesh: SubMesh, batch: _InstancesBatch, currentInstancesBufferSize: number, engine: AbstractEngine, fillMode?: number, effect?: Effect) {\r\n        const visibleInstances = batch.visibleInstances[subMesh._id];\r\n        const visibleInstanceCount = visibleInstances ? visibleInstances.length : 0;\r\n\r\n        const instanceStorage = batch.parent;\r\n        const instanceDataStorage = this._instanceDataStorage;\r\n        let instancesBuffer = instanceStorage.instancesBuffer;\r\n        let instancesPreviousBuffer = instanceStorage.instancesPreviousBuffer;\r\n\r\n        let offset = 0;\r\n        let instancesCount = 0;\r\n\r\n        const renderSelf = batch.renderSelf[subMesh._id];\r\n        const floatingOriginOffset = this._scene.floatingOriginOffset;\r\n\r\n        const needUpdateBuffer =\r\n            !instancesBuffer ||\r\n            currentInstancesBufferSize !== instanceStorage.instancesBufferSize ||\r\n            (this._scene.needsPreviousWorldMatrices && !instanceStorage.instancesPreviousBuffer);\r\n\r\n        if (!this._instanceDataStorage.manualUpdate && (!instanceDataStorage.isFrozen || needUpdateBuffer)) {\r\n            const world = this.getWorldMatrix();\r\n            if (renderSelf) {\r\n                if (this._scene.needsPreviousWorldMatrices) {\r\n                    if (!instanceDataStorage.masterMeshPreviousWorldMatrix) {\r\n                        instanceDataStorage.masterMeshPreviousWorldMatrix = world.clone();\r\n                        instanceDataStorage.masterMeshPreviousWorldMatrix.copyToArray(instanceStorage.instancesPreviousData, offset);\r\n                    } else {\r\n                        instanceDataStorage.masterMeshPreviousWorldMatrix.copyToArray(instanceStorage.instancesPreviousData, offset);\r\n                        instanceDataStorage.masterMeshPreviousWorldMatrix.copyFrom(world);\r\n                    }\r\n                }\r\n                world.copyToArray(instanceStorage.instancesData, offset);\r\n\r\n                // Apply floatingOriginOffset to underlying data sent to buffer.\r\n                // Subtract from Float64 source to preserve precision at large coordinates.\r\n                const worldM = world.asArray();\r\n                instanceStorage.instancesData[offset + 12] = worldM[12] - floatingOriginOffset.x;\r\n                instanceStorage.instancesData[offset + 13] = worldM[13] - floatingOriginOffset.y;\r\n                instanceStorage.instancesData[offset + 14] = worldM[14] - floatingOriginOffset.z;\r\n\r\n                offset += 16;\r\n                instancesCount++;\r\n            }\r\n\r\n            if (visibleInstances) {\r\n                if (Mesh.INSTANCEDMESH_SORT_TRANSPARENT && this._scene.activeCamera && subMesh.getMaterial()?.needAlphaBlendingForMesh(subMesh.getRenderingMesh())) {\r\n                    const cameraPosition = this._scene.activeCamera.globalPosition;\r\n                    for (let instanceIndex = 0; instanceIndex < visibleInstances.length; instanceIndex++) {\r\n                        const instanceMesh = visibleInstances[instanceIndex];\r\n                        instanceMesh._distanceToCamera = Vector3.Distance(instanceMesh.getBoundingInfo().boundingSphere.centerWorld, cameraPosition);\r\n                    }\r\n                    visibleInstances.sort((m1, m2) => {\r\n                        return m1._distanceToCamera > m2._distanceToCamera ? -1 : m1._distanceToCamera < m2._distanceToCamera ? 1 : 0;\r\n                    });\r\n                }\r\n                for (let instanceIndex = 0; instanceIndex < visibleInstances.length; instanceIndex++) {\r\n                    const instance = visibleInstances[instanceIndex];\r\n                    const matrix = instance.getWorldMatrix();\r\n                    matrix.copyToArray(instanceStorage.instancesData, offset);\r\n\r\n                    if (this._scene.needsPreviousWorldMatrices) {\r\n                        if (!instance._previousWorldMatrix) {\r\n                            instance._previousWorldMatrix = matrix.clone();\r\n                            instance._previousWorldMatrix.copyToArray(instanceStorage.instancesPreviousData, offset);\r\n                        } else {\r\n                            instance._previousWorldMatrix.copyToArray(instanceStorage.instancesPreviousData, offset);\r\n                            instance._previousWorldMatrix.copyFrom(matrix);\r\n                        }\r\n                    }\r\n\r\n                    // Apply floatingOriginOffset to underlying data sent to buffer.\r\n                    // Subtract from Float64 source to preserve precision at large coordinates.\r\n                    const matrixM = matrix.asArray();\r\n                    instanceStorage.instancesData[offset + 12] = matrixM[12] - floatingOriginOffset.x;\r\n                    instanceStorage.instancesData[offset + 13] = matrixM[13] - floatingOriginOffset.y;\r\n                    instanceStorage.instancesData[offset + 14] = matrixM[14] - floatingOriginOffset.z;\r\n\r\n                    offset += 16;\r\n                    instancesCount++;\r\n                }\r\n            }\r\n        } else {\r\n            instancesCount = (renderSelf ? 1 : 0) + visibleInstanceCount;\r\n        }\r\n\r\n        if (needUpdateBuffer) {\r\n            if (instancesBuffer) {\r\n                instancesBuffer.dispose();\r\n            }\r\n\r\n            if (instancesPreviousBuffer) {\r\n                instancesPreviousBuffer.dispose();\r\n            }\r\n\r\n            instancesBuffer = new Buffer(engine, instanceStorage.instancesData, true, 16, false, true);\r\n            instanceStorage.instancesBuffer = instancesBuffer;\r\n            if (!this._userInstancedBuffersStorage) {\r\n                this._userInstancedBuffersStorage = {\r\n                    data: {},\r\n                    vertexBuffers: {},\r\n                    strides: {},\r\n                    sizes: {},\r\n                    vertexArrayObjects: this.getEngine().getCaps().vertexArrayObject ? {} : undefined,\r\n                };\r\n            }\r\n\r\n            let vertexAndArrayObjectBuffers;\r\n            if (!this._instanceDataStorage.useMonoDataStorageRenderPass) {\r\n                if (!this._userInstancedBuffersStorage.renderPasses) {\r\n                    this._userInstancedBuffersStorage.renderPasses = {};\r\n                }\r\n\r\n                const currentRenderPassId = this._instanceDataStorage.engine.currentRenderPassId;\r\n                vertexAndArrayObjectBuffers = this._userInstancedBuffersStorage.renderPasses[currentRenderPassId];\r\n                if (!vertexAndArrayObjectBuffers) {\r\n                    this._userInstancedBuffersStorage.renderPasses[currentRenderPassId] = vertexAndArrayObjectBuffers = {};\r\n                }\r\n            } else {\r\n                vertexAndArrayObjectBuffers = this._userInstancedBuffersStorage.vertexBuffers;\r\n            }\r\n\r\n            vertexAndArrayObjectBuffers[\"world0\"] = instancesBuffer.createVertexBuffer(\"world0\", 0, 4);\r\n            vertexAndArrayObjectBuffers[\"world1\"] = instancesBuffer.createVertexBuffer(\"world1\", 4, 4);\r\n            vertexAndArrayObjectBuffers[\"world2\"] = instancesBuffer.createVertexBuffer(\"world2\", 8, 4);\r\n            vertexAndArrayObjectBuffers[\"world3\"] = instancesBuffer.createVertexBuffer(\"world3\", 12, 4);\r\n\r\n            if (this._scene.needsPreviousWorldMatrices) {\r\n                instancesPreviousBuffer = new Buffer(engine, instanceStorage.instancesPreviousData, true, 16, false, true);\r\n                instanceStorage.instancesPreviousBuffer = instancesPreviousBuffer;\r\n\r\n                vertexAndArrayObjectBuffers[\"previousWorld0\"] = instancesPreviousBuffer.createVertexBuffer(\"previousWorld0\", 0, 4);\r\n                vertexAndArrayObjectBuffers[\"previousWorld1\"] = instancesPreviousBuffer.createVertexBuffer(\"previousWorld1\", 4, 4);\r\n                vertexAndArrayObjectBuffers[\"previousWorld2\"] = instancesPreviousBuffer.createVertexBuffer(\"previousWorld2\", 8, 4);\r\n                vertexAndArrayObjectBuffers[\"previousWorld3\"] = instancesPreviousBuffer.createVertexBuffer(\"previousWorld3\", 12, 4);\r\n            }\r\n            this._invalidateInstanceVertexArrayObject();\r\n        } else {\r\n            if (!this._instanceDataStorage.isFrozen || this._instanceDataStorage.forceMatrixUpdates) {\r\n                instancesBuffer!.updateDirectly(instanceStorage.instancesData, 0, instancesCount);\r\n                if (this._scene.needsPreviousWorldMatrices && (!this._instanceDataStorage.manualUpdate || this._instanceDataStorage.previousManualUpdate)) {\r\n                    instancesPreviousBuffer!.updateDirectly(instanceStorage.instancesPreviousData, 0, instancesCount);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._processInstancedBuffers(visibleInstances, renderSelf);\r\n\r\n        if (effect && fillMode !== undefined) {\r\n            // Stats\r\n            this.getScene()._activeIndices.addCount(subMesh.indexCount * instancesCount, false);\r\n\r\n            // Draw\r\n            if (engine._currentDrawContext) {\r\n                engine._currentDrawContext.useInstancing = true;\r\n            }\r\n            this._bind(subMesh, effect, fillMode);\r\n            this._draw(subMesh, fillMode, instancesCount);\r\n        }\r\n\r\n        // Write current matrices as previous matrices in case of manual update\r\n        // Default behaviour when previous matrices are not specified explicitly\r\n        // Will break if instances number/order changes\r\n        if (\r\n            this._scene.needsPreviousWorldMatrices &&\r\n            !needUpdateBuffer &&\r\n            this._instanceDataStorage.manualUpdate &&\r\n            (!this._instanceDataStorage.isFrozen || this._instanceDataStorage.forceMatrixUpdates) &&\r\n            !this._instanceDataStorage.previousManualUpdate\r\n        ) {\r\n            instancesPreviousBuffer!.updateDirectly(instanceStorage.instancesData, 0, instancesCount);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: AbstractEngine): Mesh {\r\n        const visibleInstances = batch.visibleInstances[subMesh._id];\r\n        const visibleInstanceCount = visibleInstances ? visibleInstances.length : 0;\r\n\r\n        const instanceStorage = batch.parent;\r\n        const currentInstancesBufferSize = instanceStorage.instancesBufferSize;\r\n        const matricesCount = visibleInstanceCount + 1;\r\n        const bufferSize = matricesCount * 16 * 4;\r\n\r\n        while (instanceStorage.instancesBufferSize < bufferSize) {\r\n            instanceStorage.instancesBufferSize *= 2;\r\n        }\r\n\r\n        if (!instanceStorage.instancesData || currentInstancesBufferSize != instanceStorage.instancesBufferSize) {\r\n            instanceStorage.instancesData = new Float32Array(instanceStorage.instancesBufferSize / 4);\r\n        }\r\n        if ((this._scene.needsPreviousWorldMatrices && !instanceStorage.instancesPreviousData) || currentInstancesBufferSize != instanceStorage.instancesBufferSize) {\r\n            instanceStorage.instancesPreviousData = new Float32Array(instanceStorage.instancesBufferSize / 4);\r\n        }\r\n\r\n        this._updateInstancedBuffers(subMesh, batch, currentInstancesBufferSize, engine, fillMode, effect);\r\n\r\n        engine.unbindInstanceAttributes();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _renderWithThinInstances(subMesh: SubMesh, fillMode: number, effect: Effect, engine: AbstractEngine) {\r\n        // Stats\r\n        const instancesCount = this._thinInstanceDataStorage?.instancesCount ?? 0;\r\n\r\n        this.getScene()._activeIndices.addCount(subMesh.indexCount * instancesCount, false);\r\n\r\n        // Draw\r\n        if (engine._currentDrawContext) {\r\n            engine._currentDrawContext.useInstancing = true;\r\n        }\r\n        this._bind(subMesh, effect, fillMode);\r\n        this._draw(subMesh, fillMode, instancesCount);\r\n\r\n        // Write current matrices as previous matrices\r\n        // Default behaviour when previous matrices are not specified explicitly\r\n        // Will break if instances number/order changes\r\n        if (this._scene.needsPreviousWorldMatrices && !this._thinInstanceDataStorage.previousMatrixData && this._thinInstanceDataStorage.matrixData) {\r\n            if (!this._thinInstanceDataStorage.previousMatrixBuffer) {\r\n                this._thinInstanceDataStorage.previousMatrixBuffer = this._thinInstanceCreateMatrixBuffer(\"previousWorld\", this._thinInstanceDataStorage.matrixData, false);\r\n            } else {\r\n                this._thinInstanceDataStorage.previousMatrixBuffer.updateDirectly(this._thinInstanceDataStorage.matrixData, 0, instancesCount);\r\n            }\r\n        }\r\n\r\n        engine.unbindInstanceAttributes();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _processInstancedBuffers(visibleInstances: Nullable<InstancedMesh[]>, renderSelf: boolean) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _processRendering(\r\n        renderingMesh: AbstractMesh,\r\n        subMesh: SubMesh,\r\n        effect: Effect,\r\n        fillMode: number,\r\n        batch: _InstancesBatch,\r\n        hardwareInstancedRendering: boolean,\r\n        onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void,\r\n        effectiveMaterial?: Material\r\n    ): Mesh {\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n        fillMode = this._getRenderingFillMode(fillMode);\r\n\r\n        if (hardwareInstancedRendering && subMesh.getRenderingMesh().hasThinInstances) {\r\n            this._renderWithThinInstances(subMesh, fillMode, effect, engine);\r\n            return this;\r\n        }\r\n\r\n        if (hardwareInstancedRendering) {\r\n            this._renderWithInstances(subMesh, fillMode, batch, effect, engine);\r\n        } else {\r\n            if (engine._currentDrawContext) {\r\n                engine._currentDrawContext.useInstancing = false;\r\n            }\r\n\r\n            let instanceCount = 0;\r\n            if (batch.renderSelf[subMesh._id]) {\r\n                // Draw\r\n                if (onBeforeDraw) {\r\n                    onBeforeDraw(false, renderingMesh.getWorldMatrix(), effectiveMaterial);\r\n                }\r\n                instanceCount++;\r\n\r\n                this._draw(subMesh, fillMode, this._instanceDataStorage.overridenInstanceCount);\r\n            }\r\n\r\n            const visibleInstancesForSubMesh = batch.visibleInstances[subMesh._id];\r\n\r\n            if (visibleInstancesForSubMesh) {\r\n                const visibleInstanceCount = visibleInstancesForSubMesh.length;\r\n                instanceCount += visibleInstanceCount;\r\n\r\n                // Stats\r\n                for (let instanceIndex = 0; instanceIndex < visibleInstanceCount; instanceIndex++) {\r\n                    const instance = visibleInstancesForSubMesh[instanceIndex];\r\n\r\n                    // World\r\n                    const world = instance.getWorldMatrix();\r\n                    if (onBeforeDraw) {\r\n                        onBeforeDraw(true, world, effectiveMaterial);\r\n                    }\r\n                    // Draw\r\n                    this._draw(subMesh, fillMode);\r\n                }\r\n            }\r\n\r\n            // Stats\r\n            scene._activeIndices.addCount(subMesh.indexCount * instanceCount, false);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    private _disposeInstanceDataStorageRenderPass(dataStorage?: _InstanceDataStorageRenderPass, dispose = false) {\r\n        if (dataStorage?.instancesBuffer) {\r\n            // Dispose instance buffer to be recreated in _renderWithInstances when rendered\r\n            if (dispose) {\r\n                dataStorage.instancesBuffer.dispose();\r\n            }\r\n            dataStorage.instancesBuffer = null;\r\n        }\r\n        if (dataStorage?.instancesPreviousBuffer) {\r\n            if (dispose) {\r\n                dataStorage.instancesPreviousBuffer.dispose();\r\n            }\r\n            dataStorage.instancesPreviousBuffer = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _rebuild(dispose = false): void {\r\n        for (const renderPassId in this._instanceDataStorage.renderPasses) {\r\n            const instanceDataStorage = this._instanceDataStorage.renderPasses[renderPassId];\r\n            this._disposeInstanceDataStorageRenderPass(instanceDataStorage, dispose);\r\n        }\r\n        this._disposeInstanceDataStorageRenderPass(this._instanceDataStorage.dataStorageRenderPass, dispose);\r\n        if (this._userInstancedBuffersStorage) {\r\n            for (const kind in this._userInstancedBuffersStorage.vertexBuffers) {\r\n                const buffer = this._userInstancedBuffersStorage.vertexBuffers[kind];\r\n                if (buffer) {\r\n                    // Dispose instance buffer to be recreated in _renderWithInstances when rendered\r\n                    if (dispose) {\r\n                        buffer.dispose();\r\n                    }\r\n                    this._userInstancedBuffersStorage.vertexBuffers[kind] = null;\r\n                }\r\n            }\r\n            if (this._userInstancedBuffersStorage.vertexArrayObjects) {\r\n                this._userInstancedBuffersStorage.vertexArrayObjects = {};\r\n            }\r\n        }\r\n        this._internalMeshDataInfo._effectiveMaterial = null;\r\n        super._rebuild(dispose);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _releaseRenderPassId(id: number): void {\r\n        const renderPassStorage = this._instanceDataStorage.renderPasses[id];\r\n        if (renderPassStorage) {\r\n            this._disposeInstanceDataStorageRenderPass(renderPassStorage, true);\r\n            delete this._instanceDataStorage.renderPasses[id];\r\n        }\r\n        if (this._userInstancedBuffersStorage?.renderPasses) {\r\n            const passVBOs = this._userInstancedBuffersStorage.renderPasses[id];\r\n            if (passVBOs) {\r\n                for (const kind in passVBOs) {\r\n                    passVBOs[kind]?.dispose();\r\n                }\r\n            }\r\n            delete this._userInstancedBuffersStorage.renderPasses[id];\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _freeze() {\r\n        if (!this.subMeshes) {\r\n            return;\r\n        }\r\n\r\n        // Prepare batches\r\n        for (let index = 0; index < this.subMeshes.length; index++) {\r\n            this._getInstancesRenderList(index);\r\n        }\r\n\r\n        this._internalMeshDataInfo._effectiveMaterial = null;\r\n        this._instanceDataStorage.isFrozen = true;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _unFreeze() {\r\n        this._instanceDataStorage.isFrozen = false;\r\n        for (const renderPassId in this._instanceDataStorage.renderPasses) {\r\n            const instanceDataStorage = this._instanceDataStorage.renderPasses[renderPassId];\r\n            instanceDataStorage.previousBatch = null;\r\n        }\r\n        if (this._instanceDataStorage.dataStorageRenderPass) {\r\n            this._instanceDataStorage.dataStorageRenderPass.previousBatch = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Triggers the draw call for the mesh (or a submesh), for a specific render pass id\r\n     * @param renderPassId defines the render pass id to use to draw the mesh / submesh. If not provided, use the current renderPassId of the engine.\r\n     * @param enableAlphaMode defines if alpha mode can be changed (default: false)\r\n     * @param effectiveMeshReplacement defines an optional mesh used to provide info for the rendering (default: undefined)\r\n     * @param subMesh defines the subMesh to render. If not provided, draw all mesh submeshes (default: undefined)\r\n     * @param checkFrustumCulling defines if frustum culling must be checked (default: true). If you know the mesh is in the frustum (or if you don't care!), you can pass false to optimize.\r\n     * @returns the current mesh\r\n     */\r\n    public renderWithRenderPassId(renderPassId?: number, enableAlphaMode?: boolean, effectiveMeshReplacement?: AbstractMesh, subMesh?: SubMesh, checkFrustumCulling = true) {\r\n        const engine = this._scene.getEngine();\r\n        const currentRenderPassId = engine.currentRenderPassId;\r\n\r\n        if (renderPassId !== undefined) {\r\n            engine.currentRenderPassId = renderPassId;\r\n        }\r\n\r\n        if (subMesh) {\r\n            if (!checkFrustumCulling || (checkFrustumCulling && subMesh.isInFrustum(this._scene._frustumPlanes))) {\r\n                this.render(subMesh, !!enableAlphaMode, effectiveMeshReplacement);\r\n            }\r\n        } else {\r\n            for (let s = 0; s < this.subMeshes.length; s++) {\r\n                const subMesh = this.subMeshes[s];\r\n                if (!checkFrustumCulling || (checkFrustumCulling && subMesh.isInFrustum(this._scene._frustumPlanes))) {\r\n                    this.render(subMesh, !!enableAlphaMode, effectiveMeshReplacement);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (renderPassId !== undefined) {\r\n            engine.currentRenderPassId = currentRenderPassId;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Render a complete mesh by going through all submeshes\r\n     * @returns the current mesh\r\n     * @see [simple test](https://playground.babylonjs.com/#5SPY1V#2)\r\n     * @see [perf test](https://playground.babylonjs.com/#5SPY1V#5)\r\n     */\r\n    public directRender(): Mesh {\r\n        if (!this.subMeshes) {\r\n            return this;\r\n        }\r\n\r\n        for (const submesh of this.subMeshes) {\r\n            this.render(submesh, false);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager\r\n     * @param subMesh defines the subMesh to render\r\n     * @param enableAlphaMode defines if alpha mode can be changed\r\n     * @param effectiveMeshReplacement defines an optional mesh used to provide info for the rendering\r\n     * @returns the current mesh\r\n     */\r\n    public render(subMesh: SubMesh, enableAlphaMode: boolean, effectiveMeshReplacement?: AbstractMesh): Mesh {\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        if (this._internalAbstractMeshDataInfo._isActiveIntermediate) {\r\n            this._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n        } else {\r\n            this._internalAbstractMeshDataInfo._isActive = false;\r\n        }\r\n\r\n        const numActiveCameras = scene.activeCameras?.length ?? 0;\r\n        const canCheckOcclusionQuery = (numActiveCameras > 1 && scene.activeCamera === scene.activeCameras![0]) || numActiveCameras <= 1;\r\n        const occlusionCheckOnly =\r\n            this._occlusionDataStorage &&\r\n            this._occlusionDataStorage.occlusionForRenderPassId !== -1 &&\r\n            this._occlusionDataStorage.occlusionForRenderPassId !== engine.currentRenderPassId;\r\n\r\n        if (canCheckOcclusionQuery && this._checkOcclusionQuery(occlusionCheckOnly) && !this._occlusionDataStorage.forceRenderingWhenOccluded) {\r\n            return this;\r\n        }\r\n\r\n        // Managing instances\r\n        const batch = this._getInstancesRenderList(subMesh._id, !!effectiveMeshReplacement);\r\n\r\n        if (batch.mustReturn) {\r\n            return this;\r\n        }\r\n\r\n        // Checking geometry state\r\n        if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {\r\n            return this;\r\n        }\r\n\r\n        let oldCameraMaxZ = 0;\r\n        let oldCamera: Nullable<Camera> = null;\r\n        if (this.ignoreCameraMaxZ && scene.activeCamera && !scene._isInIntermediateRendering()) {\r\n            oldCameraMaxZ = scene.activeCamera.maxZ;\r\n            oldCamera = scene.activeCamera;\r\n            scene.activeCamera.maxZ = 0;\r\n            scene.updateTransformMatrix(true);\r\n        }\r\n\r\n        if (this._internalMeshDataInfo._onBeforeRenderObservable) {\r\n            this._internalMeshDataInfo._onBeforeRenderObservable.notifyObservers(this);\r\n        }\r\n\r\n        const renderingMesh = subMesh.getRenderingMesh();\r\n        const hardwareInstancedRendering =\r\n            batch.hardwareInstancedRendering[subMesh._id] ||\r\n            renderingMesh.hasThinInstances ||\r\n            (!!this._userInstancedBuffersStorage && !subMesh.getMesh()._internalAbstractMeshDataInfo._actAsRegularMesh);\r\n        const instanceDataStorage = this._instanceDataStorage;\r\n\r\n        const material = subMesh.getMaterial();\r\n        if (!material) {\r\n            if (oldCamera) {\r\n                oldCamera.maxZ = oldCameraMaxZ;\r\n                scene.updateTransformMatrix(true);\r\n            }\r\n            return this;\r\n        }\r\n\r\n        // Material\r\n        if (!instanceDataStorage.isFrozen || !this._internalMeshDataInfo._effectiveMaterial || this._internalMeshDataInfo._effectiveMaterial !== material) {\r\n            if (material._storeEffectOnSubMeshes) {\r\n                if (!material.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {\r\n                    if (oldCamera) {\r\n                        oldCamera.maxZ = oldCameraMaxZ;\r\n                        scene.updateTransformMatrix(true);\r\n                    }\r\n                    return this;\r\n                }\r\n            } else if (!material.isReady(this, hardwareInstancedRendering)) {\r\n                if (oldCamera) {\r\n                    oldCamera.maxZ = oldCameraMaxZ;\r\n                    scene.updateTransformMatrix(true);\r\n                }\r\n                return this;\r\n            }\r\n\r\n            this._internalMeshDataInfo._effectiveMaterial = material;\r\n        } else if (\r\n            (material._storeEffectOnSubMeshes && !subMesh._drawWrapper?._wasPreviouslyReady) ||\r\n            (!material._storeEffectOnSubMeshes && !material._getDrawWrapper()._wasPreviouslyReady)\r\n        ) {\r\n            if (oldCamera) {\r\n                oldCamera.maxZ = oldCameraMaxZ;\r\n                scene.updateTransformMatrix(true);\r\n            }\r\n            return this;\r\n        }\r\n\r\n        // Alpha mode\r\n        if (enableAlphaMode) {\r\n            const effectiveMaterial = this._internalMeshDataInfo._effectiveMaterial;\r\n            if (effectiveMaterial.alphaModes.length === 1) {\r\n                engine.setAlphaMode(effectiveMaterial.alphaMode);\r\n            } else {\r\n                for (let i = 0; i < effectiveMaterial.alphaModes.length; i++) {\r\n                    const alphaMode = effectiveMaterial.alphaModes[i];\r\n                    engine.setAlphaMode(alphaMode !== undefined ? alphaMode : Constants.ALPHA_COMBINE, false, i);\r\n                }\r\n            }\r\n        }\r\n\r\n        let drawWrapper: Nullable<DrawWrapper>;\r\n        if (this._internalMeshDataInfo._effectiveMaterial._storeEffectOnSubMeshes) {\r\n            drawWrapper = subMesh._drawWrapper;\r\n        } else {\r\n            drawWrapper = this._internalMeshDataInfo._effectiveMaterial._getDrawWrapper();\r\n        }\r\n\r\n        const effect = drawWrapper?.effect ?? null;\r\n\r\n        for (const step of scene._beforeRenderingMeshStage) {\r\n            step.action(this, subMesh, batch, effect);\r\n        }\r\n\r\n        if (!drawWrapper || !effect) {\r\n            if (oldCamera) {\r\n                oldCamera.maxZ = oldCameraMaxZ;\r\n                scene.updateTransformMatrix(true);\r\n            }\r\n            return this;\r\n        }\r\n\r\n        const effectiveMesh = effectiveMeshReplacement || this;\r\n\r\n        let sideOrientation: Nullable<number>;\r\n\r\n        if (\r\n            !instanceDataStorage.isFrozen &&\r\n            (this._internalMeshDataInfo._effectiveMaterial.backFaceCulling ||\r\n                this._internalMeshDataInfo._effectiveMaterial.sideOrientation !== null ||\r\n                (this._internalMeshDataInfo._effectiveMaterial as any)._twoSidedLighting)\r\n        ) {\r\n            // Note: if two sided lighting is enabled, we need to ensure that the normal will point in the right direction even if the determinant of the world matrix is negative\r\n            const mainDeterminant = effectiveMesh._getWorldMatrixDeterminant();\r\n            sideOrientation = this._internalMeshDataInfo._effectiveMaterial._getEffectiveOrientation(this);\r\n\r\n            if (mainDeterminant < 0) {\r\n                sideOrientation = sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;\r\n            }\r\n            this._internalMeshDataInfo._effectiveSideOrientation = sideOrientation!;\r\n        }\r\n\r\n        const reverse = this._internalMeshDataInfo._effectiveMaterial._preBind(drawWrapper, this._internalMeshDataInfo._effectiveSideOrientation);\r\n\r\n        if (this._internalMeshDataInfo._effectiveMaterial.forceDepthWrite) {\r\n            engine.setDepthWrite(true);\r\n        }\r\n\r\n        // Bind\r\n        const effectiveMaterial = this._internalMeshDataInfo._effectiveMaterial;\r\n        const fillMode = effectiveMaterial.fillMode;\r\n\r\n        if (this._internalMeshDataInfo._onBeforeBindObservable) {\r\n            this._internalMeshDataInfo._onBeforeBindObservable.notifyObservers(this);\r\n        }\r\n\r\n        if (!hardwareInstancedRendering) {\r\n            // Binding will be done later because we need to add more info to the VB\r\n            this._bind(subMesh, effect, fillMode, false);\r\n        }\r\n\r\n        const world = effectiveMesh.getWorldMatrix();\r\n        if (effectiveMaterial._storeEffectOnSubMeshes) {\r\n            effectiveMaterial.bindForSubMesh(world, this, subMesh);\r\n        } else {\r\n            effectiveMaterial.bind(world, this);\r\n        }\r\n\r\n        try {\r\n            if (MaterialHelperGeometryRendering._BindAttachmentsForEffect(engine, effect)) {\r\n                if (!effectiveMaterial.backFaceCulling && effectiveMaterial.separateCullingPass) {\r\n                    engine.setState(true, effectiveMaterial.zOffset, false, !reverse, effectiveMaterial.cullBackFaces, effectiveMaterial.stencil, effectiveMaterial.zOffsetUnits);\r\n                    this._processRendering(this, subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._internalMeshDataInfo._effectiveMaterial);\r\n                    engine.setState(true, effectiveMaterial.zOffset, false, reverse, effectiveMaterial.cullBackFaces, effectiveMaterial.stencil, effectiveMaterial.zOffsetUnits);\r\n\r\n                    if (this._internalMeshDataInfo._onBetweenPassObservable) {\r\n                        this._internalMeshDataInfo._onBetweenPassObservable.notifyObservers(subMesh);\r\n                    }\r\n                }\r\n\r\n                // Draw\r\n                this._processRendering(this, subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._internalMeshDataInfo._effectiveMaterial);\r\n            }\r\n        } finally {\r\n            MaterialHelperGeometryRendering._RestoreAttachments(engine);\r\n        }\r\n\r\n        // Unbind\r\n        this._internalMeshDataInfo._effectiveMaterial.unbind();\r\n\r\n        for (const step of scene._afterRenderingMeshStage) {\r\n            step.action(this, subMesh, batch, effect);\r\n        }\r\n\r\n        if (this._internalMeshDataInfo._onAfterRenderObservable) {\r\n            this._internalMeshDataInfo._onAfterRenderObservable.notifyObservers(this);\r\n        }\r\n\r\n        if (oldCamera) {\r\n            oldCamera.maxZ = oldCameraMaxZ;\r\n            scene.updateTransformMatrix(true);\r\n        }\r\n\r\n        if (scene.performancePriority === ScenePerformancePriority.Aggressive && !instanceDataStorage.isFrozen) {\r\n            this._freeze();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    private _onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void;\r\n\r\n    /**\r\n     *   Renormalize the mesh and patch it up if there are no weights\r\n     *   Similar to normalization by adding the weights compute the reciprocal and multiply all elements, this wil ensure that everything adds to 1.\r\n     *   However in the case of zero weights then we set just a single influence to 1.\r\n     *   We check in the function for extra's present and if so we use the normalizeSkinWeightsWithExtras rather than the FourWeights version.\r\n     */\r\n    public cleanMatrixWeights(): void {\r\n        if (this.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind)) {\r\n            if (this.isVerticesDataPresent(VertexBuffer.MatricesWeightsExtraKind)) {\r\n                this._normalizeSkinWeightsAndExtra();\r\n            } else {\r\n                this._normalizeSkinFourWeights();\r\n            }\r\n        }\r\n    }\r\n\r\n    // faster 4 weight version.\r\n    private _normalizeSkinFourWeights(): void {\r\n        const matricesWeights = <FloatArray>this.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n        const numWeights = matricesWeights.length;\r\n\r\n        for (let a = 0; a < numWeights; a += 4) {\r\n            // accumulate weights\r\n            const t = matricesWeights[a] + matricesWeights[a + 1] + matricesWeights[a + 2] + matricesWeights[a + 3];\r\n            // check for invalid weight and just set it to 1.\r\n            if (t === 0) {\r\n                matricesWeights[a] = 1;\r\n            } else {\r\n                // renormalize so everything adds to 1 use reciprocal\r\n                const recip = 1 / t;\r\n                matricesWeights[a] *= recip;\r\n                matricesWeights[a + 1] *= recip;\r\n                matricesWeights[a + 2] *= recip;\r\n                matricesWeights[a + 3] *= recip;\r\n            }\r\n        }\r\n        this.setVerticesData(VertexBuffer.MatricesWeightsKind, matricesWeights);\r\n    }\r\n    // handle special case of extra verts.  (in theory gltf can handle 12 influences)\r\n    private _normalizeSkinWeightsAndExtra(): void {\r\n        const matricesWeightsExtra = <FloatArray>this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind);\r\n        const matricesWeights = <FloatArray>this.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n        const numWeights = matricesWeights.length;\r\n\r\n        for (let a = 0; a < numWeights; a += 4) {\r\n            // accumulate weights\r\n            let t = matricesWeights[a] + matricesWeights[a + 1] + matricesWeights[a + 2] + matricesWeights[a + 3];\r\n            t += matricesWeightsExtra[a] + matricesWeightsExtra[a + 1] + matricesWeightsExtra[a + 2] + matricesWeightsExtra[a + 3];\r\n            // check for invalid weight and just set it to 1.\r\n            if (t === 0) {\r\n                matricesWeights[a] = 1;\r\n            } else {\r\n                // renormalize so everything adds to 1 use reciprocal\r\n                const recip = 1 / t;\r\n                matricesWeights[a] *= recip;\r\n                matricesWeights[a + 1] *= recip;\r\n                matricesWeights[a + 2] *= recip;\r\n                matricesWeights[a + 3] *= recip;\r\n                // same goes for extras\r\n                matricesWeightsExtra[a] *= recip;\r\n                matricesWeightsExtra[a + 1] *= recip;\r\n                matricesWeightsExtra[a + 2] *= recip;\r\n                matricesWeightsExtra[a + 3] *= recip;\r\n            }\r\n        }\r\n        this.setVerticesData(VertexBuffer.MatricesWeightsKind, matricesWeights);\r\n        this.setVerticesData(VertexBuffer.MatricesWeightsKind, matricesWeightsExtra);\r\n    }\r\n\r\n    /**\r\n     * ValidateSkinning is used to determine that a mesh has valid skinning data along with skin metrics, if missing weights,\r\n     * or not normalized it is returned as invalid mesh the string can be used for console logs, or on screen messages to let\r\n     * the user know there was an issue with importing the mesh\r\n     * @returns a validation object with skinned, valid and report string\r\n     */\r\n    public validateSkinning(): { skinned: boolean; valid: boolean; report: string } {\r\n        const matricesWeightsExtra = <FloatArray>this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind);\r\n        const matricesWeights = <FloatArray>this.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n        if (matricesWeights === null || this.skeleton == null) {\r\n            return { skinned: false, valid: true, report: \"not skinned\" };\r\n        }\r\n\r\n        const numWeights = matricesWeights.length;\r\n        let numberNotSorted: number = 0;\r\n        let missingWeights: number = 0;\r\n        let maxUsedWeights: number = 0;\r\n        let numberNotNormalized: number = 0;\r\n        const numInfluences: number = matricesWeightsExtra === null ? 4 : 8;\r\n        const usedWeightCounts: number[] = [];\r\n        for (let a = 0; a <= numInfluences; a++) {\r\n            usedWeightCounts[a] = 0;\r\n        }\r\n        const toleranceEpsilon: number = 0.001;\r\n\r\n        for (let a = 0; a < numWeights; a += 4) {\r\n            let lastWeight: number = matricesWeights[a];\r\n            let t = lastWeight;\r\n            let usedWeights: number = t === 0 ? 0 : 1;\r\n\r\n            for (let b = 1; b < numInfluences; b++) {\r\n                const d = b < 4 ? matricesWeights[a + b] : matricesWeightsExtra[a + b - 4];\r\n                if (d > lastWeight) {\r\n                    numberNotSorted++;\r\n                }\r\n                if (d !== 0) {\r\n                    usedWeights++;\r\n                }\r\n                t += d;\r\n                lastWeight = d;\r\n            }\r\n            // count the buffer weights usage\r\n            usedWeightCounts[usedWeights]++;\r\n\r\n            // max influences\r\n            if (usedWeights > maxUsedWeights) {\r\n                maxUsedWeights = usedWeights;\r\n            }\r\n\r\n            // check for invalid weight and just set it to 1.\r\n            if (t === 0) {\r\n                missingWeights++;\r\n            } else {\r\n                // renormalize so everything adds to 1 use reciprocal\r\n                const recip = 1 / t;\r\n                let tolerance = 0;\r\n                for (let b = 0; b < numInfluences; b++) {\r\n                    if (b < 4) {\r\n                        tolerance += Math.abs(matricesWeights[a + b] - matricesWeights[a + b] * recip);\r\n                    } else {\r\n                        tolerance += Math.abs(matricesWeightsExtra[a + b - 4] - matricesWeightsExtra[a + b - 4] * recip);\r\n                    }\r\n                }\r\n                // arbitrary epsilon value for dictating not normalized\r\n                if (tolerance > toleranceEpsilon) {\r\n                    numberNotNormalized++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // validate bone indices are in range of the skeleton\r\n        const numBones: number = this.skeleton.bones.length;\r\n        const matricesIndices = <FloatArray>this.getVerticesData(VertexBuffer.MatricesIndicesKind);\r\n        const matricesIndicesExtra = <FloatArray>this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind);\r\n        let numBadBoneIndices: number = 0;\r\n        for (let a = 0; a < numWeights; a += 4) {\r\n            for (let b = 0; b < numInfluences; b++) {\r\n                const index = b < 4 ? matricesIndices[a + b] : matricesIndicesExtra[a + b - 4];\r\n                if (index >= numBones || index < 0) {\r\n                    numBadBoneIndices++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // log mesh stats\r\n        const output =\r\n            \"Number of Weights = \" +\r\n            numWeights / 4 +\r\n            \"\\nMaximum influences = \" +\r\n            maxUsedWeights +\r\n            \"\\nMissing Weights = \" +\r\n            missingWeights +\r\n            \"\\nNot Sorted = \" +\r\n            numberNotSorted +\r\n            \"\\nNot Normalized = \" +\r\n            numberNotNormalized +\r\n            \"\\nWeightCounts = [\" +\r\n            usedWeightCounts +\r\n            \"]\" +\r\n            \"\\nNumber of bones = \" +\r\n            numBones +\r\n            \"\\nBad Bone Indices = \" +\r\n            numBadBoneIndices;\r\n\r\n        return { skinned: true, valid: missingWeights === 0 && numberNotNormalized === 0 && numBadBoneIndices === 0, report: output };\r\n    }\r\n\r\n    /** @internal */\r\n    public _checkDelayState(): Mesh {\r\n        const scene = this.getScene();\r\n        if (this._geometry) {\r\n            this._geometry.load(scene);\r\n        } else if (this.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            this.delayLoadState = Constants.DELAYLOADSTATE_LOADING;\r\n\r\n            this._queueLoad(scene);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    private _queueLoad(scene: Scene): Mesh {\r\n        scene.addPendingData(this);\r\n\r\n        const getBinaryData = this.delayLoadingFile.indexOf(\".babylonbinarymeshdata\") !== -1;\r\n\r\n        void (async () => {\r\n            try {\r\n                const data = await scene._loadDelayedFileAsync(this.delayLoadingFile, getBinaryData, true);\r\n                if (data instanceof ArrayBuffer) {\r\n                    this._delayLoadingFunction(data, this);\r\n                } else {\r\n                    this._delayLoadingFunction(JSON.parse(data), this);\r\n                }\r\n\r\n                for (const instance of this.instances) {\r\n                    instance.refreshBoundingInfo();\r\n                    instance._syncSubMeshes();\r\n                }\r\n\r\n                this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\r\n                scene.removePendingData(this);\r\n            } catch (error) {\r\n                // Remove the pending data so the scene can still become ready.\r\n                // The state is intentionally left as LOADING so a persistently failing file is not re-fetched every frame.\r\n                scene.removePendingData(this);\r\n                // Don't log when the scene is being disposed: in-flight requests are aborted as part of normal teardown.\r\n                if (!scene.isDisposed) {\r\n                    Logger.Error(`Unable to delay load geometry data for mesh \"${this.name}\" from \"${this.delayLoadingFile}\": ${error}`);\r\n                }\r\n            }\r\n        })();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns `true` if the mesh is within the frustum defined by the passed array of planes.\r\n     * A mesh is in the frustum if its bounding box intersects the frustum\r\n     * @param frustumPlanes defines the frustum to test\r\n     * @returns true if the mesh is in the frustum planes\r\n     */\r\n    public override isInFrustum(frustumPlanes: Plane[]): boolean {\r\n        if (this.delayLoadState === Constants.DELAYLOADSTATE_LOADING) {\r\n            return false;\r\n        }\r\n\r\n        if (!super.isInFrustum(frustumPlanes)) {\r\n            return false;\r\n        }\r\n\r\n        this._checkDelayState();\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh material by the material or multiMaterial `id` property\r\n     * @param id is a string identifying the material or the multiMaterial\r\n     * @returns the current mesh\r\n     */\r\n    public setMaterialById(id: string): Mesh {\r\n        const materials = this.getScene().materials;\r\n        let index: number;\r\n        for (index = materials.length - 1; index > -1; index--) {\r\n            if (materials[index].id === id) {\r\n                this.material = materials[index];\r\n                return this;\r\n            }\r\n        }\r\n\r\n        // Multi\r\n        const multiMaterials = this.getScene().multiMaterials;\r\n        for (index = multiMaterials.length - 1; index > -1; index--) {\r\n            if (multiMaterials[index].id === id) {\r\n                this.material = multiMaterials[index];\r\n                return this;\r\n            }\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Returns as a new array populated with the mesh material and/or skeleton, if any.\r\n     * @returns an array of IAnimatable\r\n     */\r\n    public getAnimatables(): IAnimatable[] {\r\n        const results: IAnimatable[] = [];\r\n\r\n        if (this.material) {\r\n            results.push(this.material);\r\n        }\r\n\r\n        if (this.skeleton) {\r\n            results.push(this.skeleton);\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Modifies the mesh geometry according to the passed transformation matrix.\r\n     * This method returns nothing, but it really modifies the mesh even if it's originally not set as updatable.\r\n     * The mesh normals are modified using the same transformation.\r\n     * Note that, under the hood, this method sets a new VertexBuffer each call.\r\n     * @param transform defines the transform matrix to use\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/bakingTransforms\r\n     * @returns the current mesh\r\n     */\r\n    public bakeTransformIntoVertices(transform: DeepImmutable<Matrix>): Mesh {\r\n        // Position\r\n        if (!this.isVerticesDataPresent(VertexBuffer.PositionKind)) {\r\n            return this;\r\n        }\r\n\r\n        const submeshes = this.subMeshes.splice(0);\r\n\r\n        this._resetPointsArrayCache();\r\n\r\n        let data = <FloatArray>this.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        const temp = Vector3.Zero();\r\n        let index: number;\r\n        for (index = 0; index < data.length; index += 3) {\r\n            Vector3.TransformCoordinatesFromFloatsToRef(data[index], data[index + 1], data[index + 2], transform, temp).toArray(data, index);\r\n        }\r\n\r\n        this.setVerticesData(VertexBuffer.PositionKind, data, (<VertexBuffer>this.getVertexBuffer(VertexBuffer.PositionKind)).isUpdatable());\r\n\r\n        // Normals\r\n        if (this.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            data = <FloatArray>this.getVerticesData(VertexBuffer.NormalKind);\r\n            for (index = 0; index < data.length; index += 3) {\r\n                Vector3.TransformNormalFromFloatsToRef(data[index], data[index + 1], data[index + 2], transform, temp)\r\n                    .normalize()\r\n                    .toArray(data, index);\r\n            }\r\n            this.setVerticesData(VertexBuffer.NormalKind, data, (<VertexBuffer>this.getVertexBuffer(VertexBuffer.NormalKind)).isUpdatable());\r\n        }\r\n\r\n        // Tangents\r\n        if (this.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n            data = <FloatArray>this.getVerticesData(VertexBuffer.TangentKind);\r\n            for (index = 0; index < data.length; index += 4) {\r\n                Vector3.TransformNormalFromFloatsToRef(data[index], data[index + 1], data[index + 2], transform, temp)\r\n                    .normalize()\r\n                    .toArray(data, index);\r\n            }\r\n            this.setVerticesData(VertexBuffer.TangentKind, data, (<VertexBuffer>this.getVertexBuffer(VertexBuffer.TangentKind)).isUpdatable());\r\n        }\r\n\r\n        // flip faces?\r\n        if (transform.determinant() < 0) {\r\n            this.flipFaces();\r\n        }\r\n\r\n        // Restore submeshes\r\n        this.releaseSubMeshes();\r\n        this.subMeshes = submeshes;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Modifies the mesh geometry according to its own current World Matrix.\r\n     * The mesh World Matrix is then reset.\r\n     * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.\r\n     * Note that, under the hood, this method sets a new VertexBuffer each call.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/bakingTransforms\r\n     * @param bakeIndependentlyOfChildren indicates whether to preserve all child nodes' World Matrix during baking\r\n     * @param forceUnique indicates whether to force the mesh geometry to be unique\r\n     * @returns the current mesh\r\n     */\r\n    public bakeCurrentTransformIntoVertices(bakeIndependentlyOfChildren: boolean = true, forceUnique: boolean = false): Mesh {\r\n        if (forceUnique) {\r\n            this.makeGeometryUnique();\r\n        }\r\n        this.bakeTransformIntoVertices(this.computeWorldMatrix(true));\r\n        this.resetLocalMatrix(bakeIndependentlyOfChildren);\r\n        return this;\r\n    }\r\n\r\n    // Cache\r\n\r\n    /** @internal */\r\n    public override get _positions(): Nullable<Vector3[]> {\r\n        return this._internalAbstractMeshDataInfo._positions || (this._geometry && this._geometry._positions) || null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _resetPointsArrayCache(): Mesh {\r\n        if (this._geometry) {\r\n            this._geometry._resetPointsArrayCache();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _generatePointsArray(): boolean {\r\n        if (this._geometry) {\r\n            return this._geometry._generatePointsArray();\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Mesh object generated from the current mesh properties.\r\n     * This method must not get confused with createInstance()\r\n     * @param name is a string, the name given to the new mesh\r\n     * @param newParent can be any Node object (default `null`) or an instance of MeshCloneOptions. If the latter, doNotCloneChildren and clonePhysicsImpostor are unused.\r\n     * @param doNotCloneChildren allows/denies the recursive cloning of the original mesh children if any (default `false`)\r\n     * @param clonePhysicsImpostor allows/denies the cloning in the same time of the original mesh `body` used by the physics engine, if any (default `true`)\r\n     * @returns a new mesh\r\n     */\r\n    public override clone(name: string = \"\", newParent: Nullable<Node> | MeshCloneOptions = null, doNotCloneChildren?: boolean, clonePhysicsImpostor: boolean = true): Mesh {\r\n        if (newParent && (newParent as Node)._addToSceneRootNodes === undefined) {\r\n            const cloneOptions = newParent as MeshCloneOptions;\r\n\r\n            MeshCreationOptions.source = this;\r\n            MeshCreationOptions.doNotCloneChildren = cloneOptions.doNotCloneChildren;\r\n            MeshCreationOptions.clonePhysicsImpostor = cloneOptions.clonePhysicsImpostor;\r\n            MeshCreationOptions.cloneThinInstances = cloneOptions.cloneThinInstances;\r\n\r\n            return new Mesh(name, this.getScene(), MeshCreationOptions);\r\n        }\r\n\r\n        return new Mesh(name, this.getScene(), newParent as Nullable<Node>, this, doNotCloneChildren, clonePhysicsImpostor);\r\n    }\r\n\r\n    /**\r\n     * Releases resources associated with this mesh.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        this.morphTargetManager = null;\r\n\r\n        if (this._geometry) {\r\n            this._geometry.releaseForMesh(this, true);\r\n        }\r\n\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n\r\n        if (internalDataInfo._onBeforeDrawObservable) {\r\n            internalDataInfo._onBeforeDrawObservable.clear();\r\n        }\r\n\r\n        if (internalDataInfo._onBeforeBindObservable) {\r\n            internalDataInfo._onBeforeBindObservable.clear();\r\n        }\r\n\r\n        if (internalDataInfo._onBeforeRenderObservable) {\r\n            internalDataInfo._onBeforeRenderObservable.clear();\r\n        }\r\n\r\n        if (internalDataInfo._onAfterRenderObservable) {\r\n            internalDataInfo._onAfterRenderObservable.clear();\r\n        }\r\n\r\n        if (internalDataInfo._onBetweenPassObservable) {\r\n            internalDataInfo._onBetweenPassObservable.clear();\r\n        }\r\n\r\n        // Sources\r\n        if (this._scene.useClonedMeshMap) {\r\n            if (internalDataInfo.meshMap) {\r\n                for (const uniqueId in internalDataInfo.meshMap) {\r\n                    const mesh = internalDataInfo.meshMap[uniqueId];\r\n                    if (mesh) {\r\n                        mesh._internalMeshDataInfo._source = null;\r\n                        internalDataInfo.meshMap[uniqueId] = undefined;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (internalDataInfo._source && internalDataInfo._source._internalMeshDataInfo.meshMap) {\r\n                internalDataInfo._source._internalMeshDataInfo.meshMap[this.uniqueId] = undefined;\r\n            }\r\n        } else {\r\n            const meshes = this.getScene().meshes;\r\n            for (const abstractMesh of meshes) {\r\n                const mesh = abstractMesh as Mesh;\r\n                if (mesh._internalMeshDataInfo && mesh._internalMeshDataInfo._source && mesh._internalMeshDataInfo._source === this) {\r\n                    mesh._internalMeshDataInfo._source = null;\r\n                }\r\n            }\r\n        }\r\n\r\n        internalDataInfo._source = null;\r\n\r\n        // Instances\r\n        this._disposeInstanceSpecificData();\r\n\r\n        // Thin instances\r\n        this._disposeThinInstanceSpecificData();\r\n\r\n        if (this._internalMeshDataInfo._checkReadinessObserver) {\r\n            this._scene.onBeforeRenderObservable.remove(this._internalMeshDataInfo._checkReadinessObserver);\r\n        }\r\n\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n\r\n    /** @internal */\r\n    public _disposeInstanceSpecificData() {\r\n        // Do nothing\r\n    }\r\n\r\n    /** @internal */\r\n    public _disposeThinInstanceSpecificData() {\r\n        // Do nothing\r\n    }\r\n\r\n    /** @internal */\r\n    public _invalidateInstanceVertexArrayObject() {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Modifies the mesh geometry according to a displacement map.\r\n     * A displacement map is a colored image. Each pixel color value (actually a gradient computed from red, green, blue values) will give the displacement to apply to each mesh vertex.\r\n     * The mesh must be set as updatable. Its internal geometry is directly modified, no new buffer are allocated.\r\n     * @param url is a string, the URL from the image file is to be downloaded.\r\n     * @param minHeight is the lower limit of the displacement.\r\n     * @param maxHeight is the upper limit of the displacement.\r\n     * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.\r\n     * @param uvOffset is an optional vector2 used to offset UV.\r\n     * @param uvScale is an optional vector2 used to scale UV.\r\n     * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.\r\n     * @param onError defines a callback called when an error occurs during the processing of the request.\r\n     * @returns the Mesh.\r\n     */\r\n    public applyDisplacementMap(\r\n        url: string,\r\n        minHeight: number,\r\n        maxHeight: number,\r\n        onSuccess?: (mesh: Mesh) => void,\r\n        uvOffset?: Vector2,\r\n        uvScale?: Vector2,\r\n        forceUpdate = false,\r\n        onError?: (message?: string, exception?: any) => void\r\n    ): Mesh {\r\n        const scene = this.getScene();\r\n\r\n        const onload = (img: HTMLImageElement | ImageBitmap) => {\r\n            // Getting height map data\r\n            const heightMapWidth = img.width;\r\n            const heightMapHeight = img.height;\r\n            const canvas = this.getEngine().createCanvas(heightMapWidth, heightMapHeight);\r\n            const context = <CanvasRenderingContext2D>canvas.getContext(\"2d\");\r\n\r\n            context.drawImage(img, 0, 0);\r\n\r\n            // Create VertexData from map data\r\n            //Cast is due to wrong definition in lib.d.ts from ts 1.3 - https://github.com/Microsoft/TypeScript/issues/949\r\n            const buffer = <Uint8Array>(<any>context.getImageData(0, 0, heightMapWidth, heightMapHeight).data);\r\n\r\n            this.applyDisplacementMapFromBuffer(buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight, uvOffset, uvScale, forceUpdate);\r\n            //execute success callback, if set\r\n            if (onSuccess) {\r\n                onSuccess(this);\r\n            }\r\n        };\r\n\r\n        LoadImage(url, onload, onError ? onError : () => {}, scene.offlineProvider);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Modifies the mesh geometry according to a displacementMap buffer.\r\n     * A displacement map is a colored image. Each pixel color value (actually a gradient computed from red, green, blue values) will give the displacement to apply to each mesh vertex.\r\n     * The mesh must be set as updatable. Its internal geometry is directly modified, no new buffer are allocated.\r\n     * @param buffer is a `Uint8Array` buffer containing series of `Uint8` lower than 255, the red, green, blue and alpha values of each successive pixel.\r\n     * @param heightMapWidth is the width of the buffer image.\r\n     * @param heightMapHeight is the height of the buffer image.\r\n     * @param minHeight is the lower limit of the displacement.\r\n     * @param maxHeight is the upper limit of the displacement.\r\n     * @param uvOffset is an optional vector2 used to offset UV.\r\n     * @param uvScale is an optional vector2 used to scale UV.\r\n     * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.\r\n     * @returns the Mesh.\r\n     */\r\n    public applyDisplacementMapFromBuffer(\r\n        buffer: Uint8Array,\r\n        heightMapWidth: number,\r\n        heightMapHeight: number,\r\n        minHeight: number,\r\n        maxHeight: number,\r\n        uvOffset?: Vector2,\r\n        uvScale?: Vector2,\r\n        forceUpdate = false\r\n    ): Mesh {\r\n        if (!this.isVerticesDataPresent(VertexBuffer.PositionKind) || !this.isVerticesDataPresent(VertexBuffer.NormalKind) || !this.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n            Logger.Warn(\"Cannot call applyDisplacementMap: Given mesh is not complete. Position, Normal or UV are missing\");\r\n            return this;\r\n        }\r\n\r\n        const positions = <FloatArray>this.getVerticesData(VertexBuffer.PositionKind, true, true);\r\n        const normals = <FloatArray>this.getVerticesData(VertexBuffer.NormalKind);\r\n        const uvs = <number[]>this.getVerticesData(VertexBuffer.UVKind);\r\n        let position = Vector3.Zero();\r\n        const normal = Vector3.Zero();\r\n        const uv = Vector2.Zero();\r\n\r\n        uvOffset = uvOffset || Vector2.Zero();\r\n        uvScale = uvScale || new Vector2(1, 1);\r\n\r\n        for (let index = 0; index < positions.length; index += 3) {\r\n            Vector3.FromArrayToRef(positions, index, position);\r\n            Vector3.FromArrayToRef(normals, index, normal);\r\n            Vector2.FromArrayToRef(uvs, (index / 3) * 2, uv);\r\n\r\n            // Compute height\r\n            const u = ((Math.abs(uv.x * uvScale.x + (uvOffset.x % 1)) * (heightMapWidth - 1)) % heightMapWidth) | 0;\r\n            const v = ((Math.abs(uv.y * uvScale.y + (uvOffset.y % 1)) * (heightMapHeight - 1)) % heightMapHeight) | 0;\r\n\r\n            const pos = (u + v * heightMapWidth) * 4;\r\n            const r = buffer[pos] / 255.0;\r\n            const g = buffer[pos + 1] / 255.0;\r\n            const b = buffer[pos + 2] / 255.0;\r\n\r\n            const gradient = r * 0.3 + g * 0.59 + b * 0.11;\r\n\r\n            normal.normalize();\r\n            normal.scaleInPlace(minHeight + (maxHeight - minHeight) * gradient);\r\n            position = position.add(normal);\r\n\r\n            position.toArray(positions, index);\r\n        }\r\n\r\n        VertexData.ComputeNormals(positions, this.getIndices(), normals);\r\n\r\n        if (forceUpdate) {\r\n            this.setVerticesData(VertexBuffer.PositionKind, positions);\r\n            this.setVerticesData(VertexBuffer.NormalKind, normals);\r\n            this.setVerticesData(VertexBuffer.UVKind, uvs);\r\n        } else {\r\n            this.updateVerticesData(VertexBuffer.PositionKind, positions);\r\n            this.updateVerticesData(VertexBuffer.NormalKind, normals);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    private _getFlattenedNormals(indices: IndicesArray, positions: FloatArray): Float32Array {\r\n        const normals = new Float32Array(indices.length * 3);\r\n        let normalsCount = 0;\r\n\r\n        // Decide if normals should be flipped\r\n        const flipNormalGeneration =\r\n            this.sideOrientation === (this._scene.useRightHandedSystem ? Constants.MATERIAL_CounterClockWiseSideOrientation : Constants.MATERIAL_ClockWiseSideOrientation);\r\n\r\n        // Generate new normals\r\n        for (let index = 0; index < indices.length; index += 3) {\r\n            const p1 = Vector3.FromArray(positions, indices[index] * 3);\r\n            const p2 = Vector3.FromArray(positions, indices[index + 1] * 3);\r\n            const p3 = Vector3.FromArray(positions, indices[index + 2] * 3);\r\n\r\n            const p1p2 = p1.subtract(p2);\r\n            const p3p2 = p3.subtract(p2);\r\n\r\n            const normal = Vector3.Normalize(Vector3.Cross(p1p2, p3p2));\r\n            if (flipNormalGeneration) {\r\n                normal.scaleInPlace(-1);\r\n            }\r\n\r\n            // Store same normals for every vertex\r\n            for (let localIndex = 0; localIndex < 3; localIndex++) {\r\n                normals[normalsCount++] = normal.x;\r\n                normals[normalsCount++] = normal.y;\r\n                normals[normalsCount++] = normal.z;\r\n            }\r\n        }\r\n\r\n        return normals;\r\n    }\r\n\r\n    private _convertToUnIndexedMesh(flattenNormals: boolean = false): Mesh {\r\n        const kinds = this.getVerticesDataKinds().filter((kind) => !this.getVertexBuffer(kind)?.getIsInstanced());\r\n        const indices = this.getIndices(false, true)!;\r\n        const data: { [kind: string]: FloatArray } = {};\r\n\r\n        const separateVertices = (data: FloatArray, size: number): Float32Array => {\r\n            const newData = new Float32Array(indices.length * size);\r\n            let count = 0;\r\n            for (let index = 0; index < indices.length; index++) {\r\n                for (let offset = 0; offset < size; offset++) {\r\n                    newData[count++] = data[indices[index] * size + offset];\r\n                }\r\n            }\r\n            return newData;\r\n        };\r\n\r\n        // Save mesh bounding info\r\n        const meshBoundingInfo = this.getBoundingInfo();\r\n\r\n        // Save previous submeshes\r\n        const previousSubmeshes = this.geometry ? this.subMeshes.slice(0) : [];\r\n\r\n        // Cache vertex data\r\n        for (const kind of kinds) {\r\n            data[kind] = this.getVerticesData(kind)!;\r\n        }\r\n\r\n        // Update vertex data\r\n        for (const kind of kinds) {\r\n            const vertexBuffer = this.getVertexBuffer(kind)!;\r\n            const size = vertexBuffer.getSize();\r\n\r\n            if (flattenNormals && kind === VertexBuffer.NormalKind) {\r\n                const normals = this._getFlattenedNormals(indices, data[VertexBuffer.PositionKind]);\r\n                this.setVerticesData(VertexBuffer.NormalKind, normals, vertexBuffer.isUpdatable(), size);\r\n            } else {\r\n                this.setVerticesData(kind, separateVertices(data[kind], size), vertexBuffer.isUpdatable(), size);\r\n            }\r\n        }\r\n\r\n        // Update morph targets\r\n        if (this.morphTargetManager) {\r\n            for (let targetIndex = 0; targetIndex < this.morphTargetManager.numTargets; targetIndex++) {\r\n                const target = this.morphTargetManager.getTarget(targetIndex);\r\n\r\n                const positions = target.getPositions()!;\r\n                target.setPositions(separateVertices(positions, 3));\r\n\r\n                const normals = target.getNormals();\r\n                if (normals) {\r\n                    target.setNormals(flattenNormals ? this._getFlattenedNormals(indices, positions) : separateVertices(normals, 3));\r\n                }\r\n\r\n                const tangents = target.getTangents();\r\n                if (tangents) {\r\n                    target.setTangents(separateVertices(tangents, 3));\r\n                }\r\n\r\n                const uvs = target.getUVs();\r\n                if (uvs) {\r\n                    target.setUVs(separateVertices(uvs, 2));\r\n                }\r\n\r\n                const colors = target.getColors();\r\n                if (colors) {\r\n                    target.setColors(separateVertices(colors, 4));\r\n                }\r\n            }\r\n            this.morphTargetManager.synchronize();\r\n        }\r\n\r\n        // Update indices\r\n        for (let index = 0; index < indices.length; index++) {\r\n            indices[index] = index;\r\n        }\r\n        this.setIndices(indices);\r\n\r\n        this._unIndexed = true;\r\n\r\n        // Update submeshes\r\n        this.releaseSubMeshes();\r\n        for (const previousOne of previousSubmeshes) {\r\n            const boundingInfo = previousOne.getBoundingInfo();\r\n            const subMesh = SubMesh.AddToMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);\r\n            subMesh.setBoundingInfo(boundingInfo);\r\n        }\r\n\r\n        this.setBoundingInfo(meshBoundingInfo);\r\n\r\n        this.synchronizeInstances();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Modify the mesh to get a flat shading rendering.\r\n     * This means each mesh facet will then have its own normals. Usually new vertices are added in the mesh geometry to get this result.\r\n     * Warning : the mesh is really modified even if not set originally as updatable and, under the hood, a new VertexBuffer is allocated.\r\n     * @returns current mesh\r\n     */\r\n    public convertToFlatShadedMesh(): Mesh {\r\n        return this._convertToUnIndexedMesh(true);\r\n    }\r\n\r\n    /**\r\n     * This method removes all the mesh indices and add new vertices (duplication) in order to unfold facets into buffers.\r\n     * In other words, more vertices, no more indices and a single bigger VBO.\r\n     * The mesh is really modified even if not set originally as updatable. Under the hood, a new VertexBuffer is allocated.\r\n     * @returns current mesh\r\n     */\r\n    public convertToUnIndexedMesh(): Mesh {\r\n        return this._convertToUnIndexedMesh();\r\n    }\r\n\r\n    /**\r\n     * Inverses facet orientations.\r\n     * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.\r\n     * @param flipNormals will also inverts the normals\r\n     * @returns current mesh\r\n     */\r\n    public flipFaces(flipNormals: boolean = false): Mesh {\r\n        const vertexData = VertexData.ExtractFromMesh(this);\r\n        let i: number;\r\n        if (flipNormals && this.isVerticesDataPresent(VertexBuffer.NormalKind) && vertexData.normals) {\r\n            for (i = 0; i < vertexData.normals.length; i++) {\r\n                vertexData.normals[i] *= -1;\r\n            }\r\n            this.setVerticesData(VertexBuffer.NormalKind, vertexData.normals, this.isVertexBufferUpdatable(VertexBuffer.NormalKind));\r\n        }\r\n\r\n        if (vertexData.indices) {\r\n            let temp;\r\n            for (i = 0; i < vertexData.indices.length; i += 3) {\r\n                // reassign indices\r\n                temp = vertexData.indices[i + 1];\r\n                vertexData.indices[i + 1] = vertexData.indices[i + 2];\r\n                vertexData.indices[i + 2] = temp;\r\n            }\r\n            this.setIndices(vertexData.indices, null, this.isVertexBufferUpdatable(VertexBuffer.PositionKind), true);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Increase the number of facets and hence vertices in a mesh\r\n     * Vertex normals are interpolated from existing vertex normals\r\n     * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.\r\n     * @param numberPerEdge the number of new vertices to add to each edge of a facet, optional default 1\r\n     */\r\n    public increaseVertices(numberPerEdge: number = 1): void {\r\n        const vertexData = VertexData.ExtractFromMesh(this);\r\n        const currentIndices = vertexData.indices && !Array.isArray(vertexData.indices) && Array.from ? Array.from(vertexData.indices) : vertexData.indices;\r\n        const positions = vertexData.positions && !Array.isArray(vertexData.positions) && Array.from ? Array.from(vertexData.positions) : vertexData.positions;\r\n        const uvs = vertexData.uvs && !Array.isArray(vertexData.uvs) && Array.from ? Array.from(vertexData.uvs) : vertexData.uvs;\r\n        const normals = vertexData.normals && !Array.isArray(vertexData.normals) && Array.from ? Array.from(vertexData.normals) : vertexData.normals;\r\n\r\n        if (!currentIndices || !positions) {\r\n            Logger.Warn(\"Couldn't increase number of vertices : VertexData must contain at least indices and positions\");\r\n        } else {\r\n            vertexData.indices = currentIndices;\r\n            vertexData.positions = positions;\r\n            if (uvs) {\r\n                vertexData.uvs = uvs;\r\n            }\r\n            if (normals) {\r\n                vertexData.normals = normals;\r\n            }\r\n\r\n            const segments: number = numberPerEdge + 1; //segments per current facet edge, become sides of new facets\r\n            const tempIndices: Array<Array<number>> = [];\r\n            for (let i = 0; i < segments + 1; i++) {\r\n                tempIndices[i] = [];\r\n            }\r\n            let a: number; //vertex index of one end of a side\r\n            let b: number; //vertex index of other end of the side\r\n            const deltaPosition: Vector3 = new Vector3(0, 0, 0);\r\n            const deltaNormal: Vector3 = new Vector3(0, 0, 0);\r\n            const deltaUV: Vector2 = new Vector2(0, 0);\r\n            const indices: number[] = [];\r\n            const vertexIndex: number[] = [];\r\n            const side: Array<Array<Array<number>>> = [];\r\n            let len: number;\r\n            let positionPtr: number = positions.length;\r\n            let uvPtr: number;\r\n            if (uvs) {\r\n                uvPtr = uvs.length;\r\n            }\r\n            let normalsPtr: number;\r\n            if (normals) {\r\n                normalsPtr = normals.length;\r\n            }\r\n\r\n            for (let i = 0; i < currentIndices.length; i += 3) {\r\n                vertexIndex[0] = currentIndices[i];\r\n                vertexIndex[1] = currentIndices[i + 1];\r\n                vertexIndex[2] = currentIndices[i + 2];\r\n                for (let j = 0; j < 3; j++) {\r\n                    a = vertexIndex[j];\r\n                    b = vertexIndex[(j + 1) % 3];\r\n                    if (side[a] === undefined && side[b] === undefined) {\r\n                        side[a] = [];\r\n                        side[b] = [];\r\n                    } else {\r\n                        if (side[a] === undefined) {\r\n                            side[a] = [];\r\n                        }\r\n                        if (side[b] === undefined) {\r\n                            side[b] = [];\r\n                        }\r\n                    }\r\n                    if (side[a][b] === undefined && side[b][a] === undefined) {\r\n                        side[a][b] = [];\r\n                        deltaPosition.x = (positions[3 * b] - positions[3 * a]) / segments;\r\n                        deltaPosition.y = (positions[3 * b + 1] - positions[3 * a + 1]) / segments;\r\n                        deltaPosition.z = (positions[3 * b + 2] - positions[3 * a + 2]) / segments;\r\n                        if (normals) {\r\n                            deltaNormal.x = (normals[3 * b] - normals[3 * a]) / segments;\r\n                            deltaNormal.y = (normals[3 * b + 1] - normals[3 * a + 1]) / segments;\r\n                            deltaNormal.z = (normals[3 * b + 2] - normals[3 * a + 2]) / segments;\r\n                        }\r\n                        if (uvs) {\r\n                            deltaUV.x = (uvs[2 * b] - uvs[2 * a]) / segments;\r\n                            deltaUV.y = (uvs[2 * b + 1] - uvs[2 * a + 1]) / segments;\r\n                        }\r\n                        side[a][b].push(a);\r\n                        for (let k = 1; k < segments; k++) {\r\n                            side[a][b].push(positions.length / 3);\r\n                            positions[positionPtr++] = positions[3 * a] + k * deltaPosition.x;\r\n                            positions[positionPtr++] = positions[3 * a + 1] + k * deltaPosition.y;\r\n                            positions[positionPtr++] = positions[3 * a + 2] + k * deltaPosition.z;\r\n                            if (normals) {\r\n                                normals[normalsPtr!++] = normals[3 * a] + k * deltaNormal.x;\r\n                                normals[normalsPtr!++] = normals[3 * a + 1] + k * deltaNormal.y;\r\n                                normals[normalsPtr!++] = normals[3 * a + 2] + k * deltaNormal.z;\r\n                            }\r\n                            if (uvs) {\r\n                                uvs[uvPtr!++] = uvs[2 * a] + k * deltaUV.x;\r\n                                uvs[uvPtr!++] = uvs[2 * a + 1] + k * deltaUV.y;\r\n                            }\r\n                        }\r\n                        side[a][b].push(b);\r\n                        side[b][a] = [];\r\n                        len = side[a][b].length;\r\n                        for (let idx = 0; idx < len; idx++) {\r\n                            side[b][a][idx] = side[a][b][len - 1 - idx];\r\n                        }\r\n                    }\r\n                }\r\n                //Calculate positions, normals and uvs of new internal vertices\r\n                tempIndices[0][0] = currentIndices[i];\r\n                tempIndices[1][0] = side[currentIndices[i]][currentIndices[i + 1]][1];\r\n                tempIndices[1][1] = side[currentIndices[i]][currentIndices[i + 2]][1];\r\n                for (let k = 2; k < segments; k++) {\r\n                    tempIndices[k][0] = side[currentIndices[i]][currentIndices[i + 1]][k];\r\n                    tempIndices[k][k] = side[currentIndices[i]][currentIndices[i + 2]][k];\r\n                    deltaPosition.x = (positions[3 * tempIndices[k][k]] - positions[3 * tempIndices[k][0]]) / k;\r\n                    deltaPosition.y = (positions[3 * tempIndices[k][k] + 1] - positions[3 * tempIndices[k][0] + 1]) / k;\r\n                    deltaPosition.z = (positions[3 * tempIndices[k][k] + 2] - positions[3 * tempIndices[k][0] + 2]) / k;\r\n                    if (normals) {\r\n                        deltaNormal.x = (normals[3 * tempIndices[k][k]] - normals[3 * tempIndices[k][0]]) / k;\r\n                        deltaNormal.y = (normals[3 * tempIndices[k][k] + 1] - normals[3 * tempIndices[k][0] + 1]) / k;\r\n                        deltaNormal.z = (normals[3 * tempIndices[k][k] + 2] - normals[3 * tempIndices[k][0] + 2]) / k;\r\n                    }\r\n                    if (uvs) {\r\n                        deltaUV.x = (uvs[2 * tempIndices[k][k]] - uvs[2 * tempIndices[k][0]]) / k;\r\n                        deltaUV.y = (uvs[2 * tempIndices[k][k] + 1] - uvs[2 * tempIndices[k][0] + 1]) / k;\r\n                    }\r\n                    for (let j = 1; j < k; j++) {\r\n                        tempIndices[k][j] = positions.length / 3;\r\n                        positions[positionPtr++] = positions[3 * tempIndices[k][0]] + j * deltaPosition.x;\r\n                        positions[positionPtr++] = positions[3 * tempIndices[k][0] + 1] + j * deltaPosition.y;\r\n                        positions[positionPtr++] = positions[3 * tempIndices[k][0] + 2] + j * deltaPosition.z;\r\n                        if (normals) {\r\n                            normals[normalsPtr!++] = normals[3 * tempIndices[k][0]] + j * deltaNormal.x;\r\n                            normals[normalsPtr!++] = normals[3 * tempIndices[k][0] + 1] + j * deltaNormal.y;\r\n                            normals[normalsPtr!++] = normals[3 * tempIndices[k][0] + 2] + j * deltaNormal.z;\r\n                        }\r\n                        if (uvs) {\r\n                            uvs[uvPtr!++] = uvs[2 * tempIndices[k][0]] + j * deltaUV.x;\r\n                            uvs[uvPtr!++] = uvs[2 * tempIndices[k][0] + 1] + j * deltaUV.y;\r\n                        }\r\n                    }\r\n                }\r\n                tempIndices[segments] = side[currentIndices[i + 1]][currentIndices[i + 2]];\r\n\r\n                // reform indices\r\n                indices.push(tempIndices[0][0], tempIndices[1][0], tempIndices[1][1]);\r\n                for (let k = 1; k < segments; k++) {\r\n                    let j: number;\r\n                    for (j = 0; j < k; j++) {\r\n                        indices.push(tempIndices[k][j], tempIndices[k + 1][j], tempIndices[k + 1][j + 1]);\r\n                        indices.push(tempIndices[k][j], tempIndices[k + 1][j + 1], tempIndices[k][j + 1]);\r\n                    }\r\n                    indices.push(tempIndices[k][j], tempIndices[k + 1][j], tempIndices[k + 1][j + 1]);\r\n                }\r\n            }\r\n\r\n            vertexData.indices = indices;\r\n            vertexData.applyToMesh(this, this.isVertexBufferUpdatable(VertexBuffer.PositionKind));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Force adjacent facets to share vertices and remove any facets that have all vertices in a line\r\n     * This will undo any application of covertToFlatShadedMesh\r\n     * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.\r\n     */\r\n    public forceSharedVertices(): void {\r\n        const vertexData = VertexData.ExtractFromMesh(this);\r\n        const currentUVs = vertexData.uvs;\r\n        const currentIndices = vertexData.indices;\r\n        const currentPositions = vertexData.positions;\r\n        const currentColors = vertexData.colors;\r\n        const currentMatrixIndices = vertexData.matricesIndices;\r\n        const currentMatrixWeights = vertexData.matricesWeights;\r\n        const currentMatrixIndicesExtra = vertexData.matricesIndicesExtra;\r\n        const currentMatrixWeightsExtra = vertexData.matricesWeightsExtra;\r\n\r\n        if (currentIndices === void 0 || currentPositions === void 0 || currentIndices === null || currentPositions === null) {\r\n            Logger.Warn(\"VertexData contains empty entries\");\r\n        } else {\r\n            const positions: Array<number> = [];\r\n            const indices: Array<number> = [];\r\n            const uvs: Array<number> = [];\r\n            const colors: Array<number> = [];\r\n            const matrixIndices: Array<number> = [];\r\n            const matrixWeights: Array<number> = [];\r\n            const matrixIndicesExtra: Array<number> = [];\r\n            const matrixWeightsExtra: Array<number> = [];\r\n            let pstring: Array<string>; //lists facet vertex positions (a,b,c) as string \"a|b|c\"\r\n\r\n            let indexPtr: number = 0; // pointer to next available index value\r\n            const uniquePositions: { [key: string]: number } = {}; // unique vertex positions\r\n            let ptr: number; // pointer to element in uniquePositions\r\n            let facet: Array<number>;\r\n\r\n            for (let i = 0; i < currentIndices.length; i += 3) {\r\n                facet = [currentIndices[i], currentIndices[i + 1], currentIndices[i + 2]]; //facet vertex indices\r\n                pstring = [];\r\n                for (let j = 0; j < 3; j++) {\r\n                    pstring[j] = \"\";\r\n                    for (let k = 0; k < 3; k++) {\r\n                        //small values make 0\r\n                        if (Math.abs(currentPositions[3 * facet[j] + k]) < 0.00000001) {\r\n                            currentPositions[3 * facet[j] + k] = 0;\r\n                        }\r\n                        pstring[j] += currentPositions[3 * facet[j] + k] + \"|\";\r\n                    }\r\n                }\r\n                //check facet vertices to see that none are repeated\r\n                // do not process any facet that has a repeated vertex, ie is a line\r\n                if (!(pstring[0] == pstring[1] || pstring[0] == pstring[2] || pstring[1] == pstring[2])) {\r\n                    //for each facet position check if already listed in uniquePositions\r\n                    // if not listed add to uniquePositions and set index pointer\r\n                    // if listed use its index in uniquePositions and new index pointer\r\n                    for (let j = 0; j < 3; j++) {\r\n                        ptr = uniquePositions[pstring[j]];\r\n                        if (ptr === undefined) {\r\n                            uniquePositions[pstring[j]] = indexPtr;\r\n                            ptr = indexPtr++;\r\n                            //not listed so add individual x, y, z coordinates to positions\r\n                            for (let k = 0; k < 3; k++) {\r\n                                positions.push(currentPositions[3 * facet[j] + k]);\r\n                            }\r\n                            if (currentColors !== null && currentColors !== void 0) {\r\n                                for (let k = 0; k < 4; k++) {\r\n                                    colors.push(currentColors[4 * facet[j] + k]);\r\n                                }\r\n                            }\r\n                            if (currentUVs !== null && currentUVs !== void 0) {\r\n                                for (let k = 0; k < 2; k++) {\r\n                                    uvs.push(currentUVs[2 * facet[j] + k]);\r\n                                }\r\n                            }\r\n                            if (currentMatrixIndices !== null && currentMatrixIndices !== void 0) {\r\n                                for (let k = 0; k < 4; k++) {\r\n                                    matrixIndices.push(currentMatrixIndices[4 * facet[j] + k]);\r\n                                }\r\n                            }\r\n                            if (currentMatrixWeights !== null && currentMatrixWeights !== void 0) {\r\n                                for (let k = 0; k < 4; k++) {\r\n                                    matrixWeights.push(currentMatrixWeights[4 * facet[j] + k]);\r\n                                }\r\n                            }\r\n                            if (currentMatrixIndicesExtra !== null && currentMatrixIndicesExtra !== void 0) {\r\n                                for (let k = 0; k < 4; k++) {\r\n                                    matrixIndicesExtra.push(currentMatrixIndicesExtra[4 * facet[j] + k]);\r\n                                }\r\n                            }\r\n                            if (currentMatrixWeightsExtra !== null && currentMatrixWeightsExtra !== void 0) {\r\n                                for (let k = 0; k < 4; k++) {\r\n                                    matrixWeightsExtra.push(currentMatrixWeightsExtra[4 * facet[j] + k]);\r\n                                }\r\n                            }\r\n                        }\r\n                        // add new index pointer to indices array\r\n                        indices.push(ptr);\r\n                    }\r\n                }\r\n            }\r\n\r\n            const normals: Array<number> = [];\r\n            VertexData.ComputeNormals(positions, indices, normals);\r\n\r\n            //create new vertex data object and update\r\n            vertexData.positions = positions;\r\n            vertexData.indices = indices;\r\n            vertexData.normals = normals;\r\n            if (currentUVs !== null && currentUVs !== void 0) {\r\n                vertexData.uvs = uvs;\r\n            }\r\n            if (currentColors !== null && currentColors !== void 0) {\r\n                vertexData.colors = colors;\r\n            }\r\n            if (currentMatrixIndices !== null && currentMatrixIndices !== void 0) {\r\n                vertexData.matricesIndices = matrixIndices;\r\n            }\r\n            if (currentMatrixWeights !== null && currentMatrixWeights !== void 0) {\r\n                vertexData.matricesWeights = matrixWeights;\r\n            }\r\n            if (currentMatrixIndicesExtra !== null && currentMatrixIndicesExtra !== void 0) {\r\n                vertexData.matricesIndicesExtra = matrixIndicesExtra;\r\n            }\r\n            if (currentMatrixWeights !== null && currentMatrixWeights !== void 0) {\r\n                vertexData.matricesWeightsExtra = matrixWeightsExtra;\r\n            }\r\n\r\n            vertexData.applyToMesh(this, this.isVertexBufferUpdatable(VertexBuffer.PositionKind));\r\n        }\r\n    }\r\n\r\n    // Instances\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/naming-convention\r\n    public static _instancedMeshFactory(name: string, mesh: Mesh): InstancedMesh {\r\n        throw _WarnImport(\"InstancedMesh\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _PhysicsImpostorParser(scene: Scene, physicObject: IPhysicsEnabledObject, jsonObject: any): PhysicsImpostor {\r\n        throw _WarnImport(\"PhysicsImpostor\");\r\n    }\r\n\r\n    /**\r\n     * Creates a new InstancedMesh object from the mesh model.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances\r\n     * @param name defines the name of the new instance\r\n     * @returns a new InstancedMesh\r\n     */\r\n    public createInstance(name: string): InstancedMesh {\r\n        const instance = Mesh._instancedMeshFactory(name, this);\r\n\r\n        instance.parent = this.parent;\r\n\r\n        return instance;\r\n    }\r\n\r\n    /**\r\n     * Synchronises all the mesh instance submeshes to the current mesh submeshes, if any.\r\n     * After this call, all the mesh instances have the same submeshes than the current mesh.\r\n     * @returns the current mesh\r\n     */\r\n    public synchronizeInstances(): Mesh {\r\n        for (let instanceIndex = 0; instanceIndex < this.instances.length; instanceIndex++) {\r\n            const instance = this.instances[instanceIndex];\r\n            instance._syncSubMeshes();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Optimization of the mesh's indices, in case a mesh has duplicated vertices.\r\n     * The function will only reorder the indices and will not remove unused vertices to avoid problems with submeshes.\r\n     * This should be used together with the simplification to avoid disappearing triangles.\r\n     * @param successCallback an optional success callback to be called after the optimization finished.\r\n     * @returns the current mesh\r\n     */\r\n    public optimizeIndices(successCallback?: (mesh?: Mesh) => void): Mesh {\r\n        const indices = <IndicesArray>this.getIndices();\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        if (!positions || !indices) {\r\n            return this;\r\n        }\r\n\r\n        const vectorPositions: Vector3[] = [];\r\n        for (let pos = 0; pos < positions.length; pos = pos + 3) {\r\n            vectorPositions.push(Vector3.FromArray(positions, pos));\r\n        }\r\n        const dupes: number[] = [];\r\n\r\n        AsyncLoop.SyncAsyncForLoop(\r\n            vectorPositions.length,\r\n            40,\r\n            (iteration) => {\r\n                const realPos = vectorPositions.length - 1 - iteration;\r\n                const testedPosition = vectorPositions[realPos];\r\n                for (let j = 0; j < realPos; ++j) {\r\n                    const againstPosition = vectorPositions[j];\r\n                    if (testedPosition.equals(againstPosition)) {\r\n                        dupes[realPos] = j;\r\n                        break;\r\n                    }\r\n                }\r\n            },\r\n            () => {\r\n                for (let i = 0; i < indices.length; ++i) {\r\n                    indices[i] = dupes[indices[i]] || indices[i];\r\n                }\r\n\r\n                //indices are now reordered\r\n                const originalSubMeshes = this.subMeshes.slice(0);\r\n                this.setIndices(indices);\r\n                this.subMeshes = originalSubMeshes;\r\n                if (successCallback) {\r\n                    successCallback(this);\r\n                }\r\n            }\r\n        );\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serialize current mesh\r\n     * @param serializationObject defines the object which will receive the serialization data\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(serializationObject: any = {}): any {\r\n        serializationObject.name = this.name;\r\n        serializationObject.id = this.id;\r\n        serializationObject.uniqueId = this.uniqueId;\r\n        serializationObject.type = this.getClassName();\r\n\r\n        if (Tags && Tags.HasTags(this)) {\r\n            serializationObject.tags = Tags.GetTags(this);\r\n        }\r\n\r\n        serializationObject.position = this.position.asArray();\r\n\r\n        if (this.rotationQuaternion) {\r\n            serializationObject.rotationQuaternion = this.rotationQuaternion.asArray();\r\n        } else if (this.rotation) {\r\n            serializationObject.rotation = this.rotation.asArray();\r\n        }\r\n\r\n        serializationObject.scaling = this.scaling.asArray();\r\n        if (this._postMultiplyPivotMatrix) {\r\n            serializationObject.pivotMatrix = this.getPivotMatrix().asArray();\r\n        } else {\r\n            serializationObject.localMatrix = this.getPivotMatrix().asArray();\r\n        }\r\n\r\n        serializationObject.isEnabled = this.isEnabled(false);\r\n        serializationObject.isVisible = this.isVisible;\r\n        serializationObject.infiniteDistance = this.infiniteDistance;\r\n        serializationObject.pickable = this.isPickable;\r\n\r\n        serializationObject.receiveShadows = this.receiveShadows;\r\n\r\n        serializationObject.billboardMode = this.billboardMode;\r\n        serializationObject.visibility = this.visibility;\r\n        serializationObject.alwaysSelectAsActiveMesh = this.alwaysSelectAsActiveMesh;\r\n\r\n        serializationObject.checkCollisions = this.checkCollisions;\r\n        serializationObject.ellipsoid = this.ellipsoid.asArray();\r\n        serializationObject.ellipsoidOffset = this.ellipsoidOffset.asArray();\r\n        serializationObject.doNotSyncBoundingInfo = this.doNotSyncBoundingInfo;\r\n        serializationObject.isBlocker = this.isBlocker;\r\n        serializationObject.sideOrientation = this.sideOrientation;\r\n\r\n        if (this._isWorldMatrixFrozen) {\r\n            serializationObject.freezeWorldMatrix = true;\r\n        }\r\n\r\n        // Parent\r\n        if (this.parent) {\r\n            this.parent._serializeAsParent(serializationObject);\r\n        }\r\n\r\n        // Geometry\r\n        serializationObject.isUnIndexed = this.isUnIndexed;\r\n        const geometry = this._geometry;\r\n        if (geometry && this.subMeshes) {\r\n            serializationObject.geometryUniqueId = geometry.uniqueId;\r\n            serializationObject.geometryId = geometry.id;\r\n\r\n            // SubMeshes\r\n            serializationObject.subMeshes = [];\r\n            for (let subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {\r\n                const subMesh = this.subMeshes[subIndex];\r\n\r\n                serializationObject.subMeshes.push({\r\n                    materialIndex: subMesh.materialIndex,\r\n                    verticesStart: subMesh.verticesStart,\r\n                    verticesCount: subMesh.verticesCount,\r\n                    indexStart: subMesh.indexStart,\r\n                    indexCount: subMesh.indexCount,\r\n                });\r\n            }\r\n        }\r\n\r\n        // Material\r\n        if (this.material) {\r\n            if (!this.material.doNotSerialize) {\r\n                serializationObject.materialUniqueId = this.material.uniqueId;\r\n                serializationObject.materialId = this.material.id; // back compat\r\n            }\r\n        } else {\r\n            this.material = null;\r\n            serializationObject.materialUniqueId = this._scene.defaultMaterial.uniqueId;\r\n            serializationObject.materialId = this._scene.defaultMaterial.id; // back compat\r\n        }\r\n\r\n        // Morph targets\r\n        if (this.morphTargetManager) {\r\n            serializationObject.morphTargetManagerId = this.morphTargetManager.uniqueId;\r\n        }\r\n\r\n        // Skeleton\r\n        if (this.skeleton) {\r\n            serializationObject.skeletonId = this.skeleton.id;\r\n            serializationObject.skeletonUniqueId = this.skeleton.uniqueId;\r\n            serializationObject.numBoneInfluencers = this.numBoneInfluencers;\r\n        }\r\n\r\n        // Physics\r\n        //TODO implement correct serialization for physics impostors.\r\n        if (this.getScene()._getComponent(SceneComponentConstants.NAME_PHYSICSENGINE)) {\r\n            const impostor = this.getPhysicsImpostor?.();\r\n            if (impostor) {\r\n                serializationObject.physicsMass = impostor.getParam(\"mass\");\r\n                serializationObject.physicsFriction = impostor.getParam(\"friction\");\r\n                serializationObject.physicsRestitution = impostor.getParam(\"mass\");\r\n                serializationObject.physicsImpostor = impostor.type;\r\n            }\r\n        }\r\n\r\n        // Metadata\r\n        if (this.metadata) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n        if (this.meshBlendingTag !== 0) {\r\n            serializationObject.meshBlendingTag = this.meshBlendingTag;\r\n        }\r\n\r\n        // Instances\r\n        serializationObject.instances = [];\r\n        for (let index = 0; index < this.instances.length; index++) {\r\n            const instance = this.instances[index];\r\n            if (instance.doNotSerialize) {\r\n                continue;\r\n            }\r\n\r\n            const serializationInstance: any = {\r\n                name: instance.name,\r\n                id: instance.id,\r\n                isEnabled: instance.isEnabled(false),\r\n                isVisible: instance.isVisible,\r\n                isPickable: instance.isPickable,\r\n                checkCollisions: instance.checkCollisions,\r\n                position: instance.position.asArray(),\r\n                scaling: instance.scaling.asArray(),\r\n            };\r\n\r\n            if (instance.parent) {\r\n                instance.parent._serializeAsParent(serializationInstance);\r\n            }\r\n\r\n            if (instance.rotationQuaternion) {\r\n                serializationInstance.rotationQuaternion = instance.rotationQuaternion.asArray();\r\n            } else if (instance.rotation) {\r\n                serializationInstance.rotation = instance.rotation.asArray();\r\n            }\r\n\r\n            // Physics\r\n            //TODO implement correct serialization for physics impostors.\r\n            if (this.getScene()._getComponent(SceneComponentConstants.NAME_PHYSICSENGINE)) {\r\n                const impostor = instance.getPhysicsImpostor?.();\r\n                if (impostor) {\r\n                    serializationInstance.physicsMass = impostor.getParam(\"mass\");\r\n                    serializationInstance.physicsFriction = impostor.getParam(\"friction\");\r\n                    serializationInstance.physicsRestitution = impostor.getParam(\"mass\");\r\n                    serializationInstance.physicsImpostor = impostor.type;\r\n                }\r\n            }\r\n\r\n            // Metadata\r\n            if (instance.metadata) {\r\n                serializationInstance.metadata = instance.metadata;\r\n            }\r\n\r\n            // Action Manager\r\n            if (instance.actionManager) {\r\n                serializationInstance.actions = instance.actionManager.serialize(instance.name);\r\n            }\r\n\r\n            serializationObject.instances.push(serializationInstance);\r\n\r\n            // Animations\r\n            SerializationHelper.AppendSerializedAnimations(instance, serializationInstance);\r\n            serializationInstance.ranges = instance.serializeAnimationRanges();\r\n        }\r\n\r\n        // Thin instances\r\n        if (this._thinInstanceDataStorage.instancesCount && this._thinInstanceDataStorage.matrixData) {\r\n            serializationObject.thinInstances = {\r\n                instancesCount: this._thinInstanceDataStorage.instancesCount,\r\n                matrixData: Array.from(this._thinInstanceDataStorage.matrixData),\r\n                matrixBufferSize: this._thinInstanceDataStorage.matrixBufferSize,\r\n                enablePicking: this.thinInstanceEnablePicking,\r\n            };\r\n\r\n            if (this._userThinInstanceBuffersStorage) {\r\n                const userThinInstance: any = {\r\n                    data: {},\r\n                    sizes: {},\r\n                    strides: {},\r\n                };\r\n\r\n                for (const kind in this._userThinInstanceBuffersStorage.data) {\r\n                    userThinInstance.data[kind] = Array.from(this._userThinInstanceBuffersStorage.data[kind]);\r\n                    userThinInstance.sizes[kind] = this._userThinInstanceBuffersStorage.sizes[kind];\r\n                    userThinInstance.strides[kind] = this._userThinInstanceBuffersStorage.strides[kind];\r\n                }\r\n\r\n                serializationObject.thinInstances.userThinInstance = userThinInstance;\r\n            }\r\n        }\r\n\r\n        // Animations\r\n        SerializationHelper.AppendSerializedAnimations(this, serializationObject);\r\n        serializationObject.ranges = this.serializeAnimationRanges();\r\n\r\n        // Layer mask\r\n        serializationObject.layerMask = this.layerMask;\r\n\r\n        // Alpha\r\n        serializationObject.alphaIndex = this.alphaIndex;\r\n        serializationObject.hasVertexAlpha = this.hasVertexAlpha;\r\n\r\n        // Overlay\r\n        serializationObject.overlayAlpha = this.overlayAlpha;\r\n        serializationObject.overlayColor = this.overlayColor.asArray();\r\n        serializationObject.renderOverlay = this.renderOverlay;\r\n\r\n        // Fog\r\n        serializationObject.applyFog = this.applyFog;\r\n\r\n        // Action Manager\r\n        if (this.actionManager) {\r\n            serializationObject.actions = this.actionManager.serialize(this.name);\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _syncGeometryWithMorphTargetManager() {\r\n        if (!this.geometry) {\r\n            return;\r\n        }\r\n\r\n        this._markSubMeshesAsAttributesDirty();\r\n\r\n        const morphTargetManager = this._internalAbstractMeshDataInfo._morphTargetManager;\r\n        if (morphTargetManager && morphTargetManager.vertexCount) {\r\n            if (morphTargetManager.vertexCount !== this.getTotalVertices()) {\r\n                Logger.Error(\"Mesh is incompatible with morph targets. Targets and mesh must all have the same vertices count.\");\r\n                this.morphTargetManager = null;\r\n                return;\r\n            }\r\n\r\n            if (morphTargetManager.isUsingTextureForTargets) {\r\n                return;\r\n            }\r\n\r\n            for (let index = 0; index < morphTargetManager.numInfluencers; index++) {\r\n                const morphTarget = morphTargetManager.getActiveTarget(index);\r\n\r\n                const positions = morphTarget.getPositions();\r\n                if (!positions) {\r\n                    Logger.Error(\"Invalid morph target. Target must have positions.\");\r\n                    return;\r\n                }\r\n\r\n                this.geometry.setVerticesData(VertexBuffer.PositionKind + index, positions, false, 3);\r\n\r\n                const normals = morphTarget.getNormals();\r\n                if (normals) {\r\n                    this.geometry.setVerticesData(VertexBuffer.NormalKind + index, normals, false, 3);\r\n                }\r\n\r\n                const tangents = morphTarget.getTangents();\r\n                if (tangents) {\r\n                    this.geometry.setVerticesData(VertexBuffer.TangentKind + index, tangents, false, 3);\r\n                }\r\n\r\n                const uvs = morphTarget.getUVs();\r\n                if (uvs) {\r\n                    this.geometry.setVerticesData(VertexBuffer.UVKind + \"_\" + index, uvs, false, 2);\r\n                }\r\n\r\n                const uv2s = morphTarget.getUV2s();\r\n                if (uv2s) {\r\n                    this.geometry.setVerticesData(VertexBuffer.UV2Kind + \"_\" + index, uv2s, false, 2);\r\n                }\r\n\r\n                const colors = morphTarget.getColors();\r\n                if (colors) {\r\n                    this.geometry.setVerticesData(VertexBuffer.ColorKind + index, colors, false, 4);\r\n                }\r\n            }\r\n        } else {\r\n            let index = 0;\r\n\r\n            // Positions\r\n            while (this.geometry.isVerticesDataPresent(VertexBuffer.PositionKind + index)) {\r\n                this.geometry.removeVerticesData(VertexBuffer.PositionKind + index);\r\n\r\n                if (this.geometry.isVerticesDataPresent(VertexBuffer.NormalKind + index)) {\r\n                    this.geometry.removeVerticesData(VertexBuffer.NormalKind + index);\r\n                }\r\n                if (this.geometry.isVerticesDataPresent(VertexBuffer.TangentKind + index)) {\r\n                    this.geometry.removeVerticesData(VertexBuffer.TangentKind + index);\r\n                }\r\n                if (this.geometry.isVerticesDataPresent(VertexBuffer.UVKind + \"_\" + index)) {\r\n                    this.geometry.removeVerticesData(VertexBuffer.UVKind + \"_\" + index);\r\n                }\r\n                if (this.geometry.isVerticesDataPresent(VertexBuffer.UV2Kind + \"_\" + index)) {\r\n                    this.geometry.removeVerticesData(VertexBuffer.UV2Kind + \"_\" + index);\r\n                }\r\n                if (this.geometry.isVerticesDataPresent(VertexBuffer.ColorKind + index)) {\r\n                    this.geometry.removeVerticesData(VertexBuffer.ColorKind + index);\r\n                }\r\n                index++;\r\n            }\r\n        }\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GroundMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"GroundMesh\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GoldbergMeshParser = (parsedMesh: any, scene: Scene): GoldbergMesh => {\r\n        throw _WarnImport(\"GoldbergMesh\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _LinesMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"LinesMesh\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GreasedLineMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"GreasedLineMesh\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GreasedLineRibbonMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"GreasedLineRibbonMesh\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _TrailMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"TrailMesh\");\r\n    };\r\n\r\n    /**\r\n     * Holder function for GaussianSplattingMesh Parser, should be GaussianSplattingMesh.Parse after imported\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GaussianSplattingMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"GaussianSplattingMesh\");\r\n    };\r\n\r\n    /**\r\n     * Holder function for GaussianSplattingPartProxyMesh Parser, should be GaussianSplattingPartProxyMesh.Parse after imported\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GaussianSplattingPartProxyMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"GaussianSplattingPartProxyMesh\");\r\n    };\r\n\r\n    /**\r\n     * Holder function for GaussianSplattingCompoundMesh Parser, should be GaussianSplattingCompoundMesh.Parse after imported\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _GaussianSplattingCompoundMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        throw _WarnImport(\"GaussianSplattingCompoundMesh\");\r\n    };\r\n\r\n    /**\r\n     * Returns a new Mesh object parsed from the source provided.\r\n     * @param parsedMesh is the source\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl is the root URL to prefix the `delayLoadingFile` property with\r\n     * @returns a new Mesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene, rootUrl: string): Mesh {\r\n        let mesh: Mesh;\r\n        // Should not import Geometry for GaussianSplattingMesh and GaussianSplattingPartProxyMesh\r\n        let skipImportGeometry = false;\r\n\r\n        if (parsedMesh.type && parsedMesh.type === \"LinesMesh\") {\r\n            mesh = Mesh._LinesMeshParser(parsedMesh, scene);\r\n        } else if (parsedMesh.type && parsedMesh.type === \"GroundMesh\") {\r\n            mesh = Mesh._GroundMeshParser(parsedMesh, scene);\r\n        } else if (parsedMesh.type && parsedMesh.type === \"GoldbergMesh\") {\r\n            mesh = Mesh._GoldbergMeshParser(parsedMesh, scene);\r\n        } else if (parsedMesh.type && parsedMesh.type === \"GreasedLineMesh\") {\r\n            mesh = Mesh._GreasedLineMeshParser(parsedMesh, scene);\r\n        } else if (parsedMesh.type && parsedMesh.type === \"TrailMesh\") {\r\n            mesh = Mesh._TrailMeshParser(parsedMesh, scene);\r\n        } else if (parsedMesh.type && parsedMesh.type === \"GaussianSplattingMesh\") {\r\n            if (parsedMesh._isCompound) {\r\n                mesh = Mesh._GaussianSplattingCompoundMeshParser(parsedMesh, scene);\r\n            } else {\r\n                mesh = Mesh._GaussianSplattingMeshParser(parsedMesh, scene);\r\n            }\r\n            skipImportGeometry = true;\r\n        } else if (parsedMesh.type && parsedMesh.type === \"GaussianSplattingPartProxyMesh\") {\r\n            mesh = Mesh._GaussianSplattingPartProxyMeshParser(parsedMesh, scene);\r\n            skipImportGeometry = true;\r\n        } else {\r\n            mesh = new Mesh(parsedMesh.name, scene);\r\n        }\r\n        mesh.id = parsedMesh.id;\r\n        mesh._waitingParsedUniqueId = parsedMesh.uniqueId;\r\n\r\n        if (Tags) {\r\n            Tags.AddTagsTo(mesh, parsedMesh.tags);\r\n        }\r\n\r\n        mesh.position = Vector3.FromArray(parsedMesh.position);\r\n\r\n        if (parsedMesh.metadata !== undefined) {\r\n            mesh.metadata = parsedMesh.metadata;\r\n        }\r\n        if (parsedMesh.meshBlendingTag !== undefined) {\r\n            mesh.meshBlendingTag = parsedMesh.meshBlendingTag;\r\n        }\r\n\r\n        if (parsedMesh.rotationQuaternion) {\r\n            mesh.rotationQuaternion = Quaternion.FromArray(parsedMesh.rotationQuaternion);\r\n        } else if (parsedMesh.rotation) {\r\n            mesh.rotation = Vector3.FromArray(parsedMesh.rotation);\r\n        }\r\n\r\n        mesh.scaling = Vector3.FromArray(parsedMesh.scaling);\r\n\r\n        if (parsedMesh.localMatrix) {\r\n            mesh.setPreTransformMatrix(Matrix.FromArray(parsedMesh.localMatrix));\r\n        } else if (parsedMesh.pivotMatrix) {\r\n            mesh.setPivotMatrix(Matrix.FromArray(parsedMesh.pivotMatrix));\r\n        }\r\n\r\n        mesh.setEnabled(parsedMesh.isEnabled);\r\n        mesh.isVisible = parsedMesh.isVisible;\r\n        mesh.infiniteDistance = parsedMesh.infiniteDistance;\r\n        mesh.alwaysSelectAsActiveMesh = !!parsedMesh.alwaysSelectAsActiveMesh;\r\n\r\n        mesh.showBoundingBox = parsedMesh.showBoundingBox;\r\n        mesh.showSubMeshesBoundingBox = parsedMesh.showSubMeshesBoundingBox;\r\n\r\n        if (parsedMesh.applyFog !== undefined) {\r\n            mesh.applyFog = parsedMesh.applyFog;\r\n        }\r\n\r\n        if (parsedMesh.pickable !== undefined) {\r\n            mesh.isPickable = parsedMesh.pickable;\r\n        }\r\n\r\n        if (parsedMesh.alphaIndex !== undefined) {\r\n            mesh.alphaIndex = parsedMesh.alphaIndex;\r\n        }\r\n\r\n        mesh.receiveShadows = parsedMesh.receiveShadows;\r\n\r\n        if (parsedMesh.billboardMode !== undefined) {\r\n            mesh.billboardMode = parsedMesh.billboardMode;\r\n        }\r\n\r\n        if (parsedMesh.visibility !== undefined) {\r\n            mesh.visibility = parsedMesh.visibility;\r\n        }\r\n\r\n        mesh.checkCollisions = parsedMesh.checkCollisions;\r\n        mesh.doNotSyncBoundingInfo = !!parsedMesh.doNotSyncBoundingInfo;\r\n\r\n        if (parsedMesh.ellipsoid) {\r\n            mesh.ellipsoid = Vector3.FromArray(parsedMesh.ellipsoid);\r\n        }\r\n\r\n        if (parsedMesh.ellipsoidOffset) {\r\n            mesh.ellipsoidOffset = Vector3.FromArray(parsedMesh.ellipsoidOffset);\r\n        }\r\n\r\n        // For Backward compatibility (\"!=\" to exclude null and undefined)\r\n        if (parsedMesh.overrideMaterialSideOrientation != null) {\r\n            mesh.sideOrientation = parsedMesh.overrideMaterialSideOrientation;\r\n        }\r\n\r\n        if (parsedMesh.sideOrientation !== undefined) {\r\n            mesh.sideOrientation = parsedMesh.sideOrientation;\r\n        }\r\n\r\n        if (parsedMesh.isBlocker !== undefined) {\r\n            mesh.isBlocker = parsedMesh.isBlocker;\r\n        }\r\n\r\n        mesh._shouldGenerateFlatShading = parsedMesh.useFlatShading;\r\n\r\n        // freezeWorldMatrix\r\n        if (parsedMesh.freezeWorldMatrix) {\r\n            mesh._waitingData.freezeWorldMatrix = parsedMesh.freezeWorldMatrix;\r\n        }\r\n\r\n        // Parent\r\n        if (parsedMesh.parentId !== undefined) {\r\n            mesh._waitingParentId = parsedMesh.parentId;\r\n        }\r\n\r\n        if (parsedMesh.parentInstanceIndex !== undefined) {\r\n            mesh._waitingParentInstanceIndex = parsedMesh.parentInstanceIndex;\r\n        }\r\n\r\n        // Actions\r\n        if (parsedMesh.actions !== undefined) {\r\n            mesh._waitingData.actions = parsedMesh.actions;\r\n        }\r\n\r\n        // Overlay\r\n        if (parsedMesh.overlayAlpha !== undefined) {\r\n            mesh.overlayAlpha = parsedMesh.overlayAlpha;\r\n        }\r\n\r\n        if (parsedMesh.overlayColor !== undefined) {\r\n            mesh.overlayColor = Color3.FromArray(parsedMesh.overlayColor);\r\n        }\r\n\r\n        if (parsedMesh.renderOverlay !== undefined) {\r\n            mesh.renderOverlay = parsedMesh.renderOverlay;\r\n        }\r\n\r\n        // Geometry\r\n        mesh.isUnIndexed = !!parsedMesh.isUnIndexed;\r\n        mesh.hasVertexAlpha = parsedMesh.hasVertexAlpha;\r\n\r\n        if (parsedMesh.delayLoadingFile) {\r\n            mesh.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n            mesh.delayLoadingFile = rootUrl + parsedMesh.delayLoadingFile;\r\n            mesh.buildBoundingInfo(Vector3.FromArray(parsedMesh.boundingBoxMinimum), Vector3.FromArray(parsedMesh.boundingBoxMaximum));\r\n\r\n            if (parsedMesh._binaryInfo) {\r\n                mesh._binaryInfo = parsedMesh._binaryInfo;\r\n            }\r\n\r\n            mesh._delayInfo = [];\r\n            if (parsedMesh.hasUVs) {\r\n                mesh._delayInfo.push(VertexBuffer.UVKind);\r\n            }\r\n\r\n            if (parsedMesh.hasUVs2) {\r\n                mesh._delayInfo.push(VertexBuffer.UV2Kind);\r\n            }\r\n\r\n            if (parsedMesh.hasUVs3) {\r\n                mesh._delayInfo.push(VertexBuffer.UV3Kind);\r\n            }\r\n\r\n            if (parsedMesh.hasUVs4) {\r\n                mesh._delayInfo.push(VertexBuffer.UV4Kind);\r\n            }\r\n\r\n            if (parsedMesh.hasUVs5) {\r\n                mesh._delayInfo.push(VertexBuffer.UV5Kind);\r\n            }\r\n\r\n            if (parsedMesh.hasUVs6) {\r\n                mesh._delayInfo.push(VertexBuffer.UV6Kind);\r\n            }\r\n\r\n            if (parsedMesh.hasColors) {\r\n                mesh._delayInfo.push(VertexBuffer.ColorKind);\r\n            }\r\n\r\n            if (parsedMesh.hasMatricesIndices) {\r\n                mesh._delayInfo.push(VertexBuffer.MatricesIndicesKind);\r\n            }\r\n\r\n            if (parsedMesh.hasMatricesWeights) {\r\n                mesh._delayInfo.push(VertexBuffer.MatricesWeightsKind);\r\n            }\r\n\r\n            mesh._delayLoadingFunction = Geometry._ImportGeometry;\r\n\r\n            if (SceneLoaderFlags.ForceFullSceneLoadingForIncremental) {\r\n                mesh._checkDelayState();\r\n            }\r\n        } else if (!skipImportGeometry) {\r\n            Geometry._ImportGeometry(parsedMesh, mesh);\r\n        }\r\n\r\n        // Material\r\n        if (parsedMesh.materialUniqueId) {\r\n            mesh._waitingMaterialId = parsedMesh.materialUniqueId;\r\n        } else if (parsedMesh.materialId) {\r\n            mesh._waitingMaterialId = parsedMesh.materialId;\r\n        }\r\n\r\n        // Morph targets\r\n        if (parsedMesh.morphTargetManagerId > -1) {\r\n            mesh._waitingMorphTargetManagerId = parsedMesh.morphTargetManagerId;\r\n        }\r\n\r\n        // Skeleton\r\n        if (parsedMesh.skeletonId !== undefined && parsedMesh.skeletonId !== null) {\r\n            mesh.skeleton = scene.getLastSkeletonById(parsedMesh.skeletonId); // Back-compat for if this function is called directly\r\n            mesh._waitingSkeletonId = parsedMesh.skeletonId;\r\n            if (parsedMesh.numBoneInfluencers) {\r\n                mesh.numBoneInfluencers = parsedMesh.numBoneInfluencers;\r\n            }\r\n        }\r\n\r\n        if (parsedMesh.skeletonUniqueId !== undefined && parsedMesh.skeletonUniqueId !== null) {\r\n            mesh._waitingSkeletonUniqueId = parsedMesh.skeletonUniqueId;\r\n        }\r\n\r\n        // Animations\r\n        if (parsedMesh.animations) {\r\n            for (let animationIndex = 0; animationIndex < parsedMesh.animations.length; animationIndex++) {\r\n                const parsedAnimation = parsedMesh.animations[animationIndex];\r\n                const internalClass = GetClass(\"BABYLON.Animation\");\r\n                if (internalClass) {\r\n                    mesh.animations.push(internalClass.Parse(parsedAnimation));\r\n                }\r\n            }\r\n            Node.ParseAnimationRanges(mesh, parsedMesh, scene);\r\n        }\r\n\r\n        if (parsedMesh.autoAnimate) {\r\n            scene.beginAnimation(mesh, parsedMesh.autoAnimateFrom, parsedMesh.autoAnimateTo, parsedMesh.autoAnimateLoop, parsedMesh.autoAnimateSpeed || 1.0);\r\n        }\r\n\r\n        // Layer Mask\r\n        if (parsedMesh.layerMask && !isNaN(parsedMesh.layerMask)) {\r\n            mesh.layerMask = Math.abs(parseInt(parsedMesh.layerMask));\r\n        } else {\r\n            mesh.layerMask = 0x0fffffff;\r\n        }\r\n\r\n        // Physics\r\n        if (parsedMesh.physicsImpostor) {\r\n            mesh.physicsImpostor = Mesh._PhysicsImpostorParser(scene, mesh, parsedMesh);\r\n        }\r\n\r\n        // Levels\r\n        if (parsedMesh.lodMeshIds) {\r\n            mesh._waitingData.lods = {\r\n                ids: parsedMesh.lodMeshIds,\r\n                distances: parsedMesh.lodDistances ? parsedMesh.lodDistances : null,\r\n                coverages: parsedMesh.lodCoverages ? parsedMesh.lodCoverages : null,\r\n            };\r\n        }\r\n\r\n        // Instances\r\n        if (parsedMesh.instances) {\r\n            for (let index = 0; index < parsedMesh.instances.length; index++) {\r\n                const parsedInstance = parsedMesh.instances[index];\r\n                const instance = mesh.createInstance(parsedInstance.name);\r\n\r\n                if (parsedInstance.id) {\r\n                    instance.id = parsedInstance.id;\r\n                }\r\n\r\n                if (Tags) {\r\n                    if (parsedInstance.tags) {\r\n                        Tags.AddTagsTo(instance, parsedInstance.tags);\r\n                    } else {\r\n                        Tags.AddTagsTo(instance, parsedMesh.tags);\r\n                    }\r\n                }\r\n\r\n                instance.position = Vector3.FromArray(parsedInstance.position);\r\n\r\n                if (parsedInstance.metadata !== undefined) {\r\n                    instance.metadata = parsedInstance.metadata;\r\n                }\r\n\r\n                if (parsedInstance.parentId !== undefined) {\r\n                    instance._waitingParentId = parsedInstance.parentId;\r\n                }\r\n\r\n                if (parsedInstance.parentInstanceIndex !== undefined) {\r\n                    instance._waitingParentInstanceIndex = parsedInstance.parentInstanceIndex;\r\n                }\r\n\r\n                if (parsedInstance.isEnabled !== undefined && parsedInstance.isEnabled !== null) {\r\n                    instance.setEnabled(parsedInstance.isEnabled);\r\n                }\r\n\r\n                if (parsedInstance.isVisible !== undefined && parsedInstance.isVisible !== null) {\r\n                    instance.isVisible = parsedInstance.isVisible;\r\n                }\r\n\r\n                if (parsedInstance.isPickable !== undefined && parsedInstance.isPickable !== null) {\r\n                    instance.isPickable = parsedInstance.isPickable;\r\n                }\r\n\r\n                if (parsedInstance.rotationQuaternion) {\r\n                    instance.rotationQuaternion = Quaternion.FromArray(parsedInstance.rotationQuaternion);\r\n                } else if (parsedInstance.rotation) {\r\n                    instance.rotation = Vector3.FromArray(parsedInstance.rotation);\r\n                }\r\n\r\n                instance.scaling = Vector3.FromArray(parsedInstance.scaling);\r\n\r\n                if (parsedInstance.checkCollisions != undefined && parsedInstance.checkCollisions != null) {\r\n                    instance.checkCollisions = parsedInstance.checkCollisions;\r\n                }\r\n                if (parsedInstance.pickable != undefined && parsedInstance.pickable != null) {\r\n                    instance.isPickable = parsedInstance.pickable;\r\n                }\r\n                if (parsedInstance.showBoundingBox != undefined && parsedInstance.showBoundingBox != null) {\r\n                    instance.showBoundingBox = parsedInstance.showBoundingBox;\r\n                }\r\n                if (parsedInstance.showSubMeshesBoundingBox != undefined && parsedInstance.showSubMeshesBoundingBox != null) {\r\n                    instance.showSubMeshesBoundingBox = parsedInstance.showSubMeshesBoundingBox;\r\n                }\r\n                if (parsedInstance.alphaIndex != undefined && parsedInstance.showSubMeshesBoundingBox != null) {\r\n                    instance.alphaIndex = parsedInstance.alphaIndex;\r\n                }\r\n\r\n                // Physics\r\n                if (parsedInstance.physicsImpostor) {\r\n                    instance.physicsImpostor = Mesh._PhysicsImpostorParser(scene, instance, parsedInstance);\r\n                }\r\n\r\n                // Actions\r\n                if (parsedInstance.actions !== undefined) {\r\n                    instance._waitingData.actions = parsedInstance.actions;\r\n                }\r\n\r\n                // Animation\r\n                if (parsedInstance.animations) {\r\n                    for (let animationIndex = 0; animationIndex < parsedInstance.animations.length; animationIndex++) {\r\n                        const parsedAnimation = parsedInstance.animations[animationIndex];\r\n                        const internalClass = GetClass(\"BABYLON.Animation\");\r\n                        if (internalClass) {\r\n                            instance.animations.push(internalClass.Parse(parsedAnimation));\r\n                        }\r\n                    }\r\n                    Node.ParseAnimationRanges(instance, parsedInstance, scene);\r\n\r\n                    if (parsedInstance.autoAnimate) {\r\n                        scene.beginAnimation(\r\n                            instance,\r\n                            parsedInstance.autoAnimateFrom,\r\n                            parsedInstance.autoAnimateTo,\r\n                            parsedInstance.autoAnimateLoop,\r\n                            parsedInstance.autoAnimateSpeed || 1.0\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Thin instances\r\n        if (parsedMesh.thinInstances) {\r\n            const thinInstances = parsedMesh.thinInstances;\r\n\r\n            mesh.thinInstanceEnablePicking = !!thinInstances.enablePicking;\r\n\r\n            if (thinInstances.matrixData) {\r\n                mesh.thinInstanceSetBuffer(\"matrix\", new Float32Array(thinInstances.matrixData), 16, false);\r\n\r\n                mesh._thinInstanceDataStorage.matrixBufferSize = thinInstances.matrixBufferSize;\r\n                mesh._thinInstanceDataStorage.instancesCount = thinInstances.instancesCount;\r\n            } else {\r\n                mesh._thinInstanceDataStorage.matrixBufferSize = thinInstances.matrixBufferSize;\r\n            }\r\n\r\n            if (parsedMesh.thinInstances.userThinInstance) {\r\n                const userThinInstance = parsedMesh.thinInstances.userThinInstance;\r\n\r\n                for (const kind in userThinInstance.data) {\r\n                    mesh.thinInstanceSetBuffer(kind, new Float32Array(userThinInstance.data[kind]), userThinInstance.strides[kind], false);\r\n                    mesh._userThinInstanceBuffersStorage.sizes[kind] = userThinInstance.sizes[kind];\r\n                }\r\n            }\r\n        }\r\n\r\n        return mesh;\r\n    }\r\n\r\n    // Skeletons\r\n\r\n    /**\r\n     * Prepare internal position array for software CPU skinning\r\n     * @returns original positions used for CPU skinning. Useful for integrating Morphing with skeletons in same mesh\r\n     */\r\n    public setPositionsForCPUSkinning(): Nullable<Float32Array> {\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n        if (!internalDataInfo._sourcePositions) {\r\n            const source = this.getVerticesData(VertexBuffer.PositionKind);\r\n            if (!source) {\r\n                return internalDataInfo._sourcePositions;\r\n            }\r\n\r\n            internalDataInfo._sourcePositions = new Float32Array(<any>source);\r\n\r\n            if (!this.isVertexBufferUpdatable(VertexBuffer.PositionKind)) {\r\n                this.setVerticesData(VertexBuffer.PositionKind, source, true);\r\n            }\r\n        }\r\n        return internalDataInfo._sourcePositions;\r\n    }\r\n\r\n    /**\r\n     * Prepare internal normal array for software CPU skinning\r\n     * @returns original normals used for CPU skinning. Useful for integrating Morphing with skeletons in same mesh.\r\n     */\r\n    public setNormalsForCPUSkinning(): Nullable<Float32Array> {\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n\r\n        if (!internalDataInfo._sourceNormals) {\r\n            const source = this.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n            if (!source) {\r\n                return internalDataInfo._sourceNormals;\r\n            }\r\n\r\n            internalDataInfo._sourceNormals = new Float32Array(<any>source);\r\n\r\n            if (!this.isVertexBufferUpdatable(VertexBuffer.NormalKind)) {\r\n                this.setVerticesData(VertexBuffer.NormalKind, source, true);\r\n            }\r\n        }\r\n        return internalDataInfo._sourceNormals;\r\n    }\r\n\r\n    /**\r\n     * Updates the vertex buffer by applying transformation from the bones\r\n     * @param skeleton defines the skeleton to apply to current mesh\r\n     * @returns the current mesh\r\n     */\r\n    public applySkeleton(skeleton: Skeleton): Mesh {\r\n        if (!this.geometry) {\r\n            return this;\r\n        }\r\n\r\n        if (this.geometry._softwareSkinningFrameId == this.getScene().getFrameId()) {\r\n            return this;\r\n        }\r\n\r\n        this.geometry._softwareSkinningFrameId = this.getScene().getFrameId();\r\n\r\n        if (!this.isVerticesDataPresent(VertexBuffer.PositionKind)) {\r\n            return this;\r\n        }\r\n        if (!this.isVerticesDataPresent(VertexBuffer.MatricesIndicesKind)) {\r\n            return this;\r\n        }\r\n        if (!this.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind)) {\r\n            return this;\r\n        }\r\n\r\n        const hasNormals = this.isVerticesDataPresent(VertexBuffer.NormalKind);\r\n\r\n        const internalDataInfo = this._internalMeshDataInfo;\r\n\r\n        if (!internalDataInfo._sourcePositions) {\r\n            const submeshes = this.subMeshes.slice();\r\n            this.setPositionsForCPUSkinning();\r\n            this.subMeshes = submeshes;\r\n        }\r\n\r\n        if (hasNormals && !internalDataInfo._sourceNormals) {\r\n            this.setNormalsForCPUSkinning();\r\n        }\r\n\r\n        // positionsData checks for not being Float32Array will only pass at most once\r\n        let positionsData = this.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        if (!positionsData) {\r\n            return this;\r\n        }\r\n\r\n        if (!(positionsData instanceof Float32Array)) {\r\n            positionsData = new Float32Array(positionsData);\r\n        }\r\n\r\n        // normalsData checks for not being Float32Array will only pass at most once\r\n        let normalsData = this.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n        if (hasNormals) {\r\n            if (!normalsData) {\r\n                return this;\r\n            }\r\n\r\n            if (!(normalsData instanceof Float32Array)) {\r\n                normalsData = new Float32Array(normalsData);\r\n            }\r\n        }\r\n\r\n        const matricesIndicesData = this.getVerticesData(VertexBuffer.MatricesIndicesKind);\r\n        const matricesWeightsData = this.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n\r\n        if (!matricesWeightsData || !matricesIndicesData) {\r\n            return this;\r\n        }\r\n\r\n        const needExtras = this.numBoneInfluencers > 4;\r\n        const matricesIndicesExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;\r\n        const matricesWeightsExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;\r\n\r\n        const skeletonMatrices = skeleton.getTransformMatrices(this);\r\n\r\n        const tempVector3 = Vector3.Zero();\r\n        const finalMatrix = new Matrix();\r\n        const tempMatrix = new Matrix();\r\n\r\n        let matWeightIdx = 0;\r\n        let inf: number;\r\n        for (let index = 0; index < positionsData.length; index += 3, matWeightIdx += 4) {\r\n            let weight: number;\r\n            for (inf = 0; inf < 4; inf++) {\r\n                weight = matricesWeightsData[matWeightIdx + inf];\r\n                if (weight > 0) {\r\n                    Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[matWeightIdx + inf] * 16), weight, tempMatrix);\r\n                    finalMatrix.addToSelf(tempMatrix);\r\n                }\r\n            }\r\n            if (needExtras) {\r\n                for (inf = 0; inf < 4; inf++) {\r\n                    weight = matricesWeightsExtraData![matWeightIdx + inf];\r\n                    if (weight > 0) {\r\n                        Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData![matWeightIdx + inf] * 16), weight, tempMatrix);\r\n                        finalMatrix.addToSelf(tempMatrix);\r\n                    }\r\n                }\r\n            }\r\n\r\n            Vector3.TransformCoordinatesFromFloatsToRef(\r\n                internalDataInfo._sourcePositions![index],\r\n                internalDataInfo._sourcePositions![index + 1],\r\n                internalDataInfo._sourcePositions![index + 2],\r\n                finalMatrix,\r\n                tempVector3\r\n            );\r\n            tempVector3.toArray(positionsData, index);\r\n\r\n            if (hasNormals) {\r\n                Vector3.TransformNormalFromFloatsToRef(\r\n                    internalDataInfo._sourceNormals![index],\r\n                    internalDataInfo._sourceNormals![index + 1],\r\n                    internalDataInfo._sourceNormals![index + 2],\r\n                    finalMatrix,\r\n                    tempVector3\r\n                );\r\n                tempVector3.toArray(normalsData!, index);\r\n            }\r\n\r\n            finalMatrix.reset();\r\n        }\r\n\r\n        this.updateVerticesData(VertexBuffer.PositionKind, positionsData);\r\n        if (hasNormals) {\r\n            this.updateVerticesData(VertexBuffer.NormalKind, normalsData!);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    // Tools\r\n\r\n    /**\r\n     * Returns an object containing a min and max Vector3 which are the minimum and maximum vectors of each mesh bounding box from the passed array, in the world coordinates\r\n     * @param meshes defines the list of meshes to scan\r\n     * @returns an object `{min:` Vector3`, max:` Vector3`}`\r\n     */\r\n    public static MinMax(meshes: AbstractMesh[]): { min: Vector3; max: Vector3 } {\r\n        let minVector: Nullable<Vector3> = null;\r\n        let maxVector: Nullable<Vector3> = null;\r\n\r\n        for (const mesh of meshes) {\r\n            const boundingInfo = mesh.getBoundingInfo();\r\n\r\n            const boundingBox = boundingInfo.boundingBox;\r\n            if (!minVector || !maxVector) {\r\n                minVector = boundingBox.minimumWorld.clone();\r\n                maxVector = boundingBox.maximumWorld.clone();\r\n            } else {\r\n                minVector.minimizeInPlace(boundingBox.minimumWorld);\r\n                maxVector.maximizeInPlace(boundingBox.maximumWorld);\r\n            }\r\n        }\r\n\r\n        if (!minVector || !maxVector) {\r\n            return {\r\n                min: Vector3.Zero(),\r\n                max: Vector3.Zero(),\r\n            };\r\n        }\r\n\r\n        return {\r\n            min: minVector,\r\n            max: maxVector,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Returns the center of the `{min:` Vector3`, max:` Vector3`}` or the center of MinMax vector3 computed from a mesh array\r\n     * @param meshesOrMinMaxVector could be an array of meshes or a `{min:` Vector3`, max:` Vector3`}` object\r\n     * @returns a vector3\r\n     */\r\n    public static Center(meshesOrMinMaxVector: { min: Vector3; max: Vector3 } | AbstractMesh[]): Vector3 {\r\n        const minMaxVector = meshesOrMinMaxVector instanceof Array ? Mesh.MinMax(meshesOrMinMaxVector) : meshesOrMinMaxVector;\r\n        return Vector3.Center(minMaxVector.min, minMaxVector.max);\r\n    }\r\n\r\n    /**\r\n     * Merge the array of meshes into a single mesh for performance reasons.\r\n     * @param meshes array of meshes with the vertices to merge. Entries cannot be empty meshes.\r\n     * @param disposeSource when true (default), dispose of the vertices from the source meshes.\r\n     * @param allow32BitsIndices when the sum of the vertices \\> 64k, this must be set to true.\r\n     * @param meshSubclass (optional) can be set to a Mesh where the merged vertices will be inserted.\r\n     * @param subdivideWithSubMeshes when true (false default), subdivide mesh into subMeshes.\r\n     * @param multiMultiMaterials when true (false default), subdivide mesh into subMeshes with multiple materials, ignores subdivideWithSubMeshes.\r\n     * @returns a new mesh\r\n     */\r\n    public static MergeMeshes(\r\n        meshes: Array<Mesh>,\r\n        disposeSource = true,\r\n        allow32BitsIndices?: boolean,\r\n        meshSubclass?: Mesh,\r\n        subdivideWithSubMeshes?: boolean,\r\n        multiMultiMaterials?: boolean\r\n    ) {\r\n        return runCoroutineSync(Mesh._MergeMeshesCoroutine(meshes, disposeSource, allow32BitsIndices, meshSubclass, subdivideWithSubMeshes, multiMultiMaterials, false));\r\n    }\r\n\r\n    /**\r\n     * Merge the array of meshes into a single mesh for performance reasons.\r\n     * @param meshes array of meshes with the vertices to merge. Entries cannot be empty meshes.\r\n     * @param disposeSource when true (default), dispose of the vertices from the source meshes.\r\n     * @param allow32BitsIndices when the sum of the vertices \\> 64k, this must be set to true.\r\n     * @param meshSubclass (optional) can be set to a Mesh where the merged vertices will be inserted.\r\n     * @param subdivideWithSubMeshes when true (false default), subdivide mesh into subMeshes.\r\n     * @param multiMultiMaterials when true (false default), subdivide mesh into subMeshes with multiple materials, ignores subdivideWithSubMeshes.\r\n     * @returns a new mesh\r\n     */\r\n    public static async MergeMeshesAsync(\r\n        meshes: Array<Mesh>,\r\n        disposeSource = true,\r\n        allow32BitsIndices?: boolean,\r\n        meshSubclass?: Mesh,\r\n        subdivideWithSubMeshes?: boolean,\r\n        multiMultiMaterials?: boolean\r\n    ) {\r\n        return await runCoroutineAsync(\r\n            Mesh._MergeMeshesCoroutine(meshes, disposeSource, allow32BitsIndices, meshSubclass, subdivideWithSubMeshes, multiMultiMaterials, true),\r\n            createYieldingScheduler()\r\n        );\r\n    }\r\n\r\n    private static *_MergeMeshesCoroutine(\r\n        meshes: Array<Mesh>,\r\n        disposeSource = true,\r\n        allow32BitsIndices: boolean | undefined,\r\n        meshSubclass: Mesh | undefined,\r\n        subdivideWithSubMeshes: boolean | undefined,\r\n        multiMultiMaterials: boolean | undefined,\r\n        isAsync: boolean\r\n    ): Coroutine<Nullable<Mesh>> {\r\n        // Remove any null/undefined entries from the mesh array\r\n        meshes = meshes.filter(Boolean);\r\n\r\n        if (meshes.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        let index: number;\r\n        if (!allow32BitsIndices) {\r\n            let totalVertices = 0;\r\n\r\n            // Counting vertices\r\n            for (index = 0; index < meshes.length; index++) {\r\n                totalVertices += meshes[index].getTotalVertices();\r\n\r\n                if (totalVertices >= 65536) {\r\n                    Logger.Warn(\"Cannot merge meshes because resulting mesh will have more than 65536 vertices. Please use allow32BitsIndices = true to use 32 bits indices\");\r\n                    return null;\r\n                }\r\n            }\r\n        }\r\n        // Preserve the caller's first mesh for naming and property copying,\r\n        // since sorting below may reorder the array.\r\n        const source = meshes[0];\r\n\r\n        if (multiMultiMaterials) {\r\n            subdivideWithSubMeshes = false;\r\n            // Sort meshes by material so that meshes sharing the same material are adjacent.\r\n            // This produces contiguous index ranges per material, enabling submesh consolidation below.\r\n            meshes.sort((a, b) => (a.material?.uniqueId ?? -1) - (b.material?.uniqueId ?? -1));\r\n        }\r\n        const materialArray: Array<Material> = new Array<Material>();\r\n        const materialIndexArray: Array<number> = new Array<number>();\r\n        // Merge\r\n        const indiceArray: Array<{ start: number; count: number }> = new Array<{ start: number; count: number }>();\r\n        const currentsideOrientation = meshes[0].sideOrientation;\r\n\r\n        for (index = 0; index < meshes.length; index++) {\r\n            const mesh = meshes[index];\r\n            if (mesh.isAnInstance) {\r\n                Logger.Warn(\"Cannot merge instance meshes.\");\r\n                return null;\r\n            }\r\n\r\n            if (currentsideOrientation !== mesh.sideOrientation) {\r\n                Logger.Warn(\"Cannot merge meshes with different sideOrientation values.\");\r\n                return null;\r\n            }\r\n\r\n            if (subdivideWithSubMeshes || multiMultiMaterials) {\r\n                const indexOffset = indiceArray.reduce((accumulator, currentValue) => {\r\n                    return Math.max(accumulator, currentValue.start + currentValue.count);\r\n                }, 0);\r\n\r\n                if (multiMultiMaterials) {\r\n                    if (mesh.material) {\r\n                        const material = mesh.material;\r\n                        if (material instanceof MultiMaterial) {\r\n                            for (let matIndex = 0; matIndex < material.subMaterials.length; matIndex++) {\r\n                                if (materialArray.indexOf(<Material>material.subMaterials[matIndex]) < 0) {\r\n                                    materialArray.push(<Material>material.subMaterials[matIndex]);\r\n                                }\r\n                            }\r\n                            for (let subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {\r\n                                materialIndexArray.push(materialArray.indexOf(<Material>material.subMaterials[mesh.subMeshes[subIndex].materialIndex]));\r\n                                indiceArray.push({ start: indexOffset + mesh.subMeshes[subIndex].indexStart, count: mesh.subMeshes[subIndex].indexCount });\r\n                            }\r\n                        } else {\r\n                            if (materialArray.indexOf(material) < 0) {\r\n                                materialArray.push(material);\r\n                            }\r\n                            for (let subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {\r\n                                materialIndexArray.push(materialArray.indexOf(material));\r\n                                indiceArray.push({ start: indexOffset + mesh.subMeshes[subIndex].indexStart, count: mesh.subMeshes[subIndex].indexCount });\r\n                            }\r\n                        }\r\n                    } else {\r\n                        for (let subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {\r\n                            materialIndexArray.push(0);\r\n                            indiceArray.push({ start: indexOffset + mesh.subMeshes[subIndex].indexStart, count: mesh.subMeshes[subIndex].indexCount });\r\n                        }\r\n                    }\r\n                } else {\r\n                    indiceArray.push({ start: indexOffset, count: mesh.getTotalIndices() });\r\n                }\r\n            }\r\n        }\r\n\r\n        // Consolidate consecutive submesh entries that share the same material and\r\n        // have contiguous index ranges. Same-material entries are not guaranteed to\r\n        // be gap-free, so only merge when the next range starts exactly where the\r\n        // current one ends.\r\n        if (multiMultiMaterials && indiceArray.length > 1) {\r\n            let writeIdx = 0;\r\n            for (let readIdx = 1; readIdx < indiceArray.length; readIdx++) {\r\n                const previousIndice = indiceArray[writeIdx];\r\n                const currentIndice = indiceArray[readIdx];\r\n                if (materialIndexArray[readIdx] === materialIndexArray[writeIdx] && previousIndice.start + previousIndice.count === currentIndice.start) {\r\n                    // Extend the previous entry only when this range is contiguous\r\n                    previousIndice.count += currentIndice.count;\r\n                } else {\r\n                    writeIdx++;\r\n                    indiceArray[writeIdx] = currentIndice;\r\n                    materialIndexArray[writeIdx] = materialIndexArray[readIdx];\r\n                }\r\n            }\r\n            indiceArray.length = writeIdx + 1;\r\n            materialIndexArray.length = writeIdx + 1;\r\n        }\r\n\r\n        const getVertexDataFromMesh = (mesh: Mesh) => {\r\n            const wm = mesh.computeWorldMatrix(true);\r\n            const vertexData = VertexData.ExtractFromMesh(mesh, false, false);\r\n            return { vertexData, transform: wm };\r\n        };\r\n\r\n        const { vertexData: sourceVertexData, transform: sourceTransform } = getVertexDataFromMesh(meshes[0]);\r\n        if (isAsync) {\r\n            yield;\r\n        }\r\n\r\n        const meshVertexDatas = new Array<{ vertexData: VertexData; transform?: Matrix }>(meshes.length - 1);\r\n        for (let i = 1; i < meshes.length; i++) {\r\n            meshVertexDatas[i - 1] = getVertexDataFromMesh(meshes[i]);\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n        }\r\n\r\n        const mergeCoroutine = sourceVertexData._mergeCoroutine(sourceTransform, meshVertexDatas, allow32BitsIndices, isAsync, !disposeSource);\r\n        let mergeCoroutineStep = mergeCoroutine.next();\r\n        while (!mergeCoroutineStep.done) {\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n            mergeCoroutineStep = mergeCoroutine.next();\r\n        }\r\n        const vertexData = mergeCoroutineStep.value;\r\n\r\n        if (!meshSubclass) {\r\n            meshSubclass = new Mesh(source.name + \"_merged\", source.getScene());\r\n        }\r\n\r\n        const applyToCoroutine = vertexData._applyToCoroutine(meshSubclass, undefined, isAsync);\r\n        let applyToCoroutineStep = applyToCoroutine.next();\r\n        while (!applyToCoroutineStep.done) {\r\n            if (isAsync) {\r\n                yield;\r\n            }\r\n            applyToCoroutineStep = applyToCoroutine.next();\r\n        }\r\n\r\n        // Setting properties\r\n        meshSubclass.checkCollisions = source.checkCollisions;\r\n        meshSubclass.sideOrientation = source.sideOrientation;\r\n\r\n        // Cleaning\r\n        if (disposeSource) {\r\n            for (index = 0; index < meshes.length; index++) {\r\n                meshes[index].dispose();\r\n            }\r\n        }\r\n\r\n        // Subdivide\r\n        if (subdivideWithSubMeshes || multiMultiMaterials) {\r\n            //-- removal of global submesh\r\n            meshSubclass.releaseSubMeshes();\r\n            index = 0;\r\n\r\n            //-- apply subdivision according to index table\r\n            while (index < indiceArray.length) {\r\n                SubMesh.CreateFromIndices(0, indiceArray[index].start, indiceArray[index].count, meshSubclass, undefined, false);\r\n                index++;\r\n            }\r\n\r\n            for (const subMesh of meshSubclass.subMeshes) {\r\n                subMesh.refreshBoundingInfo();\r\n            }\r\n\r\n            meshSubclass.computeWorldMatrix(true);\r\n        }\r\n\r\n        if (multiMultiMaterials) {\r\n            const newMultiMaterial = new MultiMaterial(source.name + \"_merged\", source.getScene());\r\n            newMultiMaterial.subMaterials = materialArray;\r\n            for (let subIndex = 0; subIndex < meshSubclass.subMeshes.length; subIndex++) {\r\n                meshSubclass.subMeshes[subIndex].materialIndex = materialIndexArray[subIndex];\r\n            }\r\n            meshSubclass.material = newMultiMaterial;\r\n        } else {\r\n            meshSubclass.material = source.material;\r\n        }\r\n\r\n        return meshSubclass;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public addInstance(instance: InstancedMesh) {\r\n        instance._indexInSourceMeshInstanceArray = this.instances.length;\r\n        this.instances.push(instance);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public removeInstance(instance: InstancedMesh) {\r\n        // Remove from mesh\r\n        const index = instance._indexInSourceMeshInstanceArray;\r\n        if (index != -1) {\r\n            if (index !== this.instances.length - 1) {\r\n                const last = this.instances[this.instances.length - 1];\r\n                this.instances[index] = last;\r\n                last._indexInSourceMeshInstanceArray = index;\r\n            }\r\n\r\n            instance._indexInSourceMeshInstanceArray = -1;\r\n            this.instances.pop();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _shouldConvertRHS() {\r\n        return this._scene.useRightHandedSystem && this.sideOrientation === Material.CounterClockWiseSideOrientation;\r\n    }\r\n\r\n    /** @internal */\r\n    public _getRenderingFillMode(fillMode: number): number {\r\n        const scene = this.getScene();\r\n\r\n        if (scene.forcePointsCloud) {\r\n            return Material.PointFillMode;\r\n        }\r\n\r\n        if (scene.forceWireframe) {\r\n            return Material.WireFrameFillMode;\r\n        }\r\n\r\n        return this.overrideRenderingFillMode ?? fillMode;\r\n    }\r\n\r\n    // deprecated methods\r\n    /**\r\n     * Sets the mesh material by the material or multiMaterial `id` property\r\n     * @param id is a string identifying the material or the multiMaterial\r\n     * @returns the current mesh\r\n     * @deprecated Please use MeshBuilder instead Please use setMaterialById instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public setMaterialByID(id: string): Mesh {\r\n        return this.setMaterialById(id);\r\n    }\r\n\r\n    /**\r\n     * Creates a ribbon mesh.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _pathArray is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry.\r\n     * @param _closeArray creates a seam between the first and the last paths of the path array (default is false)\r\n     * @param _closePath creates a seam between the first and the last points of each path of the path array\r\n     * @param _offset is taken in account only if the `pathArray` is containing a single path\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @param _instance defines an instance of an existing Ribbon object to be updated with the passed `pathArray` parameter (https://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#ribbon)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateRibbon(\r\n        _name: string,\r\n        _pathArray: Vector3[][],\r\n        _closeArray: boolean,\r\n        _closePath: boolean,\r\n        _offset: number,\r\n        _scene?: Scene,\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number,\r\n        _instance?: Mesh\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a plane polygonal mesh.  By default, this is a disc.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _radius sets the radius size (float) of the polygon (default 0.5)\r\n     * @param _tessellation sets the number of polygon sides (positive integer, default 64). So a tessellation valued to 3 will build a triangle, to 4 a square, etc\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateDisc(_name: string, _radius: number, _tessellation: number, _scene: Nullable<Scene>, _updatable?: boolean, _sideOrientation?: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a box mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _size sets the size (float) of each box side (default 1)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateBox(_name: string, _size: number, _scene: Nullable<Scene>, _updatable?: boolean, _sideOrientation?: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a sphere mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _segments sets the sphere number of horizontal stripes (positive integer, default 32)\r\n     * @param _diameter sets the diameter size (float) of the sphere (default 1)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateSphere(_name: string, _segments: number, _diameter: number, _scene?: Scene, _updatable?: boolean, _sideOrientation?: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a hemisphere mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _segments sets the sphere number of horizontal stripes (positive integer, default 32)\r\n     * @param _diameter sets the diameter size (float) of the sphere (default 1)\r\n     * @param _scene defines the hosting scene\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateHemisphere(_name: string, _segments: number, _diameter: number, _scene?: Scene): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a cylinder or a cone mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _height sets the height size (float) of the cylinder/cone (float, default 2)\r\n     * @param _diameterTop set the top cap diameter (floats, default 1)\r\n     * @param _diameterBottom set the bottom cap diameter (floats, default 1). This value can't be zero\r\n     * @param _tessellation sets the number of cylinder sides (positive integer, default 24). Set it to 3 to get a prism for instance\r\n     * @param _subdivisions sets the number of rings along the cylinder height (positive integer, default 1)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateCylinder(\r\n        _name: string,\r\n        _height: number,\r\n        _diameterTop: number,\r\n        _diameterBottom: number,\r\n        _tessellation: number,\r\n        _subdivisions: any,\r\n        _scene?: Scene,\r\n        _updatable?: any,\r\n        _sideOrientation?: number\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    // Torus  (Code from SharpDX.org)\r\n    /**\r\n     * Creates a torus mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _diameter sets the diameter size (float) of the torus (default 1)\r\n     * @param _thickness sets the diameter size of the tube of the torus (float, default 0.5)\r\n     * @param _tessellation sets the number of torus sides (positive integer, default 16)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateTorus(_name: string, _diameter: number, _thickness: number, _tessellation: number, _scene?: Scene, _updatable?: boolean, _sideOrientation?: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a torus knot mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _radius sets the global radius size (float) of the torus knot (default 2)\r\n     * @param _tube sets the diameter size of the tube of the torus (float, default 0.5)\r\n     * @param _radialSegments sets the number of sides on each tube segments (positive integer, default 32)\r\n     * @param _tubularSegments sets the number of tubes to decompose the knot into (positive integer, default 32)\r\n     * @param _p the number of windings on X axis (positive integers, default 2)\r\n     * @param _q the number of windings on Y axis (positive integers, default 3)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateTorusKnot(\r\n        _name: string,\r\n        _radius: number,\r\n        _tube: number,\r\n        _radialSegments: number,\r\n        _tubularSegments: number,\r\n        _p: number,\r\n        _q: number,\r\n        _scene?: Scene,\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a line mesh..\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _points is an array successive Vector3\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _instance is an instance of an existing LineMesh object to be updated with the passed `points` parameter (https://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#lines-and-dashedlines).\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateLines(_name: string, _points: Vector3[], _scene: Nullable<Scene>, _updatable: boolean, _instance?: Nullable<LinesMesh>): LinesMesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a dashed line mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _points is an array successive Vector3\r\n     * @param _dashSize is the size of the dashes relatively the dash number (positive float, default 3)\r\n     * @param _gapSize is the size of the gap between two successive dashes relatively the dash number (positive float, default 1)\r\n     * @param _dashNb is the intended total number of dashes (positive integer, default 200)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _instance is an instance of an existing LineMesh object to be updated with the passed `points` parameter (https://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#lines-and-dashedlines)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateDashedLines(\r\n        _name: string,\r\n        _points: Vector3[],\r\n        _dashSize: number,\r\n        _gapSize: number,\r\n        _dashNb: number,\r\n        _scene: Nullable<Scene>,\r\n        _updatable?: boolean,\r\n        _instance?: LinesMesh\r\n    ): LinesMesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a polygon mesh.Please consider using the same method from the MeshBuilder class instead\r\n     * The polygon's shape will depend on the input parameters and is constructed parallel to a ground mesh.\r\n     * The parameter `shape` is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors.\r\n     * You can set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.\r\n     * Remember you can only change the shape positions, not their number when updating a polygon.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#non-regular-polygon\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _shape is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors\r\n     * @param _scene defines the hosting scene\r\n     * @param _holes is a required array of arrays of successive Vector3 used to defines holes in the polygon\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @param _earcutInjection can be used to inject your own earcut reference\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreatePolygon(\r\n        _name: string,\r\n        _shape: Vector3[],\r\n        _scene: Scene,\r\n        _holes?: Vector3[][],\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number,\r\n        _earcutInjection?: any\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates an extruded polygon mesh, with depth in the Y direction..\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#extruded-non-regular-polygon\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _shape is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors\r\n     * @param _depth defines the height of extrusion\r\n     * @param _scene defines the hosting scene\r\n     * @param _holes is a required array of arrays of successive Vector3 used to defines holes in the polygon\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @param _earcutInjection can be used to inject your own earcut reference\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static ExtrudePolygon(\r\n        _name: string,\r\n        _shape: Vector3[],\r\n        _depth: number,\r\n        _scene: Scene,\r\n        _holes?: Vector3[][],\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number,\r\n        _earcutInjection?: any\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates an extruded shape mesh.\r\n     * The extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#extruded-shapes\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _shape is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis\r\n     * @param _path is a required array of successive Vector3. This is the axis curve the shape is extruded along\r\n     * @param _scale is the value to scale the shape\r\n     * @param _rotation is the angle value to rotate the shape each step (each path point), from the former step (so rotation added each step) along the curve\r\n     * @param _cap sets the way the extruded shape is capped. Possible values : Mesh.NO_CAP (default), Mesh.CAP_START, Mesh.CAP_END, Mesh.CAP_ALL\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @param _instance is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters (https://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#extruded-shape)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static ExtrudeShape(\r\n        _name: string,\r\n        _shape: Vector3[],\r\n        _path: Vector3[],\r\n        _scale: number,\r\n        _rotation: number,\r\n        _cap: number,\r\n        _scene: Nullable<Scene>,\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number,\r\n        _instance?: Mesh\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates an custom extruded shape mesh.\r\n     * The custom extrusion is a parametric shape.\r\n     * It has no predefined shape. Its final shape will depend on the input parameters.\r\n     *\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#extruded-shapes\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _shape is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis\r\n     * @param _path is a required array of successive Vector3. This is the axis curve the shape is extruded along\r\n     * @param _scaleFunction is a custom Javascript function called on each path point\r\n     * @param _rotationFunction is a custom Javascript function called on each path point\r\n     * @param _ribbonCloseArray forces the extrusion underlying ribbon to close all the paths in its `pathArray`\r\n     * @param _ribbonClosePath forces the extrusion underlying ribbon to close its `pathArray`\r\n     * @param _cap sets the way the extruded shape is capped. Possible values : Mesh.NO_CAP (default), Mesh.CAP_START, Mesh.CAP_END, Mesh.CAP_ALL\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @param _instance is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters (https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#extruded-shape)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static ExtrudeShapeCustom(\r\n        _name: string,\r\n        _shape: Vector3[],\r\n        _path: Vector3[],\r\n        _scaleFunction: Nullable<{ (i: number, distance: number): number }>,\r\n        _rotationFunction: Nullable<{ (i: number, distance: number): number }>,\r\n        _ribbonCloseArray: boolean,\r\n        _ribbonClosePath: boolean,\r\n        _cap: number,\r\n        _scene: Scene,\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number,\r\n        _instance?: Mesh\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates lathe mesh.\r\n     * The lathe is a shape with a symmetry axis : a 2D model shape is rotated around this axis to design the lathe.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _shape is a required array of successive Vector3. This array depicts the shape to be rotated in its local space : the shape must be designed in the xOy plane and will be rotated around the Y axis. It's usually a 2D shape, so the Vector3 z coordinates are often set to zero\r\n     * @param _radius is the radius value of the lathe\r\n     * @param _tessellation is the side number of the lathe.\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateLathe(_name: string, _shape: Vector3[], _radius: number, _tessellation: number, _scene: Scene, _updatable?: boolean, _sideOrientation?: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a plane mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _size sets the size (float) of both sides of the plane at once (default 1)\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreatePlane(_name: string, _size: number, _scene: Scene, _updatable?: boolean, _sideOrientation?: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a ground mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _width set the width of the ground\r\n     * @param _height set the height of the ground\r\n     * @param _subdivisions sets the number of subdivisions per side\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateGround(_name: string, _width: number, _height: number, _subdivisions: number, _scene?: Scene, _updatable?: boolean): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a tiled ground mesh.\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _xmin set the ground minimum X coordinate\r\n     * @param _zmin set the ground minimum Y coordinate\r\n     * @param _xmax set the ground maximum X coordinate\r\n     * @param _zmax set the ground maximum Z coordinate\r\n     * @param _subdivisions is an object `{w: positive integer, h: positive integer}` (default `{w: 6, h: 6}`). `w` and `h` are the numbers of subdivisions on the ground width and height. Each subdivision is called a tile\r\n     * @param _precision is an object `{w: positive integer, h: positive integer}` (default `{w: 2, h: 2}`). `w` and `h` are the numbers of subdivisions on the ground width and height of each tile\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateTiledGround(\r\n        _name: string,\r\n        _xmin: number,\r\n        _zmin: number,\r\n        _xmax: number,\r\n        _zmax: number,\r\n        _subdivisions: { w: number; h: number },\r\n        _precision: { w: number; h: number },\r\n        _scene: Scene,\r\n        _updatable?: boolean\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a ground mesh from a height map.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/height_map\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _url sets the URL of the height map image resource\r\n     * @param _width set the ground width size\r\n     * @param _height set the ground height size\r\n     * @param _subdivisions sets the number of subdivision per side\r\n     * @param _minHeight is the minimum altitude on the ground\r\n     * @param _maxHeight is the maximum altitude on the ground\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _onReady  is a callback function that will be called  once the mesh is built (the height map download can last some time)\r\n     * @param _alphaFilter will filter any data where the alpha channel is below this value, defaults 0 (all data visible)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateGroundFromHeightMap(\r\n        _name: string,\r\n        _url: string,\r\n        _width: number,\r\n        _height: number,\r\n        _subdivisions: number,\r\n        _minHeight: number,\r\n        _maxHeight: number,\r\n        _scene: Scene,\r\n        _updatable?: boolean,\r\n        _onReady?: (mesh: GroundMesh) => void,\r\n        _alphaFilter?: number\r\n    ): GroundMesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a tube mesh.\r\n     * The tube is a parametric shape.\r\n     * It has no predefined shape. Its final shape will depend on the input parameters.\r\n     *\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _path is a required array of successive Vector3. It is the curve used as the axis of the tube\r\n     * @param _radius sets the tube radius size\r\n     * @param _tessellation is the number of sides on the tubular surface\r\n     * @param _radiusFunction is a custom function. If it is not null, it overrides the parameter `radius`. This function is called on each point of the tube path and is passed the index `i` of the i-th point and the distance of this point from the first point of the path\r\n     * @param _cap sets the way the extruded shape is capped. Possible values : Mesh.NO_CAP (default), Mesh.CAP_START, Mesh.CAP_END, Mesh.CAP_ALL\r\n     * @param _scene defines the hosting scene\r\n     * @param _updatable defines if the mesh must be flagged as updatable\r\n     * @param _sideOrientation defines the mesh side orientation (https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation)\r\n     * @param _instance is an instance of an existing Tube object to be updated with the passed `pathArray` parameter (https://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#tube)\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateTube(\r\n        _name: string,\r\n        _path: Vector3[],\r\n        _radius: number,\r\n        _tessellation: number,\r\n        _radiusFunction: { (i: number, distance: number): number },\r\n        _cap: number,\r\n        _scene: Scene,\r\n        _updatable?: boolean,\r\n        _sideOrientation?: number,\r\n        _instance?: Mesh\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a polyhedron mesh.\r\n     *.\r\n     * * The parameter `type` (positive integer, max 14, default 0) sets the polyhedron type to build among the 15 embedded types. Please refer to the type sheet in the tutorial to choose the wanted type\r\n     * * The parameter `size` (positive float, default 1) sets the polygon size\r\n     * * You can overwrite the `size` on each dimension bu using the parameters `sizeX`, `sizeY` or `sizeZ` (positive floats, default to `size` value)\r\n     * * You can build other polyhedron types than the 15 embbeded ones by setting the parameter `custom` (`polyhedronObject`, default null). If you set the parameter `custom`, this overwrittes the parameter `type`\r\n     * * A `polyhedronObject` is a formatted javascript object. You'll find a full file with pre-set polyhedra here : https://github.com/BabylonJS/Extensions/tree/master/Polyhedron\r\n     * * You can set the color and the UV of each side of the polyhedron with the parameters `faceColors` (Color4, default `(1, 1, 1, 1)`) and faceUV (Vector4, default `(0, 0, 1, 1)`)\r\n     * * To understand how to set `faceUV` or `faceColors`, please read this by considering the right number of faces of your polyhedron, instead of only 6 for the box : https://doc.babylonjs.com/features/featuresDeepDive/materials/using/texturePerBoxFace\r\n     * * The parameter `flat` (boolean, default true). If set to false, it gives the polyhedron a single global face, so less vertices and shared normals. In this case, `faceColors` and `faceUV` are ignored\r\n     * * You can also set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n     * @param _name defines the name of the mesh to create\r\n     * @param _options defines the options used to create the mesh\r\n     * @param _scene defines the hosting scene\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreatePolyhedron(\r\n        _name: string,\r\n        _options: {\r\n            type?: number;\r\n            size?: number;\r\n            sizeX?: number;\r\n            sizeY?: number;\r\n            sizeZ?: number;\r\n            custom?: any;\r\n            faceUV?: Vector4[];\r\n            faceColors?: Color4[];\r\n            updatable?: boolean;\r\n            sideOrientation?: number;\r\n        },\r\n        _scene: Scene\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a sphere based upon an icosahedron with 20 triangular faces which can be subdivided\r\n     * * The parameter `radius` sets the radius size (float) of the icosphere (default 1)\r\n     * * You can set some different icosphere dimensions, for instance to build an ellipsoid, by using the parameters `radiusX`, `radiusY` and `radiusZ` (all by default have the same value than `radius`)\r\n     * * The parameter `subdivisions` sets the number of subdivisions (positive integer, default 4). The more subdivisions, the more faces on the icosphere whatever its size\r\n     * * The parameter `flat` (boolean, default true) gives each side its own normals. Set it to false to get a smooth continuous light reflection on the surface\r\n     * * You can also set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra#icosphere\r\n     * @param _name defines the name of the mesh\r\n     * @param _options defines the options used to create the mesh\r\n     * @param _scene defines the hosting scene\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateIcoSphere(\r\n        _name: string,\r\n        _options: { radius?: number; flat?: boolean; subdivisions?: number; sideOrientation?: number; updatable?: boolean },\r\n        _scene: Scene\r\n    ): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Creates a decal mesh.\r\n     *.\r\n     * A decal is a mesh usually applied as a model onto the surface of another mesh\r\n     * @param _name  defines the name of the mesh\r\n     * @param _sourceMesh defines the mesh receiving the decal\r\n     * @param _position sets the position of the decal in world coordinates\r\n     * @param _normal sets the normal of the mesh where the decal is applied onto in world coordinates\r\n     * @param _size sets the decal scaling\r\n     * @param _angle sets the angle to rotate the decal\r\n     * @returns a new Mesh\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateDecal(_name: string, _sourceMesh: AbstractMesh, _position: Vector3, _normal: Vector3, _size: Vector3, _angle: number): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /** Creates a Capsule Mesh\r\n     * @param _name defines the name of the mesh.\r\n     * @param _options the constructors options used to shape the mesh.\r\n     * @param _scene defines the scene the mesh is scoped to.\r\n     * @returns the capsule mesh\r\n     * @see https://doc.babylonjs.com/how_to/capsule_shape\r\n     * @deprecated Please use MeshBuilder instead\r\n     */\r\n    public static CreateCapsule(_name: string, _options: ICreateCapsuleOptions, _scene: Scene): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n\r\n    /**\r\n     * Extends a mesh to a Goldberg mesh\r\n     * Warning  the mesh to convert MUST be an import of a perviously exported Goldberg mesh\r\n     * @param _mesh the mesh to convert\r\n     * @returns the extended mesh\r\n     * @deprecated Please use ExtendMeshToGoldberg instead\r\n     */\r\n    public static ExtendToGoldberg(_mesh: Mesh): Mesh {\r\n        throw new Error(\"Import MeshBuilder to populate this function\");\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.Mesh\", Mesh);\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\n\r\nMesh.prototype.registerInstancedBuffer ??= _MissingSideEffect(\"Mesh\", \"registerInstancedBuffer\") as any;\r\nMesh.prototype.simplify ??= _MissingSideEffect(\"Mesh\", \"simplify\") as any;\r\nMesh.prototype.thinInstanceAdd ??= _MissingSideEffect(\"Mesh\", \"thinInstanceAdd\") as any;\r\nMesh.prototype.thinInstanceAddSelf ??= _MissingSideEffect(\"Mesh\", \"thinInstanceAddSelf\") as any;\r\nMesh.prototype.thinInstanceRegisterAttribute ??= _MissingSideEffect(\"Mesh\", \"thinInstanceRegisterAttribute\") as any;\r\nMesh.prototype.thinInstanceSetMatrixAt ??= _MissingSideEffect(\"Mesh\", \"thinInstanceSetMatrixAt\") as any;\r\nMesh.prototype.thinInstanceSetAttributeAt ??= _MissingSideEffect(\"Mesh\", \"thinInstanceSetAttributeAt\") as any;\r\nMesh.prototype.thinInstanceSetBuffer ??= _MissingSideEffect(\"Mesh\", \"thinInstanceSetBuffer\") as any;\r\nMesh.prototype.thinInstanceGetWorldMatrices ??= _MissingSideEffect(\"Mesh\", \"thinInstanceGetWorldMatrices\") as any;\r\nMesh.prototype.thinInstanceBufferUpdated ??= _MissingSideEffect(\"Mesh\", \"thinInstanceBufferUpdated\") as any;\r\nMesh.prototype.thinInstancePartialBufferUpdate ??= _MissingSideEffect(\"Mesh\", \"thinInstancePartialBufferUpdate\") as any;\r\nMesh.prototype.thinInstanceRefreshBoundingInfo ??= _MissingSideEffect(\"Mesh\", \"thinInstanceRefreshBoundingInfo\") as any;\r\nMesh.prototype.getEmittedParticleSystems ??= _MissingSideEffect(\"Mesh\", \"getEmittedParticleSystems\") as any;\r\nMesh.prototype.getHierarchyEmittedParticleSystems ??= _MissingSideEffect(\"Mesh\", \"getHierarchyEmittedParticleSystems\") as any;\r\nif (!Object.getOwnPropertyDescriptor(Mesh.prototype, \"edgesShareWithInstances\")) {\r\n    Object.defineProperty(Mesh.prototype, \"edgesShareWithInstances\", _MissingSideEffectProperty(\"Mesh\", \"edgesShareWithInstances\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Mesh.prototype, \"thinInstanceEnablePicking\")) {\r\n    Object.defineProperty(Mesh.prototype, \"thinInstanceEnablePicking\", _MissingSideEffectProperty(\"Mesh\", \"thinInstanceEnablePicking\"));\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Mesh.prototype, \"thinInstanceAllowAutomaticStaticBufferRecreation\")) {\r\n    Object.defineProperty(\r\n        Mesh.prototype,\r\n        \"thinInstanceAllowAutomaticStaticBufferRecreation\",\r\n        _MissingSideEffectProperty(\"Mesh\", \"thinInstanceAllowAutomaticStaticBufferRecreation\")\r\n    );\r\n}\r\nif (!Object.getOwnPropertyDescriptor(Mesh.prototype, \"thinInstanceCount\")) {\r\n    Object.defineProperty(Mesh.prototype, \"thinInstanceCount\", _MissingSideEffectProperty(\"Mesh\", \"thinInstanceCount\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FloatArray, type IndicesArray, type Nullable } from \"../types\";\r\nimport { Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type Vector3 } from \"../Maths/math.vector\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type IMeshDataOptions } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { type Skeleton } from \"../Bones/skeleton\";\r\nimport { DeepCopier } from \"../Misc/deepCopier\";\r\nimport { TransformNode } from \"./transformNode.pure\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type Geometry } from \"./geometry\";\r\n\r\nimport { type ThinEngine } from \"../Engines/thinEngine.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Creates an instance based on a source mesh.\r\n */\r\nexport class InstancedMesh extends AbstractMesh {\r\n    private _sourceMesh: Mesh;\r\n    private _currentLOD: Mesh;\r\n    private _billboardWorldMatrix: Matrix;\r\n\r\n    /** @internal */\r\n    public _indexInSourceMeshInstanceArray = -1;\r\n    /** @internal */\r\n    public _distanceToCamera: number = 0;\r\n    /** @internal */\r\n    public _previousWorldMatrix: Nullable<Matrix>;\r\n\r\n    /**\r\n     * Creates a new InstancedMesh object from the mesh source.\r\n     * @param name defines the name of the instance\r\n     * @param source the mesh to create the instance from\r\n     */\r\n    constructor(name: string, source: Mesh) {\r\n        super(name, source.getScene());\r\n\r\n        source.addInstance(this);\r\n\r\n        this._sourceMesh = source;\r\n\r\n        this._unIndexed = source._unIndexed;\r\n\r\n        this.position.copyFrom(source.position);\r\n        this.rotation.copyFrom(source.rotation);\r\n        this.scaling.copyFrom(source.scaling);\r\n\r\n        if (source.rotationQuaternion) {\r\n            this.rotationQuaternion = source.rotationQuaternion.clone();\r\n        }\r\n\r\n        this.animations = source.animations.slice();\r\n        for (const range of source.getAnimationRanges()) {\r\n            if (range != null) {\r\n                this.createAnimationRange(range.name, range.from, range.to);\r\n            }\r\n        }\r\n\r\n        this.infiniteDistance = source.infiniteDistance;\r\n\r\n        this.setPivotMatrix(source.getPivotMatrix());\r\n\r\n        if (!source.skeleton && !source.morphTargetManager && source.hasBoundingInfo) {\r\n            // without skeleton or morphTargetManager, use bounding info of source mesh directly\r\n            const boundingInfo = source.getBoundingInfo();\r\n            this.buildBoundingInfo(boundingInfo.minimum, boundingInfo.maximum);\r\n        } else {\r\n            this.refreshBoundingInfo(true, true);\r\n        }\r\n        this._syncSubMeshes();\r\n    }\r\n\r\n    /**\r\n     * @returns the string \"InstancedMesh\".\r\n     */\r\n    public override getClassName(): string {\r\n        return \"InstancedMesh\";\r\n    }\r\n\r\n    /** Gets the list of lights affecting that mesh */\r\n    public override get lightSources(): Light[] {\r\n        return this._sourceMesh._lightSources;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _resyncLightSources(): void {\r\n        // Do nothing as all the work will be done by source mesh\r\n    }\r\n\r\n    /** @internal */\r\n    public override _resyncLightSource(): void {\r\n        // Do nothing as all the work will be done by source mesh\r\n    }\r\n\r\n    /** @internal */\r\n    public override _removeLightSource(): void {\r\n        // Do nothing as all the work will be done by source mesh\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * If the source mesh receives shadows\r\n     */\r\n    public override get receiveShadows(): boolean {\r\n        return this._sourceMesh.receiveShadows;\r\n    }\r\n\r\n    public override set receiveShadows(_value: boolean) {\r\n        if (this._sourceMesh?.receiveShadows !== _value) {\r\n            Logger.Warn(\"Setting receiveShadows on an instanced mesh has no effect\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The material of the source mesh\r\n     */\r\n    public override get material(): Nullable<Material> {\r\n        return this._sourceMesh.material;\r\n    }\r\n\r\n    public override set material(_value: Nullable<Material>) {\r\n        if (this._sourceMesh?.material !== _value) {\r\n            Logger.Warn(\"Setting material on an instanced mesh has no effect\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Visibility of the source mesh\r\n     */\r\n    public override get visibility(): number {\r\n        return this._sourceMesh.visibility;\r\n    }\r\n\r\n    public override set visibility(_value: number) {\r\n        if (this._sourceMesh?.visibility !== _value) {\r\n            Logger.Warn(\"Setting visibility on an instanced mesh has no effect\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Skeleton of the source mesh\r\n     */\r\n    public override get skeleton(): Nullable<Skeleton> {\r\n        return this._sourceMesh.skeleton;\r\n    }\r\n\r\n    public override set skeleton(_value: Nullable<Skeleton>) {\r\n        if (this._sourceMesh?.skeleton !== _value) {\r\n            Logger.Warn(\"Setting skeleton on an instanced mesh has no effect\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rendering ground id of the source mesh\r\n     */\r\n    public override get renderingGroupId(): number {\r\n        return this._sourceMesh.renderingGroupId;\r\n    }\r\n\r\n    public override set renderingGroupId(value: number) {\r\n        if (!this._sourceMesh || value === this._sourceMesh.renderingGroupId) {\r\n            return;\r\n        }\r\n\r\n        //no-op with warning\r\n        Logger.Warn(\"Note - setting renderingGroupId of an instanced mesh has no effect on the scene\");\r\n    }\r\n\r\n    /**\r\n     * The packed mesh-blending tag of the source mesh.\r\n     */\r\n    public override get meshBlendingTag(): number {\r\n        return this._sourceMesh.meshBlendingTag;\r\n    }\r\n\r\n    public override set meshBlendingTag(value: number) {\r\n        if (!this._sourceMesh || value === this._sourceMesh.meshBlendingTag) {\r\n            return;\r\n        }\r\n\r\n        Logger.Warn(\"Setting meshBlendingTag on an instanced mesh has no effect\");\r\n    }\r\n\r\n    /**\r\n     * @returns the total number of vertices (integer).\r\n     */\r\n    public override getTotalVertices(): number {\r\n        return this._sourceMesh ? this._sourceMesh.getTotalVertices() : 0;\r\n    }\r\n\r\n    /**\r\n     * Returns a positive integer : the total number of indices in this mesh geometry.\r\n     * @returns the number of indices or zero if the mesh has no geometry.\r\n     */\r\n    public override getTotalIndices(): number {\r\n        return this._sourceMesh.getTotalIndices();\r\n    }\r\n\r\n    /**\r\n     * The source mesh of the instance\r\n     */\r\n    public get sourceMesh(): Mesh {\r\n        return this._sourceMesh;\r\n    }\r\n\r\n    /**\r\n     * Gets the mesh internal Geometry object\r\n     */\r\n    public override get geometry(): Nullable<Geometry> {\r\n        return this._sourceMesh._geometry;\r\n    }\r\n\r\n    /**\r\n     * Creates a new InstancedMesh object from the mesh model.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances\r\n     * @param name defines the name of the new instance\r\n     * @returns a new InstancedMesh\r\n     */\r\n    public createInstance(name: string): InstancedMesh {\r\n        return this._sourceMesh.createInstance(name);\r\n    }\r\n\r\n    /**\r\n     * Is this node ready to be used/rendered\r\n     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n     * @returns is it ready\r\n     */\r\n    public override isReady(completeCheck = false): boolean {\r\n        return this._sourceMesh.isReady(completeCheck, true);\r\n    }\r\n\r\n    /**\r\n     * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.\r\n     * @param kind kind of verticies to retrieve (eg. positions, normals, uvs, etc.)\r\n     * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.\r\n     * @param forceCopy defines a boolean forcing the copy of the buffer no matter what the value of copyWhenShared is\r\n     * @returns a float array or a Float32Array of the requested kind of data : positions, normals, uvs, etc.\r\n     */\r\n    public override getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray> {\r\n        return this._sourceMesh.getVerticesData(kind, copyWhenShared, forceCopy);\r\n    }\r\n\r\n    /** @internal */\r\n    public override copyVerticesData(kind: string, vertexData: { [kind: string]: Float32Array }): void {\r\n        this._sourceMesh.copyVerticesData(kind, vertexData);\r\n    }\r\n\r\n    /** @internal */\r\n    public override getVertexBuffer(kind: string, bypassInstanceData?: boolean): Nullable<VertexBuffer> {\r\n        return this._sourceMesh.getVertexBuffer(kind, bypassInstanceData);\r\n    }\r\n\r\n    /**\r\n     * Sets the vertex data of the mesh geometry for the requested `kind`.\r\n     * If the mesh has no geometry, a new Geometry object is set to the mesh and then passed this vertex data.\r\n     * The `data` are either a numeric array either a Float32Array.\r\n     * The parameter `updatable` is passed as is to the underlying Geometry object constructor (if initially none) or updater.\r\n     * The parameter `stride` is an optional positive integer, it is usually automatically deducted from the `kind` (3 for positions or normals, 2 for UV, etc).\r\n     * Note that a new underlying VertexBuffer object is created each call.\r\n     * If the `kind` is the `PositionKind`, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.\r\n     *\r\n     * Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     *\r\n     * Returns the Mesh.\r\n     * @param kind defines vertex data kind\r\n     * @param data defines the data source\r\n     * @param updatable defines if the data must be flagged as updatable (false as default)\r\n     * @param stride defines the vertex stride (optional)\r\n     * @returns the current mesh\r\n     */\r\n    public override setVerticesData(kind: string, data: FloatArray, updatable?: boolean, stride?: number): AbstractMesh {\r\n        if (this.sourceMesh) {\r\n            this.sourceMesh.setVerticesData(kind, data, updatable, stride);\r\n        }\r\n        return this.sourceMesh;\r\n    }\r\n\r\n    /**\r\n     * Updates the existing vertex data of the mesh geometry for the requested `kind`.\r\n     * If the mesh has no geometry, it is simply returned as it is.\r\n     * The `data` are either a numeric array either a Float32Array.\r\n     * No new underlying VertexBuffer object is created.\r\n     * If the `kind` is the `PositionKind` and if `updateExtends` is true, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.\r\n     * If the parameter `makeItUnique` is true, a new global geometry is created from this positions and is set to the mesh.\r\n     *\r\n     * Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     *\r\n     * Returns the Mesh.\r\n     * @param kind defines vertex data kind\r\n     * @param data defines the data source\r\n     * @param updateExtends defines if extends info of the mesh must be updated (can be null). This is mostly useful for \"position\" kind\r\n     * @param makeItUnique defines it the updated vertex buffer must be flagged as unique (false by default)\r\n     * @returns the source mesh\r\n     */\r\n    public override updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): Mesh {\r\n        if (this.sourceMesh) {\r\n            this.sourceMesh.updateVerticesData(kind, data, updateExtends, makeItUnique);\r\n        }\r\n        return this.sourceMesh;\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh indices.\r\n     * Expects an array populated with integers or a typed array (Int32Array, Uint32Array, Uint16Array).\r\n     * If the mesh has no geometry, a new Geometry object is created and set to the mesh.\r\n     * This method creates a new index buffer each call.\r\n     * Returns the Mesh.\r\n     * @param indices the source data\r\n     * @param totalVertices defines the total number of vertices referenced by indices (could be null)\r\n     * @returns source mesh\r\n     */\r\n    public override setIndices(indices: IndicesArray, totalVertices: Nullable<number> = null): Mesh {\r\n        if (this.sourceMesh) {\r\n            this.sourceMesh.setIndices(indices, totalVertices);\r\n        }\r\n        return this.sourceMesh;\r\n    }\r\n\r\n    /**\r\n     * Boolean : True if the mesh owns the requested kind of data.\r\n     * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :\r\n     * - VertexBuffer.PositionKind\r\n     * - VertexBuffer.UVKind\r\n     * - VertexBuffer.UV2Kind\r\n     * - VertexBuffer.UV3Kind\r\n     * - VertexBuffer.UV4Kind\r\n     * - VertexBuffer.UV5Kind\r\n     * - VertexBuffer.UV6Kind\r\n     * - VertexBuffer.ColorKind\r\n     * - VertexBuffer.MatricesIndicesKind\r\n     * - VertexBuffer.MatricesIndicesExtraKind\r\n     * - VertexBuffer.MatricesWeightsKind\r\n     * - VertexBuffer.MatricesWeightsExtraKind\r\n     * @returns true if data kind is present\r\n     */\r\n    public override isVerticesDataPresent(kind: string): boolean {\r\n        return this._sourceMesh.isVerticesDataPresent(kind);\r\n    }\r\n\r\n    /**\r\n     * @returns an array of indices (IndicesArray).\r\n     */\r\n    public override getIndices(): Nullable<IndicesArray> {\r\n        return this._sourceMesh.getIndices();\r\n    }\r\n\r\n    /** @internal */\r\n    public override get _positions(): Nullable<Vector3[]> {\r\n        return this._sourceMesh._positions;\r\n    }\r\n\r\n    /** @internal */\r\n    public override refreshBoundingInfo(applySkeletonOrOptions: boolean | IMeshDataOptions = false, applyMorph: boolean = false): InstancedMesh {\r\n        if (this.hasBoundingInfo && this.getBoundingInfo().isLocked) {\r\n            return this;\r\n        }\r\n\r\n        let options: IMeshDataOptions;\r\n        if (typeof applySkeletonOrOptions === \"object\") {\r\n            options = applySkeletonOrOptions;\r\n        } else {\r\n            options = {\r\n                applySkeleton: applySkeletonOrOptions,\r\n                applyMorph: applyMorph,\r\n            };\r\n        }\r\n\r\n        const bias = this._sourceMesh.geometry ? this._sourceMesh.geometry.boundingBias : null;\r\n        this._refreshBoundingInfo(this._sourceMesh._getData(options, null, VertexBuffer.PositionKind), bias);\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _preActivate(): InstancedMesh {\r\n        if (this._currentLOD) {\r\n            this._currentLOD._preActivate();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _activate(renderId: number, intermediateRendering: boolean): boolean {\r\n        super._activate(renderId, intermediateRendering);\r\n\r\n        if (!this._sourceMesh.subMeshes) {\r\n            Logger.Warn(\"Instances should only be created for meshes with geometry.\");\r\n        }\r\n\r\n        if (this._currentLOD) {\r\n            const differentSign = this._currentLOD._getWorldMatrixDeterminant() >= 0 !== this._getWorldMatrixDeterminant() >= 0;\r\n            if (differentSign) {\r\n                this._internalAbstractMeshDataInfo._actAsRegularMesh = true;\r\n                return true;\r\n            }\r\n            this._internalAbstractMeshDataInfo._actAsRegularMesh = false;\r\n\r\n            this._currentLOD._registerInstanceForRenderId(this, renderId);\r\n\r\n            if (intermediateRendering) {\r\n                if (!this._currentLOD._internalAbstractMeshDataInfo._isActiveIntermediate) {\r\n                    this._currentLOD._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = true;\r\n                    return true;\r\n                }\r\n            } else {\r\n                if (!this._currentLOD._internalAbstractMeshDataInfo._isActive) {\r\n                    this._currentLOD._internalAbstractMeshDataInfo._onlyForInstances = true;\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _postActivate(): void {\r\n        if (this._sourceMesh.edgesShareWithInstances && this._sourceMesh._edgesRenderer && this._sourceMesh._edgesRenderer.isEnabled && this._sourceMesh._renderingGroup) {\r\n            // we are using the edge renderer of the source mesh\r\n            this._sourceMesh._renderingGroup._edgesRenderers.pushNoDuplicate(this._sourceMesh._edgesRenderer);\r\n            this._sourceMesh._edgesRenderer.customInstances.push(this.getWorldMatrix());\r\n        } else if (this._edgesRenderer && this._edgesRenderer.isEnabled && this._sourceMesh._renderingGroup) {\r\n            // we are using the edge renderer defined for this instance\r\n            this._sourceMesh._renderingGroup._edgesRenderers.push(this._edgesRenderer);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override getWorldMatrix(): Matrix {\r\n        if (\r\n            this._currentLOD &&\r\n            this._currentLOD !== this._sourceMesh &&\r\n            this._currentLOD.billboardMode !== TransformNode.BILLBOARDMODE_NONE &&\r\n            this._currentLOD._masterMesh !== this\r\n        ) {\r\n            if (!this._billboardWorldMatrix) {\r\n                this._billboardWorldMatrix = new Matrix();\r\n            }\r\n            const tempMaster = this._currentLOD._masterMesh;\r\n            this._currentLOD._masterMesh = this;\r\n            TmpVectors.Vector3[7].copyFrom(this._currentLOD.position);\r\n            this._currentLOD.position.set(0, 0, 0);\r\n            this._billboardWorldMatrix.copyFrom(this._currentLOD.computeWorldMatrix(true));\r\n            this._currentLOD.position.copyFrom(TmpVectors.Vector3[7]);\r\n            this._currentLOD._masterMesh = tempMaster;\r\n            return this._billboardWorldMatrix;\r\n        }\r\n\r\n        return super.getWorldMatrix();\r\n    }\r\n\r\n    /** @internal */\r\n    public override get isAnInstance(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns the current associated LOD AbstractMesh.\r\n     * @param camera defines the camera to use to pick the LOD level\r\n     * @returns a Mesh or `null` if no LOD is associated with the AbstractMesh\r\n     */\r\n    public override getLOD(camera: Camera): AbstractMesh {\r\n        if (!camera) {\r\n            return this;\r\n        }\r\n\r\n        const sourceMeshLODLevels = this.sourceMesh.getLODLevels();\r\n        if (!sourceMeshLODLevels || sourceMeshLODLevels.length === 0) {\r\n            this._currentLOD = this.sourceMesh;\r\n        } else {\r\n            const boundingInfo = this.getBoundingInfo();\r\n            this._currentLOD = <Mesh>this.sourceMesh.getLOD(camera, boundingInfo.boundingSphere);\r\n        }\r\n\r\n        return this._currentLOD;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _preActivateForIntermediateRendering(renderId: number): Mesh {\r\n        return this.sourceMesh._preActivateForIntermediateRendering(renderId);\r\n    }\r\n\r\n    /** @internal */\r\n    public _syncSubMeshes(): InstancedMesh {\r\n        this.releaseSubMeshes();\r\n        if (this._sourceMesh.subMeshes) {\r\n            for (let index = 0; index < this._sourceMesh.subMeshes.length; index++) {\r\n                this._sourceMesh.subMeshes[index].clone(this, this._sourceMesh);\r\n            }\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _generatePointsArray(): boolean {\r\n        return this._sourceMesh._generatePointsArray();\r\n    }\r\n\r\n    /** @internal */\r\n    public override _updateBoundingInfo(): AbstractMesh {\r\n        if (this.hasBoundingInfo) {\r\n            this.getBoundingInfo().update(this.worldMatrixFromCache);\r\n        } else {\r\n            this.buildBoundingInfo(this.absolutePosition, this.absolutePosition, this.worldMatrixFromCache);\r\n        }\r\n        this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates a new InstancedMesh from the current mesh.\r\n     *\r\n     * Returns the clone.\r\n     * @param name the cloned mesh name\r\n     * @param newParent the optional Node to parent the clone to.\r\n     * @param doNotCloneChildren if `true` the model children aren't cloned.\r\n     * @param newSourceMesh if set this mesh will be used as the source mesh instead of ths instance's one\r\n     * @returns the clone\r\n     */\r\n    public override clone(name: string, newParent: Nullable<Node> = null, doNotCloneChildren?: boolean, newSourceMesh?: Mesh): InstancedMesh {\r\n        const result = (newSourceMesh || this._sourceMesh).createInstance(name);\r\n\r\n        // Deep copy\r\n        DeepCopier.DeepCopy(\r\n            this,\r\n            result,\r\n            [\r\n                \"name\",\r\n                \"subMeshes\",\r\n                \"uniqueId\",\r\n                \"parent\",\r\n                \"lightSources\",\r\n                \"receiveShadows\",\r\n                \"material\",\r\n                \"visibility\",\r\n                \"skeleton\",\r\n                \"sourceMesh\",\r\n                \"isAnInstance\",\r\n                \"facetNb\",\r\n                \"isFacetDataEnabled\",\r\n                \"isBlocked\",\r\n                \"useBones\",\r\n                \"hasInstances\",\r\n                \"collider\",\r\n                \"edgesRenderer\",\r\n                \"forward\",\r\n                \"up\",\r\n                \"right\",\r\n                \"absolutePosition\",\r\n                \"absoluteScaling\",\r\n                \"absoluteRotationQuaternion\",\r\n                \"isWorldMatrixFrozen\",\r\n                \"nonUniformScaling\",\r\n                \"behaviors\",\r\n                \"worldMatrixFromCache\",\r\n                \"hasThinInstances\",\r\n                \"hasBoundingInfo\",\r\n                \"geometry\",\r\n            ],\r\n            []\r\n        );\r\n\r\n        // Parent\r\n        if (newParent) {\r\n            result.parent = newParent;\r\n        }\r\n\r\n        if (!doNotCloneChildren) {\r\n            // Children\r\n            for (let index = 0; index < this.getScene().meshes.length; index++) {\r\n                const mesh = this.getScene().meshes[index];\r\n\r\n                if (mesh.parent === this) {\r\n                    mesh.clone(mesh.name, result);\r\n                }\r\n            }\r\n        }\r\n\r\n        result.computeWorldMatrix(true);\r\n\r\n        this.onClonedObservable.notifyObservers(result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Disposes the InstancedMesh.\r\n     * Returns nothing.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        // Remove from mesh\r\n        this._sourceMesh.removeInstance(this);\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _serializeAsParent(serializationObject: any) {\r\n        super._serializeAsParent(serializationObject);\r\n\r\n        serializationObject.parentId = this._sourceMesh.uniqueId;\r\n        serializationObject.parentInstanceIndex = this._indexInSourceMeshInstanceArray;\r\n    }\r\n\r\n    /**\r\n     * Instantiate (when possible) or clone that node with its hierarchy\r\n     * @param newParent defines the new parent to use for the instance (or clone)\r\n     * @param options defines options to configure how copy is done\r\n     * @param onNewNodeCreated defines an option callback to call when a clone or an instance is created\r\n     * @returns an instance (or a clone) of the current node with its hierarchy\r\n     */\r\n    public override instantiateHierarchy(\r\n        newParent: Nullable<TransformNode> = null,\r\n        options?: { doNotInstantiate: boolean | ((node: TransformNode) => boolean); newSourcedMesh?: Mesh },\r\n        onNewNodeCreated?: (source: TransformNode, clone: TransformNode) => void\r\n    ): Nullable<TransformNode> {\r\n        const clone = this.clone(\"Clone of \" + (this.name || this.id), newParent || this.parent, true, options && options.newSourcedMesh);\r\n\r\n        if (clone) {\r\n            if (onNewNodeCreated) {\r\n                onNewNodeCreated(this, clone);\r\n            }\r\n        }\r\n\r\n        for (const child of this.getChildTransformNodes(true)) {\r\n            child.instantiateHierarchy(clone, options, onNewNodeCreated);\r\n        }\r\n\r\n        return clone;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instancedMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstancedMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._instancedMeshFactory = (name: string, mesh: Mesh): InstancedMesh => {\r\n        const instance = new InstancedMesh(name, mesh);\r\n\r\n        if (mesh.instancedBuffers) {\r\n            instance.instancedBuffers = {};\r\n\r\n            for (const key in mesh.instancedBuffers) {\r\n                instance.instancedBuffers[key] = mesh.instancedBuffers[key];\r\n            }\r\n        }\r\n\r\n        return instance;\r\n    };\r\n\r\n    Mesh.prototype.registerInstancedBuffer = function (kind: string, stride: number): void {\r\n        // Remove existing one (shared VBO)\r\n        this._userInstancedBuffersStorage?.vertexBuffers[kind]?.dispose();\r\n\r\n        // Remove existing per-pass VBOs (WebGPU)\r\n        if (this._userInstancedBuffersStorage?.renderPasses) {\r\n            for (const passId in this._userInstancedBuffersStorage.renderPasses) {\r\n                const passVBOs = this._userInstancedBuffersStorage.renderPasses[passId];\r\n                passVBOs[kind]?.dispose();\r\n                delete passVBOs[kind];\r\n            }\r\n        }\r\n\r\n        // Creates the instancedBuffer field if not present\r\n        if (!this.instancedBuffers) {\r\n            this.instancedBuffers = {};\r\n\r\n            for (const instance of this.instances) {\r\n                instance.instancedBuffers = {};\r\n            }\r\n        }\r\n\r\n        if (!this._userInstancedBuffersStorage) {\r\n            this._userInstancedBuffersStorage = {\r\n                data: {},\r\n                vertexBuffers: {},\r\n                strides: {},\r\n                sizes: {},\r\n                vertexArrayObjects: this.getEngine().getCaps().vertexArrayObject ? {} : undefined,\r\n            };\r\n        }\r\n\r\n        // Creates an empty property for this kind\r\n        this.instancedBuffers[kind] = null;\r\n\r\n        this._userInstancedBuffersStorage.strides[kind] = stride;\r\n        this._userInstancedBuffersStorage.sizes[kind] = stride * 32; // Initial size\r\n        this._userInstancedBuffersStorage.data[kind] = new Float32Array(this._userInstancedBuffersStorage.sizes[kind]);\r\n        // In WebGPU, per-pass VBOs are used instead of a shared one (created on demand in _processInstancedBuffers)\r\n        this._userInstancedBuffersStorage.vertexBuffers[kind] = this._instanceDataStorage.useMonoDataStorageRenderPass\r\n            ? new VertexBuffer(this.getEngine(), this._userInstancedBuffersStorage.data[kind], kind, true, false, stride, true)\r\n            : null;\r\n\r\n        for (const instance of this.instances) {\r\n            instance.instancedBuffers[kind] = null;\r\n        }\r\n\r\n        this._invalidateInstanceVertexArrayObject();\r\n\r\n        this._markSubMeshesAsAttributesDirty();\r\n    };\r\n\r\n    Mesh.prototype._processInstancedBuffers = function (visibleInstances: Nullable<InstancedMesh[]>, renderSelf: boolean) {\r\n        const instanceCount = visibleInstances ? visibleInstances.length : 0;\r\n\r\n        // In WebGPU, queue.writeBuffer() writes are all applied before the command buffer executes,\r\n        // so a shared VBO written by multiple render passes (e.g. effect layer + main scene) will\r\n        // only reflect the last write for ALL passes. Use per-render-pass VBOs instead.\r\n        const usePerPassStorage = !this._instanceDataStorage.useMonoDataStorageRenderPass;\r\n        let perPassVertexBuffers: { [kind: string]: Nullable<VertexBuffer> } | undefined;\r\n        if (usePerPassStorage) {\r\n            const currentRenderPassId = this._instanceDataStorage.engine.currentRenderPassId;\r\n            if (!this._userInstancedBuffersStorage.renderPasses) {\r\n                this._userInstancedBuffersStorage.renderPasses = {};\r\n            }\r\n            if (!this._userInstancedBuffersStorage.renderPasses[currentRenderPassId]) {\r\n                this._userInstancedBuffersStorage.renderPasses[currentRenderPassId] = {};\r\n            }\r\n            perPassVertexBuffers = this._userInstancedBuffersStorage.renderPasses[currentRenderPassId];\r\n        }\r\n\r\n        for (const kind in this.instancedBuffers) {\r\n            let size = this._userInstancedBuffersStorage.sizes[kind];\r\n            const stride = this._userInstancedBuffersStorage.strides[kind];\r\n\r\n            // Resize if required\r\n            const expectedSize = (instanceCount + 1) * stride;\r\n\r\n            while (size < expectedSize) {\r\n                size *= 2;\r\n            }\r\n\r\n            if (this._userInstancedBuffersStorage.data[kind].length != size) {\r\n                this._userInstancedBuffersStorage.data[kind] = new Float32Array(size);\r\n                this._userInstancedBuffersStorage.sizes[kind] = size;\r\n                if (usePerPassStorage) {\r\n                    if (perPassVertexBuffers![kind]) {\r\n                        perPassVertexBuffers![kind]!.dispose();\r\n                        perPassVertexBuffers![kind] = null;\r\n                    }\r\n                } else if (this._userInstancedBuffersStorage.vertexBuffers[kind]) {\r\n                    this._userInstancedBuffersStorage.vertexBuffers[kind].dispose();\r\n                    this._userInstancedBuffersStorage.vertexBuffers[kind] = null;\r\n                }\r\n            }\r\n\r\n            const data = this._userInstancedBuffersStorage.data[kind];\r\n\r\n            // Update data buffer\r\n            let offset = 0;\r\n            if (renderSelf) {\r\n                const value = this.instancedBuffers[kind] ?? 0;\r\n\r\n                if (value.toArray) {\r\n                    value.toArray(data, offset);\r\n                } else if (value.copyToArray) {\r\n                    value.copyToArray(data, offset);\r\n                } else {\r\n                    data[offset] = value;\r\n                }\r\n\r\n                offset += stride;\r\n            }\r\n\r\n            for (let instanceIndex = 0; instanceIndex < instanceCount; instanceIndex++) {\r\n                const instance = visibleInstances![instanceIndex];\r\n\r\n                const value = instance.instancedBuffers[kind] ?? 0;\r\n\r\n                if (value.toArray) {\r\n                    value.toArray(data, offset);\r\n                } else if (value.copyToArray) {\r\n                    value.copyToArray(data, offset);\r\n                } else {\r\n                    data[offset] = value;\r\n                }\r\n\r\n                offset += stride;\r\n            }\r\n\r\n            // Update vertex buffer (per-pass in WebGPU, shared in WebGL)\r\n            if (usePerPassStorage) {\r\n                if (!perPassVertexBuffers![kind]) {\r\n                    perPassVertexBuffers![kind] = new VertexBuffer(this.getEngine(), this._userInstancedBuffersStorage.data[kind], kind, true, false, stride, true);\r\n                    this._invalidateInstanceVertexArrayObject();\r\n                } else {\r\n                    perPassVertexBuffers![kind]!.updateDirectly(data, 0);\r\n                }\r\n            } else {\r\n                if (!this._userInstancedBuffersStorage.vertexBuffers[kind]) {\r\n                    this._userInstancedBuffersStorage.vertexBuffers[kind] = new VertexBuffer(\r\n                        this.getEngine(),\r\n                        this._userInstancedBuffersStorage.data[kind],\r\n                        kind,\r\n                        true,\r\n                        false,\r\n                        stride,\r\n                        true\r\n                    );\r\n                    this._invalidateInstanceVertexArrayObject();\r\n                } else {\r\n                    this._userInstancedBuffersStorage.vertexBuffers[kind].updateDirectly(data, 0);\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    Mesh.prototype._invalidateInstanceVertexArrayObject = function () {\r\n        if (!this._userInstancedBuffersStorage || this._userInstancedBuffersStorage.vertexArrayObjects === undefined) {\r\n            return;\r\n        }\r\n\r\n        for (const kind in this._userInstancedBuffersStorage.vertexArrayObjects) {\r\n            (this.getEngine() as ThinEngine).releaseVertexArrayObject(this._userInstancedBuffersStorage.vertexArrayObjects[kind]);\r\n        }\r\n\r\n        this._userInstancedBuffersStorage.vertexArrayObjects = {};\r\n    };\r\n\r\n    Mesh.prototype._disposeInstanceSpecificData = function () {\r\n        for (const renderPassId in this._instanceDataStorage.renderPasses) {\r\n            this._instanceDataStorage.renderPasses[renderPassId].instancesBuffer?.dispose();\r\n        }\r\n        this._instanceDataStorage.renderPasses = {};\r\n        this._instanceDataStorage.dataStorageRenderPass?.instancesBuffer?.dispose();\r\n\r\n        while (this.instances.length) {\r\n            this.instances[0].dispose();\r\n        }\r\n\r\n        for (const kind in this.instancedBuffers) {\r\n            if (this._userInstancedBuffersStorage.vertexBuffers[kind]) {\r\n                this._userInstancedBuffersStorage.vertexBuffers[kind].dispose();\r\n            }\r\n        }\r\n\r\n        this._invalidateInstanceVertexArrayObject();\r\n\r\n        this.instancedBuffers = {};\r\n    };\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.InstancedMesh\", InstancedMesh);\r\n}\r\n","import { serialize, serializeAsColor3, expandToProperty } from \"../Misc/decorators\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3, TmpColors } from \"../Maths/math.color.pure\";\r\nimport { Node } from \"../node\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { type IShadowGenerator } from \"./Shadows/shadowGenerator\";\r\nimport { GetClass } from \"../Misc/typeStore\";\r\nimport { type ISortableLight, LightConstants } from \"./lightConstants\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n/**\r\n * Base class of all the lights in Babylon. It groups all the generic information about lights.\r\n * Lights are used, as you would expect, to affect how meshes are seen, in terms of both illumination and colour.\r\n * All meshes allow light to pass through them unless shadow generation is activated. The default number of lights allowed is four but this can be increased.\r\n */\r\nexport abstract class Light extends Node implements ISortableLight {\r\n    /**\r\n     * Falloff Default: light is falling off following the material specification:\r\n     * standard material is using standard falloff whereas pbr material can request special falloff per materials.\r\n     */\r\n    public static readonly FALLOFF_DEFAULT = LightConstants.FALLOFF_DEFAULT;\r\n\r\n    /**\r\n     * Falloff Physical: light is falling off following the inverse squared distance law.\r\n     */\r\n    public static readonly FALLOFF_PHYSICAL = LightConstants.FALLOFF_PHYSICAL;\r\n\r\n    /**\r\n     * Falloff gltf: light is falling off as described in the gltf moving to PBR document\r\n     * to enhance interoperability with other engines.\r\n     */\r\n    public static readonly FALLOFF_GLTF = LightConstants.FALLOFF_GLTF;\r\n\r\n    /**\r\n     * Falloff Standard: light is falling off like in the standard material\r\n     * to enhance interoperability with other materials.\r\n     */\r\n    public static readonly FALLOFF_STANDARD = LightConstants.FALLOFF_STANDARD;\r\n\r\n    //lightmapMode Consts\r\n    /**\r\n     * If every light affecting the material is in this lightmapMode,\r\n     * material.lightmapTexture adds or multiplies\r\n     * (depends on material.useLightmapAsShadowmap)\r\n     * after every other light calculations.\r\n     */\r\n    public static readonly LIGHTMAP_DEFAULT = LightConstants.LIGHTMAP_DEFAULT;\r\n    /**\r\n     * material.lightmapTexture as only diffuse lighting from this light\r\n     * adds only specular lighting from this light\r\n     * adds dynamic shadows\r\n     */\r\n    public static readonly LIGHTMAP_SPECULAR = LightConstants.LIGHTMAP_SPECULAR;\r\n    /**\r\n     * material.lightmapTexture as only lighting\r\n     * no light calculation from this light\r\n     * only adds dynamic shadows from this light\r\n     */\r\n    public static readonly LIGHTMAP_SHADOWSONLY = LightConstants.LIGHTMAP_SHADOWSONLY;\r\n\r\n    // Intensity Mode Consts\r\n    /**\r\n     * Each light type uses the default quantity according to its type:\r\n     *      point/spot lights use luminous intensity\r\n     *      directional lights use illuminance\r\n     */\r\n    public static readonly INTENSITYMODE_AUTOMATIC = LightConstants.INTENSITYMODE_AUTOMATIC;\r\n    /**\r\n     * lumen (lm)\r\n     */\r\n    public static readonly INTENSITYMODE_LUMINOUSPOWER = LightConstants.INTENSITYMODE_LUMINOUSPOWER;\r\n    /**\r\n     * candela (lm/sr)\r\n     */\r\n    public static readonly INTENSITYMODE_LUMINOUSINTENSITY = LightConstants.INTENSITYMODE_LUMINOUSINTENSITY;\r\n    /**\r\n     * lux (lm/m^2)\r\n     */\r\n    public static readonly INTENSITYMODE_ILLUMINANCE = LightConstants.INTENSITYMODE_ILLUMINANCE;\r\n    /**\r\n     * nit (cd/m^2)\r\n     */\r\n    public static readonly INTENSITYMODE_LUMINANCE = LightConstants.INTENSITYMODE_LUMINANCE;\r\n\r\n    // Light types ids const.\r\n    /**\r\n     * Light type const id of the point light.\r\n     */\r\n    public static readonly LIGHTTYPEID_POINTLIGHT = LightConstants.LIGHTTYPEID_POINTLIGHT;\r\n    /**\r\n     * Light type const id of the directional light.\r\n     */\r\n    public static readonly LIGHTTYPEID_DIRECTIONALLIGHT = LightConstants.LIGHTTYPEID_DIRECTIONALLIGHT;\r\n    /**\r\n     * Light type const id of the spot light.\r\n     */\r\n    public static readonly LIGHTTYPEID_SPOTLIGHT = LightConstants.LIGHTTYPEID_SPOTLIGHT;\r\n    /**\r\n     * Light type const id of the hemispheric light.\r\n     */\r\n    public static readonly LIGHTTYPEID_HEMISPHERICLIGHT = LightConstants.LIGHTTYPEID_HEMISPHERICLIGHT;\r\n\r\n    /**\r\n     * Light type const id of the area light.\r\n     */\r\n    public static readonly LIGHTTYPEID_RECT_AREALIGHT = LightConstants.LIGHTTYPEID_RECT_AREALIGHT;\r\n\r\n    /**\r\n     * Diffuse gives the basic color to an object.\r\n     */\r\n    @serializeAsColor3()\r\n    public diffuse = new Color3(1.0, 1.0, 1.0);\r\n\r\n    /**\r\n     * Specular produces a highlight color on an object.\r\n     * Note: This is not affecting PBR materials.\r\n     */\r\n    @serializeAsColor3()\r\n    public specular = new Color3(1.0, 1.0, 1.0);\r\n\r\n    /**\r\n     * Defines the falloff type for this light. This lets overriding how punctual light are\r\n     * falling off base on range or angle.\r\n     * This can be set to any values in Light.FALLOFF_x.\r\n     *\r\n     * Note: This is only useful for PBR Materials at the moment. This could be extended if required to\r\n     * other types of materials.\r\n     */\r\n    @serialize()\r\n    public falloffType = Light.FALLOFF_DEFAULT;\r\n\r\n    /**\r\n     * Strength of the light.\r\n     * Note: By default it is define in the framework own unit.\r\n     * Note: In PBR materials the intensityMode can be use to chose what unit the intensity is defined in.\r\n     */\r\n    @serialize()\r\n    public intensity = 1.0;\r\n\r\n    private _range = Number.MAX_VALUE;\r\n    /** @internal */\r\n    public _inverseSquaredRange = 0;\r\n\r\n    /**\r\n     * Defines how far from the source the light is impacting in scene units.\r\n     * Note: Unused in PBR material as the distance light falloff is defined following the inverse squared falloff.\r\n     */\r\n    @serialize()\r\n    public get range(): number {\r\n        return this._range;\r\n    }\r\n    /**\r\n     * Defines how far from the source the light is impacting in scene units.\r\n     * Note: Unused in PBR material as the distance light falloff is defined following the inverse squared falloff.\r\n     */\r\n    public set range(value: number) {\r\n        this._range = value;\r\n        this._inverseSquaredRange = 1.0 / (this.range * this.range);\r\n    }\r\n\r\n    /**\r\n     * Cached photometric scale default to 1.0 as the automatic intensity mode defaults to 1.0 for every type\r\n     * of light.\r\n     */\r\n    private _photometricScale = 1.0;\r\n\r\n    private _intensityMode: number = Light.INTENSITYMODE_AUTOMATIC;\r\n    /**\r\n     * Gets the photometric scale used to interpret the intensity.\r\n     * This is only relevant with PBR Materials where the light intensity can be defined in a physical way.\r\n     */\r\n    @serialize()\r\n    public get intensityMode(): number {\r\n        return this._intensityMode;\r\n    }\r\n    /**\r\n     * Sets the photometric scale used to interpret the intensity.\r\n     * This is only relevant with PBR Materials where the light intensity can be defined in a physical way.\r\n     */\r\n    public set intensityMode(value: number) {\r\n        this._intensityMode = value;\r\n        this._computePhotometricScale();\r\n    }\r\n\r\n    private _radius = 0.00001;\r\n    /**\r\n     * Gets the light radius used by PBR Materials to simulate soft area lights.\r\n     */\r\n    @serialize()\r\n    public get radius(): number {\r\n        return this._radius;\r\n    }\r\n    /**\r\n     * sets the light radius used by PBR Materials to simulate soft area lights.\r\n     */\r\n    public set radius(value: number) {\r\n        this._radius = value;\r\n        this._computePhotometricScale();\r\n    }\r\n\r\n    @serialize()\r\n    private _renderPriority: number;\r\n    /**\r\n     * Defines the rendering priority of the lights. It can help in case of fallback or number of lights\r\n     * exceeding the number allowed of the materials.\r\n     */\r\n    @expandToProperty(\"_reorderLightsInScene\")\r\n    public accessor renderPriority: number = 0;\r\n\r\n    @serialize(\"shadowEnabled\")\r\n    private _shadowEnabled: boolean = true;\r\n    /**\r\n     * Gets whether or not the shadows are enabled for this light. This can help turning off/on shadow without detaching\r\n     * the current shadow generator.\r\n     */\r\n    public get shadowEnabled(): boolean {\r\n        return this._shadowEnabled;\r\n    }\r\n    /**\r\n     * Sets whether or not the shadows are enabled for this light. This can help turning off/on shadow without detaching\r\n     * the current shadow generator.\r\n     */\r\n    public set shadowEnabled(value: boolean) {\r\n        if (this._shadowEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._shadowEnabled = value;\r\n        this._markMeshesAsLightDirty();\r\n    }\r\n\r\n    private _includedOnlyMeshes: AbstractMesh[];\r\n    /**\r\n     * Gets the only meshes impacted by this light.\r\n     */\r\n    public get includedOnlyMeshes(): AbstractMesh[] {\r\n        return this._includedOnlyMeshes;\r\n    }\r\n    /**\r\n     * Sets the only meshes impacted by this light.\r\n     */\r\n    public set includedOnlyMeshes(value: AbstractMesh[]) {\r\n        this._includedOnlyMeshes = value;\r\n        this._hookArrayForIncludedOnly(value);\r\n    }\r\n\r\n    private _excludedMeshes: AbstractMesh[];\r\n    /**\r\n     * Gets the meshes not impacted by this light.\r\n     */\r\n    public get excludedMeshes(): AbstractMesh[] {\r\n        return this._excludedMeshes;\r\n    }\r\n    /**\r\n     * Sets the meshes not impacted by this light.\r\n     */\r\n    public set excludedMeshes(value: AbstractMesh[]) {\r\n        this._excludedMeshes = value;\r\n        this._hookArrayForExcluded(value);\r\n    }\r\n\r\n    @serialize(\"excludeWithLayerMask\")\r\n    private _excludeWithLayerMask = 0;\r\n    /**\r\n     * Gets the layer id use to find what meshes are not impacted by the light.\r\n     * Inactive if 0\r\n     */\r\n    public get excludeWithLayerMask(): number {\r\n        return this._excludeWithLayerMask;\r\n    }\r\n    /**\r\n     * Sets the layer id use to find what meshes are not impacted by the light.\r\n     * Inactive if 0\r\n     */\r\n    public set excludeWithLayerMask(value: number) {\r\n        this._excludeWithLayerMask = value;\r\n        this._resyncMeshes();\r\n    }\r\n\r\n    @serialize(\"includeOnlyWithLayerMask\")\r\n    private _includeOnlyWithLayerMask = 0;\r\n    /**\r\n     * Gets the layer id use to find what meshes are impacted by the light.\r\n     * Inactive if 0\r\n     */\r\n    public get includeOnlyWithLayerMask(): number {\r\n        return this._includeOnlyWithLayerMask;\r\n    }\r\n    /**\r\n     * Sets the layer id use to find what meshes are impacted by the light.\r\n     * Inactive if 0\r\n     */\r\n    public set includeOnlyWithLayerMask(value: number) {\r\n        this._includeOnlyWithLayerMask = value;\r\n        this._resyncMeshes();\r\n    }\r\n\r\n    @serialize(\"lightmapMode\")\r\n    private _lightmapMode = 0;\r\n    /**\r\n     * Gets the lightmap mode of this light (should be one of the constants defined by Light.LIGHTMAP_x)\r\n     */\r\n    public get lightmapMode(): number {\r\n        return this._lightmapMode;\r\n    }\r\n    /**\r\n     * Sets the lightmap mode of this light (should be one of the constants defined by Light.LIGHTMAP_x)\r\n     */\r\n    public set lightmapMode(value: number) {\r\n        if (this._lightmapMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._lightmapMode = value;\r\n        this._markMeshesAsLightDirty();\r\n    }\r\n\r\n    /**\r\n     * Returns the view matrix.\r\n     * @param _faceIndex The index of the face for which we want to extract the view matrix. Only used for point light types.\r\n     * @returns The view matrix. Can be null, if a view matrix cannot be defined for the type of light considered (as for a hemispherical light, for example).\r\n     */\r\n    public getViewMatrix(_faceIndex?: number): Nullable<Matrix> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Returns the projection matrix.\r\n     * Note that viewMatrix and renderList are optional and are only used by lights that calculate the projection matrix from a list of meshes (e.g. directional lights with automatic extents calculation).\r\n     * @param _viewMatrix The view transform matrix of the light (optional).\r\n     * @param _renderList The list of meshes to take into account when calculating the projection matrix (optional).\r\n     * @returns The projection matrix. Can be null, if a projection matrix cannot be defined for the type of light considered (as for a hemispherical light, for example).\r\n     */\r\n    public getProjectionMatrix(_viewMatrix?: Matrix, _renderList?: Array<AbstractMesh>): Nullable<Matrix> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Shadow generators associated to the light.\r\n     * @internal Internal use only.\r\n     */\r\n    public _shadowGenerators: Nullable<Map<Nullable<Camera>, IShadowGenerator>> = null;\r\n\r\n    /**\r\n     * @internal Internal use only.\r\n     */\r\n    public _excludedMeshesIds = new Array<string>();\r\n\r\n    /**\r\n     * @internal Internal use only.\r\n     */\r\n    public _includedOnlyMeshesIds = new Array<string>();\r\n\r\n    /**\r\n     * The current light uniform buffer.\r\n     * @internal Internal use only.\r\n     */\r\n    public _uniformBuffer: UniformBuffer;\r\n\r\n    /** @internal */\r\n    public _renderId: number;\r\n\r\n    private _lastUseSpecular: boolean;\r\n\r\n    /**\r\n     * Used internally by ClusteredLight to sort lights\r\n     * @internal\r\n     */\r\n    public _currentViewDepth = 0;\r\n\r\n    /**\r\n     * Used internally by ClusteredLightContainer to keep child lights out of mesh light source lists.\r\n     * @internal\r\n     */\r\n    public _clusteredContainer: Nullable<Light> = null;\r\n\r\n    /**\r\n     * Creates a Light object in the scene.\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     * @param name The friendly name of the light\r\n     * @param scene The scene the light belongs too\r\n     * @param dontAddToScene True to not add the light to the scene\r\n     */\r\n    constructor(name: string, scene?: Scene, dontAddToScene?: boolean) {\r\n        super(name, scene, false);\r\n        if (!dontAddToScene) {\r\n            this.getScene().addLight(this);\r\n        }\r\n        this._uniformBuffer = new UniformBuffer(this.getScene().getEngine(), undefined, undefined, name);\r\n        this._buildUniformLayout();\r\n\r\n        this.includedOnlyMeshes = [] as AbstractMesh[];\r\n        this.excludedMeshes = [] as AbstractMesh[];\r\n\r\n        if (!dontAddToScene) {\r\n            this._resyncMeshes();\r\n        }\r\n    }\r\n\r\n    protected abstract _buildUniformLayout(): void;\r\n\r\n    /**\r\n     * Sets the passed Effect \"effect\" with the Light information.\r\n     * @param effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The light\r\n     */\r\n    public abstract transferToEffect(effect: Effect, lightIndex: string): Light;\r\n\r\n    /**\r\n     * Sets the passed Effect \"effect\" with the Light textures.\r\n     * @param effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The light\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\r\n        // Do nothing by default.\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Binds the lights information from the scene to the effect for the given mesh.\r\n     * @param lightIndex Light index\r\n     * @param scene The scene where the light belongs to\r\n     * @param effect The effect we are binding the data to\r\n     * @param useSpecular Defines if specular is supported\r\n     * @param receiveShadows Defines if the effect (mesh) we bind the light for receives shadows\r\n     */\r\n    public _bindLight(lightIndex: number, scene: Scene, effect: Effect, useSpecular: boolean, receiveShadows = true): void {\r\n        const iAsString = lightIndex.toString();\r\n        let needUpdate = false;\r\n\r\n        this._uniformBuffer.bindToEffect(effect, \"Light\" + iAsString);\r\n\r\n        if (this._renderId !== scene.getRenderId() || this._lastUseSpecular !== useSpecular || !this._uniformBuffer.useUbo) {\r\n            this._renderId = scene.getRenderId();\r\n            this._lastUseSpecular = useSpecular;\r\n\r\n            const scaledIntensity = this.getScaledIntensity();\r\n\r\n            this.transferToEffect(effect, iAsString);\r\n\r\n            this.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);\r\n            this._uniformBuffer.updateColor4(\"vLightDiffuse\", TmpColors.Color3[0], this.range, iAsString);\r\n            if (useSpecular) {\r\n                this.specular.scaleToRef(scaledIntensity, TmpColors.Color3[1]);\r\n                this._uniformBuffer.updateColor4(\"vLightSpecular\", TmpColors.Color3[1], this.radius, iAsString);\r\n            }\r\n            needUpdate = true;\r\n        }\r\n\r\n        // Textures might still need to be rebound.\r\n        this.transferTexturesToEffect(effect, iAsString);\r\n\r\n        // Shadows\r\n        if (scene.shadowsEnabled && this.shadowEnabled && receiveShadows) {\r\n            const shadowGenerator = this.getShadowGenerator(scene.activeCamera) ?? this.getShadowGenerator();\r\n            if (shadowGenerator) {\r\n                shadowGenerator.bindShadowLight(iAsString, effect);\r\n                needUpdate = true;\r\n            }\r\n        }\r\n\r\n        if (needUpdate) {\r\n            this._uniformBuffer.update();\r\n        } else {\r\n            this._uniformBuffer.bindUniformBuffer();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the passed Effect \"effect\" with the Light information.\r\n     * @param effect The effect to update\r\n     * @param lightDataUniformName The uniform used to store light data (position or direction)\r\n     * @returns The light\r\n     */\r\n    public abstract transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;\r\n\r\n    /**\r\n     * Returns the string \"Light\".\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"Light\";\r\n    }\r\n\r\n    /** @internal */\r\n    public readonly _isLight = true;\r\n\r\n    /**\r\n     * Converts the light information to a readable string for debug purpose.\r\n     * @param fullDetails Supports for multiple levels of logging within scene loading\r\n     * @returns the human readable light info\r\n     */\r\n    public override toString(fullDetails?: boolean): string {\r\n        let ret = \"Name: \" + this.name;\r\n        ret += \", type: \" + [\"Point\", \"Directional\", \"Spot\", \"Hemispheric\", \"Clustered\"][this.getTypeID()];\r\n        if (this.animations) {\r\n            for (let i = 0; i < this.animations.length; i++) {\r\n                ret += \", animation[0]: \" + this.animations[i].toString(fullDetails);\r\n            }\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /** @internal */\r\n    protected override _syncParentEnabledState() {\r\n        super._syncParentEnabledState();\r\n        if (!this.isDisposed()) {\r\n            this._resyncMeshes();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the enabled state of this node.\r\n     * @param value - the new enabled state\r\n     */\r\n    public override setEnabled(value: boolean): void {\r\n        super.setEnabled(value);\r\n\r\n        this._resyncMeshes();\r\n    }\r\n\r\n    /**\r\n     * Returns the Light associated shadow generator if any.\r\n     * @param camera Camera for which the shadow generator should be retrieved (default: null). If null, retrieves the default shadow generator\r\n     * @returns the associated shadow generator.\r\n     */\r\n    public getShadowGenerator(camera: Nullable<Camera> = null): Nullable<IShadowGenerator> {\r\n        if (this._shadowGenerators === null) {\r\n            return null;\r\n        }\r\n\r\n        return this._shadowGenerators.get(camera) ?? null;\r\n    }\r\n\r\n    /**\r\n     * Returns all the shadow generators associated to this light\r\n     * @returns\r\n     */\r\n    public getShadowGenerators(): Nullable<Map<Nullable<Camera>, IShadowGenerator>> {\r\n        return this._shadowGenerators;\r\n    }\r\n\r\n    /**\r\n     * Returns a Vector3, the absolute light position in the World.\r\n     * @returns the world space position of the light\r\n     */\r\n    public getAbsolutePosition(): Vector3 {\r\n        return Vector3.Zero();\r\n    }\r\n\r\n    /**\r\n     * Specifies if the light will affect the passed mesh.\r\n     * @param mesh The mesh to test against the light\r\n     * @returns true the mesh is affected otherwise, false.\r\n     */\r\n    public canAffectMesh(mesh: AbstractMesh): boolean {\r\n        if (!mesh) {\r\n            return true;\r\n        }\r\n\r\n        if (this.includedOnlyMeshes && this.includedOnlyMeshes.length > 0 && this.includedOnlyMeshes.indexOf(mesh) === -1) {\r\n            return false;\r\n        }\r\n\r\n        if (this.excludedMeshes && this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1) {\r\n            return false;\r\n        }\r\n\r\n        if (this.includeOnlyWithLayerMask !== 0 && (this.includeOnlyWithLayerMask & mesh.layerMask) === 0) {\r\n            return false;\r\n        }\r\n\r\n        if (this.excludeWithLayerMask !== 0 && this.excludeWithLayerMask & mesh.layerMask) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Releases resources associated with this node.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        if (this._shadowGenerators) {\r\n            const iterator = this._shadowGenerators.values();\r\n            for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                const shadowGenerator = key.value;\r\n                shadowGenerator.dispose();\r\n            }\r\n            this._shadowGenerators = null;\r\n        }\r\n\r\n        // Animations\r\n        this.getScene().stopAnimation(this);\r\n\r\n        if (this._parentContainer) {\r\n            const index = this._parentContainer.lights.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.lights.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        // Remove from meshes\r\n        for (const mesh of this.getScene().meshes) {\r\n            mesh._removeLightSource(this, true);\r\n        }\r\n\r\n        this._uniformBuffer.dispose();\r\n\r\n        // Remove from scene\r\n        this.getScene().removeLight(this);\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n\r\n    /**\r\n     * Returns the light type ID (integer).\r\n     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public getTypeID(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Returns the intensity scaled by the Photometric Scale according to the light type and intensity mode.\r\n     * @returns the scaled intensity in intensity mode unit\r\n     */\r\n    public getScaledIntensity() {\r\n        return this._photometricScale * this.intensity;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Light object, named \"name\", from the current one.\r\n     * @param name The name of the cloned light\r\n     * @param newParent The parent of this light, if it has one\r\n     * @returns the new created light\r\n     */\r\n    public override clone(name: string, newParent: Nullable<Node> = null): Nullable<Light> {\r\n        const constructor = Light.GetConstructorFromName(this.getTypeID(), name, this.getScene());\r\n\r\n        if (!constructor) {\r\n            return null;\r\n        }\r\n        const clonedLight = SerializationHelper.Clone(constructor, this);\r\n        if (name) {\r\n            clonedLight.name = name;\r\n        }\r\n        if (newParent) {\r\n            clonedLight.parent = newParent;\r\n        }\r\n        clonedLight.setEnabled(this.isEnabled());\r\n\r\n        this.onClonedObservable.notifyObservers(clonedLight);\r\n\r\n        return clonedLight;\r\n    }\r\n\r\n    /**\r\n     * Serializes the current light into a Serialization object.\r\n     * @returns the serialized object.\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        serializationObject.uniqueId = this.uniqueId;\r\n\r\n        // Type\r\n        serializationObject.type = this.getTypeID();\r\n\r\n        // Parent\r\n        if (this.parent) {\r\n            this.parent._serializeAsParent(serializationObject);\r\n        }\r\n\r\n        // Inclusion / exclusions\r\n        if (this.excludedMeshes.length > 0) {\r\n            serializationObject.excludedMeshesIds = [];\r\n            for (const mesh of this.excludedMeshes) {\r\n                serializationObject.excludedMeshesIds.push(mesh.id);\r\n            }\r\n        }\r\n\r\n        if (this.includedOnlyMeshes.length > 0) {\r\n            serializationObject.includedOnlyMeshesIds = [];\r\n            for (const mesh of this.includedOnlyMeshes) {\r\n                serializationObject.includedOnlyMeshesIds.push(mesh.id);\r\n            }\r\n        }\r\n\r\n        // Animations\r\n        SerializationHelper.AppendSerializedAnimations(this, serializationObject);\r\n        serializationObject.ranges = this.serializeAnimationRanges();\r\n\r\n        serializationObject.isEnabled = this.isEnabled();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Creates a new typed light from the passed type (integer) : point light = 0, directional light = 1, spot light = 2, hemispheric light = 3.\r\n     * This new light is named \"name\" and added to the passed scene.\r\n     * @param type Type according to the types available in Light.LIGHTTYPEID_x\r\n     * @param name The friendly name of the light\r\n     * @param scene The scene the new light will belong to\r\n     * @returns the constructor function\r\n     */\r\n    static GetConstructorFromName(type: number, name: string, scene: Scene): Nullable<() => Light> {\r\n        const constructorFunc = Node.Construct(\"Light_Type_\" + type, name, scene);\r\n\r\n        if (constructorFunc) {\r\n            return <() => Light>constructorFunc;\r\n        }\r\n\r\n        // Default to no light for none present once.\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Parses the passed \"parsedLight\" and returns a new instanced Light from this parsing.\r\n     * @param parsedLight The JSON representation of the light\r\n     * @param scene The scene to create the parsed light in\r\n     * @param rootUrl The root url to use to load assets referenced by the light (e.g. textures)\r\n     * @returns the created light after parsing\r\n     */\r\n    public static Parse(parsedLight: any, scene: Scene, rootUrl: string = \"\"): Nullable<Light> {\r\n        const constructor = Light.GetConstructorFromName(parsedLight.type, parsedLight.name, scene);\r\n\r\n        if (!constructor) {\r\n            return null;\r\n        }\r\n\r\n        const light = SerializationHelper.Parse(constructor, parsedLight, scene, rootUrl);\r\n\r\n        // Inclusion / exclusions\r\n        if (parsedLight.excludedMeshesIds) {\r\n            light._excludedMeshesIds = parsedLight.excludedMeshesIds;\r\n        }\r\n\r\n        if (parsedLight.includedOnlyMeshesIds) {\r\n            light._includedOnlyMeshesIds = parsedLight.includedOnlyMeshesIds;\r\n        }\r\n\r\n        // Parent\r\n        if (parsedLight.parentId !== undefined) {\r\n            light._waitingParentId = parsedLight.parentId;\r\n        }\r\n\r\n        if (parsedLight.parentInstanceIndex !== undefined) {\r\n            light._waitingParentInstanceIndex = parsedLight.parentInstanceIndex;\r\n        }\r\n\r\n        // Falloff\r\n        if (parsedLight.falloffType !== undefined) {\r\n            light.falloffType = parsedLight.falloffType;\r\n        }\r\n\r\n        // Lightmaps\r\n        if (parsedLight.lightmapMode !== undefined) {\r\n            light.lightmapMode = parsedLight.lightmapMode;\r\n        }\r\n\r\n        // Animations\r\n        if (parsedLight.animations) {\r\n            for (let animationIndex = 0; animationIndex < parsedLight.animations.length; animationIndex++) {\r\n                const parsedAnimation = parsedLight.animations[animationIndex];\r\n                const internalClass = GetClass(\"BABYLON.Animation\");\r\n                if (internalClass) {\r\n                    light.animations.push(internalClass.Parse(parsedAnimation));\r\n                }\r\n            }\r\n            Node.ParseAnimationRanges(light, parsedLight, scene);\r\n        }\r\n\r\n        if (parsedLight.autoAnimate) {\r\n            scene.beginAnimation(light, parsedLight.autoAnimateFrom, parsedLight.autoAnimateTo, parsedLight.autoAnimateLoop, parsedLight.autoAnimateSpeed || 1.0);\r\n        }\r\n\r\n        // Check if isEnabled is defined to be back compatible with prior serialized versions.\r\n        if (parsedLight.isEnabled !== undefined) {\r\n            light.setEnabled(parsedLight.isEnabled);\r\n        }\r\n\r\n        light._onParsed(parsedLight, scene, rootUrl);\r\n\r\n        return light;\r\n    }\r\n\r\n    /**\r\n     * Called after the light has been fully parsed and all base properties have been set.\r\n     * Override in subclasses to handle custom serialized data.\r\n     * @param _parsedLight The JSON representation of the light\r\n     * @param _scene The scene the light belongs to\r\n     * @param _rootUrl The root url to use to load assets referenced by the light (e.g. textures)\r\n     */\r\n    protected _onParsed(_parsedLight: any, _scene: Scene, _rootUrl: string = \"\"): void {\r\n        // Override in subclasses\r\n    }\r\n\r\n    private _hookArrayForExcluded(array: AbstractMesh[]): void {\r\n        const oldPush = array.push;\r\n        array.push = (...items: AbstractMesh[]) => {\r\n            const result = oldPush.apply(array, items);\r\n\r\n            if (this._clusteredContainer) {\r\n                return result;\r\n            }\r\n\r\n            for (const item of items) {\r\n                item._resyncLightSource(this);\r\n            }\r\n\r\n            return result;\r\n        };\r\n\r\n        const oldSplice = array.splice;\r\n        array.splice = (index: number, deleteCount?: number) => {\r\n            const deleted = oldSplice.call(array, index, deleteCount ?? array.length);\r\n\r\n            if (this._clusteredContainer) {\r\n                return deleted;\r\n            }\r\n\r\n            for (const item of deleted) {\r\n                item._resyncLightSource(this);\r\n            }\r\n\r\n            return deleted;\r\n        };\r\n\r\n        // Re-sync every mesh rather than just the ones in the new array: a mesh removed from the\r\n        // exclusion list would otherwise stay unlit. Mirrors _hookArrayForIncludedOnly.\r\n        this._resyncMeshes();\r\n    }\r\n\r\n    private _hookArrayForIncludedOnly(array: AbstractMesh[]): void {\r\n        const oldPush = array.push;\r\n        array.push = (...items: AbstractMesh[]) => {\r\n            const result = oldPush.apply(array, items);\r\n\r\n            this._resyncMeshes();\r\n\r\n            return result;\r\n        };\r\n\r\n        const oldSplice = array.splice;\r\n        array.splice = (index: number, deleteCount?: number) => {\r\n            const deleted = oldSplice.call(array, index, deleteCount ?? array.length);\r\n\r\n            this._resyncMeshes();\r\n\r\n            return deleted;\r\n        };\r\n\r\n        this._resyncMeshes();\r\n    }\r\n\r\n    private _resyncMeshes() {\r\n        if (this._clusteredContainer) {\r\n            return;\r\n        }\r\n\r\n        for (const mesh of this.getScene().meshes) {\r\n            mesh._resyncLightSource(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Forces the meshes to update their light related information in their rendering used effects\r\n     * @internal Internal Use Only\r\n     */\r\n    public _markMeshesAsLightDirty() {\r\n        for (const mesh of this.getScene().meshes) {\r\n            if (mesh.lightSources.indexOf(this) !== -1) {\r\n                mesh._markSubMeshesAsLightDirty();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Recomputes the cached photometric scale if needed.\r\n     */\r\n    private _computePhotometricScale(): void {\r\n        this._photometricScale = this._getPhotometricScale();\r\n        this.getScene().resetCachedMaterial();\r\n    }\r\n\r\n    /**\r\n     * @returns the Photometric Scale according to the light type and intensity mode.\r\n     */\r\n    private _getPhotometricScale() {\r\n        let photometricScale = 0.0;\r\n        const lightTypeID = this.getTypeID();\r\n\r\n        //get photometric mode\r\n        let photometricMode = this.intensityMode;\r\n        if (photometricMode === Light.INTENSITYMODE_AUTOMATIC) {\r\n            if (lightTypeID === Light.LIGHTTYPEID_DIRECTIONALLIGHT) {\r\n                photometricMode = Light.INTENSITYMODE_ILLUMINANCE;\r\n            } else {\r\n                photometricMode = Light.INTENSITYMODE_LUMINOUSINTENSITY;\r\n            }\r\n        }\r\n\r\n        //compute photometric scale\r\n        switch (lightTypeID) {\r\n            case Light.LIGHTTYPEID_POINTLIGHT:\r\n            case Light.LIGHTTYPEID_SPOTLIGHT:\r\n                switch (photometricMode) {\r\n                    case Light.INTENSITYMODE_LUMINOUSPOWER:\r\n                        photometricScale = 1.0 / (4.0 * Math.PI);\r\n                        break;\r\n                    case Light.INTENSITYMODE_LUMINOUSINTENSITY:\r\n                        photometricScale = 1.0;\r\n                        break;\r\n                    case Light.INTENSITYMODE_LUMINANCE:\r\n                        photometricScale = this.radius * this.radius;\r\n                        break;\r\n                }\r\n                break;\r\n\r\n            case Light.LIGHTTYPEID_DIRECTIONALLIGHT:\r\n                switch (photometricMode) {\r\n                    case Light.INTENSITYMODE_ILLUMINANCE:\r\n                        photometricScale = 1.0;\r\n                        break;\r\n                    case Light.INTENSITYMODE_LUMINANCE: {\r\n                        // When radius (and therefore solid angle) is non-zero a directional lights brightness can be specified via central (peak) luminance.\r\n                        // For a directional light the 'radius' defines the angular radius (in radians) rather than world-space radius (e.g. in metres).\r\n                        let apexAngleRadians = this.radius;\r\n                        // Impose a minimum light angular size to avoid the light becoming an infinitely small angular light source (i.e. a dirac delta function).\r\n                        apexAngleRadians = Math.max(apexAngleRadians, 0.001);\r\n                        const solidAngle = 2.0 * Math.PI * (1.0 - Math.cos(apexAngleRadians));\r\n                        photometricScale = solidAngle;\r\n                        break;\r\n                    }\r\n                }\r\n                break;\r\n\r\n            case Light.LIGHTTYPEID_HEMISPHERICLIGHT:\r\n                // No fall off in hemispheric light.\r\n                photometricScale = 1.0;\r\n                break;\r\n\r\n            case Light.LIGHTTYPEID_RECT_AREALIGHT:\r\n                // Area lights interpret their intensity directly; no additional photometric scaling is applied.\r\n                photometricScale = 1.0;\r\n                break;\r\n        }\r\n        return photometricScale;\r\n    }\r\n\r\n    /**\r\n     * Reorder the light in the scene according to their defined priority.\r\n     * @internal Internal Use Only\r\n     */\r\n    public _reorderLightsInScene(): void {\r\n        const scene = this.getScene();\r\n        if (this._renderPriority != 0) {\r\n            scene.requireLightSorting = true;\r\n        }\r\n        this.getScene().sortLightsByPriority();\r\n    }\r\n\r\n    /**\r\n     * Returns true when all texture resources used by this light are ready (e.g. projection textures).\r\n     * Override in subclasses that use texture resources.\r\n     * @returns true if all light textures are ready\r\n     */\r\n    public areLightTexturesReady(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Prepares the list of defines specific to the light type.\r\n     * @param defines the list of defines\r\n     * @param lightIndex defines the index of the light for the effect\r\n     */\r\n    public abstract prepareLightSpecificDefines(defines: any, lightIndex: number): void;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _isReady() {\r\n        return true;\r\n    }\r\n}\r\n","import { type Scene } from \"./scene\";\r\nimport { Mesh } from \"./Meshes/mesh.pure\";\r\nimport { TransformNode } from \"./Meshes/transformNode.pure\";\r\nimport { type Skeleton } from \"./Bones/skeleton\";\r\nimport { type AnimationGroup } from \"./Animations/animationGroup\";\r\nimport { type Animatable } from \"./Animations/animatable.core\";\r\nimport { AbstractMesh } from \"./Meshes/abstractMesh.pure\";\r\nimport { type MultiMaterial } from \"./Materials/multiMaterial\";\r\nimport { type Material } from \"./Materials/material\";\r\nimport { Logger } from \"./Misc/logger\";\r\nimport { EngineStore } from \"./Engines/engineStore\";\r\nimport { type Nullable } from \"./types\";\r\nimport { type Node } from \"./node\";\r\nimport { type Observer } from \"./Misc/observable\";\r\nimport { type AbstractEngine } from \"./Engines/abstractEngine\";\r\nimport { InstancedMesh } from \"./Meshes/instancedMesh.pure\";\r\nimport { Light } from \"./Lights/light\";\r\nimport { Camera } from \"./Cameras/camera.pure\";\r\nimport { Tools } from \"./Misc/tools.pure\";\r\nimport { type IParticleSystem } from \"./Particles/IParticleSystem\";\r\nimport { type IAssetContainer } from \"./IAssetContainer\";\r\nimport { type Animation } from \"./Animations/animation\";\r\nimport { type MorphTargetManager } from \"./Morph/morphTargetManager\";\r\nimport { type Geometry } from \"./Meshes/geometry\";\r\nimport { type AbstractActionManager } from \"./Actions/abstractActionManager\";\r\nimport { type BaseTexture } from \"./Materials/Textures/baseTexture\";\r\nimport { type PostProcess } from \"./PostProcesses/postProcess\";\r\nimport { type Sound } from \"./Audio/sound\";\r\nimport { type Layer } from \"./Layers/layer\";\r\nimport { type EffectLayer } from \"./Layers/effectLayer\";\r\nimport { type ReflectionProbe } from \"./Probes/reflectionProbe\";\r\nimport { type LensFlareSystem } from \"./LensFlares/lensFlareSystem\";\r\nimport { type ProceduralTexture } from \"./Materials/Textures/Procedurals/proceduralTexture\";\r\nimport { type SpriteManager } from \"./Sprites/spriteManager\";\r\nimport { Tags } from \"./Misc/tags\";\r\n\r\n/**\r\n * Root class for AssetContainer and KeepAssets\r\n */\r\nexport class AbstractAssetContainer implements IAssetContainer {\r\n    /**\r\n     * Gets the list of root nodes (ie. nodes with no parent)\r\n     */\r\n    public rootNodes: Node[] = [];\r\n\r\n    /** All of the cameras added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n     */\r\n    public cameras: Camera[] = [];\r\n\r\n    /**\r\n     * All of the lights added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     */\r\n    public lights: Light[] = [];\r\n\r\n    /**\r\n     * All of the (abstract) meshes added to this scene\r\n     */\r\n    public meshes: AbstractMesh[] = [];\r\n\r\n    /**\r\n     * The list of skeletons added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n     */\r\n    public skeletons: Skeleton[] = [];\r\n\r\n    /**\r\n     * All of the particle systems added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro\r\n     */\r\n    public particleSystems: IParticleSystem[] = [];\r\n\r\n    /**\r\n     * Gets a list of Animations associated with the scene\r\n     */\r\n    public animations: Animation[] = [];\r\n\r\n    /**\r\n     * All of the animation groups added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/groupAnimations\r\n     */\r\n    public animationGroups: AnimationGroup[] = [];\r\n\r\n    /**\r\n     * All of the multi-materials added to this scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials\r\n     */\r\n    public multiMaterials: MultiMaterial[] = [];\r\n\r\n    /**\r\n     * All of the materials added to this scene\r\n     * In the context of a Scene, it is not supposed to be modified manually.\r\n     * Any addition or removal should be done using the addMaterial and removeMaterial Scene methods.\r\n     * Note also that the order of the Material within the array is not significant and might change.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction\r\n     */\r\n    public materials: Material[] = [];\r\n\r\n    /**\r\n     * The list of morph target managers added to the scene\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph\r\n     */\r\n    public morphTargetManagers: MorphTargetManager[] = [];\r\n\r\n    /**\r\n     * The list of geometries used in the scene.\r\n     */\r\n    public geometries: Geometry[] = [];\r\n\r\n    /**\r\n     * All of the transform nodes added to this scene\r\n     * In the context of a Scene, it is not supposed to be modified manually.\r\n     * Any addition or removal should be done using the addTransformNode and removeTransformNode Scene methods.\r\n     * Note also that the order of the TransformNode within the array is not significant and might change.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/parent_pivot/transform_node\r\n     */\r\n    public transformNodes: TransformNode[] = [];\r\n\r\n    /**\r\n     * ActionManagers available on the scene.\r\n     * @deprecated\r\n     */\r\n    public actionManagers: AbstractActionManager[] = [];\r\n\r\n    /**\r\n     * Textures to keep.\r\n     */\r\n    public textures: BaseTexture[] = [];\r\n\r\n    /** @internal */\r\n    protected _environmentTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Texture used in all pbr material as the reflection texture.\r\n     * As in the majority of the scene they are the same (exception for multi room and so on),\r\n     * this is easier to reference from here than from all the materials.\r\n     */\r\n    public get environmentTexture(): Nullable<BaseTexture> {\r\n        return this._environmentTexture;\r\n    }\r\n\r\n    public set environmentTexture(value: Nullable<BaseTexture>) {\r\n        this._environmentTexture = value;\r\n    }\r\n\r\n    /**\r\n     * The list of postprocesses added to the scene\r\n     */\r\n    public postProcesses: PostProcess[] = [];\r\n\r\n    /**\r\n     * The list of sounds\r\n     */\r\n    public sounds: Nullable<Sound[]> = null;\r\n\r\n    /**\r\n     * The list of effect layers added to the scene\r\n     */\r\n    public effectLayers: EffectLayer[] = [];\r\n\r\n    /**\r\n     * The list of layers added to the scene\r\n     */\r\n    public layers: Layer[] = [];\r\n\r\n    /**\r\n     * The list of reflection probes added to the scene\r\n     */\r\n    public reflectionProbes: ReflectionProbe[] = [];\r\n\r\n    /**\r\n     * The list of lens flare systems added to the scene\r\n     */\r\n    public lensFlareSystems: LensFlareSystem[];\r\n\r\n    /**\r\n     * The list of procedural textures added to the scene\r\n     */\r\n    public proceduralTextures: ProceduralTexture[];\r\n\r\n    /**\r\n     * The list of sprite managers added to the scene\r\n     */\r\n    public spriteManagers: SpriteManager[] = [];\r\n\r\n    /**\r\n     * @returns all meshes, lights, cameras, transformNodes and bones\r\n     */\r\n    public getNodes(): Array<Node> {\r\n        let nodes: Node[] = [];\r\n        nodes = nodes.concat(this.meshes);\r\n        nodes = nodes.concat(this.lights);\r\n        nodes = nodes.concat(this.cameras);\r\n        nodes = nodes.concat(this.transformNodes); // dummies\r\n        for (const skeleton of this.skeletons) {\r\n            nodes = nodes.concat(skeleton.bones);\r\n        }\r\n        return nodes;\r\n    }\r\n}\r\n\r\n/**\r\n * Set of assets to keep when moving a scene into an asset container.\r\n */\r\nexport class KeepAssets extends AbstractAssetContainer {}\r\n\r\n/**\r\n * Class used to store the output of the AssetContainer.instantiateAllMeshesToScene function\r\n */\r\nexport class InstantiatedEntries {\r\n    /**\r\n     * List of new root nodes (eg. nodes with no parent)\r\n     */\r\n    public rootNodes: Node[] = [];\r\n\r\n    /**\r\n     * List of new skeletons\r\n     */\r\n    public skeletons: Skeleton[] = [];\r\n\r\n    /**\r\n     * List of new animation groups\r\n     */\r\n    public animationGroups: AnimationGroup[] = [];\r\n\r\n    /**\r\n     * Disposes the instantiated entries from the scene\r\n     */\r\n    public dispose() {\r\n        const rootNodes = this.rootNodes;\r\n        for (const rootNode of rootNodes) {\r\n            rootNode.dispose();\r\n        }\r\n        rootNodes.length = 0;\r\n\r\n        const skeletons = this.skeletons;\r\n        for (const skeleton of skeletons) {\r\n            skeleton.dispose();\r\n        }\r\n        skeletons.length = 0;\r\n\r\n        const animationGroups = this.animationGroups;\r\n        for (const animationGroup of animationGroups) {\r\n            animationGroup.dispose();\r\n        }\r\n        animationGroups.length = 0;\r\n    }\r\n}\r\n\r\n/**\r\n * Container with a set of assets that can be added or removed from a scene.\r\n */\r\nexport class AssetContainer extends AbstractAssetContainer {\r\n    private _wasAddedToScene = false;\r\n    private _onContextRestoredObserver: Nullable<Observer<AbstractEngine>>;\r\n\r\n    /**\r\n     * The scene the AssetContainer belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Instantiates an AssetContainer.\r\n     * @param scene The scene the AssetContainer belongs to.\r\n     */\r\n    constructor(scene?: Nullable<Scene>) {\r\n        super();\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this.scene = scene;\r\n        this[\"proceduralTextures\"] = [];\r\n\r\n        scene.onDisposeObservable.add(() => {\r\n            if (!this._wasAddedToScene) {\r\n                this.dispose();\r\n            }\r\n        });\r\n\r\n        this._onContextRestoredObserver = scene.getEngine().onContextRestoredObservable.add(() => {\r\n            for (const geometry of this.geometries) {\r\n                geometry._rebuild();\r\n            }\r\n\r\n            for (const mesh of this.meshes) {\r\n                mesh._rebuild();\r\n            }\r\n\r\n            for (const system of this.particleSystems) {\r\n                system.rebuild();\r\n            }\r\n\r\n            for (const texture of this.textures) {\r\n                texture._rebuild();\r\n            }\r\n\r\n            for (const spriteManager of this.spriteManagers) {\r\n                spriteManager.rebuild();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Given a list of nodes, return a topological sorting of them.\r\n     * @param nodes\r\n     * @returns a sorted array of nodes\r\n     */\r\n    private _topologicalSort(nodes: Node[]): Node[] {\r\n        const nodesUidMap = new Map<number, Node>();\r\n\r\n        for (const node of nodes) {\r\n            nodesUidMap.set(node.uniqueId, node);\r\n        }\r\n\r\n        const dependencyGraph = {\r\n            dependsOn: new Map<number, Set<number>>(), // given a node id, what are the ids of the nodes it depends on\r\n            dependedBy: new Map<number, Set<number>>(), // given a node id, what are the ids of the nodes that depend on it\r\n        };\r\n\r\n        // Build the dependency graph given the list of nodes\r\n\r\n        // First pass: Initialize the empty dependency graph\r\n        for (const node of nodes) {\r\n            const nodeId = node.uniqueId;\r\n            dependencyGraph.dependsOn.set(nodeId, new Set<number>());\r\n            dependencyGraph.dependedBy.set(nodeId, new Set<number>());\r\n        }\r\n\r\n        // Second pass: Populate the dependency graph. We assume that we\r\n        // don't need to check for cycles here, as the scene graph cannot\r\n        // contain cycles. Our graph also already contains all transitive\r\n        // dependencies because getDescendants returns the transitive\r\n        // dependencies by default.\r\n        for (const node of nodes) {\r\n            const nodeId = node.uniqueId;\r\n            const dependsOn = dependencyGraph.dependsOn.get(nodeId)!;\r\n            if (node instanceof InstancedMesh) {\r\n                const masterMesh = node.sourceMesh;\r\n                if (nodesUidMap.has(masterMesh.uniqueId)) {\r\n                    dependsOn.add(masterMesh.uniqueId);\r\n                    dependencyGraph.dependedBy.get(masterMesh.uniqueId)!.add(nodeId);\r\n                }\r\n            }\r\n            const dependedBy = dependencyGraph.dependedBy.get(nodeId)!;\r\n\r\n            for (const child of node.getDescendants()) {\r\n                const childId = child.uniqueId;\r\n                if (nodesUidMap.has(childId)) {\r\n                    dependedBy.add(childId);\r\n\r\n                    const childDependsOn = dependencyGraph.dependsOn.get(childId)!;\r\n                    childDependsOn.add(nodeId);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Third pass: Topological sort\r\n        const sortedNodes: Node[] = [];\r\n\r\n        // First: Find all nodes that have no dependencies\r\n        const leaves: Node[] = [];\r\n        for (const node of nodes) {\r\n            const nodeId = node.uniqueId;\r\n            if (dependencyGraph.dependsOn.get(nodeId)!.size === 0) {\r\n                leaves.push(node);\r\n                nodesUidMap.delete(nodeId);\r\n            }\r\n        }\r\n\r\n        const visitList = leaves;\r\n        while (visitList.length > 0) {\r\n            const nodeToVisit = visitList.shift()!;\r\n\r\n            sortedNodes.push(nodeToVisit);\r\n\r\n            // Remove the node from the dependency graph\r\n            // When a node is visited, we know that dependsOn is empty.\r\n            // So we only need to remove the node from dependedBy.\r\n            const dependedByVisitedNode = dependencyGraph.dependedBy.get(nodeToVisit.uniqueId)!;\r\n            // Array.from(x.values()) is to make the TS compiler happy\r\n            for (const dependedByVisitedNodeId of Array.from(dependedByVisitedNode.values())) {\r\n                const dependsOnDependedByVisitedNode = dependencyGraph.dependsOn.get(dependedByVisitedNodeId)!;\r\n                dependsOnDependedByVisitedNode.delete(nodeToVisit.uniqueId);\r\n\r\n                if (dependsOnDependedByVisitedNode.size === 0 && nodesUidMap.get(dependedByVisitedNodeId)) {\r\n                    visitList.push(nodesUidMap.get(dependedByVisitedNodeId)!);\r\n                    nodesUidMap.delete(dependedByVisitedNodeId);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (nodesUidMap.size > 0) {\r\n            Logger.Error(\"SceneSerializer._topologicalSort: There were unvisited nodes:\");\r\n            nodesUidMap.forEach((node) => {\r\n                Logger.Error(node.name);\r\n            });\r\n        }\r\n\r\n        return sortedNodes;\r\n    }\r\n\r\n    private _addNodeAndDescendantsToList(list: Node[], addedIds: Set<number>, rootNode?: Node, predicate?: (entity: any) => boolean) {\r\n        if (!rootNode || (predicate && !predicate(rootNode)) || addedIds.has(rootNode.uniqueId)) {\r\n            return;\r\n        }\r\n\r\n        list.push(rootNode);\r\n        addedIds.add(rootNode.uniqueId);\r\n\r\n        for (const child of rootNode.getDescendants(true)) {\r\n            this._addNodeAndDescendantsToList(list, addedIds, child, predicate);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Check if a specific node is contained in this asset container.\r\n     * @param node the node to check\r\n     * @returns true if the node is contained in this container, otherwise false.\r\n     */\r\n    private _isNodeInContainer(node: Node) {\r\n        if (node instanceof AbstractMesh && this.meshes.indexOf(node) !== -1) {\r\n            return true;\r\n        }\r\n        if (node instanceof TransformNode && this.transformNodes.indexOf(node) !== -1) {\r\n            return true;\r\n        }\r\n        if (node instanceof Light && this.lights.indexOf(node) !== -1) {\r\n            return true;\r\n        }\r\n        if (node instanceof Camera && this.cameras.indexOf(node) !== -1) {\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * For every node in the scene, check if its parent node is also in the scene.\r\n     * @returns true if every node's parent is also in the scene, otherwise false.\r\n     */\r\n    private _isValidHierarchy() {\r\n        for (const node of this.meshes) {\r\n            if (node.parent && !this._isNodeInContainer(node.parent)) {\r\n                Logger.Warn(`Node ${node.name} has a parent that is not in the container.`);\r\n                return false;\r\n            }\r\n        }\r\n        for (const node of this.transformNodes) {\r\n            if (node.parent && !this._isNodeInContainer(node.parent)) {\r\n                Logger.Warn(`Node ${node.name} has a parent that is not in the container.`);\r\n                return false;\r\n            }\r\n        }\r\n        for (const node of this.lights) {\r\n            if (node.parent && !this._isNodeInContainer(node.parent)) {\r\n                Logger.Warn(`Node ${node.name} has a parent that is not in the container.`);\r\n                return false;\r\n            }\r\n        }\r\n        for (const node of this.cameras) {\r\n            if (node.parent && !this._isNodeInContainer(node.parent)) {\r\n                Logger.Warn(`Node ${node.name} has a parent that is not in the container.`);\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Instantiate or clone all meshes and add the new ones to the scene.\r\n     * Skeletons and animation groups will all be cloned\r\n     * @param nameFunction defines an optional function used to get new names for clones\r\n     * @param cloneMaterials defines an optional boolean that defines if materials must be cloned as well (false by default)\r\n     * @param options defines an optional list of options to control how to instantiate / clone models\r\n     * @param options.doNotInstantiate defines if the model must be instantiated or just cloned\r\n     * @param options.predicate defines a predicate used to filter whih mesh to instantiate/clone\r\n     * @returns a list of rootNodes, skeletons and animation groups that were duplicated\r\n     */\r\n    public instantiateModelsToScene(\r\n        nameFunction?: (sourceName: string) => string,\r\n        cloneMaterials = false,\r\n        options?: { doNotInstantiate?: boolean | ((node: Node) => boolean); predicate?: (entity: any) => boolean }\r\n    ): InstantiatedEntries {\r\n        if (!this._isValidHierarchy()) {\r\n            Tools.Warn(\"SceneSerializer.InstantiateModelsToScene: The Asset Container hierarchy is not valid.\");\r\n        }\r\n        const conversionMap: { [key: number]: number } = {};\r\n        const storeMap: { [key: number]: any } = {};\r\n        const result = new InstantiatedEntries();\r\n        const alreadySwappedSkeletons: Skeleton[] = [];\r\n        const alreadySwappedMaterials: Material[] = [];\r\n\r\n        const localOptions = {\r\n            doNotInstantiate: true,\r\n            ...options,\r\n        };\r\n\r\n        const onClone = (source: Node, clone: Node) => {\r\n            conversionMap[source.uniqueId] = clone.uniqueId;\r\n            storeMap[clone.uniqueId] = clone;\r\n\r\n            if (nameFunction) {\r\n                clone.name = nameFunction(source.name);\r\n            }\r\n\r\n            if (clone instanceof Mesh) {\r\n                const clonedMesh = clone;\r\n\r\n                if (clonedMesh.morphTargetManager) {\r\n                    const oldMorphTargetManager = (source as Mesh).morphTargetManager!;\r\n                    clonedMesh.morphTargetManager = oldMorphTargetManager.clone();\r\n\r\n                    for (let index = 0; index < oldMorphTargetManager.numTargets; index++) {\r\n                        const oldTarget = oldMorphTargetManager.getTarget(index);\r\n                        const newTarget = clonedMesh.morphTargetManager.getTarget(index);\r\n\r\n                        conversionMap[oldTarget.uniqueId] = newTarget.uniqueId;\r\n                        storeMap[newTarget.uniqueId] = newTarget;\r\n                    }\r\n                }\r\n            }\r\n        };\r\n\r\n        const nodesToSort: Node[] = [];\r\n        const idsOnSortList = new Set<number>();\r\n\r\n        for (const transformNode of this.transformNodes) {\r\n            if (transformNode.parent === null) {\r\n                this._addNodeAndDescendantsToList(nodesToSort, idsOnSortList, transformNode, localOptions.predicate);\r\n            }\r\n        }\r\n\r\n        for (const mesh of this.meshes) {\r\n            if (mesh.parent === null) {\r\n                this._addNodeAndDescendantsToList(nodesToSort, idsOnSortList, mesh, localOptions.predicate);\r\n            }\r\n        }\r\n\r\n        // Topologically sort nodes by parenting/instancing relationships so that all resources are in place\r\n        // when a given node is instantiated.\r\n        const sortedNodes = this._topologicalSort(nodesToSort);\r\n\r\n        const onNewCreated = (source: Node, clone: Node) => {\r\n            onClone(source, clone);\r\n\r\n            if (source.parent) {\r\n                const replicatedParentId = conversionMap[source.parent.uniqueId];\r\n                const replicatedParent = storeMap[replicatedParentId];\r\n\r\n                if (replicatedParent) {\r\n                    clone.parent = replicatedParent;\r\n                } else {\r\n                    clone.parent = source.parent;\r\n                }\r\n            }\r\n\r\n            if ((clone as any).position && (source as any).position) {\r\n                (clone as any).position.copyFrom((source as any).position);\r\n            }\r\n            if ((clone as any).rotationQuaternion && (source as any).rotationQuaternion) {\r\n                (clone as any).rotationQuaternion.copyFrom((source as any).rotationQuaternion);\r\n            }\r\n            if ((clone as any).rotation && (source as any).rotation) {\r\n                (clone as any).rotation.copyFrom((source as any).rotation);\r\n            }\r\n            if ((clone as any).scaling && (source as any).scaling) {\r\n                (clone as any).scaling.copyFrom((source as any).scaling);\r\n            }\r\n\r\n            if ((clone as any).material) {\r\n                const mesh = clone as AbstractMesh;\r\n\r\n                if (mesh.material) {\r\n                    if (cloneMaterials) {\r\n                        const sourceMaterial = (source as AbstractMesh).material!;\r\n\r\n                        if (alreadySwappedMaterials.indexOf(sourceMaterial) === -1) {\r\n                            let swap = sourceMaterial.clone(nameFunction ? nameFunction(sourceMaterial.name) : \"Clone of \" + sourceMaterial.name)!;\r\n                            alreadySwappedMaterials.push(sourceMaterial);\r\n                            conversionMap[sourceMaterial.uniqueId] = swap.uniqueId;\r\n                            storeMap[swap.uniqueId] = swap;\r\n\r\n                            if (sourceMaterial.getClassName() === \"MultiMaterial\") {\r\n                                const multi = sourceMaterial as MultiMaterial;\r\n\r\n                                for (const material of multi.subMaterials) {\r\n                                    if (!material) {\r\n                                        continue;\r\n                                    }\r\n                                    swap = material.clone(nameFunction ? nameFunction(material.name) : \"Clone of \" + material.name)!;\r\n                                    alreadySwappedMaterials.push(material);\r\n                                    conversionMap[material.uniqueId] = swap.uniqueId;\r\n                                    storeMap[swap.uniqueId] = swap;\r\n                                }\r\n\r\n                                multi.subMaterials = multi.subMaterials.map((m) => m && storeMap[conversionMap[m.uniqueId]]);\r\n                            }\r\n                        }\r\n\r\n                        if (mesh.getClassName() !== \"InstancedMesh\") {\r\n                            mesh.material = storeMap[conversionMap[sourceMaterial.uniqueId]];\r\n                        }\r\n                    } else {\r\n                        if (mesh.material.getClassName() === \"MultiMaterial\") {\r\n                            if (this.scene.multiMaterials.indexOf(mesh.material as MultiMaterial) === -1) {\r\n                                this.scene.addMultiMaterial(mesh.material as MultiMaterial);\r\n                            }\r\n                        } else {\r\n                            if (this.scene.materials.indexOf(mesh.material) === -1) {\r\n                                this.scene.addMaterial(mesh.material);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (clone.parent === null) {\r\n                result.rootNodes.push(clone);\r\n            }\r\n        };\r\n\r\n        for (const node of sortedNodes) {\r\n            if (node.getClassName() === \"InstancedMesh\") {\r\n                const instancedNode = node as InstancedMesh;\r\n                const sourceMesh = instancedNode.sourceMesh;\r\n                const replicatedSourceId = conversionMap[sourceMesh.uniqueId];\r\n                const replicatedSource = typeof replicatedSourceId === \"number\" ? storeMap[replicatedSourceId] : sourceMesh;\r\n                const replicatedInstancedNode = replicatedSource.createInstance(instancedNode.name);\r\n                onNewCreated(instancedNode, replicatedInstancedNode);\r\n            } else {\r\n                // Mesh or TransformNode\r\n                let canInstance = true;\r\n                if (\r\n                    node.getClassName() === \"TransformNode\" ||\r\n                    node.getClassName() === \"Node\" ||\r\n                    (node as Mesh).skeleton ||\r\n                    !(node as any).getTotalVertices ||\r\n                    (node as Mesh).getTotalVertices() === 0\r\n                ) {\r\n                    // Transform nodes, skinned meshes, and meshes with no vertices can never be instanced!\r\n                    canInstance = false;\r\n                } else if (localOptions.doNotInstantiate) {\r\n                    if (typeof localOptions.doNotInstantiate === \"function\") {\r\n                        canInstance = !localOptions.doNotInstantiate(node);\r\n                    } else {\r\n                        canInstance = !localOptions.doNotInstantiate;\r\n                    }\r\n                }\r\n                const replicatedNode = canInstance ? (node as Mesh).createInstance(`instance of ${node.name}`) : node.clone(`Clone of ${node.name}`, null, true);\r\n                if (!replicatedNode) {\r\n                    throw new Error(`Could not clone or instantiate node on Asset Container ${node.name}`);\r\n                }\r\n                onNewCreated(node, replicatedNode);\r\n            }\r\n        }\r\n\r\n        for (const s of this.skeletons) {\r\n            if (localOptions.predicate && !localOptions.predicate(s)) {\r\n                continue;\r\n            }\r\n\r\n            const clone = s.clone(nameFunction ? nameFunction(s.name) : \"Clone of \" + s.name);\r\n\r\n            for (const m of this.meshes) {\r\n                if (m.skeleton === s && !m.isAnInstance) {\r\n                    const copy = storeMap[conversionMap[m.uniqueId]] as Mesh;\r\n                    if (!copy || copy.isAnInstance) {\r\n                        continue;\r\n                    }\r\n                    copy.skeleton = clone;\r\n\r\n                    if (alreadySwappedSkeletons.indexOf(clone) !== -1) {\r\n                        continue;\r\n                    }\r\n\r\n                    alreadySwappedSkeletons.push(clone);\r\n\r\n                    // Check if bones are mesh linked\r\n                    for (const bone of clone.bones) {\r\n                        if (bone._linkedTransformNode) {\r\n                            bone._linkedTransformNode = storeMap[conversionMap[bone._linkedTransformNode.uniqueId]];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            result.skeletons.push(clone);\r\n        }\r\n\r\n        for (const o of this.animationGroups) {\r\n            if (localOptions.predicate && !localOptions.predicate(o)) {\r\n                continue;\r\n            }\r\n\r\n            const clone = o.clone(nameFunction ? nameFunction(o.name) : \"Clone of \" + o.name, (oldTarget) => {\r\n                const newTarget = storeMap[conversionMap[oldTarget.uniqueId]];\r\n\r\n                return newTarget || oldTarget;\r\n            });\r\n\r\n            result.animationGroups.push(clone);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Adds all the assets from the container to the scene.\r\n     */\r\n    public addAllToScene() {\r\n        if (this._wasAddedToScene) {\r\n            return;\r\n        }\r\n        if (!this._isValidHierarchy()) {\r\n            Tools.Warn(\"SceneSerializer.addAllToScene: The Asset Container hierarchy is not valid.\");\r\n        }\r\n\r\n        this._wasAddedToScene = true;\r\n\r\n        this.addToScene(null);\r\n\r\n        if (this.environmentTexture) {\r\n            this.scene.environmentTexture = this.environmentTexture;\r\n        }\r\n\r\n        for (const component of this.scene._serializableComponents) {\r\n            component.addFromContainer(this);\r\n        }\r\n\r\n        this.scene.getEngine().onContextRestoredObservable.remove(this._onContextRestoredObserver);\r\n        this._onContextRestoredObserver = null;\r\n    }\r\n\r\n    /**\r\n     * Adds assets from the container to the scene.\r\n     * @param predicate defines a predicate used to select which entity will be added (can be null)\r\n     */\r\n    public addToScene(predicate: Nullable<(entity: any) => boolean> = null) {\r\n        const addedNodes: Node[] = [];\r\n        for (const o of this.cameras) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addCamera(o);\r\n            addedNodes.push(o);\r\n        }\r\n        for (const o of this.lights) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addLight(o);\r\n            addedNodes.push(o);\r\n        }\r\n        for (const o of this.meshes) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addMesh(o);\r\n            addedNodes.push(o);\r\n        }\r\n        for (const o of this.skeletons) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addSkeleton(o);\r\n        }\r\n        for (const o of this.animations) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addAnimation(o);\r\n        }\r\n        for (const o of this.animationGroups) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addAnimationGroup(o);\r\n        }\r\n        for (const o of this.multiMaterials) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addMultiMaterial(o);\r\n        }\r\n        for (const o of this.materials) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addMaterial(o);\r\n        }\r\n        for (const o of this.morphTargetManagers) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addMorphTargetManager(o);\r\n        }\r\n        for (const o of this.geometries) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addGeometry(o);\r\n        }\r\n        for (const o of this.transformNodes) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addTransformNode(o);\r\n            addedNodes.push(o);\r\n        }\r\n        for (const o of this.actionManagers) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addActionManager(o);\r\n        }\r\n        for (const o of this.textures) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addTexture(o);\r\n        }\r\n        for (const o of this.reflectionProbes) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.addReflectionProbe(o);\r\n        }\r\n\r\n        for (const o of this.spriteManagers) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            if (!this.scene.spriteManagers) {\r\n                this.scene.spriteManagers = [];\r\n            }\r\n            this.scene.spriteManagers.push(o);\r\n        }\r\n\r\n        // No more nodes added to scene after this line, so it's safe to make a \"snapshot\" of nodes\r\n        if (addedNodes.length) {\r\n            // build the nodeSet only if needed\r\n            const nodeSet = new Set<Node>(this.scene.meshes);\r\n            // benchmark shows Set constructor and Set.add have similar performance,\r\n            // but using Set.add here avoids another allocate in scene.getNodes().\r\n            for (const light of this.scene.lights) {\r\n                nodeSet.add(light);\r\n            }\r\n            for (const camera of this.scene.cameras) {\r\n                nodeSet.add(camera);\r\n            }\r\n            for (const transformNode of this.scene.transformNodes) {\r\n                nodeSet.add(transformNode);\r\n            }\r\n            for (const skeleton of this.skeletons) {\r\n                for (const bone of skeleton.bones) {\r\n                    nodeSet.add(bone);\r\n                }\r\n            }\r\n            for (const addedNode of addedNodes) {\r\n                // If node was added to the scene, but parent is not in the scene, break the relationship\r\n                if (addedNode.parent && !nodeSet.has(addedNode.parent)) {\r\n                    // Use setParent to keep transform if possible\r\n                    if ((addedNode as TransformNode).setParent) {\r\n                        (addedNode as TransformNode).setParent(null);\r\n                    } else {\r\n                        addedNode.parent = null;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all the assets in the container from the scene\r\n     */\r\n    public removeAllFromScene() {\r\n        if (!this._isValidHierarchy()) {\r\n            Tools.Warn(\"SceneSerializer.removeAllFromScene: The Asset Container hierarchy is not valid.\");\r\n        }\r\n\r\n        this._wasAddedToScene = false;\r\n\r\n        this.removeFromScene(null);\r\n\r\n        if (this.environmentTexture === this.scene.environmentTexture) {\r\n            this.scene.environmentTexture = null;\r\n        }\r\n\r\n        for (const component of this.scene._serializableComponents) {\r\n            component.removeFromContainer(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes assets in the container from the scene\r\n     * @param predicate defines a predicate used to select which entity will be added (can be null)\r\n     */\r\n    public removeFromScene(predicate: Nullable<(entity: any) => boolean> = null) {\r\n        for (const o of this.cameras) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeCamera(o);\r\n        }\r\n        for (const o of this.lights) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeLight(o);\r\n        }\r\n        for (const o of this.meshes) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeMesh(o, true);\r\n        }\r\n        for (const o of this.skeletons) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeSkeleton(o);\r\n        }\r\n        for (const o of this.animations) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeAnimation(o);\r\n        }\r\n        for (const o of this.animationGroups) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeAnimationGroup(o);\r\n        }\r\n        for (const o of this.multiMaterials) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeMultiMaterial(o);\r\n        }\r\n        for (const o of this.materials) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeMaterial(o);\r\n        }\r\n        for (const o of this.morphTargetManagers) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeMorphTargetManager(o);\r\n        }\r\n        for (const o of this.geometries) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeGeometry(o);\r\n        }\r\n        for (const o of this.transformNodes) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeTransformNode(o);\r\n        }\r\n        for (const o of this.actionManagers) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeActionManager(o);\r\n        }\r\n        for (const o of this.textures) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeTexture(o);\r\n        }\r\n        for (const o of this.reflectionProbes) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            this.scene.removeReflectionProbe(o);\r\n        }\r\n        for (const o of this.spriteManagers) {\r\n            if (predicate && !predicate(o)) {\r\n                continue;\r\n            }\r\n            if (this.scene.spriteManagers) {\r\n                const index = this.scene.spriteManagers.indexOf(o);\r\n                if (index !== -1) {\r\n                    this.scene.spriteManagers.splice(index, 1);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes all the assets in the container\r\n     */\r\n    public dispose() {\r\n        const cameras = this.cameras.slice(0);\r\n        for (const camera of cameras) {\r\n            camera.dispose();\r\n        }\r\n        this.cameras.length = 0;\r\n\r\n        const lights = this.lights.slice(0);\r\n        for (const light of lights) {\r\n            light.dispose();\r\n        }\r\n        this.lights.length = 0;\r\n\r\n        const meshes = this.meshes.slice(0);\r\n        for (const mesh of meshes) {\r\n            mesh.dispose();\r\n        }\r\n        this.meshes.length = 0;\r\n\r\n        const skeletons = this.skeletons.slice(0);\r\n        for (const skeleton of skeletons) {\r\n            skeleton.dispose();\r\n        }\r\n        this.skeletons.length = 0;\r\n\r\n        const animationGroups = this.animationGroups.slice(0);\r\n        for (const animationGroup of animationGroups) {\r\n            animationGroup.dispose();\r\n        }\r\n        this.animationGroups.length = 0;\r\n\r\n        const multiMaterials = this.multiMaterials.slice(0);\r\n        for (const multiMaterial of multiMaterials) {\r\n            multiMaterial.dispose();\r\n        }\r\n        this.multiMaterials.length = 0;\r\n\r\n        const materials = this.materials.slice(0);\r\n        for (const material of materials) {\r\n            material.dispose();\r\n        }\r\n        this.materials.length = 0;\r\n\r\n        const geometries = this.geometries.slice(0);\r\n        for (const geometry of geometries) {\r\n            geometry.dispose();\r\n        }\r\n        this.geometries.length = 0;\r\n\r\n        const transformNodes = this.transformNodes.slice(0);\r\n        for (const transformNode of transformNodes) {\r\n            transformNode.dispose();\r\n        }\r\n        this.transformNodes.length = 0;\r\n\r\n        const actionManagers = this.actionManagers.slice(0);\r\n        for (const actionManager of actionManagers) {\r\n            actionManager.dispose();\r\n        }\r\n        this.actionManagers.length = 0;\r\n\r\n        const textures = this.textures.slice(0);\r\n        for (const texture of textures) {\r\n            texture.dispose();\r\n        }\r\n        this.textures.length = 0;\r\n\r\n        const reflectionProbes = this.reflectionProbes.slice(0);\r\n        for (const reflectionProbe of reflectionProbes) {\r\n            reflectionProbe.dispose();\r\n        }\r\n        this.reflectionProbes.length = 0;\r\n\r\n        const morphTargetManagers = this.morphTargetManagers.slice(0);\r\n        for (const morphTargetManager of morphTargetManagers) {\r\n            morphTargetManager.dispose();\r\n        }\r\n        this.morphTargetManagers.length = 0;\r\n\r\n        const spriteManagers = this.spriteManagers.slice(0);\r\n        for (const spriteManager of spriteManagers) {\r\n            spriteManager.dispose();\r\n        }\r\n        this.spriteManagers.length = 0;\r\n\r\n        if (this.environmentTexture) {\r\n            this.environmentTexture.dispose();\r\n            this.environmentTexture = null;\r\n        }\r\n\r\n        for (const component of this.scene._serializableComponents) {\r\n            component.removeFromContainer(this, true);\r\n        }\r\n\r\n        if (this._onContextRestoredObserver) {\r\n            this.scene.getEngine().onContextRestoredObservable.remove(this._onContextRestoredObserver);\r\n            this._onContextRestoredObserver = null;\r\n        }\r\n    }\r\n\r\n    private _moveAssets<T>(sourceAssets: T[], targetAssets: T[], keepAssets: T[]): void {\r\n        if (!sourceAssets || !targetAssets) {\r\n            return;\r\n        }\r\n\r\n        for (const asset of sourceAssets) {\r\n            let move = true;\r\n            if (keepAssets) {\r\n                for (const keepAsset of keepAssets) {\r\n                    if (asset === keepAsset) {\r\n                        move = false;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (move) {\r\n                targetAssets.push(asset);\r\n                (asset as any)._parentContainer = this;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all the assets contained in the scene and adds them to the container.\r\n     * @param keepAssets Set of assets to keep in the scene. (default: empty)\r\n     */\r\n    public moveAllFromScene(keepAssets?: KeepAssets): void {\r\n        this._wasAddedToScene = false;\r\n\r\n        if (keepAssets === undefined) {\r\n            keepAssets = new KeepAssets();\r\n        }\r\n\r\n        for (const key in this) {\r\n            if (Object.prototype.hasOwnProperty.call(this, key)) {\r\n                (<any>this)[key] = (<any>this)[key] || (key === \"_environmentTexture\" ? null : []);\r\n                this._moveAssets((<any>this.scene)[key], (<any>this)[key], (<any>keepAssets)[key]);\r\n            }\r\n        }\r\n\r\n        this.environmentTexture = this.scene.environmentTexture;\r\n\r\n        this.removeAllFromScene();\r\n    }\r\n\r\n    /**\r\n     * Adds all meshes in the asset container to a root mesh that can be used to position all the contained meshes. The root mesh is then added to the front of the meshes in the assetContainer.\r\n     * @returns the root mesh\r\n     */\r\n    public createRootMesh() {\r\n        const rootMesh = new Mesh(\"assetContainerRootMesh\", this.scene);\r\n        for (const m of this.meshes) {\r\n            if (!m.parent) {\r\n                rootMesh.addChild(m);\r\n            }\r\n        }\r\n        this.meshes.unshift(rootMesh);\r\n        return rootMesh;\r\n    }\r\n\r\n    /**\r\n     * Merge animations (direct and animation groups) from this asset container into a scene\r\n     * @param scene is the instance of BABYLON.Scene to append to (default: last created scene)\r\n     * @param animatables set of animatables to retarget to a node from the scene\r\n     * @param targetConverter defines a function used to convert animation targets from the asset container to the scene (default: search node by name)\r\n     * @returns an array of the new AnimationGroup added to the scene (empty array if none)\r\n     */\r\n    public mergeAnimationsTo(\r\n        scene: Nullable<Scene> = EngineStore.LastCreatedScene,\r\n        animatables: Animatable[],\r\n        targetConverter: Nullable<(target: any) => Nullable<Node>> = null\r\n    ): AnimationGroup[] {\r\n        if (!scene) {\r\n            Logger.Error(\"No scene available to merge animations to\");\r\n            return [];\r\n        }\r\n\r\n        const _targetConverter = targetConverter\r\n            ? targetConverter\r\n            : (target: any) => {\r\n                  let node: any;\r\n\r\n                  const targetProperty = target.animations.length ? target.animations[0].targetProperty : \"\";\r\n                  /*\r\n              BabylonJS adds special naming to targets that are children of nodes.\r\n              This name attempts to remove that special naming to get the parent nodes name in case the target\r\n              can't be found in the node tree\r\n\r\n              Ex: Torso_primitive0 likely points to a Mesh primitive. We take away primitive0 and are left with \"Torso\" which is the name\r\n              of the primitive's parent.\r\n          */\r\n                  const name = target.name.split(\".\").join(\"\").split(\"_primitive\")[0];\r\n\r\n                  switch (targetProperty) {\r\n                      case \"position\":\r\n                      case \"rotationQuaternion\":\r\n                          node = scene.getTransformNodeByName(target.name) || scene.getTransformNodeByName(name);\r\n                          break;\r\n                      case \"influence\":\r\n                          node = scene.getMorphTargetByName(target.name) || scene.getMorphTargetByName(name);\r\n                          break;\r\n                      default:\r\n                          node = scene.getNodeByName(target.name) || scene.getNodeByName(name);\r\n                  }\r\n\r\n                  return node;\r\n              };\r\n\r\n        // Copy new node animations\r\n        const nodesInAC = this.getNodes();\r\n        for (const nodeInAC of nodesInAC) {\r\n            const nodeInScene = _targetConverter(nodeInAC);\r\n            if (nodeInScene !== null) {\r\n                // Remove old animations with same target property as a new one\r\n                for (const animationInAC of nodeInAC.animations) {\r\n                    // Doing treatment on an array for safety measure\r\n                    const animationsWithSameProperty = nodeInScene.animations.filter((animationInScene: Animation) => {\r\n                        return animationInScene.targetProperty === animationInAC.targetProperty;\r\n                    });\r\n                    for (const animationWithSameProperty of animationsWithSameProperty) {\r\n                        const index = nodeInScene.animations.indexOf(animationWithSameProperty, 0);\r\n                        if (index > -1) {\r\n                            nodeInScene.animations.splice(index, 1);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Append new animations\r\n                nodeInScene.animations = nodeInScene.animations.concat(nodeInAC.animations);\r\n            }\r\n        }\r\n\r\n        const newAnimationGroups: AnimationGroup[] = [];\r\n\r\n        // Copy new animation groups\r\n        const animationGroups = this.animationGroups.slice();\r\n        for (const animationGroupInAC of animationGroups) {\r\n            // Clone the animation group and all its animatables\r\n            newAnimationGroups.push(animationGroupInAC.clone(animationGroupInAC.name, _targetConverter));\r\n\r\n            // Remove animatables related to the asset container\r\n            for (const animatable of animationGroupInAC.animatables) {\r\n                animatable.stop();\r\n            }\r\n        }\r\n\r\n        // Retarget animatables\r\n        for (const animatable of animatables) {\r\n            const target = _targetConverter(animatable.target);\r\n\r\n            if (target) {\r\n                // Clone the animatable and retarget it\r\n                scene.beginAnimation(\r\n                    target,\r\n                    animatable.fromFrame,\r\n                    animatable.toFrame,\r\n                    animatable.loopAnimation,\r\n                    animatable.speedRatio,\r\n                    animatable.onAnimationEnd ? animatable.onAnimationEnd : undefined,\r\n                    undefined,\r\n                    true,\r\n                    undefined,\r\n                    animatable.onAnimationLoop ? animatable.onAnimationLoop : undefined\r\n                );\r\n\r\n                // Stop animation for the target in the asset container\r\n                scene.stopAnimation(animatable.target);\r\n            }\r\n        }\r\n\r\n        return newAnimationGroups;\r\n    }\r\n\r\n    /**\r\n     * @since 6.15.0\r\n     * This method checks for any node that has no parent\r\n     * and is not in the rootNodes array, and adds the node\r\n     * there, if so.\r\n     */\r\n    public populateRootNodes() {\r\n        this.rootNodes.length = 0;\r\n        for (const m of this.meshes) {\r\n            if (!m.parent && this.rootNodes.indexOf(m) === -1) {\r\n                this.rootNodes.push(m);\r\n            }\r\n        }\r\n        for (const t of this.transformNodes) {\r\n            if (!t.parent && this.rootNodes.indexOf(t) === -1) {\r\n                this.rootNodes.push(t);\r\n            }\r\n        }\r\n        for (const l of this.lights) {\r\n            if (!l.parent && this.rootNodes.indexOf(l) === -1) {\r\n                this.rootNodes.push(l);\r\n            }\r\n        }\r\n        for (const c of this.cameras) {\r\n            if (!c.parent && this.rootNodes.indexOf(c) === -1) {\r\n                this.rootNodes.push(c);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @since 6.26.0\r\n     * Given a root asset, this method will traverse its hierarchy and add it, its children and any materials/skeletons to the container.\r\n     * @param root root node\r\n     */\r\n    public addAllAssetsToContainer(root: Node) {\r\n        if (!root) {\r\n            return;\r\n        }\r\n\r\n        const nodesToVisit: Node[] = [];\r\n        const visitedNodes = new Set<Node>();\r\n\r\n        nodesToVisit.push(root);\r\n\r\n        while (nodesToVisit.length > 0) {\r\n            const nodeToVisit = nodesToVisit.pop()!;\r\n\r\n            if (nodeToVisit instanceof Mesh) {\r\n                if (nodeToVisit.geometry && this.geometries.indexOf(nodeToVisit.geometry) === -1) {\r\n                    this.geometries.push(nodeToVisit.geometry);\r\n                }\r\n                this.meshes.push(nodeToVisit);\r\n            } else if (nodeToVisit instanceof InstancedMesh) {\r\n                this.meshes.push(nodeToVisit);\r\n            } else if (nodeToVisit instanceof TransformNode) {\r\n                this.transformNodes.push(nodeToVisit);\r\n            } else if (nodeToVisit instanceof Light) {\r\n                this.lights.push(nodeToVisit);\r\n            } else if (nodeToVisit instanceof Camera) {\r\n                this.cameras.push(nodeToVisit);\r\n            }\r\n\r\n            if (nodeToVisit instanceof AbstractMesh) {\r\n                if (nodeToVisit.material && this.materials.indexOf(nodeToVisit.material) === -1) {\r\n                    this.materials.push(nodeToVisit.material);\r\n                    for (const texture of nodeToVisit.material.getActiveTextures()) {\r\n                        if (this.textures.indexOf(texture) === -1) {\r\n                            this.textures.push(texture);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (nodeToVisit.skeleton && this.skeletons.indexOf(nodeToVisit.skeleton) === -1) {\r\n                    this.skeletons.push(nodeToVisit.skeleton);\r\n                }\r\n\r\n                if (nodeToVisit.morphTargetManager && this.morphTargetManagers.indexOf(nodeToVisit.morphTargetManager) === -1) {\r\n                    this.morphTargetManagers.push(nodeToVisit.morphTargetManager);\r\n                }\r\n            }\r\n\r\n            for (const child of nodeToVisit.getChildren()) {\r\n                if (!visitedNodes.has(child)) {\r\n                    nodesToVisit.push(child);\r\n                }\r\n            }\r\n\r\n            visitedNodes.add(nodeToVisit);\r\n        }\r\n\r\n        this.populateRootNodes();\r\n    }\r\n\r\n    /**\r\n     * Get from a list of objects by tags\r\n     * @param list the list of objects to use\r\n     * @param tagsQuery the query to use\r\n     * @param filter a predicate to filter for tags\r\n     * @returns\r\n     */\r\n    private _getByTags<T>(list: T[], tagsQuery: string, filter?: (item: T) => boolean): T[] {\r\n        if (tagsQuery === undefined) {\r\n            // returns the complete list (could be done with Tags.MatchesQuery but no need to have a for-loop here)\r\n            return list;\r\n        }\r\n\r\n        const listByTags = [];\r\n\r\n        for (const i in list) {\r\n            const item = list[i];\r\n            if (Tags && Tags.MatchesQuery(item, tagsQuery) && (!filter || filter(item))) {\r\n                listByTags.push(item);\r\n            }\r\n        }\r\n\r\n        return listByTags;\r\n    }\r\n\r\n    /**\r\n     * Get a list of meshes by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Mesh\r\n     */\r\n    public getMeshesByTags(tagsQuery: string, filter?: (mesh: AbstractMesh) => boolean): AbstractMesh[] {\r\n        return this._getByTags(this.meshes, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Get a list of cameras by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Camera\r\n     */\r\n    public getCamerasByTags(tagsQuery: string, filter?: (camera: Camera) => boolean): Camera[] {\r\n        return this._getByTags(this.cameras, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Get a list of lights by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Light\r\n     */\r\n    public getLightsByTags(tagsQuery: string, filter?: (light: Light) => boolean): Light[] {\r\n        return this._getByTags(this.lights, tagsQuery, filter);\r\n    }\r\n\r\n    /**\r\n     * Get a list of materials by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of Material\r\n     */\r\n    public getMaterialsByTags(tagsQuery: string, filter?: (material: Material) => boolean): Material[] {\r\n        return this._getByTags(this.materials, tagsQuery, filter).concat(this._getByTags(this.multiMaterials, tagsQuery, filter));\r\n    }\r\n\r\n    /**\r\n     * Get a list of transform nodes by tags\r\n     * @param tagsQuery defines the tags query to use\r\n     * @param filter defines a predicate used to filter results\r\n     * @returns an array of TransformNode\r\n     */\r\n    public getTransformNodesByTags(tagsQuery: string, filter?: (transform: TransformNode) => boolean): TransformNode[] {\r\n        return this._getByTags(this.transformNodes, tagsQuery, filter);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type IAudioEngine } from \"./Interfaces/IAudioEngine\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * Class used to work with sound analyzer using fast fourier transform (FFT)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n */\r\nexport class Analyser {\r\n    /**\r\n     * Gets or sets the smoothing\r\n     */\r\n    public SMOOTHING = 0.75;\r\n    /**\r\n     * Gets or sets the FFT table size\r\n     */\r\n    public FFT_SIZE = 512;\r\n    /**\r\n     * Gets or sets the bar graph amplitude\r\n     */\r\n    public BARGRAPHAMPLITUDE = 256;\r\n    /**\r\n     * Gets or sets the position of the debug canvas\r\n     */\r\n    public DEBUGCANVASPOS = { x: 20, y: 20 };\r\n    /**\r\n     * Gets or sets the debug canvas size\r\n     */\r\n    public DEBUGCANVASSIZE = { width: 320, height: 200 };\r\n\r\n    private _byteFreqs: Uint8Array<ArrayBuffer>;\r\n    private _byteTime: Uint8Array<ArrayBuffer>;\r\n    private _floatFreqs: Float32Array<ArrayBuffer>;\r\n    private _webAudioAnalyser: AnalyserNode;\r\n    private _debugCanvas: Nullable<HTMLCanvasElement>;\r\n    private _debugCanvasContext: Nullable<CanvasRenderingContext2D>;\r\n    private _scene: Scene;\r\n    private _registerFunc: Nullable<() => void>;\r\n    private _audioEngine: IAudioEngine;\r\n\r\n    /**\r\n     * Creates a new analyser\r\n     * @param scene defines hosting scene\r\n     */\r\n    constructor(scene?: Nullable<Scene>) {\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this._scene = scene;\r\n        if (!AbstractEngine.audioEngine) {\r\n            Tools.Warn(\"No audio engine initialized, failed to create an audio analyser\");\r\n            return;\r\n        }\r\n        this._audioEngine = AbstractEngine.audioEngine;\r\n        if (this._audioEngine.canUseWebAudio && this._audioEngine.audioContext) {\r\n            this._webAudioAnalyser = this._audioEngine.audioContext.createAnalyser();\r\n            this._webAudioAnalyser.minDecibels = -140;\r\n            this._webAudioAnalyser.maxDecibels = 0;\r\n            this._byteFreqs = new Uint8Array(this._webAudioAnalyser.frequencyBinCount);\r\n            this._byteTime = new Uint8Array(this._webAudioAnalyser.frequencyBinCount);\r\n            this._floatFreqs = new Float32Array(this._webAudioAnalyser.frequencyBinCount);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the number of data values you will have to play with for the visualization\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount\r\n     * @returns a number\r\n     */\r\n    public getFrequencyBinCount(): number {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            return this._webAudioAnalyser.frequencyBinCount;\r\n        } else {\r\n            return 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the current frequency data as a byte array\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData\r\n     * @returns a Uint8Array\r\n     */\r\n    public getByteFrequencyData(): Uint8Array {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            this._webAudioAnalyser.smoothingTimeConstant = this.SMOOTHING;\r\n            this._webAudioAnalyser.fftSize = this.FFT_SIZE;\r\n            this._webAudioAnalyser.getByteFrequencyData(this._byteFreqs);\r\n        }\r\n        return this._byteFreqs;\r\n    }\r\n\r\n    /**\r\n     * Gets the current waveform as a byte array\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteTimeDomainData\r\n     * @returns a Uint8Array\r\n     */\r\n    public getByteTimeDomainData(): Uint8Array {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            this._webAudioAnalyser.smoothingTimeConstant = this.SMOOTHING;\r\n            this._webAudioAnalyser.fftSize = this.FFT_SIZE;\r\n            this._webAudioAnalyser.getByteTimeDomainData(this._byteTime);\r\n        }\r\n        return this._byteTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the current frequency data as a float array\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData\r\n     * @returns a Float32Array\r\n     */\r\n    public getFloatFrequencyData(): Float32Array {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            this._webAudioAnalyser.smoothingTimeConstant = this.SMOOTHING;\r\n            this._webAudioAnalyser.fftSize = this.FFT_SIZE;\r\n            this._webAudioAnalyser.getFloatFrequencyData(this._floatFreqs);\r\n        }\r\n        return this._floatFreqs;\r\n    }\r\n\r\n    /**\r\n     * Renders the debug canvas\r\n     */\r\n    public drawDebugCanvas() {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            if (!this._debugCanvas) {\r\n                this._debugCanvas = document.createElement(\"canvas\");\r\n                this._debugCanvas.width = this.DEBUGCANVASSIZE.width;\r\n                this._debugCanvas.height = this.DEBUGCANVASSIZE.height;\r\n                this._debugCanvas.style.position = \"absolute\";\r\n                this._debugCanvas.style.top = this.DEBUGCANVASPOS.y + \"px\";\r\n                this._debugCanvas.style.left = this.DEBUGCANVASPOS.x + \"px\";\r\n                this._debugCanvasContext = this._debugCanvas.getContext(\"2d\");\r\n                document.body.appendChild(this._debugCanvas);\r\n                this._registerFunc = () => {\r\n                    this.drawDebugCanvas();\r\n                };\r\n                this._scene.registerBeforeRender(this._registerFunc);\r\n            }\r\n            if (this._registerFunc && this._debugCanvasContext) {\r\n                const workingArray = this.getByteFrequencyData();\r\n\r\n                this._debugCanvasContext.fillStyle = \"rgb(0, 0, 0)\";\r\n                this._debugCanvasContext.fillRect(0, 0, this.DEBUGCANVASSIZE.width, this.DEBUGCANVASSIZE.height);\r\n\r\n                // Draw the frequency domain chart.\r\n                for (let i = 0; i < this.getFrequencyBinCount(); i++) {\r\n                    const value = workingArray[i];\r\n                    const percent = value / this.BARGRAPHAMPLITUDE;\r\n                    const height = this.DEBUGCANVASSIZE.height * percent;\r\n                    const offset = this.DEBUGCANVASSIZE.height - height - 1;\r\n                    const barWidth = this.DEBUGCANVASSIZE.width / this.getFrequencyBinCount();\r\n                    const hue = (i / this.getFrequencyBinCount()) * 360;\r\n                    this._debugCanvasContext.fillStyle = \"hsl(\" + hue + \", 100%, 50%)\";\r\n                    this._debugCanvasContext.fillRect(i * barWidth, offset, barWidth, height);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stops rendering the debug canvas and removes it\r\n     */\r\n    public stopDebugCanvas() {\r\n        if (this._debugCanvas) {\r\n            if (this._registerFunc) {\r\n                this._scene.unregisterBeforeRender(this._registerFunc);\r\n                this._registerFunc = null;\r\n            }\r\n            document.body.removeChild(this._debugCanvas);\r\n            this._debugCanvas = null;\r\n            this._debugCanvasContext = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Connects two audio nodes\r\n     * @param inputAudioNode defines first node to connect\r\n     * @param outputAudioNode defines second node to connect\r\n     */\r\n    public connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode) {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            inputAudioNode.connect(this._webAudioAnalyser);\r\n            this._webAudioAnalyser.connect(outputAudioNode);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases all associated resources\r\n     */\r\n    public dispose() {\r\n        if (this._audioEngine.canUseWebAudio) {\r\n            this._webAudioAnalyser.disconnect();\r\n        }\r\n    }\r\n}\r\n","import { type IDisposable } from \"../../scene\";\nimport { type Nullable } from \"../../types\";\nimport { type IReadonlyObservable, Observable } from \"../../Misc/observable\";\nimport { type IAudioParameterRampOptions } from \"../audioParameter\";\nimport { type AbstractAudioNode, type AbstractNamedAudioNode } from \"./abstractAudioNode\";\nimport { type AbstractSound } from \"./abstractSound\";\nimport { type AbstractSoundSource, type ISoundSourceOptions } from \"./abstractSoundSource\";\nimport { type AudioBus, type IAudioBusOptions } from \"./audioBus\";\nimport { type IMainAudioBusOptions, type MainAudioBus } from \"./mainAudioBus\";\nimport { type IStaticSoundOptions, type StaticSound } from \"./staticSound\";\nimport { type IStaticSoundBufferOptions, type StaticSoundBuffer } from \"./staticSoundBuffer\";\nimport { type IStreamingSoundOptions, type StreamingSound } from \"./streamingSound\";\nimport { type AbstractSpatialAudioListener, type ISpatialAudioListenerOptions } from \"./subProperties/abstractSpatialAudioListener\";\n\nconst Instances: AudioEngineV2[] = [];\n\n/**\n * Observable that notifies when a new v2 audio engine instance has been created.\n * - Fires after the engine has been fully constructed and initialized (e.g. from {@link CreateAudioEngineAsync}),\n *   so subclass state (audio context, listener, etc.) is guaranteed to be available to observers.\n */\nexport const OnAudioEngineV2CreatedObservable = new Observable<AudioEngineV2>();\n\n/**\n * Gets the most recently created v2 audio engine.\n * @returns The most recently created v2 audio engine.\n */\nexport function LastCreatedAudioEngine(): Nullable<AudioEngineV2> {\n    if (Instances.length === 0) {\n        return null;\n    }\n\n    return Instances[Instances.length - 1];\n}\n\n/**\n * Options for creating a v2 audio engine.\n */\nexport interface IAudioEngineV2Options extends ISpatialAudioListenerOptions {\n    /**\n     * The smoothing duration to use when changing audio parameters, in seconds. Defaults to `0.01` (10 milliseconds).\n     */\n    parameterRampDuration: number;\n    /**\n     * The initial output volume of the audio engine. Defaults to `1`.\n     */\n    volume: number;\n}\n\n/**\n * The state of a v2 audio engine.\n * @see {@link AudioEngineV2.state}\n */\nexport type AudioEngineV2State = \"closed\" | \"interrupted\" | \"running\" | \"suspended\";\n\n/**\n * Abstract base class for v2 audio engines.\n *\n * A v2 audio engine based on the WebAudio API can be created with the {@link CreateAudioEngineAsync} function.\n */\nexport abstract class AudioEngineV2 implements IDisposable {\n    /**\n     * The list of v2 audio engines that have been created and not yet disposed.\n     * - Engines are added on construction and removed on {@link AudioEngineV2.dispose}.\n     */\n    public static get Instances(): ReadonlyArray<AudioEngineV2> {\n        return Instances;\n    }\n\n    /** Not owned, but all items should be in `_nodes` container, too, which is owned. */\n    private readonly _mainBuses = new Set<MainAudioBus>();\n    private readonly _sounds = new Set<AbstractSound>();\n    private _soundsArray: Nullable<Array<AbstractSound>> = null;\n\n    /** Owned top-level sound and bus nodes. */\n    private readonly _nodes = new Set<AbstractNamedAudioNode>();\n\n    private _defaultMainBus: Nullable<MainAudioBus> = null;\n\n    private _parameterRampDuration: number = 0.01;\n\n    private readonly _onNodeAddedObservable = new Observable<AbstractNamedAudioNode>();\n    private readonly _onNodeRemovedObservable = new Observable<AbstractNamedAudioNode>();\n    private readonly _onDisposeObservable = new Observable<AudioEngineV2>();\n\n    /**\n     * Observable that notifies when a top-level audio node (sound, sound source, bus, or main bus) is added to this engine.\n     */\n    public get onNodeAddedObservable(): IReadonlyObservable<AbstractNamedAudioNode> {\n        return this._onNodeAddedObservable;\n    }\n\n    /**\n     * Observable that notifies when a top-level audio node (sound, sound source, bus, or main bus) is removed from this engine.\n     */\n    public get onNodeRemovedObservable(): IReadonlyObservable<AbstractNamedAudioNode> {\n        return this._onNodeRemovedObservable;\n    }\n\n    /**\n     * Observable that notifies when this engine is disposed.\n     * - Fires from {@link AudioEngineV2.dispose} after the engine has been removed from {@link AudioEngineV2.Instances}.\n     */\n    public get onDisposeObservable(): IReadonlyObservable<AudioEngineV2> {\n        return this._onDisposeObservable;\n    }\n\n    protected constructor(options: Partial<IAudioEngineV2Options>) {\n        Instances.push(this);\n\n        if (typeof options.parameterRampDuration === \"number\") {\n            this.parameterRampDuration = options.parameterRampDuration;\n        }\n\n        // Intentionally do NOT notify {@link OnAudioEngineV2CreatedObservable} here:\n        // - This base constructor runs before subclass fields (audio context, listener, ...) are initialized\n        //   and before any async {@link CreateAudioEngineAsync}-style setup completes, so observers would\n        //   see a partially constructed engine.\n        // - Engine factory functions (e.g. {@link CreateAudioEngineAsync}) call `notifyObservers` themselves\n        //   once the engine is fully constructed and initialized.\n    }\n\n    /**\n     * The elapsed time since the audio engine was started, in seconds.\n     */\n    public abstract readonly currentTime: number;\n\n    /**\n     * The default main bus that will be used for audio buses and sounds if their `outBus` option is not set.\n     * @see {@link IAudioBusOptions.outBus}\n     * @see {@link IAbstractSoundOptions.outBus}\n     */\n    public get defaultMainBus(): Nullable<MainAudioBus> {\n        if (this._mainBuses.size === 0) {\n            return null;\n        }\n\n        if (!this._defaultMainBus) {\n            this._defaultMainBus = Array.from(this._mainBuses)[0];\n        }\n\n        return this._defaultMainBus;\n    }\n\n    /**\n     * The spatial audio listener properties for the audio engine.\n     * - Each audio engine has exactly one listener.\n     */\n    public abstract readonly listener: AbstractSpatialAudioListener;\n\n    /**\n     * The main output node.\n     * - This is the last node in the audio graph before the audio is sent to the speakers.\n     */\n    public abstract readonly mainOut: AbstractAudioNode;\n\n    /**\n     * The current state of the audio engine.\n     *\n     * Possible values are:\n     * - `\"closed\"`: The audio engine has been closed.\n     * - `\"interrupted\"`: The audio engine has been interrupted and is not running.\n     * - `\"running\"`: The audio engine is running normally.\n     * - `\"suspended\"`: The audio engine is suspended and is not running.\n     */\n    public abstract readonly state: AudioEngineV2State;\n\n    /**\n     * The output volume of the audio engine.\n     */\n    public abstract volume: number;\n\n    /**\n     * The smoothing duration to use when changing audio parameters, in seconds. Defaults to `0.01` (10 milliseconds).\n     */\n    public get parameterRampDuration(): number {\n        return this._parameterRampDuration;\n    }\n\n    public set parameterRampDuration(value: number) {\n        this._parameterRampDuration = Math.max(0, value);\n    }\n\n    /**\n     * The list of static and streaming sounds created by the audio engine.\n     */\n    public get sounds(): ReadonlyArray<AbstractSound> {\n        if (!this._soundsArray) {\n            this._soundsArray = Array.from(this._sounds);\n        }\n        return this._soundsArray;\n    }\n\n    /**\n     * The list of top-level audio nodes (sounds, sound sources, buses, main buses) owned by the audio engine.\n     */\n    public get nodes(): ReadonlySet<AbstractNamedAudioNode> {\n        return this._nodes;\n    }\n\n    /**\n     * Creates a new audio bus.\n     * @param name - The name of the audio bus.\n     * @param options - The options to use when creating the audio bus.\n     * @returns A promise that resolves with the created audio bus.\n     */\n    public abstract createBusAsync(name: string, options?: Partial<IAudioBusOptions>): Promise<AudioBus>;\n\n    /**\n     * Creates a new main audio bus.\n     * @param name - The name of the main audio bus.\n     * @param options - The options to use when creating the main audio bus.\n     * @returns A promise that resolves with the created main audio bus.\n     */\n    public abstract createMainBusAsync(name: string, options?: Partial<IMainAudioBusOptions>): Promise<MainAudioBus>;\n\n    /**\n     * Creates a new microphone sound source.\n     * @param name - The name of the sound.\n     * @param options - The options for the sound source.\n     * @returns A promise that resolves to the created sound source.\n     */\n    public abstract createMicrophoneSoundSourceAsync(name: string, options?: Partial<ISoundSourceOptions>): Promise<AbstractSoundSource>;\n\n    /**\n     * Creates a new static sound.\n     * @param name - The name of the sound.\n     * @param source - The source of the sound.\n     * @param options - The options for the static sound.\n     * @returns A promise that resolves to the created static sound.\n     */\n    public abstract createSoundAsync(\n        name: string,\n        source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n        options?: Partial<IStaticSoundOptions>\n    ): Promise<StaticSound>;\n\n    /**\n     * Creates a new static sound buffer.\n     * @param source - The source of the sound buffer.\n     * @param options - The options for the static sound buffer.\n     * @returns A promise that resolves to the created static sound buffer.\n     */\n    public abstract createSoundBufferAsync(\n        source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n        options?: Partial<IStaticSoundBufferOptions>\n    ): Promise<StaticSoundBuffer>;\n\n    /**\n     * Creates a new sound source.\n     * @param name - The name of the sound.\n     * @param source - The source of the sound.\n     * @param options - The options for the sound source.\n     * @returns A promise that resolves to the created sound source.\n     */\n    public abstract createSoundSourceAsync(name: string, source: AudioNode, options?: Partial<ISoundSourceOptions>): Promise<AbstractSoundSource>;\n\n    /**\n     * Creates a new streaming sound.\n     * @param name - The name of the sound.\n     * @param source - The source of the sound.\n     * @param options - The options for the streaming sound.\n     * @returns A promise that resolves to the created streaming sound.\n     */\n    public abstract createStreamingSoundAsync(name: string, source: HTMLMediaElement | string | string[], options?: Partial<IStreamingSoundOptions>): Promise<StreamingSound>;\n\n    /**\n     * Releases associated resources.\n     */\n    public dispose(): void {\n        if (Instances.includes(this)) {\n            Instances.splice(Instances.indexOf(this), 1);\n        }\n\n        const nodeIt = this._nodes.values();\n        for (let next = nodeIt.next(); !next.done; next = nodeIt.next()) {\n            next.value.dispose();\n        }\n\n        this._mainBuses.clear();\n        this._nodes.clear();\n        this._sounds.clear();\n\n        this._disposeSoundsArray();\n\n        this._defaultMainBus = null;\n\n        this._onDisposeObservable.notifyObservers(this);\n        this._onDisposeObservable.clear();\n        this._onNodeAddedObservable.clear();\n        this._onNodeRemovedObservable.clear();\n    }\n\n    /**\n     * Checks if the specified format is valid.\n     * @param format The format to check as an audio file extension like \"mp3\" or \"wav\".\n     * @returns `true` if the format is valid; otherwise `false`.\n     */\n    public abstract isFormatValid(format: string): boolean;\n\n    /**\n     * Pauses the audio engine if it is running.\n     * @returns A promise that resolves when the audio engine is paused.\n     */\n    public abstract pauseAsync(): Promise<void>;\n\n    /**\n     * Resumes the audio engine if it is not running.\n     * @returns A promise that resolves when the audio engine is running.\n     */\n    public abstract resumeAsync(): Promise<void>;\n\n    /**\n     * Sets the audio output volume with optional ramping.\n     * If the duration is 0 then the volume is set immediately, otherwise it is ramped to the new value over the given duration using the given shape.\n     * If a ramp is already in progress then the volume is not set and an error is thrown.\n     * @param value The value to set the volume to.\n     * @param options The options to use for ramping the volume change.\n     */\n    public abstract setVolume(value: number, options?: Partial<IAudioParameterRampOptions>): void;\n\n    /**\n     * Unlocks the audio engine if it is locked.\n     * - Note that the returned promise may already be resolved if the audio engine is already unlocked.\n     * @returns A promise that is resolved when the audio engine is unlocked.\n     */\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n    public unlockAsync(): Promise<void> {\n        return this.resumeAsync();\n    }\n\n    protected _addMainBus(mainBus: MainAudioBus): void {\n        this._mainBuses.add(mainBus);\n\n        this._addNode(mainBus);\n    }\n\n    protected _removeMainBus(mainBus: MainAudioBus): void {\n        this._mainBuses.delete(mainBus);\n        this._defaultMainBus = null;\n\n        this._removeNode(mainBus);\n    }\n\n    protected _addNode(node: AbstractNamedAudioNode): void {\n        this._nodes.add(node);\n        this._onNodeAddedObservable.notifyObservers(node);\n    }\n\n    protected _removeNode(node: AbstractNamedAudioNode): void {\n        this._nodes.delete(node);\n        this._onNodeRemovedObservable.notifyObservers(node);\n    }\n\n    protected _addSound(sound: AbstractSound): void {\n        this._disposeSoundsArray();\n        this._sounds.add(sound);\n        this._addNode(sound);\n    }\n\n    protected _removeSound(sound: AbstractSound): void {\n        this._disposeSoundsArray();\n        this._sounds.delete(sound);\n        this._removeNode(sound);\n    }\n\n    /**\n     * Called when any sound's playback state changes (started, stopped, paused, resumed).\n     * Override in platform-specific implementations to react to sound playback state changes.\n     * @internal\n     */\n    public _onSoundPlaybackStateChanged(): void {\n        // No-op base implementation.\n    }\n\n    private _disposeSoundsArray(): void {\n        if (this._soundsArray) {\n            this._soundsArray.length = 0;\n            this._soundsArray = null;\n        }\n    }\n}\n\n/**\n * @internal\n * @param engine - The given audio engine. If `null` then the last created audio engine is used.\n * @returns the given audio engine or the last created audio engine.\n * @throws An error if the resulting engine is `null`.\n */\nexport function _GetAudioEngine(engine: Nullable<AudioEngineV2>): AudioEngineV2 {\n    if (!engine) {\n        engine = LastCreatedAudioEngine();\n    }\n\n    if (engine) {\n        return engine;\n    }\n\n    throw new Error(\"No audio engine.\");\n}\n\n/**\n * Creates a new audio bus.\n * @param name - The name of the audio bus.\n * @param options - The options to use when creating the audio bus.\n * @param engine - The audio engine.\n * @returns A promise that resolves with the created audio bus.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function CreateAudioBusAsync(name: string, options: Partial<IAudioBusOptions> = {}, engine: Nullable<AudioEngineV2> = null): Promise<AudioBus> {\n    engine = _GetAudioEngine(engine);\n    return engine.createBusAsync(name, options);\n}\n\n/**\n * Creates a new main audio bus.\n * @param name - The name of the main audio bus.\n * @param options - The options to use when creating the main audio bus.\n * @param engine - The audio engine.\n * @returns A promise that resolves with the created main audio bus.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function CreateMainAudioBusAsync(name: string, options: Partial<IMainAudioBusOptions> = {}, engine: Nullable<AudioEngineV2> = null): Promise<MainAudioBus> {\n    engine = _GetAudioEngine(engine);\n    return engine.createMainBusAsync(name, options);\n}\n\n/**\n * Creates a new microphone sound source.\n * @param name - The name of the sound.\n * @param options - The options for the sound source.\n * @param engine - The audio engine.\n * @returns A promise that resolves to the created sound source.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function CreateMicrophoneSoundSourceAsync(name: string, options: Partial<ISoundSourceOptions> = {}, engine: Nullable<AudioEngineV2> = null): Promise<AbstractSoundSource> {\n    engine = _GetAudioEngine(engine);\n    return engine.createMicrophoneSoundSourceAsync(name, options);\n}\n\n/**\n * Creates a new static sound.\n * @param name - The name of the sound.\n * @param source - The source of the sound.\n * @param options - The options for the static sound.\n * @param engine - The audio engine.\n * @returns A promise that resolves to the created static sound.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function CreateSoundAsync(\n    name: string,\n    source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n    options: Partial<IStaticSoundOptions> = {},\n    engine: Nullable<AudioEngineV2> = null\n): Promise<StaticSound> {\n    engine = _GetAudioEngine(engine);\n    return engine.createSoundAsync(name, source, options);\n}\n\n/**\n * Creates a new static sound buffer.\n * @param source - The source of the sound buffer.\n * @param options - The options for the static sound buffer.\n * @param engine - The audio engine.\n * @returns A promise that resolves to the created static sound buffer.\n */\nexport async function CreateSoundBufferAsync(\n    source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n    options: Partial<IStaticSoundBufferOptions> = {},\n    engine: Nullable<AudioEngineV2> = null\n): Promise<StaticSoundBuffer> {\n    engine = _GetAudioEngine(engine);\n    return await engine.createSoundBufferAsync(source, options);\n}\n\n/**\n * Creates a new sound source.\n * @param name - The name of the sound.\n * @param source - The source of the sound.\n * @param options - The options for the sound source.\n * @param engine - The audio engine.\n * @returns A promise that resolves to the created sound source.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function CreateSoundSourceAsync(\n    name: string,\n    source: AudioNode,\n    options: Partial<ISoundSourceOptions> = {},\n    engine: Nullable<AudioEngineV2> = null\n): Promise<AbstractSoundSource> {\n    engine = _GetAudioEngine(engine);\n    return engine.createSoundSourceAsync(name, source, options);\n}\n\n/**\n * Creates a new streaming sound.\n * @param name - The name of the sound.\n * @param source - The source of the sound.\n * @param options - The options for the streaming sound.\n * @param engine - The audio engine.\n * @returns A promise that resolves to the created streaming sound.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function CreateStreamingSoundAsync(\n    name: string,\n    source: HTMLMediaElement | string | string[],\n    options: Partial<IStreamingSoundOptions> = {},\n    engine: Nullable<AudioEngineV2> = null\n): Promise<StreamingSound> {\n    engine = _GetAudioEngine(engine);\n    return engine.createStreamingSoundAsync(name, source, options);\n}\n","import { Quaternion, Vector3 } from \"../../../Maths/math.vector.pure\";\nimport { type Node } from \"../../../node\";\nimport { type Nullable } from \"../../../types\";\nimport { type SpatialAudioAttachmentType } from \"../../spatialAudioAttachmentType\";\n\nexport const _SpatialAudioListenerDefaults = {\n    position: Vector3.Zero(),\n    rotation: Vector3.Zero(),\n    rotationQuaternion: new Quaternion(),\n} as const;\n\n/**\n * Options for spatial audio.\n */\nexport interface ISpatialAudioListenerOptions {\n    /**\n     * Whether to automatically update the position and rotation of the listener. Defaults to `true`.\n     */\n    listenerAutoUpdate: boolean;\n    /**\n     * Set to `true` to enable the listener. Defaults to `false`.\n     */\n    listenerEnabled: boolean;\n    /**\n     * The minimum update time in seconds of the listener if it is attached to a mesh, scene or transform node. Defaults to `0`.\n     * - The listener's position and rotation will not update faster than this time, but they may update slower depending on the frame rate.\n     */\n    listenerMinUpdateTime: number;\n    /**\n     * The listener position. Defaults to (0, 0, 0).\n     */\n    listenerPosition: Vector3;\n    /**\n     * The listener rotation, as Euler angles. Defaults to (0, 0, 0).\n     */\n    listenerRotation: Vector3;\n    /**\n     * The listener rotation, as a quaternion. Defaults to (0, 0, 0, 1).\n     */\n    listenerRotationQuaternion: Quaternion;\n}\n\n/**\n * @param options The spatial audio listener options to check.\n * @returns `true` if spatial audio listener options are defined, otherwise `false`.\n */\nexport function _HasSpatialAudioListenerOptions(options: Partial<ISpatialAudioListenerOptions>): boolean {\n    return (\n        options.listenerEnabled ||\n        options.listenerMinUpdateTime !== undefined ||\n        options.listenerPosition !== undefined ||\n        options.listenerRotation !== undefined ||\n        options.listenerRotationQuaternion !== undefined\n    );\n}\n\n/**\n * Abstract class representing the spatial audio `listener` property on an audio engine.\n *\n * @see {@link AudioEngineV2.listener}\n */\nexport abstract class AbstractSpatialAudioListener {\n    /**\n     * Whether the listener is attached to a camera, mesh or transform node.\n     */\n    public abstract isAttached: boolean;\n\n    /**\n     * The scene node this listener is currently attached to, or `null` if not attached.\n     */\n    public abstract attachedNode: Nullable<Node>;\n\n    /**\n     * The minimum update time in seconds of the listener if it is attached to a mesh, scene or transform node. Defaults to `0`.\n     * - The listener's position and rotation will not update faster than this time, but they may update slower depending on the frame rate.\n     */\n    public abstract minUpdateTime: number;\n\n    /**\n     * The listener position. Defaults to (0, 0, 0).\n     */\n    public abstract position: Vector3;\n\n    /**\n     * The listener rotation, as Euler angles. Defaults to (0, 0, 0).\n     */\n    public abstract rotation: Vector3;\n\n    /**\n     * The listener rotation, as a quaternion. Defaults to (0, 0, 0, 1).\n     */\n    public abstract rotationQuaternion: Quaternion;\n\n    /**\n     * Attaches to a scene node.\n     *\n     * Detaches automatically before attaching to the given scene node.\n     * If `sceneNode` is `null` it is the same as calling `detach()`.\n     *\n     * @param sceneNode The scene node to attach to, or `null` to detach.\n     * @param useBoundingBox Whether to use the bounding box of the node for positioning. Defaults to `false`.\n     * @param attachmentType Whether to attach to the node's position and/or rotation. Defaults to `PositionAndRotation`.\n     */\n    public abstract attach(sceneNode: Nullable<Node>, useBoundingBox?: boolean, attachmentType?: SpatialAudioAttachmentType): void;\n\n    /**\n     * Detaches from the scene node if attached.\n     */\n    public abstract detach(): void;\n\n    /**\n     * Updates the position and rotation of the associated audio engine object in the audio rendering graph.\n     *\n     * This is called automatically by default and only needs to be called manually if automatic updates are disabled.\n     */\n    public abstract update(): void;\n}\n","import { Quaternion, Vector3 } from \"../../../Maths/math.vector.pure\";\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh\";\nimport { type Node } from \"../../../node\";\nimport { type Nullable } from \"../../../types\";\nimport { SpatialAudioAttachmentType } from \"../../spatialAudioAttachmentType\";\nimport { type _SpatialAudioSubNode } from \"../subNodes/spatialAudioSubNode\";\nimport { type _SpatialAudioListener } from \"../subProperties/spatialAudioListener\";\n\n/**\n * Provides a common interface for attaching an audio listener or source to a specific entity, ensuring only one entity\n * is attached at a time.\n * @internal\n */\nexport class _SpatialAudioAttacherComponent {\n    /** @internal */\n    private _attachmentType: SpatialAudioAttachmentType = SpatialAudioAttachmentType.PositionAndRotation;\n    private readonly _position = new Vector3();\n    private readonly _rotationQuaternion = new Quaternion();\n    private _sceneNode: Nullable<Node> = null;\n    private readonly _spatialAudioNode: _SpatialAudioSubNode | _SpatialAudioListener;\n    private _useBoundingBox: boolean = false;\n\n    /** @internal */\n    public constructor(spatialAudioNode: _SpatialAudioSubNode | _SpatialAudioListener) {\n        this._spatialAudioNode = spatialAudioNode;\n    }\n\n    /**\n     * Returns `true` if attached to a scene node; otherwise returns `false`.\n     */\n    public get isAttached(): boolean {\n        return this._sceneNode !== null;\n    }\n\n    /**\n     * The scene node this attacher is currently attached to, or `null` if not attached.\n     */\n    public get sceneNode(): Nullable<Node> {\n        return this._sceneNode;\n    }\n\n    /**\n     * Whether the attacher is using the scene node's bounding box for positioning.\n     */\n    public get useBoundingBox(): boolean {\n        return this._useBoundingBox;\n    }\n\n    /**\n     * Which components (position, rotation, or both) of the scene node's world transform drive the spatial audio.\n     */\n    public get attachmentType(): SpatialAudioAttachmentType {\n        return this._attachmentType;\n    }\n\n    /**\n     * Attaches to a scene node.\n     *\n     * Detaches automatically before attaching to the given scene node.\n     * If `sceneNode` is `null` it is the same as calling `detach()`.\n     *\n     * @param sceneNode The scene node to attach to, or `null` to detach.\n     * @param useBoundingBox Whether to use the scene node's bounding box for positioning. Defaults to `false`.\n     * @param attachmentType Whether to attach to the scene node's position and/or rotation. Defaults to `PositionAndRotation`.\n     */\n    public attach(sceneNode: Nullable<Node>, useBoundingBox: boolean, attachmentType: SpatialAudioAttachmentType): void {\n        if (this._sceneNode === sceneNode) {\n            return;\n        }\n\n        this.detach();\n\n        if (!sceneNode) {\n            return;\n        }\n\n        this._attachmentType = attachmentType;\n\n        this._sceneNode = sceneNode;\n        this._sceneNode.onDisposeObservable.add(this.dispose);\n\n        this._useBoundingBox = useBoundingBox;\n    }\n\n    /**\n     * Detaches from the scene node if attached.\n     */\n    public detach() {\n        this._sceneNode?.onDisposeObservable.removeCallback(this.dispose);\n        this._sceneNode = null;\n    }\n\n    /**\n     * Releases associated resources.\n     */\n    public dispose = () => {\n        this.detach();\n    };\n\n    /**\n     * Updates the position and rotation of the associated audio engine object in the audio rendering graph.\n     *\n     * This is called automatically by default and only needs to be called manually if automatic updates are disabled.\n     */\n    public update() {\n        const updatesPosition = !!(this._attachmentType & SpatialAudioAttachmentType.Position);\n\n        if (updatesPosition) {\n            if (this._useBoundingBox && (this._sceneNode as AbstractMesh).getBoundingInfo) {\n                this._position.copyFrom((this._sceneNode as AbstractMesh).getBoundingInfo().boundingBox.centerWorld);\n            } else {\n                this._sceneNode?.getWorldMatrix().getTranslationToRef(this._position);\n            }\n\n            this._spatialAudioNode.position.copyFrom(this._position);\n            this._spatialAudioNode._updatePosition();\n        }\n\n        if (this._attachmentType & SpatialAudioAttachmentType.Rotation) {\n            this._sceneNode?.getWorldMatrix().decompose(undefined, this._rotationQuaternion);\n\n            this._spatialAudioNode.rotationQuaternion.copyFrom(this._rotationQuaternion);\n            this._spatialAudioNode._updateRotation();\n        }\n\n        if (!updatesPosition && \"panningEnabled\" in this._spatialAudioNode && !this._spatialAudioNode.panningEnabled) {\n            this._spatialAudioNode._updatePosition();\n        }\n    }\n}\n","import { type Node } from \"../../../node\";\nimport { type Nullable } from \"../../../types\";\nimport { SpatialAudioAttachmentType } from \"../../spatialAudioAttachmentType\";\nimport { _SpatialAudioAttacherComponent } from \"../components/spatialAudioAttacherComponent\";\nimport { type ISpatialAudioListenerOptions, _SpatialAudioListenerDefaults, AbstractSpatialAudioListener } from \"./abstractSpatialAudioListener\";\n\n/** @internal */\nexport abstract class _SpatialAudioListener extends AbstractSpatialAudioListener {\n    protected _attacherComponent: Nullable<_SpatialAudioAttacherComponent> = null;\n\n    protected constructor() {\n        super();\n\n        this._attacherComponent = new _SpatialAudioAttacherComponent(this);\n    }\n\n    /** @internal */\n    public get isAttached(): boolean {\n        return this._attacherComponent !== null && this._attacherComponent.isAttached;\n    }\n\n    /** @internal */\n    public get attachedNode(): Nullable<Node> {\n        return this._attacherComponent?.sceneNode ?? null;\n    }\n\n    /**\n     * Attaches to a scene node.\n     *\n     * Detaches automatically before attaching to the given scene node.\n     * If `sceneNode` is `null` it is the same as calling `detach()`.\n     *\n     * @param sceneNode The scene node to attach to, or `null` to detach.\n     * @param useBoundingBox Whether to use the bounding box of the node for positioning. Defaults to `false`.\n     * @param attachmentType Whether to attach to the node's position and/or rotation. Defaults to `PositionAndRotation`.\n     */\n    public attach(sceneNode: Nullable<Node>, useBoundingBox: boolean = false, attachmentType: SpatialAudioAttachmentType = SpatialAudioAttachmentType.PositionAndRotation): void {\n        if (!this._attacherComponent) {\n            this._attacherComponent = new _SpatialAudioAttacherComponent(this);\n        }\n        this._attacherComponent.attach(sceneNode, useBoundingBox, attachmentType);\n    }\n\n    /**\n     * Detaches from the scene node if attached.\n     */\n    public detach(): void {\n        this._attacherComponent?.detach();\n    }\n\n    /** @internal */\n    public dispose(): void {\n        this._attacherComponent?.dispose();\n        this._attacherComponent = null;\n    }\n\n    /** @internal */\n    public setOptions(options: Partial<ISpatialAudioListenerOptions>): void {\n        if (options.listenerMinUpdateTime !== undefined) {\n            this.minUpdateTime = options.listenerMinUpdateTime;\n        }\n\n        if (options.listenerPosition) {\n            this.position = options.listenerPosition.clone();\n        }\n\n        if (options.listenerRotationQuaternion) {\n            this.rotationQuaternion = options.listenerRotationQuaternion.clone();\n        } else if (options.listenerRotation) {\n            this.rotation = options.listenerRotation.clone();\n        } else {\n            this.rotationQuaternion = _SpatialAudioListenerDefaults.rotationQuaternion.clone();\n        }\n\n        this.update();\n    }\n\n    public abstract _updatePosition(): void;\n    public abstract _updateRotation(): void;\n}\n","import { PrecisionDate } from \"../../../Misc/precisionDate\";\n\n/** @internal */\nexport class _SpatialWebAudioUpdaterComponent {\n    private _autoUpdate = true;\n    private _lastUpdateTime: number = 0;\n\n    /**\n     * The minimum time in seconds between spatial audio updates. Defaults to `0`.\n     * @internal\n     */\n    public minUpdateTime = 0;\n\n    /** @internal */\n    public constructor(parent: { update: () => void }, autoUpdate: boolean, minUpdateTime: number) {\n        if (!autoUpdate) {\n            return;\n        }\n\n        this.minUpdateTime = minUpdateTime;\n\n        const update = () => {\n            if (!this._autoUpdate) {\n                return;\n            }\n\n            let skipUpdate = false;\n\n            if (0 < this.minUpdateTime) {\n                const now = PrecisionDate.Now;\n                if (this._lastUpdateTime && now - this._lastUpdateTime < this.minUpdateTime * 1000) {\n                    skipUpdate = true;\n                }\n                this._lastUpdateTime = now;\n            }\n\n            if (!skipUpdate) {\n                parent.update();\n            }\n\n            requestAnimationFrame(update);\n        };\n        requestAnimationFrame(update);\n    }\n\n    /** @internal */\n    public dispose(): void {\n        this._autoUpdate = false;\n    }\n}\n","import { type Nullable } from \"../types\";\nimport { Logger } from \"../Misc/logger\";\nimport { WebRequest } from \"../Misc/webRequest\";\nimport { AudioParameterRampShape } from \"./audioParameter\";\n\nexport const _FileExtensionRegex = new RegExp(\"\\\\.(\\\\w{3,4})($|\\\\?)\");\n\nconst CurveLength = 100;\n\nconst TmpLineValues = new Float32Array([0, 0]);\nlet TmpCurveValues: Nullable<Float32Array> = null;\n\nlet ExpCurve: Nullable<Float32Array> = null;\nlet LogCurve: Nullable<Float32Array> = null;\n\n/**\n * @returns A Float32Array representing an exponential ramp from (0, 0) to (1, 1).\n */\nfunction GetExpCurve(): Float32Array {\n    if (!ExpCurve) {\n        ExpCurve = new Float32Array(CurveLength);\n\n        const increment = 1 / (CurveLength - 1);\n        let x = increment;\n        for (let i = 1; i < CurveLength; i++) {\n            ExpCurve[i] = Math.exp(-11.512925464970227 * (1 - x));\n            x += increment;\n        }\n    }\n\n    return ExpCurve;\n}\n\n/**\n * @returns A Float32Array representing a logarithmic ramp from (0, 0) to (1, 1).\n */\nfunction GetLogCurve(): Float32Array {\n    if (!LogCurve) {\n        LogCurve = new Float32Array(CurveLength);\n\n        const increment = 1 / CurveLength;\n        let x = increment;\n        for (let i = 0; i < CurveLength; i++) {\n            LogCurve[i] = 1 + Math.log10(x) / Math.log10(CurveLength);\n            x += increment;\n        }\n    }\n\n    return LogCurve;\n}\n\n/** @internal */\nexport function _GetAudioParamCurveValues(shape: AudioParameterRampShape, from: number, to: number): Float32Array {\n    if (!TmpCurveValues) {\n        TmpCurveValues = new Float32Array(CurveLength);\n    }\n\n    let normalizedCurve: Float32Array;\n\n    if (shape === AudioParameterRampShape.Linear) {\n        TmpLineValues[0] = from;\n        TmpLineValues[1] = to;\n        return TmpLineValues;\n    } else if (shape === AudioParameterRampShape.Exponential) {\n        normalizedCurve = GetExpCurve();\n    } else if (shape === AudioParameterRampShape.Logarithmic) {\n        normalizedCurve = GetLogCurve();\n    } else {\n        throw new Error(`Unknown ramp shape: ${shape}`);\n    }\n\n    const direction = Math.sign(to - from);\n    const range = Math.abs(to - from);\n\n    if (direction === 1) {\n        for (let i = 0; i < normalizedCurve.length; i++) {\n            TmpCurveValues[i] = from + range * normalizedCurve[i];\n        }\n    } else {\n        let j = CurveLength - 1;\n        for (let i = 0; i < normalizedCurve.length; i++, j--) {\n            TmpCurveValues[i] = from - range * (1 - normalizedCurve[j]);\n        }\n    }\n\n    return TmpCurveValues;\n}\n\n/** @internal */\nexport function _CleanUrl(url: string) {\n    return url.replace(/#/gm, \"%23\");\n}\n\n/**\n * Applies `WebRequest.CustomRequestModifiers` URL transformations to the given URL for use with a streaming\n * `<audio>` element. Unlike `_LoadArrayBufferFromUrlAsync`, this does NOT download the audio content —\n * the browser streams it natively. If custom request headers are present they cannot be forwarded to the\n * `<audio>` element (which has no API for custom headers), so a warning is logged and the headers are ignored.\n * @param url - The URL to process (should already be cleaned via `_CleanUrl` if needed).\n * @returns The (possibly rewritten) URL with URL modifiers applied.\n * @internal\n */\nexport function _GetUrlForStreaming(url: string): string {\n    const { url: modifiedUrl, headers } = WebRequest._CollectCustomizations(url);\n    if (Object.keys(headers).length > 0) {\n        Logger.Warn(\n            \"WebAudioStreamingSound: Custom request headers cannot be applied to a streaming <audio> element and will be ignored. \" +\n                \"To use custom headers with audio, switch to a static (non-streaming) sound which fetches the file up-front.\"\n        );\n    }\n    return modifiedUrl;\n}\n\n/**\n * Loads an `ArrayBuffer` from the given URL using `WebRequest.FetchAsync`, so that\n * `WebRequest.CustomRequestHeaders` and `WebRequest.CustomRequestModifiers` are respected for audio network\n * requests just like for any other Babylon.js network call.\n * Uses the Fetch API when available, falling back to XMLHttpRequest otherwise.\n * @param url - The URL to load from (should already be cleaned via `_CleanUrl` if needed).\n * @returns A promise that resolves with the loaded `ArrayBuffer` and the HTTP `Content-Type` response header value.\n * @internal\n */\nexport async function _LoadArrayBufferFromUrlAsync(url: string): Promise<{ data: ArrayBuffer; contentType: string }> {\n    const response = await WebRequest.FetchAsync(url);\n    if (!response.ok) {\n        throw new Error(`HTTP ${response.status} loading '${url}': ${response.statusText}`);\n    }\n    const data = await response.arrayBuffer();\n    const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n    return { data, contentType };\n}\n","import { Logger } from \"../../../Misc/logger\";\nimport { type Nullable } from \"../../../types\";\nimport { type IAudioParameterRampOptions, AudioParameterRampShape } from \"../../audioParameter\";\nimport { _GetAudioParamCurveValues } from \"../../audioUtils\";\nimport { type _WebAudioEngine } from \"../webAudioEngine\";\n\n/**\n * Minimum duration in seconds for a ramp to be considered valid.\n *\n * If the duration is less than this value, the value will be set immediately instead of being ramped smoothly since\n * there is no perceptual difference for such short durations, so a ramp is not needed.\n */\nconst MinRampDuration = 0.000001;\n\nlet Warn = true;\n\n/** @internal */\nexport class _WebAudioParameterComponent {\n    private _rampEndTime: number = 0;\n    private _engine: _WebAudioEngine;\n    private _param: AudioParam;\n    private _targetValue: number;\n\n    /** @internal */\n    constructor(engine: _WebAudioEngine, param: AudioParam) {\n        this._engine = engine;\n        this._param = param;\n        this._targetValue = param.value;\n    }\n\n    /** @internal */\n    public get isRamping(): boolean {\n        return this._engine.currentTime < this._rampEndTime;\n    }\n\n    /** @internal */\n    public get targetValue(): number {\n        return this._targetValue;\n    }\n\n    public set targetValue(value: number) {\n        this.setTargetValue(value);\n    }\n\n    /** @internal */\n    public get value(): number {\n        return this._param.value;\n    }\n\n    /** @internal */\n    public dispose(): void {\n        this._param = null!;\n        this._engine = null!;\n    }\n\n    /**\n     * Sets the target value of the audio parameter with an optional ramping duration and shape.\n     *\n     * @internal\n     */\n    public setTargetValue(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n        if (!Number.isFinite(value)) {\n            Logger.Warn(`Attempted to set audio parameter to non-finite value: ${value}`);\n            return;\n        }\n\n        this._param.cancelScheduledValues(0);\n\n        const shape = typeof options?.shape === \"string\" ? options.shape : AudioParameterRampShape.Linear;\n        const startTime = this._engine.currentTime;\n\n        if (shape === AudioParameterRampShape.None) {\n            this._param.value = this._targetValue = value;\n            this._rampEndTime = startTime;\n            return;\n        }\n\n        let duration = typeof options?.duration === \"number\" ? Math.max(options.duration, this._engine.parameterRampDuration) : this._engine.parameterRampDuration;\n\n        this._targetValue = value;\n\n        if ((duration = Math.max(this._engine.parameterRampDuration, duration)) < MinRampDuration) {\n            this._param.setValueAtTime(value, startTime);\n            return;\n        }\n\n        try {\n            this._param.setValueCurveAtTime(_GetAudioParamCurveValues(shape, Number.isFinite(this._param.value) ? this._param.value : 0, value), startTime, duration);\n            this._rampEndTime = startTime + duration;\n        } catch (e) {\n            if (Warn) {\n                Logger.Warn(`Audio parameter ramping failed: ${(e as Error).message}`);\n                Warn = false;\n            }\n        }\n    }\n}\n","import { Matrix, Quaternion, Vector3 } from \"../../../Maths/math.vector.pure\";\nimport { _SpatialAudioListener } from \"../../abstractAudio/subProperties/spatialAudioListener\";\nimport { _SpatialWebAudioUpdaterComponent } from \"../components/spatialWebAudioUpdaterComponent\";\nimport { _WebAudioParameterComponent } from \"../components/webAudioParameterComponent\";\nimport { type _WebAudioEngine } from \"../webAudioEngine\";\n\nconst TmpMatrix = Matrix.Zero();\nconst TmpQuaternion = new Quaternion();\nconst TmpVector1 = Vector3.Zero();\nconst TmpVector2 = Vector3.Zero();\n\n/** @internal */\nexport function _CreateSpatialAudioListener(engine: _WebAudioEngine, autoUpdate: boolean, minUpdateTime: number): _SpatialAudioListener {\n    const listener = engine._audioContext.listener;\n    if (\n        listener.forwardX &&\n        listener.forwardY &&\n        listener.forwardZ &&\n        listener.positionX &&\n        listener.positionY &&\n        listener.positionZ &&\n        listener.upX &&\n        listener.upY &&\n        listener.upZ\n    ) {\n        return new _SpatialWebAudioListener(engine, autoUpdate, minUpdateTime);\n    } else {\n        return new _SpatialWebAudioListenerFallback(engine, autoUpdate, minUpdateTime);\n    }\n}\n\nabstract class _AbstractSpatialWebAudioListener extends _SpatialAudioListener {\n    protected readonly _listener: AudioListener;\n\n    protected _lastPosition: Vector3 = Vector3.Zero();\n    protected _lastRotation: Vector3 = Vector3.Zero();\n    protected _lastRotationQuaternion: Quaternion = new Quaternion();\n    protected _updaterComponent: _SpatialWebAudioUpdaterComponent;\n\n    /** @internal */\n    public readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public readonly position: Vector3 = Vector3.Zero();\n    /** @internal */\n    public readonly rotation: Vector3 = Vector3.Zero();\n    /** @internal */\n    public readonly rotationQuaternion: Quaternion = new Quaternion();\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine, autoUpdate: boolean, minUpdateTime: number) {\n        super();\n\n        this._listener = engine._audioContext.listener;\n        this.engine = engine;\n\n        this._updaterComponent = new _SpatialWebAudioUpdaterComponent(this, autoUpdate, minUpdateTime);\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._updaterComponent.dispose();\n        this._updaterComponent = null!;\n    }\n\n    /** @internal */\n    public get minUpdateTime(): number {\n        return this._updaterComponent.minUpdateTime;\n    }\n\n    /** @internal */\n    public set minUpdateTime(value: number) {\n        this._updaterComponent.minUpdateTime = value;\n    }\n\n    /** @internal */\n    public update(): void {\n        if (this.isAttached) {\n            this._attacherComponent?.update();\n        } else {\n            this._updatePosition();\n            this._updateRotation();\n        }\n    }\n\n    public _updatePosition(): void {\n        if (this._lastPosition.equalsWithEpsilon(this.position)) {\n            return;\n        }\n\n        this._setWebAudioPosition(this.position);\n\n        this._lastPosition.copyFrom(this.position);\n    }\n\n    public _updateRotation(): void {\n        if (!this._lastRotationQuaternion.equalsWithEpsilon(this.rotationQuaternion)) {\n            TmpQuaternion.copyFrom(this.rotationQuaternion);\n            this._lastRotationQuaternion.copyFrom(this.rotationQuaternion);\n        } else if (!this._lastRotation.equalsWithEpsilon(this.rotation)) {\n            Quaternion.FromEulerAnglesToRef(this.rotation.x, this.rotation.y, this.rotation.z, TmpQuaternion);\n            this._lastRotation.copyFrom(this.rotation);\n        } else {\n            return;\n        }\n\n        Matrix.FromQuaternionToRef(TmpQuaternion, TmpMatrix);\n\n        // NB: The WebAudio API is right-handed.\n        Vector3.TransformNormalToRef(Vector3.RightHandedForwardReadOnly, TmpMatrix, TmpVector1);\n        Vector3.TransformNormalToRef(Vector3.Up(), TmpMatrix, TmpVector2);\n\n        this._setWebAudioOrientation(TmpVector1, TmpVector2);\n    }\n\n    protected abstract _setWebAudioPosition(position: Vector3): void;\n    protected abstract _setWebAudioOrientation(forward: Vector3, up: Vector3): void;\n}\n\n/**\n * Full-featured spatial audio listener for the Web Audio API.\n *\n * Used in browsers that support the `forwardX/Y/Z`, `positionX/Y/Z`, and `upX/Y/Z` properties on the AudioContext listener.\n *\n * NB: Firefox falls back to using this implementation.\n *\n * @see _SpatialWebAudioListenerFallback for the implementation used if only `setPosition` and `setOrientation` are available.\n *\n * NB: This sub property is not backed by a sub node and all properties are set directly on the audio context listener.\n *\n * @internal\n */\nclass _SpatialWebAudioListener extends _AbstractSpatialWebAudioListener {\n    private _forwardX: _WebAudioParameterComponent;\n    private _forwardY: _WebAudioParameterComponent;\n    private _forwardZ: _WebAudioParameterComponent;\n    private _positionX: _WebAudioParameterComponent;\n    private _positionY: _WebAudioParameterComponent;\n    private _positionZ: _WebAudioParameterComponent;\n    private _upX: _WebAudioParameterComponent;\n    private _upY: _WebAudioParameterComponent;\n    private _upZ: _WebAudioParameterComponent;\n\n    public constructor(engine: _WebAudioEngine, autoUpdate: boolean, minUpdateTime: number) {\n        super(engine, autoUpdate, minUpdateTime);\n\n        const listener = engine._audioContext.listener;\n        this._forwardX = new _WebAudioParameterComponent(engine, listener.forwardX);\n        this._forwardY = new _WebAudioParameterComponent(engine, listener.forwardY);\n        this._forwardZ = new _WebAudioParameterComponent(engine, listener.forwardZ);\n        this._positionX = new _WebAudioParameterComponent(engine, listener.positionX);\n        this._positionY = new _WebAudioParameterComponent(engine, listener.positionY);\n        this._positionZ = new _WebAudioParameterComponent(engine, listener.positionZ);\n        this._upX = new _WebAudioParameterComponent(engine, listener.upX);\n        this._upY = new _WebAudioParameterComponent(engine, listener.upY);\n        this._upZ = new _WebAudioParameterComponent(engine, listener.upZ);\n    }\n\n    protected override _setWebAudioPosition(position: Vector3): void {\n        // If attached and there is a ramp in progress, we assume another update is coming soon that we can wait for.\n        // We don't do this for unattached nodes because there may not be another update coming.\n        if (this.isAttached && (this._positionX.isRamping || this._positionY.isRamping || this._positionZ.isRamping)) {\n            return;\n        }\n\n        this._positionX.targetValue = position.x;\n        this._positionY.targetValue = position.y;\n        this._positionZ.targetValue = position.z;\n    }\n\n    protected override _setWebAudioOrientation(forward: Vector3, up: Vector3): void {\n        // If attached and there is a ramp in progress, we assume another update is coming soon that we can wait for.\n        // We don't do this for unattached nodes because there may not be another update coming.\n        if (\n            this.isAttached &&\n            (this._forwardX.isRamping || this._forwardY.isRamping || this._forwardZ.isRamping || this._upX.isRamping || this._upY.isRamping || this._upZ.isRamping)\n        ) {\n            return;\n        }\n\n        this._forwardX.targetValue = forward.x;\n        this._forwardY.targetValue = forward.y;\n        this._forwardZ.targetValue = forward.z;\n\n        this._upX.targetValue = up.x;\n        this._upY.targetValue = up.y;\n        this._upZ.targetValue = up.z;\n    }\n}\n\n/**\n * Fallback spatial audio listener for the Web Audio API.\n *\n * Used in browsers that do not support the `forwardX/Y/Z`, `positionX/Y/Z`, and `upX/Y/Z` properties on the\n * AudioContext listener.\n *\n * @see _SpatialWebAudioListener for the implementation used if the `forwardX/Y/Z`, `positionX/Y/Z`, and `upX/Y/Z`\n * properties are available.\n *\n * NB: This sub property is not backed by a sub node and all properties are set directly on the audio context listener.\n *\n * @internal\n */\nclass _SpatialWebAudioListenerFallback extends _AbstractSpatialWebAudioListener {\n    protected override _setWebAudioPosition(position: Vector3): void {\n        this._listener.setPosition(position.x, position.y, position.z);\n    }\n\n    protected override _setWebAudioOrientation(forward: Vector3, up: Vector3): void {\n        this._listener.setOrientation(forward.x, forward.y, forward.z, up.x, up.y, up.z);\n    }\n}\n","import { Observable } from \"../../Misc/observable\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\n\nexport const enum AudioNodeType {\n    HAS_INPUTS = 1,\n    HAS_OUTPUTS = 2,\n    HAS_INPUTS_AND_OUTPUTS = 3,\n}\n\n/**\n * Abstract class for an audio node.\n *\n * An audio node is a processing unit that can receive audio data from an upstream node and/or send audio data to a\n * downstream node.\n *\n * Nodes can be connected to other nodes to create an audio graph. The audio graph represents the flow of audio data.\n *\n * There are 3 types of audio nodes:\n * 1. Input: Receives audio data from upstream nodes.\n * 2. Output: Sends audio data to downstream nodes.\n * 3. Input/Output: Receives audio data from upstream nodes and sends audio data to downstream nodes.\n */\nexport abstract class AbstractAudioNode {\n    /**\n     * The connected downstream audio nodes.\n     * - Undefined for input nodes.\n     */\n    protected readonly _downstreamNodes?: Set<AbstractAudioNode>;\n\n    /**\n     * The connected upstream audio nodes.\n     * - Undefined for output nodes.\n     */\n    protected readonly _upstreamNodes?: Set<AbstractAudioNode>;\n\n    /**\n     * The audio engine this node belongs to.\n     */\n    public readonly engine: AudioEngineV2;\n\n    /**\n     * Observable for when the audio node is disposed.\n     */\n    public readonly onDisposeObservable = new Observable<AbstractAudioNode>();\n\n    protected constructor(engine: AudioEngineV2, nodeType: AudioNodeType) {\n        this.engine = engine;\n\n        if (nodeType & AudioNodeType.HAS_INPUTS) {\n            this._upstreamNodes = new Set<AbstractAudioNode>();\n        }\n\n        if (nodeType & AudioNodeType.HAS_OUTPUTS) {\n            this._downstreamNodes = new Set<AbstractAudioNode>();\n        }\n    }\n\n    /**\n     * Releases associated resources.\n     * - Triggers `onDisposeObservable`.\n     * @see {@link onDisposeObservable}\n     */\n    public dispose(): void {\n        if (this._downstreamNodes) {\n            for (const node of Array.from(this._downstreamNodes)) {\n                if (!this._disconnect(node)) {\n                    throw new Error(\"Disconnect failed\");\n                }\n            }\n            this._downstreamNodes.clear();\n        }\n\n        if (this._upstreamNodes) {\n            for (const node of Array.from(this._upstreamNodes)) {\n                if (!node._disconnect(this)) {\n                    throw new Error(\"Disconnect failed\");\n                }\n            }\n            this._upstreamNodes.clear();\n        }\n\n        this.onDisposeObservable.notifyObservers(this);\n        this.onDisposeObservable.clear();\n    }\n\n    /**\n     * Gets a string identifying the name of the class\n     * @returns the class's name as a string\n     */\n    public abstract getClassName(): string;\n\n    /**\n     * Connect to a downstream audio input node.\n     * @param node - The downstream audio input node to connect\n     * @returns `true` if the node is successfully connected; otherwise `false`\n     */\n    protected _connect(node: AbstractAudioNode): boolean {\n        if (!this._downstreamNodes) {\n            return false;\n        }\n\n        if (this._downstreamNodes.has(node)) {\n            return false;\n        }\n\n        if (!node._onConnect(this)) {\n            return false;\n        }\n\n        this._downstreamNodes.add(node);\n\n        return true;\n    }\n\n    /**\n     * Disconnects a downstream audio input node.\n     * @param node - The downstream audio input node to disconnect\n     * @returns `true` if the node is successfully disconnected; otherwise `false`\n     */\n    protected _disconnect(node: AbstractAudioNode): boolean {\n        if (!this._downstreamNodes) {\n            return false;\n        }\n\n        if (!this._downstreamNodes.delete(node)) {\n            return false;\n        }\n\n        return node._onDisconnect(this);\n    }\n\n    /**\n     * Called when an upstream audio output node is connecting.\n     * @param node - The connecting upstream audio node\n     * @returns `true` if the node is successfully connected; otherwise `false`\n     */\n    private _onConnect(node: AbstractAudioNode): boolean {\n        if (!this._upstreamNodes) {\n            return false;\n        }\n\n        if (this._upstreamNodes.has(node)) {\n            return false;\n        }\n\n        this._upstreamNodes.add(node);\n\n        return true;\n    }\n\n    /**\n     * Called when an upstream audio output node disconnects.\n     * @param node - The disconnecting upstream audio node\n     * @returns `true` if node is sucessfully disconnected; otherwise `false`\n     */\n    private _onDisconnect(node: AbstractAudioNode): boolean {\n        return this._upstreamNodes?.delete(node) ?? false;\n    }\n}\n\n/**\n * Abstract class for a named audio node.\n */\nexport abstract class AbstractNamedAudioNode extends AbstractAudioNode {\n    private _name: string;\n\n    /**\n     * Observable for when the audio node is renamed.\n     */\n    public readonly onNameChangedObservable = new Observable<{ newName: string; oldName: string; node: AbstractNamedAudioNode }>();\n\n    protected constructor(name: string, engine: AudioEngineV2, nodeType: AudioNodeType) {\n        super(engine, nodeType);\n\n        this._name = name;\n    }\n\n    /**\n     * The name of the audio node.\n     * - Triggers `onNameChangedObservable` when changed.\n     * @see {@link onNameChangedObservable}\n     */\n    public get name(): string {\n        return this._name;\n    }\n\n    public set name(newName: string) {\n        if (this._name === newName) {\n            return;\n        }\n\n        const oldName = this._name;\n\n        this._name = newName;\n\n        this.onNameChangedObservable.notifyObservers({ newName, oldName, node: this });\n    }\n\n    public override dispose(): void {\n        super.dispose();\n\n        this.onNameChangedObservable.clear();\n    }\n}\n","import { AudioNodeType, AbstractAudioNode } from \"./abstractAudioNode\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\n\n/**\n * Abstract class for the main audio output node.\n *\n * A main audio output is the last audio node in the audio graph before the audio is sent to the speakers.\n *\n * @see {@link AudioEngineV2.mainOut}\n * @internal\n */\nexport abstract class _MainAudioOut extends AbstractAudioNode {\n    protected constructor(engine: AudioEngineV2) {\n        super(engine, AudioNodeType.HAS_INPUTS);\n    }\n}\n","import { type Nullable } from \"../../types\";\nimport { _MainAudioOut } from \"../abstractAudio/mainAudioOut\";\nimport { type IAudioParameterRampOptions } from \"../audioParameter\";\nimport { _WebAudioParameterComponent } from \"./components/webAudioParameterComponent\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode } from \"./webAudioNode\";\n\n/** @internal */\nexport class _WebAudioMainOut extends _MainAudioOut implements IWebAudioInNode {\n    private _gainNode: GainNode;\n    private _volume: _WebAudioParameterComponent;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine) {\n        super(engine);\n\n        this._setGainNode(new GainNode(engine._audioContext));\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._volume.dispose();\n        this._gainNode.disconnect();\n        this._destinationNode.disconnect();\n    }\n\n    /** @internal */\n    public get _inNode(): GainNode {\n        return this._gainNode;\n    }\n\n    public set _inNode(value: GainNode) {\n        if (this._gainNode === value) {\n            return;\n        }\n\n        this._setGainNode(value);\n    }\n\n    /** @internal */\n    public get volume(): number {\n        return this._volume.targetValue;\n    }\n\n    /** @internal */\n    public set volume(value: number) {\n        this._volume.targetValue = value;\n    }\n\n    private get _destinationNode(): AudioNode {\n        return this.engine._audioDestination;\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioMainOut\";\n    }\n\n    /** @internal */\n    public setVolume(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n        this._volume.setTargetValue(value, options);\n    }\n\n    private _setGainNode(gainNode: GainNode): void {\n        if (this._gainNode === gainNode) {\n            return;\n        }\n\n        this._gainNode?.disconnect();\n        gainNode.connect(this._destinationNode);\n\n        this._volume = new _WebAudioParameterComponent(this.engine, gainNode.gain);\n\n        this._gainNode = gainNode;\n    }\n}\n","import { type Nullable } from \"../../types\";\nimport { EngineStore } from \"../../Engines/engineStore\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\n\n/**\n * Adds a UI button that starts the audio engine's underlying audio context when the user presses it.\n * @internal\n */\nexport class _WebAudioUnmuteUI {\n    private _button: Nullable<HTMLButtonElement> = null;\n    private _enabled: boolean = true;\n    private _engine: _WebAudioEngine;\n    private _style: Nullable<HTMLStyleElement> = null;\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine, parentElement?: HTMLElement) {\n        this._engine = engine;\n        const parent = parentElement || EngineStore.LastCreatedEngine?.getInputElement()?.parentElement || document.body;\n        const top = (parent?.offsetTop || 0) + 20;\n\n        this._style = document.createElement(\"style\");\n        this._style.appendChild(\n            document.createTextNode(\n                `.babylonUnmute{position:absolute;top:${top}px;margin-left:20px;height:40px;width:60px;background-color:rgba(51,51,51,0.7);background-image:url(\"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2239%22%20height%3D%2232%22%20viewBox%3D%220%200%2039%2032%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M9.625%2018.938l-0.031%200.016h-4.953q-0.016%200-0.031-0.016v-12.453q0-0.016%200.031-0.016h4.953q0.031%200%200.031%200.016v12.453zM12.125%207.688l8.719-8.703v27.453l-8.719-8.719-0.016-0.047v-9.938zM23.359%207.875l1.406-1.406%204.219%204.203%204.203-4.203%201.422%201.406-4.219%204.219%204.219%204.203-1.484%201.359-4.141-4.156-4.219%204.219-1.406-1.422%204.219-4.203z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\");background-size:80%;background-repeat:no-repeat;background-position:center;background-position-y:4px;border:none;outline:none;transition:transform 0.125s ease-out;cursor:pointer;z-index:9999;}.babylonUnmute:hover{transform:scale(1.05)}`\n            )\n        );\n        document.head.appendChild(this._style);\n\n        this._button = document.createElement(\"button\");\n        this._button.className = \"babylonUnmute\";\n        this._button.id = \"babylonUnmuteButton\";\n\n        this._button.addEventListener(\"click\", () => {\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this._engine.unlockAsync();\n        });\n\n        parent.appendChild(this._button);\n\n        this._engine.stateChangedObservable.add(this._onStateChanged);\n    }\n\n    /** @internal */\n    public dispose(): void {\n        this._button?.remove();\n        this._button = null;\n\n        this._style?.remove();\n        this._style = null;\n\n        this._engine.stateChangedObservable.removeCallback(this._onStateChanged);\n    }\n\n    /** @internal */\n    public get enabled(): boolean {\n        return this._enabled;\n    }\n\n    public set enabled(value: boolean) {\n        this._enabled = value;\n        if (value) {\n            if (this._engine.state !== \"running\") {\n                this._show();\n            }\n        } else {\n            this._hide();\n        }\n    }\n\n    private _show(): void {\n        if (!this._button || !this._enabled) {\n            return;\n        }\n\n        this._button.style.display = \"block\";\n    }\n\n    private _hide(): void {\n        if (!this._button) {\n            return;\n        }\n\n        this._button.style.display = \"none\";\n    }\n\n    private _onStateChanged = () => {\n        if (!this._button) {\n            return;\n        }\n\n        if (this._engine.state === \"running\") {\n            this._hide();\n        } else {\n            this._show();\n        }\n    };\n}\n","import { Observable } from \"../../Misc/observable\";\nimport { type Nullable } from \"../../types\";\nimport { type AbstractNamedAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type AbstractSound } from \"../abstractAudio/abstractSound\";\nimport { SoundState } from \"../soundState\";\nimport { type AbstractSoundSource, type ISoundSourceOptions } from \"../abstractAudio/abstractSoundSource\";\nimport { type AudioBus, type IAudioBusOptions } from \"../abstractAudio/audioBus\";\nimport { type AudioEngineV2State, type IAudioEngineV2Options, AudioEngineV2, OnAudioEngineV2CreatedObservable } from \"../abstractAudio/audioEngineV2\";\nimport { type IMainAudioBusOptions, type MainAudioBus } from \"../abstractAudio/mainAudioBus\";\nimport { type IStaticSoundOptions, type StaticSound } from \"../abstractAudio/staticSound\";\nimport { type IStaticSoundBufferOptions, type StaticSoundBuffer } from \"../abstractAudio/staticSoundBuffer\";\nimport { type IStreamingSoundOptions, type StreamingSound } from \"../abstractAudio/streamingSound\";\nimport { type AbstractSpatialAudioListener, _HasSpatialAudioListenerOptions } from \"../abstractAudio/subProperties/abstractSpatialAudioListener\";\nimport { type _SpatialAudioListener } from \"../abstractAudio/subProperties/spatialAudioListener\";\nimport { type IAudioParameterRampOptions } from \"../audioParameter\";\nimport { _CreateSpatialAudioListener } from \"./subProperties/spatialWebAudioListener\";\nimport { _WebAudioMainOut } from \"./webAudioMainOut\";\nimport { _WebAudioUnmuteUI } from \"./webAudioUnmuteUI\";\n\n/**\n * Options for creating a v2 audio engine that uses the WebAudio API.\n */\nexport interface IWebAudioEngineOptions extends IAudioEngineV2Options {\n    /**\n     * The audio context to be used by the engine.\n     */\n    audioContext: AudioContext;\n    /**\n     * The default UI's parent element. Defaults to the last created graphics engine's canvas if it exists; otherwise the HTML document's body.\n     */\n    defaultUIParentElement?: HTMLElement;\n    /**\n     * Set to `true` to disable the default UI. Defaults to `false`.\n     */\n    disableDefaultUI?: boolean;\n    /**\n     * Set to `true` to disable the silent HTML audio element used to allow WebAudio playback when the iOS ringer switch is off.\n     * This can avoid rendering performance degradation on affected iOS and iPadOS devices, but WebAudio may be muted when the ringer switch is off.\n     * Defaults to `false`.\n     */\n    disableIOSRingerSwitchWorkaround?: boolean;\n    /**\n     * Set to `true` to automatically resume the audio context when the user interacts with the page. Defaults to `true`.\n     */\n    resumeOnInteraction: boolean;\n    /**\n     * Set to `true` to automatically resume the audio context when the browser pauses audio playback. Defaults to `true`.\n     */\n    resumeOnPause: boolean;\n    /**\n     * The interval in milliseconds to try resuming audio playback when `resumeOnPause` is `true`. Defaults to `1000`.\n     */\n    resumeOnPauseRetryInterval: number;\n}\n\n/**\n * Creates a new v2 audio engine that uses the WebAudio API.\n * @param options - The options for creating the audio engine.\n * @returns A promise that resolves with the created audio engine.\n */\nexport async function CreateAudioEngineAsync(options: Partial<IWebAudioEngineOptions> = {}): Promise<AudioEngineV2> {\n    const engine = new _WebAudioEngine(options);\n    await engine._initAsync(options);\n    OnAudioEngineV2CreatedObservable.notifyObservers(engine);\n    return engine;\n}\n\nconst FormatMimeTypes: { [key: string]: string } = {\n    aac: \"audio/aac\",\n    ac3: \"audio/ac3\",\n    flac: \"audio/flac\",\n    m4a: \"audio/mp4\",\n    mp3: 'audio/mpeg; codecs=\"mp3\"',\n    mp4: \"audio/mp4\",\n    ogg: 'audio/ogg; codecs=\"vorbis\"',\n    wav: \"audio/wav\",\n    webm: 'audio/webm; codecs=\"vorbis\"',\n};\n\n/** @internal */\nexport class _WebAudioEngine extends AudioEngineV2 {\n    private _audioContextStarted = false;\n    private _destinationNode: Nullable<AudioNode> = null;\n    private readonly _disableIOSRingerSwitchWorkaround: boolean;\n    private _invalidFormats = new Set<string>();\n    private _isUpdating = false;\n    private _listener: Nullable<_SpatialAudioListener> = null;\n    private readonly _listenerAutoUpdate: boolean = true;\n    private readonly _listenerMinUpdateTime: number = 0;\n    private _mainOut: _WebAudioMainOut;\n    private _pauseCalled = false;\n    private _resumeOnInteraction = true;\n    private _resumeOnPause = true;\n    private _resumeOnPauseRetryInterval = 1000;\n    private _resumeOnPauseTimerId: any = null;\n    private _resumePromise: Nullable<Promise<void>> = null;\n    private _silentHtmlAudio: Nullable<HTMLAudioElement> = null;\n    private _unmuteUI: Nullable<_WebAudioUnmuteUI> = null;\n    private _updateObservable: Nullable<Observable<void>> = null;\n    private readonly _validFormats = new Set<string>();\n    private _volume = 1;\n\n    /** @internal */\n    public readonly _audioContext: AudioContext;\n\n    /** @internal */\n    public readonly _isUsingOfflineAudioContext: boolean = false;\n\n    /** @internal */\n    public readonly isReadyPromise: Promise<void> = new Promise((resolve) => {\n        this._resolveIsReadyPromise = resolve;\n    });\n\n    /** @internal */\n    public stateChangedObservable: Observable<string> = new Observable();\n\n    /** @internal */\n    public userGestureObservable: Observable<void> = new Observable();\n\n    /** @internal */\n    public constructor(options: Partial<IWebAudioEngineOptions> = {}) {\n        super(options);\n\n        if (typeof options.listenerAutoUpdate === \"boolean\") {\n            this._listenerAutoUpdate = options.listenerAutoUpdate;\n        }\n\n        if (typeof options.listenerMinUpdateTime === \"number\") {\n            this._listenerMinUpdateTime = options.listenerMinUpdateTime;\n        }\n\n        this._disableIOSRingerSwitchWorkaround = options.disableIOSRingerSwitchWorkaround ?? false;\n        this._volume = options.volume ?? 1;\n\n        if (options.audioContext) {\n            this._isUsingOfflineAudioContext = options.audioContext instanceof OfflineAudioContext;\n            this._audioContext = options.audioContext;\n        } else {\n            this._audioContext = new AudioContext();\n        }\n\n        if (!options.disableDefaultUI) {\n            this._unmuteUI = new _WebAudioUnmuteUI(this, options.defaultUIParentElement);\n        }\n    }\n\n    /** @internal */\n    public async _initAsync(options: Partial<IWebAudioEngineOptions>): Promise<void> {\n        this._resumeOnInteraction = typeof options.resumeOnInteraction === \"boolean\" ? options.resumeOnInteraction : true;\n        this._resumeOnPause = typeof options.resumeOnPause === \"boolean\" ? options.resumeOnPause : true;\n        this._resumeOnPauseRetryInterval = options.resumeOnPauseRetryInterval ?? 1000;\n\n        document.addEventListener(\"click\", this._onUserGestureAsync);\n\n        await this._initAudioContextAsync();\n\n        if (_HasSpatialAudioListenerOptions(options)) {\n            this._listener = _CreateSpatialAudioListener(this, this._listenerAutoUpdate, this._listenerMinUpdateTime);\n            this._listener.setOptions(options);\n        }\n\n        this._resolveIsReadyPromise();\n    }\n\n    /** @internal */\n    public get currentTime(): number {\n        return this._audioContext.currentTime ?? 0;\n    }\n\n    /** @internal */\n    public get _inNode(): AudioNode {\n        return this._audioContext.destination;\n    }\n\n    /** @internal */\n    public get mainOut(): _WebAudioMainOut {\n        return this._mainOut;\n    }\n\n    /** @internal */\n    public get listener(): AbstractSpatialAudioListener {\n        return this._listener ?? (this._listener = _CreateSpatialAudioListener(this, this._listenerAutoUpdate, this._listenerMinUpdateTime));\n    }\n\n    /** @internal */\n    public get state(): AudioEngineV2State {\n        // Always return \"running\" for OfflineAudioContext so sound `play` calls work while the context is suspended.\n        return this._isUsingOfflineAudioContext ? \"running\" : this._audioContext.state;\n    }\n\n    /** @internal */\n    public get volume(): number {\n        return this._volume;\n    }\n\n    /** @internal */\n    public set volume(value: number) {\n        if (this._volume === value) {\n            return;\n        }\n\n        this._volume = value;\n\n        if (this._mainOut) {\n            this._mainOut.volume = value;\n        }\n    }\n\n    /**\n     * This property should only be used by the legacy audio engine.\n     * @internal\n     * */\n    public get _audioDestination(): AudioNode {\n        return this._destinationNode ? this._destinationNode : (this._destinationNode = this._audioContext.destination);\n    }\n\n    public set _audioDestination(value: Nullable<AudioNode>) {\n        this._destinationNode = value;\n    }\n\n    /**\n     * This property should only be used by the legacy audio engine.\n     * @internal\n     */\n    public get _unmuteUIEnabled(): boolean {\n        return this._unmuteUI ? this._unmuteUI.enabled : false;\n    }\n\n    public set _unmuteUIEnabled(value: boolean) {\n        if (this._unmuteUI) {\n            this._unmuteUI.enabled = value;\n        }\n    }\n\n    /** @internal */\n    public async createBusAsync(name: string, options: Partial<IAudioBusOptions> = {}): Promise<AudioBus> {\n        const module = await import(\"./webAudioBus\");\n\n        const bus = new module._WebAudioBus(name, this, options);\n        await bus._initAsync(options);\n\n        return bus;\n    }\n\n    /** @internal */\n    public async createMainBusAsync(name: string, options: Partial<IMainAudioBusOptions> = {}): Promise<MainAudioBus> {\n        const module = await import(\"./webAudioMainBus\");\n\n        const bus = new module._WebAudioMainBus(name, this);\n        await bus._initAsync(options);\n\n        return bus;\n    }\n\n    /** @internal */\n    public async createMicrophoneSoundSourceAsync(name: string, options?: Partial<ISoundSourceOptions>): Promise<AbstractSoundSource> {\n        let mediaStream: MediaStream;\n\n        try {\n            mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n        } catch (e) {\n            throw new Error(\"Unable to access microphone: \" + e, { cause: e });\n        }\n\n        return await this.createSoundSourceAsync(name, new MediaStreamAudioSourceNode(this._audioContext, { mediaStream }), {\n            outBusAutoDefault: false,\n            mediaStreamSinkEnabled: false,\n            stopMediaStreamTracksOnDispose: true,\n            ...options,\n        });\n    }\n\n    /** @internal */\n    public async createSoundAsync(\n        name: string,\n        source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n        options: Partial<IStaticSoundOptions> = {}\n    ): Promise<StaticSound> {\n        const module = await import(\"./webAudioStaticSound\");\n\n        const sound = new module._WebAudioStaticSound(name, this, options);\n        await sound._initAsync(source, options);\n\n        return sound;\n    }\n\n    /** @internal */\n    public async createSoundBufferAsync(\n        source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n        options: Partial<IStaticSoundBufferOptions> = {}\n    ): Promise<StaticSoundBuffer> {\n        const module = await import(\"./webAudioStaticSound\");\n\n        const soundBuffer = new module._WebAudioStaticSoundBuffer(this);\n        await soundBuffer._initAsync(source, options);\n\n        return soundBuffer;\n    }\n\n    /** @internal */\n    public async createSoundSourceAsync(name: string, source: AudioNode, options: Partial<ISoundSourceOptions> = {}): Promise<AbstractSoundSource> {\n        const module = await import(\"./webAudioSoundSource\");\n\n        const soundSource = new module._WebAudioSoundSource(name, source, this, options);\n        await soundSource._initAsync(options);\n\n        return soundSource;\n    }\n\n    /** @internal */\n    public async createStreamingSoundAsync(name: string, source: HTMLMediaElement | string | string[], options: Partial<IStreamingSoundOptions> = {}): Promise<StreamingSound> {\n        const module = await import(\"./webAudioStreamingSound\");\n\n        const sound = new module._WebAudioStreamingSound(name, this, options);\n        await sound._initAsync(source, options);\n\n        return sound;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._listener?.dispose();\n        this._listener = null;\n\n        // Note that OfflineAudioContext does not have a `close` method.\n        if (this._audioContext.state !== \"closed\" && !this._isUsingOfflineAudioContext) {\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this._audioContext.close();\n        }\n\n        document.removeEventListener(\"click\", this._onUserGestureAsync);\n        this._audioContext.removeEventListener(\"statechange\", this._onAudioContextStateChange);\n\n        this._silentHtmlAudio?.remove();\n\n        this._updateObservable?.clear();\n        this._updateObservable = null;\n\n        this._unmuteUI?.dispose();\n        this._unmuteUI = null;\n\n        this.stateChangedObservable.clear();\n    }\n\n    /** @internal */\n    public flagInvalidFormat(format: string): void {\n        this._invalidFormats.add(format);\n    }\n\n    /** @internal */\n    public isFormatValid(format: string): boolean {\n        if (this._validFormats.has(format)) {\n            return true;\n        }\n\n        if (this._invalidFormats.has(format)) {\n            return false;\n        }\n\n        const mimeType = FormatMimeTypes[format];\n        if (mimeType === undefined) {\n            return false;\n        }\n\n        const audio = new Audio();\n        if (audio.canPlayType(mimeType) === \"\") {\n            this._invalidFormats.add(format);\n            return false;\n        }\n\n        this._validFormats.add(format);\n\n        return true;\n    }\n\n    /** @internal */\n    public override async pauseAsync(): Promise<void> {\n        await this._audioContext.suspend();\n\n        this._pauseCalled = true;\n    }\n\n    /** @internal */\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n    public override resumeAsync(): Promise<void> {\n        this._pauseCalled = false;\n\n        if (this._resumePromise) {\n            return this._resumePromise;\n        }\n\n        this._resumePromise = this._audioContext.resume();\n\n        this.stateChangedObservable.notifyObservers(this.state);\n\n        return this._resumePromise;\n    }\n\n    /** @internal */\n    public setVolume(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n        if (this._mainOut) {\n            this._mainOut.setVolume(value, options);\n        } else {\n            throw new Error(\"Main output not initialized yet.\");\n        }\n    }\n\n    /** @internal */\n    public override _addMainBus(mainBus: MainAudioBus): void {\n        super._addMainBus(mainBus);\n    }\n\n    /** @internal */\n    public override _removeMainBus(mainBus: MainAudioBus): void {\n        super._removeMainBus(mainBus);\n    }\n\n    /** @internal */\n    public override _addNode(node: AbstractNamedAudioNode): void {\n        super._addNode(node);\n    }\n\n    /** @internal */\n    public override _removeNode(node: AbstractNamedAudioNode): void {\n        super._removeNode(node);\n    }\n\n    /** @internal */\n    public override _addSound(sound: AbstractSound): void {\n        super._addSound(sound);\n    }\n\n    /** @internal */\n    public override _removeSound(sound: AbstractSound): void {\n        super._removeSound(sound);\n    }\n\n    /** @internal */\n    public override _onSoundPlaybackStateChanged(): void {\n        if (!this._silentHtmlAudio) {\n            return;\n        }\n\n        const hasActiveSounds = this.sounds.some((s) => s.state === SoundState.Started || s.state === SoundState.Starting || s.state === SoundState.Stopping);\n\n        if (hasActiveSounds && this._silentHtmlAudio.paused) {\n            // Resume silent audio for iOS ringer switch workaround while sounds are playing.\n            // Errors are safe to ignore — the silent audio element is a workaround, not a\n            // user-facing sound, so a rejected play (e.g. missing user gesture) is harmless.\n            // eslint-disable-next-line github/no-then\n            void this._silentHtmlAudio.play().catch(() => {});\n        } else if (!hasActiveSounds && !this._silentHtmlAudio.paused) {\n            // Pause silent audio when no sounds are playing to avoid keeping an iOS media\n            // playback session active, which can reduce rendering performance on affected devices.\n            this._silentHtmlAudio.pause();\n        }\n    }\n\n    /** @internal */\n    public _addUpdateObserver(callback: () => void): void {\n        if (!this._updateObservable) {\n            this._updateObservable = new Observable<void>();\n        }\n\n        this._updateObservable.add(callback);\n        this._startUpdating();\n    }\n\n    public _removeUpdateObserver(callback: () => void): void {\n        if (this._updateObservable) {\n            this._updateObservable.removeCallback(callback);\n        }\n    }\n\n    private _initAudioContextAsync: () => Promise<void> = async () => {\n        this._audioContext.addEventListener(\"statechange\", this._onAudioContextStateChange);\n\n        this._mainOut = new _WebAudioMainOut(this);\n        this._mainOut.volume = this._volume;\n\n        await this.createMainBusAsync(\"default\");\n    };\n\n    private _onAudioContextStateChange = () => {\n        if (this.state === \"running\") {\n            clearInterval(this._resumeOnPauseTimerId);\n            this._audioContextStarted = true;\n            this._resumePromise = null;\n        }\n        if (this.state === \"suspended\" || this.state === \"interrupted\") {\n            if (this._audioContextStarted && this._resumeOnPause && !this._pauseCalled) {\n                clearInterval(this._resumeOnPauseTimerId);\n\n                this._resumeOnPauseTimerId = setInterval(() => {\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n                    this.resumeAsync();\n                }, this._resumeOnPauseRetryInterval);\n            }\n        }\n\n        this.stateChangedObservable.notifyObservers(this.state);\n    };\n\n    private _onUserGestureAsync: () => void = async () => {\n        if (this._resumeOnInteraction) {\n            await this._audioContext.resume();\n        }\n\n        // On iOS the ringer switch must be turned on for WebAudio to play.\n        // This gets WebAudio to play with the ringer switch turned off by playing an HTMLAudioElement.\n        // The element is activated during a user gesture so it can be played/paused programmatically\n        // later. It is immediately paused so the iOS media playback session stays inactive until\n        // a Babylon sound starts.\n        if (!this._disableIOSRingerSwitchWorkaround && !this._silentHtmlAudio) {\n            this._silentHtmlAudio = document.createElement(\"audio\");\n\n            const audio = this._silentHtmlAudio;\n            audio.controls = false;\n            audio.preload = \"auto\";\n            audio.loop = true;\n\n            // Wave data for 0.0001 seconds of silence.\n            audio.src = \"data:audio/wav;base64,UklGRjAAAABXQVZFZm10IBAAAAABAAEAgLsAAAB3AQACABAAZGF0YQwAAAAAAAEA/v8CAP//AQA=\";\n\n            // Play briefly to activate the element, then immediately pause.\n            // The rejection handler is intentionally empty — play() can reject if the\n            // browser requires a more specific user gesture; this is non-fatal since\n            // the audio context unlock is the primary goal, and the silent element is\n            // only a supplementary iOS ringer-switch workaround.\n            // eslint-disable-next-line github/no-then\n            audio.play().then(\n                () => audio.pause(),\n                () => {}\n            );\n        }\n\n        this.userGestureObservable.notifyObservers();\n    };\n\n    private _resolveIsReadyPromise: () => void;\n\n    private _startUpdating = () => {\n        if (this._isUpdating) {\n            return;\n        }\n\n        this._isUpdating = true;\n\n        if (this.state === \"running\") {\n            this._update();\n        } else {\n            const callback = () => {\n                if (this.state === \"running\") {\n                    this._update();\n                    this.stateChangedObservable.removeCallback(callback);\n                }\n            };\n\n            this.stateChangedObservable.add(callback);\n        }\n    };\n\n    private _update = (): void => {\n        if (this._updateObservable?.hasObservers()) {\n            this._updateObservable.notifyObservers();\n            requestAnimationFrame(this._update);\n        } else {\n            this._isUpdating = false;\n        }\n    };\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { _WebAudioEngine } from \"../AudioV2/webAudio/webAudioEngine\";\r\nimport { type _WebAudioMainBus } from \"../AudioV2/webAudio/webAudioMainBus\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { type Analyser } from \"./analyser\";\r\nimport { type IAudioEngine } from \"./Interfaces/IAudioEngine\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * This represents the default audio engine used in babylon.\r\n * It is responsible to play, synchronize and analyse sounds throughout the  application.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n */\r\nexport class AudioEngine implements IAudioEngine {\r\n    private _masterGain: GainNode;\r\n    private _tryToRun = false;\r\n    private _useCustomUnlockedButton: boolean = false;\r\n\r\n    /**\r\n     * Gets whether the current host supports Web Audio and thus could create AudioContexts.\r\n     */\r\n    public canUseWebAudio: boolean = true;\r\n\r\n    /**\r\n     * The master gain node defines the global audio volume of your audio engine.\r\n     */\r\n    public get masterGain(): GainNode {\r\n        return this._masterGain;\r\n    }\r\n\r\n    public set masterGain(value: GainNode) {\r\n        this._masterGain = this._v2.mainOut._inNode = value;\r\n    }\r\n\r\n    /**\r\n     * Defines if Babylon should emit a warning if WebAudio is not supported.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public WarnedWebAudioUnsupported: boolean = false;\r\n\r\n    /**\r\n     * Gets whether or not mp3 are supported by your browser.\r\n     */\r\n    public isMP3supported: boolean = false;\r\n\r\n    /**\r\n     * Gets whether or not ogg are supported by your browser.\r\n     */\r\n    public isOGGsupported: boolean = false;\r\n\r\n    /**\r\n     * Gets whether audio has been unlocked on the device.\r\n     * Some Browsers have strong restrictions about Audio and won't autoplay unless\r\n     * a user interaction has happened.\r\n     */\r\n    public unlocked: boolean = false;\r\n\r\n    /**\r\n     * Defines if the audio engine relies on a custom unlocked button.\r\n     * In this case, the embedded button will not be displayed.\r\n     */\r\n    public get useCustomUnlockedButton(): boolean {\r\n        return this._useCustomUnlockedButton;\r\n    }\r\n\r\n    public set useCustomUnlockedButton(value: boolean) {\r\n        this._useCustomUnlockedButton = value;\r\n        this._v2._unmuteUIEnabled = !value;\r\n    }\r\n\r\n    /**\r\n     * Event raised when audio has been unlocked on the browser.\r\n     */\r\n    public onAudioUnlockedObservable = new Observable<IAudioEngine>();\r\n\r\n    /**\r\n     * Event raised when audio has been locked on the browser.\r\n     */\r\n    public onAudioLockedObservable = new Observable<IAudioEngine>();\r\n\r\n    /** @internal */\r\n    public _v2: _WebAudioEngine;\r\n\r\n    /**\r\n     * Gets the current AudioContext if available.\r\n     */\r\n    public get audioContext(): Nullable<AudioContext> {\r\n        if (this._v2.state === \"running\") {\r\n            // Do not wait for the promise to unlock.\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            this._triggerRunningStateAsync();\r\n        }\r\n        return this._v2._audioContext;\r\n    }\r\n\r\n    private _connectedAnalyser: Nullable<Analyser>;\r\n\r\n    /**\r\n     * Instantiates a new audio engine.\r\n     *\r\n     * @param hostElement defines the host element where to display the mute icon if necessary\r\n     * @param audioContext defines the audio context to be used by the audio engine\r\n     * @param audioDestination defines the audio destination node to be used by audio engine\r\n     */\r\n    constructor(\r\n        hostElement: Nullable<HTMLElement> = null,\r\n        audioContext: Nullable<AudioContext> = null,\r\n        audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode> = null\r\n    ) {\r\n        const v2 = new _WebAudioEngine({\r\n            audioContext: audioContext ? audioContext : undefined,\r\n            defaultUIParentElement: hostElement?.parentElement ? hostElement.parentElement : undefined,\r\n        });\r\n\r\n        // Historically the unmute button is disabled until a sound tries to play and can't, which results in a call\r\n        // to `AudioEngine.lock()`, which is where the unmute button is enabled if no custom UI is requested.\r\n        v2._unmuteUIEnabled = false;\r\n\r\n        this._masterGain = new GainNode(v2._audioContext);\r\n        v2._audioDestination = audioDestination;\r\n\r\n        v2.stateChangedObservable.add((state) => {\r\n            if (state === \"running\") {\r\n                this.unlocked = true;\r\n                this.onAudioUnlockedObservable.notifyObservers(this);\r\n            } else {\r\n                this.unlocked = false;\r\n                this.onAudioLockedObservable.notifyObservers(this);\r\n            }\r\n        });\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        v2._initAsync({ resumeOnInteraction: false }).then(() => {\r\n            const mainBusOutNode = (v2.defaultMainBus as _WebAudioMainBus)._outNode;\r\n            if (mainBusOutNode) {\r\n                mainBusOutNode.disconnect(v2.mainOut._inNode);\r\n                mainBusOutNode.connect(this._masterGain);\r\n            }\r\n\r\n            v2.mainOut._inNode = this._masterGain;\r\n            v2.stateChangedObservable.notifyObservers(v2.state);\r\n        });\r\n\r\n        this.isMP3supported = v2.isFormatValid(\"mp3\");\r\n        this.isOGGsupported = v2.isFormatValid(\"ogg\");\r\n\r\n        this._v2 = v2;\r\n    }\r\n\r\n    /**\r\n     * Flags the audio engine in Locked state.\r\n     * This happens due to new browser policies preventing audio to autoplay.\r\n     */\r\n    public lock() {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._v2._audioContext.suspend();\r\n\r\n        if (!this._useCustomUnlockedButton) {\r\n            this._v2._unmuteUIEnabled = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Unlocks the audio engine once a user action has been done on the dom.\r\n     * This is helpful to resume play once browser policies have been satisfied.\r\n     */\r\n    public unlock() {\r\n        if (this._v2._audioContext?.state === \"running\") {\r\n            if (!this.unlocked) {\r\n                // Notify users that the audio stack is unlocked/unmuted\r\n                this.unlocked = true;\r\n                this.onAudioUnlockedObservable.notifyObservers(this);\r\n            }\r\n\r\n            return;\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._triggerRunningStateAsync();\r\n    }\r\n\r\n    /** @internal */\r\n    public _resumeAudioContextOnStateChange(): void {\r\n        this._v2._audioContext?.addEventListener(\r\n            \"statechange\",\r\n            () => {\r\n                if (this.unlocked && this._v2._audioContext?.state !== \"running\") {\r\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n                    this._resumeAudioContextAsync();\r\n                }\r\n            },\r\n            {\r\n                once: true,\r\n                passive: true,\r\n                signal: AbortSignal.timeout(3000),\r\n            }\r\n        );\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    private _resumeAudioContextAsync(): Promise<void> {\r\n        if (this._v2._isUsingOfflineAudioContext) {\r\n            return Promise.resolve();\r\n        }\r\n\r\n        if (this._v2._audioContext.state === \"suspended\" && !this._useCustomUnlockedButton) {\r\n            this._v2._unmuteUIEnabled = true;\r\n        }\r\n\r\n        return this._v2._audioContext.resume();\r\n    }\r\n\r\n    /**\r\n     * Destroy and release the resources associated with the audio context.\r\n     */\r\n    public dispose(): void {\r\n        this._v2.dispose();\r\n\r\n        this.onAudioUnlockedObservable.clear();\r\n        this.onAudioLockedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Gets the global volume sets on the master gain.\r\n     * @returns the global volume if set or -1 otherwise\r\n     */\r\n    public getGlobalVolume(): number {\r\n        return this.masterGain.gain.value;\r\n    }\r\n\r\n    /**\r\n     * Sets the global volume of your experience (sets on the master gain).\r\n     * @param newVolume Defines the new global volume of the application\r\n     */\r\n    public setGlobalVolume(newVolume: number): void {\r\n        this.masterGain.gain.value = newVolume;\r\n    }\r\n\r\n    /**\r\n     * Connect the audio engine to an audio analyser allowing some amazing\r\n     * synchronization between the sounds/music and your visualization (VuMeter for instance).\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-the-analyser\r\n     * @param analyser The analyser to connect to the engine\r\n     */\r\n    public connectToAnalyser(analyser: Analyser): void {\r\n        if (this._connectedAnalyser) {\r\n            this._connectedAnalyser.stopDebugCanvas();\r\n        }\r\n\r\n        this._connectedAnalyser = analyser;\r\n        this.masterGain.disconnect();\r\n        this._connectedAnalyser.connectAudioNodes(this.masterGain, this._v2._audioContext.destination);\r\n    }\r\n\r\n    private async _triggerRunningStateAsync() {\r\n        if (this._tryToRun) {\r\n            void this._v2._audioContext.resume();\r\n            return;\r\n        }\r\n        this._tryToRun = true;\r\n\r\n        await this._resumeAudioContextAsync();\r\n\r\n        this._tryToRun = false;\r\n        this.unlocked = true;\r\n\r\n        this.onAudioUnlockedObservable.notifyObservers(this);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for audioEngine.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAudioEngine(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Sets the default audio engine to Babylon.js\r\n    AbstractEngine.AudioEngineFactory = (\r\n        hostElement: Nullable<HTMLElement>,\r\n        audioContext: Nullable<AudioContext>,\r\n        audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode>\r\n    ) => {\r\n        return new AudioEngine(hostElement, audioContext, audioDestination);\r\n    };\r\n}\r\n","import { type Sound } from \"./sound\";\r\nimport { type Analyser } from \"./analyser\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * Options allowed during the creation of a sound track.\r\n */\r\nexport interface ISoundTrackOptions {\r\n    /**\r\n     * The volume the sound track should take during creation\r\n     */\r\n    volume?: number;\r\n    /**\r\n     * Define if the sound track is the main sound track of the scene\r\n     */\r\n    mainTrack?: boolean;\r\n}\r\n\r\n/**\r\n * It could be useful to isolate your music & sounds on several tracks to better manage volume on a grouped instance of sounds.\r\n * It will be also used in a future release to apply effects on a specific track.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-sound-tracks\r\n */\r\nexport class SoundTrack {\r\n    /**\r\n     * The unique identifier of the sound track in the scene.\r\n     */\r\n    public id: number = -1;\r\n    /**\r\n     * The list of sounds included in the sound track.\r\n     */\r\n    public soundCollection: Array<Sound>;\r\n\r\n    private _outputAudioNode: Nullable<GainNode>;\r\n    private _scene: Scene;\r\n    private _connectedAnalyser: Analyser;\r\n    private _options: ISoundTrackOptions;\r\n    private _isInitialized = false;\r\n\r\n    /**\r\n     * Creates a new sound track.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-sound-tracks\r\n     * @param scene Define the scene the sound track belongs to\r\n     * @param options\r\n     */\r\n    constructor(scene?: Nullable<Scene>, options: ISoundTrackOptions = {}) {\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this._scene = scene;\r\n        this.soundCollection = [];\r\n        this._options = options;\r\n\r\n        if (!this._options.mainTrack && this._scene.soundTracks) {\r\n            this._scene.soundTracks.push(this);\r\n            this.id = this._scene.soundTracks.length - 1;\r\n        }\r\n    }\r\n\r\n    private _initializeSoundTrackAudioGraph() {\r\n        if (AbstractEngine.audioEngine?.canUseWebAudio && AbstractEngine.audioEngine.audioContext) {\r\n            this._outputAudioNode = AbstractEngine.audioEngine.audioContext.createGain();\r\n            this._outputAudioNode.connect(AbstractEngine.audioEngine.masterGain);\r\n\r\n            if (this._options) {\r\n                if (this._options.volume) {\r\n                    this._outputAudioNode.gain.value = this._options.volume;\r\n                }\r\n            }\r\n\r\n            this._isInitialized = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release the sound track and its associated resources\r\n     */\r\n    public dispose(): void {\r\n        if (AbstractEngine.audioEngine && AbstractEngine.audioEngine.canUseWebAudio) {\r\n            if (this._connectedAnalyser) {\r\n                this._connectedAnalyser.stopDebugCanvas();\r\n            }\r\n            while (this.soundCollection.length) {\r\n                this.soundCollection[0].dispose();\r\n            }\r\n            if (this._outputAudioNode) {\r\n                this._outputAudioNode.disconnect();\r\n            }\r\n            this._outputAudioNode = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a sound to this sound track\r\n     * @param sound define the sound to add\r\n     * @ignoreNaming\r\n     */\r\n    public addSound(sound: Sound): void {\r\n        if (!this._isInitialized) {\r\n            this._initializeSoundTrackAudioGraph();\r\n        }\r\n        if (AbstractEngine.audioEngine?.canUseWebAudio && this._outputAudioNode) {\r\n            sound.connectToSoundTrackAudioNode(this._outputAudioNode);\r\n        }\r\n        if (sound.soundTrackId !== undefined) {\r\n            if (sound.soundTrackId === -1) {\r\n                this._scene.mainSoundTrack.removeSound(sound);\r\n            } else if (this._scene.soundTracks) {\r\n                this._scene.soundTracks[sound.soundTrackId].removeSound(sound);\r\n            }\r\n        }\r\n\r\n        this.soundCollection.push(sound);\r\n        sound.soundTrackId = this.id;\r\n    }\r\n\r\n    /**\r\n     * Removes a sound to this sound track\r\n     * @param sound define the sound to remove\r\n     * @ignoreNaming\r\n     */\r\n    public removeSound(sound: Sound): void {\r\n        const index = this.soundCollection.indexOf(sound);\r\n        if (index !== -1) {\r\n            this.soundCollection.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set a global volume for the full sound track.\r\n     * @param newVolume Define the new volume of the sound track\r\n     */\r\n    public setVolume(newVolume: number): void {\r\n        if (AbstractEngine.audioEngine?.canUseWebAudio && this._outputAudioNode) {\r\n            this._outputAudioNode.gain.value = newVolume;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Switch the panning model to HRTF:\r\n     * Renders a stereo output of higher quality than equalpower — it uses a convolution with measured impulse responses from human subjects.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#creating-a-spatial-3d-sound\r\n     */\r\n    public switchPanningModelToHRTF(): void {\r\n        if (AbstractEngine.audioEngine?.canUseWebAudio) {\r\n            for (let i = 0; i < this.soundCollection.length; i++) {\r\n                this.soundCollection[i].switchPanningModelToHRTF();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Switch the panning model to Equal Power:\r\n     * Represents the equal-power panning algorithm, generally regarded as simple and efficient. equalpower is the default value.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#creating-a-spatial-3d-sound\r\n     */\r\n    public switchPanningModelToEqualPower(): void {\r\n        if (AbstractEngine.audioEngine?.canUseWebAudio) {\r\n            for (let i = 0; i < this.soundCollection.length; i++) {\r\n                this.soundCollection[i].switchPanningModelToEqualPower();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Connect the sound track to an audio analyser allowing some amazing\r\n     * synchronization between the sounds/music and your visualization (VuMeter for instance).\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-the-analyser\r\n     * @param analyser The analyser to connect to the engine\r\n     */\r\n    public connectToAnalyser(analyser: Analyser): void {\r\n        if (this._connectedAnalyser) {\r\n            this._connectedAnalyser.stopDebugCanvas();\r\n        }\r\n        this._connectedAnalyser = analyser;\r\n        if (AbstractEngine.audioEngine?.canUseWebAudio && this._outputAudioNode) {\r\n            this._outputAudioNode.disconnect();\r\n            this._connectedAnalyser.connectAudioNodes(this._outputAudioNode, AbstractEngine.audioEngine.masterGain);\r\n        }\r\n    }\r\n}\r\n","import { type AssetContainer } from \"core/assetContainer\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * Defines how the parser contract is defined.\r\n * These parsers are used to parse a list of specific assets (like particle systems, etc..)\r\n */\r\nexport type BabylonFileParser = (parsedData: any, scene: Scene, container: AssetContainer, rootUrl: string) => void;\r\n\r\n/**\r\n * Defines how the individual parser contract is defined.\r\n * These parser can parse an individual asset\r\n */\r\nexport type IndividualBabylonFileParser = (parsedData: any, scene: Scene, rootUrl: string) => any;\r\n\r\n/**\r\n * Stores the list of available parsers in the application.\r\n */\r\nconst BabylonFileParsers: { [key: string]: BabylonFileParser } = {};\r\n\r\n/**\r\n * Stores the list of available individual parsers in the application.\r\n */\r\nconst IndividualBabylonFileParsers: { [key: string]: IndividualBabylonFileParser } = {};\r\n\r\n/**\r\n * Adds a parser in the list of available ones\r\n * @param name Defines the name of the parser\r\n * @param parser Defines the parser to add\r\n */\r\nexport function AddParser(name: string, parser: BabylonFileParser): void {\r\n    BabylonFileParsers[name] = parser;\r\n}\r\n\r\n/**\r\n * Gets a general parser from the list of available ones\r\n * @param name Defines the name of the parser\r\n * @returns the requested parser or null\r\n */\r\nexport function GetParser(name: string): Nullable<BabylonFileParser> {\r\n    if (BabylonFileParsers[name]) {\r\n        return BabylonFileParsers[name];\r\n    }\r\n\r\n    return null;\r\n}\r\n\r\n/**\r\n * Adds n individual parser in the list of available ones\r\n * @param name Defines the name of the parser\r\n * @param parser Defines the parser to add\r\n */\r\nexport function AddIndividualParser(name: string, parser: IndividualBabylonFileParser): void {\r\n    IndividualBabylonFileParsers[name] = parser;\r\n}\r\n\r\n/**\r\n * Gets an individual parser from the list of available ones\r\n * @param name Defines the name of the parser\r\n * @returns the requested parser or null\r\n */\r\nexport function GetIndividualParser(name: string): Nullable<IndividualBabylonFileParser> {\r\n    if (IndividualBabylonFileParsers[name]) {\r\n        return IndividualBabylonFileParsers[name];\r\n    }\r\n\r\n    return null;\r\n}\r\n\r\n/**\r\n * Parser json data and populate both a scene and its associated container object\r\n * @param jsonData Defines the data to parse\r\n * @param scene Defines the scene to parse the data for\r\n * @param container Defines the container attached to the parsing sequence\r\n * @param rootUrl Defines the root url of the data\r\n */\r\nexport function Parse(jsonData: any, scene: Scene, container: AssetContainer, rootUrl: string): void {\r\n    for (const parserName in BabylonFileParsers) {\r\n        if (Object.prototype.hasOwnProperty.call(BabylonFileParsers, parserName)) {\r\n            BabylonFileParsers[parserName](jsonData, scene, container, rootUrl);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Sound } from \"./sound.pure\";\r\nimport { SoundTrack } from \"./soundTrack\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { SceneComponentConstants, type ISceneSerializableComponent } from \"../sceneComponent\";\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { PrecisionDate } from \"../Misc/precisionDate\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AssetContainer } from \"../assetContainer\";\r\nimport { AddParser } from \"core/Loading/Plugins/babylonFileParser.function\";\r\n\r\n/**\r\n * Defines the sound scene component responsible to manage any sounds\r\n * in a given scene.\r\n * @deprecated please use AudioEngineV2 instead\r\n */\r\nexport class AudioSceneComponent implements ISceneSerializableComponent {\r\n    private static _CameraDirection = /*#__PURE__*/ new Vector3(0, 0, -1);\r\n\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_AUDIO;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    private _audioEnabled = true;\r\n    /**\r\n     * Gets whether audio is enabled or not.\r\n     * Please use related enable/disable method to switch state.\r\n     */\r\n    public get audioEnabled(): boolean {\r\n        return this._audioEnabled;\r\n    }\r\n\r\n    private _headphone = false;\r\n    /**\r\n     * Gets whether audio is outputting to headphone or not.\r\n     * Please use the according Switch methods to change output.\r\n     */\r\n    public get headphone(): boolean {\r\n        return this._headphone;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a refresh rate when using 3D audio positioning\r\n     */\r\n    public audioPositioningRefreshRate = 500;\r\n\r\n    /**\r\n     * Gets or Sets a custom listener position for all sounds in the scene\r\n     * By default, this is the position of the first active camera\r\n     */\r\n    public audioListenerPositionProvider: Nullable<() => Vector3> = null;\r\n\r\n    /**\r\n     * Gets or Sets a custom listener rotation for all sounds in the scene\r\n     * By default, this is the rotation of the first active camera\r\n     */\r\n    public audioListenerRotationProvider: Nullable<() => Vector3> = null;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene?: Nullable<Scene>) {\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this.scene = scene;\r\n\r\n        scene.soundTracks = [] as SoundTrack[];\r\n        scene.sounds = [] as Sound[];\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._afterRenderStage.registerStep(SceneComponentConstants.STEP_AFTERRENDER_AUDIO, this, this._afterRender);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do here. (Not rendering related)\r\n    }\r\n\r\n    /**\r\n     * Serializes the component data to the specified json object\r\n     * @param serializationObject The object to serialize to\r\n     */\r\n    public serialize(serializationObject: any): void {\r\n        serializationObject.sounds = [];\r\n\r\n        if (this.scene.soundTracks) {\r\n            for (let index = 0; index < this.scene.soundTracks.length; index++) {\r\n                const soundtrack = this.scene.soundTracks[index];\r\n\r\n                for (let soundId = 0; soundId < soundtrack.soundCollection.length; soundId++) {\r\n                    serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     * @param container the container holding the elements\r\n     */\r\n    public addFromContainer(container: IAssetContainer): void {\r\n        if (!container.sounds) {\r\n            return;\r\n        }\r\n        for (const sound of container.sounds) {\r\n            sound.play();\r\n            sound.autoplay = true;\r\n            this.scene.mainSoundTrack.addSound(sound);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     * @param container contains the elements to remove\r\n     * @param dispose if the removed element should be disposed (default: false)\r\n     */\r\n    public removeFromContainer(container: IAssetContainer, dispose = false): void {\r\n        if (!container.sounds) {\r\n            return;\r\n        }\r\n        for (const sound of container.sounds) {\r\n            sound.stop();\r\n            sound.autoplay = false;\r\n            this.scene.mainSoundTrack.removeSound(sound);\r\n            if (dispose) {\r\n                sound.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        const scene = this.scene;\r\n        if (scene._mainSoundTrack) {\r\n            scene.mainSoundTrack.dispose();\r\n        }\r\n\r\n        if (scene.soundTracks) {\r\n            for (let scIndex = 0; scIndex < scene.soundTracks.length; scIndex++) {\r\n                scene.soundTracks[scIndex].dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disables audio in the associated scene.\r\n     */\r\n    public disableAudio() {\r\n        const scene = this.scene;\r\n        this._audioEnabled = false;\r\n\r\n        if (AbstractEngine.audioEngine && AbstractEngine.audioEngine.audioContext) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            AbstractEngine.audioEngine.audioContext.suspend();\r\n        }\r\n\r\n        let i: number;\r\n        for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {\r\n            scene.mainSoundTrack.soundCollection[i].pause();\r\n        }\r\n        if (scene.soundTracks) {\r\n            for (i = 0; i < scene.soundTracks.length; i++) {\r\n                for (let j = 0; j < scene.soundTracks[i].soundCollection.length; j++) {\r\n                    scene.soundTracks[i].soundCollection[j].pause();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables audio in the associated scene.\r\n     */\r\n    public enableAudio() {\r\n        const scene = this.scene;\r\n        this._audioEnabled = true;\r\n\r\n        if (AbstractEngine.audioEngine && AbstractEngine.audioEngine.audioContext) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            AbstractEngine.audioEngine.audioContext.resume();\r\n        }\r\n\r\n        let i: number;\r\n        for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {\r\n            if (scene.mainSoundTrack.soundCollection[i].isPaused) {\r\n                scene.mainSoundTrack.soundCollection[i].play();\r\n            }\r\n        }\r\n        if (scene.soundTracks) {\r\n            for (i = 0; i < scene.soundTracks.length; i++) {\r\n                for (let j = 0; j < scene.soundTracks[i].soundCollection.length; j++) {\r\n                    if (scene.soundTracks[i].soundCollection[j].isPaused) {\r\n                        scene.soundTracks[i].soundCollection[j].play();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Switch audio to headphone output.\r\n     */\r\n    public switchAudioModeForHeadphones() {\r\n        const scene = this.scene;\r\n        this._headphone = true;\r\n\r\n        scene.mainSoundTrack.switchPanningModelToHRTF();\r\n        if (scene.soundTracks) {\r\n            for (let i = 0; i < scene.soundTracks.length; i++) {\r\n                scene.soundTracks[i].switchPanningModelToHRTF();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Switch audio to normal speakers.\r\n     */\r\n    public switchAudioModeForNormalSpeakers() {\r\n        const scene = this.scene;\r\n        this._headphone = false;\r\n\r\n        scene.mainSoundTrack.switchPanningModelToEqualPower();\r\n\r\n        if (scene.soundTracks) {\r\n            for (let i = 0; i < scene.soundTracks.length; i++) {\r\n                scene.soundTracks[i].switchPanningModelToEqualPower();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _cachedCameraDirection = new Vector3();\r\n    private _cachedCameraPosition = new Vector3();\r\n    private _lastCheck = 0;\r\n    private _invertMatrixTemp = new Matrix();\r\n    private _cameraDirectionTemp = new Vector3();\r\n\r\n    private _afterRender() {\r\n        const now = PrecisionDate.Now;\r\n        if (this._lastCheck && now - this._lastCheck < this.audioPositioningRefreshRate) {\r\n            return;\r\n        }\r\n\r\n        this._lastCheck = now;\r\n\r\n        const scene = this.scene;\r\n        if (!this._audioEnabled || !scene._mainSoundTrack || !scene.soundTracks || (scene._mainSoundTrack.soundCollection.length === 0 && scene.soundTracks.length === 1)) {\r\n            return;\r\n        }\r\n\r\n        const audioEngine = AbstractEngine.audioEngine;\r\n\r\n        if (!audioEngine) {\r\n            return;\r\n        }\r\n\r\n        if (audioEngine.audioContext) {\r\n            let listeningCamera = scene.activeCamera;\r\n            if (scene.activeCameras && scene.activeCameras.length > 0) {\r\n                listeningCamera = scene.activeCameras[0];\r\n            }\r\n\r\n            // A custom listener position provider was set\r\n            // Use the users provided position instead of camera's\r\n            if (this.audioListenerPositionProvider) {\r\n                const position: Vector3 = this.audioListenerPositionProvider();\r\n                // Set the listener position\r\n                audioEngine.audioContext.listener.setPosition(position.x || 0, position.y || 0, position.z || 0);\r\n                // Check if there is a listening camera\r\n            } else if (listeningCamera) {\r\n                // Set the listener position to the listening camera global position\r\n                if (!this._cachedCameraPosition.equals(listeningCamera.globalPosition)) {\r\n                    this._cachedCameraPosition.copyFrom(listeningCamera.globalPosition);\r\n                    audioEngine.audioContext.listener.setPosition(listeningCamera.globalPosition.x, listeningCamera.globalPosition.y, listeningCamera.globalPosition.z);\r\n                }\r\n            }\r\n            // Otherwise set the listener position to 0, 0 ,0\r\n            else {\r\n                // Set the listener position\r\n                audioEngine.audioContext.listener.setPosition(0, 0, 0);\r\n            }\r\n\r\n            // A custom listener rotation provider was set\r\n            // Use the users provided rotation instead of camera's\r\n            if (this.audioListenerRotationProvider) {\r\n                const rotation: Vector3 = this.audioListenerRotationProvider();\r\n                audioEngine.audioContext.listener.setOrientation(rotation.x || 0, rotation.y || 0, rotation.z || 0, 0, 1, 0);\r\n                // Check if there is a listening camera\r\n            } else if (listeningCamera) {\r\n                // for VR cameras\r\n                if (listeningCamera.rigCameras && listeningCamera.rigCameras.length > 0) {\r\n                    listeningCamera = listeningCamera.rigCameras[0];\r\n                }\r\n\r\n                listeningCamera.getViewMatrix().invertToRef(this._invertMatrixTemp);\r\n                Vector3.TransformNormalToRef(AudioSceneComponent._CameraDirection, this._invertMatrixTemp, this._cameraDirectionTemp);\r\n                this._cameraDirectionTemp.normalize();\r\n                // To avoid some errors on GearVR\r\n                if (!isNaN(this._cameraDirectionTemp.x) && !isNaN(this._cameraDirectionTemp.y) && !isNaN(this._cameraDirectionTemp.z)) {\r\n                    if (!this._cachedCameraDirection.equals(this._cameraDirectionTemp)) {\r\n                        this._cachedCameraDirection.copyFrom(this._cameraDirectionTemp);\r\n                        audioEngine.audioContext.listener.setOrientation(this._cameraDirectionTemp.x, this._cameraDirectionTemp.y, this._cameraDirectionTemp.z, 0, 1, 0);\r\n                    }\r\n                }\r\n            }\r\n            // Otherwise set the listener rotation to 0, 0 ,0\r\n            else {\r\n                // Set the listener position\r\n                audioEngine.audioContext.listener.setOrientation(0, 0, 0, 0, 1, 0);\r\n            }\r\n\r\n            let i: number;\r\n            for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {\r\n                const sound = scene.mainSoundTrack.soundCollection[i];\r\n                if (sound.useCustomAttenuation) {\r\n                    sound.updateDistanceFromListener();\r\n                }\r\n            }\r\n            if (scene.soundTracks) {\r\n                for (i = 0; i < scene.soundTracks.length; i++) {\r\n                    for (let j = 0; j < scene.soundTracks[i].soundCollection.length; j++) {\r\n                        const sound = scene.soundTracks[i].soundCollection[j];\r\n                        if (sound.useCustomAttenuation) {\r\n                            sound.updateDistanceFromListener();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for audioSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param soundClass The Sound class to register the component for\r\n */\r\nexport function RegisterAudioSceneComponent(soundClass: typeof Sound): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Adds the parser to the scene parsers.\r\n    AddParser(SceneComponentConstants.NAME_AUDIO, (parsedData: any, scene: Scene, container: AssetContainer, rootUrl: string) => {\r\n        // TODO: add sound\r\n        const loadedSounds: Sound[] = [];\r\n        let loadedSound: Sound;\r\n        container.sounds = container.sounds || [];\r\n        if (parsedData.sounds !== undefined && parsedData.sounds !== null) {\r\n            for (let index = 0, cache = parsedData.sounds.length; index < cache; index++) {\r\n                const parsedSound = parsedData.sounds[index];\r\n                if (AbstractEngine.audioEngine?.canUseWebAudio) {\r\n                    if (!parsedSound.url) {\r\n                        parsedSound.url = parsedSound.name;\r\n                    }\r\n                    if (!loadedSounds[parsedSound.url]) {\r\n                        loadedSound = soundClass.Parse(parsedSound, scene, rootUrl);\r\n                        loadedSounds[parsedSound.url] = loadedSound;\r\n                        container.sounds.push(loadedSound);\r\n                    } else {\r\n                        container.sounds.push(soundClass.Parse(parsedSound, scene, rootUrl, loadedSounds[parsedSound.url]));\r\n                    }\r\n                } else {\r\n                    container.sounds.push(new soundClass(parsedSound.name, null, scene));\r\n                }\r\n            }\r\n        }\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"mainSoundTrack\", {\r\n        get: function (this: Scene) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            if (!this._mainSoundTrack) {\r\n                this._mainSoundTrack = new SoundTrack(this, { mainTrack: true });\r\n            }\r\n\r\n            return this._mainSoundTrack;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.getSoundByName = function (name: string): Nullable<Sound> {\r\n        let index: number;\r\n        for (index = 0; index < this.mainSoundTrack.soundCollection.length; index++) {\r\n            if (this.mainSoundTrack.soundCollection[index].name === name) {\r\n                return this.mainSoundTrack.soundCollection[index];\r\n            }\r\n        }\r\n\r\n        if (this.soundTracks) {\r\n            for (let sdIndex = 0; sdIndex < this.soundTracks.length; sdIndex++) {\r\n                for (index = 0; index < this.soundTracks[sdIndex].soundCollection.length; index++) {\r\n                    if (this.soundTracks[sdIndex].soundCollection[index].name === name) {\r\n                        return this.soundTracks[sdIndex].soundCollection[index];\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    Object.defineProperty(Scene.prototype, \"audioEnabled\", {\r\n        get: function (this: Scene) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            return compo.audioEnabled;\r\n        },\r\n        set: function (this: Scene, value: boolean) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            if (value) {\r\n                compo.enableAudio();\r\n            } else {\r\n                compo.disableAudio();\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"headphone\", {\r\n        get: function (this: Scene) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            return compo.headphone;\r\n        },\r\n        set: function (this: Scene, value: boolean) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            if (value) {\r\n                compo.switchAudioModeForHeadphones();\r\n            } else {\r\n                compo.switchAudioModeForNormalSpeakers();\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"audioListenerPositionProvider\", {\r\n        get: function (this: Scene) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            return compo.audioListenerPositionProvider;\r\n        },\r\n        set: function (this: Scene, value: () => Vector3) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            if (value && typeof value !== \"function\") {\r\n                throw new Error(\"The value passed to [Scene.audioListenerPositionProvider] must be a function that returns a Vector3\");\r\n            } else {\r\n                compo.audioListenerPositionProvider = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"audioListenerRotationProvider\", {\r\n        get: function (this: Scene) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            return compo.audioListenerRotationProvider;\r\n        },\r\n        set: function (this: Scene, value: () => Vector3) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            if (value && typeof value !== \"function\") {\r\n                throw new Error(\"The value passed to [Scene.audioListenerRotationProvider] must be a function that returns a Vector3\");\r\n            } else {\r\n                compo.audioListenerRotationProvider = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"audioPositioningRefreshRate\", {\r\n        get: function (this: Scene) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            return compo.audioPositioningRefreshRate;\r\n        },\r\n        set: function (this: Scene, value: number) {\r\n            let compo = this._getComponent(SceneComponentConstants.NAME_AUDIO) as AudioSceneComponent;\r\n            if (!compo) {\r\n                compo = new AudioSceneComponent(this);\r\n                this._addComponent(compo);\r\n            }\r\n\r\n            compo.audioPositioningRefreshRate = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    soundClass._SceneComponentInitialization = (scene: Scene) => {\r\n        let compo = scene._getComponent(SceneComponentConstants.NAME_AUDIO);\r\n        if (!compo) {\r\n            compo = new AudioSceneComponent(scene);\r\n            scene._addComponent(compo);\r\n        }\r\n    };\r\n}\r\n","import { Quaternion, Vector3 } from \"../../../Maths/math.vector.pure\";\nimport { type Node } from \"../../../node\";\nimport { type Nullable } from \"../../../types\";\nimport { type SpatialAudioAttachmentType } from \"../../spatialAudioAttachmentType\";\n\nexport const _SpatialAudioDefaults = {\n    coneInnerAngle: 6.28318530718 as number,\n    coneOuterAngle: 6.28318530718 as number,\n    coneOuterVolume: 0 as number,\n    distanceModel: \"linear\" as DistanceModelType,\n    maxDistance: 10000 as number,\n    minDistance: 1 as number,\n    orientation: Vector3.Right(),\n    panningEnabled: true as boolean,\n    panningModel: \"equalpower\" as PanningModelType,\n    position: Vector3.Zero(),\n    rolloffFactor: 1 as number,\n    rotation: Vector3.Zero(),\n    rotationQuaternion: new Quaternion(),\n} as const;\n\n/**\n * Options for spatial audio.\n */\nexport interface ISpatialAudioOptions {\n    /**\n     * Whether to automatically update the spatial properties of the audio node. Defaults to `true`.\n     */\n    spatialAutoUpdate: boolean;\n    /**\n     * The spatial cone inner angle, in radians. Defaults to 2π.\n     * - When the listener is inside the cone inner angle, the volume is at its maximum.\n     */\n    spatialConeInnerAngle: number;\n    /**\n     * The spatial cone outer angle, in radians. Defaults to 2π.\n     * - When the listener is between the the cone inner and outer angles, the volume fades to its minimum as the listener approaches the outer angle.\n     * - When the listener is outside the cone outer angle, the volume is at its minimum.\n     */\n    spatialConeOuterAngle: number;\n    /**\n     * The amount of volume reduction outside the {@link spatialConeOuterAngle}. Defaults to 0.\n     */\n    spatialConeOuterVolume: number;\n    /**\n     * The algorithm to use to reduce the volume of the audio source as it moves away from the listener. Defaults to \"inverse\".\n     *\n     * Possible values are:\n     * - `\"linear\"`: The volume is reduced linearly as the source moves away from the listener.\n     * - `\"inverse\"`: The volume is reduced inversely as the source moves away from the listener.\n     * - `\"exponential\"`: The volume is reduced exponentially as the source moves away from the listener.\n     *\n     * @see {@link spatialMaxDistance}\n     * @see {@link spatialMinDistance}\n     * @see {@link spatialRolloffFactor}\n     */\n    spatialDistanceModel: \"linear\" | \"inverse\" | \"exponential\";\n    /**\n     * Enable spatial audio. Defaults to false.\n     *\n     * When set to `true`, the audio node's spatial properties will be initialized on creation and there will be no\n     * delay when setting the first spatial value.\n     *\n     * When not specified, or set to `false`, the audio node's spatial properties will not be initialized on creation\n     * and there will be a small delay when setting the first spatial value.\n     *\n     * - This option is ignored if any other spatial options are set.\n     */\n    spatialEnabled: boolean;\n    /**\n     * The maximum distance between the audio source and the listener, after which the volume is not reduced any further. Defaults to 10000.\n     * - This value is used only when the {@link spatialDistanceModel} is set to `\"linear\"`.\n     * @see {@link spatialDistanceModel}\n     */\n    spatialMaxDistance: number;\n    /**\n     * The minimum update time in seconds of the spatialization if it is attached to a mesh or transform node. Defaults to `0`.\n     * - The spatialization's position and rotation will not update faster than this time, but they may update slower depending on the frame rate.\n     */\n    spatialMinUpdateTime: number;\n    /**\n     * The spatial orientation used to determine the direction of the audio source. Defaults to (0, 0, -1).\n     */\n    spatialOrientation: Vector3;\n    /**\n     * Whether to spatially pan the audio source. Defaults to `true`.\n     *\n     * When set to `false`, the source keeps distance attenuation but does not pan between the left and right channels.\n     * Sound cone attenuation is not applied while panning is disabled.\n     */\n    spatialPanningEnabled: boolean;\n    /**\n     * Possible values are:\n     * - `\"equalpower\"`: Represents the equal-power panning algorithm, generally regarded as simple and efficient.\n     * - `\"HRTF\"`: Renders a stereo output of higher quality than `\"equalpower\"` — it uses a convolution with measured impulse responses from human subjects.\n     */\n    spatialPanningModel: \"equalpower\" | \"HRTF\";\n    /**\n     * The spatial position. Defaults to (0, 0, 0).\n     */\n    spatialPosition: Vector3;\n    /**\n     * The distance for reducing volume as the audio source moves away from the listener – i.e. the distance the volume reduction starts at. Defaults to 1.\n     * - This value is used by all distance models.\n     * @see {@link spatialDistanceModel}\n     */\n    spatialMinDistance: number;\n    /**\n     * How quickly the volume is reduced as the source moves away from the listener. Defaults to 1.\n     * - This value is used by all distance models.\n     * @see {@link spatialDistanceModel}\n     */\n    spatialRolloffFactor: number;\n    /**\n     * The spatial rotation, as Euler angles. Defaults to (0, 0, 0).\n     */\n    spatialRotation: Vector3;\n    /**\n     * The spatial rotation, as a quaternion. Defaults to (0, 0, 0, 1).\n     */\n    spatialRotationQuaternion: Quaternion;\n}\n\n/**\n * @param options The spatial audio options to check.\n * @returns `true` if spatial audio options are defined, otherwise `false`.\n */\nexport function _HasSpatialAudioOptions(options: Partial<ISpatialAudioOptions>): boolean {\n    return (\n        options.spatialEnabled ||\n        options.spatialAutoUpdate !== undefined ||\n        options.spatialConeInnerAngle !== undefined ||\n        options.spatialConeOuterAngle !== undefined ||\n        options.spatialConeOuterVolume !== undefined ||\n        options.spatialDistanceModel !== undefined ||\n        options.spatialMaxDistance !== undefined ||\n        options.spatialMinDistance !== undefined ||\n        options.spatialMinUpdateTime !== undefined ||\n        options.spatialOrientation !== undefined ||\n        options.spatialPanningEnabled !== undefined ||\n        options.spatialPanningModel !== undefined ||\n        options.spatialPosition !== undefined ||\n        options.spatialRolloffFactor !== undefined ||\n        options.spatialRotation !== undefined ||\n        options.spatialRotationQuaternion !== undefined\n    );\n}\n\n/**\n * Abstract class representing the `spatial` audio property on a sound or audio bus.\n *\n * @see {@link AudioEngineV2.listener}\n */\nexport abstract class AbstractSpatialAudio {\n    /**\n     * The spatial cone inner angle, in radians. Defaults to 2π.\n     * - When the listener is inside the cone inner angle, the volume is at its maximum.\n     */\n    public abstract coneInnerAngle: number;\n\n    /**\n     * The spatial cone outer angle, in radians. Defaults to 2π.\n     * - When the listener is between the the cone inner and outer angles, the volume fades to its minimum as the listener approaches the outer angle.\n     * - When the listener is outside the cone outer angle, the volume is at its minimum.\n     */\n    public abstract coneOuterAngle: number;\n\n    /**\n     * The amount of volume reduction outside the {@link coneOuterAngle}. Defaults to 0.\n     */\n    public abstract coneOuterVolume: number;\n\n    /**\n     * The algorithm to use to reduce the volume of the audio source as it moves away from the listener. Defaults to \"inverse\".\n     *\n     * Possible values are:\n     * - `\"linear\"`: The volume is reduced linearly as the source moves away from the listener.\n     * - `\"inverse\"`: The volume is reduced inversely as the source moves away from the listener.\n     * - `\"exponential\"`: The volume is reduced exponentially as the source moves away from the listener.\n     *\n     * @see {@link spatialMaxDistance}\n     * @see {@link spatialMinDistance}\n     * @see {@link spatialRolloffFactor}\n     */\n    public abstract distanceModel: \"linear\" | \"inverse\" | \"exponential\";\n\n    /**\n     * Whether the audio source is attached to a mesh or transform node.\n     */\n    public abstract isAttached: boolean;\n\n    /**\n     * The scene node this spatial audio is currently attached to, or `null` if not attached.\n     */\n    public abstract attachedNode: Nullable<Node>;\n\n    /**\n     * Whether the spatial audio is positioned using the attached scene node's bounding box (when the node is a mesh) instead of its world transform.\n     * - Only meaningful while {@link isAttached} is `true`.\n     */\n    public abstract useBoundingBox: boolean;\n\n    /**\n     * Which components (position, rotation, or both) of the attached scene node's world transform drive the spatial audio.\n     * - Only meaningful while {@link isAttached} is `true`.\n     */\n    public abstract attachmentType: SpatialAudioAttachmentType;\n\n    /**\n     * The maximum distance between the audio source and the listener, after which the volume is not reduced any further. Defaults to 10000.\n     * - This value is used only when the {@link distanceModel} is set to `\"linear\"`.\n     * @see {@link distanceModel}\n     */\n    public abstract maxDistance: number;\n\n    /**\n     * The distance for reducing volume as the audio source moves away from the listener – i.e. the distance the volume reduction starts at. Defaults to 1.\n     * - This value is used by all distance models.\n     * @see {@link distanceModel}\n     */\n    public abstract minDistance: number;\n\n    /**\n     * The minimum update time in seconds of the spatialization if it is attached to a mesh or transform node. Defaults to `0`.\n     * - The spatialization's position and rotation will not update faster than this time, but they may update slower depending on the frame rate.\n     */\n    public abstract minUpdateTime: number;\n\n    /**\n     * The spatial orientation used to determine the direction of the audio source. Defaults to (0, 0, -1).\n     */\n    public abstract orientation: Vector3;\n\n    /**\n     * Whether to spatially pan the audio source. Defaults to `true`.\n     *\n     * When set to `false`, the source keeps distance attenuation but does not pan between the left and right channels.\n     * Sound cone attenuation is not applied while panning is disabled.\n     */\n    public abstract panningEnabled: boolean;\n\n    /**\n     * The spatial panning model. Defaults to \"equalpower\".\n     *\n     * Possible values are:\n     * - `\"equalpower\"`: Represents the equal-power panning algorithm, generally regarded as simple and efficient.\n     * - `\"HRTF\"`:Renders a stereo output of higher quality than `\"equalpower\"` — it uses a convolution with measured impulse responses from human subjects.\n     */\n    public abstract panningModel: \"equalpower\" | \"HRTF\";\n\n    /**\n     * The spatial position. Defaults to (0, 0, 0).\n     */\n    public abstract position: Vector3;\n\n    /**\n     * How quickly the volume is reduced as the source moves away from the listener. Defaults to 1.\n     * - This value is used by all distance models.\n     * @see {@link distanceModel}\n     */\n    public abstract rolloffFactor: number;\n\n    /**\n     * The spatial rotation used to determine the direction of the audio source. Defaults to (0, 0, 0).\n     */\n    public abstract rotation: Vector3;\n\n    /**\n     * The spatial rotation quaternion used to determine the direction of the audio source. Defaults to (0, 0, 0, 1).\n     */\n    public abstract rotationQuaternion: Quaternion;\n\n    /**\n     * Attaches to a scene node.\n     *\n     * Detaches automatically before attaching to the given scene node.\n     * If `sceneNode` is `null` it is the same as calling `detach()`.\n     *\n     * @param sceneNode The scene node to attach to, or `null` to detach.\n     * @param useBoundingBox Whether to use the bounding box of the node for positioning. Defaults to `false`.\n     * @param attachmentType Whether to attach to the node's position and/or rotation. Defaults to `PositionAndRotation`.\n     */\n    public abstract attach(sceneNode: Nullable<Node>, useBoundingBox?: boolean, attachmentType?: SpatialAudioAttachmentType): void;\n\n    /**\n     * Detaches from the scene node if attached.\n     */\n    public abstract detach(): void;\n\n    /**\n     * Updates the position and rotation of the associated audio engine object in the audio rendering graph.\n     *\n     * This is called automatically by default and only needs to be called manually if automatic updates are disabled.\n     */\n    public abstract update(): void;\n\n    /**\n     * Releases associated resources.\n     */\n    public abstract dispose(): void;\n}\n","import { AudioNodeType, AbstractNamedAudioNode } from \"../abstractAudioNode\";\nimport { type AudioEngineV2 } from \"../audioEngineV2\";\n\n/** @internal */\nexport abstract class _AbstractAudioSubNode extends AbstractNamedAudioNode {\n    /** @internal */\n    protected constructor(name: string, engine: AudioEngineV2) {\n        super(name, engine, AudioNodeType.HAS_INPUTS_AND_OUTPUTS);\n    }\n\n    /** @internal */\n    public connect(node: _AbstractAudioSubNode): void {\n        if (!this._connect(node)) {\n            throw new Error(\"Connect failed\");\n        }\n    }\n\n    /** @internal */\n    public disconnect(node: _AbstractAudioSubNode): void {\n        if (!this._disconnect(node)) {\n            throw new Error(\"Disconnect failed\");\n        }\n    }\n\n    /** @internal */\n    public disconnectAll(): void {\n        if (!this._downstreamNodes) {\n            throw new Error(\"Disconnect failed\");\n        }\n\n        const it = this._downstreamNodes.values();\n\n        for (let next = it.next(); !next.done; next = it.next()) {\n            if (!this._disconnect(next.value)) {\n                throw new Error(\"Disconnect failed\");\n            }\n        }\n    }\n}\n","import { type Nullable } from \"../../../types\";\nimport { type IAudioParameterRampOptions, AudioParameterRampShape } from \"../../audioParameter\";\nimport { type AudioEngineV2 } from \"../audioEngineV2\";\nimport { _AbstractAudioSubNode } from \"../subNodes/abstractAudioSubNode\";\nimport { AudioSubNode } from \"../subNodes/audioSubNode\";\nimport { type _AbstractAudioSubGraph } from \"./abstractAudioSubGraph\";\n\n/** @internal */\nexport const _VolumeAudioDefaults = {\n    volume: 1 as number,\n} as const;\n\n/**\n * Volume options.\n */\nexport interface IVolumeAudioOptions {\n    /**\n     * The volume/gain. Defaults to 1.\n     */\n    volume: number;\n}\n\n/** @internal */\nexport abstract class _VolumeAudioSubNode extends _AbstractAudioSubNode {\n    protected constructor(engine: AudioEngineV2) {\n        super(AudioSubNode.VOLUME, engine);\n    }\n\n    public abstract volume: number;\n\n    /** @internal */\n    public setOptions(options: Partial<IVolumeAudioOptions>): void {\n        this.setVolume(options.volume ?? _VolumeAudioDefaults.volume, { shape: AudioParameterRampShape.None });\n    }\n\n    /** @internal */\n    public abstract setVolume(value: number, options?: Nullable<Partial<IAudioParameterRampOptions>>): void;\n}\n\n/** @internal */\nexport function _GetVolumeAudioSubNode(subGraph: _AbstractAudioSubGraph): Nullable<_VolumeAudioSubNode> {\n    return subGraph.getSubNode<_VolumeAudioSubNode>(AudioSubNode.VOLUME);\n}\n\n/** @internal */\nexport function _GetVolumeAudioProperty<K extends keyof typeof _VolumeAudioDefaults>(subGraph: _AbstractAudioSubGraph, property: K): (typeof _VolumeAudioDefaults)[K] {\n    return _GetVolumeAudioSubNode(subGraph)?.[property] ?? _VolumeAudioDefaults[property];\n}\n","// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type AudioAnalyzerFFTSizeType = 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768;\n\nexport const _AudioAnalyzerDefaults = {\n    fftSize: 2048 as AudioAnalyzerFFTSizeType,\n    minDecibels: -100 as number,\n    maxDecibels: -30 as number,\n    smoothing: 0.8 as number,\n} as const;\n\nlet EmptyByteTimeDomainData: Uint8Array | undefined;\nlet EmptyFloatTimeDomainData: Float32Array | undefined;\n\n/**\n * Options for the AudioAnalyzer\n */\nexport interface IAudioAnalyzerOptions {\n    /**\n     * Enable the audio analyzer. Defaults to false.\n     */\n    analyzerEnabled: boolean;\n    /**\n     * The size of the FFT (fast fourier transform) to use when converting time-domain data to frequency-domain data. Default is 2048.\n     */\n    analyzerFFTSize: AudioAnalyzerFFTSizeType;\n\n    /**\n     * The minimum decibel value for the range of the analyzer. Default is -100.\n     */\n    analyzerMinDecibels: number;\n\n    /**\n     * The maximum decibel value for the range of the analyzer. Default is -30.\n     */\n    analyzerMaxDecibels: number;\n\n    /**\n     * A number between 0 and 1 that determines how quickly the analyzer's value changes. Default is 0.8.\n     */\n    analyzerSmoothing: number;\n}\n\n/**\n * @param options The audio analyzer options to check.\n * @returns `true` if audio analyzer options are defined, otherwise `false`.\n */\nexport function _HasAudioAnalyzerOptions(options: Partial<IAudioAnalyzerOptions>): boolean {\n    return (\n        options.analyzerEnabled ||\n        options.analyzerFFTSize !== undefined ||\n        options.analyzerMinDecibels !== undefined ||\n        options.analyzerMaxDecibels !== undefined ||\n        options.analyzerSmoothing !== undefined\n    );\n}\n\n/**\n * An AudioAnalyzer converts time-domain audio data into the frequency-domain.\n */\nexport abstract class AbstractAudioAnalyzer {\n    /**\n     * The size of the FFT (fast fourier transform) to use when converting time-domain data to frequency-domain data. Default is 2048.\n     */\n    public abstract fftSize: AudioAnalyzerFFTSizeType;\n\n    /**\n     * The number of data values that will be returned when calling getByteFrequencyData() or getFloatFrequencyData(). This is always half the `fftSize`.\n     */\n    public get frequencyBinCount(): number {\n        return this.fftSize / 2;\n    }\n\n    /**\n     * Whether the analyzer is enabled or not.\n     * - The data retrieval functions return an empty array if the analyzer is not enabled.\n     * @see {@link enableAsync}\n     */\n    public abstract isEnabled: boolean;\n\n    /**\n     * The minimum decibel value for the range of the analyzer. Default is -100.\n     */\n    public abstract minDecibels: number;\n\n    /**\n     * The maximum decibel value for the range of the analyzer. Default is -30.\n     */\n    public abstract maxDecibels: number;\n\n    /**\n     * A number between 0 and 1 that determines how quickly the analyzer's value changes. Default is 0.8.\n     */\n    public abstract smoothing: number;\n\n    /**\n     * Releases associated resources.\n     */\n    public abstract dispose(): void;\n\n    /**\n     * Enables the analyzer\n     */\n    public abstract enableAsync(): Promise<void>;\n\n    /**\n     * Gets the current frequency data as a byte array\n     * @returns a Uint8Array if the analyzer is enabled, otherwise an empty array\n     */\n    public abstract getByteFrequencyData(): Uint8Array;\n\n    /**\n     * Gets the current waveform data as a byte array\n     * @returns a Uint8Array with length `fftSize` if the analyzer is enabled, otherwise an empty array\n     */\n    public getByteTimeDomainData(): Uint8Array {\n        return (EmptyByteTimeDomainData ??= new Uint8Array());\n    }\n\n    /**\n     * Gets the current frequency data as a float array\n     * @returns a Float32Array if the analyzer is enabled, otherwise an empty array\n     */\n    public abstract getFloatFrequencyData(): Float32Array;\n\n    /**\n     * Gets the current waveform data as a float array\n     * @returns a Float32Array with length `fftSize` if the analyzer is enabled, otherwise an empty array\n     */\n    public getFloatTimeDomainData(): Float32Array {\n        return (EmptyFloatTimeDomainData ??= new Float32Array());\n    }\n}\n","import { type Nullable } from \"../../../types\";\nimport { type AudioEngineV2 } from \"../audioEngineV2\";\nimport { type AudioAnalyzerFFTSizeType, type IAudioAnalyzerOptions, _AudioAnalyzerDefaults } from \"../subProperties/abstractAudioAnalyzer\";\nimport { type _AbstractAudioSubGraph } from \"./abstractAudioSubGraph\";\nimport { _AbstractAudioSubNode } from \"./abstractAudioSubNode\";\nimport { AudioSubNode } from \"./audioSubNode\";\n\n/** @internal */\nexport abstract class _AudioAnalyzerSubNode extends _AbstractAudioSubNode {\n    protected constructor(engine: AudioEngineV2) {\n        super(AudioSubNode.ANALYZER, engine);\n    }\n\n    public abstract fftSize: AudioAnalyzerFFTSizeType;\n    public abstract minDecibels: number;\n    public abstract maxDecibels: number;\n    public abstract smoothing: number;\n\n    public abstract getByteFrequencyData(): Uint8Array;\n    public abstract getByteTimeDomainData(): Uint8Array;\n    public abstract getFloatFrequencyData(): Float32Array;\n    public abstract getFloatTimeDomainData(): Float32Array;\n\n    /** @internal */\n    public setOptions(options: Partial<IAudioAnalyzerOptions>): void {\n        this.fftSize = options.analyzerFFTSize ?? _AudioAnalyzerDefaults.fftSize;\n        this.minDecibels = options.analyzerMinDecibels ?? _AudioAnalyzerDefaults.minDecibels;\n        this.maxDecibels = options.analyzerMaxDecibels ?? _AudioAnalyzerDefaults.maxDecibels;\n        this.smoothing = options.analyzerSmoothing ?? _AudioAnalyzerDefaults.smoothing;\n    }\n}\n\n/** @internal */\nexport function _GetAudioAnalyzerSubNode(subGraph: _AbstractAudioSubGraph): Nullable<_AudioAnalyzerSubNode> {\n    return subGraph.getSubNode<_AudioAnalyzerSubNode>(AudioSubNode.ANALYZER);\n}\n\n/** @internal */\nexport function _SetAudioAnalyzerProperty<K extends keyof typeof _AudioAnalyzerDefaults>(subGraph: _AbstractAudioSubGraph, property: K, value: _AudioAnalyzerSubNode[K]): void {\n    subGraph.callOnSubNode<_AudioAnalyzerSubNode>(AudioSubNode.ANALYZER, (node) => {\n        node[property] = value;\n    });\n}\n","import { Logger } from \"../../../Misc/logger\";\nimport { type Nullable } from \"../../../types\";\nimport { type AudioAnalyzerFFTSizeType, _AudioAnalyzerDefaults, AbstractAudioAnalyzer } from \"../../abstractAudio/subProperties/abstractAudioAnalyzer\";\nimport { type _AbstractAudioSubGraph } from \"../subNodes/abstractAudioSubGraph\";\nimport { _GetAudioAnalyzerSubNode, _SetAudioAnalyzerProperty } from \"../subNodes/audioAnalyzerSubNode\";\nimport { AudioSubNode } from \"../subNodes/audioSubNode\";\n\nlet EmptyByteFrequencyData: Nullable<Uint8Array> = null;\nlet EmptyFloatFrequencyData: Nullable<Float32Array> = null;\n\n/** @internal */\nexport function _GetEmptyByteFrequencyData(): Uint8Array {\n    if (!EmptyByteFrequencyData) {\n        EmptyByteFrequencyData = new Uint8Array();\n    }\n    return EmptyByteFrequencyData;\n}\n\n/** @internal */\nexport function _GetEmptyFloatFrequencyData(): Float32Array {\n    if (!EmptyFloatFrequencyData) {\n        EmptyFloatFrequencyData = new Float32Array();\n    }\n    return EmptyFloatFrequencyData;\n}\n\n/** @internal */\nexport class _AudioAnalyzer extends AbstractAudioAnalyzer {\n    private _fftSize: AudioAnalyzerFFTSizeType = _AudioAnalyzerDefaults.fftSize;\n    private _maxDecibels: number = _AudioAnalyzerDefaults.maxDecibels;\n    private _minDecibels: number = _AudioAnalyzerDefaults.minDecibels;\n    private _smoothing: number = _AudioAnalyzerDefaults.smoothing;\n    private _subGraph: _AbstractAudioSubGraph;\n\n    /** @internal */\n    public constructor(subGraph: _AbstractAudioSubGraph) {\n        super();\n        this._subGraph = subGraph;\n    }\n\n    /** @internal */\n    public get fftSize(): AudioAnalyzerFFTSizeType {\n        return this._fftSize;\n    }\n\n    public set fftSize(value: AudioAnalyzerFFTSizeType) {\n        this._fftSize = value;\n        _SetAudioAnalyzerProperty(this._subGraph, \"fftSize\", value);\n    }\n\n    /** @internal */\n    public get isEnabled(): boolean {\n        return _GetAudioAnalyzerSubNode(this._subGraph) !== null;\n    }\n\n    /** @internal */\n    public get minDecibels(): number {\n        return this._minDecibels;\n    }\n\n    public set minDecibels(value: number) {\n        this._minDecibels = value;\n        _SetAudioAnalyzerProperty(this._subGraph, \"minDecibels\", value);\n    }\n\n    /** @internal */\n    public get maxDecibels(): number {\n        return this._maxDecibels;\n    }\n\n    public set maxDecibels(value: number) {\n        this._maxDecibels = value;\n        _SetAudioAnalyzerProperty(this._subGraph, \"maxDecibels\", value);\n    }\n\n    /** @internal */\n    public get smoothing(): number {\n        return this._smoothing;\n    }\n\n    public set smoothing(value: number) {\n        this._smoothing = value;\n        _SetAudioAnalyzerProperty(this._subGraph, \"smoothing\", value);\n    }\n\n    /** @internal */\n    public dispose(): void {\n        const subNode = _GetAudioAnalyzerSubNode(this._subGraph);\n        if (subNode) {\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this._subGraph.removeSubNodeAsync(subNode);\n            subNode.dispose();\n        }\n    }\n\n    /** @internal */\n    public async enableAsync(): Promise<void> {\n        const subNode = _GetAudioAnalyzerSubNode(this._subGraph);\n        if (!subNode) {\n            await this._subGraph.createAndAddSubNodeAsync(AudioSubNode.ANALYZER);\n        }\n    }\n\n    /** @internal */\n    public getByteFrequencyData(): Uint8Array {\n        const subNode = _GetAudioAnalyzerSubNode(this._subGraph);\n        if (!subNode) {\n            Logger.Warn(\"AudioAnalyzer not enabled\");\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this.enableAsync();\n            return _GetEmptyByteFrequencyData();\n        }\n        return subNode.getByteFrequencyData();\n    }\n\n    /** @internal */\n    public override getByteTimeDomainData(): Uint8Array {\n        const subNode = _GetAudioAnalyzerSubNode(this._subGraph);\n        if (!subNode) {\n            Logger.Warn(\"AudioAnalyzer not enabled\");\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this.enableAsync();\n            return super.getByteTimeDomainData();\n        }\n        return subNode.getByteTimeDomainData();\n    }\n\n    /** @internal */\n    public getFloatFrequencyData(): Float32Array {\n        const subNode = _GetAudioAnalyzerSubNode(this._subGraph);\n        if (!subNode) {\n            Logger.Warn(\"AudioAnalyzer not enabled\");\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this.enableAsync();\n            return _GetEmptyFloatFrequencyData();\n        }\n        return subNode.getFloatFrequencyData();\n    }\n\n    /** @internal */\n    public override getFloatTimeDomainData(): Float32Array {\n        const subNode = _GetAudioAnalyzerSubNode(this._subGraph);\n        if (!subNode) {\n            Logger.Warn(\"AudioAnalyzer not enabled\");\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this.enableAsync();\n            return super.getFloatTimeDomainData();\n        }\n        return subNode.getFloatTimeDomainData();\n    }\n}\n","import { type Nullable } from \"../../types\";\nimport { type IAudioParameterRampOptions } from \"../audioParameter\";\nimport { type AudioNodeType, AbstractNamedAudioNode } from \"./abstractAudioNode\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\nimport { type _AbstractAudioSubGraph } from \"./subNodes/abstractAudioSubGraph\";\nimport { type IVolumeAudioOptions, _GetVolumeAudioProperty, _GetVolumeAudioSubNode } from \"./subNodes/volumeAudioSubNode\";\nimport { type AbstractAudioAnalyzer, type IAudioAnalyzerOptions } from \"./subProperties/abstractAudioAnalyzer\";\nimport { _AudioAnalyzer } from \"./subProperties/audioAnalyzer\";\n\n/** @internal */\nexport interface IAbstractAudioOutNodeOptions extends IAudioAnalyzerOptions, IVolumeAudioOptions {}\n\n/**\n * Abstract class representing and audio output node with an analyzer and volume control.\n */\nexport abstract class AbstractAudioOutNode extends AbstractNamedAudioNode {\n    private _analyzer: Nullable<AbstractAudioAnalyzer> = null;\n\n    protected abstract _subGraph: _AbstractAudioSubGraph;\n\n    protected constructor(name: string, engine: AudioEngineV2, nodeType: AudioNodeType) {\n        super(name, engine, nodeType);\n    }\n\n    /**\n     * The audio analyzer features.\n     */\n    public get analyzer(): AbstractAudioAnalyzer {\n        return this._analyzer ?? (this._analyzer = new _AudioAnalyzer(this._subGraph));\n    }\n\n    /**\n     * The audio output volume.\n     */\n    public get volume(): number {\n        return _GetVolumeAudioProperty(this._subGraph, \"volume\");\n    }\n\n    public set volume(value: number) {\n        // The volume subnode is created on initialization and should always exist.\n        const node = _GetVolumeAudioSubNode(this._subGraph);\n        if (!node) {\n            throw new Error(\"No volume subnode\");\n        }\n\n        node.volume = value;\n    }\n\n    /**\n     * Releases associated resources.\n     */\n    public override dispose(): void {\n        super.dispose();\n\n        this._analyzer?.dispose();\n        this._analyzer = null;\n\n        this._subGraph.dispose();\n    }\n\n    /**\n     * Sets the audio output volume with optional ramping.\n     * If the duration is 0 then the volume is set immediately, otherwise it is ramped to the new value over the given duration using the given shape.\n     * If a ramp is already in progress then the volume is not set and an error is thrown.\n     * @param value The value to set the volume to.\n     * @param options The options to use for ramping the volume change.\n     */\n    public setVolume(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n        const node = _GetVolumeAudioSubNode(this._subGraph);\n        if (!node) {\n            throw new Error(\"No volume subnode\");\n        }\n\n        node.setVolume(value, options);\n    }\n}\n","import { type Nullable } from \"../../types\";\nimport { AudioNodeType } from \"./abstractAudioNode\";\nimport { type IAbstractAudioOutNodeOptions, AbstractAudioOutNode } from \"./abstractAudioOutNode\";\nimport { type PrimaryAudioBus } from \"./audioBus\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\nimport { type AbstractSpatialAudio, type ISpatialAudioOptions } from \"./subProperties/abstractSpatialAudio\";\nimport { type AbstractStereoAudio, type IStereoAudioOptions } from \"./subProperties/abstractStereoAudio\";\n\n/**\n * Options for creating a sound source.\n */\nexport interface ISoundSourceOptions extends IAbstractAudioOutNodeOptions, ISpatialAudioOptions, IStereoAudioOptions {\n    /**\n     * The output bus for the sound source. Defaults to `null`.\n     * - If not set or `null`, and `outBusAutoDefault` is `true`, then the sound source is automatically connected to the audio engine's default main bus.\n     * @see {@link AudioEngineV2.defaultMainBus}\n     */\n    outBus: Nullable<PrimaryAudioBus>;\n\n    /**\n     * Whether the sound's `outBus` should default to the audio engine's main bus. Defaults to `true` for all sound sources except microphones.\n     */\n    outBusAutoDefault: boolean;\n\n    /**\n     * Whether a `MediaStream`-backed sound source (for example, a `MediaStreamAudioSourceNode` created from a remote\n     * WebRTC stream) is automatically kept audible by attaching its `MediaStream` to a hidden, muted `HTMLAudioElement`.\n     * Defaults to `true`.\n     *\n     * Some browsers (notably Chromium) only deliver audio samples from a `MediaStreamAudioSourceNode` while the\n     * underlying `MediaStream` is also being pulled by an `HTMLMediaElement`. Without this, a remote WebRTC stream routed\n     * through the Web Audio graph is silent and therefore cannot be heard or spatialized. The attached element is muted\n     * so it does not add a second, non-spatial playback of the stream.\n     *\n     * Set this to `false` if you are already routing the same `MediaStream` through your own `HTMLMediaElement`, to avoid\n     * creating a redundant one. Has no effect for sources that are not backed by a `MediaStreamAudioSourceNode`.\n     */\n    mediaStreamSinkEnabled: boolean;\n\n    /**\n     * Whether disposing the sound source stops the tracks of its backing `MediaStream` (via `MediaStreamTrack.stop()`).\n     * Defaults to `false`.\n     *\n     * When the `MediaStream` is owned by the caller (for example, a remote WebRTC stream), stopping its tracks on dispose\n     * would permanently end them and could not be resumed without renegotiation, so the sound source leaves the stream\n     * lifecycle to the caller by default. The microphone source enables this so it releases the capture device it owns.\n     *\n     * Set this to `true` if the sound source should own and stop the stream's tracks when disposed. Has no effect for\n     * sources that are not backed by a `MediaStreamAudioSourceNode`.\n     */\n    stopMediaStreamTracksOnDispose: boolean;\n}\n\n/**\n * Abstract class representing a sound in the audio engine.\n */\nexport abstract class AbstractSoundSource extends AbstractAudioOutNode {\n    private readonly _spatialAutoUpdate: boolean = true;\n    private readonly _spatialMinUpdateTime: number = 0;\n    private _outBus: Nullable<PrimaryAudioBus> = null;\n    private _spatial: Nullable<AbstractSpatialAudio> = null;\n\n    protected constructor(name: string, engine: AudioEngineV2, options: Partial<ISoundSourceOptions>, nodeType: AudioNodeType = AudioNodeType.HAS_OUTPUTS) {\n        super(name, engine, nodeType);\n\n        if (typeof options.spatialAutoUpdate === \"boolean\") {\n            this._spatialAutoUpdate = options.spatialAutoUpdate;\n        }\n\n        if (typeof options.spatialMinUpdateTime === \"number\") {\n            this._spatialMinUpdateTime = options.spatialMinUpdateTime;\n        }\n    }\n\n    /**\n     * The output bus for the sound.\n     * @see {@link AudioEngineV2.defaultMainBus}\n     */\n    public get outBus(): Nullable<PrimaryAudioBus> {\n        return this._outBus;\n    }\n\n    public set outBus(outBus: Nullable<PrimaryAudioBus>) {\n        if (this._outBus === outBus) {\n            return;\n        }\n\n        if (this._outBus) {\n            if (this._onOutBusDisposed) {\n                this._outBus.onDisposeObservable.removeCallback(this._onOutBusDisposed);\n                this._onOutBusDisposed = null;\n            }\n            if (!this._disconnect(this._outBus)) {\n                throw new Error(\"Disconnect failed\");\n            }\n        }\n\n        this._outBus = outBus;\n\n        if (this._outBus) {\n            this._onOutBusDisposed = () => {\n                this._outBus = null;\n            };\n            this._outBus.onDisposeObservable.add(this._onOutBusDisposed);\n            if (!this._connect(this._outBus)) {\n                throw new Error(\"Connect failed\");\n            }\n        }\n    }\n\n    /**\n     * The spatial audio features.\n     */\n    public get spatial(): AbstractSpatialAudio {\n        if (this._spatial) {\n            return this._spatial;\n        }\n        return this._initSpatialProperty();\n    }\n\n    /**\n     * The stereo features of the sound.\n     */\n    public abstract stereo: AbstractStereoAudio;\n\n    /**\n     * Releases associated resources.\n     */\n    public override dispose(): void {\n        super.dispose();\n\n        this._spatial?.dispose();\n        this._spatial = null;\n\n        if (this._outBus && this._onOutBusDisposed) {\n            this._outBus.onDisposeObservable.removeCallback(this._onOutBusDisposed);\n            this._onOutBusDisposed = null;\n        }\n        this._outBus = null;\n    }\n\n    protected abstract _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio;\n\n    protected _initSpatialProperty(): AbstractSpatialAudio {\n        return (this._spatial = this._createSpatialProperty(this._spatialAutoUpdate, this._spatialMinUpdateTime));\n    }\n\n    private _onOutBusDisposed: Nullable<() => void> = null;\n\n    /** @internal */\n    public get _isSpatial(): boolean {\n        return this._spatial !== null;\n    }\n\n    public set _isSpatial(value: boolean) {\n        if (value && !this._spatial) {\n            this._initSpatialProperty();\n        } else if (!value && this._spatial) {\n            this._spatial.dispose();\n            this._spatial = null;\n        }\n    }\n}\n","export const _StereoAudioDefaults = {\n    pan: 0 as number,\n} as const;\n\n/** */\nexport interface IStereoAudioOptions {\n    /**\n     * Enable stereo. Defaults to false.\n     *\n     * When set to `true`, the audio node's stereo properties will be initialized on creation and there will be no\n     * delay when setting the first stereo value.\n     *\n     * When not specified, or set to `false`, the audio node's stereo properties will not be initialized on creation\n     * and there will be a small delay when setting the first stereo value.\n     *\n     * - This option is ignored if any other stereo options are set.\n     */\n    stereoEnabled: boolean;\n    /**\n     * The stereo pan from -1 (left) to 1 (right). Defaults to 0.\n     */\n    stereoPan: number;\n}\n\n/**\n * @param options The stereo audio options to check.\n * @returns `true` if stereo audio options are defined, otherwise `false`.\n */\nexport function _HasStereoAudioOptions(options: Partial<IStereoAudioOptions>): boolean {\n    return options.stereoEnabled || options.stereoPan !== undefined;\n}\n\n/**\n * Abstract class representing the `stereo` audio property on a sound or audio bus.\n *\n * @see {@link AudioEngineV2.listener}\n */\nexport abstract class AbstractStereoAudio {\n    /**\n     * The stereo pan from -1 (left) to 1 (right). Defaults to 0.\n     */\n    public abstract pan: number;\n}\n","import { type Nullable } from \"../../../types\";\nimport { type AudioEngineV2 } from \"../../abstractAudio/audioEngineV2\";\nimport { _AbstractAudioSubNode } from \"../../abstractAudio/subNodes/abstractAudioSubNode\";\nimport { AudioSubNode } from \"../../abstractAudio/subNodes/audioSubNode\";\nimport { type IStereoAudioOptions, _StereoAudioDefaults } from \"../../abstractAudio/subProperties/abstractStereoAudio\";\nimport { type _AbstractAudioSubGraph } from \"./abstractAudioSubGraph\";\n\n/** @internal */\nexport abstract class _StereoAudioSubNode extends _AbstractAudioSubNode {\n    protected constructor(engine: AudioEngineV2) {\n        super(AudioSubNode.STEREO, engine);\n    }\n\n    public abstract pan: number;\n\n    /** @internal */\n    public setOptions(options: Partial<IStereoAudioOptions>): void {\n        this.pan = options.stereoPan ?? _StereoAudioDefaults.pan;\n    }\n}\n\n/** @internal */\nexport function _GetStereoAudioSubNode(subGraph: _AbstractAudioSubGraph): Nullable<_StereoAudioSubNode> {\n    return subGraph.getSubNode<_StereoAudioSubNode>(AudioSubNode.STEREO);\n}\n\n/** @internal */\nexport function _SetStereoAudioProperty<K extends keyof typeof _StereoAudioDefaults>(subGraph: _AbstractAudioSubGraph, property: K, value: _StereoAudioSubNode[K]): void {\n    subGraph.callOnSubNode<_StereoAudioSubNode>(AudioSubNode.STEREO, (node) => {\n        node[property] = value;\n    });\n}\n","import { _StereoAudioDefaults, AbstractStereoAudio } from \"../../abstractAudio/subProperties/abstractStereoAudio\";\nimport { type _AbstractAudioSubGraph } from \"../subNodes/abstractAudioSubGraph\";\nimport { _SetStereoAudioProperty } from \"../subNodes/stereoAudioSubNode\";\n\n/** @internal */\nexport class _StereoAudio extends AbstractStereoAudio {\n    private _pan: number = _StereoAudioDefaults.pan;\n    private _subGraph: _AbstractAudioSubGraph;\n\n    /** @internal */\n    public constructor(subGraph: _AbstractAudioSubGraph) {\n        super();\n        this._subGraph = subGraph;\n    }\n\n    /** @internal */\n    public get pan(): number {\n        return this._pan;\n    }\n\n    public set pan(value: number) {\n        this._pan = value;\n        _SetStereoAudioProperty(this._subGraph, \"pan\", value);\n    }\n}\n","import { type Quaternion, type Vector3 } from \"../../../Maths/math.vector\";\nimport { type Node } from \"../../../node\";\nimport { type Nullable } from \"../../../types\";\nimport { SpatialAudioAttachmentType } from \"../../spatialAudioAttachmentType\";\nimport { type AudioEngineV2 } from \"../audioEngineV2\";\nimport { _SpatialAudioAttacherComponent } from \"../components/spatialAudioAttacherComponent\";\nimport { type ISpatialAudioOptions, _SpatialAudioDefaults } from \"../subProperties/abstractSpatialAudio\";\nimport { type _AbstractAudioSubGraph } from \"./abstractAudioSubGraph\";\nimport { _AbstractAudioSubNode } from \"./abstractAudioSubNode\";\nimport { AudioSubNode } from \"./audioSubNode\";\n\n/** @internal */\nexport abstract class _SpatialAudioSubNode extends _AbstractAudioSubNode {\n    private _attacherComponent: Nullable<_SpatialAudioAttacherComponent> = null;\n\n    protected constructor(engine: AudioEngineV2) {\n        super(AudioSubNode.SPATIAL, engine);\n    }\n\n    public abstract coneInnerAngle: number;\n    public abstract coneOuterAngle: number;\n    public abstract coneOuterVolume: number;\n    public abstract distanceModel: DistanceModelType;\n    public abstract maxDistance: number;\n    public abstract minDistance: number;\n    public abstract orientation: Vector3;\n    public abstract panningEnabled: boolean;\n    public abstract panningModel: PanningModelType;\n    public abstract position: Vector3;\n    public abstract rolloffFactor: number;\n    public abstract rotation: Vector3;\n    public abstract rotationQuaternion: Quaternion;\n    public abstract _inNode: AudioNode;\n\n    /** @internal */\n    public get isAttached(): boolean {\n        return this._attacherComponent !== null && this._attacherComponent.isAttached;\n    }\n\n    /** @internal */\n    public get attachedNode(): Nullable<Node> {\n        return this._attacherComponent?.sceneNode ?? null;\n    }\n\n    /** @internal */\n    public get useBoundingBox(): boolean {\n        return this._attacherComponent?.useBoundingBox ?? false;\n    }\n\n    /** @internal */\n    public get attachmentType(): SpatialAudioAttachmentType {\n        return this._attacherComponent?.attachmentType ?? SpatialAudioAttachmentType.PositionAndRotation;\n    }\n\n    /** @internal */\n    public attach(sceneNode: Nullable<Node>, useBoundingBox: boolean, attachmentType: SpatialAudioAttachmentType): void {\n        this.detach();\n\n        if (!this._attacherComponent) {\n            this._attacherComponent = new _SpatialAudioAttacherComponent(this);\n        }\n\n        this._attacherComponent.attach(sceneNode, useBoundingBox, attachmentType);\n    }\n\n    /** @internal */\n    public detach(): void {\n        this._attacherComponent?.detach();\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._attacherComponent?.dispose();\n        this._attacherComponent = null;\n    }\n\n    /** @internal */\n    public setOptions(options: Partial<ISpatialAudioOptions>): void {\n        this.coneInnerAngle = options.spatialConeInnerAngle ?? _SpatialAudioDefaults.coneInnerAngle;\n        this.coneOuterAngle = options.spatialConeOuterAngle ?? _SpatialAudioDefaults.coneOuterAngle;\n        this.coneOuterVolume = options.spatialConeOuterVolume ?? _SpatialAudioDefaults.coneOuterVolume;\n        this.distanceModel = options.spatialDistanceModel ?? _SpatialAudioDefaults.distanceModel;\n        this.maxDistance = options.spatialMaxDistance ?? _SpatialAudioDefaults.maxDistance;\n        this.minDistance = options.spatialMinDistance ?? _SpatialAudioDefaults.minDistance;\n        this.orientation = options.spatialOrientation ?? _SpatialAudioDefaults.orientation;\n        this.panningEnabled = options.spatialPanningEnabled ?? _SpatialAudioDefaults.panningEnabled;\n        this.panningModel = options.spatialPanningModel ?? _SpatialAudioDefaults.panningModel;\n        this.rolloffFactor = options.spatialRolloffFactor ?? _SpatialAudioDefaults.rolloffFactor;\n\n        if (options.spatialPosition) {\n            this.position = options.spatialPosition.clone();\n        }\n\n        if (options.spatialRotationQuaternion) {\n            this.rotationQuaternion = options.spatialRotationQuaternion.clone();\n        } else if (options.spatialRotation) {\n            this.rotation = options.spatialRotation.clone();\n        } else {\n            this.rotationQuaternion = _SpatialAudioDefaults.rotationQuaternion.clone();\n        }\n\n        this.update();\n    }\n\n    /** @internal */\n    public update(): void {\n        if (this.isAttached) {\n            this._attacherComponent?.update();\n        } else {\n            this._updatePosition();\n            this._updateRotation();\n        }\n    }\n\n    public abstract _updatePosition(): void;\n    public abstract _updateRotation(): void;\n}\n\n/** @internal */\nexport function _GetSpatialAudioSubNode(subGraph: _AbstractAudioSubGraph): Nullable<_SpatialAudioSubNode> {\n    return subGraph.getSubNode<_SpatialAudioSubNode>(AudioSubNode.SPATIAL);\n}\n\n/** @internal */\nexport function _SetSpatialAudioProperty<K extends keyof typeof _SpatialAudioDefaults>(subGraph: _AbstractAudioSubGraph, property: K, value: _SpatialAudioSubNode[K]): void {\n    subGraph.callOnSubNode<_SpatialAudioSubNode>(AudioSubNode.SPATIAL, (node) => {\n        node[property] = value;\n    });\n}\n","import { Matrix, Quaternion, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { _SpatialAudioSubNode } from \"../../abstractAudio/subNodes/spatialAudioSubNode\";\r\nimport { _SpatialAudioDefaults } from \"../../abstractAudio/subProperties/abstractSpatialAudio\";\r\nimport { _WebAudioParameterComponent } from \"../components/webAudioParameterComponent\";\r\nimport { type _WebAudioEngine } from \"../webAudioEngine\";\r\nimport { type IWebAudioInNode } from \"../webAudioNode\";\r\n\r\nconst TmpMatrix = Matrix.Zero();\r\nconst TmpQuaternion = new Quaternion();\r\n\r\nfunction D2r(degrees: number): number {\r\n    return (degrees * Math.PI) / 180;\r\n}\r\n\r\nfunction R2d(radians: number): number {\r\n    return (radians * 180) / Math.PI;\r\n}\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/require-await\r\nexport async function _CreateSpatialAudioSubNodeAsync(engine: _WebAudioEngine): Promise<_SpatialAudioSubNode> {\r\n    return new _SpatialWebAudioSubNode(engine);\r\n}\r\n\r\n/** @internal */\r\nexport class _SpatialWebAudioSubNode extends _SpatialAudioSubNode {\r\n    private _attenuation: _WebAudioParameterComponent;\r\n    private readonly _attenuationNode: GainNode;\r\n    private readonly _inputNode: GainNode;\r\n    private _lastOrientation: Vector3 = Vector3.Zero();\r\n    private _lastPosition: Vector3 = Vector3.Zero();\r\n    private _lastRotation: Vector3 = Vector3.Zero();\r\n    private _lastRotationQuaternion: Quaternion = new Quaternion();\r\n    private _orientationX: _WebAudioParameterComponent;\r\n    private _orientationY: _WebAudioParameterComponent;\r\n    private _orientationZ: _WebAudioParameterComponent;\r\n    private _panningEnabled = _SpatialAudioDefaults.panningEnabled;\r\n    private _positionX: _WebAudioParameterComponent;\r\n    private _positionY: _WebAudioParameterComponent;\r\n    private _positionZ: _WebAudioParameterComponent;\r\n\r\n    /** @internal */\r\n    public override readonly engine: _WebAudioEngine;\r\n\r\n    /** @internal */\r\n    public readonly orientation: Vector3 = _SpatialAudioDefaults.orientation.clone();\r\n    /** @internal */\r\n    public readonly position = _SpatialAudioDefaults.position.clone();\r\n    /** @internal */\r\n    public readonly rotation: Vector3 = _SpatialAudioDefaults.rotation.clone();\r\n    /** @internal */\r\n    public readonly rotationQuaternion: Quaternion = _SpatialAudioDefaults.rotationQuaternion.clone();\r\n\r\n    /** @internal */\r\n    public readonly node: PannerNode;\r\n\r\n    /** @internal */\r\n    public constructor(engine: _WebAudioEngine) {\r\n        super(engine);\r\n\r\n        this._inputNode = new GainNode(engine._audioContext);\r\n        this._attenuationNode = new GainNode(engine._audioContext);\r\n        this._attenuation = new _WebAudioParameterComponent(engine, this._attenuationNode.gain);\r\n        this.node = new PannerNode(engine._audioContext);\r\n\r\n        this._orientationX = new _WebAudioParameterComponent(engine, this.node.orientationX);\r\n        this._orientationY = new _WebAudioParameterComponent(engine, this.node.orientationY);\r\n        this._orientationZ = new _WebAudioParameterComponent(engine, this.node.orientationZ);\r\n\r\n        this._positionX = new _WebAudioParameterComponent(engine, this.node.positionX);\r\n        this._positionY = new _WebAudioParameterComponent(engine, this.node.positionY);\r\n        this._positionZ = new _WebAudioParameterComponent(engine, this.node.positionZ);\r\n\r\n        this._connectActiveInput();\r\n    }\r\n\r\n    /** @internal */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        this._attenuation.dispose();\r\n        this._orientationX.dispose();\r\n        this._orientationY.dispose();\r\n        this._orientationZ.dispose();\r\n        this._positionX.dispose();\r\n        this._positionY.dispose();\r\n        this._positionZ.dispose();\r\n\r\n        this._inputNode.disconnect();\r\n        this._attenuationNode.disconnect();\r\n        this.node.disconnect();\r\n    }\r\n\r\n    /** @internal */\r\n    public get coneInnerAngle(): number {\r\n        return D2r(this.node.coneInnerAngle);\r\n    }\r\n\r\n    public set coneInnerAngle(value: number) {\r\n        this.node.coneInnerAngle = R2d(value);\r\n    }\r\n\r\n    /** @internal */\r\n    public get coneOuterAngle(): number {\r\n        return D2r(this.node.coneOuterAngle);\r\n    }\r\n\r\n    public set coneOuterAngle(value: number) {\r\n        this.node.coneOuterAngle = R2d(value);\r\n    }\r\n\r\n    /** @internal */\r\n    public get coneOuterVolume(): number {\r\n        return this.node.coneOuterGain;\r\n    }\r\n\r\n    public set coneOuterVolume(value: number) {\r\n        this.node.coneOuterGain = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public get distanceModel(): \"linear\" | \"inverse\" | \"exponential\" {\r\n        return this.node.distanceModel;\r\n    }\r\n\r\n    public set distanceModel(value: \"linear\" | \"inverse\" | \"exponential\") {\r\n        this.node.distanceModel = value;\r\n\r\n        // Wiggle the max distance to make the change take effect.\r\n        const maxDistance = this.node.maxDistance;\r\n        this.node.maxDistance = maxDistance + 0.001;\r\n        this.node.maxDistance = maxDistance;\r\n\r\n        this._updateAttenuation();\r\n    }\r\n\r\n    /** @internal */\r\n    public get minDistance(): number {\r\n        return this.node.refDistance;\r\n    }\r\n\r\n    public set minDistance(value: number) {\r\n        this.node.refDistance = value;\r\n        this._updateAttenuation();\r\n    }\r\n\r\n    /** @internal */\r\n    public get maxDistance(): number {\r\n        return this.node.maxDistance;\r\n    }\r\n\r\n    public set maxDistance(value: number) {\r\n        this.node.maxDistance = value;\r\n        this._updateAttenuation();\r\n    }\r\n\r\n    /** @internal */\r\n    public get panningEnabled(): boolean {\r\n        return this._panningEnabled;\r\n    }\r\n\r\n    public set panningEnabled(value: boolean) {\r\n        if (this._panningEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._panningEnabled = value;\r\n        this._connectActiveInput();\r\n        this._updateAttenuation();\r\n    }\r\n\r\n    /** @internal */\r\n    public get panningModel(): \"equalpower\" | \"HRTF\" {\r\n        return this.node.panningModel;\r\n    }\r\n\r\n    public set panningModel(value: \"equalpower\" | \"HRTF\") {\r\n        this.node.panningModel = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public get rolloffFactor(): number {\r\n        return this.node.rolloffFactor;\r\n    }\r\n\r\n    public set rolloffFactor(value: number) {\r\n        this.node.rolloffFactor = value;\r\n        this._updateAttenuation();\r\n    }\r\n\r\n    /** @internal */\r\n    public get _inNode(): AudioNode {\r\n        return this._inputNode;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _outNode(): AudioNode {\r\n        return this._panningEnabled ? this.node : this._attenuationNode;\r\n    }\r\n\r\n    /** @internal */\r\n    public _updatePosition(): void {\r\n        if (this._lastPosition.equalsWithEpsilon(this.position)) {\r\n            this._updateAttenuation();\r\n            return;\r\n        }\r\n\r\n        this._positionX.targetValue = this.position.x;\r\n        this._positionY.targetValue = this.position.y;\r\n        this._positionZ.targetValue = this.position.z;\r\n\r\n        this._lastPosition.copyFrom(this.position);\r\n        this._updateAttenuation();\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateRotation(): void {\r\n        let rotated = false;\r\n        if (!this._lastRotationQuaternion.equalsWithEpsilon(this.rotationQuaternion)) {\r\n            TmpQuaternion.copyFrom(this.rotationQuaternion);\r\n            this._lastRotationQuaternion.copyFrom(this.rotationQuaternion);\r\n            rotated = true;\r\n        } else if (!this._lastRotation.equalsWithEpsilon(this.rotation)) {\r\n            Quaternion.FromEulerAnglesToRef(this.rotation.x, this.rotation.y, this.rotation.z, TmpQuaternion);\r\n            this._lastRotation.copyFrom(this.rotation);\r\n            rotated = true;\r\n        } else if (this._lastOrientation.equalsWithEpsilon(this.orientation)) {\r\n            return;\r\n        }\r\n\r\n        if (rotated) {\r\n            Matrix.FromQuaternionToRef(TmpQuaternion, TmpMatrix);\r\n            Vector3.TransformNormalToRef(Vector3.RightReadOnly, TmpMatrix, this.orientation);\r\n        }\r\n\r\n        this._orientationX.targetValue = this.orientation.x;\r\n        this._orientationY.targetValue = this.orientation.y;\r\n        this._orientationZ.targetValue = this.orientation.z;\r\n    }\r\n\r\n    protected override _connect(node: IWebAudioInNode): boolean {\r\n        const connected = super._connect(node);\r\n\r\n        if (!connected) {\r\n            return false;\r\n        }\r\n\r\n        // If the wrapped node is not available now, it will be connected later by the subgraph.\r\n        if (node._inNode) {\r\n            this.node.connect(node._inNode);\r\n            this._attenuationNode.connect(node._inNode);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    protected override _disconnect(node: IWebAudioInNode): boolean {\r\n        const disconnected = super._disconnect(node);\r\n\r\n        if (!disconnected) {\r\n            return false;\r\n        }\r\n\r\n        if (node._inNode) {\r\n            this.node.disconnect(node._inNode);\r\n            this._attenuationNode.disconnect(node._inNode);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public getClassName(): string {\r\n        return \"_SpatialWebAudioSubNode\";\r\n    }\r\n\r\n    private _connectActiveInput(): void {\r\n        this._inputNode.disconnect();\r\n\r\n        if (this._panningEnabled) {\r\n            this._inputNode.connect(this.node);\r\n        } else {\r\n            this._inputNode.connect(this._attenuationNode);\r\n        }\r\n    }\r\n\r\n    private _updateAttenuation(): void {\r\n        if (this._panningEnabled) {\r\n            this._attenuation.targetValue = 1;\r\n            return;\r\n        }\r\n\r\n        const listenerPosition = this.engine.listener.position;\r\n        const deltaX = this.position.x - listenerPosition.x;\r\n        const deltaY = this.position.y - listenerPosition.y;\r\n        const deltaZ = this.position.z - listenerPosition.z;\r\n        const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);\r\n        const minDistance = Math.max(this.minDistance, 0);\r\n        let attenuation = 1;\r\n\r\n        switch (this.distanceModel) {\r\n            case \"linear\":\r\n                {\r\n                    const maxDistance = Math.max(this.maxDistance, minDistance);\r\n                    const clampedDistance = Math.min(Math.max(distance, minDistance), maxDistance);\r\n\r\n                    attenuation =\r\n                        maxDistance === minDistance ? (distance <= minDistance ? 1 : 0) : 1 - (this.rolloffFactor * (clampedDistance - minDistance)) / (maxDistance - minDistance);\r\n                }\r\n                break;\r\n            case \"inverse\":\r\n                if (minDistance === 0) {\r\n                    attenuation = 0;\r\n                    break;\r\n                }\r\n\r\n                attenuation = minDistance / (minDistance + this.rolloffFactor * (Math.max(distance, minDistance) - minDistance));\r\n                break;\r\n            case \"exponential\":\r\n                if (minDistance === 0) {\r\n                    attenuation = 0;\r\n                    break;\r\n                }\r\n\r\n                attenuation = Math.pow(Math.max(distance, minDistance) / minDistance, -this.rolloffFactor);\r\n                break;\r\n        }\r\n\r\n        this._attenuation.targetValue = Math.min(Math.max(attenuation, 0), 1);\r\n    }\r\n}\r\n","import { _StereoAudioSubNode } from \"../../abstractAudio/subNodes/stereoAudioSubNode\";\nimport { _WebAudioParameterComponent } from \"../components/webAudioParameterComponent\";\nimport { type _WebAudioEngine } from \"../webAudioEngine\";\nimport { type IWebAudioInNode } from \"../webAudioNode\";\n\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function _CreateStereoAudioSubNodeAsync(engine: _WebAudioEngine): Promise<_StereoAudioSubNode> {\n    return new _StereoWebAudioSubNode(engine);\n}\n\n/** @internal */\nexport class _StereoWebAudioSubNode extends _StereoAudioSubNode {\n    private _pan: _WebAudioParameterComponent;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public readonly node: StereoPannerNode;\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine) {\n        super(engine);\n\n        this.node = new StereoPannerNode(engine._audioContext);\n\n        this._pan = new _WebAudioParameterComponent(engine, this.node.pan);\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._pan.dispose();\n    }\n\n    /** @internal */\n    public get pan(): number {\n        return this._pan.targetValue;\n    }\n\n    /** @internal */\n    public set pan(value: number) {\n        this._pan.targetValue = value;\n    }\n\n    /** @internal */\n    public get _inNode(): AudioNode {\n        return this.node;\n    }\n\n    /** @internal */\n    public get _outNode(): AudioNode {\n        return this.node;\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_StereoWebAudioSubNode\";\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the subgraph.\n        if (node._inNode) {\n            this.node.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this.node.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n}\n","import { type Nullable } from \"../../../types\";\nimport { type AbstractAudioNode, type AbstractNamedAudioNode } from \"../abstractAudioNode\";\nimport { type _AbstractAudioSubNode } from \"./abstractAudioSubNode\";\nimport { type AudioSubNode } from \"./audioSubNode\";\n\n/**\n * Adds common sub graph functionality to an audio node.\n *\n * Audio nodes such as static sounds, streaming sounds, and buses can use audio sub graphs to process audio internally\n * before sending it to connected downstream audio nodes. This is useful for applying effects, spatial audio, and other\n * audio processing tasks common to multiple audio node classes.\n *\n * A key feature of audio sub graphs is their audio sub nodes are created asynchronously on demand so the minimum set\n * of sub nodes are used at all times to save memory and CPU resources. The tradeoff is a small delay when first\n * setting a property backed by a sub node. This delay is avoided by using the appropriate options to initialize the\n * sub node on creation, e.g. `spatialEnabled` and `stereoEnabled`, or by setting any creation option backed by the\n * sub node, e.g. `spatialPosition` and `stereoPan`.\n *\n * @internal\n */\nexport abstract class _AbstractAudioSubGraph {\n    private _createSubNodePromises: { [key: string]: Promise<_AbstractAudioSubNode> } = {};\n    private _isDisposed = false;\n    private _subNodes: { [key: string]: _AbstractAudioSubNode } = {};\n\n    /**\n     * Executes the given callback with the named sub node, creating the sub node if needed.\n     *\n     * @param name The name of the sub node\n     * @param callback The function to call with the named sub node\n     *\n     * @internal\n     */\n    public callOnSubNode<T extends _AbstractAudioSubNode>(name: AudioSubNode, callback: (node: T) => void): void {\n        const node = this.getSubNode(name);\n        if (node) {\n            callback(node as T);\n            return;\n        }\n\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\n        this._createSubNodePromisesResolvedAsync().then(() => {\n            const node = this.getSubNode(name);\n            if (node) {\n                callback(node as T);\n                return;\n            }\n\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\n            this.createAndAddSubNodeAsync(name).then((node) => {\n                callback(node as T);\n            });\n        });\n    }\n\n    /**\n     * Creates the named subnode and adds it to the sub graph.\n     *\n     * @param name The name of the sub node.\n     * @returns A promise that resolves to the created sub node.\n     *\n     * @internal\n     */\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n    public createAndAddSubNodeAsync(name: AudioSubNode): Promise<_AbstractAudioSubNode> {\n        // eslint-disable-next-line github/no-then\n        this._createSubNodePromises[name] ||= this._createSubNode(name).then((node) => {\n            this._addSubNode(node);\n            return node;\n        });\n\n        return this._createSubNodePromises[name];\n    }\n\n    /**\n     * Releases associated resources.\n     *\n     * @internal\n     */\n    public dispose() {\n        this._isDisposed = true;\n\n        const subNodes = Object.values(this._subNodes);\n        for (const subNode of subNodes) {\n            subNode.dispose();\n        }\n\n        this._subNodes = {};\n        this._createSubNodePromises = {};\n    }\n\n    /**\n     * Gets a previously created sub node.\n     *\n     * @param name - The name of the sub node\n     * @returns The named sub node, or `null` if it has not been created, yet\n     *\n     * @internal\n     * */\n    public getSubNode<T extends _AbstractAudioSubNode>(name: string): Nullable<T> {\n        return (this._subNodes[name] as T) ?? null;\n    }\n\n    /**\n     * Removes a sub node from the sub graph.\n     *\n     * @param subNode - The sub node to remove\n     * @returns A promise that resolves when the sub node is removed\n     *\n     * @internal\n     */\n    public async removeSubNodeAsync(subNode: Nullable<_AbstractAudioSubNode>): Promise<void> {\n        if (!subNode) {\n            return;\n        }\n\n        await this._createSubNodePromisesResolvedAsync();\n\n        const name = subNode.name;\n        if (this._subNodes[name]) {\n            delete this._subNodes[name];\n        }\n\n        delete this._createSubNodePromises[name];\n\n        this._onSubNodesChanged();\n    }\n\n    protected abstract _createSubNode(name: string): Promise<_AbstractAudioSubNode>;\n\n    /**\n     * Called when sub-nodes are added or removed.\n     * - Override this to connect and reconnect sub-nodes as needed.\n     */\n    protected abstract _onSubNodesChanged(): void;\n\n    protected async _createSubNodePromisesResolvedAsync(): Promise<_AbstractAudioSubNode[]> {\n        return await Promise.all(Object.values(this._createSubNodePromises));\n    }\n\n    private _addSubNode(node: _AbstractAudioSubNode): void {\n        if (this._isDisposed) {\n            node.dispose();\n            return;\n        }\n\n        this._subNodes[node.name] = node;\n\n        node.onDisposeObservable.addOnce(this._onSubNodeDisposed);\n\n        this._onSubNodesChanged();\n    }\n\n    private _onSubNodeDisposed = (node: AbstractAudioNode) => {\n        const subNode = node as AbstractNamedAudioNode;\n\n        delete this._subNodes[subNode.name];\n\n        this._onSubNodesChanged();\n    };\n}\n","import { type Nullable } from \"../../../types\";\nimport { _VolumeAudioSubNode } from \"../../abstractAudio/subNodes/volumeAudioSubNode\";\nimport { type IAudioParameterRampOptions } from \"../../audioParameter\";\nimport { _WebAudioParameterComponent } from \"../components/webAudioParameterComponent\";\nimport { type _WebAudioEngine } from \"../webAudioEngine\";\nimport { type IWebAudioInNode, type IWebAudioSubNode } from \"../webAudioNode\";\n\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function _CreateVolumeAudioSubNodeAsync(engine: _WebAudioEngine): Promise<_VolumeAudioSubNode> {\n    return new _VolumeWebAudioSubNode(engine);\n}\n\n/** @internal */\nexport class _VolumeWebAudioSubNode extends _VolumeAudioSubNode implements IWebAudioSubNode {\n    private _volume: _WebAudioParameterComponent;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public readonly node: AudioNode;\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine) {\n        super(engine);\n\n        const gainNode = (this.node = new GainNode(engine._audioContext));\n        this._volume = new _WebAudioParameterComponent(engine, gainNode.gain);\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._volume.dispose();\n    }\n\n    /** @internal */\n    public get volume(): number {\n        return this._volume.value;\n    }\n\n    /** @internal */\n    public set volume(value: number) {\n        this.setVolume(value);\n    }\n\n    /** @internal */\n    public get _inNode(): AudioNode {\n        return this.node;\n    }\n\n    /** @internal */\n    public get _outNode(): AudioNode {\n        return this.node;\n    }\n\n    /** @internal */\n    public setVolume(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n        this._volume.setTargetValue(value, options);\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the subgraph.\n        if (node._inNode) {\n            this.node.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this.node.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_VolumeWebAudioSubNode\";\n    }\n}\n","import { type Nullable } from \"../../../types\";\nimport { _AudioAnalyzerSubNode } from \"../../abstractAudio/subNodes/audioAnalyzerSubNode\";\nimport { type AudioAnalyzerFFTSizeType } from \"../../abstractAudio/subProperties/abstractAudioAnalyzer\";\nimport { type _WebAudioEngine } from \"../webAudioEngine\";\nimport { type IWebAudioInNode } from \"../webAudioNode\";\n\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function _CreateAudioAnalyzerSubNodeAsync(engine: _WebAudioEngine): Promise<_AudioAnalyzerSubNode> {\n    return new _WebAudioAnalyzerSubNode(engine);\n}\n\n/** @internal */\nexport class _WebAudioAnalyzerSubNode extends _AudioAnalyzerSubNode implements IWebAudioInNode {\n    private readonly _analyzerNode: AnalyserNode;\n    private _byteFrequencyData: Nullable<Uint8Array<ArrayBuffer>> = null;\n    private _byteTimeDomainData: Nullable<Uint8Array<ArrayBuffer>> = null;\n    private _floatFrequencyData: Nullable<Float32Array<ArrayBuffer>> = null;\n    private _floatTimeDomainData: Nullable<Float32Array<ArrayBuffer>> = null;\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine) {\n        super(engine);\n\n        this._analyzerNode = new AnalyserNode(engine._audioContext);\n    }\n\n    /** @internal */\n    public get fftSize(): AudioAnalyzerFFTSizeType {\n        return this._analyzerNode.fftSize as AudioAnalyzerFFTSizeType;\n    }\n\n    public set fftSize(value: AudioAnalyzerFFTSizeType) {\n        if (value === this._analyzerNode.fftSize) {\n            return;\n        }\n\n        this._analyzerNode.fftSize = value;\n\n        this._clearArrays();\n    }\n\n    /** @internal */\n    public get _inNode(): AudioNode {\n        return this._analyzerNode;\n    }\n\n    /** @internal */\n    public get minDecibels(): number {\n        return this._analyzerNode.minDecibels;\n    }\n\n    public set minDecibels(value: number) {\n        this._analyzerNode.minDecibels = value;\n    }\n\n    /** @internal */\n    public get maxDecibels(): number {\n        return this._analyzerNode.maxDecibels;\n    }\n\n    public set maxDecibels(value: number) {\n        this._analyzerNode.maxDecibels = value;\n    }\n\n    /** @internal */\n    public get smoothing(): number {\n        return this._analyzerNode.smoothingTimeConstant;\n    }\n\n    public set smoothing(value: number) {\n        this._analyzerNode.smoothingTimeConstant = value;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._clearArrays();\n\n        this._analyzerNode.disconnect();\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioAnalyzerSubNode\";\n    }\n\n    /** @internal */\n    public getByteFrequencyData(): Uint8Array {\n        if (!this._byteFrequencyData || this._byteFrequencyData.length === 0) {\n            this._byteFrequencyData = new Uint8Array(this._analyzerNode.frequencyBinCount);\n        }\n        this._analyzerNode.getByteFrequencyData(this._byteFrequencyData);\n        return this._byteFrequencyData;\n    }\n\n    /** @internal */\n    public getByteTimeDomainData(): Uint8Array {\n        if (!this._byteTimeDomainData || this._byteTimeDomainData.length === 0) {\n            this._byteTimeDomainData = new Uint8Array(this._analyzerNode.fftSize);\n        }\n        this._analyzerNode.getByteTimeDomainData(this._byteTimeDomainData);\n        return this._byteTimeDomainData;\n    }\n\n    /** @internal */\n    public getFloatFrequencyData(): Float32Array {\n        if (!this._floatFrequencyData || this._floatFrequencyData.length === 0) {\n            this._floatFrequencyData = new Float32Array(this._analyzerNode.frequencyBinCount);\n        }\n        this._analyzerNode.getFloatFrequencyData(this._floatFrequencyData);\n        return this._floatFrequencyData;\n    }\n\n    /** @internal */\n    public getFloatTimeDomainData(): Float32Array {\n        if (!this._floatTimeDomainData || this._floatTimeDomainData.length === 0) {\n            this._floatTimeDomainData = new Float32Array(this._analyzerNode.fftSize);\n        }\n        this._analyzerNode.getFloatTimeDomainData(this._floatTimeDomainData);\n        return this._floatTimeDomainData;\n    }\n\n    private _clearArrays(): void {\n        this._byteFrequencyData = null;\n        this._byteTimeDomainData = null;\n        this._floatFrequencyData = null;\n        this._floatTimeDomainData = null;\n    }\n}\n","import { type Nullable } from \"../../../types\";\nimport { type AbstractAudioNode } from \"../../abstractAudio/abstractAudioNode\";\nimport { _AbstractAudioSubGraph } from \"../../abstractAudio/subNodes/abstractAudioSubGraph\";\nimport { type _AbstractAudioSubNode } from \"../../abstractAudio/subNodes/abstractAudioSubNode\";\nimport { _GetAudioAnalyzerSubNode } from \"../../abstractAudio/subNodes/audioAnalyzerSubNode\";\nimport { AudioSubNode } from \"../../abstractAudio/subNodes/audioSubNode\";\nimport { type IVolumeAudioOptions, _GetVolumeAudioSubNode } from \"../../abstractAudio/subNodes/volumeAudioSubNode\";\nimport { type IAudioAnalyzerOptions, _HasAudioAnalyzerOptions } from \"../../abstractAudio/subProperties/abstractAudioAnalyzer\";\nimport { type IWebAudioInNode, type IWebAudioSuperNode } from \"../webAudioNode\";\nimport { type _VolumeWebAudioSubNode, _CreateVolumeAudioSubNodeAsync } from \"./volumeWebAudioSubNode\";\nimport { _CreateAudioAnalyzerSubNodeAsync } from \"./webAudioAnalyzerSubNode\";\n\n/**\n * Options for creating a WebAudioBaseSubGraph.\n */\nexport interface IWebAudioBaseSubGraphOptions extends IAudioAnalyzerOptions, IVolumeAudioOptions {}\n\n/** @internal */\nexport abstract class _WebAudioBaseSubGraph extends _AbstractAudioSubGraph {\n    protected _owner: IWebAudioSuperNode;\n    protected _outputNode: Nullable<AudioNode> = null;\n\n    /** @internal */\n    public constructor(owner: IWebAudioSuperNode) {\n        super();\n\n        this._owner = owner;\n    }\n\n    /** @internal */\n    public async initAsync(options: Partial<IWebAudioBaseSubGraphOptions>): Promise<void> {\n        const hasAnalyzerOptions = _HasAudioAnalyzerOptions(options);\n\n        if (hasAnalyzerOptions) {\n            await this.createAndAddSubNodeAsync(AudioSubNode.ANALYZER);\n        }\n\n        await this.createAndAddSubNodeAsync(AudioSubNode.VOLUME);\n\n        await this._createSubNodePromisesResolvedAsync();\n\n        if (hasAnalyzerOptions) {\n            const analyzerNode = _GetAudioAnalyzerSubNode(this);\n            if (!analyzerNode) {\n                throw new Error(\"No analyzer subnode.\");\n            }\n\n            analyzerNode.setOptions(options);\n        }\n\n        const volumeNode = _GetVolumeAudioSubNode(this);\n        if (!volumeNode) {\n            throw new Error(\"No volume subnode.\");\n        }\n\n        volumeNode.setOptions(options);\n\n        if (volumeNode.getClassName() !== \"_VolumeWebAudioSubNode\") {\n            throw new Error(\"Not a WebAudio subnode.\");\n        }\n\n        this._outputNode = (volumeNode as _VolumeWebAudioSubNode).node;\n\n        // Connect the new wrapped WebAudio node to the wrapped downstream WebAudio nodes.\n        // The wrapper nodes are unaware of this change.\n        if (this._outputNode && this._downstreamNodes) {\n            const it = this._downstreamNodes.values();\n            for (let next = it.next(); !next.done; next = it.next()) {\n                const inNode = (next.value as IWebAudioInNode)._inNode;\n                if (inNode) {\n                    this._outputNode.connect(inNode);\n                }\n            }\n        }\n    }\n\n    protected abstract readonly _downstreamNodes: Nullable<Set<AbstractAudioNode>>;\n\n    /** @internal */\n    public get _inNode(): Nullable<AudioNode> {\n        return this._outputNode;\n    }\n\n    /** @internal */\n    public get _outNode(): Nullable<AudioNode> {\n        return this._outputNode;\n    }\n\n    // Function is async, but throws synchronously. Avoiding breaking changes.\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    protected _createSubNode(name: string): Promise<_AbstractAudioSubNode> {\n        switch (name) {\n            case AudioSubNode.ANALYZER:\n                return _CreateAudioAnalyzerSubNodeAsync(this._owner.engine);\n            case AudioSubNode.VOLUME:\n                return _CreateVolumeAudioSubNodeAsync(this._owner.engine);\n            default:\n                throw new Error(`Unknown subnode name: ${name}`);\n        }\n    }\n\n    protected _onSubNodesChanged(): void {\n        const analyzerNode = _GetAudioAnalyzerSubNode(this);\n        const volumeNode = _GetVolumeAudioSubNode(this);\n\n        if (analyzerNode && volumeNode) {\n            volumeNode.connect(analyzerNode);\n        }\n    }\n}\n","import { type Nullable } from \"../../../types\";\nimport { type AbstractAudioNode } from \"../../abstractAudio/abstractAudioNode\";\nimport { type _AbstractAudioSubNode } from \"../../abstractAudio/subNodes/abstractAudioSubNode\";\nimport { AudioSubNode } from \"../../abstractAudio/subNodes/audioSubNode\";\nimport { _GetSpatialAudioSubNode } from \"../../abstractAudio/subNodes/spatialAudioSubNode\";\nimport { _GetStereoAudioSubNode } from \"../../abstractAudio/subNodes/stereoAudioSubNode\";\nimport { type IVolumeAudioOptions, _GetVolumeAudioSubNode } from \"../../abstractAudio/subNodes/volumeAudioSubNode\";\nimport { type ISpatialAudioOptions, _HasSpatialAudioOptions } from \"../../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { type IStereoAudioOptions, _HasStereoAudioOptions } from \"../../abstractAudio/subProperties/abstractStereoAudio\";\nimport { type IWebAudioInNode, type IWebAudioOutNode } from \"../webAudioNode\";\nimport { type _SpatialWebAudioSubNode, _CreateSpatialAudioSubNodeAsync } from \"./spatialWebAudioSubNode\";\nimport { type _StereoWebAudioSubNode, _CreateStereoAudioSubNodeAsync } from \"./stereoWebAudioSubNode\";\nimport { type _VolumeWebAudioSubNode } from \"./volumeWebAudioSubNode\";\nimport { _WebAudioBaseSubGraph } from \"./webAudioBaseSubGraph\";\n\n/** @internal */\nexport interface IWebAudioBusAndSoundSubGraphOptions extends ISpatialAudioOptions, IStereoAudioOptions, IVolumeAudioOptions {}\n\n/** @internal */\nexport abstract class _WebAudioBusAndSoundSubGraph extends _WebAudioBaseSubGraph {\n    private _rootNode: Nullable<GainNode> = null;\n    protected abstract readonly _upstreamNodes: Nullable<Set<AbstractAudioNode>>;\n\n    protected _inputNode: Nullable<AudioNode> = null;\n\n    /** @internal */\n    public override async initAsync(options: Partial<IWebAudioBusAndSoundSubGraphOptions>): Promise<void> {\n        await super.initAsync(options);\n\n        let hasSpatialOptions: boolean;\n        let hasStereoOptions: boolean;\n\n        if ((hasSpatialOptions = _HasSpatialAudioOptions(options))) {\n            await this.createAndAddSubNodeAsync(AudioSubNode.SPATIAL);\n        }\n        if ((hasStereoOptions = _HasStereoAudioOptions(options))) {\n            await this.createAndAddSubNodeAsync(AudioSubNode.STEREO);\n        }\n\n        await this._createSubNodePromisesResolvedAsync();\n\n        if (hasSpatialOptions) {\n            _GetSpatialAudioSubNode(this)?.setOptions(options);\n        }\n        if (hasStereoOptions) {\n            _GetStereoAudioSubNode(this)?.setOptions(options);\n        }\n    }\n\n    /** @internal */\n    public override get _inNode(): Nullable<AudioNode> {\n        return this._inputNode;\n    }\n\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\n    protected override _createSubNode(name: string): Promise<_AbstractAudioSubNode> {\n        try {\n            const node = super._createSubNode(name);\n            return node;\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        } catch (e) {}\n\n        switch (name) {\n            case AudioSubNode.SPATIAL:\n                return _CreateSpatialAudioSubNodeAsync(this._owner.engine);\n            case AudioSubNode.STEREO:\n                return _CreateStereoAudioSubNodeAsync(this._owner.engine);\n            default:\n                throw new Error(`Unknown subnode name: ${name}`);\n        }\n    }\n\n    protected override _onSubNodesChanged(): void {\n        super._onSubNodesChanged();\n\n        const spatialNode = _GetSpatialAudioSubNode(this);\n        const stereoNode = _GetStereoAudioSubNode(this);\n        const volumeNode = _GetVolumeAudioSubNode(this);\n\n        if (spatialNode && spatialNode.getClassName() !== \"_SpatialWebAudioSubNode\") {\n            throw new Error(\"Not a WebAudio subnode.\");\n        }\n        if (stereoNode && stereoNode.getClassName() !== \"_StereoWebAudioSubNode\") {\n            throw new Error(\"Not a WebAudio subnode.\");\n        }\n        if (volumeNode && volumeNode.getClassName() !== \"_VolumeWebAudioSubNode\") {\n            throw new Error(\"Not a WebAudio subnode.\");\n        }\n\n        if (spatialNode) {\n            spatialNode.disconnectAll();\n\n            if (volumeNode) {\n                spatialNode.connect(volumeNode);\n            }\n        }\n\n        if (stereoNode) {\n            stereoNode.disconnectAll();\n\n            if (volumeNode) {\n                stereoNode.connect(volumeNode);\n            }\n        }\n\n        if (spatialNode && stereoNode) {\n            this._rootNode = new GainNode(this._owner.engine._audioContext);\n            this._rootNode.connect((spatialNode as _SpatialWebAudioSubNode)._inNode);\n            this._rootNode.connect((stereoNode as _StereoWebAudioSubNode)._inNode);\n        } else {\n            this._rootNode?.disconnect();\n            this._rootNode = null;\n        }\n\n        let inSubNode: Nullable<IWebAudioInNode> = null;\n\n        let inNode: Nullable<AudioNode>;\n\n        if (this._rootNode) {\n            inNode = this._rootNode;\n        } else {\n            if (spatialNode) {\n                inSubNode = spatialNode as _SpatialWebAudioSubNode;\n            } else if (stereoNode) {\n                inSubNode = stereoNode as _StereoWebAudioSubNode;\n            } else if (volumeNode) {\n                inSubNode = volumeNode as _VolumeWebAudioSubNode;\n            }\n\n            inNode = inSubNode?._inNode ?? null;\n        }\n\n        if (this._inputNode !== inNode) {\n            // Disconnect the wrapped upstream WebAudio nodes from the old wrapped WebAudio node.\n            // The wrapper nodes are unaware of this change.\n            if (this._inputNode && this._upstreamNodes) {\n                const it = this._upstreamNodes.values();\n                for (let next = it.next(); !next.done; next = it.next()) {\n                    (next.value as IWebAudioOutNode)._outNode?.disconnect(this._inputNode);\n                }\n            }\n\n            this._inputNode = inNode;\n\n            // Connect the wrapped upstream WebAudio nodes to the new wrapped WebAudio node.\n            // The wrapper nodes are unaware of this change.\n            if (inNode && this._upstreamNodes) {\n                const it = this._upstreamNodes.values();\n                for (let next = it.next(); !next.done; next = it.next()) {\n                    (next.value as IWebAudioOutNode)._outNode?.connect(inNode);\n                }\n            }\n        }\n    }\n}\n","import { type Quaternion, type Vector3 } from \"../../../Maths/math.vector\";\nimport { type Node } from \"../../../node\";\nimport { type Nullable } from \"../../../types\";\nimport { SpatialAudioAttachmentType } from \"../../spatialAudioAttachmentType\";\nimport { type _AbstractAudioSubGraph } from \"../subNodes/abstractAudioSubGraph\";\nimport { AudioSubNode } from \"../subNodes/audioSubNode\";\nimport { type _SpatialAudioSubNode, _GetSpatialAudioSubNode, _SetSpatialAudioProperty } from \"../subNodes/spatialAudioSubNode\";\nimport { _SpatialAudioDefaults, AbstractSpatialAudio } from \"./abstractSpatialAudio\";\n\n/** @internal */\nexport abstract class _SpatialAudio extends AbstractSpatialAudio {\n    private _coneInnerAngle: number = _SpatialAudioDefaults.coneInnerAngle;\n    private _coneOuterAngle: number = _SpatialAudioDefaults.coneOuterAngle;\n    private _coneOuterVolume: number = _SpatialAudioDefaults.coneOuterVolume;\n    private _distanceModel: DistanceModelType = _SpatialAudioDefaults.distanceModel;\n    private _maxDistance: number = _SpatialAudioDefaults.maxDistance;\n    private _minDistance: number = _SpatialAudioDefaults.minDistance;\n    private _orientation: Vector3;\n    private _panningEnabled: boolean = _SpatialAudioDefaults.panningEnabled;\n    private _panningModel: PanningModelType = _SpatialAudioDefaults.panningModel;\n    private _position: Vector3;\n    private _rolloffFactor: number = _SpatialAudioDefaults.rolloffFactor;\n    private _rotation: Vector3;\n    private _rotationQuaternion: Quaternion;\n    private _subGraph: _AbstractAudioSubGraph;\n\n    /** @internal */\n    public constructor(subGraph: _AbstractAudioSubGraph) {\n        super();\n\n        const subNode = _GetSpatialAudioSubNode(subGraph);\n        if (subNode) {\n            this._orientation = subNode.orientation.clone();\n            this._panningEnabled = subNode.panningEnabled;\n            this._position = subNode.position.clone();\n            this._rotation = subNode.rotation.clone();\n            this._rotationQuaternion = subNode.rotationQuaternion.clone();\n        } else {\n            this._orientation = _SpatialAudioDefaults.orientation.clone();\n            this._position = _SpatialAudioDefaults.position.clone();\n            this._rotation = _SpatialAudioDefaults.rotation.clone();\n            this._rotationQuaternion = _SpatialAudioDefaults.rotationQuaternion.clone();\n\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            subGraph.createAndAddSubNodeAsync(AudioSubNode.SPATIAL);\n        }\n\n        this._subGraph = subGraph;\n    }\n\n    /** @internal */\n    public dispose(): void {\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        this._subGraph.removeSubNodeAsync(_GetSpatialAudioSubNode(this._subGraph));\n    }\n\n    /** @internal */\n    public get coneInnerAngle(): number {\n        return this._coneInnerAngle;\n    }\n\n    public set coneInnerAngle(value: number) {\n        this._coneInnerAngle = value;\n        _SetSpatialAudioProperty(this._subGraph, \"coneInnerAngle\", value);\n    }\n\n    /** @internal */\n    public get coneOuterAngle(): number {\n        return this._coneOuterAngle;\n    }\n\n    public set coneOuterAngle(value: number) {\n        this._coneOuterAngle = value;\n        _SetSpatialAudioProperty(this._subGraph, \"coneOuterAngle\", value);\n    }\n\n    /** @internal */\n    public get coneOuterVolume(): number {\n        return this._coneOuterVolume;\n    }\n\n    public set coneOuterVolume(value: number) {\n        this._coneOuterVolume = value;\n        _SetSpatialAudioProperty(this._subGraph, \"coneOuterVolume\", value);\n    }\n\n    /** @internal */\n    public get distanceModel(): DistanceModelType {\n        return this._distanceModel;\n    }\n\n    public set distanceModel(value: DistanceModelType) {\n        this._distanceModel = value;\n        _SetSpatialAudioProperty(this._subGraph, \"distanceModel\", value);\n    }\n\n    /** @internal */\n    public get isAttached(): boolean {\n        return this._subGraph.getSubNode<_SpatialAudioSubNode>(AudioSubNode.SPATIAL)?.isAttached ?? false;\n    }\n\n    /** @internal */\n    public get attachedNode(): Nullable<Node> {\n        return this._subGraph.getSubNode<_SpatialAudioSubNode>(AudioSubNode.SPATIAL)?.attachedNode ?? null;\n    }\n\n    /** @internal */\n    public get useBoundingBox(): boolean {\n        return this._subGraph.getSubNode<_SpatialAudioSubNode>(AudioSubNode.SPATIAL)?.useBoundingBox ?? false;\n    }\n\n    /** @internal */\n    public get attachmentType(): SpatialAudioAttachmentType {\n        return this._subGraph.getSubNode<_SpatialAudioSubNode>(AudioSubNode.SPATIAL)?.attachmentType ?? SpatialAudioAttachmentType.PositionAndRotation;\n    }\n\n    /** @internal */\n    public get maxDistance(): number {\n        return this._maxDistance;\n    }\n\n    public set maxDistance(value: number) {\n        if (value <= 0) {\n            value = 0.000001;\n        }\n\n        this._maxDistance = value;\n        _SetSpatialAudioProperty(this._subGraph, \"maxDistance\", value);\n    }\n\n    /** @internal */\n    public get minDistance(): number {\n        return this._minDistance;\n    }\n\n    public set minDistance(value: number) {\n        this._minDistance = value;\n        _SetSpatialAudioProperty(this._subGraph, \"minDistance\", value);\n    }\n\n    /** @internal */\n    public get orientation(): Vector3 {\n        return this._orientation;\n    }\n\n    public set orientation(value: Vector3) {\n        this._orientation = value;\n        this._updateRotation();\n    }\n\n    /** @internal */\n    public get panningEnabled(): boolean {\n        return this._panningEnabled;\n    }\n\n    public set panningEnabled(value: boolean) {\n        this._panningEnabled = value;\n        _SetSpatialAudioProperty(this._subGraph, \"panningEnabled\", value);\n    }\n\n    /** @internal */\n    public get panningModel(): PanningModelType {\n        return this._panningModel;\n    }\n\n    public set panningModel(value: PanningModelType) {\n        this._panningModel = value;\n        _SetSpatialAudioProperty(this._subGraph, \"panningModel\", value);\n    }\n\n    /** @internal */\n    public get position(): Vector3 {\n        return this._position;\n    }\n\n    public set position(value: Vector3) {\n        this._position = value;\n        this._updatePosition();\n    }\n\n    /** @internal */\n    public get rolloffFactor(): number {\n        return this._rolloffFactor;\n    }\n\n    public set rolloffFactor(value: number) {\n        this._rolloffFactor = value;\n        _SetSpatialAudioProperty(this._subGraph, \"rolloffFactor\", value);\n    }\n\n    /** @internal */\n    public get rotation(): Vector3 {\n        return this._rotation;\n    }\n\n    public set rotation(value: Vector3) {\n        this._rotation = value;\n        this._updateRotation();\n    }\n\n    /** @internal */\n    public get rotationQuaternion(): Quaternion {\n        return this._rotationQuaternion;\n    }\n\n    public set rotationQuaternion(value: Quaternion) {\n        this._rotationQuaternion = value;\n        this._updateRotation();\n    }\n\n    /**\n     * Attaches to a scene node.\n     *\n     * Detaches automatically before attaching to the given scene node.\n     * If `sceneNode` is `null` it is the same as calling `detach()`.\n     *\n     * @param sceneNode The scene node to attach to, or `null` to detach.\n     * @param useBoundingBox Whether to use the bounding box of the node for positioning. Defaults to `false`.\n     * @param attachmentType Whether to attach to the node's position and/or rotation. Defaults to `PositionAndRotation`.\n     */\n    public attach(sceneNode: Nullable<Node>, useBoundingBox: boolean = false, attachmentType: SpatialAudioAttachmentType = SpatialAudioAttachmentType.PositionAndRotation): void {\n        _GetSpatialAudioSubNode(this._subGraph)?.attach(sceneNode, useBoundingBox, attachmentType);\n    }\n\n    /**\n     * Detaches from the scene node if attached.\n     */\n    public detach(): void {\n        _GetSpatialAudioSubNode(this._subGraph)?.detach();\n    }\n\n    /** @internal */\n    public update(): void {\n        const subNode = _GetSpatialAudioSubNode(this._subGraph);\n\n        if (!subNode) {\n            return;\n        }\n\n        if (subNode.isAttached) {\n            subNode.update();\n        } else {\n            this._updatePosition(subNode);\n            this._updateRotation(subNode);\n        }\n    }\n\n    private _updatePosition(subNode: Nullable<_SpatialAudioSubNode> = null): void {\n        if (!subNode) {\n            subNode = _GetSpatialAudioSubNode(this._subGraph);\n\n            if (!subNode) {\n                return;\n            }\n        }\n\n        const position = subNode.position;\n        if (!position.equalsWithEpsilon(this._position)) {\n            subNode.position.copyFrom(this._position);\n            subNode._updatePosition();\n        } else if (!subNode.panningEnabled) {\n            subNode._updatePosition();\n        }\n    }\n\n    private _updateRotation(subNode: Nullable<_SpatialAudioSubNode> = null): void {\n        if (!subNode) {\n            subNode = _GetSpatialAudioSubNode(this._subGraph);\n\n            if (!subNode) {\n                return;\n            }\n        }\n\n        if (!subNode.rotationQuaternion.equalsWithEpsilon(this._rotationQuaternion)) {\n            subNode.rotationQuaternion.copyFrom(this._rotationQuaternion);\n            subNode._updateRotation();\n            this._orientation.copyFrom(subNode.orientation);\n            this._rotation.copyFrom(subNode.rotation);\n        } else if (!subNode.rotation.equalsWithEpsilon(this._rotation)) {\n            subNode.rotation.copyFrom(this._rotation);\n            subNode._updateRotation();\n            this._orientation.copyFrom(subNode.orientation);\n            this._rotationQuaternion.copyFrom(subNode.rotationQuaternion);\n        } else if (!subNode.orientation.equalsWithEpsilon(this._orientation)) {\n            subNode.orientation.copyFrom(this._orientation);\n            subNode._updateRotation();\n            this._rotation.copyFrom(subNode.rotation);\n            this._rotationQuaternion.copyFrom(subNode.rotationQuaternion);\n        }\n    }\n}\n","import { type _AbstractAudioSubGraph } from \"../../abstractAudio/subNodes/abstractAudioSubGraph\";\nimport { _SpatialAudio } from \"../../abstractAudio/subProperties/spatialAudio\";\nimport { _SpatialWebAudioUpdaterComponent } from \"../components/spatialWebAudioUpdaterComponent\";\n\n/** @internal */\nexport class _SpatialWebAudio extends _SpatialAudio {\n    private _updaterComponent: _SpatialWebAudioUpdaterComponent;\n\n    /** @internal */\n    public constructor(subGraph: _AbstractAudioSubGraph, autoUpdate: boolean, minUpdateTime: number) {\n        super(subGraph);\n\n        this._updaterComponent = new _SpatialWebAudioUpdaterComponent(this, autoUpdate, minUpdateTime);\n    }\n\n    /** @internal */\n    public get minUpdateTime(): number {\n        return this._updaterComponent.minUpdateTime;\n    }\n\n    /** @internal */\n    public set minUpdateTime(value: number) {\n        this._updaterComponent.minUpdateTime = value;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._updaterComponent.dispose();\n        this._updaterComponent = null!;\n    }\n}\n","import { type Nullable } from \"../../types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type ISoundSourceOptions, AbstractSoundSource } from \"../abstractAudio/abstractSoundSource\";\nimport { type AbstractSpatialAudio, _HasSpatialAudioOptions } from \"../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode } from \"./webAudioNode\";\n\n/** @internal */\nexport class _WebAudioSoundSource extends AbstractSoundSource {\n    private _stereo: Nullable<_StereoAudio> = null;\n\n    protected _subGraph: _WebAudioBusAndSoundSubGraph;\n    protected _webAudioNode: Nullable<AudioNode> = null;\n\n    private _mediaStreamAudioElement: Nullable<HTMLAudioElement> = null;\n    private _stopMediaStreamTracksOnDispose = false;\n\n    /** @internal */\n    public _audioContext: AudioContext | OfflineAudioContext;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public constructor(name: string, webAudioNode: AudioNode, engine: _WebAudioEngine, options: Partial<ISoundSourceOptions>) {\n        super(name, engine, options);\n\n        this._audioContext = this.engine._audioContext;\n        this._webAudioNode = webAudioNode;\n\n        this._stopMediaStreamTracksOnDispose = options.stopMediaStreamTracksOnDispose === true;\n\n        if (options.mediaStreamSinkEnabled !== false && webAudioNode instanceof MediaStreamAudioSourceNode) {\n            this._attachMediaStreamSink(webAudioNode.mediaStream);\n        }\n\n        this._subGraph = new _WebAudioSoundSource._SubGraph(this);\n    }\n\n    /**\n     * Keeps a `MediaStream`-backed source audible by attaching the stream to a hidden, muted audio element.\n     *\n     * Some browsers (notably Chromium) only deliver samples from a `MediaStreamAudioSourceNode` while its `MediaStream`\n     * is also being pulled by an `HTMLMediaElement`; without this, a remote WebRTC stream routed through Web Audio is\n     * silent and cannot be spatialized. The element is muted so it does not add a second, non-spatial playback.\n     * @param mediaStream - the `MediaStream` backing this sound source\n     */\n    private _attachMediaStreamSink(mediaStream: MediaStream): void {\n        if (typeof Audio === \"undefined\") {\n            return;\n        }\n\n        const mediaElement = new Audio();\n        mediaElement.muted = true;\n        mediaElement.srcObject = mediaStream;\n        this._mediaStreamAudioElement = mediaElement;\n\n        void this._startMediaStreamSinkAsync(mediaElement);\n    }\n\n    /**\n     * Starts best-effort playback of the muted keep-alive media element.\n     * @param mediaElement - the muted media element pulling the source `MediaStream`\n     */\n    private async _startMediaStreamSinkAsync(mediaElement: HTMLAudioElement): Promise<void> {\n        try {\n            // Muted media is allowed to autoplay without a user gesture.\n            await mediaElement.play();\n        } catch {\n            // A rejected play() only means this browser-specific keep-alive is unavailable, which is non-fatal.\n        }\n    }\n\n    /** @internal */\n    public async _initAsync(options: Partial<ISoundSourceOptions>): Promise<void> {\n        if (options.outBus) {\n            this.outBus = options.outBus;\n        } else if (options.outBusAutoDefault !== false) {\n            await this.engine.isReadyPromise;\n            this.outBus = this.engine.defaultMainBus;\n        }\n\n        await this._subGraph.initAsync(options);\n\n        if (_HasSpatialAudioOptions(options)) {\n            this._initSpatialProperty();\n        }\n\n        this.engine._addNode(this);\n    }\n\n    /** @internal */\n    public get _inNode() {\n        return this._webAudioNode;\n    }\n\n    /** @internal */\n    public get _outNode() {\n        return this._subGraph._outNode;\n    }\n\n    /** @internal */\n    public override get stereo(): _StereoAudio {\n        return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        if (this._mediaStreamAudioElement) {\n            this._mediaStreamAudioElement.pause();\n            this._mediaStreamAudioElement.srcObject = null;\n            this._mediaStreamAudioElement = null;\n        }\n\n        if (this._webAudioNode) {\n            if (this._stopMediaStreamTracksOnDispose && this._webAudioNode instanceof MediaStreamAudioSourceNode) {\n                for (const track of this._webAudioNode.mediaStream.getTracks()) {\n                    track.stop();\n                }\n            }\n\n            this._webAudioNode.disconnect();\n            this._webAudioNode = null;\n        }\n\n        this._stereo = null;\n\n        this._subGraph.dispose();\n\n        this.engine._removeNode(this);\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioSoundSource\";\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the subgraph.\n        if (node._inNode) {\n            this._outNode?.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio {\n        return new _SpatialWebAudio(this._subGraph, autoUpdate, minUpdateTime);\n    }\n\n    private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n        protected override _owner: _WebAudioSoundSource;\n\n        protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._downstreamNodes ?? null;\n        }\n\n        protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._upstreamNodes ?? null;\n        }\n\n        protected override _onSubNodesChanged(): void {\n            super._onSubNodesChanged();\n\n            this._owner._inNode?.disconnect();\n\n            if (this._owner._subGraph._inNode) {\n                this._owner._inNode?.connect(this._owner._subGraph._inNode);\n            }\n        }\n    };\n}\n","import { Observable } from \"../../Misc/observable\";\nimport { type Nullable } from \"../../types\";\nimport { SoundState } from \"../soundState\";\nimport { AudioNodeType } from \"./abstractAudioNode\";\nimport { type _AbstractSoundInstance } from \"./abstractSoundInstance\";\nimport { AbstractSoundSource, type ISoundSourceOptions } from \"./abstractSoundSource\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\nimport { type IVolumeAudioOptions } from \"./subNodes/volumeAudioSubNode\";\n\n/** @internal */\nexport interface IAbstractSoundOptionsBase {\n    /**\n     * Whether the sound should start playing automatically. Defaults to `false`.\n     */\n    autoplay: boolean;\n    /**\n     * The maximum number of instances that can play at the same time. Defaults to `Infinity`.\n     */\n    maxInstances: number;\n}\n\n/** @internal */\nexport interface IAbstractSoundPlayOptionsBase {\n    /**\n     * Whether the sound should loop. Defaults to `false`.\n     */\n    loop: boolean;\n    /**\n     * The time within the sound buffer to start playing at, in seconds. Defaults to `0`.\n     */\n    startOffset: number;\n}\n\n/**\n * Options for creating a sound.\n */\nexport interface IAbstractSoundOptions extends IAbstractSoundOptionsBase, IAbstractSoundPlayOptions, ISoundSourceOptions {}\n\n/**\n * Options for playing a sound.\n */\nexport interface IAbstractSoundPlayOptions extends IAbstractSoundPlayOptionsBase, IVolumeAudioOptions {}\n\n/**\n * Options stored in a sound.\n * @internal\n */\nexport interface IAbstractSoundStoredOptions extends IAbstractSoundOptionsBase, IAbstractSoundPlayOptionsBase {}\n\n/**\n * Abstract class representing a sound in the audio engine.\n */\nexport abstract class AbstractSound extends AbstractSoundSource {\n    private _newestInstance: Nullable<_AbstractSoundInstance> = null;\n    private _privateInstances = new Set<_AbstractSoundInstance>();\n    private _state: SoundState = SoundState.Stopped;\n\n    protected _instances: ReadonlySet<_AbstractSoundInstance> = this._privateInstances;\n    protected abstract readonly _options: IAbstractSoundStoredOptions;\n\n    /**\n     * Observable for when the sound stops playing.\n     */\n    public readonly onEndedObservable = new Observable<AbstractSound>();\n\n    protected constructor(name: string, engine: AudioEngineV2, options: Partial<IAbstractSoundOptions>) {\n        super(name, engine, options, AudioNodeType.HAS_INPUTS_AND_OUTPUTS); // Inputs are for instances.\n    }\n\n    /**\n     * The number of active instances of the sound that are currently playing.\n     */\n    public get activeInstancesCount(): number {\n        return this._instances.size;\n    }\n\n    /**\n     * Whether the sound should start playing automatically. Defaults to `false`.\n     */\n    public get autoplay(): boolean {\n        return this._options.autoplay;\n    }\n\n    /**\n     * The current playback time of the sound, in seconds.\n     */\n    public get currentTime(): number {\n        const instance = this._getNewestInstance();\n        return instance ? instance.currentTime : 0;\n    }\n\n    public set currentTime(value: number) {\n        this.startOffset = value;\n\n        const instance = this._getNewestInstance();\n        if (instance) {\n            instance.currentTime = value;\n        }\n    }\n\n    /**\n     * Whether the sound should loop. Defaults to `false`.\n     */\n    public get loop(): boolean {\n        return this._options.loop;\n    }\n\n    public set loop(value: boolean) {\n        this._options.loop = value;\n\n        const it = this._instances.values();\n        for (let instance = it.next(); !instance.done; instance = it.next()) {\n            instance.value.loop = value;\n        }\n    }\n\n    /**\n     * The maximum number of instances that can play at the same time. Defaults to `Infinity`.\n     */\n    public get maxInstances(): number {\n        return this._options.maxInstances;\n    }\n\n    public set maxInstances(value: number) {\n        this._options.maxInstances = value;\n    }\n\n    /**\n     * The time within the sound buffer to start playing at, in seconds. Defaults to `0`.\n     */\n    public get startOffset(): number {\n        return this._options.startOffset;\n    }\n\n    public set startOffset(value: number) {\n        this._options.startOffset = value;\n    }\n\n    /**\n     * The state of the sound.\n     */\n    public get state(): SoundState {\n        return this._state;\n    }\n\n    /**\n     * Releases associated resources.\n     */\n    public override dispose(): void {\n        super.dispose();\n\n        this.stop();\n\n        this._newestInstance = null;\n\n        this._privateInstances.clear();\n        this.onEndedObservable.clear();\n    }\n\n    /**\n     * Plays the sound.\n     * - Triggers `onEndedObservable` if played for the full duration and the `loop` option is not set.\n     * @param options The options to use when playing the sound. Options set here override the sound's options.\n     */\n    public abstract play(options?: Partial<IAbstractSoundPlayOptions>): void;\n\n    /**\n     * Pauses the sound.\n     */\n    public pause(): void {\n        const it = this._instances.values();\n        for (let next = it.next(); !next.done; next = it.next()) {\n            next.value.pause();\n        }\n\n        this._state = SoundState.Paused;\n        this.engine._onSoundPlaybackStateChanged();\n    }\n\n    /**\n     * Resumes the sound.\n     * @param options The options to use when resuming the sound. Only options explicitly set here override the paused instance's current options; unset options keep their paused values so playback continues from where it was paused.\n     */\n    public resume(options?: Partial<IAbstractSoundPlayOptions>): void {\n        if (this._state !== SoundState.Paused) {\n            return;\n        }\n\n        const it = this._instances.values();\n        for (let next = it.next(); !next.done; next = it.next()) {\n            next.value.resume(options);\n        }\n\n        this._state = SoundState.Started;\n        this.engine._onSoundPlaybackStateChanged();\n    }\n\n    /**\n     * Stops the sound.\n     * - Triggers `onEndedObservable` if the sound is playing.\n     */\n    public abstract stop(): void;\n\n    protected _beforePlay(instance: _AbstractSoundInstance): void {\n        if (this.state === SoundState.Paused && this._instances.size > 0) {\n            this.resume();\n            return;\n        }\n\n        instance.onEndedObservable.addOnce(this._onInstanceEnded);\n        instance.onStateChangedObservable.add(this._onInstanceStateChanged);\n        this._privateInstances.add(instance);\n        this._newestInstance = instance;\n    }\n\n    protected _afterPlay(instance: _AbstractSoundInstance): void {\n        this._state = instance.state;\n        this.engine._onSoundPlaybackStateChanged();\n    }\n\n    protected _getNewestInstance(): Nullable<_AbstractSoundInstance> {\n        if (this._instances.size === 0) {\n            return null;\n        }\n\n        if (!this._newestInstance) {\n            const it = this._instances.values();\n            for (let next = it.next(); !next.done; next = it.next()) {\n                this._newestInstance = next.value;\n            }\n        }\n\n        return this._newestInstance;\n    }\n\n    protected _setState(state: SoundState): void {\n        this._state = state;\n    }\n\n    protected abstract _createInstance(): _AbstractSoundInstance;\n\n    protected _stopExcessInstances(): void {\n        if (this.maxInstances < Infinity) {\n            const startedInstances = Array.from(this._instances).filter((instance) => instance.state === SoundState.Started);\n            const numberOfInstancesToStop = startedInstances.length - this.maxInstances;\n\n            for (let i = 0; i < numberOfInstancesToStop; i++) {\n                startedInstances[i].stop();\n            }\n        }\n    }\n\n    private _onInstanceEnded: (instance: _AbstractSoundInstance) => void = (instance) => {\n        if (this._newestInstance === instance) {\n            this._newestInstance = null;\n        }\n\n        instance.onStateChangedObservable.removeCallback(this._onInstanceStateChanged);\n        this._privateInstances.delete(instance);\n\n        if (this._instances.size === 0) {\n            this._state = SoundState.Stopped;\n            this.onEndedObservable.notifyObservers(this);\n        }\n\n        instance.dispose();\n\n        this.engine._onSoundPlaybackStateChanged();\n    };\n\n    private _onInstanceStateChanged: (instance: _AbstractSoundInstance) => void = (_instance) => {\n        this.engine._onSoundPlaybackStateChanged();\n    };\n}\n","import { type Nullable } from \"../../types\";\nimport { SoundState } from \"../soundState\";\nimport { type IAbstractSoundOptions, type IAbstractSoundPlayOptions, type IAbstractSoundStoredOptions, AbstractSound } from \"./abstractSound\";\nimport { type PrimaryAudioBus } from \"./audioBus\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\nimport { type IStaticSoundBufferOptions, type StaticSoundBuffer } from \"./staticSoundBuffer\";\nimport { type _StaticSoundInstance } from \"./staticSoundInstance\";\n\n/** @internal */\nexport interface IStaticSoundOptionsBase {\n    /**\n     * The amount of time to play the sound for, in seconds. Defaults to `0`.\n     * - If less than or equal to `0`, the sound plays for its full duration.\n     */\n    duration: number;\n    /**\n     * The end of the loop range in seconds. Defaults to `0`.\n     * - If less than or equal to `0`, the loop plays for the sound's full duration.\n     * - Has no effect if {@link loop} is `false`.\n     */\n    loopEnd: number;\n    /**\n     * The start of the loop range in seconds. Defaults to `0`.\n     * - If less than or equal to `0`, the loop starts at the beginning of the sound.\n     * - Has no effect if {@link loop} is `false`.\n     *\n     */\n    loopStart: number;\n}\n\n/**\n * Options stored in a static sound.\n * @internal\n */\nexport interface IStaticSoundStoredOptions extends IAbstractSoundStoredOptions, IStaticSoundOptionsBase {\n    /**\n     * The pitch of the sound, in cents. Defaults to `0`.\n     * - Can be combined with {@link playbackRate}.\n     */\n    pitch: number;\n    /**\n     * The playback rate of the sound. Defaults to `1`.\n     * - Can be combined with {@link pitch}.\n     */\n    playbackRate: number;\n}\n\n/**\n * Options for creating a static sound.\n */\nexport interface IStaticSoundOptions extends IAbstractSoundOptions, IStaticSoundBufferOptions, IStaticSoundStoredOptions {}\n\n/**\n * Options for playing a static sound.\n */\nexport interface IStaticSoundPlayOptions extends IAbstractSoundPlayOptions, IStaticSoundOptionsBase {\n    /**\n     * The time to wait before playing the sound, in seconds. Defaults to `0`.\n     */\n    waitTime: number;\n}\n\n/**\n * Options for stopping a static sound.\n */\nexport interface IStaticSoundStopOptions {\n    /**\n     * The time to wait before stopping the sound, in seconds. Defaults to `0`.\n     */\n    waitTime: number;\n}\n\n/**\n * Options for cloning a static sound.\n * - @see {@link StaticSound.clone}.\n */\nexport interface IStaticSoundCloneOptions {\n    /**\n     * Whether to clone the sound buffer when cloning the sound. Defaults to `false`.\n     * - If `true`, the original sound's buffer is cloned, and the cloned sound will use its own copy.\n     * - If `false`, the sound buffer is shared with the original sound.\n     */\n    cloneBuffer: boolean;\n\n    /**\n     * The output bus for the cloned sound. Defaults to `null`.\n     * - If not set or `null`, the cloned sound uses the original sound's `outBus`.\n     * @see {@link AudioEngineV2.defaultMainBus}\n     */\n    outBus: Nullable<PrimaryAudioBus>;\n}\n\n/**\n * Abstract class representing a static sound.\n *\n * A static sound has a sound buffer that is loaded into memory all at once. This allows it to have more capabilities\n * than a streaming sound, such as loop points and playback rate changes, but it also means that the sound must be\n * fully downloaded and decoded before it can be played, which may take a long time for sounds with long durations.\n *\n * To prevent downloading and decoding a sound multiple times, a sound's buffer can be shared with other sounds.\n * See {@link CreateSoundBufferAsync}, {@link StaticSoundBuffer} and {@link StaticSound.buffer} for more information.\n *\n * Static sounds are created by the {@link CreateSoundAsync} function.\n */\nexport abstract class StaticSound extends AbstractSound {\n    protected override _instances: Set<_StaticSoundInstance>;\n    protected abstract override readonly _options: IStaticSoundStoredOptions;\n\n    /**\n     * The sound buffer that the sound uses.\n     *\n     * This buffer can be shared with other static sounds.\n     */\n    public abstract readonly buffer: StaticSoundBuffer;\n\n    protected constructor(name: string, engine: AudioEngineV2, options: Partial<IStaticSoundOptions>) {\n        super(name, engine, options);\n    }\n\n    /**\n     * The amount of time to play the sound for, in seconds. Defaults to `0`.\n     * - If less than or equal to `0`, the sound plays for its full duration.\n     */\n    public get duration(): number {\n        return this._options.duration;\n    }\n\n    public set duration(value: number) {\n        this._options.duration = value;\n    }\n\n    /**\n     * The start of the loop range, in seconds. Defaults to `0`.\n     * - If less than or equal to `0`, the loop starts at the beginning of the sound.\n     */\n    public get loopStart(): number {\n        return this._options.loopStart;\n    }\n\n    public set loopStart(value: number) {\n        this._options.loopStart = value;\n\n        const it = this._instances.values();\n        for (let instance = it.next(); !instance.done; instance = it.next()) {\n            instance.value.loopStart = value;\n        }\n    }\n\n    /**\n     * The end of the loop range, in seconds. Defaults to `0`.\n     * - If less than or equal to `0`, the loop plays for the sound's full duration.\n     */\n    public get loopEnd(): number {\n        return this._options.loopEnd;\n    }\n\n    public set loopEnd(value: number) {\n        this._options.loopEnd = value;\n\n        const it = this._instances.values();\n        for (let instance = it.next(); !instance.done; instance = it.next()) {\n            instance.value.loopEnd = value;\n        }\n    }\n\n    /**\n     * The pitch of the sound, in cents. Defaults to `0`.\n     * - Gets combined with {@link playbackRate} to determine the final pitch.\n     */\n    public get pitch(): number {\n        return this._options.pitch;\n    }\n\n    public set pitch(value: number) {\n        this._options.pitch = value;\n\n        const it = this._instances.values();\n        for (let instance = it.next(); !instance.done; instance = it.next()) {\n            instance.value.pitch = value;\n        }\n    }\n\n    /**\n     * The playback rate of the sound. Defaults to `1`.\n     * - Gets combined with {@link pitch} to determine the final playback rate.\n     */\n    public get playbackRate(): number {\n        return this._options.playbackRate;\n    }\n\n    public set playbackRate(value: number) {\n        this._options.playbackRate = value;\n\n        const it = this._instances.values();\n        for (let instance = it.next(); !instance.done; instance = it.next()) {\n            instance.value.playbackRate = value;\n        }\n    }\n\n    /**\n     * Clones the sound.\n     * @param options Options for cloning the sound.\n     */\n    public abstract cloneAsync(options?: Partial<IStaticSoundCloneOptions>): Promise<StaticSound>;\n\n    /**\n     * Plays the sound.\n     * - Triggers `onEndedObservable` if played for the full duration and the `loop` option is not set.\n     * @param options The options to use when playing the sound. Options set here override the sound's options.\n     */\n    public play(options: Partial<IStaticSoundPlayOptions> = {}): void {\n        if (this.state === SoundState.Paused) {\n            this.resume(options);\n            return;\n        }\n\n        options.duration ??= this.duration;\n        options.loop ??= this.loop;\n        options.loopStart ??= this.loopStart;\n        options.loopEnd ??= this.loopEnd;\n        options.startOffset ??= this.startOffset;\n        options.volume ??= 1;\n        options.waitTime ??= 0;\n\n        const instance = this._createInstance();\n        this._beforePlay(instance);\n        instance.play(options);\n        this._afterPlay(instance);\n\n        this._stopExcessInstances();\n    }\n\n    /**\n     * Resumes the sound.\n     * - Only options explicitly set here override the paused instance's current options; unset options keep their paused values so playback continues from where it was paused.\n     * @param options The options to use when resuming the sound.\n     */\n    public override resume(options?: Partial<IStaticSoundPlayOptions>): void {\n        super.resume(options);\n    }\n\n    /**\n     * Stops the sound.\n     * - Triggers `onEndedObservable` if the sound is playing.\n     * @param options - The options to use when stopping the sound.\n     */\n    public stop(options: Partial<IStaticSoundStopOptions> = {}): void {\n        if (options.waitTime && 0 < options.waitTime) {\n            this._setState(SoundState.Stopping);\n        } else {\n            this._setState(SoundState.Stopped);\n        }\n\n        if (!this._instances) {\n            return;\n        }\n\n        for (const instance of Array.from(this._instances)) {\n            instance.stop(options);\n        }\n    }\n\n    protected abstract override _createInstance(): _StaticSoundInstance;\n}\n","import { type AudioEngineV2 } from \"./audioEngineV2\";\n\nlet StaticSoundBufferId = 1;\n\n/**\n * Options for creating a static sound buffer.\n */\nexport interface IStaticSoundBufferOptions {\n    /**\n     * Whether to skip codec checking before attempting to load each source URL when `source` is a string array. Defaults to `false`.\n     * - Has no effect if the sound's source is not a string array.\n     * @see {@link CreateSoundAsync} `source` parameter.\n     */\n    skipCodecCheck: boolean;\n}\n\n/**\n * Options for cloning a static sound buffer.\n * - @see {@link StaticSoundBuffer.clone}.\n */\nexport interface IStaticSoundBufferCloneOptions {\n    /**\n     * The name of the cloned sound buffer. Defaults to `StaticSoundBuffer #${id}`.\n     */\n    name: string;\n}\n\n/**\n * Abstract class representing a static sound buffer.\n *\n * A static sound buffer is a fully downloaded and decoded array of audio data that is ready to be played.\n *\n * Static sound buffers can be reused multiple times by different {@link StaticSound} instances.\n *\n * Static sound buffers are created by the {@link CreateSoundBufferAsync} function.\n *\n * @see {@link StaticSound.buffer}\n */\nexport abstract class StaticSoundBuffer {\n    /**\n     * The engine that the sound buffer belongs to.\n     */\n    public readonly engine: AudioEngineV2;\n\n    /**\n     * The name of the sound buffer.\n     */\n    public name: string = `StaticSoundBuffer #${StaticSoundBufferId++}`;\n\n    protected constructor(engine: AudioEngineV2) {\n        this.engine = engine;\n    }\n\n    /**\n     * The sample rate of the sound buffer.\n     */\n    public abstract readonly sampleRate: number;\n\n    /**\n     * The length of the sound buffer, in sample frames.\n     */\n    public abstract readonly length: number;\n\n    /**\n     * The duration of the sound buffer, in seconds.\n     */\n    public abstract readonly duration: number;\n\n    /**\n     * The number of channels in the sound buffer.\n     */\n    public abstract readonly channelCount: number;\n\n    /**\n     * Clones the sound buffer.\n     * @param options Options for cloning the sound buffer.\n     */\n    public abstract clone(options?: Partial<IStaticSoundBufferCloneOptions>): StaticSoundBuffer;\n}\n","import { Observable } from \"../../Misc/observable\";\nimport { SoundState } from \"../soundState\";\nimport { AbstractAudioNode, AudioNodeType } from \"./abstractAudioNode\";\nimport { type AbstractSound, type IAbstractSoundPlayOptions, type IAbstractSoundPlayOptionsBase } from \"./abstractSound\";\n\n/**\n * Options for creating a sound instance.\n * @internal\n * */\nexport interface IAbstractSoundInstanceOptions extends IAbstractSoundPlayOptionsBase {}\n\n/** @internal */\nexport abstract class _AbstractSoundInstance extends AbstractAudioNode {\n    protected _sound: AbstractSound;\n    protected _state: SoundState = SoundState.Stopped;\n\n    /** Observable triggered when the sound instance's playback ends */\n    public readonly onEndedObservable = new Observable<_AbstractSoundInstance>();\n\n    /** Observable triggered if the sound instance encounters an error and can not be played */\n    public readonly onErrorObservable = new Observable<any>();\n\n    /** Observable triggered when the sound instance's state changes */\n    public readonly onStateChangedObservable = new Observable<_AbstractSoundInstance>();\n\n    protected abstract readonly _options: IAbstractSoundInstanceOptions;\n\n    protected constructor(sound: AbstractSound) {\n        super(sound.engine, AudioNodeType.HAS_OUTPUTS);\n\n        this._sound = sound;\n    }\n\n    public abstract currentTime: number;\n\n    public abstract readonly startTime: number;\n\n    /** @internal */\n    public abstract set loop(value: boolean);\n\n    /** The playback state of the sound instance */\n    public get state(): SoundState {\n        return this._state;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n        this.stop();\n        this.onEndedObservable.clear();\n        this.onStateChangedObservable.clear();\n    }\n\n    public abstract play(options: Partial<IAbstractSoundPlayOptions>): void;\n    public abstract pause(): void;\n    public abstract resume(options?: Partial<IAbstractSoundPlayOptions>): void;\n    public abstract stop(): void;\n\n    protected _setState(value: SoundState) {\n        if (this._state === value) {\n            return;\n        }\n\n        this._state = value;\n        this.onStateChangedObservable.notifyObservers(this);\n\n        if (this._state === SoundState.Stopped) {\n            this.onEndedObservable.notifyObservers(this);\n        }\n    }\n}\n","import { type IAbstractSoundInstanceOptions, _AbstractSoundInstance } from \"./abstractSoundInstance\";\nimport { type IStaticSoundOptionsBase, type IStaticSoundPlayOptions, type IStaticSoundStopOptions } from \"./staticSound\";\n\n/**\n * Options for creating a static sound instance.\n * @internal\n */\nexport interface IStaticSoundInstanceOptions extends IAbstractSoundInstanceOptions, IStaticSoundOptionsBase {}\n\n/** @internal */\nexport abstract class _StaticSoundInstance extends _AbstractSoundInstance {\n    protected abstract override readonly _options: IStaticSoundInstanceOptions;\n\n    public abstract set loopStart(value: number);\n    public abstract set loopEnd(value: number);\n    public abstract set pitch(value: number);\n    public abstract set playbackRate(value: number);\n\n    public abstract override play(options: Partial<IStaticSoundPlayOptions>): void;\n    public abstract override stop(options?: Partial<IStaticSoundStopOptions>): void;\n}\n","import { type Nullable } from \"../../types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport {\n    type IStaticSoundCloneOptions,\n    type IStaticSoundOptions,\n    type IStaticSoundPlayOptions,\n    type IStaticSoundStopOptions,\n    type IStaticSoundStoredOptions,\n    StaticSound,\n} from \"../abstractAudio/staticSound\";\nimport { type IStaticSoundBufferCloneOptions, type IStaticSoundBufferOptions, StaticSoundBuffer } from \"../abstractAudio/staticSoundBuffer\";\nimport { type IStaticSoundInstanceOptions, _StaticSoundInstance } from \"../abstractAudio/staticSoundInstance\";\nimport { _HasSpatialAudioOptions, type AbstractSpatialAudio } from \"../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _CleanUrl, _FileExtensionRegex, _LoadArrayBufferFromUrlAsync } from \"../audioUtils\";\nimport { SoundState } from \"../soundState\";\nimport { _WebAudioParameterComponent } from \"./components/webAudioParameterComponent\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode, type IWebAudioOutNode, type IWebAudioSuperNode } from \"./webAudioNode\";\n\ntype StaticSoundSourceType = ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[];\n\n/** @internal */\nexport class _WebAudioStaticSound extends StaticSound implements IWebAudioSuperNode {\n    private _buffer: _WebAudioStaticSoundBuffer;\n    private _stereo: Nullable<_StereoAudio> = null;\n\n    protected override readonly _options: IStaticSoundStoredOptions;\n    protected _subGraph: _WebAudioBusAndSoundSubGraph;\n\n    /** @internal */\n    public _audioContext: AudioContext | OfflineAudioContext;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public constructor(name: string, engine: _WebAudioEngine, options: Partial<IStaticSoundOptions>) {\n        super(name, engine, options);\n\n        this._options = {\n            autoplay: options.autoplay ?? false,\n            duration: options.duration ?? 0,\n            loop: options.loop ?? false,\n            loopEnd: options.loopEnd ?? 0,\n            loopStart: options.loopStart ?? 0,\n            maxInstances: options.maxInstances ?? Infinity,\n            pitch: options.pitch ?? 0,\n            playbackRate: options.playbackRate ?? 1,\n            startOffset: options.startOffset ?? 0,\n        };\n\n        this._subGraph = new _WebAudioStaticSound._SubGraph(this);\n    }\n\n    /** @internal */\n    public async _initAsync(source: StaticSoundSourceType, options: Partial<IStaticSoundOptions>): Promise<void> {\n        this._audioContext = this.engine._audioContext;\n\n        if (source instanceof _WebAudioStaticSoundBuffer) {\n            this._buffer = source;\n        } else if (typeof source === \"string\" || Array.isArray(source) || source instanceof ArrayBuffer || source instanceof AudioBuffer) {\n            this._buffer = (await this.engine.createSoundBufferAsync(source, options)) as _WebAudioStaticSoundBuffer;\n        }\n\n        if (options.outBus) {\n            this.outBus = options.outBus;\n        } else if (options.outBusAutoDefault !== false) {\n            await this.engine.isReadyPromise;\n            this.outBus = this.engine.defaultMainBus;\n        }\n\n        await this._subGraph.initAsync(options);\n\n        if (_HasSpatialAudioOptions(options)) {\n            this._initSpatialProperty();\n        }\n\n        if (options.autoplay) {\n            this.play();\n        }\n\n        this.engine._addSound(this);\n    }\n\n    /** @internal */\n    public get buffer(): _WebAudioStaticSoundBuffer {\n        return this._buffer;\n    }\n\n    /** @internal */\n    public get _inNode() {\n        return this._subGraph._inNode;\n    }\n\n    /** @internal */\n    public get _outNode() {\n        return this._subGraph._outNode;\n    }\n\n    /** @internal */\n    public override get stereo(): _StereoAudio {\n        return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n    }\n\n    /** @internal */\n    public override async cloneAsync(options: Nullable<Partial<IStaticSoundCloneOptions>> = null): Promise<StaticSound> {\n        const clone = await this.engine.createSoundAsync(this.name, options?.cloneBuffer ? this.buffer.clone() : this.buffer, this._options);\n\n        clone.outBus = options?.outBus ? options.outBus : this.outBus;\n\n        return clone;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._stereo = null;\n\n        this._subGraph.dispose();\n\n        this.engine._removeSound(this);\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioStaticSound\";\n    }\n\n    protected _createInstance(): _WebAudioStaticSoundInstance {\n        return new _WebAudioStaticSoundInstance(this, this._options);\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the subgraph.\n        if (node._inNode) {\n            this._outNode?.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio {\n        return new _SpatialWebAudio(this._subGraph, autoUpdate, minUpdateTime);\n    }\n\n    public _getOptions(): IStaticSoundStoredOptions {\n        return this._options;\n    }\n\n    private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n        protected override _owner: _WebAudioStaticSound;\n\n        protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._downstreamNodes ?? null;\n        }\n\n        protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._upstreamNodes ?? null;\n        }\n    };\n}\n\n/** @internal */\nexport class _WebAudioStaticSoundBuffer extends StaticSoundBuffer {\n    /** @internal */\n    public _audioBuffer: AudioBuffer;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public constructor(engine: _WebAudioEngine) {\n        super(engine);\n    }\n\n    public async _initAsync(source: StaticSoundSourceType, options: Partial<IStaticSoundBufferOptions>): Promise<void> {\n        if (source instanceof AudioBuffer) {\n            this._audioBuffer = source;\n        } else if (typeof source === \"string\") {\n            await this._initFromUrlAsync(source);\n        } else if (Array.isArray(source)) {\n            await this._initFromUrlsAsync(source, options.skipCodecCheck ?? false);\n        } else if (source instanceof ArrayBuffer) {\n            await this._initFromArrayBufferAsync(source);\n        }\n    }\n\n    /** @internal */\n    public get channelCount(): number {\n        return this._audioBuffer.numberOfChannels;\n    }\n\n    /** @internal */\n    public get duration(): number {\n        return this._audioBuffer.duration;\n    }\n\n    /** @internal */\n    public get length(): number {\n        return this._audioBuffer.length;\n    }\n\n    /** @internal */\n    public get sampleRate(): number {\n        return this._audioBuffer.sampleRate;\n    }\n\n    /** @internal */\n    public override clone(options: Nullable<Partial<IStaticSoundBufferCloneOptions>> = null): StaticSoundBuffer {\n        const audioBuffer = new AudioBuffer({\n            length: this._audioBuffer.length,\n            numberOfChannels: this._audioBuffer.numberOfChannels,\n            sampleRate: this._audioBuffer.sampleRate,\n        });\n\n        for (let i = 0; i < this._audioBuffer.numberOfChannels; i++) {\n            audioBuffer.copyToChannel(this._audioBuffer.getChannelData(i), i);\n        }\n\n        const buffer = new _WebAudioStaticSoundBuffer(this.engine);\n        buffer._audioBuffer = audioBuffer;\n        buffer.name = options?.name ? options.name : this.name;\n\n        return buffer;\n    }\n\n    private async _initFromArrayBufferAsync(arrayBuffer: ArrayBuffer): Promise<void> {\n        this._audioBuffer = await this.engine._audioContext.decodeAudioData(arrayBuffer);\n    }\n\n    private async _initFromUrlAsync(url: string): Promise<void> {\n        url = _CleanUrl(url);\n        const { data } = await _LoadArrayBufferFromUrlAsync(url);\n        await this._initFromArrayBufferAsync(data);\n    }\n\n    private async _initFromUrlsAsync(urls: string[], skipCodecCheck: boolean): Promise<void> {\n        for (const url of urls) {\n            if (skipCodecCheck) {\n                // eslint-disable-next-line no-await-in-loop\n                await this._initFromUrlAsync(url);\n            } else {\n                const matches = url.match(_FileExtensionRegex);\n                const format = matches?.at(1);\n                if (format && this.engine.isFormatValid(format)) {\n                    try {\n                        // eslint-disable-next-line no-await-in-loop\n                        await this._initFromUrlAsync(url);\n                    } catch {\n                        if (format && 0 < format.length) {\n                            this.engine.flagInvalidFormat(format);\n                        }\n                    }\n                }\n            }\n\n            if (this._audioBuffer) {\n                break;\n            }\n        }\n    }\n}\n\n/** @internal */\nclass _WebAudioStaticSoundInstance extends _StaticSoundInstance implements IWebAudioOutNode {\n    private _enginePlayTime: number = 0;\n    private _enginePauseTime: number = 0;\n    private _isConnected: boolean = false;\n    private _pitch: Nullable<_WebAudioParameterComponent> = null;\n    private _playbackRate: Nullable<_WebAudioParameterComponent> = null;\n    private _sourceNode: Nullable<AudioBufferSourceNode> = null;\n    private _volumeNode: GainNode;\n\n    protected override readonly _options: IStaticSoundInstanceOptions;\n    protected override _sound: _WebAudioStaticSound;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    public constructor(sound: _WebAudioStaticSound, options: IStaticSoundInstanceOptions) {\n        super(sound);\n\n        this._options = options;\n\n        this._volumeNode = new GainNode(sound._audioContext);\n        this._initSourceNode();\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._pitch?.dispose();\n        this._playbackRate?.dispose();\n\n        this.stop();\n\n        this._deinitSourceNode();\n\n        this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n    }\n\n    /** @internal */\n    public get currentTime(): number {\n        if (this._state === SoundState.Stopped) {\n            return 0;\n        }\n\n        const timeSinceLastStart = this._state === SoundState.Paused ? 0 : this.engine.currentTime - this._enginePlayTime;\n        return this._enginePauseTime + timeSinceLastStart + this._options.startOffset;\n    }\n\n    public set currentTime(value: number) {\n        const restart = this._state === SoundState.Starting || this._state === SoundState.Started;\n\n        if (restart) {\n            // Stop source node without sending `onEndedObservable` so instance's `dispose` function is not called.\n            const sourceNode = this._sourceNode;\n            this._deinitSourceNode();\n            sourceNode?.stop();\n            this._state = SoundState.Stopped;\n        }\n\n        // Seeking sets an absolute position that is fully described by `startOffset`, so any playback time accumulated\n        // across previous pause/resume cycles must be cleared. Otherwise the stale value leaks into the `currentTime`\n        // getter and the next `pause()` calculation, offsetting them by the total paused duration.\n        this._enginePauseTime = 0;\n        this._options.startOffset = value;\n\n        if (restart) {\n            this.play();\n        }\n    }\n\n    public get _outNode(): Nullable<AudioNode> {\n        return this._volumeNode;\n    }\n\n    /** @internal */\n    public set loop(value: boolean) {\n        this._options.loop = value;\n\n        if (this._sourceNode) {\n            this._sourceNode.loop = value;\n        }\n    }\n\n    /** @internal */\n    public set loopStart(value: number) {\n        this._options.loopStart = value;\n\n        if (this._sourceNode) {\n            this._sourceNode.loopStart = value;\n        }\n    }\n\n    /** @internal */\n    public set loopEnd(value: number) {\n        this._options.loopEnd = value;\n\n        if (this._sourceNode) {\n            this._sourceNode.loopEnd = value;\n        }\n    }\n\n    /** @internal */\n    public set pitch(value: number) {\n        this._pitch?.setTargetValue(value);\n    }\n\n    /** @internal */\n    public set playbackRate(value: number) {\n        this._playbackRate?.setTargetValue(value);\n    }\n\n    /** @internal */\n    public get startTime(): number {\n        if (this._state === SoundState.Stopped) {\n            return 0;\n        }\n\n        return this._enginePlayTime;\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioStaticSoundInstance\";\n    }\n\n    /** @internal */\n    public play(options: Partial<IStaticSoundPlayOptions> = {}): void {\n        if (this._state === SoundState.Started) {\n            return;\n        }\n\n        if (options.duration !== undefined) {\n            this._options.duration = options.duration;\n        }\n        if (options.loop !== undefined) {\n            this._options.loop = options.loop;\n        }\n        if (options.loopStart !== undefined) {\n            this._options.loopStart = options.loopStart;\n        }\n        if (options.loopEnd !== undefined) {\n            this._options.loopEnd = options.loopEnd;\n        }\n        if (options.startOffset !== undefined) {\n            this._options.startOffset = options.startOffset;\n        }\n\n        let startOffset = this._options.startOffset;\n\n        if (this._state === SoundState.Paused) {\n            const duration = this._sound.buffer.duration;\n            const elapsed = this._enginePauseTime;\n\n            if (this._options.loop) {\n                // Web Audio only loops over `[loopStart, loopEnd)` when they describe a valid sub-range; otherwise it\n                // loops over the whole buffer. Mirror that here (matching the `AudioBufferSourceNode` playback algorithm)\n                // to compute the correct resume position inside the loop region.\n                let loopStart = 0;\n                let loopEnd = duration;\n\n                if (this._options.loopStart >= 0 && this._options.loopEnd > 0 && this._options.loopStart < this._options.loopEnd) {\n                    loopStart = this._options.loopStart;\n                    loopEnd = Math.min(this._options.loopEnd, duration);\n                }\n\n                // Time spent before the playback position first reaches `loopEnd` and wraps back to `loopStart`.\n                const timeToLoopEnd = loopEnd - startOffset;\n\n                if (elapsed < timeToLoopEnd) {\n                    startOffset += elapsed;\n                } else {\n                    startOffset = loopStart + ((elapsed - timeToLoopEnd) % (loopEnd - loopStart));\n                }\n            } else {\n                startOffset += elapsed;\n                startOffset %= duration;\n            }\n        }\n\n        this._enginePlayTime = this.engine.currentTime + (options.waitTime ?? 0);\n\n        // Only override the volume when explicitly provided so resuming a paused instance keeps its current volume.\n        if (options.volume !== undefined) {\n            this._volumeNode.gain.value = options.volume;\n        }\n\n        this._initSourceNode();\n\n        if (this.engine.state === \"running\") {\n            this._setState(SoundState.Started);\n            this._sourceNode?.start(this._enginePlayTime, startOffset, this._options.duration > 0 ? this._options.duration : undefined);\n        } else if (this._options.loop) {\n            this._setState(SoundState.Starting);\n            this.engine.stateChangedObservable.add(this._onEngineStateChanged);\n        }\n    }\n\n    /** @internal */\n    public pause(): void {\n        if (this._state !== SoundState.Started && this._state !== SoundState.Starting) {\n            return;\n        }\n\n        const wasStarted = this._state === SoundState.Started;\n\n        this._setState(SoundState.Paused);\n        this._enginePauseTime += this.engine.currentTime - this._enginePlayTime;\n\n        if (wasStarted) {\n            this._sourceNode?.stop();\n        } else {\n            this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n        }\n\n        this._deinitSourceNode();\n    }\n\n    /** @internal */\n    public resume(options: Partial<IStaticSoundPlayOptions> = {}): void {\n        if (this._state === SoundState.Paused) {\n            this.play(options);\n        }\n    }\n\n    /** @internal */\n    public stop(options: Partial<IStaticSoundStopOptions> = {}): void {\n        if (this._state === SoundState.Stopped) {\n            return;\n        }\n\n        if (this._state === SoundState.Started) {\n            const engineStopTime = this.engine.currentTime + (options.waitTime ?? 0);\n            this._sourceNode?.stop(engineStopTime);\n        }\n\n        if (options.waitTime === undefined || options.waitTime <= 0) {\n            this._setState(SoundState.Stopped);\n            this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n        }\n    }\n\n    protected override _connect(node: AbstractAudioNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the sound's subgraph.\n        if (node instanceof _WebAudioStaticSound && node._inNode) {\n            this._outNode?.connect(node._inNode);\n            this._isConnected = true;\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: AbstractAudioNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node instanceof _WebAudioStaticSound && node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n            this._isConnected = false;\n        }\n\n        return true;\n    }\n\n    protected _onEnded = () => {\n        this._enginePlayTime = 0;\n\n        if (this._state !== SoundState.Paused) {\n            this.onEndedObservable.notifyObservers(this);\n        }\n\n        this._deinitSourceNode();\n    };\n\n    private _deinitSourceNode(): void {\n        if (!this._sourceNode) {\n            return;\n        }\n\n        if (this._isConnected && !this._disconnect(this._sound)) {\n            throw new Error(\"Disconnect failed\");\n        }\n\n        this._sourceNode.disconnect(this._volumeNode);\n        this._sourceNode.removeEventListener(\"ended\", this._onEnded);\n\n        this._sourceNode = null;\n    }\n\n    private _initSourceNode(): void {\n        if (!this._sourceNode) {\n            this._sourceNode = new AudioBufferSourceNode(this._sound._audioContext, { buffer: this._sound.buffer._audioBuffer });\n\n            this._sourceNode.addEventListener(\"ended\", this._onEnded, { once: true });\n            this._sourceNode.connect(this._volumeNode);\n\n            if (!this._connect(this._sound)) {\n                throw new Error(\"Connect failed\");\n            }\n\n            this._pitch = new _WebAudioParameterComponent(this.engine, this._sourceNode.detune);\n            this._playbackRate = new _WebAudioParameterComponent(this.engine, this._sourceNode.playbackRate);\n        }\n\n        const node = this._sourceNode;\n        node.detune.value = this._sound.pitch;\n        node.loop = this._options.loop;\n        node.loopEnd = this._options.loopEnd;\n        node.loopStart = this._options.loopStart;\n        node.playbackRate.value = this._sound.playbackRate;\n    }\n\n    private _onEngineStateChanged = () => {\n        if (this.engine.state !== \"running\") {\n            return;\n        }\n\n        if (this._options.loop && this.state === SoundState.Starting) {\n            this.play();\n        }\n\n        this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n    };\n}\n","import { SoundState } from \"../soundState\";\nimport { type IAbstractSoundOptions, type IAbstractSoundPlayOptions, type IAbstractSoundStoredOptions, AbstractSound } from \"./abstractSound\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\nimport { type _StreamingSoundInstance } from \"./streamingSoundInstance\";\n\n/** @internal */\nexport interface IStreamingSoundOptionsBase {\n    /**\n     * The number of instances to preload. Defaults to 1.\n     * */\n    preloadCount: number;\n}\n\n/**\n * Options for creating a streaming sound.\n */\nexport interface IStreamingSoundOptions extends IAbstractSoundOptions, IStreamingSoundOptionsBase {}\n\n/**\n * Options for playing a streaming sound.\n */\nexport interface IStreamingSoundPlayOptions extends IAbstractSoundPlayOptions {}\n\n/**\n * Options stored in a streaming sound.\n * @internal\n */\nexport interface IStreamingSoundStoredOptions extends IAbstractSoundStoredOptions, IStreamingSoundOptionsBase {}\n\n/**\n * Abstract class representing a streaming sound.\n *\n * A streaming sound has a sound buffer that is loaded into memory in chunks as it is played. This allows it to be played\n * more quickly than a static sound, but it also means that it cannot have loop points or playback rate changes.\n *\n * Due to the way streaming sounds are typically implemented, there can be a significant delay when attempting to play\n * a streaming sound for the first time. To prevent this delay, it is recommended to preload instances of the sound\n * using the {@link IStreamingSoundStoredOptions.preloadCount} options, or the {@link preloadInstanceAsync} and\n * {@link preloadInstancesAsync} methods before calling the `play` method.\n *\n * Streaming sounds are created by the {@link CreateStreamingSoundAsync} function.\n */\nexport abstract class StreamingSound extends AbstractSound {\n    private _preloadedInstances = new Array<_StreamingSoundInstance>();\n\n    protected abstract override readonly _options: IStreamingSoundStoredOptions;\n\n    protected constructor(name: string, engine: AudioEngineV2, options: Partial<IStreamingSoundOptions>) {\n        super(name, engine, options);\n    }\n\n    /**\n     * The number of instances to preload. Defaults to `1`.\n     */\n    public get preloadCount(): number {\n        return this._options.preloadCount ?? 1;\n    }\n\n    /**\n     * Returns the number of instances that have been preloaded.\n     */\n    public get preloadCompletedCount(): number {\n        return this._preloadedInstances.length;\n    }\n\n    /**\n     * Preloads an instance of the sound.\n     * @returns A promise that resolves when the instance is preloaded.\n     */\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n    public preloadInstanceAsync(): Promise<void> {\n        const instance = this._createInstance();\n\n        this._addPreloadedInstance(instance);\n\n        return instance.preloadedPromise;\n    }\n\n    /**\n     * Preloads the given number of instances of the sound.\n     * @param count - The number of instances to preload.\n     * @returns A promise that resolves when all instances are preloaded.\n     */\n    public async preloadInstancesAsync(count: number): Promise<void> {\n        for (let i = 0; i < count; i++) {\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\n            this.preloadInstanceAsync();\n        }\n\n        await Promise.all(this._preloadedInstances.map(async (instance) => await instance.preloadedPromise));\n    }\n\n    /**\n     * Plays the sound.\n     * - Triggers `onEndedObservable` if played for the full duration and the `loop` option is not set.\n     * @param options The options to use when playing the sound. Options set here override the sound's options.\n     */\n    public play(options: Partial<IStreamingSoundPlayOptions> = {}): void {\n        if (this.state === SoundState.Paused) {\n            this.resume(options);\n            return;\n        }\n\n        let instance: _StreamingSoundInstance;\n\n        if (this.preloadCompletedCount > 0) {\n            instance = this._preloadedInstances[0];\n            instance.startOffset = this.startOffset;\n            this._removePreloadedInstance(instance);\n        } else {\n            instance = this._createInstance();\n        }\n\n        const onInstanceStateChanged = () => {\n            if (instance.state === SoundState.Started) {\n                this._stopExcessInstances();\n                instance.onStateChangedObservable.removeCallback(onInstanceStateChanged);\n            }\n        };\n        instance.onStateChangedObservable.add(onInstanceStateChanged);\n\n        options.startOffset ??= this.startOffset;\n        options.loop ??= this.loop;\n        options.volume ??= 1;\n\n        this._beforePlay(instance);\n        instance.play(options);\n        this._afterPlay(instance);\n    }\n\n    /**\n     * Resumes the sound.\n     * - Only options explicitly set here override the paused instance's current options; unset options keep their paused values so playback continues from where it was paused.\n     * @param options The options to use when resuming the sound.\n     */\n    public override resume(options?: Partial<IStreamingSoundPlayOptions>): void {\n        super.resume(options);\n    }\n\n    /**\n     * Stops the sound.\n     */\n    public stop(): void {\n        this._setState(SoundState.Stopped);\n\n        if (!this._instances) {\n            return;\n        }\n\n        for (const instance of Array.from(this._instances)) {\n            instance.stop();\n        }\n    }\n\n    protected abstract override _createInstance(): _StreamingSoundInstance;\n\n    private _addPreloadedInstance(instance: _StreamingSoundInstance): void {\n        if (!this._preloadedInstances.includes(instance)) {\n            this._preloadedInstances.push(instance);\n        }\n    }\n\n    private _removePreloadedInstance(instance: _StreamingSoundInstance): void {\n        const index = this._preloadedInstances.indexOf(instance);\n        if (index !== -1) {\n            this._preloadedInstances.splice(index, 1);\n        }\n    }\n}\n","import { Observable } from \"../../Misc/observable\";\nimport { type IAbstractSoundInstanceOptions, _AbstractSoundInstance } from \"./abstractSoundInstance\";\nimport { type IStreamingSoundOptionsBase, type StreamingSound } from \"./streamingSound\";\n\n/**\n * Options for creating streaming sound instance.\n * @internal\n */\nexport interface IStreamingSoundInstanceOptions extends IAbstractSoundInstanceOptions, IStreamingSoundOptionsBase {}\n\n/** @internal */\nexport abstract class _StreamingSoundInstance extends _AbstractSoundInstance {\n    private _rejectPreloadedPromise: (reason?: any) => void;\n    private _resolvePreloadedPromise: () => void;\n\n    protected abstract override readonly _options: IStreamingSoundInstanceOptions;\n\n    /** @internal */\n    public readonly onReadyObservable = new Observable<_StreamingSoundInstance>();\n\n    /** @internal */\n    public readonly preloadedPromise = new Promise<void>((resolve, reject) => {\n        this._rejectPreloadedPromise = reject;\n        this._resolvePreloadedPromise = resolve;\n    });\n\n    protected constructor(sound: StreamingSound) {\n        super(sound);\n\n        this.onErrorObservable.add(this._rejectPreloadedPromise);\n        this.onReadyObservable.add(this._resolvePreloadedPromise);\n    }\n\n    /** @internal */\n    public set startOffset(value: number) {\n        this._options.startOffset = value;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this.onErrorObservable.clear();\n        this.onReadyObservable.clear();\n\n        this._resolvePreloadedPromise();\n    }\n}\n","import { Logger } from \"../../Misc/logger\";\nimport { Tools } from \"../../Misc/tools.pure\";\nimport { type Nullable } from \"../../types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport type {} from \"../abstractAudio/abstractSound\";\nimport { type IStreamingSoundOptions, type IStreamingSoundPlayOptions, type IStreamingSoundStoredOptions, StreamingSound } from \"../abstractAudio/streamingSound\";\nimport { _StreamingSoundInstance } from \"../abstractAudio/streamingSoundInstance\";\nimport { _HasSpatialAudioOptions, type AbstractSpatialAudio } from \"../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _CleanUrl, _GetUrlForStreaming } from \"../audioUtils\";\nimport { WebRequest } from \"../../Misc/webRequest\";\nimport { SoundState } from \"../soundState\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode, type IWebAudioOutNode, type IWebAudioSuperNode } from \"./webAudioNode\";\n\ntype StreamingSoundSourceType = HTMLMediaElement | string | string[];\n\n/** @internal */\nexport class _WebAudioStreamingSound extends StreamingSound implements IWebAudioSuperNode {\n    private _stereo: Nullable<_StereoAudio> = null;\n\n    protected override readonly _options: IStreamingSoundStoredOptions;\n    protected _subGraph: _WebAudioBusAndSoundSubGraph;\n\n    /** @internal */\n    public _audioContext: AudioContext;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public _source: StreamingSoundSourceType;\n\n    /** @internal */\n    public constructor(name: string, engine: _WebAudioEngine, options: Partial<IStreamingSoundOptions>) {\n        super(name, engine, options);\n\n        this._options = {\n            autoplay: options.autoplay ?? false,\n            loop: options.loop ?? false,\n            maxInstances: options.maxInstances ?? Infinity,\n            preloadCount: options.preloadCount ?? 1,\n            startOffset: options.startOffset ?? 0,\n        };\n\n        this._subGraph = new _WebAudioStreamingSound._SubGraph(this);\n    }\n\n    /** @internal */\n    public async _initAsync(source: StreamingSoundSourceType, options: Partial<IStreamingSoundOptions>): Promise<void> {\n        const audioContext = this.engine._audioContext;\n\n        if (!(audioContext instanceof AudioContext)) {\n            throw new Error(\"Unsupported audio context type.\");\n        }\n\n        this._audioContext = audioContext;\n        this._source = source;\n\n        if (options.outBus) {\n            this.outBus = options.outBus;\n        } else if (options.outBusAutoDefault !== false) {\n            await this.engine.isReadyPromise;\n            this.outBus = this.engine.defaultMainBus;\n        }\n\n        await this._subGraph.initAsync(options);\n\n        if (_HasSpatialAudioOptions(options)) {\n            this._initSpatialProperty();\n        }\n\n        if (this.preloadCount) {\n            await this.preloadInstancesAsync(this.preloadCount);\n        }\n\n        if (options.autoplay) {\n            this.play(options);\n        }\n\n        this.engine._addSound(this);\n    }\n\n    /** @internal */\n    public get _inNode() {\n        return this._subGraph._inNode;\n    }\n\n    /** @internal */\n    public get _outNode() {\n        return this._subGraph._outNode;\n    }\n\n    /** @internal */\n    public override get stereo(): _StereoAudio {\n        return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._stereo = null;\n\n        this._subGraph.dispose();\n\n        this.engine._removeSound(this);\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioStreamingSound\";\n    }\n\n    protected _createInstance(): _WebAudioStreamingSoundInstance {\n        return new _WebAudioStreamingSoundInstance(this, this._options);\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the subgraph.\n        if (node._inNode) {\n            this._outNode?.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio {\n        return new _SpatialWebAudio(this._subGraph, autoUpdate, minUpdateTime);\n    }\n\n    public _getOptions(): IStreamingSoundStoredOptions {\n        return this._options;\n    }\n\n    private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n        protected override _owner: _WebAudioStreamingSound;\n\n        protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._downstreamNodes ?? null;\n        }\n\n        protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._upstreamNodes ?? null;\n        }\n    };\n}\n\n/** @internal */\nclass _WebAudioStreamingSoundInstance extends _StreamingSoundInstance implements IWebAudioOutNode {\n    private _currentTimeChangedWhilePaused = false;\n    private _enginePlayTime: number = Infinity;\n    private _enginePauseTime: number = 0;\n    private _isReady: boolean = false;\n    private _isReadyPromise: Promise<HTMLMediaElement> = new Promise((resolve, reject) => {\n        this._resolveIsReadyPromise = resolve;\n        this._rejectIsReadyPromise = reject;\n    });\n    private _mediaElement: HTMLMediaElement;\n    private _sourceNode: Nullable<MediaElementAudioSourceNode>;\n    private _volumeNode: GainNode;\n\n    protected override readonly _options: IStreamingSoundStoredOptions;\n    protected override _sound: _WebAudioStreamingSound;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    public constructor(sound: _WebAudioStreamingSound, options: IStreamingSoundStoredOptions) {\n        super(sound);\n\n        this._options = options;\n        this._volumeNode = new GainNode(sound._audioContext);\n\n        if (typeof sound._source === \"string\") {\n            this._initFromUrl(sound._source);\n        } else if (Array.isArray(sound._source)) {\n            this._initFromUrls(sound._source);\n        } else if (sound._source instanceof HTMLMediaElement) {\n            this._initFromMediaElement(sound._source);\n        } else {\n            throw new Error(`Invalid streaming sound source (${sound._source}).`);\n        }\n    }\n\n    /** @internal */\n    public get currentTime(): number {\n        if (this._state === SoundState.Stopped) {\n            return 0;\n        }\n\n        const timeSinceLastStart = this._state === SoundState.Paused ? 0 : this.engine.currentTime - this._enginePlayTime;\n        return this._enginePauseTime + timeSinceLastStart + this._options.startOffset;\n    }\n\n    public set currentTime(value: number) {\n        const restart = this._state === SoundState.Starting || this._state === SoundState.Started;\n\n        if (restart) {\n            this._mediaElement.pause();\n            this._state = SoundState.Stopped;\n        }\n\n        // Seeking sets an absolute position that is fully described by `startOffset`, so any playback time accumulated\n        // across previous pause/resume cycles must be cleared. Otherwise the stale value leaks into the `currentTime`\n        // getter and the next `pause()` calculation, offsetting them by the total paused duration.\n        this._enginePauseTime = 0;\n        this._options.startOffset = value;\n\n        if (restart) {\n            this.play({ startOffset: value });\n        } else if (this._state === SoundState.Paused) {\n            this._currentTimeChangedWhilePaused = true;\n        }\n    }\n\n    public get _outNode(): Nullable<AudioNode> {\n        return this._volumeNode;\n    }\n\n    /** @internal */\n    public set loop(value: boolean) {\n        this._options.loop = value;\n        this._mediaElement.loop = value;\n    }\n\n    /** @internal */\n    public get startTime(): number {\n        if (this._state === SoundState.Stopped) {\n            return 0;\n        }\n\n        return this._enginePlayTime;\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this.stop();\n\n        this._sourceNode?.disconnect(this._volumeNode);\n        this._sourceNode = null;\n\n        this._mediaElement.removeEventListener(\"error\", this._onError);\n        this._mediaElement.removeEventListener(\"ended\", this._onEnded);\n        this._mediaElement.removeEventListener(\"canplaythrough\", this._onCanPlayThrough);\n\n        for (const source of Array.from(this._mediaElement.children)) {\n            this._mediaElement.removeChild(source);\n        }\n\n        this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n        this.engine.userGestureObservable.removeCallback(this._onUserGesture);\n    }\n\n    /** @internal */\n    public play(options: Partial<IStreamingSoundPlayOptions> = {}): void {\n        if (this._state === SoundState.Started) {\n            return;\n        }\n\n        if (options.loop !== undefined) {\n            this._options.loop = options.loop;\n        }\n        this._mediaElement.loop = this._options.loop;\n\n        let startOffset = options.startOffset;\n\n        if (this._currentTimeChangedWhilePaused) {\n            startOffset = this._options.startOffset;\n            this._currentTimeChangedWhilePaused = false;\n        } else if (this._state === SoundState.Paused) {\n            startOffset = this.currentTime;\n        }\n\n        if (startOffset && startOffset > 0) {\n            this._mediaElement.currentTime = startOffset;\n        }\n\n        // Only override the volume when explicitly provided so resuming a paused instance keeps its current volume.\n        if (options.volume !== undefined) {\n            this._volumeNode.gain.value = options.volume;\n        }\n\n        this._play();\n    }\n\n    /** @internal */\n    public pause(): void {\n        if (this._state !== SoundState.Starting && this._state !== SoundState.Started) {\n            return;\n        }\n\n        this._setState(SoundState.Paused);\n        this._enginePauseTime += this.engine.currentTime - this._enginePlayTime;\n\n        this._mediaElement.pause();\n    }\n\n    /** @internal */\n    public resume(options: Partial<IStreamingSoundPlayOptions> = {}): void {\n        if (this._state === SoundState.Paused) {\n            this.play(options);\n        } else if (this._currentTimeChangedWhilePaused) {\n            this.play(options);\n        }\n    }\n\n    /** @internal */\n    public override stop(): void {\n        if (this._state === SoundState.Stopped) {\n            return;\n        }\n\n        this._stop();\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioStreamingSoundInstance\";\n    }\n\n    protected override _connect(node: AbstractAudioNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        // If the wrapped node is not available now, it will be connected later by the sound's subgraph.\n        if (node instanceof _WebAudioStreamingSound && node._inNode) {\n            this._outNode?.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: AbstractAudioNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node instanceof _WebAudioStreamingSound && node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    private _initFromMediaElement(mediaElement: HTMLMediaElement): void {\n        Tools.SetCorsBehavior(mediaElement.currentSrc, mediaElement);\n\n        mediaElement.controls = false;\n        mediaElement.loop = this._options.loop;\n        mediaElement.preload = \"auto\";\n\n        mediaElement.addEventListener(\"canplaythrough\", this._onCanPlayThrough, { once: true });\n        mediaElement.addEventListener(\"ended\", this._onEnded, { once: true });\n        mediaElement.addEventListener(\"error\", this._onError, { once: true });\n\n        mediaElement.load();\n\n        this._sourceNode = new MediaElementAudioSourceNode(this._sound._audioContext, { mediaElement: mediaElement });\n        this._sourceNode.connect(this._volumeNode);\n\n        if (!this._connect(this._sound)) {\n            throw new Error(\"Connect failed\");\n        }\n\n        this._mediaElement = mediaElement;\n    }\n\n    private _initFromUrl(url: string): void {\n        // Apply any WebRequest URL modifiers (but do NOT download the content — the <audio> element streams natively).\n        // Custom headers cannot be forwarded to HTMLMediaElement; _GetUrlForStreaming logs a warning if any are present.\n        const resolvedUrl = WebRequest.IsCustomRequestAvailable ? _GetUrlForStreaming(_CleanUrl(url)) : _CleanUrl(url);\n        const audio = new Audio(resolvedUrl);\n        this._initFromMediaElement(audio);\n    }\n\n    private _initFromUrls(urls: string[]): void {\n        const audio = new Audio();\n\n        // Apply any WebRequest URL modifiers to each candidate URL (but do NOT download the content —\n        // the <audio> element picks the first compatible format and streams natively).\n        // Custom headers cannot be forwarded to HTMLMediaElement; _GetUrlForStreaming logs a warning if any are present.\n        for (const url of urls) {\n            const source = document.createElement(\"source\");\n            source.src = WebRequest.IsCustomRequestAvailable ? _GetUrlForStreaming(_CleanUrl(url)) : _CleanUrl(url);\n            audio.appendChild(source);\n        }\n\n        this._initFromMediaElement(audio);\n    }\n\n    private _onCanPlayThrough: () => void = () => {\n        this._isReady = true;\n        this._resolveIsReadyPromise(this._mediaElement);\n        this.onReadyObservable.notifyObservers(this);\n    };\n\n    private _onEnded: () => void = () => {\n        this._setState(SoundState.Stopped);\n    };\n\n    private _onError: (reason: any) => void = (reason: any) => {\n        this._setState(SoundState.FailedToStart);\n        this.onErrorObservable.notifyObservers(reason);\n        this._rejectIsReadyPromise(reason);\n        this.dispose();\n    };\n\n    private _onEngineStateChanged = () => {\n        if (this.engine.state !== \"running\") {\n            return;\n        }\n\n        if (this._options.loop && this.state === SoundState.Starting) {\n            this.play();\n        }\n\n        this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n    };\n\n    private _onUserGesture = () => {\n        this.play();\n    };\n\n    private _play(): void {\n        this._setState(SoundState.Starting);\n\n        if (!this._isReady) {\n            this._playWhenReady();\n            return;\n        }\n\n        if (this._state !== SoundState.Starting) {\n            return;\n        }\n\n        if (this.engine.state === \"running\") {\n            const result = this._mediaElement.play();\n\n            this._enginePlayTime = this.engine.currentTime;\n            this._setState(SoundState.Started);\n\n            // It's possible that the play() method fails on Safari, even if the audio engine's state is \"running\".\n            // This occurs when the audio context is paused by the system and resumed automatically by the audio engine\n            // without a user interaction (e.g. when the Vision Pro exits and reenters immersive mode).\n            // eslint-disable-next-line github/no-then\n            result.catch(() => {\n                this._setState(SoundState.FailedToStart);\n\n                if (this._options.loop) {\n                    this.engine.userGestureObservable.addOnce(this._onUserGesture);\n                }\n            });\n        } else if (this._options.loop) {\n            this.engine.stateChangedObservable.add(this._onEngineStateChanged);\n        } else {\n            this.stop();\n            this._setState(SoundState.FailedToStart);\n        }\n    }\n\n    private _playWhenReady(): void {\n        this._isReadyPromise\n            // eslint-disable-next-line github/no-then\n            .then(() => {\n                this._play();\n            })\n            // eslint-disable-next-line github/no-then\n            .catch(() => {\n                Logger.Error(\"Streaming sound instance failed to play\");\n                this._setState(SoundState.FailedToStart);\n            });\n    }\n\n    private _rejectIsReadyPromise: (reason?: any) => void;\n    private _resolveIsReadyPromise: (mediaElement: HTMLMediaElement) => void;\n\n    private _stop(): void {\n        this._mediaElement.pause();\n        this._onEnded();\n        this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n    }\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IStaticSoundOptions, type IStaticSoundPlayOptions, type IStaticSoundStopOptions } from \"../AudioV2/abstractAudio/staticSound\";\r\nimport { type IStreamingSoundOptions } from \"../AudioV2/abstractAudio/streamingSound\";\r\nimport { _HasSpatialAudioOptions, _SpatialAudioDefaults } from \"../AudioV2/abstractAudio/subProperties/abstractSpatialAudio\";\r\nimport { type IAudioParameterRampOptions, AudioParameterRampShape } from \"../AudioV2/audioParameter\";\r\nimport { SoundState } from \"../AudioV2/soundState\";\r\nimport { _WebAudioSoundSource } from \"../AudioV2/webAudio/webAudioSoundSource\";\r\nimport { _WebAudioStaticSound } from \"../AudioV2/webAudio/webAudioStaticSound\";\r\nimport { _WebAudioStreamingSound } from \"../AudioV2/webAudio/webAudioStreamingSound\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { _RetryWithInterval } from \"../Misc/timingTools\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AudioEngine } from \"./audioEngine.pure\";\r\nimport { type ISoundOptions } from \"./Interfaces/ISoundOptions\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport { RegisterAudioSceneComponent } from \"./audioSceneComponent.pure\";\r\n\r\nconst TmpRampOptions: IAudioParameterRampOptions = {\r\n    duration: 0,\r\n    shape: AudioParameterRampShape.Linear,\r\n};\r\n\r\nconst TmpPlayOptions: Partial<IStaticSoundPlayOptions> = {\r\n    duration: 0,\r\n    startOffset: 0,\r\n    waitTime: 0,\r\n};\r\n\r\nconst TmpStopOptions: IStaticSoundStopOptions = {\r\n    waitTime: 0,\r\n};\r\n\r\nfunction D2r(degrees: number): number {\r\n    return (degrees * Math.PI) / 180;\r\n}\r\n\r\nfunction R2d(radians: number): number {\r\n    return (radians * 180) / Math.PI;\r\n}\r\n\r\n/**\r\n * Defines a sound that can be played in the application.\r\n * The sound can either be an ambient track or a simple sound played in reaction to a user action.\r\n * @see https://doc.babylonjs.com/legacy/audio\r\n */\r\nexport class Sound {\r\n    /**\r\n     * The name of the sound in the scene.\r\n     */\r\n    public get name(): string {\r\n        return this._soundV2.name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._soundV2.name = value;\r\n    }\r\n\r\n    /**\r\n     * Does the sound autoplay once loaded.\r\n     */\r\n    public get autoplay(): boolean {\r\n        return this._soundV2 instanceof _WebAudioSoundSource ? true : this._optionsV2.autoplay!;\r\n    }\r\n\r\n    public set autoplay(value: boolean) {\r\n        this._optionsV2.autoplay = value;\r\n    }\r\n\r\n    /**\r\n     * Does the sound loop after it finishes playing once.\r\n     */\r\n    public get loop(): boolean {\r\n        return this._soundV2 instanceof _WebAudioSoundSource ? true : this._soundV2.loop;\r\n    }\r\n\r\n    public set loop(value: boolean) {\r\n        if (this._soundV2 instanceof _WebAudioSoundSource) {\r\n            return;\r\n        }\r\n\r\n        if (this._soundV2) {\r\n            this._soundV2.loop = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Does the sound use a custom attenuation curve to simulate the falloff\r\n     * happening when the source gets further away from the camera.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-your-own-custom-attenuation-function\r\n     */\r\n    public useCustomAttenuation: boolean = false;\r\n    /**\r\n     * The sound track id this sound belongs to.\r\n     */\r\n    public soundTrackId: number = -1;\r\n    /**\r\n     * Is this sound currently played.\r\n     */\r\n    public get isPlaying(): boolean {\r\n        return this._soundV2 instanceof _WebAudioSoundSource ? true : this._soundV2?.state === SoundState.Started || (!this.isReady() && this._optionsV2.autoplay!);\r\n    }\r\n\r\n    /**\r\n     * Is this sound currently paused.\r\n     */\r\n    public get isPaused(): boolean {\r\n        return this._soundV2 instanceof _WebAudioSoundSource ? false : this._soundV2.state === SoundState.Paused;\r\n    }\r\n\r\n    /**\r\n     * Define the reference distance the sound should be heard perfectly.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public refDistance: number = 1;\r\n    /**\r\n     * Define the roll off factor of spatial sounds.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public rolloffFactor: number = 1;\r\n    /**\r\n     * Define the max distance the sound should be heard (intensity just became 0 at this point).\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public get maxDistance(): number {\r\n        return this._optionsV2.spatialMaxDistance || 100;\r\n    }\r\n    public set maxDistance(value: number) {\r\n        this._optionsV2.spatialMaxDistance = value;\r\n\r\n        if (this.useCustomAttenuation) {\r\n            return;\r\n        }\r\n\r\n        if (this._soundV2) {\r\n            this._initSpatial();\r\n            this._soundV2.spatial.maxDistance = value;\r\n        }\r\n    }\r\n    /**\r\n     * Define the distance attenuation model the sound will follow.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public get distanceModel(): \"linear\" | \"inverse\" | \"exponential\" {\r\n        return this._optionsV2.spatialDistanceModel || \"linear\";\r\n    }\r\n    public set distanceModel(value: \"linear\" | \"inverse\" | \"exponential\") {\r\n        this._optionsV2.spatialDistanceModel = value;\r\n\r\n        if (this._soundV2) {\r\n            this._initSpatial();\r\n            this._soundV2.spatial.distanceModel = value;\r\n        }\r\n    }\r\n    /**\r\n     * @internal\r\n     * Back Compat\r\n     **/\r\n    public onended: () => any;\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the sound.\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /**\r\n     * Observable event when the current playing sound finishes.\r\n     */\r\n    public onEndedObservable = new Observable<Sound>();\r\n\r\n    /**\r\n     * Gets the current time for the sound.\r\n     */\r\n    public get currentTime(): number {\r\n        return this._soundV2 instanceof _WebAudioSoundSource ? this._soundV2.engine.currentTime : this._soundV2.currentTime;\r\n    }\r\n\r\n    /**\r\n     * Does this sound enables spatial sound.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public get spatialSound(): boolean {\r\n        return this._soundV2?._isSpatial ?? false;\r\n    }\r\n\r\n    /**\r\n     * Does this sound enables spatial sound.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public set spatialSound(newValue: boolean) {\r\n        if (this._soundV2) {\r\n            if (newValue) {\r\n                this._initSpatial();\r\n            } else {\r\n                this._soundV2._isSpatial = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _localDirection: Vector3 = new Vector3(1, 0, 0);\r\n    private _volume: number = 1;\r\n    private _isReadyToPlay: boolean = false;\r\n    private _isDirectional: boolean = false;\r\n    private _readyToPlayCallback: () => any;\r\n    private _scene: Scene;\r\n    private _connectedTransformNode: Nullable<TransformNode>;\r\n    private _customAttenuationFunction: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number;\r\n    private _registerFunc: Nullable<(connectedMesh: TransformNode) => void>;\r\n    private _isOutputConnected = false;\r\n    private _url: Nullable<string> = null;\r\n\r\n    private readonly _optionsV2: Partial<IStaticSoundOptions>;\r\n    private readonly _soundV2: _WebAudioSoundSource | _WebAudioStaticSound | _WebAudioStreamingSound;\r\n    private _onReadyObservable: Nullable<Observable<void>> = null;\r\n\r\n    private get _onReady(): Observable<void> {\r\n        if (!this._onReadyObservable) {\r\n            this._onReadyObservable = new Observable<void>();\r\n        }\r\n        return this._onReadyObservable;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"AudioSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * Create a sound and attach it to a scene\r\n     * @param name Name of your sound\r\n     * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer, it also works with MediaStreams and AudioBuffers\r\n     * @param scene defines the scene the sound belongs to\r\n     * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played\r\n     * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming\r\n     */\r\n    constructor(name: string, urlOrArrayBuffer: any, scene?: Nullable<Scene>, readyToPlayCallback: Nullable<() => void> = null, options?: ISoundOptions) {\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this._scene = scene;\r\n        RegisterAudioSceneComponent(Sound);\r\n        Sound._SceneComponentInitialization(scene);\r\n        this._readyToPlayCallback = readyToPlayCallback || (() => {});\r\n\r\n        // Default custom attenuation function is a linear attenuation\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        this._customAttenuationFunction = (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => {\r\n            if (currentDistance < maxDistance) {\r\n                return currentVolume * (1 - currentDistance / maxDistance);\r\n            } else {\r\n                return 0;\r\n            }\r\n        };\r\n\r\n        options = options || {};\r\n\r\n        const optionsV2: Partial<IStaticSoundOptions> = {\r\n            analyzerEnabled: false,\r\n            autoplay: false, // `false` for now, but will be set to given option later\r\n            duration: options.length || 0,\r\n            loop: options.loop || false,\r\n            loopEnd: 0,\r\n            loopStart: 0,\r\n            outBus: null,\r\n            outBusAutoDefault: false,\r\n            playbackRate: options.playbackRate || 1,\r\n            pitch: 0,\r\n            skipCodecCheck: options.skipCodecCheck || false,\r\n            spatialDistanceModel: options.distanceModel,\r\n            spatialEnabled: options.spatialSound,\r\n            spatialMaxDistance: options.maxDistance,\r\n            spatialMinDistance: options.refDistance,\r\n            spatialRolloffFactor: options.rolloffFactor,\r\n            stereoEnabled: false,\r\n            startOffset: options.offset || 0,\r\n            volume: options.volume ?? 1,\r\n        };\r\n        this._volume = options.volume ?? 1;\r\n\r\n        if (_HasSpatialAudioOptions(optionsV2)) {\r\n            optionsV2.spatialAutoUpdate = false;\r\n            optionsV2.spatialConeInnerAngle = _SpatialAudioDefaults.coneInnerAngle;\r\n            optionsV2.spatialConeOuterAngle = _SpatialAudioDefaults.coneOuterAngle;\r\n            optionsV2.spatialConeOuterVolume = _SpatialAudioDefaults.coneOuterVolume;\r\n            optionsV2.spatialMinUpdateTime = 0;\r\n            optionsV2.spatialOrientation = _SpatialAudioDefaults.orientation.clone();\r\n            optionsV2.spatialPanningModel = (this._scene.headphone ? \"HRTF\" : \"equalpower\") as \"equalpower\" | \"HRTF\";\r\n            optionsV2.spatialPosition = _SpatialAudioDefaults.position.clone();\r\n            optionsV2.spatialRotation = _SpatialAudioDefaults.rotation.clone();\r\n            optionsV2.spatialRotationQuaternion = _SpatialAudioDefaults.rotationQuaternion.clone();\r\n\r\n            if (optionsV2.spatialMaxDistance === undefined) {\r\n                optionsV2.spatialMaxDistance = 100;\r\n            }\r\n        }\r\n\r\n        this._optionsV2 = { ...optionsV2 };\r\n        this._optionsV2.autoplay = options.autoplay || false;\r\n\r\n        this.useCustomAttenuation = options.useCustomAttenuation ?? false;\r\n        if (this.useCustomAttenuation) {\r\n            optionsV2.spatialMaxDistance = Number.MAX_VALUE;\r\n            optionsV2.volume = 0;\r\n        }\r\n\r\n        let streaming = options?.streaming || false;\r\n\r\n        const audioEngine = AbstractEngine.audioEngine;\r\n        if (!audioEngine) {\r\n            return;\r\n        }\r\n\r\n        const audioEngineV2 = (AbstractEngine.audioEngine as AudioEngine)._v2;\r\n\r\n        const createSoundV2 = () => {\r\n            if (streaming) {\r\n                const streamingOptionsV2: Partial<IStreamingSoundOptions> = {\r\n                    preloadCount: 0,\r\n                    ...optionsV2,\r\n                };\r\n\r\n                const sound = new _WebAudioStreamingSound(name, audioEngineV2, streamingOptionsV2);\r\n\r\n                // eslint-disable-next-line github/no-then\r\n                void sound._initAsync(urlOrArrayBuffer, optionsV2).then(() => {\r\n                    // eslint-disable-next-line github/no-then\r\n                    void sound.preloadInstancesAsync(1).then(this._onReadyToPlay);\r\n                });\r\n\r\n                return sound;\r\n            } else {\r\n                const sound = new _WebAudioStaticSound(name, audioEngineV2, optionsV2);\r\n\r\n                // eslint-disable-next-line github/no-then\r\n                void sound._initAsync(urlOrArrayBuffer, optionsV2).then(this._onReadyToPlay);\r\n\r\n                return sound;\r\n            }\r\n        };\r\n\r\n        // If no parameter is passed then the setAudioBuffer should be called to prepare the sound.\r\n        if (!urlOrArrayBuffer) {\r\n            // Create the sound but don't call _initAsync on it, yet. Call it later when `setAudioBuffer` is called.\r\n            this._soundV2 = new _WebAudioStaticSound(name, audioEngineV2, optionsV2);\r\n        } else if (typeof urlOrArrayBuffer === \"string\") {\r\n            this._url = urlOrArrayBuffer;\r\n            this._soundV2 = createSoundV2();\r\n        } else if (urlOrArrayBuffer instanceof ArrayBuffer) {\r\n            streaming = false;\r\n            this._soundV2 = createSoundV2();\r\n        } else if (urlOrArrayBuffer instanceof HTMLMediaElement) {\r\n            streaming = true;\r\n            this._soundV2 = createSoundV2();\r\n        } else if (urlOrArrayBuffer instanceof MediaStream) {\r\n            const node = new MediaStreamAudioSourceNode(audioEngineV2._audioContext, { mediaStream: urlOrArrayBuffer });\r\n            this._soundV2 = new _WebAudioSoundSource(name, node, audioEngineV2, optionsV2);\r\n            // eslint-disable-next-line github/no-then\r\n            void this._soundV2._initAsync(optionsV2).then(this._onReadyToPlay);\r\n        } else if (urlOrArrayBuffer instanceof AudioBuffer) {\r\n            streaming = false;\r\n            this._soundV2 = createSoundV2();\r\n        } else if (Array.isArray(urlOrArrayBuffer)) {\r\n            this._soundV2 = createSoundV2();\r\n        }\r\n\r\n        if (!this._soundV2) {\r\n            Logger.Error(\"Parameter must be a URL to the sound, an Array of URLs (.mp3 & .ogg) or an ArrayBuffer of the sound.\");\r\n            return;\r\n        }\r\n\r\n        if (!(this._soundV2 instanceof _WebAudioSoundSource)) {\r\n            this._soundV2.onEndedObservable.add(this._onended);\r\n        }\r\n    }\r\n\r\n    private _onReadyToPlay = () => {\r\n        this._scene.mainSoundTrack.addSound(this);\r\n        this._isReadyToPlay = true;\r\n        this._readyToPlayCallback();\r\n\r\n        if (this._onReadyObservable) {\r\n            this._onReadyObservable.notifyObservers();\r\n        }\r\n\r\n        if (this._optionsV2.autoplay) {\r\n            this.play();\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Release the sound and its associated resources\r\n     */\r\n    public dispose() {\r\n        if (this.isPlaying) {\r\n            this.stop();\r\n        }\r\n        this._isReadyToPlay = false;\r\n        if (this.soundTrackId === -1) {\r\n            this._scene.mainSoundTrack.removeSound(this);\r\n        } else if (this._scene.soundTracks) {\r\n            this._scene.soundTracks[this.soundTrackId].removeSound(this);\r\n        }\r\n\r\n        if (this._connectedTransformNode && this._registerFunc) {\r\n            this._connectedTransformNode.unregisterAfterWorldMatrixUpdate(this._registerFunc);\r\n            this._connectedTransformNode = null;\r\n        }\r\n\r\n        this._soundV2.dispose();\r\n    }\r\n\r\n    /**\r\n     * Gets if the sounds is ready to be played or not.\r\n     * @returns true if ready, otherwise false\r\n     */\r\n    public isReady(): boolean {\r\n        return this._isReadyToPlay;\r\n    }\r\n\r\n    /**\r\n     * Get the current class name.\r\n     * @returns current class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"Sound\";\r\n    }\r\n\r\n    /**\r\n     * Sets the data of the sound from an audiobuffer\r\n     * @param audioBuffer The audioBuffer containing the data\r\n     */\r\n    public setAudioBuffer(audioBuffer: AudioBuffer): void {\r\n        if (this._isReadyToPlay) {\r\n            return;\r\n        }\r\n\r\n        if (this._soundV2 instanceof _WebAudioStaticSound) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            this._soundV2._initAsync(audioBuffer, this._optionsV2).then(this._onReadyToPlay);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the current sounds options such as maxdistance, loop...\r\n     * @param options A JSON object containing values named as the object properties\r\n     */\r\n    public updateOptions(options: ISoundOptions): void {\r\n        if (options) {\r\n            this.loop = options.loop ?? this.loop;\r\n            this.maxDistance = options.maxDistance ?? this.maxDistance;\r\n            this.useCustomAttenuation = options.useCustomAttenuation ?? this.useCustomAttenuation;\r\n            this.rolloffFactor = options.rolloffFactor ?? this.rolloffFactor;\r\n            this.refDistance = options.refDistance ?? this.refDistance;\r\n            this.distanceModel = options.distanceModel ?? this.distanceModel;\r\n            if (options.playbackRate !== undefined) {\r\n                this.setPlaybackRate(options.playbackRate);\r\n            }\r\n            if (options.spatialSound !== undefined) {\r\n                this.spatialSound = options.spatialSound;\r\n            }\r\n            if (options.volume !== undefined) {\r\n                this.setVolume(options.volume);\r\n            }\r\n            if (this._soundV2 instanceof _WebAudioStaticSound) {\r\n                let updated = false;\r\n                if (options.offset !== undefined) {\r\n                    this._optionsV2.startOffset = options.offset;\r\n                    updated = true;\r\n                }\r\n                if (options.length !== undefined) {\r\n                    this._soundV2.duration = options.length;\r\n                    updated = true;\r\n                }\r\n                if (updated && this.isPaused) {\r\n                    this.stop();\r\n                }\r\n            }\r\n\r\n            this._updateSpatialParameters();\r\n        }\r\n    }\r\n\r\n    private _updateSpatialParameters() {\r\n        if (!this.spatialSound) {\r\n            return;\r\n        }\r\n\r\n        const spatial = this._soundV2.spatial;\r\n\r\n        if (this.useCustomAttenuation) {\r\n            // Disable WebAudio attenuation.\r\n            spatial.distanceModel = \"linear\";\r\n            spatial.minDistance = 1;\r\n            spatial.maxDistance = Number.MAX_VALUE;\r\n            spatial.rolloffFactor = 1;\r\n            spatial.panningModel = \"equalpower\";\r\n        } else {\r\n            spatial.distanceModel = this.distanceModel;\r\n            spatial.minDistance = this.refDistance;\r\n            spatial.maxDistance = this.maxDistance;\r\n            spatial.rolloffFactor = this.rolloffFactor;\r\n            spatial.panningModel = this._optionsV2.spatialPanningModel || \"equalpower\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Switch the panning model to HRTF:\r\n     * Renders a stereo output of higher quality than equalpower — it uses a convolution with measured impulse responses from human subjects.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public switchPanningModelToHRTF() {\r\n        if (this.spatialSound) {\r\n            this._initSpatial();\r\n            this._soundV2.spatial.panningModel = \"HRTF\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Switch the panning model to Equal Power:\r\n     * Represents the equal-power panning algorithm, generally regarded as simple and efficient. equalpower is the default value.\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-a-spatial-3d-sound\r\n     */\r\n    public switchPanningModelToEqualPower() {\r\n        if (this.spatialSound) {\r\n            this._initSpatial();\r\n            this._soundV2.spatial.panningModel = \"equalpower\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Connect this sound to a sound track audio node like gain...\r\n     * @param soundTrackAudioNode the sound track audio node to connect to\r\n     */\r\n    public connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void {\r\n        const outputNode = this._soundV2._outNode;\r\n        if (outputNode) {\r\n            if (this._isOutputConnected) {\r\n                outputNode.disconnect();\r\n            }\r\n            outputNode.connect(soundTrackAudioNode);\r\n            this._isOutputConnected = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Transform this sound into a directional source\r\n     * @param coneInnerAngle Size of the inner cone in degree\r\n     * @param coneOuterAngle Size of the outer cone in degree\r\n     * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)\r\n     */\r\n    public setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void {\r\n        if (coneOuterAngle < coneInnerAngle) {\r\n            Logger.Error(\"setDirectionalCone(): outer angle of the cone must be superior or equal to the inner angle.\");\r\n            return;\r\n        }\r\n\r\n        this._optionsV2.spatialConeInnerAngle = D2r(coneInnerAngle);\r\n        this._optionsV2.spatialConeOuterAngle = D2r(coneOuterAngle);\r\n        this._optionsV2.spatialConeOuterVolume = coneOuterGain;\r\n\r\n        this._initSpatial();\r\n        this._soundV2.spatial.coneInnerAngle = this._optionsV2.spatialConeInnerAngle;\r\n        this._soundV2.spatial.coneOuterAngle = this._optionsV2.spatialConeOuterAngle;\r\n        this._soundV2.spatial.coneOuterVolume = coneOuterGain;\r\n\r\n        this._isDirectional = true;\r\n\r\n        if (this.isPlaying && this.loop) {\r\n            this.stop();\r\n            this.play(0, this._optionsV2.startOffset, this._optionsV2.duration);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the inner angle for the directional cone.\r\n     */\r\n    public get directionalConeInnerAngle(): number {\r\n        return R2d(typeof this._optionsV2.spatialConeInnerAngle === \"number\" ? this._optionsV2.spatialConeInnerAngle : _SpatialAudioDefaults.coneInnerAngle);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the inner angle for the directional cone.\r\n     */\r\n    public set directionalConeInnerAngle(value: number) {\r\n        value = D2r(value);\r\n\r\n        if (value != this._optionsV2.spatialConeInnerAngle) {\r\n            if (this.directionalConeOuterAngle < value) {\r\n                Logger.Error(\"directionalConeInnerAngle: outer angle of the cone must be superior or equal to the inner angle.\");\r\n                return;\r\n            }\r\n            this._optionsV2.spatialConeInnerAngle = value;\r\n            if (this.spatialSound) {\r\n                this._initSpatial();\r\n                this._soundV2.spatial.coneInnerAngle = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the outer angle for the directional cone.\r\n     */\r\n    public get directionalConeOuterAngle(): number {\r\n        return R2d(typeof this._optionsV2.spatialConeOuterAngle === \"number\" ? this._optionsV2.spatialConeOuterAngle : _SpatialAudioDefaults.coneOuterAngle);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the outer angle for the directional cone.\r\n     */\r\n    public set directionalConeOuterAngle(value: number) {\r\n        value = D2r(value);\r\n\r\n        if (value != this._optionsV2.spatialConeOuterAngle) {\r\n            if (value < this.directionalConeInnerAngle) {\r\n                Logger.Error(\"directionalConeOuterAngle: outer angle of the cone must be superior or equal to the inner angle.\");\r\n                return;\r\n            }\r\n            this._optionsV2.spatialConeOuterAngle = value;\r\n            if (this.spatialSound) {\r\n                this._initSpatial();\r\n                this._soundV2.spatial.coneOuterAngle = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the position of the emitter if spatial sound is enabled\r\n     * @param newPosition Defines the new position\r\n     */\r\n    public setPosition(newPosition: Vector3): void {\r\n        if (this._optionsV2.spatialPosition && newPosition.equals(this._optionsV2.spatialPosition)) {\r\n            return;\r\n        }\r\n        if (!this._optionsV2.spatialPosition) {\r\n            this._optionsV2.spatialPosition = Vector3.Zero();\r\n        }\r\n        this._optionsV2.spatialPosition.copyFrom(newPosition);\r\n        if (this.spatialSound && !isNaN(newPosition.x) && !isNaN(newPosition.y) && !isNaN(newPosition.z)) {\r\n            this._initSpatial();\r\n            this._soundV2.spatial.position = newPosition;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the local direction of the emitter if spatial sound is enabled\r\n     * @param newLocalDirection Defines the new local direction\r\n     */\r\n    public setLocalDirectionToMesh(newLocalDirection: Vector3): void {\r\n        this._localDirection = newLocalDirection;\r\n\r\n        if (this._connectedTransformNode && this.isPlaying) {\r\n            this._updateDirection();\r\n        }\r\n    }\r\n\r\n    private _updateDirection() {\r\n        if (!this._connectedTransformNode || !this.spatialSound) {\r\n            return;\r\n        }\r\n\r\n        const mat = this._connectedTransformNode.getWorldMatrix();\r\n        const direction = Vector3.TransformNormal(this._localDirection, mat);\r\n        direction.normalize();\r\n\r\n        this._initSpatial();\r\n        this._soundV2.spatial.orientation = direction;\r\n    }\r\n\r\n    private _initSpatial() {\r\n        this._soundV2._isSpatial = true;\r\n\r\n        if (this._optionsV2.spatialDistanceModel === undefined) {\r\n            this._optionsV2.spatialDistanceModel = \"linear\";\r\n            this._soundV2.spatial.distanceModel = \"linear\";\r\n        }\r\n\r\n        if (this._optionsV2.spatialMaxDistance === undefined) {\r\n            this._optionsV2.spatialMaxDistance = 100;\r\n            this._soundV2.spatial.maxDistance = 100;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public updateDistanceFromListener() {\r\n        if (this._soundV2._outNode && this._connectedTransformNode && this.useCustomAttenuation && this._scene.activeCamera) {\r\n            const distance = this._scene.audioListenerPositionProvider\r\n                ? this._connectedTransformNode.position.subtract(this._scene.audioListenerPositionProvider()).length()\r\n                : this._connectedTransformNode.getDistanceToCamera(this._scene.activeCamera);\r\n            this._soundV2.volume = this._customAttenuationFunction(this._volume, distance, this.maxDistance, this.refDistance, this.rolloffFactor);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a new custom attenuation function for the sound.\r\n     * @param callback Defines the function used for the attenuation\r\n     * @see https://doc.babylonjs.com/legacy/audio#creating-your-own-custom-attenuation-function\r\n     */\r\n    public setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void {\r\n        this._customAttenuationFunction = callback;\r\n    }\r\n\r\n    /**\r\n     * Play the sound\r\n     * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.\r\n     * @param offset (optional) Start the sound at a specific time in seconds\r\n     * @param length (optional) Sound duration (in seconds)\r\n     */\r\n    public play(time?: number, offset?: number, length?: number): void {\r\n        const audioEngine = AbstractEngine.audioEngine;\r\n        audioEngine?.unlock();\r\n\r\n        // WebAudio sound sources have no `play` function because they are always playing.\r\n        if (this._soundV2 instanceof _WebAudioSoundSource) {\r\n            return;\r\n        }\r\n\r\n        if (this._isReadyToPlay && this._scene.audioEnabled) {\r\n            // The sound can only resume from pause when the `time`, `offset` and `length` args are not set.\r\n            if (this._soundV2.state === SoundState.Paused && (time !== undefined || offset !== undefined || length !== undefined)) {\r\n                this._soundV2.stop();\r\n            }\r\n\r\n            try {\r\n                TmpPlayOptions.duration = length || 0;\r\n                TmpPlayOptions.startOffset = offset !== undefined ? offset || this._optionsV2.startOffset! : this._optionsV2.startOffset!;\r\n                TmpPlayOptions.waitTime = time || 0;\r\n                TmpPlayOptions.loop = undefined;\r\n                TmpPlayOptions.loopStart = undefined;\r\n                TmpPlayOptions.loopEnd = undefined;\r\n                TmpPlayOptions.volume = undefined;\r\n\r\n                if (audioEngine?.unlocked) {\r\n                    this._soundV2.play(TmpPlayOptions);\r\n                } else {\r\n                    // Wait a bit for FF as context seems late to be ready.\r\n                    setTimeout(() => {\r\n                        (this._soundV2 as _WebAudioStaticSound | _WebAudioStreamingSound).play(TmpPlayOptions);\r\n                    }, 500);\r\n                }\r\n            } catch (ex) {\r\n                Logger.Error(\"Error while trying to play audio: \" + this.name + \", \" + ex.message);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onended = () => {\r\n        if (this.onended) {\r\n            this.onended();\r\n        }\r\n        this.onEndedObservable.notifyObservers(this);\r\n    };\r\n\r\n    /**\r\n     * Stop the sound\r\n     * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.\r\n     */\r\n    public stop(time?: number): void {\r\n        if (!this._soundV2) {\r\n            return;\r\n        }\r\n\r\n        // WebAudio sound sources have no `stop` function because they are always playing.\r\n        if (this._soundV2 instanceof _WebAudioSoundSource) {\r\n            return;\r\n        }\r\n\r\n        TmpStopOptions.waitTime = time || 0;\r\n        this._soundV2.stop(TmpStopOptions);\r\n    }\r\n\r\n    /**\r\n     * Put the sound in pause\r\n     */\r\n    public pause(): void {\r\n        if (!this._soundV2) {\r\n            return;\r\n        }\r\n\r\n        // WebAudio sound sources have no `pause` function because they are always playing.\r\n        if (this._soundV2 instanceof _WebAudioSoundSource) {\r\n            return;\r\n        }\r\n\r\n        this._soundV2.pause();\r\n    }\r\n\r\n    /**\r\n     * Sets a dedicated volume for this sounds\r\n     * @param newVolume Define the new volume of the sound\r\n     * @param time Define time for gradual change to new volume\r\n     */\r\n    public setVolume(newVolume: number, time?: number): void {\r\n        if (!this.isReady()) {\r\n            this._onReady.addOnce(() => {\r\n                this.setVolume(newVolume, time);\r\n            });\r\n            return;\r\n        }\r\n\r\n        TmpRampOptions.duration = time || 0;\r\n        this._soundV2.setVolume(newVolume, TmpRampOptions);\r\n        this._volume = newVolume;\r\n    }\r\n\r\n    /**\r\n     * Set the sound play back rate\r\n     * @param newPlaybackRate Define the playback rate the sound should be played at\r\n     */\r\n    public setPlaybackRate(newPlaybackRate: number): void {\r\n        if (this._soundV2 instanceof _WebAudioStaticSound) {\r\n            this._soundV2.playbackRate = newPlaybackRate;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the sound play back rate.\r\n     * @returns the  play back rate of the sound\r\n     */\r\n    public getPlaybackRate(): number {\r\n        if (this._soundV2 instanceof _WebAudioStaticSound) {\r\n            return this._soundV2.playbackRate;\r\n        }\r\n\r\n        return 1;\r\n    }\r\n\r\n    /**\r\n     * Gets the volume of the sound.\r\n     * @returns the volume of the sound\r\n     */\r\n    public getVolume(): number {\r\n        return this._volume;\r\n    }\r\n\r\n    /**\r\n     * Attach the sound to a dedicated mesh\r\n     * @param transformNode The transform node to connect the sound with\r\n     * @see https://doc.babylonjs.com/legacy/audio#attaching-a-sound-to-a-mesh\r\n     */\r\n    public attachToMesh(transformNode: TransformNode): void {\r\n        if (this._connectedTransformNode && this._registerFunc) {\r\n            this._connectedTransformNode.unregisterAfterWorldMatrixUpdate(this._registerFunc);\r\n            this._registerFunc = null;\r\n        }\r\n        this._connectedTransformNode = transformNode;\r\n        if (!this.spatialSound) {\r\n            this.spatialSound = true;\r\n            if (this.isPlaying && this.loop) {\r\n                this.stop();\r\n                this.play(0, this._optionsV2.startOffset, this._optionsV2.duration);\r\n            }\r\n        }\r\n        this._onRegisterAfterWorldMatrixUpdate(this._connectedTransformNode);\r\n        this._registerFunc = (transformNode: TransformNode) => this._onRegisterAfterWorldMatrixUpdate(transformNode);\r\n        this._connectedTransformNode.registerAfterWorldMatrixUpdate(this._registerFunc);\r\n    }\r\n\r\n    /**\r\n     * Detach the sound from the previously attached mesh\r\n     * @see https://doc.babylonjs.com/legacy/audio#attaching-a-sound-to-a-mesh\r\n     */\r\n    public detachFromMesh() {\r\n        if (this._connectedTransformNode && this._registerFunc) {\r\n            this._connectedTransformNode.unregisterAfterWorldMatrixUpdate(this._registerFunc);\r\n            this._registerFunc = null;\r\n            this._connectedTransformNode = null;\r\n        }\r\n    }\r\n\r\n    private _onRegisterAfterWorldMatrixUpdate(node: TransformNode): void {\r\n        if (!(<any>node).getBoundingInfo) {\r\n            this.setPosition(node.absolutePosition);\r\n        } else {\r\n            const mesh = node as AbstractMesh;\r\n            const boundingInfo = mesh.getBoundingInfo();\r\n            this.setPosition(boundingInfo.boundingSphere.centerWorld);\r\n        }\r\n        if (this._isDirectional && this.isPlaying) {\r\n            this._updateDirection();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the current sound in the scene.\r\n     * @returns the new sound clone\r\n     */\r\n    public clone(): Nullable<Sound> {\r\n        if (!(this._soundV2 instanceof _WebAudioStaticSound)) {\r\n            return null;\r\n        }\r\n\r\n        const currentOptions: ISoundOptions = {\r\n            autoplay: this.autoplay,\r\n            loop: this.loop,\r\n            volume: this._volume,\r\n            spatialSound: this.spatialSound,\r\n            maxDistance: this.maxDistance,\r\n            useCustomAttenuation: this.useCustomAttenuation,\r\n            rolloffFactor: this.rolloffFactor,\r\n            refDistance: this.refDistance,\r\n            distanceModel: this.distanceModel,\r\n        };\r\n        const clonedSound = new Sound(this.name + \"_cloned\", this._soundV2.buffer, this._scene, null, currentOptions);\r\n        (clonedSound._optionsV2 as any) = this._optionsV2;\r\n        if (this.useCustomAttenuation) {\r\n            clonedSound.setAttenuationFunction(this._customAttenuationFunction);\r\n        }\r\n        return clonedSound;\r\n    }\r\n\r\n    /**\r\n     * Gets the current underlying audio buffer containing the data\r\n     * @returns the audio buffer\r\n     */\r\n    public getAudioBuffer(): Nullable<AudioBuffer> {\r\n        if (this._soundV2 instanceof _WebAudioStaticSound) {\r\n            return this._soundV2.buffer._audioBuffer;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the WebAudio AudioBufferSourceNode, lets you keep track of and stop instances of this Sound.\r\n     * @returns the source node\r\n     */\r\n    public getSoundSource(): Nullable<AudioBufferSourceNode> {\r\n        // return this._soundSource;\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the WebAudio GainNode, gives you precise control over the gain of instances of this Sound.\r\n     * @returns the gain node\r\n     */\r\n    public getSoundGain(): Nullable<GainNode> {\r\n        return this._soundV2._outNode as GainNode;\r\n    }\r\n\r\n    /**\r\n     * Serializes the Sound in a JSON representation\r\n     * @returns the JSON representation of the sound\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {\r\n            name: this.name,\r\n            url: this._url,\r\n            autoplay: this.autoplay,\r\n            loop: this.loop,\r\n            volume: this._volume,\r\n            spatialSound: this.spatialSound,\r\n            maxDistance: this.maxDistance,\r\n            rolloffFactor: this.rolloffFactor,\r\n            refDistance: this.refDistance,\r\n            distanceModel: this.distanceModel,\r\n            playbackRate: this.getPlaybackRate(),\r\n            panningModel: this._soundV2.spatial.panningModel,\r\n            soundTrackId: this.soundTrackId,\r\n            metadata: this.metadata,\r\n        };\r\n\r\n        if (this.spatialSound) {\r\n            if (this._connectedTransformNode) {\r\n                serializationObject.connectedMeshId = this._connectedTransformNode.id;\r\n            }\r\n\r\n            serializationObject.position = this._soundV2.spatial.position.asArray();\r\n            serializationObject.refDistance = this.refDistance;\r\n            serializationObject.distanceModel = this.distanceModel;\r\n\r\n            serializationObject.isDirectional = this._isDirectional;\r\n            serializationObject.localDirectionToMesh = this._localDirection.asArray();\r\n            serializationObject.coneInnerAngle = this.directionalConeInnerAngle;\r\n            serializationObject.coneOuterAngle = this.directionalConeOuterAngle;\r\n            serializationObject.coneOuterGain = this._soundV2.spatial.coneOuterVolume;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse a JSON representation of a sound to instantiate in a given scene\r\n     * @param parsedSound Define the JSON representation of the sound (usually coming from the serialize method)\r\n     * @param scene Define the scene the new parsed sound should be created in\r\n     * @param rootUrl Define the rooturl of the load in case we need to fetch relative dependencies\r\n     * @param sourceSound Define a sound place holder if do not need to instantiate a new one\r\n     * @returns the newly parsed sound\r\n     */\r\n    public static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound {\r\n        const soundName = parsedSound.name;\r\n        let soundUrl;\r\n        if (parsedSound.url) {\r\n            soundUrl = rootUrl + parsedSound.url;\r\n        } else {\r\n            soundUrl = rootUrl + soundName;\r\n        }\r\n        const options = {\r\n            autoplay: parsedSound.autoplay,\r\n            loop: parsedSound.loop,\r\n            volume: parsedSound.volume,\r\n            spatialSound: parsedSound.spatialSound,\r\n            maxDistance: parsedSound.maxDistance,\r\n            rolloffFactor: parsedSound.rolloffFactor,\r\n            refDistance: parsedSound.refDistance,\r\n            distanceModel: parsedSound.distanceModel,\r\n            playbackRate: parsedSound.playbackRate,\r\n        };\r\n        let newSound: Sound;\r\n        if (!sourceSound) {\r\n            newSound = new Sound(\r\n                soundName,\r\n                soundUrl,\r\n                scene,\r\n                () => {\r\n                    scene.removePendingData(newSound);\r\n                },\r\n                options\r\n            );\r\n            scene.addPendingData(newSound);\r\n        } else {\r\n            const setBufferAndRun = () => {\r\n                _RetryWithInterval(\r\n                    () => sourceSound._isReadyToPlay,\r\n                    () => {\r\n                        const audioBuffer = sourceSound.getAudioBuffer();\r\n                        if (audioBuffer) {\r\n                            newSound.setAudioBuffer(audioBuffer);\r\n                        }\r\n                        newSound._isReadyToPlay = true;\r\n                        if (newSound.autoplay) {\r\n                            newSound.play(0, sourceSound._optionsV2.startOffset, sourceSound._optionsV2.duration);\r\n                        }\r\n                    },\r\n                    undefined,\r\n                    300\r\n                );\r\n            };\r\n            newSound = new Sound(soundName, new ArrayBuffer(0), scene, null, options);\r\n            setBufferAndRun();\r\n        }\r\n        if (parsedSound.position) {\r\n            const soundPosition = Vector3.FromArray(parsedSound.position);\r\n            newSound.setPosition(soundPosition);\r\n        }\r\n        if (parsedSound.isDirectional) {\r\n            newSound.setDirectionalCone(parsedSound.coneInnerAngle || 360, parsedSound.coneOuterAngle || 360, parsedSound.coneOuterGain || 0);\r\n            if (parsedSound.localDirectionToMesh) {\r\n                const localDirectionToMesh = Vector3.FromArray(parsedSound.localDirectionToMesh);\r\n                newSound.setLocalDirectionToMesh(localDirectionToMesh);\r\n            }\r\n        }\r\n        if (parsedSound.connectedMeshId) {\r\n            const connectedMesh = scene.getMeshById(parsedSound.connectedMeshId);\r\n            if (connectedMesh) {\r\n                newSound.attachToMesh(connectedMesh);\r\n            }\r\n        }\r\n        if (parsedSound.metadata) {\r\n            newSound.metadata = parsedSound.metadata;\r\n        }\r\n        return newSound;\r\n    }\r\n}\r\n\r\n// Register Class Name\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sound.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSound(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.Sound\", Sound);\r\n}\r\n","import { type Sound } from \"../Audio/sound\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\n/**\r\n * Wraps one or more Sound objects and selects one with random weight for playback.\r\n */\r\nexport class WeightedSound {\r\n    /** When true a Sound will be selected and played when the current playing Sound completes. */\r\n    public loop: boolean = false;\r\n    private _coneInnerAngle: number = 360;\r\n    private _coneOuterAngle: number = 360;\r\n    private _volume: number = 1;\r\n    /** A Sound is currently playing. */\r\n    public isPlaying: boolean = false;\r\n    /** A Sound is currently paused. */\r\n    public isPaused: boolean = false;\r\n\r\n    private _sounds: Sound[] = [];\r\n    private _weights: number[] = [];\r\n    private _currentIndex?: number;\r\n\r\n    /**\r\n     * Creates a new WeightedSound from the list of sounds given.\r\n     * @param loop When true a Sound will be selected and played when the current playing Sound completes.\r\n     * @param sounds Array of Sounds that will be selected from.\r\n     * @param weights Array of number values for selection weights; length must equal sounds, values will be normalized to 1\r\n     */\r\n    constructor(loop: boolean, sounds: Sound[], weights: number[]) {\r\n        if (sounds.length !== weights.length) {\r\n            throw new Error(\"Sounds length does not equal weights length\");\r\n        }\r\n\r\n        this.loop = loop;\r\n        this._weights = weights;\r\n        // Normalize the weights\r\n        let weightSum = 0;\r\n        for (const weight of weights) {\r\n            weightSum += weight;\r\n        }\r\n        const invWeightSum = weightSum > 0 ? 1 / weightSum : 0;\r\n        for (let i = 0; i < this._weights.length; i++) {\r\n            this._weights[i] *= invWeightSum;\r\n        }\r\n        this._sounds = sounds;\r\n        for (const sound of this._sounds) {\r\n            sound.onEndedObservable.add(() => {\r\n                this._onended();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The size of cone in degrees for a directional sound in which there will be no attenuation.\r\n     */\r\n    public get directionalConeInnerAngle(): number {\r\n        return this._coneInnerAngle;\r\n    }\r\n\r\n    /**\r\n     * The size of cone in degrees for a directional sound in which there will be no attenuation.\r\n     */\r\n    public set directionalConeInnerAngle(value: number) {\r\n        if (value !== this._coneInnerAngle) {\r\n            if (this._coneOuterAngle < value) {\r\n                Logger.Error(\"directionalConeInnerAngle: outer angle of the cone must be superior or equal to the inner angle.\");\r\n                return;\r\n            }\r\n\r\n            this._coneInnerAngle = value;\r\n            for (const sound of this._sounds) {\r\n                sound.directionalConeInnerAngle = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Size of cone in degrees for a directional sound outside of which there will be no sound.\r\n     * Listener angles between innerAngle and outerAngle will falloff linearly.\r\n     */\r\n    public get directionalConeOuterAngle(): number {\r\n        return this._coneOuterAngle;\r\n    }\r\n\r\n    /**\r\n     * Size of cone in degrees for a directional sound outside of which there will be no sound.\r\n     * Listener angles between innerAngle and outerAngle will falloff linearly.\r\n     */\r\n    public set directionalConeOuterAngle(value: number) {\r\n        if (value !== this._coneOuterAngle) {\r\n            if (value < this._coneInnerAngle) {\r\n                Logger.Error(\"directionalConeOuterAngle: outer angle of the cone must be superior or equal to the inner angle.\");\r\n                return;\r\n            }\r\n\r\n            this._coneOuterAngle = value;\r\n            for (const sound of this._sounds) {\r\n                sound.directionalConeOuterAngle = value;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Playback volume.\r\n     */\r\n    public get volume(): number {\r\n        return this._volume;\r\n    }\r\n\r\n    /**\r\n     * Playback volume.\r\n     */\r\n    public set volume(value: number) {\r\n        if (value !== this._volume) {\r\n            for (const sound of this._sounds) {\r\n                sound.setVolume(value);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onended() {\r\n        if (this._currentIndex !== undefined) {\r\n            this._sounds[this._currentIndex].autoplay = false;\r\n        }\r\n        if (this.loop && this.isPlaying) {\r\n            this.play();\r\n        } else {\r\n            this.isPlaying = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Suspend playback\r\n     */\r\n    public pause() {\r\n        if (this.isPlaying) {\r\n            this.isPaused = true;\r\n            if (this._currentIndex !== undefined) {\r\n                this._sounds[this._currentIndex].pause();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stop playback\r\n     */\r\n    public stop() {\r\n        this.isPlaying = false;\r\n        if (this._currentIndex !== undefined) {\r\n            this._sounds[this._currentIndex].stop();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Start playback.\r\n     * @param startOffset Position the clip head at a specific time in seconds.\r\n     */\r\n    public play(startOffset?: number) {\r\n        if (!this.isPaused) {\r\n            this.stop();\r\n            const randomValue = Math.random();\r\n            let total = 0;\r\n            for (let i = 0; i < this._weights.length; i++) {\r\n                total += this._weights[i];\r\n                if (randomValue <= total) {\r\n                    this._currentIndex = i;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        const sound = this._sounds[this._currentIndex ?? 0];\r\n        if (sound.isReady()) {\r\n            sound.play(0, this.isPaused ? undefined : startOffset);\r\n        } else {\r\n            sound.autoplay = true;\r\n        }\r\n        this.isPlaying = true;\r\n        this.isPaused = false;\r\n    }\r\n}\r\n","import { AudioNodeType } from \"./abstractAudioNode\";\nimport { type IAbstractAudioOutNodeOptions, AbstractAudioOutNode } from \"./abstractAudioOutNode\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\n\n/** @internal */\nexport interface IAbstractAudioBusOptions extends IAbstractAudioOutNodeOptions {}\n\n/**\n * Abstract class representing an audio bus with volume control.\n *\n * An audio bus is a node in the audio graph that can have multiple inputs and outputs. It is typically used to group\n * sounds together and apply effects to them.\n */\nexport abstract class AbstractAudioBus extends AbstractAudioOutNode {\n    protected constructor(name: string, engine: AudioEngineV2) {\n        super(name, engine, AudioNodeType.HAS_INPUTS_AND_OUTPUTS);\n    }\n}\n","import { type Nullable } from \"../../types\";\nimport { type IAbstractAudioBusOptions, AbstractAudioBus } from \"./abstractAudioBus\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\nimport { type MainAudioBus } from \"./mainAudioBus\";\nimport { type AbstractSpatialAudio, type ISpatialAudioOptions } from \"./subProperties/abstractSpatialAudio\";\nimport { type AbstractStereoAudio, type IStereoAudioOptions } from \"./subProperties/abstractStereoAudio\";\n\n// NB: Secondary audio buses will be added later.\nexport type PrimaryAudioBus = MainAudioBus | AudioBus;\n\n/**\n * Options for creating an audio bus.\n */\nexport interface IAudioBusOptions extends IAbstractAudioBusOptions, ISpatialAudioOptions, IStereoAudioOptions {\n    /**\n     * The output bus of the audio bus. Defaults to the audio engine's default main bus.\n     * @see {@link AudioEngineV2.defaultMainBus}\n     */\n    outBus: PrimaryAudioBus;\n}\n\n/**\n * Abstract class for an audio bus that has spatial audio and stereo output capabilities.\n *\n * Instances of this class can be connected to other audio buses.\n *\n * Audio buses are created by the {@link CreateAudioBusAsync} function.\n */\nexport abstract class AudioBus extends AbstractAudioBus {\n    private readonly _spatialAutoUpdate: boolean = true;\n    private readonly _spatialMinUpdateTime: number = 0;\n    private _outBus: Nullable<PrimaryAudioBus> = null;\n    private _spatial: Nullable<AbstractSpatialAudio> = null;\n\n    protected constructor(name: string, engine: AudioEngineV2, options: Partial<IAudioBusOptions>) {\n        super(name, engine);\n\n        if (typeof options.spatialAutoUpdate === \"boolean\") {\n            this._spatialAutoUpdate = options.spatialAutoUpdate;\n        }\n\n        if (typeof options.spatialMinUpdateTime === \"number\") {\n            this._spatialMinUpdateTime = options.spatialMinUpdateTime;\n        }\n    }\n\n    /**\n     * The output bus of the audio bus. Defaults to the audio engine's default main bus.\n     */\n    public get outBus(): Nullable<PrimaryAudioBus> {\n        return this._outBus;\n    }\n\n    public set outBus(outBus: Nullable<PrimaryAudioBus>) {\n        if (this._outBus === outBus) {\n            return;\n        }\n\n        if (this._outBus) {\n            this._outBus.onDisposeObservable.removeCallback(this._onOutBusDisposed);\n\n            if (!this._disconnect(this._outBus)) {\n                throw new Error(\"Disconnect failed\");\n            }\n        }\n\n        this._outBus = outBus;\n\n        if (this._outBus) {\n            this._outBus.onDisposeObservable.add(this._onOutBusDisposed);\n\n            if (!this._connect(this._outBus)) {\n                throw new Error(\"Connect failed\");\n            }\n        }\n    }\n\n    /**\n     * The spatial audio features.\n     */\n    public get spatial(): AbstractSpatialAudio {\n        if (this._spatial) {\n            return this._spatial;\n        }\n        return this._initSpatialProperty();\n    }\n\n    /**\n     * The stereo features of the audio bus.\n     */\n    public abstract readonly stereo: AbstractStereoAudio;\n\n    /**\n     * Releases associated resources.\n     */\n    public override dispose(): void {\n        super.dispose();\n\n        this._spatial?.dispose();\n        this._spatial = null;\n\n        if (this._outBus) {\n            this._outBus.onDisposeObservable.removeCallback(this._onOutBusDisposed);\n        }\n        this._outBus = null;\n    }\n\n    protected abstract _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio;\n\n    protected _initSpatialProperty(): AbstractSpatialAudio {\n        return (this._spatial = this._createSpatialProperty(this._spatialAutoUpdate, this._spatialMinUpdateTime));\n    }\n\n    private _onOutBusDisposed = () => {\n        this.outBus = this.engine.defaultMainBus;\n    };\n}\n","import { AbstractAudioBus, type IAbstractAudioBusOptions } from \"./abstractAudioBus\";\nimport { type AudioEngineV2 } from \"./audioEngineV2\";\n\n/**\n * Options for creating a main audio bus.\n */\nexport interface IMainAudioBusOptions extends IAbstractAudioBusOptions {}\n\n/**\n * Abstract class representing a main audio bus.\n *\n * Main audio buses are the last bus in the audio graph.\n *\n * Unlike {@link AudioBus} instances, `MainAudioBus` instances have no spatial audio and stereo output capabilities,\n * and they cannot be connected downstream to another audio bus. They only connect downstream to the audio engine's\n * main output.\n *\n * Main audio buses are created by the {@link CreateMainAudioBusAsync} function.\n */\nexport abstract class MainAudioBus extends AbstractAudioBus {\n    protected constructor(name: string, engine: AudioEngineV2) {\n        super(name, engine);\n    }\n}\n","/**\n * The shape of the audio ramp used to set an audio parameter's value, such as a sound's volume.\n */\nexport const enum AudioParameterRampShape {\n    /**\n     * The ramp is linear.\n     */\n    Linear = \"linear\",\n    /**\n     * The ramp is exponential.\n     */\n    Exponential = \"exponential\",\n    /**\n     * The ramp is logarithmic.\n     */\n    Logarithmic = \"logarithmic\",\n    /**\n     * No ramp is used; the value is set immediately.\n     */\n    None = \"none\",\n}\n\n/**\n * Options for ramping an audio parameter's value.\n */\nexport interface IAudioParameterRampOptions {\n    /**\n     * The ramp time, in seconds. Must be greater than 0. Defaults to 0.01 seconds.\n     * The audio parameter's value will reach the target value at the end of the duration.\n     */\n    duration: number;\n    /**\n     * The shape of the ramp to use for the parameter change. Defaults to {@link AudioParameterRampShape.Linear}.\n     */\n    shape: AudioParameterRampShape;\n}\n","/**\n * The state of a sound.\n */\nexport const enum SoundState {\n    /**\n     * The sound is waiting for its instances to stop.\n     */\n    Stopping,\n    /**\n     * The sound is stopped.\n     */\n    Stopped,\n    /**\n     * The sound is waiting for its instances to start.\n     */\n    Starting,\n    /**\n     * The sound has started playing.\n     */\n    Started,\n    /**\n     * The sound failed to start, most likely due to the user not interacting with the page, yet.\n     */\n    FailedToStart,\n    /**\n     * The sound is paused.\n     */\n    Paused,\n}\n","export const enum SpatialAudioAttachmentType {\n    Position = 1,\n    Rotation = 2,\n    PositionAndRotation = 3,\n}\n","import { type Nullable } from \"core/types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type IAudioBusOptions, AudioBus } from \"../abstractAudio/audioBus\";\nimport { _HasSpatialAudioOptions, type AbstractSpatialAudio } from \"../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode, type IWebAudioSuperNode } from \"./webAudioNode\";\n\n/** @internal */\nexport class _WebAudioBus extends AudioBus implements IWebAudioSuperNode {\n    private _stereo: Nullable<_StereoAudio> = null;\n\n    protected _subGraph: _WebAudioBusAndSoundSubGraph;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public constructor(name: string, engine: _WebAudioEngine, options: Partial<IAudioBusOptions>) {\n        super(name, engine, options);\n\n        this._subGraph = new _WebAudioBus._SubGraph(this);\n    }\n\n    /** @internal */\n    public async _initAsync(options: Partial<IAudioBusOptions>): Promise<void> {\n        if (options.outBus) {\n            this.outBus = options.outBus;\n        } else {\n            await this.engine.isReadyPromise;\n            this.outBus = this.engine.defaultMainBus;\n        }\n\n        await this._subGraph.initAsync(options);\n\n        if (_HasSpatialAudioOptions(options)) {\n            this._initSpatialProperty();\n        }\n\n        this.engine._addNode(this);\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this._stereo = null;\n\n        this.engine._removeNode(this);\n    }\n\n    /** @internal */\n    public get _inNode() {\n        return this._subGraph._inNode;\n    }\n\n    /** @internal */\n    public get _outNode() {\n        return this._subGraph._outNode;\n    }\n\n    /** @internal */\n    public override get stereo(): _StereoAudio {\n        return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioBus\";\n    }\n\n    protected override _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio {\n        return new _SpatialWebAudio(this._subGraph, autoUpdate, minUpdateTime);\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n        protected override _owner: _WebAudioBus;\n\n        protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._downstreamNodes ?? null;\n        }\n\n        protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._upstreamNodes ?? null;\n        }\n    };\n}\n","import { type Nullable } from \"../../types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type IMainAudioBusOptions, MainAudioBus } from \"../abstractAudio/mainAudioBus\";\nimport { _WebAudioBaseSubGraph } from \"./subNodes/webAudioBaseSubGraph\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode, type IWebAudioSuperNode } from \"./webAudioNode\";\n\n/** @internal */\nexport class _WebAudioMainBus extends MainAudioBus implements IWebAudioSuperNode {\n    protected _subGraph: _WebAudioBaseSubGraph;\n\n    /** @internal */\n    public override readonly engine: _WebAudioEngine;\n\n    /** @internal */\n    public constructor(name: string, engine: _WebAudioEngine) {\n        super(name, engine);\n\n        this._subGraph = new _WebAudioMainBus._SubGraph(this);\n    }\n\n    /** @internal */\n    public async _initAsync(options: Partial<IMainAudioBusOptions>): Promise<void> {\n        await this._subGraph.initAsync(options);\n\n        if (this.engine.mainOut) {\n            if (!this._connect(this.engine.mainOut)) {\n                throw new Error(\"Connect failed\");\n            }\n        }\n\n        this.engine._addMainBus(this);\n    }\n\n    /** @internal */\n    public override dispose(): void {\n        super.dispose();\n\n        this.engine._removeMainBus(this);\n    }\n\n    /** @internal */\n    public get _inNode() {\n        return this._subGraph._inNode;\n    }\n\n    /** @internal */\n    public get _outNode() {\n        return this._subGraph._outNode;\n    }\n\n    protected override _connect(node: IWebAudioInNode): boolean {\n        const connected = super._connect(node);\n\n        if (!connected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.connect(node._inNode);\n        }\n\n        return true;\n    }\n\n    protected override _disconnect(node: IWebAudioInNode): boolean {\n        const disconnected = super._disconnect(node);\n\n        if (!disconnected) {\n            return false;\n        }\n\n        if (node._inNode) {\n            this._outNode?.disconnect(node._inNode);\n        }\n\n        return true;\n    }\n\n    /** @internal */\n    public getClassName(): string {\n        return \"_WebAudioMainBus\";\n    }\n\n    private static _SubGraph = class extends _WebAudioBaseSubGraph {\n        protected override _owner: _WebAudioMainBus;\n\n        protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n            return this._owner._downstreamNodes ?? null;\n        }\n    };\n}\n","import { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { serialize, expandToProperty, serializeAsTexture } from \"../Misc/decorators\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\n/**\r\n * Interface for baked vertex animation texture, see BakedVertexAnimationManager\r\n * @since 5.0\r\n */\r\nexport interface IBakedVertexAnimationManager {\r\n    /**\r\n     * The vertex animation texture\r\n     */\r\n    texture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the edgesRenderer is active\r\n     */\r\n    isEnabled: boolean;\r\n\r\n    /**\r\n     * The animation parameters for the mesh. See setAnimationParameters()\r\n     */\r\n    animationParameters: Vector4;\r\n\r\n    /**\r\n     * The time counter, to pick the correct animation frame.\r\n     */\r\n    time: number;\r\n\r\n    /**\r\n     * Binds to the effect.\r\n     * @param effect The effect to bind to.\r\n     * @param useInstances True when it's an instance.\r\n     */\r\n    bind(effect: Effect, useInstances: boolean): void;\r\n\r\n    /**\r\n     * Sets animation parameters.\r\n     * @param startFrame The first frame of the animation.\r\n     * @param endFrame The last frame of the animation.\r\n     * @param offset The offset when starting the animation.\r\n     * @param speedFramesPerSecond The frame rate.\r\n     */\r\n    setAnimationParameters(startFrame: number, endFrame: number, offset: number, speedFramesPerSecond: number): void;\r\n\r\n    /**\r\n     * Disposes the resources of the manager.\r\n     * @param forceDisposeTextures - Forces the disposal of all textures.\r\n     */\r\n    dispose(forceDisposeTextures?: boolean): void;\r\n\r\n    /**\r\n     * Get the current class name useful for serialization or dynamic coding.\r\n     * @returns \"BakedVertexAnimationManager\"\r\n     */\r\n    getClassName(): string;\r\n}\r\n\r\n/**\r\n * This class is used to animate meshes using a baked vertex animation texture\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/baked_texture_animations\r\n * @since 5.0\r\n */\r\nexport class BakedVertexAnimationManager implements IBakedVertexAnimationManager {\r\n    private _scene: Scene;\r\n\r\n    private _texture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * The vertex animation texture\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markSubMeshesAsAttributesDirty\")\r\n    public accessor texture: Nullable<BaseTexture>;\r\n\r\n    private _isEnabled = true;\r\n    /**\r\n     * Enable or disable the vertex animation manager\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markSubMeshesAsAttributesDirty\")\r\n    public accessor isEnabled = true;\r\n\r\n    /**\r\n     * The animation parameters for the mesh. See setAnimationParameters()\r\n     */\r\n    @serialize()\r\n    public animationParameters: Vector4;\r\n\r\n    /**\r\n     * The time counter, to pick the correct animation frame.\r\n     */\r\n    @serialize()\r\n    public time = 0;\r\n\r\n    /**\r\n     * Creates a new BakedVertexAnimationManager\r\n     * @param scene defines the current scene\r\n     */\r\n    constructor(scene?: Nullable<Scene>) {\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this._scene = scene;\r\n        this.animationParameters = new Vector4(0, 0, 0, 30);\r\n    }\r\n\r\n    /** @internal */\r\n    public _markSubMeshesAsAttributesDirty(): void {\r\n        for (const mesh of this._scene.meshes) {\r\n            if ((<any>mesh).bakedVertexAnimationManager === this) {\r\n                mesh._markSubMeshesAsAttributesDirty();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds to the effect.\r\n     * @param effect The effect to bind to.\r\n     * @param useInstances True when it's an instance.\r\n     */\r\n    public bind(effect: Effect, useInstances = false): void {\r\n        if (!this._texture || !this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const size = this._texture.getSize();\r\n        effect.setFloat2(\"bakedVertexAnimationTextureSizeInverted\", 1.0 / size.width, 1.0 / size.height);\r\n        effect.setFloat(\"bakedVertexAnimationTime\", this.time);\r\n\r\n        if (!useInstances) {\r\n            effect.setVector4(\"bakedVertexAnimationSettings\", this.animationParameters);\r\n        }\r\n\r\n        effect.setTexture(\"bakedVertexAnimationTexture\", this._texture);\r\n    }\r\n\r\n    /**\r\n     * Clone the current manager\r\n     * @returns a new BakedVertexAnimationManager\r\n     */\r\n    public clone(): BakedVertexAnimationManager {\r\n        const copy = new BakedVertexAnimationManager(this._scene);\r\n        this.copyTo(copy);\r\n        return copy;\r\n    }\r\n\r\n    /**\r\n     * Sets animation parameters.\r\n     * @param startFrame The first frame of the animation.\r\n     * @param endFrame The last frame of the animation.\r\n     * @param offset The offset when starting the animation.\r\n     * @param speedFramesPerSecond The frame rate.\r\n     */\r\n    public setAnimationParameters(startFrame: number, endFrame: number, offset: number = 0, speedFramesPerSecond: number = 30): void {\r\n        this.animationParameters = new Vector4(startFrame, endFrame, offset, speedFramesPerSecond);\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources of the manager.\r\n     * @param forceDisposeTextures - Forces the disposal of all textures.\r\n     */\r\n    public dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            this._texture?.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the current class name useful for serialization or dynamic coding.\r\n     * @returns \"BakedVertexAnimationManager\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"BakedVertexAnimationManager\";\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current instance into another one.\r\n     * @param vatMap define the instance where to copy the info\r\n     */\r\n    public copyTo(vatMap: BakedVertexAnimationManager): void {\r\n        SerializationHelper.Clone(() => vatMap, this);\r\n    }\r\n\r\n    /**\r\n     * Serializes this vertex animation instance\r\n     * @returns - An object with the serialized instance.\r\n     */\r\n    public serialize(): any {\r\n        return SerializationHelper.Serialize(this);\r\n    }\r\n\r\n    /**\r\n     * Parses a vertex animation setting from a serialized object.\r\n     * @param source - Serialized object.\r\n     * @param scene Defines the scene we are parsing for\r\n     * @param rootUrl Defines the rootUrl to load from\r\n     */\r\n    public parse(source: any, scene: Scene, rootUrl: string): void {\r\n        SerializationHelper.Parse(() => this, source, scene, rootUrl);\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Constants } from \"../../Engines/constants\";\r\n\r\nimport { type ISize, Size } from \"../../Maths/math.size\";\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\r\n\r\n/**\r\n * Base class of all the textures in babylon.\r\n * It groups all the common properties required to work with Thin Engine.\r\n */\r\nexport class ThinTexture {\r\n    protected _wrapU = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    public get wrapU() {\r\n        return this._wrapU;\r\n    }\r\n\r\n    public set wrapU(value: number) {\r\n        this._wrapU = value;\r\n    }\r\n\r\n    protected _wrapV = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    public get wrapV() {\r\n        return this._wrapV;\r\n    }\r\n\r\n    public set wrapV(value: number) {\r\n        this._wrapV = value;\r\n    }\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    public wrapR = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n\r\n    /**\r\n     * With compliant hardware and browser (supporting anisotropic filtering)\r\n     * this defines the level of anisotropic filtering in the texture.\r\n     * The higher the better but the slower. This defaults to 4 as it seems to be the best tradeoff.\r\n     */\r\n    public anisotropicFilteringLevel = 4;\r\n\r\n    /**\r\n     * Define the current state of the loading sequence when in delayed load mode.\r\n     */\r\n    public delayLoadState = Constants.DELAYLOADSTATE_NONE;\r\n\r\n    /**\r\n     * How a texture is mapped.\r\n     * Unused in thin texture mode.\r\n     */\r\n    public get coordinatesMode(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Define if the texture is a cube texture or if false a 2d texture.\r\n     */\r\n    public get isCube(): boolean {\r\n        if (!this._texture) {\r\n            return false;\r\n        }\r\n\r\n        return this._texture.isCube;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected set isCube(value: boolean) {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n\r\n        this._texture.isCube = value;\r\n    }\r\n\r\n    /**\r\n     * Define if the texture is a 3d texture (webgl 2) or if false a 2d texture.\r\n     */\r\n    public get is3D(): boolean {\r\n        if (!this._texture) {\r\n            return false;\r\n        }\r\n\r\n        return this._texture.is3D;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected set is3D(value: boolean) {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n\r\n        this._texture.is3D = value;\r\n    }\r\n\r\n    /**\r\n     * Define if the texture is a 2d array texture (webgl 2) or if false a 2d texture.\r\n     */\r\n    public get is2DArray(): boolean {\r\n        if (!this._texture) {\r\n            return false;\r\n        }\r\n\r\n        return this._texture.is2DArray;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected set is2DArray(value: boolean) {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n\r\n        this._texture.is2DArray = value;\r\n    }\r\n\r\n    /**\r\n     * Get the class name of the texture.\r\n     * @returns \"ThinTexture\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"ThinTexture\";\r\n    }\r\n\r\n    /** @internal */\r\n    public _texture: Nullable<InternalTexture> = null;\r\n\r\n    protected _engine: Nullable<AbstractEngine> = null;\r\n\r\n    private _cachedSize: ISize = Size.Zero();\r\n    private _cachedBaseSize: ISize = Size.Zero();\r\n\r\n    private static _IsRenderTargetWrapper(texture: Nullable<InternalTexture> | Nullable<RenderTargetWrapper>): texture is RenderTargetWrapper {\r\n        return (texture as RenderTargetWrapper)?.shareDepth !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new ThinTexture.\r\n     * Base class of all the textures in babylon.\r\n     * This can be used as an internal texture wrapper in AbstractEngine to benefit from the cache\r\n     * @param internalTexture Define the internalTexture to wrap. You can also pass a RenderTargetWrapper, in which case the texture will be the render target's texture\r\n     */\r\n    constructor(internalTexture: Nullable<InternalTexture | RenderTargetWrapper>) {\r\n        this._texture = ThinTexture._IsRenderTargetWrapper(internalTexture) ? internalTexture.texture : internalTexture;\r\n        if (this._texture) {\r\n            this._engine = this._texture.getEngine();\r\n\r\n            this.wrapU = this._texture._cachedWrapU ?? this.wrapU;\r\n            this.wrapV = this._texture._cachedWrapV ?? this.wrapV;\r\n            this.wrapR = this._texture._cachedWrapR ?? this.wrapR;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get if the texture is ready to be used (downloaded, converted, mip mapped...).\r\n     * @returns true if fully ready\r\n     */\r\n    public isReady(): boolean {\r\n        if (this.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            this.delayLoad();\r\n            return false;\r\n        }\r\n\r\n        if (this._texture) {\r\n            return this._texture.isReady;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Triggers the load sequence in delayed load mode.\r\n     */\r\n    public delayLoad(): void {}\r\n\r\n    /**\r\n     * Get the underlying lower level texture from Babylon.\r\n     * @returns the internal texture\r\n     */\r\n    public getInternalTexture(): Nullable<InternalTexture> {\r\n        return this._texture;\r\n    }\r\n\r\n    /**\r\n     * Get the size of the texture.\r\n     * @returns the texture size.\r\n     */\r\n    public getSize(): ISize {\r\n        if (this._texture) {\r\n            if (this._texture.width) {\r\n                this._cachedSize.width = this._texture.width;\r\n                this._cachedSize.height = this._texture.height;\r\n                return this._cachedSize;\r\n            }\r\n\r\n            if (this._texture._size) {\r\n                this._cachedSize.width = this._texture._size;\r\n                this._cachedSize.height = this._texture._size;\r\n                return this._cachedSize;\r\n            }\r\n        }\r\n\r\n        return this._cachedSize;\r\n    }\r\n\r\n    /**\r\n     * Get the base size of the texture.\r\n     * It can be different from the size if the texture has been resized for POT for instance\r\n     * @returns the base size\r\n     */\r\n    public getBaseSize(): ISize {\r\n        if (!this.isReady() || !this._texture) {\r\n            this._cachedBaseSize.width = 0;\r\n            this._cachedBaseSize.height = 0;\r\n            return this._cachedBaseSize;\r\n        }\r\n\r\n        if (this._texture._size) {\r\n            this._cachedBaseSize.width = this._texture._size;\r\n            this._cachedBaseSize.height = this._texture._size;\r\n            return this._cachedBaseSize;\r\n        }\r\n\r\n        this._cachedBaseSize.width = this._texture.baseWidth;\r\n        this._cachedBaseSize.height = this._texture.baseHeight;\r\n        return this._cachedBaseSize;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _initialSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * Get the current sampling mode associated with the texture.\r\n     */\r\n    public get samplingMode(): number {\r\n        if (!this._texture) {\r\n            return this._initialSamplingMode;\r\n        }\r\n\r\n        return this._texture.samplingMode;\r\n    }\r\n\r\n    /**\r\n     * Update the sampling mode of the texture.\r\n     * Default is Trilinear mode.\r\n     *\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 1     | NEAREST_SAMPLINGMODE or NEAREST_NEAREST_MIPLINEAR  | Nearest is: mag = nearest, min = nearest, mip = linear |\r\n     * | 2     | BILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPNEAREST | Bilinear is: mag = linear, min = linear, mip = nearest |\r\n     * | 3     | TRILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPLINEAR | Trilinear is: mag = linear, min = linear, mip = linear |\r\n     * | 4     | NEAREST_NEAREST_MIPNEAREST |             |\r\n     * | 5    | NEAREST_LINEAR_MIPNEAREST |             |\r\n     * | 6    | NEAREST_LINEAR_MIPLINEAR |             |\r\n     * | 7    | NEAREST_LINEAR |             |\r\n     * | 8    | NEAREST_NEAREST |             |\r\n     * | 9   | LINEAR_NEAREST_MIPNEAREST |             |\r\n     * | 10   | LINEAR_NEAREST_MIPLINEAR |             |\r\n     * | 11   | LINEAR_LINEAR |             |\r\n     * | 12   | LINEAR_NEAREST |             |\r\n     *\r\n     *    > _mag_: magnification filter (close to the viewer)\r\n     *    > _min_: minification filter (far from the viewer)\r\n     *    > _mip_: filter used between mip map levels\r\n     *@param samplingMode Define the new sampling mode of the texture\r\n     *@param generateMipMaps Define if the texture should generate mip maps or not. Default is false.\r\n     */\r\n    public updateSamplingMode(samplingMode: number, generateMipMaps = false): void {\r\n        if (this._texture && this._engine) {\r\n            this._engine.updateTextureSamplingMode(samplingMode, this._texture, this._texture.generateMipMaps && generateMipMaps);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release and destroy the underlying lower level texture aka internalTexture.\r\n     */\r\n    public releaseInternalTexture(): void {\r\n        if (this._texture) {\r\n            this._texture.dispose();\r\n            this._texture = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public dispose(): void {\r\n        if (this._texture) {\r\n            this.releaseInternalTexture();\r\n            this._engine = null;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { type Observer, Observable } from \"../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Matrix, type Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { RandomGUID } from \"../../Misc/guid\";\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { ThinTexture } from \"./thinTexture\";\r\n\r\nimport { type Animation } from \"../../Animations/animation.pure\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\n\r\n/**\r\n * Base class of all the textures in babylon.\r\n * It groups all the common properties the materials, post process, lights... might need\r\n * in order to make a correct use of the texture.\r\n */\r\nexport class BaseTexture extends ThinTexture implements IAnimatable {\r\n    /**\r\n     * Default anisotropic filtering level for the application.\r\n     * It is set to 4 as a good tradeoff between perf and quality.\r\n     */\r\n    public static DEFAULT_ANISOTROPIC_FILTERING_LEVEL = 4;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the texture\r\n     */\r\n    @serialize()\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Define the name of the texture.\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * Define the display name of the texture, which is used as tree item name of the dedicated node in the inspector\r\n     */\r\n    @serialize()\r\n    public displayName: string;\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information.\r\n     */\r\n    @serialize()\r\n    public metadata: any = null;\r\n\r\n    /** @internal */\r\n    public _internalMetadata: any;\r\n\r\n    /**\r\n     * For internal use only. Please do not use.\r\n     */\r\n    public reservedDataStore: any = null;\r\n\r\n    @serialize(\"hasAlpha\")\r\n    private _hasAlpha = false;\r\n    /**\r\n     * Define if the texture is having a usable alpha value (can be use for transparency or glossiness for instance).\r\n     */\r\n    public set hasAlpha(value: boolean) {\r\n        if (this._hasAlpha === value) {\r\n            return;\r\n        }\r\n        this._hasAlpha = value;\r\n        if (this._scene) {\r\n            this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n    }\r\n    public get hasAlpha(): boolean {\r\n        return this._hasAlpha;\r\n    }\r\n\r\n    @serialize(\"getAlphaFromRGB\")\r\n    private _getAlphaFromRGB = false;\r\n    /**\r\n     * Defines if the alpha value should be determined via the rgb values.\r\n     * If true the luminance of the pixel might be used to find the corresponding alpha value.\r\n     */\r\n    public set getAlphaFromRGB(value: boolean) {\r\n        if (this._getAlphaFromRGB === value) {\r\n            return;\r\n        }\r\n        this._getAlphaFromRGB = value;\r\n        if (this._scene) {\r\n            this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n    }\r\n    public get getAlphaFromRGB(): boolean {\r\n        return this._getAlphaFromRGB;\r\n    }\r\n\r\n    /**\r\n     * Intensity or strength of the texture.\r\n     * It is commonly used by materials to fine tune the intensity of the texture\r\n     */\r\n    @serialize()\r\n    public level = 1;\r\n\r\n    @serialize(\"coordinatesIndex\")\r\n    protected _coordinatesIndex = 0;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the texture should try to reduce shader code if there is no UV manipulation.\r\n     * (ie. when texture.getTextureMatrix().isIdentityAs3x2() returns true)\r\n     */\r\n    @serialize()\r\n    public optimizeUVAllocation = true;\r\n\r\n    /**\r\n     * Define the UV channel to use starting from 0 and defaulting to 0.\r\n     * This is part of the texture as textures usually maps to one uv set.\r\n     */\r\n    public set coordinatesIndex(value: number) {\r\n        if (this._coordinatesIndex === value) {\r\n            return;\r\n        }\r\n        this._coordinatesIndex = value;\r\n        if (this._scene) {\r\n            this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n    }\r\n    public get coordinatesIndex(): number {\r\n        return this._coordinatesIndex;\r\n    }\r\n\r\n    @serialize(\"coordinatesMode\")\r\n    protected _coordinatesMode = Constants.TEXTURE_EXPLICIT_MODE;\r\n\r\n    /**\r\n     * How a texture is mapped.\r\n     *\r\n     * | Value | Type                                | Description |\r\n     * | ----- | ----------------------------------- | ----------- |\r\n     * | 0     | EXPLICIT_MODE                       |             |\r\n     * | 1     | SPHERICAL_MODE                      |             |\r\n     * | 2     | PLANAR_MODE                         |             |\r\n     * | 3     | CUBIC_MODE                          |             |\r\n     * | 4     | PROJECTION_MODE                     |             |\r\n     * | 5     | SKYBOX_MODE                         |             |\r\n     * | 6     | INVCUBIC_MODE                       |             |\r\n     * | 7     | EQUIRECTANGULAR_MODE                |             |\r\n     * | 8     | FIXED_EQUIRECTANGULAR_MODE          |             |\r\n     * | 9     | FIXED_EQUIRECTANGULAR_MIRRORED_MODE |             |\r\n     */\r\n    public override set coordinatesMode(value: number) {\r\n        if (this._coordinatesMode === value) {\r\n            return;\r\n        }\r\n        this._coordinatesMode = value;\r\n        if (this._scene) {\r\n            this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n    }\r\n    public override get coordinatesMode(): number {\r\n        return this._coordinatesMode;\r\n    }\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    @serialize()\r\n    public override get wrapU() {\r\n        return this._wrapU;\r\n    }\r\n    public override set wrapU(value: number) {\r\n        this._wrapU = value;\r\n    }\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    @serialize()\r\n    public override get wrapV() {\r\n        return this._wrapV;\r\n    }\r\n    public override set wrapV(value: number) {\r\n        this._wrapV = value;\r\n    }\r\n\r\n    /**\r\n     * | Value | Type               | Description |\r\n     * | ----- | ------------------ | ----------- |\r\n     * | 0     | CLAMP_ADDRESSMODE  |             |\r\n     * | 1     | WRAP_ADDRESSMODE   |             |\r\n     * | 2     | MIRROR_ADDRESSMODE |             |\r\n     */\r\n    @serialize()\r\n    public override wrapR = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n\r\n    /**\r\n     * With compliant hardware and browser (supporting anisotropic filtering)\r\n     * this defines the level of anisotropic filtering in the texture.\r\n     * The higher the better but the slower. This defaults to 4 as it seems to be the best tradeoff.\r\n     */\r\n    @serialize()\r\n    public override anisotropicFilteringLevel = BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL;\r\n\r\n    /** @internal */\r\n    public _isCube = false;\r\n    /**\r\n     * Define if the texture is a cube texture or if false a 2d texture.\r\n     */\r\n    @serialize()\r\n    public override get isCube(): boolean {\r\n        if (!this._texture) {\r\n            return this._isCube;\r\n        }\r\n\r\n        return this._texture.isCube;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected override set isCube(value: boolean) {\r\n        if (!this._texture) {\r\n            this._isCube = value;\r\n        } else {\r\n            this._texture.isCube = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Define if the texture is a 3d texture (webgl 2) or if false a 2d texture.\r\n     */\r\n    @serialize()\r\n    public override get is3D(): boolean {\r\n        if (!this._texture) {\r\n            return false;\r\n        }\r\n\r\n        return this._texture.is3D;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected override set is3D(value: boolean) {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n\r\n        this._texture.is3D = value;\r\n    }\r\n\r\n    /**\r\n     * Define if the texture is a 2d array texture (webgl 2) or if false a 2d texture.\r\n     */\r\n    @serialize()\r\n    public override get is2DArray(): boolean {\r\n        if (!this._texture) {\r\n            return false;\r\n        }\r\n\r\n        return this._texture.is2DArray;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected override set is2DArray(value: boolean) {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n\r\n        this._texture.is2DArray = value;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _gammaSpace = true;\r\n    /**\r\n     * Define if the texture contains data in gamma space (most of the png/jpg aside bump).\r\n     * HDR texture are usually stored in linear space.\r\n     * This only impacts the PBR and Background materials\r\n     */\r\n    @serialize()\r\n    public get gammaSpace(): boolean {\r\n        if (!this._texture) {\r\n            return this._gammaSpace;\r\n        } else {\r\n            if (this._texture._gammaSpace === null) {\r\n                this._texture._gammaSpace = this._gammaSpace;\r\n            }\r\n        }\r\n\r\n        return this._texture._gammaSpace && !this._texture._useSRGBBuffer;\r\n    }\r\n\r\n    public set gammaSpace(gamma: boolean) {\r\n        if (!this._texture) {\r\n            if (this._gammaSpace === gamma) {\r\n                return;\r\n            }\r\n\r\n            this._gammaSpace = gamma;\r\n        } else {\r\n            if (this._texture._gammaSpace === gamma) {\r\n                return;\r\n            }\r\n            this._texture._gammaSpace = gamma;\r\n        }\r\n\r\n        this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n            return mat.hasTexture(this);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets or sets whether or not the texture contains RGBD data.\r\n     */\r\n    public get isRGBD(): boolean {\r\n        return this._texture != null && this._texture._isRGBD;\r\n    }\r\n    public set isRGBD(value: boolean) {\r\n        if (value === this.isRGBD) {\r\n            return;\r\n        }\r\n\r\n        if (this._texture) {\r\n            this._texture._isRGBD = value;\r\n        }\r\n\r\n        this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n            return mat.hasTexture(this);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Is Z inverted in the texture (useful in a cube texture).\r\n     */\r\n    @serialize()\r\n    public invertZ = false;\r\n\r\n    /**\r\n     * Are mip maps generated for this texture or not.\r\n     */\r\n    public get noMipmap(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    @serialize()\r\n    public lodLevelInAlpha = false;\r\n\r\n    /**\r\n     * With prefiltered texture, defined the offset used during the prefiltering steps.\r\n     */\r\n    @serialize()\r\n    public get lodGenerationOffset(): number {\r\n        if (this._texture) {\r\n            return this._texture._lodGenerationOffset;\r\n        }\r\n\r\n        return 0.0;\r\n    }\r\n    public set lodGenerationOffset(value: number) {\r\n        if (this._texture) {\r\n            this._texture._lodGenerationOffset = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * With prefiltered texture, defined the scale used during the prefiltering steps.\r\n     */\r\n    @serialize()\r\n    public get lodGenerationScale(): number {\r\n        if (this._texture) {\r\n            return this._texture._lodGenerationScale;\r\n        }\r\n\r\n        return 0.0;\r\n    }\r\n    public set lodGenerationScale(value: number) {\r\n        if (this._texture) {\r\n            this._texture._lodGenerationScale = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * With prefiltered texture, defined if the specular generation is based on a linear ramp.\r\n     * By default we are using a log2 of the linear roughness helping to keep a better resolution for\r\n     * average roughness values.\r\n     */\r\n    @serialize()\r\n    public get linearSpecularLOD(): boolean {\r\n        if (this._texture) {\r\n            return this._texture._linearSpecularLOD;\r\n        }\r\n\r\n        return false;\r\n    }\r\n    public set linearSpecularLOD(value: boolean) {\r\n        if (this._texture) {\r\n            this._texture._linearSpecularLOD = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * In case a better definition than spherical harmonics is required for the diffuse part of the environment.\r\n     * You can set the irradiance texture to rely on a texture instead of the spherical approach.\r\n     * This texture need to have the same characteristics than its parent (Cube vs 2d, coordinates mode, Gamma/Linear, RGBD).\r\n     */\r\n    @serializeAsTexture()\r\n    public get irradianceTexture(): Nullable<BaseTexture> {\r\n        if (this._texture) {\r\n            return this._texture._irradianceTexture;\r\n        }\r\n\r\n        return null;\r\n    }\r\n    public set irradianceTexture(value: Nullable<BaseTexture>) {\r\n        if (this._texture) {\r\n            this._texture._irradianceTexture = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates the average direction of light in an environment map. This\r\n     * can be treated as the most dominant direction but it's magnitude also\r\n     * tells you something about how dominant that direction is.\r\n     */\r\n    /** @internal */\r\n    public _dominantDirection: Nullable<Vector3> = null;\r\n\r\n    /**\r\n     * Define if the texture is a render target.\r\n     */\r\n    @serialize()\r\n    public isRenderTarget = false;\r\n\r\n    /**\r\n     * Define the unique id of the texture in the scene.\r\n     */\r\n    public get uid(): string {\r\n        if (!this._uid) {\r\n            this._uid = RandomGUID();\r\n        }\r\n        return this._uid;\r\n    }\r\n\r\n    /** @internal */\r\n    public _prefiltered: boolean = false;\r\n    /** @internal */\r\n    public _forceSerialize: boolean = false;\r\n\r\n    /**\r\n     * Return a string representation of the texture.\r\n     * @returns the texture as a string\r\n     */\r\n    public override toString(): string {\r\n        return this.name;\r\n    }\r\n\r\n    /**\r\n     * Get the class name of the texture.\r\n     * @returns \"BaseTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"BaseTexture\";\r\n    }\r\n\r\n    /**\r\n     * Define the list of animation attached to the texture.\r\n     */\r\n    public animations: Animation[] = [];\r\n\r\n    /**\r\n     * An event triggered when the texture is disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<BaseTexture>();\r\n\r\n    private _onDisposeObserver: Nullable<Observer<BaseTexture>> = null;\r\n    /**\r\n     * Callback triggered when the texture has been disposed.\r\n     * Kept for back compatibility, you can use the onDisposeObservable instead.\r\n     */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    protected _scene: Nullable<Scene> = null;\r\n\r\n    /** @internal */\r\n    private _uid: Nullable<string> = null;\r\n\r\n    /**\r\n     * Define if the texture is preventing a material to render or not.\r\n     * If not and the texture is not ready, the engine will use a default black texture instead.\r\n     */\r\n    public get isBlocking(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    protected _loadingError: boolean = false;\r\n    protected _errorObject?: {\r\n        message?: string;\r\n        exception?: any;\r\n    };\r\n\r\n    /**\r\n     * Was there any loading error?\r\n     */\r\n    public get loadingError(): boolean {\r\n        return this._loadingError;\r\n    }\r\n\r\n    /**\r\n     * If a loading error occurred this object will be populated with information about the error.\r\n     */\r\n    public get errorObject():\r\n        | {\r\n              message?: string;\r\n              exception?: any;\r\n          }\r\n        | undefined {\r\n        return this._errorObject;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new BaseTexture.\r\n     * Base class of all the textures in babylon.\r\n     * It groups all the common properties the materials, post process, lights... might need\r\n     * in order to make a correct use of the texture.\r\n     * @param sceneOrEngine Define the scene or engine the texture belongs to\r\n     * @param internalTexture Define the internal texture associated with the texture\r\n     */\r\n    constructor(sceneOrEngine?: Nullable<Scene | AbstractEngine>, internalTexture: Nullable<InternalTexture> = null) {\r\n        super(null);\r\n\r\n        if (sceneOrEngine) {\r\n            if (BaseTexture._IsScene(sceneOrEngine)) {\r\n                this._scene = sceneOrEngine;\r\n            } else {\r\n                this._engine = sceneOrEngine;\r\n            }\r\n        } else {\r\n            this._scene = EngineStore.LastCreatedScene;\r\n        }\r\n\r\n        if (this._scene) {\r\n            this.uniqueId = this._scene.getUniqueId();\r\n            this._scene.addTexture(this);\r\n            this._engine = this._scene.getEngine();\r\n        }\r\n\r\n        this._texture = internalTexture;\r\n\r\n        this._uid = null;\r\n    }\r\n\r\n    /**\r\n     * Get the scene the texture belongs to.\r\n     * @returns the scene or null if undefined\r\n     */\r\n    public getScene(): Nullable<Scene> {\r\n        return this._scene;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _getEngine(): Nullable<AbstractEngine> {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * Get the texture transform matrix used to offset tile the texture for instance.\r\n     * @returns the transformation matrix\r\n     */\r\n    public getTextureMatrix(): Matrix {\r\n        return <Matrix>Matrix.IdentityReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Get the texture reflection matrix used to rotate/transform the reflection.\r\n     * @returns the reflection matrix\r\n     */\r\n    public getReflectionTextureMatrix(): Matrix {\r\n        return <Matrix>Matrix.IdentityReadOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets a suitable rotate/transform matrix when the texture is used for refraction.\r\n     * There's a separate function from getReflectionTextureMatrix because refraction requires a special configuration of the matrix in right-handed mode.\r\n     * @returns The refraction matrix\r\n     */\r\n    public getRefractionTextureMatrix(): Matrix {\r\n        return this.getReflectionTextureMatrix();\r\n    }\r\n\r\n    /**\r\n     * Get if the texture is ready to be consumed (either it is ready or it is not blocking)\r\n     * @returns true if ready, not blocking or if there was an error loading the texture\r\n     */\r\n    public isReadyOrNotBlocking(): boolean {\r\n        return !this.isBlocking || this.isReady() || this.loadingError;\r\n    }\r\n\r\n    /**\r\n     * Scales the texture if is `canRescale()`\r\n     * @param ratio the resize factor we want to use to rescale\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public scale(ratio: number): void {}\r\n\r\n    /**\r\n     * Get if the texture can rescale.\r\n     */\r\n    public get canRescale(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getFromCache(url: Nullable<string>, noMipmap: boolean, sampling?: number, invertY?: boolean, useSRGBBuffer?: boolean, isCube?: boolean): Nullable<InternalTexture> {\r\n        const engine = this._getEngine();\r\n        if (!engine) {\r\n            return null;\r\n        }\r\n\r\n        const correctedUseSRGBBuffer = engine._getUseSRGBBuffer(!!useSRGBBuffer, noMipmap);\r\n\r\n        const texturesCache = engine.getLoadedTexturesCache();\r\n        for (let index = 0; index < texturesCache.length; index++) {\r\n            const texturesCacheEntry = texturesCache[index];\r\n\r\n            if (useSRGBBuffer === undefined || correctedUseSRGBBuffer === texturesCacheEntry._useSRGBBuffer) {\r\n                if (invertY === undefined || invertY === texturesCacheEntry.invertY) {\r\n                    if (texturesCacheEntry.url === url && texturesCacheEntry.generateMipMaps === !noMipmap) {\r\n                        if (!sampling || sampling === texturesCacheEntry.samplingMode) {\r\n                            if (isCube === undefined || isCube === texturesCacheEntry.isCube) {\r\n                                texturesCacheEntry.incrementReferences();\r\n                                return texturesCacheEntry;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(_fromContextLost = false): void {}\r\n\r\n    /**\r\n     * Clones the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public clone(): Nullable<BaseTexture> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Get the texture underlying type (INT, FLOAT...)\r\n     */\r\n    public get textureType(): number {\r\n        if (!this._texture) {\r\n            return Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        }\r\n\r\n        return this._texture.type !== undefined ? this._texture.type : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    }\r\n\r\n    /**\r\n     * Get the texture underlying format (RGB, RGBA...)\r\n     */\r\n    public get textureFormat(): number {\r\n        if (!this._texture) {\r\n            return Constants.TEXTUREFORMAT_RGBA;\r\n        }\r\n\r\n        return this._texture.format !== undefined ? this._texture.format : Constants.TEXTUREFORMAT_RGBA;\r\n    }\r\n\r\n    /**\r\n     * Indicates that textures need to be re-calculated for all materials\r\n     */\r\n    protected _markAllSubMeshesAsTexturesDirty() {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Reads the pixels stored in the webgl texture and returns them as an ArrayBuffer.\r\n     * This will returns an RGBA array buffer containing either in values (0-255) or\r\n     * float values (0-1) depending of the underlying buffer type.\r\n     * Note that you can use {@link GetTextureDataAsync} instead, which will also support reading from a compressed texture (by rendering it to an intermediate RGBA texture and retrieving the bytes from it).\r\n     * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n     * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n     * @param buffer defines a user defined buffer to fill with data (can be null)\r\n     * @param flushRenderer true to flush the renderer from the pending commands before reading the pixels\r\n     * @param noDataConversion false to convert the data to Uint8Array (if texture type is UNSIGNED_BYTE) or to Float32Array (if texture type is anything but UNSIGNED_BYTE). If true, the type of the generated buffer (if buffer==null) will depend on the type of the texture\r\n     * @param x defines the region x coordinates to start reading from (default to 0)\r\n     * @param y defines the region y coordinates to start reading from (default to 0)\r\n     * @param width defines the region width to read from (default to the texture size at level)\r\n     * @param height defines the region width to read from (default to the texture size at level)\r\n     * @returns The Array buffer promise containing the pixels data.\r\n     */\r\n    public readPixels(\r\n        faceIndex = 0,\r\n        level = 0,\r\n        buffer: Nullable<ArrayBufferView> = null,\r\n        flushRenderer = true,\r\n        noDataConversion = false,\r\n        x = 0,\r\n        y = 0,\r\n        width = Number.MAX_VALUE,\r\n        height = Number.MAX_VALUE\r\n    ): Nullable<Promise<ArrayBufferView>> {\r\n        if (!this._texture) {\r\n            return null;\r\n        }\r\n\r\n        const engine = this._getEngine();\r\n        if (!engine) {\r\n            return null;\r\n        }\r\n\r\n        const size = this.getSize();\r\n        let maxWidth = size.width;\r\n        let maxHeight = size.height;\r\n        if (level !== 0) {\r\n            maxWidth = maxWidth / Math.pow(2, level);\r\n            maxHeight = maxHeight / Math.pow(2, level);\r\n            maxWidth = Math.round(maxWidth);\r\n            maxHeight = Math.round(maxHeight);\r\n        }\r\n\r\n        width = Math.min(maxWidth, width);\r\n        height = Math.min(maxHeight, height);\r\n\r\n        try {\r\n            if (this._texture.isCube || this._texture.is2DArray) {\r\n                return engine._readTexturePixels(this._texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion, x, y);\r\n            }\r\n\r\n            return engine._readTexturePixels(this._texture, width, height, -1, level, buffer, flushRenderer, noDataConversion, x, y);\r\n        } catch (e) {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _readPixelsSync(faceIndex = 0, level = 0, buffer: Nullable<ArrayBufferView> = null, flushRenderer = true, noDataConversion = false): Nullable<ArrayBufferView> {\r\n        if (!this._texture) {\r\n            return null;\r\n        }\r\n\r\n        const size = this.getSize();\r\n        let width = size.width;\r\n        let height = size.height;\r\n\r\n        const engine = this._getEngine();\r\n        if (!engine) {\r\n            return null;\r\n        }\r\n\r\n        if (level != 0) {\r\n            width = width / Math.pow(2, level);\r\n            height = height / Math.pow(2, level);\r\n\r\n            width = Math.round(width);\r\n            height = Math.round(height);\r\n        }\r\n\r\n        try {\r\n            if (this._texture.isCube) {\r\n                return engine._readTexturePixelsSync(this._texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion);\r\n            }\r\n\r\n            return engine._readTexturePixelsSync(this._texture, width, height, -1, level, buffer, flushRenderer, noDataConversion);\r\n        } catch (e) {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public get _lodTextureHigh(): Nullable<BaseTexture> {\r\n        if (this._texture) {\r\n            return this._texture._lodTextureHigh;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _lodTextureMid(): Nullable<BaseTexture> {\r\n        if (this._texture) {\r\n            return this._texture._lodTextureMid;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _lodTextureLow(): Nullable<BaseTexture> {\r\n        if (this._texture) {\r\n            return this._texture._lodTextureLow;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        if (this._scene) {\r\n            // Animations\r\n            if (this._scene.stopAnimation) {\r\n                this._scene.stopAnimation(this);\r\n            }\r\n\r\n            // Remove from scene\r\n            this._scene.removePendingData(this);\r\n            const index = this._scene.textures.indexOf(this);\r\n\r\n            if (index >= 0) {\r\n                this._scene.textures.splice(index, 1);\r\n            }\r\n            this._scene.onTextureRemovedObservable.notifyObservers(this);\r\n            this._scene = null;\r\n\r\n            if (this._parentContainer) {\r\n                const index = this._parentContainer.textures.indexOf(this);\r\n                if (index > -1) {\r\n                    this._parentContainer.textures.splice(index, 1);\r\n                }\r\n                this._parentContainer = null;\r\n            }\r\n        }\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n\r\n        this.metadata = null;\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture into a JSON representation that can be parsed later on.\r\n     * @param allowEmptyName True to force serialization even if name is empty. Default: false\r\n     * @returns the JSON representation of the texture\r\n     */\r\n    public serialize(allowEmptyName = false): any {\r\n        if (!this.name && !allowEmptyName) {\r\n            return null;\r\n        }\r\n\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n\r\n        // Animations\r\n        SerializationHelper.AppendSerializedAnimations(this, serializationObject);\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Helper function to be called back once a list of texture contains only ready textures.\r\n     * @param textures Define the list of textures to wait for\r\n     * @param callback Define the callback triggered once the entire list will be ready\r\n     */\r\n    public static WhenAllReady(textures: BaseTexture[], callback: () => void): void {\r\n        let numRemaining = textures.length;\r\n        if (numRemaining === 0) {\r\n            callback();\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < textures.length; i++) {\r\n            const texture = textures[i];\r\n\r\n            if (texture.isReady()) {\r\n                if (--numRemaining === 0) {\r\n                    callback();\r\n                }\r\n            } else {\r\n                const onLoadObservable = (texture as any).onLoadObservable as Observable<BaseTexture>;\r\n\r\n                if (onLoadObservable) {\r\n                    onLoadObservable.addOnce(() => {\r\n                        if (--numRemaining === 0) {\r\n                            callback();\r\n                        }\r\n                    });\r\n                } else {\r\n                    if (--numRemaining === 0) {\r\n                        callback();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private static _IsScene(sceneOrEngine: Scene | AbstractEngine): sceneOrEngine is Scene {\r\n        return sceneOrEngine.getClassName() === \"Scene\";\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffect, _MissingSideEffectProperty } from \"../../Misc/devTools\";\r\n\r\nBaseTexture.prototype.forceSphericalPolynomialsRecompute ??= _MissingSideEffect(\"BaseTexture\", \"forceSphericalPolynomialsRecompute\") as any;\r\nif (!Object.getOwnPropertyDescriptor(BaseTexture.prototype, \"sphericalPolynomial\")) {\r\n    Object.defineProperty(BaseTexture.prototype, \"sphericalPolynomial\", _MissingSideEffectProperty(\"BaseTexture\", \"sphericalPolynomial\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type ISize } from \"../Maths/math.size\";\r\nimport { type Nullable } from \"../types\";\r\n\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\n\r\n/**\r\n * Transform some pixel data to a base64 string\r\n * @param pixels defines the pixel data to transform to base64\r\n * @param size defines the width and height of the (texture) data\r\n * @param invertY true if the data must be inverted for the Y coordinate during the conversion\r\n * @returns The base64 encoded string or null\r\n */\r\nexport function GenerateBase64StringFromPixelData(pixels: ArrayBufferView, size: ISize, invertY = false): Nullable<string> {\r\n    const width = size.width;\r\n    const height = size.height;\r\n\r\n    if (pixels instanceof Float32Array) {\r\n        let len = pixels.byteLength / pixels.BYTES_PER_ELEMENT;\r\n        const npixels = new Uint8Array(len);\r\n\r\n        while (--len >= 0) {\r\n            let val = pixels[len];\r\n            if (val < 0) {\r\n                val = 0;\r\n            } else if (val > 1) {\r\n                val = 1;\r\n            }\r\n            npixels[len] = val * 255;\r\n        }\r\n\r\n        pixels = npixels;\r\n    }\r\n\r\n    const canvas = document.createElement(\"canvas\");\r\n    canvas.width = width;\r\n    canvas.height = height;\r\n\r\n    const ctx = canvas.getContext(\"2d\");\r\n    if (!ctx) {\r\n        return null;\r\n    }\r\n\r\n    const imageData = ctx.createImageData(width, height);\r\n    const castData = <any>imageData.data;\r\n    castData.set(pixels);\r\n    ctx.putImageData(imageData, 0, 0);\r\n\r\n    if (invertY) {\r\n        const canvas2 = document.createElement(\"canvas\");\r\n        canvas2.width = width;\r\n        canvas2.height = height;\r\n\r\n        const ctx2 = canvas2.getContext(\"2d\");\r\n        if (!ctx2) {\r\n            return null;\r\n        }\r\n\r\n        ctx2.translate(0, height);\r\n        ctx2.scale(1, -1);\r\n        ctx2.drawImage(canvas, 0, 0);\r\n\r\n        return canvas2.toDataURL(\"image/png\");\r\n    }\r\n\r\n    return canvas.toDataURL(\"image/png\");\r\n}\r\n\r\n/**\r\n * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n * @param texture defines the texture to read pixels from\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @returns The base64 encoded string or null\r\n */\r\nexport function GenerateBase64StringFromTexture(texture: BaseTexture, faceIndex = 0, level = 0): Nullable<string> {\r\n    const internalTexture = texture.getInternalTexture();\r\n    if (!internalTexture) {\r\n        return null;\r\n    }\r\n\r\n    const pixels = texture._readPixelsSync(faceIndex, level);\r\n    if (!pixels) {\r\n        return null;\r\n    }\r\n\r\n    return GenerateBase64StringFromPixelData(pixels, texture.getSize(), internalTexture.invertY);\r\n}\r\n\r\n/**\r\n * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n * @param texture defines the texture to read pixels from\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @returns The base64 encoded string or null wrapped in a promise\r\n */\r\nexport async function GenerateBase64StringFromTextureAsync(texture: BaseTexture, faceIndex = 0, level = 0): Promise<Nullable<string>> {\r\n    const internalTexture = texture.getInternalTexture();\r\n    if (!internalTexture) {\r\n        return null;\r\n    }\r\n\r\n    const pixels = await texture.readPixels(faceIndex, level);\r\n    if (!pixels) {\r\n        return null;\r\n    }\r\n\r\n    return GenerateBase64StringFromPixelData(pixels, texture.getSize(), internalTexture.invertY);\r\n}\r\n\r\n/**\r\n * Class used to host copy specific utilities\r\n * (Back-compat)\r\n */\r\nexport const CopyTools = {\r\n    /**\r\n     * Transform some pixel data to a base64 string\r\n     * @param pixels defines the pixel data to transform to base64\r\n     * @param size defines the width and height of the (texture) data\r\n     * @param invertY true if the data must be inverted for the Y coordinate during the conversion\r\n     * @returns The base64 encoded string or null\r\n     */\r\n    GenerateBase64StringFromPixelData,\r\n\r\n    /**\r\n     * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n     * @param texture defines the texture to read pixels from\r\n     * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n     * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n     * @returns The base64 encoded string or null\r\n     */\r\n    GenerateBase64StringFromTexture,\r\n\r\n    /**\r\n     * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n     * @param texture defines the texture to read pixels from\r\n     * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n     * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n     * @returns The base64 encoded string or null wrapped in a promise\r\n     */\r\n    GenerateBase64StringFromTextureAsync,\r\n};\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { GetClass, RegisterClass } from \"../../Misc/typeStore\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\nimport { type IInspectable } from \"../../Misc/iInspectable\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { TimingTools } from \"../../Misc/timingTools\";\r\nimport { InstantiationTools } from \"../../Misc/instantiationTools\";\r\nimport { Plane } from \"../../Maths/math.plane\";\r\nimport { EncodeArrayBufferToBase64 } from \"../../Misc/stringTools\";\r\nimport { GenerateBase64StringFromTexture, GenerateBase64StringFromTextureAsync } from \"../../Misc/copyTools\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type InternalTexture } from \"./internalTexture\";\r\nimport { type CubeTexture } from \"../../Materials/Textures/cubeTexture.pure\";\r\nimport { type MirrorTexture } from \"../../Materials/Textures/mirrorTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type VideoTexture, type VideoTextureSettings } from \"./videoTexture.pure\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\n\r\n/**\r\n * Defines the available options when creating a texture\r\n */\r\nexport interface ITextureCreationOptions {\r\n    /** Defines if the texture will require mip maps or not (default: false) */\r\n    noMipmap?: boolean;\r\n\r\n    /** Defines if the texture needs to be inverted on the y axis during loading (default: true) */\r\n    invertY?: boolean;\r\n\r\n    /** Defines the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...) (default: Texture.TRILINEAR_SAMPLINGMODE) */\r\n    samplingMode?: number;\r\n\r\n    /** Defines a callback triggered when the texture has been loaded (default: null) */\r\n    onLoad?: Nullable<() => void>;\r\n\r\n    /** Defines a callback triggered when an error occurred during the loading session (default: null) */\r\n    onError?: Nullable<(message?: string, exception?: any) => void>;\r\n\r\n    /** Defines the buffer to load the texture from in case the texture is loaded from a buffer representation (default: null) */\r\n    buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap>;\r\n\r\n    /** Defines if the buffer we are loading the texture from should be deleted after load (default: false) */\r\n    deleteBuffer?: boolean;\r\n\r\n    /** Defines the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...) (default: ) */\r\n    format?: number;\r\n\r\n    /** Defines an optional mime type information (default: undefined) */\r\n    mimeType?: string;\r\n\r\n    /** Options to be passed to the loader (default: undefined) */\r\n    loaderOptions?: any;\r\n\r\n    /** Specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg) (default: undefined) */\r\n    creationFlags?: number;\r\n\r\n    /** Defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU) (default: false) */\r\n    useSRGBBuffer?: boolean;\r\n\r\n    /** Defines the underlying texture from an already existing one */\r\n    internalTexture?: InternalTexture;\r\n\r\n    /** Defines the underlying texture texture space */\r\n    gammaSpace?: boolean;\r\n\r\n    /** Defines the extension to use to pick the right loader */\r\n    forcedExtension?: string;\r\n}\r\n\r\n/**\r\n * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction#texture\r\n */\r\nexport class Texture extends BaseTexture {\r\n    /**\r\n     * Gets or sets a general boolean used to indicate that textures containing direct data (buffers) must be saved as part of the serialization process\r\n     */\r\n    public static SerializeBuffers = true;\r\n\r\n    /**\r\n     * Gets or sets a general boolean used to indicate that texture buffers must be saved as part of the serialization process.\r\n     * If no buffer exists, one will be created as base64 string from the internal webgl data.\r\n     */\r\n    public static ForceSerializeBuffers = false;\r\n\r\n    /**\r\n     * This observable will notify when any texture had a loading error\r\n     */\r\n    public static OnTextureLoadErrorObservable = /*#__PURE__*/ new Observable<BaseTexture>();\r\n\r\n    /** @internal */\r\n    public static _SerializeInternalTextureUniqueId = false;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _CubeTextureParser = (jsonTexture: any, scene: Scene, rootUrl: string): CubeTexture => {\r\n        throw _WarnImport(\"CubeTexture\");\r\n    };\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _CreateMirror = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean): MirrorTexture => {\r\n        throw _WarnImport(\"MirrorTexture\");\r\n    };\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _CreateRenderTargetTexture = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean, creationFlags?: number): RenderTargetTexture => {\r\n        throw _WarnImport(\"RenderTargetTexture\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _CreateVideoTexture(\r\n        name: Nullable<string>,\r\n        src: string | string[] | HTMLVideoElement,\r\n        scene: Nullable<Scene>,\r\n        generateMipMaps = false,\r\n        invertY = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        settings: Partial<VideoTextureSettings> = {},\r\n        onError?: Nullable<(message?: string, exception?: any) => void>,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA\r\n    ): VideoTexture {\r\n        throw _WarnImport(\"VideoTexture\");\r\n    }\r\n\r\n    /** nearest is mag = nearest and min = nearest and no mip */\r\n    public static readonly NEAREST_SAMPLINGMODE = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n    /** nearest is mag = nearest and min = nearest and mip = linear */\r\n    public static readonly NEAREST_NEAREST_MIPLINEAR = Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR; // nearest is mag = nearest and min = nearest and mip = linear\r\n\r\n    /** Bilinear is mag = linear and min = linear and no mip */\r\n    public static readonly BILINEAR_SAMPLINGMODE = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n    /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n    public static readonly LINEAR_LINEAR_MIPNEAREST = Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST; // Bilinear is mag = linear and min = linear and mip = nearest\r\n\r\n    /** Trilinear is mag = linear and min = linear and mip = linear */\r\n    public static readonly TRILINEAR_SAMPLINGMODE = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n    /** Trilinear is mag = linear and min = linear and mip = linear */\r\n    public static readonly LINEAR_LINEAR_MIPLINEAR = Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR; // Trilinear is mag = linear and min = linear and mip = linear\r\n\r\n    /** mag = nearest and min = nearest and mip = nearest */\r\n    public static readonly NEAREST_NEAREST_MIPNEAREST = Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST;\r\n    /** mag = nearest and min = linear and mip = nearest */\r\n    public static readonly NEAREST_LINEAR_MIPNEAREST = Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST;\r\n    /** mag = nearest and min = linear and mip = linear */\r\n    public static readonly NEAREST_LINEAR_MIPLINEAR = Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR;\r\n    /** mag = nearest and min = linear and mip = none */\r\n    public static readonly NEAREST_LINEAR = Constants.TEXTURE_NEAREST_LINEAR;\r\n    /** mag = nearest and min = nearest and mip = none */\r\n    public static readonly NEAREST_NEAREST = Constants.TEXTURE_NEAREST_NEAREST;\r\n    /** mag = linear and min = nearest and mip = nearest */\r\n    public static readonly LINEAR_NEAREST_MIPNEAREST = Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST;\r\n    /** mag = linear and min = nearest and mip = linear */\r\n    public static readonly LINEAR_NEAREST_MIPLINEAR = Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR;\r\n    /** mag = linear and min = linear and mip = none */\r\n    public static readonly LINEAR_LINEAR = Constants.TEXTURE_LINEAR_LINEAR;\r\n    /** mag = linear and min = nearest and mip = none */\r\n    public static readonly LINEAR_NEAREST = Constants.TEXTURE_LINEAR_NEAREST;\r\n\r\n    /** Explicit coordinates mode */\r\n    public static readonly EXPLICIT_MODE = Constants.TEXTURE_EXPLICIT_MODE;\r\n    /** Spherical coordinates mode */\r\n    public static readonly SPHERICAL_MODE = Constants.TEXTURE_SPHERICAL_MODE;\r\n    /** Planar coordinates mode */\r\n    public static readonly PLANAR_MODE = Constants.TEXTURE_PLANAR_MODE;\r\n    /** Cubic coordinates mode */\r\n    public static readonly CUBIC_MODE = Constants.TEXTURE_CUBIC_MODE;\r\n    /** Projection coordinates mode */\r\n    public static readonly PROJECTION_MODE = Constants.TEXTURE_PROJECTION_MODE;\r\n    /** Inverse Cubic coordinates mode */\r\n    public static readonly SKYBOX_MODE = Constants.TEXTURE_SKYBOX_MODE;\r\n    /** Inverse Cubic coordinates mode */\r\n    public static readonly INVCUBIC_MODE = Constants.TEXTURE_INVCUBIC_MODE;\r\n    /** Equirectangular coordinates mode */\r\n    public static readonly EQUIRECTANGULAR_MODE = Constants.TEXTURE_EQUIRECTANGULAR_MODE;\r\n    /** Equirectangular Fixed coordinates mode */\r\n    public static readonly FIXED_EQUIRECTANGULAR_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE;\r\n    /** Equirectangular Fixed Mirrored coordinates mode */\r\n    public static readonly FIXED_EQUIRECTANGULAR_MIRRORED_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE;\r\n\r\n    /** Texture is not repeating outside of 0..1 UVs */\r\n    public static readonly CLAMP_ADDRESSMODE = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n    /** Texture is repeating outside of 0..1 UVs */\r\n    public static readonly WRAP_ADDRESSMODE = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n    /** Texture is repeating and mirrored */\r\n    public static readonly MIRROR_ADDRESSMODE = Constants.TEXTURE_MIRROR_ADDRESSMODE;\r\n\r\n    /**\r\n     * Gets or sets a boolean which defines if the texture url must be build from the serialized URL instead of just using the name and loading them side by side with the scene file\r\n     */\r\n    public static UseSerializedUrlIfAny = false;\r\n\r\n    /**\r\n     * Define the url of the texture.\r\n     */\r\n    @serialize()\r\n    public url: Nullable<string> = null;\r\n\r\n    /**\r\n     * Define an offset on the texture to offset the u coordinates of the UVs\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#offsetting\r\n     */\r\n    @serialize()\r\n    public uOffset = 0;\r\n\r\n    /**\r\n     * Define an offset on the texture to offset the v coordinates of the UVs\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#offsetting\r\n     */\r\n    @serialize()\r\n    public vOffset = 0;\r\n\r\n    /**\r\n     * Define an offset on the texture to scale the u coordinates of the UVs\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#tiling\r\n     */\r\n    @serialize()\r\n    public uScale = 1.0;\r\n\r\n    /**\r\n     * Define an offset on the texture to scale the v coordinates of the UVs\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#tiling\r\n     */\r\n    @serialize()\r\n    public vScale = 1.0;\r\n\r\n    /**\r\n     * Define an offset on the texture to rotate around the u coordinates of the UVs\r\n     * The angle is defined in radians.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials\r\n     */\r\n    @serialize()\r\n    public uAng = 0;\r\n\r\n    /**\r\n     * Define an offset on the texture to rotate around the v coordinates of the UVs\r\n     * The angle is defined in radians.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials\r\n     */\r\n    @serialize()\r\n    public vAng = 0;\r\n\r\n    /**\r\n     * Define an offset on the texture to rotate around the w coordinates of the UVs (in case of 3d texture)\r\n     * The angle is defined in radians.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials\r\n     */\r\n    @serialize()\r\n    public wAng = 0;\r\n\r\n    /**\r\n     * Defines the center of rotation (U)\r\n     */\r\n    @serialize()\r\n    public uRotationCenter = 0.5;\r\n\r\n    /**\r\n     * Defines the center of rotation (V)\r\n     */\r\n    @serialize()\r\n    public vRotationCenter = 0.5;\r\n\r\n    /**\r\n     * Defines the center of rotation (W)\r\n     */\r\n    @serialize()\r\n    public wRotationCenter = 0.5;\r\n\r\n    /**\r\n     * Sets this property to true to avoid deformations when rotating the texture with non-uniform scaling\r\n     */\r\n    @serialize()\r\n    public homogeneousRotationInUVTransform = false;\r\n\r\n    /**\r\n     * Are mip maps generated for this texture or not.\r\n     */\r\n    override get noMipmap(): boolean {\r\n        return this._noMipmap;\r\n    }\r\n\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    public inspectableCustomProperties: Nullable<IInspectable[]> = null;\r\n\r\n    /** @internal */\r\n    public _noMipmap: boolean = false;\r\n    /** @internal */\r\n    public _invertY: boolean = false;\r\n    private _rowGenerationMatrix: Nullable<Matrix> = null;\r\n    private _cachedTextureMatrix: Nullable<Matrix> = null;\r\n    private _projectionModeMatrix: Nullable<Matrix> = null;\r\n    private _t0: Nullable<Vector3> = null;\r\n    private _t1: Nullable<Vector3> = null;\r\n    private _t2: Nullable<Vector3> = null;\r\n\r\n    private _cachedUOffset: number = -1;\r\n    private _cachedVOffset: number = -1;\r\n    private _cachedUScale: number = 0;\r\n    private _cachedVScale: number = 0;\r\n    private _cachedUAng: number = -1;\r\n    private _cachedVAng: number = -1;\r\n    private _cachedWAng: number = -1;\r\n    private _cachedReflectionProjectionMatrixId: number = -1;\r\n    private _cachedURotationCenter: number = -1;\r\n    private _cachedVRotationCenter: number = -1;\r\n    private _cachedWRotationCenter: number = -1;\r\n    private _cachedHomogeneousRotationInUVTransform: boolean = false;\r\n    private _cachedIdentity3x2: boolean = true;\r\n\r\n    private _cachedReflectionTextureMatrix: Nullable<Matrix> = null;\r\n    private _cachedReflectionUOffset = -1;\r\n    private _cachedReflectionVOffset = -1;\r\n    private _cachedReflectionUScale = 0;\r\n    private _cachedReflectionVScale = 0;\r\n    private _cachedReflectionCoordinatesMode = -1;\r\n\r\n    /** @internal */\r\n    public _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null;\r\n    private _deleteBuffer: boolean = false;\r\n    protected _format: Nullable<number> = null;\r\n    private _delayedOnLoad: Nullable<() => void> = null;\r\n    private _delayedOnError: Nullable<() => void> = null;\r\n    private _mimeType?: string;\r\n    private _loaderOptions?: any;\r\n    private _creationFlags?: number;\r\n    /** @internal */\r\n    public _useSRGBBuffer?: boolean;\r\n    private _forcedExtension?: string;\r\n\r\n    /** Returns the texture mime type if it was defined by a loader (undefined else) */\r\n    public get mimeType() {\r\n        return this._mimeType;\r\n    }\r\n\r\n    /**\r\n     * Observable triggered once the texture has been loaded.\r\n     */\r\n    public onLoadObservable: Observable<Texture> = new Observable<Texture>();\r\n\r\n    protected _isBlocking: boolean = true;\r\n    /**\r\n     * Is the texture preventing material to render while loading.\r\n     * If false, a default texture will be used instead of the loading one during the preparation step.\r\n     */\r\n    public override set isBlocking(value: boolean) {\r\n        this._isBlocking = value;\r\n    }\r\n    @serialize()\r\n    public override get isBlocking(): boolean {\r\n        return this._isBlocking;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the texture needs to be inverted on the y axis during loading\r\n     */\r\n    public get invertY(): boolean {\r\n        return this._invertY;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new texture.\r\n     * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction#texture\r\n     * @param url defines the url of the picture to load as a texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param noMipmapOrOptions defines if the texture will require mip maps or not or set of all options to create the texture\r\n     * @param invertY defines if the texture needs to be inverted on the y axis during loading\r\n     * @param samplingMode defines the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...)\r\n     * @param onLoad defines a callback triggered when the texture has been loaded\r\n     * @param onError defines a callback triggered when an error occurred during the loading session\r\n     * @param buffer defines the buffer to load the texture from in case the texture is loaded from a buffer representation\r\n     * @param deleteBuffer defines if the buffer we are loading the texture from should be deleted after load\r\n     * @param format defines the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)\r\n     * @param mimeType defines an optional mime type information\r\n     * @param loaderOptions options to be passed to the loader\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     */\r\n    constructor(\r\n        url: Nullable<string>,\r\n        sceneOrEngine?: Nullable<Scene | AbstractEngine>,\r\n        noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n        invertY?: boolean,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        deleteBuffer: boolean = false,\r\n        format?: number,\r\n        mimeType?: string,\r\n        loaderOptions?: any,\r\n        creationFlags?: number,\r\n        forcedExtension?: string\r\n    ) {\r\n        super(sceneOrEngine);\r\n\r\n        this.name = url || \"\";\r\n        this.url = url;\r\n\r\n        let noMipmap: boolean;\r\n        let useSRGBBuffer: boolean = false;\r\n        let internalTexture: Nullable<InternalTexture> = null;\r\n        let gammaSpace = true;\r\n\r\n        if (typeof noMipmapOrOptions === \"object\" && noMipmapOrOptions !== null) {\r\n            noMipmap = noMipmapOrOptions.noMipmap ?? false;\r\n            invertY = noMipmapOrOptions.invertY ?? !useOpenGLOrientationForUV;\r\n            samplingMode = noMipmapOrOptions.samplingMode ?? Texture.TRILINEAR_SAMPLINGMODE;\r\n            onLoad = noMipmapOrOptions.onLoad ?? null;\r\n            onError = noMipmapOrOptions.onError ?? null;\r\n            buffer = noMipmapOrOptions.buffer ?? null;\r\n            deleteBuffer = noMipmapOrOptions.deleteBuffer ?? false;\r\n            format = noMipmapOrOptions.format;\r\n            mimeType = noMipmapOrOptions.mimeType;\r\n            loaderOptions = noMipmapOrOptions.loaderOptions;\r\n            creationFlags = noMipmapOrOptions.creationFlags;\r\n            useSRGBBuffer = noMipmapOrOptions.useSRGBBuffer ?? false;\r\n            internalTexture = noMipmapOrOptions.internalTexture ?? null;\r\n            gammaSpace = noMipmapOrOptions.gammaSpace ?? gammaSpace;\r\n            forcedExtension = noMipmapOrOptions.forcedExtension ?? forcedExtension;\r\n        } else {\r\n            noMipmap = !!noMipmapOrOptions;\r\n        }\r\n\r\n        this._gammaSpace = gammaSpace;\r\n        this._noMipmap = noMipmap;\r\n        this._invertY = invertY === undefined ? !useOpenGLOrientationForUV : invertY;\r\n        this._initialSamplingMode = samplingMode;\r\n        this._buffer = buffer;\r\n        this._deleteBuffer = deleteBuffer;\r\n        this._mimeType = mimeType;\r\n        this._loaderOptions = loaderOptions;\r\n        this._creationFlags = creationFlags;\r\n        this._useSRGBBuffer = useSRGBBuffer;\r\n        this._forcedExtension = forcedExtension;\r\n        if (format !== undefined) {\r\n            this._format = format;\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const engine = this._getEngine();\r\n        if (!engine) {\r\n            return;\r\n        }\r\n\r\n        engine.onBeforeTextureInitObservable.notifyObservers(this);\r\n\r\n        const load = () => {\r\n            if (this._texture) {\r\n                if (this._texture._invertVScale) {\r\n                    this.vScale *= -1;\r\n                    this.vOffset += 1;\r\n                }\r\n\r\n                // Update texture to match internal texture's wrapping\r\n                if (this._texture._cachedWrapU !== null) {\r\n                    this.wrapU = this._texture._cachedWrapU;\r\n                    this._texture._cachedWrapU = null;\r\n                }\r\n                if (this._texture._cachedWrapV !== null) {\r\n                    this.wrapV = this._texture._cachedWrapV;\r\n                    this._texture._cachedWrapV = null;\r\n                }\r\n                if (this._texture._cachedWrapR !== null) {\r\n                    this.wrapR = this._texture._cachedWrapR;\r\n                    this._texture._cachedWrapR = null;\r\n                }\r\n            }\r\n\r\n            if (this.onLoadObservable.hasObservers()) {\r\n                this.onLoadObservable.notifyObservers(this);\r\n            }\r\n            if (onLoad) {\r\n                onLoad();\r\n            }\r\n\r\n            if (!this.isBlocking && scene) {\r\n                scene.resetCachedMaterial();\r\n            }\r\n        };\r\n\r\n        const errorHandler = (message?: string, exception?: any) => {\r\n            this._loadingError = true;\r\n            this._errorObject = { message, exception };\r\n            if (onError) {\r\n                onError(message, exception);\r\n            }\r\n            Texture.OnTextureLoadErrorObservable.notifyObservers(this);\r\n        };\r\n\r\n        if (!this.url && !internalTexture) {\r\n            this._delayedOnLoad = load;\r\n            this._delayedOnError = errorHandler;\r\n            return;\r\n        }\r\n\r\n        this._texture = internalTexture ?? this._getFromCache(this.url, noMipmap, samplingMode, this._invertY, useSRGBBuffer, this.isCube);\r\n\r\n        if (!this._texture) {\r\n            if (!scene || !scene.useDelayedTextureLoading) {\r\n                try {\r\n                    this._texture = engine.createTexture(\r\n                        this.url,\r\n                        noMipmap,\r\n                        this._invertY,\r\n                        scene,\r\n                        samplingMode,\r\n                        load,\r\n                        errorHandler,\r\n                        this._buffer,\r\n                        undefined,\r\n                        this._format,\r\n                        this._forcedExtension,\r\n                        mimeType,\r\n                        loaderOptions,\r\n                        creationFlags,\r\n                        useSRGBBuffer\r\n                    );\r\n                } catch (e) {\r\n                    errorHandler(\"error loading\", e);\r\n                    throw e;\r\n                }\r\n                if (deleteBuffer) {\r\n                    this._buffer = null;\r\n                }\r\n            } else {\r\n                this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n\r\n                this._delayedOnLoad = load;\r\n                this._delayedOnError = errorHandler;\r\n            }\r\n        } else {\r\n            if (this._texture.isReady) {\r\n                TimingTools.SetImmediate(() => load());\r\n            } else {\r\n                const loadObserver = this._texture.onLoadedObservable.add(load);\r\n                this._texture.onErrorObservable.add((e) => {\r\n                    errorHandler(e.message, e.exception);\r\n                    this._texture?.onLoadedObservable.remove(loadObserver);\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the url (and optional buffer) of this texture if url was null during construction.\r\n     * @param url the url of the texture\r\n     * @param buffer the buffer of the texture (defaults to null)\r\n     * @param onLoad callback called when the texture is loaded  (defaults to null)\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     */\r\n    public updateURL(\r\n        url: string,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        onLoad?: () => void,\r\n        forcedExtension?: string\r\n    ): void {\r\n        if (this.url) {\r\n            this.releaseInternalTexture();\r\n            this.getScene()!.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n\r\n        if (!this.name || this.name.startsWith(\"data:\")) {\r\n            this.name = url;\r\n        }\r\n        this.url = url;\r\n        this._buffer = buffer;\r\n        this._forcedExtension = forcedExtension;\r\n        this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n\r\n        const existingOnLoad = this._delayedOnLoad;\r\n        const load = () => {\r\n            if (existingOnLoad) {\r\n                existingOnLoad();\r\n            } else if (this.onLoadObservable.hasObservers()) {\r\n                this.onLoadObservable.notifyObservers(this);\r\n            }\r\n            if (onLoad) {\r\n                onLoad();\r\n            }\r\n        };\r\n\r\n        this._delayedOnLoad = load;\r\n        this.delayLoad();\r\n    }\r\n\r\n    /**\r\n     * Finish the loading sequence of a texture flagged as delayed load.\r\n     * @internal\r\n     */\r\n    public override delayLoad(): void {\r\n        if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            return;\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        let url = this.url;\r\n\r\n        if (!url && (this.name.indexOf(\"://\") > 0 || this.name.startsWith(\"data:\"))) {\r\n            // Some textures are serialized with an empty url and use name instead for storing the url.\r\n            // When created without delayed load, the url is set properly because it is passed to the constructor and the texture is created right away.\r\n            // But when created with delayed load, the url property is overwritten to \"\" (because it is the value in the serialized data) when the properties are parsed (see SerializationHelper.Parse).\r\n            url = this.name;\r\n        }\r\n\r\n        this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\r\n        this._texture = this._getFromCache(url, this._noMipmap, this.samplingMode, this._invertY, this._useSRGBBuffer, this.isCube);\r\n\r\n        if (!this._texture) {\r\n            this._texture = scene\r\n                .getEngine()\r\n                .createTexture(\r\n                    url,\r\n                    this._noMipmap,\r\n                    this._invertY,\r\n                    scene,\r\n                    this.samplingMode,\r\n                    this._delayedOnLoad,\r\n                    this._delayedOnError,\r\n                    this._buffer,\r\n                    null,\r\n                    this._format,\r\n                    this._forcedExtension,\r\n                    this._mimeType,\r\n                    this._loaderOptions,\r\n                    this._creationFlags,\r\n                    this._useSRGBBuffer\r\n                );\r\n            if (this._deleteBuffer) {\r\n                this._buffer = null;\r\n            }\r\n        } else {\r\n            if (this._delayedOnLoad) {\r\n                if (this._texture.isReady) {\r\n                    TimingTools.SetImmediate(this._delayedOnLoad);\r\n                } else {\r\n                    this._texture.onLoadedObservable.add(this._delayedOnLoad);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._delayedOnLoad = null;\r\n        this._delayedOnError = null;\r\n    }\r\n\r\n    private _prepareRowForTextureGeneration(x: number, y: number, z: number, t: Vector3): void {\r\n        x *= this._cachedUScale;\r\n        y *= this._cachedVScale;\r\n\r\n        x -= this.uRotationCenter * this._cachedUScale;\r\n        y -= this.vRotationCenter * this._cachedVScale;\r\n        z -= this.wRotationCenter;\r\n\r\n        Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix!, t);\r\n\r\n        t.x += this.uRotationCenter * this._cachedUScale + this._cachedUOffset;\r\n        t.y += this.vRotationCenter * this._cachedVScale + this._cachedVOffset;\r\n        t.z += this.wRotationCenter;\r\n    }\r\n\r\n    /**\r\n     * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.\r\n     * @param uBase The horizontal base offset multiplier (1 by default)\r\n     * @returns the transform matrix of the texture.\r\n     */\r\n    public override getTextureMatrix(uBase = 1): Matrix {\r\n        if (\r\n            this.uOffset === this._cachedUOffset &&\r\n            this.vOffset === this._cachedVOffset &&\r\n            this.uScale * uBase === this._cachedUScale &&\r\n            this.vScale === this._cachedVScale &&\r\n            this.uAng === this._cachedUAng &&\r\n            this.vAng === this._cachedVAng &&\r\n            this.wAng === this._cachedWAng &&\r\n            this.uRotationCenter === this._cachedURotationCenter &&\r\n            this.vRotationCenter === this._cachedVRotationCenter &&\r\n            this.wRotationCenter === this._cachedWRotationCenter &&\r\n            this.homogeneousRotationInUVTransform === this._cachedHomogeneousRotationInUVTransform\r\n        ) {\r\n            return this._cachedTextureMatrix!;\r\n        }\r\n\r\n        this._cachedUOffset = this.uOffset;\r\n        this._cachedVOffset = this.vOffset;\r\n        this._cachedUScale = this.uScale * uBase;\r\n        this._cachedVScale = this.vScale;\r\n        this._cachedUAng = this.uAng;\r\n        this._cachedVAng = this.vAng;\r\n        this._cachedWAng = this.wAng;\r\n        this._cachedURotationCenter = this.uRotationCenter;\r\n        this._cachedVRotationCenter = this.vRotationCenter;\r\n        this._cachedWRotationCenter = this.wRotationCenter;\r\n        this._cachedHomogeneousRotationInUVTransform = this.homogeneousRotationInUVTransform;\r\n\r\n        if (!this._cachedTextureMatrix || !this._rowGenerationMatrix) {\r\n            this._cachedTextureMatrix = Matrix.Zero();\r\n            this._rowGenerationMatrix = new Matrix();\r\n            this._t0 = Vector3.Zero();\r\n            this._t1 = Vector3.Zero();\r\n            this._t2 = Vector3.Zero();\r\n        }\r\n\r\n        Matrix.RotationYawPitchRollToRef(this.vAng, this.uAng, this.wAng, this._rowGenerationMatrix);\r\n\r\n        if (this.homogeneousRotationInUVTransform) {\r\n            Matrix.TranslationToRef(-this._cachedURotationCenter, -this._cachedVRotationCenter, -this._cachedWRotationCenter, TmpVectors.Matrix[0]);\r\n            Matrix.TranslationToRef(this._cachedURotationCenter, this._cachedVRotationCenter, this._cachedWRotationCenter, TmpVectors.Matrix[1]);\r\n            Matrix.ScalingToRef(this._cachedUScale, this._cachedVScale, 0, TmpVectors.Matrix[2]);\r\n            Matrix.TranslationToRef(this._cachedUOffset, this._cachedVOffset, 0, TmpVectors.Matrix[3]);\r\n\r\n            TmpVectors.Matrix[0].multiplyToRef(this._rowGenerationMatrix, this._cachedTextureMatrix);\r\n            this._cachedTextureMatrix.multiplyToRef(TmpVectors.Matrix[1], this._cachedTextureMatrix);\r\n            this._cachedTextureMatrix.multiplyToRef(TmpVectors.Matrix[2], this._cachedTextureMatrix);\r\n            this._cachedTextureMatrix.multiplyToRef(TmpVectors.Matrix[3], this._cachedTextureMatrix);\r\n\r\n            // copy the translation row to the 3rd row of the matrix so that we don't need to update the shaders (which expects the translation to be on the 3rd row)\r\n            this._cachedTextureMatrix.setRowFromFloats(2, this._cachedTextureMatrix.m[12], this._cachedTextureMatrix.m[13], this._cachedTextureMatrix.m[14], 1);\r\n        } else {\r\n            this._prepareRowForTextureGeneration(0, 0, 0, this._t0!);\r\n            this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1!);\r\n            this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2!);\r\n\r\n            this._t1!.subtractInPlace(this._t0!);\r\n            this._t2!.subtractInPlace(this._t0!);\r\n\r\n            Matrix.FromValuesToRef(\r\n                this._t1!.x,\r\n                this._t1!.y,\r\n                this._t1!.z,\r\n                0.0,\r\n                this._t2!.x,\r\n                this._t2!.y,\r\n                this._t2!.z,\r\n                0.0,\r\n                this._t0!.x,\r\n                this._t0!.y,\r\n                this._t0!.z,\r\n                0.0,\r\n                0.0,\r\n                0.0,\r\n                0.0,\r\n                1.0,\r\n                this._cachedTextureMatrix\r\n            );\r\n        }\r\n\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return this._cachedTextureMatrix;\r\n        }\r\n\r\n        const previousIdentity3x2 = this._cachedIdentity3x2;\r\n        this._cachedIdentity3x2 = this._cachedTextureMatrix.isIdentityAs3x2();\r\n\r\n        if (this.optimizeUVAllocation && previousIdentity3x2 !== this._cachedIdentity3x2) {\r\n            // We flag the materials that are using this texture as \"texture dirty\" because depending on the fact that the matrix is the identity or not, some defines\r\n            // will get different values (see PrepareDefinesForMergedUV), meaning we should regenerate the effect accordingly\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n\r\n        return this._cachedTextureMatrix;\r\n    }\r\n\r\n    /**\r\n     * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.\r\n     * @returns The reflection texture transform\r\n     */\r\n    public override getReflectionTextureMatrix(): Matrix {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return this._cachedReflectionTextureMatrix!;\r\n        }\r\n\r\n        if (\r\n            this.uOffset === this._cachedReflectionUOffset &&\r\n            this.vOffset === this._cachedReflectionVOffset &&\r\n            this.uScale === this._cachedReflectionUScale &&\r\n            this.vScale === this._cachedReflectionVScale &&\r\n            this.coordinatesMode === this._cachedReflectionCoordinatesMode\r\n        ) {\r\n            if (this.coordinatesMode === Texture.PROJECTION_MODE) {\r\n                if (this._cachedReflectionProjectionMatrixId === scene.getProjectionMatrix().updateFlag) {\r\n                    return this._cachedReflectionTextureMatrix!;\r\n                }\r\n            } else {\r\n                return this._cachedReflectionTextureMatrix!;\r\n            }\r\n        }\r\n\r\n        if (!this._cachedReflectionTextureMatrix) {\r\n            this._cachedReflectionTextureMatrix = Matrix.Zero();\r\n        }\r\n\r\n        if (!this._projectionModeMatrix) {\r\n            this._projectionModeMatrix = Matrix.Zero();\r\n        }\r\n\r\n        const flagMaterialsAsTextureDirty = this._cachedReflectionCoordinatesMode !== this.coordinatesMode;\r\n\r\n        this._cachedReflectionUOffset = this.uOffset;\r\n        this._cachedReflectionVOffset = this.vOffset;\r\n        this._cachedReflectionUScale = this.uScale;\r\n        this._cachedReflectionVScale = this.vScale;\r\n        this._cachedReflectionCoordinatesMode = this.coordinatesMode;\r\n\r\n        switch (this.coordinatesMode) {\r\n            case Texture.PLANAR_MODE: {\r\n                Matrix.IdentityToRef(this._cachedReflectionTextureMatrix);\r\n                (<any>this._cachedReflectionTextureMatrix)[0] = this.uScale;\r\n                (<any>this._cachedReflectionTextureMatrix)[5] = this.vScale;\r\n                (<any>this._cachedReflectionTextureMatrix)[12] = this.uOffset;\r\n                (<any>this._cachedReflectionTextureMatrix)[13] = this.vOffset;\r\n                break;\r\n            }\r\n            case Texture.PROJECTION_MODE: {\r\n                Matrix.FromValuesToRef(0.5, 0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, this._projectionModeMatrix);\r\n\r\n                const projectionMatrix = scene.getProjectionMatrix();\r\n                this._cachedReflectionProjectionMatrixId = projectionMatrix.updateFlag;\r\n                projectionMatrix.multiplyToRef(this._projectionModeMatrix, this._cachedReflectionTextureMatrix);\r\n                break;\r\n            }\r\n            default:\r\n                Matrix.IdentityToRef(this._cachedReflectionTextureMatrix);\r\n                break;\r\n        }\r\n\r\n        if (flagMaterialsAsTextureDirty) {\r\n            // We flag the materials that are using this texture as \"texture dirty\" if the coordinatesMode has changed.\r\n            // Indeed, this property is used to set the value of some defines used to generate the effect (in material.isReadyForSubMesh), so we must make sure this code will be re-executed and the effect recreated if necessary\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this);\r\n            });\r\n        }\r\n\r\n        return this._cachedReflectionTextureMatrix;\r\n    }\r\n\r\n    /**\r\n     * Clones the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): Texture {\r\n        const options: ITextureCreationOptions = {\r\n            noMipmap: this._noMipmap,\r\n            invertY: this._invertY,\r\n            samplingMode: this.samplingMode,\r\n            onLoad: undefined,\r\n            onError: undefined,\r\n            buffer: this._texture ? this._texture._buffer : undefined,\r\n            deleteBuffer: this._deleteBuffer,\r\n            format: this.textureFormat,\r\n            mimeType: this.mimeType,\r\n            loaderOptions: this._loaderOptions,\r\n            creationFlags: this._creationFlags,\r\n            useSRGBBuffer: this._useSRGBBuffer,\r\n        };\r\n\r\n        return SerializationHelper.Clone(() => {\r\n            return new Texture(this._texture ? this._texture.url : null, this.getScene(), options);\r\n        }, this);\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture to a JSON representation we can easily use in the respective Parse function.\r\n     * @returns The JSON representation of the texture\r\n     */\r\n    public override serialize(): any {\r\n        const savedName = this.name;\r\n\r\n        if (!Texture.SerializeBuffers) {\r\n            if (this.name.startsWith(\"data:\")) {\r\n                this.name = \"\";\r\n            }\r\n        }\r\n\r\n        if (this.name.startsWith(\"data:\") && this.url === this.name) {\r\n            this.url = \"\";\r\n        }\r\n\r\n        const serializationObject = super.serialize(Texture._SerializeInternalTextureUniqueId);\r\n\r\n        if (!serializationObject) {\r\n            return null;\r\n        }\r\n\r\n        if (Texture.SerializeBuffers || Texture.ForceSerializeBuffers) {\r\n            if (typeof this._buffer === \"string\" && this._buffer.startsWith(\"data:\")) {\r\n                serializationObject.base64String = this._buffer;\r\n                serializationObject.name = serializationObject.name.replace(\"data:\", \"\");\r\n            } else if (this.url && this.url.startsWith(\"data:\") && this._buffer instanceof Uint8Array) {\r\n                const mimeType = this.mimeType || \"image/png\";\r\n                serializationObject.base64String = `data:${mimeType};base64,${EncodeArrayBufferToBase64(this._buffer)}`;\r\n            } else if (Texture.ForceSerializeBuffers || (this.url && this.url.startsWith(\"blob:\")) || this._forceSerialize) {\r\n                serializationObject.base64String =\r\n                    !this._engine || this._engine._features.supportSyncTextureRead ? GenerateBase64StringFromTexture(this) : GenerateBase64StringFromTextureAsync(this);\r\n            }\r\n        }\r\n\r\n        serializationObject.invertY = this._invertY;\r\n        serializationObject.samplingMode = this.samplingMode;\r\n        serializationObject._creationFlags = this._creationFlags;\r\n        serializationObject._useSRGBBuffer = this._useSRGBBuffer;\r\n        if (Texture._SerializeInternalTextureUniqueId) {\r\n            serializationObject.internalTextureUniqueId = this._texture?.uniqueId;\r\n        }\r\n        serializationObject.internalTextureLabel = this._texture?.label;\r\n        serializationObject.noMipmap = this._noMipmap;\r\n\r\n        this.name = savedName;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the texture useful for serialization or dynamic coding.\r\n     * @returns \"Texture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"Texture\";\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        this.onLoadObservable.clear();\r\n\r\n        this._delayedOnLoad = null;\r\n        this._delayedOnError = null;\r\n        this._buffer = null;\r\n    }\r\n\r\n    /**\r\n     * Parse the JSON representation of a texture in order to recreate the texture in the given scene.\r\n     * @param parsedTexture Define the JSON representation of the texture\r\n     * @param scene Define the scene the parsed texture should be instantiated in\r\n     * @param rootUrl Define the root url of the parsing sequence in the case of relative dependencies\r\n     * @returns The parsed texture if successful\r\n     */\r\n    public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable<BaseTexture> {\r\n        if (parsedTexture.customType) {\r\n            const customTexture = InstantiationTools.Instantiate(parsedTexture.customType);\r\n            // Update Sampling Mode\r\n            const parsedCustomTexture: any = customTexture.Parse(parsedTexture, scene, rootUrl);\r\n            if (parsedTexture.samplingMode && parsedCustomTexture.updateSamplingMode && parsedCustomTexture._samplingMode) {\r\n                if (parsedCustomTexture._samplingMode !== parsedTexture.samplingMode) {\r\n                    parsedCustomTexture.updateSamplingMode(parsedTexture.samplingMode);\r\n                }\r\n            }\r\n            return parsedCustomTexture;\r\n        }\r\n\r\n        if (parsedTexture.isCube && !parsedTexture.isRenderTarget) {\r\n            return Texture._CubeTextureParser(parsedTexture, scene, rootUrl);\r\n        }\r\n\r\n        const hasInternalTextureUniqueId = parsedTexture.internalTextureUniqueId !== undefined;\r\n\r\n        if (!parsedTexture.name && !parsedTexture.isRenderTarget && !hasInternalTextureUniqueId) {\r\n            return null;\r\n        }\r\n\r\n        let internalTexture: InternalTexture | undefined;\r\n\r\n        if (hasInternalTextureUniqueId) {\r\n            const cache = scene.getEngine().getLoadedTexturesCache();\r\n            for (const texture of cache) {\r\n                if (texture.uniqueId === parsedTexture.internalTextureUniqueId) {\r\n                    internalTexture = texture;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        const onLoaded = (texture: Texture | null) => {\r\n            // Clear cache\r\n            if (texture && texture._texture) {\r\n                texture._texture._cachedWrapU = null;\r\n                texture._texture._cachedWrapV = null;\r\n                texture._texture._cachedWrapR = null;\r\n            }\r\n\r\n            // Update Sampling Mode\r\n            if (parsedTexture.samplingMode) {\r\n                const sampling: number = parsedTexture.samplingMode;\r\n                if (texture && texture.samplingMode !== sampling) {\r\n                    texture.updateSamplingMode(sampling);\r\n                }\r\n            }\r\n            // Animations\r\n            if (texture && parsedTexture.animations) {\r\n                for (let animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {\r\n                    const parsedAnimation = parsedTexture.animations[animationIndex];\r\n                    const internalClass = GetClass(\"BABYLON.Animation\");\r\n                    if (internalClass) {\r\n                        texture.animations.push(internalClass.Parse(parsedAnimation));\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (texture && texture._texture) {\r\n                if (hasInternalTextureUniqueId && !internalTexture) {\r\n                    texture._texture._setUniqueId(parsedTexture.internalTextureUniqueId);\r\n                }\r\n\r\n                texture._texture.label = parsedTexture.internalTextureLabel;\r\n            }\r\n        };\r\n\r\n        const texture = SerializationHelper.Parse(\r\n            () => {\r\n                let generateMipMaps: boolean = true;\r\n                if (parsedTexture.noMipmap) {\r\n                    generateMipMaps = false;\r\n                }\r\n                if (parsedTexture.mirrorPlane) {\r\n                    const mirrorTexture = Texture._CreateMirror(parsedTexture.name, parsedTexture.renderTargetSize, scene, generateMipMaps);\r\n                    mirrorTexture._waitingRenderList = parsedTexture.renderList;\r\n                    mirrorTexture.mirrorPlane = Plane.FromArray(parsedTexture.mirrorPlane);\r\n                    onLoaded(mirrorTexture);\r\n                    return mirrorTexture;\r\n                } else if (parsedTexture.isRenderTarget && !parsedTexture.base64String) {\r\n                    // if base64string is set it means the original RTT was baked\r\n                    let renderTargetTexture: Nullable<RenderTargetTexture> = null;\r\n                    if (parsedTexture.isCube) {\r\n                        // Search for an existing reflection probe (which contains a cube render target texture)\r\n                        if (scene.reflectionProbes) {\r\n                            for (let index = 0; index < scene.reflectionProbes.length; index++) {\r\n                                const probe = scene.reflectionProbes[index];\r\n                                if (probe.name === parsedTexture.name) {\r\n                                    return probe.cubeTexture;\r\n                                }\r\n                            }\r\n                        }\r\n                    } else {\r\n                        renderTargetTexture = Texture._CreateRenderTargetTexture(\r\n                            parsedTexture.name,\r\n                            parsedTexture.renderTargetSize,\r\n                            scene,\r\n                            generateMipMaps,\r\n                            parsedTexture._creationFlags ?? 0\r\n                        );\r\n                        renderTargetTexture._waitingRenderList = parsedTexture.renderList;\r\n                    }\r\n                    onLoaded(renderTargetTexture);\r\n                    return renderTargetTexture;\r\n                } else if (parsedTexture.isVideo) {\r\n                    const texture = Texture._CreateVideoTexture(\r\n                        rootUrl + (parsedTexture.url || parsedTexture.name),\r\n                        rootUrl + (parsedTexture.src || parsedTexture.url),\r\n                        scene,\r\n                        generateMipMaps,\r\n                        parsedTexture.invertY,\r\n                        parsedTexture.samplingMode,\r\n                        parsedTexture.settings || {}\r\n                    );\r\n                    onLoaded(texture);\r\n                    return texture;\r\n                } else {\r\n                    let texture: Texture;\r\n\r\n                    if (typeof parsedTexture.base64String === \"string\" && parsedTexture.base64String && !internalTexture) {\r\n                        const options: ITextureCreationOptions = {\r\n                            buffer: parsedTexture.base64String,\r\n                            noMipmap: !generateMipMaps,\r\n                            invertY: parsedTexture.invertY,\r\n                            samplingMode: parsedTexture.samplingMode,\r\n                            useSRGBBuffer: parsedTexture._useSRGBBuffer ?? false,\r\n                            creationFlags: parsedTexture._creationFlags ?? 0,\r\n                            onLoad: () => {\r\n                                onLoaded(texture);\r\n                            },\r\n                        };\r\n\r\n                        // use the base64 string as the texture name for caching; the actual payload comes from options.buffer\r\n                        const base64String = parsedTexture.base64String;\r\n                        const noPrefixBase64String = base64String.startsWith(\"data:\") ? base64String.substring(5) : base64String;\r\n\r\n                        texture = Texture.CreateFromBase64String(\"\", noPrefixBase64String, scene, options);\r\n\r\n                        // prettier name to fit with the loaded data\r\n                        texture.name = parsedTexture.name;\r\n                    } else {\r\n                        let url: string;\r\n                        if (parsedTexture.name && (parsedTexture.name.indexOf(\"://\") > 0 || parsedTexture.name.startsWith(\"data:\"))) {\r\n                            url = parsedTexture.name;\r\n                        } else {\r\n                            url = rootUrl + parsedTexture.name;\r\n                        }\r\n\r\n                        if (parsedTexture.url && (parsedTexture.url.startsWith(\"data:\") || Texture.UseSerializedUrlIfAny)) {\r\n                            url = parsedTexture.url;\r\n                        }\r\n\r\n                        const options: ITextureCreationOptions = {\r\n                            noMipmap: !generateMipMaps,\r\n                            invertY: parsedTexture.invertY,\r\n                            samplingMode: parsedTexture.samplingMode,\r\n                            useSRGBBuffer: parsedTexture._useSRGBBuffer ?? false,\r\n                            creationFlags: parsedTexture._creationFlags ?? 0,\r\n                            onLoad: () => {\r\n                                onLoaded(texture);\r\n                            },\r\n                            internalTexture,\r\n                        };\r\n\r\n                        texture = new Texture(url, scene, options);\r\n                    }\r\n\r\n                    return texture;\r\n                }\r\n            },\r\n            parsedTexture,\r\n            scene\r\n        );\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Creates a texture from its base 64 representation.\r\n     * @param data Define the base64 payload without the data: prefix\r\n     * @param name Define the name of the texture in the scene useful fo caching purpose for instance\r\n     * @param scene Define the scene the texture should belong to\r\n     * @param noMipmapOrOptions defines if the texture will require mip maps or not or set of all options to create the texture\r\n     * @param invertY define if the texture needs to be inverted on the y axis during loading\r\n     * @param samplingMode define the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...)\r\n     * @param onLoad define a callback triggered when the texture has been loaded\r\n     * @param onError define a callback triggered when an error occurred during the loading session\r\n     * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @returns the created texture\r\n     */\r\n    public static CreateFromBase64String(\r\n        data: string,\r\n        name: string,\r\n        scene: Scene,\r\n        noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n        invertY?: boolean,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<() => void> = null,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA,\r\n        creationFlags?: number,\r\n        forcedExtension?: string\r\n    ): Texture {\r\n        return new Texture(\r\n            \"data:\" + name,\r\n            scene,\r\n            noMipmapOrOptions,\r\n            invertY,\r\n            samplingMode,\r\n            onLoad,\r\n            onError,\r\n            data,\r\n            false,\r\n            format,\r\n            undefined,\r\n            undefined,\r\n            creationFlags,\r\n            forcedExtension\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a texture from its data: representation. (data: will be added in case only the payload has been passed in)\r\n     * @param name Define the name of the texture in the scene useful fo caching purpose for instance\r\n     * @param buffer define the buffer to load the texture from in case the texture is loaded from a buffer representation\r\n     * @param scene Define the scene the texture should belong to\r\n     * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load\r\n     * @param noMipmapOrOptions defines if the texture will require mip maps or not or set of all options to create the texture\r\n     * @param invertY define if the texture needs to be inverted on the y axis during loading\r\n     * @param samplingMode define the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...)\r\n     * @param onLoad define a callback triggered when the texture has been loaded\r\n     * @param onError define a callback triggered when an error occurred during the loading session\r\n     * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @returns the created texture\r\n     */\r\n    public static LoadFromDataString(\r\n        name: string,\r\n        buffer: any,\r\n        scene: Scene,\r\n        deleteBuffer: boolean = false,\r\n        noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n        invertY: boolean = true,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA,\r\n        creationFlags?: number,\r\n        forcedExtension?: string\r\n    ): Texture {\r\n        if (name.substring(0, 5) !== \"data:\") {\r\n            name = \"data:\" + name;\r\n        }\r\n\r\n        return new Texture(\r\n            name,\r\n            scene,\r\n            noMipmapOrOptions,\r\n            invertY,\r\n            samplingMode,\r\n            onLoad,\r\n            onError,\r\n            buffer,\r\n            deleteBuffer,\r\n            format,\r\n            undefined,\r\n            undefined,\r\n            creationFlags,\r\n            forcedExtension\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for texture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // References the dependencies.\r\n    RegisterClass(\"BABYLON.Texture\", Texture);\r\n\r\n    SerializationHelper._TextureParser = Texture.Parse;\r\n}\r\n","import { Texture } from \"./texture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\nimport { type Scene } from \"../../scene\";\r\n\r\n/**\r\n * Raw texture can help creating a texture directly from an array of data.\r\n * This can be super useful if you either get the data from an uncompressed source or\r\n * if you wish to create your texture pixel by pixel.\r\n */\r\nexport class RawTexture extends Texture {\r\n    private _waitingForData: boolean;\r\n    /**\r\n     * Instantiates a new RawTexture.\r\n     * Raw texture can help creating a texture directly from an array of data.\r\n     * This can be super useful if you either get the data from an uncompressed source or\r\n     * if you wish to create your texture pixel by pixel.\r\n     * @param data define the array of data to use to create the texture (null to create an empty texture)\r\n     * @param width define the width of the texture\r\n     * @param height define the height of the texture\r\n     * @param format define the format of the data (RGB, RGBA... Engine.TEXTUREFORMAT_xxx)\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps define whether mip maps should be generated or not\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @param waitDataToBeReady If set to true Rawtexture will wait data to be set in order to be flaged as ready.\r\n     * @param mipLevelCount defines the number of mip levels to allocate for the texture\r\n     */\r\n    constructor(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        /**\r\n         * Define the format of the data (RGB, RGBA... Engine.TEXTUREFORMAT_xxx)\r\n         */\r\n        public format: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags?: number,\r\n        useSRGBBuffer?: boolean,\r\n        waitDataToBeReady?: boolean,\r\n        mipLevelCount?: number\r\n    ) {\r\n        super(null, sceneOrEngine, !generateMipMaps, invertY, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, creationFlags);\r\n\r\n        if (!this._engine) {\r\n            return;\r\n        }\r\n\r\n        if (!this._engine._caps.textureFloatLinearFiltering && type === Constants.TEXTURETYPE_FLOAT) {\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        if (!this._engine._caps.textureHalfFloatLinearFiltering && type === Constants.TEXTURETYPE_HALF_FLOAT) {\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n\r\n        this._texture = this._engine.createRawTexture(\r\n            data,\r\n            width,\r\n            height,\r\n            format,\r\n            generateMipMaps,\r\n            invertY,\r\n            samplingMode,\r\n            null,\r\n            type,\r\n            creationFlags ?? 0,\r\n            useSRGBBuffer ?? false,\r\n            mipLevelCount\r\n        );\r\n\r\n        this.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._waitingForData = !!waitDataToBeReady && !data;\r\n    }\r\n\r\n    /**\r\n     * Updates the texture underlying data.\r\n     * @param data Define the new data of the texture\r\n     */\r\n    public update(data: ArrayBufferView): void {\r\n        this.updateMipLevel(data, 0);\r\n    }\r\n\r\n    /**\r\n     * Updates a specific mip level of the texture.\r\n     * @param data The new data for the mip level\r\n     * @param mipLevel The mip level to update (0 is the base level)\r\n     */\r\n    public updateMipLevel(data: ArrayBufferView, mipLevel: number): void {\r\n        this._getEngine()!.updateRawTexture(this._texture, data, this._texture!.format, this._texture!.invertY, null, this._texture!.type, this._texture!._useSRGBBuffer, mipLevel);\r\n        this._waitingForData = false;\r\n    }\r\n\r\n    /**\r\n     * Clones the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): Texture {\r\n        if (!this._texture) {\r\n            return super.clone();\r\n        }\r\n\r\n        const rawTexture = new RawTexture(\r\n            null,\r\n            this.getSize().width,\r\n            this.getSize().height,\r\n            this.format,\r\n            this.getScene(),\r\n            this._texture.generateMipMaps,\r\n            this._invertY,\r\n            this.samplingMode,\r\n            this._texture.type,\r\n            this._texture._creationFlags,\r\n            this._useSRGBBuffer\r\n        );\r\n\r\n        rawTexture._texture = this._texture;\r\n        this._texture.incrementReferences();\r\n\r\n        return rawTexture;\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return super.isReady() && !this._waitingForData;\r\n    }\r\n\r\n    /**\r\n     * Creates a luminance texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @returns the luminance texture\r\n     */\r\n    public static CreateLuminanceTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE\r\n    ): RawTexture {\r\n        return new RawTexture(data, width, height, Constants.TEXTUREFORMAT_LUMINANCE, sceneOrEngine, generateMipMaps, invertY, samplingMode);\r\n    }\r\n\r\n    /**\r\n     * Creates a luminance alpha texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @returns the luminance alpha texture\r\n     */\r\n    public static CreateLuminanceAlphaTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE\r\n    ): RawTexture {\r\n        return new RawTexture(data, width, height, Constants.TEXTUREFORMAT_LUMINANCE_ALPHA, sceneOrEngine, generateMipMaps, invertY, samplingMode);\r\n    }\r\n\r\n    /**\r\n     * Creates an alpha texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @returns the alpha texture\r\n     */\r\n    public static CreateAlphaTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE\r\n    ): RawTexture {\r\n        return new RawTexture(data, width, height, Constants.TEXTUREFORMAT_ALPHA, sceneOrEngine, generateMipMaps, invertY, samplingMode);\r\n    }\r\n\r\n    /**\r\n     * Creates a RGB texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns the RGB alpha texture\r\n     */\r\n    public static CreateRGBTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags: number = 0,\r\n        useSRGBBuffer: boolean = false\r\n    ): RawTexture {\r\n        return new RawTexture(data, width, height, Constants.TEXTUREFORMAT_RGB, sceneOrEngine, generateMipMaps, invertY, samplingMode, type, creationFlags, useSRGBBuffer);\r\n    }\r\n\r\n    /**\r\n     * Creates a RGBA texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @param waitDataToBeReady if set to true this will force texture to wait for data to be set before it is considered ready.\r\n     * @returns the RGBA texture\r\n     */\r\n    public static CreateRGBATexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags: number = 0,\r\n        useSRGBBuffer: boolean = false,\r\n        waitDataToBeReady: boolean = false\r\n    ): RawTexture {\r\n        return new RawTexture(\r\n            data,\r\n            width,\r\n            height,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            sceneOrEngine,\r\n            generateMipMaps,\r\n            invertY,\r\n            samplingMode,\r\n            type,\r\n            creationFlags,\r\n            useSRGBBuffer,\r\n            waitDataToBeReady\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a RGBA storage texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns the RGBA texture\r\n     */\r\n    public static CreateRGBAStorageTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        useSRGBBuffer: boolean = false\r\n    ): RawTexture {\r\n        return new RawTexture(\r\n            data,\r\n            width,\r\n            height,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            sceneOrEngine,\r\n            generateMipMaps,\r\n            invertY,\r\n            samplingMode,\r\n            type,\r\n            Constants.TEXTURE_CREATIONFLAG_STORAGE,\r\n            useSRGBBuffer\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a R texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @returns the R texture\r\n     */\r\n    public static CreateRTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_FLOAT\r\n    ): RawTexture {\r\n        return new RawTexture(data, width, height, Constants.TEXTUREFORMAT_R, sceneOrEngine, generateMipMaps, invertY, samplingMode, type);\r\n    }\r\n\r\n    /**\r\n     * Creates a R storage texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @returns the R texture\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static CreateRStorageTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        sceneOrEngine: Nullable<Scene | AbstractEngine>,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_FLOAT\r\n    ): RawTexture {\r\n        return new RawTexture(data, width, height, Constants.TEXTUREFORMAT_R, sceneOrEngine, generateMipMaps, invertY, samplingMode, type, Constants.TEXTURE_CREATIONFLAG_STORAGE);\r\n    }\r\n}\r\n","import { Bone } from \"./bone\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { type Animatable } from \"../Animations/animatable.core\";\r\nimport { type AnimationPropertiesOverride } from \"../Animations/animationPropertiesOverride\";\r\nimport { type Animation, AnimationMakeAnimationAdditive, AnimationParse } from \"../Animations/animation.pure\";\r\nimport { AnimationRange } from \"../Animations/animationRange\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { DeepCopier } from \"../Misc/deepCopier\";\r\nimport { type IInspectable } from \"../Misc/iInspectable\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode\";\r\n\r\n/**\r\n * Class used to handle skinning animations\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n */\r\nexport class Skeleton implements IAnimatable {\r\n    /**\r\n     * Defines the list of child bones\r\n     */\r\n    public bones: Bone[] = [];\r\n    /**\r\n     * Defines an estimate of the dimension of the skeleton at rest\r\n     */\r\n    public dimensionsAtRest: Vector3;\r\n    /**\r\n     * Defines a boolean indicating if the root matrix is provided by meshes or by the current skeleton (this is the default value)\r\n     */\r\n    public needInitialSkinMatrix = false;\r\n\r\n    /**\r\n     * Gets the list of animations attached to this skeleton\r\n     */\r\n    public animations: Array<Animation>;\r\n\r\n    private _scene: Scene;\r\n    private _isDirty = true;\r\n    private _transformMatrices: Float32Array;\r\n    private _transformMatrixTexture: Nullable<RawTexture>;\r\n    private _meshesWithPoseMatrix = new Array<AbstractMesh>();\r\n    private _animatables: IAnimatable[];\r\n    private _identity = Matrix.Identity();\r\n    private _synchronizedWithMesh: AbstractMesh;\r\n    private _currentRenderId = -1;\r\n\r\n    /** @internal */\r\n    public _textureWidth = 0;\r\n\r\n    /** @internal */\r\n    public _textureHeight = 1;\r\n\r\n    private _ranges: { [name: string]: Nullable<AnimationRange> } = {};\r\n\r\n    private _absoluteTransformIsDirty = true;\r\n\r\n    private _canUseTextureForBones = false;\r\n    private _uniqueId = 0;\r\n\r\n    /** @internal */\r\n    public _numBonesWithLinkedTransformNode = 0;\r\n\r\n    /** @internal */\r\n    public _hasWaitingData: Nullable<boolean> = null;\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /**\r\n     * Specifies if the skeleton should be serialized\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    private _useTextureToStoreBoneMatrices = true;\r\n    /**\r\n     * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).\r\n     * Please note that this option is not available if the hardware does not support it\r\n     */\r\n    public get useTextureToStoreBoneMatrices(): boolean {\r\n        return this._useTextureToStoreBoneMatrices;\r\n    }\r\n\r\n    public set useTextureToStoreBoneMatrices(value: boolean) {\r\n        this._useTextureToStoreBoneMatrices = value;\r\n        this._markAsDirty();\r\n    }\r\n\r\n    private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;\r\n\r\n    /**\r\n     * Gets or sets the animation properties override\r\n     */\r\n    public get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n        if (!this._animationPropertiesOverride) {\r\n            return this._scene.animationPropertiesOverride;\r\n        }\r\n        return this._animationPropertiesOverride;\r\n    }\r\n\r\n    public set animationPropertiesOverride(value: Nullable<AnimationPropertiesOverride>) {\r\n        this._animationPropertiesOverride = value;\r\n    }\r\n\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    public inspectableCustomProperties: IInspectable[];\r\n\r\n    // Events\r\n\r\n    /**\r\n     * An observable triggered before computing the skeleton's matrices\r\n     */\r\n    public onBeforeComputeObservable = new Observable<Skeleton>();\r\n\r\n    /**\r\n     * Gets a boolean indicating that the skeleton effectively stores matrices into a texture\r\n     */\r\n    public get isUsingTextureForMatrices() {\r\n        return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;\r\n    }\r\n\r\n    /**\r\n     * Gets the unique ID of this skeleton\r\n     */\r\n    public get uniqueId(): number {\r\n        return this._uniqueId;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the skeleton\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /**\r\n     * Creates a new skeleton\r\n     * @param name defines the skeleton name\r\n     * @param id defines the skeleton Id\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(\r\n        /** defines the skeleton name */\r\n        public name: string,\r\n        /** defines the skeleton Id */\r\n        public id: string,\r\n        scene: Scene\r\n    ) {\r\n        this.bones = [];\r\n\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        this._uniqueId = this._scene.getUniqueId();\r\n\r\n        this._scene.addSkeleton(this);\r\n\r\n        //make sure it will recalculate the matrix next time prepare is called.\r\n        this._isDirty = true;\r\n\r\n        const engineCaps = this._scene.getEngine().getCaps();\r\n        this._canUseTextureForBones = engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"Skeleton\";\r\n    }\r\n\r\n    /**\r\n     * Returns an array containing the root bones\r\n     * @returns an array containing the root bones\r\n     */\r\n    public getChildren(): Array<Bone> {\r\n        return this.bones.filter((b) => !b.getParent());\r\n    }\r\n\r\n    // Members\r\n    /**\r\n     * Gets the list of transform matrices to send to shaders (one matrix per bone)\r\n     * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\r\n     * @returns a Float32Array containing matrices data\r\n     */\r\n    public getTransformMatrices(mesh: Nullable<AbstractMesh>): Float32Array {\r\n        if (this.needInitialSkinMatrix) {\r\n            if (!mesh) {\r\n                throw new Error(\"getTransformMatrices: When using the needInitialSkinMatrix flag, a mesh must be provided\");\r\n            }\r\n            if (!mesh._bonesTransformMatrices) {\r\n                this.prepare(true);\r\n            }\r\n\r\n            return mesh._bonesTransformMatrices!;\r\n        }\r\n\r\n        if (!this._transformMatrices || this._isDirty) {\r\n            this.prepare(!this._transformMatrices);\r\n        }\r\n\r\n        return this._transformMatrices;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)\r\n     * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\r\n     * @returns a raw texture containing the data\r\n     */\r\n    public getTransformMatrixTexture(mesh: AbstractMesh): Nullable<RawTexture> {\r\n        if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {\r\n            return mesh._transformMatrixTexture;\r\n        }\r\n\r\n        return this._transformMatrixTexture;\r\n    }\r\n\r\n    /**\r\n     * Gets the current hosting scene\r\n     * @returns a scene object\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Gets a string representing the current skeleton data\r\n     * @param fullDetails defines a boolean indicating if we want a verbose version\r\n     * @returns a string representing the current skeleton data\r\n     */\r\n    public toString(fullDetails?: boolean): string {\r\n        let ret = `Name: ${this.name}, nBones: ${this.bones.length}`;\r\n        ret += `, nAnimationRanges: ${this._ranges ? Object.keys(this._ranges).length : \"none\"}`;\r\n        if (fullDetails) {\r\n            ret += \", Ranges: {\";\r\n            let first = true;\r\n            for (const name in this._ranges) {\r\n                if (first) {\r\n                    ret += \", \";\r\n                    first = false;\r\n                }\r\n                ret += name;\r\n            }\r\n            ret += \"}\";\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Get bone's index searching by name\r\n     * @param name defines bone's name to search for\r\n     * @returns the indice of the bone. Returns -1 if not found\r\n     */\r\n    public getBoneIndexByName(name: string): number {\r\n        for (let boneIndex = 0, cache = this.bones.length; boneIndex < cache; boneIndex++) {\r\n            if (this.bones[boneIndex].name === name) {\r\n                return boneIndex;\r\n            }\r\n        }\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Finds a bone in a skeleton that is linked to the given transform node.\r\n     * @param transformNode The transform node to find the bone for\r\n     * @returns The bone linked to the transform node, or null if not found\r\n     */\r\n    public findBoneFromLinkedTransformNode(transformNode: TransformNode) {\r\n        for (const bone of this.bones) {\r\n            if (bone._linkedTransformNode === transformNode) {\r\n                return bone;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Finds a bone in a skeleton by the name of its linked transform node.\r\n     * @param name The name of the linked transform node\r\n     * @returns The bone linked to the transform node with the given name, or null if not found\r\n     */\r\n    public findBoneFromLinkedTransformNodeName(name: string) {\r\n        for (const bone of this.bones) {\r\n            if (bone._linkedTransformNode && bone._linkedTransformNode.name === name) {\r\n                return bone;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Create a new animation range\r\n     * @param name defines the name of the range\r\n     * @param from defines the start key\r\n     * @param to defines the end key\r\n     */\r\n    public createAnimationRange(name: string, from: number, to: number): void {\r\n        // check name not already in use\r\n        if (!this._ranges[name]) {\r\n            this._ranges[name] = new AnimationRange(name, from, to);\r\n            for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n                if (this.bones[i].animations[0]) {\r\n                    this.bones[i].animations[0].createRange(name, from, to);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Delete a specific animation range\r\n     * @param name defines the name of the range\r\n     * @param deleteFrames defines if frames must be removed as well\r\n     */\r\n    public deleteAnimationRange(name: string, deleteFrames = true): void {\r\n        for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n            if (this.bones[i].animations[0]) {\r\n                this.bones[i].animations[0].deleteRange(name, deleteFrames);\r\n            }\r\n        }\r\n        this._ranges[name] = null; // said much faster than 'delete this._range[name]'\r\n    }\r\n\r\n    /**\r\n     * Gets a specific animation range\r\n     * @param name defines the name of the range to look for\r\n     * @returns the requested animation range or null if not found\r\n     */\r\n    public getAnimationRange(name: string): Nullable<AnimationRange> {\r\n        return this._ranges[name] || null;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of all animation ranges defined on this skeleton\r\n     * @returns an array\r\n     */\r\n    public getAnimationRanges(): Nullable<AnimationRange>[] {\r\n        const animationRanges: Nullable<AnimationRange>[] = [];\r\n        let name: string;\r\n        for (name in this._ranges) {\r\n            animationRanges.push(this._ranges[name]);\r\n        }\r\n        return animationRanges;\r\n    }\r\n\r\n    /**\r\n     * Copy animation range from a source skeleton.\r\n     * This is not for a complete retargeting, only between very similar skeleton's with only possible bone length differences\r\n     * @param source defines the source skeleton\r\n     * @param name defines the name of the range to copy\r\n     * @param rescaleAsRequired defines if rescaling must be applied if required\r\n     * @returns true if operation was successful\r\n     */\r\n    public copyAnimationRange(source: Skeleton, name: string, rescaleAsRequired = false): boolean {\r\n        if (this._ranges[name] || !source.getAnimationRange(name)) {\r\n            return false;\r\n        }\r\n        let ret = true;\r\n        const frameOffset = this._getHighestAnimationFrame() + 1;\r\n\r\n        // make a dictionary of source skeleton's bones, so exact same order or doubly nested loop is not required\r\n        const boneDict: { [key: string]: Bone } = {};\r\n        const sourceBones = source.bones;\r\n        let nBones: number;\r\n        let i: number;\r\n        for (i = 0, nBones = sourceBones.length; i < nBones; i++) {\r\n            boneDict[sourceBones[i].name] = sourceBones[i];\r\n        }\r\n\r\n        if (this.bones.length !== sourceBones.length) {\r\n            Logger.Warn(`copyAnimationRange: this rig has ${this.bones.length} bones, while source as ${sourceBones.length}`);\r\n            ret = false;\r\n        }\r\n\r\n        const skelDimensionsRatio = rescaleAsRequired && this.dimensionsAtRest && source.dimensionsAtRest ? this.dimensionsAtRest.divide(source.dimensionsAtRest) : null;\r\n\r\n        for (i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n            const boneName = this.bones[i].name;\r\n            const sourceBone = boneDict[boneName];\r\n            if (sourceBone) {\r\n                ret = ret && this.bones[i].copyAnimationRange(sourceBone, name, frameOffset, rescaleAsRequired, skelDimensionsRatio);\r\n            } else {\r\n                Logger.Warn(\"copyAnimationRange: not same rig, missing source bone \" + boneName);\r\n                ret = false;\r\n            }\r\n        }\r\n        // do not call createAnimationRange(), since it also is done to bones, which was already done\r\n        const range = source.getAnimationRange(name);\r\n        if (range) {\r\n            this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Forces the skeleton to go to rest pose\r\n     */\r\n    public returnToRest(): void {\r\n        for (const bone of this.bones) {\r\n            if (bone._index !== -1) {\r\n                bone.returnToRest();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getHighestAnimationFrame(): number {\r\n        let ret = 0;\r\n        for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n            if (this.bones[i].animations[0]) {\r\n                const highest = this.bones[i].animations[0].getHighestFrame();\r\n                if (ret < highest) {\r\n                    ret = highest;\r\n                }\r\n            }\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Begin a specific animation range\r\n     * @param name defines the name of the range to start\r\n     * @param loop defines if looping must be turned on (false by default)\r\n     * @param speedRatio defines the speed ratio to apply (1 by default)\r\n     * @param onAnimationEnd defines a callback which will be called when animation will end\r\n     * @returns a new animatable\r\n     */\r\n    public beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): Nullable<Animatable> {\r\n        const range = this.getAnimationRange(name);\r\n\r\n        if (!range) {\r\n            return null;\r\n        }\r\n\r\n        return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);\r\n    }\r\n\r\n    /**\r\n     * Convert the keyframes for a range of animation on a skeleton to be relative to a given reference frame.\r\n     * @param skeleton defines the Skeleton containing the animation range to convert\r\n     * @param referenceFrame defines the frame that keyframes in the range will be relative to\r\n     * @param range defines the name of the AnimationRange belonging to the Skeleton to convert\r\n     * @returns the original skeleton\r\n     */\r\n    public static MakeAnimationAdditive(skeleton: Skeleton, referenceFrame = 0, range: string): Nullable<Skeleton> {\r\n        const rangeValue = skeleton.getAnimationRange(range);\r\n\r\n        // We can't make a range additive if it doesn't exist\r\n        if (!rangeValue) {\r\n            return null;\r\n        }\r\n\r\n        // Find any current scene-level animatable belonging to the target that matches the range\r\n        const sceneAnimatables = skeleton._scene.getAllAnimatablesByTarget(skeleton);\r\n        let rangeAnimatable: Nullable<Animatable> = null;\r\n\r\n        for (let index = 0; index < sceneAnimatables.length; index++) {\r\n            const sceneAnimatable = sceneAnimatables[index];\r\n\r\n            if (sceneAnimatable.fromFrame === rangeValue?.from && sceneAnimatable.toFrame === rangeValue?.to) {\r\n                rangeAnimatable = sceneAnimatable;\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Convert the animations belonging to the skeleton to additive keyframes\r\n        const animatables = skeleton.getAnimatables();\r\n\r\n        for (let index = 0; index < animatables.length; index++) {\r\n            const animatable = animatables[index];\r\n            const animations = animatable.animations;\r\n\r\n            if (!animations) {\r\n                continue;\r\n            }\r\n\r\n            for (let animIndex = 0; animIndex < animations.length; animIndex++) {\r\n                AnimationMakeAnimationAdditive(animations[animIndex], referenceFrame, range);\r\n            }\r\n        }\r\n\r\n        // Mark the scene-level animatable as additive\r\n        if (rangeAnimatable) {\r\n            rangeAnimatable.isAdditive = true;\r\n        }\r\n\r\n        return skeleton;\r\n    }\r\n\r\n    /** @internal */\r\n    public _markAsDirty(): void {\r\n        this._isDirty = true;\r\n        this._absoluteTransformIsDirty = true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _registerMeshWithPoseMatrix(mesh: AbstractMesh): void {\r\n        this._meshesWithPoseMatrix.push(mesh);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _unregisterMeshWithPoseMatrix(mesh: AbstractMesh): void {\r\n        const index = this._meshesWithPoseMatrix.indexOf(mesh);\r\n\r\n        if (index > -1) {\r\n            this._meshesWithPoseMatrix.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    private _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Nullable<Matrix>): void {\r\n        this.onBeforeComputeObservable.notifyObservers(this);\r\n\r\n        for (let index = 0; index < this.bones.length; index++) {\r\n            const bone = this.bones[index];\r\n            bone._childUpdateId++;\r\n            const parentBone = bone.getParent();\r\n\r\n            if (parentBone) {\r\n                bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\r\n            } else {\r\n                if (initialSkinMatrix) {\r\n                    bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getFinalMatrix());\r\n                } else {\r\n                    bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\r\n                }\r\n            }\r\n\r\n            if (bone._index !== -1) {\r\n                const mappedIndex = bone._index === null ? index : bone._index;\r\n                bone.getAbsoluteInverseBindMatrix().multiplyToArray(bone.getFinalMatrix(), targetMatrix, mappedIndex * 16);\r\n            }\r\n        }\r\n\r\n        this._identity.copyToArray(targetMatrix, this.bones.length * 16);\r\n    }\r\n\r\n    private _computeTextureSize(): number {\r\n        const requiredElementCount = 4 * (this.bones.length + 1); // 16 element -> RGBA x 4\r\n        let requiredTextureWidth = requiredElementCount;\r\n        let requiredTextureHeight = 1;\r\n\r\n        if (this.isUsingTextureForMatrices) {\r\n            const maxTextureSize = this.getScene().getEngine().getCaps().maxTextureSize & ~3; // must be a multiple of 4\r\n            if (maxTextureSize < requiredTextureWidth) {\r\n                requiredTextureWidth = maxTextureSize;\r\n                requiredTextureHeight = Math.ceil(requiredElementCount / maxTextureSize);\r\n            }\r\n        }\r\n        this._textureWidth = requiredTextureWidth;\r\n        this._textureHeight = requiredTextureHeight;\r\n\r\n        return this._textureWidth * this._textureHeight * 4; // 4 floats per RGBA pixel\r\n    }\r\n\r\n    /**\r\n     * Build all resources required to render a skeleton\r\n     * @param dontCheckFrameId defines a boolean indicating if prepare should be run without checking first the current frame id (default: false)\r\n     */\r\n    public prepare(dontCheckFrameId = false): void {\r\n        if (!dontCheckFrameId) {\r\n            const currentRenderId = this.getScene().getRenderId();\r\n            if (this._currentRenderId === currentRenderId) {\r\n                return;\r\n            }\r\n            this._currentRenderId = currentRenderId;\r\n        }\r\n\r\n        // Update the local matrix of bones with linked transform nodes.\r\n        if (this._numBonesWithLinkedTransformNode > 0) {\r\n            for (const bone of this.bones) {\r\n                if (bone._linkedTransformNode) {\r\n                    const node = bone._linkedTransformNode;\r\n                    bone.position = node.position;\r\n                    if (node.rotationQuaternion) {\r\n                        bone.rotationQuaternion = node.rotationQuaternion;\r\n                    } else {\r\n                        bone.rotation = node.rotation;\r\n                    }\r\n                    bone.scaling = node.scaling;\r\n                }\r\n            }\r\n        }\r\n\r\n        let requiredTransformBufferElementCount: Nullable<number> = null;\r\n\r\n        if (this.needInitialSkinMatrix) {\r\n            for (const mesh of this._meshesWithPoseMatrix) {\r\n                const poseMatrix = mesh.getPoseMatrix();\r\n\r\n                let needsUpdate = this._isDirty;\r\n\r\n                if (requiredTransformBufferElementCount === null) {\r\n                    requiredTransformBufferElementCount = this._computeTextureSize();\r\n                }\r\n\r\n                if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== requiredTransformBufferElementCount) {\r\n                    mesh._bonesTransformMatrices = new Float32Array(requiredTransformBufferElementCount);\r\n                    needsUpdate = true;\r\n                }\r\n\r\n                if (!needsUpdate) {\r\n                    continue;\r\n                }\r\n\r\n                if (this._synchronizedWithMesh !== mesh) {\r\n                    this._synchronizedWithMesh = mesh;\r\n\r\n                    // Prepare bones\r\n                    for (const bone of this.bones) {\r\n                        if (!bone.getParent()) {\r\n                            const matrix = bone.getBindMatrix();\r\n                            matrix.multiplyToRef(poseMatrix, TmpVectors.Matrix[1]);\r\n                            bone._updateAbsoluteBindMatrices(TmpVectors.Matrix[1]);\r\n                        }\r\n                    }\r\n\r\n                    if (this.isUsingTextureForMatrices) {\r\n                        const meshTextureSize = mesh._transformMatrixTexture?.getSize();\r\n                        const meshTextureElementCount = meshTextureSize ? meshTextureSize.width * meshTextureSize.height * 4 : 0;\r\n                        if (!mesh._transformMatrixTexture || meshTextureElementCount !== requiredTransformBufferElementCount) {\r\n                            if (mesh._transformMatrixTexture) {\r\n                                mesh._transformMatrixTexture.dispose();\r\n                            }\r\n\r\n                            mesh._transformMatrixTexture = RawTexture.CreateRGBATexture(\r\n                                mesh._bonesTransformMatrices,\r\n                                this._textureWidth,\r\n                                this._textureHeight,\r\n                                this._scene,\r\n                                false,\r\n                                false,\r\n                                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                                Constants.TEXTURETYPE_FLOAT\r\n                            );\r\n                        }\r\n                    }\r\n                }\r\n\r\n                this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);\r\n\r\n                if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {\r\n                    mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);\r\n                }\r\n            }\r\n        } else {\r\n            if (!this._isDirty) {\r\n                return;\r\n            }\r\n\r\n            if (requiredTransformBufferElementCount === null) {\r\n                requiredTransformBufferElementCount = this._computeTextureSize();\r\n            }\r\n\r\n            if (!this._transformMatrices || this._transformMatrices.length !== requiredTransformBufferElementCount) {\r\n                this._transformMatrices = new Float32Array(requiredTransformBufferElementCount);\r\n\r\n                if (this.isUsingTextureForMatrices) {\r\n                    if (this._transformMatrixTexture) {\r\n                        this._transformMatrixTexture.dispose();\r\n                    }\r\n\r\n                    this._transformMatrixTexture = RawTexture.CreateRGBATexture(\r\n                        this._transformMatrices,\r\n                        this._textureWidth,\r\n                        this._textureHeight,\r\n                        this._scene,\r\n                        false,\r\n                        false,\r\n                        Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                        Constants.TEXTURETYPE_FLOAT\r\n                    );\r\n                }\r\n            }\r\n\r\n            this._computeTransformMatrices(this._transformMatrices, null);\r\n\r\n            if (this.isUsingTextureForMatrices && this._transformMatrixTexture) {\r\n                this._transformMatrixTexture.update(this._transformMatrices);\r\n            }\r\n        }\r\n\r\n        this._isDirty = false;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of animatables currently running for this skeleton\r\n     * @returns an array of animatables\r\n     */\r\n    public getAnimatables(): IAnimatable[] {\r\n        if (!this._animatables || this._animatables.length !== this.bones.length) {\r\n            this._animatables = [];\r\n\r\n            for (let index = 0; index < this.bones.length; index++) {\r\n                this._animatables.push(this.bones[index]);\r\n            }\r\n        }\r\n\r\n        return this._animatables;\r\n    }\r\n\r\n    /**\r\n     * Clone the current skeleton\r\n     * @param name defines the name of the new skeleton\r\n     * @param id defines the id of the new skeleton\r\n     * @returns the new skeleton\r\n     */\r\n    public clone(name: string, id?: string): Skeleton {\r\n        const result = new Skeleton(name, id || name, this._scene);\r\n\r\n        result.needInitialSkinMatrix = this.needInitialSkinMatrix;\r\n        result.metadata = this.metadata;\r\n\r\n        for (let index = 0; index < this.bones.length; index++) {\r\n            const source = this.bones[index];\r\n            let parentBone = null;\r\n\r\n            const parent = source.getParent();\r\n            if (parent) {\r\n                const parentIndex = this.bones.indexOf(parent);\r\n                parentBone = result.bones[parentIndex];\r\n            }\r\n\r\n            const bone = new Bone(source.name, result, parentBone, source.getBindMatrix().clone(), source.getRestMatrix().clone());\r\n            bone._index = source._index;\r\n\r\n            if (source._linkedTransformNode) {\r\n                bone.linkTransformNode(source._linkedTransformNode);\r\n            }\r\n\r\n            DeepCopier.DeepCopy(source.animations, bone.animations);\r\n        }\r\n\r\n        if (this._ranges) {\r\n            result._ranges = {};\r\n            for (const rangeName in this._ranges) {\r\n                const range = this._ranges[rangeName];\r\n\r\n                if (range) {\r\n                    result._ranges[rangeName] = range.clone();\r\n                }\r\n            }\r\n        }\r\n\r\n        this._isDirty = true;\r\n\r\n        result.prepare(true);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Enable animation blending for this skeleton\r\n     * @param blendingSpeed defines the blending speed to apply\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\r\n     */\r\n    public enableBlending(blendingSpeed = 0.01) {\r\n        for (const bone of this.bones) {\r\n            for (const animation of bone.animations) {\r\n                animation.enableBlending = true;\r\n                animation.blendingSpeed = blendingSpeed;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases all resources associated with the current skeleton\r\n     */\r\n    public dispose() {\r\n        this._meshesWithPoseMatrix.length = 0;\r\n        this.metadata = null;\r\n\r\n        // Animations\r\n        this.getScene().stopAnimation(this);\r\n\r\n        // Remove from scene\r\n        this.getScene().removeSkeleton(this);\r\n\r\n        if (this._parentContainer) {\r\n            const index = this._parentContainer.skeletons.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.skeletons.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        if (this._transformMatrixTexture) {\r\n            this._transformMatrixTexture.dispose();\r\n            this._transformMatrixTexture = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serialize the skeleton in a JSON object\r\n     * @returns a JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.id = this.id;\r\n        serializationObject.uniqueId = this.uniqueId;\r\n\r\n        if (this.dimensionsAtRest) {\r\n            serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();\r\n        }\r\n\r\n        serializationObject.bones = [];\r\n\r\n        serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;\r\n\r\n        if (this.metadata) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n\r\n        for (let index = 0; index < this.bones.length; index++) {\r\n            const bone = this.bones[index];\r\n            const parent = bone.getParent();\r\n\r\n            const serializedBone: any = {\r\n                parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,\r\n                index: bone.getIndex(),\r\n                name: bone.name,\r\n                id: bone.id,\r\n                uniqueId: bone.uniqueId,\r\n                matrix: bone.getBindMatrix().asArray(),\r\n                rest: bone.getRestMatrix().asArray(),\r\n                linkedTransformNodeId: bone.getTransformNode()?.id,\r\n                linkedTransformNodeUniqueId: bone.getTransformNode()?.uniqueId,\r\n            };\r\n\r\n            serializationObject.bones.push(serializedBone);\r\n\r\n            if (bone.length) {\r\n                serializedBone.length = bone.length;\r\n            }\r\n\r\n            if (bone.metadata) {\r\n                serializedBone.metadata = bone.metadata;\r\n            }\r\n\r\n            if (bone.animations && bone.animations.length > 0) {\r\n                serializedBone.animation = bone.animations[0].serialize();\r\n            }\r\n\r\n            serializationObject.ranges = [];\r\n            for (const name in this._ranges) {\r\n                const source = this._ranges[name];\r\n\r\n                if (!source) {\r\n                    continue;\r\n                }\r\n\r\n                const range: any = {};\r\n                range.name = name;\r\n                range.from = source.from;\r\n                range.to = source.to;\r\n                serializationObject.ranges.push(range);\r\n            }\r\n        }\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Creates a new skeleton from serialized data\r\n     * @param parsedSkeleton defines the serialized data\r\n     * @param scene defines the hosting scene\r\n     * @returns a new skeleton\r\n     */\r\n    public static Parse(parsedSkeleton: any, scene: Scene): Skeleton {\r\n        const skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);\r\n        if (parsedSkeleton.dimensionsAtRest) {\r\n            skeleton.dimensionsAtRest = Vector3.FromArray(parsedSkeleton.dimensionsAtRest);\r\n        }\r\n\r\n        skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;\r\n\r\n        if (parsedSkeleton.metadata) {\r\n            skeleton.metadata = parsedSkeleton.metadata;\r\n        }\r\n\r\n        let index: number;\r\n        for (index = 0; index < parsedSkeleton.bones.length; index++) {\r\n            const parsedBone = parsedSkeleton.bones[index];\r\n            const parsedBoneIndex = parsedSkeleton.bones[index].index;\r\n            let parentBone = null;\r\n            if (parsedBone.parentBoneIndex > -1) {\r\n                parentBone = skeleton.bones[parsedBone.parentBoneIndex];\r\n            }\r\n\r\n            const rest: Nullable<Matrix> = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;\r\n            const bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest, null, parsedBoneIndex);\r\n\r\n            if (parsedBone.id !== undefined && parsedBone.id !== null) {\r\n                bone.id = parsedBone.id;\r\n            }\r\n\r\n            if (parsedBone.length) {\r\n                bone.length = parsedBone.length;\r\n            }\r\n\r\n            if (parsedBone.metadata) {\r\n                bone.metadata = parsedBone.metadata;\r\n            }\r\n\r\n            if (parsedBone.animation) {\r\n                bone.animations.push(AnimationParse(parsedBone.animation));\r\n            }\r\n\r\n            if (parsedBone.linkedTransformNodeId !== undefined && parsedBone.linkedTransformNodeId !== null) {\r\n                skeleton._hasWaitingData = true;\r\n                bone._waitingTransformNodeId = parsedBone.linkedTransformNodeId;\r\n            }\r\n\r\n            if (parsedBone.linkedTransformNodeUniqueId !== undefined && parsedBone.linkedTransformNodeUniqueId !== null) {\r\n                skeleton._hasWaitingData = true;\r\n                bone._waitingTransformNodeUniqueId = parsedBone.linkedTransformNodeUniqueId;\r\n            }\r\n        }\r\n\r\n        // placed after bones, so createAnimationRange can cascade down\r\n        if (parsedSkeleton.ranges) {\r\n            for (index = 0; index < parsedSkeleton.ranges.length; index++) {\r\n                const data = parsedSkeleton.ranges[index];\r\n                skeleton.createAnimationRange(data.name, data.from, data.to);\r\n            }\r\n        }\r\n        return skeleton;\r\n    }\r\n\r\n    /**\r\n     * Compute all node absolute matrices\r\n     * @param forceUpdate defines if computation must be done even if cache is up to date\r\n     */\r\n    public computeAbsoluteMatrices(forceUpdate = false): void {\r\n        if (this._absoluteTransformIsDirty || forceUpdate) {\r\n            this.bones[0].computeAbsoluteMatrices();\r\n            this._absoluteTransformIsDirty = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Compute all node absolute matrices\r\n     * @param forceUpdate defines if computation must be done even if cache is up to date\r\n     * @deprecated Please use computeAbsoluteMatrices instead\r\n     */\r\n    public computeAbsoluteTransforms(forceUpdate = false): void {\r\n        this.computeAbsoluteMatrices(forceUpdate);\r\n    }\r\n\r\n    /**\r\n     * Gets the root pose matrix\r\n     * @returns a matrix\r\n     */\r\n    public getPoseMatrix(): Nullable<Matrix> {\r\n        let poseMatrix: Nullable<Matrix> = null;\r\n\r\n        if (this._meshesWithPoseMatrix.length > 0) {\r\n            poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();\r\n        }\r\n\r\n        return poseMatrix;\r\n    }\r\n\r\n    /**\r\n     * Sorts bones per internal index\r\n     */\r\n    public sortBones(): void {\r\n        const bones: Bone[] = [];\r\n        const visited = new Array<boolean>(this.bones.length);\r\n        for (let index = 0; index < this.bones.length; index++) {\r\n            this._sortBones(index, bones, visited);\r\n        }\r\n\r\n        this.bones = bones;\r\n    }\r\n\r\n    private _sortBones(index: number, bones: Bone[], visited: boolean[]): void {\r\n        if (visited[index]) {\r\n            return;\r\n        }\r\n\r\n        visited[index] = true;\r\n\r\n        const bone = this.bones[index];\r\n        if (!bone) {\r\n            return;\r\n        }\r\n\r\n        if (bone._index === undefined) {\r\n            bone._index = index;\r\n        }\r\n\r\n        const parentBone = bone.getParent();\r\n        if (parentBone) {\r\n            this._sortBones(this.bones.indexOf(parentBone), bones, visited);\r\n        }\r\n\r\n        bones.push(bone);\r\n    }\r\n\r\n    /**\r\n     * Set the current local matrix as the restPose for all bones in the skeleton.\r\n     */\r\n    public setCurrentPoseAsRest(): void {\r\n        for (const b of this.bones) {\r\n            b.setCurrentPoseAsRest();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type DepthTextureCreationOptions, type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { type RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.createDepthStencilTexture = function (size: TextureSize, options: DepthTextureCreationOptions, rtWrapper: RenderTargetWrapper): InternalTexture {\r\n        if (options.isCube) {\r\n            const width = (<{ width: number; height: number }>size).width || <number>size;\r\n            return this._createDepthStencilCubeTexture(width, options);\r\n        } else {\r\n            return this._createDepthStencilTexture(size, options, rtWrapper);\r\n        }\r\n    };\r\n}\r\n","import {\r\n    type Nullable,\r\n    type Immutable,\r\n    type Camera,\r\n    type Scene,\r\n    type AbstractMesh,\r\n    type SubMesh,\r\n    type Material,\r\n    type IParticleSystem,\r\n    type InstancedMesh,\r\n    type BoundingBox,\r\n    type BoundingBoxRenderer,\r\n    type AbstractEngine,\r\n    type ClusteredLightContainer,\r\n    type Mesh,\r\n    type ISpriteManager,\r\n} from \"core/index\";\r\nimport { UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { RenderingManager } from \"../Rendering/renderingManager\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { _ObserveArray } from \"../Misc/arrayTools\";\r\nimport { _RetryWithInterval } from \"../Misc/timingTools\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { LightConstants } from \"../Lights/lightConstants\";\r\n\r\n/**\r\n * Defines the options of the object renderer\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface ObjectRendererOptions {\r\n    /** The number of passes the renderer will support (1 by default) */\r\n    numPasses?: number;\r\n\r\n    /** True (default) to not change the aspect ratio of the scene in the RTT */\r\n    doNotChangeAspectRatio?: boolean;\r\n\r\n    /** True to enable clustered lights (default: false) */\r\n    enableClusteredLights?: boolean;\r\n}\r\n\r\n/**\r\n * A class that renders objects to the currently bound render target.\r\n * This class only renders objects, and is not concerned with the output texture or post-processing.\r\n */\r\nexport class ObjectRenderer {\r\n    /**\r\n     * Objects will only be rendered once which can be useful to improve performance if everything in your render is static for instance.\r\n     */\r\n    public static readonly REFRESHRATE_RENDER_ONCE: number = 0;\r\n    /**\r\n     * Objects will be rendered every frame and is recommended for dynamic contents.\r\n     */\r\n    public static readonly REFRESHRATE_RENDER_ONEVERYFRAME: number = 1;\r\n    /**\r\n     * Objects will be rendered every 2 frames which could be enough if your dynamic objects are not\r\n     * the central point of your effect and can save a lot of performances.\r\n     */\r\n    public static readonly REFRESHRATE_RENDER_ONEVERYTWOFRAMES: number = 2;\r\n\r\n    /**\r\n     * Use this predicate to dynamically define the list of mesh you want to render.\r\n     * If set, the renderList property will be overwritten.\r\n     */\r\n    public renderListPredicate: (AbstractMesh: AbstractMesh) => boolean;\r\n\r\n    private _renderList: Nullable<Array<AbstractMesh>>;\r\n    private _unObserveRenderList: Nullable<() => void> = null;\r\n\r\n    /**\r\n     * Use this list to define the list of mesh you want to render.\r\n     */\r\n    public get renderList(): Nullable<Array<AbstractMesh>> {\r\n        return this._renderList;\r\n    }\r\n\r\n    public set renderList(value: Nullable<Array<AbstractMesh>>) {\r\n        if (this._renderList === value) {\r\n            return;\r\n        }\r\n        if (this._unObserveRenderList) {\r\n            this._unObserveRenderList();\r\n            this._unObserveRenderList = null;\r\n        }\r\n\r\n        if (value) {\r\n            this._unObserveRenderList = _ObserveArray(value, this._renderListHasChanged);\r\n        }\r\n\r\n        this._renderList = value;\r\n    }\r\n\r\n    private _renderListHasChanged = (_functionName: string, previousLength: number) => {\r\n        const newLength = this._renderList ? this._renderList.length : 0;\r\n        if ((previousLength === 0 && newLength > 0) || newLength === 0) {\r\n            for (const mesh of this._scene.meshes) {\r\n                mesh._markSubMeshesAsLightDirty();\r\n            }\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Define the list of particle systems to render. If not provided, will render all the particle systems of the scene.\r\n     * Note that the particle systems are rendered only if renderParticles is set to true.\r\n     */\r\n    public particleSystemList: Nullable<Array<IParticleSystem>> = null;\r\n\r\n    /**\r\n     * Define the list of sprite managers to render. If not provided, will render all the sprite managers of the scene.\r\n     * An empty array will render no sprite managers.\r\n     * Note that the sprite managers are rendered only if renderSprites is set to true.\r\n     */\r\n    public spriteManagerList: Nullable<Array<ISpriteManager>> = null;\r\n\r\n    /**\r\n     * Use this function to overload the renderList array at rendering time.\r\n     * Return null to render with the current renderList, else return the list of meshes to use for rendering.\r\n     * For 2DArray, layerOrFace is the index of the layer that is going to be rendered, else it is the faceIndex of\r\n     * the cube (if the RTT is a cube, else layerOrFace=0).\r\n     * The renderList passed to the function is the current render list (the one that will be used if the function returns null).\r\n     * The length of this list is passed through renderListLength: don't use renderList.length directly because the array can\r\n     * hold dummy elements!\r\n     */\r\n    public getCustomRenderList: Nullable<(layerOrFace: number, renderList: Nullable<Immutable<Array<AbstractMesh>>>, renderListLength: number) => Nullable<Array<AbstractMesh>>> =\r\n        null;\r\n\r\n    /**\r\n     * Define if meshes should be rendered (default is true).\r\n     */\r\n    public renderMeshes = true;\r\n\r\n    /**\r\n     * Define if depth only meshes should be rendered (default is true). No effect if renderMeshes is false.\r\n     */\r\n    public renderDepthOnlyMeshes = true;\r\n\r\n    /**\r\n     * Define if opaque meshes should be rendered (default is true). No effect if renderMeshes is false.\r\n     */\r\n    public renderOpaqueMeshes = true;\r\n\r\n    /**\r\n     * Define if alpha test meshes should be rendered (default is true). No effect if renderMeshes is false.\r\n     */\r\n    public renderAlphaTestMeshes = true;\r\n\r\n    /**\r\n     * Define if transparent meshes should be rendered (default is true). No effect if renderMeshes is false.\r\n     */\r\n    public renderTransparentMeshes = true;\r\n\r\n    /**\r\n     * Custom render function for transparent submeshes.\r\n     */\r\n    public customRenderTransparentSubMeshes?: (transparentSubMeshes: SmartArray<SubMesh>) => void;\r\n\r\n    /**\r\n     * Define if particles should be rendered (default is true).\r\n     */\r\n    public renderParticles = true;\r\n\r\n    /**\r\n     * Define if sprites should be rendered (default is false).\r\n     */\r\n    public renderSprites = false;\r\n\r\n    /**\r\n     * Force checking the layerMask property even if a custom list of meshes is provided (ie. if renderList is not undefined)\r\n     */\r\n    public forceLayerMaskCheck = false;\r\n\r\n    /**\r\n     * Enables the rendering of bounding boxes for meshes (still subject to Mesh.showBoundingBox or scene.forceShowBoundingBoxes). Default is false.\r\n     */\r\n    public enableBoundingBoxRendering = false;\r\n\r\n    /**\r\n     * Enables the rendering of outline/overlay for meshes (still subject to Mesh.renderOutline/Mesh.renderOverlay). Default is true.\r\n     */\r\n    public enableOutlineRendering = true;\r\n\r\n    /**\r\n     * Define the camera used to render the objects.\r\n     */\r\n    public activeCamera: Nullable<Camera>;\r\n\r\n    /**\r\n     * Define the camera used to calculate the LOD of the objects.\r\n     * If not defined, activeCamera will be used. If not defined nor activeCamera, scene's active camera will be used.\r\n     */\r\n    public cameraForLOD: Nullable<Camera>;\r\n\r\n    private _disableImageProcessing = false;\r\n    /**\r\n     * If true, the object renderer will render all objects without any image processing applied.\r\n     * If false (default value), the renderer will use the current setting of the scene's image processing configuration.\r\n     */\r\n    public get disableImageProcessing() {\r\n        return this._disableImageProcessing;\r\n    }\r\n\r\n    public set disableImageProcessing(value: boolean) {\r\n        if (value === this._disableImageProcessing) {\r\n            return;\r\n        }\r\n\r\n        this._disableImageProcessing = value;\r\n        this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_ImageProcessingDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * If true, the object renderer will not set the view/projection/transformation matrices for the active camera (default: false).\r\n     * By default, the view/projection/transformation matrices are set from the active camera (either ObjectRenderer.activeCamera or scene.activeCamera).\r\n     * Sets this property to true if you want to define your own transformation matrices (use the onInitRenderingObservable observable\r\n     * to set your own matrices, to be sure they will be correctly taken into account)\r\n     */\r\n    public dontSetTransformationMatrix = false;\r\n\r\n    private _disableDepthPrePass = false;\r\n    /**\r\n     * Specifies to disable depth pre-pass if true (default: false)\r\n     */\r\n    public get disableDepthPrePass() {\r\n        return this._disableDepthPrePass;\r\n    }\r\n\r\n    public set disableDepthPrePass(value: boolean) {\r\n        this._disableDepthPrePass = value;\r\n        this._renderingManager.disableDepthPrePass = value;\r\n    }\r\n\r\n    /**\r\n     * Override the mesh isReady function with your own one.\r\n     */\r\n    public customIsReadyFunction: (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => boolean;\r\n\r\n    /**\r\n     * Override the render function with your own one.\r\n     */\r\n    public customRenderFunction: (\r\n        opaqueSubMeshes: SmartArray<SubMesh>,\r\n        alphaTestSubMeshes: SmartArray<SubMesh>,\r\n        transparentSubMeshes: SmartArray<SubMesh>,\r\n        depthOnlySubMeshes: SmartArray<SubMesh>,\r\n        beforeTransparents?: () => void\r\n    ) => void;\r\n\r\n    /**\r\n     * An event triggered before rendering the objects.\r\n     * Note: This observable is also triggered during readiness checks (e.g. when calling scene.isReady()),\r\n     * in which case the render target is not bound to the output. Observers should avoid performing\r\n     * GPU state changes (such as clearing or modifying the framebuffer) unless the render target is actually bound.\r\n     */\r\n    public readonly onBeforeRenderObservable = new Observable<number>();\r\n\r\n    /**\r\n     * An event triggered after rendering the objects.\r\n     * Note: This observable is also triggered during readiness checks (e.g. when calling scene.isReady()),\r\n     * in which case the render target is not bound to the output. Observers should avoid performing\r\n     * GPU state changes (such as clearing or modifying the framebuffer) unless the render target is actually bound.\r\n     */\r\n    public readonly onAfterRenderObservable = new Observable<number>();\r\n\r\n    /**\r\n     * An event triggered before the rendering group is processed\r\n     */\r\n    public readonly onBeforeRenderingManagerRenderObservable = new Observable<number>();\r\n\r\n    /**\r\n     * An event triggered after the rendering group is processed\r\n     */\r\n    public readonly onAfterRenderingManagerRenderObservable = new Observable<number>();\r\n\r\n    /**\r\n     * An event triggered when initRender is called\r\n     */\r\n    public readonly onInitRenderingObservable = new Observable<ObjectRenderer>();\r\n\r\n    /**\r\n     * An event triggered when finishRender is called\r\n     */\r\n    public readonly onFinishRenderingObservable = new Observable<ObjectRenderer>();\r\n\r\n    /**\r\n     * An event triggered when fast path rendering is used\r\n     */\r\n    public readonly onFastPathRenderObservable = new Observable<number>();\r\n\r\n    protected _engine: AbstractEngine;\r\n    protected _scene: Scene;\r\n    protected _renderingManager: RenderingManager;\r\n    /** @internal */\r\n    public _waitingRenderList?: string[];\r\n    protected _currentRefreshId = -1;\r\n    protected _refreshRate = 1;\r\n    protected _currentApplyByPostProcessSetting = false;\r\n    protected _activeMeshes = new SmartArray<AbstractMesh>(256);\r\n    protected _activeBoundingBoxes = new SmartArray<BoundingBox>(32);\r\n    protected _useUBO: boolean;\r\n    protected _sceneUBOs: UniformBuffer[]; // It's an array because we may need multiple ubos per frame if the object renderer is used several times in a frame (e.g. for rigged cameras)\r\n    protected _sceneUBOIsMultiview: boolean[]; // Parallel array caching the multiview state per UBO slot — avoids getUniformNames().indexOf() in the hot path\r\n    protected _currentSceneUBO: UniformBuffer;\r\n    protected _currentFrameId = -1;\r\n    protected _currentSceneUBOIndex = 0;\r\n\r\n    /**\r\n     * The options used by the object renderer\r\n     */\r\n    public options: Required<ObjectRendererOptions>;\r\n\r\n    private _name: string;\r\n    /**\r\n     * Friendly name of the object renderer\r\n     */\r\n    public get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        if (this._name === value) {\r\n            return;\r\n        }\r\n\r\n        this._name = value;\r\n        if (this._sceneUBOs) {\r\n            for (let i = 0; i < this._sceneUBOs.length; ++i) {\r\n                this._sceneUBOs[i].name = `Scene ubo #${i} for ${this.name}`;\r\n            }\r\n        }\r\n\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < this._renderPassIds.length; ++i) {\r\n            const renderPassId = this._renderPassIds[i];\r\n            this._engine._renderPassNames[renderPassId] = `${this._name}#${i}`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Current render pass id. Note it can change over the rendering as there's a separate id for each face of a cube / each layer of an array layer!\r\n     */\r\n    public renderPassId: number;\r\n    private readonly _renderPassIds: number[];\r\n    /**\r\n     * Gets the render pass ids used by the object renderer.\r\n     */\r\n    public get renderPassIds(): readonly number[] {\r\n        return this._renderPassIds;\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the refreshId counter\r\n     */\r\n    public get currentRefreshId() {\r\n        return this._currentRefreshId;\r\n    }\r\n\r\n    /**\r\n     * Gets the array of active meshes\r\n     * @returns an array of AbstractMesh\r\n     */\r\n    public getActiveMeshes(): SmartArray<AbstractMesh> {\r\n        return this._activeMeshes;\r\n    }\r\n\r\n    /**\r\n     * Sets a specific material to be used to render a mesh/a list of meshes with this object renderer\r\n     * @param mesh mesh or array of meshes\r\n     * @param material material or array of materials to use for this render pass. If undefined is passed, no specific material will be used but the regular material instead (mesh.material). It's possible to provide an array of materials to use a different material for each rendering pass.\r\n     */\r\n    public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material | Material[]): void {\r\n        let meshes;\r\n        if (!Array.isArray(mesh)) {\r\n            meshes = [mesh];\r\n        } else {\r\n            meshes = mesh;\r\n        }\r\n        for (let j = 0; j < meshes.length; ++j) {\r\n            for (let i = 0; i < this.options.numPasses; ++i) {\r\n                let mesh = meshes[j];\r\n                if (meshes[j].isAnInstance) {\r\n                    mesh = (meshes[j] as InstancedMesh).sourceMesh;\r\n                }\r\n                mesh.setMaterialForRenderPass(this._renderPassIds[i], material !== undefined ? (Array.isArray(material) ? material[i] : material) : undefined);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _isFrozen = false;\r\n\r\n    /** @internal */\r\n    public _freezeActiveMeshesCancel: Nullable<() => void> = null;\r\n\r\n    /** @internal */\r\n    public _freezeActiveMeshes(freezeMeshes: boolean) {\r\n        this._freezeActiveMeshesCancel = _RetryWithInterval(\r\n            () => {\r\n                return this._checkReadiness();\r\n            },\r\n            () => {\r\n                this._freezeActiveMeshesCancel = null;\r\n                if (freezeMeshes) {\r\n                    for (let index = 0; index < this._activeMeshes.length; index++) {\r\n                        this._activeMeshes.data[index]._freeze();\r\n                    }\r\n                }\r\n                this._prepareRenderingManager(0, true);\r\n                this._isFrozen = true;\r\n            },\r\n            (err, isTimeout) => {\r\n                this._freezeActiveMeshesCancel = null;\r\n                if (!isTimeout) {\r\n                    Logger.Error(\"ObjectRenderer: An unexpected error occurred while waiting for the renderer to be ready.\");\r\n                    if (err) {\r\n                        Logger.Error(err);\r\n                        if (err.stack) {\r\n                            Logger.Error(err.stack);\r\n                        }\r\n                    }\r\n                } else {\r\n                    Logger.Error(`ObjectRenderer: Timeout while waiting for the renderer to be ready.`);\r\n                    if (err) {\r\n                        Logger.Error(err);\r\n                    }\r\n                }\r\n            }\r\n        );\r\n    }\r\n\r\n    /** @internal */\r\n    public _unfreezeActiveMeshes() {\r\n        this._freezeActiveMeshesCancel?.();\r\n        this._freezeActiveMeshesCancel = null;\r\n        for (let index = 0; index < this._activeMeshes.length; index++) {\r\n            this._activeMeshes.data[index]._unFreeze();\r\n        }\r\n        this._isFrozen = false;\r\n    }\r\n\r\n    /**\r\n     * Instantiates an object renderer.\r\n     * @param name The friendly name of the object renderer\r\n     * @param scene The scene the renderer belongs to\r\n     * @param options The options used to create the renderer (optional)\r\n     */\r\n    constructor(name: string, scene: Scene, options?: ObjectRendererOptions) {\r\n        this.name = name;\r\n        this._scene = scene;\r\n        this._engine = this._scene.getEngine();\r\n        this._useUBO = this._engine.supportsUniformBuffers;\r\n\r\n        this.renderList = [] as AbstractMesh[];\r\n        this._renderPassIds = [];\r\n\r\n        this.options = {\r\n            numPasses: 1,\r\n            doNotChangeAspectRatio: true,\r\n            enableClusteredLights: false,\r\n            ...options,\r\n        };\r\n\r\n        this._createRenderPassId();\r\n\r\n        this.renderPassId = this._renderPassIds[0];\r\n\r\n        // Rendering groups\r\n        this._renderingManager = new RenderingManager(scene);\r\n        this._renderingManager._useSceneAutoClearSetup = true;\r\n\r\n        if (this.options.enableClusteredLights) {\r\n            this.onInitRenderingObservable.add(() => {\r\n                for (const light of this._scene.lights) {\r\n                    if (light.getTypeID() === LightConstants.LIGHTTYPEID_CLUSTERED_CONTAINER && (light as ClusteredLightContainer).isSupported) {\r\n                        (light as ClusteredLightContainer)._updateBatches(this.activeCamera).render();\r\n                    }\r\n                }\r\n            });\r\n        }\r\n\r\n        this._scene.addObjectRenderer(this);\r\n    }\r\n\r\n    private _releaseRenderPassId(): void {\r\n        for (let i = 0; i < this.options.numPasses; ++i) {\r\n            this._engine.releaseRenderPassId(this._renderPassIds[i]);\r\n        }\r\n        this._renderPassIds.length = 0;\r\n    }\r\n\r\n    private _createRenderPassId(): void {\r\n        this._releaseRenderPassId();\r\n\r\n        for (let i = 0; i < this.options.numPasses; ++i) {\r\n            this._renderPassIds[i] = this._engine.createRenderPassId(`${this.name}#${i}`);\r\n        }\r\n    }\r\n\r\n    private _createSceneUBO(name: string, isMultiview: boolean): UniformBuffer {\r\n        const engine = this._scene.getEngine();\r\n        const ubo = new UniformBuffer(engine, undefined, isMultiview, name, undefined, false);\r\n        ubo.addUniform(\"viewProjection\", 16);\r\n        if (isMultiview) {\r\n            ubo.addUniform(\"viewProjectionR\", 16);\r\n        }\r\n        ubo.addUniform(\"view\", 16);\r\n        ubo.addUniform(\"projection\", 16);\r\n        ubo.addUniform(\"vEyePosition\", 4);\r\n        ubo.addUniform(\"inverseProjection\", 16);\r\n        return ubo;\r\n    }\r\n\r\n    private _getSceneUBO(): UniformBuffer {\r\n        if (this._currentFrameId !== this._engine.frameId) {\r\n            this._currentSceneUBOIndex = 0;\r\n            this._currentFrameId = this._engine.frameId;\r\n        }\r\n\r\n        if (!this._sceneUBOs) {\r\n            this._sceneUBOs = [];\r\n            this._sceneUBOIsMultiview = [];\r\n        }\r\n\r\n        const activeRenderTarget = this._engine._currentRenderTarget;\r\n        const isMultiview = !!(activeRenderTarget && activeRenderTarget.texture?.isMultiview) || !!(this._scene as any)._multiviewSceneUboIsActive;\r\n\r\n        // Check if we have enough UBOs or if the current one is compatible\r\n        if (this._currentSceneUBOIndex >= this._sceneUBOs.length) {\r\n            const index = this._sceneUBOs.length;\r\n            this._sceneUBOs.push(this._createSceneUBO(`Scene ubo #${index} for ${this.name}`, isMultiview));\r\n            this._sceneUBOIsMultiview.push(isMultiview);\r\n        } else if (this._sceneUBOIsMultiview[this._currentSceneUBOIndex] !== isMultiview) {\r\n            // Layout mismatch, recreate\r\n            this._sceneUBOs[this._currentSceneUBOIndex].dispose();\r\n            this._sceneUBOs[this._currentSceneUBOIndex] = this._createSceneUBO(`Scene ubo #${this._currentSceneUBOIndex} for ${this.name}`, isMultiview);\r\n            this._sceneUBOIsMultiview[this._currentSceneUBOIndex] = isMultiview;\r\n        }\r\n\r\n        const ubo = this._sceneUBOs[this._currentSceneUBOIndex++];\r\n        ubo.unbindEffect();\r\n\r\n        return ubo;\r\n    }\r\n\r\n    /**\r\n     * Resets the refresh counter of the renderer and start back from scratch.\r\n     * Could be useful to re-render if it is setup to render only once.\r\n     */\r\n    public resetRefreshCounter(): void {\r\n        this._currentRefreshId = -1;\r\n    }\r\n\r\n    /**\r\n     * Defines the refresh rate of the rendering or the rendering frequency.\r\n     * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...\r\n     */\r\n    public get refreshRate(): number {\r\n        return this._refreshRate;\r\n    }\r\n    public set refreshRate(value: number) {\r\n        this._refreshRate = value;\r\n        this.resetRefreshCounter();\r\n    }\r\n\r\n    /**\r\n     * Indicates if the renderer should render the current frame.\r\n     * The output is based on the specified refresh rate.\r\n     * When snapshot rendering is active, this always returns true to ensure render pass\r\n     * topology stays consistent between the recording frame and playback frames.\r\n     * @returns true if the renderer should render the current frame\r\n     */\r\n    public shouldRender(): boolean {\r\n        if (this._engine.snapshotRendering) {\r\n            // When snapshot rendering is active (recording or playing), we must always render\r\n            // to ensure the number of render passes stays consistent between the recording frame\r\n            // and all playback frames. If a render target is skipped during recording but not\r\n            // during playback (or vice versa), the recorded bundle list indices become misaligned,\r\n            // causing visual artifacts such as flickering.\r\n            return true;\r\n        }\r\n\r\n        if (this._currentRefreshId === -1) {\r\n            // At least render once\r\n            this._currentRefreshId = 1;\r\n            return true;\r\n        }\r\n\r\n        if (this.refreshRate === this._currentRefreshId) {\r\n            this._currentRefreshId = 1;\r\n            return true;\r\n        }\r\n\r\n        this._currentRefreshId++;\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * This function will check if the renderer is ready to render (textures are loaded, shaders are compiled)\r\n     * @param viewportWidth defines the width of the viewport\r\n     * @param viewportHeight defines the height of the viewport\r\n     * @returns true if all required resources are ready\r\n     */\r\n    public isReadyForRendering(viewportWidth: number, viewportHeight: number): boolean {\r\n        this.prepareRenderList();\r\n        this.initRender(viewportWidth, viewportHeight);\r\n\r\n        const isReady = this._checkReadiness();\r\n\r\n        this.finishRender();\r\n\r\n        return isReady;\r\n    }\r\n\r\n    /**\r\n     * Makes sure the list of meshes is ready to be rendered\r\n     * You should call this function before \"initRender\", but if you know the render list is ok, you may call \"initRender\" directly\r\n     */\r\n    public prepareRenderList(): void {\r\n        const scene = this._scene;\r\n\r\n        if (this._waitingRenderList) {\r\n            if (!this.renderListPredicate) {\r\n                this.renderList = [];\r\n                for (let index = 0; index < this._waitingRenderList.length; index++) {\r\n                    const id = this._waitingRenderList[index];\r\n                    const mesh = scene.getMeshById(id);\r\n                    if (mesh) {\r\n                        this.renderList.push(mesh);\r\n                    }\r\n                }\r\n            }\r\n            this._waitingRenderList = undefined;\r\n        }\r\n\r\n        // Is predicate defined?\r\n        if (this.renderListPredicate) {\r\n            if (this.renderList) {\r\n                this.renderList.length = 0; // Clear previous renderList\r\n            } else {\r\n                this.renderList = [];\r\n            }\r\n\r\n            const sceneMeshes = this._scene.meshes;\r\n\r\n            for (let index = 0; index < sceneMeshes.length; index++) {\r\n                const mesh = sceneMeshes[index];\r\n                if (this.renderListPredicate(mesh)) {\r\n                    this.renderList.push(mesh);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._currentApplyByPostProcessSetting = this._scene.imageProcessingConfiguration.applyByPostProcess;\r\n        if (this._disableImageProcessing) {\r\n            // we do not use the applyByPostProcess setter to avoid flagging all the materials as \"image processing dirty\"!\r\n            this._scene.imageProcessingConfiguration._applyByPostProcess = this._disableImageProcessing;\r\n        }\r\n    }\r\n\r\n    private _defaultRenderListPrepared: boolean;\r\n    private _currentSceneCamera: Nullable<Camera> = null;\r\n\r\n    /**\r\n     * This method makes sure everything is setup before \"render\" can be called\r\n     * @param viewportWidth Width of the viewport to render to\r\n     * @param viewportHeight Height of the viewport to render to\r\n     */\r\n    public initRender(viewportWidth: number, viewportHeight: number): void {\r\n        const camera: Nullable<Camera> = this.activeCamera ?? this._scene.activeCamera;\r\n\r\n        this._currentSceneCamera = this._scene.activeCamera;\r\n\r\n        if (this._useUBO) {\r\n            this._currentSceneUBO = this._scene.getSceneUniformBuffer();\r\n            this._currentSceneUBO.unbindEffect();\r\n            this._scene.setSceneUniformBuffer(this._getSceneUBO());\r\n        }\r\n\r\n        this.onInitRenderingObservable.notifyObservers(this);\r\n\r\n        if (camera) {\r\n            if (!this.dontSetTransformationMatrix) {\r\n                this._scene.setTransformMatrix(camera.getViewMatrix(), camera.getProjectionMatrix(true));\r\n            }\r\n            // Use _activeCamera instead of activeCamera to avoid onActiveCameraChanged for this internal render pass.\r\n            this._scene._activeCamera = camera;\r\n            this._engine.setViewport(camera.rigParent ? camera.rigParent.viewport : camera.viewport, viewportWidth, viewportHeight);\r\n        }\r\n\r\n        if (this._useUBO) {\r\n            this._scene.finalizeSceneUbo();\r\n        }\r\n\r\n        this._defaultRenderListPrepared = false;\r\n    }\r\n\r\n    /**\r\n     * This method must be called after the \"render\" call(s), to complete the rendering process.\r\n     */\r\n    public finishRender() {\r\n        const scene = this._scene;\r\n\r\n        if (this._useUBO) {\r\n            this._scene.setSceneUniformBuffer(this._currentSceneUBO);\r\n        }\r\n\r\n        if (this._disableImageProcessing) {\r\n            scene.imageProcessingConfiguration._applyByPostProcess = this._currentApplyByPostProcessSetting;\r\n        }\r\n\r\n        // Use _activeCamera instead of activeCamera to avoid onActiveCameraChanged for this internal render pass.\r\n        scene._activeCamera = this._currentSceneCamera;\r\n        if (this._currentSceneCamera) {\r\n            if (this.activeCamera && this.activeCamera !== scene.activeCamera) {\r\n                scene.setTransformMatrix(this._currentSceneCamera.getViewMatrix(), this._currentSceneCamera.getProjectionMatrix(true));\r\n            }\r\n            this._engine.setViewport(this._currentSceneCamera.viewport);\r\n        }\r\n\r\n        scene.resetCachedMaterial();\r\n\r\n        this.onFinishRenderingObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Renders all the objects (meshes, particles systems, sprites) to the currently bound render target texture.\r\n     * @param passIndex defines the pass index to use (default: 0)\r\n     * @param skipOnAfterRenderObservable defines a flag to skip raising the onAfterRenderObservable\r\n     */\r\n    public render(passIndex = 0, skipOnAfterRenderObservable = false): void {\r\n        const currentRenderPassId = this._engine.currentRenderPassId;\r\n\r\n        this._engine.currentRenderPassId = this._renderPassIds[passIndex];\r\n\r\n        this.onBeforeRenderObservable.notifyObservers(passIndex);\r\n\r\n        const fastPath = this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n\r\n        if (!fastPath) {\r\n            const currentRenderList = this._prepareRenderingManager(passIndex);\r\n\r\n            // The cast to \"any\" is to avoid an error in ES6 in case you don't import outlineRenderer\r\n            const outlineRenderer = (this._scene as any).getOutlineRenderer?.();\r\n            const outlineRendererIsEnabled = outlineRenderer?.enabled;\r\n\r\n            if (outlineRenderer) {\r\n                outlineRenderer.enabled = this.enableOutlineRendering;\r\n            }\r\n\r\n            this.onBeforeRenderingManagerRenderObservable.notifyObservers(passIndex);\r\n\r\n            this._renderingManager.render(\r\n                this.customRenderFunction,\r\n                currentRenderList,\r\n                this.renderParticles,\r\n                this.renderSprites,\r\n                this.renderDepthOnlyMeshes,\r\n                this.renderOpaqueMeshes,\r\n                this.renderAlphaTestMeshes,\r\n                this.renderTransparentMeshes,\r\n                this.customRenderTransparentSubMeshes,\r\n                this.spriteManagerList\r\n            );\r\n            this.onAfterRenderingManagerRenderObservable.notifyObservers(passIndex);\r\n\r\n            if (outlineRenderer) {\r\n                outlineRenderer.enabled = outlineRendererIsEnabled;\r\n            }\r\n        } else {\r\n            this.onFastPathRenderObservable.notifyObservers(passIndex);\r\n        }\r\n\r\n        if (!skipOnAfterRenderObservable) {\r\n            this.onAfterRenderObservable.notifyObservers(passIndex);\r\n        }\r\n\r\n        this._engine.currentRenderPassId = currentRenderPassId;\r\n    }\r\n\r\n    /** @internal */\r\n    public _checkReadiness(): boolean {\r\n        const scene = this._scene;\r\n        const currentRenderPassId = this._engine.currentRenderPassId;\r\n\r\n        let returnValue = true;\r\n\r\n        if (!scene.getViewMatrix()) {\r\n            // We probably didn't execute scene.render() yet, so make sure we have a view/projection matrix setup for the scene\r\n            scene.updateTransformMatrix();\r\n        }\r\n\r\n        const numPasses = this.options.numPasses;\r\n        for (let passIndex = 0; passIndex < numPasses && returnValue; passIndex++) {\r\n            const defaultRenderList = this.renderList ? this.renderList : scene.frameGraph ? scene.meshes : scene.getActiveMeshes().data;\r\n            const defaultRenderListLength = this.renderList || scene.frameGraph ? defaultRenderList.length : scene.getActiveMeshes().length;\r\n\r\n            this._engine.currentRenderPassId = this._renderPassIds[passIndex];\r\n\r\n            this.onBeforeRenderObservable.notifyObservers(passIndex);\r\n\r\n            let currentRenderList: Nullable<Array<AbstractMesh>> = null;\r\n            let currentRenderListLength = defaultRenderListLength;\r\n\r\n            if (this.getCustomRenderList) {\r\n                currentRenderList = this.getCustomRenderList(passIndex, defaultRenderList, defaultRenderListLength);\r\n                if (currentRenderList) {\r\n                    currentRenderListLength = currentRenderList.length;\r\n                }\r\n            }\r\n\r\n            if (!currentRenderList) {\r\n                currentRenderList = defaultRenderList;\r\n            }\r\n\r\n            if (!this.options.doNotChangeAspectRatio) {\r\n                scene.updateTransformMatrix(true);\r\n            }\r\n\r\n            for (let i = 0; i < currentRenderListLength && returnValue; ++i) {\r\n                const mesh = currentRenderList[i];\r\n\r\n                if (!mesh.isEnabled() || mesh.isBlocked || !mesh.isVisible || !mesh.subMeshes) {\r\n                    continue;\r\n                }\r\n\r\n                if (this.customIsReadyFunction) {\r\n                    if (!this.customIsReadyFunction(mesh, this.refreshRate, true)) {\r\n                        returnValue = false;\r\n                        continue;\r\n                    }\r\n                } else if (!mesh.isReady(true)) {\r\n                    returnValue = false;\r\n                    continue;\r\n                }\r\n\r\n                let edgesRenderer = mesh._edgesRenderer;\r\n                let useInstances = mesh.hasThinInstances;\r\n                if (mesh.isAnInstance) {\r\n                    const sourceMesh = (mesh as InstancedMesh).sourceMesh;\r\n                    if (sourceMesh.edgesShareWithInstances && sourceMesh._edgesRenderer?.isEnabled) {\r\n                        edgesRenderer = sourceMesh._edgesRenderer;\r\n                        useInstances = true;\r\n                    }\r\n                } else if (mesh.hasInstances && (mesh as Mesh).edgesShareWithInstances) {\r\n                    useInstances = true;\r\n                }\r\n                if (!this.customRenderFunction && this.renderOpaqueMeshes && edgesRenderer?.isEnabled) {\r\n                    if (!edgesRenderer.isReady(useInstances)) {\r\n                        returnValue = false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.renderParticles && scene.particlesEnabled) {\r\n                const particleSystems = this.particleSystemList || scene.particleSystems;\r\n                for (const particleSystem of particleSystems) {\r\n                    if (!particleSystem.isReady()) {\r\n                        returnValue = false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.renderSprites && scene.spritesEnabled) {\r\n                const spriteManagers = this.spriteManagerList || scene.spriteManagers;\r\n                if (spriteManagers) {\r\n                    for (const spriteManager of spriteManagers) {\r\n                        if (scene.activeCamera && (spriteManager.layerMask & scene.activeCamera.layerMask) === 0) {\r\n                            continue;\r\n                        }\r\n                        if (spriteManager.isReady && !spriteManager.isReady()) {\r\n                            returnValue = false;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.onAfterRenderObservable.notifyObservers(passIndex);\r\n\r\n            if (numPasses > 1) {\r\n                scene.incrementRenderId();\r\n                scene.resetCachedMaterial();\r\n            }\r\n        }\r\n\r\n        this._engine.currentRenderPassId = currentRenderPassId;\r\n\r\n        return returnValue;\r\n    }\r\n\r\n    private _prepareRenderingManager(passIndex = 0, winterIsComing = false): Array<AbstractMesh> {\r\n        const scene = this._scene;\r\n\r\n        // Get the list of meshes to dispatch to the rendering manager\r\n        let currentRenderList: Nullable<Array<AbstractMesh>> = null;\r\n        let currentRenderListLength: number;\r\n        let checkLayerMask: boolean;\r\n\r\n        const defaultRenderList = this.renderList ? this.renderList : scene.frameGraph ? scene.meshes : scene.getActiveMeshes().data;\r\n        const defaultRenderListLength = this.renderList || scene.frameGraph ? defaultRenderList.length : scene.getActiveMeshes().length;\r\n\r\n        if (this.getCustomRenderList) {\r\n            currentRenderList = this.getCustomRenderList(passIndex, defaultRenderList, defaultRenderListLength);\r\n        }\r\n\r\n        if (!currentRenderList) {\r\n            // No custom render list provided, we prepare the rendering for the default list, but check\r\n            // first if we did not already performed the preparation (in this frame) before so as to avoid re-doing it several times.\r\n            // In WebGPU, instance data (visibleInstances) is stored per render pass ID. Each cascade/face (in CSM) uses a different\r\n            // render pass ID, so we must re-prepare for each pass to register instances in the correct per-pass storage.\r\n            if (this._defaultRenderListPrepared && !winterIsComing && !this._engine.isWebGPU) {\r\n                return defaultRenderList;\r\n            }\r\n            this._defaultRenderListPrepared = true;\r\n            currentRenderList = defaultRenderList;\r\n            currentRenderListLength = defaultRenderListLength;\r\n            checkLayerMask = !this.renderList || this.forceLayerMaskCheck;\r\n        } else {\r\n            // Prepare the rendering for the custom render list provided\r\n            currentRenderListLength = currentRenderList.length;\r\n            checkLayerMask = this.forceLayerMaskCheck;\r\n        }\r\n\r\n        const camera = scene.activeCamera; // note that at this point, scene.activeCamera == this.activeCamera if defined, because initRender() has been called before\r\n        const cameraForLOD = this.cameraForLOD ?? camera;\r\n\r\n        // The cast to \"any\" is to avoid an error in ES6 in case you don't import boundingBoxRenderer\r\n        const boundingBoxRenderer = (scene as any).getBoundingBoxRenderer?.() as Nullable<BoundingBoxRenderer>;\r\n\r\n        if (scene._activeMeshesFrozen && this._isFrozen) {\r\n            this._renderingManager.resetSprites();\r\n\r\n            if (this.enableBoundingBoxRendering && boundingBoxRenderer) {\r\n                boundingBoxRenderer.reset();\r\n                for (let i = 0; i < this._activeBoundingBoxes.length; i++) {\r\n                    const boundingBox = this._activeBoundingBoxes.data[i];\r\n                    boundingBoxRenderer.renderList.push(boundingBox);\r\n                }\r\n            }\r\n\r\n            return currentRenderList;\r\n        }\r\n\r\n        this._renderingManager.reset();\r\n        this._activeMeshes.reset();\r\n        this._activeBoundingBoxes.reset();\r\n\r\n        // We do not check option.enableBoundingBoxRendering before resetting the current list of bounding boxes, because:\r\n        // * if bounding box rendering is enabled, we want to start with an empty list and add new bounding boxes to it\r\n        // * if bounding box rendering is disabled, we don't want to render any bounding boxes that may have been generated by previous code\r\n        boundingBoxRenderer && boundingBoxRenderer.reset();\r\n\r\n        if (this.renderMeshes) {\r\n            const sceneRenderId = scene.getRenderId();\r\n            const currentFrameId = scene.getFrameId();\r\n            for (let meshIndex = 0; meshIndex < currentRenderListLength; meshIndex++) {\r\n                const mesh = currentRenderList[meshIndex];\r\n\r\n                if (mesh && !mesh.isBlocked) {\r\n                    if (this.customIsReadyFunction) {\r\n                        if (!this.customIsReadyFunction(mesh, this.refreshRate, false)) {\r\n                            this.resetRefreshCounter();\r\n                            continue;\r\n                        }\r\n                    } else if (!mesh.isReady(this.refreshRate === 0)) {\r\n                        this.resetRefreshCounter();\r\n                        continue;\r\n                    }\r\n\r\n                    let meshToRender: Nullable<AbstractMesh>;\r\n\r\n                    if (cameraForLOD) {\r\n                        const meshToRenderAndFrameId = mesh._internalAbstractMeshDataInfo._currentLOD.get(cameraForLOD);\r\n                        if (!meshToRenderAndFrameId || meshToRenderAndFrameId[1] !== currentFrameId) {\r\n                            meshToRender = scene.customLODSelector ? scene.customLODSelector(mesh, cameraForLOD) : mesh.getLOD(cameraForLOD);\r\n                            if (!meshToRenderAndFrameId) {\r\n                                mesh._internalAbstractMeshDataInfo._currentLOD.set(cameraForLOD, [meshToRender, currentFrameId]);\r\n                            } else {\r\n                                meshToRenderAndFrameId[0] = meshToRender;\r\n                                meshToRenderAndFrameId[1] = currentFrameId;\r\n                            }\r\n                        } else {\r\n                            meshToRender = meshToRenderAndFrameId[0];\r\n                        }\r\n                    } else {\r\n                        meshToRender = mesh;\r\n                    }\r\n\r\n                    if (!meshToRender) {\r\n                        continue;\r\n                    }\r\n\r\n                    if (meshToRender !== mesh && meshToRender.billboardMode !== 0) {\r\n                        meshToRender.computeWorldMatrix(); // Compute world matrix if LOD is billboard\r\n                    }\r\n\r\n                    meshToRender._preActivateForIntermediateRendering(sceneRenderId);\r\n\r\n                    let isMasked;\r\n                    if (checkLayerMask && camera) {\r\n                        isMasked = (mesh.layerMask & camera.layerMask) === 0;\r\n                    } else {\r\n                        isMasked = false;\r\n                    }\r\n\r\n                    if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && !isMasked) {\r\n                        this._activeMeshes.push(mesh);\r\n                        meshToRender._internalAbstractMeshDataInfo._wasActiveLastFrame = true;\r\n\r\n                        if (meshToRender !== mesh) {\r\n                            meshToRender._activate(sceneRenderId, true);\r\n                        }\r\n\r\n                        this.enableBoundingBoxRendering && boundingBoxRenderer && boundingBoxRenderer._preActiveMesh(mesh);\r\n\r\n                        if (mesh._activate(sceneRenderId, true) && mesh.subMeshes.length) {\r\n                            if (!mesh.isAnInstance) {\r\n                                meshToRender._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;\r\n                            } else {\r\n                                if (mesh._internalAbstractMeshDataInfo._actAsRegularMesh) {\r\n                                    meshToRender = mesh;\r\n                                }\r\n                            }\r\n                            meshToRender._internalAbstractMeshDataInfo._isActiveIntermediate = true;\r\n\r\n                            scene._prepareSkeleton(meshToRender);\r\n\r\n                            for (let subIndex = 0; subIndex < meshToRender.subMeshes.length; subIndex++) {\r\n                                const subMesh = meshToRender.subMeshes[subIndex];\r\n                                this.enableBoundingBoxRendering && boundingBoxRenderer && boundingBoxRenderer._evaluateSubMesh(mesh, subMesh);\r\n                                this._renderingManager.dispatch(subMesh, meshToRender);\r\n                            }\r\n                        }\r\n\r\n                        mesh._postActivate();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this.enableBoundingBoxRendering && boundingBoxRenderer && winterIsComing) {\r\n            for (let i = 0; i < boundingBoxRenderer.renderList.length; i++) {\r\n                const boundingBox = boundingBoxRenderer.renderList.data[i];\r\n                this._activeBoundingBoxes.push(boundingBox);\r\n            }\r\n        }\r\n\r\n        if (this._scene.particlesEnabled && this.renderParticles) {\r\n            this._scene.onBeforeParticlesRenderingObservable.notifyObservers(this._scene);\r\n            const particleSystems = this.particleSystemList || scene.particleSystems;\r\n            for (let particleIndex = 0; particleIndex < particleSystems.length; particleIndex++) {\r\n                const particleSystem = particleSystems[particleIndex];\r\n\r\n                const emitter: any = particleSystem.emitter;\r\n\r\n                if (!particleSystem.isStarted() || !emitter || (emitter.position && !emitter.isEnabled())) {\r\n                    continue;\r\n                }\r\n\r\n                this._renderingManager.dispatchParticles(particleSystem);\r\n            }\r\n            this._scene.onAfterParticlesRenderingObservable.notifyObservers(this._scene);\r\n        }\r\n\r\n        return currentRenderList;\r\n    }\r\n\r\n    /**\r\n     * Gets the rendering manager\r\n     */\r\n    public get renderingManager(): RenderingManager {\r\n        return this._renderingManager;\r\n    }\r\n\r\n    /**\r\n     * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n     * This allowed control for front to back rendering or reversely depending of the special needs.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n     * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n     */\r\n    public setRenderingOrder(\r\n        renderingGroupId: number,\r\n        opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n    ): void {\r\n        this._renderingManager.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n     * @param depth Automatically clears depth between groups if true and autoClear is true.\r\n     * @param stencil Automatically clears stencil between groups if true and autoClear is true.\r\n     */\r\n    public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean, depth = true, stencil = true): void {\r\n        this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil, depth, stencil);\r\n        this._renderingManager._useSceneAutoClearSetup = false;\r\n    }\r\n\r\n    /**\r\n     * Clones the renderer.\r\n     * @returns the cloned renderer\r\n     */\r\n    public clone(): ObjectRenderer {\r\n        const newRenderer = new ObjectRenderer(this.name, this._scene, this.options);\r\n\r\n        if (this.renderList) {\r\n            newRenderer.renderList = this.renderList.slice(0);\r\n        }\r\n\r\n        return newRenderer;\r\n    }\r\n\r\n    /**\r\n     * Dispose the renderer and release its associated resources.\r\n     */\r\n    public dispose(): void {\r\n        const renderList = this.renderList ? this.renderList : this._scene.getActiveMeshes().data;\r\n        const renderListLength = this.renderList ? this.renderList.length : this._scene.getActiveMeshes().length;\r\n        for (let i = 0; i < renderListLength; i++) {\r\n            const mesh = renderList[i];\r\n            if (mesh && mesh.getMaterialForRenderPass(this.renderPassId) !== undefined) {\r\n                mesh.setMaterialForRenderPass(this.renderPassId, undefined);\r\n            }\r\n        }\r\n\r\n        this.onInitRenderingObservable.clear();\r\n        this.onFinishRenderingObservable.clear();\r\n        this.onBeforeRenderObservable.clear();\r\n        this.onAfterRenderObservable.clear();\r\n        this.onBeforeRenderingManagerRenderObservable.clear();\r\n        this.onAfterRenderingManagerRenderObservable.clear();\r\n        this.onFastPathRenderObservable.clear();\r\n\r\n        this._releaseRenderPassId();\r\n\r\n        this.renderList = null;\r\n        if (this._sceneUBOs) {\r\n            for (const ubo of this._sceneUBOs) {\r\n                ubo.dispose();\r\n            }\r\n        }\r\n        this._sceneUBOs = undefined as any;\r\n\r\n        this._scene.removeObjectRenderer(this);\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        if (this.refreshRate === ObjectRenderer.REFRESHRATE_RENDER_ONCE) {\r\n            this.refreshRate = ObjectRenderer.REFRESHRATE_RENDER_ONCE;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the info related to rendering groups preventing retention point in material dispose.\r\n     */\r\n    public freeRenderingGroups(): void {\r\n        if (this._renderingManager) {\r\n            this._renderingManager.freeRenderingGroups();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type SmartArray } from \"../../Misc/smartArray\";\r\nimport { type Immutable, type Nullable } from \"../../types\";\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Color4 } from \"../../Maths/math.color.pure\";\r\nimport { type RenderTargetCreationOptions, type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { PostProcessManager } from \"../../PostProcesses/postProcessManager\";\r\nimport { type PostProcess } from \"../../PostProcesses/postProcess.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type IRenderTargetTexture, type RenderTargetWrapper } from \"../../Engines/renderTargetWrapper\";\r\nimport { type Material } from \"../material.pure\";\r\nimport { FloorPOT, NearestPOT } from \"../../Misc/tools.functions\";\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { RegisterAbstractEngineTexture } from \"../../Engines/AbstractEngine/abstractEngine.texture.pure\";\r\nimport { type IParticleSystem } from \"core/Particles/IParticleSystem\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { ObjectRenderer } from \"core/Rendering/objectRenderer\";\r\n\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Effect } from \"../effect.pure\";\r\n\r\n/**\r\n * Options for the RenderTargetTexture constructor\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface RenderTargetTextureOptions {\r\n    /** True (default: false) if mipmaps need to be generated after render */\r\n    generateMipMaps?: boolean;\r\n\r\n    /** True (default) to not change the aspect ratio of the scene in the RTT */\r\n    doNotChangeAspectRatio?: boolean;\r\n\r\n    /** The type of the buffer in the RTT (byte (default), half float, float...) */\r\n    type?: number;\r\n\r\n    /** True (default: false) if a cube texture needs to be created */\r\n    isCube?: boolean;\r\n\r\n    /** The sampling mode to be used with the render target (Trilinear (default), Linear, Nearest...) */\r\n    samplingMode?: number;\r\n\r\n    /** True (default) to generate a depth buffer */\r\n    generateDepthBuffer?: boolean;\r\n\r\n    /** True (default: false) to generate a stencil buffer */\r\n    generateStencilBuffer?: boolean;\r\n\r\n    /** True (default: false) if multiple textures need to be created (Draw Buffers) */\r\n    isMulti?: boolean;\r\n\r\n    /** The internal format of the buffer in the RTT (RED, RG, RGB, RGBA (default), ALPHA...) */\r\n    format?: number;\r\n\r\n    /** True (default: false) if the texture allocation should be delayed */\r\n    delayAllocation?: boolean;\r\n\r\n    /** Sample count to use when creating the RTT */\r\n    samples?: number;\r\n\r\n    /** specific flags to use when creating the texture (e.g., Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures) */\r\n    creationFlags?: number;\r\n\r\n    /** True (default: false) to indicate that no color target should be created. (e.g., if you only want to write to the depth buffer) */\r\n    noColorAttachment?: boolean;\r\n\r\n    /** Specifies the internal texture to use directly instead of creating one (ignores `noColorAttachment` flag when set) **/\r\n    colorAttachment?: InternalTexture;\r\n\r\n    /** True (default: false) to create a SRGB texture */\r\n    useSRGBBuffer?: boolean;\r\n\r\n    /** Defines the underlying texture texture space */\r\n    gammaSpace?: boolean;\r\n\r\n    /** If not provided (default), a new object renderer instance will be created */\r\n    existingObjectRenderer?: ObjectRenderer;\r\n\r\n    /** True to enable clustered lights (default: false) */\r\n    enableClusteredLights?: boolean;\r\n}\r\n\r\n/**\r\n * This Helps creating a texture that will be created from a camera in your scene.\r\n * It is basically a dynamic texture that could be used to create special effects for instance.\r\n * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...\r\n */\r\nexport class RenderTargetTexture extends Texture implements IRenderTargetTexture {\r\n    /**\r\n     * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.\r\n     */\r\n    public static readonly REFRESHRATE_RENDER_ONCE: number = ObjectRenderer.REFRESHRATE_RENDER_ONCE;\r\n    /**\r\n     * The texture will be rendered every frame and is recommended for dynamic contents.\r\n     */\r\n    public static readonly REFRESHRATE_RENDER_ONEVERYFRAME: number = ObjectRenderer.REFRESHRATE_RENDER_ONEVERYFRAME;\r\n    /**\r\n     * The texture will be rendered every 2 frames which could be enough if your dynamic objects are not\r\n     * the central point of your effect and can save a lot of performances.\r\n     */\r\n    public static readonly REFRESHRATE_RENDER_ONEVERYTWOFRAMES: number = ObjectRenderer.REFRESHRATE_RENDER_ONEVERYTWOFRAMES;\r\n\r\n    /**\r\n     * Use this predicate to dynamically define the list of mesh you want to render.\r\n     * If set, the renderList property will be overwritten.\r\n     */\r\n    public get renderListPredicate(): (AbstractMesh: AbstractMesh) => boolean {\r\n        return this._objectRenderer.renderListPredicate;\r\n    }\r\n\r\n    public set renderListPredicate(value: (AbstractMesh: AbstractMesh) => boolean) {\r\n        this._objectRenderer.renderListPredicate = value;\r\n    }\r\n\r\n    /**\r\n     * Use this list to define the list of mesh you want to render.\r\n     */\r\n    public get renderList(): Nullable<Array<AbstractMesh>> {\r\n        return this._objectRenderer.renderList;\r\n    }\r\n\r\n    public set renderList(value: Nullable<Array<AbstractMesh>>) {\r\n        this._objectRenderer.renderList = value;\r\n    }\r\n\r\n    /**\r\n     * Define the list of particle systems to render in the texture. If not provided, will render all the particle systems of the scene.\r\n     * Note that the particle systems are rendered only if renderParticles is set to true.\r\n     */\r\n    public get particleSystemList(): Nullable<Array<IParticleSystem>> {\r\n        return this._objectRenderer.particleSystemList;\r\n    }\r\n\r\n    public set particleSystemList(value: Nullable<Array<IParticleSystem>>) {\r\n        this._objectRenderer.particleSystemList = value;\r\n    }\r\n\r\n    /**\r\n     * Use this function to overload the renderList array at rendering time.\r\n     * Return null to render with the current renderList, else return the list of meshes to use for rendering.\r\n     * For 2DArray RTT, layerOrFace is the index of the layer that is going to be rendered, else it is the faceIndex of\r\n     * the cube (if the RTT is a cube, else layerOrFace=0).\r\n     * The renderList passed to the function is the current render list (the one that will be used if the function returns null).\r\n     * The length of this list is passed through renderListLength: don't use renderList.length directly because the array can\r\n     * hold dummy elements!\r\n     */\r\n    public get getCustomRenderList(): Nullable<\r\n        (layerOrFace: number, renderList: Nullable<Immutable<Array<AbstractMesh>>>, renderListLength: number) => Nullable<Array<AbstractMesh>>\r\n    > {\r\n        return this._objectRenderer.getCustomRenderList;\r\n    }\r\n\r\n    public set getCustomRenderList(\r\n        value: Nullable<(layerOrFace: number, renderList: Nullable<Immutable<Array<AbstractMesh>>>, renderListLength: number) => Nullable<Array<AbstractMesh>>>\r\n    ) {\r\n        this._objectRenderer.getCustomRenderList = value;\r\n    }\r\n\r\n    /**\r\n     * Define if particles should be rendered in your texture (default: true).\r\n     */\r\n    public get renderParticles() {\r\n        return this._objectRenderer.renderParticles;\r\n    }\r\n\r\n    public set renderParticles(value: boolean) {\r\n        this._objectRenderer.renderParticles = value;\r\n    }\r\n\r\n    /**\r\n     * Define if sprites should be rendered in your texture (default: false).\r\n     */\r\n    public get renderSprites() {\r\n        return this._objectRenderer.renderSprites;\r\n    }\r\n\r\n    public set renderSprites(value: boolean) {\r\n        this._objectRenderer.renderSprites = value;\r\n    }\r\n\r\n    /**\r\n     * Define if bounding box rendering should be enabled (still subject to Mesh.showBoundingBox or scene.forceShowBoundingBoxes). (Default: false).\r\n     */\r\n    public get enableBoundingBoxRendering() {\r\n        return this._objectRenderer.enableBoundingBoxRendering;\r\n    }\r\n\r\n    public set enableBoundingBoxRendering(value: boolean) {\r\n        this._objectRenderer.enableBoundingBoxRendering = value;\r\n    }\r\n\r\n    /**\r\n     * Define if outline/overlay rendering should be enabled (still subject to Mesh.renderOutline/Mesh.renderOverlay). (Default: true).\r\n     */\r\n    public get enableOutlineRendering() {\r\n        return this._objectRenderer.enableOutlineRendering;\r\n    }\r\n\r\n    public set enableOutlineRendering(value: boolean) {\r\n        this._objectRenderer.enableOutlineRendering = value;\r\n    }\r\n\r\n    /**\r\n     * Force checking the layerMask property even if a custom list of meshes is provided (ie. if renderList is not undefined) (default: false).\r\n     */\r\n    public get forceLayerMaskCheck() {\r\n        return this._objectRenderer.forceLayerMaskCheck;\r\n    }\r\n\r\n    public set forceLayerMaskCheck(value: boolean) {\r\n        this._objectRenderer.forceLayerMaskCheck = value;\r\n    }\r\n\r\n    /**\r\n     * Define the camera used to render the texture.\r\n     */\r\n    public get activeCamera(): Nullable<Camera> {\r\n        return this._objectRenderer.activeCamera;\r\n    }\r\n\r\n    public set activeCamera(value: Nullable<Camera>) {\r\n        this._objectRenderer.activeCamera = value;\r\n    }\r\n\r\n    /**\r\n     * Define the camera used to calculate the LOD of the objects.\r\n     * If not defined, activeCamera will be used. If not defined nor activeCamera, scene's active camera will be used.\r\n     */\r\n    public get cameraForLOD(): Nullable<Camera> {\r\n        return this._objectRenderer.cameraForLOD;\r\n    }\r\n\r\n    public set cameraForLOD(value: Nullable<Camera>) {\r\n        this._objectRenderer.cameraForLOD = value;\r\n    }\r\n\r\n    /**\r\n     * If true, the renderer will render all objects without any image processing applied.\r\n     * If false (default value), the renderer will use the current setting of the scene's image processing configuration.\r\n     */\r\n    public get disableImageProcessing() {\r\n        return this._objectRenderer.disableImageProcessing;\r\n    }\r\n\r\n    public set disableImageProcessing(value: boolean) {\r\n        this._objectRenderer.disableImageProcessing = value;\r\n    }\r\n\r\n    /**\r\n     * Override the mesh isReady function with your own one.\r\n     */\r\n    public get customIsReadyFunction(): (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => boolean {\r\n        return this._objectRenderer.customIsReadyFunction;\r\n    }\r\n\r\n    public set customIsReadyFunction(value: (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => boolean) {\r\n        this._objectRenderer.customIsReadyFunction = value;\r\n    }\r\n\r\n    /**\r\n     * Override the render function of the texture with your own one.\r\n     */\r\n    public get customRenderFunction(): (\r\n        opaqueSubMeshes: SmartArray<SubMesh>,\r\n        alphaTestSubMeshes: SmartArray<SubMesh>,\r\n        transparentSubMeshes: SmartArray<SubMesh>,\r\n        depthOnlySubMeshes: SmartArray<SubMesh>,\r\n        beforeTransparents?: () => void\r\n    ) => void {\r\n        return this._objectRenderer.customRenderFunction;\r\n    }\r\n\r\n    public set customRenderFunction(\r\n        value: (\r\n            opaqueSubMeshes: SmartArray<SubMesh>,\r\n            alphaTestSubMeshes: SmartArray<SubMesh>,\r\n            transparentSubMeshes: SmartArray<SubMesh>,\r\n            depthOnlySubMeshes: SmartArray<SubMesh>,\r\n            beforeTransparents?: () => void\r\n        ) => void\r\n    ) {\r\n        this._objectRenderer.customRenderFunction = value;\r\n    }\r\n\r\n    /**\r\n     * Define if camera post processes should be use while rendering the texture.\r\n     */\r\n    public useCameraPostProcesses: boolean;\r\n    /**\r\n     * Define if the camera viewport should be respected while rendering the texture or if the render should be done to the entire texture.\r\n     */\r\n    public ignoreCameraViewport: boolean = false;\r\n\r\n    private _postProcessManager: Nullable<PostProcessManager>;\r\n\r\n    /**\r\n     * Post-processes for this render target\r\n     */\r\n    public get postProcesses() {\r\n        return this._postProcesses;\r\n    }\r\n    private _postProcesses: PostProcess[];\r\n    private _resizeObserver: Nullable<Observer<AbstractEngine>>;\r\n\r\n    private get _prePassEnabled() {\r\n        return !!this._prePassRenderTarget && this._prePassRenderTarget.enabled;\r\n    }\r\n\r\n    /**\r\n     * An event triggered before the texture is bound to the output.\r\n     */\r\n    public onBeforeBindObservable = new Observable<RenderTargetTexture>();\r\n\r\n    /**\r\n     * An event triggered after the texture is unbound.\r\n     */\r\n    public onAfterUnbindObservable = new Observable<RenderTargetTexture>();\r\n\r\n    private _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;\r\n    /**\r\n     * Set a after unbind callback in the texture.\r\n     * This has been kept for backward compatibility and use of onAfterUnbindObservable is recommended.\r\n     */\r\n    public set onAfterUnbind(callback: () => void) {\r\n        if (this._onAfterUnbindObserver) {\r\n            this.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);\r\n        }\r\n        this._onAfterUnbindObserver = this.onAfterUnbindObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered before rendering the texture\r\n     */\r\n    public get onBeforeRenderObservable() {\r\n        return this._objectRenderer.onBeforeRenderObservable;\r\n    }\r\n\r\n    private _onBeforeRenderObserver: Nullable<Observer<number>>;\r\n    /**\r\n     * Set a before render callback in the texture.\r\n     * This has been kept for backward compatibility and use of onBeforeRenderObservable is recommended.\r\n     */\r\n    public set onBeforeRender(callback: (faceIndex: number) => void) {\r\n        if (this._onBeforeRenderObserver) {\r\n            this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n        }\r\n        this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered after rendering the texture\r\n     */\r\n    public get onAfterRenderObservable() {\r\n        return this._objectRenderer.onAfterRenderObservable;\r\n    }\r\n\r\n    private _onAfterRenderObserver: Nullable<Observer<number>>;\r\n    /**\r\n     * Set a after render callback in the texture.\r\n     * This has been kept for backward compatibility and use of onAfterRenderObservable is recommended.\r\n     */\r\n    public set onAfterRender(callback: (faceIndex: number) => void) {\r\n        if (this._onAfterRenderObserver) {\r\n            this.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n        }\r\n        this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered after the texture clear\r\n     */\r\n    public onClearObservable = new Observable<AbstractEngine>();\r\n\r\n    private _onClearObserver: Nullable<Observer<AbstractEngine>>;\r\n    /**\r\n     * Set a clear callback in the texture.\r\n     * This has been kept for backward compatibility and use of onClearObservable is recommended.\r\n     */\r\n    public set onClear(callback: (Engine: AbstractEngine) => void) {\r\n        if (this._onClearObserver) {\r\n            this.onClearObservable.remove(this._onClearObserver);\r\n        }\r\n        this._onClearObserver = this.onClearObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the texture is resized.\r\n     */\r\n    public onResizeObservable = new Observable<RenderTargetTexture>();\r\n\r\n    /**\r\n     * Define the clear color of the Render Target if it should be different from the scene.\r\n     */\r\n    public clearColor: Color4;\r\n    /** @internal */\r\n    public _size: TextureSize;\r\n    protected _initialSizeParameter: TextureSize | { ratio: number };\r\n    protected _sizeRatio: Nullable<number>;\r\n    /** @internal */\r\n    public _generateMipMaps: boolean;\r\n    /** @internal */\r\n    public _cleared = false;\r\n    /**\r\n     * Skip the initial clear of the rtt at the beginning of the frame render loop\r\n     */\r\n    public skipInitialClear = false;\r\n    /** @internal */\r\n    public get _waitingRenderList() {\r\n        return this._objectRenderer._waitingRenderList;\r\n    }\r\n\r\n    /** @internal */\r\n    public set _waitingRenderList(value: string[] | undefined) {\r\n        this._objectRenderer._waitingRenderList = value;\r\n    }\r\n\r\n    protected _objectRenderer: ObjectRenderer;\r\n    protected _doNotChangeAspectRatio: boolean;\r\n    protected _textureMatrix: Matrix;\r\n    protected _samples = 1;\r\n    protected _renderTargetOptions: RenderTargetCreationOptions;\r\n    private _canRescale = true;\r\n    protected _renderTarget: Nullable<RenderTargetWrapper> = null;\r\n    private _currentFaceIndex: number;\r\n    private _currentLayer: number;\r\n    private _currentUseCameraPostProcess: boolean;\r\n    private _currentDumpForDebug: boolean;\r\n    private _dontDisposeObjectRenderer = false;\r\n\r\n    /**\r\n     * Current render pass id of the render target texture. Note it can change over the rendering as there's a separate id for each face of a cube / each layer of an array layer!\r\n     */\r\n    public get renderPassId(): number {\r\n        return this._objectRenderer.renderPassId;\r\n    }\r\n\r\n    /**\r\n     * Gets the render pass ids used by the render target texture. For a single render target the array length will be 1, for a cube texture it will be 6 and for\r\n     * a 2D texture array it will return an array of ids the size of the 2D texture array\r\n     */\r\n    public get renderPassIds(): readonly number[] {\r\n        return this._objectRenderer.renderPassIds;\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the refreshId counter\r\n     */\r\n    public get currentRefreshId() {\r\n        return this._objectRenderer.currentRefreshId;\r\n    }\r\n\r\n    /**\r\n     * Sets a specific material to be used to render a mesh/a list of meshes in this render target texture\r\n     * @param mesh mesh or array of meshes\r\n     * @param material material or array of materials to use for this render pass. If undefined is passed, no specific material will be used but the regular material instead (mesh.material). It's possible to provide an array of materials to use a different material for each rendering in the case of a cube texture (6 rendering) and a 2D texture array (as many rendering as the length of the array)\r\n     */\r\n    public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material | Material[]): void {\r\n        this._objectRenderer.setMaterialForRendering(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Define if the texture has multiple draw buffers or if false a single draw buffer.\r\n     */\r\n    public get isMulti(): boolean {\r\n        return this._renderTarget?.isMulti ?? false;\r\n    }\r\n\r\n    /**\r\n     * Gets render target creation options that were used.\r\n     */\r\n    public get renderTargetOptions(): RenderTargetCreationOptions {\r\n        return this._renderTargetOptions;\r\n    }\r\n\r\n    /**\r\n     * Gets the render target wrapper associated with this render target\r\n     */\r\n    public get renderTarget(): Nullable<RenderTargetWrapper> {\r\n        return this._renderTarget;\r\n    }\r\n\r\n    protected _onRatioRescale(): void {\r\n        if (this._sizeRatio) {\r\n            this.resize(this._initialSizeParameter);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the center of the bounding box associated with the texture (when in cube mode)\r\n     * It must define where the camera used to render the texture is set\r\n     */\r\n    public boundingBoxPosition = Vector3.Zero();\r\n\r\n    private _boundingBoxSize: Vector3;\r\n\r\n    /**\r\n     * Gets or sets the size of the bounding box associated with the texture (when in cube mode)\r\n     * When defined, the cubemap will switch to local mode\r\n     * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity\r\n     * @example https://www.babylonjs-playground.com/#RNASML\r\n     */\r\n    public set boundingBoxSize(value: Vector3) {\r\n        if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {\r\n            return;\r\n        }\r\n        this._boundingBoxSize = value;\r\n        const scene = this.getScene();\r\n        if (scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n        }\r\n    }\r\n    public get boundingBoxSize(): Vector3 {\r\n        return this._boundingBoxSize;\r\n    }\r\n\r\n    /**\r\n     * In case the RTT has been created with a depth texture, get the associated\r\n     * depth texture.\r\n     * Otherwise, return null.\r\n     */\r\n    public get depthStencilTexture(): Nullable<InternalTexture> {\r\n        return this._renderTarget?._depthStencilTexture ?? null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _disableEngineStages = false; // TODO: remove this when the shadow generator task (frame graph) is reworked (see https://github.com/BabylonJS/Babylon.js/pull/15962#discussion_r1874417607)\r\n\r\n    private readonly _onBeforeRenderingManagerRenderObserver: Nullable<Observer<number>>;\r\n    private readonly _onAfterRenderingManagerRenderObserver: Nullable<Observer<number>>;\r\n    private readonly _onFastPathRenderObserver: Nullable<Observer<number>>;\r\n\r\n    /**\r\n     * Instantiate a render target texture. This is mainly used to render the scene off screen, to apply (for instance) post processing effects\r\n     * or use a shadow or depth texture...\r\n     * @param name The friendly name of the texture\r\n     * @param size The size of the RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)\r\n     * @param scene The scene the RTT belongs to. Default is the last created scene.\r\n     * @param options The options for creating the render target texture.\r\n     */\r\n    constructor(name: string, size: TextureSize | { ratio: number }, scene?: Nullable<Scene>, options?: RenderTargetTextureOptions);\r\n\r\n    /**\r\n     * Instantiate a render target texture. This is mainly used to render the scene off screen, to apply (for instance) post processing effects\r\n     * or use a shadow or depth texture...\r\n     * @param name The friendly name of the texture\r\n     * @param size The size of the RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)\r\n     * @param scene The scene the RTT belongs to. Default is the last created scene\r\n     * @param generateMipMaps True (default: false) if mipmaps need to be generated after render\r\n     * @param doNotChangeAspectRatio True (default) to not change the aspect ratio of the scene in the RTT\r\n     * @param type The type of the buffer in the RTT (byte (default), half float, float...)\r\n     * @param isCube True (default: false) if a cube texture needs to be created\r\n     * @param samplingMode The sampling mode to be used with the render target (Trilinear (default), Linear, Nearest...)\r\n     * @param generateDepthBuffer True (default) to generate a depth buffer\r\n     * @param generateStencilBuffer True (default: false) to generate a stencil buffer\r\n     * @param isMulti True (default: false) if multiple textures need to be created (Draw Buffers)\r\n     * @param format The internal format of the buffer in the RTT (RED, RG, RGB, RGBA (default), ALPHA...)\r\n     * @param delayAllocation True (default: false) if the texture allocation should be delayed\r\n     * @param samples Sample count to use when creating the RTT\r\n     * @param creationFlags specific flags to use when creating the texture (e.g., Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures)\r\n     * @param noColorAttachment True (default: false) to indicate that no color target should be created. (e.g., if you only want to write to the depth buffer)\r\n     * @param useSRGBBuffer True (default: false) to create a SRGB texture\r\n     */\r\n    constructor(\r\n        name: string,\r\n        size: TextureSize | { ratio: number },\r\n        scene?: Nullable<Scene>,\r\n        generateMipMaps?: boolean,\r\n        doNotChangeAspectRatio?: boolean,\r\n        type?: number,\r\n        isCube?: boolean,\r\n        samplingMode?: number,\r\n        generateDepthBuffer?: boolean,\r\n        generateStencilBuffer?: boolean,\r\n        isMulti?: boolean,\r\n        format?: number,\r\n        delayAllocation?: boolean,\r\n        samples?: number,\r\n        creationFlags?: number,\r\n        noColorAttachment?: boolean,\r\n        useSRGBBuffer?: boolean\r\n    );\r\n\r\n    /** @internal */\r\n    constructor(\r\n        name: string,\r\n        size: TextureSize | { ratio: number },\r\n        scene?: Nullable<Scene>,\r\n        generateMipMaps: boolean | RenderTargetTextureOptions = false,\r\n        doNotChangeAspectRatio: boolean = true,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        isCube = false,\r\n        samplingMode = Texture.TRILINEAR_SAMPLINGMODE,\r\n        generateDepthBuffer = true,\r\n        generateStencilBuffer = false,\r\n        isMulti = false,\r\n        format = Constants.TEXTUREFORMAT_RGBA,\r\n        delayAllocation = false,\r\n        samples?: number,\r\n        creationFlags?: number,\r\n        noColorAttachment = false,\r\n        useSRGBBuffer = false\r\n    ) {\r\n        let colorAttachment: InternalTexture | undefined = undefined;\r\n        let gammaSpace = true;\r\n        let existingObjectRenderer: ObjectRenderer | undefined = undefined;\r\n        let enableClusteredLights = false;\r\n        if (typeof generateMipMaps === \"object\") {\r\n            const options = generateMipMaps;\r\n            generateMipMaps = !!options.generateMipMaps;\r\n            doNotChangeAspectRatio = options.doNotChangeAspectRatio ?? true;\r\n            type = options.type ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            isCube = !!options.isCube;\r\n            samplingMode = options.samplingMode ?? Texture.TRILINEAR_SAMPLINGMODE;\r\n            generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n            generateStencilBuffer = !!options.generateStencilBuffer;\r\n            isMulti = !!options.isMulti;\r\n            format = options.format ?? Constants.TEXTUREFORMAT_RGBA;\r\n            delayAllocation = !!options.delayAllocation;\r\n            samples = options.samples;\r\n            creationFlags = options.creationFlags;\r\n            noColorAttachment = !!options.noColorAttachment;\r\n            useSRGBBuffer = !!options.useSRGBBuffer;\r\n            colorAttachment = options.colorAttachment;\r\n            gammaSpace = options.gammaSpace ?? gammaSpace;\r\n            existingObjectRenderer = options.existingObjectRenderer;\r\n            enableClusteredLights = !!options.enableClusteredLights;\r\n        }\r\n\r\n        super(null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format);\r\n\r\n        scene = this.getScene();\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        const engine = this.getScene()!.getEngine();\r\n\r\n        this._gammaSpace = gammaSpace;\r\n        this._coordinatesMode = Texture.PROJECTION_MODE;\r\n        this.name = name;\r\n        this.isRenderTarget = true;\r\n        this._initialSizeParameter = size;\r\n        this._dontDisposeObjectRenderer = !!existingObjectRenderer;\r\n\r\n        this._processSizeParameter(size);\r\n\r\n        this._objectRenderer =\r\n            existingObjectRenderer ??\r\n            new ObjectRenderer(name, scene, {\r\n                numPasses: isCube ? 6 : this.getRenderLayers() || 1,\r\n                doNotChangeAspectRatio,\r\n                enableClusteredLights,\r\n            });\r\n\r\n        this._onBeforeRenderingManagerRenderObserver = this._objectRenderer.onBeforeRenderingManagerRenderObservable.add(() => {\r\n            // One of the actions below can dispose this RTT, so capture the scene first.\r\n            const scene = this._scene!;\r\n\r\n            // Before clear\r\n            if (!this._disableEngineStages) {\r\n                for (const step of scene._beforeRenderTargetClearStage) {\r\n                    step.action(this, this._currentFaceIndex, this._currentLayer);\r\n                }\r\n            }\r\n\r\n            // Clear\r\n            if (this.onClearObservable.hasObservers()) {\r\n                this.onClearObservable.notifyObservers(engine);\r\n            } else if (!this.skipInitialClear) {\r\n                engine.clear(this.clearColor ?? scene.clearColor, true, true, true);\r\n            }\r\n\r\n            if (!this._doNotChangeAspectRatio) {\r\n                scene.updateTransformMatrix(true);\r\n            }\r\n\r\n            // Before Camera Draw\r\n            if (!this._disableEngineStages) {\r\n                for (const step of scene._beforeRenderTargetDrawStage) {\r\n                    step.action(this, this._currentFaceIndex, this._currentLayer);\r\n                }\r\n            }\r\n\r\n            if (engine._debugPushGroup) {\r\n                engine._debugPushGroup(`Render to ${this.name} (face #${this._currentFaceIndex} layer #${this._currentLayer})`);\r\n            }\r\n        });\r\n\r\n        this._onAfterRenderingManagerRenderObserver = this._objectRenderer.onAfterRenderingManagerRenderObservable.add(() => {\r\n            if (engine._debugPopGroup) {\r\n                engine._debugPopGroup();\r\n            }\r\n\r\n            // After Camera Draw\r\n            if (!this._disableEngineStages) {\r\n                for (const step of this._scene!._afterRenderTargetDrawStage) {\r\n                    step.action(this, this._currentFaceIndex, this._currentLayer);\r\n                }\r\n            }\r\n\r\n            const saveGenerateMipMaps = this._texture?.generateMipMaps ?? false;\r\n\r\n            if (this._texture) {\r\n                this._texture.generateMipMaps = false; // if left true, the mipmaps will be generated (if this._texture.generateMipMaps = true) when the first post process binds its own RTT: by doing so it will unbind the current RTT,\r\n                // which will trigger a mipmap generation. We don't want this because it's a wasted work, we will do an unbind of the current RTT at the end of the process (see unbindFrameBuffer) which will\r\n                // trigger the generation of the final mipmaps\r\n            }\r\n\r\n            if (this._postProcessManager) {\r\n                this._postProcessManager._finalizeFrame(false, this._renderTarget ?? undefined, this._currentFaceIndex, this._postProcesses, this.ignoreCameraViewport);\r\n            } else if (this._currentUseCameraPostProcess) {\r\n                this._scene!.postProcessManager._finalizeFrame(false, this._renderTarget ?? undefined, this._currentFaceIndex);\r\n            }\r\n\r\n            if (!this._disableEngineStages) {\r\n                for (const step of this._scene!._afterRenderTargetPostProcessStage) {\r\n                    step.action(this, this._currentFaceIndex, this._currentLayer);\r\n                }\r\n            }\r\n\r\n            if (this._texture) {\r\n                this._texture.generateMipMaps = saveGenerateMipMaps;\r\n            }\r\n\r\n            if (!this._doNotChangeAspectRatio) {\r\n                this._scene!.updateTransformMatrix(true);\r\n            }\r\n\r\n            // Dump ?\r\n            if (this._currentDumpForDebug) {\r\n                if (!this._dumpTools) {\r\n                    Logger.Error(\"dumpTools module is still being loaded. To speed up the process import dump tools directly in your project\");\r\n                } else {\r\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n                    this._dumpTools.DumpFramebuffer(this.getRenderWidth(), this.getRenderHeight(), engine);\r\n                }\r\n            }\r\n        });\r\n\r\n        this._onFastPathRenderObserver = this._objectRenderer.onFastPathRenderObservable.add(() => {\r\n            if (this.onClearObservable.hasObservers()) {\r\n                this.onClearObservable.notifyObservers(engine);\r\n            } else {\r\n                if (!this.skipInitialClear) {\r\n                    engine.clear(this.clearColor || this._scene!.clearColor, true, true, true);\r\n                }\r\n            }\r\n        });\r\n\r\n        this._resizeObserver = engine.onResizeObservable.add(() => {});\r\n\r\n        this._generateMipMaps = generateMipMaps ? true : false;\r\n        this._doNotChangeAspectRatio = doNotChangeAspectRatio;\r\n\r\n        if (isMulti) {\r\n            return;\r\n        }\r\n\r\n        this._renderTargetOptions = {\r\n            generateMipMaps: generateMipMaps,\r\n            type: type,\r\n            format: this._format ?? undefined,\r\n            samplingMode: this.samplingMode,\r\n            generateDepthBuffer: generateDepthBuffer,\r\n            generateStencilBuffer: generateStencilBuffer,\r\n            samples,\r\n            creationFlags,\r\n            noColorAttachment: noColorAttachment,\r\n            useSRGBBuffer,\r\n            colorAttachment: colorAttachment,\r\n            label: this.name,\r\n        };\r\n\r\n        if (this.samplingMode === Texture.NEAREST_SAMPLINGMODE) {\r\n            this.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n            this.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        }\r\n\r\n        if (!delayAllocation) {\r\n            if (isCube) {\r\n                this._renderTarget = scene.getEngine().createRenderTargetCubeTexture(this.getRenderSize(), this._renderTargetOptions);\r\n                this.coordinatesMode = Texture.INVCUBIC_MODE;\r\n                this._textureMatrix = Matrix.Identity();\r\n            } else {\r\n                this._renderTarget = scene.getEngine().createRenderTargetTexture(this._size, this._renderTargetOptions);\r\n            }\r\n            this._texture = this._renderTarget.texture;\r\n            if (samples !== undefined) {\r\n                this.samples = samples;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a depth stencil texture.\r\n     * This is only available in WebGL 2 or with the depth texture extension available.\r\n     * @param comparisonFunction Specifies the comparison function to set on the texture. If 0 or undefined, the texture is not in comparison mode (default: 0)\r\n     * @param bilinearFiltering Specifies whether or not bilinear filtering is enable on the texture (default: true)\r\n     * @param generateStencil Specifies whether or not a stencil should be allocated in the texture (default: false)\r\n     * @param samples sample count of the depth/stencil texture (default: 1)\r\n     * @param format format of the depth texture (default: Constants.TEXTUREFORMAT_DEPTH32_FLOAT)\r\n     * @param label defines the label of the texture (for debugging purpose)\r\n     */\r\n    public createDepthStencilTexture(\r\n        comparisonFunction: number = 0,\r\n        bilinearFiltering: boolean = true,\r\n        generateStencil: boolean = false,\r\n        samples: number = 1,\r\n        format: number = Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n        label?: string\r\n    ): void {\r\n        this._renderTarget?.createDepthStencilTexture(comparisonFunction, bilinearFiltering, generateStencil, samples, format, label);\r\n    }\r\n\r\n    protected _processSizeParameter(size: TextureSize | { ratio: number }): void {\r\n        if ((<{ ratio: number }>size).ratio) {\r\n            this._sizeRatio = (<{ ratio: number }>size).ratio;\r\n            const engine = this._getEngine()!;\r\n            this._size = {\r\n                width: this._bestReflectionRenderTargetDimension(engine.getRenderWidth(), this._sizeRatio),\r\n                height: this._bestReflectionRenderTargetDimension(engine.getRenderHeight(), this._sizeRatio),\r\n            };\r\n        } else {\r\n            this._size = <TextureSize>size;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Define the number of samples to use in case of MSAA.\r\n     * It defaults to one meaning no MSAA has been enabled.\r\n     */\r\n    public get samples(): number {\r\n        return this._renderTarget?.samples ?? this._samples;\r\n    }\r\n\r\n    public set samples(value: number) {\r\n        if (this._renderTarget) {\r\n            this._samples = this._renderTarget.setSamples(value);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a post process to the render target rendering passes.\r\n     * @param postProcess define the post process to add\r\n     */\r\n    public addPostProcess(postProcess: PostProcess): void {\r\n        if (!this._postProcessManager) {\r\n            const scene = this.getScene();\r\n\r\n            if (!scene) {\r\n                return;\r\n            }\r\n            this._postProcessManager = new PostProcessManager(scene);\r\n            this._postProcesses = new Array<PostProcess>();\r\n        }\r\n\r\n        this._postProcesses.push(postProcess);\r\n        this._postProcesses[0].autoClear = false;\r\n    }\r\n\r\n    /**\r\n     * Clear all the post processes attached to the render target\r\n     * @param dispose define if the cleared post processes should also be disposed (false by default)\r\n     */\r\n    public clearPostProcesses(dispose: boolean = false): void {\r\n        if (!this._postProcesses) {\r\n            return;\r\n        }\r\n\r\n        if (dispose) {\r\n            for (const postProcess of this._postProcesses) {\r\n                postProcess.dispose();\r\n            }\r\n        }\r\n\r\n        this._postProcesses = [];\r\n    }\r\n\r\n    /**\r\n     * Remove one of the post process from the list of attached post processes to the texture\r\n     * @param postProcess define the post process to remove from the list\r\n     */\r\n    public removePostProcess(postProcess: PostProcess): void {\r\n        if (!this._postProcesses) {\r\n            return;\r\n        }\r\n\r\n        const index = this._postProcesses.indexOf(postProcess);\r\n\r\n        if (index === -1) {\r\n            return;\r\n        }\r\n\r\n        this._postProcesses.splice(index, 1);\r\n\r\n        if (this._postProcesses.length > 0) {\r\n            this._postProcesses[0].autoClear = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the refresh counter of the texture and start bak from scratch.\r\n     * Could be useful to regenerate the texture if it is setup to render only once.\r\n     */\r\n    public resetRefreshCounter(): void {\r\n        this._objectRenderer.resetRefreshCounter();\r\n    }\r\n\r\n    /**\r\n     * Define the refresh rate of the texture or the rendering frequency.\r\n     * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...\r\n     */\r\n    public get refreshRate(): number {\r\n        return this._objectRenderer.refreshRate;\r\n    }\r\n    public set refreshRate(value: number) {\r\n        this._objectRenderer.refreshRate = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public _shouldRender(): boolean {\r\n        return this._objectRenderer.shouldRender();\r\n    }\r\n\r\n    /**\r\n     * Gets the actual render size of the texture.\r\n     * @returns the width of the render size\r\n     */\r\n    public getRenderSize(): number {\r\n        return this.getRenderWidth();\r\n    }\r\n\r\n    /**\r\n     * Gets the actual render width of the texture.\r\n     * @returns the width of the render size\r\n     */\r\n    public getRenderWidth(): number {\r\n        if ((<{ width: number; height: number }>this._size).width) {\r\n            return (<{ width: number; height: number }>this._size).width;\r\n        }\r\n\r\n        return <number>this._size;\r\n    }\r\n\r\n    /**\r\n     * Gets the actual render height of the texture.\r\n     * @returns the height of the render size\r\n     */\r\n    public getRenderHeight(): number {\r\n        if ((<{ width: number; height: number }>this._size).width) {\r\n            return (<{ width: number; height: number }>this._size).height;\r\n        }\r\n\r\n        return <number>this._size;\r\n    }\r\n\r\n    /**\r\n     * Gets the actual number of layers of the texture or, in the case of a 3D texture, return the depth.\r\n     * @returns the number of layers\r\n     */\r\n    public getRenderLayers(): number {\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>this._size).layers;\r\n        if (layers) {\r\n            return layers;\r\n        }\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>this._size).depth;\r\n        if (depth) {\r\n            return depth;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Don't allow this render target texture to rescale. Mainly used to prevent rescaling by the scene optimizer.\r\n     */\r\n    public disableRescaling() {\r\n        this._canRescale = false;\r\n    }\r\n\r\n    /**\r\n     * Get if the texture can be rescaled or not.\r\n     */\r\n    public override get canRescale(): boolean {\r\n        return this._canRescale;\r\n    }\r\n\r\n    /**\r\n     * Resize the texture using a ratio.\r\n     * @param ratio the ratio to apply to the texture size in order to compute the new target size\r\n     */\r\n    public override scale(ratio: number): void {\r\n        const newSize = Math.max(1, this.getRenderSize() * ratio);\r\n\r\n        this.resize(newSize);\r\n    }\r\n\r\n    /**\r\n     * Get the texture reflection matrix used to rotate/transform the reflection.\r\n     * @returns the reflection matrix\r\n     */\r\n    public override getReflectionTextureMatrix(): Matrix {\r\n        if (this.isCube) {\r\n            return this._textureMatrix;\r\n        }\r\n\r\n        return super.getReflectionTextureMatrix();\r\n    }\r\n\r\n    /**\r\n     * Resize the texture to a new desired size.\r\n     * Be careful as it will recreate all the data in the new texture.\r\n     * @param size Define the new size. It can be:\r\n     *   - a number for squared texture,\r\n     *   - an object containing { width: number, height: number }\r\n     *   - or an object containing a ratio { ratio: number }\r\n     */\r\n    public resize(size: TextureSize | { ratio: number }): void {\r\n        const wasCube = this.isCube;\r\n\r\n        this._renderTarget?.dispose();\r\n        this._renderTarget = null;\r\n\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        this._processSizeParameter(size);\r\n\r\n        if (wasCube) {\r\n            this._renderTarget = scene.getEngine().createRenderTargetCubeTexture(this.getRenderSize(), this._renderTargetOptions);\r\n        } else {\r\n            this._renderTarget = scene.getEngine().createRenderTargetTexture(this._size, this._renderTargetOptions);\r\n        }\r\n        this._texture = this._renderTarget.texture;\r\n\r\n        if (this._renderTargetOptions.samples !== undefined) {\r\n            this.samples = this._renderTargetOptions.samples;\r\n        }\r\n\r\n        if (this.onResizeObservable.hasObservers()) {\r\n            this.onResizeObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Renders all the objects from the render list into the texture.\r\n     * @param useCameraPostProcess Define if camera post processes should be used during the rendering\r\n     * @param dumpForDebug Define if the rendering result should be dumped (copied) for debugging purpose\r\n     */\r\n    public render(useCameraPostProcess: boolean = false, dumpForDebug: boolean = false): void {\r\n        this._render(useCameraPostProcess, dumpForDebug);\r\n    }\r\n\r\n    private _dumpToolsLoading = false;\r\n    private _dumpTools: typeof import(\"../../Misc/dumpTools.pure\");\r\n\r\n    /**\r\n     * This function will check if the render target texture can be rendered (textures are loaded, shaders are compiled)\r\n     * @returns true if all required resources are ready\r\n     */\r\n    public isReadyForRendering(): boolean {\r\n        if (!this._dumpToolsLoading) {\r\n            this._dumpToolsLoading = true;\r\n            // avoid a static import to allow ignoring the import in some cases\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            import(\"../../Misc/dumpTools.pure\").then((module) => (this._dumpTools = module));\r\n        }\r\n\r\n        this._objectRenderer.prepareRenderList();\r\n\r\n        this.onBeforeBindObservable.notifyObservers(this);\r\n\r\n        this._objectRenderer.initRender(this.getRenderWidth(), this.getRenderHeight());\r\n\r\n        const isReady = this._objectRenderer._checkReadiness();\r\n\r\n        this.onAfterUnbindObservable.notifyObservers(this);\r\n\r\n        this._objectRenderer.finishRender();\r\n\r\n        return isReady;\r\n    }\r\n\r\n    private _render(useCameraPostProcess: boolean = false, dumpForDebug: boolean = false): void {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        if (this.useCameraPostProcesses !== undefined) {\r\n            useCameraPostProcess = this.useCameraPostProcesses;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        if (engine._debugPushGroup) {\r\n            engine._debugPushGroup(`Render to ${this.name}`);\r\n        }\r\n\r\n        this._objectRenderer.prepareRenderList();\r\n\r\n        this.onBeforeBindObservable.notifyObservers(this);\r\n\r\n        this._objectRenderer.initRender(this.getRenderWidth(), this.getRenderHeight());\r\n\r\n        if ((this.is2DArray || this.is3D) && !this.isMulti) {\r\n            for (let layer = 0; layer < this.getRenderLayers(); layer++) {\r\n                this._renderToTarget(0, useCameraPostProcess, dumpForDebug, layer);\r\n                scene.incrementRenderId();\r\n                scene.resetCachedMaterial();\r\n            }\r\n        } else if (this.isCube && !this.isMulti) {\r\n            for (let face = 0; face < 6; face++) {\r\n                this._renderToTarget(face, useCameraPostProcess, dumpForDebug);\r\n                scene.incrementRenderId();\r\n                scene.resetCachedMaterial();\r\n            }\r\n        } else {\r\n            this._renderToTarget(0, useCameraPostProcess, dumpForDebug);\r\n        }\r\n\r\n        this.onAfterUnbindObservable.notifyObservers(this);\r\n\r\n        this._objectRenderer.finishRender();\r\n\r\n        if (engine._debugPopGroup) {\r\n            engine._debugPopGroup();\r\n        }\r\n    }\r\n\r\n    private _bestReflectionRenderTargetDimension(renderDimension: number, scale: number): number {\r\n        const minimum = 128;\r\n        const x = renderDimension * scale;\r\n        const curved = NearestPOT(x + (minimum * minimum) / (minimum + x));\r\n\r\n        // Ensure we don't exceed the render dimension (while staying POT)\r\n        return Math.min(FloorPOT(renderDimension), curved);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * @param faceIndex face index to bind to if this is a cubetexture\r\n     * @param layer defines the index of the texture to bind in the array\r\n     */\r\n    public _bindFrameBuffer(faceIndex: number = 0, layer = 0) {\r\n        const scene = this.getScene();\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n        if (this._renderTarget) {\r\n            engine.bindFramebuffer(this._renderTarget, this.isCube ? faceIndex : undefined, undefined, undefined, this.ignoreCameraViewport, 0, layer);\r\n        }\r\n    }\r\n\r\n    protected _unbindFrameBuffer(engine: AbstractEngine, faceIndex: number): void {\r\n        if (!this._renderTarget) {\r\n            return;\r\n        }\r\n        engine.unBindFramebuffer(this._renderTarget, this.isCube, () => {\r\n            this.onAfterRenderObservable.notifyObservers(faceIndex);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _prepareFrame(scene: Scene, faceIndex?: number, layer?: number, useCameraPostProcess?: boolean) {\r\n        if (this._postProcessManager) {\r\n            if (!this._prePassEnabled) {\r\n                if (!this._postProcessManager._prepareFrame(this._texture, this._postProcesses)) {\r\n                    this._bindFrameBuffer(faceIndex, layer);\r\n                }\r\n            }\r\n        } else if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {\r\n            this._bindFrameBuffer(faceIndex, layer);\r\n        }\r\n    }\r\n\r\n    private _renderToTarget(faceIndex: number, useCameraPostProcess: boolean, dumpForDebug: boolean, layer = 0): void {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        this._currentFaceIndex = faceIndex;\r\n        this._currentLayer = layer;\r\n        this._currentUseCameraPostProcess = useCameraPostProcess;\r\n        this._currentDumpForDebug = dumpForDebug;\r\n\r\n        this._prepareFrame(scene, faceIndex, layer, useCameraPostProcess);\r\n\r\n        this._objectRenderer.render(faceIndex + layer, true); // only faceIndex or layer (if any) will be different from 0 (we don't support array of cubes), so it's safe to add them to get the pass index\r\n\r\n        this._unbindFrameBuffer(engine, faceIndex);\r\n\r\n        if (this._texture && this.isCube && faceIndex === 5) {\r\n            engine.generateMipMapsForCubemap(this._texture, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n     * This allowed control for front to back rendering or reversely depending of the special needs.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n     * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n     */\r\n    public setRenderingOrder(\r\n        renderingGroupId: number,\r\n        opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n        transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n    ): void {\r\n        this._objectRenderer.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n     *\r\n     * @param renderingGroupId The rendering group id corresponding to its index\r\n     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n     */\r\n    public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean): void {\r\n        this._objectRenderer.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);\r\n    }\r\n\r\n    /**\r\n     * Clones the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): RenderTargetTexture {\r\n        const textureSize = this.getSize();\r\n        const newTexture = new RenderTargetTexture(\r\n            this.name,\r\n            textureSize,\r\n            this.getScene(),\r\n            this._renderTargetOptions.generateMipMaps,\r\n            this._doNotChangeAspectRatio,\r\n            this._renderTargetOptions.type,\r\n            this.isCube,\r\n            this._renderTargetOptions.samplingMode,\r\n            this._renderTargetOptions.generateDepthBuffer,\r\n            this._renderTargetOptions.generateStencilBuffer,\r\n            undefined,\r\n            this._renderTargetOptions.format,\r\n            undefined,\r\n            this._renderTargetOptions.samples\r\n        );\r\n\r\n        // Base texture\r\n        newTexture.hasAlpha = this.hasAlpha;\r\n        newTexture.level = this.level;\r\n\r\n        // RenderTarget Texture\r\n        newTexture.coordinatesMode = this.coordinatesMode;\r\n        if (this.renderList) {\r\n            newTexture.renderList = this.renderList.slice(0);\r\n        }\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture to a JSON representation we can easily use in the respective Parse function.\r\n     * @returns The JSON representation of the texture\r\n     */\r\n    public override serialize(): any {\r\n        if (!this.name) {\r\n            return null;\r\n        }\r\n\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.renderTargetSize = this.getRenderSize();\r\n        serializationObject.renderList = [];\r\n\r\n        if (this.renderList) {\r\n            for (let index = 0; index < this.renderList.length; index++) {\r\n                serializationObject.renderList.push(this.renderList[index].id);\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     *  This will remove the attached framebuffer objects. The texture will not be able to be used as render target anymore\r\n     */\r\n    public disposeFramebufferObjects(): void {\r\n        this._renderTarget?.dispose(true);\r\n    }\r\n\r\n    /**\r\n     * Release and destroy the underlying lower level texture aka internalTexture.\r\n     */\r\n    public override releaseInternalTexture(): void {\r\n        this._renderTarget?.releaseTextures();\r\n        this._texture = null;\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        this.onResizeObservable.clear();\r\n        this.onClearObservable.clear();\r\n        this.onAfterUnbindObservable.clear();\r\n        this.onBeforeBindObservable.clear();\r\n\r\n        if (this._postProcessManager) {\r\n            this._postProcessManager.dispose();\r\n            this._postProcessManager = null;\r\n        }\r\n\r\n        if (this._prePassRenderTarget) {\r\n            this._prePassRenderTarget.dispose();\r\n        }\r\n\r\n        this._objectRenderer.onBeforeRenderingManagerRenderObservable.remove(this._onBeforeRenderingManagerRenderObserver);\r\n        this._objectRenderer.onAfterRenderingManagerRenderObservable.remove(this._onAfterRenderingManagerRenderObserver);\r\n        this._objectRenderer.onFastPathRenderObservable.remove(this._onFastPathRenderObserver);\r\n\r\n        if (!this._dontDisposeObjectRenderer) {\r\n            this._objectRenderer.dispose();\r\n        }\r\n\r\n        this.clearPostProcesses(true);\r\n\r\n        if (this._resizeObserver) {\r\n            this.getScene()!.getEngine().onResizeObservable.remove(this._resizeObserver);\r\n            this._resizeObserver = null;\r\n        }\r\n\r\n        // Remove from custom render targets\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        let index = scene.customRenderTargets.indexOf(this);\r\n\r\n        if (index >= 0) {\r\n            scene.customRenderTargets.splice(index, 1);\r\n        }\r\n\r\n        for (const camera of scene.cameras) {\r\n            index = camera.customRenderTargets.indexOf(this);\r\n\r\n            if (index >= 0) {\r\n                camera.customRenderTargets.splice(index, 1);\r\n            }\r\n        }\r\n\r\n        this._renderTarget?.dispose();\r\n        this._renderTarget = null;\r\n        this._texture = null;\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    /** @internal */\r\n    public override _rebuild(): void {\r\n        this._objectRenderer._rebuild();\r\n\r\n        if (this._postProcessManager) {\r\n            this._postProcessManager._rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the info related to rendering groups preventing retention point in material dispose.\r\n     */\r\n    public freeRenderingGroups(): void {\r\n        this._objectRenderer.freeRenderingGroups();\r\n    }\r\n\r\n    /**\r\n     * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)\r\n     * @returns the view count\r\n     */\r\n    public getViewCount() {\r\n        return 1;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for renderTargetTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRenderTargetTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Depth-stencil render targets (shadow maps, RTT depth, etc.) call\r\n    // AbstractEngine.createDepthStencilTexture, which is only installed by the\r\n    // abstractEngine.texture registration. This module imports the pure engine\r\n    // (side-effect free), so pull the registration in here to guarantee the method\r\n    // exists whenever a render target texture is used.\r\n    RegisterAbstractEngineTexture();\r\n\r\n    /**\r\n     * Sets a depth stencil texture from a render target on the engine to be used in the shader.\r\n     * @param channel Name of the sampler variable.\r\n     * @param texture Texture to set.\r\n     */\r\n    Effect.prototype.setDepthStencilTexture = function (channel: string, texture: Nullable<RenderTargetTexture>): void {\r\n        this._engine.setDepthStencilTexture(this._samplers[channel], this._uniforms[channel], texture, channel);\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    Texture._CreateRenderTargetTexture = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean, creationFlags?: number) => {\r\n        return new RenderTargetTexture(name, renderTargetSize, scene, generateMipMaps);\r\n    };\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffectProperty } from \"../../Misc/devTools\";\r\n\r\nif (!Object.getOwnPropertyDescriptor(RenderTargetTexture.prototype, \"noPrePassRenderer\")) {\r\n    Object.defineProperty(RenderTargetTexture.prototype, \"noPrePassRenderer\", _MissingSideEffectProperty(\"RenderTargetTexture\", \"noPrePassRenderer\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NonNullableFields, type Nullable } from \"../types\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Viewport } from \"../Maths/math.viewport\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { type IShaderPath, Effect } from \"./effect.pure\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { DrawWrapper } from \"./drawWrapper\";\r\nimport { type IRenderTargetTexture, type RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\n\r\n// Prevents ES6 issue if not imported.\r\n\r\n/**\r\n * Effect Render Options\r\n */\r\nexport interface IEffectRendererOptions {\r\n    /**\r\n     * Defines the vertices positions.\r\n     */\r\n    positions?: number[];\r\n    /**\r\n     * Defines the indices.\r\n     */\r\n    indices?: number[];\r\n}\r\n\r\n// Fullscreen quad buffers by default.\r\nconst DefaultOptions = {\r\n    positions: [1, 1, -1, 1, -1, -1, 1, -1],\r\n    indices: [0, 1, 2, 0, 2, 3],\r\n};\r\n\r\n/**\r\n * Helper class to render one or more effects.\r\n * You can access the previous rendering in your shader by declaring a sampler named textureSampler\r\n */\r\nexport class EffectRenderer {\r\n    /**\r\n     * The engine the effect renderer has been created for.\r\n     */\r\n    public readonly engine: AbstractEngine;\r\n\r\n    private _vertexBuffers: { [key: string]: VertexBuffer };\r\n    private _indexBuffer: DataBuffer;\r\n    private _indexBufferLength: number;\r\n\r\n    private _fullscreenViewport = new Viewport(0, 0, 1, 1);\r\n    private _onContextRestoredObserver: Nullable<Observer<AbstractEngine>>;\r\n\r\n    private _savedStateDepthTest: boolean;\r\n    private _savedStateStencilTest: boolean;\r\n\r\n    /**\r\n     * Creates an effect renderer\r\n     * @param engine the engine to use for rendering\r\n     * @param options defines the options of the effect renderer\r\n     */\r\n    constructor(engine: AbstractEngine, options: IEffectRendererOptions = DefaultOptions) {\r\n        const positions = options.positions ?? DefaultOptions.positions;\r\n        const indices = options.indices ?? DefaultOptions.indices;\r\n\r\n        this.engine = engine;\r\n        this._vertexBuffers = {\r\n            // Note, always assumes stride of 2.\r\n            [VertexBuffer.PositionKind]: new VertexBuffer(engine, positions, VertexBuffer.PositionKind, false, false, 2),\r\n        };\r\n        this._indexBuffer = engine.createIndexBuffer(indices);\r\n        this._indexBufferLength = indices.length;\r\n\r\n        this._onContextRestoredObserver = engine.onContextRestoredObservable.add(() => {\r\n            this._indexBuffer = engine.createIndexBuffer(indices);\r\n\r\n            for (const key in this._vertexBuffers) {\r\n                const vertexBuffer = this._vertexBuffers[key];\r\n                vertexBuffer._rebuild();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Sets the current viewport in normalized coordinates 0-1\r\n     * @param viewport Defines the viewport to set (defaults to 0 0 1 1)\r\n     */\r\n    public setViewport(viewport = this._fullscreenViewport): void {\r\n        this.engine.setViewport(viewport);\r\n    }\r\n\r\n    /**\r\n     * Binds the embedded attributes buffer to the effect.\r\n     * @param effect Defines the effect to bind the attributes for\r\n     */\r\n    public bindBuffers(effect: Effect): void {\r\n        this.engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);\r\n    }\r\n\r\n    /**\r\n     * Sets the current effect wrapper to use during draw.\r\n     * The effect needs to be ready before calling this api.\r\n     * This also sets the default full screen position attribute.\r\n     * @param effectWrapper Defines the effect to draw with\r\n     * @param depthTest Whether to enable depth testing (default: false)\r\n     * @param stencilTest Whether to enable stencil testing (default: false)\r\n     */\r\n    public applyEffectWrapper(effectWrapper: EffectWrapper, depthTest = false, stencilTest = false): void {\r\n        this.engine.setState(true);\r\n        this.engine.depthCullingState.depthTest = depthTest;\r\n        this.engine.stencilState.stencilTest = stencilTest;\r\n        this.engine.enableEffect(effectWrapper.drawWrapper);\r\n        this.bindBuffers(effectWrapper.effect);\r\n        effectWrapper.onApplyObservable.notifyObservers({});\r\n    }\r\n\r\n    /**\r\n     * Saves engine states\r\n     */\r\n    public saveStates(): void {\r\n        this._savedStateDepthTest = this.engine.depthCullingState.depthTest;\r\n        this._savedStateStencilTest = this.engine.stencilState.stencilTest;\r\n    }\r\n\r\n    /**\r\n     * Restores engine states\r\n     */\r\n    public restoreStates(): void {\r\n        this.engine.depthCullingState.depthTest = this._savedStateDepthTest;\r\n        this.engine.stencilState.stencilTest = this._savedStateStencilTest;\r\n    }\r\n\r\n    /**\r\n     * Draws a full screen quad.\r\n     */\r\n    public draw(): void {\r\n        this.engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, this._indexBufferLength);\r\n    }\r\n\r\n    private _isRenderTargetTexture(texture: RenderTargetWrapper | IRenderTargetTexture): texture is IRenderTargetTexture {\r\n        return (texture as IRenderTargetTexture).renderTarget !== undefined;\r\n    }\r\n\r\n    /**\r\n     * renders one or more effects to a specified texture\r\n     * @param effectWrapper the effect to renderer\r\n     * @param outputTexture texture to draw to, if null it will render to the currently bound frame buffer\r\n     */\r\n    public render(effectWrapper: EffectWrapper, outputTexture: Nullable<RenderTargetWrapper | IRenderTargetTexture> = null) {\r\n        // Ensure effect is ready\r\n        if (!effectWrapper.effect.isReady()) {\r\n            return;\r\n        }\r\n\r\n        this.saveStates();\r\n\r\n        // Reset state\r\n        this.setViewport();\r\n\r\n        const out = outputTexture === null ? null : this._isRenderTargetTexture(outputTexture) ? outputTexture.renderTarget! : outputTexture;\r\n\r\n        if (out) {\r\n            this.engine.bindFramebuffer(out);\r\n        }\r\n\r\n        this.applyEffectWrapper(effectWrapper);\r\n\r\n        this.draw();\r\n\r\n        if (out) {\r\n            this.engine.unBindFramebuffer(out);\r\n        }\r\n\r\n        this.restoreStates();\r\n    }\r\n\r\n    /**\r\n     * Disposes of the effect renderer\r\n     */\r\n    dispose() {\r\n        const vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (vertexBuffer) {\r\n            vertexBuffer.dispose();\r\n            delete this._vertexBuffers[VertexBuffer.PositionKind];\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this.engine._releaseBuffer(this._indexBuffer);\r\n        }\r\n\r\n        if (this._onContextRestoredObserver) {\r\n            this.engine.onContextRestoredObservable.remove(this._onContextRestoredObserver);\r\n            this._onContextRestoredObserver = null;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Allows for custom processing of the shader code used by an effect wrapper\r\n */\r\nexport type EffectWrapperCustomShaderCodeProcessing = {\r\n    /**\r\n     * If provided, will be called two times with the vertex and fragment code so that this code can be updated after the #include have been processed\r\n     */\r\n    processCodeAfterIncludes?: (postProcessName: string, shaderType: string, code: string) => string;\r\n    /**\r\n     * If provided, will be called two times with the vertex and fragment code so that this code can be updated before it is compiled by the GPU\r\n     */\r\n    processFinalCode?: (postProcessName: string, shaderType: string, code: string) => string;\r\n    /**\r\n     * If provided, will be called before creating the effect to collect additional custom bindings (defines, uniforms, samplers)\r\n     */\r\n    defineCustomBindings?: (postProcessName: string, defines: Nullable<string>, uniforms: string[], samplers: string[]) => Nullable<string>;\r\n    /**\r\n     * If provided, will be called when binding inputs to the shader code to allow the user to add custom bindings\r\n     */\r\n    bindCustomBindings?: (postProcessName: string, effect: Effect) => void;\r\n};\r\n\r\n/**\r\n * Options to create an EffectWrapper\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface EffectWrapperCreationOptions {\r\n    /**\r\n     * Engine to use to create the effect\r\n     */\r\n    engine?: AbstractEngine;\r\n    /**\r\n     * Fragment shader for the effect\r\n     */\r\n    fragmentShader?: string;\r\n    /**\r\n     * Use the shader store instead of direct source code\r\n     */\r\n    useShaderStore?: boolean;\r\n    /**\r\n     * Vertex shader for the effect (default: \"postprocess\")\r\n     */\r\n    vertexShader?: string;\r\n    /**\r\n     * Alias for vertexShader\r\n     */\r\n    vertexUrl?: string;\r\n    /**\r\n     * Attributes to use in the shader (default: [\"position\"])\r\n     */\r\n    attributeNames?: Array<string>;\r\n    /**\r\n     * Uniforms to use in the shader\r\n     */\r\n    uniformNames?: Array<string>;\r\n    /**\r\n     * Alias for uniformNames. Note that if it is provided, it takes precedence over uniformNames.\r\n     */\r\n    uniforms?: Nullable<string[]>;\r\n    /**\r\n     * Texture sampler names to use in the shader\r\n     */\r\n    samplerNames?: Array<string>;\r\n    /**\r\n     * Alias for samplerNames. Note that if it is provided, it takes precedence over samplerNames.\r\n     */\r\n    samplers?: Nullable<string[]>;\r\n    /**\r\n     * The list of uniform buffers used in the shader (if any)\r\n     */\r\n    uniformBuffers?: Nullable<string[]>;\r\n    /**\r\n     * Defines to use in the shader\r\n     */\r\n    defines?: Nullable<string | Array<string>>;\r\n    /**\r\n     * The index parameters to be used for babylons include syntax \"#include<kernelBlurVaryingDeclaration>[0..varyingCount]\". (default: undefined)\r\n     * See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n     */\r\n    indexParameters?: any;\r\n    /**\r\n     * If the shader should not be compiled immediately. (default: false)\r\n     */\r\n    blockCompilation?: boolean;\r\n    /**\r\n     * Callback when effect is compiled\r\n     */\r\n    onCompiled?: Nullable<(effect: Effect) => void>;\r\n    /**\r\n     * The friendly name of the effect (default: \"effectWrapper\")\r\n     */\r\n    name?: string;\r\n    /**\r\n     * The language the shader is written in (default: GLSL)\r\n     */\r\n    shaderLanguage?: ShaderLanguage;\r\n    /**\r\n     * Defines additional code to call to prepare the shader code\r\n     */\r\n    extraInitializations?: (useWebGPU: boolean, list: Promise<any>[]) => void;\r\n    /**\r\n     * Additional async code to run before preparing the effect\r\n     */\r\n    extraInitializationsAsync?: () => Promise<void>;\r\n    /**\r\n     * If the effect should be used as a post process (default: false). If true, the effect will be created with a \"scale\" uniform and a \"textureSampler\" sampler\r\n     */\r\n    useAsPostProcess?: boolean;\r\n    /**\r\n     * Sets this property to true if the fragment shader doesn't use a textureSampler texture (default: false).\r\n     */\r\n    allowEmptySourceTexture?: boolean;\r\n}\r\n\r\n/**\r\n * Wraps an effect to be used for rendering\r\n */\r\nexport class EffectWrapper {\r\n    /**\r\n     * Force code to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    private static _CustomShaderCodeProcessing: { [effectWrapperName: string]: EffectWrapperCustomShaderCodeProcessing } = {};\r\n\r\n    /**\r\n     * Registers a shader code processing with an effect wrapper name.\r\n     * @param effectWrapperName name of the effect wrapper. Use null for the fallback shader code processing. This is the shader code processing that will be used in case no specific shader code processing has been associated to an effect wrapper name\r\n     * @param customShaderCodeProcessing shader code processing to associate to the effect wrapper name\r\n     */\r\n    public static RegisterShaderCodeProcessing(effectWrapperName: Nullable<string>, customShaderCodeProcessing?: EffectWrapperCustomShaderCodeProcessing) {\r\n        if (!customShaderCodeProcessing) {\r\n            delete EffectWrapper._CustomShaderCodeProcessing[effectWrapperName ?? \"\"];\r\n            return;\r\n        }\r\n\r\n        EffectWrapper._CustomShaderCodeProcessing[effectWrapperName ?? \"\"] = customShaderCodeProcessing;\r\n    }\r\n\r\n    private static _GetShaderCodeProcessing(effectWrapperName: string) {\r\n        return EffectWrapper._CustomShaderCodeProcessing[effectWrapperName] ?? EffectWrapper._CustomShaderCodeProcessing[\"\"];\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the name of the effect wrapper\r\n     */\r\n    public get name() {\r\n        return this.options.name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this.options.name = value;\r\n    }\r\n\r\n    /**\r\n     * Type of alpha mode to use when applying the effect (default: Engine.ALPHA_DISABLE). Used only if useAsPostProcess is true.\r\n     */\r\n    public alphaMode = Constants.ALPHA_DISABLE;\r\n\r\n    /**\r\n     * Executed when the effect is created\r\n     * @returns effect that was created for this effect wrapper\r\n     */\r\n    public onEffectCreatedObservable = new Observable<Effect>(undefined, true);\r\n\r\n    /**\r\n     * Options used to create the effect wrapper\r\n     */\r\n    public readonly options: Required<NonNullableFields<EffectWrapperCreationOptions>>;\r\n\r\n    /**\r\n     * Get a value indicating if the effect is ready to be used\r\n     * @returns true if the post-process is ready (shader is compiled)\r\n     */\r\n    public isReady() {\r\n        return this._drawWrapper.effect?.isReady() ?? false;\r\n    }\r\n\r\n    /**\r\n     * Get the draw wrapper associated with the effect wrapper\r\n     * @returns the draw wrapper associated with the effect wrapper\r\n     */\r\n    public get drawWrapper() {\r\n        return this._drawWrapper;\r\n    }\r\n\r\n    /**\r\n     * Event that is fired (only when the EffectWrapper is used with an EffectRenderer) right before the effect is drawn (should be used to update uniforms)\r\n     */\r\n    public onApplyObservable = new Observable<{}>();\r\n\r\n    /**\r\n     * The underlying effect\r\n     */\r\n    public get effect(): Effect {\r\n        return this._drawWrapper.effect!;\r\n    }\r\n\r\n    public set effect(effect: Effect) {\r\n        this._drawWrapper.effect = effect;\r\n    }\r\n\r\n    protected readonly _drawWrapper: DrawWrapper;\r\n    protected _shadersLoaded = false;\r\n    protected readonly _shaderPath: IShaderPath;\r\n    /** @internal */\r\n    public _webGPUReady = false;\r\n\r\n    private _onContextRestoredObserver: Nullable<Observer<AbstractEngine>>;\r\n\r\n    /**\r\n     * Creates an effect to be rendered\r\n     * @param creationOptions options to create the effect\r\n     */\r\n    constructor(creationOptions: EffectWrapperCreationOptions) {\r\n        this.options = {\r\n            ...creationOptions,\r\n            name: creationOptions.name || \"effectWrapper\",\r\n            engine: creationOptions.engine!,\r\n            uniforms: creationOptions.uniforms || creationOptions.uniformNames || [],\r\n            uniformNames: undefined as any,\r\n            samplers: creationOptions.samplers || creationOptions.samplerNames || [],\r\n            samplerNames: undefined as any,\r\n            attributeNames: creationOptions.attributeNames || [\"position\"],\r\n            uniformBuffers: creationOptions.uniformBuffers || [],\r\n            defines: creationOptions.defines || \"\",\r\n            useShaderStore: creationOptions.useShaderStore || false,\r\n            vertexUrl: creationOptions.vertexUrl || creationOptions.vertexShader || \"postprocess\",\r\n            vertexShader: undefined as any,\r\n            fragmentShader: creationOptions.fragmentShader || \"pass\",\r\n            indexParameters: creationOptions.indexParameters,\r\n            blockCompilation: creationOptions.blockCompilation || false,\r\n            shaderLanguage: creationOptions.shaderLanguage || ShaderLanguage.GLSL,\r\n            onCompiled: creationOptions.onCompiled || (undefined as any),\r\n            extraInitializations: creationOptions.extraInitializations || (undefined as any),\r\n            extraInitializationsAsync: creationOptions.extraInitializationsAsync || (undefined as any),\r\n            useAsPostProcess: creationOptions.useAsPostProcess ?? false,\r\n            allowEmptySourceTexture: creationOptions.allowEmptySourceTexture ?? false,\r\n        };\r\n\r\n        this.options.uniformNames = this.options.uniforms;\r\n        this.options.samplerNames = this.options.samplers;\r\n        this.options.vertexShader = this.options.vertexUrl;\r\n\r\n        if (this.options.useAsPostProcess) {\r\n            if (!this.options.allowEmptySourceTexture && this.options.samplers.indexOf(\"textureSampler\") === -1) {\r\n                this.options.samplers.push(\"textureSampler\");\r\n            }\r\n            if (this.options.uniforms.indexOf(\"scale\") === -1) {\r\n                this.options.uniforms.push(\"scale\");\r\n            }\r\n        }\r\n\r\n        if (creationOptions.vertexUrl || creationOptions.vertexShader) {\r\n            this._shaderPath = {\r\n                vertexSource: this.options.vertexShader,\r\n            };\r\n        } else {\r\n            if (!this.options.useAsPostProcess) {\r\n                this.options.uniforms.push(\"scale\");\r\n\r\n                this.onApplyObservable.add(() => {\r\n                    this.effect.setFloat2(\"scale\", 1, 1);\r\n                });\r\n            }\r\n\r\n            this._shaderPath = {\r\n                vertex: this.options.vertexShader,\r\n            };\r\n        }\r\n\r\n        this._shaderPath.fragmentSource = this.options.fragmentShader;\r\n        this._shaderPath.spectorName = this.options.name;\r\n\r\n        if (this.options.useShaderStore) {\r\n            this._shaderPath.fragment = this._shaderPath.fragmentSource;\r\n            if (!this._shaderPath.vertex) {\r\n                this._shaderPath.vertex = this._shaderPath.vertexSource;\r\n            }\r\n\r\n            delete this._shaderPath.fragmentSource;\r\n            delete this._shaderPath.vertexSource;\r\n        }\r\n\r\n        this.onApplyObservable.add(() => {\r\n            this.bind();\r\n        });\r\n\r\n        if (!this.options.useShaderStore) {\r\n            this._onContextRestoredObserver = this.options.engine.onContextRestoredObservable.add(() => {\r\n                this.effect._pipelineContext = null; // because _prepareEffect will try to dispose this pipeline before recreating it and that would lead to webgl errors\r\n                this.effect._prepareEffect();\r\n            });\r\n        }\r\n\r\n        this._drawWrapper = new DrawWrapper(this.options.engine);\r\n        this._webGPUReady = this.options.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        const defines = Array.isArray(this.options.defines) ? this.options.defines.join(\"\\n\") : this.options.defines;\r\n\r\n        this._postConstructor(this.options.blockCompilation, defines, this.options.extraInitializations);\r\n    }\r\n\r\n    protected _gatherImports(_useWebGPU = false, _list: Promise<any>[]) {}\r\n\r\n    private _importPromises: Array<Promise<any>> = [];\r\n\r\n    /** @internal */\r\n    public _postConstructor(\r\n        blockCompilation: boolean,\r\n        defines: Nullable<string> = null,\r\n        extraInitializations?: (useWebGPU: boolean, list: Promise<any>[]) => void,\r\n        importPromises?: Array<Promise<any>>\r\n    ) {\r\n        this._importPromises.length = 0;\r\n\r\n        if (importPromises) {\r\n            this._importPromises.push(...importPromises);\r\n        }\r\n\r\n        const useWebGPU = this.options.engine.isWebGPU && !EffectWrapper.ForceGLSL;\r\n\r\n        this._gatherImports(useWebGPU, this._importPromises);\r\n        if (this.options.useShaderStore && this._shaderPath.vertex === \"postprocess\") {\r\n            this._importPromises.push(useWebGPU && this._webGPUReady ? import(\"../ShadersWGSL/postprocess.vertex\") : import(\"../Shaders/postprocess.vertex\"));\r\n        }\r\n        if (extraInitializations !== undefined) {\r\n            extraInitializations(useWebGPU, this._importPromises);\r\n        }\r\n\r\n        if (useWebGPU && this._webGPUReady) {\r\n            this.options.shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        if (!blockCompilation) {\r\n            this.updateEffect(defines);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the effect with the current effect wrapper compile time values and recompiles the shader.\r\n     * @param defines Define statements that should be added at the beginning of the shader. (default: null)\r\n     * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)\r\n     * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)\r\n     * @param indexParameters The index parameters to be used for babylons include syntax \"#include<kernelBlurVaryingDeclaration>[0..varyingCount]\". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n     * @param onCompiled Called when the shader has been compiled.\r\n     * @param onError Called if there is an error when compiling a shader.\r\n     * @param vertexUrl The url of the vertex shader to be used (default: the one given at construction time)\r\n     * @param fragmentUrl The url of the fragment shader to be used (default: the one given at construction time)\r\n     */\r\n    public updateEffect(\r\n        defines: Nullable<string> = null,\r\n        uniforms: Nullable<string[]> = null,\r\n        samplers: Nullable<string[]> = null,\r\n        indexParameters?: any,\r\n        onCompiled?: (effect: Effect) => void,\r\n        onError?: (effect: Effect, errors: string) => void,\r\n        vertexUrl?: string,\r\n        fragmentUrl?: string\r\n    ) {\r\n        const customShaderCodeProcessing = EffectWrapper._GetShaderCodeProcessing(this.name);\r\n        if (customShaderCodeProcessing?.defineCustomBindings) {\r\n            const newUniforms = uniforms?.slice() ?? [];\r\n            newUniforms.push(...this.options.uniforms);\r\n\r\n            const newSamplers = samplers?.slice() ?? [];\r\n            newSamplers.push(...this.options.samplers);\r\n\r\n            defines = customShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers);\r\n            uniforms = newUniforms;\r\n            samplers = newSamplers;\r\n        }\r\n\r\n        this.options.defines = defines || \"\";\r\n\r\n        const waitImportsLoaded =\r\n            this._shadersLoaded || this._importPromises.length === 0\r\n                ? undefined\r\n                : async () => {\r\n                      await Promise.all(this._importPromises);\r\n                      this._shadersLoaded = true;\r\n                  };\r\n\r\n        let extraInitializationsAsync: (() => Promise<void>) | undefined;\r\n        if (this.options.extraInitializationsAsync) {\r\n            extraInitializationsAsync = async () => {\r\n                await waitImportsLoaded?.();\r\n                await this.options.extraInitializationsAsync();\r\n            };\r\n        } else {\r\n            extraInitializationsAsync = waitImportsLoaded;\r\n        }\r\n\r\n        if (this.options.useShaderStore) {\r\n            this._drawWrapper.effect = this.options.engine.createEffect(\r\n                { vertex: vertexUrl ?? this._shaderPath.vertex, fragment: fragmentUrl ?? this._shaderPath.fragment },\r\n                {\r\n                    attributes: this.options.attributeNames,\r\n                    uniformsNames: uniforms || this.options.uniforms,\r\n                    uniformBuffersNames: this.options.uniformBuffers,\r\n                    samplers: samplers || this.options.samplers,\r\n                    defines: defines !== null ? defines : \"\",\r\n                    fallbacks: null,\r\n                    onCompiled: onCompiled ?? this.options.onCompiled,\r\n                    onError: onError ?? null,\r\n                    indexParameters: indexParameters || this.options.indexParameters,\r\n                    processCodeAfterIncludes: customShaderCodeProcessing?.processCodeAfterIncludes\r\n                        ? (shaderType: string, code: string) => customShaderCodeProcessing.processCodeAfterIncludes!(this.name, shaderType, code)\r\n                        : null,\r\n                    processFinalCode: customShaderCodeProcessing?.processFinalCode\r\n                        ? (shaderType: string, code: string) => customShaderCodeProcessing.processFinalCode!(this.name, shaderType, code)\r\n                        : null,\r\n                    shaderLanguage: this.options.shaderLanguage,\r\n                    extraInitializationsAsync,\r\n                },\r\n                this.options.engine\r\n            );\r\n        } else {\r\n            this._drawWrapper.effect = new Effect(\r\n                this._shaderPath,\r\n                this.options.attributeNames,\r\n                uniforms || this.options.uniforms,\r\n                samplers || this.options.samplerNames,\r\n                this.options.engine,\r\n                defines,\r\n                undefined,\r\n                onCompiled || this.options.onCompiled,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                this.options.shaderLanguage,\r\n                extraInitializationsAsync\r\n            );\r\n        }\r\n\r\n        this.onEffectCreatedObservable.notifyObservers(this._drawWrapper.effect);\r\n    }\r\n\r\n    /**\r\n     * Binds the data to the effect.\r\n     * @param noDefaultBindings if true, the default bindings (scale and alpha mode) will not be set.\r\n     */\r\n    public bind(noDefaultBindings = false) {\r\n        if (this.options.useAsPostProcess && !noDefaultBindings) {\r\n            this.options.engine.setAlphaMode(this.alphaMode);\r\n            this.drawWrapper.effect!.setFloat2(\"scale\", 1, 1);\r\n        }\r\n\r\n        EffectWrapper._GetShaderCodeProcessing(this.name)?.bindCustomBindings?.(this.name, this._drawWrapper.effect!);\r\n    }\r\n\r\n    /**\r\n     * Disposes of the effect wrapper\r\n     * @param _ignored kept for backward compatibility\r\n     */\r\n    public dispose(_ignored: boolean = false) {\r\n        if (this._onContextRestoredObserver) {\r\n            this.effect.getEngine().onContextRestoredObservable.remove(this._onContextRestoredObserver);\r\n            this._onContextRestoredObserver = null;\r\n        }\r\n        this.onEffectCreatedObservable.clear();\r\n        this._drawWrapper.dispose(true);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { type Observer } from \"../Misc/observable\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Effect } from \"../Materials/effect.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type RenderTargetCreationOptions } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { type IInspectable } from \"../Misc/iInspectable\";\r\nimport { type Color4 } from \"../Maths/math.color.pure\";\r\nimport { type NodeMaterial } from \"../Materials/Node/nodeMaterial.pure\";\r\nimport { serialize, serializeAsColor4 } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { GetClass, RegisterClass } from \"../Misc/typeStore\";\r\nimport { type RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type Animation } from \"../Animations/animation.pure\";\r\nimport { type PrePassRenderer } from \"../Rendering/prePassRenderer.pure\";\r\nimport { type PrePassEffectConfiguration } from \"../Rendering/prePassEffectConfiguration\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { GetExponentOfTwo } from \"../Misc/tools.functions\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { type EffectWrapperCustomShaderCodeProcessing, type EffectWrapperCreationOptions } from \"../Materials/effectRenderer\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * Options for the PostProcess constructor\r\n */\r\nexport type PostProcessOptions = EffectWrapperCreationOptions & {\r\n    /**\r\n     * The width of the texture created for this post process.\r\n     * This parameter (and height) is only used when passing a value for the 5th parameter (options) to the PostProcess constructor function.\r\n     * If you use a PostProcessOptions for the 3rd parameter of the constructor, size is used instead of width and height.\r\n     */\r\n    width?: number;\r\n    /**\r\n     * The height of the texture created for this post process.\r\n     * This parameter (and width) is only used when passing a value for the 5th parameter (options) to the PostProcess constructor function.\r\n     * If you use a PostProcessOptions for the 3rd parameter of the constructor, size is used instead of width and height.\r\n     */\r\n    height?: number;\r\n\r\n    /**\r\n     * The size of the post process texture.\r\n     * It is either a ratio to downscale or upscale the texture create for this post process, or an object containing width and height values.\r\n     * Default: 1\r\n     */\r\n    size?: number | { width: number; height: number };\r\n    /**\r\n     * The camera that the post process will be attached to (default: null)\r\n     */\r\n    camera?: Nullable<Camera>;\r\n    /**\r\n     * The sampling mode to be used by the shader (default: Constants.TEXTURE_NEAREST_SAMPLINGMODE)\r\n     */\r\n    samplingMode?: number;\r\n    /**\r\n     * The engine to be used to render the post process (default: engine from scene)\r\n     */\r\n    engine?: AbstractEngine;\r\n    /**\r\n     * If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    reusable?: boolean;\r\n    /**\r\n     * Type of the texture created for this post process (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    textureType?: number;\r\n    /**\r\n     * Format of the texture created for this post process (default: TEXTUREFORMAT_RGBA)\r\n     */\r\n    textureFormat?: number;\r\n    /**\r\n     * The effect wrapper instance used by the post process. If not provided, a new one will be created.\r\n     */\r\n    effectWrapper?: EffectWrapper;\r\n};\r\n\r\ntype TextureCache = { texture: RenderTargetWrapper; postProcessChannel: number; lastUsedRenderId: number };\r\n\r\n/**\r\n * PostProcess can be used to apply a shader to a texture after it has been rendered\r\n * See https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses\r\n */\r\nexport class PostProcess {\r\n    /**\r\n     * Force all the postprocesses to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static get ForceGLSL(): boolean {\r\n        return EffectWrapper.ForceGLSL;\r\n    }\r\n\r\n    public static set ForceGLSL(force: boolean) {\r\n        EffectWrapper.ForceGLSL = force;\r\n    }\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /**\r\n     * Registers a shader code processing with a post process name.\r\n     * @param postProcessName name of the post process. Use null for the fallback shader code processing. This is the shader code processing that will be used in case no specific shader code processing has been associated to a post process name\r\n     * @param customShaderCodeProcessing shader code processing to associate to the post process name\r\n     */\r\n    public static RegisterShaderCodeProcessing(postProcessName: Nullable<string>, customShaderCodeProcessing?: EffectWrapperCustomShaderCodeProcessing) {\r\n        EffectWrapper.RegisterShaderCodeProcessing(postProcessName, customShaderCodeProcessing);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the unique id of the post process\r\n     */\r\n    @serialize()\r\n    public uniqueId: number;\r\n\r\n    /** Name of the PostProcess. */\r\n    @serialize()\r\n    public get name() {\r\n        return this._effectWrapper.name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._effectWrapper.name = value;\r\n    }\r\n\r\n    /**\r\n     * Width of the texture to apply the post process on\r\n     */\r\n    @serialize()\r\n    public width = -1;\r\n\r\n    /**\r\n     * Height of the texture to apply the post process on\r\n     */\r\n    @serialize()\r\n    public height = -1;\r\n\r\n    /**\r\n     * Gets the node material used to create this postprocess (null if the postprocess was manually created)\r\n     */\r\n    public nodeMaterialSource: Nullable<NodeMaterial> = null;\r\n\r\n    /**\r\n     * Internal, reference to the location where this postprocess was output to. (Typically the texture on the next postprocess in the chain)\r\n     * @internal\r\n     */\r\n    public _outputTexture: Nullable<RenderTargetWrapper> = null;\r\n    /**\r\n     * Sampling mode used by the shader\r\n     */\r\n    @serialize()\r\n    public renderTargetSamplingMode: number;\r\n    /**\r\n     * Clear color to use when screen clearing\r\n     */\r\n    @serializeAsColor4()\r\n    public clearColor: Color4;\r\n    /**\r\n     * If the buffer needs to be cleared before applying the post process. (default: true)\r\n     * Should be set to false if shader will overwrite all previous pixels.\r\n     */\r\n    @serialize()\r\n    public autoClear = true;\r\n    /**\r\n     * If clearing the buffer should be forced in autoClear mode, even when alpha mode is enabled (default: false).\r\n     * By default, the buffer will only be cleared if alpha mode is disabled (and autoClear is true).\r\n     */\r\n    @serialize()\r\n    public forceAutoClearInAlphaMode = false;\r\n\r\n    /**\r\n     * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)\r\n     */\r\n    @serialize()\r\n    public get alphaMode() {\r\n        return this._effectWrapper.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(value: number) {\r\n        this._effectWrapper.alphaMode = value;\r\n    }\r\n\r\n    /**\r\n     * Sets the setAlphaBlendConstants of the babylon engine\r\n     */\r\n    @serialize()\r\n    public alphaConstants: Color4;\r\n\r\n    /**\r\n     * Animations to be used for the post processing\r\n     */\r\n    public animations: Animation[] = [];\r\n\r\n    /**\r\n     * Enable Pixel Perfect mode where texture is not scaled to be power of 2.\r\n     * Can only be used on a single postprocess or on the last one of a chain. (default: false)\r\n     */\r\n    @serialize()\r\n    public enablePixelPerfectMode = false;\r\n\r\n    /**\r\n     * Force the postprocess to be applied without taking in account viewport\r\n     */\r\n    @serialize()\r\n    public forceFullscreenViewport = true;\r\n\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    public inspectableCustomProperties: IInspectable[];\r\n\r\n    /**\r\n     * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)\r\n     *\r\n     * | Value | Type                                | Description |\r\n     * | ----- | ----------------------------------- | ----------- |\r\n     * | 1     | SCALEMODE_FLOOR                     | [engine.scalemode_floor](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_floor) |\r\n     * | 2     | SCALEMODE_NEAREST                   | [engine.scalemode_nearest](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_nearest) |\r\n     * | 3     | SCALEMODE_CEILING                   | [engine.scalemode_ceiling](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |\r\n     *\r\n     */\r\n    @serialize()\r\n    public scaleMode = Constants.SCALEMODE_FLOOR;\r\n    /**\r\n     * Force textures to be a power of two (default: false)\r\n     */\r\n    @serialize()\r\n    public alwaysForcePOT = false;\r\n\r\n    @serialize(\"samples\")\r\n    private _samples = 1;\r\n\r\n    /**\r\n     * Number of sample textures (default: 1)\r\n     */\r\n    public get samples() {\r\n        return this._samples;\r\n    }\r\n\r\n    public set samples(n: number) {\r\n        this._samples = Math.min(n, this._engine.getCaps().maxMSAASamples);\r\n\r\n        this._textures.forEach((texture) => {\r\n            texture.setSamples(this._samples);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Modify the scale of the post process to be the same as the viewport (default: false)\r\n     */\r\n    @serialize()\r\n    public adaptScaleToCurrentViewport = false;\r\n\r\n    /**\r\n     * Specifies if the post process should be serialized\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    private _camera: Camera;\r\n    protected _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n\r\n    protected _webGPUReady = false;\r\n\r\n    private _options: number | { width: number; height: number };\r\n    private _reusable = false;\r\n    private _renderId = 0;\r\n    private _textureType: number;\r\n    private _textureFormat: number;\r\n    /** @internal */\r\n    private _shaderLanguage: ShaderLanguage;\r\n\r\n    /**\r\n     * Gets the shader language type used to generate vertex and fragment source code.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * if externalTextureSamplerBinding is true, the \"apply\" method won't bind the textureSampler texture, it is expected to be done by the \"outside\" (by the onApplyObservable observer most probably).\r\n     * counter-productive in some cases because if the texture bound by \"apply\" is different from the currently texture bound, (the one set by the onApplyObservable observer, for eg) some\r\n     * internal structures (materialContext) will be dirtified, which may impact performances\r\n     */\r\n    public externalTextureSamplerBinding = false;\r\n\r\n    /**\r\n     * Smart array of input and output textures for the post process.\r\n     * @internal\r\n     */\r\n    public _textures = new SmartArray<RenderTargetWrapper>(2);\r\n    /**\r\n     * Smart array of input and output textures for the post process.\r\n     * @internal\r\n     */\r\n    private _textureCache: TextureCache[] = [];\r\n    /**\r\n     * The index in _textures that corresponds to the output texture.\r\n     * @internal\r\n     */\r\n    public _currentRenderTextureInd = 0;\r\n    private _samplers: string[];\r\n    private _fragmentUrl: string;\r\n    private _vertexUrl: string;\r\n    private _parameters: string[];\r\n    private _uniformBuffers: string[];\r\n    protected _postProcessDefines: Nullable<string>;\r\n    private _scaleRatio = new Vector2(1, 1);\r\n    protected _indexParameters: any;\r\n    private _shareOutputWithPostProcess: Nullable<PostProcess>;\r\n    private _texelSize = Vector2.Zero();\r\n\r\n    /** @internal */\r\n    public _forcedOutputTexture: Nullable<RenderTargetWrapper>;\r\n\r\n    /**\r\n     * Prepass configuration in case this post process needs a texture from prepass\r\n     * @internal\r\n     */\r\n    public _prePassEffectConfiguration: PrePassEffectConfiguration;\r\n\r\n    /**\r\n     * Returns the fragment url or shader name used in the post process.\r\n     * @returns the fragment url or name in the shader store.\r\n     */\r\n    public getEffectName(): string {\r\n        return this._fragmentUrl;\r\n    }\r\n\r\n    /**\r\n     * Executed when the effect was created\r\n     * @returns effect that was created for this post process\r\n     */\r\n    public onEffectCreatedObservable;\r\n\r\n    // Events\r\n\r\n    /**\r\n     * An event triggered when the postprocess is activated.\r\n     */\r\n    public onActivateObservable = new Observable<Camera>();\r\n\r\n    private _onActivateObserver: Nullable<Observer<Camera>>;\r\n    /**\r\n     * A function that is added to the onActivateObservable\r\n     */\r\n    public set onActivate(callback: Nullable<(camera: Camera) => void>) {\r\n        if (this._onActivateObserver) {\r\n            this.onActivateObservable.remove(this._onActivateObserver);\r\n        }\r\n        if (callback) {\r\n            this._onActivateObserver = this.onActivateObservable.add(callback);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the postprocess changes its size.\r\n     */\r\n    public onSizeChangedObservable = new Observable<PostProcess>();\r\n\r\n    private _onSizeChangedObserver: Nullable<Observer<PostProcess>>;\r\n    /**\r\n     * A function that is added to the onSizeChangedObservable\r\n     */\r\n    public set onSizeChanged(callback: (postProcess: PostProcess) => void) {\r\n        if (this._onSizeChangedObserver) {\r\n            this.onSizeChangedObservable.remove(this._onSizeChangedObserver);\r\n        }\r\n        this._onSizeChangedObserver = this.onSizeChangedObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the postprocess applies its effect.\r\n     */\r\n    public onApplyObservable = new Observable<Effect>();\r\n\r\n    private _onApplyObserver: Nullable<Observer<Effect>>;\r\n    /**\r\n     * A function that is added to the onApplyObservable\r\n     */\r\n    public set onApply(callback: (effect: Effect) => void) {\r\n        if (this._onApplyObserver) {\r\n            this.onApplyObservable.remove(this._onApplyObserver);\r\n        }\r\n        this._onApplyObserver = this.onApplyObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered before rendering the postprocess\r\n     */\r\n    public onBeforeRenderObservable = new Observable<Effect>();\r\n\r\n    private _onBeforeRenderObserver: Nullable<Observer<Effect>>;\r\n    /**\r\n     * A function that is added to the onBeforeRenderObservable\r\n     */\r\n    public set onBeforeRender(callback: (effect: Effect) => void) {\r\n        if (this._onBeforeRenderObserver) {\r\n            this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n        }\r\n        this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered after rendering the postprocess\r\n     */\r\n    public onAfterRenderObservable = new Observable<Effect>();\r\n\r\n    private _onAfterRenderObserver: Nullable<Observer<Effect>>;\r\n    /**\r\n     * A function that is added to the onAfterRenderObservable\r\n     */\r\n    public set onAfterRender(callback: (efect: Effect) => void) {\r\n        if (this._onAfterRenderObserver) {\r\n            this.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n        }\r\n        this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the post-process is disposed\r\n     */\r\n    public readonly onDisposeObservable = new Observable<void>();\r\n\r\n    /**\r\n     * The input texture for this post process and the output texture of the previous post process. When added to a pipeline the previous post process will\r\n     * render it's output into this texture and this texture will be used as textureSampler in the fragment shader of this post process.\r\n     */\r\n    public get inputTexture(): RenderTargetWrapper {\r\n        return this._textures.data[this._currentRenderTextureInd];\r\n    }\r\n\r\n    public set inputTexture(value: RenderTargetWrapper) {\r\n        this._forcedOutputTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Since inputTexture should always be defined, if we previously manually set `inputTexture`,\r\n     * the only way to unset it is to use this function to restore its internal state\r\n     */\r\n    public restoreDefaultInputTexture() {\r\n        if (this._forcedOutputTexture) {\r\n            this._forcedOutputTexture = null;\r\n            this.markTextureDirty();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the camera which post process is applied to.\r\n     * @returns The camera the post process is applied to.\r\n     */\r\n    public getCamera(): Camera {\r\n        return this._camera;\r\n    }\r\n\r\n    /**\r\n     * Gets the texel size of the postprocess.\r\n     * See https://en.wikipedia.org/wiki/Texel_(graphics)\r\n     */\r\n    public get texelSize(): Vector2 {\r\n        if (this._shareOutputWithPostProcess) {\r\n            return this._shareOutputWithPostProcess.texelSize;\r\n        }\r\n\r\n        if (this._forcedOutputTexture) {\r\n            this._texelSize.copyFromFloats(1.0 / this._forcedOutputTexture.width, 1.0 / this._forcedOutputTexture.height);\r\n        }\r\n\r\n        return this._texelSize;\r\n    }\r\n\r\n    protected readonly _effectWrapper: EffectWrapper;\r\n    protected readonly _useExistingThinPostProcess: boolean;\r\n\r\n    /**\r\n     * Creates a new instance PostProcess\r\n     * @param name The name of the PostProcess.\r\n     * @param fragmentUrl The url of the fragment shader to be used.\r\n     * @param options The options to be used when constructing the post process.\r\n     */\r\n    constructor(name: string, fragmentUrl: string, options?: PostProcessOptions);\r\n\r\n    /**\r\n     * Creates a new instance PostProcess\r\n     * @param name The name of the PostProcess.\r\n     * @param fragmentUrl The url of the fragment shader to be used.\r\n     * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.\r\n     * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param defines String of defines that will be set when running the fragment shader. (default: null)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param vertexUrl The url of the vertex shader to be used. (default: \"postprocess\")\r\n     * @param indexParameters The index parameters to be used for babylons include syntax \"#include<kernelBlurVaryingDeclaration>[0..varyingCount]\". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n     * @param blockCompilation If the shader should not be compiled immediatly. (default: false)\r\n     * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)\r\n     * @param shaderLanguage The shader language of the shader. (default: GLSL)\r\n     * @param extraInitializations Defines additional code to call to prepare the shader code\r\n     */\r\n    constructor(\r\n        name: string,\r\n        fragmentUrl: string,\r\n        parameters: Nullable<string[]>,\r\n        samplers: Nullable<string[]>,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        defines?: Nullable<string>,\r\n        textureType?: number,\r\n        vertexUrl?: string,\r\n        indexParameters?: any,\r\n        blockCompilation?: boolean,\r\n        textureFormat?: number,\r\n        shaderLanguage?: ShaderLanguage,\r\n        extraInitializations?: (useWebGPU: boolean, list: Promise<any>[]) => void\r\n    );\r\n\r\n    /** @internal */\r\n    constructor(\r\n        name: string,\r\n        fragmentUrl: string,\r\n        parameters?: Nullable<string[]> | PostProcessOptions,\r\n        samplers?: Nullable<string[]>,\r\n        _size?: number | PostProcessOptions,\r\n        camera?: Nullable<Camera>,\r\n        samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        defines: Nullable<string> = null,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        vertexUrl: string = \"postprocess\",\r\n        indexParameters?: any,\r\n        blockCompilation = false,\r\n        textureFormat = Constants.TEXTUREFORMAT_RGBA,\r\n        shaderLanguage?: ShaderLanguage,\r\n        extraInitializations?: (useWebGPU: boolean, list: Promise<any>[]) => void\r\n    ) {\r\n        // PostProcess pipelines that chain textures (SSAO2, bloom, depth of field, ...) rely on the\r\n        // setTextureFromPostProcess / setTextureFromPostProcessOutput engine/effect methods, which are\r\n        // registered as a side effect. Register them at construction time so these methods work in\r\n        // tree-shaken builds that import the pure module without the side-effect wrapper. Idempotent.\r\n        RegisterPostProcess();\r\n\r\n        let size: number | { width: number; height: number } = 1;\r\n        let uniformBuffers: Nullable<string[]> = null;\r\n        let effectWrapper: EffectWrapper | undefined;\r\n        if (parameters && !Array.isArray(parameters)) {\r\n            const options = parameters;\r\n            parameters = options.uniforms ?? null;\r\n            samplers = options.samplers ?? null;\r\n            size = options.size ?? 1;\r\n            camera = options.camera ?? null;\r\n            samplingMode = options.samplingMode ?? Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            engine = options.engine;\r\n            reusable = options.reusable;\r\n            defines = Array.isArray(options.defines) ? options.defines.join(\"\\n\") : (options.defines ?? null);\r\n            textureType = options.textureType ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            vertexUrl = options.vertexUrl ?? \"postprocess\";\r\n            indexParameters = options.indexParameters;\r\n            blockCompilation = options.blockCompilation ?? false;\r\n            textureFormat = options.textureFormat ?? Constants.TEXTUREFORMAT_RGBA;\r\n            shaderLanguage = options.shaderLanguage ?? ShaderLanguage.GLSL;\r\n            uniformBuffers = options.uniformBuffers ?? null;\r\n            extraInitializations = options.extraInitializations;\r\n            effectWrapper = options.effectWrapper;\r\n        } else if (_size) {\r\n            if (typeof _size === \"number\") {\r\n                size = _size;\r\n            } else {\r\n                size = { width: _size.width!, height: _size.height! };\r\n            }\r\n        }\r\n\r\n        this._useExistingThinPostProcess = !!effectWrapper;\r\n\r\n        this._effectWrapper =\r\n            effectWrapper ??\r\n            new EffectWrapper({\r\n                name,\r\n                useShaderStore: true,\r\n                useAsPostProcess: true,\r\n                fragmentShader: fragmentUrl,\r\n                engine: engine || camera?.getScene().getEngine(),\r\n                uniforms: parameters,\r\n                samplers,\r\n                uniformBuffers,\r\n                defines,\r\n                vertexUrl,\r\n                indexParameters,\r\n                blockCompilation: true,\r\n                shaderLanguage,\r\n                extraInitializations: undefined,\r\n            });\r\n\r\n        this.name = name;\r\n        this.onEffectCreatedObservable = this._effectWrapper.onEffectCreatedObservable;\r\n\r\n        if (camera != null) {\r\n            this._camera = camera;\r\n            this._scene = camera.getScene();\r\n            camera.attachPostProcess(this);\r\n            this._engine = this._scene.getEngine();\r\n\r\n            this._scene.addPostProcess(this);\r\n            this.uniqueId = this._scene.getUniqueId();\r\n        } else if (engine) {\r\n            this._engine = engine;\r\n            this._engine.postProcesses.push(this);\r\n        }\r\n\r\n        this._options = size;\r\n        this.renderTargetSamplingMode = samplingMode ? samplingMode : Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        this._reusable = reusable || false;\r\n        this._textureType = textureType;\r\n        this._textureFormat = textureFormat;\r\n        this._shaderLanguage = shaderLanguage || ShaderLanguage.GLSL;\r\n\r\n        this._samplers = samplers || [];\r\n        if (this._samplers.indexOf(\"textureSampler\") === -1) {\r\n            this._samplers.push(\"textureSampler\");\r\n        }\r\n\r\n        this._fragmentUrl = fragmentUrl;\r\n        this._vertexUrl = vertexUrl;\r\n        this._parameters = parameters || [];\r\n\r\n        if (this._parameters.indexOf(\"scale\") === -1) {\r\n            this._parameters.push(\"scale\");\r\n        }\r\n        this._uniformBuffers = uniformBuffers || [];\r\n\r\n        this._indexParameters = indexParameters;\r\n\r\n        if (!this._useExistingThinPostProcess) {\r\n            this._webGPUReady = this._shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n            const importPromises: Array<Promise<any>> = [];\r\n\r\n            this._gatherImports(this._engine.isWebGPU && !PostProcess.ForceGLSL, importPromises);\r\n\r\n            this._effectWrapper._webGPUReady = this._webGPUReady;\r\n            this._effectWrapper._postConstructor(blockCompilation, defines, extraInitializations, importPromises);\r\n        }\r\n    }\r\n\r\n    protected _gatherImports(useWebGPU = false, list: Promise<any>[]) {\r\n        // this._webGPUReady is used to detect when a postprocess is intended to be used with WebGPU\r\n        if (useWebGPU && this._webGPUReady) {\r\n            list.push(Promise.all([import(\"../ShadersWGSL/postprocess.vertex\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/postprocess.vertex\")]));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"PostProcess\" string\r\n     */\r\n    public getClassName(): string {\r\n        return \"PostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Gets the engine which this post process belongs to.\r\n     * @returns The engine the post process was enabled with.\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * The effect that is created when initializing the post process.\r\n     * @returns The created effect corresponding to the postprocess.\r\n     */\r\n    public getEffect(): Effect {\r\n        return this._effectWrapper.drawWrapper.effect!;\r\n    }\r\n\r\n    /**\r\n     * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.\r\n     * @param postProcess The post process to share the output with.\r\n     * @returns This post process.\r\n     */\r\n    public shareOutputWith(postProcess: PostProcess): PostProcess {\r\n        this._disposeTextures();\r\n\r\n        this._shareOutputWithPostProcess = postProcess;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Reverses the effect of calling shareOutputWith and returns the post process back to its original state.\r\n     * This should be called if the post process that shares output with this post process is disabled/disposed.\r\n     */\r\n    public useOwnOutput() {\r\n        if (this._textures.length == 0) {\r\n            this._textures = new SmartArray<RenderTargetWrapper>(2);\r\n        }\r\n\r\n        this._shareOutputWithPostProcess = null;\r\n    }\r\n\r\n    /**\r\n     * Updates the effect with the current post process compile time values and recompiles the shader.\r\n     * @param defines Define statements that should be added at the beginning of the shader. (default: null)\r\n     * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)\r\n     * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)\r\n     * @param indexParameters The index parameters to be used for babylons include syntax \"#include<kernelBlurVaryingDeclaration>[0..varyingCount]\". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n     * @param onCompiled Called when the shader has been compiled.\r\n     * @param onError Called if there is an error when compiling a shader.\r\n     * @param vertexUrl The url of the vertex shader to be used (default: the one given at construction time)\r\n     * @param fragmentUrl The url of the fragment shader to be used (default: the one given at construction time)\r\n     */\r\n    public updateEffect(\r\n        defines: Nullable<string> = null,\r\n        uniforms: Nullable<string[]> = null,\r\n        samplers: Nullable<string[]> = null,\r\n        indexParameters?: any,\r\n        onCompiled?: (effect: Effect) => void,\r\n        onError?: (effect: Effect, errors: string) => void,\r\n        vertexUrl?: string,\r\n        fragmentUrl?: string\r\n    ) {\r\n        this._effectWrapper.updateEffect(defines, uniforms, samplers, indexParameters, onCompiled, onError, vertexUrl, fragmentUrl);\r\n        this._postProcessDefines = Array.isArray(this._effectWrapper.options.defines) ? this._effectWrapper.options.defines.join(\"\\n\") : this._effectWrapper.options.defines;\r\n    }\r\n\r\n    /**\r\n     * The post process is reusable if it can be used multiple times within one frame.\r\n     * @returns If the post process is reusable\r\n     */\r\n    public isReusable(): boolean {\r\n        return this._reusable;\r\n    }\r\n\r\n    /** invalidate frameBuffer to hint the postprocess to create a depth buffer */\r\n    public markTextureDirty(): void {\r\n        this.width = -1;\r\n    }\r\n\r\n    private _createRenderTargetTexture(textureSize: { width: number; height: number }, textureOptions: RenderTargetCreationOptions, channel = 0) {\r\n        for (let i = 0; i < this._textureCache.length; i++) {\r\n            if (\r\n                this._textureCache[i].texture.width === textureSize.width &&\r\n                this._textureCache[i].texture.height === textureSize.height &&\r\n                this._textureCache[i].postProcessChannel === channel &&\r\n                this._textureCache[i].texture._generateDepthBuffer === textureOptions.generateDepthBuffer &&\r\n                this._textureCache[i].texture.samples === textureOptions.samples\r\n            ) {\r\n                return this._textureCache[i].texture;\r\n            }\r\n        }\r\n\r\n        const tex = this._engine.createRenderTargetTexture(textureSize, textureOptions);\r\n        this._textureCache.push({ texture: tex, postProcessChannel: channel, lastUsedRenderId: -1 });\r\n\r\n        return tex;\r\n    }\r\n\r\n    private _flushTextureCache() {\r\n        const currentRenderId = this._renderId;\r\n\r\n        for (let i = this._textureCache.length - 1; i >= 0; i--) {\r\n            if (currentRenderId - this._textureCache[i].lastUsedRenderId > 100) {\r\n                let currentlyUsed = false;\r\n                for (let j = 0; j < this._textures.length; j++) {\r\n                    if (this._textures.data[j] === this._textureCache[i].texture) {\r\n                        currentlyUsed = true;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (!currentlyUsed) {\r\n                    this._textureCache[i].texture.dispose();\r\n                    this._textureCache.splice(i, 1);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resizes the post-process texture\r\n     * @param width Width of the texture\r\n     * @param height Height of the texture\r\n     * @param camera The camera this post-process is applied to. Pass null if the post-process is used outside the context of a camera post-process chain (default: null)\r\n     * @param needMipMaps True if mip maps need to be generated after render (default: false)\r\n     * @param forceDepthStencil True to force post-process texture creation with stencil depth and buffer (default: false)\r\n     */\r\n    public resize(width: number, height: number, camera: Nullable<Camera> = null, needMipMaps = false, forceDepthStencil = false) {\r\n        if (this._textures.length > 0) {\r\n            this._textures.reset();\r\n        }\r\n\r\n        this.width = width;\r\n        this.height = height;\r\n\r\n        let firstPP = null;\r\n        if (camera) {\r\n            for (let i = 0; i < camera._postProcesses.length; i++) {\r\n                if (camera._postProcesses[i] !== null) {\r\n                    firstPP = camera._postProcesses[i];\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        const textureSize = { width: this.width, height: this.height };\r\n        const textureOptions = {\r\n            generateMipMaps: needMipMaps,\r\n            generateDepthBuffer: forceDepthStencil || firstPP === this,\r\n            generateStencilBuffer: (forceDepthStencil || firstPP === this) && this._engine.isStencilEnable,\r\n            samplingMode: this.renderTargetSamplingMode,\r\n            type: this._textureType,\r\n            format: this._textureFormat,\r\n            samples: this._samples,\r\n            label: \"PostProcessRTT-\" + this.name,\r\n        };\r\n\r\n        this._textures.push(this._createRenderTargetTexture(textureSize, textureOptions, 0));\r\n\r\n        if (this._reusable) {\r\n            this._textures.push(this._createRenderTargetTexture(textureSize, textureOptions, 1));\r\n        }\r\n\r\n        this._texelSize.copyFromFloats(1.0 / this.width, 1.0 / this.height);\r\n\r\n        this.onSizeChangedObservable.notifyObservers(this);\r\n    }\r\n\r\n    private _getTarget() {\r\n        let target: RenderTargetWrapper;\r\n\r\n        if (this._shareOutputWithPostProcess) {\r\n            target = this._shareOutputWithPostProcess.inputTexture;\r\n        } else if (this._forcedOutputTexture) {\r\n            target = this._forcedOutputTexture;\r\n\r\n            this.width = this._forcedOutputTexture.width;\r\n            this.height = this._forcedOutputTexture.height;\r\n        } else {\r\n            target = this.inputTexture;\r\n\r\n            let cache;\r\n            for (let i = 0; i < this._textureCache.length; i++) {\r\n                if (this._textureCache[i].texture === target) {\r\n                    cache = this._textureCache[i];\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (cache) {\r\n                cache.lastUsedRenderId = this._renderId;\r\n            }\r\n        }\r\n\r\n        return target;\r\n    }\r\n\r\n    /**\r\n     * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.\r\n     * When this post process is used in a pipeline, this is call will bind the input texture of this post process to the output of the previous.\r\n     * @param cameraOrScene The camera that will be used in the post process. This camera will be used when calling onActivateObservable. You can also pass the scene if no camera is available.\r\n     * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)\r\n     * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)\r\n     * @returns The render target wrapper that was bound to be written to.\r\n     */\r\n    public activate(cameraOrScene: Nullable<Camera> | Scene, sourceTexture: Nullable<InternalTexture> = null, forceDepthStencil?: boolean): RenderTargetWrapper {\r\n        const camera = cameraOrScene === null || (cameraOrScene as Camera).cameraRigMode !== undefined ? (cameraOrScene as Camera) || this._camera : null;\r\n\r\n        const scene = camera?.getScene() ?? (cameraOrScene as Scene);\r\n        const engine = scene.getEngine();\r\n        const maxSize = engine.getCaps().maxTextureSize;\r\n\r\n        const requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * <number>this._options) | 0;\r\n        const requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * <number>this._options) | 0;\r\n\r\n        let desiredWidth = (<PostProcessOptions>this._options).width || requiredWidth;\r\n        let desiredHeight = (<PostProcessOptions>this._options).height || requiredHeight;\r\n\r\n        const needMipMaps =\r\n            this.renderTargetSamplingMode !== Constants.TEXTURE_NEAREST_LINEAR &&\r\n            this.renderTargetSamplingMode !== Constants.TEXTURE_NEAREST_NEAREST &&\r\n            this.renderTargetSamplingMode !== Constants.TEXTURE_LINEAR_LINEAR;\r\n\r\n        let target: Nullable<RenderTargetWrapper> = null;\r\n\r\n        if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {\r\n            if (this.adaptScaleToCurrentViewport) {\r\n                const currentViewport = engine.currentViewport;\r\n\r\n                if (currentViewport) {\r\n                    desiredWidth *= currentViewport.width;\r\n                    desiredHeight *= currentViewport.height;\r\n                }\r\n            }\r\n\r\n            if (needMipMaps || this.alwaysForcePOT) {\r\n                if (!(<PostProcessOptions>this._options).width) {\r\n                    desiredWidth = engine.needPOTTextures ? GetExponentOfTwo(desiredWidth, maxSize, this.scaleMode) : desiredWidth;\r\n                }\r\n\r\n                if (!(<PostProcessOptions>this._options).height) {\r\n                    desiredHeight = engine.needPOTTextures ? GetExponentOfTwo(desiredHeight, maxSize, this.scaleMode) : desiredHeight;\r\n                }\r\n            }\r\n\r\n            if (this.width !== desiredWidth || this.height !== desiredHeight || !(target = this._getTarget())) {\r\n                this.resize(desiredWidth, desiredHeight, camera, needMipMaps, forceDepthStencil);\r\n            }\r\n\r\n            this._textures.forEach((texture) => {\r\n                if (texture.samples !== this.samples) {\r\n                    this._engine.updateRenderTargetTextureSampleCount(texture, this.samples);\r\n                }\r\n            });\r\n\r\n            this._flushTextureCache();\r\n            this._renderId++;\r\n        }\r\n\r\n        if (!target) {\r\n            target = this._getTarget();\r\n        }\r\n\r\n        // Bind the input of this post process to be used as the output of the previous post process.\r\n        if (this.enablePixelPerfectMode) {\r\n            this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);\r\n            this._engine.bindFramebuffer(target, 0, requiredWidth, requiredHeight, this.forceFullscreenViewport);\r\n        } else {\r\n            this._scaleRatio.copyFromFloats(1, 1);\r\n            this._engine.bindFramebuffer(target, 0, undefined, undefined, this.forceFullscreenViewport);\r\n        }\r\n\r\n        this._engine._debugInsertMarker?.(`post process ${this.name} input`);\r\n\r\n        this.onActivateObservable.notifyObservers(camera!);\r\n\r\n        // Clear\r\n        if (this.autoClear && (this.alphaMode === Constants.ALPHA_DISABLE || this.forceAutoClearInAlphaMode)) {\r\n            this._engine.clear(this.clearColor ? this.clearColor : scene.clearColor, scene._allowPostProcessClearColor, true, true);\r\n        }\r\n\r\n        if (this._reusable) {\r\n            this._currentRenderTextureInd = (this._currentRenderTextureInd + 1) % 2;\r\n        }\r\n        return target;\r\n    }\r\n\r\n    /**\r\n     * If the post process is supported.\r\n     */\r\n    public get isSupported(): boolean {\r\n        return this._effectWrapper.drawWrapper.effect!.isSupported;\r\n    }\r\n\r\n    /**\r\n     * The aspect ratio of the output texture.\r\n     */\r\n    public get aspectRatio(): number {\r\n        if (this._shareOutputWithPostProcess) {\r\n            return this._shareOutputWithPostProcess.aspectRatio;\r\n        }\r\n\r\n        if (this._forcedOutputTexture) {\r\n            return this._forcedOutputTexture.width / this._forcedOutputTexture.height;\r\n        }\r\n        return this.width / this.height;\r\n    }\r\n\r\n    /**\r\n     * Get a value indicating if the post-process is ready to be used\r\n     * @returns true if the post-process is ready (shader is compiled)\r\n     */\r\n    public isReady(): boolean {\r\n        return this._effectWrapper.isReady();\r\n    }\r\n\r\n    /**\r\n     * Binds all textures and uniforms to the shader, this will be run on every pass.\r\n     * @returns the effect corresponding to this post process. Null if not compiled or not ready.\r\n     */\r\n    public apply(): Nullable<Effect> {\r\n        // Check\r\n        if (!this._effectWrapper.isReady()) {\r\n            return null;\r\n        }\r\n\r\n        // States\r\n        this._engine.enableEffect(this._effectWrapper.drawWrapper);\r\n        this._engine.setState(false);\r\n        this._engine.setDepthBuffer(false);\r\n        this._engine.setDepthWrite(false);\r\n\r\n        // Alpha\r\n        if (this.alphaConstants) {\r\n            this.getEngine().setAlphaConstants(this.alphaConstants.r, this.alphaConstants.g, this.alphaConstants.b, this.alphaConstants.a);\r\n        }\r\n\r\n        this._engine.setAlphaMode(this.alphaMode);\r\n\r\n        // Bind the output texture of the preivous post process as the input to this post process.\r\n        let source: RenderTargetWrapper;\r\n        if (this._shareOutputWithPostProcess) {\r\n            source = this._shareOutputWithPostProcess.inputTexture;\r\n        } else if (this._forcedOutputTexture) {\r\n            source = this._forcedOutputTexture;\r\n        } else {\r\n            source = this.inputTexture;\r\n        }\r\n\r\n        if (!this.externalTextureSamplerBinding) {\r\n            this._effectWrapper.drawWrapper.effect!._bindTexture(\"textureSampler\", source?.texture);\r\n        }\r\n\r\n        // Parameters\r\n        this._effectWrapper.drawWrapper.effect!.setVector2(\"scale\", this._scaleRatio);\r\n        this.onApplyObservable.notifyObservers(this._effectWrapper.drawWrapper.effect!);\r\n\r\n        this._effectWrapper.bind(true);\r\n\r\n        return this._effectWrapper.drawWrapper.effect;\r\n    }\r\n\r\n    private _disposeTextures() {\r\n        if (this._shareOutputWithPostProcess || this._forcedOutputTexture) {\r\n            this._disposeTextureCache();\r\n            return;\r\n        }\r\n\r\n        this._disposeTextureCache();\r\n        this._textures.dispose();\r\n    }\r\n\r\n    private _disposeTextureCache() {\r\n        for (let i = this._textureCache.length - 1; i >= 0; i--) {\r\n            this._textureCache[i].texture.dispose();\r\n        }\r\n\r\n        this._textureCache.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the required values to the prepass renderer.\r\n     * @param prePassRenderer defines the prepass renderer to setup.\r\n     * @returns true if the pre pass is needed.\r\n     */\r\n    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {\r\n        if (this._prePassEffectConfiguration) {\r\n            this._prePassEffectConfiguration = prePassRenderer.addEffectConfiguration(this._prePassEffectConfiguration);\r\n            this._prePassEffectConfiguration.enabled = true;\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Disposes the post process.\r\n     * @param camera The camera to dispose the post process on.\r\n     */\r\n    public dispose(camera?: Camera): void {\r\n        camera = camera || this._camera;\r\n\r\n        if (!this._useExistingThinPostProcess) {\r\n            this._effectWrapper.dispose();\r\n        }\r\n\r\n        this._disposeTextures();\r\n\r\n        if (this._scene) {\r\n            this._scene.removePostProcess(this);\r\n        }\r\n\r\n        let index: number;\r\n        if (this._parentContainer) {\r\n            index = this._parentContainer.postProcesses.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.postProcesses.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        index = this._engine.postProcesses.indexOf(this);\r\n        if (index !== -1) {\r\n            this._engine.postProcesses.splice(index, 1);\r\n        }\r\n\r\n        this.onDisposeObservable.notifyObservers();\r\n\r\n        if (!camera) {\r\n            return;\r\n        }\r\n        camera.detachPostProcess(this);\r\n\r\n        index = camera._postProcesses.indexOf(this);\r\n        if (index === 0 && camera._postProcesses.length > 0) {\r\n            const firstPostProcess = this._camera._getFirstPostProcess();\r\n            if (firstPostProcess) {\r\n                firstPostProcess.markTextureDirty();\r\n            }\r\n        }\r\n\r\n        this.onActivateObservable.clear();\r\n        this.onAfterRenderObservable.clear();\r\n        this.onApplyObservable.clear();\r\n        this.onBeforeRenderObservable.clear();\r\n        this.onSizeChangedObservable.clear();\r\n        this.onEffectCreatedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Serializes the post process to a JSON object\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        const camera = this.getCamera() || (this._scene && this._scene.activeCamera);\r\n        serializationObject.customType = \"BABYLON.\" + this.getClassName();\r\n        serializationObject.cameraId = camera ? camera.id : null;\r\n        serializationObject.reusable = this._reusable;\r\n        serializationObject.textureType = this._textureType;\r\n        serializationObject.fragmentUrl = this._fragmentUrl;\r\n        serializationObject.parameters = this._parameters;\r\n        serializationObject.samplers = this._samplers;\r\n        serializationObject.uniformBuffers = this._uniformBuffers;\r\n        serializationObject.options = this._options;\r\n        serializationObject.defines = this._postProcessDefines;\r\n        serializationObject.textureFormat = this._textureFormat;\r\n        serializationObject.vertexUrl = this._vertexUrl;\r\n        serializationObject.indexParameters = this._indexParameters;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Clones this post process\r\n     * @returns a new post process similar to this one\r\n     */\r\n    public clone(): Nullable<PostProcess> {\r\n        const serializationObject = this.serialize();\r\n        serializationObject._engine = this._engine;\r\n        serializationObject.cameraId = null;\r\n\r\n        const result = PostProcess.Parse(serializationObject, this._scene, \"\");\r\n\r\n        if (!result) {\r\n            return null;\r\n        }\r\n\r\n        result.onActivateObservable = this.onActivateObservable.clone();\r\n        result.onSizeChangedObservable = this.onSizeChangedObservable.clone();\r\n        result.onApplyObservable = this.onApplyObservable.clone();\r\n        result.onBeforeRenderObservable = this.onBeforeRenderObservable.clone();\r\n        result.onAfterRenderObservable = this.onAfterRenderObservable.clone();\r\n\r\n        result._prePassEffectConfiguration = this._prePassEffectConfiguration;\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a material from parsed material data\r\n     * @param parsedPostProcess defines parsed post process data\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures\r\n     * @returns a new post process\r\n     */\r\n    public static Parse(parsedPostProcess: any, scene: Scene, rootUrl: string): Nullable<PostProcess> {\r\n        const postProcessType = GetClass(parsedPostProcess.customType);\r\n\r\n        if (!postProcessType || !postProcessType._Parse) {\r\n            return null;\r\n        }\r\n\r\n        const camera = scene ? scene.getCameraById(parsedPostProcess.cameraId) : null;\r\n        return postProcessType._Parse(parsedPostProcess, camera, scene, rootUrl) as Nullable<PostProcess>;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _Parse(parsedPostProcess: any, targetCamera: Nullable<Camera>, scene: Nullable<Scene>, rootUrl: string): Nullable<PostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new PostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.fragmentUrl,\r\n                    parsedPostProcess.parameters,\r\n                    parsedPostProcess.samplers,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    parsedPostProcess._engine,\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.defines,\r\n                    parsedPostProcess.textureType,\r\n                    parsedPostProcess.vertexUrl,\r\n                    parsedPostProcess.indexParameters,\r\n                    false,\r\n                    parsedPostProcess.textureFormat\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for postProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.setTextureFromPostProcess = function (channel: number, postProcess: Nullable<PostProcess>, name: string): void {\r\n        let postProcessInput = null;\r\n        if (postProcess) {\r\n            if (postProcess._forcedOutputTexture) {\r\n                postProcessInput = postProcess._forcedOutputTexture;\r\n            } else if (postProcess._textures.data[postProcess._currentRenderTextureInd]) {\r\n                postProcessInput = postProcess._textures.data[postProcess._currentRenderTextureInd];\r\n            }\r\n        }\r\n\r\n        this._bindTexture(channel, postProcessInput?.texture ?? null, name);\r\n    };\r\n\r\n    AbstractEngine.prototype.setTextureFromPostProcessOutput = function (channel: number, postProcess: Nullable<PostProcess>, name: string): void {\r\n        this._bindTexture(channel, postProcess?._outputTexture?.texture ?? null, name);\r\n    };\r\n\r\n    /**\r\n     * Sets a texture to be the input of the specified post process. (To use the output, pass in the next post process in the pipeline)\r\n     * @param channel Name of the sampler variable.\r\n     * @param postProcess Post process to get the input texture from.\r\n     */\r\n    Effect.prototype.setTextureFromPostProcess = function (channel: string, postProcess: Nullable<PostProcess>): void {\r\n        this._engine.setTextureFromPostProcess(this._samplers[channel], postProcess, channel);\r\n    };\r\n\r\n    /**\r\n     * (Warning! setTextureFromPostProcessOutput may be desired instead)\r\n     * Sets the input texture of the passed in post process to be input of this effect. (To use the output of the passed in post process use setTextureFromPostProcessOutput)\r\n     * @param channel Name of the sampler variable.\r\n     * @param postProcess Post process to get the output texture from.\r\n     */\r\n    Effect.prototype.setTextureFromPostProcessOutput = function (channel: string, postProcess: Nullable<PostProcess>): void {\r\n        this._engine.setTextureFromPostProcessOutput(this._samplers[channel], postProcess, channel);\r\n    };\r\n\r\n    RegisterClass(\"BABYLON.PostProcess\", PostProcess);\r\n}\r\n","import { type Nullable, type EffectWrapperCreationOptions, type AbstractEngine } from \"core/index\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * PassPostProcess which produces an output the same as it's input\r\n */\r\nexport class ThinPassPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"pass\";\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/pass.fragment\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/pass.fragment\")]));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    /**\r\n     * Constructs a new pass post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        const localOptions: EffectWrapperCreationOptions = {\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinPassPostProcess.FragmentUrl,\r\n            ...options,\r\n        };\r\n\r\n        if (!localOptions.engine) {\r\n            localOptions.engine = EngineStore.LastCreatedEngine!;\r\n        }\r\n\r\n        super(localOptions);\r\n    }\r\n}\r\n\r\n/**\r\n * PassCubePostProcess which produces an output the same as it's input (which must be a cube texture)\r\n */\r\nexport class ThinPassCubePostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"passCube\";\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/passCube.fragment\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/passCube.fragment\")]));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    /**\r\n     * Creates the PassCubePostProcess\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinPassCubePostProcess.FragmentUrl,\r\n            defines: \"#define POSITIVEX\",\r\n        });\r\n    }\r\n\r\n    private _face = 0;\r\n\r\n    /**\r\n     * Gets or sets the cube face to display.\r\n     *  * 0 is +X\r\n     *  * 1 is -X\r\n     *  * 2 is +Y\r\n     *  * 3 is -Y\r\n     *  * 4 is +Z\r\n     *  * 5 is -Z\r\n     */\r\n    public get face(): number {\r\n        return this._face;\r\n    }\r\n\r\n    public set face(value: number) {\r\n        if (value < 0 || value > 5) {\r\n            return;\r\n        }\r\n\r\n        this._face = value;\r\n        switch (this._face) {\r\n            case 0:\r\n                this.updateEffect(\"#define POSITIVEX\");\r\n                break;\r\n            case 1:\r\n                this.updateEffect(\"#define NEGATIVEX\");\r\n                break;\r\n            case 2:\r\n                this.updateEffect(\"#define POSITIVEY\");\r\n                break;\r\n            case 3:\r\n                this.updateEffect(\"#define NEGATIVEY\");\r\n                break;\r\n            case 4:\r\n                this.updateEffect(\"#define POSITIVEZ\");\r\n                break;\r\n            case 5:\r\n                this.updateEffect(\"#define NEGATIVEZ\");\r\n                break;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type PostProcessOptions } from \"./postProcess\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinPassCubePostProcess, ThinPassPostProcess } from \"./thinPassPostProcess\";\r\nimport { serialize } from \"core/Misc/decorators\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * PassPostProcess which produces an output the same as it's input\r\n */\r\nexport class PassPostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"PassPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PassPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Creates the PassPostProcess\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType The type of texture to be used when performing the post processing.\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinPassPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinPassPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new PassPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    parsedPostProcess._engine,\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * PassCubePostProcess which produces an output the same as it's input (which must be a cube texture)\r\n */\r\nexport class PassCubePostProcess extends PostProcess {\r\n    /**\r\n     * Gets or sets the cube face to display.\r\n     *  * 0 is +X\r\n     *  * 1 is -X\r\n     *  * 2 is +Y\r\n     *  * 3 is -Y\r\n     *  * 4 is +Z\r\n     *  * 5 is -Z\r\n     */\r\n    @serialize()\r\n    public get face(): number {\r\n        return this._effectWrapper.face;\r\n    }\r\n\r\n    public set face(value: number) {\r\n        this._effectWrapper.face = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"PassCubePostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PassCubePostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinPassCubePostProcess;\r\n\r\n    /**\r\n     * Creates the PassCubePostProcess\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType The type of texture to be used when performing the post processing.\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinPassPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinPassCubePostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new PassCubePostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    parsedPostProcess._engine,\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for passPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPassPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PassPostProcess\", PassPostProcess);\r\n\r\n    AbstractEngine._RescalePostProcessFactory = (engine: AbstractEngine) => {\r\n        return new PassPostProcess(\"rescale\", 1, null, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, engine, false, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n    };\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { PassPostProcess } from \"../PostProcesses/passPostProcess.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Scene } from \"../scene\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type Observable } from \"./observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { FromHalfFloat, ToHalfFloat } from \"./halfFloat\";\r\n\r\nexport { FromHalfFloat, ToHalfFloat };\r\n\r\n/**\r\n * Uses the GPU to create a copy texture rescaled at a given size\r\n * @param texture Texture to copy from\r\n * @param width defines the desired width\r\n * @param height defines the desired height\r\n * @param useBilinearMode defines if bilinear mode has to be used\r\n * @returns the generated texture\r\n */\r\nexport function CreateResizedCopy(texture: Texture, width: number, height: number, useBilinearMode: boolean = true): Texture {\r\n    const scene = <Scene>texture.getScene();\r\n    const engine = scene.getEngine();\r\n\r\n    const rtt = new RenderTargetTexture(\r\n        \"resized\" + texture.name,\r\n        { width: width, height: height },\r\n        scene,\r\n        !texture.noMipmap,\r\n        true,\r\n        (<InternalTexture>texture._texture).type,\r\n        false,\r\n        texture.samplingMode,\r\n        false\r\n    );\r\n\r\n    rtt.wrapU = texture.wrapU;\r\n    rtt.wrapV = texture.wrapV;\r\n    rtt.uOffset = texture.uOffset;\r\n    rtt.vOffset = texture.vOffset;\r\n    rtt.uScale = texture.uScale;\r\n    rtt.vScale = texture.vScale;\r\n    rtt.uAng = texture.uAng;\r\n    rtt.vAng = texture.vAng;\r\n    rtt.wAng = texture.wAng;\r\n    rtt.coordinatesIndex = texture.coordinatesIndex;\r\n    rtt.level = texture.level;\r\n    rtt.anisotropicFilteringLevel = texture.anisotropicFilteringLevel;\r\n    (<InternalTexture>rtt._texture).isReady = false;\r\n\r\n    texture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n    texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n\r\n    const passPostProcess = new PassPostProcess(\r\n        \"pass\",\r\n        1,\r\n        null,\r\n        useBilinearMode ? Texture.BILINEAR_SAMPLINGMODE : Texture.NEAREST_SAMPLINGMODE,\r\n        engine,\r\n        false,\r\n        Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    );\r\n    passPostProcess.externalTextureSamplerBinding = true;\r\n    passPostProcess.onEffectCreatedObservable.addOnce((e) => {\r\n        e.executeWhenCompiled(() => {\r\n            passPostProcess.onApply = function (effect) {\r\n                effect.setTexture(\"textureSampler\", texture);\r\n            };\r\n\r\n            const internalTexture = rtt.renderTarget;\r\n\r\n            if (internalTexture) {\r\n                scene.postProcessManager.directRender([passPostProcess], internalTexture);\r\n\r\n                engine.unBindFramebuffer(internalTexture);\r\n                rtt.disposeFramebufferObjects();\r\n                passPostProcess.dispose();\r\n\r\n                rtt.getInternalTexture()!.isReady = true;\r\n            }\r\n        });\r\n    });\r\n\r\n    return rtt;\r\n}\r\n\r\n/**\r\n * Apply a post process to a texture\r\n * @param postProcessName name of the fragment post process\r\n * @param internalTexture the texture to encode\r\n * @param scene the scene hosting the texture\r\n * @param type type of the output texture. If not provided, use the one from internalTexture\r\n * @param samplingMode sampling mode to use to sample the source texture. If not provided, use the one from internalTexture\r\n * @param format format of the output texture. If not provided, use the one from internalTexture\r\n * @param width width of the output texture. If not provided, use the one from internalTexture\r\n * @param height height of the output texture. If not provided, use the one from internalTexture\r\n * @returns a promise with the internalTexture having its texture replaced by the result of the processing\r\n */\r\n// eslint-disable-next-line @typescript-eslint/promise-function-async\r\nexport function ApplyPostProcess(\r\n    postProcessName: string,\r\n    internalTexture: InternalTexture,\r\n    scene: Scene,\r\n    type?: number,\r\n    samplingMode?: number,\r\n    format?: number,\r\n    width?: number,\r\n    height?: number\r\n): Promise<InternalTexture> {\r\n    // Gets everything ready.\r\n    const engine = internalTexture.getEngine();\r\n\r\n    internalTexture.isReady = false;\r\n\r\n    samplingMode = samplingMode ?? internalTexture.samplingMode;\r\n    type = type ?? internalTexture.type;\r\n    format = format ?? internalTexture.format;\r\n    width = width ?? internalTexture.width;\r\n    height = height ?? internalTexture.height;\r\n\r\n    if (type === -1) {\r\n        type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    }\r\n\r\n    return new Promise((resolve) => {\r\n        // Create the post process\r\n        const postProcess = new PostProcess(\"postprocess\", postProcessName, null, null, 1, null, samplingMode, engine, false, undefined, type, undefined, null, false, format);\r\n        postProcess.externalTextureSamplerBinding = true;\r\n\r\n        // Hold the output of the decoding.\r\n        const encodedTexture = engine.createRenderTargetTexture(\r\n            { width: width, height: height },\r\n            {\r\n                generateDepthBuffer: false,\r\n                generateMipMaps: false,\r\n                generateStencilBuffer: false,\r\n                samplingMode,\r\n                type,\r\n                format,\r\n            }\r\n        );\r\n\r\n        postProcess.onEffectCreatedObservable.addOnce((e) => {\r\n            e.executeWhenCompiled(() => {\r\n                // PP Render Pass\r\n                postProcess.onApply = (effect) => {\r\n                    effect._bindTexture(\"textureSampler\", internalTexture);\r\n                    effect.setFloat2(\"scale\", 1, 1);\r\n                };\r\n                scene.postProcessManager.directRender([postProcess], encodedTexture, true);\r\n\r\n                // Cleanup\r\n                engine.restoreDefaultFramebuffer();\r\n                engine._releaseTexture(internalTexture);\r\n                if (postProcess) {\r\n                    postProcess.dispose();\r\n                }\r\n\r\n                // Internal Swap\r\n                encodedTexture._swapAndDie(internalTexture);\r\n\r\n                // Ready to get rolling again.\r\n                internalTexture.type = type!;\r\n                internalTexture.format = Constants.TEXTUREFORMAT_RGBA;\r\n                internalTexture.isReady = true;\r\n\r\n                resolve(internalTexture);\r\n            });\r\n        });\r\n    });\r\n}\r\n\r\nfunction IsCompressedTextureFormat(format: number): boolean {\r\n    switch (format) {\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:\r\n            return true;\r\n        default:\r\n            return false;\r\n    }\r\n}\r\n\r\n/**\r\n * Waits for when the given texture is ready to be used (downloaded, converted, mip mapped...)\r\n * @param texture the texture to wait for\r\n * @returns a promise that resolves when the texture is ready\r\n */\r\nexport async function WhenTextureReadyAsync(texture: BaseTexture): Promise<void> {\r\n    if (texture.isReady()) {\r\n        return;\r\n    }\r\n\r\n    if (texture.loadingError) {\r\n        throw new Error(texture.errorObject?.message || `Texture ${texture.name} errored while loading.`);\r\n    }\r\n\r\n    const onLoadObservable = (texture as any).onLoadObservable as Observable<BaseTexture>;\r\n    if (onLoadObservable) {\r\n        return await new Promise((res) => onLoadObservable.addOnce(() => res()));\r\n    }\r\n\r\n    const onLoadedObservable = texture._texture?.onLoadedObservable;\r\n    if (onLoadedObservable) {\r\n        return await new Promise((res) => onLoadedObservable.addOnce(() => res()));\r\n    }\r\n\r\n    throw new Error(`Cannot determine readiness of texture ${texture.name}.`);\r\n}\r\n\r\n/**\r\n * Gets the data of the specified texture by rendering it to an intermediate RGBA texture and retrieving the bytes from it.\r\n * This is convienent to get 8-bit RGBA values for a texture in a GPU compressed format, which cannot be read using readPixels.\r\n * @internal\r\n */\r\nasync function ReadPixelsUsingRTT(texture: BaseTexture, width: number, height: number, face: number, lod: number, slice: number = 0): Promise<Uint8Array> {\r\n    const scene = texture.getScene()!;\r\n    const engine = scene.getEngine();\r\n    const sourceInternalTexture = texture.getInternalTexture();\r\n    const is3DTexture = texture.is3D || !!sourceInternalTexture?.is3D;\r\n\r\n    if (!engine.isWebGPU) {\r\n        if (is3DTexture) {\r\n            await import(\"../Shaders/lod3D.fragment\");\r\n        } else if (texture.isCube) {\r\n            await import(\"../Shaders/lodCube.fragment\");\r\n        } else {\r\n            await import(\"../Shaders/lod.fragment\");\r\n        }\r\n    } else {\r\n        if (is3DTexture) {\r\n            await import(\"../ShadersWGSL/lod3D.fragment\");\r\n        } else if (texture.isCube) {\r\n            await import(\"../ShadersWGSL/lodCube.fragment\");\r\n        } else {\r\n            await import(\"../ShadersWGSL/lod.fragment\");\r\n        }\r\n    }\r\n\r\n    let lodPostProcess: PostProcess;\r\n\r\n    if (is3DTexture) {\r\n        lodPostProcess = new PostProcess(\"lod3D\", \"lod3D\", {\r\n            uniforms: [\"lod\", \"gamma\", \"slice\"],\r\n            samplingMode: Texture.NEAREST_NEAREST_MIPNEAREST,\r\n            engine,\r\n            shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n    } else if (!texture.isCube) {\r\n        lodPostProcess = new PostProcess(\"lod\", \"lod\", {\r\n            uniforms: [\"lod\", \"gamma\"],\r\n            samplingMode: Texture.NEAREST_NEAREST_MIPNEAREST,\r\n            engine,\r\n            shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n    } else {\r\n        const faceDefines = [\"#define POSITIVEX\", \"#define NEGATIVEX\", \"#define POSITIVEY\", \"#define NEGATIVEY\", \"#define POSITIVEZ\", \"#define NEGATIVEZ\"];\r\n        lodPostProcess = new PostProcess(\"lodCube\", \"lodCube\", {\r\n            uniforms: [\"lod\", \"gamma\"],\r\n            samplingMode: Texture.NEAREST_NEAREST_MIPNEAREST,\r\n            engine,\r\n            defines: faceDefines[face],\r\n            shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n    }\r\n\r\n    await new Promise((resolve) => {\r\n        lodPostProcess.onEffectCreatedObservable.addOnce((e) => {\r\n            e.executeWhenCompiled(() => {\r\n                resolve(0);\r\n            });\r\n        });\r\n    });\r\n\r\n    const rtt = new RenderTargetTexture(\"temp\", { width: width, height: height }, scene, false);\r\n\r\n    lodPostProcess.onApply = function (effect) {\r\n        effect.setTexture(\"textureSampler\", texture);\r\n        effect.setFloat(\"lod\", lod);\r\n        effect.setInt(\"gamma\", texture.gammaSpace ? 1 : 0);\r\n        if (is3DTexture) {\r\n            effect.setFloat(\"slice\", slice);\r\n        }\r\n    };\r\n\r\n    try {\r\n        if (rtt.renderTarget && sourceInternalTexture) {\r\n            const samplingMode = sourceInternalTexture.samplingMode;\r\n            if (lod !== 0) {\r\n                texture.updateSamplingMode(Texture.NEAREST_NEAREST_MIPNEAREST);\r\n            } else {\r\n                texture.updateSamplingMode(Texture.NEAREST_NEAREST);\r\n            }\r\n\r\n            scene.postProcessManager.directRender([lodPostProcess], rtt.renderTarget, true);\r\n            texture.updateSamplingMode(samplingMode);\r\n\r\n            //Reading datas from WebGL\r\n            const bufferView = await engine.readPixels(0, 0, width, height);\r\n            const data = new Uint8Array(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);\r\n\r\n            // Unbind\r\n            engine.unBindFramebuffer(rtt.renderTarget);\r\n\r\n            return data;\r\n        } else {\r\n            throw Error(\"Render to texture failed.\");\r\n        }\r\n    } finally {\r\n        rtt.dispose();\r\n        lodPostProcess.dispose();\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the pixel data of the specified texture, either by reading it directly\r\n * or by rendering it to an intermediate RGBA texture and retrieving the bytes from it.\r\n * This is convenient to get 8-bit RGBA values for a texture in a GPU compressed format.\r\n * When direct readback returns non-RGBA channel layouts, the result is normalized to RGBA8.\r\n * @param texture the source texture\r\n * @param width the target width of the result, which does not have to match the source texture width\r\n * @param height the target height of the result, which does not have to match the source texture height\r\n * @param face if the texture has multiple faces, the face index to use for the source\r\n * @param lod if the texture has multiple LODs, the lod index to use for the source\r\n * @param forceRTT if true, forces the use of the RTT path for reading pixels (useful for cube maps to ensure correct orientation and gamma)\r\n * @param slice if the texture is 3D, the depth slice index to use for the source\r\n * @returns the 8-bit texture data\r\n */\r\nexport async function GetTextureDataAsync(\r\n    texture: BaseTexture,\r\n    width?: number,\r\n    height?: number,\r\n    face: number = 0,\r\n    lod: number = 0,\r\n    forceRTT: boolean = false,\r\n    slice: number = 0\r\n): Promise<Uint8Array> {\r\n    await WhenTextureReadyAsync(texture);\r\n    const internalTexture = texture.getInternalTexture();\r\n    const is3DTexture = texture.is3D || !!internalTexture?.is3D;\r\n\r\n    const { width: textureWidth, height: textureHeight } = texture.getSize();\r\n    const targetWidth = width ?? textureWidth;\r\n    const targetHeight = height ?? textureHeight;\r\n\r\n    // If the internal texture format is compressed, we cannot read the pixels directly.\r\n    // If we're resizing the texture, we need to use a render target texture.\r\n    // forceRTT can be used to ensure correct orientation and gamma for cube maps.\r\n    // 3D textures must also use RTT because direct readPixels does not expose slice selection.\r\n    if (forceRTT || is3DTexture || IsCompressedTextureFormat(texture.textureFormat) || targetWidth !== textureWidth || targetHeight !== textureHeight) {\r\n        if (texture.is2DArray) {\r\n            throw new Error(`Reading pixels from 2D array textures with ${forceRTT ? \"RTT\" : \"compression\"} is not supported.`);\r\n        }\r\n        return await ReadPixelsUsingRTT(texture, targetWidth, targetHeight, face, lod, slice);\r\n    }\r\n\r\n    let data = (await texture.readPixels(face, lod)) as Nullable<Uint8Array | Float32Array>;\r\n    if (!data) {\r\n        throw new Error(`Failed to read pixels from texture ${texture.name}.`);\r\n    }\r\n\r\n    // Convert float RGBA values to uint8, if necessary.\r\n    if (data instanceof Float32Array) {\r\n        const data2 = new Uint8Array(data.length);\r\n        let n = data.length;\r\n        while (n--) {\r\n            const v = data[n];\r\n            data2[n] = Math.round(Clamp(v) * 255);\r\n        }\r\n        data = data2;\r\n    }\r\n\r\n    // Some backends (notably WebGPU for single/dual/triple channel formats) can return\r\n    // readback data that is not RGBA8. The inspector preview pipeline expects 4 bytes\r\n    // per pixel, so normalize to RGBA here when needed.\r\n    const pixelCount = targetWidth * targetHeight;\r\n    const expectedLength = pixelCount * 4;\r\n\r\n    if (data.length !== expectedLength) {\r\n        const componentCount = pixelCount === 0 ? 0 : data.length / pixelCount;\r\n\r\n        if (componentCount === 1 || componentCount === 2 || componentCount === 3) {\r\n            const normalizedData = new Uint8Array(expectedLength);\r\n\r\n            for (let pixel = 0, src = 0, dst = 0; pixel < pixelCount; pixel++, dst += 4) {\r\n                const c0 = data[src++];\r\n\r\n                if (componentCount === 1) {\r\n                    // Luminance/R-style data: replicate to RGB and use opaque alpha.\r\n                    normalizedData[dst] = c0;\r\n                    normalizedData[dst + 1] = c0;\r\n                    normalizedData[dst + 2] = c0;\r\n                    normalizedData[dst + 3] = 255;\r\n                    continue;\r\n                }\r\n\r\n                const c1 = data[src++];\r\n                if (componentCount === 2) {\r\n                    // Two-channel data has no standard blue/alpha semantics for preview,\r\n                    // so preserve R/G, clear B, and force opaque alpha.\r\n                    normalizedData[dst] = c0;\r\n                    normalizedData[dst + 1] = c1;\r\n                    normalizedData[dst + 2] = 0;\r\n                    normalizedData[dst + 3] = 255;\r\n                    continue;\r\n                }\r\n\r\n                // RGB data: append an opaque alpha channel.\r\n                normalizedData[dst] = c0;\r\n                normalizedData[dst + 1] = c1;\r\n                normalizedData[dst + 2] = data[src++];\r\n                normalizedData[dst + 3] = 255;\r\n            }\r\n\r\n            return normalizedData;\r\n        }\r\n    }\r\n\r\n    return data;\r\n}\r\n\r\n/**\r\n * Class used to host texture specific utilities\r\n */\r\nexport const TextureTools = {\r\n    /**\r\n     * Uses the GPU to create a copy texture rescaled at a given size\r\n     * @param texture Texture to copy from\r\n     * @param width defines the desired width\r\n     * @param height defines the desired height\r\n     * @param useBilinearMode defines if bilinear mode has to be used\r\n     * @returns the generated texture\r\n     */\r\n    CreateResizedCopy,\r\n\r\n    /**\r\n     * Apply a post process to a texture\r\n     * @param postProcessName name of the fragment post process\r\n     * @param internalTexture the texture to encode\r\n     * @param scene the scene hosting the texture\r\n     * @param type type of the output texture. If not provided, use the one from internalTexture\r\n     * @param samplingMode sampling mode to use to sample the source texture. If not provided, use the one from internalTexture\r\n     * @param format format of the output texture. If not provided, use the one from internalTexture\r\n     * @returns a promise with the internalTexture having its texture replaced by the result of the processing\r\n     */\r\n    ApplyPostProcess,\r\n    /**\r\n     * Converts a number to half float\r\n     * @param value number to convert\r\n     * @returns converted number\r\n     */\r\n    ToHalfFloat,\r\n\r\n    /**\r\n     * Converts a half float to a number\r\n     * @param value half float to convert\r\n     * @returns converted half float\r\n     */\r\n    FromHalfFloat,\r\n\r\n    /**\r\n     * Gets the data of the specified texture by rendering it to an intermediate RGBA texture and retrieving the bytes from it.\r\n     * This is convienent to get 8-bit RGBA values for a texture in a GPU compressed format.\r\n     * @param texture the source texture\r\n     * @param width the width of the result, which does not have to match the source texture width\r\n     * @param height the height of the result, which does not have to match the source texture height\r\n     * @param face if the texture has multiple faces, the face index to use for the source\r\n     * @param lod if the texture has multiple LODs, the lod index to use for the source\r\n     * @returns the 8-bit texture data\r\n     */\r\n    GetTextureDataAsync,\r\n};\r\n","import { type AnimationRange } from \"../Animations/animationRange\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { EncodeArrayBufferToBase64, DecodeBase64ToBinary } from \"../Misc/stringTools\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Skeleton } from \"core/Bones/skeleton\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { ToHalfFloat } from \"../Misc/textureTools\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\n/**\r\n * Class to bake vertex animation textures.\r\n * @since 5.0\r\n */\r\nexport class VertexAnimationBaker {\r\n    private _scene: Scene;\r\n    private _mesh: Nullable<Mesh>;\r\n    private _skeleton: Nullable<Skeleton>;\r\n\r\n    /**\r\n     * Create a new VertexAnimationBaker object which can help baking animations into a texture.\r\n     * @param scene Defines the scene the VAT belongs to\r\n     * @param meshOrSkeleton Defines the skeleton or the mesh from which to retrieve the skeleton from.\r\n     */\r\n    constructor(scene: Scene, meshOrSkeleton: Mesh | Skeleton) {\r\n        this._scene = scene;\r\n        if (meshOrSkeleton instanceof Skeleton) {\r\n            this._skeleton = meshOrSkeleton;\r\n            this._mesh = null;\r\n        } else {\r\n            this._mesh = meshOrSkeleton;\r\n            this._skeleton = meshOrSkeleton.skeleton;\r\n        }\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @param ranges Defines the ranges in the animation that will be baked.\r\n     * @param halfFloat If true, the vertex data will be returned as half-float (Uint16Array), otherwise as full float (Float32Array).\r\n     * @returns The array of matrix transforms for each vertex (columns) and frame (rows), as a Float32Array or Uint16Array.\r\n     */\r\n    public bakeVertexDataSync(ranges: AnimationRange[], halfFloat: boolean): Float32Array | Uint16Array {\r\n        if (!this._skeleton) {\r\n            throw new Error(\"No skeleton provided.\");\r\n        }\r\n        const bones = this._skeleton.bones.length;\r\n        const floatsPerFrame = (bones + 1) * 16;\r\n        const totalFrames = ranges.reduce((sum, r) => sum + (Math.floor(r.to) - Math.floor(r.from) + 1), 0);\r\n\r\n        const vertexData = halfFloat ? new Uint16Array(floatsPerFrame * totalFrames) : new Float32Array(floatsPerFrame * totalFrames);\r\n\r\n        let frameIdx = 0;\r\n\r\n        this._skeleton.returnToRest();\r\n\r\n        for (const range of ranges) {\r\n            for (let f = Math.floor(range.from); f <= Math.floor(range.to); f++) {\r\n                this._scene.beginAnimation(this._skeleton, f, f, false, 1.0);\r\n                this._scene.render();\r\n                this._skeleton.computeAbsoluteMatrices(true);\r\n                const matrices = this._skeleton.getTransformMatrices(this._mesh);\r\n                const base = frameIdx * floatsPerFrame;\r\n                if (halfFloat) {\r\n                    matrices.forEach((val, i) => {\r\n                        vertexData[base + i] = ToHalfFloat(val);\r\n                    });\r\n                } else {\r\n                    matrices.forEach((val, i) => {\r\n                        vertexData[base + i] = val;\r\n                    });\r\n                }\r\n                frameIdx++;\r\n            }\r\n        }\r\n\r\n        return vertexData;\r\n    }\r\n\r\n    /**\r\n     * Bakes the animation into the texture. This should be called once, when the\r\n     * scene starts, so the VAT is generated and associated to the mesh.\r\n     * @param ranges Defines the ranges in the animation that will be baked.\r\n     * @returns The array of matrix transforms for each vertex (columns) and frame (rows), as a Float32Array.\r\n     */\r\n    // async function, without Async suffix, to avoid breaking the API\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async bakeVertexData(ranges: AnimationRange[]): Promise<Float32Array> {\r\n        if (!this._skeleton) {\r\n            throw new Error(\"No skeleton provided.\");\r\n        }\r\n        const boneCount = this._skeleton.bones.length;\r\n\r\n        /** total number of frames in our animations */\r\n        const frameCount = ranges.reduce((previous: number, current: AnimationRange) => previous + current.to - current.from + 1, 0);\r\n\r\n        if (isNaN(frameCount)) {\r\n            throw new Error(\"Invalid animation ranges.\");\r\n        }\r\n\r\n        // reset our loop data\r\n        let textureIndex = 0;\r\n        const textureSize = (boneCount + 1) * 4 * 4 * frameCount;\r\n        const vertexData = new Float32Array(textureSize);\r\n        this._scene.stopAnimation(this._skeleton);\r\n        this._skeleton.returnToRest();\r\n\r\n        // render all frames from our slices\r\n        for (const range of ranges) {\r\n            for (let frameIndex = range.from; frameIndex <= range.to; frameIndex++) {\r\n                // eslint-disable-next-line no-await-in-loop\r\n                await this._executeAnimationFrameAsync(vertexData, frameIndex, textureIndex++);\r\n            }\r\n        }\r\n\r\n        return vertexData;\r\n    }\r\n\r\n    /**\r\n     * Runs an animation frame and stores its vertex data\r\n     *\r\n     * @param vertexData The array to save data to.\r\n     * @param frameIndex Current frame in the skeleton animation to render.\r\n     * @param textureIndex Current index of the texture data.\r\n     * @returns A promise that resolves when the animation frame is done.\r\n     */\r\n    private async _executeAnimationFrameAsync(vertexData: Float32Array, frameIndex: number, textureIndex: number): Promise<void> {\r\n        return await new Promise<void>((resolve, _reject) => {\r\n            this._scene.beginAnimation(this._skeleton, frameIndex, frameIndex, false, 1.0, () => {\r\n                // generate matrices\r\n                const skeletonMatrices = this._skeleton!.getTransformMatrices(this._mesh);\r\n                vertexData.set(skeletonMatrices, textureIndex * skeletonMatrices.length);\r\n\r\n                resolve();\r\n            });\r\n        });\r\n    }\r\n    /**\r\n     * Builds a vertex animation texture given the vertexData in an array.\r\n     * @param vertexData The vertex animation data. You can generate it with bakeVertexData(). You can pass in a Float32Array to return a full precision texture, or a Uint16Array to return a half-float texture.\r\n     * If you pass in a Uint16Array, make sure your device supports half-float textures\r\n     * @returns The vertex animation texture to be used with BakedVertexAnimationManager.\r\n     */\r\n    public textureFromBakedVertexData(vertexData: Float32Array | Uint16Array): RawTexture {\r\n        if (!this._skeleton) {\r\n            throw new Error(\"No skeleton provided.\");\r\n        }\r\n        const boneCount = this._skeleton.bones.length;\r\n\r\n        if (vertexData instanceof Uint16Array) {\r\n            if (!this._scene.getEngine().getCaps().textureHalfFloatRender) {\r\n                Logger.Warn(\"VertexAnimationBaker: Half-float textures are not supported on this device\");\r\n            }\r\n        }\r\n\r\n        const texture = RawTexture.CreateRGBATexture(\r\n            vertexData,\r\n            (boneCount + 1) * 4,\r\n            vertexData.length / ((boneCount + 1) * 4 * 4),\r\n            this._scene,\r\n            false,\r\n            false,\r\n            Texture.NEAREST_NEAREST,\r\n            vertexData instanceof Float32Array ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_HALF_FLOAT\r\n        );\r\n        texture.name = \"VAT\" + this._skeleton.name;\r\n        return texture;\r\n    }\r\n    /**\r\n     * Serializes our vertexData to an object, with a nice string for the vertexData.\r\n     * @param vertexData The vertex array data.\r\n     * @returns This object serialized to a JS dict.\r\n     */\r\n    public serializeBakedVertexDataToObject(vertexData: Float32Array): Record<string, any> {\r\n        if (!this._skeleton) {\r\n            throw new Error(\"No skeleton provided.\");\r\n        }\r\n\r\n        // this converts the float array to a serialized base64 string, ~1.3x larger\r\n        // than the original.\r\n        const boneCount = this._skeleton.bones.length;\r\n        const width = (boneCount + 1) * 4;\r\n        const height = vertexData.length / ((boneCount + 1) * 4 * 4);\r\n        const data = {\r\n            vertexData: EncodeArrayBufferToBase64(vertexData),\r\n            width,\r\n            height,\r\n        };\r\n        return data;\r\n    }\r\n    /**\r\n     * Loads previously baked data.\r\n     * @param data The object as serialized by serializeBakedVertexDataToObject()\r\n     * @returns The array of matrix transforms for each vertex (columns) and frame (rows), as a Float32Array.\r\n     */\r\n    public loadBakedVertexDataFromObject(data: Record<string, any>): Float32Array {\r\n        return new Float32Array(DecodeBase64ToBinary(data.vertexData));\r\n    }\r\n    /**\r\n     * Serializes our vertexData to a JSON string, with a nice string for the vertexData.\r\n     * Should be called right after bakeVertexData().\r\n     * @param vertexData The vertex array data.\r\n     * @returns This object serialized to a safe string.\r\n     */\r\n    public serializeBakedVertexDataToJSON(vertexData: Float32Array): string {\r\n        return JSON.stringify(this.serializeBakedVertexDataToObject(vertexData));\r\n    }\r\n    /**\r\n     * Loads previously baked data in string format.\r\n     * @param json The json string as serialized by serializeBakedVertexDataToJSON().\r\n     * @returns The array of matrix transforms for each vertex (columns) and frame (rows), as a Float32Array.\r\n     */\r\n    public loadBakedVertexDataFromJSON(json: string): Float32Array {\r\n        return this.loadBakedVertexDataFromObject(JSON.parse(json));\r\n    }\r\n}\r\n","import { type Behavior } from \"../../Behaviors/behavior\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type PointerInfoPre, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { PrecisionDate } from \"../../Misc/precisionDate\";\r\nimport { Epsilon } from \"../../Maths/math.constants\";\r\n\r\n/**\r\n * The autoRotation behavior (AutoRotationBehavior) is designed to create a smooth rotation of an ArcRotateCamera when there is no user interaction.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#autorotation-behavior\r\n */\r\nexport class AutoRotationBehavior implements Behavior<ArcRotateCamera> {\r\n    /**\r\n     * Gets the name of the behavior.\r\n     */\r\n    public get name(): string {\r\n        return \"AutoRotation\";\r\n    }\r\n\r\n    private _zoomStopsAnimation = false;\r\n    private _idleRotationSpeed = 0.05;\r\n    private _idleRotationWaitTime = 2000;\r\n    private _idleRotationSpinupTime = 2000;\r\n\r\n    /**\r\n     * Target alpha\r\n     */\r\n    public targetAlpha: Nullable<number> = null;\r\n\r\n    /**\r\n     * Sets the flag that indicates if user zooming should stop animation.\r\n     */\r\n    public set zoomStopsAnimation(flag: boolean) {\r\n        this._zoomStopsAnimation = flag;\r\n    }\r\n\r\n    /**\r\n     * Gets the flag that indicates if user zooming should stop animation.\r\n     */\r\n    public get zoomStopsAnimation(): boolean {\r\n        return this._zoomStopsAnimation;\r\n    }\r\n\r\n    /**\r\n     * Sets the default speed at which the camera rotates around the model.\r\n     */\r\n    public set idleRotationSpeed(speed: number) {\r\n        this._idleRotationSpeed = speed;\r\n    }\r\n\r\n    /**\r\n     * Gets the default speed at which the camera rotates around the model.\r\n     */\r\n    public get idleRotationSpeed() {\r\n        return this._idleRotationSpeed;\r\n    }\r\n\r\n    /**\r\n     * Sets the time (in milliseconds) to wait after user interaction before the camera starts rotating.\r\n     */\r\n    public set idleRotationWaitTime(time: number) {\r\n        this._idleRotationWaitTime = time;\r\n    }\r\n\r\n    /**\r\n     * Gets the time (milliseconds) to wait after user interaction before the camera starts rotating.\r\n     */\r\n    public get idleRotationWaitTime() {\r\n        return this._idleRotationWaitTime;\r\n    }\r\n\r\n    /**\r\n     * Sets the time (milliseconds) to take to spin up to the full idle rotation speed.\r\n     */\r\n    public set idleRotationSpinupTime(time: number) {\r\n        this._idleRotationSpinupTime = time;\r\n    }\r\n\r\n    /**\r\n     * Gets the time (milliseconds) to take to spin up to the full idle rotation speed.\r\n     */\r\n    public get idleRotationSpinupTime() {\r\n        return this._idleRotationSpinupTime;\r\n    }\r\n\r\n    /**\r\n     * Gets a value indicating if the camera is currently rotating because of this behavior\r\n     */\r\n    public get rotationInProgress(): boolean {\r\n        return Math.abs(this._cameraRotationSpeed) > 0;\r\n    }\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<ArcRotateCamera> {\r\n        return this._attachedCamera;\r\n    }\r\n\r\n    // Default behavior functions\r\n    private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;\r\n    private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;\r\n    private _attachedCamera: Nullable<ArcRotateCamera> = null;\r\n    private _isPointerDown = false;\r\n    private _lastFrameTime: Nullable<number> = null;\r\n    private _lastInteractionTime = -Infinity;\r\n    private _cameraRotationSpeed: number = 0;\r\n\r\n    /**\r\n     * Initializes the behavior.\r\n     */\r\n    public init(): void {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Attaches the behavior to its arc rotate camera.\r\n     * @param camera Defines the camera to attach the behavior to\r\n     */\r\n    public attach(camera: ArcRotateCamera): void {\r\n        this._attachedCamera = camera;\r\n        const scene = this._attachedCamera.getScene();\r\n\r\n        this._onPrePointerObservableObserver = scene.onPrePointerObservable.add((pointerInfoPre) => {\r\n            if (pointerInfoPre.type === PointerEventTypes.POINTERDOWN) {\r\n                this._isPointerDown = true;\r\n                return;\r\n            }\r\n\r\n            if (pointerInfoPre.type === PointerEventTypes.POINTERUP) {\r\n                this._isPointerDown = false;\r\n            }\r\n        });\r\n\r\n        this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(() => {\r\n            if (this._reachTargetAlpha()) {\r\n                return;\r\n            }\r\n            const now = PrecisionDate.Now;\r\n            let dt = 0;\r\n            if (this._lastFrameTime != null) {\r\n                dt = now - this._lastFrameTime;\r\n            }\r\n            this._lastFrameTime = now;\r\n\r\n            // Stop the animation if there is user interaction and the animation should stop for this interaction\r\n            this._applyUserInteraction();\r\n\r\n            const timeToRotation = now - this._lastInteractionTime - this._idleRotationWaitTime;\r\n            const scale = Math.max(Math.min(timeToRotation / this._idleRotationSpinupTime, 1), 0);\r\n            this._cameraRotationSpeed = this._idleRotationSpeed * scale;\r\n\r\n            // Step camera rotation by rotation speed\r\n            if (this._attachedCamera) {\r\n                this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from its current arc rotate camera.\r\n     */\r\n    public detach(): void {\r\n        if (!this._attachedCamera) {\r\n            return;\r\n        }\r\n        const scene = this._attachedCamera.getScene();\r\n\r\n        if (this._onPrePointerObservableObserver) {\r\n            scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);\r\n        }\r\n\r\n        this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);\r\n        this._attachedCamera = null;\r\n        this._lastFrameTime = null;\r\n    }\r\n\r\n    /**\r\n     * Force-reset the last interaction time\r\n     * @param customTime an optional time that will be used instead of the current last interaction time. For example `Date.now()`\r\n     */\r\n    public resetLastInteractionTime(customTime?: number): void {\r\n        this._lastInteractionTime = customTime ?? PrecisionDate.Now;\r\n    }\r\n\r\n    /**\r\n     * Returns true if camera alpha reaches the target alpha\r\n     * @returns true if camera alpha reaches the target alpha\r\n     */\r\n    private _reachTargetAlpha(): boolean {\r\n        if (this._attachedCamera && this.targetAlpha !== null) {\r\n            return Math.abs(this._attachedCamera.alpha - this.targetAlpha) < Epsilon;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns true if user is scrolling.\r\n     * @returns true if user is scrolling.\r\n     */\r\n    private _userIsZooming(): boolean {\r\n        if (!this._attachedCamera) {\r\n            return false;\r\n        }\r\n        return this._attachedCamera.inertialRadiusOffset !== 0;\r\n    }\r\n\r\n    private _lastFrameRadius = 0;\r\n    private _shouldAnimationStopForInteraction(): boolean {\r\n        if (!this._attachedCamera) {\r\n            return false;\r\n        }\r\n\r\n        let zoomHasHitLimit = false;\r\n        if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {\r\n            zoomHasHitLimit = true;\r\n        }\r\n\r\n        // Update the record of previous radius - works as an approx. indicator of hitting radius limits\r\n        this._lastFrameRadius = this._attachedCamera.radius;\r\n        return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();\r\n    }\r\n\r\n    /**\r\n     *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.\r\n     */\r\n    private _applyUserInteraction(): void {\r\n        if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {\r\n            this._lastInteractionTime = PrecisionDate.Now;\r\n        }\r\n    }\r\n\r\n    // Tools\r\n    private _userIsMoving(): boolean {\r\n        if (!this._attachedCamera) {\r\n            return false;\r\n        }\r\n\r\n        return (\r\n            this._attachedCamera.inertialAlphaOffset !== 0 ||\r\n            this._attachedCamera.inertialBetaOffset !== 0 ||\r\n            this._attachedCamera.inertialRadiusOffset !== 0 ||\r\n            this._attachedCamera.inertialPanningX !== 0 ||\r\n            this._attachedCamera.inertialPanningY !== 0 ||\r\n            this._isPointerDown\r\n        );\r\n    }\r\n}\r\n","import { type Behavior } from \"../../Behaviors/behavior\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { BackEase, EasingFunction } from \"../../Animations/easing\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type Animatable } from \"../../Animations/animatable.core\";\r\nimport { Animation } from \"../../Animations/animation.pure\";\r\n\r\n/**\r\n * Add a bouncing effect to an ArcRotateCamera when reaching a specified minimum and maximum radius\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#bouncing-behavior\r\n */\r\nexport class BouncingBehavior implements Behavior<ArcRotateCamera> {\r\n    /**\r\n     * Gets the name of the behavior.\r\n     */\r\n    public get name(): string {\r\n        return \"Bouncing\";\r\n    }\r\n\r\n    /**\r\n     * The easing function used by animations\r\n     */\r\n    public static EasingFunction = new BackEase(0.3);\r\n\r\n    /**\r\n     * The easing mode used by animations\r\n     */\r\n    public static EasingMode = EasingFunction.EASINGMODE_EASEOUT;\r\n\r\n    /**\r\n     * The duration of the animation, in milliseconds\r\n     */\r\n    public transitionDuration = 450;\r\n\r\n    /**\r\n     * Length of the distance animated by the transition when lower radius is reached\r\n     */\r\n    public lowerRadiusTransitionRange = 2;\r\n\r\n    /**\r\n     * Length of the distance animated by the transition when upper radius is reached\r\n     */\r\n    public upperRadiusTransitionRange = -2;\r\n\r\n    private _autoTransitionRange = false;\r\n\r\n    /**\r\n     * Gets a value indicating if the lowerRadiusTransitionRange and upperRadiusTransitionRange are defined automatically\r\n     */\r\n    public get autoTransitionRange(): boolean {\r\n        return this._autoTransitionRange;\r\n    }\r\n\r\n    /**\r\n     * Sets a value indicating if the lowerRadiusTransitionRange and upperRadiusTransitionRange are defined automatically\r\n     * Transition ranges will be set to 5% of the bounding box diagonal in world space\r\n     */\r\n    public set autoTransitionRange(value: boolean) {\r\n        if (this._autoTransitionRange === value) {\r\n            return;\r\n        }\r\n\r\n        this._autoTransitionRange = value;\r\n\r\n        const camera = this._attachedCamera;\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add((transformNode) => {\r\n                if (!transformNode) {\r\n                    return;\r\n                }\r\n\r\n                transformNode.computeWorldMatrix(true);\r\n                if ((transformNode as AbstractMesh).getBoundingInfo) {\r\n                    const diagonal = (transformNode as AbstractMesh).getBoundingInfo().diagonalLength;\r\n\r\n                    this.lowerRadiusTransitionRange = diagonal * 0.05;\r\n                    this.upperRadiusTransitionRange = diagonal * 0.05;\r\n                }\r\n            });\r\n        } else if (this._onMeshTargetChangedObserver) {\r\n            camera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<ArcRotateCamera> {\r\n        return this._attachedCamera;\r\n    }\r\n\r\n    // Connection\r\n    private _attachedCamera: Nullable<ArcRotateCamera> = null;\r\n    private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;\r\n    private _onMeshTargetChangedObserver: Nullable<Observer<Nullable<TransformNode>>>;\r\n\r\n    /**\r\n     * Initializes the behavior.\r\n     */\r\n    public init(): void {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Attaches the behavior to its arc rotate camera.\r\n     * @param camera Defines the camera to attach the behavior to\r\n     */\r\n    public attach(camera: ArcRotateCamera): void {\r\n        this._attachedCamera = camera;\r\n        this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(() => {\r\n            if (!this._attachedCamera) {\r\n                return;\r\n            }\r\n\r\n            // Add the bounce animation to the lower radius limit\r\n            if (this._isRadiusAtLimit(this._attachedCamera.lowerRadiusLimit)) {\r\n                this._applyBoundRadiusAnimation(this.lowerRadiusTransitionRange);\r\n            }\r\n\r\n            // Add the bounce animation to the upper radius limit\r\n            if (this._isRadiusAtLimit(this._attachedCamera.upperRadiusLimit)) {\r\n                this._applyBoundRadiusAnimation(this.upperRadiusTransitionRange);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from its current arc rotate camera.\r\n     */\r\n    public detach(): void {\r\n        if (!this._attachedCamera) {\r\n            return;\r\n        }\r\n        if (this._onAfterCheckInputsObserver) {\r\n            this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);\r\n        }\r\n        if (this._onMeshTargetChangedObserver) {\r\n            this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);\r\n        }\r\n        this._attachedCamera = null;\r\n    }\r\n\r\n    // Animations\r\n    private _radiusIsAnimating: boolean = false;\r\n    private _radiusBounceTransition: Nullable<Animation> = null;\r\n    private _animatables = new Array<Animatable>();\r\n    private _cachedWheelPrecision: number;\r\n\r\n    /**\r\n     * Checks if the camera radius is at the specified limit. Takes into account animation locks.\r\n     * @param radiusLimit The limit to check against.\r\n     * @returns Bool to indicate if at limit.\r\n     */\r\n    private _isRadiusAtLimit(radiusLimit: Nullable<number>): boolean {\r\n        if (!this._attachedCamera) {\r\n            return false;\r\n        }\r\n\r\n        if (this._attachedCamera.radius === radiusLimit && !this._radiusIsAnimating) {\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Applies an animation to the radius of the camera, extending by the radiusDelta.\r\n     * @param radiusDelta The delta by which to animate to. Can be negative.\r\n     */\r\n    private _applyBoundRadiusAnimation(radiusDelta: number): void {\r\n        if (!this._attachedCamera) {\r\n            return;\r\n        }\r\n\r\n        if (!this._radiusBounceTransition) {\r\n            BouncingBehavior.EasingFunction.setEasingMode(BouncingBehavior.EasingMode);\r\n            this._radiusBounceTransition = Animation.CreateAnimation(\"radius\", Animation.ANIMATIONTYPE_FLOAT, 60, BouncingBehavior.EasingFunction);\r\n        }\r\n        // Prevent zoom until bounce has completed\r\n        this._cachedWheelPrecision = this._attachedCamera.wheelPrecision;\r\n        this._attachedCamera.wheelPrecision = Infinity;\r\n        this._attachedCamera.inertialRadiusOffset = 0;\r\n\r\n        // Animate to the radius limit\r\n        this.stopAllAnimations();\r\n        this._radiusIsAnimating = true;\r\n        const animatable = Animation.TransitionTo(\r\n            \"radius\",\r\n            this._attachedCamera.radius + radiusDelta,\r\n            this._attachedCamera,\r\n            this._attachedCamera.getScene(),\r\n            60,\r\n            this._radiusBounceTransition,\r\n            this.transitionDuration,\r\n            () => this._clearAnimationLocks()\r\n        );\r\n\r\n        if (animatable) {\r\n            this._animatables.push(animatable);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all animation locks. Allows new animations to be added to any of the camera properties.\r\n     */\r\n    protected _clearAnimationLocks(): void {\r\n        this._radiusIsAnimating = false;\r\n\r\n        if (this._attachedCamera) {\r\n            this._attachedCamera.wheelPrecision = this._cachedWheelPrecision;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stops and removes all animations that have been applied to the camera\r\n     */\r\n    public stopAllAnimations(): void {\r\n        if (this._attachedCamera) {\r\n            this._attachedCamera.animations = [];\r\n        }\r\n        while (this._animatables.length) {\r\n            this._animatables[0].onAnimationEnd = null;\r\n            this._animatables[0].stop();\r\n            this._animatables.shift();\r\n        }\r\n    }\r\n}\r\n","import { type Behavior } from \"../../Behaviors/behavior\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { ExponentialEase, EasingFunction } from \"../../Animations/easing\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type PointerInfoPre, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { PrecisionDate } from \"../../Misc/precisionDate\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Animatable } from \"../../Animations/animatable.core\";\r\nimport { Animation } from \"../../Animations/animation.pure\";\r\n\r\n/**\r\n * The framing behavior (FramingBehavior) is designed to automatically position an ArcRotateCamera when its target is set to a mesh. It is also useful if you want to prevent the camera to go under a virtual horizontal plane.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#framing-behavior\r\n */\r\nexport class FramingBehavior implements Behavior<ArcRotateCamera> {\r\n    /**\r\n     * Gets the name of the behavior.\r\n     */\r\n    public get name(): string {\r\n        return \"Framing\";\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the animation to zoom on target mesh has ended\r\n     */\r\n    public onTargetFramingAnimationEndObservable = new Observable<void>();\r\n\r\n    private _mode = FramingBehavior.FitFrustumSidesMode;\r\n    private _radiusScale = 1.0;\r\n    private _positionScale = 0.5;\r\n    private _defaultElevation = 0.3;\r\n    private _elevationReturnTime = 1500;\r\n    private _elevationReturnWaitTime = 1000;\r\n    private _zoomStopsAnimation = false;\r\n    private _framingTime = 1500;\r\n\r\n    /**\r\n     * The easing function used by animations\r\n     */\r\n    public static EasingFunction = new ExponentialEase();\r\n\r\n    /**\r\n     * The easing mode used by animations\r\n     */\r\n    public static EasingMode = EasingFunction.EASINGMODE_EASEINOUT;\r\n\r\n    /**\r\n     * Sets the current mode used by the behavior\r\n     */\r\n    public set mode(mode: number) {\r\n        this._mode = mode;\r\n    }\r\n\r\n    /**\r\n     * Gets current mode used by the behavior.\r\n     */\r\n    public get mode(): number {\r\n        return this._mode;\r\n    }\r\n\r\n    /**\r\n     * Sets the scale applied to the radius (1 by default)\r\n     */\r\n    public set radiusScale(radius: number) {\r\n        this._radiusScale = radius;\r\n    }\r\n\r\n    /**\r\n     * Gets the scale applied to the radius\r\n     */\r\n    public get radiusScale(): number {\r\n        return this._radiusScale;\r\n    }\r\n\r\n    /**\r\n     * Sets the scale to apply on Y axis to position camera focus. 0.5 by default which means the center of the bounding box.\r\n     */\r\n    public set positionScale(scale: number) {\r\n        this._positionScale = scale;\r\n    }\r\n\r\n    /**\r\n     * Gets the scale to apply on Y axis to position camera focus. 0.5 by default which means the center of the bounding box.\r\n     */\r\n    public get positionScale(): number {\r\n        return this._positionScale;\r\n    }\r\n\r\n    /**\r\n     * Sets the angle above/below the horizontal plane to return to when the return to default elevation idle\r\n     * behaviour is triggered, in radians.\r\n     */\r\n    public set defaultElevation(elevation: number) {\r\n        this._defaultElevation = elevation;\r\n    }\r\n\r\n    /**\r\n     * Gets the angle above/below the horizontal plane to return to when the return to default elevation idle\r\n     * behaviour is triggered, in radians.\r\n     */\r\n    public get defaultElevation() {\r\n        return this._defaultElevation;\r\n    }\r\n\r\n    /**\r\n     * Sets the time (in milliseconds) taken to return to the default beta position.\r\n     * Negative value indicates camera should not return to default.\r\n     */\r\n    public set elevationReturnTime(speed: number) {\r\n        this._elevationReturnTime = speed;\r\n    }\r\n\r\n    /**\r\n     * Gets the time (in milliseconds) taken to return to the default beta position.\r\n     * Negative value indicates camera should not return to default.\r\n     */\r\n    public get elevationReturnTime(): number {\r\n        return this._elevationReturnTime;\r\n    }\r\n\r\n    /**\r\n     * Sets the delay (in milliseconds) taken before the camera returns to the default beta position.\r\n     */\r\n    public set elevationReturnWaitTime(time: number) {\r\n        this._elevationReturnWaitTime = time;\r\n    }\r\n\r\n    /**\r\n     * Gets the delay (in milliseconds) taken before the camera returns to the default beta position.\r\n     */\r\n    public get elevationReturnWaitTime(): number {\r\n        return this._elevationReturnWaitTime;\r\n    }\r\n\r\n    /**\r\n     * Sets the flag that indicates if user zooming should stop animation.\r\n     */\r\n    public set zoomStopsAnimation(flag: boolean) {\r\n        this._zoomStopsAnimation = flag;\r\n    }\r\n\r\n    /**\r\n     * Gets the flag that indicates if user zooming should stop animation.\r\n     */\r\n    public get zoomStopsAnimation(): boolean {\r\n        return this._zoomStopsAnimation;\r\n    }\r\n\r\n    /**\r\n     * Sets the transition time when framing the mesh, in milliseconds\r\n     */\r\n    public set framingTime(time: number) {\r\n        this._framingTime = time;\r\n    }\r\n\r\n    /**\r\n     * Gets the transition time when framing the mesh, in milliseconds\r\n     */\r\n    public get framingTime() {\r\n        return this._framingTime;\r\n    }\r\n\r\n    /**\r\n     * Define if the behavior should automatically change the configured\r\n     * camera limits and sensibilities.\r\n     */\r\n    public autoCorrectCameraLimitsAndSensibility = true;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<ArcRotateCamera> {\r\n        return this._attachedCamera;\r\n    }\r\n\r\n    // Default behavior functions\r\n    private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;\r\n    private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;\r\n    private _onMeshTargetChangedObserver: Nullable<Observer<Nullable<TransformNode>>>;\r\n    private _attachedCamera: Nullable<ArcRotateCamera> = null;\r\n    private _isPointerDown = false;\r\n    private _lastInteractionTime = -Infinity;\r\n\r\n    /**\r\n     * Initializes the behavior.\r\n     */\r\n    public init(): void {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Attaches the behavior to its arc rotate camera.\r\n     * @param camera Defines the camera to attach the behavior to\r\n     */\r\n    public attach(camera: ArcRotateCamera): void {\r\n        this._attachedCamera = camera;\r\n        const scene = this._attachedCamera.getScene();\r\n\r\n        FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);\r\n\r\n        this._onPrePointerObservableObserver = scene.onPrePointerObservable.add((pointerInfoPre) => {\r\n            if (pointerInfoPre.type === PointerEventTypes.POINTERDOWN) {\r\n                this._isPointerDown = true;\r\n                return;\r\n            }\r\n\r\n            if (pointerInfoPre.type === PointerEventTypes.POINTERUP) {\r\n                this._isPointerDown = false;\r\n            }\r\n        });\r\n\r\n        this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add((transformNode) => {\r\n            if (transformNode && (transformNode as AbstractMesh).getBoundingInfo) {\r\n                this.zoomOnMesh(transformNode as AbstractMesh, undefined, () => {\r\n                    this.onTargetFramingAnimationEndObservable.notifyObservers();\r\n                });\r\n            }\r\n        });\r\n\r\n        this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(() => {\r\n            // Stop the animation if there is user interaction and the animation should stop for this interaction\r\n            this._applyUserInteraction();\r\n\r\n            // Maintain the camera above the ground. If the user pulls the camera beneath the ground plane, lift it\r\n            // back to the default position after a given timeout\r\n            this._maintainCameraAboveGround();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from its current arc rotate camera.\r\n     */\r\n    public detach(): void {\r\n        if (!this._attachedCamera) {\r\n            return;\r\n        }\r\n\r\n        const scene = this._attachedCamera.getScene();\r\n\r\n        if (this._onPrePointerObservableObserver) {\r\n            scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);\r\n        }\r\n\r\n        if (this._onAfterCheckInputsObserver) {\r\n            this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);\r\n        }\r\n\r\n        if (this._onMeshTargetChangedObserver) {\r\n            this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);\r\n        }\r\n\r\n        this._attachedCamera = null;\r\n    }\r\n\r\n    // Framing control\r\n    private _animatables = new Array<Animatable>();\r\n    private _betaIsAnimating = false;\r\n    private _betaTransition: Animation;\r\n    private _radiusTransition: Animation;\r\n    private _vectorTransition: Animation;\r\n\r\n    /**\r\n     * Targets the given mesh and updates zoom level accordingly.\r\n     * @param mesh  The mesh to target.\r\n     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh\r\n     * @param onAnimationEnd Callback triggered at the end of the framing animation\r\n     */\r\n    public zoomOnMesh(mesh: AbstractMesh, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {\r\n        mesh.computeWorldMatrix(true);\r\n\r\n        const boundingBox = mesh.getBoundingInfo().boundingBox;\r\n        this.zoomOnBoundingInfo(boundingBox.minimumWorld, boundingBox.maximumWorld, focusOnOriginXZ, onAnimationEnd);\r\n    }\r\n\r\n    /**\r\n     * Targets the given mesh with its children and updates zoom level accordingly.\r\n     * @param mesh The mesh to target.\r\n     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh\r\n     * @param onAnimationEnd Callback triggered at the end of the framing animation\r\n     */\r\n    public zoomOnMeshHierarchy(mesh: AbstractMesh, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {\r\n        mesh.computeWorldMatrix(true);\r\n\r\n        const boundingBox = mesh.getHierarchyBoundingVectors(true);\r\n        this.zoomOnBoundingInfo(boundingBox.min, boundingBox.max, focusOnOriginXZ, onAnimationEnd);\r\n    }\r\n\r\n    /**\r\n     * Targets the given meshes with their children and updates zoom level accordingly.\r\n     * @param meshes  The mesh to target.\r\n     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh\r\n     * @param onAnimationEnd Callback triggered at the end of the framing animation\r\n     */\r\n    public zoomOnMeshesHierarchy(meshes: AbstractMesh[], focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {\r\n        const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const boundingInfo = meshes[i].getHierarchyBoundingVectors(true);\r\n            Vector3.CheckExtends(boundingInfo.min, min, max);\r\n            Vector3.CheckExtends(boundingInfo.max, min, max);\r\n        }\r\n\r\n        this.zoomOnBoundingInfo(min, max, focusOnOriginXZ, onAnimationEnd);\r\n    }\r\n\r\n    /**\r\n     * Targets the bounding box info defined by its extends and updates zoom level accordingly.\r\n     * @param minimumWorld Determines the smaller position of the bounding box extend\r\n     * @param maximumWorld Determines the bigger position of the bounding box extend\r\n     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh\r\n     * @param onAnimationEnd Callback triggered at the end of the framing animation\r\n     * @returns true if the zoom was done\r\n     */\r\n    public zoomOnBoundingInfo(minimumWorld: Vector3, maximumWorld: Vector3, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): boolean {\r\n        let zoomTarget: Vector3;\r\n\r\n        if (!this._attachedCamera) {\r\n            return false;\r\n        }\r\n\r\n        // Find target by interpolating from bottom of bounding box in world-space to top via framingPositionY\r\n        const bottom = minimumWorld.y;\r\n        const top = maximumWorld.y;\r\n        const zoomTargetY = bottom + (top - bottom) * this._positionScale;\r\n        const radiusWorld = maximumWorld.subtract(minimumWorld).scale(0.5);\r\n\r\n        if (!isFinite(zoomTargetY)) {\r\n            return false; // Abort mission as there is no target\r\n        }\r\n\r\n        if (focusOnOriginXZ) {\r\n            zoomTarget = new Vector3(0, zoomTargetY, 0);\r\n        } else {\r\n            const centerWorld = minimumWorld.add(radiusWorld);\r\n            zoomTarget = new Vector3(centerWorld.x, zoomTargetY, centerWorld.z);\r\n        }\r\n\r\n        if (!this._vectorTransition) {\r\n            this._vectorTransition = Animation.CreateAnimation(\"target\", Animation.ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);\r\n        }\r\n\r\n        this._betaIsAnimating = true;\r\n        let animatable = Animation.TransitionTo(\"target\", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 60, this._vectorTransition, this._framingTime);\r\n        if (animatable) {\r\n            this._animatables.push(animatable);\r\n        }\r\n\r\n        // sets the radius and lower radius bounds\r\n        // Small delta ensures camera is not always at lower zoom limit.\r\n        let radius = 0;\r\n        if (this._mode === FramingBehavior.FitFrustumSidesMode) {\r\n            const position = this._calculateLowerRadiusFromModelBoundingSphere(minimumWorld, maximumWorld);\r\n            if (this.autoCorrectCameraLimitsAndSensibility) {\r\n                this._attachedCamera.lowerRadiusLimit = radiusWorld.length() + this._attachedCamera.minZ;\r\n            }\r\n            radius = position;\r\n        } else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {\r\n            radius = this._calculateLowerRadiusFromModelBoundingSphere(minimumWorld, maximumWorld);\r\n            if (this.autoCorrectCameraLimitsAndSensibility && this._attachedCamera.lowerRadiusLimit === null) {\r\n                this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;\r\n            }\r\n        }\r\n\r\n        // Set sensibilities\r\n        if (this.autoCorrectCameraLimitsAndSensibility) {\r\n            const extend = maximumWorld.subtract(minimumWorld).length();\r\n            this._attachedCamera.panningSensibility = 5000 / extend;\r\n            this._attachedCamera.wheelPrecision = 100 / radius;\r\n        }\r\n\r\n        // transition to new radius\r\n        if (!this._radiusTransition) {\r\n            this._radiusTransition = Animation.CreateAnimation(\"radius\", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);\r\n        }\r\n\r\n        animatable = Animation.TransitionTo(\"radius\", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime, () => {\r\n            this.stopAllAnimations();\r\n            if (onAnimationEnd) {\r\n                onAnimationEnd();\r\n            }\r\n\r\n            if (this._attachedCamera && this._attachedCamera.useInputToRestoreState) {\r\n                this._attachedCamera.storeState();\r\n            }\r\n        });\r\n\r\n        if (animatable) {\r\n            this._animatables.push(animatable);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Calculates the lowest radius for the camera based on the bounding box of the mesh.\r\n     * @param minimumWorld\r\n     * @param maximumWorld\r\n     * @returns The minimum distance from the primary mesh's center point at which the camera must be kept in order\r\n     *\t\t to fully enclose the mesh in the viewing frustum.\r\n     */\r\n    protected _calculateLowerRadiusFromModelBoundingSphere(minimumWorld: Vector3, maximumWorld: Vector3): number {\r\n        const camera = this._attachedCamera;\r\n\r\n        if (!camera) {\r\n            return 0;\r\n        }\r\n\r\n        let distance = camera._calculateLowerRadiusFromModelBoundingSphere(minimumWorld, maximumWorld, this._radiusScale);\r\n        if (camera.lowerRadiusLimit && this._mode === FramingBehavior.IgnoreBoundsSizeMode) {\r\n            // Don't exceed the requested limit\r\n            distance = distance < camera.lowerRadiusLimit ? camera.lowerRadiusLimit : distance;\r\n        }\r\n\r\n        // Don't exceed the upper radius limit\r\n        if (camera.upperRadiusLimit) {\r\n            distance = distance > camera.upperRadiusLimit ? camera.upperRadiusLimit : distance;\r\n        }\r\n\r\n        return distance;\r\n    }\r\n\r\n    /**\r\n     * Keeps the camera above the ground plane. If the user pulls the camera below the ground plane, the camera\r\n     * is automatically returned to its default position (expected to be above ground plane).\r\n     */\r\n    private _maintainCameraAboveGround(): void {\r\n        if (this._elevationReturnTime < 0) {\r\n            return;\r\n        }\r\n\r\n        const timeSinceInteraction = PrecisionDate.Now - this._lastInteractionTime;\r\n        const defaultBeta = Math.PI * 0.5 - this._defaultElevation;\r\n        const limitBeta = Math.PI * 0.5;\r\n\r\n        // Bring the camera back up if below the ground plane\r\n        if (this._attachedCamera && !this._betaIsAnimating && this._attachedCamera.beta > limitBeta && timeSinceInteraction >= this._elevationReturnWaitTime) {\r\n            this._betaIsAnimating = true;\r\n\r\n            //Transition to new position\r\n            this.stopAllAnimations();\r\n\r\n            if (!this._betaTransition) {\r\n                this._betaTransition = Animation.CreateAnimation(\"beta\", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);\r\n            }\r\n\r\n            const animatable = Animation.TransitionTo(\r\n                \"beta\",\r\n                defaultBeta,\r\n                this._attachedCamera,\r\n                this._attachedCamera.getScene(),\r\n                60,\r\n                this._betaTransition,\r\n                this._elevationReturnTime,\r\n                () => {\r\n                    this._clearAnimationLocks();\r\n                    this.stopAllAnimations();\r\n                }\r\n            );\r\n\r\n            if (animatable) {\r\n                this._animatables.push(animatable);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all animation locks. Allows new animations to be added to any of the arcCamera properties.\r\n     */\r\n    private _clearAnimationLocks(): void {\r\n        this._betaIsAnimating = false;\r\n    }\r\n\r\n    /**\r\n     *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.\r\n     */\r\n    private _applyUserInteraction(): void {\r\n        if (this.isUserIsMoving) {\r\n            this._lastInteractionTime = PrecisionDate.Now;\r\n            this.stopAllAnimations();\r\n            this._clearAnimationLocks();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stops and removes all animations that have been applied to the camera\r\n     */\r\n    public stopAllAnimations(): void {\r\n        if (this._attachedCamera) {\r\n            this._attachedCamera.animations = [];\r\n        }\r\n\r\n        while (this._animatables.length) {\r\n            if (this._animatables[0]) {\r\n                this._animatables[0].onAnimationEnd = null;\r\n                this._animatables[0].stop();\r\n            }\r\n            this._animatables.shift();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a value indicating if the user is moving the camera\r\n     */\r\n    public get isUserIsMoving(): boolean {\r\n        if (!this._attachedCamera) {\r\n            return false;\r\n        }\r\n\r\n        return (\r\n            this._attachedCamera.inertialAlphaOffset !== 0 ||\r\n            this._attachedCamera.inertialBetaOffset !== 0 ||\r\n            this._attachedCamera.inertialRadiusOffset !== 0 ||\r\n            this._attachedCamera.inertialPanningX !== 0 ||\r\n            this._attachedCamera.inertialPanningY !== 0 ||\r\n            this._isPointerDown\r\n        );\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * The camera can move all the way towards the mesh.\r\n     */\r\n    public static IgnoreBoundsSizeMode = 0;\r\n\r\n    /**\r\n     * The camera is not allowed to zoom closer to the mesh than the point at which the adjusted bounding sphere touches the frustum sides\r\n     */\r\n    public static FitFrustumSidesMode = 1;\r\n}\r\n","import { type Behavior } from \"../behavior\";\r\nimport { CubicEase, EasingFunction } from \"../../Animations/easing\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Animatable } from \"../../Animations/animatable.core\";\r\nimport { Animation } from \"../../Animations/animation.pure\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type IColor3Like, type IColor4Like, type IMatrixLike, type IQuaternionLike, type IVector2Like, type IVector3Like } from \"../../Maths/math.like\";\r\n\r\nexport type AllowedAnimValue = number | IVector2Like | IVector3Like | IQuaternionLike | IMatrixLike | IColor3Like | IColor4Like | SizeLike | undefined;\r\n\r\n/**\r\n * Animate camera property changes with an interpolation effect\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors\r\n */\r\nexport class InterpolatingBehavior<C extends Camera = Camera> implements Behavior<C> {\r\n    /**\r\n     * Gets the name of the behavior.\r\n     */\r\n    public get name(): string {\r\n        return \"Interpolating\";\r\n    }\r\n\r\n    /**\r\n     * The easing function to use for interpolation\r\n     */\r\n    public easingFunction: EasingFunction = new CubicEase();\r\n\r\n    /**\r\n     * The easing mode (default is EASINGMODE_EASEINOUT)\r\n     */\r\n    public easingMode = EasingFunction.EASINGMODE_EASEINOUT;\r\n\r\n    /**\r\n     * Duration of the animation in milliseconds\r\n     */\r\n    public transitionDuration = 450;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<C> {\r\n        return this._attachedCamera;\r\n    }\r\n\r\n    private _attachedCamera: Nullable<C> = null;\r\n    private _animatables: Map<string, Animatable> = new Map<string, Animatable>();\r\n    private _promiseResolve?: () => void;\r\n\r\n    // Frame rate used for all generated transition animations. Kept as a single constant so the duration\r\n    // math in remainingDurationMs stays consistent with the animations created in animatePropertiesAsync.\r\n    private static readonly _FrameRate = 60;\r\n\r\n    /**\r\n     * Initializes the behavior\r\n     */\r\n    constructor() {\r\n        this.easingFunction.setEasingMode(this.easingMode);\r\n    }\r\n\r\n    /**\r\n     * Initializes the behavior\r\n     */\r\n    public init(): void {\r\n        // Nothing to do on init\r\n    }\r\n\r\n    /**\r\n     * Attaches the behavior to a camera\r\n     * @param camera The camera to attach to\r\n     */\r\n    public attach(camera: C): void {\r\n        this._attachedCamera = camera;\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from the camera\r\n     */\r\n    public detach(): void {\r\n        if (!this._attachedCamera) {\r\n            return;\r\n        }\r\n\r\n        this.stopAllAnimations();\r\n        this._attachedCamera = null;\r\n    }\r\n\r\n    public get isInterpolating(): boolean {\r\n        return this._animatables.size > 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the longest remaining duration (in milliseconds) across all in-flight property animations.\r\n     * Returns 0 when nothing is currently animating.\r\n     */\r\n    public get remainingDurationMs(): number {\r\n        let remaining = 0;\r\n        this._animatables.forEach((animatable) => {\r\n            const remainingFrames = Math.max(animatable.toFrame - animatable.masterFrame, 0);\r\n            remaining = Math.max(remaining, (remainingFrames / InterpolatingBehavior._FrameRate) * 1000);\r\n        });\r\n        return remaining;\r\n    }\r\n\r\n    /**\r\n     * Stops and removes all animations\r\n     */\r\n    public stopAllAnimations(): void {\r\n        if (this._attachedCamera) {\r\n            this._animatables.forEach((animatable) => animatable.stop());\r\n        }\r\n        this._animatables.clear();\r\n        this._promiseResolve?.();\r\n        this._promiseResolve = undefined;\r\n    }\r\n\r\n    /**\r\n     * Called when a single property's transition completes (or is applied instantly). Cleans up the\r\n     * spent animation and resolves the in-flight promise once every property has reached its target.\r\n     * @param propertyName name of the property whose animation has finished\r\n     */\r\n    private _onPropertyAnimationEnd(propertyName: string): void {\r\n        const camera = this._attachedCamera;\r\n        if (camera) {\r\n            // Remove the associated animation from camera once the transition to target is complete so that property animations don't accumulate\r\n            for (let i = camera.animations.length - 1; i >= 0; --i) {\r\n                if (camera.animations[i].name === propertyName + \"Animation\") {\r\n                    camera.animations.splice(i, 1);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._animatables.delete(propertyName);\r\n        if (this._animatables.size === 0) {\r\n            const resolve = this._promiseResolve;\r\n            this._promiseResolve = undefined;\r\n            resolve?.();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Redirects any in-flight transition toward the given property values, reusing the time remaining in the\r\n     * current transition. No-op when nothing is currently animating.\r\n     * @deprecated Prefer `animatePropertiesAsync(properties, remainingDurationMs)`, which makes the duration\r\n     * explicit. This method is retained for backward compatibility.\r\n     * @param properties defines the property values to redirect toward\r\n     */\r\n    public updateProperties<K extends keyof C>(properties: Map<K, AllowedAnimValue>): void {\r\n        if (!this.isInterpolating) {\r\n            return;\r\n        }\r\n        void this.animatePropertiesAsync(properties, this.remainingDurationMs);\r\n    }\r\n\r\n    /**\r\n     * Animates camera properties to new values.\r\n     * @param properties defines the property values to animate to\r\n     * @param transitionDuration defines the transition duration in milliseconds\r\n     * @param easingFn defines the easing function to use\r\n     * @param updateAnimation defines an optional callback used to update each generated animation\r\n     * @returns a promise that resolves when the animation completes\r\n     */\r\n    public async animatePropertiesAsync<K extends keyof C>(\r\n        properties: Map<K, AllowedAnimValue>,\r\n        transitionDuration: number = this.transitionDuration,\r\n        easingFn: EasingFunction = this.easingFunction,\r\n        updateAnimation?: (key: string, animation: Animation) => void\r\n    ): Promise<void> {\r\n        const promise = new Promise<void>((resolve) => {\r\n            this.stopAllAnimations();\r\n\r\n            this._promiseResolve = resolve;\r\n            if (!this._attachedCamera) {\r\n                this._promiseResolve = undefined;\r\n                return resolve();\r\n            }\r\n            const camera = this._attachedCamera;\r\n            const scene = camera.getScene();\r\n\r\n            properties.forEach((value, key) => {\r\n                if (value !== undefined && camera[key] !== value) {\r\n                    const propertyName = String(key);\r\n                    const animation = Animation.CreateAnimation(propertyName, GetAnimationType(value), InterpolatingBehavior._FrameRate, easingFn);\r\n                    // Optionally allow caller to further customize the animation\r\n                    updateAnimation?.(propertyName, animation);\r\n\r\n                    // Pass false for stopCurrent so that we can interpolate multiple properties at once\r\n                    const animatable = Animation.TransitionTo(\r\n                        propertyName,\r\n                        value,\r\n                        camera,\r\n                        scene,\r\n                        InterpolatingBehavior._FrameRate,\r\n                        animation,\r\n                        transitionDuration,\r\n                        () => this._onPropertyAnimationEnd(propertyName),\r\n                        false\r\n                    );\r\n                    if (animatable) {\r\n                        this._animatables.set(propertyName, animatable);\r\n                    }\r\n                }\r\n            });\r\n\r\n            // Nothing needed animating (already at target): resolve immediately rather than hang.\r\n            if (this._animatables.size === 0) {\r\n                this._promiseResolve = undefined;\r\n                resolve();\r\n            }\r\n        });\r\n        return await promise;\r\n    }\r\n}\r\n\r\n// Structural type-guards (no instanceof)\r\nfunction IsQuaternionLike(v: any): v is IQuaternionLike {\r\n    return v != null && typeof v.x === \"number\" && typeof v.y === \"number\" && typeof v.z === \"number\" && typeof v.w === \"number\";\r\n}\r\n\r\nfunction IsMatrixLike(v: any): v is IMatrixLike {\r\n    return v != null && (Array.isArray((v as any).m) || typeof (v as any).m === \"object\");\r\n}\r\n\r\nfunction IsVector3Like(v: any): v is IVector3Like {\r\n    return v != null && typeof v.x === \"number\" && typeof v.y === \"number\" && typeof v.z === \"number\";\r\n}\r\n\r\nfunction IsVector2Like(v: any): v is IVector2Like {\r\n    return v != null && typeof v.x === \"number\" && typeof v.y === \"number\";\r\n}\r\n\r\nfunction IsColor3Like(v: any): v is IColor3Like {\r\n    return v != null && typeof v.r === \"number\" && typeof v.g === \"number\" && typeof v.b === \"number\";\r\n}\r\n\r\nfunction IsColor4Like(v: any): v is IColor4Like {\r\n    return v != null && typeof v.r === \"number\" && typeof v.g === \"number\" && typeof v.b === \"number\" && typeof v.a === \"number\";\r\n}\r\n\r\nexport type SizeLike = { width: number; height: number };\r\n\r\nfunction IsSizeLike(v: any): v is SizeLike {\r\n    return v != null && typeof v.width === \"number\" && typeof v.height === \"number\";\r\n}\r\n\r\nconst GetAnimationType = (value: AllowedAnimValue): number => {\r\n    if (IsQuaternionLike(value)) {\r\n        return Animation.ANIMATIONTYPE_QUATERNION;\r\n    }\r\n    if (IsMatrixLike(value)) {\r\n        return Animation.ANIMATIONTYPE_MATRIX;\r\n    }\r\n    if (IsVector3Like(value)) {\r\n        return Animation.ANIMATIONTYPE_VECTOR3;\r\n    }\r\n    if (IsVector2Like(value)) {\r\n        return Animation.ANIMATIONTYPE_VECTOR2;\r\n    }\r\n    if (IsColor3Like(value)) {\r\n        return Animation.ANIMATIONTYPE_COLOR3;\r\n    }\r\n    if (IsColor4Like(value)) {\r\n        return Animation.ANIMATIONTYPE_COLOR4;\r\n    }\r\n    if (IsSizeLike(value)) {\r\n        return Animation.ANIMATIONTYPE_SIZE;\r\n    }\r\n\r\n    // Fallback to float for numbers and unknown shapes\r\n    return Animation.ANIMATIONTYPE_FLOAT;\r\n};\r\n","import { type Behavior } from \"../../Behaviors/behavior\";\r\nimport { type GeospatialCamera } from \"../../Cameras/geospatialCamera\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Scene } from \"../../scene\";\r\n\r\n/**\r\n * The GeospatialClippingBehavior automatically adjusts the near and far clip planes of a GeospatialCamera\r\n * based on altitude to optimize depth buffer precision for geospatial applications.\r\n *\r\n * The near plane scales with altitude (distance to planet surface) to maintain good depth precision.\r\n * The far plane is calculated based on the visible horizon distance.\r\n */\r\nexport class GeospatialClippingBehavior implements Behavior<GeospatialCamera> {\r\n    /**\r\n     * Gets the name of the behavior.\r\n     */\r\n    public get name(): string {\r\n        return \"GeospatialClipping\";\r\n    }\r\n\r\n    private _attachedCamera: Nullable<GeospatialCamera> = null;\r\n    private _onBeforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    /**\r\n     * Gets the attached camera.\r\n     */\r\n    public get attachedNode(): Nullable<GeospatialCamera> {\r\n        return this._attachedCamera;\r\n    }\r\n\r\n    /**\r\n     * Initializes the behavior.\r\n     */\r\n    public init(): void {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Attaches the behavior to its geospatial camera.\r\n     * @param camera Defines the camera to attach the behavior to\r\n     */\r\n    public attach(camera: GeospatialCamera): void {\r\n        this._attachedCamera = camera;\r\n        const scene = camera.getScene();\r\n\r\n        this._onBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {\r\n            this._updateCameraClipPlanes();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from its current geospatial camera.\r\n     */\r\n    public detach(): void {\r\n        if (this._attachedCamera) {\r\n            const scene = this._attachedCamera.getScene();\r\n            if (this._onBeforeRenderObserver) {\r\n                scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n                this._onBeforeRenderObserver = null;\r\n            }\r\n        }\r\n        this._attachedCamera = null;\r\n    }\r\n\r\n    /**\r\n     * Updates the camera's near and far clip planes based on altitude.\r\n     */\r\n    private _updateCameraClipPlanes(): void {\r\n        const camera = this._attachedCamera;\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        const planetRadius = camera.limits.planetRadius;\r\n        // Camera position length gives distance to world origin (planet center)\r\n        const altitude = Math.max(1, camera.position.length() - planetRadius);\r\n\r\n        // Near plane: scale with altitude to maintain depth buffer precision\r\n        // Use a fraction of altitude - the closest visible point on a sphere is straight down at distance = altitude\r\n        camera.minZ = Math.max(1, altitude * 0.001);\r\n\r\n        // Far plane: see to the horizon and beyond\r\n        // Horizon distance formula: √(2Rh + h²) where h is altitude above surface\r\n        const horizonDist = Math.sqrt(2 * planetRadius * altitude + altitude * altitude);\r\n        camera.maxZ = horizonDist + planetRadius * 0.1;\r\n    }\r\n}\r\n","import { Vector3, Matrix, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Behavior } from \"../../Behaviors/behavior\";\r\n\r\n/**\r\n * @internal\r\n */\r\nclass FaceDirectionInfo {\r\n    constructor(\r\n        public direction: Vector3,\r\n        public rotatedDirection = new Vector3(),\r\n        public diff = 0,\r\n        public ignore = false\r\n    ) {}\r\n}\r\n\r\n/**\r\n * A behavior that when attached to a mesh will will place a specified node on the meshes face pointing towards the camera\r\n */\r\nexport class AttachToBoxBehavior implements Behavior<Mesh> {\r\n    /**\r\n     *  [\"AttachToBoxBehavior\"] The name of the behavior\r\n     */\r\n    public name = \"AttachToBoxBehavior\";\r\n    /**\r\n     * [0.15] The distance away from the face of the mesh that the UI should be attached to (default: 0.15)\r\n     */\r\n    public distanceAwayFromFace = 0.15;\r\n    /**\r\n     * [0.15] The distance from the bottom of the face that the UI should be attached to (default: 0.15)\r\n     */\r\n    public distanceAwayFromBottomOfFace = 0.15;\r\n    private _faceVectors = [\r\n        new FaceDirectionInfo(Vector3.Up()),\r\n        new FaceDirectionInfo(Vector3.Down()),\r\n        new FaceDirectionInfo(Vector3.Left()),\r\n        new FaceDirectionInfo(Vector3.Right()),\r\n        new FaceDirectionInfo(Vector3.Forward()),\r\n        new FaceDirectionInfo(Vector3.Forward().scaleInPlace(-1)),\r\n    ];\r\n    private _target: Mesh;\r\n    private _scene: Scene;\r\n    private _onRenderObserver: Nullable<Observer<Scene>>;\r\n    private _tmpMatrix = new Matrix();\r\n    private _tmpVector = new Vector3();\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<Mesh> {\r\n        return this._target;\r\n    }\r\n\r\n    /**\r\n     * Creates the AttachToBoxBehavior, used to attach UI to the closest face of the box to a camera\r\n     * @param _ui The transform node that should be attached to the mesh\r\n     */\r\n    constructor(private _ui: TransformNode) {\r\n        this._target = null!;\r\n    }\r\n\r\n    /**\r\n     *  Initializes the behavior\r\n     */\r\n    public init() {\r\n        /* Does nothing */\r\n    }\r\n\r\n    private _closestFace(targetDirection: Vector3) {\r\n        // Go over each face and calculate the angle between the face's normal and targetDirection\r\n        for (const v of this._faceVectors) {\r\n            if (!this._target.rotationQuaternion) {\r\n                this._target.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._target.rotation.y, this._target.rotation.x, this._target.rotation.z);\r\n            }\r\n            this._target.rotationQuaternion.toRotationMatrix(this._tmpMatrix);\r\n            Vector3.TransformCoordinatesToRef(v.direction, this._tmpMatrix, v.rotatedDirection);\r\n            v.diff = Vector3.GetAngleBetweenVectors(v.rotatedDirection, targetDirection, Vector3.Cross(v.rotatedDirection, targetDirection));\r\n        }\r\n        // Return the face information of the one with the normal closest to target direction\r\n        return this._faceVectors.reduce((min, p) => {\r\n            if (min.ignore) {\r\n                return p;\r\n            } else if (p.ignore) {\r\n                return min;\r\n            } else {\r\n                return min.diff < p.diff ? min : p;\r\n            }\r\n        }, this._faceVectors[0]);\r\n    }\r\n\r\n    private _zeroVector = Vector3.Zero();\r\n    private _lookAtTmpMatrix = new Matrix();\r\n    private _lookAtToRef(pos: Vector3, up = new Vector3(0, 1, 0), ref: Quaternion) {\r\n        Matrix.LookAtLHToRef(this._zeroVector, pos, up, this._lookAtTmpMatrix);\r\n        this._lookAtTmpMatrix.invert();\r\n        Quaternion.FromRotationMatrixToRef(this._lookAtTmpMatrix, ref);\r\n    }\r\n\r\n    /**\r\n     * Attaches the AttachToBoxBehavior to the passed in mesh\r\n     * @param target The mesh that the specified node will be attached to\r\n     */\r\n    attach(target: Mesh) {\r\n        this._target = target;\r\n        this._scene = this._target.getScene();\r\n\r\n        // Every frame, update the app bars position\r\n        this._onRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n            if (!this._scene.activeCamera) {\r\n                return;\r\n            }\r\n\r\n            // Find the face closest to the cameras position\r\n            let cameraPos = this._scene.activeCamera.position;\r\n            if ((<any>this._scene.activeCamera).devicePosition) {\r\n                cameraPos = (<any>this._scene.activeCamera).devicePosition;\r\n            }\r\n            const facing = this._closestFace(cameraPos.subtract(target.position));\r\n            if (this._scene.activeCamera.leftCamera) {\r\n                this._scene.activeCamera.leftCamera.computeWorldMatrix().getRotationMatrixToRef(this._tmpMatrix);\r\n            } else {\r\n                this._scene.activeCamera.computeWorldMatrix().getRotationMatrixToRef(this._tmpMatrix);\r\n            }\r\n\r\n            // Get camera up direction\r\n            Vector3.TransformCoordinatesToRef(Vector3.Up(), this._tmpMatrix, this._tmpVector);\r\n            // Ignore faces to not select a parallel face for the up vector of the UI\r\n            for (const v of this._faceVectors) {\r\n                if (facing.direction.x && v.direction.x) {\r\n                    v.ignore = true;\r\n                }\r\n                if (facing.direction.y && v.direction.y) {\r\n                    v.ignore = true;\r\n                }\r\n                if (facing.direction.z && v.direction.z) {\r\n                    v.ignore = true;\r\n                }\r\n            }\r\n            const facingUp = this._closestFace(this._tmpVector);\r\n            // Unignore faces\r\n            for (const v of this._faceVectors) {\r\n                v.ignore = false;\r\n            }\r\n\r\n            // Position the app bar on that face\r\n            this._ui.position.copyFrom(target.position);\r\n            if (facing.direction.x) {\r\n                facing.rotatedDirection.scaleToRef(target.scaling.x / 2 + this.distanceAwayFromFace, this._tmpVector);\r\n                this._ui.position.addInPlace(this._tmpVector);\r\n            }\r\n            if (facing.direction.y) {\r\n                facing.rotatedDirection.scaleToRef(target.scaling.y / 2 + this.distanceAwayFromFace, this._tmpVector);\r\n                this._ui.position.addInPlace(this._tmpVector);\r\n            }\r\n            if (facing.direction.z) {\r\n                facing.rotatedDirection.scaleToRef(target.scaling.z / 2 + this.distanceAwayFromFace, this._tmpVector);\r\n                this._ui.position.addInPlace(this._tmpVector);\r\n            }\r\n\r\n            // Rotate to be oriented properly to the camera\r\n            if (!this._ui.rotationQuaternion) {\r\n                this._ui.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._ui.rotation.y, this._ui.rotation.x, this._ui.rotation.z);\r\n            }\r\n            facing.rotatedDirection.scaleToRef(-1, this._tmpVector);\r\n            this._lookAtToRef(this._tmpVector, facingUp.rotatedDirection, this._ui.rotationQuaternion);\r\n\r\n            // Place ui the correct distance from the bottom of the mesh\r\n            if (facingUp.direction.x) {\r\n                this._ui.up.scaleToRef(this.distanceAwayFromBottomOfFace - target.scaling.x / 2, this._tmpVector);\r\n            }\r\n            if (facingUp.direction.y) {\r\n                this._ui.up.scaleToRef(this.distanceAwayFromBottomOfFace - target.scaling.y / 2, this._tmpVector);\r\n            }\r\n            if (facingUp.direction.z) {\r\n                this._ui.up.scaleToRef(this.distanceAwayFromBottomOfFace - target.scaling.z / 2, this._tmpVector);\r\n            }\r\n            this._ui.position.addInPlace(this._tmpVector);\r\n        });\r\n    }\r\n\r\n    /**\r\n     *  Detaches the behavior from the mesh\r\n     */\r\n    detach() {\r\n        this._scene.onBeforeRenderObservable.remove(this._onRenderObserver);\r\n        this._target = null!;\r\n    }\r\n}\r\n","import { type Behavior } from \"../behavior\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\nimport { type Scene } from \"core/scene\";\r\n\r\n/**\r\n * A behavior that when attached to a mesh will allow the mesh to fade in and out\r\n */\r\nexport class FadeInOutBehavior implements Behavior<Mesh> {\r\n    /**\r\n     * Time in milliseconds to delay before fading in (Default: 0)\r\n     */\r\n    public fadeInDelay = 0;\r\n\r\n    /**\r\n     * Time in milliseconds to delay before fading out (Default: 0)\r\n     */\r\n    public fadeOutDelay = 0;\r\n\r\n    /**\r\n     * Time in milliseconds for the mesh to fade in (Default: 300)\r\n     */\r\n    public fadeInTime = 300;\r\n\r\n    /**\r\n     * Time in milliseconds for the mesh to fade out (Default: 300)\r\n     */\r\n    public fadeOutTime = 300;\r\n\r\n    /**\r\n     * Time in milliseconds to delay before fading in (Default: 0)\r\n     * Will set both fade in and out delay to the same value\r\n     */\r\n    public get delay(): number {\r\n        return this.fadeInDelay;\r\n    }\r\n\r\n    public set delay(value: number) {\r\n        this.fadeInDelay = value;\r\n        this.fadeOutDelay = value;\r\n    }\r\n\r\n    private _millisecondsPerFrame = 1000 / 60;\r\n    private _hovered = false;\r\n    private _hoverValue = 0;\r\n    private _ownerNode: Nullable<Mesh> = null;\r\n    private _onBeforeRenderObserver: Nullable<Observer<Scene>> | undefined;\r\n    private _delay: number = 0;\r\n    private _time: number = 300;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<Mesh> {\r\n        return this._ownerNode;\r\n    }\r\n\r\n    /**\r\n     * Instantiates the FadeInOutBehavior\r\n     */\r\n    constructor() {}\r\n\r\n    /**\r\n     *  The name of the behavior\r\n     */\r\n    public get name(): string {\r\n        return \"FadeInOut\";\r\n    }\r\n\r\n    /**\r\n     *  Initializes the behavior\r\n     */\r\n    public init() {}\r\n\r\n    /**\r\n     * Attaches the fade behavior on the passed in mesh\r\n     * @param ownerNode The mesh that will be faded in/out once attached\r\n     */\r\n    public attach(ownerNode: Mesh): void {\r\n        this._ownerNode = ownerNode;\r\n        this._setAllVisibility(this._ownerNode, 0);\r\n    }\r\n    /**\r\n     *  Detaches the behavior from the mesh\r\n     */\r\n    public detach(): void {\r\n        this._ownerNode = null;\r\n    }\r\n\r\n    /**\r\n     * Triggers the mesh to begin fading in (or out)\r\n     * @param fadeIn if the object should fade in or out (true to fade in)\r\n     */\r\n    public fadeIn(fadeIn: boolean = true) {\r\n        this._delay = fadeIn ? this.fadeInDelay : this.fadeOutDelay;\r\n        this._time = fadeIn ? this.fadeInTime : this.fadeOutTime;\r\n\r\n        // Cancel any pending updates\r\n        this._detachObserver();\r\n\r\n        // If fading in and already visible or fading out and already not visible do nothing\r\n        if (this._ownerNode && ((fadeIn && this._ownerNode.visibility >= 1) || (!fadeIn && this._ownerNode.visibility <= 0))) {\r\n            return;\r\n        }\r\n\r\n        this._hovered = fadeIn;\r\n        if (!this._hovered) {\r\n            // Make the delay the negative of fadeout delay so the hoverValue is kept above 1 until\r\n            // fadeOutDelay has elapsed\r\n            this._delay *= -1;\r\n        }\r\n\r\n        // Reset the hoverValue.  This is necessary because we may have been fading out, e.g. but not yet reached\r\n        // the delay, so the hover value is greater than 1\r\n        if (this._ownerNode!.visibility >= 1) {\r\n            this._hoverValue = this._time;\r\n        } else if (this._ownerNode!.visibility <= 0) {\r\n            this._hoverValue = 0;\r\n        }\r\n        this._update();\r\n    }\r\n\r\n    /**\r\n     * Triggers the mesh to begin fading out\r\n     */\r\n    public fadeOut() {\r\n        this.fadeIn(false);\r\n    }\r\n\r\n    private _update = () => {\r\n        if (this._ownerNode) {\r\n            this._hoverValue += this._hovered ? this._millisecondsPerFrame : -this._millisecondsPerFrame;\r\n\r\n            this._setAllVisibility(this._ownerNode, (this._hoverValue - this._delay) / this._time);\r\n\r\n            if (this._ownerNode.visibility > 1) {\r\n                this._setAllVisibility(this._ownerNode, 1);\r\n                if (this._hoverValue > this._time) {\r\n                    this._hoverValue = this._time;\r\n                    this._detachObserver();\r\n                    return;\r\n                }\r\n            } else if (this._ownerNode.visibility < 0) {\r\n                this._setAllVisibility(this._ownerNode, 0);\r\n                if (this._hoverValue < 0) {\r\n                    this._hoverValue = 0;\r\n                    this._detachObserver();\r\n                    return;\r\n                }\r\n            }\r\n\r\n            this._attachObserver();\r\n        }\r\n    };\r\n\r\n    private _setAllVisibility(mesh: AbstractMesh, value: number) {\r\n        mesh.visibility = value;\r\n\r\n        const children = mesh.getChildMeshes();\r\n\r\n        for (const c of children) {\r\n            this._setAllVisibility(c, value);\r\n        }\r\n    }\r\n\r\n    private _attachObserver() {\r\n        if (!this._onBeforeRenderObserver) {\r\n            this._onBeforeRenderObserver = this._ownerNode?.getScene().onBeforeRenderObservable.add(this._update);\r\n        }\r\n    }\r\n\r\n    private _detachObserver() {\r\n        if (this._onBeforeRenderObserver) {\r\n            this._ownerNode?.getScene().onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n            this._onBeforeRenderObserver = null;\r\n        }\r\n    }\r\n}\r\n","import { Epsilon } from \"core/Maths/math.constants\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { BuildArray } from \"core/Misc/arrayTools\";\r\nimport { IntersectionInfo } from \"../Collisions/intersectionInfo\";\r\nimport { type BoundingInfo } from \"./boundingInfo\";\r\nimport { type BoundingBox } from \"./boundingBox\";\r\nimport { type BoundingSphere } from \"./boundingSphere\";\r\nimport { type DeepImmutable, type float, type Nullable } from \"core/types\";\r\nimport { type Plane } from \"core/Maths/math.plane\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { PickingInfo } from \"core/Collisions/pickingInfo\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Camera } from \"core/Cameras/camera\";\r\nimport { type Mesh } from \"core/Meshes/mesh\";\r\nimport { _ImportHelper } from \"core/import.helper\";\r\n\r\n/**\r\n * Type used to define predicate for selecting meshes and instances (if exist)\r\n */\r\nexport type MeshPredicate = (mesh: AbstractMesh, thinInstanceIndex: number) => boolean;\r\n\r\n/**\r\n * Type used to define predicate used to select faces when a mesh intersection is detected\r\n */\r\nexport type TrianglePickingPredicate = (p0: Vector3, p1: Vector3, p2: Vector3, ray: Ray, i0: number, i1: number, i2: number) => boolean;\r\n\r\n/**\r\n * This class allows user to customize internal picking mechanism\r\n */\r\nexport interface IPickingCustomization {\r\n    /**\r\n     * Predicate to select faces when a mesh intersection is detected\r\n     */\r\n    internalPickerForMesh?: (\r\n        pickingInfo: Nullable<PickingInfo>,\r\n        rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray,\r\n        mesh: AbstractMesh,\r\n        world: Matrix,\r\n        fastCheck?: boolean,\r\n        onlyBoundingInfo?: boolean,\r\n        trianglePredicate?: TrianglePickingPredicate,\r\n        skipBoundingInfo?: boolean\r\n    ) => PickingInfo;\r\n}\r\n\r\n/**\r\n * Use this object to customize mesh picking behavior\r\n */\r\nexport const PickingCustomization: IPickingCustomization = {\r\n    internalPickerForMesh: undefined,\r\n};\r\n\r\n/**\r\n * Class representing a ray with position and direction\r\n */\r\nexport class Ray {\r\n    private static readonly _TmpVector3 = BuildArray(6, Vector3.Zero);\r\n    private static _RayDistant = Ray.Zero();\r\n    private _tmpRay: Ray;\r\n\r\n    /**\r\n     * Creates a new ray\r\n     * @param origin origin point\r\n     * @param direction direction\r\n     * @param length length of the ray\r\n     * @param epsilon The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants)\r\n     */\r\n    constructor(\r\n        /** origin point */\r\n        public origin: Vector3,\r\n        /** direction */\r\n        public direction: Vector3,\r\n        /** [Number.MAX_VALUE] length of the ray */\r\n        public length: number = Number.MAX_VALUE,\r\n        /** [Epsilon] The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants) */\r\n        public epsilon: number = Epsilon\r\n    ) {}\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Clone the current ray\r\n     * @returns a new ray\r\n     */\r\n    public clone(): Ray {\r\n        return new Ray(this.origin.clone(), this.direction.clone(), this.length);\r\n    }\r\n\r\n    /**\r\n     * Checks if the ray intersects a box\r\n     * This does not account for the ray length by design to improve perfs.\r\n     * @param minimum bound of the box\r\n     * @param maximum bound of the box\r\n     * @param intersectionTreshold extra extend to be added to the box in all direction\r\n     * @returns if the box was hit\r\n     */\r\n    public intersectsBoxMinMax(minimum: DeepImmutable<Vector3>, maximum: DeepImmutable<Vector3>, intersectionTreshold: number = 0): boolean {\r\n        const newMinimum = Ray._TmpVector3[0].copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);\r\n        const newMaximum = Ray._TmpVector3[1].copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);\r\n        let d = 0.0;\r\n        let maxValue = Number.MAX_VALUE;\r\n        let inv: number;\r\n        let min: number;\r\n        let max: number;\r\n        let temp: number;\r\n        if (Math.abs(this.direction.x) < 0.0000001) {\r\n            if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {\r\n                return false;\r\n            }\r\n        } else {\r\n            inv = 1.0 / this.direction.x;\r\n            min = (newMinimum.x - this.origin.x) * inv;\r\n            max = (newMaximum.x - this.origin.x) * inv;\r\n            if (max === -Infinity) {\r\n                max = Infinity;\r\n            }\r\n\r\n            if (min > max) {\r\n                temp = min;\r\n                min = max;\r\n                max = temp;\r\n            }\r\n\r\n            d = Math.max(min, d);\r\n            maxValue = Math.min(max, maxValue);\r\n\r\n            if (d > maxValue) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (Math.abs(this.direction.y) < 0.0000001) {\r\n            if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {\r\n                return false;\r\n            }\r\n        } else {\r\n            inv = 1.0 / this.direction.y;\r\n            min = (newMinimum.y - this.origin.y) * inv;\r\n            max = (newMaximum.y - this.origin.y) * inv;\r\n\r\n            if (max === -Infinity) {\r\n                max = Infinity;\r\n            }\r\n\r\n            if (min > max) {\r\n                temp = min;\r\n                min = max;\r\n                max = temp;\r\n            }\r\n\r\n            d = Math.max(min, d);\r\n            maxValue = Math.min(max, maxValue);\r\n\r\n            if (d > maxValue) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (Math.abs(this.direction.z) < 0.0000001) {\r\n            if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {\r\n                return false;\r\n            }\r\n        } else {\r\n            inv = 1.0 / this.direction.z;\r\n            min = (newMinimum.z - this.origin.z) * inv;\r\n            max = (newMaximum.z - this.origin.z) * inv;\r\n\r\n            if (max === -Infinity) {\r\n                max = Infinity;\r\n            }\r\n\r\n            if (min > max) {\r\n                temp = min;\r\n                min = max;\r\n                max = temp;\r\n            }\r\n\r\n            d = Math.max(min, d);\r\n            maxValue = Math.min(max, maxValue);\r\n\r\n            if (d > maxValue) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Checks if the ray intersects a box\r\n     * This does not account for the ray length by design to improve perfs.\r\n     * @param box the bounding box to check\r\n     * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction\r\n     * @returns if the box was hit\r\n     */\r\n    public intersectsBox(box: DeepImmutable<BoundingBox>, intersectionTreshold: number = 0): boolean {\r\n        return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);\r\n    }\r\n\r\n    /**\r\n     * If the ray hits a sphere\r\n     * @param sphere the bounding sphere to check\r\n     * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction\r\n     * @returns true if it hits the sphere\r\n     */\r\n    public intersectsSphere(sphere: DeepImmutable<BoundingSphere>, intersectionTreshold: number = 0): boolean {\r\n        const x = sphere.center.x - this.origin.x;\r\n        const y = sphere.center.y - this.origin.y;\r\n        const z = sphere.center.z - this.origin.z;\r\n        const pyth = x * x + y * y + z * z;\r\n        const radius = sphere.radius + intersectionTreshold;\r\n        const rr = radius * radius;\r\n\r\n        if (pyth <= rr) {\r\n            return true;\r\n        }\r\n\r\n        const dot = x * this.direction.x + y * this.direction.y + z * this.direction.z;\r\n        if (dot < 0.0) {\r\n            return false;\r\n        }\r\n\r\n        const temp = pyth - dot * dot;\r\n\r\n        return temp <= rr;\r\n    }\r\n\r\n    /**\r\n     * If the ray hits a triange\r\n     * @param vertex0 triangle vertex\r\n     * @param vertex1 triangle vertex\r\n     * @param vertex2 triangle vertex\r\n     * @returns intersection information if hit\r\n     */\r\n    public intersectsTriangle(vertex0: DeepImmutable<Vector3>, vertex1: DeepImmutable<Vector3>, vertex2: DeepImmutable<Vector3>): Nullable<IntersectionInfo> {\r\n        const edge1 = Ray._TmpVector3[0];\r\n        const edge2 = Ray._TmpVector3[1];\r\n        const pvec = Ray._TmpVector3[2];\r\n        const tvec = Ray._TmpVector3[3];\r\n        const qvec = Ray._TmpVector3[4];\r\n\r\n        vertex1.subtractToRef(vertex0, edge1);\r\n        vertex2.subtractToRef(vertex0, edge2);\r\n        Vector3.CrossToRef(this.direction, edge2, pvec);\r\n        const det = Vector3.Dot(edge1, pvec);\r\n\r\n        if (det === 0) {\r\n            return null;\r\n        }\r\n\r\n        const invdet = 1 / det;\r\n\r\n        this.origin.subtractToRef(vertex0, tvec);\r\n\r\n        const bv = Vector3.Dot(tvec, pvec) * invdet;\r\n\r\n        if (bv < -this.epsilon || bv > 1.0 + this.epsilon) {\r\n            return null;\r\n        }\r\n\r\n        Vector3.CrossToRef(tvec, edge1, qvec);\r\n\r\n        const bw = Vector3.Dot(this.direction, qvec) * invdet;\r\n\r\n        if (bw < -this.epsilon || bv + bw > 1.0 + this.epsilon) {\r\n            return null;\r\n        }\r\n\r\n        //check if the distance is longer than the predefined length.\r\n        const distance = Vector3.Dot(edge2, qvec) * invdet;\r\n        if (distance > this.length || distance < 0) {\r\n            return null;\r\n        }\r\n\r\n        return new IntersectionInfo(1 - bv - bw, bv, distance);\r\n    }\r\n\r\n    /**\r\n     * Checks if ray intersects a plane\r\n     * @param plane the plane to check\r\n     * @returns the distance away it was hit\r\n     */\r\n    public intersectsPlane(plane: DeepImmutable<Plane>): Nullable<number> {\r\n        let distance: number;\r\n        const result1 = Vector3.Dot(plane.normal, this.direction);\r\n        if (Math.abs(result1) < 9.99999997475243e-7) {\r\n            return null;\r\n        } else {\r\n            const result2 = Vector3.Dot(plane.normal, this.origin);\r\n            distance = (-plane.d - result2) / result1;\r\n            if (distance < 0.0) {\r\n                if (distance < -9.99999997475243e-7) {\r\n                    return null;\r\n                } else {\r\n                    return 0;\r\n                }\r\n            }\r\n\r\n            return distance;\r\n        }\r\n    }\r\n    /**\r\n     * Calculate the intercept of a ray on a given axis\r\n     * @param axis to check 'x' | 'y' | 'z'\r\n     * @param offset from axis interception (i.e. an offset of 1y is intercepted above ground)\r\n     * @returns a vector containing the coordinates where 'axis' is equal to zero (else offset), or null if there is no intercept.\r\n     */\r\n    public intersectsAxis(axis: string, offset: number = 0): Nullable<Vector3> {\r\n        switch (axis) {\r\n            case \"y\": {\r\n                const t = (this.origin.y - offset) / this.direction.y;\r\n                if (t > 0) {\r\n                    return null;\r\n                }\r\n                return new Vector3(this.origin.x + this.direction.x * -t, offset, this.origin.z + this.direction.z * -t);\r\n            }\r\n            case \"x\": {\r\n                const t = (this.origin.x - offset) / this.direction.x;\r\n                if (t > 0) {\r\n                    return null;\r\n                }\r\n                return new Vector3(offset, this.origin.y + this.direction.y * -t, this.origin.z + this.direction.z * -t);\r\n            }\r\n            case \"z\": {\r\n                const t = (this.origin.z - offset) / this.direction.z;\r\n                if (t > 0) {\r\n                    return null;\r\n                }\r\n                return new Vector3(this.origin.x + this.direction.x * -t, this.origin.y + this.direction.y * -t, offset);\r\n            }\r\n            default:\r\n                return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if ray intersects a mesh. The ray is defined in WORLD space. A mesh triangle can be picked both from its front and back sides,\r\n     * irrespective of orientation.\r\n     * @param mesh the mesh to check\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n     * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)\r\n     * @param worldToUse defines the world matrix to use to get the world coordinate of the intersection point\r\n     * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n     * @returns picking info of the intersection\r\n     */\r\n    public intersectsMesh(\r\n        mesh: DeepImmutable<AbstractMesh>,\r\n        fastCheck?: boolean,\r\n        trianglePredicate?: TrianglePickingPredicate,\r\n        onlyBoundingInfo = false,\r\n        worldToUse?: Matrix,\r\n        skipBoundingInfo = false\r\n    ): PickingInfo {\r\n        const tm = TmpVectors.Matrix[0];\r\n\r\n        mesh.getWorldMatrix().invertToRef(tm);\r\n\r\n        if (this._tmpRay) {\r\n            Ray.TransformToRef(this, tm, this._tmpRay);\r\n        } else {\r\n            this._tmpRay = Ray.Transform(this, tm);\r\n        }\r\n\r\n        return mesh.intersects(this._tmpRay, fastCheck, trianglePredicate, onlyBoundingInfo, worldToUse, skipBoundingInfo);\r\n    }\r\n\r\n    /**\r\n     * Checks if ray intersects a mesh\r\n     * @param meshes the meshes to check\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @param results array to store result in\r\n     * @returns Array of picking infos\r\n     */\r\n    public intersectsMeshes(meshes: Array<DeepImmutable<AbstractMesh>>, fastCheck?: boolean, results?: Array<PickingInfo>): Array<PickingInfo> {\r\n        if (results) {\r\n            results.length = 0;\r\n        } else {\r\n            results = [];\r\n        }\r\n\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const pickInfo = this.intersectsMesh(meshes[i], fastCheck);\r\n\r\n            if (pickInfo.hit) {\r\n                results.push(pickInfo);\r\n            }\r\n        }\r\n\r\n        results.sort(this._comparePickingInfo);\r\n\r\n        return results;\r\n    }\r\n\r\n    private _comparePickingInfo(pickingInfoA: DeepImmutable<PickingInfo>, pickingInfoB: DeepImmutable<PickingInfo>): number {\r\n        if (pickingInfoA.distance < pickingInfoB.distance) {\r\n            return -1;\r\n        } else if (pickingInfoA.distance > pickingInfoB.distance) {\r\n            return 1;\r\n        } else {\r\n            return 0;\r\n        }\r\n    }\r\n\r\n    private static _Smallnum = 0.00000001;\r\n    private static _Rayl = 10e8;\r\n\r\n    /**\r\n     * Intersection test between the ray and a given segment within a given tolerance (threshold)\r\n     * @param sega the first point of the segment to test the intersection against\r\n     * @param segb the second point of the segment to test the intersection against\r\n     * @param threshold the tolerance margin, if the ray doesn't intersect the segment but is close to the given threshold, the intersection is successful\r\n     * @returns the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection\r\n     */\r\n    intersectionSegment(sega: DeepImmutable<Vector3>, segb: DeepImmutable<Vector3>, threshold: number): number {\r\n        const o = this.origin;\r\n        const u = TmpVectors.Vector3[0];\r\n        const rsegb = TmpVectors.Vector3[1];\r\n        const v = TmpVectors.Vector3[2];\r\n        const w = TmpVectors.Vector3[3];\r\n\r\n        segb.subtractToRef(sega, u);\r\n\r\n        this.direction.scaleToRef(Ray._Rayl, v);\r\n        o.addToRef(v, rsegb);\r\n\r\n        sega.subtractToRef(o, w);\r\n\r\n        const a = Vector3.Dot(u, u); // always >= 0\r\n        const b = Vector3.Dot(u, v);\r\n        const c = Vector3.Dot(v, v); // always >= 0\r\n        const d = Vector3.Dot(u, w);\r\n        const e = Vector3.Dot(v, w);\r\n        const discriminant = a * c - b * b; // always >= 0\r\n        let sN: number,\r\n            sD = discriminant; // sc = sN / sD, default sD = D >= 0\r\n        let tN: number,\r\n            tD = discriminant; // tc = tN / tD, default tD = D >= 0\r\n\r\n        // compute the line parameters of the two closest points\r\n        if (discriminant < Ray._Smallnum) {\r\n            // the lines are almost parallel\r\n            sN = 0.0; // force using point P0 on segment S1\r\n            sD = 1.0; // to prevent possible division by 0.0 later\r\n            tN = e;\r\n            tD = c;\r\n        } else {\r\n            // get the closest points on the infinite lines\r\n            sN = b * e - c * d;\r\n            tN = a * e - b * d;\r\n            if (sN < 0.0) {\r\n                // sc < 0 => the s=0 edge is visible\r\n                sN = 0.0;\r\n                tN = e;\r\n                tD = c;\r\n            } else if (sN > sD) {\r\n                // sc > 1 => the s=1 edge is visible\r\n                sN = sD;\r\n                tN = e + b;\r\n                tD = c;\r\n            }\r\n        }\r\n\r\n        if (tN < 0.0) {\r\n            // tc < 0 => the t=0 edge is visible\r\n            tN = 0.0;\r\n            // recompute sc for this edge\r\n            if (-d < 0.0) {\r\n                sN = 0.0;\r\n            } else if (-d > a) {\r\n                sN = sD;\r\n            } else {\r\n                sN = -d;\r\n                sD = a;\r\n            }\r\n        } else if (tN > tD) {\r\n            // tc > 1 => the t=1 edge is visible\r\n            tN = tD;\r\n            // recompute sc for this edge\r\n            if (-d + b < 0.0) {\r\n                sN = 0;\r\n            } else if (-d + b > a) {\r\n                sN = sD;\r\n            } else {\r\n                sN = -d + b;\r\n                sD = a;\r\n            }\r\n        }\r\n        // finally do the division to get sc and tc\r\n        const sc = Math.abs(sN) < Ray._Smallnum ? 0.0 : sN / sD;\r\n        const tc = Math.abs(tN) < Ray._Smallnum ? 0.0 : tN / tD;\r\n\r\n        // get the difference of the two closest points\r\n        const qtc = TmpVectors.Vector3[4];\r\n        v.scaleToRef(tc, qtc);\r\n        const qsc = TmpVectors.Vector3[5];\r\n        u.scaleToRef(sc, qsc);\r\n        qsc.addInPlace(w);\r\n        const dP = TmpVectors.Vector3[6];\r\n        qsc.subtractToRef(qtc, dP); // = S1(sc) - S2(tc)\r\n\r\n        const isIntersected = tc > 0 && tc <= this.length && dP.lengthSquared() < threshold * threshold; // return intersection result\r\n\r\n        if (isIntersected) {\r\n            return qsc.length();\r\n        }\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Update the ray from viewport position\r\n     * @param x position\r\n     * @param y y position\r\n     * @param viewportWidth viewport width\r\n     * @param viewportHeight viewport height\r\n     * @param world world matrix\r\n     * @param view view matrix\r\n     * @param projection projection matrix\r\n     * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\r\n     * @returns this ray updated\r\n     */\r\n    public update(\r\n        x: number,\r\n        y: number,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>,\r\n        enableDistantPicking: boolean = false\r\n    ): Ray {\r\n        if (enableDistantPicking) {\r\n            // With world matrices having great values (like 8000000000 on 1 or more scaling or position axis),\r\n            // multiplying view/projection/world and doing invert will result in loss of float precision in the matrix.\r\n            // One way to fix it is to compute the ray with world at identity then transform the ray in object space.\r\n            // This is slower (2 matrix inverts instead of 1) but precision is preserved.\r\n            // This is hidden behind `EnableDistantPicking` flag (default is false)\r\n            if (!Ray._RayDistant) {\r\n                Ray._RayDistant = Ray.Zero();\r\n            }\r\n\r\n            Ray._RayDistant.unprojectRayToRef(x, y, viewportWidth, viewportHeight, Matrix.IdentityReadOnly, view, projection);\r\n\r\n            const tm = TmpVectors.Matrix[0];\r\n            world.invertToRef(tm);\r\n            Ray.TransformToRef(Ray._RayDistant, tm, this);\r\n        } else {\r\n            this.unprojectRayToRef(x, y, viewportWidth, viewportHeight, world, view, projection);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Creates a ray with origin and direction of 0,0,0\r\n     * @returns the new ray\r\n     */\r\n    public static Zero(): Ray {\r\n        return new Ray(Vector3.Zero(), Vector3.Zero());\r\n    }\r\n\r\n    /**\r\n     * Creates a new ray from screen space and viewport\r\n     * @param x position\r\n     * @param y y position\r\n     * @param viewportWidth viewport width\r\n     * @param viewportHeight viewport height\r\n     * @param world world matrix\r\n     * @param view view matrix\r\n     * @param projection projection matrix\r\n     * @returns new ray\r\n     */\r\n    public static CreateNew(\r\n        x: number,\r\n        y: number,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>\r\n    ): Ray {\r\n        const result = Ray.Zero();\r\n\r\n        return result.update(x, y, viewportWidth, viewportHeight, world, view, projection);\r\n    }\r\n\r\n    /**\r\n     * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be\r\n     * transformed to the given world matrix.\r\n     * @param origin The origin point\r\n     * @param end The end point\r\n     * @param world a matrix to transform the ray to. Default is the identity matrix.\r\n     * @returns the new ray\r\n     */\r\n    public static CreateNewFromTo(origin: Vector3, end: Vector3, world: DeepImmutable<Matrix> = Matrix.IdentityReadOnly): Ray {\r\n        const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\r\n        return Ray.CreateFromToToRef(origin, end, result, world);\r\n    }\r\n\r\n    /**\r\n     * Function will update a transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be\r\n     * transformed to the given world matrix.\r\n     * @param origin The origin point\r\n     * @param end The end point\r\n     * @param result the object to store the result\r\n     * @param world a matrix to transform the ray to. Default is the identity matrix.\r\n     * @returns the ref ray\r\n     */\r\n    public static CreateFromToToRef(origin: Vector3, end: Vector3, result: Ray, world: DeepImmutable<Matrix> = Matrix.IdentityReadOnly): Ray {\r\n        result.origin.copyFrom(origin);\r\n        const direction = end.subtractToRef(origin, result.direction);\r\n        const length = Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);\r\n        result.length = length;\r\n        result.direction.normalize();\r\n\r\n        return Ray.TransformToRef(result, world, result);\r\n    }\r\n\r\n    /**\r\n     * Transforms a ray by a matrix\r\n     * @param ray ray to transform\r\n     * @param matrix matrix to apply\r\n     * @returns the resulting new ray\r\n     */\r\n    public static Transform(ray: DeepImmutable<Ray>, matrix: DeepImmutable<Matrix>): Ray {\r\n        const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\r\n        Ray.TransformToRef(ray, matrix, result);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Transforms a ray by a matrix\r\n     * @param ray ray to transform\r\n     * @param matrix matrix to apply\r\n     * @param result ray to store result in\r\n     * @returns the updated result ray\r\n     */\r\n    public static TransformToRef(ray: DeepImmutable<Ray>, matrix: DeepImmutable<Matrix>, result: Ray): Ray {\r\n        Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);\r\n        Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);\r\n        result.length = ray.length;\r\n        result.epsilon = ray.epsilon;\r\n\r\n        const dir = result.direction;\r\n        const len = dir.length();\r\n\r\n        if (!(len === 0 || len === 1)) {\r\n            const num = 1.0 / len;\r\n            dir.x *= num;\r\n            dir.y *= num;\r\n            dir.z *= num;\r\n            result.length *= len;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Unproject a ray from screen space to object space\r\n     * @param sourceX defines the screen space x coordinate to use\r\n     * @param sourceY defines the screen space y coordinate to use\r\n     * @param viewportWidth defines the current width of the viewport\r\n     * @param viewportHeight defines the current height of the viewport\r\n     * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n     * @param view defines the view matrix to use\r\n     * @param projection defines the projection matrix to use\r\n     */\r\n    public unprojectRayToRef(\r\n        sourceX: float,\r\n        sourceY: float,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        world: DeepImmutable<Matrix>,\r\n        view: DeepImmutable<Matrix>,\r\n        projection: DeepImmutable<Matrix>\r\n    ): void {\r\n        const matrix = TmpVectors.Matrix[0];\r\n        world.multiplyToRef(view, matrix);\r\n        matrix.multiplyToRef(projection, matrix);\r\n        matrix.invert();\r\n\r\n        const engine = EngineStore.LastCreatedEngine;\r\n        const nearScreenSource = TmpVectors.Vector3[0];\r\n        nearScreenSource.x = (sourceX / viewportWidth) * 2 - 1;\r\n        nearScreenSource.y = -((sourceY / viewportHeight) * 2 - 1);\r\n        nearScreenSource.z = engine?.useReverseDepthBuffer ? 1 : engine?.isNDCHalfZRange ? 0 : -1;\r\n\r\n        // far Z need to be close but < to 1 or camera projection matrix with maxZ = 0 will NaN\r\n        const farScreenSource = TmpVectors.Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0 - 1e-8);\r\n        const nearVec3 = TmpVectors.Vector3[2];\r\n        const farVec3 = TmpVectors.Vector3[3];\r\n        Vector3.TransformCoordinatesToRef(nearScreenSource, matrix, nearVec3);\r\n        Vector3.TransformCoordinatesToRef(farScreenSource, matrix, farVec3);\r\n\r\n        this.origin.copyFrom(nearVec3);\r\n        farVec3.subtractToRef(nearVec3, this.direction);\r\n        this.direction.normalize();\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a ray that can be used to pick in the scene\r\n * @param scene defines the scene to use for the picking\r\n * @param x defines the x coordinate of the origin (on-screen)\r\n * @param y defines the y coordinate of the origin (on-screen)\r\n * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\r\n * @param camera defines the camera to use for the picking\r\n * @param cameraViewSpace defines if picking will be done in view space (false by default)\r\n * @returns a Ray\r\n */\r\nexport function CreatePickingRay(scene: Scene, x: number, y: number, world: Nullable<Matrix>, camera: Nullable<Camera>, cameraViewSpace = false): Ray {\r\n    const result = Ray.Zero();\r\n\r\n    CreatePickingRayToRef(scene, x, y, world, result, camera, cameraViewSpace);\r\n\r\n    return result;\r\n}\r\n\r\n/**\r\n * Creates a ray that can be used to pick in the scene\r\n * @param scene defines the scene to use for the picking\r\n * @param x defines the x coordinate of the origin (on-screen)\r\n * @param y defines the y coordinate of the origin (on-screen)\r\n * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\r\n * @param result defines the ray where to store the picking ray\r\n * @param camera defines the camera to use for the picking\r\n * @param cameraViewSpace defines if picking will be done in view space (false by default)\r\n * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\r\n * @returns the current scene\r\n */\r\nexport function CreatePickingRayToRef(\r\n    scene: Scene,\r\n    x: number,\r\n    y: number,\r\n    world: Nullable<Matrix>,\r\n    result: Ray,\r\n    camera: Nullable<Camera>,\r\n    cameraViewSpace = false,\r\n    enableDistantPicking = false\r\n): Scene {\r\n    const engine = scene.getEngine();\r\n\r\n    if (!camera && !(camera = scene.activeCamera!) && !(camera = scene.cameraToUseForPointers)) {\r\n        return scene;\r\n    }\r\n\r\n    const cameraViewport = camera.viewport;\r\n    const renderHeight = engine.getRenderHeight();\r\n    const { x: vx, y: vy, width, height } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);\r\n\r\n    // Moving coordinates to local viewport world\r\n    const levelInv = 1 / engine.getHardwareScalingLevel();\r\n    x = x * levelInv - vx;\r\n    y = y * levelInv - (renderHeight - vy - height);\r\n\r\n    result.update(\r\n        x,\r\n        y,\r\n        width,\r\n        height,\r\n        world ? world : Matrix.IdentityReadOnly,\r\n        cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(),\r\n        camera.getProjectionMatrix(),\r\n        enableDistantPicking\r\n    );\r\n    return scene;\r\n}\r\n\r\n/**\r\n * Creates a ray that can be used to pick in the scene\r\n * @param scene defines the scene to use for the picking\r\n * @param x defines the x coordinate of the origin (on-screen)\r\n * @param y defines the y coordinate of the origin (on-screen)\r\n * @param camera defines the camera to use for the picking\r\n * @returns a Ray\r\n */\r\nexport function CreatePickingRayInCameraSpace(scene: Scene, x: number, y: number, camera?: Camera): Ray {\r\n    const result = Ray.Zero();\r\n\r\n    CreatePickingRayInCameraSpaceToRef(scene, x, y, result, camera);\r\n\r\n    return result;\r\n}\r\n\r\n/**\r\n * Creates a ray that can be used to pick in the scene\r\n * @param scene defines the scene to use for the picking\r\n * @param x defines the x coordinate of the origin (on-screen)\r\n * @param y defines the y coordinate of the origin (on-screen)\r\n * @param result defines the ray where to store the picking ray\r\n * @param camera defines the camera to use for the picking\r\n * @returns the current scene\r\n */\r\nexport function CreatePickingRayInCameraSpaceToRef(scene: Scene, x: number, y: number, result: Ray, camera?: Camera): Scene {\r\n    if (!PickingInfo) {\r\n        return scene;\r\n    }\r\n\r\n    const engine = scene.getEngine();\r\n\r\n    if (!camera && !(camera = scene.activeCamera!) && !(camera = scene.cameraToUseForPointers!)) {\r\n        throw new Error(\"Active camera not set\");\r\n    }\r\n\r\n    const cameraViewport = camera.viewport;\r\n    const renderHeight = engine.getRenderHeight();\r\n    const { x: vx, y: vy, width, height } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);\r\n    const identity = Matrix.Identity();\r\n\r\n    // Moving coordinates to local viewport world\r\n    const levelInv = 1 / engine.getHardwareScalingLevel();\r\n    x = x * levelInv - vx;\r\n    y = y * levelInv - (renderHeight - vy - height);\r\n    result.update(x, y, width, height, identity, identity, camera.getProjectionMatrix());\r\n    return scene;\r\n}\r\n\r\nfunction InternalPickForMesh(\r\n    pickingInfo: Nullable<PickingInfo>,\r\n    rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray,\r\n    mesh: AbstractMesh,\r\n    world: Matrix,\r\n    fastCheck?: boolean,\r\n    onlyBoundingInfo?: boolean,\r\n    trianglePredicate?: TrianglePickingPredicate,\r\n    skipBoundingInfo?: boolean\r\n) {\r\n    const ray = rayFunction(world, mesh.enableDistantPicking);\r\n\r\n    return InternalPickForMeshWithRay(pickingInfo, mesh, world, ray, fastCheck, onlyBoundingInfo, trianglePredicate, skipBoundingInfo);\r\n}\r\n\r\n// Used when a caller already has the mesh-local ray and wants to avoid rebuilding it through rayFunction.\r\nfunction InternalPickForMeshWithRay(\r\n    pickingInfo: Nullable<PickingInfo>,\r\n    mesh: AbstractMesh,\r\n    world: Matrix,\r\n    ray: Ray,\r\n    fastCheck?: boolean,\r\n    onlyBoundingInfo?: boolean,\r\n    trianglePredicate?: TrianglePickingPredicate,\r\n    skipBoundingInfo?: boolean\r\n) {\r\n    const result = mesh.intersects(ray, fastCheck, trianglePredicate, onlyBoundingInfo, world, skipBoundingInfo);\r\n    if (!result || !result.hit) {\r\n        return null;\r\n    }\r\n\r\n    if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {\r\n        return null;\r\n    }\r\n\r\n    return result;\r\n}\r\n\r\nfunction GetThinInstancePickingIntersectionThreshold(className: string, mesh: AbstractMesh): number {\r\n    return className === \"InstancedLinesMesh\" || className === \"LinesMesh\" ? (mesh as any).intersectionThreshold : 0;\r\n}\r\n\r\nfunction GetThinInstanceRawBoundingInfo(mesh: AbstractMesh): { rawBoundingInfo: Nullable<BoundingInfo>; intersectionThreshold: number } {\r\n    const className = mesh.getClassName();\r\n\r\n    // GreasedLineMesh has a custom width-aware pick path, so the generic raw sphere+box precheck is not safe there.\r\n    if (className === \"GreasedLineMesh\") {\r\n        return { rawBoundingInfo: null, intersectionThreshold: 0 };\r\n    }\r\n\r\n    const rawBoundingInfo = mesh.rawBoundingInfo;\r\n\r\n    return { rawBoundingInfo, intersectionThreshold: rawBoundingInfo ? GetThinInstancePickingIntersectionThreshold(className, mesh) : 0 };\r\n}\r\n\r\n// Returns null when the raw-bounds precheck rejects; otherwise returns the mesh-local thin-instance ray to reuse downstream.\r\nfunction ThinInstanceIntersectsRawBoundingInfo(\r\n    rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray,\r\n    mesh: AbstractMesh,\r\n    world: Matrix,\r\n    rawBoundingInfo: BoundingInfo,\r\n    intersectionThreshold: number\r\n): Nullable<Ray> {\r\n    const ray = rayFunction(world, mesh.enableDistantPicking);\r\n\r\n    if (!ray.intersectsSphere(rawBoundingInfo.boundingSphere, intersectionThreshold) || !ray.intersectsBox(rawBoundingInfo.boundingBox, intersectionThreshold)) {\r\n        return null;\r\n    }\r\n\r\n    return ray;\r\n}\r\n\r\nfunction InternalPick(\r\n    scene: Scene,\r\n    rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray,\r\n    predicate?: MeshPredicate,\r\n    fastCheck?: boolean,\r\n    onlyBoundingInfo?: boolean,\r\n    trianglePredicate?: TrianglePickingPredicate\r\n): PickingInfo {\r\n    let pickingInfo = null;\r\n\r\n    const computeWorldMatrixForCamera = !!(scene.activeCameras && scene.activeCameras.length > 1 && scene.cameraToUseForPointers !== scene.activeCamera);\r\n    const currentCamera = scene.cameraToUseForPointers || scene.activeCamera;\r\n    const picker = PickingCustomization.internalPickerForMesh || InternalPickForMesh;\r\n    const useFastPath = picker === InternalPickForMesh;\r\n\r\n    for (let meshIndex = 0; meshIndex < scene.meshes.length; meshIndex++) {\r\n        const mesh = scene.meshes[meshIndex];\r\n\r\n        if (predicate) {\r\n            if (!predicate(mesh, -1)) {\r\n                continue;\r\n            }\r\n        } else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {\r\n            continue;\r\n        }\r\n\r\n        const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();\r\n        const world = mesh.computeWorldMatrix(forceCompute, currentCamera);\r\n\r\n        if (mesh.hasThinInstances && (mesh as Mesh).thinInstanceEnablePicking) {\r\n            // first check if the ray intersects the whole bounding box/sphere of the mesh\r\n            const result = picker(pickingInfo, rayFunction, mesh, world, true, true, trianglePredicate);\r\n            if (result) {\r\n                if (onlyBoundingInfo) {\r\n                    // the user only asked for a bounding info check so we can return\r\n                    return result;\r\n                }\r\n                const { rawBoundingInfo: thinInstanceRawBoundingInfo, intersectionThreshold: thinInstanceIntersectionThreshold } = GetThinInstanceRawBoundingInfo(mesh);\r\n                const thinMatrixData = (mesh as Mesh)._thinInstanceDataStorage.matrixData;\r\n                if (thinMatrixData) {\r\n                    const thinMatrix = TmpVectors.Matrix[0];\r\n                    const combinedWorld = TmpVectors.Matrix[1];\r\n                    const instancesCount = Math.min((mesh as Mesh).thinInstanceCount, thinMatrixData.length >> 4);\r\n                    for (let index = 0; index < instancesCount; index++) {\r\n                        if (predicate && !predicate(mesh, index)) {\r\n                            continue;\r\n                        }\r\n                        Matrix.FromArrayToRef(thinMatrixData, index << 4, thinMatrix);\r\n                        thinMatrix.multiplyToRef(world, combinedWorld);\r\n                        const thinInstanceRay =\r\n                            useFastPath && thinInstanceRawBoundingInfo\r\n                                ? ThinInstanceIntersectsRawBoundingInfo(rayFunction, mesh, combinedWorld, thinInstanceRawBoundingInfo, thinInstanceIntersectionThreshold)\r\n                                : null;\r\n\r\n                        if (useFastPath && thinInstanceRawBoundingInfo && !thinInstanceRay) {\r\n                            continue;\r\n                        }\r\n\r\n                        const result: Nullable<PickingInfo> =\r\n                            useFastPath && thinInstanceRay\r\n                                ? InternalPickForMeshWithRay(pickingInfo, mesh, combinedWorld, thinInstanceRay, fastCheck, onlyBoundingInfo, trianglePredicate, true)\r\n                                : picker(pickingInfo, rayFunction, mesh, combinedWorld, fastCheck, onlyBoundingInfo, trianglePredicate, true);\r\n\r\n                        if (result) {\r\n                            pickingInfo = result;\r\n                            pickingInfo.thinInstanceIndex = index;\r\n\r\n                            if (fastCheck) {\r\n                                return pickingInfo;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const result = picker(pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate);\r\n\r\n            if (result) {\r\n                pickingInfo = result;\r\n\r\n                if (fastCheck) {\r\n                    return pickingInfo;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    return pickingInfo || new PickingInfo();\r\n}\r\n\r\nfunction InternalMultiPick(\r\n    scene: Scene,\r\n    rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray,\r\n    predicate?: MeshPredicate,\r\n    trianglePredicate?: TrianglePickingPredicate\r\n): Nullable<PickingInfo[]> {\r\n    if (!PickingInfo) {\r\n        return null;\r\n    }\r\n    const pickingInfos: PickingInfo[] = [];\r\n    const computeWorldMatrixForCamera = !!(scene.activeCameras && scene.activeCameras.length > 1 && scene.cameraToUseForPointers !== scene.activeCamera);\r\n    const currentCamera = scene.cameraToUseForPointers || scene.activeCamera;\r\n    const picker = PickingCustomization.internalPickerForMesh || InternalPickForMesh;\r\n    const useFastPath = picker === InternalPickForMesh;\r\n\r\n    for (let meshIndex = 0; meshIndex < scene.meshes.length; meshIndex++) {\r\n        const mesh = scene.meshes[meshIndex];\r\n\r\n        if (predicate) {\r\n            if (!predicate(mesh, -1)) {\r\n                continue;\r\n            }\r\n        } else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {\r\n            continue;\r\n        }\r\n\r\n        const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();\r\n        const world = mesh.computeWorldMatrix(forceCompute, currentCamera);\r\n\r\n        if (mesh.hasThinInstances && (mesh as Mesh).thinInstanceEnablePicking) {\r\n            const result = picker(null, rayFunction, mesh, world, true, true, trianglePredicate);\r\n            if (result) {\r\n                const { rawBoundingInfo: thinInstanceRawBoundingInfo, intersectionThreshold: thinInstanceIntersectionThreshold } = GetThinInstanceRawBoundingInfo(mesh);\r\n                const thinMatrixData = (mesh as Mesh)._thinInstanceDataStorage.matrixData;\r\n                if (thinMatrixData) {\r\n                    const thinMatrix = TmpVectors.Matrix[0];\r\n                    const combinedWorld = TmpVectors.Matrix[1];\r\n                    const instancesCount = Math.min((mesh as Mesh).thinInstanceCount, thinMatrixData.length >> 4);\r\n                    for (let index = 0; index < instancesCount; index++) {\r\n                        if (predicate && !predicate(mesh, index)) {\r\n                            continue;\r\n                        }\r\n                        Matrix.FromArrayToRef(thinMatrixData, index << 4, thinMatrix);\r\n                        thinMatrix.multiplyToRef(world, combinedWorld);\r\n                        const thinInstanceRay =\r\n                            useFastPath && thinInstanceRawBoundingInfo\r\n                                ? ThinInstanceIntersectsRawBoundingInfo(rayFunction, mesh, combinedWorld, thinInstanceRawBoundingInfo, thinInstanceIntersectionThreshold)\r\n                                : null;\r\n\r\n                        if (useFastPath && thinInstanceRawBoundingInfo && !thinInstanceRay) {\r\n                            continue;\r\n                        }\r\n\r\n                        const result: Nullable<PickingInfo> =\r\n                            useFastPath && thinInstanceRay\r\n                                ? InternalPickForMeshWithRay(null, mesh, combinedWorld, thinInstanceRay, false, false, trianglePredicate, true)\r\n                                : picker(null, rayFunction, mesh, combinedWorld, false, false, trianglePredicate, true);\r\n\r\n                        if (result) {\r\n                            result.thinInstanceIndex = index;\r\n                            pickingInfos.push(result);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const result = picker(null, rayFunction, mesh, world, false, false, trianglePredicate);\r\n\r\n            if (result) {\r\n                pickingInfos.push(result);\r\n            }\r\n        }\r\n    }\r\n\r\n    return pickingInfos;\r\n}\r\n\r\n/** Launch a ray to try to pick a mesh in the scene using only bounding information of the main mesh (not using submeshes)\r\n * @param scene defines the scene to use for the picking\r\n * @param x position on screen\r\n * @param y position on screen\r\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\r\n * @returns a PickingInfo (Please note that some info will not be set like distance, bv, bu and everything that cannot be capture by only using bounding infos)\r\n */\r\nexport function PickWithBoundingInfo(scene: Scene, x: number, y: number, predicate?: MeshPredicate, fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {\r\n    if (!PickingInfo) {\r\n        return null;\r\n    }\r\n    const result = InternalPick(\r\n        scene,\r\n        (world) => {\r\n            if (!scene._tempPickingRay) {\r\n                scene._tempPickingRay = Ray.Zero();\r\n            }\r\n\r\n            CreatePickingRayToRef(scene, x, y, world, scene._tempPickingRay, camera || null);\r\n            return scene._tempPickingRay;\r\n        },\r\n        predicate,\r\n        fastCheck,\r\n        true\r\n    );\r\n    if (result) {\r\n        result.ray = CreatePickingRay(scene, x, y, Matrix.Identity(), camera || null);\r\n    }\r\n    return result;\r\n}\r\n\r\n/** Launch a ray to try to pick a mesh in the scene\r\n * @param scene defines the scene to use for the picking\r\n * @param x position on screen\r\n * @param y position on screen\r\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\r\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n * @param _enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\r\n * @returns a PickingInfo\r\n */\r\nexport function Pick(\r\n    scene: Scene,\r\n    x: number,\r\n    y: number,\r\n    predicate?: MeshPredicate,\r\n    fastCheck?: boolean,\r\n    camera?: Nullable<Camera>,\r\n    trianglePredicate?: TrianglePickingPredicate,\r\n    _enableDistantPicking = false\r\n): PickingInfo {\r\n    const result = InternalPick(\r\n        scene,\r\n        (world, enableDistantPicking) => {\r\n            if (!scene._tempPickingRay) {\r\n                scene._tempPickingRay = Ray.Zero();\r\n            }\r\n\r\n            CreatePickingRayToRef(scene, x, y, world, scene._tempPickingRay, camera || null, false, enableDistantPicking);\r\n            return scene._tempPickingRay;\r\n        },\r\n        predicate,\r\n        fastCheck,\r\n        false,\r\n        trianglePredicate\r\n    );\r\n    if (result) {\r\n        result.ray = CreatePickingRay(scene, x, y, Matrix.Identity(), camera || null);\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * Use the given ray to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\r\n * irrespective of orientation.\r\n * @param scene defines the scene to use for the picking\r\n * @param ray The ray to use to pick meshes\r\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must have isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n * @returns a PickingInfo\r\n */\r\nexport function PickWithRay(scene: Scene, ray: Ray, predicate?: MeshPredicate, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {\r\n    const result = InternalPick(\r\n        scene,\r\n        (world) => {\r\n            if (!scene._pickWithRayInverseMatrix) {\r\n                scene._pickWithRayInverseMatrix = Matrix.Identity();\r\n            }\r\n            world.invertToRef(scene._pickWithRayInverseMatrix);\r\n\r\n            if (!scene._cachedRayForTransform) {\r\n                scene._cachedRayForTransform = Ray.Zero();\r\n            }\r\n\r\n            Ray.TransformToRef(ray, scene._pickWithRayInverseMatrix, scene._cachedRayForTransform);\r\n            return scene._cachedRayForTransform;\r\n        },\r\n        predicate,\r\n        fastCheck,\r\n        false,\r\n        trianglePredicate\r\n    );\r\n    if (result) {\r\n        result.ray = ray;\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * Launch a ray to try to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\r\n * irrespective of orientation.\r\n * @param scene defines the scene to use for the picking\r\n * @param x X position on screen\r\n * @param y Y position on screen\r\n * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n * @param camera camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\r\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n * @returns an array of PickingInfo\r\n */\r\nexport function MultiPick(scene: Scene, x: number, y: number, predicate?: MeshPredicate, camera?: Camera, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {\r\n    return InternalMultiPick(scene, (world) => CreatePickingRay(scene, x, y, world, camera || null), predicate, trianglePredicate);\r\n}\r\n\r\n/**\r\n * Launch a ray to try to pick a mesh in the scene\r\n * @param scene defines the scene to use for the picking\r\n * @param ray Ray to use\r\n * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\r\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\r\n * @returns an array of PickingInfo\r\n */\r\nexport function MultiPickWithRay(scene: Scene, ray: Ray, predicate?: MeshPredicate, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {\r\n    return InternalMultiPick(\r\n        scene,\r\n        (world) => {\r\n            if (!scene._pickWithRayInverseMatrix) {\r\n                scene._pickWithRayInverseMatrix = Matrix.Identity();\r\n            }\r\n            world.invertToRef(scene._pickWithRayInverseMatrix);\r\n\r\n            if (!scene._cachedRayForTransform) {\r\n                scene._cachedRayForTransform = Ray.Zero();\r\n            }\r\n\r\n            Ray.TransformToRef(ray, scene._pickWithRayInverseMatrix, scene._cachedRayForTransform);\r\n            return scene._cachedRayForTransform;\r\n        },\r\n        predicate,\r\n        trianglePredicate\r\n    );\r\n}\r\n\r\n/**\r\n * Gets a ray in the forward direction from the camera.\r\n * @param camera Defines the camera to use to get the ray from\r\n * @param length Defines the length of the ray to create\r\n * @param transform Defines the transform to apply to the ray, by default the world matrix is used to create a workd space ray\r\n * @param origin Defines the start point of the ray which defaults to the camera position\r\n * @returns the forward ray\r\n */\r\nexport function GetForwardRay(camera: Camera, length = 100, transform?: Matrix, origin?: Vector3): Ray {\r\n    return GetForwardRayToRef(camera, new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);\r\n}\r\n\r\n/**\r\n * Gets a ray in the forward direction from the camera.\r\n * @param camera Defines the camera to use to get the ray from\r\n * @param refRay the ray to (re)use when setting the values\r\n * @param length Defines the length of the ray to create\r\n * @param transform Defines the transform to apply to the ray, by default the world matrx is used to create a workd space ray\r\n * @param origin Defines the start point of the ray which defaults to the camera position\r\n * @returns the forward ray\r\n */\r\nexport function GetForwardRayToRef(camera: Camera, refRay: Ray, length = 100, transform?: Matrix, origin?: Vector3): Ray {\r\n    if (!transform) {\r\n        transform = camera.getWorldMatrix();\r\n    }\r\n    refRay.length = length;\r\n\r\n    if (origin) {\r\n        refRay.origin.copyFrom(origin);\r\n    } else {\r\n        refRay.origin.copyFrom(camera.position);\r\n    }\r\n    const forward = TmpVectors.Vector3[2];\r\n    forward.set(0, 0, camera._scene.useRightHandedSystem ? -1 : 1);\r\n    const worldForward = TmpVectors.Vector3[3];\r\n    Vector3.TransformNormalToRef(forward, transform, worldForward);\r\n    Vector3.NormalizeToRef(worldForward, refRay.direction);\r\n\r\n    return refRay;\r\n}\r\n\r\n/**\r\n * Initialize the minimal interdependecies between the Ray and Scene and Camera\r\n * @param sceneClass defines the scene prototype to use\r\n * @param cameraClass defines the camera prototype to use\r\n */\r\nexport function AddRayExtensions(sceneClass: typeof Scene, cameraClass: typeof Camera): void {\r\n    if (cameraClass) {\r\n        cameraClass.prototype.getForwardRay = function (length = 100, transform?: Matrix, origin?: Vector3): Ray {\r\n            return GetForwardRayToRef(this, new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);\r\n        };\r\n\r\n        cameraClass.prototype.getForwardRayToRef = function (refRay: Ray, length = 100, transform?: Matrix, origin?: Vector3): Ray {\r\n            return GetForwardRayToRef(this, refRay, length, transform, origin);\r\n        };\r\n    }\r\n\r\n    if (!sceneClass) {\r\n        return;\r\n    }\r\n\r\n    _ImportHelper._IsPickingAvailable = true;\r\n\r\n    sceneClass.prototype.createPickingRay = function (x: number, y: number, world: Nullable<Matrix>, camera: Nullable<Camera>, cameraViewSpace = false): Ray {\r\n        return CreatePickingRay(this, x, y, world, camera, cameraViewSpace);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport {\r\n    type MeshPredicate,\r\n    type TrianglePickingPredicate,\r\n    type Ray,\r\n    AddRayExtensions,\r\n    CreatePickingRayInCameraSpace,\r\n    CreatePickingRayInCameraSpaceToRef,\r\n    CreatePickingRayToRef,\r\n    MultiPick,\r\n    MultiPickWithRay,\r\n    Pick,\r\n    PickWithBoundingInfo,\r\n    PickWithRay,\r\n} from \"./ray.core\";\r\n\r\nexport * from \"./ray.core\";\r\n\r\nexport {};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ray.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRay(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Picking\r\n    AddRayExtensions(Scene, Camera);\r\n\r\n    Scene.prototype.createPickingRayToRef = function (\r\n        x: number,\r\n        y: number,\r\n        world: Nullable<Matrix>,\r\n        result: Ray,\r\n        camera: Nullable<Camera>,\r\n        cameraViewSpace = false,\r\n        enableDistantPicking = false\r\n    ): Scene {\r\n        return CreatePickingRayToRef(this, x, y, world, result, camera, cameraViewSpace, enableDistantPicking);\r\n    };\r\n\r\n    Scene.prototype.createPickingRayInCameraSpace = function (x: number, y: number, camera?: Camera): Ray {\r\n        return CreatePickingRayInCameraSpace(this, x, y, camera);\r\n    };\r\n\r\n    Scene.prototype.createPickingRayInCameraSpaceToRef = function (x: number, y: number, result: Ray, camera?: Camera): Scene {\r\n        return CreatePickingRayInCameraSpaceToRef(this, x, y, result, camera);\r\n    };\r\n\r\n    Scene.prototype.pickWithBoundingInfo = function (x: number, y: number, predicate?: MeshPredicate, fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {\r\n        return PickWithBoundingInfo(this, x, y, predicate, fastCheck, camera);\r\n    };\r\n\r\n    Scene.prototype.pick = function (\r\n        x: number,\r\n        y: number,\r\n        predicate?: MeshPredicate,\r\n        fastCheck?: boolean,\r\n        camera?: Nullable<Camera>,\r\n        trianglePredicate?: TrianglePickingPredicate,\r\n        _enableDistantPicking = false\r\n    ): PickingInfo {\r\n        return Pick(this, x, y, predicate, fastCheck, camera, trianglePredicate, _enableDistantPicking);\r\n    };\r\n\r\n    Scene.prototype.pickWithRay = function (ray: Ray, predicate?: MeshPredicate, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {\r\n        return PickWithRay(this, ray, predicate, fastCheck, trianglePredicate);\r\n    };\r\n\r\n    Scene.prototype.multiPick = function (x: number, y: number, predicate?: MeshPredicate, camera?: Camera, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {\r\n        return MultiPick(this, x, y, predicate, camera, trianglePredicate);\r\n    };\r\n\r\n    Scene.prototype.multiPickWithRay = function (ray: Ray, predicate?: MeshPredicate, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {\r\n        return MultiPickWithRay(this, ray, predicate, trianglePredicate);\r\n    };\r\n}\r\n","import { Vector3, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\n\r\n/**\r\n * Class containing a set of static utilities functions for managing Pivots\r\n * @internal\r\n */\r\nexport class PivotTools {\r\n    // Stores the state of the pivot cache (_oldPivotPoint, _pivotTranslation)\r\n    // store/remove pivot point should only be applied during their outermost calls\r\n    private static _PivotCached = 0;\r\n    private static _OldPivotPoint = new Vector3();\r\n    private static _PivotTranslation = new Vector3();\r\n    private static _PivotTmpVector = new Vector3();\r\n    private static _PivotPostMultiplyPivotMatrix = false;\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _RemoveAndStorePivotPoint(mesh: TransformNode) {\r\n        if (mesh && PivotTools._PivotCached === 0) {\r\n            // Save old pivot and set pivot to 0,0,0\r\n            mesh.getPivotPointToRef(PivotTools._OldPivotPoint);\r\n            PivotTools._PivotPostMultiplyPivotMatrix = mesh._postMultiplyPivotMatrix;\r\n            if (!PivotTools._OldPivotPoint.equalsToFloats(0, 0, 0)) {\r\n                mesh.setPivotMatrix(Matrix.IdentityReadOnly);\r\n                PivotTools._OldPivotPoint.subtractToRef(mesh.getPivotPoint(), PivotTools._PivotTranslation);\r\n                PivotTools._PivotTmpVector.copyFromFloats(1, 1, 1);\r\n                PivotTools._PivotTmpVector.subtractInPlace(mesh.scaling);\r\n                PivotTools._PivotTmpVector.multiplyInPlace(PivotTools._PivotTranslation);\r\n                mesh.position.addInPlace(PivotTools._PivotTmpVector);\r\n            }\r\n        }\r\n        PivotTools._PivotCached++;\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _RestorePivotPoint(mesh: TransformNode) {\r\n        if (mesh && !PivotTools._OldPivotPoint.equalsToFloats(0, 0, 0) && PivotTools._PivotCached === 1) {\r\n            mesh.setPivotPoint(PivotTools._OldPivotPoint);\r\n            mesh._postMultiplyPivotMatrix = PivotTools._PivotPostMultiplyPivotMatrix;\r\n            PivotTools._PivotTmpVector.copyFromFloats(1, 1, 1);\r\n            PivotTools._PivotTmpVector.subtractInPlace(mesh.scaling);\r\n            PivotTools._PivotTmpVector.multiplyInPlace(PivotTools._PivotTranslation);\r\n            mesh.position.subtractInPlace(PivotTools._PivotTmpVector);\r\n        }\r\n        this._PivotCached--;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Plane } from \"../../Maths/math.plane\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData for a Plane\r\n * @param options an object used to set the following optional parameters for the plane, required but can be empty\r\n * * size sets the width and height of the plane to the value of size, optional default 1\r\n * * width sets the width (x direction) of the plane, overwrites the width set by size, optional, default size\r\n * * height sets the height (y direction) of the plane, overwrites the height set by size, optional, default size\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the box\r\n */\r\nexport function CreatePlaneVertexData(options: { size?: number; width?: number; height?: number; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4 }): VertexData {\r\n    const indices = [];\r\n    const positions = [];\r\n    const normals = [];\r\n    const uvs = [];\r\n\r\n    const width: number = options.width !== undefined ? options.width : options.size !== undefined ? options.size : 1;\r\n    const height: number = options.height !== undefined ? options.height : options.size !== undefined ? options.size : 1;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    // Vertices\r\n    const halfWidth = width / 2.0;\r\n    const halfHeight = height / 2.0;\r\n\r\n    positions.push(-halfWidth, -halfHeight, 0);\r\n    normals.push(0, 0, -1.0);\r\n    uvs.push(0.0, useOpenGLOrientationForUV ? 1.0 : 0.0);\r\n\r\n    positions.push(halfWidth, -halfHeight, 0);\r\n    normals.push(0, 0, -1.0);\r\n    uvs.push(1.0, useOpenGLOrientationForUV ? 1.0 : 0.0);\r\n\r\n    positions.push(halfWidth, halfHeight, 0);\r\n    normals.push(0, 0, -1.0);\r\n    uvs.push(1.0, useOpenGLOrientationForUV ? 0.0 : 1.0);\r\n\r\n    positions.push(-halfWidth, halfHeight, 0);\r\n    normals.push(0, 0, -1.0);\r\n    uvs.push(0.0, useOpenGLOrientationForUV ? 0.0 : 1.0);\r\n\r\n    // Indices\r\n    indices.push(0);\r\n    indices.push(1);\r\n    indices.push(2);\r\n\r\n    indices.push(0);\r\n    indices.push(2);\r\n    indices.push(3);\r\n\r\n    // Sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a plane mesh\r\n * * The parameter `size` sets the size (float) of both sides of the plane at once (default 1)\r\n * * You can set some different plane dimensions by using the parameters `width` and `height` (both by default have the same value of `size`)\r\n * * The parameter `sourcePlane` is a Plane instance. It builds a mesh plane from a Math plane\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the plane mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#plane\r\n */\r\nexport function CreatePlane(\r\n    name: string,\r\n    options: { size?: number; width?: number; height?: number; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4; updatable?: boolean; sourcePlane?: Plane } = {},\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const plane = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    plane._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreatePlaneVertexData(options);\r\n\r\n    vertexData.applyToMesh(plane, options.updatable);\r\n\r\n    if (options.sourcePlane) {\r\n        plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);\r\n        plane.setDirection(options.sourcePlane.normal.scale(-1));\r\n    }\r\n\r\n    return plane;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the function directly from the module\r\n */\r\nexport const PlaneBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreatePlane,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for planeBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPlaneBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreatePlane = CreatePlaneVertexData;\r\n\r\n    Mesh.CreatePlane = (name: string, size: number, scene: Scene, updatable?: boolean, sideOrientation?: number): Mesh => {\r\n        const options = {\r\n            size,\r\n            width: size,\r\n            height: size,\r\n            sideOrientation,\r\n            updatable,\r\n        };\r\n\r\n        return CreatePlane(name, options, scene);\r\n    };\r\n}\r\n","import { type IWebXRFeature } from \"./webXRFeaturesManager\";\n\nlet _FeaturesWithSpecificDisableWarning: WeakSet<IWebXRFeature> | undefined;\n\n/**\n * Records that a feature used the warning-emitting intentional-disable path.\n * @param feature the feature that reported its intentional disable\n * @internal\n */\nexport function _MarkWebXRFeatureWithSpecificDisableWarning(feature: IWebXRFeature): void {\n    (_FeaturesWithSpecificDisableWarning ??= new WeakSet()).add(feature);\n}\n\n/**\n * Clears and returns whether a feature used the warning-emitting intentional-disable path.\n * @param feature the feature to query\n * @returns whether the feature reported its intentional disable since the previous query\n * @internal\n */\nexport function _ConsumeWebXRFeatureSpecificDisableWarning(feature: IWebXRFeature): boolean {\n    return _FeaturesWithSpecificDisableWarning?.delete(feature) ?? false;\n}\n","import { type Behavior } from \"../../Behaviors/behavior\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { Ray } from \"../../Culling/ray.pure\";\r\nimport { PivotTools } from \"../../Misc/pivotTools\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { CreatePlane } from \"../../Meshes/Builders/planeBuilder.pure\";\r\n\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { Epsilon } from \"../../Maths/math.constants\";\r\nimport { type DragEvent, type DragStartEndEvent } from \"./pointerDragEvents\";\r\n\r\n/**\r\n * A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events\r\n */\r\nexport class PointerDragBehavior implements Behavior<AbstractMesh> {\r\n    private static _AnyMouseId = -2;\r\n    /**\r\n     * Abstract mesh the behavior is set on\r\n     */\r\n    public attachedNode: AbstractMesh;\r\n    protected _dragPlane: Mesh;\r\n    private _scene: Scene;\r\n    private _pointerObserver: Nullable<Observer<PointerInfo>>;\r\n    private _beforeRenderObserver: Nullable<Observer<Scene>>;\r\n    private static _PlaneScene: Scene;\r\n    private _useAlternatePickedPointAboveMaxDragAngleDragSpeed = -1.1;\r\n    private _activeDragButton: number = -1;\r\n    private _activePointerInfo: Nullable<PointerInfo>;\r\n    /**\r\n     * The maximum tolerated angle between the drag plane and dragging pointer rays to trigger pointer events. Set to 0 to allow any angle (default: 0)\r\n     */\r\n    public maxDragAngle = 0;\r\n    /**\r\n     * Butttons that can be used to initiate a drag\r\n     */\r\n    public dragButtons = [0, 1, 2];\r\n    /**\r\n     * @internal\r\n     */\r\n    public _useAlternatePickedPointAboveMaxDragAngle = false;\r\n    /**\r\n     * Get or set the currentDraggingPointerId\r\n     * @deprecated Please use currentDraggingPointerId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get currentDraggingPointerID(): number {\r\n        return this.currentDraggingPointerId;\r\n    }\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set currentDraggingPointerID(currentDraggingPointerId: number) {\r\n        this.currentDraggingPointerId = currentDraggingPointerId;\r\n    }\r\n    /**\r\n     * The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)\r\n     */\r\n    public currentDraggingPointerId = -1;\r\n    /**\r\n     * The last position where the pointer hit the drag plane in world space\r\n     */\r\n    public lastDragPosition: Vector3;\r\n    /**\r\n     * If the behavior is currently in a dragging state\r\n     */\r\n    public dragging = false;\r\n    /**\r\n     * The distance towards the target drag position to move each frame. This can be useful to avoid jitter. Set this to 1 for no delay. (Default: 0.2)\r\n     */\r\n    public dragDeltaRatio = 0.2;\r\n    /**\r\n     * If the drag plane orientation should be updated during the dragging (Default: true)\r\n     */\r\n    public updateDragPlane = true;\r\n    // Debug mode will display drag planes to help visualize behavior\r\n    private _debugMode = false;\r\n    private _moving = false;\r\n    /**\r\n     *  Fires each time the attached mesh is dragged with the pointer\r\n     */\r\n    public onDragObservable = new Observable<DragEvent>();\r\n    /**\r\n     *  Fires each time a drag begins (eg. mouse down on mesh)\r\n     */\r\n    public onDragStartObservable = new Observable<DragStartEndEvent>();\r\n    /**\r\n     *  Fires each time a drag ends (eg. mouse release after drag)\r\n     */\r\n    public onDragEndObservable = new Observable<DragStartEndEvent>();\r\n    /**\r\n     *  Fires each time behavior enabled state changes\r\n     */\r\n    public onEnabledObservable = new Observable<boolean>();\r\n\r\n    /**\r\n     *  If the attached mesh should be moved when dragged\r\n     */\r\n    public moveAttached = true;\r\n\r\n    /**\r\n     *  If the drag behavior will react to drag events (Default: true)\r\n     */\r\n    public set enabled(value: boolean) {\r\n        if (value != this._enabled) {\r\n            this.onEnabledObservable.notifyObservers(value);\r\n        }\r\n        this._enabled = value;\r\n    }\r\n\r\n    public get enabled() {\r\n        return this._enabled;\r\n    }\r\n    private _enabled = true;\r\n\r\n    /**\r\n     * If pointer events should start and release the drag (Default: true)\r\n     */\r\n    public startAndReleaseDragOnPointerEvents = true;\r\n    /**\r\n     * If camera controls should be detached during the drag\r\n     */\r\n    public detachCameraControls = true;\r\n\r\n    /**\r\n     * If set, the drag plane/axis will be rotated based on the attached mesh's world rotation (Default: true)\r\n     */\r\n    public useObjectOrientationForDragging = true;\r\n\r\n    /**\r\n     * Normally a drag is canceled when the user presses another button on the same pointer. If this is set to true,\r\n     * the drag will continue even if another button is pressed on the same pointer.\r\n     */\r\n    public allowOtherButtonsDuringDrag = false;\r\n\r\n    /**\r\n     * If set, the drag axis will be transformed by the inverse of this node's world matrix.\r\n     * Useful when the drag behavior is used with a gizmo that has an additionalTransformNode.\r\n     */\r\n    public additionalTransformNode?: TransformNode;\r\n\r\n    private _options: { dragAxis?: Vector3; dragPlaneNormal?: Vector3 };\r\n\r\n    /**\r\n     * Gets the options used by the behavior\r\n     */\r\n    public get options(): { dragAxis?: Vector3; dragPlaneNormal?: Vector3 } {\r\n        return this._options;\r\n    }\r\n\r\n    /**\r\n     * Sets the options used by the behavior\r\n     */\r\n    public set options(options: { dragAxis?: Vector3; dragPlaneNormal?: Vector3 }) {\r\n        this._options = options;\r\n    }\r\n\r\n    /**\r\n     * Creates a pointer drag behavior that can be attached to a mesh\r\n     * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)\r\n     * @param options.dragAxis\r\n     * @param options.dragPlaneNormal\r\n     */\r\n    constructor(options?: { dragAxis?: Vector3; dragPlaneNormal?: Vector3 }) {\r\n        this._options = options ? options : {};\r\n\r\n        let optionCount = 0;\r\n        if (this._options.dragAxis) {\r\n            optionCount++;\r\n        }\r\n        if (this._options.dragPlaneNormal) {\r\n            optionCount++;\r\n        }\r\n        if (optionCount > 1) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Multiple drag modes specified in dragBehavior options. Only one expected\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Predicate to determine if it is valid to move the object to a new position when it is moved.\r\n     * In the case of rotation gizmo, target contains the angle.\r\n     * @param target destination position or desired angle delta\r\n     * @returns boolean for whether or not it is valid to move\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public validateDrag = (target: Vector3) => {\r\n        return true;\r\n    };\r\n\r\n    /**\r\n     *  The name of the behavior\r\n     */\r\n    public get name(): string {\r\n        return \"PointerDrag\";\r\n    }\r\n\r\n    /**\r\n     *  Initializes the behavior\r\n     */\r\n    public init() {}\r\n\r\n    private _tmpVector = new Vector3(0, 0, 0);\r\n    private _alternatePickedPoint = new Vector3(0, 0, 0);\r\n    private _worldDragAxis = new Vector3(0, 0, 0);\r\n    private _targetPosition = new Vector3(0, 0, 0);\r\n    private _attachedToElement: boolean = false;\r\n    /**\r\n     * Attaches the drag behavior the passed in mesh\r\n     * @param ownerNode The mesh that will be dragged around once attached\r\n     * @param predicate Predicate to use for pick filtering\r\n     */\r\n    public attach(ownerNode: AbstractMesh, predicate?: (m: AbstractMesh) => boolean): void {\r\n        this._scene = ownerNode.getScene();\r\n        ownerNode.isNearGrabbable = true;\r\n        this.attachedNode = ownerNode;\r\n\r\n        // Initialize drag plane to not interfere with existing scene\r\n        if (!PointerDragBehavior._PlaneScene) {\r\n            if (this._debugMode) {\r\n                PointerDragBehavior._PlaneScene = this._scene;\r\n            } else {\r\n                PointerDragBehavior._PlaneScene = new Scene(this._scene.getEngine(), { virtual: true });\r\n                PointerDragBehavior._PlaneScene.detachControl();\r\n                this._scene.onDisposeObservable.addOnce(() => {\r\n                    PointerDragBehavior._PlaneScene.dispose();\r\n                    (<any>PointerDragBehavior._PlaneScene) = null;\r\n                });\r\n            }\r\n        }\r\n        this._dragPlane = CreatePlane(\r\n            \"pointerDragPlane\",\r\n            { size: this._debugMode ? 1 : 10000, updatable: false, sideOrientation: Mesh.DOUBLESIDE },\r\n            PointerDragBehavior._PlaneScene\r\n        );\r\n\r\n        // State of the drag\r\n        this.lastDragPosition = new Vector3(0, 0, 0);\r\n\r\n        const pickPredicate = predicate\r\n            ? predicate\r\n            : (m: AbstractMesh) => {\r\n                  return this.attachedNode == m || m.isDescendantOf(this.attachedNode);\r\n              };\r\n\r\n        this._pointerObserver = this._scene.onPointerObservable.add((pointerInfo) => {\r\n            if (!this.enabled) {\r\n                // If behavior is disabled before releaseDrag is ever called, call it now.\r\n                if (this._attachedToElement) {\r\n                    this.releaseDrag();\r\n                }\r\n\r\n                return;\r\n            }\r\n\r\n            // If we are dragging and the user presses another button on the same pointer, end the drag. Otherwise,\r\n            // tracking when the drag should end becomes very complex.\r\n            // gizmo.ts has similar behavior.\r\n            if (\r\n                this.dragging &&\r\n                this.currentDraggingPointerId == (<IPointerEvent>pointerInfo.event).pointerId &&\r\n                pointerInfo.event.button !== -1 &&\r\n                pointerInfo.event.button !== this._activeDragButton &&\r\n                !this.allowOtherButtonsDuringDrag\r\n            ) {\r\n                this.releaseDrag();\r\n                return;\r\n            }\r\n\r\n            if (pointerInfo.type == PointerEventTypes.POINTERDOWN) {\r\n                if (\r\n                    this.startAndReleaseDragOnPointerEvents &&\r\n                    !this.dragging &&\r\n                    pointerInfo.pickInfo &&\r\n                    pointerInfo.pickInfo.hit &&\r\n                    pointerInfo.pickInfo.pickedMesh &&\r\n                    pointerInfo.pickInfo.pickedPoint &&\r\n                    pointerInfo.pickInfo.ray &&\r\n                    pickPredicate(pointerInfo.pickInfo.pickedMesh)\r\n                ) {\r\n                    if (this._activeDragButton === -1 && this.dragButtons.indexOf(pointerInfo.event.button) !== -1) {\r\n                        this._activeDragButton = pointerInfo.event.button;\r\n                        this._activePointerInfo = pointerInfo;\r\n                        this._startDrag((<IPointerEvent>pointerInfo.event).pointerId, pointerInfo.pickInfo.ray, pointerInfo.pickInfo.pickedPoint);\r\n                    }\r\n                }\r\n            } else if (pointerInfo.type == PointerEventTypes.POINTERUP) {\r\n                if (\r\n                    this.startAndReleaseDragOnPointerEvents &&\r\n                    this.currentDraggingPointerId == (<IPointerEvent>pointerInfo.event).pointerId &&\r\n                    (this._activeDragButton === pointerInfo.event.button || this._activeDragButton === -1)\r\n                ) {\r\n                    this.releaseDrag();\r\n                }\r\n            } else if (pointerInfo.type == PointerEventTypes.POINTERMOVE) {\r\n                const pointerId = (<IPointerEvent>pointerInfo.event).pointerId;\r\n\r\n                // If drag was started with anyMouseID specified, set pointerID to the next mouse that moved\r\n                if (this.currentDraggingPointerId === PointerDragBehavior._AnyMouseId && pointerId !== PointerDragBehavior._AnyMouseId) {\r\n                    const evt = <IPointerEvent>pointerInfo.event;\r\n                    const isMouseEvent = evt.pointerType === \"mouse\" || (!this._scene.getEngine().hostInformation.isMobile && evt instanceof MouseEvent);\r\n                    if (isMouseEvent) {\r\n                        if (this._lastPointerRay[this.currentDraggingPointerId]) {\r\n                            this._lastPointerRay[pointerId] = this._lastPointerRay[this.currentDraggingPointerId];\r\n                            delete this._lastPointerRay[this.currentDraggingPointerId];\r\n                        }\r\n                        this.currentDraggingPointerId = pointerId;\r\n                    }\r\n                }\r\n\r\n                // Keep track of last pointer ray, this is used simulating the start of a drag in startDrag()\r\n                if (!this._lastPointerRay[pointerId]) {\r\n                    this._lastPointerRay[pointerId] = new Ray(new Vector3(), new Vector3());\r\n                }\r\n                if (pointerInfo.pickInfo && pointerInfo.pickInfo.ray) {\r\n                    this._lastPointerRay[pointerId].origin.copyFrom(pointerInfo.pickInfo.ray.origin);\r\n                    this._lastPointerRay[pointerId].direction.copyFrom(pointerInfo.pickInfo.ray.direction);\r\n\r\n                    if (this.currentDraggingPointerId == pointerId && this.dragging) {\r\n                        this._moveDrag(pointerInfo.pickInfo.ray);\r\n                    }\r\n                }\r\n            }\r\n        });\r\n\r\n        this._beforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n            if (this._moving && this.moveAttached) {\r\n                let needMatrixUpdate = false;\r\n                PivotTools._RemoveAndStorePivotPoint(this.attachedNode);\r\n                // Slowly move mesh to avoid jitter\r\n                this._targetPosition.subtractToRef(this.attachedNode.absolutePosition, this._tmpVector);\r\n                this._tmpVector.scaleInPlace(this.dragDeltaRatio);\r\n                this.attachedNode.getAbsolutePosition().addToRef(this._tmpVector, this._tmpVector);\r\n                if (this.validateDrag(this._tmpVector)) {\r\n                    this.attachedNode.setAbsolutePosition(this._tmpVector);\r\n                    needMatrixUpdate = true;\r\n                }\r\n                PivotTools._RestorePivotPoint(this.attachedNode);\r\n                if (needMatrixUpdate) {\r\n                    this.attachedNode.computeWorldMatrix();\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Force release the drag action by code.\r\n     */\r\n    public releaseDrag() {\r\n        if (this.dragging) {\r\n            this.dragging = false;\r\n            this.onDragEndObservable.notifyObservers({ dragPlanePoint: this.lastDragPosition, pointerId: this.currentDraggingPointerId, pointerInfo: this._activePointerInfo });\r\n        }\r\n\r\n        this.currentDraggingPointerId = -1;\r\n        this._activeDragButton = -1;\r\n        this._activePointerInfo = null;\r\n        this._moving = false;\r\n\r\n        // Reattach camera controls\r\n        if (this.detachCameraControls && this._attachedToElement && this._scene.activeCamera && !this._scene.activeCamera.leftCamera) {\r\n            if (this._scene.activeCamera.getClassName() === \"ArcRotateCamera\") {\r\n                const arcRotateCamera = this._scene.activeCamera as ArcRotateCamera;\r\n                arcRotateCamera.attachControl(\r\n                    arcRotateCamera.inputs ? arcRotateCamera.inputs.noPreventDefault : true,\r\n                    arcRotateCamera._useCtrlForPanning,\r\n                    arcRotateCamera._panningMouseButton\r\n                );\r\n            } else {\r\n                this._scene.activeCamera.attachControl(this._scene.activeCamera.inputs ? this._scene.activeCamera.inputs.noPreventDefault : true);\r\n            }\r\n            this._attachedToElement = false;\r\n        }\r\n    }\r\n\r\n    private _startDragRay = new Ray(new Vector3(), new Vector3());\r\n    private _lastPointerRay: { [key: number]: Ray } = {};\r\n    /**\r\n     * Simulates the start of a pointer drag event on the behavior\r\n     * @param pointerId pointerID of the pointer that should be simulated (Default: Any mouse pointer ID)\r\n     * @param fromRay initial ray of the pointer to be simulated (Default: Ray from camera to attached mesh)\r\n     * @param startPickedPoint picked point of the pointer to be simulated (Default: attached mesh position)\r\n     */\r\n    public startDrag(pointerId: number = PointerDragBehavior._AnyMouseId, fromRay?: Ray, startPickedPoint?: Vector3) {\r\n        this._startDrag(pointerId, fromRay, startPickedPoint);\r\n\r\n        let lastRay = this._lastPointerRay[pointerId];\r\n        if (pointerId === PointerDragBehavior._AnyMouseId) {\r\n            lastRay = this._lastPointerRay[<any>Object.keys(this._lastPointerRay)[0]];\r\n        }\r\n\r\n        if (lastRay) {\r\n            // if there was a last pointer ray drag the object there\r\n            this._moveDrag(lastRay);\r\n        }\r\n    }\r\n\r\n    protected _startDrag(pointerId: number, fromRay?: Ray, startPickedPoint?: Vector3) {\r\n        if (!this._scene.activeCamera || this.dragging || !this.attachedNode) {\r\n            return;\r\n        }\r\n\r\n        PivotTools._RemoveAndStorePivotPoint(this.attachedNode);\r\n        // Create start ray from the camera to the object\r\n        if (fromRay) {\r\n            this._startDragRay.direction.copyFrom(fromRay.direction);\r\n            this._startDragRay.origin.copyFrom(fromRay.origin);\r\n        } else {\r\n            this._startDragRay.origin.copyFrom(this._scene.activeCamera.position);\r\n            this.attachedNode.getWorldMatrix().getTranslationToRef(this._tmpVector);\r\n            this._tmpVector.subtractToRef(this._scene.activeCamera.position, this._startDragRay.direction);\r\n        }\r\n\r\n        this._updateDragPlanePosition(this._startDragRay, startPickedPoint ? startPickedPoint : this._tmpVector);\r\n\r\n        const pickedPoint = this._pickWithRayOnDragPlane(this._startDragRay);\r\n        if (pickedPoint) {\r\n            this.dragging = true;\r\n            this.currentDraggingPointerId = pointerId;\r\n            this.lastDragPosition.copyFrom(pickedPoint);\r\n            this.onDragStartObservable.notifyObservers({ dragPlanePoint: pickedPoint, pointerId: this.currentDraggingPointerId, pointerInfo: this._activePointerInfo });\r\n            this._targetPosition.copyFrom(this.attachedNode.getAbsolutePosition());\r\n\r\n            // Detatch camera controls\r\n            if (this.detachCameraControls && this._scene.activeCamera && this._scene.activeCamera.inputs && !this._scene.activeCamera.leftCamera) {\r\n                if (this._scene.activeCamera.inputs.attachedToElement) {\r\n                    this._scene.activeCamera.detachControl();\r\n                    this._attachedToElement = true;\r\n                } else {\r\n                    this._attachedToElement = false;\r\n                }\r\n            }\r\n        } else {\r\n            this.releaseDrag();\r\n        }\r\n        PivotTools._RestorePivotPoint(this.attachedNode);\r\n    }\r\n\r\n    private _dragDelta = new Vector3();\r\n    protected _moveDrag(ray: Ray) {\r\n        this._moving = true;\r\n        const pickedPoint = this._pickWithRayOnDragPlane(ray);\r\n\r\n        if (pickedPoint) {\r\n            PivotTools._RemoveAndStorePivotPoint(this.attachedNode);\r\n\r\n            if (this.updateDragPlane) {\r\n                this._updateDragPlanePosition(ray, pickedPoint);\r\n            }\r\n            let dragLength: number;\r\n            // depending on the drag mode option drag accordingly\r\n            if (this._options.dragAxis) {\r\n                // Convert local drag axis to world if useObjectOrientationForDragging\r\n                this.useObjectOrientationForDragging\r\n                    ? Vector3.TransformCoordinatesToRef(this._options.dragAxis, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis)\r\n                    : this._worldDragAxis.copyFrom(this._options.dragAxis);\r\n                // Project delta drag from the drag plane onto the drag axis\r\n                pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);\r\n\r\n                if (this.additionalTransformNode) {\r\n                    this.additionalTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n                    Vector3.TransformNormalToRef(this._worldDragAxis, TmpVectors.Matrix[0], this._worldDragAxis);\r\n                }\r\n                this._worldDragAxis.normalize();\r\n                dragLength = Vector3.Dot(this._tmpVector, this._worldDragAxis);\r\n                this._worldDragAxis.scaleToRef(dragLength, this._dragDelta);\r\n            } else {\r\n                dragLength = this._dragDelta.length();\r\n                pickedPoint.subtractToRef(this.lastDragPosition, this._dragDelta);\r\n            }\r\n            this._targetPosition.addInPlace(this._dragDelta);\r\n            this.onDragObservable.notifyObservers({\r\n                dragDistance: dragLength,\r\n                delta: this._dragDelta,\r\n                dragPlanePoint: pickedPoint,\r\n                dragPlaneNormal: this._dragPlane.forward,\r\n                pointerId: this.currentDraggingPointerId,\r\n                pointerInfo: this._activePointerInfo,\r\n            });\r\n            this.lastDragPosition.copyFrom(pickedPoint);\r\n\r\n            PivotTools._RestorePivotPoint(this.attachedNode);\r\n        }\r\n    }\r\n\r\n    private _pickWithRayOnDragPlane(ray: Nullable<Ray>) {\r\n        if (!ray) {\r\n            return null;\r\n        }\r\n\r\n        // Calculate angle between plane normal and ray\r\n        let angle = Math.acos(Vector3.Dot(this._dragPlane.forward, ray.direction));\r\n        // Correct if ray is casted from oposite side\r\n        if (angle > Math.PI / 2) {\r\n            angle = Math.PI - angle;\r\n        }\r\n\r\n        // If the angle is too perpendicular to the plane pick another point on the plane where it is looking\r\n        if (this.maxDragAngle > 0 && angle > this.maxDragAngle) {\r\n            if (this._useAlternatePickedPointAboveMaxDragAngle) {\r\n                // Invert ray direction along the towards object axis\r\n                this._tmpVector.copyFrom(ray.direction);\r\n                this.attachedNode.absolutePosition.subtractToRef(ray.origin, this._alternatePickedPoint);\r\n                this._alternatePickedPoint.normalize();\r\n                this._alternatePickedPoint.scaleInPlace(this._useAlternatePickedPointAboveMaxDragAngleDragSpeed * Vector3.Dot(this._alternatePickedPoint, this._tmpVector));\r\n                this._tmpVector.addInPlace(this._alternatePickedPoint);\r\n\r\n                // Project resulting vector onto the drag plane and add it to the attached nodes absolute position to get a picked point\r\n                const dot = Vector3.Dot(this._dragPlane.forward, this._tmpVector);\r\n                this._dragPlane.forward.scaleToRef(-dot, this._alternatePickedPoint);\r\n                this._alternatePickedPoint.addInPlace(this._tmpVector);\r\n                this._alternatePickedPoint.addInPlace(this.attachedNode.absolutePosition);\r\n                return this._alternatePickedPoint;\r\n            } else {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        // use an infinite plane instead of ray picking a mesh that must be updated every frame\r\n        const planeNormal = this._dragPlane.forward;\r\n        const planePosition = this._dragPlane.position;\r\n        const dotProduct = ray.direction.dot(planeNormal);\r\n        if (Math.abs(dotProduct) < Epsilon) {\r\n            // Ray and plane are parallel, no intersection\r\n            return null;\r\n        }\r\n\r\n        planePosition.subtractToRef(ray.origin, TmpVectors.Vector3[0]);\r\n        const t = TmpVectors.Vector3[0].dot(planeNormal) / dotProduct;\r\n        // Ensure the intersection point is in front of the ray (t must be positive)\r\n        if (t < 0) {\r\n            // Intersection point is behind the ray\r\n            return null;\r\n        }\r\n\r\n        // Calculate the intersection point using the parameter t\r\n        ray.direction.scaleToRef(t, TmpVectors.Vector3[0]);\r\n        const intersectionPoint = ray.origin.add(TmpVectors.Vector3[0]);\r\n        return intersectionPoint;\r\n    }\r\n\r\n    // Variables to avoid instantiation in the below method\r\n    private _pointA = new Vector3(0, 0, 0);\r\n    private _pointC = new Vector3(0, 0, 0);\r\n    private _localAxis = new Vector3(0, 0, 0);\r\n    private _lookAt = new Vector3(0, 0, 0);\r\n    // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera\r\n    private _updateDragPlanePosition(ray: Ray, dragPlanePosition: Vector3) {\r\n        this._pointA.copyFrom(dragPlanePosition);\r\n        if (this._options.dragAxis) {\r\n            this.useObjectOrientationForDragging\r\n                ? Vector3.TransformCoordinatesToRef(this._options.dragAxis, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis)\r\n                : this._localAxis.copyFrom(this._options.dragAxis);\r\n\r\n            // Calculate plane normal that is the cross product of local axis and (eye-dragPlanePosition)\r\n            ray.origin.subtractToRef(this._pointA, this._pointC);\r\n            this._pointC.normalize();\r\n            if (Math.abs(Vector3.Dot(this._localAxis, this._pointC)) > 0.999) {\r\n                // the drag axis is colinear with the (eye to position) ray. The cross product will give jittered values.\r\n                // A new axis vector need to be computed\r\n                if (Math.abs(Vector3.Dot(Vector3.UpReadOnly, this._pointC)) > 0.999) {\r\n                    this._lookAt.copyFrom(Vector3.Right());\r\n                } else {\r\n                    this._lookAt.copyFrom(Vector3.UpReadOnly);\r\n                }\r\n            } else {\r\n                Vector3.CrossToRef(this._localAxis, this._pointC, this._lookAt);\r\n                // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendicular to camera\r\n                Vector3.CrossToRef(this._localAxis, this._lookAt, this._lookAt);\r\n                this._lookAt.normalize();\r\n            }\r\n\r\n            this._dragPlane.position.copyFrom(this._pointA);\r\n            this._pointA.addToRef(this._lookAt, this._lookAt);\r\n            this._dragPlane.lookAt(this._lookAt);\r\n        } else if (this._options.dragPlaneNormal) {\r\n            this.useObjectOrientationForDragging\r\n                ? Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis)\r\n                : this._localAxis.copyFrom(this._options.dragPlaneNormal);\r\n            this._dragPlane.position.copyFrom(this._pointA);\r\n            this._pointA.addToRef(this._localAxis, this._lookAt);\r\n            this._dragPlane.lookAt(this._lookAt);\r\n        } else {\r\n            if (this._scene.activeCamera) {\r\n                this._scene.activeCamera.getForwardRay().direction.normalizeToRef(this._localAxis);\r\n            }\r\n            this._dragPlane.position.copyFrom(this._pointA);\r\n            this._dragPlane.lookAt(this._pointA.add(this._localAxis));\r\n        }\r\n        // Update the position of the drag plane so it doesn't get out of sync with the node (eg. when moving back and forth quickly)\r\n        this._dragPlane.position.copyFrom(this.attachedNode.getAbsolutePosition());\r\n\r\n        this._dragPlane.computeWorldMatrix(true);\r\n    }\r\n\r\n    /**\r\n     *  Detaches the behavior from the mesh\r\n     */\r\n    public detach(): void {\r\n        this._lastPointerRay = {};\r\n        if (this.attachedNode) {\r\n            this.attachedNode.isNearGrabbable = false;\r\n        }\r\n        if (this._pointerObserver) {\r\n            this._scene.onPointerObservable.remove(this._pointerObserver);\r\n        }\r\n        if (this._beforeRenderObserver) {\r\n            this._scene.onBeforeRenderObservable.remove(this._beforeRenderObserver);\r\n        }\r\n        if (this._dragPlane) {\r\n            this._dragPlane.dispose();\r\n        }\r\n        this.releaseDrag();\r\n    }\r\n}\r\n","import { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Behavior } from \"../behavior\";\r\nimport { PointerDragBehavior } from \"./pointerDragBehavior\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Scene } from \"../../scene\";\r\n\r\n/**\r\n * A behavior that when attached to a mesh will allow the mesh to be scaled\r\n */\r\nexport class MultiPointerScaleBehavior implements Behavior<Mesh> {\r\n    private _dragBehaviorA: PointerDragBehavior;\r\n    private _dragBehaviorB: PointerDragBehavior;\r\n    private _startDistance = 0;\r\n    private _initialScale = new Vector3(0, 0, 0);\r\n    private _targetScale = new Vector3(0, 0, 0);\r\n    private _ownerNode: Mesh;\r\n    private _sceneRenderObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<Mesh> {\r\n        return this._ownerNode;\r\n    }\r\n\r\n    /**\r\n     * Instantiate a new behavior that when attached to a mesh will allow the mesh to be scaled\r\n     */\r\n    constructor() {\r\n        this._dragBehaviorA = new PointerDragBehavior({});\r\n        this._dragBehaviorA.moveAttached = false;\r\n        this._dragBehaviorB = new PointerDragBehavior({});\r\n        this._dragBehaviorB.moveAttached = false;\r\n        this._ownerNode = null!;\r\n    }\r\n\r\n    /**\r\n     *  The name of the behavior\r\n     */\r\n    public get name(): string {\r\n        return \"MultiPointerScale\";\r\n    }\r\n\r\n    /**\r\n     *  Initializes the behavior\r\n     */\r\n    public init() {}\r\n\r\n    private _getCurrentDistance() {\r\n        return this._dragBehaviorA.lastDragPosition.subtract(this._dragBehaviorB.lastDragPosition).length();\r\n    }\r\n\r\n    /**\r\n     * Attaches the scale behavior the passed in mesh\r\n     * @param ownerNode The mesh that will be scaled around once attached\r\n     */\r\n    public attach(ownerNode: Mesh): void {\r\n        this._ownerNode = ownerNode;\r\n\r\n        // Create 2 drag behaviors such that each will only be triggered by a separate pointer\r\n        this._dragBehaviorA.onDragStartObservable.add(() => {\r\n            if (this._dragBehaviorA.dragging && this._dragBehaviorB.dragging) {\r\n                if (this._dragBehaviorA.currentDraggingPointerId == this._dragBehaviorB.currentDraggingPointerId) {\r\n                    this._dragBehaviorA.releaseDrag();\r\n                } else {\r\n                    this._initialScale.copyFrom(ownerNode.scaling);\r\n                    this._startDistance = this._getCurrentDistance();\r\n                }\r\n            }\r\n        });\r\n        this._dragBehaviorB.onDragStartObservable.add(() => {\r\n            if (this._dragBehaviorA.dragging && this._dragBehaviorB.dragging) {\r\n                if (this._dragBehaviorA.currentDraggingPointerId == this._dragBehaviorB.currentDraggingPointerId) {\r\n                    this._dragBehaviorB.releaseDrag();\r\n                } else {\r\n                    this._initialScale.copyFrom(ownerNode.scaling);\r\n                    this._startDistance = this._getCurrentDistance();\r\n                }\r\n            }\r\n        });\r\n\r\n        // Once both drag behaviors are active scale based on the distance between the two pointers\r\n        const dragBehaviors = [this._dragBehaviorA, this._dragBehaviorB];\r\n        for (const behavior of dragBehaviors) {\r\n            behavior.onDragObservable.add(() => {\r\n                if (this._dragBehaviorA.dragging && this._dragBehaviorB.dragging) {\r\n                    const ratio = this._getCurrentDistance() / this._startDistance;\r\n                    this._initialScale.scaleToRef(ratio, this._targetScale);\r\n                }\r\n            });\r\n        }\r\n\r\n        ownerNode.addBehavior(this._dragBehaviorA);\r\n        ownerNode.addBehavior(this._dragBehaviorB);\r\n\r\n        // On every frame move towards target scaling to avoid jitter caused by vr controllers\r\n        this._sceneRenderObserver = ownerNode.getScene().onBeforeRenderObservable.add(() => {\r\n            if (this._dragBehaviorA.dragging && this._dragBehaviorB.dragging) {\r\n                const change = this._targetScale.subtract(ownerNode.scaling).scaleInPlace(0.1);\r\n                if (change.length() > 0.01) {\r\n                    ownerNode.scaling.addInPlace(change);\r\n                }\r\n            }\r\n        });\r\n    }\r\n    /**\r\n     *  Detaches the behavior from the mesh\r\n     */\r\n    public detach(): void {\r\n        this._ownerNode.getScene().onBeforeRenderObservable.remove(this._sceneRenderObserver);\r\n        const dragBehaviors = [this._dragBehaviorA, this._dragBehaviorB];\r\n        for (const behavior of dragBehaviors) {\r\n            behavior.onDragStartObservable.clear();\r\n            behavior.onDragObservable.clear();\r\n            this._ownerNode.removeBehavior(behavior);\r\n        }\r\n        this._ownerNode = null!;\r\n    }\r\n}\r\n","import { type Behavior } from \"../../Behaviors/behavior\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { type PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { type Ray } from \"../../Culling/ray\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\n\r\n/**\r\n * Data store to track virtual pointers movement\r\n */\r\ntype VirtualMeshInfo = {\r\n    dragging: boolean;\r\n    moving: boolean;\r\n    dragMesh: TransformNode;\r\n    originMesh: TransformNode;\r\n    pivotMesh: TransformNode;\r\n    startingPivotPosition: Vector3;\r\n    startingPivotOrientation: Quaternion;\r\n    startingPosition: Vector3;\r\n    startingOrientation: Quaternion;\r\n    lastOriginPosition: Vector3;\r\n    lastDragPosition: Vector3;\r\n};\r\n\r\n/**\r\n * Base behavior for six degrees of freedom interactions in XR experiences.\r\n * Creates virtual meshes that are dragged around\r\n * And observables for position/rotation changes\r\n */\r\nexport class BaseSixDofDragBehavior implements Behavior<TransformNode> {\r\n    protected static _VirtualScene: Scene;\r\n    private _pointerObserver: Nullable<Observer<PointerInfo>>;\r\n    private _attachedToElement: boolean = false;\r\n    protected _virtualMeshesInfo: {\r\n        [id: number]: VirtualMeshInfo;\r\n    } = {};\r\n\r\n    private _tmpVector: Vector3 = new Vector3();\r\n    private _tmpQuaternion: Quaternion = new Quaternion();\r\n\r\n    protected _dragType = {\r\n        NONE: 0,\r\n        DRAG: 1,\r\n        DRAG_WITH_CONTROLLER: 2,\r\n        NEAR_DRAG: 3,\r\n    };\r\n\r\n    protected _scene: Scene;\r\n    protected _moving = false;\r\n    protected _ownerNode: TransformNode = null!;\r\n    protected _dragging = this._dragType.NONE;\r\n\r\n    /**\r\n     * The list of child meshes that can receive drag events\r\n     * If `null`, all child meshes will receive drag event\r\n     */\r\n    public draggableMeshes: Nullable<AbstractMesh[]> = null;\r\n\r\n    /**\r\n     * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 3)\r\n     */\r\n    public zDragFactor = 3;\r\n    /**\r\n     * The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)\r\n     */\r\n    public get currentDraggingPointerId() {\r\n        if (this.currentDraggingPointerIds[0] !== undefined) {\r\n            return this.currentDraggingPointerIds[0];\r\n        }\r\n        return -1;\r\n    }\r\n\r\n    public set currentDraggingPointerId(value: number) {\r\n        this.currentDraggingPointerIds[0] = value;\r\n    }\r\n\r\n    /**\r\n     * In case of multipointer interaction, all pointer ids currently active are stored here\r\n     */\r\n    public currentDraggingPointerIds: number[] = [];\r\n\r\n    /**\r\n     * Get or set the currentDraggingPointerId\r\n     * @deprecated Please use currentDraggingPointerId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get currentDraggingPointerID(): number {\r\n        return this.currentDraggingPointerId;\r\n    }\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set currentDraggingPointerID(currentDraggingPointerID: number) {\r\n        this.currentDraggingPointerId = currentDraggingPointerID;\r\n    }\r\n    /**\r\n    /**\r\n     * If camera controls should be detached during the drag\r\n     */\r\n    public detachCameraControls = true;\r\n\r\n    /**\r\n     * Fires each time a drag starts\r\n     */\r\n    public onDragStartObservable = new Observable<{ position: Vector3 }>();\r\n    /**\r\n     * Fires each time a drag happens\r\n     */\r\n    public onDragObservable = new Observable<{ delta: Vector3; position: Vector3; pickInfo: PickingInfo }>();\r\n    /**\r\n     *  Fires each time a drag ends (eg. mouse release after drag)\r\n     */\r\n    public onDragEndObservable = new Observable<unknown>();\r\n\r\n    /**\r\n     * Should the behavior allow simultaneous pointers to interact with the owner node.\r\n     */\r\n    public allowMultiPointer: boolean = true;\r\n\r\n    /**\r\n     *  The name of the behavior\r\n     */\r\n    public get name(): string {\r\n        return \"BaseSixDofDrag\";\r\n    }\r\n\r\n    /**\r\n     *  Returns true if the attached mesh is currently moving with this behavior\r\n     */\r\n    public get isMoving(): boolean {\r\n        return this._moving;\r\n    }\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<TransformNode> {\r\n        return this._ownerNode;\r\n    }\r\n\r\n    /**\r\n     *  Initializes the behavior\r\n     */\r\n    public init() {}\r\n\r\n    /**\r\n     * In the case of multiple active cameras, the cameraToUseForPointers should be used if set instead of active camera\r\n     */\r\n    private get _pointerCamera() {\r\n        if (this._scene.cameraToUseForPointers) {\r\n            return this._scene.cameraToUseForPointers;\r\n        } else {\r\n            return this._scene.activeCamera;\r\n        }\r\n    }\r\n\r\n    private _createVirtualMeshInfo() {\r\n        // Setup virtual meshes to be used for dragging without dirtying the existing scene\r\n\r\n        const dragMesh = new TransformNode(\"\", BaseSixDofDragBehavior._VirtualScene);\r\n        dragMesh.rotationQuaternion = new Quaternion();\r\n        const originMesh = new TransformNode(\"\", BaseSixDofDragBehavior._VirtualScene);\r\n        originMesh.rotationQuaternion = new Quaternion();\r\n        const pivotMesh = new TransformNode(\"\", BaseSixDofDragBehavior._VirtualScene);\r\n        pivotMesh.rotationQuaternion = new Quaternion();\r\n\r\n        return {\r\n            dragging: false,\r\n            moving: false,\r\n            dragMesh,\r\n            originMesh,\r\n            pivotMesh,\r\n            startingPivotPosition: new Vector3(),\r\n            startingPivotOrientation: new Quaternion(),\r\n            startingPosition: new Vector3(),\r\n            startingOrientation: new Quaternion(),\r\n            lastOriginPosition: new Vector3(),\r\n            lastDragPosition: new Vector3(),\r\n        };\r\n    }\r\n\r\n    protected _resetVirtualMeshesPosition() {\r\n        for (let i = 0; i < this.currentDraggingPointerIds.length; i++) {\r\n            this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].pivotMesh.position.copyFrom(this._ownerNode.getAbsolutePivotPoint());\r\n            this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].pivotMesh.rotationQuaternion!.copyFrom(this._ownerNode.rotationQuaternion!);\r\n            this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].startingPivotPosition.copyFrom(\r\n                this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].pivotMesh.position\r\n            );\r\n            this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].startingPivotOrientation.copyFrom(\r\n                this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].pivotMesh.rotationQuaternion!\r\n            );\r\n            this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].startingPosition.copyFrom(this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].dragMesh.position);\r\n            this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].startingOrientation.copyFrom(\r\n                this._virtualMeshesInfo[this.currentDraggingPointerIds[i]].dragMesh.rotationQuaternion!\r\n            );\r\n        }\r\n    }\r\n\r\n    private _pointerUpdate2D(ray: Ray, pointerId: number, zDragFactor: number) {\r\n        if (this._pointerCamera && this._pointerCamera.cameraRigMode == Camera.RIG_MODE_NONE && !this._pointerCamera._isLeftCamera && !this._pointerCamera._isRightCamera) {\r\n            ray.origin.copyFrom(this._pointerCamera.globalPosition);\r\n            zDragFactor = 0;\r\n        }\r\n\r\n        const virtualMeshesInfo = this._virtualMeshesInfo[pointerId];\r\n\r\n        // Calculate controller drag distance in controller space\r\n        const originDragDifference = TmpVectors.Vector3[11];\r\n        ray.origin.subtractToRef(virtualMeshesInfo.lastOriginPosition, originDragDifference);\r\n        virtualMeshesInfo.lastOriginPosition.copyFrom(ray.origin);\r\n        const localOriginDragDifference = -Vector3.Dot(originDragDifference, ray.direction);\r\n\r\n        virtualMeshesInfo.originMesh.addChild(virtualMeshesInfo.dragMesh);\r\n        virtualMeshesInfo.originMesh.addChild(virtualMeshesInfo.pivotMesh);\r\n\r\n        this._applyZOffset(virtualMeshesInfo.dragMesh, localOriginDragDifference, zDragFactor);\r\n        this._applyZOffset(virtualMeshesInfo.pivotMesh, localOriginDragDifference, zDragFactor);\r\n\r\n        // Update the controller position\r\n        virtualMeshesInfo.originMesh.position.copyFrom(ray.origin);\r\n        const lookAt = TmpVectors.Vector3[10];\r\n        ray.origin.addToRef(ray.direction, lookAt);\r\n        virtualMeshesInfo.originMesh.lookAt(lookAt);\r\n\r\n        virtualMeshesInfo.originMesh.removeChild(virtualMeshesInfo.dragMesh);\r\n        virtualMeshesInfo.originMesh.removeChild(virtualMeshesInfo.pivotMesh);\r\n    }\r\n\r\n    private _pointerUpdateXR(controllerAimTransform: TransformNode, controllerGripTransform: Nullable<TransformNode>, pointerId: number, zDragFactor: number) {\r\n        const virtualMeshesInfo = this._virtualMeshesInfo[pointerId];\r\n        virtualMeshesInfo.originMesh.position.copyFrom(controllerAimTransform.position);\r\n        if (this._dragging === this._dragType.NEAR_DRAG && controllerGripTransform) {\r\n            virtualMeshesInfo.originMesh.rotationQuaternion!.copyFrom(controllerGripTransform.rotationQuaternion!);\r\n        } else {\r\n            virtualMeshesInfo.originMesh.rotationQuaternion!.copyFrom(controllerAimTransform.rotationQuaternion!);\r\n        }\r\n\r\n        virtualMeshesInfo.pivotMesh.computeWorldMatrix(true);\r\n        virtualMeshesInfo.dragMesh.computeWorldMatrix(true);\r\n\r\n        // Z scaling logic\r\n        if (zDragFactor !== 0) {\r\n            // Camera.getForwardRay modifies TmpVectors.Vector[0-3], so cache it in advance\r\n            const cameraForwardVec = TmpVectors.Vector3[10];\r\n            const originDragDirection = TmpVectors.Vector3[11];\r\n            cameraForwardVec.copyFrom(this._pointerCamera!.getForwardRay().direction);\r\n            virtualMeshesInfo.originMesh.position.subtractToRef(virtualMeshesInfo.lastOriginPosition, originDragDirection);\r\n            virtualMeshesInfo.lastOriginPosition.copyFrom(virtualMeshesInfo.originMesh.position);\r\n            const controllerDragDistance = originDragDirection.length();\r\n            originDragDirection.normalize();\r\n\r\n            const cameraToDrag = TmpVectors.Vector3[12];\r\n            const controllerToDrag = TmpVectors.Vector3[9];\r\n            virtualMeshesInfo.dragMesh.absolutePosition.subtractToRef(this._pointerCamera!.globalPosition, cameraToDrag);\r\n            virtualMeshesInfo.dragMesh.absolutePosition.subtractToRef(virtualMeshesInfo.originMesh.position, controllerToDrag);\r\n            const controllerToDragDistance = controllerToDrag.length();\r\n            cameraToDrag.normalize();\r\n            controllerToDrag.normalize();\r\n\r\n            const controllerDragScaling = Math.abs(Vector3.Dot(originDragDirection, controllerToDrag)) * Vector3.Dot(originDragDirection, cameraForwardVec);\r\n            let zOffsetScaling = controllerDragScaling * zDragFactor * controllerDragDistance * controllerToDragDistance;\r\n\r\n            // Prevent pulling the mesh through the controller\r\n            const minDistanceFromControllerToDragMesh = 0.01;\r\n            if (zOffsetScaling < 0 && minDistanceFromControllerToDragMesh - controllerToDragDistance > zOffsetScaling) {\r\n                zOffsetScaling = Math.min(minDistanceFromControllerToDragMesh - controllerToDragDistance, 0);\r\n            }\r\n            controllerToDrag.scaleInPlace(zOffsetScaling);\r\n\r\n            controllerToDrag.addToRef(virtualMeshesInfo.pivotMesh.absolutePosition, this._tmpVector);\r\n            virtualMeshesInfo.pivotMesh.setAbsolutePosition(this._tmpVector);\r\n            controllerToDrag.addToRef(virtualMeshesInfo.dragMesh.absolutePosition, this._tmpVector);\r\n            virtualMeshesInfo.dragMesh.setAbsolutePosition(this._tmpVector);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attaches the scale behavior the passed in mesh\r\n     * @param ownerNode The mesh that will be scaled around once attached\r\n     */\r\n    public attach(ownerNode: TransformNode): void {\r\n        this._ownerNode = ownerNode;\r\n        this._scene = this._ownerNode.getScene();\r\n        if (!BaseSixDofDragBehavior._VirtualScene) {\r\n            BaseSixDofDragBehavior._VirtualScene = new Scene(this._scene.getEngine(), { virtual: true });\r\n            BaseSixDofDragBehavior._VirtualScene.detachControl();\r\n        }\r\n\r\n        const pickPredicate = (m: AbstractMesh) => {\r\n            return this._ownerNode === m || (m.isDescendantOf(this._ownerNode) && (!this.draggableMeshes || this.draggableMeshes.indexOf(m) !== -1));\r\n        };\r\n\r\n        this._pointerObserver = this._scene.onPointerObservable.add((pointerInfo) => {\r\n            const pointerId = (<IPointerEvent>pointerInfo.event).pointerId;\r\n            if (!this._virtualMeshesInfo[pointerId]) {\r\n                this._virtualMeshesInfo[pointerId] = this._createVirtualMeshInfo();\r\n            }\r\n            const virtualMeshesInfo = this._virtualMeshesInfo[pointerId];\r\n            const isXRPointer = (<IPointerEvent>pointerInfo.event).pointerType === \"xr-near\" || (<IPointerEvent>pointerInfo.event).pointerType === \"xr\";\r\n            const isNearXRPointer = (<IPointerEvent>pointerInfo.event).pointerType === \"xr-near\";\r\n            if (pointerInfo.type == PointerEventTypes.POINTERDOWN) {\r\n                if (\r\n                    !virtualMeshesInfo.dragging &&\r\n                    pointerInfo.pickInfo &&\r\n                    pointerInfo.pickInfo.hit &&\r\n                    pointerInfo.pickInfo.pickedMesh &&\r\n                    pointerInfo.pickInfo.pickedPoint &&\r\n                    pointerInfo.pickInfo.ray &&\r\n                    (!isNearXRPointer || pointerInfo.pickInfo.aimTransform) &&\r\n                    pickPredicate(pointerInfo.pickInfo.pickedMesh)\r\n                ) {\r\n                    if ((!this.allowMultiPointer || isXRPointer) && this.currentDraggingPointerIds.length > 0) {\r\n                        return;\r\n                    }\r\n\r\n                    if (\r\n                        this._pointerCamera &&\r\n                        this._pointerCamera.cameraRigMode === Camera.RIG_MODE_NONE &&\r\n                        !this._pointerCamera._isLeftCamera &&\r\n                        !this._pointerCamera._isRightCamera\r\n                    ) {\r\n                        pointerInfo.pickInfo.ray.origin.copyFrom(this._pointerCamera.globalPosition);\r\n                    }\r\n\r\n                    this._ownerNode.computeWorldMatrix(true);\r\n                    const virtualMeshesInfo = this._virtualMeshesInfo[pointerId];\r\n\r\n                    if (isXRPointer) {\r\n                        this._dragging = pointerInfo.pickInfo.originMesh ? this._dragType.NEAR_DRAG : this._dragType.DRAG_WITH_CONTROLLER;\r\n                        virtualMeshesInfo.originMesh.position.copyFrom(pointerInfo.pickInfo.aimTransform!.position);\r\n                        if (this._dragging === this._dragType.NEAR_DRAG && pointerInfo.pickInfo.gripTransform) {\r\n                            virtualMeshesInfo.originMesh.rotationQuaternion!.copyFrom(pointerInfo.pickInfo.gripTransform.rotationQuaternion!);\r\n                        } else {\r\n                            virtualMeshesInfo.originMesh.rotationQuaternion!.copyFrom(pointerInfo.pickInfo.aimTransform!.rotationQuaternion!);\r\n                        }\r\n                    } else {\r\n                        this._dragging = this._dragType.DRAG;\r\n                        virtualMeshesInfo.originMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);\r\n                    }\r\n\r\n                    virtualMeshesInfo.lastOriginPosition.copyFrom(virtualMeshesInfo.originMesh.position);\r\n\r\n                    virtualMeshesInfo.dragMesh.position.copyFrom(pointerInfo.pickInfo.pickedPoint);\r\n                    virtualMeshesInfo.lastDragPosition.copyFrom(pointerInfo.pickInfo.pickedPoint);\r\n\r\n                    virtualMeshesInfo.pivotMesh.position.copyFrom(this._ownerNode.getAbsolutePivotPoint());\r\n                    virtualMeshesInfo.pivotMesh.rotationQuaternion!.copyFrom(this._ownerNode.absoluteRotationQuaternion);\r\n\r\n                    virtualMeshesInfo.startingPosition.copyFrom(virtualMeshesInfo.dragMesh.position);\r\n                    virtualMeshesInfo.startingPivotPosition.copyFrom(virtualMeshesInfo.pivotMesh.position);\r\n                    virtualMeshesInfo.startingOrientation.copyFrom(virtualMeshesInfo.dragMesh.rotationQuaternion!);\r\n                    virtualMeshesInfo.startingPivotOrientation.copyFrom(virtualMeshesInfo.pivotMesh.rotationQuaternion!);\r\n\r\n                    if (isNearXRPointer) {\r\n                        virtualMeshesInfo.originMesh.addChild(virtualMeshesInfo.dragMesh);\r\n                        virtualMeshesInfo.originMesh.addChild(virtualMeshesInfo.pivotMesh);\r\n                    } else {\r\n                        virtualMeshesInfo.originMesh.lookAt(virtualMeshesInfo.dragMesh.position);\r\n                    }\r\n\r\n                    // Update state\r\n                    virtualMeshesInfo.dragging = true;\r\n\r\n                    if (this.currentDraggingPointerIds.indexOf(pointerId) === -1) {\r\n                        this.currentDraggingPointerIds.push(pointerId);\r\n                    }\r\n\r\n                    // Detach camera controls\r\n                    if (this.detachCameraControls && this._pointerCamera && !this._pointerCamera.leftCamera) {\r\n                        if (this._pointerCamera.inputs && this._pointerCamera.inputs.attachedToElement) {\r\n                            this._pointerCamera.detachControl();\r\n                            this._attachedToElement = true;\r\n                        } else if (!this.allowMultiPointer || this.currentDraggingPointerIds.length === 0) {\r\n                            this._attachedToElement = false;\r\n                        }\r\n                    }\r\n\r\n                    this._targetDragStart(virtualMeshesInfo.pivotMesh.position, virtualMeshesInfo.pivotMesh.rotationQuaternion!, pointerId);\r\n                    this.onDragStartObservable.notifyObservers({ position: virtualMeshesInfo.pivotMesh.position });\r\n                }\r\n            } else if (pointerInfo.type == PointerEventTypes.POINTERUP || pointerInfo.type == PointerEventTypes.POINTERDOUBLETAP) {\r\n                const registeredPointerIndex = this.currentDraggingPointerIds.indexOf(pointerId);\r\n\r\n                // Update state\r\n                virtualMeshesInfo.dragging = false;\r\n\r\n                if (registeredPointerIndex !== -1) {\r\n                    this.currentDraggingPointerIds.splice(registeredPointerIndex, 1);\r\n                    if (this.currentDraggingPointerIds.length === 0) {\r\n                        this._moving = false;\r\n                        this._dragging = this._dragType.NONE;\r\n\r\n                        // Reattach camera controls\r\n                        if (this.detachCameraControls && this._attachedToElement && this._pointerCamera && !this._pointerCamera.leftCamera) {\r\n                            this._reattachCameraControls();\r\n                            this._attachedToElement = false;\r\n                        }\r\n                    }\r\n\r\n                    virtualMeshesInfo.originMesh.removeChild(virtualMeshesInfo.dragMesh);\r\n                    virtualMeshesInfo.originMesh.removeChild(virtualMeshesInfo.pivotMesh);\r\n                    this._targetDragEnd(pointerId);\r\n                    this.onDragEndObservable.notifyObservers({});\r\n                }\r\n            } else if (pointerInfo.type == PointerEventTypes.POINTERMOVE) {\r\n                const registeredPointerIndex = this.currentDraggingPointerIds.indexOf(pointerId);\r\n\r\n                if (registeredPointerIndex !== -1 && virtualMeshesInfo.dragging && pointerInfo.pickInfo && (pointerInfo.pickInfo.ray || pointerInfo.pickInfo.aimTransform)) {\r\n                    let zDragFactor = this.zDragFactor;\r\n\r\n                    // 2 pointer interaction should not have a z axis drag factor\r\n                    // as well as near interaction\r\n                    if (this.currentDraggingPointerIds.length > 1 || pointerInfo.pickInfo.originMesh) {\r\n                        zDragFactor = 0;\r\n                    }\r\n\r\n                    this._ownerNode.computeWorldMatrix(true);\r\n                    if (!isNearXRPointer) {\r\n                        this._pointerUpdate2D(pointerInfo.pickInfo.ray!, pointerId, zDragFactor);\r\n                    } else {\r\n                        this._pointerUpdateXR(pointerInfo.pickInfo.aimTransform!, pointerInfo.pickInfo.gripTransform, pointerId, zDragFactor);\r\n                    }\r\n\r\n                    // Get change in rotation\r\n                    this._tmpQuaternion.copyFrom(virtualMeshesInfo.startingPivotOrientation);\r\n                    this._tmpQuaternion.x = -this._tmpQuaternion.x;\r\n                    this._tmpQuaternion.y = -this._tmpQuaternion.y;\r\n                    this._tmpQuaternion.z = -this._tmpQuaternion.z;\r\n                    virtualMeshesInfo.pivotMesh.absoluteRotationQuaternion.multiplyToRef(this._tmpQuaternion, this._tmpQuaternion);\r\n                    virtualMeshesInfo.pivotMesh.absolutePosition.subtractToRef(virtualMeshesInfo.startingPivotPosition, this._tmpVector);\r\n\r\n                    this.onDragObservable.notifyObservers({ delta: this._tmpVector, position: virtualMeshesInfo.pivotMesh.position, pickInfo: pointerInfo.pickInfo });\r\n\r\n                    // Notify herited methods and observables\r\n                    this._targetDrag(this._tmpVector, this._tmpQuaternion, pointerId);\r\n                    virtualMeshesInfo.lastDragPosition.copyFrom(virtualMeshesInfo.dragMesh.absolutePosition);\r\n\r\n                    this._moving = true;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    private _applyZOffset(node: TransformNode, localOriginDragDifference: number, zDragFactor: number) {\r\n        // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away\r\n        node.position.z -= node.position.z < 1 ? localOriginDragDifference * zDragFactor : localOriginDragDifference * zDragFactor * node.position.z;\r\n        if (node.position.z < 0) {\r\n            node.position.z = 0;\r\n        }\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _targetDragStart(worldPosition: Vector3, worldRotation: Quaternion, pointerId: number) {\r\n        // Herited classes can override that\r\n    }\r\n\r\n    protected _targetDrag(worldDeltaPosition: Vector3, worldDeltaRotation: Quaternion, pointerId: number) {\r\n        // Herited classes can override that\r\n    }\r\n\r\n    protected _targetDragEnd(pointerId: number) {\r\n        // Herited classes can override that\r\n    }\r\n\r\n    protected _reattachCameraControls() {\r\n        if (this._pointerCamera) {\r\n            // If the camera is an ArcRotateCamera, preserve the settings from the camera\r\n            // when reattaching control\r\n            if (this._pointerCamera.getClassName() === \"ArcRotateCamera\") {\r\n                const arcRotateCamera = this._pointerCamera as ArcRotateCamera;\r\n                arcRotateCamera.attachControl(\r\n                    arcRotateCamera.inputs ? arcRotateCamera.inputs.noPreventDefault : true,\r\n                    arcRotateCamera._useCtrlForPanning,\r\n                    arcRotateCamera._panningMouseButton\r\n                );\r\n            } else {\r\n                // preserve the settings from the camera when reattaching control\r\n                this._pointerCamera.attachControl(this._pointerCamera.inputs ? this._pointerCamera.inputs.noPreventDefault : true);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from the mesh\r\n     */\r\n    public detach(): void {\r\n        if (this._scene) {\r\n            if (this.detachCameraControls && this._attachedToElement && this._pointerCamera && !this._pointerCamera.leftCamera) {\r\n                this._reattachCameraControls();\r\n                this._attachedToElement = false;\r\n            }\r\n            this._scene.onPointerObservable.remove(this._pointerObserver);\r\n        }\r\n\r\n        for (const pointerId in this._virtualMeshesInfo) {\r\n            this._virtualMeshesInfo[pointerId].originMesh.dispose();\r\n            this._virtualMeshesInfo[pointerId].dragMesh.dispose();\r\n        }\r\n\r\n        this.onDragEndObservable.clear();\r\n        this.onDragObservable.clear();\r\n        this.onDragStartObservable.clear();\r\n\r\n        this._ownerNode = null!;\r\n    }\r\n}\r\n","import { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Vector3, Quaternion, Matrix, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { BaseSixDofDragBehavior } from \"./baseSixDofDragBehavior\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Space } from \"../../Maths/math.axis\";\r\n\r\n/**\r\n * A behavior that when attached to a mesh will allow the mesh to be dragged around based on directions and origin of the pointer's ray\r\n */\r\nexport class SixDofDragBehavior extends BaseSixDofDragBehavior {\r\n    private _sceneRenderObserver: Nullable<Observer<Scene>> = null;\r\n    private _virtualTransformNode: TransformNode;\r\n\r\n    protected _targetPosition = new Vector3(0, 0, 0);\r\n    protected _targetOrientation = new Quaternion();\r\n    protected _targetScaling = new Vector3(1, 1, 1);\r\n    protected _startingPosition = new Vector3(0, 0, 0);\r\n    protected _startingOrientation = new Quaternion();\r\n    protected _startingScaling = new Vector3(1, 1, 1);\r\n\r\n    /**\r\n     * Fires when position is updated\r\n     */\r\n    public onPositionChangedObservable = new Observable<{ position: Vector3 }>();\r\n\r\n    /**\r\n     * The distance towards the target drag position to move each frame. This can be useful to avoid jitter. Set this to 1 for no delay. (Default: 0.2)\r\n     */\r\n    public dragDeltaRatio = 0.2;\r\n\r\n    /**\r\n     * If the object should rotate to face the drag origin\r\n     */\r\n    public rotateDraggedObject = true;\r\n\r\n    /**\r\n     * If `rotateDraggedObject` is set to `true`, this parameter determines if we are only rotating around the y axis (yaw)\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public rotateAroundYOnly = false;\r\n\r\n    /**\r\n     * Should the behavior rotate 1:1 with the motion controller, when one is used.\r\n     */\r\n    public rotateWithMotionController = true;\r\n\r\n    /**\r\n     *  The name of the behavior\r\n     */\r\n    public override get name(): string {\r\n        return \"SixDofDrag\";\r\n    }\r\n\r\n    /**\r\n     * Use this flag to update the target but not move the owner node towards the target\r\n     */\r\n    public disableMovement: boolean = false;\r\n\r\n    /**\r\n     * Should the object rotate towards the camera when we start dragging it\r\n     */\r\n    public faceCameraOnDragStart = false;\r\n\r\n    /**\r\n     * Attaches the six DoF drag behavior\r\n     * In XR mode the mesh and its children will have their isNearGrabbable property set to true\r\n     * @param ownerNode The mesh that will be dragged around once attached\r\n     */\r\n    public override attach(ownerNode: Mesh): void {\r\n        super.attach(ownerNode);\r\n\r\n        ownerNode.isNearGrabbable = true;\r\n        // if it has children, make sure they are grabbable too\r\n        const children = ownerNode.getChildMeshes();\r\n        for (const m of children) {\r\n            m.isNearGrabbable = true;\r\n        }\r\n\r\n        // Node that will save the owner's transform\r\n        this._virtualTransformNode = new TransformNode(\"virtual_sixDof\", BaseSixDofDragBehavior._VirtualScene);\r\n        this._virtualTransformNode.rotationQuaternion = Quaternion.Identity();\r\n\r\n        // On every frame move towards target scaling to avoid jitter caused by vr controllers\r\n        this._sceneRenderObserver = ownerNode.getScene().onBeforeRenderObservable.add(() => {\r\n            if (this.currentDraggingPointerIds.length === 1 && this._moving && !this.disableMovement) {\r\n                // 1 pointer only drags mesh\r\n                const deltaToAdd = TmpVectors.Vector3[0];\r\n                deltaToAdd.copyFrom(this._targetPosition).subtractInPlace(ownerNode.absolutePosition).scaleInPlace(this.dragDeltaRatio);\r\n                const deltaToAddTransformed = TmpVectors.Vector3[1];\r\n                deltaToAddTransformed.copyFrom(deltaToAdd);\r\n                // If the node has a parent, transform the delta to local space, so it can be added to the\r\n                // position in local space\r\n                if (ownerNode.parent) {\r\n                    const parentRotationMatrixInverse = TmpVectors.Matrix[0];\r\n                    (ownerNode.parent as TransformNode).absoluteRotationQuaternion.toRotationMatrix(parentRotationMatrixInverse);\r\n                    parentRotationMatrixInverse.invert();\r\n                    Vector3.TransformNormalToRef(deltaToAdd, parentRotationMatrixInverse, deltaToAddTransformed);\r\n                }\r\n                ownerNode.position.addInPlace(deltaToAddTransformed);\r\n\r\n                this.onPositionChangedObservable.notifyObservers({ position: ownerNode.absolutePosition });\r\n\r\n                // Only rotate the mesh if it's parent has uniform scaling\r\n                if (!ownerNode.parent || ((ownerNode.parent as TransformNode).scaling && !(ownerNode.parent as TransformNode).scaling.isNonUniformWithinEpsilon(0.001))) {\r\n                    const rotationToApply = TmpVectors.Quaternion[0];\r\n                    rotationToApply.copyFrom(this._targetOrientation);\r\n                    if (ownerNode.parent) {\r\n                        const parentRotationInverse = TmpVectors.Quaternion[0];\r\n                        parentRotationInverse.copyFrom((ownerNode.parent as TransformNode).absoluteRotationQuaternion);\r\n                        parentRotationInverse.invertInPlace();\r\n                        parentRotationInverse.multiplyToRef(this._targetOrientation, rotationToApply);\r\n                    }\r\n                    Quaternion.SlerpToRef(ownerNode.rotationQuaternion!, rotationToApply, this.dragDeltaRatio, ownerNode.rotationQuaternion!);\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    private _getPositionOffsetAround(transformationLocalOrigin: Vector3, scaling: number, rotation: Quaternion): Vector3 {\r\n        const translationMatrix = TmpVectors.Matrix[0]; // T\r\n        const translationMatrixInv = TmpVectors.Matrix[1]; // T'\r\n        const rotationMatrix = TmpVectors.Matrix[2]; // R\r\n        const scaleMatrix = TmpVectors.Matrix[3]; // S\r\n        const finalMatrix = TmpVectors.Matrix[4]; // T' x R x S x T\r\n\r\n        Matrix.TranslationToRef(transformationLocalOrigin.x, transformationLocalOrigin.y, transformationLocalOrigin.z, translationMatrix); // T\r\n        Matrix.TranslationToRef(-transformationLocalOrigin.x, -transformationLocalOrigin.y, -transformationLocalOrigin.z, translationMatrixInv); // T'\r\n        Matrix.FromQuaternionToRef(rotation, rotationMatrix); // R\r\n        Matrix.ScalingToRef(scaling, scaling, scaling, scaleMatrix);\r\n        translationMatrixInv.multiplyToRef(rotationMatrix, finalMatrix); // T' x R\r\n        finalMatrix.multiplyToRef(scaleMatrix, finalMatrix); // T' x R x S\r\n        finalMatrix.multiplyToRef(translationMatrix, finalMatrix); // T' x R x S x T\r\n\r\n        return finalMatrix.getTranslation();\r\n    }\r\n\r\n    private _onePointerPositionUpdated(worldDeltaPosition: Vector3, worldDeltaRotation: Quaternion) {\r\n        const pointerDelta = TmpVectors.Vector3[0];\r\n        pointerDelta.setAll(0);\r\n\r\n        if (this._dragging === this._dragType.DRAG) {\r\n            if (this.rotateDraggedObject) {\r\n                if (this.rotateAroundYOnly) {\r\n                    // Convert change in rotation to only y axis rotation\r\n                    Quaternion.RotationYawPitchRollToRef(worldDeltaRotation.toEulerAngles().y, 0, 0, TmpVectors.Quaternion[0]);\r\n                } else {\r\n                    TmpVectors.Quaternion[0].copyFrom(worldDeltaRotation);\r\n                }\r\n                TmpVectors.Quaternion[0].multiplyToRef(this._startingOrientation, this._targetOrientation);\r\n            }\r\n        } else if (this._dragging === this._dragType.NEAR_DRAG || (this._dragging === this._dragType.DRAG_WITH_CONTROLLER && this.rotateWithMotionController)) {\r\n            worldDeltaRotation.multiplyToRef(this._startingOrientation, this._targetOrientation);\r\n        }\r\n\r\n        this._targetPosition.copyFrom(this._startingPosition).addInPlace(worldDeltaPosition);\r\n    }\r\n\r\n    private _twoPointersPositionUpdated() {\r\n        const startingPosition0 = this._virtualMeshesInfo[this.currentDraggingPointerIds[0]].startingPosition;\r\n        const startingPosition1 = this._virtualMeshesInfo[this.currentDraggingPointerIds[1]].startingPosition;\r\n        const startingCenter = TmpVectors.Vector3[0];\r\n        startingPosition0.addToRef(startingPosition1, startingCenter);\r\n        startingCenter.scaleInPlace(0.5);\r\n        const startingVector = TmpVectors.Vector3[1];\r\n        startingPosition1.subtractToRef(startingPosition0, startingVector);\r\n\r\n        const currentPosition0 = this._virtualMeshesInfo[this.currentDraggingPointerIds[0]].dragMesh.absolutePosition;\r\n        const currentPosition1 = this._virtualMeshesInfo[this.currentDraggingPointerIds[1]].dragMesh.absolutePosition;\r\n        const currentCenter = TmpVectors.Vector3[2];\r\n        currentPosition0.addToRef(currentPosition1, currentCenter);\r\n        currentCenter.scaleInPlace(0.5);\r\n        const currentVector = TmpVectors.Vector3[3];\r\n        currentPosition1.subtractToRef(currentPosition0, currentVector);\r\n\r\n        const scaling = currentVector.length() / startingVector.length();\r\n        const translation = currentCenter.subtract(startingCenter);\r\n        const rotationQuaternion = Quaternion.FromEulerAngles(\r\n            0,\r\n            Vector3.GetAngleBetweenVectorsOnPlane(startingVector.normalize(), currentVector.normalize(), Vector3.UpReadOnly),\r\n            0\r\n        );\r\n\r\n        const oldParent = this._ownerNode.parent;\r\n        this._ownerNode.setParent(null);\r\n\r\n        const positionOffset = this._getPositionOffsetAround(startingCenter.subtract(this._virtualTransformNode.getAbsolutePivotPoint()), scaling, rotationQuaternion);\r\n        this._virtualTransformNode.rotationQuaternion!.multiplyToRef(rotationQuaternion, this._ownerNode.rotationQuaternion!);\r\n        this._virtualTransformNode.scaling.scaleToRef(scaling, this._ownerNode.scaling);\r\n        this._virtualTransformNode.position.addToRef(translation.addInPlace(positionOffset), this._ownerNode.position);\r\n        this.onPositionChangedObservable.notifyObservers({ position: this._ownerNode.position });\r\n\r\n        this._ownerNode.setParent(oldParent);\r\n    }\r\n\r\n    protected override _targetDragStart() {\r\n        const pointerCount = this.currentDraggingPointerIds.length;\r\n\r\n        if (!this._ownerNode.rotationQuaternion) {\r\n            this._ownerNode.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._ownerNode.rotation.y, this._ownerNode.rotation.x, this._ownerNode.rotation.z);\r\n        }\r\n        const worldPivot = this._ownerNode.getAbsolutePivotPoint();\r\n\r\n        if (pointerCount === 1) {\r\n            this._targetPosition.copyFrom(this._ownerNode.absolutePosition);\r\n            this._targetOrientation.copyFrom(this._ownerNode.rotationQuaternion);\r\n            this._targetScaling.copyFrom(this._ownerNode.absoluteScaling);\r\n\r\n            if (this.faceCameraOnDragStart && this._scene.activeCamera) {\r\n                const toCamera = TmpVectors.Vector3[0];\r\n                this._scene.activeCamera.position.subtractToRef(worldPivot, toCamera);\r\n                toCamera.normalize();\r\n                const quat = TmpVectors.Quaternion[0];\r\n                if (this._scene.useRightHandedSystem) {\r\n                    Quaternion.FromLookDirectionRHToRef(toCamera, new Vector3(0, 1, 0), quat);\r\n                } else {\r\n                    Quaternion.FromLookDirectionLHToRef(toCamera, new Vector3(0, 1, 0), quat);\r\n                }\r\n                quat.normalize();\r\n                Quaternion.RotationYawPitchRollToRef(quat.toEulerAngles().y, 0, 0, TmpVectors.Quaternion[0]);\r\n                this._targetOrientation.copyFrom(TmpVectors.Quaternion[0]);\r\n            }\r\n            this._startingPosition.copyFrom(this._targetPosition);\r\n            this._startingOrientation.copyFrom(this._targetOrientation);\r\n            this._startingScaling.copyFrom(this._targetScaling);\r\n        } else if (pointerCount === 2) {\r\n            this._virtualTransformNode.setPivotPoint(new Vector3(0, 0, 0), Space.LOCAL);\r\n            this._virtualTransformNode.position.copyFrom(this._ownerNode.absolutePosition);\r\n            this._virtualTransformNode.scaling.copyFrom(this._ownerNode.absoluteScaling);\r\n            this._virtualTransformNode.rotationQuaternion!.copyFrom(this._ownerNode.absoluteRotationQuaternion);\r\n            this._virtualTransformNode.setPivotPoint(worldPivot, Space.WORLD);\r\n            this._resetVirtualMeshesPosition();\r\n        }\r\n    }\r\n\r\n    protected override _targetDrag(worldDeltaPosition: Vector3, worldDeltaRotation: Quaternion) {\r\n        if (this.currentDraggingPointerIds.length === 1) {\r\n            this._onePointerPositionUpdated(worldDeltaPosition, worldDeltaRotation);\r\n        } else if (this.currentDraggingPointerIds.length === 2) {\r\n            this._twoPointersPositionUpdated();\r\n        }\r\n    }\r\n\r\n    protected override _targetDragEnd() {\r\n        if (this.currentDraggingPointerIds.length === 1) {\r\n            // We still have 1 active pointer, we must simulate a dragstart with a reseted position/orientation\r\n            this._resetVirtualMeshesPosition();\r\n            const previousFaceCameraFlag = this.faceCameraOnDragStart;\r\n            this.faceCameraOnDragStart = false;\r\n            this._targetDragStart();\r\n            this.faceCameraOnDragStart = previousFaceCameraFlag;\r\n        }\r\n    }\r\n\r\n    /**\r\n     *  Detaches the behavior from the mesh\r\n     */\r\n    public override detach(): void {\r\n        if (this._ownerNode) {\r\n            this._ownerNode.getScene().onBeforeRenderObservable.remove(this._sceneRenderObserver);\r\n        }\r\n\r\n        if (this._virtualTransformNode) {\r\n            this._virtualTransformNode.dispose();\r\n        }\r\n\r\n        super.detach();\r\n    }\r\n}\r\n","import { type PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { Quaternion, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Behavior } from \"../behavior\";\r\n\r\n/**\r\n * A behavior that allows a transform node to stick to a surface position/orientation\r\n * @since 5.0.0\r\n */\r\nexport class SurfaceMagnetismBehavior implements Behavior<Mesh> {\r\n    private _scene: Scene;\r\n    private _attachedMesh: Nullable<Mesh> = null;\r\n    private _attachPointLocalOffset: Vector3 = new Vector3();\r\n    private _pointerObserver: Nullable<Observer<PointerInfo>>;\r\n    private _workingPosition: Vector3 = new Vector3();\r\n    private _workingQuaternion: Quaternion = new Quaternion();\r\n    private _lastTick: number = -1;\r\n    private _onBeforeRender: Nullable<Observer<Scene>>;\r\n    private _hit = false;\r\n\r\n    /**\r\n     * Distance offset from the hit point to place the target at, along the hit normal.\r\n     */\r\n    public hitNormalOffset: number = 0.05;\r\n\r\n    /**\r\n     * Name of the behavior\r\n     */\r\n    public get name(): string {\r\n        return \"SurfaceMagnetism\";\r\n    }\r\n\r\n    /**\r\n     * Spatial mapping meshes to collide with\r\n     */\r\n    public meshes: AbstractMesh[] = [];\r\n\r\n    /**\r\n     * Function called when the behavior needs to be initialized (after attaching it to a target)\r\n     */\r\n    public init(): void {}\r\n\r\n    /**\r\n     * Set to false if the node should strictly follow the camera without any interpolation time\r\n     */\r\n    public interpolatePose = true;\r\n\r\n    /**\r\n     * Rate of interpolation of position and rotation of the attached node.\r\n     * Higher values will give a slower interpolation.\r\n     */\r\n    public lerpTime = 250;\r\n\r\n    /**\r\n     * If true, pitch and roll are omitted.\r\n     */\r\n    public keepOrientationVertical = true;\r\n\r\n    /**\r\n     * Is this behavior reacting to pointer events\r\n     */\r\n    public enabled = true;\r\n\r\n    /**\r\n     * Maximum distance for the node to stick to the surface\r\n     */\r\n    public maxStickingDistance = 0.8;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<Mesh> {\r\n        return this._attachedMesh;\r\n    }\r\n\r\n    /**\r\n     * Attaches the behavior to a transform node\r\n     * @param target defines the target where the behavior is attached to\r\n     * @param scene the scene\r\n     */\r\n    public attach(target: Mesh, scene?: Scene): void {\r\n        this._attachedMesh = target;\r\n        this._scene = scene || target.getScene();\r\n        if (!this._attachedMesh.rotationQuaternion) {\r\n            this._attachedMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._attachedMesh.rotation.y, this._attachedMesh.rotation.x, this._attachedMesh.rotation.z);\r\n        }\r\n        this.updateAttachPoint();\r\n\r\n        this._workingPosition.copyFrom(this._attachedMesh.position);\r\n        this._workingQuaternion.copyFrom(this._attachedMesh.rotationQuaternion);\r\n        this._addObservables();\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior\r\n     */\r\n    public detach(): void {\r\n        this._attachedMesh = null;\r\n        this._removeObservables();\r\n    }\r\n\r\n    private _getTargetPose(pickingInfo: PickingInfo): Nullable<{ position: Vector3; quaternion: Quaternion }> {\r\n        if (!this._attachedMesh) {\r\n            return null;\r\n        }\r\n\r\n        if (pickingInfo && pickingInfo.hit) {\r\n            const pickedNormal = pickingInfo.getNormal(true, true);\r\n            const pickedPoint = pickingInfo.pickedPoint;\r\n\r\n            if (!pickedNormal || !pickedPoint) {\r\n                return null;\r\n            }\r\n            pickedNormal.normalize();\r\n\r\n            const worldTarget = TmpVectors.Vector3[0];\r\n            worldTarget.copyFrom(pickedNormal);\r\n            worldTarget.scaleInPlace(this.hitNormalOffset);\r\n            worldTarget.addInPlace(pickedPoint);\r\n\r\n            if (this._attachedMesh.parent) {\r\n                TmpVectors.Matrix[0].copyFrom(this._attachedMesh.parent.getWorldMatrix()).invert();\r\n                Vector3.TransformNormalToRef(worldTarget, TmpVectors.Matrix[0], worldTarget);\r\n            }\r\n\r\n            return {\r\n                position: worldTarget,\r\n                quaternion: Quaternion.RotationYawPitchRoll(\r\n                    -Math.atan2(pickedNormal.x, -pickedNormal.z),\r\n                    this.keepOrientationVertical ? 0 : Math.atan2(pickedNormal.y, Math.sqrt(pickedNormal.z * pickedNormal.z + pickedNormal.x * pickedNormal.x)),\r\n                    0\r\n                ),\r\n            };\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Updates the attach point with the current geometry extents of the attached mesh\r\n     */\r\n    public updateAttachPoint() {\r\n        this._getAttachPointOffsetToRef(this._attachPointLocalOffset);\r\n    }\r\n\r\n    /**\r\n     * Finds the intersection point of the given ray onto the meshes and updates the target.\r\n     * Transformation will be interpolated according to `interpolatePose` and `lerpTime` properties.\r\n     * If no mesh of `meshes` are hit, this does nothing.\r\n     * @param pickInfo The input pickingInfo that will be used to intersect the meshes\r\n     * @returns a boolean indicating if we found a hit to stick to\r\n     */\r\n    public findAndUpdateTarget(pickInfo: PickingInfo): boolean {\r\n        this._hit = false;\r\n        if (!pickInfo.ray) {\r\n            return false;\r\n        }\r\n\r\n        const subPicking = pickInfo.ray.intersectsMeshes(this.meshes)[0];\r\n\r\n        if (this._attachedMesh && subPicking && subPicking.hit && subPicking.pickedMesh) {\r\n            const pose = this._getTargetPose(subPicking);\r\n            if (pose && Vector3.Distance(this._attachedMesh.position, pose.position) < this.maxStickingDistance) {\r\n                this._workingPosition.copyFrom(pose.position);\r\n                this._workingQuaternion.copyFrom(pose.quaternion);\r\n                this._hit = true;\r\n            }\r\n        }\r\n\r\n        return this._hit;\r\n    }\r\n\r\n    private _getAttachPointOffsetToRef(ref: Vector3) {\r\n        if (!this._attachedMesh) {\r\n            ref.setAll(0);\r\n            return;\r\n        }\r\n\r\n        const storedQuat = TmpVectors.Quaternion[0];\r\n        storedQuat.copyFrom(this._attachedMesh.rotationQuaternion!);\r\n        this._attachedMesh.rotationQuaternion!.copyFromFloats(0, 0, 0, 1);\r\n        this._attachedMesh.computeWorldMatrix();\r\n        const boundingMinMax = this._attachedMesh.getHierarchyBoundingVectors();\r\n        const center = TmpVectors.Vector3[0];\r\n        boundingMinMax.max.addToRef(boundingMinMax.min, center);\r\n        center.scaleInPlace(0.5);\r\n        center.z = boundingMinMax.max.z;\r\n        // We max the z coordinate because we want the attach point to be on the back of the mesh\r\n        const invWorld = TmpVectors.Matrix[0];\r\n        this._attachedMesh.getWorldMatrix().invertToRef(invWorld);\r\n        Vector3.TransformCoordinatesToRef(center, invWorld, ref);\r\n        this._attachedMesh.rotationQuaternion!.copyFrom(storedQuat);\r\n    }\r\n\r\n    private _updateTransformToGoal(elapsed: number) {\r\n        if (!this._attachedMesh || !this._hit) {\r\n            return;\r\n        }\r\n\r\n        const oldParent = this._attachedMesh.parent;\r\n        this._attachedMesh.setParent(null);\r\n\r\n        const worldOffset = TmpVectors.Vector3[0];\r\n        Vector3.TransformNormalToRef(this._attachPointLocalOffset, this._attachedMesh.getWorldMatrix(), worldOffset);\r\n\r\n        if (!this.interpolatePose) {\r\n            this._attachedMesh.position.copyFrom(this._workingPosition).subtractInPlace(worldOffset);\r\n            this._attachedMesh.rotationQuaternion!.copyFrom(this._workingQuaternion);\r\n            this._attachedMesh.setParent(oldParent);\r\n            return;\r\n        }\r\n\r\n        // position\r\n        const interpolatedPosition = new Vector3();\r\n        Vector3.SmoothToRef(this._attachedMesh.position, this._workingPosition, elapsed, this.lerpTime, interpolatedPosition);\r\n        this._attachedMesh.position.copyFrom(interpolatedPosition);\r\n\r\n        // rotation\r\n        const currentRotation = new Quaternion();\r\n        currentRotation.copyFrom(this._attachedMesh.rotationQuaternion!);\r\n        Quaternion.SmoothToRef(currentRotation, this._workingQuaternion, elapsed, this.lerpTime, this._attachedMesh.rotationQuaternion!);\r\n\r\n        this._attachedMesh.setParent(oldParent);\r\n    }\r\n\r\n    private _addObservables() {\r\n        this._pointerObserver = this._scene.onPointerObservable.add((pointerInfo) => {\r\n            if (this.enabled && pointerInfo.type == PointerEventTypes.POINTERMOVE && pointerInfo.pickInfo) {\r\n                this.findAndUpdateTarget(pointerInfo.pickInfo);\r\n            }\r\n        });\r\n\r\n        this._lastTick = Date.now();\r\n        this._onBeforeRender = this._scene.onBeforeRenderObservable.add(() => {\r\n            const tick = Date.now();\r\n            this._updateTransformToGoal(tick - this._lastTick);\r\n            this._lastTick = tick;\r\n        });\r\n    }\r\n\r\n    private _removeObservables() {\r\n        this._scene.onPointerObservable.remove(this._pointerObserver);\r\n        this._scene.onBeforeRenderObservable.remove(this._onBeforeRender);\r\n        this._pointerObserver = null;\r\n        this._onBeforeRender = null;\r\n    }\r\n}\r\n","import { type Behavior } from \"../behavior\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { Matrix, Quaternion, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Clamp } from \"../../Maths/math.scalar.functions\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { Epsilon } from \"../../Maths/math.constants\";\r\n\r\n/**\r\n * A behavior that when attached to a mesh will follow a camera\r\n * @since 5.0.0\r\n */\r\nexport class FollowBehavior implements Behavior<TransformNode> {\r\n    private _scene: Scene;\r\n\r\n    // Memory cache to avoid GC usage\r\n    private _tmpQuaternion: Quaternion = new Quaternion();\r\n    private _tmpVectors: Vector3[] = [new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3()];\r\n    private _tmpMatrix: Matrix = new Matrix();\r\n    private _tmpInvertView: Matrix = new Matrix();\r\n    private _tmpForward: Vector3 = new Vector3();\r\n    private _tmpNodeForward: Vector3 = new Vector3();\r\n    private _tmpPosition: Vector3 = new Vector3();\r\n\r\n    private _followedCamera: Nullable<Camera>;\r\n    private _onBeforeRender: Nullable<Observer<Scene>>;\r\n\r\n    private _workingPosition: Vector3 = new Vector3();\r\n    private _workingQuaternion: Quaternion = new Quaternion();\r\n    private _lastTick: number = -1;\r\n    private _recenterNextUpdate = true;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public attachedNode: Nullable<TransformNode>;\r\n\r\n    /**\r\n     * Set to false if the node should strictly follow the camera without any interpolation time\r\n     */\r\n    public interpolatePose = true;\r\n\r\n    /**\r\n     * Rate of interpolation of position and rotation of the attached node.\r\n     * Higher values will give a slower interpolation.\r\n     */\r\n    public lerpTime = 500;\r\n\r\n    /**\r\n     * If the behavior should ignore the pitch and roll of the camera.\r\n     */\r\n    public ignoreCameraPitchAndRoll = false;\r\n\r\n    /**\r\n     * Pitch offset from camera (relative to Max Distance)\r\n     * Is only effective if `ignoreCameraPitchAndRoll` is set to `true`.\r\n     */\r\n    public pitchOffset = 15;\r\n\r\n    /**\r\n     * The vertical angle from the camera forward axis to the owner will not exceed this value\r\n     */\r\n    public maxViewVerticalDegrees = 30;\r\n\r\n    /**\r\n     * The horizontal angle from the camera forward axis to the owner will not exceed this value\r\n     */\r\n    public maxViewHorizontalDegrees = 30;\r\n    /**\r\n     * The attached node will not reorient until the angle between its forward vector and the vector to the camera is greater than this value\r\n     */\r\n    public orientToCameraDeadzoneDegrees = 60;\r\n    /**\r\n     * Option to ignore distance clamping\r\n     */\r\n    public ignoreDistanceClamp = false;\r\n    /**\r\n     * Option to ignore angle clamping\r\n     */\r\n    public ignoreAngleClamp = false;\r\n    /**\r\n     * Max vertical distance between the attachedNode and camera\r\n     */\r\n    public verticalMaxDistance = 0;\r\n    /**\r\n     *  Default distance from eye to attached node, i.e. the sphere radius\r\n     */\r\n    public defaultDistance = 0.8;\r\n    /**\r\n     *  Max distance from eye to attached node, i.e. the sphere radius\r\n     */\r\n    public maximumDistance = 2;\r\n    /**\r\n     *  Min distance from eye to attached node, i.e. the sphere radius\r\n     */\r\n    public minimumDistance = 0.3;\r\n\r\n    /**\r\n     * Ignore vertical movement and lock the Y position of the object.\r\n     */\r\n    public useFixedVerticalOffset = false;\r\n\r\n    /**\r\n     * Fixed vertical position offset distance.\r\n     */\r\n    public fixedVerticalOffset = 0;\r\n\r\n    /**\r\n     * Enables/disables the behavior\r\n     * @internal\r\n     */\r\n    public _enabled = true;\r\n\r\n    /**\r\n     * The camera that should be followed by this behavior\r\n     */\r\n    public get followedCamera(): Nullable<Camera> {\r\n        return this._followedCamera || this._scene.activeCamera;\r\n    }\r\n\r\n    public set followedCamera(camera: Nullable<Camera>) {\r\n        this._followedCamera = camera;\r\n    }\r\n\r\n    /**\r\n     *  The name of the behavior\r\n     */\r\n    public get name(): string {\r\n        return \"Follow\";\r\n    }\r\n\r\n    /**\r\n     *  Initializes the behavior\r\n     */\r\n    public init() {}\r\n\r\n    /**\r\n     * Attaches the follow behavior\r\n     * @param ownerNode The mesh that will be following once attached\r\n     * @param followedCamera The camera that should be followed by the node\r\n     */\r\n    public attach(ownerNode: TransformNode, followedCamera?: Camera): void {\r\n        this._scene = ownerNode.getScene();\r\n        this.attachedNode = ownerNode;\r\n\r\n        if (followedCamera) {\r\n            this.followedCamera = followedCamera;\r\n        }\r\n\r\n        this._addObservables();\r\n    }\r\n\r\n    /**\r\n     *  Detaches the behavior from the mesh\r\n     */\r\n    public detach(): void {\r\n        this.attachedNode = null;\r\n        this._removeObservables();\r\n    }\r\n\r\n    /**\r\n     * Recenters the attached node in front of the camera on the next update\r\n     */\r\n    public recenter() {\r\n        this._recenterNextUpdate = true;\r\n    }\r\n\r\n    private _angleBetweenVectorAndPlane(vector: Vector3, normal: Vector3) {\r\n        // Work on copies\r\n        this._tmpVectors[0].copyFrom(vector);\r\n        vector = this._tmpVectors[0];\r\n        this._tmpVectors[1].copyFrom(normal);\r\n        normal = this._tmpVectors[1];\r\n\r\n        vector.normalize();\r\n        normal.normalize();\r\n\r\n        return Math.PI / 2 - Math.acos(Vector3.Dot(vector, normal));\r\n    }\r\n\r\n    private _length2D(vector: Vector3) {\r\n        return Math.sqrt(vector.x * vector.x + vector.z * vector.z);\r\n    }\r\n\r\n    private _distanceClamp(currentToTarget: Vector3, moveToDefault: boolean = false) {\r\n        let minDistance = this.minimumDistance;\r\n        let maxDistance = this.maximumDistance;\r\n        const defaultDistance = this.defaultDistance;\r\n\r\n        const direction = this._tmpVectors[0];\r\n        direction.copyFrom(currentToTarget);\r\n        let currentDistance = direction.length();\r\n        direction.normalizeFromLength(currentDistance);\r\n\r\n        if (this.ignoreCameraPitchAndRoll) {\r\n            // If we don't account for pitch offset, the casted object will float up/down as the reference\r\n            // gets closer to it because we will still be casting in the direction of the pitched offset.\r\n            // To fix this, only modify the XZ position of the object.\r\n            minDistance = this._length2D(direction) * minDistance;\r\n            maxDistance = this._length2D(direction) * maxDistance;\r\n\r\n            const currentDistance2D = this._length2D(currentToTarget);\r\n            direction.scaleInPlace(currentDistance / currentDistance2D);\r\n            currentDistance = currentDistance2D;\r\n        }\r\n\r\n        let clampedDistance: number;\r\n\r\n        if (moveToDefault) {\r\n            clampedDistance = defaultDistance;\r\n        } else {\r\n            clampedDistance = Clamp(currentDistance, minDistance, maxDistance);\r\n        }\r\n\r\n        currentToTarget.copyFrom(direction).scaleInPlace(clampedDistance);\r\n\r\n        return currentDistance !== clampedDistance;\r\n    }\r\n\r\n    private _applyVerticalClamp(currentToTarget: Vector3) {\r\n        if (this.verticalMaxDistance !== 0) {\r\n            currentToTarget.y = Clamp(currentToTarget.y, -this.verticalMaxDistance, this.verticalMaxDistance);\r\n        }\r\n    }\r\n\r\n    private _toOrientationQuatToRef(vector: Vector3, quaternion: Quaternion) {\r\n        Quaternion.RotationYawPitchRollToRef(Math.atan2(vector.x, vector.z), Math.atan2(vector.y, Math.sqrt(vector.z * vector.z + vector.x * vector.x)), 0, quaternion);\r\n    }\r\n\r\n    private _applyPitchOffset(invertView: Matrix) {\r\n        const forward = this._tmpVectors[0];\r\n        const right = this._tmpVectors[1];\r\n        forward.copyFromFloats(0, 0, this._scene.useRightHandedSystem ? -1 : 1);\r\n        right.copyFromFloats(1, 0, 0);\r\n        Vector3.TransformNormalToRef(forward, invertView, forward);\r\n        forward.y = 0;\r\n        forward.normalize();\r\n        Vector3.TransformNormalToRef(right, invertView, right);\r\n\r\n        Quaternion.RotationAxisToRef(right, (this.pitchOffset * Math.PI) / 180, this._tmpQuaternion);\r\n        forward.rotateByQuaternionToRef(this._tmpQuaternion, forward);\r\n        this._toOrientationQuatToRef(forward, this._tmpQuaternion);\r\n        this._tmpQuaternion.toRotationMatrix(this._tmpMatrix);\r\n\r\n        // Since we already extracted position from the invert view matrix, we can\r\n        // disregard the position part of the matrix in the copy\r\n        invertView.copyFrom(this._tmpMatrix);\r\n    }\r\n\r\n    private _angularClamp(invertView: Matrix, currentToTarget: Vector3): boolean {\r\n        const forward = this._tmpVectors[5];\r\n        forward.copyFromFloats(0, 0, this._scene.useRightHandedSystem ? -1 : 1);\r\n        const right = this._tmpVectors[6];\r\n        right.copyFromFloats(1, 0, 0);\r\n\r\n        // forward and right are related to camera frame of reference\r\n        Vector3.TransformNormalToRef(forward, invertView, forward);\r\n        Vector3.TransformNormalToRef(right, invertView, right);\r\n\r\n        // Up is global Z\r\n        const up = Vector3.UpReadOnly;\r\n\r\n        const dist = currentToTarget.length();\r\n\r\n        if (dist < Epsilon) {\r\n            return false;\r\n        }\r\n\r\n        let angularClamped = false;\r\n        const rotationQuat = this._tmpQuaternion;\r\n\r\n        // X-axis leashing\r\n        if (this.ignoreCameraPitchAndRoll) {\r\n            const angle = Vector3.GetAngleBetweenVectorsOnPlane(currentToTarget, forward, right);\r\n            Quaternion.RotationAxisToRef(right, angle, rotationQuat);\r\n            currentToTarget.rotateByQuaternionToRef(rotationQuat, currentToTarget);\r\n        } else {\r\n            const angle = -Vector3.GetAngleBetweenVectorsOnPlane(currentToTarget, forward, right);\r\n            const minMaxAngle = ((this.maxViewVerticalDegrees * Math.PI) / 180) * 0.5;\r\n            if (angle < -minMaxAngle) {\r\n                Quaternion.RotationAxisToRef(right, -angle - minMaxAngle, rotationQuat);\r\n                currentToTarget.rotateByQuaternionToRef(rotationQuat, currentToTarget);\r\n                angularClamped = true;\r\n            } else if (angle > minMaxAngle) {\r\n                Quaternion.RotationAxisToRef(right, -angle + minMaxAngle, rotationQuat);\r\n                currentToTarget.rotateByQuaternionToRef(rotationQuat, currentToTarget);\r\n                angularClamped = true;\r\n            }\r\n        }\r\n\r\n        // Y-axis leashing\r\n        const angle = this._angleBetweenVectorAndPlane(currentToTarget, right) * (this._scene.useRightHandedSystem ? -1 : 1);\r\n        const minMaxAngle = ((this.maxViewHorizontalDegrees * Math.PI) / 180) * 0.5;\r\n        if (angle < -minMaxAngle) {\r\n            Quaternion.RotationAxisToRef(up, -angle - minMaxAngle, rotationQuat);\r\n            currentToTarget.rotateByQuaternionToRef(rotationQuat, currentToTarget);\r\n            angularClamped = true;\r\n        } else if (angle > minMaxAngle) {\r\n            Quaternion.RotationAxisToRef(up, -angle + minMaxAngle, rotationQuat);\r\n            currentToTarget.rotateByQuaternionToRef(rotationQuat, currentToTarget);\r\n            angularClamped = true;\r\n        }\r\n\r\n        return angularClamped;\r\n    }\r\n\r\n    private _orientationClamp(currentToTarget: Vector3, rotationQuaternion: Quaternion) {\r\n        // Construct a rotation quat from up vector and target vector\r\n        const toFollowed = this._tmpVectors[0];\r\n        toFollowed.copyFrom(currentToTarget).scaleInPlace(-1).normalize();\r\n\r\n        const up = this._tmpVectors[1];\r\n        const right = this._tmpVectors[2];\r\n        // We use global up vector to orient the following node (global +Y)\r\n        up.copyFromFloats(0, 1, 0);\r\n\r\n        // Gram-Schmidt to create an orthonormal frame\r\n        Vector3.CrossToRef(toFollowed, up, right);\r\n        const length = right.length();\r\n\r\n        if (length < Epsilon) {\r\n            return;\r\n        }\r\n\r\n        right.normalizeFromLength(length);\r\n\r\n        Vector3.CrossToRef(right, toFollowed, up);\r\n        if (this.attachedNode?.getScene().useRightHandedSystem) {\r\n            Quaternion.FromLookDirectionRHToRef(toFollowed, up, rotationQuaternion);\r\n        } else {\r\n            Quaternion.FromLookDirectionLHToRef(toFollowed, up, rotationQuaternion);\r\n        }\r\n    }\r\n\r\n    private _passedOrientationDeadzone(currentToTarget: Vector3, forward: Vector3) {\r\n        const leashToFollow = this._tmpVectors[5];\r\n        leashToFollow.copyFrom(currentToTarget);\r\n        leashToFollow.normalize();\r\n\r\n        const angle = Math.abs(Vector3.GetAngleBetweenVectorsOnPlane(forward, leashToFollow, Vector3.UpReadOnly));\r\n        return (angle * 180) / Math.PI > this.orientToCameraDeadzoneDegrees;\r\n    }\r\n\r\n    private _updateLeashing(camera: Camera) {\r\n        if (this.attachedNode && this._enabled) {\r\n            const oldParent = this.attachedNode.parent;\r\n            this.attachedNode.setParent(null);\r\n\r\n            const worldMatrix = this.attachedNode.getWorldMatrix();\r\n            const currentToTarget = this._workingPosition;\r\n            const rotationQuaternion = this._workingQuaternion;\r\n            const pivot = this.attachedNode.getPivotPoint();\r\n            const invertView = this._tmpInvertView;\r\n            invertView.copyFrom(camera.getViewMatrix());\r\n            invertView.invert();\r\n\r\n            Vector3.TransformCoordinatesToRef(pivot, worldMatrix, currentToTarget);\r\n            const position = this._tmpPosition;\r\n            position.copyFromFloats(0, 0, 0);\r\n            Vector3.TransformCoordinatesToRef(position, worldMatrix, position);\r\n            position.scaleInPlace(-1).subtractInPlace(pivot);\r\n            currentToTarget.subtractInPlace(camera.globalPosition);\r\n\r\n            if (this.ignoreCameraPitchAndRoll) {\r\n                this._applyPitchOffset(invertView);\r\n            }\r\n\r\n            let angularClamped = false;\r\n            const forward = this._tmpForward;\r\n            forward.copyFromFloats(0, 0, this._scene.useRightHandedSystem ? -1 : 1);\r\n            Vector3.TransformNormalToRef(forward, invertView, forward);\r\n\r\n            const nodeForward = this._tmpNodeForward;\r\n            nodeForward.copyFromFloats(0, 0, this._scene.useRightHandedSystem ? -1 : 1);\r\n            Vector3.TransformNormalToRef(nodeForward, worldMatrix, nodeForward);\r\n\r\n            if (this._recenterNextUpdate) {\r\n                currentToTarget.copyFrom(forward).scaleInPlace(this.defaultDistance);\r\n            } else {\r\n                if (this.ignoreAngleClamp) {\r\n                    const currentDistance = currentToTarget.length();\r\n                    currentToTarget.copyFrom(forward).scaleInPlace(currentDistance);\r\n                } else {\r\n                    angularClamped = this._angularClamp(invertView, currentToTarget);\r\n                }\r\n            }\r\n\r\n            let distanceClamped = false;\r\n            if (!this.ignoreDistanceClamp) {\r\n                distanceClamped = this._distanceClamp(currentToTarget, angularClamped);\r\n                this._applyVerticalClamp(currentToTarget);\r\n            }\r\n\r\n            if (this.useFixedVerticalOffset) {\r\n                currentToTarget.y = position.y - camera.globalPosition.y + this.fixedVerticalOffset;\r\n            }\r\n\r\n            if (angularClamped || distanceClamped || this._passedOrientationDeadzone(currentToTarget, nodeForward) || this._recenterNextUpdate) {\r\n                this._orientationClamp(currentToTarget, rotationQuaternion);\r\n            }\r\n\r\n            this._workingPosition.subtractInPlace(pivot);\r\n            this._recenterNextUpdate = false;\r\n\r\n            this.attachedNode.setParent(oldParent);\r\n        }\r\n    }\r\n\r\n    private _updateTransformToGoal(elapsed: number) {\r\n        if (!this.attachedNode || !this.followedCamera || !this._enabled) {\r\n            return;\r\n        }\r\n\r\n        if (!this.attachedNode.rotationQuaternion) {\r\n            this.attachedNode.rotationQuaternion = Quaternion.Identity();\r\n        }\r\n\r\n        const oldParent = this.attachedNode.parent;\r\n        this.attachedNode.setParent(null);\r\n\r\n        if (!this.interpolatePose) {\r\n            this.attachedNode.position.copyFrom(this.followedCamera.globalPosition).addInPlace(this._workingPosition);\r\n            this.attachedNode.rotationQuaternion.copyFrom(this._workingQuaternion);\r\n            this.attachedNode.setParent(oldParent);\r\n            return;\r\n        }\r\n\r\n        // position\r\n        const currentDirection = new Vector3();\r\n        currentDirection.copyFrom(this.attachedNode.position).subtractInPlace(this.followedCamera.globalPosition);\r\n        Vector3.SmoothToRef(currentDirection, this._workingPosition, elapsed, this.lerpTime, currentDirection);\r\n        currentDirection.addInPlace(this.followedCamera.globalPosition);\r\n        this.attachedNode.position.copyFrom(currentDirection);\r\n\r\n        // rotation\r\n        const currentRotation = new Quaternion();\r\n        currentRotation.copyFrom(this.attachedNode.rotationQuaternion);\r\n        Quaternion.SmoothToRef(currentRotation, this._workingQuaternion, elapsed, this.lerpTime, this.attachedNode.rotationQuaternion);\r\n\r\n        this.attachedNode.setParent(oldParent);\r\n    }\r\n\r\n    private _addObservables() {\r\n        this._lastTick = Date.now();\r\n        this._onBeforeRender = this._scene.onBeforeRenderObservable.add(() => {\r\n            if (!this.followedCamera) {\r\n                return;\r\n            }\r\n\r\n            const tick = Date.now();\r\n            this._updateLeashing(this.followedCamera);\r\n            this._updateTransformToGoal(tick - this._lastTick);\r\n            this._lastTick = tick;\r\n        });\r\n    }\r\n\r\n    private _removeObservables() {\r\n        if (this._onBeforeRender) {\r\n            this._scene.onBeforeRenderObservable.remove(this._onBeforeRender);\r\n        }\r\n    }\r\n}\r\n","import { type Observable } from \"core/Misc/observable\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type IDisposable } from \"../scene\";\r\nimport { type IWebXRAnchorSystemOptions, type WebXRAnchorSystem } from \"./features/WebXRAnchorSystem\";\r\nimport { type IWebXRBackgroundRemoverOptions, type WebXRBackgroundRemover } from \"./features/WebXRBackgroundRemover\";\r\nimport { type IWebXRBodyTrackingOptions, type WebXRBodyTracking } from \"./features/WebXRBodyTracking\";\r\nimport { type IWebXRControllerMovementOptions, type WebXRControllerMovement } from \"./features/WebXRControllerMovement\";\r\nimport { type IWebXRControllerPhysicsOptions, type WebXRControllerPhysics } from \"./features/WebXRControllerPhysics\";\r\nimport { type IWebXRControllerPointerSelectionOptions, type WebXRControllerPointerSelection } from \"./features/WebXRControllerPointerSelection\";\r\nimport { type IWebXRTeleportationOptions, type WebXRMotionControllerTeleportation } from \"./features/WebXRControllerTeleportation\";\r\nimport { type IWebXRDepthSensingOptions, type WebXRDepthSensing } from \"./features/WebXRDepthSensing\";\r\nimport { type IWebXRDomOverlayOptions, type WebXRDomOverlay } from \"./features/WebXRDOMOverlay\";\r\nimport { type WebXREyeTracking } from \"./features/WebXREyeTracking\";\r\nimport { type WebXRFeaturePointSystem } from \"./features/WebXRFeaturePointSystem\";\r\nimport { type IWebXRHandTrackingOptions, type WebXRHandTracking } from \"./features/WebXRHandTracking\";\r\nimport { type IWebXRHitTestOptions, type WebXRHitTest } from \"./features/WebXRHitTest\";\r\nimport { type IWebXRImageTrackingOptions, type WebXRImageTracking } from \"./features/WebXRImageTracking\";\r\nimport { type IWebXRLayersOptions, type WebXRLayers } from \"./features/WebXRLayers\";\r\nimport { type IWebXRLightEstimationOptions, type WebXRLightEstimation } from \"./features/WebXRLightEstimation\";\r\nimport { type IWebXRMeshDetectorOptions, type WebXRMeshDetector } from \"./features/WebXRMeshDetector\";\r\nimport { type IWebXRNearInteractionOptions, type WebXRNearInteraction } from \"./features/WebXRNearInteraction\";\r\nimport { type IWebXRPlaneDetectorOptions, type WebXRPlaneDetector } from \"./features/WebXRPlaneDetector\";\r\nimport { type IWebXRRawCameraAccessOptions, type WebXRRawCameraAccess } from \"./features/WebXRRawCameraAccess\";\r\nimport { type WebXRSpaceWarp } from \"./features/WebXRSpaceWarp\";\r\nimport { type WebXRTrackedSources } from \"./features/WebXRTrackedSources\";\r\nimport { type IWebXRWalkingLocomotionOptions, type WebXRWalkingLocomotion } from \"./features/WebXRWalkingLocomotion\";\r\nimport { _ConsumeWebXRFeatureSpecificDisableWarning } from \"./webXRFeatureWarningRegistry\";\r\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\r\n\r\n/**\r\n * Defining the interface required for a (webxr) feature\r\n */\r\nexport interface IWebXRFeature extends IDisposable {\r\n    /**\r\n     * Is this feature attached\r\n     */\r\n    attached: boolean;\r\n    /**\r\n     * Should auto-attach be disabled?\r\n     */\r\n    disableAutoAttach: boolean;\r\n    /**\r\n     * The auto-attach policy in effect before the features manager starts a manual attachment.\r\n     * @internal\r\n     */\r\n    _autoAttachPolicyBeforeAttach?: boolean;\r\n\r\n    /**\r\n     * Attach the feature to the session\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @param force should attachment be forced (even when already attached)\r\n     * @returns true if successful.\r\n     */\r\n    attach(force?: boolean): boolean;\r\n    /**\r\n     * Detach the feature from the session\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    detach(): boolean;\r\n\r\n    /**\r\n     * This function will be executed during before enabling the feature and can be used to not-allow enabling it.\r\n     * Note that at this point the session has NOT started, so this is purely checking if the browser supports it\r\n     *\r\n     * @returns whether or not the feature is compatible in this environment\r\n     */\r\n    isCompatible(): boolean;\r\n\r\n    /**\r\n     * Was this feature disposed;\r\n     */\r\n    isDisposed: boolean;\r\n\r\n    /**\r\n     * The name of the native xr feature name, if applicable (like anchor, hit-test, or hand-tracking)\r\n     */\r\n    xrNativeFeatureName?: string;\r\n\r\n    /**\r\n     * A list of (Babylon WebXR) features this feature depends on\r\n     */\r\n    dependsOn?: string[];\r\n\r\n    /**\r\n     * If this feature requires to extend the XRSessionInit object, this function will return the partial XR session init object\r\n     */\r\n    getXRSessionInitExtension?: () => Promise<Partial<XRSessionInit>>;\r\n\r\n    /**\r\n     * Triggered when the feature is attached\r\n     */\r\n    onFeatureAttachObservable: Observable<IWebXRFeature>;\r\n    /**\r\n     * Triggered when the feature is detached\r\n     */\r\n    onFeatureDetachObservable: Observable<IWebXRFeature>;\r\n}\r\n\r\n/**\r\n * A list of the currently available features without referencing them\r\n */\r\nexport class WebXRFeatureName {\r\n    /**\r\n     * The name of the anchor system feature\r\n     */\r\n    public static readonly ANCHOR_SYSTEM = \"xr-anchor-system\" as const;\r\n    /**\r\n     * The name of the background remover feature\r\n     */\r\n    public static readonly BACKGROUND_REMOVER = \"xr-background-remover\" as const;\r\n    /**\r\n     * The name of the hit test feature\r\n     */\r\n    public static readonly HIT_TEST = \"xr-hit-test\" as const;\r\n    /**\r\n     * The name of the mesh detection feature\r\n     */\r\n    public static readonly MESH_DETECTION = \"xr-mesh-detection\" as const;\r\n    /**\r\n     * physics impostors for xr controllers feature\r\n     */\r\n    public static readonly PHYSICS_CONTROLLERS = \"xr-physics-controller\" as const;\r\n    /**\r\n     * The name of the plane detection feature\r\n     */\r\n    public static readonly PLANE_DETECTION = \"xr-plane-detection\" as const;\r\n    /**\r\n     * The name of the pointer selection feature\r\n     */\r\n    public static readonly POINTER_SELECTION = \"xr-controller-pointer-selection\" as const;\r\n    /**\r\n     * The name of the teleportation feature\r\n     */\r\n    public static readonly TELEPORTATION = \"xr-controller-teleportation\" as const;\r\n    /**\r\n     * The name of the feature points feature.\r\n     */\r\n    public static readonly FEATURE_POINTS = \"xr-feature-points\" as const;\r\n    /**\r\n     * The name of the hand tracking feature.\r\n     */\r\n    public static readonly HAND_TRACKING = \"xr-hand-tracking\" as const;\r\n    /**\r\n     * The name of the image tracking feature\r\n     */\r\n    public static readonly IMAGE_TRACKING = \"xr-image-tracking\" as const;\r\n    /**\r\n     * The name of the near interaction feature\r\n     */\r\n    public static readonly NEAR_INTERACTION = \"xr-near-interaction\" as const;\r\n    /**\r\n     * The name of the DOM overlay feature\r\n     */\r\n    public static readonly DOM_OVERLAY = \"xr-dom-overlay\" as const;\r\n    /**\r\n     * The name of the movement feature\r\n     */\r\n    public static readonly MOVEMENT = \"xr-controller-movement\" as const;\r\n    /**\r\n     * The name of the light estimation feature\r\n     */\r\n    public static readonly LIGHT_ESTIMATION = \"xr-light-estimation\" as const;\r\n    /**\r\n     * The name of the eye tracking feature\r\n     */\r\n    public static readonly EYE_TRACKING = \"xr-eye-tracking\" as const;\r\n    /**\r\n     * The name of the walking locomotion feature\r\n     */\r\n    public static readonly WALKING_LOCOMOTION = \"xr-walking-locomotion\" as const;\r\n    /**\r\n     * The name of the composition layers feature\r\n     */\r\n    public static readonly LAYERS = \"xr-layers\" as const;\r\n    /**\r\n     * The name of the depth sensing feature\r\n     */\r\n    public static readonly DEPTH_SENSING = \"xr-depth-sensing\" as const;\r\n    /**\r\n     * The name of the WebXR Space Warp feature\r\n     */\r\n    public static readonly SPACE_WARP = \"xr-space-warp\" as const;\r\n    /**\r\n     * The name of the WebXR Raw Camera Access feature\r\n     */\r\n    public static readonly RAW_CAMERA_ACCESS = \"xr-raw-camera-access\" as const;\r\n    /**\r\n     * The name of the body tracking feature\r\n     */\r\n    public static readonly BODY_TRACKING = \"xr-body-tracking\" as const;\r\n    /**\r\n     * The name of the tracked sources feature\r\n     */\r\n    public static readonly TRACKED_SOURCES = \"xr-tracked-sources\" as const;\r\n}\r\n\r\nexport type WebXRFeatureNameType = (typeof WebXRFeatureName)[Exclude<keyof typeof WebXRFeatureName, \"prototype\">];\r\n\r\n/**\r\n * Maps feature names to their corresponding feature implementation classes.\r\n */\r\nexport interface IWebXRFeatureNameTypeMap {\r\n    /** Anchor system feature implementation. */\r\n    [WebXRFeatureName.ANCHOR_SYSTEM]: WebXRAnchorSystem;\r\n    /** Background remover feature implementation. */\r\n    [WebXRFeatureName.BACKGROUND_REMOVER]: WebXRBackgroundRemover;\r\n    /** Depth sensing feature implementation. */\r\n    [WebXRFeatureName.DEPTH_SENSING]: WebXRDepthSensing;\r\n    /** DOM overlay feature implementation. */\r\n    [WebXRFeatureName.DOM_OVERLAY]: WebXRDomOverlay;\r\n    /** Eye tracking feature implementation. */\r\n    [WebXRFeatureName.EYE_TRACKING]: WebXREyeTracking;\r\n    /** Feature points feature implementation. */\r\n    [WebXRFeatureName.FEATURE_POINTS]: WebXRFeaturePointSystem;\r\n    /** Hand tracking feature implementation. */\r\n    [WebXRFeatureName.HAND_TRACKING]: WebXRHandTracking;\r\n    /** Hit test feature implementation. */\r\n    [WebXRFeatureName.HIT_TEST]: WebXRHitTest;\r\n    /** Image tracking feature implementation. */\r\n    [WebXRFeatureName.IMAGE_TRACKING]: WebXRImageTracking;\r\n    /** Layers feature implementation. */\r\n    [WebXRFeatureName.LAYERS]: WebXRLayers;\r\n    /** Light estimation feature implementation. */\r\n    [WebXRFeatureName.LIGHT_ESTIMATION]: WebXRLightEstimation;\r\n    /** Mesh detection feature implementation. */\r\n    [WebXRFeatureName.MESH_DETECTION]: WebXRMeshDetector;\r\n    /** Controller movement feature implementation. */\r\n    [WebXRFeatureName.MOVEMENT]: WebXRControllerMovement;\r\n    /** Near interaction feature implementation. */\r\n    [WebXRFeatureName.NEAR_INTERACTION]: WebXRNearInteraction;\r\n    /** Physics controllers feature implementation. */\r\n    [WebXRFeatureName.PHYSICS_CONTROLLERS]: WebXRControllerPhysics;\r\n    /** Plane detection feature implementation. */\r\n    [WebXRFeatureName.PLANE_DETECTION]: WebXRPlaneDetector;\r\n    /** Controller pointer selection feature implementation. */\r\n    [WebXRFeatureName.POINTER_SELECTION]: WebXRControllerPointerSelection;\r\n    /** Raw camera access feature implementation. */\r\n    [WebXRFeatureName.RAW_CAMERA_ACCESS]: WebXRRawCameraAccess;\r\n    /** Space warp feature implementation. */\r\n    [WebXRFeatureName.SPACE_WARP]: WebXRSpaceWarp;\r\n    /** Teleportation feature implementation. */\r\n    [WebXRFeatureName.TELEPORTATION]: WebXRMotionControllerTeleportation;\r\n    /** Walking locomotion feature implementation. */\r\n    [WebXRFeatureName.WALKING_LOCOMOTION]: WebXRWalkingLocomotion;\r\n    /** Body tracking feature implementation. */\r\n    [WebXRFeatureName.BODY_TRACKING]: WebXRBodyTracking;\r\n    /** Tracked sources feature implementation. */\r\n    [WebXRFeatureName.TRACKED_SOURCES]: WebXRTrackedSources;\r\n}\r\n\r\n/**\r\n * Maps feature names to their corresponding options interfaces.\r\n */\r\nexport interface IWebXRFeatureNameOptionsMap {\r\n    /** Anchor system feature options. */\r\n    [WebXRFeatureName.ANCHOR_SYSTEM]: IWebXRAnchorSystemOptions;\r\n    /** Background remover feature options. */\r\n    [WebXRFeatureName.BACKGROUND_REMOVER]: IWebXRBackgroundRemoverOptions;\r\n    /** Depth sensing feature options. */\r\n    [WebXRFeatureName.DEPTH_SENSING]: IWebXRDepthSensingOptions;\r\n    /** DOM overlay feature options. */\r\n    [WebXRFeatureName.DOM_OVERLAY]: IWebXRDomOverlayOptions;\r\n    /** Eye tracking feature options. */\r\n    [WebXRFeatureName.EYE_TRACKING]: undefined;\r\n    /** Feature points feature options. */\r\n    [WebXRFeatureName.FEATURE_POINTS]: undefined;\r\n    /** Hand tracking feature options. */\r\n    [WebXRFeatureName.HAND_TRACKING]: IWebXRHandTrackingOptions;\r\n    /** Hit test feature options. */\r\n    [WebXRFeatureName.HIT_TEST]: IWebXRHitTestOptions;\r\n    /** Image tracking feature options. */\r\n    [WebXRFeatureName.IMAGE_TRACKING]: IWebXRImageTrackingOptions;\r\n    /** Layers feature options. */\r\n    [WebXRFeatureName.LAYERS]: IWebXRLayersOptions;\r\n    /** Light estimation feature options. */\r\n    [WebXRFeatureName.LIGHT_ESTIMATION]: IWebXRLightEstimationOptions;\r\n    /** Mesh detection feature options. */\r\n    [WebXRFeatureName.MESH_DETECTION]: IWebXRMeshDetectorOptions;\r\n    /** Controller movement feature options. */\r\n    [WebXRFeatureName.MOVEMENT]: IWebXRControllerMovementOptions;\r\n    /** Near interaction feature options. */\r\n    [WebXRFeatureName.NEAR_INTERACTION]: IWebXRNearInteractionOptions;\r\n    /** Physics controllers feature options. */\r\n    [WebXRFeatureName.PHYSICS_CONTROLLERS]: IWebXRControllerPhysicsOptions;\r\n    /** Plane detection feature options. */\r\n    [WebXRFeatureName.PLANE_DETECTION]: IWebXRPlaneDetectorOptions;\r\n    /** Controller pointer selection feature options. */\r\n    [WebXRFeatureName.POINTER_SELECTION]: IWebXRControllerPointerSelectionOptions;\r\n    /** Raw camera access feature options. */\r\n    [WebXRFeatureName.RAW_CAMERA_ACCESS]: IWebXRRawCameraAccessOptions;\r\n    /** Space warp feature options. */\r\n    [WebXRFeatureName.SPACE_WARP]: undefined;\r\n    /** Teleportation feature options. */\r\n    [WebXRFeatureName.TELEPORTATION]: IWebXRTeleportationOptions;\r\n    /** Walking locomotion feature options. */\r\n    [WebXRFeatureName.WALKING_LOCOMOTION]: IWebXRWalkingLocomotionOptions;\r\n    /** Body tracking feature options. */\r\n    [WebXRFeatureName.BODY_TRACKING]: IWebXRBodyTrackingOptions;\r\n    /** Tracked sources feature options. */\r\n    [WebXRFeatureName.TRACKED_SOURCES]: undefined;\r\n}\r\n\r\n/**\r\n * Helper type that expands/flattens a type to show its properties inline in IntelliSense\r\n */\r\ntype Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;\r\n\r\n/**\r\n * Helper type to resolve the specific feature type based on the feature name,\r\n * or fallback to IWebXRFeature if the feature name is not in the type map.\r\n */\r\nexport type ResolveWebXRFeature<T extends WebXRFeatureNameType> = T extends keyof IWebXRFeatureNameTypeMap ? IWebXRFeatureNameTypeMap[T] : IWebXRFeature;\r\n\r\n/**\r\n * Helper type to resolve the options type for a specific feature based on the feature name,\r\n * or fallback to any if the feature name is not in the type map.\r\n * The Expand utility type flattens the interface to show properties inline in IntelliSense.\r\n */\r\nexport type ResolveWebXRFeatureOptions<T extends WebXRFeatureNameType> = T extends keyof IWebXRFeatureNameOptionsMap\r\n    ? IWebXRFeatureNameOptionsMap[T] extends undefined\r\n        ? undefined\r\n        : Expand<IWebXRFeatureNameOptionsMap[T]>\r\n    : any;\r\n\r\n/**\r\n * Defining the constructor of a feature. Used to register the modules.\r\n */\r\nexport type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => () => IWebXRFeature;\r\n\r\n/**\r\n * The WebXR features manager is responsible of enabling or disabling features required for the current XR session.\r\n * It is mainly used in AR sessions.\r\n *\r\n * A feature can have a version that is defined by Babylon (and does not correspond with the webxr version).\r\n */\r\nexport class WebXRFeaturesManager implements IDisposable {\r\n    private static readonly _AvailableFeatures: {\r\n        [name: string]: {\r\n            stable: number;\r\n            latest: number;\r\n            [version: number]: WebXRFeatureConstructor;\r\n        };\r\n    } = {};\r\n\r\n    private _features: {\r\n        [name: string]: {\r\n            featureImplementation: IWebXRFeature;\r\n            version: number;\r\n            enabled: boolean;\r\n            required: boolean;\r\n        };\r\n    } = {};\r\n\r\n    /**\r\n     * The key is the feature to check and the value is the feature that conflicts.\r\n     */\r\n    private static readonly _ConflictingFeatures: { [key: string]: string } = {\r\n        [WebXRFeatureName.TELEPORTATION]: WebXRFeatureName.MOVEMENT,\r\n        [WebXRFeatureName.MOVEMENT]: WebXRFeatureName.TELEPORTATION,\r\n    };\r\n\r\n    /**\r\n     * constructs a new features manages.\r\n     *\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     */\r\n    constructor(private _xrSessionManager: WebXRSessionManager) {\r\n        // when session starts / initialized - attach\r\n        this._xrSessionManager.onXRSessionInit.add(() => {\r\n            const features = this.getEnabledFeatures();\r\n            for (const featureName of features) {\r\n                const feature = this._features[featureName];\r\n                if (feature.enabled && !feature.featureImplementation.attached && !feature.featureImplementation.disableAutoAttach) {\r\n                    this.attachFeature(featureName);\r\n                }\r\n            }\r\n        });\r\n\r\n        // when session ends - detach\r\n        this._xrSessionManager.onXRSessionEnded.add(() => {\r\n            const features = this.getEnabledFeatures();\r\n            for (const featureName of features) {\r\n                const feature = this._features[featureName];\r\n                if (feature.enabled && feature.featureImplementation.attached) {\r\n                    // detach, but don't disable!\r\n                    this.detachFeature(featureName);\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Used to register a module. After calling this function a developer can use this feature in the scene.\r\n     * Mainly used internally.\r\n     *\r\n     * @param featureName the name of the feature to register\r\n     * @param constructorFunction the function used to construct the module\r\n     * @param version the (babylon) version of the module\r\n     * @param stable is that a stable version of this module\r\n     */\r\n    public static AddWebXRFeature(featureName: string, constructorFunction: WebXRFeatureConstructor, version: number = 1, stable: boolean = false) {\r\n        this._AvailableFeatures[featureName] = this._AvailableFeatures[featureName] || { latest: version };\r\n        if (version > this._AvailableFeatures[featureName].latest) {\r\n            this._AvailableFeatures[featureName].latest = version;\r\n        }\r\n        if (stable) {\r\n            this._AvailableFeatures[featureName].stable = version;\r\n        }\r\n        this._AvailableFeatures[featureName][version] = constructorFunction;\r\n    }\r\n\r\n    /**\r\n     * Returns a constructor of a specific feature.\r\n     *\r\n     * @param featureName the name of the feature to construct\r\n     * @param version the version of the feature to load\r\n     * @param xrSessionManager the xrSessionManager. Used to construct the module\r\n     * @param options optional options provided to the module.\r\n     * @returns a function that, when called, will return a new instance of this feature\r\n     */\r\n    public static ConstructFeature(featureName: string, version: number = 1, xrSessionManager: WebXRSessionManager, options?: any): () => IWebXRFeature {\r\n        const constructorFunction = this._AvailableFeatures[featureName][version];\r\n        if (!constructorFunction) {\r\n            // throw an error? return nothing?\r\n            throw new Error(\"feature not found\");\r\n        }\r\n\r\n        return constructorFunction(xrSessionManager, options);\r\n    }\r\n\r\n    /**\r\n     * Can be used to return the list of features currently registered\r\n     *\r\n     * @returns an Array of available features\r\n     */\r\n    public static GetAvailableFeatures() {\r\n        return Object.keys(this._AvailableFeatures);\r\n    }\r\n\r\n    /**\r\n     * Gets the versions available for a specific feature\r\n     * @param featureName the name of the feature\r\n     * @returns an array with the available versions\r\n     */\r\n    public static GetAvailableVersions(featureName: string) {\r\n        return Object.keys(this._AvailableFeatures[featureName]);\r\n    }\r\n\r\n    /**\r\n     * Return the latest unstable version of this feature\r\n     * @param featureName the name of the feature to search\r\n     * @returns the version number. if not found will return -1\r\n     */\r\n    public static GetLatestVersionOfFeature(featureName: string): number {\r\n        return (this._AvailableFeatures[featureName] && this._AvailableFeatures[featureName].latest) || -1;\r\n    }\r\n\r\n    /**\r\n     * Return the latest stable version of this feature\r\n     * @param featureName the name of the feature to search\r\n     * @returns the version number. if not found will return -1\r\n     */\r\n    public static GetStableVersionOfFeature(featureName: string): number {\r\n        return (this._AvailableFeatures[featureName] && this._AvailableFeatures[featureName].stable) || -1;\r\n    }\r\n\r\n    /**\r\n     * Attach a feature to the current session. Mainly used when session started to start the feature effect.\r\n     * Can be used during a session to start a feature\r\n     * @param featureName the name of feature to attach\r\n     */\r\n    public attachFeature(featureName: string) {\r\n        const feature = this._features[featureName];\r\n        if (feature && feature.enabled && !feature.featureImplementation.attached) {\r\n            const disableAutoAttachBeforeAttach = feature.featureImplementation.disableAutoAttach;\r\n            feature.featureImplementation._autoAttachPolicyBeforeAttach = disableAutoAttachBeforeAttach;\r\n            feature.featureImplementation.disableAutoAttach = false;\r\n            let attached: boolean;\r\n            try {\r\n                attached = feature.featureImplementation.attach();\r\n            } finally {\r\n                delete feature.featureImplementation._autoAttachPolicyBeforeAttach;\r\n            }\r\n            const intentionallyDisabledDuringAttach = feature.featureImplementation.disableAutoAttach;\r\n            if (!intentionallyDisabledDuringAttach) {\r\n                feature.featureImplementation.disableAutoAttach = disableAutoAttachBeforeAttach;\r\n            }\r\n            if (!attached && !intentionallyDisabledDuringAttach) {\r\n                Tools.Warn(`Feature ${featureName} failed to attach`);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Can be used inside a session or when the session ends to detach a specific feature\r\n     * @param featureName the name of the feature to detach\r\n     */\r\n    public detachFeature(featureName: string) {\r\n        const feature = this._features[featureName];\r\n        if (feature && feature.featureImplementation.attached) {\r\n            const detached = feature.featureImplementation.detach();\r\n            if (!detached) {\r\n                Tools.Warn(`Feature ${featureName} failed to detach`);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Used to disable an already-enabled feature\r\n     * The feature will be disposed and will be recreated once enabled.\r\n     * @param featureName the feature to disable\r\n     * @returns true if disable was successful\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public disableFeature(featureName: string | { Name: string }): boolean {\r\n        const name = typeof featureName === \"string\" ? featureName : featureName.Name;\r\n        const feature = this._features[name];\r\n        if (feature && feature.enabled) {\r\n            feature.enabled = false;\r\n            this.detachFeature(name);\r\n            feature.featureImplementation.dispose();\r\n            delete this._features[name];\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * dispose this features manager\r\n     */\r\n    public dispose(): void {\r\n        const features = this.getEnabledFeatures();\r\n        for (const featureName of features) {\r\n            this.disableFeature(featureName);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enable a feature using its name and a version. This will enable it in the scene, and will be responsible to attach it when the session starts.\r\n     * If used twice, the old version will be disposed and a new one will be constructed. This way you can re-enable with different configuration.\r\n     *\r\n     * @param featureName the name of the feature to load or the class of the feature\r\n     * @param version optional version to load. if not provided the latest version will be enabled\r\n     * @param moduleOptions options provided to the module. Ses the module documentation / constructor\r\n     * @param attachIfPossible if set to true (default) the feature will be automatically attached, if it is currently possible\r\n     * @param required is this feature required to the app. If set to true the session init will fail if the feature is not available.\r\n     * @returns a new constructed feature or throws an error if feature not found or conflicts with another enabled feature.\r\n     */\r\n    public enableFeature<T extends WebXRFeatureNameType>(\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        featureName: T | { Name: T },\r\n        version: number | string = \"latest\",\r\n        moduleOptions: ResolveWebXRFeatureOptions<T> = {} as ResolveWebXRFeatureOptions<T>,\r\n        attachIfPossible: boolean = true,\r\n        required: boolean = true\r\n    ): ResolveWebXRFeature<T> {\r\n        const name = typeof featureName === \"string\" ? featureName : featureName.Name;\r\n        let versionToLoad: number;\r\n        if (typeof version === \"string\") {\r\n            if (!version) {\r\n                throw new Error(`Error in provided version - ${name} (${version})`);\r\n            }\r\n            if (version === \"stable\") {\r\n                versionToLoad = WebXRFeaturesManager.GetStableVersionOfFeature(name);\r\n            } else if (version === \"latest\") {\r\n                versionToLoad = WebXRFeaturesManager.GetLatestVersionOfFeature(name);\r\n            } else {\r\n                // try loading the number the string represents\r\n                versionToLoad = +version;\r\n            }\r\n            if (versionToLoad === -1 || isNaN(versionToLoad)) {\r\n                throw new Error(`feature not found - ${name} (${version})`);\r\n            }\r\n        } else {\r\n            versionToLoad = version;\r\n        }\r\n\r\n        // check if there is a feature conflict\r\n        const conflictingFeature = WebXRFeaturesManager._ConflictingFeatures[name];\r\n        if (conflictingFeature !== undefined && this.getEnabledFeatures().indexOf(conflictingFeature) !== -1) {\r\n            throw new Error(`Feature ${name} cannot be enabled while ${conflictingFeature} is enabled.`);\r\n        }\r\n\r\n        // check if already initialized\r\n        const feature = this._features[name];\r\n        const constructFunction = WebXRFeaturesManager.ConstructFeature(name, versionToLoad, this._xrSessionManager, moduleOptions);\r\n        if (!constructFunction) {\r\n            // report error?\r\n            throw new Error(`feature not found - ${name}`);\r\n        }\r\n\r\n        /* If the feature is already enabled, detach and dispose it, and create a new one */\r\n        if (feature) {\r\n            this.disableFeature(name);\r\n        }\r\n\r\n        const constructed = constructFunction();\r\n        if (constructed.dependsOn) {\r\n            const dependentsFound = constructed.dependsOn.every((featureName) => !!this._features[featureName]);\r\n            if (!dependentsFound) {\r\n                throw new Error(`Dependant features missing. Make sure the following features are enabled - ${constructed.dependsOn.join(\", \")}`);\r\n            }\r\n        }\r\n        _ConsumeWebXRFeatureSpecificDisableWarning(constructed);\r\n        const isCompatible = constructed.isCompatible();\r\n        const emittedSpecificDisableWarning = _ConsumeWebXRFeatureSpecificDisableWarning(constructed);\r\n        if (isCompatible) {\r\n            this._features[name] = {\r\n                featureImplementation: constructed,\r\n                enabled: true,\r\n                version: versionToLoad,\r\n                required,\r\n            };\r\n\r\n            if (attachIfPossible) {\r\n                // if session started already, request and enable\r\n                if (this._xrSessionManager.session && !this._features[name].featureImplementation.attached) {\r\n                    // enable feature\r\n                    this.attachFeature(name);\r\n                }\r\n            } else {\r\n                // disable auto-attach when session starts\r\n                this._features[name].featureImplementation.disableAutoAttach = true;\r\n            }\r\n\r\n            return this._features[name].featureImplementation as ResolveWebXRFeature<T>;\r\n        } else {\r\n            if (required) {\r\n                throw new Error(\"required feature not compatible\");\r\n            } else {\r\n                if (!emittedSpecificDisableWarning) {\r\n                    Tools.Warn(`Feature ${name} not compatible with the current environment/browser and was not enabled.`);\r\n                }\r\n                return constructed as ResolveWebXRFeature<T>;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * get the implementation of an enabled feature.\r\n     * @param featureName the name of the feature to load\r\n     * @returns the feature class, if found\r\n     */\r\n    public getEnabledFeature<T extends WebXRFeatureNameType>(featureName: T): ResolveWebXRFeature<T> {\r\n        return this._features[featureName] && (this._features[featureName].featureImplementation as ResolveWebXRFeature<T>);\r\n    }\r\n\r\n    /**\r\n     * Get the list of enabled features\r\n     * @returns an array of enabled features\r\n     */\r\n    public getEnabledFeatures() {\r\n        return Object.keys(this._features);\r\n    }\r\n\r\n    /**\r\n     * This function will extend the session creation configuration object with enabled features.\r\n     * If, for example, the anchors feature is enabled, it will be automatically added to the optional or required features list,\r\n     * according to the defined \"required\" variable, provided during enableFeature call\r\n     * @param xrSessionInit the xr Session init object to extend\r\n     *\r\n     * @returns an extended XRSessionInit object\r\n     */\r\n    public async _extendXRSessionInitObject(xrSessionInit: XRSessionInit): Promise<XRSessionInit> {\r\n        const enabledFeatures = this.getEnabledFeatures();\r\n        for (const featureName of enabledFeatures) {\r\n            const feature = this._features[featureName];\r\n            const nativeName = feature.featureImplementation.xrNativeFeatureName;\r\n            if (nativeName) {\r\n                if (feature.required) {\r\n                    xrSessionInit.requiredFeatures = xrSessionInit.requiredFeatures || [];\r\n                    if (xrSessionInit.requiredFeatures.indexOf(nativeName) === -1) {\r\n                        xrSessionInit.requiredFeatures.push(nativeName);\r\n                    }\r\n                } else {\r\n                    xrSessionInit.optionalFeatures = xrSessionInit.optionalFeatures || [];\r\n                    if (xrSessionInit.optionalFeatures.indexOf(nativeName) === -1) {\r\n                        xrSessionInit.optionalFeatures.push(nativeName);\r\n                    }\r\n                }\r\n            }\r\n            if (feature.featureImplementation.getXRSessionInitExtension) {\r\n                // eslint-disable-next-line no-await-in-loop\r\n                const extended = await feature.featureImplementation.getXRSessionInitExtension();\r\n                xrSessionInit = {\r\n                    ...xrSessionInit,\r\n                    ...extended,\r\n                };\r\n            }\r\n        }\r\n        return xrSessionInit;\r\n    }\r\n}\r\n","import { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { WebXRFeatureName, type WebXRFeaturesManager } from \"../../XR/webXRFeaturesManager\";\r\nimport { type WebXREyeTracking } from \"../../XR/features/WebXREyeTracking\";\r\nimport { type WebXRHandTracking, WebXRHandJoint } from \"../../XR/features/WebXRHandTracking.pure\";\r\nimport { type WebXRExperienceHelper } from \"../../XR/webXRExperienceHelper\";\r\nimport { type Behavior } from \"../behavior\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Quaternion, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Ray } from \"../../Culling/ray\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\n\r\n/**\r\n * Zones around the hand\r\n */\r\nexport const enum HandConstraintZone {\r\n    /**\r\n     * Above finger tips\r\n     */\r\n    ABOVE_FINGER_TIPS,\r\n    /**\r\n     * Next to the thumb\r\n     */\r\n    RADIAL_SIDE,\r\n    /**\r\n     * Next to the pinky finger\r\n     */\r\n    ULNAR_SIDE,\r\n    /**\r\n     * Below the wrist\r\n     */\r\n    BELOW_WRIST,\r\n}\r\n\r\n/**\r\n * Orientations for the hand zones and for the attached node\r\n */\r\nexport const enum HandConstraintOrientation {\r\n    /**\r\n     * Orientation is towards the camera\r\n     */\r\n    LOOK_AT_CAMERA,\r\n    /**\r\n     * Orientation is determined by the rotation of the palm\r\n     */\r\n    HAND_ROTATION,\r\n}\r\n\r\n/**\r\n * Orientations for the hand zones and for the attached node\r\n */\r\nexport const enum HandConstraintVisibility {\r\n    /**\r\n     * Constraint is always visible\r\n     */\r\n    ALWAYS_VISIBLE,\r\n    /**\r\n     * Constraint is only visible when the palm is up\r\n     */\r\n    PALM_UP,\r\n    /**\r\n     * Constraint is only visible when the user is looking at the constraint.\r\n     * Uses XR Eye Tracking if enabled/available, otherwise uses camera direction\r\n     */\r\n    GAZE_FOCUS,\r\n    /**\r\n     * Constraint is only visible when the palm is up and the user is looking at it\r\n     */\r\n    PALM_AND_GAZE,\r\n}\r\n\r\ntype HandPoseInfo = {\r\n    position: Vector3;\r\n    quaternion: Quaternion;\r\n    id: string;\r\n};\r\n\r\n/**\r\n * Hand constraint behavior that makes the attached `TransformNode` follow hands in XR experiences.\r\n * @since 5.0.0\r\n */\r\nexport class HandConstraintBehavior implements Behavior<TransformNode> {\r\n    private _scene: Scene;\r\n    private _node: TransformNode;\r\n    private _eyeTracking: Nullable<WebXREyeTracking>;\r\n    private _handTracking: Nullable<WebXRHandTracking>;\r\n    private _sceneRenderObserver: Nullable<Observer<Scene>> = null;\r\n    private _zoneAxis: { [id: number]: Vector3 } = {};\r\n\r\n    /**\r\n     * Sets the HandConstraintVisibility level for the hand constraint\r\n     */\r\n    public handConstraintVisibility: HandConstraintVisibility = HandConstraintVisibility.PALM_AND_GAZE;\r\n\r\n    /**\r\n     * A number from 0.0 to 1.0, marking how restricted the direction the palm faces is for the attached node to be enabled.\r\n     * A 1 means the palm must be directly facing the user before the node is enabled, a 0 means it is always enabled.\r\n     * Used with HandConstraintVisibility.PALM_UP\r\n     */\r\n    public palmUpStrictness: number = 0.95;\r\n\r\n    /**\r\n     * The radius in meters around the center of the hand that the user must gaze inside for the attached node to be enabled and appear.\r\n     * Used with HandConstraintVisibility.GAZE_FOCUS\r\n     */\r\n    public gazeProximityRadius: number = 0.15;\r\n\r\n    /**\r\n     * Offset distance from the hand in meters\r\n     */\r\n    public targetOffset: number = 0.1;\r\n\r\n    /**\r\n     * Where to place the node regarding the center of the hand.\r\n     */\r\n    public targetZone: HandConstraintZone = HandConstraintZone.ULNAR_SIDE;\r\n\r\n    /**\r\n     * Orientation mode of the 4 zones around the hand\r\n     */\r\n    public zoneOrientationMode: HandConstraintOrientation = HandConstraintOrientation.HAND_ROTATION;\r\n    /**\r\n     * Orientation mode of the node attached to this behavior\r\n     */\r\n    public nodeOrientationMode: HandConstraintOrientation = HandConstraintOrientation.HAND_ROTATION;\r\n\r\n    /**\r\n     * Set the hand this behavior should follow. If set to \"none\", it will follow any visible hand (prioritising the left one).\r\n     */\r\n    public handedness: XRHandedness = \"none\";\r\n\r\n    /**\r\n     * Rate of interpolation of position and rotation of the attached node.\r\n     * Higher values will give a slower interpolation.\r\n     */\r\n    public lerpTime = 100;\r\n\r\n    /**\r\n     * Attached node of this behavior\r\n     */\r\n    public get attachedNode(): Nullable<TransformNode> {\r\n        return this._node;\r\n    }\r\n\r\n    /**\r\n     * Builds a hand constraint behavior\r\n     */\r\n    constructor() {\r\n        this._node = null!;\r\n        // For a right hand\r\n        this._zoneAxis[HandConstraintZone.ABOVE_FINGER_TIPS] = new Vector3(0, 1, 0);\r\n        this._zoneAxis[HandConstraintZone.RADIAL_SIDE] = new Vector3(-1, 0, 0);\r\n        this._zoneAxis[HandConstraintZone.ULNAR_SIDE] = new Vector3(1, 0, 0);\r\n        this._zoneAxis[HandConstraintZone.BELOW_WRIST] = new Vector3(0, -1, 0);\r\n    }\r\n\r\n    /** gets or sets behavior's name */\r\n    public get name() {\r\n        return \"HandConstraint\";\r\n    }\r\n\r\n    /** Enable the behavior */\r\n    public enable() {\r\n        this._node.setEnabled(true);\r\n    }\r\n\r\n    /** Disable the behavior */\r\n    public disable() {\r\n        this._node.setEnabled(false);\r\n    }\r\n\r\n    private _getHandPose(): Nullable<HandPoseInfo> {\r\n        if (!this._handTracking) {\r\n            return null;\r\n        }\r\n\r\n        // Retrieve any available hand, starting by the left\r\n        let hand;\r\n        if (this.handedness === \"none\") {\r\n            hand = this._handTracking.getHandByHandedness(\"left\") || this._handTracking.getHandByHandedness(\"right\");\r\n        } else {\r\n            hand = this._handTracking.getHandByHandedness(this.handedness);\r\n        }\r\n\r\n        if (hand) {\r\n            const pinkyMetacarpal = hand.getJointMesh(WebXRHandJoint.PINKY_FINGER_METACARPAL);\r\n            const middleMetacarpal = hand.getJointMesh(WebXRHandJoint.MIDDLE_FINGER_METACARPAL);\r\n            const wrist = hand.getJointMesh(WebXRHandJoint.WRIST);\r\n\r\n            if (wrist && middleMetacarpal && pinkyMetacarpal) {\r\n                const handPose: HandPoseInfo = { position: middleMetacarpal.absolutePosition, quaternion: new Quaternion(), id: hand.xrController.uniqueId };\r\n\r\n                // palm forward\r\n                const up = TmpVectors.Vector3[0];\r\n                const forward = TmpVectors.Vector3[1];\r\n                const left = TmpVectors.Vector3[2];\r\n                up.copyFrom(middleMetacarpal.absolutePosition).subtractInPlace(wrist.absolutePosition).normalize();\r\n                forward.copyFrom(pinkyMetacarpal.absolutePosition).subtractInPlace(middleMetacarpal.absolutePosition).normalize();\r\n\r\n                // Create vectors for a rotation quaternion, where forward points out from the palm\r\n                Vector3.CrossToRef(up, forward, forward);\r\n                Vector3.CrossToRef(forward, up, left);\r\n\r\n                if (this.handedness === \"right\") {\r\n                    forward.negateInPlace();\r\n                }\r\n\r\n                if (this._scene.useRightHandedSystem) {\r\n                    Quaternion.FromLookDirectionRHToRef(forward, up, handPose.quaternion);\r\n                } else {\r\n                    Quaternion.FromLookDirectionLHToRef(forward, up, handPose.quaternion);\r\n                }\r\n\r\n                return handPose;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Initializes the hand constraint behavior\r\n     */\r\n    public init() {}\r\n\r\n    /**\r\n     * Attaches the hand constraint to a `TransformNode`\r\n     * @param node defines the node to attach the behavior to\r\n     */\r\n    public attach(node: TransformNode): void {\r\n        this._node = node;\r\n        this._scene = node.getScene();\r\n\r\n        if (!this._node.rotationQuaternion) {\r\n            this._node.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._node.rotation.y, this._node.rotation.x, this._node.rotation.z);\r\n        }\r\n\r\n        let lastTick = Date.now();\r\n        this._sceneRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n            const pose = this._getHandPose();\r\n\r\n            this._node.reservedDataStore = this._node.reservedDataStore || {};\r\n            this._node.reservedDataStore.nearInteraction = this._node.reservedDataStore.nearInteraction || {};\r\n            this._node.reservedDataStore.nearInteraction.excludedControllerId = null;\r\n\r\n            if (pose) {\r\n                const zoneOffset = TmpVectors.Vector3[0];\r\n                const camera = this._scene.activeCamera;\r\n\r\n                zoneOffset.copyFrom(this._zoneAxis[this.targetZone]);\r\n\r\n                const cameraLookAtQuaternion = TmpVectors.Quaternion[0];\r\n                if (camera && (this.zoneOrientationMode === HandConstraintOrientation.LOOK_AT_CAMERA || this.nodeOrientationMode === HandConstraintOrientation.LOOK_AT_CAMERA)) {\r\n                    const toCamera = TmpVectors.Vector3[1];\r\n                    toCamera.copyFrom(camera.position).subtractInPlace(pose.position).normalize();\r\n                    if (this._scene.useRightHandedSystem) {\r\n                        Quaternion.FromLookDirectionRHToRef(toCamera, Vector3.UpReadOnly, cameraLookAtQuaternion);\r\n                    } else {\r\n                        Quaternion.FromLookDirectionLHToRef(toCamera, Vector3.UpReadOnly, cameraLookAtQuaternion);\r\n                    }\r\n                }\r\n\r\n                if (this.zoneOrientationMode === HandConstraintOrientation.HAND_ROTATION) {\r\n                    pose.quaternion.toRotationMatrix(TmpVectors.Matrix[0]);\r\n                } else {\r\n                    cameraLookAtQuaternion.toRotationMatrix(TmpVectors.Matrix[0]);\r\n                }\r\n\r\n                Vector3.TransformNormalToRef(zoneOffset, TmpVectors.Matrix[0], zoneOffset);\r\n                zoneOffset.scaleInPlace(this.targetOffset);\r\n\r\n                const targetPosition = TmpVectors.Vector3[2];\r\n                const targetRotation = TmpVectors.Quaternion[1];\r\n                targetPosition.copyFrom(pose.position).addInPlace(zoneOffset);\r\n\r\n                if (this.nodeOrientationMode === HandConstraintOrientation.HAND_ROTATION) {\r\n                    targetRotation.copyFrom(pose.quaternion);\r\n                } else {\r\n                    targetRotation.copyFrom(cameraLookAtQuaternion);\r\n                }\r\n\r\n                const elapsed = Date.now() - lastTick;\r\n\r\n                Vector3.SmoothToRef(this._node.position, targetPosition, elapsed, this.lerpTime, this._node.position);\r\n                Quaternion.SmoothToRef(this._node.rotationQuaternion!, targetRotation, elapsed, this.lerpTime, this._node.rotationQuaternion!);\r\n\r\n                this._node.reservedDataStore.nearInteraction.excludedControllerId = pose.id;\r\n            }\r\n\r\n            this._setVisibility(pose);\r\n\r\n            lastTick = Date.now();\r\n        });\r\n    }\r\n\r\n    private _setVisibility(pose: Nullable<HandPoseInfo>) {\r\n        let palmVisible = true;\r\n        let gazeVisible = true;\r\n        const camera = this._scene.activeCamera;\r\n\r\n        if (camera) {\r\n            const cameraForward = camera.getForwardRay();\r\n\r\n            if (this.handConstraintVisibility === HandConstraintVisibility.GAZE_FOCUS || this.handConstraintVisibility === HandConstraintVisibility.PALM_AND_GAZE) {\r\n                gazeVisible = false;\r\n                let gaze: Ray | undefined;\r\n                if (this._eyeTracking) {\r\n                    gaze = this._eyeTracking.getEyeGaze()!;\r\n                }\r\n\r\n                gaze = gaze || cameraForward;\r\n\r\n                const gazeToBehavior = TmpVectors.Vector3[0];\r\n                if (pose) {\r\n                    pose.position.subtractToRef(gaze.origin, gazeToBehavior);\r\n                } else {\r\n                    this._node.getAbsolutePosition().subtractToRef(gaze.origin, gazeToBehavior);\r\n                }\r\n\r\n                const projectedDistance = Vector3.Dot(gazeToBehavior, gaze.direction);\r\n                const projectedSquared = projectedDistance * projectedDistance;\r\n\r\n                if (projectedDistance > 0) {\r\n                    const radiusSquared = gazeToBehavior.lengthSquared() - projectedSquared;\r\n                    if (radiusSquared < this.gazeProximityRadius * this.gazeProximityRadius) {\r\n                        gazeVisible = true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.handConstraintVisibility === HandConstraintVisibility.PALM_UP || this.handConstraintVisibility === HandConstraintVisibility.PALM_AND_GAZE) {\r\n                palmVisible = false;\r\n\r\n                if (pose) {\r\n                    const palmDirection = TmpVectors.Vector3[0];\r\n                    Vector3.LeftHandedForwardReadOnly.rotateByQuaternionToRef(pose.quaternion, palmDirection);\r\n\r\n                    if (Vector3.Dot(palmDirection, cameraForward.direction) > this.palmUpStrictness * 2 - 1) {\r\n                        palmVisible = true;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._node.setEnabled(palmVisible && gazeVisible);\r\n    }\r\n\r\n    /**\r\n     * Detaches the behavior from the `TransformNode`\r\n     */\r\n    public detach(): void {\r\n        this._scene.onBeforeRenderObservable.remove(this._sceneRenderObserver);\r\n        this._node = null!;\r\n    }\r\n\r\n    /**\r\n     * Links the behavior to the XR experience in which to retrieve hand transform information.\r\n     * @param xr xr experience\r\n     */\r\n    public linkToXRExperience(xr: WebXRExperienceHelper | WebXRFeaturesManager) {\r\n        const featuresManager: WebXRFeaturesManager = (xr as WebXRExperienceHelper).featuresManager ? (xr as WebXRExperienceHelper).featuresManager : (xr as WebXRFeaturesManager);\r\n        if (!featuresManager) {\r\n            Tools.Error(\"XR features manager must be available or provided directly for the Hand Menu to work\");\r\n        } else {\r\n            try {\r\n                this._eyeTracking = featuresManager.getEnabledFeature(WebXRFeatureName.EYE_TRACKING);\r\n            } catch {}\r\n\r\n            try {\r\n                this._handTracking = featuresManager.getEnabledFeature(WebXRFeatureName.HAND_TRACKING);\r\n            } catch {\r\n                Tools.Error(\"Hand tracking must be enabled for the Hand Menu to work\");\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type Bone } from \"./bone\";\r\nimport { Vector3, Quaternion, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Space } from \"../Maths/math.axis\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\n/**\r\n * Class used to apply inverse kinematics to bones\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons#boneikcontroller\r\n */\r\nexport class BoneIKController {\r\n    private static _TmpVecs: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];\r\n    private static _TmpQuat = Quaternion.Identity();\r\n    private static _TmpMats: Matrix[] = [Matrix.Identity(), Matrix.Identity()];\r\n\r\n    /**\r\n     * Gets or sets the target TransformNode\r\n     * Name kept as mesh for back compatibility\r\n     */\r\n    public targetMesh: TransformNode;\r\n\r\n    /** Gets or sets the mesh used as pole */\r\n    public poleTargetMesh: TransformNode;\r\n\r\n    /**\r\n     * Gets or sets the bone used as pole\r\n     */\r\n    public poleTargetBone: Nullable<Bone>;\r\n\r\n    /**\r\n     * Gets or sets the target position\r\n     */\r\n    public targetPosition = Vector3.Zero();\r\n\r\n    /**\r\n     * Gets or sets the pole target position\r\n     */\r\n    public poleTargetPosition = Vector3.Zero();\r\n\r\n    /**\r\n     * Gets or sets the pole target local offset\r\n     */\r\n    public poleTargetLocalOffset = Vector3.Zero();\r\n\r\n    /**\r\n     * Gets or sets the pole angle\r\n     */\r\n    public poleAngle = 0;\r\n\r\n    /**\r\n     * Gets or sets the TransformNode associated with the controller\r\n     * Name kept as mesh for back compatibility\r\n     */\r\n    public mesh: TransformNode;\r\n\r\n    /**\r\n     * The amount to slerp (spherical linear interpolation) to the target.  Set this to a value between 0 and 1 (a value of 1 disables slerp)\r\n     */\r\n    public slerpAmount = 1;\r\n\r\n    private _bone1Quat = Quaternion.Identity();\r\n    private _bone1Mat = Matrix.Identity();\r\n    private _bone2Ang = Math.PI;\r\n\r\n    private _bone1: Bone;\r\n    private _bone2: Bone;\r\n    private _bone1Length: number;\r\n    private _bone2Length: number;\r\n    private _maxAngle = Math.PI;\r\n    private _maxReach: number;\r\n\r\n    private _rightHandedSystem = false;\r\n\r\n    private _bendAxis = Vector3.Right();\r\n    private _slerping = false;\r\n\r\n    private _adjustRoll = 0;\r\n\r\n    private _notEnoughInformation = false;\r\n\r\n    /**\r\n     * Gets or sets maximum allowed angle\r\n     */\r\n    public get maxAngle(): number {\r\n        return this._maxAngle;\r\n    }\r\n\r\n    public set maxAngle(value: number) {\r\n        this._setMaxAngle(value);\r\n    }\r\n\r\n    /**\r\n     * Creates a new BoneIKController\r\n     * @param mesh defines the TransformNode to control\r\n     * @param bone defines the bone to control. The bone needs to have a parent bone. It also needs to have a length greater than 0 or a children we can use to infer its length.\r\n     * @param options defines options to set up the controller\r\n     * @param options.targetMesh\r\n     * @param options.poleTargetMesh\r\n     * @param options.poleTargetBone\r\n     * @param options.poleTargetLocalOffset\r\n     * @param options.poleAngle\r\n     * @param options.bendAxis\r\n     * @param options.maxAngle\r\n     * @param options.slerpAmount\r\n     */\r\n    constructor(\r\n        mesh: TransformNode,\r\n        bone: Bone,\r\n        options?: {\r\n            targetMesh?: TransformNode;\r\n            poleTargetMesh?: TransformNode;\r\n            poleTargetBone?: Bone;\r\n            poleTargetLocalOffset?: Vector3;\r\n            poleAngle?: number;\r\n            bendAxis?: Vector3;\r\n            maxAngle?: number;\r\n            slerpAmount?: number;\r\n        }\r\n    ) {\r\n        this._bone2 = bone;\r\n        const bone1 = bone.getParent();\r\n\r\n        if (!bone1) {\r\n            this._notEnoughInformation = true;\r\n            Logger.Error(\"BoneIKController: bone must have a parent for IK to work.\");\r\n            return;\r\n        }\r\n        this._bone1 = bone1;\r\n\r\n        if (this._bone2.children.length === 0 && !this._bone2.length) {\r\n            this._notEnoughInformation = true;\r\n            Logger.Error(\"BoneIKController: bone must not be a leaf or it should have a length for IK to work.\");\r\n            return;\r\n        }\r\n\r\n        this.mesh = mesh;\r\n\r\n        bone.getSkeleton().computeAbsoluteMatrices();\r\n\r\n        const bonePos = bone.getPosition();\r\n\r\n        if (bone.getAbsoluteMatrix().determinant() > 0) {\r\n            this._rightHandedSystem = true;\r\n            this._bendAxis.x = 0;\r\n            this._bendAxis.y = 0;\r\n            this._bendAxis.z = -1;\r\n\r\n            if (bonePos.x > bonePos.y && bonePos.x > bonePos.z) {\r\n                this._adjustRoll = Math.PI * 0.5;\r\n                this._bendAxis.z = 1;\r\n            }\r\n        }\r\n\r\n        if (this._bone1.length && this._bone2.length) {\r\n            const boneScale1 = this._bone1.getScale();\r\n            const boneScale2 = this._bone2.getScale();\r\n\r\n            this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;\r\n            this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;\r\n        } else if (this._bone2.children[0]) {\r\n            mesh.computeWorldMatrix(true);\r\n\r\n            const pos1 = this._bone2.children[0].getAbsolutePosition(mesh);\r\n            const pos2 = this._bone2.getAbsolutePosition(mesh);\r\n            const pos3 = this._bone1.getAbsolutePosition(mesh);\r\n\r\n            this._bone2Length = Vector3.Distance(pos1, pos2);\r\n            this._bone1Length = Vector3.Distance(pos2, pos3);\r\n        } else {\r\n            mesh.computeWorldMatrix(true);\r\n\r\n            const boneScale2 = this._bone2.getScale();\r\n            this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;\r\n\r\n            const pos2 = this._bone2.getAbsolutePosition(mesh);\r\n            const pos3 = this._bone1.getAbsolutePosition(mesh);\r\n\r\n            this._bone1Length = Vector3.Distance(pos2, pos3);\r\n        }\r\n\r\n        this._bone1.getRotationMatrixToRef(Space.WORLD, mesh, this._bone1Mat);\r\n        this.maxAngle = Math.PI;\r\n\r\n        if (options) {\r\n            if (options.targetMesh) {\r\n                this.targetMesh = options.targetMesh;\r\n                this.targetMesh.computeWorldMatrix(true);\r\n            }\r\n\r\n            if (options.poleTargetMesh) {\r\n                this.poleTargetMesh = options.poleTargetMesh;\r\n                this.poleTargetMesh.computeWorldMatrix(true);\r\n            } else if (options.poleTargetBone) {\r\n                this.poleTargetBone = options.poleTargetBone;\r\n            } else if (this._bone1.getParent()) {\r\n                this.poleTargetBone = this._bone1.getParent();\r\n            }\r\n\r\n            if (options.poleTargetLocalOffset) {\r\n                this.poleTargetLocalOffset.copyFrom(options.poleTargetLocalOffset);\r\n            }\r\n\r\n            if (options.poleAngle) {\r\n                this.poleAngle = options.poleAngle;\r\n            }\r\n\r\n            if (options.bendAxis) {\r\n                this._bendAxis.copyFrom(options.bendAxis);\r\n            }\r\n\r\n            if (options.maxAngle) {\r\n                this.maxAngle = options.maxAngle;\r\n            }\r\n\r\n            if (options.slerpAmount) {\r\n                this.slerpAmount = options.slerpAmount;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _setMaxAngle(ang: number): void {\r\n        if (ang < 0) {\r\n            ang = 0;\r\n        }\r\n\r\n        if (ang > Math.PI || ang == undefined) {\r\n            ang = Math.PI;\r\n        }\r\n\r\n        this._maxAngle = ang;\r\n\r\n        const a = this._bone1Length;\r\n        const b = this._bone2Length;\r\n\r\n        this._maxReach = Math.sqrt(a * a + b * b - 2 * a * b * Math.cos(ang));\r\n    }\r\n\r\n    /**\r\n     * Force the controller to update the bones\r\n     */\r\n    public update(): void {\r\n        if (this._notEnoughInformation) {\r\n            return;\r\n        }\r\n\r\n        const target = this.targetPosition;\r\n        const poleTarget = this.poleTargetPosition;\r\n\r\n        const mat1 = BoneIKController._TmpMats[0];\r\n        const mat2 = BoneIKController._TmpMats[1];\r\n\r\n        if (this.targetMesh) {\r\n            target.copyFrom(this.targetMesh.getAbsolutePosition());\r\n        }\r\n\r\n        if (this.poleTargetBone) {\r\n            this.poleTargetBone.getAbsolutePositionFromLocalToRef(this.poleTargetLocalOffset, this.mesh, poleTarget);\r\n        } else if (this.poleTargetMesh) {\r\n            Vector3.TransformCoordinatesToRef(this.poleTargetLocalOffset, this.poleTargetMesh.getWorldMatrix(), poleTarget);\r\n        }\r\n\r\n        const bonePos = BoneIKController._TmpVecs[0];\r\n        const zaxis = BoneIKController._TmpVecs[1];\r\n        const xaxis = BoneIKController._TmpVecs[2];\r\n        const yaxis = BoneIKController._TmpVecs[3];\r\n        const upAxis = BoneIKController._TmpVecs[4];\r\n\r\n        const tmpQuat = BoneIKController._TmpQuat;\r\n\r\n        this._bone1.getAbsolutePositionToRef(this.mesh, bonePos);\r\n\r\n        poleTarget.subtractToRef(bonePos, upAxis);\r\n\r\n        if (upAxis.x == 0 && upAxis.y == 0 && upAxis.z == 0) {\r\n            upAxis.y = 1;\r\n        } else {\r\n            upAxis.normalize();\r\n        }\r\n\r\n        target.subtractToRef(bonePos, yaxis);\r\n        yaxis.normalize();\r\n\r\n        Vector3.CrossToRef(yaxis, upAxis, zaxis);\r\n        zaxis.normalize();\r\n\r\n        Vector3.CrossToRef(yaxis, zaxis, xaxis);\r\n        xaxis.normalize();\r\n\r\n        Matrix.FromXYZAxesToRef(xaxis, yaxis, zaxis, mat1);\r\n\r\n        const a = this._bone1Length;\r\n        const b = this._bone2Length;\r\n\r\n        let c = Vector3.Distance(bonePos, target);\r\n\r\n        if (this._maxReach > 0) {\r\n            c = Math.min(this._maxReach, c);\r\n        }\r\n\r\n        let acosa = (b * b + c * c - a * a) / (2 * b * c);\r\n        let acosb = (c * c + a * a - b * b) / (2 * c * a);\r\n\r\n        if (acosa > 1) {\r\n            acosa = 1;\r\n        }\r\n\r\n        if (acosb > 1) {\r\n            acosb = 1;\r\n        }\r\n\r\n        if (acosa < -1) {\r\n            acosa = -1;\r\n        }\r\n\r\n        if (acosb < -1) {\r\n            acosb = -1;\r\n        }\r\n\r\n        const angA = Math.acos(acosa);\r\n        const angB = Math.acos(acosb);\r\n\r\n        let angC = -angA - angB;\r\n\r\n        if (this._rightHandedSystem) {\r\n            Matrix.RotationYawPitchRollToRef(0, 0, this._adjustRoll, mat2);\r\n            mat2.multiplyToRef(mat1, mat1);\r\n\r\n            Matrix.RotationAxisToRef(this._bendAxis, angB, mat2);\r\n            mat2.multiplyToRef(mat1, mat1);\r\n        } else {\r\n            const _tmpVec = BoneIKController._TmpVecs[5];\r\n\r\n            _tmpVec.copyFrom(this._bendAxis);\r\n            _tmpVec.x *= -1;\r\n\r\n            Matrix.RotationAxisToRef(_tmpVec, -angB, mat2);\r\n            mat2.multiplyToRef(mat1, mat1);\r\n        }\r\n\r\n        if (this.poleAngle) {\r\n            Matrix.RotationAxisToRef(yaxis, this.poleAngle, mat2);\r\n            mat1.multiplyToRef(mat2, mat1);\r\n        }\r\n\r\n        if (this._bone1) {\r\n            if (this.slerpAmount < 1) {\r\n                if (!this._slerping) {\r\n                    Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);\r\n                }\r\n                Quaternion.FromRotationMatrixToRef(mat1, tmpQuat);\r\n                Quaternion.SlerpToRef(this._bone1Quat, tmpQuat, this.slerpAmount, this._bone1Quat);\r\n                angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;\r\n\r\n                this._bone1.setRotationQuaternion(this._bone1Quat, Space.WORLD, this.mesh);\r\n                this._slerping = true;\r\n            } else {\r\n                this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);\r\n                this._bone1Mat.copyFrom(mat1);\r\n                this._slerping = false;\r\n            }\r\n            this._updateLinkedTransformRotation(this._bone1);\r\n        }\r\n\r\n        this._bone2.setAxisAngle(this._bendAxis, angC, Space.LOCAL);\r\n        this._updateLinkedTransformRotation(this._bone2);\r\n        this._bone2Ang = angC;\r\n    }\r\n\r\n    private _updateLinkedTransformRotation(bone: Bone): void {\r\n        if (bone._linkedTransformNode) {\r\n            if (!bone._linkedTransformNode.rotationQuaternion) {\r\n                bone._linkedTransformNode.rotationQuaternion = new Quaternion();\r\n            }\r\n            bone.getRotationQuaternionToRef(Space.LOCAL, null, bone._linkedTransformNode.rotationQuaternion);\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { BuildArray } from \"../Misc/arrayTools\";\r\nimport { Vector3, Quaternion, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type Bone } from \"./bone\";\r\nimport { Space, Axis } from \"../Maths/math.axis\";\r\n\r\n/**\r\n * Class used to make a bone look toward a point in space\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons#bonelookcontroller\r\n */\r\nexport class BoneLookController {\r\n    private static _TmpVecs: Vector3[] = BuildArray(10, Vector3.Zero);\r\n    private static _TmpQuat = Quaternion.Identity();\r\n    private static _TmpMats: Matrix[] = BuildArray(5, Matrix.Identity);\r\n\r\n    /**\r\n     * The target Vector3 that the bone will look at\r\n     */\r\n    public target: Vector3;\r\n\r\n    /**\r\n     * The TransformNode that the bone is attached to\r\n     * Name kept as mesh for back compatibility\r\n     */\r\n    public mesh: TransformNode;\r\n\r\n    /**\r\n     * The bone that will be looking to the target\r\n     */\r\n    public bone: Bone;\r\n\r\n    /**\r\n     * The up axis of the coordinate system that is used when the bone is rotated\r\n     */\r\n    public upAxis: Vector3 = Vector3.Up();\r\n\r\n    /**\r\n     * The space that the up axis is in - Space.BONE, Space.LOCAL (default), or Space.WORLD\r\n     */\r\n    public upAxisSpace: Space = Space.LOCAL;\r\n\r\n    /**\r\n     * Used to make an adjustment to the yaw of the bone\r\n     */\r\n    public adjustYaw = 0;\r\n\r\n    /**\r\n     * Used to make an adjustment to the pitch of the bone\r\n     */\r\n    public adjustPitch = 0;\r\n\r\n    /**\r\n     * Used to make an adjustment to the roll of the bone\r\n     */\r\n    public adjustRoll = 0;\r\n\r\n    /**\r\n     * The amount to slerp (spherical linear interpolation) to the target.  Set this to a value between 0 and 1 (a value of 1 disables slerp)\r\n     */\r\n    public slerpAmount = 1;\r\n\r\n    private _minYaw: number;\r\n    private _maxYaw: number;\r\n    private _minPitch: number;\r\n    private _maxPitch: number;\r\n    private _minYawSin: number;\r\n    private _minYawCos: number;\r\n    private _maxYawSin: number;\r\n    private _maxYawCos: number;\r\n    private _midYawConstraint: number;\r\n    private _minPitchTan: number;\r\n    private _maxPitchTan: number;\r\n\r\n    private _boneQuat: Quaternion = Quaternion.Identity();\r\n    private _slerping = false;\r\n    private _transformYawPitch: Matrix;\r\n    private _transformYawPitchInv: Matrix;\r\n    private _firstFrameSkipped = false;\r\n    private _yawRange: number;\r\n    private _fowardAxis: Vector3 = Vector3.Forward();\r\n\r\n    /**\r\n     * Gets or sets the minimum yaw angle that the bone can look to\r\n     */\r\n    get minYaw(): number {\r\n        return this._minYaw;\r\n    }\r\n\r\n    set minYaw(value: number) {\r\n        this._minYaw = value;\r\n        this._minYawSin = Math.sin(value);\r\n        this._minYawCos = Math.cos(value);\r\n        if (this._maxYaw != null) {\r\n            this._midYawConstraint = this._getAngleDiff(this._minYaw, this._maxYaw) * 0.5 + this._minYaw;\r\n            this._yawRange = this._maxYaw - this._minYaw;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the maximum yaw angle that the bone can look to\r\n     */\r\n    get maxYaw(): number {\r\n        return this._maxYaw;\r\n    }\r\n\r\n    set maxYaw(value: number) {\r\n        this._maxYaw = value;\r\n        this._maxYawSin = Math.sin(value);\r\n        this._maxYawCos = Math.cos(value);\r\n        if (this._minYaw != null) {\r\n            this._midYawConstraint = this._getAngleDiff(this._minYaw, this._maxYaw) * 0.5 + this._minYaw;\r\n            this._yawRange = this._maxYaw - this._minYaw;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Use the absolute value for yaw when checking the min/max constraints\r\n     */\r\n    public useAbsoluteValueForYaw = false;\r\n\r\n    /**\r\n     * Gets or sets the minimum pitch angle that the bone can look to\r\n     */\r\n    get minPitch(): number {\r\n        return this._minPitch;\r\n    }\r\n\r\n    set minPitch(value: number) {\r\n        this._minPitch = value;\r\n        this._minPitchTan = Math.tan(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the maximum pitch angle that the bone can look to\r\n     */\r\n    get maxPitch(): number {\r\n        return this._maxPitch;\r\n    }\r\n\r\n    set maxPitch(value: number) {\r\n        this._maxPitch = value;\r\n        this._maxPitchTan = Math.tan(value);\r\n    }\r\n\r\n    /**\r\n     * Create a BoneLookController\r\n     * @param mesh the TransformNode that the bone belongs to\r\n     * @param bone the bone that will be looking to the target\r\n     * @param target the target Vector3 to look at\r\n     * @param options optional settings:\r\n     * * maxYaw: the maximum angle the bone will yaw to\r\n     * * minYaw: the minimum angle the bone will yaw to\r\n     * * maxPitch: the maximum angle the bone will pitch to\r\n     * * minPitch: the minimum angle the bone will yaw to\r\n     * * slerpAmount: set the between 0 and 1 to make the bone slerp to the target.\r\n     * * upAxis: the up axis of the coordinate system\r\n     * * upAxisSpace: the space that the up axis is in - Space.BONE, Space.LOCAL (default), or Space.WORLD.\r\n     * * yawAxis: set yawAxis if the bone does not yaw on the y axis\r\n     * * pitchAxis: set pitchAxis if the bone does not pitch on the x axis\r\n     * * adjustYaw: used to make an adjustment to the yaw of the bone\r\n     * * adjustPitch: used to make an adjustment to the pitch of the bone\r\n     * * adjustRoll: used to make an adjustment to the roll of the bone\r\n     * @param options.maxYaw\r\n     * @param options.minYaw\r\n     * @param options.maxPitch\r\n     * @param options.minPitch\r\n     * @param options.slerpAmount\r\n     * @param options.upAxis\r\n     * @param options.upAxisSpace\r\n     * @param options.yawAxis\r\n     * @param options.pitchAxis\r\n     * @param options.adjustYaw\r\n     * @param options.adjustPitch\r\n     * @param options.adjustRoll\r\n     **/\r\n    constructor(\r\n        mesh: TransformNode,\r\n        bone: Bone,\r\n        target: Vector3,\r\n        options?: {\r\n            maxYaw?: number;\r\n            minYaw?: number;\r\n            maxPitch?: number;\r\n            minPitch?: number;\r\n            slerpAmount?: number;\r\n            upAxis?: Vector3;\r\n            upAxisSpace?: Space;\r\n            yawAxis?: Vector3;\r\n            pitchAxis?: Vector3;\r\n            adjustYaw?: number;\r\n            adjustPitch?: number;\r\n            adjustRoll?: number;\r\n            useAbsoluteValueForYaw?: boolean;\r\n        }\r\n    ) {\r\n        this.mesh = mesh;\r\n        this.bone = bone;\r\n        this.target = target;\r\n\r\n        if (options) {\r\n            if (options.adjustYaw) {\r\n                this.adjustYaw = options.adjustYaw;\r\n            }\r\n\r\n            if (options.adjustPitch) {\r\n                this.adjustPitch = options.adjustPitch;\r\n            }\r\n\r\n            if (options.adjustRoll) {\r\n                this.adjustRoll = options.adjustRoll;\r\n            }\r\n\r\n            if (options.maxYaw != null) {\r\n                this.maxYaw = options.maxYaw;\r\n            } else {\r\n                this.maxYaw = Math.PI;\r\n            }\r\n\r\n            if (options.minYaw != null) {\r\n                this.minYaw = options.minYaw;\r\n            } else {\r\n                this.minYaw = -Math.PI;\r\n            }\r\n\r\n            if (options.maxPitch != null) {\r\n                this.maxPitch = options.maxPitch;\r\n            } else {\r\n                this.maxPitch = Math.PI;\r\n            }\r\n\r\n            if (options.minPitch != null) {\r\n                this.minPitch = options.minPitch;\r\n            } else {\r\n                this.minPitch = -Math.PI;\r\n            }\r\n\r\n            if (options.slerpAmount != null) {\r\n                this.slerpAmount = options.slerpAmount;\r\n            }\r\n\r\n            if (options.upAxis != null) {\r\n                this.upAxis = options.upAxis;\r\n            }\r\n\r\n            if (options.upAxisSpace != null) {\r\n                this.upAxisSpace = options.upAxisSpace;\r\n            }\r\n\r\n            if (options.yawAxis != null || options.pitchAxis != null) {\r\n                let newYawAxis = Axis.Y;\r\n                let newPitchAxis = Axis.X;\r\n\r\n                if (options.yawAxis != null) {\r\n                    newYawAxis = options.yawAxis.clone();\r\n                    newYawAxis.normalize();\r\n                }\r\n\r\n                if (options.pitchAxis != null) {\r\n                    newPitchAxis = options.pitchAxis.clone();\r\n                    newPitchAxis.normalize();\r\n                }\r\n\r\n                const newRollAxis = Vector3.Cross(newPitchAxis, newYawAxis);\r\n\r\n                this._transformYawPitch = Matrix.Identity();\r\n                Matrix.FromXYZAxesToRef(newPitchAxis, newYawAxis, newRollAxis, this._transformYawPitch);\r\n\r\n                this._transformYawPitchInv = this._transformYawPitch.clone();\r\n                this._transformYawPitch.invert();\r\n            }\r\n\r\n            if (options.useAbsoluteValueForYaw !== undefined) {\r\n                this.useAbsoluteValueForYaw = options.useAbsoluteValueForYaw;\r\n            }\r\n        }\r\n\r\n        if (!bone.getParent() && this.upAxisSpace == Space.BONE) {\r\n            this.upAxisSpace = Space.LOCAL;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the bone to look at the target.  This should be called before the scene is rendered (use scene.registerBeforeRender())\r\n     */\r\n    public update(): void {\r\n        //skip the first frame when slerping so that the TransformNode rotation is correct\r\n        if (this.slerpAmount < 1 && !this._firstFrameSkipped) {\r\n            this._firstFrameSkipped = true;\r\n            return;\r\n        }\r\n\r\n        const bone = this.bone;\r\n        const bonePos = BoneLookController._TmpVecs[0];\r\n        bone.getAbsolutePositionToRef(this.mesh, bonePos);\r\n\r\n        let target = this.target;\r\n        const _tmpMat1 = BoneLookController._TmpMats[0];\r\n        const _tmpMat2 = BoneLookController._TmpMats[1];\r\n\r\n        const mesh = this.mesh;\r\n        const parentBone = bone.getParent();\r\n\r\n        const upAxis = BoneLookController._TmpVecs[1];\r\n        upAxis.copyFrom(this.upAxis);\r\n\r\n        if (this.upAxisSpace == Space.BONE && parentBone) {\r\n            if (this._transformYawPitch) {\r\n                Vector3.TransformCoordinatesToRef(upAxis, this._transformYawPitchInv, upAxis);\r\n            }\r\n            parentBone.getDirectionToRef(upAxis, this.mesh, upAxis);\r\n        } else if (this.upAxisSpace == Space.LOCAL) {\r\n            mesh.getDirectionToRef(upAxis, upAxis);\r\n            if (mesh.scaling.x != 1 || mesh.scaling.y != 1 || mesh.scaling.z != 1) {\r\n                upAxis.normalize();\r\n            }\r\n        }\r\n\r\n        let checkYaw = false;\r\n        let checkPitch = false;\r\n\r\n        if (this._maxYaw != Math.PI || this._minYaw != -Math.PI) {\r\n            checkYaw = true;\r\n        }\r\n        if (this._maxPitch != Math.PI || this._minPitch != -Math.PI) {\r\n            checkPitch = true;\r\n        }\r\n\r\n        if (checkYaw || checkPitch) {\r\n            const spaceMat = BoneLookController._TmpMats[2];\r\n            const spaceMatInv = BoneLookController._TmpMats[3];\r\n\r\n            if (this.upAxisSpace == Space.BONE && upAxis.y == 1 && parentBone) {\r\n                parentBone.getRotationMatrixToRef(Space.WORLD, this.mesh, spaceMat);\r\n            } else if (this.upAxisSpace == Space.LOCAL && upAxis.y == 1 && !parentBone) {\r\n                spaceMat.copyFrom(mesh.getWorldMatrix());\r\n            } else {\r\n                let forwardAxis = BoneLookController._TmpVecs[2];\r\n                forwardAxis.copyFrom(this._fowardAxis);\r\n\r\n                if (this._transformYawPitch) {\r\n                    Vector3.TransformCoordinatesToRef(forwardAxis, this._transformYawPitchInv, forwardAxis);\r\n                }\r\n\r\n                if (parentBone) {\r\n                    parentBone.getDirectionToRef(forwardAxis, this.mesh, forwardAxis);\r\n                } else {\r\n                    mesh.getDirectionToRef(forwardAxis, forwardAxis);\r\n                }\r\n\r\n                const rightAxis = Vector3.Cross(upAxis, forwardAxis);\r\n                rightAxis.normalize();\r\n                forwardAxis = Vector3.Cross(rightAxis, upAxis);\r\n\r\n                Matrix.FromXYZAxesToRef(rightAxis, upAxis, forwardAxis, spaceMat);\r\n            }\r\n\r\n            spaceMat.invertToRef(spaceMatInv);\r\n\r\n            let xzlen: Nullable<number> = null;\r\n\r\n            if (checkPitch) {\r\n                const localTarget = BoneLookController._TmpVecs[3];\r\n                target.subtractToRef(bonePos, localTarget);\r\n                Vector3.TransformCoordinatesToRef(localTarget, spaceMatInv, localTarget);\r\n\r\n                xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);\r\n                const pitch = Math.atan2(localTarget.y, xzlen);\r\n                let newPitch = pitch;\r\n\r\n                if (pitch > this._maxPitch) {\r\n                    localTarget.y = this._maxPitchTan * xzlen;\r\n                    newPitch = this._maxPitch;\r\n                } else if (pitch < this._minPitch) {\r\n                    localTarget.y = this._minPitchTan * xzlen;\r\n                    newPitch = this._minPitch;\r\n                }\r\n\r\n                if (pitch != newPitch) {\r\n                    Vector3.TransformCoordinatesToRef(localTarget, spaceMat, localTarget);\r\n                    localTarget.addInPlace(bonePos);\r\n                    target = localTarget;\r\n                }\r\n            }\r\n\r\n            if (checkYaw) {\r\n                const localTarget = BoneLookController._TmpVecs[4];\r\n                target.subtractToRef(bonePos, localTarget);\r\n                Vector3.TransformCoordinatesToRef(localTarget, spaceMatInv, localTarget);\r\n\r\n                const yaw = Math.atan2(localTarget.x, localTarget.z);\r\n                const yawCheck = this.useAbsoluteValueForYaw ? Math.abs(yaw) : yaw;\r\n                let newYaw = yaw;\r\n\r\n                if (yawCheck > this._maxYaw || yawCheck < this._minYaw) {\r\n                    if (xzlen == null) {\r\n                        xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);\r\n                    }\r\n\r\n                    if (this._yawRange > Math.PI) {\r\n                        if (this._isAngleBetween(yaw, this._maxYaw, this._midYawConstraint)) {\r\n                            localTarget.z = this._maxYawCos * xzlen;\r\n                            localTarget.x = this._maxYawSin * xzlen;\r\n                            newYaw = this._maxYaw;\r\n                        } else if (this._isAngleBetween(yaw, this._midYawConstraint, this._minYaw)) {\r\n                            localTarget.z = this._minYawCos * xzlen;\r\n                            localTarget.x = this._minYawSin * xzlen;\r\n                            newYaw = this._minYaw;\r\n                        }\r\n                    } else {\r\n                        if (yawCheck > this._maxYaw) {\r\n                            localTarget.z = this._maxYawCos * xzlen;\r\n                            localTarget.x = this._maxYawSin * xzlen;\r\n                            if (yaw < 0 && this.useAbsoluteValueForYaw) {\r\n                                localTarget.x *= -1;\r\n                            }\r\n                            newYaw = this._maxYaw;\r\n                        } else if (yawCheck < this._minYaw) {\r\n                            localTarget.z = this._minYawCos * xzlen;\r\n                            localTarget.x = this._minYawSin * xzlen;\r\n                            if (yaw < 0 && this.useAbsoluteValueForYaw) {\r\n                                localTarget.x *= -1;\r\n                            }\r\n                            newYaw = this._minYaw;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this._slerping && this._yawRange > Math.PI) {\r\n                    //are we going to be crossing into the min/max region?\r\n                    const boneFwd = BoneLookController._TmpVecs[8];\r\n                    boneFwd.copyFrom(Axis.Z);\r\n                    if (this._transformYawPitch) {\r\n                        Vector3.TransformCoordinatesToRef(boneFwd, this._transformYawPitchInv, boneFwd);\r\n                    }\r\n\r\n                    const boneRotMat = BoneLookController._TmpMats[4];\r\n                    this._boneQuat.toRotationMatrix(boneRotMat);\r\n                    this.mesh.getWorldMatrix().multiplyToRef(boneRotMat, boneRotMat);\r\n                    Vector3.TransformCoordinatesToRef(boneFwd, boneRotMat, boneFwd);\r\n                    Vector3.TransformCoordinatesToRef(boneFwd, spaceMatInv, boneFwd);\r\n\r\n                    const boneYaw = Math.atan2(boneFwd.x, boneFwd.z);\r\n                    const angBtwTar = this._getAngleBetween(boneYaw, yaw);\r\n                    const angBtwMidYaw = this._getAngleBetween(boneYaw, this._midYawConstraint);\r\n\r\n                    if (angBtwTar > angBtwMidYaw) {\r\n                        if (xzlen == null) {\r\n                            xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);\r\n                        }\r\n\r\n                        const angBtwMax = this._getAngleBetween(boneYaw, this._maxYaw);\r\n                        const angBtwMin = this._getAngleBetween(boneYaw, this._minYaw);\r\n\r\n                        if (angBtwMin < angBtwMax) {\r\n                            newYaw = boneYaw + Math.PI * 0.75;\r\n                            localTarget.z = Math.cos(newYaw) * xzlen;\r\n                            localTarget.x = Math.sin(newYaw) * xzlen;\r\n                        } else {\r\n                            newYaw = boneYaw - Math.PI * 0.75;\r\n                            localTarget.z = Math.cos(newYaw) * xzlen;\r\n                            localTarget.x = Math.sin(newYaw) * xzlen;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (yaw != newYaw) {\r\n                    Vector3.TransformCoordinatesToRef(localTarget, spaceMat, localTarget);\r\n                    localTarget.addInPlace(bonePos);\r\n                    target = localTarget;\r\n                }\r\n            }\r\n        }\r\n\r\n        const zaxis = BoneLookController._TmpVecs[5];\r\n        const xaxis = BoneLookController._TmpVecs[6];\r\n        const yaxis = BoneLookController._TmpVecs[7];\r\n        const tmpQuat = BoneLookController._TmpQuat;\r\n        const boneScaling = BoneLookController._TmpVecs[9];\r\n\r\n        target.subtractToRef(bonePos, zaxis);\r\n        zaxis.normalize();\r\n        Vector3.CrossToRef(upAxis, zaxis, xaxis);\r\n        xaxis.normalize();\r\n        Vector3.CrossToRef(zaxis, xaxis, yaxis);\r\n        yaxis.normalize();\r\n        Matrix.FromXYZAxesToRef(xaxis, yaxis, zaxis, _tmpMat1);\r\n\r\n        if (xaxis.x === 0 && xaxis.y === 0 && xaxis.z === 0) {\r\n            return;\r\n        }\r\n\r\n        if (yaxis.x === 0 && yaxis.y === 0 && yaxis.z === 0) {\r\n            return;\r\n        }\r\n\r\n        if (zaxis.x === 0 && zaxis.y === 0 && zaxis.z === 0) {\r\n            return;\r\n        }\r\n\r\n        if (this.adjustYaw || this.adjustPitch || this.adjustRoll) {\r\n            Matrix.RotationYawPitchRollToRef(this.adjustYaw, this.adjustPitch, this.adjustRoll, _tmpMat2);\r\n            _tmpMat2.multiplyToRef(_tmpMat1, _tmpMat1);\r\n        }\r\n\r\n        boneScaling.copyFrom(this.bone.getScale());\r\n\r\n        if (this.slerpAmount < 1) {\r\n            if (!this._slerping) {\r\n                this.bone.getRotationQuaternionToRef(Space.WORLD, this.mesh, this._boneQuat);\r\n            }\r\n            if (this._transformYawPitch) {\r\n                this._transformYawPitch.multiplyToRef(_tmpMat1, _tmpMat1);\r\n            }\r\n            Quaternion.FromRotationMatrixToRef(_tmpMat1, tmpQuat);\r\n            Quaternion.SlerpToRef(this._boneQuat, tmpQuat, this.slerpAmount, this._boneQuat);\r\n\r\n            this.bone.setRotationQuaternion(this._boneQuat, Space.WORLD, this.mesh);\r\n            this._slerping = true;\r\n        } else {\r\n            if (this._transformYawPitch) {\r\n                this._transformYawPitch.multiplyToRef(_tmpMat1, _tmpMat1);\r\n            }\r\n            this.bone.setRotationMatrix(_tmpMat1, Space.WORLD, this.mesh);\r\n            this._slerping = false;\r\n        }\r\n\r\n        this.bone.setScale(boneScaling);\r\n\r\n        this._updateLinkedTransformRotation();\r\n    }\r\n\r\n    private _getAngleDiff(ang1: number, ang2: number): number {\r\n        let angDiff = ang2 - ang1;\r\n        angDiff %= Math.PI * 2;\r\n\r\n        if (angDiff > Math.PI) {\r\n            angDiff -= Math.PI * 2;\r\n        } else if (angDiff < -Math.PI) {\r\n            angDiff += Math.PI * 2;\r\n        }\r\n\r\n        return angDiff;\r\n    }\r\n\r\n    private _getAngleBetween(ang1: number, ang2: number): number {\r\n        ang1 %= 2 * Math.PI;\r\n        ang1 = ang1 < 0 ? ang1 + 2 * Math.PI : ang1;\r\n\r\n        ang2 %= 2 * Math.PI;\r\n        ang2 = ang2 < 0 ? ang2 + 2 * Math.PI : ang2;\r\n\r\n        let ab: number;\r\n\r\n        if (ang1 < ang2) {\r\n            ab = ang2 - ang1;\r\n        } else {\r\n            ab = ang1 - ang2;\r\n        }\r\n\r\n        if (ab > Math.PI) {\r\n            ab = Math.PI * 2 - ab;\r\n        }\r\n\r\n        return ab;\r\n    }\r\n\r\n    private _isAngleBetween(ang: number, ang1: number, ang2: number): boolean {\r\n        ang %= 2 * Math.PI;\r\n        ang = ang < 0 ? ang + 2 * Math.PI : ang;\r\n        ang1 %= 2 * Math.PI;\r\n        ang1 = ang1 < 0 ? ang1 + 2 * Math.PI : ang1;\r\n        ang2 %= 2 * Math.PI;\r\n        ang2 = ang2 < 0 ? ang2 + 2 * Math.PI : ang2;\r\n\r\n        if (ang1 < ang2) {\r\n            if (ang > ang1 && ang < ang2) {\r\n                return true;\r\n            }\r\n        } else {\r\n            if (ang > ang2 && ang < ang1) {\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    private _updateLinkedTransformRotation(): void {\r\n        const bone = this.bone;\r\n        if (bone._linkedTransformNode) {\r\n            if (!bone._linkedTransformNode.rotationQuaternion) {\r\n                bone._linkedTransformNode.rotationQuaternion = new Quaternion();\r\n            }\r\n            bone.getRotationQuaternionToRef(Space.LOCAL, null, bone._linkedTransformNode.rotationQuaternion);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type FloatArray } from \"../../types\";\r\nimport { TmpVectors, type Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector2, type Vector4 } from \"../../Maths/math.vector\";\r\nimport { type Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh, _CreationDataStorage } from \"../mesh.pure\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData for a Ribbon\r\n * @param options an object used to set the following optional parameters for the ribbon, required but can be empty\r\n * * pathArray array of paths, each of which an array of successive Vector3\r\n * * closeArray creates a seam between the first and the last paths of the pathArray, optional, default false\r\n * * closePath creates a seam between the first and the last points of each path of the path array, optional, default false\r\n * * offset a positive integer, only used when pathArray contains a single path (offset = 10 means the point 1 is joined to the point 11), default rounded half size of the pathArray length\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * * invertUV swaps in the U and V coordinates when applying a texture, optional, default false\r\n * * uvs a linear array, of length 2 * number of vertices, of custom UV values, optional\r\n * * colors a linear array, of length 4 * number of vertices, of custom color values, optional\r\n * @returns the VertexData of the ribbon\r\n */\r\nexport function CreateRibbonVertexData(options: {\r\n    pathArray: Vector3[][];\r\n    closeArray?: boolean;\r\n    closePath?: boolean;\r\n    offset?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n    invertUV?: boolean;\r\n    uvs?: Vector2[];\r\n    colors?: Color4[];\r\n}): VertexData {\r\n    let pathArray: Vector3[][] = options.pathArray;\r\n    const closeArray: boolean = options.closeArray || false;\r\n    const closePath: boolean = options.closePath || false;\r\n    const invertUV: boolean = options.invertUV || false;\r\n    const defaultOffset: number = Math.floor(pathArray[0].length / 2);\r\n    let offset: number = options.offset || defaultOffset;\r\n    offset = offset > defaultOffset ? defaultOffset : Math.floor(offset); // offset max allowed : defaultOffset\r\n    const sideOrientation: number = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n    const customUV = options.uvs;\r\n    const customColors = options.colors;\r\n\r\n    const positions: number[] = [];\r\n    const indices: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n\r\n    const us: number[][] = []; // us[path_id] = [uDist1, uDist2, uDist3 ... ] distances between points on path path_id\r\n    const vs: number[][] = []; // vs[i] = [vDist1, vDist2, vDist3, ... ] distances between points i of consecutive paths from pathArray\r\n    const uTotalDistance: number[] = []; // uTotalDistance[p] : total distance of path p\r\n    const vTotalDistance: number[] = []; //  vTotalDistance[i] : total distance between points i of first and last path from pathArray\r\n    let minlg: number; // minimal length among all paths from pathArray\r\n    const lg: number[] = []; // array of path lengths : nb of vertex per path\r\n    const idx: number[] = []; // array of path indexes : index of each path (first vertex) in the total vertex number\r\n    let p: number; // path iterator\r\n    let i: number; // point iterator\r\n    let j: number; // point iterator\r\n\r\n    // if single path in pathArray\r\n    if (pathArray.length < 2) {\r\n        const ar1: Vector3[] = [];\r\n        const ar2: Vector3[] = [];\r\n        for (i = 0; i < pathArray[0].length - offset; i++) {\r\n            ar1.push(pathArray[0][i]);\r\n            ar2.push(pathArray[0][i + offset]);\r\n        }\r\n        pathArray = [ar1, ar2];\r\n    }\r\n\r\n    // positions and horizontal distances (u)\r\n    let idc: number = 0;\r\n    const closePathCorr: number = closePath ? 1 : 0; // the final index will be +1 if closePath\r\n    const closeArrayCorr: number = closeArray ? 1 : 0;\r\n    let path: Vector3[];\r\n    let l: number;\r\n    minlg = pathArray[0].length;\r\n    let vectlg: number;\r\n    let dist: number;\r\n    for (p = 0; p < pathArray.length + closeArrayCorr; p++) {\r\n        uTotalDistance[p] = 0;\r\n        us[p] = [0];\r\n        path = p === pathArray.length ? pathArray[0] : pathArray[p];\r\n        l = path.length;\r\n        minlg = minlg < l ? minlg : l;\r\n\r\n        j = 0;\r\n        while (j < l) {\r\n            positions.push(path[j].x, path[j].y, path[j].z);\r\n            if (j > 0) {\r\n                vectlg = path[j].subtract(path[j - 1]).length();\r\n                dist = vectlg + uTotalDistance[p];\r\n                us[p].push(dist);\r\n                uTotalDistance[p] = dist;\r\n            }\r\n            j++;\r\n        }\r\n\r\n        if (closePath) {\r\n            // an extra hidden vertex is added in the \"positions\" array\r\n            j--;\r\n            positions.push(path[0].x, path[0].y, path[0].z);\r\n            vectlg = path[j].subtract(path[0]).length();\r\n            dist = vectlg + uTotalDistance[p];\r\n            us[p].push(dist);\r\n            uTotalDistance[p] = dist;\r\n        }\r\n\r\n        lg[p] = l + closePathCorr;\r\n        idx[p] = idc;\r\n        idc += l + closePathCorr;\r\n    }\r\n\r\n    // vertical distances (v)\r\n    let path1: Vector3[];\r\n    let path2: Vector3[];\r\n    let vertex1: Nullable<Vector3>;\r\n    let vertex2: Nullable<Vector3>;\r\n    for (i = 0; i < minlg + closePathCorr; i++) {\r\n        vTotalDistance[i] = 0;\r\n        vs[i] = [0];\r\n        for (p = 0; p < pathArray.length - 1 + closeArrayCorr; p++) {\r\n            path1 = pathArray[p];\r\n            path2 = p === pathArray.length - 1 ? pathArray[0] : pathArray[p + 1];\r\n            if (i === minlg) {\r\n                // closePath\r\n                vertex1 = path1[0];\r\n                vertex2 = path2[0];\r\n            } else {\r\n                vertex1 = path1[i];\r\n                vertex2 = path2[i];\r\n            }\r\n            vectlg = vertex2.subtract(vertex1).length();\r\n            dist = vectlg + vTotalDistance[i];\r\n            vs[i].push(dist);\r\n            vTotalDistance[i] = dist;\r\n        }\r\n    }\r\n\r\n    // uvs\r\n    let u: number;\r\n    let v: number;\r\n    if (customUV) {\r\n        for (p = 0; p < customUV.length; p++) {\r\n            uvs.push(customUV[p].x, useOpenGLOrientationForUV ? 1.0 - customUV[p].y : customUV[p].y);\r\n        }\r\n    } else {\r\n        for (p = 0; p < pathArray.length + closeArrayCorr; p++) {\r\n            for (i = 0; i < minlg + closePathCorr; i++) {\r\n                u = uTotalDistance[p] != 0.0 ? us[p][i] / uTotalDistance[p] : 0.0;\r\n                v = vTotalDistance[i] != 0.0 ? vs[i][p] / vTotalDistance[i] : 0.0;\r\n                if (invertUV) {\r\n                    uvs.push(v, u);\r\n                } else {\r\n                    uvs.push(u, useOpenGLOrientationForUV ? 1.0 - v : v);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // indices\r\n    p = 0; // path index\r\n    let pi: number = 0; // positions array index\r\n    let l1: number = lg[p] - 1; // path1 length\r\n    let l2: number = lg[p + 1] - 1; // path2 length\r\n    let min: number = l1 < l2 ? l1 : l2; // current path stop index\r\n    let shft: number = idx[1] - idx[0]; // shift\r\n    const path1nb: number = lg.length - 1; // number of path1 to iterate on\r\n\r\n    while (pi <= min && p < path1nb) {\r\n        //  stay under min and don't go over next to last path\r\n        // draw two triangles between path1 (p1) and path2 (p2) : (p1.pi, p2.pi, p1.pi+1) and (p2.pi+1, p1.pi+1, p2.pi) clockwise\r\n\r\n        indices.push(pi, pi + shft, pi + 1);\r\n        indices.push(pi + shft + 1, pi + 1, pi + shft);\r\n        pi += 1;\r\n        if (pi === min) {\r\n            // if end of one of two consecutive paths reached, go to next existing path\r\n            p++;\r\n            shft = idx[p + 1] - idx[p];\r\n            l1 = lg[p] - 1;\r\n            l2 = lg[p + 1] - 1;\r\n            pi = idx[p];\r\n            min = l1 < l2 ? l1 + pi : l2 + pi;\r\n        }\r\n    }\r\n\r\n    // normals\r\n    VertexData.ComputeNormals(positions, indices, normals);\r\n\r\n    if (closePath) {\r\n        // update both the first and last vertex normals to their average value\r\n        let indexFirst: number;\r\n        let indexLast: number;\r\n        for (p = 0; p < pathArray.length; p++) {\r\n            indexFirst = idx[p] * 3;\r\n            if (p + 1 < pathArray.length) {\r\n                indexLast = (idx[p + 1] - 1) * 3;\r\n            } else {\r\n                indexLast = normals.length - 3;\r\n            }\r\n            normals[indexFirst] = (normals[indexFirst] + normals[indexLast]) * 0.5;\r\n            normals[indexFirst + 1] = (normals[indexFirst + 1] + normals[indexLast + 1]) * 0.5;\r\n            normals[indexFirst + 2] = (normals[indexFirst + 2] + normals[indexLast + 2]) * 0.5;\r\n            const l = Math.sqrt(normals[indexFirst] * normals[indexFirst] + normals[indexFirst + 1] * normals[indexFirst + 1] + normals[indexFirst + 2] * normals[indexFirst + 2]);\r\n            normals[indexFirst] /= l;\r\n            normals[indexFirst + 1] /= l;\r\n            normals[indexFirst + 2] /= l;\r\n            normals[indexLast] = normals[indexFirst];\r\n            normals[indexLast + 1] = normals[indexFirst + 1];\r\n            normals[indexLast + 2] = normals[indexFirst + 2];\r\n        }\r\n    }\r\n\r\n    if (closeArray) {\r\n        let indexFirst = idx[0] * 3;\r\n        let indexLast = idx[pathArray.length] * 3;\r\n        for (i = 0; i < minlg + closePathCorr; i++) {\r\n            normals[indexFirst] = (normals[indexFirst] + normals[indexLast]) * 0.5;\r\n            normals[indexFirst + 1] = (normals[indexFirst + 1] + normals[indexLast + 1]) * 0.5;\r\n            normals[indexFirst + 2] = (normals[indexFirst + 2] + normals[indexLast + 2]) * 0.5;\r\n            const l = Math.sqrt(normals[indexFirst] * normals[indexFirst] + normals[indexFirst + 1] * normals[indexFirst + 1] + normals[indexFirst + 2] * normals[indexFirst + 2]);\r\n            normals[indexFirst] /= l;\r\n            normals[indexFirst + 1] /= l;\r\n            normals[indexFirst + 2] /= l;\r\n            normals[indexLast] = normals[indexFirst];\r\n            normals[indexLast + 1] = normals[indexFirst + 1];\r\n            normals[indexLast + 2] = normals[indexFirst + 2];\r\n            indexFirst += 3;\r\n            indexLast += 3;\r\n        }\r\n    }\r\n\r\n    // sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Colors\r\n    let colors: Nullable<Float32Array> = null;\r\n    if (customColors) {\r\n        colors = new Float32Array(customColors.length * 4);\r\n        for (let c = 0; c < customColors.length; c++) {\r\n            colors[c * 4] = customColors[c].r;\r\n            colors[c * 4 + 1] = customColors[c].g;\r\n            colors[c * 4 + 2] = customColors[c].b;\r\n            colors[c * 4 + 3] = customColors[c].a;\r\n        }\r\n    }\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n    const positions32 = new Float32Array(positions);\r\n    const normals32 = new Float32Array(normals);\r\n    const uvs32 = new Float32Array(uvs);\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions32;\r\n    vertexData.normals = normals32;\r\n    vertexData.uvs = uvs32;\r\n    if (colors) {\r\n        vertexData.set(colors, VertexBuffer.ColorKind);\r\n    }\r\n\r\n    if (closePath) {\r\n        (<any>vertexData)._idx = idx;\r\n    }\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a ribbon mesh. The ribbon is a parametric shape.  It has no predefined shape. Its final shape will depend on the input parameters\r\n * * The parameter `pathArray` is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry\r\n * * The parameter `closeArray` (boolean, default false) creates a seam between the first and the last paths of the path array\r\n * * The parameter `closePath` (boolean, default false) creates a seam between the first and the last points of each path of the path array\r\n * * The parameter `offset` (positive integer, default : rounded half size of the pathArray length), is taken in account only if the `pathArray` is containing a single path\r\n * * It's the offset to join the points from the same path. Ex : offset = 10 means the point 1 is joined to the point 11\r\n * * The optional parameter `instance` is an instance of an existing Ribbon object to be updated with the passed `pathArray` parameter : https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#ribbon\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture\r\n * * The parameter `uvs` is an optional flat array of `Vector2` to update/set each ribbon vertex with its own custom UV values instead of the computed ones\r\n * * The parameters `colors` is an optional flat array of `Color4` to set/update each ribbon vertex with its own custom color values\r\n * * Note that if you use the parameters `uvs` or `colors`, the passed arrays must be populated with the right number of elements, it is to say the number of ribbon vertices. Remember that if you set `closePath` to `true`, there's one extra vertex per path in the geometry\r\n * * Moreover, you can use the parameter `color` with `instance` (to update the ribbon), only if you previously used it at creation time\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the ribbon mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/ribbon_extra\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n */\r\nexport function CreateRibbon(\r\n    name: string,\r\n    options: {\r\n        pathArray: Vector3[][];\r\n        closeArray?: boolean;\r\n        closePath?: boolean;\r\n        offset?: number;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        instance?: Mesh;\r\n        invertUV?: boolean;\r\n        uvs?: Vector2[];\r\n        colors?: Color4[];\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const pathArray = options.pathArray;\r\n    const closeArray = options.closeArray;\r\n    const closePath = options.closePath;\r\n    const sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    const instance = options.instance;\r\n    const updatable = options.updatable;\r\n\r\n    if (instance) {\r\n        // existing ribbon instance update\r\n        // positionFunction : ribbon case\r\n        // only pathArray and sideOrientation parameters are taken into account for positions update\r\n        const minimum = TmpVectors.Vector3[0].setAll(Number.MAX_VALUE);\r\n        const maximum = TmpVectors.Vector3[1].setAll(-Number.MAX_VALUE);\r\n        const positionFunction = (positions: FloatArray) => {\r\n            let minlg = pathArray[0].length;\r\n            const mesh = instance;\r\n            let i = 0;\r\n            const ns = mesh._originalBuilderSideOrientation === Mesh.DOUBLESIDE ? 2 : 1;\r\n            for (let si = 1; si <= ns; ++si) {\r\n                for (let p = 0; p < pathArray.length; ++p) {\r\n                    const path = pathArray[p];\r\n                    const l = path.length;\r\n                    minlg = minlg < l ? minlg : l;\r\n                    for (let j = 0; j < minlg; ++j) {\r\n                        const pathPoint = path[j];\r\n                        positions[i] = pathPoint.x;\r\n                        positions[i + 1] = pathPoint.y;\r\n                        positions[i + 2] = pathPoint.z;\r\n                        minimum.minimizeInPlaceFromFloats(pathPoint.x, pathPoint.y, pathPoint.z);\r\n                        maximum.maximizeInPlaceFromFloats(pathPoint.x, pathPoint.y, pathPoint.z);\r\n                        i += 3;\r\n                    }\r\n                    if (mesh._creationDataStorage && mesh._creationDataStorage.closePath) {\r\n                        const pathPoint = path[0];\r\n                        positions[i] = pathPoint.x;\r\n                        positions[i + 1] = pathPoint.y;\r\n                        positions[i + 2] = pathPoint.z;\r\n                        i += 3;\r\n                    }\r\n                }\r\n            }\r\n        };\r\n        const positions = <FloatArray>instance.getVerticesData(VertexBuffer.PositionKind);\r\n        positionFunction(positions);\r\n        if (instance.hasBoundingInfo) {\r\n            instance.getBoundingInfo().reConstruct(minimum, maximum, instance._worldMatrix);\r\n        } else {\r\n            instance.buildBoundingInfo(minimum, maximum, instance._worldMatrix);\r\n        }\r\n        instance.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);\r\n        if (options.colors) {\r\n            const colors = <FloatArray>instance.getVerticesData(VertexBuffer.ColorKind);\r\n            for (let c = 0, colorIndex = 0; c < options.colors.length; c++, colorIndex += 4) {\r\n                const color = options.colors[c];\r\n                colors[colorIndex] = color.r;\r\n                colors[colorIndex + 1] = color.g;\r\n                colors[colorIndex + 2] = color.b;\r\n                colors[colorIndex + 3] = color.a;\r\n            }\r\n            instance.updateVerticesData(VertexBuffer.ColorKind, colors, false, false);\r\n        }\r\n        if (options.uvs) {\r\n            const uvs = <FloatArray>instance.getVerticesData(VertexBuffer.UVKind);\r\n            for (let i = 0; i < options.uvs.length; i++) {\r\n                uvs[i * 2] = options.uvs[i].x;\r\n                uvs[i * 2 + 1] = useOpenGLOrientationForUV ? 1.0 - options.uvs[i].y : options.uvs[i].y;\r\n            }\r\n            instance.updateVerticesData(VertexBuffer.UVKind, uvs, false, false);\r\n        }\r\n        if (!instance.areNormalsFrozen || instance.isFacetDataEnabled) {\r\n            const indices = instance.getIndices();\r\n            const normals = <FloatArray>instance.getVerticesData(VertexBuffer.NormalKind);\r\n            const params = instance.isFacetDataEnabled ? instance.getFacetDataParameters() : null;\r\n            VertexData.ComputeNormals(positions, indices, normals, params);\r\n\r\n            if (instance._creationDataStorage && instance._creationDataStorage.closePath) {\r\n                let indexFirst: number;\r\n                let indexLast: number;\r\n                for (let p = 0; p < pathArray.length; p++) {\r\n                    indexFirst = instance._creationDataStorage.idx[p] * 3;\r\n                    if (p + 1 < pathArray.length) {\r\n                        indexLast = (instance._creationDataStorage.idx[p + 1] - 1) * 3;\r\n                    } else {\r\n                        indexLast = normals.length - 3;\r\n                    }\r\n                    normals[indexFirst] = (normals[indexFirst] + normals[indexLast]) * 0.5;\r\n                    normals[indexFirst + 1] = (normals[indexFirst + 1] + normals[indexLast + 1]) * 0.5;\r\n                    normals[indexFirst + 2] = (normals[indexFirst + 2] + normals[indexLast + 2]) * 0.5;\r\n                    normals[indexLast] = normals[indexFirst];\r\n                    normals[indexLast + 1] = normals[indexFirst + 1];\r\n                    normals[indexLast + 2] = normals[indexFirst + 2];\r\n                }\r\n            }\r\n            if (!instance.areNormalsFrozen) {\r\n                instance.updateVerticesData(VertexBuffer.NormalKind, normals, false, false);\r\n            }\r\n        }\r\n\r\n        return instance;\r\n    } else {\r\n        // new ribbon creation\r\n\r\n        const ribbon = new Mesh(name, scene);\r\n        ribbon._originalBuilderSideOrientation = sideOrientation;\r\n        ribbon._creationDataStorage = new _CreationDataStorage();\r\n\r\n        const vertexData = CreateRibbonVertexData(options);\r\n        if (closePath) {\r\n            ribbon._creationDataStorage.idx = (<any>vertexData)._idx;\r\n        }\r\n        ribbon._creationDataStorage.closePath = closePath;\r\n        ribbon._creationDataStorage.closeArray = closeArray;\r\n\r\n        vertexData.applyToMesh(ribbon, updatable);\r\n\r\n        return ribbon;\r\n    }\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateRibbon directly\r\n */\r\nexport const RibbonBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateRibbon,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ribbonBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRibbonBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateRibbon = CreateRibbonVertexData;\r\n\r\n    Mesh.CreateRibbon = (\r\n        name: string,\r\n        pathArray: Vector3[][],\r\n        closeArray: boolean = false,\r\n        closePath: boolean,\r\n        offset: number,\r\n        scene?: Scene,\r\n        updatable: boolean = false,\r\n        sideOrientation?: number,\r\n        instance?: Mesh\r\n    ) => {\r\n        return CreateRibbon(\r\n            name,\r\n            {\r\n                pathArray: pathArray,\r\n                closeArray: closeArray,\r\n                closePath: closePath,\r\n                offset: offset,\r\n                updatable: updatable,\r\n                sideOrientation: sideOrientation,\r\n                instance: instance,\r\n            },\r\n            scene\r\n        );\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData of the Disc or regular Polygon\r\n * @param options an object used to set the following optional parameters for the disc, required but can be empty\r\n * * radius the radius of the disc, optional default 0.5\r\n * * tessellation the number of polygon sides, optional, default 64\r\n * * arc a number from 0 to 1, to create an unclosed polygon based on the fraction of the circumference given by the arc value, optional, default 1\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the box\r\n */\r\nexport function CreateDiscVertexData(options: {\r\n    radius?: number;\r\n    tessellation?: number;\r\n    arc?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n}): VertexData {\r\n    const positions: number[] = [];\r\n    const indices: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n\r\n    const radius = options.radius || 0.5;\r\n    const tessellation = options.tessellation || 64;\r\n    const arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    // positions and uvs\r\n    positions.push(0, 0, 0); // disc center first\r\n    uvs.push(0.5, 0.5);\r\n\r\n    const theta = Math.PI * 2 * arc;\r\n    const step = arc === 1 ? theta / tessellation : theta / (tessellation - 1);\r\n    let a = 0;\r\n    for (let t = 0; t < tessellation; t++) {\r\n        const x = Math.cos(a);\r\n        const y = Math.sin(a);\r\n        const u = (x + 1) / 2;\r\n        const v = (1 - y) / 2;\r\n        positions.push(radius * x, radius * y, 0);\r\n        uvs.push(u, useOpenGLOrientationForUV ? 1 - v : v);\r\n        a += step;\r\n    }\r\n    if (arc === 1) {\r\n        positions.push(positions[3], positions[4], positions[5]); // close the circle\r\n        uvs.push(uvs[2], useOpenGLOrientationForUV ? 1 - uvs[3] : uvs[3]);\r\n    }\r\n\r\n    //indices\r\n    const vertexNb = positions.length / 3;\r\n    for (let i = 1; i < vertexNb - 1; i++) {\r\n        indices.push(i + 1, 0, i);\r\n    }\r\n\r\n    // result\r\n    VertexData.ComputeNormals(positions, indices, normals);\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a plane polygonal mesh.  By default, this is a disc\r\n * * The parameter `radius` sets the radius size (float) of the polygon (default 0.5)\r\n * * The parameter `tessellation` sets the number of polygon sides (positive integer, default 64). So a tessellation valued to 3 will build a triangle, to 4 a square, etc\r\n * * You can create an unclosed polygon with the parameter `arc` (positive float, default 1), valued between 0 and 1, what is the ratio of the circumference : 2 x PI x ratio\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the plane polygonal mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#disc-or-regular-polygon\r\n */\r\nexport function CreateDisc(\r\n    name: string,\r\n    options: { radius?: number; tessellation?: number; arc?: number; updatable?: boolean; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4 } = {},\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const disc = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    disc._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateDiscVertexData(options);\r\n\r\n    vertexData.applyToMesh(disc, options.updatable);\r\n\r\n    return disc;\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated please use CreateDisc directly\r\n */\r\nexport const DiscBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateDisc,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for discBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDiscBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateDisc = CreateDiscVertexData;\r\n\r\n    Mesh.CreateDisc = (name: string, radius: number, tessellation: number, scene: Nullable<Scene> = null, updatable?: boolean, sideOrientation?: number): Mesh => {\r\n        const options = {\r\n            radius,\r\n            tessellation,\r\n            sideOrientation,\r\n            updatable,\r\n        };\r\n\r\n        return CreateDisc(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3, Vector2, TmpVectors, Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { _IsSideEffectImplemented } from \"../Misc/devTools\";\r\nimport { type Scene } from \"../scene.pure\";\r\n\r\n/**\r\n * Mesh representing the ground\r\n */\r\nexport class GroundMesh extends Mesh {\r\n    /** If octree should be generated */\r\n    public generateOctree = false;\r\n\r\n    private _heightQuads: { slope: Vector2; facet1: Vector4; facet2: Vector4 }[];\r\n\r\n    /** @internal */\r\n    public _subdivisionsX: number;\r\n    /** @internal */\r\n    public _subdivisionsY: number;\r\n    /** @internal */\r\n    public _width: number;\r\n    /** @internal */\r\n    public _height: number;\r\n    /** @internal */\r\n    public _minX: number;\r\n    /** @internal */\r\n    public _maxX: number;\r\n    /** @internal */\r\n    public _minZ: number;\r\n    /** @internal */\r\n    public _maxZ: number;\r\n\r\n    /** @internal */\r\n    constructor(name: string, scene?: Scene) {\r\n        super(name, scene);\r\n    }\r\n\r\n    /**\r\n     * \"GroundMesh\"\r\n     * @returns \"GroundMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GroundMesh\";\r\n    }\r\n\r\n    /**\r\n     * The minimum of x and y subdivisions\r\n     */\r\n    public get subdivisions(): number {\r\n        return Math.min(this._subdivisionsX, this._subdivisionsY);\r\n    }\r\n\r\n    /**\r\n     * X subdivisions\r\n     */\r\n    public get subdivisionsX(): number {\r\n        return this._subdivisionsX;\r\n    }\r\n\r\n    /**\r\n     * Y subdivisions\r\n     */\r\n    public get subdivisionsY(): number {\r\n        return this._subdivisionsY;\r\n    }\r\n\r\n    /**\r\n     * This function will divide the mesh into submeshes and update an octree to help to select the right submeshes\r\n     * for rendering, picking and collision computations. Please note that you must have a decent number of submeshes\r\n     * to get performance improvements when using an octree.\r\n     * @param chunksCount the number of submeshes the mesh will be divided into\r\n     * @param octreeBlocksSize the maximum size of the octree blocks (Default: 32)\r\n     */\r\n    public optimize(chunksCount: number, octreeBlocksSize = 32): void {\r\n        this._subdivisionsX = chunksCount;\r\n        this._subdivisionsY = chunksCount;\r\n        this.subdivide(chunksCount);\r\n\r\n        // Call the octree system optimization if it is defined.\r\n        const thisAsAny = this as any;\r\n        if (_IsSideEffectImplemented(thisAsAny.createOrUpdateSubmeshesOctree)) {\r\n            thisAsAny.createOrUpdateSubmeshesOctree(octreeBlocksSize);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a height (y) value in the World system :\r\n     * the ground altitude at the coordinates (x, z) expressed in the World system.\r\n     * @param x x coordinate\r\n     * @param z z coordinate\r\n     * @returns the ground y position if (x, z) are outside the ground surface.\r\n     */\r\n    public getHeightAtCoordinates(x: number, z: number): number {\r\n        const world = this.getWorldMatrix();\r\n        const invMat = TmpVectors.Matrix[5];\r\n        world.invertToRef(invMat);\r\n        const tmpVect = TmpVectors.Vector3[8];\r\n        Vector3.TransformCoordinatesFromFloatsToRef(x, 0.0, z, invMat, tmpVect); // transform x,z in the mesh local space\r\n        x = tmpVect.x;\r\n        z = tmpVect.z;\r\n        if (x < this._minX || x >= this._maxX || z <= this._minZ || z > this._maxZ) {\r\n            return this.position.y;\r\n        }\r\n        if (!this._heightQuads || this._heightQuads.length == 0) {\r\n            this._initHeightQuads();\r\n            this._computeHeightQuads();\r\n        }\r\n        const facet = this._getFacetAt(x, z);\r\n        const y = -(facet.x * x + facet.z * z + facet.w) / facet.y;\r\n        // return y in the World system\r\n        Vector3.TransformCoordinatesFromFloatsToRef(0.0, y, 0.0, world, tmpVect);\r\n        return tmpVect.y;\r\n    }\r\n\r\n    /**\r\n     * Returns a normalized vector (Vector3) orthogonal to the ground\r\n     * at the ground coordinates (x, z) expressed in the World system.\r\n     * @param x x coordinate\r\n     * @param z z coordinate\r\n     * @returns Vector3(0.0, 1.0, 0.0) if (x, z) are outside the ground surface.\r\n     */\r\n    public getNormalAtCoordinates(x: number, z: number): Vector3 {\r\n        const normal = new Vector3(0.0, 1.0, 0.0);\r\n        this.getNormalAtCoordinatesToRef(x, z, normal);\r\n        return normal;\r\n    }\r\n\r\n    /**\r\n     * Updates the Vector3 passed a reference with a normalized vector orthogonal to the ground\r\n     * at the ground coordinates (x, z) expressed in the World system.\r\n     * Doesn't update the reference Vector3 if (x, z) are outside the ground surface.\r\n     * @param x x coordinate\r\n     * @param z z coordinate\r\n     * @param ref vector to store the result\r\n     * @returns the GroundMesh.\r\n     */\r\n    public getNormalAtCoordinatesToRef(x: number, z: number, ref: Vector3): GroundMesh {\r\n        const world = this.getWorldMatrix();\r\n        const tmpMat = TmpVectors.Matrix[5];\r\n        world.invertToRef(tmpMat);\r\n        const tmpVect = TmpVectors.Vector3[8];\r\n        Vector3.TransformCoordinatesFromFloatsToRef(x, 0.0, z, tmpMat, tmpVect); // transform x,z in the mesh local space\r\n        x = tmpVect.x;\r\n        z = tmpVect.z;\r\n        if (x < this._minX || x >= this._maxX || z <= this._minZ || z > this._maxZ) {\r\n            return this;\r\n        }\r\n        if (!this._heightQuads || this._heightQuads.length == 0) {\r\n            this._initHeightQuads();\r\n            this._computeHeightQuads();\r\n        }\r\n        const facet = this._getFacetAt(x, z);\r\n        Vector3.TransformNormalFromFloatsToRef(facet.x, facet.y, facet.z, world, ref);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Force the heights to be recomputed for getHeightAtCoordinates() or getNormalAtCoordinates()\r\n     * if the ground has been updated.\r\n     * This can be used in the render loop.\r\n     * @returns the GroundMesh.\r\n     */\r\n    public updateCoordinateHeights(): GroundMesh {\r\n        if (!this._heightQuads || this._heightQuads.length == 0) {\r\n            this._initHeightQuads();\r\n        }\r\n        this._computeHeightQuads();\r\n        return this;\r\n    }\r\n\r\n    // Returns the element \"facet\" from the heightQuads array relative to (x, z) local coordinates\r\n    private _getFacetAt(x: number, z: number): Vector4 {\r\n        // retrieve col and row from x, z coordinates in the ground local system\r\n        const col = Math.floor(((x + this._maxX) * this._subdivisionsX) / this._width);\r\n        const row = Math.floor((-(z + this._maxZ) * this._subdivisionsY) / this._height + this._subdivisionsY);\r\n        const quad = this._heightQuads[row * this._subdivisionsX + col];\r\n        let facet;\r\n        if (z < quad.slope.x * x + quad.slope.y) {\r\n            facet = quad.facet1;\r\n        } else {\r\n            facet = quad.facet2;\r\n        }\r\n        return facet;\r\n    }\r\n\r\n    //  Creates and populates the heightMap array with \"facet\" elements :\r\n    // a quad is two triangular facets separated by a slope, so a \"facet\" element is 1 slope + 2 facets\r\n    // slope : Vector2(c, h) = 2D diagonal line equation setting apart two triangular facets in a quad : z = cx + h\r\n    // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0\r\n    // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0\r\n    // Returns the GroundMesh.\r\n    private _initHeightQuads(): GroundMesh {\r\n        const subdivisionsX = this._subdivisionsX;\r\n        const subdivisionsY = this._subdivisionsY;\r\n        this._heightQuads = [];\r\n        for (let row = 0; row < subdivisionsY; row++) {\r\n            for (let col = 0; col < subdivisionsX; col++) {\r\n                const quad = { slope: Vector2.Zero(), facet1: new Vector4(0.0, 0.0, 0.0, 0.0), facet2: new Vector4(0.0, 0.0, 0.0, 0.0) };\r\n                this._heightQuads[row * subdivisionsX + col] = quad;\r\n            }\r\n        }\r\n        return this;\r\n    }\r\n\r\n    // Compute each quad element values and update the heightMap array :\r\n    // slope : Vector2(c, h) = 2D diagonal line equation setting apart two triangular facets in a quad : z = cx + h\r\n    // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0\r\n    // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0\r\n    // Returns the GroundMesh.\r\n    private _computeHeightQuads(): GroundMesh {\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        if (!positions) {\r\n            return this;\r\n        }\r\n\r\n        const v1 = TmpVectors.Vector3[3];\r\n        const v2 = TmpVectors.Vector3[2];\r\n        const v3 = TmpVectors.Vector3[1];\r\n        const v4 = TmpVectors.Vector3[0];\r\n        const v1v2 = TmpVectors.Vector3[4];\r\n        const v1v3 = TmpVectors.Vector3[5];\r\n        const v1v4 = TmpVectors.Vector3[6];\r\n        const norm1 = TmpVectors.Vector3[7];\r\n        const norm2 = TmpVectors.Vector3[8];\r\n        let i: number;\r\n        let j: number;\r\n        let k: number;\r\n        let cd: number; // 2D slope coefficient : z = cd * x + h\r\n        let h: number;\r\n        let d1: number; // facet plane equation : ax + by + cz + d = 0\r\n        let d2: number;\r\n\r\n        const subdivisionsX = this._subdivisionsX;\r\n        const subdivisionsY = this._subdivisionsY;\r\n\r\n        for (let row = 0; row < subdivisionsY; row++) {\r\n            for (let col = 0; col < subdivisionsX; col++) {\r\n                i = col * 3;\r\n                j = row * (subdivisionsX + 1) * 3;\r\n                k = (row + 1) * (subdivisionsX + 1) * 3;\r\n                v1.x = positions[j + i];\r\n                v1.y = positions[j + i + 1];\r\n                v1.z = positions[j + i + 2];\r\n                v2.x = positions[j + i + 3];\r\n                v2.y = positions[j + i + 4];\r\n                v2.z = positions[j + i + 5];\r\n                v3.x = positions[k + i];\r\n                v3.y = positions[k + i + 1];\r\n                v3.z = positions[k + i + 2];\r\n                v4.x = positions[k + i + 3];\r\n                v4.y = positions[k + i + 4];\r\n                v4.z = positions[k + i + 5];\r\n\r\n                // 2D slope V1V4\r\n                cd = (v4.z - v1.z) / (v4.x - v1.x);\r\n                h = v1.z - cd * v1.x; // v1 belongs to the slope\r\n\r\n                // facet equations :\r\n                // we compute each facet normal vector\r\n                // the equation of the facet plane is : norm.x * x + norm.y * y + norm.z * z + d = 0\r\n                // we compute the value d by applying the equation to v1 which belongs to the plane\r\n                // then we store the facet equation in a Vector4\r\n                v2.subtractToRef(v1, v1v2);\r\n                v3.subtractToRef(v1, v1v3);\r\n                v4.subtractToRef(v1, v1v4);\r\n                Vector3.CrossToRef(v1v4, v1v3, norm1); // caution : CrossToRef uses the Tmp class\r\n                Vector3.CrossToRef(v1v2, v1v4, norm2);\r\n                norm1.normalize();\r\n                norm2.normalize();\r\n                d1 = -(norm1.x * v1.x + norm1.y * v1.y + norm1.z * v1.z);\r\n                d2 = -(norm2.x * v2.x + norm2.y * v2.y + norm2.z * v2.z);\r\n\r\n                const quad = this._heightQuads[row * subdivisionsX + col];\r\n                quad.slope.copyFromFloats(cd, h);\r\n                quad.facet1.copyFromFloats(norm1.x, norm1.y, norm1.z, d1);\r\n                quad.facet2.copyFromFloats(norm2.x, norm2.y, norm2.z, d2);\r\n            }\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes this ground mesh\r\n     * @param serializationObject object to write serialization to\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.subdivisionsX = this._subdivisionsX;\r\n        serializationObject.subdivisionsY = this._subdivisionsY;\r\n\r\n        serializationObject.minX = this._minX;\r\n        serializationObject.maxX = this._maxX;\r\n\r\n        serializationObject.minZ = this._minZ;\r\n        serializationObject.maxZ = this._maxZ;\r\n\r\n        serializationObject.width = this._width;\r\n        serializationObject.height = this._height;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized ground mesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the ground mesh in\r\n     * @returns the created ground mesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): GroundMesh {\r\n        const result = new GroundMesh(parsedMesh.name, scene);\r\n\r\n        result._subdivisionsX = parsedMesh.subdivisionsX || 1;\r\n        result._subdivisionsY = parsedMesh.subdivisionsY || 1;\r\n\r\n        result._minX = parsedMesh.minX;\r\n        result._maxX = parsedMesh.maxX;\r\n\r\n        result._minZ = parsedMesh.minZ;\r\n        result._maxZ = parsedMesh.maxZ;\r\n\r\n        result._width = parsedMesh.width;\r\n        result._height = parsedMesh.height;\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for groundMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGroundMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GroundMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        return GroundMesh.Parse(parsedMesh, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { GroundMesh } from \"../groundMesh.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { Epsilon } from \"../../Maths/math.constants\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData for a Ground\r\n * @param options an object used to set the following optional parameters for the Ground, required but can be empty\r\n * - `width` the width (x direction) of the ground, optional, default 1\r\n * - `height` the height (z direction) of the ground, optional, default 1\r\n * - `subdivisions` the number of subdivisions per side, optional, default 1\r\n * - `subdivisionsX` the number of subdivisions in the x direction, overrides options.subdivisions, optional, default undefined\r\n * - `subdivisionsY` the number of subdivisions in the y direction, overrides options.subdivisions, optional, default undefined\r\n * @returns the VertexData of the Ground\r\n */\r\nexport function CreateGroundVertexData(options: {\r\n    size?: number;\r\n    width?: number;\r\n    height?: number;\r\n    subdivisions?: number;\r\n    subdivisionsX?: number;\r\n    subdivisionsY?: number;\r\n}): VertexData {\r\n    const indices = [];\r\n    const positions = [];\r\n    const normals = [];\r\n    const uvs = [];\r\n    let row: number, col: number;\r\n\r\n    const width: number = options.width || options.size || 1;\r\n    const height: number = options.height || options.size || 1;\r\n    const subdivisionsX: number = (options.subdivisionsX || options.subdivisions || 1) | 0;\r\n    const subdivisionsY: number = (options.subdivisionsY || options.subdivisions || 1) | 0;\r\n\r\n    for (row = 0; row <= subdivisionsY; row++) {\r\n        for (col = 0; col <= subdivisionsX; col++) {\r\n            const position = new Vector3((col * width) / subdivisionsX - width / 2.0, 0, ((subdivisionsY - row) * height) / subdivisionsY - height / 2.0);\r\n            const normal = new Vector3(0, 1.0, 0);\r\n\r\n            positions.push(position.x, position.y, position.z);\r\n            normals.push(normal.x, normal.y, normal.z);\r\n            uvs.push(col / subdivisionsX, useOpenGLOrientationForUV ? row / subdivisionsY : 1.0 - row / subdivisionsY);\r\n        }\r\n    }\r\n\r\n    for (row = 0; row < subdivisionsY; row++) {\r\n        for (col = 0; col < subdivisionsX; col++) {\r\n            indices.push(col + 1 + (row + 1) * (subdivisionsX + 1));\r\n            indices.push(col + 1 + row * (subdivisionsX + 1));\r\n            indices.push(col + row * (subdivisionsX + 1));\r\n\r\n            indices.push(col + (row + 1) * (subdivisionsX + 1));\r\n            indices.push(col + 1 + (row + 1) * (subdivisionsX + 1));\r\n            indices.push(col + row * (subdivisionsX + 1));\r\n        }\r\n    }\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates the VertexData for a TiledGround by subdividing the ground into tiles\r\n * @param options an object used to set the following optional parameters for the Ground\r\n * - `xmin` ground minimum X coordinate, default -1\r\n * - `zmin` ground minimum Z coordinate, default -1\r\n * - `xmax` ground maximum X coordinate, default 1\r\n * - `zmax` ground maximum Z coordinate, default 1\r\n * - `subdivisions` a javascript object `\\{w: positive integer, h: positive integer\\}`, `w` and `h` are the numbers of subdivisions on the ground width and height creating 'tiles', default `\\{w: 6, h: 6\\}`\r\n * - `precision` a javascript object `\\{w: positive integer, h: positive integer\\}`, `w` and `h` are the numbers of subdivisions on the tile width and height, default `\\{w: 2, h: 2\\}`\r\n * @returns the VertexData of the TiledGround\r\n */\r\nexport function CreateTiledGroundVertexData(options: {\r\n    xmin: number;\r\n    zmin: number;\r\n    xmax: number;\r\n    zmax: number;\r\n    subdivisions?: { w: number; h: number };\r\n    precision?: { w: number; h: number };\r\n}): VertexData {\r\n    const xmin = options.xmin !== undefined && options.xmin !== null ? options.xmin : -1.0;\r\n    const zmin = options.zmin !== undefined && options.zmin !== null ? options.zmin : -1.0;\r\n    const xmax = options.xmax !== undefined && options.xmax !== null ? options.xmax : 1.0;\r\n    const zmax = options.zmax !== undefined && options.zmax !== null ? options.zmax : 1.0;\r\n    const subdivisions = options.subdivisions || { w: 1, h: 1 };\r\n    const precision = options.precision || { w: 1, h: 1 };\r\n\r\n    const indices: number[] = [];\r\n    const positions: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n    let row: number, col: number, tileRow: number, tileCol: number;\r\n\r\n    subdivisions.h = subdivisions.h < 1 ? 1 : subdivisions.h;\r\n    subdivisions.w = subdivisions.w < 1 ? 1 : subdivisions.w;\r\n    precision.w = precision.w < 1 ? 1 : precision.w;\r\n    precision.h = precision.h < 1 ? 1 : precision.h;\r\n\r\n    const tileSize = {\r\n        w: (xmax - xmin) / subdivisions.w,\r\n        h: (zmax - zmin) / subdivisions.h,\r\n    };\r\n\r\n    function applyTile(xTileMin: number, zTileMin: number, xTileMax: number, zTileMax: number) {\r\n        // Indices\r\n        const base = positions.length / 3;\r\n        const rowLength = precision.w + 1;\r\n        for (row = 0; row < precision.h; row++) {\r\n            for (col = 0; col < precision.w; col++) {\r\n                const square = [base + col + row * rowLength, base + (col + 1) + row * rowLength, base + (col + 1) + (row + 1) * rowLength, base + col + (row + 1) * rowLength];\r\n\r\n                indices.push(square[1]);\r\n                indices.push(square[2]);\r\n                indices.push(square[3]);\r\n                indices.push(square[0]);\r\n                indices.push(square[1]);\r\n                indices.push(square[3]);\r\n            }\r\n        }\r\n\r\n        // Position, normals and uvs\r\n        const position = Vector3.Zero();\r\n        const normal = new Vector3(0, 1.0, 0);\r\n        for (row = 0; row <= precision.h; row++) {\r\n            position.z = (row * (zTileMax - zTileMin)) / precision.h + zTileMin;\r\n            for (col = 0; col <= precision.w; col++) {\r\n                position.x = (col * (xTileMax - xTileMin)) / precision.w + xTileMin;\r\n                position.y = 0;\r\n\r\n                positions.push(position.x, position.y, position.z);\r\n                normals.push(normal.x, normal.y, normal.z);\r\n                uvs.push(col / precision.w, row / precision.h);\r\n            }\r\n        }\r\n    }\r\n\r\n    for (tileRow = 0; tileRow < subdivisions.h; tileRow++) {\r\n        for (tileCol = 0; tileCol < subdivisions.w; tileCol++) {\r\n            applyTile(xmin + tileCol * tileSize.w, zmin + tileRow * tileSize.h, xmin + (tileCol + 1) * tileSize.w, zmin + (tileRow + 1) * tileSize.h);\r\n        }\r\n    }\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates the VertexData of the Ground designed from a heightmap\r\n * @param options an object used to set the following parameters for the Ground, required and provided by CreateGroundFromHeightMap\r\n * - `width` the width (x direction) of the ground\r\n * - `height` the height (z direction) of the ground\r\n * - `subdivisions` the number of subdivisions per side\r\n * - `minHeight` the minimum altitude on the ground, optional, default 0\r\n * - `maxHeight` the maximum altitude on the ground, optional default 1\r\n * - `colorFilter` the filter to apply to the image pixel colors to compute the height, optional Color3, default (0.3, 0.59, 0.11)\r\n * - `buffer` the array holding the image color data\r\n * - `bufferWidth` the width of image\r\n * - `bufferHeight` the height of image\r\n * - `alphaFilter` Remove any data where the alpha channel is below this value, defaults 0 (all data visible)\r\n * - `heightBuffer` a array of floats where the height data can be saved, if its length is greater than zero.\r\n * @returns the VertexData of the Ground designed from a heightmap\r\n */\r\nexport function CreateGroundFromHeightMapVertexData(options: {\r\n    width: number;\r\n    height: number;\r\n    subdivisions: number;\r\n    minHeight: number;\r\n    maxHeight: number;\r\n    colorFilter: Color3;\r\n    buffer: Uint8Array;\r\n    bufferWidth: number;\r\n    bufferHeight: number;\r\n    alphaFilter: number;\r\n    heightBuffer?: Float32Array;\r\n}): VertexData {\r\n    const indices = [];\r\n    const positions = [];\r\n    const normals = [];\r\n    const uvs = [];\r\n    let row, col;\r\n    const filter = options.colorFilter || new Color3(0.3, 0.59, 0.11);\r\n    const alphaFilter = options.alphaFilter || 0.0;\r\n    let invert = false;\r\n\r\n    if (options.minHeight > options.maxHeight) {\r\n        invert = true;\r\n        const temp = options.maxHeight;\r\n        options.maxHeight = options.minHeight;\r\n        options.minHeight = temp;\r\n    }\r\n\r\n    // Vertices\r\n    for (row = 0; row <= options.subdivisions; row++) {\r\n        for (col = 0; col <= options.subdivisions; col++) {\r\n            const position = new Vector3(\r\n                (col * options.width) / options.subdivisions - options.width / 2.0,\r\n                0,\r\n                ((options.subdivisions - row) * options.height) / options.subdivisions - options.height / 2.0\r\n            );\r\n\r\n            // Compute height\r\n            const heightMapX = (((position.x + options.width / 2) / options.width) * (options.bufferWidth - 1)) | 0;\r\n            const heightMapY = ((1.0 - (position.z + options.height / 2) / options.height) * (options.bufferHeight - 1)) | 0;\r\n            const pos = (heightMapX + heightMapY * options.bufferWidth) * 4;\r\n            let r = options.buffer[pos] / 255.0;\r\n            let g = options.buffer[pos + 1] / 255.0;\r\n            let b = options.buffer[pos + 2] / 255.0;\r\n            const a = options.buffer[pos + 3] / 255.0;\r\n\r\n            if (invert) {\r\n                r = 1.0 - r;\r\n                g = 1.0 - g;\r\n                b = 1.0 - b;\r\n            }\r\n\r\n            const gradient = r * filter.r + g * filter.g + b * filter.b;\r\n\r\n            // If our alpha channel is not within our filter then we will assign a 'special' height\r\n            // Then when building the indices, we will ignore any vertex that is using the special height\r\n            if (a >= alphaFilter) {\r\n                position.y = options.minHeight + (options.maxHeight - options.minHeight) * gradient;\r\n            } else {\r\n                position.y = options.minHeight - Epsilon; // We can't have a height below minHeight, normally.\r\n            }\r\n            if (options.heightBuffer) {\r\n                // set the height buffer information in row major order.\r\n                options.heightBuffer[row * (options.subdivisions + 1) + col] = position.y;\r\n            }\r\n\r\n            // Add  vertex\r\n            positions.push(position.x, position.y, position.z);\r\n            normals.push(0, 0, 0);\r\n            uvs.push(col / options.subdivisions, 1.0 - row / options.subdivisions);\r\n        }\r\n    }\r\n\r\n    // Indices\r\n    for (row = 0; row < options.subdivisions; row++) {\r\n        for (col = 0; col < options.subdivisions; col++) {\r\n            // Calculate Indices\r\n            const idx1 = col + 1 + (row + 1) * (options.subdivisions + 1);\r\n            const idx2 = col + 1 + row * (options.subdivisions + 1);\r\n            const idx3 = col + row * (options.subdivisions + 1);\r\n            const idx4 = col + (row + 1) * (options.subdivisions + 1);\r\n\r\n            // Check that all indices are visible (based on our special height)\r\n            // Only display the vertex if all Indices are visible\r\n            // Positions are stored x,y,z for each vertex, hence the * 3 and + 1 for height\r\n            const isVisibleIdx1 = positions[idx1 * 3 + 1] >= options.minHeight;\r\n            const isVisibleIdx2 = positions[idx2 * 3 + 1] >= options.minHeight;\r\n            const isVisibleIdx3 = positions[idx3 * 3 + 1] >= options.minHeight;\r\n            if (isVisibleIdx1 && isVisibleIdx2 && isVisibleIdx3) {\r\n                indices.push(idx1);\r\n                indices.push(idx2);\r\n                indices.push(idx3);\r\n            }\r\n\r\n            const isVisibleIdx4 = positions[idx4 * 3 + 1] >= options.minHeight;\r\n            if (isVisibleIdx4 && isVisibleIdx1 && isVisibleIdx3) {\r\n                indices.push(idx4);\r\n                indices.push(idx1);\r\n                indices.push(idx3);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Normals\r\n    VertexData.ComputeNormals(positions, indices, normals);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a ground mesh\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * - `width` set the width size (float, default 1)\r\n * - `height` set the height size (float, default 1)\r\n * - `subdivisions` sets the number of subdivision per side (default 1)\r\n * - `subdivisionsX` sets the number of subdivision on the X axis (overrides subdivisions)\r\n * - `subdivisionsY` sets the number of subdivision on the Y axis (overrides subdivisions)\r\n * - `updatable` defines if the mesh must be flagged as updatable (default false)\r\n * @param scene defines the hosting scene\r\n * @returns the ground mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#ground\r\n */\r\nexport function CreateGround(\r\n    name: string,\r\n    options: { width?: number; height?: number; subdivisions?: number; subdivisionsX?: number; subdivisionsY?: number; updatable?: boolean } = {},\r\n    scene?: Scene\r\n): GroundMesh {\r\n    const ground = new GroundMesh(name, scene);\r\n    ground._setReady(false);\r\n    ground._subdivisionsX = options.subdivisionsX || options.subdivisions || 1;\r\n    ground._subdivisionsY = options.subdivisionsY || options.subdivisions || 1;\r\n    ground._width = options.width || 1;\r\n    ground._height = options.height || 1;\r\n    ground._maxX = ground._width / 2;\r\n    ground._maxZ = ground._height / 2;\r\n    ground._minX = -ground._maxX;\r\n    ground._minZ = -ground._maxZ;\r\n\r\n    const vertexData = CreateGroundVertexData(options);\r\n\r\n    vertexData.applyToMesh(ground, options.updatable);\r\n\r\n    ground._setReady(true);\r\n\r\n    return ground;\r\n}\r\n\r\n/**\r\n * Creates a tiled ground mesh\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * - `xmin` ground minimum X coordinate (float, default -1)\r\n * - `zmin` ground minimum Z coordinate (float, default -1)\r\n * - `xmax` ground maximum X coordinate (float, default 1)\r\n * - `zmax` ground maximum Z coordinate (float, default 1)\r\n * - `subdivisions` a javascript object `{w: positive integer, h: positive integer}` (default `{w: 6, h: 6}`). `w` and `h` are the numbers of subdivisions on the ground width and height. Each subdivision is called a tile\r\n * - `subdivisions.w` positive integer, default 6\r\n * - `subdivisions.h` positive integer, default 6\r\n * - `precision` a javascript object `{w: positive integer, h: positive integer}` (default `{w: 2, h: 2}`). `w` and `h` are the numbers of subdivisions on the ground width and height of each tile\r\n * - `precision.w` positive integer, default 2\r\n * - `precision.h` positive integer, default 2\r\n * - `updatable` boolean, default false, true if the mesh must be flagged as updatable\r\n * @param scene defines the hosting scene\r\n * @returns the tiled ground mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#tiled-ground\r\n */\r\nexport function CreateTiledGround(\r\n    name: string,\r\n    options: { xmin: number; zmin: number; xmax: number; zmax: number; subdivisions?: { w: number; h: number }; precision?: { w: number; h: number }; updatable?: boolean },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const tiledGround = new Mesh(name, scene);\r\n\r\n    const vertexData = CreateTiledGroundVertexData(options);\r\n\r\n    vertexData.applyToMesh(tiledGround, options.updatable);\r\n\r\n    return tiledGround;\r\n}\r\n\r\n/**\r\n * Creates a ground mesh from a height map. The height map download can take some frames,\r\n * so the mesh is not immediately ready. To wait for the mesh to be completely built,\r\n * you should use the `onReady` callback option.\r\n * @param name defines the name of the mesh\r\n * @param url sets the URL of the height map image resource.\r\n * @param options defines the options used to create the mesh\r\n * - `width` sets the ground width size (positive float, default 10)\r\n * - `height` sets the ground height size (positive float, default 10)\r\n * - `subdivisions` sets the number of subdivision per side (positive integer, default 1)\r\n * - `minHeight` is the minimum altitude on the ground (float, default 0)\r\n * - `maxHeight` is the maximum altitude on the ground (float, default 1)\r\n * - `colorFilter` is the filter to apply to the image pixel colors to compute the height (optional Color3, default (0.3, 0.59, 0.11) )\r\n * - `alphaFilter` will filter any data where the alpha channel is below this value, defaults 0 (all data visible)\r\n * - `updatable` defines if the mesh must be flagged as updatable\r\n * - `onReady` is a javascript callback function that will be called once the mesh is just built (the height map download can last some time)\r\n * - `onError` is a javascript callback function that will be called if there is an error\r\n * - `passHeightBufferInCallback` a boolean that indicates if the calculated height data will be passed in the onReady callback. Useful if you need the height data for physics, for example.\r\n * @param scene defines the hosting scene\r\n * @returns the ground mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/height_map\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#ground-from-a-height-map\r\n */\r\nexport function CreateGroundFromHeightMap(\r\n    name: string,\r\n    url: string | { data: Uint8Array; width: number; height: number },\r\n    options: {\r\n        width?: number;\r\n        height?: number;\r\n        subdivisions?: number;\r\n        minHeight?: number;\r\n        maxHeight?: number;\r\n        colorFilter?: Color3;\r\n        alphaFilter?: number;\r\n        updatable?: boolean;\r\n        onReady?: (mesh: GroundMesh, heightBuffer?: Float32Array) => void;\r\n        onError?: (message?: string, exception?: any) => void;\r\n        passHeightBufferInCallback?: boolean;\r\n    } = {},\r\n    scene: Nullable<Scene> = null\r\n): GroundMesh {\r\n    const width = options.width || 10.0;\r\n    const height = options.height || 10.0;\r\n    const subdivisions = options.subdivisions || 1 | 0;\r\n    const minHeight = options.minHeight || 0.0;\r\n    const maxHeight = options.maxHeight || 1.0;\r\n    const filter = options.colorFilter || new Color3(0.3, 0.59, 0.11);\r\n    const alphaFilter = options.alphaFilter || 0.0;\r\n    const updatable = options.updatable;\r\n    const onReady = options.onReady;\r\n\r\n    scene = scene || EngineStore.LastCreatedScene!;\r\n\r\n    const ground = new GroundMesh(name, scene);\r\n    ground._subdivisionsX = subdivisions;\r\n    ground._subdivisionsY = subdivisions;\r\n    ground._width = width;\r\n    ground._height = height;\r\n    ground._maxX = ground._width / 2.0;\r\n    ground._maxZ = ground._height / 2.0;\r\n    ground._minX = -ground._maxX;\r\n    ground._minZ = -ground._maxZ;\r\n\r\n    ground._setReady(false);\r\n\r\n    let heightBuffer: Float32Array;\r\n    if (options.passHeightBufferInCallback) {\r\n        heightBuffer = new Float32Array((subdivisions + 1) * (subdivisions + 1));\r\n    }\r\n\r\n    const onBufferLoaded = (buffer: Uint8Array, bufferWidth: number, bufferHeight: number) => {\r\n        const vertexData = CreateGroundFromHeightMapVertexData({\r\n            width: width,\r\n            height: height,\r\n            subdivisions: subdivisions,\r\n            minHeight: minHeight,\r\n            maxHeight: maxHeight,\r\n            colorFilter: filter,\r\n            buffer: buffer,\r\n            bufferWidth: bufferWidth,\r\n            bufferHeight: bufferHeight,\r\n            alphaFilter: alphaFilter,\r\n            heightBuffer,\r\n        });\r\n\r\n        vertexData.applyToMesh(ground, updatable);\r\n\r\n        //execute ready callback, if set\r\n        if (onReady) {\r\n            onReady(ground, heightBuffer);\r\n        }\r\n\r\n        ground._setReady(true);\r\n    };\r\n\r\n    if (typeof url === \"string\") {\r\n        // Track the async image load as pending scene data so that scene.isReady()\r\n        // (and therefore scene.executeWhenReady) waits for it. Without this, an\r\n        // in-flight heightmap leaves the ground mesh with no subMeshes, which\r\n        // scene.isReady skips entirely, causing executeWhenReady to fire before\r\n        // geometry exists.\r\n        scene.addPendingData(ground);\r\n\r\n        const onload = (img: HTMLImageElement | ImageBitmap) => {\r\n            const bufferWidth = img.width;\r\n            const bufferHeight = img.height;\r\n\r\n            if (scene.isDisposed) {\r\n                scene.removePendingData(ground);\r\n                return;\r\n            }\r\n\r\n            const buffer = scene?.getEngine().resizeImageBitmap(img, bufferWidth, bufferHeight);\r\n\r\n            onBufferLoaded(buffer, bufferWidth, bufferHeight);\r\n            scene.removePendingData(ground);\r\n        };\r\n\r\n        const onError = (message?: string, exception?: any) => {\r\n            scene.removePendingData(ground);\r\n            if (options.onError) {\r\n                options.onError(message, exception);\r\n            }\r\n        };\r\n\r\n        Tools.LoadImage(url, onload, onError, scene.offlineProvider);\r\n    } else {\r\n        onBufferLoaded(url.data, url.width, url.height);\r\n    }\r\n\r\n    return ground;\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the functions directly from the module\r\n */\r\nexport const GroundBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateGround,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateGroundFromHeightMap,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateTiledGround,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for groundBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGroundBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateGround = CreateGroundVertexData;\r\n\r\n    VertexData.CreateTiledGround = CreateTiledGroundVertexData;\r\n\r\n    VertexData.CreateGroundFromHeightMap = CreateGroundFromHeightMapVertexData;\r\n\r\n    Mesh.CreateGround = (name: string, width: number, height: number, subdivisions: number, scene?: Scene, updatable?: boolean): Mesh => {\r\n        const options = {\r\n            width,\r\n            height,\r\n            subdivisions,\r\n            updatable,\r\n        };\r\n\r\n        return CreateGround(name, options, scene);\r\n    };\r\n\r\n    Mesh.CreateTiledGround = (\r\n        name: string,\r\n        xmin: number,\r\n        zmin: number,\r\n        xmax: number,\r\n        zmax: number,\r\n        subdivisions: { w: number; h: number },\r\n        precision: { w: number; h: number },\r\n        scene: Scene,\r\n        updatable?: boolean\r\n    ): Mesh => {\r\n        const options = {\r\n            xmin,\r\n            zmin,\r\n            xmax,\r\n            zmax,\r\n            subdivisions,\r\n            precision,\r\n            updatable,\r\n        };\r\n\r\n        return CreateTiledGround(name, options, scene);\r\n    };\r\n\r\n    Mesh.CreateGroundFromHeightMap = (\r\n        name: string,\r\n        url: string,\r\n        width: number,\r\n        height: number,\r\n        subdivisions: number,\r\n        minHeight: number,\r\n        maxHeight: number,\r\n        scene: Scene,\r\n        updatable?: boolean,\r\n        onReady?: (mesh: GroundMesh) => void,\r\n        alphaFilter?: number\r\n    ): GroundMesh => {\r\n        const options = {\r\n            width,\r\n            height,\r\n            subdivisions,\r\n            minHeight,\r\n            maxHeight,\r\n            updatable,\r\n            onReady,\r\n            alphaFilter,\r\n        };\r\n\r\n        return CreateGroundFromHeightMap(name, url, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Matrix, Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { CreateGroundVertexData } from \"./groundBuilder.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData for a box\r\n * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n * * size sets the width, height and depth of the box to the value of size, optional default 1\r\n * * width sets the width (x direction) of the box, overwrites the width set by size, optional, default size\r\n * * height sets the height (y direction) of the box, overwrites the height set by size, optional, default size\r\n * * depth sets the depth (z direction) of the box, overwrites the depth set by size, optional, default size\r\n * * faceUV an array of 6 Vector4 elements used to set different images to each box side\r\n * * faceColors an array of 6 Color3 elements used to set different colors to each box side\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the box\r\n */\r\nexport function CreateBoxVertexData(options: {\r\n    size?: number;\r\n    width?: number;\r\n    height?: number;\r\n    depth?: number;\r\n    faceUV?: Vector4[];\r\n    faceColors?: Color4[];\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n    wrap?: boolean;\r\n    topBaseAt?: number;\r\n    bottomBaseAt?: number;\r\n}): VertexData {\r\n    const nbFaces = 6;\r\n    let indices = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23];\r\n    const normals = [\r\n        0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0,\r\n        1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,\r\n    ];\r\n    const uvs = [];\r\n    const width = options.width || options.size || 1;\r\n    const height = options.height || options.size || 1;\r\n    const depth = options.depth || options.size || 1;\r\n    const wrap = options.wrap || false;\r\n    let topBaseAt = options.topBaseAt === void 0 ? 1 : options.topBaseAt;\r\n    let bottomBaseAt = options.bottomBaseAt === void 0 ? 0 : options.bottomBaseAt;\r\n    topBaseAt = (topBaseAt + 4) % 4; // places values as 0 to 3\r\n    bottomBaseAt = (bottomBaseAt + 4) % 4; // places values as 0 to 3\r\n    const topOrder = [2, 0, 3, 1];\r\n    const bottomOrder = [2, 0, 1, 3];\r\n    let topIndex = topOrder[topBaseAt];\r\n    let bottomIndex = bottomOrder[bottomBaseAt];\r\n    let basePositions = [\r\n        1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1,\r\n        1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1,\r\n    ];\r\n    if (wrap) {\r\n        indices = [2, 3, 0, 2, 0, 1, 4, 5, 6, 4, 6, 7, 9, 10, 11, 9, 11, 8, 12, 14, 15, 12, 13, 14];\r\n        basePositions = [\r\n            -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1,\r\n        ];\r\n        let topFaceBase: any = [\r\n            [1, 1, 1],\r\n            [-1, 1, 1],\r\n            [-1, 1, -1],\r\n            [1, 1, -1],\r\n        ];\r\n        let bottomFaceBase: any = [\r\n            [-1, -1, 1],\r\n            [1, -1, 1],\r\n            [1, -1, -1],\r\n            [-1, -1, -1],\r\n        ];\r\n        const topFaceOrder: any = [17, 18, 19, 16];\r\n        const bottomFaceOrder: any = [22, 23, 20, 21];\r\n        while (topIndex > 0) {\r\n            topFaceBase.unshift(topFaceBase.pop());\r\n            topFaceOrder.unshift(topFaceOrder.pop());\r\n            topIndex--;\r\n        }\r\n        while (bottomIndex > 0) {\r\n            bottomFaceBase.unshift(bottomFaceBase.pop());\r\n            bottomFaceOrder.unshift(bottomFaceOrder.pop());\r\n            bottomIndex--;\r\n        }\r\n        topFaceBase = topFaceBase.flat();\r\n        bottomFaceBase = bottomFaceBase.flat();\r\n        basePositions = basePositions.concat(topFaceBase).concat(bottomFaceBase);\r\n        indices.push(topFaceOrder[0], topFaceOrder[2], topFaceOrder[3], topFaceOrder[0], topFaceOrder[1], topFaceOrder[2]);\r\n        indices.push(bottomFaceOrder[0], bottomFaceOrder[2], bottomFaceOrder[3], bottomFaceOrder[0], bottomFaceOrder[1], bottomFaceOrder[2]);\r\n    }\r\n    const scaleArray = [width / 2, height / 2, depth / 2];\r\n    const positions = basePositions.reduce((accumulator: Array<number>, currentValue, currentIndex) => accumulator.concat(currentValue * scaleArray[currentIndex % 3]), []);\r\n\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    const faceUV: Vector4[] = options.faceUV || new Array<Vector4>(6);\r\n    const faceColors = options.faceColors;\r\n    const colors = [];\r\n\r\n    // default face colors and UV if undefined\r\n    for (let f = 0; f < 6; f++) {\r\n        if (faceUV[f] === undefined) {\r\n            faceUV[f] = new Vector4(0, 0, 1, 1);\r\n        }\r\n        if (faceColors && faceColors[f] === undefined) {\r\n            faceColors[f] = new Color4(1, 1, 1, 1);\r\n        }\r\n    }\r\n\r\n    // Create each face in turn.\r\n    for (let index = 0; index < nbFaces; index++) {\r\n        uvs.push(faceUV[index].z, useOpenGLOrientationForUV ? 1.0 - faceUV[index].w : faceUV[index].w);\r\n        uvs.push(faceUV[index].x, useOpenGLOrientationForUV ? 1.0 - faceUV[index].w : faceUV[index].w);\r\n        uvs.push(faceUV[index].x, useOpenGLOrientationForUV ? 1.0 - faceUV[index].y : faceUV[index].y);\r\n        uvs.push(faceUV[index].z, useOpenGLOrientationForUV ? 1.0 - faceUV[index].y : faceUV[index].y);\r\n        if (faceColors) {\r\n            for (let c = 0; c < 4; c++) {\r\n                colors.push(faceColors[index].r, faceColors[index].g, faceColors[index].b, faceColors[index].a);\r\n            }\r\n        }\r\n    }\r\n\r\n    // sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    if (faceColors) {\r\n        const totalColors = sideOrientation === VertexData.DOUBLESIDE ? colors.concat(colors) : colors;\r\n        vertexData.colors = totalColors;\r\n    }\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates the VertexData for a segmented box\r\n * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n * * size sets the width, height and depth of the box to the value of size, optional default 1\r\n * * width sets the width (x direction) of the box, overwrites the width set by size, optional, default size\r\n * * height sets the height (y direction) of the box, overwrites the height set by size, optional, default size\r\n * * depth sets the depth (z direction) of the box, overwrites the depth set by size, optional, default size\r\n * * segments sets the number of segments on the all axis (1 by default)\r\n * * widthSegments sets the number of segments on the x axis (1 by default)\r\n * * heightSegments sets the number of segments on the y axis (1 by default)\r\n * * depthSegments sets the number of segments on the z axis (1 by default)\r\n * @returns the VertexData of the box\r\n */\r\nexport function CreateSegmentedBoxVertexData(options: {\r\n    size?: number;\r\n    width?: number;\r\n    height?: number;\r\n    depth?: number;\r\n    segments?: number;\r\n    widthSegments?: number;\r\n    heightSegments?: number;\r\n    depthSegments?: number;\r\n}): VertexData {\r\n    const width = options.width || options.size || 1;\r\n    const height = options.height || options.size || 1;\r\n    const depth = options.depth || options.size || 1;\r\n    const widthSegments = (options.widthSegments || options.segments || 1) | 0;\r\n    const heightSegments = (options.heightSegments || options.segments || 1) | 0;\r\n    const depthSegments = (options.depthSegments || options.segments || 1) | 0;\r\n    const rotationMatrix = new Matrix();\r\n    const translationMatrix = new Matrix();\r\n    const transformMatrix = new Matrix();\r\n\r\n    const bottomPlane = CreateGroundVertexData({ width: width, height: depth, subdivisionsX: widthSegments, subdivisionsY: depthSegments });\r\n    Matrix.TranslationToRef(0, -height / 2, 0, translationMatrix);\r\n    Matrix.RotationZToRef(Math.PI, rotationMatrix);\r\n    rotationMatrix.multiplyToRef(translationMatrix, transformMatrix);\r\n    bottomPlane.transform(transformMatrix);\r\n\r\n    const topPlane = CreateGroundVertexData({ width: width, height: depth, subdivisionsX: widthSegments, subdivisionsY: depthSegments });\r\n    Matrix.TranslationToRef(0, height / 2, 0, transformMatrix);\r\n    topPlane.transform(transformMatrix);\r\n\r\n    const negXPlane = CreateGroundVertexData({ width: height, height: depth, subdivisionsX: heightSegments, subdivisionsY: depthSegments });\r\n    Matrix.TranslationToRef(-width / 2, 0, 0, translationMatrix);\r\n    Matrix.RotationZToRef(Math.PI / 2, rotationMatrix);\r\n    rotationMatrix.multiplyToRef(translationMatrix, transformMatrix);\r\n    negXPlane.transform(transformMatrix);\r\n\r\n    const posXPlane = CreateGroundVertexData({ width: height, height: depth, subdivisionsX: heightSegments, subdivisionsY: depthSegments });\r\n    Matrix.TranslationToRef(width / 2, 0, 0, translationMatrix);\r\n    Matrix.RotationZToRef(-Math.PI / 2, rotationMatrix);\r\n    rotationMatrix.multiplyToRef(translationMatrix, transformMatrix);\r\n    posXPlane.transform(transformMatrix);\r\n\r\n    const negZPlane = CreateGroundVertexData({ width: width, height: height, subdivisionsX: widthSegments, subdivisionsY: heightSegments });\r\n    Matrix.TranslationToRef(0, 0, -depth / 2, translationMatrix);\r\n    Matrix.RotationXToRef(-Math.PI / 2, rotationMatrix);\r\n    rotationMatrix.multiplyToRef(translationMatrix, transformMatrix);\r\n    negZPlane.transform(transformMatrix);\r\n\r\n    const posZPlane = CreateGroundVertexData({ width: width, height: height, subdivisionsX: widthSegments, subdivisionsY: heightSegments });\r\n    Matrix.TranslationToRef(0, 0, depth / 2, translationMatrix);\r\n    Matrix.RotationXToRef(Math.PI / 2, rotationMatrix);\r\n    rotationMatrix.multiplyToRef(translationMatrix, transformMatrix);\r\n    posZPlane.transform(transformMatrix);\r\n\r\n    // Result\r\n    bottomPlane.merge([topPlane, posXPlane, negXPlane, negZPlane, posZPlane], true);\r\n\r\n    return bottomPlane;\r\n}\r\n\r\n/**\r\n * Creates a box mesh\r\n * * The parameter `size` sets the size (float) of each box side (default 1)\r\n * * You can set some different box dimensions by using the parameters `width`, `height` and `depth` (all by default have the same value of `size`)\r\n * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of 6 Color3 elements) and `faceUV` (an array of 6 Vector4 elements)\r\n * * Please read this tutorial : https://doc.babylonjs.com/features/featuresDeepDive/materials/using/texturePerBoxFace\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#box\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the box mesh\r\n */\r\nexport function CreateBox(\r\n    name: string,\r\n    options: {\r\n        size?: number;\r\n        width?: number;\r\n        height?: number;\r\n        depth?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        wrap?: boolean;\r\n        topBaseAt?: number;\r\n        bottomBaseAt?: number;\r\n        updatable?: boolean;\r\n    } = {},\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const box = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    box._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateBoxVertexData(options);\r\n\r\n    vertexData.applyToMesh(box, options.updatable);\r\n\r\n    return box;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated please use CreateBox directly\r\n */\r\nexport const BoxBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateBox,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for boxBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBoxBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Side effects\r\n    VertexData.CreateBox = CreateBoxVertexData;\r\n\r\n    Mesh.CreateBox = (name: string, size: number, scene: Nullable<Scene> = null, updatable?: boolean, sideOrientation?: number): Mesh => {\r\n        const options = {\r\n            size,\r\n            sideOrientation,\r\n            updatable,\r\n        };\r\n\r\n        return CreateBox(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\n\r\n/**\r\n * Creates the VertexData for a tiled plane\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/tiled_plane\r\n * @param options an object used to set the following optional parameters for the tiled plane, required but can be empty\r\n * * pattern a limited pattern arrangement depending on the number\r\n * * size of the box\r\n * * width of the box, overwrites size\r\n * * height of the box, overwrites size\r\n * * tileSize sets the width, height and depth of the tile to the value of size, optional default 1\r\n * * tileWidth sets the width (x direction) of the tile, overwrites the width set by size, optional, default size\r\n * * tileHeight sets the height (y direction) of the tile, overwrites the height set by size, optional, default size\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * alignHorizontal places whole tiles aligned to the center, left or right of a row\r\n * * alignVertical places whole tiles aligned to the center, left or right of a column\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the tiled plane\r\n */\r\nexport function CreateTiledPlaneVertexData(options: {\r\n    pattern?: number;\r\n    tileSize?: number;\r\n    tileWidth?: number;\r\n    tileHeight?: number;\r\n    size?: number;\r\n    width?: number;\r\n    height?: number;\r\n    alignHorizontal?: number;\r\n    alignVertical?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n}): VertexData {\r\n    const flipTile = options.pattern || Mesh.NO_FLIP;\r\n    const tileWidth = options.tileWidth || options.tileSize || 1;\r\n    const tileHeight = options.tileHeight || options.tileSize || 1;\r\n    const alignH = options.alignHorizontal || 0;\r\n    const alignV = options.alignVertical || 0;\r\n\r\n    const width = options.width || options.size || 1;\r\n    const tilesX = Math.floor(width / tileWidth);\r\n    let offsetX = width - tilesX * tileWidth;\r\n\r\n    const height = options.height || options.size || 1;\r\n    const tilesY = Math.floor(height / tileHeight);\r\n    let offsetY = height - tilesY * tileHeight;\r\n\r\n    const halfWidth = (tileWidth * tilesX) / 2;\r\n    const halfHeight = (tileHeight * tilesY) / 2;\r\n\r\n    let adjustX = 0;\r\n    let adjustY = 0;\r\n    let startX = 0;\r\n    let startY = 0;\r\n    let endX = 0;\r\n    let endY = 0;\r\n\r\n    //Part Tiles\r\n    if (offsetX > 0 || offsetY > 0) {\r\n        startX = -halfWidth;\r\n        startY = -halfHeight;\r\n        endX = halfWidth;\r\n        endY = halfHeight;\r\n\r\n        switch (alignH) {\r\n            case Mesh.CENTER:\r\n                offsetX /= 2;\r\n                startX -= offsetX;\r\n                endX += offsetX;\r\n                break;\r\n            case Mesh.LEFT:\r\n                endX += offsetX;\r\n                adjustX = -offsetX / 2;\r\n                break;\r\n            case Mesh.RIGHT:\r\n                startX -= offsetX;\r\n                adjustX = offsetX / 2;\r\n                break;\r\n        }\r\n\r\n        switch (alignV) {\r\n            case Mesh.CENTER:\r\n                offsetY /= 2;\r\n                startY -= offsetY;\r\n                endY += offsetY;\r\n                break;\r\n            case Mesh.BOTTOM:\r\n                endY += offsetY;\r\n                adjustY = -offsetY / 2;\r\n                break;\r\n            case Mesh.TOP:\r\n                startY -= offsetY;\r\n                adjustY = offsetY / 2;\r\n                break;\r\n        }\r\n    }\r\n\r\n    const positions = [];\r\n    const normals = [];\r\n    const uvBase = [];\r\n    uvBase[0] = [0, 0, 1, 0, 1, 1, 0, 1];\r\n    uvBase[1] = [0, 0, 1, 0, 1, 1, 0, 1];\r\n    if (flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.ROTATE_ROW) {\r\n        uvBase[1] = [1, 1, 0, 1, 0, 0, 1, 0];\r\n    }\r\n    if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.FLIP_ROW) {\r\n        uvBase[1] = [1, 0, 0, 0, 0, 1, 1, 1];\r\n    }\r\n    if (flipTile === Mesh.FLIP_N_ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n        uvBase[1] = [0, 1, 1, 1, 1, 0, 0, 0];\r\n    }\r\n    let uvs: Array<number> = [];\r\n    const colors = [];\r\n    const indices = [];\r\n    let index = 0;\r\n    for (let y = 0; y < tilesY; y++) {\r\n        for (let x = 0; x < tilesX; x++) {\r\n            positions.push(-halfWidth + x * tileWidth + adjustX, -halfHeight + y * tileHeight + adjustY, 0);\r\n            positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, -halfHeight + y * tileHeight + adjustY, 0);\r\n            positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);\r\n            positions.push(-halfWidth + x * tileWidth + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);\r\n            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n            if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_TILE) {\r\n                uvs = uvs.concat(uvBase[((x % 2) + (y % 2)) % 2]);\r\n            } else if (flipTile === Mesh.FLIP_ROW || flipTile === Mesh.ROTATE_ROW || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                uvs = uvs.concat(uvBase[y % 2]);\r\n            } else {\r\n                uvs = uvs.concat(uvBase[0]);\r\n            }\r\n            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n            index += 4;\r\n        }\r\n    }\r\n\r\n    //Part Tiles\r\n    if (offsetX > 0 || offsetY > 0) {\r\n        const partialBottomRow: boolean = offsetY > 0 && (alignV === Mesh.CENTER || alignV === Mesh.TOP);\r\n        const partialTopRow: boolean = offsetY > 0 && (alignV === Mesh.CENTER || alignV === Mesh.BOTTOM);\r\n        const partialLeftCol: boolean = offsetX > 0 && (alignH === Mesh.CENTER || alignH === Mesh.RIGHT);\r\n        const partialRightCol: boolean = offsetX > 0 && (alignH === Mesh.CENTER || alignH === Mesh.LEFT);\r\n        let uvPart: Array<number>;\r\n        let a, b, c, d: number;\r\n\r\n        //corners\r\n        if (partialBottomRow && partialLeftCol) {\r\n            //bottom left corner\r\n            positions.push(startX + adjustX, startY + adjustY, 0);\r\n            positions.push(-halfWidth + adjustX, startY + adjustY, 0);\r\n            positions.push(-halfWidth + adjustX, startY + offsetY + adjustY, 0);\r\n            positions.push(startX + adjustX, startY + offsetY + adjustY, 0);\r\n            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n            index += 4;\r\n            a = 1 - offsetX / tileWidth;\r\n            b = 1 - offsetY / tileHeight;\r\n            c = 1;\r\n            d = 1;\r\n            uvPart = [a, b, c, b, c, d, a, d];\r\n            if (flipTile === Mesh.ROTATE_ROW) {\r\n                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_ROW) {\r\n                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            uvs = uvs.concat(uvPart);\r\n            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n        }\r\n\r\n        if (partialBottomRow && partialRightCol) {\r\n            //bottom right corner\r\n            positions.push(halfWidth + adjustX, startY + adjustY, 0);\r\n            positions.push(endX + adjustX, startY + adjustY, 0);\r\n            positions.push(endX + adjustX, startY + offsetY + adjustY, 0);\r\n            positions.push(halfWidth + adjustX, startY + offsetY + adjustY, 0);\r\n            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n            index += 4;\r\n            a = 0;\r\n            b = 1 - offsetY / tileHeight;\r\n            c = offsetX / tileWidth;\r\n            d = 1;\r\n            uvPart = [a, b, c, b, c, d, a, d];\r\n            if (flipTile === Mesh.ROTATE_ROW || (flipTile === Mesh.ROTATE_TILE && tilesX % 2 === 0)) {\r\n                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_ROW || (flipTile === Mesh.FLIP_TILE && tilesX % 2 === 0)) {\r\n                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_N_ROTATE_ROW || (flipTile === Mesh.FLIP_N_ROTATE_TILE && tilesX % 2 === 0)) {\r\n                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            uvs = uvs.concat(uvPart);\r\n            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n        }\r\n\r\n        if (partialTopRow && partialLeftCol) {\r\n            //top left corner\r\n            positions.push(startX + adjustX, halfHeight + adjustY, 0);\r\n            positions.push(-halfWidth + adjustX, halfHeight + adjustY, 0);\r\n            positions.push(-halfWidth + adjustX, endY + adjustY, 0);\r\n            positions.push(startX + adjustX, endY + adjustY, 0);\r\n            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n            index += 4;\r\n            a = 1 - offsetX / tileWidth;\r\n            b = 0;\r\n            c = 1;\r\n            d = offsetY / tileHeight;\r\n            uvPart = [a, b, c, b, c, d, a, d];\r\n            if ((flipTile === Mesh.ROTATE_ROW && tilesY % 2 === 1) || (flipTile === Mesh.ROTATE_TILE && tilesY % 1 === 0)) {\r\n                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if ((flipTile === Mesh.FLIP_ROW && tilesY % 2 === 1) || (flipTile === Mesh.FLIP_TILE && tilesY % 2 === 0)) {\r\n                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if ((flipTile === Mesh.FLIP_N_ROTATE_ROW && tilesY % 2 === 1) || (flipTile === Mesh.FLIP_N_ROTATE_TILE && tilesY % 2 === 0)) {\r\n                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            uvs = uvs.concat(uvPart);\r\n            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n        }\r\n\r\n        if (partialTopRow && partialRightCol) {\r\n            //top right corner\r\n            positions.push(halfWidth + adjustX, halfHeight + adjustY, 0);\r\n            positions.push(endX + adjustX, halfHeight + adjustY, 0);\r\n            positions.push(endX + adjustX, endY + adjustY, 0);\r\n            positions.push(halfWidth + adjustX, endY + adjustY, 0);\r\n            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n            index += 4;\r\n            a = 0;\r\n            b = 0;\r\n            c = offsetX / tileWidth;\r\n            d = offsetY / tileHeight;\r\n            uvPart = [a, b, c, b, c, d, a, d];\r\n            if ((flipTile === Mesh.ROTATE_ROW && tilesY % 2 === 1) || (flipTile === Mesh.ROTATE_TILE && (tilesY + tilesX) % 2 === 1)) {\r\n                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if ((flipTile === Mesh.FLIP_ROW && tilesY % 2 === 1) || (flipTile === Mesh.FLIP_TILE && (tilesY + tilesX) % 2 === 1)) {\r\n                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if ((flipTile === Mesh.FLIP_N_ROTATE_ROW && tilesY % 2 === 1) || (flipTile === Mesh.FLIP_N_ROTATE_TILE && (tilesY + tilesX) % 2 === 1)) {\r\n                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            uvs = uvs.concat(uvPart);\r\n            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n        }\r\n\r\n        //part rows\r\n        if (partialBottomRow) {\r\n            const uvBaseBR = [];\r\n            a = 0;\r\n            b = 1 - offsetY / tileHeight;\r\n            c = 1;\r\n            d = 1;\r\n            uvBaseBR[0] = [a, b, c, b, c, d, a, d];\r\n            uvBaseBR[1] = [a, b, c, b, c, d, a, d];\r\n            if (flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.ROTATE_ROW) {\r\n                uvBaseBR[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.FLIP_ROW) {\r\n                uvBaseBR[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_N_ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                uvBaseBR[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            for (let x = 0; x < tilesX; x++) {\r\n                positions.push(-halfWidth + x * tileWidth + adjustX, startY + adjustY, 0);\r\n                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, startY + adjustY, 0);\r\n                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, startY + offsetY + adjustY, 0);\r\n                positions.push(-halfWidth + x * tileWidth + adjustX, startY + offsetY + adjustY, 0);\r\n                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n                index += 4;\r\n                if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_TILE) {\r\n                    uvs = uvs.concat(uvBaseBR[(x + 1) % 2]);\r\n                } else if (flipTile === Mesh.FLIP_ROW || flipTile === Mesh.ROTATE_ROW || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                    uvs = uvs.concat(uvBaseBR[1]);\r\n                } else {\r\n                    uvs = uvs.concat(uvBaseBR[0]);\r\n                }\r\n                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n            }\r\n        }\r\n\r\n        if (partialTopRow) {\r\n            const uvBaseTR = [];\r\n            a = 0;\r\n            b = 0;\r\n            c = 1;\r\n            d = offsetY / tileHeight;\r\n            uvBaseTR[0] = [a, b, c, b, c, d, a, d];\r\n            uvBaseTR[1] = [a, b, c, b, c, d, a, d];\r\n            if (flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.ROTATE_ROW) {\r\n                uvBaseTR[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.FLIP_ROW) {\r\n                uvBaseTR[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_N_ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                uvBaseTR[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            for (let x = 0; x < tilesX; x++) {\r\n                positions.push(-halfWidth + x * tileWidth + adjustX, endY - offsetY + adjustY, 0);\r\n                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, endY - offsetY + adjustY, 0);\r\n                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, endY + adjustY, 0);\r\n                positions.push(-halfWidth + x * tileWidth + adjustX, endY + adjustY, 0);\r\n                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n                index += 4;\r\n                if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_TILE) {\r\n                    uvs = uvs.concat(uvBaseTR[(x + tilesY) % 2]);\r\n                } else if (flipTile === Mesh.FLIP_ROW || flipTile === Mesh.ROTATE_ROW || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                    uvs = uvs.concat(uvBaseTR[tilesY % 2]);\r\n                } else {\r\n                    uvs = uvs.concat(uvBaseTR[0]);\r\n                }\r\n                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n            }\r\n        }\r\n\r\n        if (partialLeftCol) {\r\n            const uvBaseLC = [];\r\n            a = 1 - offsetX / tileWidth;\r\n            b = 0;\r\n            c = 1;\r\n            d = 1;\r\n            uvBaseLC[0] = [a, b, c, b, c, d, a, d];\r\n            uvBaseLC[1] = [a, b, c, b, c, d, a, d];\r\n            if (flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.ROTATE_ROW) {\r\n                uvBaseLC[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.FLIP_ROW) {\r\n                uvBaseLC[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_N_ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                uvBaseLC[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            for (let y = 0; y < tilesY; y++) {\r\n                positions.push(startX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);\r\n                positions.push(startX + offsetX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);\r\n                positions.push(startX + offsetX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);\r\n                positions.push(startX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);\r\n                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n                index += 4;\r\n                if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_TILE) {\r\n                    uvs = uvs.concat(uvBaseLC[(y + 1) % 2]);\r\n                } else if (flipTile === Mesh.FLIP_ROW || flipTile === Mesh.ROTATE_ROW || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                    uvs = uvs.concat(uvBaseLC[y % 2]);\r\n                } else {\r\n                    uvs = uvs.concat(uvBaseLC[0]);\r\n                }\r\n                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n            }\r\n        }\r\n\r\n        if (partialRightCol) {\r\n            const uvBaseRC = [];\r\n            a = 0;\r\n            b = 0;\r\n            c = offsetX / tileHeight;\r\n            d = 1;\r\n            uvBaseRC[0] = [a, b, c, b, c, d, a, d];\r\n            uvBaseRC[1] = [a, b, c, b, c, d, a, d];\r\n            if (flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.ROTATE_ROW) {\r\n                uvBaseRC[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.FLIP_ROW) {\r\n                uvBaseRC[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];\r\n            }\r\n            if (flipTile === Mesh.FLIP_N_ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                uvBaseRC[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];\r\n            }\r\n            for (let y = 0; y < tilesY; y++) {\r\n                positions.push(endX - offsetX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);\r\n                positions.push(endX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);\r\n                positions.push(endX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);\r\n                positions.push(endX - offsetX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);\r\n                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);\r\n                index += 4;\r\n                if (flipTile === Mesh.FLIP_TILE || flipTile === Mesh.ROTATE_TILE || flipTile === Mesh.FLIP_N_ROTATE_TILE) {\r\n                    uvs = uvs.concat(uvBaseRC[(y + tilesX) % 2]);\r\n                } else if (flipTile === Mesh.FLIP_ROW || flipTile === Mesh.ROTATE_ROW || flipTile === Mesh.FLIP_N_ROTATE_ROW) {\r\n                    uvs = uvs.concat(uvBaseRC[y % 2]);\r\n                } else {\r\n                    uvs = uvs.concat(uvBaseRC[0]);\r\n                }\r\n                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);\r\n                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);\r\n            }\r\n        }\r\n    }\r\n\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    // sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    const totalColors = sideOrientation === VertexData.DOUBLESIDE ? colors.concat(colors) : colors;\r\n    vertexData.colors = totalColors;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a tiled plane mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/tiled_plane\r\n * @param name defines the name of the mesh\r\n * @param options an object used to set the following optional parameters for the tiled plane, required but can be empty\r\n * * pattern a limited pattern arrangement depending on the number\r\n * * size of the box\r\n * * width of the box, overwrites size\r\n * * height of the box, overwrites size\r\n * * tileSize sets the width, height and depth of the tile to the value of size, optional default 1\r\n * * tileWidth sets the width (x direction) of the tile, overwrites the width set by size, optional, default size\r\n * * tileHeight sets the height (y direction) of the tile, overwrites the height set by size, optional, default size\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * alignHorizontal places whole tiles aligned to the center, left or right of a row\r\n * * alignVertical places whole tiles aligned to the center, left or right of a column\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @param scene defines the hosting scene\r\n * @returns the box mesh\r\n */\r\nexport function CreateTiledPlane(\r\n    name: string,\r\n    options: {\r\n        pattern?: number;\r\n        tileSize?: number;\r\n        tileWidth?: number;\r\n        tileHeight?: number;\r\n        size?: number;\r\n        width?: number;\r\n        height?: number;\r\n        alignHorizontal?: number;\r\n        alignVertical?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        updatable?: boolean;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const plane = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    plane._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateTiledPlaneVertexData(options);\r\n\r\n    vertexData.applyToMesh(plane, options.updatable);\r\n\r\n    return plane;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateTiledPlane instead\r\n */\r\nexport const TiledPlaneBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateTiledPlane,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for the tiled plane builder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTiledPlaneBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateTiledPlane = CreateTiledPlaneVertexData;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Matrix, Vector3, Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { CreateTiledPlaneVertexData, RegisterTiledPlaneBuilder } from \"./tiledPlaneBuilder.pure\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\n\r\nconst OP_ADD = 1;\r\nconst OP_SUB = -1;\r\n\r\n/**\r\n * Creates the VertexData for a tiled box\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/tiled_box\r\n * @param options an object used to set the following optional parameters for the tiled box, required but can be empty\r\n * * pattern sets the rotation or reflection pattern for the tiles,\r\n * * size of the box\r\n * * width of the box, overwrites size\r\n * * height of the box, overwrites size\r\n * * depth of the box, overwrites size\r\n * * tileSize sets the size of a tile\r\n * * tileWidth sets the tile width and overwrites tileSize\r\n * * tileHeight sets the tile width and overwrites tileSize\r\n * * faceUV an array of 6 Vector4 elements used to set different images to each box side\r\n * * faceColors an array of 6 Color4 elements used to set different colors to each box side\r\n * * alignHorizontal places whole tiles aligned to the center, left or right of a row\r\n * * alignVertical places whole tiles aligned to the center, left or right of a column\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * @returns the VertexData of the TiledBox\r\n */\r\nexport function CreateTiledBoxVertexData(options: {\r\n    pattern?: number;\r\n    size?: number;\r\n    width?: number;\r\n    height?: number;\r\n    depth?: number;\r\n    tileSize?: number;\r\n    tileWidth?: number;\r\n    tileHeight?: number;\r\n    faceUV?: Vector4[];\r\n    faceColors?: Color4[];\r\n    alignHorizontal?: number;\r\n    alignVertical?: number;\r\n    sideOrientation?: number;\r\n}): VertexData {\r\n    const nbFaces = 6;\r\n\r\n    const faceUV: Vector4[] = options.faceUV || new Array<Vector4>(6);\r\n    const faceColors = options.faceColors;\r\n\r\n    const flipTile = options.pattern || Mesh.NO_FLIP;\r\n\r\n    const width = options.width || options.size || 1;\r\n    const height = options.height || options.size || 1;\r\n    const depth = options.depth || options.size || 1;\r\n    const tileWidth = options.tileWidth || options.tileSize || 1;\r\n    const tileHeight = options.tileHeight || options.tileSize || 1;\r\n    const alignH = options.alignHorizontal || 0;\r\n    const alignV = options.alignVertical || 0;\r\n\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    // default face colors and UV if undefined\r\n    for (let f = 0; f < nbFaces; f++) {\r\n        if (faceUV[f] === undefined) {\r\n            faceUV[f] = new Vector4(0, 0, 1, 1);\r\n        }\r\n        if (faceColors && faceColors[f] === undefined) {\r\n            faceColors[f] = new Color4(1, 1, 1, 1);\r\n        }\r\n    }\r\n\r\n    const halfWidth = width / 2;\r\n    const halfHeight = height / 2;\r\n    const halfDepth = depth / 2;\r\n\r\n    const faceVertexData: Array<VertexData> = [];\r\n\r\n    for (let f = 0; f < 2; f++) {\r\n        //front and back\r\n        faceVertexData[f] = CreateTiledPlaneVertexData({\r\n            pattern: flipTile,\r\n            tileWidth: tileWidth,\r\n            tileHeight: tileHeight,\r\n            width: width,\r\n            height: height,\r\n            alignVertical: alignV,\r\n            alignHorizontal: alignH,\r\n            sideOrientation: sideOrientation,\r\n        });\r\n    }\r\n\r\n    for (let f = 2; f < 4; f++) {\r\n        //sides\r\n        faceVertexData[f] = CreateTiledPlaneVertexData({\r\n            pattern: flipTile,\r\n            tileWidth: tileWidth,\r\n            tileHeight: tileHeight,\r\n            width: depth,\r\n            height: height,\r\n            alignVertical: alignV,\r\n            alignHorizontal: alignH,\r\n            sideOrientation: sideOrientation,\r\n        });\r\n    }\r\n\r\n    let baseAlignV = alignV;\r\n    if (alignV === Mesh.BOTTOM) {\r\n        baseAlignV = Mesh.TOP;\r\n    } else if (alignV === Mesh.TOP) {\r\n        baseAlignV = Mesh.BOTTOM;\r\n    }\r\n\r\n    for (let f = 4; f < 6; f++) {\r\n        //top and bottom\r\n        faceVertexData[f] = CreateTiledPlaneVertexData({\r\n            pattern: flipTile,\r\n            tileWidth: tileWidth,\r\n            tileHeight: tileHeight,\r\n            width: width,\r\n            height: depth,\r\n            alignVertical: baseAlignV,\r\n            alignHorizontal: alignH,\r\n            sideOrientation: sideOrientation,\r\n        });\r\n    }\r\n\r\n    const positions: Array<number> = [];\r\n    const normals: Array<number> = [];\r\n    let uvs: Array<number> = [];\r\n    let indices: Array<number> = [];\r\n    const colors: Array<number> = [];\r\n    const facePositions: Array<Array<Vector3>> = [];\r\n    const faceNormals: Array<Array<Vector3>> = [];\r\n\r\n    const newFaceUV: Array<Array<number>> = [];\r\n    let lu: number;\r\n\r\n    let li: number = 0;\r\n\r\n    for (let f = 0; f < nbFaces; f++) {\r\n        const len = faceVertexData[f].positions!.length;\r\n        facePositions[f] = [];\r\n        faceNormals[f] = [];\r\n        for (let p = 0; p < len / 3; p++) {\r\n            facePositions[f].push(new Vector3(faceVertexData[f].positions![3 * p], faceVertexData[f].positions![3 * p + 1], faceVertexData[f].positions![3 * p + 2]));\r\n            faceNormals[f].push(new Vector3(faceVertexData[f].normals![3 * p], faceVertexData[f].normals![3 * p + 1], faceVertexData[f].normals![3 * p + 2]));\r\n        }\r\n        // uvs\r\n        lu = faceVertexData[f].uvs!.length;\r\n        newFaceUV[f] = [];\r\n        for (let i = 0; i < lu; i += 2) {\r\n            newFaceUV[f][i] = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * faceVertexData[f].uvs![i];\r\n            newFaceUV[f][i + 1] = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * faceVertexData[f].uvs![i + 1];\r\n\r\n            if (useOpenGLOrientationForUV) {\r\n                newFaceUV[f][i + 1] = 1.0 - newFaceUV[f][i + 1];\r\n            }\r\n        }\r\n        uvs = uvs.concat(newFaceUV[f]);\r\n\r\n        indices = indices.concat(<Array<number>>faceVertexData[f].indices!.map((x: number) => x + li));\r\n        li += facePositions[f].length;\r\n        if (faceColors) {\r\n            const color = faceColors[f];\r\n            for (let p = 0; p < facePositions[f].length; p++) {\r\n                colors.push(color.r, color.g, color.b, color.a);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Define transforms for each face\r\n    const faceTransforms = [\r\n        // FRONT\r\n        { m: Matrix.RotationY(Math.PI), t: new Vector3(0, 0, halfDepth), op: OP_ADD },\r\n        // BACK\r\n        { m: Matrix.Identity(), t: new Vector3(0, 0, halfDepth), op: OP_SUB },\r\n        // RIGHT\r\n        { m: Matrix.RotationY(-Math.PI / 2), t: new Vector3(halfWidth, 0, 0), op: OP_ADD },\r\n        // LEFT\r\n        { m: Matrix.RotationY(Math.PI / 2), t: new Vector3(halfWidth, 0, 0), op: OP_SUB },\r\n        // TOP\r\n        { m: Matrix.RotationX(Math.PI / 2), t: new Vector3(0, halfHeight, 0), op: OP_ADD },\r\n        // BOTTOM\r\n        { m: Matrix.RotationX(-Math.PI / 2), t: new Vector3(0, halfHeight, 0), op: OP_SUB },\r\n    ];\r\n\r\n    // Assemble positions and normals\r\n    for (let f = 0; f < nbFaces; f++) {\r\n        const { m, t, op } = faceTransforms[f];\r\n\r\n        for (const v of facePositions[f]) {\r\n            const p = Vector3.TransformCoordinates(v, m);\r\n            const final = op === OP_ADD ? p.add(t) : p.subtract(t);\r\n            positions.push(final.x, final.y, final.z);\r\n        }\r\n\r\n        for (const n of faceNormals[f]) {\r\n            const nn = Vector3.TransformNormal(n, m);\r\n            normals.push(nn.x, nn.y, nn.z);\r\n        }\r\n    }\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    if (faceColors) {\r\n        const totalColors = sideOrientation === VertexData.DOUBLESIDE ? colors.concat(colors) : colors;\r\n        vertexData.colors = totalColors;\r\n    }\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a tiled box mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/tiled_box\r\n * @param name defines the name of the mesh\r\n * @param options an object used to set the following optional parameters for the tiled box, required but can be empty\r\n * * pattern sets the rotation or reflection pattern for the tiles,\r\n * * size of the box\r\n * * width of the box, overwrites size\r\n * * height of the box, overwrites size\r\n * * depth of the box, overwrites size\r\n * * tileSize sets the size of a tile\r\n * * tileWidth sets the tile width and overwrites tileSize\r\n * * tileHeight sets the tile width and overwrites tileSize\r\n * * faceUV an array of 6 Vector4 elements used to set different images to each box side\r\n * * faceColors an array of 6 Color3 elements used to set different colors to each box side\r\n * * alignHorizontal places whole tiles aligned to the center, left or right of a row\r\n * * alignVertical places whole tiles aligned to the center, left or right of a column\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * @param scene defines the hosting scene\r\n * @returns the box mesh\r\n */\r\nexport function CreateTiledBox(\r\n    name: string,\r\n    options: {\r\n        pattern?: number;\r\n        width?: number;\r\n        height?: number;\r\n        depth?: number;\r\n        tileSize?: number;\r\n        tileWidth?: number;\r\n        tileHeight?: number;\r\n        alignHorizontal?: number;\r\n        alignVertical?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        sideOrientation?: number;\r\n        updatable?: boolean;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const box = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    box._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateTiledBoxVertexData(options);\r\n\r\n    vertexData.applyToMesh(box, options.updatable);\r\n\r\n    return box;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateTiledBox instead\r\n */\r\nexport const TiledBoxBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateTiledBox,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for the tiled box builder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTiledBoxBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterTiledPlaneBuilder();\r\n    VertexData.CreateTiledBox = CreateTiledBoxVertexData;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData for an ellipsoid, defaults to a sphere\r\n * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n * * segments sets the number of horizontal strips optional, default 32\r\n * * diameter sets the axes dimensions, diameterX, diameterY and diameterZ to the value of diameter, optional default 1\r\n * * diameterX sets the diameterX (x direction) of the ellipsoid, overwrites the diameterX set by diameter, optional, default diameter\r\n * * diameterY sets the diameterY (y direction) of the ellipsoid, overwrites the diameterY set by diameter, optional, default diameter\r\n * * diameterZ sets the diameterZ (z direction) of the ellipsoid, overwrites the diameterZ set by diameter, optional, default diameter\r\n * * arc a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the circumference (latitude) given by the arc value, optional, default 1\r\n * * slice a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the height (latitude) given by the arc value, optional, default 1\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the ellipsoid\r\n */\r\nexport function CreateSphereVertexData(options: {\r\n    segments?: number;\r\n    diameter?: number;\r\n    diameterX?: number;\r\n    diameterY?: number;\r\n    diameterZ?: number;\r\n    arc?: number;\r\n    slice?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n    dedupTopBottomIndices?: boolean;\r\n}): VertexData {\r\n    const segments: number = (options.segments || 32) | 0;\r\n    const diameterX: number = options.diameterX || options.diameter || 1;\r\n    const diameterY: number = options.diameterY || options.diameter || 1;\r\n    const diameterZ: number = options.diameterZ || options.diameter || 1;\r\n    const arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;\r\n    const slice: number = options.slice && options.slice <= 0 ? 1.0 : options.slice || 1.0;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n    const dedupTopBottomIndices = !!options.dedupTopBottomIndices;\r\n\r\n    const radius = new Vector3(diameterX / 2, diameterY / 2, diameterZ / 2);\r\n\r\n    const totalZRotationSteps = 2 + segments;\r\n    const totalYRotationSteps = 2 * totalZRotationSteps;\r\n\r\n    const indices = [];\r\n    const positions = [];\r\n    const normals = [];\r\n    const uvs = [];\r\n\r\n    for (let zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) {\r\n        const normalizedZ = zRotationStep / totalZRotationSteps;\r\n        const angleZ = normalizedZ * Math.PI * slice;\r\n\r\n        for (let yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) {\r\n            const normalizedY = yRotationStep / totalYRotationSteps;\r\n\r\n            const angleY = normalizedY * Math.PI * 2 * arc;\r\n\r\n            const rotationZ = Matrix.RotationZ(-angleZ);\r\n            const rotationY = Matrix.RotationY(angleY);\r\n            const afterRotZ = Vector3.TransformCoordinates(Vector3.Up(), rotationZ);\r\n            const complete = Vector3.TransformCoordinates(afterRotZ, rotationY);\r\n\r\n            const vertex = complete.multiply(radius);\r\n            const normal = complete.divide(radius).normalize();\r\n\r\n            positions.push(vertex.x, vertex.y, vertex.z);\r\n            normals.push(normal.x, normal.y, normal.z);\r\n            uvs.push(normalizedY, useOpenGLOrientationForUV ? 1.0 - normalizedZ : normalizedZ);\r\n        }\r\n\r\n        if (zRotationStep > 0) {\r\n            const verticesCount = positions.length / 3;\r\n            for (let firstIndex = verticesCount - 2 * (totalYRotationSteps + 1); firstIndex + totalYRotationSteps + 2 < verticesCount; firstIndex++) {\r\n                if (dedupTopBottomIndices) {\r\n                    if (zRotationStep > 1) {\r\n                        indices.push(firstIndex);\r\n                        indices.push(firstIndex + 1);\r\n                        indices.push(firstIndex + totalYRotationSteps + 1);\r\n                    }\r\n                    if (zRotationStep < totalZRotationSteps || slice < 1.0) {\r\n                        indices.push(firstIndex + totalYRotationSteps + 1);\r\n                        indices.push(firstIndex + 1);\r\n                        indices.push(firstIndex + totalYRotationSteps + 2);\r\n                    }\r\n                } else {\r\n                    indices.push(firstIndex);\r\n                    indices.push(firstIndex + 1);\r\n                    indices.push(firstIndex + totalYRotationSteps + 1);\r\n\r\n                    indices.push(firstIndex + totalYRotationSteps + 1);\r\n                    indices.push(firstIndex + 1);\r\n                    indices.push(firstIndex + totalYRotationSteps + 2);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // Sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a sphere mesh\r\n * * The parameter `diameter` sets the diameter size (float) of the sphere (default 1)\r\n * * You can set some different sphere dimensions, for instance to build an ellipsoid, by using the parameters `diameterX`, `diameterY` and `diameterZ` (all by default have the same value of `diameter`)\r\n * * The parameter `segments` sets the sphere number of horizontal stripes (positive integer, default 32)\r\n * * You can create an unclosed sphere with the parameter `arc` (positive float, default 1), valued between 0 and 1, what is the ratio of the circumference (latitude) : 2 x PI x ratio\r\n * * You can create an unclosed sphere on its height with the parameter `slice` (positive float, default1), valued between 0 and 1, what is the height ratio (longitude)\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the sphere mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#sphere\r\n */\r\nexport function CreateSphere(\r\n    name: string,\r\n    options: {\r\n        segments?: number;\r\n        diameter?: number;\r\n        diameterX?: number;\r\n        diameterY?: number;\r\n        diameterZ?: number;\r\n        arc?: number;\r\n        slice?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        updatable?: boolean;\r\n    } = {},\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const sphere = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    sphere._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateSphereVertexData(options);\r\n\r\n    vertexData.applyToMesh(sphere, options.updatable);\r\n\r\n    return sphere;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateSphere directly\r\n */\r\nexport const SphereBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateSphere,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sphereBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSphereBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateSphere = CreateSphereVertexData;\r\n\r\n    Mesh.CreateSphere = (name: string, segments: number, diameter: number, scene?: Scene, updatable?: boolean, sideOrientation?: number): Mesh => {\r\n        const options = {\r\n            segments: segments,\r\n            diameterX: diameter,\r\n            diameterY: diameter,\r\n            diameterZ: diameter,\r\n            sideOrientation: sideOrientation,\r\n            updatable: updatable,\r\n        };\r\n\r\n        return CreateSphere(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector4, Vector3, Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\n\r\n/**\r\n * Creates the VertexData for a cylinder, cone or prism\r\n * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n * * height sets the height (y direction) of the cylinder, optional, default 2\r\n * * diameterTop sets the diameter of the top of the cone, overwrites diameter,  optional, default diameter\r\n * * diameterBottom sets the diameter of the bottom of the cone, overwrites diameter,  optional, default diameter\r\n * * diameter sets the diameter of the top and bottom of the cone, optional default 1\r\n * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24\r\n * * `subdivisions` the number of rings along the cylinder height, optional, default 1\r\n * * arc a number from 0 to 1, to create an unclosed cylinder based on the fraction of the circumference given by the arc value, optional, default 1\r\n * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n * * hasRings when true makes each subdivision independently treated as a face for faceUV and faceColors, optional, default false\r\n * * enclose when true closes an open cylinder by adding extra flat faces between the height axis and vertical edges, think cut cake\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the cylinder, cone or prism\r\n */\r\nexport function CreateCylinderVertexData(options: {\r\n    height?: number;\r\n    diameterTop?: number;\r\n    diameterBottom?: number;\r\n    diameter?: number;\r\n    tessellation?: number;\r\n    subdivisions?: number;\r\n    arc?: number;\r\n    faceColors?: Color4[];\r\n    faceUV?: Vector4[];\r\n    hasRings?: boolean;\r\n    enclose?: boolean;\r\n    cap?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n}): VertexData {\r\n    const height: number = options.height || 2;\r\n    let diameterTop: number = options.diameterTop === 0 ? 0 : options.diameterTop || options.diameter || 1;\r\n    let diameterBottom: number = options.diameterBottom === 0 ? 0 : options.diameterBottom || options.diameter || 1;\r\n    diameterTop = diameterTop || 0.00001; // Prevent broken normals\r\n    diameterBottom = diameterBottom || 0.00001; // Prevent broken normals\r\n    const tessellation: number = (options.tessellation || 24) | 0;\r\n    const subdivisions: number = (options.subdivisions || 1) | 0;\r\n    const hasRings: boolean = options.hasRings ? true : false;\r\n    const enclose: boolean = options.enclose ? true : false;\r\n    const cap = options.cap === 0 ? 0 : options.cap || Mesh.CAP_ALL;\r\n    const arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;\r\n    const sideOrientation: number = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n    const faceUV: Vector4[] = options.faceUV || new Array<Vector4>(3);\r\n    const faceColors = options.faceColors;\r\n    // default face colors and UV if undefined\r\n    const quadNb: number = arc !== 1 && enclose ? 2 : 0;\r\n    const ringNb: number = hasRings ? subdivisions : 1;\r\n    const surfaceNb: number = 2 + (1 + quadNb) * ringNb;\r\n    let f: number;\r\n\r\n    for (f = 0; f < surfaceNb; f++) {\r\n        if (faceColors && faceColors[f] === undefined) {\r\n            faceColors[f] = new Color4(1, 1, 1, 1);\r\n        }\r\n    }\r\n    for (f = 0; f < surfaceNb; f++) {\r\n        if (faceUV && faceUV[f] === undefined) {\r\n            faceUV[f] = new Vector4(0, 0, 1, 1);\r\n        }\r\n    }\r\n\r\n    const indices: number[] = [];\r\n    const positions: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n    const colors: number[] = [];\r\n\r\n    const angleStep = (Math.PI * 2 * arc) / tessellation;\r\n    let angle: number;\r\n    let h: number;\r\n    let radius: number;\r\n    const tan = (diameterBottom - diameterTop) / 2 / height;\r\n    const ringVertex: Vector3 = Vector3.Zero();\r\n    const ringNormal: Vector3 = Vector3.Zero();\r\n    const ringFirstVertex: Vector3 = Vector3.Zero();\r\n    const ringFirstNormal: Vector3 = Vector3.Zero();\r\n    const quadNormal: Vector3 = Vector3.Zero();\r\n    const y: Vector3 = Axis.Y;\r\n\r\n    // positions, normals, uvs\r\n    let i: number;\r\n    let j: number;\r\n    let r: number;\r\n    let ringIdx: number;\r\n    let s: number = 1; // surface index\r\n    let cs: number = 0;\r\n    let v: number;\r\n\r\n    for (i = 0; i <= subdivisions; i++) {\r\n        h = i / subdivisions;\r\n        radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;\r\n        ringIdx = hasRings && i !== 0 && i !== subdivisions ? 2 : 1;\r\n        for (r = 0; r < ringIdx; r++) {\r\n            if (hasRings) {\r\n                s += r;\r\n            }\r\n            if (enclose) {\r\n                s += 2 * r;\r\n            }\r\n            for (j = 0; j <= tessellation; j++) {\r\n                angle = j * angleStep;\r\n\r\n                // position\r\n                ringVertex.x = Math.cos(-angle) * radius;\r\n                ringVertex.y = -height / 2 + h * height;\r\n                ringVertex.z = Math.sin(-angle) * radius;\r\n\r\n                // normal\r\n                if (diameterTop === 0 && i === subdivisions) {\r\n                    // if no top cap, reuse former normals\r\n                    ringNormal.x = normals[normals.length - (tessellation + 1) * 3];\r\n                    ringNormal.y = normals[normals.length - (tessellation + 1) * 3 + 1];\r\n                    ringNormal.z = normals[normals.length - (tessellation + 1) * 3 + 2];\r\n                } else {\r\n                    ringNormal.x = ringVertex.x;\r\n                    ringNormal.z = ringVertex.z;\r\n                    ringNormal.y = Math.sqrt(ringNormal.x * ringNormal.x + ringNormal.z * ringNormal.z) * tan;\r\n                    ringNormal.normalize();\r\n                }\r\n\r\n                // keep first ring vertex values for enclose\r\n                if (j === 0) {\r\n                    ringFirstVertex.copyFrom(ringVertex);\r\n                    ringFirstNormal.copyFrom(ringNormal);\r\n                }\r\n\r\n                positions.push(ringVertex.x, ringVertex.y, ringVertex.z);\r\n                normals.push(ringNormal.x, ringNormal.y, ringNormal.z);\r\n                if (hasRings) {\r\n                    v = cs !== s ? faceUV[s].y : faceUV[s].w;\r\n                } else {\r\n                    v = faceUV[s].y + (faceUV[s].w - faceUV[s].y) * h;\r\n                }\r\n                uvs.push(faceUV[s].x + ((faceUV[s].z - faceUV[s].x) * j) / tessellation, useOpenGLOrientationForUV ? 1 - v : v);\r\n                if (faceColors) {\r\n                    colors.push(faceColors[s].r, faceColors[s].g, faceColors[s].b, faceColors[s].a);\r\n                }\r\n            }\r\n\r\n            // if enclose, add four vertices and their dedicated normals\r\n            if (arc !== 1 && enclose) {\r\n                positions.push(ringVertex.x, ringVertex.y, ringVertex.z);\r\n                positions.push(0, ringVertex.y, 0);\r\n                positions.push(0, ringVertex.y, 0);\r\n                positions.push(ringFirstVertex.x, ringFirstVertex.y, ringFirstVertex.z);\r\n                Vector3.CrossToRef(y, ringNormal, quadNormal);\r\n                quadNormal.normalize();\r\n                normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);\r\n                Vector3.CrossToRef(ringFirstNormal, y, quadNormal);\r\n                quadNormal.normalize();\r\n                normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);\r\n                if (hasRings) {\r\n                    v = cs !== s ? faceUV[s + 1].y : faceUV[s + 1].w;\r\n                } else {\r\n                    v = faceUV[s + 1].y + (faceUV[s + 1].w - faceUV[s + 1].y) * h;\r\n                }\r\n                uvs.push(faceUV[s + 1].x, useOpenGLOrientationForUV ? 1 - v : v);\r\n                uvs.push(faceUV[s + 1].z, useOpenGLOrientationForUV ? 1 - v : v);\r\n                if (hasRings) {\r\n                    v = cs !== s ? faceUV[s + 2].y : faceUV[s + 2].w;\r\n                } else {\r\n                    v = faceUV[s + 2].y + (faceUV[s + 2].w - faceUV[s + 2].y) * h;\r\n                }\r\n                uvs.push(faceUV[s + 2].x, useOpenGLOrientationForUV ? 1 - v : v);\r\n                uvs.push(faceUV[s + 2].z, useOpenGLOrientationForUV ? 1 - v : v);\r\n                if (faceColors) {\r\n                    colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);\r\n                    colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);\r\n                    colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);\r\n                    colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);\r\n                }\r\n            }\r\n            if (cs !== s) {\r\n                cs = s;\r\n            }\r\n        }\r\n    }\r\n\r\n    // indices\r\n    const e: number = arc !== 1 && enclose ? tessellation + 4 : tessellation; // correction of number of iteration if enclose\r\n    i = 0;\r\n    for (s = 0; s < subdivisions; s++) {\r\n        let i0: number = 0;\r\n        let i1: number = 0;\r\n        let i2: number = 0;\r\n        let i3: number = 0;\r\n        for (j = 0; j < tessellation; j++) {\r\n            i0 = i * (e + 1) + j;\r\n            i1 = (i + 1) * (e + 1) + j;\r\n            i2 = i * (e + 1) + (j + 1);\r\n            i3 = (i + 1) * (e + 1) + (j + 1);\r\n            indices.push(i0, i1, i2);\r\n            indices.push(i3, i2, i1);\r\n        }\r\n        if (arc !== 1 && enclose) {\r\n            // if enclose, add two quads\r\n            indices.push(i0 + 2, i1 + 2, i2 + 2);\r\n            indices.push(i3 + 2, i2 + 2, i1 + 2);\r\n            indices.push(i0 + 4, i1 + 4, i2 + 4);\r\n            indices.push(i3 + 4, i2 + 4, i1 + 4);\r\n        }\r\n        i = hasRings ? i + 2 : i + 1;\r\n    }\r\n\r\n    // Caps\r\n    const createCylinderCap = (isTop: boolean) => {\r\n        const radius = isTop ? diameterTop / 2 : diameterBottom / 2;\r\n        if (radius === 0) {\r\n            return;\r\n        }\r\n\r\n        // Cap positions, normals & uvs\r\n        let angle;\r\n        let circleVector;\r\n        let i: number;\r\n        const u: Vector4 = isTop ? faceUV[surfaceNb - 1] : faceUV[0];\r\n        let c: Nullable<Color4> = null;\r\n        if (faceColors) {\r\n            c = isTop ? faceColors[surfaceNb - 1] : faceColors[0];\r\n        }\r\n        // cap center\r\n        const vbase = positions.length / 3;\r\n        const offset = isTop ? height / 2 : -height / 2;\r\n        const center = new Vector3(0, offset, 0);\r\n        positions.push(center.x, center.y, center.z);\r\n        normals.push(0, isTop ? 1 : -1, 0);\r\n        const v = u.y + (u.w - u.y) * 0.5;\r\n        uvs.push(u.x + (u.z - u.x) * 0.5, useOpenGLOrientationForUV ? 1 - v : v);\r\n        if (c) {\r\n            colors.push(c.r, c.g, c.b, c.a);\r\n        }\r\n\r\n        const textureScale = new Vector2(0.5, 0.5);\r\n        for (i = 0; i <= tessellation; i++) {\r\n            angle = (Math.PI * 2 * i * arc) / tessellation;\r\n            const cos = Math.cos(-angle);\r\n            const sin = Math.sin(-angle);\r\n            circleVector = new Vector3(cos * radius, offset, sin * radius);\r\n            const textureCoordinate = new Vector2(cos * textureScale.x + 0.5, sin * textureScale.y + 0.5);\r\n            positions.push(circleVector.x, circleVector.y, circleVector.z);\r\n            normals.push(0, isTop ? 1 : -1, 0);\r\n            const v = u.y + (u.w - u.y) * textureCoordinate.y;\r\n            uvs.push(u.x + (u.z - u.x) * textureCoordinate.x, useOpenGLOrientationForUV ? 1 - v : v);\r\n            if (c) {\r\n                colors.push(c.r, c.g, c.b, c.a);\r\n            }\r\n        }\r\n        // Cap indices\r\n        for (i = 0; i < tessellation; i++) {\r\n            if (!isTop) {\r\n                indices.push(vbase);\r\n                indices.push(vbase + (i + 1));\r\n                indices.push(vbase + (i + 2));\r\n            } else {\r\n                indices.push(vbase);\r\n                indices.push(vbase + (i + 2));\r\n                indices.push(vbase + (i + 1));\r\n            }\r\n        }\r\n    };\r\n\r\n    // add caps to geometry based on cap parameter\r\n    if (cap === Mesh.CAP_START || cap === Mesh.CAP_ALL) {\r\n        createCylinderCap(false);\r\n    }\r\n    if (cap === Mesh.CAP_END || cap === Mesh.CAP_ALL) {\r\n        createCylinderCap(true);\r\n    }\r\n\r\n    // Sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n    if (faceColors) {\r\n        vertexData.colors = colors;\r\n    }\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a cylinder or a cone mesh\r\n * * The parameter `height` sets the height size (float) of the cylinder/cone (float, default 2).\r\n * * The parameter `diameter` sets the diameter of the top and bottom cap at once (float, default 1).\r\n * * The parameters `diameterTop` and `diameterBottom` overwrite the parameter `diameter` and set respectively the top cap and bottom cap diameter (floats, default 1). The parameter \"diameterBottom\" can't be zero.\r\n * * The parameter `tessellation` sets the number of cylinder sides (positive integer, default 24). Set it to 3 to get a prism for instance.\r\n * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).\r\n * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.\r\n * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.\r\n * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).\r\n * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.\r\n * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).\r\n * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3\r\n * * Now, if the cylinder has 5 independent subdivisions (hasRings = true), n equals : top face + 5 stripe surfaces + bottom face = 2 + 5 = 7\r\n * * Finally, if the cylinder has 5 independent subdivisions and is enclose, n equals : top face + 5 x (stripe surface + 2 closing faces) + bottom face = 2 + 5 * 3 = 17\r\n * * Each array (color or UVs) is always ordered the same way : the first element is the bottom cap, the last element is the top cap. The other elements are each a ring surface.\r\n * * If `enclose` is false, a ring surface is one element.\r\n * * If `enclose` is true, a ring surface is 3 successive elements in the array : the tubular surface, then the two closing faces.\r\n * * Example how to set colors and textures on a sliced cylinder : https://www.html5gamedevs.com/topic/17945-creating-a-closed-slice-of-a-cylinder/#comment-106379\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the cylinder mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#cylinder-or-cone\r\n */\r\nexport function CreateCylinder(\r\n    name: string,\r\n    options: {\r\n        height?: number;\r\n        diameterTop?: number;\r\n        diameterBottom?: number;\r\n        diameter?: number;\r\n        tessellation?: number;\r\n        subdivisions?: number;\r\n        arc?: number;\r\n        faceColors?: Color4[];\r\n        faceUV?: Vector4[];\r\n        updatable?: boolean;\r\n        hasRings?: boolean;\r\n        enclose?: boolean;\r\n        cap?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    } = {},\r\n    scene?: Nullable<Scene>\r\n): Mesh {\r\n    const cylinder = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    cylinder._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateCylinderVertexData(options);\r\n\r\n    vertexData.applyToMesh(cylinder, options.updatable);\r\n\r\n    return cylinder;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated Please use CreateCylinder directly\r\n */\r\nexport const CylinderBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateCylinder,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cylinderBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCylinderBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateCylinder = CreateCylinderVertexData;\r\n\r\n    Mesh.CreateCylinder = (\r\n        name: string,\r\n        height: number,\r\n        diameterTop: number,\r\n        diameterBottom: number,\r\n        tessellation: number,\r\n        subdivisions: any,\r\n        scene?: Scene,\r\n        updatable?: any,\r\n        sideOrientation?: number\r\n    ): Mesh => {\r\n        if (scene === undefined || !(scene instanceof Scene)) {\r\n            if (scene !== undefined) {\r\n                sideOrientation = updatable || Mesh.DEFAULTSIDE;\r\n                updatable = scene;\r\n            }\r\n            scene = <Scene>subdivisions;\r\n            subdivisions = 1;\r\n        }\r\n\r\n        const options = {\r\n            height,\r\n            diameterTop,\r\n            diameterBottom,\r\n            tessellation,\r\n            subdivisions,\r\n            sideOrientation,\r\n            updatable,\r\n        };\r\n\r\n        return CreateCylinder(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Matrix, Vector3, Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData for a torus\r\n * @param options an object used to set the following optional parameters for the box, required but can be empty\r\n * * diameter the diameter of the torus, optional default 1\r\n * * thickness the diameter of the tube forming the torus, optional default 0.5\r\n * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the torus\r\n */\r\nexport function CreateTorusVertexData(options: { diameter?: number; thickness?: number; tessellation?: number; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4 }) {\r\n    const indices = [];\r\n    const positions = [];\r\n    const normals = [];\r\n    const uvs = [];\r\n\r\n    const diameter = options.diameter || 1;\r\n    const thickness = options.thickness || 0.5;\r\n    const tessellation = (options.tessellation || 16) | 0;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    const stride = tessellation + 1;\r\n\r\n    for (let i = 0; i <= tessellation; i++) {\r\n        const u = i / tessellation;\r\n\r\n        const outerAngle = (i * Math.PI * 2.0) / tessellation - Math.PI / 2.0;\r\n\r\n        const transform = Matrix.Translation(diameter / 2.0, 0, 0).multiply(Matrix.RotationY(outerAngle));\r\n\r\n        for (let j = 0; j <= tessellation; j++) {\r\n            const v = 1 - j / tessellation;\r\n\r\n            const innerAngle = (j * Math.PI * 2.0) / tessellation + Math.PI;\r\n            const dx = Math.cos(innerAngle);\r\n            const dy = Math.sin(innerAngle);\r\n\r\n            // Create a vertex.\r\n            let normal = new Vector3(dx, dy, 0);\r\n            let position = normal.scale(thickness / 2);\r\n            const textureCoordinate = new Vector2(u, v);\r\n\r\n            position = Vector3.TransformCoordinates(position, transform);\r\n            normal = Vector3.TransformNormal(normal, transform);\r\n\r\n            positions.push(position.x, position.y, position.z);\r\n            normals.push(normal.x, normal.y, normal.z);\r\n            uvs.push(textureCoordinate.x, useOpenGLOrientationForUV ? 1.0 - textureCoordinate.y : textureCoordinate.y);\r\n\r\n            // And create indices for two triangles.\r\n            const nextI = (i + 1) % stride;\r\n            const nextJ = (j + 1) % stride;\r\n\r\n            indices.push(i * stride + j);\r\n            indices.push(i * stride + nextJ);\r\n            indices.push(nextI * stride + j);\r\n\r\n            indices.push(i * stride + nextJ);\r\n            indices.push(nextI * stride + nextJ);\r\n            indices.push(nextI * stride + j);\r\n        }\r\n    }\r\n\r\n    // Sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a torus mesh\r\n * * The parameter `diameter` sets the diameter size (float) of the torus (default 1)\r\n * * The parameter `thickness` sets the diameter size of the tube of the torus (float, default 0.5)\r\n * * The parameter `tessellation` sets the number of torus sides (positive integer, default 16)\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the torus mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#torus\r\n */\r\nexport function CreateTorus(\r\n    name: string,\r\n    options: { diameter?: number; thickness?: number; tessellation?: number; updatable?: boolean; sideOrientation?: number; frontUVs?: Vector4; backUVs?: Vector4 } = {},\r\n    scene?: Scene\r\n): Mesh {\r\n    const torus = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    torus._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateTorusVertexData(options);\r\n\r\n    vertexData.applyToMesh(torus, options.updatable);\r\n\r\n    return torus;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateTorus instead\r\n */\r\nexport const TorusBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateTorus,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for torusBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTorusBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateTorus = CreateTorusVertexData;\r\n\r\n    Mesh.CreateTorus = (name: string, diameter: number, thickness: number, tessellation: number, scene?: Scene, updatable?: boolean, sideOrientation?: number): Mesh => {\r\n        const options = {\r\n            diameter,\r\n            thickness,\r\n            tessellation,\r\n            sideOrientation,\r\n            updatable,\r\n        };\r\n\r\n        return CreateTorus(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n// based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473\r\n/**\r\n * Creates the VertexData for a TorusKnot\r\n * @param options an object used to set the following optional parameters for the TorusKnot, required but can be empty\r\n * * radius the radius of the torus knot, optional, default 2\r\n * * tube the thickness of the tube, optional, default 0.5\r\n * * radialSegments the number of sides on each tube segments, optional, default 32\r\n * * tubularSegments the number of tubes to decompose the knot into, optional, default 32\r\n * * p the number of windings around the z axis, optional,  default 2\r\n * * q the number of windings around the x axis, optional,  default 3\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the Torus Knot\r\n */\r\nexport function CreateTorusKnotVertexData(options: {\r\n    radius?: number;\r\n    tube?: number;\r\n    radialSegments?: number;\r\n    tubularSegments?: number;\r\n    p?: number;\r\n    q?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n}): VertexData {\r\n    const indices: number[] = [];\r\n    const positions: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n\r\n    const radius = options.radius || 2;\r\n    const tube = options.tube || 0.5;\r\n    const radialSegments = options.radialSegments || 32;\r\n    const tubularSegments = options.tubularSegments || 32;\r\n    const p = options.p || 2;\r\n    const q = options.q || 3;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    // Helper\r\n    const getPos = (angle: number) => {\r\n        const cu = Math.cos(angle);\r\n        const su = Math.sin(angle);\r\n        const quOverP = (q / p) * angle;\r\n        const cs = Math.cos(quOverP);\r\n\r\n        const tx = radius * (2 + cs) * 0.5 * cu;\r\n        const ty = radius * (2 + cs) * su * 0.5;\r\n        const tz = radius * Math.sin(quOverP) * 0.5;\r\n\r\n        return new Vector3(tx, ty, tz);\r\n    };\r\n\r\n    // Vertices\r\n    let i: number;\r\n    let j: number;\r\n    for (i = 0; i <= radialSegments; i++) {\r\n        const modI = i % radialSegments;\r\n        const u = (modI / radialSegments) * 2 * p * Math.PI;\r\n        const p1 = getPos(u);\r\n        const p2 = getPos(u + 0.01);\r\n        const tang = p2.subtract(p1);\r\n        let n = p2.add(p1);\r\n\r\n        const bitan = Vector3.Cross(tang, n);\r\n        n = Vector3.Cross(bitan, tang);\r\n\r\n        bitan.normalize();\r\n        n.normalize();\r\n\r\n        for (j = 0; j < tubularSegments; j++) {\r\n            const modJ = j % tubularSegments;\r\n            const v = (modJ / tubularSegments) * 2 * Math.PI;\r\n            const cx = -tube * Math.cos(v);\r\n            const cy = tube * Math.sin(v);\r\n\r\n            positions.push(p1.x + cx * n.x + cy * bitan.x);\r\n            positions.push(p1.y + cx * n.y + cy * bitan.y);\r\n            positions.push(p1.z + cx * n.z + cy * bitan.z);\r\n\r\n            uvs.push(i / radialSegments);\r\n            uvs.push(useOpenGLOrientationForUV ? 1.0 - j / tubularSegments : j / tubularSegments);\r\n        }\r\n    }\r\n\r\n    for (i = 0; i < radialSegments; i++) {\r\n        for (j = 0; j < tubularSegments; j++) {\r\n            const jNext = (j + 1) % tubularSegments;\r\n            const a = i * tubularSegments + j;\r\n            const b = (i + 1) * tubularSegments + j;\r\n            const c = (i + 1) * tubularSegments + jNext;\r\n            const d = i * tubularSegments + jNext;\r\n\r\n            indices.push(d);\r\n            indices.push(b);\r\n            indices.push(a);\r\n            indices.push(d);\r\n            indices.push(c);\r\n            indices.push(b);\r\n        }\r\n    }\r\n\r\n    // Normals\r\n    VertexData.ComputeNormals(positions, indices, normals);\r\n\r\n    // Sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a torus knot mesh\r\n * * The parameter `radius` sets the global radius size (float) of the torus knot (default 2)\r\n * * The parameter `radialSegments` sets the number of sides on each tube segments (positive integer, default 32)\r\n * * The parameter `tubularSegments` sets the number of tubes to decompose the knot into (positive integer, default 32)\r\n * * The parameters `p` and `q` are the number of windings on each axis (positive integers, default 2 and 3)\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the torus knot mesh\r\n * @see  https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#torus-knot\r\n */\r\nexport function CreateTorusKnot(\r\n    name: string,\r\n    options: {\r\n        radius?: number;\r\n        tube?: number;\r\n        radialSegments?: number;\r\n        tubularSegments?: number;\r\n        p?: number;\r\n        q?: number;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    } = {},\r\n    scene?: Scene\r\n): Mesh {\r\n    const torusKnot = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    torusKnot._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateTorusKnotVertexData(options);\r\n\r\n    vertexData.applyToMesh(torusKnot, options.updatable);\r\n\r\n    return torusKnot;\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateTorusKnot instead\r\n */\r\nexport const TorusKnotBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateTorusKnot,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for torusKnotBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTorusKnotBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateTorusKnot = CreateTorusKnotVertexData;\r\n\r\n    Mesh.CreateTorusKnot = (\r\n        name: string,\r\n        radius: number,\r\n        tube: number,\r\n        radialSegments: number,\r\n        tubularSegments: number,\r\n        p: number,\r\n        q: number,\r\n        scene?: Scene,\r\n        updatable?: boolean,\r\n        sideOrientation?: number\r\n    ): Mesh => {\r\n        const options = {\r\n            radius,\r\n            tube,\r\n            radialSegments,\r\n            tubularSegments,\r\n            p,\r\n            q,\r\n            sideOrientation,\r\n            updatable,\r\n        };\r\n\r\n        return CreateTorusKnot(name, options, scene);\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type IEffectFallbacks } from \"./iEffectFallbacks\";\r\n\r\nimport { type Effect } from \"./effect\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * EffectFallbacks can be used to add fallbacks (properties to disable) to certain properties when desired to improve performance.\r\n * (Eg. Start at high quality with reflection and fog, if fps is low, remove reflection, if still low remove fog)\r\n */\r\nexport class EffectFallbacks implements IEffectFallbacks {\r\n    private _defines: { [key: string]: Array<string> } = {};\r\n\r\n    private _currentRank = 32;\r\n    private _maxRank = -1;\r\n\r\n    private _mesh: Nullable<AbstractMesh> = null;\r\n\r\n    /**\r\n     * Removes the fallback from the bound mesh.\r\n     */\r\n    public unBindMesh() {\r\n        this._mesh = null;\r\n    }\r\n\r\n    /**\r\n     * Adds a fallback on the specified property.\r\n     * @param rank The rank of the fallback (Lower ranks will be fallbacked to first)\r\n     * @param define The name of the define in the shader\r\n     */\r\n    public addFallback(rank: number, define: string): void {\r\n        if (!this._defines[rank]) {\r\n            if (rank < this._currentRank) {\r\n                this._currentRank = rank;\r\n            }\r\n\r\n            if (rank > this._maxRank) {\r\n                this._maxRank = rank;\r\n            }\r\n\r\n            this._defines[rank] = new Array<string>();\r\n        }\r\n\r\n        this._defines[rank].push(define);\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh to use CPU skinning when needing to fallback.\r\n     * @param rank The rank of the fallback (Lower ranks will be fallbacked to first)\r\n     * @param mesh The mesh to use the fallbacks.\r\n     */\r\n    public addCPUSkinningFallback(rank: number, mesh: AbstractMesh) {\r\n        this._mesh = mesh;\r\n\r\n        if (rank < this._currentRank) {\r\n            this._currentRank = rank;\r\n        }\r\n        if (rank > this._maxRank) {\r\n            this._maxRank = rank;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks to see if more fallbacks are still available.\r\n     */\r\n    public get hasMoreFallbacks(): boolean {\r\n        return this._currentRank <= this._maxRank;\r\n    }\r\n\r\n    /**\r\n     * Removes the defines that should be removed when falling back.\r\n     * @param currentDefines defines the current define statements for the shader.\r\n     * @param effect defines the current effect we try to compile\r\n     * @returns The resulting defines with defines of the current rank removed.\r\n     */\r\n    public reduce(currentDefines: string, effect: Effect): string {\r\n        // First we try to switch to CPU skinning\r\n        if (this._mesh && this._mesh.computeBonesUsingShaders && this._mesh.numBoneInfluencers > 0) {\r\n            this._mesh.computeBonesUsingShaders = false;\r\n            currentDefines = currentDefines.replace(\"#define NUM_BONE_INFLUENCERS \" + this._mesh.numBoneInfluencers, \"#define NUM_BONE_INFLUENCERS 0\");\r\n            effect._bonesComputationForcedToCPU = true;\r\n\r\n            const scene = this._mesh.getScene();\r\n            for (let index = 0; index < scene.meshes.length; index++) {\r\n                const otherMesh = scene.meshes[index];\r\n\r\n                if (!otherMesh.material) {\r\n                    if (!this._mesh.material && otherMesh.computeBonesUsingShaders && otherMesh.numBoneInfluencers > 0) {\r\n                        otherMesh.computeBonesUsingShaders = false;\r\n                    }\r\n                    continue;\r\n                }\r\n\r\n                if (!otherMesh.computeBonesUsingShaders || otherMesh.numBoneInfluencers === 0) {\r\n                    continue;\r\n                }\r\n\r\n                if (otherMesh.material.getEffect() === effect) {\r\n                    otherMesh.computeBonesUsingShaders = false;\r\n                } else if (otherMesh.subMeshes) {\r\n                    for (const subMesh of otherMesh.subMeshes) {\r\n                        const subMeshEffect = subMesh.effect;\r\n\r\n                        if (subMeshEffect === effect) {\r\n                            otherMesh.computeBonesUsingShaders = false;\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const currentFallbacks = this._defines[this._currentRank];\r\n            if (currentFallbacks) {\r\n                for (let index = 0; index < currentFallbacks.length; index++) {\r\n                    currentDefines = currentDefines.replace(\"#define \" + currentFallbacks[index], \"\");\r\n                }\r\n            }\r\n\r\n            this._currentRank++;\r\n        }\r\n\r\n        return currentDefines;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\n/**\r\n * Base class of materials working in push mode in babylon JS\r\n * @internal\r\n */\r\nexport class PushMaterial extends Material {\r\n    protected _activeEffect?: Effect;\r\n\r\n    protected _normalMatrix: Matrix = new Matrix();\r\n\r\n    constructor(name: string, scene?: Scene, storeEffectOnSubMeshes = true, forceGLSL = false) {\r\n        super(name, scene, undefined, forceGLSL);\r\n        this._storeEffectOnSubMeshes = storeEffectOnSubMeshes;\r\n    }\r\n\r\n    public override getEffect(): Effect {\r\n        return this._storeEffectOnSubMeshes ? this._activeEffect! : super.getEffect()!;\r\n    }\r\n\r\n    public override isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {\r\n        if (!mesh) {\r\n            return false;\r\n        }\r\n\r\n        if (!this._storeEffectOnSubMeshes) {\r\n            return true;\r\n        }\r\n\r\n        if (!mesh.subMeshes || mesh.subMeshes.length === 0) {\r\n            return true;\r\n        }\r\n\r\n        return this.isReadyForSubMesh(mesh, mesh.subMeshes[0], useInstances);\r\n    }\r\n\r\n    protected _isReadyForSubMesh(subMesh: SubMesh) {\r\n        const defines = subMesh.materialDefines;\r\n        if (!this.checkReadyOnEveryCall && subMesh.effect && defines) {\r\n            if (defines._renderId === this.getScene().getRenderId()) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Binds the given world matrix to the active effect\r\n     *\r\n     * @param world the matrix to bind\r\n     */\r\n    public override bindOnlyWorldMatrix(world: Matrix): void {\r\n        this._activeEffect!.setMatrix(\"world\", world);\r\n    }\r\n\r\n    /**\r\n     * Binds the given normal matrix to the active effect\r\n     *\r\n     * @param normalMatrix the matrix to bind\r\n     */\r\n    public bindOnlyNormalMatrix(normalMatrix: Matrix): void {\r\n        this._activeEffect!.setMatrix(\"normalMatrix\", normalMatrix);\r\n    }\r\n\r\n    public override bind(world: Matrix, mesh?: Mesh): void {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        this.bindForSubMesh(world, mesh, mesh.subMeshes[0]);\r\n    }\r\n\r\n    protected override _afterBind(mesh?: AbstractMesh, effect: Nullable<Effect> = null, subMesh?: SubMesh): void {\r\n        super._afterBind(mesh, effect, subMesh);\r\n        this.getScene()._cachedEffect = effect;\r\n        if (subMesh) {\r\n            subMesh._drawWrapper._forceRebindOnNextCall = false;\r\n        } else {\r\n            this._drawWrapper._forceRebindOnNextCall = false;\r\n        }\r\n    }\r\n\r\n    protected _mustRebind(scene: Scene, effect: Effect, subMesh: SubMesh, visibility = 1): boolean {\r\n        return subMesh._drawWrapper._forceRebindOnNextCall || scene.isCachedMaterialInvalid(this, effect, visibility);\r\n    }\r\n\r\n    /**\r\n     * Disposes the push material resources.\r\n     * @param forceDisposeEffect defines whether to dispose the effect\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     * @param notBoundToMesh defines whether the material is not bound to a mesh\r\n     */\r\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, notBoundToMesh?: boolean) {\r\n        this._activeEffect = undefined;\r\n        super.dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh);\r\n    }\r\n}\r\n","import { type Effect } from \"./effect\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Geometry } from \"../Meshes/geometry\";\r\n\r\n/**\r\n * Interface representing metadata for vertex pulling\r\n */\r\nexport interface IVertexPullingMetadata {\r\n    /**\r\n     * Offset in vertex buffer where data starts\r\n     */\r\n    offset: number;\r\n\r\n    /**\r\n     * Stride between elements in the vertex buffer\r\n     */\r\n    stride: number;\r\n\r\n    /**\r\n     * Type of the vertex buffer (e.g., float, int)\r\n     */\r\n    type: number; // VertexBuffer type constant\r\n\r\n    /**\r\n     * Whether integer data should be normalized when read\r\n     */\r\n    normalized: boolean;\r\n}\r\n\r\n// Store vertex pulling metadata per geometry\r\nconst _VertexPullingMetadataCache = new WeakMap<Geometry, Map<string, IVertexPullingMetadata>>();\r\n\r\n/**\r\n * Prepares vertex pulling uniforms for the given attributes and mesh\r\n * @param geometry The geometry containing the vertex buffers\r\n * @returns A map of attribute names to their metadata, or null if unavailable\r\n */\r\nexport function PrepareVertexPullingUniforms(geometry: Geometry): Nullable<Map<string, IVertexPullingMetadata>> {\r\n    const vertexBuffers = geometry.getVertexBuffers();\r\n    if (!vertexBuffers) {\r\n        return null;\r\n    }\r\n\r\n    // Check cache first\r\n    let metadata = _VertexPullingMetadataCache.get(geometry);\r\n    if (!metadata) {\r\n        metadata = new Map<string, IVertexPullingMetadata>();\r\n        _VertexPullingMetadataCache.set(geometry, metadata);\r\n    } else {\r\n        // Return cached metadata if it exists and hasn't changed\r\n        let needsUpdate = false;\r\n        for (const vb in vertexBuffers) {\r\n            if (!metadata.has(vb)) {\r\n                needsUpdate = true;\r\n                break;\r\n            }\r\n        }\r\n        if (!needsUpdate) {\r\n            return metadata;\r\n        }\r\n    }\r\n\r\n    // Build or update metadata\r\n    for (const vb in vertexBuffers) {\r\n        const vertexBuffer = vertexBuffers[vb];\r\n        if (vertexBuffer) {\r\n            const offset = vertexBuffer.byteOffset;\r\n            const stride = vertexBuffer.byteStride;\r\n            const type = vertexBuffer.type;\r\n            const normalized = vertexBuffer.normalized;\r\n\r\n            metadata.set(vb, {\r\n                offset: offset,\r\n                stride: stride,\r\n                type: type,\r\n                normalized: normalized,\r\n            });\r\n        }\r\n    }\r\n\r\n    return metadata;\r\n}\r\n\r\n/**\r\n * Bind vertex pulling uniforms to the effect\r\n * @param effect The effect to bind the uniforms to\r\n * @param metadata The vertex pulling metadata\r\n */\r\nexport function BindVertexPullingUniforms(effect: Effect, metadata: Map<string, IVertexPullingMetadata>): void {\r\n    metadata.forEach((data, attribute) => {\r\n        const uniformName = `vp_${attribute}_info`;\r\n        // Pack into vec4: (offset, stride, type, normalized)\r\n        effect.setFloat4(uniformName, data.offset, data.stride, data.type, data.normalized ? 1 : 0);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\nimport { type Nullable } from \"../types\";\nimport { Scene } from \"../scene.pure\";\nimport { Matrix, Quaternion } from \"../Maths/math.vector.pure\";\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\nimport { type Mesh } from \"../Meshes/mesh.pure\";\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\nimport { Texture } from \"../Materials/Textures/texture.pure\";\nimport { type Effect, type IEffectCreationOptions, type IShaderPath } from \"./effect.pure\";\nimport { EffectFallbacks } from \"./effectFallbacks\";\nimport { WebRequest } from \"../Misc/webRequest\";\nimport { type ShaderLanguage } from \"./shaderLanguage\";\nimport { type UniformBuffer } from \"./uniformBuffer\";\nimport { type TextureSampler } from \"./Textures/textureSampler\";\nimport { type StorageBuffer } from \"../Buffers/storageBuffer\";\nimport { PushMaterial } from \"./pushMaterial\";\nimport { EngineStore } from \"../Engines/engineStore\";\nimport { Constants } from \"../Engines/constants\";\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"./clipPlaneMaterialHelper\";\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine.pure\";\n\nimport { type ExternalTexture } from \"./Textures/externalTexture\";\nimport {\n    BindBonesParameters,\n    BindFogParameters,\n    BindLogDepth,\n    BindMorphTargetParameters,\n    BindSceneUniformBuffer,\n    PrepareDefinesAndAttributesForMorphTargets,\n    PushAttributesForInstances,\n} from \"./materialHelper.functions\";\nimport { type IColor3Like, type IColor4Like, type IVector2Like, type IVector3Like, type IVector4Like } from \"core/Maths/math.like\";\nimport { type InternalTexture } from \"./Textures/internalTexture\";\n\nimport { PrepareVertexPullingUniforms, BindVertexPullingUniforms, type IVertexPullingMetadata } from \"./vertexPullingHelper.functions\";\nimport { RegisterClass } from \"../Misc/typeStore\";\n\nconst OnCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };\n\ninterface IShaderMaterialMatrixArrayAccess {\n    _matrixArrays: { [name: string]: Float32Array | Array<number> };\n}\n\n/**\n * Defines the options associated with the creation of a shader material.\n */\nexport interface IShaderMaterialOptions {\n    /**\n     * Does the material work in alpha blend mode\n     */\n    needAlphaBlending: boolean;\n\n    /**\n     * Does the material work in alpha test mode\n     */\n    needAlphaTesting: boolean;\n\n    /**\n     * The list of attribute names used in the shader\n     */\n    attributes: string[];\n\n    /**\n     * The list of uniform names used in the shader\n     */\n    uniforms: string[];\n\n    /**\n     * The list of UBO names used in the shader\n     */\n    uniformBuffers: string[];\n\n    /**\n     * The list of sampler (texture) names used in the shader\n     */\n    samplers: string[];\n\n    /**\n     * The list of external texture names used in the shader\n     */\n    externalTextures: string[];\n\n    /**\n     * The list of sampler object names used in the shader\n     */\n    samplerObjects: string[];\n\n    /**\n     * The list of storage buffer names used in the shader\n     */\n    storageBuffers: string[];\n\n    /**\n     * The list of defines used in the shader\n     */\n    defines: string[];\n\n    /**\n     * Defines if clip planes have to be turned on: true to turn them on, false to turn them off and null to turn them on/off depending on the scene configuration (scene.clipPlaneX)\n     */\n    useClipPlane: Nullable<boolean>;\n\n    /**\n     * The language the shader is written in (default: GLSL)\n     */\n    shaderLanguage?: ShaderLanguage;\n\n    /**\n     * Defines additional code to call to prepare the shader code\n     */\n    extraInitializationsAsync?: () => Promise<void>;\n}\n\n/**\n * The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh.\n *\n * This returned material effects how the mesh will look based on the code in the shaders.\n *\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/shaders/shaderMaterial\n */\nexport class ShaderMaterial extends PushMaterial {\n    private _shaderPath: IShaderPath | string;\n    private _options: IShaderMaterialOptions;\n    private _textures: { [name: string]: BaseTexture } = {};\n    private _internalTextures: { [name: string]: InternalTexture } = {};\n    private _textureArrays: { [name: string]: BaseTexture[] } = {};\n    private _externalTextures: { [name: string]: ExternalTexture } = {};\n    private _floats: { [name: string]: number } = {};\n    private _ints: { [name: string]: number } = {};\n    private _uints: { [name: string]: number } = {};\n    private _floatsArrays: { [name: string]: number[] } = {};\n    private _colors3: { [name: string]: IColor3Like } = {};\n    private _colors3Arrays: { [name: string]: number[] } = {};\n    private _colors4: { [name: string]: IColor4Like } = {};\n    private _colors4Arrays: { [name: string]: number[] } = {};\n    private _vectors2: { [name: string]: IVector2Like } = {};\n    private _vectors3: { [name: string]: IVector3Like } = {};\n    private _vectors4: { [name: string]: IVector4Like } = {};\n    private _quaternions: { [name: string]: Quaternion } = {};\n    private _quaternionsArrays: { [name: string]: number[] } = {};\n    private _matrices: { [name: string]: Matrix } = {};\n    private _matrixArrays: { [name: string]: Float32Array | Array<number> } = {};\n    private _matrices3x3: { [name: string]: Float32Array | Array<number> } = {};\n    private _matrices2x2: { [name: string]: Float32Array | Array<number> } = {};\n    private _vectors2Arrays: { [name: string]: number[] } = {};\n    private _vectors3Arrays: { [name: string]: number[] } = {};\n    private _vectors4Arrays: { [name: string]: number[] } = {};\n    private _uniformBuffers: { [name: string]: UniformBuffer } = {};\n    private _textureSamplers: { [name: string]: TextureSampler } = {};\n    private _storageBuffers: { [name: string]: StorageBuffer } = {};\n    private _cachedWorldViewMatrix = new Matrix();\n    private _cachedWorldViewProjectionMatrix = new Matrix();\n    private _multiview = false;\n    private _vertexPullingMetadata: Map<string, IVertexPullingMetadata> | null = null;\n\n    /**\n     * @internal\n     */\n    public _materialHelperNeedsPreviousMatrices = false;\n\n    /** Define the Url to load snippets */\n    public static SnippetUrl = Constants.SnippetUrl;\n\n    /** Snippet ID if the material was created from the snippet server */\n    public snippetId: string;\n\n    /**\n     * Instantiate a new shader material.\n     * The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh.\n     * This returned material effects how the mesh will look based on the code in the shaders.\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/shaders/shaderMaterial\n     * @param name Define the name of the material in the scene\n     * @param scene Define the scene the material belongs to\n     * @param shaderPath Defines  the route to the shader code.\n     * @param options Define the options used to create the shader\n     * @param storeEffectOnSubMeshes true to store effect on submeshes, false to store the effect directly in the material class.\n     */\n    constructor(name: string, scene: Scene, shaderPath: IShaderPath | string, options: Partial<IShaderMaterialOptions> = {}, storeEffectOnSubMeshes = true) {\n        super(name, scene, storeEffectOnSubMeshes);\n        this._shaderPath = shaderPath;\n\n        this._options = {\n            needAlphaBlending: false,\n            needAlphaTesting: false,\n            attributes: [\"position\", \"normal\", \"uv\"],\n            uniforms: [\"worldViewProjection\"],\n            uniformBuffers: [],\n            samplers: [],\n            externalTextures: [],\n            samplerObjects: [],\n            storageBuffers: [],\n            defines: [],\n            useClipPlane: false,\n            ...options,\n        };\n    }\n\n    /**\n     * Gets the shader path used to define the shader code\n     * It can be modified to trigger a new compilation\n     */\n    public get shaderPath() {\n        return this._shaderPath;\n    }\n\n    /**\n     * Sets the shader path used to define the shader code\n     * It can be modified to trigger a new compilation\n     */\n    public set shaderPath(shaderPath: IShaderPath | string) {\n        this._shaderPath = shaderPath;\n    }\n\n    /**\n     * Gets the options used to compile the shader.\n     * They can be modified to trigger a new compilation\n     */\n    public get options(): IShaderMaterialOptions {\n        return this._options;\n    }\n\n    /**\n     * is multiview set to true?\n     */\n    public get isMultiview(): boolean {\n        return this._multiview;\n    }\n\n    /**\n     * Gets the current class name of the material e.g. \"ShaderMaterial\"\n     * Mainly use in serialization.\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return \"ShaderMaterial\";\n    }\n\n    /**\n     * Specifies if the material will require alpha blending\n     * @returns a boolean specifying if alpha blending is needed\n     */\n    public override needAlphaBlending(): boolean {\n        return this.alpha < 1.0 || this._options.needAlphaBlending;\n    }\n\n    /**\n     * Specifies if this material should be rendered in alpha test mode\n     * @returns a boolean specifying if an alpha test is needed.\n     */\n    public override needAlphaTesting(): boolean {\n        return this._options.needAlphaTesting;\n    }\n\n    private _checkUniform(uniformName: string): void {\n        if (this._options.uniforms.indexOf(uniformName) === -1) {\n            this._options.uniforms.push(uniformName);\n        }\n    }\n\n    /**\n     * Set a texture in the shader.\n     * @param name Define the name of the uniform samplers as defined in the shader\n     * @param texture Define the texture to bind to this sampler\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setTexture(name: string, texture: BaseTexture): ShaderMaterial {\n        if (this._options.samplers.indexOf(name) === -1) {\n            this._options.samplers.push(name);\n        }\n        this._textures[name] = texture;\n\n        return this;\n    }\n\n    /**\n     * Set an internal texture in the shader.\n     * @param name Define the name of the uniform samplers as defined in the shader\n     * @param texture Define the texture to bind to this sampler\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setInternalTexture(name: string, texture: InternalTexture): ShaderMaterial {\n        if (this._options.samplers.indexOf(name) === -1) {\n            this._options.samplers.push(name);\n        }\n        this._internalTextures[name] = texture;\n\n        return this;\n    }\n\n    /**\n     * Remove a texture from the material.\n     * @param name Define the name of the texture to remove\n     */\n    public removeTexture(name: string): void {\n        delete this._textures[name];\n    }\n\n    /**\n     * Set a texture array in the shader.\n     * @param name Define the name of the uniform sampler array as defined in the shader\n     * @param textures Define the list of textures to bind to this sampler\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setTextureArray(name: string, textures: BaseTexture[]): ShaderMaterial {\n        if (this._options.samplers.indexOf(name) === -1) {\n            this._options.samplers.push(name);\n        }\n\n        this._checkUniform(name);\n\n        this._textureArrays[name] = textures;\n\n        return this;\n    }\n\n    /**\n     * Set an internal texture in the shader.\n     * @param name Define the name of the uniform samplers as defined in the shader\n     * @param texture Define the texture to bind to this sampler\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setExternalTexture(name: string, texture: ExternalTexture): ShaderMaterial {\n        if (this._options.externalTextures.indexOf(name) === -1) {\n            this._options.externalTextures.push(name);\n        }\n        this._externalTextures[name] = texture;\n\n        return this;\n    }\n\n    /**\n     * Set a float in the shader.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setFloat(name: string, value: number): ShaderMaterial {\n        this._checkUniform(name);\n        this._floats[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a int in the shader.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setInt(name: string, value: number): ShaderMaterial {\n        this._checkUniform(name);\n        this._ints[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a unsigned int in the shader.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setUInt(name: string, value: number): ShaderMaterial {\n        this._checkUniform(name);\n        this._uints[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set an array of floats in the shader.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setFloats(name: string, value: number[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._floatsArrays[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec3 in the shader from a Color3.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setColor3(name: string, value: IColor3Like): ShaderMaterial {\n        this._checkUniform(name);\n        this._colors3[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec3 array in the shader from a IColor3Like array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setColor3Array(name: string, value: IColor3Like[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._colors3Arrays[name] = value.reduce((arr: number[], color) => {\n            arr.push(color.r, color.g, color.b);\n            return arr;\n        }, []);\n        return this;\n    }\n\n    /**\n     * Set a vec4 in the shader from a Color4.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setColor4(name: string, value: IColor4Like): ShaderMaterial {\n        this._checkUniform(name);\n        this._colors4[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec4 array in the shader from a IColor4Like array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setColor4Array(name: string, value: IColor4Like[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._colors4Arrays[name] = value.reduce((arr: number[], color) => {\n            arr.push(color.r, color.g, color.b, color.a);\n            return arr;\n        }, []);\n        return this;\n    }\n\n    /**\n     * Set a vec2 in the shader from a Vector2.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setVector2(name: string, value: IVector2Like): ShaderMaterial {\n        this._checkUniform(name);\n        this._vectors2[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec3 in the shader from a Vector3.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setVector3(name: string, value: IVector3Like): ShaderMaterial {\n        this._checkUniform(name);\n        this._vectors3[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec4 in the shader from a Vector4.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setVector4(name: string, value: IVector4Like): ShaderMaterial {\n        this._checkUniform(name);\n        this._vectors4[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec4 in the shader from a Quaternion.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setQuaternion(name: string, value: Quaternion): ShaderMaterial {\n        this._checkUniform(name);\n        this._quaternions[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec4 array in the shader from a Quaternion array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setQuaternionArray(name: string, value: Quaternion[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._quaternionsArrays[name] = value.reduce((arr, quaternion) => {\n            quaternion.toArray(arr, arr.length);\n            return arr;\n        }, []);\n        return this;\n    }\n\n    /**\n     * Set a mat4 in the shader from a Matrix.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setMatrix(name: string, value: Matrix): ShaderMaterial {\n        this._checkUniform(name);\n        this._matrices[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a float32Array in the shader from a matrix array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setMatrices(name: string, value: Matrix[]): ShaderMaterial {\n        this._checkUniform(name);\n\n        const float32Array = new Float32Array(value.length * 16);\n\n        for (let index = 0; index < value.length; index++) {\n            const matrix = value[index];\n\n            matrix.copyToArray(float32Array, index * 16);\n        }\n\n        this._matrixArrays[name] = float32Array;\n\n        return this;\n    }\n\n    /**\n     * Set a mat3 in the shader from a Float32Array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setMatrix3x3(name: string, value: Float32Array | Array<number>): ShaderMaterial {\n        this._checkUniform(name);\n        this._matrices3x3[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a mat2 in the shader from a Float32Array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setMatrix2x2(name: string, value: Float32Array | Array<number>): ShaderMaterial {\n        this._checkUniform(name);\n        this._matrices2x2[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec2 array in the shader from a number array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setArray2(name: string, value: number[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._vectors2Arrays[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec3 array in the shader from a number array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setArray3(name: string, value: number[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._vectors3Arrays[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a vec4 array in the shader from a number array.\n     * @param name Define the name of the uniform as defined in the shader\n     * @param value Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setArray4(name: string, value: number[]): ShaderMaterial {\n        this._checkUniform(name);\n        this._vectors4Arrays[name] = value;\n\n        return this;\n    }\n\n    /**\n     * Set a uniform buffer in the shader\n     * @param name Define the name of the uniform as defined in the shader\n     * @param buffer Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setUniformBuffer(name: string, buffer: UniformBuffer): ShaderMaterial {\n        if (this._options.uniformBuffers.indexOf(name) === -1) {\n            this._options.uniformBuffers.push(name);\n        }\n        this._uniformBuffers[name] = buffer;\n\n        return this;\n    }\n\n    /**\n     * Set a texture sampler in the shader\n     * @param name Define the name of the uniform as defined in the shader\n     * @param sampler Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setTextureSampler(name: string, sampler: TextureSampler): ShaderMaterial {\n        if (this._options.samplerObjects.indexOf(name) === -1) {\n            this._options.samplerObjects.push(name);\n        }\n        this._textureSamplers[name] = sampler;\n\n        return this;\n    }\n\n    /**\n     * Set a storage buffer in the shader\n     * @param name Define the name of the storage buffer as defined in the shader\n     * @param buffer Define the value to give to the uniform\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setStorageBuffer(name: string, buffer: StorageBuffer): ShaderMaterial {\n        if (this._options.storageBuffers.indexOf(name) === -1) {\n            this._options.storageBuffers.push(name);\n        }\n        this._storageBuffers[name] = buffer;\n\n        return this;\n    }\n\n    /**\n     * Adds, removes, or replaces the specified shader define and value.\n     * * setDefine(\"MY_DEFINE\", true); // enables a boolean define\n     * * setDefine(\"MY_DEFINE\", \"0.5\"); // adds \"#define MY_DEFINE 0.5\" to the shader (or sets and replaces the value of any existing define with that name)\n     * * setDefine(\"MY_DEFINE\", false); // disables and removes the define\n     * Note if the active defines do change, the shader will be recompiled and this can be expensive.\n     * @param define the define name e.g., \"OUTPUT_TO_SRGB\" or \"#define OUTPUT_TO_SRGB\". If the define was passed into the constructor already, the version used should match that, and in either case, it should not include any appended value.\n     * @param value either the value of the define (e.g. a numerical value) or for booleans, true if the define should be enabled or false if it should be disabled\n     * @returns the material itself allowing \"fluent\" like uniform updates\n     */\n    public setDefine(define: string, value: boolean | string): ShaderMaterial {\n        // First remove any existing define with this name.\n        const defineName = define.trimEnd() + \" \";\n        const existingDefineIdx = this.options.defines.findIndex((x) => x === define || x.startsWith(defineName));\n        if (existingDefineIdx >= 0) {\n            this.options.defines.splice(existingDefineIdx, 1);\n        }\n\n        // Then add the new define value. (If it's a boolean value and false, don't add it.)\n        if (typeof value !== \"boolean\" || value) {\n            this.options.defines.push(defineName + value);\n        }\n\n        return this;\n    }\n\n    /**\n     * Specifies that the submesh is ready to be used\n     * @param mesh defines the mesh to check\n     * @param subMesh defines which submesh to check\n     * @param useInstances specifies that instances should be used\n     * @returns a boolean indicating that the submesh is ready or not\n     */\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {\n        return this.isReady(mesh, useInstances, subMesh);\n    }\n\n    /**\n     * Checks if the material is ready to render the requested mesh\n     * @param mesh Define the mesh to render\n     * @param useInstances Define whether or not the material is used with instances\n     * @param subMesh defines which submesh to render\n     * @returns true if ready, otherwise false\n     */\n    public override isReady(mesh?: AbstractMesh, useInstances?: boolean, subMesh?: SubMesh): boolean {\n        const storeEffectOnSubMeshes = subMesh && this._storeEffectOnSubMeshes;\n\n        if (this.isFrozen) {\n            const drawWrapper = storeEffectOnSubMeshes ? subMesh._drawWrapper : this._drawWrapper;\n            if (drawWrapper.effect && drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\n                return true;\n            }\n        }\n\n        const scene = this.getScene();\n        const engine = scene.getEngine();\n\n        // Instances\n        const defines = [];\n        const attribs = [];\n        let fallbacks: Nullable<EffectFallbacks> = null;\n\n        let shaderName = this._shaderPath,\n            uniforms = this._options.uniforms,\n            uniformBuffers = this._options.uniformBuffers,\n            samplers = this._options.samplers;\n\n        // global multiview\n        if (engine.getCaps().multiview && scene.activeCamera && scene.activeCamera.outputRenderTarget && scene.activeCamera.outputRenderTarget.getViewCount() > 1) {\n            this._multiview = true;\n            defines.push(\"#define MULTIVIEW\");\n            if (uniforms.indexOf(\"viewProjection\") !== -1 && uniforms.indexOf(\"viewProjectionR\") === -1) {\n                uniforms.push(\"viewProjectionR\");\n            }\n        }\n\n        for (let index = 0; index < this._options.defines.length; index++) {\n            const defineToAdd = this._options.defines[index].indexOf(\"#define\") === 0 ? this._options.defines[index] : `#define ${this._options.defines[index]}`;\n            defines.push(defineToAdd);\n        }\n\n        for (let index = 0; index < this._options.attributes.length; index++) {\n            attribs.push(this._options.attributes[index]);\n        }\n\n        if (mesh && mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {\n            if (attribs.indexOf(VertexBuffer.ColorKind) === -1) {\n                attribs.push(VertexBuffer.ColorKind);\n            }\n            defines.push(\"#define VERTEXCOLOR\");\n        }\n\n        if (useInstances) {\n            defines.push(\"#define INSTANCES\");\n            PushAttributesForInstances(attribs, this._materialHelperNeedsPreviousMatrices);\n            if (mesh?.hasThinInstances) {\n                defines.push(\"#define THIN_INSTANCES\");\n                if (mesh && mesh.isVerticesDataPresent(VertexBuffer.ColorInstanceKind)) {\n                    attribs.push(VertexBuffer.ColorInstanceKind);\n                    defines.push(\"#define INSTANCESCOLOR\");\n                }\n            }\n        }\n\n        // Bones\n        if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\n            attribs.push(VertexBuffer.MatricesIndicesKind);\n            attribs.push(VertexBuffer.MatricesWeightsKind);\n            if (mesh.numBoneInfluencers > 4) {\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\n            }\n\n            const skeleton = mesh.skeleton;\n\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\n            fallbacks = new EffectFallbacks();\n            fallbacks.addCPUSkinningFallback(0, mesh);\n\n            if (skeleton.isUsingTextureForMatrices) {\n                defines.push(\"#define BONETEXTURE\");\n\n                if (uniforms.indexOf(\"boneTextureInfo\") === -1) {\n                    uniforms.push(\"boneTextureInfo\");\n                }\n\n                if (this._options.samplers.indexOf(\"boneSampler\") === -1) {\n                    this._options.samplers.push(\"boneSampler\");\n                }\n            } else {\n                defines.push(\"#define BonesPerMesh \" + (skeleton.bones.length + 1));\n\n                if (uniforms.indexOf(\"mBones\") === -1) {\n                    uniforms.push(\"mBones\");\n                }\n            }\n        } else {\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\n        }\n\n        // Morph\n        let numInfluencers = 0;\n        const manager = mesh ? (<Mesh>mesh).morphTargetManager : null;\n        if (manager) {\n            const uv = defines.indexOf(\"#define UV1\") !== -1;\n            const uv2 = defines.indexOf(\"#define UV2\") !== -1;\n            const tangent = defines.indexOf(\"#define TANGENT\") !== -1;\n            const normal = defines.indexOf(\"#define NORMAL\") !== -1;\n            const color = defines.indexOf(\"#define VERTEXCOLOR\") !== -1;\n            numInfluencers = PrepareDefinesAndAttributesForMorphTargets(\n                manager,\n                defines,\n                attribs,\n                mesh!,\n                true, // usePositionMorph\n                normal, // useNormalMorph\n                tangent, // useTangentMorph\n                uv, // useUVMorph\n                uv2, // useUV2Morph\n                color // useColorMorph\n            );\n            if (manager.isUsingTextureForTargets) {\n                if (uniforms.indexOf(\"morphTargetTextureIndices\") === -1) {\n                    uniforms.push(\"morphTargetTextureIndices\");\n                }\n\n                if (this._options.samplers.indexOf(\"morphTargets\") === -1) {\n                    this._options.samplers.push(\"morphTargets\");\n                }\n            }\n            if (numInfluencers > 0) {\n                uniforms = uniforms.slice();\n                uniforms.push(\"morphTargetInfluences\");\n                uniforms.push(\"morphTargetCount\");\n                uniforms.push(\"morphTargetTextureInfo\");\n                uniforms.push(\"morphTargetTextureIndices\");\n            }\n        } else {\n            defines.push(\"#define NUM_MORPH_INFLUENCERS 0\");\n        }\n\n        // Baked Vertex Animation\n        if (mesh) {\n            const bvaManager = (<AbstractMesh>mesh).bakedVertexAnimationManager;\n\n            if (bvaManager && bvaManager.isEnabled) {\n                defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\n                if (uniforms.indexOf(\"bakedVertexAnimationSettings\") === -1) {\n                    uniforms.push(\"bakedVertexAnimationSettings\");\n                }\n                if (uniforms.indexOf(\"bakedVertexAnimationTextureSizeInverted\") === -1) {\n                    uniforms.push(\"bakedVertexAnimationTextureSizeInverted\");\n                }\n                if (uniforms.indexOf(\"bakedVertexAnimationTime\") === -1) {\n                    uniforms.push(\"bakedVertexAnimationTime\");\n                }\n\n                if (this._options.samplers.indexOf(\"bakedVertexAnimationTexture\") === -1) {\n                    this._options.samplers.push(\"bakedVertexAnimationTexture\");\n                }\n\n                if (useInstances) {\n                    attribs.push(\"bakedVertexAnimationSettingsInstanced\");\n                }\n            }\n        }\n\n        // Textures\n        for (const name in this._textures) {\n            if (!this._textures[name].isReady()) {\n                return false;\n            }\n        }\n\n        for (const name in this._internalTextures) {\n            if (!this._internalTextures[name].isReady) {\n                return false;\n            }\n        }\n\n        // Alpha test\n        if (mesh && this.needAlphaTestingForMesh(mesh)) {\n            defines.push(\"#define ALPHATEST\");\n        }\n\n        // Clip planes\n        if (this._options.useClipPlane !== false) {\n            AddClipPlaneUniforms(uniforms);\n\n            PrepareStringDefinesForClipPlanes(this, scene, defines);\n        }\n\n        // Fog\n        if (scene.fogEnabled && mesh?.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {\n            defines.push(\"#define FOG\");\n            if (uniforms.indexOf(\"view\") === -1) {\n                uniforms.push(\"view\");\n            }\n            if (uniforms.indexOf(\"vFogInfos\") === -1) {\n                uniforms.push(\"vFogInfos\");\n            }\n            if (uniforms.indexOf(\"vFogColor\") === -1) {\n                uniforms.push(\"vFogColor\");\n            }\n        }\n\n        // Misc\n        if (this._useLogarithmicDepth) {\n            defines.push(\"#define LOGARITHMICDEPTH\");\n            if (uniforms.indexOf(\"logarithmicDepthConstant\") === -1) {\n                uniforms.push(\"logarithmicDepthConstant\");\n            }\n        }\n\n        const renderingMesh = subMesh ? subMesh.getRenderingMesh() : mesh;\n        if (renderingMesh && this.useVertexPulling) {\n            // Add vertex buffer metadata defines for proper stride/offset handling\n            const geometry = renderingMesh.geometry;\n            if (geometry) {\n                this._vertexPullingMetadata = PrepareVertexPullingUniforms(geometry);\n                if (this._vertexPullingMetadata) {\n                    this._vertexPullingMetadata.forEach((_, attribute) => {\n                        uniforms.push(`vp_${attribute}_info`);\n                    });\n                }\n            }\n\n            defines.push(\"#define USE_VERTEX_PULLING\");\n\n            const indexBuffer = renderingMesh.geometry?.getIndexBuffer();\n            if (indexBuffer && !(renderingMesh as Mesh).isUnIndexed) {\n                defines.push(\"#define VERTEX_PULLING_USE_INDEX_BUFFER\");\n                if (indexBuffer.is32Bits) {\n                    defines.push(\"#define VERTEX_PULLING_INDEX_BUFFER_32BITS\");\n                }\n            }\n        }\n\n        if (this.customShaderNameResolve) {\n            uniforms = uniforms.slice();\n            uniformBuffers = uniformBuffers.slice();\n            samplers = samplers.slice();\n            shaderName = this.customShaderNameResolve(this.name, uniforms, uniformBuffers, samplers, defines, attribs);\n        }\n\n        const drawWrapper = storeEffectOnSubMeshes ? subMesh._getDrawWrapper(undefined, true) : this._drawWrapper;\n        const previousEffect = drawWrapper?.effect ?? null;\n        const previousDefines = drawWrapper?.defines ?? null;\n        const join = defines.join(\"\\n\");\n\n        let effect = previousEffect;\n        if (previousDefines !== join) {\n            effect = engine.createEffect(\n                shaderName,\n                <IEffectCreationOptions>{\n                    attributes: attribs,\n                    uniformsNames: uniforms,\n                    uniformBuffersNames: uniformBuffers,\n                    samplers: samplers,\n                    defines: join,\n                    fallbacks: fallbacks,\n                    onCompiled: this.onCompiled,\n                    onError: this.onError,\n                    indexParameters: { maxSimultaneousMorphTargets: numInfluencers },\n                    shaderLanguage: this._options.shaderLanguage,\n                    extraInitializationsAsync: this._options.extraInitializationsAsync,\n                },\n                engine\n            );\n\n            if (storeEffectOnSubMeshes) {\n                subMesh.setEffect(effect, join, this._materialContext);\n            } else if (drawWrapper) {\n                drawWrapper.setEffect(effect, join);\n            }\n\n            if (this._onEffectCreatedObservable) {\n                OnCreatedEffectParameters.effect = effect;\n                OnCreatedEffectParameters.subMesh = subMesh ?? mesh?.subMeshes[0] ?? null;\n                this._onEffectCreatedObservable.notifyObservers(OnCreatedEffectParameters);\n            }\n        }\n\n        drawWrapper!._wasPreviouslyUsingInstances = !!useInstances;\n\n        if (!effect?.isReady()) {\n            return false;\n        }\n\n        if (previousEffect !== effect) {\n            scene.resetCachedMaterial();\n        }\n\n        drawWrapper!._wasPreviouslyReady = true;\n\n        return true;\n    }\n\n    /**\n     * Binds the world matrix to the material\n     * @param world defines the world transformation matrix\n     * @param effectOverride - If provided, use this effect instead of internal effect\n     */\n    public override bindOnlyWorldMatrix(world: Matrix, effectOverride?: Nullable<Effect>): void {\n        const effect = effectOverride ?? this.getEffect();\n        if (!effect) {\n            return;\n        }\n\n        const uniforms = this._options.uniforms;\n        if (uniforms.indexOf(\"world\") !== -1) {\n            effect.setMatrix(\"world\", world);\n        }\n\n        const scene = this.getScene();\n        if (uniforms.indexOf(\"worldView\") !== -1) {\n            world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);\n            effect.setMatrix(\"worldView\", this._cachedWorldViewMatrix);\n        }\n\n        if (uniforms.indexOf(\"worldViewProjection\") !== -1) {\n            world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);\n            effect.setMatrix(\"worldViewProjection\", this._cachedWorldViewProjectionMatrix);\n        }\n\n        if (uniforms.indexOf(\"view\") !== -1) {\n            effect.setMatrix(\"view\", scene.getViewMatrix());\n        }\n    }\n\n    /**\n     * Binds the submesh to this material by preparing the effect and shader to draw\n     * @param world defines the world transformation matrix\n     * @param mesh defines the mesh containing the submesh\n     * @param subMesh defines the submesh to bind the material to\n     */\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\n        this.bind(world, mesh, subMesh._drawWrapperOverride?.effect, subMesh);\n    }\n\n    /**\n     * Binds the material to the mesh\n     * @param world defines the world transformation matrix\n     * @param mesh defines the mesh to bind the material to\n     * @param effectOverride - If provided, use this effect instead of internal effect\n     * @param subMesh defines the submesh to bind the material to\n     */\n    public override bind(world: Matrix, mesh?: AbstractMesh, effectOverride?: Nullable<Effect>, subMesh?: SubMesh): void {\n        // Std values\n        const storeEffectOnSubMeshes = subMesh && this._storeEffectOnSubMeshes;\n        const effect = effectOverride ?? (storeEffectOnSubMeshes ? subMesh.effect : this.getEffect());\n\n        if (!effect) {\n            return;\n        }\n\n        const scene = this.getScene();\n\n        this._activeEffect = effect;\n\n        this.bindOnlyWorldMatrix(world, effectOverride);\n\n        const uniformBuffers = this._options.uniformBuffers;\n\n        let useSceneUBO = false;\n\n        if (effect && uniformBuffers && uniformBuffers.length > 0 && scene.getEngine().supportsUniformBuffers) {\n            for (let i = 0; i < uniformBuffers.length; ++i) {\n                const bufferName = uniformBuffers[i];\n                switch (bufferName) {\n                    case \"Mesh\":\n                        if (mesh) {\n                            mesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\n                            mesh.transferToEffect(world);\n                        }\n                        break;\n                    case \"Scene\":\n                        BindSceneUniformBuffer(effect, scene.getSceneUniformBuffer());\n                        scene.finalizeSceneUbo();\n                        useSceneUBO = true;\n                        break;\n                }\n            }\n        }\n\n        const mustRebind = mesh && storeEffectOnSubMeshes ? this._mustRebind(scene, effect, subMesh, mesh.visibility) : scene.getCachedMaterial() !== this;\n\n        if (effect && mustRebind) {\n            if (!useSceneUBO && this._options.uniforms.indexOf(\"view\") !== -1) {\n                effect.setMatrix(\"view\", scene.getViewMatrix());\n            }\n\n            if (!useSceneUBO && this._options.uniforms.indexOf(\"projection\") !== -1) {\n                effect.setMatrix(\"projection\", scene.getProjectionMatrix());\n            }\n\n            if (!useSceneUBO && this._options.uniforms.indexOf(\"viewProjection\") !== -1) {\n                effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\n                if (this._multiview) {\n                    effect.setMatrix(\"viewProjectionR\", scene._transformMatrixR);\n                }\n            }\n\n            if (scene.activeCamera && this._options.uniforms.indexOf(\"cameraPosition\") !== -1) {\n                effect.setVector3(\"cameraPosition\", scene.activeCamera.globalPosition);\n            }\n\n            // Bones\n            BindBonesParameters(mesh, effect);\n\n            // Clip plane\n            BindClipPlane(effect, this, scene);\n\n            if (this._vertexPullingMetadata) {\n                BindVertexPullingUniforms(effect, this._vertexPullingMetadata);\n            }\n\n            // Misc\n            if (this._useLogarithmicDepth) {\n                BindLogDepth(storeEffectOnSubMeshes ? subMesh.materialDefines : effect.defines, effect, scene);\n            }\n\n            // Fog\n            if (mesh) {\n                BindFogParameters(scene, mesh, effect);\n            }\n\n            let name: string;\n            // Texture\n            for (name in this._textures) {\n                effect.setTexture(name, this._textures[name]);\n            }\n\n            for (name in this._internalTextures) {\n                effect._bindTexture(name, this._internalTextures[name]);\n            }\n\n            // Texture arrays\n            for (name in this._textureArrays) {\n                effect.setTextureArray(name, this._textureArrays[name]);\n            }\n\n            // Int\n            for (name in this._ints) {\n                effect.setInt(name, this._ints[name]);\n            }\n\n            // UInt\n            for (name in this._uints) {\n                effect.setUInt(name, this._uints[name]);\n            }\n\n            // Float\n            for (name in this._floats) {\n                effect.setFloat(name, this._floats[name]);\n            }\n\n            // Floats\n            for (name in this._floatsArrays) {\n                effect.setArray(name, this._floatsArrays[name]);\n            }\n\n            // Color3\n            for (name in this._colors3) {\n                effect.setColor3(name, this._colors3[name]);\n            }\n\n            // Color3Array\n            for (name in this._colors3Arrays) {\n                effect.setArray3(name, this._colors3Arrays[name]);\n            }\n\n            // Color4\n            for (name in this._colors4) {\n                const color = this._colors4[name];\n                effect.setFloat4(name, color.r, color.g, color.b, color.a);\n            }\n\n            // Color4Array\n            for (name in this._colors4Arrays) {\n                effect.setArray4(name, this._colors4Arrays[name]);\n            }\n\n            // Vector2\n            for (name in this._vectors2) {\n                effect.setVector2(name, this._vectors2[name]);\n            }\n\n            // Vector3\n            for (name in this._vectors3) {\n                effect.setVector3(name, this._vectors3[name]);\n            }\n\n            // Vector4\n            for (name in this._vectors4) {\n                effect.setVector4(name, this._vectors4[name]);\n            }\n\n            // Quaternion\n            for (name in this._quaternions) {\n                effect.setQuaternion(name, this._quaternions[name]);\n            }\n\n            // Matrix\n            for (name in this._matrices) {\n                effect.setMatrix(name, this._matrices[name]);\n            }\n\n            // MatrixArray\n            for (name in this._matrixArrays) {\n                effect.setMatrices(name, this._matrixArrays[name]);\n            }\n\n            // Matrix 3x3\n            for (name in this._matrices3x3) {\n                effect.setMatrix3x3(name, this._matrices3x3[name]);\n            }\n\n            // Matrix 2x2\n            for (name in this._matrices2x2) {\n                effect.setMatrix2x2(name, this._matrices2x2[name]);\n            }\n\n            // Vector2Array\n            for (name in this._vectors2Arrays) {\n                effect.setArray2(name, this._vectors2Arrays[name]);\n            }\n\n            // Vector3Array\n            for (name in this._vectors3Arrays) {\n                effect.setArray3(name, this._vectors3Arrays[name]);\n            }\n\n            // Vector4Array\n            for (name in this._vectors4Arrays) {\n                effect.setArray4(name, this._vectors4Arrays[name]);\n            }\n\n            // QuaternionArray\n            for (name in this._quaternionsArrays) {\n                effect.setArray4(name, this._quaternionsArrays[name]);\n            }\n\n            // Uniform buffers\n            for (name in this._uniformBuffers) {\n                const buffer = this._uniformBuffers[name].getBuffer();\n                if (buffer) {\n                    effect.bindUniformBuffer(buffer, name);\n                }\n            }\n\n            const engineWebGPU = scene.getEngine() as WebGPUEngine;\n\n            // External texture\n            const setExternalTexture = engineWebGPU.setExternalTexture;\n            if (setExternalTexture) {\n                for (name in this._externalTextures) {\n                    setExternalTexture.call(engineWebGPU, name, this._externalTextures[name]);\n                }\n            }\n\n            // Samplers\n            const setTextureSampler = engineWebGPU.setTextureSampler;\n            if (setTextureSampler) {\n                for (name in this._textureSamplers) {\n                    setTextureSampler.call(engineWebGPU, name, this._textureSamplers[name]);\n                }\n            }\n\n            // Storage buffers\n            const setStorageBuffer = engineWebGPU.setStorageBuffer;\n            if (setStorageBuffer) {\n                for (name in this._storageBuffers) {\n                    setStorageBuffer.call(engineWebGPU, name, this._storageBuffers[name]);\n                }\n            }\n        }\n\n        if (effect && mesh && (mustRebind || !this.isFrozen)) {\n            // Morph targets\n            BindMorphTargetParameters(mesh, effect);\n            if (mesh.morphTargetManager && mesh.morphTargetManager.isUsingTextureForTargets) {\n                mesh.morphTargetManager._bind(effect);\n            }\n\n            const bvaManager = (<AbstractMesh>mesh).bakedVertexAnimationManager;\n\n            if (bvaManager && bvaManager.isEnabled) {\n                const drawWrapper = storeEffectOnSubMeshes ? subMesh._drawWrapper : this._drawWrapper;\n                mesh.bakedVertexAnimationManager?.bind(effect, !!drawWrapper._wasPreviouslyUsingInstances);\n            }\n        }\n\n        this._afterBind(mesh, effect, subMesh);\n    }\n\n    /**\n     * Gets the active textures from the material\n     * @returns an array of textures\n     */\n    public override getActiveTextures(): BaseTexture[] {\n        const activeTextures = super.getActiveTextures();\n\n        for (const name in this._textures) {\n            activeTextures.push(this._textures[name]);\n        }\n\n        for (const name in this._textureArrays) {\n            const array = this._textureArrays[name];\n            for (let index = 0; index < array.length; index++) {\n                activeTextures.push(array[index]);\n            }\n        }\n\n        return activeTextures;\n    }\n\n    /**\n     * Specifies if the material uses a texture\n     * @param texture defines the texture to check against the material\n     * @returns a boolean specifying if the material uses the texture\n     */\n    public override hasTexture(texture: BaseTexture): boolean {\n        if (super.hasTexture(texture)) {\n            return true;\n        }\n\n        for (const name in this._textures) {\n            if (this._textures[name] === texture) {\n                return true;\n            }\n        }\n\n        const internalTexture = texture.getInternalTexture();\n        for (const name in this._internalTextures) {\n            if (this._internalTextures[name] === internalTexture) {\n                return true;\n            }\n        }\n\n        for (const name in this._textureArrays) {\n            const array = this._textureArrays[name];\n            for (let index = 0; index < array.length; index++) {\n                if (array[index] === texture) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Makes a duplicate of the material, and gives it a new name\n     * @param name defines the new name for the duplicated material\n     * @returns the cloned material\n     */\n    public override clone(name: string): ShaderMaterial {\n        const result = SerializationHelper.Clone(() => new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options, this._storeEffectOnSubMeshes), this);\n\n        result.name = name;\n        result.id = name;\n\n        // Shader code path\n        if (typeof result._shaderPath === \"object\") {\n            result._shaderPath = { ...result._shaderPath };\n        }\n\n        // Options\n        this._options = { ...this._options };\n\n        const keys = Object.keys(this._options) as Array<keyof IShaderMaterialOptions>;\n\n        for (const propName of keys) {\n            const propValue = this._options[propName];\n            if (Array.isArray(propValue)) {\n                (<string[]>this._options[propName]) = propValue.slice(0);\n            }\n        }\n\n        // Stencil\n        this.stencil.copyTo(result.stencil);\n\n        // Texture\n        for (const key in this._textures) {\n            result.setTexture(key, this._textures[key]);\n        }\n\n        for (const key in this._internalTextures) {\n            result.setInternalTexture(key, this._internalTextures[key]);\n        }\n\n        // TextureArray\n        for (const key in this._textureArrays) {\n            result.setTextureArray(key, this._textureArrays[key]);\n        }\n\n        // External texture\n        for (const key in this._externalTextures) {\n            result.setExternalTexture(key, this._externalTextures[key]);\n        }\n\n        // Int\n        for (const key in this._ints) {\n            result.setInt(key, this._ints[key]);\n        }\n\n        // UInt\n        for (const key in this._uints) {\n            result.setUInt(key, this._uints[key]);\n        }\n\n        // Float\n        for (const key in this._floats) {\n            result.setFloat(key, this._floats[key]);\n        }\n\n        // Floats\n        for (const key in this._floatsArrays) {\n            result.setFloats(key, this._floatsArrays[key]);\n        }\n\n        // Color3\n        for (const key in this._colors3) {\n            result.setColor3(key, this._colors3[key]);\n        }\n\n        // Color3Array\n        for (const key in this._colors3Arrays) {\n            result._colors3Arrays[key] = this._colors3Arrays[key];\n        }\n\n        // Color4\n        for (const key in this._colors4) {\n            result.setColor4(key, this._colors4[key]);\n        }\n\n        // Color4Array\n        for (const key in this._colors4Arrays) {\n            result._colors4Arrays[key] = this._colors4Arrays[key];\n        }\n\n        // Vector2\n        for (const key in this._vectors2) {\n            result.setVector2(key, this._vectors2[key]);\n        }\n\n        // Vector3\n        for (const key in this._vectors3) {\n            result.setVector3(key, this._vectors3[key]);\n        }\n\n        // Vector4\n        for (const key in this._vectors4) {\n            result.setVector4(key, this._vectors4[key]);\n        }\n\n        // Quaternion\n        for (const key in this._quaternions) {\n            result.setQuaternion(key, this._quaternions[key]);\n        }\n\n        // QuaternionArray\n        for (const key in this._quaternionsArrays) {\n            result._quaternionsArrays[key] = this._quaternionsArrays[key];\n        }\n\n        // Matrix\n        for (const key in this._matrices) {\n            result.setMatrix(key, this._matrices[key]);\n        }\n\n        // MatrixArray\n        for (const key in this._matrixArrays) {\n            result._matrixArrays[key] = this._matrixArrays[key].slice();\n        }\n\n        // Matrix 3x3\n        for (const key in this._matrices3x3) {\n            result.setMatrix3x3(key, this._matrices3x3[key]);\n        }\n\n        // Matrix 2x2\n        for (const key in this._matrices2x2) {\n            result.setMatrix2x2(key, this._matrices2x2[key]);\n        }\n\n        // Vector2Array\n        for (const key in this._vectors2Arrays) {\n            result.setArray2(key, this._vectors2Arrays[key]);\n        }\n\n        // Vector3Array\n        for (const key in this._vectors3Arrays) {\n            result.setArray3(key, this._vectors3Arrays[key]);\n        }\n\n        // Vector4Array\n        for (const key in this._vectors4Arrays) {\n            result.setArray4(key, this._vectors4Arrays[key]);\n        }\n\n        // Uniform buffers\n        for (const key in this._uniformBuffers) {\n            result.setUniformBuffer(key, this._uniformBuffers[key]);\n        }\n\n        // Samplers\n        for (const key in this._textureSamplers) {\n            result.setTextureSampler(key, this._textureSamplers[key]);\n        }\n\n        // Storag buffers\n        for (const key in this._storageBuffers) {\n            result.setStorageBuffer(key, this._storageBuffers[key]);\n        }\n\n        return result;\n    }\n\n    /**\n     * Disposes the material\n     * @param forceDisposeEffect specifies if effects should be forcefully disposed\n     * @param forceDisposeTextures specifies if textures should be forcefully disposed\n     * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh\n     */\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, notBoundToMesh?: boolean): void {\n        if (forceDisposeTextures) {\n            let name: string;\n            for (name in this._textures) {\n                this._textures[name].dispose();\n            }\n            for (name in this._internalTextures) {\n                this._internalTextures[name].dispose();\n            }\n\n            for (name in this._textureArrays) {\n                const array = this._textureArrays[name];\n                for (let index = 0; index < array.length; index++) {\n                    array[index].dispose();\n                }\n            }\n        }\n\n        this._textures = {};\n        this._internalTextures = {};\n        super.dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh);\n    }\n\n    /**\n     * Serializes this material in a JSON representation\n     * @returns the serialized material object\n     */\n    public override serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n        serializationObject.customType = \"BABYLON.ShaderMaterial\";\n        serializationObject.uniqueId = this.uniqueId;\n\n        serializationObject.options = this._options;\n        serializationObject.shaderPath = this._shaderPath;\n        serializationObject.storeEffectOnSubMeshes = this._storeEffectOnSubMeshes;\n\n        let name: string;\n\n        // Stencil\n        serializationObject.stencil = this.stencil.serialize();\n\n        // Texture\n        serializationObject.textures = {};\n        for (name in this._textures) {\n            serializationObject.textures[name] = this._textures[name].serialize();\n        }\n\n        // Texture arrays\n        serializationObject.textureArrays = {};\n        for (name in this._textureArrays) {\n            serializationObject.textureArrays[name] = [];\n            const array = this._textureArrays[name];\n            for (let index = 0; index < array.length; index++) {\n                serializationObject.textureArrays[name].push(array[index].serialize());\n            }\n        }\n\n        // Int\n        serializationObject.ints = {};\n        for (name in this._ints) {\n            serializationObject.ints[name] = this._ints[name];\n        }\n\n        // UInt\n        serializationObject.uints = {};\n        for (name in this._uints) {\n            serializationObject.uints[name] = this._uints[name];\n        }\n\n        // Float\n        serializationObject.floats = {};\n        for (name in this._floats) {\n            serializationObject.floats[name] = this._floats[name];\n        }\n\n        // Floats\n        serializationObject.floatsArrays = {};\n        for (name in this._floatsArrays) {\n            serializationObject.floatsArrays[name] = this._floatsArrays[name];\n        }\n\n        // Color3\n        serializationObject.colors3 = {};\n        for (name in this._colors3) {\n            const color3 = this._colors3[name];\n            serializationObject.colors3[name] = [color3.r, color3.g, color3.b];\n        }\n\n        // Color3 array\n        serializationObject.colors3Arrays = {};\n        for (name in this._colors3Arrays) {\n            serializationObject.colors3Arrays[name] = this._colors3Arrays[name];\n        }\n\n        // Color4\n        serializationObject.colors4 = {};\n        for (name in this._colors4) {\n            const color4 = this._colors4[name];\n            serializationObject.colors4[name] = [color4.r, color4.g, color4.b, color4.a];\n        }\n\n        // Color4 array\n        serializationObject.colors4Arrays = {};\n        for (name in this._colors4Arrays) {\n            serializationObject.colors4Arrays[name] = this._colors4Arrays[name];\n        }\n\n        // Vector2\n        serializationObject.vectors2 = {};\n        for (name in this._vectors2) {\n            const v2 = this._vectors2[name];\n            serializationObject.vectors2[name] = [v2.x, v2.y];\n        }\n\n        // Vector3\n        serializationObject.vectors3 = {};\n        for (name in this._vectors3) {\n            const v3 = this._vectors3[name];\n            serializationObject.vectors3[name] = [v3.x, v3.y, v3.z];\n        }\n\n        // Vector4\n        serializationObject.vectors4 = {};\n        for (name in this._vectors4) {\n            const v4 = this._vectors4[name];\n            serializationObject.vectors4[name] = [v4.x, v4.y, v4.z, v4.w];\n        }\n\n        // Quaternion\n        serializationObject.quaternions = {};\n        for (name in this._quaternions) {\n            serializationObject.quaternions[name] = this._quaternions[name].asArray();\n        }\n\n        // Matrix\n        serializationObject.matrices = {};\n        for (name in this._matrices) {\n            serializationObject.matrices[name] = this._matrices[name].asArray();\n        }\n\n        // MatrixArray\n        serializationObject.matrixArray = {};\n        for (name in this._matrixArrays) {\n            serializationObject.matrixArray[name] = this._matrixArrays[name];\n        }\n\n        // Matrix 3x3\n        serializationObject.matrices3x3 = {};\n        for (name in this._matrices3x3) {\n            serializationObject.matrices3x3[name] = this._matrices3x3[name];\n        }\n\n        // Matrix 2x2\n        serializationObject.matrices2x2 = {};\n        for (name in this._matrices2x2) {\n            serializationObject.matrices2x2[name] = this._matrices2x2[name];\n        }\n\n        // Vector2Array\n        serializationObject.vectors2Arrays = {};\n        for (name in this._vectors2Arrays) {\n            serializationObject.vectors2Arrays[name] = this._vectors2Arrays[name];\n        }\n\n        // Vector3Array\n        serializationObject.vectors3Arrays = {};\n        for (name in this._vectors3Arrays) {\n            serializationObject.vectors3Arrays[name] = this._vectors3Arrays[name];\n        }\n\n        // Vector4Array\n        serializationObject.vectors4Arrays = {};\n        for (name in this._vectors4Arrays) {\n            serializationObject.vectors4Arrays[name] = this._vectors4Arrays[name];\n        }\n\n        // QuaternionArray\n        serializationObject.quaternionsArrays = {};\n        for (name in this._quaternionsArrays) {\n            serializationObject.quaternionsArrays[name] = this._quaternionsArrays[name];\n        }\n\n        return serializationObject;\n    }\n}\n\n/**\n * Creates a shader material from parsed shader material data\n * @param source defines the JSON representation of the material\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @returns a new material\n */\nexport function ShaderMaterialParse(source: any, scene: Scene, rootUrl: string): ShaderMaterial {\n    const material = SerializationHelper.Parse(\n        () => new ShaderMaterial(source.name, scene, source.shaderPath, source.options, source.storeEffectOnSubMeshes),\n        source,\n        scene,\n        rootUrl\n    );\n\n    let name: string;\n\n    // Stencil\n    if (source.stencil) {\n        material.stencil.parse(source.stencil, scene, rootUrl);\n    }\n\n    // Texture\n    for (name in source.textures) {\n        material.setTexture(name, <BaseTexture>Texture.Parse(source.textures[name], scene, rootUrl));\n    }\n\n    // Texture arrays\n    for (name in source.textureArrays) {\n        const array = source.textureArrays[name];\n        const textureArray: BaseTexture[] = [];\n\n        for (let index = 0; index < array.length; index++) {\n            textureArray.push(<BaseTexture>Texture.Parse(array[index], scene, rootUrl));\n        }\n        material.setTextureArray(name, textureArray);\n    }\n\n    // Int\n    for (name in source.ints) {\n        material.setInt(name, source.ints[name]);\n    }\n\n    // UInt\n    for (name in source.uints) {\n        material.setUInt(name, source.uints[name]);\n    }\n\n    // Float\n    for (name in source.floats) {\n        material.setFloat(name, source.floats[name]);\n    }\n\n    // Floats\n    for (name in source.floatsArrays) {\n        material.setFloats(name, source.floatsArrays[name]);\n    }\n\n    // Color3\n    for (name in source.colors3) {\n        const color = source.colors3[name];\n        material.setColor3(name, { r: color[0], g: color[1], b: color[2] });\n    }\n\n    // Color3 arrays\n    for (name in source.colors3Arrays) {\n        const colors: IColor3Like[] = source.colors3Arrays[name]\n            .reduce((arr: Array<Array<number>>, num: number, i: number) => {\n                if (i % 3 === 0) {\n                    arr.push([num]);\n                } else {\n                    arr[arr.length - 1].push(num);\n                }\n                return arr;\n            }, [])\n            .map((color: ArrayLike<number>) => ({ r: color[0], g: color[1], b: color[2] }));\n        material.setColor3Array(name, colors);\n    }\n\n    // Color4\n    for (name in source.colors4) {\n        const color = source.colors4[name];\n        material.setColor4(name, { r: color[0], g: color[1], b: color[2], a: color[3] });\n    }\n\n    // Color4 arrays\n    for (name in source.colors4Arrays) {\n        const colors: IColor4Like[] = source.colors4Arrays[name]\n            .reduce((arr: Array<Array<number>>, num: number, i: number) => {\n                if (i % 4 === 0) {\n                    arr.push([num]);\n                } else {\n                    arr[arr.length - 1].push(num);\n                }\n                return arr;\n            }, [])\n            .map((color: ArrayLike<number>) => ({ r: color[0], g: color[1], b: color[2], a: color[3] }));\n        material.setColor4Array(name, colors);\n    }\n\n    // Vector2\n    for (name in source.vectors2) {\n        const vector = source.vectors2[name];\n        material.setVector2(name, { x: vector[0], y: vector[1] });\n    }\n\n    // Vector3\n    for (name in source.vectors3) {\n        const vector = source.vectors3[name];\n        material.setVector3(name, { x: vector[0], y: vector[1], z: vector[2] });\n    }\n\n    // Vector4\n    for (name in source.vectors4) {\n        const vector = source.vectors4[name];\n        material.setVector4(name, { x: vector[0], y: vector[1], z: vector[2], w: vector[3] });\n    }\n\n    // Quaternion\n    for (name in source.quaternions) {\n        material.setQuaternion(name, Quaternion.FromArray(source.quaternions[name]));\n    }\n\n    // Matrix\n    for (name in source.matrices) {\n        material.setMatrix(name, Matrix.FromArray(source.matrices[name]));\n    }\n\n    // MatrixArray\n    const matrixArrayAccess = material as unknown as IShaderMaterialMatrixArrayAccess;\n    for (name in source.matrixArray) {\n        matrixArrayAccess._matrixArrays[name] = new Float32Array(source.matrixArray[name]);\n    }\n\n    // Matrix 3x3\n    for (name in source.matrices3x3) {\n        material.setMatrix3x3(name, source.matrices3x3[name]);\n    }\n\n    // Matrix 2x2\n    for (name in source.matrices2x2) {\n        material.setMatrix2x2(name, source.matrices2x2[name]);\n    }\n\n    // Vector2Array\n    for (name in source.vectors2Arrays) {\n        material.setArray2(name, source.vectors2Arrays[name]);\n    }\n\n    // Vector3Array\n    for (name in source.vectors3Arrays) {\n        material.setArray3(name, source.vectors3Arrays[name]);\n    }\n\n    // Vector4Array\n    for (name in source.vectors4Arrays) {\n        material.setArray4(name, source.vectors4Arrays[name]);\n    }\n\n    // QuaternionArray\n    for (name in source.quaternionsArrays) {\n        material.setArray4(name, source.quaternionsArrays[name]);\n    }\n\n    return material;\n}\n\n/**\n * Creates a new ShaderMaterial from a snippet saved in a remote file\n * @param name defines the name of the ShaderMaterial to create (can be null or empty to use the one from the json data)\n * @param url defines the url to load from\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @returns a promise that will resolve to the new ShaderMaterial\n */\nexport async function ShaderMaterialParseFromFileAsync(name: Nullable<string>, url: string, scene: Scene, rootUrl = \"\"): Promise<ShaderMaterial> {\n    return await new Promise((resolve, reject) => {\n        const request = new WebRequest();\n        request.addEventListener(\"readystatechange\", () => {\n            if (request.readyState == 4) {\n                if (request.status == 200) {\n                    const serializationObject = JSON.parse(request.responseText);\n                    const output = ShaderMaterialParse(serializationObject, scene || EngineStore.LastCreatedScene, rootUrl);\n\n                    if (name) {\n                        output.name = name;\n                    }\n\n                    resolve(output);\n                } else {\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                    reject(\"Unable to load the ShaderMaterial\");\n                }\n            }\n        });\n\n        request.open(\"GET\", url);\n        request.send();\n    });\n}\n\n/**\n * Creates a ShaderMaterial from a snippet saved by the Inspector\n * @param snippetId defines the snippet to load\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @returns a promise that will resolve to the new ShaderMaterial\n */\nexport async function ShaderMaterialParseFromSnippetAsync(this: typeof ShaderMaterial | void, snippetId: string, scene: Scene, rootUrl = \"\"): Promise<ShaderMaterial> {\n    const snippetUrl = this?.SnippetUrl ?? ShaderMaterial.SnippetUrl;\n\n    return await new Promise((resolve, reject) => {\n        const request = new WebRequest();\n        request.addEventListener(\"readystatechange\", () => {\n            if (request.readyState == 4) {\n                if (request.status == 200) {\n                    const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\n                    const serializationObject = JSON.parse(snippet.shaderMaterial);\n                    const output = ShaderMaterialParse(serializationObject, scene || EngineStore.LastCreatedScene, rootUrl);\n\n                    output.snippetId = snippetId;\n\n                    resolve(output);\n                } else {\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                    reject(\"Unable to load the snippet \" + snippetId);\n                }\n            }\n        });\n\n        request.open(\"GET\", snippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\n        request.send();\n    });\n}\n\n/**\n * Creates a ShaderMaterial from a snippet saved by the Inspector\n * @deprecated Please use ShaderMaterialParseFromSnippetAsync instead\n * @param snippetId defines the snippet to load\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @returns a promise that will resolve to the new ShaderMaterial\n */\nexport const ShaderMaterialCreateFromSnippetAsync = ShaderMaterialParseFromSnippetAsync;\n\nlet _Registered = false;\n/**\n * Register side effects for shaderMaterial.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterShaderMaterial(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    ShaderMaterial.Parse = ShaderMaterialParse;\n    ShaderMaterial.ParseFromFileAsync = ShaderMaterialParseFromFileAsync;\n    ShaderMaterial.ParseFromSnippetAsync = ShaderMaterialParseFromSnippetAsync;\n    ShaderMaterial.CreateFromSnippetAsync = ShaderMaterialCreateFromSnippetAsync;\n\n    RegisterClass(\"BABYLON.ShaderMaterial\", ShaderMaterial);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { InstancedMesh } from \"../Meshes/instancedMesh.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { ShaderMaterial } from \"../Materials/shaderMaterial.pure\";\r\nimport { type IShaderMaterialOptions } from \"../Materials/shaderMaterial\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type MeshCreationOptions } from \"./mesh.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type Scene } from \"../scene.pure\";\r\n\r\n/**\r\n * Line mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n */\r\nexport class LinesMesh extends Mesh {\r\n    /**\r\n     * Force all the LineMeshes to compile their default color material to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * Color of the line (Default: White)\r\n     */\r\n    public color = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * Alpha of the line (Default: 1)\r\n     */\r\n    public alpha = 1;\r\n\r\n    /**\r\n     * The intersection Threshold is the margin applied when intersection a segment of the LinesMesh with a Ray.\r\n     * This margin is expressed in world space coordinates, so its value may vary.\r\n     * Default value is 0.1\r\n     */\r\n    public intersectionThreshold: number;\r\n\r\n    private _isShaderMaterial(shader: Nullable<Material>): shader is ShaderMaterial {\r\n        if (!shader) {\r\n            return false;\r\n        }\r\n\r\n        return shader.getClassName() === \"ShaderMaterial\";\r\n    }\r\n\r\n    private _color4: Color4;\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    private _ownsMaterial: boolean = false;\r\n\r\n    /**\r\n     * Creates a new LinesMesh\r\n     * @param name defines the name\r\n     * @param scene defines the hosting scene\r\n     * @param parent defines the parent mesh if any\r\n     * @param source defines the optional source LinesMesh used to clone data from\r\n     * @param doNotCloneChildren When cloning, skip cloning child meshes of source, default False.\r\n     * When false, achieved by calling a clone(), also passing False.\r\n     * This will make creation of children, recursive.\r\n     * @param useVertexColor defines if this LinesMesh supports vertex color\r\n     * @param useVertexAlpha defines if this LinesMesh supports vertex alpha\r\n     * @param material material to use to draw the line. If not provided, will create a new one\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Nullable<Scene> = null,\r\n        parent: Nullable<Node> = null,\r\n        source: Nullable<LinesMesh> = null,\r\n        doNotCloneChildren?: boolean,\r\n        /**\r\n         * If vertex color should be applied to the mesh\r\n         */\r\n        public readonly useVertexColor?: boolean,\r\n        /**\r\n         * If vertex alpha should be applied to the mesh\r\n         */\r\n        public readonly useVertexAlpha?: boolean,\r\n        material?: Material\r\n    ) {\r\n        super(name, scene, parent, source, doNotCloneChildren);\r\n\r\n        if (source) {\r\n            this.color = source.color.clone();\r\n            this.alpha = source.alpha;\r\n            this.useVertexColor = source.useVertexColor;\r\n            this.useVertexAlpha = source.useVertexAlpha;\r\n        }\r\n\r\n        this.intersectionThreshold = 0.1;\r\n\r\n        const defines: string[] = [];\r\n        const options: Partial<IShaderMaterialOptions> = {\r\n            attributes: [VertexBuffer.PositionKind],\r\n            uniforms: [\"world\", \"viewProjection\"],\r\n            needAlphaBlending: true,\r\n            defines: defines,\r\n            useClipPlane: null,\r\n            shaderLanguage: ShaderLanguage.GLSL,\r\n        };\r\n\r\n        if (!this.useVertexAlpha) {\r\n            options.needAlphaBlending = false;\r\n        } else {\r\n            options.defines!.push(\"#define VERTEXALPHA\");\r\n        }\r\n\r\n        if (!this.useVertexColor) {\r\n            options.uniforms!.push(\"color\");\r\n            this._color4 = new Color4();\r\n        } else {\r\n            options.defines!.push(\"#define VERTEXCOLOR\");\r\n            options.attributes!.push(VertexBuffer.ColorKind);\r\n        }\r\n\r\n        if (material) {\r\n            this.material = material;\r\n        } else {\r\n            const engine = this.getScene().getEngine();\r\n\r\n            if (engine.isWebGPU && !LinesMesh.ForceGLSL) {\r\n                this._shaderLanguage = ShaderLanguage.WGSL;\r\n            }\r\n\r\n            options.shaderLanguage = this._shaderLanguage;\r\n            options.extraInitializationsAsync = async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await Promise.all([import(\"../ShadersWGSL/color.vertex\"), import(\"../ShadersWGSL/color.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../Shaders/color.vertex\"), import(\"../Shaders/color.fragment\")]);\r\n                }\r\n            };\r\n\r\n            const material = new ShaderMaterial(\"colorShader\", this.getScene(), \"color\", options, false);\r\n            material.doNotSerialize = true;\r\n\r\n            this._ownsMaterial = true;\r\n            this._setInternalMaterial(material);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns the string \"LineMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"LinesMesh\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override get material(): Nullable<Material> {\r\n        return this._internalAbstractMeshDataInfo._material as Material;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override set material(value: Nullable<Material>) {\r\n        const currentMaterial = this.material;\r\n        if (currentMaterial === value) {\r\n            return;\r\n        }\r\n\r\n        const shouldDispose = currentMaterial && this._ownsMaterial;\r\n        this._ownsMaterial = false;\r\n        this._setInternalMaterial(value);\r\n\r\n        if (shouldDispose) {\r\n            currentMaterial?.dispose();\r\n        }\r\n    }\r\n\r\n    private _setInternalMaterial(material: Nullable<Material>) {\r\n        this._setMaterial(material);\r\n        if (this.material) {\r\n            this.material.fillMode = Material.LineListDrawMode;\r\n            (this.material as any).disableLighting = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override get checkCollisions(): boolean {\r\n        return false;\r\n    }\r\n\r\n    public override set checkCollisions(value: boolean) {\r\n        // Just ignore it\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _bind(_subMesh: SubMesh, colorEffect: Effect): Mesh {\r\n        if (!this._geometry) {\r\n            return this;\r\n        }\r\n\r\n        // VBOs\r\n        const indexToBind = this.isUnIndexed ? null : this._geometry.getIndexBuffer();\r\n        if (!this._userInstancedBuffersStorage || this.hasThinInstances) {\r\n            this._geometry._bind(colorEffect, indexToBind);\r\n        } else {\r\n            this._geometry._bind(colorEffect, indexToBind, this._userInstancedBuffersStorage.vertexBuffers, this._userInstancedBuffersStorage.vertexArrayObjects);\r\n        }\r\n\r\n        // Color\r\n        if (!this.useVertexColor && this._isShaderMaterial(this.material)) {\r\n            const { r, g, b } = this.color;\r\n            this._color4.set(r, g, b, this.alpha);\r\n            this.material.setColor4(\"color\", this._color4);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _draw(subMesh: SubMesh, fillMode: number, instancesCount?: number): Mesh {\r\n        if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {\r\n            return this;\r\n        }\r\n\r\n        const engine = this.getScene().getEngine();\r\n\r\n        // Draw order\r\n\r\n        if (this._unIndexed) {\r\n            engine.drawArraysType(Material.LineListDrawMode, subMesh.verticesStart, subMesh.verticesCount, instancesCount);\r\n        } else {\r\n            engine.drawElementsType(Material.LineListDrawMode, subMesh.indexStart, subMesh.indexCount, instancesCount);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the line mesh (this disposes of the automatically created material if not instructed otherwise).\r\n     * @param doNotRecurse If children should be disposed\r\n     * @param disposeMaterialAndTextures This parameter is used to force disposing the material in case it is not the default one\r\n     * @param doNotDisposeMaterial If the material should not be disposed (default: false, meaning the material might be disposed)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false, doNotDisposeMaterial?: boolean): void {\r\n        if (!doNotDisposeMaterial) {\r\n            if (this._ownsMaterial) {\r\n                this.material?.dispose(false, false, true);\r\n            } else if (disposeMaterialAndTextures) {\r\n                this.material?.dispose(false, false, true);\r\n            }\r\n        }\r\n\r\n        super.dispose(doNotRecurse);\r\n    }\r\n\r\n    /**\r\n     * Returns a new LineMesh object cloned from the current one.\r\n     * @param name defines the cloned mesh name\r\n     * @param newParent defines the new mesh parent\r\n     * @param doNotCloneChildren if set to true, none of the mesh children are cloned (false by default)\r\n     * @returns the new mesh\r\n     */\r\n    public override clone(name: string, newParent: Nullable<Node> | MeshCreationOptions = null, doNotCloneChildren?: boolean): LinesMesh {\r\n        if (newParent && (newParent as Node)._addToSceneRootNodes === undefined) {\r\n            const createOptions = newParent as MeshCreationOptions;\r\n            createOptions.source = this;\r\n\r\n            return new LinesMesh(name, this.getScene(), createOptions.parent, createOptions.source as Nullable<LinesMesh>, createOptions.doNotCloneChildren);\r\n        }\r\n\r\n        return new LinesMesh(name, this.getScene(), newParent as Nullable<Node>, this, doNotCloneChildren);\r\n    }\r\n\r\n    /**\r\n     * Creates a new InstancedLinesMesh object from the mesh model.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances\r\n     * @param name defines the name of the new instance\r\n     * @returns a new InstancedLinesMesh\r\n     */\r\n    public override createInstance(name: string): InstancedLinesMesh {\r\n        const instance = new InstancedLinesMesh(name, this);\r\n\r\n        if (this.instancedBuffers) {\r\n            instance.instancedBuffers = {};\r\n\r\n            for (const key in this.instancedBuffers) {\r\n                instance.instancedBuffers[key] = this.instancedBuffers[key];\r\n            }\r\n        }\r\n\r\n        return instance;\r\n    }\r\n\r\n    /**\r\n     * Serializes this ground mesh\r\n     * @param serializationObject object to write serialization to\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.color = this.color.asArray();\r\n        serializationObject.alpha = this.alpha;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized ground mesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the ground mesh in\r\n     * @returns the created ground mesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): LinesMesh {\r\n        const result = new LinesMesh(parsedMesh.name, scene);\r\n\r\n        result.color = Color3.FromArray(parsedMesh.color);\r\n        result.alpha = parsedMesh.alpha;\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\n/**\r\n * Creates an instance based on a source LinesMesh\r\n */\r\nexport class InstancedLinesMesh extends InstancedMesh {\r\n    /**\r\n     * The intersection Threshold is the margin applied when intersection a segment of the LinesMesh with a Ray.\r\n     * This margin is expressed in world space coordinates, so its value may vary.\r\n     * Initialized with the intersectionThreshold value of the source LinesMesh\r\n     */\r\n    public intersectionThreshold: number;\r\n\r\n    constructor(name: string, source: LinesMesh) {\r\n        super(name, source);\r\n        this.intersectionThreshold = source.intersectionThreshold;\r\n    }\r\n\r\n    /**\r\n     * @returns the string \"InstancedLinesMesh\".\r\n     */\r\n    public override getClassName(): string {\r\n        return \"InstancedLinesMesh\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for linesMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLinesMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._LinesMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        return LinesMesh.Parse(parsedMesh, scene);\r\n    };\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffect } from \"../Misc/devTools\";\r\n\r\nLinesMesh.prototype.enableEdgesRendering ??= _MissingSideEffect(\"LinesMesh\", \"enableEdgesRendering\") as any;\r\nInstancedLinesMesh.prototype.enableEdgesRendering ??= _MissingSideEffect(\"InstancedLinesMesh\", \"enableEdgesRendering\") as any;\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Color4 } from \"../../Maths/math.color.pure\";\r\nimport { _CreationDataStorage, Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type FloatArray, type Nullable } from \"../../types\";\r\nimport { LinesMesh } from \"../../Meshes/linesMesh.pure\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Material } from \"../../Materials/material.pure\";\r\n\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * Creates the VertexData of the LineSystem\r\n * @param options an object used to set the following optional parameters for the LineSystem, required but can be empty\r\n *  - lines an array of lines, each line being an array of successive Vector3\r\n *  - colors an array of line colors, each of the line colors being an array of successive Color4, one per line point\r\n * @returns the VertexData of the LineSystem\r\n */\r\nexport function CreateLineSystemVertexData(options: { lines: Vector3[][]; colors?: Nullable<Color4[][]> }): VertexData {\r\n    const indices = [];\r\n    const positions = [];\r\n    const lines = options.lines;\r\n    const colors = options.colors;\r\n    const vertexColors = [];\r\n    let idx = 0;\r\n\r\n    for (let l = 0; l < lines.length; l++) {\r\n        const points = lines[l];\r\n        for (let index = 0; index < points.length; index++) {\r\n            const { x, y, z } = points[index];\r\n            positions.push(x, y, z);\r\n            if (colors) {\r\n                const color = colors[l];\r\n                const { r, g, b, a } = color[index];\r\n                vertexColors.push(r, g, b, a);\r\n            }\r\n            if (index > 0) {\r\n                indices.push(idx - 1);\r\n                indices.push(idx);\r\n            }\r\n            idx++;\r\n        }\r\n    }\r\n    const vertexData = new VertexData();\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    if (colors) {\r\n        vertexData.colors = vertexColors;\r\n    }\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Create the VertexData for a DashedLines\r\n * @param options an object used to set the following optional parameters for the DashedLines, required but can be empty\r\n *  - points an array successive Vector3\r\n *  - dashSize the size of the dashes relative to the dash number, optional, default 3\r\n *  - gapSize the size of the gap between two successive dashes relative to the dash number, optional, default 1\r\n *  - dashNb the intended total number of dashes, optional, default 200\r\n * @returns the VertexData for the DashedLines\r\n */\r\nexport function CreateDashedLinesVertexData(options: { points: Vector3[]; dashSize?: number; gapSize?: number; dashNb?: number }): VertexData {\r\n    const dashSize = options.dashSize || 3;\r\n    const gapSize = options.gapSize || 1;\r\n    const dashNb = options.dashNb || 200;\r\n    const points = options.points;\r\n\r\n    const positions: number[] = [];\r\n    const indices: number[] = [];\r\n\r\n    const curvect = Vector3.Zero();\r\n    let lg = 0;\r\n    let nb: number;\r\n    let curshft: number;\r\n    let idx = 0;\r\n    let i: number;\r\n    for (i = 0; i < points.length - 1; i++) {\r\n        points[i + 1].subtractToRef(points[i], curvect);\r\n        lg += curvect.length();\r\n    }\r\n    const shft = lg / dashNb;\r\n    const dashshft = (dashSize * shft) / (dashSize + gapSize);\r\n    for (i = 0; i < points.length - 1; i++) {\r\n        points[i + 1].subtractToRef(points[i], curvect);\r\n        nb = Math.floor(curvect.length() / shft);\r\n        curvect.normalize();\r\n        for (let j = 0; j < nb; j++) {\r\n            curshft = shft * j;\r\n            positions.push(points[i].x + curshft * curvect.x, points[i].y + curshft * curvect.y, points[i].z + curshft * curvect.z);\r\n            positions.push(points[i].x + (curshft + dashshft) * curvect.x, points[i].y + (curshft + dashshft) * curvect.y, points[i].z + (curshft + dashshft) * curvect.z);\r\n            indices.push(idx, idx + 1);\r\n            idx += 2;\r\n        }\r\n    }\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n    vertexData.positions = positions;\r\n    vertexData.indices = indices;\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a line system mesh. A line system is a pool of many lines gathered in a single mesh\r\n * * A line system mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of lines as an input parameter\r\n * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineSystem to this static function\r\n * * The parameter `lines` is an array of lines, each line being an array of successive Vector3\r\n * * The optional parameter `instance` is an instance of an existing LineSystem object to be updated with the passed `lines` parameter\r\n * * The optional parameter `colors` is an array of line colors, each line colors being an array of successive Color4, one per line point\r\n * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need the alpha blending (faster)\r\n * * The optional parameter `material` is the material to use to draw the lines if provided. If not, a default material will be created\r\n * * Updating a simple Line mesh, you just need to update every line in the `lines` array : https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#lines-and-dashedlines\r\n * * When updating an instance, remember that only line point positions can change, not the number of points, neither the number of lines\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#line-system\r\n * @param name defines the name of the new line system\r\n * @param options defines the options used to create the line system\r\n * @param scene defines the hosting scene\r\n * @returns a new line system mesh\r\n */\r\nexport function CreateLineSystem(\r\n    name: string,\r\n    options: { lines: Vector3[][]; updatable?: boolean; instance?: Nullable<LinesMesh>; colors?: Nullable<Color4[][]>; useVertexAlpha?: boolean; material?: Material },\r\n    scene: Nullable<Scene> = null\r\n): LinesMesh {\r\n    const instance = options.instance;\r\n    const lines = options.lines;\r\n    const colors = options.colors;\r\n\r\n    if (instance) {\r\n        // lines update\r\n        const positions = instance.getVerticesData(VertexBuffer.PositionKind)!;\r\n        let vertexColor;\r\n        let lineColors;\r\n        if (colors) {\r\n            vertexColor = instance.getVerticesData(VertexBuffer.ColorKind)!;\r\n        }\r\n        let i = 0;\r\n        let c = 0;\r\n        for (let l = 0; l < lines.length; l++) {\r\n            const points = lines[l];\r\n            for (let p = 0; p < points.length; p++) {\r\n                positions[i] = points[p].x;\r\n                positions[i + 1] = points[p].y;\r\n                positions[i + 2] = points[p].z;\r\n                if (colors && vertexColor) {\r\n                    lineColors = colors[l];\r\n                    vertexColor[c] = lineColors[p].r;\r\n                    vertexColor[c + 1] = lineColors[p].g;\r\n                    vertexColor[c + 2] = lineColors[p].b;\r\n                    vertexColor[c + 3] = lineColors[p].a;\r\n                    c += 4;\r\n                }\r\n                i += 3;\r\n            }\r\n        }\r\n        instance.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);\r\n        if (colors && vertexColor) {\r\n            instance.updateVerticesData(VertexBuffer.ColorKind, vertexColor, false, false);\r\n        }\r\n        instance.refreshBoundingInfo();\r\n        return instance;\r\n    }\r\n\r\n    // line system creation\r\n    const useVertexColor = colors ? true : false;\r\n    const lineSystem = new LinesMesh(name, scene, null, undefined, undefined, useVertexColor, options.useVertexAlpha, options.material);\r\n    const vertexData = CreateLineSystemVertexData(options);\r\n    vertexData.applyToMesh(lineSystem, options.updatable);\r\n    return lineSystem;\r\n}\r\n\r\n/**\r\n * Creates a line mesh\r\n * A line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter\r\n * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function\r\n * * The parameter `points` is an array successive Vector3\r\n * * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#lines-and-dashedlines\r\n * * The optional parameter `colors` is an array of successive Color4, one per line point\r\n * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need alpha blending (faster)\r\n * * The optional parameter `material` is the material to use to draw the lines if provided. If not, a default material will be created\r\n * * When updating an instance, remember that only point positions can change, not the number of points\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#lines\r\n * @param name defines the name of the new line system\r\n * @param options defines the options used to create the line system\r\n * @param scene defines the hosting scene\r\n * @returns a new line mesh\r\n */\r\nexport function CreateLines(\r\n    name: string,\r\n    options: { points: Vector3[]; updatable?: boolean; instance?: Nullable<LinesMesh>; colors?: Color4[]; useVertexAlpha?: boolean; material?: Material },\r\n    scene: Nullable<Scene> = null\r\n): LinesMesh {\r\n    const colors = options.colors ? [options.colors] : null;\r\n    const lines = CreateLineSystem(\r\n        name,\r\n        { lines: [options.points], updatable: options.updatable, instance: options.instance, colors: colors, useVertexAlpha: options.useVertexAlpha, material: options.material },\r\n        scene\r\n    );\r\n    return lines;\r\n}\r\n\r\n/**\r\n * Creates a dashed line mesh\r\n * * A dashed line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter\r\n * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function\r\n * * The parameter `points` is an array successive Vector3\r\n * * The parameter `dashNb` is the intended total number of dashes (positive integer, default 200)\r\n * * The parameter `dashSize` is the size of the dashes relatively the dash number (positive float, default 3)\r\n * * The parameter `gapSize` is the size of the gap between two successive dashes relatively the dash number (positive float, default 1)\r\n * * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#lines-and-dashedlines\r\n * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need the alpha blending (faster)\r\n * * The optional parameter `material` is the material to use to draw the lines if provided. If not, a default material will be created\r\n * * When updating an instance, remember that only point positions can change, not the number of points\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the dashed line mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#dashed-lines\r\n */\r\nexport function CreateDashedLines(\r\n    name: string,\r\n    options: { points: Vector3[]; dashSize?: number; gapSize?: number; dashNb?: number; updatable?: boolean; instance?: LinesMesh; useVertexAlpha?: boolean; material?: Material },\r\n    scene: Nullable<Scene> = null\r\n): LinesMesh {\r\n    const points = options.points;\r\n    const instance = options.instance;\r\n    const gapSize = options.gapSize || 1;\r\n    const dashSize = options.dashSize || 3;\r\n\r\n    if (instance) {\r\n        //  dashed lines update\r\n        const positionFunction = (positions: FloatArray): void => {\r\n            const curvect = Vector3.Zero();\r\n            const nbSeg = positions.length / 6;\r\n            let lg = 0;\r\n            let nb: number;\r\n            let curshft: number;\r\n            let p = 0;\r\n            let i: number;\r\n            let j: number;\r\n            for (i = 0; i < points.length - 1; i++) {\r\n                points[i + 1].subtractToRef(points[i], curvect);\r\n                lg += curvect.length();\r\n            }\r\n            const shft = lg / nbSeg;\r\n            const dashSize = instance._creationDataStorage!.dashSize;\r\n            const gapSize = instance._creationDataStorage!.gapSize;\r\n            const dashshft = (dashSize * shft) / (dashSize + gapSize);\r\n            for (i = 0; i < points.length - 1; i++) {\r\n                points[i + 1].subtractToRef(points[i], curvect);\r\n                nb = Math.floor(curvect.length() / shft);\r\n                curvect.normalize();\r\n                j = 0;\r\n                while (j < nb && p < positions.length) {\r\n                    curshft = shft * j;\r\n                    positions[p] = points[i].x + curshft * curvect.x;\r\n                    positions[p + 1] = points[i].y + curshft * curvect.y;\r\n                    positions[p + 2] = points[i].z + curshft * curvect.z;\r\n                    positions[p + 3] = points[i].x + (curshft + dashshft) * curvect.x;\r\n                    positions[p + 4] = points[i].y + (curshft + dashshft) * curvect.y;\r\n                    positions[p + 5] = points[i].z + (curshft + dashshft) * curvect.z;\r\n                    p += 6;\r\n                    j++;\r\n                }\r\n            }\r\n            while (p < positions.length) {\r\n                positions[p] = points[i].x;\r\n                positions[p + 1] = points[i].y;\r\n                positions[p + 2] = points[i].z;\r\n                p += 3;\r\n            }\r\n        };\r\n        if (options.dashNb || options.dashSize || options.gapSize || options.useVertexAlpha || options.material) {\r\n            Logger.Warn(\"You have used an option other than points with the instance option. Please be aware that these other options will be ignored.\");\r\n        }\r\n        instance.updateMeshPositions(positionFunction, false);\r\n        return instance;\r\n    }\r\n    // dashed lines creation\r\n    const dashedLines = new LinesMesh(name, scene, null, undefined, undefined, undefined, options.useVertexAlpha, options.material);\r\n    const vertexData = CreateDashedLinesVertexData(options);\r\n    vertexData.applyToMesh(dashedLines, options.updatable);\r\n\r\n    dashedLines._creationDataStorage = new _CreationDataStorage();\r\n    dashedLines._creationDataStorage.dashSize = dashSize;\r\n    dashedLines._creationDataStorage.gapSize = gapSize;\r\n    return dashedLines;\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the functions directly from the module\r\n */\r\nexport const LinesBuilder = {\r\n    CreateDashedLines,\r\n    CreateLineSystem,\r\n    CreateLines,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for linesBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLinesBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateLineSystem = CreateLineSystemVertexData;\r\n\r\n    VertexData.CreateDashedLines = CreateDashedLinesVertexData;\r\n\r\n    Mesh.CreateLines = (name: string, points: Vector3[], scene: Nullable<Scene> = null, updatable: boolean = false, instance: Nullable<LinesMesh> = null): LinesMesh => {\r\n        const options = {\r\n            points,\r\n            updatable,\r\n            instance,\r\n        };\r\n        return CreateLines(name, options, scene);\r\n    };\r\n\r\n    Mesh.CreateDashedLines = (\r\n        name: string,\r\n        points: Vector3[],\r\n        dashSize: number,\r\n        gapSize: number,\r\n        dashNb: number,\r\n        scene: Nullable<Scene> = null,\r\n        updatable?: boolean,\r\n        instance?: LinesMesh\r\n    ): LinesMesh => {\r\n        const options = {\r\n            points,\r\n            dashSize,\r\n            gapSize,\r\n            dashNb,\r\n            updatable,\r\n            instance,\r\n        };\r\n        return CreateDashedLines(name, options, scene);\r\n    };\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Vector3, Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Path2 } from \"../Maths/math.path\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare let earcut: any;\r\n/**\r\n * Vector2 wth index property\r\n */\r\nclass IndexedVector2 extends Vector2 {\r\n    /** @internal */\r\n    constructor(\r\n        original: Vector2,\r\n        /** Index of the vector2 */\r\n        public index: number\r\n    ) {\r\n        super(original.x, original.y);\r\n    }\r\n}\r\n\r\n/**\r\n * Defines points to create a polygon\r\n */\r\nclass PolygonPoints {\r\n    /** @internal */\r\n    elements = [] as IndexedVector2[];\r\n\r\n    /** @internal */\r\n    add(originalPoints: Array<Vector2>): Array<IndexedVector2> {\r\n        const result: IndexedVector2[] = [];\r\n        for (const point of originalPoints) {\r\n            const newPoint = new IndexedVector2(point, this.elements.length);\r\n            result.push(newPoint);\r\n            this.elements.push(newPoint);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /** @internal */\r\n    computeBounds(): { min: Vector2; max: Vector2; width: number; height: number } {\r\n        const lmin = new Vector2(this.elements[0].x, this.elements[0].y);\r\n        const lmax = new Vector2(this.elements[0].x, this.elements[0].y);\r\n\r\n        for (const point of this.elements) {\r\n            // x\r\n            if (point.x < lmin.x) {\r\n                lmin.x = point.x;\r\n            } else if (point.x > lmax.x) {\r\n                lmax.x = point.x;\r\n            }\r\n\r\n            // y\r\n            if (point.y < lmin.y) {\r\n                lmin.y = point.y;\r\n            } else if (point.y > lmax.y) {\r\n                lmax.y = point.y;\r\n            }\r\n        }\r\n\r\n        return {\r\n            min: lmin,\r\n            max: lmax,\r\n            width: lmax.x - lmin.x,\r\n            height: lmax.y - lmin.y,\r\n        };\r\n    }\r\n}\r\n\r\n/**\r\n * Polygon\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#non-regular-polygon\r\n */\r\nexport class Polygon {\r\n    /**\r\n     * Creates a rectangle\r\n     * @param xmin bottom X coord\r\n     * @param ymin bottom Y coord\r\n     * @param xmax top X coord\r\n     * @param ymax top Y coord\r\n     * @returns points that make the resulting rectangle\r\n     */\r\n    static Rectangle(xmin: number, ymin: number, xmax: number, ymax: number): Vector2[] {\r\n        return [new Vector2(xmin, ymin), new Vector2(xmax, ymin), new Vector2(xmax, ymax), new Vector2(xmin, ymax)];\r\n    }\r\n\r\n    /**\r\n     * Creates a circle\r\n     * @param radius radius of circle\r\n     * @param cx scale in x\r\n     * @param cy scale in y\r\n     * @param numberOfSides number of sides that make up the circle\r\n     * @returns points that make the resulting circle\r\n     */\r\n    static Circle(radius: number, cx: number = 0, cy: number = 0, numberOfSides: number = 32): Vector2[] {\r\n        const result: Vector2[] = [];\r\n\r\n        let angle = 0;\r\n        const increment = (Math.PI * 2) / numberOfSides;\r\n\r\n        for (let i = 0; i < numberOfSides; i++) {\r\n            result.push(new Vector2(cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius));\r\n            angle -= increment;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a polygon from input string\r\n     * @param input Input polygon data\r\n     * @returns the parsed points\r\n     */\r\n    static Parse(input: string): Vector2[] {\r\n        const floats = input\r\n            .split(/[^-+eE.\\d]+/)\r\n            .map(parseFloat)\r\n            .filter((val) => !isNaN(val));\r\n        let i: number;\r\n        const result = [];\r\n        for (i = 0; i < (floats.length & 0x7ffffffe); i += 2) {\r\n            result.push(new Vector2(floats[i], floats[i + 1]));\r\n        }\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Starts building a polygon from x and y coordinates\r\n     * @param x x coordinate\r\n     * @param y y coordinate\r\n     * @returns the started path2\r\n     */\r\n    static StartingAt(x: number, y: number): Path2 {\r\n        return Path2.StartingAt(x, y);\r\n    }\r\n}\r\n\r\n/**\r\n * Builds a polygon\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/polyMeshBuilder\r\n */\r\nexport class PolygonMeshBuilder {\r\n    private _points = new PolygonPoints();\r\n    private _outlinepoints = new PolygonPoints();\r\n    private _holes = new Array<PolygonPoints>();\r\n\r\n    private _name: string;\r\n    private _scene: Nullable<Scene>;\r\n\r\n    private _epoints: number[] = new Array<number>();\r\n    private _eholes: number[] = new Array<number>();\r\n\r\n    private _addToepoint(points: Vector2[]) {\r\n        for (const p of points) {\r\n            this._epoints.push(p.x, p.y);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Babylon reference to the earcut plugin.\r\n     */\r\n    public bjsEarcut: any;\r\n\r\n    /**\r\n     * Creates a PolygonMeshBuilder\r\n     * @param name name of the builder\r\n     * @param contours Path of the polygon\r\n     * @param scene scene to add to when creating the mesh\r\n     * @param earcutInjection can be used to inject your own earcut reference\r\n     */\r\n    constructor(name: string, contours: Path2 | Vector2[] | any, scene?: Scene, earcutInjection = earcut) {\r\n        this.bjsEarcut = earcutInjection;\r\n        this._name = name;\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n\r\n        let points: Vector2[];\r\n        if (contours instanceof Path2) {\r\n            points = contours.getPoints();\r\n        } else {\r\n            points = <Vector2[]>contours;\r\n        }\r\n\r\n        this._addToepoint(points);\r\n\r\n        this._points.add(points);\r\n        this._outlinepoints.add(points);\r\n\r\n        if (typeof this.bjsEarcut === \"undefined\") {\r\n            Logger.Warn(\"Earcut was not found, the polygon will not be built.\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a hole within the polygon\r\n     * @param hole Array of points defining the hole\r\n     * @returns this\r\n     */\r\n    addHole(hole: Vector2[]): PolygonMeshBuilder {\r\n        this._points.add(hole);\r\n        const holepoints = new PolygonPoints();\r\n        holepoints.add(hole);\r\n        this._holes.push(holepoints);\r\n\r\n        this._eholes.push(this._epoints.length / 2);\r\n        this._addToepoint(hole);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates the polygon\r\n     * @param updatable If the mesh should be updatable\r\n     * @param depth The depth of the mesh created\r\n     * @param smoothingThreshold Dot product threshold for smoothed normals\r\n     * @returns the created mesh\r\n     */\r\n    build(updatable: boolean = false, depth: number = 0, smoothingThreshold: number = 2): Mesh {\r\n        const result = new Mesh(this._name, this._scene);\r\n\r\n        const vertexData = this.buildVertexData(depth, smoothingThreshold);\r\n\r\n        result.setVerticesData(VertexBuffer.PositionKind, <number[]>vertexData.positions, updatable);\r\n        result.setVerticesData(VertexBuffer.NormalKind, <number[]>vertexData.normals, updatable);\r\n        result.setVerticesData(VertexBuffer.UVKind, <number[]>vertexData.uvs, updatable);\r\n        result.setIndices(<number[]>vertexData.indices);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates the polygon\r\n     * @param depth The depth of the mesh created\r\n     * @param smoothingThreshold Dot product threshold for smoothed normals\r\n     * @returns the created VertexData\r\n     */\r\n    buildVertexData(depth: number = 0, smoothingThreshold: number = 2): VertexData {\r\n        const result = new VertexData();\r\n\r\n        const normals: number[] = [];\r\n        const positions: number[] = [];\r\n        const uvs: number[] = [];\r\n\r\n        const bounds = this._points.computeBounds();\r\n        for (const p of this._points.elements) {\r\n            normals.push(0, 1.0, 0);\r\n            positions.push(p.x, 0, p.y);\r\n            uvs.push((p.x - bounds.min.x) / bounds.width, (p.y - bounds.min.y) / bounds.height);\r\n        }\r\n\r\n        const indices: number[] = [];\r\n\r\n        const res = this.bjsEarcut(this._epoints, this._eholes, 2);\r\n\r\n        for (let i = 0; i < res.length; i++) {\r\n            indices.push(res[i]);\r\n        }\r\n\r\n        if (depth > 0) {\r\n            const positionscount = positions.length / 3; //get the current pointcount\r\n\r\n            for (const p of this._points.elements) {\r\n                //add the elements at the depth\r\n                normals.push(0, -1.0, 0);\r\n                positions.push(p.x, -depth, p.y);\r\n                uvs.push(1 - (p.x - bounds.min.x) / bounds.width, 1 - (p.y - bounds.min.y) / bounds.height);\r\n            }\r\n\r\n            const totalCount = indices.length;\r\n            for (let i = 0; i < totalCount; i += 3) {\r\n                const i0 = indices[i + 0];\r\n                const i1 = indices[i + 1];\r\n                const i2 = indices[i + 2];\r\n\r\n                indices.push(i2 + positionscount);\r\n                indices.push(i1 + positionscount);\r\n                indices.push(i0 + positionscount);\r\n            }\r\n\r\n            //Add the sides\r\n            this._addSide(positions, normals, uvs, indices, bounds, this._outlinepoints, depth, false, smoothingThreshold);\r\n\r\n            for (const hole of this._holes) {\r\n                this._addSide(positions, normals, uvs, indices, bounds, hole, depth, true, smoothingThreshold);\r\n            }\r\n        }\r\n\r\n        result.indices = indices;\r\n        result.positions = positions;\r\n        result.normals = normals;\r\n        result.uvs = uvs;\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Adds a side to the polygon\r\n     * @param positions points that make the polygon\r\n     * @param normals normals of the polygon\r\n     * @param uvs uvs of the polygon\r\n     * @param indices indices of the polygon\r\n     * @param bounds bounds of the polygon\r\n     * @param points points of the polygon\r\n     * @param depth depth of the polygon\r\n     * @param flip flip of the polygon\r\n     * @param smoothingThreshold\r\n     */\r\n    private _addSide(positions: any[], normals: any[], uvs: any[], indices: any[], bounds: any, points: PolygonPoints, depth: number, flip: boolean, smoothingThreshold: number) {\r\n        let startIndex: number = positions.length / 3;\r\n        let ulength: number = 0;\r\n        for (let i: number = 0; i < points.elements.length; i++) {\r\n            const p: IndexedVector2 = points.elements[i];\r\n            const p1: IndexedVector2 = points.elements[(i + 1) % points.elements.length];\r\n\r\n            positions.push(p.x, 0, p.y);\r\n            positions.push(p.x, -depth, p.y);\r\n            positions.push(p1.x, 0, p1.y);\r\n            positions.push(p1.x, -depth, p1.y);\r\n\r\n            const p0: IndexedVector2 = points.elements[(i + points.elements.length - 1) % points.elements.length];\r\n            const p2: IndexedVector2 = points.elements[(i + 2) % points.elements.length];\r\n\r\n            let vc = new Vector3(-(p1.y - p.y), 0, p1.x - p.x);\r\n            let vp = new Vector3(-(p.y - p0.y), 0, p.x - p0.x);\r\n            let vn = new Vector3(-(p2.y - p1.y), 0, p2.x - p1.x);\r\n\r\n            if (!flip) {\r\n                vc = vc.scale(-1);\r\n                vp = vp.scale(-1);\r\n                vn = vn.scale(-1);\r\n            }\r\n\r\n            const vcNorm = vc.normalizeToNew();\r\n            let vpNorm = vp.normalizeToNew();\r\n            let vnNorm: Vector3;\r\n\r\n            const dotp = Vector3.Dot(vpNorm, vcNorm);\r\n            if (dotp > smoothingThreshold) {\r\n                if (dotp < Epsilon - 1) {\r\n                    vpNorm = new Vector3(p.x, 0, p.y).subtract(new Vector3(p1.x, 0, p1.y)).normalize();\r\n                } else {\r\n                    // cheap average weighed by side length\r\n                    vpNorm = vp.add(vc).normalize();\r\n                }\r\n            } else {\r\n                vpNorm = vcNorm;\r\n            }\r\n\r\n            const dotn = Vector3.Dot(vn, vc);\r\n            if (dotn > smoothingThreshold) {\r\n                if (dotn < Epsilon - 1) {\r\n                    // back to back\r\n                    vnNorm = new Vector3(p1.x, 0, p1.y).subtract(new Vector3(p.x, 0, p.y)).normalize();\r\n                } else {\r\n                    // cheap average weighed by side length\r\n                    vnNorm = vn.add(vc).normalize();\r\n                }\r\n            } else {\r\n                vnNorm = vcNorm;\r\n            }\r\n\r\n            uvs.push(ulength / bounds.width, 0);\r\n            uvs.push(ulength / bounds.width, 1);\r\n            ulength += vc.length();\r\n            uvs.push(ulength / bounds.width, 0);\r\n            uvs.push(ulength / bounds.width, 1);\r\n\r\n            normals.push(vpNorm.x, vpNorm.y, vpNorm.z);\r\n            normals.push(vpNorm.x, vpNorm.y, vpNorm.z);\r\n            normals.push(vnNorm.x, vnNorm.y, vnNorm.z);\r\n            normals.push(vnNorm.x, vnNorm.y, vnNorm.z);\r\n\r\n            if (!flip) {\r\n                indices.push(startIndex);\r\n                indices.push(startIndex + 1);\r\n                indices.push(startIndex + 2);\r\n\r\n                indices.push(startIndex + 1);\r\n                indices.push(startIndex + 3);\r\n                indices.push(startIndex + 2);\r\n            } else {\r\n                indices.push(startIndex);\r\n                indices.push(startIndex + 2);\r\n                indices.push(startIndex + 1);\r\n\r\n                indices.push(startIndex + 1);\r\n                indices.push(startIndex + 2);\r\n                indices.push(startIndex + 3);\r\n            }\r\n            startIndex += 4;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector4, type Vector3 } from \"../../Maths/math.vector.pure\";\r\n\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { PolygonMeshBuilder } from \"../polygonMesh\";\r\nimport { type FloatArray, type IndicesArray, type Nullable } from \"../../types\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\ndeclare let earcut: any;\r\n\r\n/**\r\n * Creates the VertexData for an irregular Polygon in the XoZ plane using a mesh built by polygonTriangulation.build()\r\n * All parameters are provided by CreatePolygon as needed\r\n * @param polygon a mesh built from polygonTriangulation.build()\r\n * @param sideOrientation takes the values Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * @param fUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n * @param fColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n * @param frontUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * @param backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @param wrp a boolean, default false, when true and fUVs used texture is wrapped around all sides, when false texture is applied side\r\n * @returns the VertexData of the Polygon\r\n */\r\nexport function CreatePolygonVertexData(polygon: Mesh, sideOrientation: number, fUV?: Vector4[], fColors?: Color4[], frontUVs?: Vector4, backUVs?: Vector4, wrp?: boolean) {\r\n    const faceUV: Vector4[] = fUV || new Array<Vector4>(3);\r\n    const faceColors = fColors;\r\n    const colors = [];\r\n    const wrap: boolean = wrp || false;\r\n\r\n    // default face colors and UV if undefined\r\n    for (let f = 0; f < 3; f++) {\r\n        if (faceUV[f] === undefined) {\r\n            faceUV[f] = new Vector4(0, 0, 1, 1);\r\n        }\r\n        if (faceColors && faceColors[f] === undefined) {\r\n            faceColors[f] = new Color4(1, 1, 1, 1);\r\n        }\r\n    }\r\n\r\n    const positions = <FloatArray>polygon.getVerticesData(VertexBuffer.PositionKind);\r\n    const normals = <FloatArray>polygon.getVerticesData(VertexBuffer.NormalKind);\r\n    const uvs = <FloatArray>polygon.getVerticesData(VertexBuffer.UVKind);\r\n    const indices = <IndicesArray>polygon.getIndices();\r\n    const startIndex = positions.length / 9;\r\n    let disp: number;\r\n    let distX: number;\r\n    let distZ: number;\r\n    let dist: number;\r\n    let totalLen = 0;\r\n    const cumulate = [0];\r\n    if (wrap) {\r\n        for (let idx = startIndex; idx < positions.length / 3; idx += 4) {\r\n            distX = positions[3 * (idx + 2)] - positions[3 * idx];\r\n            distZ = positions[3 * (idx + 2) + 2] - positions[3 * idx + 2];\r\n            dist = Math.sqrt(distX * distX + distZ * distZ);\r\n            totalLen += dist;\r\n            cumulate.push(totalLen);\r\n        }\r\n    }\r\n    // set face colours and textures\r\n    let idx: number;\r\n    let face: number = 0;\r\n    for (let index = 0; index < normals.length; index += 3) {\r\n        //Edge Face  no. 1\r\n        if (Math.abs(normals[index + 1]) < 0.001) {\r\n            face = 1;\r\n        }\r\n        //Top Face  no. 0\r\n        if (Math.abs(normals[index + 1] - 1) < 0.001) {\r\n            face = 0;\r\n        }\r\n        //Bottom Face  no. 2\r\n        if (Math.abs(normals[index + 1] + 1) < 0.001) {\r\n            face = 2;\r\n        }\r\n        idx = index / 3;\r\n        if (face === 1) {\r\n            disp = idx - startIndex;\r\n            if (disp % 4 < 1.5) {\r\n                if (wrap) {\r\n                    uvs[2 * idx] = faceUV[face].x + ((faceUV[face].z - faceUV[face].x) * cumulate[Math.floor(disp / 4)]) / totalLen;\r\n                } else {\r\n                    uvs[2 * idx] = faceUV[face].x;\r\n                }\r\n            } else {\r\n                if (wrap) {\r\n                    uvs[2 * idx] = faceUV[face].x + ((faceUV[face].z - faceUV[face].x) * cumulate[Math.floor(disp / 4) + 1]) / totalLen;\r\n                } else {\r\n                    uvs[2 * idx] = faceUV[face].z;\r\n                }\r\n            }\r\n            if (disp % 2 === 0) {\r\n                uvs[2 * idx + 1] = useOpenGLOrientationForUV ? 1.0 - faceUV[face].w : faceUV[face].w;\r\n            } else {\r\n                uvs[2 * idx + 1] = useOpenGLOrientationForUV ? 1.0 - faceUV[face].y : faceUV[face].y;\r\n            }\r\n        } else {\r\n            uvs[2 * idx] = (1 - uvs[2 * idx]) * faceUV[face].x + uvs[2 * idx] * faceUV[face].z;\r\n            uvs[2 * idx + 1] = (1 - uvs[2 * idx + 1]) * faceUV[face].y + uvs[2 * idx + 1] * faceUV[face].w;\r\n\r\n            if (useOpenGLOrientationForUV) {\r\n                uvs[2 * idx + 1] = 1.0 - uvs[2 * idx + 1];\r\n            }\r\n        }\r\n        if (faceColors) {\r\n            colors.push(faceColors[face].r, faceColors[face].g, faceColors[face].b, faceColors[face].a);\r\n        }\r\n    }\r\n\r\n    // sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, frontUVs, backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n\r\n    if (faceColors) {\r\n        const totalColors = sideOrientation === VertexData.DOUBLESIDE ? colors.concat(colors) : colors;\r\n        vertexData.colors = totalColors;\r\n    }\r\n\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a polygon mesh\r\n * The polygon's shape will depend on the input parameters and is constructed parallel to a ground mesh\r\n * * The parameter `shape` is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors\r\n * * You can set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4)\r\n * * Remember you can only change the shape positions, not their number when updating a polygon\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @param earcutInjection can be used to inject your own earcut reference\r\n * @returns the polygon mesh\r\n */\r\nexport function CreatePolygon(\r\n    name: string,\r\n    options: {\r\n        shape: Vector3[];\r\n        holes?: Vector3[][];\r\n        depth?: number;\r\n        smoothingThreshold?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        wrap?: boolean;\r\n    },\r\n    scene: Nullable<Scene> = null,\r\n    earcutInjection = earcut\r\n): Mesh {\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    const shape = options.shape;\r\n    const holes = options.holes || [];\r\n    const depth = options.depth || 0;\r\n    const smoothingThreshold = options.smoothingThreshold || 2;\r\n    const contours: Array<Vector2> = [];\r\n    let hole: Array<Vector2>;\r\n\r\n    for (let i = 0; i < shape.length; i++) {\r\n        contours[i] = new Vector2(shape[i].x, shape[i].z);\r\n    }\r\n    const epsilon = 0.00000001;\r\n    if (contours[0].equalsWithEpsilon(contours[contours.length - 1], epsilon)) {\r\n        contours.pop();\r\n    }\r\n\r\n    const polygonTriangulation = new PolygonMeshBuilder(name, contours, scene || EngineStore.LastCreatedScene!, earcutInjection);\r\n    for (let hNb = 0; hNb < holes.length; hNb++) {\r\n        hole = [];\r\n        for (let hPoint = 0; hPoint < holes[hNb].length; hPoint++) {\r\n            hole.push(new Vector2(holes[hNb][hPoint].x, holes[hNb][hPoint].z));\r\n        }\r\n        polygonTriangulation.addHole(hole);\r\n    }\r\n    //updatability is set during applyToMesh; setting to true in triangulation build produces errors\r\n    const polygon = polygonTriangulation.build(false, depth, smoothingThreshold);\r\n    polygon._originalBuilderSideOrientation = options.sideOrientation;\r\n    const vertexData = CreatePolygonVertexData(polygon, options.sideOrientation, options.faceUV, options.faceColors, options.frontUVs, options.backUVs, options.wrap);\r\n    vertexData.applyToMesh(polygon, options.updatable);\r\n\r\n    return polygon;\r\n}\r\n\r\n/**\r\n * Creates an extruded polygon mesh, with depth in the Y direction.\r\n * * You can set different colors and different images to the top, bottom and extruded side by using the parameters `faceColors` (an array of 3 Color3 elements) and `faceUV` (an array of 3 Vector4 elements)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/texturePerBoxFace\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @param earcutInjection can be used to inject your own earcut reference\r\n * @returns the polygon mesh\r\n */\r\nexport function ExtrudePolygon(\r\n    name: string,\r\n    options: {\r\n        shape: Vector3[];\r\n        holes?: Vector3[][];\r\n        depth?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        wrap?: boolean;\r\n    },\r\n    scene: Nullable<Scene> = null,\r\n    earcutInjection = earcut\r\n): Mesh {\r\n    return CreatePolygon(name, options, scene, earcutInjection);\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the functions directly from the module\r\n */\r\nexport const PolygonBuilder = {\r\n    ExtrudePolygon,\r\n    CreatePolygon,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for polygonBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPolygonBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreatePolygon = CreatePolygonVertexData;\r\n\r\n    Mesh.CreatePolygon = (name: string, shape: Vector3[], scene: Scene, holes?: Vector3[][], updatable?: boolean, sideOrientation?: number, earcutInjection = earcut): Mesh => {\r\n        const options = {\r\n            shape: shape,\r\n            holes: holes,\r\n            updatable: updatable,\r\n            sideOrientation: sideOrientation,\r\n        };\r\n        return CreatePolygon(name, options, scene, earcutInjection);\r\n    };\r\n\r\n    Mesh.ExtrudePolygon = (\r\n        name: string,\r\n        shape: Vector3[],\r\n        depth: number,\r\n        scene: Scene,\r\n        holes?: Vector3[][],\r\n        updatable?: boolean,\r\n        sideOrientation?: number,\r\n        earcutInjection = earcut\r\n    ): Mesh => {\r\n        const options = {\r\n            shape: shape,\r\n            holes: holes,\r\n            depth: depth,\r\n            updatable: updatable,\r\n            sideOrientation: sideOrientation,\r\n        };\r\n        return ExtrudePolygon(name, options, scene, earcutInjection);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3, TmpVectors, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { CreateRibbon } from \"./ribbonBuilder.pure\";\r\nimport { Path3D } from \"../../Maths/math.path\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates an extruded shape mesh. The extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.\r\n * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis.\r\n * * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.\r\n * * The parameter `rotation` (float, default 0 radians) is the angle value to rotate the shape each step (each path point), from the former step (so rotation added each step) along the curve.\r\n * * The parameter `scale` (float, default 1) is the value to scale the shape.\r\n * * The parameter `closeShape` (boolean, default false) closes the shape when true, since v5.0.0.\r\n * * The parameter `closePath` (boolean, default false) closes the path when true and no caps, since v5.0.0.\r\n * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL\r\n * * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#extruded-shape\r\n * * Remember you can only change the shape or path point positions, not their number when updating an extruded shape.\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture.\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.\r\n * * The optional parameter `firstNormal` (Vector3) defines the direction of the first normal of the supplied path. Consider using this for any path that is straight, and particular for paths in the xy plane.\r\n * * The optional `adjustFrame` (boolean, default false) will cause the internally generated Path3D tangents, normals, and binormals to be adjusted so that a) they are always well-defined, and b) they do not reverse from one path point to the next. This prevents the extruded shape from being flipped and/or rotated with resulting mesh self-intersections. This is primarily useful for straight paths that can reverse direction.\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the extruded shape mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#extruded-shapes\r\n */\r\nexport function ExtrudeShape(\r\n    name: string,\r\n    options: {\r\n        shape: Vector3[];\r\n        path: Vector3[];\r\n        scale?: number;\r\n        rotation?: number;\r\n        closeShape?: boolean;\r\n        closePath?: boolean;\r\n        cap?: number;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        instance?: Mesh;\r\n        invertUV?: boolean;\r\n        firstNormal?: Vector3;\r\n        adjustFrame?: boolean;\r\n        capFunction?: Nullable<{ (shapePath: Vector3[]): Vector3[] }>;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const path = options.path;\r\n    const shape = options.shape;\r\n    const scale = options.scale || 1;\r\n    const rotation = options.rotation || 0;\r\n    const cap = options.cap === 0 ? 0 : options.cap || Mesh.NO_CAP;\r\n    const updatable = options.updatable;\r\n    const sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    const instance = options.instance || null;\r\n    const invertUV = options.invertUV || false;\r\n    const closeShape = options.closeShape || false;\r\n    const closePath = options.closePath || false;\r\n    const capFunction = options.capFunction || null;\r\n\r\n    return ExtrudeShapeGeneric(\r\n        name,\r\n        shape,\r\n        path,\r\n        scale,\r\n        rotation,\r\n        null,\r\n        null,\r\n        closePath,\r\n        closeShape,\r\n        cap,\r\n        false,\r\n        scene,\r\n        updatable ? true : false,\r\n        sideOrientation,\r\n        instance,\r\n        invertUV,\r\n        options.frontUVs || null,\r\n        options.backUVs || null,\r\n        options.firstNormal || null,\r\n        options.adjustFrame ? true : false,\r\n        capFunction\r\n    );\r\n}\r\n\r\n/**\r\n * Creates an custom extruded shape mesh.\r\n * The custom extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.\r\n * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis.\r\n * * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.\r\n * * The parameter `rotationFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path and the distance of this point from the beginning of the path\r\n * * It must returns a float value that will be the rotation in radians applied to the shape on each path point.\r\n * * The parameter `scaleFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path and the distance of this point from the beginning of the path\r\n * * The parameter `scaleVectorFunction` (JS function) has the same purpose as `scaleFunction` but instead of returning a float it returns a Vector3 to allow non uniform scaling. If provided, it takes precedence over `scaleFunction`.\r\n * * It must returns a float value that will be the scale value applied to the shape on each path point\r\n * * The parameter `closeShape` (boolean, default false) closes the shape when true, since v5.0.0.\r\n * * The parameter `closePath` (boolean, default false) closes the path when true and no caps, since v5.0.0.\r\n * * The parameter `ribbonClosePath` (boolean, default false) forces the extrusion underlying ribbon to close all the paths in its `pathArray` - depreciated in favor of closeShape\r\n * * The parameter `ribbonCloseArray` (boolean, default false) forces the extrusion underlying ribbon to close its `pathArray` - depreciated in favor of closePath\r\n * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL\r\n * * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#extruded-shape\r\n * * Remember you can only change the shape or path point positions, not their number when updating an extruded shape\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * * The optional parameter `firstNormal` (Vector3) defines the direction of the first normal of the supplied path. It should be supplied when the path is in the xy plane, and particularly if these sections are straight, because the underlying Path3D object will pick a normal in the xy plane that causes the extrusion to be collapsed into the plane. This should be used for any path that is straight.\r\n * * The optional `adjustFrame` (boolean, default false) will cause the internally generated Path3D tangents, normals, and binormals to be adjusted so that a) they are always well-defined, and b) they do not reverse from one path point to the next. This prevents the extruded shape from being flipped and/or rotated with resulting mesh self-intersections. This is primarily useful for straight paths that can reverse direction.\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the custom extruded shape mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#custom-extruded-shapes\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#extruded-shapes\r\n */\r\nexport function ExtrudeShapeCustom(\r\n    name: string,\r\n    options: {\r\n        shape: Vector3[];\r\n        path: Vector3[];\r\n        scaleFunction?: Nullable<{ (i: number, distance: number): number }>;\r\n        scaleVectorFunction?: Nullable<{ (i: number, distance: number): Vector3 }>;\r\n        rotationFunction?: Nullable<{ (i: number, distance: number): number }>;\r\n        ribbonCloseArray?: boolean;\r\n        ribbonClosePath?: boolean;\r\n        closeShape?: boolean;\r\n        closePath?: boolean;\r\n        cap?: number;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        instance?: Mesh;\r\n        invertUV?: boolean;\r\n        firstNormal?: Vector3;\r\n        adjustFrame?: boolean;\r\n        capFunction?: Nullable<{ (shapePath: Vector3[]): Vector3[] }>;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const path = options.path;\r\n    const shape = options.shape;\r\n    const tmpVector3 = Vector3.Zero();\r\n    const scaleFunction = (i: number, distance: number) => {\r\n        const s = options.scaleFunction?.(i, distance) ?? 1;\r\n        return tmpVector3.copyFromFloats(s, s, s);\r\n    };\r\n    const rotationFunction =\r\n        options.rotationFunction ||\r\n        (() => {\r\n            return 0;\r\n        });\r\n    const ribbonCloseArray = options.closePath || options.ribbonCloseArray || false;\r\n    const ribbonClosePath = options.closeShape || options.ribbonClosePath || false;\r\n    const cap = options.cap === 0 ? 0 : options.cap || Mesh.NO_CAP;\r\n    const updatable = options.updatable;\r\n    const firstNormal = options.firstNormal || null;\r\n    const adjustFrame = options.adjustFrame || false;\r\n    const sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    const instance = options.instance;\r\n    const invertUV = options.invertUV || false;\r\n    const capFunction = options.capFunction || null;\r\n    return ExtrudeShapeGeneric(\r\n        name,\r\n        shape,\r\n        path,\r\n        null,\r\n        null,\r\n        options.scaleVectorFunction ?? scaleFunction,\r\n        rotationFunction,\r\n        ribbonCloseArray,\r\n        ribbonClosePath,\r\n        cap,\r\n        true,\r\n        scene,\r\n        updatable ? true : false,\r\n        sideOrientation,\r\n        instance || null,\r\n        invertUV,\r\n        options.frontUVs || null,\r\n        options.backUVs || null,\r\n        firstNormal,\r\n        adjustFrame,\r\n        capFunction || null\r\n    );\r\n}\r\n\r\nfunction ExtrudeShapeGeneric(\r\n    name: string,\r\n    shape: Vector3[],\r\n    curve: Vector3[],\r\n    scale: Nullable<number>,\r\n    rotation: Nullable<number>,\r\n    scaleFunction: Nullable<{ (i: number, distance: number): Vector3 }>,\r\n    rotateFunction: Nullable<{ (i: number, distance: number): number }>,\r\n    rbCA: boolean,\r\n    rbCP: boolean,\r\n    cap: number,\r\n    custom: boolean,\r\n    scene: Nullable<Scene>,\r\n    updtbl: boolean,\r\n    side: number,\r\n    instance: Nullable<Mesh>,\r\n    invertUV: boolean,\r\n    frontUVs: Nullable<Vector4>,\r\n    backUVs: Nullable<Vector4>,\r\n    firstNormal: Nullable<Vector3>,\r\n    adjustFrame: boolean,\r\n    capFunction: Nullable<{ (shapePath: Vector3[]): Vector3[] }>\r\n): Mesh {\r\n    // extrusion geometry\r\n    const extrusionPathArray = (\r\n        shape: Vector3[],\r\n        curve: Vector3[],\r\n        path3D: Path3D,\r\n        shapePaths: Vector3[][],\r\n        scale: Nullable<Vector3>,\r\n        rotation: Nullable<number>,\r\n        scaleFunction: Nullable<{ (i: number, distance: number): Vector3 }>,\r\n        rotateFunction: Nullable<{ (i: number, distance: number): number }>,\r\n        cap: number,\r\n        custom: boolean,\r\n        adjustFrame: boolean\r\n    ) => {\r\n        const tangents = path3D.getTangents();\r\n        const normals = path3D.getNormals();\r\n        const binormals = path3D.getBinormals();\r\n        const distances = path3D.getDistances();\r\n        if (adjustFrame) {\r\n            /* fix tangents,normals, binormals */\r\n            for (let i = 0; i < tangents.length; i++) {\r\n                if (tangents[i].x == 0 && tangents[i].y == 0 && tangents[i].z == 0) {\r\n                    tangents[i].copyFrom(tangents[i - 1]);\r\n                }\r\n                if (normals[i].x == 0 && normals[i].y == 0 && normals[i].z == 0) {\r\n                    normals[i].copyFrom(normals[i - 1]);\r\n                }\r\n                if (binormals[i].x == 0 && binormals[i].y == 0 && binormals[i].z == 0) {\r\n                    binormals[i].copyFrom(binormals[i - 1]);\r\n                }\r\n                if (i > 0) {\r\n                    let v = tangents[i - 1];\r\n                    if (Vector3.Dot(v, tangents[i]) < 0) {\r\n                        tangents[i].scaleInPlace(-1);\r\n                    }\r\n                    v = normals[i - 1];\r\n                    if (Vector3.Dot(v, normals[i]) < 0) {\r\n                        normals[i].scaleInPlace(-1);\r\n                    }\r\n                    v = binormals[i - 1];\r\n                    if (Vector3.Dot(v, binormals[i]) < 0) {\r\n                        binormals[i].scaleInPlace(-1);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        let angle = 0;\r\n        const returnScale = () => {\r\n            return scale !== null ? scale : Vector3.OneReadOnly;\r\n        };\r\n        const returnRotation = () => {\r\n            return rotation !== null ? rotation : 0;\r\n        };\r\n        const rotate: { (i: number, distance: number): number } = custom && rotateFunction ? rotateFunction : returnRotation;\r\n        const scl: { (i: number, distance: number): Vector3 } = custom && scaleFunction ? scaleFunction : returnScale;\r\n        let index = cap === Mesh.NO_CAP || cap === Mesh.CAP_END ? 0 : 2;\r\n        const rotationMatrix: Matrix = TmpVectors.Matrix[0];\r\n\r\n        for (let i = 0; i < curve.length; i++) {\r\n            const shapePath: Vector3[] = [];\r\n            const angleStep = rotate(i, distances[i]);\r\n            const scaleRatio = scl(i, distances[i]);\r\n            Matrix.RotationAxisToRef(tangents[i], angle, rotationMatrix);\r\n            for (let p = 0; p < shape.length; p++) {\r\n                const planed = tangents[i].scale(shape[p].z).add(normals[i].scale(shape[p].x)).add(binormals[i].scale(shape[p].y));\r\n                const rotated = Vector3.Zero();\r\n                Vector3.TransformCoordinatesToRef(planed, rotationMatrix, rotated);\r\n                rotated.multiplyInPlace(scaleRatio).addInPlace(curve[i]);\r\n                shapePath[p] = rotated;\r\n            }\r\n            shapePaths[index] = shapePath;\r\n            angle += angleStep;\r\n            index++;\r\n        }\r\n        // cap\r\n        const defaultCapPath = (shapePath: Vector3[]) => {\r\n            const pointCap = Array<Vector3>();\r\n            const barycenter = Vector3.Zero();\r\n            let i: number;\r\n            for (i = 0; i < shapePath.length; i++) {\r\n                barycenter.addInPlace(shapePath[i]);\r\n            }\r\n            barycenter.scaleInPlace(1.0 / shapePath.length);\r\n            for (i = 0; i < shapePath.length; i++) {\r\n                pointCap.push(barycenter);\r\n            }\r\n            return pointCap;\r\n        };\r\n        const capPath = capFunction || defaultCapPath;\r\n        switch (cap) {\r\n            case Mesh.NO_CAP:\r\n                break;\r\n            case Mesh.CAP_START:\r\n                shapePaths[0] = capPath(shapePaths[2]);\r\n                shapePaths[1] = shapePaths[2];\r\n                break;\r\n            case Mesh.CAP_END:\r\n                shapePaths[index] = shapePaths[index - 1];\r\n                shapePaths[index + 1] = capPath(shapePaths[index - 1]);\r\n                break;\r\n            case Mesh.CAP_ALL:\r\n                shapePaths[0] = capPath(shapePaths[2]);\r\n                shapePaths[1] = shapePaths[2];\r\n                shapePaths[index] = shapePaths[index - 1];\r\n                shapePaths[index + 1] = capPath(shapePaths[index - 1]);\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n        return shapePaths;\r\n    };\r\n    const scaleVector = scale !== null ? new Vector3(scale, scale, scale) : null;\r\n    let pathArray;\r\n    if (instance) {\r\n        // instance update\r\n        const storage = instance._creationDataStorage!;\r\n        firstNormal ? storage.path3D.update(curve, firstNormal) : storage.path3D.update(curve);\r\n        pathArray = extrusionPathArray(shape, curve, storage.path3D, storage.pathArray, scaleVector, rotation, scaleFunction, rotateFunction, storage.cap, custom, adjustFrame);\r\n        instance = CreateRibbon(\"\", { pathArray, closeArray: false, closePath: false, offset: 0, updatable: false, sideOrientation: 0, instance }, scene || undefined);\r\n\r\n        return instance;\r\n    }\r\n    // extruded shape creation\r\n    const path3D = firstNormal ? new Path3D(curve, firstNormal) : new Path3D(curve);\r\n    const newShapePaths = new Array<Array<Vector3>>();\r\n    cap = cap < 0 || cap > 3 ? 0 : cap;\r\n    pathArray = extrusionPathArray(shape, curve, path3D, newShapePaths, scaleVector, rotation, scaleFunction, rotateFunction, cap, custom, adjustFrame);\r\n    const extrudedGeneric = CreateRibbon(\r\n        name,\r\n        {\r\n            pathArray: pathArray,\r\n            closeArray: rbCA,\r\n            closePath: rbCP,\r\n            updatable: updtbl,\r\n            sideOrientation: side,\r\n            invertUV: invertUV,\r\n            frontUVs: frontUVs || undefined,\r\n            backUVs: backUVs || undefined,\r\n        },\r\n        scene\r\n    );\r\n    extrudedGeneric._creationDataStorage!.pathArray = pathArray;\r\n    extrudedGeneric._creationDataStorage!.path3D = path3D;\r\n    extrudedGeneric._creationDataStorage!.cap = cap;\r\n\r\n    return extrudedGeneric;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated please use the functions directly from the module\r\n */\r\nexport const ShapeBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    ExtrudeShape,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    ExtrudeShapeCustom,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for shapeBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterShapeBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh.ExtrudeShape = (\r\n        name: string,\r\n        shape: Vector3[],\r\n        path: Vector3[],\r\n        scale: number,\r\n        rotation: number,\r\n        cap: number,\r\n        scene: Nullable<Scene> = null,\r\n        updatable?: boolean,\r\n        sideOrientation?: number,\r\n        instance?: Mesh\r\n    ): Mesh => {\r\n        const options = {\r\n            shape: shape,\r\n            path: path,\r\n            scale: scale,\r\n            rotation: rotation,\r\n            cap: cap === 0 ? 0 : cap || Mesh.NO_CAP,\r\n            sideOrientation: sideOrientation,\r\n            instance: instance,\r\n            updatable: updatable,\r\n        };\r\n\r\n        return ExtrudeShape(name, options, scene);\r\n    };\r\n\r\n    Mesh.ExtrudeShapeCustom = (\r\n        name: string,\r\n        shape: Vector3[],\r\n        path: Vector3[],\r\n        scaleFunction: Nullable<{ (i: number, distance: number): number }>,\r\n        rotationFunction: Nullable<{ (i: number, distance: number): number }>,\r\n        ribbonCloseArray: boolean,\r\n        ribbonClosePath: boolean,\r\n        cap: number,\r\n        scene: Scene,\r\n        updatable?: boolean,\r\n        sideOrientation?: number,\r\n        instance?: Mesh\r\n    ): Mesh => {\r\n        const options = {\r\n            shape: shape,\r\n            path: path,\r\n            scaleFunction: scaleFunction,\r\n            rotationFunction: rotationFunction,\r\n            ribbonCloseArray: ribbonCloseArray,\r\n            ribbonClosePath: ribbonClosePath,\r\n            cap: cap === 0 ? 0 : cap || Mesh.NO_CAP,\r\n            sideOrientation: sideOrientation,\r\n            instance: instance,\r\n            updatable: updatable,\r\n        };\r\n\r\n        return ExtrudeShapeCustom(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { CreateRibbon } from \"./ribbonBuilder.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates lathe mesh.\r\n * The lathe is a shape with a symmetry axis : a 2D model shape is rotated around this axis to design the lathe\r\n * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be rotated in its local space : the shape must be designed in the xOy plane and will be rotated around the Y axis. It's usually a 2D shape, so the Vector3 z coordinates are often set to zero\r\n * * The parameter `radius` (positive float, default 1) is the radius value of the lathe\r\n * * The parameter `tessellation` (positive integer, default 64) is the side number of the lathe\r\n * * The parameter `clip` (positive integer, default 0) is the number of sides to not create without effecting the general shape of the sides\r\n * * The parameter `arc` (positive float, default 1) is the ratio of the lathe. 0.5 builds for instance half a lathe, so an opened shape\r\n * * The parameter `closed` (boolean, default true) opens/closes the lathe circumference. This should be set to false when used with the parameter \"arc\"\r\n * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the lathe mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param#lathe\r\n */\r\nexport function CreateLathe(\r\n    name: string,\r\n    options: {\r\n        shape: Vector3[];\r\n        radius?: number;\r\n        tessellation?: number;\r\n        clip?: number;\r\n        arc?: number;\r\n        closed?: boolean;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        cap?: number;\r\n        invertUV?: boolean;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const arc: number = options.arc ? (options.arc <= 0 || options.arc > 1 ? 1.0 : options.arc) : 1.0;\r\n    const closed: boolean = options.closed === undefined ? true : options.closed;\r\n    const shape = options.shape;\r\n    const radius = options.radius || 1;\r\n    const tessellation = options.tessellation || 64;\r\n    const clip = options.clip || 0;\r\n    const updatable = options.updatable;\r\n    const sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    const cap = options.cap || Mesh.NO_CAP;\r\n    const pi2 = Math.PI * 2;\r\n    const paths = [];\r\n    const invertUV = options.invertUV || false;\r\n\r\n    let i: number;\r\n    let p: number;\r\n    const step = (pi2 / tessellation) * arc;\r\n    let rotated;\r\n    let path: Array<Vector3>;\r\n    for (i = 0; i <= tessellation - clip; i++) {\r\n        path = [];\r\n        if (cap == Mesh.CAP_START || cap == Mesh.CAP_ALL) {\r\n            path.push(new Vector3(0, shape[0].y, 0));\r\n            path.push(new Vector3(Math.cos(i * step) * shape[0].x * radius, shape[0].y, Math.sin(i * step) * shape[0].x * radius));\r\n        }\r\n        for (p = 0; p < shape.length; p++) {\r\n            rotated = new Vector3(Math.cos(i * step) * shape[p].x * radius, shape[p].y, Math.sin(i * step) * shape[p].x * radius);\r\n            path.push(rotated);\r\n        }\r\n        if (cap == Mesh.CAP_END || cap == Mesh.CAP_ALL) {\r\n            path.push(new Vector3(Math.cos(i * step) * shape[shape.length - 1].x * radius, shape[shape.length - 1].y, Math.sin(i * step) * shape[shape.length - 1].x * radius));\r\n            path.push(new Vector3(0, shape[shape.length - 1].y, 0));\r\n        }\r\n        paths.push(path);\r\n    }\r\n\r\n    // lathe ribbon\r\n    const lathe = CreateRibbon(\r\n        name,\r\n        { pathArray: paths, closeArray: closed, sideOrientation: sideOrientation, updatable: updatable, invertUV: invertUV, frontUVs: options.frontUVs, backUVs: options.backUVs },\r\n        scene\r\n    );\r\n    return lathe;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the function direction from the module\r\n */\r\nexport const LatheBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateLathe,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for latheBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLatheBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh.CreateLathe = (name: string, shape: Vector3[], radius: number, tessellation: number, scene: Scene, updatable?: boolean, sideOrientation?: number): Mesh => {\r\n        const options = {\r\n            shape: shape,\r\n            radius: radius,\r\n            tessellation: tessellation,\r\n            sideOrientation: sideOrientation,\r\n            updatable: updatable,\r\n        };\r\n\r\n        return CreateLathe(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { Vector3, TmpVectors, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { CreateRibbon } from \"./ribbonBuilder.pure\";\r\nimport { Path3D } from \"../../Maths/math.path\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates a tube mesh.\r\n * The tube is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters\r\n * * The parameter `path` is a required array of successive Vector3. It is the curve used as the axis of the tube\r\n * * The parameter `radius` (positive float, default 1) sets the tube radius size\r\n * * The parameter `tessellation` (positive float, default 64) is the number of sides on the tubular surface\r\n * * The parameter `radiusFunction` (javascript function, default null) is a vanilla javascript function. If it is not null, it overrides the parameter `radius`\r\n * * This function is called on each point of the tube path and is passed the index `i` of the i-th point and the distance of this point from the first point of the path. It must return a radius value (positive float)\r\n * * The parameter `arc` (positive float, maximum 1, default 1) is the ratio to apply to the tube circumference : 2 x PI x arc\r\n * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL\r\n * * The optional parameter `instance` is an instance of an existing Tube object to be updated with the passed `pathArray` parameter. The `path`Array HAS to have the SAME number of points as the previous one: https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph#tube\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created. The NUMBER of points CAN'T CHANGE, only their positions.\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the tube mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#tube\r\n */\r\nexport function CreateTube(\r\n    name: string,\r\n    options: {\r\n        path: Vector3[];\r\n        radius?: number;\r\n        tessellation?: number;\r\n        radiusFunction?: { (i: number, distance: number): number };\r\n        cap?: number;\r\n        arc?: number;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        instance?: Mesh;\r\n        invertUV?: boolean;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const path = options.path;\r\n    let instance = options.instance;\r\n    let radius = 1.0;\r\n\r\n    if (options.radius !== undefined) {\r\n        radius = options.radius;\r\n    } else if (instance) {\r\n        radius = instance._creationDataStorage!.radius;\r\n    }\r\n\r\n    const tessellation = options.tessellation || 64 | 0;\r\n    const radiusFunction = options.radiusFunction || null;\r\n    let cap = options.cap || Mesh.NO_CAP;\r\n    const invertUV = options.invertUV || false;\r\n    const updatable = options.updatable;\r\n    const sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    options.arc = options.arc && (options.arc <= 0.0 || options.arc > 1.0) ? 1.0 : options.arc || 1.0;\r\n\r\n    // tube geometry\r\n    const tubePathArray = (\r\n        path: Vector3[],\r\n        path3D: Path3D,\r\n        circlePaths: Vector3[][],\r\n        radius: number,\r\n        tessellation: number,\r\n        radiusFunction: Nullable<{ (i: number, distance: number): number }>,\r\n        cap: number,\r\n        arc: number\r\n    ) => {\r\n        const tangents = path3D.getTangents();\r\n        const normals = path3D.getNormals();\r\n        const distances = path3D.getDistances();\r\n        const pi2 = Math.PI * 2;\r\n        const step = (pi2 / tessellation) * arc;\r\n        const returnRadius: { (i: number, distance: number): number } = () => radius;\r\n        const radiusFunctionFinal: { (i: number, distance: number): number } = radiusFunction || returnRadius;\r\n\r\n        let circlePath: Vector3[];\r\n        let rad: number;\r\n        let normal: Vector3;\r\n        let rotated: Vector3;\r\n        const rotationMatrix: Matrix = TmpVectors.Matrix[0];\r\n        let index = cap === Mesh.NO_CAP || cap === Mesh.CAP_END ? 0 : 2;\r\n        for (let i = 0; i < path.length; i++) {\r\n            rad = radiusFunctionFinal(i, distances[i]); // current radius\r\n            circlePath = Array<Vector3>(); // current circle array\r\n            normal = normals[i]; // current normal\r\n            for (let t = 0; t < tessellation; t++) {\r\n                Matrix.RotationAxisToRef(tangents[i], step * t, rotationMatrix);\r\n                rotated = circlePath[t] ? circlePath[t] : Vector3.Zero();\r\n                Vector3.TransformCoordinatesToRef(normal, rotationMatrix, rotated);\r\n                rotated.scaleInPlace(rad).addInPlace(path[i]);\r\n                circlePath[t] = rotated;\r\n            }\r\n            circlePaths[index] = circlePath;\r\n            index++;\r\n        }\r\n        // cap\r\n        const capPath = (nbPoints: number, pathIndex: number): Array<Vector3> => {\r\n            const pointCap = Array<Vector3>();\r\n            for (let i = 0; i < nbPoints; i++) {\r\n                pointCap.push(path[pathIndex]);\r\n            }\r\n            return pointCap;\r\n        };\r\n        switch (cap) {\r\n            case Mesh.NO_CAP:\r\n                break;\r\n            case Mesh.CAP_START:\r\n                circlePaths[0] = capPath(tessellation, 0);\r\n                circlePaths[1] = circlePaths[2].slice(0);\r\n                break;\r\n            case Mesh.CAP_END:\r\n                circlePaths[index] = circlePaths[index - 1].slice(0);\r\n                circlePaths[index + 1] = capPath(tessellation, path.length - 1);\r\n                break;\r\n            case Mesh.CAP_ALL:\r\n                circlePaths[0] = capPath(tessellation, 0);\r\n                circlePaths[1] = circlePaths[2].slice(0);\r\n                circlePaths[index] = circlePaths[index - 1].slice(0);\r\n                circlePaths[index + 1] = capPath(tessellation, path.length - 1);\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n        return circlePaths;\r\n    };\r\n\r\n    let path3D;\r\n    let pathArray;\r\n    if (instance) {\r\n        // tube update\r\n        const storage = instance._creationDataStorage!;\r\n        const arc = options.arc || storage.arc;\r\n        path3D = storage.path3D.update(path);\r\n        pathArray = tubePathArray(path, path3D, storage.pathArray, radius, storage.tessellation, radiusFunction, storage.cap, arc);\r\n        instance = CreateRibbon(\"\", { pathArray: pathArray, instance: instance });\r\n        // Update mode, no need to recreate the storage.\r\n        storage.path3D = path3D;\r\n        storage.pathArray = pathArray;\r\n        storage.arc = arc;\r\n        storage.radius = radius;\r\n\r\n        return instance;\r\n    }\r\n\r\n    // tube creation\r\n    path3D = <any>new Path3D(path);\r\n    const newPathArray = new Array<Array<Vector3>>();\r\n    cap = cap < 0 || cap > 3 ? 0 : cap;\r\n    pathArray = tubePathArray(path, path3D, newPathArray, radius, tessellation, radiusFunction, cap, options.arc);\r\n    const tube = CreateRibbon(\r\n        name,\r\n        {\r\n            pathArray: pathArray,\r\n            closePath: true,\r\n            closeArray: false,\r\n            updatable: updatable,\r\n            sideOrientation: sideOrientation,\r\n            invertUV: invertUV,\r\n            frontUVs: options.frontUVs,\r\n            backUVs: options.backUVs,\r\n        },\r\n        scene\r\n    );\r\n    tube._creationDataStorage!.pathArray = pathArray;\r\n    tube._creationDataStorage!.path3D = path3D;\r\n    tube._creationDataStorage!.tessellation = tessellation;\r\n    tube._creationDataStorage!.cap = cap;\r\n    tube._creationDataStorage!.arc = options.arc;\r\n    tube._creationDataStorage!.radius = radius;\r\n\r\n    return tube;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use CreateTube directly\r\n */\r\nexport const TubeBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateTube,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for tubeBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTubeBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh.CreateTube = (\r\n        name: string,\r\n        path: Vector3[],\r\n        radius: number,\r\n        tessellation: number,\r\n        radiusFunction: { (i: number, distance: number): number },\r\n        cap: number,\r\n        scene: Scene,\r\n        updatable?: boolean,\r\n        sideOrientation?: number,\r\n        instance?: Mesh\r\n    ): Mesh => {\r\n        const options = {\r\n            path: path,\r\n            radius: radius,\r\n            tessellation: tessellation,\r\n            radiusFunction: radiusFunction,\r\n            arc: 1,\r\n            cap: cap,\r\n            updatable: updatable,\r\n            sideOrientation: sideOrientation,\r\n            instance: instance,\r\n        };\r\n        return CreateTube(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n// inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html\r\n/**\r\n * Creates the VertexData for a Polyhedron\r\n * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty\r\n * * type provided types are:\r\n *  * 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)\r\n *  * 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)\r\n * * size the size of the IcoSphere, optional default 1\r\n * * sizeX allows stretching in the x direction, optional, default size\r\n * * sizeY allows stretching in the y direction, optional, default size\r\n * * sizeZ allows stretching in the z direction, optional, default size\r\n * * custom a number that overwrites the type to create from an extended set of polyhedron from https://www.babylonjs-playground.com/#21QRSK#15 with minimised editor\r\n * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n * * flat when true creates a flat shaded mesh, optional, default true\r\n * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the Polyhedron\r\n */\r\nexport function CreatePolyhedronVertexData(options: {\r\n    type?: number;\r\n    size?: number;\r\n    sizeX?: number;\r\n    sizeY?: number;\r\n    sizeZ?: number;\r\n    custom?: any;\r\n    faceUV?: Vector4[];\r\n    faceColors?: Color4[];\r\n    flat?: boolean;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n}): VertexData {\r\n    // provided polyhedron types :\r\n    // 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)\r\n    // 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)\r\n    const polyhedra: { vertex: number[][]; face: number[][] }[] = [];\r\n    polyhedra[0] = {\r\n        vertex: [\r\n            [0, 0, 1.732051],\r\n            [1.632993, 0, -0.5773503],\r\n            [-0.8164966, 1.414214, -0.5773503],\r\n            [-0.8164966, -1.414214, -0.5773503],\r\n        ],\r\n        face: [\r\n            [0, 1, 2],\r\n            [0, 2, 3],\r\n            [0, 3, 1],\r\n            [1, 3, 2],\r\n        ],\r\n    };\r\n    polyhedra[1] = {\r\n        vertex: [\r\n            [0, 0, 1.414214],\r\n            [1.414214, 0, 0],\r\n            [0, 1.414214, 0],\r\n            [-1.414214, 0, 0],\r\n            [0, -1.414214, 0],\r\n            [0, 0, -1.414214],\r\n        ],\r\n        face: [\r\n            [0, 1, 2],\r\n            [0, 2, 3],\r\n            [0, 3, 4],\r\n            [0, 4, 1],\r\n            [1, 4, 5],\r\n            [1, 5, 2],\r\n            [2, 5, 3],\r\n            [3, 5, 4],\r\n        ],\r\n    };\r\n    polyhedra[2] = {\r\n        vertex: [\r\n            [0, 0, 1.070466],\r\n            [0.7136442, 0, 0.7978784],\r\n            [-0.3568221, 0.618034, 0.7978784],\r\n            [-0.3568221, -0.618034, 0.7978784],\r\n            [0.7978784, 0.618034, 0.3568221],\r\n            [0.7978784, -0.618034, 0.3568221],\r\n            [-0.9341724, 0.381966, 0.3568221],\r\n            [0.1362939, 1, 0.3568221],\r\n            [0.1362939, -1, 0.3568221],\r\n            [-0.9341724, -0.381966, 0.3568221],\r\n            [0.9341724, 0.381966, -0.3568221],\r\n            [0.9341724, -0.381966, -0.3568221],\r\n            [-0.7978784, 0.618034, -0.3568221],\r\n            [-0.1362939, 1, -0.3568221],\r\n            [-0.1362939, -1, -0.3568221],\r\n            [-0.7978784, -0.618034, -0.3568221],\r\n            [0.3568221, 0.618034, -0.7978784],\r\n            [0.3568221, -0.618034, -0.7978784],\r\n            [-0.7136442, 0, -0.7978784],\r\n            [0, 0, -1.070466],\r\n        ],\r\n        face: [\r\n            [0, 1, 4, 7, 2],\r\n            [0, 2, 6, 9, 3],\r\n            [0, 3, 8, 5, 1],\r\n            [1, 5, 11, 10, 4],\r\n            [2, 7, 13, 12, 6],\r\n            [3, 9, 15, 14, 8],\r\n            [4, 10, 16, 13, 7],\r\n            [5, 8, 14, 17, 11],\r\n            [6, 12, 18, 15, 9],\r\n            [10, 11, 17, 19, 16],\r\n            [12, 13, 16, 19, 18],\r\n            [14, 15, 18, 19, 17],\r\n        ],\r\n    };\r\n    polyhedra[3] = {\r\n        vertex: [\r\n            [0, 0, 1.175571],\r\n            [1.051462, 0, 0.5257311],\r\n            [0.3249197, 1, 0.5257311],\r\n            [-0.8506508, 0.618034, 0.5257311],\r\n            [-0.8506508, -0.618034, 0.5257311],\r\n            [0.3249197, -1, 0.5257311],\r\n            [0.8506508, 0.618034, -0.5257311],\r\n            [0.8506508, -0.618034, -0.5257311],\r\n            [-0.3249197, 1, -0.5257311],\r\n            [-1.051462, 0, -0.5257311],\r\n            [-0.3249197, -1, -0.5257311],\r\n            [0, 0, -1.175571],\r\n        ],\r\n        face: [\r\n            [0, 1, 2],\r\n            [0, 2, 3],\r\n            [0, 3, 4],\r\n            [0, 4, 5],\r\n            [0, 5, 1],\r\n            [1, 5, 7],\r\n            [1, 7, 6],\r\n            [1, 6, 2],\r\n            [2, 6, 8],\r\n            [2, 8, 3],\r\n            [3, 8, 9],\r\n            [3, 9, 4],\r\n            [4, 9, 10],\r\n            [4, 10, 5],\r\n            [5, 10, 7],\r\n            [6, 7, 11],\r\n            [6, 11, 8],\r\n            [7, 10, 11],\r\n            [8, 11, 9],\r\n            [9, 11, 10],\r\n        ],\r\n    };\r\n    polyhedra[4] = {\r\n        vertex: [\r\n            [0, 0, 1.070722],\r\n            [0.7148135, 0, 0.7971752],\r\n            [-0.104682, 0.7071068, 0.7971752],\r\n            [-0.6841528, 0.2071068, 0.7971752],\r\n            [-0.104682, -0.7071068, 0.7971752],\r\n            [0.6101315, 0.7071068, 0.5236279],\r\n            [1.04156, 0.2071068, 0.1367736],\r\n            [0.6101315, -0.7071068, 0.5236279],\r\n            [-0.3574067, 1, 0.1367736],\r\n            [-0.7888348, -0.5, 0.5236279],\r\n            [-0.9368776, 0.5, 0.1367736],\r\n            [-0.3574067, -1, 0.1367736],\r\n            [0.3574067, 1, -0.1367736],\r\n            [0.9368776, -0.5, -0.1367736],\r\n            [0.7888348, 0.5, -0.5236279],\r\n            [0.3574067, -1, -0.1367736],\r\n            [-0.6101315, 0.7071068, -0.5236279],\r\n            [-1.04156, -0.2071068, -0.1367736],\r\n            [-0.6101315, -0.7071068, -0.5236279],\r\n            [0.104682, 0.7071068, -0.7971752],\r\n            [0.6841528, -0.2071068, -0.7971752],\r\n            [0.104682, -0.7071068, -0.7971752],\r\n            [-0.7148135, 0, -0.7971752],\r\n            [0, 0, -1.070722],\r\n        ],\r\n        face: [\r\n            [0, 2, 3],\r\n            [1, 6, 5],\r\n            [4, 9, 11],\r\n            [7, 15, 13],\r\n            [8, 16, 10],\r\n            [12, 14, 19],\r\n            [17, 22, 18],\r\n            [20, 21, 23],\r\n            [0, 1, 5, 2],\r\n            [0, 3, 9, 4],\r\n            [0, 4, 7, 1],\r\n            [1, 7, 13, 6],\r\n            [2, 5, 12, 8],\r\n            [2, 8, 10, 3],\r\n            [3, 10, 17, 9],\r\n            [4, 11, 15, 7],\r\n            [5, 6, 14, 12],\r\n            [6, 13, 20, 14],\r\n            [8, 12, 19, 16],\r\n            [9, 17, 18, 11],\r\n            [10, 16, 22, 17],\r\n            [11, 18, 21, 15],\r\n            [13, 15, 21, 20],\r\n            [14, 20, 23, 19],\r\n            [16, 19, 23, 22],\r\n            [18, 22, 23, 21],\r\n        ],\r\n    };\r\n    polyhedra[5] = {\r\n        vertex: [\r\n            [0, 0, 1.322876],\r\n            [1.309307, 0, 0.1889822],\r\n            [-0.9819805, 0.8660254, 0.1889822],\r\n            [0.1636634, -1.299038, 0.1889822],\r\n            [0.3273268, 0.8660254, -0.9449112],\r\n            [-0.8183171, -0.4330127, -0.9449112],\r\n        ],\r\n        face: [\r\n            [0, 3, 1],\r\n            [2, 4, 5],\r\n            [0, 1, 4, 2],\r\n            [0, 2, 5, 3],\r\n            [1, 3, 5, 4],\r\n        ],\r\n    };\r\n    polyhedra[6] = {\r\n        vertex: [\r\n            [0, 0, 1.159953],\r\n            [1.013464, 0, 0.5642542],\r\n            [-0.3501431, 0.9510565, 0.5642542],\r\n            [-0.7715208, -0.6571639, 0.5642542],\r\n            [0.6633206, 0.9510565, -0.03144481],\r\n            [0.8682979, -0.6571639, -0.3996071],\r\n            [-1.121664, 0.2938926, -0.03144481],\r\n            [-0.2348831, -1.063314, -0.3996071],\r\n            [0.5181548, 0.2938926, -0.9953061],\r\n            [-0.5850262, -0.112257, -0.9953061],\r\n        ],\r\n        face: [\r\n            [0, 1, 4, 2],\r\n            [0, 2, 6, 3],\r\n            [1, 5, 8, 4],\r\n            [3, 6, 9, 7],\r\n            [5, 7, 9, 8],\r\n            [0, 3, 7, 5, 1],\r\n            [2, 4, 8, 9, 6],\r\n        ],\r\n    };\r\n    polyhedra[7] = {\r\n        vertex: [\r\n            [0, 0, 1.118034],\r\n            [0.8944272, 0, 0.6708204],\r\n            [-0.2236068, 0.8660254, 0.6708204],\r\n            [-0.7826238, -0.4330127, 0.6708204],\r\n            [0.6708204, 0.8660254, 0.2236068],\r\n            [1.006231, -0.4330127, -0.2236068],\r\n            [-1.006231, 0.4330127, 0.2236068],\r\n            [-0.6708204, -0.8660254, -0.2236068],\r\n            [0.7826238, 0.4330127, -0.6708204],\r\n            [0.2236068, -0.8660254, -0.6708204],\r\n            [-0.8944272, 0, -0.6708204],\r\n            [0, 0, -1.118034],\r\n        ],\r\n        face: [\r\n            [0, 1, 4, 2],\r\n            [0, 2, 6, 3],\r\n            [1, 5, 8, 4],\r\n            [3, 6, 10, 7],\r\n            [5, 9, 11, 8],\r\n            [7, 10, 11, 9],\r\n            [0, 3, 7, 9, 5, 1],\r\n            [2, 4, 8, 11, 10, 6],\r\n        ],\r\n    };\r\n    polyhedra[8] = {\r\n        vertex: [\r\n            [-0.729665, 0.670121, 0.319155],\r\n            [-0.655235, -0.29213, -0.754096],\r\n            [-0.093922, -0.607123, 0.537818],\r\n            [0.702196, 0.595691, 0.485187],\r\n            [0.776626, -0.36656, -0.588064],\r\n        ],\r\n        face: [\r\n            [1, 4, 2],\r\n            [0, 1, 2],\r\n            [3, 0, 2],\r\n            [4, 3, 2],\r\n            [4, 1, 0, 3],\r\n        ],\r\n    };\r\n    polyhedra[9] = {\r\n        vertex: [\r\n            [-0.868849, -0.100041, 0.61257],\r\n            [-0.329458, 0.976099, 0.28078],\r\n            [-0.26629, -0.013796, -0.477654],\r\n            [-0.13392, -1.034115, 0.229829],\r\n            [0.738834, 0.707117, -0.307018],\r\n            [0.859683, -0.535264, -0.338508],\r\n        ],\r\n        face: [\r\n            [3, 0, 2],\r\n            [5, 3, 2],\r\n            [4, 5, 2],\r\n            [1, 4, 2],\r\n            [0, 1, 2],\r\n            [0, 3, 5, 4, 1],\r\n        ],\r\n    };\r\n    polyhedra[10] = {\r\n        vertex: [\r\n            [-0.610389, 0.243975, 0.531213],\r\n            [-0.187812, -0.48795, -0.664016],\r\n            [-0.187812, 0.9759, -0.664016],\r\n            [0.187812, -0.9759, 0.664016],\r\n            [0.798201, 0.243975, 0.132803],\r\n        ],\r\n        face: [\r\n            [1, 3, 0],\r\n            [3, 4, 0],\r\n            [3, 1, 4],\r\n            [0, 2, 1],\r\n            [0, 4, 2],\r\n            [2, 4, 1],\r\n        ],\r\n    };\r\n    polyhedra[11] = {\r\n        vertex: [\r\n            [-1.028778, 0.392027, -0.048786],\r\n            [-0.640503, -0.646161, 0.621837],\r\n            [-0.125162, -0.395663, -0.540059],\r\n            [0.004683, 0.888447, -0.651988],\r\n            [0.125161, 0.395663, 0.540059],\r\n            [0.632925, -0.791376, 0.433102],\r\n            [1.031672, 0.157063, -0.354165],\r\n        ],\r\n        face: [\r\n            [3, 2, 0],\r\n            [2, 1, 0],\r\n            [2, 5, 1],\r\n            [0, 4, 3],\r\n            [0, 1, 4],\r\n            [4, 1, 5],\r\n            [2, 3, 6],\r\n            [3, 4, 6],\r\n            [5, 2, 6],\r\n            [4, 5, 6],\r\n        ],\r\n    };\r\n    polyhedra[12] = {\r\n        vertex: [\r\n            [-0.669867, 0.334933, -0.529576],\r\n            [-0.669867, 0.334933, 0.529577],\r\n            [-0.4043, 1.212901, 0],\r\n            [-0.334933, -0.669867, -0.529576],\r\n            [-0.334933, -0.669867, 0.529577],\r\n            [0.334933, 0.669867, -0.529576],\r\n            [0.334933, 0.669867, 0.529577],\r\n            [0.4043, -1.212901, 0],\r\n            [0.669867, -0.334933, -0.529576],\r\n            [0.669867, -0.334933, 0.529577],\r\n        ],\r\n        face: [\r\n            [8, 9, 7],\r\n            [6, 5, 2],\r\n            [3, 8, 7],\r\n            [5, 0, 2],\r\n            [4, 3, 7],\r\n            [0, 1, 2],\r\n            [9, 4, 7],\r\n            [1, 6, 2],\r\n            [9, 8, 5, 6],\r\n            [8, 3, 0, 5],\r\n            [3, 4, 1, 0],\r\n            [4, 9, 6, 1],\r\n        ],\r\n    };\r\n    polyhedra[13] = {\r\n        vertex: [\r\n            [-0.931836, 0.219976, -0.264632],\r\n            [-0.636706, 0.318353, 0.692816],\r\n            [-0.613483, -0.735083, -0.264632],\r\n            [-0.326545, 0.979634, 0],\r\n            [-0.318353, -0.636706, 0.692816],\r\n            [-0.159176, 0.477529, -0.856368],\r\n            [0.159176, -0.477529, -0.856368],\r\n            [0.318353, 0.636706, 0.692816],\r\n            [0.326545, -0.979634, 0],\r\n            [0.613482, 0.735082, -0.264632],\r\n            [0.636706, -0.318353, 0.692816],\r\n            [0.931835, -0.219977, -0.264632],\r\n        ],\r\n        face: [\r\n            [11, 10, 8],\r\n            [7, 9, 3],\r\n            [6, 11, 8],\r\n            [9, 5, 3],\r\n            [2, 6, 8],\r\n            [5, 0, 3],\r\n            [4, 2, 8],\r\n            [0, 1, 3],\r\n            [10, 4, 8],\r\n            [1, 7, 3],\r\n            [10, 11, 9, 7],\r\n            [11, 6, 5, 9],\r\n            [6, 2, 0, 5],\r\n            [2, 4, 1, 0],\r\n            [4, 10, 7, 1],\r\n        ],\r\n    };\r\n    polyhedra[14] = {\r\n        vertex: [\r\n            [-0.93465, 0.300459, -0.271185],\r\n            [-0.838689, -0.260219, -0.516017],\r\n            [-0.711319, 0.717591, 0.128359],\r\n            [-0.710334, -0.156922, 0.080946],\r\n            [-0.599799, 0.556003, -0.725148],\r\n            [-0.503838, -0.004675, -0.969981],\r\n            [-0.487004, 0.26021, 0.48049],\r\n            [-0.460089, -0.750282, -0.512622],\r\n            [-0.376468, 0.973135, -0.325605],\r\n            [-0.331735, -0.646985, 0.084342],\r\n            [-0.254001, 0.831847, 0.530001],\r\n            [-0.125239, -0.494738, -0.966586],\r\n            [0.029622, 0.027949, 0.730817],\r\n            [0.056536, -0.982543, -0.262295],\r\n            [0.08085, 1.087391, 0.076037],\r\n            [0.125583, -0.532729, 0.485984],\r\n            [0.262625, 0.599586, 0.780328],\r\n            [0.391387, -0.726999, -0.716259],\r\n            [0.513854, -0.868287, 0.139347],\r\n            [0.597475, 0.85513, 0.326364],\r\n            [0.641224, 0.109523, 0.783723],\r\n            [0.737185, -0.451155, 0.538891],\r\n            [0.848705, -0.612742, -0.314616],\r\n            [0.976075, 0.365067, 0.32976],\r\n            [1.072036, -0.19561, 0.084927],\r\n        ],\r\n        face: [\r\n            [15, 18, 21],\r\n            [12, 20, 16],\r\n            [6, 10, 2],\r\n            [3, 0, 1],\r\n            [9, 7, 13],\r\n            [2, 8, 4, 0],\r\n            [0, 4, 5, 1],\r\n            [1, 5, 11, 7],\r\n            [7, 11, 17, 13],\r\n            [13, 17, 22, 18],\r\n            [18, 22, 24, 21],\r\n            [21, 24, 23, 20],\r\n            [20, 23, 19, 16],\r\n            [16, 19, 14, 10],\r\n            [10, 14, 8, 2],\r\n            [15, 9, 13, 18],\r\n            [12, 15, 21, 20],\r\n            [6, 12, 16, 10],\r\n            [3, 6, 2, 0],\r\n            [9, 3, 1, 7],\r\n            [9, 15, 12, 6, 3],\r\n            [22, 17, 11, 5, 4, 8, 14, 19, 23, 24],\r\n        ],\r\n    };\r\n\r\n    const type: number = options.type && (options.type < 0 || options.type >= polyhedra.length) ? 0 : options.type || 0;\r\n    const size = options.size;\r\n    const sizeX: number = options.sizeX || size || 1;\r\n    const sizeY: number = options.sizeY || size || 1;\r\n    const sizeZ: number = options.sizeZ || size || 1;\r\n    const data: { vertex: number[][]; face: number[][]; name?: string; category?: string } = options.custom || polyhedra[type];\r\n    const nbfaces = data.face.length;\r\n    const faceUV = options.faceUV || new Array(nbfaces);\r\n    const faceColors = options.faceColors;\r\n    const flat = options.flat === undefined ? true : options.flat;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    const positions: number[] = [];\r\n    const indices: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n    const colors: number[] = [];\r\n    let index = 0;\r\n    let faceIdx = 0; // face cursor in the array \"indexes\"\r\n    const indexes: number[] = [];\r\n    let i: number;\r\n    let f: number;\r\n    let u: number, v: number, ang: number, x: number, y: number, tmp: number;\r\n\r\n    // default face colors and UV if undefined\r\n    if (flat) {\r\n        for (f = 0; f < nbfaces; f++) {\r\n            if (faceColors && faceColors[f] === undefined) {\r\n                faceColors[f] = new Color4(1, 1, 1, 1);\r\n            }\r\n            if (faceUV && faceUV[f] === undefined) {\r\n                faceUV[f] = new Vector4(0, 0, 1, 1);\r\n            }\r\n        }\r\n    }\r\n\r\n    if (!flat) {\r\n        for (i = 0; i < data.vertex.length; i++) {\r\n            positions.push(data.vertex[i][0] * sizeX, data.vertex[i][1] * sizeY, data.vertex[i][2] * sizeZ);\r\n            uvs.push(0, useOpenGLOrientationForUV ? 1.0 : 0);\r\n        }\r\n        for (f = 0; f < nbfaces; f++) {\r\n            for (i = 0; i < data.face[f].length - 2; i++) {\r\n                indices.push(data.face[f][0], data.face[f][i + 2], data.face[f][i + 1]);\r\n            }\r\n        }\r\n    } else {\r\n        for (f = 0; f < nbfaces; f++) {\r\n            const fl = data.face[f].length; // number of vertices of the current face\r\n            ang = (2 * Math.PI) / fl;\r\n            x = 0.5 * Math.tan(ang / 2);\r\n            y = 0.5;\r\n\r\n            // positions, uvs, colors\r\n            for (i = 0; i < fl; i++) {\r\n                // positions\r\n                positions.push(data.vertex[data.face[f][i]][0] * sizeX, data.vertex[data.face[f][i]][1] * sizeY, data.vertex[data.face[f][i]][2] * sizeZ);\r\n                indexes.push(index);\r\n                index++;\r\n                // uvs\r\n                u = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * (0.5 + x);\r\n                v = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * (y - 0.5);\r\n                uvs.push(u, useOpenGLOrientationForUV ? 1.0 - v : v);\r\n                tmp = x * Math.cos(ang) - y * Math.sin(ang);\r\n                y = x * Math.sin(ang) + y * Math.cos(ang);\r\n                x = tmp;\r\n                // colors\r\n                if (faceColors) {\r\n                    colors.push(faceColors[f].r, faceColors[f].g, faceColors[f].b, faceColors[f].a);\r\n                }\r\n            }\r\n\r\n            // indices from indexes\r\n            for (i = 0; i < fl - 2; i++) {\r\n                indices.push(indexes[0 + faceIdx], indexes[i + 2 + faceIdx], indexes[i + 1 + faceIdx]);\r\n            }\r\n            faceIdx += fl;\r\n        }\r\n    }\r\n\r\n    VertexData.ComputeNormals(positions, indices, normals);\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    const vertexData = new VertexData();\r\n    vertexData.positions = positions;\r\n    vertexData.indices = indices;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n    if (faceColors && flat) {\r\n        vertexData.colors = colors;\r\n    }\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a polyhedron mesh\r\n * * The parameter `type` (positive integer, max 14, default 0) sets the polyhedron type to build among the 15 embbeded types. Please refer to the type sheet in the tutorial to choose the wanted type\r\n * * The parameter `size` (positive float, default 1) sets the polygon size\r\n * * You can overwrite the `size` on each dimension bu using the parameters `sizeX`, `sizeY` or `sizeZ` (positive floats, default to `size` value)\r\n * * You can build other polyhedron types than the 15 embbeded ones by setting the parameter `custom` (`polyhedronObject`, default null). If you set the parameter `custom`, this overrides the parameter `type`\r\n * * A `polyhedronObject` is a formatted javascript object. You'll find a full file with pre-set polyhedra here : https://github.com/BabylonJS/Extensions/tree/master/Polyhedron\r\n * * You can set the color and the UV of each side of the polyhedron with the parameters `faceColors` (Color4, default `(1, 1, 1, 1)`) and faceUV (Vector4, default `(0, 0, 1, 1)`)\r\n * * To understand how to set `faceUV` or `faceColors`, please read this by considering the right number of faces of your polyhedron, instead of only 6 for the box : https://doc.babylonjs.com/features/featuresDeepDive/materials/using/texturePerBoxFace\r\n * * The parameter `flat` (boolean, default true). If set to false, it gives the polyhedron a single global face, so less vertices and shared normals. In this case, `faceColors` and `faceUV` are ignored\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the polyhedron mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra\r\n */\r\nexport function CreatePolyhedron(\r\n    name: string,\r\n    options: {\r\n        type?: number;\r\n        size?: number;\r\n        sizeX?: number;\r\n        sizeY?: number;\r\n        sizeZ?: number;\r\n        custom?: any;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        flat?: boolean;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    } = {},\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const polyhedron = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    polyhedron._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreatePolyhedronVertexData(options);\r\n\r\n    vertexData.applyToMesh(polyhedron, options.updatable);\r\n\r\n    return polyhedron;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the function directly from the module\r\n */\r\nexport const PolyhedronBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreatePolyhedron,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for polyhedronBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPolyhedronBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreatePolyhedron = CreatePolyhedronVertexData;\r\n\r\n    Mesh.CreatePolyhedron = (\r\n        name: string,\r\n        options: {\r\n            type?: number;\r\n            size?: number;\r\n            sizeX?: number;\r\n            sizeY?: number;\r\n            sizeZ?: number;\r\n            custom?: any;\r\n            faceUV?: Vector4[];\r\n            faceColors?: Color4[];\r\n            updatable?: boolean;\r\n            sideOrientation?: number;\r\n        },\r\n        scene: Scene\r\n    ): Mesh => {\r\n        return CreatePolyhedron(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3, Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates the VertexData of the IcoSphere\r\n * @param options an object used to set the following optional parameters for the IcoSphere, required but can be empty\r\n * * radius the radius of the IcoSphere, optional default 1\r\n * * radiusX allows stretching in the x direction, optional, default radius\r\n * * radiusY allows stretching in the y direction, optional, default radius\r\n * * radiusZ allows stretching in the z direction, optional, default radius\r\n * * flat when true creates a flat shaded mesh, optional, default true\r\n * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @returns the VertexData of the IcoSphere\r\n */\r\nexport function CreateIcoSphereVertexData(options: {\r\n    radius?: number;\r\n    radiusX?: number;\r\n    radiusY?: number;\r\n    radiusZ?: number;\r\n    flat?: boolean;\r\n    subdivisions?: number;\r\n    sideOrientation?: number;\r\n    frontUVs?: Vector4;\r\n    backUVs?: Vector4;\r\n}): VertexData {\r\n    const sideOrientation = options.sideOrientation || VertexData.DEFAULTSIDE;\r\n    const radius = options.radius || 1;\r\n    const flat = options.flat === undefined ? true : options.flat;\r\n    const subdivisions = (options.subdivisions || 4) | 0;\r\n    const radiusX = options.radiusX || radius;\r\n    const radiusY = options.radiusY || radius;\r\n    const radiusZ = options.radiusZ || radius;\r\n\r\n    const t = (1 + Math.sqrt(5)) / 2;\r\n\r\n    // 12 vertex x,y,z\r\n    const icoVertices = [\r\n        -1,\r\n        t,\r\n        -0,\r\n        1,\r\n        t,\r\n        0,\r\n        -1,\r\n        -t,\r\n        0,\r\n        1,\r\n        -t,\r\n        0, // v0-3\r\n        0,\r\n        -1,\r\n        -t,\r\n        0,\r\n        1,\r\n        -t,\r\n        0,\r\n        -1,\r\n        t,\r\n        0,\r\n        1,\r\n        t, // v4-7\r\n        t,\r\n        0,\r\n        1,\r\n        t,\r\n        0,\r\n        -1,\r\n        -t,\r\n        0,\r\n        1,\r\n        -t,\r\n        0,\r\n        -1, // v8-11\r\n    ];\r\n\r\n    // index of 3 vertex makes a face of icopshere\r\n    const icoIndices = [\r\n        0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 12, 22, 23, 1, 5, 20, 5, 11, 4, 23, 22, 13, 22, 18, 6, 7, 1, 8, 14, 21, 4, 14, 4, 2, 16, 13, 6, 15, 6, 19, 3, 8, 9, 4, 21, 5, 13, 17,\r\n        23, 6, 13, 22, 19, 6, 18, 9, 8, 1,\r\n    ];\r\n    // vertex for uv have aliased position, not for UV\r\n    const verticesUnaliasId = [\r\n        0,\r\n        1,\r\n        2,\r\n        3,\r\n        4,\r\n        5,\r\n        6,\r\n        7,\r\n        8,\r\n        9,\r\n        10,\r\n        11,\r\n        // vertex alias\r\n        0, // 12: 0 + 12\r\n        2, // 13: 2 + 11\r\n        3, // 14: 3 + 11\r\n        3, // 15: 3 + 12\r\n        3, // 16: 3 + 13\r\n        4, // 17: 4 + 13\r\n        7, // 18: 7 + 11\r\n        8, // 19: 8 + 11\r\n        9, // 20: 9 + 11\r\n        9, // 21: 9 + 12\r\n        10, // 22: A + 12\r\n        11, // 23: B + 12\r\n    ];\r\n\r\n    // uv as integer step (not pixels !)\r\n    const icoVertexuv = [\r\n        5,\r\n        1,\r\n        3,\r\n        1,\r\n        6,\r\n        4,\r\n        0,\r\n        0, // v0-3\r\n        5,\r\n        3,\r\n        4,\r\n        2,\r\n        2,\r\n        2,\r\n        4,\r\n        0, // v4-7\r\n        2,\r\n        0,\r\n        1,\r\n        1,\r\n        6,\r\n        0,\r\n        6,\r\n        2, // v8-11\r\n        // vertex alias (for same vertex on different faces)\r\n        0,\r\n        4, // 12: 0 + 12\r\n        3,\r\n        3, // 13: 2 + 11\r\n        4,\r\n        4, // 14: 3 + 11\r\n        3,\r\n        1, // 15: 3 + 12\r\n        4,\r\n        2, // 16: 3 + 13\r\n        4,\r\n        4, // 17: 4 + 13\r\n        0,\r\n        2, // 18: 7 + 11\r\n        1,\r\n        1, // 19: 8 + 11\r\n        2,\r\n        2, // 20: 9 + 11\r\n        3,\r\n        3, // 21: 9 + 12\r\n        1,\r\n        3, // 22: A + 12\r\n        2,\r\n        4, // 23: B + 12\r\n    ];\r\n\r\n    // Vertices[0, 1, ...9, A, B] : position on UV plane\r\n    // '+' indicate duplicate position to be fixed (3,9:0,2,3,4,7,8,A,B)\r\n    // First island of uv mapping\r\n    // v = 4h          3+  2\r\n    // v = 3h        9+  4\r\n    // v = 2h      9+  5   B\r\n    // v = 1h    9   1   0\r\n    // v = 0h  3   8   7   A\r\n    //     u = 0 1 2 3 4 5 6  *a\r\n\r\n    // Second island of uv mapping\r\n    // v = 4h  0+  B+  4+\r\n    // v = 3h    A+  2+\r\n    // v = 2h  7+  6   3+\r\n    // v = 1h    8+  3+\r\n    // v = 0h\r\n    //     u = 0 1 2 3 4 5 6  *a\r\n\r\n    // Face layout on texture UV mapping\r\n    // ============\r\n    // \\ 4  /\\ 16 /   ======\r\n    //  \\  /  \\  /   /\\ 11 /\r\n    //   \\/ 7  \\/   /  \\  /\r\n    //    =======  / 10 \\/\r\n    //   /\\ 17 /\\  =======\r\n    //  /  \\  /  \\ \\ 15 /\\\r\n    // / 8  \\/ 12 \\ \\  /  \\\r\n    // ============  \\/ 6  \\\r\n    // \\ 18 /\\  ============\r\n    //  \\  /  \\ \\ 5  /\\ 0  /\r\n    //   \\/ 13 \\ \\  /  \\  /\r\n    //   =======  \\/ 1  \\/\r\n    //       =============\r\n    //      /\\ 19 /\\  2 /\\\r\n    //     /  \\  /  \\  /  \\\r\n    //    / 14 \\/ 9  \\/  3 \\\r\n    //   ===================\r\n\r\n    // uv step is u:1 or 0.5, v:cos(30)=sqrt(3)/2, ratio approx is 84/97\r\n    const ustep = 138 / 1024;\r\n    const vstep = 239 / 1024;\r\n    const uoffset = 60 / 1024;\r\n    const voffset = 26 / 1024;\r\n    // Second island should have margin, not to touch the first island\r\n    // avoid any borderline artefact in pixel rounding\r\n    const islandUoffset = -40 / 1024;\r\n    const islandVoffset = +20 / 1024;\r\n    // face is either island 0 or 1 :\r\n    // second island is for faces : [4, 7, 8, 12, 13, 16, 17, 18]\r\n    const island = [\r\n        0,\r\n        0,\r\n        0,\r\n        0,\r\n        1, //  0 - 4\r\n        0,\r\n        0,\r\n        1,\r\n        1,\r\n        0, //  5 - 9\r\n        0,\r\n        0,\r\n        1,\r\n        1,\r\n        0, //  10 - 14\r\n        0,\r\n        1,\r\n        1,\r\n        1,\r\n        0, //  15 - 19\r\n    ];\r\n\r\n    const indices: number[] = [];\r\n    const positions: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n\r\n    let currentIndice = 0;\r\n    // prepare array of 3 vector (empty) (to be worked in place, shared for each face)\r\n    const faceVertexPos = new Array(3);\r\n    const faceVertexUv = new Array(3);\r\n    let v012;\r\n    for (v012 = 0; v012 < 3; v012++) {\r\n        faceVertexPos[v012] = Vector3.Zero();\r\n        faceVertexUv[v012] = Vector2.Zero();\r\n    }\r\n    // create all with normals\r\n    for (let face = 0; face < 20; face++) {\r\n        // 3 vertex per face\r\n        for (v012 = 0; v012 < 3; v012++) {\r\n            // look up vertex 0,1,2 to its index in 0 to 11 (or 23 including alias)\r\n            const vId = icoIndices[3 * face + v012];\r\n            // vertex have 3D position (x,y,z)\r\n            faceVertexPos[v012].copyFromFloats(icoVertices[3 * verticesUnaliasId[vId]], icoVertices[3 * verticesUnaliasId[vId] + 1], icoVertices[3 * verticesUnaliasId[vId] + 2]);\r\n            // Normalize to get normal\r\n            faceVertexPos[v012].normalize();\r\n\r\n            // uv Coordinates from vertex ID\r\n            faceVertexUv[v012].copyFromFloats(\r\n                icoVertexuv[2 * vId] * ustep + uoffset + island[face] * islandUoffset,\r\n                icoVertexuv[2 * vId + 1] * vstep + voffset + island[face] * islandVoffset\r\n            );\r\n        }\r\n\r\n        // Subdivide the face (interpolate pos, norm, uv)\r\n        // - pos is linear interpolation, then projected to sphere (converge polyhedron to sphere)\r\n        // - norm is linear interpolation of vertex corner normal\r\n        //   (to be checked if better to re-calc from face vertex, or if approximation is OK ??? )\r\n        // - uv is linear interpolation\r\n        //\r\n        // Topology is as below for sub-divide by 2\r\n        // vertex shown as v0,v1,v2\r\n        // interp index is i1 to progress in range [v0,v1[\r\n        // interp index is i2 to progress in range [v0,v2[\r\n        // face index as  (i1,i2)  for /\\  : (i1,i2),(i1+1,i2),(i1,i2+1)\r\n        //            and (i1,i2)' for \\/  : (i1+1,i2),(i1+1,i2+1),(i1,i2+1)\r\n        //\r\n        //\r\n        //                    i2    v2\r\n        //                    ^    ^\r\n        //                   /    / \\\r\n        //                  /    /   \\\r\n        //                 /    /     \\\r\n        //                /    / (0,1) \\\r\n        //               /    #---------\\\r\n        //              /    / \\ (0,0)'/ \\\r\n        //             /    /   \\     /   \\\r\n        //            /    /     \\   /     \\\r\n        //           /    / (0,0) \\ / (1,0) \\\r\n        //          /    #---------#---------\\\r\n        //              v0                    v1\r\n        //\r\n        //              --------------------> i1\r\n        //\r\n        // interp of (i1,i2):\r\n        //  along i2 :  x0=lerp(v0,v2, i2/S) <---> x1=lerp(v1,v2, i2/S)\r\n        //  along i1 :  lerp(x0,x1, i1/(S-i2))\r\n        //\r\n        // centroid of triangle is needed to get help normal computation\r\n        //  (c1,c2) are used for centroid location\r\n\r\n        const interpVertex = (i1: number, i2: number, c1: number, c2: number) => {\r\n            // vertex is interpolated from\r\n            //   - face_vertex_pos[0..2]\r\n            //   - face_vertex_uv[0..2]\r\n            const posX0 = Vector3.Lerp(faceVertexPos[0], faceVertexPos[2], i2 / subdivisions);\r\n            const posX1 = Vector3.Lerp(faceVertexPos[1], faceVertexPos[2], i2 / subdivisions);\r\n            const posInterp = subdivisions === i2 ? faceVertexPos[2] : Vector3.Lerp(posX0, posX1, i1 / (subdivisions - i2));\r\n            posInterp.normalize();\r\n\r\n            let vertexNormal;\r\n            if (flat) {\r\n                // in flat mode, recalculate normal as face centroid normal\r\n                const centroidX0 = Vector3.Lerp(faceVertexPos[0], faceVertexPos[2], c2 / subdivisions);\r\n                const centroidX1 = Vector3.Lerp(faceVertexPos[1], faceVertexPos[2], c2 / subdivisions);\r\n                vertexNormal = Vector3.Lerp(centroidX0, centroidX1, c1 / (subdivisions - c2));\r\n            } else {\r\n                // in smooth mode, recalculate normal from each single vertex position\r\n                vertexNormal = new Vector3(posInterp.x, posInterp.y, posInterp.z);\r\n            }\r\n            // Vertex normal need correction due to X,Y,Z radius scaling\r\n            vertexNormal.x /= radiusX;\r\n            vertexNormal.y /= radiusY;\r\n            vertexNormal.z /= radiusZ;\r\n            vertexNormal.normalize();\r\n\r\n            const uvX0 = Vector2.Lerp(faceVertexUv[0], faceVertexUv[2], i2 / subdivisions);\r\n            const uvX1 = Vector2.Lerp(faceVertexUv[1], faceVertexUv[2], i2 / subdivisions);\r\n            const uvInterp = subdivisions === i2 ? faceVertexUv[2] : Vector2.Lerp(uvX0, uvX1, i1 / (subdivisions - i2));\r\n            positions.push(posInterp.x * radiusX, posInterp.y * radiusY, posInterp.z * radiusZ);\r\n            normals.push(vertexNormal.x, vertexNormal.y, vertexNormal.z);\r\n            uvs.push(uvInterp.x, useOpenGLOrientationForUV ? 1.0 - uvInterp.y : uvInterp.y);\r\n            // push each vertex has member of a face\r\n            // Same vertex can belong to multiple face, it is pushed multiple time (duplicate vertex are present)\r\n            indices.push(currentIndice);\r\n            currentIndice++;\r\n        };\r\n\r\n        for (let i2 = 0; i2 < subdivisions; i2++) {\r\n            for (let i1 = 0; i1 + i2 < subdivisions; i1++) {\r\n                // face : (i1,i2)  for /\\  :\r\n                // interp for : (i1,i2),(i1+1,i2),(i1,i2+1)\r\n                interpVertex(i1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);\r\n                interpVertex(i1 + 1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);\r\n                interpVertex(i1, i2 + 1, i1 + 1.0 / 3, i2 + 1.0 / 3);\r\n                if (i1 + i2 + 1 < subdivisions) {\r\n                    // face : (i1,i2)' for \\/  :\r\n                    // interp for (i1+1,i2),(i1+1,i2+1),(i1,i2+1)\r\n                    interpVertex(i1 + 1, i2, i1 + 2.0 / 3, i2 + 2.0 / 3);\r\n                    interpVertex(i1 + 1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);\r\n                    interpVertex(i1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // Sides\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);\r\n\r\n    // Result\r\n    const vertexData = new VertexData();\r\n    vertexData.indices = indices;\r\n    vertexData.positions = positions;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates a sphere based upon an icosahedron with 20 triangular faces which can be subdivided\r\n * * The parameter `radius` sets the radius size (float) of the icosphere (default 1)\r\n * * You can set some different icosphere dimensions, for instance to build an ellipsoid, by using the parameters `radiusX`, `radiusY` and `radiusZ` (all by default have the same value of `radius`)\r\n * * The parameter `subdivisions` sets the number of subdivisions (positive integer, default 4). The more subdivisions, the more faces on the icosphere whatever its size\r\n * * The parameter `flat` (boolean, default true) gives each side its own normals. Set it to false to get a smooth continuous light reflection on the surface\r\n * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE\r\n * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set#side-orientation\r\n * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the icosahedron mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra#icosphere\r\n */\r\nexport function CreateIcoSphere(\r\n    name: string,\r\n    options: {\r\n        radius?: number;\r\n        radiusX?: number;\r\n        radiusY?: number;\r\n        radiusZ?: number;\r\n        flat?: boolean;\r\n        subdivisions?: number;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n        updatable?: boolean;\r\n    } = {},\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const sphere = new Mesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    sphere._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateIcoSphereVertexData(options);\r\n\r\n    vertexData.applyToMesh(sphere, options.updatable);\r\n\r\n    return sphere;\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the function directly from the module\r\n */\r\nexport const IcoSphereBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateIcoSphere,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for icoSphereBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterIcoSphereBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    VertexData.CreateIcoSphere = CreateIcoSphereVertexData;\r\n\r\n    Mesh.CreateIcoSphere = (\r\n        name: string,\r\n        options: { radius?: number; flat?: boolean; subdivisions?: number; sideOrientation?: number; updatable?: boolean },\r\n        scene: Scene\r\n    ): Mesh => {\r\n        return CreateIcoSphere(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type IndicesArray, type FloatArray } from \"../../types\";\r\nimport { Vector3, Matrix, Vector2, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { Lerp } from \"../../Maths/math.scalar.functions\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type AbstractMesh } from \"../abstractMesh.pure\";\r\n\r\nconst XpAxis = /*#__PURE__*/ new Vector3(1, 0, 0);\r\nconst XnAxis = /*#__PURE__*/ new Vector3(-1, 0, 0);\r\nconst YpAxis = /*#__PURE__*/ new Vector3(0, 1, 0);\r\nconst YnAxis = /*#__PURE__*/ new Vector3(0, -1, 0);\r\nconst ZpAxis = /*#__PURE__*/ new Vector3(0, 0, 1);\r\nconst ZnAxis = /*#__PURE__*/ new Vector3(0, 0, -1);\r\n\r\n/** @internal */\r\nclass DecalVertex {\r\n    /** @internal */\r\n    constructor(\r\n        public position: Vector3 = Vector3.Zero(),\r\n        public normal: Vector3 = Vector3.Up(),\r\n        public uv: Vector2 = Vector2.Zero(),\r\n        public vertexIdx: number = 0,\r\n        public vertexIdxForBones: number = 0,\r\n        public localPositionOverride: Nullable<number[]> = null,\r\n        public localNormalOverride: Nullable<number[]> = null,\r\n        public matrixIndicesOverride: Nullable<number[]> = null,\r\n        public matrixWeightsOverride: Nullable<number[]> = null\r\n    ) {}\r\n    /** @internal */\r\n    public clone(): DecalVertex {\r\n        return new DecalVertex(\r\n            this.position.clone(),\r\n            this.normal.clone(),\r\n            this.uv.clone(),\r\n            this.vertexIdx,\r\n            this.vertexIdxForBones,\r\n            this.localPositionOverride?.slice(),\r\n            this.localNormalOverride?.slice(),\r\n            this.matrixIndicesOverride?.slice(),\r\n            this.matrixWeightsOverride?.slice()\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a decal mesh.\r\n * A decal is a mesh usually applied as a model onto the surface of another mesh. So don't forget the parameter `sourceMesh` depicting the decal\r\n * * The parameter `position` (Vector3, default `(0, 0, 0)`) sets the position of the decal in World coordinates\r\n * * The parameter `normal` (Vector3, default `Vector3.Up`) sets the normal of the mesh where the decal is applied onto in World coordinates\r\n * * The parameter `size` (Vector3, default `(1, 1, 1)`) sets the decal scaling\r\n * * The parameter `angle` (float in radian, default 0) sets the angle to rotate the decal\r\n * * The parameter `captureUVS` defines if we need to capture the uvs or compute them\r\n * * The parameter `cullBackFaces` defines if the back faces should be removed from the decal mesh\r\n * * The parameter `localMode` defines that the computations should be done with the local mesh coordinates instead of the world space coordinates.\r\n * *    Use this mode if you want the decal to be parented to the sourceMesh and move/rotate with it.\r\n * Note: Meshes with morph targets are not supported!\r\n * @param name defines the name of the mesh\r\n * @param sourceMesh defines the mesh where the decal must be applied\r\n * @param options defines the options used to create the mesh\r\n * @returns the decal mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/decals\r\n */\r\nexport function CreateDecal(\r\n    name: string,\r\n    sourceMesh: AbstractMesh,\r\n    options: { position?: Vector3; normal?: Vector3; size?: Vector3; angle?: number; captureUVS?: boolean; cullBackFaces?: boolean; localMode?: boolean }\r\n): Mesh {\r\n    const hasSkeleton = !!sourceMesh.skeleton;\r\n    const hasMorphTargets = !!sourceMesh.morphTargetManager?.numTargets;\r\n    const useLocalComputation = options.localMode || hasSkeleton;\r\n\r\n    const indices = <IndicesArray>sourceMesh.getIndices();\r\n    const positions = hasSkeleton || hasMorphTargets ? sourceMesh.getPositionData(true, true) : sourceMesh.getVerticesData(VertexBuffer.PositionKind);\r\n    const normals = hasSkeleton || hasMorphTargets ? sourceMesh.getNormalsData(true, true) : sourceMesh.getVerticesData(VertexBuffer.NormalKind);\r\n    const localPositions = useLocalComputation ? (hasSkeleton ? sourceMesh.getVerticesData(VertexBuffer.PositionKind) : positions) : null;\r\n    const localNormals = useLocalComputation ? (hasSkeleton ? sourceMesh.getVerticesData(VertexBuffer.NormalKind) : normals) : null;\r\n    const uvs = sourceMesh.getVerticesData(VertexBuffer.UVKind);\r\n    const matIndices = hasSkeleton ? sourceMesh.getVerticesData(VertexBuffer.MatricesIndicesKind) : null;\r\n    const matWeights = hasSkeleton ? sourceMesh.getVerticesData(VertexBuffer.MatricesWeightsKind) : null;\r\n    const matIndicesExtra = hasSkeleton ? sourceMesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;\r\n    const matWeightsExtra = hasSkeleton ? sourceMesh.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;\r\n\r\n    const position = options.position || Vector3.Zero();\r\n    let normal = options.normal || Vector3.Up();\r\n    const size = options.size || Vector3.One();\r\n    const angle = options.angle || 0;\r\n\r\n    // Getting correct rotation\r\n    if (!normal) {\r\n        const target = new Vector3(0, 0, 1);\r\n        const camera = <Camera>sourceMesh.getScene().activeCamera;\r\n        const cameraWorldTarget = Vector3.TransformCoordinates(target, camera.getWorldMatrix());\r\n\r\n        normal = camera.globalPosition.subtract(cameraWorldTarget);\r\n    }\r\n\r\n    const yaw = -Math.atan2(normal.z, normal.x) - Math.PI / 2;\r\n    const len = Math.sqrt(normal.x * normal.x + normal.z * normal.z);\r\n    const pitch = Math.atan2(normal.y, len);\r\n\r\n    const vertexData = new VertexData();\r\n    vertexData.indices = [];\r\n    vertexData.positions = [];\r\n    vertexData.normals = [];\r\n    vertexData.uvs = [];\r\n    vertexData.matricesIndices = hasSkeleton ? [] : null;\r\n    vertexData.matricesWeights = hasSkeleton ? [] : null;\r\n    vertexData.matricesIndicesExtra = matIndicesExtra ? [] : null;\r\n    vertexData.matricesWeightsExtra = matWeightsExtra ? [] : null;\r\n\r\n    let currentVertexDataIndex = 0;\r\n\r\n    const extractDecalVector3 = (indexId: number, transformMatrix: Matrix): DecalVertex => {\r\n        const result = new DecalVertex();\r\n        if (!indices || !positions || !normals) {\r\n            return result;\r\n        }\r\n\r\n        const vertexId = indices[indexId];\r\n\r\n        result.vertexIdx = vertexId * 3;\r\n        result.vertexIdxForBones = vertexId * 4;\r\n\r\n        // Send vector to decal local world\r\n        result.position = new Vector3(positions[vertexId * 3], positions[vertexId * 3 + 1], positions[vertexId * 3 + 2]);\r\n        Vector3.TransformCoordinatesToRef(result.position, transformMatrix, result.position);\r\n\r\n        // Get normal\r\n        result.normal = new Vector3(normals[vertexId * 3], normals[vertexId * 3 + 1], normals[vertexId * 3 + 2]);\r\n        Vector3.TransformNormalToRef(result.normal, transformMatrix, result.normal);\r\n\r\n        if (options.captureUVS && uvs) {\r\n            const v = uvs[vertexId * 2 + 1];\r\n            result.uv = new Vector2(uvs[vertexId * 2], useOpenGLOrientationForUV ? 1 - v : v);\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    const emptyArray = [0, 0, 0, 0];\r\n\r\n    // Inspired by https://github.com/mrdoob/three.js/blob/eee231960882f6f3b6113405f524956145148146/examples/js/geometries/DecalGeometry.js\r\n    const clip = (vertices: DecalVertex[], axis: Vector3): Nullable<DecalVertex[]> => {\r\n        if (vertices.length === 0) {\r\n            return vertices;\r\n        }\r\n\r\n        const clipSize = 0.5 * Math.abs(Vector3.Dot(size, axis));\r\n\r\n        const indexOf = (arr: FloatArray | number[], val: number, start: number, num: number) => {\r\n            for (let i = 0; i < num; ++i) {\r\n                if (arr[start + i] === val) {\r\n                    return start + i;\r\n                }\r\n            }\r\n            return -1;\r\n        };\r\n\r\n        const clipVertices = (v0: DecalVertex, v1: DecalVertex): DecalVertex => {\r\n            const clipFactor = Vector3.GetClipFactor(v0.position, v1.position, axis, clipSize);\r\n\r\n            let indices = emptyArray;\r\n            let weights = emptyArray;\r\n\r\n            if (matIndices && matWeights) {\r\n                const mat0Index = v0.matrixIndicesOverride ? 0 : v0.vertexIdxForBones;\r\n                const v0Indices = v0.matrixIndicesOverride ?? matIndices;\r\n                const v0Weights = v0.matrixWeightsOverride ?? matWeights;\r\n\r\n                const mat1Index = v1.matrixIndicesOverride ? 0 : v1.vertexIdxForBones;\r\n                const v1Indices = v1.matrixIndicesOverride ?? matIndices;\r\n                const v1Weights = v1.matrixWeightsOverride ?? matWeights;\r\n\r\n                indices = [0, 0, 0, 0];\r\n                weights = [0, 0, 0, 0];\r\n\r\n                let index = 0;\r\n                for (let i = 0; i < 4; ++i) {\r\n                    if (v0Weights[mat0Index + i] > 0) {\r\n                        const idx = indexOf(v1Indices, v0Indices[mat0Index + i], mat1Index, 4);\r\n                        indices[index] = v0Indices[mat0Index + i];\r\n                        weights[index] = Lerp(v0Weights[mat0Index + i], idx >= 0 ? v1Weights[idx] : 0, clipFactor);\r\n                        index++;\r\n                    }\r\n                }\r\n\r\n                for (let i = 0; i < 4 && index < 4; ++i) {\r\n                    const ind = v1Indices[mat1Index + i];\r\n                    if (indexOf(v0Indices, ind, mat0Index, 4) !== -1) {\r\n                        continue;\r\n                    }\r\n\r\n                    indices[index] = ind;\r\n                    weights[index] = Lerp(0, v1Weights[mat1Index + i], clipFactor);\r\n                    index++;\r\n                }\r\n\r\n                const sumw = weights[0] + weights[1] + weights[2] + weights[3];\r\n\r\n                weights[0] /= sumw;\r\n                weights[1] /= sumw;\r\n                weights[2] /= sumw;\r\n                weights[3] /= sumw;\r\n            }\r\n\r\n            const v0LocalPositionX = v0.localPositionOverride ? v0.localPositionOverride[0] : (localPositions?.[v0.vertexIdx] ?? 0);\r\n            const v0LocalPositionY = v0.localPositionOverride ? v0.localPositionOverride[1] : (localPositions?.[v0.vertexIdx + 1] ?? 0);\r\n            const v0LocalPositionZ = v0.localPositionOverride ? v0.localPositionOverride[2] : (localPositions?.[v0.vertexIdx + 2] ?? 0);\r\n\r\n            const v1LocalPositionX = v1.localPositionOverride ? v1.localPositionOverride[0] : (localPositions?.[v1.vertexIdx] ?? 0);\r\n            const v1LocalPositionY = v1.localPositionOverride ? v1.localPositionOverride[1] : (localPositions?.[v1.vertexIdx + 1] ?? 0);\r\n            const v1LocalPositionZ = v1.localPositionOverride ? v1.localPositionOverride[2] : (localPositions?.[v1.vertexIdx + 2] ?? 0);\r\n\r\n            const v0LocalNormalX = v0.localNormalOverride ? v0.localNormalOverride[0] : (localNormals?.[v0.vertexIdx] ?? 0);\r\n            const v0LocalNormalY = v0.localNormalOverride ? v0.localNormalOverride[1] : (localNormals?.[v0.vertexIdx + 1] ?? 0);\r\n            const v0LocalNormalZ = v0.localNormalOverride ? v0.localNormalOverride[2] : (localNormals?.[v0.vertexIdx + 2] ?? 0);\r\n\r\n            const v1LocalNormalX = v1.localNormalOverride ? v1.localNormalOverride[0] : (localNormals?.[v1.vertexIdx] ?? 0);\r\n            const v1LocalNormalY = v1.localNormalOverride ? v1.localNormalOverride[1] : (localNormals?.[v1.vertexIdx + 1] ?? 0);\r\n            const v1LocalNormalZ = v1.localNormalOverride ? v1.localNormalOverride[2] : (localNormals?.[v1.vertexIdx + 2] ?? 0);\r\n\r\n            const interpNormalX = v0LocalNormalX + (v1LocalNormalX - v0LocalNormalX) * clipFactor;\r\n            const interpNormalY = v0LocalNormalY + (v1LocalNormalY - v0LocalNormalY) * clipFactor;\r\n            const interpNormalZ = v0LocalNormalZ + (v1LocalNormalZ - v0LocalNormalZ) * clipFactor;\r\n\r\n            const norm = Math.sqrt(interpNormalX * interpNormalX + interpNormalY * interpNormalY + interpNormalZ * interpNormalZ);\r\n\r\n            return new DecalVertex(\r\n                Vector3.Lerp(v0.position, v1.position, clipFactor),\r\n                Vector3.Lerp(v0.normal, v1.normal, clipFactor).normalize(),\r\n                Vector2.Lerp(v0.uv, v1.uv, clipFactor),\r\n                -1,\r\n                -1,\r\n                localPositions\r\n                    ? [\r\n                          v0LocalPositionX + (v1LocalPositionX - v0LocalPositionX) * clipFactor,\r\n                          v0LocalPositionY + (v1LocalPositionY - v0LocalPositionY) * clipFactor,\r\n                          v0LocalPositionZ + (v1LocalPositionZ - v0LocalPositionZ) * clipFactor,\r\n                      ]\r\n                    : null,\r\n                localNormals ? [interpNormalX / norm, interpNormalY / norm, interpNormalZ / norm] : null,\r\n                indices,\r\n                weights\r\n            );\r\n        };\r\n\r\n        let clipResult: Nullable<DecalVertex[]> = null;\r\n\r\n        if (vertices.length > 3) {\r\n            clipResult = [] as DecalVertex[];\r\n        }\r\n\r\n        for (let index = 0; index < vertices.length; index += 3) {\r\n            let nV1: Nullable<DecalVertex> = null;\r\n            let nV2: Nullable<DecalVertex> = null;\r\n            let nV3: Nullable<DecalVertex> = null;\r\n            let nV4: Nullable<DecalVertex> = null;\r\n\r\n            const d1 = Vector3.Dot(vertices[index].position, axis) - clipSize;\r\n            const d2 = Vector3.Dot(vertices[index + 1].position, axis) - clipSize;\r\n            const d3 = Vector3.Dot(vertices[index + 2].position, axis) - clipSize;\r\n\r\n            const v1Out = d1 > 0;\r\n            const v2Out = d2 > 0;\r\n            const v3Out = d3 > 0;\r\n\r\n            const total = (v1Out ? 1 : 0) + (v2Out ? 1 : 0) + (v3Out ? 1 : 0);\r\n\r\n            switch (total) {\r\n                case 0:\r\n                    if (vertices.length > 3) {\r\n                        clipResult!.push(vertices[index]);\r\n                        clipResult!.push(vertices[index + 1]);\r\n                        clipResult!.push(vertices[index + 2]);\r\n                    } else {\r\n                        clipResult = vertices;\r\n                    }\r\n                    break;\r\n                case 1:\r\n                    clipResult = clipResult ?? new Array<DecalVertex>();\r\n                    if (v1Out) {\r\n                        nV1 = vertices[index + 1];\r\n                        nV2 = vertices[index + 2];\r\n                        nV3 = clipVertices(vertices[index], nV1);\r\n                        nV4 = clipVertices(vertices[index], nV2);\r\n                    }\r\n\r\n                    if (v2Out) {\r\n                        nV1 = vertices[index];\r\n                        nV2 = vertices[index + 2];\r\n                        nV3 = clipVertices(vertices[index + 1], nV1);\r\n                        nV4 = clipVertices(vertices[index + 1], nV2);\r\n\r\n                        clipResult.push(nV3);\r\n                        clipResult.push(nV2.clone());\r\n                        clipResult.push(nV1.clone());\r\n\r\n                        clipResult.push(nV2.clone());\r\n                        clipResult.push(nV3.clone());\r\n                        clipResult.push(nV4);\r\n                        break;\r\n                    }\r\n                    if (v3Out) {\r\n                        nV1 = vertices[index];\r\n                        nV2 = vertices[index + 1];\r\n                        nV3 = clipVertices(vertices[index + 2], nV1);\r\n                        nV4 = clipVertices(vertices[index + 2], nV2);\r\n                    }\r\n\r\n                    if (nV1 && nV2 && nV3 && nV4) {\r\n                        clipResult.push(nV1.clone());\r\n                        clipResult.push(nV2.clone());\r\n                        clipResult.push(nV3);\r\n\r\n                        clipResult.push(nV4);\r\n                        clipResult.push(nV3.clone());\r\n                        clipResult.push(nV2.clone());\r\n                    }\r\n                    break;\r\n                case 2:\r\n                    clipResult = clipResult ?? new Array<DecalVertex>();\r\n                    if (!v1Out) {\r\n                        nV1 = vertices[index].clone();\r\n                        nV2 = clipVertices(nV1, vertices[index + 1]);\r\n                        nV3 = clipVertices(nV1, vertices[index + 2]);\r\n                        clipResult.push(nV1);\r\n                        clipResult.push(nV2);\r\n                        clipResult.push(nV3);\r\n                    }\r\n                    if (!v2Out) {\r\n                        nV1 = vertices[index + 1].clone();\r\n                        nV2 = clipVertices(nV1, vertices[index + 2]);\r\n                        nV3 = clipVertices(nV1, vertices[index]);\r\n                        clipResult.push(nV1);\r\n                        clipResult.push(nV2);\r\n                        clipResult.push(nV3);\r\n                    }\r\n                    if (!v3Out) {\r\n                        nV1 = vertices[index + 2].clone();\r\n                        nV2 = clipVertices(nV1, vertices[index]);\r\n                        nV3 = clipVertices(nV1, vertices[index + 1]);\r\n                        clipResult.push(nV1);\r\n                        clipResult.push(nV2);\r\n                        clipResult.push(nV3);\r\n                    }\r\n                    break;\r\n                case 3:\r\n                    break;\r\n            }\r\n        }\r\n\r\n        return clipResult;\r\n    };\r\n\r\n    const sourceMeshAsMesh = sourceMesh instanceof Mesh ? sourceMesh : null;\r\n    const matrixData = sourceMeshAsMesh?._thinInstanceDataStorage.matrixData;\r\n\r\n    const numMatrices = sourceMeshAsMesh?.thinInstanceCount || 1;\r\n    const thinInstanceMatrix = TmpVectors.Matrix[0];\r\n\r\n    thinInstanceMatrix.copyFrom(Matrix.IdentityReadOnly);\r\n\r\n    for (let m = 0; m < numMatrices; ++m) {\r\n        if (sourceMeshAsMesh?.hasThinInstances && matrixData) {\r\n            const ofst = m * 16;\r\n\r\n            thinInstanceMatrix.setRowFromFloats(0, matrixData[ofst + 0], matrixData[ofst + 1], matrixData[ofst + 2], matrixData[ofst + 3]);\r\n            thinInstanceMatrix.setRowFromFloats(1, matrixData[ofst + 4], matrixData[ofst + 5], matrixData[ofst + 6], matrixData[ofst + 7]);\r\n            thinInstanceMatrix.setRowFromFloats(2, matrixData[ofst + 8], matrixData[ofst + 9], matrixData[ofst + 10], matrixData[ofst + 11]);\r\n            thinInstanceMatrix.setRowFromFloats(3, matrixData[ofst + 12], matrixData[ofst + 13], matrixData[ofst + 14], matrixData[ofst + 15]);\r\n        }\r\n\r\n        // Matrix\r\n        const decalWorldMatrix = Matrix.RotationYawPitchRoll(yaw, pitch, angle).multiply(Matrix.Translation(position.x, position.y, position.z));\r\n        const inverseDecalWorldMatrix = Matrix.Invert(decalWorldMatrix);\r\n        const meshWorldMatrix = sourceMesh.getWorldMatrix();\r\n        const transformMatrix = thinInstanceMatrix.multiply(meshWorldMatrix).multiply(inverseDecalWorldMatrix);\r\n\r\n        const oneFaceVertices = new Array<DecalVertex>(3);\r\n\r\n        for (let index = 0; index < indices.length; index += 3) {\r\n            let faceVertices: Nullable<DecalVertex[]> = oneFaceVertices;\r\n\r\n            faceVertices[0] = extractDecalVector3(index, transformMatrix);\r\n            faceVertices[1] = extractDecalVector3(index + 1, transformMatrix);\r\n            faceVertices[2] = extractDecalVector3(index + 2, transformMatrix);\r\n\r\n            if (options.cullBackFaces) {\r\n                // If all the normals of the vertices of the face are pointing away from the view direction we discard the face.\r\n                // As computations are done in the decal coordinate space, the viewDirection is (0,0,1), so when dot(vertexNormal, -viewDirection) <= 0 the vertex is culled\r\n                if (-faceVertices[0].normal.z <= 0 && -faceVertices[1].normal.z <= 0 && -faceVertices[2].normal.z <= 0) {\r\n                    continue;\r\n                }\r\n            }\r\n\r\n            // Clip\r\n            faceVertices = clip(faceVertices, XpAxis);\r\n            if (!faceVertices) {\r\n                continue;\r\n            }\r\n            faceVertices = clip(faceVertices, XnAxis);\r\n            if (!faceVertices) {\r\n                continue;\r\n            }\r\n            faceVertices = clip(faceVertices, YpAxis);\r\n            if (!faceVertices) {\r\n                continue;\r\n            }\r\n            faceVertices = clip(faceVertices, YnAxis);\r\n            if (!faceVertices) {\r\n                continue;\r\n            }\r\n            faceVertices = clip(faceVertices, ZpAxis);\r\n            if (!faceVertices) {\r\n                continue;\r\n            }\r\n            faceVertices = clip(faceVertices, ZnAxis);\r\n            if (!faceVertices) {\r\n                continue;\r\n            }\r\n\r\n            // Add UVs and get back to world\r\n            for (let vIndex = 0; vIndex < faceVertices.length; vIndex++) {\r\n                const vertex = faceVertices[vIndex];\r\n\r\n                //TODO check for Int32Array | Uint32Array | Uint16Array\r\n                vertexData.indices.push(currentVertexDataIndex);\r\n                if (useLocalComputation) {\r\n                    if (vertex.localPositionOverride) {\r\n                        vertexData.positions[currentVertexDataIndex * 3] = vertex.localPositionOverride[0];\r\n                        vertexData.positions[currentVertexDataIndex * 3 + 1] = vertex.localPositionOverride[1];\r\n                        vertexData.positions[currentVertexDataIndex * 3 + 2] = vertex.localPositionOverride[2];\r\n                    } else if (localPositions) {\r\n                        vertexData.positions[currentVertexDataIndex * 3] = localPositions[vertex.vertexIdx];\r\n                        vertexData.positions[currentVertexDataIndex * 3 + 1] = localPositions[vertex.vertexIdx + 1];\r\n                        vertexData.positions[currentVertexDataIndex * 3 + 2] = localPositions[vertex.vertexIdx + 2];\r\n                    }\r\n                    if (vertex.localNormalOverride) {\r\n                        vertexData.normals[currentVertexDataIndex * 3] = vertex.localNormalOverride[0];\r\n                        vertexData.normals[currentVertexDataIndex * 3 + 1] = vertex.localNormalOverride[1];\r\n                        vertexData.normals[currentVertexDataIndex * 3 + 2] = vertex.localNormalOverride[2];\r\n                    } else if (localNormals) {\r\n                        vertexData.normals[currentVertexDataIndex * 3] = localNormals[vertex.vertexIdx];\r\n                        vertexData.normals[currentVertexDataIndex * 3 + 1] = localNormals[vertex.vertexIdx + 1];\r\n                        vertexData.normals[currentVertexDataIndex * 3 + 2] = localNormals[vertex.vertexIdx + 2];\r\n                    }\r\n                } else {\r\n                    vertex.position.toArray(vertexData.positions, currentVertexDataIndex * 3);\r\n                    vertex.normal.toArray(vertexData.normals, currentVertexDataIndex * 3);\r\n                }\r\n                if (vertexData.matricesIndices && vertexData.matricesWeights) {\r\n                    if (vertex.matrixIndicesOverride) {\r\n                        vertexData.matricesIndices[currentVertexDataIndex * 4] = vertex.matrixIndicesOverride[0];\r\n                        vertexData.matricesIndices[currentVertexDataIndex * 4 + 1] = vertex.matrixIndicesOverride[1];\r\n                        vertexData.matricesIndices[currentVertexDataIndex * 4 + 2] = vertex.matrixIndicesOverride[2];\r\n                        vertexData.matricesIndices[currentVertexDataIndex * 4 + 3] = vertex.matrixIndicesOverride[3];\r\n                    } else {\r\n                        if (matIndices) {\r\n                            vertexData.matricesIndices[currentVertexDataIndex * 4] = matIndices[vertex.vertexIdxForBones];\r\n                            vertexData.matricesIndices[currentVertexDataIndex * 4 + 1] = matIndices[vertex.vertexIdxForBones + 1];\r\n                            vertexData.matricesIndices[currentVertexDataIndex * 4 + 2] = matIndices[vertex.vertexIdxForBones + 2];\r\n                            vertexData.matricesIndices[currentVertexDataIndex * 4 + 3] = matIndices[vertex.vertexIdxForBones + 3];\r\n                        }\r\n                        if (matIndicesExtra && vertexData.matricesIndicesExtra) {\r\n                            vertexData.matricesIndicesExtra[currentVertexDataIndex * 4] = matIndicesExtra[vertex.vertexIdxForBones];\r\n                            vertexData.matricesIndicesExtra[currentVertexDataIndex * 4 + 1] = matIndicesExtra[vertex.vertexIdxForBones + 1];\r\n                            vertexData.matricesIndicesExtra[currentVertexDataIndex * 4 + 2] = matIndicesExtra[vertex.vertexIdxForBones + 2];\r\n                            vertexData.matricesIndicesExtra[currentVertexDataIndex * 4 + 3] = matIndicesExtra[vertex.vertexIdxForBones + 3];\r\n                        }\r\n                    }\r\n                    if (vertex.matrixWeightsOverride) {\r\n                        vertexData.matricesWeights[currentVertexDataIndex * 4] = vertex.matrixWeightsOverride[0];\r\n                        vertexData.matricesWeights[currentVertexDataIndex * 4 + 1] = vertex.matrixWeightsOverride[1];\r\n                        vertexData.matricesWeights[currentVertexDataIndex * 4 + 2] = vertex.matrixWeightsOverride[2];\r\n                        vertexData.matricesWeights[currentVertexDataIndex * 4 + 3] = vertex.matrixWeightsOverride[3];\r\n                    } else {\r\n                        if (matWeights) {\r\n                            vertexData.matricesWeights[currentVertexDataIndex * 4] = matWeights[vertex.vertexIdxForBones];\r\n                            vertexData.matricesWeights[currentVertexDataIndex * 4 + 1] = matWeights[vertex.vertexIdxForBones + 1];\r\n                            vertexData.matricesWeights[currentVertexDataIndex * 4 + 2] = matWeights[vertex.vertexIdxForBones + 2];\r\n                            vertexData.matricesWeights[currentVertexDataIndex * 4 + 3] = matWeights[vertex.vertexIdxForBones + 3];\r\n                        }\r\n                        if (matWeightsExtra && vertexData.matricesWeightsExtra) {\r\n                            vertexData.matricesWeightsExtra[currentVertexDataIndex * 4] = matWeightsExtra[vertex.vertexIdxForBones];\r\n                            vertexData.matricesWeightsExtra[currentVertexDataIndex * 4 + 1] = matWeightsExtra[vertex.vertexIdxForBones + 1];\r\n                            vertexData.matricesWeightsExtra[currentVertexDataIndex * 4 + 2] = matWeightsExtra[vertex.vertexIdxForBones + 2];\r\n                            vertexData.matricesWeightsExtra[currentVertexDataIndex * 4 + 3] = matWeightsExtra[vertex.vertexIdxForBones + 3];\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (!options.captureUVS) {\r\n                    vertexData.uvs.push(0.5 + vertex.position.x / size.x);\r\n                    const v = 0.5 + vertex.position.y / size.y;\r\n                    vertexData.uvs.push(useOpenGLOrientationForUV ? 1 - v : v);\r\n                } else {\r\n                    vertex.uv.toArray(vertexData.uvs, currentVertexDataIndex * 2);\r\n                }\r\n                currentVertexDataIndex++;\r\n            }\r\n        }\r\n    }\r\n\r\n    // Avoid the \"Setting vertex data kind 'XXX' with an empty array\" warning when calling vertexData.applyToMesh\r\n    if (vertexData.indices.length === 0) {\r\n        vertexData.indices = null;\r\n    }\r\n    if (vertexData.positions.length === 0) {\r\n        vertexData.positions = null;\r\n    }\r\n    if (vertexData.normals.length === 0) {\r\n        vertexData.normals = null;\r\n    }\r\n    if (vertexData.uvs.length === 0) {\r\n        vertexData.uvs = null;\r\n    }\r\n    if (vertexData.matricesIndices?.length === 0) {\r\n        vertexData.matricesIndices = null;\r\n    }\r\n    if (vertexData.matricesWeights?.length === 0) {\r\n        vertexData.matricesWeights = null;\r\n    }\r\n    if (vertexData.matricesIndicesExtra?.length === 0) {\r\n        vertexData.matricesIndicesExtra = null;\r\n    }\r\n    if (vertexData.matricesWeightsExtra?.length === 0) {\r\n        vertexData.matricesWeightsExtra = null;\r\n    }\r\n\r\n    // Return mesh\r\n    const decal = new Mesh(name, sourceMesh.getScene());\r\n    vertexData.applyToMesh(decal);\r\n\r\n    if (useLocalComputation) {\r\n        decal.skeleton = sourceMesh.skeleton;\r\n        decal.parent = sourceMesh;\r\n    } else {\r\n        decal.position = position.clone();\r\n        decal.rotation = new Vector3(pitch, yaw, angle);\r\n    }\r\n\r\n    decal.computeWorldMatrix(true);\r\n    decal.refreshBoundingInfo(true, true);\r\n\r\n    return decal;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the function directly from the module\r\n */\r\nexport const DecalBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateDecal,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for decalBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDecalBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh.CreateDecal = (name: string, sourceMesh: AbstractMesh, position: Vector3, normal: Vector3, size: Vector3, angle: number): Mesh => {\r\n        const options = {\r\n            position,\r\n            normal,\r\n            size,\r\n            angle,\r\n        };\r\n\r\n        return CreateDecal(name, sourceMesh, options);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { Vector2, Vector3, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Scripts based off of https://github.com/maximeq/three-js-capsule-geometry/blob/master/src/CapsuleBufferGeometry.js\r\n * @param options the constructors options used to shape the mesh.\r\n * @returns the capsule VertexData\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/capsule\r\n */\r\nexport function CreateCapsuleVertexData(\r\n    options: ICreateCapsuleOptions = {\r\n        subdivisions: 2,\r\n        tessellation: 16,\r\n        height: 1,\r\n        radius: 0.25,\r\n        capSubdivisions: 6,\r\n    }\r\n): VertexData {\r\n    const subdivisions = Math.max(options.subdivisions ? options.subdivisions : 2, 1) | 0;\r\n    const tessellation = Math.max(options.tessellation ? options.tessellation : 16, 3) | 0;\r\n    const height = Math.max(options.height ? options.height : 1, 0);\r\n    const radius = Math.max(options.radius ? options.radius : 0.25, 0);\r\n    const capDetail = Math.max(options.capSubdivisions ? options.capSubdivisions : 6, 1) | 0;\r\n\r\n    const radialSegments = tessellation;\r\n    const heightSegments = subdivisions;\r\n\r\n    const radiusTop = Math.max(options.radiusTop ? options.radiusTop : radius, 0);\r\n    const radiusBottom = Math.max(options.radiusBottom ? options.radiusBottom : radius, 0);\r\n\r\n    const heightMinusCaps = height - (radiusTop + radiusBottom);\r\n\r\n    const thetaStart = 0.0;\r\n    const thetaLength = 2.0 * Math.PI;\r\n\r\n    const capsTopSegments = Math.max(options.topCapSubdivisions ? options.topCapSubdivisions : capDetail, 1);\r\n    const capsBottomSegments = Math.max(options.bottomCapSubdivisions ? options.bottomCapSubdivisions : capDetail, 1);\r\n\r\n    const alpha = Math.acos((radiusBottom - radiusTop) / height);\r\n\r\n    let indices = [];\r\n    const vertices = [];\r\n    const normals = [];\r\n    const uvs = [];\r\n\r\n    let index = 0;\r\n    const indexArray = [],\r\n        halfHeight = heightMinusCaps * 0.5;\r\n    const pi2 = Math.PI * 0.5;\r\n\r\n    let x, y;\r\n    const normal = Vector3.Zero();\r\n    const vertex = Vector3.Zero();\r\n\r\n    const cosAlpha = Math.cos(alpha);\r\n    const sinAlpha = Math.sin(alpha);\r\n\r\n    const coneLength = new Vector2(radiusTop * sinAlpha, halfHeight + radiusTop * cosAlpha)\r\n        .subtract(new Vector2(radiusBottom * sinAlpha, -halfHeight + radiusBottom * cosAlpha))\r\n        .length();\r\n\r\n    // Total length for v texture coord\r\n    const vl = radiusTop * alpha + coneLength + radiusBottom * (pi2 - alpha);\r\n\r\n    let v = 0;\r\n    for (y = 0; y <= capsTopSegments; y++) {\r\n        const indexRow = [];\r\n\r\n        const a = pi2 - alpha * (y / capsTopSegments);\r\n\r\n        v += (radiusTop * alpha) / capsTopSegments;\r\n\r\n        const cosA = Math.cos(a);\r\n        const sinA = Math.sin(a);\r\n\r\n        // calculate the radius of the current row\r\n        const _radius = cosA * radiusTop;\r\n\r\n        for (x = 0; x <= radialSegments; x++) {\r\n            const u = x / radialSegments;\r\n            const theta = u * thetaLength + thetaStart;\r\n            const sinTheta = Math.sin(theta);\r\n            const cosTheta = Math.cos(theta);\r\n            // vertex\r\n            vertex.x = _radius * sinTheta;\r\n            vertex.y = halfHeight + sinA * radiusTop;\r\n            vertex.z = _radius * cosTheta;\r\n            vertices.push(vertex.x, vertex.y, vertex.z);\r\n            // normal\r\n            normal.set(cosA * sinTheta, sinA, cosA * cosTheta);\r\n            normals.push(normal.x, normal.y, normal.z);\r\n            // uv\r\n            uvs.push(u, useOpenGLOrientationForUV ? v / vl : 1 - v / vl);\r\n            // save index of vertex in respective row\r\n            indexRow.push(index);\r\n            // increase index\r\n            index++;\r\n        }\r\n        // now save vertices of the row in our index array\r\n        indexArray.push(indexRow);\r\n    }\r\n\r\n    const coneHeight = height - radiusTop - radiusBottom + cosAlpha * radiusTop - cosAlpha * radiusBottom;\r\n    const slope = (sinAlpha * (radiusBottom - radiusTop)) / coneHeight;\r\n\r\n    for (y = 1; y <= heightSegments; y++) {\r\n        const indexRow = [];\r\n        v += coneLength / heightSegments;\r\n        // calculate the radius of the current row\r\n        const _radius = sinAlpha * ((y * (radiusBottom - radiusTop)) / heightSegments + radiusTop);\r\n        for (x = 0; x <= radialSegments; x++) {\r\n            const u = x / radialSegments;\r\n            const theta = u * thetaLength + thetaStart;\r\n            const sinTheta = Math.sin(theta);\r\n            const cosTheta = Math.cos(theta);\r\n            // vertex\r\n            vertex.x = _radius * sinTheta;\r\n            vertex.y = halfHeight + cosAlpha * radiusTop - (y * coneHeight) / heightSegments;\r\n            vertex.z = _radius * cosTheta;\r\n            vertices.push(vertex.x, vertex.y, vertex.z);\r\n            // normal\r\n            normal.set(sinTheta, slope, cosTheta).normalize();\r\n            normals.push(normal.x, normal.y, normal.z);\r\n            // uv\r\n            uvs.push(u, useOpenGLOrientationForUV ? v / vl : 1 - v / vl);\r\n            // save index of vertex in respective row\r\n            indexRow.push(index);\r\n            // increase index\r\n            index++;\r\n        }\r\n        // now save vertices of the row in our index array\r\n        indexArray.push(indexRow);\r\n    }\r\n\r\n    for (y = 1; y <= capsBottomSegments; y++) {\r\n        const indexRow = [];\r\n        const a = pi2 - alpha - (Math.PI - alpha) * (y / capsBottomSegments);\r\n        v += (radiusBottom * alpha) / capsBottomSegments;\r\n        const cosA = Math.cos(a);\r\n        const sinA = Math.sin(a);\r\n        // calculate the radius of the current row\r\n        const _radius = cosA * radiusBottom;\r\n        for (x = 0; x <= radialSegments; x++) {\r\n            const u = x / radialSegments;\r\n            const theta = u * thetaLength + thetaStart;\r\n            const sinTheta = Math.sin(theta);\r\n            const cosTheta = Math.cos(theta);\r\n            // vertex\r\n            vertex.x = _radius * sinTheta;\r\n            vertex.y = -halfHeight + sinA * radiusBottom;\r\n            vertex.z = _radius * cosTheta;\r\n            vertices.push(vertex.x, vertex.y, vertex.z);\r\n            // normal\r\n            normal.set(cosA * sinTheta, sinA, cosA * cosTheta);\r\n            normals.push(normal.x, normal.y, normal.z);\r\n            // uv\r\n            uvs.push(u, useOpenGLOrientationForUV ? v / vl : 1 - v / vl);\r\n            // save index of vertex in respective row\r\n            indexRow.push(index);\r\n            // increase index\r\n            index++;\r\n        }\r\n        // now save vertices of the row in our index array\r\n        indexArray.push(indexRow);\r\n    }\r\n    // generate indices\r\n    for (x = 0; x < radialSegments; x++) {\r\n        for (y = 0; y < capsTopSegments + heightSegments + capsBottomSegments; y++) {\r\n            // we use the index array to access the correct indices\r\n            const i1 = indexArray[y][x];\r\n            const i2 = indexArray[y + 1][x];\r\n            const i3 = indexArray[y + 1][x + 1];\r\n            const i4 = indexArray[y][x + 1];\r\n            // face one\r\n            indices.push(i1);\r\n            indices.push(i2);\r\n            indices.push(i4);\r\n            // face two\r\n            indices.push(i2);\r\n            indices.push(i3);\r\n            indices.push(i4);\r\n        }\r\n    }\r\n\r\n    indices = indices.reverse();\r\n\r\n    if (options.orientation && !options.orientation.equals(Vector3.Up())) {\r\n        const m = new Matrix();\r\n        options.orientation\r\n            .clone()\r\n            .scale(Math.PI * 0.5)\r\n            .cross(Vector3.Up())\r\n            .toQuaternion()\r\n            .toRotationMatrix(m);\r\n        const v = Vector3.Zero();\r\n        for (let i = 0; i < vertices.length; i += 3) {\r\n            v.set(vertices[i], vertices[i + 1], vertices[i + 2]);\r\n            Vector3.TransformCoordinatesToRef(v.clone(), m, v);\r\n            vertices[i] = v.x;\r\n            vertices[i + 1] = v.y;\r\n            vertices[i + 2] = v.z;\r\n        }\r\n    }\r\n\r\n    const vDat = new VertexData();\r\n    vDat.positions = vertices;\r\n    vDat.normals = normals;\r\n    vDat.uvs = uvs;\r\n    vDat.indices = indices;\r\n\r\n    return vDat;\r\n}\r\n\r\n/**\r\n * The options Interface for creating a Capsule Mesh\r\n */\r\nexport interface ICreateCapsuleOptions {\r\n    /** The Orientation of the capsule.  Default : Vector3.Up() */\r\n    orientation?: Vector3;\r\n\r\n    /** Number of sub segments on the tube section of the capsule running parallel to orientation. */\r\n    subdivisions?: number;\r\n\r\n    /** Number of cylindrical segments on the capsule. */\r\n    tessellation?: number;\r\n\r\n    /** Height or Length of the capsule. */\r\n    height?: number;\r\n\r\n    /** Radius of the capsule. */\r\n    radius?: number;\r\n\r\n    /** Number of sub segments on the cap sections of the capsule running parallel to orientation. */\r\n    capSubdivisions?: number;\r\n\r\n    /** Overwrite for the top radius. */\r\n    radiusTop?: number;\r\n\r\n    /** Overwrite for the bottom radius. */\r\n    radiusBottom?: number;\r\n\r\n    /** Overwrite for the top capSubdivisions. */\r\n    topCapSubdivisions?: number;\r\n\r\n    /** Overwrite for the bottom capSubdivisions. */\r\n    bottomCapSubdivisions?: number;\r\n\r\n    /** Internal geometry is supposed to change once created. */\r\n    updatable?: boolean;\r\n}\r\n\r\n/**\r\n * Creates a capsule or a pill mesh\r\n * @param name defines the name of the mesh\r\n * @param options The constructors options.\r\n * @param scene The scene the mesh is scoped to.\r\n * @returns Capsule Mesh\r\n */\r\nexport function CreateCapsule(\r\n    name: string,\r\n    options: ICreateCapsuleOptions = {\r\n        orientation: Vector3.Up(),\r\n        subdivisions: 2,\r\n        tessellation: 16,\r\n        height: 1,\r\n        radius: 0.25,\r\n        capSubdivisions: 6,\r\n        updatable: false,\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    const capsule = new Mesh(name, scene);\r\n    const vertexData = CreateCapsuleVertexData(options);\r\n    vertexData.applyToMesh(capsule, options.updatable);\r\n    return capsule;\r\n}\r\n\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated please use CreateCapsule directly\r\n */\r\nexport const CapsuleBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateCapsule,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for capsuleBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCapsuleBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Creates a capsule or a pill mesh\r\n     * @param name defines the name of the mesh.\r\n     * @param options the constructors options used to shape the mesh.\r\n     * @param scene defines the scene the mesh is scoped to.\r\n     * @returns the capsule mesh\r\n     * @see https://doc.babylonjs.com/how_to/capsule_shape\r\n     */\r\n    Mesh.CreateCapsule = (name: string, options: ICreateCapsuleOptions, scene?: Nullable<Scene>): Mesh => {\r\n        return CreateCapsule(name, options, scene);\r\n    };\r\n\r\n    VertexData.CreateCapsule = CreateCapsuleVertexData;\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { Vector3 } from \"./math.vector.pure\";\r\n\r\n/**\r\n * Class representing an isovector a vector containing 2 INTEGER coordinates\r\n * x axis is horizontal\r\n * y axis is 60 deg counter clockwise from positive y axis\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _IsoVector {\r\n    /**\r\n     * Creates a new isovector from the given x and y coordinates\r\n     * @param x defines the first coordinate, must be an integer\r\n     * @param y defines the second coordinate, must be an integer\r\n     */\r\n    constructor(\r\n        /** [0] defines the first coordinate */\r\n        public x: number = 0,\r\n        /** [0] defines the second coordinate */\r\n        public y: number = 0\r\n    ) {\r\n        if (x !== Math.floor(x)) {\r\n            x = Math.floor(x);\r\n            Logger.Warn(\"x is not an integer, floor(x) used\");\r\n        }\r\n        if (y !== Math.floor(y)) {\r\n            y = Math.floor(y);\r\n            Logger.Warn(\"y is not an integer, floor(y) used\");\r\n        }\r\n    }\r\n\r\n    // Operators\r\n\r\n    /**\r\n     * Gets a new IsoVector copied from the IsoVector\r\n     * @returns a new IsoVector\r\n     */\r\n    public clone(): _IsoVector {\r\n        return new _IsoVector(this.x, this.y);\r\n    }\r\n\r\n    /**\r\n     * Rotates one IsoVector 60 degrees counter clockwise about another\r\n     * Please note that this is an in place operation\r\n     * @param other an IsoVector a center of rotation\r\n     * @returns the rotated IsoVector\r\n     */\r\n    public rotate60About(other: _IsoVector) {\r\n        //other IsoVector\r\n        const x: number = this.x;\r\n        this.x = other.x + other.y - this.y;\r\n        this.y = x + this.y - other.x;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Rotates one IsoVector 60 degrees clockwise about another\r\n     * Please note that this is an in place operation\r\n     * @param other an IsoVector as center of rotation\r\n     * @returns the rotated IsoVector\r\n     */\r\n    public rotateNeg60About(other: _IsoVector) {\r\n        const x = this.x;\r\n        this.x = x + this.y - other.y;\r\n        this.y = other.x + other.y - x;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * For an equilateral triangle OAB with O at isovector (0, 0) and A at isovector (m, n)\r\n     * Rotates one IsoVector 120 degrees counter clockwise about the center of the triangle\r\n     * Please note that this is an in place operation\r\n     * @param m integer a measure a Primary triangle of order (m, n) m > n\r\n     * @param n >= 0 integer a measure for a Primary triangle of order (m, n)\r\n     * @returns the rotated IsoVector\r\n     */\r\n    public rotate120(m: number, n: number) {\r\n        //m, n integers\r\n        if (m !== Math.floor(m)) {\r\n            m = Math.floor(m);\r\n            Logger.Warn(\"m not an integer only floor(m) used\");\r\n        }\r\n        if (n !== Math.floor(n)) {\r\n            n = Math.floor(n);\r\n            Logger.Warn(\"n not an integer only floor(n) used\");\r\n        }\r\n        const x = this.x;\r\n        this.x = m - x - this.y;\r\n        this.y = n + x;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * For an equilateral triangle OAB with O at isovector (0, 0) and A at isovector (m, n)\r\n     * Rotates one IsoVector 120 degrees clockwise about the center of the triangle\r\n     * Please note that this is an in place operation\r\n     * @param m integer a measure a Primary triangle of order (m, n) m > n\r\n     * @param n >= 0 integer a measure for a Primary triangle of order (m, n)\r\n     * @returns the rotated IsoVector\r\n     */\r\n    public rotateNeg120(m: number, n: number) {\r\n        //m, n integers\r\n        if (m !== Math.floor(m)) {\r\n            m = Math.floor(m);\r\n            Logger.Warn(\"m is not an integer, floor(m) used\");\r\n        }\r\n        if (n !== Math.floor(n)) {\r\n            n = Math.floor(n);\r\n            Logger.Warn(\"n is not an integer,   floor(n) used\");\r\n        }\r\n        const x = this.x;\r\n        this.x = this.y - n;\r\n        this.y = m + n - x - this.y;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Transforms an IsoVector to one in Cartesian 3D space based on an isovector\r\n     * @param origin an IsoVector\r\n     * @param isoGridSize\r\n     * @returns Point as a Vector3\r\n     */\r\n    public toCartesianOrigin(origin: _IsoVector, isoGridSize: number) {\r\n        const point = Vector3.Zero();\r\n        point.x = origin.x + 2 * this.x * isoGridSize + this.y * isoGridSize;\r\n        point.y = origin.y + Math.sqrt(3) * this.y * isoGridSize;\r\n        return point;\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Gets a new IsoVector(0, 0)\r\n     * @returns a new IsoVector\r\n     */\r\n    public static Zero(): _IsoVector {\r\n        return new _IsoVector(0, 0);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { HighestCommonFactor } from \"../Maths/math.scalar.functions\";\r\nimport { PHI } from \"../Maths/math.constants\";\r\nimport { _IsoVector } from \"../Maths/math.isovector\";\r\n\r\n/**\r\n * Class representing data for one face OAB of an equilateral icosahedron\r\n * When O is the isovector (0, 0), A is isovector (m, n)\r\n * @internal\r\n */\r\nexport class _PrimaryIsoTriangle {\r\n    //properties\r\n    /** @internal */\r\n    public m: number;\r\n    /** @internal */\r\n    public n: number;\r\n    /** @internal */\r\n    public cartesian: Vector3[] = [];\r\n    /** @internal */\r\n    public vertices: _IsoVector[] = [];\r\n    /** @internal */\r\n    public max: number[] = [];\r\n    /** @internal */\r\n    public min: number[] = [];\r\n    /** @internal */\r\n    public vecToidx: { [key: string]: number };\r\n    /** @internal */\r\n    public vertByDist: { [key: string]: number[] };\r\n    /** @internal */\r\n    public closestTo: number[][] = [];\r\n\r\n    /** @internal */\r\n    public innerFacets: string[][] = [];\r\n    /** @internal */\r\n    public isoVecsABOB: _IsoVector[][] = [];\r\n    /** @internal */\r\n    public isoVecsOBOA: _IsoVector[][] = [];\r\n    /** @internal */\r\n    public isoVecsBAOA: _IsoVector[][] = [];\r\n    /** @internal */\r\n    public vertexTypes: number[][] = [];\r\n\r\n    /** @internal */\r\n    public coau: number;\r\n    /** @internal */\r\n    public cobu: number;\r\n    /** @internal */\r\n    public coav: number;\r\n    /** @internal */\r\n    public cobv: number;\r\n\r\n    /** @internal */\r\n    public IDATA: PolyhedronData = new PolyhedronData(\r\n        \"icosahedron\",\r\n        \"Regular\",\r\n        [\r\n            [0, PHI, -1],\r\n            [-PHI, 1, 0],\r\n            [-1, 0, -PHI],\r\n            [1, 0, -PHI],\r\n            [PHI, 1, 0],\r\n            [0, PHI, 1],\r\n            [-1, 0, PHI],\r\n            [-PHI, -1, 0],\r\n            [0, -PHI, -1],\r\n            [PHI, -1, 0],\r\n            [1, 0, PHI],\r\n            [0, -PHI, 1],\r\n        ],\r\n        [\r\n            [0, 2, 1],\r\n            [0, 3, 2],\r\n            [0, 4, 3],\r\n            [0, 5, 4],\r\n            [0, 1, 5],\r\n            [7, 6, 1],\r\n            [8, 7, 2],\r\n            [9, 8, 3],\r\n            [10, 9, 4],\r\n            [6, 10, 5],\r\n            [2, 7, 1],\r\n            [3, 8, 2],\r\n            [4, 9, 3],\r\n            [5, 10, 4],\r\n            [1, 6, 5],\r\n            [11, 6, 7],\r\n            [11, 7, 8],\r\n            [11, 8, 9],\r\n            [11, 9, 10],\r\n            [11, 10, 6],\r\n        ]\r\n    );\r\n\r\n    /**\r\n     * Creates the PrimaryIsoTriangle Triangle OAB\r\n     * @param m an integer\r\n     * @param n an integer\r\n     */\r\n\r\n    //operators\r\n    public setIndices() {\r\n        let indexCount = 12; // 12 vertices already assigned\r\n        const vecToidx: { [key: string]: number } = {}; //maps iso-vectors to indexCount;\r\n        const m = this.m;\r\n        const n = this.n;\r\n        let g = m; // hcf of m, n when n != 0\r\n        if (n !== 0) {\r\n            g = HighestCommonFactor(m, n);\r\n        }\r\n        const m1 = m / g;\r\n        const n1 = n / g;\r\n\r\n        let fr: number | string; //face to the right of current face\r\n        let rot: number | string; //rotation about which vertex for fr\r\n        let O: number;\r\n        let A: number;\r\n        let B: number;\r\n        const oVec: _IsoVector = _IsoVector.Zero();\r\n        const aVec = new _IsoVector(m, n);\r\n        const bVec = new _IsoVector(-n, m + n);\r\n        const oaVec: _IsoVector = _IsoVector.Zero();\r\n        const abVec: _IsoVector = _IsoVector.Zero();\r\n        const obVec: _IsoVector = _IsoVector.Zero();\r\n        let verts: number[] = [];\r\n        let idx: string;\r\n        let idxR: string;\r\n        let isoId: string;\r\n        let isoIdR: string;\r\n\r\n        const closestTo: number[][] = [];\r\n        const vDist = this.vertByDist;\r\n\r\n        const matchIdx = (f: number, fr: number, isoId: string, isoIdR: string) => {\r\n            idx = f + \"|\" + isoId;\r\n            idxR = fr + \"|\" + isoIdR;\r\n            if (!(idx in vecToidx || idxR in vecToidx)) {\r\n                vecToidx[idx] = indexCount;\r\n                vecToidx[idxR] = indexCount;\r\n                indexCount++;\r\n            } else if (idx in vecToidx && !(idxR in vecToidx)) {\r\n                vecToidx[idxR] = vecToidx[idx];\r\n            } else if (idxR in vecToidx && !(idx in vecToidx)) {\r\n                vecToidx[idx] = vecToidx[idxR];\r\n            }\r\n            if (vDist[isoId][0] > 2) {\r\n                closestTo[vecToidx[idx]] = [-vDist[isoId][0], vDist[isoId][1], vecToidx[idx]];\r\n            } else {\r\n                closestTo[vecToidx[idx]] = [verts[vDist[isoId][0]], vDist[isoId][1], vecToidx[idx]];\r\n            }\r\n        };\r\n\r\n        this.IDATA.edgematch = [\r\n            [1, \"B\"],\r\n            [2, \"B\"],\r\n            [3, \"B\"],\r\n            [4, \"B\"],\r\n            [0, \"B\"],\r\n            [10, \"O\", 14, \"A\"],\r\n            [11, \"O\", 10, \"A\"],\r\n            [12, \"O\", 11, \"A\"],\r\n            [13, \"O\", 12, \"A\"],\r\n            [14, \"O\", 13, \"A\"],\r\n            [0, \"O\"],\r\n            [1, \"O\"],\r\n            [2, \"O\"],\r\n            [3, \"O\"],\r\n            [4, \"O\"],\r\n            [19, \"B\", 5, \"A\"],\r\n            [15, \"B\", 6, \"A\"],\r\n            [16, \"B\", 7, \"A\"],\r\n            [17, \"B\", 8, \"A\"],\r\n            [18, \"B\", 9, \"A\"],\r\n        ];\r\n\r\n        /***edges AB to OB***** rotation about B*/\r\n        for (let f = 0; f < 20; f++) {\r\n            //f current face\r\n\r\n            verts = this.IDATA.face[f];\r\n            O = verts[2];\r\n            A = verts[1];\r\n            B = verts[0];\r\n\r\n            isoId = oVec.x + \"|\" + oVec.y;\r\n            idx = f + \"|\" + isoId;\r\n            if (!(idx in vecToidx)) {\r\n                vecToidx[idx] = O;\r\n                closestTo[O] = [verts[vDist[isoId][0]], vDist[isoId][1]];\r\n            }\r\n\r\n            isoId = aVec.x + \"|\" + aVec.y;\r\n            idx = f + \"|\" + isoId;\r\n            if (!(idx in vecToidx)) {\r\n                vecToidx[idx] = A;\r\n                closestTo[A] = [verts[vDist[isoId][0]], vDist[isoId][1]];\r\n            }\r\n\r\n            isoId = bVec.x + \"|\" + bVec.y;\r\n            idx = f + \"|\" + isoId;\r\n            if (!(idx in vecToidx)) {\r\n                vecToidx[idx] = B;\r\n                closestTo[B] = [verts[vDist[isoId][0]], vDist[isoId][1]];\r\n            }\r\n\r\n            //for edge vertices\r\n            fr = <number>this.IDATA.edgematch[f][0];\r\n            rot = <string>this.IDATA.edgematch[f][1];\r\n            if (rot === \"B\") {\r\n                for (let i = 1; i < g; i++) {\r\n                    abVec.x = m - i * (m1 + n1);\r\n                    abVec.y = n + i * m1;\r\n                    obVec.x = -i * n1;\r\n                    obVec.y = i * (m1 + n1);\r\n                    isoId = abVec.x + \"|\" + abVec.y;\r\n                    isoIdR = obVec.x + \"|\" + obVec.y;\r\n                    matchIdx(f, fr, isoId, isoIdR);\r\n                }\r\n            }\r\n\r\n            if (rot === \"O\") {\r\n                for (let i = 1; i < g; i++) {\r\n                    obVec.x = -i * n1;\r\n                    obVec.y = i * (m1 + n1);\r\n                    oaVec.x = i * m1;\r\n                    oaVec.y = i * n1;\r\n                    isoId = obVec.x + \"|\" + obVec.y;\r\n                    isoIdR = oaVec.x + \"|\" + oaVec.y;\r\n                    matchIdx(f, fr, isoId, isoIdR);\r\n                }\r\n            }\r\n\r\n            fr = <number>this.IDATA.edgematch[f][2];\r\n            rot = <string>this.IDATA.edgematch[f][3];\r\n            if (rot && rot === \"A\") {\r\n                for (let i = 1; i < g; i++) {\r\n                    oaVec.x = i * m1;\r\n                    oaVec.y = i * n1;\r\n                    abVec.x = m - (g - i) * (m1 + n1); //reversed for BA\r\n                    abVec.y = n + (g - i) * m1; //reversed for BA\r\n                    isoId = oaVec.x + \"|\" + oaVec.y;\r\n                    isoIdR = abVec.x + \"|\" + abVec.y;\r\n                    matchIdx(f, fr, isoId, isoIdR);\r\n                }\r\n            }\r\n\r\n            for (let i = 0; i < this.vertices.length; i++) {\r\n                isoId = this.vertices[i].x + \"|\" + this.vertices[i].y;\r\n                idx = f + \"|\" + isoId;\r\n                if (!(idx in vecToidx)) {\r\n                    vecToidx[idx] = indexCount++;\r\n                    if (vDist[isoId][0] > 2) {\r\n                        closestTo[vecToidx[idx]] = [-vDist[isoId][0], vDist[isoId][1], vecToidx[idx]];\r\n                    } else {\r\n                        closestTo[vecToidx[idx]] = [verts[vDist[isoId][0]], vDist[isoId][1], vecToidx[idx]];\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this.closestTo = closestTo;\r\n        this.vecToidx = vecToidx;\r\n    }\r\n\r\n    /** @internal */\r\n    public calcCoeffs() {\r\n        const m = this.m;\r\n        const n = this.n;\r\n        const thirdR3 = Math.sqrt(3) / 3;\r\n\r\n        const LSQD = m * m + n * n + m * n;\r\n\r\n        this.coau = (m + n) / LSQD;\r\n        this.cobu = -n / LSQD;\r\n        this.coav = (-thirdR3 * (m - n)) / LSQD;\r\n        this.cobv = (thirdR3 * (2 * m + n)) / LSQD;\r\n    }\r\n\r\n    /** @internal */\r\n    public createInnerFacets() {\r\n        const m = this.m;\r\n        const n = this.n;\r\n        for (let y = 0; y < n + m + 1; y++) {\r\n            for (let x = this.min[y]; x < this.max[y] + 1; x++) {\r\n                if (x < this.max[y] && x < this.max[y + 1] + 1) {\r\n                    this.innerFacets.push([\"|\" + x + \"|\" + y, \"|\" + x + \"|\" + (y + 1), \"|\" + (x + 1) + \"|\" + y]);\r\n                }\r\n                if (y > 0 && x < this.max[y - 1] && x + 1 < this.max[y] + 1) {\r\n                    this.innerFacets.push([\"|\" + x + \"|\" + y, \"|\" + (x + 1) + \"|\" + y, \"|\" + (x + 1) + \"|\" + (y - 1)]);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public edgeVecsABOB() {\r\n        const m = this.m;\r\n        const n = this.n;\r\n\r\n        const B = new _IsoVector(-n, m + n);\r\n\r\n        for (let y = 1; y < m + n; y++) {\r\n            const point = new _IsoVector(this.min[y], y);\r\n            const prev = new _IsoVector(this.min[y - 1], y - 1);\r\n            const next = new _IsoVector(this.min[y + 1], y + 1);\r\n            const pointR = point.clone();\r\n            const prevR = prev.clone();\r\n            const nextR = next.clone();\r\n\r\n            pointR.rotate60About(B);\r\n            prevR.rotate60About(B);\r\n            nextR.rotate60About(B);\r\n\r\n            const maxPoint = new _IsoVector(this.max[pointR.y], pointR.y);\r\n            const maxPrev = new _IsoVector(this.max[pointR.y - 1], pointR.y - 1);\r\n            const maxLeftPrev = new _IsoVector(this.max[pointR.y - 1] - 1, pointR.y - 1);\r\n\r\n            if (pointR.x !== maxPoint.x || pointR.y !== maxPoint.y) {\r\n                if (pointR.x !== maxPrev.x) {\r\n                    // type2\r\n                    //up\r\n                    this.vertexTypes.push([1, 0, 0]);\r\n                    this.isoVecsABOB.push([point, maxPrev, maxLeftPrev]);\r\n                    //down\r\n                    this.vertexTypes.push([1, 0, 0]);\r\n                    this.isoVecsABOB.push([point, maxLeftPrev, maxPoint]);\r\n                } else if (pointR.y === nextR.y) {\r\n                    // type1\r\n                    //up\r\n                    this.vertexTypes.push([1, 1, 0]);\r\n                    this.isoVecsABOB.push([point, prev, maxPrev]);\r\n                    //down\r\n                    this.vertexTypes.push([1, 0, 1]);\r\n                    this.isoVecsABOB.push([point, maxPrev, next]);\r\n                } else {\r\n                    // type 0\r\n                    //up\r\n                    this.vertexTypes.push([1, 1, 0]);\r\n                    this.isoVecsABOB.push([point, prev, maxPrev]);\r\n                    //down\r\n                    this.vertexTypes.push([1, 0, 0]);\r\n                    this.isoVecsABOB.push([point, maxPrev, maxPoint]);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public mapABOBtoOBOA() {\r\n        const point = new _IsoVector(0, 0);\r\n        for (let i = 0; i < this.isoVecsABOB.length; i++) {\r\n            const temp = [];\r\n            for (let j = 0; j < 3; j++) {\r\n                point.x = this.isoVecsABOB[i][j].x;\r\n                point.y = this.isoVecsABOB[i][j].y;\r\n                if (this.vertexTypes[i][j] === 0) {\r\n                    point.rotateNeg120(this.m, this.n);\r\n                }\r\n                temp.push(point.clone());\r\n            }\r\n            this.isoVecsOBOA.push(temp);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public mapABOBtoBAOA() {\r\n        const point = new _IsoVector(0, 0);\r\n        for (let i = 0; i < this.isoVecsABOB.length; i++) {\r\n            const temp = [];\r\n            for (let j = 0; j < 3; j++) {\r\n                point.x = this.isoVecsABOB[i][j].x;\r\n                point.y = this.isoVecsABOB[i][j].y;\r\n                if (this.vertexTypes[i][j] === 1) {\r\n                    point.rotate120(this.m, this.n);\r\n                }\r\n                temp.push(point.clone());\r\n            }\r\n            this.isoVecsBAOA.push(temp);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public MapToFace(faceNb: number, geodesicData: PolyhedronData) {\r\n        const F = this.IDATA.face[faceNb];\r\n        const oidx = F[2];\r\n        const aidx = F[1];\r\n        const bidx = F[0];\r\n\r\n        const O = Vector3.FromArray(this.IDATA.vertex[oidx]);\r\n        const A = Vector3.FromArray(this.IDATA.vertex[aidx]);\r\n        const B = Vector3.FromArray(this.IDATA.vertex[bidx]);\r\n\r\n        const OA = A.subtract(O);\r\n        const OB = B.subtract(O);\r\n\r\n        const x: Vector3 = OA.scale(this.coau).add(OB.scale(this.cobu));\r\n        const y: Vector3 = OA.scale(this.coav).add(OB.scale(this.cobv));\r\n\r\n        const mapped = [];\r\n\r\n        let idx: string;\r\n        let tempVec: Vector3;\r\n        for (let i = 0; i < this.cartesian.length; i++) {\r\n            tempVec = x.scale(this.cartesian[i].x).add(y.scale(this.cartesian[i].y)).add(O);\r\n            mapped[i] = [tempVec.x, tempVec.y, tempVec.z];\r\n            idx = faceNb + \"|\" + this.vertices[i].x + \"|\" + this.vertices[i].y;\r\n            geodesicData.vertex[this.vecToidx[idx]] = [tempVec.x, tempVec.y, tempVec.z];\r\n        }\r\n    }\r\n\r\n    //statics\r\n    /**Creates a primary triangle\r\n     * @internal\r\n     */\r\n\r\n    public build(m: number, n: number) {\r\n        const vertices: _IsoVector[] = [];\r\n\r\n        const O: _IsoVector = _IsoVector.Zero();\r\n        const A: _IsoVector = new _IsoVector(m, n);\r\n        const B: _IsoVector = new _IsoVector(-n, m + n);\r\n        vertices.push(O, A, B);\r\n\r\n        //max internal isoceles triangle vertices\r\n        for (let y = n; y < m + 1; y++) {\r\n            for (let x = 0; x < m + 1 - y; x++) {\r\n                vertices.push(new _IsoVector(x, y));\r\n            }\r\n        }\r\n\r\n        //shared vertices along edges when needed\r\n        if (n > 0) {\r\n            const g = HighestCommonFactor(m, n);\r\n            const m1 = m / g;\r\n            const n1 = n / g;\r\n\r\n            for (let i = 1; i < g; i++) {\r\n                vertices.push(new _IsoVector(i * m1, i * n1)); //OA\r\n                vertices.push(new _IsoVector(-i * n1, i * (m1 + n1))); //OB\r\n                vertices.push(new _IsoVector(m - i * (m1 + n1), n + i * m1)); // AB\r\n            }\r\n\r\n            //lower rows vertices and their rotations\r\n            const ratio = m / n;\r\n            for (let y = 1; y < n; y++) {\r\n                for (let x = 0; x < y * ratio; x++) {\r\n                    vertices.push(new _IsoVector(x, y));\r\n                    vertices.push(new _IsoVector(x, y).rotate120(m, n));\r\n                    vertices.push(new _IsoVector(x, y).rotateNeg120(m, n));\r\n                }\r\n            }\r\n        }\r\n        //order vertices by x and then y\r\n        vertices.sort((a, b) => {\r\n            return a.x - b.x;\r\n        });\r\n\r\n        vertices.sort((a, b) => {\r\n            return a.y - b.y;\r\n        });\r\n\r\n        const min = new Array<number>(m + n + 1);\r\n        const max = new Array<number>(m + n + 1);\r\n        for (let i = 0; i < min.length; i++) {\r\n            min[i] = Infinity;\r\n            max[i] = -Infinity;\r\n        }\r\n\r\n        let y: number;\r\n        let x: number;\r\n\r\n        const len: number = vertices.length;\r\n        for (let i = 0; i < len; i++) {\r\n            x = vertices[i].x;\r\n            y = vertices[i].y;\r\n            min[y] = Math.min(x, min[y]);\r\n            max[y] = Math.max(x, max[y]);\r\n        }\r\n\r\n        //calculates the distance of a vertex from a given primary vertex\r\n        const distFrom = (vert: _IsoVector, primVert: string) => {\r\n            const v = vert.clone();\r\n            if (primVert === \"A\") {\r\n                v.rotateNeg120(m, n);\r\n            }\r\n            if (primVert === \"B\") {\r\n                v.rotate120(m, n);\r\n            }\r\n            if (v.x < 0) {\r\n                return v.y;\r\n            }\r\n            return v.x + v.y;\r\n        };\r\n\r\n        const cartesian: Vector3[] = [];\r\n        const distFromO: number[] = [];\r\n        const distFromA: number[] = [];\r\n        const distFromB: number[] = [];\r\n        const vertByDist: { [key: string]: number[] } = {};\r\n        const vertData: number[][] = [];\r\n        let closest: number = -1;\r\n        let dist: number = -1;\r\n        for (let i = 0; i < len; i++) {\r\n            cartesian[i] = vertices[i].toCartesianOrigin(new _IsoVector(0, 0), 0.5);\r\n            distFromO[i] = distFrom(vertices[i], \"O\");\r\n            distFromA[i] = distFrom(vertices[i], \"A\");\r\n            distFromB[i] = distFrom(vertices[i], \"B\");\r\n\r\n            if (distFromO[i] === distFromA[i] && distFromA[i] === distFromB[i]) {\r\n                closest = 3;\r\n                dist = distFromO[i];\r\n            } else if (distFromO[i] === distFromA[i]) {\r\n                closest = 4;\r\n                dist = distFromO[i];\r\n            } else if (distFromA[i] === distFromB[i]) {\r\n                closest = 5;\r\n                dist = distFromA[i];\r\n            } else if (distFromB[i] === distFromO[i]) {\r\n                closest = 6;\r\n                dist = distFromO[i];\r\n            }\r\n            if (distFromO[i] < distFromA[i] && distFromO[i] < distFromB[i]) {\r\n                closest = 2;\r\n                dist = distFromO[i];\r\n            }\r\n            if (distFromA[i] < distFromO[i] && distFromA[i] < distFromB[i]) {\r\n                closest = 1;\r\n                dist = distFromA[i];\r\n            }\r\n            if (distFromB[i] < distFromA[i] && distFromB[i] < distFromO[i]) {\r\n                closest = 0;\r\n                dist = distFromB[i];\r\n            }\r\n            vertData.push([closest, dist, vertices[i].x, vertices[i].y]);\r\n        }\r\n\r\n        vertData.sort((a, b) => {\r\n            return a[2] - b[2];\r\n        });\r\n        vertData.sort((a, b) => {\r\n            return a[3] - b[3];\r\n        });\r\n        vertData.sort((a, b) => {\r\n            return a[1] - b[1];\r\n        });\r\n        vertData.sort((a, b) => {\r\n            return a[0] - b[0];\r\n        });\r\n\r\n        for (let v = 0; v < vertData.length; v++) {\r\n            vertByDist[vertData[v][2] + \"|\" + vertData[v][3]] = [vertData[v][0], vertData[v][1], v];\r\n        }\r\n\r\n        this.m = m;\r\n        this.n = n;\r\n        this.vertices = vertices;\r\n        this.vertByDist = vertByDist;\r\n        this.cartesian = cartesian;\r\n        this.min = min;\r\n        this.max = max;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\n/** Builds Polyhedron Data\r\n * @internal\r\n */\r\nexport class PolyhedronData {\r\n    /**\r\n     * @internal\r\n     */\r\n    public edgematch: (number | string)[][];\r\n\r\n    /** @internal */\r\n    constructor(\r\n        /**\r\n         * The name of the polyhedron\r\n         */\r\n        public name: string,\r\n        /**\r\n         * The category of the polyhedron\r\n         */\r\n        public category: string,\r\n        /**\r\n         * vertex data\r\n         */\r\n        public vertex: number[][],\r\n        /**\r\n         * face data\r\n         */\r\n        public face: number[][]\r\n    ) {}\r\n}\r\n\r\n/**\r\n * This class Extends the PolyhedronData Class to provide measures for a Geodesic Polyhedron\r\n */\r\nexport class GeodesicData extends PolyhedronData {\r\n    /**\r\n     * @internal\r\n     */\r\n    public override edgematch: (number | string)[][];\r\n    /**\r\n     * @internal\r\n     */\r\n    public adjacentFaces: number[][];\r\n    /**\r\n     * @internal\r\n     */\r\n    public sharedNodes: number;\r\n    /**\r\n     * @internal\r\n     */\r\n    public poleNodes: number;\r\n    /**\r\n     * @internal\r\n     */\r\n    public innerToData(face: number, primTri: _PrimaryIsoTriangle) {\r\n        for (let i = 0; i < primTri.innerFacets.length; i++) {\r\n            this.face.push(primTri.innerFacets[i].map((el) => primTri.vecToidx[face + el]));\r\n        }\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public mapABOBtoDATA(faceNb: number, primTri: _PrimaryIsoTriangle) {\r\n        const fr = primTri.IDATA.edgematch[faceNb][0];\r\n        for (let i = 0; i < primTri.isoVecsABOB.length; i++) {\r\n            const temp = [];\r\n            for (let j = 0; j < 3; j++) {\r\n                if (primTri.vertexTypes[i][j] === 0) {\r\n                    temp.push(faceNb + \"|\" + primTri.isoVecsABOB[i][j].x + \"|\" + primTri.isoVecsABOB[i][j].y);\r\n                } else {\r\n                    temp.push(fr + \"|\" + primTri.isoVecsABOB[i][j].x + \"|\" + primTri.isoVecsABOB[i][j].y);\r\n                }\r\n            }\r\n            this.face.push([primTri.vecToidx[temp[0]], primTri.vecToidx[temp[1]], primTri.vecToidx[temp[2]]]);\r\n        }\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public mapOBOAtoDATA(faceNb: number, primTri: _PrimaryIsoTriangle) {\r\n        const fr = primTri.IDATA.edgematch[faceNb][0];\r\n        for (let i = 0; i < primTri.isoVecsOBOA.length; i++) {\r\n            const temp = [];\r\n            for (let j = 0; j < 3; j++) {\r\n                if (primTri.vertexTypes[i][j] === 1) {\r\n                    temp.push(faceNb + \"|\" + primTri.isoVecsOBOA[i][j].x + \"|\" + primTri.isoVecsOBOA[i][j].y);\r\n                } else {\r\n                    temp.push(fr + \"|\" + primTri.isoVecsOBOA[i][j].x + \"|\" + primTri.isoVecsOBOA[i][j].y);\r\n                }\r\n            }\r\n            this.face.push([primTri.vecToidx[temp[0]], primTri.vecToidx[temp[1]], primTri.vecToidx[temp[2]]]);\r\n        }\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public mapBAOAtoDATA(faceNb: number, primTri: _PrimaryIsoTriangle) {\r\n        const fr = primTri.IDATA.edgematch[faceNb][2];\r\n        for (let i = 0; i < primTri.isoVecsBAOA.length; i++) {\r\n            const temp = [];\r\n            for (let j = 0; j < 3; j++) {\r\n                if (primTri.vertexTypes[i][j] === 1) {\r\n                    temp.push(faceNb + \"|\" + primTri.isoVecsBAOA[i][j].x + \"|\" + primTri.isoVecsBAOA[i][j].y);\r\n                } else {\r\n                    temp.push(fr + \"|\" + primTri.isoVecsBAOA[i][j].x + \"|\" + primTri.isoVecsBAOA[i][j].y);\r\n                }\r\n            }\r\n            this.face.push([primTri.vecToidx[temp[0]], primTri.vecToidx[temp[1]], primTri.vecToidx[temp[2]]]);\r\n        }\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public orderData(primTri: _PrimaryIsoTriangle) {\r\n        const nearTo: number[][][] = [];\r\n        for (let i = 0; i < 13; i++) {\r\n            nearTo[i] = [];\r\n        }\r\n        const close: number[][] = primTri.closestTo;\r\n        for (let i = 0; i < close.length; i++) {\r\n            if (close[i][0] > -1) {\r\n                if (close[i][1] > 0) {\r\n                    nearTo[close[i][0]].push([i, close[i][1]]);\r\n                }\r\n            } else {\r\n                nearTo[12].push([i, close[i][0]]);\r\n            }\r\n        }\r\n\r\n        const near: number[] = [];\r\n        for (let i = 0; i < 12; i++) {\r\n            near[i] = i;\r\n        }\r\n        let nearIndex = 12;\r\n        for (let i = 0; i < 12; i++) {\r\n            nearTo[i].sort((a: number[], b: number[]) => {\r\n                return a[1] - b[1];\r\n            });\r\n            for (let j = 0; j < nearTo[i].length; j++) {\r\n                near[nearTo[i][j][0]] = nearIndex++;\r\n            }\r\n        }\r\n\r\n        for (let j = 0; j < nearTo[12].length; j++) {\r\n            near[nearTo[12][j][0]] = nearIndex++;\r\n        }\r\n\r\n        for (let i = 0; i < this.vertex.length; i++) {\r\n            this.vertex[i].push(near[i]);\r\n        }\r\n\r\n        this.vertex.sort((a, b) => {\r\n            return a[3] - b[3];\r\n        });\r\n\r\n        for (let i = 0; i < this.vertex.length; i++) {\r\n            this.vertex[i].pop();\r\n        }\r\n\r\n        for (let i = 0; i < this.face.length; i++) {\r\n            for (let j = 0; j < this.face[i].length; j++) {\r\n                this.face[i][j] = near[this.face[i][j]];\r\n            }\r\n        }\r\n\r\n        this.sharedNodes = nearTo[12].length;\r\n        this.poleNodes = this.vertex.length - this.sharedNodes;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public setOrder(m: number, faces: number[]) {\r\n        const adjVerts: number[] = [];\r\n        const dualFaces: number[] = [];\r\n        let face: number = <number>faces.pop();\r\n        dualFaces.push(face);\r\n        let index = this.face[face].indexOf(m);\r\n        index = (index + 2) % 3;\r\n        let v = this.face[face][index];\r\n        adjVerts.push(v);\r\n        let f = 0;\r\n        while (faces.length > 0) {\r\n            face = faces[f];\r\n            if (this.face[face].indexOf(v) > -1) {\r\n                // v is a vertex of face f\r\n                index = (this.face[face].indexOf(v) + 1) % 3;\r\n                v = this.face[face][index];\r\n                adjVerts.push(v);\r\n                dualFaces.push(face);\r\n                faces.splice(f, 1);\r\n                f = 0;\r\n            } else {\r\n                f++;\r\n            }\r\n        }\r\n        this.adjacentFaces.push(adjVerts);\r\n        return dualFaces;\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public toGoldbergPolyhedronData(): PolyhedronData {\r\n        const goldbergPolyhedronData: PolyhedronData = new PolyhedronData(\"GeoDual\", \"Goldberg\", [], []);\r\n        goldbergPolyhedronData.name = \"GD dual\";\r\n        const verticesNb: number = this.vertex.length;\r\n        const map = new Array(verticesNb);\r\n        for (let v = 0; v < verticesNb; v++) {\r\n            map[v] = [];\r\n        }\r\n        for (let f = 0; f < this.face.length; f++) {\r\n            for (let i = 0; i < 3; i++) {\r\n                map[this.face[f][i]].push(f);\r\n            }\r\n        }\r\n        let cx: number;\r\n        let cy: number;\r\n        let cz: number;\r\n        let face: number[];\r\n        let vertex: number[];\r\n        this.adjacentFaces = [];\r\n        for (let m = 0; m < map.length; m++) {\r\n            goldbergPolyhedronData.face[m] = this.setOrder(m, map[m].concat([]));\r\n            for (const el of map[m]) {\r\n                cx = 0;\r\n                cy = 0;\r\n                cz = 0;\r\n                face = this.face[el];\r\n                for (let i = 0; i < 3; i++) {\r\n                    vertex = this.vertex[face[i]];\r\n                    cx += vertex[0];\r\n                    cy += vertex[1];\r\n                    cz += vertex[2];\r\n                }\r\n                goldbergPolyhedronData.vertex[el] = [cx / 3, cy / 3, cz / 3];\r\n            }\r\n        }\r\n        return goldbergPolyhedronData;\r\n    }\r\n\r\n    //statics\r\n    /**Builds the data for a Geodesic Polyhedron from a primary triangle\r\n     * @param primTri the primary triangle\r\n     * @internal\r\n     */\r\n\r\n    public static BuildGeodesicData(primTri: _PrimaryIsoTriangle) {\r\n        const geodesicData = new GeodesicData(\r\n            \"Geodesic-m-n\",\r\n            \"Geodesic\",\r\n            [\r\n                [0, PHI, -1],\r\n                [-PHI, 1, 0],\r\n                [-1, 0, -PHI],\r\n                [1, 0, -PHI],\r\n                [PHI, 1, 0],\r\n                [0, PHI, 1],\r\n                [-1, 0, PHI],\r\n                [-PHI, -1, 0],\r\n                [0, -PHI, -1],\r\n                [PHI, -1, 0],\r\n                [1, 0, PHI],\r\n                [0, -PHI, 1],\r\n            ],\r\n            []\r\n        );\r\n\r\n        primTri.setIndices();\r\n        primTri.calcCoeffs();\r\n        primTri.createInnerFacets();\r\n        primTri.edgeVecsABOB();\r\n        primTri.mapABOBtoOBOA();\r\n        primTri.mapABOBtoBAOA();\r\n\r\n        for (let f = 0; f < primTri.IDATA.face.length; f++) {\r\n            primTri.MapToFace(f, geodesicData);\r\n            geodesicData.innerToData(f, primTri);\r\n            if (primTri.IDATA.edgematch[f][1] === \"B\") {\r\n                geodesicData.mapABOBtoDATA(f, primTri);\r\n            }\r\n            if (primTri.IDATA.edgematch[f][1] === \"O\") {\r\n                geodesicData.mapOBOAtoDATA(f, primTri);\r\n            }\r\n            if (primTri.IDATA.edgematch[f][3] === \"A\") {\r\n                geodesicData.mapBAOAtoDATA(f, primTri);\r\n            }\r\n        }\r\n\r\n        geodesicData.orderData(primTri);\r\n        const radius = 1;\r\n        geodesicData.vertex = geodesicData.vertex.map(function (el) {\r\n            const a = el[0];\r\n            const b = el[1];\r\n            const c = el[2];\r\n            const d = Math.sqrt(a * a + b * b + c * c);\r\n            el[0] *= radius / d;\r\n            el[1] *= radius / d;\r\n            el[2] *= radius / d;\r\n            return el;\r\n        });\r\n\r\n        return geodesicData;\r\n    }\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { type Vector4 } from \"../../Maths/math.vector\";\r\nimport { type Color4 } from \"../../Maths/math.color\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { CreatePolyhedron } from \"./polyhedronBuilder.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { _PrimaryIsoTriangle, GeodesicData } from \"../geodesicMesh\";\r\n\r\n/**\r\n * Creates the Mesh for a Geodesic Polyhedron\r\n * @see https://en.wikipedia.org/wiki/Geodesic_polyhedron\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra/geodesic_poly\r\n * @param name defines the name of the mesh\r\n * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty\r\n * * m number of horizontal steps along an isogrid\r\n * * n number of angled steps along an isogrid\r\n * * size the size of the Geodesic, optional default 1\r\n * * sizeX allows stretching in the x direction, optional, default size\r\n * * sizeY allows stretching in the y direction, optional, default size\r\n * * sizeZ allows stretching in the z direction, optional, default size\r\n * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively\r\n * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively\r\n * * flat when true creates a flat shaded mesh, optional, default true\r\n * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4\r\n * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)\r\n * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)\r\n * @param scene defines the hosting scene\r\n * @returns Geodesic mesh\r\n */\r\nexport function CreateGeodesic(\r\n    name: string,\r\n    options: {\r\n        m?: number;\r\n        n?: number;\r\n        size?: number;\r\n        sizeX?: number;\r\n        sizeY?: number;\r\n        sizeZ?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        flat?: boolean;\r\n        updatable?: boolean;\r\n        sideOrientation?: number;\r\n        frontUVs?: Vector4;\r\n        backUVs?: Vector4;\r\n    },\r\n    scene: Nullable<Scene> = null\r\n): Mesh {\r\n    let m: number = options.m || 1;\r\n    if (m !== Math.floor(m)) {\r\n        m = Math.floor(m);\r\n        Logger.Warn(\"m not an integer only floor(m) used\");\r\n    }\r\n    let n: number = options.n || 0;\r\n    if (n !== Math.floor(n)) {\r\n        n = Math.floor(n);\r\n        Logger.Warn(\"n not an integer only floor(n) used\");\r\n    }\r\n    if (n > m) {\r\n        const temp = n;\r\n        n = m;\r\n        m = temp;\r\n        Logger.Warn(\"n > m therefore m and n swapped\");\r\n    }\r\n    const primTri: _PrimaryIsoTriangle = new _PrimaryIsoTriangle();\r\n    primTri.build(m, n);\r\n    const geodesicData = GeodesicData.BuildGeodesicData(primTri);\r\n\r\n    const geoOptions: object = {\r\n        custom: geodesicData,\r\n        size: options.size,\r\n        sizeX: options.sizeX,\r\n        sizeY: options.sizeY,\r\n        sizeZ: options.sizeZ,\r\n        faceUV: options.faceUV,\r\n        faceColors: options.faceColors,\r\n        flat: options.flat,\r\n        updatable: options.updatable,\r\n        sideOrientation: options.sideOrientation,\r\n        frontUVs: options.frontUVs,\r\n        backUVs: options.backUVs,\r\n    };\r\n    const geodesic = CreatePolyhedron(name, geoOptions, scene);\r\n\r\n    return geodesic;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Vector2 } from \"../Maths/math.vector\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type FloatArray } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\n\r\n/**\r\n * Defines the set of goldberg data used to create the polygon\r\n */\r\nexport type GoldbergData = {\r\n    /**\r\n     * The list of Goldberg faces colors\r\n     */\r\n    faceColors: Color4[];\r\n    /**\r\n     * The list of Goldberg faces centers\r\n     */\r\n    faceCenters: Vector3[];\r\n    /**\r\n     * The list of Goldberg faces Z axis\r\n     */\r\n    faceZaxis: Vector3[];\r\n    /**\r\n     * The list of Goldberg faces Y axis\r\n     */\r\n    faceXaxis: Vector3[];\r\n    /**\r\n     * The list of Goldberg faces X axis\r\n     */\r\n    faceYaxis: Vector3[];\r\n    /**\r\n     * Defines the number of shared faces\r\n     */\r\n    nbSharedFaces: number;\r\n    /**\r\n     * Defines the number of unshared faces\r\n     */\r\n    nbUnsharedFaces: number;\r\n    /**\r\n     * Defines the total number of goldberg faces\r\n     */\r\n    nbFaces: number;\r\n    /**\r\n     * Defines the number of goldberg faces at the pole\r\n     */\r\n    nbFacesAtPole: number;\r\n    /**\r\n     * Defines the number of adjacent faces per goldberg faces\r\n     */\r\n    adjacentFaces: number[][];\r\n};\r\n\r\n/**\r\n * Mesh for a Goldberg Polyhedron which is made from 12 pentagonal and the rest hexagonal faces\r\n * @see https://en.wikipedia.org/wiki/Goldberg_polyhedron\r\n */\r\nexport class GoldbergMesh extends Mesh {\r\n    /**\r\n     * Defines the specific Goldberg data used in this mesh construction.\r\n     */\r\n    public goldbergData: GoldbergData = {\r\n        faceColors: [],\r\n        faceCenters: [],\r\n        faceZaxis: [],\r\n        faceXaxis: [],\r\n        faceYaxis: [],\r\n        nbSharedFaces: 0,\r\n        nbUnsharedFaces: 0,\r\n        nbFaces: 0,\r\n        nbFacesAtPole: 0,\r\n        adjacentFaces: [],\r\n    };\r\n\r\n    /**\r\n     * Gets the related Goldberg face from pole infos\r\n     * @param poleOrShared Defines the pole index or the shared face index if the fromPole parameter is passed in\r\n     * @param fromPole Defines an optional pole index to find the related info from\r\n     * @returns the goldberg face number\r\n     */\r\n    public relatedGoldbergFace(poleOrShared: number, fromPole?: number): number {\r\n        if (fromPole === void 0) {\r\n            if (poleOrShared > this.goldbergData.nbUnsharedFaces - 1) {\r\n                Logger.Warn(\"Maximum number of unshared faces used\");\r\n                poleOrShared = this.goldbergData.nbUnsharedFaces - 1;\r\n            }\r\n            return this.goldbergData.nbUnsharedFaces + poleOrShared;\r\n        }\r\n        if (poleOrShared > 11) {\r\n            Logger.Warn(\"Last pole used\");\r\n            poleOrShared = 11;\r\n        }\r\n        if (fromPole > this.goldbergData.nbFacesAtPole - 1) {\r\n            Logger.Warn(\"Maximum number of faces at a pole used\");\r\n            fromPole = this.goldbergData.nbFacesAtPole - 1;\r\n        }\r\n\r\n        return 12 + poleOrShared * this.goldbergData.nbFacesAtPole + fromPole;\r\n    }\r\n\r\n    private _changeGoldbergFaceColors(colorRange: (number | Color4)[][]): number[] {\r\n        for (let i = 0; i < colorRange.length; i++) {\r\n            const min: number = <number>colorRange[i][0];\r\n            const max: number = <number>colorRange[i][1];\r\n            const col: Color4 = <Color4>colorRange[i][2];\r\n            for (let f = min; f < max + 1; f++) {\r\n                this.goldbergData.faceColors[f] = col;\r\n            }\r\n        }\r\n\r\n        const newCols: number[] = [];\r\n        for (let f = 0; f < 12; f++) {\r\n            for (let i = 0; i < 5; i++) {\r\n                newCols.push(this.goldbergData.faceColors[f].r, this.goldbergData.faceColors[f].g, this.goldbergData.faceColors[f].b, this.goldbergData.faceColors[f].a);\r\n            }\r\n        }\r\n        for (let f = 12; f < this.goldbergData.faceColors.length; f++) {\r\n            for (let i = 0; i < 6; i++) {\r\n                newCols.push(this.goldbergData.faceColors[f].r, this.goldbergData.faceColors[f].g, this.goldbergData.faceColors[f].b, this.goldbergData.faceColors[f].a);\r\n            }\r\n        }\r\n        return newCols;\r\n    }\r\n\r\n    /**\r\n     * Set new goldberg face colors\r\n     * @param colorRange the new color to apply to the mesh\r\n     */\r\n    public setGoldbergFaceColors(colorRange: (number | Color4)[][]) {\r\n        const newCols = this._changeGoldbergFaceColors(colorRange);\r\n        this.setVerticesData(VertexBuffer.ColorKind, newCols);\r\n    }\r\n\r\n    /**\r\n     * Updates new goldberg face colors\r\n     * @param colorRange the new color to apply to the mesh\r\n     */\r\n    public updateGoldbergFaceColors(colorRange: (number | Color4)[][]) {\r\n        const newCols = this._changeGoldbergFaceColors(colorRange);\r\n        this.updateVerticesData(VertexBuffer.ColorKind, newCols);\r\n    }\r\n\r\n    private _changeGoldbergFaceUVs(uvRange: (number | Vector2)[][]): FloatArray {\r\n        const uvs: FloatArray = this.getVerticesData(VertexBuffer.UVKind)!;\r\n        for (let i = 0; i < uvRange.length; i++) {\r\n            const min: number = <number>uvRange[i][0];\r\n            const max: number = <number>uvRange[i][1];\r\n            const center: Vector2 = <Vector2>uvRange[i][2];\r\n            const radius: number = <number>uvRange[i][3];\r\n            const angle: number = <number>uvRange[i][4];\r\n            const points5: number[] = [];\r\n            const points6: number[] = [];\r\n            let u: number;\r\n            let v: number;\r\n            for (let p = 0; p < 5; p++) {\r\n                u = center.x + radius * Math.cos(angle + (p * Math.PI) / 2.5);\r\n                v = center.y + radius * Math.sin(angle + (p * Math.PI) / 2.5);\r\n                if (u < 0) {\r\n                    u = 0;\r\n                }\r\n                if (u > 1) {\r\n                    u = 1;\r\n                }\r\n                points5.push(u, v);\r\n            }\r\n            for (let p = 0; p < 6; p++) {\r\n                u = center.x + radius * Math.cos(angle + (p * Math.PI) / 3);\r\n                v = center.y + radius * Math.sin(angle + (p * Math.PI) / 3);\r\n                if (u < 0) {\r\n                    u = 0;\r\n                }\r\n                if (u > 1) {\r\n                    u = 1;\r\n                }\r\n                points6.push(u, v);\r\n            }\r\n            for (let f = min; f < Math.min(12, max + 1); f++) {\r\n                for (let p = 0; p < 5; p++) {\r\n                    uvs[10 * f + 2 * p] = points5[2 * p];\r\n                    uvs[10 * f + 2 * p + 1] = points5[2 * p + 1];\r\n                }\r\n            }\r\n            for (let f = Math.max(12, min); f < max + 1; f++) {\r\n                for (let p = 0; p < 6; p++) {\r\n                    //120 + 12 * (f - 12) = 12 * f - 24\r\n                    uvs[12 * f - 24 + 2 * p] = points6[2 * p];\r\n                    uvs[12 * f - 23 + 2 * p] = points6[2 * p + 1];\r\n                }\r\n            }\r\n        }\r\n        return uvs;\r\n    }\r\n\r\n    /**\r\n     * set new goldberg face UVs\r\n     * @param uvRange the new UVs to apply to the mesh\r\n     */\r\n    public setGoldbergFaceUVs(uvRange: (number | Vector2)[][]) {\r\n        const newUVs: FloatArray = this._changeGoldbergFaceUVs(uvRange);\r\n        this.setVerticesData(VertexBuffer.UVKind, newUVs);\r\n    }\r\n\r\n    /**\r\n     * Updates new goldberg face UVs\r\n     * @param uvRange the new UVs to apply to the mesh\r\n     */\r\n    public updateGoldbergFaceUVs(uvRange: (number | Vector2)[][]) {\r\n        const newUVs = this._changeGoldbergFaceUVs(uvRange);\r\n        this.updateVerticesData(VertexBuffer.UVKind, newUVs);\r\n    }\r\n\r\n    /**\r\n     * Places a mesh on a particular face of the goldberg polygon\r\n     * @param mesh Defines the mesh to position\r\n     * @param face Defines the face to position onto\r\n     * @param position Defines the position relative to the face we are positioning the mesh onto\r\n     */\r\n    public placeOnGoldbergFaceAt(mesh: Mesh, face: number, position: Vector3) {\r\n        const orientation = Vector3.RotationFromAxis(this.goldbergData.faceXaxis[face], this.goldbergData.faceYaxis[face], this.goldbergData.faceZaxis[face]);\r\n        mesh.rotation = orientation;\r\n        mesh.position = this.goldbergData.faceCenters[face]\r\n            .add(this.goldbergData.faceXaxis[face].scale(position.x))\r\n            .add(this.goldbergData.faceYaxis[face].scale(position.y))\r\n            .add(this.goldbergData.faceZaxis[face].scale(position.z));\r\n    }\r\n\r\n    /**\r\n     * Serialize current mesh\r\n     * @param serializationObject defines the object which will receive the serialization data\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.type = \"GoldbergMesh\";\r\n\r\n        const goldbergData: any = {};\r\n        goldbergData.adjacentFaces = this.goldbergData.adjacentFaces;\r\n        goldbergData.nbSharedFaces = this.goldbergData.nbSharedFaces;\r\n        goldbergData.nbUnsharedFaces = this.goldbergData.nbUnsharedFaces;\r\n        goldbergData.nbFaces = this.goldbergData.nbFaces;\r\n        goldbergData.nbFacesAtPole = this.goldbergData.nbFacesAtPole;\r\n\r\n        if (this.goldbergData.faceColors) {\r\n            goldbergData.faceColors = [];\r\n            for (const color of this.goldbergData.faceColors) {\r\n                goldbergData.faceColors.push(color.asArray());\r\n            }\r\n        }\r\n        if (this.goldbergData.faceCenters) {\r\n            goldbergData.faceCenters = [];\r\n            for (const vector of this.goldbergData.faceCenters) {\r\n                goldbergData.faceCenters.push(vector.asArray());\r\n            }\r\n        }\r\n        if (this.goldbergData.faceZaxis) {\r\n            goldbergData.faceZaxis = [];\r\n            for (const vector of this.goldbergData.faceZaxis) {\r\n                goldbergData.faceZaxis.push(vector.asArray());\r\n            }\r\n        }\r\n        if (this.goldbergData.faceYaxis) {\r\n            goldbergData.faceYaxis = [];\r\n            for (const vector of this.goldbergData.faceYaxis) {\r\n                goldbergData.faceYaxis.push(vector.asArray());\r\n            }\r\n        }\r\n        if (this.goldbergData.faceXaxis) {\r\n            goldbergData.faceXaxis = [];\r\n            for (const vector of this.goldbergData.faceXaxis) {\r\n                goldbergData.faceXaxis.push(vector.asArray());\r\n            }\r\n        }\r\n\r\n        serializationObject.goldbergData = goldbergData;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized goldberg mesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the goldberg mesh in\r\n     * @returns the created goldberg mesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): GoldbergMesh {\r\n        const goldbergData = parsedMesh.goldbergData;\r\n        goldbergData.faceColors = goldbergData.faceColors.map((el: number[]) => Color4.FromArray(el));\r\n        goldbergData.faceCenters = goldbergData.faceCenters.map((el: number[]) => Vector3.FromArray(el));\r\n        goldbergData.faceZaxis = goldbergData.faceZaxis.map((el: number[]) => Vector3.FromArray(el));\r\n        goldbergData.faceXaxis = goldbergData.faceXaxis.map((el: number[]) => Vector3.FromArray(el));\r\n        goldbergData.faceYaxis = goldbergData.faceYaxis.map((el: number[]) => Vector3.FromArray(el));\r\n\r\n        const goldberg = new GoldbergMesh(parsedMesh.name, scene);\r\n        goldberg.goldbergData = goldbergData;\r\n\r\n        return goldberg;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for goldbergMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGoldbergMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GoldbergMeshParser = (parsedMesh: any, scene: Scene): GoldbergMesh => {\r\n        return GoldbergMesh.Parse(parsedMesh, scene);\r\n    };\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type PolyhedronData, _PrimaryIsoTriangle, GeodesicData } from \"../geodesicMesh\";\r\nimport { GoldbergMesh } from \"../goldbergMesh.pure\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\n\r\n/**\r\n * Defines the set of data required to create goldberg vertex data.\r\n */\r\nexport type GoldbergVertexDataOption = {\r\n    /**\r\n     * the size of the Goldberg, optional default 1\r\n     */\r\n    size?: number;\r\n    /**\r\n     * allows stretching in the x direction, optional, default size\r\n     */\r\n    sizeX?: number;\r\n    /**\r\n     * allows stretching in the y direction, optional, default size\r\n     */\r\n    sizeY?: number;\r\n    /**\r\n     * allows stretching in the z direction, optional, default size\r\n     */\r\n    sizeZ?: number;\r\n    /**\r\n     * optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE\r\n     */\r\n    sideOrientation?: number;\r\n};\r\n\r\n/**\r\n * Defines the set of data required to create a goldberg mesh.\r\n */\r\nexport type GoldbergCreationOption = {\r\n    /**\r\n     * number of horizontal steps along an isogrid\r\n     */\r\n    m?: number;\r\n    /**\r\n     * number of angled steps along an isogrid\r\n     */\r\n    n?: number;\r\n    /**\r\n     * defines if the mesh must be flagged as updatable\r\n     */\r\n    updatable?: boolean;\r\n} & GoldbergVertexDataOption;\r\n\r\n/**\r\n * Creates the Mesh for a Goldberg Polyhedron\r\n * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty\r\n * @param goldbergData polyhedronData defining the Goldberg polyhedron\r\n * @returns GoldbergSphere mesh\r\n */\r\nexport function CreateGoldbergVertexData(options: GoldbergVertexDataOption, goldbergData: PolyhedronData): VertexData {\r\n    const size = options.size;\r\n    const sizeX: number = options.sizeX || size || 1;\r\n    const sizeY: number = options.sizeY || size || 1;\r\n    const sizeZ: number = options.sizeZ || size || 1;\r\n    const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;\r\n\r\n    const positions: number[] = [];\r\n    const indices: number[] = [];\r\n    const normals: number[] = [];\r\n    const uvs: number[] = [];\r\n\r\n    let minX = Infinity;\r\n    let maxX = -Infinity;\r\n    let minY = Infinity;\r\n    let maxY = -Infinity;\r\n\r\n    for (let v = 0; v < goldbergData.vertex.length; v++) {\r\n        minX = Math.min(minX, goldbergData.vertex[v][0] * sizeX);\r\n        maxX = Math.max(maxX, goldbergData.vertex[v][0] * sizeX);\r\n        minY = Math.min(minY, goldbergData.vertex[v][1] * sizeY);\r\n        maxY = Math.max(maxY, goldbergData.vertex[v][1] * sizeY);\r\n    }\r\n\r\n    let index: number = 0;\r\n    for (let f = 0; f < goldbergData.face.length; f++) {\r\n        const verts = goldbergData.face[f];\r\n        const a = Vector3.FromArray(goldbergData.vertex[verts[0]]);\r\n        const b = Vector3.FromArray(goldbergData.vertex[verts[2]]);\r\n        const c = Vector3.FromArray(goldbergData.vertex[verts[1]]);\r\n        const ba = b.subtract(a);\r\n        const ca = c.subtract(a);\r\n        const norm = Vector3.Cross(ca, ba).normalize();\r\n        for (let v = 0; v < verts.length; v++) {\r\n            normals.push(norm.x, norm.y, norm.z);\r\n            const pdata = goldbergData.vertex[verts[v]];\r\n            positions.push(pdata[0] * sizeX, pdata[1] * sizeY, pdata[2] * sizeZ);\r\n            const vCoord = (pdata[1] * sizeY - minY) / (maxY - minY);\r\n            uvs.push((pdata[0] * sizeX - minX) / (maxX - minX), useOpenGLOrientationForUV ? 1 - vCoord : vCoord);\r\n        }\r\n        for (let v = 0; v < verts.length - 2; v++) {\r\n            indices.push(index, index + v + 2, index + v + 1);\r\n        }\r\n        index += verts.length;\r\n    }\r\n\r\n    VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);\r\n\r\n    const vertexData = new VertexData();\r\n    vertexData.positions = positions;\r\n    vertexData.indices = indices;\r\n    vertexData.normals = normals;\r\n    vertexData.uvs = uvs;\r\n    return vertexData;\r\n}\r\n\r\n/**\r\n * Creates the Mesh for a Goldberg Polyhedron which is made from 12 pentagonal and the rest hexagonal faces\r\n * @see https://en.wikipedia.org/wiki/Goldberg_polyhedron\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra/goldberg_poly\r\n * @param name defines the name of the mesh\r\n * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty\r\n * @param scene defines the hosting scene\r\n * @returns Goldberg mesh\r\n */\r\nexport function CreateGoldberg(name: string, options: GoldbergCreationOption, scene: Nullable<Scene> = null): GoldbergMesh {\r\n    const size = options.size;\r\n    const sizeX: number = options.sizeX || size || 1;\r\n    const sizeY: number = options.sizeY || size || 1;\r\n    const sizeZ: number = options.sizeZ || size || 1;\r\n    let m: number = options.m || 1;\r\n    if (m !== Math.floor(m)) {\r\n        m = Math.floor(m);\r\n        Logger.Warn(\"m not an integer only floor(m) used\");\r\n    }\r\n    let n: number = options.n || 0;\r\n    if (n !== Math.floor(n)) {\r\n        n = Math.floor(n);\r\n        Logger.Warn(\"n not an integer only floor(n) used\");\r\n    }\r\n    if (n > m) {\r\n        const temp = n;\r\n        n = m;\r\n        m = temp;\r\n        Logger.Warn(\"n > m therefore m and n swapped\");\r\n    }\r\n    const primTri: _PrimaryIsoTriangle = new _PrimaryIsoTriangle();\r\n    primTri.build(m, n);\r\n    const geodesicData = GeodesicData.BuildGeodesicData(primTri);\r\n    const goldbergData = geodesicData.toGoldbergPolyhedronData();\r\n\r\n    const goldberg = new GoldbergMesh(name, scene);\r\n\r\n    options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);\r\n    goldberg._originalBuilderSideOrientation = options.sideOrientation;\r\n\r\n    const vertexData = CreateGoldbergVertexData(options, goldbergData);\r\n\r\n    vertexData.applyToMesh(goldberg, options.updatable);\r\n\r\n    goldberg.goldbergData.nbSharedFaces = geodesicData.sharedNodes;\r\n    goldberg.goldbergData.nbUnsharedFaces = geodesicData.poleNodes;\r\n    goldberg.goldbergData.adjacentFaces = geodesicData.adjacentFaces;\r\n    goldberg.goldbergData.nbFaces = goldberg.goldbergData.nbSharedFaces + goldberg.goldbergData.nbUnsharedFaces;\r\n    goldberg.goldbergData.nbFacesAtPole = (goldberg.goldbergData.nbUnsharedFaces - 12) / 12;\r\n    for (let f = 0; f < geodesicData.vertex.length; f++) {\r\n        goldberg.goldbergData.faceCenters.push(Vector3.FromArray(geodesicData.vertex[f]));\r\n        goldberg.goldbergData.faceCenters[f].x *= sizeX;\r\n        goldberg.goldbergData.faceCenters[f].y *= sizeY;\r\n        goldberg.goldbergData.faceCenters[f].z *= sizeZ;\r\n        goldberg.goldbergData.faceColors.push(new Color4(1, 1, 1, 1));\r\n    }\r\n\r\n    for (let f = 0; f < goldbergData.face.length; f++) {\r\n        const verts = goldbergData.face[f];\r\n        const a = Vector3.FromArray(goldbergData.vertex[verts[0]]);\r\n        const b = Vector3.FromArray(goldbergData.vertex[verts[2]]);\r\n        const c = Vector3.FromArray(goldbergData.vertex[verts[1]]);\r\n        const ba = b.subtract(a);\r\n        const ca = c.subtract(a);\r\n        const norm = Vector3.Cross(ca, ba).normalize();\r\n        const z = Vector3.Cross(ca, norm).normalize();\r\n        goldberg.goldbergData.faceXaxis.push(ca.normalize());\r\n        goldberg.goldbergData.faceYaxis.push(norm);\r\n        goldberg.goldbergData.faceZaxis.push(z);\r\n    }\r\n\r\n    return goldberg;\r\n}\r\n","import { type Color4 } from \"../../Maths/math.color\";\r\nimport { Path2 } from \"../../Maths/math.path\";\r\nimport { Vector3, type Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { TransformNode } from \"../transformNode.pure\";\r\nimport { ExtrudePolygon } from \"./polygonBuilder.pure\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare let earcut: any;\r\n\r\n/**\r\n * Parser inspired by https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/FontLoader.js\r\n */\r\n\r\n// Interfaces\r\n\r\n/**\r\n * Represents glyph data generated by http://gero3.github.io/facetype.js/\r\n */\r\nexport interface IGlyphData {\r\n    /** Commands used to draw (line, move, curve, etc..) */\r\n    o: string;\r\n\r\n    /** Width */\r\n    ha: number;\r\n}\r\n\r\n/**\r\n * Represents font data generated by http://gero3.github.io/facetype.js/\r\n */\r\nexport interface IFontData {\r\n    /**\r\n     * Font resolution\r\n     */\r\n    resolution: number;\r\n    /** Underline tickness */\r\n    underlineThickness: number;\r\n    /** Bounding box */\r\n    boundingBox: {\r\n        yMax: number;\r\n        yMin: number;\r\n    };\r\n    /** List of supported glyphs */\r\n    glyphs: { [key: string]: IGlyphData };\r\n}\r\n\r\n// Shape functions\r\nclass ShapePath {\r\n    private _paths: Path2[] = [];\r\n    private _tempPaths: Path2[] = [];\r\n    private _holes: Path2[] = [];\r\n    private _currentPath: Path2;\r\n    private _resolution: number;\r\n\r\n    /** Create the ShapePath used to support glyphs\r\n     * @param resolution defines the resolution used to determine the number of points per curve (default is 4)\r\n     */\r\n    constructor(resolution: number) {\r\n        this._resolution = resolution;\r\n    }\r\n\r\n    /** Move the virtual cursor to a coordinate\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     */\r\n    moveTo(x: number, y: number) {\r\n        this._currentPath = new Path2(x, y);\r\n        this._tempPaths.push(this._currentPath);\r\n    }\r\n\r\n    /** Draw a line from the virtual cursor to a given coordinate\r\n     * @param x defines the x coordinate\r\n     * @param y defines the y coordinate\r\n     */\r\n    lineTo(x: number, y: number) {\r\n        this._currentPath.addLineTo(x, y);\r\n    }\r\n\r\n    /** Create a quadratic curve from the virtual cursor to a given coordinate\r\n     * @param cpx defines the x coordinate of the control point\r\n     * @param cpy defines the y coordinate of the control point\r\n     * @param x defines the x coordinate of the end point\r\n     * @param y defines the y coordinate of the end point\r\n     */\r\n    quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {\r\n        this._currentPath.addQuadraticCurveTo(cpx, cpy, x, y, this._resolution);\r\n    }\r\n\r\n    /**\r\n     * Create a bezier curve from the virtual cursor to a given coordinate\r\n     * @param cpx1 defines the x coordinate of the first control point\r\n     * @param cpy1 defines the y coordinate of the first control point\r\n     * @param cpx2 defines the x coordinate of the second control point\r\n     * @param cpy2 defines the y coordinate of the second control point\r\n     * @param x defines the x coordinate of the end point\r\n     * @param y defines the y coordinate of the end point\r\n     */\r\n    bezierCurveTo(cpx1: number, cpy1: number, cpx2: number, cpy2: number, x: number, y: number) {\r\n        this._currentPath.addBezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y, this._resolution);\r\n    }\r\n\r\n    /** Extract holes based on CW / CCW */\r\n    extractHoles() {\r\n        for (const path of this._tempPaths) {\r\n            if (path.area() > 0) {\r\n                this._holes.push(path);\r\n            } else {\r\n                this._paths.push(path);\r\n            }\r\n        }\r\n\r\n        if (!this._paths.length && this._holes.length) {\r\n            const temp = this._holes;\r\n            this._holes = this._paths;\r\n            this._paths = temp;\r\n        }\r\n\r\n        this._tempPaths.length = 0;\r\n    }\r\n\r\n    /** Gets the list of paths */\r\n    get paths() {\r\n        return this._paths;\r\n    }\r\n\r\n    /** Gets the list of holes */\r\n    get holes() {\r\n        return this._holes;\r\n    }\r\n}\r\n\r\n// Utility functions\r\nfunction CreateShapePath(\r\n    char: string,\r\n    scale: number,\r\n    offsetX: number,\r\n    offsetY: number,\r\n    resolution: number,\r\n    fontData: IFontData\r\n): Nullable<{\r\n    offsetX: number;\r\n    shapePath: ShapePath;\r\n}> {\r\n    const glyph = fontData.glyphs[char] || fontData.glyphs[\"?\"];\r\n\r\n    if (!glyph) {\r\n        // return if there is no glyph data\r\n        return null;\r\n    }\r\n\r\n    const shapePath = new ShapePath(resolution);\r\n\r\n    if (glyph.o) {\r\n        const outline = glyph.o.split(\" \");\r\n\r\n        for (let i = 0, l = outline.length; i < l;) {\r\n            const action = outline[i++];\r\n\r\n            switch (action) {\r\n                case \"m\": {\r\n                    // moveTo\r\n                    const x = parseInt(outline[i++]) * scale + offsetX;\r\n                    const y = parseInt(outline[i++]) * scale + offsetY;\r\n\r\n                    shapePath.moveTo(x, y);\r\n                    break;\r\n                }\r\n                case \"l\": {\r\n                    // lineTo\r\n                    const x = parseInt(outline[i++]) * scale + offsetX;\r\n                    const y = parseInt(outline[i++]) * scale + offsetY;\r\n\r\n                    shapePath.lineTo(x, y);\r\n                    break;\r\n                }\r\n                case \"q\": {\r\n                    // quadraticCurveTo\r\n                    const cpx = parseInt(outline[i++]) * scale + offsetX;\r\n                    const cpy = parseInt(outline[i++]) * scale + offsetY;\r\n                    const cpx1 = parseInt(outline[i++]) * scale + offsetX;\r\n                    const cpy1 = parseInt(outline[i++]) * scale + offsetY;\r\n\r\n                    shapePath.quadraticCurveTo(cpx1, cpy1, cpx, cpy);\r\n                    break;\r\n                }\r\n                case \"b\": {\r\n                    // bezierCurveTo\r\n                    const cpx = parseInt(outline[i++]) * scale + offsetX;\r\n                    const cpy = parseInt(outline[i++]) * scale + offsetY;\r\n                    const cpx1 = parseInt(outline[i++]) * scale + offsetX;\r\n                    const cpy1 = parseInt(outline[i++]) * scale + offsetY;\r\n                    const cpx2 = parseInt(outline[i++]) * scale + offsetX;\r\n                    const cpy2 = parseInt(outline[i++]) * scale + offsetY;\r\n\r\n                    shapePath.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy);\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // Extract holes (based on clockwise data)\r\n    shapePath.extractHoles();\r\n\r\n    return { offsetX: glyph.ha * scale, shapePath: shapePath };\r\n}\r\n\r\n/**\r\n * Creates shape paths from a text and font\r\n * @param text the text\r\n * @param size size of the font\r\n * @param resolution resolution of the font\r\n * @param fontData defines the font data (can be generated with http://gero3.github.io/facetype.js/)\r\n * @returns array of ShapePath objects\r\n */\r\nexport function CreateTextShapePaths(text: string, size: number, resolution: number, fontData: IFontData) {\r\n    const chars = Array.from(text);\r\n    const scale = size / fontData.resolution;\r\n    const lineHeight = (fontData.boundingBox.yMax - fontData.boundingBox.yMin + fontData.underlineThickness) * scale;\r\n\r\n    const shapePaths: ShapePath[] = [];\r\n\r\n    let offsetX = 0,\r\n        offsetY = 0;\r\n\r\n    for (let i = 0; i < chars.length; i++) {\r\n        const char = chars[i];\r\n\r\n        if (char === \"\\n\") {\r\n            offsetX = 0;\r\n            offsetY -= lineHeight;\r\n        } else {\r\n            const ret = CreateShapePath(char, scale, offsetX, offsetY, resolution, fontData);\r\n\r\n            if (ret) {\r\n                offsetX += ret.offsetX;\r\n                shapePaths.push(ret.shapePath);\r\n            }\r\n        }\r\n    }\r\n\r\n    return shapePaths;\r\n}\r\n\r\n/**\r\n * Create a text mesh\r\n * @param name defines the name of the mesh\r\n * @param text defines the text to use to build the mesh\r\n * @param fontData defines the font data (can be generated with http://gero3.github.io/facetype.js/)\r\n * @param options defines options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @param earcutInjection can be used to inject your own earcut reference\r\n * @returns a new Mesh\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set/text\r\n */\r\nexport function CreateText(\r\n    name: string,\r\n    text: string,\r\n    fontData: IFontData,\r\n    options: {\r\n        size?: number;\r\n        resolution?: number;\r\n        depth?: number;\r\n        sideOrientation?: number;\r\n        faceUV?: Vector4[];\r\n        faceColors?: Color4[];\r\n        perLetterFaceUV?: (letterIndex: number) => Vector4[];\r\n        perLetterFaceColors?: (letterIndex: number) => Color4[];\r\n    } = {\r\n        size: 50,\r\n        resolution: 8,\r\n        depth: 1.0,\r\n    },\r\n    scene: Nullable<Scene> = null,\r\n    earcutInjection = earcut\r\n): Nullable<Mesh> {\r\n    // First we need to generate the paths\r\n    const shapePaths = CreateTextShapePaths(text, options.size || 50, options.resolution || 8, fontData);\r\n\r\n    // And extrude them\r\n    const meshes: Mesh[] = [];\r\n    let letterIndex = 0;\r\n    for (const shapePath of shapePaths) {\r\n        if (!shapePath.paths.length) {\r\n            continue;\r\n        }\r\n\r\n        const holes = shapePath.holes.slice(); // Copy it as we will update the copy\r\n        for (const path of shapePath.paths) {\r\n            const holeVectors: Vector3[][] = [];\r\n            const shapeVectors: Vector3[] = [];\r\n            const points = path.getPoints();\r\n            for (const point of points) {\r\n                shapeVectors.push(new Vector3(point.x, 0, point.y)); // ExtrudePolygon expects data on the xz plane\r\n            }\r\n\r\n            // Holes\r\n            const localHolesCopy = holes.slice();\r\n            for (const hole of localHolesCopy) {\r\n                const points = hole.getPoints();\r\n\r\n                let found = false;\r\n                for (const point of points) {\r\n                    if (path.isPointInside(point)) {\r\n                        found = true;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (!found) {\r\n                    continue;\r\n                }\r\n\r\n                const holePoints: Vector3[] = [];\r\n                for (const point of points) {\r\n                    holePoints.push(new Vector3(point.x, 0, point.y)); // ExtrudePolygon expects data on the xz plane\r\n                }\r\n                holeVectors.push(holePoints);\r\n\r\n                // Remove the hole as it was already used\r\n                holes.splice(holes.indexOf(hole), 1);\r\n            }\r\n\r\n            // There is at least a hole but it was unaffected\r\n            if (!holeVectors.length && holes.length) {\r\n                for (const hole of holes) {\r\n                    const points = hole.getPoints();\r\n                    const holePoints: Vector3[] = [];\r\n                    for (const point of points) {\r\n                        holePoints.push(new Vector3(point.x, 0, point.y)); // ExtrudePolygon expects data on the xz plane\r\n                    }\r\n                    holeVectors.push(holePoints);\r\n                }\r\n            }\r\n\r\n            // Extrusion!\r\n            const mesh = ExtrudePolygon(\r\n                name,\r\n                {\r\n                    shape: shapeVectors,\r\n                    holes: holeVectors.length ? holeVectors : undefined,\r\n                    depth: options.depth || 1.0,\r\n                    faceUV: options.faceUV || options.perLetterFaceUV?.(letterIndex),\r\n                    faceColors: options.faceColors || options.perLetterFaceColors?.(letterIndex),\r\n                    sideOrientation: Mesh._GetDefaultSideOrientation(options.sideOrientation || Mesh.DOUBLESIDE),\r\n                },\r\n                scene,\r\n                earcutInjection\r\n            );\r\n            meshes.push(mesh);\r\n            letterIndex++;\r\n        }\r\n    }\r\n\r\n    // Then we can merge everyone into one single mesh\r\n    const newMesh = Mesh.MergeMeshes(meshes, true, true);\r\n\r\n    if (newMesh) {\r\n        // Move pivot to desired center / bottom / center position\r\n        const bbox = newMesh.getBoundingInfo().boundingBox;\r\n        newMesh.position.x += -(bbox.minimumWorld.x + bbox.maximumWorld.x) / 2; // Mid X\r\n        newMesh.position.y += -(bbox.minimumWorld.y + bbox.maximumWorld.y) / 2; // Mid Z as it will rotate\r\n        newMesh.position.z += -(bbox.minimumWorld.z + bbox.maximumWorld.z) / 2 + bbox.extendSize.z; // Bottom Y as it will rotate\r\n        newMesh.name = name;\r\n\r\n        // Rotate 90° Up\r\n        const pivot = new TransformNode(\"pivot\", scene);\r\n        pivot.rotation.x = -Math.PI / 2;\r\n        newMesh.parent = pivot;\r\n\r\n        newMesh.bakeCurrentTransformIntoVertices();\r\n\r\n        // Remove the pivot\r\n        newMesh.parent = null;\r\n        pivot.dispose();\r\n    }\r\n\r\n    return newMesh;\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { CreateRibbon } from \"./Builders/ribbonBuilder.pure\";\nimport { CreateDisc } from \"./Builders/discBuilder.pure\";\nimport { CreateBox } from \"./Builders/boxBuilder.pure\";\nimport { CreateTiledBox } from \"./Builders/tiledBoxBuilder.pure\";\nimport { CreateSphere } from \"./Builders/sphereBuilder.pure\";\nimport { CreateCylinder } from \"./Builders/cylinderBuilder.pure\";\nimport { CreateTorus } from \"./Builders/torusBuilder.pure\";\nimport { CreateTorusKnot } from \"./Builders/torusKnotBuilder.pure\";\nimport { CreateDashedLines, CreateLineSystem, CreateLines } from \"./Builders/linesBuilder.pure\";\nimport { CreatePolygon, ExtrudePolygon } from \"./Builders/polygonBuilder.pure\";\nimport { ExtrudeShape, ExtrudeShapeCustom } from \"./Builders/shapeBuilder.pure\";\nimport { CreateLathe } from \"./Builders/latheBuilder.pure\";\nimport { CreatePlane } from \"./Builders/planeBuilder.pure\";\nimport { CreateTiledPlane } from \"./Builders/tiledPlaneBuilder.pure\";\nimport { CreateGround, CreateGroundFromHeightMap, CreateTiledGround } from \"./Builders/groundBuilder.pure\";\nimport { CreateTube } from \"./Builders/tubeBuilder.pure\";\nimport { CreatePolyhedron } from \"./Builders/polyhedronBuilder.pure\";\nimport { CreateIcoSphere } from \"./Builders/icoSphereBuilder.pure\";\nimport { CreateDecal } from \"./Builders/decalBuilder.pure\";\nimport { CreateCapsule } from \"./Builders/capsuleBuilder.pure\";\nimport { CreateGeodesic } from \"./Builders/geodesicBuilder\";\nimport { CreateGoldberg } from \"./Builders/goldbergBuilder\";\nimport { CreateText } from \"./Builders/textBuilder\";\n\n/**\n * Class containing static functions to help procedurally build meshes\n */\nexport const MeshBuilder = {\n    CreateBox,\n    CreateTiledBox,\n    CreateSphere,\n    CreateDisc,\n    CreateIcoSphere,\n    CreateRibbon,\n    CreateCylinder,\n    CreateTorus,\n    CreateTorusKnot,\n    CreateLineSystem,\n    CreateLines,\n    CreateDashedLines,\n    ExtrudeShape,\n    ExtrudeShapeCustom,\n    CreateLathe,\n    CreateTiledPlane,\n    CreatePlane,\n    CreateGround,\n    CreateTiledGround,\n    CreateGroundFromHeightMap,\n    CreatePolygon,\n    ExtrudePolygon,\n    CreateTube,\n    CreatePolyhedron,\n    CreateGeodesic,\n    CreateGoldberg,\n    CreateDecal,\n    CreateCapsule,\n    CreateText,\n};\n","import { Bone } from \"./bone\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { MeshBuilder } from \"core/Meshes/meshBuilder.pure\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\nimport { Skeleton } from \"./skeleton\";\r\n\r\n/**\r\n * Creates a skeleton from a hierarchy of transform nodes by converting each node into a bone.\r\n * Each transform node in the hierarchy will be linked to its corresponding bone, allowing the skeleton\r\n * to be driven by the transform node transformations.\r\n * @param rootNode The root transform node of the hierarchy to convert into a skeleton\r\n * @param scene The scene in which to create the skeleton\r\n * @param options Optional parameters for skeleton creation\r\n *    - name: The name for the created skeleton (defaults to rootNode.name + \"_skeleton\")\r\n *    - boneMeshSize: The diameter of the sphere mesh created for each bone (defaults to 1, only used if createMesh is true)\r\n *    - createMesh: If true, creates a mesh with spheres at each bone location for visualization purposes.\r\n *       The mesh will be parented to the rootNode's parent and returned through options.mesh\r\n *    - mesh: An existing mesh to attach the skeleton to. If provided, the skeleton will be assigned to this mesh\r\n * @returns A new skeleton with bones corresponding to the transform node hierarchy\r\n * @remarks\r\n * - Only transform nodes with a rotationQuaternion property will be converted into bones\r\n */\r\nexport function CreateSkeletonFromTransformNodeHierarchy(\r\n    rootNode: TransformNode,\r\n    scene: Scene,\r\n    options?: { name?: string; boneMeshSize?: number; createMesh?: boolean; mesh?: Mesh }\r\n): Skeleton {\r\n    const name = options?.name || rootNode.name + \"_skeleton\";\r\n    const skeleton = new Skeleton(name, name, scene);\r\n\r\n    const nodes = rootNode.getChildTransformNodes(false);\r\n\r\n    nodes.unshift(rootNode);\r\n\r\n    let mesh = options?.mesh || null;\r\n    if (options?.createMesh) {\r\n        mesh = new Mesh(`${name}_mesh`, scene);\r\n        mesh.parent = rootNode.parent;\r\n        mesh.skeleton = skeleton;\r\n\r\n        options.mesh = mesh;\r\n    } else if (mesh) {\r\n        mesh.skeleton = skeleton;\r\n    }\r\n\r\n    const positions: number[] = [];\r\n    const indices: number[] = [];\r\n    const normals: number[] = [];\r\n    const boneIndices: number[] = [];\r\n    const boneWeights: number[] = [];\r\n\r\n    const boneMesh = options?.createMesh ? MeshBuilder.CreateSphere(\"dummy\", { diameter: options?.boneMeshSize || 1, segments: 8 }, scene) : null;\r\n\r\n    const boneMeshNumVertices = boneMesh?.getTotalVertices() || 0;\r\n    const boneMeshPositions = boneMesh?.getVerticesData(VertexBuffer.PositionKind);\r\n    const boneMeshIndices = boneMesh?.getIndices();\r\n    const boneMeshNormals = boneMesh?.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n    const mapNameToBone: { [name: string]: Bone } = {};\r\n\r\n    for (const node of nodes) {\r\n        if (!node.rotationQuaternion || node.getClassName() !== \"TransformNode\") {\r\n            continue;\r\n        }\r\n\r\n        const currentVertexIndex = positions.length / 3;\r\n\r\n        if (boneMeshPositions) {\r\n            for (let i = 0; i < boneMeshPositions.length; ++i) {\r\n                positions.push(boneMeshPositions[i]);\r\n            }\r\n        }\r\n        if (boneMeshNormals) {\r\n            for (let i = 0; i < boneMeshNormals.length; ++i) {\r\n                normals.push(boneMeshNormals[i]);\r\n            }\r\n        }\r\n\r\n        const boneIndex = skeleton.bones.length;\r\n\r\n        if (boneMesh) {\r\n            for (let i = 0; i < boneMeshNumVertices; ++i) {\r\n                boneIndices.push(boneIndex, -1, -1, -1);\r\n                boneWeights.push(1, 0, 0, 0);\r\n            }\r\n        }\r\n\r\n        if (boneMeshIndices) {\r\n            for (let i = 0; i < boneMeshIndices.length; ++i) {\r\n                indices.push(currentVertexIndex + boneMeshIndices[i]);\r\n            }\r\n        }\r\n\r\n        const bone = new Bone(\r\n            node.name,\r\n            skeleton,\r\n            node.parent ? mapNameToBone[node.parent.name] : null,\r\n            Matrix.Compose(node.scaling, node.rotationQuaternion, node.position), // local matrix\r\n            undefined,\r\n            Matrix.Identity() // bind matrix\r\n        );\r\n\r\n        bone.linkTransformNode(node);\r\n\r\n        mapNameToBone[node.name] = bone;\r\n    }\r\n\r\n    mesh?.setVerticesData(VertexBuffer.PositionKind, positions);\r\n    mesh?.setVerticesData(VertexBuffer.NormalKind, normals);\r\n    mesh?.setVerticesData(VertexBuffer.MatricesIndicesKind, boneIndices);\r\n    mesh?.setVerticesData(VertexBuffer.MatricesWeightsKind, boneWeights);\r\n    mesh?.setIndices(indices);\r\n\r\n    mesh?.refreshBoundingInfo(true, false);\r\n\r\n    boneMesh?.dispose();\r\n\r\n    return skeleton;\r\n}\r\n","import { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type DataArray } from \"../types\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * This class is a small wrapper around a native buffer that can be read and/or written\r\n */\r\nexport class StorageBuffer {\r\n    private _engine: WebGPUEngine;\r\n    private _buffer: DataBuffer;\r\n    private _bufferSize: number;\r\n    private _creationFlags: number;\r\n    private _label?: string;\r\n\r\n    /**\r\n     * Creates a new storage buffer instance\r\n     * @param engine The engine the buffer will be created inside\r\n     * @param size The size of the buffer in bytes\r\n     * @param creationFlags flags to use when creating the buffer (see Constants.BUFFER_CREATIONFLAG_XXX). The BUFFER_CREATIONFLAG_STORAGE flag will be automatically added.\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     */\r\n    constructor(engine: WebGPUEngine, size: number, creationFlags = Constants.BUFFER_CREATIONFLAG_READWRITE, label?: string) {\r\n        this._engine = engine;\r\n        this._label = label;\r\n        this._engine._storageBuffers.push(this);\r\n        this._create(size, creationFlags);\r\n    }\r\n\r\n    private _create(size: number, creationFlags: number): void {\r\n        this._bufferSize = size;\r\n        this._creationFlags = creationFlags;\r\n        this._buffer = this._engine.createStorageBuffer(size, creationFlags, this._label);\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        this._create(this._bufferSize, this._creationFlags);\r\n    }\r\n\r\n    /**\r\n     * Gets underlying native buffer\r\n     * @returns underlying native buffer\r\n     */\r\n    public getBuffer(): DataBuffer {\r\n        return this._buffer;\r\n    }\r\n\r\n    /**\r\n     * Clears the storage buffer to zeros\r\n     * @param byteOffset the byte offset to start clearing (optional)\r\n     * @param byteLength the byte length to clear (optional)\r\n     */\r\n    public clear(byteOffset?: number, byteLength?: number): void {\r\n        this._engine.clearStorageBuffer(this._buffer, byteOffset, byteLength);\r\n    }\r\n\r\n    /**\r\n     * Updates the storage buffer\r\n     * @param data the data used to update the storage buffer\r\n     * @param byteOffset the byte offset of the data (optional)\r\n     * @param byteLength the byte length of the data (optional)\r\n     */\r\n    public update(data: DataArray, byteOffset?: number, byteLength?: number): void {\r\n        if (!this._buffer) {\r\n            return;\r\n        }\r\n\r\n        this._engine.updateStorageBuffer(this._buffer, data, byteOffset, byteLength);\r\n    }\r\n\r\n    /**\r\n     * Reads data from the storage buffer\r\n     * @param offset The offset in the storage buffer to start reading from (default: 0)\r\n     * @param size  The number of bytes to read from the storage buffer (default: capacity of the buffer)\r\n     * @param buffer The buffer to write the data we have read from the storage buffer to (optional)\r\n     * @param noDelay If true, a call to flushFramebuffer will be issued so that the data can be read back immediately. This can speed up data retrieval, at the cost of a small perf penalty (default: false).\r\n     * @returns If not undefined, returns the (promise) buffer (as provided by the 4th parameter) filled with the data, else it returns a (promise) Uint8Array with the data read from the storage buffer\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async read(offset?: number, size?: number, buffer?: ArrayBufferView, noDelay?: boolean): Promise<ArrayBufferView> {\r\n        return await this._engine.readFromStorageBuffer(this._buffer, offset, size, buffer, noDelay);\r\n    }\r\n\r\n    /**\r\n     * Disposes the storage buffer\r\n     */\r\n    public dispose(): void {\r\n        const storageBuffers = this._engine._storageBuffers;\r\n        const index = storageBuffers.indexOf(this);\r\n\r\n        if (index !== -1) {\r\n            storageBuffers[index] = storageBuffers[storageBuffers.length - 1];\r\n            storageBuffers.pop();\r\n        }\r\n\r\n        this._engine._releaseBuffer(this._buffer);\r\n        this._buffer = null as any;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { GetTypeByteLength } from \"./bufferUtils\";\r\nimport { Buffer, VertexBuffer } from \"./buffer.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for bufferAlign.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBufferAlign(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const IsLittleEndian = (() => {\r\n        const array = new Uint8Array(4);\r\n        const view = new Uint32Array(array.buffer);\r\n\r\n        return !!((view[0] = 1) & array[0]);\r\n    })();\r\n\r\n    Object.defineProperty(VertexBuffer.prototype, \"effectiveByteStride\", {\r\n        get: function (this: VertexBuffer) {\r\n            return (this._alignedBuffer && this._alignedBuffer.byteStride) || this.byteStride;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(VertexBuffer.prototype, \"effectiveByteOffset\", {\r\n        get: function (this: VertexBuffer) {\r\n            return this._alignedBuffer ? 0 : this.byteOffset;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(VertexBuffer.prototype, \"effectiveBuffer\", {\r\n        get: function (this: VertexBuffer) {\r\n            return (this._alignedBuffer && this._alignedBuffer.getBuffer()) || this._buffer.getBuffer();\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    VertexBuffer.prototype._rebuild = function (): void {\r\n        this._buffer?._rebuild();\r\n        this._alignedBuffer?._rebuild();\r\n    };\r\n\r\n    VertexBuffer.prototype.dispose = function (): void {\r\n        if (this._ownsBuffer) {\r\n            this._buffer.dispose();\r\n        }\r\n\r\n        this._alignedBuffer?.dispose();\r\n        this._alignedBuffer = undefined;\r\n\r\n        this._isDisposed = true;\r\n    };\r\n\r\n    VertexBuffer.prototype.getWrapperBuffer = function (): Buffer {\r\n        return this._alignedBuffer || this._buffer;\r\n    };\r\n\r\n    VertexBuffer.prototype._alignBuffer = function (): void {\r\n        const data = this._buffer.getData();\r\n\r\n        if (!this.engine._features.forceVertexBufferStrideAndOffsetMultiple4Bytes || (this.byteStride % 4 === 0 && this.byteOffset % 4 === 0) || !data) {\r\n            return;\r\n        }\r\n\r\n        const typeByteLength = GetTypeByteLength(this.type);\r\n        const alignedByteStride = (this.byteStride + 3) & ~3;\r\n        const alignedSize = alignedByteStride / typeByteLength;\r\n        const totalVertices = this._maxVerticesCount;\r\n        const totalByteLength = totalVertices * alignedByteStride;\r\n        const totalLength = totalByteLength / typeByteLength;\r\n\r\n        let sourceData: DataView;\r\n\r\n        if (Array.isArray(data)) {\r\n            const sourceDataAsFloat = new Float32Array(data);\r\n            sourceData = new DataView(sourceDataAsFloat.buffer, sourceDataAsFloat.byteOffset, sourceDataAsFloat.byteLength);\r\n        } else if (ArrayBuffer.isView(data)) {\r\n            sourceData = new DataView(data.buffer, data.byteOffset, data.byteLength);\r\n        } else {\r\n            sourceData = new DataView(data, 0, data.byteLength);\r\n        }\r\n\r\n        let alignedData: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array;\r\n\r\n        if (this.type === VertexBuffer.BYTE) {\r\n            alignedData = new Int8Array(totalLength);\r\n        } else if (this.type === VertexBuffer.UNSIGNED_BYTE) {\r\n            alignedData = new Uint8Array(totalLength);\r\n        } else if (this.type === VertexBuffer.SHORT) {\r\n            alignedData = new Int16Array(totalLength);\r\n        } else if (this.type === VertexBuffer.UNSIGNED_SHORT) {\r\n            alignedData = new Uint16Array(totalLength);\r\n        } else if (this.type === VertexBuffer.HALF_FLOAT) {\r\n            alignedData = new Uint16Array(totalLength);\r\n        } else if (this.type === VertexBuffer.INT) {\r\n            alignedData = new Int32Array(totalLength);\r\n        } else if (this.type === VertexBuffer.UNSIGNED_INT) {\r\n            alignedData = new Uint32Array(totalLength);\r\n        } else {\r\n            alignedData = new Float32Array(totalLength);\r\n        }\r\n\r\n        const numComponents = this.getSize();\r\n\r\n        let sourceOffset = this.byteOffset;\r\n\r\n        for (let i = 0; i < totalVertices; ++i) {\r\n            for (let j = 0; j < numComponents; ++j) {\r\n                switch (this.type) {\r\n                    case VertexBuffer.BYTE:\r\n                        alignedData[i * alignedSize + j] = sourceData.getInt8(sourceOffset + j);\r\n                        break;\r\n                    case VertexBuffer.UNSIGNED_BYTE:\r\n                        alignedData[i * alignedSize + j] = sourceData.getUint8(sourceOffset + j);\r\n                        break;\r\n                    case VertexBuffer.SHORT:\r\n                        alignedData[i * alignedSize + j] = sourceData.getInt16(sourceOffset + j * 2, IsLittleEndian);\r\n                        break;\r\n                    case VertexBuffer.UNSIGNED_SHORT:\r\n                        alignedData[i * alignedSize + j] = sourceData.getUint16(sourceOffset + j * 2, IsLittleEndian);\r\n                        break;\r\n                    case VertexBuffer.HALF_FLOAT:\r\n                        alignedData[i * alignedSize + j] = sourceData.getUint16(sourceOffset + j * 2, IsLittleEndian);\r\n                        break;\r\n                    case VertexBuffer.INT:\r\n                        alignedData[i * alignedSize + j] = sourceData.getInt32(sourceOffset + j * 4, IsLittleEndian);\r\n                        break;\r\n                    case VertexBuffer.UNSIGNED_INT:\r\n                        alignedData[i * alignedSize + j] = sourceData.getUint32(sourceOffset + j * 4, IsLittleEndian);\r\n                        break;\r\n                    case VertexBuffer.FLOAT:\r\n                        alignedData[i * alignedSize + j] = sourceData.getFloat32(sourceOffset + j * 4, IsLittleEndian);\r\n                        break;\r\n                }\r\n            }\r\n            sourceOffset += this.byteStride;\r\n        }\r\n\r\n        this._alignedBuffer?.dispose();\r\n        this._alignedBuffer = new Buffer(\r\n            this.engine,\r\n            alignedData,\r\n            false,\r\n            alignedByteStride,\r\n            false,\r\n            this.getIsInstanced(),\r\n            true,\r\n            this.instanceDivisor,\r\n            (this._label ?? \"VertexBuffer\") + \"_aligned\"\r\n        );\r\n    };\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type ICameraInput } from \"../../Cameras/cameraInputsManager\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { type IWheelEvent, EventConstants } from \"../../Events/deviceInputEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\n\r\n/**\r\n * Base class for mouse wheel input..\r\n * See FollowCameraMouseWheelInput in src/Cameras/Inputs/freeCameraMouseWheelInput.ts\r\n * for example usage.\r\n */\r\nexport abstract class BaseCameraMouseWheelInput implements ICameraInput<Camera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public abstract camera: Camera;\r\n\r\n    /**\r\n     * How fast is the camera moves in relation to X axis mouseWheel events.\r\n     * Use negative value to reverse direction.\r\n     */\r\n    @serialize()\r\n    public wheelPrecisionX = 3.0;\r\n\r\n    /**\r\n     * How fast is the camera moves in relation to Y axis mouseWheel events.\r\n     * Use negative value to reverse direction.\r\n     */\r\n    @serialize()\r\n    public wheelPrecisionY = 3.0;\r\n\r\n    /**\r\n     * How fast is the camera moves in relation to Z axis mouseWheel events.\r\n     * Use negative value to reverse direction.\r\n     */\r\n    @serialize()\r\n    public wheelPrecisionZ = 3.0;\r\n\r\n    /**\r\n     * Observable for when a mouse wheel move event occurs.\r\n     */\r\n    public onChangedObservable = new Observable<{ wheelDeltaX: number; wheelDeltaY: number; wheelDeltaZ: number }>();\r\n\r\n    private _wheel: Nullable<(pointer: PointerInfo) => void>;\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls\r\n     *   should call preventdefault().\r\n     *   (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n\r\n        this._wheel = (pointer) => {\r\n            // sanity check - this should be a PointerWheel event.\r\n            if (pointer.type !== PointerEventTypes.POINTERWHEEL) {\r\n                return;\r\n            }\r\n\r\n            const event = <IWheelEvent>pointer.event;\r\n\r\n            const platformScale = event.deltaMode === EventConstants.DOM_DELTA_LINE ? this._ffMultiplier : 1; // If this happens to be set to DOM_DELTA_LINE, adjust accordingly\r\n\r\n            this._wheelDeltaX += (this.wheelPrecisionX * platformScale * event.deltaX) / this._normalize;\r\n            this._wheelDeltaY -= (this.wheelPrecisionY * platformScale * event.deltaY) / this._normalize;\r\n            this._wheelDeltaZ += (this.wheelPrecisionZ * platformScale * event.deltaZ) / this._normalize;\r\n\r\n            if (event.preventDefault) {\r\n                if (!noPreventDefault) {\r\n                    event.preventDefault();\r\n                }\r\n            }\r\n        };\r\n\r\n        this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(this._wheel, PointerEventTypes.POINTERWHEEL);\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._observer) {\r\n            this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n            this._observer = null;\r\n            this._wheel = null;\r\n        }\r\n        if (this.onChangedObservable) {\r\n            this.onChangedObservable.clear();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called for each rendered frame.\r\n     */\r\n    public checkInputs(): void {\r\n        this.onChangedObservable.notifyObservers({\r\n            wheelDeltaX: this._wheelDeltaX,\r\n            wheelDeltaY: this._wheelDeltaY,\r\n            wheelDeltaZ: this._wheelDeltaZ,\r\n        });\r\n\r\n        // Clear deltas.\r\n        this._wheelDeltaX = 0;\r\n        this._wheelDeltaY = 0;\r\n        this._wheelDeltaZ = 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"BaseCameraMouseWheelInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"mousewheel\";\r\n    }\r\n\r\n    /**\r\n     * Incremental value of multiple mouse wheel movements of the X axis.\r\n     * Should be zero-ed when read.\r\n     */\r\n    protected _wheelDeltaX: number = 0;\r\n\r\n    /**\r\n     * Incremental value of multiple mouse wheel movements of the Y axis.\r\n     * Should be zero-ed when read.\r\n     */\r\n    protected _wheelDeltaY: number = 0;\r\n\r\n    /**\r\n     * Incremental value of multiple mouse wheel movements of the Z axis.\r\n     * Should be zero-ed when read.\r\n     */\r\n    protected _wheelDeltaZ: number = 0;\r\n\r\n    /**\r\n     * Firefox uses a different scheme to report scroll distances to other\r\n     * browsers. Rather than use complicated methods to calculate the exact\r\n     * multiple we need to apply, let's just cheat and use a constant.\r\n     * https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode\r\n     * https://stackoverflow.com/questions/20110224/what-is-the-height-of-a-line-in-a-wheel-event-deltamode-dom-delta-line\r\n     */\r\n    private readonly _ffMultiplier = 12;\r\n\r\n    /**\r\n     * Different event attributes for wheel data fall into a few set ranges.\r\n     * Some relevant but dated date here:\r\n     * https://stackoverflow.com/questions/5527601/normalizing-mousewheel-speed-across-browsers\r\n     */\r\n    private readonly _normalize = 120;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type EventState, type Observer } from \"../../Misc/observable\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type ICameraInput } from \"../../Cameras/cameraInputsManager\";\r\nimport { type PointerInfo, type PointerTouch, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\n\r\n/**\r\n * Base class for Camera Pointer Inputs.\r\n * See FollowCameraPointersInput in src/Cameras/Inputs/followCameraPointersInput.ts\r\n * for example usage.\r\n */\r\nexport abstract class BaseCameraPointersInput implements ICameraInput<Camera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public abstract camera: Camera;\r\n\r\n    /**\r\n     * Whether keyboard modifier keys are pressed at time of last mouse event.\r\n     */\r\n    protected _altKey: boolean;\r\n    protected _ctrlKey: boolean;\r\n    protected _metaKey: boolean;\r\n    protected _shiftKey: boolean;\r\n\r\n    /**\r\n     * Which mouse buttons were pressed at time of last mouse event.\r\n     * https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons\r\n     */\r\n    protected _buttonsPressed: number;\r\n\r\n    /**\r\n     * Which pointer ID is currently down (only for mouse events, not used for touch events)\r\n     */\r\n    private _currentMousePointerIdDown: number = -1;\r\n    private _contextMenuBind: EventListener;\r\n\r\n    /**\r\n     * Defines the buttons associated with the input to handle camera move.\r\n     */\r\n    @serialize()\r\n    public buttons = [0, 1, 2];\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        const engine = this.camera.getEngine();\r\n        const element = engine.getInputElement();\r\n        let previousPinchSquaredDistance = 0;\r\n        let previousMultiTouchPanPosition: Nullable<PointerTouch> = null;\r\n\r\n        this._pointA = null;\r\n        this._pointB = null;\r\n\r\n        this._altKey = false;\r\n        this._ctrlKey = false;\r\n        this._metaKey = false;\r\n        this._shiftKey = false;\r\n        this._buttonsPressed = 0;\r\n\r\n        this._pointerInput = (p) => {\r\n            const evt = <IPointerEvent>p.event;\r\n            const isTouch = evt.pointerType === \"touch\";\r\n\r\n            if (p.type !== PointerEventTypes.POINTERMOVE && this.buttons.indexOf(evt.button) === -1) {\r\n                return;\r\n            }\r\n\r\n            const srcElement = <HTMLElement>evt.target;\r\n\r\n            this._altKey = evt.altKey;\r\n            this._ctrlKey = evt.ctrlKey;\r\n            this._metaKey = evt.metaKey;\r\n            this._shiftKey = evt.shiftKey;\r\n            this._buttonsPressed = evt.buttons;\r\n\r\n            if (engine.isPointerLock) {\r\n                const offsetX = evt.movementX;\r\n                const offsetY = evt.movementY;\r\n\r\n                this.onTouch(null, offsetX, offsetY);\r\n                this._pointA = null;\r\n                this._pointB = null;\r\n            } else if (\r\n                p.type !== PointerEventTypes.POINTERDOWN &&\r\n                p.type !== PointerEventTypes.POINTERDOUBLETAP &&\r\n                isTouch &&\r\n                this._pointA?.pointerId !== evt.pointerId &&\r\n                this._pointB?.pointerId !== evt.pointerId\r\n            ) {\r\n                return; // If we get a non-down event for a touch that we're not tracking, ignore it\r\n            } else if (p.type === PointerEventTypes.POINTERDOWN && (this._currentMousePointerIdDown === -1 || isTouch)) {\r\n                try {\r\n                    srcElement?.setPointerCapture(evt.pointerId);\r\n                } catch (e) {\r\n                    //Nothing to do with the error. Execution will continue.\r\n                }\r\n\r\n                if (this._pointA === null) {\r\n                    this._pointA = {\r\n                        x: evt.clientX,\r\n                        y: evt.clientY,\r\n                        pointerId: evt.pointerId,\r\n                        type: evt.pointerType,\r\n                        button: evt.button,\r\n                    };\r\n                } else if (this._pointB === null) {\r\n                    this._pointB = {\r\n                        x: evt.clientX,\r\n                        y: evt.clientY,\r\n                        pointerId: evt.pointerId,\r\n                        type: evt.pointerType,\r\n                        button: evt.button,\r\n                    };\r\n                } else {\r\n                    return; // We are already tracking two pointers so ignore this one\r\n                }\r\n\r\n                if (this._currentMousePointerIdDown === -1 && !isTouch) {\r\n                    this._currentMousePointerIdDown = evt.pointerId;\r\n                }\r\n                this.onButtonDown(evt);\r\n\r\n                if (!noPreventDefault) {\r\n                    evt.preventDefault();\r\n                    if (element) {\r\n                        element.focus();\r\n                    }\r\n                }\r\n            } else if (p.type === PointerEventTypes.POINTERDOUBLETAP) {\r\n                this.onDoubleTap(evt.pointerType, evt);\r\n            } else if (p.type === PointerEventTypes.POINTERUP && (this._currentMousePointerIdDown === evt.pointerId || isTouch)) {\r\n                try {\r\n                    srcElement?.releasePointerCapture(evt.pointerId);\r\n                } catch (e) {\r\n                    //Nothing to do with the error.\r\n                }\r\n\r\n                if (!isTouch) {\r\n                    this._pointB = null; // Mouse and pen are mono pointer\r\n                }\r\n\r\n                //would be better to use pointers.remove(evt.pointerId) for multitouch gestures,\r\n                //but emptying completely pointers collection is required to fix a bug on iPhone :\r\n                //when changing orientation while pinching camera,\r\n                //one pointer stay pressed forever if we don't release all pointers\r\n                //will be ok to put back pointers.remove(evt.pointerId); when iPhone bug corrected\r\n                if (engine._badOS) {\r\n                    this._pointA = this._pointB = null;\r\n                } else {\r\n                    //only remove the impacted pointer in case of multitouch allowing on most\r\n                    //platforms switching from rotate to zoom and pan seamlessly.\r\n                    if (this._pointB && this._pointA && this._pointA.pointerId == evt.pointerId) {\r\n                        this._pointA = this._pointB;\r\n                        this._pointB = null;\r\n                    } else if (this._pointA && this._pointB && this._pointB.pointerId == evt.pointerId) {\r\n                        this._pointB = null;\r\n                    } else {\r\n                        this._pointA = this._pointB = null;\r\n                    }\r\n                }\r\n\r\n                if (previousPinchSquaredDistance !== 0 || previousMultiTouchPanPosition) {\r\n                    // Previous pinch data is populated but a button has been lifted\r\n                    // so pinch has ended.\r\n                    this.onMultiTouch(\r\n                        this._pointA,\r\n                        this._pointB,\r\n                        previousPinchSquaredDistance,\r\n                        0, // pinchSquaredDistance\r\n                        previousMultiTouchPanPosition,\r\n                        null // multiTouchPanPosition\r\n                    );\r\n                    previousPinchSquaredDistance = 0;\r\n                    previousMultiTouchPanPosition = null;\r\n                }\r\n\r\n                this._currentMousePointerIdDown = -1;\r\n                this.onButtonUp(evt);\r\n\r\n                if (!noPreventDefault) {\r\n                    evt.preventDefault();\r\n                }\r\n            } else if (p.type === PointerEventTypes.POINTERMOVE) {\r\n                if (!noPreventDefault) {\r\n                    evt.preventDefault();\r\n                }\r\n\r\n                // One button down\r\n                if (this._pointA && this._pointB === null) {\r\n                    const offsetX = evt.clientX - this._pointA.x;\r\n                    const offsetY = evt.clientY - this._pointA.y;\r\n                    this._pointA.x = evt.clientX;\r\n                    this._pointA.y = evt.clientY;\r\n                    this.onTouch(this._pointA, offsetX, offsetY);\r\n                }\r\n                // Two buttons down: pinch\r\n                else if (this._pointA && this._pointB) {\r\n                    const ed = this._pointA.pointerId === evt.pointerId ? this._pointA : this._pointB;\r\n                    ed.x = evt.clientX;\r\n                    ed.y = evt.clientY;\r\n                    const distX = this._pointA.x - this._pointB.x;\r\n                    const distY = this._pointA.y - this._pointB.y;\r\n                    const pinchSquaredDistance = distX * distX + distY * distY;\r\n                    const multiTouchPanPosition = {\r\n                        x: (this._pointA.x + this._pointB.x) / 2,\r\n                        y: (this._pointA.y + this._pointB.y) / 2,\r\n                        pointerId: evt.pointerId,\r\n                        type: p.type,\r\n                    };\r\n\r\n                    this.onMultiTouch(this._pointA, this._pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition);\r\n\r\n                    previousMultiTouchPanPosition = multiTouchPanPosition;\r\n                    previousPinchSquaredDistance = pinchSquaredDistance;\r\n                }\r\n            }\r\n        };\r\n\r\n        this._observer = this.camera\r\n            .getScene()\r\n            ._inputManager._addCameraPointerObserver(\r\n                this._pointerInput,\r\n                PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE | PointerEventTypes.POINTERDOUBLETAP\r\n            );\r\n\r\n        this._onLostFocus = () => {\r\n            this._pointA = this._pointB = null;\r\n            previousPinchSquaredDistance = 0;\r\n            previousMultiTouchPanPosition = null;\r\n            this.onLostFocus();\r\n        };\r\n\r\n        this._contextMenuBind = (evt: Event) => this.onContextMenu(evt as PointerEvent);\r\n\r\n        if (element) {\r\n            element.addEventListener(\"contextmenu\", this._contextMenuBind, false);\r\n        }\r\n\r\n        const hostWindow = this.camera.getScene().getEngine().getHostWindow();\r\n\r\n        if (hostWindow) {\r\n            Tools.RegisterTopRootEvents(hostWindow, [{ name: \"blur\", handler: this._onLostFocus }]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._onLostFocus) {\r\n            const hostWindow = this.camera.getScene().getEngine().getHostWindow();\r\n            if (hostWindow) {\r\n                Tools.UnregisterTopRootEvents(hostWindow, [{ name: \"blur\", handler: this._onLostFocus }]);\r\n            }\r\n        }\r\n\r\n        if (this._observer) {\r\n            this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n            this._observer = null;\r\n\r\n            if (this._contextMenuBind) {\r\n                const inputElement = this.camera.getScene().getEngine().getInputElement();\r\n                if (inputElement) {\r\n                    inputElement.removeEventListener(\"contextmenu\", this._contextMenuBind);\r\n                }\r\n            }\r\n\r\n            this._onLostFocus = null;\r\n        }\r\n\r\n        this._altKey = false;\r\n        this._ctrlKey = false;\r\n        this._metaKey = false;\r\n        this._shiftKey = false;\r\n        this._buttonsPressed = 0;\r\n        this._currentMousePointerIdDown = -1;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"BaseCameraPointersInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"pointers\";\r\n    }\r\n\r\n    /**\r\n     * Called on pointer POINTERDOUBLETAP event.\r\n     * Override this method to provide functionality on POINTERDOUBLETAP event.\r\n     * @param type type of event\r\n     * @param evt the pointer event that triggered the double tap (carries button / buttons state)\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public onDoubleTap(type: string, evt?: IPointerEvent) {}\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    /**\r\n     * Called on pointer POINTERMOVE event if only a single touch is active.\r\n     * Override this method to provide functionality.\r\n     * @param point The current position of the pointer\r\n     * @param offsetX The offsetX of the pointer when the event occurred\r\n     * @param offsetY The offsetY of the pointer when the event occurred\r\n     */\r\n    public onTouch(point: Nullable<PointerTouch>, offsetX: number, offsetY: number): void {}\r\n\r\n    /**\r\n     * Called on pointer POINTERMOVE event if multiple touches are active.\r\n     * Override this method to provide functionality.\r\n     * @param _pointA First point in the pair\r\n     * @param _pointB Second point in the pair\r\n     * @param previousPinchSquaredDistance Sqr Distance between the points the last time this event was fired (by this input)\r\n     * @param pinchSquaredDistance Sqr Distance between the points this time\r\n     * @param previousMultiTouchPanPosition Previous center point between the points\r\n     * @param multiTouchPanPosition Current center point between the points\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public onMultiTouch(\r\n        _pointA: Nullable<PointerTouch>,\r\n        _pointB: Nullable<PointerTouch>,\r\n        previousPinchSquaredDistance: number,\r\n        pinchSquaredDistance: number,\r\n        previousMultiTouchPanPosition: Nullable<PointerTouch>,\r\n        multiTouchPanPosition: Nullable<PointerTouch>\r\n    ): void {}\r\n\r\n    /**\r\n     * Called on JS contextmenu event.\r\n     * Override this method to provide functionality.\r\n     * @param evt the event to be handled\r\n     */\r\n    public onContextMenu(evt: PointerEvent): void {\r\n        evt.preventDefault();\r\n    }\r\n\r\n    /**\r\n     * Called each time a new POINTERDOWN event occurs. Ie, for each button\r\n     * press.\r\n     * Override this method to provide functionality.\r\n     * @param _evt Defines the event to track\r\n     */\r\n    public onButtonDown(_evt: IPointerEvent): void {}\r\n\r\n    /**\r\n     * Called each time a new POINTERUP event occurs. Ie, for each button\r\n     * release.\r\n     * Override this method to provide functionality.\r\n     * @param _evt Defines the event to track\r\n     */\r\n    public onButtonUp(_evt: IPointerEvent): void {}\r\n\r\n    /**\r\n     * Called when window becomes inactive.\r\n     * Override this method to provide functionality.\r\n     */\r\n    public onLostFocus(): void {}\r\n\r\n    private _pointerInput: (p: PointerInfo, s: EventState) => void;\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n    private _onLostFocus: Nullable<(e: FocusEvent) => any>;\r\n    private _pointA: Nullable<PointerTouch>;\r\n    private _pointB: Nullable<PointerTouch>;\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Camera } from \"./camera.pure\";\r\n/**\r\n * @ignore\r\n * This is a list of all the different input types that are available in the application.\r\n * Fo instance: ArcRotateCameraGamepadInput...\r\n */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var CameraInputTypes = {};\r\n\r\n/**\r\n * This is the contract to implement in order to create a new input class.\r\n * Inputs are dealing with listening to user actions and moving the camera accordingly.\r\n */\r\nexport interface ICameraInput<Tcamera extends Camera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    camera: Nullable<Tcamera>;\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    getClassName(): string;\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    getSimpleName(): string;\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    attachControl(noPreventDefault?: boolean): void;\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    detachControl(): void;\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    checkInputs?: () => void;\r\n}\r\n\r\n/**\r\n * Represents a map of input types to input instance or input index to input instance.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface CameraInputsMap<Tcamera extends Camera> {\r\n    /**\r\n     * Accessor to the input by input type.\r\n     */\r\n    [name: string]: ICameraInput<Tcamera>;\r\n    /**\r\n     * Accessor to the input by input index.\r\n     */\r\n    [idx: number]: ICameraInput<Tcamera>;\r\n}\r\n\r\n/**\r\n * This represents the input manager used within a camera.\r\n * It helps dealing with all the different kind of input attached to a camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class CameraInputsManager<Tcamera extends Camera> {\r\n    /**\r\n     * Defines the list of inputs attached to the camera.\r\n     */\r\n    public attached: CameraInputsMap<Tcamera>;\r\n\r\n    /**\r\n     * Defines the dom element the camera is collecting inputs from.\r\n     * This is null if the controls have not been attached.\r\n     */\r\n    public attachedToElement: boolean = false;\r\n\r\n    /**\r\n     * Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public noPreventDefault: boolean;\r\n\r\n    /**\r\n     * Defined the camera the input manager belongs to.\r\n     */\r\n    public camera: Tcamera;\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs: () => void;\r\n\r\n    /**\r\n     * Instantiate a new Camera Input Manager.\r\n     * @param camera Defines the camera the input manager belongs to\r\n     */\r\n    constructor(camera: Tcamera) {\r\n        this.attached = {};\r\n        this.camera = camera;\r\n        this.checkInputs = () => {};\r\n    }\r\n\r\n    /**\r\n     * Add an input method to a camera\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n     * @param input Camera input method\r\n     */\r\n    public add(input: ICameraInput<Tcamera>): void {\r\n        const type = input.getSimpleName();\r\n        if (this.attached[type]) {\r\n            Logger.Warn(\"camera input of type \" + type + \" already exists on camera\");\r\n            return;\r\n        }\r\n\r\n        this.attached[type] = input;\r\n\r\n        input.camera = this.camera;\r\n\r\n        // for checkInputs, we are dynamically creating a function\r\n        // the goal is to avoid the performance penalty of looping for inputs in the render loop\r\n        if (input.checkInputs) {\r\n            this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));\r\n        }\r\n\r\n        if (this.attachedToElement) {\r\n            input.attachControl(this.noPreventDefault);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a specific input method from a camera\r\n     * example: camera.inputs.remove(camera.inputs.attached.mouse);\r\n     * @param inputToRemove camera input method\r\n     */\r\n    public remove(inputToRemove: ICameraInput<Tcamera>): void {\r\n        for (const cam in this.attached) {\r\n            const input = this.attached[cam];\r\n            if (input === inputToRemove) {\r\n                input.detachControl();\r\n                input.camera = null;\r\n                delete this.attached[cam];\r\n                this.rebuildInputCheck();\r\n\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a specific input type from a camera\r\n     * example: camera.inputs.remove(\"ArcRotateCameraGamepadInput\");\r\n     * @param inputType the type of the input to remove\r\n     */\r\n    public removeByType(inputType: string): void {\r\n        for (const cam in this.attached) {\r\n            const input = this.attached[cam];\r\n            if (input.getClassName() === inputType) {\r\n                input.detachControl();\r\n                input.camera = null;\r\n                delete this.attached[cam];\r\n                this.rebuildInputCheck();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _addCheckInputs(fn: () => void) {\r\n        const current = this.checkInputs;\r\n        return () => {\r\n            current();\r\n            fn();\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to the currently attached dom element to listen the events from.\r\n     * @param input Defines the input to attach\r\n     */\r\n    public attachInput(input: ICameraInput<Tcamera>): void {\r\n        if (this.attachedToElement) {\r\n            input.attachControl(this.noPreventDefault);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attach the current manager inputs controls to a specific dom element to listen the events from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachElement(noPreventDefault: boolean = false): void {\r\n        if (this.attachedToElement) {\r\n            return;\r\n        }\r\n\r\n        noPreventDefault = Camera.ForceAttachControlToAlwaysPreventDefault ? false : noPreventDefault;\r\n        this.attachedToElement = true;\r\n        this.noPreventDefault = noPreventDefault;\r\n\r\n        for (const cam in this.attached) {\r\n            this.attached[cam].attachControl(noPreventDefault);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current manager inputs controls from a specific dom element.\r\n     * @param disconnect Defines whether the input should be removed from the current list of attached inputs\r\n     */\r\n    public detachElement(disconnect = false): void {\r\n        for (const cam in this.attached) {\r\n            this.attached[cam].detachControl();\r\n\r\n            if (disconnect) {\r\n                this.attached[cam].camera = null;\r\n            }\r\n        }\r\n        this.attachedToElement = false;\r\n    }\r\n\r\n    /**\r\n     * Rebuild the dynamic inputCheck function from the current list of\r\n     * defined inputs in the manager.\r\n     */\r\n    public rebuildInputCheck(): void {\r\n        this.checkInputs = () => {};\r\n\r\n        for (const cam in this.attached) {\r\n            const input = this.attached[cam];\r\n            if (input.checkInputs) {\r\n                this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove all attached input methods from a camera\r\n     */\r\n    public clear(): void {\r\n        if (this.attachedToElement) {\r\n            this.detachElement(true);\r\n        }\r\n        this.attached = {};\r\n        this.attachedToElement = false;\r\n        this.checkInputs = () => {};\r\n    }\r\n\r\n    /**\r\n     * Serialize the current input manager attached to a camera.\r\n     * This ensures than once parsed,\r\n     * the input associated to the camera will be identical to the current ones\r\n     * @param serializedCamera Defines the camera serialization JSON the input serialization should write to\r\n     */\r\n    public serialize(serializedCamera: any): void {\r\n        const inputs: { [key: string]: any } = {};\r\n        for (const cam in this.attached) {\r\n            const input = this.attached[cam];\r\n            const res = SerializationHelper.Serialize(input);\r\n            inputs[input.getClassName()] = res;\r\n        }\r\n\r\n        serializedCamera.inputsmgr = inputs;\r\n    }\r\n\r\n    /**\r\n     * Parses an input manager serialized JSON to restore the previous list of inputs\r\n     * and states associated to a camera.\r\n     * @param parsedCamera Defines the JSON to parse\r\n     */\r\n    public parse(parsedCamera: any): void {\r\n        const parsedInputs = parsedCamera.inputsmgr;\r\n        if (parsedInputs) {\r\n            this.clear();\r\n\r\n            for (const n in parsedInputs) {\r\n                const construct = (<any>CameraInputTypes)[n];\r\n                if (construct) {\r\n                    const parsedinput = parsedInputs[n];\r\n                    const input = SerializationHelper.Parse(\r\n                        () => {\r\n                            return new construct();\r\n                        },\r\n                        parsedinput,\r\n                        null\r\n                    );\r\n                    this.add(input);\r\n                }\r\n            }\r\n        } else {\r\n            //2016-03-08 this part is for managing backward compatibility\r\n            for (const n in this.attached) {\r\n                const construct = (<any>CameraInputTypes)[this.attached[n].getClassName()];\r\n                if (construct) {\r\n                    const input = SerializationHelper.Parse(\r\n                        () => {\r\n                            return new construct();\r\n                        },\r\n                        parsedCamera,\r\n                        null\r\n                    );\r\n                    this.remove(this.attached[n]);\r\n                    this.add(input);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\n\r\n/**\r\n * Represents a gamepad control stick position\r\n */\r\nexport class StickValues {\r\n    /**\r\n     * Initializes the gamepad x and y control stick values\r\n     * @param x The x component of the gamepad control stick value\r\n     * @param y The y component of the gamepad control stick value\r\n     */\r\n    constructor(\r\n        /**\r\n         * The x component of the control stick\r\n         */\r\n        public x: number,\r\n        /**\r\n         * The y component of the control stick\r\n         */\r\n        public y: number\r\n    ) {}\r\n}\r\n\r\n/**\r\n * An interface which manages callbacks for gamepad button changes\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GamepadButtonChanges {\r\n    /**\r\n     * Called when a gamepad has been changed\r\n     */\r\n    changed: boolean;\r\n    /**\r\n     * Called when a gamepad press event has been triggered\r\n     */\r\n    pressChanged: boolean;\r\n    /**\r\n     * Called when a touch event has been triggered\r\n     */\r\n    touchChanged: boolean;\r\n    /**\r\n     * Called when a value has changed\r\n     */\r\n    valueChanged: boolean;\r\n}\r\n\r\n/**\r\n * Represents a gamepad\r\n */\r\nexport class Gamepad {\r\n    /**\r\n     * Specifies what type of gamepad this represents\r\n     */\r\n    public type: number;\r\n\r\n    private _leftStick: StickValues = { x: 0, y: 0 };\r\n    private _rightStick: StickValues = { x: 0, y: 0 };\r\n\r\n    /** @internal */\r\n    public _isConnected = true;\r\n\r\n    private _leftStickAxisX: number;\r\n    private _leftStickAxisY: number;\r\n    private _rightStickAxisX: number;\r\n    private _rightStickAxisY: number;\r\n\r\n    /**\r\n     * Triggered when the left control stick has been changed\r\n     */\r\n    private _onleftstickchanged: (values: StickValues) => void;\r\n\r\n    /**\r\n     * Triggered when the right control stick has been changed\r\n     */\r\n    private _onrightstickchanged: (values: StickValues) => void;\r\n\r\n    /**\r\n     * Represents a gamepad controller\r\n     */\r\n    public static GAMEPAD = 0;\r\n    /**\r\n     * Represents a generic controller\r\n     */\r\n    public static GENERIC = 1;\r\n    /**\r\n     * Represents an XBox controller\r\n     */\r\n    public static XBOX = 2;\r\n    /**\r\n     * Represents a pose-enabled controller\r\n     */\r\n    public static POSE_ENABLED = 3;\r\n    /**\r\n     * Represents an Dual Shock controller\r\n     */\r\n    public static DUALSHOCK = 4;\r\n\r\n    /**\r\n     * Specifies whether the left control stick should be Y-inverted\r\n     */\r\n    protected _invertLeftStickY: boolean = false;\r\n\r\n    /**\r\n     * Specifies if the gamepad has been connected\r\n     */\r\n    public get isConnected(): boolean {\r\n        return this._isConnected;\r\n    }\r\n\r\n    /**\r\n     * Initializes the gamepad\r\n     * @param id The id of the gamepad\r\n     * @param index The index of the gamepad\r\n     * @param browserGamepad The browser gamepad\r\n     * @param leftStickX The x component of the left joystick\r\n     * @param leftStickY The y component of the left joystick\r\n     * @param rightStickX The x component of the right joystick\r\n     * @param rightStickY The y component of the right joystick\r\n     */\r\n    constructor(\r\n        /**\r\n         * The id of the gamepad\r\n         */\r\n        public id: string,\r\n        /**\r\n         * The index of the gamepad\r\n         */\r\n        public index: number,\r\n        /**\r\n         * The browser gamepad\r\n         */\r\n        public browserGamepad: any,\r\n        leftStickX: number = 0,\r\n        leftStickY: number = 1,\r\n        rightStickX: number = 2,\r\n        rightStickY: number = 3\r\n    ) {\r\n        this.type = Gamepad.GAMEPAD;\r\n        this._leftStickAxisX = leftStickX;\r\n        this._leftStickAxisY = leftStickY;\r\n        this._rightStickAxisX = rightStickX;\r\n        this._rightStickAxisY = rightStickY;\r\n        if (this.browserGamepad.axes.length >= 2) {\r\n            this._leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };\r\n        }\r\n        if (this.browserGamepad.axes.length >= 4) {\r\n            this._rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Callback triggered when the left joystick has changed\r\n     * @param callback callback to trigger\r\n     */\r\n    public onleftstickchanged(callback: (values: StickValues) => void) {\r\n        this._onleftstickchanged = callback;\r\n    }\r\n\r\n    /**\r\n     * Callback triggered when the right joystick has changed\r\n     * @param callback callback to trigger\r\n     */\r\n    public onrightstickchanged(callback: (values: StickValues) => void) {\r\n        this._onrightstickchanged = callback;\r\n    }\r\n\r\n    /**\r\n     * Gets the left joystick\r\n     */\r\n    public get leftStick(): StickValues {\r\n        return this._leftStick;\r\n    }\r\n    /**\r\n     * Sets the left joystick values\r\n     */\r\n    public set leftStick(newValues: StickValues) {\r\n        if (this._onleftstickchanged && (this._leftStick.x !== newValues.x || this._leftStick.y !== newValues.y)) {\r\n            this._onleftstickchanged(newValues);\r\n        }\r\n        this._leftStick = newValues;\r\n    }\r\n    /**\r\n     * Gets the right joystick\r\n     */\r\n    public get rightStick(): StickValues {\r\n        return this._rightStick;\r\n    }\r\n    /**\r\n     * Sets the right joystick value\r\n     */\r\n    public set rightStick(newValues: StickValues) {\r\n        if (this._onrightstickchanged && (this._rightStick.x !== newValues.x || this._rightStick.y !== newValues.y)) {\r\n            this._onrightstickchanged(newValues);\r\n        }\r\n        this._rightStick = newValues;\r\n    }\r\n\r\n    /**\r\n     * Updates the gamepad joystick positions\r\n     */\r\n\r\n    public update() {\r\n        if (this._leftStick) {\r\n            this.leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };\r\n            if (this._invertLeftStickY) {\r\n                this.leftStick.y *= -1;\r\n            }\r\n        }\r\n        if (this._rightStick) {\r\n            this.rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the gamepad\r\n     */\r\n    public dispose() {}\r\n}\r\n\r\n/**\r\n * Represents a generic gamepad\r\n */\r\nexport class GenericPad extends Gamepad {\r\n    private _buttons: Array<number>;\r\n    private _onbuttondown: (buttonPressed: number) => void;\r\n    private _onbuttonup: (buttonReleased: number) => void;\r\n\r\n    /**\r\n     * Observable triggered when a button has been pressed\r\n     */\r\n    public onButtonDownObservable = new Observable<number>();\r\n    /**\r\n     * Observable triggered when a button has been released\r\n     */\r\n    public onButtonUpObservable = new Observable<number>();\r\n\r\n    /**\r\n     * Callback triggered when a button has been pressed\r\n     * @param callback Called when a button has been pressed\r\n     */\r\n    public onbuttondown(callback: (buttonPressed: number) => void) {\r\n        this._onbuttondown = callback;\r\n    }\r\n    /**\r\n     * Callback triggered when a button has been released\r\n     * @param callback Called when a button has been released\r\n     */\r\n    public onbuttonup(callback: (buttonReleased: number) => void) {\r\n        this._onbuttonup = callback;\r\n    }\r\n\r\n    /**\r\n     * Initializes the generic gamepad\r\n     * @param id The id of the generic gamepad\r\n     * @param index The index of the generic gamepad\r\n     * @param browserGamepad The browser gamepad\r\n     */\r\n    constructor(id: string, index: number, browserGamepad: any) {\r\n        super(id, index, browserGamepad);\r\n        this.type = Gamepad.GENERIC;\r\n        this._buttons = new Array(browserGamepad.buttons.length);\r\n    }\r\n\r\n    private _setButtonValue(newValue: number, currentValue: number, buttonIndex: number): number {\r\n        if (newValue !== currentValue) {\r\n            if (newValue === 1) {\r\n                if (this._onbuttondown) {\r\n                    this._onbuttondown(buttonIndex);\r\n                }\r\n\r\n                this.onButtonDownObservable.notifyObservers(buttonIndex);\r\n            }\r\n            if (newValue === 0) {\r\n                if (this._onbuttonup) {\r\n                    this._onbuttonup(buttonIndex);\r\n                }\r\n\r\n                this.onButtonUpObservable.notifyObservers(buttonIndex);\r\n            }\r\n        }\r\n        return newValue;\r\n    }\r\n\r\n    /**\r\n     * Updates the generic gamepad\r\n     */\r\n    public override update() {\r\n        super.update();\r\n        for (let index = 0; index < this._buttons.length; index++) {\r\n            this._buttons[index] = this._setButtonValue(this.browserGamepad.buttons[index].value, this._buttons[index], index);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the generic gamepad\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        this.onButtonDownObservable.clear();\r\n        this.onButtonUpObservable.clear();\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { Gamepad } from \"../../Gamepads/gamepad\";\r\n/**\r\n * Manage the gamepad inputs to control an arc rotate camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraGamepadInput implements ICameraInput<ArcRotateCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: ArcRotateCamera;\r\n\r\n    /**\r\n     * Defines the gamepad the input is gathering event from.\r\n     */\r\n    public gamepad: Nullable<Gamepad>;\r\n\r\n    /**\r\n     * Defines the gamepad rotation sensibility.\r\n     * This is the threshold from when rotation starts to be accounted for to prevent jittering.\r\n     */\r\n    @serialize()\r\n    public gamepadRotationSensibility = 80;\r\n\r\n    /**\r\n     * Defines the gamepad move sensibility.\r\n     * This is the threshold from when moving starts to be accounted for for to prevent jittering.\r\n     */\r\n    @serialize()\r\n    public gamepadMoveSensibility = 40;\r\n\r\n    private _yAxisScale = 1.0;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that Yaxis (for right stick) should be inverted\r\n     */\r\n    public get invertYAxis() {\r\n        return this._yAxisScale !== 1.0;\r\n    }\r\n\r\n    public set invertYAxis(value: boolean) {\r\n        this._yAxisScale = value ? -1.0 : 1.0;\r\n    }\r\n\r\n    private _onGamepadConnectedObserver: Nullable<Observer<Gamepad>>;\r\n    private _onGamepadDisconnectedObserver: Nullable<Observer<Gamepad>>;\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     */\r\n    public attachControl(): void {\r\n        const manager = this.camera.getScene().gamepadManager;\r\n        this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add((gamepad) => {\r\n            if (gamepad.type !== Gamepad.POSE_ENABLED) {\r\n                // prioritize XBOX gamepads.\r\n                if (!this.gamepad || gamepad.type === Gamepad.XBOX) {\r\n                    this.gamepad = gamepad;\r\n                }\r\n            }\r\n        });\r\n\r\n        this._onGamepadDisconnectedObserver = manager.onGamepadDisconnectedObservable.add((gamepad) => {\r\n            if (this.gamepad === gamepad) {\r\n                this.gamepad = null;\r\n            }\r\n        });\r\n\r\n        this.gamepad = manager.getGamepadByType(Gamepad.XBOX);\r\n        // if no xbox controller was found, but there are gamepad controllers, take the first one\r\n        if (!this.gamepad && manager.gamepads.length) {\r\n            this.gamepad = manager.gamepads[0];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        this.camera.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);\r\n        this.camera.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);\r\n        this.gamepad = null;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this.gamepad) {\r\n            const camera = this.camera;\r\n            const rsValues = this.gamepad.rightStick;\r\n\r\n            if (rsValues) {\r\n                if (rsValues.x != 0) {\r\n                    const normalizedRX = rsValues.x / this.gamepadRotationSensibility;\r\n                    if (normalizedRX != 0 && Math.abs(normalizedRX) > 0.005) {\r\n                        camera.movement.activeInput = true;\r\n                        camera.movement.rotationAccumulatedPixels.x += normalizedRX;\r\n                    }\r\n                }\r\n\r\n                if (rsValues.y != 0) {\r\n                    const normalizedRY = (rsValues.y / this.gamepadRotationSensibility) * this._yAxisScale;\r\n                    if (normalizedRY != 0 && Math.abs(normalizedRY) > 0.005) {\r\n                        camera.movement.activeInput = true;\r\n                        camera.movement.rotationAccumulatedPixels.y += normalizedRY;\r\n                    }\r\n                }\r\n            }\r\n\r\n            const lsValues = this.gamepad.leftStick;\r\n            if (lsValues && lsValues.y != 0) {\r\n                const normalizedLY = lsValues.y / this.gamepadMoveSensibility;\r\n                if (normalizedLY != 0 && Math.abs(normalizedLY) > 0.005) {\r\n                    camera.movement.activeInput = true;\r\n                    camera.movement.zoomAccumulatedPixels -= normalizedLY;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current intput.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ArcRotateCameraGamepadInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"gamepad\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"ArcRotateCameraGamepadInput\"] = ArcRotateCameraGamepadInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type KeyboardConditions } from \"../inputMapper\";\r\nimport { Vector2 } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of an arc rotate camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraKeyboardMoveInput implements ICameraInput<ArcRotateCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: ArcRotateCamera;\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the up action (increase alpha)\r\n     */\r\n    @serialize()\r\n    public keysUp = [38];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the down action (decrease alpha)\r\n     */\r\n    @serialize()\r\n    public keysDown = [40];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the left action (increase beta)\r\n     */\r\n    @serialize()\r\n    public keysLeft = [37];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the right action (decrease beta)\r\n     */\r\n    @serialize()\r\n    public keysRight = [39];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the reset action.\r\n     * Those keys reset the camera to its last stored state (with the method camera.storeState())\r\n     */\r\n    @serialize()\r\n    public keysReset = [220];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the zoom in action.\r\n     * Only used when CameraMovement is active — these keys always trigger zoom regardless of modifiers.\r\n     */\r\n    @serialize()\r\n    public keysZoomIn: number[] = [187, 107]; // 187 = +/= key, 107 = numpad +\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the zoom out action.\r\n     * Only used when CameraMovement is active — these keys always trigger zoom regardless of modifiers.\r\n     */\r\n    @serialize()\r\n    public keysZoomOut: number[] = [189, 109]; // 189 = -/_ key, 109 = numpad -\r\n\r\n    /**\r\n     * Defines the panning sensibility of the inputs.\r\n     * (How fast is the camera panning)\r\n     */\r\n    @serialize()\r\n    public panningSensibility: number = 50.0;\r\n\r\n    /**\r\n     * Defines the zooming sensibility of the inputs.\r\n     * (How fast is the camera zooming)\r\n     */\r\n    @serialize()\r\n    public zoomingSensibility: number = 25.0;\r\n\r\n    /**\r\n     * Rotation speed of the camera\r\n     */\r\n    @serialize()\r\n    public angularSpeed = 0.01;\r\n\r\n    private _useAltToZoom: boolean = true;\r\n\r\n    /**\r\n     * Defines whether alt+arrows/wasd triggers zoom instead of rotation/pan.\r\n     * When disabled, alt+keyboard events are ignored by the zoom inputMap entry.\r\n     * Setting this updates the corresponding inputMap entry on the camera's movement system.\r\n     * If set before the camera is attached, the value is cached and applied during `attachControl`.\r\n     */\r\n    @serialize()\r\n    public get useAltToZoom(): boolean {\r\n        return this._useAltToZoom;\r\n    }\r\n\r\n    public set useAltToZoom(value: boolean) {\r\n        this._useAltToZoom = value;\r\n        this._applyUseAltToZoomToInputMap();\r\n    }\r\n\r\n    /**\r\n     * Applies the cached `_useAltToZoom` value to the camera's inputMap.\r\n     * Safe to call before the camera is attached: it is a no-op until `this.camera.movement` is available.\r\n     * Idempotent — calling it when the inputMap already matches the cached value is a no-op.\r\n     */\r\n    private _applyUseAltToZoomToInputMap(): void {\r\n        if (!this.camera?.movement) {\r\n            return;\r\n        }\r\n        const input = this.camera.movement.input;\r\n        const entry = input.getEntry(\"keyboard\", \"zoom\", { modifiers: { alt: true } });\r\n        if (!this._useAltToZoom && entry) {\r\n            input.inputMap.splice(input.inputMap.indexOf(entry), 1);\r\n        } else if (this._useAltToZoom && !entry) {\r\n            input.addEntry({ source: \"keyboard\", modifiers: { alt: true }, interaction: \"zoom\" });\r\n        }\r\n    }\r\n\r\n    private _keys = new Array<number>();\r\n    private _ctrlPressed: boolean;\r\n    private _altPressed: boolean;\r\n    private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n    private _engine: AbstractEngine;\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Modifier state stored separately from `_keyboardConditions` so it can be typed as a\r\n     * concrete (non-optional) object. This avoids non-null assertions when updating modifier\r\n     * fields each frame, and the conditions object holds the same reference so\r\n     * resolveInteraction sees the live state.\r\n     */\r\n    private _keyboardModifiers: { ctrl: boolean; alt: boolean } = { ctrl: false, alt: false };\r\n\r\n    /** Cached conditions object to avoid per-frame allocations in checkInputs */\r\n    private _keyboardConditions: KeyboardConditions = { modifiers: this._keyboardModifiers };\r\n\r\n    /** Reused accumulators for the per-frame keyboard rotate/pan directions, to avoid per-frame allocations */\r\n    private _rotateDirection = new Vector2();\r\n    private _panDirection = new Vector2();\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        // was there a second variable defined?\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n\r\n        if (this._onCanvasBlurObserver) {\r\n            return;\r\n        }\r\n\r\n        this._scene = this.camera.getScene();\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._applyUseAltToZoomToInputMap();\r\n\r\n        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n            this._keys.length = 0;\r\n        });\r\n\r\n        this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n            const evt = info.event;\r\n            if (!evt.metaKey) {\r\n                if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n                    this._ctrlPressed = evt.ctrlKey;\r\n                    this._altPressed = evt.altKey;\r\n\r\n                    if (\r\n                        this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysReset.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index === -1) {\r\n                            this._keys.push(evt.keyCode);\r\n                        }\r\n\r\n                        if (evt.preventDefault) {\r\n                            if (!noPreventDefault) {\r\n                                evt.preventDefault();\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (\r\n                        this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysReset.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index >= 0) {\r\n                            this._keys.splice(index, 1);\r\n                        }\r\n\r\n                        if (evt.preventDefault) {\r\n                            if (!noPreventDefault) {\r\n                                evt.preventDefault();\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._scene) {\r\n            if (this._onKeyboardObserver) {\r\n                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n            }\r\n            if (this._onCanvasBlurObserver) {\r\n                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n            }\r\n            this._onKeyboardObserver = null;\r\n            this._onCanvasBlurObserver = null;\r\n        }\r\n\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._onKeyboardObserver) {\r\n            const camera = this.camera;\r\n            const input = camera.movement.input;\r\n\r\n            this._keyboardModifiers.ctrl = this._ctrlPressed;\r\n            this._keyboardModifiers.alt = this._altPressed;\r\n\r\n            // Rotate and pan directions are accumulated across keys and applied once below (normalized), so\r\n            // holding two directions at once (e.g. up + left) moves along a normalized diagonal at the same\r\n            // speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from applying\r\n            // each key independently. Zoom is one-dimensional and is applied per key.\r\n            const rotateDirection = this._rotateDirection.set(0, 0);\r\n            const panDirection = this._panDirection.set(0, 0);\r\n            let rotateSensitivity = 0;\r\n            let panSensitivity = 0;\r\n\r\n            for (let index = 0; index < this._keys.length; index++) {\r\n                const keyCode = this._keys[index];\r\n\r\n                this._keyboardConditions.key = keyCode;\r\n\r\n                // Skip resolveInteraction for the reset key — it has no inputMap entry of its own\r\n                // and would otherwise spuriously match the catch-all keyboard→rotate entry.\r\n                if (this.keysReset.indexOf(keyCode) === -1) {\r\n                    const resolved = input.resolveInteraction(\"keyboard\", this._keyboardConditions);\r\n\r\n                    if (resolved) {\r\n                        // Per-frame impulse magnitude. The inputMap entry's `sensitivity` takes precedence\r\n                        // when set so consumers can tune feel declaratively (and so we can phase out the\r\n                        // legacy sensibility/angularSpeed properties over time). When `sensitivity` is\r\n                        // undefined, fall back to the legacy properties for backward compatibility.\r\n                        if (resolved.interaction === \"pan\") {\r\n                            // Accumulate a unit direction per pan key; the combined vector is normalized after the loop.\r\n                            // Aggregate sensitivity with max so the pan speed is independent of key insertion order\r\n                            // when keys resolve to different per-key sensitivities.\r\n                            panSensitivity = Math.max(panSensitivity, resolved.sensitivity ?? 1 / this.panningSensibility);\r\n                            if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n                                panDirection.x -= 1;\r\n                            } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n                                panDirection.x += 1;\r\n                            } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n                                panDirection.y += 1;\r\n                            } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n                                panDirection.y -= 1;\r\n                            }\r\n                        } else if (resolved.interaction === \"zoom\") {\r\n                            const zoomSens = resolved.sensitivity ?? 1 / this.zoomingSensibility;\r\n                            if (this.keysUp.indexOf(keyCode) !== -1 || this.keysZoomIn.indexOf(keyCode) !== -1) {\r\n                                input.handlers.zoom(zoomSens);\r\n                            } else if (this.keysDown.indexOf(keyCode) !== -1 || this.keysZoomOut.indexOf(keyCode) !== -1) {\r\n                                input.handlers.zoom(-zoomSens);\r\n                            }\r\n                        } else if (resolved.interaction === \"rotate\") {\r\n                            // Accumulate a unit direction per rotate key; the combined vector is normalized after the loop.\r\n                            // Aggregate sensitivity with max so the rotate speed is independent of key insertion order\r\n                            // when keys resolve to different per-key sensitivities.\r\n                            rotateSensitivity = Math.max(rotateSensitivity, resolved.sensitivity ?? this.angularSpeed);\r\n                            if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n                                rotateDirection.x -= 1;\r\n                            } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n                                rotateDirection.x += 1;\r\n                            } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n                                rotateDirection.y -= 1;\r\n                            } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n                                rotateDirection.y += 1;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this.keysReset.indexOf(keyCode) !== -1) {\r\n                    if (camera.useInputToRestoreState) {\r\n                        camera.restoreState();\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Apply the accumulated rotate/pan once, normalized so a diagonal isn't faster than an axis-aligned move.\r\n            if (rotateDirection.x !== 0 || rotateDirection.y !== 0) {\r\n                rotateDirection.normalize().scaleInPlace(rotateSensitivity);\r\n                input.handlers.rotate(rotateDirection.x, rotateDirection.y);\r\n            }\r\n            if (panDirection.x !== 0 || panDirection.y !== 0) {\r\n                panDirection.normalize().scaleInPlace(panSensitivity);\r\n                input.handlers.pan(panDirection.x, panDirection.y);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ArcRotateCameraKeyboardMoveInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"keyboard\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"ArcRotateCameraKeyboardMoveInput\"] = ArcRotateCameraKeyboardMoveInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type EventState, type Observer } from \"../../Misc/observable\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { Plane } from \"../../Maths/math.plane\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { Epsilon } from \"../../Maths/math.constants\";\r\nimport { type IWheelEvent, EventConstants } from \"../../Events/deviceInputEvents\";\r\nimport { Clamp } from \"../../Maths/math.scalar.functions\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\n\r\n/**\r\n * Firefox uses a different scheme to report scroll distances to other\r\n * browsers. Rather than use complicated methods to calculate the exact\r\n * multiple we need to apply, let's just cheat and use a constant.\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode\r\n * https://stackoverflow.com/questions/20110224/what-is-the-height-of-a-line-in-a-wheel-event-deltamode-dom-delta-line\r\n */\r\nconst FfMultiplier = 40;\r\n\r\n/**\r\n * Manage the mouse wheel inputs to control an arc rotate camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraMouseWheelInput implements ICameraInput<ArcRotateCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: ArcRotateCamera;\r\n\r\n    /**\r\n     * Gets or Set the mouse wheel precision or how fast is the camera zooming.\r\n     */\r\n    @serialize()\r\n    public wheelPrecision = 3.0;\r\n\r\n    /**\r\n     * Gets or Set the boolean value that controls whether or not the mouse wheel\r\n     * zooms to the location of the mouse pointer or not.  The default is false.\r\n     */\r\n    @serialize()\r\n    public zoomToMouseLocation = false;\r\n\r\n    /**\r\n     * wheelDeltaPercentage will be used instead of wheelPrecision if different from 0.\r\n     * It defines the percentage of current camera.radius to use as delta when wheel is used.\r\n     */\r\n    @serialize()\r\n    public wheelDeltaPercentage = 0;\r\n\r\n    /**\r\n     * If set, this function will be used to set the radius delta that will be added to the current camera radius\r\n     */\r\n    public customComputeDeltaFromMouseWheel: Nullable<(wheelDelta: number, input: ArcRotateCameraMouseWheelInput, event: IWheelEvent) => number> = null;\r\n\r\n    private _wheel: Nullable<(p: PointerInfo, s: EventState) => void>;\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n    private _hitPlane: Nullable<Plane>;\r\n    private _viewOffset: Vector3 = new Vector3(0, 0, 0);\r\n    private _globalOffset: Vector3 = new Vector3(0, 0, 0);\r\n\r\n    protected _computeDeltaFromMouseWheelLegacyEvent(mouseWheelDelta: number, radius: number) {\r\n        let delta: number;\r\n        const wheelDelta = mouseWheelDelta * 0.01 * this.wheelDeltaPercentage * radius;\r\n        if (mouseWheelDelta > 0) {\r\n            delta = wheelDelta / (1.0 + this.wheelDeltaPercentage);\r\n        } else {\r\n            delta = wheelDelta * (1.0 + this.wheelDeltaPercentage);\r\n        }\r\n        return delta;\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        this._wheel = (p) => {\r\n            //sanity check - this should be a PointerWheel event.\r\n            if (p.type !== PointerEventTypes.POINTERWHEEL) {\r\n                return;\r\n            }\r\n            const event = <IWheelEvent>p.event;\r\n            let delta: number;\r\n            const platformScale = event.deltaMode === EventConstants.DOM_DELTA_LINE ? FfMultiplier : 1; // If this happens to be set to DOM_DELTA_LINE, adjust accordingly\r\n\r\n            const wheelDelta = -(event.deltaY * platformScale);\r\n\r\n            if (this.customComputeDeltaFromMouseWheel) {\r\n                delta = this.customComputeDeltaFromMouseWheel(wheelDelta, this, event);\r\n            } else {\r\n                if (this.wheelDeltaPercentage) {\r\n                    delta = this._computeDeltaFromMouseWheelLegacyEvent(wheelDelta, this.camera.radius);\r\n\r\n                    // If zooming in, estimate the target radius and use that to compute the delta for inertia\r\n                    // this will stop multiple scroll events zooming in from adding too much inertia\r\n                    if (delta > 0) {\r\n                        // When zoomToMouseLocation is active, the accumulating state lives in our private\r\n                        // `_zoomToMouseRadiusOffset` field. Otherwise fall back to the legacy surface.\r\n                        const currentAccumulated = this.zoomToMouseLocation ? this._zoomToMouseRadiusOffset : this.camera.inertialRadiusOffset;\r\n                        let estimatedTargetRadius = this.camera.radius;\r\n                        let targetInertia = currentAccumulated + delta;\r\n                        for (let i = 0; i < 20; i++) {\r\n                            // 20 iterations should be enough to converge\r\n                            if (estimatedTargetRadius <= targetInertia) {\r\n                                // We do not want a negative radius, so we break out of the loop\r\n                                break;\r\n                            }\r\n                            if (Math.abs(targetInertia * this.camera.inertia) < 0.001) {\r\n                                // We do not want to go below a certain threshold, so we break out of the loop\r\n                                break;\r\n                            }\r\n                            estimatedTargetRadius -= targetInertia;\r\n                            targetInertia *= this.camera.inertia;\r\n                        }\r\n                        estimatedTargetRadius = Clamp(estimatedTargetRadius, 0, Number.MAX_VALUE);\r\n                        delta = this._computeDeltaFromMouseWheelLegacyEvent(wheelDelta, estimatedTargetRadius);\r\n                    }\r\n                } else {\r\n                    // The inputMap entry's `sensitivity` takes precedence so consumers can tune\r\n                    // wheel zoom feel declaratively; fall back to the legacy `wheelPrecision`.\r\n                    const wheelEntry = this.camera.movement.input.getEntry(\"wheel\", \"zoom\");\r\n                    const wheelScale = wheelEntry?.sensitivity ?? 1 / (this.wheelPrecision * 40);\r\n                    delta = wheelDelta * wheelScale;\r\n                }\r\n            }\r\n\r\n            if (delta) {\r\n                if (this.zoomToMouseLocation) {\r\n                    // If we are zooming to the mouse location, then we need to get the hit plane at the start of the zoom gesture if it doesn't exist\r\n                    // The hit plane is normally calculated after the first motion and each time there's motion so if we don't do this first,\r\n                    // the first zoom will be to the center of the screen\r\n                    if (!this._hitPlane) {\r\n                        this._updateHitPlane();\r\n                    }\r\n\r\n                    this._zoomToMouse(delta);\r\n                } else {\r\n                    this.camera.movement.zoomAccumulatedPixels += delta;\r\n                }\r\n            }\r\n            if (event.preventDefault) {\r\n                if (!noPreventDefault) {\r\n                    event.preventDefault();\r\n                }\r\n            }\r\n        };\r\n\r\n        this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(this._wheel, PointerEventTypes.POINTERWHEEL);\r\n\r\n        if (this.zoomToMouseLocation) {\r\n            this._inertialPanning.setAll(0);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._observer) {\r\n            this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n            this._observer = null;\r\n            this._wheel = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (!this.zoomToMouseLocation) {\r\n            return;\r\n        }\r\n\r\n        const camera = this.camera;\r\n        // Motion check based on our private accumulator state + the legacy inertialRadiusOffset\r\n        // surface (so user code that still writes to it continues to animate). Legacy also\r\n        // included alpha/beta offsets in the motion check — keep that for compatibility so\r\n        // the hit plane stays updated while the camera rotates.\r\n        const motion =\r\n            Math.abs(this._zoomToMouseRadiusOffset) +\r\n            this._inertialPanning.lengthSquared() +\r\n            Math.abs(camera.inertialAlphaOffset) +\r\n            Math.abs(camera.inertialBetaOffset) +\r\n            Math.abs(camera.inertialRadiusOffset);\r\n        if (motion) {\r\n            // if zooming is still happening as a result of inertia, then we also need to update\r\n            // the hit plane.\r\n            this._updateHitPlane();\r\n\r\n            // Apply this frame's coupled radius + pan delta to the camera. They must stay\r\n            // in lockstep so the cursor remains at the zoom focal point — keep pan here instead\r\n            // of routing through `arcRotateCamera.inertialPanning` which uses a different\r\n            // `panningInertia`.\r\n            camera.target.addInPlace(this._inertialPanning);\r\n            camera.radius -= this._zoomToMouseRadiusOffset;\r\n\r\n            // Framerate-independent decay — matches legacy `* camera.inertia` exactly at 60fps\r\n            // and preserves glide duration at any other fps.\r\n            const decay = camera.movement.getFrameIndependentDecay(camera.inertia);\r\n            this._inertialPanning.scaleInPlace(decay);\r\n            this._zoomToMouseRadiusOffset *= decay;\r\n\r\n            this._zeroIfClose(this._inertialPanning);\r\n            if (Math.abs(this._zoomToMouseRadiusOffset) < Epsilon) {\r\n                this._zoomToMouseRadiusOffset = 0;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ArcRotateCameraMouseWheelInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"mousewheel\";\r\n    }\r\n\r\n    private _updateHitPlane() {\r\n        const camera = this.camera;\r\n        const direction = camera.target.subtract(camera.position);\r\n        this._hitPlane = Plane.FromPositionAndNormal(camera.target, direction);\r\n    }\r\n\r\n    // Get position on the hit plane\r\n    private _getPosition(): Vector3 {\r\n        const camera = this.camera;\r\n        const scene = camera.getScene();\r\n\r\n        // since the _hitPlane is always updated to be orthogonal to the camera position vector\r\n        // we don't have to worry about this ray shooting off to infinity. This ray creates\r\n        // a vector defining where we want to zoom to.\r\n        const ray = scene.createPickingRay(scene.pointerX, scene.pointerY, Matrix.Identity(), camera, false);\r\n        // Since the camera is the origin of the picking ray, we need to offset it by the camera's offset manually\r\n        // Because the offset is in view space, we need to convert it to world space first\r\n        if (camera.targetScreenOffset.x !== 0 || camera.targetScreenOffset.y !== 0) {\r\n            this._viewOffset.set(camera.targetScreenOffset.x, camera.targetScreenOffset.y, 0);\r\n            camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n            this._globalOffset = Vector3.TransformNormal(this._viewOffset, camera._cameraTransformMatrix);\r\n            ray.origin.addInPlace(this._globalOffset);\r\n        }\r\n\r\n        let distance = 0;\r\n        if (this._hitPlane) {\r\n            distance = ray.intersectsPlane(this._hitPlane) ?? 0;\r\n        }\r\n\r\n        // not using this ray again, so modifying its vectors here is fine\r\n        return ray.origin.addInPlace(ray.direction.scaleInPlace(distance));\r\n    }\r\n\r\n    private _inertialPanning: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Decaying accumulator for radius motion in the `zoomToMouseLocation` path.\r\n     *\r\n     * Units: world-space radius units. On each frame, this value is *subtracted* from\r\n     * `camera.radius` and then multiplied by a framerate-independent decay factor (via\r\n     * `CameraMovement.getFrameIndependentDecay`). New input from `_zoomToMouse(delta)`\r\n     * is added on top each frame, scaled by the matching framerate-independent input\r\n     * factor so the steady-state and total-glide-distance match legacy at 60fps at any\r\n     * actual refresh rate.\r\n     *\r\n     * Replaces the use of the legacy `camera.inertialRadiusOffset` for this code path\r\n     * so the coupled radius + pan motion can be decayed with framerate-independent\r\n     * semantics without disturbing the public `inertialRadiusOffset` back-compat surface.\r\n     */\r\n    private _zoomToMouseRadiusOffset: number = 0;\r\n\r\n    private _zoomToMouse(delta: number) {\r\n        const camera = this.camera;\r\n        const inertiaComp = 1 - camera.inertia;\r\n        // inputScale corrects per-frame input so that the decayed sum matches the legacy 60fps total\r\n        // at any actual framerate. At 60fps inputScale = 1 (no-op).\r\n        const inputScale = camera.movement.getFrameIndependentInputScale(camera.inertia);\r\n        if (camera.lowerRadiusLimit) {\r\n            const lowerLimit = camera.lowerRadiusLimit ?? 0;\r\n            if (camera.radius - (this._zoomToMouseRadiusOffset + delta * inputScale) / inertiaComp < lowerLimit) {\r\n                delta = ((camera.radius - lowerLimit) * inertiaComp - this._zoomToMouseRadiusOffset) / inputScale;\r\n            }\r\n        }\r\n        if (camera.upperRadiusLimit) {\r\n            const upperLimit = camera.upperRadiusLimit ?? 0;\r\n            if (camera.radius - (this._zoomToMouseRadiusOffset + delta * inputScale) / inertiaComp > upperLimit) {\r\n                delta = ((camera.radius - upperLimit) * inertiaComp - this._zoomToMouseRadiusOffset) / inputScale;\r\n            }\r\n        }\r\n\r\n        const zoomDistance = delta / inertiaComp;\r\n        const ratio = zoomDistance / camera.radius;\r\n        const vec = this._getPosition();\r\n\r\n        // Now this vector tells us how much we also need to pan the camera\r\n        // so the targeted mouse location becomes the center of zooming.\r\n\r\n        const directionToZoomLocation = TmpVectors.Vector3[6];\r\n        vec.subtractToRef(camera.target, directionToZoomLocation);\r\n        directionToZoomLocation.scaleInPlace(ratio);\r\n        directionToZoomLocation.scaleInPlace(inertiaComp);\r\n\r\n        directionToZoomLocation.scaleInPlace(inputScale);\r\n        this._inertialPanning.addInPlace(directionToZoomLocation);\r\n\r\n        this._zoomToMouseRadiusOffset += delta * inputScale;\r\n    }\r\n\r\n    // Sets x y or z of passed in vector to zero if less than Epsilon.\r\n    private _zeroIfClose(vec: Vector3) {\r\n        if (Math.abs(vec.x) < Epsilon) {\r\n            vec.x = 0;\r\n        }\r\n        if (Math.abs(vec.y) < Epsilon) {\r\n            vec.y = 0;\r\n        }\r\n        if (Math.abs(vec.z) < Epsilon) {\r\n            vec.z = 0;\r\n        }\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"ArcRotateCameraMouseWheelInput\"] = ArcRotateCameraMouseWheelInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type PointerTouch } from \"../../Events/pointerEvents\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { BaseCameraPointersInput } from \"./BaseCameraPointersInput\";\r\n\r\n/**\r\n * Used by both arcrotatecamera and geospatialcamera, OrbitCameraPointersInputs handle pinchToZoom and multiTouchPanning\r\n * as though you are orbiting around a target point\r\n */\r\nexport abstract class OrbitCameraPointersInput extends BaseCameraPointersInput {\r\n    /**\r\n     * Defines whether zoom (2 fingers pinch) is enabled through multitouch\r\n     */\r\n    @serialize()\r\n    public pinchZoom: boolean = true;\r\n\r\n    /**\r\n     * Defines whether panning (2 fingers swipe) is enabled through multitouch.\r\n     */\r\n    @serialize()\r\n    public multiTouchPanning: boolean = true;\r\n\r\n    /**\r\n     * Defines whether panning is enabled for both pan (2 fingers swipe) and\r\n     * zoom (pinch) through multitouch.\r\n     */\r\n    @serialize()\r\n    public multiTouchPanAndZoom: boolean = true;\r\n\r\n    protected _isPinching: boolean = false;\r\n    protected _twoFingerActivityCount: number = 0;\r\n    protected _shouldStartPinchZoom: boolean = false;\r\n\r\n    protected _computePinchZoom(_previousPinchSquaredDistance: number, _pinchSquaredDistance: number): void {}\r\n\r\n    protected _computeMultiTouchPanning(_previousMultiTouchPanPosition: Nullable<PointerTouch>, _multiTouchPanPosition: Nullable<PointerTouch>): void {}\r\n\r\n    /**\r\n     * Called on pointer POINTERMOVE event if multiple touches are active.\r\n     * Override this method to provide functionality.\r\n     * @param _pointA First point in the pair\r\n     * @param _pointB Second point in the pair\r\n     * @param previousPinchSquaredDistance Sqr Distance between the points the last time this event was fired (by this input)\r\n     * @param pinchSquaredDistance Sqr Distance between the points this time\r\n     * @param previousMultiTouchPanPosition Previous center point between the points\r\n     * @param multiTouchPanPosition Current center point between the points\r\n     */\r\n    public override onMultiTouch(\r\n        _pointA: Nullable<PointerTouch>,\r\n        _pointB: Nullable<PointerTouch>,\r\n        previousPinchSquaredDistance: number,\r\n        pinchSquaredDistance: number,\r\n        previousMultiTouchPanPosition: Nullable<PointerTouch>,\r\n        multiTouchPanPosition: Nullable<PointerTouch>\r\n    ): void {\r\n        if (previousPinchSquaredDistance === 0 && previousMultiTouchPanPosition === null) {\r\n            // First time this method is called for new pinch.\r\n            // Next time this is called there will be a\r\n            // previousPinchSquaredDistance and pinchSquaredDistance to compare.\r\n            return;\r\n        }\r\n        if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {\r\n            // Last time this method is called at the end of a pinch.\r\n            return;\r\n        }\r\n\r\n        // Zoom and panning enabled together\r\n        if (this.multiTouchPanAndZoom) {\r\n            this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);\r\n            this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);\r\n\r\n            // Zoom and panning enabled but only one at a time\r\n        } else if (this.multiTouchPanning && this.pinchZoom) {\r\n            this._twoFingerActivityCount++;\r\n\r\n            if (this._isPinching || this._shouldStartPinchZoom) {\r\n                // Since pinch has not been active long, assume we intend to zoom.\r\n                this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);\r\n\r\n                // Since we are pinching, remain pinching on next iteration.\r\n                this._isPinching = true;\r\n            } else {\r\n                // Pause between pinch starting and moving implies not a zoom event. Pan instead.\r\n                this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);\r\n            }\r\n\r\n            // Panning enabled, zoom disabled\r\n        } else if (this.multiTouchPanning) {\r\n            this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);\r\n\r\n            // Zoom enabled, panning disabled\r\n        } else if (this.pinchZoom) {\r\n            this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called each time a new POINTERUP event occurs. Ie, for each button\r\n     * release.\r\n     * @param _evt Defines the event to track\r\n     */\r\n    public override onButtonUp(_evt: IPointerEvent): void {\r\n        this._twoFingerActivityCount = 0;\r\n        this._isPinching = false;\r\n    }\r\n\r\n    /**\r\n     * Called when window becomes inactive.\r\n     */\r\n    public override onLostFocus(): void {\r\n        this._twoFingerActivityCount = 0;\r\n        this._isPinching = false;\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { OrbitCameraPointersInput } from \"../../Cameras/Inputs/orbitCameraPointersInput\";\r\nimport { type PointerTouch } from \"../../Events/pointerEvents\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { type PointerConditions, type PointerInputMapEntry } from \"../inputMapper\";\r\n\r\n/**\r\n * Manage the pointers inputs to control an arc rotate camera.\r\n * Uses the inputMap on the movement class to determine which button maps to which interaction.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraPointersInput extends OrbitCameraPointersInput {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: ArcRotateCamera;\r\n\r\n    /**\r\n     * The minimum radius used for pinch, to avoid radius lock at 0\r\n     */\r\n    public static MinimumRadiusForPinch: number = 0.001;\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ArcRotateCameraPointersInput\";\r\n    }\r\n\r\n    /**\r\n     * Defines the buttons associated with the input to handle camera move.\r\n     */\r\n    @serialize()\r\n    public override buttons = [0, 1, 2];\r\n\r\n    /**\r\n     * Defines the pointer angular sensibility  along the X axis or how fast is\r\n     * the camera rotating.\r\n     */\r\n    @serialize()\r\n    public angularSensibilityX = 1000.0;\r\n\r\n    /**\r\n     * Defines the pointer angular sensibility along the Y axis or how fast is\r\n     * the camera rotating.\r\n     */\r\n    @serialize()\r\n    public angularSensibilityY = 1000.0;\r\n\r\n    /**\r\n     * Defines the pointer pinch precision or how fast is the camera zooming.\r\n     */\r\n    @serialize()\r\n    public pinchPrecision = 12.0;\r\n\r\n    /**\r\n     * pinchDeltaPercentage will be used instead of pinchPrecision if different\r\n     * from 0.\r\n     * It defines the percentage of current camera.radius to use as delta when\r\n     * pinch zoom is used.\r\n     */\r\n    @serialize()\r\n    public pinchDeltaPercentage = 0;\r\n\r\n    /**\r\n     * When useNaturalPinchZoom is true, multi touch zoom will zoom in such\r\n     * that any object in the plane at the camera's target point will scale\r\n     * perfectly with finger motion.\r\n     * Overrides pinchDeltaPercentage and pinchPrecision.\r\n     */\r\n    @serialize()\r\n    public useNaturalPinchZoom: boolean = false;\r\n\r\n    /**\r\n     * Defines the pointer panning sensibility or how fast is the camera moving.\r\n     */\r\n    @serialize()\r\n    public panningSensibility: number = 1000.0;\r\n\r\n    /**\r\n     * Revers pinch action direction.\r\n     */\r\n    public pinchInwards = true;\r\n\r\n    /** Cached resolved inputMap entry for the current pointer gesture */\r\n    private _activeEntry: Nullable<PointerInputMapEntry> = null;\r\n\r\n    /** Cached conditions object for pointer-lock fallback resolution to avoid per-event allocations */\r\n    private _pointerLockConditions: PointerConditions = { button: 0, modifiers: {} };\r\n\r\n    /**\r\n     * Modifier state stored separately from `_pointerConditions` so it can be typed as a\r\n     * concrete (non-optional) object. This avoids non-null assertions when updating modifier\r\n     * fields on every pointer-down, and the conditions object holds the same reference so\r\n     * resolveInteraction sees the live state.\r\n     */\r\n    private _pointerModifiers: { ctrl: boolean; alt: boolean; shift: boolean } = { ctrl: false, alt: false, shift: false };\r\n\r\n    /** Cached conditions object for pointer-down resolution */\r\n    private _pointerConditions: PointerConditions = { modifiers: this._pointerModifiers };\r\n\r\n    /**\r\n     * Move camera from multi touch panning positions.\r\n     * @param previousMultiTouchPanPosition\r\n     * @param multiTouchPanPosition\r\n     */\r\n    protected override _computeMultiTouchPanning(previousMultiTouchPanPosition: Nullable<PointerTouch>, multiTouchPanPosition: Nullable<PointerTouch>): void {\r\n        if (previousMultiTouchPanPosition && multiTouchPanPosition) {\r\n            const moveDeltaX = multiTouchPanPosition.x - previousMultiTouchPanPosition.x;\r\n            const moveDeltaY = multiTouchPanPosition.y - previousMultiTouchPanPosition.y;\r\n            // Multi-touch pan is a gesture (no button), so consult the default pointer→pan entry for an\r\n            // explicit `sensitivity` override. When unset, fall back to the legacy `panningSensibility`\r\n            // (treating panningSensibility=0 as \"panning disabled\" for backward compatibility).\r\n            const panEntry = this.camera.movement.input.getEntry(\"pointer\", \"pan\");\r\n            const panScale = panEntry?.sensitivity ?? (this.panningSensibility !== 0 ? 1 / this.panningSensibility : 0);\r\n            if (panScale !== 0) {\r\n                this.camera.movement.activeInput = true;\r\n                this.camera.movement.panAccumulatedPixels.x += -moveDeltaX * panScale;\r\n                this.camera.movement.panAccumulatedPixels.y += moveDeltaY * panScale;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Move camera from multitouch (pinch) zoom distances.\r\n     * @param previousPinchSquaredDistance\r\n     * @param pinchSquaredDistance\r\n     */\r\n    protected override _computePinchZoom(previousPinchSquaredDistance: number, pinchSquaredDistance: number): void {\r\n        const radius = this.camera.radius || ArcRotateCameraPointersInput.MinimumRadiusForPinch;\r\n        if (this.useNaturalPinchZoom) {\r\n            this.camera.radius = (radius * Math.sqrt(previousPinchSquaredDistance)) / Math.sqrt(pinchSquaredDistance);\r\n        } else if (this.pinchDeltaPercentage) {\r\n            const delta = (pinchSquaredDistance - previousPinchSquaredDistance) * 0.001 * radius * this.pinchDeltaPercentage;\r\n            this.camera.movement.activeInput = true;\r\n            this.camera.movement.zoomAccumulatedPixels += delta;\r\n        } else {\r\n            const delta =\r\n                (pinchSquaredDistance - previousPinchSquaredDistance) /\r\n                ((this.pinchPrecision * (this.pinchInwards ? 1 : -1) * (this.angularSensibilityX + this.angularSensibilityY)) / 2);\r\n            this.camera.movement.activeInput = true;\r\n            this.camera.movement.zoomAccumulatedPixels += delta;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on pointer POINTERMOVE event if only a single touch is active.\r\n     * @param point current touch point\r\n     * @param offsetX offset on X\r\n     * @param offsetY offset on Y\r\n     */\r\n    public override onTouch(point: Nullable<PointerTouch>, offsetX: number, offsetY: number): void {\r\n        // In pointer-lock mode, mouse movement rotates the camera even without a button held.\r\n        // This matches legacy behavior where pointer-lock mouse deltas always drove rotation.\r\n        const entry = this._activeEntry ?? (this.camera.getEngine().isPointerLock ? this.camera.movement.input.resolveInteraction(\"pointer\", this._pointerLockConditions) : null);\r\n        if (entry) {\r\n            // Per-pixel scale. The inputMap entry's `sensitivity` takes precedence so consumers can\r\n            // tune feel declaratively (and so we can phase out the legacy sensibility properties).\r\n            // When `sensitivity` is unset, fall back to the legacy properties for backward compat.\r\n            // For rotate, a single `sensitivity` value applies to both axes; the legacy fallback\r\n            // preserves separate X/Y tuning via `angularSensibilityX/Y`.\r\n            if (entry.interaction === \"pan\") {\r\n                const panScale = entry.sensitivity ?? (this.panningSensibility !== 0 ? 1 / this.panningSensibility : 0);\r\n                if (panScale !== 0) {\r\n                    this.camera.movement.activeInput = true;\r\n                    this.camera.movement.panAccumulatedPixels.x += -offsetX * panScale;\r\n                    this.camera.movement.panAccumulatedPixels.y += offsetY * panScale;\r\n                }\r\n            } else if (entry.interaction === \"rotate\") {\r\n                const rotateScaleX = entry.sensitivityX ?? entry.sensitivity ?? 1 / this.angularSensibilityX;\r\n                const rotateScaleY = entry.sensitivityY ?? entry.sensitivity ?? 1 / this.angularSensibilityY;\r\n                this.camera.movement.activeInput = true;\r\n                this.camera.movement.rotationAccumulatedPixels.x += -offsetX * rotateScaleX;\r\n                this.camera.movement.rotationAccumulatedPixels.y += -offsetY * rotateScaleY;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on pointer POINTERDOUBLETAP event.\r\n     */\r\n    public override onDoubleTap() {\r\n        if (this.camera.useInputToRestoreState) {\r\n            this.camera.restoreState();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on pointer POINTERMOVE event if multiple touches are active.\r\n     * @param pointA point A\r\n     * @param pointB point B\r\n     * @param previousPinchSquaredDistance distance between points in previous pinch\r\n     * @param pinchSquaredDistance distance between points in current pinch\r\n     * @param previousMultiTouchPanPosition multi-touch position in previous step\r\n     * @param multiTouchPanPosition multi-touch position in current step\r\n     */\r\n    public override onMultiTouch(\r\n        pointA: Nullable<PointerTouch>,\r\n        pointB: Nullable<PointerTouch>,\r\n        previousPinchSquaredDistance: number,\r\n        pinchSquaredDistance: number,\r\n        previousMultiTouchPanPosition: Nullable<PointerTouch>,\r\n        multiTouchPanPosition: Nullable<PointerTouch>\r\n    ): void {\r\n        this._shouldStartPinchZoom =\r\n            this._twoFingerActivityCount < 20 && Math.abs(Math.sqrt(pinchSquaredDistance) - Math.sqrt(previousPinchSquaredDistance)) > this.camera.pinchToPanMaxDistance;\r\n        super.onMultiTouch(pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition);\r\n    }\r\n\r\n    /**\r\n     * Called each time a new POINTERDOWN event occurs. Ie, for each button\r\n     * press.\r\n     * @param evt Defines the event to track\r\n     */\r\n    public override onButtonDown(evt: IPointerEvent): void {\r\n        this._pointerConditions.button = evt.button;\r\n        this._pointerModifiers.ctrl = evt.ctrlKey;\r\n        this._pointerModifiers.alt = evt.altKey;\r\n        this._pointerModifiers.shift = evt.shiftKey;\r\n        this._activeEntry = this.camera.movement.input.resolveInteraction(\"pointer\", this._pointerConditions);\r\n        super.onButtonDown(evt);\r\n    }\r\n\r\n    /**\r\n     * Called each time a new POINTERUP event occurs. Ie, for each button\r\n     * release.\r\n     * @param _evt Defines the event to track\r\n     */\r\n    public override onButtonUp(_evt: IPointerEvent): void {\r\n        this._activeEntry = null;\r\n        super.onButtonUp(_evt);\r\n    }\r\n\r\n    /**\r\n     * Called when window becomes inactive.\r\n     */\r\n    public override onLostFocus(): void {\r\n        this._activeEntry = null;\r\n        super.onLostFocus();\r\n    }\r\n}\r\n(<any>CameraInputTypes)[\"ArcRotateCameraPointersInput\"] = ArcRotateCameraPointersInput;\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ArcRotateCamera } from \"./arcRotateCamera.pure\";\r\nimport { ArcRotateCameraPointersInput } from \"../Cameras/Inputs/arcRotateCameraPointersInput\";\r\nimport { ArcRotateCameraKeyboardMoveInput } from \"../Cameras/Inputs/arcRotateCameraKeyboardMoveInput\";\r\nimport { ArcRotateCameraMouseWheelInput } from \"../Cameras/Inputs/arcRotateCameraMouseWheelInput\";\r\nimport { CameraInputsManager } from \"../Cameras/cameraInputsManager\";\r\n\r\n/**\r\n * Default Inputs manager for the ArcRotateCamera.\r\n * It groups all the default supported inputs for ease of use.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraInputsManager extends CameraInputsManager<ArcRotateCamera> {\r\n    /**\r\n     * Instantiates a new ArcRotateCameraInputsManager.\r\n     * @param camera Defines the camera the inputs belong to\r\n     */\r\n    constructor(camera: ArcRotateCamera) {\r\n        super(camera);\r\n    }\r\n\r\n    /**\r\n     * Add mouse wheel input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addMouseWheel(): ArcRotateCameraInputsManager {\r\n        this.add(new ArcRotateCameraMouseWheelInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add pointers input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addPointers(): ArcRotateCameraInputsManager {\r\n        this.add(new ArcRotateCameraPointersInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add keyboard input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addKeyboard(): ArcRotateCameraInputsManager {\r\n        this.add(new ArcRotateCameraKeyboardMoveInput());\r\n        return this;\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffect } from \"../Misc/devTools\";\r\n\r\nArcRotateCameraInputsManager.prototype.addVRDeviceOrientation ??= _MissingSideEffect(\"ArcRotateCameraInputsManager\", \"addVRDeviceOrientation\") as any;\r\nArcRotateCameraInputsManager.prototype.addGamepad ??= _MissingSideEffect(\"ArcRotateCameraInputsManager\", \"addGamepad\") as any;\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ArcRotateCamera } from \"../../Cameras/arcRotateCamera.pure\";\r\nimport { CameraInputTypes, type ICameraInput } from \"../../Cameras/cameraInputsManager\";\r\n\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { ArcRotateCameraInputsManager } from \"../../Cameras/arcRotateCameraInputsManager.pure\";\r\n\r\n/**\r\n * Manage the device orientation inputs (gyroscope) to control an arc rotate camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraVRDeviceOrientationInput implements ICameraInput<ArcRotateCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: ArcRotateCamera;\r\n\r\n    /**\r\n     * Defines a correction factor applied on the alpha value retrieved from the orientation events.\r\n     */\r\n    public alphaCorrection = 1;\r\n\r\n    /**\r\n     * Defines a correction factor applied on the gamma value retrieved from the orientation events.\r\n     */\r\n    public gammaCorrection = 1;\r\n\r\n    private _alpha = 0;\r\n    private _gamma = 0;\r\n    private _dirty = false;\r\n\r\n    private _deviceOrientationHandler: (evt: DeviceOrientationEvent) => void;\r\n\r\n    /**\r\n     * Instantiate a new ArcRotateCameraVRDeviceOrientationInput.\r\n     */\r\n    constructor() {\r\n        this._deviceOrientationHandler = (evt: DeviceOrientationEvent) => this._onOrientationEvent(evt);\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n\r\n        this.camera.attachControl(noPreventDefault);\r\n\r\n        const hostWindow = this.camera.getScene().getEngine().getHostWindow();\r\n\r\n        if (hostWindow) {\r\n            // check iOS 13+ support\r\n            if (typeof DeviceOrientationEvent !== \"undefined\" && typeof (<any>DeviceOrientationEvent).requestPermission === \"function\") {\r\n                (<any>DeviceOrientationEvent)\r\n                    .requestPermission()\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((response: string) => {\r\n                        if (response === \"granted\") {\r\n                            hostWindow.addEventListener(\"deviceorientation\", this._deviceOrientationHandler);\r\n                        } else {\r\n                            Logger.Warn(\"Permission not granted.\");\r\n                        }\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((error: any) => {\r\n                        Logger.Error(error);\r\n                    });\r\n            } else {\r\n                hostWindow.addEventListener(\"deviceorientation\", this._deviceOrientationHandler);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _onOrientationEvent(evt: DeviceOrientationEvent): void {\r\n        if (evt.alpha !== null) {\r\n            this._alpha = (+evt.alpha | 0) * this.alphaCorrection;\r\n        }\r\n\r\n        if (evt.gamma !== null) {\r\n            this._gamma = (+evt.gamma | 0) * this.gammaCorrection;\r\n        }\r\n        this._dirty = true;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._dirty) {\r\n            this._dirty = false;\r\n\r\n            if (this._gamma < 0) {\r\n                this._gamma = 180 + this._gamma;\r\n            }\r\n\r\n            this.camera.alpha = (((-this._alpha / 180.0) * Math.PI) % Math.PI) * 2;\r\n            this.camera.beta = (this._gamma / 180.0) * Math.PI;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        window.removeEventListener(\"deviceorientation\", this._deviceOrientationHandler);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ArcRotateCameraVRDeviceOrientationInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"VRDeviceOrientation\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"ArcRotateCameraVRDeviceOrientationInput\"] = ArcRotateCameraVRDeviceOrientationInput;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for arcRotateCameraVRDeviceOrientationInput.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterArcRotateCameraVRDeviceOrientationInput(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Add orientation input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    ArcRotateCameraInputsManager.prototype.addVRDeviceOrientation = function (): ArcRotateCameraInputsManager {\r\n        this.add(new ArcRotateCameraVRDeviceOrientationInput());\r\n        return this;\r\n    };\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FlyCamera } from \"../../Cameras/flyCamera\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\n/**\r\n * Listen to keyboard events to control the camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FlyCameraKeyboardInput implements ICameraInput<FlyCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FlyCamera;\r\n\r\n    /**\r\n     * The list of keyboard keys used to control the forward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysForward = [87];\r\n\r\n    /**\r\n     * The list of keyboard keys used to control the backward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysBackward = [83];\r\n\r\n    /**\r\n     * The list of keyboard keys used to control the forward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysUp = [69];\r\n\r\n    /**\r\n     * The list of keyboard keys used to control the backward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysDown = [81];\r\n\r\n    /**\r\n     * The list of keyboard keys used to control the right strafe move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysRight = [68];\r\n\r\n    /**\r\n     * The list of keyboard keys used to control the left strafe move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysLeft = [65];\r\n\r\n    private _keys = new Array<number>();\r\n    private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n    private _engine: AbstractEngine;\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        if (this._onCanvasBlurObserver) {\r\n            return;\r\n        }\r\n\r\n        this._scene = this.camera.getScene();\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n            this._keys.length = 0;\r\n        });\r\n\r\n        this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n            const evt = info.event;\r\n\r\n            if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n                if (\r\n                    this.keysForward.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysBackward.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysRight.indexOf(evt.keyCode) !== -1\r\n                ) {\r\n                    const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                    if (index === -1) {\r\n                        this._keys.push(evt.keyCode);\r\n                    }\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                    }\r\n                }\r\n            } else {\r\n                if (\r\n                    this.keysForward.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysBackward.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                    this.keysRight.indexOf(evt.keyCode) !== -1\r\n                ) {\r\n                    const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                    if (index >= 0) {\r\n                        this._keys.splice(index, 1);\r\n                    }\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._scene) {\r\n            if (this._onKeyboardObserver) {\r\n                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n            }\r\n\r\n            if (this._onCanvasBlurObserver) {\r\n                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n            }\r\n            this._onKeyboardObserver = null;\r\n            this._onCanvasBlurObserver = null;\r\n        }\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FlyCameraKeyboardInput\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _onLostFocus(): void {\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"keyboard\";\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._onKeyboardObserver) {\r\n            const camera = this.camera;\r\n            // All fly-keyboard keys move the camera, so they are gated on the keyboard→translate\r\n            // mapping. Removing that entry disables keyboard movement; an entry `sensitivity`\r\n            // acts as a gain (default 1) over the legacy local-camera speed.\r\n            const translateEntry = camera.movement.input.getEntry(\"keyboard\", \"translate\");\r\n            if (!translateEntry) {\r\n                return;\r\n            }\r\n            const translateGain = translateEntry.sensitivity ?? 1;\r\n\r\n            // Movement keys are accumulated into a single local direction and applied once below, so that\r\n            // holding two directions at once (e.g. forward + left) moves along a normalized diagonal at the\r\n            // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from\r\n            // applying each movement key independently.\r\n            const localDirection = camera._localDirection.copyFromFloats(0, 0, 0);\r\n\r\n            // Keyboard\r\n            for (let index = 0; index < this._keys.length; index++) {\r\n                const keyCode = this._keys[index];\r\n\r\n                if (this.keysForward.indexOf(keyCode) !== -1) {\r\n                    localDirection.z += 1;\r\n                } else if (this.keysBackward.indexOf(keyCode) !== -1) {\r\n                    localDirection.z -= 1;\r\n                } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n                    localDirection.y += 1;\r\n                } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n                    localDirection.y -= 1;\r\n                } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n                    localDirection.x += 1;\r\n                } else if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n                    localDirection.x -= 1;\r\n                }\r\n            }\r\n\r\n            // Apply a single, normalized movement once all keys for this frame have been accumulated.\r\n            if (localDirection.x !== 0 || localDirection.y !== 0 || localDirection.z !== 0) {\r\n                const speed = camera._computeLocalCameraSpeed() * translateGain;\r\n                // Normalize so a diagonal isn't faster than an axis-aligned move, then scale to the per-frame speed.\r\n                localDirection.normalize().scaleInPlace(speed);\r\n\r\n                if (camera.getScene().useRightHandedSystem) {\r\n                    localDirection.z *= -1;\r\n                }\r\n\r\n                camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n                Vector3.TransformNormalToRef(localDirection, camera._cameraTransformMatrix, camera._transformedDirection);\r\n                camera.cameraDirection.addInPlace(camera._transformedDirection);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FlyCameraKeyboardInput\"] = FlyCameraKeyboardInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FlyCamera } from \"../../Cameras/flyCamera\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { type InputConditions } from \"../inputMapper\";\r\n/**\r\n * Listen to mouse events to control the camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FlyCameraMouseInput implements ICameraInput<FlyCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FlyCamera;\r\n\r\n    /**\r\n     * Defines if touch is enabled. (Default is true.)\r\n     */\r\n    public touchEnabled: boolean;\r\n\r\n    /**\r\n     * Defines the buttons associated with the input to handle camera rotation.\r\n     */\r\n    @serialize()\r\n    public buttons = [0, 1, 2];\r\n\r\n    /**\r\n     * Assign buttons for Yaw control.\r\n     */\r\n    public buttonsYaw: number[] = [-1, 0, 1];\r\n\r\n    /**\r\n     * Assign buttons for Pitch control.\r\n     */\r\n    public buttonsPitch: number[] = [-1, 0, 1];\r\n\r\n    /**\r\n     * Assign buttons for Roll control.\r\n     */\r\n    public buttonsRoll: number[] = [2];\r\n\r\n    /**\r\n     * Detect if any button is being pressed while mouse is moved.\r\n     * -1 = Mouse locked.\r\n     * 0 = Left button.\r\n     * 1 = Middle Button.\r\n     * 2 = Right Button.\r\n     */\r\n    public activeButton: number = -1;\r\n\r\n    /**\r\n     * Defines the pointer's angular sensibility, to control the camera rotation speed.\r\n     * Higher values reduce its sensitivity.\r\n     */\r\n    @serialize()\r\n    public angularSensibility = 1000.0;\r\n\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n    private _rollObserver: Nullable<Observer<Scene>>;\r\n    private _previousPosition: Nullable<{ x: number; y: number }> = null;\r\n    private _noPreventDefault: boolean | undefined;\r\n\r\n    /** Reused conditions object for `resolveInteraction` to avoid per-move allocations. */\r\n    private readonly _pointerConditions: InputConditions = {};\r\n\r\n    /**\r\n     * Listen to mouse events to control the camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n     */\r\n    constructor() {}\r\n\r\n    /**\r\n     * Attach the mouse control to the HTML DOM element.\r\n     * @param noPreventDefault Defines whether events caught by the controls should call preventdefault().\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        this._noPreventDefault = noPreventDefault;\r\n\r\n        this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(\r\n            (p: any) => {\r\n                this._pointerInput(p);\r\n            },\r\n            PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE\r\n        );\r\n\r\n        // Correct Roll by rate, if enabled.\r\n        this._rollObserver = this.camera.getScene().onBeforeRenderObservable.add(() => {\r\n            if (this.camera.rollCorrect) {\r\n                this.camera.restoreRoll(this.camera.rollCorrect);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._observer) {\r\n            this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n\r\n            this.camera.getScene().onBeforeRenderObservable.remove(this._rollObserver);\r\n\r\n            this._observer = null;\r\n            this._rollObserver = null;\r\n            this._previousPosition = null;\r\n            this._noPreventDefault = undefined;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name.\r\n     */\r\n    public getClassName(): string {\r\n        return \"FlyCameraMouseInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input's friendly name.\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"mouse\";\r\n    }\r\n\r\n    // Track mouse movement, when the pointer is not locked.\r\n    private _pointerInput(p: any): void {\r\n        const e = <IPointerEvent>p.event;\r\n\r\n        const camera = this.camera;\r\n        const engine = camera.getEngine();\r\n\r\n        if (!this.touchEnabled && e.pointerType === \"touch\") {\r\n            return;\r\n        }\r\n\r\n        // Mouse is moved but an unknown mouse button is pressed.\r\n        if (p.type !== PointerEventTypes.POINTERMOVE && this.buttons.indexOf(e.button) === -1) {\r\n            return;\r\n        }\r\n\r\n        const srcElement = <HTMLElement>e.target;\r\n\r\n        // Mouse down.\r\n        if (p.type === PointerEventTypes.POINTERDOWN) {\r\n            try {\r\n                srcElement?.setPointerCapture(e.pointerId);\r\n            } catch (e) {\r\n                // Nothing to do with the error. Execution continues.\r\n            }\r\n\r\n            this._previousPosition = {\r\n                x: e.clientX,\r\n                y: e.clientY,\r\n            };\r\n\r\n            this.activeButton = e.button;\r\n\r\n            if (!this._noPreventDefault) {\r\n                e.preventDefault();\r\n            }\r\n\r\n            // This is required to move while pointer button is down\r\n            if (engine.isPointerLock) {\r\n                this._onMouseMove(p.event);\r\n            }\r\n        }\r\n        // Mouse up.\r\n        else if (p.type === PointerEventTypes.POINTERUP) {\r\n            try {\r\n                srcElement?.releasePointerCapture(e.pointerId);\r\n            } catch (e) {\r\n                // Nothing to do with the error. Execution continues.\r\n            }\r\n\r\n            this.activeButton = -1;\r\n\r\n            this._previousPosition = null;\r\n            if (!this._noPreventDefault) {\r\n                e.preventDefault();\r\n            }\r\n        }\r\n        // Mouse move.\r\n        else if (p.type === PointerEventTypes.POINTERMOVE) {\r\n            if (!this._previousPosition) {\r\n                if (engine.isPointerLock) {\r\n                    this._onMouseMove(p.event);\r\n                }\r\n\r\n                return;\r\n            }\r\n\r\n            const offsetX = e.clientX - this._previousPosition.x;\r\n            const offsetY = e.clientY - this._previousPosition.y;\r\n\r\n            this._rotateCamera(offsetX, offsetY);\r\n\r\n            this._previousPosition = {\r\n                x: e.clientX,\r\n                y: e.clientY,\r\n            };\r\n\r\n            if (!this._noPreventDefault) {\r\n                e.preventDefault();\r\n            }\r\n        }\r\n    }\r\n\r\n    // Track mouse movement, when pointer is locked.\r\n    private _onMouseMove(e: any): void {\r\n        const camera = this.camera;\r\n        const engine = camera.getEngine();\r\n\r\n        if (!engine.isPointerLock) {\r\n            return;\r\n        }\r\n\r\n        const offsetX = e.movementX;\r\n        const offsetY = e.movementY;\r\n\r\n        this._rotateCamera(offsetX, offsetY);\r\n\r\n        this._previousPosition = null;\r\n\r\n        if (!this._noPreventDefault) {\r\n            e.preventDefault();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rotate camera by mouse offset.\r\n     * @param offsetX\r\n     * @param offsetY\r\n     */\r\n    private _rotateCamera(offsetX: number, offsetY: number): void {\r\n        const camera = this.camera;\r\n\r\n        // Consult the configurable input map: only rotate when the active button resolves to the\r\n        // \"rotate\" interaction, letting consumers remap or disable pointer-driven rotation. The\r\n        // resolved entry's sensitivity overrides the legacy `angularSensibility` (used as fallback).\r\n        this._pointerConditions.button = this.activeButton;\r\n        const entry = camera.movement.input.resolveInteraction(\"pointer\", this._pointerConditions);\r\n        if (!entry || entry.interaction !== \"rotate\") {\r\n            return;\r\n        }\r\n\r\n        const handednessMultiplier = camera._calculateHandednessMultiplier();\r\n        const sensitivityX = entry.sensitivityX ?? entry.sensitivity ?? 1 / this.angularSensibility;\r\n        const sensitivityY = entry.sensitivityY ?? entry.sensitivity ?? 1 / this.angularSensibility;\r\n        const x = offsetX * handednessMultiplier * sensitivityX;\r\n        const y = offsetY * handednessMultiplier * sensitivityY;\r\n\r\n        // Initialize to current rotation.\r\n        const currentRotation = Quaternion.RotationYawPitchRoll(camera.rotation.y, camera.rotation.x, camera.rotation.z);\r\n        let rotationChange: Quaternion;\r\n\r\n        // Pitch.\r\n        if (\r\n            this.buttonsPitch.some((v) => {\r\n                return v === this.activeButton;\r\n            })\r\n        ) {\r\n            // Apply change in Radians to vector Angle.\r\n            rotationChange = Quaternion.RotationAxis(Axis.X, y);\r\n            // Apply Pitch to quaternion.\r\n            currentRotation.multiplyInPlace(rotationChange);\r\n        }\r\n\r\n        // Yaw.\r\n        if (\r\n            this.buttonsYaw.some((v) => {\r\n                return v === this.activeButton;\r\n            })\r\n        ) {\r\n            // Apply change in Radians to vector Angle.\r\n            rotationChange = Quaternion.RotationAxis(Axis.Y, x);\r\n            // Apply Yaw to quaternion.\r\n            currentRotation.multiplyInPlace(rotationChange);\r\n\r\n            // Add Roll, if banked turning is enabled, within Roll limit.\r\n            const limit = camera.bankedTurnLimit + camera._trackRoll; // Defaults to 90° plus manual roll.\r\n            if (camera.bankedTurn && -limit < camera.rotation.z && camera.rotation.z < limit) {\r\n                const bankingDelta = camera.bankedTurnMultiplier * -x;\r\n                // Apply change in Radians to vector Angle.\r\n                rotationChange = Quaternion.RotationAxis(Axis.Z, bankingDelta);\r\n                // Apply Yaw to quaternion.\r\n                currentRotation.multiplyInPlace(rotationChange);\r\n            }\r\n        }\r\n\r\n        // Roll.\r\n        if (\r\n            this.buttonsRoll.some((v) => {\r\n                return v === this.activeButton;\r\n            })\r\n        ) {\r\n            // Apply change in Radians to vector Angle.\r\n            rotationChange = Quaternion.RotationAxis(Axis.Z, -x);\r\n            // Track Rolling.\r\n            camera._trackRoll -= x;\r\n            // Apply Pitch to quaternion.\r\n            currentRotation.multiplyInPlace(rotationChange);\r\n        }\r\n\r\n        // Apply rotationQuaternion to Euler camera.rotation.\r\n        currentRotation.toEulerAnglesToRef(camera.rotation);\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FlyCameraMouseInput\"] = FlyCameraMouseInput;\r\n","import { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FollowCamera } from \"../../Cameras/followCamera\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of a follow camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FollowCameraKeyboardMoveInput implements ICameraInput<FollowCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FollowCamera;\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the up action (increase heightOffset)\r\n     */\r\n    @serialize()\r\n    public keysHeightOffsetIncr = [38];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the down action (decrease heightOffset)\r\n     */\r\n    @serialize()\r\n    public keysHeightOffsetDecr = [40];\r\n\r\n    /**\r\n     * Defines whether the Alt modifier key is required to move up/down (alter heightOffset)\r\n     */\r\n    @serialize()\r\n    public keysHeightOffsetModifierAlt: boolean = false;\r\n\r\n    /**\r\n     * Defines whether the Ctrl modifier key is required to move up/down (alter heightOffset)\r\n     */\r\n    @serialize()\r\n    public keysHeightOffsetModifierCtrl: boolean = false;\r\n\r\n    /**\r\n     * Defines whether the Shift modifier key is required to move up/down (alter heightOffset)\r\n     */\r\n    @serialize()\r\n    public keysHeightOffsetModifierShift: boolean = false;\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the left action (increase rotationOffset)\r\n     */\r\n    @serialize()\r\n    public keysRotationOffsetIncr = [37];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the right action (decrease rotationOffset)\r\n     */\r\n    @serialize()\r\n    public keysRotationOffsetDecr = [39];\r\n\r\n    /**\r\n     * Defines whether the Alt modifier key is required to move left/right (alter rotationOffset)\r\n     */\r\n    @serialize()\r\n    public keysRotationOffsetModifierAlt: boolean = false;\r\n\r\n    /**\r\n     * Defines whether the Ctrl modifier key is required to move left/right (alter rotationOffset)\r\n     */\r\n    @serialize()\r\n    public keysRotationOffsetModifierCtrl: boolean = false;\r\n\r\n    /**\r\n     * Defines whether the Shift modifier key is required to move left/right (alter rotationOffset)\r\n     */\r\n    @serialize()\r\n    public keysRotationOffsetModifierShift: boolean = false;\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the zoom-in action (decrease radius)\r\n     */\r\n    @serialize()\r\n    public keysRadiusIncr = [40];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the zoom-out action (increase radius)\r\n     */\r\n    @serialize()\r\n    public keysRadiusDecr = [38];\r\n\r\n    /**\r\n     * Defines whether the Alt modifier key is required to zoom in/out (alter radius value)\r\n     */\r\n    @serialize()\r\n    public keysRadiusModifierAlt: boolean = true;\r\n\r\n    /**\r\n     * Defines whether the Ctrl modifier key is required to zoom in/out (alter radius value)\r\n     */\r\n    @serialize()\r\n    public keysRadiusModifierCtrl: boolean = false;\r\n\r\n    /**\r\n     * Defines whether the Shift modifier key is required to zoom in/out (alter radius value)\r\n     */\r\n    @serialize()\r\n    public keysRadiusModifierShift: boolean = false;\r\n\r\n    /**\r\n     * Defines the rate of change of heightOffset.\r\n     */\r\n    @serialize()\r\n    public heightSensibility: number = 1;\r\n\r\n    /**\r\n     * Defines the rate of change of rotationOffset.\r\n     */\r\n    @serialize()\r\n    public rotationSensibility: number = 1;\r\n\r\n    /**\r\n     * Defines the rate of change of radius.\r\n     */\r\n    @serialize()\r\n    public radiusSensibility: number = 1;\r\n\r\n    private _keys = new Array<number>();\r\n    private _ctrlPressed: boolean;\r\n    private _altPressed: boolean;\r\n    private _shiftPressed: boolean;\r\n    private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n    private _engine: AbstractEngine;\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        if (this._onCanvasBlurObserver) {\r\n            return;\r\n        }\r\n\r\n        this._scene = this.camera.getScene();\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n            this._keys.length = 0;\r\n        });\r\n\r\n        this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n            const evt = info.event;\r\n            if (!evt.metaKey) {\r\n                if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n                    this._ctrlPressed = evt.ctrlKey;\r\n                    this._altPressed = evt.altKey;\r\n                    this._shiftPressed = evt.shiftKey;\r\n\r\n                    if (\r\n                        this.keysHeightOffsetIncr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysHeightOffsetDecr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotationOffsetIncr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotationOffsetDecr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRadiusIncr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRadiusDecr.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index === -1) {\r\n                            this._keys.push(evt.keyCode);\r\n                        }\r\n\r\n                        if (evt.preventDefault) {\r\n                            if (!noPreventDefault) {\r\n                                evt.preventDefault();\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (\r\n                        this.keysHeightOffsetIncr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysHeightOffsetDecr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotationOffsetIncr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotationOffsetDecr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRadiusIncr.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRadiusDecr.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index >= 0) {\r\n                            this._keys.splice(index, 1);\r\n                        }\r\n\r\n                        if (evt.preventDefault) {\r\n                            if (!noPreventDefault) {\r\n                                evt.preventDefault();\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._scene) {\r\n            if (this._onKeyboardObserver) {\r\n                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n            }\r\n            if (this._onCanvasBlurObserver) {\r\n                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n            }\r\n            this._onKeyboardObserver = null;\r\n            this._onCanvasBlurObserver = null;\r\n        }\r\n\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._onKeyboardObserver) {\r\n            for (const keyCode of this._keys) {\r\n                if (this.keysHeightOffsetIncr.indexOf(keyCode) !== -1 && this._modifierHeightOffset()) {\r\n                    this.camera.heightOffset += this.heightSensibility;\r\n                } else if (this.keysHeightOffsetDecr.indexOf(keyCode) !== -1 && this._modifierHeightOffset()) {\r\n                    this.camera.heightOffset -= this.heightSensibility;\r\n                } else if (this.keysRotationOffsetIncr.indexOf(keyCode) !== -1 && this._modifierRotationOffset()) {\r\n                    this.camera.rotationOffset += this.rotationSensibility;\r\n                    this.camera.rotationOffset %= 360;\r\n                } else if (this.keysRotationOffsetDecr.indexOf(keyCode) !== -1 && this._modifierRotationOffset()) {\r\n                    this.camera.rotationOffset -= this.rotationSensibility;\r\n                    this.camera.rotationOffset %= 360;\r\n                } else if (this.keysRadiusIncr.indexOf(keyCode) !== -1 && this._modifierRadius()) {\r\n                    this.camera.radius += this.radiusSensibility;\r\n                } else if (this.keysRadiusDecr.indexOf(keyCode) !== -1 && this._modifierRadius()) {\r\n                    this.camera.radius -= this.radiusSensibility;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FollowCameraKeyboardMoveInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"keyboard\";\r\n    }\r\n\r\n    /**\r\n     * Check if the pressed modifier keys (Alt/Ctrl/Shift) match those configured to\r\n     * allow modification of the heightOffset value.\r\n     * @returns true if modifier keys match\r\n     */\r\n    private _modifierHeightOffset(): boolean {\r\n        return (\r\n            this.keysHeightOffsetModifierAlt === this._altPressed &&\r\n            this.keysHeightOffsetModifierCtrl === this._ctrlPressed &&\r\n            this.keysHeightOffsetModifierShift === this._shiftPressed\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Check if the pressed modifier keys (Alt/Ctrl/Shift) match those configured to\r\n     * allow modification of the rotationOffset value.\r\n     * @returns true if modifier keys match\r\n     */\r\n    private _modifierRotationOffset(): boolean {\r\n        return (\r\n            this.keysRotationOffsetModifierAlt === this._altPressed &&\r\n            this.keysRotationOffsetModifierCtrl === this._ctrlPressed &&\r\n            this.keysRotationOffsetModifierShift === this._shiftPressed\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Check if the pressed modifier keys (Alt/Ctrl/Shift) match those configured to\r\n     * allow modification of the radius value.\r\n     * @returns true if modifier keys match\r\n     */\r\n    private _modifierRadius(): boolean {\r\n        return this.keysRadiusModifierAlt === this._altPressed && this.keysRadiusModifierCtrl === this._ctrlPressed && this.keysRadiusModifierShift === this._shiftPressed;\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FollowCameraKeyboardMoveInput\"] = FollowCameraKeyboardMoveInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type EventState, type Observer } from \"../../Misc/observable\";\r\nimport { type FollowCamera } from \"../../Cameras/followCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { type IWheelEvent } from \"../../Events/deviceInputEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Manage the mouse wheel inputs to control a follow camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FollowCameraMouseWheelInput implements ICameraInput<FollowCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FollowCamera;\r\n\r\n    /**\r\n     * Moue wheel controls zoom. (Mouse wheel modifies camera.radius value.)\r\n     */\r\n    @serialize()\r\n    public axisControlRadius: boolean = true;\r\n\r\n    /**\r\n     * Moue wheel controls height. (Mouse wheel modifies camera.heightOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisControlHeight: boolean = false;\r\n\r\n    /**\r\n     * Moue wheel controls angle. (Mouse wheel modifies camera.rotationOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisControlRotation: boolean = false;\r\n\r\n    /**\r\n     * Gets or Set the mouse wheel precision or how fast is the camera moves in\r\n     * relation to mouseWheel events.\r\n     */\r\n    @serialize()\r\n    public wheelPrecision = 3.0;\r\n\r\n    /**\r\n     * wheelDeltaPercentage will be used instead of wheelPrecision if different from 0.\r\n     * It defines the percentage of current camera.radius to use as delta when wheel is used.\r\n     */\r\n    @serialize()\r\n    public wheelDeltaPercentage = 0;\r\n\r\n    private _wheel: Nullable<(p: PointerInfo, s: EventState) => void>;\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        this._wheel = (p) => {\r\n            // sanity check - this should be a PointerWheel event.\r\n            if (p.type !== PointerEventTypes.POINTERWHEEL) {\r\n                return;\r\n            }\r\n            const event = <IWheelEvent>p.event;\r\n            let delta = 0;\r\n\r\n            const wheelDelta = Math.max(-1, Math.min(1, event.deltaY));\r\n            if (this.wheelDeltaPercentage) {\r\n                if (+this.axisControlRadius + +this.axisControlHeight + +this.axisControlRotation > 1) {\r\n                    Logger.Warn(\r\n                        \"wheelDeltaPercentage only usable when mouse wheel \" +\r\n                            \"controls ONE axis. \" +\r\n                            \"Currently enabled: \" +\r\n                            \"axisControlRadius: \" +\r\n                            this.axisControlRadius +\r\n                            \", axisControlHeightOffset: \" +\r\n                            this.axisControlHeight +\r\n                            \", axisControlRotationOffset: \" +\r\n                            this.axisControlRotation\r\n                    );\r\n                }\r\n\r\n                if (this.axisControlRadius) {\r\n                    delta = wheelDelta * 0.01 * this.wheelDeltaPercentage * this.camera.radius;\r\n                } else if (this.axisControlHeight) {\r\n                    delta = wheelDelta * 0.01 * this.wheelDeltaPercentage * this.camera.heightOffset;\r\n                } else if (this.axisControlRotation) {\r\n                    delta = wheelDelta * 0.01 * this.wheelDeltaPercentage * this.camera.rotationOffset;\r\n                }\r\n            } else {\r\n                delta = wheelDelta * this.wheelPrecision;\r\n            }\r\n\r\n            if (delta) {\r\n                if (this.axisControlRadius) {\r\n                    this.camera.radius += delta;\r\n                } else if (this.axisControlHeight) {\r\n                    this.camera.heightOffset -= delta;\r\n                } else if (this.axisControlRotation) {\r\n                    this.camera.rotationOffset -= delta;\r\n                }\r\n            }\r\n\r\n            if (event.preventDefault) {\r\n                if (!noPreventDefault) {\r\n                    event.preventDefault();\r\n                }\r\n            }\r\n        };\r\n\r\n        this._observer = this.camera.getScene()._inputManager._addCameraPointerObserver(this._wheel, PointerEventTypes.POINTERWHEEL);\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._observer) {\r\n            this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n            this._observer = null;\r\n            this._wheel = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FollowCameraMouseWheelInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"mousewheel\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FollowCameraMouseWheelInput\"] = FollowCameraMouseWheelInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type FollowCamera } from \"../../Cameras/followCamera\";\r\nimport { CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { BaseCameraPointersInput } from \"../../Cameras/Inputs/BaseCameraPointersInput\";\r\nimport { type PointerTouch } from \"../../Events/pointerEvents\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Manage the pointers inputs to control an follow camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FollowCameraPointersInput extends BaseCameraPointersInput {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FollowCamera;\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FollowCameraPointersInput\";\r\n    }\r\n\r\n    /**\r\n     * Defines the pointer angular sensibility along the X axis or how fast is\r\n     * the camera rotating.\r\n     * A negative number will reverse the axis direction.\r\n     */\r\n    @serialize()\r\n    public angularSensibilityX = 1;\r\n\r\n    /**\r\n     * Defines the pointer angular sensibility along the Y axis or how fast is\r\n     * the camera rotating.\r\n     * A negative number will reverse the axis direction.\r\n     */\r\n    @serialize()\r\n    public angularSensibilityY = 1;\r\n\r\n    /**\r\n     * Defines the pointer pinch precision or how fast is the camera zooming.\r\n     * A negative number will reverse the axis direction.\r\n     */\r\n    @serialize()\r\n    public pinchPrecision = 10000.0;\r\n\r\n    /**\r\n     * pinchDeltaPercentage will be used instead of pinchPrecision if different\r\n     * from 0.\r\n     * It defines the percentage of current camera.radius to use as delta when\r\n     * pinch zoom is used.\r\n     */\r\n    @serialize()\r\n    public pinchDeltaPercentage = 0;\r\n\r\n    /**\r\n     * Pointer X axis controls zoom. (X axis modifies camera.radius value.)\r\n     */\r\n    @serialize()\r\n    public axisXControlRadius: boolean = false;\r\n\r\n    /**\r\n     * Pointer X axis controls height. (X axis modifies camera.heightOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisXControlHeight: boolean = false;\r\n\r\n    /**\r\n     * Pointer X axis controls angle. (X axis modifies camera.rotationOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisXControlRotation: boolean = true;\r\n\r\n    /**\r\n     * Pointer Y axis controls zoom. (Y axis modifies camera.radius value.)\r\n     */\r\n    @serialize()\r\n    public axisYControlRadius: boolean = false;\r\n\r\n    /**\r\n     * Pointer Y axis controls height. (Y axis modifies camera.heightOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisYControlHeight: boolean = true;\r\n\r\n    /**\r\n     * Pointer Y axis controls angle. (Y axis modifies camera.rotationOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisYControlRotation: boolean = false;\r\n\r\n    /**\r\n     * Pinch controls zoom. (Pinch modifies camera.radius value.)\r\n     */\r\n    @serialize()\r\n    public axisPinchControlRadius: boolean = true;\r\n\r\n    /**\r\n     * Pinch controls height. (Pinch modifies camera.heightOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisPinchControlHeight: boolean = false;\r\n\r\n    /**\r\n     * Pinch controls angle. (Pinch modifies camera.rotationOffset value.)\r\n     */\r\n    @serialize()\r\n    public axisPinchControlRotation: boolean = false;\r\n\r\n    /**\r\n     * Log error messages if basic misconfiguration has occurred.\r\n     */\r\n    public warningEnable: boolean = true;\r\n\r\n    /**\r\n     * Called on pointer POINTERMOVE event if only a single touch is active.\r\n     * @param pointA The current position of the pointer\r\n     * @param offsetX The offsetX of the pointer when the event occurred\r\n     * @param offsetY The offsetY of the pointer when the event occurred\r\n     */\r\n    public override onTouch(pointA: Nullable<PointerTouch>, offsetX: number, offsetY: number): void {\r\n        this._warning();\r\n\r\n        if (this.axisXControlRotation) {\r\n            this.camera.rotationOffset += offsetX / this.angularSensibilityX;\r\n        } else if (this.axisYControlRotation) {\r\n            this.camera.rotationOffset += offsetY / this.angularSensibilityX;\r\n        }\r\n\r\n        if (this.axisXControlHeight) {\r\n            this.camera.heightOffset += offsetX / this.angularSensibilityY;\r\n        } else if (this.axisYControlHeight) {\r\n            this.camera.heightOffset += offsetY / this.angularSensibilityY;\r\n        }\r\n\r\n        if (this.axisXControlRadius) {\r\n            this.camera.radius -= offsetX / this.angularSensibilityY;\r\n        } else if (this.axisYControlRadius) {\r\n            this.camera.radius -= offsetY / this.angularSensibilityY;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on pointer POINTERMOVE event if multiple touches are active.\r\n     * @param pointA First point in the pair\r\n     * @param pointB Second point in the pair\r\n     * @param previousPinchSquaredDistance Sqr Distance between the points the last time this event was fired (by this input)\r\n     * @param pinchSquaredDistance Sqr Distance between the points this time\r\n     * @param previousMultiTouchPanPosition Previous center point between the points\r\n     * @param multiTouchPanPosition Current center point between the points\r\n     */\r\n    public override onMultiTouch(\r\n        pointA: Nullable<PointerTouch>,\r\n        pointB: Nullable<PointerTouch>,\r\n        previousPinchSquaredDistance: number,\r\n        pinchSquaredDistance: number,\r\n        previousMultiTouchPanPosition: Nullable<PointerTouch>,\r\n        multiTouchPanPosition: Nullable<PointerTouch>\r\n    ): void {\r\n        if (previousPinchSquaredDistance === 0 && previousMultiTouchPanPosition === null) {\r\n            // First time this method is called for new pinch.\r\n            // Next time this is called there will be a\r\n            // previousPinchSquaredDistance and pinchSquaredDistance to compare.\r\n            return;\r\n        }\r\n        if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {\r\n            // Last time this method is called at the end of a pinch.\r\n            return;\r\n        }\r\n        let pinchDelta = (pinchSquaredDistance - previousPinchSquaredDistance) / ((this.pinchPrecision * (this.angularSensibilityX + this.angularSensibilityY)) / 2);\r\n\r\n        if (this.pinchDeltaPercentage) {\r\n            pinchDelta *= 0.01 * this.pinchDeltaPercentage;\r\n            if (this.axisPinchControlRotation) {\r\n                this.camera.rotationOffset += pinchDelta * this.camera.rotationOffset;\r\n            }\r\n            if (this.axisPinchControlHeight) {\r\n                this.camera.heightOffset += pinchDelta * this.camera.heightOffset;\r\n            }\r\n            if (this.axisPinchControlRadius) {\r\n                this.camera.radius -= pinchDelta * this.camera.radius;\r\n            }\r\n        } else {\r\n            if (this.axisPinchControlRotation) {\r\n                this.camera.rotationOffset += pinchDelta;\r\n            }\r\n\r\n            if (this.axisPinchControlHeight) {\r\n                this.camera.heightOffset += pinchDelta;\r\n            }\r\n\r\n            if (this.axisPinchControlRadius) {\r\n                this.camera.radius -= pinchDelta;\r\n            }\r\n        }\r\n    }\r\n\r\n    /* Check for obvious misconfiguration. */\r\n    private _warningCounter: number = 0;\r\n    private _warning(): void {\r\n        if (!this.warningEnable || this._warningCounter++ % 100 !== 0) {\r\n            return;\r\n        }\r\n        const warn =\r\n            \"It probably only makes sense to control ONE camera \" + \"property with each pointer axis. Set 'warningEnable = false' \" + \"if you are sure. Currently enabled: \";\r\n\r\n        if (+this.axisXControlRotation + +this.axisXControlHeight + +this.axisXControlRadius > 1) {\r\n            Logger.Warn(\r\n                warn +\r\n                    \"axisXControlRotation: \" +\r\n                    this.axisXControlRotation +\r\n                    \", axisXControlHeight: \" +\r\n                    this.axisXControlHeight +\r\n                    \", axisXControlRadius: \" +\r\n                    this.axisXControlRadius\r\n            );\r\n        }\r\n        if (+this.axisYControlRotation + +this.axisYControlHeight + +this.axisYControlRadius > 1) {\r\n            Logger.Warn(\r\n                warn +\r\n                    \"axisYControlRotation: \" +\r\n                    this.axisYControlRotation +\r\n                    \", axisYControlHeight: \" +\r\n                    this.axisYControlHeight +\r\n                    \", axisYControlRadius: \" +\r\n                    this.axisYControlRadius\r\n            );\r\n        }\r\n        if (+this.axisPinchControlRotation + +this.axisPinchControlHeight + +this.axisPinchControlRadius > 1) {\r\n            Logger.Warn(\r\n                warn +\r\n                    \"axisPinchControlRotation: \" +\r\n                    this.axisPinchControlRotation +\r\n                    \", axisPinchControlHeight: \" +\r\n                    this.axisPinchControlHeight +\r\n                    \", axisPinchControlRadius: \" +\r\n                    this.axisPinchControlRadius\r\n            );\r\n        }\r\n    }\r\n}\r\n(<any>CameraInputTypes)[\"FollowCameraPointersInput\"] = FollowCameraPointersInput;\r\n","import { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n/**\r\n * Manage the keyboard inputs to control the movement of a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FreeCamera;\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the forward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysUp = [38];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the upward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysUpward = [33];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the backward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysDown = [40];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the downward move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysDownward = [34];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysLeft = [37];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysRight = [39];\r\n\r\n    /**\r\n     * Defines the pointer angular sensibility  along the X and Y axis or how fast is the camera rotating.\r\n     */\r\n    @serialize()\r\n    public rotationSpeed = 0.5;\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the left rotation move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysRotateLeft: number[] = [];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the right rotation move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysRotateRight: number[] = [];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the up rotation move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysRotateUp: number[] = [];\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the down rotation move of the camera.\r\n     */\r\n    @serialize()\r\n    public keysRotateDown: number[] = [];\r\n\r\n    private _keys = new Array<number>();\r\n    private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n    private _engine: AbstractEngine;\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        if (this._onCanvasBlurObserver) {\r\n            return;\r\n        }\r\n\r\n        this._scene = this.camera.getScene();\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n            this._keys.length = 0;\r\n        });\r\n\r\n        this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n            const evt = info.event;\r\n            if (!evt.metaKey) {\r\n                if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n                    if (\r\n                        this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysUpward.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDownward.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateDown.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index === -1) {\r\n                            this._keys.push(evt.keyCode);\r\n                        }\r\n                        if (!noPreventDefault) {\r\n                            evt.preventDefault();\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (\r\n                        this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysUpward.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDownward.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRotateDown.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index >= 0) {\r\n                            this._keys.splice(index, 1);\r\n                        }\r\n                        if (!noPreventDefault) {\r\n                            evt.preventDefault();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._scene) {\r\n            if (this._onKeyboardObserver) {\r\n                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n            }\r\n\r\n            if (this._onCanvasBlurObserver) {\r\n                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n            }\r\n            this._onKeyboardObserver = null;\r\n            this._onCanvasBlurObserver = null;\r\n        }\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._onKeyboardObserver) {\r\n            const camera = this.camera;\r\n            // Movement keys are gated on the keyboard→translate mapping and rotation keys on\r\n            // keyboard→rotate. Removing the corresponding entry disables that family of keys.\r\n            // An entry's optional `sensitivity` acts as a gain (default 1) over the legacy scaling.\r\n            const input = camera.movement.input;\r\n            const translateEntry = input.getEntry(\"keyboard\", \"translate\");\r\n            const rotateEntry = input.getEntry(\"keyboard\", \"rotate\");\r\n            const rotateGain = rotateEntry?.sensitivity ?? 1;\r\n\r\n            // Movement keys are accumulated into a single local direction and applied once below, so that\r\n            // holding two directions at once (e.g. forward + left) moves along a normalized diagonal at the\r\n            // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from\r\n            // applying each movement key independently. Rotation keys act on separate angular axes and are\r\n            // applied directly as before.\r\n            const localDirection = camera._localDirection.copyFromFloats(0, 0, 0);\r\n\r\n            // Keyboard\r\n            for (let index = 0; index < this._keys.length; index++) {\r\n                const keyCode = this._keys[index];\r\n\r\n                if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n                    localDirection.x -= 1;\r\n                } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n                    localDirection.z += 1;\r\n                } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n                    localDirection.x += 1;\r\n                } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n                    localDirection.z -= 1;\r\n                } else if (this.keysUpward.indexOf(keyCode) !== -1) {\r\n                    localDirection.y += 1;\r\n                } else if (this.keysDownward.indexOf(keyCode) !== -1) {\r\n                    localDirection.y -= 1;\r\n                } else if (this.keysRotateLeft.indexOf(keyCode) !== -1) {\r\n                    if (rotateEntry) {\r\n                        camera.cameraRotation.y -= this._getLocalRotation() * rotateGain;\r\n                    }\r\n                } else if (this.keysRotateRight.indexOf(keyCode) !== -1) {\r\n                    if (rotateEntry) {\r\n                        camera.cameraRotation.y += this._getLocalRotation() * rotateGain;\r\n                    }\r\n                } else if (this.keysRotateUp.indexOf(keyCode) !== -1) {\r\n                    if (rotateEntry) {\r\n                        camera.cameraRotation.x -= this._getLocalRotation() * rotateGain;\r\n                    }\r\n                } else if (this.keysRotateDown.indexOf(keyCode) !== -1) {\r\n                    if (rotateEntry) {\r\n                        camera.cameraRotation.x += this._getLocalRotation() * rotateGain;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Apply a single, normalized movement once all keys for this frame have been accumulated.\r\n            // Translation is suppressed when the keyboard→translate mapping is removed.\r\n            if (translateEntry && (localDirection.x !== 0 || localDirection.y !== 0 || localDirection.z !== 0)) {\r\n                const speed = camera._computeLocalCameraSpeed() * (translateEntry.sensitivity ?? 1);\r\n                // Normalize so a diagonal isn't faster than an axis-aligned move, then scale to the per-frame speed.\r\n                localDirection.normalize().scaleInPlace(speed);\r\n\r\n                if (camera.getScene().useRightHandedSystem) {\r\n                    localDirection.z *= -1;\r\n                }\r\n\r\n                camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n                Vector3.TransformNormalToRef(localDirection, camera._cameraTransformMatrix, camera._transformedDirection);\r\n                camera.cameraDirection.addInPlace(camera._transformedDirection);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FreeCameraKeyboardMoveInput\";\r\n    }\r\n\r\n    /** @internal */\r\n    public _onLostFocus(): void {\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"keyboard\";\r\n    }\r\n\r\n    private _getLocalRotation(): number {\r\n        const handednessMultiplier = this.camera._calculateHandednessMultiplier();\r\n        const rotation = ((this.rotationSpeed * this._engine.getDeltaTime()) / 1000) * handednessMultiplier;\r\n\r\n        return rotation;\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraKeyboardMoveInput\"] = FreeCameraKeyboardMoveInput;\r\n","import { type Observer, type EventState, Observable } from \"../../Misc/observable\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type IMouseEvent, type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { type InputConditions } from \"../inputMapper\";\r\n/**\r\n * Manage the mouse inputs to control the movement of a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraMouseInput implements ICameraInput<FreeCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FreeCamera;\r\n\r\n    /**\r\n     * Defines the buttons associated with the input to handle camera move.\r\n     */\r\n    @serialize()\r\n    public buttons = [0, 1, 2];\r\n\r\n    /**\r\n     * Defines the pointer angular sensibility  along the X and Y axis or how fast is the camera rotating.\r\n     */\r\n    @serialize()\r\n    public angularSensibility = 2000.0;\r\n\r\n    private _pointerInput: (p: PointerInfo, s: EventState) => void;\r\n    private _onMouseMove: Nullable<(e: IMouseEvent) => any>;\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n    private _previousPosition: Nullable<{ x: number; y: number }> = null;\r\n\r\n    /**\r\n     * Observable for when a pointer move event occurs containing the move offset\r\n     */\r\n    public onPointerMovedObservable = new Observable<{ offsetX: number; offsetY: number }>();\r\n    /**\r\n     * @internal\r\n     * If the camera should be rotated automatically based on pointer movement\r\n     */\r\n    public _allowCameraRotation = true;\r\n\r\n    private _currentActiveButton: number = -1;\r\n    private _activePointerId: number = -1;\r\n    private _contextMenuBind: (evt: MouseEvent) => void;\r\n\r\n    /** Reused conditions object for `resolveInteraction` to avoid per-move allocations. */\r\n    private readonly _pointerConditions: InputConditions = {};\r\n\r\n    /**\r\n     * Applies a pointer-drag delta as camera rotation, but only if the camera's configurable\r\n     * input map resolves the current pointer interaction to \"rotate\". The map is consulted with\r\n     * the currently active mouse button so consumers can remap or disable pointer-driven rotation.\r\n     * The applied scale comes from the resolved entry's `sensitivity`/`sensitivityX`/`sensitivityY`,\r\n     * falling back to the legacy `angularSensibility` for backward compatibility. The rotation is\r\n     * still written to `camera.cameraRotation` (not the movement accumulators) so existing code that\r\n     * reads `cameraRotation` immediately after a pointer event keeps working.\r\n     * @param offsetX Horizontal pointer delta (already handedness-adjusted).\r\n     * @param offsetY Vertical pointer delta (already handedness-adjusted).\r\n     */\r\n    private _applyPointerRotation(offsetX: number, offsetY: number): void {\r\n        this._pointerConditions.button = this._currentActiveButton;\r\n        const entry = this.camera.movement.input.resolveInteraction(\"pointer\", this._pointerConditions);\r\n        if (!entry || entry.interaction !== \"rotate\") {\r\n            return;\r\n        }\r\n        const sensitivityX = entry.sensitivityX ?? entry.sensitivity ?? 1 / this.angularSensibility;\r\n        const sensitivityY = entry.sensitivityY ?? entry.sensitivity ?? 1 / this.angularSensibility;\r\n        this.camera.cameraRotation.y += offsetX * sensitivityX;\r\n        this.camera.cameraRotation.x += offsetY * sensitivityY;\r\n    }\r\n\r\n    /**\r\n     * Manage the mouse inputs to control the movement of a free camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n     * @param touchEnabled Defines if touch is enabled or not\r\n     */\r\n    constructor(\r\n        /**\r\n         * [true] Define if touch is enabled in the mouse input\r\n         */\r\n        public touchEnabled = true\r\n    ) {}\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        const engine = this.camera.getEngine();\r\n        const element = engine.getInputElement();\r\n\r\n        if (!this._pointerInput) {\r\n            this._pointerInput = (p) => {\r\n                const evt = <IPointerEvent>p.event;\r\n                const isTouch = evt.pointerType === \"touch\";\r\n\r\n                if (!this.touchEnabled && isTouch) {\r\n                    return;\r\n                }\r\n\r\n                if (p.type !== PointerEventTypes.POINTERMOVE && this.buttons.indexOf(evt.button) === -1) {\r\n                    return;\r\n                }\r\n\r\n                const srcElement = <HTMLElement>evt.target;\r\n\r\n                if (p.type === PointerEventTypes.POINTERDOWN) {\r\n                    // If the input is touch with more than one touch OR if the input is mouse and there is already an active button, return\r\n                    if ((isTouch && this._activePointerId !== -1) || (!isTouch && this._currentActiveButton !== -1)) {\r\n                        return;\r\n                    }\r\n\r\n                    this._activePointerId = evt.pointerId;\r\n                    try {\r\n                        srcElement?.setPointerCapture(evt.pointerId);\r\n                    } catch (e) {\r\n                        //Nothing to do with the error. Execution will continue.\r\n                    }\r\n\r\n                    if (this._currentActiveButton === -1) {\r\n                        this._currentActiveButton = evt.button;\r\n                    }\r\n\r\n                    this._previousPosition = {\r\n                        x: evt.clientX,\r\n                        y: evt.clientY,\r\n                    };\r\n\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                        if (element) {\r\n                            element.focus();\r\n                        }\r\n                    }\r\n\r\n                    // This is required to move while pointer button is down\r\n                    if (engine.isPointerLock && this._onMouseMove) {\r\n                        this._onMouseMove(p.event);\r\n                    }\r\n                } else if (p.type === PointerEventTypes.POINTERUP) {\r\n                    // If input is touch with a different touch id OR if input is mouse with a different button, return\r\n                    if ((isTouch && this._activePointerId !== evt.pointerId) || (!isTouch && this._currentActiveButton !== evt.button)) {\r\n                        return;\r\n                    }\r\n\r\n                    try {\r\n                        srcElement?.releasePointerCapture(evt.pointerId);\r\n                    } catch (e) {\r\n                        //Nothing to do with the error.\r\n                    }\r\n                    this._currentActiveButton = -1;\r\n\r\n                    this._previousPosition = null;\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                    }\r\n\r\n                    this._activePointerId = -1;\r\n                } else if (p.type === PointerEventTypes.POINTERMOVE && (this._activePointerId === evt.pointerId || !isTouch)) {\r\n                    if (engine.isPointerLock && this._onMouseMove) {\r\n                        this._onMouseMove(p.event);\r\n                    } else if (this._previousPosition) {\r\n                        const handednessMultiplier = this.camera._calculateHandednessMultiplier();\r\n                        const offsetX = (evt.clientX - this._previousPosition.x) * handednessMultiplier;\r\n                        const offsetY = (evt.clientY - this._previousPosition.y) * handednessMultiplier;\r\n\r\n                        if (this._allowCameraRotation) {\r\n                            this._applyPointerRotation(offsetX, offsetY);\r\n                        }\r\n                        this.onPointerMovedObservable.notifyObservers({ offsetX: offsetX, offsetY: offsetY });\r\n\r\n                        this._previousPosition = {\r\n                            x: evt.clientX,\r\n                            y: evt.clientY,\r\n                        };\r\n\r\n                        if (!noPreventDefault) {\r\n                            evt.preventDefault();\r\n                        }\r\n                    }\r\n                }\r\n            };\r\n        }\r\n\r\n        this._onMouseMove = (evt) => {\r\n            if (!engine.isPointerLock) {\r\n                return;\r\n            }\r\n\r\n            const handednessMultiplier = this.camera._calculateHandednessMultiplier();\r\n            this._applyPointerRotation(evt.movementX * handednessMultiplier, evt.movementY * handednessMultiplier);\r\n\r\n            this._previousPosition = null;\r\n\r\n            if (!noPreventDefault) {\r\n                evt.preventDefault();\r\n            }\r\n        };\r\n\r\n        this._observer = this.camera\r\n            .getScene()\r\n            ._inputManager._addCameraPointerObserver(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);\r\n\r\n        if (element) {\r\n            this._contextMenuBind = (evt: MouseEvent) => this.onContextMenu(evt as PointerEvent);\r\n            element.addEventListener(\"contextmenu\", this._contextMenuBind, false); // TODO: We need to figure out how to handle this for Native\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on JS contextmenu event.\r\n     * Override this method to provide functionality.\r\n     * @param evt the context menu event\r\n     */\r\n    public onContextMenu(evt: PointerEvent): void {\r\n        evt.preventDefault();\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._observer) {\r\n            this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n\r\n            if (this._contextMenuBind) {\r\n                const engine = this.camera.getEngine();\r\n                const element = engine.getInputElement();\r\n                if (element) {\r\n                    element.removeEventListener(\"contextmenu\", this._contextMenuBind);\r\n                }\r\n            }\r\n\r\n            if (this.onPointerMovedObservable) {\r\n                this.onPointerMovedObservable.clear();\r\n            }\r\n\r\n            this._observer = null;\r\n            this._onMouseMove = null;\r\n            this._previousPosition = null;\r\n        }\r\n\r\n        this._activePointerId = -1;\r\n        this._currentActiveButton = -1;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FreeCameraMouseInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"mouse\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraMouseInput\"] = FreeCameraMouseInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { BaseCameraMouseWheelInput } from \"../../Cameras/Inputs/BaseCameraMouseWheelInput\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Coordinate } from \"../../Maths/math.axis\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nenum _CameraProperty {\r\n    MoveRelative,\r\n    RotateRelative,\r\n    MoveScene,\r\n}\r\n\r\n/**\r\n * Manage the mouse wheel inputs to control a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraMouseWheelInput extends BaseCameraMouseWheelInput {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FreeCamera;\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FreeCameraMouseWheelInput\";\r\n    }\r\n\r\n    /**\r\n     * Set which movement axis (relative to camera's orientation) the mouse\r\n     * wheel's X axis controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelXMoveRelative(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelXAction !== _CameraProperty.MoveRelative) {\r\n            // Attempting to clear different _wheelXAction.\r\n            return;\r\n        }\r\n        this._wheelXAction = _CameraProperty.MoveRelative;\r\n        this._wheelXActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured movement axis (relative to camera's orientation) the\r\n     * mouse wheel's X axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelXMoveRelative(): Nullable<Coordinate> {\r\n        if (this._wheelXAction !== _CameraProperty.MoveRelative) {\r\n            return null;\r\n        }\r\n        return this._wheelXActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which movement axis (relative to camera's orientation) the mouse\r\n     * wheel's Y axis controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelYMoveRelative(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelYAction !== _CameraProperty.MoveRelative) {\r\n            // Attempting to clear different _wheelYAction.\r\n            return;\r\n        }\r\n        this._wheelYAction = _CameraProperty.MoveRelative;\r\n        this._wheelYActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured movement axis (relative to camera's orientation) the\r\n     * mouse wheel's Y axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelYMoveRelative(): Nullable<Coordinate> {\r\n        if (this._wheelYAction !== _CameraProperty.MoveRelative) {\r\n            return null;\r\n        }\r\n        return this._wheelYActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which movement axis (relative to camera's orientation) the mouse\r\n     * wheel's Z axis controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelZMoveRelative(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelZAction !== _CameraProperty.MoveRelative) {\r\n            // Attempting to clear different _wheelZAction.\r\n            return;\r\n        }\r\n        this._wheelZAction = _CameraProperty.MoveRelative;\r\n        this._wheelZActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured movement axis (relative to camera's orientation) the\r\n     * mouse wheel's Z axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelZMoveRelative(): Nullable<Coordinate> {\r\n        if (this._wheelZAction !== _CameraProperty.MoveRelative) {\r\n            return null;\r\n        }\r\n        return this._wheelZActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which rotation axis (relative to camera's orientation) the mouse\r\n     * wheel's X axis controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelXRotateRelative(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelXAction !== _CameraProperty.RotateRelative) {\r\n            // Attempting to clear different _wheelXAction.\r\n            return;\r\n        }\r\n        this._wheelXAction = _CameraProperty.RotateRelative;\r\n        this._wheelXActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured rotation axis (relative to camera's orientation) the\r\n     * mouse wheel's X axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelXRotateRelative(): Nullable<Coordinate> {\r\n        if (this._wheelXAction !== _CameraProperty.RotateRelative) {\r\n            return null;\r\n        }\r\n        return this._wheelXActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which rotation axis (relative to camera's orientation) the mouse\r\n     * wheel's Y axis controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelYRotateRelative(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelYAction !== _CameraProperty.RotateRelative) {\r\n            // Attempting to clear different _wheelYAction.\r\n            return;\r\n        }\r\n        this._wheelYAction = _CameraProperty.RotateRelative;\r\n        this._wheelYActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured rotation axis (relative to camera's orientation) the\r\n     * mouse wheel's Y axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelYRotateRelative(): Nullable<Coordinate> {\r\n        if (this._wheelYAction !== _CameraProperty.RotateRelative) {\r\n            return null;\r\n        }\r\n        return this._wheelYActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which rotation axis (relative to camera's orientation) the mouse\r\n     * wheel's Z axis controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelZRotateRelative(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelZAction !== _CameraProperty.RotateRelative) {\r\n            // Attempting to clear different _wheelZAction.\r\n            return;\r\n        }\r\n        this._wheelZAction = _CameraProperty.RotateRelative;\r\n        this._wheelZActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured rotation axis (relative to camera's orientation) the\r\n     * mouse wheel's Z axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelZRotateRelative(): Nullable<Coordinate> {\r\n        if (this._wheelZAction !== _CameraProperty.RotateRelative) {\r\n            return null;\r\n        }\r\n        return this._wheelZActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which movement axis (relative to the scene) the mouse wheel's X axis\r\n     * controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelXMoveScene(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelXAction !== _CameraProperty.MoveScene) {\r\n            // Attempting to clear different _wheelXAction.\r\n            return;\r\n        }\r\n        this._wheelXAction = _CameraProperty.MoveScene;\r\n        this._wheelXActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured movement axis (relative to the scene) the mouse wheel's\r\n     * X axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelXMoveScene(): Nullable<Coordinate> {\r\n        if (this._wheelXAction !== _CameraProperty.MoveScene) {\r\n            return null;\r\n        }\r\n        return this._wheelXActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which movement axis (relative to the scene) the mouse wheel's Y axis\r\n     * controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelYMoveScene(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelYAction !== _CameraProperty.MoveScene) {\r\n            // Attempting to clear different _wheelYAction.\r\n            return;\r\n        }\r\n        this._wheelYAction = _CameraProperty.MoveScene;\r\n        this._wheelYActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured movement axis (relative to the scene) the mouse wheel's\r\n     * Y axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelYMoveScene(): Nullable<Coordinate> {\r\n        if (this._wheelYAction !== _CameraProperty.MoveScene) {\r\n            return null;\r\n        }\r\n        return this._wheelYActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Set which movement axis (relative to the scene) the mouse wheel's Z axis\r\n     * controls.\r\n     * @param axis The axis to be moved. Set null to clear.\r\n     */\r\n    @serialize()\r\n    public set wheelZMoveScene(axis: Nullable<Coordinate>) {\r\n        if (axis === null && this._wheelZAction !== _CameraProperty.MoveScene) {\r\n            // Attempting to clear different _wheelZAction.\r\n            return;\r\n        }\r\n        this._wheelZAction = _CameraProperty.MoveScene;\r\n        this._wheelZActionCoordinate = axis;\r\n    }\r\n\r\n    /**\r\n     * Get the configured movement axis (relative to the scene) the mouse wheel's\r\n     * Z axis controls.\r\n     * @returns The configured axis or null if none.\r\n     */\r\n    public get wheelZMoveScene(): Nullable<Coordinate> {\r\n        if (this._wheelZAction !== _CameraProperty.MoveScene) {\r\n            return null;\r\n        }\r\n        return this._wheelZActionCoordinate;\r\n    }\r\n\r\n    /**\r\n     * Called for each rendered frame.\r\n     */\r\n    public override checkInputs(): void {\r\n        if (this._wheelDeltaX === 0 && this._wheelDeltaY === 0 && this._wheelDeltaZ == 0) {\r\n            return;\r\n        }\r\n\r\n        // Clear the camera properties that we might be updating.\r\n        this._moveRelative.setAll(0);\r\n        this._rotateRelative.setAll(0);\r\n        this._moveScene.setAll(0);\r\n\r\n        // Set the camera properties that are to be updated.\r\n        this._updateCamera();\r\n\r\n        if (this.camera.getScene().useRightHandedSystem) {\r\n            // TODO: Does this need done for worldUpdate too?\r\n            this._moveRelative.z *= -1;\r\n        }\r\n\r\n        // Convert updates relative to camera to world position update.\r\n        const cameraTransformMatrix = Matrix.Zero();\r\n        this.camera.getViewMatrix().invertToRef(cameraTransformMatrix);\r\n\r\n        const transformedDirection = Vector3.Zero();\r\n        Vector3.TransformNormalToRef(this._moveRelative, cameraTransformMatrix, transformedDirection);\r\n\r\n        // Apply updates to camera position.\r\n        this.camera.cameraRotation.x += this._rotateRelative.x / 200;\r\n        this.camera.cameraRotation.y += this._rotateRelative.y / 200;\r\n        this.camera.cameraDirection.addInPlace(transformedDirection);\r\n        this.camera.cameraDirection.addInPlace(this._moveScene);\r\n\r\n        // Call the base class implementation to handle observers and do cleanup.\r\n        super.checkInputs();\r\n    }\r\n\r\n    private _moveRelative = Vector3.Zero();\r\n    private _rotateRelative = Vector3.Zero();\r\n    private _moveScene = Vector3.Zero();\r\n\r\n    /**\r\n     * These are set to the desired default behaviour.\r\n     */\r\n    private _wheelXAction: Nullable<_CameraProperty> = _CameraProperty.MoveRelative;\r\n    private _wheelXActionCoordinate: Nullable<Coordinate> = Coordinate.X;\r\n    private _wheelYAction: Nullable<_CameraProperty> = _CameraProperty.MoveRelative;\r\n    private _wheelYActionCoordinate: Nullable<Coordinate> = Coordinate.Z;\r\n    private _wheelZAction: Nullable<_CameraProperty> = null;\r\n    private _wheelZActionCoordinate: Nullable<Coordinate> = null;\r\n\r\n    /**\r\n     * Update the camera according to any configured properties for the 3\r\n     * mouse-wheel axis.\r\n     */\r\n    private _updateCamera(): void {\r\n        // Do the camera updates for each of the 3 touch-wheel axis.\r\n        this._updateCameraProperty(this._wheelDeltaX, this._wheelXAction, this._wheelXActionCoordinate);\r\n        this._updateCameraProperty(this._wheelDeltaY, this._wheelYAction, this._wheelYActionCoordinate);\r\n        this._updateCameraProperty(this._wheelDeltaZ, this._wheelZAction, this._wheelZActionCoordinate);\r\n    }\r\n\r\n    /**\r\n     * Update one property of the camera.\r\n     * @param value\r\n     * @param cameraProperty\r\n     * @param coordinate\r\n     */\r\n    private _updateCameraProperty(\r\n        /* Mouse-wheel delta. */\r\n        value: number,\r\n        /* Camera property to be changed. */\r\n        cameraProperty: Nullable<_CameraProperty>,\r\n        /* Axis of Camera property to be changed. */\r\n        coordinate: Nullable<Coordinate>\r\n    ): void {\r\n        if (value === 0) {\r\n            // Mouse wheel has not moved.\r\n            return;\r\n        }\r\n        if (cameraProperty === null || coordinate === null) {\r\n            // Mouse wheel axis not configured.\r\n            return;\r\n        }\r\n\r\n        let action = null;\r\n        switch (cameraProperty) {\r\n            case _CameraProperty.MoveRelative:\r\n                action = this._moveRelative;\r\n                break;\r\n            case _CameraProperty.RotateRelative:\r\n                action = this._rotateRelative;\r\n                break;\r\n            case _CameraProperty.MoveScene:\r\n                action = this._moveScene;\r\n                break;\r\n        }\r\n\r\n        switch (coordinate) {\r\n            case Coordinate.X:\r\n                action.set(value, 0, 0);\r\n                break;\r\n            case Coordinate.Y:\r\n                action.set(0, value, 0);\r\n                break;\r\n            case Coordinate.Z:\r\n                action.set(0, 0, value);\r\n                break;\r\n        }\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraMouseWheelInput\"] = FreeCameraMouseWheelInput;\r\n","import { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer, type EventState } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\n/**\r\n * Manage the touch inputs to control the movement of a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraTouchInput implements ICameraInput<FreeCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FreeCamera;\r\n\r\n    /**\r\n     * Defines the touch sensibility for rotation.\r\n     * The lower the faster.\r\n     */\r\n    @serialize()\r\n    public touchAngularSensibility: number = 200000.0;\r\n\r\n    /**\r\n     * Defines the touch sensibility for move.\r\n     * The lower the faster.\r\n     */\r\n    @serialize()\r\n    public touchMoveSensibility: number = 250.0;\r\n\r\n    /**\r\n     * Swap touch actions so that one touch is used for rotation and multiple for movement\r\n     */\r\n    public singleFingerRotate: boolean = false;\r\n\r\n    private _offsetX: Nullable<number> = null;\r\n    private _offsetY: Nullable<number> = null;\r\n\r\n    private _pointerPressed = new Array<number>();\r\n    private _pointerInput?: (p: PointerInfo, s: EventState) => void;\r\n    private _observer: Nullable<Observer<PointerInfo>>;\r\n    private _onLostFocus: Nullable<(e: FocusEvent) => any>;\r\n    private _isSafari: boolean;\r\n\r\n    /**\r\n     * Manage the touch inputs to control the movement of a free camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n     * @param allowMouse Defines if mouse events can be treated as touch events\r\n     */\r\n    constructor(\r\n        /**\r\n         * [false] Define if mouse events can be treated as touch events\r\n         */\r\n        public allowMouse = false\r\n    ) {\r\n        this._isSafari = Tools.IsSafari();\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        let previousPosition: Nullable<{ x: number; y: number }> = null;\r\n\r\n        if (this._pointerInput === undefined) {\r\n            this._onLostFocus = () => {\r\n                this._offsetX = null;\r\n                this._offsetY = null;\r\n            };\r\n\r\n            this._pointerInput = (p) => {\r\n                const evt = <IPointerEvent>p.event;\r\n\r\n                const isMouseEvent = evt.pointerType === \"mouse\" || (this._isSafari && typeof evt.pointerType === \"undefined\");\r\n\r\n                if (!this.allowMouse && isMouseEvent) {\r\n                    return;\r\n                }\r\n\r\n                if (p.type === PointerEventTypes.POINTERDOWN) {\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                    }\r\n\r\n                    this._pointerPressed.push(evt.pointerId);\r\n\r\n                    if (this._pointerPressed.length !== 1) {\r\n                        return;\r\n                    }\r\n\r\n                    previousPosition = {\r\n                        x: evt.clientX,\r\n                        y: evt.clientY,\r\n                    };\r\n                } else if (p.type === PointerEventTypes.POINTERUP) {\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                    }\r\n\r\n                    const index: number = this._pointerPressed.indexOf(evt.pointerId);\r\n\r\n                    if (index === -1) {\r\n                        return;\r\n                    }\r\n                    this._pointerPressed.splice(index, 1);\r\n\r\n                    if (index != 0) {\r\n                        return;\r\n                    }\r\n                    previousPosition = null;\r\n                    this._offsetX = null;\r\n                    this._offsetY = null;\r\n                } else if (p.type === PointerEventTypes.POINTERMOVE) {\r\n                    if (!noPreventDefault) {\r\n                        evt.preventDefault();\r\n                    }\r\n\r\n                    if (!previousPosition) {\r\n                        return;\r\n                    }\r\n\r\n                    const index: number = this._pointerPressed.indexOf(evt.pointerId);\r\n\r\n                    if (index != 0) {\r\n                        return;\r\n                    }\r\n\r\n                    this._offsetX = evt.clientX - previousPosition.x;\r\n                    this._offsetY = -(evt.clientY - previousPosition.y);\r\n                }\r\n            };\r\n        }\r\n\r\n        this._observer = this.camera\r\n            .getScene()\r\n            ._inputManager._addCameraPointerObserver(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);\r\n\r\n        if (this._onLostFocus) {\r\n            const engine = this.camera.getEngine();\r\n            const element = engine.getInputElement();\r\n            if (element) {\r\n                element.addEventListener(\"blur\", this._onLostFocus);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._pointerInput) {\r\n            if (this._observer) {\r\n                this.camera.getScene()._inputManager._removeCameraPointerObserver(this._observer);\r\n                this._observer = null;\r\n            }\r\n\r\n            if (this._onLostFocus) {\r\n                const engine = this.camera.getEngine();\r\n                const element = engine.getInputElement();\r\n                if (element) {\r\n                    element.removeEventListener(\"blur\", this._onLostFocus);\r\n                }\r\n\r\n                this._onLostFocus = null;\r\n            }\r\n            this._pointerPressed.length = 0;\r\n            this._offsetX = null;\r\n            this._offsetY = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._offsetX === null || this._offsetY === null) {\r\n            return;\r\n        }\r\n        if (this._offsetX === 0 && this._offsetY === 0) {\r\n            return;\r\n        }\r\n\r\n        const camera = this.camera;\r\n        // Touch look (yaw/pitch) is gated on touch→rotate and the forward drag-move on\r\n        // touch→translate. Removing an entry disables that touch behavior. An entry's optional\r\n        // `sensitivity` replaces the legacy 1/touchAngularSensibility (rotate) or\r\n        // 1/touchMoveSensibility (translate) scale factor.\r\n        const input = camera.movement.input;\r\n        const rotateEntry = input.getEntry(\"touch\", \"rotate\");\r\n        const translateEntry = input.getEntry(\"touch\", \"translate\");\r\n        const handednessMultiplier = camera._calculateHandednessMultiplier();\r\n\r\n        const rotateCamera = (this.singleFingerRotate && this._pointerPressed.length === 1) || (!this.singleFingerRotate && this._pointerPressed.length > 1);\r\n\r\n        if (rotateEntry) {\r\n            const rotateSensitivity = rotateEntry.sensitivity ?? 1 / this.touchAngularSensibility;\r\n            camera.cameraRotation.y = this._offsetX * handednessMultiplier * rotateSensitivity;\r\n            if (rotateCamera) {\r\n                camera.cameraRotation.x = -(this._offsetY * handednessMultiplier) * rotateSensitivity;\r\n            }\r\n        }\r\n\r\n        if (!rotateCamera && translateEntry) {\r\n            const speed = camera._computeLocalCameraSpeed();\r\n            const moveSensitivity = translateEntry.sensitivity ?? (this.touchMoveSensibility !== 0 ? 1 / this.touchMoveSensibility : 0);\r\n            const direction = TmpVectors.Vector3[0];\r\n            direction.copyFromFloats(0, 0, speed * this._offsetY * moveSensitivity);\r\n\r\n            Matrix.RotationYawPitchRollToRef(camera.rotation.y, camera.rotation.x, 0, camera._cameraRotationMatrix);\r\n            Vector3.TransformCoordinatesToRef(direction, camera._cameraRotationMatrix, direction);\r\n            camera.cameraDirection.addInPlace(direction);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FreeCameraTouchInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"touch\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraTouchInput\"] = FreeCameraTouchInput;\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FreeCamera } from \"./freeCamera.pure\";\r\nimport { CameraInputsManager } from \"./cameraInputsManager\";\r\nimport { FreeCameraKeyboardMoveInput } from \"../Cameras/Inputs/freeCameraKeyboardMoveInput\";\r\nimport { FreeCameraMouseInput } from \"../Cameras/Inputs/freeCameraMouseInput\";\r\nimport { FreeCameraMouseWheelInput } from \"../Cameras/Inputs/freeCameraMouseWheelInput\";\r\nimport { FreeCameraTouchInput } from \"../Cameras/Inputs/freeCameraTouchInput\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * Default Inputs manager for the FreeCamera.\r\n * It groups all the default supported inputs for ease of use.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraInputsManager extends CameraInputsManager<FreeCamera> {\r\n    /**\r\n     * @internal\r\n     */\r\n    public _mouseInput: Nullable<FreeCameraMouseInput> = null;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _mouseWheelInput: Nullable<FreeCameraMouseWheelInput> = null;\r\n    /**\r\n     * Instantiates a new FreeCameraInputsManager.\r\n     * @param camera Defines the camera the inputs belong to\r\n     */\r\n    constructor(camera: FreeCamera) {\r\n        super(camera);\r\n    }\r\n\r\n    /**\r\n     * Add keyboard input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    addKeyboard(): FreeCameraInputsManager {\r\n        this.add(new FreeCameraKeyboardMoveInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add mouse input support to the input manager.\r\n     * @param touchEnabled if the FreeCameraMouseInput should support touch (default: true)\r\n     * @returns the current input manager\r\n     */\r\n    addMouse(touchEnabled = true): FreeCameraInputsManager {\r\n        if (!this._mouseInput) {\r\n            this._mouseInput = new FreeCameraMouseInput(touchEnabled);\r\n            this.add(this._mouseInput);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Removes the mouse input support from the manager\r\n     * @returns the current input manager\r\n     */\r\n    removeMouse(): FreeCameraInputsManager {\r\n        if (this._mouseInput) {\r\n            this.remove(this._mouseInput);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add mouse wheel input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    addMouseWheel(): FreeCameraInputsManager {\r\n        if (!this._mouseWheelInput) {\r\n            this._mouseWheelInput = new FreeCameraMouseWheelInput();\r\n            this.add(this._mouseWheelInput);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Removes the mouse wheel input support from the manager\r\n     * @returns the current input manager\r\n     */\r\n    removeMouseWheel(): FreeCameraInputsManager {\r\n        if (this._mouseWheelInput) {\r\n            this.remove(this._mouseWheelInput);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add touch input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    addTouch(): FreeCameraInputsManager {\r\n        this.add(new FreeCameraTouchInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove all attached input methods from a camera\r\n     */\r\n    public override clear(): void {\r\n        super.clear();\r\n        this._mouseInput = null;\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffect } from \"../Misc/devTools\";\r\n\r\nFreeCameraInputsManager.prototype.addDeviceOrientation ??= _MissingSideEffect(\"FreeCameraInputsManager\", \"addDeviceOrientation\") as any;\r\nFreeCameraInputsManager.prototype.addVirtualJoystick ??= _MissingSideEffect(\"FreeCameraInputsManager\", \"addVirtualJoystick\") as any;\r\nFreeCameraInputsManager.prototype.addGamepad ??= _MissingSideEffect(\"FreeCameraInputsManager\", \"addGamepad\") as any;\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { CameraInputTypes, type ICameraInput } from \"../../Cameras/cameraInputsManager\";\r\n\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera.pure\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\n\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { FreeCameraInputsManager } from \"../../Cameras/freeCameraInputsManager.pure\";\r\n\r\n/**\r\n * Takes information about the orientation of the device as reported by the deviceorientation event to orient the camera.\r\n * Screen rotation is taken into account.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraDeviceOrientationInput implements ICameraInput<FreeCamera> {\r\n    private _camera: FreeCamera;\r\n\r\n    private _screenOrientationAngle: number = 0;\r\n\r\n    private _constantTransform: Quaternion;\r\n    private _screenQuaternion: Quaternion = new Quaternion();\r\n\r\n    private _alpha: number = 0;\r\n    private _beta: number = 0;\r\n    private _gamma: number = 0;\r\n\r\n    /** alpha+beta+gamma smoothing. 0: no smoothing, 1: new data ignored, 0.9 recommended for smoothing */\r\n    public smoothFactor: number = 0;\r\n\r\n    /**\r\n     * Can be used to detect if a device orientation sensor is available on a device\r\n     * @param timeout amount of time in milliseconds to wait for a response from the sensor (default: infinite)\r\n     * @returns a promise that will resolve on orientation change\r\n     */\r\n    public static async WaitForOrientationChangeAsync(timeout?: number): Promise<void> {\r\n        return await new Promise((res, rej) => {\r\n            let gotValue = false;\r\n            const eventHandler = () => {\r\n                window.removeEventListener(\"deviceorientation\", eventHandler);\r\n                gotValue = true;\r\n                res();\r\n            };\r\n\r\n            // If timeout is populated reject the promise\r\n            if (timeout) {\r\n                setTimeout(() => {\r\n                    if (!gotValue) {\r\n                        window.removeEventListener(\"deviceorientation\", eventHandler);\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        rej(\"WaitForOrientationChangeAsync timed out\");\r\n                    }\r\n                }, timeout);\r\n            }\r\n\r\n            if (typeof DeviceOrientationEvent !== \"undefined\" && typeof (<any>DeviceOrientationEvent).requestPermission === \"function\") {\r\n                (<any>DeviceOrientationEvent)\r\n                    .requestPermission()\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((response: string) => {\r\n                        if (response == \"granted\") {\r\n                            window.addEventListener(\"deviceorientation\", eventHandler);\r\n                        } else {\r\n                            Logger.Warn(\"Permission not granted.\");\r\n                        }\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((error: any) => {\r\n                        Logger.Error(error);\r\n                    });\r\n            } else {\r\n                window.addEventListener(\"deviceorientation\", eventHandler);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _onDeviceOrientationChangedObservable = new Observable<void>();\r\n    /**\r\n     * Instantiates a new input\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n     */\r\n    constructor() {\r\n        this._constantTransform = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\r\n        this._orientationChanged();\r\n    }\r\n\r\n    /**\r\n     * Define the camera controlled by the input.\r\n     */\r\n    public get camera(): FreeCamera {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(camera: FreeCamera) {\r\n        this._camera = camera;\r\n        if (this._camera != null && !this._camera.rotationQuaternion) {\r\n            this._camera.rotationQuaternion = new Quaternion();\r\n        }\r\n        if (this._camera) {\r\n            this._camera.onDisposeObservable.add(() => {\r\n                this._onDeviceOrientationChangedObservable.clear();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     */\r\n    public attachControl(): void {\r\n        const hostWindow = this.camera.getScene().getEngine().getHostWindow();\r\n\r\n        if (hostWindow) {\r\n            const eventHandler = () => {\r\n                hostWindow.addEventListener(\"orientationchange\", this._orientationChanged);\r\n                hostWindow.addEventListener(\"deviceorientation\", this._deviceOrientation);\r\n                //In certain cases, the attach control is called AFTER orientation was changed,\r\n                //So this is needed.\r\n                this._orientationChanged();\r\n            };\r\n            if (typeof DeviceOrientationEvent !== \"undefined\" && typeof (<any>DeviceOrientationEvent).requestPermission === \"function\") {\r\n                (<any>DeviceOrientationEvent)\r\n                    .requestPermission()\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((response: string) => {\r\n                        if (response === \"granted\") {\r\n                            eventHandler();\r\n                        } else {\r\n                            Logger.Warn(\"Permission not granted.\");\r\n                        }\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((error: any) => {\r\n                        Logger.Error(error);\r\n                    });\r\n            } else {\r\n                eventHandler();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _orientationChanged = () => {\r\n        this._screenOrientationAngle =\r\n            <any>window.orientation !== undefined\r\n                ? +(<any>window.orientation)\r\n                : (<any>window.screen).orientation && (<any>window.screen).orientation[\"angle\"]\r\n                  ? (<any>window.screen).orientation.angle\r\n                  : 0;\r\n        this._screenOrientationAngle = -(this._screenOrientationAngle / 2) * (Math.PI / 180);\r\n        this._screenQuaternion.copyFromFloats(0, Math.sin(this._screenOrientationAngle), 0, Math.cos(this._screenOrientationAngle));\r\n    };\r\n\r\n    private _deviceOrientation = (evt: DeviceOrientationEvent) => {\r\n        if (this.smoothFactor) {\r\n            this._alpha = evt.alpha !== null ? Tools.SmoothAngleChange(this._alpha, evt.alpha, this.smoothFactor) : 0;\r\n            this._beta = evt.beta !== null ? Tools.SmoothAngleChange(this._beta, evt.beta, this.smoothFactor) : 0;\r\n            this._gamma = evt.gamma !== null ? Tools.SmoothAngleChange(this._gamma, evt.gamma, this.smoothFactor) : 0;\r\n        } else {\r\n            this._alpha = evt.alpha !== null ? evt.alpha : 0;\r\n            this._beta = evt.beta !== null ? evt.beta : 0;\r\n            this._gamma = evt.gamma !== null ? evt.gamma : 0;\r\n        }\r\n\r\n        if (evt.alpha !== null) {\r\n            this._onDeviceOrientationChangedObservable.notifyObservers();\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        window.removeEventListener(\"orientationchange\", this._orientationChanged);\r\n        window.removeEventListener(\"deviceorientation\", this._deviceOrientation);\r\n        this._alpha = 0;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        // if no device orientation provided, don't update the rotation.\r\n        // Only testing against alpha under the assumption that orientation will never be so exact when set.\r\n        if (!this._alpha) {\r\n            return;\r\n        }\r\n        if (this._camera.rotationQuaternion) {\r\n            Quaternion.RotationYawPitchRollToRef(this._alpha * (Math.PI / 180), this._beta * (Math.PI / 180), -this._gamma * (Math.PI / 180), this._camera.rotationQuaternion);\r\n\r\n            this._camera.rotationQuaternion.multiplyInPlace(this._screenQuaternion);\r\n            this._camera.rotationQuaternion.multiplyInPlace(this._constantTransform);\r\n            if (this._camera.getScene().useRightHandedSystem) {\r\n                this._camera.rotationQuaternion.y *= -1;\r\n            } else {\r\n                this._camera.rotationQuaternion.z *= -1;\r\n            }\r\n            this._camera.rotationQuaternion.w *= -1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FreeCameraDeviceOrientationInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"deviceOrientation\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraDeviceOrientationInput\"] = FreeCameraDeviceOrientationInput;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for freeCameraDeviceOrientationInput.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFreeCameraDeviceOrientationInput(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Add orientation input support to the input manager.\r\n     * @param smoothFactor deviceOrientation smoothing. 0: no smoothing, 1: new data ignored, 0.9 recommended for smoothing\r\n     * @returns the current input manager\r\n     */\r\n    FreeCameraInputsManager.prototype.addDeviceOrientation = function (smoothFactor?: number): FreeCameraInputsManager {\r\n        if (!this._deviceOrientationInput) {\r\n            this._deviceOrientationInput = new FreeCameraDeviceOrientationInput();\r\n            if (smoothFactor) {\r\n                this._deviceOrientationInput.smoothFactor = smoothFactor;\r\n            }\r\n            this.add(this._deviceOrientationInput);\r\n        }\r\n\r\n        return this;\r\n    };\r\n}\r\n","import { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { Matrix, Vector3, Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { Gamepad } from \"../../Gamepads/gamepad\";\r\n\r\n/**\r\n * Manage the gamepad inputs to control a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraGamepadInput implements ICameraInput<FreeCamera> {\r\n    /**\r\n     * Define the camera the input is attached to.\r\n     */\r\n    public camera: FreeCamera;\r\n\r\n    /**\r\n     * Define the Gamepad controlling the input\r\n     */\r\n    public gamepad: Nullable<Gamepad>;\r\n\r\n    /**\r\n     * Defines the gamepad rotation sensibility.\r\n     * This is the threshold from when rotation starts to be accounted for to prevent jittering.\r\n     */\r\n    @serialize()\r\n    public gamepadAngularSensibility = 200;\r\n\r\n    /**\r\n     * Defines the gamepad move sensibility.\r\n     * This is the threshold from when moving starts to be accounted for for to prevent jittering.\r\n     */\r\n    @serialize()\r\n    public gamepadMoveSensibility = 40;\r\n\r\n    /**\r\n     * Defines the minimum value at which any analog stick input is ignored.\r\n     * Note: This value should only be a value between 0 and 1.\r\n     */\r\n    public deadzoneDelta = 0.1;\r\n\r\n    private _yAxisScale = 1.0;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that Yaxis (for right stick) should be inverted\r\n     */\r\n    public get invertYAxis() {\r\n        return this._yAxisScale !== 1.0;\r\n    }\r\n\r\n    public set invertYAxis(value: boolean) {\r\n        this._yAxisScale = value ? -1.0 : 1.0;\r\n    }\r\n\r\n    // private members\r\n    private _onGamepadConnectedObserver: Nullable<Observer<Gamepad>>;\r\n    private _onGamepadDisconnectedObserver: Nullable<Observer<Gamepad>>;\r\n    private _cameraTransform: Matrix = Matrix.Identity();\r\n    private _deltaTransform: Vector3 = Vector3.Zero();\r\n    private _vector3: Vector3 = Vector3.Zero();\r\n    private _vector2: Vector2 = Vector2.Zero();\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     */\r\n    public attachControl(): void {\r\n        const manager = this.camera.getScene().gamepadManager;\r\n        this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add((gamepad) => {\r\n            if (gamepad.type !== Gamepad.POSE_ENABLED) {\r\n                // prioritize XBOX gamepads.\r\n                if (!this.gamepad || gamepad.type === Gamepad.XBOX) {\r\n                    this.gamepad = gamepad;\r\n                }\r\n            }\r\n        });\r\n\r\n        this._onGamepadDisconnectedObserver = manager.onGamepadDisconnectedObservable.add((gamepad) => {\r\n            if (this.gamepad === gamepad) {\r\n                this.gamepad = null;\r\n            }\r\n        });\r\n\r\n        // check if there are already other controllers connected\r\n        this.gamepad = manager.getGamepadByType(Gamepad.XBOX);\r\n        // if no xbox controller was found, but there are gamepad controllers, take the first one\r\n        if (!this.gamepad && manager.gamepads.length) {\r\n            this.gamepad = manager.gamepads[0];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        this.camera.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);\r\n        this.camera.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);\r\n        this.gamepad = null;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this.gamepad && this.gamepad.leftStick) {\r\n            const camera = this.camera;\r\n            const lsValues = this.gamepad.leftStick;\r\n            if (this.gamepadMoveSensibility !== 0) {\r\n                lsValues.x = Math.abs(lsValues.x) > this.deadzoneDelta ? lsValues.x / this.gamepadMoveSensibility : 0;\r\n                lsValues.y = Math.abs(lsValues.y) > this.deadzoneDelta ? lsValues.y / this.gamepadMoveSensibility : 0;\r\n            }\r\n\r\n            let rsValues = this.gamepad.rightStick;\r\n            if (rsValues && this.gamepadAngularSensibility !== 0) {\r\n                rsValues.x = Math.abs(rsValues.x) > this.deadzoneDelta ? rsValues.x / this.gamepadAngularSensibility : 0;\r\n                rsValues.y = (Math.abs(rsValues.y) > this.deadzoneDelta ? rsValues.y / this.gamepadAngularSensibility : 0) * this._yAxisScale;\r\n            } else {\r\n                rsValues = { x: 0, y: 0 };\r\n            }\r\n\r\n            if (!camera.rotationQuaternion) {\r\n                Matrix.RotationYawPitchRollToRef(camera.rotation.y, camera.rotation.x, 0, this._cameraTransform);\r\n            } else {\r\n                camera.rotationQuaternion.toRotationMatrix(this._cameraTransform);\r\n            }\r\n\r\n            const speed = camera._computeLocalCameraSpeed() * 50.0;\r\n            this._vector3.copyFromFloats(lsValues.x * speed, 0, -lsValues.y * speed);\r\n\r\n            Vector3.TransformCoordinatesToRef(this._vector3, this._cameraTransform, this._deltaTransform);\r\n            camera.cameraDirection.addInPlace(this._deltaTransform);\r\n            this._vector2.copyFromFloats(rsValues.y, rsValues.x);\r\n            camera.cameraRotation.addInPlace(this._vector2);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FreeCameraGamepadInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"gamepad\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraGamepadInput\"] = FreeCameraGamepadInput;\r\n","import { type Nullable } from \"../types\";\r\nimport { Vector3, Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { StringDictionary } from \"./stringDictionary\";\r\n\r\n// Mainly based on these 2 articles :\r\n// Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS : http://blogs.msdn.com/b/davrous/archive/2013/02/22/creating-an-universal-virtual-touch-joystick-working-for-all-touch-models-thanks-to-hand-js.aspx\r\n// & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/\r\n\r\n/**\r\n * Defines the potential axis of a Joystick\r\n */\r\nexport const enum JoystickAxis {\r\n    /** X axis */\r\n    X,\r\n    /** Y axis */\r\n    Y,\r\n    /** Z axis */\r\n    Z,\r\n}\r\n\r\n/**\r\n * Represents the different customization options available\r\n * for VirtualJoystick\r\n */\r\ninterface IVirtualJoystickCustomizations {\r\n    /**\r\n     * Size of the joystick's puck\r\n     */\r\n    puckSize: number;\r\n    /**\r\n     * Size of the joystick's container\r\n     */\r\n    containerSize: number;\r\n    /**\r\n     * Color of the joystick && puck\r\n     */\r\n    color: string;\r\n    /**\r\n     * Image URL for the joystick's puck\r\n     */\r\n    puckImage?: string;\r\n    /**\r\n     * Image URL for the joystick's container\r\n     */\r\n    containerImage?: string;\r\n    /**\r\n     * Defines the unmoving position of the joystick container\r\n     */\r\n    position?: { x: number; y: number };\r\n    /**\r\n     * Defines whether or not the joystick container is always visible\r\n     */\r\n    alwaysVisible: boolean;\r\n    /**\r\n     * Defines whether or not to limit the movement of the puck to the joystick's container\r\n     */\r\n    limitToContainer: boolean;\r\n}\r\n\r\n/**\r\n * Class used to define virtual joystick (used in touch mode)\r\n */\r\nexport class VirtualJoystick {\r\n    /**\r\n     * Gets or sets a boolean indicating that left and right values must be inverted\r\n     */\r\n    public reverseLeftRight: boolean;\r\n    /**\r\n     * Gets or sets a boolean indicating that up and down values must be inverted\r\n     */\r\n    public reverseUpDown: boolean;\r\n    /**\r\n     * Gets the offset value for the position (ie. the change of the position value)\r\n     */\r\n    public deltaPosition: Vector3;\r\n    /**\r\n     * Gets a boolean indicating if the virtual joystick was pressed\r\n     */\r\n    public pressed: boolean;\r\n    /**\r\n     * Canvas the virtual joystick will render onto, default z-index of this is 5\r\n     */\r\n    public static Canvas: Nullable<HTMLCanvasElement>;\r\n\r\n    /**\r\n     * boolean indicating whether or not the joystick's puck's movement should be limited to the joystick's container area\r\n     */\r\n    public limitToContainer: boolean;\r\n\r\n    // Used to draw the virtual joystick inside a 2D canvas on top of the WebGL rendering canvas\r\n    private static _GlobalJoystickIndex: number = 0;\r\n    private static _AlwaysVisibleSticks: number = 0;\r\n    private static _VjCanvasContext: CanvasRenderingContext2D;\r\n    private static _VjCanvasWidth: number;\r\n    private static _VjCanvasHeight: number;\r\n    private static _HalfWidth: number;\r\n    private static _GetDefaultOptions(): IVirtualJoystickCustomizations {\r\n        return {\r\n            puckSize: 40,\r\n            containerSize: 60,\r\n            color: \"cyan\",\r\n            puckImage: undefined,\r\n            containerImage: undefined,\r\n            position: undefined,\r\n            alwaysVisible: false,\r\n            limitToContainer: false,\r\n        };\r\n    }\r\n\r\n    private _action: () => any;\r\n    private _axisTargetedByLeftAndRight: JoystickAxis;\r\n    private _axisTargetedByUpAndDown: JoystickAxis;\r\n    private _joystickSensibility: number;\r\n    private _inversedSensibility: number;\r\n    private _joystickPointerId: number;\r\n    private _joystickColor: string;\r\n    private _joystickPointerPos: Vector2;\r\n    private _joystickPreviousPointerPos: Vector2;\r\n    private _joystickPointerStartPos: Vector2;\r\n    private _deltaJoystickVector: Vector2;\r\n    private _leftJoystick: boolean;\r\n    private _touches: StringDictionary<{ x: number; y: number; prevX: number; prevY: number } | PointerEvent>;\r\n    private _joystickPosition: Nullable<Vector2>;\r\n    private _alwaysVisible: boolean;\r\n    private _puckImage: HTMLImageElement;\r\n    private _containerImage: HTMLImageElement;\r\n    private _released = false;\r\n\r\n    // size properties\r\n    private _joystickPuckSize: number;\r\n    private _joystickContainerSize: number;\r\n    private _clearPuckSize: number;\r\n    private _clearContainerSize: number;\r\n    private _clearPuckSizeOffset: number;\r\n    private _clearContainerSizeOffset: number;\r\n\r\n    private _onPointerDownHandlerRef: (e: PointerEvent) => any;\r\n    private _onPointerMoveHandlerRef: (e: PointerEvent) => any;\r\n    private _onPointerUpHandlerRef: (e: PointerEvent) => any;\r\n    private _onResize: (e: any) => any;\r\n\r\n    /**\r\n     * Creates a new virtual joystick\r\n     * @param leftJoystick defines that the joystick is for left hand (false by default)\r\n     * @param customizations Defines the options we want to customize the VirtualJoystick\r\n     */\r\n    constructor(leftJoystick?: boolean, customizations?: Partial<IVirtualJoystickCustomizations>) {\r\n        const options = {\r\n            ...VirtualJoystick._GetDefaultOptions(),\r\n            ...customizations,\r\n        };\r\n\r\n        if (leftJoystick) {\r\n            this._leftJoystick = true;\r\n        } else {\r\n            this._leftJoystick = false;\r\n        }\r\n\r\n        VirtualJoystick._GlobalJoystickIndex++;\r\n\r\n        // By default left & right arrow keys are moving the X\r\n        // and up & down keys are moving the Y\r\n        this._axisTargetedByLeftAndRight = JoystickAxis.X;\r\n        this._axisTargetedByUpAndDown = JoystickAxis.Y;\r\n\r\n        this.reverseLeftRight = false;\r\n        this.reverseUpDown = false;\r\n\r\n        // collections of pointers\r\n        this._touches = new StringDictionary<{ x: number; y: number; prevX: number; prevY: number } | PointerEvent>();\r\n        this.deltaPosition = Vector3.Zero();\r\n\r\n        this._joystickSensibility = 25;\r\n        this._inversedSensibility = 1 / (this._joystickSensibility / 1000);\r\n\r\n        this._onResize = () => {\r\n            VirtualJoystick._VjCanvasWidth = window.innerWidth;\r\n            VirtualJoystick._VjCanvasHeight = window.innerHeight;\r\n            if (VirtualJoystick.Canvas) {\r\n                VirtualJoystick.Canvas.width = VirtualJoystick._VjCanvasWidth;\r\n                VirtualJoystick.Canvas.height = VirtualJoystick._VjCanvasHeight;\r\n            }\r\n            VirtualJoystick._HalfWidth = VirtualJoystick._VjCanvasWidth / 2;\r\n        };\r\n\r\n        // injecting a canvas element on top of the canvas 3D game\r\n        if (!VirtualJoystick.Canvas) {\r\n            window.addEventListener(\"resize\", this._onResize, false);\r\n            VirtualJoystick.Canvas = document.createElement(\"canvas\");\r\n            VirtualJoystick._VjCanvasWidth = window.innerWidth;\r\n            VirtualJoystick._VjCanvasHeight = window.innerHeight;\r\n            VirtualJoystick.Canvas.width = window.innerWidth;\r\n            VirtualJoystick.Canvas.height = window.innerHeight;\r\n            VirtualJoystick.Canvas.style.width = \"100%\";\r\n            VirtualJoystick.Canvas.style.height = \"100%\";\r\n            VirtualJoystick.Canvas.style.position = \"absolute\";\r\n            VirtualJoystick.Canvas.style.backgroundColor = \"transparent\";\r\n            VirtualJoystick.Canvas.style.top = \"0px\";\r\n            VirtualJoystick.Canvas.style.left = \"0px\";\r\n            VirtualJoystick.Canvas.style.zIndex = \"5\";\r\n            VirtualJoystick.Canvas.style.touchAction = \"none\"; // fix https://forum.babylonjs.com/t/virtualjoystick-needs-to-set-style-touch-action-none-explicitly/9562\r\n            // Support for jQuery PEP polyfill\r\n            VirtualJoystick.Canvas.setAttribute(\"touch-action\", \"none\");\r\n            const context = VirtualJoystick.Canvas.getContext(\"2d\");\r\n\r\n            if (!context) {\r\n                throw new Error(\"Unable to create canvas for virtual joystick\");\r\n            }\r\n\r\n            VirtualJoystick._VjCanvasContext = context;\r\n            VirtualJoystick._VjCanvasContext.strokeStyle = \"#ffffff\";\r\n            VirtualJoystick._VjCanvasContext.lineWidth = 2;\r\n            document.body.appendChild(VirtualJoystick.Canvas);\r\n        }\r\n        VirtualJoystick._HalfWidth = VirtualJoystick.Canvas.width / 2;\r\n        this.pressed = false;\r\n        this.limitToContainer = options.limitToContainer;\r\n\r\n        // default joystick color\r\n        this._joystickColor = options.color;\r\n\r\n        // default joystick size\r\n        this.containerSize = options.containerSize;\r\n        this.puckSize = options.puckSize;\r\n\r\n        if (options.position) {\r\n            this.setPosition(options.position.x, options.position.y);\r\n        }\r\n        if (options.puckImage) {\r\n            this.setPuckImage(options.puckImage);\r\n        }\r\n        if (options.containerImage) {\r\n            this.setContainerImage(options.containerImage);\r\n        }\r\n        if (options.alwaysVisible) {\r\n            VirtualJoystick._AlwaysVisibleSticks++;\r\n        }\r\n\r\n        // must come after position potentially set\r\n        this.alwaysVisible = options.alwaysVisible;\r\n\r\n        this._joystickPointerId = -1;\r\n        // current joystick position\r\n        this._joystickPointerPos = new Vector2(0, 0);\r\n        this._joystickPreviousPointerPos = new Vector2(0, 0);\r\n        // origin joystick position\r\n        this._joystickPointerStartPos = new Vector2(0, 0);\r\n        this._deltaJoystickVector = new Vector2(0, 0);\r\n\r\n        this._onPointerDownHandlerRef = (evt) => {\r\n            this._onPointerDown(evt);\r\n        };\r\n        this._onPointerMoveHandlerRef = (evt) => {\r\n            this._onPointerMove(evt);\r\n        };\r\n        this._onPointerUpHandlerRef = (evt) => {\r\n            this._onPointerUp(evt);\r\n        };\r\n\r\n        VirtualJoystick.Canvas.addEventListener(\"pointerdown\", this._onPointerDownHandlerRef, false);\r\n        VirtualJoystick.Canvas.addEventListener(\"pointermove\", this._onPointerMoveHandlerRef, false);\r\n        VirtualJoystick.Canvas.addEventListener(\"pointerup\", this._onPointerUpHandlerRef, false);\r\n        VirtualJoystick.Canvas.addEventListener(\"pointerout\", this._onPointerUpHandlerRef, false);\r\n        VirtualJoystick.Canvas.addEventListener(\"pointercancel\", this._onPointerUpHandlerRef, false);\r\n        VirtualJoystick.Canvas.addEventListener(\r\n            \"contextmenu\",\r\n            (evt) => {\r\n                evt.preventDefault(); // Disables system menu\r\n            },\r\n            false\r\n        );\r\n        requestAnimationFrame(() => {\r\n            this._drawVirtualJoystick();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Defines joystick sensibility (ie. the ratio between a physical move and virtual joystick position change)\r\n     * @param newJoystickSensibility defines the new sensibility\r\n     */\r\n    public setJoystickSensibility(newJoystickSensibility: number) {\r\n        this._joystickSensibility = newJoystickSensibility;\r\n        this._inversedSensibility = 1 / (this._joystickSensibility / 1000);\r\n    }\r\n\r\n    private _onPointerDown(e: PointerEvent) {\r\n        let positionOnScreenCondition: boolean;\r\n\r\n        e.preventDefault();\r\n\r\n        if (this._leftJoystick === true) {\r\n            positionOnScreenCondition = e.clientX < VirtualJoystick._HalfWidth;\r\n        } else {\r\n            positionOnScreenCondition = e.clientX > VirtualJoystick._HalfWidth;\r\n        }\r\n\r\n        if (positionOnScreenCondition && this._joystickPointerId < 0) {\r\n            // First contact will be dedicated to the virtual joystick\r\n            this._joystickPointerId = e.pointerId;\r\n\r\n            if (this._joystickPosition) {\r\n                this._joystickPointerStartPos = this._joystickPosition.clone();\r\n                this._joystickPointerPos = this._joystickPosition.clone();\r\n                this._joystickPreviousPointerPos = this._joystickPosition.clone();\r\n\r\n                // in case the user only clicks down && doesn't move:\r\n                // this ensures the delta is properly set\r\n                this._onPointerMove(e);\r\n            } else {\r\n                this._joystickPointerStartPos.x = e.clientX;\r\n                this._joystickPointerStartPos.y = e.clientY;\r\n                this._joystickPointerPos = this._joystickPointerStartPos.clone();\r\n                this._joystickPreviousPointerPos = this._joystickPointerStartPos.clone();\r\n            }\r\n\r\n            this._deltaJoystickVector.x = 0;\r\n            this._deltaJoystickVector.y = 0;\r\n            this.pressed = true;\r\n            this._touches.add(e.pointerId.toString(), e);\r\n        } else {\r\n            // You can only trigger the action buttons with a joystick declared\r\n            if (VirtualJoystick._GlobalJoystickIndex < 2 && this._action) {\r\n                this._action();\r\n                this._touches.add(e.pointerId.toString(), { x: e.clientX, y: e.clientY, prevX: e.clientX, prevY: e.clientY });\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onPointerMove(e: PointerEvent) {\r\n        // If the current pointer is the one associated to the joystick (first touch contact)\r\n        if (this._joystickPointerId == e.pointerId) {\r\n            // limit to container if need be\r\n            if (this.limitToContainer) {\r\n                const vector = new Vector2(e.clientX - this._joystickPointerStartPos.x, e.clientY - this._joystickPointerStartPos.y);\r\n                const distance = vector.length();\r\n\r\n                if (distance > this.containerSize) {\r\n                    vector.scaleInPlace(this.containerSize / distance);\r\n                }\r\n\r\n                this._joystickPointerPos.x = this._joystickPointerStartPos.x + vector.x;\r\n                this._joystickPointerPos.y = this._joystickPointerStartPos.y + vector.y;\r\n            } else {\r\n                this._joystickPointerPos.x = e.clientX;\r\n                this._joystickPointerPos.y = e.clientY;\r\n            }\r\n\r\n            // create delta vector\r\n            this._deltaJoystickVector = this._joystickPointerPos.clone();\r\n            this._deltaJoystickVector = this._deltaJoystickVector.subtract(this._joystickPointerStartPos);\r\n\r\n            // if a joystick is always visible, there will be clipping issues if\r\n            // you drag the puck from one over the container of the other\r\n            if (0 < VirtualJoystick._AlwaysVisibleSticks) {\r\n                if (this._leftJoystick) {\r\n                    this._joystickPointerPos.x = Math.min(VirtualJoystick._HalfWidth, this._joystickPointerPos.x);\r\n                } else {\r\n                    this._joystickPointerPos.x = Math.max(VirtualJoystick._HalfWidth, this._joystickPointerPos.x);\r\n                }\r\n            }\r\n\r\n            const directionLeftRight = this.reverseLeftRight ? -1 : 1;\r\n            const deltaJoystickX = (directionLeftRight * this._deltaJoystickVector.x) / this._inversedSensibility;\r\n            switch (this._axisTargetedByLeftAndRight) {\r\n                case JoystickAxis.X:\r\n                    this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickX));\r\n                    break;\r\n                case JoystickAxis.Y:\r\n                    this.deltaPosition.y = Math.min(1, Math.max(-1, deltaJoystickX));\r\n                    break;\r\n                case JoystickAxis.Z:\r\n                    this.deltaPosition.z = Math.min(1, Math.max(-1, deltaJoystickX));\r\n                    break;\r\n            }\r\n            const directionUpDown = this.reverseUpDown ? 1 : -1;\r\n            const deltaJoystickY = (directionUpDown * this._deltaJoystickVector.y) / this._inversedSensibility;\r\n            switch (this._axisTargetedByUpAndDown) {\r\n                case JoystickAxis.X:\r\n                    this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickY));\r\n                    break;\r\n                case JoystickAxis.Y:\r\n                    this.deltaPosition.y = Math.min(1, Math.max(-1, deltaJoystickY));\r\n                    break;\r\n                case JoystickAxis.Z:\r\n                    this.deltaPosition.z = Math.min(1, Math.max(-1, deltaJoystickY));\r\n                    break;\r\n            }\r\n        } else {\r\n            const data = this._touches.get(e.pointerId.toString());\r\n            if (data) {\r\n                (data as any).x = e.clientX;\r\n                (data as any).y = e.clientY;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onPointerUp(e: PointerEvent) {\r\n        if (this._joystickPointerId == e.pointerId) {\r\n            this._clearPreviousDraw();\r\n\r\n            this._joystickPointerId = -1;\r\n            this.pressed = false;\r\n        } else {\r\n            const touch = <{ x: number; y: number; prevX: number; prevY: number }>this._touches.get(e.pointerId.toString());\r\n            if (touch) {\r\n                VirtualJoystick._VjCanvasContext.clearRect(touch.prevX - 44, touch.prevY - 44, 88, 88);\r\n            }\r\n        }\r\n        this._deltaJoystickVector.x = 0;\r\n        this._deltaJoystickVector.y = 0;\r\n\r\n        this._touches.remove(e.pointerId.toString());\r\n    }\r\n\r\n    /**\r\n     * Change the color of the virtual joystick\r\n     * @param newColor a string that must be a CSS color value (like \"red\") or the hexa value (like \"#FF0000\")\r\n     */\r\n    public setJoystickColor(newColor: string) {\r\n        this._joystickColor = newColor;\r\n    }\r\n\r\n    /**\r\n     * Size of the joystick's container\r\n     */\r\n    public set containerSize(newSize: number) {\r\n        this._joystickContainerSize = newSize;\r\n        this._clearContainerSize = ~~(this._joystickContainerSize * 2.1);\r\n        this._clearContainerSizeOffset = ~~(this._clearContainerSize / 2);\r\n    }\r\n    public get containerSize() {\r\n        return this._joystickContainerSize;\r\n    }\r\n\r\n    /**\r\n     * Size of the joystick's puck\r\n     */\r\n    public set puckSize(newSize: number) {\r\n        this._joystickPuckSize = newSize;\r\n        this._clearPuckSize = ~~(this._joystickPuckSize * 2.1);\r\n        this._clearPuckSizeOffset = ~~(this._clearPuckSize / 2);\r\n    }\r\n    public get puckSize() {\r\n        return this._joystickPuckSize;\r\n    }\r\n\r\n    /**\r\n     * Clears the set position of the joystick\r\n     */\r\n    public clearPosition() {\r\n        this.alwaysVisible = false;\r\n\r\n        this._joystickPosition = null;\r\n    }\r\n\r\n    /**\r\n     * Defines whether or not the joystick container is always visible\r\n     */\r\n    public set alwaysVisible(value: boolean) {\r\n        if (this._alwaysVisible === value) {\r\n            return;\r\n        }\r\n\r\n        if (value && this._joystickPosition) {\r\n            VirtualJoystick._AlwaysVisibleSticks++;\r\n\r\n            this._alwaysVisible = true;\r\n        } else {\r\n            VirtualJoystick._AlwaysVisibleSticks--;\r\n\r\n            this._alwaysVisible = false;\r\n        }\r\n    }\r\n    public get alwaysVisible() {\r\n        return this._alwaysVisible;\r\n    }\r\n\r\n    /**\r\n     * Sets the constant position of the Joystick container\r\n     * @param x X axis coordinate\r\n     * @param y Y axis coordinate\r\n     */\r\n    public setPosition(x: number, y: number) {\r\n        // just in case position is moved while the container is visible\r\n        if (this._joystickPointerStartPos) {\r\n            this._clearPreviousDraw();\r\n        }\r\n\r\n        this._joystickPosition = new Vector2(x, y);\r\n    }\r\n\r\n    /**\r\n     * Defines a callback to call when the joystick is touched\r\n     * @param action defines the callback\r\n     */\r\n    public setActionOnTouch(action: () => any) {\r\n        this._action = action;\r\n    }\r\n\r\n    /**\r\n     * Defines which axis you'd like to control for left & right\r\n     * @param axis defines the axis to use\r\n     */\r\n    public setAxisForLeftRight(axis: JoystickAxis) {\r\n        switch (axis) {\r\n            case JoystickAxis.X:\r\n            case JoystickAxis.Y:\r\n            case JoystickAxis.Z:\r\n                this._axisTargetedByLeftAndRight = axis;\r\n                break;\r\n            default:\r\n                this._axisTargetedByLeftAndRight = JoystickAxis.X;\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines which axis you'd like to control for up & down\r\n     * @param axis defines the axis to use\r\n     */\r\n    public setAxisForUpDown(axis: JoystickAxis) {\r\n        switch (axis) {\r\n            case JoystickAxis.X:\r\n            case JoystickAxis.Y:\r\n            case JoystickAxis.Z:\r\n                this._axisTargetedByUpAndDown = axis;\r\n                break;\r\n            default:\r\n                this._axisTargetedByUpAndDown = JoystickAxis.Y;\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clears the canvas from the previous puck / container draw\r\n     */\r\n    private _clearPreviousDraw() {\r\n        const jp = this._joystickPosition || this._joystickPointerStartPos;\r\n\r\n        // clear container pixels\r\n        VirtualJoystick._VjCanvasContext.clearRect(\r\n            jp.x - this._clearContainerSizeOffset,\r\n            jp.y - this._clearContainerSizeOffset,\r\n            this._clearContainerSize,\r\n            this._clearContainerSize\r\n        );\r\n\r\n        // clear puck pixels + 1 pixel for the change made before it moved\r\n        VirtualJoystick._VjCanvasContext.clearRect(\r\n            this._joystickPreviousPointerPos.x - this._clearPuckSizeOffset - 1,\r\n            this._joystickPreviousPointerPos.y - this._clearPuckSizeOffset - 1,\r\n            this._clearPuckSize + 2,\r\n            this._clearPuckSize + 2\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Loads `urlPath` to be used for the container's image\r\n     * @param urlPath defines the urlPath of an image to use\r\n     */\r\n    public setContainerImage(urlPath: string) {\r\n        const image = new Image();\r\n        image.src = urlPath;\r\n\r\n        image.onload = () => (this._containerImage = image);\r\n    }\r\n\r\n    /**\r\n     * Loads `urlPath` to be used for the puck's image\r\n     * @param urlPath defines the urlPath of an image to use\r\n     */\r\n    public setPuckImage(urlPath: string) {\r\n        const image = new Image();\r\n        image.src = urlPath;\r\n\r\n        image.onload = () => (this._puckImage = image);\r\n    }\r\n\r\n    /**\r\n     * Draws the Virtual Joystick's container\r\n     */\r\n    private _drawContainer() {\r\n        const jp = this._joystickPosition || this._joystickPointerStartPos;\r\n\r\n        this._clearPreviousDraw();\r\n\r\n        if (this._containerImage) {\r\n            VirtualJoystick._VjCanvasContext.drawImage(this._containerImage, jp.x - this.containerSize, jp.y - this.containerSize, this.containerSize * 2, this.containerSize * 2);\r\n        } else {\r\n            // outer container\r\n            VirtualJoystick._VjCanvasContext.beginPath();\r\n            VirtualJoystick._VjCanvasContext.strokeStyle = this._joystickColor;\r\n            VirtualJoystick._VjCanvasContext.lineWidth = 2;\r\n            VirtualJoystick._VjCanvasContext.arc(jp.x, jp.y, this.containerSize, 0, Math.PI * 2, true);\r\n            VirtualJoystick._VjCanvasContext.stroke();\r\n            VirtualJoystick._VjCanvasContext.closePath();\r\n\r\n            // inner container\r\n            VirtualJoystick._VjCanvasContext.beginPath();\r\n            VirtualJoystick._VjCanvasContext.lineWidth = 6;\r\n            VirtualJoystick._VjCanvasContext.strokeStyle = this._joystickColor;\r\n            VirtualJoystick._VjCanvasContext.arc(jp.x, jp.y, this.puckSize, 0, Math.PI * 2, true);\r\n            VirtualJoystick._VjCanvasContext.stroke();\r\n            VirtualJoystick._VjCanvasContext.closePath();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Draws the Virtual Joystick's puck\r\n     */\r\n    private _drawPuck() {\r\n        if (this._puckImage) {\r\n            VirtualJoystick._VjCanvasContext.drawImage(\r\n                this._puckImage,\r\n                this._joystickPointerPos.x - this.puckSize,\r\n                this._joystickPointerPos.y - this.puckSize,\r\n                this.puckSize * 2,\r\n                this.puckSize * 2\r\n            );\r\n        } else {\r\n            VirtualJoystick._VjCanvasContext.beginPath();\r\n            VirtualJoystick._VjCanvasContext.strokeStyle = this._joystickColor;\r\n            VirtualJoystick._VjCanvasContext.lineWidth = 2;\r\n            VirtualJoystick._VjCanvasContext.arc(this._joystickPointerPos.x, this._joystickPointerPos.y, this.puckSize, 0, Math.PI * 2, true);\r\n            VirtualJoystick._VjCanvasContext.stroke();\r\n            VirtualJoystick._VjCanvasContext.closePath();\r\n        }\r\n    }\r\n\r\n    private _drawVirtualJoystick() {\r\n        // canvas released? don't continue iterating\r\n        if (this._released) {\r\n            return;\r\n        }\r\n        if (this.alwaysVisible) {\r\n            this._drawContainer();\r\n        }\r\n\r\n        if (this.pressed) {\r\n            this._touches.forEach((key, touch) => {\r\n                if ((<PointerEvent>touch).pointerId === this._joystickPointerId) {\r\n                    if (!this.alwaysVisible) {\r\n                        this._drawContainer();\r\n                    }\r\n\r\n                    this._drawPuck();\r\n\r\n                    // store current pointer for next clear\r\n                    this._joystickPreviousPointerPos = this._joystickPointerPos.clone();\r\n                } else {\r\n                    VirtualJoystick._VjCanvasContext.clearRect((<any>touch).prevX - 44, (<any>touch).prevY - 44, 88, 88);\r\n                    VirtualJoystick._VjCanvasContext.beginPath();\r\n                    VirtualJoystick._VjCanvasContext.fillStyle = \"white\";\r\n                    VirtualJoystick._VjCanvasContext.beginPath();\r\n                    VirtualJoystick._VjCanvasContext.strokeStyle = \"red\";\r\n                    VirtualJoystick._VjCanvasContext.lineWidth = 6;\r\n                    VirtualJoystick._VjCanvasContext.arc(touch.x, touch.y, 40, 0, Math.PI * 2, true);\r\n                    VirtualJoystick._VjCanvasContext.stroke();\r\n                    VirtualJoystick._VjCanvasContext.closePath();\r\n                    (<any>touch).prevX = touch.x;\r\n                    (<any>touch).prevY = touch.y;\r\n                }\r\n            });\r\n        }\r\n        requestAnimationFrame(() => {\r\n            this._drawVirtualJoystick();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Release internal HTML canvas\r\n     */\r\n    public releaseCanvas() {\r\n        if (VirtualJoystick.Canvas) {\r\n            VirtualJoystick.Canvas.removeEventListener(\"pointerdown\", this._onPointerDownHandlerRef);\r\n            VirtualJoystick.Canvas.removeEventListener(\"pointermove\", this._onPointerMoveHandlerRef);\r\n            VirtualJoystick.Canvas.removeEventListener(\"pointerup\", this._onPointerUpHandlerRef);\r\n            VirtualJoystick.Canvas.removeEventListener(\"pointerout\", this._onPointerUpHandlerRef);\r\n            VirtualJoystick.Canvas.removeEventListener(\"pointercancel\", this._onPointerUpHandlerRef);\r\n            window.removeEventListener(\"resize\", this._onResize);\r\n            document.body.removeChild(VirtualJoystick.Canvas);\r\n            VirtualJoystick.Canvas = null;\r\n        }\r\n        this._released = true;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { VirtualJoystick, JoystickAxis } from \"../../Misc/virtualJoystick\";\r\nimport { CameraInputTypes, type ICameraInput } from \"../../Cameras/cameraInputsManager\";\r\n\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera.pure\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { FreeCameraInputsManager } from \"../../Cameras/freeCameraInputsManager.pure\";\r\n\r\n/**\r\n * Manage the Virtual Joystick inputs to control the movement of a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraVirtualJoystickInput implements ICameraInput<FreeCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: FreeCamera;\r\n\r\n    private _leftjoystick: VirtualJoystick;\r\n    private _rightjoystick: VirtualJoystick;\r\n\r\n    /**\r\n     * Gets the left stick of the virtual joystick.\r\n     * @returns The virtual Joystick\r\n     */\r\n    public getLeftJoystick(): VirtualJoystick {\r\n        return this._leftjoystick;\r\n    }\r\n\r\n    /**\r\n     * Gets the right stick of the virtual joystick.\r\n     * @returns The virtual Joystick\r\n     */\r\n    public getRightJoystick(): VirtualJoystick {\r\n        return this._rightjoystick;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs() {\r\n        if (this._leftjoystick) {\r\n            const camera = this.camera;\r\n            const speed = camera._computeLocalCameraSpeed() * 50;\r\n            const cameraTransform = TmpVectors.Matrix[0];\r\n            const deltaPosition = TmpVectors.Vector3[0];\r\n            const transformedDeltaPosition = TmpVectors.Vector3[1];\r\n            Matrix.RotationYawPitchRollToRef(camera.rotation.y, camera.rotation.x, 0, cameraTransform);\r\n            deltaPosition.copyFromFloats(this._leftjoystick.deltaPosition.x * speed, this._leftjoystick.deltaPosition.y * speed, this._leftjoystick.deltaPosition.z * speed);\r\n            Vector3.TransformCoordinatesToRef(deltaPosition, cameraTransform, transformedDeltaPosition);\r\n            camera.cameraDirection.addInPlace(transformedDeltaPosition);\r\n            camera.cameraRotation.addInPlaceFromFloats(this._rightjoystick.deltaPosition.x, this._rightjoystick.deltaPosition.y);\r\n\r\n            if (!this._leftjoystick.pressed) {\r\n                this._leftjoystick.deltaPosition.scaleInPlace(0.9);\r\n            }\r\n            if (!this._rightjoystick.pressed) {\r\n                this._rightjoystick.deltaPosition.scaleInPlace(0.9);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     */\r\n    public attachControl(): void {\r\n        this._leftjoystick = new VirtualJoystick(true);\r\n        this._leftjoystick.setAxisForUpDown(JoystickAxis.Z);\r\n        this._leftjoystick.setAxisForLeftRight(JoystickAxis.X);\r\n        this._leftjoystick.setJoystickSensibility(0.15);\r\n        this._rightjoystick = new VirtualJoystick(false);\r\n        this._rightjoystick.setAxisForUpDown(JoystickAxis.X);\r\n        this._rightjoystick.setAxisForLeftRight(JoystickAxis.Y);\r\n        this._rightjoystick.reverseUpDown = true;\r\n        this._rightjoystick.setJoystickSensibility(0.05);\r\n        this._rightjoystick.setJoystickColor(\"yellow\");\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        this._leftjoystick.releaseCanvas();\r\n        this._rightjoystick.releaseCanvas();\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FreeCameraVirtualJoystickInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"virtualJoystick\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraVirtualJoystickInput\"] = FreeCameraVirtualJoystickInput;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for freeCameraVirtualJoystickInput.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFreeCameraVirtualJoystickInput(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Add virtual joystick input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    FreeCameraInputsManager.prototype.addVirtualJoystick = function (): FreeCameraInputsManager {\r\n        this.add(new FreeCameraVirtualJoystickInput());\r\n        return this;\r\n    };\r\n}\r\n","import { type DeepImmutable } from \"../types\";\r\nimport { type IVector2Like, type IVector3Like, type IVector4Like } from \"./math.like\";\r\n\r\n/**\r\n * Creates a string representation of the IVector2Like\r\n * @param vector defines the IVector2Like to stringify\r\n * @param decimalCount defines the number of decimals to use\r\n * @returns a string with the IVector2Like coordinates.\r\n */\r\nexport function Vector2ToFixed(vector: DeepImmutable<IVector2Like>, decimalCount: number): string {\r\n    return `{X: ${vector.x.toFixed(decimalCount)} Y: ${vector.y.toFixed(decimalCount)}}`;\r\n}\r\n\r\n/**\r\n * Computes the dot product of two IVector3Like objects.\r\n * @param a defines the first vector\r\n * @param b defines the second vector\r\n * @returns the dot product\r\n */\r\nexport function Vector3Dot(a: DeepImmutable<IVector3Like>, b: DeepImmutable<IVector3Like>): number {\r\n    return a.x * b.x + a.y * b.y + a.z * b.z;\r\n}\r\n\r\n/**\r\n * Computes the squared length of the IVector3Like\r\n * @param vector the vector to measure\r\n * @returns the squared length of the vector\r\n */\r\nexport function Vector3LengthSquared(vector: DeepImmutable<IVector3Like>): number {\r\n    return vector.x * vector.x + vector.y * vector.y + vector.z * vector.z;\r\n}\r\n\r\n/**\r\n * Computes the length of the IVector3Like\r\n * @param vector the vector to measure\r\n * @returns the length of the vector\r\n */\r\nexport function Vector3Length(vector: DeepImmutable<IVector3Like>): number {\r\n    return Math.sqrt(Vector3LengthSquared(vector));\r\n}\r\n\r\n/**\r\n * Computes the squared distance between the IVector3Like objects\r\n * @param a defines the first vector\r\n * @param b defines the second vector\r\n * @returns the squared distance\r\n */\r\nexport function Vector3DistanceSquared(a: DeepImmutable<IVector3Like>, b: DeepImmutable<IVector3Like>): number {\r\n    const x = b.x - a.x;\r\n    const y = b.y - a.y;\r\n    const z = b.z - a.z;\r\n    return x * x + y * y + z * z;\r\n}\r\n\r\n/**\r\n * Computes the distance between the IVector3Like objects\r\n * @param a defines the first vector\r\n * @param b defines the second vector\r\n * @returns the distance\r\n */\r\nexport function Vector3Distance(a: DeepImmutable<IVector3Like>, b: DeepImmutable<IVector3Like>): number {\r\n    return Math.sqrt(Vector3DistanceSquared(a, b));\r\n}\r\n\r\n/**\r\n * Sets the given floats into the result.\r\n * @param x defines the x coordinate\r\n * @param y defines the y coordinate\r\n * @param z defines the z coordinate\r\n * @param result defines the result vector\r\n * @returns the result vector\r\n */\r\nexport function Vector3FromFloatsToRef<T extends IVector3Like>(x: number, y: number, z: number, result: T): T {\r\n    result.x = x;\r\n    result.y = y;\r\n    result.z = z;\r\n    return result;\r\n}\r\n\r\n/**\r\n * Stores the scaled values of a vector into the result.\r\n * @param a defines the source vector\r\n * @param scale defines the scale factor\r\n * @param result defines the result vector\r\n * @returns the scaled vector\r\n */\r\nexport function Vector3ScaleToRef<T extends IVector3Like>(a: DeepImmutable<IVector3Like>, scale: number, result: T): T {\r\n    result.x = a.x * scale;\r\n    result.y = a.y * scale;\r\n    result.z = a.z * scale;\r\n    return result;\r\n}\r\n\r\n/**\r\n * Scales the current vector values in place by a factor.\r\n * @param vector defines the vector to scale\r\n * @param scale defines the scale factor\r\n * @returns the scaled vector\r\n */\r\nexport function Vector3ScaleInPlace<T extends IVector3Like>(vector: T, scale: number): T {\r\n    vector.x *= scale;\r\n    vector.y *= scale;\r\n    vector.z *= scale;\r\n    return vector;\r\n}\r\n\r\nexport function Vector3SubtractToRef<T extends IVector3Like>(a: DeepImmutable<IVector3Like>, b: DeepImmutable<IVector3Like>, result: T): T {\r\n    result.x = a.x - b.x;\r\n    result.y = a.y - b.y;\r\n    result.z = a.z - b.z;\r\n    return result;\r\n}\r\n\r\nexport function Vector3CopyToRef<T extends IVector3Like>(source: DeepImmutable<IVector3Like>, result: T): T {\r\n    result.x = source.x;\r\n    result.y = source.y;\r\n    result.z = source.z;\r\n    return result;\r\n}\r\n\r\nexport function Vector3LerpToRef<T extends IVector3Like>(start: DeepImmutable<IVector3Like>, end: DeepImmutable<IVector3Like>, amount: number, result: T): T {\r\n    result.x = start.x + (end.x - start.x) * amount;\r\n    result.y = start.y + (end.y - start.y) * amount;\r\n    result.z = start.z + (end.z - start.z) * amount;\r\n    return result;\r\n}\r\n\r\nexport function Vector3NormalizeToRef<T extends IVector3Like>(vector: DeepImmutable<IVector3Like>, result: T): T {\r\n    const len = Vector3Length(vector);\r\n    if (len === 0) {\r\n        result.x = 0;\r\n        result.y = 0;\r\n        result.z = 0;\r\n    } else {\r\n        result.x = vector.x / len;\r\n        result.y = vector.y / len;\r\n        result.z = vector.z / len;\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * Computes the signed distance between the specified point and plane.\r\n * @param origin defines a point on the plane\r\n * @param normal defines the plane normal (assumes normalized)\r\n * @param point defines the point to compute the signed distance to\r\n * @returns the signed distance\r\n */\r\nexport function Vector3SignedDistanceToPlaneFromPositionAndNormal(\r\n    origin: DeepImmutable<IVector3Like>,\r\n    normal: DeepImmutable<IVector3Like>,\r\n    point: DeepImmutable<IVector3Like>\r\n): number {\r\n    return (point.x - origin.x) * normal.x + (point.y - origin.y) * normal.y + (point.z - origin.z) * normal.z;\r\n}\r\n\r\n/**\r\n * Creates a string representation of the IVector3Like\r\n * @param vector defines the IVector3Like to stringify\r\n * @param decimalCount defines the number of decimals to use\r\n * @returns a string with the IVector3Like coordinates.\r\n */\r\nexport function Vector3ToFixed(vector: DeepImmutable<IVector3Like>, decimalCount: number): string {\r\n    return `{X: ${vector.x.toFixed(decimalCount)} Y: ${vector.y.toFixed(decimalCount)} Z: ${vector.z.toFixed(decimalCount)}}`;\r\n}\r\n\r\n/**\r\n * Computes the dot product of two IVector4Like objects\r\n * @param a defines the first vector\r\n * @param b defines the second vector\r\n * @returns the dot product\r\n */\r\nexport function Vector4Dot(a: DeepImmutable<IVector4Like>, b: DeepImmutable<IVector4Like>): number {\r\n    return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;\r\n}\r\n\r\n/**\r\n * Creates a string representation of the IVector4Like\r\n * @param vector defines the IVector4Like to stringify\r\n * @param decimalCount defines the number of decimals to use\r\n * @returns a string with the IVector4Like coordinates.\r\n */\r\nexport function Vector4ToFixed(vector: DeepImmutable<IVector4Like>, decimalCount: number): string {\r\n    return `{X: ${vector.x.toFixed(decimalCount)} Y: ${vector.y.toFixed(decimalCount)} Z: ${vector.z.toFixed(decimalCount)} W: ${vector.w.toFixed(decimalCount)}}`;\r\n}\r\n","import { type GeospatialCamera } from \"../../Cameras/geospatialCamera\";\r\nimport { type EasingFunction } from \"../../Animations/easing\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { type PointerTouch } from \"../../Events/pointerEvents\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { OrbitCameraPointersInput } from \"./orbitCameraPointersInput\";\r\nimport { Vector3Distance } from \"../../Maths/math.vector.functions\";\r\nimport { type PointerConditions, type PointerInputMapEntry } from \"../inputMapper\";\r\n\r\n/**\r\n * Geospatial camera inputs can simulate dragging the globe around or tilting the camera around some point on the globe\r\n * This class will update the GeospatialCameraMovement class's movementDeltaCurrentFrame, and the camera is responsible for using these updates to calculate viewMatrix appropriately\r\n *\r\n * Uses the inputMap on the movement class to determine which button maps to which interaction.\r\n * Default: Left mouse button = pan (drag globe), Middle/Right mouse button = rotate (tilt)\r\n *\r\n */\r\nexport class GeospatialCameraPointersInput extends OrbitCameraPointersInput {\r\n    public camera: GeospatialCamera;\r\n\r\n    private _initialPinchSquaredDistance: number = 0;\r\n    private _pinchCentroid: Nullable<PointerTouch> = null;\r\n\r\n    /** Cached resolved inputMap entry for the current pointer gesture */\r\n    private _activeEntry: Nullable<PointerInputMapEntry> = null;\r\n\r\n    /**\r\n     * Modifier state stored separately from `_pointerConditions` so it can be typed as a\r\n     * concrete (non-optional) object. This avoids non-null assertions when updating modifier\r\n     * fields on every pointer-down, and the conditions object holds the same reference so\r\n     * resolveInteraction sees the live state.\r\n     */\r\n    private _pointerModifiers: { ctrl: boolean; alt: boolean; shift: boolean } = { ctrl: false, alt: false, shift: false };\r\n\r\n    /** Cached conditions object for pointer-down resolution */\r\n    private _pointerConditions: PointerConditions = { modifiers: this._pointerModifiers };\r\n\r\n    /**\r\n     * Defines the rotation sensitivity of the pointer when rotating camera around the x axis (pitch).\r\n     * (Multiplied by the true pixel delta of pointer input, before rotation speed factor is applied by movement class)\r\n     * @deprecated Use the `sensitivity` field on the pointer rotate entry in `camera.movement.input.inputMap` instead.\r\n     */\r\n    public get pitchSensitivity(): number {\r\n        const entry = this.camera?.movement.input.getEntry(\"pointer\", \"rotate\");\r\n        return entry?.sensitivityY ?? entry?.sensitivity ?? 1;\r\n    }\r\n\r\n    public set pitchSensitivity(value: number) {\r\n        for (const entry of this.camera?.movement.input.getEntries(\"pointer\", \"rotate\") ?? []) {\r\n            entry.sensitivityY = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the rotation sensitivity of the pointer when rotating the camera around the Y axis (yaw).\r\n     * (Multiplied by the true pixel delta of pointer input, before rotation speed factor is applied by movement class)\r\n     * @deprecated Use the `sensitivity` field on the pointer rotate entry in `camera.movement.input.inputMap` instead.\r\n     */\r\n    public get yawSensitivity(): number {\r\n        const entry = this.camera?.movement.input.getEntry(\"pointer\", \"rotate\");\r\n        return entry?.sensitivityX ?? entry?.sensitivity ?? 1;\r\n    }\r\n\r\n    public set yawSensitivity(value: number) {\r\n        for (const entry of this.camera?.movement.input.getEntries(\"pointer\", \"rotate\") ?? []) {\r\n            entry.sensitivityX = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the distance used to consider the camera in pan mode vs pinch/zoom.\r\n     * Basically if your fingers moves away from more than this distance you will be considered\r\n     * in pinch mode.\r\n     */\r\n    public pinchToPanMax: number = 20;\r\n\r\n    /**\r\n     * Duration (in milliseconds) of the fly-to animation triggered by a double tap.\r\n     */\r\n    public doubleTapAnimationDurationMs: number = 1000;\r\n\r\n    /**\r\n     * Optional easing function applied to the double-tap fly-to animation.\r\n     * An EasingFunction instance can be created once and reused across double taps.\r\n     */\r\n    public doubleTapEasingFunction: Nullable<EasingFunction> = null;\r\n\r\n    public override getClassName(): string {\r\n        return \"GeospatialCameraPointersInput\";\r\n    }\r\n\r\n    /**\r\n     * Handles the pointer-down event. Captures the active button + modifier state, resolves which\r\n     * inputMap entry should drive the gesture, and starts pan tracking if the resolved interaction is \"pan\".\r\n     * @param evt - The pointer-down event.\r\n     */\r\n    public override onButtonDown(evt: IPointerEvent): void {\r\n        this.camera.movement.activeInput = true;\r\n        const scene = this.camera.getScene();\r\n\r\n        this._pointerConditions.button = evt.button;\r\n        this._pointerModifiers.ctrl = evt.ctrlKey;\r\n        this._pointerModifiers.alt = evt.altKey;\r\n        this._pointerModifiers.shift = evt.shiftKey;\r\n        this._activeEntry = this.camera.movement.input.resolveInteraction(\"pointer\", this._pointerConditions);\r\n\r\n        if (this._activeEntry?.interaction === \"pan\") {\r\n            this.camera.movement.input.handlers.pan.start(scene.pointerX, scene.pointerY);\r\n        }\r\n    }\r\n\r\n    public override onTouch(point: Nullable<PointerTouch>, offsetX: number, offsetY: number): void {\r\n        if (!this._activeEntry) {\r\n            return;\r\n        }\r\n        const sens = this._activeEntry.sensitivity ?? 1;\r\n        const sensX = this._activeEntry.sensitivityX ?? sens;\r\n        const sensY = this._activeEntry.sensitivityY ?? sens;\r\n        const scene = this.camera.getScene();\r\n\r\n        if (this._activeEntry.interaction === \"pan\") {\r\n            this.camera.movement.input.handlers.pan.update(scene.pointerX, scene.pointerY);\r\n        } else if (this._activeEntry.interaction === \"rotate\") {\r\n            this.camera.movement.input.handlers.rotate(offsetX * sensX, -offsetY * sensY);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Move camera from multitouch (pinch) zoom distances.\r\n     * Zooms towards the centroid (midpoint between the two fingers).\r\n     * @param previousPinchSquaredDistance\r\n     * @param pinchSquaredDistance\r\n     */\r\n    protected override _computePinchZoom(previousPinchSquaredDistance: number, pinchSquaredDistance: number): void {\r\n        const camera = this.camera;\r\n\r\n        // Calculate zoom distance based on pinch delta\r\n        const previousDistance = Math.sqrt(previousPinchSquaredDistance);\r\n        const currentDistance = Math.sqrt(pinchSquaredDistance);\r\n        const pinchDelta = currentDistance - previousDistance;\r\n\r\n        // Try to zoom towards centroid if we have it\r\n        if (this._pinchCentroid) {\r\n            const scene = camera.getScene();\r\n            const engine = scene.getEngine();\r\n            const canvasRect = engine.getInputElementClientRect();\r\n\r\n            if (canvasRect) {\r\n                // Convert centroid from clientX/Y to canvas-relative coordinates (same as scene.pointerX/Y)\r\n                const canvasX = this._pinchCentroid.x - canvasRect.left;\r\n                const canvasY = this._pinchCentroid.y - canvasRect.top;\r\n\r\n                // Pick at centroid\r\n                const pickResult = scene.pick(canvasX, canvasY, camera.movement.pickPredicate);\r\n                if (pickResult?.pickedPoint) {\r\n                    // Scale zoom by distance to picked point\r\n                    const distanceToPoint = Vector3Distance(pickResult.pickedPoint, camera.position);\r\n                    const zoomDistance = pinchDelta * distanceToPoint * 0.005;\r\n                    const clampedZoom = camera.limits.clampZoomDistance(zoomDistance, camera.radius, distanceToPoint);\r\n                    camera.zoomToPoint(pickResult.pickedPoint, clampedZoom);\r\n                    return;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Fallback: scale zoom by camera radius along lookat vector\r\n        const zoomDistance = pinchDelta * camera.radius * 0.005;\r\n        const clampedZoom = camera.limits.clampZoomDistance(zoomDistance, camera.radius);\r\n        camera.zoomAlongLookAt(clampedZoom);\r\n    }\r\n\r\n    /**\r\n     * Move camera from multi touch panning positions.\r\n     * In geospatialcamera, multi touch panning tilts the globe (whereas single touch will pan/drag it)\r\n     * @param previousMultiTouchPanPosition\r\n     * @param multiTouchPanPosition\r\n     */\r\n    protected override _computeMultiTouchPanning(previousMultiTouchPanPosition: Nullable<PointerTouch>, multiTouchPanPosition: Nullable<PointerTouch>): void {\r\n        if (previousMultiTouchPanPosition && multiTouchPanPosition) {\r\n            const moveDeltaX = multiTouchPanPosition.x - previousMultiTouchPanPosition.x;\r\n            const moveDeltaY = multiTouchPanPosition.y - previousMultiTouchPanPosition.y;\r\n            // Multi-touch is a gesture (no button), so `_activeEntry` is null. Resolve a fresh\r\n            // pointer→rotate entry so the configured rotate sensitivity (yaw/pitch) is honored.\r\n            const rotateEntry = this.camera.movement.input.getEntry(\"pointer\", \"rotate\");\r\n            const sens = rotateEntry?.sensitivity ?? 1;\r\n            const sensX = rotateEntry?.sensitivityX ?? sens;\r\n            const sensY = rotateEntry?.sensitivityY ?? sens;\r\n            this.camera.movement.input.handlers.rotate(moveDeltaX * sensX, -moveDeltaY * sensY);\r\n        }\r\n    }\r\n\r\n    public override onDoubleTap(type: string, evt?: IPointerEvent): void {\r\n        // Only respond to a double tap from the primary pointer (left mouse button / primary touch).\r\n        // Ignore non-primary buttons (e.g. double right-click) and mixed combinations (e.g. left then right).\r\n        // Also ignore the double tap if any other button is still pressed (e.g. right-click held for\r\n        // rotation while double-tapping left), since `evt.buttons` is a bitmask of currently-pressed buttons.\r\n        if (evt && (evt.button !== 0 || evt.buttons !== 0)) {\r\n            return;\r\n        }\r\n        const pickResult = this.camera._scene.pick(this.camera._scene.pointerX, this.camera._scene.pointerY, this.camera.movement.pickPredicate);\r\n        if (pickResult.pickedPoint) {\r\n            void this.camera.flyToPointAsync(pickResult.pickedPoint, undefined, this.doubleTapAnimationDurationMs, this.doubleTapEasingFunction ?? undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Handles a multi-touch (pinch / two-finger pan) gesture. Detects whether the gesture should be\r\n     * interpreted as a pinch zoom or a two-finger pan based on cumulative finger distance change,\r\n     * and forwards the gesture to the parent class once a mode is decided.\r\n     * @param pointA - First active touch point, or null if it just ended.\r\n     * @param pointB - Second active touch point, or null if it just ended.\r\n     * @param previousPinchSquaredDistance - Squared distance between the two touches on the previous frame.\r\n     * @param pinchSquaredDistance - Squared distance between the two touches on the current frame.\r\n     * @param previousMultiTouchPanPosition - Centroid of the two touches on the previous frame, or null if unavailable.\r\n     * @param multiTouchPanPosition - Centroid of the two touches on the current frame, or null if the gesture ended.\r\n     */\r\n    public override onMultiTouch(\r\n        pointA: Nullable<PointerTouch>,\r\n        pointB: Nullable<PointerTouch>,\r\n        previousPinchSquaredDistance: number,\r\n        pinchSquaredDistance: number,\r\n        previousMultiTouchPanPosition: Nullable<PointerTouch>,\r\n        multiTouchPanPosition: Nullable<PointerTouch>\r\n    ): void {\r\n        // Store centroid for use in _computePinchZoom (it's already calculated by parent)\r\n        this._pinchCentroid = multiTouchPanPosition;\r\n\r\n        // Reset on gesture end\r\n        if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {\r\n            this._initialPinchSquaredDistance = 0;\r\n            this._pinchCentroid = null;\r\n            super.onMultiTouch(pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition);\r\n            return;\r\n        }\r\n\r\n        // Track initial distance at gesture start for cumulative threshold detection\r\n        if (this._initialPinchSquaredDistance === 0 && pinchSquaredDistance !== 0) {\r\n            this._initialPinchSquaredDistance = pinchSquaredDistance;\r\n        }\r\n\r\n        // Use cumulative delta from gesture start for threshold detection (more forgiving than frame-to-frame)\r\n        const cumulativeDelta = Math.abs(Math.sqrt(pinchSquaredDistance) - Math.sqrt(this._initialPinchSquaredDistance));\r\n        this._shouldStartPinchZoom = this._twoFingerActivityCount < 20 && cumulativeDelta > this.pinchToPanMax;\r\n\r\n        super.onMultiTouch(pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition);\r\n    }\r\n\r\n    public override onButtonUp(_evt: IPointerEvent): void {\r\n        if (this._activeEntry?.interaction === \"pan\") {\r\n            this.camera.movement.input.handlers.pan.stop();\r\n        }\r\n        this._activeEntry = null;\r\n        this.camera.movement.activeInput = false;\r\n        this._initialPinchSquaredDistance = 0;\r\n        this._pinchCentroid = null;\r\n        super.onButtonUp(_evt);\r\n    }\r\n\r\n    public override onLostFocus(): void {\r\n        this._activeEntry = null;\r\n        this._initialPinchSquaredDistance = 0;\r\n        this._pinchCentroid = null;\r\n        super.onLostFocus();\r\n    }\r\n}\r\n","import { type GeospatialCamera } from \"../../Cameras/geospatialCamera\";\r\nimport { CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { BaseCameraMouseWheelInput } from \"./BaseCameraMouseWheelInput\";\r\n\r\n/**\r\n * Manage the mouse wheel inputs to control a geospatial camera.\r\n */\r\nexport class GeospatialCameraMouseWheelInput extends BaseCameraMouseWheelInput {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: GeospatialCamera;\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GeospatialCameraMouseWheelInput\";\r\n    }\r\n\r\n    public override checkInputs(): void {\r\n        this.camera.movement.input.handlers.zoom(this._wheelDeltaY, true);\r\n        super.checkInputs();\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"GeospatialCameraMouseWheelInput\"] = GeospatialCameraMouseWheelInput;\r\n","import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type GeospatialCamera } from \"../geospatialCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../cameraInputsManager\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type KeyboardConditions } from \"../inputMapper\";\r\nimport { Vector2 } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of a geospatial camera.\r\n * Arrow keys + Modifier key (ctrl/alt/option on mac): rotate\r\n * Arrow keys alone: pan\r\n * + / - keys: zoom in/out\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class GeospatialCameraKeyboardInput implements ICameraInput<GeospatialCamera> {\r\n    /**\r\n     * Defines the camera the input is attached to.\r\n     */\r\n    public camera: GeospatialCamera;\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the up action (pan up)\r\n     */\r\n    @serialize()\r\n    public keysUp = [38];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the down action (pan down)\r\n     */\r\n    @serialize()\r\n    public keysDown = [40];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the left action (pan left)\r\n     */\r\n    @serialize()\r\n    public keysLeft = [37];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with the right action (pan right)\r\n     */\r\n    @serialize()\r\n    public keysRight = [39];\r\n\r\n    /**\r\n     * Defines the list of key codes associated with zoom in (+ or =)\r\n     */\r\n    @serialize()\r\n    public keysZoomIn = [187, 107]; // 187 = + key, 107 = numpad +\r\n\r\n    /**\r\n     * Defines the list of key codes associated with zoom out (-)\r\n     */\r\n    @serialize()\r\n    public keysZoomOut = [189, 109]; // 189 = - key, 109 = numpad -\r\n\r\n    /**\r\n     * Defines the rotation sensitivity of the inputs.\r\n     * (How many pixels of pointer input to apply per keypress, before rotation speed factor is applied by movement class)\r\n     * @deprecated Use the `sensitivity` field on the keyboard rotate entry in `camera.movement.input.inputMap` instead.\r\n     */\r\n    @serialize()\r\n    public get rotationSensitivity(): number {\r\n        const entry = this.camera?.movement.input.getEntry(\"keyboard\", \"rotate\");\r\n        return entry?.sensitivity ?? 1;\r\n    }\r\n\r\n    public set rotationSensitivity(value: number) {\r\n        for (const entry of this.camera?.movement.input.getEntries(\"keyboard\", \"rotate\") ?? []) {\r\n            entry.sensitivity = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the panning sensitivity of the inputs.\r\n     * (How many pixels of pointer input to apply per keypress, before pan speed factor is applied by movement class)\r\n     * @deprecated Use the `sensitivity` field on the keyboard pan entry in `camera.movement.input.inputMap` instead.\r\n     */\r\n    @serialize()\r\n    public get panSensitivity(): number {\r\n        const entry = this.camera?.movement.input.getEntry(\"keyboard\", \"pan\");\r\n        return entry?.sensitivity ?? 1;\r\n    }\r\n\r\n    public set panSensitivity(value: number) {\r\n        for (const entry of this.camera?.movement.input.getEntries(\"keyboard\", \"pan\") ?? []) {\r\n            entry.sensitivity = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the zooming sensitivity of the inputs.\r\n     * (How many pixels of pointer input to apply per keypress, before zoom speed factor is applied by movement class)\r\n     * @deprecated Use the `sensitivity` field on the keyboard zoom entry in `camera.movement.input.inputMap` instead.\r\n     */\r\n    @serialize()\r\n    public get zoomSensitivity(): number {\r\n        const entry = this.camera?.movement.input.getEntry(\"keyboard\", \"zoom\");\r\n        return entry?.sensitivity ?? 1;\r\n    }\r\n\r\n    public set zoomSensitivity(value: number) {\r\n        for (const entry of this.camera?.movement.input.getEntries(\"keyboard\", \"zoom\") ?? []) {\r\n            entry.sensitivity = value;\r\n        }\r\n    }\r\n\r\n    private _keys = new Array<number>();\r\n    private _ctrlPressed: boolean;\r\n    private _altPressed: boolean;\r\n    private _shiftPressed: boolean;\r\n    private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n    private _engine: AbstractEngine;\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Modifier state stored separately from `_keyboardConditions` so it can be typed as a\r\n     * concrete (non-optional) object. This avoids non-null assertions when updating modifier\r\n     * fields each frame, and the conditions object holds the same reference so\r\n     * resolveInteraction sees the live state.\r\n     */\r\n    private _keyboardModifiers: { ctrl: boolean; alt: boolean; shift: boolean } = { ctrl: false, alt: false, shift: false };\r\n\r\n    /** Cached conditions object to avoid per-frame allocations in checkInputs */\r\n    private _keyboardConditions: KeyboardConditions = { modifiers: this._keyboardModifiers };\r\n\r\n    /** Reused accumulator for the per-frame keyboard pan direction, to avoid per-frame allocations */\r\n    private _panDirection = new Vector2();\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public attachControl(noPreventDefault?: boolean): void {\r\n        // was there a second variable defined?\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n\r\n        if (this._onCanvasBlurObserver) {\r\n            return;\r\n        }\r\n\r\n        this._scene = this.camera.getScene();\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n            this._keys.length = 0;\r\n        });\r\n\r\n        this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n            const evt = info.event;\r\n            const isArrowKey =\r\n                this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                this.keysRight.indexOf(evt.keyCode) !== -1;\r\n            // Allow metaKey (Cmd on Mac) through for arrow keys so Cmd+Arrow\r\n            // works as the Mac equivalent of Ctrl+Arrow for rotation.\r\n            // Block metaKey for other keys to avoid capturing browser shortcuts (e.g., Cmd+=/Cmd+-).\r\n            if (!evt.metaKey || isArrowKey) {\r\n                if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n                    this._ctrlPressed = evt.ctrlKey;\r\n                    this._altPressed = evt.altKey;\r\n                    this._shiftPressed = evt.shiftKey;\r\n\r\n                    if (\r\n                        this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index === -1) {\r\n                            this._keys.push(evt.keyCode);\r\n                        }\r\n\r\n                        if (evt.preventDefault) {\r\n                            if (!noPreventDefault) {\r\n                                evt.preventDefault();\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (\r\n                        this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n                        this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n                    ) {\r\n                        const index = this._keys.indexOf(evt.keyCode);\r\n\r\n                        if (index >= 0) {\r\n                            this._keys.splice(index, 1);\r\n                        }\r\n\r\n                        if (evt.preventDefault) {\r\n                            if (!noPreventDefault) {\r\n                                evt.preventDefault();\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public detachControl(): void {\r\n        if (this._scene) {\r\n            this._onKeyboardObserver?.remove();\r\n            this._onKeyboardObserver = null;\r\n            this._onCanvasBlurObserver?.remove();\r\n            this._onCanvasBlurObserver = null;\r\n        }\r\n\r\n        this._keys.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Update the current camera state depending on the inputs that have been used this frame.\r\n     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n     */\r\n    public checkInputs(): void {\r\n        if (this._onKeyboardObserver) {\r\n            const camera = this.camera;\r\n            const input = camera.movement.input;\r\n\r\n            // Update cached modifier state\r\n            this._keyboardModifiers.ctrl = this._ctrlPressed;\r\n            this._keyboardModifiers.alt = this._altPressed;\r\n            this._keyboardModifiers.shift = this._shiftPressed;\r\n\r\n            // Pan keys are accumulated into a single direction vector and applied once below, so that\r\n            // holding two directions at once (e.g. up + left) pans along a normalized diagonal at the\r\n            // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from\r\n            // applying each pan key independently.\r\n            const panDirection = this._panDirection.set(0, 0);\r\n            let panSensitivity = 0;\r\n\r\n            for (let index = 0; index < this._keys.length; index++) {\r\n                const keyCode = this._keys[index];\r\n\r\n                // Resolve per key — allows different keys to map to different interactions\r\n                this._keyboardConditions.key = keyCode;\r\n                const resolved = input.resolveInteraction(\"keyboard\", this._keyboardConditions);\r\n\r\n                if (resolved) {\r\n                    const sens = resolved.sensitivity ?? 1;\r\n                    if (resolved.interaction === \"zoom\") {\r\n                        if (this.keysZoomIn.indexOf(keyCode) !== -1 || this.keysUp.indexOf(keyCode) !== -1) {\r\n                            input.handlers.zoom(sens, false);\r\n                        } else if (this.keysZoomOut.indexOf(keyCode) !== -1 || this.keysDown.indexOf(keyCode) !== -1) {\r\n                            input.handlers.zoom(-sens, false);\r\n                        }\r\n                    } else if (resolved.interaction === \"rotate\") {\r\n                        if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n                            input.handlers.rotate(-sens, 0);\r\n                        } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n                            input.handlers.rotate(sens, 0);\r\n                        } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n                            input.handlers.rotate(0, -sens);\r\n                        } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n                            input.handlers.rotate(0, sens);\r\n                        }\r\n                    } else if (resolved.interaction === \"pan\") {\r\n                        // Accumulate a unit direction per pan key; the combined vector is normalized after the loop.\r\n                        // Aggregate sensitivity with max so the pan speed is independent of key insertion order\r\n                        // when keys resolve to different per-key sensitivities.\r\n                        panSensitivity = Math.max(panSensitivity, sens);\r\n                        if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n                            panDirection.x += 1;\r\n                        } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n                            panDirection.x -= 1;\r\n                        } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n                            panDirection.y += 1;\r\n                        } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n                            panDirection.y -= 1;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Apply a single, normalized pan once all pan keys for this frame have been accumulated.\r\n            if (panDirection.x !== 0 || panDirection.y !== 0) {\r\n                // Normalize so a diagonal isn't faster than an axis-aligned pan (normalize() is a no-op on a zero-length vector).\r\n                panDirection.normalize().scaleInPlace(panSensitivity);\r\n\r\n                // Call into movement class handleDrag so that behavior matches that of pointer input, simulating drag from center of screen.\r\n                // getRenderWidth/Height return render buffer pixels (scaled by hardwareScalingLevel relative to CSS pixels),\r\n                // but the picking logic (scene.pick via CreatePickingRayToRef) expects CSS pixels (it divides by hardwareScalingLevel internally).\r\n                const hardwareScaling = this._engine.getHardwareScalingLevel();\r\n                const centerX = (this._engine.getRenderWidth() / 2) * hardwareScaling;\r\n                const centerY = (this._engine.getRenderHeight() / 2) * hardwareScaling;\r\n                input.handlers.pan.start(centerX, centerY);\r\n                input.handlers.pan.update(centerX + panDirection.x, centerY + panDirection.y);\r\n                input.handlers.pan.stop();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the current input.\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"GeospatialCameraKeyboardInput\";\r\n    }\r\n\r\n    /**\r\n     * Get the friendly name associated with the input class.\r\n     * @returns the input friendly name\r\n     */\r\n    public getSimpleName(): string {\r\n        return \"keyboard\";\r\n    }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"GeospatialCameraKeyboardInput\"] = GeospatialCameraKeyboardInput;\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\n\r\nconst DefaultReferenceFrameRate = 60;\r\n/**\r\n * Base class for camera movement systems that convert raw input into framerate-independent camera deltas.\r\n *\r\n * This class handles the physics layer: velocity tracking, inertial decay, speed multipliers,\r\n * and per-frame delta computation. Input mapping (which physical inputs trigger which interactions)\r\n * is handled by an `InputMapper` instance composed on each movement subclass as `input`.\r\n *\r\n * **Speed and inertia** — Properties on this class that control how accumulated pixel deltas\r\n * are converted to framerate-independent camera deltas via `computeCurrentFrameDeltas()`:\r\n * - `panSpeed`, `rotationXSpeed`, `rotationYSpeed`, `zoomSpeed` — units of movement per pixel\r\n * - `panInertia`, `rotationInertia`, `zoomInertia` — velocity decay factor when input stops (0 = instant stop, 0.9 = smooth glide)\r\n */\r\nexport class CameraMovement {\r\n    protected _scene: Scene;\r\n\r\n    /**\r\n     * Should be set by input classes to indicate whether there is active input this frame.\r\n     * This helps differentiate between 0 pixel delta due to no input vs user actively holding still.\r\n     */\r\n    public activeInput: boolean = false;\r\n\r\n    /**\r\n     * ------------ Speed ----------------\r\n     * Speed defines the amount of camera movement expected per input pixel movement\r\n     * -----------------------------------\r\n     */\r\n    /**\r\n     * Global speed multiplier applied to all movement (pan, rotation, zoom).\r\n     * Acts as a master scale factor on top of the individual speed properties.\r\n     */\r\n    public speed: number = 1;\r\n    /**\r\n     * Desired coordinate unit movement per input pixel when zooming\r\n     */\r\n    public zoomSpeed: number = 1;\r\n    /**\r\n     * Desired coordinate unit movement per input pixel when panning\r\n     */\r\n    public panSpeed: number = 1;\r\n    /**\r\n     * Desired radians movement per input pixel when rotating along x axis\r\n     */\r\n    public rotationXSpeed: number = 1;\r\n    /**\r\n     * Desired radians movement per input pixel when rotating along y axis\r\n     */\r\n    public rotationYSpeed: number = 1;\r\n\r\n    /**\r\n     * ----------- Speed multipliers ---------------\r\n     * Multipliers allow movement classes to modify the effective speed dynamically per-frame\r\n     * (ex: scale zoom based on distance from target)\r\n     * -----------------------------------\r\n     */\r\n    /**\r\n     * Multiplied atop zoom speed. Used to dynamically adjust zoom speed based on per-frame context (ex: zoom faster when further from target)\r\n     */\r\n    protected _zoomSpeedMultiplier: number = 1;\r\n    /**\r\n     * Multiplied atop pan speed. Used to dynamically adjust pan speed based on per-frame context (ex: pan slowly when close to target)\r\n     */\r\n    protected _panSpeedMultiplier: number = 1;\r\n\r\n    /**\r\n     * ---------- Inertia ----------------\r\n     * Inertia represents the decay factor per-frame applied to the velocity when there is no user input.\r\n     * 0 = No inertia, instant stop (velocity immediately becomes 0)\r\n     * 0.5 = Strong decay, velocity halves every frame at 60fps\r\n     * 0.9 = Moderate inertia, velocity retains 90% per frame at 60fps\r\n     * 0.95 = High inertia, smooth glide, velocity retains 95% per frame at 60fps\r\n     * 1 = Infinite inertia, never stops (velocity never decays)\r\n     * -----------------------------------\r\n     */\r\n    /**\r\n     * Inertia applied to the zoom velocity when there is no user input.\r\n     * Higher inertia === slower decay, velocity retains more of its value each frame.\r\n     *\r\n     * Note: ArcRotateCamera syncs this from `camera.inertia` via an accessor on the camera class.\r\n     * To tune independently, override inside `scene.onBeforeRenderObservable` after `camera.inertia` is read.\r\n     */\r\n    public zoomInertia: number = 0.9;\r\n    /**\r\n     * Inertia applied to the panning velocity when there is no user input.\r\n     * Higher inertia === slower decay, velocity retains more of its value each frame.\r\n     *\r\n     * Note: ArcRotateCamera overrides this from `camera.panningInertia` (which defaults to `camera.inertia`).\r\n     */\r\n    public panInertia: number = 0.9;\r\n    /**\r\n     * Inertia applied to the rotation velocity when there is no user input.\r\n     * Higher inertia === slower decay, velocity retains more of its value each frame.\r\n     *\r\n     * Note: ArcRotateCamera syncs this from `camera.inertia` via an accessor on the camera class.\r\n     * To tune independently, override inside `scene.onBeforeRenderObservable` after `camera.inertia` is read.\r\n     */\r\n    public rotationInertia: number = 0.9;\r\n\r\n    /**\r\n     * ---------- Accumulated Pixel Deltas -----------\r\n     * Pixel inputs accumulated throughout the frame by input classes (reset each frame after processing)\r\n     * -----------------------------------\r\n     */\r\n    /**\r\n     * Accumulated pixel delta (by input classes) for zoom this frame\r\n     * Read by computeCurrentFrameDeltas() function and converted into zoomDeltaCurrentFrame (taking speed into account)\r\n     * Reset to zero after each frame\r\n     */\r\n    public zoomAccumulatedPixels: number = 0;\r\n    /**\r\n     * Accumulated pixel delta (by input classes) for panning this frame\r\n     * Read by computeCurrentFrameDeltas() function and converted into panDeltaCurrentFrame (taking speed into account)\r\n     * Reset to zero after each frame\r\n     */\r\n    public panAccumulatedPixels: Vector3 = new Vector3();\r\n    /**\r\n     * Accumulated pixel delta (by input classes) for rotation this frame\r\n     * Read by computeCurrentFrameDeltas() function and converted into rotationDeltaCurrentFrame (taking speed into account)\r\n     * Reset to zero after each frame\r\n     */\r\n    public rotationAccumulatedPixels: Vector3 = new Vector3();\r\n\r\n    /**\r\n     * ---------- Current Frame Movement Deltas -----------\r\n     * Deltas read on each frame by camera class in order to move the camera\r\n     * -----------------------------------\r\n     */\r\n    /**\r\n     * Zoom delta to apply to camera this frame, computed by computeCurrentFrameDeltas() from zoomPixelDelta (taking speed into account)\r\n     */\r\n    public zoomDeltaCurrentFrame: number = 0;\r\n    /**\r\n     * Pan delta to apply to camera this frame, computed by computeCurrentFrameDeltas() from panPixelDelta (taking speed into account)\r\n     */\r\n    public panDeltaCurrentFrame: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Rotation delta to apply to camera this frame, computed by computeCurrentFrameDeltas() from rotationPixelDelta (taking speed into account)\r\n     */\r\n    public rotationDeltaCurrentFrame: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * ---------- Velocity -----------\r\n     * Used to track velocity between frames for inertia calculation\r\n     * -----------------------------------\r\n     */\r\n    /**\r\n     * Zoom pixel velocity used for inertia calculations (pixels / ms).\r\n     */\r\n    protected _zoomVelocity: number = 0;\r\n    /**\r\n     * Pan velocity used for inertia calculations (movement / time)\r\n     */\r\n    private _panVelocity: Vector3 = new Vector3();\r\n    /**\r\n     * Framerate (Hz) at which inertia values are calibrated. Default 60 matches legacy camera feel\r\n     * at any actual refresh rate. Override to 120, 144, etc. only if your app was tuned on that\r\n     * specific refresh rate under the legacy (framerate-dependent) camera math and you want to\r\n     * preserve that exact decay characteristic. Most applications should leave this at 60.\r\n     */\r\n    public referenceFrameRate: number = DefaultReferenceFrameRate;\r\n\r\n    /**\r\n     * Rotation velocity used for inertia calculations (movement / time)\r\n     */\r\n    private _rotationVelocity: Vector3 = new Vector3();\r\n\r\n    /**\r\n     * Last frame's effective deltaTime in ms. Updated at the end of each\r\n     * `computeCurrentFrameDeltas` call. Initialized to 0 so the very-first-frame fallback\r\n     * (used when the engine reports `getDeltaTime() === 0`) always reflects the *current*\r\n     * `referenceFrameRate` rather than baking in the value at construction time — see\r\n     * `_getEffectiveDeltaMs`.\r\n     */\r\n    private _prevFrameTimeMs: number = 0;\r\n\r\n    constructor(\r\n        scene: Scene,\r\n        protected _cameraPosition: Vector3,\r\n        protected _behavior?: InterpolatingBehavior\r\n    ) {\r\n        this._scene = scene;\r\n    }\r\n\r\n    /**\r\n     * When called, will take the accumulated pixel deltas set by input classes and convert them into current frame deltas, stored in currentFrameMovementDelta properties\r\n     * Takes speed, scaling, inertia, and framerate into account to ensure smooth movement\r\n     * Zeros out pixelDeltas before returning\r\n     */\r\n    public computeCurrentFrameDeltas(): void {\r\n        const deltaTimeMs = this._scene.getEngine().getDeltaTime();\r\n        // Use prevFrameTime as fallback when deltaTime is 0 (e.g. first render frame in tests or unusual conditions)\r\n        const effectiveDeltaMs = this._getEffectiveDeltaMs(deltaTimeMs);\r\n\r\n        // Fast-path: when nothing is moving (no accumulated input, all velocities zero), skip all work.\r\n        if (\r\n            this._zoomVelocity === 0 &&\r\n            this.zoomAccumulatedPixels === 0 &&\r\n            this._panVelocity.x === 0 &&\r\n            this._panVelocity.y === 0 &&\r\n            this._panVelocity.z === 0 &&\r\n            this.panAccumulatedPixels.x === 0 &&\r\n            this.panAccumulatedPixels.y === 0 &&\r\n            this.panAccumulatedPixels.z === 0 &&\r\n            this._rotationVelocity.x === 0 &&\r\n            this._rotationVelocity.y === 0 &&\r\n            this._rotationVelocity.z === 0 &&\r\n            this.rotationAccumulatedPixels.x === 0 &&\r\n            this.rotationAccumulatedPixels.y === 0 &&\r\n            this.rotationAccumulatedPixels.z === 0 &&\r\n            !this.activeInput\r\n        ) {\r\n            this.panDeltaCurrentFrame.setAll(0);\r\n            this.rotationDeltaCurrentFrame.setAll(0);\r\n            this.zoomDeltaCurrentFrame = 0;\r\n            if (deltaTimeMs > 0) {\r\n                this._prevFrameTimeMs = deltaTimeMs;\r\n            }\r\n            return;\r\n        }\r\n\r\n        this.panDeltaCurrentFrame.setAll(0);\r\n        this.rotationDeltaCurrentFrame.setAll(0);\r\n        this.zoomDeltaCurrentFrame = 0;\r\n\r\n        const hasUserInput = this.panAccumulatedPixels.lengthSquared() > 0 || this.rotationAccumulatedPixels.lengthSquared() > 0 || this.zoomAccumulatedPixels !== 0;\r\n\r\n        if (hasUserInput && this._behavior?.isInterpolating) {\r\n            this._behavior.stopAllAnimations();\r\n        }\r\n\r\n        this._panVelocity.copyFromFloats(\r\n            this._calculateCurrentVelocity(this._panVelocity.x, this.panAccumulatedPixels.x, this.panInertia),\r\n            this._calculateCurrentVelocity(this._panVelocity.y, this.panAccumulatedPixels.y, this.panInertia),\r\n            this._calculateCurrentVelocity(this._panVelocity.z, this.panAccumulatedPixels.z, this.panInertia)\r\n        );\r\n        this._panVelocity.scaleToRef(this.speed * this.panSpeed * this._panSpeedMultiplier * effectiveDeltaMs, this.panDeltaCurrentFrame);\r\n\r\n        this._rotationVelocity.copyFromFloats(\r\n            this._calculateCurrentVelocity(this._rotationVelocity.x, this.rotationAccumulatedPixels.x, this.rotationInertia),\r\n            this._calculateCurrentVelocity(this._rotationVelocity.y, this.rotationAccumulatedPixels.y, this.rotationInertia),\r\n            this._calculateCurrentVelocity(this._rotationVelocity.z, this.rotationAccumulatedPixels.z, this.rotationInertia)\r\n        );\r\n        this.rotationDeltaCurrentFrame.copyFromFloats(\r\n            this._rotationVelocity.x * this.speed * this.rotationXSpeed * effectiveDeltaMs,\r\n            this._rotationVelocity.y * this.speed * this.rotationYSpeed * effectiveDeltaMs,\r\n            // z is not used by current handlers; keep at 0. Add a rotationZSpeed if z motion is wired up later.\r\n            0\r\n        );\r\n\r\n        this._zoomVelocity = this._calculateCurrentVelocity(this._zoomVelocity, this.zoomAccumulatedPixels, this.zoomInertia);\r\n        this.zoomDeltaCurrentFrame = this._zoomVelocity * (this.speed * this.zoomSpeed * this._zoomSpeedMultiplier) * effectiveDeltaMs;\r\n\r\n        if (deltaTimeMs > 0) {\r\n            this._prevFrameTimeMs = deltaTimeMs;\r\n        }\r\n        this.zoomAccumulatedPixels = 0;\r\n        this.panAccumulatedPixels.setAll(0);\r\n        this.rotationAccumulatedPixels.setAll(0);\r\n        this.activeInput = false;\r\n    }\r\n\r\n    /**\r\n     * Resets the rotation velocity and accumulated pixels, stopping any in-progress rotation inertia.\r\n     * Called when inertialAlphaOffset or inertialBetaOffset are explicitly zeroed (backward compat).\r\n     */\r\n    public resetRotationVelocity(): void {\r\n        this._rotationVelocity.setAll(0);\r\n        this.rotationAccumulatedPixels.setAll(0);\r\n    }\r\n\r\n    /**\r\n     * Resets the pan velocity and accumulated pixels, stopping any in-progress pan inertia.\r\n     */\r\n    public resetPanVelocity(): void {\r\n        this._panVelocity.setAll(0);\r\n        this.panAccumulatedPixels.setAll(0);\r\n    }\r\n\r\n    /**\r\n     * Resets the zoom velocity and accumulated pixels, stopping any in-progress zoom inertia.\r\n     * Called when inertialRadiusOffset is explicitly zeroed out (backward compat).\r\n     */\r\n    public resetZoomVelocity(): void {\r\n        this._zoomVelocity = 0;\r\n        this.zoomAccumulatedPixels = 0;\r\n    }\r\n\r\n    /**\r\n     * Returns true when the camera is playing an interpolating (fly-to) animation.\r\n     * Useful for suppressing user-input movement while a programmatic animation is active.\r\n     */\r\n    public get isInterpolating(): boolean {\r\n        return !!this._behavior?.isInterpolating;\r\n    }\r\n\r\n    /**\r\n     * Returns the per-frame decay factor for a given inertia, adjusted to this frame's `dt`.\r\n     * At the reference frame rate, returns `inertia` unchanged (matches legacy per-frame `*= inertia`).\r\n     * Use this when implementing custom decaying accumulators (e.g. zoom-to-cursor coupled pan)\r\n     * that need framerate-independent glide duration.\r\n     * @param inertia - The inertia value (0-1) whose per-frame decay factor is needed.\r\n     * @returns The decay factor to multiply a value by this frame.\r\n     */\r\n    public getFrameIndependentDecay(inertia: number): number {\r\n        const dt = this._scene.getEngine().getDeltaTime();\r\n        const effectiveDt = this._getEffectiveDeltaMs(dt);\r\n        const referenceFrameDurationMs = 1000 / this.referenceFrameRate;\r\n        return Math.pow(inertia, effectiveDt / referenceFrameDurationMs);\r\n    }\r\n\r\n    /**\r\n     * Returns the input-scale factor to apply to an impulse injected into a decaying accumulator\r\n     * so that the integrated total is framerate-independent and matches legacy at 60fps.\r\n     * At the reference frame rate, returns 1 (no-op). At high fps, scales the impulse down so\r\n     * the sum over the decay tail stays equal to `impulse / (1 - inertia)` — the legacy total.\r\n     * @param inertia - The inertia value (0-1) used by the accumulator.\r\n     * @returns The scaling factor to multiply an impulse by before adding it to the accumulator.\r\n     */\r\n    public getFrameIndependentInputScale(inertia: number): number {\r\n        const oneMinusInertia = 1 - inertia;\r\n        if (oneMinusInertia <= 0) {\r\n            return 1;\r\n        }\r\n        const decay = this.getFrameIndependentDecay(inertia);\r\n        return (1 - decay) / oneMinusInertia;\r\n    }\r\n\r\n    /**\r\n     * Resolves the effective delta time for the current frame, falling back to the previous\r\n     * frame's value when the engine reports a 0 delta. When neither is available yet (first\r\n     * frame), falls back to the duration of one frame at `referenceFrameRate` so the very\r\n     * first frame's decay matches the user's currently configured frame rate.\r\n     * @param dt - Raw delta time in ms reported by the engine (0 if unavailable this frame).\r\n     * @returns The effective delta time in ms to use for this frame's decay calculations.\r\n     */\r\n    private _getEffectiveDeltaMs(dt: number): number {\r\n        if (dt > 0) {\r\n            return dt;\r\n        }\r\n        if (this._prevFrameTimeMs > 0) {\r\n            return this._prevFrameTimeMs;\r\n        }\r\n        return 1000 / this.referenceFrameRate;\r\n    }\r\n\r\n    private _calculateCurrentVelocity(velocityRef: number, pixelDelta: number, inertialDecayFactor: number): number {\r\n        let inputVelocity = velocityRef;\r\n        const deltaTimeMs = this._scene.getEngine().getDeltaTime();\r\n        // Use prevFrameTime as fallback when deltaTime is 0 (e.g. first render frame in tests or unusual conditions)\r\n        const effectiveDeltaMs = this._getEffectiveDeltaMs(deltaTimeMs);\r\n\r\n        if (effectiveDeltaMs === 0) {\r\n            return inputVelocity;\r\n        }\r\n\r\n        // Apply inertial decay every frame\r\n        const frameIndependentDecay = this.getFrameIndependentDecay(inertialDecayFactor);\r\n        inputVelocity *= frameIndependentDecay;\r\n\r\n        // When there's input this frame, add it on top of the decayed velocity — matches legacy's\r\n        // `offset += pointerDelta` accumulation. The `inputScale` factor keeps the sustained-drag\r\n        // steady-state identical to legacy at the reference framerate (`R/(1-inertia)`) at any\r\n        // actual framerate. Without this factor, `v_ss = R/(1-pow(k, dt/T))` blows up at high fps\r\n        // (2.3x at 144fps). When running at the reference framerate, inputScale = 1 (no-op).\r\n        if (pixelDelta !== 0 || this.activeInput) {\r\n            const oneMinusInertia = 1 - inertialDecayFactor;\r\n            const inputScale = oneMinusInertia > 0 ? (1 - frameIndependentDecay) / oneMinusInertia : 1;\r\n            inputVelocity += (pixelDelta / effectiveDeltaMs) * inputScale;\r\n        } else if (Math.abs(inputVelocity) < 1e-6) {\r\n            // Epsilon cutoff when gliding with no input\r\n            inputVelocity = 0;\r\n        }\r\n\r\n        return inputVelocity;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Physical input source that generated an interaction.\r\n */\r\nexport type InputSource = \"pointer\" | \"wheel\" | \"touch\" | \"keyboard\";\r\n\r\n/**\r\n * Modifier key state, shared across input sources that support modifiers.\r\n */\r\nexport type InputModifiers = {\r\n    /** Ctrl key pressed */\r\n    ctrl?: boolean;\r\n    /** Shift key pressed */\r\n    shift?: boolean;\r\n    /** Alt key pressed */\r\n    alt?: boolean;\r\n};\r\n\r\n// ── Per-source condition shapes ────────────────────────────────────\r\n\r\n/**\r\n * Conditions for pointer inputs.\r\n */\r\nexport type PointerConditions = {\r\n    /** Mouse button (0=left, 1=middle, 2=right). Omit to match any button. */\r\n    button?: number;\r\n    /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n    modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for mouse wheel inputs.\r\n */\r\nexport type WheelConditions = {\r\n    /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n    modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for touch inputs.\r\n */\r\nexport type TouchConditions = {\r\n    /** Number of active touch points. Omit to match any count. */\r\n    touchCount?: number;\r\n};\r\n\r\n/**\r\n * Conditions for keyboard inputs.\r\n */\r\nexport type KeyboardConditions = {\r\n    /** Key code of the current key being resolved. Omit to match any key. */\r\n    key?: number;\r\n    /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n    modifiers?: InputModifiers;\r\n};\r\n\r\n// ── Per-source inputMap entry types ────────────────────────────────\r\n\r\n/**\r\n * Mapping rule for pointer (mouse button) inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type PointerInputMapEntry<TInteraction extends string = string> = {\r\n    source: \"pointer\";\r\n    interaction: TInteraction;\r\n    /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n    sensitivity?: number;\r\n    /** Optional per-axis override for the X (horizontal / yaw) component. Falls back to `sensitivity` if unset. */\r\n    sensitivityX?: number;\r\n    /** Optional per-axis override for the Y (vertical / pitch) component. Falls back to `sensitivity` if unset. */\r\n    sensitivityY?: number;\r\n} & PointerConditions;\r\n\r\n/**\r\n * Mapping rule for mouse wheel inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type WheelInputMapEntry<TInteraction extends string = string> = {\r\n    source: \"wheel\";\r\n    interaction: TInteraction;\r\n    /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n    sensitivity?: number;\r\n} & WheelConditions;\r\n\r\n/**\r\n * Mapping rule for touch inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type TouchInputMapEntry<TInteraction extends string = string> = {\r\n    source: \"touch\";\r\n    interaction: TInteraction;\r\n    /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n    sensitivity?: number;\r\n    /** Optional per-axis override for the X component. Falls back to `sensitivity` if unset. */\r\n    sensitivityX?: number;\r\n    /** Optional per-axis override for the Y component. Falls back to `sensitivity` if unset. */\r\n    sensitivityY?: number;\r\n} & TouchConditions;\r\n\r\n/**\r\n * Mapping rule for keyboard inputs.\r\n * The `key` field on the entry supports a single key code or an array of key codes for matching.\r\n * When resolving, the condition's `key` is checked against the entry's `key` value(s).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type KeyboardInputMapEntry<TInteraction extends string = string> = {\r\n    /** Discriminator: keyboard input source */\r\n    source: \"keyboard\";\r\n    /** Interaction type to dispatch when this entry matches */\r\n    interaction: TInteraction;\r\n    /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n    sensitivity?: number;\r\n    /** Key code filter(s). Supports a single code or an array. Omit to match any key. */\r\n    key?: number | number[];\r\n    /** Modifier keys that must be active for this entry to match. Omit to match regardless of modifiers. */\r\n    modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * A single mapping rule: source + optional conditions → interaction type.\r\n * The inputMap is an ordered array on the movement class; first matching entry wins.\r\n * The interaction string should match a handler property name on the camera's movement subclass.\r\n *\r\n * Discriminated union by `source` — only fields relevant to that source are available.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InputMapEntry<TInteraction extends string = string> =\r\n    PointerInputMapEntry<TInteraction> | WheelInputMapEntry<TInteraction> | TouchInputMapEntry<TInteraction> | KeyboardInputMapEntry<TInteraction>;\r\n\r\n/**\r\n * Flat conditions object passed to resolveInteraction().\r\n * Only the fields relevant to the source type need to be set.\r\n * Per-source condition types (PointerConditions, KeyboardConditions, etc.) are subtypes\r\n * of this and should be used at call sites for clarity.\r\n */\r\nexport type InputConditions = {\r\n    /** Mouse button (0=left, 1=middle, 2=right) */\r\n    button?: number;\r\n    /** Current modifier key state */\r\n    modifiers?: InputModifiers;\r\n    /** Number of active touch points */\r\n    touchCount?: number;\r\n    /** Key code of the current key being resolved */\r\n    key?: number;\r\n};\r\n\r\n/**\r\n * Extracts the string-typed interaction names from a handlers object type.\r\n * Equivalent to `keyof THandlers & string` — filters out symbol/number keys.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InteractionName<THandlers> = keyof THandlers & string;\r\n\r\n/**\r\n * Generic input-to-interaction mapper that resolves physical input events to semantic interaction types\r\n * and dispatches them to typed handlers.\r\n *\r\n * `InputMapper` is not tied to cameras — any object that needs a configurable, prioritized\r\n * mapping from physical inputs (pointer, keyboard, wheel, touch) to named interactions can use it.\r\n *\r\n * The mapper holds an ordered `inputMap` array. When `resolveInteraction` is called, the first\r\n * entry whose source and conditions match the current input wins. More specific entries (with more\r\n * conditions like button, key, modifiers) should be placed before less specific ones; use `addEntry`\r\n * to auto-insert based on specificity.\r\n *\r\n * @typeParam THandlers - Object type whose keys are the valid interaction type strings and values\r\n *   are the handler functions/objects for each interaction (e.g. `ArcRotateHandlers`).\r\n *   Interaction types are derived as `InteractionName<THandlers>`.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class InputMapper<THandlers extends Record<string, unknown>> {\r\n    /**\r\n     * Ordered list of input-to-interaction mapping rules. First matching entry wins.\r\n     */\r\n    public inputMap: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n\r\n    /**\r\n     * Interaction handlers keyed by interaction type.\r\n     * Override individual handlers to customize behavior without changing input mapping.\r\n     */\r\n    public readonly handlers: THandlers;\r\n\r\n    /**\r\n     * Creates a new InputMapper.\r\n     * @param handlers - The interaction handlers, keyed by interaction type.\r\n     * @param createDefaultEntries - Optional factory that returns the default inputMap entries.\r\n     *   Called by `resetInputMap()` and during construction. When omitted, the default map is empty.\r\n     */\r\n    constructor(handlers: THandlers, createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[]) {\r\n        this.handlers = handlers;\r\n        this._createDefaultEntries = createDefaultEntries;\r\n        this.resetInputMap();\r\n    }\r\n\r\n    private _createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[];\r\n\r\n    /**\r\n     * Resolves a physical input event to a matching inputMap entry.\r\n     * Iterates the inputMap in order; the first entry whose source and conditions match wins.\r\n     * @param source - The physical input source (e.g. \"pointer\", \"keyboard\")\r\n     * @param currentConditions - Conditions to match against, specific to the source type\r\n     * @returns The matched InputMapEntry, or null if no entry matches\r\n     */\r\n    public resolveInteraction(source: \"pointer\", currentConditions?: InputConditions): PointerInputMapEntry<InteractionName<THandlers>> | null;\r\n    public resolveInteraction(source: \"wheel\", currentConditions?: InputConditions): WheelInputMapEntry<InteractionName<THandlers>> | null;\r\n    public resolveInteraction(source: \"touch\", currentConditions?: InputConditions): TouchInputMapEntry<InteractionName<THandlers>> | null;\r\n    public resolveInteraction(source: \"keyboard\", currentConditions?: InputConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | null;\r\n    public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null;\r\n    public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null {\r\n        for (const entry of this.inputMap) {\r\n            if (entry.source === source && this._entryMatches(entry, currentConditions)) {\r\n                return entry;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Restores the inputMap to the default entries provided at construction time.\r\n     * If no factory was provided, resets to an empty array.\r\n     */\r\n    public resetInputMap(): void {\r\n        this.inputMap = this._createDefaultEntries?.() ?? [];\r\n    }\r\n\r\n    /**\r\n     * Finds the first inputMap entry matching the given source, interaction, and optional entry conditions.\r\n     * Useful for modifying entry properties (e.g. sensitivity) without rebuilding the entire inputMap.\r\n     * @param source - The physical input source to match\r\n     * @param interaction - The interaction type to match\r\n     * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n     * @returns The matching entry, or undefined if not found\r\n     */\r\n    public getEntry(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>> | undefined;\r\n    public getEntry(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>> | undefined;\r\n    public getEntry(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>> | undefined;\r\n    public getEntry(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | undefined;\r\n    public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined;\r\n    public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined {\r\n        // Manual loop instead of `inputMap.find(arrow)` to avoid per-call closure allocation;\r\n        // this is hit per pointer-move from multi-touch panning paths.\r\n        const arr = this.inputMap;\r\n        for (let i = 0; i < arr.length; i++) {\r\n            const e = arr[i];\r\n            if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n                return e;\r\n            }\r\n        }\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Finds all inputMap entries matching the given source, interaction, and optional entry conditions.\r\n     * Useful for bulk updates when more than one physical input maps to the same interaction.\r\n     * @param source - The physical input source to match\r\n     * @param interaction - The interaction type to match\r\n     * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n     * @returns All matching entries, in inputMap order\r\n     */\r\n    public getEntries(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>>[];\r\n    public getEntries(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>>[];\r\n    public getEntries(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>>[];\r\n    public getEntries(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>>[];\r\n    public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[];\r\n    public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[] {\r\n        const matches: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n        const arr = this.inputMap;\r\n        for (let i = 0; i < arr.length; i++) {\r\n            const e = arr[i];\r\n            if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n                matches.push(e);\r\n            }\r\n        }\r\n        return matches;\r\n    }\r\n\r\n    /**\r\n     * Adds an entry to the inputMap at the correct position based on specificity.\r\n     * More specific entries (with more conditions like button, key, modifiers) are placed\r\n     * before less specific ones, ensuring they match first. Among equally specific entries,\r\n     * the new entry is placed after existing ones.\r\n     * @param entry - The entry to add\r\n     */\r\n    public addEntry(entry: InputMapEntry<InteractionName<THandlers>>): void {\r\n        const score = this._entrySpecificity(entry);\r\n        let insertIndex = this.inputMap.length;\r\n        for (let i = 0; i < this.inputMap.length; i++) {\r\n            if (this._entrySpecificity(this.inputMap[i]) < score) {\r\n                insertIndex = i;\r\n                break;\r\n            }\r\n        }\r\n        this.inputMap.splice(insertIndex, 0, entry);\r\n    }\r\n\r\n    /**\r\n     * Sets the interaction for the input combination described by `conditions`. If an\r\n     * existing entry maps that exact combination, its `interaction` is updated in place;\r\n     * otherwise a new entry is inserted via {@link addEntry}.\r\n     *\r\n     * To force an update on every matching entry use {@link setInteractions}; to address\r\n     * an individual entry beyond the first, look it up via {@link getEntries} and assign\r\n     * `entry.interaction` directly.\r\n     * @param source - The physical input source to match\r\n     * @param conditions - Conditions describing the input combination (button, modifiers, key, etc.)\r\n     * @param interaction - The interaction to assign / insert\r\n     * @returns true (the mapping is always made effective)\r\n     */\r\n    public setInteraction(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): boolean {\r\n        // resolveInteraction returns the first entry that fires for `conditions` (so its\r\n        // conditions are no stricter than the request). If that entry also covers every\r\n        // condition present in the request, it's an exact match — mutate. Otherwise it's\r\n        // broader (or nothing matches): add a more-specific entry so we don't clobber the\r\n        // broader one.\r\n        const entry = this.resolveInteraction(source, conditions);\r\n        if (entry && this._entryCoversAllConditionsOf(entry, conditions)) {\r\n            entry.interaction = interaction;\r\n            return true;\r\n        }\r\n        this.addEntry({ source, ...(conditions ?? {}), interaction } as InputMapEntry<InteractionName<THandlers>>);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns true when `entry` constrains every field that `conditions` specifies — i.e.\r\n     * `entry` covers all of the request's conditions. Used by {@link setInteraction} as one\r\n     * half of the \"exactly as specific\" check: combined with {@link resolveInteraction}'s\r\n     * guarantee that the returned entry is no *stricter* than the request, a true result\r\n     * here means `entry` and `conditions` constrain the same fields, and mutating\r\n     * `entry.interaction` is safe.\r\n     *\r\n     * On its own this predicate does not exclude entries that are stricter than `conditions`\r\n     * (those would also trivially cover every field present in `conditions`); callers must\r\n     * rely on the upstream resolve step to rule them out.\r\n     *\r\n     * `InputConditions` is a flat type covering all source-specific fields (`button`, `key`,\r\n     * `touchCount`, `modifiers`); for any given source the irrelevant fields are `undefined`\r\n     * on both `entry` and `conditions`, so checking them all is harmless.\r\n     * @param entry - The matched inputMap entry to test\r\n     * @param conditions - The conditions the caller supplied to `setInteraction`\r\n     * @returns true if `entry` covers every condition present in `conditions`\r\n     */\r\n    private _entryCoversAllConditionsOf(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n        if (!conditions) {\r\n            return true;\r\n        }\r\n        // `as any` here because `entry` is a discriminated union and TypeScript can't narrow it\r\n        // from a string-keyed loop. The runtime check is harmless: irrelevant-for-this-source\r\n        // fields are undefined on both entry and conditions and skip the early return.\r\n        const e = entry as any;\r\n        for (const key of Object.keys(conditions) as (keyof InputConditions)[]) {\r\n            const condValue = conditions[key];\r\n            if (condValue === undefined) {\r\n                continue;\r\n            }\r\n            if (key === \"modifiers\") {\r\n                const entryMods = (e.modifiers ?? {}) as InputModifiers;\r\n                for (const modKey of Object.keys(condValue) as (keyof InputModifiers)[]) {\r\n                    if ((condValue as InputModifiers)[modKey] !== undefined && entryMods[modKey] === undefined) {\r\n                        return false;\r\n                    }\r\n                }\r\n            } else if (e[key] === undefined) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Changes the interaction for every inputMap entry matching the given source and conditions.\r\n     * Useful when more than one entry maps to the same physical input (e.g. duplicate bindings,\r\n     * or several keys aliased to the same action) and all of them should be remapped together.\r\n     * @param source - The physical input source to match\r\n     * @param conditions - Conditions to match (button, modifiers, key, etc.). Uses the same\r\n     *                     event-resolution semantics as {@link resolveInteraction}: omitted entry\r\n     *                     condition fields are treated as wildcards and will match.\r\n     * @param interaction - The new interaction to assign to every matched entry\r\n     * @returns The number of entries that were updated\r\n     */\r\n    public setInteractions(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): number {\r\n        let count = 0;\r\n        const arr = this.inputMap;\r\n        for (let i = 0; i < arr.length; i++) {\r\n            const entry = arr[i];\r\n            if (entry.source === source && this._entryMatches(entry, conditions)) {\r\n                entry.interaction = interaction;\r\n                count++;\r\n            }\r\n        }\r\n        return count;\r\n    }\r\n\r\n    private _entryMatches(entry: InputMapEntry<InteractionName<THandlers>>, currentConditions?: InputConditions): boolean {\r\n        switch (entry.source) {\r\n            case \"pointer\":\r\n                if (entry.button !== undefined && entry.button !== currentConditions?.button) {\r\n                    return false;\r\n                }\r\n                return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n            case \"wheel\":\r\n                return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n            case \"touch\":\r\n                if (entry.touchCount !== undefined && entry.touchCount !== currentConditions?.touchCount) {\r\n                    return false;\r\n                }\r\n                return true;\r\n            case \"keyboard\":\r\n                if (entry.key !== undefined) {\r\n                    if (Array.isArray(entry.key) ? entry.key.indexOf(currentConditions?.key ?? -1) === -1 : entry.key !== currentConditions?.key) {\r\n                        return false;\r\n                    }\r\n                }\r\n                return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n        }\r\n    }\r\n\r\n    private _entryConditionsMatch(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n        if (!conditions) {\r\n            return true;\r\n        }\r\n\r\n        // NOTE: Uses the `\"key\" in conditions` form rather than `conditions.key !== undefined`\r\n        // so that callers can explicitly target entries with no constraint via\r\n        // `getEntries({ button: undefined })` — i.e. \"find catch-all entries that don't\r\n        // require a specific button\". `!== undefined` would silently ignore a deliberate\r\n        // `undefined` and behave like the property was omitted, which would be wrong here.\r\n        switch (entry.source) {\r\n            case \"pointer\":\r\n                if (\"button\" in conditions && entry.button !== conditions.button) {\r\n                    return false;\r\n                }\r\n                return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n            case \"wheel\":\r\n                return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n            case \"touch\":\r\n                return !(\"touchCount\" in conditions) || entry.touchCount === conditions.touchCount;\r\n            case \"keyboard\":\r\n                if (\"key\" in conditions) {\r\n                    if (entry.key === undefined) {\r\n                        return conditions.key === undefined;\r\n                    }\r\n                    if (conditions.key === undefined || (Array.isArray(entry.key) ? entry.key.indexOf(conditions.key) === -1 : entry.key !== conditions.key)) {\r\n                        return false;\r\n                    }\r\n                }\r\n                return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n        }\r\n    }\r\n\r\n    private _entrySpecificity(entry: InputMapEntry<InteractionName<THandlers>>): number {\r\n        let score = 0;\r\n        if (\"button\" in entry && entry.button !== undefined) {\r\n            score++;\r\n        }\r\n        if (\"key\" in entry && entry.key !== undefined) {\r\n            score++;\r\n        }\r\n        if (\"touchCount\" in entry && entry.touchCount !== undefined) {\r\n            score++;\r\n        }\r\n        if (\"modifiers\" in entry && entry.modifiers) {\r\n            score++;\r\n        }\r\n        return score;\r\n    }\r\n\r\n    private _matchModifiers(entryModifiers?: InputModifiers, currentModifiers?: InputModifiers): boolean {\r\n        if (!entryModifiers) {\r\n            return true;\r\n        }\r\n        if (entryModifiers.ctrl !== undefined && entryModifiers.ctrl !== (currentModifiers?.ctrl ?? false)) {\r\n            return false;\r\n        }\r\n        if (entryModifiers.shift !== undefined && entryModifiers.shift !== (currentModifiers?.shift ?? false)) {\r\n            return false;\r\n        }\r\n        if (entryModifiers.alt !== undefined && entryModifiers.alt !== (currentModifiers?.alt ?? false)) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private _entryModifiersMatch(entryModifiers?: InputModifiers, conditionsModifiers?: InputModifiers): boolean {\r\n        if (!conditionsModifiers) {\r\n            return !entryModifiers;\r\n        }\r\n\r\n        const hasModifierConditions = conditionsModifiers.ctrl !== undefined || conditionsModifiers.shift !== undefined || conditionsModifiers.alt !== undefined;\r\n        if (!hasModifierConditions) {\r\n            return !entryModifiers || (entryModifiers.ctrl === undefined && entryModifiers.shift === undefined && entryModifiers.alt === undefined);\r\n        }\r\n\r\n        if (conditionsModifiers.ctrl !== undefined && entryModifiers?.ctrl !== conditionsModifiers.ctrl) {\r\n            return false;\r\n        }\r\n        if (conditionsModifiers.shift !== undefined && entryModifiers?.shift !== conditionsModifiers.shift) {\r\n            return false;\r\n        }\r\n        if (conditionsModifiers.alt !== undefined && entryModifiers?.alt !== conditionsModifiers.alt) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { CameraMovement } from \"./cameraMovement\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport { type InputMapEntry, InputMapper } from \"./inputMapper\";\r\n\r\n// ── TargetCamera handler types ─────────────────────────────────────\r\n\r\n/**\r\n * Handler shape for target/free camera interactions.\r\n * Property names are the canonical interaction type strings used in inputMap entries.\r\n * All handlers are plain functions since none need multi-method lifecycle.\r\n */\r\nexport type TargetCameraHandlers = {\r\n    /**\r\n     * Translate the camera by world-space deltas (already oriented; the camera applies them directly).\r\n     * Mirrors the legacy `cameraDirection` accumulation surface, which input classes populate after\r\n     * transforming their local intent (e.g. keyboard strafe) into world space.\r\n     */\r\n    translate: (deltaX: number, deltaY: number, deltaZ: number) => void;\r\n    /**\r\n     * Rotate the camera by pitch/yaw deltas.\r\n     * pitch rotates around the local X axis (look up/down), yaw around the local Y axis (look left/right).\r\n     * Mirrors the legacy `cameraRotation` accumulation surface (x = pitch, y = yaw).\r\n     */\r\n    rotate: (pitch: number, yaw: number) => void;\r\n};\r\n\r\n/** Interaction type string for target/free camera, derived from handler property names */\r\nexport type TargetCameraInteraction = keyof TargetCameraHandlers;\r\n\r\n/**\r\n * Shared movement system for {@link TargetCamera} and its subclasses (FreeCamera, FlyCamera,\r\n * FollowCamera). Provides framerate-independent physics (via {@link CameraMovement}) and a\r\n * declarative {@link InputMapper} for configuring which physical inputs trigger which interactions.\r\n *\r\n * Accumulator mapping for this camera family:\r\n * - `translate` feeds `panAccumulatedPixels` as a WORLD-space direction (input classes orient local\r\n *   intent into world space before populating it, mirroring the legacy `cameraDirection` surface).\r\n * - `rotate` feeds `rotationAccumulatedPixels` (x=pitch, y=yaw), mirroring legacy `cameraRotation`.\r\n *\r\n * These camera classes have no separate zoom channel: mouse-wheel input folds into translation/rotation\r\n * just like the legacy inputs, so there is no `zoom` interaction here.\r\n *\r\n * Input classes inject deltas using the same scaling they applied historically and the movement\r\n * system leaves all speed multipliers at 1, so at the reference framerate the per-frame applied\r\n * delta matches the legacy value exactly while inertial glide becomes framerate-independent.\r\n */\r\nexport class TargetCameraMovement extends CameraMovement {\r\n    /** Input system that maps physical inputs to interactions and dispatches to handlers. */\r\n    public readonly input: InputMapper<TargetCameraHandlers>;\r\n\r\n    /**\r\n     * Creates a movement system for the {@link TargetCamera} family.\r\n     * @param scene The scene the owning camera belongs to.\r\n     * @param cameraPosition The owning camera's position vector (shared by reference).\r\n     * @param behavior Optional interpolating behavior used to suppress input while animating.\r\n     */\r\n    constructor(scene: Scene, cameraPosition: Vector3, behavior?: InterpolatingBehavior) {\r\n        super(scene, cameraPosition, behavior);\r\n\r\n        this.input = new InputMapper<TargetCameraHandlers>(\r\n            {\r\n                translate: (deltaX, deltaY, deltaZ) => {\r\n                    this.panAccumulatedPixels.x += deltaX;\r\n                    this.panAccumulatedPixels.y += deltaY;\r\n                    this.panAccumulatedPixels.z += deltaZ;\r\n                },\r\n                rotate: (pitch, yaw) => {\r\n                    this.rotationAccumulatedPixels.x += pitch;\r\n                    this.rotationAccumulatedPixels.y += yaw;\r\n                },\r\n            },\r\n            () => this._createDefaultInputMap()\r\n        );\r\n    }\r\n\r\n    private _createDefaultInputMap(): InputMapEntry<TargetCameraInteraction>[] {\r\n        // Default entries leave `sensitivity` unset so each input class falls back to its legacy\r\n        // sensibility properties (`angularSensibility`, `rotationSpeed`, `touchAngularSensibility`,\r\n        // etc.) for backward compatibility. Setting `sensitivity` on an entry overrides those.\r\n        //\r\n        // These entries declare which interactions each source is allowed to drive; the input\r\n        // classes still decide *direction* from their own configuration (keyboard key lists,\r\n        // touch single/multi-finger mode, mouse-wheel per-axis actions). Removing an entry\r\n        // disables that source→interaction pairing without otherwise changing the input class.\r\n        return [\r\n            // Mouse drag → look (any button; FreeCameraMouseInput gates on its own `buttons` list).\r\n            { source: \"pointer\", interaction: \"rotate\" },\r\n            // Keyboard movement keys → translate, rotation keys → look.\r\n            { source: \"keyboard\", interaction: \"translate\" },\r\n            { source: \"keyboard\", interaction: \"rotate\" },\r\n            // Touch drag → look or move depending on the input's single/multi-finger mode.\r\n            { source: \"touch\", interaction: \"rotate\" },\r\n            { source: \"touch\", interaction: \"translate\" },\r\n        ];\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsVector3, serializeAsMeshReference } from \"../Misc/decorators\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Camera } from \"./camera.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Quaternion, Matrix, Vector3, Vector2, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { Axis } from \"../Maths/math.axis\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Node } from \"../node\";\r\nimport { type CameraMovement } from \"./cameraMovement\";\r\nimport { TargetCameraMovement } from \"./targetCameraMovement\";\r\n\r\n// Temporary cache variables to avoid allocations.\r\nconst TmpMatrix = /*#__PURE__*/ Matrix.Zero();\r\nconst TmpQuaternion = /*#__PURE__*/ Quaternion.Identity();\r\n\r\n/**\r\n * A target camera takes a mesh or position as a target and continues to look at it while it moves.\r\n * This is the base of the follow, arc rotate cameras and Free camera\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n */\r\nexport class TargetCamera extends Camera {\r\n    private static _RigCamTransformMatrix = /*#__PURE__*/ new Matrix();\r\n    private static _TargetTransformMatrix = /*#__PURE__*/ new Matrix();\r\n    private static _TargetFocalPoint = /*#__PURE__*/ new Vector3();\r\n\r\n    /**\r\n     * Define the current direction the camera is moving to\r\n     */\r\n    public cameraDirection = new Vector3(0, 0, 0);\r\n    /**\r\n     * Define the current rotation the camera is rotating to\r\n     */\r\n    public cameraRotation = new Vector2(0, 0);\r\n\r\n    /**\r\n     * Framerate-independent movement controller shared by the TargetCamera family\r\n     * (FreeCamera/FlyCamera/FollowCamera). Provides inertial physics and the configurable\r\n     * input map. Subclasses may replace it with a specialized {@link CameraMovement}\r\n     * (for example ArcRotateCamera uses ArcRotateCameraMovement).\r\n     */\r\n    public movement: CameraMovement;\r\n\r\n    private _targetInertia = 0.9;\r\n\r\n    /**\r\n     * Defines the inertia (decay coefficient applied per reference frame at 60fps) of the camera.\r\n     * This helps giving a smooth feeling to the camera movement.\r\n     *\r\n     * Override of {@link Camera.inertia} that writes through to the {@link movement} system so the\r\n     * framerate-independent pan/rotation glide stays in sync. Setting this updates the movement\r\n     * system immediately (matching the accessor convergence used by {@link ArcRotateCamera}).\r\n     *\r\n     * Backed by a local field rather than `super.inertia`: the shipped UMD bundle is compiled with\r\n     * TypeScript at `target: ES5`, and ES5 downleveling of `super` access inside a decorated accessor\r\n     * (the base {@link Camera.inertia} carries `@serialize()`) mis-compiles to `undefined`. That would\r\n     * feed `NaN` into the movement decay and freeze the camera. It only breaks in the ES5 UMD bundle;\r\n     * native-ESM dev keeps real `super`. See the `babylonjs/no-super-in-accessor` lint rule.\r\n     */\r\n    public override get inertia(): number {\r\n        return this._targetInertia;\r\n    }\r\n\r\n    public override set inertia(value: number) {\r\n        this._targetInertia = value;\r\n        // `movement` is constructed in this class' constructor; guard for the base-constructor\r\n        // assignment that runs before it exists.\r\n        if (this.movement) {\r\n            this.movement.panInertia = value;\r\n            this.movement.rotationInertia = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * When set, the up vector of the camera will be updated by the rotation of the camera\r\n     */\r\n    @serialize()\r\n    public updateUpVectorFromRotation = false;\r\n\r\n    /**\r\n     * Define the current rotation of the camera\r\n     */\r\n    @serializeAsVector3()\r\n    public rotation: Vector3;\r\n\r\n    /**\r\n     * Define the current rotation of the camera as a quaternion to prevent Gimbal lock\r\n     */\r\n    public rotationQuaternion: Nullable<Quaternion>;\r\n\r\n    /**\r\n     * Define the current speed of the camera\r\n     */\r\n    @serialize()\r\n    public speed = 2.0;\r\n\r\n    /**\r\n     * Add constraint to the camera to prevent it to move freely in all directions and\r\n     * around all axis.\r\n     */\r\n    public noRotationConstraint = false;\r\n\r\n    /**\r\n     * Reverses mouselook direction to 'natural' panning as opposed to traditional direct\r\n     * panning\r\n     */\r\n    public invertRotation = false;\r\n\r\n    /**\r\n     * Speed multiplier for inverse camera panning\r\n     */\r\n    public inverseRotationSpeed = 0.2;\r\n\r\n    /**\r\n     * @internal\r\n     * @experimental\r\n     * Can be used to change clamping behavior for inertia. Hook into onBeforeRenderObservable to change the value per-frame\r\n     */\r\n    public _panningEpsilon = Epsilon;\r\n    /**\r\n     * @internal\r\n     * @experimental\r\n     * Can be used to change clamping behavior for inertia. Hook into onBeforeRenderObservable to change the value per-frame\r\n     */\r\n    public _rotationEpsilon = Epsilon;\r\n\r\n    /**\r\n     * Define the current target of the camera as an object or a position.\r\n     * Please note that locking a target will disable panning.\r\n     */\r\n    @serializeAsMeshReference(\"lockedTargetId\")\r\n    public lockedTarget: any = null;\r\n\r\n    protected readonly _currentTarget = Vector3.Zero();\r\n    protected _initialFocalDistance = 1;\r\n    protected readonly _viewMatrix = Matrix.Zero();\r\n\r\n    /** @internal */\r\n    public readonly _cameraTransformMatrix = Matrix.Zero();\r\n    /** @internal */\r\n    public readonly _cameraRotationMatrix = Matrix.Zero();\r\n\r\n    protected readonly _referencePoint: Vector3;\r\n    protected readonly _transformedReferencePoint = Vector3.Zero();\r\n\r\n    protected readonly _deferredPositionUpdate = new Vector3();\r\n    protected readonly _deferredRotationQuaternionUpdate = new Quaternion();\r\n    protected readonly _deferredRotationUpdate = new Vector3();\r\n    protected _deferredUpdated = false;\r\n    protected _deferOnly: boolean = false;\r\n\r\n    /** @internal */\r\n    public _reset: () => void;\r\n\r\n    /**\r\n     * Instantiates a target camera that takes a mesh or position as a target and continues to look at it while it moves.\r\n     * This is the base of the follow, arc rotate cameras and Free camera\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n     * @param name Defines the name of the camera in the scene\r\n     * @param position Defines the start position of the camera in the scene\r\n     * @param scene Defines the scene the camera belongs to\r\n     * @param setActiveOnSceneIfNoneActive Defines whether the camera should be marked as active if not other active cameras have been defined\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive = true) {\r\n        super(name, position, scene, setActiveOnSceneIfNoneActive);\r\n\r\n        this._referencePoint = Vector3.Forward(this.getScene().useRightHandedSystem);\r\n\r\n        // Set the y component of the rotation to Math.PI in right-handed system for backwards compatibility.\r\n        this.rotation = new Vector3(0, this.getScene().useRightHandedSystem ? Math.PI : 0, 0);\r\n\r\n        this.movement = new TargetCameraMovement(this.getScene(), this.position);\r\n        // Seed movement-system inertia from the value set during base/subclass construction.\r\n        // After this point, the `inertia` setter on this class pushes directly to movement.\r\n        this.movement.panInertia = this.inertia;\r\n        this.movement.rotationInertia = this.inertia;\r\n    }\r\n\r\n    /**\r\n     * Gets the position in front of the camera at a given distance.\r\n     * @param distance The distance from the camera we want the position to be\r\n     * @returns the position\r\n     */\r\n    public getFrontPosition(distance: number): Vector3 {\r\n        this.getWorldMatrix();\r\n        const worldForward = TmpVectors.Vector3[0];\r\n        const localForward = TmpVectors.Vector3[1];\r\n        localForward.set(0, 0, this._scene.useRightHandedSystem ? -1.0 : 1.0);\r\n        this.getDirectionToRef(localForward, worldForward);\r\n        worldForward.scaleInPlace(distance);\r\n        return this.globalPosition.add(worldForward);\r\n    }\r\n\r\n    /** @internal */\r\n    public _getLockedTargetPosition(): Nullable<Vector3> {\r\n        if (!this.lockedTarget) {\r\n            return null;\r\n        }\r\n\r\n        if (this.lockedTarget.absolutePosition) {\r\n            const lockedTarget = this.lockedTarget as AbstractMesh;\r\n            const m = lockedTarget.computeWorldMatrix();\r\n            // in some cases the absolute position resets externally, but doesn't update since the matrix is cached.\r\n            m.getTranslationToRef(lockedTarget.absolutePosition);\r\n        }\r\n\r\n        return this.lockedTarget.absolutePosition || this.lockedTarget;\r\n    }\r\n\r\n    private _storedPosition: Vector3;\r\n    private _storedRotation: Vector3;\r\n    private _storedRotationQuaternion: Nullable<Quaternion>;\r\n\r\n    /**\r\n     * Store current camera state of the camera (fov, position, rotation, etc..)\r\n     * @returns the camera\r\n     */\r\n    public override storeState(): Camera {\r\n        this._storedPosition = this.position.clone();\r\n        this._storedRotation = this.rotation.clone();\r\n        if (this.rotationQuaternion) {\r\n            this._storedRotationQuaternion = this.rotationQuaternion.clone();\r\n        }\r\n\r\n        return super.storeState();\r\n    }\r\n\r\n    /**\r\n     * Restored camera state. You must call storeState() first\r\n     * @returns whether it was successful or not\r\n     * @internal\r\n     */\r\n    public override _restoreStateValues(): boolean {\r\n        if (!super._restoreStateValues()) {\r\n            return false;\r\n        }\r\n\r\n        this.position = this._storedPosition.clone();\r\n        this.rotation = this._storedRotation.clone();\r\n\r\n        if (this.rotationQuaternion && this._storedRotationQuaternion) {\r\n            this.rotationQuaternion = this._storedRotationQuaternion.clone();\r\n        }\r\n\r\n        this.cameraDirection.copyFromFloats(0, 0, 0);\r\n        this.cameraRotation.copyFromFloats(0, 0);\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _initCache() {\r\n        super._initCache();\r\n        this._cache.lockedTarget = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        this._cache.rotation = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        this._cache.rotationQuaternion = new Quaternion(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateCache(ignoreParentClass?: boolean): void {\r\n        if (!ignoreParentClass) {\r\n            super._updateCache();\r\n        }\r\n\r\n        const lockedTargetPosition = this._getLockedTargetPosition();\r\n        if (!lockedTargetPosition) {\r\n            this._cache.lockedTarget = null;\r\n        } else {\r\n            if (!this._cache.lockedTarget) {\r\n                this._cache.lockedTarget = lockedTargetPosition.clone();\r\n            } else {\r\n                this._cache.lockedTarget.copyFrom(lockedTargetPosition);\r\n            }\r\n        }\r\n\r\n        this._cache.rotation.copyFrom(this.rotation);\r\n        if (this.rotationQuaternion) {\r\n            this._cache.rotationQuaternion.copyFrom(this.rotationQuaternion);\r\n        }\r\n    }\r\n\r\n    // Synchronized\r\n    /** @internal */\r\n    public override _isSynchronizedViewMatrix(): boolean {\r\n        if (!super._isSynchronizedViewMatrix()) {\r\n            return false;\r\n        }\r\n\r\n        const lockedTargetPosition = this._getLockedTargetPosition();\r\n\r\n        return (\r\n            (this._cache.lockedTarget ? this._cache.lockedTarget.equals(lockedTargetPosition) : !lockedTargetPosition) &&\r\n            (this.rotationQuaternion ? this.rotationQuaternion.equals(this._cache.rotationQuaternion) : this._cache.rotation.equals(this.rotation))\r\n        );\r\n    }\r\n\r\n    // Methods\r\n    /** @internal */\r\n    public _computeLocalCameraSpeed(): number {\r\n        const engine = this.getEngine();\r\n        return this.speed * Math.sqrt(engine.getDeltaTime() / (engine.getFps() * 100.0));\r\n    }\r\n\r\n    // Target\r\n\r\n    /**\r\n     * Defines the target the camera should look at.\r\n     * @param target Defines the new target as a Vector\r\n     */\r\n    public setTarget(target: Vector3): void {\r\n        this.upVector.normalize();\r\n\r\n        this._initialFocalDistance = target.subtract(this.position).length();\r\n\r\n        if (this.position.z === target.z) {\r\n            this.position.z += Epsilon;\r\n        }\r\n\r\n        this._referencePoint.normalize().scaleInPlace(this._initialFocalDistance);\r\n\r\n        if (this.getScene().useRightHandedSystem) {\r\n            Matrix.LookAtRHToRef(this.position, target, Vector3.UpReadOnly, TmpMatrix);\r\n        } else {\r\n            Matrix.LookAtLHToRef(this.position, target, Vector3.UpReadOnly, TmpMatrix);\r\n        }\r\n        TmpMatrix.invert();\r\n\r\n        const rotationQuaternion = this.rotationQuaternion || TmpQuaternion;\r\n        Quaternion.FromRotationMatrixToRef(TmpMatrix, rotationQuaternion);\r\n\r\n        rotationQuaternion.toEulerAnglesToRef(this.rotation);\r\n\r\n        // Explicitly set z to 0 to match previous behavior.\r\n        this.rotation.z = 0;\r\n    }\r\n\r\n    /**\r\n     * Defines the target point of the camera.\r\n     * The camera looks towards it form the radius distance.\r\n     */\r\n    public get target(): Vector3 {\r\n        return this.getTarget();\r\n    }\r\n    public set target(value: Vector3) {\r\n        this.setTarget(value);\r\n    }\r\n\r\n    /**\r\n     * Return the current target position of the camera. This value is expressed in local space.\r\n     * @returns the target position\r\n     */\r\n    public getTarget(): Vector3 {\r\n        return this._currentTarget;\r\n    }\r\n\r\n    /** @internal */\r\n    public _decideIfNeedsToMove(): boolean {\r\n        return Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public _updatePosition(): void {\r\n        if (this.parent) {\r\n            this.parent.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n            Vector3.TransformNormalToRef(this.cameraDirection, TmpVectors.Matrix[0], TmpVectors.Vector3[0]);\r\n            this._deferredPositionUpdate.addInPlace(TmpVectors.Vector3[0]);\r\n            if (!this._deferOnly) {\r\n                this.position.copyFrom(this._deferredPositionUpdate);\r\n            } else {\r\n                this._deferredUpdated = true;\r\n            }\r\n            return;\r\n        }\r\n        this._deferredPositionUpdate.addInPlace(this.cameraDirection);\r\n        if (!this._deferOnly) {\r\n            this.position.copyFrom(this._deferredPositionUpdate);\r\n        } else {\r\n            this._deferredUpdated = true;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _checkInputs(): void {\r\n        // Fold this frame's raw input — written to `cameraDirection`/`cameraRotation` by the input\r\n        // classes (and honored from direct external writes) — into the movement system, then let it\r\n        // produce framerate-independent per-frame deltas (input plus inertial glide). The applied\r\n        // delta is written back into `cameraDirection`/`cameraRotation` purely as a within-frame\r\n        // hand-off so the collision, gravity, and rotation-constraint logic below reads it unchanged.\r\n        // Both fields are reset to 0 at the end of this method (the inertial glide now lives in the\r\n        // movement system's velocity, not in these fields), so external code polling them *after*\r\n        // `_checkInputs()` reads 0 rather than the legacy residual glide value.\r\n        const movement = this.movement;\r\n        // Capture whether there is raw input on the pan channel THIS frame, before it is folded into the\r\n        // movement system. This gates the legacy panning cutoff below so it only ends a decaying inertial\r\n        // tail and never discards a small but legitimate active-input delta.\r\n        const hasPanInput = this.cameraDirection.x !== 0 || this.cameraDirection.y !== 0 || this.cameraDirection.z !== 0;\r\n        movement.panAccumulatedPixels.addInPlace(this.cameraDirection);\r\n        movement.rotationAccumulatedPixels.x += this.cameraRotation.x;\r\n        movement.rotationAccumulatedPixels.y += this.cameraRotation.y;\r\n        movement.computeCurrentFrameDeltas();\r\n        this.cameraDirection.copyFrom(movement.panDeltaCurrentFrame);\r\n        this.cameraRotation.set(movement.rotationDeltaCurrentFrame.x, movement.rotationDeltaCurrentFrame.y);\r\n\r\n        // Backward-compat glide cutoff: honor the legacy `_panningEpsilon` knob for translation.\r\n        // Legacy `_checkInputs` snapped `cameraDirection` to 0 once the glide fell below the threshold,\r\n        // ending the inertial glide at that point. The framerate-independent port moved glide into the\r\n        // movement system's velocity, so we mirror that cutoff here and reset the velocity so the glide\r\n        // terminates at the same point (and the public knob stays meaningful). This is gated on\r\n        // `!hasPanInput` so it only fires on the decaying tail: on an active-input frame the emitted\r\n        // delta is always applied, even when it is below the limit. Translation magnitude scales with\r\n        // `this.speed` (inputs use `_computeLocalCameraSpeed`), so the panning cutoff is scaled by\r\n        // `speed` too, keeping the glide *duration* independent of speed.\r\n        const inertialPanningLimit = this.speed * this._panningEpsilon;\r\n        if (\r\n            !hasPanInput &&\r\n            Math.abs(this.cameraDirection.x) < inertialPanningLimit &&\r\n            Math.abs(this.cameraDirection.y) < inertialPanningLimit &&\r\n            Math.abs(this.cameraDirection.z) < inertialPanningLimit\r\n        ) {\r\n            this.cameraDirection.setAll(0);\r\n            movement.resetPanVelocity();\r\n        }\r\n        // Rotation has no legacy per-frame-delta cutoff: the movement system already terminates the\r\n        // glide via its own framerate-independent velocity epsilon, so `cameraRotation` is naturally 0\r\n        // once the rotation velocity decays. Applying a coarse `_rotationEpsilon` snap on top truncated\r\n        // the inertia tail and reintroduced framerate dependence (the snap tests a per-frame delta, which\r\n        // shrinks at high refresh rates), producing a visible \"cut\" in the glide that was worst at high\r\n        // speeds and high frame rates (forum 61001). Deferring entirely to the velocity epsilon gives the\r\n        // same smooth ease-out at every `speed` and refresh rate.\r\n\r\n        const directionMultiplier = this.invertRotation ? -this.inverseRotationSpeed : 1.0;\r\n        const needToMove = this._decideIfNeedsToMove();\r\n        const needToRotate = !!(this.cameraRotation.x || this.cameraRotation.y);\r\n\r\n        this._deferredUpdated = false;\r\n        this._deferredRotationUpdate.copyFrom(this.rotation);\r\n        this._deferredPositionUpdate.copyFrom(this.position);\r\n        if (this.rotationQuaternion) {\r\n            this._deferredRotationQuaternionUpdate.copyFrom(this.rotationQuaternion);\r\n        }\r\n\r\n        // Move\r\n        if (needToMove) {\r\n            this._updatePosition();\r\n        }\r\n\r\n        // Rotate\r\n        if (needToRotate) {\r\n            //rotate, if quaternion is set and rotation was used\r\n            if (this.rotationQuaternion) {\r\n                this.rotationQuaternion.toEulerAnglesToRef(this._deferredRotationUpdate);\r\n            }\r\n\r\n            this._deferredRotationUpdate.x += this.cameraRotation.x * directionMultiplier;\r\n            this._deferredRotationUpdate.y += this.cameraRotation.y * directionMultiplier;\r\n\r\n            // Apply constraints\r\n            if (!this.noRotationConstraint) {\r\n                const limit = 1.570796;\r\n\r\n                if (this._deferredRotationUpdate.x > limit) {\r\n                    this._deferredRotationUpdate.x = limit;\r\n                }\r\n                if (this._deferredRotationUpdate.x < -limit) {\r\n                    this._deferredRotationUpdate.x = -limit;\r\n                }\r\n            }\r\n\r\n            if (!this._deferOnly) {\r\n                this.rotation.copyFrom(this._deferredRotationUpdate);\r\n            } else {\r\n                this._deferredUpdated = true;\r\n            }\r\n\r\n            //rotate, if quaternion is set and rotation was used\r\n            if (this.rotationQuaternion) {\r\n                const len = this._deferredRotationUpdate.lengthSquared();\r\n                if (len) {\r\n                    Quaternion.RotationYawPitchRollToRef(\r\n                        this._deferredRotationUpdate.y,\r\n                        this._deferredRotationUpdate.x,\r\n                        this._deferredRotationUpdate.z,\r\n                        this._deferredRotationQuaternionUpdate\r\n                    );\r\n                    if (!this._deferOnly) {\r\n                        this.rotationQuaternion.copyFrom(this._deferredRotationQuaternionUpdate);\r\n                    } else {\r\n                        this._deferredUpdated = true;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // The movement system now owns inertial decay (framerate-independent), so reset the\r\n        // per-frame delta surfaces. Glide persists inside the movement velocity and is re-emitted\r\n        // next frame via `computeCurrentFrameDeltas`; zeroing here prevents the just-applied delta\r\n        // from being re-folded into the accumulators on the next frame.\r\n        this.cameraDirection.setAll(0);\r\n        this.cameraRotation.set(0, 0);\r\n\r\n        super._checkInputs();\r\n    }\r\n\r\n    protected _updateCameraRotationMatrix() {\r\n        if (this.rotationQuaternion) {\r\n            this.rotationQuaternion.toRotationMatrix(this._cameraRotationMatrix);\r\n        } else {\r\n            Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._cameraRotationMatrix);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the up vector to apply the rotation of the camera (So if you changed the camera rotation.z this will let you update the up vector as well)\r\n     * @returns the current camera\r\n     */\r\n    private _rotateUpVectorWithCameraRotationMatrix(): TargetCamera {\r\n        Vector3.TransformNormalToRef(Vector3.UpReadOnly, this._cameraRotationMatrix, this.upVector);\r\n        return this;\r\n    }\r\n\r\n    private _cachedRotationZ = 0;\r\n    private _cachedQuaternionRotationZ = 0;\r\n    /** @internal */\r\n    public override _getViewMatrix(): Matrix {\r\n        if (this.lockedTarget) {\r\n            this.setTarget(this._getLockedTargetPosition()!);\r\n        }\r\n\r\n        // Compute\r\n        this._updateCameraRotationMatrix();\r\n\r\n        // Apply the changed rotation to the upVector\r\n        if (this.rotationQuaternion && this._cachedQuaternionRotationZ != this.rotationQuaternion.z) {\r\n            this._rotateUpVectorWithCameraRotationMatrix();\r\n            this._cachedQuaternionRotationZ = this.rotationQuaternion.z;\r\n        } else if (this._cachedRotationZ !== this.rotation.z) {\r\n            this._rotateUpVectorWithCameraRotationMatrix();\r\n            this._cachedRotationZ = this.rotation.z;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);\r\n\r\n        // Computing target and final matrix\r\n        this.position.addToRef(this._transformedReferencePoint, this._currentTarget);\r\n        if (this.updateUpVectorFromRotation) {\r\n            if (this.rotationQuaternion) {\r\n                Axis.Y.rotateByQuaternionToRef(this.rotationQuaternion, this.upVector);\r\n            } else {\r\n                Quaternion.FromEulerVectorToRef(this.rotation, TmpQuaternion);\r\n                Axis.Y.rotateByQuaternionToRef(TmpQuaternion, this.upVector);\r\n            }\r\n        }\r\n        this._computeViewMatrix(this.position, this._currentTarget, this.upVector);\r\n        return this._viewMatrix;\r\n    }\r\n\r\n    protected _computeViewMatrix(position: Vector3, target: Vector3, up: Vector3): void {\r\n        if (this.getScene().useRightHandedSystem) {\r\n            Matrix.LookAtRHToRef(position, target, up, this._viewMatrix);\r\n        } else {\r\n            Matrix.LookAtLHToRef(position, target, up, this._viewMatrix);\r\n        }\r\n\r\n        if (this.parent) {\r\n            const parentWorldMatrix = this.parent.getWorldMatrix();\r\n            this._viewMatrix.invert();\r\n            this._viewMatrix.multiplyToRef(parentWorldMatrix, this._viewMatrix);\r\n            this._viewMatrix.invert();\r\n\r\n            this._markSyncedWithParent();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public override createRigCamera(name: string, cameraIndex: number): Nullable<Camera> {\r\n        if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {\r\n            const rigCamera = new TargetCamera(name, this.position.clone(), this.getScene());\r\n            rigCamera.isRigCamera = true;\r\n            rigCamera.rigParent = this;\r\n            if (this.cameraRigMode === Camera.RIG_MODE_VR) {\r\n                if (!this.rotationQuaternion) {\r\n                    this.rotationQuaternion = new Quaternion();\r\n                }\r\n                rigCamera._cameraRigParams = {};\r\n                rigCamera.rotationQuaternion = new Quaternion();\r\n            }\r\n\r\n            rigCamera.mode = this.mode;\r\n            rigCamera.orthoLeft = this.orthoLeft;\r\n            rigCamera.orthoRight = this.orthoRight;\r\n            rigCamera.orthoTop = this.orthoTop;\r\n            rigCamera.orthoBottom = this.orthoBottom;\r\n\r\n            return rigCamera;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateRigCameras() {\r\n        const camLeft = <TargetCamera>this._rigCameras[0];\r\n        const camRight = <TargetCamera>this._rigCameras[1];\r\n\r\n        this.computeWorldMatrix();\r\n\r\n        switch (this.cameraRigMode) {\r\n            case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_INTERLACED: {\r\n                //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:\r\n                const leftSign = this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED ? 1 : -1;\r\n                const rightSign = this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED ? -1 : 1;\r\n                this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft);\r\n                this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * rightSign, camRight);\r\n                break;\r\n            }\r\n            case Camera.RIG_MODE_VR:\r\n                if (camLeft.rotationQuaternion && camRight.rotationQuaternion && this.rotationQuaternion) {\r\n                    camLeft.rotationQuaternion.copyFrom(this.rotationQuaternion);\r\n                    camRight.rotationQuaternion.copyFrom(this.rotationQuaternion);\r\n                } else {\r\n                    camLeft.rotation.copyFrom(this.rotation);\r\n                    camRight.rotation.copyFrom(this.rotation);\r\n                }\r\n                camLeft.position.copyFrom(this.position);\r\n                camRight.position.copyFrom(this.position);\r\n\r\n                break;\r\n        }\r\n        super._updateRigCameras();\r\n    }\r\n\r\n    private _getRigCamPositionAndTarget(halfSpace: number, rigCamera: TargetCamera) {\r\n        const target = this.getTarget();\r\n        target.subtractToRef(this.position, TargetCamera._TargetFocalPoint);\r\n\r\n        TargetCamera._TargetFocalPoint.normalize().scaleInPlace(this._initialFocalDistance);\r\n        const newFocalTarget = TargetCamera._TargetFocalPoint.addInPlace(this.position);\r\n\r\n        Matrix.TranslationToRef(-newFocalTarget.x, -newFocalTarget.y, -newFocalTarget.z, TargetCamera._TargetTransformMatrix);\r\n        TargetCamera._TargetTransformMatrix.multiplyToRef(Matrix.RotationAxis(rigCamera.upVector, halfSpace), TargetCamera._RigCamTransformMatrix);\r\n        Matrix.TranslationToRef(newFocalTarget.x, newFocalTarget.y, newFocalTarget.z, TargetCamera._TargetTransformMatrix);\r\n\r\n        TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);\r\n\r\n        Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, rigCamera.position);\r\n        rigCamera.setTarget(newFocalTarget);\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"TargetCamera\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for targetCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTargetCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"TargetCamera\", (name, scene) => {\r\n        return () => new TargetCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { serializeAsVector3, serialize } from \"../Misc/decorators\";\r\nimport { Vector3, Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { TargetCamera } from \"./targetCamera.pure\";\r\nimport { type TargetCameraMovement } from \"./targetCameraMovement\";\r\nimport { FreeCameraInputsManager } from \"./freeCameraInputsManager.pure\";\r\nimport { type FreeCameraMouseInput } from \"../Cameras/Inputs/freeCameraMouseInput\";\r\nimport { type FreeCameraKeyboardMoveInput } from \"../Cameras/Inputs/freeCameraKeyboardMoveInput\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\n\r\nimport { type Collider } from \"../Collisions/collider\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This represents a free type of camera. It can be useful in First Person Shooter game for instance.\r\n * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n */\r\nexport class FreeCamera extends TargetCamera {\r\n    /**\r\n     * Define the collision ellipsoid of the camera.\r\n     * This is helpful to simulate a camera body like the player body around the camera\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions#arcrotatecamera\r\n     */\r\n    @serializeAsVector3()\r\n    public ellipsoid = new Vector3(0.5, 1, 0.5);\r\n\r\n    /**\r\n     * Define an offset for the position of the ellipsoid around the camera.\r\n     * This can be helpful to determine the center of the body near the gravity center of the body\r\n     * instead of its head.\r\n     */\r\n    @serializeAsVector3()\r\n    public ellipsoidOffset = new Vector3(0, 0, 0);\r\n\r\n    /**\r\n     * Enable or disable collisions of the camera with the rest of the scene objects.\r\n     */\r\n    @serialize()\r\n    public checkCollisions = false;\r\n\r\n    /**\r\n     * Enable or disable gravity on the camera.\r\n     */\r\n    @serialize()\r\n    public applyGravity = false;\r\n\r\n    /**\r\n     * Define the input manager associated to the camera.\r\n     */\r\n    public override inputs: FreeCameraInputsManager;\r\n\r\n    /**\r\n     * Framerate-independent movement controller for the free camera, exposing the configurable\r\n     * {@link InputMapper} (`movement.input`) consulted by the free-camera input classes. Narrows\r\n     * the inherited {@link TargetCamera.movement} to {@link TargetCameraMovement}; the instance is\r\n     * created by the {@link TargetCamera} constructor.\r\n     */\r\n    // `declare`, not `override`: the value is created by the base TargetCamera constructor. Under TC39\r\n    // decorators a plain field redeclaration is materialized as a constructor field-init that runs after\r\n    // super() and would clobber that value back to undefined; `declare` keeps this a type-only narrowing.\r\n    declare public movement: TargetCameraMovement;\r\n\r\n    /**\r\n     * Gets the input sensibility for a mouse input. (default is 2000.0)\r\n     * Higher values reduce sensitivity.\r\n     */\r\n    public get angularSensibility(): number {\r\n        const mouse = <FreeCameraMouseInput>this.inputs.attached[\"mouse\"];\r\n        if (mouse) {\r\n            return mouse.angularSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the input sensibility for a mouse input. (default is 2000.0)\r\n     * Higher values reduce sensitivity.\r\n     */\r\n    public set angularSensibility(value: number) {\r\n        const mouse = <FreeCameraMouseInput>this.inputs.attached[\"mouse\"];\r\n        if (mouse) {\r\n            mouse.angularSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the forward move of the camera.\r\n     */\r\n    public get keysUp(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysUp;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysUp(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysUp = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the upward move of the camera.\r\n     */\r\n    public get keysUpward(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysUpward;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysUpward(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysUpward = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the backward move of the camera.\r\n     */\r\n    public get keysDown(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysDown;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysDown(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysDown = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the downward move of the camera.\r\n     */\r\n    public get keysDownward(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysDownward;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysDownward(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysDownward = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.\r\n     */\r\n    public get keysLeft(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysLeft;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysLeft(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysLeft = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.\r\n     */\r\n    public get keysRight(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRight;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysRight(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRight = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the left rotation move of the camera.\r\n     */\r\n    public get keysRotateLeft(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRotateLeft;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysRotateLeft(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRotateLeft = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the right rotation move of the camera.\r\n     */\r\n    public get keysRotateRight(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRotateRight;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysRotateRight(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRotateRight = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the up rotation move of the camera.\r\n     */\r\n    public get keysRotateUp(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRotateUp;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysRotateUp(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRotateUp = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control the down rotation move of the camera.\r\n     */\r\n    public get keysRotateDown(): number[] {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRotateDown;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysRotateDown(value: number[]) {\r\n        const keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRotateDown = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Event raised when the camera collide with a mesh in the scene.\r\n     */\r\n    public onCollide: (collidedMesh: AbstractMesh) => void;\r\n\r\n    private _collider: Collider;\r\n    private _needMoveForGravity = false;\r\n    private _oldPosition = Vector3.Zero();\r\n    private _diffPosition = Vector3.Zero();\r\n    private _newPosition = Vector3.Zero();\r\n\r\n    /** @internal */\r\n    public _localDirection: Vector3;\r\n    /** @internal */\r\n    public _transformedDirection: Vector3;\r\n\r\n    /**\r\n     * Instantiates a Free Camera.\r\n     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.\r\n     * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n     * @param name Define the name of the camera in the scene\r\n     * @param position Define the start position of the camera in the scene\r\n     * @param scene Define the scene the camera belongs to\r\n     * @param setActiveOnSceneIfNoneActive Defines whether the camera should be marked as active if not other active cameras have been defined\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive = true) {\r\n        super(name, position, scene, setActiveOnSceneIfNoneActive);\r\n        this.inputs = new FreeCameraInputsManager(this);\r\n        this.inputs.addKeyboard().addMouse();\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(noPreventDefault?: boolean): void;\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     * BACK COMPAT SIGNATURE ONLY.\r\n     */\r\n    public override attachControl(ignored: any, noPreventDefault?: boolean): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(ignored?: any, noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        this.inputs.attachElement(noPreventDefault);\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public override detachControl(): void {\r\n        this.inputs.detachElement();\r\n\r\n        this.cameraDirection = new Vector3(0, 0, 0);\r\n        this.cameraRotation = new Vector2(0, 0);\r\n    }\r\n\r\n    // Collisions\r\n    private _collisionMask = -1;\r\n\r\n    /**\r\n     * Define a collision mask to limit the list of object the camera can collide with\r\n     */\r\n    public get collisionMask(): number {\r\n        return this._collisionMask;\r\n    }\r\n\r\n    public set collisionMask(mask: number) {\r\n        this._collisionMask = !isNaN(mask) ? mask : -1;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _collideWithWorld(displacement: Vector3): void {\r\n        let globalPosition: Vector3;\r\n\r\n        if (this.parent) {\r\n            globalPosition = Vector3.TransformCoordinates(this.position, this.parent.getWorldMatrix());\r\n        } else {\r\n            globalPosition = this.position;\r\n        }\r\n\r\n        globalPosition.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPosition);\r\n        this._oldPosition.addInPlace(this.ellipsoidOffset);\r\n\r\n        const coordinator = this.getScene().collisionCoordinator;\r\n        if (!this._collider) {\r\n            this._collider = coordinator.createCollider();\r\n        }\r\n\r\n        this._collider._radius = this.ellipsoid;\r\n        this._collider.collisionMask = this._collisionMask;\r\n\r\n        //no need for clone, as long as gravity is not on.\r\n        let actualDisplacement = displacement;\r\n\r\n        //add gravity to the direction to prevent the dual-collision checking\r\n        if (this.applyGravity) {\r\n            //this prevents mending with cameraDirection, a global variable of the free camera class.\r\n            actualDisplacement = displacement.add(this.getScene().gravity);\r\n        }\r\n\r\n        coordinator.getNewPosition(this._oldPosition, actualDisplacement, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId);\r\n    }\r\n\r\n    private _onCollisionPositionChange = (collisionId: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh> = null) => {\r\n        this._newPosition.copyFrom(newPosition);\r\n\r\n        this._newPosition.subtractToRef(this._oldPosition, this._diffPosition);\r\n\r\n        if (this._diffPosition.length() > AbstractEngine.CollisionsEpsilon) {\r\n            this.position.addToRef(this._diffPosition, this._deferredPositionUpdate);\r\n            if (!this._deferOnly) {\r\n                this.position.copyFrom(this._deferredPositionUpdate);\r\n            } else {\r\n                this._deferredUpdated = true;\r\n            }\r\n            // call onCollide, if defined. Note that in case of deferred update, the actual position change might happen in the next frame.\r\n            if (this.onCollide && collidedMesh) {\r\n                this.onCollide(collidedMesh);\r\n            }\r\n        }\r\n    };\r\n\r\n    /** @internal */\r\n    public override _checkInputs(): void {\r\n        if (!this._localDirection) {\r\n            this._localDirection = Vector3.Zero();\r\n            this._transformedDirection = Vector3.Zero();\r\n        }\r\n\r\n        this.inputs.checkInputs();\r\n\r\n        super._checkInputs();\r\n    }\r\n\r\n    /**\r\n     * Enable movement without a user input. This allows gravity to always be applied.\r\n     */\r\n    public set needMoveForGravity(value: boolean) {\r\n        this._needMoveForGravity = value;\r\n    }\r\n\r\n    /**\r\n     * When true, gravity is applied whether there is user input or not.\r\n     */\r\n    public get needMoveForGravity(): boolean {\r\n        return this._needMoveForGravity;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _decideIfNeedsToMove(): boolean {\r\n        return this._needMoveForGravity || Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _updatePosition(): void {\r\n        if (this.checkCollisions && this.getScene().collisionsEnabled) {\r\n            this._collideWithWorld(this.cameraDirection);\r\n        } else {\r\n            super._updatePosition();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Destroy the camera and release the current resources hold by it.\r\n     */\r\n    public override dispose(): void {\r\n        this.inputs.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FreeCamera\";\r\n    }\r\n}\r\n\r\n// Register Class Name\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for freeCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFreeCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FreeCamera\", FreeCamera);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FreeCamera } from \"./freeCamera.pure\";\r\nimport { type FreeCameraTouchInput } from \"../Cameras/Inputs/freeCameraTouchInput\";\r\nimport { type FreeCameraMouseInput } from \"../Cameras/Inputs/freeCameraMouseInput\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Node } from \"../node\";\r\n\r\n/**\r\n * This represents a FPS type of camera controlled by touch.\r\n * This is like a universal camera minus the Gamepad controls.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n */\r\nexport class TouchCamera extends FreeCamera {\r\n    /**\r\n     * Defines the touch sensibility for rotation.\r\n     * The higher the faster.\r\n     */\r\n    public get touchAngularSensibility(): number {\r\n        const touch = <FreeCameraTouchInput>this.inputs.attached[\"touch\"];\r\n        if (touch) {\r\n            return touch.touchAngularSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set touchAngularSensibility(value: number) {\r\n        const touch = <FreeCameraTouchInput>this.inputs.attached[\"touch\"];\r\n        if (touch) {\r\n            touch.touchAngularSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the touch sensibility for move.\r\n     * The higher the faster.\r\n     */\r\n    public get touchMoveSensibility(): number {\r\n        const touch = <FreeCameraTouchInput>this.inputs.attached[\"touch\"];\r\n        if (touch) {\r\n            return touch.touchMoveSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set touchMoveSensibility(value: number) {\r\n        const touch = <FreeCameraTouchInput>this.inputs.attached[\"touch\"];\r\n        if (touch) {\r\n            touch.touchMoveSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new touch camera.\r\n     * This represents a FPS type of camera controlled by touch.\r\n     * This is like a universal camera minus the Gamepad controls.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n     * @param name Define the name of the camera in the scene\r\n     * @param position Define the start position of the camera in the scene\r\n     * @param scene Define the scene the camera belongs to\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.inputs.addTouch();\r\n\r\n        this._setupInputs();\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"TouchCamera\";\r\n    }\r\n\r\n    /** @internal */\r\n    public override _setupInputs() {\r\n        const touch = this.inputs.attached[\"touch\"] as FreeCameraTouchInput | undefined;\r\n        const mouse = this.inputs.attached[\"mouse\"] as FreeCameraMouseInput | undefined;\r\n        if (mouse) {\r\n            // enable touch in mouse input if touch module is not enabled\r\n            mouse.touchEnabled = !touch;\r\n        } else if (touch) {\r\n            // allow mouse in touch input if mouse module is not available\r\n            touch.allowMouse = !mouse;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for touchCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTouchCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"TouchCamera\", (name, scene) => {\r\n        return () => new TouchCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { CameraMovement } from \"./cameraMovement\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport { type ArcRotateCamera } from \"./arcRotateCamera.pure\";\r\nimport { type InputMapEntry, InputMapper } from \"./inputMapper\";\r\n\r\n// ── ArcRotate handler types ────────────────────────────────────────\r\n\r\n/**\r\n * Handler shape for arc-rotate camera interactions.\r\n * Property names are the canonical interaction type strings used in inputMap entries.\r\n * All handlers are plain functions since none need multi-method lifecycle.\r\n */\r\nexport type ArcRotateHandlers = {\r\n    /** Pan by pre-scaled pixel deltas */\r\n    pan: (deltaX: number, deltaY: number) => void;\r\n    /** Orbit by pre-scaled pixel deltas */\r\n    rotate: (deltaX: number, deltaY: number) => void;\r\n    /** Zoom by a pre-computed delta (already scaled by input) */\r\n    zoom: (delta: number) => void;\r\n};\r\n\r\n/** Interaction type string for arc-rotate camera, derived from handler property names */\r\nexport type ArcRotateInteraction = keyof ArcRotateHandlers;\r\n\r\n/**\r\n * Arc-rotate camera movement system that provides framerate-independent physics\r\n * and input mapping for pan, rotate, and zoom interactions.\r\n *\r\n * Default accumulator-based flow: input classes feed pixel deltas into the accumulators\r\n * (panAccumulatedPixels, rotationAccumulatedPixels, zoomAccumulatedPixels).\r\n * The base class's computeCurrentFrameDeltas() converts these to framerate-independent\r\n * deltas with proper inertia, which the camera reads each frame.\r\n */\r\nexport class ArcRotateCameraMovement extends CameraMovement {\r\n    /** Input system that maps physical inputs to interactions and dispatches to handlers. */\r\n    public readonly input: InputMapper<ArcRotateHandlers>;\r\n\r\n    constructor(scene: Scene, cameraPosition: Vector3, behavior?: InterpolatingBehavior<ArcRotateCamera>) {\r\n        super(scene, cameraPosition, behavior);\r\n\r\n        this.input = new InputMapper<ArcRotateHandlers>(\r\n            {\r\n                pan: (deltaX, deltaY) => {\r\n                    this.panAccumulatedPixels.x += deltaX;\r\n                    this.panAccumulatedPixels.y += deltaY;\r\n                },\r\n                rotate: (deltaX, deltaY) => {\r\n                    this.rotationAccumulatedPixels.x += deltaX;\r\n                    this.rotationAccumulatedPixels.y += deltaY;\r\n                },\r\n                zoom: (delta) => {\r\n                    this.zoomAccumulatedPixels += delta;\r\n                },\r\n            },\r\n            () => this._createDefaultInputMap()\r\n        );\r\n    }\r\n\r\n    private _createDefaultInputMap(): InputMapEntry<ArcRotateInteraction>[] {\r\n        // Default entries leave `sensitivity` unset so each input class falls back to its legacy\r\n        // sensibility properties (`angularSensibilityX/Y`, `panningSensibility`, `wheelPrecision`,\r\n        // `angularSpeed`, `zoomingSensibility`) for backward compatibility. Setting `sensitivity`\r\n        // on an entry overrides those properties — the long-term path for phasing them out.\r\n        return [\r\n            // ctrl+left-drag → pan (more specific than the bare rotate entry below; must come first so first-match-wins picks it).\r\n            { source: \"pointer\", button: 0, modifiers: { ctrl: true }, interaction: \"pan\" },\r\n            { source: \"pointer\", button: 0, interaction: \"rotate\" },\r\n            { source: \"pointer\", button: 2, interaction: \"pan\" },\r\n            { source: \"wheel\", interaction: \"zoom\" },\r\n            { source: \"keyboard\", key: [187, 107, 189, 109], interaction: \"zoom\" }, // +/-/numpad+/numpad-\r\n            { source: \"keyboard\", modifiers: { ctrl: true }, interaction: \"pan\" },\r\n            { source: \"keyboard\", modifiers: { alt: true }, interaction: \"zoom\" },\r\n            { source: \"keyboard\", interaction: \"rotate\" },\r\n        ];\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsVector3, serializeAsMeshReference, serializeAsVector2 } from \"../Misc/decorators\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Matrix, Vector3, Vector2, TmpVectors, Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { Node } from \"../node\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { AutoRotationBehavior } from \"../Behaviors/Cameras/autoRotationBehavior\";\r\nimport { BouncingBehavior } from \"../Behaviors/Cameras/bouncingBehavior\";\r\nimport { FramingBehavior } from \"../Behaviors/Cameras/framingBehavior\";\r\nimport { Camera } from \"./camera.pure\";\r\nimport { TargetCamera } from \"./targetCamera.pure\";\r\nimport { type ArcRotateCameraPointersInput } from \"../Cameras/Inputs/arcRotateCameraPointersInput\";\r\nimport { type ArcRotateCameraKeyboardMoveInput } from \"../Cameras/Inputs/arcRotateCameraKeyboardMoveInput\";\r\nimport { type ArcRotateCameraMouseWheelInput } from \"../Cameras/Inputs/arcRotateCameraMouseWheelInput\";\r\nimport { ArcRotateCameraInputsManager } from \"../Cameras/arcRotateCameraInputsManager.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport { ArcRotateCameraMovement } from \"./arcRotateCameraMovement\";\r\n\r\nimport { type Collider } from \"../Collisions/collider\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode.pure\";\r\n\r\n/**\r\n * Computes the alpha angle based on the source position and the target position.\r\n * @param offset The directional offset between the source position and the target position\r\n * @returns The alpha angle in radians\r\n */\r\nexport function ComputeAlpha(offset: Vector3): number {\r\n    // Default alpha to π/2 to handle the edge case where x and z are both zero (when looking along up axis)\r\n    let alpha = Math.PI / 2;\r\n    if (!(offset.x === 0 && offset.z === 0)) {\r\n        alpha = Math.acos(offset.x / Math.sqrt(Math.pow(offset.x, 2) + Math.pow(offset.z, 2)));\r\n    }\r\n\r\n    if (offset.z < 0) {\r\n        alpha = 2 * Math.PI - alpha;\r\n    }\r\n\r\n    return alpha;\r\n}\r\n\r\n/**\r\n * Computes the beta angle based on the source position and the target position.\r\n * @param verticalOffset The y value of the directional offset between the source position and the target position\r\n * @param radius The distance between the source position and the target position\r\n * @returns The beta angle in radians\r\n */\r\nexport function ComputeBeta(verticalOffset: number, radius: number): number {\r\n    return Math.acos(verticalOffset / radius);\r\n}\r\n\r\n// Returns the value if not NaN, otherwise returns the fallback value.\r\nfunction CheckNaN(value: number, fallback: number): number {\r\n    return isNaN(value) ? fallback : value;\r\n}\r\n\r\n/**\r\n * This represents an orbital type of camera.\r\n *\r\n * This camera always points towards a given target position and can be rotated around that target with the target as the centre of rotation. It can be controlled with cursors and mouse, or with touch events.\r\n * Think of this camera as one orbiting its target position, or more imaginatively as a spy satellite orbiting the earth. Its position relative to the target (earth) can be set by three parameters, alpha (radians) the longitudinal rotation, beta (radians) the latitudinal rotation and radius the distance from the target position.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#arc-rotate-camera\r\n */\r\nexport class ArcRotateCamera extends TargetCamera {\r\n    /**\r\n     * Defines the rotation angle of the camera along the longitudinal axis.\r\n     */\r\n    @serialize()\r\n    public alpha: number;\r\n\r\n    /**\r\n     * Defines the rotation angle of the camera along the latitudinal axis.\r\n     */\r\n    @serialize()\r\n    public beta: number;\r\n\r\n    /**\r\n     * Defines the radius of the camera from its target point.\r\n     */\r\n    @serialize()\r\n    public radius: number;\r\n\r\n    /**\r\n     * Defines an override value to use as the parameter to setTarget.\r\n     * This allows the parameter to be specified when animating the target (e.g. using FramingBehavior).\r\n     */\r\n    @serialize()\r\n    public overrideCloneAlphaBetaRadius: Nullable<boolean>;\r\n\r\n    @serializeAsVector3(\"target\")\r\n    protected _target: Vector3;\r\n    @serializeAsMeshReference(\"targetHost\")\r\n    protected _targetHost: Nullable<TransformNode>;\r\n\r\n    /**\r\n     * Defines the target point of the camera.\r\n     * The camera looks towards it from the radius distance.\r\n     */\r\n    public override get target(): Vector3 {\r\n        return this._target;\r\n    }\r\n    public override set target(value: Vector3) {\r\n        this.setTarget(value);\r\n    }\r\n\r\n    /**\r\n     * Defines the target transform node of the camera.\r\n     * The camera looks towards it from the radius distance.\r\n     * Please note that setting a target host will disable panning.\r\n     */\r\n    public get targetHost(): Nullable<TransformNode> {\r\n        return this._targetHost;\r\n    }\r\n    public set targetHost(value: Nullable<TransformNode>) {\r\n        if (value) {\r\n            this.setTarget(value);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Return the current target position of the camera. This value is expressed in local space.\r\n     * @returns the target position\r\n     */\r\n    public override getTarget(): Vector3 {\r\n        return this.target;\r\n    }\r\n\r\n    /**\r\n     * Define the current local position of the camera in the scene\r\n     */\r\n    public override get position(): Vector3 {\r\n        return this._position;\r\n    }\r\n\r\n    public override set position(newPosition: Vector3) {\r\n        this.setPosition(newPosition);\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected _upToYMatrix: Matrix;\r\n    protected _yToUpMatrix: Matrix;\r\n\r\n    /**\r\n     * The vector the camera should consider as up. (default is Vector3(0, 1, 0) as returned by Vector3.Up())\r\n     * Setting this will copy the given vector to the camera's upVector, and set rotation matrices to and from Y up.\r\n     * DO NOT set the up vector using copyFrom or copyFromFloats, as this bypasses setting the above matrices.\r\n     */\r\n    override set upVector(vec: Vector3) {\r\n        if (!this._upToYMatrix) {\r\n            this._yToUpMatrix = new Matrix();\r\n            this._upToYMatrix = new Matrix();\r\n\r\n            this._upVector = Vector3.Zero();\r\n        }\r\n\r\n        vec.normalize();\r\n        this._upVector.copyFrom(vec);\r\n        this.setMatUp();\r\n    }\r\n\r\n    override get upVector() {\r\n        return this._upVector;\r\n    }\r\n\r\n    /**\r\n     * Sets the Y-up to camera up-vector rotation matrix, and the up-vector to Y-up rotation matrix.\r\n     */\r\n    public setMatUp() {\r\n        // from y-up to custom-up (used in _getViewMatrix)\r\n        Matrix.RotationAlignToRef(Vector3.UpReadOnly, this._upVector, this._yToUpMatrix);\r\n\r\n        // from custom-up to y-up (used in rebuildAnglesAndRadius)\r\n        Matrix.RotationAlignToRef(this._upVector, Vector3.UpReadOnly, this._upToYMatrix);\r\n    }\r\n\r\n    /**\r\n     * Current inertia value on the longitudinal axis.\r\n     * When nonzero, represents the per-frame angular offset (in radians) applied to `alpha`.\r\n     * Each frame, this value is multiplied by {@link inertia} (a decay coefficient where\r\n     * 0 = instant stop, 0.9 = smooth glide, 1 = never stops).\r\n     * Reading this value also reflects the rotation delta the movement system will apply this frame\r\n     * (decays toward 0 over the inertia tail), preserving legacy semantics for \"is the camera still animating?\" checks.\r\n     * Setting this to 0 also stops the movement system's rotation velocity for backward compatibility.\r\n     */\r\n    @serialize()\r\n    public get inertialAlphaOffset(): number {\r\n        if (this._inertialAlphaOffset !== 0) {\r\n            return this._inertialAlphaOffset;\r\n        }\r\n        if (this.movement.rotationAccumulatedPixels.x !== 0) {\r\n            return this.movement.rotationAccumulatedPixels.x;\r\n        }\r\n        const delta = this.movement.rotationDeltaCurrentFrame.x;\r\n        return Math.abs(delta) < this._rotationEpsilon ? 0 : delta;\r\n    }\r\n\r\n    public set inertialAlphaOffset(value: number) {\r\n        this._inertialAlphaOffset = value;\r\n        if (value === 0) {\r\n            this.movement.resetRotationVelocity();\r\n        }\r\n    }\r\n\r\n    private _inertialAlphaOffset: number = 0;\r\n\r\n    /**\r\n     * Current inertia value on the latitudinal axis.\r\n     * When nonzero, represents the per-frame angular offset (in radians) applied to `beta`.\r\n     * Each frame, this value is multiplied by {@link inertia} (a decay coefficient where\r\n     * 0 = instant stop, 0.9 = smooth glide, 1 = never stops).\r\n     * Reading this value also reflects the rotation delta the movement system will apply this frame\r\n     * (decays toward 0 over the inertia tail), preserving legacy semantics for \"is the camera still animating?\" checks.\r\n     * Setting this to 0 also stops the movement system's rotation velocity for backward compatibility.\r\n     */\r\n    @serialize()\r\n    public get inertialBetaOffset(): number {\r\n        if (this._inertialBetaOffset !== 0) {\r\n            return this._inertialBetaOffset;\r\n        }\r\n        if (this.movement.rotationAccumulatedPixels.y !== 0) {\r\n            return this.movement.rotationAccumulatedPixels.y;\r\n        }\r\n        const delta = this.movement.rotationDeltaCurrentFrame.y;\r\n        return Math.abs(delta) < this._rotationEpsilon ? 0 : delta;\r\n    }\r\n\r\n    public set inertialBetaOffset(value: number) {\r\n        this._inertialBetaOffset = value;\r\n        if (value === 0) {\r\n            this.movement.resetRotationVelocity();\r\n        }\r\n    }\r\n\r\n    private _inertialBetaOffset: number = 0;\r\n\r\n    /**\r\n     * Current inertia value on the radius axis.\r\n     * When nonzero, represents the per-frame offset (in scene units) applied to `radius`.\r\n     * Each frame, this value is multiplied by {@link inertia} (a decay coefficient where\r\n     * 0 = instant stop, 0.9 = smooth glide, 1 = never stops).\r\n     * Reading this value also reflects the zoom delta the movement system will apply this frame\r\n     * (decays toward 0 over the inertia tail), preserving legacy semantics for \"is the camera still animating?\" checks.\r\n     * Setting this to 0 also stops the movement system's zoom velocity for backward compatibility.\r\n     */\r\n    @serialize()\r\n    public get inertialRadiusOffset(): number {\r\n        if (this._inertialRadiusOffset !== 0) {\r\n            return this._inertialRadiusOffset;\r\n        }\r\n        if (this.movement.zoomAccumulatedPixels !== 0) {\r\n            return this.movement.zoomAccumulatedPixels;\r\n        }\r\n        const delta = this.movement.zoomDeltaCurrentFrame;\r\n        return Math.abs(delta) < this._rotationEpsilon ? 0 : delta;\r\n    }\r\n\r\n    public set inertialRadiusOffset(value: number) {\r\n        this._inertialRadiusOffset = value;\r\n        if (value === 0) {\r\n            this.movement.resetZoomVelocity();\r\n        }\r\n    }\r\n\r\n    private _inertialRadiusOffset: number = 0;\r\n\r\n    /**\r\n     * Minimum allowed angle on the longitudinal axis.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public lowerAlphaLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Maximum allowed angle on the longitudinal axis.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public upperAlphaLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Minimum allowed angle on the latitudinal axis.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public lowerBetaLimit: Nullable<number> = 0.01;\r\n\r\n    /**\r\n     * Maximum allowed angle on the latitudinal axis.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public upperBetaLimit: Nullable<number> = Math.PI - 0.01;\r\n\r\n    /**\r\n     * Minimum allowed distance of the camera to the target (The camera can not get closer).\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public lowerRadiusLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Maximum allowed distance of the camera to the target (The camera can not get further).\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public upperRadiusLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Minimum allowed vertical target position of the camera.\r\n     * Use this setting in combination with `upperRadiusLimit` to set a global limit for the Cameras vertical position.\r\n     */\r\n    @serialize()\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public lowerTargetYLimit: number = -Infinity;\r\n\r\n    /**\r\n     * Defines the current inertia value used during panning of the camera along the X axis.\r\n     */\r\n    @serialize()\r\n    public inertialPanningX: number = 0;\r\n\r\n    /**\r\n     * Defines the current inertia value used during panning of the camera along the Y axis.\r\n     */\r\n    @serialize()\r\n    public inertialPanningY: number = 0;\r\n\r\n    /**\r\n     * Defines the distance used to consider the camera in pan mode vs pinch/zoom.\r\n     * Basically if your fingers moves away from more than this distance you will be considered\r\n     * in pinch mode.\r\n     */\r\n    @serialize()\r\n    public pinchToPanMaxDistance: number = 20;\r\n\r\n    /**\r\n     * Defines the maximum distance the camera can pan.\r\n     * This could help keeping the camera always in your scene.\r\n     */\r\n    @serialize()\r\n    public panningDistanceLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Defines the target of the camera before panning.\r\n     */\r\n    @serializeAsVector3()\r\n    public panningOriginTarget: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Defines the value of the inertia used during panning.\r\n     * A decay coefficient applied per reference frame at 60fps:\r\n     * 0 means stop instantly, 0.9 means smooth glide, 1 means never stop.\r\n     * Setting this also updates the movement system's pan inertia.\r\n     */\r\n    @serialize()\r\n    public get panningInertia(): number {\r\n        return this._panningInertia;\r\n    }\r\n\r\n    public set panningInertia(value: number) {\r\n        this._panningInertia = value;\r\n        if (this.movement) {\r\n            this.movement.panInertia = value;\r\n        }\r\n    }\r\n\r\n    private _panningInertia = 0.9;\r\n\r\n    private _inertia = 0.9;\r\n\r\n    /**\r\n     * Defines the rotation/zoom inertia (decay coefficient applied per reference frame at 60fps).\r\n     * Override of {@link Camera.inertia} that automatically syncs to the movement system\r\n     * (rotation and zoom). Panning inertia is controlled separately via {@link panningInertia}.\r\n     */\r\n    public override get inertia(): number {\r\n        return this._inertia;\r\n    }\r\n\r\n    public override set inertia(value: number) {\r\n        this._inertia = value;\r\n        if (this.movement) {\r\n            this.movement.rotationInertia = value;\r\n            this.movement.zoomInertia = value;\r\n        }\r\n    }\r\n\r\n    //-- begin properties for backward compatibility for inputs\r\n\r\n    /**\r\n     * Gets or Set the pointer angular sensibility  along the X axis or how fast is the camera rotating.\r\n     */\r\n    public get angularSensibilityX(): number {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            return pointers.angularSensibilityX;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set angularSensibilityX(value: number) {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            pointers.angularSensibilityX = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the pointer angular sensibility along the Y axis or how fast is the camera rotating.\r\n     */\r\n    public get angularSensibilityY(): number {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            return pointers.angularSensibilityY;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set angularSensibilityY(value: number) {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            pointers.angularSensibilityY = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the pointer pinch precision or how fast is the camera zooming.\r\n     */\r\n    public get pinchPrecision(): number {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            return pointers.pinchPrecision;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set pinchPrecision(value: number) {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            pointers.pinchPrecision = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the pointer pinch delta percentage or how fast is the camera zooming.\r\n     * It will be used instead of pinchPrecision if different from 0.\r\n     * It defines the percentage of current camera.radius to use as delta when pinch zoom is used.\r\n     */\r\n    public get pinchDeltaPercentage(): number {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            return pointers.pinchDeltaPercentage;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set pinchDeltaPercentage(value: number) {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            pointers.pinchDeltaPercentage = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the pointer use natural pinch zoom to override the pinch precision\r\n     * and pinch delta percentage.\r\n     * When useNaturalPinchZoom is true, multi touch zoom will zoom in such\r\n     * that any object in the plane at the camera's target point will scale\r\n     * perfectly with finger motion.\r\n     */\r\n    public get useNaturalPinchZoom(): boolean {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            return pointers.useNaturalPinchZoom;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public set useNaturalPinchZoom(value: boolean) {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            pointers.useNaturalPinchZoom = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the pointer panning sensibility or how fast is the camera moving.\r\n     */\r\n    public get panningSensibility(): number {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            return pointers.panningSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set panningSensibility(value: number) {\r\n        const pointers = <ArcRotateCameraPointersInput>this.inputs.attached[\"pointers\"];\r\n        if (pointers) {\r\n            pointers.panningSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control beta angle in a positive direction.\r\n     */\r\n    public get keysUp(): number[] {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysUp;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysUp(value: number[]) {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysUp = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control beta angle in a negative direction.\r\n     */\r\n    public get keysDown(): number[] {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysDown;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysDown(value: number[]) {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysDown = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control alpha angle in a negative direction.\r\n     */\r\n    public get keysLeft(): number[] {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysLeft;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysLeft(value: number[]) {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysLeft = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the list of keyboard keys used to control alpha angle in a positive direction.\r\n     */\r\n    public get keysRight(): number[] {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRight;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysRight(value: number[]) {\r\n        const keyboard = <ArcRotateCameraKeyboardMoveInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRight = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the mouse wheel precision or how fast is the camera zooming.\r\n     */\r\n    public get wheelPrecision(): number {\r\n        const mousewheel = <ArcRotateCameraMouseWheelInput>this.inputs.attached[\"mousewheel\"];\r\n        if (mousewheel) {\r\n            return mousewheel.wheelPrecision;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set wheelPrecision(value: number) {\r\n        const mousewheel = <ArcRotateCameraMouseWheelInput>this.inputs.attached[\"mousewheel\"];\r\n        if (mousewheel) {\r\n            mousewheel.wheelPrecision = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the boolean value that controls whether or not the mouse wheel\r\n     * zooms to the location of the mouse pointer or not.  The default is false.\r\n     */\r\n    @serialize()\r\n    public get zoomToMouseLocation(): boolean {\r\n        const mousewheel = <ArcRotateCameraMouseWheelInput>this.inputs.attached[\"mousewheel\"];\r\n        if (mousewheel) {\r\n            return mousewheel.zoomToMouseLocation;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public set zoomToMouseLocation(value: boolean) {\r\n        const mousewheel = <ArcRotateCameraMouseWheelInput>this.inputs.attached[\"mousewheel\"];\r\n        if (mousewheel) {\r\n            mousewheel.zoomToMouseLocation = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or Set the mouse wheel delta percentage or how fast is the camera zooming.\r\n     * It will be used instead of wheelPrecision if different from 0.\r\n     * It defines the percentage of current camera.radius to use as delta when wheel zoom is used.\r\n     */\r\n    public get wheelDeltaPercentage(): number {\r\n        const mousewheel = <ArcRotateCameraMouseWheelInput>this.inputs.attached[\"mousewheel\"];\r\n        if (mousewheel) {\r\n            return mousewheel.wheelDeltaPercentage;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set wheelDeltaPercentage(value: number) {\r\n        const mousewheel = <ArcRotateCameraMouseWheelInput>this.inputs.attached[\"mousewheel\"];\r\n        if (mousewheel) {\r\n            mousewheel.wheelDeltaPercentage = value;\r\n        }\r\n    }\r\n\r\n    //-- end properties for backward compatibility for inputs\r\n\r\n    /**\r\n     * Defines how much the radius should be scaled while zooming on a particular mesh (through the zoomOn function)\r\n     */\r\n    @serialize()\r\n    public zoomOnFactor = 1;\r\n\r\n    /**\r\n     * Defines a screen offset for the camera position.\r\n     */\r\n    @serializeAsVector2()\r\n    public targetScreenOffset = Vector2.Zero();\r\n\r\n    /**\r\n     * Allows the camera to be completely reversed.\r\n     * If false the camera can not arrive upside down.\r\n     */\r\n    @serialize()\r\n    public allowUpsideDown = true;\r\n\r\n    /**\r\n     * Define if double tap/click is used to restore the previously saved state of the camera.\r\n     */\r\n    @serialize()\r\n    public useInputToRestoreState = true;\r\n\r\n    /**\r\n     * Factor for restoring information interpolation. default is 0 = off. Any value \\< 0 or \\> 1 will disable interpolation.\r\n     */\r\n    @serialize()\r\n    public restoreStateInterpolationFactor = 0;\r\n\r\n    private _currentInterpolationFactor = 0;\r\n\r\n    /** @internal */\r\n    public override _viewMatrix = new Matrix();\r\n\r\n    private _useCtrlForPanningInternal: boolean = true;\r\n    private _panningMouseButtonInternal: number = 2;\r\n\r\n    /**\r\n     * Defines the input associated to the camera.\r\n     */\r\n    declare public inputs: ArcRotateCameraInputsManager;\r\n\r\n    /**\r\n     * Movement controller that provides framerate-independent physics and the declarative\r\n     * inputMap for configuring which inputs map to which camera behaviors.\r\n     *\r\n     * See {@link InputMapper} for the full inputMap API (e.g. `setInteraction`, `getEntry`, `addEntry`).\r\n     */\r\n    public override movement: ArcRotateCameraMovement;\r\n\r\n    /**\r\n     * Gets or sets whether ctrl+keyboard triggers panning.\r\n     * Setting this updates the keyboard→pan inputMap entry.\r\n     * @internal kept for backward compatibility\r\n     */\r\n    public get _useCtrlForPanning(): boolean {\r\n        return this._useCtrlForPanningInternal;\r\n    }\r\n\r\n    public set _useCtrlForPanning(value: boolean) {\r\n        this._useCtrlForPanningInternal = value;\r\n        const input = this.movement.input;\r\n\r\n        // Manage keyboard ctrl → pan entry\r\n        const keyboardEntry = input.getEntry(\"keyboard\", \"pan\", { modifiers: { ctrl: true } });\r\n        if (!value && keyboardEntry) {\r\n            input.inputMap.splice(input.inputMap.indexOf(keyboardEntry), 1);\r\n        } else if (value && !keyboardEntry) {\r\n            input.addEntry({ source: \"keyboard\", modifiers: { ctrl: true }, interaction: \"pan\" });\r\n        }\r\n\r\n        // Manage pointer ctrl+left-drag → pan entry (matches legacy ArcRotateCameraPointersInput behavior)\r\n        const pointerEntry = input.getEntry(\"pointer\", \"pan\", { modifiers: { ctrl: true } });\r\n        if (!value && pointerEntry) {\r\n            input.inputMap.splice(input.inputMap.indexOf(pointerEntry), 1);\r\n        } else if (value && !pointerEntry) {\r\n            input.addEntry({ source: \"pointer\", button: 0, modifiers: { ctrl: true }, interaction: \"pan\" });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets which mouse button triggers panning (0=left, 1=middle, 2=right).\r\n     * Setting this updates the pointer→pan inputMap entry.\r\n     * @internal kept for backward compatibility with attachControl signature\r\n     */\r\n    public get _panningMouseButton(): number {\r\n        return this._panningMouseButtonInternal;\r\n    }\r\n\r\n    public set _panningMouseButton(value: number) {\r\n        this._panningMouseButtonInternal = value;\r\n        const entry = this.movement.input.getEntry(\"pointer\", \"pan\", { modifiers: {} });\r\n        if (entry) {\r\n            entry.button = value;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _reset: () => void;\r\n\r\n    /**\r\n     * Defines the allowed panning axis.\r\n     */\r\n    public panningAxis: Vector3 = new Vector3(1, 1, 0);\r\n    protected _transformedDirection: Vector3 = new Vector3();\r\n\r\n    /**\r\n     * Defines if camera will eliminate transform on y axis.\r\n     */\r\n    public mapPanning: boolean = false;\r\n\r\n    // Behaviors\r\n    private _bouncingBehavior: Nullable<BouncingBehavior>;\r\n\r\n    // This is redundant with all _goal* properties being NaN, but we track it anyway because we check for active interpolation in the hot path.\r\n    private _isInterpolating = false;\r\n\r\n    /**\r\n     * If true, indicates the camera is currently interpolating to a new pose.\r\n     */\r\n    public get isInterpolating(): boolean {\r\n        return this._isInterpolating;\r\n    }\r\n\r\n    /**\r\n     * Gets the bouncing behavior of the camera if it has been enabled.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#bouncing-behavior\r\n     */\r\n    public get bouncingBehavior(): Nullable<BouncingBehavior> {\r\n        return this._bouncingBehavior;\r\n    }\r\n\r\n    /**\r\n     * Defines if the bouncing behavior of the camera is enabled on the camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#bouncing-behavior\r\n     */\r\n    public get useBouncingBehavior(): boolean {\r\n        return this._bouncingBehavior != null;\r\n    }\r\n\r\n    public set useBouncingBehavior(value: boolean) {\r\n        if (value === this.useBouncingBehavior) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this._bouncingBehavior = new BouncingBehavior();\r\n            this.addBehavior(this._bouncingBehavior);\r\n        } else if (this._bouncingBehavior) {\r\n            this.removeBehavior(this._bouncingBehavior);\r\n            this._bouncingBehavior = null;\r\n        }\r\n    }\r\n\r\n    private _framingBehavior: Nullable<FramingBehavior>;\r\n\r\n    /**\r\n     * Gets the framing behavior of the camera if it has been enabled.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#framing-behavior\r\n     */\r\n    public get framingBehavior(): Nullable<FramingBehavior> {\r\n        return this._framingBehavior;\r\n    }\r\n\r\n    /**\r\n     * Defines if the framing behavior of the camera is enabled on the camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#framing-behavior\r\n     */\r\n    public get useFramingBehavior(): boolean {\r\n        return this._framingBehavior != null;\r\n    }\r\n\r\n    public set useFramingBehavior(value: boolean) {\r\n        if (value === this.useFramingBehavior) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this._framingBehavior = new FramingBehavior();\r\n            this.addBehavior(this._framingBehavior);\r\n        } else if (this._framingBehavior) {\r\n            this.removeBehavior(this._framingBehavior);\r\n            this._framingBehavior = null;\r\n        }\r\n    }\r\n\r\n    private _autoRotationBehavior: Nullable<AutoRotationBehavior>;\r\n\r\n    /**\r\n     * Gets the auto rotation behavior of the camera if it has been enabled.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#autorotation-behavior\r\n     */\r\n    public get autoRotationBehavior(): Nullable<AutoRotationBehavior> {\r\n        return this._autoRotationBehavior;\r\n    }\r\n\r\n    /**\r\n     * Defines if the auto rotation behavior of the camera is enabled on the camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors#autorotation-behavior\r\n     */\r\n    public get useAutoRotationBehavior(): boolean {\r\n        return this._autoRotationBehavior != null;\r\n    }\r\n\r\n    public set useAutoRotationBehavior(value: boolean) {\r\n        if (value === this.useAutoRotationBehavior) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this._autoRotationBehavior = new AutoRotationBehavior();\r\n            this.addBehavior(this._autoRotationBehavior);\r\n        } else if (this._autoRotationBehavior) {\r\n            this.removeBehavior(this._autoRotationBehavior);\r\n            this._autoRotationBehavior = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Observable triggered when the transform node target has been changed on the camera.\r\n     */\r\n    public onMeshTargetChangedObservable = new Observable<Nullable<TransformNode>>();\r\n\r\n    /**\r\n     * Event raised when the camera is colliding with a mesh.\r\n     */\r\n    public onCollide: (collidedMesh: AbstractMesh) => void;\r\n\r\n    /**\r\n     * Defines whether the camera should check collision with the objects oh the scene.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions#how-can-i-do-this-\r\n     */\r\n    public checkCollisions = false;\r\n\r\n    /**\r\n     * Defines the collision radius of the camera.\r\n     * This simulates a sphere around the camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions#arcrotatecamera\r\n     */\r\n    public collisionRadius = new Vector3(0.5, 0.5, 0.5);\r\n\r\n    protected _collider: Collider;\r\n    protected _previousPosition = Vector3.Zero();\r\n    protected _collisionVelocity = Vector3.Zero();\r\n    protected _newPosition = Vector3.Zero();\r\n    protected _previousAlpha: number;\r\n    protected _previousBeta: number;\r\n    protected _previousRadius: number;\r\n    //due to async collision inspection\r\n    protected _collisionTriggered: boolean;\r\n\r\n    protected _targetBoundingCenter: Nullable<Vector3>;\r\n\r\n    private _computationVector: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Instantiates a new ArcRotateCamera in a given scene\r\n     * @param name Defines the name of the camera\r\n     * @param alpha Defines the camera rotation along the longitudinal axis\r\n     * @param beta Defines the camera rotation along the latitudinal axis\r\n     * @param radius Defines the camera distance from its target\r\n     * @param target Defines the camera target\r\n     * @param scene Defines the scene the camera belongs to\r\n     * @param setActiveOnSceneIfNoneActive Defines whether the camera should be marked as active if not other active cameras have been defined\r\n     */\r\n    constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive = true) {\r\n        super(name, Vector3.Zero(), scene, setActiveOnSceneIfNoneActive);\r\n\r\n        this._target = Vector3.Zero();\r\n        if (target) {\r\n            this.setTarget(target);\r\n        }\r\n\r\n        this.alpha = alpha;\r\n        this.beta = beta;\r\n        this.radius = radius;\r\n\r\n        this.getViewMatrix();\r\n        this.inputs = new ArcRotateCameraInputsManager(this);\r\n        this.inputs.addKeyboard().addMouseWheel().addPointers();\r\n        this.movement = new ArcRotateCameraMovement(this.getScene(), this._position);\r\n        // Seed movement-system inertia from the values set during base/subclass construction.\r\n        // After this point, the inertia/panningInertia setters on this class push directly to movement.\r\n        this.movement.rotationInertia = this._inertia;\r\n        this.movement.zoomInertia = this._inertia;\r\n        this.movement.panInertia = this._panningInertia;\r\n    }\r\n\r\n    // Cache\r\n    /** @internal */\r\n    public override _initCache(): void {\r\n        super._initCache();\r\n        this._cache._target = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        this._cache.alpha = undefined;\r\n        this._cache.beta = undefined;\r\n        this._cache.radius = undefined;\r\n        this._cache.targetScreenOffset = Vector2.Zero();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateCache(ignoreParentClass?: boolean): void {\r\n        if (!ignoreParentClass) {\r\n            super._updateCache();\r\n        }\r\n\r\n        this._cache._target.copyFrom(this._getTargetPosition());\r\n        this._cache.alpha = this.alpha;\r\n        this._cache.beta = this.beta;\r\n        this._cache.radius = this.radius;\r\n        this._cache.targetScreenOffset.copyFrom(this.targetScreenOffset);\r\n    }\r\n\r\n    protected _getTargetPosition(): Vector3 {\r\n        if (this._targetHost && this._targetHost.getAbsolutePosition) {\r\n            const pos: Vector3 = this._targetHost.getAbsolutePosition();\r\n            if (this._targetBoundingCenter) {\r\n                pos.addToRef(this._targetBoundingCenter, this._target);\r\n            } else {\r\n                this._target.copyFrom(pos);\r\n            }\r\n        }\r\n\r\n        const lockedTargetPosition = this._getLockedTargetPosition();\r\n\r\n        if (lockedTargetPosition) {\r\n            return lockedTargetPosition;\r\n        }\r\n\r\n        return this._target;\r\n    }\r\n\r\n    private _storedAlpha: number;\r\n    private _storedBeta: number;\r\n    private _storedRadius: number;\r\n    private _storedTarget: Vector3;\r\n    private _storedTargetScreenOffset: Vector2;\r\n\r\n    private _goalAlpha = NaN;\r\n    private _goalBeta = NaN;\r\n    private _goalRadius = NaN;\r\n    private readonly _goalTarget = new Vector3(NaN, NaN, NaN);\r\n    private readonly _goalTargetScreenOffset = new Vector2(NaN, NaN);\r\n\r\n    /**\r\n     * Stores the current state of the camera (alpha, beta, radius and target)\r\n     * @returns the camera itself\r\n     */\r\n    public override storeState(): Camera {\r\n        this._storedAlpha = this.alpha;\r\n        this._storedBeta = this.beta;\r\n        this._storedRadius = this.radius;\r\n        this._storedTarget = this._getTargetPosition().clone();\r\n        this._storedTargetScreenOffset = this.targetScreenOffset.clone();\r\n\r\n        return super.storeState();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Restored camera state. You must call storeState() first\r\n     */\r\n    public override _restoreStateValues(): boolean {\r\n        if (this.hasStateStored() && this.restoreStateInterpolationFactor > Epsilon && this.restoreStateInterpolationFactor < 1) {\r\n            this.interpolateTo(this._storedAlpha, this._storedBeta, this._storedRadius, this._storedTarget, this._storedTargetScreenOffset, this.restoreStateInterpolationFactor);\r\n            return true;\r\n        }\r\n        if (!super._restoreStateValues()) {\r\n            return false;\r\n        }\r\n\r\n        this.setTarget(this._storedTarget.clone());\r\n        this.alpha = this._storedAlpha;\r\n        this.beta = this._storedBeta;\r\n        this.radius = this._storedRadius;\r\n        this.targetScreenOffset = this._storedTargetScreenOffset.clone();\r\n\r\n        this.inertialAlphaOffset = 0;\r\n        this.inertialBetaOffset = 0;\r\n        this.inertialRadiusOffset = 0;\r\n        this.inertialPanningX = 0;\r\n        this.inertialPanningY = 0;\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Stops any in-progress interpolation.\r\n     */\r\n    public stopInterpolation(): void {\r\n        this._goalAlpha = NaN;\r\n        this._goalBeta = NaN;\r\n        this._goalRadius = NaN;\r\n        this._goalTarget.set(NaN, NaN, NaN);\r\n        this._goalTargetScreenOffset.set(NaN, NaN);\r\n    }\r\n\r\n    /**\r\n     * Interpolates the camera to a goal state.\r\n     * @param alpha Defines the goal alpha.\r\n     * @param beta Defines the goal beta.\r\n     * @param radius Defines the goal radius.\r\n     * @param target Defines the goal target.\r\n     * @param targetScreenOffset Defines the goal target screen offset.\r\n     * @param interpolationFactor A value  between 0 and 1 that determines the speed of the interpolation.\r\n     * @remarks Passing undefined for any of the parameters will use the current value (effectively stopping any in-progress interpolation for that parameter).\r\n     *          Passing NaN will not start or stop any interpolation for that parameter (effectively allowing multiple interpolations of different parameters to overlap).\r\n     */\r\n    public interpolateTo(\r\n        alpha = this.alpha,\r\n        beta = this.beta,\r\n        radius = this.radius,\r\n        target = this.target,\r\n        targetScreenOffset = this.targetScreenOffset,\r\n        interpolationFactor?: number\r\n    ): void {\r\n        this.inertialAlphaOffset = 0;\r\n        this.inertialBetaOffset = 0;\r\n        this.inertialRadiusOffset = 0;\r\n        this.inertialPanningX = 0;\r\n        this.inertialPanningY = 0;\r\n\r\n        if (interpolationFactor != null) {\r\n            this._currentInterpolationFactor = interpolationFactor;\r\n        } else if (this.restoreStateInterpolationFactor !== 0) {\r\n            this._currentInterpolationFactor = this.restoreStateInterpolationFactor;\r\n        } else {\r\n            this._currentInterpolationFactor = 0.1;\r\n        }\r\n\r\n        // If NaN is passed in for a goal value, keep the current goal value.\r\n        this._goalAlpha = CheckNaN(alpha, this._goalAlpha);\r\n        this._goalBeta = CheckNaN(beta, this._goalBeta);\r\n        this._goalRadius = CheckNaN(radius, this._goalRadius);\r\n        this._goalTarget.set(CheckNaN(target.x, this._goalTarget.x), CheckNaN(target.y, this._goalTarget.y), CheckNaN(target.z, this._goalTarget.z));\r\n        this._goalTargetScreenOffset.set(CheckNaN(targetScreenOffset.x, this._goalTargetScreenOffset.x), CheckNaN(targetScreenOffset.y, this._goalTargetScreenOffset.y));\r\n\r\n        this._goalAlpha = Clamp(this._goalAlpha, this.lowerAlphaLimit ?? -Infinity, this.upperAlphaLimit ?? Infinity);\r\n        this._goalBeta = Clamp(this._goalBeta, this.lowerBetaLimit ?? -Infinity, this.upperBetaLimit ?? Infinity);\r\n        this._goalRadius = Clamp(this._goalRadius, this.lowerRadiusLimit ?? -Infinity, this.upperRadiusLimit ?? Infinity);\r\n        this._goalTarget.y = Clamp(this._goalTarget.y, this.lowerTargetYLimit ?? -Infinity, Infinity);\r\n\r\n        this._isInterpolating = true;\r\n    }\r\n\r\n    // Synchronized\r\n    /** @internal */\r\n    public override _isSynchronizedViewMatrix(): boolean {\r\n        if (!super._isSynchronizedViewMatrix()) {\r\n            return false;\r\n        }\r\n\r\n        return (\r\n            this._cache._target.equals(this._getTargetPosition()) &&\r\n            this._cache.alpha === this.alpha &&\r\n            this._cache.beta === this.beta &&\r\n            this._cache.radius === this.radius &&\r\n            this._cache.targetScreenOffset.equals(this.targetScreenOffset)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(noPreventDefault?: boolean): void;\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(ignored: any, noPreventDefault?: boolean): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     * @param useCtrlForPanning  Defines whether ctrl is used for panning within the controls\r\n     */\r\n    public override attachControl(noPreventDefault: boolean, useCtrlForPanning: boolean): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     * @param useCtrlForPanning  Defines whether ctrl is used for panning within the controls\r\n     */\r\n    public override attachControl(ignored: any, noPreventDefault: boolean, useCtrlForPanning: boolean): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     * @param useCtrlForPanning  Defines whether ctrl is used for panning within the controls\r\n     * @param panningMouseButton Defines whether panning is allowed through mouse click button\r\n     */\r\n    public override attachControl(noPreventDefault: boolean, useCtrlForPanning: boolean, panningMouseButton: number): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     * @param useCtrlForPanning  Defines whether ctrl is used for panning within the controls\r\n     * @param panningMouseButton Defines whether panning is allowed through mouse click button\r\n     */\r\n    public override attachControl(ignored: any, noPreventDefault?: boolean, useCtrlForPanning: boolean | number = true, panningMouseButton: number = 2): void {\r\n        const args = arguments;\r\n\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(args);\r\n        this._useCtrlForPanning = useCtrlForPanning as boolean;\r\n        this._panningMouseButton = panningMouseButton;\r\n        // backwards compatibility\r\n        if (typeof args[0] === \"boolean\") {\r\n            if (args.length > 1) {\r\n                this._useCtrlForPanning = args[1];\r\n            }\r\n            if (args.length > 2) {\r\n                this._panningMouseButton = args[2];\r\n            }\r\n        }\r\n\r\n        this.inputs.attachElement(noPreventDefault);\r\n\r\n        this._reset = () => {\r\n            this.inertialAlphaOffset = 0;\r\n            this.inertialBetaOffset = 0;\r\n            this.inertialRadiusOffset = 0;\r\n            this.inertialPanningX = 0;\r\n            this.inertialPanningY = 0;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public override detachControl(): void {\r\n        this.inputs.detachElement();\r\n\r\n        if (this._reset) {\r\n            this._reset();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Applies rotation and zoom deltas to the camera, handling invertRotation, handedness, and beta-flip.\r\n     * Shared by both the movement system and legacy inertia paths.\r\n     * @param alphaOffset - Alpha (horizontal orbit) delta\r\n     * @param betaOffset - Beta (vertical orbit) delta\r\n     * @param radiusOffset - Radius (zoom) delta\r\n     */\r\n    private _applyRotationAndZoomDelta(alphaOffset: number, betaOffset: number, radiusOffset: number): void {\r\n        const directionModifier = this.invertRotation ? -1 : 1;\r\n        const handednessMultiplier = this._calculateHandednessMultiplier();\r\n        let adjustedAlpha = alphaOffset * handednessMultiplier;\r\n\r\n        if (this.beta < 0) {\r\n            adjustedAlpha *= -1;\r\n        }\r\n\r\n        this.alpha += adjustedAlpha * directionModifier;\r\n        this.beta += betaOffset * directionModifier;\r\n        this.radius -= radiusOffset;\r\n    }\r\n\r\n    /**\r\n     * Applies a pan delta to the camera target in screen space.\r\n     * Shared by both the movement system and legacy inertia paths.\r\n     * @param panX - Horizontal pan delta\r\n     * @param panY - Vertical pan delta\r\n     */\r\n    private _applyPanDelta(panX: number, panY: number): void {\r\n        const localDirection = TmpVectors.Vector3[0].copyFromFloats(panX, panY, panY);\r\n\r\n        this._viewMatrix.invertToRef(this._cameraTransformMatrix);\r\n        localDirection.multiplyInPlace(this.panningAxis);\r\n        Vector3.TransformNormalToRef(localDirection, this._cameraTransformMatrix, this._transformedDirection);\r\n\r\n        if (this.mapPanning) {\r\n            const up = this.upVector;\r\n            const right = Vector3.CrossToRef(this._transformedDirection, up, this._transformedDirection);\r\n            Vector3.CrossToRef(up, right, this._transformedDirection);\r\n        } else if (!this.panningAxis.y) {\r\n            this._transformedDirection.y = 0;\r\n        }\r\n\r\n        if (!this._targetHost) {\r\n            if (this.panningDistanceLimit !== null) {\r\n                this._transformedDirection.addInPlace(this._target);\r\n                const distanceSquared = Vector3.DistanceSquared(this._transformedDirection, this.panningOriginTarget);\r\n                if (distanceSquared <= this.panningDistanceLimit * this.panningDistanceLimit) {\r\n                    this._target.copyFrom(this._transformedDirection);\r\n                }\r\n            } else {\r\n                if (this.parent) {\r\n                    const m = TmpVectors.Matrix[0];\r\n                    this.parent.getWorldMatrix().getRotationMatrixToRef(m);\r\n                    m.transposeToRef(m);\r\n                    Vector3.TransformCoordinatesToRef(this._transformedDirection, m, this._transformedDirection);\r\n                }\r\n                this._target.addInPlace(this._transformedDirection);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _checkInputs(): void {\r\n        //if (async) collision inspection was triggered, don't update the camera's position - until the collision callback was called.\r\n        if (this._collisionTriggered) {\r\n            return;\r\n        }\r\n\r\n        this.inputs.checkInputs();\r\n        let hasUserInteractions = false;\r\n\r\n        this.movement.computeCurrentFrameDeltas();\r\n\r\n        const rotDelta = this.movement.rotationDeltaCurrentFrame;\r\n        const zoomDelta = this.movement.zoomDeltaCurrentFrame;\r\n        const panDelta = this.movement.panDeltaCurrentFrame;\r\n\r\n        if (rotDelta.x !== 0 || rotDelta.y !== 0 || zoomDelta !== 0 || panDelta.x !== 0 || panDelta.y !== 0) {\r\n            hasUserInteractions = true;\r\n            if (rotDelta.x !== 0 || rotDelta.y !== 0 || zoomDelta !== 0) {\r\n                this._applyRotationAndZoomDelta(rotDelta.x, rotDelta.y, zoomDelta);\r\n            }\r\n\r\n            if (panDelta.x !== 0 || panDelta.y !== 0) {\r\n                this._applyPanDelta(panDelta.x, panDelta.y);\r\n            }\r\n        }\r\n\r\n        // Legacy inertial offsets — backward compat path. Handles direct writes to inertialAlphaOffset\r\n        // etc. (including zoomToMouseLocation which writes to inertialRadiusOffset).\r\n        // Only activates when these values are nonzero, so it is free when unused.\r\n        // We check the private fields here instead of the public getters because the getters fall back\r\n        // to the movement system's current-frame deltas (for back-compat polling), which would cause\r\n        // double-application of the rotation/zoom that movement.computeCurrentFrameDeltas just produced.\r\n        //\r\n        // Note: unlike TargetCamera, none of ArcRotateCamera's channels (rotate/zoom/pan) scale their\r\n        // magnitude by `this.speed` (movement.speed stays 1; inputs use angularSensibility / wheel\r\n        // precision / panningSensibility). So the glide cutoffs below must NOT be scaled by `speed` —\r\n        // doing so only truncated the inertia tail earlier at higher speeds without making the camera\r\n        // any faster (forum 61001).\r\n        if (this._inertialAlphaOffset !== 0 || this._inertialBetaOffset !== 0 || this._inertialRadiusOffset !== 0) {\r\n            this._applyRotationAndZoomDelta(this._inertialAlphaOffset, this._inertialBetaOffset, this._inertialRadiusOffset);\r\n            this._inertialAlphaOffset *= this.inertia;\r\n            this._inertialBetaOffset *= this.inertia;\r\n            this._inertialRadiusOffset *= this.inertia;\r\n            if (Math.abs(this._inertialAlphaOffset) < this._rotationEpsilon) {\r\n                this._inertialAlphaOffset = 0;\r\n            }\r\n            if (Math.abs(this._inertialBetaOffset) < this._rotationEpsilon) {\r\n                this._inertialBetaOffset = 0;\r\n            }\r\n            if (Math.abs(this._inertialRadiusOffset) < this._rotationEpsilon) {\r\n                this._inertialRadiusOffset = 0;\r\n            }\r\n            hasUserInteractions = true;\r\n        }\r\n\r\n        if (this.inertialPanningX !== 0 || this.inertialPanningY !== 0) {\r\n            this._applyPanDelta(this.inertialPanningX, this.inertialPanningY);\r\n            this.inertialPanningX *= this.panningInertia;\r\n            this.inertialPanningY *= this.panningInertia;\r\n            const inertialPanningLimit = this._panningEpsilon;\r\n            if (Math.abs(this.inertialPanningX) < inertialPanningLimit) {\r\n                this.inertialPanningX = 0;\r\n            }\r\n            if (Math.abs(this.inertialPanningY) < inertialPanningLimit) {\r\n                this.inertialPanningY = 0;\r\n            }\r\n            hasUserInteractions = true;\r\n        }\r\n\r\n        if (hasUserInteractions) {\r\n            this.stopInterpolation();\r\n        } else if (this._isInterpolating) {\r\n            let isInterpolating = false;\r\n            const dt = this._scene.getEngine().getDeltaTime() / 1000;\r\n            const t = 1 - Math.pow(2, -dt / this._currentInterpolationFactor);\r\n\r\n            // NOTE: If the goal is NaN, it means we are not interpolating to a new value, so we can use the current value. Hence the calls to checkNaN.\r\n\r\n            // Get the goal radius immediately as we'll need it for determining interpolation termination for the target.\r\n            const goalRadius = CheckNaN(this._goalRadius, this.radius);\r\n\r\n            // Interpolate the target if we haven't reached the goal yet.\r\n            if (!isNaN(this._goalTarget.x) || !isNaN(this._goalTarget.y) || !isNaN(this._goalTarget.z)) {\r\n                const goalTarget = TmpVectors.Vector3[0].set(\r\n                    CheckNaN(this._goalTarget.x, this._target.x),\r\n                    CheckNaN(this._goalTarget.y, this._target.y),\r\n                    CheckNaN(this._goalTarget.z, this._target.z)\r\n                );\r\n                Vector3.LerpToRef(this.target, goalTarget, t, this._target);\r\n\r\n                // Terminate the target interpolation if we the target is close relative to the radius.\r\n                // This is when visually (regardless of scale) the target appears close to its final goal position.\r\n                if ((Vector3.Distance(this.target, goalTarget) * 10) / goalRadius < Epsilon) {\r\n                    this._goalTarget.set(NaN, NaN, NaN);\r\n                    this.target.copyFrom(goalTarget);\r\n                    // Call setTarget to trigger side effects like onMeshTargetChangedObservable.\r\n                    // NOTE: We pass in true for allowSamePosition because we already checked that the goal target is different from the current target,\r\n                    // but since we are updating the existing target Vector3 instance, it will otherwise look like the value has not changed.\r\n                    this.setTarget(this.target, false, true, true);\r\n                } else {\r\n                    isInterpolating = true;\r\n                }\r\n            }\r\n\r\n            // Interpolate the rotation if we haven't reached the goal yet.\r\n            if (!isNaN(this._goalAlpha) || !isNaN(this._goalBeta)) {\r\n                // Using quaternion for smoother interpolation (and no Euler angles modulo)\r\n                const goalRotation = Quaternion.RotationAlphaBetaGammaToRef(\r\n                    CheckNaN(this._goalAlpha, this.alpha),\r\n                    CheckNaN(this._goalBeta, this.beta),\r\n                    0,\r\n                    TmpVectors.Quaternion[0]\r\n                );\r\n                const currentRotation = Quaternion.RotationAlphaBetaGammaToRef(this.alpha, this.beta, 0, TmpVectors.Quaternion[1]);\r\n                const newRotation = Quaternion.SlerpToRef(currentRotation, goalRotation, t, TmpVectors.Quaternion[2]);\r\n                newRotation.normalize();\r\n                const newAlphaBetaGamma = newRotation.toAlphaBetaGammaToRef(TmpVectors.Vector3[0]);\r\n                this.alpha = newAlphaBetaGamma.x;\r\n                this.beta = newAlphaBetaGamma.y;\r\n\r\n                // Terminate the rotation interpolation when the rotation appears visually close to the final goal rotation.\r\n                if (newRotation.isApprox(goalRotation, Epsilon / 5)) {\r\n                    this._goalAlpha = NaN;\r\n                    this._goalBeta = NaN;\r\n                    const goalAlphaBetaGamma = goalRotation.toAlphaBetaGammaToRef(TmpVectors.Vector3[0]);\r\n                    this.alpha = goalAlphaBetaGamma.x;\r\n                    this.beta = goalAlphaBetaGamma.y;\r\n                } else {\r\n                    isInterpolating = true;\r\n                }\r\n            }\r\n\r\n            // Interpolate the radius if we haven't reached the goal yet.\r\n            if (!isNaN(this._goalRadius)) {\r\n                this.radius += (goalRadius - this.radius) * t;\r\n\r\n                // Terminate the radius interpolation when we are 99.9% of the way to the goal radius, at which point it is visually indistinguishable from the goal.\r\n                if (Math.abs(goalRadius / this.radius - 1) < Epsilon) {\r\n                    this._goalRadius = NaN;\r\n                    this.radius = goalRadius;\r\n                } else {\r\n                    isInterpolating = true;\r\n                }\r\n            }\r\n\r\n            // Interpolate the target screen offset if we haven't reached the goal yet.\r\n            if (!isNaN(this._goalTargetScreenOffset.x) || !isNaN(this._goalTargetScreenOffset.y)) {\r\n                const goalTargetScreenOffset = TmpVectors.Vector2[0].set(\r\n                    CheckNaN(this._goalTargetScreenOffset.x, this.targetScreenOffset.x),\r\n                    CheckNaN(this._goalTargetScreenOffset.y, this.targetScreenOffset.y)\r\n                );\r\n                Vector2.LerpToRef(this.targetScreenOffset, goalTargetScreenOffset, t, this.targetScreenOffset);\r\n\r\n                // Terminate the target screen offset interpolation when the target screen offset appears visually close to the final goal target screen offset.\r\n                if (Vector2.Distance(this.targetScreenOffset, goalTargetScreenOffset) < Epsilon) {\r\n                    this._goalTargetScreenOffset.set(NaN, NaN);\r\n                    this.targetScreenOffset.copyFrom(goalTargetScreenOffset);\r\n                } else {\r\n                    isInterpolating = true;\r\n                }\r\n            }\r\n\r\n            this._isInterpolating = isInterpolating;\r\n        }\r\n\r\n        // Limits\r\n        this._checkLimits();\r\n\r\n        super._checkInputs();\r\n    }\r\n\r\n    protected _checkLimits() {\r\n        if (this.lowerBetaLimit === null || this.lowerBetaLimit === undefined) {\r\n            if (this.allowUpsideDown && this.beta > Math.PI) {\r\n                this.beta = this.beta - 2 * Math.PI;\r\n            }\r\n        } else {\r\n            if (this.beta < this.lowerBetaLimit) {\r\n                this.beta = this.lowerBetaLimit;\r\n            }\r\n        }\r\n\r\n        if (this.upperBetaLimit === null || this.upperBetaLimit === undefined) {\r\n            if (this.allowUpsideDown && this.beta < -Math.PI) {\r\n                this.beta = this.beta + 2 * Math.PI;\r\n            }\r\n        } else {\r\n            if (this.beta > this.upperBetaLimit) {\r\n                this.beta = this.upperBetaLimit;\r\n            }\r\n        }\r\n\r\n        if (this.lowerAlphaLimit !== null && this.alpha < this.lowerAlphaLimit) {\r\n            this.alpha = this.lowerAlphaLimit;\r\n        }\r\n        if (this.upperAlphaLimit !== null && this.alpha > this.upperAlphaLimit) {\r\n            this.alpha = this.upperAlphaLimit;\r\n        }\r\n\r\n        if (this.lowerRadiusLimit !== null && this.radius < this.lowerRadiusLimit) {\r\n            this.radius = this.lowerRadiusLimit;\r\n            this.inertialRadiusOffset = 0;\r\n        }\r\n        if (this.upperRadiusLimit !== null && this.radius > this.upperRadiusLimit) {\r\n            this.radius = this.upperRadiusLimit;\r\n            this.inertialRadiusOffset = 0;\r\n        }\r\n\r\n        this.target.y = Math.max(this.target.y, this.lowerTargetYLimit);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds angles (alpha, beta) and radius from the give position and target\r\n     */\r\n    public rebuildAnglesAndRadius(): void {\r\n        this._position.subtractToRef(this._getTargetPosition(), this._computationVector);\r\n\r\n        // need to rotate to Y up equivalent if up vector not Axis.Y\r\n        if (this._upVector.x !== 0 || this._upVector.y !== 1.0 || this._upVector.z !== 0) {\r\n            Vector3.TransformCoordinatesToRef(this._computationVector, this._upToYMatrix, this._computationVector);\r\n        }\r\n\r\n        this.radius = this._computationVector.length();\r\n\r\n        if (this.radius === 0) {\r\n            this.radius = 0.0001; // Just to avoid division by zero\r\n        }\r\n\r\n        // Alpha and Beta\r\n        const previousAlpha = this.alpha;\r\n        this.alpha = ComputeAlpha(this._computationVector);\r\n        this.beta = ComputeBeta(this._computationVector.y, this.radius);\r\n\r\n        // Calculate the number of revolutions between the new and old alpha values.\r\n        const alphaCorrectionTurns = Math.round((previousAlpha - this.alpha) / (2.0 * Math.PI));\r\n        // Adjust alpha so that its numerical representation is the closest one to the old value.\r\n        this.alpha += alphaCorrectionTurns * 2.0 * Math.PI;\r\n\r\n        this._checkLimits();\r\n    }\r\n\r\n    /**\r\n     * Use a position to define the current camera related information like alpha, beta and radius\r\n     * @param position Defines the position to set the camera at\r\n     */\r\n    public setPosition(position: Vector3): void {\r\n        if (this._position.equals(position)) {\r\n            return;\r\n        }\r\n        this._position.copyFrom(position);\r\n\r\n        this.rebuildAnglesAndRadius();\r\n    }\r\n\r\n    /**\r\n     * Defines the target the camera should look at.\r\n     * This will automatically adapt alpha beta and radius to fit within the new target.\r\n     * Please note that setting a target as a mesh will disable panning.\r\n     * @param target Defines the new target as a Vector or a transform node\r\n     * @param toBoundingCenter In case of a mesh target, defines whether to target the mesh position or its bounding information center\r\n     * @param allowSamePosition If false, prevents reapplying the new computed position if it is identical to the current one (optim)\r\n     * @param cloneAlphaBetaRadius If true, replicate the current setup (alpha, beta, radius) on the new target\r\n     */\r\n    public override setTarget(target: TransformNode | Vector3, toBoundingCenter = false, allowSamePosition = false, cloneAlphaBetaRadius = false): void {\r\n        cloneAlphaBetaRadius = this.overrideCloneAlphaBetaRadius ?? cloneAlphaBetaRadius;\r\n\r\n        if ((target as TransformNode).computeWorldMatrix) {\r\n            if (toBoundingCenter && (<any>target).getBoundingInfo) {\r\n                this._targetBoundingCenter = (<any>target).getBoundingInfo().boundingBox.centerWorld.clone();\r\n            } else {\r\n                this._targetBoundingCenter = null;\r\n            }\r\n            (<TransformNode>target).computeWorldMatrix();\r\n            this._targetHost = <TransformNode>target;\r\n            this._target = this._getTargetPosition();\r\n\r\n            this.onMeshTargetChangedObservable.notifyObservers(this._targetHost);\r\n        } else {\r\n            const newTarget = <Vector3>target;\r\n            const currentTarget = this._getTargetPosition();\r\n            if (currentTarget && !allowSamePosition && currentTarget.equals(newTarget)) {\r\n                return;\r\n            }\r\n            this._targetHost = null;\r\n            this._target = newTarget;\r\n            this._targetBoundingCenter = null;\r\n            this.onMeshTargetChangedObservable.notifyObservers(null);\r\n        }\r\n\r\n        if (!cloneAlphaBetaRadius) {\r\n            this.rebuildAnglesAndRadius();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _getViewMatrix(): Matrix {\r\n        // Compute\r\n        const cosa = Math.cos(this.alpha);\r\n        const sina = Math.sin(this.alpha);\r\n        const cosb = Math.cos(this.beta);\r\n        let sinb = Math.sin(this.beta);\r\n\r\n        if (sinb === 0) {\r\n            sinb = 0.0001;\r\n        }\r\n\r\n        if (this.radius === 0) {\r\n            this.radius = 0.0001; // Just to avoid division by zero\r\n        }\r\n\r\n        const target = this._getTargetPosition();\r\n        this._computationVector.copyFromFloats(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb);\r\n\r\n        // Rotate according to up vector\r\n        if (this._upVector.x !== 0 || this._upVector.y !== 1.0 || this._upVector.z !== 0) {\r\n            Vector3.TransformCoordinatesToRef(this._computationVector, this._yToUpMatrix, this._computationVector);\r\n        }\r\n\r\n        target.addToRef(this._computationVector, this._newPosition);\r\n        if (this.getScene().collisionsEnabled && this.checkCollisions) {\r\n            const coordinator = this.getScene().collisionCoordinator;\r\n            if (!this._collider) {\r\n                this._collider = coordinator.createCollider();\r\n            }\r\n            this._collider._radius = this.collisionRadius;\r\n            this._newPosition.subtractToRef(this._position, this._collisionVelocity);\r\n            this._collisionTriggered = true;\r\n            coordinator.getNewPosition(this._position, this._collisionVelocity, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId);\r\n        } else {\r\n            this._position.copyFrom(this._newPosition);\r\n\r\n            let up = this.upVector;\r\n            if (this.allowUpsideDown && sinb < 0) {\r\n                up = up.negate();\r\n            }\r\n\r\n            this._computeViewMatrix(this._position, target, up);\r\n\r\n            this._viewMatrix.addAtIndex(12, this.targetScreenOffset.x);\r\n            this._viewMatrix.addAtIndex(13, this.targetScreenOffset.y);\r\n        }\r\n        this._currentTarget.copyFrom(target);\r\n        return this._viewMatrix;\r\n    }\r\n\r\n    protected _onCollisionPositionChange = (collisionId: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh> = null) => {\r\n        if (!collidedMesh) {\r\n            this._previousPosition.copyFrom(this._position);\r\n        } else {\r\n            this.setPosition(newPosition);\r\n\r\n            if (this.onCollide) {\r\n                this.onCollide(collidedMesh);\r\n            }\r\n        }\r\n\r\n        // Recompute because of constraints\r\n        const cosa = Math.cos(this.alpha);\r\n        const sina = Math.sin(this.alpha);\r\n        const cosb = Math.cos(this.beta);\r\n        let sinb = Math.sin(this.beta);\r\n\r\n        if (sinb === 0) {\r\n            sinb = 0.0001;\r\n        }\r\n\r\n        const target = this._getTargetPosition();\r\n        this._computationVector.copyFromFloats(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb);\r\n        target.addToRef(this._computationVector, this._newPosition);\r\n        this._position.copyFrom(this._newPosition);\r\n\r\n        let up = this.upVector;\r\n        if (this.allowUpsideDown && this.beta < 0) {\r\n            up = up.clone();\r\n            up = up.negate();\r\n        }\r\n\r\n        this._computeViewMatrix(this._position, target, up);\r\n        this._viewMatrix.addAtIndex(12, this.targetScreenOffset.x);\r\n        this._viewMatrix.addAtIndex(13, this.targetScreenOffset.y);\r\n\r\n        this._collisionTriggered = false;\r\n    };\r\n\r\n    /**\r\n     * Zooms on a mesh to be at the min distance where we could see it fully in the current viewport.\r\n     * @param meshes Defines the mesh to zoom on\r\n     * @param doNotUpdateMaxZ Defines whether or not maxZ should be updated whilst zooming on the mesh (this can happen if the mesh is big and the maxradius pretty small for instance)\r\n     */\r\n    public zoomOn(meshes?: AbstractMesh[], doNotUpdateMaxZ = false): void {\r\n        meshes = meshes || this.getScene().meshes;\r\n\r\n        const minMaxVector = Mesh.MinMax(meshes);\r\n        let distance = this._calculateLowerRadiusFromModelBoundingSphere(minMaxVector.min, minMaxVector.max);\r\n\r\n        // If there are defined limits, we need to take them into account\r\n        distance = Math.max(Math.min(distance, this.upperRadiusLimit || Number.MAX_VALUE), this.lowerRadiusLimit || 0);\r\n        this.radius = distance * this.zoomOnFactor;\r\n\r\n        if (this.mode === Camera.ORTHOGRAPHIC_CAMERA) {\r\n            const aspectRatio = this.getScene().getEngine().getAspectRatio(this);\r\n            const orthoExtent = (distance * this.zoomOnFactor) / 2;\r\n            this.orthoLeft = -orthoExtent * aspectRatio;\r\n            this.orthoRight = orthoExtent * aspectRatio;\r\n            this.orthoBottom = -orthoExtent;\r\n            this.orthoTop = orthoExtent;\r\n        }\r\n\r\n        this.focusOn({ min: minMaxVector.min, max: minMaxVector.max, distance: distance }, doNotUpdateMaxZ);\r\n    }\r\n\r\n    /**\r\n     * Focus on a mesh or a bounding box. This adapts the target and maxRadius if necessary but does not update the current radius.\r\n     * The target will be changed but the radius\r\n     * @param meshesOrMinMaxVectorAndDistance Defines the mesh or bounding info to focus on\r\n     * @param doNotUpdateMaxZ Defines whether or not maxZ should be updated whilst zooming on the mesh (this can happen if the mesh is big and the maxradius pretty small for instance)\r\n     */\r\n    public focusOn(meshesOrMinMaxVectorAndDistance: AbstractMesh[] | { min: Vector3; max: Vector3; distance: number }, doNotUpdateMaxZ = false): void {\r\n        let meshesOrMinMaxVector: { min: Vector3; max: Vector3 };\r\n        let distance: number;\r\n\r\n        if ((<any>meshesOrMinMaxVectorAndDistance).min === undefined) {\r\n            // meshes\r\n            const meshes = <AbstractMesh[]>meshesOrMinMaxVectorAndDistance || this.getScene().meshes;\r\n            meshesOrMinMaxVector = Mesh.MinMax(meshes);\r\n            distance = Vector3.Distance(meshesOrMinMaxVector.min, meshesOrMinMaxVector.max);\r\n        } else {\r\n            //minMaxVector and distance\r\n            const minMaxVectorAndDistance = <any>meshesOrMinMaxVectorAndDistance;\r\n            meshesOrMinMaxVector = minMaxVectorAndDistance;\r\n            distance = minMaxVectorAndDistance.distance;\r\n        }\r\n\r\n        this._target = Mesh.Center(meshesOrMinMaxVector);\r\n\r\n        if (!doNotUpdateMaxZ) {\r\n            this.maxZ = distance * 2;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @override\r\n     * Override Camera.createRigCamera\r\n     * @param name the name of the camera\r\n     * @param cameraIndex the index of the camera in the rig cameras array\r\n     */\r\n    public override createRigCamera(name: string, cameraIndex: number): Camera {\r\n        let alphaShift: number = 0;\r\n        switch (this.cameraRigMode) {\r\n            case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_INTERLACED:\r\n            case Camera.RIG_MODE_VR:\r\n                alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);\r\n                break;\r\n            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:\r\n                alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? -1 : 1);\r\n                break;\r\n        }\r\n        const rigCam = new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this._target, this.getScene());\r\n        rigCam._cameraRigParams = {};\r\n        rigCam.isRigCamera = true;\r\n        rigCam.rigParent = this;\r\n        rigCam.upVector = this.upVector;\r\n\r\n        rigCam.mode = this.mode;\r\n        rigCam.orthoLeft = this.orthoLeft;\r\n        rigCam.orthoRight = this.orthoRight;\r\n        rigCam.orthoBottom = this.orthoBottom;\r\n        rigCam.orthoTop = this.orthoTop;\r\n\r\n        return rigCam;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * @override\r\n     * Override Camera._updateRigCameras\r\n     */\r\n    public override _updateRigCameras() {\r\n        const camLeft = <ArcRotateCamera>this._rigCameras[0];\r\n        const camRight = <ArcRotateCamera>this._rigCameras[1];\r\n\r\n        camLeft.beta = camRight.beta = this.beta;\r\n\r\n        switch (this.cameraRigMode) {\r\n            case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:\r\n            case Camera.RIG_MODE_STEREOSCOPIC_INTERLACED:\r\n            case Camera.RIG_MODE_VR:\r\n                camLeft.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;\r\n                camRight.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;\r\n                break;\r\n            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:\r\n                camLeft.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;\r\n                camRight.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;\r\n                break;\r\n        }\r\n        super._updateRigCameras();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _calculateLowerRadiusFromModelBoundingSphere(minimumWorld: Vector3, maximumWorld: Vector3, radiusScale: number = 1): number {\r\n        const boxVectorGlobalDiagonal = Vector3.Distance(minimumWorld, maximumWorld);\r\n\r\n        // Get aspect ratio in order to calculate frustum slope\r\n        const engine = this.getScene().getEngine();\r\n        const aspectRatio = engine.getAspectRatio(this);\r\n        const frustumSlopeY = Math.tan(this.fov / 2);\r\n        const frustumSlopeX = frustumSlopeY * aspectRatio;\r\n\r\n        // Formula for setting distance\r\n        // (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)\r\n        const radiusWithoutFraming = boxVectorGlobalDiagonal * 0.5;\r\n\r\n        // Horizon distance\r\n        const radius = radiusWithoutFraming * radiusScale;\r\n        const distanceForHorizontalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlopeX * frustumSlopeX));\r\n        const distanceForVerticalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlopeY * frustumSlopeY));\r\n        return Math.max(distanceForHorizontalFrustum, distanceForVerticalFrustum);\r\n    }\r\n\r\n    /**\r\n     * Destroy the camera and release the current resources hold by it.\r\n     */\r\n    public override dispose(): void {\r\n        this.inputs.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ArcRotateCamera\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for arcRotateCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterArcRotateCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"ArcRotateCamera\", (name, scene) => {\r\n        return () => new ArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), scene);\r\n    });\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.ArcRotateCamera\", ArcRotateCamera);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FreeCamera } from \"./freeCamera.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Axis } from \"../Maths/math.axis\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Node } from \"../node\";\r\n\r\n// We're mainly based on the logic defined into the FreeCamera code\r\n/**\r\n * This is a camera specifically designed to react to device orientation events such as a modern mobile device\r\n * being tilted forward or back and left or right.\r\n */\r\nexport class DeviceOrientationCamera extends FreeCamera {\r\n    private _initialQuaternion: Nullable<Quaternion>;\r\n    private _quaternionCache: Quaternion;\r\n    private _tmpDragQuaternion = new Quaternion();\r\n    private _disablePointerInputWhenUsingDeviceOrientation = true;\r\n\r\n    /**\r\n     * Creates a new device orientation camera\r\n     * @param name The name of the camera\r\n     * @param position The start position camera\r\n     * @param scene The scene the camera belongs to\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this._quaternionCache = new Quaternion();\r\n        this.inputs.addDeviceOrientation();\r\n\r\n        // When the orientation sensor fires it's first event, disable mouse input\r\n        if (this.inputs._deviceOrientationInput) {\r\n            this.inputs._deviceOrientationInput._onDeviceOrientationChangedObservable.addOnce(() => {\r\n                if (this._disablePointerInputWhenUsingDeviceOrientation) {\r\n                    if (this.inputs._mouseInput) {\r\n                        this.inputs._mouseInput._allowCameraRotation = false;\r\n                        this.inputs._mouseInput.onPointerMovedObservable.add((e) => {\r\n                            if (this._dragFactor != 0) {\r\n                                if (!this._initialQuaternion) {\r\n                                    this._initialQuaternion = new Quaternion();\r\n                                }\r\n                                // Rotate the initial space around the y axis to allow users to \"turn around\" via touch/mouse\r\n                                Quaternion.FromEulerAnglesToRef(0, e.offsetX * this._dragFactor, 0, this._tmpDragQuaternion);\r\n                                this._initialQuaternion.multiplyToRef(this._tmpDragQuaternion, this._initialQuaternion);\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)\r\n     */\r\n    public get disablePointerInputWhenUsingDeviceOrientation() {\r\n        return this._disablePointerInputWhenUsingDeviceOrientation;\r\n    }\r\n\r\n    public set disablePointerInputWhenUsingDeviceOrientation(value: boolean) {\r\n        this._disablePointerInputWhenUsingDeviceOrientation = value;\r\n    }\r\n\r\n    private _dragFactor = 0;\r\n    /**\r\n     * Enabled turning on the y axis when the orientation sensor is active\r\n     * @param dragFactor the factor that controls the turn speed (default: 1/300)\r\n     */\r\n    public enableHorizontalDragging(dragFactor = 1 / 300) {\r\n        this._dragFactor = dragFactor;\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance class name (\"DeviceOrientationCamera\").\r\n     * This helps avoiding instanceof at run time.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DeviceOrientationCamera\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Checks and applies the current values of the inputs to the camera. (Internal use only)\r\n     */\r\n    public override _checkInputs(): void {\r\n        super._checkInputs();\r\n        if (this.rotationQuaternion) {\r\n            this._quaternionCache.copyFrom(this.rotationQuaternion);\r\n            if (this._initialQuaternion) {\r\n                this._initialQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reset the camera to its default orientation on the specified axis only.\r\n     * @param axis The axis to reset\r\n     */\r\n    public resetToCurrentRotation(axis: Axis = Axis.Y): void {\r\n        //can only work if this camera has a rotation quaternion already.\r\n        if (!this.rotationQuaternion) {\r\n            return;\r\n        }\r\n\r\n        if (!this._initialQuaternion) {\r\n            this._initialQuaternion = new Quaternion();\r\n        }\r\n\r\n        this._initialQuaternion.copyFrom(this._quaternionCache || this.rotationQuaternion);\r\n        const list = [\"x\", \"y\", \"z\"];\r\n\r\n        for (const axisName of list) {\r\n            if (!(<any>axis)[axisName]) {\r\n                (<any>this._initialQuaternion)[axisName] = 0;\r\n            } else {\r\n                (<any>this._initialQuaternion)[axisName] *= -1;\r\n            }\r\n        }\r\n        this._initialQuaternion.normalize();\r\n        //force rotation update\r\n        this._initialQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for deviceOrientationCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDeviceOrientationCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"DeviceOrientationCamera\", (name, scene) => {\r\n        return () => new DeviceOrientationCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","import { type FlyCamera } from \"./flyCamera\";\r\nimport { CameraInputsManager } from \"./cameraInputsManager\";\r\nimport { FlyCameraMouseInput } from \"../Cameras/Inputs/flyCameraMouseInput\";\r\nimport { FlyCameraKeyboardInput } from \"../Cameras/Inputs/flyCameraKeyboardInput\";\r\n\r\n/**\r\n * Default Inputs manager for the FlyCamera.\r\n * It groups all the default supported inputs for ease of use.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FlyCameraInputsManager extends CameraInputsManager<FlyCamera> {\r\n    /**\r\n     * Instantiates a new FlyCameraInputsManager.\r\n     * @param camera Defines the camera the inputs belong to.\r\n     */\r\n    constructor(camera: FlyCamera) {\r\n        super(camera);\r\n    }\r\n\r\n    /**\r\n     * Add keyboard input support to the input manager.\r\n     * @returns the new FlyCameraKeyboardMoveInput().\r\n     */\r\n    addKeyboard(): FlyCameraInputsManager {\r\n        this.add(new FlyCameraKeyboardInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add mouse input support to the input manager.\r\n     * @returns the new FlyCameraMouseInput().\r\n     */\r\n    addMouse(): FlyCameraInputsManager {\r\n        this.add(new FlyCameraMouseInput());\r\n        return this;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsVector3 } from \"../Misc/decorators\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type Quaternion, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { TargetCamera } from \"./targetCamera.pure\";\r\nimport { type TargetCameraMovement } from \"./targetCameraMovement\";\r\nimport { FlyCameraInputsManager } from \"./flyCameraInputsManager\";\r\nimport { type FlyCameraMouseInput } from \"../Cameras/Inputs/flyCameraMouseInput\";\r\nimport { type FlyCameraKeyboardInput } from \"../Cameras/Inputs/flyCameraKeyboardInput\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\n\r\nimport { type Collider } from \"../Collisions/collider\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This is a flying camera, designed for 3D movement and rotation in all directions,\r\n * such as in a 3D Space Shooter or a Flight Simulator.\r\n */\r\nexport class FlyCamera extends TargetCamera {\r\n    /**\r\n     * Define the collision ellipsoid of the camera.\r\n     * This is helpful for simulating a camera body, like a player's body.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions#arcrotatecamera\r\n     */\r\n    @serializeAsVector3()\r\n    public ellipsoid = new Vector3(1, 1, 1);\r\n\r\n    /**\r\n     * Define an offset for the position of the ellipsoid around the camera.\r\n     * This can be helpful if the camera is attached away from the player's body center,\r\n     * such as at its head.\r\n     */\r\n    @serializeAsVector3()\r\n    public ellipsoidOffset = new Vector3(0, 0, 0);\r\n\r\n    /**\r\n     * Enable or disable collisions of the camera with the rest of the scene objects.\r\n     */\r\n    @serialize()\r\n    public checkCollisions = false;\r\n\r\n    /**\r\n     * Enable or disable gravity on the camera.\r\n     */\r\n    @serialize()\r\n    public applyGravity = false;\r\n\r\n    /**\r\n     * Define the current direction the camera is moving to.\r\n     */\r\n    public override cameraDirection = Vector3.Zero();\r\n\r\n    /**\r\n     * Define the current local rotation of the camera as a quaternion to prevent Gimbal lock.\r\n     * This overrides and empties cameraRotation.\r\n     */\r\n    public override rotationQuaternion: Nullable<Quaternion>;\r\n\r\n    /**\r\n     * Track Roll to maintain the wanted Rolling when looking around.\r\n     */\r\n    public _trackRoll: number = 0;\r\n\r\n    /**\r\n     * Slowly correct the Roll to its original value after a Pitch+Yaw rotation.\r\n     */\r\n    public rollCorrect: number = 100;\r\n\r\n    /**\r\n     * Mimic a banked turn, Rolling the camera when Yawing.\r\n     * It's recommended to use rollCorrect = 10 for faster banking correction.\r\n     */\r\n    public bankedTurn: boolean = false;\r\n\r\n    /**\r\n     * Limit in radians for how much Roll banking will add. (Default: 90°)\r\n     */\r\n    public bankedTurnLimit: number = Math.PI / 2;\r\n\r\n    /**\r\n     * Value of 0 disables the banked Roll.\r\n     * Value of 1 is equal to the Yaw angle in radians.\r\n     */\r\n    public bankedTurnMultiplier: number = 1;\r\n\r\n    /**\r\n     * The inputs manager loads all the input sources, such as keyboard and mouse.\r\n     */\r\n    public override inputs: FlyCameraInputsManager;\r\n\r\n    /**\r\n     * Framerate-independent movement controller for the fly camera, exposing the configurable\r\n     * {@link InputMapper} (`movement.input`) consulted by {@link FlyCameraMouseInput}. Narrows the\r\n     * inherited {@link TargetCamera.movement} to {@link TargetCameraMovement}; the instance is\r\n     * created by the {@link TargetCamera} constructor.\r\n     */\r\n    // `declare`, not `override`: the value is created by the base TargetCamera constructor. Under TC39\r\n    // decorators a plain field redeclaration is materialized as a constructor field-init that runs after\r\n    // super() and would clobber that value back to undefined; `declare` keeps this a type-only narrowing.\r\n    declare public movement: TargetCameraMovement;\r\n\r\n    /**\r\n     * Gets the input sensibility for mouse input.\r\n     * Higher values reduce sensitivity.\r\n     */\r\n    public get angularSensibility(): number {\r\n        const mouse = <FlyCameraMouseInput>this.inputs.attached[\"mouse\"];\r\n        if (mouse) {\r\n            return mouse.angularSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the input sensibility for a mouse input.\r\n     * Higher values reduce sensitivity.\r\n     */\r\n    public set angularSensibility(value: number) {\r\n        const mouse = <FlyCameraMouseInput>this.inputs.attached[\"mouse\"];\r\n        if (mouse) {\r\n            mouse.angularSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the keys for camera movement forward.\r\n     */\r\n    public get keysForward(): number[] {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysForward;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Set the keys for camera movement forward.\r\n     */\r\n    public set keysForward(value: number[]) {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysForward = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the keys for camera movement backward.\r\n     */\r\n    public get keysBackward(): number[] {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysBackward;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    public set keysBackward(value: number[]) {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysBackward = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the keys for camera movement up.\r\n     */\r\n    public get keysUp(): number[] {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysUp;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Set the keys for camera movement up.\r\n     */\r\n    public set keysUp(value: number[]) {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysUp = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the keys for camera movement down.\r\n     */\r\n    public get keysDown(): number[] {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysDown;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Set the keys for camera movement down.\r\n     */\r\n    public set keysDown(value: number[]) {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysDown = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the keys for camera movement left.\r\n     */\r\n    public get keysLeft(): number[] {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysLeft;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Set the keys for camera movement left.\r\n     */\r\n    public set keysLeft(value: number[]) {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysLeft = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the keys for camera movement right.\r\n     */\r\n    public get keysRight(): number[] {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            return keyboard.keysRight;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Set the keys for camera movement right.\r\n     */\r\n    public set keysRight(value: number[]) {\r\n        const keyboard = <FlyCameraKeyboardInput>this.inputs.attached[\"keyboard\"];\r\n        if (keyboard) {\r\n            keyboard.keysRight = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Event raised when the camera collides with a mesh in the scene.\r\n     */\r\n    public onCollide: (collidedMesh: AbstractMesh) => void;\r\n\r\n    private _collider: Collider;\r\n    private _needMoveForGravity = false;\r\n    private _oldPosition = Vector3.Zero();\r\n    private _diffPosition = Vector3.Zero();\r\n    private _newPosition = Vector3.Zero();\r\n\r\n    /** @internal */\r\n    public _localDirection: Vector3;\r\n    /** @internal */\r\n    public _transformedDirection: Vector3;\r\n\r\n    /**\r\n     * Instantiates a FlyCamera.\r\n     * This is a flying camera, designed for 3D movement and rotation in all directions,\r\n     * such as in a 3D Space Shooter or a Flight Simulator.\r\n     * @param name Define the name of the camera in the scene.\r\n     * @param position Define the starting position of the camera in the scene.\r\n     * @param scene Define the scene the camera belongs to.\r\n     * @param setActiveOnSceneIfNoneActive Defines whether the camera should be marked as active, if no other camera has been defined as active.\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive = true) {\r\n        super(name, position, scene, setActiveOnSceneIfNoneActive);\r\n        this.inputs = new FlyCameraInputsManager(this);\r\n        this.inputs.addKeyboard().addMouse();\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(noPreventDefault?: boolean): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(ignored: any, noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        this.inputs.attachElement(noPreventDefault);\r\n    }\r\n\r\n    /**\r\n     * Detach a control from the HTML DOM element.\r\n     * The camera will stop reacting to that input.\r\n     */\r\n    public override detachControl(): void {\r\n        this.inputs.detachElement();\r\n\r\n        this.cameraDirection = new Vector3(0, 0, 0);\r\n    }\r\n\r\n    // Collisions.\r\n    private _collisionMask = -1;\r\n\r\n    /**\r\n     * Get the mask that the camera ignores in collision events.\r\n     */\r\n    public get collisionMask(): number {\r\n        return this._collisionMask;\r\n    }\r\n\r\n    /**\r\n     * Set the mask that the camera ignores in collision events.\r\n     */\r\n    public set collisionMask(mask: number) {\r\n        this._collisionMask = !isNaN(mask) ? mask : -1;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _collideWithWorld(displacement: Vector3): void {\r\n        let globalPosition: Vector3;\r\n\r\n        if (this.parent) {\r\n            globalPosition = Vector3.TransformCoordinates(this.position, this.parent.getWorldMatrix());\r\n        } else {\r\n            globalPosition = this.position;\r\n        }\r\n\r\n        globalPosition.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPosition);\r\n        this._oldPosition.addInPlace(this.ellipsoidOffset);\r\n        const coordinator = this.getScene().collisionCoordinator;\r\n\r\n        if (!this._collider) {\r\n            this._collider = coordinator.createCollider();\r\n        }\r\n\r\n        this._collider._radius = this.ellipsoid;\r\n        this._collider.collisionMask = this._collisionMask;\r\n\r\n        // No need for clone, as long as gravity is not on.\r\n        let actualDisplacement = displacement;\r\n\r\n        // Add gravity to direction to prevent dual-collision checking.\r\n        if (this.applyGravity) {\r\n            // This prevents mending with cameraDirection, a global variable of the fly camera class.\r\n            actualDisplacement = displacement.add(this.getScene().gravity);\r\n        }\r\n\r\n        coordinator.getNewPosition(this._oldPosition, actualDisplacement, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    private _onCollisionPositionChange = (collisionId: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh> = null) => {\r\n        const updatePosition = (newPos: Vector3) => {\r\n            this._newPosition.copyFrom(newPos);\r\n\r\n            this._newPosition.subtractToRef(this._oldPosition, this._diffPosition);\r\n\r\n            if (this._diffPosition.length() > AbstractEngine.CollisionsEpsilon) {\r\n                this.position.addInPlace(this._diffPosition);\r\n                if (this.onCollide && collidedMesh) {\r\n                    this.onCollide(collidedMesh);\r\n                }\r\n            }\r\n        };\r\n\r\n        updatePosition(newPosition);\r\n    };\r\n\r\n    /** @internal */\r\n    public override _checkInputs(): void {\r\n        if (!this._localDirection) {\r\n            this._localDirection = Vector3.Zero();\r\n            this._transformedDirection = Vector3.Zero();\r\n        }\r\n\r\n        this.inputs.checkInputs();\r\n\r\n        super._checkInputs();\r\n    }\r\n\r\n    /**\r\n     * Enable movement without a user input. This allows gravity to always be applied.\r\n     */\r\n    public set needMoveForGravity(value: boolean) {\r\n        this._needMoveForGravity = value;\r\n    }\r\n\r\n    /**\r\n     * When true, gravity is applied whether there is user input or not.\r\n     */\r\n    public get needMoveForGravity(): boolean {\r\n        return this._needMoveForGravity;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _decideIfNeedsToMove(): boolean {\r\n        return this._needMoveForGravity || Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _updatePosition(): void {\r\n        if (this.checkCollisions && this.getScene().collisionsEnabled) {\r\n            this._collideWithWorld(this.cameraDirection);\r\n        } else {\r\n            super._updatePosition();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Restore the Roll to its target value at the rate specified.\r\n     * @param rate - Higher means slower restoring.\r\n     * @internal\r\n     */\r\n    public restoreRoll(rate: number): void {\r\n        const limit = this._trackRoll; // Target Roll.\r\n        const z = this.rotation.z; // Current Roll.\r\n        const delta = limit - z; // Difference in Roll.\r\n\r\n        const minRad = 0.001; // Tenth of a radian is a barely noticable difference.\r\n\r\n        // If the difference is noticable, restore the Roll.\r\n        if (Math.abs(delta) >= minRad) {\r\n            // Change Z rotation towards the target Roll.\r\n            this.rotation.z += delta / rate;\r\n\r\n            // Match when near enough.\r\n            if (Math.abs(limit - this.rotation.z) <= minRad) {\r\n                this.rotation.z = limit;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Destroy the camera and release the current resources held by it.\r\n     */\r\n    public override dispose(): void {\r\n        this.inputs.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Get the current object class name.\r\n     * @returns the class name.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FlyCamera\";\r\n    }\r\n}\r\n\r\n// Register Class Name\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flyCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlyCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FlyCamera\", FlyCamera);\r\n}\r\n","import { Logger } from \"core/Misc/logger\";\r\nimport { CameraInputsManager } from \"./cameraInputsManager\";\r\nimport { type FollowCamera } from \"./followCamera\";\r\nimport { FollowCameraKeyboardMoveInput } from \"./Inputs/followCameraKeyboardMoveInput\";\r\nimport { FollowCameraMouseWheelInput } from \"./Inputs/followCameraMouseWheelInput\";\r\nimport { FollowCameraPointersInput } from \"./Inputs/followCameraPointersInput\";\r\n\r\n/**\r\n * Default Inputs manager for the FollowCamera.\r\n * It groups all the default supported inputs for ease of use.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FollowCameraInputsManager extends CameraInputsManager<FollowCamera> {\r\n    /**\r\n     * Instantiates a new FollowCameraInputsManager.\r\n     * @param camera Defines the camera the inputs belong to\r\n     */\r\n    constructor(camera: FollowCamera) {\r\n        super(camera);\r\n    }\r\n\r\n    /**\r\n     * Add keyboard input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addKeyboard(): FollowCameraInputsManager {\r\n        this.add(new FollowCameraKeyboardMoveInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add mouse wheel input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addMouseWheel(): FollowCameraInputsManager {\r\n        this.add(new FollowCameraMouseWheelInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add pointers input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addPointers(): FollowCameraInputsManager {\r\n        this.add(new FollowCameraPointersInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add orientation input support to the input manager.\r\n     * @returns the current input manager\r\n     */\r\n    public addVRDeviceOrientation(): FollowCameraInputsManager {\r\n        Logger.Warn(\"DeviceOrientation support not yet implemented for FollowCamera.\");\r\n        return this;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { serialize, serializeAsMeshReference } from \"../Misc/decorators\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { TargetCamera } from \"./targetCamera.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { FollowCameraInputsManager } from \"./followCameraInputsManager\";\r\nimport { Node } from \"../node\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * A follow camera takes a mesh as a target and follows it as it moves. Both a free camera version followCamera and\r\n * an arc rotate version arcFollowCamera are available.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera\r\n */\r\nexport class FollowCamera extends TargetCamera {\r\n    /**\r\n     * Distance the follow camera should follow an object at\r\n     */\r\n    @serialize()\r\n    public radius: number = 12;\r\n\r\n    /**\r\n     * Minimum allowed distance of the camera to the axis of rotation\r\n     * (The camera can not get closer).\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public lowerRadiusLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Maximum allowed distance of the camera to the axis of rotation\r\n     * (The camera can not get further).\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public upperRadiusLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Define a rotation offset between the camera and the object it follows\r\n     */\r\n    @serialize()\r\n    public rotationOffset: number = 0;\r\n\r\n    /**\r\n     * Minimum allowed angle to camera position relative to target object.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public lowerRotationOffsetLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Maximum allowed angle to camera position relative to target object.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public upperRotationOffsetLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Define a height offset between the camera and the object it follows.\r\n     * It can help following an object from the top (like a car chasing a plane)\r\n     */\r\n    @serialize()\r\n    public heightOffset: number = 4;\r\n\r\n    /**\r\n     * Minimum allowed height of camera position relative to target object.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public lowerHeightOffsetLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Maximum allowed height of camera position relative to target object.\r\n     * This can help limiting how the Camera is able to move in the scene.\r\n     */\r\n    @serialize()\r\n    public upperHeightOffsetLimit: Nullable<number> = null;\r\n\r\n    /**\r\n     * Define how fast the camera can accelerate to follow it s target.\r\n     */\r\n    @serialize()\r\n    public cameraAcceleration: number = 0.05;\r\n\r\n    /**\r\n     * Define the speed limit of the camera following an object.\r\n     */\r\n    @serialize()\r\n    public maxCameraSpeed: number = 20;\r\n\r\n    /**\r\n     * Define the target of the camera.\r\n     */\r\n    @serializeAsMeshReference(\"lockedTargetId\")\r\n    public override lockedTarget: Nullable<AbstractMesh> = null;\r\n\r\n    /**\r\n     * Defines the input associated with the camera.\r\n     */\r\n    declare public inputs: FollowCameraInputsManager;\r\n\r\n    /**\r\n     * Instantiates the follow camera.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera\r\n     * @param name Define the name of the camera in the scene\r\n     * @param position Define the position of the camera\r\n     * @param scene Define the scene the camera belong to\r\n     * @param lockedTarget Define the target of the camera\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, lockedTarget: Nullable<AbstractMesh> = null) {\r\n        super(name, position, scene);\r\n\r\n        this.lockedTarget = lockedTarget;\r\n        this.inputs = new FollowCameraInputsManager(this);\r\n        this.inputs.addKeyboard().addMouseWheel().addPointers();\r\n        // Uncomment the following line when the relevant handlers have been implemented.\r\n        // this.inputs.addKeyboard().addMouseWheel().addPointers().addVRDeviceOrientation();\r\n    }\r\n\r\n    private _follow(cameraTarget: AbstractMesh) {\r\n        if (!cameraTarget) {\r\n            return;\r\n        }\r\n\r\n        const rotMatrix = TmpVectors.Matrix[0];\r\n        cameraTarget.absoluteRotationQuaternion.toRotationMatrix(rotMatrix);\r\n        const yRotation = Math.atan2(rotMatrix.m[8], rotMatrix.m[10]);\r\n\r\n        const radians = this.rotationOffset * (Math.PI / 180) + yRotation;\r\n        const targetPosition = cameraTarget.getAbsolutePosition();\r\n        const targetX: number = targetPosition.x + Math.sin(radians) * this.radius;\r\n\r\n        const targetZ: number = targetPosition.z + Math.cos(radians) * this.radius;\r\n        const dx: number = targetX - this.position.x;\r\n        const dy: number = targetPosition.y + this.heightOffset - this.position.y;\r\n        const dz: number = targetZ - this.position.z;\r\n        let vx: number = dx * this.cameraAcceleration * 2; //this is set to .05\r\n        let vy: number = dy * this.cameraAcceleration;\r\n        let vz: number = dz * this.cameraAcceleration * 2;\r\n\r\n        if (vx > this.maxCameraSpeed || vx < -this.maxCameraSpeed) {\r\n            vx = vx < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;\r\n        }\r\n\r\n        if (vy > this.maxCameraSpeed || vy < -this.maxCameraSpeed) {\r\n            vy = vy < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;\r\n        }\r\n\r\n        if (vz > this.maxCameraSpeed || vz < -this.maxCameraSpeed) {\r\n            vz = vz < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;\r\n        }\r\n\r\n        this.position.addInPlaceFromFloats(vx, vy, vz);\r\n        this.setTarget(targetPosition);\r\n    }\r\n\r\n    /**\r\n     * Attach the input controls to a specific dom element to get the input from.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(noPreventDefault?: boolean): void;\r\n    /**\r\n     * Attached controls to the current camera.\r\n     * @param ignored defines an ignored parameter kept for backward compatibility.\r\n     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n     */\r\n    public override attachControl(ignored: any, noPreventDefault?: boolean): void {\r\n        noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n        this.inputs.attachElement(noPreventDefault);\r\n\r\n        this._reset = () => {};\r\n    }\r\n\r\n    /**\r\n     * Detach the current controls from the specified dom element.\r\n     */\r\n    public override detachControl(): void {\r\n        this.inputs.detachElement();\r\n\r\n        if (this._reset) {\r\n            this._reset();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _checkInputs(): void {\r\n        this.inputs.checkInputs();\r\n        this._checkLimits();\r\n        super._checkInputs();\r\n        if (this.lockedTarget) {\r\n            this._follow(this.lockedTarget);\r\n        }\r\n    }\r\n\r\n    private _checkLimits() {\r\n        if (this.lowerRadiusLimit !== null && this.radius < this.lowerRadiusLimit) {\r\n            this.radius = this.lowerRadiusLimit;\r\n        }\r\n        if (this.upperRadiusLimit !== null && this.radius > this.upperRadiusLimit) {\r\n            this.radius = this.upperRadiusLimit;\r\n        }\r\n\r\n        if (this.lowerHeightOffsetLimit !== null && this.heightOffset < this.lowerHeightOffsetLimit) {\r\n            this.heightOffset = this.lowerHeightOffsetLimit;\r\n        }\r\n        if (this.upperHeightOffsetLimit !== null && this.heightOffset > this.upperHeightOffsetLimit) {\r\n            this.heightOffset = this.upperHeightOffsetLimit;\r\n        }\r\n\r\n        if (this.lowerRotationOffsetLimit !== null && this.rotationOffset < this.lowerRotationOffsetLimit) {\r\n            this.rotationOffset = this.lowerRotationOffsetLimit;\r\n        }\r\n        if (this.upperRotationOffsetLimit !== null && this.rotationOffset > this.upperRotationOffsetLimit) {\r\n            this.rotationOffset = this.upperRotationOffsetLimit;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the camera class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FollowCamera\";\r\n    }\r\n}\r\n\r\n/**\r\n * Arc Rotate version of the follow camera.\r\n * It still follows a Defined mesh but in an Arc Rotate Camera fashion.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera\r\n */\r\nexport class ArcFollowCamera extends TargetCamera {\r\n    private _cartesianCoordinates: Vector3 = Vector3.Zero();\r\n\r\n    /** Define the camera target (the mesh it should follow) */\r\n    private _meshTarget: Nullable<AbstractMesh>;\r\n\r\n    /**\r\n     * Instantiates a new ArcFollowCamera\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera\r\n     * @param name Define the name of the camera\r\n     * @param alpha Define the rotation angle of the camera around the longitudinal axis\r\n     * @param beta Define the rotation angle of the camera around the elevation axis\r\n     * @param radius Define the radius of the camera from its target point\r\n     * @param target Define the target of the camera\r\n     * @param scene Define the scene the camera belongs to\r\n     */\r\n    constructor(\r\n        name: string,\r\n        /** The longitudinal angle of the camera */\r\n        public alpha: number,\r\n        /** The latitudinal angle of the camera */\r\n        public beta: number,\r\n        /** The radius of the camera from its target */\r\n        public radius: number,\r\n        /** Define the camera target (the mesh it should follow) */\r\n        target: Nullable<AbstractMesh>,\r\n        scene: Scene\r\n    ) {\r\n        super(name, Vector3.Zero(), scene);\r\n        this.setMeshTarget(target);\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh to follow with this camera.\r\n     * @param target the target to follow\r\n     */\r\n    public setMeshTarget(target: Nullable<AbstractMesh>) {\r\n        this._meshTarget = target;\r\n        this._follow();\r\n    }\r\n\r\n    private _follow(): void {\r\n        if (!this._meshTarget) {\r\n            return;\r\n        }\r\n        this._cartesianCoordinates.x = this.radius * Math.cos(this.alpha) * Math.cos(this.beta);\r\n        this._cartesianCoordinates.y = this.radius * Math.sin(this.beta);\r\n        this._cartesianCoordinates.z = this.radius * Math.sin(this.alpha) * Math.cos(this.beta);\r\n\r\n        const targetPosition = this._meshTarget.getAbsolutePosition();\r\n        this.position = targetPosition.add(this._cartesianCoordinates);\r\n        this.setTarget(targetPosition);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _checkInputs(): void {\r\n        super._checkInputs();\r\n        this._follow();\r\n    }\r\n\r\n    /**\r\n     * Returns the class name of the object.\r\n     * It is mostly used internally for serialization purposes.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ArcFollowCamera\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for followCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFollowCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"FollowCamera\", (name, scene) => {\r\n        return () => new FollowCamera(name, Vector3.Zero(), scene);\r\n    });\r\n\r\n    Node.AddNodeConstructor(\"ArcFollowCamera\", (name, scene) => {\r\n        return () => new ArcFollowCamera(name, 0, 0, 1.0, null, scene);\r\n    });\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.FollowCamera\", FollowCamera);\r\n\r\n    RegisterClass(\"BABYLON.ArcFollowCamera\", ArcFollowCamera);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { TouchCamera } from \"./touchCamera.pure\";\r\nimport { type FreeCameraGamepadInput } from \"../Cameras/Inputs/freeCameraGamepadInput\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Node } from \"../node\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Camera } from \"./camera.pure\";\r\n\r\n/**\r\n * The Universal Camera is the one to choose for first person shooter type games, and works with all the keyboard, mouse, touch and gamepads. This replaces the earlier Free Camera,\r\n * which still works and will still be found in many Playgrounds.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n */\r\nexport class UniversalCamera extends TouchCamera {\r\n    /**\r\n     * Defines the gamepad rotation sensibility.\r\n     * This is the threshold from when rotation starts to be accounted for to prevent jittering.\r\n     */\r\n    public get gamepadAngularSensibility(): number {\r\n        const gamepad = <FreeCameraGamepadInput>this.inputs.attached[\"gamepad\"];\r\n        if (gamepad) {\r\n            return gamepad.gamepadAngularSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set gamepadAngularSensibility(value: number) {\r\n        const gamepad = <FreeCameraGamepadInput>this.inputs.attached[\"gamepad\"];\r\n        if (gamepad) {\r\n            gamepad.gamepadAngularSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the gamepad move sensibility.\r\n     * This is the threshold from when moving starts to be accounted for to prevent jittering.\r\n     */\r\n    public get gamepadMoveSensibility(): number {\r\n        const gamepad = <FreeCameraGamepadInput>this.inputs.attached[\"gamepad\"];\r\n        if (gamepad) {\r\n            return gamepad.gamepadMoveSensibility;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set gamepadMoveSensibility(value: number) {\r\n        const gamepad = <FreeCameraGamepadInput>this.inputs.attached[\"gamepad\"];\r\n        if (gamepad) {\r\n            gamepad.gamepadMoveSensibility = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The Universal Camera is the one to choose for first person shooter type games, and works with all the keyboard, mouse, touch and gamepads. This replaces the earlier Free Camera,\r\n     * which still works and will still be found in many Playgrounds.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n     * @param name Define the name of the camera in the scene\r\n     * @param position Define the start position of the camera in the scene\r\n     * @param scene Define the scene the camera belongs to\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.inputs.addGamepad();\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"UniversalCamera\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for universalCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUniversalCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"FreeCamera\", (name, scene) => {\r\n        // Forcing to use the Universal camera\r\n        return () => new UniversalCamera(name, Vector3.Zero(), scene);\r\n    });\r\n\r\n    Camera._CreateDefaultParsedCamera = (name: string, scene: Scene) => {\r\n        return new UniversalCamera(name, Vector3.Zero(), scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { UniversalCamera } from \"./universalCamera.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Node } from \"../node\";\r\n\r\n/**\r\n * This represents a FPS type of camera. This is only here for back compat purpose.\r\n * Please use the UniversalCamera instead as both are identical.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n */\r\nexport class GamepadCamera extends UniversalCamera {\r\n    /**\r\n     * Instantiates a new Gamepad Camera\r\n     * This represents a FPS type of camera. This is only here for back compat purpose.\r\n     * Please use the UniversalCamera instead as both are identical.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#universal-camera\r\n     * @param name Define the name of the camera in the scene\r\n     * @param position Define the start position of the camera in the scene\r\n     * @param scene Define the scene the camera belongs to\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene) {\r\n        super(name, position, scene);\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GamepadCamera\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gamepadCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGamepadCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"GamepadCamera\", (name, scene) => {\r\n        return () => new GamepadCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Postprocess used to generate anaglyphic rendering\r\n */\r\nexport class ThinAnaglyphPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"anaglyph\";\r\n\r\n    /**\r\n     * The list of samplers used by the effect\r\n     */\r\n    public static readonly Samplers = [\"leftSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/anaglyph.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/anaglyph.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new anaglyph post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinAnaglyphPostProcess.FragmentUrl,\r\n            samplers: ThinAnaglyphPostProcess.Samplers,\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { ThinAnaglyphPostProcess } from \"./thinAnaglyphPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Postprocess used to generate anaglyphic rendering\r\n */\r\nexport class AnaglyphPostProcess extends PostProcess {\r\n    private _passedProcess: Nullable<PostProcess>;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"AnaglyphPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"AnaglyphPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Creates a new AnaglyphPostProcess\r\n     * @param name defines postprocess name\r\n     * @param options defines creation options or target ratio scale\r\n     * @param rigCameras defines cameras using this postprocess\r\n     * @param samplingMode defines required sampling mode (BABYLON.Texture.NEAREST_SAMPLINGMODE by default)\r\n     * @param engine defines hosting engine\r\n     * @param reusable defines if the postprocess will be reused multiple times per frame\r\n     */\r\n    constructor(name: string, options: number | PostProcessOptions, rigCameras: Camera[], samplingMode?: number, engine?: AbstractEngine, reusable?: boolean) {\r\n        const localOptions = {\r\n            samplers: ThinAnaglyphPostProcess.Samplers,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera: rigCameras[1],\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinAnaglyphPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinAnaglyphPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this._passedProcess = rigCameras[0]._rigPostProcess;\r\n\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setTextureFromPostProcess(\"leftSampler\", this._passedProcess);\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anaglyphPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnaglyphPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AnaglyphPostProcess\", AnaglyphPostProcess);\r\n}\r\n","import { type Camera } from \"../camera\";\r\nimport { PassPostProcess } from \"../../PostProcesses/passPostProcess.pure\";\r\nimport { AnaglyphPostProcess } from \"../../PostProcesses/anaglyphPostProcess.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _SetStereoscopicAnaglyphRigMode(camera: Camera) {\r\n    camera._rigCameras[0]._rigPostProcess = new PassPostProcess(camera.name + \"_passthru\", 1.0, camera._rigCameras[0]);\r\n    camera._rigCameras[1]._rigPostProcess = new AnaglyphPostProcess(camera.name + \"_anaglyph\", 1.0, camera._rigCameras);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { ArcRotateCamera } from \"../../Cameras/arcRotateCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicAnaglyphRigMode } from \"../RigModes/stereoscopicAnaglyphRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate anaglyphic rendering (based on ArcRotateCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#anaglyph-cameras\r\n */\r\nexport class AnaglyphArcRotateCamera extends ArcRotateCamera {\r\n    /**\r\n     * Creates a new AnaglyphArcRotateCamera\r\n     * @param name defines camera name\r\n     * @param alpha defines alpha angle (in radians)\r\n     * @param beta defines beta angle (in radians)\r\n     * @param radius defines radius\r\n     * @param target defines camera target\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, interaxialDistance: number, scene?: Scene) {\r\n        super(name, alpha, beta, radius, target, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns AnaglyphArcRotateCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"AnaglyphArcRotateCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicAnaglyphRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anaglyphArcRotateCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnaglyphArcRotateCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"AnaglyphArcRotateCamera\", (name, scene, options) => {\r\n        return () => new AnaglyphArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), options.interaxial_distance, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { FreeCamera } from \"../../Cameras/freeCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicAnaglyphRigMode } from \"../RigModes/stereoscopicAnaglyphRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate anaglyphic rendering (based on FreeCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#anaglyph-cameras\r\n */\r\nexport class AnaglyphFreeCamera extends FreeCamera {\r\n    /**\r\n     * Creates a new AnaglyphFreeCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, position: Vector3, interaxialDistance: number, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns AnaglyphFreeCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"AnaglyphFreeCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicAnaglyphRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anaglyphFreeCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnaglyphFreeCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"AnaglyphFreeCamera\", (name, scene, options) => {\r\n        return () => new AnaglyphFreeCamera(name, Vector3.Zero(), options.interaxial_distance, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { GamepadCamera } from \"../../Cameras/gamepadCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicAnaglyphRigMode } from \"../RigModes/stereoscopicAnaglyphRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate anaglyphic rendering (based on GamepadCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#anaglyph-cameras\r\n */\r\nexport class AnaglyphGamepadCamera extends GamepadCamera {\r\n    /**\r\n     * Creates a new AnaglyphGamepadCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, position: Vector3, interaxialDistance: number, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns AnaglyphGamepadCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"AnaglyphGamepadCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicAnaglyphRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anaglyphGamepadCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnaglyphGamepadCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"AnaglyphGamepadCamera\", (name, scene, options) => {\r\n        return () => new AnaglyphGamepadCamera(name, Vector3.Zero(), options.interaxial_distance, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { UniversalCamera } from \"../../Cameras/universalCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicAnaglyphRigMode } from \"../RigModes/stereoscopicAnaglyphRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate anaglyphic rendering (based on UniversalCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#anaglyph-cameras\r\n */\r\nexport class AnaglyphUniversalCamera extends UniversalCamera {\r\n    /**\r\n     * Creates a new AnaglyphUniversalCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, position: Vector3, interaxialDistance: number, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns AnaglyphUniversalCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"AnaglyphUniversalCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicAnaglyphRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anaglyphUniversalCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnaglyphUniversalCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"AnaglyphUniversalCamera\", (name, scene, options) => {\r\n        return () => new AnaglyphUniversalCamera(name, Vector3.Zero(), options.interaxial_distance, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n\r\n/**\r\n * StereoscopicInterlacePostProcessI used to render stereo views from a rigged camera with support for alternate line interlacing\r\n */\r\nexport class StereoscopicInterlacePostProcessI extends PostProcess {\r\n    private _stepSize: Vector2;\r\n    private _passedProcess: Nullable<PostProcess>;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"StereoscopicInterlacePostProcessI\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicInterlacePostProcessI\";\r\n    }\r\n\r\n    /**\r\n     * Initializes a StereoscopicInterlacePostProcessI\r\n     * @param name The name of the effect.\r\n     * @param rigCameras The rig cameras to be applied to the post process\r\n     * @param isStereoscopicHoriz If the rendered results are horizontal or vertical\r\n     * @param isStereoscopicInterlaced If the rendered results are alternate line interlaced\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        rigCameras: Camera[],\r\n        isStereoscopicHoriz: boolean,\r\n        isStereoscopicInterlaced: boolean,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean\r\n    ) {\r\n        super(\r\n            name,\r\n            \"stereoscopicInterlace\",\r\n            [\"stepSize\"],\r\n            [\"camASampler\"],\r\n            1,\r\n            rigCameras[1],\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            isStereoscopicInterlaced ? \"#define IS_STEREOSCOPIC_INTERLACED 1\" : isStereoscopicHoriz ? \"#define IS_STEREOSCOPIC_HORIZ 1\" : undefined\r\n        );\r\n\r\n        this._passedProcess = rigCameras[0]._rigPostProcess;\r\n        this._stepSize = new Vector2(1 / this.width, 1 / this.height);\r\n\r\n        this.onSizeChangedObservable.add(() => {\r\n            this._stepSize = new Vector2(1 / this.width, 1 / this.height);\r\n        });\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setTextureFromPostProcess(\"camASampler\", this._passedProcess);\r\n            effect.setFloat2(\"stepSize\", this._stepSize.x, this._stepSize.y);\r\n        });\r\n    }\r\n}\r\n/**\r\n * StereoscopicInterlacePostProcess used to render stereo views from a rigged camera\r\n */\r\nexport class StereoscopicInterlacePostProcess extends PostProcess {\r\n    private _stepSize: Vector2;\r\n    private _passedProcess: Nullable<PostProcess>;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"StereoscopicInterlacePostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicInterlacePostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Initializes a StereoscopicInterlacePostProcess\r\n     * @param name The name of the effect.\r\n     * @param rigCameras The rig cameras to be applied to the post process\r\n     * @param isStereoscopicHoriz If the rendered results are horizontal or vertical\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(name: string, rigCameras: Camera[], isStereoscopicHoriz: boolean, samplingMode?: number, engine?: AbstractEngine, reusable?: boolean) {\r\n        super(\r\n            name,\r\n            \"stereoscopicInterlace\",\r\n            [\"stepSize\"],\r\n            [\"camASampler\"],\r\n            1,\r\n            rigCameras[1],\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            isStereoscopicHoriz ? \"#define IS_STEREOSCOPIC_HORIZ 1\" : undefined\r\n        );\r\n\r\n        this._passedProcess = rigCameras[0]._rigPostProcess;\r\n        this._stepSize = new Vector2(1 / this.width, 1 / this.height);\r\n\r\n        this.onSizeChangedObservable.add(() => {\r\n            this._stepSize = new Vector2(1 / this.width, 1 / this.height);\r\n        });\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setTextureFromPostProcess(\"camASampler\", this._passedProcess);\r\n            effect.setFloat2(\"stepSize\", this._stepSize.x, this._stepSize.y);\r\n        });\r\n    }\r\n}\r\n","import { Camera } from \"../camera.pure\";\r\nimport { Viewport } from \"../../Maths/math.viewport\";\r\nimport { PassPostProcess } from \"../../PostProcesses/passPostProcess.pure\";\r\nimport { StereoscopicInterlacePostProcessI } from \"../../PostProcesses/stereoscopicInterlacePostProcess.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _SetStereoscopicRigMode(camera: Camera): void {\r\n    const isStereoscopicHoriz =\r\n        camera.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || camera.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;\r\n    const isCrossEye = camera.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;\r\n    const isInterlaced = camera.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_INTERLACED;\r\n    // Use post-processors for interlacing\r\n    if (isInterlaced) {\r\n        camera._rigCameras[0]._rigPostProcess = new PassPostProcess(camera.name + \"_passthru\", 1.0, camera._rigCameras[0]);\r\n        camera._rigCameras[1]._rigPostProcess = new StereoscopicInterlacePostProcessI(camera.name + \"_stereoInterlace\", camera._rigCameras, false, true);\r\n    }\r\n    // Otherwise, create appropriate viewports\r\n    else {\r\n        camera._rigCameras[isCrossEye ? 1 : 0].viewport = new Viewport(0, 0, isStereoscopicHoriz ? 0.5 : 1.0, isStereoscopicHoriz ? 1.0 : 0.5);\r\n        camera._rigCameras[isCrossEye ? 0 : 1].viewport = new Viewport(\r\n            isStereoscopicHoriz ? 0.5 : 0,\r\n            isStereoscopicHoriz ? 0 : 0.5,\r\n            isStereoscopicHoriz ? 0.5 : 1.0,\r\n            isStereoscopicHoriz ? 1.0 : 0.5\r\n        );\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { ArcRotateCamera } from \"../../Cameras/arcRotateCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicRigMode } from \"../RigModes/stereoscopicRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate stereoscopic rendering (based on ArcRotateCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n */\r\nexport class StereoscopicArcRotateCamera extends ArcRotateCamera {\r\n    /**\r\n     * Creates a new StereoscopicArcRotateCamera\r\n     * @param name defines camera name\r\n     * @param alpha defines alpha angle (in radians)\r\n     * @param beta defines beta angle (in radians)\r\n     * @param radius defines radius\r\n     * @param target defines camera target\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, alpha: number, beta: number, radius: number, target: Vector3, interaxialDistance: number, isStereoscopicSideBySide: boolean, scene?: Scene) {\r\n        super(name, alpha, beta, radius, target, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.isStereoscopicSideBySide = isStereoscopicSideBySide;\r\n        this.setCameraRigMode(isStereoscopicSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, {\r\n            interaxialDistance: interaxialDistance,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns StereoscopicArcRotateCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicArcRotateCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for stereoscopicArcRotateCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStereoscopicArcRotateCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"StereoscopicArcRotateCamera\", (name, scene, options) => {\r\n        return () => new StereoscopicArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { FreeCamera } from \"../../Cameras/freeCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicRigMode } from \"../RigModes/stereoscopicRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate stereoscopic rendering (based on FreeCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n */\r\nexport class StereoscopicFreeCamera extends FreeCamera {\r\n    /**\r\n     * Creates a new StereoscopicFreeCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, position: Vector3, interaxialDistance: number, isStereoscopicSideBySide: boolean, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.isStereoscopicSideBySide = isStereoscopicSideBySide;\r\n        this.setCameraRigMode(isStereoscopicSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, {\r\n            interaxialDistance: interaxialDistance,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns StereoscopicFreeCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicFreeCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for stereoscopicFreeCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStereoscopicFreeCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"StereoscopicFreeCamera\", (name, scene, options) => {\r\n        return () => new StereoscopicFreeCamera(name, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { GamepadCamera } from \"../../Cameras/gamepadCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicRigMode } from \"../RigModes/stereoscopicRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate stereoscopic rendering (based on GamepadCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n */\r\nexport class StereoscopicGamepadCamera extends GamepadCamera {\r\n    /**\r\n     * Creates a new StereoscopicGamepadCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, position: Vector3, interaxialDistance: number, isStereoscopicSideBySide: boolean, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.isStereoscopicSideBySide = isStereoscopicSideBySide;\r\n        this.setCameraRigMode(isStereoscopicSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, {\r\n            interaxialDistance: interaxialDistance,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns StereoscopicGamepadCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicGamepadCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for stereoscopicGamepadCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStereoscopicGamepadCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"StereoscopicGamepadCamera\", (name, scene, options) => {\r\n        return () => new StereoscopicGamepadCamera(name, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { UniversalCamera } from \"../../Cameras/universalCamera.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetStereoscopicRigMode } from \"../RigModes/stereoscopicRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate stereoscopic rendering (based on UniversalCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n */\r\nexport class StereoscopicUniversalCamera extends UniversalCamera {\r\n    /**\r\n     * Creates a new StereoscopicUniversalCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param interaxialDistance defines distance between each color axis\r\n     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under\r\n     * @param scene defines the hosting scene\r\n     */\r\n    constructor(name: string, position: Vector3, interaxialDistance: number, isStereoscopicSideBySide: boolean, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.interaxialDistance = interaxialDistance;\r\n        this.isStereoscopicSideBySide = isStereoscopicSideBySide;\r\n        this.setCameraRigMode(isStereoscopicSideBySide ? Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER, {\r\n            interaxialDistance: interaxialDistance,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns StereoscopicUniversalCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicUniversalCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = () => _SetStereoscopicRigMode(this);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for stereoscopicUniversalCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStereoscopicUniversalCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"StereoscopicUniversalCamera\", (name, scene, options) => {\r\n        return () => new StereoscopicUniversalCamera(name, Vector3.Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene);\r\n    });\r\n}\r\n","import { Camera } from \"../../Cameras/camera.pure\";\r\nimport { UniversalCamera } from \"../../Cameras/universalCamera.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { TargetCamera } from \"../targetCamera.pure\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Viewport } from \"../../Maths/math.viewport\";\r\n\r\n/**\r\n * Camera used to simulate stereoscopic rendering on real screens (based on UniversalCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras\r\n */\r\nexport class StereoscopicScreenUniversalCamera extends UniversalCamera {\r\n    private _distanceToProjectionPlane: number;\r\n    private _distanceBetweenEyes: number;\r\n\r\n    public set distanceBetweenEyes(newValue: number) {\r\n        this._distanceBetweenEyes = newValue;\r\n    }\r\n\r\n    /**\r\n     * distance between the eyes\r\n     */\r\n    public get distanceBetweenEyes(): number {\r\n        return this._distanceBetweenEyes;\r\n    }\r\n\r\n    public set distanceToProjectionPlane(newValue: number) {\r\n        this._distanceToProjectionPlane = newValue;\r\n    }\r\n\r\n    /**\r\n     * Distance to projection plane (should be the same units the like distance between the eyes)\r\n     */\r\n    public get distanceToProjectionPlane(): number {\r\n        return this._distanceToProjectionPlane;\r\n    }\r\n    /**\r\n     * Creates a new StereoscopicScreenUniversalCamera\r\n     * @param name defines camera name\r\n     * @param position defines initial position\r\n     * @param scene defines the hosting scene\r\n     * @param distanceToProjectionPlane defines distance between each color axis. The rig cameras will receive this as their negative z position!\r\n     * @param distanceBetweenEyes defines is stereoscopic is done side by side or over under\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, distanceToProjectionPlane: number = 1, distanceBetweenEyes: number = 0.065) {\r\n        super(name, position, scene);\r\n        this._distanceBetweenEyes = distanceBetweenEyes;\r\n        this._distanceToProjectionPlane = distanceToProjectionPlane;\r\n        this.setCameraRigMode(Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL, {\r\n            stereoHalfAngle: 0,\r\n        });\r\n        this._cameraRigParams.stereoHalfAngle = 0;\r\n        this._cameraRigParams.interaxialDistance = distanceBetweenEyes;\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns StereoscopicScreenUniversalCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StereoscopicScreenUniversalCamera\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override createRigCamera(name: string): Nullable<Camera> {\r\n        const camera = new TargetCamera(name, Vector3.Zero(), this.getScene());\r\n        const transform = new TransformNode(\"tm_\" + name, this.getScene());\r\n        camera.parent = transform;\r\n        transform.setPivotMatrix(Matrix.Identity(), false);\r\n        camera.isRigCamera = true;\r\n        camera.rigParent = this;\r\n        return camera;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateRigCameras() {\r\n        for (let cameraIndex = 0; cameraIndex < this._rigCameras.length; cameraIndex++) {\r\n            const cam = this._rigCameras[cameraIndex] as TargetCamera;\r\n            cam.minZ = this.minZ;\r\n            cam.maxZ = this.maxZ;\r\n            cam.fov = this.fov;\r\n            cam.upVector.copyFrom(this.upVector);\r\n            if (cam.rotationQuaternion && this.rotationQuaternion) {\r\n                cam.rotationQuaternion.copyFrom(this.rotationQuaternion);\r\n            } else {\r\n                cam.rotation.copyFrom(this.rotation);\r\n            }\r\n            this._updateCamera(this._rigCameras[cameraIndex] as TargetCamera, cameraIndex);\r\n        }\r\n    }\r\n\r\n    private _updateCamera(camera: TargetCamera, cameraIndex: number) {\r\n        const b = this.distanceBetweenEyes / 2;\r\n        const z = b / this.distanceToProjectionPlane;\r\n        camera.position.copyFrom(this.position);\r\n        camera.position.addInPlaceFromFloats(cameraIndex === 0 ? -b : b, 0, -this._distanceToProjectionPlane);\r\n        const transform = camera.parent as TransformNode;\r\n        const m = transform.getPivotMatrix();\r\n        m.setTranslationFromFloats(cameraIndex === 0 ? b : -b, 0, 0);\r\n        m.setRowFromFloats(2, cameraIndex === 0 ? z : -z, 0, 1, 0);\r\n        transform.setPivotMatrix(m, false);\r\n    }\r\n\r\n    protected override _setRigMode() {\r\n        this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1);\r\n        this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);\r\n        for (let cameraIndex = 0; cameraIndex < this._rigCameras.length; cameraIndex++) {\r\n            this._updateCamera(this._rigCameras[cameraIndex] as TargetCamera, cameraIndex);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FreeCamera } from \"./freeCamera.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Node } from \"../node\";\r\n\r\n/**\r\n * This represents a free type of camera. It can be useful in First Person Shooter game for instance.\r\n * It is identical to the Free Camera and simply adds by default a virtual joystick.\r\n * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#virtual-joysticks-camera\r\n */\r\nexport class VirtualJoysticksCamera extends FreeCamera {\r\n    /**\r\n     * Instantiates a VirtualJoysticksCamera. It can be useful in First Person Shooter game for instance.\r\n     * It is identical to the Free Camera and simply adds by default a virtual joystick.\r\n     * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#virtual-joysticks-camera\r\n     * @param name Define the name of the camera in the scene\r\n     * @param position Define the start position of the camera in the scene\r\n     * @param scene Define the scene the camera belongs to\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene) {\r\n        super(name, position, scene);\r\n        this.inputs.addVirtualJoystick();\r\n    }\r\n\r\n    /**\r\n     * Gets the current object class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VirtualJoysticksCamera\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for virtualJoysticksCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVirtualJoysticksCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"VirtualJoysticksCamera\", (name, scene) => {\r\n        return () => new VirtualJoysticksCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","import { Matrix } from \"../../Maths/math.vector.pure\";\r\n/**\r\n * This represents all the required metrics to create a VR camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#device-orientation-camera\r\n */\r\nexport class VRCameraMetrics {\r\n    /**\r\n     * Define the horizontal resolution off the screen.\r\n     */\r\n    public hResolution: number;\r\n    /**\r\n     * Define the vertical resolution off the screen.\r\n     */\r\n    public vResolution: number;\r\n    /**\r\n     * Define the horizontal screen size.\r\n     */\r\n    public hScreenSize: number;\r\n    /**\r\n     * Define the vertical screen size.\r\n     */\r\n    public vScreenSize: number;\r\n    /**\r\n     * Define the vertical screen center position.\r\n     */\r\n    public vScreenCenter: number;\r\n    /**\r\n     * Define the distance of the eyes to the screen.\r\n     */\r\n    public eyeToScreenDistance: number;\r\n    /**\r\n     * Define the distance between both lenses\r\n     */\r\n    public lensSeparationDistance: number;\r\n    /**\r\n     * Define the distance between both viewer's eyes.\r\n     */\r\n    public interpupillaryDistance: number;\r\n    /**\r\n     * Define the distortion factor of the VR postprocess.\r\n     * Please, touch with care.\r\n     */\r\n    public distortionK: number[];\r\n    /**\r\n     * Define the chromatic aberration correction factors for the VR post process.\r\n     */\r\n    public chromaAbCorrection: number[];\r\n    /**\r\n     * Define the scale factor of the post process.\r\n     * The smaller the better but the slower.\r\n     */\r\n    public postProcessScaleFactor: number;\r\n    /**\r\n     * Define an offset for the lens center.\r\n     */\r\n    public lensCenterOffset: number;\r\n    /**\r\n     * Define if the current vr camera should compensate the distortion of the lens or not.\r\n     */\r\n    public compensateDistortion = true;\r\n\r\n    /**\r\n     * Defines if multiview should be enabled when rendering (Default: false)\r\n     */\r\n    public multiviewEnabled = false;\r\n\r\n    /**\r\n     * Gets the rendering aspect ratio based on the provided resolutions.\r\n     */\r\n    public get aspectRatio(): number {\r\n        return this.hResolution / (2 * this.vResolution);\r\n    }\r\n\r\n    /**\r\n     * Gets the aspect ratio based on the FOV, scale factors, and real screen sizes.\r\n     */\r\n    public get aspectRatioFov(): number {\r\n        return 2 * Math.atan((this.postProcessScaleFactor * this.vScreenSize) / (2 * this.eyeToScreenDistance));\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get leftHMatrix(): Matrix {\r\n        const meters = this.hScreenSize / 4 - this.lensSeparationDistance / 2;\r\n        const h = (4 * meters) / this.hScreenSize;\r\n\r\n        return Matrix.Translation(h, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get rightHMatrix(): Matrix {\r\n        const meters = this.hScreenSize / 4 - this.lensSeparationDistance / 2;\r\n        const h = (4 * meters) / this.hScreenSize;\r\n\r\n        return Matrix.Translation(-h, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public get leftPreViewMatrix(): Matrix {\r\n        return Matrix.Translation(0.5 * this.interpupillaryDistance, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public get rightPreViewMatrix(): Matrix {\r\n        return Matrix.Translation(-0.5 * this.interpupillaryDistance, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * Get the default VRMetrics based on the most generic setup.\r\n     * @returns the default vr metrics\r\n     */\r\n    public static GetDefault(): VRCameraMetrics {\r\n        const result = new VRCameraMetrics();\r\n\r\n        result.hResolution = 1280;\r\n        result.vResolution = 800;\r\n        result.hScreenSize = 0.149759993;\r\n        result.vScreenSize = 0.0935999975;\r\n        result.vScreenCenter = 0.0467999987;\r\n        result.eyeToScreenDistance = 0.0410000011;\r\n        result.lensSeparationDistance = 0.063500002;\r\n        result.interpupillaryDistance = 0.064000003;\r\n        result.distortionK = [1.0, 0.219999999, 0.239999995, 0.0];\r\n        result.chromaAbCorrection = [0.995999992, -0.00400000019, 1.01400006, 0.0];\r\n        result.postProcessScaleFactor = 1.714605507808412;\r\n        result.lensCenterOffset = 0.151976421;\r\n\r\n        return result;\r\n    }\r\n}\r\n","import { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type VRCameraMetrics } from \"../Cameras/VR/vrCameraMetrics\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\n\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * VRDistortionCorrectionPostProcess used for mobile VR\r\n */\r\nexport class VRDistortionCorrectionPostProcess extends PostProcess {\r\n    private _isRightEye: boolean;\r\n    private _distortionFactors: number[];\r\n    private _postProcessScaleFactor: number;\r\n    private _lensCenterOffset: number;\r\n    private _scaleIn: Vector2;\r\n    private _scaleFactor: Vector2;\r\n    private _lensCenter: Vector2;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"VRDistortionCorrectionPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VRDistortionCorrectionPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Initializes the VRDistortionCorrectionPostProcess\r\n     * @param name The name of the effect.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param isRightEye If this is for the right eye distortion\r\n     * @param vrMetrics All the required metrics for the VR camera\r\n     */\r\n    constructor(name: string, camera: Nullable<Camera>, isRightEye: boolean, vrMetrics: VRCameraMetrics) {\r\n        super(name, \"vrDistortionCorrection\", [\"LensCenter\", \"Scale\", \"ScaleIn\", \"HmdWarpParam\"], null, vrMetrics.postProcessScaleFactor, camera, Texture.BILINEAR_SAMPLINGMODE);\r\n\r\n        this._isRightEye = isRightEye;\r\n        this._distortionFactors = vrMetrics.distortionK;\r\n        this._postProcessScaleFactor = vrMetrics.postProcessScaleFactor;\r\n        this._lensCenterOffset = vrMetrics.lensCenterOffset;\r\n        this.adaptScaleToCurrentViewport = true;\r\n\r\n        this.onSizeChangedObservable.add(() => {\r\n            this._scaleIn = new Vector2(2, 2 / this.aspectRatio);\r\n            this._scaleFactor = new Vector2(0.5 * (1 / this._postProcessScaleFactor), 0.5 * (1 / this._postProcessScaleFactor) * this.aspectRatio);\r\n            this._lensCenter = new Vector2(this._isRightEye ? 0.5 - this._lensCenterOffset * 0.5 : 0.5 + this._lensCenterOffset * 0.5, 0.5);\r\n        });\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setFloat2(\"LensCenter\", this._lensCenter.x, this._lensCenter.y);\r\n            effect.setFloat2(\"Scale\", this._scaleFactor.x, this._scaleFactor.y);\r\n            effect.setFloat2(\"ScaleIn\", this._scaleIn.x, this._scaleIn.y);\r\n            effect.setFloat4(\"HmdWarpParam\", this._distortionFactors[0], this._distortionFactors[1], this._distortionFactors[2], this._distortionFactors[3]);\r\n        });\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/vrDistortionCorrection.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/vrDistortionCorrection.fragment\"));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n}\r\n","import { RenderTargetTexture } from \"../Textures/renderTargetTexture.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type Engine } from \"../../Engines/engine\";\r\n\r\n/**\r\n * Renders to multiple views with a single draw call\r\n * Only for WebGL backends\r\n * @see https://www.khronos.org/registry/webgl/extensions/OVR_multiview2/\r\n */\r\nexport class MultiviewRenderTarget extends RenderTargetTexture {\r\n    public override set samples(value: number) {\r\n        // We override this setter because multisampling is handled by framebufferTextureMultisampleMultiviewOVR\r\n        this._samples = value;\r\n    }\r\n\r\n    public override get samples(): number {\r\n        return this._samples;\r\n    }\r\n\r\n    /**\r\n     * Creates a multiview render target\r\n     * @param scene scene used with the render target\r\n     * @param size the size of the render target (used for each view)\r\n     */\r\n    constructor(scene?: Scene, size: number | { width: number; height: number } | { ratio: number } = 512) {\r\n        super(\"multiview rtt\", size, scene, false, true, Constants.TEXTURETYPE_UNSIGNED_BYTE, false, undefined, false, false, true, undefined, true);\r\n        this._renderTarget = (this.getScene()!.getEngine() as Engine).createMultiviewRenderTargetTexture(this.getRenderWidth(), this.getRenderHeight());\r\n        this._texture = this._renderTarget.texture!;\r\n        this._texture.isMultiview = true;\r\n        this._texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n        this.samples = this._getEngine()!.getCaps().maxSamples || this.samples;\r\n        this._texture.samples = this._samples;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _bindFrameBuffer() {\r\n        if (!this._renderTarget) {\r\n            return;\r\n        }\r\n        (this.getScene()!.getEngine() as Engine).bindMultiviewFramebuffer(this._renderTarget);\r\n    }\r\n\r\n    /**\r\n     * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)\r\n     * @returns the view count\r\n     */\r\n    public override getViewCount() {\r\n        return 2;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { PrecisionDate } from \"./precisionDate\";\r\n\r\n/**\r\n * Performance monitor tracks rolling average frame-time and frame-time variance over a user defined sliding-window\r\n */\r\nexport class PerformanceMonitor {\r\n    private _enabled: boolean = true;\r\n    private _rollingFrameTime: RollingAverage;\r\n    private _lastFrameTimeMs: Nullable<number>;\r\n\r\n    /**\r\n     * constructor\r\n     * @param frameSampleSize The number of samples required to saturate the sliding window\r\n     */\r\n    constructor(frameSampleSize: number = 30) {\r\n        this._rollingFrameTime = new RollingAverage(frameSampleSize);\r\n    }\r\n\r\n    /**\r\n     * Samples current frame\r\n     * @param timeMs A timestamp in milliseconds of the current frame to compare with other frames\r\n     */\r\n    public sampleFrame(timeMs: number = PrecisionDate.Now) {\r\n        if (!this._enabled) {\r\n            return;\r\n        }\r\n\r\n        if (this._lastFrameTimeMs != null) {\r\n            const dt = timeMs - this._lastFrameTimeMs;\r\n            this._rollingFrameTime.add(dt);\r\n        }\r\n\r\n        this._lastFrameTimeMs = timeMs;\r\n    }\r\n\r\n    /**\r\n     * Returns the average frame time in milliseconds over the sliding window (or the subset of frames sampled so far)\r\n     */\r\n    public get averageFrameTime(): number {\r\n        return this._rollingFrameTime.average;\r\n    }\r\n\r\n    /**\r\n     * Returns the variance frame time in milliseconds over the sliding window (or the subset of frames sampled so far)\r\n     */\r\n    public get averageFrameTimeVariance(): number {\r\n        return this._rollingFrameTime.variance;\r\n    }\r\n\r\n    /**\r\n     * Returns the frame time of the most recent frame\r\n     */\r\n    public get instantaneousFrameTime(): number {\r\n        return this._rollingFrameTime.history(0);\r\n    }\r\n\r\n    /**\r\n     * Returns the average framerate in frames per second over the sliding window (or the subset of frames sampled so far)\r\n     */\r\n    public get averageFPS(): number {\r\n        return 1000.0 / this._rollingFrameTime.average;\r\n    }\r\n\r\n    /**\r\n     * Returns the average framerate in frames per second using the most recent frame time\r\n     */\r\n    public get instantaneousFPS(): number {\r\n        const history = this._rollingFrameTime.history(0);\r\n\r\n        if (history === 0) {\r\n            return 0;\r\n        }\r\n\r\n        return 1000.0 / history;\r\n    }\r\n\r\n    /**\r\n     * Returns true if enough samples have been taken to completely fill the sliding window\r\n     */\r\n    public get isSaturated(): boolean {\r\n        return this._rollingFrameTime.isSaturated();\r\n    }\r\n\r\n    /**\r\n     * Enables contributions to the sliding window sample set\r\n     */\r\n    public enable() {\r\n        this._enabled = true;\r\n    }\r\n\r\n    /**\r\n     * Disables contributions to the sliding window sample set\r\n     * Samples will not be interpolated over the disabled period\r\n     */\r\n    public disable() {\r\n        this._enabled = false;\r\n        //clear last sample to avoid interpolating over the disabled period when next enabled\r\n        this._lastFrameTimeMs = null;\r\n    }\r\n\r\n    /**\r\n     * Returns true if sampling is enabled\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    /**\r\n     * Resets performance monitor\r\n     */\r\n    public reset() {\r\n        //clear last sample to avoid interpolating over the disabled period when next enabled\r\n        this._lastFrameTimeMs = null;\r\n        //wipe record\r\n        this._rollingFrameTime.reset();\r\n    }\r\n}\r\n\r\n/**\r\n * RollingAverage\r\n *\r\n * Utility to efficiently compute the rolling average and variance over a sliding window of samples\r\n */\r\nexport class RollingAverage {\r\n    /**\r\n     * Current average\r\n     */\r\n    public average: number;\r\n    /**\r\n     * Current variance\r\n     */\r\n    public variance: number;\r\n\r\n    protected _samples: Array<number>;\r\n    protected _sampleCount: number;\r\n    protected _pos: number;\r\n    protected _m2: number; //sum of squares of differences from the (current) mean\r\n\r\n    /**\r\n     * constructor\r\n     * @param length The number of samples required to saturate the sliding window\r\n     */\r\n    constructor(length: number) {\r\n        this._samples = new Array<number>(length);\r\n        this.reset();\r\n    }\r\n\r\n    /**\r\n     * Adds a sample to the sample set\r\n     * @param v The sample value\r\n     */\r\n    public add(v: number) {\r\n        //http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance\r\n        let delta: number;\r\n\r\n        //we need to check if we've already wrapped round\r\n        if (this.isSaturated()) {\r\n            //remove bottom of stack from mean\r\n            const bottomValue = this._samples[this._pos];\r\n            delta = bottomValue - this.average;\r\n            this.average -= delta / (this._sampleCount - 1);\r\n            this._m2 -= delta * (bottomValue - this.average);\r\n        } else {\r\n            this._sampleCount++;\r\n        }\r\n\r\n        //add new value to mean\r\n        delta = v - this.average;\r\n        this.average += delta / this._sampleCount;\r\n        this._m2 += delta * (v - this.average);\r\n\r\n        //set the new variance\r\n        this.variance = this._m2 / (this._sampleCount - 1);\r\n\r\n        this._samples[this._pos] = v;\r\n        this._pos++;\r\n\r\n        this._pos %= this._samples.length; //positive wrap around\r\n    }\r\n\r\n    /**\r\n     * Returns previously added values or null if outside of history or outside the sliding window domain\r\n     * @param i Index in history. For example, pass 0 for the most recent value and 1 for the value before that\r\n     * @returns Value previously recorded with add() or null if outside of range\r\n     */\r\n    public history(i: number): number {\r\n        if (i >= this._sampleCount || i >= this._samples.length) {\r\n            return 0;\r\n        }\r\n\r\n        const i0 = this._wrapPosition(this._pos - 1.0);\r\n        return this._samples[this._wrapPosition(i0 - i)];\r\n    }\r\n\r\n    /**\r\n     * Returns true if enough samples have been taken to completely fill the sliding window\r\n     * @returns true if sample-set saturated\r\n     */\r\n    public isSaturated(): boolean {\r\n        return this._sampleCount >= this._samples.length;\r\n    }\r\n\r\n    /**\r\n     * Resets the rolling average (equivalent to 0 samples taken so far)\r\n     */\r\n    public reset() {\r\n        this.average = 0;\r\n        this.variance = 0;\r\n        this._sampleCount = 0;\r\n        this._pos = 0;\r\n        this._m2 = 0;\r\n    }\r\n\r\n    /**\r\n     * Wraps a value around the sample range boundaries\r\n     * @param i Position in sample range, for example if the sample length is 5, and i is -3, then 2 will be returned.\r\n     * @returns Wrapped position in sample range\r\n     */\r\n    protected _wrapPosition(i: number): number {\r\n        const max = this._samples.length;\r\n        return ((i % max) + max) % max;\r\n    }\r\n}\r\n","import { IsDocumentAvailable } from \"../Misc/domManagement\";\r\nimport { type Nullable } from \"../types\";\r\nimport { AbstractEngine, type AbstractEngineOptions } from \"./abstractEngine\";\r\nimport { EngineStore } from \"./engineStore\";\r\n\r\n/** @internal */\r\nfunction DisableTouchAction(canvas: Nullable<HTMLCanvasElement>): void {\r\n    if (!canvas || !canvas.setAttribute) {\r\n        return;\r\n    }\r\n\r\n    canvas.setAttribute(\"touch-action\", \"none\");\r\n    canvas.style.touchAction = \"none\";\r\n    (canvas.style as any).webkitTapHighlightColor = \"transparent\";\r\n}\r\n\r\n/** @internal */\r\nexport function _CommonInit(commonEngine: AbstractEngine, canvas: HTMLCanvasElement, creationOptions: AbstractEngineOptions) {\r\n    commonEngine._onCanvasFocus = () => {\r\n        commonEngine.onCanvasFocusObservable.notifyObservers(commonEngine);\r\n    };\r\n\r\n    commonEngine._onCanvasBlur = () => {\r\n        commonEngine.onCanvasBlurObservable.notifyObservers(commonEngine);\r\n    };\r\n\r\n    commonEngine._onCanvasContextMenu = (evt: Event) => {\r\n        if (commonEngine.disableContextMenu) {\r\n            evt.preventDefault();\r\n        }\r\n    };\r\n\r\n    canvas.addEventListener(\"focus\", commonEngine._onCanvasFocus);\r\n    canvas.addEventListener(\"blur\", commonEngine._onCanvasBlur);\r\n    canvas.addEventListener(\"contextmenu\", commonEngine._onCanvasContextMenu);\r\n\r\n    commonEngine._onBlur = () => {\r\n        if (commonEngine.disablePerformanceMonitorInBackground) {\r\n            commonEngine.performanceMonitor.disable();\r\n        }\r\n        commonEngine._windowIsBackground = true;\r\n    };\r\n\r\n    commonEngine._onFocus = () => {\r\n        if (commonEngine.disablePerformanceMonitorInBackground) {\r\n            commonEngine.performanceMonitor.enable();\r\n        }\r\n        commonEngine._windowIsBackground = false;\r\n    };\r\n\r\n    commonEngine._onCanvasPointerOut = (ev) => {\r\n        // Check that the element at the point of the pointer out isn't the canvas and if it isn't, notify observers\r\n        // Note: This is a workaround for a bug with Safari\r\n        if (document.elementFromPoint(ev.clientX, ev.clientY) !== canvas) {\r\n            commonEngine.onCanvasPointerOutObservable.notifyObservers(ev);\r\n        }\r\n    };\r\n\r\n    const hostWindow = commonEngine.getHostWindow(); // it calls IsWindowObjectExist()\r\n    if (hostWindow && typeof hostWindow.addEventListener === \"function\") {\r\n        hostWindow.addEventListener(\"blur\", commonEngine._onBlur);\r\n        hostWindow.addEventListener(\"focus\", commonEngine._onFocus);\r\n    }\r\n\r\n    canvas.addEventListener(\"pointerout\", commonEngine._onCanvasPointerOut);\r\n\r\n    if (!creationOptions.doNotHandleTouchAction) {\r\n        DisableTouchAction(canvas);\r\n    }\r\n\r\n    // Create Audio Engine if needed.\r\n    if (!AbstractEngine.audioEngine && creationOptions.audioEngine && AbstractEngine.AudioEngineFactory) {\r\n        AbstractEngine.audioEngine = AbstractEngine.AudioEngineFactory(commonEngine.getRenderingCanvas(), commonEngine.getAudioContext(), commonEngine.getAudioDestination());\r\n    }\r\n\r\n    if (IsDocumentAvailable()) {\r\n        // Fullscreen\r\n        commonEngine._onFullscreenChange = () => {\r\n            commonEngine.isFullscreen = !!document.fullscreenElement;\r\n\r\n            // Pointer lock\r\n            if (commonEngine.isFullscreen && commonEngine._pointerLockRequested && canvas) {\r\n                RequestPointerlock(canvas);\r\n            }\r\n        };\r\n\r\n        document.addEventListener(\"fullscreenchange\", commonEngine._onFullscreenChange, false);\r\n        document.addEventListener(\"webkitfullscreenchange\", commonEngine._onFullscreenChange, false);\r\n\r\n        // Pointer lock\r\n        commonEngine._onPointerLockChange = () => {\r\n            commonEngine.isPointerLock = document.pointerLockElement === canvas;\r\n        };\r\n\r\n        document.addEventListener(\"pointerlockchange\", commonEngine._onPointerLockChange, false);\r\n        document.addEventListener(\"webkitpointerlockchange\", commonEngine._onPointerLockChange, false);\r\n    }\r\n\r\n    commonEngine.enableOfflineSupport = AbstractEngine.OfflineProviderFactory !== undefined;\r\n\r\n    commonEngine._deterministicLockstep = !!creationOptions.deterministicLockstep;\r\n    commonEngine._lockstepMaxSteps = creationOptions.lockstepMaxSteps || 0;\r\n    commonEngine._timeStep = creationOptions.timeStep || 1 / 60;\r\n}\r\n\r\n/** @internal */\r\nexport function _CommonDispose(commonEngine: AbstractEngine, canvas: Nullable<HTMLCanvasElement>) {\r\n    // Release audio engine\r\n    if (EngineStore.Instances.length === 1 && AbstractEngine.audioEngine) {\r\n        AbstractEngine.audioEngine.dispose();\r\n        AbstractEngine.audioEngine = null;\r\n    }\r\n\r\n    // Events\r\n    const hostWindow = commonEngine.getHostWindow(); // it calls IsWindowObjectExist()\r\n    if (hostWindow && typeof hostWindow.removeEventListener === \"function\") {\r\n        hostWindow.removeEventListener(\"blur\", commonEngine._onBlur);\r\n        hostWindow.removeEventListener(\"focus\", commonEngine._onFocus);\r\n    }\r\n\r\n    if (canvas) {\r\n        canvas.removeEventListener(\"focus\", commonEngine._onCanvasFocus);\r\n        canvas.removeEventListener(\"blur\", commonEngine._onCanvasBlur);\r\n        canvas.removeEventListener(\"pointerout\", commonEngine._onCanvasPointerOut);\r\n        canvas.removeEventListener(\"contextmenu\", commonEngine._onCanvasContextMenu);\r\n    }\r\n\r\n    if (IsDocumentAvailable()) {\r\n        document.removeEventListener(\"fullscreenchange\", commonEngine._onFullscreenChange);\r\n        document.removeEventListener(\"mozfullscreenchange\", commonEngine._onFullscreenChange);\r\n        document.removeEventListener(\"webkitfullscreenchange\", commonEngine._onFullscreenChange);\r\n        document.removeEventListener(\"msfullscreenchange\", commonEngine._onFullscreenChange);\r\n        document.removeEventListener(\"pointerlockchange\", commonEngine._onPointerLockChange);\r\n        document.removeEventListener(\"mspointerlockchange\", commonEngine._onPointerLockChange);\r\n        document.removeEventListener(\"mozpointerlockchange\", commonEngine._onPointerLockChange);\r\n        document.removeEventListener(\"webkitpointerlockchange\", commonEngine._onPointerLockChange);\r\n    }\r\n}\r\n\r\n/**\r\n * Get Font size information\r\n * @param font font name\r\n * @returns an object containing ascent, height and descent\r\n */\r\nexport function GetFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n    const domFontOffset = GetFontOffsetFromDom(font);\r\n    if (domFontOffset) {\r\n        return domFontOffset;\r\n    }\r\n\r\n    const canvasFontOffset = GetFontOffsetFromCanvas(font);\r\n    if (canvasFontOffset) {\r\n        return canvasFontOffset;\r\n    }\r\n\r\n    return GetFallbackFontOffset(font);\r\n}\r\n\r\nfunction GetFontOffsetFromDom(font: string): Nullable<{ ascent: number; height: number; descent: number }> {\r\n    if (!IsDocumentAvailable() || !document.body) {\r\n        return null;\r\n    }\r\n\r\n    const text = document.createElement(\"span\");\r\n    text.textContent = \"Hg\";\r\n    text.style.font = font;\r\n\r\n    const block = document.createElement(\"div\");\r\n    block.style.display = \"inline-block\";\r\n    block.style.width = \"1px\";\r\n    block.style.height = \"0px\";\r\n    block.style.verticalAlign = \"bottom\";\r\n\r\n    const div = document.createElement(\"div\");\r\n    div.style.whiteSpace = \"nowrap\";\r\n    div.appendChild(text);\r\n    div.appendChild(block);\r\n\r\n    document.body.appendChild(div);\r\n\r\n    let fontAscent: number;\r\n    let fontHeight: number;\r\n    try {\r\n        fontHeight = block.getBoundingClientRect().top - text.getBoundingClientRect().top;\r\n        block.style.verticalAlign = \"baseline\";\r\n        fontAscent = block.getBoundingClientRect().top - text.getBoundingClientRect().top;\r\n    } finally {\r\n        document.body.removeChild(div);\r\n    }\r\n\r\n    const offset = { ascent: fontAscent, height: fontHeight, descent: fontHeight - fontAscent };\r\n    return IsValidFontOffset(offset) ? offset : null;\r\n}\r\n\r\nfunction GetFontOffsetFromCanvas(font: string): Nullable<{ ascent: number; height: number; descent: number }> {\r\n    let canvas: Nullable<OffscreenCanvas | HTMLCanvasElement> = null;\r\n    try {\r\n        if (typeof OffscreenCanvas !== \"undefined\") {\r\n            canvas = new OffscreenCanvas(64, 64);\r\n        } else if (IsDocumentAvailable() && typeof document.createElement === \"function\") {\r\n            canvas = document.createElement(\"canvas\");\r\n            canvas.width = 64;\r\n            canvas.height = 64;\r\n        }\r\n\r\n        const context = canvas?.getContext(\"2d\") as Nullable<CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D>;\r\n        if (!context) {\r\n            return null;\r\n        }\r\n\r\n        context.font = font;\r\n        const metrics = context.measureText(\"Hg\");\r\n        const ascent = Number(metrics.actualBoundingBoxAscent ?? metrics.fontBoundingBoxAscent);\r\n        const descent = Number(metrics.actualBoundingBoxDescent ?? metrics.fontBoundingBoxDescent);\r\n        const offset = { ascent, height: ascent + descent, descent };\r\n        return IsValidFontOffset(offset) ? offset : null;\r\n    } catch {\r\n        return null;\r\n    } finally {\r\n        const disposableCanvas = canvas as Nullable<{ dispose?: () => void }>;\r\n        if (typeof disposableCanvas?.dispose === \"function\") {\r\n            disposableCanvas.dispose();\r\n        }\r\n    }\r\n}\r\n\r\nfunction GetFallbackFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n    const size = Math.max(1, GetCssPixelFontSize(font));\r\n    const ascent = size * 0.8;\r\n    const descent = size * 0.2;\r\n    return { ascent, height: ascent + descent, descent };\r\n}\r\n\r\nfunction GetCssPixelFontSize(font: string): number {\r\n    const match = /(?:^|\\s)([0-9]+(?:\\.[0-9]+)?)px(?:\\/|\\s|$)/.exec(String(font || \"\"));\r\n    return match ? Number(match[1]) : 16;\r\n}\r\n\r\nfunction IsValidFontOffset(offset: { ascent: number; height: number; descent: number }): boolean {\r\n    return Number.isFinite(offset.ascent) && Number.isFinite(offset.height) && Number.isFinite(offset.descent) && offset.height > 0;\r\n}\r\n\r\n/** @internal */\r\nexport async function CreateImageBitmapFromSource(engine: AbstractEngine, imageSource: string, options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n    return await new Promise<ImageBitmap>((resolve, reject) => {\r\n        const image = new Image();\r\n        image.onload = () => {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            image.decode().then(() => {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                engine.createImageBitmap(image, options).then((imageBitmap) => {\r\n                    resolve(imageBitmap);\r\n                });\r\n            });\r\n        };\r\n        image.onerror = () => {\r\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n            reject(`Error loading image ${image.src}`);\r\n        };\r\n\r\n        image.src = imageSource;\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function ResizeImageBitmap(engine: AbstractEngine, image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n    const canvas = engine.createCanvas(bufferWidth, bufferHeight);\r\n    const context = canvas.getContext(\"2d\");\r\n\r\n    if (!context) {\r\n        throw new Error(\"Unable to get 2d context for resizeImageBitmap\");\r\n    }\r\n\r\n    context.drawImage(image, 0, 0);\r\n\r\n    // Create VertexData from map data\r\n    // Cast is due to wrong definition in lib.d.ts from ts 1.3 - https://github.com/Microsoft/TypeScript/issues/949\r\n    const buffer = <Uint8Array>(<any>context.getImageData(0, 0, bufferWidth, bufferHeight).data);\r\n    return buffer;\r\n}\r\n\r\n/**\r\n * Ask the browser to promote the current element to fullscreen rendering mode\r\n * @param element defines the DOM element to promote\r\n */\r\nexport function RequestFullscreen(element: HTMLElement): void {\r\n    const requestFunction = element.requestFullscreen || (<any>element).webkitRequestFullscreen;\r\n    if (!requestFunction) {\r\n        return;\r\n    }\r\n    void requestFunction.call(element);\r\n}\r\n\r\n/**\r\n * Asks the browser to exit fullscreen mode\r\n */\r\nexport function ExitFullscreen(): void {\r\n    const anyDoc = document as any;\r\n\r\n    if (document.exitFullscreen) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        document.exitFullscreen();\r\n    } else if (anyDoc.webkitCancelFullScreen) {\r\n        anyDoc.webkitCancelFullScreen();\r\n    }\r\n}\r\n\r\n/**\r\n * Ask the browser to promote the current element to pointerlock mode\r\n * @param element defines the DOM element to promote\r\n */\r\nexport function RequestPointerlock(element: HTMLElement): void {\r\n    if (element.requestPointerLock) {\r\n        // In some browsers, requestPointerLock returns a promise.\r\n        // Handle possible rejections to avoid an unhandled top-level exception.\r\n        const promise: unknown = element.requestPointerLock();\r\n        if (promise instanceof Promise) {\r\n            promise\r\n                // eslint-disable-next-line github/no-then\r\n                .then(() => {\r\n                    element.focus();\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .catch(() => {});\r\n        } else {\r\n            element.focus();\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Asks the browser to exit pointerlock mode\r\n */\r\nexport function ExitPointerlock(): void {\r\n    if (document.exitPointerLock) {\r\n        document.exitPointerLock();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IViewportLike } from \"../../Maths/math.like\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\n/**\r\n * Defines the interface used by objects containing a viewport (like a camera)\r\n */\r\nexport interface IViewportOwnerLike {\r\n    /**\r\n     * Gets or sets the viewport\r\n     */\r\n    viewport: IViewportLike;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineDom.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineDom(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.getInputElement = function (): Nullable<HTMLElement> {\r\n        return this._renderingCanvas;\r\n    };\r\n\r\n    AbstractEngine.prototype.getRenderingCanvasClientRect = function (): Nullable<ClientRect> {\r\n        if (!this._renderingCanvas) {\r\n            return null;\r\n        }\r\n        return this._renderingCanvas.getBoundingClientRect();\r\n    };\r\n\r\n    AbstractEngine.prototype.getInputElementClientRect = function (): Nullable<ClientRect> {\r\n        if (!this._renderingCanvas) {\r\n            return null;\r\n        }\r\n        return this.getInputElement()!.getBoundingClientRect();\r\n    };\r\n\r\n    AbstractEngine.prototype.getAspectRatio = function (viewportOwner: IViewportOwnerLike, useScreen = false): number {\r\n        const viewport = viewportOwner.viewport;\r\n        return (this.getRenderWidth(useScreen) * viewport.width) / (this.getRenderHeight(useScreen) * viewport.height);\r\n    };\r\n\r\n    AbstractEngine.prototype.getScreenAspectRatio = function (): number {\r\n        return this.getRenderWidth(true) / this.getRenderHeight(true);\r\n    };\r\n\r\n    AbstractEngine.prototype._verifyPointerLock = function (): void {\r\n        this._onPointerLockChange?.();\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { type ILoadingScreen } from \"../Loading/loadingScreen.pure\";\r\nimport { EngineStore } from \"./engineStore\";\r\nimport { type WebGLPipelineContext } from \"./WebGL/webGLPipelineContext\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { type EngineOptions, ThinEngine } from \"./thinEngine.pure\";\r\nimport { Constants } from \"./constants\";\r\nimport { type IViewportLike, type IColor4Like } from \"../Maths/math.like\";\r\nimport { PerformanceMonitor } from \"../Misc/performanceMonitor\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { WebGLDataBuffer } from \"../Meshes/WebGL/webGLDataBuffer\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { WebGLHardwareTexture } from \"./WebGL/webGLHardwareTexture\";\r\nimport { type WebGLRenderTargetWrapper } from \"./WebGL/webGLRenderTargetWrapper\";\r\n\r\nimport { type PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { AbstractEngine } from \"./abstractEngine.pure\";\r\nimport {\r\n    CreateImageBitmapFromSource,\r\n    ExitFullscreen,\r\n    ExitPointerlock,\r\n    GetFontOffset,\r\n    RequestFullscreen,\r\n    RequestPointerlock,\r\n    ResizeImageBitmap,\r\n    _CommonDispose,\r\n    _CommonInit,\r\n} from \"./engine.common\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport { _RetryWithInterval } from \"core/Misc/timingTools\";\r\nimport { RegisterAbstractEngineDom } from \"./AbstractEngine/abstractEngine.dom.pure\";\r\nimport { RegisterAbstractEngineRenderPass } from \"./AbstractEngine/abstractEngine.renderPass.pure\";\r\n\r\n/**\r\n * The engine class is responsible for interfacing with all lower-level APIs such as WebGL and Audio\r\n */\r\nexport class Engine extends ThinEngine {\r\n    // Const statics\r\n\r\n    /** Defines that alpha blending is disabled */\r\n    public static readonly ALPHA_DISABLE = Constants.ALPHA_DISABLE;\r\n    /** Defines that alpha blending to SRC ALPHA * SRC + DEST */\r\n    public static readonly ALPHA_ADD = Constants.ALPHA_ADD;\r\n    /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC ALPHA) * DEST */\r\n    public static readonly ALPHA_COMBINE = Constants.ALPHA_COMBINE;\r\n    /** Defines that alpha blending to DEST - SRC * DEST */\r\n    public static readonly ALPHA_SUBTRACT = Constants.ALPHA_SUBTRACT;\r\n    /** Defines that alpha blending to SRC * DEST */\r\n    public static readonly ALPHA_MULTIPLY = Constants.ALPHA_MULTIPLY;\r\n    /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC) * DEST */\r\n    public static readonly ALPHA_MAXIMIZED = Constants.ALPHA_MAXIMIZED;\r\n    /** Defines that alpha blending to SRC + DEST */\r\n    public static readonly ALPHA_ONEONE = Constants.ALPHA_ONEONE;\r\n    /** Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST */\r\n    public static readonly ALPHA_PREMULTIPLIED = Constants.ALPHA_PREMULTIPLIED;\r\n    /**\r\n     * Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST\r\n     * Alpha will be set to (1 - SRC ALPHA) * DEST ALPHA\r\n     */\r\n    public static readonly ALPHA_PREMULTIPLIED_PORTERDUFF = Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n    /** Defines that alpha blending to CST * SRC + (1 - CST) * DEST */\r\n    public static readonly ALPHA_INTERPOLATE = Constants.ALPHA_INTERPOLATE;\r\n    /**\r\n     * Defines that alpha blending to SRC + (1 - SRC) * DEST\r\n     * Alpha will be set to SRC ALPHA + (1 - SRC ALPHA) * DEST ALPHA\r\n     */\r\n    public static readonly ALPHA_SCREENMODE = Constants.ALPHA_SCREENMODE;\r\n\r\n    /** Defines that the resource is not delayed*/\r\n    public static readonly DELAYLOADSTATE_NONE = Constants.DELAYLOADSTATE_NONE;\r\n    /** Defines that the resource was successfully delay loaded */\r\n    public static readonly DELAYLOADSTATE_LOADED = Constants.DELAYLOADSTATE_LOADED;\r\n    /** Defines that the resource is currently delay loading */\r\n    public static readonly DELAYLOADSTATE_LOADING = Constants.DELAYLOADSTATE_LOADING;\r\n    /** Defines that the resource is delayed and has not started loading */\r\n    public static readonly DELAYLOADSTATE_NOTLOADED = Constants.DELAYLOADSTATE_NOTLOADED;\r\n\r\n    // Depht or Stencil test Constants.\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass. i.e. Nothing will be drawn */\r\n    public static readonly NEVER = Constants.NEVER;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */\r\n    public static readonly ALWAYS = Constants.ALWAYS;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value */\r\n    public static readonly LESS = Constants.LESS;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value */\r\n    public static readonly EQUAL = Constants.EQUAL;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value */\r\n    public static readonly LEQUAL = Constants.LEQUAL;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value */\r\n    public static readonly GREATER = Constants.GREATER;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value */\r\n    public static readonly GEQUAL = Constants.GEQUAL;\r\n    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value */\r\n    public static readonly NOTEQUAL = Constants.NOTEQUAL;\r\n\r\n    // Stencil Actions Constants.\r\n    /** Passed to stencilOperation to specify that stencil value must be kept */\r\n    public static readonly KEEP = Constants.KEEP;\r\n    /** Passed to stencilOperation to specify that stencil value must be replaced */\r\n    public static readonly REPLACE = Constants.REPLACE;\r\n    /** Passed to stencilOperation to specify that stencil value must be incremented */\r\n    public static readonly INCR = Constants.INCR;\r\n    /** Passed to stencilOperation to specify that stencil value must be decremented */\r\n    public static readonly DECR = Constants.DECR;\r\n    /** Passed to stencilOperation to specify that stencil value must be inverted */\r\n    public static readonly INVERT = Constants.INVERT;\r\n    /** Passed to stencilOperation to specify that stencil value must be incremented with wrapping */\r\n    public static readonly INCR_WRAP = Constants.INCR_WRAP;\r\n    /** Passed to stencilOperation to specify that stencil value must be decremented with wrapping */\r\n    public static readonly DECR_WRAP = Constants.DECR_WRAP;\r\n\r\n    /** Texture is not repeating outside of 0..1 UVs */\r\n    public static readonly TEXTURE_CLAMP_ADDRESSMODE = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n    /** Texture is repeating outside of 0..1 UVs */\r\n    public static readonly TEXTURE_WRAP_ADDRESSMODE = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n    /** Texture is repeating and mirrored */\r\n    public static readonly TEXTURE_MIRROR_ADDRESSMODE = Constants.TEXTURE_MIRROR_ADDRESSMODE;\r\n\r\n    /** ALPHA */\r\n    public static readonly TEXTUREFORMAT_ALPHA = Constants.TEXTUREFORMAT_ALPHA;\r\n    /** LUMINANCE */\r\n    public static readonly TEXTUREFORMAT_LUMINANCE = Constants.TEXTUREFORMAT_LUMINANCE;\r\n    /** LUMINANCE_ALPHA */\r\n    public static readonly TEXTUREFORMAT_LUMINANCE_ALPHA = Constants.TEXTUREFORMAT_LUMINANCE_ALPHA;\r\n    /** RGB */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGB = Constants.TEXTUREFORMAT_RGB;\r\n    /** RGBA */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGBA = Constants.TEXTUREFORMAT_RGBA;\r\n    /** RED */\r\n    public static readonly TEXTUREFORMAT_RED = Constants.TEXTUREFORMAT_RED;\r\n    /** RED (2nd reference) */\r\n    public static readonly TEXTUREFORMAT_R = Constants.TEXTUREFORMAT_R;\r\n    /** RED unsigned short normed to [0, 1] **/\r\n    public static readonly TEXTUREFORMAT_R16_UNORM = Constants.TEXTUREFORMAT_R16_UNORM;\r\n    /** RG unsigned short normed to [0, 1] **/\r\n    public static readonly TEXTUREFORMAT_RG16_UNORM = Constants.TEXTUREFORMAT_RG16_UNORM;\r\n    /** RGB unsigned short normed to [0, 1] **/\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGB16_UNORM = Constants.TEXTUREFORMAT_RGB16_UNORM;\r\n    /** RGBA unsigned short normed to [0, 1] **/\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGBA16_UNORM = Constants.TEXTUREFORMAT_RGBA16_UNORM;\r\n    /** RED signed short normed to [-1, 1] **/\r\n    public static readonly TEXTUREFORMAT_R16_SNORM = Constants.TEXTUREFORMAT_R16_SNORM;\r\n    /** RG signed short normed to [-1, 1] **/\r\n    public static readonly TEXTUREFORMAT_RG16_SNORM = Constants.TEXTUREFORMAT_RG16_SNORM;\r\n    /** RGB signed short normed to [-1, 1] **/\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGB16_SNORM = Constants.TEXTUREFORMAT_RGB16_SNORM;\r\n    /** RGBA signed short normed to [-1, 1] **/\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGBA16_SNORM = Constants.TEXTUREFORMAT_RGBA16_SNORM;\r\n    /** RG */\r\n    public static readonly TEXTUREFORMAT_RG = Constants.TEXTUREFORMAT_RG;\r\n    /** RED_INTEGER */\r\n    public static readonly TEXTUREFORMAT_RED_INTEGER = Constants.TEXTUREFORMAT_RED_INTEGER;\r\n    /** RED_INTEGER (2nd reference) */\r\n    public static readonly TEXTUREFORMAT_R_INTEGER = Constants.TEXTUREFORMAT_R_INTEGER;\r\n    /** RG_INTEGER */\r\n    public static readonly TEXTUREFORMAT_RG_INTEGER = Constants.TEXTUREFORMAT_RG_INTEGER;\r\n    /** RGB_INTEGER */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGB_INTEGER = Constants.TEXTUREFORMAT_RGB_INTEGER;\r\n    /** RGBA_INTEGER */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTUREFORMAT_RGBA_INTEGER = Constants.TEXTUREFORMAT_RGBA_INTEGER;\r\n\r\n    /** UNSIGNED_BYTE */\r\n    public static readonly TEXTURETYPE_UNSIGNED_BYTE = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    /** @deprecated use more explicit TEXTURETYPE_UNSIGNED_BYTE instead. Use TEXTURETYPE_UNSIGNED_INTEGER for 32bits values.*/\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT = Constants.TEXTURETYPE_UNSIGNED_INT;\r\n    /** FLOAT */\r\n    public static readonly TEXTURETYPE_FLOAT = Constants.TEXTURETYPE_FLOAT;\r\n    /** HALF_FLOAT */\r\n    public static readonly TEXTURETYPE_HALF_FLOAT = Constants.TEXTURETYPE_HALF_FLOAT;\r\n    /** BYTE */\r\n    public static readonly TEXTURETYPE_BYTE = Constants.TEXTURETYPE_BYTE;\r\n    /** SHORT */\r\n    public static readonly TEXTURETYPE_SHORT = Constants.TEXTURETYPE_SHORT;\r\n    /** UNSIGNED_SHORT */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT = Constants.TEXTURETYPE_UNSIGNED_SHORT;\r\n    /** INT */\r\n    public static readonly TEXTURETYPE_INT = Constants.TEXTURETYPE_INT;\r\n    /** UNSIGNED_INT */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INTEGER = Constants.TEXTURETYPE_UNSIGNED_INTEGER;\r\n    /** UNSIGNED_SHORT_4_4_4_4 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 = Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4;\r\n    /** UNSIGNED_SHORT_5_5_5_1 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 = Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1;\r\n    /** UNSIGNED_SHORT_5_6_5 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_SHORT_5_6_5 = Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5;\r\n    /** UNSIGNED_INT_2_10_10_10_REV */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV = Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV;\r\n    /** UNSIGNED_INT_24_8 */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_24_8 = Constants.TEXTURETYPE_UNSIGNED_INT_24_8;\r\n    /** UNSIGNED_INT_10F_11F_11F_REV */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV = Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV;\r\n    /** UNSIGNED_INT_5_9_9_9_REV */\r\n    public static readonly TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV = Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV;\r\n    /** FLOAT_32_UNSIGNED_INT_24_8_REV */\r\n    public static readonly TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV = Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV;\r\n\r\n    /** nearest is mag = nearest and min = nearest and mip = none */\r\n    public static readonly TEXTURE_NEAREST_SAMPLINGMODE = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n    /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n    public static readonly TEXTURE_BILINEAR_SAMPLINGMODE = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n    /** Trilinear is mag = linear and min = linear and mip = linear */\r\n    public static readonly TEXTURE_TRILINEAR_SAMPLINGMODE = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n    /** nearest is mag = nearest and min = nearest and mip = linear */\r\n    public static readonly TEXTURE_NEAREST_NEAREST_MIPLINEAR = Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR;\r\n    /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n    public static readonly TEXTURE_LINEAR_LINEAR_MIPNEAREST = Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST;\r\n    /** Trilinear is mag = linear and min = linear and mip = linear */\r\n    public static readonly TEXTURE_LINEAR_LINEAR_MIPLINEAR = Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR;\r\n    /** mag = nearest and min = nearest and mip = nearest */\r\n    public static readonly TEXTURE_NEAREST_NEAREST_MIPNEAREST = Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST;\r\n    /** mag = nearest and min = linear and mip = nearest */\r\n    public static readonly TEXTURE_NEAREST_LINEAR_MIPNEAREST = Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST;\r\n    /** mag = nearest and min = linear and mip = linear */\r\n    public static readonly TEXTURE_NEAREST_LINEAR_MIPLINEAR = Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR;\r\n    /** mag = nearest and min = linear and mip = none */\r\n    public static readonly TEXTURE_NEAREST_LINEAR = Constants.TEXTURE_NEAREST_LINEAR;\r\n    /** mag = nearest and min = nearest and mip = none */\r\n    public static readonly TEXTURE_NEAREST_NEAREST = Constants.TEXTURE_NEAREST_NEAREST;\r\n    /** mag = linear and min = nearest and mip = nearest */\r\n    public static readonly TEXTURE_LINEAR_NEAREST_MIPNEAREST = Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST;\r\n    /** mag = linear and min = nearest and mip = linear */\r\n    public static readonly TEXTURE_LINEAR_NEAREST_MIPLINEAR = Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR;\r\n    /** mag = linear and min = linear and mip = none */\r\n    public static readonly TEXTURE_LINEAR_LINEAR = Constants.TEXTURE_LINEAR_LINEAR;\r\n    /** mag = linear and min = nearest and mip = none */\r\n    public static readonly TEXTURE_LINEAR_NEAREST = Constants.TEXTURE_LINEAR_NEAREST;\r\n\r\n    /** Explicit coordinates mode */\r\n    public static readonly TEXTURE_EXPLICIT_MODE = Constants.TEXTURE_EXPLICIT_MODE;\r\n    /** Spherical coordinates mode */\r\n    public static readonly TEXTURE_SPHERICAL_MODE = Constants.TEXTURE_SPHERICAL_MODE;\r\n    /** Planar coordinates mode */\r\n    public static readonly TEXTURE_PLANAR_MODE = Constants.TEXTURE_PLANAR_MODE;\r\n    /** Cubic coordinates mode */\r\n    public static readonly TEXTURE_CUBIC_MODE = Constants.TEXTURE_CUBIC_MODE;\r\n    /** Projection coordinates mode */\r\n    public static readonly TEXTURE_PROJECTION_MODE = Constants.TEXTURE_PROJECTION_MODE;\r\n    /** Skybox coordinates mode */\r\n    public static readonly TEXTURE_SKYBOX_MODE = Constants.TEXTURE_SKYBOX_MODE;\r\n    /** Inverse Cubic coordinates mode */\r\n    public static readonly TEXTURE_INVCUBIC_MODE = Constants.TEXTURE_INVCUBIC_MODE;\r\n    /** Equirectangular coordinates mode */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTURE_EQUIRECTANGULAR_MODE = Constants.TEXTURE_EQUIRECTANGULAR_MODE;\r\n    /** Equirectangular Fixed coordinates mode */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTURE_FIXED_EQUIRECTANGULAR_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE;\r\n    /** Equirectangular Fixed Mirrored coordinates mode */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static readonly TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE;\r\n\r\n    // Texture rescaling mode\r\n    /** Defines that texture rescaling will use a floor to find the closer power of 2 size */\r\n    public static readonly SCALEMODE_FLOOR = Constants.SCALEMODE_FLOOR;\r\n    /** Defines that texture rescaling will look for the nearest power of 2 size */\r\n    public static readonly SCALEMODE_NEAREST = Constants.SCALEMODE_NEAREST;\r\n    /** Defines that texture rescaling will use a ceil to find the closer power of 2 size */\r\n    public static readonly SCALEMODE_CEILING = Constants.SCALEMODE_CEILING;\r\n\r\n    /**\r\n     * Returns the current npm package of the sdk\r\n     */\r\n    // Not mixed with Version for tooling purpose.\r\n    public static override get NpmPackage(): string {\r\n        return AbstractEngine.NpmPackage;\r\n    }\r\n\r\n    /**\r\n     * Returns the current version of the framework\r\n     */\r\n    public static override get Version(): string {\r\n        return AbstractEngine.Version;\r\n    }\r\n\r\n    /** Gets the list of created engines */\r\n    public static get Instances(): AbstractEngine[] {\r\n        return EngineStore.Instances;\r\n    }\r\n\r\n    /**\r\n     * Gets the latest created engine\r\n     */\r\n    public static get LastCreatedEngine(): Nullable<AbstractEngine> {\r\n        return EngineStore.LastCreatedEngine;\r\n    }\r\n\r\n    /**\r\n     * Gets the latest created scene\r\n     */\r\n    public static get LastCreatedScene(): Nullable<Scene> {\r\n        return EngineStore.LastCreatedScene;\r\n    }\r\n\r\n    /** @internal */\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Method called to create the default loading screen.\r\n     * This can be overridden in your own app.\r\n     * @param canvas The rendering canvas element\r\n     * @returns The loading screen\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static override DefaultLoadingScreenFactory(canvas: HTMLCanvasElement): ILoadingScreen {\r\n        return AbstractEngine.DefaultLoadingScreenFactory(canvas);\r\n    }\r\n\r\n    // Members\r\n\r\n    private _rescalePostProcess: Nullable<PostProcess>;\r\n\r\n    protected override get _supportsHardwareTextureRescaling() {\r\n        return !!Engine._RescalePostProcessFactory;\r\n    }\r\n\r\n    private _measureFps(): void {\r\n        this._performanceMonitor.sampleFrame();\r\n        this._fps = this._performanceMonitor.averageFPS;\r\n        this._deltaTime = this._performanceMonitor.instantaneousFrameTime || 0;\r\n    }\r\n\r\n    private _performanceMonitor = new PerformanceMonitor();\r\n    /**\r\n     * Gets the performance monitor attached to this engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n     */\r\n    public override get performanceMonitor(): PerformanceMonitor {\r\n        return this._performanceMonitor;\r\n    }\r\n\r\n    // Events\r\n\r\n    /**\r\n     * Creates a new engine\r\n     * @param canvasOrContext defines the canvas or WebGL context to use for rendering. If you provide a WebGL context, Babylon.js will not hook events on the canvas (like pointers, keyboards, etc...) so no event observables will be available. This is mostly used when Babylon.js is used as a plugin on a system which already used the WebGL context\r\n     * @param antialias defines enable antialiasing (default: false)\r\n     * @param options defines further options to be sent to the getContext() function\r\n     * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)\r\n     */\r\n    constructor(\r\n        canvasOrContext: Nullable<HTMLCanvasElement | OffscreenCanvas | WebGLRenderingContext | WebGL2RenderingContext>,\r\n        antialias?: boolean,\r\n        options?: EngineOptions,\r\n        adaptToDeviceRatio: boolean = false\r\n    ) {\r\n        RegisterAbstractEngineDom();\r\n        RegisterAbstractEngineRenderPass();\r\n        super(canvasOrContext, antialias, options, adaptToDeviceRatio);\r\n\r\n        this._drawCalls = new PerfCounter();\r\n\r\n        if (!canvasOrContext) {\r\n            return;\r\n        }\r\n\r\n        this._features.supportRenderPasses = true;\r\n    }\r\n\r\n    protected override _initGLContext(): void {\r\n        super._initGLContext();\r\n\r\n        this._rescalePostProcess = null;\r\n    }\r\n\r\n    /**\r\n     * Shared initialization across engines types.\r\n     * @param canvas The canvas associated with this instance of the engine.\r\n     */\r\n    protected override _sharedInit(canvas: HTMLCanvasElement) {\r\n        super._sharedInit(canvas);\r\n\r\n        _CommonInit(this, canvas, this._creationOptions);\r\n    }\r\n\r\n    /**\r\n     * Resize an image and returns the image data as an uint8array\r\n     * @param image image to resize\r\n     * @param bufferWidth destination buffer width\r\n     * @param bufferHeight destination buffer height\r\n     * @returns an uint8array containing RGBA values of bufferWidth * bufferHeight size\r\n     */\r\n    public override resizeImageBitmap(image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n        return ResizeImageBitmap(this, image, bufferWidth, bufferHeight);\r\n    }\r\n\r\n    /**\r\n     * Engine abstraction for loading and creating an image bitmap from a given source string.\r\n     * @param imageSource source to load the image from.\r\n     * @param options An object that sets options for the image's extraction.\r\n     * @returns ImageBitmap\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public override async _createImageBitmapFromSource(imageSource: string, options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n        return await CreateImageBitmapFromSource(this, imageSource, options);\r\n    }\r\n\r\n    /**\r\n     * Toggle full screen mode\r\n     * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n     */\r\n    public override switchFullscreen(requestPointerLock: boolean): void {\r\n        if (this.isFullscreen) {\r\n            this.exitFullscreen();\r\n        } else {\r\n            this.enterFullscreen(requestPointerLock);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enters full screen mode\r\n     * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n     */\r\n    public override enterFullscreen(requestPointerLock: boolean): void {\r\n        if (!this.isFullscreen) {\r\n            this._pointerLockRequested = requestPointerLock;\r\n            if (this._renderingCanvas) {\r\n                RequestFullscreen(this._renderingCanvas);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Exits full screen mode\r\n     */\r\n    public override exitFullscreen(): void {\r\n        if (this.isFullscreen) {\r\n            ExitFullscreen();\r\n        }\r\n    }\r\n\r\n    /** States */\r\n\r\n    /**\r\n     * Sets a boolean indicating if the dithering state is enabled or disabled\r\n     * @param value defines the dithering state\r\n     */\r\n    public setDitheringState(value: boolean): void {\r\n        if (value) {\r\n            this._gl.enable(this._gl.DITHER);\r\n        } else {\r\n            this._gl.disable(this._gl.DITHER);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a boolean indicating if the rasterizer state is enabled or disabled\r\n     * @param value defines the rasterizer state\r\n     */\r\n    public setRasterizerState(value: boolean): void {\r\n        if (value) {\r\n            this._gl.disable(this._gl.RASTERIZER_DISCARD);\r\n        } else {\r\n            this._gl.enable(this._gl.RASTERIZER_DISCARD);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Directly set the WebGL Viewport\r\n     * @param x defines the x coordinate of the viewport (in screen space)\r\n     * @param y defines the y coordinate of the viewport (in screen space)\r\n     * @param width defines the width of the viewport (in screen space)\r\n     * @param height defines the height of the viewport (in screen space)\r\n     * @returns the current viewport Object (if any) that is being replaced by this call. You can restore this viewport later on to go back to the original state\r\n     */\r\n    public setDirectViewport(x: number, y: number, width: number, height: number): Nullable<IViewportLike> {\r\n        const currentViewport = this._cachedViewport;\r\n        this._cachedViewport = null;\r\n\r\n        this._viewport(x, y, width, height);\r\n\r\n        return currentViewport;\r\n    }\r\n\r\n    /**\r\n     * Executes a scissor clear (ie. a clear on a specific portion of the screen)\r\n     * @param x defines the x-coordinate of the bottom left corner of the clear rectangle\r\n     * @param y defines the y-coordinate of the corner of the clear rectangle\r\n     * @param width defines the width of the clear rectangle\r\n     * @param height defines the height of the clear rectangle\r\n     * @param clearColor defines the clear color\r\n     */\r\n    public scissorClear(x: number, y: number, width: number, height: number, clearColor: IColor4Like): void {\r\n        this.enableScissor(x, y, width, height);\r\n        this.clear(clearColor, true, true, true);\r\n        this.disableScissor();\r\n    }\r\n\r\n    /**\r\n     * Gets the source code of the vertex shader associated with a specific webGL program\r\n     * @param program defines the program to use\r\n     * @returns a string containing the source code of the vertex shader associated with the program\r\n     */\r\n    public getVertexShaderSource(program: WebGLProgram): Nullable<string> {\r\n        const shaders = this._gl.getAttachedShaders(program);\r\n\r\n        if (!shaders) {\r\n            return null;\r\n        }\r\n\r\n        return this._gl.getShaderSource(shaders[0]);\r\n    }\r\n\r\n    /**\r\n     * Gets the source code of the fragment shader associated with a specific webGL program\r\n     * @param program defines the program to use\r\n     * @returns a string containing the source code of the fragment shader associated with the program\r\n     */\r\n    public getFragmentShaderSource(program: WebGLProgram): Nullable<string> {\r\n        const shaders = this._gl.getAttachedShaders(program);\r\n\r\n        if (!shaders) {\r\n            return null;\r\n        }\r\n\r\n        return this._gl.getShaderSource(shaders[1]);\r\n    }\r\n\r\n    /**\r\n     * sets the object from which width and height will be taken from when getting render width and height\r\n     * Will fallback to the gl object\r\n     * @param dimensions the framebuffer width and height that will be used.\r\n     */\r\n    public override set framebufferDimensionsObject(dimensions: Nullable<{ framebufferWidth: number; framebufferHeight: number }>) {\r\n        this._framebufferDimensionsObject = dimensions;\r\n        if (this._framebufferDimensionsObject) {\r\n            this.onResizeObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    protected override _rebuildBuffers(): void {\r\n        // Index / Vertex\r\n        for (const scene of this.scenes) {\r\n            scene.resetCachedMaterial();\r\n            scene._rebuildGeometries();\r\n        }\r\n\r\n        for (const scene of this._virtualScenes) {\r\n            scene.resetCachedMaterial();\r\n            scene._rebuildGeometries();\r\n        }\r\n\r\n        super._rebuildBuffers();\r\n    }\r\n\r\n    /**\r\n     * Get Font size information\r\n     * @param font font name\r\n     * @returns an object containing ascent, height and descent\r\n     */\r\n    public override getFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n        return GetFontOffset(font);\r\n    }\r\n\r\n    /**\r\n     * Enters Pointerlock mode\r\n     */\r\n    public enterPointerlock(): void {\r\n        if (this._renderingCanvas) {\r\n            RequestPointerlock(this._renderingCanvas);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Exits Pointerlock mode\r\n     */\r\n    public exitPointerlock(): void {\r\n        ExitPointerlock();\r\n    }\r\n\r\n    /**\r\n     * Begin a new frame\r\n     */\r\n    public override beginFrame(): void {\r\n        this._measureFps();\r\n        super.beginFrame();\r\n    }\r\n\r\n    public override _deletePipelineContext(pipelineContext: IPipelineContext): void {\r\n        const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n        if (webGLPipelineContext && webGLPipelineContext.program) {\r\n            if (webGLPipelineContext.transformFeedback) {\r\n                this.deleteTransformFeedback(webGLPipelineContext.transformFeedback);\r\n                webGLPipelineContext.transformFeedback = null;\r\n            }\r\n        }\r\n        super._deletePipelineContext(pipelineContext);\r\n    }\r\n\r\n    public override createShaderProgram(\r\n        pipelineContext: IPipelineContext,\r\n        vertexCode: string,\r\n        fragmentCode: string,\r\n        defines: Nullable<string>,\r\n        context?: WebGLRenderingContext,\r\n        transformFeedbackVaryings: Nullable<string[]> = null\r\n    ): WebGLProgram {\r\n        context = context || this._gl;\r\n\r\n        this.onBeforeShaderCompilationObservable.notifyObservers(this);\r\n\r\n        const program = super.createShaderProgram(pipelineContext, vertexCode, fragmentCode, defines, context, transformFeedbackVaryings);\r\n        this.onAfterShaderCompilationObservable.notifyObservers(this);\r\n\r\n        return program;\r\n    }\r\n\r\n    protected override _createShaderProgram(\r\n        pipelineContext: WebGLPipelineContext,\r\n        vertexShader: WebGLShader,\r\n        fragmentShader: WebGLShader,\r\n        context: WebGLRenderingContext,\r\n        transformFeedbackVaryings: Nullable<string[]> = null\r\n    ): WebGLProgram {\r\n        const shaderProgram = context.createProgram();\r\n        pipelineContext.program = shaderProgram;\r\n\r\n        if (!shaderProgram) {\r\n            throw new Error(\"Unable to create program\");\r\n        }\r\n\r\n        context.attachShader(shaderProgram, vertexShader);\r\n        context.attachShader(shaderProgram, fragmentShader);\r\n\r\n        if (this.webGLVersion > 1 && transformFeedbackVaryings) {\r\n            const transformFeedback = this.createTransformFeedback();\r\n\r\n            this.bindTransformFeedback(transformFeedback);\r\n            this.setTranformFeedbackVaryings(shaderProgram, transformFeedbackVaryings);\r\n            pipelineContext.transformFeedback = transformFeedback;\r\n        }\r\n\r\n        context.linkProgram(shaderProgram);\r\n\r\n        if (this.webGLVersion > 1 && transformFeedbackVaryings) {\r\n            this.bindTransformFeedback(null);\r\n        }\r\n\r\n        pipelineContext.context = context;\r\n        pipelineContext.vertexShader = vertexShader;\r\n        pipelineContext.fragmentShader = fragmentShader;\r\n\r\n        if (!pipelineContext.isParallelCompiled) {\r\n            this._finalizePipelineContext(pipelineContext);\r\n        }\r\n\r\n        return shaderProgram;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _releaseTexture(texture: InternalTexture): void {\r\n        super._releaseTexture(texture);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _releaseRenderTargetWrapper(rtWrapper: RenderTargetWrapper): void {\r\n        super._releaseRenderTargetWrapper(rtWrapper);\r\n\r\n        // Set output texture of post process to null if the framebuffer has been released/disposed\r\n        for (const scene of this.scenes) {\r\n            for (const postProcess of scene.postProcesses) {\r\n                if (postProcess._outputTexture === rtWrapper) {\r\n                    postProcess._outputTexture = null;\r\n                }\r\n            }\r\n            for (const camera of scene.cameras) {\r\n                for (const postProcess of camera._postProcesses) {\r\n                    if (postProcess) {\r\n                        if (postProcess._outputTexture === rtWrapper) {\r\n                            postProcess._outputTexture = null;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Rescales a texture\r\n     * @param source input texture\r\n     * @param destination destination texture\r\n     * @param scene scene to use to render the resize\r\n     * @param internalFormat format to use when resizing\r\n     * @param onComplete callback to be called when resize has completed\r\n     */\r\n    public override _rescaleTexture(source: InternalTexture, destination: InternalTexture, scene: Nullable<any>, internalFormat: number, onComplete: () => void): void {\r\n        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, this._gl.LINEAR);\r\n        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, this._gl.LINEAR);\r\n        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);\r\n        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);\r\n\r\n        const rtt = this.createRenderTargetTexture(\r\n            {\r\n                width: destination.width,\r\n                height: destination.height,\r\n            },\r\n            {\r\n                generateMipMaps: false,\r\n                type: Constants.TEXTURETYPE_UNSIGNED_INT,\r\n                samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n                generateDepthBuffer: false,\r\n                generateStencilBuffer: false,\r\n            }\r\n        );\r\n\r\n        if (!this._rescalePostProcess && Engine._RescalePostProcessFactory) {\r\n            this._rescalePostProcess = Engine._RescalePostProcessFactory(this);\r\n        }\r\n\r\n        if (this._rescalePostProcess) {\r\n            this._rescalePostProcess.externalTextureSamplerBinding = true;\r\n            const onCompiled = () => {\r\n                this._rescalePostProcess!.onApply = function (effect) {\r\n                    effect._bindTexture(\"textureSampler\", source);\r\n                };\r\n\r\n                let hostingScene: Scene = scene;\r\n\r\n                if (!hostingScene) {\r\n                    hostingScene = this.scenes[this.scenes.length - 1];\r\n                }\r\n                hostingScene.postProcessManager.directRender([this._rescalePostProcess!], rtt, true);\r\n\r\n                this._bindTextureDirectly(this._gl.TEXTURE_2D, destination, true);\r\n                this._gl.copyTexImage2D(this._gl.TEXTURE_2D, 0, internalFormat, 0, 0, destination.width, destination.height, 0);\r\n\r\n                this.unBindFramebuffer(rtt);\r\n                rtt.dispose();\r\n\r\n                if (onComplete) {\r\n                    onComplete();\r\n                }\r\n            };\r\n            const effect = this._rescalePostProcess.getEffect();\r\n            if (effect) {\r\n                effect.executeWhenCompiled(onCompiled);\r\n            } else {\r\n                this._rescalePostProcess.onEffectCreatedObservable.addOnce((effect) => {\r\n                    effect.executeWhenCompiled(onCompiled);\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Wraps an external web gl texture in a Babylon texture.\r\n     * @param texture defines the external texture\r\n     * @param hasMipMaps defines whether the external texture has mip maps (default: false)\r\n     * @param samplingMode defines the sampling mode for the external texture (default: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE)\r\n     * @param width defines the width for the external texture (default: 0)\r\n     * @param height defines the height for the external texture (default: 0)\r\n     * @returns the babylon internal texture\r\n     */\r\n    public wrapWebGLTexture(\r\n        texture: WebGLTexture,\r\n        hasMipMaps: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        width: number = 0,\r\n        height: number = 0\r\n    ): InternalTexture {\r\n        const hardwareTexture = new WebGLHardwareTexture(texture, this._gl);\r\n        const internalTexture = new InternalTexture(this, InternalTextureSource.External, true);\r\n        internalTexture._hardwareTexture = hardwareTexture;\r\n        internalTexture.baseWidth = width;\r\n        internalTexture.baseHeight = height;\r\n        internalTexture.width = width;\r\n        internalTexture.height = height;\r\n        internalTexture.isReady = true;\r\n        internalTexture.useMipMaps = hasMipMaps;\r\n        this.updateTextureSamplingMode(samplingMode, internalTexture);\r\n        return internalTexture;\r\n    }\r\n\r\n    /**\r\n     * Replaces the underlying WebGL handle of a texture previously created via {@link wrapWebGLTexture}, preserving\r\n     * the InternalTexture identity.\r\n     *\r\n     * Intended for the context-loss / context-restored flow: when the host application recreates its external resource\r\n     * on the new WebGL context, it calls this method to repoint Babylon's wrapper at the new handle without losing\r\n     * references held by materials, render-target wrappers, particle systems, etc.\r\n     *\r\n     * The new handle must describe a texture with the same dimensions the wrapped texture was created with. A WebGL\r\n     * handle is opaque (the dimensions can't be introspected), so we can't validate this -- passing a mismatched\r\n     * handle is undefined behaviour. Sampling mode and mip-map flag are properties of the logical wrapped texture and\r\n     * are re-applied to the new resource. Any render-target wrapper holding this texture as its color attachment has\r\n     * its framebuffer rebuilt with the new handle (including a fresh depth/stencil renderbuffer, since the old one\r\n     * came from the dead context). If the wrapper is multisampled, the MSAA framebuffer + color renderbuffer + MSAA\r\n     * depth/stencil buffer are rebuilt too.\r\n     *\r\n     * Throws if the target was not produced by {@link wrapWebGLTexture}, if the wrapped texture is part of a multi\r\n     * render-target wrapper, or if the wrapper has a depth/stencil texture (these are not supported in this version;\r\n     * dispose and re-wrap).\r\n     * @param internalTexture defines the wrapped InternalTexture to repoint\r\n     * @param texture defines the new WebGL handle to wrap\r\n     */\r\n    public updateWrappedWebGLTexture(internalTexture: InternalTexture, texture: WebGLTexture): void {\r\n        if (internalTexture.source !== InternalTextureSource.External) {\r\n            throw new Error(\"updateWrappedWebGLTexture: target InternalTexture was not produced by wrapWebGLTexture.\");\r\n        }\r\n\r\n        // Pre-validate before mutating any state so a thrown precondition leaves the InternalTexture untouched.\r\n        // Note: rtWrapper.texture only returns _textures[0]; walk every attachment to catch the multi-RT case where\r\n        // the wrapped texture is at index > 0.\r\n        for (const rtWrapper of this._renderTargetWrapperCache) {\r\n            if (!rtWrapper.textures?.includes(internalTexture)) {\r\n                continue;\r\n            }\r\n            if (rtWrapper.isMulti) {\r\n                throw new Error(\"updateWrappedWebGLTexture: wrapped texture is part of a multi render-target; not supported. Dispose and re-wrap.\");\r\n            }\r\n            if (rtWrapper._depthStencilTexture) {\r\n                // The depth/stencil texture's GL handle was also lost on context restore. Rebuilding it from the\r\n                // wrapper's stored depth settings + re-attaching is feasible but non-trivial; v1 rejects and asks\r\n                // the caller to dispose + re-wrap (which also recreates the depth/stencil texture via the public API).\r\n                throw new Error(\"updateWrappedWebGLTexture: wrapped texture's render-target wrapper has a depth/stencil texture; not supported. Dispose and re-wrap.\");\r\n            }\r\n        }\r\n\r\n        internalTexture._hardwareTexture = new WebGLHardwareTexture(texture, this._gl);\r\n        internalTexture.isReady = true;\r\n\r\n        // The new GL texture has default sampler state; clear the per-InternalTexture cached sampler params so the\r\n        // next _setTexture re-applies them, then drop any binding-cache slot pointing at this InternalTexture so the\r\n        // identity short-circuit (this._boundTexturesCache[channel] === internalTexture) doesn't skip the rebind.\r\n        internalTexture._cachedCoordinatesMode = null;\r\n        internalTexture._cachedWrapU = null;\r\n        internalTexture._cachedWrapV = null;\r\n        internalTexture._cachedWrapR = null;\r\n        internalTexture._cachedAnisotropicFilteringLevel = null;\r\n        for (const key in this._boundTexturesCache) {\r\n            if (this._boundTexturesCache[key] === internalTexture) {\r\n                this._boundTexturesCache[key] = null;\r\n            }\r\n        }\r\n\r\n        this.updateTextureSamplingMode(internalTexture.samplingMode, internalTexture);\r\n\r\n        // Rebuild the framebuffer of any render-target wrapper holding this wrapped texture as its color attachment.\r\n        // After a context-loss / restore cycle the GL framebuffer + depth/stencil renderbuffer came from the dead\r\n        // context; the consumer-supplied new texture is the moment we have a fresh handle to rebuild against.\r\n        const gl = this._gl;\r\n        for (const rtWrapper of this._renderTargetWrapperCache) {\r\n            if (rtWrapper.texture !== internalTexture) {\r\n                continue;\r\n            }\r\n            const webGLRtWrapper = rtWrapper as WebGLRenderTargetWrapper;\r\n            const savedSamples = rtWrapper.samples;\r\n            const isMSAA = savedSamples > 1;\r\n\r\n            if (webGLRtWrapper._framebuffer) {\r\n                gl.deleteFramebuffer(webGLRtWrapper._framebuffer);\r\n            }\r\n            if (!isMSAA && webGLRtWrapper._depthStencilBuffer) {\r\n                gl.deleteRenderbuffer(webGLRtWrapper._depthStencilBuffer);\r\n                webGLRtWrapper._depthStencilBuffer = null;\r\n            }\r\n\r\n            const previousFramebuffer = this._currentFramebuffer;\r\n            const framebuffer = gl.createFramebuffer();\r\n            this._bindUnboundFramebuffer(framebuffer);\r\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n            if (!isMSAA) {\r\n                webGLRtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(\r\n                    rtWrapper._generateStencilBuffer,\r\n                    rtWrapper._generateDepthBuffer,\r\n                    rtWrapper.width,\r\n                    rtWrapper.height\r\n                );\r\n            }\r\n            this._bindUnboundFramebuffer(previousFramebuffer);\r\n            webGLRtWrapper._framebuffer = framebuffer;\r\n\r\n            if (isMSAA) {\r\n                // Defer MSAA framebuffer + color renderbuffer + multisampled depth/stencil rebuild to the existing\r\n                // helper. The helper early-returns when samples matches the cached value, so zero the cache first\r\n                // to force the work; updateRenderTargetTextureSampleCount restores _samples to savedSamples.\r\n                rtWrapper._samples = 1;\r\n                this.updateRenderTargetTextureSampleCount(webGLRtWrapper, savedSamples);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement | ImageBitmap, faceIndex: number = 0, lod: number = 0) {\r\n        const gl = this._gl;\r\n\r\n        const textureType = this._getWebGLTextureType(texture.type);\r\n        const format = this._getInternalFormat(texture.format);\r\n        const internalFormat = this._getRGBABufferInternalSizedFormat(texture.type, format);\r\n\r\n        const bindTarget = texture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\r\n\r\n        this._bindTextureDirectly(bindTarget, texture, true);\r\n        this._unpackFlipY(texture.invertY);\r\n\r\n        let target: GLenum = gl.TEXTURE_2D;\r\n        if (texture.isCube) {\r\n            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;\r\n        }\r\n\r\n        gl.texImage2D(target, lod, internalFormat, format, textureType, image);\r\n        this._bindTextureDirectly(bindTarget, null, true);\r\n    }\r\n\r\n    /**\r\n     * Updates a depth texture Comparison Mode and Function.\r\n     * If the comparison Function is equal to 0, the mode will be set to none.\r\n     * Otherwise, this only works in webgl 2 and requires a shadow sampler in the shader.\r\n     * @param texture The texture to set the comparison function for\r\n     * @param comparisonFunction The comparison function to set, 0 if no comparison required\r\n     */\r\n    public updateTextureComparisonFunction(texture: InternalTexture, comparisonFunction: number): void {\r\n        if (this.webGLVersion === 1) {\r\n            Logger.Error(\"WebGL 1 does not support texture comparison.\");\r\n            return;\r\n        }\r\n\r\n        const gl = this._gl;\r\n\r\n        if (texture.isCube) {\r\n            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);\r\n\r\n            if (comparisonFunction === 0) {\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, Constants.LEQUAL);\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.NONE);\r\n            } else {\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);\r\n            }\r\n\r\n            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);\r\n        } else {\r\n            this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);\r\n\r\n            if (comparisonFunction === 0) {\r\n                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, Constants.LEQUAL);\r\n                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.NONE);\r\n            } else {\r\n                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);\r\n                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);\r\n            }\r\n\r\n            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n        }\r\n\r\n        texture._comparisonFunction = comparisonFunction;\r\n    }\r\n\r\n    /**\r\n     * Creates a webGL buffer to use with instantiation\r\n     * @param capacity defines the size of the buffer\r\n     * @returns the webGL buffer\r\n     */\r\n    public createInstancesBuffer(capacity: number): DataBuffer {\r\n        const buffer = this._gl.createBuffer();\r\n\r\n        if (!buffer) {\r\n            throw new Error(\"Unable to create instance buffer\");\r\n        }\r\n\r\n        const result = new WebGLDataBuffer(buffer);\r\n        result.capacity = capacity;\r\n\r\n        this.bindArrayBuffer(result);\r\n        this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);\r\n\r\n        result.references = 1;\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Delete a webGL buffer used with instantiation\r\n     * @param buffer defines the webGL buffer to delete\r\n     */\r\n    public deleteInstancesBuffer(buffer: WebGLBuffer): void {\r\n        this._gl.deleteBuffer(buffer);\r\n    }\r\n\r\n    private async _clientWaitAsync(sync: WebGLSync, flags = 0, intervalms = 10): Promise<void> {\r\n        const gl = <WebGL2RenderingContext>(this._gl as any);\r\n        return await new Promise((resolve, reject) => {\r\n            _RetryWithInterval(\r\n                () => {\r\n                    const res = gl.clientWaitSync(sync, flags, 0);\r\n                    if (res == gl.WAIT_FAILED) {\r\n                        throw new Error(\"clientWaitSync failed\");\r\n                    }\r\n                    if (res == gl.TIMEOUT_EXPIRED) {\r\n                        return false;\r\n                    }\r\n                    return true;\r\n                },\r\n                resolve,\r\n                reject,\r\n                intervalms\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * This function might return null synchronously, so it is technically not async.\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, outputBuffer: ArrayBufferView): Nullable<Promise<ArrayBufferView>> {\r\n        if (this._webGLVersion < 2) {\r\n            throw new Error(\"_readPixelsAsync only work on WebGL2+\");\r\n        }\r\n\r\n        const gl = <WebGL2RenderingContext>(this._gl as any);\r\n        const buf = gl.createBuffer();\r\n        gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf);\r\n        gl.bufferData(gl.PIXEL_PACK_BUFFER, outputBuffer.byteLength, gl.STREAM_READ);\r\n        gl.readPixels(x, y, w, h, format, type, 0);\r\n        gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);\r\n\r\n        const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\r\n        if (!sync) {\r\n            return null;\r\n        }\r\n\r\n        gl.flush();\r\n\r\n        // eslint-disable-next-line github/no-then\r\n        return this._clientWaitAsync(sync, 0, 10).then(() => {\r\n            gl.deleteSync(sync);\r\n\r\n            gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf);\r\n            gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, outputBuffer);\r\n            gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);\r\n            gl.deleteBuffer(buf);\r\n\r\n            return outputBuffer;\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.hideLoadingUI?.();\r\n\r\n        // Rescale PP\r\n        if (this._rescalePostProcess) {\r\n            this._rescalePostProcess.dispose();\r\n        }\r\n\r\n        _CommonDispose(this, this._renderingCanvas);\r\n\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ICreateSceneUboOptions, Scene } from \"../../scene.pure\";\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { TmpVectors, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { MultiviewRenderTarget } from \"../../Materials/Textures/MultiviewRenderTarget\";\r\nimport { Frustum } from \"../../Maths/math.frustum\";\r\nimport { type WebGLRenderTargetWrapper } from \"../WebGL/webGLRenderTargetWrapper\";\r\nimport { type RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { type AbstractEngine } from \"../abstractEngine.pure\";\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { Engine } from \"../../Engines/engine.pure\";\r\nimport { UniformBuffer } from \"../../Materials/uniformBuffer\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for engineMultiview.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEngineMultiview(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function CreateMultiviewUbo(engine: AbstractEngine, name?: string, trackUBOsInFrame?: boolean) {\r\n        const ubo = new UniformBuffer(engine, undefined, true, name, undefined, trackUBOsInFrame);\r\n        ubo.addUniform(\"viewProjection\", 16);\r\n        ubo.addUniform(\"viewProjectionR\", 16);\r\n        ubo.addUniform(\"view\", 16);\r\n        ubo.addUniform(\"projection\", 16);\r\n        ubo.addUniform(\"vEyePosition\", 4);\r\n        ubo.addUniform(\"inverseProjection\", 16);\r\n        return ubo;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const CurrentCreateSceneUniformBuffer = Scene.prototype.createSceneUniformBuffer;\r\n\r\n    Engine.prototype.createMultiviewRenderTargetTexture = function (width: number, height: number, colorTexture?: WebGLTexture, depthStencilTexture?: WebGLTexture) {\r\n        const gl = this._gl;\r\n\r\n        if (!this.getCaps().multiview) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Multiview is not supported\";\r\n        }\r\n\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, false, { width, height }) as WebGLRenderTargetWrapper;\r\n\r\n        rtWrapper._framebuffer = gl.createFramebuffer();\r\n\r\n        const internalTexture = new InternalTexture(this, InternalTextureSource.Unknown, true);\r\n        internalTexture.width = width;\r\n        internalTexture.height = height;\r\n        internalTexture.isMultiview = true;\r\n\r\n        if (!colorTexture) {\r\n            colorTexture = gl.createTexture();\r\n            gl.bindTexture(gl.TEXTURE_2D_ARRAY, colorTexture);\r\n            (gl as any).texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, 2);\r\n        }\r\n\r\n        rtWrapper._colorTextureArray = colorTexture;\r\n\r\n        if (!depthStencilTexture) {\r\n            depthStencilTexture = gl.createTexture();\r\n            gl.bindTexture(gl.TEXTURE_2D_ARRAY, depthStencilTexture);\r\n            (gl as any).texStorage3D(gl.TEXTURE_2D_ARRAY, 1, (gl as any).DEPTH24_STENCIL8, width, height, 2);\r\n        }\r\n\r\n        rtWrapper._depthStencilTextureArray = depthStencilTexture;\r\n\r\n        internalTexture.isReady = true;\r\n\r\n        rtWrapper.setTextures(internalTexture);\r\n        rtWrapper._depthStencilTexture = internalTexture;\r\n\r\n        return rtWrapper;\r\n    };\r\n\r\n    Engine.prototype.bindMultiviewFramebuffer = function (_multiviewTexture: RenderTargetWrapper) {\r\n        const multiviewTexture = _multiviewTexture as WebGLRenderTargetWrapper;\r\n\r\n        const gl: any = this._gl;\r\n        const ext = this.getCaps().oculusMultiview || this.getCaps().multiview;\r\n\r\n        this.bindFramebuffer(multiviewTexture, undefined, undefined, undefined, true);\r\n        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, multiviewTexture._framebuffer);\r\n        if (multiviewTexture._colorTextureArray && multiviewTexture._depthStencilTextureArray) {\r\n            if (this.getCaps().oculusMultiview) {\r\n                ext.framebufferTextureMultisampleMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, multiviewTexture.samples, 0, 2);\r\n                ext.framebufferTextureMultisampleMultiviewOVR(\r\n                    gl.DRAW_FRAMEBUFFER,\r\n                    gl.DEPTH_STENCIL_ATTACHMENT,\r\n                    multiviewTexture._depthStencilTextureArray,\r\n                    0,\r\n                    multiviewTexture.samples,\r\n                    0,\r\n                    2\r\n                );\r\n            } else {\r\n                ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, 0, 2);\r\n                ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, multiviewTexture._depthStencilTextureArray, 0, 0, 2);\r\n            }\r\n        } else {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Invalid multiview frame buffer\";\r\n        }\r\n    };\r\n\r\n    Engine.prototype.bindSpaceWarpFramebuffer = function (_spaceWarpTexture: RenderTargetWrapper) {\r\n        const spaceWarpTexture = _spaceWarpTexture as WebGLRenderTargetWrapper;\r\n\r\n        const gl: any = this._gl;\r\n        const ext = this.getCaps().oculusMultiview || this.getCaps().multiview;\r\n\r\n        this.bindFramebuffer(spaceWarpTexture, undefined, undefined, undefined, true);\r\n        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, spaceWarpTexture._framebuffer);\r\n        if (spaceWarpTexture._colorTextureArray && spaceWarpTexture._depthStencilTextureArray) {\r\n            ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, spaceWarpTexture._colorTextureArray, 0, 0, 2);\r\n            ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, spaceWarpTexture._depthStencilTextureArray, 0, 0, 2);\r\n        } else {\r\n            throw new Error(\"Invalid Space Warp framebuffer\");\r\n        }\r\n    };\r\n\r\n    Camera.prototype._useMultiviewToSingleView = false;\r\n\r\n    Camera.prototype._multiviewTexture = null;\r\n\r\n    Camera.prototype._resizeOrCreateMultiviewTexture = function (width: number, height: number) {\r\n        if (!this._multiviewTexture) {\r\n            this._multiviewTexture = new MultiviewRenderTarget(this.getScene(), { width: width, height: height });\r\n        } else if (this._multiviewTexture.getRenderWidth() != width || this._multiviewTexture.getRenderHeight() != height) {\r\n            this._multiviewTexture.dispose();\r\n            this._multiviewTexture = new MultiviewRenderTarget(this.getScene(), { width: width, height: height });\r\n        }\r\n    };\r\n\r\n    Scene.prototype._transformMatrixR = Matrix.Zero();\r\n\r\n    Scene.prototype._multiviewSceneUbo = null;\r\n\r\n    Scene.prototype._multiviewSceneUboIsActive = false;\r\n\r\n    Scene.prototype._createMultiviewUbo = function () {\r\n        this._multiviewSceneUbo = CreateMultiviewUbo(this.getEngine(), \"scene_multiview\");\r\n        this._multiviewSceneUboIsActive = true;\r\n    };\r\n\r\n    Scene.prototype.createSceneUniformBuffer = function (name?: string, trackUBOsInFrameOrOptions?: boolean | ICreateSceneUboOptions): UniformBuffer {\r\n        const forceMono = typeof trackUBOsInFrameOrOptions === \"object\" && !!trackUBOsInFrameOrOptions?.forceMono;\r\n        if (!forceMono && this._multiviewSceneUboIsActive) {\r\n            const trackUBOsInFrame = typeof trackUBOsInFrameOrOptions === \"boolean\" ? trackUBOsInFrameOrOptions : trackUBOsInFrameOrOptions?.trackUBOsInFrame;\r\n            return CreateMultiviewUbo(this.getEngine(), name, trackUBOsInFrame);\r\n        }\r\n        // Cast to implementation signature: .call() on overloaded functions resolves to the last overload in TypeScript,\r\n        // but the original implementation correctly handles boolean | ICreateSceneUboOptions | undefined.\r\n        return (CurrentCreateSceneUniformBuffer as (this: Scene, name?: string, trackUBOsInFrameOrOptions?: boolean | ICreateSceneUboOptions) => UniformBuffer).call(\r\n            this,\r\n            name,\r\n            trackUBOsInFrameOrOptions\r\n        );\r\n    };\r\n\r\n    Scene.prototype._updateMultiviewUbo = function (viewR?: Matrix, projectionR?: Matrix) {\r\n        if (viewR && projectionR) {\r\n            viewR.multiplyToRef(projectionR, this._transformMatrixR);\r\n        }\r\n\r\n        if (!this._inverseProjectionMatrix) {\r\n            this._inverseProjectionMatrix = new Matrix();\r\n        }\r\n        this._projectionMatrix.invertToRef(this._inverseProjectionMatrix);\r\n\r\n        if (viewR && projectionR) {\r\n            viewR.multiplyToRef(projectionR, TmpVectors.Matrix[0]);\r\n            Frustum.GetRightPlaneToRef(TmpVectors.Matrix[0], this._frustumPlanes[3]); // Replace right plane by second camera right plane\r\n        }\r\n\r\n        if (this._multiviewSceneUbo) {\r\n            this._multiviewSceneUbo.updateMatrix(\"viewProjection\", this.getTransformMatrix());\r\n            this._multiviewSceneUbo.updateMatrix(\"viewProjectionR\", this._transformMatrixR);\r\n            this._multiviewSceneUbo.updateMatrix(\"view\", this._viewMatrix);\r\n            this._multiviewSceneUbo.updateMatrix(\"projection\", this._projectionMatrix);\r\n            this._multiviewSceneUbo.updateMatrix(\"inverseProjection\", this._inverseProjectionMatrix);\r\n        }\r\n    };\r\n\r\n    Scene.prototype._renderMultiviewToSingleView = function (camera: Camera) {\r\n        // Multiview is only able to be displayed directly for API's such as webXR\r\n        // This displays a multiview image by rendering to the multiview image and then\r\n        // copying the result into the sub cameras instead of rendering them and proceeding as normal from there\r\n\r\n        // Render to a multiview texture\r\n        camera._resizeOrCreateMultiviewTexture(\r\n            camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.width > 0 ? camera._rigPostProcess.width : this.getEngine().getRenderWidth(true),\r\n            camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.height > 0 ? camera._rigPostProcess.height : this.getEngine().getRenderHeight(true)\r\n        );\r\n        if (!this._multiviewSceneUbo) {\r\n            this._createMultiviewUbo();\r\n        }\r\n        camera.outputRenderTarget = camera._multiviewTexture;\r\n        this._renderForCamera(camera);\r\n        camera.outputRenderTarget = null;\r\n\r\n        // Consume the multiview texture through a shader for each eye\r\n        for (let index = 0; index < camera._rigCameras.length; index++) {\r\n            const engine = this.getEngine();\r\n            this._activeCamera = camera._rigCameras[index];\r\n            engine.setViewport(this._activeCamera.viewport);\r\n            if (this.postProcessManager) {\r\n                this.postProcessManager._prepareFrame();\r\n                this.postProcessManager._finalizeFrame(this._activeCamera.isIntermediate);\r\n            }\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { RegisterEngineMultiview } from \"../Engines/Extensions/engine.multiview.pure\";\r\n\r\n/**\r\n * VRMultiviewToSingleview used to convert multiview texture arrays to standard textures for scenarios such as webVR\r\n * This will not be used for webXR as it supports displaying texture arrays directly\r\n */\r\nexport class VRMultiviewToSingleviewPostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"VRMultiviewToSingleviewPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VRMultiviewToSingleviewPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Initializes a VRMultiviewToSingleview\r\n     * @param name name of the post process\r\n     * @param camera camera to be applied to\r\n     * @param scaleFactor scaling factor to the size of the output texture\r\n     */\r\n    constructor(name: string, camera: Nullable<Camera>, scaleFactor: number) {\r\n        super(name, \"vrMultiviewToSingleview\", [\"imageIndex\"], [\"multiviewSampler\"], scaleFactor, camera, Texture.BILINEAR_SAMPLINGMODE);\r\n\r\n        RegisterEngineMultiview();\r\n\r\n        const cam = camera ?? this.getCamera();\r\n        this.onSizeChangedObservable.add(() => {});\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            if (cam._scene.activeCamera && cam._scene.activeCamera.isLeftCamera) {\r\n                effect.setInt(\"imageIndex\", 0);\r\n            } else {\r\n                effect.setInt(\"imageIndex\", 1);\r\n            }\r\n            effect.setTexture(\"multiviewSampler\", cam._multiviewTexture);\r\n        });\r\n    }\r\n}\r\n","import { type Camera } from \"../camera\";\r\nimport { Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { VRDistortionCorrectionPostProcess } from \"../../PostProcesses/vrDistortionCorrectionPostProcess\";\r\nimport { VRMultiviewToSingleviewPostProcess } from \"../../PostProcesses/vrMultiviewToSingleviewPostProcess.pure\";\r\nimport { VRCameraMetrics } from \"../VR/vrCameraMetrics\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Viewport } from \"../../Maths/math.viewport\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _SetVrRigMode(camera: Camera, rigParams: any) {\r\n    const metrics = <VRCameraMetrics>rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();\r\n\r\n    camera._rigCameras[0]._cameraRigParams.vrMetrics = metrics;\r\n    camera._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);\r\n    camera._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();\r\n    camera._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;\r\n    camera._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;\r\n    camera._rigCameras[0].getProjectionMatrix = camera._rigCameras[0]._getVRProjectionMatrix;\r\n\r\n    camera._rigCameras[1]._cameraRigParams.vrMetrics = metrics;\r\n    camera._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);\r\n    camera._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();\r\n    camera._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;\r\n    camera._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;\r\n    camera._rigCameras[1].getProjectionMatrix = camera._rigCameras[1]._getVRProjectionMatrix;\r\n\r\n    // For multiview camera\r\n    // First multiview will be rendered to camera._multiviewTexture\r\n    // Then this postprocess will run on each eye to copy the right texture to each eye\r\n    if (metrics.multiviewEnabled) {\r\n        if (!camera.getScene().getEngine().getCaps().multiview) {\r\n            Logger.Warn(\"Multiview is not supported, falling back to standard rendering\");\r\n            metrics.multiviewEnabled = false;\r\n        } else {\r\n            camera._useMultiviewToSingleView = true;\r\n            camera._rigPostProcess = new VRMultiviewToSingleviewPostProcess(\"VRMultiviewToSingleview\", camera, metrics.postProcessScaleFactor);\r\n        }\r\n    }\r\n\r\n    if (metrics.compensateDistortion) {\r\n        camera._rigCameras[0]._rigPostProcess = new VRDistortionCorrectionPostProcess(\"VR_Distort_Compensation_Left\", camera._rigCameras[0], false, metrics);\r\n        camera._rigCameras[1]._rigPostProcess = new VRDistortionCorrectionPostProcess(\"VR_Distort_Compensation_Right\", camera._rigCameras[1], true, metrics);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { ArcRotateCamera } from \"../../Cameras/arcRotateCamera.pure\";\r\nimport { VRCameraMetrics } from \"./vrCameraMetrics\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetVrRigMode } from \"../RigModes/vrRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate VR rendering (based on ArcRotateCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#vr-device-orientation-cameras\r\n */\r\nexport class VRDeviceOrientationArcRotateCamera extends ArcRotateCamera {\r\n    /**\r\n     * Creates a new VRDeviceOrientationArcRotateCamera\r\n     * @param name defines camera name\r\n     * @param alpha defines the camera rotation along the longitudinal axis\r\n     * @param beta defines the camera rotation along the latitudinal axis\r\n     * @param radius defines the camera distance from its target\r\n     * @param target defines the camera target\r\n     * @param scene defines the scene the camera belongs to\r\n     * @param compensateDistortion defines if the camera needs to compensate the lens distortion\r\n     * @param vrCameraMetrics defines the vr metrics associated to the camera\r\n     */\r\n    constructor(\r\n        name: string,\r\n        alpha: number,\r\n        beta: number,\r\n        radius: number,\r\n        target: Vector3,\r\n        scene?: Scene,\r\n        compensateDistortion = true,\r\n        vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault()\r\n    ) {\r\n        super(name, alpha, beta, radius, target, scene);\r\n\r\n        vrCameraMetrics.compensateDistortion = compensateDistortion;\r\n        this.setCameraRigMode(Camera.RIG_MODE_VR, { vrCameraMetrics: vrCameraMetrics });\r\n\r\n        this.inputs.addVRDeviceOrientation();\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns VRDeviceOrientationArcRotateCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VRDeviceOrientationArcRotateCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = (rigParams: any) => _SetVrRigMode(this, rigParams);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vrDeviceOrientationArcRotateCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVrDeviceOrientationArcRotateCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"VRDeviceOrientationArcRotateCamera\", (name, scene) => {\r\n        return () => new VRDeviceOrientationArcRotateCamera(name, 0, 0, 1.0, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { DeviceOrientationCamera } from \"../../Cameras/deviceOrientationCamera.pure\";\r\nimport { VRCameraMetrics } from \"./vrCameraMetrics\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetVrRigMode } from \"../RigModes/vrRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate VR rendering (based on FreeCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#vr-device-orientation-cameras\r\n */\r\nexport class VRDeviceOrientationFreeCamera extends DeviceOrientationCamera {\r\n    /**\r\n     * Creates a new VRDeviceOrientationFreeCamera\r\n     * @param name defines camera name\r\n     * @param position defines the start position of the camera\r\n     * @param scene defines the scene the camera belongs to\r\n     * @param compensateDistortion defines if the camera needs to compensate the lens distortion\r\n     * @param vrCameraMetrics defines the vr metrics associated to the camera\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, compensateDistortion = true, vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault()) {\r\n        super(name, position, scene);\r\n\r\n        vrCameraMetrics.compensateDistortion = compensateDistortion;\r\n        this.setCameraRigMode(Camera.RIG_MODE_VR, { vrCameraMetrics: vrCameraMetrics });\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns VRDeviceOrientationFreeCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VRDeviceOrientationFreeCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = (rigParams: any) => _SetVrRigMode(this, rigParams);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vrDeviceOrientationFreeCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVrDeviceOrientationFreeCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"VRDeviceOrientationFreeCamera\", (name, scene) => {\r\n        return () => new VRDeviceOrientationFreeCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { VRDeviceOrientationFreeCamera } from \"./vrDeviceOrientationFreeCamera.pure\";\r\nimport { VRCameraMetrics } from \"./vrCameraMetrics\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { _SetVrRigMode } from \"../RigModes/vrRigMode\";\r\nimport { Node } from \"../../node\";\r\n\r\n/**\r\n * Camera used to simulate VR rendering (based on VRDeviceOrientationFreeCamera)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#vr-device-orientation-cameras\r\n */\r\nexport class VRDeviceOrientationGamepadCamera extends VRDeviceOrientationFreeCamera {\r\n    /**\r\n     * Creates a new VRDeviceOrientationGamepadCamera\r\n     * @param name defines camera name\r\n     * @param position defines the start position of the camera\r\n     * @param scene defines the scene the camera belongs to\r\n     * @param compensateDistortion defines if the camera needs to compensate the lens distortion\r\n     * @param vrCameraMetrics defines the vr metrics associated to the camera\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, compensateDistortion = true, vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault()) {\r\n        super(name, position, scene, compensateDistortion, vrCameraMetrics);\r\n\r\n        this.inputs.addGamepad();\r\n    }\r\n\r\n    /**\r\n     * Gets camera class name\r\n     * @returns VRDeviceOrientationGamepadCamera\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VRDeviceOrientationGamepadCamera\";\r\n    }\r\n\r\n    protected override _setRigMode = (rigParams: any) => _SetVrRigMode(this, rigParams);\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vrDeviceOrientationGamepadCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVrDeviceOrientationGamepadCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"VRDeviceOrientationGamepadCamera\", (name, scene) => {\r\n        return () => new VRDeviceOrientationGamepadCamera(name, Vector3.Zero(), scene);\r\n    });\r\n}\r\n","import { type Matrix } from \"../Maths/math.vector\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * Configuration needed for prepass-capable materials\r\n */\r\nexport class PrePassConfiguration {\r\n    /**\r\n     * Previous world matrices of meshes carrying this material\r\n     * Used for computing velocity\r\n     */\r\n    public previousWorldMatrices: { [index: number]: Matrix } = {};\r\n    /**\r\n     * Previous view project matrix\r\n     * Used for computing velocity\r\n     */\r\n    public previousViewProjection: Matrix;\r\n    /**\r\n     * Current view projection matrix\r\n     * Used for computing velocity\r\n     */\r\n    public currentViewProjection: Matrix;\r\n    /**\r\n     * Previous bones of meshes carrying this material\r\n     * Used for computing velocity\r\n     */\r\n    public previousBones: { [index: number]: Float32Array } = {};\r\n\r\n    private _lastUpdateFrameId: number;\r\n\r\n    /**\r\n     * Add the required uniforms to the current list.\r\n     * @param uniforms defines the current uniform list.\r\n     */\r\n    public static AddUniforms(uniforms: string[]): void {\r\n        uniforms.push(\"previousWorld\", \"previousViewProjection\", \"mPreviousBones\");\r\n    }\r\n\r\n    /**\r\n     * Add the required samplers to the current list.\r\n     * @param samplers defines the current sampler list.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static AddSamplers(samplers: string[]): void {\r\n        // pass\r\n    }\r\n\r\n    /**\r\n     * Binds the material data.\r\n     * @param effect defines the effect to update\r\n     * @param scene defines the scene the material belongs to.\r\n     * @param mesh The mesh\r\n     * @param world World matrix of this mesh\r\n     * @param isFrozen Is the material frozen\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public bindForSubMesh(effect: Effect, scene: Scene, mesh: Mesh, world: Matrix, isFrozen: boolean): void {\r\n        if (scene.prePassRenderer && scene.prePassRenderer.enabled && scene.prePassRenderer.currentRTisSceneRT) {\r\n            if (\r\n                scene.prePassRenderer.getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE) !== -1 ||\r\n                scene.prePassRenderer.getIndex(Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE) !== -1\r\n            ) {\r\n                if (!this.previousWorldMatrices[mesh.uniqueId]) {\r\n                    this.previousWorldMatrices[mesh.uniqueId] = world.clone();\r\n                }\r\n\r\n                if (!this.previousViewProjection) {\r\n                    this.previousViewProjection = scene.getTransformMatrix().clone();\r\n                    this.currentViewProjection = scene.getTransformMatrix().clone();\r\n                }\r\n\r\n                const engine = scene.getEngine();\r\n\r\n                if (this.currentViewProjection.updateFlag !== scene.getTransformMatrix().updateFlag) {\r\n                    // First update of the prepass configuration for this rendering pass\r\n                    this._lastUpdateFrameId = engine.frameId;\r\n                    this.previousViewProjection.copyFrom(this.currentViewProjection);\r\n                    this.currentViewProjection.copyFrom(scene.getTransformMatrix());\r\n                } else if (this._lastUpdateFrameId !== engine.frameId) {\r\n                    // The scene transformation did not change from the previous frame (so no camera motion), we must update previousViewProjection accordingly\r\n                    this._lastUpdateFrameId = engine.frameId;\r\n                    this.previousViewProjection.copyFrom(this.currentViewProjection);\r\n                }\r\n\r\n                effect.setMatrix(\"previousWorld\", this.previousWorldMatrices[mesh.uniqueId]);\r\n                effect.setMatrix(\"previousViewProjection\", this.previousViewProjection);\r\n\r\n                this.previousWorldMatrices[mesh.uniqueId] = world.clone();\r\n            }\r\n        }\r\n    }\r\n}\r\n","/**\r\n * Manages the defines for the Material\r\n */\r\nexport class MaterialDefines {\r\n    public VERTEXOUTPUT_INVARIANT = false;\r\n\r\n    /** @internal */\r\n    protected _keys: string[] = [];\r\n    private _isDirty = true;\r\n    /** @internal */\r\n    public _renderId: number;\r\n\r\n    /** @internal */\r\n    public _areLightsDirty = true;\r\n    /** @internal */\r\n    public _areLightsDisposed = false;\r\n    /** @internal */\r\n    public _areAttributesDirty = true;\r\n    /** @internal */\r\n    public _areTexturesDirty = true;\r\n    /** @internal */\r\n    public _areFresnelDirty = true;\r\n    /** @internal */\r\n    public _areMiscDirty = true;\r\n    /** @internal */\r\n    public _arePrePassDirty = true;\r\n    /** @internal */\r\n    public _areImageProcessingDirty = true;\r\n\r\n    /** @internal */\r\n    public _normals = false;\r\n    /** @internal */\r\n    public _uvs = false;\r\n\r\n    /** @internal */\r\n    public _needNormals = false;\r\n    /** @internal */\r\n    public _needUVs = false;\r\n\r\n    protected _externalProperties?: { [name: string]: { type: string; default: any } };\r\n\r\n    [id: string]: any;\r\n\r\n    /**\r\n     * Creates a new instance\r\n     * @param externalProperties list of external properties to inject into the object\r\n     */\r\n    constructor(externalProperties?: { [name: string]: { type: string; default: any } }) {\r\n        this._externalProperties = externalProperties;\r\n\r\n        // Initialize External Properties\r\n        if (externalProperties) {\r\n            for (const prop in externalProperties) {\r\n                if (Object.prototype.hasOwnProperty.call(externalProperties, prop)) {\r\n                    this._setDefaultValue(prop);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material needs to be re-calculated\r\n     */\r\n    public get isDirty(): boolean {\r\n        return this._isDirty;\r\n    }\r\n\r\n    /**\r\n     * Marks the material to indicate that it has been re-calculated\r\n     */\r\n    public markAsProcessed() {\r\n        this._isDirty = false;\r\n        this._areAttributesDirty = false;\r\n        this._areTexturesDirty = false;\r\n        this._areFresnelDirty = false;\r\n        this._areLightsDirty = false;\r\n        this._areLightsDisposed = false;\r\n        this._areMiscDirty = false;\r\n        this._arePrePassDirty = false;\r\n        this._areImageProcessingDirty = false;\r\n    }\r\n\r\n    /**\r\n     * Marks the material to indicate that it needs to be re-calculated\r\n     */\r\n    public markAsUnprocessed() {\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the material to indicate all of its defines need to be re-calculated\r\n     */\r\n    public markAllAsDirty() {\r\n        this._areTexturesDirty = true;\r\n        this._areAttributesDirty = true;\r\n        this._areLightsDirty = true;\r\n        this._areFresnelDirty = true;\r\n        this._areMiscDirty = true;\r\n        this._arePrePassDirty = true;\r\n        this._areImageProcessingDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the material to indicate that image processing needs to be re-calculated\r\n     */\r\n    public markAsImageProcessingDirty() {\r\n        this._areImageProcessingDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the material to indicate the lights need to be re-calculated\r\n     * @param disposed Defines whether the light is dirty due to dispose or not\r\n     */\r\n    public markAsLightDirty(disposed = false) {\r\n        this._areLightsDirty = true;\r\n        this._areLightsDisposed = this._areLightsDisposed || disposed;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the attribute state as changed\r\n     */\r\n    public markAsAttributesDirty() {\r\n        this._areAttributesDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the texture state as changed\r\n     */\r\n    public markAsTexturesDirty() {\r\n        this._areTexturesDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the fresnel state as changed\r\n     */\r\n    public markAsFresnelDirty() {\r\n        this._areFresnelDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the misc state as changed\r\n     */\r\n    public markAsMiscDirty() {\r\n        this._areMiscDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Marks the prepass state as changed\r\n     */\r\n    public markAsPrePassDirty() {\r\n        this._arePrePassDirty = true;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the material defines\r\n     */\r\n    public rebuild() {\r\n        this._keys.length = 0;\r\n\r\n        for (const key of Object.keys(this)) {\r\n            if (key[0] === \"_\") {\r\n                continue;\r\n            }\r\n\r\n            this._keys.push(key);\r\n        }\r\n\r\n        if (this._externalProperties) {\r\n            for (const name in this._externalProperties) {\r\n                if (this._keys.indexOf(name) === -1) {\r\n                    this._keys.push(name);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Specifies if two material defines are equal\r\n     * @param other - A material define instance to compare to\r\n     * @returns - Boolean indicating if the material defines are equal (true) or not (false)\r\n     */\r\n    public isEqual(other: MaterialDefines): boolean {\r\n        if (this._keys.length !== other._keys.length) {\r\n            return false;\r\n        }\r\n\r\n        for (let index = 0; index < this._keys.length; index++) {\r\n            const prop = this._keys[index];\r\n\r\n            if ((<any>this)[prop] !== (<any>other)[prop]) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Clones this instance's defines to another instance\r\n     * @param other - material defines to clone values to\r\n     */\r\n    public cloneTo(other: MaterialDefines): void {\r\n        if (this._keys.length !== other._keys.length) {\r\n            other._keys = this._keys.slice(0);\r\n        }\r\n\r\n        for (let index = 0; index < this._keys.length; index++) {\r\n            const prop = this._keys[index];\r\n\r\n            (<any>other)[prop] = (<any>this)[prop];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the material define values\r\n     */\r\n    public reset(): void {\r\n        for (const prop of this._keys) {\r\n            this._setDefaultValue(prop);\r\n        }\r\n    }\r\n\r\n    private _setDefaultValue(prop: string): void {\r\n        const type = this._externalProperties?.[prop]?.type ?? typeof (<any>this)[prop];\r\n        const defValue = this._externalProperties?.[prop]?.default;\r\n\r\n        switch (type) {\r\n            case \"number\":\r\n                (<any>this)[prop] = defValue ?? 0;\r\n                break;\r\n            case \"string\":\r\n                (<any>this)[prop] = defValue ?? \"\";\r\n                break;\r\n            default:\r\n                (<any>this)[prop] = defValue ?? false;\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Converts the material define values to a string\r\n     * @returns - String of material define information\r\n     */\r\n    public toString(): string {\r\n        let result = \"\";\r\n        for (let index = 0; index < this._keys.length; index++) {\r\n            const prop = this._keys[index];\r\n            const value = (<any>this)[prop];\r\n            const type = typeof value;\r\n\r\n            switch (type) {\r\n                case \"number\":\r\n                case \"string\":\r\n                    result += \"#define \" + prop + \" \" + value + \"\\n\";\r\n                    break;\r\n                default:\r\n                    if (value) {\r\n                        result += \"#define \" + prop + \"\\n\";\r\n                    }\r\n                    break;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n","import { MaterialDefines } from \"./materialDefines\";\r\n/**\r\n * Interface to follow in your material defines to integrate easily the\r\n * Image processing functions.\r\n * @internal\r\n */\r\nexport interface IImageProcessingConfigurationDefines {\r\n    IMAGEPROCESSING: boolean;\r\n    WHITEBALANCE: boolean;\r\n    VIGNETTE: boolean;\r\n    VIGNETTEBLENDMODEMULTIPLY: boolean;\r\n    VIGNETTEBLENDMODEOPAQUE: boolean;\r\n    TONEMAPPING: number;\r\n    CONTRAST: boolean;\r\n    EXPOSURE: boolean;\r\n    COLORCURVES: boolean;\r\n    COLORGRADING: boolean;\r\n    COLORGRADING3D: boolean;\r\n    SAMPLER3DGREENDEPTH: boolean;\r\n    SAMPLER3DBGRMAP: boolean;\r\n    DITHER: boolean;\r\n    IMAGEPROCESSINGPOSTPROCESS: boolean;\r\n    SKIPFINALCOLORCLAMP: boolean;\r\n}\r\n\r\ntype ImageProcessingDefinesMixinConstructor<T = {}> = new (...args: any[]) => T;\r\n\r\n/**\r\n * Mixin to add Image processing defines to your material defines\r\n * @internal\r\n */\r\nexport function ImageProcessingDefinesMixin<Tbase extends ImageProcessingDefinesMixinConstructor>(base: Tbase) {\r\n    return class extends base implements IImageProcessingConfigurationDefines {\r\n        // Implement all members of IImageProcessingConfigurationDefines here\r\n        public IMAGEPROCESSING = false;\r\n        public WHITEBALANCE = false;\r\n        public VIGNETTE = false;\r\n        public VIGNETTEBLENDMODEMULTIPLY = false;\r\n        public VIGNETTEBLENDMODEOPAQUE = false;\r\n        public TONEMAPPING = 0;\r\n        public CONTRAST = false;\r\n        public COLORCURVES = false;\r\n        public COLORGRADING = false;\r\n        public COLORGRADING3D = false;\r\n        public SAMPLER3DGREENDEPTH = false;\r\n        public SAMPLER3DBGRMAP = false;\r\n        public DITHER = false;\r\n        public IMAGEPROCESSINGPOSTPROCESS = false;\r\n        public SKIPFINALCOLORCLAMP = false;\r\n        public EXPOSURE = false;\r\n    };\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ImageProcessingConfigurationDefines extends MaterialDefines implements IImageProcessingConfigurationDefines {\r\n    public IMAGEPROCESSING = false;\r\n    public WHITEBALANCE = false;\r\n    public VIGNETTE = false;\r\n    public VIGNETTEBLENDMODEMULTIPLY = false;\r\n    public VIGNETTEBLENDMODEOPAQUE = false;\r\n    public TONEMAPPING = 0;\r\n    public CONTRAST = false;\r\n    public COLORCURVES = false;\r\n    public COLORGRADING = false;\r\n    public COLORGRADING3D = false;\r\n    public SAMPLER3DGREENDEPTH = false;\r\n    public SAMPLER3DBGRMAP = false;\r\n    public DITHER = false;\r\n    public IMAGEPROCESSINGPOSTPROCESS = false;\r\n    public EXPOSURE = false;\r\n    public SKIPFINALCOLORCLAMP = false;\r\n\r\n    constructor() {\r\n        super();\r\n        this.rebuild();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type _IProcessingOptions, type ShaderCustomProcessingFunction } from \"../Engines/Processors/shaderProcessingOptions\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Material } from \"./material.pure\";\r\nimport {\r\n    type MaterialPluginPrepareEffect,\r\n    type MaterialPluginBindForSubMesh,\r\n    type MaterialPluginDisposed,\r\n    type MaterialPluginGetActiveTextures,\r\n    type MaterialPluginGetAnimatables,\r\n    type MaterialPluginGetDefineNames,\r\n    type MaterialPluginHasTexture,\r\n    type MaterialPluginIsReadyForSubMesh,\r\n    type MaterialPluginPrepareDefines,\r\n    type MaterialPluginPrepareUniformBuffer,\r\n    type MaterialPluginHardBindForSubMesh,\r\n    type MaterialPluginHasRenderTargetTextures,\r\n    type MaterialPluginFillRenderTargetTextures,\r\n    MaterialPluginEvent,\r\n} from \"./materialPluginEvent\";\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type MaterialPluginBase } from \"./materialPluginBase.pure\";\r\nimport { ProcessIncludes } from \"../Engines/Processors/shaderProcessor\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { ShaderStore } from \"../Engines/shaderStore\";\r\n\r\nconst RxOption = /*#__PURE__*/ new RegExp(\"^([gimus]+)!\");\r\n\r\n/**\r\n * Class that manages the plugins of a material\r\n * @since 5.0\r\n */\r\nexport class MaterialPluginManager {\r\n    /** Map a plugin class name to a #define name (used in the vertex/fragment shaders as a marker of the plugin usage) */\r\n    private static _MaterialPluginClassToMainDefine: { [name: string]: string } = {};\r\n    private static _MaterialPluginCounter: number = 0;\r\n\r\n    protected _material: Material;\r\n    protected _scene: Scene;\r\n    protected _engine: AbstractEngine;\r\n    /** @internal */\r\n    public _plugins: MaterialPluginBase[] = [];\r\n    protected _activePlugins: MaterialPluginBase[] = [];\r\n    protected _activePluginsForExtraEvents: MaterialPluginBase[] = [];\r\n    protected _codeInjectionPoints: { [shaderType: string]: { [codeName: string]: boolean } };\r\n    protected _defineNamesFromPlugins?: { [name: string]: { type: string; default: any } };\r\n    protected _uboDeclaration: string;\r\n    protected _vertexDeclaration: string;\r\n    protected _fragmentDeclaration: string;\r\n    protected _uniformList: string[];\r\n    protected _samplerList: string[];\r\n    protected _uboList: string[];\r\n\r\n    /**\r\n     * Creates a new instance of the plugin manager\r\n     * @param material material that this manager will manage the plugins for\r\n     */\r\n    constructor(material: Material) {\r\n        this._material = material;\r\n        this._scene = material.getScene();\r\n        this._engine = this._scene.getEngine();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _addPlugin(plugin: MaterialPluginBase): boolean {\r\n        for (let i = 0; i < this._plugins.length; ++i) {\r\n            if (this._plugins[i].name === plugin.name) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (this._material._uniformBufferLayoutBuilt) {\r\n            this._material.resetDrawCache();\r\n            this._material._createUniformBuffer();\r\n        }\r\n\r\n        if (!plugin.isCompatible(this._material.shaderLanguage)) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw `The plugin \"${plugin.name}\" can't be added to the material \"${this._material.name}\" because the plugin is not compatible with the shader language of the material.`;\r\n        }\r\n\r\n        const pluginClassName = plugin.getClassName();\r\n        if (!MaterialPluginManager._MaterialPluginClassToMainDefine[pluginClassName]) {\r\n            MaterialPluginManager._MaterialPluginClassToMainDefine[pluginClassName] = \"MATERIALPLUGIN_\" + ++MaterialPluginManager._MaterialPluginCounter;\r\n        }\r\n\r\n        this._material._callbackPluginEventGeneric = (id, info) => this._handlePluginEvent(id, info);\r\n\r\n        this._plugins.push(plugin);\r\n        this._plugins.sort((a, b) => a.priority - b.priority);\r\n\r\n        this._codeInjectionPoints = {};\r\n\r\n        const defineNamesFromPlugins: { [name: string]: { type: string; default: any } } = {};\r\n        defineNamesFromPlugins[MaterialPluginManager._MaterialPluginClassToMainDefine[pluginClassName]] = {\r\n            type: \"boolean\",\r\n            default: true,\r\n        };\r\n\r\n        for (const plugin of this._plugins) {\r\n            plugin.collectDefines(defineNamesFromPlugins);\r\n            this._collectPointNames(\"vertex\", plugin.getCustomCode(\"vertex\", this._material.shaderLanguage));\r\n            this._collectPointNames(\"fragment\", plugin.getCustomCode(\"fragment\", this._material.shaderLanguage));\r\n        }\r\n\r\n        this._defineNamesFromPlugins = defineNamesFromPlugins;\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _activatePlugin(plugin: MaterialPluginBase): void {\r\n        if (this._activePlugins.indexOf(plugin) === -1) {\r\n            this._activePlugins.push(plugin);\r\n            this._activePlugins.sort((a, b) => a.priority - b.priority);\r\n\r\n            this._material._callbackPluginEventIsReadyForSubMesh = this._handlePluginEventIsReadyForSubMesh.bind(this);\r\n            this._material._callbackPluginEventPrepareDefinesBeforeAttributes = this._handlePluginEventPrepareDefinesBeforeAttributes.bind(this);\r\n            this._material._callbackPluginEventPrepareDefines = this._handlePluginEventPrepareDefines.bind(this);\r\n            this._material._callbackPluginEventBindForSubMesh = this._handlePluginEventBindForSubMesh.bind(this);\r\n\r\n            if (plugin.registerForExtraEvents) {\r\n                this._activePluginsForExtraEvents.push(plugin);\r\n                this._activePluginsForExtraEvents.sort((a, b) => a.priority - b.priority);\r\n                this._material._callbackPluginEventHasRenderTargetTextures = this._handlePluginEventHasRenderTargetTextures.bind(this);\r\n                this._material._callbackPluginEventFillRenderTargetTextures = this._handlePluginEventFillRenderTargetTextures.bind(this);\r\n                this._material._callbackPluginEventHardBindForSubMesh = this._handlePluginEventHardBindForSubMesh.bind(this);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a plugin from the list of plugins managed by this manager\r\n     * @param name name of the plugin\r\n     * @returns the plugin if found, else null\r\n     */\r\n    public getPlugin<T = MaterialPluginBase>(name: string): Nullable<T> {\r\n        for (let i = 0; i < this._plugins.length; ++i) {\r\n            if (this._plugins[i].name === name) {\r\n                return this._plugins[i] as T;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    protected _handlePluginEventIsReadyForSubMesh(eventData: MaterialPluginIsReadyForSubMesh): void {\r\n        let isReady = true;\r\n        for (const plugin of this._activePlugins) {\r\n            isReady = isReady && plugin.isReadyForSubMesh(eventData.defines, this._scene, this._engine, eventData.subMesh);\r\n        }\r\n        eventData.isReadyForSubMesh = isReady;\r\n    }\r\n\r\n    protected _handlePluginEventPrepareDefinesBeforeAttributes(eventData: MaterialPluginPrepareDefines): void {\r\n        for (const plugin of this._activePlugins) {\r\n            plugin.prepareDefinesBeforeAttributes(eventData.defines, this._scene, eventData.mesh);\r\n        }\r\n    }\r\n\r\n    protected _handlePluginEventPrepareDefines(eventData: MaterialPluginPrepareDefines): void {\r\n        for (const plugin of this._activePlugins) {\r\n            plugin.prepareDefines(eventData.defines, this._scene, eventData.mesh);\r\n        }\r\n    }\r\n\r\n    protected _handlePluginEventHardBindForSubMesh(eventData: MaterialPluginHardBindForSubMesh): void {\r\n        for (const plugin of this._activePluginsForExtraEvents) {\r\n            plugin.hardBindForSubMesh(this._material._uniformBuffer, this._scene, this._engine, eventData.subMesh);\r\n        }\r\n    }\r\n\r\n    protected _handlePluginEventBindForSubMesh(eventData: MaterialPluginBindForSubMesh): void {\r\n        for (const plugin of this._activePlugins) {\r\n            plugin.bindForSubMesh(this._material._uniformBuffer, this._scene, this._engine, eventData.subMesh);\r\n        }\r\n    }\r\n\r\n    protected _handlePluginEventHasRenderTargetTextures(eventData: MaterialPluginHasRenderTargetTextures): void {\r\n        let hasRenderTargetTextures = false;\r\n        for (const plugin of this._activePluginsForExtraEvents) {\r\n            hasRenderTargetTextures = plugin.hasRenderTargetTextures();\r\n            if (hasRenderTargetTextures) {\r\n                break;\r\n            }\r\n        }\r\n        eventData.hasRenderTargetTextures = hasRenderTargetTextures;\r\n    }\r\n\r\n    protected _handlePluginEventFillRenderTargetTextures(eventData: MaterialPluginFillRenderTargetTextures): void {\r\n        for (const plugin of this._activePluginsForExtraEvents) {\r\n            plugin.fillRenderTargetTextures(eventData.renderTargets);\r\n        }\r\n    }\r\n\r\n    protected _handlePluginEvent(\r\n        id: number,\r\n        info:\r\n            | MaterialPluginGetActiveTextures\r\n            | MaterialPluginGetAnimatables\r\n            | MaterialPluginHasTexture\r\n            | MaterialPluginDisposed\r\n            | MaterialPluginGetDefineNames\r\n            | MaterialPluginPrepareEffect\r\n            | MaterialPluginPrepareUniformBuffer\r\n    ): void {\r\n        switch (id) {\r\n            case MaterialPluginEvent.GetActiveTextures: {\r\n                const eventData = info as MaterialPluginGetActiveTextures;\r\n                for (const plugin of this._activePlugins) {\r\n                    plugin.getActiveTextures(eventData.activeTextures);\r\n                }\r\n                break;\r\n            }\r\n\r\n            case MaterialPluginEvent.GetAnimatables: {\r\n                const eventData = info as MaterialPluginGetAnimatables;\r\n                for (const plugin of this._activePlugins) {\r\n                    plugin.getAnimatables(eventData.animatables);\r\n                }\r\n                break;\r\n            }\r\n\r\n            case MaterialPluginEvent.HasTexture: {\r\n                const eventData = info as MaterialPluginHasTexture;\r\n                let hasTexture = false;\r\n                for (const plugin of this._activePlugins) {\r\n                    hasTexture = plugin.hasTexture(eventData.texture);\r\n                    if (hasTexture) {\r\n                        break;\r\n                    }\r\n                }\r\n                eventData.hasTexture = hasTexture;\r\n                break;\r\n            }\r\n\r\n            case MaterialPluginEvent.Disposed: {\r\n                const eventData = info as MaterialPluginDisposed;\r\n                for (const plugin of this._plugins) {\r\n                    plugin.dispose(eventData.forceDisposeTextures);\r\n                }\r\n                break;\r\n            }\r\n\r\n            case MaterialPluginEvent.GetDefineNames: {\r\n                const eventData = info as MaterialPluginGetDefineNames;\r\n                eventData.defineNames = this._defineNamesFromPlugins;\r\n                break;\r\n            }\r\n\r\n            case MaterialPluginEvent.PrepareEffect: {\r\n                const eventData = info as MaterialPluginPrepareEffect;\r\n                for (const plugin of this._activePlugins) {\r\n                    eventData.fallbackRank = plugin.addFallbacks(eventData.defines, eventData.fallbacks, eventData.fallbackRank);\r\n                    plugin.getAttributes(eventData.attributes, this._scene, eventData.mesh);\r\n                }\r\n                if (this._uniformList.length > 0) {\r\n                    eventData.uniforms.push(...this._uniformList);\r\n                }\r\n                if (this._samplerList.length > 0) {\r\n                    eventData.samplers.push(...this._samplerList);\r\n                }\r\n                if (this._uboList.length > 0) {\r\n                    eventData.uniformBuffersNames.push(...this._uboList);\r\n                }\r\n                eventData.customCode = this._injectCustomCode(eventData, eventData.customCode);\r\n                break;\r\n            }\r\n\r\n            case MaterialPluginEvent.PrepareUniformBuffer: {\r\n                const eventData = info as MaterialPluginPrepareUniformBuffer;\r\n                this._uboDeclaration = \"\";\r\n                this._vertexDeclaration = \"\";\r\n                this._fragmentDeclaration = \"\";\r\n                this._uniformList = [];\r\n                this._samplerList = [];\r\n                this._uboList = [];\r\n                const isWebGPU = this._material.shaderLanguage === ShaderLanguage.WGSL;\r\n                for (const plugin of this._plugins) {\r\n                    const uniforms = plugin.getUniforms(this._material.shaderLanguage);\r\n                    if (uniforms) {\r\n                        if (uniforms.ubo) {\r\n                            for (const uniform of uniforms.ubo) {\r\n                                if (uniform.size && uniform.type) {\r\n                                    const arraySize = uniform.arraySize ?? 0;\r\n                                    eventData.ubo.addUniform(uniform.name, uniform.size, arraySize);\r\n                                    if (isWebGPU) {\r\n                                        let type: string;\r\n                                        switch (uniform.type) {\r\n                                            case \"mat4\":\r\n                                                type = \"mat4x4f\";\r\n                                                break;\r\n                                            case \"float\":\r\n                                                type = \"f32\";\r\n                                                break;\r\n                                            default:\r\n                                                type = `${uniform.type}f`;\r\n                                                break;\r\n                                        }\r\n\r\n                                        if (arraySize > 0) {\r\n                                            this._uboDeclaration += `uniform ${uniform.name}: array<${type}, ${arraySize}>;\\n`;\r\n                                        } else {\r\n                                            this._uboDeclaration += `uniform ${uniform.name}: ${type};\\n`;\r\n                                        }\r\n                                    } else {\r\n                                        this._uboDeclaration += `${uniform.type} ${uniform.name}${arraySize > 0 ? `[${arraySize}]` : \"\"};\\n`;\r\n                                    }\r\n                                }\r\n                                this._uniformList.push(uniform.name);\r\n                            }\r\n                        }\r\n                        if (uniforms.vertex) {\r\n                            this._vertexDeclaration += uniforms.vertex + \"\\n\";\r\n                        }\r\n                        if (uniforms.fragment) {\r\n                            this._fragmentDeclaration += uniforms.fragment + \"\\n\";\r\n                        }\r\n\r\n                        // These are uniforms which are used by the shader but not updated by the plugin directly.\r\n                        // They still need to be present in the _uniformList so the Effect can determine their locations.\r\n                        if (uniforms.externalUniforms) {\r\n                            this._uniformList.push(...uniforms.externalUniforms);\r\n                        }\r\n                    }\r\n                    plugin.getSamplers(this._samplerList);\r\n                    plugin.getUniformBuffersNames(this._uboList);\r\n                }\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _collectPointNames(shaderType: string, customCode: Nullable<{ [pointName: string]: string }> | undefined): void {\r\n        if (!customCode) {\r\n            return;\r\n        }\r\n        for (const pointName in customCode) {\r\n            if (!this._codeInjectionPoints[shaderType]) {\r\n                this._codeInjectionPoints[shaderType] = {};\r\n            }\r\n            this._codeInjectionPoints[shaderType][pointName] = true;\r\n        }\r\n    }\r\n\r\n    protected _injectCustomCode(eventData: MaterialPluginPrepareEffect, existingCallback?: (shaderType: string, code: string) => string): ShaderCustomProcessingFunction {\r\n        return (shaderType: string, code: string) => {\r\n            if (existingCallback) {\r\n                code = existingCallback(shaderType, code);\r\n            }\r\n            if (this._uboDeclaration) {\r\n                code = code.replace(\"#define ADDITIONAL_UBO_DECLARATION\", this._uboDeclaration);\r\n            }\r\n            if (this._vertexDeclaration) {\r\n                code = code.replace(\"#define ADDITIONAL_VERTEX_DECLARATION\", this._vertexDeclaration);\r\n            }\r\n            if (this._fragmentDeclaration) {\r\n                code = code.replace(\"#define ADDITIONAL_FRAGMENT_DECLARATION\", this._fragmentDeclaration);\r\n            }\r\n            const points = this._codeInjectionPoints?.[shaderType];\r\n            if (!points) {\r\n                return code;\r\n            }\r\n            let processorOptions: Nullable<_IProcessingOptions> = null;\r\n            for (let pointName in points) {\r\n                let injectedCode = \"\";\r\n                for (const plugin of this._activePlugins) {\r\n                    const shaderLanguage = this._material.shaderLanguage;\r\n                    let customCode = plugin.getCustomCode(shaderType, shaderLanguage)?.[pointName];\r\n                    if (!customCode) {\r\n                        continue;\r\n                    }\r\n                    if (plugin.resolveIncludes) {\r\n                        if (processorOptions === null) {\r\n                            processorOptions = {\r\n                                defines: [], // not used by _ProcessIncludes\r\n                                indexParameters: eventData.indexParameters,\r\n                                isFragment: false,\r\n                                shouldUseHighPrecisionShader: this._engine._shouldUseHighPrecisionShader,\r\n                                processor: undefined as any, // not used by _ProcessIncludes\r\n                                supportsUniformBuffers: this._engine.supportsUniformBuffers,\r\n                                shadersRepository: ShaderStore.GetShadersRepository(shaderLanguage),\r\n                                includesShadersStore: ShaderStore.GetIncludesShadersStore(shaderLanguage),\r\n                                version: undefined as any, // not used by _ProcessIncludes\r\n                                platformName: this._engine.shaderPlatformName,\r\n                                processingContext: undefined as any, // not used by _ProcessIncludes\r\n                                isNDCHalfZRange: this._engine.isNDCHalfZRange,\r\n                                useReverseDepthBuffer: this._engine.useReverseDepthBuffer,\r\n                                processCodeAfterIncludes: undefined as any, // not used by _ProcessIncludes\r\n                            };\r\n                        }\r\n                        processorOptions.isFragment = shaderType === \"fragment\";\r\n                        ProcessIncludes(customCode, processorOptions, (code) => (customCode = code));\r\n                    }\r\n                    injectedCode += customCode + \"\\n\";\r\n                }\r\n                if (injectedCode.length > 0) {\r\n                    if (pointName.charAt(0) === \"!\") {\r\n                        // pointName is a regular expression\r\n                        pointName = pointName.substring(1);\r\n\r\n                        let regexFlags = \"g\";\r\n                        if (pointName.charAt(0) === \"!\") {\r\n                            // no flags\r\n                            regexFlags = \"\";\r\n                            pointName = pointName.substring(1);\r\n                        } else {\r\n                            // get the flag(s)\r\n                            const matchOption = RxOption.exec(pointName);\r\n                            if (matchOption && matchOption.length >= 2) {\r\n                                regexFlags = matchOption[1];\r\n                                pointName = pointName.substring(regexFlags.length + 1);\r\n                            }\r\n                        }\r\n\r\n                        if (regexFlags.indexOf(\"g\") < 0) {\r\n                            // we force the \"g\" flag so that the regexp object is stateful!\r\n                            regexFlags += \"g\";\r\n                        }\r\n\r\n                        const rx = new RegExp(pointName, regexFlags);\r\n                        let match = rx.exec(code);\r\n                        while (match !== null) {\r\n                            const { index } = match;\r\n                            const newCode = ReplaceRegExpSubstitutions(injectedCode, match);\r\n                            code = code.substring(0, index) + newCode + code.substring(index + match[0].length);\r\n                            rx.lastIndex = index + newCode.length;\r\n                            match = rx.exec(code);\r\n                        }\r\n                    } else {\r\n                        const fullPointName = \"#define \" + pointName;\r\n                        code = code.replace(fullPointName, \"\\n\" + injectedCode + \"\\n\" + fullPointName);\r\n                    }\r\n                }\r\n            }\r\n            return code;\r\n        };\r\n    }\r\n}\r\n\r\n/**\r\n * Type for plugin material factories.\r\n */\r\nexport type PluginMaterialFactory = (material: Material) => Nullable<MaterialPluginBase>;\r\n\r\nconst Plugins: Array<[string, PluginMaterialFactory]> = [];\r\nlet Inited = false;\r\nlet MaterialObserver: Nullable<Observer<Material>> = null;\r\nlet _MaterialPluginManagerRegistered = false;\r\n\r\n/**\r\n * Registers side effects for the material plugin manager.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialPluginManager(): void {\r\n    if (_MaterialPluginManagerRegistered) {\r\n        return;\r\n    }\r\n    _MaterialPluginManagerRegistered = true;\r\n\r\n    EngineStore.OnEnginesDisposedObservable.add(() => {\r\n        UnregisterAllMaterialPlugins();\r\n    });\r\n}\r\n\r\n/**\r\n * Registers a new material plugin through a factory, or updates it. This makes the plugin available to all materials instantiated after its registration.\r\n * Register side effects for materialPlugin.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param pluginName The plugin name\r\n * @param factory The factory function which allows to create the plugin\r\n */\r\nexport function RegisterMaterialPlugin(pluginName: string, factory: PluginMaterialFactory): void {\r\n    if (!Inited) {\r\n        MaterialObserver = Material.OnEventObservable.add((material: Material) => {\r\n            for (const [, factory] of Plugins) {\r\n                factory(material);\r\n            }\r\n        }, MaterialPluginEvent.Created);\r\n        Inited = true;\r\n    }\r\n    const existing = Plugins.filter(([name, _factory]) => name === pluginName);\r\n    if (existing.length > 0) {\r\n        existing[0][1] = factory;\r\n    } else {\r\n        Plugins.push([pluginName, factory]);\r\n    }\r\n}\r\n\r\n/**\r\n * Removes a material plugin from the list of global plugins.\r\n * @param pluginName The plugin name\r\n * @returns true if the plugin has been removed, else false\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function UnregisterMaterialPlugin(pluginName: string): boolean {\r\n    for (let i = 0; i < Plugins.length; ++i) {\r\n        if (Plugins[i][0] === pluginName) {\r\n            Plugins.splice(i, 1);\r\n            if (Plugins.length === 0) {\r\n                UnregisterAllMaterialPlugins();\r\n            }\r\n            return true;\r\n        }\r\n    }\r\n    return false;\r\n}\r\n\r\n/**\r\n * Clear the list of global material plugins\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function UnregisterAllMaterialPlugins(): void {\r\n    Plugins.length = 0;\r\n    Inited = false;\r\n    Material.OnEventObservable.remove(MaterialObserver);\r\n    MaterialObserver = null;\r\n}\r\n\r\n/**\r\n * Replace regex substitution patterns (e.g. $1, $2, etc.)\r\n * @param value The replacement string\r\n * @param match The regex match array\r\n * @returns Value having $X substitutions replaced with the equivalent `match[X]`\r\n */\r\nfunction ReplaceRegExpSubstitutions(value: string, match: ReadonlyArray<string>): string {\r\n    return value.replace(/\\$(\\d+)/g, (group0: string, group1: string): string => {\r\n        const index = Number(group1);\r\n        return index < match.length ? match[index] : \"\";\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { type Nullable } from \"../types\";\r\nimport { MaterialPluginManager } from \"./materialPluginManager.pure\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type EffectFallbacks } from \"./effectFallbacks\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { type Material } from \"./material.pure\";\r\nimport { type BaseTexture } from \"./Textures/baseTexture.pure\";\r\nimport { type RenderTargetTexture } from \"./Textures/renderTargetTexture.pure\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Base class for material plugins.\r\n * @since 5.0\r\n */\r\nexport class MaterialPluginBase {\r\n    /**\r\n     * Defines the name of the plugin\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * Defines the priority of the plugin. Lower numbers run first.\r\n     */\r\n    @serialize()\r\n    public priority: number = 500;\r\n\r\n    /**\r\n     * Indicates that any #include directive in the plugin code must be replaced by the corresponding code.\r\n     */\r\n    @serialize()\r\n    public resolveIncludes: boolean = false;\r\n\r\n    /**\r\n     * Indicates that this plugin should be notified for the extra events (HasRenderTargetTextures / FillRenderTargetTextures / HardBindForSubMesh)\r\n     */\r\n    @serialize()\r\n    public registerForExtraEvents: boolean = false;\r\n\r\n    /**\r\n     * Specifies if the material plugin should be serialized, `true` to skip serialization\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    protected _material: Material;\r\n    protected _pluginManager: MaterialPluginManager;\r\n    protected _pluginDefineNames?: { [name: string]: any };\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n        switch (shaderLanguage) {\r\n            case ShaderLanguage.GLSL:\r\n                return true;\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    protected _enable(enable: boolean) {\r\n        if (enable) {\r\n            this._pluginManager._activatePlugin(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Helper function to mark defines as being dirty.\r\n     */\r\n    public readonly markAllDefinesAsDirty: () => void;\r\n\r\n    /**\r\n     * Creates a new material plugin\r\n     * @param material parent material of the plugin\r\n     * @param name name of the plugin\r\n     * @param priority priority of the plugin\r\n     * @param defines list of defines used by the plugin. The value of the property is the default value for this property\r\n     * @param addToPluginList true to add the plugin to the list of plugins managed by the material plugin manager of the material (default: true)\r\n     * @param enable true to enable the plugin (it is handy if the plugin does not handle properties to switch its current activation)\r\n     * @param resolveIncludes Indicates that any #include directive in the plugin code must be replaced by the corresponding code (default: false)\r\n     */\r\n    constructor(material: Material, name: string, priority: number, defines?: { [key: string]: any }, addToPluginList = true, enable = false, resolveIncludes = false) {\r\n        this._material = material;\r\n        this.name = name;\r\n        this.priority = priority;\r\n        this.resolveIncludes = resolveIncludes;\r\n\r\n        if (!material.pluginManager) {\r\n            material.pluginManager = new MaterialPluginManager(material);\r\n            material.onDisposeObservable.add(() => {\r\n                material.pluginManager = undefined;\r\n            });\r\n        }\r\n\r\n        this._pluginDefineNames = defines;\r\n        this._pluginManager = material.pluginManager;\r\n\r\n        if (addToPluginList) {\r\n            this._pluginManager._addPlugin(this);\r\n        }\r\n\r\n        if (enable) {\r\n            this._enable(true);\r\n        }\r\n\r\n        this.markAllDefinesAsDirty = material._dirtyCallbacks[Constants.MATERIAL_AllDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name useful for serialization or dynamic coding.\r\n     * @returns The class name.\r\n     */\r\n    public getClassName(): string {\r\n        return \"MaterialPluginBase\";\r\n    }\r\n\r\n    /**\r\n     * Specifies that the submesh is ready to be used.\r\n     * @param _defines the list of \"defines\" to update.\r\n     * @param _scene defines the scene the material belongs to.\r\n     * @param _engine the engine this scene belongs to.\r\n     * @param _subMesh the submesh to check for readiness\r\n     * @returns - boolean indicating that the submesh is ready or not.\r\n     */\r\n    public isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Binds the material data (this function is called even if mustRebind() returns false)\r\n     * @param _uniformBuffer defines the Uniform buffer to fill in.\r\n     * @param _scene defines the scene the material belongs to.\r\n     * @param _engine defines the engine the material belongs to.\r\n     * @param _subMesh the submesh to bind data for\r\n     */\r\n    public hardBindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): void {}\r\n\r\n    /**\r\n     * Binds the material data.\r\n     * @param _uniformBuffer defines the Uniform buffer to fill in.\r\n     * @param _scene defines the scene the material belongs to.\r\n     * @param _engine the engine this scene belongs to.\r\n     * @param _subMesh the submesh to bind data for\r\n     */\r\n    public bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): void {}\r\n\r\n    /**\r\n     * Disposes the resources of the material.\r\n     * @param _forceDisposeTextures - Forces the disposal of all textures.\r\n     */\r\n    public dispose(_forceDisposeTextures?: boolean): void {}\r\n\r\n    /**\r\n     * Returns a list of custom shader code fragments to customize the shader.\r\n     * @param _shaderType \"vertex\" or \"fragment\"\r\n     * @param _shaderLanguage The shader language to use.\r\n     * @returns null if no code to be added, or a list of pointName =\\> code.\r\n     * Note that `pointName` can also be a regular expression if it starts with a `!`.\r\n     * In that case, the string found by the regular expression (if any) will be\r\n     * replaced by the code provided.\r\n     */\r\n    public getCustomCode(_shaderType: string, _shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Collects all defines.\r\n     * @param defines The object to append to.\r\n     */\r\n    public collectDefines(defines: { [name: string]: { type: string; default: any } }): void {\r\n        if (!this._pluginDefineNames) {\r\n            return;\r\n        }\r\n        for (const key of Object.keys(this._pluginDefineNames)) {\r\n            if (key[0] === \"_\") {\r\n                continue;\r\n            }\r\n\r\n            const type = typeof this._pluginDefineNames[key];\r\n            defines[key] = {\r\n                type: type === \"number\" ? \"number\" : type === \"string\" ? \"string\" : type === \"boolean\" ? \"boolean\" : \"object\",\r\n                default: this._pluginDefineNames[key],\r\n            };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the defines for the next rendering. Called before PrepareDefinesForAttributes is called.\r\n     * @param _defines the list of \"defines\" to update.\r\n     * @param _scene defines the scene to the material belongs to.\r\n     * @param _mesh the mesh being rendered\r\n     */\r\n    public prepareDefinesBeforeAttributes(_defines: MaterialDefines, _scene: Scene, _mesh: AbstractMesh): void {}\r\n\r\n    /**\r\n     * Sets the defines for the next rendering\r\n     * @param _defines the list of \"defines\" to update.\r\n     * @param _scene defines the scene to the material belongs to.\r\n     * @param _mesh the mesh being rendered\r\n     */\r\n    public prepareDefines(_defines: MaterialDefines, _scene: Scene, _mesh: AbstractMesh): void {}\r\n\r\n    /**\r\n     * Checks to see if a texture is used in the material.\r\n     * @param _texture - Base texture to use.\r\n     * @returns - Boolean specifying if a texture is used in the material.\r\n     */\r\n    public hasTexture(_texture: BaseTexture): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     * @returns true if this uses a render target otherwise false.\r\n     */\r\n    public hasRenderTargetTextures(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Fills the list of render target textures.\r\n     * @param _renderTargets the list of render targets to update\r\n     */\r\n    public fillRenderTargetTextures(_renderTargets: SmartArray<RenderTargetTexture>): void {}\r\n\r\n    /**\r\n     * Returns an array of the actively used textures.\r\n     * @param _activeTextures Array of BaseTextures\r\n     */\r\n    public getActiveTextures(_activeTextures: BaseTexture[]): void {}\r\n\r\n    /**\r\n     * Returns the animatable textures.\r\n     * @param _animatables Array of animatable textures.\r\n     */\r\n    public getAnimatables(_animatables: IAnimatable[]): void {}\r\n\r\n    /**\r\n     * Add fallbacks to the effect fallbacks list.\r\n     * @param defines defines the Base texture to use.\r\n     * @param fallbacks defines the current fallback list.\r\n     * @param currentRank defines the current fallback rank.\r\n     * @returns the new fallback rank.\r\n     */\r\n    public addFallbacks(defines: MaterialDefines, fallbacks: EffectFallbacks, currentRank: number): number {\r\n        return currentRank;\r\n    }\r\n\r\n    /**\r\n     * Gets the samplers used by the plugin.\r\n     * @param _samplers list that the sampler names should be added to.\r\n     */\r\n    public getSamplers(_samplers: string[]): void {}\r\n\r\n    /**\r\n     * Gets the attributes used by the plugin.\r\n     * @param _attributes list that the attribute names should be added to.\r\n     * @param _scene the scene that the material belongs to.\r\n     * @param _mesh the mesh being rendered.\r\n     */\r\n    public getAttributes(_attributes: string[], _scene: Scene, _mesh: AbstractMesh): void {}\r\n\r\n    /**\r\n     * Gets the uniform buffers names added by the plugin.\r\n     * @param _ubos list that the ubo names should be added to.\r\n     */\r\n    public getUniformBuffersNames(_ubos: string[]): void {}\r\n\r\n    /**\r\n     * Gets the description of the uniforms to add to the ubo (if engine supports ubos) or to inject directly in the vertex/fragment shaders (if engine does not support ubos)\r\n     * @param _shaderLanguage The shader language to use.\r\n     * @returns the description of the uniforms\r\n     */\r\n    public getUniforms(_shaderLanguage = ShaderLanguage.GLSL): {\r\n        ubo?: Array<{ name: string; size?: number; type?: string; arraySize?: number }>;\r\n        vertex?: string;\r\n        fragment?: string;\r\n        externalUniforms?: string[];\r\n    } {\r\n        return {};\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current configuration into another one.\r\n     * @param plugin define the config where to copy the info\r\n     */\r\n    public copyTo(plugin: MaterialPluginBase): void {\r\n        SerializationHelper.Clone(() => plugin, this);\r\n    }\r\n\r\n    /**\r\n     * Serializes this plugin configuration.\r\n     * @returns - An object with the serialized config.\r\n     */\r\n    public serialize(): any {\r\n        return SerializationHelper.Serialize(this);\r\n    }\r\n\r\n    /**\r\n     * Parses a plugin configuration from a serialized object.\r\n     * @param source - Serialized object.\r\n     * @param scene Defines the scene we are parsing for\r\n     * @param rootUrl Defines the rootUrl to load from\r\n     */\r\n    public parse(source: any, scene: Scene, rootUrl: string): void {\r\n        SerializationHelper.Parse(() => this, source, scene, rootUrl);\r\n    }\r\n}\r\n\r\n// Register Class Name\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialPluginBase.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialPluginBase(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MaterialPluginBase\", MaterialPluginBase);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { Material } from \"./material\";\r\nimport { serialize, expandToProperty, serializeAsTexture } from \"../Misc/decorators\";\r\nimport { MaterialFlags } from \"./materialFlags\";\r\nimport { type BaseTexture } from \"./Textures/baseTexture\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { MaterialDefines } from \"./materialDefines\";\r\nimport { MaterialPluginBase } from \"./materialPluginBase.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { type Scene } from \"../scene\";\r\nimport { type StandardMaterial } from \"./standardMaterial\";\r\nimport { type PBRBaseMaterial } from \"./PBR/pbrBaseMaterial\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"./materialHelper.functions\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialDetailMapDefines extends MaterialDefines {\r\n    DETAIL = false;\r\n    DETAILDIRECTUV = 0;\r\n    DETAIL_NORMALBLENDMETHOD = 0;\r\n}\r\n\r\n/**\r\n * Plugin that implements the detail map component of a material\r\n *\r\n * Inspired from:\r\n *   Unity: https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@9.0/manual/Mask-Map-and-Detail-Map.html and https://docs.unity3d.com/Manual/StandardShaderMaterialParameterDetail.html\r\n *   Unreal: https://docs.unrealengine.com/en-US/Engine/Rendering/Materials/HowTo/DetailTexturing/index.html\r\n *   Cryengine: https://docs.cryengine.com/display/SDKDOC2/Detail+Maps\r\n */\r\nexport class DetailMapConfiguration extends MaterialPluginBase {\r\n    private _texture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * The detail texture of the material.\r\n     */\r\n    @serializeAsTexture(\"detailTexture\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor texture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Defines how strongly the detail diffuse/albedo channel is blended with the regular diffuse/albedo texture\r\n     * Bigger values mean stronger blending\r\n     */\r\n    @serialize()\r\n    public diffuseBlendLevel = 1;\r\n\r\n    /**\r\n     * Defines how strongly the detail roughness channel is blended with the regular roughness value\r\n     * Bigger values mean stronger blending. Only used with PBR materials\r\n     */\r\n    @serialize()\r\n    public roughnessBlendLevel = 1;\r\n\r\n    /**\r\n     * Defines how strong the bump effect from the detail map is\r\n     * Bigger values mean stronger effect\r\n     */\r\n    @serialize()\r\n    public bumpLevel = 1;\r\n\r\n    private _normalBlendMethod = Material.MATERIAL_NORMALBLENDMETHOD_WHITEOUT;\r\n    /**\r\n     * The method used to blend the bump and detail normals together\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor normalBlendMethod: number;\r\n\r\n    private _isEnabled = false;\r\n    /**\r\n     * Enable or disable the detail map on this material\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial | StandardMaterial, addToPluginList = true) {\r\n        super(material, \"DetailMap\", 140, new MaterialDetailMapDefines(), addToPluginList);\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks whether the detail map textures are ready for the sub mesh.\r\n     * @param defines defines the material defines to inspect\r\n     * @param scene defines the scene to use for readiness checks\r\n     * @param engine defines the engine to use for readiness checks\r\n     * @returns true if the detail map is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: MaterialDetailMapDefines, scene: Scene, engine: AbstractEngine): boolean {\r\n        if (!this._isEnabled) {\r\n            return true;\r\n        }\r\n\r\n        if (defines._areTexturesDirty && scene.texturesEnabled) {\r\n            if (engine.getCaps().standardDerivatives && this._texture && MaterialFlags.DetailTextureEnabled) {\r\n                // Detail texture cannot be not blocking.\r\n                if (!this._texture.isReady()) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates the material defines for the detail map.\r\n     * @param defines defines the material defines to update\r\n     * @param scene defines the scene to use for texture checks\r\n     */\r\n    public override prepareDefines(defines: MaterialDetailMapDefines, scene: Scene): void {\r\n        if (this._isEnabled) {\r\n            defines.DETAIL_NORMALBLENDMETHOD = this._normalBlendMethod;\r\n\r\n            const engine = scene.getEngine();\r\n\r\n            if (defines._areTexturesDirty) {\r\n                if (engine.getCaps().standardDerivatives && this._texture && MaterialFlags.DetailTextureEnabled && this._isEnabled) {\r\n                    PrepareDefinesForMergedUV(this._texture, defines, \"DETAIL\");\r\n                    defines.DETAIL_NORMALBLENDMETHOD = this._normalBlendMethod;\r\n                } else {\r\n                    defines.DETAIL = false;\r\n                }\r\n            }\r\n        } else {\r\n            defines.DETAIL = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the detail map data for a sub mesh.\r\n     * @param uniformBuffer defines the uniform buffer to update\r\n     * @param scene defines the scene to use for texture binding\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene): void {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            if (this._texture && MaterialFlags.DetailTextureEnabled) {\r\n                uniformBuffer.updateFloat4(\"vDetailInfos\", this._texture.coordinatesIndex, this.diffuseBlendLevel, this.bumpLevel, this.roughnessBlendLevel);\r\n                BindTextureMatrix(this._texture, uniformBuffer, \"detail\");\r\n            }\r\n        }\r\n\r\n        // Textures\r\n        if (scene.texturesEnabled) {\r\n            if (this._texture && MaterialFlags.DetailTextureEnabled) {\r\n                uniformBuffer.setTexture(\"detailSampler\", this._texture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether the detail map uses a texture.\r\n     * @param texture defines the texture to check\r\n     * @returns true if the texture is used by the detail map\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (this._texture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds the active detail map textures.\r\n     * @param activeTextures defines the list of active textures to update\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this._texture) {\r\n            activeTextures.push(this._texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the animatable detail map textures.\r\n     * @param animatables defines the list of animatables to update\r\n     */\r\n    public override getAnimatables(animatables: IAnimatable[]): void {\r\n        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {\r\n            animatables.push(this._texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the detail map textures.\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     */\r\n    public override dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            this._texture?.dispose();\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"DetailMapConfiguration\";\r\n    }\r\n\r\n    /**\r\n     * Adds the detail map sampler names.\r\n     * @param samplers defines the list of sampler names to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"detailSampler\");\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vDetailInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"detailMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n}\r\n","import { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\n\r\ntype ShaderImportFunction = () => readonly Promise<unknown>[];\r\n\r\ninterface IShaderImportState {\r\n    readonly load: ShaderImportFunction;\r\n    loaded: boolean;\r\n    loadPromise: Promise<unknown> | null;\r\n}\r\n\r\n/**\r\n * Caches dynamic shader imports per shader language.\r\n * @internal\r\n */\r\nexport class _ShaderImportLoader {\r\n    private readonly _webGL: IShaderImportState;\r\n    private readonly _webGPU: IShaderImportState;\r\n\r\n    /**\r\n     * Creates a shader import loader.\r\n     * @param loadWebGL Imports the GLSL shader modules.\r\n     * @param loadWebGPU Imports the WGSL shader modules.\r\n     */\r\n    public constructor(loadWebGL: ShaderImportFunction, loadWebGPU: ShaderImportFunction) {\r\n        this._webGL = { load: loadWebGL, loaded: false, loadPromise: null };\r\n        this._webGPU = { load: loadWebGPU, loaded: false, loadPromise: null };\r\n    }\r\n\r\n    /**\r\n     * Gets the initialization callback needed to load shaders for the requested language.\r\n     * @param shaderLanguage The shader language to load.\r\n     * @returns The shared loading callback, or `undefined` when the shaders are already loaded.\r\n     */\r\n    public getLoadCallback(shaderLanguage: ShaderLanguage): (() => Promise<void>) | undefined {\r\n        const state = shaderLanguage === ShaderLanguage.WGSL ? this._webGPU : this._webGL;\r\n        return state.loaded\r\n            ? undefined\r\n            : async () => {\r\n                  await this._loadAsync(state);\r\n              };\r\n    }\r\n\r\n    private async _loadAsync(state: IShaderImportState): Promise<void> {\r\n        if (state.loaded) {\r\n            return;\r\n        }\r\n\r\n        let loadPromise = state.loadPromise;\r\n        const ownsLoad = loadPromise === null;\r\n\r\n        if (ownsLoad) {\r\n            loadPromise = Promise.all(state.load());\r\n            state.loadPromise = loadPromise;\r\n        }\r\n\r\n        let loaded = false;\r\n        try {\r\n            await loadPromise;\r\n            loaded = true;\r\n        } finally {\r\n            if (ownsLoad) {\r\n                this._completeLoad(state, loaded);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _completeLoad(state: IShaderImportState, loaded: boolean): void {\r\n        state.loaded = loaded;\r\n        state.loadPromise = null;\r\n    }\r\n}\r\n","type UVDefinesMixinConstructor<T = {}> = new (...args: any[]) => T;\r\n\r\n/**\r\n * Mixin to add UV defines to your material defines\r\n * @internal\r\n */\r\nexport function UVDefinesMixin<Tbase extends UVDefinesMixinConstructor>(base: Tbase) {\r\n    return class extends base {\r\n        public MAINUV1 = false;\r\n        public MAINUV2 = false;\r\n        public MAINUV3 = false;\r\n        public MAINUV4 = false;\r\n        public MAINUV5 = false;\r\n        public MAINUV6 = false;\r\n        public UV1 = false;\r\n        public UV2 = false;\r\n        public UV3 = false;\r\n        public UV4 = false;\r\n        public UV5 = false;\r\n        public UV6 = false;\r\n    };\r\n}\r\n","type PrepassDefinesMixinConstructor<T = {}> = new (...args: any[]) => T;\r\n\r\n/**\r\n * Mixin to add prepass defines to your material defines\r\n * @internal\r\n */\r\nexport function PrepassDefinesMixin<Tbase extends PrepassDefinesMixinConstructor>(base: Tbase) {\r\n    return class extends base {\r\n        public PREPASS = false;\r\n        public PREPASS_COLOR = false;\r\n        public PREPASS_COLOR_INDEX = -1;\r\n        public PREPASS_IRRADIANCE_LEGACY = false;\r\n        public PREPASS_IRRADIANCE_LEGACY_INDEX = -1;\r\n        public PREPASS_IRRADIANCE = false;\r\n        public PREPASS_IRRADIANCE_INDEX = -1;\r\n        public PREPASS_ALBEDO = false;\r\n        public PREPASS_ALBEDO_INDEX = -1;\r\n        public PREPASS_ALBEDO_SQRT = false;\r\n        public PREPASS_ALBEDO_SQRT_INDEX = -1;\r\n        public PREPASS_DEPTH = false;\r\n        public PREPASS_DEPTH_INDEX = -1;\r\n        public PREPASS_SCREENSPACE_DEPTH = false;\r\n        public PREPASS_SCREENSPACE_DEPTH_INDEX = -1;\r\n        public PREPASS_NORMALIZED_VIEW_DEPTH = false;\r\n        public PREPASS_NORMALIZED_VIEW_DEPTH_INDEX = -1;\r\n        public PREPASS_NORMAL = false;\r\n        public PREPASS_NORMAL_INDEX = -1;\r\n        public PREPASS_NORMAL_WORLDSPACE = false;\r\n        public PREPASS_WORLD_NORMAL = false;\r\n        public PREPASS_WORLD_NORMAL_INDEX = -1;\r\n        public PREPASS_POSITION = false;\r\n        public PREPASS_POSITION_INDEX = -1;\r\n        public PREPASS_LOCAL_POSITION = false;\r\n        public PREPASS_LOCAL_POSITION_INDEX = -1;\r\n        public PREPASS_VELOCITY = false;\r\n        public PREPASS_VELOCITY_INDEX = -1;\r\n        public PREPASS_VELOCITY_LINEAR = false;\r\n        public PREPASS_VELOCITY_LINEAR_INDEX = -1;\r\n        public PREPASS_REFLECTIVITY = false;\r\n        public PREPASS_REFLECTIVITY_INDEX = -1;\r\n        public PREPASS_OBJECT_ID = false;\r\n        public PREPASS_OBJECT_ID_INDEX = -1;\r\n        public PREPASS_OBJECT_ID_R8 = false;\r\n        public PREPASS_MESH_BLEND_TAG = false;\r\n        public PREPASS_MESH_BLEND_TAG_INDEX = -1;\r\n        public SCENE_MRT_COUNT = 0;\r\n    };\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { GetDirectStoreFromMetadata } from \"../Misc/decorators.functions\";\r\nimport { SerializedFieldType } from \"../Misc/decorators.serializationUtilities\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type ImageProcessingConfiguration } from \"./imageProcessingConfiguration\";\r\nimport { type Observer } from \"../Misc/observable\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { type ColorCurves } from \"../Materials/colorCurves\";\r\n\r\ntype ImageProcessingMixinConstructor<T = {}> = new (...args: any[]) => T;\r\n\r\n/**\r\n * Mixin to add Image processing defines to your material defines\r\n * @internal\r\n */\r\nexport function ImageProcessingMixin<Tbase extends ImageProcessingMixinConstructor>(base: Tbase) {\r\n    return class extends base {\r\n        /**\r\n         * Constructor for the ImageProcessingMixin.\r\n         * @param args - arguments to pass to the base class constructor\r\n         */\r\n        constructor(...args: any[]) {\r\n            super(...args);\r\n            // Decorators don't work on this anonymous class\r\n            // so manually register the serialization metadata.\r\n            const ctor = new.target as any;\r\n            if (!ctor[Symbol.metadata]) {\r\n                const parentMeta = Object.getPrototypeOf(ctor)?.[Symbol.metadata];\r\n                ctor[Symbol.metadata] = parentMeta ? Object.create(parentMeta) : {};\r\n            }\r\n            const store = GetDirectStoreFromMetadata(ctor[Symbol.metadata]);\r\n            if (!store[\"_imageProcessingConfiguration\"]) {\r\n                store[\"_imageProcessingConfiguration\"] = { type: SerializedFieldType.IMAGE_PROCESSING, sourceName: undefined };\r\n            }\r\n        }\r\n        /**\r\n         * Default configuration related to image processing available in the standard Material.\r\n         */\r\n        public _imageProcessingConfiguration: ImageProcessingConfiguration;\r\n\r\n        /**\r\n         * Gets the image processing configuration used either in this material.\r\n         */\r\n        public get imageProcessingConfiguration(): ImageProcessingConfiguration {\r\n            return this._imageProcessingConfiguration;\r\n        }\r\n\r\n        /**\r\n         * Sets the Default image processing configuration used either in the this material.\r\n         *\r\n         * If sets to null, the scene one is in use.\r\n         */\r\n        public set imageProcessingConfiguration(value: ImageProcessingConfiguration) {\r\n            this._attachImageProcessingConfiguration(value);\r\n\r\n            // Ensure the effect will be rebuilt.\r\n            if ((this as any)._markAllSubMeshesAsImageProcessingDirty) {\r\n                (this as any)._markAllSubMeshesAsImageProcessingDirty();\r\n            }\r\n        }\r\n\r\n        /**\r\n         * Keep track of the image processing observer to allow dispose and replace.\r\n         */\r\n        public _imageProcessingObserver: Nullable<Observer<ImageProcessingConfiguration>>;\r\n\r\n        /**\r\n         * Attaches a new image processing configuration to the Standard Material.\r\n         * @param configuration\r\n         */\r\n        public _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void {\r\n            if (configuration === this._imageProcessingConfiguration) {\r\n                return;\r\n            }\r\n\r\n            // Detaches observer\r\n            if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n                this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n            }\r\n\r\n            // Pick the scene configuration if needed\r\n            if (!configuration && (this as any).getScene) {\r\n                this._imageProcessingConfiguration = (this as any).getScene().imageProcessingConfiguration;\r\n            } else if (configuration) {\r\n                this._imageProcessingConfiguration = configuration;\r\n            }\r\n\r\n            // Attaches observer\r\n            if (this._imageProcessingConfiguration) {\r\n                this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(() => {\r\n                    // Ensure the effect will be rebuilt.\r\n                    if ((this as any)._markAllSubMeshesAsImageProcessingDirty) {\r\n                        (this as any)._markAllSubMeshesAsImageProcessingDirty();\r\n                    }\r\n                });\r\n            }\r\n        }\r\n\r\n        /**\r\n         * Gets whether the color curves effect is enabled.\r\n         */\r\n        public get cameraColorCurvesEnabled(): boolean {\r\n            return this.imageProcessingConfiguration.colorCurvesEnabled;\r\n        }\r\n        /**\r\n         * Sets whether the color curves effect is enabled.\r\n         */\r\n        public set cameraColorCurvesEnabled(value: boolean) {\r\n            this.imageProcessingConfiguration.colorCurvesEnabled = value;\r\n        }\r\n\r\n        /**\r\n         * Gets whether the color grading effect is enabled.\r\n         */\r\n        public get cameraColorGradingEnabled(): boolean {\r\n            return this.imageProcessingConfiguration.colorGradingEnabled;\r\n        }\r\n        /**\r\n         * Gets whether the color grading effect is enabled.\r\n         */\r\n        public set cameraColorGradingEnabled(value: boolean) {\r\n            this.imageProcessingConfiguration.colorGradingEnabled = value;\r\n        }\r\n\r\n        /**\r\n         * Gets whether tonemapping is enabled or not.\r\n         */\r\n        public get cameraToneMappingEnabled(): boolean {\r\n            return this._imageProcessingConfiguration.toneMappingEnabled;\r\n        }\r\n        /**\r\n         * Sets whether tonemapping is enabled or not\r\n         */\r\n        public set cameraToneMappingEnabled(value: boolean) {\r\n            this._imageProcessingConfiguration.toneMappingEnabled = value;\r\n        }\r\n\r\n        /**\r\n         * The camera exposure used on this material.\r\n         * This property is here and not in the camera to allow controlling exposure without full screen post process.\r\n         * This corresponds to a photographic exposure.\r\n         */\r\n        public get cameraExposure(): number {\r\n            return this._imageProcessingConfiguration.exposure;\r\n        }\r\n        /**\r\n         * The camera exposure used on this material.\r\n         * This property is here and not in the camera to allow controlling exposure without full screen post process.\r\n         * This corresponds to a photographic exposure.\r\n         */\r\n        public set cameraExposure(value: number) {\r\n            this._imageProcessingConfiguration.exposure = value;\r\n        }\r\n\r\n        /**\r\n         * Gets The camera contrast used on this material.\r\n         */\r\n        public get cameraContrast(): number {\r\n            return this._imageProcessingConfiguration.contrast;\r\n        }\r\n\r\n        /**\r\n         * Sets The camera contrast used on this material.\r\n         */\r\n        public set cameraContrast(value: number) {\r\n            this._imageProcessingConfiguration.contrast = value;\r\n        }\r\n\r\n        /**\r\n         * Gets the Color Grading 2D Lookup Texture.\r\n         */\r\n        public get cameraColorGradingTexture(): Nullable<BaseTexture> {\r\n            return this._imageProcessingConfiguration.colorGradingTexture;\r\n        }\r\n        /**\r\n         * Sets the Color Grading 2D Lookup Texture.\r\n         */\r\n        public set cameraColorGradingTexture(value: Nullable<BaseTexture>) {\r\n            this._imageProcessingConfiguration.colorGradingTexture = value;\r\n        }\r\n\r\n        /**\r\n         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).\r\n         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.\r\n         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;\r\n         * corresponding to low luminance, medium luminance, and high luminance areas respectively.\r\n         */\r\n        public get cameraColorCurves(): Nullable<ColorCurves> {\r\n            return this._imageProcessingConfiguration.colorCurves;\r\n        }\r\n        /**\r\n         * The color grading curves provide additional color adjustment that is applied after any color grading transform (3D LUT).\r\n         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.\r\n         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;\r\n         * corresponding to low luminance, medium luminance, and high luminance areas respectively.\r\n         */\r\n        public set cameraColorCurves(value: Nullable<ColorCurves>) {\r\n            this._imageProcessingConfiguration.colorCurves = value;\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsColor3, expandToProperty, serializeAsFresnelParameters, serializeAsTexture } from \"../Misc/decorators\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type Matrix } from \"../Maths/math.vector.pure\";\r\nimport { Color3, TmpColors } from \"../Maths/math.color.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { PrePassConfiguration } from \"./prePassConfiguration\";\r\nimport { ImageProcessingDefinesMixin } from \"./imageProcessingConfiguration.defines\";\r\nimport { ImageProcessingConfiguration, RegisterImageProcessingConfiguration } from \"./imageProcessingConfiguration.pure\";\r\nimport { type FresnelParameters } from \"./fresnelParameters.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { type ICustomShaderNameResolveOptions } from \"../Materials/material\";\r\nimport { MaterialPluginEvent } from \"./materialPluginEvent\";\r\nimport { MaterialDefines } from \"../Materials/materialDefines\";\r\nimport { PushMaterial } from \"./pushMaterial\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type CubeTexture } from \"../Materials/Textures/cubeTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { MaterialFlags } from \"./materialFlags\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EffectFallbacks } from \"./effectFallbacks\";\r\nimport { type Effect, type IEffectCreationOptions } from \"./effect.pure\";\r\nimport { DetailMapConfiguration } from \"./material.detailMapConfiguration\";\r\nimport { AddClipPlaneUniforms, BindClipPlane } from \"./clipPlaneMaterialHelper\";\r\nimport { PrepareVertexPullingUniforms, BindVertexPullingUniforms, type IVertexPullingMetadata } from \"./vertexPullingHelper.functions\";\r\n\r\nimport {\r\n    BindBonesParameters,\r\n    BindFogParameters,\r\n    BindLights,\r\n    BindLogDepth,\r\n    BindMorphTargetParameters,\r\n    BindTextureMatrix,\r\n    BindIBLParameters,\r\n    HandleFallbacksForShadows,\r\n    PrepareAttributesForBakedVertexAnimation,\r\n    PrepareAttributesForBones,\r\n    PrepareAttributesForInstances,\r\n    PrepareAttributesForMorphTargets,\r\n    PrepareDefinesForAttributes,\r\n    PrepareDefinesForFrameBoundValues,\r\n    PrepareDefinesForLights,\r\n    PrepareDefinesForIBL,\r\n    PrepareDefinesForMergedUV,\r\n    PrepareDefinesForMisc,\r\n    PrepareDefinesForMultiview,\r\n    PrepareDefinesForOIT,\r\n    PrepareDefinesForPrePass,\r\n    PrepareUniformsAndSamplersForIBL,\r\n    PrepareUniformsAndSamplersList,\r\n    PrepareUniformLayoutForIBL,\r\n    AreLightsTexturesReady,\r\n} from \"./materialHelper.functions\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { _ShaderImportLoader } from \"../Misc/shaderImportLoader\";\r\nimport { MaterialHelperGeometryRendering } from \"./materialHelper.geometryrendering\";\r\nimport { UVDefinesMixin } from \"./uv.defines\";\r\nimport { PrepassDefinesMixin } from \"./prepass.defines\";\r\nimport { ImageProcessingMixin } from \"./imageProcessing\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\nconst onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };\r\n\r\nclass StandardMaterialDefinesBase extends PrepassDefinesMixin(UVDefinesMixin(MaterialDefines)) {}\r\n\r\n/** @internal */\r\nexport class StandardMaterialDefines extends ImageProcessingDefinesMixin(StandardMaterialDefinesBase) {\r\n    public DIFFUSE = false;\r\n    public DIFFUSEDIRECTUV = 0;\r\n    public BAKED_VERTEX_ANIMATION_TEXTURE = false;\r\n    public AMBIENT = false;\r\n    public AMBIENTDIRECTUV = 0;\r\n    public OPACITY = false;\r\n    public OPACITYDIRECTUV = 0;\r\n    public OPACITYRGB = false;\r\n    public REFLECTION = false;\r\n    public EMISSIVE = false;\r\n    public EMISSIVEDIRECTUV = 0;\r\n    public SPECULAR = false;\r\n    public SPECULARDIRECTUV = 0;\r\n    public BUMP = false;\r\n    public BUMPDIRECTUV = 0;\r\n    public PARALLAX = false;\r\n    public PARALLAX_RHS = false;\r\n    public PARALLAXOCCLUSION = false;\r\n    public SPECULAROVERALPHA = false;\r\n    public CLIPPLANE = false;\r\n    public CLIPPLANE2 = false;\r\n    public CLIPPLANE3 = false;\r\n    public CLIPPLANE4 = false;\r\n    public CLIPPLANE5 = false;\r\n    public CLIPPLANE6 = false;\r\n    public ALPHATEST = false;\r\n    public DEPTHPREPASS = false;\r\n    public ALPHAFROMDIFFUSE = false;\r\n    public POINTSIZE = false;\r\n    public FOG = false;\r\n    public SPECULARTERM = false;\r\n    public DIFFUSEFRESNEL = false;\r\n    public OPACITYFRESNEL = false;\r\n    public REFLECTIONFRESNEL = false;\r\n    public REFRACTIONFRESNEL = false;\r\n    public EMISSIVEFRESNEL = false;\r\n    public FRESNEL = false;\r\n    public NORMAL = false;\r\n    public TANGENT = false;\r\n    public VERTEXCOLOR = false;\r\n    public VERTEXALPHA = false;\r\n    public NUM_BONE_INFLUENCERS = 0;\r\n    public BonesPerMesh = 0;\r\n    public BONETEXTURE = false;\r\n    public BONES_VELOCITY_ENABLED = false;\r\n    public INSTANCES = false;\r\n    public THIN_INSTANCES = false;\r\n    public INSTANCESCOLOR = false;\r\n    public GLOSSINESS = false;\r\n    public ROUGHNESS = false;\r\n    public EMISSIVEASILLUMINATION = false;\r\n    public LINKEMISSIVEWITHDIFFUSE = false;\r\n    public REFLECTIONFRESNELFROMSPECULAR = false;\r\n    public LIGHTMAP = false;\r\n    public LIGHTMAPDIRECTUV = 0;\r\n    public OBJECTSPACE_NORMALMAP = false;\r\n    public USELIGHTMAPASSHADOWMAP = false;\r\n    public REFLECTIONMAP_3D = false;\r\n    public REFLECTIONMAP_SPHERICAL = false;\r\n    public REFLECTIONMAP_PLANAR = false;\r\n    public REFLECTIONMAP_CUBIC = false;\r\n    public USE_LOCAL_REFLECTIONMAP_CUBIC = false;\r\n    public USE_LOCAL_REFRACTIONMAP_CUBIC = false;\r\n    public REFLECTIONMAP_PROJECTION = false;\r\n    public REFLECTIONMAP_SKYBOX = false;\r\n    public REFLECTIONMAP_EXPLICIT = false;\r\n    public REFLECTIONMAP_EQUIRECTANGULAR = false;\r\n    public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;\r\n    public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;\r\n    public REFLECTIONMAP_OPPOSITEZ = false;\r\n    public INVERTCUBICMAP = false;\r\n    public LOGARITHMICDEPTH = false;\r\n    public REFRACTION = false;\r\n    public REFRACTIONMAP_3D = false;\r\n    public REFLECTIONOVERALPHA = false;\r\n    public TWOSIDEDLIGHTING = false;\r\n    public SHADOWFLOAT = false;\r\n    public MORPHTARGETS = false;\r\n    public MORPHTARGETS_POSITION = false;\r\n    public MORPHTARGETS_NORMAL = false;\r\n    public MORPHTARGETS_TANGENT = false;\r\n    public MORPHTARGETS_UV = false;\r\n    public MORPHTARGETS_UV2 = false;\r\n    public MORPHTARGETS_COLOR = false;\r\n    public MORPHTARGETTEXTURE_HASPOSITIONS = false;\r\n    public MORPHTARGETTEXTURE_HASNORMALS = false;\r\n    public MORPHTARGETTEXTURE_HASTANGENTS = false;\r\n    public MORPHTARGETTEXTURE_HASUVS = false;\r\n    public MORPHTARGETTEXTURE_HASUV2S = false;\r\n    public MORPHTARGETTEXTURE_HASCOLORS = false;\r\n    public NUM_MORPH_INFLUENCERS = 0;\r\n    public MORPHTARGETS_TEXTURE = false;\r\n    public NONUNIFORMSCALING = false; // https://playground.babylonjs.com#V6DWIH\r\n    public PREMULTIPLYALPHA = false; // https://playground.babylonjs.com#LNVJJ7\r\n    public ALPHATEST_AFTERALLALPHACOMPUTATIONS = false;\r\n    public ALPHABLEND = true;\r\n\r\n    public RGBDLIGHTMAP = false;\r\n    public RGBDREFLECTION = false;\r\n    public RGBDREFRACTION = false;\r\n    public MULTIVIEW = false;\r\n    public ORDER_INDEPENDENT_TRANSPARENCY = false;\r\n    public ORDER_INDEPENDENT_TRANSPARENCY_16BITS = false;\r\n    public CAMERA_ORTHOGRAPHIC = false;\r\n    public CAMERA_PERSPECTIVE = false;\r\n    public AREALIGHTSUPPORTED = true;\r\n    public USE_VERTEX_PULLING = false;\r\n    public VERTEX_PULLING_USE_INDEX_BUFFER = false;\r\n    public VERTEX_PULLING_INDEX_BUFFER_32BITS = false;\r\n    public RIGHT_HANDED = false;\r\n\r\n    public CLUSTLIGHT_SLICES = 0;\r\n    public CLUSTLIGHT_BATCH = 0;\r\n\r\n    /**\r\n     * If the reflection texture on this material is in linear color space\r\n     * @internal\r\n     */\r\n    public IS_REFLECTION_LINEAR = false;\r\n    /**\r\n     * If the refraction texture on this material is in linear color space\r\n     * @internal\r\n     */\r\n    public IS_REFRACTION_LINEAR = false;\r\n\r\n    public DECAL_AFTER_DETAIL = false;\r\n\r\n    public TEXTURE_REPETITION_MODE = 0;\r\n\r\n    /**\r\n     * Initializes the Standard Material defines.\r\n     * @param externalProperties The external properties\r\n     */\r\n    constructor(externalProperties?: { [name: string]: { type: string; default: any } }) {\r\n        super(externalProperties);\r\n        this.rebuild();\r\n    }\r\n}\r\n\r\nclass StandardMaterialBase extends ImageProcessingMixin(PushMaterial) {}\r\n/**\r\n * This is the default material used in Babylon. It is the best trade off between quality\r\n * and performances.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction\r\n */\r\nexport class StandardMaterial extends StandardMaterialBase {\r\n    /**\r\n     * Force all the standard materials to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    @serializeAsTexture(\"diffuseTexture\")\r\n    private _diffuseTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * The basic texture of the material as viewed under a light.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor diffuseTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"ambientTexture\")\r\n    private _ambientTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * AKA Occlusion Texture in other nomenclature, it helps adding baked shadows into your material.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor ambientTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"opacityTexture\")\r\n    private _opacityTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Define the transparency of the material from a texture.\r\n     * The final alpha value can be read either from the red channel (if texture.getAlphaFromRGB is false)\r\n     * or from the luminance or the current texel (if texture.getAlphaFromRGB is true)\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor opacityTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"reflectionTexture\")\r\n    private _reflectionTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Define the texture used to display the reflection.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#how-to-obtain-reflections-and-refractions\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"emissiveTexture\")\r\n    private _emissiveTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Define texture of the material as if self lit.\r\n     * This will be mixed in the final result even in the absence of light.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor emissiveTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"specularTexture\")\r\n    private _specularTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Define how the color and intensity of the highlight given by the light in the material.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor specularTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"bumpTexture\")\r\n    private _bumpTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Bump mapping is a technique to simulate bump and dents on a rendered surface.\r\n     * These are made by creating a normal map from an image. The means to do this can be found on the web, a search for 'normal map generator' will bring up free and paid for methods of doing this.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#bump-map\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor bumpTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"lightmapTexture\")\r\n    private _lightmapTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Complex lighting can be computationally expensive to compute at runtime.\r\n     * To save on computation, lightmaps may be used to store calculated lighting in a texture which will be applied to a given mesh.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction#lightmaps\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor lightmapTexture: Nullable<BaseTexture>;\r\n\r\n    @serializeAsTexture(\"refractionTexture\")\r\n    private _refractionTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Define the texture used to display the refraction.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#how-to-obtain-reflections-and-refractions\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor refractionTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * The color of the material lit by the environmental background lighting.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction#ambient-color-example\r\n     */\r\n    @serializeAsColor3(\"ambient\")\r\n    public ambientColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * The basic color of the material as viewed under a light.\r\n     */\r\n    @serializeAsColor3(\"diffuse\")\r\n    public diffuseColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * Define how the color and intensity of the highlight given by the light in the material.\r\n     */\r\n    @serializeAsColor3(\"specular\")\r\n    public specularColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * Define the color of the material as if self lit.\r\n     * This will be mixed in the final result even in the absence of light.\r\n     */\r\n    @serializeAsColor3(\"emissive\")\r\n    public emissiveColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * Defines how sharp are the highlights in the material.\r\n     * The bigger the value the sharper giving a more glossy feeling to the result.\r\n     * Reversely, the smaller the value the blurrier giving a more rough feeling to the result.\r\n     */\r\n    @serialize()\r\n    public specularPower = 64;\r\n\r\n    @serialize(\"useAlphaFromDiffuseTexture\")\r\n    private _useAlphaFromDiffuseTexture = false;\r\n    /**\r\n     * Does the transparency come from the diffuse texture alpha channel.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor useAlphaFromDiffuseTexture: boolean;\r\n\r\n    @serialize(\"useEmissiveAsIllumination\")\r\n    private _useEmissiveAsIllumination = false;\r\n    /**\r\n     * If true, the emissive value is added into the end result, otherwise it is multiplied in.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useEmissiveAsIllumination: boolean;\r\n\r\n    @serialize(\"linkEmissiveWithDiffuse\")\r\n    private _linkEmissiveWithDiffuse = false;\r\n    /**\r\n     * If true, some kind of energy conservation will prevent the end result to be more than 1 by reducing\r\n     * the emissive level when the final color is close to one.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor linkEmissiveWithDiffuse: boolean;\r\n\r\n    @serialize(\"useSpecularOverAlpha\")\r\n    private _useSpecularOverAlpha = false;\r\n    /**\r\n     * Specifies that the material will keep the specular highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good exemple of that. When sun reflects on it you can not see what is behind.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useSpecularOverAlpha: boolean;\r\n\r\n    @serialize(\"useReflectionOverAlpha\")\r\n    private _useReflectionOverAlpha = false;\r\n    /**\r\n     * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useReflectionOverAlpha: boolean;\r\n\r\n    @serialize(\"disableLighting\")\r\n    private _disableLighting = false;\r\n    /**\r\n     * Does lights from the scene impacts this material.\r\n     * It can be a nice trick for performance to disable lighting on a fully emissive material.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor disableLighting: boolean;\r\n\r\n    @serialize(\"useObjectSpaceNormalMap\")\r\n    private _useObjectSpaceNormalMap = false;\r\n    /**\r\n     * Allows using an object space normal map (instead of tangent space).\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useObjectSpaceNormalMap: boolean;\r\n\r\n    @serialize(\"useParallax\")\r\n    private _useParallax = false;\r\n    /**\r\n     * Is parallax enabled or not.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/parallaxMapping\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useParallax: boolean;\r\n\r\n    @serialize(\"useParallaxOcclusion\")\r\n    private _useParallaxOcclusion = false;\r\n    /**\r\n     * Is parallax occlusion enabled or not.\r\n     * If true, the outcome is way more realistic than traditional Parallax but you can expect a performance hit that worthes consideration.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/parallaxMapping\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useParallaxOcclusion: boolean;\r\n\r\n    /**\r\n     * Apply a scaling factor that determine which \"depth\" the height map should reprensent. A value between 0.05 and 0.1 is reasonnable in Parallax, you can reach 0.2 using Parallax Occlusion.\r\n     */\r\n    @serialize()\r\n    public parallaxScaleBias = 0.05;\r\n\r\n    @serialize(\"roughness\")\r\n    private _roughness = 0;\r\n    /**\r\n     * Helps to define how blurry the reflections should appears in the material.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor roughness: number;\r\n\r\n    /**\r\n     * In case of refraction, define the value of the index of refraction.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#how-to-obtain-reflections-and-refractions\r\n     */\r\n    @serialize()\r\n    public indexOfRefraction = 0.98;\r\n\r\n    /**\r\n     * Invert the refraction texture alongside the y axis.\r\n     * It can be useful with procedural textures or probe for instance.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#how-to-obtain-reflections-and-refractions\r\n     */\r\n    @serialize()\r\n    public invertRefractionY = true;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     */\r\n    @serialize()\r\n    public alphaCutOff = 0.4;\r\n\r\n    @serialize(\"useLightmapAsShadowmap\")\r\n    private _useLightmapAsShadowmap = false;\r\n    /**\r\n     * In case of light mapping, define whether the map contains light or shadow informations.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useLightmapAsShadowmap: boolean;\r\n\r\n    // Fresnel\r\n    @serializeAsFresnelParameters(\"diffuseFresnelParameters\")\r\n    private _diffuseFresnelParameters: FresnelParameters;\r\n    /**\r\n     * Define the diffuse fresnel parameters of the material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsFresnelDirty\")\r\n    public accessor diffuseFresnelParameters: FresnelParameters;\r\n\r\n    @serializeAsFresnelParameters(\"opacityFresnelParameters\")\r\n    private _opacityFresnelParameters: FresnelParameters;\r\n    /**\r\n     * Define the opacity fresnel parameters of the material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsFresnelAndMiscDirty\")\r\n    public accessor opacityFresnelParameters: FresnelParameters;\r\n\r\n    @serializeAsFresnelParameters(\"reflectionFresnelParameters\")\r\n    private _reflectionFresnelParameters: FresnelParameters;\r\n    /**\r\n     * Define the reflection fresnel parameters of the material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsFresnelDirty\")\r\n    public accessor reflectionFresnelParameters: FresnelParameters;\r\n\r\n    @serializeAsFresnelParameters(\"refractionFresnelParameters\")\r\n    private _refractionFresnelParameters: FresnelParameters;\r\n    /**\r\n     * Define the refraction fresnel parameters of the material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsFresnelDirty\")\r\n    public accessor refractionFresnelParameters: FresnelParameters;\r\n\r\n    @serializeAsFresnelParameters(\"emissiveFresnelParameters\")\r\n    private _emissiveFresnelParameters: FresnelParameters;\r\n    /**\r\n     * Define the emissive fresnel parameters of the material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsFresnelDirty\")\r\n    public accessor emissiveFresnelParameters: FresnelParameters;\r\n\r\n    @serialize(\"useReflectionFresnelFromSpecular\")\r\n    private _useReflectionFresnelFromSpecular = false;\r\n    /**\r\n     * If true automatically deducts the fresnels values from the material specularity.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsFresnelDirty\")\r\n    public accessor useReflectionFresnelFromSpecular: boolean;\r\n\r\n    @serialize(\"useGlossinessFromSpecularMapAlpha\")\r\n    private _useGlossinessFromSpecularMapAlpha = false;\r\n    /**\r\n     * Defines if the glossiness/roughness of the material should be read from the specular map alpha channel\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useGlossinessFromSpecularMapAlpha: boolean;\r\n\r\n    @serialize(\"maxSimultaneousLights\")\r\n    private _maxSimultaneousLights = 4;\r\n    /**\r\n     * Defines the maximum number of lights that can be used in the material\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor maxSimultaneousLights: number;\r\n\r\n    @serialize(\"invertNormalMapX\")\r\n    private _invertNormalMapX = false;\r\n    /**\r\n     * If sets to true, x component of normal map value will invert (x = 1.0 - x).\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapX: boolean;\r\n\r\n    @serialize(\"invertNormalMapY\")\r\n    private _invertNormalMapY = false;\r\n    /**\r\n     * If sets to true, y component of normal map value will invert (y = 1.0 - y).\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapY: boolean;\r\n\r\n    @serialize(\"twoSidedLighting\")\r\n    private _twoSidedLighting = false;\r\n    /**\r\n     * If sets to true and backfaceCulling is false, normals will be flipped on the backside.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor twoSidedLighting: boolean;\r\n\r\n    @serialize(\"applyDecalMapAfterDetailMap\")\r\n    private _applyDecalMapAfterDetailMap = false;\r\n    /**\r\n     * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false)\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor applyDecalMapAfterDetailMap: boolean;\r\n\r\n    private static readonly _ShaderLoader = /*#__PURE__*/ new _ShaderImportLoader(\r\n        () => [import(\"../Shaders/default.vertex\"), import(\"../Shaders/default.fragment\")],\r\n        () => [import(\"../ShadersWGSL/default.vertex\"), import(\"../ShadersWGSL/default.fragment\")]\r\n    );\r\n    private _vertexPullingMetadata: Map<string, IVertexPullingMetadata> | null = null;\r\n\r\n    /**\r\n     * Defines additional PrePass parameters for the material.\r\n     */\r\n    public readonly prePassConfiguration: PrePassConfiguration;\r\n\r\n    /**\r\n     * Can this material render to prepass\r\n     */\r\n    public override get isPrePassCapable(): boolean {\r\n        return !this.disableDepthWrite;\r\n    }\r\n\r\n    /**\r\n     * Can this material render to several textures at once\r\n     */\r\n    public override get canRenderToMRT() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Defines the detail map parameters for the material.\r\n     */\r\n    public readonly detailMap: DetailMapConfiguration;\r\n\r\n    protected _renderTargets = new SmartArray<RenderTargetTexture>(16);\r\n    protected _globalAmbientColor = new Color3(0, 0, 0);\r\n    protected _cacheHasRenderTargetTextures = false;\r\n\r\n    /**\r\n     * Instantiates a new standard material.\r\n     * This is the default material used in Babylon. It is the best trade off between quality\r\n     * and performances.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction\r\n     * @param name Define the name of the material in the scene\r\n     * @param scene Define the scene the material belong to\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(name: string, scene?: Scene, forceGLSL = false) {\r\n        super(name, scene, undefined, forceGLSL || StandardMaterial.ForceGLSL);\r\n\r\n        this.detailMap = new DetailMapConfiguration(this);\r\n\r\n        // Setup the default processing configuration to the scene.\r\n        this._attachImageProcessingConfiguration(null);\r\n        this.prePassConfiguration = new PrePassConfiguration();\r\n\r\n        this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {\r\n            this._renderTargets.reset();\r\n\r\n            if (StandardMaterial.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n                this._renderTargets.push(<RenderTargetTexture>this._reflectionTexture);\r\n            }\r\n\r\n            if (StandardMaterial.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {\r\n                this._renderTargets.push(<RenderTargetTexture>this._refractionTexture);\r\n            }\r\n\r\n            this._eventInfo.renderTargets = this._renderTargets;\r\n            this._callbackPluginEventFillRenderTargetTextures(this._eventInfo);\r\n\r\n            return this._renderTargets;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     */\r\n    public override get hasRenderTargetTextures(): boolean {\r\n        if (StandardMaterial.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        if (StandardMaterial.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        return this._cacheHasRenderTargetTextures;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name of the material e.g. \"StandardMaterial\"\r\n     * Mainly use in serialization.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"StandardMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material will require alpha blending\r\n     * @returns a boolean specifying if alpha blending is needed\r\n     */\r\n    public override needAlphaBlending(): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsBlend;\r\n        }\r\n\r\n        if (this._disableAlphaBlending) {\r\n            return false;\r\n        }\r\n\r\n        return (\r\n            this.alpha < 1.0 ||\r\n            this._opacityTexture != null ||\r\n            this._shouldUseAlphaFromDiffuseTexture() ||\r\n            (this._opacityFresnelParameters && this._opacityFresnelParameters.isEnabled)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Specifies if this material should be rendered in alpha test mode\r\n     * @returns a boolean specifying if an alpha test is needed.\r\n     */\r\n    public override needAlphaTesting(): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsTest;\r\n        }\r\n\r\n        return this._hasAlphaChannel() && (this._transparencyMode == null || this._transparencyMode === Material.MATERIAL_ALPHATEST);\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not the alpha value of the diffuse texture should be used for alpha blending.\r\n     */\r\n    protected _shouldUseAlphaFromDiffuseTexture(): boolean {\r\n        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha && this._useAlphaFromDiffuseTexture && this._transparencyMode !== Material.MATERIAL_OPAQUE;\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not there is a usable alpha channel for transparency.\r\n     */\r\n    protected _hasAlphaChannel(): boolean {\r\n        return (this._diffuseTexture != null && this._diffuseTexture.hasAlpha) || this._opacityTexture != null;\r\n    }\r\n\r\n    /**\r\n     * Get the texture used for alpha test purpose.\r\n     * @returns the diffuse texture in case of the standard material.\r\n     */\r\n    public override getAlphaTestTexture(): Nullable<BaseTexture> {\r\n        return this._diffuseTexture;\r\n    }\r\n\r\n    /**\r\n     * Get if the submesh is ready to be used and all its information available.\r\n     * Child classes can use it to update shaders\r\n     * @param mesh defines the mesh to check\r\n     * @param subMesh defines which submesh to check\r\n     * @param useInstances specifies that instances should be used\r\n     * @returns a boolean indicating that the submesh is ready or not\r\n     */\r\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances: boolean = false): boolean {\r\n        if (!this._uniformBufferLayoutBuilt) {\r\n            this.buildUniformLayout();\r\n        }\r\n\r\n        const drawWrapper = subMesh._drawWrapper;\r\n\r\n        if (drawWrapper.effect && this.isFrozen) {\r\n            if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (!subMesh.materialDefines) {\r\n            this._callbackPluginEventGeneric(MaterialPluginEvent.GetDefineNames, this._eventInfo);\r\n            subMesh.materialDefines = new StandardMaterialDefines(this._eventInfo.defineNames);\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const defines = <StandardMaterialDefines>subMesh.materialDefines;\r\n        if (this._isReadyForSubMesh(subMesh)) {\r\n            return true;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        // Lights\r\n        defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);\r\n\r\n        if (!AreLightsTexturesReady(scene, mesh, this._maxSimultaneousLights, this._disableLighting)) {\r\n            return false;\r\n        }\r\n\r\n        // Multiview\r\n        PrepareDefinesForMultiview(scene, defines);\r\n\r\n        // PrePass\r\n        const oit = this.needAlphaBlendingForMesh(mesh) && this.getScene().useOrderIndependentTransparency;\r\n        PrepareDefinesForPrePass(scene, defines, this.canRenderToMRT && !oit);\r\n\r\n        // Order independant transparency\r\n        PrepareDefinesForOIT(scene, defines, oit);\r\n\r\n        MaterialHelperGeometryRendering.PrepareDefines(engine.currentRenderPassId, mesh, defines);\r\n\r\n        // Textures\r\n        if (defines._areTexturesDirty) {\r\n            this._eventInfo.hasRenderTargetTextures = false;\r\n            this._callbackPluginEventHasRenderTargetTextures(this._eventInfo);\r\n            this._cacheHasRenderTargetTextures = this._eventInfo.hasRenderTargetTextures;\r\n            defines._needUVs = false;\r\n            for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n                defines[\"MAINUV\" + i] = false;\r\n            }\r\n            if (scene.texturesEnabled) {\r\n                defines.DIFFUSEDIRECTUV = 0;\r\n                defines.BUMPDIRECTUV = 0;\r\n                defines.AMBIENTDIRECTUV = 0;\r\n                defines.OPACITYDIRECTUV = 0;\r\n                defines.EMISSIVEDIRECTUV = 0;\r\n                defines.SPECULARDIRECTUV = 0;\r\n                defines.LIGHTMAPDIRECTUV = 0;\r\n\r\n                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {\r\n                    if (!this._diffuseTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._diffuseTexture, defines, \"DIFFUSE\");\r\n                    }\r\n                } else {\r\n                    defines.DIFFUSE = false;\r\n                }\r\n\r\n                if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {\r\n                    if (!this._ambientTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._ambientTexture, defines, \"AMBIENT\");\r\n                    }\r\n                } else {\r\n                    defines.AMBIENT = false;\r\n                }\r\n\r\n                if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {\r\n                    if (!this._opacityTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._opacityTexture, defines, \"OPACITY\");\r\n                        defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;\r\n                    }\r\n                } else {\r\n                    defines.OPACITY = false;\r\n                }\r\n                if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {\r\n                    defines.ROUGHNESS = this._roughness > 0;\r\n                    defines.REFLECTIONOVERALPHA = this._useReflectionOverAlpha;\r\n                } else {\r\n                    defines.ROUGHNESS = false;\r\n                    defines.REFLECTIONOVERALPHA = false;\r\n                }\r\n                if (!PrepareDefinesForIBL(scene, this._reflectionTexture, defines)) {\r\n                    return false;\r\n                }\r\n\r\n                if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {\r\n                    if (!this._emissiveTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._emissiveTexture, defines, \"EMISSIVE\");\r\n                    }\r\n                } else {\r\n                    defines.EMISSIVE = false;\r\n                }\r\n\r\n                if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {\r\n                    if (!this._lightmapTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._lightmapTexture, defines, \"LIGHTMAP\");\r\n                        defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;\r\n                        defines.RGBDLIGHTMAP = this._lightmapTexture.isRGBD;\r\n                    }\r\n                } else {\r\n                    defines.LIGHTMAP = false;\r\n                }\r\n\r\n                if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {\r\n                    if (!this._specularTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._specularTexture, defines, \"SPECULAR\");\r\n                        defines.GLOSSINESS = this._useGlossinessFromSpecularMapAlpha;\r\n                    }\r\n                } else {\r\n                    defines.SPECULAR = false;\r\n                }\r\n\r\n                if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && StandardMaterial.BumpTextureEnabled) {\r\n                    // Bump texture can not be not blocking.\r\n                    if (!this._bumpTexture.isReady()) {\r\n                        return false;\r\n                    } else {\r\n                        PrepareDefinesForMergedUV(this._bumpTexture, defines, \"BUMP\");\r\n\r\n                        defines.PARALLAX = this._useParallax;\r\n                        defines.PARALLAX_RHS = scene.useRightHandedSystem;\r\n                        defines.PARALLAXOCCLUSION = this._useParallaxOcclusion;\r\n                    }\r\n\r\n                    defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;\r\n                } else {\r\n                    defines.BUMP = false;\r\n                    defines.PARALLAX = false;\r\n                    defines.PARALLAX_RHS = false;\r\n                    defines.PARALLAXOCCLUSION = false;\r\n                }\r\n\r\n                if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {\r\n                    if (!this._refractionTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    } else {\r\n                        defines._needUVs = true;\r\n                        defines.REFRACTION = true;\r\n\r\n                        defines.REFRACTIONMAP_3D = this._refractionTexture.isCube;\r\n                        defines.RGBDREFRACTION = this._refractionTexture.isRGBD;\r\n                        defines.USE_LOCAL_REFRACTIONMAP_CUBIC = (<any>this._refractionTexture).boundingBoxSize ? true : false;\r\n                    }\r\n                } else {\r\n                    defines.REFRACTION = false;\r\n                }\r\n\r\n                defines.TWOSIDEDLIGHTING = !this._backFaceCulling && this._twoSidedLighting;\r\n            } else {\r\n                defines.DIFFUSE = false;\r\n                defines.AMBIENT = false;\r\n                defines.OPACITY = false;\r\n                defines.REFLECTION = false;\r\n                defines.EMISSIVE = false;\r\n                defines.LIGHTMAP = false;\r\n                defines.BUMP = false;\r\n                defines.REFRACTION = false;\r\n            }\r\n\r\n            defines.ALPHAFROMDIFFUSE = this._shouldUseAlphaFromDiffuseTexture();\r\n\r\n            defines.EMISSIVEASILLUMINATION = this._useEmissiveAsIllumination;\r\n\r\n            defines.LINKEMISSIVEWITHDIFFUSE = this._linkEmissiveWithDiffuse;\r\n\r\n            defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;\r\n\r\n            defines.PREMULTIPLYALPHA = this.alphaMode === Constants.ALPHA_PREMULTIPLIED || this.alphaMode === Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n\r\n            defines.ALPHATEST_AFTERALLALPHACOMPUTATIONS = this.transparencyMode !== null;\r\n\r\n            defines.ALPHABLEND = this.transparencyMode === null || this.needAlphaBlendingForMesh(mesh); // check on null for backward compatibility\r\n\r\n            defines.TEXTURE_REPETITION_MODE = engine.version > 1 || engine.isWebGPU ? this.textureRepetitionMode : 0;\r\n        }\r\n\r\n        this._eventInfo.isReadyForSubMesh = true;\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);\r\n\r\n        if (!this._eventInfo.isReadyForSubMesh) {\r\n            return false;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {\r\n            if (!this._imageProcessingConfiguration.isReady()) {\r\n                return false;\r\n            }\r\n\r\n            this._imageProcessingConfiguration.prepareDefines(defines);\r\n\r\n            defines.IS_REFLECTION_LINEAR = this.reflectionTexture != null && !this.reflectionTexture.gammaSpace;\r\n            defines.IS_REFRACTION_LINEAR = this.refractionTexture != null && !this.refractionTexture.gammaSpace;\r\n        }\r\n\r\n        if (defines._areFresnelDirty) {\r\n            if (StandardMaterial.FresnelEnabled) {\r\n                // Fresnel\r\n                if (\r\n                    this._diffuseFresnelParameters ||\r\n                    this._opacityFresnelParameters ||\r\n                    this._emissiveFresnelParameters ||\r\n                    this._refractionFresnelParameters ||\r\n                    this._reflectionFresnelParameters\r\n                ) {\r\n                    defines.DIFFUSEFRESNEL = this._diffuseFresnelParameters && this._diffuseFresnelParameters.isEnabled;\r\n\r\n                    defines.OPACITYFRESNEL = this._opacityFresnelParameters && this._opacityFresnelParameters.isEnabled;\r\n\r\n                    defines.REFLECTIONFRESNEL = this._reflectionFresnelParameters && this._reflectionFresnelParameters.isEnabled;\r\n\r\n                    defines.REFLECTIONFRESNELFROMSPECULAR = this._useReflectionFresnelFromSpecular;\r\n\r\n                    defines.REFRACTIONFRESNEL = this._refractionFresnelParameters && this._refractionFresnelParameters.isEnabled;\r\n\r\n                    defines.EMISSIVEFRESNEL = this._emissiveFresnelParameters && this._emissiveFresnelParameters.isEnabled;\r\n\r\n                    defines._needNormals = true;\r\n                    defines.FRESNEL = true;\r\n                }\r\n            } else {\r\n                defines.FRESNEL = false;\r\n            }\r\n        }\r\n\r\n        // Check if lights are ready\r\n        if (defines[\"AREALIGHTUSED\"] || defines[\"CLUSTLIGHT_BATCH\"]) {\r\n            for (let index = 0; index < mesh.lightSources.length; index++) {\r\n                if (!mesh.lightSources[index]._isReady()) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Misc.\r\n        PrepareDefinesForMisc(\r\n            mesh,\r\n            scene,\r\n            this._useLogarithmicDepth,\r\n            this.pointsCloud,\r\n            this.fogEnabled,\r\n            this.needAlphaTestingForMesh(mesh),\r\n            defines,\r\n            this._applyDecalMapAfterDetailMap,\r\n            this._useVertexPulling,\r\n            subMesh.getRenderingMesh(),\r\n            this._isVertexOutputInvariant\r\n        );\r\n\r\n        // Values that need to be evaluated on every frame\r\n        PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, subMesh.getRenderingMesh().hasThinInstances);\r\n\r\n        // External config\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.mesh = mesh;\r\n        this._callbackPluginEventPrepareDefinesBeforeAttributes(this._eventInfo);\r\n\r\n        // Attribs\r\n        PrepareDefinesForAttributes(mesh, defines, true, true, true);\r\n\r\n        // External config\r\n        this._callbackPluginEventPrepareDefines(this._eventInfo);\r\n\r\n        // Get correct effect\r\n        let forceWasNotReadyPreviously = false;\r\n\r\n        if (defines.isDirty) {\r\n            const lightDisposed = defines._areLightsDisposed;\r\n            defines.markAsProcessed();\r\n\r\n            // Fallbacks\r\n            const fallbacks = new EffectFallbacks();\r\n            if (defines.REFLECTION) {\r\n                fallbacks.addFallback(0, \"REFLECTION\");\r\n            }\r\n\r\n            if (defines.SPECULAR) {\r\n                fallbacks.addFallback(0, \"SPECULAR\");\r\n            }\r\n\r\n            if (defines.BUMP) {\r\n                fallbacks.addFallback(0, \"BUMP\");\r\n            }\r\n\r\n            if (defines.PARALLAX) {\r\n                fallbacks.addFallback(1, \"PARALLAX\");\r\n            }\r\n\r\n            if (defines.PARALLAX_RHS) {\r\n                fallbacks.addFallback(1, \"PARALLAX_RHS\");\r\n            }\r\n\r\n            if (defines.PARALLAXOCCLUSION) {\r\n                fallbacks.addFallback(0, \"PARALLAXOCCLUSION\");\r\n            }\r\n\r\n            if (defines.SPECULAROVERALPHA) {\r\n                fallbacks.addFallback(0, \"SPECULAROVERALPHA\");\r\n            }\r\n\r\n            if (defines.FOG) {\r\n                fallbacks.addFallback(1, \"FOG\");\r\n            }\r\n\r\n            if (defines.POINTSIZE) {\r\n                fallbacks.addFallback(0, \"POINTSIZE\");\r\n            }\r\n\r\n            if (defines.LOGARITHMICDEPTH) {\r\n                fallbacks.addFallback(0, \"LOGARITHMICDEPTH\");\r\n            }\r\n\r\n            HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights);\r\n\r\n            if (defines.SPECULARTERM) {\r\n                fallbacks.addFallback(0, \"SPECULARTERM\");\r\n            }\r\n\r\n            if (defines.DIFFUSEFRESNEL) {\r\n                fallbacks.addFallback(1, \"DIFFUSEFRESNEL\");\r\n            }\r\n\r\n            if (defines.OPACITYFRESNEL) {\r\n                fallbacks.addFallback(2, \"OPACITYFRESNEL\");\r\n            }\r\n\r\n            if (defines.REFLECTIONFRESNEL) {\r\n                fallbacks.addFallback(3, \"REFLECTIONFRESNEL\");\r\n            }\r\n\r\n            if (defines.EMISSIVEFRESNEL) {\r\n                fallbacks.addFallback(4, \"EMISSIVEFRESNEL\");\r\n            }\r\n\r\n            if (defines.FRESNEL) {\r\n                fallbacks.addFallback(4, \"FRESNEL\");\r\n            }\r\n\r\n            if (defines.MULTIVIEW) {\r\n                fallbacks.addFallback(0, \"MULTIVIEW\");\r\n            }\r\n\r\n            //Attributes\r\n            const attribs = [VertexBuffer.PositionKind];\r\n\r\n            if (defines.NORMAL) {\r\n                attribs.push(VertexBuffer.NormalKind);\r\n            }\r\n\r\n            if (defines.TANGENT) {\r\n                attribs.push(VertexBuffer.TangentKind);\r\n            }\r\n\r\n            for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n                if (defines[\"UV\" + i]) {\r\n                    attribs.push(`uv${i === 1 ? \"\" : i}`);\r\n                }\r\n            }\r\n\r\n            if (defines.VERTEXCOLOR) {\r\n                attribs.push(VertexBuffer.ColorKind);\r\n            }\r\n\r\n            PrepareAttributesForBones(attribs, mesh, defines, fallbacks);\r\n            PrepareAttributesForInstances(attribs, defines);\r\n            PrepareAttributesForMorphTargets(attribs, mesh, defines);\r\n            PrepareAttributesForBakedVertexAnimation(attribs, mesh, defines);\r\n\r\n            let shaderName = \"default\";\r\n\r\n            const uniforms = [\r\n                \"world\",\r\n                \"view\",\r\n                \"viewProjection\",\r\n                \"vEyePosition\",\r\n                \"vLightsType\",\r\n                \"vAmbientColor\",\r\n                \"vDiffuseColor\",\r\n                \"vSpecularColor\",\r\n                \"vEmissiveColor\",\r\n                \"visibility\",\r\n                \"vFogInfos\",\r\n                \"vFogColor\",\r\n                \"pointSize\",\r\n                \"vDiffuseInfos\",\r\n                \"vAmbientInfos\",\r\n                \"vOpacityInfos\",\r\n                \"vEmissiveInfos\",\r\n                \"vSpecularInfos\",\r\n                \"vBumpInfos\",\r\n                \"vLightmapInfos\",\r\n                \"vRefractionInfos\",\r\n                \"mBones\",\r\n                \"diffuseMatrix\",\r\n                \"ambientMatrix\",\r\n                \"opacityMatrix\",\r\n                \"emissiveMatrix\",\r\n                \"specularMatrix\",\r\n                \"bumpMatrix\",\r\n                \"normalMatrix\",\r\n                \"lightmapMatrix\",\r\n                \"refractionMatrix\",\r\n                \"diffuseLeftColor\",\r\n                \"diffuseRightColor\",\r\n                \"opacityParts\",\r\n                \"reflectionLeftColor\",\r\n                \"reflectionRightColor\",\r\n                \"emissiveLeftColor\",\r\n                \"emissiveRightColor\",\r\n                \"refractionLeftColor\",\r\n                \"refractionRightColor\",\r\n                \"vRefractionPosition\",\r\n                \"vRefractionSize\",\r\n                \"logarithmicDepthConstant\",\r\n                \"vTangentSpaceParams\",\r\n                \"alphaCutOff\",\r\n                \"boneTextureInfo\",\r\n                \"morphTargetTextureInfo\",\r\n                \"morphTargetTextureIndices\",\r\n                \"cameraInfo\",\r\n                \"vTextureRepetitionHexTilingParams\",\r\n            ];\r\n\r\n            const samplers = [\r\n                \"diffuseSampler\",\r\n                \"ambientSampler\",\r\n                \"opacitySampler\",\r\n                \"reflectionCubeSampler\",\r\n                \"reflection2DSampler\",\r\n                \"emissiveSampler\",\r\n                \"specularSampler\",\r\n                \"bumpSampler\",\r\n                \"lightmapSampler\",\r\n                \"refractionCubeSampler\",\r\n                \"refraction2DSampler\",\r\n                \"boneSampler\",\r\n                \"morphTargets\",\r\n                \"oitDepthSampler\",\r\n                \"oitFrontColorSampler\",\r\n                \"areaLightsLTC1Sampler\",\r\n                \"areaLightsLTC2Sampler\",\r\n            ];\r\n\r\n            PrepareUniformsAndSamplersForIBL(uniforms, samplers, false);\r\n            const uniformBuffers = [\"Material\", \"Scene\", \"Mesh\"];\r\n\r\n            const indexParameters = { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS };\r\n\r\n            this._eventInfo.fallbacks = fallbacks;\r\n            this._eventInfo.fallbackRank = 0;\r\n            this._eventInfo.defines = defines;\r\n            this._eventInfo.uniforms = uniforms;\r\n            this._eventInfo.attributes = attribs;\r\n            this._eventInfo.samplers = samplers;\r\n            this._eventInfo.uniformBuffersNames = uniformBuffers;\r\n            this._eventInfo.customCode = undefined;\r\n            this._eventInfo.mesh = mesh;\r\n            this._eventInfo.indexParameters = indexParameters;\r\n            this._callbackPluginEventGeneric(MaterialPluginEvent.PrepareEffect, this._eventInfo);\r\n\r\n            MaterialHelperGeometryRendering.AddUniformsAndSamplers(uniforms, samplers);\r\n\r\n            PrePassConfiguration.AddUniforms(uniforms);\r\n            PrePassConfiguration.AddSamplers(samplers);\r\n\r\n            if (ImageProcessingConfiguration) {\r\n                ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);\r\n                ImageProcessingConfiguration.PrepareSamplers(samplers, defines);\r\n            }\r\n\r\n            PrepareUniformsAndSamplersList(<IEffectCreationOptions>{\r\n                uniformsNames: uniforms,\r\n                uniformBuffersNames: uniformBuffers,\r\n                samplers: samplers,\r\n                defines: defines,\r\n                maxSimultaneousLights: this._maxSimultaneousLights,\r\n                shaderLanguage: this._shaderLanguage,\r\n            });\r\n\r\n            AddClipPlaneUniforms(uniforms);\r\n\r\n            // Vertex pulling metadata uniforms\r\n            if (this._useVertexPulling) {\r\n                const renderingMesh = subMesh.getRenderingMesh();\r\n                const geometry = renderingMesh?.geometry;\r\n                if (geometry) {\r\n                    this._vertexPullingMetadata = PrepareVertexPullingUniforms(geometry);\r\n                    if (this._vertexPullingMetadata) {\r\n                        this._vertexPullingMetadata.forEach((_, attribute) => {\r\n                            uniforms.push(`vp_${attribute}_info`);\r\n                        });\r\n                    }\r\n                }\r\n            } else {\r\n                this._vertexPullingMetadata = null;\r\n            }\r\n\r\n            const csnrOptions: ICustomShaderNameResolveOptions = {};\r\n\r\n            if (this.customShaderNameResolve) {\r\n                shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines, attribs, csnrOptions);\r\n            }\r\n\r\n            const join = defines.toString();\r\n\r\n            const previousEffect = subMesh.effect;\r\n            const effect = scene.getEngine().createEffect(\r\n                shaderName,\r\n                <IEffectCreationOptions>{\r\n                    attributes: attribs,\r\n                    uniformsNames: uniforms,\r\n                    uniformBuffersNames: uniformBuffers,\r\n                    samplers: samplers,\r\n                    defines: join,\r\n                    fallbacks: fallbacks,\r\n                    onCompiled: this.onCompiled,\r\n                    onError: this.onError,\r\n                    indexParameters,\r\n                    processFinalCode: csnrOptions.processFinalCode,\r\n                    processCodeAfterIncludes: this._eventInfo.customCode,\r\n                    multiTarget: defines.PREPASS,\r\n                    shaderLanguage: this._shaderLanguage,\r\n                    extraInitializationsAsync: StandardMaterial._ShaderLoader.getLoadCallback(this._shaderLanguage),\r\n                },\r\n                engine\r\n            );\r\n\r\n            this._eventInfo.customCode = undefined;\r\n\r\n            if (effect) {\r\n                if (this._onEffectCreatedObservable) {\r\n                    onCreatedEffectParameters.effect = effect;\r\n                    onCreatedEffectParameters.subMesh = subMesh;\r\n                    this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);\r\n                }\r\n\r\n                // Use previous effect while new one is compiling\r\n                if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {\r\n                    defines.markAsUnprocessed();\r\n\r\n                    forceWasNotReadyPreviously = this.isFrozen;\r\n\r\n                    if (lightDisposed) {\r\n                        // re register in case it takes more than one frame.\r\n                        defines._areLightsDisposed = true;\r\n                        return false;\r\n                    }\r\n                } else {\r\n                    scene.resetCachedMaterial();\r\n                    subMesh.setEffect(effect, defines, this._materialContext);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!subMesh.effect || !subMesh.effect.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        defines._renderId = scene.getRenderId();\r\n        drawWrapper._wasPreviouslyReady = forceWasNotReadyPreviously ? false : true;\r\n        drawWrapper._wasPreviouslyUsingInstances = useInstances;\r\n\r\n        this._checkScenePerformancePriority();\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Builds the material UBO layouts.\r\n     * Used internally during the effect preparation.\r\n     */\r\n    public override buildUniformLayout(): void {\r\n        // Order is important !\r\n        const ubo = this._uniformBuffer;\r\n        ubo.addUniform(\"diffuseLeftColor\", 4);\r\n        ubo.addUniform(\"diffuseRightColor\", 4);\r\n        ubo.addUniform(\"opacityParts\", 4);\r\n        ubo.addUniform(\"reflectionLeftColor\", 4);\r\n        ubo.addUniform(\"reflectionRightColor\", 4);\r\n        ubo.addUniform(\"refractionLeftColor\", 4);\r\n        ubo.addUniform(\"refractionRightColor\", 4);\r\n        ubo.addUniform(\"emissiveLeftColor\", 4);\r\n        ubo.addUniform(\"emissiveRightColor\", 4);\r\n\r\n        ubo.addUniform(\"vDiffuseInfos\", 2);\r\n        ubo.addUniform(\"vAmbientInfos\", 2);\r\n        ubo.addUniform(\"vOpacityInfos\", 2);\r\n        ubo.addUniform(\"vEmissiveInfos\", 2);\r\n        ubo.addUniform(\"vLightmapInfos\", 2);\r\n        ubo.addUniform(\"vSpecularInfos\", 2);\r\n        ubo.addUniform(\"vBumpInfos\", 3);\r\n\r\n        ubo.addUniform(\"diffuseMatrix\", 16);\r\n        ubo.addUniform(\"ambientMatrix\", 16);\r\n        ubo.addUniform(\"opacityMatrix\", 16);\r\n        ubo.addUniform(\"emissiveMatrix\", 16);\r\n        ubo.addUniform(\"lightmapMatrix\", 16);\r\n        ubo.addUniform(\"specularMatrix\", 16);\r\n        ubo.addUniform(\"bumpMatrix\", 16);\r\n        ubo.addUniform(\"vTangentSpaceParams\", 2);\r\n        ubo.addUniform(\"pointSize\", 1);\r\n        ubo.addUniform(\"alphaCutOff\", 1);\r\n        ubo.addUniform(\"refractionMatrix\", 16);\r\n        ubo.addUniform(\"vRefractionInfos\", 4);\r\n        ubo.addUniform(\"vRefractionPosition\", 3);\r\n        ubo.addUniform(\"vRefractionSize\", 3);\r\n        ubo.addUniform(\"vSpecularColor\", 4);\r\n        ubo.addUniform(\"vEmissiveColor\", 3);\r\n        ubo.addUniform(\"vDiffuseColor\", 4);\r\n        ubo.addUniform(\"vAmbientColor\", 3);\r\n        ubo.addUniform(\"cameraInfo\", 4);\r\n        ubo.addUniform(\"vTextureRepetitionHexTilingParams\", 4);\r\n\r\n        PrepareUniformLayoutForIBL(ubo, false, true);\r\n\r\n        super.buildUniformLayout();\r\n    }\r\n\r\n    /**\r\n     * Binds the submesh to this material by preparing the effect and shader to draw\r\n     * @param world defines the world transformation matrix\r\n     * @param mesh defines the mesh containing the submesh\r\n     * @param subMesh defines the submesh to bind the material to\r\n     */\r\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\r\n        const scene = this.getScene();\r\n\r\n        const defines = <StandardMaterialDefines>subMesh.materialDefines;\r\n        if (!defines) {\r\n            return;\r\n        }\r\n\r\n        const effect = subMesh.effect;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n        this._activeEffect = effect;\r\n\r\n        // Matrices Mesh.\r\n        mesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n        mesh.transferToEffect(world);\r\n\r\n        // Binding unconditionally\r\n        this._uniformBuffer.bindToEffect(effect, \"Material\");\r\n\r\n        this.prePassConfiguration.bindForSubMesh(this._activeEffect, scene, mesh, world, this.isFrozen);\r\n\r\n        MaterialHelperGeometryRendering.Bind(scene.getEngine().currentRenderPassId, this._activeEffect, mesh, world, this);\r\n\r\n        const camera = scene.activeCamera;\r\n        if (camera) {\r\n            this._uniformBuffer.updateFloat4(\"cameraInfo\", camera.minZ, camera.maxZ, 0, 0);\r\n        } else {\r\n            this._uniformBuffer.updateFloat4(\"cameraInfo\", 0, 0, 0, 0);\r\n        }\r\n\r\n        const hexParams = this.textureRepetitionHexTilingParams;\r\n        this._uniformBuffer.updateFloat4(\"vTextureRepetitionHexTilingParams\", hexParams[0], hexParams[1], hexParams[2], hexParams[3]);\r\n\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventHardBindForSubMesh(this._eventInfo);\r\n\r\n        // Normal Matrix\r\n        if (defines.OBJECTSPACE_NORMALMAP) {\r\n            world.toNormalMatrix(this._normalMatrix);\r\n            this.bindOnlyNormalMatrix(this._normalMatrix);\r\n        }\r\n\r\n        const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);\r\n        const needToAlwaysBindUniformBuffers = scene.getEngine()._features.needToAlwaysBindUniformBuffers;\r\n\r\n        // Bones\r\n        BindBonesParameters(mesh, effect);\r\n\r\n        // Vertex pulling\r\n        if (this._vertexPullingMetadata) {\r\n            BindVertexPullingUniforms(effect, this._vertexPullingMetadata);\r\n        }\r\n\r\n        const ubo = this._uniformBuffer;\r\n        if (mustRebind) {\r\n            this.bindViewProjection(effect);\r\n            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync || subMesh._drawWrapper._forceRebindOnNextCall) {\r\n                if (StandardMaterial.FresnelEnabled && defines.FRESNEL) {\r\n                    // Fresnel\r\n                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {\r\n                        ubo.updateColor4(\"diffuseLeftColor\", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);\r\n                        ubo.updateColor4(\"diffuseRightColor\", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);\r\n                    }\r\n\r\n                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {\r\n                        const opacityParts = TmpColors.Color3[0];\r\n                        opacityParts.set(\r\n                            this.opacityFresnelParameters.leftColor.toLuminance(),\r\n                            this.opacityFresnelParameters.rightColor.toLuminance(),\r\n                            this.opacityFresnelParameters.bias\r\n                        );\r\n                        ubo.updateColor4(\"opacityParts\", opacityParts, this.opacityFresnelParameters.power);\r\n                    }\r\n\r\n                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {\r\n                        ubo.updateColor4(\"reflectionLeftColor\", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);\r\n                        ubo.updateColor4(\"reflectionRightColor\", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);\r\n                    }\r\n\r\n                    if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {\r\n                        ubo.updateColor4(\"refractionLeftColor\", this.refractionFresnelParameters.leftColor, this.refractionFresnelParameters.power);\r\n                        ubo.updateColor4(\"refractionRightColor\", this.refractionFresnelParameters.rightColor, this.refractionFresnelParameters.bias);\r\n                    }\r\n\r\n                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {\r\n                        ubo.updateColor4(\"emissiveLeftColor\", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);\r\n                        ubo.updateColor4(\"emissiveRightColor\", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);\r\n                    }\r\n                }\r\n\r\n                // The alpha test compares against alphaCutOff whatever supplies the alpha: a texture, vertex or\r\n                // instance color, opacity fresnel or the material alpha. Binding it only when a texture carried\r\n                // alpha left every other case testing against the default of 0, so nothing was ever discarded.\r\n                if (defines.ALPHATEST) {\r\n                    ubo.updateFloat(\"alphaCutOff\", this.alphaCutOff);\r\n                }\r\n\r\n                // Textures\r\n                if (scene.texturesEnabled) {\r\n                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {\r\n                        ubo.updateFloat2(\"vDiffuseInfos\", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);\r\n                        BindTextureMatrix(this._diffuseTexture, ubo, \"diffuse\");\r\n                    }\r\n\r\n                    if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {\r\n                        ubo.updateFloat2(\"vAmbientInfos\", this._ambientTexture.coordinatesIndex, this._ambientTexture.level);\r\n                        BindTextureMatrix(this._ambientTexture, ubo, \"ambient\");\r\n                    }\r\n\r\n                    if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {\r\n                        ubo.updateFloat2(\"vOpacityInfos\", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);\r\n                        BindTextureMatrix(this._opacityTexture, ubo, \"opacity\");\r\n                    }\r\n\r\n                    BindIBLParameters(scene, defines, ubo, Color3.White(), this._reflectionTexture, false, false, true, false, false, false, this.roughness);\r\n                    if (!this._reflectionTexture || !StandardMaterial.ReflectionTextureEnabled) {\r\n                        ubo.updateFloat2(\"vReflectionInfos\", 0.0, this.roughness);\r\n                    }\r\n\r\n                    if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {\r\n                        ubo.updateFloat2(\"vEmissiveInfos\", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);\r\n                        BindTextureMatrix(this._emissiveTexture, ubo, \"emissive\");\r\n                    }\r\n\r\n                    if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {\r\n                        ubo.updateFloat2(\"vLightmapInfos\", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);\r\n                        BindTextureMatrix(this._lightmapTexture, ubo, \"lightmap\");\r\n                    }\r\n\r\n                    if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {\r\n                        ubo.updateFloat2(\"vSpecularInfos\", this._specularTexture.coordinatesIndex, this._specularTexture.level);\r\n                        BindTextureMatrix(this._specularTexture, ubo, \"specular\");\r\n                    }\r\n\r\n                    if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {\r\n                        ubo.updateFloat3(\"vBumpInfos\", this._bumpTexture.coordinatesIndex, 1.0 / this._bumpTexture.level, this.parallaxScaleBias);\r\n                        BindTextureMatrix(this._bumpTexture, ubo, \"bump\");\r\n\r\n                        if (scene._mirroredCameraPosition) {\r\n                            ubo.updateFloat2(\"vTangentSpaceParams\", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);\r\n                        } else {\r\n                            ubo.updateFloat2(\"vTangentSpaceParams\", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);\r\n                        }\r\n                    }\r\n\r\n                    if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {\r\n                        let depth = 1.0;\r\n                        if (!this._refractionTexture.isCube) {\r\n                            ubo.updateMatrix(\"refractionMatrix\", this._refractionTexture.getReflectionTextureMatrix());\r\n\r\n                            if ((<any>this._refractionTexture).depth) {\r\n                                depth = (<any>this._refractionTexture).depth;\r\n                            }\r\n                        }\r\n                        ubo.updateFloat4(\"vRefractionInfos\", this._refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);\r\n\r\n                        if ((<any>this._refractionTexture).boundingBoxSize) {\r\n                            const cubeTexture = <CubeTexture>this._refractionTexture;\r\n\r\n                            ubo.updateVector3(\"vRefractionPosition\", cubeTexture.boundingBoxPosition);\r\n                            ubo.updateVector3(\"vRefractionSize\", cubeTexture.boundingBoxSize);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Point size\r\n                if (this.pointsCloud) {\r\n                    ubo.updateFloat(\"pointSize\", this.pointSize);\r\n                }\r\n\r\n                ubo.updateColor4(\"vSpecularColor\", this.specularColor, this.specularPower);\r\n\r\n                ubo.updateColor3(\"vEmissiveColor\", StandardMaterial.EmissiveTextureEnabled ? this.emissiveColor : Color3.BlackReadOnly);\r\n                ubo.updateColor4(\"vDiffuseColor\", this.diffuseColor, this.alpha);\r\n\r\n                scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);\r\n                ubo.updateColor3(\"vAmbientColor\", this._globalAmbientColor);\r\n            }\r\n\r\n            // Textures\r\n            if (scene.texturesEnabled) {\r\n                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {\r\n                    effect.setTexture(\"diffuseSampler\", this._diffuseTexture);\r\n                }\r\n\r\n                if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {\r\n                    effect.setTexture(\"ambientSampler\", this._ambientTexture);\r\n                }\r\n\r\n                if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {\r\n                    effect.setTexture(\"opacitySampler\", this._opacityTexture);\r\n                }\r\n\r\n                if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {\r\n                    if (this._reflectionTexture.isCube) {\r\n                        effect.setTexture(\"reflectionCubeSampler\", this._reflectionTexture);\r\n                    } else {\r\n                        effect.setTexture(\"reflection2DSampler\", this._reflectionTexture);\r\n                    }\r\n                }\r\n\r\n                if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {\r\n                    effect.setTexture(\"emissiveSampler\", this._emissiveTexture);\r\n                }\r\n\r\n                if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {\r\n                    effect.setTexture(\"lightmapSampler\", this._lightmapTexture);\r\n                }\r\n\r\n                if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {\r\n                    effect.setTexture(\"specularSampler\", this._specularTexture);\r\n                }\r\n\r\n                if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {\r\n                    effect.setTexture(\"bumpSampler\", this._bumpTexture);\r\n                }\r\n\r\n                if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {\r\n                    if (this._refractionTexture.isCube) {\r\n                        effect.setTexture(\"refractionCubeSampler\", this._refractionTexture);\r\n                    } else {\r\n                        effect.setTexture(\"refraction2DSampler\", this._refractionTexture);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // OIT with depth peeling\r\n            if (this.getScene().useOrderIndependentTransparency && this.needAlphaBlendingForMesh(mesh)) {\r\n                this.getScene().depthPeelingRenderer!.bind(effect);\r\n            }\r\n\r\n            this._eventInfo.subMesh = subMesh;\r\n            this._callbackPluginEventBindForSubMesh(this._eventInfo);\r\n\r\n            // Clip plane\r\n            BindClipPlane(effect, this, scene);\r\n\r\n            // Colors\r\n            this.bindEyePosition(effect);\r\n        } else if (needToAlwaysBindUniformBuffers) {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n\r\n        // Lights\r\n        if ((mustRebind || !this.isFrozen || needToAlwaysBindUniformBuffers) && scene.lightsEnabled && !this._disableLighting) {\r\n            BindLights(scene, mesh, effect, defines, this._maxSimultaneousLights);\r\n        }\r\n\r\n        if (mustRebind || !this.isFrozen) {\r\n            // View\r\n            if (\r\n                (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) ||\r\n                this._reflectionTexture ||\r\n                this._refractionTexture ||\r\n                mesh.receiveShadows ||\r\n                defines.PREPASS ||\r\n                defines[\"CLUSTLIGHT_BATCH\"]\r\n            ) {\r\n                this.bindView(effect);\r\n            }\r\n\r\n            // Fog\r\n            BindFogParameters(scene, mesh, effect);\r\n\r\n            // Morph targets\r\n            if (defines.NUM_MORPH_INFLUENCERS) {\r\n                BindMorphTargetParameters(mesh, effect);\r\n            }\r\n\r\n            if (defines.BAKED_VERTEX_ANIMATION_TEXTURE) {\r\n                mesh.bakedVertexAnimationManager?.bind(effect, defines.INSTANCES);\r\n            }\r\n\r\n            // Log. depth\r\n            if (this.useLogarithmicDepth) {\r\n                BindLogDepth(defines, effect, scene);\r\n            }\r\n\r\n            // image processing\r\n            if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {\r\n                this._imageProcessingConfiguration.bind(this._activeEffect);\r\n            }\r\n        }\r\n\r\n        this._afterBind(mesh, this._activeEffect, subMesh);\r\n        ubo.update();\r\n    }\r\n\r\n    /**\r\n     * Get the list of animatables in the material.\r\n     * @returns the list of animatables object used in the material\r\n     */\r\n    public override getAnimatables(): IAnimatable[] {\r\n        const results = super.getAnimatables();\r\n\r\n        if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {\r\n            results.push(this._diffuseTexture);\r\n        }\r\n\r\n        if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {\r\n            results.push(this._ambientTexture);\r\n        }\r\n\r\n        if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {\r\n            results.push(this._opacityTexture);\r\n        }\r\n\r\n        if (this._reflectionTexture && this._reflectionTexture.animations && this._reflectionTexture.animations.length > 0) {\r\n            results.push(this._reflectionTexture);\r\n        }\r\n\r\n        if (this._emissiveTexture && this._emissiveTexture.animations && this._emissiveTexture.animations.length > 0) {\r\n            results.push(this._emissiveTexture);\r\n        }\r\n\r\n        if (this._specularTexture && this._specularTexture.animations && this._specularTexture.animations.length > 0) {\r\n            results.push(this._specularTexture);\r\n        }\r\n\r\n        if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {\r\n            results.push(this._bumpTexture);\r\n        }\r\n\r\n        if (this._lightmapTexture && this._lightmapTexture.animations && this._lightmapTexture.animations.length > 0) {\r\n            results.push(this._lightmapTexture);\r\n        }\r\n\r\n        if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) {\r\n            results.push(this._refractionTexture);\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Gets the active textures from the material\r\n     * @returns an array of textures\r\n     */\r\n    public override getActiveTextures(): BaseTexture[] {\r\n        const activeTextures = super.getActiveTextures();\r\n\r\n        if (this._diffuseTexture) {\r\n            activeTextures.push(this._diffuseTexture);\r\n        }\r\n\r\n        if (this._ambientTexture) {\r\n            activeTextures.push(this._ambientTexture);\r\n        }\r\n\r\n        if (this._opacityTexture) {\r\n            activeTextures.push(this._opacityTexture);\r\n        }\r\n\r\n        if (this._reflectionTexture) {\r\n            activeTextures.push(this._reflectionTexture);\r\n        }\r\n\r\n        if (this._emissiveTexture) {\r\n            activeTextures.push(this._emissiveTexture);\r\n        }\r\n\r\n        if (this._specularTexture) {\r\n            activeTextures.push(this._specularTexture);\r\n        }\r\n\r\n        if (this._bumpTexture) {\r\n            activeTextures.push(this._bumpTexture);\r\n        }\r\n\r\n        if (this._lightmapTexture) {\r\n            activeTextures.push(this._lightmapTexture);\r\n        }\r\n\r\n        if (this._refractionTexture) {\r\n            activeTextures.push(this._refractionTexture);\r\n        }\r\n\r\n        return activeTextures;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material uses a texture\r\n     * @param texture defines the texture to check against the material\r\n     * @returns a boolean specifying if the material uses the texture\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (super.hasTexture(texture)) {\r\n            return true;\r\n        }\r\n\r\n        if (this._diffuseTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._ambientTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._opacityTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._reflectionTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._emissiveTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._specularTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._bumpTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._lightmapTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._refractionTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Disposes the material\r\n     * @param forceDisposeEffect specifies if effects should be forcefully disposed\r\n     * @param forceDisposeTextures specifies if textures should be forcefully disposed\r\n     */\r\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            this._diffuseTexture?.dispose();\r\n            this._ambientTexture?.dispose();\r\n            this._opacityTexture?.dispose();\r\n            this._reflectionTexture?.dispose();\r\n            this._emissiveTexture?.dispose();\r\n            this._specularTexture?.dispose();\r\n            this._bumpTexture?.dispose();\r\n            this._lightmapTexture?.dispose();\r\n            this._refractionTexture?.dispose();\r\n        }\r\n\r\n        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n        }\r\n\r\n        super.dispose(forceDisposeEffect, forceDisposeTextures);\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the material, and gives it a new name\r\n     * @param name defines the new name for the duplicated material\r\n     * @param cloneTexturesOnlyOnce - if a texture is used in more than one channel (e.g diffuse and opacity), only clone it once and reuse it on the other channels. Default false.\r\n     * @param rootUrl defines the root URL to use to load textures\r\n     * @returns the cloned material\r\n     */\r\n    public override clone(name: string, cloneTexturesOnlyOnce: boolean = true, rootUrl = \"\"): StandardMaterial {\r\n        const result = SerializationHelper.Clone(() => new StandardMaterial(name, this.getScene()), this, { cloneTexturesOnlyOnce });\r\n\r\n        result.name = name;\r\n        result.id = name;\r\n\r\n        this.stencil.copyTo(result.stencil);\r\n\r\n        this._clonePlugins(result, rootUrl);\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a standard material from parsed material data\r\n     * @param source defines the JSON representation of the material\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @returns a new standard material\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {\r\n        const material = SerializationHelper.Parse(() => new StandardMaterial(source.name, scene), source, scene, rootUrl);\r\n\r\n        if (source.stencil) {\r\n            material.stencil.parse(source.stencil, scene, rootUrl);\r\n        }\r\n\r\n        Material._ParsePlugins(source, material, scene, rootUrl);\r\n\r\n        return material;\r\n    }\r\n\r\n    // Flags used to enable or disable a type of texture for all Standard Materials\r\n    /**\r\n     * Are diffuse textures enabled in the application.\r\n     */\r\n    public static get DiffuseTextureEnabled(): boolean {\r\n        return MaterialFlags.DiffuseTextureEnabled;\r\n    }\r\n    public static set DiffuseTextureEnabled(value: boolean) {\r\n        MaterialFlags.DiffuseTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are detail textures enabled in the application.\r\n     */\r\n    public static get DetailTextureEnabled(): boolean {\r\n        return MaterialFlags.DetailTextureEnabled;\r\n    }\r\n    public static set DetailTextureEnabled(value: boolean) {\r\n        MaterialFlags.DetailTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are ambient textures enabled in the application.\r\n     */\r\n    public static get AmbientTextureEnabled(): boolean {\r\n        return MaterialFlags.AmbientTextureEnabled;\r\n    }\r\n    public static set AmbientTextureEnabled(value: boolean) {\r\n        MaterialFlags.AmbientTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are opacity textures enabled in the application.\r\n     */\r\n    public static get OpacityTextureEnabled(): boolean {\r\n        return MaterialFlags.OpacityTextureEnabled;\r\n    }\r\n    public static set OpacityTextureEnabled(value: boolean) {\r\n        MaterialFlags.OpacityTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are reflection textures enabled in the application.\r\n     */\r\n    public static get ReflectionTextureEnabled(): boolean {\r\n        return MaterialFlags.ReflectionTextureEnabled;\r\n    }\r\n    public static set ReflectionTextureEnabled(value: boolean) {\r\n        MaterialFlags.ReflectionTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are emissive textures enabled in the application.\r\n     */\r\n    public static get EmissiveTextureEnabled(): boolean {\r\n        return MaterialFlags.EmissiveTextureEnabled;\r\n    }\r\n    public static set EmissiveTextureEnabled(value: boolean) {\r\n        MaterialFlags.EmissiveTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are specular textures enabled in the application.\r\n     */\r\n    public static get SpecularTextureEnabled(): boolean {\r\n        return MaterialFlags.SpecularTextureEnabled;\r\n    }\r\n    public static set SpecularTextureEnabled(value: boolean) {\r\n        MaterialFlags.SpecularTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are bump textures enabled in the application.\r\n     */\r\n    public static get BumpTextureEnabled(): boolean {\r\n        return MaterialFlags.BumpTextureEnabled;\r\n    }\r\n    public static set BumpTextureEnabled(value: boolean) {\r\n        MaterialFlags.BumpTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are lightmap textures enabled in the application.\r\n     */\r\n    public static get LightmapTextureEnabled(): boolean {\r\n        return MaterialFlags.LightmapTextureEnabled;\r\n    }\r\n    public static set LightmapTextureEnabled(value: boolean) {\r\n        MaterialFlags.LightmapTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are refraction textures enabled in the application.\r\n     */\r\n    public static get RefractionTextureEnabled(): boolean {\r\n        return MaterialFlags.RefractionTextureEnabled;\r\n    }\r\n    public static set RefractionTextureEnabled(value: boolean) {\r\n        MaterialFlags.RefractionTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are color grading textures enabled in the application.\r\n     */\r\n    public static get ColorGradingTextureEnabled(): boolean {\r\n        return MaterialFlags.ColorGradingTextureEnabled;\r\n    }\r\n    public static set ColorGradingTextureEnabled(value: boolean) {\r\n        MaterialFlags.ColorGradingTextureEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Are fresnels enabled in the application.\r\n     */\r\n    public static get FresnelEnabled(): boolean {\r\n        return MaterialFlags.FresnelEnabled;\r\n    }\r\n    public static set FresnelEnabled(value: boolean) {\r\n        MaterialFlags.FresnelEnabled = value;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for standardMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStandardMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // StandardMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\r\n    RegisterImageProcessingConfiguration();\r\n\r\n    RegisterClass(\"BABYLON.StandardMaterial\", StandardMaterial);\r\n\r\n    Scene.DefaultMaterialFactory = (scene: Scene) => {\r\n        return new StandardMaterial(\"default material\", scene);\r\n    };\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffectProperty } from \"../Misc/devTools\";\r\n\r\nif (!Object.getOwnPropertyDescriptor(StandardMaterial.prototype, \"decalMap\")) {\r\n    Object.defineProperty(StandardMaterial.prototype, \"decalMap\", _MissingSideEffectProperty(\"StandardMaterial\", \"decalMap\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { GetExponentOfTwo } from \"core/Misc/tools.functions\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { InternalTextureSource, InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type ImageSource, type Nullable } from \"../../types\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineDynamicTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineDynamicTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.createDynamicTexture = function (width: number, height: number, generateMipMaps: boolean, samplingMode: number): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Dynamic);\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n\r\n        if (generateMipMaps) {\r\n            width = this.needPOTTextures ? GetExponentOfTwo(width, this._caps.maxTextureSize) : width;\r\n            height = this.needPOTTextures ? GetExponentOfTwo(height, this._caps.maxTextureSize) : height;\r\n        }\r\n\r\n        //  this.resetTextureCache();\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.isReady = false;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n\r\n        this.updateTextureSamplingMode(samplingMode, texture);\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinEngine.prototype.updateDynamicTexture = function (\r\n        texture: Nullable<InternalTexture>,\r\n        source: ImageSource,\r\n        invertY?: boolean,\r\n        premulAlpha: boolean = false,\r\n        format?: number,\r\n        forceBindTexture: boolean = false,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        allowGPUOptimization: boolean = false\r\n    ): void {\r\n        if (!texture) {\r\n            return;\r\n        }\r\n\r\n        const gl = this._gl;\r\n        const target = gl.TEXTURE_2D;\r\n\r\n        const wasPreviouslyBound = this._bindTextureDirectly(target, texture, true, forceBindTexture);\r\n\r\n        this._unpackFlipY(invertY === undefined ? texture.invertY : invertY);\r\n\r\n        if (premulAlpha) {\r\n            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);\r\n        }\r\n\r\n        const textureType = this._getWebGLTextureType(texture.type);\r\n        const glformat = this._getInternalFormat(format ? format : texture.format);\r\n        const internalFormat = this._getRGBABufferInternalSizedFormat(texture.type, glformat);\r\n\r\n        gl.texImage2D(target, 0, internalFormat, glformat, textureType, source as TexImageSource);\r\n\r\n        if (texture.generateMipMaps) {\r\n            gl.generateMipmap(target);\r\n        }\r\n\r\n        if (!wasPreviouslyBound) {\r\n            this._bindTextureDirectly(target, null);\r\n        }\r\n\r\n        if (premulAlpha) {\r\n            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\r\n        }\r\n\r\n        if (format) {\r\n            texture.format = format;\r\n        }\r\n\r\n        texture._dynamicTextureSource = source;\r\n        texture._premulAlpha = premulAlpha;\r\n        texture.invertY = invertY || false;\r\n        texture.isReady = true;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type ISize } from \"../../Maths/math.size\";\r\nimport { type ITextureCreationOptions, Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type ICanvas, type ICanvasRenderingContext } from \"../../Engines/ICanvas\";\r\nimport { RegisterEnginesExtensionsEngineDynamicTexture } from \"../../Engines/Extensions/engine.dynamicTexture.pure\";\r\n\r\n/**\r\n * Interface defining options used to create a dynamic texture\r\n */\r\nexport interface IDynamicTextureOptions extends ITextureCreationOptions {\r\n    /** defines the width of the texture (default: 0) */\r\n    width?: number;\r\n    /** defines the height of the texture (default: 0) */\r\n    height?: number;\r\n    /** defines the hosting scene (default: null) */\r\n    scene?: Nullable<Scene>;\r\n}\r\n\r\n/**\r\n * A class extending Texture allowing drawing on a texture\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/dynamicTexture\r\n */\r\nexport class DynamicTexture extends Texture {\r\n    private _generateMipMaps: boolean;\r\n    private _canvas: ICanvas;\r\n    private _ownCanvas: boolean;\r\n    private _context: ICanvasRenderingContext;\r\n\r\n    /**\r\n     * Creates a DynamicTexture\r\n     * @param name defines the name of the texture\r\n     * @param canvasOrSize provides 3 alternatives for width and height of texture, a canvas, object with width and height properties, number for both width and height\r\n     * @param options The options to be used when constructing the dynamic texture\r\n     */\r\n    constructor(name: string, canvasOrSize: ICanvas | { width: number; height: number } | number, options?: IDynamicTextureOptions);\r\n\r\n    /**\r\n     * Creates a DynamicTexture\r\n     * @param name defines the name of the texture\r\n     * @param options provides 3 alternatives for width and height of texture, a canvas, object with width and height properties, number for both width and height\r\n     * @param scene defines the scene where you want the texture\r\n     * @param generateMipMaps defines the use of MipMaps or not (default is false)\r\n     * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)\r\n     * @param format defines the texture format to use (default is Engine.TEXTUREFORMAT_RGBA)\r\n     * @param invertY defines if the texture needs to be inverted on the y axis during loading\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: ICanvas | { width: number; height: number } | number,\r\n        scene?: Nullable<Scene>,\r\n        generateMipMaps?: boolean,\r\n        samplingMode?: number,\r\n        format?: number,\r\n        invertY?: boolean\r\n    );\r\n\r\n    /** @internal */\r\n    constructor(\r\n        name: string,\r\n        canvasOrSize: ICanvas | { width: number; height: number } | number,\r\n        sceneOrOptions?: Nullable<Scene> | IDynamicTextureOptions,\r\n        generateMipMaps?: boolean,\r\n        samplingMode?: number,\r\n        format?: number,\r\n        invertY?: boolean\r\n    );\r\n\r\n    /** @internal */\r\n    constructor(\r\n        name: string,\r\n        canvasOrSize: ICanvas | { width: number; height: number } | number,\r\n        sceneOrOptions?: Nullable<Scene> | IDynamicTextureOptions,\r\n        generateMipMaps: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA,\r\n        invertY?: boolean\r\n    ) {\r\n        const isScene = !sceneOrOptions || (sceneOrOptions as Scene)._isScene;\r\n        const scene = isScene ? (sceneOrOptions as Scene) : (sceneOrOptions as IDynamicTextureOptions)?.scene;\r\n        const noMipmap = isScene ? !generateMipMaps : (sceneOrOptions as IDynamicTextureOptions);\r\n\r\n        super(null, scene, noMipmap, invertY, samplingMode, undefined, undefined, undefined, undefined, format);\r\n\r\n        RegisterEnginesExtensionsEngineDynamicTexture();\r\n\r\n        this.name = name;\r\n        this.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n\r\n        this._generateMipMaps = generateMipMaps;\r\n\r\n        const engine = this._getEngine();\r\n        if (!engine) {\r\n            return;\r\n        }\r\n\r\n        if ((canvasOrSize as ICanvas).getContext) {\r\n            this._canvas = canvasOrSize as ICanvas;\r\n            this._ownCanvas = false;\r\n            this._texture = engine.createDynamicTexture(this._canvas.width, this._canvas.height, generateMipMaps, samplingMode);\r\n        } else {\r\n            this._canvas = engine.createCanvas(1, 1);\r\n            this._ownCanvas = true;\r\n\r\n            const optionsAsSize = canvasOrSize as ISize;\r\n            if (optionsAsSize.width || optionsAsSize.width === 0) {\r\n                this._texture = engine.createDynamicTexture(optionsAsSize.width, optionsAsSize.height, generateMipMaps, samplingMode);\r\n            } else {\r\n                this._texture = engine.createDynamicTexture(canvasOrSize as number, canvasOrSize as number, generateMipMaps, samplingMode);\r\n            }\r\n        }\r\n\r\n        const textureSize = this.getSize();\r\n\r\n        if (this._canvas.width !== textureSize.width) {\r\n            this._canvas.width = textureSize.width;\r\n        }\r\n        if (this._canvas.height !== textureSize.height) {\r\n            this._canvas.height = textureSize.height;\r\n        }\r\n        this._context = this._canvas.getContext(\"2d\");\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the texture useful for serialization or dynamic coding.\r\n     * @returns \"DynamicTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DynamicTexture\";\r\n    }\r\n\r\n    /**\r\n     * Gets the current state of canRescale\r\n     */\r\n    public override get canRescale(): boolean {\r\n        return true;\r\n    }\r\n\r\n    private _recreate(textureSize: ISize): void {\r\n        this._canvas.width = textureSize.width;\r\n        this._canvas.height = textureSize.height;\r\n\r\n        this.releaseInternalTexture();\r\n\r\n        this._texture = this._getEngine()!.createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this.samplingMode);\r\n    }\r\n\r\n    /**\r\n     * Scales the texture\r\n     * @param ratio the scale factor to apply to both width and height\r\n     */\r\n    public override scale(ratio: number): void {\r\n        const textureSize = this.getSize();\r\n\r\n        textureSize.width *= ratio;\r\n        textureSize.height *= ratio;\r\n\r\n        this._recreate(textureSize);\r\n    }\r\n\r\n    /**\r\n     * Resizes the texture\r\n     * @param width the new width\r\n     * @param height the new height\r\n     */\r\n    public scaleTo(width: number, height: number): void {\r\n        const textureSize = this.getSize();\r\n\r\n        textureSize.width = width;\r\n        textureSize.height = height;\r\n\r\n        this._recreate(textureSize);\r\n    }\r\n\r\n    /**\r\n     * Gets the context of the canvas used by the texture\r\n     * @returns the canvas context of the dynamic texture\r\n     */\r\n    public getContext(): ICanvasRenderingContext {\r\n        return this._context;\r\n    }\r\n\r\n    /**\r\n     * Clears the texture\r\n     * @param clearColor Defines the clear color to use\r\n     */\r\n    public clear(clearColor?: string): void {\r\n        const size = this.getSize();\r\n        if (clearColor) {\r\n            this._context.fillStyle = clearColor;\r\n        }\r\n        this._context.clearRect(0, 0, size.width, size.height);\r\n    }\r\n\r\n    /**\r\n     * Updates the texture\r\n     * @param invertY defines the direction for the Y axis (default is true - y increases downwards)\r\n     * @param premulAlpha defines if alpha is stored as premultiplied (default is false)\r\n     * @param allowGPUOptimization true to allow some specific GPU optimizations (subject to engine feature \"allowGPUOptimizationsForGUI\" being true)\r\n     */\r\n    public update(invertY?: boolean, premulAlpha = false, allowGPUOptimization = false): void {\r\n        // When disposed, this._texture will be null.\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n\r\n        this._getEngine()!.updateDynamicTexture(\r\n            this._texture,\r\n            this._canvas,\r\n            invertY === undefined ? true : invertY,\r\n            premulAlpha,\r\n            this._format || undefined,\r\n            undefined,\r\n            allowGPUOptimization\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Draws text onto the texture\r\n     * @param text defines the text to be drawn\r\n     * @param x defines the placement of the text from the left\r\n     * @param y defines the placement of the text from the top when invertY is true and from the bottom when false\r\n     * @param font defines the font to be used with font-style, font-size, font-name\r\n     * @param color defines the color used for the text\r\n     * @param fillColor defines the color for the canvas, use null to not overwrite canvas (this blends with the background to replace, use the clear function)\r\n     * @param invertY defines the direction for the Y axis (default is true - y increases downwards)\r\n     * @param update defines whether texture is immediately update (default is true)\r\n     */\r\n    public drawText(\r\n        text: string,\r\n        x: number | null | undefined,\r\n        y: number | null | undefined,\r\n        font: string,\r\n        color: string | null,\r\n        fillColor: string | null,\r\n        invertY?: boolean,\r\n        update = true\r\n    ) {\r\n        const size = this.getSize();\r\n        if (fillColor) {\r\n            this._context.fillStyle = fillColor;\r\n            this._context.fillRect(0, 0, size.width, size.height);\r\n        }\r\n\r\n        this._context.font = font;\r\n        if (x === null || x === undefined) {\r\n            const textSize = this._context.measureText(text);\r\n            x = (size.width - textSize.width) / 2;\r\n        }\r\n        if (y === null || y === undefined) {\r\n            const fontSize = parseInt(font.replace(/\\D/g, \"\"));\r\n            y = size.height / 2 + fontSize / 3.65;\r\n        }\r\n\r\n        this._context.fillStyle = color || \"\";\r\n        this._context.fillText(text, x, y);\r\n\r\n        if (update) {\r\n            this.update(invertY);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the dynamic texture.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        if (this._ownCanvas) {\r\n            this._canvas?.remove?.();\r\n        }\r\n        (this._canvas as any) = null;\r\n        (this._context as any) = null;\r\n    }\r\n\r\n    /**\r\n     * Clones the texture\r\n     * @returns the clone of the texture.\r\n     */\r\n    public override clone(): DynamicTexture {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return this;\r\n        }\r\n\r\n        const textureSize = this.getSize();\r\n        const newTexture = new DynamicTexture(this.name, textureSize, scene, this._generateMipMaps);\r\n\r\n        // Base texture\r\n        newTexture.hasAlpha = this.hasAlpha;\r\n        newTexture.level = this.level;\r\n\r\n        // Dynamic Texture\r\n        newTexture.wrapU = this.wrapU;\r\n        newTexture.wrapV = this.wrapV;\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Serializes the dynamic texture.  The scene should be ready before the dynamic texture is serialized\r\n     * @returns a serialized dynamic texture object\r\n     */\r\n    public override serialize(): any {\r\n        const scene = this.getScene();\r\n        if (scene && !scene.isReady()) {\r\n            Logger.Warn(\"The scene must be ready before serializing the dynamic texture\");\r\n        }\r\n\r\n        const serializationObject = super.serialize();\r\n        if (DynamicTexture._IsCanvasElement(this._canvas)) {\r\n            serializationObject.base64String = this._canvas.toDataURL();\r\n        }\r\n\r\n        serializationObject.invertY = this._invertY;\r\n        serializationObject.samplingMode = this.samplingMode;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    private static _IsCanvasElement(canvas: HTMLCanvasElement | OffscreenCanvas | ICanvas): canvas is HTMLCanvasElement {\r\n        return (canvas as HTMLCanvasElement).toDataURL !== undefined;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _rebuild(): void {\r\n        this.update();\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\r\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\r\n\r\n/** Covers all supported subclasses of WebXR's XRCompositionLayer */\r\nexport type WebXRCompositionLayerType = \"XRProjectionLayer\";\r\n\r\n/**\r\n * The quad-layer type name.\r\n */\r\nexport type WebXRQuadLayerType = \"XRQuadLayer\";\r\n\r\n/** Covers all supported subclasses of WebXR's XRLayer */\r\nexport type WebXRLayerType = \"XRWebGLLayer\" | WebXRCompositionLayerType | WebXRQuadLayerType;\r\n\r\n/** Covers the spatial composition-layer types supported by WebXRLayers. */\r\nexport type WebXRSpatialLayerType = WebXRQuadLayerType | \"XRCylinderLayer\" | \"XREquirectLayer\" | \"XRCubeLayer\";\r\n\r\n/** Covers every native layer type supported by Babylon.js. */\r\nexport type WebXRSupportedLayerType = WebXRLayerType | WebXRSpatialLayerType;\r\n\r\n/**\r\n * Wrapper over subclasses of XRLayer.\r\n * @internal\r\n */\r\nexport class WebXRLayerWrapper<LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType> {\r\n    private _rttWrapper: Nullable<WebXRLayerRenderTargetTextureProvider<LayerTypeT>> = null;\r\n\r\n    /**\r\n     * The render target provider created for this layer, or `null` until one is created.\r\n     */\r\n    public get renderTargetTextureProvider(): Nullable<WebXRLayerRenderTargetTextureProvider<LayerTypeT>> {\r\n        return this._rttWrapper;\r\n    }\r\n    /**\r\n     * Check if fixed foveation is supported by the wrapped XRWebGLLayer or XRProjectionLayer.\r\n     */\r\n    public get isFixedFoveationSupported(): boolean {\r\n        const isFoveationLayer = this.layerType === \"XRWebGLLayer\" || this.layerType === \"XRProjectionLayer\";\r\n        return isFoveationLayer && typeof (this.layer as XRWebGLLayer | XRProjectionLayer).fixedFoveation === \"number\";\r\n    }\r\n\r\n    /**\r\n     * Gets the fixed foveation currently set, as specified by the WebXR specs.\r\n     * @returns The fixed foveation level, or `null` when fixed foveation is not supported.\r\n     */\r\n    public get fixedFoveation(): Nullable<number> {\r\n        if (this.isFixedFoveationSupported) {\r\n            return (this.layer as XRWebGLLayer | XRProjectionLayer).fixedFoveation ?? null;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the fixed foveation level, as specified by the WebXR specs.\r\n     * The value is normalized between 0 and 1, where 1 is maximum foveation and 0 is no foveation.\r\n     * Unsupported native layers ignore the assignment, matching the WebXR fixed-foveation contract.\r\n     * @param value The fixed foveation level, or `null` to use no foveation.\r\n     */\r\n    public set fixedFoveation(value: Nullable<number>) {\r\n        if (this.isFixedFoveationSupported) {\r\n            const val = Math.max(0, Math.min(1, value || 0));\r\n            (this.layer as XRWebGLLayer | XRProjectionLayer).fixedFoveation = val;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a render target provider for the wrapped layer.\r\n     * @param xrSessionManager The XR Session Manager\r\n     * @returns A new render target texture provider for the wrapped layer.\r\n     */\r\n    public createRenderTargetTextureProvider(xrSessionManager: WebXRSessionManager): WebXRLayerRenderTargetTextureProvider<LayerTypeT> {\r\n        this._rttWrapper = this._createRenderTargetTextureProvider(xrSessionManager);\r\n        return this._rttWrapper;\r\n    }\r\n\r\n    /**\r\n     * Disposes the render target provider created for this layer.\r\n     */\r\n    public dispose(): void {\r\n        if (this._rttWrapper) {\r\n            this._rttWrapper.dispose();\r\n            this._rttWrapper = null;\r\n        }\r\n    }\r\n\r\n    protected constructor(\r\n        /** The width of the layer's framebuffer. */\r\n        public getWidth: () => number,\r\n        /** The height of the layer's framebuffer. */\r\n        public getHeight: () => number,\r\n        /** The XR layer that this WebXRLayerWrapper wraps. */\r\n        public readonly layer: XRLayer,\r\n        /** The type of XR layer that is being wrapped. */\r\n        public readonly layerType: LayerTypeT,\r\n        /** Create a render target provider for the wrapped layer. */\r\n        private _createRenderTargetTextureProvider: (xrSessionManager: WebXRSessionManager) => WebXRLayerRenderTargetTextureProvider<LayerTypeT>\r\n    ) {}\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { MultiviewRenderTarget } from \"../Materials/Textures/MultiviewRenderTarget\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Viewport } from \"../Maths/math.viewport\";\r\nimport { type IDisposable, type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type WebXRLayerType, type WebXRLayerWrapper, type WebXRSupportedLayerType } from \"./webXRLayerWrapper\";\r\n\r\n/**\r\n * An interface for objects that provide render target textures for XR rendering.\r\n */\r\nexport interface IWebXRRenderTargetTextureProvider extends IDisposable {\r\n    /**\r\n     * Attempts to set the framebuffer-size-normalized viewport to be rendered this frame for this view.\r\n     * In the event of a failure, the supplied viewport is not updated.\r\n     * @param viewport the viewport to which the view will be rendered\r\n     * @param view the view for which to set the viewport\r\n     * @returns whether the operation was successful\r\n     */\r\n    trySetViewportForView(viewport: Viewport, view: XRView): boolean;\r\n    /**\r\n     * Gets the correct render target texture to be rendered this frame for this eye\r\n     * @param eye the eye for which to get the render target\r\n     * @returns the render target for the specified eye or null if not available\r\n     */\r\n    getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture>;\r\n    /**\r\n     * Gets the correct render target texture to be rendered this frame for this view\r\n     * @param view the view for which to get the render target\r\n     * @returns the render target for the specified view or null if not available\r\n     */\r\n    getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture>;\r\n}\r\n\r\n/**\r\n * Provides render target textures and other important rendering information for a given XRLayer.\r\n * @internal\r\n */\r\nexport abstract class WebXRLayerRenderTargetTextureProvider<LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType> implements IWebXRRenderTargetTextureProvider {\r\n    public abstract trySetViewportForView(viewport: Viewport, view: XRView): boolean;\r\n    public abstract getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture>;\r\n    public abstract getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture>;\r\n\r\n    protected _renderTargetTextures = new Array<RenderTargetTexture>();\r\n    protected _framebufferDimensions: Nullable<{ framebufferWidth: number; framebufferHeight: number }>;\r\n\r\n    protected _engine: AbstractEngine;\r\n\r\n    constructor(\r\n        protected readonly _scene: Scene,\r\n        public readonly layerWrapper: WebXRLayerWrapper<LayerTypeT>\r\n    ) {\r\n        this._engine = _scene.getEngine();\r\n    }\r\n\r\n    /**\r\n     * Creates the render target texture \"shell\" (with the correct multiview type and MSAA sample count)\r\n     * without attaching any graphics-API-specific resource. Subclasses attach their own textures.\r\n     * @param width the width of the render target\r\n     * @param height the height of the render target\r\n     * @param multiview whether the render target should be a multiview render target\r\n     * @returns the created (but not yet registered) render target texture\r\n     */\r\n    protected _createRenderTargetTextureShell(width: number, height: number, multiview: boolean): RenderTargetTexture {\r\n        const textureSize = { width, height };\r\n        const renderTargetTexture = multiview ? new MultiviewRenderTarget(this._scene, textureSize) : new RenderTargetTexture(\"XR renderTargetTexture\", textureSize, this._scene);\r\n        renderTargetTexture.renderTarget!._samples = renderTargetTexture.samples;\r\n        return renderTargetTexture;\r\n    }\r\n\r\n    /**\r\n     * Builds a render target texture from already-wrapped internal textures, without referencing any\r\n     * graphics-API-specific type. A GPU-based backend (e.g. WebGPU / XRGPUBinding) wraps its native\r\n     * textures with the engine and calls this hook; the WebGL backend has its own typed entry point.\r\n     * @param width the width of the render target\r\n     * @param height the height of the render target\r\n     * @param colorTexture the internal texture to use as the color attachment, if any\r\n     * @param depthStencilTexture the internal texture to use as the depth/stencil attachment, if any\r\n     * @param multiview whether the render target should be a multiview render target\r\n     * @returns the created render target texture\r\n     */\r\n    protected _createRenderTargetTextureInternal(\r\n        width: number,\r\n        height: number,\r\n        colorTexture: Nullable<InternalTexture>,\r\n        depthStencilTexture: Nullable<InternalTexture>,\r\n        multiview: boolean\r\n    ): RenderTargetTexture {\r\n        if (multiview) {\r\n            // The multiview color/depth array wiring is not implemented on this API-agnostic hook yet.\r\n            // The WebGL provider still owns the array path via its own _createRenderTargetTexture.\r\n            throw new Error(\"Multiview render targets are not yet supported by the API-agnostic render target creation path.\");\r\n        }\r\n        const renderTargetTexture = this._createRenderTargetTextureShell(width, height, multiview);\r\n        const renderTargetWrapper = renderTargetTexture.renderTarget!;\r\n\r\n        if (colorTexture) {\r\n            renderTargetWrapper.setTexture(colorTexture, 0);\r\n            renderTargetTexture._texture = colorTexture;\r\n        }\r\n\r\n        if (depthStencilTexture) {\r\n            renderTargetWrapper._depthStencilTexture = depthStencilTexture;\r\n        }\r\n\r\n        renderTargetTexture.disableRescaling();\r\n\r\n        this._renderTargetTextures.push(renderTargetTexture);\r\n\r\n        return renderTargetTexture;\r\n    }\r\n\r\n    protected _destroyRenderTargetTexture(renderTargetTexture: RenderTargetTexture) {\r\n        this._renderTargetTextures.splice(this._renderTargetTextures.indexOf(renderTargetTexture), 1);\r\n        renderTargetTexture.dispose();\r\n    }\r\n\r\n    public getFramebufferDimensions(): Nullable<{ framebufferWidth: number; framebufferHeight: number }> {\r\n        return this._framebufferDimensions;\r\n    }\r\n\r\n    public dispose() {\r\n        for (const rtt of this._renderTargetTextures) {\r\n            rtt.dispose();\r\n        }\r\n        this._renderTargetTextures.length = 0;\r\n    }\r\n}\r\n","import { type ThinEngine } from \"../Engines/thinEngine\";\nimport { WebGLHardwareTexture } from \"../Engines/WebGL/webGLHardwareTexture\";\nimport { type WebGLRenderTargetWrapper } from \"../Engines/WebGL/webGLRenderTargetWrapper\";\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\nimport { type Nullable } from \"../types\";\nimport { WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\nimport { type WebXRLayerType, type WebXRSupportedLayerType } from \"./webXRLayerWrapper\";\n\n/**\n * Provides render target textures for WebGL-backed XR layers. Owns all WebGL-specific\n * framebuffer/texture wiring so the base provider can stay graphics-API-agnostic.\n * @internal\n */\nexport abstract class WebXRWebGLRenderTargetTextureProvider<LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType> extends WebXRLayerRenderTargetTextureProvider<LayerTypeT> {\n    private _createInternalTexture(textureSize: { width: number; height: number }, texture: WebGLTexture): InternalTexture {\n        const gl = (this._engine as ThinEngine)._gl;\n        if (!gl) {\n            throw new Error(\"WebXRWebGLRenderTargetTextureProvider requires a WebGL-capable engine.\");\n        }\n        const internalTexture = new InternalTexture(this._engine, InternalTextureSource.Unknown, true);\n        internalTexture.width = textureSize.width;\n        internalTexture.height = textureSize.height;\n        internalTexture._hardwareTexture = new WebGLHardwareTexture(texture, gl);\n        internalTexture.isReady = true;\n        return internalTexture;\n    }\n\n    protected _createRenderTargetTexture(\n        width: number,\n        height: number,\n        framebuffer: Nullable<WebGLFramebuffer>,\n        colorTexture?: WebGLTexture,\n        depthStencilTexture?: WebGLTexture,\n        multiview?: boolean\n    ): RenderTargetTexture {\n        if (!this._engine) {\n            throw new Error(\"Engine is disposed\");\n        }\n\n        const textureSize = { width, height };\n\n        const renderTargetTexture = this._createRenderTargetTextureShell(width, height, !!multiview);\n        const renderTargetWrapper = renderTargetTexture.renderTarget as WebGLRenderTargetWrapper;\n        // Set the framebuffer, make sure it works in all scenarios - emulator, no layers and layers.\n        // This must happen before binding any texture, since setTexture binds it to the framebuffer.\n        if (framebuffer || !colorTexture) {\n            renderTargetWrapper._framebuffer = framebuffer;\n        }\n\n        // Create internal texture\n        if (colorTexture) {\n            if (multiview) {\n                renderTargetWrapper._colorTextureArray = colorTexture;\n            } else {\n                const internalTexture = this._createInternalTexture(textureSize, colorTexture);\n                renderTargetWrapper.setTexture(internalTexture, 0);\n                renderTargetTexture._texture = internalTexture;\n            }\n        }\n\n        if (depthStencilTexture) {\n            if (multiview) {\n                renderTargetWrapper._depthStencilTextureArray = depthStencilTexture;\n            } else {\n                renderTargetWrapper._depthStencilTexture = this._createInternalTexture(textureSize, depthStencilTexture);\n            }\n        }\n\n        renderTargetTexture.disableRescaling();\n\n        this._renderTargetTextures.push(renderTargetTexture);\n\n        return renderTargetTexture;\n    }\n}\n","import { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { type Viewport } from \"../Maths/math.viewport\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\nimport { WebXRWebGLRenderTargetTextureProvider } from \"./webXRWebGLRenderTargetTextureProvider\";\r\n\r\n/**\r\n * Wraps xr webgl layers.\r\n * @internal\r\n */\r\nexport class WebXRWebGLLayerWrapper extends WebXRLayerWrapper {\r\n    /**\r\n     * @param layer is the layer to be wrapped.\r\n     * @returns a new WebXRLayerWrapper wrapping the provided XRWebGLLayer.\r\n     */\r\n    constructor(public override readonly layer: XRWebGLLayer) {\r\n        super(\r\n            () => layer.framebufferWidth,\r\n            () => layer.framebufferHeight,\r\n            layer,\r\n            \"XRWebGLLayer\",\r\n            (sessionManager) => new WebXRWebGLLayerRenderTargetTextureProvider(sessionManager.scene, this)\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Provides render target textures and other important rendering information for a given XRWebGLLayer.\r\n * @internal\r\n */\r\nexport class WebXRWebGLLayerRenderTargetTextureProvider extends WebXRWebGLRenderTargetTextureProvider {\r\n    // The dimensions will always be defined in this class.\r\n    protected override _framebufferDimensions: { framebufferWidth: number; framebufferHeight: number };\r\n    private _rtt: Nullable<RenderTargetTexture>;\r\n    private _framebuffer: WebGLFramebuffer;\r\n    private _layer: XRWebGLLayer;\r\n\r\n    constructor(\r\n        scene: Scene,\r\n        public override readonly layerWrapper: WebXRWebGLLayerWrapper\r\n    ) {\r\n        super(scene, layerWrapper);\r\n        this._layer = layerWrapper.layer;\r\n        this._framebufferDimensions = {\r\n            framebufferWidth: this._layer.framebufferWidth,\r\n            framebufferHeight: this._layer.framebufferHeight,\r\n        };\r\n    }\r\n\r\n    public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n        const xrViewport = this._layer.getViewport(view);\r\n        if (!xrViewport) {\r\n            return false;\r\n        }\r\n        const framebufferWidth = this._framebufferDimensions.framebufferWidth;\r\n        const framebufferHeight = this._framebufferDimensions.framebufferHeight;\r\n        viewport.x = xrViewport.x / framebufferWidth;\r\n        viewport.y = xrViewport.y / framebufferHeight;\r\n        viewport.width = xrViewport.width / framebufferWidth;\r\n        viewport.height = xrViewport.height / framebufferHeight;\r\n        return true;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\r\n        const layerWidth = this._layer.framebufferWidth;\r\n        const layerHeight = this._layer.framebufferHeight;\r\n        const framebuffer = this._layer.framebuffer;\r\n\r\n        if (\r\n            !this._rtt ||\r\n            layerWidth !== this._framebufferDimensions.framebufferWidth ||\r\n            layerHeight !== this._framebufferDimensions.framebufferHeight ||\r\n            framebuffer !== this._framebuffer\r\n        ) {\r\n            this._rtt = this._createRenderTargetTexture(layerWidth, layerHeight, framebuffer);\r\n            this._framebufferDimensions.framebufferWidth = layerWidth;\r\n            this._framebufferDimensions.framebufferHeight = layerHeight;\r\n            this._framebuffer = framebuffer;\r\n        }\r\n\r\n        return this._rtt;\r\n    }\r\n\r\n    public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n        return this.getRenderTargetTextureForEye(view.eye);\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\nimport { WebXRWebGLLayerWrapper } from \"./webXRWebGLLayer\";\r\n\r\n/**\r\n * Configuration object for WebXR output canvas\r\n */\r\nexport class WebXRManagedOutputCanvasOptions {\r\n    /**\r\n     * An optional canvas in case you wish to create it yourself and provide it here.\r\n     * If not provided, a new canvas will be created\r\n     */\r\n    public canvasElement?: HTMLCanvasElement;\r\n    /**\r\n     * Options for this XR Layer output\r\n     */\r\n    public canvasOptions?: XRWebGLLayerInit;\r\n    /**\r\n     * CSS styling for a newly created canvas (if not provided)\r\n     */\r\n    public newCanvasCssStyle?: string;\r\n\r\n    /**\r\n     * Get the default values of the configuration object\r\n     * @param engine defines the engine to use (can be null)\r\n     * @returns default values of this configuration object\r\n     */\r\n    public static GetDefaults(engine?: AbstractEngine): WebXRManagedOutputCanvasOptions {\r\n        const defaults = new WebXRManagedOutputCanvasOptions();\r\n        defaults.canvasOptions = {\r\n            antialias: true,\r\n            depth: true,\r\n            stencil: engine ? engine.isStencilEnable : true,\r\n            alpha: true,\r\n            framebufferScaleFactor: 1,\r\n        };\r\n\r\n        defaults.newCanvasCssStyle = \"position:absolute; bottom:0px;right:0px;z-index:10;width:90%;height:100%;background-color: #000000;\";\r\n\r\n        return defaults;\r\n    }\r\n}\r\n/**\r\n * Creates a canvas that is added/removed from the webpage when entering/exiting XR\r\n */\r\nexport class WebXRManagedOutputCanvas implements WebXRRenderTarget {\r\n    private _canvas: Nullable<HTMLCanvasElement> = null;\r\n    private _engine: Nullable<AbstractEngine> = null;\r\n    private _originalCanvasSize: {\r\n        width: number;\r\n        height: number;\r\n    };\r\n\r\n    /**\r\n     * Rendering context of the canvas which can be used to display/mirror xr content\r\n     */\r\n    public canvasContext: WebGL2RenderingContext;\r\n\r\n    /**\r\n     * xr layer for the canvas\r\n     */\r\n    public xrLayer: Nullable<XRWebGLLayer> = null;\r\n\r\n    private _xrLayerWrapper: Nullable<WebXRLayerWrapper> = null;\r\n\r\n    /**\r\n     * Observers registered here will be triggered when the xr layer was initialized\r\n     */\r\n    public onXRLayerInitObservable: Observable<XRWebGLLayer> = new Observable();\r\n\r\n    private _canvasCompatiblePromise: Promise<void>;\r\n\r\n    /**\r\n     * Initializes the canvas to be added/removed upon entering/exiting xr\r\n     * @param _xrSessionManager The XR Session manager\r\n     * @param _options optional configuration for this canvas output. defaults will be used if not provided\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private _options: WebXRManagedOutputCanvasOptions = WebXRManagedOutputCanvasOptions.GetDefaults()\r\n    ) {\r\n        this._engine = _xrSessionManager.scene.getEngine();\r\n        this._engine.onDisposeObservable.addOnce(() => {\r\n            this._engine = null;\r\n        });\r\n\r\n        if (!_options.canvasElement) {\r\n            const canvas = document.createElement(\"canvas\");\r\n            canvas.style.cssText = this._options.newCanvasCssStyle || \"position:absolute; bottom:0px;right:0px;\";\r\n            this._setManagedOutputCanvas(canvas);\r\n        } else {\r\n            this._setManagedOutputCanvas(_options.canvasElement);\r\n        }\r\n\r\n        _xrSessionManager.onXRSessionInit.add(() => {\r\n            this._addCanvas();\r\n        });\r\n\r\n        _xrSessionManager.onXRSessionEnded.add(() => {\r\n            this._removeCanvas();\r\n        });\r\n\r\n        this._makeCanvasCompatible();\r\n    }\r\n\r\n    /**\r\n     * Disposes of the object\r\n     */\r\n    public dispose() {\r\n        this._removeCanvas();\r\n        this._setManagedOutputCanvas(null);\r\n        this.onXRLayerInitObservable.clear();\r\n    }\r\n\r\n    private _makeCanvasCompatible() {\r\n        this._canvasCompatiblePromise = new Promise<void>((resolve, reject) => {\r\n            // stay safe - make sure the context has the function\r\n            try {\r\n                if (this.canvasContext && (this.canvasContext as any).makeXRCompatible) {\r\n                    // eslint-disable-next-line github/no-then\r\n                    this.canvasContext.makeXRCompatible().then(\r\n                        () => {\r\n                            resolve();\r\n                        },\r\n                        () => {\r\n                            // fail silently\r\n                            Tools.Warn(\"Error executing makeXRCompatible. This does not mean that the session will work incorrectly.\");\r\n                            resolve();\r\n                        }\r\n                    );\r\n                } else {\r\n                    resolve();\r\n                }\r\n            } catch (e) {\r\n                // if this fails - the exception will be caught and the promise will be rejected\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                reject(e);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Initializes a XRWebGLLayer to be used as the session's baseLayer.\r\n     * @param xrSession xr session\r\n     * @returns a promise that will resolve once the XR Layer has been created\r\n     */\r\n    public async initializeXRLayerAsync(xrSession: XRSession): Promise<XRWebGLLayer> {\r\n        const createLayer = () => {\r\n            this.xrLayer = this._createXRLayer(xrSession);\r\n            this._xrLayerWrapper = new WebXRWebGLLayerWrapper(this.xrLayer);\r\n            this.onXRLayerInitObservable.notifyObservers(this.xrLayer);\r\n            return this.xrLayer;\r\n        };\r\n\r\n        return await this._canvasCompatiblePromise\r\n            // eslint-disable-next-line github/no-then\r\n            .then(\r\n                // catch any error and continue. When using the emulator is throws this error for no apparent reason.\r\n                () => {},\r\n                () => {}\r\n            )\r\n            // eslint-disable-next-line github/no-then\r\n            .then(() => {\r\n                return createLayer();\r\n            });\r\n    }\r\n\r\n    /**\r\n     * Creates the XR layer that will be used as the session's baseLayer.\r\n     * This is the WebGL-specific seam: a non-WebGL backend can override it to build a different layer type.\r\n     * @param xrSession the xr session the layer is created for\r\n     * @returns the created XR layer\r\n     */\r\n    protected _createXRLayer(xrSession: XRSession): XRWebGLLayer {\r\n        return new XRWebGLLayer(xrSession, this.canvasContext, this._options.canvasOptions);\r\n    }\r\n\r\n    private _addCanvas() {\r\n        if (this._canvas && this._engine && this._canvas !== this._engine.getRenderingCanvas()) {\r\n            document.body.appendChild(this._canvas);\r\n        }\r\n        if (this.xrLayer) {\r\n            this._setCanvasSize(true);\r\n        } else {\r\n            this.onXRLayerInitObservable.addOnce(() => {\r\n                this._setCanvasSize(true);\r\n            });\r\n        }\r\n    }\r\n\r\n    private _removeCanvas() {\r\n        if (this._canvas && this._engine && document.body.contains(this._canvas) && this._canvas !== this._engine.getRenderingCanvas()) {\r\n            document.body.removeChild(this._canvas);\r\n        }\r\n        this._setCanvasSize(false);\r\n    }\r\n\r\n    private _setCanvasSize(init: boolean = true, xrLayer = this._xrLayerWrapper) {\r\n        if (!this._canvas || !this._engine) {\r\n            return;\r\n        }\r\n        if (init) {\r\n            if (xrLayer) {\r\n                if (this._canvas !== this._engine.getRenderingCanvas()) {\r\n                    this._canvas.style.width = xrLayer.getWidth() + \"px\";\r\n                    this._canvas.style.height = xrLayer.getHeight() + \"px\";\r\n                } else {\r\n                    this._engine.setSize(xrLayer.getWidth(), xrLayer.getHeight());\r\n                }\r\n            }\r\n        } else {\r\n            if (this._originalCanvasSize) {\r\n                if (this._canvas !== this._engine.getRenderingCanvas()) {\r\n                    this._canvas.style.width = this._originalCanvasSize.width + \"px\";\r\n                    this._canvas.style.height = this._originalCanvasSize.height + \"px\";\r\n                } else {\r\n                    this._engine.setSize(this._originalCanvasSize.width, this._originalCanvasSize.height);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _setManagedOutputCanvas(canvas: Nullable<HTMLCanvasElement>) {\r\n        this._removeCanvas();\r\n        if (!canvas) {\r\n            this._canvas = null;\r\n            (this.canvasContext as any) = null;\r\n        } else {\r\n            this._originalCanvasSize = {\r\n                width: canvas.offsetWidth,\r\n                height: canvas.offsetHeight,\r\n            };\r\n            this._canvas = canvas;\r\n            this.canvasContext = this._createXRCompatibleRenderingContext(canvas);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates the rendering context used for the XR layer.\r\n     * This is the WebGL-specific seam: a non-WebGL backend can override it to obtain a different context.\r\n     * @param canvas the canvas to obtain the context from\r\n     * @returns the rendering context to use for the XR layer\r\n     */\r\n    protected _createXRCompatibleRenderingContext(canvas: HTMLCanvasElement): WebGL2RenderingContext {\r\n        let context = <any>canvas.getContext(\"webgl2\");\r\n        if (!context) {\r\n            context = <any>canvas.getContext(\"webgl\");\r\n        }\r\n        return context;\r\n    }\r\n}\r\n","import { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture\";\r\nimport { type Viewport } from \"../../Maths/math.viewport\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { WebXRLayerWrapper } from \"../webXRLayerWrapper\";\r\nimport { type WebXRLayerRenderTargetTextureProvider } from \"../webXRRenderTargetTextureProvider\";\r\nimport { WebXRWebGLRenderTargetTextureProvider } from \"../webXRWebGLRenderTargetTextureProvider\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type WebXRRenderTarget } from \"../webXRTypes\";\r\n\r\n/**\r\n * Wraps XRWebGLLayer's created by Babylon Native.\r\n * @internal\r\n */\r\nexport class NativeXRLayerWrapper extends WebXRLayerWrapper {\r\n    constructor(public override readonly layer: XRWebGLLayer) {\r\n        super(\r\n            () => layer.framebufferWidth,\r\n            () => layer.framebufferHeight,\r\n            layer,\r\n            \"XRWebGLLayer\",\r\n            (sessionManager) => new NativeXRLayerRenderTargetTextureProvider(sessionManager, this)\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Provides render target textures for layers created by Babylon Native.\r\n * @internal\r\n */\r\nexport class NativeXRLayerRenderTargetTextureProvider extends WebXRWebGLRenderTargetTextureProvider {\r\n    private _nativeRTTProvider: WebXRLayerRenderTargetTextureProvider;\r\n    private _nativeLayer: XRWebGLLayer;\r\n\r\n    constructor(\r\n        sessionManager: WebXRSessionManager,\r\n        public override readonly layerWrapper: NativeXRLayerWrapper\r\n    ) {\r\n        super(sessionManager.scene, layerWrapper);\r\n        this._nativeRTTProvider = (navigator as any).xr.getNativeRenderTargetProvider(\r\n            sessionManager.session,\r\n            this._createRenderTargetTexture.bind(this),\r\n            this._destroyRenderTargetTexture.bind(this)\r\n        );\r\n        this._nativeLayer = layerWrapper.layer;\r\n    }\r\n\r\n    public trySetViewportForView(viewport: Viewport): boolean {\r\n        viewport.x = 0;\r\n        viewport.y = 0;\r\n        viewport.width = 1;\r\n        viewport.height = 1;\r\n        return true;\r\n    }\r\n\r\n    public getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\r\n        // TODO (rgerd): Update the contract on the BabylonNative side to call this \"getRenderTargetTextureForEye\"\r\n        return (this._nativeRTTProvider as any).getRenderTargetForEye(eye);\r\n    }\r\n\r\n    public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n        return (this._nativeRTTProvider as any).getRenderTargetForEye(view.eye);\r\n    }\r\n\r\n    public override getFramebufferDimensions(): Nullable<{ framebufferWidth: number; framebufferHeight: number }> {\r\n        return {\r\n            framebufferWidth: this._nativeLayer.framebufferWidth,\r\n            framebufferHeight: this._nativeLayer.framebufferHeight,\r\n        };\r\n    }\r\n}\r\n\r\n/**\r\n * Creates the xr layer that will be used as the xr session's base layer.\r\n * @internal\r\n */\r\nexport class NativeXRRenderTarget implements WebXRRenderTarget {\r\n    public canvasContext: WebGLRenderingContext;\r\n    public xrLayer: Nullable<XRWebGLLayer>;\r\n\r\n    private _nativeRenderTarget: WebXRRenderTarget;\r\n\r\n    constructor(_xrSessionManager: WebXRSessionManager) {\r\n        this._nativeRenderTarget = (navigator as any).xr.getWebXRRenderTarget(_xrSessionManager.scene.getEngine());\r\n    }\r\n\r\n    public async initializeXRLayerAsync(xrSession: XRSession): Promise<XRWebGLLayer> {\r\n        await this._nativeRenderTarget.initializeXRLayerAsync(xrSession);\r\n        this.xrLayer = this._nativeRenderTarget.xrLayer!;\r\n        return this.xrLayer;\r\n    }\r\n\r\n    dispose(): void {\r\n        /* empty */\r\n    }\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine\";\nimport { type ThinEngine } from \"../Engines/thinEngine\";\nimport { type WebGPUEngine } from \"../Engines/webgpuEngine\";\n\n/**\n * The error shown when the active WebGPU engine cannot start an XR session.\n * @internal\n */\nexport const WebGPUXRNotSupportedErrorMessage =\n    \"WebGPU XR is unavailable in this browser or device. This experimental path requires XRGPUBinding with projection-layer support. To fall back, create a WebGL engine before creating the scene; Babylon.js cannot switch an existing scene's rendering backend.\";\n\n/**\n * The error shown when a WebGPU XR session request is rejected as unsupported.\n * @internal\n */\nexport const WebGPUXRSessionNotSupportedErrorMessage =\n    \"The WebGPU XR session request was rejected as unsupported. The session mode, WebGPU or Layers requirements, or another required feature may be unavailable. If WebGPU XR is unavailable, create a WebGL engine before creating the scene.\";\n\n/**\n * The error shown when the active WebGPU engine was not created with XR compatibility enabled.\n * @internal\n */\nexport const WebGPUXREngineNotCompatibleErrorMessage =\n    \"WebGPU XR requires a WebGPUEngine created with { xrCompatible: true }. Select an XR-capable WebGPU engine or WebGL before creating scene resources.\";\n\n/**\n * Checks whether the runtime exposes the XRGPUBinding projection path required by Babylon.js.\n * This is an advisory shape check; session negotiation can still reject for the active device.\n * @returns whether the required WebGPU-XR binding APIs are exposed\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function IsWebGPUXRSupported(): boolean {\n    return (\n        typeof XRGPUBinding === \"function\" &&\n        typeof XRGPUBinding.prototype.createProjectionLayer === \"function\" &&\n        typeof XRGPUBinding.prototype.getViewSubImage === \"function\" &&\n        typeof XRGPUBinding.prototype.getPreferredColorFormat === \"function\" &&\n        typeof XRGPUSubImage === \"function\" &&\n        typeof XRGPUSubImage.prototype.getViewDescriptor === \"function\"\n    );\n}\n\n/**\n * Checks whether an engine was initialized with the adapter option required for WebGPU XR.\n * @param engine the engine to test\n * @returns true for non-WebGPU engines or WebGPU engines created with xrCompatible enabled\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function IsWebGPUXREngineCompatible(engine: AbstractEngine): boolean {\n    return !engine.isWebGPU || (engine as WebGPUEngine)._options?.xrCompatible === true;\n}\n\n/**\n * The kind of underlying native binding an {@link IWebXRGraphicsBinding} wraps.\n * @internal\n */\nexport const enum WebXRGraphicsBindingType {\n    /**\n     * Backed by an XRWebGLBinding (WebGL / WebGL2).\n     */\n    WebGL,\n\n    /**\n     * Backed by an XRGPUBinding (WebGPU).\n     */\n    WebGPU,\n}\n\n/**\n * Abstraction over the native WebXR graphics binding used to interact with the XR compositor.\n * @internal\n */\nexport interface IWebXRGraphicsBinding {\n    /**\n     * The kind of native binding that is wrapped.\n     */\n    readonly bindingType: WebXRGraphicsBindingType;\n}\n\n/**\n * WebGL implementation of {@link IWebXRGraphicsBinding}, wrapping an `XRWebGLBinding`.\n * @internal\n */\nexport class WebXRWebGLGraphicsBinding implements IWebXRGraphicsBinding {\n    /**\n     * The kind of native binding that is wrapped.\n     */\n    public readonly bindingType = WebXRGraphicsBindingType.WebGL;\n\n    /**\n     * The wrapped native `XRWebGLBinding`.\n     */\n    public readonly binding: XRWebGLBinding;\n\n    /**\n     * Creates a new WebGL graphics binding.\n     * @param session the XR session the binding is created for\n     * @param context the WebGL rendering context to bind to\n     */\n    constructor(\n        session: XRSession,\n        /**\n         * The WebGL rendering context used by the native binding.\n         */\n        public readonly context: WebGLRenderingContext | WebGL2RenderingContext\n    ) {\n        this.binding = new XRWebGLBinding(session, context);\n    }\n\n    /**\n     * Creates a new WebGL graphics binding from an engine, extracting its WebGL context.\n     * The WebGL-specific context access is localized here so callers can stay graphics-API-agnostic.\n     * @param session the XR session the binding is created for\n     * @param engine the engine whose WebGL context should be bound\n     * @returns the created WebGL graphics binding\n     */\n    public static CreateFromEngine(session: XRSession, engine: AbstractEngine): WebXRWebGLGraphicsBinding {\n        const gl = (engine as ThinEngine)._gl;\n        if (!gl) {\n            throw new Error(\"WebXRWebGLGraphicsBinding requires a WebGL-capable engine.\");\n        }\n        return new WebXRWebGLGraphicsBinding(session, gl);\n    }\n}\n\n/**\n * WebGPU implementation of {@link IWebXRGraphicsBinding}, wrapping an `XRGPUBinding`.\n *\n * The `XRGPUBinding` requires a WebGPU-compatible XR session (created with the `webgpu` feature\n * descriptor) and a `GPUDevice` obtained from an `xrCompatible` adapter, otherwise its constructor throws.\n * @internal\n */\nexport class WebXRWebGPUGraphicsBinding implements IWebXRGraphicsBinding {\n    /**\n     * The kind of native binding that is wrapped.\n     */\n    public readonly bindingType = WebXRGraphicsBindingType.WebGPU;\n\n    /**\n     * The wrapped native `XRGPUBinding`.\n     */\n    public readonly binding: XRGPUBinding;\n\n    /**\n     * Creates a new WebGPU graphics binding.\n     * @param session the XR session the binding is created for\n     * @param device the WebGPU device to bind to\n     */\n    constructor(session: XRSession, device: GPUDevice) {\n        this.binding = new XRGPUBinding(session, device);\n    }\n\n    /**\n     * Creates a new WebGPU graphics binding from an engine, extracting its `GPUDevice`.\n     * The WebGPU-specific device access is localized here so callers can stay graphics-API-agnostic.\n     * @param session the XR session the binding is created for\n     * @param engine the engine whose WebGPU device should be bound\n     * @returns the created WebGPU graphics binding\n     */\n    public static CreateFromEngine(session: XRSession, engine: AbstractEngine): WebXRWebGPUGraphicsBinding {\n        const device = (engine as WebGPUEngine)._device;\n        if (!device) {\n            throw new Error(\"WebXRWebGPUGraphicsBinding requires a WebGPU-capable engine.\");\n        }\n        return new WebXRWebGPUGraphicsBinding(session, device);\n    }\n}\n\n/**\n * The graphics bindings supported by the WebXR session manager.\n * @internal\n */\nexport type WebXRGraphicsBinding = WebXRWebGLGraphicsBinding | WebXRWebGPUGraphicsBinding;\n","import { Logger } from \"../Misc/logger\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type IDisposable, type Scene } from \"../scene\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { type WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRManagedOutputCanvas, WebXRManagedOutputCanvasOptions } from \"./webXRManagedOutputCanvas\";\r\nimport { type IWebXRRenderTargetTextureProvider, type WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\r\nimport { type Viewport } from \"../Maths/math.viewport\";\r\nimport { type WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\nimport { NativeXRLayerWrapper, NativeXRRenderTarget } from \"./native/nativeXRRenderTarget\";\r\nimport { WebXRWebGLLayerWrapper } from \"./webXRWebGLLayer\";\r\nimport {\r\n    IsWebGPUXREngineCompatible,\r\n    IsWebGPUXRSupported,\r\n    type WebXRGraphicsBinding,\r\n    WebGPUXREngineNotCompatibleErrorMessage,\r\n    WebGPUXRNotSupportedErrorMessage,\r\n    WebGPUXRSessionNotSupportedErrorMessage,\r\n    WebXRWebGLGraphicsBinding,\r\n    WebXRWebGPUGraphicsBinding,\r\n} from \"./webXRGraphicsBinding\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\n/**\r\n * Manages an XRSession to work with Babylon's engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRSessionManagers\r\n */\r\nexport class WebXRSessionManager implements IDisposable, IWebXRRenderTargetTextureProvider {\r\n    private _engine: Nullable<AbstractEngine>;\r\n    private _referenceSpace: XRReferenceSpace;\r\n    private _baseLayerWrapper: Nullable<WebXRLayerWrapper>;\r\n    private _baseLayerRTTProvider: Nullable<WebXRLayerRenderTargetTextureProvider>;\r\n    private _graphicsBinding: Nullable<WebXRGraphicsBinding> = null;\r\n    private _xrNavigator: any;\r\n    private _sessionMode: XRSessionMode;\r\n    private _onEngineDisposedObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _sessionCleanup: Nullable<() => void> = null;\r\n    private _referenceSpaceInitialized = false;\r\n\r\n    /**\r\n     * The base reference space from which the session started. good if you want to reset your\r\n     * reference space\r\n     */\r\n    public baseReferenceSpace: XRReferenceSpace;\r\n    /**\r\n     * Current XR frame\r\n     */\r\n    public currentFrame: Nullable<XRFrame>;\r\n    /** WebXR timestamp updated every frame */\r\n    public currentTimestamp: number = -1;\r\n    /**\r\n     * Used just in case of a failure to initialize an immersive session.\r\n     * The viewer reference space is compensated using this height, creating a kind of \"viewer-floor\" reference space\r\n     */\r\n    public defaultHeightCompensation = 1.7;\r\n    /**\r\n     * Fires every time a new xrFrame arrives which can be used to update the camera\r\n     */\r\n    public onXRFrameObservable: Observable<XRFrame> = new Observable<XRFrame>();\r\n    /**\r\n     * Fires when the reference space changed\r\n     */\r\n    public onXRReferenceSpaceChanged: Observable<XRReferenceSpace> = new Observable();\r\n    /**\r\n     * Fires when the xr session is ended either by the device or manually done\r\n     */\r\n    public onXRSessionEnded: Observable<any> = new Observable<any>();\r\n    /**\r\n     * Fires when the xr session is initialized: right after requestSession was called and returned with a successful result\r\n     */\r\n    public onXRSessionInit: Observable<XRSession> = new Observable<XRSession>();\r\n\r\n    /**\r\n     * Fires when the xr reference space has been initialized\r\n     */\r\n    public onXRReferenceSpaceInitialized: Observable<XRReferenceSpace> = new Observable<XRReferenceSpace>();\r\n\r\n    /**\r\n     * Fires when the session manager is rendering the first frame\r\n     */\r\n    public onXRReady: Observable<WebXRSessionManager> = new Observable<WebXRSessionManager>();\r\n    /**\r\n     * Underlying xr session\r\n     */\r\n    public session: XRSession;\r\n    /**\r\n     * The viewer (head position) reference space. This can be used to get the XR world coordinates\r\n     * or get the offset the player is currently at.\r\n     */\r\n    public viewerReferenceSpace: XRReferenceSpace;\r\n    /**\r\n     * Are we currently in the XR loop?\r\n     */\r\n    public inXRFrameLoop: boolean = false;\r\n    /**\r\n     * Are we in an XR session?\r\n     */\r\n    public inXRSession: boolean = false;\r\n\r\n    private _worldScalingFactor: number = 1;\r\n\r\n    /**\r\n     * Observable raised when the world scale has changed\r\n     */\r\n    public onWorldScaleFactorChangedObservable: Observable<{\r\n        previousScaleFactor: number;\r\n        newScaleFactor: number;\r\n    }> = new Observable(undefined, true);\r\n\r\n    /**\r\n     * Scale factor to apply to all XR-related elements (camera, controllers)\r\n     */\r\n    public get worldScalingFactor(): number {\r\n        return this._worldScalingFactor;\r\n    }\r\n\r\n    public set worldScalingFactor(value: number) {\r\n        const oldValue = this._worldScalingFactor;\r\n        this._worldScalingFactor = value;\r\n        this.onWorldScaleFactorChangedObservable.notifyObservers({\r\n            previousScaleFactor: oldValue,\r\n            newScaleFactor: value,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Constructs a WebXRSessionManager, this must be initialized within a user action before usage\r\n     * @param scene The scene which the session should be created for\r\n     */\r\n    constructor(\r\n        /** The scene which the session should be created for */\r\n        public scene: Scene\r\n    ) {\r\n        this._engine = scene.getEngine();\r\n        this._onEngineDisposedObserver = this._engine.onDisposeObservable.addOnce(() => {\r\n            this._engine = null;\r\n        });\r\n        scene.onDisposeObservable.addOnce(() => {\r\n            this.dispose();\r\n        });\r\n\r\n        this.onXRSessionEnded.add(() => {\r\n            // Set the scene's pointer camera to null to stop the XR camera being used for picking.\r\n            scene.cameraToUseForPointers = null;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The current reference space used in this session. This reference space can constantly change!\r\n     * It is mainly used to offset the camera's position.\r\n     */\r\n    public get referenceSpace(): XRReferenceSpace {\r\n        return this._referenceSpace;\r\n    }\r\n\r\n    /**\r\n     * Set a new reference space and triggers the observable\r\n     */\r\n    public set referenceSpace(newReferenceSpace: XRReferenceSpace) {\r\n        this._referenceSpace = newReferenceSpace;\r\n        this._referenceSpaceInitialized = true;\r\n        this.onXRReferenceSpaceChanged.notifyObservers(this._referenceSpace);\r\n    }\r\n\r\n    /**\r\n     * The mode for the managed XR session\r\n     */\r\n    public get sessionMode(): XRSessionMode {\r\n        return this._sessionMode;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the session manager\r\n     * This should be called explicitly by the dev, if required.\r\n     */\r\n    public dispose() {\r\n        // disposing without leaving XR? Exit XR first\r\n        if (this.inXRSession) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            this.exitXRAsync();\r\n        }\r\n        this.onXRReady.clear();\r\n        this.onXRFrameObservable.clear();\r\n        this.onXRSessionEnded.clear();\r\n        this.onXRReferenceSpaceChanged.clear();\r\n        this.onXRReferenceSpaceInitialized.clear();\r\n        this.onXRSessionInit.clear();\r\n        this.onWorldScaleFactorChangedObservable.clear();\r\n        this._engine?.onDisposeObservable.remove(this._onEngineDisposedObserver);\r\n        this._engine = null;\r\n    }\r\n\r\n    /**\r\n     * Stops the xrSession and restores the render loop\r\n     * @returns Promise which resolves after it exits XR\r\n     */\r\n    public async exitXRAsync() {\r\n        if (this.session && this.inXRSession) {\r\n            try {\r\n                await this.session.end();\r\n            } catch {\r\n                Logger.Warn(\"Could not end XR session.\");\r\n            }\r\n            try {\r\n                this._sessionCleanup?.();\r\n            } catch {\r\n                Logger.Warn(\"Could not fully clean up XR state after the session ended.\");\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attempts to set the framebuffer-size-normalized viewport to be rendered this frame for this view.\r\n     * In the event of a failure, the supplied viewport is not updated.\r\n     * @param viewport the viewport to which the view will be rendered\r\n     * @param view the view for which to set the viewport\r\n     * @returns whether the operation was successful\r\n     */\r\n    public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n        return this._baseLayerRTTProvider?.trySetViewportForView(viewport, view) || false;\r\n    }\r\n\r\n    /**\r\n     * Gets the correct render target texture to be rendered this frame for this eye\r\n     * @param eye the eye for which to get the render target\r\n     * @returns the render target for the specified eye or null if not available\r\n     */\r\n    public getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\r\n        return this._baseLayerRTTProvider?.getRenderTargetTextureForEye(eye) || null;\r\n    }\r\n\r\n    /**\r\n     * Gets the correct render target texture to be rendered this frame for this view\r\n     * @param view the view for which to get the render target\r\n     * @returns the render target for the specified view or null if not available\r\n     */\r\n    public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n        return this._baseLayerRTTProvider?.getRenderTargetTextureForView(view) || null;\r\n    }\r\n\r\n    /**\r\n     * Checks whether the current XR view exposes the dynamic viewport scaling API.\r\n     * API availability does not guarantee that the active XR device will change the viewport dimensions.\r\n     * This method must be called during an active XR frame.\r\n     * @param viewIndex the index of the view in the current viewer pose\r\n     * @returns whether dynamic viewport scaling is exposed for the view\r\n     * @see https://playground.babylonjs.com/#BAGIIM#0\r\n     */\r\n    public isViewportScaleSupported(viewIndex: number): boolean {\r\n        const view = this._getCurrentXRView(viewIndex);\r\n        return \"recommendedViewportScale\" in view && typeof view.requestViewportScale === \"function\";\r\n    }\r\n\r\n    /**\r\n     * Gets the runtime-recommended viewport scale for the current XR view.\r\n     * A number is returned when the runtime has a recommendation, `null` when the API is supported but\r\n     * the runtime has no recommendation, and `undefined` when the API is not supported.\r\n     * This method must be called during an active XR frame.\r\n     * @param viewIndex the index of the view in the current viewer pose\r\n     * @returns the recommended viewport scale, `null` when no recommendation is available, or `undefined` when unsupported\r\n     * @see https://playground.babylonjs.com/#BAGIIM#0\r\n     */\r\n    public getRecommendedViewportScale(viewIndex: number): Nullable<number> | undefined {\r\n        const view = this._getCurrentXRView(viewIndex);\r\n        if (!(\"recommendedViewportScale\" in view) || typeof view.requestViewportScale !== \"function\") {\r\n            return undefined;\r\n        }\r\n        return view.recommendedViewportScale ?? null;\r\n    }\r\n\r\n    /**\r\n     * Requests a viewport scale for the current XR view.\r\n     * The request is a hint to the runtime. Babylon uses the native viewport returned on subsequent frames\r\n     * and does not derive viewport dimensions from this value. Pass `1` to restore the full viewport scale;\r\n     * `null` follows the native no-op behavior. Native ignored-value, clamping, and exception behavior is preserved.\r\n     * Requests made from an application observer of `onXRFrameObservable` apply to a future frame because\r\n     * Babylon's camera acquires the current frame's viewport before notifying application observers.\r\n     * This method must be called during an active XR frame.\r\n     * @param viewIndex the index of the view in the current viewer pose\r\n     * @param scale the viewport scale requested from the runtime\r\n     * @see https://playground.babylonjs.com/#BAGIIM#0\r\n     */\r\n    public requestViewportScale(viewIndex: number, scale: Nullable<number>): void {\r\n        const view = this._getCurrentXRView(viewIndex);\r\n        if (!(\"recommendedViewportScale\" in view) || typeof view.requestViewportScale !== \"function\") {\r\n            throw new Error(`Dynamic viewport scaling is not supported for XR view ${viewIndex}.`);\r\n        }\r\n        view.requestViewportScale(scale);\r\n    }\r\n\r\n    private _getCurrentXRView(viewIndex: number): XRView {\r\n        if (!this.inXRSession || !this.session) {\r\n            throw new Error(\"Dynamic viewport scaling requires an active XR session.\");\r\n        }\r\n        if (!this.inXRFrameLoop || !this.currentFrame) {\r\n            throw new Error(\"Dynamic viewport scaling must be used during an active XR frame.\");\r\n        }\r\n        if (!this._referenceSpaceInitialized) {\r\n            throw new Error(\"Dynamic viewport scaling requires an initialized XR reference space.\");\r\n        }\r\n        if (!Number.isInteger(viewIndex) || viewIndex < 0) {\r\n            throw new RangeError(\"The XR view index must be a non-negative integer.\");\r\n        }\r\n\r\n        const pose = this.currentFrame.getViewerPose(this.referenceSpace);\r\n        if (!pose || viewIndex >= pose.views.length) {\r\n            throw new RangeError(`XR view ${viewIndex} is not available in the current viewer pose.`);\r\n        }\r\n        return pose.views[viewIndex];\r\n    }\r\n\r\n    /**\r\n     * Obtains the XR graphics binding for the current session, creating it lazily.\r\n     * This is the API-agnostic seam used by WebGL and WebGPU XR features to share a binding.\r\n     * @returns the XR graphics binding for the current session\r\n     * @internal\r\n     */\r\n    public _getGraphicsBinding(): WebXRGraphicsBinding {\r\n        if (!this._engine) {\r\n            throw new Error(\"Cannot create the XR graphics binding: the engine has been disposed.\");\r\n        }\r\n        if (!this.session) {\r\n            throw new Error(\"Cannot create the XR graphics binding before the XR session is initialized.\");\r\n        }\r\n        if (!this._graphicsBinding) {\r\n            this._graphicsBinding = this._engine.isWebGPU\r\n                ? WebXRWebGPUGraphicsBinding.CreateFromEngine(this.session, this._engine)\r\n                : WebXRWebGLGraphicsBinding.CreateFromEngine(this.session, this._engine);\r\n        }\r\n        return this._graphicsBinding;\r\n    }\r\n\r\n    /**\r\n     * Creates a WebXRRenderTarget object for the XR session\r\n     * @param options optional options to provide when creating a new render target\r\n     * @returns a WebXR render target to which the session can render\r\n     */\r\n    public getWebXRRenderTarget(options?: WebXRManagedOutputCanvasOptions): WebXRRenderTarget {\r\n        const engine = this.scene.getEngine();\r\n        if (this._xrNavigator.xr.native) {\r\n            return new NativeXRRenderTarget(this);\r\n        } else {\r\n            options = options || WebXRManagedOutputCanvasOptions.GetDefaults(engine);\r\n            options.canvasElement = options.canvasElement || engine.getRenderingCanvas() || undefined;\r\n            return new WebXRManagedOutputCanvas(this, options);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Initializes the manager\r\n     * After initialization enterXR can be called to start an XR session\r\n     * @returns Promise which resolves after it is initialized\r\n     */\r\n    public async initializeAsync(): Promise<void> {\r\n        // Check if the browser supports webXR\r\n        this._xrNavigator = navigator;\r\n        if (!this._xrNavigator.xr) {\r\n            throw new Error(\"WebXR not supported on this browser.\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Initializes an xr session\r\n     * @param xrSessionMode mode to initialize\r\n     * @param xrSessionInit defines optional and required values to pass to the session builder\r\n     * @returns a promise which will resolve once the session has been initialized\r\n     */\r\n    public async initializeSessionAsync(xrSessionMode: XRSessionMode = \"immersive-vr\", xrSessionInit: XRSessionInit = {}): Promise<XRSession> {\r\n        const isWebGPU = !!this._engine?.isWebGPU;\r\n        if (isWebGPU && !IsWebGPUXREngineCompatible(this._engine!)) {\r\n            throw new Error(WebGPUXREngineNotCompatibleErrorMessage);\r\n        }\r\n        if (isWebGPU && !WebXRSessionManager.IsWebGPUXRSupported) {\r\n            throw new Error(WebGPUXRNotSupportedErrorMessage);\r\n        }\r\n\r\n        // A WebGPU engine requires a WebGPU-compatible XR session (per the WebXR/WebGPU binding spec).\r\n        // The \"webgpu\" feature descriptor is requested as a *required* feature: a WebGPU engine cannot\r\n        // fall back to a WebGL-compatible session. WebGL engines leave xrSessionInit untouched.\r\n        if (isWebGPU) {\r\n            const requiredFeatures = xrSessionInit.requiredFeatures ? [...xrSessionInit.requiredFeatures] : [];\r\n            if (!requiredFeatures.includes(\"webgpu\")) {\r\n                requiredFeatures.push(\"webgpu\");\r\n            }\r\n            xrSessionInit = { ...xrSessionInit, requiredFeatures };\r\n        }\r\n\r\n        let session: XRSession;\r\n        try {\r\n            session = await this._xrNavigator.xr.requestSession(xrSessionMode, xrSessionInit);\r\n        } catch (error) {\r\n            const isNotSupportedError = typeof error === \"object\" && error !== null && \"name\" in error && error.name === \"NotSupportedError\";\r\n            if (isWebGPU && isNotSupportedError) {\r\n                throw new Error(WebGPUXRSessionNotSupportedErrorMessage, { cause: error });\r\n            }\r\n            throw error;\r\n        }\r\n\r\n        this.session = session;\r\n        this._referenceSpaceInitialized = false;\r\n        this._sessionMode = xrSessionMode;\r\n        this.inXRSession = true;\r\n\r\n        // handle when the session is ended (By calling session.end or device ends its own session eg. pressing home button on phone)\r\n        let sessionCleanupComplete = false;\r\n        const cleanupSession = () => {\r\n            if (sessionCleanupComplete) {\r\n                return;\r\n            }\r\n            sessionCleanupComplete = true;\r\n            this._sessionCleanup = null;\r\n            this.inXRSession = false;\r\n            this._referenceSpaceInitialized = false;\r\n\r\n            // Cache the value of engine in case it is disposed during onXRSessionEnded callbacks\r\n            const engine = this._engine;\r\n\r\n            try {\r\n                // Notify frame observers\r\n                this.onXRSessionEnded.notifyObservers(null);\r\n            } finally {\r\n                try {\r\n                    if (engine && !engine.isDisposed) {\r\n                        // make sure dimensions object is restored\r\n                        engine.framebufferDimensionsObject = null;\r\n\r\n                        // Restore frame buffer to avoid clear on xr framebuffer after session end\r\n                        engine.restoreDefaultFramebuffer();\r\n\r\n                        // Need to restart render loop as after the session is ended the last request for new frame will never call callback\r\n                        engine.customAnimationFrameRequester = null;\r\n                        engine._renderLoop();\r\n                    }\r\n                } finally {\r\n                    try {\r\n                        // Dispose render target textures.\r\n                        // Only dispose on native because we can't destroy opaque textures on browser.\r\n                        if (this.isNative) {\r\n                            this._baseLayerRTTProvider?.dispose();\r\n                        }\r\n                    } finally {\r\n                        this._baseLayerRTTProvider = null;\r\n                        this._baseLayerWrapper = null;\r\n                        this._graphicsBinding = null;\r\n                    }\r\n                }\r\n            }\r\n        };\r\n        this._sessionCleanup = cleanupSession;\r\n        this.session.addEventListener(\"end\", cleanupSession, { once: true });\r\n\r\n        try {\r\n            this.onXRSessionInit.notifyObservers(session);\r\n        } catch (error) {\r\n            let sessionEnded = false;\r\n            try {\r\n                await this.session.end();\r\n                sessionEnded = true;\r\n            } catch {\r\n                Logger.Warn(\"Could not end XR session after initialization failed.\");\r\n            }\r\n            if (sessionEnded) {\r\n                try {\r\n                    cleanupSession();\r\n                } catch {\r\n                    Logger.Warn(\"Could not fully clean up XR state after initialization failed.\");\r\n                }\r\n            }\r\n            throw error;\r\n        }\r\n\r\n        return this.session;\r\n    }\r\n\r\n    /**\r\n     * Checks if a session would be supported for the creation options specified\r\n     * @param sessionMode session mode to check if supported eg. immersive-vr\r\n     * @returns A Promise that resolves to true if supported and false if not\r\n     */\r\n    public async isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {\r\n        return await WebXRSessionManager.IsSessionSupportedAsync(sessionMode);\r\n    }\r\n\r\n    /**\r\n     * Resets the reference space to the one started the session\r\n     */\r\n    public resetReferenceSpace() {\r\n        this.referenceSpace = this.baseReferenceSpace;\r\n    }\r\n\r\n    /**\r\n     * Starts rendering to the xr layer\r\n     */\r\n    public runXRRenderLoop() {\r\n        if (!this.inXRSession || !this._engine) {\r\n            return;\r\n        }\r\n\r\n        // Tell the engine's render loop to be driven by the xr session's refresh rate and provide xr pose information\r\n        this._engine.customAnimationFrameRequester = {\r\n            requestAnimationFrame: (callback: FrameRequestCallback) => this.session.requestAnimationFrame(callback),\r\n            renderFunction: (timestamp: number, xrFrame: Nullable<XRFrame>) => {\r\n                if (!this.inXRSession || !this._engine) {\r\n                    return;\r\n                }\r\n                // Store the XR frame and timestamp in the session manager\r\n                this.currentFrame = xrFrame;\r\n                this.currentTimestamp = timestamp;\r\n                if (xrFrame) {\r\n                    this.inXRFrameLoop = true;\r\n                    const framebufferDimensionsObject = this._baseLayerRTTProvider?.getFramebufferDimensions() || null;\r\n                    // equality can be tested as it should be the same object\r\n                    if (this._engine.framebufferDimensionsObject !== framebufferDimensionsObject) {\r\n                        this._engine.framebufferDimensionsObject = framebufferDimensionsObject;\r\n                    }\r\n                    this.onXRFrameObservable.notifyObservers(xrFrame);\r\n                    this._engine._renderLoop();\r\n                    this._engine.framebufferDimensionsObject = null;\r\n                    this.inXRFrameLoop = false;\r\n                }\r\n            },\r\n        };\r\n\r\n        this._engine.framebufferDimensionsObject = this._baseLayerRTTProvider?.getFramebufferDimensions() || null;\r\n        this.onXRFrameObservable.addOnce(() => {\r\n            this.onXRReady.notifyObservers(this);\r\n        });\r\n\r\n        // Stop window's animation frame and trigger sessions animation frame\r\n        if (typeof window !== \"undefined\" && window.cancelAnimationFrame) {\r\n            window.cancelAnimationFrame(this._engine._frameHandler);\r\n        }\r\n        this._engine._renderLoop();\r\n    }\r\n\r\n    /**\r\n     * Sets the reference space on the xr session\r\n     * @param referenceSpaceType space to set\r\n     * @returns a promise that will resolve once the reference space has been set\r\n     */\r\n    public async setReferenceSpaceTypeAsync(referenceSpaceType: XRReferenceSpaceType = \"local-floor\"): Promise<XRReferenceSpace> {\r\n        let referenceSpace: XRReferenceSpace;\r\n        let viewerReferenceSpace: Nullable<XRReferenceSpace> = null;\r\n        try {\r\n            referenceSpace = await this.session.requestReferenceSpace(referenceSpaceType);\r\n        } catch (rejectionReason) {\r\n            Logger.Error(\"XR.requestReferenceSpace failed for the following reason: \");\r\n            Logger.Error(rejectionReason);\r\n            Logger.Log('Defaulting to universally-supported \"viewer\" reference space type.');\r\n\r\n            try {\r\n                viewerReferenceSpace = (await this.session.requestReferenceSpace(\"viewer\")) as XRReferenceSpace;\r\n                const heightCompensation = new XRRigidTransform({ x: 0, y: -this.defaultHeightCompensation, z: 0 });\r\n                referenceSpace = viewerReferenceSpace.getOffsetReferenceSpace(heightCompensation);\r\n            } catch (rejectionReason) {\r\n                Logger.Error(rejectionReason);\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw 'XR initialization failed: required \"viewer\" reference space type not supported.';\r\n            }\r\n        }\r\n        // create viewer reference space before setting the first reference space\r\n        this.viewerReferenceSpace = viewerReferenceSpace ?? ((await this.session.requestReferenceSpace(\"viewer\")) as XRReferenceSpace);\r\n        // initialize the base and offset (currently the same)\r\n        this.referenceSpace = this.baseReferenceSpace = referenceSpace;\r\n        this.onXRReferenceSpaceInitialized.notifyObservers(referenceSpace);\r\n        return this.referenceSpace;\r\n    }\r\n\r\n    /**\r\n     * Updates the render state of the session.\r\n     * Note that this is deprecated in favor of WebXRSessionManager.updateRenderState().\r\n     * @param state state to set\r\n     * @returns a promise that resolves once the render state has been updated\r\n     * @deprecated Use updateRenderState() instead.\r\n     */\r\n    public async updateRenderStateAsync(state: XRRenderState): Promise<void> {\r\n        return await this.session.updateRenderState(state);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setBaseLayerWrapper(baseLayerWrapper: Nullable<WebXRLayerWrapper>): void {\r\n        if (this.isNative) {\r\n            this._baseLayerRTTProvider?.dispose();\r\n        }\r\n        this._baseLayerWrapper = baseLayerWrapper;\r\n        this._baseLayerRTTProvider = this._baseLayerWrapper?.createRenderTargetTextureProvider(this) || null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getBaseLayerWrapper(): Nullable<WebXRLayerWrapper> {\r\n        return this._baseLayerWrapper;\r\n    }\r\n\r\n    /**\r\n     * Updates the render state of the session\r\n     * @param state state to set\r\n     */\r\n    public updateRenderState(state: XRRenderStateInit): void {\r\n        if (state.baseLayer) {\r\n            this._setBaseLayerWrapper(this.isNative ? new NativeXRLayerWrapper(state.baseLayer) : new WebXRWebGLLayerWrapper(state.baseLayer));\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this.session.updateRenderState(state);\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves with a boolean indicating if the provided session mode is supported by this browser\r\n     * @param sessionMode defines the session to test\r\n     * @returns a promise with boolean as final value\r\n     */\r\n    public static async IsSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {\r\n        if (!(navigator as any).xr) {\r\n            return false;\r\n        }\r\n        // When the specs are final, remove supportsSession!\r\n        const functionToUse = (navigator as any).xr.isSessionSupported || (navigator as any).xr.supportsSession;\r\n        if (!functionToUse) {\r\n            return false;\r\n        } else {\r\n            try {\r\n                const result = functionToUse.call((navigator as any).xr, sessionMode);\r\n                const returnValue = typeof result === \"undefined\" ? true : result;\r\n                return returnValue;\r\n            } catch (e: any) {\r\n                Logger.Warn(e);\r\n                return false;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns whether the runtime exposes the WebGPU-XR binding APIs required by Babylon.js.\r\n     *\r\n     * This is an advisory check only. XR session negotiation can still fail for the active device,\r\n     * permissions, or adapter. A WebGPU engine intended for XR must also be created with\r\n     * `xrCompatible: true`.\r\n     * @returns whether the required XRGPUBinding projection APIs are exposed\r\n     * @experimental WebGPU-XR support is experimental and may change.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static get IsWebGPUXRSupported(): boolean {\r\n        return IsWebGPUXRSupported();\r\n    }\r\n\r\n    /**\r\n     * Returns true if Babylon.js is using the BabylonNative backend, otherwise false\r\n     */\r\n    public get isNative(): boolean {\r\n        return this._xrNavigator.xr.native ?? false;\r\n    }\r\n\r\n    /**\r\n     * The current frame rate as reported by the device\r\n     */\r\n    public get currentFrameRate(): number | undefined {\r\n        return this.session?.frameRate;\r\n    }\r\n\r\n    /**\r\n     * A list of supported frame rates (only available in-session!\r\n     */\r\n    public get supportedFrameRates(): Float32Array | undefined {\r\n        return this.session?.supportedFrameRates;\r\n    }\r\n\r\n    /**\r\n     * Set the framerate of the session.\r\n     * @param rate the new framerate. This value needs to be in the supportedFrameRates array\r\n     * @returns a promise that resolves once the framerate has been set\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async updateTargetFrameRate(rate: number): Promise<void> {\r\n        return await this.session.updateTargetFrameRate(rate);\r\n    }\r\n\r\n    /**\r\n     * Run a callback in the xr render loop\r\n     * @param callback the callback to call when in XR Frame\r\n     * @param ignoreIfNotInSession if no session is currently running, run it first thing on the next session\r\n     */\r\n    public runInXRFrame(callback: () => void, ignoreIfNotInSession = true): void {\r\n        if (this.inXRFrameLoop) {\r\n            callback();\r\n        } else if (this.inXRSession || !ignoreIfNotInSession) {\r\n            this.onXRFrameObservable.addOnce(callback);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Check if fixed foveation is supported on this device\r\n     */\r\n    public get isFixedFoveationSupported(): boolean {\r\n        return this._baseLayerWrapper?.isFixedFoveationSupported || false;\r\n    }\r\n\r\n    /**\r\n     * Get the fixed foveation currently set, as specified by the webxr specs\r\n     * If this returns null, then fixed foveation is not supported\r\n     */\r\n    public get fixedFoveation(): Nullable<number> {\r\n        return this._baseLayerWrapper?.fixedFoveation ?? null;\r\n    }\r\n\r\n    /**\r\n     * Set the fixed foveation to the specified value, as specified by the webxr specs\r\n     * This value will be normalized to be between 0 and 1, 1 being max foveation, 0 being no foveation\r\n     */\r\n    public set fixedFoveation(value: Nullable<number>) {\r\n        const val = Math.max(0, Math.min(1, value || 0));\r\n        if (this._baseLayerWrapper) {\r\n            this._baseLayerWrapper.fixedFoveation = val;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the features enabled on the current session\r\n     * This is only available in-session!\r\n     * @see https://www.w3.org/TR/webxr/#dom-xrsession-enabledfeatures\r\n     */\r\n    public get enabledFeatures(): Nullable<string[]> {\r\n        return this.session?.enabledFeatures ?? null;\r\n    }\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\nimport { Gamepad } from \"../Gamepads/gamepad\";\r\n/**\r\n * Defines supported buttons for XBox360 compatible gamepads\r\n */\r\nexport const enum Xbox360Button {\r\n    /** A */\r\n    A = 0,\r\n    /** B */\r\n    B = 1,\r\n    /** X */\r\n    X = 2,\r\n    /** Y */\r\n    Y = 3,\r\n    /** Left button */\r\n    LB = 4,\r\n    /** Right button */\r\n    RB = 5,\r\n    /** Back */\r\n    Back = 8,\r\n    /** Start */\r\n    Start = 9,\r\n    /** Left stick */\r\n    LeftStick = 10,\r\n    /** Right stick */\r\n    RightStick = 11,\r\n}\r\n\r\n/** Defines values for XBox360 DPad  */\r\nexport const enum Xbox360Dpad {\r\n    /** Up */\r\n    Up = 12,\r\n    /** Down */\r\n    Down = 13,\r\n    /** Left */\r\n    Left = 14,\r\n    /** Right */\r\n    Right = 15,\r\n}\r\n\r\n/**\r\n * Defines a XBox360 gamepad\r\n */\r\nexport class Xbox360Pad extends Gamepad {\r\n    private _leftTrigger: number = 0;\r\n    private _rightTrigger: number = 0;\r\n\r\n    private _onlefttriggerchanged: (value: number) => void;\r\n    private _onrighttriggerchanged: (value: number) => void;\r\n\r\n    private _onbuttondown: (buttonPressed: Xbox360Button) => void;\r\n    private _onbuttonup: (buttonReleased: Xbox360Button) => void;\r\n    private _ondpaddown: (dPadPressed: Xbox360Dpad) => void;\r\n    private _ondpadup: (dPadReleased: Xbox360Dpad) => void;\r\n\r\n    /** Observable raised when a button is pressed */\r\n    public onButtonDownObservable = new Observable<Xbox360Button>();\r\n    /** Observable raised when a button is released */\r\n    public onButtonUpObservable = new Observable<Xbox360Button>();\r\n    /** Observable raised when a pad is pressed */\r\n    public onPadDownObservable = new Observable<Xbox360Dpad>();\r\n    /** Observable raised when a pad is released */\r\n    public onPadUpObservable = new Observable<Xbox360Dpad>();\r\n\r\n    private _buttonA: number = 0;\r\n    private _buttonB: number = 0;\r\n    private _buttonX: number = 0;\r\n    private _buttonY: number = 0;\r\n    private _buttonBack: number = 0;\r\n    private _buttonStart: number = 0;\r\n    private _buttonLb: number = 0;\r\n    private _buttonRb: number = 0;\r\n\r\n    private _buttonLeftStick: number = 0;\r\n    private _buttonRightStick: number = 0;\r\n    private _dPadUp: number = 0;\r\n    private _dPadDown: number = 0;\r\n    private _dPadLeft: number = 0;\r\n    private _dPadRight: number = 0;\r\n\r\n    private _isXboxOnePad: boolean = false;\r\n\r\n    /**\r\n     * Creates a new XBox360 gamepad object\r\n     * @param id defines the id of this gamepad\r\n     * @param index defines its index\r\n     * @param gamepad defines the internal HTML gamepad object\r\n     * @param xboxOne defines if it is a XBox One gamepad\r\n     */\r\n    constructor(id: string, index: number, gamepad: any, xboxOne: boolean = false) {\r\n        super(id, index, gamepad, 0, 1, 2, 3);\r\n        this.type = Gamepad.XBOX;\r\n        this._isXboxOnePad = xboxOne;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when left trigger is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onlefttriggerchanged(callback: (value: number) => void) {\r\n        this._onlefttriggerchanged = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when right trigger is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onrighttriggerchanged(callback: (value: number) => void) {\r\n        this._onrighttriggerchanged = callback;\r\n    }\r\n\r\n    /**\r\n     * Gets the left trigger value\r\n     */\r\n    public get leftTrigger(): number {\r\n        return this._leftTrigger;\r\n    }\r\n    /**\r\n     * Sets the left trigger value\r\n     */\r\n    public set leftTrigger(newValue: number) {\r\n        if (this._onlefttriggerchanged && this._leftTrigger !== newValue) {\r\n            this._onlefttriggerchanged(newValue);\r\n        }\r\n        this._leftTrigger = newValue;\r\n    }\r\n\r\n    /**\r\n     * Gets the right trigger value\r\n     */\r\n    public get rightTrigger(): number {\r\n        return this._rightTrigger;\r\n    }\r\n    /**\r\n     * Sets the right trigger value\r\n     */\r\n    public set rightTrigger(newValue: number) {\r\n        if (this._onrighttriggerchanged && this._rightTrigger !== newValue) {\r\n            this._onrighttriggerchanged(newValue);\r\n        }\r\n        this._rightTrigger = newValue;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a button is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onbuttondown(callback: (buttonPressed: Xbox360Button) => void) {\r\n        this._onbuttondown = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a button is released\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onbuttonup(callback: (buttonReleased: Xbox360Button) => void) {\r\n        this._onbuttonup = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a pad is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public ondpaddown(callback: (dPadPressed: Xbox360Dpad) => void) {\r\n        this._ondpaddown = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a pad is released\r\n     * @param callback defines the callback to use\r\n     */\r\n    public ondpadup(callback: (dPadReleased: Xbox360Dpad) => void) {\r\n        this._ondpadup = callback;\r\n    }\r\n\r\n    private _setButtonValue(newValue: number, currentValue: number, buttonType: Xbox360Button): number {\r\n        if (newValue !== currentValue) {\r\n            if (newValue === 1) {\r\n                if (this._onbuttondown) {\r\n                    this._onbuttondown(buttonType);\r\n                }\r\n\r\n                this.onButtonDownObservable.notifyObservers(buttonType);\r\n            }\r\n            if (newValue === 0) {\r\n                if (this._onbuttonup) {\r\n                    this._onbuttonup(buttonType);\r\n                }\r\n\r\n                this.onButtonUpObservable.notifyObservers(buttonType);\r\n            }\r\n        }\r\n        return newValue;\r\n    }\r\n\r\n    private _setDpadValue(newValue: number, currentValue: number, buttonType: Xbox360Dpad): number {\r\n        if (newValue !== currentValue) {\r\n            if (newValue === 1) {\r\n                if (this._ondpaddown) {\r\n                    this._ondpaddown(buttonType);\r\n                }\r\n\r\n                this.onPadDownObservable.notifyObservers(buttonType);\r\n            }\r\n            if (newValue === 0) {\r\n                if (this._ondpadup) {\r\n                    this._ondpadup(buttonType);\r\n                }\r\n\r\n                this.onPadUpObservable.notifyObservers(buttonType);\r\n            }\r\n        }\r\n        return newValue;\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `A` button\r\n     */\r\n    public get buttonA(): number {\r\n        return this._buttonA;\r\n    }\r\n    /**\r\n     * Sets the value of the `A` button\r\n     */\r\n    public set buttonA(value) {\r\n        this._buttonA = this._setButtonValue(value, this._buttonA, Xbox360Button.A);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `B` button\r\n     */\r\n    public get buttonB(): number {\r\n        return this._buttonB;\r\n    }\r\n    /**\r\n     * Sets the value of the `B` button\r\n     */\r\n    public set buttonB(value) {\r\n        this._buttonB = this._setButtonValue(value, this._buttonB, Xbox360Button.B);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `X` button\r\n     */\r\n    public get buttonX(): number {\r\n        return this._buttonX;\r\n    }\r\n    /**\r\n     * Sets the value of the `X` button\r\n     */\r\n    public set buttonX(value) {\r\n        this._buttonX = this._setButtonValue(value, this._buttonX, Xbox360Button.X);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Y` button\r\n     */\r\n    public get buttonY(): number {\r\n        return this._buttonY;\r\n    }\r\n    /**\r\n     * Sets the value of the `Y` button\r\n     */\r\n    public set buttonY(value) {\r\n        this._buttonY = this._setButtonValue(value, this._buttonY, Xbox360Button.Y);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Start` button\r\n     */\r\n    public get buttonStart(): number {\r\n        return this._buttonStart;\r\n    }\r\n    /**\r\n     * Sets the value of the `Start` button\r\n     */\r\n    public set buttonStart(value) {\r\n        this._buttonStart = this._setButtonValue(value, this._buttonStart, Xbox360Button.Start);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Back` button\r\n     */\r\n    public get buttonBack(): number {\r\n        return this._buttonBack;\r\n    }\r\n    /**\r\n     * Sets the value of the `Back` button\r\n     */\r\n    public set buttonBack(value) {\r\n        this._buttonBack = this._setButtonValue(value, this._buttonBack, Xbox360Button.Back);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Left` button\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get buttonLB(): number {\r\n        return this._buttonLb;\r\n    }\r\n    /**\r\n     * Sets the value of the `Left` button\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set buttonLB(value) {\r\n        this._buttonLb = this._setButtonValue(value, this._buttonLb, Xbox360Button.LB);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Right` button\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get buttonRB(): number {\r\n        return this._buttonRb;\r\n    }\r\n    /**\r\n     * Sets the value of the `Right` button\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set buttonRB(value) {\r\n        this._buttonRb = this._setButtonValue(value, this._buttonRb, Xbox360Button.RB);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the Left joystick\r\n     */\r\n    public get buttonLeftStick(): number {\r\n        return this._buttonLeftStick;\r\n    }\r\n    /**\r\n     * Sets the value of the Left joystick\r\n     */\r\n    public set buttonLeftStick(value) {\r\n        this._buttonLeftStick = this._setButtonValue(value, this._buttonLeftStick, Xbox360Button.LeftStick);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the Right joystick\r\n     */\r\n    public get buttonRightStick(): number {\r\n        return this._buttonRightStick;\r\n    }\r\n    /**\r\n     * Sets the value of the Right joystick\r\n     */\r\n    public set buttonRightStick(value) {\r\n        this._buttonRightStick = this._setButtonValue(value, this._buttonRightStick, Xbox360Button.RightStick);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad up\r\n     */\r\n    public get dPadUp(): number {\r\n        return this._dPadUp;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad up\r\n     */\r\n    public set dPadUp(value) {\r\n        this._dPadUp = this._setDpadValue(value, this._dPadUp, Xbox360Dpad.Up);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad down\r\n     */\r\n    public get dPadDown(): number {\r\n        return this._dPadDown;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad down\r\n     */\r\n    public set dPadDown(value) {\r\n        this._dPadDown = this._setDpadValue(value, this._dPadDown, Xbox360Dpad.Down);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad left\r\n     */\r\n    public get dPadLeft(): number {\r\n        return this._dPadLeft;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad left\r\n     */\r\n    public set dPadLeft(value) {\r\n        this._dPadLeft = this._setDpadValue(value, this._dPadLeft, Xbox360Dpad.Left);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad right\r\n     */\r\n    public get dPadRight(): number {\r\n        return this._dPadRight;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad right\r\n     */\r\n    public set dPadRight(value) {\r\n        this._dPadRight = this._setDpadValue(value, this._dPadRight, Xbox360Dpad.Right);\r\n    }\r\n\r\n    /**\r\n     * Force the gamepad to synchronize with device values\r\n     */\r\n    public override update() {\r\n        super.update();\r\n        if (this._isXboxOnePad) {\r\n            this.buttonA = this.browserGamepad.buttons[0].value;\r\n            this.buttonB = this.browserGamepad.buttons[1].value;\r\n            this.buttonX = this.browserGamepad.buttons[2].value;\r\n            this.buttonY = this.browserGamepad.buttons[3].value;\r\n            this.buttonLB = this.browserGamepad.buttons[4].value;\r\n            this.buttonRB = this.browserGamepad.buttons[5].value;\r\n            this.leftTrigger = this.browserGamepad.buttons[6].value;\r\n            this.rightTrigger = this.browserGamepad.buttons[7].value;\r\n            this.buttonBack = this.browserGamepad.buttons[8].value;\r\n            this.buttonStart = this.browserGamepad.buttons[9].value;\r\n            this.buttonLeftStick = this.browserGamepad.buttons[10].value;\r\n            this.buttonRightStick = this.browserGamepad.buttons[11].value;\r\n            this.dPadUp = this.browserGamepad.buttons[12].value;\r\n            this.dPadDown = this.browserGamepad.buttons[13].value;\r\n            this.dPadLeft = this.browserGamepad.buttons[14].value;\r\n            this.dPadRight = this.browserGamepad.buttons[15].value;\r\n        } else {\r\n            this.buttonA = this.browserGamepad.buttons[0].value;\r\n            this.buttonB = this.browserGamepad.buttons[1].value;\r\n            this.buttonX = this.browserGamepad.buttons[2].value;\r\n            this.buttonY = this.browserGamepad.buttons[3].value;\r\n            this.buttonLB = this.browserGamepad.buttons[4].value;\r\n            this.buttonRB = this.browserGamepad.buttons[5].value;\r\n            this.leftTrigger = this.browserGamepad.buttons[6].value;\r\n            this.rightTrigger = this.browserGamepad.buttons[7].value;\r\n            this.buttonBack = this.browserGamepad.buttons[8].value;\r\n            this.buttonStart = this.browserGamepad.buttons[9].value;\r\n            this.buttonLeftStick = this.browserGamepad.buttons[10].value;\r\n            this.buttonRightStick = this.browserGamepad.buttons[11].value;\r\n            this.dPadUp = this.browserGamepad.buttons[12].value;\r\n            this.dPadDown = this.browserGamepad.buttons[13].value;\r\n            this.dPadLeft = this.browserGamepad.buttons[14].value;\r\n            this.dPadRight = this.browserGamepad.buttons[15].value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the gamepad\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        this.onButtonDownObservable.clear();\r\n        this.onButtonUpObservable.clear();\r\n        this.onPadDownObservable.clear();\r\n        this.onPadUpObservable.clear();\r\n    }\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\nimport { Gamepad } from \"./gamepad\";\r\n\r\n/**\r\n * Defines supported buttons for DualShock compatible gamepads\r\n */\r\nexport const enum DualShockButton {\r\n    /** Cross */\r\n    Cross = 0,\r\n    /** Circle */\r\n    Circle = 1,\r\n    /** Square */\r\n    Square = 2,\r\n    /** Triangle */\r\n    Triangle = 3,\r\n    /** L1 */\r\n    L1 = 4,\r\n    /** R1 */\r\n    R1 = 5,\r\n    /** Share */\r\n    Share = 8,\r\n    /** Options */\r\n    Options = 9,\r\n    /** Left stick */\r\n    LeftStick = 10,\r\n    /** Right stick */\r\n    RightStick = 11,\r\n}\r\n\r\n/** Defines values for DualShock DPad  */\r\nexport const enum DualShockDpad {\r\n    /** Up */\r\n    Up = 12,\r\n    /** Down */\r\n    Down = 13,\r\n    /** Left */\r\n    Left = 14,\r\n    /** Right */\r\n    Right = 15,\r\n}\r\n\r\n/**\r\n * Defines a DualShock gamepad\r\n */\r\nexport class DualShockPad extends Gamepad {\r\n    private _leftTrigger: number = 0;\r\n    private _rightTrigger: number = 0;\r\n\r\n    private _onlefttriggerchanged: (value: number) => void;\r\n    private _onrighttriggerchanged: (value: number) => void;\r\n\r\n    private _onbuttondown: (buttonPressed: DualShockButton) => void;\r\n    private _onbuttonup: (buttonReleased: DualShockButton) => void;\r\n    private _ondpaddown: (dPadPressed: DualShockDpad) => void;\r\n    private _ondpadup: (dPadReleased: DualShockDpad) => void;\r\n\r\n    /** Observable raised when a button is pressed */\r\n    public onButtonDownObservable = new Observable<DualShockButton>();\r\n    /** Observable raised when a button is released */\r\n    public onButtonUpObservable = new Observable<DualShockButton>();\r\n    /** Observable raised when a pad is pressed */\r\n    public onPadDownObservable = new Observable<DualShockDpad>();\r\n    /** Observable raised when a pad is released */\r\n    public onPadUpObservable = new Observable<DualShockDpad>();\r\n\r\n    private _buttonCross: number = 0;\r\n    private _buttonCircle: number = 0;\r\n    private _buttonSquare: number = 0;\r\n    private _buttonTriangle: number = 0;\r\n    private _buttonShare: number = 0;\r\n    private _buttonOptions: number = 0;\r\n    private _buttonL1: number = 0;\r\n    private _buttonR1: number = 0;\r\n\r\n    private _buttonLeftStick: number = 0;\r\n    private _buttonRightStick: number = 0;\r\n    private _dPadUp: number = 0;\r\n    private _dPadDown: number = 0;\r\n    private _dPadLeft: number = 0;\r\n    private _dPadRight: number = 0;\r\n\r\n    /**\r\n     * Creates a new DualShock gamepad object\r\n     * @param id defines the id of this gamepad\r\n     * @param index defines its index\r\n     * @param gamepad defines the internal HTML gamepad object\r\n     */\r\n    constructor(id: string, index: number, gamepad: any) {\r\n        super(id.replace(\"STANDARD GAMEPAD\", \"SONY PLAYSTATION DUALSHOCK\"), index, gamepad, 0, 1, 2, 3);\r\n        this.type = Gamepad.DUALSHOCK;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when left trigger is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onlefttriggerchanged(callback: (value: number) => void) {\r\n        this._onlefttriggerchanged = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when right trigger is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onrighttriggerchanged(callback: (value: number) => void) {\r\n        this._onrighttriggerchanged = callback;\r\n    }\r\n\r\n    /**\r\n     * Gets the left trigger value\r\n     */\r\n    public get leftTrigger(): number {\r\n        return this._leftTrigger;\r\n    }\r\n    /**\r\n     * Sets the left trigger value\r\n     */\r\n    public set leftTrigger(newValue: number) {\r\n        if (this._onlefttriggerchanged && this._leftTrigger !== newValue) {\r\n            this._onlefttriggerchanged(newValue);\r\n        }\r\n        this._leftTrigger = newValue;\r\n    }\r\n\r\n    /**\r\n     * Gets the right trigger value\r\n     */\r\n    public get rightTrigger(): number {\r\n        return this._rightTrigger;\r\n    }\r\n    /**\r\n     * Sets the right trigger value\r\n     */\r\n    public set rightTrigger(newValue: number) {\r\n        if (this._onrighttriggerchanged && this._rightTrigger !== newValue) {\r\n            this._onrighttriggerchanged(newValue);\r\n        }\r\n        this._rightTrigger = newValue;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a button is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onbuttondown(callback: (buttonPressed: DualShockButton) => void) {\r\n        this._onbuttondown = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a button is released\r\n     * @param callback defines the callback to use\r\n     */\r\n    public onbuttonup(callback: (buttonReleased: DualShockButton) => void) {\r\n        this._onbuttonup = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a pad is pressed\r\n     * @param callback defines the callback to use\r\n     */\r\n    public ondpaddown(callback: (dPadPressed: DualShockDpad) => void) {\r\n        this._ondpaddown = callback;\r\n    }\r\n\r\n    /**\r\n     * Defines the callback to call when a pad is released\r\n     * @param callback defines the callback to use\r\n     */\r\n    public ondpadup(callback: (dPadReleased: DualShockDpad) => void) {\r\n        this._ondpadup = callback;\r\n    }\r\n\r\n    private _setButtonValue(newValue: number, currentValue: number, buttonType: DualShockButton): number {\r\n        if (newValue !== currentValue) {\r\n            if (newValue === 1) {\r\n                if (this._onbuttondown) {\r\n                    this._onbuttondown(buttonType);\r\n                }\r\n\r\n                this.onButtonDownObservable.notifyObservers(buttonType);\r\n            }\r\n            if (newValue === 0) {\r\n                if (this._onbuttonup) {\r\n                    this._onbuttonup(buttonType);\r\n                }\r\n\r\n                this.onButtonUpObservable.notifyObservers(buttonType);\r\n            }\r\n        }\r\n        return newValue;\r\n    }\r\n\r\n    private _setDpadValue(newValue: number, currentValue: number, buttonType: DualShockDpad): number {\r\n        if (newValue !== currentValue) {\r\n            if (newValue === 1) {\r\n                if (this._ondpaddown) {\r\n                    this._ondpaddown(buttonType);\r\n                }\r\n\r\n                this.onPadDownObservable.notifyObservers(buttonType);\r\n            }\r\n            if (newValue === 0) {\r\n                if (this._ondpadup) {\r\n                    this._ondpadup(buttonType);\r\n                }\r\n\r\n                this.onPadUpObservable.notifyObservers(buttonType);\r\n            }\r\n        }\r\n        return newValue;\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Cross` button\r\n     */\r\n    public get buttonCross(): number {\r\n        return this._buttonCross;\r\n    }\r\n    /**\r\n     * Sets the value of the `Cross` button\r\n     */\r\n    public set buttonCross(value) {\r\n        this._buttonCross = this._setButtonValue(value, this._buttonCross, DualShockButton.Cross);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Circle` button\r\n     */\r\n    public get buttonCircle(): number {\r\n        return this._buttonCircle;\r\n    }\r\n    /**\r\n     * Sets the value of the `Circle` button\r\n     */\r\n    public set buttonCircle(value) {\r\n        this._buttonCircle = this._setButtonValue(value, this._buttonCircle, DualShockButton.Circle);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Square` button\r\n     */\r\n    public get buttonSquare(): number {\r\n        return this._buttonSquare;\r\n    }\r\n    /**\r\n     * Sets the value of the `Square` button\r\n     */\r\n    public set buttonSquare(value) {\r\n        this._buttonSquare = this._setButtonValue(value, this._buttonSquare, DualShockButton.Square);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Triangle` button\r\n     */\r\n    public get buttonTriangle(): number {\r\n        return this._buttonTriangle;\r\n    }\r\n    /**\r\n     * Sets the value of the `Triangle` button\r\n     */\r\n    public set buttonTriangle(value) {\r\n        this._buttonTriangle = this._setButtonValue(value, this._buttonTriangle, DualShockButton.Triangle);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Options` button\r\n     */\r\n    public get buttonOptions(): number {\r\n        return this._buttonOptions;\r\n    }\r\n    /**\r\n     * Sets the value of the `Options` button\r\n     */\r\n    public set buttonOptions(value) {\r\n        this._buttonOptions = this._setButtonValue(value, this._buttonOptions, DualShockButton.Options);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `Share` button\r\n     */\r\n    public get buttonShare(): number {\r\n        return this._buttonShare;\r\n    }\r\n    /**\r\n     * Sets the value of the `Share` button\r\n     */\r\n    public set buttonShare(value) {\r\n        this._buttonShare = this._setButtonValue(value, this._buttonShare, DualShockButton.Share);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `L1` button\r\n     */\r\n    public get buttonL1(): number {\r\n        return this._buttonL1;\r\n    }\r\n    /**\r\n     * Sets the value of the `L1` button\r\n     */\r\n    public set buttonL1(value) {\r\n        this._buttonL1 = this._setButtonValue(value, this._buttonL1, DualShockButton.L1);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the `R1` button\r\n     */\r\n    public get buttonR1(): number {\r\n        return this._buttonR1;\r\n    }\r\n    /**\r\n     * Sets the value of the `R1` button\r\n     */\r\n    public set buttonR1(value) {\r\n        this._buttonR1 = this._setButtonValue(value, this._buttonR1, DualShockButton.R1);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the Left joystick\r\n     */\r\n    public get buttonLeftStick(): number {\r\n        return this._buttonLeftStick;\r\n    }\r\n    /**\r\n     * Sets the value of the Left joystick\r\n     */\r\n    public set buttonLeftStick(value) {\r\n        this._buttonLeftStick = this._setButtonValue(value, this._buttonLeftStick, DualShockButton.LeftStick);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the Right joystick\r\n     */\r\n    public get buttonRightStick(): number {\r\n        return this._buttonRightStick;\r\n    }\r\n    /**\r\n     * Sets the value of the Right joystick\r\n     */\r\n    public set buttonRightStick(value) {\r\n        this._buttonRightStick = this._setButtonValue(value, this._buttonRightStick, DualShockButton.RightStick);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad up\r\n     */\r\n    public get dPadUp(): number {\r\n        return this._dPadUp;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad up\r\n     */\r\n    public set dPadUp(value) {\r\n        this._dPadUp = this._setDpadValue(value, this._dPadUp, DualShockDpad.Up);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad down\r\n     */\r\n    public get dPadDown(): number {\r\n        return this._dPadDown;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad down\r\n     */\r\n    public set dPadDown(value) {\r\n        this._dPadDown = this._setDpadValue(value, this._dPadDown, DualShockDpad.Down);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad left\r\n     */\r\n    public get dPadLeft(): number {\r\n        return this._dPadLeft;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad left\r\n     */\r\n    public set dPadLeft(value) {\r\n        this._dPadLeft = this._setDpadValue(value, this._dPadLeft, DualShockDpad.Left);\r\n    }\r\n\r\n    /**\r\n     * Gets the value of D-pad right\r\n     */\r\n    public get dPadRight(): number {\r\n        return this._dPadRight;\r\n    }\r\n    /**\r\n     * Sets the value of D-pad right\r\n     */\r\n    public set dPadRight(value) {\r\n        this._dPadRight = this._setDpadValue(value, this._dPadRight, DualShockDpad.Right);\r\n    }\r\n\r\n    /**\r\n     * Force the gamepad to synchronize with device values\r\n     */\r\n    public override update() {\r\n        super.update();\r\n        this.buttonCross = this.browserGamepad.buttons[0].value;\r\n        this.buttonCircle = this.browserGamepad.buttons[1].value;\r\n        this.buttonSquare = this.browserGamepad.buttons[2].value;\r\n        this.buttonTriangle = this.browserGamepad.buttons[3].value;\r\n        this.buttonL1 = this.browserGamepad.buttons[4].value;\r\n        this.buttonR1 = this.browserGamepad.buttons[5].value;\r\n        this.leftTrigger = this.browserGamepad.buttons[6].value;\r\n        this.rightTrigger = this.browserGamepad.buttons[7].value;\r\n        this.buttonShare = this.browserGamepad.buttons[8].value;\r\n        this.buttonOptions = this.browserGamepad.buttons[9].value;\r\n        this.buttonLeftStick = this.browserGamepad.buttons[10].value;\r\n        this.buttonRightStick = this.browserGamepad.buttons[11].value;\r\n        this.dPadUp = this.browserGamepad.buttons[12].value;\r\n        this.dPadDown = this.browserGamepad.buttons[13].value;\r\n        this.dPadLeft = this.browserGamepad.buttons[14].value;\r\n        this.dPadRight = this.browserGamepad.buttons[15].value;\r\n    }\r\n\r\n    /**\r\n     * Disposes the gamepad\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        this.onButtonDownObservable.clear();\r\n        this.onButtonUpObservable.clear();\r\n        this.onPadDownObservable.clear();\r\n        this.onPadUpObservable.clear();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { FreeCameraGamepadInput } from \"../Cameras/Inputs/freeCameraGamepadInput\";\r\nimport { ArcRotateCameraGamepadInput } from \"../Cameras/Inputs/arcRotateCameraGamepadInput\";\r\nimport { type GamepadManager } from \"./gamepadManager\";\r\nimport { FreeCameraInputsManager } from \"../Cameras/freeCameraInputsManager.pure\";\r\nimport { ArcRotateCameraInputsManager } from \"../Cameras/arcRotateCameraInputsManager.pure\";\r\n\r\n/**\r\n * Defines the gamepad scene component responsible to manage gamepads in a given scene\r\n */\r\nexport class GamepadSystemSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpfull to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_GAMEPAD;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        // Nothing to do for gamepads\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for gamepads\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        const gamepadManager = this.scene._gamepadManager;\r\n        if (gamepadManager) {\r\n            gamepadManager.dispose();\r\n            this.scene._gamepadManager = null;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gamepadSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param gamepadManagerClass The GamepadManager class to use for lazy instantiation\r\n */\r\nexport function RegisterGamepadSceneComponent(gamepadManagerClass: typeof GamepadManager): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"gamepadManager\", {\r\n        get: function (this: Scene) {\r\n            if (!this._gamepadManager) {\r\n                this._gamepadManager = new gamepadManagerClass(this);\r\n                let component = this._getComponent(SceneComponentConstants.NAME_GAMEPAD) as GamepadSystemSceneComponent;\r\n                if (!component) {\r\n                    component = new GamepadSystemSceneComponent(this);\r\n                    this._addComponent(component);\r\n                }\r\n            }\r\n\r\n            return this._gamepadManager;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    /**\r\n     * Adds a gamepad to the free camera inputs manager\r\n     * @returns the FreeCameraInputsManager\r\n     */\r\n    FreeCameraInputsManager.prototype.addGamepad = function (): FreeCameraInputsManager {\r\n        this.add(new FreeCameraGamepadInput());\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Adds a gamepad to the arc rotate camera inputs manager\r\n     * @returns the camera inputs manager\r\n     */\r\n    ArcRotateCameraInputsManager.prototype.addGamepad = function (): ArcRotateCameraInputsManager {\r\n        this.add(new ArcRotateCameraGamepadInput());\r\n        return this;\r\n    };\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\nimport { IsWindowObjectExist } from \"../Misc/domManagement\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Xbox360Pad } from \"./xboxGamepad\";\r\nimport { Gamepad, GenericPad } from \"./gamepad\";\r\nimport { DualShockPad } from \"./dualShockGamepad\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { RegisterGamepadSceneComponent } from \"./gamepadSceneComponent.pure\";\r\n/**\r\n * Manager for handling gamepads\r\n */\r\nexport class GamepadManager {\r\n    private _babylonGamepads: Array<Gamepad> = [];\r\n    private _oneGamepadConnected: boolean = false;\r\n\r\n    /** @internal */\r\n    public _isMonitoring: boolean = false;\r\n    private _gamepadEventSupported: boolean;\r\n    private _gamepadSupport?: () => Array<any>;\r\n\r\n    /**\r\n     * observable to be triggered when the gamepad controller has been connected\r\n     */\r\n    public onGamepadConnectedObservable: Observable<Gamepad>;\r\n\r\n    /**\r\n     * observable to be triggered when the gamepad controller has been disconnected\r\n     */\r\n    public onGamepadDisconnectedObservable = new Observable<Gamepad>();\r\n\r\n    private _onGamepadConnectedEvent: Nullable<(evt: any) => void>;\r\n    private _onGamepadDisconnectedEvent: Nullable<(evt: any) => void>;\r\n    private _hostWindow: Nullable<Window> = null;\r\n\r\n    /**\r\n     * Initializes the gamepad manager\r\n     * @param _scene BabylonJS scene\r\n     */\r\n    constructor(private _scene?: Scene) {\r\n        RegisterGamepadSceneComponent(GamepadManager);\r\n\r\n        if (!IsWindowObjectExist()) {\r\n            this._gamepadEventSupported = false;\r\n        } else {\r\n            this._gamepadEventSupported = \"GamepadEvent\" in window;\r\n            this._gamepadSupport = navigator && navigator.getGamepads;\r\n        }\r\n\r\n        this.onGamepadConnectedObservable = new Observable<Gamepad>((observer) => {\r\n            // This will be used to raise the onGamepadConnected for all gamepads ALREADY connected\r\n            for (const i in this._babylonGamepads) {\r\n                const gamepad = this._babylonGamepads[i];\r\n                if (gamepad && gamepad._isConnected) {\r\n                    this.onGamepadConnectedObservable.notifyObserver(observer, gamepad);\r\n                }\r\n            }\r\n        });\r\n\r\n        this._onGamepadConnectedEvent = (evt) => {\r\n            const gamepad = evt.gamepad;\r\n\r\n            if (gamepad.index in this._babylonGamepads) {\r\n                if (this._babylonGamepads[gamepad.index].isConnected) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            let newGamepad: Gamepad;\r\n\r\n            if (this._babylonGamepads[gamepad.index]) {\r\n                newGamepad = this._babylonGamepads[gamepad.index];\r\n                newGamepad.browserGamepad = gamepad;\r\n                newGamepad._isConnected = true;\r\n            } else {\r\n                newGamepad = this._addNewGamepad(gamepad);\r\n            }\r\n            this.onGamepadConnectedObservable.notifyObservers(newGamepad);\r\n            this._startMonitoringGamepads();\r\n        };\r\n\r\n        this._onGamepadDisconnectedEvent = (evt) => {\r\n            const gamepad = evt.gamepad;\r\n\r\n            // Remove the gamepad from the list of gamepads to monitor.\r\n            for (const i in this._babylonGamepads) {\r\n                if (this._babylonGamepads[i].index === gamepad.index) {\r\n                    const disconnectedGamepad = this._babylonGamepads[i];\r\n                    disconnectedGamepad._isConnected = false;\r\n\r\n                    this.onGamepadDisconnectedObservable.notifyObservers(disconnectedGamepad);\r\n                    if (disconnectedGamepad.dispose) {\r\n                        disconnectedGamepad.dispose();\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n        };\r\n\r\n        if (this._gamepadSupport) {\r\n            //first add already-connected gamepads\r\n            this._updateGamepadObjects();\r\n            if (this._babylonGamepads.length) {\r\n                this._startMonitoringGamepads();\r\n            }\r\n            // Checking if the gamepad connected event is supported (like in Firefox)\r\n            if (this._gamepadEventSupported) {\r\n                const hostWindow = this._scene ? this._scene.getEngine().getHostWindow() : window;\r\n\r\n                if (hostWindow) {\r\n                    this._hostWindow = hostWindow;\r\n                    hostWindow.addEventListener(\"gamepadconnected\", this._onGamepadConnectedEvent, false);\r\n                    hostWindow.addEventListener(\"gamepaddisconnected\", this._onGamepadDisconnectedEvent, false);\r\n                }\r\n            } else {\r\n                this._startMonitoringGamepads();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The gamepads in the game pad manager\r\n     */\r\n    public get gamepads(): Gamepad[] {\r\n        return this._babylonGamepads;\r\n    }\r\n\r\n    /**\r\n     * Get the gamepad controllers based on type\r\n     * @param type The type of gamepad controller\r\n     * @returns Nullable gamepad\r\n     */\r\n    public getGamepadByType(type: number = Gamepad.XBOX): Nullable<Gamepad> {\r\n        for (const gamepad of this._babylonGamepads) {\r\n            if (gamepad && gamepad.type === type) {\r\n                return gamepad;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Disposes the gamepad manager\r\n     */\r\n    public dispose() {\r\n        if (this._gamepadEventSupported) {\r\n            if (this._onGamepadConnectedEvent) {\r\n                this._hostWindow?.removeEventListener(\"gamepadconnected\", this._onGamepadConnectedEvent);\r\n            }\r\n\r\n            if (this._onGamepadDisconnectedEvent) {\r\n                this._hostWindow?.removeEventListener(\"gamepaddisconnected\", this._onGamepadDisconnectedEvent);\r\n            }\r\n            this._hostWindow = null;\r\n            this._onGamepadConnectedEvent = null;\r\n            this._onGamepadDisconnectedEvent = null;\r\n        }\r\n\r\n        for (const gamepad of this._babylonGamepads) {\r\n            gamepad.dispose();\r\n        }\r\n\r\n        this.onGamepadConnectedObservable.clear();\r\n        this.onGamepadDisconnectedObservable.clear();\r\n\r\n        this._oneGamepadConnected = false;\r\n        this._stopMonitoringGamepads();\r\n        this._babylonGamepads = [];\r\n    }\r\n\r\n    private _addNewGamepad(gamepad: any): Gamepad {\r\n        if (!this._oneGamepadConnected) {\r\n            this._oneGamepadConnected = true;\r\n        }\r\n\r\n        let newGamepad;\r\n        const dualShock: boolean = (<string>gamepad.id).search(\"054c\") !== -1 && (<string>gamepad.id).search(\"0ce6\") === -1;\r\n        const xboxOne: boolean = (<string>gamepad.id).search(\"Xbox One\") !== -1;\r\n        if (\r\n            xboxOne ||\r\n            (<string>gamepad.id).search(\"Xbox 360\") !== -1 ||\r\n            (<string>gamepad.id).search(\"xinput\") !== -1 ||\r\n            ((<string>gamepad.id).search(\"045e\") !== -1 && (<string>gamepad.id).search(\"Surface Dock\") === -1)\r\n        ) {\r\n            // make sure the Surface Dock Extender is not detected as an xbox controller\r\n            newGamepad = new Xbox360Pad(gamepad.id, gamepad.index, gamepad, xboxOne);\r\n        } else if (dualShock) {\r\n            newGamepad = new DualShockPad(gamepad.id, gamepad.index, gamepad);\r\n        } else {\r\n            newGamepad = new GenericPad(gamepad.id, gamepad.index, gamepad);\r\n        }\r\n        this._babylonGamepads[newGamepad.index] = newGamepad;\r\n        return newGamepad;\r\n    }\r\n\r\n    private _startMonitoringGamepads() {\r\n        if (!this._isMonitoring) {\r\n            this._isMonitoring = true;\r\n            //back-comp\r\n            this._checkGamepadsStatus();\r\n        }\r\n    }\r\n\r\n    private _stopMonitoringGamepads() {\r\n        this._isMonitoring = false;\r\n    }\r\n\r\n    private _loggedErrors: number[];\r\n\r\n    /** @internal */\r\n    public _checkGamepadsStatus() {\r\n        // Hack to be compatible Chrome\r\n        this._updateGamepadObjects();\r\n\r\n        for (const i in this._babylonGamepads) {\r\n            const gamepad = this._babylonGamepads[i];\r\n            if (!gamepad || !gamepad.isConnected) {\r\n                continue;\r\n            }\r\n            try {\r\n                gamepad.update();\r\n            } catch {\r\n                if (this._loggedErrors.indexOf(gamepad.index) === -1) {\r\n                    Tools.Warn(`Error updating gamepad ${gamepad.id}`);\r\n                    this._loggedErrors.push(gamepad.index);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._isMonitoring) {\r\n            AbstractEngine.QueueNewFrame(() => {\r\n                this._checkGamepadsStatus();\r\n            });\r\n        }\r\n    }\r\n\r\n    // This function is called only on Chrome, which does not properly support\r\n    // connection/disconnection events and forces you to recopy again the gamepad object\r\n    private _updateGamepadObjects() {\r\n        const gamepads = navigator.getGamepads ? navigator.getGamepads() : [];\r\n        for (let i = 0; i < gamepads.length; i++) {\r\n            const gamepad = gamepads[i];\r\n            if (gamepad) {\r\n                if (!this._babylonGamepads[gamepad.index]) {\r\n                    const newGamepad = this._addNewGamepad(gamepad);\r\n                    this.onGamepadConnectedObservable.notifyObservers(newGamepad);\r\n                } else {\r\n                    // Forced to copy again this object for Chrome for unknown reason\r\n                    this._babylonGamepads[i].browserGamepad = gamepad;\r\n\r\n                    if (!this._babylonGamepads[i].isConnected) {\r\n                        this._babylonGamepads[i]._isConnected = true;\r\n                        this.onGamepadConnectedObservable.notifyObservers(this._babylonGamepads[i]);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable github/no-then */\r\n/* eslint-disable @typescript-eslint/no-floating-promises */\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { FreeCamera } from \"../../Cameras/freeCamera.pure\";\r\nimport { TargetCamera } from \"../../Cameras/targetCamera.pure\";\r\nimport { DeviceOrientationCamera } from \"../../Cameras/deviceOrientationCamera.pure\";\r\nimport { VRDeviceOrientationFreeCamera } from \"../../Cameras/VR/vrDeviceOrientationFreeCamera.pure\";\r\nimport { PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { type Scene, type IDisposable } from \"../../scene.pure\";\r\nimport { Quaternion, Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../../Maths/math.color.pure\";\r\nimport { type StickValues, Gamepad } from \"../../Gamepads/gamepad\";\r\nimport { type Xbox360Pad, Xbox360Button } from \"../../Gamepads/xboxGamepad\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { Ray } from \"../../Culling/ray.pure\";\r\nimport { ImageProcessingConfiguration } from \"../../Materials/imageProcessingConfiguration.pure\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial.pure\";\r\nimport { DynamicTexture } from \"../../Materials/Textures/dynamicTexture.pure\";\r\nimport { type ImageProcessingPostProcess } from \"../../PostProcesses/imageProcessingPostProcess\";\r\nimport { SineEase, EasingFunction, CircleEase } from \"../../Animations/easing\";\r\nimport { Animation } from \"../../Animations/animation.pure\";\r\nimport { type VRCameraMetrics } from \"../../Cameras/VR/vrCameraMetrics\";\r\nimport { WebXRSessionManager } from \"../../XR/webXRSessionManager\";\r\nimport { type WebXRDefaultExperience } from \"../../XR/webXRDefaultExperience\";\r\nimport { WebXRState } from \"../../XR/webXRTypes\";\r\nimport { CreateGround } from \"../../Meshes/Builders/groundBuilder.pure\";\r\nimport { type IPointerEvent } from \"../../Events/deviceInputEvents\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { CreateTorus } from \"core/Meshes/Builders/torusBuilder.pure\";\r\nimport { GamepadManager } from \"../../Gamepads/gamepadManager\";\r\nimport { RegisterGamepadSceneComponent } from \"../../Gamepads/gamepadSceneComponent.pure\";\r\nimport { RegisterAnimatable } from \"../../Animations/animatable.pure\";\r\n\r\n/**\r\n * Options to modify the vr teleportation behavior.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface VRTeleportationOptions {\r\n    /**\r\n     * The name of the mesh which should be used as the teleportation floor. (default: null)\r\n     */\r\n    floorMeshName?: string;\r\n    /**\r\n     * A list of meshes to be used as the teleportation floor. (default: empty)\r\n     */\r\n    floorMeshes?: Mesh[];\r\n    /**\r\n     * The teleportation mode. (default: TELEPORTATIONMODE_CONSTANTTIME)\r\n     */\r\n    teleportationMode?: number;\r\n    /**\r\n     * The duration of the animation in ms, apply when animationMode is TELEPORTATIONMODE_CONSTANTTIME. (default 122ms)\r\n     */\r\n    teleportationTime?: number;\r\n    /**\r\n     * The speed of the animation in distance/sec, apply when animationMode is TELEPORTATIONMODE_CONSTANTSPEED. (default 20 units / sec)\r\n     */\r\n    teleportationSpeed?: number;\r\n    /**\r\n     * The easing function used in the animation or null for Linear. (default CircleEase)\r\n     */\r\n    easingFunction?: EasingFunction;\r\n}\r\n\r\n/**\r\n * Options to modify the vr experience helper's behavior.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface VRExperienceHelperOptions {\r\n    /**\r\n     * Create a DeviceOrientationCamera to be used as your out of vr camera. (default: true)\r\n     */\r\n    createDeviceOrientationCamera?: boolean;\r\n    /**\r\n     * Create a VRDeviceOrientationFreeCamera to be used for VR when no external HMD is found. (default: true)\r\n     */\r\n    createFallbackVRDeviceOrientationFreeCamera?: boolean;\r\n    /**\r\n     * Uses the main button on the controller to toggle the laser casted. (default: true)\r\n     */\r\n    laserToggle?: boolean;\r\n    /**\r\n     * A list of meshes to be used as the teleportation floor. If specified, teleportation will be enabled (default: undefined)\r\n     */\r\n    floorMeshes?: Mesh[];\r\n    /**\r\n     * Distortion metrics for the fallback vrDeviceOrientationCamera (default: VRCameraMetrics.Default)\r\n     */\r\n    vrDeviceOrientationCameraMetrics?: VRCameraMetrics;\r\n    /**\r\n     * Defines if WebXR should be used (if available)\r\n     */\r\n    useXR?: boolean;\r\n}\r\n\r\nclass VRExperienceHelperGazer implements IDisposable {\r\n    /** @internal */\r\n    public _gazeTracker: Mesh;\r\n\r\n    /** @internal */\r\n    public _currentMeshSelected: Nullable<AbstractMesh>;\r\n    /** @internal */\r\n    public _currentHit: Nullable<PickingInfo>;\r\n\r\n    public static _IdCounter = 0;\r\n    /** @internal */\r\n    public _id: number;\r\n\r\n    /** @internal */\r\n    public _pointerDownOnMeshAsked: boolean = false;\r\n    /** @internal */\r\n    public _isActionableMesh: boolean = false;\r\n\r\n    /** @internal */\r\n    public _interactionsEnabled: boolean;\r\n    /** @internal */\r\n    public _teleportationEnabled: boolean;\r\n    /** @internal */\r\n    public _teleportationRequestInitiated = false;\r\n    /** @internal */\r\n    public _teleportationBackRequestInitiated = false;\r\n    /** @internal */\r\n    public _rotationRightAsked = false;\r\n    /** @internal */\r\n    public _rotationLeftAsked = false;\r\n    /** @internal */\r\n    public _dpadPressed = true;\r\n\r\n    /** @internal */\r\n    public _activePointer = false;\r\n\r\n    constructor(\r\n        public scene: Scene,\r\n        gazeTrackerToClone: Nullable<Mesh> = null\r\n    ) {\r\n        this._id = VRExperienceHelperGazer._IdCounter++;\r\n\r\n        // Gaze tracker\r\n        if (!gazeTrackerToClone) {\r\n            this._gazeTracker = CreateTorus(\r\n                \"gazeTracker\",\r\n                {\r\n                    diameter: 0.0035,\r\n                    thickness: 0.0025,\r\n                    tessellation: 20,\r\n                    updatable: false,\r\n                },\r\n                scene\r\n            );\r\n            this._gazeTracker.bakeCurrentTransformIntoVertices();\r\n            this._gazeTracker.isPickable = false;\r\n            this._gazeTracker.isVisible = false;\r\n            const targetMat = new StandardMaterial(\"targetMat\", scene);\r\n            targetMat.specularColor = Color3.Black();\r\n            targetMat.emissiveColor = new Color3(0.7, 0.7, 0.7);\r\n            targetMat.backFaceCulling = false;\r\n            this._gazeTracker.material = targetMat;\r\n        } else {\r\n            this._gazeTracker = gazeTrackerToClone.clone(\"gazeTracker\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getForwardRay(length: number): Ray {\r\n        return new Ray(Vector3.Zero(), new Vector3(0, 0, length));\r\n    }\r\n\r\n    /** @internal */\r\n    public _selectionPointerDown() {\r\n        this._pointerDownOnMeshAsked = true;\r\n        if (this._currentHit) {\r\n            this.scene.simulatePointerDown(this._currentHit, { pointerId: this._id });\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _selectionPointerUp() {\r\n        if (this._currentHit) {\r\n            this.scene.simulatePointerUp(this._currentHit, { pointerId: this._id });\r\n        }\r\n        this._pointerDownOnMeshAsked = false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _activatePointer() {\r\n        this._activePointer = true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _deactivatePointer() {\r\n        this._activePointer = false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _updatePointerDistance(distance: number = 100) {}\r\n\r\n    public dispose() {\r\n        this._interactionsEnabled = false;\r\n        this._teleportationEnabled = false;\r\n        if (this._gazeTracker) {\r\n            this._gazeTracker.dispose();\r\n        }\r\n    }\r\n}\r\n\r\nclass VRExperienceHelperCameraGazer extends VRExperienceHelperGazer {\r\n    constructor(\r\n        private _getCamera: () => Nullable<Camera>,\r\n        scene: Scene\r\n    ) {\r\n        super(scene);\r\n    }\r\n\r\n    override _getForwardRay(length: number): Ray {\r\n        const camera = this._getCamera();\r\n        if (camera) {\r\n            return camera.getForwardRay(length);\r\n        } else {\r\n            return new Ray(Vector3.Zero(), Vector3.Forward());\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Event containing information after VR has been entered\r\n */\r\nexport class OnAfterEnteringVRObservableEvent {\r\n    /**\r\n     * If entering vr was successful\r\n     */\r\n    public success: boolean;\r\n}\r\n\r\n/**\r\n * Helps to quickly add VR support to an existing scene.\r\n * See https://doc.babylonjs.com/features/featuresDeepDive/cameras/webVRHelper\r\n * @deprecated Use WebXR instead!\r\n */\r\nexport class VRExperienceHelper {\r\n    private _scene: Scene;\r\n    private _position: Vector3;\r\n    private _btnVR: Nullable<HTMLButtonElement>;\r\n    private _btnVRDisplayed: boolean;\r\n\r\n    // Have we entered VR? (this is the VRExperienceHelper state)\r\n    private _hasEnteredVR: boolean;\r\n\r\n    // Are we presenting in the fullscreen fallback?\r\n    private _fullscreenVRpresenting = false;\r\n\r\n    private _inputElement: Nullable<HTMLElement>;\r\n    private _vrDeviceOrientationCamera: Nullable<VRDeviceOrientationFreeCamera>;\r\n    private _deviceOrientationCamera: Nullable<DeviceOrientationCamera>;\r\n    private _existingCamera: Camera;\r\n\r\n    private _onKeyDown: (event: KeyboardEvent) => void;\r\n    private _onVrDisplayPresentChangeBind: any;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that gaze can be enabled even if pointer lock is not engage (useful on iOS where fullscreen mode and pointer lock are not supported)\r\n     */\r\n    public enableGazeEvenWhenNoPointerLock = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the VREXperienceHelper will exit VR if double tap is detected\r\n     */\r\n    public exitVROnDoubleTap = true;\r\n\r\n    /**\r\n     * Observable raised right before entering VR.\r\n     */\r\n    public onEnteringVRObservable = new Observable<VRExperienceHelper>();\r\n\r\n    /**\r\n     * Observable raised when entering VR has completed.\r\n     */\r\n    public onAfterEnteringVRObservable = new Observable<OnAfterEnteringVRObservableEvent>();\r\n\r\n    /**\r\n     * Observable raised when exiting VR.\r\n     */\r\n    public onExitingVRObservable = new Observable<VRExperienceHelper>();\r\n\r\n    /** Return this.onEnteringVRObservable\r\n     * Note: This one is for backward compatibility. Please use onEnteringVRObservable directly\r\n     */\r\n    public get onEnteringVR(): Observable<VRExperienceHelper> {\r\n        return this.onEnteringVRObservable;\r\n    }\r\n\r\n    /** Return this.onExitingVRObservable\r\n     * Note: This one is for backward compatibility. Please use onExitingVRObservable directly\r\n     */\r\n    public get onExitingVR(): Observable<VRExperienceHelper> {\r\n        return this.onExitingVRObservable;\r\n    }\r\n\r\n    private _useCustomVRButton: boolean = false;\r\n    private _teleportActive = false;\r\n    private _floorMeshName: string;\r\n    private _floorMeshesCollection: Mesh[] = [];\r\n    private _teleportationMode: number = VRExperienceHelper.TELEPORTATIONMODE_CONSTANTTIME;\r\n    private _teleportationTime: number = 122;\r\n    private _teleportationSpeed: number = 20;\r\n    private _teleportationEasing: EasingFunction;\r\n    private _rotationAllowed: boolean = true;\r\n    private _teleportBackwardsVector = new Vector3(0, -1, -1);\r\n    private _teleportationTarget: Mesh;\r\n    private _isDefaultTeleportationTarget = true;\r\n    private _postProcessMove: ImageProcessingPostProcess;\r\n    private _teleportationFillColor: string = \"#444444\";\r\n    private _teleportationBorderColor: string = \"#FFFFFF\";\r\n    private _rotationAngle: number = 0;\r\n    private _haloCenter = new Vector3(0, 0, 0);\r\n    private _cameraGazer: VRExperienceHelperCameraGazer;\r\n    private _padSensibilityUp = 0.65;\r\n    private _padSensibilityDown = 0.35;\r\n\r\n    private _pickedLaserColor: Color3 = new Color3(0.2, 0.2, 1);\r\n    private _pickedGazeColor: Color3 = new Color3(0, 0, 1);\r\n\r\n    /**\r\n     * Observable raised when a new mesh is selected based on meshSelectionPredicate\r\n     */\r\n    public onNewMeshSelected = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * Observable raised when a new mesh is picked based on meshSelectionPredicate\r\n     */\r\n    public onNewMeshPicked = new Observable<PickingInfo>();\r\n\r\n    private _circleEase: CircleEase;\r\n\r\n    /**\r\n     * Observable raised before camera teleportation\r\n     */\r\n    public onBeforeCameraTeleport = new Observable<Vector3>();\r\n\r\n    /**\r\n     *  Observable raised after camera teleportation\r\n     */\r\n    public onAfterCameraTeleport = new Observable<Vector3>();\r\n\r\n    /**\r\n     * Observable raised when current selected mesh gets unselected\r\n     */\r\n    public onSelectedMeshUnselected = new Observable<AbstractMesh>();\r\n\r\n    private _raySelectionPredicate: (mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * To be optionally changed by user to define custom ray selection\r\n     */\r\n    public raySelectionPredicate: (mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * To be optionally changed by user to define custom selection logic (after ray selection)\r\n     */\r\n    public meshSelectionPredicate: (mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * Set teleportation enabled. If set to false camera teleportation will be disabled but camera rotation will be kept.\r\n     */\r\n    public teleportationEnabled: boolean = true;\r\n\r\n    private _defaultHeight: number;\r\n    private _teleportationInitialized = false;\r\n    private _interactionsEnabled = false;\r\n    private _displayGaze = true;\r\n    private _displayLaserPointer = true;\r\n\r\n    /**\r\n     * The mesh used to display where the user is going to teleport.\r\n     */\r\n    public get teleportationTarget(): Mesh {\r\n        return this._teleportationTarget;\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh to be used to display where the user is going to teleport.\r\n     */\r\n    public set teleportationTarget(value: Mesh) {\r\n        if (value) {\r\n            value.name = \"teleportationTarget\";\r\n            this._isDefaultTeleportationTarget = false;\r\n            this._teleportationTarget = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The mesh used to display where the user is selecting, this mesh will be cloned and set as the gazeTracker for the left and right controller\r\n     * when set bakeCurrentTransformIntoVertices will be called on the mesh.\r\n     * See https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/bakingTransforms\r\n     */\r\n    public get gazeTrackerMesh(): Mesh {\r\n        return this._cameraGazer._gazeTracker;\r\n    }\r\n\r\n    public set gazeTrackerMesh(value: Mesh) {\r\n        if (value) {\r\n            // Dispose of existing meshes\r\n            if (this._cameraGazer._gazeTracker) {\r\n                this._cameraGazer._gazeTracker.dispose();\r\n            }\r\n\r\n            // Set and create gaze trackers on head and controllers\r\n            this._cameraGazer._gazeTracker = value;\r\n            this._cameraGazer._gazeTracker.bakeCurrentTransformIntoVertices();\r\n            this._cameraGazer._gazeTracker.isPickable = false;\r\n            this._cameraGazer._gazeTracker.isVisible = false;\r\n            this._cameraGazer._gazeTracker.name = \"gazeTracker\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the gaze trackers scale should be updated to be constant size when pointing at near/far meshes\r\n     */\r\n    public updateGazeTrackerScale = true;\r\n    /**\r\n     * If the gaze trackers color should be updated when selecting meshes\r\n     */\r\n    public updateGazeTrackerColor = true;\r\n    /**\r\n     * If the controller laser color should be updated when selecting meshes\r\n     */\r\n    public updateControllerLaserColor = true;\r\n\r\n    /**\r\n     * If the ray of the gaze should be displayed.\r\n     */\r\n    public get displayGaze(): boolean {\r\n        return this._displayGaze;\r\n    }\r\n\r\n    /**\r\n     * Sets if the ray of the gaze should be displayed.\r\n     */\r\n    public set displayGaze(value: boolean) {\r\n        this._displayGaze = value;\r\n        if (!value) {\r\n            this._cameraGazer._gazeTracker.isVisible = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the ray of the LaserPointer should be displayed.\r\n     */\r\n    public get displayLaserPointer(): boolean {\r\n        return this._displayLaserPointer;\r\n    }\r\n\r\n    /**\r\n     * Sets if the ray of the LaserPointer should be displayed.\r\n     */\r\n    public set displayLaserPointer(value: boolean) {\r\n        this._displayLaserPointer = value;\r\n    }\r\n\r\n    /**\r\n     * The deviceOrientationCamera used as the camera when not in VR.\r\n     */\r\n    public get deviceOrientationCamera(): Nullable<DeviceOrientationCamera> {\r\n        return this._deviceOrientationCamera;\r\n    }\r\n\r\n    /**\r\n     * Based on the current WebVR support, returns the current VR camera used.\r\n     */\r\n    public get currentVRCamera(): Nullable<Camera> {\r\n        return this._scene.activeCamera;\r\n    }\r\n\r\n    /**\r\n     * The deviceOrientationCamera that is used as a fallback when vr device is not connected.\r\n     */\r\n    public get vrDeviceOrientationCamera(): Nullable<VRDeviceOrientationFreeCamera> {\r\n        return this._vrDeviceOrientationCamera;\r\n    }\r\n\r\n    /**\r\n     * The html button that is used to trigger entering into VR.\r\n     */\r\n    public get vrButton(): Nullable<HTMLButtonElement> {\r\n        return this._btnVR;\r\n    }\r\n\r\n    private get _teleportationRequestInitiated(): boolean {\r\n        return this._cameraGazer._teleportationRequestInitiated;\r\n    }\r\n\r\n    /**\r\n     * Defines whether or not Pointer lock should be requested when switching to\r\n     * full screen.\r\n     */\r\n    public requestPointerLockOnFullScreen = true;\r\n\r\n    // XR\r\n\r\n    /**\r\n     * If asking to force XR, this will be populated with the default xr experience\r\n     */\r\n    public xr: WebXRDefaultExperience;\r\n\r\n    /**\r\n     * Was the XR test done already. If this is true AND this.xr exists, xr is initialized.\r\n     * If this is true and no this.xr, xr exists but is not supported, using WebVR.\r\n     */\r\n    public xrTestDone: boolean = false;\r\n\r\n    /**\r\n     * Instantiates a VRExperienceHelper.\r\n     * Helps to quickly add VR support to an existing scene.\r\n     * @param scene The scene the VRExperienceHelper belongs to.\r\n     * @param webVROptions Options to modify the vr experience helper's behavior.\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        /** [Empty object] Options to modify the vr experience helper's behavior. */\r\n        public webVROptions: VRExperienceHelperOptions = {}\r\n    ) {\r\n        Logger.Warn(\"WebVR is deprecated. Please avoid using this experience helper and use the WebXR experience helper instead\");\r\n        this._scene = scene;\r\n        RegisterGamepadSceneComponent(GamepadManager);\r\n        RegisterAnimatable();\r\n        this._inputElement = scene.getEngine().getInputElement();\r\n\r\n        // check for VR support:\r\n\r\n        const vrSupported = \"getVRDisplays\" in navigator;\r\n        // no VR support? force XR but only when it is not set because web vr can work without the getVRDisplays\r\n        if (!vrSupported && webVROptions.useXR === undefined) {\r\n            webVROptions.useXR = true;\r\n        }\r\n\r\n        // Parse options\r\n        if (webVROptions.createFallbackVRDeviceOrientationFreeCamera === undefined) {\r\n            webVROptions.createFallbackVRDeviceOrientationFreeCamera = true;\r\n        }\r\n        if (webVROptions.createDeviceOrientationCamera === undefined) {\r\n            webVROptions.createDeviceOrientationCamera = true;\r\n        }\r\n        if (webVROptions.laserToggle === undefined) {\r\n            webVROptions.laserToggle = true;\r\n        }\r\n\r\n        this._hasEnteredVR = false;\r\n\r\n        // Set position\r\n        if (this._scene.activeCamera) {\r\n            this._position = this._scene.activeCamera.position.clone();\r\n        } else {\r\n            this._position = new Vector3(0, this._defaultHeight, 0);\r\n        }\r\n\r\n        // Set non-vr camera\r\n        if (webVROptions.createDeviceOrientationCamera || !this._scene.activeCamera) {\r\n            this._deviceOrientationCamera = new DeviceOrientationCamera(\"deviceOrientationVRHelper\", this._position.clone(), scene);\r\n\r\n            // Copy data from existing camera\r\n            if (this._scene.activeCamera) {\r\n                this._deviceOrientationCamera.minZ = this._scene.activeCamera.minZ;\r\n                this._deviceOrientationCamera.maxZ = this._scene.activeCamera.maxZ;\r\n                // Set rotation from previous camera\r\n                if (this._scene.activeCamera instanceof TargetCamera && this._scene.activeCamera.rotation) {\r\n                    const targetCamera = this._scene.activeCamera;\r\n                    if (targetCamera.rotationQuaternion) {\r\n                        this._deviceOrientationCamera.rotationQuaternion?.copyFrom(targetCamera.rotationQuaternion);\r\n                    } else {\r\n                        this._deviceOrientationCamera.rotationQuaternion?.copyFrom(\r\n                            Quaternion.RotationYawPitchRoll(targetCamera.rotation.y, targetCamera.rotation.x, targetCamera.rotation.z)\r\n                        );\r\n                    }\r\n                    this._deviceOrientationCamera.rotation = targetCamera.rotation.clone();\r\n                }\r\n            }\r\n\r\n            this._scene.activeCamera = this._deviceOrientationCamera;\r\n            if (this._inputElement) {\r\n                this._scene.activeCamera.attachControl();\r\n            }\r\n        } else {\r\n            this._existingCamera = this._scene.activeCamera;\r\n        }\r\n\r\n        if (this.webVROptions.useXR && (navigator as any).xr) {\r\n            // force-check XR session support\r\n            WebXRSessionManager.IsSessionSupportedAsync(\"immersive-vr\").then((supported) => {\r\n                if (supported) {\r\n                    Logger.Log(\"Using WebXR. It is recommended to use the WebXRDefaultExperience directly\");\r\n                    // it is possible to use XR, let's do it!\r\n                    scene\r\n                        .createDefaultXRExperienceAsync({\r\n                            floorMeshes: webVROptions.floorMeshes || [],\r\n                        })\r\n                        .then((xr) => {\r\n                            this.xr = xr;\r\n                            // connect observables\r\n                            this.xrTestDone = true;\r\n\r\n                            this._cameraGazer = new VRExperienceHelperCameraGazer(() => {\r\n                                return this.xr.baseExperience.camera;\r\n                            }, scene);\r\n\r\n                            this.xr.baseExperience.onStateChangedObservable.add((state) => {\r\n                                // support for entering / exiting\r\n                                switch (state) {\r\n                                    case WebXRState.ENTERING_XR:\r\n                                        this.onEnteringVRObservable.notifyObservers(this);\r\n                                        if (!this._interactionsEnabled) {\r\n                                            this.xr.pointerSelection.detach();\r\n                                        }\r\n                                        this.xr.pointerSelection.displayLaserPointer = this._displayLaserPointer;\r\n                                        break;\r\n                                    case WebXRState.EXITING_XR:\r\n                                        this.onExitingVRObservable.notifyObservers(this);\r\n\r\n                                        // resize to update width and height when exiting vr exits fullscreen\r\n                                        this._scene.getEngine().resize();\r\n                                        break;\r\n                                    case WebXRState.IN_XR:\r\n                                        this._hasEnteredVR = true;\r\n                                        break;\r\n                                    case WebXRState.NOT_IN_XR:\r\n                                        this._hasEnteredVR = false;\r\n                                        break;\r\n                                }\r\n                            });\r\n                        });\r\n                } else {\r\n                    // XR not supported (thou exists), continue WebVR init\r\n                    this._completeVRInit(scene, webVROptions);\r\n                }\r\n            });\r\n        } else {\r\n            // no XR, continue init synchronous\r\n            this._completeVRInit(scene, webVROptions);\r\n        }\r\n    }\r\n\r\n    private _completeVRInit(scene: Scene, webVROptions: VRExperienceHelperOptions): void {\r\n        this.xrTestDone = true;\r\n        // Create VR cameras\r\n        if (webVROptions.createFallbackVRDeviceOrientationFreeCamera) {\r\n            this._vrDeviceOrientationCamera = new VRDeviceOrientationFreeCamera(\r\n                \"VRDeviceOrientationVRHelper\",\r\n                this._position,\r\n                this._scene,\r\n                true,\r\n                webVROptions.vrDeviceOrientationCameraMetrics\r\n            );\r\n            this._vrDeviceOrientationCamera.angularSensibility = Number.MAX_VALUE;\r\n        }\r\n\r\n        this._cameraGazer = new VRExperienceHelperCameraGazer(() => {\r\n            return this.currentVRCamera;\r\n        }, scene);\r\n        // Create default button\r\n        if (!this._useCustomVRButton) {\r\n            this._btnVR = <HTMLButtonElement>document.createElement(\"BUTTON\");\r\n            this._btnVR.className = \"babylonVRicon\";\r\n            this._btnVR.id = \"babylonVRiconbtn\";\r\n            this._btnVR.title = \"Click to switch to VR\";\r\n            const url = !window.SVGSVGElement\r\n                ? \"https://cdn.babylonjs.com/Assets/vrButton.png\"\r\n                : \"data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%222048%22%20height%3D%221152%22%20viewBox%3D%220%200%202048%201152%22%20version%3D%221.1%22%3E%3Cpath%20transform%3D%22rotate%28180%201024%2C576.0000000000001%29%22%20d%3D%22m1109%2C896q17%2C0%2030%2C-12t13%2C-30t-12.5%2C-30.5t-30.5%2C-12.5l-170%2C0q-18%2C0%20-30.5%2C12.5t-12.5%2C30.5t13%2C30t30%2C12l170%2C0zm-85%2C256q59%2C0%20132.5%2C-1.5t154.5%2C-5.5t164.5%2C-11.5t163%2C-20t150%2C-30t124.5%2C-41.5q23%2C-11%2042%2C-24t38%2C-30q27%2C-25%2041%2C-61.5t14%2C-72.5l0%2C-257q0%2C-123%20-47%2C-232t-128%2C-190t-190%2C-128t-232%2C-47l-81%2C0q-37%2C0%20-68.5%2C14t-60.5%2C34.5t-55.5%2C45t-53%2C45t-53%2C34.5t-55.5%2C14t-55.5%2C-14t-53%2C-34.5t-53%2C-45t-55.5%2C-45t-60.5%2C-34.5t-68.5%2C-14l-81%2C0q-123%2C0%20-232%2C47t-190%2C128t-128%2C190t-47%2C232l0%2C257q0%2C68%2038%2C115t97%2C73q54%2C24%20124.5%2C41.5t150%2C30t163%2C20t164.5%2C11.5t154.5%2C5.5t132.5%2C1.5zm939%2C-298q0%2C39%20-24.5%2C67t-58.5%2C42q-54%2C23%20-122%2C39.5t-143.5%2C28t-155.5%2C19t-157%2C11t-148.5%2C5t-129.5%2C1.5q-59%2C0%20-130%2C-1.5t-148%2C-5t-157%2C-11t-155.5%2C-19t-143.5%2C-28t-122%2C-39.5q-34%2C-14%20-58.5%2C-42t-24.5%2C-67l0%2C-257q0%2C-106%2040.5%2C-199t110%2C-162.5t162.5%2C-109.5t199%2C-40l81%2C0q27%2C0%2052%2C14t50%2C34.5t51%2C44.5t55.5%2C44.5t63.5%2C34.5t74%2C14t74%2C-14t63.5%2C-34.5t55.5%2C-44.5t51%2C-44.5t50%2C-34.5t52%2C-14l14%2C0q37%2C0%2070%2C0.5t64.5%2C4.5t63.5%2C12t68%2C23q71%2C30%20128.5%2C78.5t98.5%2C110t63.5%2C133.5t22.5%2C149l0%2C257z%22%20fill%3D%22white%22%20/%3E%3C/svg%3E%0A\";\r\n            let css =\r\n                \".babylonVRicon { position: absolute; right: 20px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-image: url(\" +\r\n                url +\r\n                \"); background-size: 80%; background-repeat:no-repeat; background-position: center; border: none; outline: none; transition: transform 0.125s ease-out } .babylonVRicon:hover { transform: scale(1.05) } .babylonVRicon:active {background-color: rgba(51,51,51,1) } .babylonVRicon:focus {background-color: rgba(51,51,51,1) }\";\r\n            css += \".babylonVRicon.vrdisplaypresenting { display: none; }\";\r\n            // TODO: Add user feedback so that they know what state the VRDisplay is in (disconnected, connected, entering-VR)\r\n            // css += \".babylonVRicon.vrdisplaysupported { }\";\r\n            // css += \".babylonVRicon.vrdisplayready { }\";\r\n            // css += \".babylonVRicon.vrdisplayrequesting { }\";\r\n\r\n            const style = document.createElement(\"style\");\r\n            style.appendChild(document.createTextNode(css));\r\n            document.getElementsByTagName(\"head\")[0].appendChild(style);\r\n\r\n            this._moveButtonToBottomRight();\r\n        }\r\n\r\n        // VR button click event\r\n        if (this._btnVR) {\r\n            this._btnVR.addEventListener(\"click\", () => {\r\n                if (!this.isInVRMode) {\r\n                    this.enterVR();\r\n                }\r\n            });\r\n        }\r\n\r\n        // Window events\r\n\r\n        const hostWindow = this._scene.getEngine().getHostWindow();\r\n        if (!hostWindow) {\r\n            return;\r\n        }\r\n\r\n        hostWindow.addEventListener(\"resize\", this._onResize);\r\n        document.addEventListener(\"fullscreenchange\", this._onFullscreenChange, false);\r\n\r\n        // Display vr button when headset is connected\r\n        if (webVROptions.createFallbackVRDeviceOrientationFreeCamera) {\r\n            this._displayVRButton();\r\n        }\r\n\r\n        // Exiting VR mode using 'ESC' key on desktop\r\n        this._onKeyDown = (event: KeyboardEvent) => {\r\n            if (event.keyCode === 27 && this.isInVRMode) {\r\n                this.exitVR();\r\n            }\r\n        };\r\n        document.addEventListener(\"keydown\", this._onKeyDown);\r\n\r\n        // Exiting VR mode double tapping the touch screen\r\n        this._scene.onPrePointerObservable.add(\r\n            () => {\r\n                if (this._hasEnteredVR && this.exitVROnDoubleTap) {\r\n                    this.exitVR();\r\n                    if (this._fullscreenVRpresenting) {\r\n                        this._scene.getEngine().exitFullscreen();\r\n                    }\r\n                }\r\n            },\r\n            PointerEventTypes.POINTERDOUBLETAP,\r\n            false\r\n        );\r\n\r\n        scene.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n\r\n        this._updateButtonVisibility();\r\n\r\n        //create easing functions\r\n        this._circleEase = new CircleEase();\r\n        this._circleEase.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);\r\n        this._teleportationEasing = this._circleEase;\r\n\r\n        // Allow clicking in the vrDeviceOrientationCamera\r\n        scene.onPointerObservable.add((e) => {\r\n            if (this._interactionsEnabled) {\r\n                if (scene.activeCamera === this.vrDeviceOrientationCamera && (e.event as IPointerEvent).pointerType === \"mouse\") {\r\n                    if (e.type === PointerEventTypes.POINTERDOWN) {\r\n                        this._cameraGazer._selectionPointerDown();\r\n                    } else if (e.type === PointerEventTypes.POINTERUP) {\r\n                        this._cameraGazer._selectionPointerUp();\r\n                    }\r\n                }\r\n            }\r\n        });\r\n\r\n        if (this.webVROptions.floorMeshes) {\r\n            this.enableTeleportation({ floorMeshes: this.webVROptions.floorMeshes });\r\n        }\r\n    }\r\n\r\n    private _onResize = () => {\r\n        this._moveButtonToBottomRight();\r\n    };\r\n\r\n    private _onFullscreenChange = () => {\r\n        this._fullscreenVRpresenting = !!document.fullscreenElement;\r\n        if (!this._fullscreenVRpresenting && this._inputElement) {\r\n            this.exitVR();\r\n            if (!this._useCustomVRButton && this._btnVR) {\r\n                this._btnVR.style.top = this._inputElement.offsetTop + this._inputElement.offsetHeight - 70 + \"px\";\r\n                this._btnVR.style.left = this._inputElement.offsetLeft + this._inputElement.offsetWidth - 100 + \"px\";\r\n                // make sure the button is visible after setting its position\r\n                this._updateButtonVisibility();\r\n            }\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Gets a value indicating if we are currently in VR mode.\r\n     */\r\n    public get isInVRMode(): boolean {\r\n        return (this.xr && this.webVROptions.useXR && this.xr.baseExperience.state === WebXRState.IN_XR) || this._fullscreenVRpresenting;\r\n    }\r\n\r\n    private _moveButtonToBottomRight() {\r\n        if (this._inputElement && !this._useCustomVRButton && this._btnVR) {\r\n            const rect: ClientRect = this._inputElement.getBoundingClientRect();\r\n            this._btnVR.style.top = rect.top + rect.height - 70 + \"px\";\r\n            this._btnVR.style.left = rect.left + rect.width - 100 + \"px\";\r\n        }\r\n    }\r\n\r\n    private _displayVRButton() {\r\n        if (!this._useCustomVRButton && !this._btnVRDisplayed && this._btnVR) {\r\n            document.body.appendChild(this._btnVR);\r\n            this._btnVRDisplayed = true;\r\n        }\r\n    }\r\n\r\n    private _updateButtonVisibility() {\r\n        if (!this._btnVR || this._useCustomVRButton) {\r\n            return;\r\n        }\r\n        this._btnVR.className = \"babylonVRicon\";\r\n        if (this.isInVRMode) {\r\n            this._btnVR.className += \" vrdisplaypresenting\";\r\n        }\r\n    }\r\n\r\n    private _cachedAngularSensibility = { angularSensibilityX: null, angularSensibilityY: null, angularSensibility: null };\r\n    /**\r\n     * Attempt to enter VR. If a headset is connected and ready, will request present on that.\r\n     * Otherwise, will use the fullscreen API.\r\n     */\r\n    public enterVR() {\r\n        if (this.xr) {\r\n            this.xr.baseExperience.enterXRAsync(\"immersive-vr\", \"local-floor\", this.xr.renderTarget);\r\n            return;\r\n        }\r\n        if (this.onEnteringVRObservable) {\r\n            try {\r\n                this.onEnteringVRObservable.notifyObservers(this);\r\n            } catch (err) {\r\n                Logger.Warn(\"Error in your custom logic onEnteringVR: \" + err);\r\n            }\r\n        }\r\n\r\n        if (this._scene.activeCamera) {\r\n            this._position = this._scene.activeCamera.position.clone();\r\n\r\n            if (this.vrDeviceOrientationCamera) {\r\n                this.vrDeviceOrientationCamera.rotation = Quaternion.FromRotationMatrix(this._scene.activeCamera.getWorldMatrix().getRotationMatrix()).toEulerAngles();\r\n                this.vrDeviceOrientationCamera.angularSensibility = 2000;\r\n            }\r\n\r\n            // make sure that we return to the last active camera\r\n            this._existingCamera = this._scene.activeCamera;\r\n\r\n            // Remove and cache angular sensability to avoid camera rotation when in VR\r\n            if ((<any>this._existingCamera).angularSensibilityX) {\r\n                this._cachedAngularSensibility.angularSensibilityX = (<any>this._existingCamera).angularSensibilityX;\r\n                (<any>this._existingCamera).angularSensibilityX = Number.MAX_VALUE;\r\n            }\r\n            if ((<any>this._existingCamera).angularSensibilityY) {\r\n                this._cachedAngularSensibility.angularSensibilityY = (<any>this._existingCamera).angularSensibilityY;\r\n                (<any>this._existingCamera).angularSensibilityY = Number.MAX_VALUE;\r\n            }\r\n            if ((<any>this._existingCamera).angularSensibility) {\r\n                this._cachedAngularSensibility.angularSensibility = (<any>this._existingCamera).angularSensibility;\r\n                (<any>this._existingCamera).angularSensibility = Number.MAX_VALUE;\r\n            }\r\n        }\r\n\r\n        // If WebVR is supported and a headset is connected\r\n        if (this._vrDeviceOrientationCamera) {\r\n            this._vrDeviceOrientationCamera.position = this._position;\r\n            if (this._scene.activeCamera) {\r\n                this._vrDeviceOrientationCamera.minZ = this._scene.activeCamera.minZ;\r\n            }\r\n            this._scene.activeCamera = this._vrDeviceOrientationCamera;\r\n            this._scene.getEngine().enterFullscreen(this.requestPointerLockOnFullScreen);\r\n            this._updateButtonVisibility();\r\n            this._vrDeviceOrientationCamera.onViewMatrixChangedObservable.addOnce(() => {\r\n                this.onAfterEnteringVRObservable.notifyObservers({ success: true });\r\n            });\r\n        }\r\n\r\n        if (this._scene.activeCamera && this._inputElement) {\r\n            this._scene.activeCamera.attachControl();\r\n        }\r\n\r\n        if (this._interactionsEnabled) {\r\n            this._scene.registerBeforeRender(this._beforeRender);\r\n        }\r\n\r\n        this._hasEnteredVR = true;\r\n    }\r\n\r\n    /**\r\n     * Attempt to exit VR, or fullscreen.\r\n     */\r\n    public exitVR() {\r\n        if (this.xr) {\r\n            this.xr.baseExperience.exitXRAsync();\r\n            return;\r\n        }\r\n        if (this._hasEnteredVR) {\r\n            if (this.onExitingVRObservable) {\r\n                try {\r\n                    this.onExitingVRObservable.notifyObservers(this);\r\n                } catch (err) {\r\n                    Logger.Warn(\"Error in your custom logic onExitingVR: \" + err);\r\n                }\r\n            }\r\n            if (this._scene.activeCamera) {\r\n                this._position = this._scene.activeCamera.position.clone();\r\n            }\r\n\r\n            if (this.vrDeviceOrientationCamera) {\r\n                this.vrDeviceOrientationCamera.angularSensibility = Number.MAX_VALUE;\r\n            }\r\n\r\n            if (this._deviceOrientationCamera) {\r\n                this._deviceOrientationCamera.position = this._position;\r\n                this._scene.activeCamera = this._deviceOrientationCamera;\r\n\r\n                // Restore angular sensibility\r\n                if (this._cachedAngularSensibility.angularSensibilityX) {\r\n                    (<any>this._deviceOrientationCamera).angularSensibilityX = this._cachedAngularSensibility.angularSensibilityX;\r\n                    this._cachedAngularSensibility.angularSensibilityX = null;\r\n                }\r\n                if (this._cachedAngularSensibility.angularSensibilityY) {\r\n                    (<any>this._deviceOrientationCamera).angularSensibilityY = this._cachedAngularSensibility.angularSensibilityY;\r\n                    this._cachedAngularSensibility.angularSensibilityY = null;\r\n                }\r\n                if (this._cachedAngularSensibility.angularSensibility) {\r\n                    (<any>this._deviceOrientationCamera).angularSensibility = this._cachedAngularSensibility.angularSensibility;\r\n                    this._cachedAngularSensibility.angularSensibility = null;\r\n                }\r\n            } else if (this._existingCamera) {\r\n                this._existingCamera.position = this._position;\r\n                this._scene.activeCamera = this._existingCamera;\r\n                if (this._inputElement) {\r\n                    this._scene.activeCamera.attachControl();\r\n                }\r\n\r\n                // Restore angular sensibility\r\n                if (this._cachedAngularSensibility.angularSensibilityX) {\r\n                    (<any>this._existingCamera).angularSensibilityX = this._cachedAngularSensibility.angularSensibilityX;\r\n                    this._cachedAngularSensibility.angularSensibilityX = null;\r\n                }\r\n                if (this._cachedAngularSensibility.angularSensibilityY) {\r\n                    (<any>this._existingCamera).angularSensibilityY = this._cachedAngularSensibility.angularSensibilityY;\r\n                    this._cachedAngularSensibility.angularSensibilityY = null;\r\n                }\r\n                if (this._cachedAngularSensibility.angularSensibility) {\r\n                    (<any>this._existingCamera).angularSensibility = this._cachedAngularSensibility.angularSensibility;\r\n                    this._cachedAngularSensibility.angularSensibility = null;\r\n                }\r\n            }\r\n\r\n            this._updateButtonVisibility();\r\n\r\n            if (this._interactionsEnabled) {\r\n                this._scene.unregisterBeforeRender(this._beforeRender);\r\n                this._cameraGazer._gazeTracker.isVisible = false;\r\n            }\r\n\r\n            // resize to update width and height when exiting vr exits fullscreen\r\n            this._scene.getEngine().resize();\r\n\r\n            this._hasEnteredVR = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The position of the vr experience helper.\r\n     */\r\n    public get position(): Vector3 {\r\n        return this._position;\r\n    }\r\n\r\n    /**\r\n     * Sets the position of the vr experience helper.\r\n     */\r\n    public set position(value: Vector3) {\r\n        this._position = value;\r\n\r\n        if (this._scene.activeCamera) {\r\n            this._scene.activeCamera.position = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables controllers and user interactions such as selecting and object or clicking on an object.\r\n     */\r\n    public enableInteractions() {\r\n        if (!this._interactionsEnabled) {\r\n            // in XR it is enabled by default, but just to make sure, re-attach\r\n            if (this.xr) {\r\n                if (this.xr.baseExperience.state === WebXRState.IN_XR) {\r\n                    this.xr.pointerSelection.attach();\r\n                }\r\n                return;\r\n            }\r\n\r\n            this.raySelectionPredicate = (mesh) => {\r\n                return mesh.isVisible && (mesh.isPickable || mesh.name === this._floorMeshName);\r\n            };\r\n\r\n            this.meshSelectionPredicate = () => {\r\n                return true;\r\n            };\r\n\r\n            this._raySelectionPredicate = (mesh) => {\r\n                if (\r\n                    this._isTeleportationFloor(mesh) ||\r\n                    (mesh.name.indexOf(\"gazeTracker\") === -1 && mesh.name.indexOf(\"teleportationTarget\") === -1 && mesh.name.indexOf(\"torusTeleportation\") === -1)\r\n                ) {\r\n                    return this.raySelectionPredicate(mesh);\r\n                }\r\n                return false;\r\n            };\r\n\r\n            this._interactionsEnabled = true;\r\n        }\r\n    }\r\n\r\n    private _beforeRender = () => {\r\n        if (this._scene.getEngine().isPointerLock || this.enableGazeEvenWhenNoPointerLock) {\r\n            // no-op\r\n        } else {\r\n            this._cameraGazer._gazeTracker.isVisible = false;\r\n        }\r\n    };\r\n\r\n    private _isTeleportationFloor(mesh: AbstractMesh): boolean {\r\n        for (let i = 0; i < this._floorMeshesCollection.length; i++) {\r\n            if (this._floorMeshesCollection[i].id === mesh.id) {\r\n                return true;\r\n            }\r\n        }\r\n        if (this._floorMeshName && mesh.name === this._floorMeshName) {\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds a floor mesh to be used for teleportation.\r\n     * @param floorMesh the mesh to be used for teleportation.\r\n     */\r\n    public addFloorMesh(floorMesh: Mesh): void {\r\n        if (!this._floorMeshesCollection) {\r\n            return;\r\n        }\r\n\r\n        if (this._floorMeshesCollection.indexOf(floorMesh) > -1) {\r\n            return;\r\n        }\r\n\r\n        this._floorMeshesCollection.push(floorMesh);\r\n    }\r\n\r\n    /**\r\n     * Removes a floor mesh from being used for teleportation.\r\n     * @param floorMesh the mesh to be removed.\r\n     */\r\n    public removeFloorMesh(floorMesh: Mesh): void {\r\n        if (!this._floorMeshesCollection) {\r\n            return;\r\n        }\r\n\r\n        const meshIndex = this._floorMeshesCollection.indexOf(floorMesh);\r\n        if (meshIndex !== -1) {\r\n            this._floorMeshesCollection.splice(meshIndex, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables interactions and teleportation using the VR controllers and gaze.\r\n     * @param vrTeleportationOptions options to modify teleportation behavior.\r\n     */\r\n    public enableTeleportation(vrTeleportationOptions: VRTeleportationOptions = {}) {\r\n        if (!this._teleportationInitialized) {\r\n            this.enableInteractions();\r\n\r\n            if (this.webVROptions.useXR && (vrTeleportationOptions.floorMeshes || vrTeleportationOptions.floorMeshName)) {\r\n                const floorMeshes: AbstractMesh[] = vrTeleportationOptions.floorMeshes || [];\r\n                if (!floorMeshes.length) {\r\n                    const floorMesh = this._scene.getMeshByName(vrTeleportationOptions.floorMeshName!);\r\n                    if (floorMesh) {\r\n                        floorMeshes.push(floorMesh);\r\n                    }\r\n                }\r\n                if (this.xr) {\r\n                    for (const mesh of floorMeshes) {\r\n                        this.xr.teleportation.addFloorMesh(mesh);\r\n                    }\r\n                    if (!this.xr.teleportation.attached) {\r\n                        this.xr.teleportation.attach();\r\n                    }\r\n                    return;\r\n                } else if (!this.xrTestDone) {\r\n                    const waitForXr = () => {\r\n                        if (this.xrTestDone) {\r\n                            this._scene.unregisterBeforeRender(waitForXr);\r\n                            if (this.xr) {\r\n                                if (!this.xr.teleportation.attached) {\r\n                                    this.xr.teleportation.attach();\r\n                                }\r\n                            } else {\r\n                                this.enableTeleportation(vrTeleportationOptions);\r\n                            }\r\n                        }\r\n                    };\r\n                    this._scene.registerBeforeRender(waitForXr);\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (vrTeleportationOptions.floorMeshName) {\r\n                this._floorMeshName = vrTeleportationOptions.floorMeshName;\r\n            }\r\n            if (vrTeleportationOptions.floorMeshes) {\r\n                this._floorMeshesCollection = vrTeleportationOptions.floorMeshes;\r\n            }\r\n\r\n            if (vrTeleportationOptions.teleportationMode) {\r\n                this._teleportationMode = vrTeleportationOptions.teleportationMode;\r\n            }\r\n            if (vrTeleportationOptions.teleportationTime && vrTeleportationOptions.teleportationTime > 0) {\r\n                this._teleportationTime = vrTeleportationOptions.teleportationTime;\r\n            }\r\n            if (vrTeleportationOptions.teleportationSpeed && vrTeleportationOptions.teleportationSpeed > 0) {\r\n                this._teleportationSpeed = vrTeleportationOptions.teleportationSpeed;\r\n            }\r\n            if (vrTeleportationOptions.easingFunction !== undefined) {\r\n                this._teleportationEasing = vrTeleportationOptions.easingFunction;\r\n            }\r\n\r\n            // Creates an image processing post process for the vignette not relying\r\n            // on the main scene configuration for image processing to reduce setup and spaces\r\n            // (gamma/linear) conflicts.\r\n            const imageProcessingConfiguration = new ImageProcessingConfiguration();\r\n            imageProcessingConfiguration.vignetteColor = new Color4(0, 0, 0, 0);\r\n            imageProcessingConfiguration.vignetteEnabled = true;\r\n            this._teleportationInitialized = true;\r\n            if (this._isDefaultTeleportationTarget) {\r\n                this._createTeleportationCircles();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onNewGamepadConnected = (gamepad: Gamepad) => {\r\n        if (gamepad.type !== Gamepad.POSE_ENABLED) {\r\n            if (gamepad.leftStick) {\r\n                gamepad.onleftstickchanged((stickValues) => {\r\n                    if (this._teleportationInitialized && this.teleportationEnabled) {\r\n                        // Listening to classic/xbox gamepad only if no VR controller is active\r\n                        this._checkTeleportWithRay(stickValues, this._cameraGazer);\r\n                        this._checkTeleportBackwards(stickValues, this._cameraGazer);\r\n                    }\r\n                });\r\n            }\r\n            if (gamepad.rightStick) {\r\n                gamepad.onrightstickchanged((stickValues) => {\r\n                    if (this._teleportationInitialized) {\r\n                        this._checkRotate(stickValues, this._cameraGazer);\r\n                    }\r\n                });\r\n            }\r\n            if (gamepad.type === Gamepad.XBOX) {\r\n                (<Xbox360Pad>gamepad).onbuttondown((buttonPressed: Xbox360Button) => {\r\n                    if (this._interactionsEnabled && buttonPressed === Xbox360Button.A) {\r\n                        this._cameraGazer._selectionPointerDown();\r\n                    }\r\n                });\r\n                (<Xbox360Pad>gamepad).onbuttonup((buttonPressed: Xbox360Button) => {\r\n                    if (this._interactionsEnabled && buttonPressed === Xbox360Button.A) {\r\n                        this._cameraGazer._selectionPointerUp();\r\n                    }\r\n                });\r\n            }\r\n        }\r\n    };\r\n\r\n    private _checkTeleportWithRay(stateObject: StickValues, gazer: VRExperienceHelperGazer) {\r\n        // Dont teleport if another gaze already requested teleportation\r\n        if (this._teleportationRequestInitiated && !gazer._teleportationRequestInitiated) {\r\n            return;\r\n        }\r\n        if (!gazer._teleportationRequestInitiated) {\r\n            if (stateObject.y < -this._padSensibilityUp && gazer._dpadPressed) {\r\n                gazer._activatePointer();\r\n                gazer._teleportationRequestInitiated = true;\r\n            }\r\n        } else {\r\n            // Listening to the proper controller values changes to confirm teleportation\r\n            if (Math.sqrt(stateObject.y * stateObject.y + stateObject.x * stateObject.x) < this._padSensibilityDown) {\r\n                if (this._teleportActive) {\r\n                    this.teleportCamera(this._haloCenter);\r\n                }\r\n\r\n                gazer._teleportationRequestInitiated = false;\r\n            }\r\n        }\r\n    }\r\n    private _checkRotate(stateObject: StickValues, gazer: VRExperienceHelperGazer) {\r\n        // Only rotate when user is not currently selecting a teleportation location\r\n        if (gazer._teleportationRequestInitiated) {\r\n            return;\r\n        }\r\n\r\n        if (!gazer._rotationLeftAsked) {\r\n            if (stateObject.x < -this._padSensibilityUp && gazer._dpadPressed) {\r\n                gazer._rotationLeftAsked = true;\r\n                if (this._rotationAllowed) {\r\n                    this._rotateCamera(false);\r\n                }\r\n            }\r\n        } else {\r\n            if (stateObject.x > -this._padSensibilityDown) {\r\n                gazer._rotationLeftAsked = false;\r\n            }\r\n        }\r\n\r\n        if (!gazer._rotationRightAsked) {\r\n            if (stateObject.x > this._padSensibilityUp && gazer._dpadPressed) {\r\n                gazer._rotationRightAsked = true;\r\n                if (this._rotationAllowed) {\r\n                    this._rotateCamera(true);\r\n                }\r\n            }\r\n        } else {\r\n            if (stateObject.x < this._padSensibilityDown) {\r\n                gazer._rotationRightAsked = false;\r\n            }\r\n        }\r\n    }\r\n    private _checkTeleportBackwards(stateObject: StickValues, gazer: VRExperienceHelperGazer) {\r\n        // Only teleport backwards when user is not currently selecting a teleportation location\r\n        if (gazer._teleportationRequestInitiated) {\r\n            return;\r\n        }\r\n        // Teleport backwards\r\n        if (stateObject.y > this._padSensibilityUp && gazer._dpadPressed) {\r\n            if (!gazer._teleportationBackRequestInitiated) {\r\n                if (!this.currentVRCamera) {\r\n                    return;\r\n                }\r\n\r\n                // Get rotation and position of the current camera\r\n                const rotation = Quaternion.FromRotationMatrix(this.currentVRCamera.getWorldMatrix().getRotationMatrix());\r\n                const position = this.currentVRCamera.position;\r\n\r\n                // Get matrix with only the y rotation of the device rotation\r\n                rotation.toEulerAnglesToRef(this._workingVector);\r\n                this._workingVector.z = 0;\r\n                this._workingVector.x = 0;\r\n                Quaternion.RotationYawPitchRollToRef(this._workingVector.y, this._workingVector.x, this._workingVector.z, this._workingQuaternion);\r\n                this._workingQuaternion.toRotationMatrix(this._workingMatrix);\r\n\r\n                // Rotate backwards ray by device rotation to cast at the ground behind the user\r\n                Vector3.TransformCoordinatesToRef(this._teleportBackwardsVector, this._workingMatrix, this._workingVector);\r\n\r\n                // Teleport if ray hit the ground and is not to far away eg. backwards off a cliff\r\n                const ray = new Ray(position, this._workingVector);\r\n                const hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);\r\n                if (hit && hit.pickedPoint && hit.pickedMesh && this._isTeleportationFloor(hit.pickedMesh) && hit.distance < 5) {\r\n                    this.teleportCamera(hit.pickedPoint);\r\n                }\r\n\r\n                gazer._teleportationBackRequestInitiated = true;\r\n            }\r\n        } else {\r\n            gazer._teleportationBackRequestInitiated = false;\r\n        }\r\n    }\r\n\r\n    private _createTeleportationCircles() {\r\n        this._teleportationTarget = CreateGround(\"teleportationTarget\", { width: 2, height: 2, subdivisions: 2 }, this._scene);\r\n        this._teleportationTarget.isPickable = false;\r\n\r\n        const length = 512;\r\n        const dynamicTexture = new DynamicTexture(\"DynamicTexture\", length, this._scene, true);\r\n        dynamicTexture.hasAlpha = true;\r\n        const context = dynamicTexture.getContext();\r\n\r\n        const centerX = length / 2;\r\n        const centerY = length / 2;\r\n        const radius = 200;\r\n\r\n        context.beginPath();\r\n        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);\r\n        context.fillStyle = this._teleportationFillColor;\r\n        context.fill();\r\n        context.lineWidth = 10;\r\n        context.strokeStyle = this._teleportationBorderColor;\r\n        context.stroke();\r\n        context.closePath();\r\n        dynamicTexture.update();\r\n\r\n        const teleportationCircleMaterial = new StandardMaterial(\"TextPlaneMaterial\", this._scene);\r\n        teleportationCircleMaterial.diffuseTexture = dynamicTexture;\r\n        this._teleportationTarget.material = teleportationCircleMaterial;\r\n\r\n        const torus = CreateTorus(\r\n            \"torusTeleportation\",\r\n            {\r\n                diameter: 0.75,\r\n                thickness: 0.1,\r\n                tessellation: 25,\r\n                updatable: false,\r\n            },\r\n            this._scene\r\n        );\r\n        torus.isPickable = false;\r\n        torus.parent = this._teleportationTarget;\r\n\r\n        const animationInnerCircle = new Animation(\"animationInnerCircle\", \"position.y\", 30, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE);\r\n\r\n        const keys = [];\r\n        keys.push({\r\n            frame: 0,\r\n            value: 0,\r\n        });\r\n        keys.push({\r\n            frame: 30,\r\n            value: 0.4,\r\n        });\r\n        keys.push({\r\n            frame: 60,\r\n            value: 0,\r\n        });\r\n\r\n        animationInnerCircle.setKeys(keys);\r\n\r\n        const easingFunction = new SineEase();\r\n        easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);\r\n        animationInnerCircle.setEasingFunction(easingFunction);\r\n\r\n        torus.animations = [];\r\n        torus.animations.push(animationInnerCircle);\r\n\r\n        this._scene.beginAnimation(torus, 0, 60, true);\r\n\r\n        this._hideTeleportationTarget();\r\n    }\r\n\r\n    private _hideTeleportationTarget() {\r\n        this._teleportActive = false;\r\n        if (this._teleportationInitialized) {\r\n            this._teleportationTarget.isVisible = false;\r\n            if (this._isDefaultTeleportationTarget) {\r\n                (<Mesh>this._teleportationTarget.getChildren()[0]).isVisible = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _rotateCamera(right: boolean) {\r\n        if (!(this.currentVRCamera instanceof FreeCamera)) {\r\n            return;\r\n        }\r\n\r\n        if (right) {\r\n            this._rotationAngle++;\r\n        } else {\r\n            this._rotationAngle--;\r\n        }\r\n\r\n        this.currentVRCamera.animations = [];\r\n\r\n        const target = Quaternion.FromRotationMatrix(Matrix.RotationY((Math.PI / 4) * this._rotationAngle));\r\n\r\n        const animationRotation = new Animation(\"animationRotation\", \"rotationQuaternion\", 90, Animation.ANIMATIONTYPE_QUATERNION, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        const animationRotationKeys = [];\r\n        animationRotationKeys.push({\r\n            frame: 0,\r\n            value: this.currentVRCamera.rotationQuaternion,\r\n        });\r\n        animationRotationKeys.push({\r\n            frame: 6,\r\n            value: target,\r\n        });\r\n\r\n        animationRotation.setKeys(animationRotationKeys);\r\n\r\n        animationRotation.setEasingFunction(this._circleEase);\r\n\r\n        this.currentVRCamera.animations.push(animationRotation);\r\n\r\n        this._postProcessMove.animations = [];\r\n\r\n        const animationPp = new Animation(\"animationPP\", \"vignetteWeight\", 90, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        const vignetteWeightKeys = [];\r\n        vignetteWeightKeys.push({\r\n            frame: 0,\r\n            value: 0,\r\n        });\r\n        vignetteWeightKeys.push({\r\n            frame: 3,\r\n            value: 4,\r\n        });\r\n        vignetteWeightKeys.push({\r\n            frame: 6,\r\n            value: 0,\r\n        });\r\n\r\n        animationPp.setKeys(vignetteWeightKeys);\r\n        animationPp.setEasingFunction(this._circleEase);\r\n        this._postProcessMove.animations.push(animationPp);\r\n\r\n        const animationPp2 = new Animation(\"animationPP2\", \"vignetteStretch\", 90, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        const vignetteStretchKeys = [];\r\n        vignetteStretchKeys.push({\r\n            frame: 0,\r\n            value: 0,\r\n        });\r\n        vignetteStretchKeys.push({\r\n            frame: 3,\r\n            value: 10,\r\n        });\r\n        vignetteStretchKeys.push({\r\n            frame: 6,\r\n            value: 0,\r\n        });\r\n\r\n        animationPp2.setKeys(vignetteStretchKeys);\r\n        animationPp2.setEasingFunction(this._circleEase);\r\n        this._postProcessMove.animations.push(animationPp2);\r\n\r\n        this._postProcessMove.imageProcessingConfiguration.vignetteWeight = 0;\r\n        this._postProcessMove.imageProcessingConfiguration.vignetteStretch = 0;\r\n        this._postProcessMove.samples = 4;\r\n        this._scene.beginAnimation(this.currentVRCamera, 0, 6, false, 1);\r\n    }\r\n\r\n    private _workingVector = Vector3.Zero();\r\n    private _workingQuaternion = Quaternion.Identity();\r\n    private _workingMatrix = Matrix.Identity();\r\n\r\n    /**\r\n     * Time Constant Teleportation Mode\r\n     */\r\n    public static readonly TELEPORTATIONMODE_CONSTANTTIME = 0;\r\n    /**\r\n     * Speed Constant Teleportation Mode\r\n     */\r\n    public static readonly TELEPORTATIONMODE_CONSTANTSPEED = 1;\r\n\r\n    /**\r\n     * Teleports the users feet to the desired location\r\n     * @param location The location where the user's feet should be placed\r\n     */\r\n    public teleportCamera(location: Vector3) {\r\n        if (!(this.currentVRCamera instanceof FreeCamera)) {\r\n            return;\r\n        }\r\n        // Teleport the hmd to where the user is looking by moving the anchor to where they are looking minus the\r\n        // offset of the headset from the anchor.\r\n\r\n        this._workingVector.copyFrom(location);\r\n        // Add height to account for user's height offset\r\n        if (this.isInVRMode) {\r\n            // no-op\r\n        } else {\r\n            this._workingVector.y += this._defaultHeight;\r\n        }\r\n\r\n        this.onBeforeCameraTeleport.notifyObservers(this._workingVector);\r\n\r\n        // Animations FPS\r\n        const fps = 90;\r\n        let speedRatio, lastFrame;\r\n        if (this._teleportationMode == VRExperienceHelper.TELEPORTATIONMODE_CONSTANTSPEED) {\r\n            lastFrame = fps;\r\n            const dist = Vector3.Distance(this.currentVRCamera.position, this._workingVector);\r\n            speedRatio = this._teleportationSpeed / dist;\r\n        } else {\r\n            // teleportationMode is TELEPORTATIONMODE_CONSTANTTIME\r\n            lastFrame = Math.round((this._teleportationTime * fps) / 1000);\r\n            speedRatio = 1;\r\n        }\r\n\r\n        // Create animation from the camera's position to the new location\r\n        this.currentVRCamera.animations = [];\r\n        const animationCameraTeleportation = new Animation(\"animationCameraTeleportation\", \"position\", fps, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n        const animationCameraTeleportationKeys = [\r\n            {\r\n                frame: 0,\r\n                value: this.currentVRCamera.position,\r\n            },\r\n            {\r\n                frame: lastFrame,\r\n                value: this._workingVector,\r\n            },\r\n        ];\r\n\r\n        animationCameraTeleportation.setKeys(animationCameraTeleportationKeys);\r\n        animationCameraTeleportation.setEasingFunction(this._teleportationEasing);\r\n        this.currentVRCamera.animations.push(animationCameraTeleportation);\r\n\r\n        this._postProcessMove.animations = [];\r\n\r\n        // Calculate the mid frame for vignette animations\r\n        const midFrame = Math.round(lastFrame / 2);\r\n\r\n        const animationPp = new Animation(\"animationPP\", \"vignetteWeight\", fps, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        const vignetteWeightKeys = [];\r\n        vignetteWeightKeys.push({\r\n            frame: 0,\r\n            value: 0,\r\n        });\r\n        vignetteWeightKeys.push({\r\n            frame: midFrame,\r\n            value: 8,\r\n        });\r\n        vignetteWeightKeys.push({\r\n            frame: lastFrame,\r\n            value: 0,\r\n        });\r\n\r\n        animationPp.setKeys(vignetteWeightKeys);\r\n        this._postProcessMove.animations.push(animationPp);\r\n\r\n        const animationPp2 = new Animation(\"animationPP2\", \"vignetteStretch\", fps, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        const vignetteStretchKeys = [];\r\n        vignetteStretchKeys.push({\r\n            frame: 0,\r\n            value: 0,\r\n        });\r\n        vignetteStretchKeys.push({\r\n            frame: midFrame,\r\n            value: 10,\r\n        });\r\n        vignetteStretchKeys.push({\r\n            frame: lastFrame,\r\n            value: 0,\r\n        });\r\n\r\n        animationPp2.setKeys(vignetteStretchKeys);\r\n        this._postProcessMove.animations.push(animationPp2);\r\n\r\n        this._postProcessMove.imageProcessingConfiguration.vignetteWeight = 0;\r\n        this._postProcessMove.imageProcessingConfiguration.vignetteStretch = 0;\r\n\r\n        this._scene.beginAnimation(this.currentVRCamera, 0, lastFrame, false, speedRatio, () => {\r\n            this.onAfterCameraTeleport.notifyObservers(this._workingVector);\r\n        });\r\n\r\n        this._hideTeleportationTarget();\r\n    }\r\n\r\n    /**\r\n     * Permanently set new colors for the laser pointer\r\n     * @param color the new laser color\r\n     * @param pickedColor the new laser color when picked mesh detected\r\n     */\r\n    public setLaserColor(color: Color3, pickedColor: Color3 = this._pickedLaserColor) {\r\n        this._pickedLaserColor = pickedColor;\r\n    }\r\n\r\n    /**\r\n     * Set lighting enabled / disabled on the laser pointer of both controllers\r\n     * @param _enabled should the lighting be enabled on the laser pointer\r\n     */\r\n    public setLaserLightingState(_enabled: boolean = true) {\r\n        // no-op\r\n    }\r\n\r\n    /**\r\n     * Permanently set new colors for the gaze pointer\r\n     * @param color the new gaze color\r\n     * @param pickedColor the new gaze color when picked mesh detected\r\n     */\r\n    public setGazeColor(color: Color3, pickedColor: Color3 = this._pickedGazeColor) {\r\n        this._pickedGazeColor = pickedColor;\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the laser ray from the vr controllers.\r\n     * @param _color new color for the ray.\r\n     */\r\n    public changeLaserColor(_color: Color3) {\r\n        if (!this.updateControllerLaserColor) {\r\n            return;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the ray from the vr headsets gaze.\r\n     * @param color new color for the ray.\r\n     */\r\n    public changeGazeColor(color: Color3) {\r\n        if (!this.updateGazeTrackerColor) {\r\n            return;\r\n        }\r\n        if (!(<StandardMaterial>this._cameraGazer._gazeTracker.material)) {\r\n            return;\r\n        }\r\n        (<StandardMaterial>this._cameraGazer._gazeTracker.material).emissiveColor = color;\r\n    }\r\n\r\n    /**\r\n     * Exits VR and disposes of the vr experience helper\r\n     */\r\n    public dispose() {\r\n        if (this.isInVRMode) {\r\n            this.exitVR();\r\n        }\r\n\r\n        if (this._postProcessMove) {\r\n            this._postProcessMove.dispose();\r\n        }\r\n\r\n        if (this._vrDeviceOrientationCamera) {\r\n            this._vrDeviceOrientationCamera.dispose();\r\n        }\r\n        if (!this._useCustomVRButton && this._btnVR && this._btnVR.parentNode) {\r\n            document.body.removeChild(this._btnVR);\r\n        }\r\n\r\n        if (this._deviceOrientationCamera && this._scene.activeCamera != this._deviceOrientationCamera) {\r\n            this._deviceOrientationCamera.dispose();\r\n        }\r\n\r\n        if (this._cameraGazer) {\r\n            this._cameraGazer.dispose();\r\n        }\r\n\r\n        if (this._teleportationTarget) {\r\n            this._teleportationTarget.dispose();\r\n        }\r\n\r\n        if (this.xr) {\r\n            this.xr.dispose();\r\n        }\r\n\r\n        this._floorMeshesCollection.length = 0;\r\n\r\n        document.removeEventListener(\"keydown\", this._onKeyDown);\r\n        window.removeEventListener(\"vrdisplaypresentchange\", this._onVrDisplayPresentChangeBind);\r\n\r\n        window.removeEventListener(\"resize\", this._onResize);\r\n        document.removeEventListener(\"fullscreenchange\", this._onFullscreenChange);\r\n\r\n        this._scene.gamepadManager.onGamepadConnectedObservable.removeCallback(this._onNewGamepadConnected);\r\n\r\n        this._scene.unregisterBeforeRender(this._beforeRender);\r\n    }\r\n\r\n    /**\r\n     * Gets the name of the VRExperienceHelper class\r\n     * @returns \"VRExperienceHelper\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"VRExperienceHelper\";\r\n    }\r\n}\r\n","import { CameraInputsManager } from \"./cameraInputsManager\";\r\nimport { type GeospatialCamera } from \"./geospatialCamera\";\r\nimport { GeospatialCameraPointersInput } from \"./Inputs/geospatialCameraPointersInput\";\r\nimport { GeospatialCameraMouseWheelInput } from \"./Inputs/geospatialCameraMouseWheelInput\";\r\nimport { GeospatialCameraKeyboardInput } from \"./Inputs/geospatialCameraKeyboardInput\";\r\n\r\n/**\r\n * Default Inputs manager for the GeospatialCamera.\r\n * It groups all the default supported inputs for ease of use.\r\n */\r\nexport class GeospatialCameraInputsManager extends CameraInputsManager<GeospatialCamera> {\r\n    /**\r\n     * Instantiates a new GeospatialCameraInputsManager.\r\n     * @param camera Defines the camera the inputs belong to\r\n     */\r\n    constructor(camera: GeospatialCamera) {\r\n        super(camera);\r\n    }\r\n\r\n    /**\r\n     * Add mouse input support to the input manager\r\n     * @returns the current input manager\r\n     */\r\n    public addMouse(): GeospatialCameraInputsManager {\r\n        this.add(new GeospatialCameraPointersInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add mouse wheel input support to the input manager\r\n     * @returns the current input manager\r\n     */\r\n    public addMouseWheel(): GeospatialCameraInputsManager {\r\n        this.add(new GeospatialCameraMouseWheelInput());\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add mouse wheel input support to the input manager\r\n     * @returns the current input manager\r\n     */\r\n    public addKeyboard(): GeospatialCameraInputsManager {\r\n        this.add(new GeospatialCameraKeyboardInput());\r\n        return this;\r\n    }\r\n}\r\n","import { Epsilon } from \"../../Maths/math.constants\";\r\nimport { Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { Clamp } from \"../../Maths/math.scalar.functions\";\r\n/**\r\n * Limits for geospatial camera\r\n */\r\nexport class GeospatialLimits {\r\n    private _planetRadius: number;\r\n    private _radiusMin: number = 10;\r\n    private _radiusMax: number = Infinity;\r\n\r\n    /** Gets the minimum pitch angle (angle from horizon) -- 0 means looking straight down at planet */\r\n    public pitchMin: number = Epsilon;\r\n\r\n    /**  Gets the maximum pitch angle (angle from horizon) -- Pi/2 means looking at horizon */\r\n    public pitchMax: number = Math.PI / 2 - 0.01;\r\n\r\n    /**\r\n     * Controls how pitch is disabled as the camera zooms out.\r\n     * x = radius scale at which full pitch is allowed (e.g., 1.5 means 1.5 * planetRadius)\r\n     * y = radius scale at which pitch is fully disabled (forced to pitchMin)\r\n     * Set to undefined to disable this feature.\r\n     */\r\n    public pitchDisabledRadiusScale?: Vector2 = new Vector2(2, 4);\r\n\r\n    /** Gets the minimum yaw angle (rotation around up axis) */\r\n    public yawMin: number = -Infinity;\r\n\r\n    /** Gets the maximum yaw angle (rotation around up axis) */\r\n    public yawMax: number = Infinity;\r\n\r\n    /**\r\n     * @param planetRadius The radius of the planet\r\n     */\r\n    constructor(planetRadius: number) {\r\n        this._planetRadius = planetRadius;\r\n        this.radiusMax = planetRadius * 4;\r\n    }\r\n\r\n    public get radiusMin(): number {\r\n        return this._radiusMin;\r\n    }\r\n\r\n    /**\r\n     * Sets the minimum radius\r\n     */\r\n    public set radiusMin(value: number) {\r\n        this._radiusMin = value;\r\n    }\r\n\r\n    public get radiusMax(): number {\r\n        return this._radiusMax;\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum radius\r\n     */\r\n    public set radiusMax(value: number) {\r\n        this._radiusMax = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the planet radius used for altitude/radius conversions\r\n     */\r\n    public get planetRadius(): number {\r\n        return this._planetRadius;\r\n    }\r\n\r\n    /** Sets the planet radius and updates the radius limits to maintain current altitude */\r\n    public set planetRadius(value: number) {\r\n        this._planetRadius = value;\r\n    }\r\n\r\n    /**\r\n     * Clamps a zoom distance to respect the radius limits.\r\n     * @param zoomDistance The requested zoom distance (positive = zoom in, negative = zoom out)\r\n     * @param currentRadius The current camera radius\r\n     * @param distanceToTarget Optional distance to the zoom target point (used for zoom-in clamping)\r\n     * @returns The clamped zoom distance\r\n     */\r\n    public clampZoomDistance(zoomDistance: number, currentRadius: number, distanceToTarget?: number): number {\r\n        if (zoomDistance > 0) {\r\n            // Zooming IN - don't zoom past the surface or below radiusMin\r\n            const maxZoomIn = (distanceToTarget ?? currentRadius) - this._radiusMin;\r\n            return Math.min(zoomDistance, Math.max(0, maxZoomIn));\r\n        } else {\r\n            // Zooming OUT - don't exceed radiusMax\r\n            const maxZoomOut = this._radiusMax - currentRadius;\r\n            return Math.max(zoomDistance, -Math.max(0, maxZoomOut));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Computes the effective maximum pitch based on the current camera radius.\r\n     * When pitchDisabledRadiusScale is set, pitch is interpolated from pitchMax to pitchMin\r\n     * as the camera zooms out from x*planetRadius to y*planetRadius.\r\n     * @param currentRadius The current camera radius\r\n     * @returns The effective maximum pitch angle\r\n     */\r\n    public getEffectivePitchMax(currentRadius: number): number {\r\n        if (!this.pitchDisabledRadiusScale) {\r\n            return this.pitchMax;\r\n        }\r\n\r\n        const fullPitchRadius = this.pitchDisabledRadiusScale.x * this._planetRadius;\r\n        const noPitchRadius = this.pitchDisabledRadiusScale.y * this._planetRadius;\r\n\r\n        if (currentRadius <= fullPitchRadius) {\r\n            // Full pitch allowed\r\n            return this.pitchMax;\r\n        } else if (currentRadius >= noPitchRadius) {\r\n            // No pitch allowed\r\n            return this.pitchMin;\r\n        } else {\r\n            // Interpolate between pitchMax and pitchMin\r\n            const t = (currentRadius - fullPitchRadius) / (noPitchRadius - fullPitchRadius);\r\n            const clampedT = Clamp(t, 0, 1);\r\n            return this.pitchMax * (1 - clampedT) + this.pitchMin * clampedT;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { CameraMovement } from \"./cameraMovement\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { type GeospatialLimits } from \"./Limits/geospatialLimits\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type MeshPredicate, Pick, PickWithRay, Ray } from \"../Culling/ray.core\";\r\nimport { Plane } from \"../Maths/math.plane\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Vector3Distance } from \"../Maths/math.vector.functions\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { type PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport { type GeospatialCamera } from \"./geospatialCamera.pure\";\r\nimport { type InputMapEntry, InputMapper } from \"./inputMapper\";\r\n\r\n// ── Geospatial handler types ────────────────────────────────────────\r\n\r\n/**\r\n * Handler for geospatial pan (globe drag) interactions.\r\n * Pan uses screen coordinates and needs a lifecycle (start/update/stop) because\r\n * it establishes a drag plane on the globe surface to anchor the cursor.\r\n */\r\nexport type GeospatialPanHandler = {\r\n    /** Begin a pan gesture at screen position */\r\n    start(screenX: number, screenY: number): void;\r\n    /** Continue panning to new screen position */\r\n    update(screenX: number, screenY: number): void;\r\n    /** End the pan gesture */\r\n    stop(): void;\r\n};\r\n\r\n/**\r\n * Handler shape for geospatial camera interactions.\r\n * Property names are the canonical interaction type strings used in inputMap entries.\r\n * Single-method handlers are plain functions; multi-method handlers (pan) are objects.\r\n */\r\nexport type GeospatialHandlers = {\r\n    /** Handler for pan (globe drag) interactions — object because it needs start/update/stop lifecycle */\r\n    pan: GeospatialPanHandler;\r\n    /** Handler for rotate (tilt) interactions — accepts yaw (horizontal) and pitch (vertical) deltas */\r\n    rotate: (yaw: number, pitch: number) => void;\r\n    /** Handler for zoom interactions — accepts delta and whether to zoom toward cursor */\r\n    zoom: (delta: number, toCursor: boolean) => void;\r\n};\r\n\r\n/** Interaction type string for geospatial camera, derived from handler property names */\r\nexport type GeospatialInteraction = keyof GeospatialHandlers;\r\n\r\n/**\r\n * Geospatial-specific camera movement system that extends the base movement with\r\n * raycasting and altitude-aware zoom constraints.\r\n *\r\n * This class encapsulates geospatial camera movement logic:\r\n * - Dragging in a way which keeps cursor anchored to globe\r\n * - Latitude-based pan speed dampening\r\n * - Zoom speed scaling based on distance to center\r\n * - Raycasting to determine zoom constraints based on terrain/globe\r\n * - Altitude-based zoom clamping\r\n * - Zoom direction calculation (towards cursor vs along look vector)\r\n */\r\nexport class GeospatialCameraMovement extends CameraMovement {\r\n    /** Predicate function to determine which meshes to pick against (e.g., globe mesh) */\r\n    public pickPredicate?: MeshPredicate;\r\n\r\n    /**\r\n     * World-space picked point under the cursor, computed each frame that zoom input is active.\r\n     * Used to determine the zoom direction when `zoomToCursor` is true.\r\n     * Undefined when there is no active zoom or the pick misses the globe.\r\n     */\r\n    public computedPerFrameZoomPickPoint?: Vector3;\r\n\r\n    /**\r\n     * When true, zooming moves toward the point under the cursor.\r\n     * When false, zooming moves along the camera's look vector.\r\n     */\r\n    public zoomToCursor: boolean = true;\r\n\r\n    /** Input system that maps physical inputs to interactions and dispatches to handlers. */\r\n    public readonly input: InputMapper<GeospatialHandlers>;\r\n\r\n    private _tempPickingRay: Ray;\r\n\r\n    private _hitPointRadius?: number = undefined;\r\n    private _dragPlane: Plane = new Plane(0, 0, 0, 0);\r\n    private _dragPlaneNormal: Vector3 = Vector3.Zero();\r\n    private _dragPlaneOriginPointEcef: Vector3 = Vector3.Zero();\r\n    private _dragPlaneHitPointLocal: Vector3 = Vector3.Zero();\r\n    private _previousDragPlaneHitPointLocal: Vector3 = Vector3.Zero();\r\n\r\n    constructor(\r\n        scene: Scene,\r\n        /** Geospatial bounds (min/max latitude, longitude, altitude, etc.) used to clamp camera motion. */\r\n        public limits: GeospatialLimits,\r\n        cameraPosition: Vector3,\r\n        private _cameraCenter: Vector3,\r\n        private _cameraLookAt: Vector3,\r\n        pickPredicate?: MeshPredicate,\r\n        behavior?: InterpolatingBehavior<GeospatialCamera>\r\n    ) {\r\n        super(scene, cameraPosition, behavior);\r\n        this.pickPredicate = pickPredicate;\r\n        this._tempPickingRay = Ray.Zero();\r\n        this.panInertia = 0;\r\n        this.rotationInertia = 0;\r\n        this.rotationXSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel\r\n        this.rotationYSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel\r\n        this.zoomSpeed = 2; // Base zoom speed; actual speed is scaled based on altitude\r\n\r\n        this.input = new InputMapper<GeospatialHandlers>(\r\n            {\r\n                pan: {\r\n                    start: (screenX: number, screenY: number) => {\r\n                        this.startDrag(screenX, screenY);\r\n                    },\r\n                    update: (screenX: number, screenY: number) => {\r\n                        this.handleDrag(screenX, screenY);\r\n                    },\r\n                    stop: () => {\r\n                        this.stopDrag();\r\n                    },\r\n                },\r\n                rotate: (yaw: number, pitch: number) => {\r\n                    this.rotationAccumulatedPixels.y += yaw;\r\n                    this.rotationAccumulatedPixels.x += pitch;\r\n                },\r\n                zoom: (delta: number, toCursor: boolean) => {\r\n                    this.handleZoom(delta, toCursor);\r\n                },\r\n            },\r\n            () => this._createDefaultInputMap()\r\n        );\r\n    }\r\n\r\n    private _createDefaultInputMap(): InputMapEntry<GeospatialInteraction>[] {\r\n        return [\r\n            { source: \"pointer\", button: 0, interaction: \"pan\" },\r\n            { source: \"pointer\", button: 1, interaction: \"rotate\" },\r\n            { source: \"pointer\", button: 2, interaction: \"rotate\" },\r\n            { source: \"wheel\", interaction: \"zoom\" },\r\n            { source: \"keyboard\", key: [187, 107, 189, 109], interaction: \"zoom\", sensitivity: 1.0 }, // +/-/numpad+/numpad-\r\n            { source: \"keyboard\", modifiers: { ctrl: true }, interaction: \"rotate\", sensitivity: 1.0 },\r\n            { source: \"keyboard\", modifiers: { alt: true }, interaction: \"rotate\", sensitivity: 1.0 },\r\n            { source: \"keyboard\", interaction: \"pan\", sensitivity: 1.0 },\r\n        ];\r\n    }\r\n\r\n    /**\r\n     * Function to calculate the up vector from a given point.\r\n     * Can be overridden to support non-spherical planets or custom up vector logic.\r\n     * Defaults to using the geocentric normal.\r\n     * @param point The point from which to calculate the up vector (e.g., camera position)\r\n     * @param result The vector to store the calculated up vector\r\n     * @returns The calculated up vector\r\n     */\r\n    public calculateUpVectorFromPointToRef = (point: Vector3, result: Vector3): Vector3 => {\r\n        return point.normalizeToRef(result);\r\n    };\r\n\r\n    /**\r\n     * Begins a drag (pan) gesture by picking the globe at the given screen position\r\n     * and establishing a drag plane for subsequent updates.\r\n     * @param pointerX - Screen X coordinate of the pointer\r\n     * @param pointerY - Screen Y coordinate of the pointer\r\n     */\r\n    public startDrag(pointerX: number, pointerY: number) {\r\n        const pickResult = this._scene.pick(pointerX, pointerY, this.pickPredicate);\r\n        if (pickResult.pickedPoint && pickResult.ray) {\r\n            // Store radius from earth center to pickedPoint, used when calculating drag plane\r\n            this._hitPointRadius = pickResult.pickedPoint.length();\r\n\r\n            this._recalculateDragPlaneHitPoint(this._hitPointRadius, pickResult.ray, TmpVectors.Matrix[0]);\r\n            this._previousDragPlaneHitPointLocal.copyFrom(this._dragPlaneHitPointLocal);\r\n        } else {\r\n            this._hitPointRadius = undefined; // can't drag without a hit on the globe\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Ends the current drag gesture, releasing the drag plane.\r\n     */\r\n    public stopDrag() {\r\n        this._hitPointRadius = undefined;\r\n    }\r\n\r\n    /**\r\n     * The previous drag plane hit point in local space is stored to compute the movement delta.\r\n     * As the drag movement occurs, we will continuously recalculate this point. The delta between the previous and current hit points is the delta we will apply to the camera's localtranslation\r\n     * @param hitPointRadius The distance between the world origin (center of globe) and the initial drag hit point\r\n     * @param ray The ray from the camera to the new cursor location\r\n     * @param localToEcefResult The matrix to convert from local to ECEF space\r\n     */\r\n    private _recalculateDragPlaneHitPoint(hitPointRadius: number, ray: Ray, localToEcefResult: Matrix): void {\r\n        // Use the camera's geocentric normal to find the dragPlaneOriginPoint which lives at hitPointRadius along the camera's geocentric normal\r\n        this._cameraPosition.scaleToRef(hitPointRadius / Math.max(0.00001, this._cameraPosition.length()), this._dragPlaneOriginPointEcef);\r\n\r\n        // The dragPlaneOffsetVector will later be recalculated when drag occurs, and the delta between the offset vectors will be applied to localTranslation\r\n        ComputeLocalBasisToRefs(\r\n            this._dragPlaneOriginPointEcef,\r\n            TmpVectors.Vector3[0],\r\n            TmpVectors.Vector3[1],\r\n            this._dragPlaneNormal,\r\n            this._scene.useRightHandedSystem,\r\n            this.calculateUpVectorFromPointToRef\r\n        );\r\n        const localToEcef = Matrix.FromXYZAxesToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[1], this._dragPlaneNormal, localToEcefResult);\r\n        localToEcef.setTranslationFromFloats(this._dragPlaneOriginPointEcef.x, this._dragPlaneOriginPointEcef.y, this._dragPlaneOriginPointEcef.z);\r\n        const ecefToLocal = localToEcef.invertToRef(TmpVectors.Matrix[1]);\r\n\r\n        // Now create a plane at that point, perpendicular to _dragPlaneNormal.\r\n        Plane.FromPositionAndNormalToRef(this._dragPlaneOriginPointEcef, this._dragPlaneNormal, this._dragPlane);\r\n\r\n        // Lastly, find the _dragPlaneHitPoint where the ray intersects the _dragPlane.\r\n        if (IntersectRayWithPlaneToRef(ray, this._dragPlane, this._dragPlaneHitPointLocal)) {\r\n            // If hit, convert the drag plane hit point into the local space.\r\n            Vector3.TransformCoordinatesToRef(this._dragPlaneHitPointLocal, ecefToLocal, this._dragPlaneHitPointLocal);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the drag gesture by recalculating the intersection with the drag plane\r\n     * and accumulating the resulting pan delta.\r\n     * @param pointerX - Current screen X coordinate\r\n     * @param pointerY - Current screen Y coordinate\r\n     */\r\n    public handleDrag(pointerX: number, pointerY: number) {\r\n        const scene = this._scene;\r\n        if (!this._hitPointRadius || !scene.activeCamera) {\r\n            return;\r\n        }\r\n\r\n        scene.createPickingRayToRef(pointerX, pointerY, null, this._tempPickingRay, scene.activeCamera);\r\n\r\n        const localToEcef = TmpVectors.Matrix[0];\r\n        this._recalculateDragPlaneHitPoint(this._hitPointRadius, this._tempPickingRay, localToEcef);\r\n\r\n        const delta = this._dragPlaneHitPointLocal.subtractToRef(this._previousDragPlaneHitPointLocal, TmpVectors.Vector3[6]);\r\n\r\n        // When the camera is pitched nearly parallel to the drag plane, ray-plane intersection\r\n        // can produce enormous deltas. Clamp the delta to avoid massive jumps.\r\n        const maxDragDelta = this._hitPointRadius * 0.1; // Max 10% of hit radius per frame\r\n        const deltaLength = delta.length();\r\n        if (deltaLength > maxDragDelta) {\r\n            delta.scaleInPlace(maxDragDelta / deltaLength);\r\n        }\r\n\r\n        this._previousDragPlaneHitPointLocal.copyFrom(this._dragPlaneHitPointLocal);\r\n\r\n        Vector3.TransformNormalToRef(delta, localToEcef, delta);\r\n        this._dragPlaneOriginPointEcef.addInPlace(delta);\r\n\r\n        this.panAccumulatedPixels.subtractInPlace(delta);\r\n    }\r\n\r\n    /**\r\n     * Consumes the per-frame accumulated pan/rotate/zoom deltas and applies them to the camera state,\r\n     * with geospatial-specific dampening (e.g. slower panning near the poles, parallax-based pan compensation).\r\n     * Called once per frame by the scene's render loop via `_checkInputs`.\r\n     * @override\r\n     */\r\n    public override computeCurrentFrameDeltas(): void {\r\n        const cameraCenter = this._cameraCenter;\r\n\r\n        // Slows down panning near the poles\r\n        if (this.panAccumulatedPixels.lengthSquared() > Epsilon) {\r\n            const centerRadius = cameraCenter.length(); // distance from planet origin to camera center\r\n            const currentRadius = this._cameraPosition.length();\r\n            // Dampen the pan speed based on latitude (slower near poles)\r\n            const upAtCenter = TmpVectors.Vector3[7];\r\n            this.calculateUpVectorFromPointToRef(cameraCenter, upAtCenter);\r\n            // Latitude is derived from the Z component of the up vector (ECEF convention: Z = polar axis)\r\n            const sineOfSphericalLat = upAtCenter.z;\r\n            const cosOfSphericalLat = Math.sqrt(1 - Math.min(1, sineOfSphericalLat * sineOfSphericalLat));\r\n            const latitudeDampening = Math.sqrt(Math.abs(cosOfSphericalLat)); // sqrt here reduces effect near equator\r\n\r\n            // Reduce the dampening effect near surface (so that at ground level, pan speed is not affected by latitude)\r\n            const height = Math.max(currentRadius - centerRadius, Epsilon);\r\n            const latitudeDampeningScale = Math.max(1, centerRadius / height);\r\n\r\n            this._panSpeedMultiplier = Clamp(latitudeDampeningScale * latitudeDampening, 0, 1);\r\n        } else {\r\n            this._panSpeedMultiplier = 1;\r\n        }\r\n\r\n        // If a pan drag is occurring, stop zooming. Rotation and zoom are allowed simultaneously.\r\n        let zoomTargetDistance: number | undefined;\r\n        if (this.isDragging) {\r\n            this._zoomSpeedMultiplier = 0;\r\n            this._zoomVelocity = 0;\r\n        } else {\r\n            zoomTargetDistance = this.computedPerFrameZoomPickPoint ? Vector3Distance(this._cameraPosition, this.computedPerFrameZoomPickPoint) : undefined;\r\n\r\n            // Scales zoom movement speed based on camera distance to zoom target.\r\n            this._zoomSpeedMultiplier = (zoomTargetDistance ?? Vector3Distance(this._cameraPosition, cameraCenter)) * 0.01;\r\n        }\r\n\r\n        super.computeCurrentFrameDeltas();\r\n    }\r\n\r\n    /**\r\n     * Returns true when a drag gesture is active (between startDrag and stopDrag).\r\n     */\r\n    public get isDragging() {\r\n        return this._hitPointRadius !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Accumulates a zoom delta and determines the zoom target point via raycasting.\r\n     * @param zoomDelta - Signed zoom amount (positive = zoom in, negative = zoom out)\r\n     * @param toCursor - When true, zoom toward the point under the cursor; when false, zoom along the look vector\r\n     */\r\n    public handleZoom(zoomDelta: number, toCursor: boolean) {\r\n        if (zoomDelta !== 0) {\r\n            this.zoomAccumulatedPixels += zoomDelta;\r\n\r\n            const pickResult = Pick(this._scene, this._scene.pointerX, this._scene.pointerY, this.pickPredicate);\r\n\r\n            if (toCursor && pickResult.hit && pickResult.pickedPoint && pickResult.ray && this.zoomToCursor) {\r\n                this.computedPerFrameZoomPickPoint = pickResult.pickedPoint;\r\n            } else {\r\n                // If no hit under cursor or explicitly told not to zoom to cursor, zoom along lookVector instead\r\n                const lookPickResult = this.pickAlongVector(this._cameraLookAt);\r\n                this.computedPerFrameZoomPickPoint = lookPickResult?.pickedPoint ?? undefined;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Casts a ray from the camera position along the given direction and returns the pick result.\r\n     * @param vector - World-space direction to cast along\r\n     * @returns The pick result, or null if no hit\r\n     */\r\n    public pickAlongVector(vector: Vector3): Nullable<PickingInfo> {\r\n        this._tempPickingRay.origin.copyFrom(this._cameraPosition);\r\n        this._tempPickingRay.direction.copyFrom(vector);\r\n        return PickWithRay(this._scene, this._tempPickingRay, this.pickPredicate);\r\n    }\r\n}\r\n/** @internal */\r\nexport function ClampCenterFromPolesInPlace(center: Vector3) {\r\n    const sineOfSphericalLatitudeLimit = 0.998749218; // ~90 degrees\r\n    const centerMagnitude = center.length(); // distance from planet origin\r\n    if (centerMagnitude > Epsilon) {\r\n        const sineSphericalLat = centerMagnitude === 0 ? 0 : center.z / centerMagnitude;\r\n        if (Math.abs(sineSphericalLat) > sineOfSphericalLatitudeLimit) {\r\n            // Clamp the spherical latitude (and derive longitude)\r\n            const sineOfClampedSphericalLat = Clamp(sineSphericalLat, -sineOfSphericalLatitudeLimit, sineOfSphericalLatitudeLimit);\r\n            const cosineOfClampedSphericalLat = Math.sqrt(1 - sineOfClampedSphericalLat * sineOfClampedSphericalLat);\r\n            const longitude = Math.atan2(center.y, center.x);\r\n\r\n            // Spherical to Cartesian\r\n            const newX = centerMagnitude * Math.cos(longitude) * cosineOfClampedSphericalLat;\r\n            const newY = centerMagnitude * Math.sin(longitude) * cosineOfClampedSphericalLat;\r\n            const newZ = centerMagnitude * sineOfClampedSphericalLat;\r\n\r\n            center.set(newX, newY, newZ);\r\n        }\r\n    }\r\n    return center;\r\n}\r\n\r\nfunction IntersectRayWithPlaneToRef(ray: Ray, plane: Plane, ref: Vector3): boolean {\r\n    // Distance along the ray to the plane; null if no hit\r\n    const dist = ray.intersectsPlane(plane);\r\n\r\n    if (dist !== null && dist >= 0) {\r\n        ray.origin.addToRef(ray.direction.scaleToRef(dist, TmpVectors.Vector3[0]), ref);\r\n        return true;\r\n    }\r\n\r\n    return false;\r\n}\r\n\r\n/**\r\n * Helper to build east/north/up basis vectors at a world position.\r\n * Cross product order is swapped based on handedness so that the east vector\r\n * encodes the coordinate-system convention, removing the need for a separate yawScale.\r\n * @param worldPos - The position on the globe\r\n * @param refEast - Receives the east direction\r\n * @param refNorth - Receives the north direction\r\n * @param refUp - Receives the up (outward) direction\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system (default: false)\r\n * @param calculateUpVectorFromPointToRef - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.\r\n * @internal\r\n */\r\nexport function ComputeLocalBasisToRefs(\r\n    worldPos: Vector3,\r\n    refEast: Vector3,\r\n    refNorth: Vector3,\r\n    refUp: Vector3,\r\n    useRightHandedSystem: boolean = false,\r\n    calculateUpVectorFromPointToRef?: (point: Vector3, result: Vector3) => Vector3\r\n): void {\r\n    if (calculateUpVectorFromPointToRef) {\r\n        calculateUpVectorFromPointToRef(worldPos, refUp);\r\n    } else {\r\n        // up = normalized position (geocentric normal)\r\n        refUp.copyFrom(worldPos).normalize();\r\n    }\r\n\r\n    // east – cross product order determines handedness\r\n    const worldNorth = Vector3.LeftHandedForwardReadOnly; // (0,0,1)\r\n    if (useRightHandedSystem) {\r\n        Vector3.CrossToRef(worldNorth, refUp, refEast);\r\n    } else {\r\n        Vector3.CrossToRef(refUp, worldNorth, refEast);\r\n    }\r\n\r\n    // at poles, cross with worldRight instead\r\n    if (refEast.lengthSquared() < Epsilon) {\r\n        if (useRightHandedSystem) {\r\n            Vector3.CrossToRef(Vector3.Right(), refUp, refEast);\r\n        } else {\r\n            Vector3.CrossToRef(refUp, Vector3.Right(), refEast);\r\n        }\r\n    }\r\n    refEast.normalize();\r\n\r\n    // north – completes the basis (cross order also swapped for handedness)\r\n    if (useRightHandedSystem) {\r\n        Vector3.CrossToRef(refUp, refEast, refNorth);\r\n    } else {\r\n        Vector3.CrossToRef(refEast, refUp, refNorth);\r\n    }\r\n    refNorth.normalize();\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { GeospatialCameraInputsManager } from \"./geospatialCameraInputsManager\";\r\nimport { Vector3, Matrix, TmpVectors, type Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { Camera } from \"./camera.pure\";\r\nimport { serialize, serializeAsVector3 } from \"../Misc/decorators\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type MeshPredicate } from \"../Culling/ray.core\";\r\nimport { type DeepImmutable } from \"../types\";\r\nimport { GeospatialLimits } from \"./Limits/geospatialLimits\";\r\nimport { ClampCenterFromPolesInPlace, ComputeLocalBasisToRefs, GeospatialCameraMovement } from \"./geospatialCameraMovement\";\r\nimport { type IVector3Like } from \"../Maths/math.like\";\r\nimport { Vector3CopyToRef, Vector3Distance, Vector3Dot, Vector3SubtractToRef } from \"../Maths/math.vector.functions\";\r\nimport { Clamp, NormalizeRadians } from \"../Maths/math.scalar.functions\";\r\nimport { type AllowedAnimValue, InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport { type Collider } from \"../Collisions/collider\";\r\nimport { type EasingFunction } from \"../Animations/easing\";\r\nimport { type Animation } from \"../Animations/animation.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nexport type GeospatialCameraOptions = {\r\n    /**\r\n     * Radius of the planet being orbited\r\n     */\r\n    planetRadius: number;\r\n    /**\r\n     * If supplied, will be used by the movement class when picking the globe. Can later update camera.movement.pickPredicate directly\r\n     */\r\n    pickPredicate?: MeshPredicate;\r\n};\r\n\r\n/**\r\n * Camera equipped to orbit a spherical planet centered at world origin\r\n */\r\nexport class GeospatialCamera extends Camera {\r\n    override inputs: GeospatialCameraInputsManager;\r\n\r\n    /** Movement controller that provides input mapping and framerate-independent physics for geospatial interactions */\r\n    public readonly movement: GeospatialCameraMovement;\r\n\r\n    // Temp vars\r\n    private _tempPosition: Vector3 = new Vector3();\r\n    private _tempCenter: Vector3 = new Vector3();\r\n\r\n    private _viewMatrix = new Matrix();\r\n    private _isViewMatrixDirty: boolean;\r\n    private _lookAtVector: Vector3 = new Vector3();\r\n\r\n    /** Behavior used for smooth flying animations */\r\n    private _flyingBehavior: InterpolatingBehavior<GeospatialCamera>;\r\n    private _flyToTargets: Map<keyof GeospatialCamera, AllowedAnimValue> = new Map();\r\n\r\n    // Collision properties\r\n    private _collider?: Collider;\r\n    private _collisionVelocity: Vector3 = new Vector3();\r\n    /** Public option to customize the collision offset applied each frame - vs the one calculated using internal CollisionCoordinator */\r\n    public perFrameCollisionOffset: Vector3 = new Vector3();\r\n    /** Enable or disable collision checking for this camera. Default is false. */\r\n    @serialize()\r\n    public checkCollisions: boolean = false;\r\n\r\n    constructor(name: string, scene: Scene, options: GeospatialCameraOptions) {\r\n        super(name, new Vector3(), scene);\r\n\r\n        this._limits = new GeospatialLimits(options.planetRadius);\r\n\r\n        this._flyingBehavior = new InterpolatingBehavior();\r\n        this.addBehavior(this._flyingBehavior);\r\n\r\n        this.movement = new GeospatialCameraMovement(scene, this._limits, this.position, this.center, this._lookAtVector, options.pickPredicate, this._flyingBehavior);\r\n\r\n        this._resetToDefault(this._limits);\r\n\r\n        this.inputs = new GeospatialCameraInputsManager(this);\r\n        this.inputs.addMouse().addMouseWheel().addKeyboard();\r\n    }\r\n\r\n    @serializeAsVector3()\r\n    private _center: Vector3 = new Vector3();\r\n    /** The point on the globe that we are anchoring around. If no alternate rotation point is supplied, this will represent the center of screen*/\r\n    public get center(): Vector3 {\r\n        return this._center;\r\n    }\r\n\r\n    /**\r\n     * Sets the camera position to orbit around a new center point\r\n     * @param center The world position (ECEF) to orbit around\r\n     */\r\n    public set center(center: IVector3Like) {\r\n        this._center.copyFromFloats(center.x, center.y, center.z);\r\n        this._setOrientation(this._yaw, this._pitch, this._radius, this._center);\r\n    }\r\n\r\n    @serialize()\r\n    private _yaw: number = 0;\r\n    /**\r\n     * Gets the camera's yaw (rotation around the geocentric normal) in radians\r\n     */\r\n    public get yaw(): number {\r\n        return this._yaw;\r\n    }\r\n\r\n    /**\r\n     * Sets the camera's yaw (rotation around the geocentric normal). Will wrap value to [-π, π)\r\n     * @param yaw The desired yaw angle in radians (0 = north, π/2 = east)\r\n     */\r\n    public set yaw(yaw: number) {\r\n        yaw !== this._yaw && this._setOrientation(yaw, this.pitch, this.radius, this.center);\r\n    }\r\n\r\n    @serialize()\r\n    private _pitch: number = 0;\r\n\r\n    /**\r\n     * Gets the camera's pitch (angle from looking straight at globe)\r\n     * Pitch is measured from looking straight down at planet center:\r\n     * - zero pitch = looking straight at planet center (down)\r\n     * - positive pitch = tilting up away from planet\r\n     * - π/2 pitch = looking at horizon (perpendicular to geocentric normal)\r\n     */\r\n    public get pitch(): number {\r\n        return this._pitch;\r\n    }\r\n\r\n    /**\r\n     * Sets the camera's pitch (angle from looking straight at globe). Will wrap value to [-π, π)\r\n     * @param pitch The desired pitch angle in radians (0 = looking at planet center, π/2 = looking at horizon)\r\n     */\r\n    public set pitch(pitch: number) {\r\n        pitch !== this._pitch && this._setOrientation(this.yaw, pitch, this.radius, this.center);\r\n    }\r\n\r\n    @serialize()\r\n    private _radius: number = 0;\r\n    /**\r\n     * Gets the camera's distance from the current center point. This is distinct from planetRadius supplied at construction.\r\n     */\r\n    public get radius(): number {\r\n        return this._radius;\r\n    }\r\n\r\n    /**\r\n     * Sets the camera's distance from the current center point\r\n     * @param radius The desired radius\r\n     */\r\n    public set radius(radius: number) {\r\n        radius !== this._radius && this._setOrientation(this.yaw, this.pitch, radius, this.center);\r\n    }\r\n\r\n    protected _checkLimits() {\r\n        const limits = this.limits;\r\n        this._yaw = Clamp(this._yaw, limits.yawMin, limits.yawMax);\r\n        const effectivePitchMax = limits.getEffectivePitchMax(this._radius);\r\n        this._pitch = Clamp(this._pitch, limits.pitchMin, effectivePitchMax);\r\n        this._radius = Clamp(this._radius, limits.radiusMin, limits.radiusMax);\r\n        ClampCenterFromPolesInPlace(this._center);\r\n    }\r\n\r\n    private _tempVect = new Vector3();\r\n    private _tempEast = new Vector3();\r\n    private _tempNorth = new Vector3();\r\n    private _tempUp = new Vector3();\r\n\r\n    private _setOrientation(yaw: number, pitch: number, radius: number, center: DeepImmutable<IVector3Like>): void {\r\n        // Wrap yaw and pitch to [-π, π)\r\n        this._yaw = NormalizeRadians(yaw);\r\n        this._pitch = NormalizeRadians(pitch);\r\n        this._radius = radius;\r\n\r\n        Vector3CopyToRef(center, this._center);\r\n\r\n        // Clamp to limits\r\n        this._checkLimits();\r\n\r\n        // Refresh local basis at center (treat these as read-only for the whole call)\r\n        ComputeLocalBasisToRefs(this._center, this._tempEast, this._tempNorth, this._tempUp, this._scene.useRightHandedSystem, this.movement.calculateUpVectorFromPointToRef);\r\n\r\n        // Compute lookAt from yaw/pitch\r\n        ComputeLookAtFromYawPitchToRef(this._yaw, this._pitch, this._center, this._scene.useRightHandedSystem, this._lookAtVector, this.movement.calculateUpVectorFromPointToRef);\r\n\r\n        // Build an orthonormal up aligned with geocentric Up\r\n        // When looking straight down (pitch ≈ 0), lookAt is parallel to Up, so use the horizontal direction as the camera's up.\r\n        const right = TmpVectors.Vector3[10];\r\n        Vector3.CrossToRef(this._tempUp, this._lookAtVector, right);\r\n        if (right.lengthSquared() < Epsilon) {\r\n            // horiz = north * cos(yaw) + east * sin(yaw)\r\n            // Using tempEast directly ensures handedness is taken into account\r\n            const horiz = TmpVectors.Vector3[11];\r\n            const t1 = TmpVectors.Vector3[12];\r\n            horiz\r\n                .copyFrom(this._tempNorth)\r\n                .scaleInPlace(Math.cos(this._yaw))\r\n                .addInPlace(t1.copyFrom(this._tempEast).scaleInPlace(Math.sin(this._yaw)));\r\n            // right = cross(horiz, lookAt)\r\n            Vector3.CrossToRef(horiz, this._lookAtVector, right);\r\n        }\r\n        right.normalize();\r\n\r\n        // up = normalize(cross(look, right))\r\n        Vector3.CrossToRef(this._lookAtVector, right, this.upVector);\r\n        this.upVector.normalize();\r\n\r\n        // Position = center - look * radius  (preserve unit look)\r\n        this._tempVect.copyFrom(this._lookAtVector).scaleInPlace(-this._radius);\r\n        this._tempPosition.copyFrom(this._center).addInPlace(this._tempVect);\r\n\r\n        // Recalculate collisionOffset to be applied later when viewMatrix is calculated (allowing camera users to modify the value in afterCheckInputsObservable)\r\n        if (this.checkCollisions) {\r\n            this.perFrameCollisionOffset = this._getCollisionOffset(this._tempPosition);\r\n        }\r\n\r\n        this._position.copyFrom(this._tempPosition);\r\n\r\n        this._isViewMatrixDirty = true;\r\n    }\r\n\r\n    /**\r\n     * If the camera is actively in flight, redirects it toward a new destination, using up the remaining\r\n     * duration from the original flyToAsync call. The redirect starts from the camera's current pose, so it\r\n     * stays smooth (no snap). If the camera is not currently in flight this is a no-op; start a new flight\r\n     * with flyToAsync instead.\r\n     *\r\n     * Note: redirecting interrupts the in-flight animation, so the promise returned by the original\r\n     * flyToAsync call resolves early. Await the promise returned here to be notified when the redirected\r\n     * flight actually completes.\r\n     *\r\n     * Any property left undefined is frozen at its current value (matching flyToAsync), it does not continue\r\n     * toward the original flight's destination for that property.\r\n     * @param targetYaw - Target yaw in radians, or undefined to freeze yaw at its current value.\r\n     * @param targetPitch - Target pitch in radians, or undefined to freeze pitch at its current value.\r\n     * @param targetRadius - Target radius (distance from the look-at center), or undefined to freeze radius at its current value.\r\n     * @param targetCenter - Target look-at center in scene coordinates, or undefined to freeze the center at its current value.\r\n     * @returns Promise that resolves when the redirected flight completes (or is interrupted), or undefined if the camera was not in flight.\r\n     */\r\n    public updateFlyToDestination(targetYaw?: number, targetPitch?: number, targetRadius?: number, targetCenter?: Vector3): Promise<void> | undefined {\r\n        if (!this._flyingBehavior.isInterpolating) {\r\n            // Nothing in flight to redirect. Callers should use flyToAsync to start a new flight.\r\n            return undefined;\r\n        }\r\n\r\n        // Redirecting is just a fresh flight that starts from the camera's current pose and uses up the\r\n        // time left in the original flight. flyToAsync already eases from the current values, so this stays\r\n        // smooth (no snap).\r\n        return this._flyToAsync(targetYaw, targetPitch, targetRadius, targetCenter, this._flyingBehavior.remainingDurationMs);\r\n    }\r\n\r\n    /**\r\n     * Animate camera towards passed in property values. If undefined, will use current value\r\n     * @param targetYaw - Target yaw in radians, or undefined to keep the current yaw.\r\n     * @param targetPitch - Target pitch in radians, or undefined to keep the current pitch.\r\n     * @param targetRadius - Target radius (distance from the look-at center), or undefined to keep the current radius.\r\n     * @param targetCenter - Target look-at center in scene coordinates, or undefined to keep the current center.\r\n     * @param flightDurationMs - Total duration of the animation in milliseconds. Defaults to 1000ms.\r\n     * @param easingFunction - Optional easing function applied to the animation curve.\r\n     * @param centerHopScale If supplied, will define the parabolic hop height scale for center animation to create a \"bounce\" effect\r\n     * @returns Promise that will return when the animation is complete (or interuppted by pointer input)\r\n     */\r\n    public async flyToAsync(\r\n        targetYaw?: number,\r\n        targetPitch?: number,\r\n        targetRadius?: number,\r\n        targetCenter?: Vector3,\r\n        flightDurationMs: number = 1000,\r\n        easingFunction?: EasingFunction,\r\n        centerHopScale?: number\r\n    ): Promise<void> {\r\n        return await this._flyToAsync(targetYaw, targetPitch, targetRadius, targetCenter, flightDurationMs, easingFunction, centerHopScale);\r\n    }\r\n\r\n    /**\r\n     * Shared flight implementation used by both flyToAsync (new flight) and updateFlyToDestination (redirect).\r\n     * Builds the target property map (and the center SLERP/hop interpolation) and animates from the camera's\r\n     * current pose over the given duration.\r\n     * @param targetYaw - Target yaw in radians, or undefined to keep the current yaw.\r\n     * @param targetPitch - Target pitch in radians, or undefined to keep the current pitch.\r\n     * @param targetRadius - Target radius (distance from the look-at center), or undefined to keep the current radius.\r\n     * @param targetCenter - Target look-at center in scene coordinates, or undefined to keep the current center.\r\n     * @param flightDurationMs - Total duration of the animation in milliseconds. Defaults to 1000ms.\r\n     * @param easingFunction - Optional easing function applied to the animation curve.\r\n     * @param centerHopScale - If supplied, defines the parabolic hop height scale for the center animation to create a \"bounce\" effect.\r\n     * @returns Promise that resolves when the animation is complete (or interrupted).\r\n     */\r\n    private async _flyToAsync(\r\n        targetYaw?: number,\r\n        targetPitch?: number,\r\n        targetRadius?: number,\r\n        targetCenter?: Vector3,\r\n        flightDurationMs: number = 1000,\r\n        easingFunction?: EasingFunction,\r\n        centerHopScale?: number\r\n    ): Promise<void> {\r\n        this._flyToTargets.clear();\r\n\r\n        // For yaw, use shortest path to target.\r\n        const deltaYaw = targetYaw !== undefined ? NormalizeRadians(NormalizeRadians(targetYaw) - this._yaw) : 0;\r\n        this._flyToTargets.set(\"yaw\", deltaYaw === 0 ? undefined : this._yaw + deltaYaw);\r\n        this._flyToTargets.set(\"pitch\", targetPitch !== undefined ? NormalizeRadians(targetPitch) : undefined);\r\n        this._flyToTargets.set(\"radius\", targetRadius);\r\n        this._flyToTargets.set(\"center\", targetCenter?.clone());\r\n\r\n        let overrideAnimationFunction;\r\n        if (targetCenter !== undefined && !targetCenter.equals(this.center)) {\r\n            // Animate center directly with custom interpolation\r\n            overrideAnimationFunction = (key: string, animation: Animation): void => {\r\n                if (key === \"center\") {\r\n                    // Override the Vector3 interpolation to use SLERP + hop\r\n                    animation.vector3InterpolateFunction = (startValue, endValue, gradient) => {\r\n                        // gradient is the eased value (0 to 1) after easing function is applied\r\n\r\n                        // Slerp between start and end\r\n                        const newCenter = Vector3.SlerpToRef(startValue, endValue, gradient, this._tempCenter);\r\n\r\n                        // Apply parabolic hop if requested\r\n                        if (centerHopScale && centerHopScale > 0) {\r\n                            // Parabolic formula: peaks at t=0.5, returns to 0 at gradient=0 and gradient=1\r\n                            // if hopPeakT = .5 the denominator would be hopPeakT * hopPeakT - hopPeakT, which = -.25\r\n                            const hopPeakOffset = centerHopScale * Vector3Distance(startValue, endValue);\r\n                            const hopOffset = hopPeakOffset * Clamp((gradient * gradient - gradient) / -0.25);\r\n                            // Scale the center outward (away from origin)\r\n                            newCenter.scaleInPlace(1 + hopOffset / newCenter.length());\r\n                        }\r\n\r\n                        return newCenter;\r\n                    };\r\n                }\r\n            };\r\n        }\r\n\r\n        return await this._flyingBehavior.animatePropertiesAsync(this._flyToTargets, flightDurationMs, easingFunction, overrideAnimationFunction);\r\n    }\r\n\r\n    /**\r\n     * Helper function to move camera towards a given point by `distanceScale` of the current camera-to-destination distance (by default 50%).\r\n     * @param destination point to move towards\r\n     * @param distanceScale value between 0 and 1, % of distance to move\r\n     * @param durationMs duration of flight, default 1s\r\n     * @param easingFn optional easing function for flight interpolation of properties\r\n     * @param centerHopScale If supplied, will define the parabolic hop height scale for center animation to create a \"bounce\" effect\r\n     */\r\n    public async flyToPointAsync(destination: Vector3, distanceScale: number = 0.5, durationMs: number = 1000, easingFn?: EasingFunction, centerHopScale?: number) {\r\n        // Move by a fraction of the camera-to-destination distance\r\n        const zoomDistance = Vector3Distance(this.position, destination) * distanceScale;\r\n        const newRadius = this._getCenterAndRadiusFromZoomToPoint(destination, zoomDistance, this._tempCenter);\r\n        await this.flyToAsync(undefined, undefined, newRadius, this._tempCenter, durationMs, easingFn, centerHopScale);\r\n        !this.isDisposed() && this._recalculateCenter(false, true /** force */);\r\n    }\r\n\r\n    private _limits: GeospatialLimits;\r\n    /**\r\n     * Gets the limits for this camera\r\n     */\r\n    public get limits(): GeospatialLimits {\r\n        return this._limits;\r\n    }\r\n\r\n    private _resetToDefault(limits: GeospatialLimits): void {\r\n        // Camera configuration vars\r\n        const restingAltitude = limits.radiusMax !== Infinity ? limits.radiusMax : limits.planetRadius * 4;\r\n        this.position.copyFromFloats(restingAltitude, 0, 0);\r\n        this._center.copyFromFloats(limits.planetRadius, 0, 0);\r\n        this._radius = Vector3.Distance(this.position, this.center);\r\n\r\n        // Temp vars\r\n        this._tempPosition = new Vector3();\r\n\r\n        // View matrix calculation vars\r\n        this._viewMatrix = Matrix.Identity();\r\n        this._center.subtractToRef(this._position, this._lookAtVector).normalize(); // Lookat vector of the camera\r\n        this.upVector = Vector3.Up(); // Up vector of the camera (does work for -X look at)\r\n        this._isViewMatrixDirty = true;\r\n\r\n        this._setOrientation(this._yaw, this._pitch, this._radius, this._center);\r\n    }\r\n\r\n    /** @internal */\r\n    override _getViewMatrix() {\r\n        if (!this._isViewMatrixDirty) {\r\n            return this._viewMatrix;\r\n        }\r\n        this._isViewMatrixDirty = false;\r\n\r\n        // Ensure vectors are normalized\r\n        this.upVector.normalize();\r\n        this._lookAtVector.normalize();\r\n\r\n        // Apply the same offset to both position and center to preserve orbital relationship\r\n        // This keeps yaw/pitch/radius intact - just lifts the whole \"rig\"\r\n        this._position.addInPlace(this.perFrameCollisionOffset);\r\n        this._center.addInPlace(this.perFrameCollisionOffset);\r\n\r\n        // Calculate view matrix with camera position and center\r\n        if (this.getScene().useRightHandedSystem) {\r\n            Matrix.LookAtRHToRef(this.position, this._center, this.upVector, this._viewMatrix);\r\n        } else {\r\n            Matrix.LookAtLHToRef(this.position, this._center, this.upVector, this._viewMatrix);\r\n        }\r\n\r\n        return this._viewMatrix;\r\n    }\r\n\r\n    /** @internal */\r\n    override _isSynchronizedViewMatrix(): boolean {\r\n        if (!super._isSynchronizedViewMatrix() || this._isViewMatrixDirty) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private _applyGeocentricTranslation() {\r\n        // Store pending position (without any corrections applied)\r\n        this.center.addToRef(this.movement.panDeltaCurrentFrame, this._tempPosition);\r\n\r\n        if (!this.movement.isInterpolating) {\r\n            // Calculate the position correction to keep camera at the same radius when applying translation\r\n            this._tempPosition.normalize().scaleInPlace(this.center.length());\r\n        }\r\n        // Set center which will call _setOrientation\r\n        this.center = this._tempPosition;\r\n    }\r\n\r\n    /**\r\n     * This rotation keeps the camera oriented towards the globe as it orbits around it. This is different from cameraCentricRotation which is when the camera rotates around its own axis\r\n     */\r\n    private _applyGeocentricRotation(): void {\r\n        const rotationDeltaCurrentFrame = this.movement.rotationDeltaCurrentFrame;\r\n        if (rotationDeltaCurrentFrame.x !== 0 || rotationDeltaCurrentFrame.y !== 0) {\r\n            const pitch = rotationDeltaCurrentFrame.x !== 0 ? Clamp(this._pitch + rotationDeltaCurrentFrame.x, 0, 0.5 * Math.PI - Epsilon) : this._pitch;\r\n            const yaw = rotationDeltaCurrentFrame.y !== 0 ? this._yaw + rotationDeltaCurrentFrame.y : this._yaw;\r\n\r\n            this._setOrientation(yaw, pitch, this._radius, this._center);\r\n        }\r\n    }\r\n\r\n    private _getCenterAndRadiusFromZoomToPoint(targetPoint: DeepImmutable<IVector3Like>, distance: number, newCenterResult: Vector3): number {\r\n        const directionToTarget = Vector3SubtractToRef(targetPoint, this._position, TmpVectors.Vector3[0]);\r\n        const distanceToTarget = directionToTarget.length();\r\n\r\n        // Don't zoom past the min radius limit.\r\n        if (distanceToTarget < this.limits.radiusMin) {\r\n            newCenterResult.copyFrom(this._center);\r\n            const requestedRadius = this._radius - distance;\r\n            const newRadius = Clamp(requestedRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n            return newRadius;\r\n        }\r\n\r\n        // Move the camera position towards targetPoint by distanceToTarget\r\n        directionToTarget.scaleInPlace(distance / distanceToTarget);\r\n        const newPosition = this._position.addToRef(directionToTarget, TmpVectors.Vector3[1]);\r\n\r\n        // Project the movement onto the look vector to derive the new center/radius.\r\n        const projectedDistance = Vector3Dot(directionToTarget, this._lookAtVector);\r\n        const newRadius = this._radius - projectedDistance;\r\n        const newRadiusClamped = Clamp(newRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n        newCenterResult.copyFrom(newPosition).addInPlace(this._lookAtVector.scale(newRadiusClamped));\r\n\r\n        return newRadiusClamped;\r\n    }\r\n\r\n    /**\r\n     * Apply zoom by moving the camera toward/away from a target point.\r\n     */\r\n    private _applyZoom() {\r\n        let zoomDelta = this.movement.zoomDeltaCurrentFrame;\r\n        const pickedPoint = this.movement.computedPerFrameZoomPickPoint;\r\n\r\n        // Clamp zoom delta to limits before applying\r\n        zoomDelta = this._clampZoomDelta(zoomDelta, pickedPoint);\r\n\r\n        if (Math.abs(zoomDelta) < Epsilon) {\r\n            return;\r\n        }\r\n        if (pickedPoint) {\r\n            // Zoom toward the picked point under cursor\r\n            this.zoomToPoint(pickedPoint, zoomDelta);\r\n        } else {\r\n            // Zoom along lookAt vector (fallback when no surface under cursor)\r\n            this.zoomAlongLookAt(zoomDelta);\r\n        }\r\n    }\r\n\r\n    private _clampZoomDelta(zoomDelta: number, pickedPoint?: Vector3): number {\r\n        if (Math.abs(zoomDelta) < Epsilon) {\r\n            return 0;\r\n        }\r\n\r\n        const distanceToTarget = pickedPoint ? Vector3Distance(this._position, pickedPoint) : undefined;\r\n        return this.limits.clampZoomDistance(zoomDelta, this._radius, distanceToTarget);\r\n    }\r\n\r\n    /**\r\n     * Zoom towards a specific point on the globe\r\n     * @param targetPoint The point to zoom towards\r\n     * @param distance The distance to move\r\n     */\r\n    public zoomToPoint(targetPoint: DeepImmutable<IVector3Like>, distance: number) {\r\n        const newRadius = this._getCenterAndRadiusFromZoomToPoint(targetPoint, distance, this._tempCenter);\r\n        // Apply the new orientation\r\n        this._setOrientation(this._yaw, this._pitch, newRadius, this._tempCenter);\r\n    }\r\n\r\n    /**\r\n     * Zoom along the camera's lookAt direction\r\n     * @param distance The distance to zoom\r\n     */\r\n    public zoomAlongLookAt(distance: number) {\r\n        // Clamp radius to limits\r\n        const requestedRadius = this._radius - distance;\r\n        const newRadius = Clamp(requestedRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n\r\n        // Simply change radius without moving center\r\n        this._setOrientation(this._yaw, this._pitch, newRadius, this._center);\r\n    }\r\n\r\n    /** @internal */\r\n    override _checkInputs(): void {\r\n        this.inputs.checkInputs();\r\n        this.perFrameCollisionOffset.setAll(0);\r\n\r\n        // Let movement class handle all per-frame logic\r\n        this.movement.computeCurrentFrameDeltas();\r\n\r\n        let isCenterMoving = false;\r\n        if (this.movement.panDeltaCurrentFrame.lengthSquared() > 0) {\r\n            this._applyGeocentricTranslation();\r\n            // After a drag, recalculate the center point to ensure it's still on the surface.\r\n            isCenterMoving = true;\r\n        }\r\n        if (this.movement.rotationDeltaCurrentFrame.lengthSquared() > 0) {\r\n            this._applyGeocentricRotation();\r\n        }\r\n\r\n        if (Math.abs(this.movement.zoomDeltaCurrentFrame) > Epsilon) {\r\n            this._applyZoom();\r\n            isCenterMoving = true;\r\n        }\r\n\r\n        // After a movement impacting center or radius, recalculate the center point to ensure it's still on the surface.\r\n        this._recalculateCenter(isCenterMoving);\r\n\r\n        super._checkInputs();\r\n    }\r\n\r\n    private _wasCenterMovingLastFrame = false;\r\n\r\n    private _recalculateCenter(isCenterMoving: boolean, forceRecalculate: boolean = false): void {\r\n        const shouldRecalculateCenterAfterMove = this._wasCenterMovingLastFrame && !isCenterMoving;\r\n        this._wasCenterMovingLastFrame = isCenterMoving;\r\n\r\n        // Wait until movement impacting center is complete to avoid wasted raycasting\r\n        if (shouldRecalculateCenterAfterMove || forceRecalculate) {\r\n            const newCenter = this.movement.pickAlongVector(this._lookAtVector);\r\n            if (newCenter?.pickedPoint) {\r\n                // Direction from new center to origin\r\n                const centerToOrigin = TmpVectors.Vector3[4];\r\n                centerToOrigin.copyFrom(newCenter.pickedPoint).negateInPlace().normalize();\r\n\r\n                // Check if this direction aligns with camera's lookAt vector\r\n                const dotProduct = Vector3Dot(this._lookAtVector, centerToOrigin);\r\n\r\n                // Only update if the center is looking toward the origin (dot product > 0) to avoid a center on the opposite side of globe\r\n                if (dotProduct > 0) {\r\n                    // Compute the new radius as distance from camera position to new center\r\n                    const newRadius = Vector3Distance(this._position, newCenter.pickedPoint);\r\n\r\n                    // Only update if the new center is in front of the camera\r\n                    if (newRadius > Epsilon) {\r\n                        // Compute yaw/pitch that correspond to current lookAt at new center\r\n                        const yawPitch = TmpVectors.Vector2[0];\r\n                        ComputeYawPitchFromLookAtToRef(\r\n                            this._lookAtVector,\r\n                            newCenter.pickedPoint,\r\n                            this._scene.useRightHandedSystem,\r\n                            this._yaw,\r\n                            yawPitch,\r\n                            this.movement.calculateUpVectorFromPointToRef\r\n                        );\r\n\r\n                        // Call _setOrientation with the computed yaw/pitch and new center\r\n                        this._setOrientation(yawPitch.x, yawPitch.y, newRadius, newCenter.pickedPoint);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Allows extended classes to override how collision offset is calculated\r\n     * @param newPosition\r\n     * @returns\r\n     */\r\n    protected _getCollisionOffset(newPosition: Vector3): Vector3 {\r\n        const collisionOffset = TmpVectors.Vector3[6].setAll(0);\r\n        if (!this.checkCollisions || !this._scene.collisionsEnabled) {\r\n            return collisionOffset;\r\n        }\r\n\r\n        const coordinator = this.getScene().collisionCoordinator;\r\n        if (!coordinator) {\r\n            return collisionOffset;\r\n        }\r\n\r\n        if (!this._collider) {\r\n            this._collider = coordinator.createCollider();\r\n        }\r\n        this._collider._radius.setAll(this.limits.radiusMin);\r\n\r\n        // Calculate velocity from old position to new position\r\n        newPosition.subtractToRef(this._position, this._collisionVelocity);\r\n\r\n        // Get the collision-adjusted position\r\n        const adjustedPosition = coordinator.getNewPosition(this._position, this._collisionVelocity, this._collider, 3, null, () => {}, this.uniqueId);\r\n\r\n        // Calculate the collision offset (how much the position was pushed)\r\n        adjustedPosition.subtractToRef(newPosition, collisionOffset);\r\n\r\n        return collisionOffset;\r\n    }\r\n\r\n    /** @internal */\r\n    override attachControl(noPreventDefault?: boolean): void {\r\n        this.inputs.attachElement(noPreventDefault);\r\n    }\r\n\r\n    /** @internal */\r\n    override detachControl(): void {\r\n        this.inputs.detachElement();\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the camera.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GeospatialCamera\";\r\n    }\r\n}\r\n\r\n// Register Class Name\r\n\r\n/**\r\n * Compute the lookAt direction vector from yaw and pitch angles at a given center point.\r\n * This is the forward formula used by GeospatialCamera._setOrientation.\r\n * @param yaw - The yaw angle in radians (0 = north, π/2 = east)\r\n * @param pitch - The pitch angle in radians (0 = looking at planet center, π/2 = looking at horizon)\r\n * @param center - The center point on the globe\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system\r\n * @param result - The vector to store the result in\r\n * @param calculateUpVectorFromPointToRef - Optional function to calculate the up vector from a point, allowing for non-spherical planets. If not supplied, a perfect sphere is assumed and the up vector is just the normalized center point.\r\n * @returns The normalized lookAt direction vector (same as result)\r\n */\r\nexport function ComputeLookAtFromYawPitchToRef(\r\n    yaw: number,\r\n    pitch: number,\r\n    center: Vector3,\r\n    useRightHandedSystem: boolean,\r\n    result: Vector3,\r\n    calculateUpVectorFromPointToRef?: (point: Vector3, result: Vector3) => Vector3\r\n): Vector3 {\r\n    const east = TmpVectors.Vector3[0];\r\n    const north = TmpVectors.Vector3[1];\r\n    const up = TmpVectors.Vector3[2];\r\n    ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem, calculateUpVectorFromPointToRef);\r\n    const sinPitch = Math.sin(pitch);\r\n    const cosPitch = Math.cos(pitch);\r\n\r\n    // horiz = north * cos(yaw) + east * sin(yaw)\r\n    // Handedness is taken into account when defining east vector via ComputeLocalBasisToRefs.\r\n    const horiz = TmpVectors.Vector3[3];\r\n    const t1 = TmpVectors.Vector3[4];\r\n    horiz\r\n        .copyFrom(north)\r\n        .scaleInPlace(Math.cos(yaw))\r\n        .addInPlace(t1.copyFrom(east).scaleInPlace(Math.sin(yaw)));\r\n\r\n    // lookAt = horiz * sinPitch - up * cosPitch\r\n    const t2 = TmpVectors.Vector3[5];\r\n    result.copyFrom(horiz).scaleInPlace(sinPitch).addInPlace(t2.copyFrom(up).scaleInPlace(-cosPitch));\r\n    return result.normalize();\r\n}\r\n\r\n/**\r\n * Given a lookAt direction and center, compute the yaw and pitch angles that would produce that lookAt.\r\n * This is the inverse of ComputeLookAtFromYawPitchToRef.\r\n * @param lookAt - The normalized lookAt direction vector\r\n * @param center - The center point on the globe\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system\r\n * @param currentYaw - The current yaw value to use as fallback when pitch is near 0 (looking straight down/up)\r\n * @param result - The Vector2 to store the result in (x = yaw, y = pitch)\r\n * @param calculateUpVectorFromPointToRef - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.\r\n * @returns The result Vector2\r\n */\r\nexport function ComputeYawPitchFromLookAtToRef(\r\n    lookAt: Vector3,\r\n    center: Vector3,\r\n    useRightHandedSystem: boolean,\r\n    currentYaw: number,\r\n    result: Vector2,\r\n    calculateUpVectorFromPointToRef?: (point: Vector3, result: Vector3) => Vector3\r\n): Vector2 {\r\n    // Compute local basis at center\r\n    const east = TmpVectors.Vector3[6];\r\n    const north = TmpVectors.Vector3[7];\r\n    const up = TmpVectors.Vector3[8];\r\n    ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem, calculateUpVectorFromPointToRef);\r\n\r\n    // lookAt = horiz*sinPitch - up*cosPitch\r\n    // where horiz = north*cos(yaw) + east*sin(yaw)\r\n    //\r\n    // The vertical component of lookAt (along up) gives us cosPitch:\r\n    // lookAt · up = -cosPitch\r\n    const lookDotUp = Vector3Dot(lookAt, up);\r\n    const cosPitch = -lookDotUp;\r\n\r\n    // Clamp cosPitch to valid range to avoid NaN from acos\r\n    const clampedCosPitch = Clamp(cosPitch, -1, 1);\r\n    const pitch = Math.acos(clampedCosPitch);\r\n\r\n    // The horizontal component gives us yaw\r\n    // lookHorizontal = lookAt + up*cosPitch = horiz*sinPitch\r\n    const lookHorizontal = TmpVectors.Vector3[9];\r\n    const scaledUp = TmpVectors.Vector3[10];\r\n    scaledUp.copyFrom(up).scaleInPlace(cosPitch);\r\n    lookHorizontal.copyFrom(lookAt).addInPlace(scaledUp);\r\n\r\n    const sinPitch = Math.sin(pitch);\r\n    if (Math.abs(sinPitch) < Epsilon) {\r\n        // Looking straight down or up, yaw is undefined - keep current\r\n        result.x = currentYaw;\r\n        result.y = pitch;\r\n        return result;\r\n    }\r\n\r\n    // horiz = lookHorizontal / sinPitch\r\n    const horiz = lookHorizontal.scaleInPlace(1 / sinPitch);\r\n\r\n    // From the forward formula: horiz = North*cos(yaw) + East*sin(yaw)\r\n    // So: cosYaw = horiz · north, sinYaw = horiz · east\r\n    const cosYaw = Vector3Dot(horiz, north);\r\n    const sinYaw = Vector3Dot(horiz, east);\r\n\r\n    result.x = Math.atan2(sinYaw, cosYaw);\r\n    result.y = pitch;\r\n    return result;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geospatialCamera.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeospatialCamera(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeospatialCamera\", GeospatialCamera);\r\n}\r\n","import { type Nullable, type IndicesArray } from \"../types\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Plane } from \"../Maths/math.plane\";\r\n\r\nconst IntersectBoxAaSphere = (boxMin: Vector3, boxMax: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean => {\r\n    if (boxMin.x > sphereCenter.x + sphereRadius) {\r\n        return false;\r\n    }\r\n\r\n    if (sphereCenter.x - sphereRadius > boxMax.x) {\r\n        return false;\r\n    }\r\n\r\n    if (boxMin.y > sphereCenter.y + sphereRadius) {\r\n        return false;\r\n    }\r\n\r\n    if (sphereCenter.y - sphereRadius > boxMax.y) {\r\n        return false;\r\n    }\r\n\r\n    if (boxMin.z > sphereCenter.z + sphereRadius) {\r\n        return false;\r\n    }\r\n\r\n    if (sphereCenter.z - sphereRadius > boxMax.z) {\r\n        return false;\r\n    }\r\n\r\n    return true;\r\n};\r\n\r\nconst GetLowestRoot: (a: number, b: number, c: number, maxR: number) => { root: number; found: boolean } = (function () {\r\n    const result = { root: 0, found: false };\r\n    return function (a: number, b: number, c: number, maxR: number) {\r\n        result.root = 0;\r\n        result.found = false;\r\n        const determinant = b * b - 4.0 * a * c;\r\n        if (determinant < 0) {\r\n            return result;\r\n        }\r\n\r\n        const sqrtD = Math.sqrt(determinant);\r\n        let r1 = (-b - sqrtD) / (2.0 * a);\r\n        let r2 = (-b + sqrtD) / (2.0 * a);\r\n\r\n        if (r1 > r2) {\r\n            const temp = r2;\r\n            r2 = r1;\r\n            r1 = temp;\r\n        }\r\n\r\n        if (r1 > 0 && r1 < maxR) {\r\n            result.root = r1;\r\n            result.found = true;\r\n            return result;\r\n        }\r\n\r\n        if (r2 > 0 && r2 < maxR) {\r\n            result.root = r2;\r\n            result.found = true;\r\n            return result;\r\n        }\r\n\r\n        return result;\r\n    };\r\n})();\r\n\r\n/** @internal */\r\nexport class Collider {\r\n    // Implementation of the \"Improved Collision detection and Response\" algorithm proposed by Kasper Fauerby\r\n    // https://www.peroxide.dk/papers/collision/collision.pdf\r\n\r\n    /** Define if a collision was found */\r\n    public collisionFound: boolean;\r\n\r\n    /**\r\n     * Define last intersection point in local space\r\n     */\r\n    public intersectionPoint: Vector3;\r\n\r\n    /**\r\n     * Define last collided mesh\r\n     */\r\n    public collidedMesh: Nullable<AbstractMesh>;\r\n\r\n    /**\r\n     * If true, it check for double sided faces and only returns 1 collision instead of 2\r\n     */\r\n    public static DoubleSidedCheck = false;\r\n\r\n    private _collisionPoint = Vector3.Zero();\r\n    private _planeIntersectionPoint = Vector3.Zero();\r\n    private _tempVector = Vector3.Zero();\r\n    private _tempVector2 = Vector3.Zero();\r\n    private _tempVector3 = Vector3.Zero();\r\n    private _tempVector4 = Vector3.Zero();\r\n    private _edge = Vector3.Zero();\r\n    private _baseToVertex = Vector3.Zero();\r\n    private _destinationPoint = Vector3.Zero();\r\n    private _slidePlaneNormal = Vector3.Zero();\r\n    private _displacementVector = Vector3.Zero();\r\n\r\n    /** @internal */\r\n    public _radius = Vector3.One();\r\n    /** @internal */\r\n    public _retry = 0;\r\n    private _velocity: Vector3;\r\n    private _basePoint: Vector3;\r\n    private _epsilon: number;\r\n    /** @internal */\r\n    public _velocityWorldLength: number;\r\n    /** @internal */\r\n    public _basePointWorld = Vector3.Zero();\r\n    private _velocityWorld = Vector3.Zero();\r\n    private _normalizedVelocity = Vector3.Zero();\r\n    /** @internal */\r\n    public _initialVelocity: Vector3;\r\n    /** @internal */\r\n    public _initialPosition: Vector3;\r\n    private _nearestDistance: number;\r\n\r\n    private _collisionMask = -1;\r\n    private _velocitySquaredLength: number;\r\n    private _nearestDistanceSquared: number;\r\n\r\n    public get collisionMask(): number {\r\n        return this._collisionMask;\r\n    }\r\n\r\n    public set collisionMask(mask: number) {\r\n        this._collisionMask = !isNaN(mask) ? mask : -1;\r\n    }\r\n\r\n    /**\r\n     * Gets the plane normal used to compute the sliding response (in local space)\r\n     */\r\n    public get slidePlaneNormal(): Vector3 {\r\n        return this._slidePlaneNormal;\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * @internal\r\n     */\r\n    public _initialize(source: Vector3, dir: Vector3, e: number): void {\r\n        this._velocity = dir;\r\n        this._velocitySquaredLength = this._velocity.lengthSquared();\r\n        const len = Math.sqrt(this._velocitySquaredLength);\r\n        if (len === 0 || len === 1.0) {\r\n            this._normalizedVelocity.copyFromFloats(dir._x, dir._y, dir._z);\r\n        } else {\r\n            dir.scaleToRef(1.0 / len, this._normalizedVelocity);\r\n        }\r\n        this._basePoint = source;\r\n\r\n        source.multiplyToRef(this._radius, this._basePointWorld);\r\n        dir.multiplyToRef(this._radius, this._velocityWorld);\r\n\r\n        this._velocityWorldLength = this._velocityWorld.length();\r\n\r\n        this._epsilon = e;\r\n        this.collisionFound = false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _checkPointInTriangle(point: Vector3, pa: Vector3, pb: Vector3, pc: Vector3, n: Vector3): boolean {\r\n        pa.subtractToRef(point, this._tempVector);\r\n        pb.subtractToRef(point, this._tempVector2);\r\n\r\n        Vector3.CrossToRef(this._tempVector, this._tempVector2, this._tempVector4);\r\n        let d = Vector3.Dot(this._tempVector4, n);\r\n        if (d < 0) {\r\n            return false;\r\n        }\r\n\r\n        pc.subtractToRef(point, this._tempVector3);\r\n        Vector3.CrossToRef(this._tempVector2, this._tempVector3, this._tempVector4);\r\n        d = Vector3.Dot(this._tempVector4, n);\r\n        if (d < 0) {\r\n            return false;\r\n        }\r\n\r\n        Vector3.CrossToRef(this._tempVector3, this._tempVector, this._tempVector4);\r\n        d = Vector3.Dot(this._tempVector4, n);\r\n        return d >= 0;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _canDoCollision(sphereCenter: Vector3, sphereRadius: number, vecMin: Vector3, vecMax: Vector3): boolean {\r\n        const distance = Vector3.Distance(this._basePointWorld, sphereCenter);\r\n\r\n        const max = Math.max(this._radius.x, this._radius.y, this._radius.z);\r\n\r\n        if (distance > this._velocityWorldLength + max + sphereRadius) {\r\n            return false;\r\n        }\r\n\r\n        if (!IntersectBoxAaSphere(vecMin, vecMax, this._basePointWorld, this._velocityWorldLength + max)) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _testTriangle(faceIndex: number, trianglePlaneArray: Array<Plane>, p1: Vector3, p2: Vector3, p3: Vector3, hasMaterial: boolean, hostMesh: AbstractMesh): void {\r\n        let t0;\r\n        let embeddedInPlane = false;\r\n\r\n        //defensive programming, actually not needed.\r\n        if (!trianglePlaneArray) {\r\n            trianglePlaneArray = [];\r\n        }\r\n\r\n        if (!trianglePlaneArray[faceIndex]) {\r\n            trianglePlaneArray[faceIndex] = new Plane(0, 0, 0, 0);\r\n            trianglePlaneArray[faceIndex].copyFromPoints(p1, p2, p3);\r\n        }\r\n\r\n        const trianglePlane = trianglePlaneArray[faceIndex];\r\n\r\n        if (!hasMaterial && !trianglePlane.isFrontFacingTo(this._normalizedVelocity, 0)) {\r\n            return;\r\n        }\r\n\r\n        const signedDistToTrianglePlane = trianglePlane.signedDistanceTo(this._basePoint);\r\n        const normalDotVelocity = Vector3.Dot(trianglePlane.normal, this._velocity);\r\n\r\n        // if DoubleSidedCheck is false(default), a double sided face will be consided 2 times.\r\n        // if true, it discard the faces having normal not facing velocity\r\n        if (Collider.DoubleSidedCheck && normalDotVelocity > 0.0001) {\r\n            return;\r\n        }\r\n\r\n        if (normalDotVelocity == 0) {\r\n            if (Math.abs(signedDistToTrianglePlane) >= 1.0) {\r\n                return;\r\n            }\r\n            embeddedInPlane = true;\r\n            t0 = 0;\r\n        } else {\r\n            t0 = (-1.0 - signedDistToTrianglePlane) / normalDotVelocity;\r\n            let t1 = (1.0 - signedDistToTrianglePlane) / normalDotVelocity;\r\n\r\n            if (t0 > t1) {\r\n                const temp = t1;\r\n                t1 = t0;\r\n                t0 = temp;\r\n            }\r\n\r\n            if (t0 > 1.0 || t1 < 0.0) {\r\n                return;\r\n            }\r\n\r\n            if (t0 < 0) {\r\n                t0 = 0;\r\n            }\r\n            if (t0 > 1.0) {\r\n                t0 = 1.0;\r\n            }\r\n        }\r\n\r\n        this._collisionPoint.copyFromFloats(0, 0, 0);\r\n\r\n        let found = false;\r\n        let t = 1.0;\r\n\r\n        if (!embeddedInPlane) {\r\n            this._basePoint.subtractToRef(trianglePlane.normal, this._planeIntersectionPoint);\r\n            this._velocity.scaleToRef(t0, this._tempVector);\r\n            this._planeIntersectionPoint.addInPlace(this._tempVector);\r\n\r\n            if (this._checkPointInTriangle(this._planeIntersectionPoint, p1, p2, p3, trianglePlane.normal)) {\r\n                found = true;\r\n                t = t0;\r\n                this._collisionPoint.copyFrom(this._planeIntersectionPoint);\r\n            }\r\n        }\r\n\r\n        if (!found) {\r\n            let a = this._velocitySquaredLength;\r\n\r\n            this._basePoint.subtractToRef(p1, this._tempVector);\r\n            let b = 2.0 * Vector3.Dot(this._velocity, this._tempVector);\r\n            let c = this._tempVector.lengthSquared() - 1.0;\r\n\r\n            let lowestRoot = GetLowestRoot(a, b, c, t);\r\n            if (lowestRoot.found) {\r\n                t = lowestRoot.root;\r\n                found = true;\r\n                this._collisionPoint.copyFrom(p1);\r\n            }\r\n\r\n            this._basePoint.subtractToRef(p2, this._tempVector);\r\n            b = 2.0 * Vector3.Dot(this._velocity, this._tempVector);\r\n            c = this._tempVector.lengthSquared() - 1.0;\r\n\r\n            lowestRoot = GetLowestRoot(a, b, c, t);\r\n            if (lowestRoot.found) {\r\n                t = lowestRoot.root;\r\n                found = true;\r\n                this._collisionPoint.copyFrom(p2);\r\n            }\r\n\r\n            this._basePoint.subtractToRef(p3, this._tempVector);\r\n            b = 2.0 * Vector3.Dot(this._velocity, this._tempVector);\r\n            c = this._tempVector.lengthSquared() - 1.0;\r\n\r\n            lowestRoot = GetLowestRoot(a, b, c, t);\r\n            if (lowestRoot.found) {\r\n                t = lowestRoot.root;\r\n                found = true;\r\n                this._collisionPoint.copyFrom(p3);\r\n            }\r\n\r\n            p2.subtractToRef(p1, this._edge);\r\n            p1.subtractToRef(this._basePoint, this._baseToVertex);\r\n            let edgeSquaredLength = this._edge.lengthSquared();\r\n            let edgeDotVelocity = Vector3.Dot(this._edge, this._velocity);\r\n            let edgeDotBaseToVertex = Vector3.Dot(this._edge, this._baseToVertex);\r\n\r\n            a = edgeSquaredLength * -this._velocitySquaredLength + edgeDotVelocity * edgeDotVelocity;\r\n            b = 2 * (edgeSquaredLength * Vector3.Dot(this._velocity, this._baseToVertex) - edgeDotVelocity * edgeDotBaseToVertex);\r\n            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;\r\n\r\n            lowestRoot = GetLowestRoot(a, b, c, t);\r\n            if (lowestRoot.found) {\r\n                const f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;\r\n\r\n                if (f >= 0.0 && f <= 1.0) {\r\n                    t = lowestRoot.root;\r\n                    found = true;\r\n                    this._edge.scaleInPlace(f);\r\n                    p1.addToRef(this._edge, this._collisionPoint);\r\n                }\r\n            }\r\n\r\n            p3.subtractToRef(p2, this._edge);\r\n            p2.subtractToRef(this._basePoint, this._baseToVertex);\r\n            edgeSquaredLength = this._edge.lengthSquared();\r\n            edgeDotVelocity = Vector3.Dot(this._edge, this._velocity);\r\n            edgeDotBaseToVertex = Vector3.Dot(this._edge, this._baseToVertex);\r\n\r\n            a = edgeSquaredLength * -this._velocitySquaredLength + edgeDotVelocity * edgeDotVelocity;\r\n            b = 2 * (edgeSquaredLength * Vector3.Dot(this._velocity, this._baseToVertex) - edgeDotVelocity * edgeDotBaseToVertex);\r\n            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;\r\n            lowestRoot = GetLowestRoot(a, b, c, t);\r\n            if (lowestRoot.found) {\r\n                const f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;\r\n\r\n                if (f >= 0.0 && f <= 1.0) {\r\n                    t = lowestRoot.root;\r\n                    found = true;\r\n                    this._edge.scaleInPlace(f);\r\n                    p2.addToRef(this._edge, this._collisionPoint);\r\n                }\r\n            }\r\n\r\n            p1.subtractToRef(p3, this._edge);\r\n            p3.subtractToRef(this._basePoint, this._baseToVertex);\r\n            edgeSquaredLength = this._edge.lengthSquared();\r\n            edgeDotVelocity = Vector3.Dot(this._edge, this._velocity);\r\n            edgeDotBaseToVertex = Vector3.Dot(this._edge, this._baseToVertex);\r\n\r\n            a = edgeSquaredLength * -this._velocitySquaredLength + edgeDotVelocity * edgeDotVelocity;\r\n            b = 2 * (edgeSquaredLength * Vector3.Dot(this._velocity, this._baseToVertex) - edgeDotVelocity * edgeDotBaseToVertex);\r\n            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;\r\n\r\n            lowestRoot = GetLowestRoot(a, b, c, t);\r\n            if (lowestRoot.found) {\r\n                const f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;\r\n\r\n                if (f >= 0.0 && f <= 1.0) {\r\n                    t = lowestRoot.root;\r\n                    found = true;\r\n                    this._edge.scaleInPlace(f);\r\n                    p3.addToRef(this._edge, this._collisionPoint);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (found) {\r\n            const distToCollisionSquared = t * t * this._velocitySquaredLength;\r\n\r\n            if (!this.collisionFound || distToCollisionSquared < this._nearestDistanceSquared) {\r\n                // if collisionResponse is false, collision is not found but the collidedMesh is set anyway.\r\n                // onCollide observable are triggered if collideMesh is set\r\n                // this allow trigger volumes to be created.\r\n                if (hostMesh.collisionResponse) {\r\n                    if (!this.intersectionPoint) {\r\n                        this.intersectionPoint = this._collisionPoint.clone();\r\n                    } else {\r\n                        this.intersectionPoint.copyFrom(this._collisionPoint);\r\n                    }\r\n                    this._nearestDistanceSquared = distToCollisionSquared;\r\n                    this._nearestDistance = Math.sqrt(distToCollisionSquared);\r\n                    this.collisionFound = true;\r\n                }\r\n                this.collidedMesh = hostMesh;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _collide(\r\n        trianglePlaneArray: Array<Plane>,\r\n        pts: Vector3[],\r\n        indices: IndicesArray,\r\n        indexStart: number,\r\n        indexEnd: number,\r\n        decal: number,\r\n        hasMaterial: boolean,\r\n        hostMesh: AbstractMesh,\r\n        invertTriangles?: boolean,\r\n        triangleStrip: boolean = false\r\n    ): void {\r\n        if (triangleStrip) {\r\n            if (!indices || indices.length === 0) {\r\n                for (let i = 0; i < pts.length - 2; i += 1) {\r\n                    const p1 = pts[i];\r\n                    const p2 = pts[i + 1];\r\n                    const p3 = pts[i + 2];\r\n\r\n                    // stay defensive and don't check against undefined positions.\r\n                    if (!p1 || !p2 || !p3) {\r\n                        continue;\r\n                    }\r\n                    // Handles strip faces one on two is reversed\r\n                    if ((invertTriangles ? 1 : 0) ^ (i % 2)) {\r\n                        this._testTriangle(i, trianglePlaneArray, p1, p2, p3, hasMaterial, hostMesh);\r\n                    } else {\r\n                        this._testTriangle(i, trianglePlaneArray, p2, p1, p3, hasMaterial, hostMesh);\r\n                    }\r\n                }\r\n            } else {\r\n                for (let i = indexStart; i < indexEnd - 2; i += 1) {\r\n                    const indexA = indices[i];\r\n                    const indexB = indices[i + 1];\r\n                    const indexC = indices[i + 2];\r\n\r\n                    if (indexC === 0xffffffff) {\r\n                        i += 2;\r\n                        continue;\r\n                    }\r\n\r\n                    const p1 = pts[indexA];\r\n                    const p2 = pts[indexB];\r\n                    const p3 = pts[indexC];\r\n\r\n                    // stay defensive and don't check against undefined positions.\r\n                    if (!p1 || !p2 || !p3) {\r\n                        continue;\r\n                    }\r\n\r\n                    // Handles strip faces one on two is reversed\r\n                    if ((invertTriangles ? 1 : 0) ^ (i % 2)) {\r\n                        this._testTriangle(i, trianglePlaneArray, p1, p2, p3, hasMaterial, hostMesh);\r\n                    } else {\r\n                        this._testTriangle(i, trianglePlaneArray, p2, p1, p3, hasMaterial, hostMesh);\r\n                    }\r\n                }\r\n            }\r\n        } else if (!indices || indices.length === 0) {\r\n            for (let i = 0; i < pts.length; i += 3) {\r\n                const p1 = pts[i];\r\n                const p2 = pts[i + 1];\r\n                const p3 = pts[i + 2];\r\n\r\n                if (invertTriangles) {\r\n                    this._testTriangle(i, trianglePlaneArray, p1, p2, p3, hasMaterial, hostMesh);\r\n                } else {\r\n                    this._testTriangle(i, trianglePlaneArray, p3, p2, p1, hasMaterial, hostMesh);\r\n                }\r\n            }\r\n        } else {\r\n            for (let i = indexStart; i < indexEnd; i += 3) {\r\n                const p1 = pts[indices[i] - decal];\r\n                const p2 = pts[indices[i + 1] - decal];\r\n                const p3 = pts[indices[i + 2] - decal];\r\n\r\n                if (invertTriangles) {\r\n                    this._testTriangle(i, trianglePlaneArray, p1, p2, p3, hasMaterial, hostMesh);\r\n                } else {\r\n                    this._testTriangle(i, trianglePlaneArray, p3, p2, p1, hasMaterial, hostMesh);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getResponse(pos: Vector3, vel: Vector3, slideOnCollide: boolean): void {\r\n        // Handle straight movement up to collision\r\n\r\n        pos.addToRef(vel, this._destinationPoint);\r\n\r\n        if (!slideOnCollide) {\r\n            // Move to one \"close distance\" less than the collision point to\r\n            // prevent any collision penetration from floating point inaccuracy\r\n            vel.scaleInPlace((this._nearestDistance - this._epsilon) / vel.length());\r\n            this._basePoint.addToRef(vel, pos);\r\n            return;\r\n        } else {\r\n            vel.scaleInPlace(this._nearestDistance / vel.length());\r\n            this._basePoint.addToRef(vel, pos);\r\n        }\r\n\r\n        // Handle slide movement past collision\r\n\r\n        pos.subtractToRef(this.intersectionPoint, this._slidePlaneNormal);\r\n        this._slidePlaneNormal.normalize();\r\n        this._slidePlaneNormal.scaleToRef(this._epsilon, this._displacementVector);\r\n\r\n        pos.addInPlace(this._displacementVector);\r\n        this.intersectionPoint.addInPlace(this._displacementVector);\r\n\r\n        this._slidePlaneNormal.scaleInPlace(Plane.SignedDistanceToPlaneFromPositionAndNormal(this.intersectionPoint, this._slidePlaneNormal, this._destinationPoint));\r\n        this._destinationPoint.subtractInPlace(this._slidePlaneNormal);\r\n\r\n        this._destinationPoint.subtractToRef(this.intersectionPoint, vel);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Collider } from \"./collider\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n\r\n/** @internal */\r\nexport interface ICollisionCoordinator {\r\n    createCollider(): Collider;\r\n    getNewPosition(\r\n        position: Vector3,\r\n        displacement: Vector3,\r\n        collider: Collider,\r\n        maximumRetry: number,\r\n        excludedMesh: Nullable<AbstractMesh>,\r\n        onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void,\r\n        collisionIndex: number,\r\n        slideOnCollide?: boolean\r\n    ): Vector3;\r\n    init(scene: Scene): void;\r\n}\r\n\r\n/** @internal */\r\nexport class DefaultCollisionCoordinator implements ICollisionCoordinator {\r\n    private _scene: Scene;\r\n\r\n    private _scaledPosition = Vector3.Zero();\r\n    private _scaledVelocity = Vector3.Zero();\r\n\r\n    private _finalPosition = Vector3.Zero();\r\n\r\n    public getNewPosition(\r\n        position: Vector3,\r\n        displacement: Vector3,\r\n        collider: Collider,\r\n        maximumRetry: number,\r\n        excludedMesh: AbstractMesh,\r\n        onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void,\r\n        collisionIndex: number,\r\n        slideOnCollide: boolean = true\r\n    ): Vector3 {\r\n        position.divideToRef(collider._radius, this._scaledPosition);\r\n        displacement.divideToRef(collider._radius, this._scaledVelocity);\r\n        collider.collidedMesh = null;\r\n        collider._retry = 0;\r\n        collider._initialVelocity = this._scaledVelocity;\r\n        collider._initialPosition = this._scaledPosition;\r\n        this._collideWithWorld(this._scaledPosition, this._scaledVelocity, collider, maximumRetry, this._finalPosition, slideOnCollide, excludedMesh);\r\n\r\n        this._finalPosition.multiplyInPlace(collider._radius);\r\n        //run the callback\r\n        onNewPosition(collisionIndex, this._finalPosition, collider.collidedMesh);\r\n\r\n        return this._finalPosition;\r\n    }\r\n\r\n    public createCollider(): Collider {\r\n        return new Collider();\r\n    }\r\n\r\n    public init(scene: Scene): void {\r\n        this._scene = scene;\r\n    }\r\n\r\n    private _collideWithWorld(\r\n        position: Vector3,\r\n        velocity: Vector3,\r\n        collider: Collider,\r\n        maximumRetry: number,\r\n        finalPosition: Vector3,\r\n        slideOnCollide: boolean,\r\n        excludedMesh: Nullable<AbstractMesh> = null\r\n    ): void {\r\n        const closeDistance = AbstractEngine.CollisionsEpsilon * 10.0;\r\n\r\n        if (collider._retry >= maximumRetry) {\r\n            finalPosition.copyFrom(position);\r\n            return;\r\n        }\r\n\r\n        // Check if this is a mesh else camera or -1\r\n        const collisionMask = excludedMesh ? excludedMesh.collisionMask : collider.collisionMask;\r\n\r\n        collider._initialize(position, velocity, closeDistance);\r\n\r\n        // Check if collision detection should happen against specified list of meshes or,\r\n        // if not specified, against all meshes in the scene\r\n        const meshes = (excludedMesh && excludedMesh.surroundingMeshes) || this._scene.meshes;\r\n\r\n        for (let index = 0; index < meshes.length; index++) {\r\n            const mesh = meshes[index];\r\n            if (mesh.isEnabled() && mesh.checkCollisions && mesh.subMeshes && mesh !== excludedMesh && (collisionMask & mesh.collisionGroup) !== 0) {\r\n                mesh._checkCollision(collider);\r\n            }\r\n        }\r\n\r\n        if (!collider.collisionFound) {\r\n            position.addToRef(velocity, finalPosition);\r\n            return;\r\n        }\r\n\r\n        if (velocity.x !== 0 || velocity.y !== 0 || velocity.z !== 0) {\r\n            collider._getResponse(position, velocity, slideOnCollide);\r\n            // Halt all movement at the first collision, if not slideOnCollide\r\n            if (!slideOnCollide) {\r\n                velocity.setAll(0);\r\n            }\r\n        }\r\n\r\n        if (velocity.length() <= closeDistance) {\r\n            finalPosition.copyFrom(position);\r\n            return;\r\n        }\r\n\r\n        collider._retry++;\r\n        this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, slideOnCollide, excludedMesh);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for collisionCoordinator.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCollisionCoordinator(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.CollisionCoordinatorFactory = () => {\r\n        return new DefaultCollisionCoordinator();\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { type IMultiRenderTargetOptions } from \"../../Materials/Textures/multiRenderTarget.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../constants\";\r\nimport { ThinEngine } from \"../thinEngine.pure\";\r\nimport { type RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { type WebGLRenderTargetWrapper } from \"../WebGL/webGLRenderTargetWrapper\";\r\nimport { type WebGLHardwareTexture } from \"../WebGL/webGLHardwareTexture\";\r\nimport { type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { type IColor4Like } from \"../../Maths/math.like\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { IsIntegerTextureFormat, IsUnsignedIntegerTextureType } from \"../../Materials/Textures/textureHelper.functions\";\r\n\r\nlet _Registered = false;\r\nconst _UnsignedIntegerClearColor = /*#__PURE__*/ new Color4();\r\nconst _SignedIntegerClearColor = /*#__PURE__*/ new Color4();\r\n/**\r\n * Register side effects for enginesExtensionsEngineMultiRender.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineMultiRender(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.restoreSingleAttachment = function (): void {\r\n        const gl = this._gl;\r\n\r\n        this.bindAttachments([gl.BACK]);\r\n    };\r\n\r\n    ThinEngine.prototype.restoreSingleAttachmentForRenderTarget = function (): void {\r\n        const gl = this._gl;\r\n\r\n        this.bindAttachments([gl.COLOR_ATTACHMENT0]);\r\n    };\r\n\r\n    ThinEngine.prototype.buildTextureLayout = function (textureStatus: boolean[], backBufferLayout = false): number[] {\r\n        const gl = this._gl;\r\n\r\n        const result = [];\r\n\r\n        if (backBufferLayout) {\r\n            result.push(gl.BACK);\r\n        } else {\r\n            for (let i = 0; i < textureStatus.length; i++) {\r\n                if (textureStatus[i]) {\r\n                    result.push((<any>gl)[\"COLOR_ATTACHMENT\" + i]);\r\n                } else {\r\n                    result.push(gl.NONE);\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    ThinEngine.prototype.bindAttachments = function (attachments: number[]): void {\r\n        const gl = this._gl;\r\n        const textures = this._currentRenderTarget?.textures;\r\n\r\n        this._integerMRTAttachmentsMask = 0;\r\n        if (textures) {\r\n            for (let index = 0; index < attachments.length; index++) {\r\n                if (attachments[index] !== gl.NONE && textures[index] && IsIntegerTextureFormat(textures[index].format)) {\r\n                    this._integerMRTAttachmentsMask |= 1 << index;\r\n                }\r\n            }\r\n        }\r\n\r\n        gl.drawBuffers(attachments);\r\n    };\r\n\r\n    ThinEngine.prototype.clearAttachments = function (\r\n        color: Nullable<IColor4Like>,\r\n        attachments: number[],\r\n        clearColor: boolean,\r\n        clearDepth: boolean,\r\n        clearStencil = false,\r\n        stencilClearValue = 0\r\n    ): void {\r\n        const textures = this._currentRenderTarget?.textures;\r\n        let hasIntegerAttachment = false;\r\n        if (clearColor && color && textures) {\r\n            for (let index = 0; index < attachments.length; index++) {\r\n                const texture = textures[index];\r\n                if (attachments[index] !== this._gl.NONE && texture && IsIntegerTextureFormat(texture.format)) {\r\n                    if (this._webGLVersion < 2) {\r\n                        throw new Error(\"ThinEngine.clearAttachments: integer MRT attachments require WebGL2\");\r\n                    }\r\n                    hasIntegerAttachment = true;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!hasIntegerAttachment || !color || !textures) {\r\n            this.bindAttachments(attachments);\r\n            this.clear(color, clearColor, clearDepth, clearStencil, stencilClearValue);\r\n            return;\r\n        }\r\n\r\n        this.bindAttachments(attachments);\r\n        this._applyColorWriteState();\r\n        for (let index = 0; index < attachments.length; index++) {\r\n            const texture = textures[index];\r\n            if (attachments[index] !== this._gl.NONE && texture) {\r\n                let clearValue = color;\r\n                if (IsIntegerTextureFormat(texture.format)) {\r\n                    const unsigned = IsUnsignedIntegerTextureType(texture.type);\r\n                    clearValue = unsigned ? _UnsignedIntegerClearColor : _SignedIntegerClearColor;\r\n                    const scale = unsigned ? 255 : 1;\r\n                    clearValue.r = Math.round(color.r * scale);\r\n                    clearValue.g = Math.round(color.g * scale);\r\n                    clearValue.b = Math.round(color.b * scale);\r\n                    clearValue.a = Math.round(color.a * scale);\r\n                }\r\n                this._clearColorAttachment(index, clearValue, texture.format, texture.type);\r\n            }\r\n        }\r\n        if (clearDepth || clearStencil) {\r\n            const integerMRTAttachmentsMask = this._integerMRTAttachmentsMask;\r\n            this._integerMRTAttachmentsMask = 0;\r\n            try {\r\n                this.clear(null, false, clearDepth, clearStencil, stencilClearValue);\r\n            } finally {\r\n                this._integerMRTAttachmentsMask = integerMRTAttachmentsMask;\r\n            }\r\n        }\r\n    };\r\n\r\n    ThinEngine.prototype.unBindMultiColorAttachmentFramebuffer = function (\r\n        rtWrapper: WebGLRenderTargetWrapper,\r\n        disableGenerateMipMaps: boolean = false,\r\n        onBeforeUnbind?: () => void\r\n    ): void {\r\n        this._currentRenderTarget = null;\r\n        this._integerMRTAttachmentsMask = 0;\r\n\r\n        if (!rtWrapper.disableAutomaticMSAAResolve) {\r\n            this.resolveMultiFramebuffer(rtWrapper);\r\n        }\r\n\r\n        if (!disableGenerateMipMaps) {\r\n            this.generateMipMapsMultiFramebuffer(rtWrapper);\r\n        }\r\n\r\n        if (onBeforeUnbind) {\r\n            if (rtWrapper._MSAAFramebuffer) {\r\n                // Bind the correct framebuffer\r\n                this._bindUnboundFramebuffer(rtWrapper._framebuffer);\r\n            }\r\n            onBeforeUnbind();\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(null);\r\n    };\r\n\r\n    ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, options: IMultiRenderTargetOptions, initializeBuffers: boolean = true): RenderTargetWrapper {\r\n        let generateMipMaps = false;\r\n        let generateDepthBuffer = true;\r\n        let generateStencilBuffer = false;\r\n        let generateDepthTexture = false;\r\n        let depthTextureFormat: number | undefined = undefined;\r\n        let textureCount = 1;\r\n        let samples = 1;\r\n\r\n        const defaultType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        const defaultSamplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n        const defaultUseSRGBBuffer = false;\r\n        const defaultFormat = Constants.TEXTUREFORMAT_RGBA;\r\n        const defaultTarget = Constants.TEXTURE_2D;\r\n\r\n        let types: number[] = [];\r\n        let samplingModes: number[] = [];\r\n        let useSRGBBuffers: boolean[] = [];\r\n        let formats: number[] = [];\r\n        let targets: number[] = [];\r\n        let faceIndex: number[] = [];\r\n        let layerIndex: number[] = [];\r\n        let layers: number[] = [];\r\n        let labels: string[] = [];\r\n        let dontCreateTextures = false;\r\n\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(true, false, size) as WebGLRenderTargetWrapper;\r\n\r\n        if (options !== undefined) {\r\n            generateMipMaps = options.generateMipMaps === undefined ? false : options.generateMipMaps;\r\n            generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;\r\n            generateStencilBuffer = options.generateStencilBuffer === undefined ? false : options.generateStencilBuffer;\r\n            generateDepthTexture = options.generateDepthTexture === undefined ? false : options.generateDepthTexture;\r\n            textureCount = options.textureCount ?? 1;\r\n            samples = options.samples ?? samples;\r\n            types = options.types || types;\r\n            samplingModes = options.samplingModes || samplingModes;\r\n            useSRGBBuffers = options.useSRGBBuffers || useSRGBBuffers;\r\n            formats = options.formats || formats;\r\n            targets = options.targetTypes || targets;\r\n            faceIndex = options.faceIndex || faceIndex;\r\n            layerIndex = options.layerIndex || layerIndex;\r\n            layers = options.layerCounts || layers;\r\n            labels = options.labels || labels;\r\n            dontCreateTextures = options.dontCreateTextures ?? false;\r\n\r\n            if (\r\n                this.webGLVersion > 1 &&\r\n                (options.depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 ||\r\n                    options.depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 ||\r\n                    options.depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24 ||\r\n                    options.depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH32_FLOAT ||\r\n                    options.depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8)\r\n            ) {\r\n                depthTextureFormat = options.depthTextureFormat;\r\n            }\r\n        }\r\n\r\n        if (depthTextureFormat === undefined) {\r\n            depthTextureFormat = generateStencilBuffer ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT;\r\n        }\r\n\r\n        const gl = this._gl;\r\n        // Create the framebuffer\r\n        const currentFramebuffer = this._currentFramebuffer;\r\n        const framebuffer = gl.createFramebuffer();\r\n        this._bindUnboundFramebuffer(framebuffer);\r\n\r\n        const width = (<{ width: number; height: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number }>size).height ?? <number>size;\r\n\r\n        const textures: InternalTexture[] = [];\r\n        const attachments: number[] = [];\r\n\r\n        const useStencilTexture =\r\n            this.webGLVersion > 1 &&\r\n            (depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 ||\r\n                depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 ||\r\n                depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8);\r\n\r\n        rtWrapper.label = options?.label ?? \"MultiRenderTargetWrapper\";\r\n        rtWrapper._framebuffer = framebuffer;\r\n        rtWrapper._generateDepthBuffer = generateDepthTexture || generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = generateDepthTexture ? useStencilTexture : generateStencilBuffer;\r\n        rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(\r\n            rtWrapper._generateStencilBuffer,\r\n            rtWrapper._generateDepthBuffer,\r\n            width,\r\n            height,\r\n            1,\r\n            depthTextureFormat\r\n        );\r\n        rtWrapper._attachments = attachments;\r\n\r\n        for (let i = 0; i < textureCount; i++) {\r\n            let samplingMode = samplingModes[i] || defaultSamplingMode;\r\n            let type = types[i] || defaultType;\r\n            let useSRGBBuffer = useSRGBBuffers[i] || defaultUseSRGBBuffer;\r\n            const format = formats[i] || defaultFormat;\r\n\r\n            const target = targets[i] || defaultTarget;\r\n            const layerCount = layers[i] ?? 1;\r\n\r\n            if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n                // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n                samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n                // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n                samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            }\r\n\r\n            const filters = this._getSamplingParameters(samplingMode, generateMipMaps);\r\n            if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n                type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                Logger.Warn(\"Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type\");\r\n            }\r\n\r\n            useSRGBBuffer = useSRGBBuffer && this._caps.supportSRGBBuffers && (this.webGLVersion > 1 || this.isWebGPU);\r\n\r\n            const isWebGL2 = this.webGLVersion > 1;\r\n            const attachment = (<any>gl)[isWebGL2 ? \"COLOR_ATTACHMENT\" + i : \"COLOR_ATTACHMENT\" + i + \"_WEBGL\"];\r\n\r\n            attachments.push(attachment);\r\n\r\n            if (target === -1 || dontCreateTextures) {\r\n                continue;\r\n            }\r\n\r\n            const texture = new InternalTexture(this, InternalTextureSource.MultiRenderTarget);\r\n            textures[i] = texture;\r\n\r\n            gl.activeTexture((<any>gl)[\"TEXTURE\" + i]);\r\n            gl.bindTexture(target, texture._hardwareTexture!.underlyingResource);\r\n\r\n            gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, filters.mag);\r\n            gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, filters.min);\r\n            gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n            gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n            const internalSizedFormat = this._getRGBABufferInternalSizedFormat(type, format, useSRGBBuffer);\r\n            const internalFormat = this._getInternalFormat(format);\r\n            const webGLTextureType = this._getWebGLTextureType(type);\r\n\r\n            if (isWebGL2 && (target === Constants.TEXTURE_2D_ARRAY || target === Constants.TEXTURE_3D)) {\r\n                if (target === Constants.TEXTURE_2D_ARRAY) {\r\n                    texture.is2DArray = true;\r\n                } else {\r\n                    texture.is3D = true;\r\n                }\r\n\r\n                texture.baseDepth = texture.depth = layerCount;\r\n\r\n                gl.texImage3D(target, 0, internalSizedFormat, width, height, layerCount, 0, internalFormat, webGLTextureType, null);\r\n            } else if (target === Constants.TEXTURE_CUBE_MAP) {\r\n                // We have to generate all faces to complete the framebuffer\r\n                for (let i = 0; i < 6; i++) {\r\n                    gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalSizedFormat, width, height, 0, internalFormat, webGLTextureType, null);\r\n                }\r\n                texture.isCube = true;\r\n            } else {\r\n                gl.texImage2D(gl.TEXTURE_2D, 0, internalSizedFormat, width, height, 0, internalFormat, webGLTextureType, null);\r\n            }\r\n\r\n            if (generateMipMaps) {\r\n                gl.generateMipmap(target);\r\n            }\r\n\r\n            // Unbind\r\n            this._bindTextureDirectly(target, null);\r\n\r\n            texture.baseWidth = width;\r\n            texture.baseHeight = height;\r\n            texture.width = width;\r\n            texture.height = height;\r\n            texture.isReady = true;\r\n            texture.samples = 1;\r\n            texture.generateMipMaps = generateMipMaps;\r\n            texture.samplingMode = samplingMode;\r\n            texture.type = type;\r\n            texture._useSRGBBuffer = useSRGBBuffer;\r\n            texture.format = format;\r\n            texture.label = labels[i] ?? rtWrapper.label + \"-Texture\" + i;\r\n\r\n            this._internalTexturesCache.push(texture);\r\n        }\r\n\r\n        if (generateDepthTexture && this._caps.depthTextureExtension && !dontCreateTextures) {\r\n            // Depth texture\r\n            const depthTexture = new InternalTexture(this, InternalTextureSource.Depth);\r\n\r\n            let depthTextureType = Constants.TEXTURETYPE_UNSIGNED_SHORT;\r\n            let glDepthTextureInternalFormat: GLenum = gl.DEPTH_COMPONENT16;\r\n            let glDepthTextureFormat: GLenum = gl.DEPTH_COMPONENT;\r\n            let glDepthTextureType: GLenum = gl.UNSIGNED_SHORT;\r\n            let glDepthTextureAttachment: GLenum = gl.DEPTH_ATTACHMENT;\r\n            if (this.webGLVersion < 2) {\r\n                glDepthTextureInternalFormat = gl.DEPTH_COMPONENT;\r\n            } else {\r\n                if (depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH32_FLOAT) {\r\n                    depthTextureType = Constants.TEXTURETYPE_FLOAT;\r\n                    glDepthTextureType = gl.FLOAT;\r\n                    glDepthTextureInternalFormat = gl.DEPTH_COMPONENT32F;\r\n                } else if (depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8) {\r\n                    depthTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                    glDepthTextureType = gl.FLOAT_32_UNSIGNED_INT_24_8_REV;\r\n                    glDepthTextureInternalFormat = gl.DEPTH32F_STENCIL8;\r\n                    glDepthTextureFormat = gl.DEPTH_STENCIL;\r\n                    glDepthTextureAttachment = gl.DEPTH_STENCIL_ATTACHMENT;\r\n                } else if (depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24) {\r\n                    depthTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                    glDepthTextureType = gl.UNSIGNED_INT;\r\n                    glDepthTextureInternalFormat = gl.DEPTH_COMPONENT24;\r\n                    glDepthTextureAttachment = gl.DEPTH_ATTACHMENT;\r\n                } else if (depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 || depthTextureFormat === Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8) {\r\n                    depthTextureType = Constants.TEXTURETYPE_UNSIGNED_INT_24_8;\r\n                    glDepthTextureType = gl.UNSIGNED_INT_24_8;\r\n                    glDepthTextureInternalFormat = gl.DEPTH24_STENCIL8;\r\n                    glDepthTextureFormat = gl.DEPTH_STENCIL;\r\n                    glDepthTextureAttachment = gl.DEPTH_STENCIL_ATTACHMENT;\r\n                }\r\n            }\r\n\r\n            this._bindTextureDirectly(gl.TEXTURE_2D, depthTexture, true);\r\n\r\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n            gl.texImage2D(gl.TEXTURE_2D, 0, glDepthTextureInternalFormat, width, height, 0, glDepthTextureFormat, glDepthTextureType, null);\r\n\r\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, glDepthTextureAttachment, gl.TEXTURE_2D, depthTexture._hardwareTexture!.underlyingResource, 0);\r\n\r\n            this._bindTextureDirectly(gl.TEXTURE_2D, null);\r\n\r\n            rtWrapper._depthStencilTexture = depthTexture;\r\n            rtWrapper._depthStencilTextureWithStencil = useStencilTexture;\r\n\r\n            depthTexture.baseWidth = width;\r\n            depthTexture.baseHeight = height;\r\n            depthTexture.width = width;\r\n            depthTexture.height = height;\r\n            depthTexture.isReady = true;\r\n            depthTexture.samples = 1;\r\n            depthTexture.generateMipMaps = generateMipMaps;\r\n            depthTexture.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            depthTexture.format = depthTextureFormat;\r\n            depthTexture.type = depthTextureType;\r\n            depthTexture.label = rtWrapper.label + \"-DepthStencil\";\r\n\r\n            textures[textureCount] = depthTexture;\r\n            this._internalTexturesCache.push(depthTexture);\r\n        }\r\n        rtWrapper.setTextures(textures);\r\n        if (initializeBuffers) {\r\n            gl.drawBuffers(attachments);\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(currentFramebuffer);\r\n\r\n        rtWrapper.setLayerAndFaceIndices(layerIndex, faceIndex);\r\n\r\n        this.resetTextureCache();\r\n\r\n        if (!dontCreateTextures) {\r\n            this.updateMultipleRenderTargetTextureSampleCount(rtWrapper, samples, initializeBuffers);\r\n        } else if (samples > 1) {\r\n            const framebuffer = gl.createFramebuffer();\r\n\r\n            if (!framebuffer) {\r\n                throw new Error(\"Unable to create multi sampled framebuffer\");\r\n            }\r\n\r\n            rtWrapper._samples = samples;\r\n            rtWrapper._MSAAFramebuffer = framebuffer;\r\n\r\n            if (textureCount > 0 && initializeBuffers) {\r\n                this._bindUnboundFramebuffer(framebuffer);\r\n                gl.drawBuffers(attachments);\r\n                this._bindUnboundFramebuffer(currentFramebuffer);\r\n            }\r\n        }\r\n\r\n        return rtWrapper;\r\n    };\r\n\r\n    ThinEngine.prototype.updateMultipleRenderTargetTextureSampleCount = function (\r\n        rtWrapper: Nullable<WebGLRenderTargetWrapper>,\r\n        samples: number,\r\n        initializeBuffers: boolean = true\r\n    ): number {\r\n        if (this.webGLVersion < 2 || !rtWrapper) {\r\n            return 1;\r\n        }\r\n\r\n        if (rtWrapper.samples === samples) {\r\n            return samples;\r\n        }\r\n\r\n        const gl = this._gl;\r\n\r\n        samples = Math.min(samples, this.getCaps().maxMSAASamples);\r\n\r\n        // Dispose previous render buffers\r\n        if (rtWrapper._depthStencilBuffer) {\r\n            gl.deleteRenderbuffer(rtWrapper._depthStencilBuffer);\r\n            rtWrapper._depthStencilBuffer = null;\r\n        }\r\n\r\n        if (rtWrapper._MSAAFramebuffer) {\r\n            gl.deleteFramebuffer(rtWrapper._MSAAFramebuffer);\r\n            rtWrapper._MSAAFramebuffer = null;\r\n        }\r\n\r\n        const count = rtWrapper._attachments!.length; // We do it this way instead of rtWrapper.textures.length to avoid taking into account the depth/stencil texture, in case it has been created\r\n\r\n        for (let i = 0; i < count; i++) {\r\n            const texture = rtWrapper.textures![i];\r\n            const hardwareTexture = texture._hardwareTexture as Nullable<WebGLHardwareTexture>;\r\n\r\n            hardwareTexture?.releaseMSAARenderBuffers();\r\n        }\r\n\r\n        if (samples > 1 && typeof gl.renderbufferStorageMultisample === \"function\") {\r\n            const framebuffer = gl.createFramebuffer();\r\n\r\n            if (!framebuffer) {\r\n                throw new Error(\"Unable to create multi sampled framebuffer\");\r\n            }\r\n\r\n            rtWrapper._MSAAFramebuffer = framebuffer;\r\n            this._bindUnboundFramebuffer(framebuffer);\r\n\r\n            const attachments = [];\r\n\r\n            for (let i = 0; i < count; i++) {\r\n                const texture = rtWrapper.textures![i];\r\n                const hardwareTexture = texture._hardwareTexture as WebGLHardwareTexture;\r\n                const attachment = (<any>gl)[this.webGLVersion > 1 ? \"COLOR_ATTACHMENT\" + i : \"COLOR_ATTACHMENT\" + i + \"_WEBGL\"];\r\n\r\n                const colorRenderbuffer = this._createRenderBuffer(\r\n                    texture.width,\r\n                    texture.height,\r\n                    samples,\r\n                    -1 /* not used */,\r\n                    this._getRGBABufferInternalSizedFormat(texture.type, texture.format, texture._useSRGBBuffer),\r\n                    attachment\r\n                );\r\n\r\n                if (!colorRenderbuffer) {\r\n                    throw new Error(\"Unable to create multi sampled framebuffer\");\r\n                }\r\n\r\n                hardwareTexture.addMSAARenderBuffer(colorRenderbuffer);\r\n                texture.samples = samples;\r\n\r\n                attachments.push(attachment);\r\n            }\r\n            if (initializeBuffers) {\r\n                gl.drawBuffers(attachments);\r\n            }\r\n        } else {\r\n            this._bindUnboundFramebuffer(rtWrapper._framebuffer);\r\n        }\r\n\r\n        const depthFormat = rtWrapper._depthStencilTexture ? rtWrapper._depthStencilTexture.format : undefined;\r\n\r\n        rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(\r\n            rtWrapper._generateStencilBuffer,\r\n            rtWrapper._generateDepthBuffer,\r\n            rtWrapper.width,\r\n            rtWrapper.height,\r\n            samples,\r\n            depthFormat\r\n        );\r\n\r\n        this._bindUnboundFramebuffer(null);\r\n\r\n        rtWrapper._samples = samples;\r\n\r\n        return samples;\r\n    };\r\n\r\n    ThinEngine.prototype.generateMipMapsMultiFramebuffer = function (texture: RenderTargetWrapper): void {\r\n        const rtWrapper = texture as WebGLRenderTargetWrapper;\r\n        const gl = this._gl;\r\n\r\n        if (!rtWrapper.isMulti) {\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < rtWrapper._attachments!.length; i++) {\r\n            const texture = rtWrapper.textures![i];\r\n            if (texture?.generateMipMaps && !texture?.isCube && !texture?.is3D) {\r\n                this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);\r\n                gl.generateMipmap(gl.TEXTURE_2D);\r\n                this._bindTextureDirectly(gl.TEXTURE_2D, null);\r\n            }\r\n        }\r\n    };\r\n\r\n    ThinEngine.prototype.resolveMultiFramebuffer = function (texture: RenderTargetWrapper): void {\r\n        const rtWrapper = texture as WebGLRenderTargetWrapper;\r\n        const gl = this._gl;\r\n\r\n        if (!rtWrapper._MSAAFramebuffer || !rtWrapper.isMulti) {\r\n            return;\r\n        }\r\n\r\n        let bufferBits = rtWrapper.resolveMSAAColors ? gl.COLOR_BUFFER_BIT : 0;\r\n        bufferBits |= rtWrapper._generateDepthBuffer && rtWrapper.resolveMSAADepth ? gl.DEPTH_BUFFER_BIT : 0;\r\n        bufferBits |= rtWrapper._generateStencilBuffer && rtWrapper.resolveMSAAStencil ? gl.STENCIL_BUFFER_BIT : 0;\r\n\r\n        const attachments = rtWrapper._attachments!;\r\n        const count = attachments.length;\r\n\r\n        gl.bindFramebuffer(gl.READ_FRAMEBUFFER, rtWrapper._MSAAFramebuffer);\r\n        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, rtWrapper._framebuffer);\r\n\r\n        for (let i = 0; i < count; i++) {\r\n            const texture = rtWrapper.textures![i];\r\n\r\n            for (let j = 0; j < count; j++) {\r\n                attachments[j] = gl.NONE;\r\n            }\r\n\r\n            attachments[i] = (<any>gl)[this.webGLVersion > 1 ? \"COLOR_ATTACHMENT\" + i : \"COLOR_ATTACHMENT\" + i + \"_WEBGL\"];\r\n            gl.readBuffer(attachments[i]);\r\n            gl.drawBuffers(attachments);\r\n            gl.blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width, texture.height, bufferBits, gl.NEAREST);\r\n        }\r\n\r\n        for (let i = 0; i < count; i++) {\r\n            attachments[i] = (<any>gl)[this.webGLVersion > 1 ? \"COLOR_ATTACHMENT\" + i : \"COLOR_ATTACHMENT\" + i + \"_WEBGL\"];\r\n        }\r\n\r\n        gl.drawBuffers(attachments);\r\n        gl.bindFramebuffer(this._gl.FRAMEBUFFER, rtWrapper._MSAAFramebuffer);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type Engine } from \"../../Engines/engine.pure\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\n\r\nimport { type InternalTexture } from \"./internalTexture\";\r\nimport { RegisterEnginesExtensionsEngineMultiRender } from \"../../Engines/Extensions/engine.multiRender.pure\";\r\n\r\n/**\r\n * Creation options of the multi render target texture.\r\n */\r\nexport interface IMultiRenderTargetOptions {\r\n    /**\r\n     * Specifies if mipmaps must be created. If undefined, the value from generateMipMaps is taken instead\r\n     */\r\n    createMipMaps?: boolean;\r\n    /**\r\n     * Define if the texture needs to create mip maps after render (default: false).\r\n     */\r\n    generateMipMaps?: boolean;\r\n    /**\r\n     * Define the types of all the draw buffers (render textures) we want to create\r\n     */\r\n    types?: number[];\r\n    /**\r\n     * Define the sampling modes of all the draw buffers (render textures) we want to create\r\n     */\r\n    samplingModes?: number[];\r\n    /**\r\n     * Define if sRGB format should be used for each of the draw buffers (render textures) we want to create\r\n     */\r\n    useSRGBBuffers?: boolean[];\r\n    /**\r\n     * Define if a depth buffer is required (default: true)\r\n     */\r\n    generateDepthBuffer?: boolean;\r\n    /**\r\n     * Define if a stencil buffer is required (default: false)\r\n     */\r\n    generateStencilBuffer?: boolean;\r\n    /**\r\n     * Define if a depth texture is required instead of a depth buffer (default: false)\r\n     */\r\n    generateDepthTexture?: boolean;\r\n    /**\r\n     * Define the internal format of the buffer in the RTT (RED, RG, RGB, RGBA (default), ALPHA...) of all the draw buffers (render textures) we want to create\r\n     */\r\n    formats?: number[];\r\n    /**\r\n     * Define depth texture format to use\r\n     */\r\n    depthTextureFormat?: number;\r\n    /**\r\n     * Define the number of desired draw buffers (render textures). You can set it to 0 if you don't need any color attachment. (default: 1)\r\n     */\r\n    textureCount?: number;\r\n    /**\r\n     * Define if aspect ratio should be adapted to the texture or stay the scene one (default: true)\r\n     */\r\n    doNotChangeAspectRatio?: boolean;\r\n    /**\r\n     * Define the default type of the buffers we are creating (default: Constants.TEXTURETYPE_UNSIGNED_BYTE). types[] is prioritized over defaultType if provided.\r\n     */\r\n    defaultType?: number;\r\n    /**\r\n     * Defines sample count (1 by default)\r\n     */\r\n    samples?: number;\r\n    /**\r\n     * Defines if we should draw into all attachments or the first one only by default (default: false)\r\n     */\r\n    drawOnlyOnFirstAttachmentByDefault?: boolean;\r\n    /**\r\n     * Define the type of texture at each attahment index (of Constants.TEXTURE_2D, .TEXTURE_2D_ARRAY, .TEXTURE_CUBE_MAP, .TEXTURE_CUBE_MAP_ARRAY, .TEXTURE_3D).\r\n     * You can also use the -1 value to indicate that no texture should be created but that you will assign a texture to that attachment index later.\r\n     * Can be useful when you want to attach several layers of the same 2DArrayTexture / 3DTexture or several faces of the same CubeMapTexture: Use the setInternalTexture\r\n     * method for that purpose, after the MultiRenderTarget has been created.\r\n     */\r\n    targetTypes?: number[];\r\n    /**\r\n     * Define the face index of each texture in the textures array (if applicable, given the corresponding targetType) at creation time (for Constants.TEXTURE_CUBE_MAP and .TEXTURE_CUBE_MAP_ARRAY).\r\n     * Can be changed at any time by calling setLayerAndFaceIndices or setLayerAndFaceIndex\r\n     */\r\n    faceIndex?: number[];\r\n    /**\r\n     * Define the layer index of each texture in the textures array (if applicable, given the corresponding targetType) at creation time (for Constants.TEXTURE_3D, .TEXTURE_2D_ARRAY, and .TEXTURE_CUBE_MAP_ARRAY).\r\n     * Can be changed at any time by calling setLayerAndFaceIndices or setLayerAndFaceIndex\r\n     */\r\n    layerIndex?: number[];\r\n    /**\r\n     * Define the number of layer of each texture in the textures array (if applicable, given the corresponding targetType) (for Constants.TEXTURE_3D, .TEXTURE_2D_ARRAY, and .TEXTURE_CUBE_MAP_ARRAY)\r\n     */\r\n    layerCounts?: number[];\r\n    /**\r\n     * Define the creation flags of the textures (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     */\r\n    creationFlags?: number[];\r\n    /**\r\n     * Define the names of the textures (used for debugging purpose)\r\n     */\r\n    labels?: string[];\r\n    /**\r\n     * Label of the RenderTargetWrapper (used for debugging only)\r\n     */\r\n    label?: string;\r\n    /**\r\n     * Define if the textures should not be created by the MultiRenderTarget (default: false)\r\n     * If true, you will need to set the textures yourself by calling setTexture on the MultiRenderTarget.\r\n     */\r\n    dontCreateTextures?: boolean;\r\n}\r\n\r\n/**\r\n * A multi render target, like a render target provides the ability to render to a texture.\r\n * Unlike the render target, it can render to several draw buffers (render textures) in one draw.\r\n * This is specially interesting in deferred rendering or for any effects requiring more than\r\n * just one color from a single pass.\r\n */\r\nexport class MultiRenderTarget extends RenderTargetTexture {\r\n    private _textures: Texture[];\r\n    private _multiRenderTargetOptions: IMultiRenderTargetOptions;\r\n    private _count: number;\r\n    private _drawOnlyOnFirstAttachmentByDefault: boolean;\r\n    private _textureNames?: string[];\r\n\r\n    /**\r\n     * Get if draw buffers (render textures) are currently supported by the used hardware and browser.\r\n     */\r\n    public get isSupported(): boolean {\r\n        return this._engine?.getCaps().drawBuffersExtension ?? false;\r\n    }\r\n\r\n    /**\r\n     * Get the list of textures generated by the multi render target.\r\n     */\r\n    public get textures(): Texture[] {\r\n        return this._textures;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of textures in this MRT. This number can be different from `_textures.length` in case a depth texture is generated.\r\n     */\r\n    public get count(): number {\r\n        return this._count;\r\n    }\r\n\r\n    /**\r\n     * Get the depth texture generated by the multi render target if options.generateDepthTexture has been set\r\n     */\r\n    public get depthTexture(): Texture {\r\n        return this._textures[this._textures.length - 1];\r\n    }\r\n\r\n    /**\r\n     * Set the wrapping mode on U of all the textures we are rendering to.\r\n     * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)\r\n     */\r\n    public override set wrapU(wrap: number) {\r\n        if (this._textures) {\r\n            for (let i = 0; i < this._textures.length; i++) {\r\n                this._textures[i].wrapU = wrap;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the wrapping mode on V of all the textures we are rendering to.\r\n     * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)\r\n     */\r\n    public override set wrapV(wrap: number) {\r\n        if (this._textures) {\r\n            for (let i = 0; i < this._textures.length; i++) {\r\n                this._textures[i].wrapV = wrap;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiate a new multi render target texture.\r\n     * A multi render target, like a render target provides the ability to render to a texture.\r\n     * Unlike the render target, it can render to several draw buffers (render textures) in one draw.\r\n     * This is specially interesting in deferred rendering or for any effects requiring more than\r\n     * just one color from a single pass.\r\n     * @param name Define the name of the texture\r\n     * @param size Define the size of the buffers to render to\r\n     * @param count Define the number of target we are rendering into\r\n     * @param scene Define the scene the texture belongs to\r\n     * @param options Define the options used to create the multi render target\r\n     * @param textureNames Define the names to set to the textures (if count \\> 0 - optional)\r\n     */\r\n    constructor(name: string, size: any, count: number, scene?: Scene, options?: IMultiRenderTargetOptions, textureNames?: string[]) {\r\n        const generateMipMaps = options && options.generateMipMaps ? options.generateMipMaps : false;\r\n        const generateDepthTexture = options && options.generateDepthTexture ? options.generateDepthTexture : false;\r\n        const depthTextureFormat = options && options.depthTextureFormat ? options.depthTextureFormat : Constants.TEXTUREFORMAT_DEPTH16;\r\n        const doNotChangeAspectRatio = !options || options.doNotChangeAspectRatio === undefined ? true : options.doNotChangeAspectRatio;\r\n        const drawOnlyOnFirstAttachmentByDefault = options && options.drawOnlyOnFirstAttachmentByDefault ? options.drawOnlyOnFirstAttachmentByDefault : false;\r\n        super(name, size, scene, generateMipMaps, doNotChangeAspectRatio, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true);\r\n\r\n        RegisterEnginesExtensionsEngineMultiRender();\r\n\r\n        if (!this.isSupported) {\r\n            this.dispose();\r\n            return;\r\n        }\r\n\r\n        this._textureNames = textureNames;\r\n\r\n        const types: number[] = [];\r\n        const samplingModes: number[] = [];\r\n        const useSRGBBuffers: boolean[] = [];\r\n        const formats: number[] = [];\r\n        const targetTypes: number[] = [];\r\n        const faceIndex: number[] = [];\r\n        const layerIndex: number[] = [];\r\n        const layerCounts: number[] = [];\r\n        this._initTypes(count, types, samplingModes, useSRGBBuffers, formats, targetTypes, faceIndex, layerIndex, layerCounts, options);\r\n\r\n        const generateDepthBuffer = !options || options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;\r\n        const generateStencilBuffer = !options || options.generateStencilBuffer === undefined ? false : options.generateStencilBuffer;\r\n        const samples = options && options.samples ? options.samples : 1;\r\n\r\n        this._multiRenderTargetOptions = {\r\n            samplingModes: samplingModes,\r\n            generateMipMaps: generateMipMaps,\r\n            generateDepthBuffer: generateDepthBuffer,\r\n            generateStencilBuffer: generateStencilBuffer,\r\n            generateDepthTexture: generateDepthTexture,\r\n            depthTextureFormat: depthTextureFormat,\r\n            types: types,\r\n            textureCount: count,\r\n            useSRGBBuffers: useSRGBBuffers,\r\n            samples,\r\n            formats: formats,\r\n            targetTypes: targetTypes,\r\n            faceIndex: faceIndex,\r\n            layerIndex: layerIndex,\r\n            layerCounts: layerCounts,\r\n            labels: textureNames,\r\n            label: name,\r\n        };\r\n\r\n        this._count = count;\r\n        this._drawOnlyOnFirstAttachmentByDefault = drawOnlyOnFirstAttachmentByDefault;\r\n\r\n        if (count > 0) {\r\n            this._createInternalTextures();\r\n            this._createTextures(textureNames);\r\n        }\r\n    }\r\n\r\n    private _initTypes(\r\n        count: number,\r\n        types: number[],\r\n        samplingModes: number[],\r\n        useSRGBBuffers: boolean[],\r\n        formats: number[],\r\n        targets: number[],\r\n        faceIndex: number[],\r\n        layerIndex: number[],\r\n        layerCounts: number[],\r\n        options?: IMultiRenderTargetOptions\r\n    ) {\r\n        for (let i = 0; i < count; i++) {\r\n            if (options && options.types && options.types[i] !== undefined) {\r\n                types.push(options.types[i]);\r\n            } else {\r\n                types.push(options && options.defaultType ? options.defaultType : Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n            }\r\n\r\n            if (options && options.samplingModes && options.samplingModes[i] !== undefined) {\r\n                samplingModes.push(options.samplingModes[i]);\r\n            } else {\r\n                samplingModes.push(Texture.BILINEAR_SAMPLINGMODE);\r\n            }\r\n\r\n            if (options && options.useSRGBBuffers && options.useSRGBBuffers[i] !== undefined) {\r\n                useSRGBBuffers.push(options.useSRGBBuffers[i]);\r\n            } else {\r\n                useSRGBBuffers.push(false);\r\n            }\r\n\r\n            if (options && options.formats && options.formats[i] !== undefined) {\r\n                formats.push(options.formats[i]);\r\n            } else {\r\n                formats.push(Constants.TEXTUREFORMAT_RGBA);\r\n            }\r\n\r\n            if (options && options.targetTypes && options.targetTypes[i] !== undefined) {\r\n                targets.push(options.targetTypes[i]);\r\n            } else {\r\n                targets.push(Constants.TEXTURE_2D);\r\n            }\r\n\r\n            if (options && options.faceIndex && options.faceIndex[i] !== undefined) {\r\n                faceIndex.push(options.faceIndex[i]);\r\n            } else {\r\n                faceIndex.push(0);\r\n            }\r\n\r\n            if (options && options.layerIndex && options.layerIndex[i] !== undefined) {\r\n                layerIndex.push(options.layerIndex[i]);\r\n            } else {\r\n                layerIndex.push(0);\r\n            }\r\n\r\n            if (options && options.layerCounts && options.layerCounts[i] !== undefined) {\r\n                layerCounts.push(options.layerCounts[i]);\r\n            } else {\r\n                layerCounts.push(1);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _createInternaTextureIndexMapping() {\r\n        const mapMainInternalTexture2Index: { [key: number]: number } = {};\r\n        const mapInternalTexture2MainIndex: number[] = [];\r\n\r\n        if (!this._renderTarget) {\r\n            return mapInternalTexture2MainIndex;\r\n        }\r\n\r\n        const internalTextures = this._renderTarget.textures!;\r\n        for (let i = 0; i < internalTextures.length; i++) {\r\n            const texture = internalTextures[i];\r\n            if (!texture) {\r\n                continue;\r\n            }\r\n            const mainIndex = mapMainInternalTexture2Index[texture.uniqueId];\r\n            if (mainIndex !== undefined) {\r\n                mapInternalTexture2MainIndex[i] = mainIndex;\r\n            } else {\r\n                mapMainInternalTexture2Index[texture.uniqueId] = i;\r\n            }\r\n        }\r\n\r\n        return mapInternalTexture2MainIndex;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _rebuild(fromContextLost = false, forceFullRebuild: boolean = false, textureNames?: string[]): void {\r\n        if (this._count < 1 || fromContextLost) {\r\n            return;\r\n        }\r\n\r\n        const mapInternalTexture2MainIndex = this._createInternaTextureIndexMapping();\r\n\r\n        this.releaseInternalTextures();\r\n        this._createInternalTextures();\r\n\r\n        if (forceFullRebuild) {\r\n            this._releaseTextures();\r\n            this._createTextures(textureNames);\r\n        }\r\n\r\n        const internalTextures = this._renderTarget!.textures!;\r\n        for (let i = 0; i < internalTextures.length; i++) {\r\n            const texture = this._textures[i];\r\n            if (mapInternalTexture2MainIndex[i] !== undefined) {\r\n                this._renderTarget!.setTexture(internalTextures[mapInternalTexture2MainIndex[i]], i);\r\n            }\r\n            texture._texture = internalTextures[i];\r\n            if (texture._texture) {\r\n                texture._noMipmap = !texture._texture.useMipMaps;\r\n                texture._useSRGBBuffer = texture._texture._useSRGBBuffer;\r\n            }\r\n        }\r\n\r\n        if (this.samples !== 1) {\r\n            this._renderTarget!.setSamples(this.samples, !this._drawOnlyOnFirstAttachmentByDefault, true);\r\n        }\r\n    }\r\n\r\n    private _createInternalTextures(): void {\r\n        this._renderTarget = this._getEngine()!.createMultipleRenderTarget(this._size, this._multiRenderTargetOptions, !this._drawOnlyOnFirstAttachmentByDefault);\r\n        this._texture = this._renderTarget.texture;\r\n    }\r\n\r\n    private _releaseTextures(): void {\r\n        if (this._textures) {\r\n            for (let i = 0; i < this._textures.length; i++) {\r\n                this._textures[i]._texture = null; // internal textures are released by a call to releaseInternalTextures()\r\n                this._textures[i].dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _createTextures(textureNames?: string[]): void {\r\n        const internalTextures = this._renderTarget!.textures!;\r\n        this._textures = [];\r\n        for (let i = 0; i < internalTextures.length; i++) {\r\n            const texture = new Texture(null, this.getScene());\r\n            if (textureNames?.[i]) {\r\n                texture.name = textureNames[i];\r\n            }\r\n            texture._texture = internalTextures[i];\r\n            if (texture._texture) {\r\n                texture._noMipmap = !texture._texture.useMipMaps;\r\n                texture._useSRGBBuffer = texture._texture._useSRGBBuffer;\r\n            }\r\n            this._textures.push(texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Replaces an internal texture within the MRT. Useful to share textures between MultiRenderTarget.\r\n     * @param texture The new texture to set in the MRT\r\n     * @param index The index of the texture to replace\r\n     * @param disposePrevious Set to true if the previous internal texture should be disposed\r\n     */\r\n    public setInternalTexture(texture: InternalTexture, index: number, disposePrevious: boolean = true) {\r\n        if (!this.renderTarget) {\r\n            return;\r\n        }\r\n\r\n        if (index === 0) {\r\n            this._texture = texture;\r\n        }\r\n\r\n        this.renderTarget.setTexture(texture, index, disposePrevious);\r\n\r\n        if (!this.textures[index]) {\r\n            this.textures[index] = new Texture(null, this.getScene());\r\n            this.textures[index].name = this._textureNames?.[index] ?? this.textures[index].name;\r\n        }\r\n        this.textures[index]._texture = texture;\r\n        this.textures[index]._noMipmap = !texture.useMipMaps;\r\n        this.textures[index]._useSRGBBuffer = texture._useSRGBBuffer;\r\n\r\n        this._count = this.renderTarget.textures ? this.renderTarget.textures.length : 0;\r\n\r\n        if (this._multiRenderTargetOptions.types) {\r\n            this._multiRenderTargetOptions.types[index] = texture.type;\r\n        }\r\n        if (this._multiRenderTargetOptions.samplingModes) {\r\n            this._multiRenderTargetOptions.samplingModes[index] = texture.samplingMode;\r\n        }\r\n        if (this._multiRenderTargetOptions.useSRGBBuffers) {\r\n            this._multiRenderTargetOptions.useSRGBBuffers[index] = texture._useSRGBBuffer;\r\n        }\r\n        if (this._multiRenderTargetOptions.targetTypes && this._multiRenderTargetOptions.targetTypes[index] !== -1) {\r\n            let target: number;\r\n            if (texture.is2DArray) {\r\n                target = Constants.TEXTURE_2D_ARRAY;\r\n            } else if (texture.isCube) {\r\n                target = Constants.TEXTURE_CUBE_MAP;\r\n            } /*else if (texture.isCubeArray) {\r\n                target = Constants.TEXTURE_CUBE_MAP_ARRAY;\r\n            }*/ else if (texture.is3D) {\r\n                target = Constants.TEXTURE_3D;\r\n            } else {\r\n                target = Constants.TEXTURE_2D;\r\n            }\r\n            this._multiRenderTargetOptions.targetTypes[index] = target;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Changes an attached texture's face index or layer.\r\n     * @param index The index of the texture to modify the attachment of\r\n     * @param layerIndex The layer index of the texture to be attached to the framebuffer\r\n     * @param faceIndex The face index of the texture to be attached to the framebuffer\r\n     */\r\n    public setLayerAndFaceIndex(index: number, layerIndex: number = -1, faceIndex: number = -1) {\r\n        if (!this.textures[index] || !this.renderTarget) {\r\n            return;\r\n        }\r\n\r\n        if (this._multiRenderTargetOptions.layerIndex) {\r\n            this._multiRenderTargetOptions.layerIndex[index] = layerIndex;\r\n        }\r\n        if (this._multiRenderTargetOptions.faceIndex) {\r\n            this._multiRenderTargetOptions.faceIndex[index] = faceIndex;\r\n        }\r\n\r\n        this.renderTarget.setLayerAndFaceIndex(index, layerIndex, faceIndex);\r\n    }\r\n\r\n    /**\r\n     * Changes every attached texture's face index or layer.\r\n     * @param layerIndices The layer indices of the texture to be attached to the framebuffer\r\n     * @param faceIndices The face indices of the texture to be attached to the framebuffer\r\n     */\r\n    public setLayerAndFaceIndices(layerIndices: number[], faceIndices: number[]) {\r\n        if (!this.renderTarget) {\r\n            return;\r\n        }\r\n\r\n        this._multiRenderTargetOptions.layerIndex = layerIndices;\r\n        this._multiRenderTargetOptions.faceIndex = faceIndices;\r\n\r\n        this.renderTarget.setLayerAndFaceIndices(layerIndices, faceIndices);\r\n    }\r\n\r\n    /**\r\n     * Define the number of samples used if MSAA is enabled.\r\n     */\r\n    public override get samples(): number {\r\n        return this._samples;\r\n    }\r\n\r\n    public override set samples(value: number) {\r\n        if (this._renderTarget) {\r\n            this._samples = this._renderTarget.setSamples(value);\r\n        } else {\r\n            // In case samples are set with 0 textures created, we must save the desired samples value\r\n            this._samples = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resize all the textures in the multi render target.\r\n     * Be careful as it will recreate all the data in the new texture.\r\n     * @param size Define the new size\r\n     */\r\n    public override resize(size: any) {\r\n        this._processSizeParameter(size);\r\n        this._rebuild(false, undefined, this._textureNames);\r\n    }\r\n\r\n    /**\r\n     * Changes the number of render targets in this MRT\r\n     * Be careful as it will recreate all the data in the new texture.\r\n     * @param count new texture count\r\n     * @param options Specifies texture types and sampling modes for new textures\r\n     * @param textureNames Specifies the names of the textures (optional)\r\n     */\r\n    public updateCount(count: number, options?: IMultiRenderTargetOptions, textureNames?: string[]) {\r\n        this._multiRenderTargetOptions.textureCount = count;\r\n        this._count = count;\r\n\r\n        const types: number[] = [];\r\n        const samplingModes: number[] = [];\r\n        const useSRGBBuffers: boolean[] = [];\r\n        const formats: number[] = [];\r\n        const targetTypes: number[] = [];\r\n        const faceIndex: number[] = [];\r\n        const layerIndex: number[] = [];\r\n        const layerCounts: number[] = [];\r\n\r\n        this._textureNames = textureNames;\r\n\r\n        this._initTypes(count, types, samplingModes, useSRGBBuffers, formats, targetTypes, faceIndex, layerIndex, layerCounts, options);\r\n        this._multiRenderTargetOptions.types = types;\r\n        this._multiRenderTargetOptions.samplingModes = samplingModes;\r\n        this._multiRenderTargetOptions.useSRGBBuffers = useSRGBBuffers;\r\n        this._multiRenderTargetOptions.formats = formats;\r\n        this._multiRenderTargetOptions.targetTypes = targetTypes;\r\n        this._multiRenderTargetOptions.faceIndex = faceIndex;\r\n        this._multiRenderTargetOptions.layerIndex = layerIndex;\r\n        this._multiRenderTargetOptions.layerCounts = layerCounts;\r\n        this._multiRenderTargetOptions.labels = textureNames;\r\n\r\n        this._rebuild(false, true, textureNames);\r\n    }\r\n\r\n    protected override _unbindFrameBuffer(engine: Engine, faceIndex: number): void {\r\n        if (this._renderTarget) {\r\n            engine.unBindMultiColorAttachmentFramebuffer(this._renderTarget, this.isCube, () => {\r\n                this.onAfterRenderObservable.notifyObservers(faceIndex);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the render targets and their associated resources\r\n     * @param doNotDisposeInternalTextures if set to true, internal textures won't be disposed (default: false).\r\n     */\r\n    public override dispose(doNotDisposeInternalTextures = false): void {\r\n        this._releaseTextures();\r\n        if (!doNotDisposeInternalTextures) {\r\n            this.releaseInternalTextures();\r\n        } else {\r\n            // Prevent internal texture dispose in super.dispose\r\n            this._texture = null;\r\n        }\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Release all the underlying texture used as draw buffers (render textures).\r\n     */\r\n    public releaseInternalTextures(): void {\r\n        const internalTextures = this._renderTarget?.textures;\r\n\r\n        if (!internalTextures) {\r\n            return;\r\n        }\r\n\r\n        for (let i = internalTextures.length - 1; i >= 0; i--) {\r\n            this._textures[i]._texture = null;\r\n        }\r\n\r\n        this._renderTarget?.dispose();\r\n        this._renderTarget = null;\r\n    }\r\n}\r\n","import { type Observer } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type Material } from \"./material\";\r\nimport { type IEffectCreationOptions, Effect } from \"./effect\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Node } from \"../node\";\r\nimport { type ShadowGenerator } from \"../Lights/Shadows/shadowGenerator\";\r\nimport { RandomGUID } from \"../Misc/guid\";\r\nimport { DrawWrapper } from \"./drawWrapper\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\n\r\n/**\r\n * Options to be used when creating a shadow depth material\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface IIOptionShadowDepthMaterial {\r\n    /** Variables in the vertex shader code that need to have their names remapped.\r\n     * The format is: [\"var_name\", \"var_remapped_name\", \"var_name\", \"var_remapped_name\", ...]\r\n     * \"var_name\" should be either: worldPos or vNormalW\r\n     * So, if the variable holding the world position in your vertex shader is not named worldPos, you must tell the system\r\n     * the name to use instead by using: [\"worldPos\", \"myWorldPosVar\"] assuming the variable is named myWorldPosVar in your code.\r\n     * If the normal must also be remapped: [\"worldPos\", \"myWorldPosVar\", \"vNormalW\", \"myWorldNormal\"]\r\n     */\r\n    remappedVariables?: string[];\r\n\r\n    /** Set standalone to true if the base material wrapped by ShadowDepthMaterial is not used for a regular object but for depth shadow generation only */\r\n    standalone?: boolean;\r\n\r\n    /** Set doNotInjectCode if the specific shadow map generation code is already implemented by the material. That will prevent this code to be injected twice by ShadowDepthWrapper */\r\n    doNotInjectCode?: boolean;\r\n}\r\n\r\nclass MapMap<Ka, Kb, V> {\r\n    readonly mm = new Map<Ka, Map<Kb, V>>();\r\n\r\n    get(a: Ka, b: Kb): V | undefined {\r\n        const m = this.mm.get(a);\r\n        if (m !== undefined) {\r\n            return m.get(b);\r\n        }\r\n        return undefined;\r\n    }\r\n\r\n    set(a: Ka, b: Kb, v: V): void {\r\n        let m = this.mm.get(a);\r\n        if (m === undefined) {\r\n            this.mm.set(a, (m = new Map()));\r\n        }\r\n        m.set(b, v);\r\n    }\r\n}\r\n\r\n/**\r\n * Class that can be used to wrap a base material to generate accurate shadows when using custom vertex/fragment code in the base material\r\n */\r\nexport class ShadowDepthWrapper {\r\n    private _scene: Scene;\r\n    private _options?: IIOptionShadowDepthMaterial;\r\n    private _baseMaterial: Material;\r\n    private _onEffectCreatedObserver: Nullable<Observer<{ effect: Effect; subMesh: Nullable<SubMesh> }>>;\r\n    private _subMeshToEffect: Map<Nullable<SubMesh>, [Effect, number]>;\r\n    private _subMeshToDepthWrapper: MapMap<\r\n        Nullable<SubMesh>,\r\n        ShadowGenerator,\r\n        { drawWrapper: Array<Nullable<DrawWrapper>>; mainDrawWrapper: DrawWrapper; depthDefines: string; token: string }\r\n    >; // key is (subMesh + shadowGenerator)\r\n    private _meshes: Map<AbstractMesh, Nullable<Observer<Node>>>;\r\n\r\n    /** Gets the standalone status of the wrapper */\r\n    public get standalone(): boolean {\r\n        return this._options?.standalone ?? false;\r\n    }\r\n\r\n    /** Gets the base material the wrapper is built upon */\r\n    public get baseMaterial(): Material {\r\n        return this._baseMaterial;\r\n    }\r\n\r\n    /** Gets the doNotInjectCode status of the wrapper */\r\n    public get doNotInjectCode(): boolean {\r\n        return this._options?.doNotInjectCode ?? false;\r\n    }\r\n\r\n    /**\r\n     * Instantiate a new shadow depth wrapper.\r\n     * It works by injecting some specific code in the vertex/fragment shaders of the base material and is used by a shadow generator to\r\n     * generate the shadow depth map. For more information, please refer to the documentation:\r\n     * https://doc.babylonjs.com/features/featuresDeepDive/lights/shadows\r\n     * @param baseMaterial Material to wrap\r\n     * @param scene Define the scene the material belongs to\r\n     * @param options Options used to create the wrapper\r\n     */\r\n    constructor(baseMaterial: Material, scene?: Scene, options?: IIOptionShadowDepthMaterial) {\r\n        this._baseMaterial = baseMaterial;\r\n        this._scene = scene ?? <Scene>EngineStore.LastCreatedScene;\r\n        this._options = options;\r\n\r\n        this._subMeshToEffect = new Map();\r\n        this._subMeshToDepthWrapper = new MapMap();\r\n        this._meshes = new Map();\r\n\r\n        // Register for onEffectCreated to store the effect of the base material when it is (re)generated. This effect will be used\r\n        // to create the depth effect later on\r\n        this._onEffectCreatedObserver = this._baseMaterial.onEffectCreatedObservable.add((params: { effect: Effect; subMesh: Nullable<SubMesh> }) => {\r\n            const mesh = params.subMesh?.getMesh();\r\n\r\n            if (mesh && !this._meshes.has(mesh)) {\r\n                // Register for mesh onDispose to clean up our internal maps when a mesh is disposed\r\n                this._meshes.set(\r\n                    mesh,\r\n                    mesh.onDisposeObservable.add((mesh: Node) => {\r\n                        const iterator = this._subMeshToEffect.keys();\r\n                        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                            const subMesh = key.value;\r\n                            if (subMesh?.getMesh() === (mesh as AbstractMesh)) {\r\n                                this._subMeshToEffect.delete(subMesh);\r\n                                this._deleteDepthWrapperEffect(subMesh);\r\n                            }\r\n                        }\r\n                    })\r\n                );\r\n            }\r\n\r\n            if (this._subMeshToEffect.get(params.subMesh)?.[0] !== params.effect) {\r\n                this._subMeshToEffect.set(params.subMesh, [params.effect, this._scene.getEngine().currentRenderPassId]);\r\n                this._deleteDepthWrapperEffect(params.subMesh);\r\n            }\r\n        });\r\n    }\r\n\r\n    private _deleteDepthWrapperEffect(subMesh: Nullable<SubMesh>): void {\r\n        const depthWrapperEntries = this._subMeshToDepthWrapper.mm.get(subMesh);\r\n        if (depthWrapperEntries) {\r\n            // find and release the previous depth effect\r\n            depthWrapperEntries.forEach((depthWrapper) => {\r\n                depthWrapper.mainDrawWrapper.effect?.dispose();\r\n            });\r\n            this._subMeshToDepthWrapper.mm.delete(subMesh); // trigger a depth effect recreation\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the effect to use to generate the depth map\r\n     * @param subMesh subMesh to get the effect for\r\n     * @param shadowGenerator shadow generator to get the effect for\r\n     * @param passIdForDrawWrapper Id of the pass for which the effect from the draw wrapper must be retrieved from\r\n     * @returns the effect to use to generate the depth map for the subMesh + shadow generator specified\r\n     */\r\n    public getEffect(subMesh: Nullable<SubMesh>, shadowGenerator: ShadowGenerator, passIdForDrawWrapper: number): Nullable<DrawWrapper> {\r\n        const entry = this._subMeshToDepthWrapper.mm.get(subMesh)?.get(shadowGenerator);\r\n        if (!entry) {\r\n            return null;\r\n        }\r\n        let drawWrapper = entry.drawWrapper[passIdForDrawWrapper];\r\n        if (!drawWrapper) {\r\n            drawWrapper = entry.drawWrapper[passIdForDrawWrapper] = new DrawWrapper(this._scene.getEngine());\r\n            drawWrapper.setEffect(entry.mainDrawWrapper.effect, entry.mainDrawWrapper.defines);\r\n        }\r\n\r\n        return drawWrapper;\r\n    }\r\n\r\n    /**\r\n     * Specifies that the submesh is ready to be used for depth rendering\r\n     * @param subMesh submesh to check\r\n     * @param defines the list of defines to take into account when checking the effect\r\n     * @param shadowGenerator combined with subMesh, it defines the effect to check\r\n     * @param useInstances specifies that instances should be used\r\n     * @param passIdForDrawWrapper Id of the pass for which the draw wrapper should be created\r\n     * @returns a boolean indicating that the submesh is ready or not\r\n     */\r\n    public isReadyForSubMesh(subMesh: SubMesh, defines: string[], shadowGenerator: ShadowGenerator, useInstances: boolean, passIdForDrawWrapper: number): boolean {\r\n        if (this.standalone) {\r\n            // will ensure the effect is (re)created for the base material\r\n            if (!this._baseMaterial.isReadyForSubMesh(subMesh.getMesh(), subMesh, useInstances)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return this._makeEffect(subMesh, defines, shadowGenerator, passIdForDrawWrapper)?.isReady() ?? false;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources\r\n     */\r\n    public dispose(): void {\r\n        this._baseMaterial.onEffectCreatedObservable.remove(this._onEffectCreatedObserver);\r\n        this._onEffectCreatedObserver = null;\r\n\r\n        const iterator = this._meshes.entries();\r\n        for (let entry = iterator.next(); entry.done !== true; entry = iterator.next()) {\r\n            const [mesh, observer] = entry.value;\r\n\r\n            mesh.onDisposeObservable.remove(observer);\r\n        }\r\n    }\r\n\r\n    private _makeEffect(subMesh: SubMesh, defines: string[], shadowGenerator: ShadowGenerator, passIdForDrawWrapper: number): Nullable<Effect> {\r\n        const engine = this._scene.getEngine();\r\n        const origEffectAndRenderPassId = this._subMeshToEffect.get(subMesh);\r\n\r\n        if (!origEffectAndRenderPassId) {\r\n            return null;\r\n        }\r\n\r\n        const [origEffect, origRenderPassId] = origEffectAndRenderPassId;\r\n\r\n        if (!origEffect.isReady()) {\r\n            return null;\r\n        }\r\n\r\n        let params = this._subMeshToDepthWrapper.get(subMesh, shadowGenerator);\r\n        if (!params) {\r\n            const mainDrawWrapper = new DrawWrapper(engine);\r\n            const originalDefines = subMesh._getDrawWrapper(origRenderPassId)?.defines;\r\n            mainDrawWrapper.defines = typeof originalDefines === \"string\" ? null : (originalDefines ?? null);\r\n\r\n            params = {\r\n                drawWrapper: [],\r\n                mainDrawWrapper,\r\n                depthDefines: \"\",\r\n                token: RandomGUID(),\r\n            };\r\n            params.drawWrapper[passIdForDrawWrapper] = mainDrawWrapper;\r\n            this._subMeshToDepthWrapper.set(subMesh, shadowGenerator, params);\r\n        }\r\n\r\n        const join = defines.join(\"\\n\");\r\n\r\n        if (params.mainDrawWrapper.effect) {\r\n            if (join === params.depthDefines) {\r\n                // we already created the depth effect and it is still up to date for this submesh + shadow generator\r\n                return params.mainDrawWrapper.effect;\r\n            }\r\n        }\r\n\r\n        params.depthDefines = join;\r\n\r\n        const uniforms = origEffect.getUniformNames().slice();\r\n\r\n        // the depth effect is either out of date or has not been created yet\r\n        let vertexCode = origEffect.vertexSourceCodeBeforeMigration,\r\n            fragmentCode = origEffect.fragmentSourceCodeBeforeMigration;\r\n\r\n        if (!vertexCode && !fragmentCode) {\r\n            return null;\r\n        }\r\n\r\n        if (!this.doNotInjectCode) {\r\n            // Declare the shadow map includes\r\n            const vertexNormalBiasCode =\r\n                    this._options && this._options.remappedVariables\r\n                        ? `#include<shadowMapVertexNormalBias>(${this._options.remappedVariables.join(\",\")})`\r\n                        : `#include<shadowMapVertexNormalBias>`,\r\n                vertexMetricCode =\r\n                    this._options && this._options.remappedVariables\r\n                        ? `#include<shadowMapVertexMetric>(${this._options.remappedVariables.join(\",\")})`\r\n                        : `#include<shadowMapVertexMetric>`,\r\n                fragmentSoftTransparentShadow =\r\n                    this._options && this._options.remappedVariables\r\n                        ? `#include<shadowMapFragmentSoftTransparentShadow>(${this._options.remappedVariables.join(\",\")})`\r\n                        : `#include<shadowMapFragmentSoftTransparentShadow>`,\r\n                fragmentBlockCode = `#include<shadowMapFragment>`,\r\n                vertexExtraDeclartion = `#include<shadowMapVertexExtraDeclaration>`;\r\n\r\n            // vertex code\r\n            if (origEffect.shaderLanguage === ShaderLanguage.GLSL) {\r\n                vertexCode = vertexCode.replace(/void\\s+?main/g, `\\n${vertexExtraDeclartion}\\nvoid main`);\r\n            } else {\r\n                vertexCode = vertexCode.replace(/@vertex/g, `\\n${vertexExtraDeclartion}\\n@vertex`);\r\n            }\r\n            vertexCode = vertexCode.replace(/#define SHADOWDEPTH_NORMALBIAS|#define CUSTOM_VERTEX_UPDATE_WORLDPOS/g, vertexNormalBiasCode);\r\n\r\n            if (vertexCode.indexOf(\"#define SHADOWDEPTH_METRIC\") !== -1) {\r\n                vertexCode = vertexCode.replace(/#define SHADOWDEPTH_METRIC/g, vertexMetricCode);\r\n            } else {\r\n                vertexCode = vertexCode.replace(/}\\s*$/g, vertexMetricCode + \"\\n}\");\r\n            }\r\n            vertexCode = vertexCode.replace(/#define SHADER_NAME.*?\\n|out vec4 glFragColor;\\n/g, \"\");\r\n\r\n            // fragment code\r\n            const hasLocationForSoftTransparentShadow =\r\n                fragmentCode.indexOf(\"#define SHADOWDEPTH_SOFTTRANSPARENTSHADOW\") >= 0 || fragmentCode.indexOf(\"#define CUSTOM_FRAGMENT_BEFORE_FOG\") >= 0;\r\n            const hasLocationForFragment = fragmentCode.indexOf(\"#define SHADOWDEPTH_FRAGMENT\") !== -1;\r\n\r\n            let fragmentCodeToInjectAtEnd = \"\";\r\n\r\n            if (!hasLocationForSoftTransparentShadow) {\r\n                fragmentCodeToInjectAtEnd = fragmentSoftTransparentShadow + \"\\n\";\r\n            } else {\r\n                fragmentCode = fragmentCode.replace(/#define SHADOWDEPTH_SOFTTRANSPARENTSHADOW|#define CUSTOM_FRAGMENT_BEFORE_FOG/g, fragmentSoftTransparentShadow);\r\n            }\r\n\r\n            fragmentCode = fragmentCode.replace(/void\\s+?main/g, Effect.IncludesShadersStore[\"shadowMapFragmentExtraDeclaration\"] + \"\\nvoid main\");\r\n\r\n            if (hasLocationForFragment) {\r\n                fragmentCode = fragmentCode.replace(/#define SHADOWDEPTH_FRAGMENT/g, fragmentBlockCode);\r\n            } else {\r\n                fragmentCodeToInjectAtEnd += fragmentBlockCode + \"\\n\";\r\n            }\r\n            if (fragmentCodeToInjectAtEnd) {\r\n                fragmentCode = fragmentCode.replace(/}\\s*$/g, fragmentCodeToInjectAtEnd + \"}\");\r\n            }\r\n\r\n            uniforms.push(\"biasAndScaleSM\", \"depthValuesSM\", \"lightDataSM\", \"softTransparentShadowSM\");\r\n        }\r\n\r\n        params.mainDrawWrapper.effect = engine.createEffect(\r\n            {\r\n                vertexSource: vertexCode,\r\n                fragmentSource: fragmentCode,\r\n                vertexToken: params.token,\r\n                fragmentToken: params.token,\r\n            },\r\n            <IEffectCreationOptions>{\r\n                attributes: origEffect.getAttributesNames(),\r\n                uniformsNames: uniforms,\r\n                uniformBuffersNames: origEffect.getUniformBuffersNames(),\r\n                samplers: origEffect.getSamplers(),\r\n                defines: join + \"\\n\" + origEffect.defines.replace(\"#define SHADOWS\", \"\").replace(/#define SHADOW\\d/g, \"\"),\r\n                indexParameters: origEffect.getIndexParameters(),\r\n                shaderLanguage: origEffect.shaderLanguage,\r\n            },\r\n            engine\r\n        );\r\n\r\n        for (let id = 0; id < params.drawWrapper.length; ++id) {\r\n            if (id !== passIdForDrawWrapper) {\r\n                params.drawWrapper[id]?.setEffect(params.mainDrawWrapper.effect, params.mainDrawWrapper.defines);\r\n            }\r\n        }\r\n        return params.mainDrawWrapper.effect;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../../Materials/effect.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { type GaussianSplattingMesh } from \"../../Meshes/GaussianSplatting/gaussianSplattingMesh.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { MaterialDefines } from \"../../Materials/materialDefines\";\r\nimport { PushMaterial } from \"../../Materials/pushMaterial\";\r\nimport { AddClipPlaneUniforms, BindClipPlane } from \"../clipPlaneMaterialHelper\";\r\nimport { Camera } from \"../../Cameras/camera.pure\";\r\nimport { ShadowDepthWrapper } from \"../../Materials/shadowDepthWrapper\";\r\nimport { ShaderMaterial } from \"../../Materials/shaderMaterial.pure\";\r\nimport { MaterialPluginEvent } from \"../materialPluginEvent\";\r\nimport { Material } from \"../material.pure\";\r\nimport {\r\n    BindFogParameters,\r\n    BindLogDepth,\r\n    PrepareAttributesForInstances,\r\n    PrepareDefinesForAttributes,\r\n    PrepareDefinesForFrameBoundValues,\r\n    PrepareDefinesForMisc,\r\n    PrepareUniformsAndSamplersList,\r\n} from \"../materialHelper.functions\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { Engine } from \"../../Engines/engine.pure\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\nimport { PrepassDefinesMixin } from \"../prepass.defines\";\r\nimport { MaterialHelperGeometryRendering, type GeometryRenderingConfiguration } from \"../materialHelper.geometryrendering\";\r\nimport { Observable, type Observer } from \"../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Computes the maximum number of Gaussian Splatting compound parts supported by the given engine.\r\n * The limit is derived from the engine's maximum vertex uniform vectors capability.\r\n * @param engine - The engine to compute the limit for\r\n * @returns The maximum number of parts supported\r\n */\r\nexport function GetGaussianSplattingMaxPartCount(engine: AbstractEngine): number {\r\n    // Each GS compound part requires 5 uniform vectors: 4 for the mat4 world matrix + 1 for the visibility float.\r\n    // The maximum number of parts is limited by the engine's uniform vector capacity and by the uint8 partIndices texture format (max 256).\r\n\r\n    const uniformsPerSplat = 5;\r\n    const reservedUniforms = 40; // base shader uniforms + margin for plugins/clip planes\r\n    const absoluteMax = 256; // uint8 partIndices texture format limit\r\n\r\n    const maxUniformVectors = engine.getCaps().maxVertexUniformVectors;\r\n    const available = Math.max(maxUniformVectors - reservedUniforms, 0);\r\n    const maxFromUniforms = Math.floor(available / uniformsPerSplat);\r\n    return Math.min(Math.max(maxFromUniforms, 1), absoluteMax);\r\n}\r\n\r\n/**\r\n * @deprecated Use {@link GetGaussianSplattingMaxPartCount} with an engine instance instead.\r\n */\r\nexport const GaussianSplattingMaxPartCount = 128;\r\n\r\n/**\r\n * Returns an include-guarded declaration of the `vPartIndex` varying shared by the Gaussian\r\n * Splatting material plugins (debug, solid-color, GPU picking). More than one of these plugins can\r\n * be attached to the same material at once; each needs `vPartIndex` to carry `splat.partIndex` from\r\n * the vertex to the fragment stage. Without a guard each plugin injects its own `varying vPartIndex`,\r\n * which is a duplicate declaration — fatal under WGSL (\"redefinition of 'vPartIndex'\"). The guard\r\n * makes the declaration idempotent so exactly one survives regardless of how many plugins inject it.\r\n * Inject the result at a CUSTOM_VERTEX_DEFINITIONS / CUSTOM_FRAGMENT_DEFINITIONS point.\r\n * @param shaderLanguage - The shader language the host material is compiling.\r\n * @returns The guarded `vPartIndex` varying declaration.\r\n */\r\nexport function GetPartIndexVaryingDeclaration(shaderLanguage: ShaderLanguage): string {\r\n    const decl = shaderLanguage === ShaderLanguage.WGSL ? \"varying vPartIndex: f32;\" : \"varying float vPartIndex;\";\r\n    return `\r\n#if !defined(VPARTINDEX_VARYING_DECLARED)\r\n#define VPARTINDEX_VARYING_DECLARED\r\n${decl}\r\n#endif\r\n`;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nclass GaussianSplattingMaterialDefinesBase extends PrepassDefinesMixin(MaterialDefines) {}\r\n\r\n/**\r\n * @internal\r\n */\r\nclass GaussianSplattingMaterialDefines extends GaussianSplattingMaterialDefinesBase {\r\n    /** Defines whether fog is enabled */\r\n    public FOG = false;\r\n    /** Defines whether thin instances are used */\r\n    public THIN_INSTANCES = true;\r\n    /** Defines whether logarithmic depth is enabled */\r\n    public LOGARITHMICDEPTH = false;\r\n    /** Defines whether clip plane 1 is enabled */\r\n    public CLIPPLANE = false;\r\n    /** Defines whether clip plane 2 is enabled */\r\n    public CLIPPLANE2 = false;\r\n    /** Defines whether clip plane 3 is enabled */\r\n    public CLIPPLANE3 = false;\r\n    /** Defines whether clip plane 4 is enabled */\r\n    public CLIPPLANE4 = false;\r\n    /** Defines whether clip plane 5 is enabled */\r\n    public CLIPPLANE5 = false;\r\n    /** Defines whether clip plane 6 is enabled */\r\n    public CLIPPLANE6 = false;\r\n    /** Defines the spherical harmonics degree */\r\n    public SH_DEGREE = 0;\r\n    /** Defines whether compensation is applied */\r\n    public COMPENSATION = false;\r\n    /** Defines whether this is a compound splat */\r\n    public IS_COMPOUND = false;\r\n    /** Defines the maximum number of parts (computed from engine caps at runtime) */\r\n    public MAX_PART_COUNT = GaussianSplattingMaxPartCount;\r\n    /** Defines whether SOG raw-texture in-shader dequantization is enabled */\r\n    public USE_SOG = false;\r\n    /** Defines whether SOG v2 (codebook) dequantization is enabled */\r\n    public USE_SOG_V2 = false;\r\n\r\n    /**\r\n     * Constructor of the defines.\r\n     * @param externalProperties External properties (e.g. from material plugins) to add to the defines.\r\n     */\r\n    constructor(externalProperties?: { [name: string]: { type: string; default: any } }) {\r\n        super(externalProperties);\r\n        this.rebuild();\r\n    }\r\n\r\n    /**\r\n     * Checks if a define is part of the generated define list.\r\n     * @param name define name to check\r\n     * @returns true if the define exists\r\n     */\r\n    public hasDefine(name: string): boolean {\r\n        return this._keys.indexOf(name) !== -1;\r\n    }\r\n}\r\n\r\ninterface IGaussianSplattingPartMotionHistory {\r\n    configuration: GeometryRenderingConfiguration;\r\n    currentPartWorldMatrices: Matrix[];\r\n    previousPartWorldData: Float32Array;\r\n    lastUpdateFrameId: number;\r\n}\r\n\r\n/**\r\n * GaussianSplattingMaterial material used to render Gaussian Splatting\r\n * @experimental\r\n */\r\nexport class GaussianSplattingMaterial extends PushMaterial {\r\n    /**\r\n     * Instantiates a Gaussian Splatting Material in the given scene\r\n     * @param name The friendly name of the material\r\n     * @param scene The scene to add the material to\r\n     */\r\n    constructor(name: string, scene?: Scene) {\r\n        super(name, scene);\r\n\r\n        this.backFaceCulling = false;\r\n        this.shadowDepthWrapper = GaussianSplattingMaterial._MakeGaussianSplattingShadowDepthWrapper(scene!, this.shaderLanguage);\r\n    }\r\n\r\n    /**\r\n     * Point spread function (default 0.3). Can be overriden per GS material\r\n     */\r\n    public static KernelSize: number = 0.3;\r\n\r\n    /**\r\n     * Compensation\r\n     */\r\n    public static Compensation: boolean = false;\r\n\r\n    /**\r\n     * Minimum projected splat size, in pixels, below which a splat is discarded (default 0 = disabled).\r\n     * Matches PlayCanvas `minPixelSize`. Applies to all Gaussian Splatting meshes using this material.\r\n     */\r\n    public static MinPixelSize: number = 0;\r\n\r\n    /**\r\n     * Point spread function (default 0.3). Can be overriden per GS material, otherwise, using default static `KernelSize` value\r\n     */\r\n    public kernelSize = GaussianSplattingMaterial.KernelSize;\r\n\r\n    /**\r\n     * Minimum projected splat size, in pixels, below which a splat is discarded (default 0 = disabled).\r\n     */\r\n    public minPixelSize = GaussianSplattingMaterial.MinPixelSize;\r\n    private _compensation = GaussianSplattingMaterial.Compensation;\r\n\r\n    // set to true when material defines are dirty\r\n    private _isDirty = false;\r\n\r\n    /**\r\n     * Set compensation default value is `GaussianSplattingMaterial.Compensation`\r\n     */\r\n    public set compensation(value: boolean) {\r\n        this._isDirty = this._isDirty != value;\r\n        this._compensation = value;\r\n    }\r\n\r\n    /**\r\n     * Get compensation\r\n     */\r\n    public get compensation(): boolean {\r\n        return this._compensation;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     */\r\n    public override get hasRenderTargetTextures(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not this material should be rendered in alpha test mode.\r\n     * @returns false\r\n     */\r\n    public override needAlphaTesting(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not this material should be rendered in alpha blend mode.\r\n     * @returns true\r\n     */\r\n    public override needAlphaBlending(): boolean {\r\n        return true;\r\n    }\r\n\r\n    protected static _Attribs = [VertexBuffer.PositionKind, \"splatIndex0\", \"splatIndex1\", \"splatIndex2\", \"splatIndex3\"];\r\n    protected static _Samplers = [\r\n        \"covariancesATexture\",\r\n        \"covariancesBTexture\",\r\n        \"centersTexture\",\r\n        \"colorsTexture\",\r\n        \"shTexture0\",\r\n        \"shTexture1\",\r\n        \"shTexture2\",\r\n        \"shTexture3\",\r\n        \"shTexture4\",\r\n        \"partIndicesTexture\",\r\n        \"sogQuatsTexture\",\r\n        \"sogShNCentroidsTexture\",\r\n        \"sogShNLabelsTexture\",\r\n        \"sogCodebookTexture\",\r\n    ];\r\n    protected static _UniformBuffers = [\"Scene\", \"Mesh\"];\r\n    protected static _VoxelUniforms = [\r\n        \"world\",\r\n        \"dataTextureSize\",\r\n        \"alpha\",\r\n        \"invWorldScale\",\r\n        \"viewMatrix\",\r\n        \"nearPlane\",\r\n        \"farPlane\",\r\n        \"stepSize\",\r\n        \"partWorld\",\r\n        \"partVisibility\",\r\n        \"axis\",\r\n    ];\r\n    protected static _VoxelSamplers = [\"rotationsATexture\", \"rotationsBTexture\", \"rotationScaleTexture\", \"centersTexture\", \"colorsTexture\", \"partIndicesTexture\"];\r\n    protected static _Uniforms = [\r\n        \"world\",\r\n        \"view\",\r\n        \"projection\",\r\n        \"inverseProjection\",\r\n        \"vFogInfos\",\r\n        \"vFogColor\",\r\n        \"logarithmicDepthConstant\",\r\n        \"invViewport\",\r\n        \"dataTextureSize\",\r\n        \"focal\",\r\n        \"eyePosition\",\r\n        \"kernelSize\",\r\n        \"minPixelSize\",\r\n        \"alpha\",\r\n        \"depthValues\",\r\n        \"geometryDepthRange\",\r\n        \"geometryZeroAlphaDiscard\",\r\n        \"partWorld\",\r\n        \"previousPartWorld\",\r\n        \"partVisibility\",\r\n        \"sogMeansMin\",\r\n        \"sogMeansMax\",\r\n        \"sogScalesMin\",\r\n        \"sogScalesMax\",\r\n        \"sogSh0Min\",\r\n        \"sogSh0Max\",\r\n        \"sogShnMin\",\r\n        \"sogShnMax\",\r\n        \"sogShCoeffCount\",\r\n    ];\r\n    private _sourceMesh: GaussianSplattingMesh | null = null;\r\n    private _inverseProjection = Matrix.Identity();\r\n    private _geometryProjectionUpdateFlag = -1;\r\n    private _partMotionHistory = new Map<number, IGaussianSplattingPartMotionHistory>();\r\n    private _renderPassObserver: Nullable<Observer<number>> = null;\r\n\r\n    private static _BindViewportAndFocal(effect: Effect, camera: Camera | null, renderWidth: number, renderHeight: number, invViewportWidth = renderWidth): void {\r\n        effect.setFloat2(\"invViewport\", 1 / invViewportWidth, 1 / renderHeight);\r\n\r\n        if (camera) {\r\n            const projection = camera.getProjectionMatrix();\r\n            effect.setFloat2(\"focal\", (renderWidth * projection.m[0]) / 2, (renderHeight * projection.m[5]) / 2);\r\n        } else {\r\n            effect.setFloat2(\"focal\", 1000, 1000);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether the material is ready to be rendered for a given mesh.\r\n     * @param mesh The mesh to render\r\n     * @param subMesh The submesh to check against\r\n     * @returns true if all the dependencies are ready (Textures, Effects...)\r\n     */\r\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh): boolean {\r\n        const useInstances = true;\r\n\r\n        const drawWrapper = subMesh._drawWrapper;\r\n        let defines = <GaussianSplattingMaterialDefines>subMesh.materialDefines;\r\n\r\n        if (defines && this._isDirty) {\r\n            defines.markAsUnprocessed();\r\n        }\r\n\r\n        if (drawWrapper.effect && this.isFrozen) {\r\n            if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (!subMesh.materialDefines || this.pluginManager) {\r\n            this._callbackPluginEventGeneric(MaterialPluginEvent.GetDefineNames, this._eventInfo);\r\n            const defineNames = this._eventInfo.defineNames;\r\n            const needsNewDefines = !subMesh.materialDefines || (defineNames && Object.keys(defineNames).some((name) => !defines.hasDefine(name)));\r\n            if (needsNewDefines) {\r\n                defines = subMesh.materialDefines = new GaussianSplattingMaterialDefines(defineNames);\r\n            }\r\n        }\r\n\r\n        const scene = this.getScene();\r\n\r\n        if (this._isReadyForSubMesh(subMesh)) {\r\n            return true;\r\n        }\r\n\r\n        // Check plugin readiness\r\n        this._eventInfo.isReadyForSubMesh = true;\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);\r\n\r\n        if (!this._eventInfo.isReadyForSubMesh) {\r\n            return false;\r\n        }\r\n\r\n        if (!this._sourceMesh) {\r\n            return false;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n        const gsMesh = this._sourceMesh;\r\n\r\n        MaterialHelperGeometryRendering.PrepareDefines(engine.currentRenderPassId, gsMesh, defines);\r\n\r\n        // Misc.\r\n        PrepareDefinesForMisc(\r\n            mesh,\r\n            scene,\r\n            this._useLogarithmicDepth,\r\n            this.pointsCloud,\r\n            this.fogEnabled,\r\n            false,\r\n            defines,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            this._isVertexOutputInvariant\r\n        );\r\n\r\n        // Values that need to be evaluated on every frame\r\n        PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, true);\r\n\r\n        // External config\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.mesh = mesh;\r\n        this._callbackPluginEventPrepareDefinesBeforeAttributes(this._eventInfo);\r\n\r\n        // Attribs\r\n        PrepareDefinesForAttributes(mesh, defines, false, false);\r\n\r\n        // External config\r\n        this._callbackPluginEventPrepareDefines(this._eventInfo);\r\n\r\n        // SH is disabled for webGL1\r\n        if (engine.version > 1 || engine.isWebGPU) {\r\n            defines[\"SH_DEGREE\"] = gsMesh.shDegree;\r\n        }\r\n\r\n        defines[\"IS_COMPOUND\"] = gsMesh.isCompound;\r\n        defines[\"MAX_PART_COUNT\"] = GetGaussianSplattingMaxPartCount(engine);\r\n        if (gsMesh.isCompound && (defines.PREPASS_VELOCITY || defines.PREPASS_VELOCITY_LINEAR)) {\r\n            // Reserve the regular 40 vectors plus projection/history matrices and the depth range.\r\n            defines.MAX_PART_COUNT = Math.min(defines.MAX_PART_COUNT, Math.max(1, Math.floor((engine.getCaps().maxVertexUniformVectors - 53) / 9)));\r\n            if (gsMesh.partCount > defines.MAX_PART_COUNT) {\r\n                throw new Error(`GaussianSplattingMaterial \"${this.name}\": geometry velocity supports at most ${defines.MAX_PART_COUNT} compound parts on this engine`);\r\n            }\r\n        }\r\n        defines[\"USE_SOG\"] = gsMesh.useSog;\r\n        defines[\"USE_SOG_V2\"] = gsMesh.useSog && gsMesh.sogParams?.version === 2;\r\n\r\n        // Compensation\r\n        const splatMaterial = gsMesh.material as GaussianSplattingMaterial;\r\n        defines[\"COMPENSATION\"] = splatMaterial && splatMaterial.compensation ? splatMaterial.compensation : GaussianSplattingMaterial.Compensation;\r\n\r\n        // Get correct effect\r\n        if (defines.isDirty) {\r\n            defines.markAsProcessed();\r\n            scene.resetCachedMaterial();\r\n\r\n            //Attributes\r\n            PrepareAttributesForInstances(GaussianSplattingMaterial._Attribs, defines);\r\n\r\n            const attribs = GaussianSplattingMaterial._Attribs.slice();\r\n            const uniforms = GaussianSplattingMaterial._Uniforms.slice();\r\n            const samplers = GaussianSplattingMaterial._Samplers.slice();\r\n            const uniformBuffers = GaussianSplattingMaterial._UniformBuffers.slice();\r\n\r\n            MaterialHelperGeometryRendering.AddUniformsAndSamplers(uniforms, samplers);\r\n\r\n            PrepareUniformsAndSamplersList(<IEffectCreationOptions>{\r\n                uniformsNames: uniforms,\r\n                uniformBuffersNames: uniformBuffers,\r\n                samplers: samplers,\r\n                defines: defines,\r\n            });\r\n\r\n            AddClipPlaneUniforms(uniforms);\r\n\r\n            // Let plugin manager prepare its uniform/sampler/ubo lists\r\n            if (!this._uniformBufferLayoutBuilt) {\r\n                this.buildUniformLayout();\r\n            }\r\n\r\n            // Prepare plugin effect\r\n            this._eventInfo.fallbackRank = 0;\r\n            this._eventInfo.defines = defines;\r\n            this._eventInfo.attributes = attribs;\r\n            this._eventInfo.uniforms = uniforms;\r\n            this._eventInfo.samplers = samplers;\r\n            this._eventInfo.uniformBuffersNames = uniformBuffers;\r\n            this._eventInfo.customCode = undefined;\r\n            this._eventInfo.mesh = mesh;\r\n\r\n            this._callbackPluginEventGeneric(MaterialPluginEvent.PrepareEffect, this._eventInfo);\r\n\r\n            const join = defines.toString();\r\n            const effect = scene.getEngine().createEffect(\r\n                \"gaussianSplatting\",\r\n                <IEffectCreationOptions>{\r\n                    attributes: attribs,\r\n                    uniformsNames: uniforms,\r\n                    uniformBuffersNames: uniformBuffers,\r\n                    samplers: samplers,\r\n                    defines: join,\r\n                    onCompiled: this.onCompiled,\r\n                    onError: this.onError,\r\n                    indexParameters: { SCENE_MRT_COUNT: defines.SCENE_MRT_COUNT },\r\n                    processCodeAfterIncludes: this._eventInfo.customCode,\r\n                    multiTarget: defines.PREPASS,\r\n                    shaderLanguage: this._shaderLanguage,\r\n                    extraInitializationsAsync: async () => {\r\n                        if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                            await Promise.all([import(\"../../ShadersWGSL/gaussianSplatting.fragment\"), import(\"../../ShadersWGSL/gaussianSplatting.vertex\")]);\r\n                        } else {\r\n                            await Promise.all([import(\"../../Shaders/gaussianSplatting.fragment\"), import(\"../../Shaders/gaussianSplatting.vertex\")]);\r\n                        }\r\n                    },\r\n                },\r\n                engine\r\n            );\r\n            subMesh.setEffect(effect, defines, this._materialContext);\r\n        }\r\n\r\n        if (!subMesh.effect || !subMesh.effect.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        defines._renderId = scene.getRenderId();\r\n        drawWrapper._wasPreviouslyReady = true;\r\n        drawWrapper._wasPreviouslyUsingInstances = useInstances;\r\n        this._isDirty = false;\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * GaussianSplattingMaterial belongs to a single mesh\r\n     * @param mesh mesh this material belongs to\r\n     */\r\n    public setSourceMesh(mesh: GaussianSplattingMesh) {\r\n        if (this._sourceMesh !== mesh) {\r\n            this._partMotionHistory.clear();\r\n        }\r\n        this._sourceMesh = mesh;\r\n    }\r\n\r\n    /**\r\n     * Gets the source mesh of this material, which is the Gaussian Splatting mesh that provides the data for rendering\r\n     * @returns The Gaussian Splatting mesh that provides the data for rendering, or null if not set\r\n     */\r\n    public getSourceMesh(): GaussianSplattingMesh | null {\r\n        return this._sourceMesh;\r\n    }\r\n\r\n    /**\r\n     * Bind material effect for a specific Gaussian Splatting mesh\r\n     * @param mesh Gaussian splatting mesh\r\n     * @param effect Splatting material or node material\r\n     * @param scene scene that contains mesh and camera used for rendering\r\n     */\r\n    public static BindEffect(mesh: Mesh, effect: Effect, scene: Scene): void {\r\n        const engine = scene.getEngine();\r\n        const camera = scene.activeCamera;\r\n\r\n        const renderWidth = engine.getRenderWidth() * (camera?.viewport.width ?? 1);\r\n        const renderHeight = engine.getRenderHeight() * (camera?.viewport.height ?? 1);\r\n\r\n        const material = mesh.material;\r\n        const gsMaterial = material instanceof GaussianSplattingMaterial ? material : null;\r\n        const gsMesh = gsMaterial?._sourceMesh ?? (mesh.reservedDataStore?._gaussianSplattingSourceMesh as GaussianSplattingMesh | undefined);\r\n\r\n        if (!gsMesh) {\r\n            return;\r\n        }\r\n\r\n        // check if rigcamera, get number of rigs\r\n        const numberOfRigs = camera?.rigParent?.rigCameras.length || 1;\r\n\r\n        GaussianSplattingMaterial._BindViewportAndFocal(effect, camera, renderWidth, renderHeight, renderWidth / numberOfRigs);\r\n        effect.setFloat(\"kernelSize\", gsMaterial?.kernelSize || GaussianSplattingMaterial.KernelSize);\r\n        effect.setFloat(\"minPixelSize\", gsMaterial ? gsMaterial.minPixelSize : GaussianSplattingMaterial.MinPixelSize);\r\n        effect.setFloat(\"alpha\", material?.alpha ?? 1);\r\n        scene.bindEyePosition(effect, \"eyePosition\", true);\r\n\r\n        if (gsMesh.covariancesATexture) {\r\n            const textureSize = gsMesh.covariancesATexture.getSize();\r\n\r\n            effect.setFloat2(\"dataTextureSize\", textureSize.width, textureSize.height);\r\n\r\n            effect.setTexture(\"covariancesATexture\", gsMesh.covariancesATexture);\r\n            effect.setTexture(\"covariancesBTexture\", gsMesh.covariancesBTexture);\r\n            effect.setTexture(\"centersTexture\", gsMesh.centersTexture);\r\n            effect.setTexture(\"colorsTexture\", gsMesh.colorsTexture);\r\n\r\n            if (gsMesh.useSog) {\r\n                GaussianSplattingMaterial._BindSogUniforms(gsMesh, effect);\r\n            } else if (gsMesh.shTextures) {\r\n                for (let i = 0; i < gsMesh.shTextures.length; i++) {\r\n                    effect.setTexture(`shTexture${i}`, gsMesh.shTextures[i]);\r\n                }\r\n            }\r\n\r\n            // Bind part indices texture, if the\r\n            gsMesh.bindExtraEffectUniforms(effect);\r\n        }\r\n    }\r\n\r\n    private _bindGeometryRendering(effect: Effect, defines: GaussianSplattingMaterialDefines, mustRebind: boolean): void {\r\n        const sourceMesh = this._sourceMesh;\r\n        if (!sourceMesh || !defines.PREPASS) {\r\n            return;\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n        const renderPassId = engine.currentRenderPassId;\r\n        const configuration = MaterialHelperGeometryRendering.GetConfiguration(renderPassId);\r\n        if (!configuration) {\r\n            return;\r\n        }\r\n\r\n        MaterialHelperGeometryRendering.Bind(renderPassId, effect, sourceMesh, sourceMesh.getWorldMatrix(), this);\r\n        MaterialHelperGeometryRendering._BindZeroAlphaDiscard(engine, effect);\r\n\r\n        const camera = scene.activeCamera;\r\n        if (camera) {\r\n            if (defines.PREPASS_POSITION || defines.PREPASS_LOCAL_POSITION || defines.PREPASS_VELOCITY || defines.PREPASS_VELOCITY_LINEAR) {\r\n                const projection = camera.getProjectionMatrix();\r\n                if (projection.updateFlag !== this._geometryProjectionUpdateFlag) {\r\n                    projection.invertToRef(this._inverseProjection);\r\n                    this._geometryProjectionUpdateFlag = projection.updateFlag;\r\n                }\r\n                effect.setMatrix(\"inverseProjection\", this._inverseProjection);\r\n            }\r\n            if (defines.PREPASS_NORMALIZED_VIEW_DEPTH) {\r\n                effect.setFloat2(\"geometryDepthRange\", camera.minZ, camera.maxZ);\r\n            }\r\n        }\r\n\r\n        if (!mustRebind) {\r\n            sourceMesh.bindExtraEffectUniforms(effect);\r\n        }\r\n\r\n        if (!sourceMesh.isCompound || (!defines.PREPASS_VELOCITY && !defines.PREPASS_VELOCITY_LINEAR)) {\r\n            return;\r\n        }\r\n\r\n        const partCount = sourceMesh.partCount;\r\n        let history = this._partMotionHistory.get(renderPassId);\r\n        if (!history || history.configuration !== configuration || history.currentPartWorldMatrices.length !== partCount) {\r\n            if (partCount > defines.MAX_PART_COUNT) {\r\n                throw new Error(`GaussianSplattingMaterial \"${this.name}\": geometry velocity supports at most ${defines.MAX_PART_COUNT} compound parts on this engine`);\r\n            }\r\n            const currentPartWorldMatrices = new Array<Matrix>(partCount);\r\n            for (let i = 0; i < partCount; i++) {\r\n                currentPartWorldMatrices[i] = sourceMesh.getWorldMatrixForPart(i).clone();\r\n            }\r\n            history = {\r\n                configuration,\r\n                currentPartWorldMatrices,\r\n                previousPartWorldData: new Float32Array(partCount * 16),\r\n                lastUpdateFrameId: -1,\r\n            };\r\n            this._partMotionHistory.set(renderPassId, history);\r\n            this._renderPassObserver ??= (engine._onReleaseRenderPassObservable ??= new Observable<number>()).add((id) => this._partMotionHistory.delete(id));\r\n        }\r\n\r\n        if (history.lastUpdateFrameId !== engine.frameId) {\r\n            const consecutiveFrame = history.lastUpdateFrameId === engine.frameId - 1;\r\n            for (let i = 0; i < partCount; i++) {\r\n                const previous = consecutiveFrame ? history.currentPartWorldMatrices[i] : sourceMesh.getWorldMatrixForPart(i);\r\n                previous.toArray(history.previousPartWorldData, i * 16);\r\n            }\r\n            history.lastUpdateFrameId = engine.frameId;\r\n        }\r\n        effect.setMatrices(\"previousPartWorld\", history.previousPartWorldData);\r\n        for (let i = 0; i < partCount; i++) {\r\n            history.currentPartWorldMatrices[i].copyFrom(sourceMesh.getWorldMatrixForPart(i));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases the material and its render-pass motion histories.\r\n     * @param forceDisposeEffect whether associated effects should be disposed\r\n     * @param forceDisposeTextures whether associated textures should be disposed\r\n     * @param notBoundToMesh whether mesh references can be left unchanged\r\n     */\r\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, notBoundToMesh?: boolean): void {\r\n        this.getScene().getEngine()._onReleaseRenderPassObservable?.remove(this._renderPassObserver);\r\n        this._renderPassObserver = null;\r\n        this._partMotionHistory.clear();\r\n        super.dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh);\r\n    }\r\n\r\n    /**\r\n     * Bind SOG dequantization uniforms + raw textures.\r\n     * @internal\r\n     */\r\n    protected static _BindSogUniforms(gsMesh: GaussianSplattingMesh, effect: Effect): void {\r\n        const p = gsMesh.sogParams;\r\n        if (!p) {\r\n            return;\r\n        }\r\n        effect.setTexture(\"sogQuatsTexture\", gsMesh.rotationsATexture);\r\n        if (gsMesh.shTextures && gsMesh.shTextures.length >= 2) {\r\n            effect.setTexture(\"sogShNCentroidsTexture\", gsMesh.shTextures[0]);\r\n            effect.setTexture(\"sogShNLabelsTexture\", gsMesh.shTextures[1]);\r\n        }\r\n        if (p.codebookTexture) {\r\n            effect.setTexture(\"sogCodebookTexture\", p.codebookTexture);\r\n        }\r\n        effect.setFloat3(\"sogMeansMin\", p.meansMin[0], p.meansMin[1], p.meansMin[2]);\r\n        effect.setFloat3(\"sogMeansMax\", p.meansMax[0], p.meansMax[1], p.meansMax[2]);\r\n        if (p.scalesMin && p.scalesMax) {\r\n            effect.setFloat3(\"sogScalesMin\", p.scalesMin[0], p.scalesMin[1], p.scalesMin[2]);\r\n            effect.setFloat3(\"sogScalesMax\", p.scalesMax[0], p.scalesMax[1], p.scalesMax[2]);\r\n        }\r\n        if (p.sh0Min && p.sh0Max) {\r\n            effect.setFloat4(\"sogSh0Min\", p.sh0Min[0], p.sh0Min[1], p.sh0Min[2], p.sh0Min[3]);\r\n            effect.setFloat4(\"sogSh0Max\", p.sh0Max[0], p.sh0Max[1], p.sh0Max[2], p.sh0Max[3]);\r\n        }\r\n        effect.setFloat(\"sogShnMin\", p.shnMin ?? 0);\r\n        effect.setFloat(\"sogShnMax\", p.shnMax ?? 0);\r\n        effect.setFloat(\"sogShCoeffCount\", p.shCoeffCount ?? 0);\r\n    }\r\n    /**\r\n     * Binds the submesh to this material by preparing the effect and shader to draw\r\n     * @param world defines the world transformation matrix\r\n     * @param mesh defines the mesh containing the submesh\r\n     * @param subMesh defines the submesh to bind the material to\r\n     */\r\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\r\n        const scene = this.getScene();\r\n\r\n        const defines = <GaussianSplattingMaterialDefines>subMesh.materialDefines;\r\n        if (!defines) {\r\n            return;\r\n        }\r\n\r\n        const effect = subMesh.effect;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n        this._activeEffect = effect;\r\n\r\n        // Matrices Mesh.\r\n        mesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n        mesh.transferToEffect(world);\r\n\r\n        // Bind data\r\n        const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);\r\n\r\n        if (mustRebind) {\r\n            this.bindView(effect);\r\n            this.bindViewProjection(effect);\r\n            GaussianSplattingMaterial.BindEffect(mesh, this._activeEffect, scene);\r\n            // Clip plane\r\n            BindClipPlane(effect, this, scene);\r\n        } else if (scene.getEngine()._features.needToAlwaysBindUniformBuffers) {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n\r\n        this._bindGeometryRendering(effect, defines, mustRebind);\r\n\r\n        // Fog\r\n        BindFogParameters(scene, mesh, effect);\r\n\r\n        // Log. depth\r\n        if (this.useLogarithmicDepth) {\r\n            BindLogDepth(defines, effect, scene);\r\n        }\r\n\r\n        // Bind plugins\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventBindForSubMesh(this._eventInfo);\r\n\r\n        this._afterBind(mesh, this._activeEffect, subMesh);\r\n    }\r\n\r\n    protected static _BindEffectUniforms(gsMesh: GaussianSplattingMesh, gsMaterial: GaussianSplattingMaterial, shaderMaterial: ShaderMaterial, scene: Scene): void {\r\n        const engine = scene.getEngine();\r\n        const effect = shaderMaterial.getEffect()!;\r\n        const camera = scene.activeCamera;\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        gsMesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n        shaderMaterial.bindView(effect);\r\n        shaderMaterial.bindViewProjection(effect);\r\n\r\n        const renderWidth = engine.getRenderWidth() * camera.viewport.width;\r\n        const renderHeight = engine.getRenderHeight() * camera.viewport.height;\r\n        GaussianSplattingMaterial._BindViewportAndFocal(effect, camera, renderWidth, renderHeight);\r\n        effect.setFloat(\"kernelSize\", gsMaterial && gsMaterial.kernelSize ? gsMaterial.kernelSize : GaussianSplattingMaterial.KernelSize);\r\n        effect.setFloat(\"minPixelSize\", gsMaterial ? gsMaterial.minPixelSize : GaussianSplattingMaterial.MinPixelSize);\r\n        effect.setFloat(\"alpha\", gsMaterial.alpha);\r\n\r\n        let minZ: number, maxZ: number;\r\n\r\n        const cameraIsOrtho = camera.mode === Camera.ORTHOGRAPHIC_CAMERA;\r\n        if (cameraIsOrtho) {\r\n            minZ = !engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\r\n            maxZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\r\n        } else {\r\n            minZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? camera.minZ : engine.isNDCHalfZRange ? 0 : camera.minZ;\r\n            maxZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : camera.maxZ;\r\n        }\r\n\r\n        effect.setFloat2(\"depthValues\", minZ, minZ + maxZ);\r\n\r\n        if (gsMesh.covariancesATexture) {\r\n            const textureSize = gsMesh.covariancesATexture.getSize();\r\n            effect.setFloat2(\"dataTextureSize\", textureSize.width, textureSize.height);\r\n\r\n            effect.setTexture(\"covariancesATexture\", gsMesh.covariancesATexture);\r\n            effect.setTexture(\"covariancesBTexture\", gsMesh.covariancesBTexture);\r\n            effect.setTexture(\"centersTexture\", gsMesh.centersTexture);\r\n            effect.setTexture(\"colorsTexture\", gsMesh.colorsTexture);\r\n\r\n            gsMesh.bindExtraEffectUniforms(effect);\r\n        }\r\n    }\r\n\r\n    private _voxelMissingTextureWarned = new Set<number>();\r\n    private _voxelPartWorldData = new Float32Array(0);\r\n    private readonly _voxelPartVisibilityData: number[] = [];\r\n\r\n    protected _bindVoxelEffectUniforms(gsMesh: GaussianSplattingMesh, gsMaterial: GaussianSplattingMaterial, shaderMaterial: ShaderMaterial): boolean {\r\n        if (!gsMesh.rotationsATexture) {\r\n            // Attempt to enable rotation/scale texture generation (no-op if already enabled).\r\n            // If the mesh is already loaded and splat data is in RAM this triggers updateData() synchronously.\r\n            // If the mesh was loaded without keepInRam=true the setter will log an error.\r\n            gsMesh.needsRotationScaleTextures = true;\r\n\r\n            if (!gsMesh.rotationsATexture) {\r\n                // Mesh data was already processed but rotation textures couldn't be generated — warn once.\r\n                if (gsMesh.centersTexture && !gsMesh.splatsData && !this._voxelMissingTextureWarned.has(gsMesh.uniqueId)) {\r\n                    this._voxelMissingTextureWarned.add(gsMesh.uniqueId);\r\n                    Logger.Error(\r\n                        \"IBL voxelization: GaussianSplattingMesh rotation/scale textures are not available. \" +\r\n                            \"Create the mesh either with keepInRam=true or needsRotationScaleTextures=true to enable IBL shadow voxelization.\"\r\n                    );\r\n                }\r\n                return false;\r\n            }\r\n        }\r\n        this._voxelMissingTextureWarned.delete(gsMesh.uniqueId);\r\n\r\n        const effect = shaderMaterial.getEffect()!;\r\n        gsMesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n\r\n        const textureSize = gsMesh.rotationsATexture.getSize();\r\n        effect.setFloat(\"alpha\", gsMaterial.alpha);\r\n        effect.setFloat2(\"dataTextureSize\", textureSize.width, textureSize.height);\r\n        effect.setTexture(\"rotationsATexture\", gsMesh.rotationsATexture);\r\n        effect.setTexture(\"rotationsBTexture\", gsMesh.rotationsBTexture);\r\n        effect.setTexture(\"rotationScaleTexture\", gsMesh.rotationScaleTexture);\r\n        effect.setTexture(\"centersTexture\", gsMesh.centersTexture);\r\n        effect.setTexture(\"colorsTexture\", gsMesh.colorsTexture);\r\n\r\n        if (gsMesh.partIndicesTexture) {\r\n            effect.setTexture(\"partIndicesTexture\", gsMesh.partIndicesTexture);\r\n            const partWorldDataLength = gsMesh.partCount * 16;\r\n            if (this._voxelPartWorldData.length !== partWorldDataLength) {\r\n                this._voxelPartWorldData = new Float32Array(partWorldDataLength);\r\n            }\r\n            const partWorldData = this._voxelPartWorldData;\r\n            for (let i = 0; i < gsMesh.partCount; i++) {\r\n                gsMesh.getWorldMatrixForPart(i).toArray(partWorldData, i * 16);\r\n            }\r\n            effect.setMatrices(\"partWorld\", partWorldData);\r\n            const partVisibilityData = this._voxelPartVisibilityData;\r\n            partVisibilityData.length = gsMesh.partCount;\r\n            for (let i = 0; i < gsMesh.partCount; i++) {\r\n                partVisibilityData[i] = gsMesh.partVisibility[i] ?? 1.0;\r\n            }\r\n            effect.setArray(\"partVisibility\", partVisibilityData);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Create a voxel rendering material for a Gaussian Splatting mesh, for use with IBL shadow voxelization.\r\n     * The returned ShaderMaterial's onBindObservable binds the GS mesh-side uniforms (textures, alpha, dataTextureSize, part data).\r\n     * The caller (e.g. iblShadowsVoxelRenderer) is responsible for setting the per-slab uniforms on the returned material:\r\n     * viewMatrix, invWorldScale, nearPlane, farPlane, stepSize.\r\n     * @param scene scene it belongs to\r\n     * @param shaderLanguage GLSL or WGSL\r\n     * @param maxDrawBuffers number of draw buffers (MRT outputs) per voxelization slab\r\n     * @param compoundMesh whether the mesh is a compound mesh\r\n     * @returns voxel rendering shader material\r\n     */\r\n    public makeVoxelRenderingMaterial(scene: Scene, shaderLanguage: ShaderLanguage, maxDrawBuffers: number, compoundMesh: boolean = false): ShaderMaterial {\r\n        const defines = [`#define MAX_DRAW_BUFFERS ${maxDrawBuffers}`];\r\n\r\n        defines.push(\"#define IS_FOR_VOXELIZATION\");\r\n\r\n        if (compoundMesh) {\r\n            defines.push(\"#define IS_COMPOUND 1\");\r\n            defines.push(`#define MAX_PART_COUNT ${GetGaussianSplattingMaxPartCount(scene.getEngine())}`);\r\n        }\r\n\r\n        const shaderMaterial = new ShaderMaterial(\r\n            \"gaussianSplattingVoxelRender\",\r\n            scene,\r\n            {\r\n                vertex: \"gaussianSplattingVoxel\",\r\n                fragment: \"gaussianSplattingVoxel\",\r\n            },\r\n            {\r\n                attributes: GaussianSplattingMaterial._Attribs,\r\n                uniforms: GaussianSplattingMaterial._VoxelUniforms,\r\n                samplers: GaussianSplattingMaterial._VoxelSamplers,\r\n                uniformBuffers: GaussianSplattingMaterial._UniformBuffers,\r\n                // WebGPU accumulates non-binary voxel opacity via atomicMax into this storage buffer.\r\n                storageBuffers: shaderLanguage === ShaderLanguage.WGSL ? [\"voxelOpacityBuffer\"] : [],\r\n                shaderLanguage: shaderLanguage,\r\n                defines: defines,\r\n                needAlphaBlending: false,\r\n                extraInitializationsAsync: async () => {\r\n                    if (shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await Promise.all([import(\"../../ShadersWGSL/gaussianSplattingVoxel.vertex\"), import(\"../../ShadersWGSL/gaussianSplattingVoxel.fragment\")]);\r\n                    } else {\r\n                        await Promise.all([import(\"../../Shaders/gaussianSplattingVoxel.vertex\"), import(\"../../Shaders/gaussianSplattingVoxel.fragment\")]);\r\n                    }\r\n                },\r\n            }\r\n        );\r\n        shaderMaterial.cullBackFaces = false;\r\n        shaderMaterial.backFaceCulling = false;\r\n        shaderMaterial.depthFunction = Engine.ALWAYS;\r\n        shaderMaterial.onBindObservable.add((mesh: AbstractMesh) => {\r\n            const gsMaterial = mesh.material as GaussianSplattingMaterial;\r\n            const gsMesh = mesh as GaussianSplattingMesh;\r\n            this._bindVoxelEffectUniforms(gsMesh, gsMaterial, shaderMaterial);\r\n        });\r\n        return shaderMaterial;\r\n    }\r\n\r\n    /**\r\n     * Create a depth rendering material for a Gaussian Splatting mesh\r\n     * @param scene scene it belongs to\r\n     * @param shaderLanguage GLSL or WGSL\r\n     * @param alphaBlendedDepth whether to enable alpha blended depth rendering\r\n     * @param compoundMesh whether the mesh is a compound mesh\r\n     * @returns depth rendering shader material\r\n     */\r\n    public makeDepthRenderingMaterial(scene: Scene, shaderLanguage: ShaderLanguage, alphaBlendedDepth: boolean = false, compoundMesh: boolean = false): ShaderMaterial {\r\n        const defines = [\"#define DEPTH_RENDER\"];\r\n\r\n        if (alphaBlendedDepth) {\r\n            defines.push(\"#define ALPHA_BLENDED_DEPTH\");\r\n        }\r\n\r\n        if (compoundMesh) {\r\n            defines.push(\"#define IS_COMPOUND 1\");\r\n            defines.push(`#define MAX_PART_COUNT ${GetGaussianSplattingMaxPartCount(scene.getEngine())}`);\r\n        }\r\n\r\n        const shaderMaterial = new ShaderMaterial(\r\n            \"gaussianSplattingDepthRender\",\r\n            scene,\r\n            {\r\n                vertex: \"gaussianSplattingDepth\",\r\n                fragment: \"gaussianSplattingDepth\",\r\n            },\r\n            {\r\n                attributes: GaussianSplattingMaterial._Attribs,\r\n                uniforms: GaussianSplattingMaterial._Uniforms,\r\n                samplers: GaussianSplattingMaterial._Samplers,\r\n                uniformBuffers: GaussianSplattingMaterial._UniformBuffers,\r\n                shaderLanguage: shaderLanguage,\r\n                defines: defines,\r\n                needAlphaBlending: alphaBlendedDepth,\r\n            }\r\n        );\r\n        shaderMaterial.doNotSerialize = true;\r\n        shaderMaterial.backFaceCulling = false;\r\n        shaderMaterial.onBindObservable.add((mesh: AbstractMesh) => {\r\n            const gsMaterial = mesh.material as GaussianSplattingMaterial;\r\n            // Use the source mesh from the material for GS-specific properties (textures, etc.),\r\n            // since the bound mesh may be a camera mesh proxy without those properties.\r\n            const gsMesh = (gsMaterial?.getSourceMesh() ?? mesh) as GaussianSplattingMesh;\r\n            GaussianSplattingMaterial._BindEffectUniforms(gsMesh, gsMaterial, shaderMaterial, scene);\r\n        });\r\n        return shaderMaterial;\r\n    }\r\n\r\n    protected static _MakeGaussianSplattingShadowDepthWrapper(scene: Scene, shaderLanguage: ShaderLanguage): ShadowDepthWrapper {\r\n        const shaderMaterial = new ShaderMaterial(\r\n            \"gaussianSplattingDepth\",\r\n            scene,\r\n            {\r\n                vertex: \"gaussianSplattingDepth\",\r\n                fragment: \"gaussianSplattingDepth\",\r\n            },\r\n            {\r\n                attributes: GaussianSplattingMaterial._Attribs,\r\n                uniforms: GaussianSplattingMaterial._Uniforms,\r\n                samplers: GaussianSplattingMaterial._Samplers,\r\n                uniformBuffers: GaussianSplattingMaterial._UniformBuffers,\r\n                shaderLanguage: shaderLanguage,\r\n            }\r\n        );\r\n        shaderMaterial.doNotSerialize = true;\r\n        shaderMaterial.backFaceCulling = false;\r\n\r\n        const shadowDepthWrapper = new ShadowDepthWrapper(shaderMaterial, scene, {\r\n            standalone: true,\r\n        });\r\n\r\n        shaderMaterial.onBindObservable.add((mesh: AbstractMesh) => {\r\n            const gsMaterial = mesh.material as GaussianSplattingMaterial;\r\n            // Use the source mesh from the material for GS-specific properties (textures, etc.),\r\n            // since the bound mesh may be a camera mesh proxy without those properties.\r\n            const gsMesh = (gsMaterial?.getSourceMesh() ?? mesh) as GaussianSplattingMesh;\r\n\r\n            GaussianSplattingMaterial._BindEffectUniforms(gsMesh, gsMaterial, shaderMaterial, scene);\r\n        });\r\n\r\n        return shadowDepthWrapper;\r\n    }\r\n\r\n    /**\r\n     * Clones the material.\r\n     * @param name The cloned name.\r\n     * @returns The cloned material.\r\n     */\r\n    public override clone(name: string): GaussianSplattingMaterial {\r\n        const clone = SerializationHelper.Clone(() => new GaussianSplattingMaterial(name, this.getScene()), this);\r\n\r\n        clone.id = name;\r\n        clone.name = name;\r\n\r\n        this._clonePlugins(clone, \"\");\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serializes the current material to its JSON representation.\r\n     * @returns The JSON representation.\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.customType = \"BABYLON.GaussianSplattingMaterial\";\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the material\r\n     * @returns \"GaussianSplattingMaterial\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GaussianSplattingMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Parse a JSON input to create back a Gaussian Splatting material.\r\n     * @param source The JSON data to parse\r\n     * @param scene The scene to create the parsed material in\r\n     * @param rootUrl The root url of the assets the material depends upon\r\n     * @returns the instantiated GaussianSplattingMaterial.\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): GaussianSplattingMaterial {\r\n        const material = SerializationHelper.Parse(() => new GaussianSplattingMaterial(source.name, scene), source, scene, rootUrl);\r\n\r\n        Material._ParsePlugins(source, material, scene, rootUrl);\r\n\r\n        return material;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GaussianSplattingMaterial\", GaussianSplattingMaterial);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { type UniformBuffer } from \"../uniformBuffer\";\r\nimport { type MaterialDefines } from \"../materialDefines\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { GetGaussianSplattingMaxPartCount, GetPartIndexVaryingDeclaration, type GaussianSplattingMaterial } from \"./gaussianSplattingMaterial.pure\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * Plugin for GaussianSplattingMaterial that replaces per-splat color output with\r\n * a pre-computed picking color for GPU-based hit testing.\r\n *\r\n * The picking color is computed on the CPU by encoding a 24-bit picking ID as RGB\r\n * (matching the readback decoding in GPUPicker).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBase {\r\n    private _pickingColor: [number, number, number] = [0, 0, 0];\r\n    private _isCompound: boolean = false;\r\n    private _partPickingColors: number[] = [];\r\n    private _partVisibility: number[] = [];\r\n    private _defaultPartVisibility: number[] = [];\r\n    private _maxPartCount: number;\r\n    private _enableDepthPicking = false;\r\n    private _enablePackedDepthPicking = false;\r\n\r\n    /**\r\n     * Creates a new GaussianSplattingGpuPickingMaterialPlugin.\r\n     * @param material The GaussianSplattingMaterial to attach the plugin to.\r\n     * @param maxPartCount The maximum number of parts supported for compound meshes.\r\n     */\r\n    constructor(material: GaussianSplattingMaterial, maxPartCount?: number) {\r\n        super(material, \"GaussianSplatGpuPicking\", 200, {\r\n            GPUPICKER_DEPTH: false,\r\n            GPUPICKER_PACK_DEPTH: false,\r\n        });\r\n\r\n        this._maxPartCount = maxPartCount ?? GetGaussianSplattingMaxPartCount(material.getScene().getEngine());\r\n        this._defaultPartVisibility = new Array(this._maxPartCount).fill(1.0);\r\n        this._enable(true);\r\n    }\r\n\r\n    /**\r\n     * Enables writing the GPU picker depth MRT attachment.\r\n     */\r\n    public set enableDepthPicking(value: boolean) {\r\n        if (this._enableDepthPicking === value) {\r\n            return;\r\n        }\r\n\r\n        this._enableDepthPicking = value;\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Enables byte-packed depth output for the GPU picker depth MRT attachment.\r\n     */\r\n    public set enablePackedDepthPicking(value: boolean) {\r\n        if (this._enablePackedDepthPicking === value) {\r\n            return;\r\n        }\r\n\r\n        this._enablePackedDepthPicking = value;\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Encodes a 24-bit picking ID into normalized RGB components.\r\n     * @param id The picking ID to encode\r\n     * @returns A tuple [r, g, b] with values in [0, 1]\r\n     */\r\n    public static EncodeIdToColor(id: number): [number, number, number] {\r\n        return [((id >> 16) & 0xff) / 255, ((id >> 8) & 0xff) / 255, (id & 0xff) / 255];\r\n    }\r\n\r\n    /**\r\n     * Sets the picking color for a non-compound mesh from a picking ID.\r\n     * The ID is encoded into an RGB color on the CPU.\r\n     * @param id The 24-bit picking ID.\r\n     */\r\n    public set meshId(id: number) {\r\n        this._pickingColor = GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(id);\r\n    }\r\n\r\n    /**\r\n     * Sets whether this material is for a compound mesh with per-part picking.\r\n     */\r\n    public set isCompound(value: boolean) {\r\n        this._isCompound = value;\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets whether this material is for a compound mesh with per-part picking.\r\n     */\r\n    public get isCompound(): boolean {\r\n        return this._isCompound;\r\n    }\r\n\r\n    /**\r\n     * Sets the per-part picking colors from an array of picking IDs.\r\n     * Each ID is encoded into an RGB color on the CPU.\r\n     * @param ids Array mapping part index to picking ID.\r\n     */\r\n    public set partMeshIds(ids: number[]) {\r\n        const colors: number[] = [];\r\n        for (let i = 0; i < this._maxPartCount; i++) {\r\n            const c = i < ids.length ? GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(ids[i]) : ([0, 0, 0] as [number, number, number]);\r\n            colors.push(c[0], c[1], c[2]);\r\n        }\r\n        this._partPickingColors = colors;\r\n    }\r\n\r\n    /**\r\n     * Sets which parts are active (pickable) for the compound picking pass.\r\n     * Parts not in the set are discarded in the shader by overriding partVisibility to 0.\r\n     * @param activeParts Array of part indices that should be pickable.\r\n     */\r\n    public setPartActive(activeParts: number[]): void {\r\n        const visibility = this._partVisibility;\r\n        visibility.length = this._maxPartCount;\r\n        visibility.fill(0.0);\r\n        for (const index of activeParts) {\r\n            if (index >= 0 && index < this._maxPartCount) {\r\n                visibility[index] = 1.0;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GaussianSplattingGpuPickingMaterialPlugin\";\r\n    }\r\n\r\n    /**\r\n     * Indicates this plugin supports both GLSL and WGSL.\r\n     * @param shaderLanguage the shader language to check\r\n     * @returns true for GLSL and WGSL\r\n     */\r\n    public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n        switch (shaderLanguage) {\r\n            case ShaderLanguage.GLSL:\r\n            case ShaderLanguage.WGSL:\r\n                return true;\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Always ready — no textures or async resources to wait on.\r\n     * @param _defines the defines\r\n     * @param _scene the scene\r\n     * @param _engine the engine\r\n     * @param _subMesh the submesh\r\n     * @returns true\r\n     */\r\n    public override isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Sets the defines for the next rendering.\r\n     * @param defines the list of defines to update\r\n     */\r\n    public override prepareDefines(defines: MaterialDefines): void {\r\n        defines[\"GPUPICKER_DEPTH\"] = this._enableDepthPicking;\r\n        defines[\"GPUPICKER_PACK_DEPTH\"] = this._enableDepthPicking && this._enablePackedDepthPicking;\r\n    }\r\n\r\n    /**\r\n     * Returns custom shader code to inject GPU picking color output.\r\n     *\r\n     * @param shaderType \"vertex\" or \"fragment\"\r\n     * @param shaderLanguage the shader language to use (default: GLSL)\r\n     * @returns null or a map of injection point names to code strings\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return this._getCustomCodeWGSL(shaderType);\r\n        }\r\n        return this._getCustomCodeGLSL(shaderType);\r\n    }\r\n\r\n    private _getCustomCodeGLSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderType === \"vertex\") {\r\n            return {\r\n                CUSTOM_VERTEX_DEFINITIONS: GetPartIndexVaryingDeclaration(ShaderLanguage.GLSL),\r\n                CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n    vPartIndex = float(splat.partIndex);\r\n#else\r\n    vPartIndex = 0.0;\r\n#endif\r\n                `,\r\n            };\r\n        } else if (shaderType === \"fragment\") {\r\n            return {\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n${GetPartIndexVaryingDeclaration(ShaderLanguage.GLSL)}\r\n#if IS_COMPOUND\r\nuniform vec3 partPickingColors[${this._maxPartCount}];\r\n#else\r\nuniform vec3 pickingColor;\r\n#endif\r\n                `,\r\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#if IS_COMPOUND\r\n    if (vColor.a < 0.001) discard;\r\n    finalColor = vec4(partPickingColors[int(vPartIndex + 0.5)], 1.0);\r\n#else\r\n    if (vColor.a < 0.001) discard;\r\n    finalColor = vec4(pickingColor, 1.0);\r\n#endif\r\n                `,\r\n            };\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private _getCustomCodeWGSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderType === \"vertex\") {\r\n            return {\r\n                CUSTOM_VERTEX_DEFINITIONS: GetPartIndexVaryingDeclaration(ShaderLanguage.WGSL),\r\n                CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n    vertexOutputs.vPartIndex = f32(splat.partIndex);\r\n#else\r\n    vertexOutputs.vPartIndex = 0.0;\r\n#endif\r\n                `,\r\n            };\r\n        } else if (shaderType === \"fragment\") {\r\n            return {\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n${GetPartIndexVaryingDeclaration(ShaderLanguage.WGSL)}\r\n#if IS_COMPOUND\r\nuniform partPickingColors: array<vec3f, ${this._maxPartCount}>;\r\n#else\r\nuniform pickingColor: vec3f;\r\n#endif\r\n                `,\r\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#if IS_COMPOUND\r\n    if (fragmentInputs.vColor.a < 0.001) { discard; }\r\n    finalColor = vec4f(uniforms.partPickingColors[i32(fragmentInputs.vPartIndex + 0.5)], 1.0);\r\n#else\r\n    if (fragmentInputs.vColor.a < 0.001) { discard; }\r\n    finalColor = vec4f(uniforms.pickingColor, 1.0);\r\n#endif\r\n                `,\r\n            };\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Registers the picking uniforms with the engine.\r\n     * @returns uniform descriptions\r\n     */\r\n    public override getUniforms(): {\r\n        ubo?: Array<{ name: string; size?: number; type?: string; arraySize?: number }>;\r\n        vertex?: string;\r\n        fragment?: string;\r\n        externalUniforms?: string[];\r\n    } {\r\n        return {\r\n            externalUniforms: [\"pickingColor\", \"partPickingColors\"],\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Binds the picking color uniform(s) each frame.\r\n     * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect)\r\n     * @param _scene the current scene\r\n     * @param _engine the current engine\r\n     * @param subMesh the submesh being rendered\r\n     */\r\n    public override bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void {\r\n        const effect = subMesh.effect;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        if (this._isCompound) {\r\n            effect.setArray3(\"partPickingColors\", this._partPickingColors);\r\n            // default all visible when setPartActive hasn't been called\r\n            const visibility = this._partVisibility.length > 0 ? this._partVisibility : this._defaultPartVisibility;\r\n            effect.setArray(\"partVisibility\", visibility);\r\n        } else {\r\n            effect.setFloat3(\"pickingColor\", this._pickingColor[0], this._pickingColor[1], this._pickingColor[2]);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingGpuPickingMaterialPlugin.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingGpuPickingMaterialPlugin(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GaussianSplattingGpuPickingMaterialPlugin\", GaussianSplattingGpuPickingMaterialPlugin);\r\n}\r\n","import { type AbstractMesh } from \"../abstractMesh.pure\";\r\n\r\n/**\r\n * True when `className` (from `AbstractMesh.getClassName()`) identifies a Gaussian Splatting mesh whose\r\n * `position.z` vertex attribute encodes a splat index rather than world-space Z: `\"GaussianSplattingMesh\"`\r\n * (also returned by `GaussianSplattingCompoundMesh`) or `\"GaussianSplattingStream\"`.\r\n *\r\n * This function is retained for backward compatibility. Internal code should prefer\r\n * {@link _IsGaussianSplattingMesh}, which also recognizes the inherited Gaussian Splatting capability.\r\n * @param className the mesh class name to test, e.g. from `AbstractMesh.getClassName()`\r\n * @returns true if the class name identifies a Gaussian Splatting mesh\r\n */\r\nexport function IsGaussianSplattingClassName(className: string): boolean {\r\n    return className === \"GaussianSplattingMesh\" || className === \"GaussianSplattingStream\";\r\n}\r\n\r\n/**\r\n * Tests whether a mesh uses Gaussian Splatting rendering behavior.\r\n * @param mesh the mesh to test\r\n * @returns true if the mesh is a Gaussian Splatting mesh\r\n * @internal\r\n */\r\nexport function _IsGaussianSplattingMesh(mesh: AbstractMesh): boolean {\r\n    return mesh._isGaussianSplatting || IsGaussianSplattingClassName(mesh.getClassName());\r\n}\r\n","import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Engine } from \"core/Engines/engine\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\r\nimport { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget.pure\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Material } from \"core/Materials/material\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type IShaderMaterialOptions, ShaderMaterial } from \"core/Materials/shaderMaterial.pure\";\r\nimport { GaussianSplattingMaterial } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { GaussianSplattingGpuPickingMaterialPlugin } from \"core/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure\";\r\nimport { _IsGaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplatting.functions\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { type IVector2Like } from \"core/Maths/math.like\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Meshes/buffer\";\r\nimport { type Mesh } from \"core/Meshes/mesh\";\r\nimport { type InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\n\r\n/**\r\n * Class used to store the result of a GPU picking operation\r\n */\r\nexport interface IGPUPickingInfo {\r\n    /**\r\n     * Picked mesh\r\n     */\r\n    mesh: AbstractMesh;\r\n    /**\r\n     * Picked thin instance index\r\n     */\r\n    thinInstanceIndex?: number;\r\n    /**\r\n     * Picked point in world space.\r\n     *\r\n     * Only available when enableDepthPicking is true and a valid depth value can be read.\r\n     * Custom picking materials or special material plugins that do not write the depth attachment may return undefined.\r\n     */\r\n    pickedPoint?: Vector3;\r\n    /**\r\n     * Reconstructed normal in world space.\r\n     *\r\n     * Only available when enableDepthPicking is true and enough valid depth neighbors can be read.\r\n     * Custom picking materials or special material plugins that do not write the depth attachment may return undefined.\r\n     */\r\n    normal?: Vector3;\r\n}\r\n\r\n/**\r\n * Stores the result of a multi GPU picking operation\r\n */\r\nexport interface IGPUMultiPickingInfo {\r\n    /**\r\n     * Picked mesh\r\n     */\r\n    meshes: Nullable<AbstractMesh>[];\r\n    /**\r\n     * Picked thin instance index\r\n     */\r\n    thinInstanceIndexes?: number[];\r\n    /**\r\n     * Picked points in world space.\r\n     *\r\n     * Only available when enableDepthPicking is true and a valid depth value can be read.\r\n     * Custom picking materials or special material plugins that do not write the depth attachment may return null.\r\n     */\r\n    pickedPoints?: Nullable<Vector3>[];\r\n    /**\r\n     * Reconstructed normals in world space.\r\n     *\r\n     * Only available when enableDepthPicking is true and enough valid depth neighbors can be read.\r\n     * Custom picking materials or special material plugins that do not write the depth attachment may return null.\r\n     */\r\n    normals?: Nullable<Vector3>[];\r\n}\r\n\r\n/**\r\n * Defines how multi pick texture readbacks should be performed.\r\n */\r\nexport const enum GPUMultiPickReadbackStrategy {\r\n    /**\r\n     * Chooses between a single rectangle readback and small per-point readbacks using the thresholds in IGPUMultiPickOptions.\r\n     */\r\n    Auto = 0,\r\n    /**\r\n     * Always reads the full bounding rectangle of the picked points. This minimizes readback calls and is best for dense point sets.\r\n     */\r\n    Rectangle = 1,\r\n    /**\r\n     * Always reads each picked point independently. This minimizes transferred pixels for sparse point sets but can be slower when many points are picked.\r\n     */\r\n    Individual = 2,\r\n}\r\n\r\n/**\r\n * Options used to tune multi GPU picking.\r\n */\r\nexport interface IGPUMultiPickOptions {\r\n    /**\r\n     * Defines how multi pick texture readbacks should be performed.\r\n     *\r\n     * Defaults to GPUMultiPickReadbackStrategy.Auto.\r\n     */\r\n    readbackStrategy?: GPUMultiPickReadbackStrategy;\r\n    /**\r\n     * Maximum number of in-bounds points allowed for the automatic individual readback path.\r\n     * This value is ignored when readbackStrategy is set to GPUMultiPickReadbackStrategy.Rectangle or GPUMultiPickReadbackStrategy.Individual.\r\n     *\r\n     * Defaults to 32.\r\n     */\r\n    maxIndividualReadbackCount?: number;\r\n    /**\r\n     * Minimum rectangle-area / individual-area ratio required before the automatic path uses individual readbacks.\r\n     * This value is ignored when readbackStrategy is set to GPUMultiPickReadbackStrategy.Rectangle or GPUMultiPickReadbackStrategy.Individual.\r\n     *\r\n     * Defaults to 16.\r\n     */\r\n    individualReadbackAreaRatio?: number;\r\n}\r\n\r\n/**\r\n * Class used to perform a picking operation using GPU\r\n * GPUPicker can pick meshes, instances and thin instances\r\n */\r\nexport class GPUPicker {\r\n    private static readonly _AttributeName = \"instanceMeshID\";\r\n    private static readonly _MaxPickingId = 0x00ffffff; // 24 bits unsigned integer max\r\n    private static readonly _DepthPixelRadius = 1;\r\n    private static readonly _MaxMultiPickIndividualReadbackCount = 32;\r\n    private static readonly _MultiPickIndividualReadbackAreaRatio = 16;\r\n    private static readonly _DepthNeighborOffsets = [\r\n        [-1, 1],\r\n        [0, 1],\r\n        [1, 1],\r\n        [1, 0],\r\n        [1, -1],\r\n        [0, -1],\r\n        [-1, -1],\r\n        [-1, 0],\r\n    ] as const;\r\n\r\n    private _pickingTexture: Nullable<RenderTargetTexture | MultiRenderTarget> = null;\r\n\r\n    private readonly _idMap: Array<number> = [];\r\n    private readonly _thinIdMap: Array<{ meshId: number; thinId: number }> = [];\r\n    private readonly _meshUniqueIdToPickerId: Array<number> = [];\r\n    private _idWarningIssued = false;\r\n\r\n    private _cachedScene: Nullable<Scene> = null;\r\n    private _engine: Nullable<AbstractEngine> = null;\r\n\r\n    private readonly _pickingMaterialCache: Nullable<ShaderMaterial>[] = new Array(9).fill(null);\r\n\r\n    private _pickableMeshes: Array<AbstractMesh> = [];\r\n    private readonly _meshMaterialMap: Map<AbstractMesh, Material> = new Map();\r\n    private _readbuffer: Nullable<Uint8Array> = null;\r\n    private _depthReadbuffer: Nullable<ArrayBufferView> = null;\r\n    private _depthTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    private _isDepthTexturePacked = false;\r\n    private _useDepthPicking = false;\r\n    private _isUsingDepthPickingRenderTarget = false;\r\n\r\n    private _meshRenderingCount: number = 0;\r\n    private _renderWarningIssued = false;\r\n    private _renderPickingTexture = false;\r\n\r\n    private _sceneBeforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n    private _pickingTextureClearObserver: Nullable<Observer<AbstractEngine>> = null;\r\n    private _pickingTextureAfterRenderObserver: Nullable<Observer<number>> = null;\r\n\r\n    private _nextFreeId = 1;\r\n\r\n    private readonly _gsPickingMaterials: Material[] = [];\r\n    private readonly _gsCompoundRenderMeshes: AbstractMesh[] = [];\r\n\r\n    /** Shader language used by the generator */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this generator.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    private _pickingInProgress = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the picking is in progress\r\n     */\r\n    public get pickingInProgress(): boolean {\r\n        return this._pickingInProgress;\r\n    }\r\n\r\n    /**\r\n     * Gets the default render materials used by the picker.\r\n     *\r\n     * index is Material filling mode\r\n     */\r\n    public get defaultRenderMaterials(): readonly Nullable<ShaderMaterial>[] {\r\n        return this._pickingMaterialCache;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if depth-based pickedPoint and normal reconstruction should be enabled.\r\n     *\r\n     * When disabled, GPUPicker uses the original single-color render target and shader path. When enabled, GPUPicker\r\n     * switches to a MultiRenderTarget and compiles the default picking shader with GPUPICKER_DEPTH to output both the\r\n     * picking id and the depth required to reconstruct the picked point and normal.\r\n     *\r\n     * Custom picking materials and special picking material plugins should also write the depth attachment. If they do\r\n     * not, GPUPicker will still try to reconstruct pickedPoint and normal from the depth target, but the returned values\r\n     * may be missing or incorrect.\r\n     */\r\n    public get enableDepthPicking(): boolean {\r\n        return this._useDepthPicking;\r\n    }\r\n\r\n    public set enableDepthPicking(value: boolean) {\r\n        if (this._useDepthPicking === value) {\r\n            return;\r\n        }\r\n\r\n        this._useDepthPicking = value;\r\n        this._isUsingDepthPickingRenderTarget = false;\r\n        this._depthReadbuffer = null;\r\n\r\n        let pickableMeshes: Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }> = [];\r\n        if (this._cachedScene && this._pickingTexture) {\r\n            pickableMeshes = this._pickableMeshes.map((mesh) => {\r\n                const material = this._meshMaterialMap.get(mesh);\r\n                const className = mesh.getClassName();\r\n                if (\r\n                    material instanceof ShaderMaterial &&\r\n                    !this._pickingMaterialCache.includes(material) &&\r\n                    !_IsGaussianSplattingMesh(mesh) &&\r\n                    className !== \"GaussianSplattingPartProxyMesh\"\r\n                ) {\r\n                    return { mesh, material };\r\n                }\r\n\r\n                return mesh;\r\n            });\r\n        }\r\n\r\n        this._clearPickingMaterials();\r\n\r\n        if (this._cachedScene && this._pickingTexture) {\r\n            this.clearPickingList();\r\n            this._pickingTexture.dispose();\r\n            this._pickingTexture = null;\r\n            if (pickableMeshes.length > 0) {\r\n                this.addPickingList(pickableMeshes);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getColorIdFromReadBuffer(offset: number): number {\r\n        const r = this._readbuffer![offset];\r\n        const g = this._readbuffer![offset + 1];\r\n        const b = this._readbuffer![offset + 2];\r\n        return (r << 16) + (g << 8) + b;\r\n    }\r\n\r\n    private _getReadBufferOffset(x: number, y: number, width: number, height: number): number {\r\n        const bufferY = this._cachedScene?.getEngine().isWebGPU ? height - y - 1 : y;\r\n        return (bufferY * width + x) * 4;\r\n    }\r\n\r\n    private _createColorPickingRenderTarget(scene: Scene, width: number, height: number): RenderTargetTexture {\r\n        return new RenderTargetTexture(\"pickingTexture\", { width: width, height: height }, scene, {\r\n            generateMipMaps: false,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            samplingMode: Constants.TEXTURE_NEAREST_NEAREST,\r\n        });\r\n    }\r\n\r\n    private _createRenderTarget(scene: Scene, width: number, height: number): void {\r\n        if (this._cachedScene && this._pickingTexture) {\r\n            const index = this._cachedScene.customRenderTargets.indexOf(this._pickingTexture);\r\n            if (index > -1) {\r\n                this._cachedScene.customRenderTargets.splice(index, 1);\r\n                this._renderPickingTexture = false;\r\n            }\r\n        }\r\n        if (this._pickingTexture) {\r\n            this._pickingTexture.dispose();\r\n        }\r\n        if (this._useDepthPicking) {\r\n            const engine = scene.getEngine();\r\n            const supportsDepthPickingRenderTarget = engine.isWebGPU || (engine as AbstractEngine & { webGLVersion?: number }).webGLVersion !== 1;\r\n            if (!supportsDepthPickingRenderTarget) {\r\n                Logger.Warn(\"GPUPicker depth picking requires WebGL2, WebGPU, or Native engine support. Falling back to color-only GPU picking.\");\r\n                this._useDepthPicking = false;\r\n                this._isUsingDepthPickingRenderTarget = false;\r\n                this._isDepthTexturePacked = false;\r\n                this._pickingTexture = this._createColorPickingRenderTarget(scene, width, height);\r\n                return;\r\n            }\r\n\r\n            if (engine.getCaps().textureFloatRender) {\r\n                this._depthTextureType = Constants.TEXTURETYPE_FLOAT;\r\n            } else if (engine.getCaps().textureHalfFloatRender) {\r\n                this._depthTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else {\r\n                this._depthTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            }\r\n            this._isDepthTexturePacked = this._depthTextureType === Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n            const pickingTexture = new MultiRenderTarget(\r\n                \"pickingTexture\",\r\n                { width: width, height: height },\r\n                2,\r\n                scene,\r\n                {\r\n                    generateMipMaps: false,\r\n                    generateDepthBuffer: true,\r\n                    generateStencilBuffer: false,\r\n                    types: [Constants.TEXTURETYPE_UNSIGNED_BYTE, this._depthTextureType],\r\n                    samplingModes: [Constants.TEXTURE_NEAREST_NEAREST, Constants.TEXTURE_NEAREST_NEAREST],\r\n                    formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\r\n                },\r\n                [\"pickingTexture_id\", \"pickingTexture_depth\"]\r\n            );\r\n            if (pickingTexture.isSupported) {\r\n                this._pickingTexture = pickingTexture;\r\n                this._isUsingDepthPickingRenderTarget = true;\r\n            } else {\r\n                Logger.Warn(\"GPUPicker depth picking requires MultiRenderTarget support. Falling back to color-only GPU picking.\");\r\n                this._useDepthPicking = false;\r\n                this._isUsingDepthPickingRenderTarget = false;\r\n                this._isDepthTexturePacked = false;\r\n                pickingTexture.dispose();\r\n                this._pickingTexture = this._createColorPickingRenderTarget(scene, width, height);\r\n            }\r\n        } else {\r\n            this._pickingTexture = this._createColorPickingRenderTarget(scene, width, height);\r\n            this._isUsingDepthPickingRenderTarget = false;\r\n            this._isDepthTexturePacked = false;\r\n        }\r\n    }\r\n\r\n    private _clearPickingMaterials(): void {\r\n        for (let i = 0; i < this._pickingMaterialCache.length; i++) {\r\n            const material = this._pickingMaterialCache[i];\r\n            if (material !== null) {\r\n                material.dispose();\r\n                this._pickingMaterialCache[i] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getPickingMaterial(scene: Scene, fillMode: number): ShaderMaterial {\r\n        if (fillMode < 0 || 8 < fillMode) {\r\n            fillMode = Constants.MATERIAL_TriangleFillMode;\r\n        }\r\n\r\n        const cachedMaterial = this._pickingMaterialCache[fillMode];\r\n        if (cachedMaterial) {\r\n            return cachedMaterial;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        const defines: string[] = [];\r\n        if (this._useDepthPicking) {\r\n            defines.push(\"#define GPUPICKER_DEPTH\");\r\n            if (this._isDepthTexturePacked) {\r\n                defines.push(\"#define GPUPICKER_PACK_DEPTH\");\r\n            }\r\n        }\r\n        const options: Partial<IShaderMaterialOptions> = {\r\n            attributes: [VertexBuffer.PositionKind, GPUPicker._AttributeName],\r\n            uniforms: [\"world\", \"viewProjection\", \"meshID\"],\r\n            needAlphaBlending: false,\r\n            defines: defines,\r\n            useClipPlane: null,\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await Promise.all([import(\"../ShadersWGSL/picking.fragment\"), import(\"../ShadersWGSL/picking.vertex\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../Shaders/picking.fragment\"), import(\"../Shaders/picking.vertex\")]);\r\n                }\r\n            },\r\n        };\r\n\r\n        const newMaterial = new ShaderMaterial(\"pickingShader\", scene, \"picking\", options, false);\r\n        newMaterial.fillMode = fillMode;\r\n        newMaterial.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);\r\n\r\n        this._pickingMaterialCache[fillMode] = newMaterial;\r\n        return newMaterial;\r\n    }\r\n\r\n    private _materialBindCallback(mesh: AbstractMesh | undefined): void {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const material = this._meshMaterialMap.get(mesh)!;\r\n\r\n        if (!material) {\r\n            if (!this._renderWarningIssued) {\r\n                this._renderWarningIssued = true;\r\n                Logger.Warn(\"GPUPicker issue: Mesh not found in the material map. This may happen when the root mesh of an instance is not in the picking list.\");\r\n            }\r\n            return;\r\n        }\r\n\r\n        const effect = material.getEffect();\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        if (!mesh.hasInstances && !mesh.isAnInstance && !mesh.hasThinInstances && this._meshUniqueIdToPickerId[mesh.uniqueId] !== undefined) {\r\n            effect.setFloat(\"meshID\", this._meshUniqueIdToPickerId[mesh.uniqueId]);\r\n        }\r\n\r\n        this._meshRenderingCount++;\r\n    }\r\n\r\n    /**\r\n     * Set the list of meshes to pick from\r\n     * Set that value to null to clear the list (and avoid leaks)\r\n     * The module will read and delete from the array provided by reference. Disposing the module or setting the value to null will clear the array.\r\n     * @param list defines the list of meshes to pick from\r\n     */\r\n    public setPickingList(list: Nullable<Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }>>): void {\r\n        this.clearPickingList();\r\n\r\n        if (!list || list.length === 0) {\r\n            return;\r\n        }\r\n\r\n        // Prepare target\r\n        const scene = (\"mesh\" in list[0] ? list[0].mesh : list[0]).getScene();\r\n        if (!this._cachedScene || this._cachedScene !== scene) {\r\n            this._clearPickingMaterials();\r\n        }\r\n\r\n        this.addPickingList(list);\r\n    }\r\n\r\n    /**\r\n     * Clear the current picking list and free resources\r\n     */\r\n    public clearPickingList(): void {\r\n        if (this._pickableMeshes) {\r\n            // Cleanup\r\n            for (let index = 0; index < this._pickableMeshes.length; index++) {\r\n                const mesh = this._pickableMeshes[index];\r\n                const className = mesh.getClassName();\r\n\r\n                // Skip GS part proxies - they don't have instance buffers or render list entries\r\n                if (className === \"GaussianSplattingPartProxyMesh\") {\r\n                    continue;\r\n                }\r\n\r\n                // Skip thin instance cleanup for Gaussian Splatting meshes (thin instances are for batching, not picking)\r\n                if (!_IsGaussianSplattingMesh(mesh)) {\r\n                    if (mesh.hasInstances) {\r\n                        (mesh as Mesh).removeVerticesData(GPUPicker._AttributeName);\r\n                    }\r\n                    if (mesh.hasThinInstances) {\r\n                        (mesh as Mesh).thinInstanceSetBuffer(GPUPicker._AttributeName, null);\r\n                    }\r\n                }\r\n\r\n                if (this._pickingTexture) {\r\n                    this._pickingTexture.setMaterialForRendering(mesh, undefined);\r\n                }\r\n\r\n                const material = this._meshMaterialMap.get(mesh);\r\n                if (material && !this._pickingMaterialCache.includes(material as ShaderMaterial)) {\r\n                    material.onBindObservable.removeCallback(this._materialBindCallback);\r\n                }\r\n            }\r\n\r\n            // Clean up GS compound meshes from render list\r\n            for (const mesh of this._gsCompoundRenderMeshes) {\r\n                if (this._pickingTexture) {\r\n                    this._pickingTexture.setMaterialForRendering(mesh, undefined);\r\n                }\r\n            }\r\n            this._gsCompoundRenderMeshes.length = 0;\r\n\r\n            // Dispose GS picking materials\r\n            for (const material of this._gsPickingMaterials) {\r\n                material.dispose();\r\n            }\r\n            this._gsPickingMaterials.length = 0;\r\n\r\n            this._pickableMeshes.length = 0;\r\n            this._meshMaterialMap.clear();\r\n            this._idMap.length = 0;\r\n            this._thinIdMap.length = 0;\r\n            this._meshUniqueIdToPickerId.length = 0;\r\n            if (this._pickingTexture) {\r\n                this._pickingTexture.renderList = [];\r\n            }\r\n        }\r\n\r\n        this._nextFreeId = 1;\r\n    }\r\n\r\n    /**\r\n     * Add array of meshes to the current picking list\r\n     * @param list defines the array of meshes to add to the current picking list\r\n     */\r\n    public addPickingList(list: Array<AbstractMesh | { mesh: AbstractMesh; material: ShaderMaterial }>): void {\r\n        if (!list || list.length === 0) {\r\n            return;\r\n        }\r\n\r\n        // Prepare target\r\n        const scene = (\"mesh\" in list[0] ? list[0].mesh : list[0]).getScene();\r\n        const engine = scene.getEngine();\r\n        const rttSizeW = engine.getRenderWidth();\r\n        const rttSizeH = engine.getRenderHeight();\r\n        if (!this._pickingTexture) {\r\n            this._createRenderTarget(scene, rttSizeW, rttSizeH);\r\n        } else {\r\n            const size = this._pickingTexture.getSize();\r\n\r\n            if (size.width !== rttSizeW || size.height !== rttSizeH || this._cachedScene !== scene) {\r\n                this._createRenderTarget(scene, rttSizeW, rttSizeH);\r\n            }\r\n        }\r\n\r\n        this._sceneBeforeRenderObserver?.remove();\r\n        this._sceneBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {\r\n            if (scene.frameGraph && this._renderPickingTexture && this._cachedScene && this._pickingTexture) {\r\n                this._cachedScene._renderRenderTarget(this._pickingTexture, this._cachedScene.cameras?.[0] ?? null);\r\n                this._cachedScene.activeCamera = null;\r\n            }\r\n        });\r\n\r\n        this._cachedScene = scene;\r\n        this._engine = scene.getEngine();\r\n        if (!this._pickingTexture!.renderList) {\r\n            this._pickingTexture!.renderList = [];\r\n        }\r\n\r\n        const newPickableMeshes: AbstractMesh[] = new Array(list.length);\r\n        const pickableMeshOffset = this._pickableMeshes?.length ?? 0;\r\n\r\n        this._cachedScene = scene;\r\n        this._engine = scene.getEngine();\r\n\r\n        for (let i = 0; i < list.length; i++) {\r\n            const item = list[i];\r\n            if (\"mesh\" in item) {\r\n                this._meshMaterialMap.set(item.mesh, item.material);\r\n                newPickableMeshes[i] = item.mesh;\r\n            } else {\r\n                const className = item.getClassName();\r\n                if (_IsGaussianSplattingMesh(item) || className === \"GaussianSplattingPartProxyMesh\") {\r\n                    // GS meshes get special picking materials - handled in the ID assignment loop below\r\n                    newPickableMeshes[i] = item;\r\n                } else {\r\n                    const material = this._getPickingMaterial(scene, item.material?.fillMode ?? Constants.MATERIAL_TriangleFillMode);\r\n                    this._meshMaterialMap.set(item, material);\r\n                    newPickableMeshes[i] = item;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._pickableMeshes !== null) {\r\n            this._pickableMeshes = [...this._pickableMeshes, ...newPickableMeshes];\r\n        } else {\r\n            this._pickableMeshes = newPickableMeshes;\r\n        }\r\n\r\n        // We will affect colors and create vertex color buffers\r\n        let nextFreeId = this._nextFreeId;\r\n\r\n        // Collect GaussianSplatting part proxy groups for compound picking\r\n        const gsCompoundGroups: { compound: AbstractMesh; partEntries: { proxy: AbstractMesh; globalIndex: number }[] }[] = [];\r\n\r\n        for (let index = 0; index < newPickableMeshes.length; index++) {\r\n            const mesh = newPickableMeshes[index];\r\n            const className = mesh.getClassName();\r\n\r\n            // Handle GaussianSplatting part proxy meshes - collect by compound for processing after the loop\r\n            if (className === \"GaussianSplattingPartProxyMesh\") {\r\n                const proxy = mesh as any; // GaussianSplattingPartProxyMesh\r\n                const compound = proxy.compoundSplatMesh;\r\n                const globalIndex = index + pickableMeshOffset;\r\n\r\n                let group = gsCompoundGroups[compound.uniqueId];\r\n                if (!group) {\r\n                    group = { compound, partEntries: [] };\r\n                    gsCompoundGroups[compound.uniqueId] = group;\r\n                }\r\n                group.partEntries.push({ proxy, globalIndex });\r\n                continue; // Don't add to render list - the compound mesh will render for all parts\r\n            }\r\n\r\n            // Handle non-compound GaussianSplatting meshes (including streamed)\r\n            if (_IsGaussianSplattingMesh(mesh)) {\r\n                const globalIndex = index + pickableMeshOffset;\r\n                const pickId = nextFreeId;\r\n                this._idMap[pickId] = globalIndex;\r\n                this._meshUniqueIdToPickerId[mesh.uniqueId] = pickId;\r\n                nextFreeId++;\r\n\r\n                if (!mesh.isPickable || !mesh.isVisible) {\r\n                    continue;\r\n                }\r\n\r\n                // Create a GaussianSplattingMaterial with picking plugin for GPU picking\r\n                const gsPickingMaterial = this._createGaussianSplattingPickingMaterial(scene, mesh);\r\n                const plugin = gsPickingMaterial.pluginManager!.getPlugin<GaussianSplattingGpuPickingMaterialPlugin>(\"GaussianSplatGpuPicking\")!;\r\n                plugin.meshId = pickId;\r\n\r\n                gsPickingMaterial.onBindObservable.add(() => {\r\n                    this._meshRenderingCount++;\r\n                });\r\n\r\n                this._gsPickingMaterials.push(gsPickingMaterial);\r\n                this._meshMaterialMap.set(mesh, gsPickingMaterial);\r\n                this._pickingTexture!.setMaterialForRendering(mesh, gsPickingMaterial);\r\n                this._pickingTexture!.renderList!.push(mesh);\r\n                continue;\r\n            }\r\n\r\n            // Standard mesh processing\r\n            const material = this._meshMaterialMap.get(mesh)!;\r\n\r\n            if (!this._pickingMaterialCache.includes(material as ShaderMaterial)) {\r\n                material.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);\r\n            }\r\n            this._pickingTexture!.setMaterialForRendering(mesh, material);\r\n            this._pickingTexture!.renderList!.push(mesh);\r\n\r\n            if (mesh.isAnInstance) {\r\n                continue; // This will be handled by the source mesh\r\n            }\r\n\r\n            const globalIndex = index + pickableMeshOffset;\r\n\r\n            if (mesh.hasThinInstances) {\r\n                const thinInstanceCount = (mesh as Mesh).thinInstanceCount;\r\n                const instanceIdData = new Float32Array(thinInstanceCount);\r\n                for (let i = 0; i < thinInstanceCount; i++) {\r\n                    instanceIdData[i] = nextFreeId;\r\n                    this._thinIdMap[nextFreeId] = { meshId: globalIndex, thinId: i };\r\n                    nextFreeId++;\r\n                }\r\n                (mesh as Mesh).thinInstanceSetBuffer(GPUPicker._AttributeName, instanceIdData, 1);\r\n            } else {\r\n                const currentMeshId = nextFreeId;\r\n                this._idMap[currentMeshId] = globalIndex;\r\n                nextFreeId++;\r\n\r\n                if (mesh.hasInstances) {\r\n                    // find index of instances of that mesh\r\n                    const instancesForPick: number[] = [];\r\n                    for (let pickableMeshIndex = 0; pickableMeshIndex < newPickableMeshes.length; ++pickableMeshIndex) {\r\n                        const m = newPickableMeshes[pickableMeshIndex];\r\n                        if (m.isAnInstance && (m as InstancedMesh).sourceMesh === mesh) {\r\n                            instancesForPick.push(pickableMeshIndex);\r\n                        }\r\n                    }\r\n                    const instanceIdData = new Float32Array(instancesForPick.length + 1); // +1 for the source mesh\r\n\r\n                    instanceIdData[0] = currentMeshId;\r\n                    for (let i = 0; i < instancesForPick.length; i++) {\r\n                        instanceIdData[i + 1] = nextFreeId;\r\n                        const globalInstanceIndex = instancesForPick[i] + pickableMeshOffset;\r\n                        this._idMap[nextFreeId] = globalInstanceIndex;\r\n                        nextFreeId++;\r\n                    }\r\n\r\n                    const engine = mesh.getEngine();\r\n                    const buffer = new VertexBuffer(engine, instanceIdData, GPUPicker._AttributeName, false, false, 1, true);\r\n                    (mesh as Mesh).setVerticesBuffer(buffer, true);\r\n                } else {\r\n                    this._meshUniqueIdToPickerId[mesh.uniqueId] = currentMeshId;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Process GaussianSplatting compound groups (part proxy meshes)\r\n        for (const group of gsCompoundGroups) {\r\n            if (!group) {\r\n                continue;\r\n            }\r\n            const compound = group.compound;\r\n\r\n            // Assign picking IDs for each part\r\n            const partMeshIds: number[] = new Array((compound as any).partCount || 1).fill(0);\r\n            for (const entry of group.partEntries) {\r\n                const pickId = nextFreeId;\r\n                this._idMap[pickId] = entry.globalIndex;\r\n                const partIndex = (entry.proxy as any).partIndex;\r\n                if (partIndex < partMeshIds.length) {\r\n                    partMeshIds[partIndex] = pickId;\r\n                }\r\n                nextFreeId++;\r\n            }\r\n\r\n            // Create compound GS picking material with plugin\r\n            const gsPickingMaterial = this._createGaussianSplattingPickingMaterial(scene, compound);\r\n            const plugin = gsPickingMaterial.pluginManager!.getPlugin<GaussianSplattingGpuPickingMaterialPlugin>(\"GaussianSplatGpuPicking\")!;\r\n            plugin.isCompound = true;\r\n            plugin.partMeshIds = partMeshIds;\r\n            // Only active (included, enabled, visible, and pickable) parts should contribute to the depth buffer.\r\n            const activeParts = group.partEntries.filter((e) => this._isPartProxyActiveForPicking(e.proxy as AbstractMesh)).map((e) => (e.proxy as any).partIndex as number);\r\n            plugin.setPartActive(activeParts);\r\n\r\n            gsPickingMaterial.onBindObservable.add(() => {\r\n                this._meshRenderingCount++;\r\n            });\r\n\r\n            this._gsPickingMaterials.push(gsPickingMaterial);\r\n            this._meshMaterialMap.set(compound, gsPickingMaterial);\r\n            this._pickingTexture!.setMaterialForRendering(compound, gsPickingMaterial);\r\n            this._pickingTexture!.renderList!.push(compound);\r\n            this._gsCompoundRenderMeshes.push(compound);\r\n        }\r\n\r\n        if (GPUPicker._MaxPickingId < nextFreeId - 1) {\r\n            if (!this._idWarningIssued) {\r\n                this._idWarningIssued = true;\r\n                Logger.Warn(`GPUPicker maximum number of pickable meshes and instances is ${GPUPicker._MaxPickingId}. Some meshes or instances won't be pickable.`);\r\n            }\r\n        }\r\n\r\n        this._nextFreeId = nextFreeId;\r\n    }\r\n\r\n    /**\r\n     * Execute a picking operation\r\n     * @param x defines the X coordinates where to run the pick\r\n     * @param y defines the Y coordinates where to run the pick\r\n     * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n     * @returns A promise with the picking results\r\n     */\r\n    public async pickAsync(x: number, y: number, disposeWhenDone = false): Promise<Nullable<IGPUPickingInfo>> {\r\n        if (this._pickingInProgress) {\r\n            return null;\r\n        }\r\n\r\n        if (!this._pickableMeshes || this._pickableMeshes.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        const { rttSizeW, rttSizeH, scaleX, scaleY } = this._getRenderInfo();\r\n\r\n        const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y, scaleX, scaleY);\r\n        if (adjustedX < 0 || adjustedY < 0 || adjustedX >= rttSizeW || adjustedY >= rttSizeH) {\r\n            return null;\r\n        }\r\n\r\n        this._pickingInProgress = true;\r\n\r\n        // Invert Y\r\n        const invertedY = rttSizeH - adjustedY - 1;\r\n        const pickingRegion = this._getPickingRenderRegion(adjustedX, invertedY, rttSizeW, rttSizeH);\r\n        this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, pickingRegion.x, pickingRegion.y, pickingRegion.width, pickingRegion.height);\r\n\r\n        await this._waitForPickingMaterialsReadyAsync();\r\n        this._addPickingTextureToRenderTargets();\r\n\r\n        return await this._executePickingAsync(adjustedX, invertedY, disposeWhenDone);\r\n    }\r\n\r\n    /**\r\n     * Execute a picking operation on multiple coordinates\r\n     * @param xy defines the X,Y coordinates where to run the pick\r\n     * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n     * @param options defines options used to tune the multi pick readback strategy\r\n     * @returns A promise with the picking results. Always returns an array with the same length as the number of coordinates. The mesh or null at the index where no mesh was picked.\r\n     */\r\n    public async multiPickAsync(xy: IVector2Like[], disposeWhenDone = false, options?: IGPUMultiPickOptions): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n        if (this._pickingInProgress) {\r\n            return null;\r\n        }\r\n\r\n        if (!this._pickableMeshes || this._pickableMeshes.length === 0 || xy.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (xy.length === 1) {\r\n            const pi = await this.pickAsync(xy[0].x, xy[0].y, disposeWhenDone);\r\n            const result: IGPUMultiPickingInfo = {\r\n                meshes: [pi?.mesh ?? null],\r\n                thinInstanceIndexes: pi?.thinInstanceIndex !== undefined ? [pi.thinInstanceIndex] : undefined,\r\n            };\r\n            if (this._useDepthPicking) {\r\n                result.pickedPoints = [pi?.pickedPoint ?? null];\r\n                result.normals = [pi?.normal ?? null];\r\n            }\r\n            return result;\r\n        }\r\n\r\n        this._pickingInProgress = true;\r\n\r\n        const processedXY = new Array<IVector2Like>(xy.length);\r\n\r\n        let minX = Infinity;\r\n        let maxX = -Infinity;\r\n        let minY = Infinity;\r\n        let maxY = -Infinity;\r\n\r\n        const { rttSizeW, rttSizeH, scaleX, scaleY } = this._getRenderInfo();\r\n        let hasInBoundsPoint = false;\r\n        let inBoundsPointCount = 0;\r\n\r\n        // Process screen coordinates adjust to dpr\r\n        for (let i = 0; i < xy.length; i++) {\r\n            const item = xy[i];\r\n            const { x, y } = item;\r\n            const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y, scaleX, scaleY);\r\n            processedXY[i] = {\r\n                ...item,\r\n                x: adjustedX,\r\n                y: adjustedY,\r\n            };\r\n\r\n            if (adjustedX < 0 || adjustedY < 0 || adjustedX >= rttSizeW || adjustedY >= rttSizeH) {\r\n                continue;\r\n            }\r\n\r\n            hasInBoundsPoint = true;\r\n            inBoundsPointCount++;\r\n            minX = Math.min(minX, adjustedX);\r\n            maxX = Math.max(maxX, adjustedX);\r\n            minY = Math.min(minY, adjustedY);\r\n            maxY = Math.max(maxY, adjustedY);\r\n        }\r\n\r\n        if (!hasInBoundsPoint) {\r\n            this._pickingInProgress = false;\r\n            return null;\r\n        }\r\n\r\n        const depthPadding = this._useDepthPicking ? GPUPicker._DepthPixelRadius : 0;\r\n        const regionLeft = Math.max(minX - depthPadding, 0);\r\n        const regionRight = Math.min(maxX + depthPadding, rttSizeW - 1);\r\n        const regionTop = Math.max(minY - depthPadding, 0);\r\n        const regionBottom = Math.min(maxY + depthPadding, rttSizeH - 1);\r\n\r\n        if (regionLeft >= rttSizeW || regionTop >= rttSizeH || regionRight < 0 || regionBottom < 0) {\r\n            this._pickingInProgress = false;\r\n            return null;\r\n        }\r\n\r\n        const w = regionRight - regionLeft + 1;\r\n        const h = regionBottom - regionTop + 1;\r\n        const partialCutH = rttSizeH - regionBottom - 1;\r\n        const useIndividualReadback = this._shouldUseIndividualMultiPickReadback(inBoundsPointCount, w * h, options);\r\n\r\n        this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, regionLeft, partialCutH, w, h, useIndividualReadback ? 1 : w, useIndividualReadback ? 1 : h);\r\n\r\n        await this._waitForPickingMaterialsReadyAsync();\r\n        this._addPickingTextureToRenderTargets();\r\n\r\n        return await this._executeMultiPickingAsync(processedXY, regionLeft, partialCutH, rttSizeW, rttSizeH, w, h, useIndividualReadback, disposeWhenDone);\r\n    }\r\n\r\n    /**\r\n     * Execute a picking operation on box defined by two screen coordinates\r\n     * @param x1 defines the X coordinate of the first corner of the box where to run the pick\r\n     * @param y1 defines the Y coordinate of the first corner of the box where to run the pick\r\n     * @param x2 defines the X coordinate of the opposite corner of the box where to run the pick\r\n     * @param y2 defines the Y coordinate of the opposite corner of the box where to run the pick\r\n     * @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)\r\n     * @returns A promise with the picking results. Contains one entry for each picked pixel in the box.\r\n     */\r\n    public async boxPickAsync(x1: number, y1: number, x2: number, y2: number, disposeWhenDone = false): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n        if (this._pickingInProgress) {\r\n            return null;\r\n        }\r\n\r\n        if (!this._pickableMeshes || this._pickableMeshes.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        this._pickingInProgress = true;\r\n\r\n        const { rttSizeW, rttSizeH, scaleX, scaleY } = this._getRenderInfo();\r\n\r\n        const { x: adjustedX1, y: adjustedY1 } = this._prepareForPicking(x1, y1, scaleX, scaleY);\r\n        const { x: adjustedX2, y: adjustedY2 } = this._prepareForPicking(x2, y2, scaleX, scaleY);\r\n\r\n        const minX = Math.max(Math.min(adjustedX1, adjustedX2), 0);\r\n        const maxX = Math.min(Math.max(adjustedX1, adjustedX2), rttSizeW - 1);\r\n        const minY = Math.max(Math.min(adjustedY1, adjustedY2), 0);\r\n        const maxY = Math.min(Math.max(adjustedY1, adjustedY2), rttSizeH - 1);\r\n\r\n        if (minX >= rttSizeW || minY >= rttSizeH || maxX < 0 || maxY < 0) {\r\n            this._pickingInProgress = false;\r\n            return null;\r\n        }\r\n\r\n        const depthPadding = this._useDepthPicking ? GPUPicker._DepthPixelRadius : 0;\r\n        const regionLeft = Math.max(minX - depthPadding, 0);\r\n        const regionRight = Math.min(maxX + depthPadding, rttSizeW - 1);\r\n        const regionTop = Math.max(minY - depthPadding, 0);\r\n        const regionBottom = Math.min(maxY + depthPadding, rttSizeH - 1);\r\n        const w = regionRight - regionLeft + 1;\r\n        const h = regionBottom - regionTop + 1;\r\n        const partialCutH = rttSizeH - regionBottom - 1;\r\n\r\n        this._preparePickingBuffer(this._engine!, rttSizeW, rttSizeH, regionLeft, partialCutH, w, h);\r\n\r\n        await this._waitForPickingMaterialsReadyAsync();\r\n        this._addPickingTextureToRenderTargets();\r\n\r\n        return await this._executeBoxPickingAsync(\r\n            minX,\r\n            maxY,\r\n            Math.max(maxX - minX, 1),\r\n            Math.max(maxY - minY, 1),\r\n            regionLeft,\r\n            partialCutH,\r\n            rttSizeW,\r\n            rttSizeH,\r\n            w,\r\n            h,\r\n            disposeWhenDone\r\n        );\r\n    }\r\n\r\n    private _getRenderInfo(): { rttSizeW: number; rttSizeH: number; scaleX: number; scaleY: number } {\r\n        const engine = this._cachedScene!.getEngine();\r\n        const rttSizeW = engine.getRenderWidth();\r\n        const rttSizeH = engine.getRenderHeight();\r\n        // Picking coordinates are expected in input/canvas CSS pixels, matching Babylon pointer coordinates.\r\n        // Use the actual client rect so CSS scaling/stretching is handled, and fall back to hardware scaling\r\n        // for engines without a DOM input element.\r\n        let inputElementClientRect: Nullable<ClientRect> = null;\r\n        try {\r\n            inputElementClientRect = engine.getInputElementClientRect();\r\n        } catch {\r\n            // Non-DOM or pure engine builds may not register the DOM side effect. Fall back below.\r\n        }\r\n        const scaleX = inputElementClientRect?.width ? rttSizeW / inputElementClientRect.width : 1 / engine._hardwareScalingLevel;\r\n        const scaleY = inputElementClientRect?.height ? rttSizeH / inputElementClientRect.height : 1 / engine._hardwareScalingLevel;\r\n\r\n        return {\r\n            rttSizeW,\r\n            rttSizeH,\r\n            scaleX,\r\n            scaleY,\r\n        };\r\n    }\r\n\r\n    private _prepareForPicking(x: number, y: number, scaleX: number, scaleY: number): IVector2Like {\r\n        return { x: (scaleX * x) >> 0, y: (scaleY * y) >> 0 };\r\n    }\r\n\r\n    private _getPickingRenderRegion(x: number, y: number, renderWidth: number, renderHeight: number): { x: number; y: number; width: number; height: number } {\r\n        if (!this._useDepthPicking) {\r\n            return { x, y, width: 1, height: 1 };\r\n        }\r\n\r\n        const radius = GPUPicker._DepthPixelRadius;\r\n        const left = Math.max(x - radius, 0);\r\n        const bottom = Math.max(y - radius, 0);\r\n        const right = Math.min(x + radius, renderWidth - 1);\r\n        const top = Math.min(y + radius, renderHeight - 1);\r\n\r\n        return {\r\n            x: left,\r\n            y: bottom,\r\n            width: right - left + 1,\r\n            height: top - bottom + 1,\r\n        };\r\n    }\r\n\r\n    private _shouldUseIndividualMultiPickReadback(inBoundsPointCount: number, readArea: number, options?: IGPUMultiPickOptions): boolean {\r\n        const readbackStrategy = options?.readbackStrategy ?? GPUMultiPickReadbackStrategy.Auto;\r\n        if (inBoundsPointCount === 0 || readbackStrategy === GPUMultiPickReadbackStrategy.Rectangle) {\r\n            return false;\r\n        }\r\n\r\n        if (readbackStrategy === GPUMultiPickReadbackStrategy.Individual) {\r\n            return true;\r\n        }\r\n\r\n        const maxIndividualReadbackCount =\r\n            options?.maxIndividualReadbackCount !== undefined && Number.isFinite(options.maxIndividualReadbackCount) && options.maxIndividualReadbackCount >= 0\r\n                ? options.maxIndividualReadbackCount\r\n                : GPUPicker._MaxMultiPickIndividualReadbackCount;\r\n        if (inBoundsPointCount > maxIndividualReadbackCount) {\r\n            return false;\r\n        }\r\n\r\n        const individualReadbackAreaRatio =\r\n            options?.individualReadbackAreaRatio !== undefined && Number.isFinite(options.individualReadbackAreaRatio) && options.individualReadbackAreaRatio > 0\r\n                ? options.individualReadbackAreaRatio\r\n                : GPUPicker._MultiPickIndividualReadbackAreaRatio;\r\n        const pointReadArea = inBoundsPointCount * (this._useDepthPicking ? 1 + (GPUPicker._DepthPixelRadius * 2 + 1) ** 2 : 1);\r\n        return readArea > pointReadArea * individualReadbackAreaRatio;\r\n    }\r\n\r\n    private _isPartProxyActiveForPicking(proxy: Pick<AbstractMesh, \"isEnabled\" | \"isPickable\" | \"isVisible\">): boolean {\r\n        return proxy.isEnabled() && proxy.isPickable && proxy.isVisible;\r\n    }\r\n\r\n    private _preparePickingBuffer(engine: AbstractEngine, rttSizeW: number, rttSizeH: number, x: number, y: number, w = 1, h = 1, readBufferW = w, readBufferH = h): void {\r\n        this._meshRenderingCount = 0;\r\n\r\n        const requiredBufferSize = engine.isWebGPU ? (4 * readBufferW * readBufferH + 255) & ~255 : 4 * readBufferW * readBufferH;\r\n        if (!this._readbuffer || this._readbuffer.length < requiredBufferSize) {\r\n            this._readbuffer = new Uint8Array(requiredBufferSize);\r\n        }\r\n\r\n        // Do we need to rebuild the RTT?\r\n        const size = this._pickingTexture!.getSize();\r\n        if (size.width !== rttSizeW || size.height !== rttSizeH) {\r\n            this._createRenderTarget(this._cachedScene!, rttSizeW, rttSizeH);\r\n            this._updateRenderList();\r\n        }\r\n\r\n        this._pickingTexture!.clearColor = new Color4(0, 0, 0, 0);\r\n\r\n        this._pickingTextureClearObserver?.remove();\r\n        this._pickingTextureClearObserver = this._pickingTexture!.onClearObservable.add((engine) => {\r\n            if (this._isUsingDepthPickingRenderTarget) {\r\n                engine.bindAttachments(engine.buildTextureLayout([true, false]));\r\n            }\r\n            engine.clear(this._pickingTexture!.clearColor, true, true, true);\r\n            if (this._isUsingDepthPickingRenderTarget) {\r\n                engine.bindAttachments(engine.buildTextureLayout([true, true]));\r\n            }\r\n        });\r\n\r\n        this._pickingTexture!.onBeforeRender = (): void => {\r\n            this._enableScissor(x, y, w, h);\r\n        };\r\n\r\n        this._pickingTextureAfterRenderObserver?.remove();\r\n        this._pickingTextureAfterRenderObserver = this._pickingTexture!.onAfterRenderObservable.add(() => {\r\n            this._disableScissor();\r\n        });\r\n    }\r\n\r\n    private _addPickingTextureToRenderTargets(): void {\r\n        this._removePickingTextureFromRenderTargets();\r\n        this._cachedScene!.customRenderTargets.push(this._pickingTexture!);\r\n        this._renderPickingTexture = true;\r\n    }\r\n\r\n    private _removePickingTextureFromRenderTargets(): void {\r\n        if (!this._cachedScene || !this._pickingTexture) {\r\n            return;\r\n        }\r\n\r\n        const index = this._cachedScene.customRenderTargets.indexOf(this._pickingTexture);\r\n        if (index > -1) {\r\n            this._cachedScene.customRenderTargets.splice(index, 1);\r\n            this._renderPickingTexture = false;\r\n        }\r\n    }\r\n\r\n    // pick one pixel\r\n    private async _executePickingAsync(x: number, y: number, disposeWhenDone: boolean): Promise<Nullable<IGPUPickingInfo>> {\r\n        return await new Promise((resolve, reject) => {\r\n            if (!this._pickingTexture) {\r\n                this._pickingInProgress = false;\r\n                reject(new Error(\"Picking texture not created\"));\r\n                return;\r\n            }\r\n\r\n            // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n            this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n                if (this._checkRenderStatus()) {\r\n                    try {\r\n                        this._pickingTexture!.onAfterRender = null as any;\r\n                        let pickedMesh: Nullable<AbstractMesh> = null;\r\n                        let thinInstanceIndex: number | undefined = undefined;\r\n\r\n                        this._removePickingTextureFromRenderTargets();\r\n\r\n                        // Do the actual picking\r\n                        if (await this._readTexturePixelsAsync(x, y)) {\r\n                            const colorId = this._getColorIdFromReadBuffer(0);\r\n\r\n                            // Thin?\r\n                            if (this._thinIdMap[colorId]) {\r\n                                pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n                                thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n                            } else {\r\n                                pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n                            }\r\n                        }\r\n\r\n                        // Depth reconstruction is guaranteed for GPUPicker's default picking shader. Custom picking\r\n                        // materials and special material plugins can also work if they write the second MRT attachment;\r\n                        // otherwise the reconstructed pickedPoint/normal may be missing or incorrect.\r\n                        let depthPickingInfo: Nullable<{ pickedPoint?: Vector3; normal?: Vector3 }> = null;\r\n                        if (this._useDepthPicking && pickedMesh) {\r\n                            const camera = this._cachedScene!.activeCamera;\r\n                            if (camera) {\r\n                                const { rttSizeW, rttSizeH } = this._getRenderInfo();\r\n                                const viewport = camera.viewport.toGlobal(rttSizeW, rttSizeH);\r\n                                const view = this._cachedScene!.getViewMatrix().clone();\r\n                                const projection = this._cachedScene!.getProjectionMatrix().clone();\r\n                                const cameraPosition = camera.globalPosition.clone();\r\n                                depthPickingInfo = await this._getDepthPickingInfoAsync(x, y, rttSizeW, rttSizeH, view, projection, cameraPosition, viewport);\r\n                            }\r\n                        }\r\n                        if (disposeWhenDone) {\r\n                            this.dispose();\r\n                        }\r\n\r\n                        this._pickingInProgress = false;\r\n                        if (pickedMesh) {\r\n                            resolve({ mesh: pickedMesh, thinInstanceIndex: thinInstanceIndex, ...depthPickingInfo });\r\n                        } else {\r\n                            resolve(null);\r\n                        }\r\n                    } catch (error) {\r\n                        this._removePickingTextureFromRenderTargets();\r\n                        this._pickingInProgress = false;\r\n                        reject(error instanceof Error ? error : new Error(`${error}`));\r\n                    }\r\n                }\r\n            };\r\n        });\r\n    }\r\n\r\n    // pick multiple pixels\r\n    private async _executeMultiPickingAsync(\r\n        xy: IVector2Like[],\r\n        readX: number,\r\n        readY: number,\r\n        rttSizeW: number,\r\n        rttSizeH: number,\r\n        w: number,\r\n        h: number,\r\n        useIndividualReadback: boolean,\r\n        disposeWhenDone: boolean\r\n    ): Promise<Nullable<IGPUMultiPickingInfo>> {\r\n        return await new Promise((resolve, reject) => {\r\n            if (!this._pickingTexture) {\r\n                this._pickingInProgress = false;\r\n                reject(new Error(\"Picking texture not created\"));\r\n                return;\r\n            }\r\n\r\n            // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n            this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n                if (this._checkRenderStatus()) {\r\n                    try {\r\n                        this._pickingTexture!.onAfterRender = null as any;\r\n                        const pickedMeshes = new Array<Nullable<AbstractMesh>>(xy.length).fill(null);\r\n                        const thinInstanceIndexes = new Array<number>(xy.length).fill(0);\r\n\r\n                        if (useIndividualReadback) {\r\n                            for (let i = 0; i < xy.length; i++) {\r\n                                const pointBottomY = rttSizeH - xy[i].y - 1;\r\n                                if (xy[i].x < 0 || pointBottomY < 0 || xy[i].x >= rttSizeW || pointBottomY >= rttSizeH) {\r\n                                    continue;\r\n                                }\r\n\r\n                                // eslint-disable-next-line no-await-in-loop\r\n                                if (await this._readTexturePixelsAsync(xy[i].x, pointBottomY, 1, 1)) {\r\n                                    const { pickedMesh, thinInstanceIndex } = this._getMeshFromReadBuffer(0);\r\n                                    pickedMeshes[i] = pickedMesh;\r\n                                    thinInstanceIndexes[i] = thinInstanceIndex ?? 0;\r\n                                }\r\n                            }\r\n                        } else {\r\n                            if (await this._readTexturePixelsAsync(readX, readY, w, h)) {\r\n                                for (let i = 0; i < xy.length; i++) {\r\n                                    const { pickedMesh, thinInstanceIndex } = this._getMeshFromMultiplePoints(xy[i].x, xy[i].y, readX, readY, rttSizeH, w, h);\r\n                                    pickedMeshes[i] = pickedMesh;\r\n                                    thinInstanceIndexes[i] = thinInstanceIndex ?? 0;\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        let pickedPoints: Nullable<Vector3>[] | undefined;\r\n                        let normals: Nullable<Vector3>[] | undefined;\r\n                        if (this._useDepthPicking) {\r\n                            pickedPoints = new Array(xy.length).fill(null);\r\n                            normals = new Array(xy.length).fill(null);\r\n                        }\r\n\r\n                        if (pickedPoints && normals && pickedMeshes.some((mesh) => !!mesh)) {\r\n                            const camera = this._cachedScene!.activeCamera;\r\n                            if (camera) {\r\n                                const viewport = camera.viewport.toGlobal(rttSizeW, rttSizeH);\r\n                                const view = this._cachedScene!.getViewMatrix().clone();\r\n                                const projection = this._cachedScene!.getProjectionMatrix().clone();\r\n                                const cameraPosition = camera.globalPosition.clone();\r\n\r\n                                if (useIndividualReadback) {\r\n                                    for (let i = 0; i < xy.length; i++) {\r\n                                        if (!pickedMeshes[i]) {\r\n                                            continue;\r\n                                        }\r\n\r\n                                        const pointY = rttSizeH - xy[i].y - 1;\r\n                                        // eslint-disable-next-line no-await-in-loop\r\n                                        const depthPickingInfo = await this._getDepthPickingInfoAsync(\r\n                                            xy[i].x,\r\n                                            pointY,\r\n                                            rttSizeW,\r\n                                            rttSizeH,\r\n                                            view,\r\n                                            projection,\r\n                                            cameraPosition,\r\n                                            viewport\r\n                                        );\r\n                                        pickedPoints[i] = depthPickingInfo?.pickedPoint ?? null;\r\n                                        normals[i] = depthPickingInfo?.normal ?? null;\r\n                                    }\r\n                                } else {\r\n                                    const depthPixels = await this._readDepthTexturePixelsAsync(readX, readY, w, h);\r\n                                    if (depthPixels) {\r\n                                        for (let i = 0; i < xy.length; i++) {\r\n                                            if (!pickedMeshes[i]) {\r\n                                                continue;\r\n                                            }\r\n\r\n                                            const pointY = rttSizeH - xy[i].y - 1;\r\n                                            const depthPickingInfo = this._getDepthPickingInfoFromBuffer(\r\n                                                depthPixels,\r\n                                                xy[i].x,\r\n                                                pointY,\r\n                                                readX,\r\n                                                readY,\r\n                                                w,\r\n                                                h,\r\n                                                rttSizeH,\r\n                                                view,\r\n                                                projection,\r\n                                                cameraPosition,\r\n                                                viewport\r\n                                            );\r\n                                            pickedPoints[i] = depthPickingInfo?.pickedPoint ?? null;\r\n                                            normals[i] = depthPickingInfo?.normal ?? null;\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        if (disposeWhenDone) {\r\n                            this.dispose();\r\n                        }\r\n\r\n                        this._pickingInProgress = false;\r\n                        resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes, pickedPoints, normals });\r\n                    } catch (error) {\r\n                        this._removePickingTextureFromRenderTargets();\r\n                        this._pickingInProgress = false;\r\n                        reject(error instanceof Error ? error : new Error(`${error}`));\r\n                    }\r\n                }\r\n            };\r\n        });\r\n    }\r\n\r\n    // pick box area\r\n    private async _executeBoxPickingAsync(\r\n        scanX: number,\r\n        scanMaxY: number,\r\n        scanW: number,\r\n        scanH: number,\r\n        readX: number,\r\n        readY: number,\r\n        rttSizeW: number,\r\n        rttSizeH: number,\r\n        readW: number,\r\n        readH: number,\r\n        disposeWhenDone: boolean\r\n    ): Promise<IGPUMultiPickingInfo> {\r\n        return await new Promise((resolve, reject) => {\r\n            if (!this._pickingTexture) {\r\n                this._pickingInProgress = false;\r\n                reject(new Error(\"Picking texture not created\"));\r\n                return;\r\n            }\r\n\r\n            // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n            this._pickingTexture.onAfterRender = async (): Promise<void> => {\r\n                if (this._checkRenderStatus()) {\r\n                    try {\r\n                        this._pickingTexture!.onAfterRender = null as any;\r\n                        const pickedMeshes: Nullable<AbstractMesh>[] = [];\r\n                        const thinInstanceIndexes: number[] = [];\r\n                        const pickedPixelCoordinates: IVector2Like[] = [];\r\n                        const scanBufferX = scanX - readX;\r\n                        const scanBufferY = rttSizeH - scanMaxY - 1 - readY;\r\n\r\n                        if (await this._readTexturePixelsAsync(readX, readY, readW, readH)) {\r\n                            for (let offsetY = 0; offsetY < scanH; ++offsetY) {\r\n                                for (let offsetX = 0; offsetX < scanW; ++offsetX) {\r\n                                    const bufferX = scanBufferX + offsetX;\r\n                                    const bufferY = scanBufferY + offsetY;\r\n                                    if (bufferX < 0 || bufferY < 0 || bufferX >= readW || bufferY >= readH) {\r\n                                        continue;\r\n                                    }\r\n\r\n                                    const colorId = this._getColorIdFromReadBuffer(this._getReadBufferOffset(bufferX, bufferY, readW, readH));\r\n                                    if (colorId > 0) {\r\n                                        // Thin?\r\n                                        if (this._thinIdMap[colorId]) {\r\n                                            const pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n                                            const thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n                                            pickedMeshes.push(pickedMesh);\r\n                                            thinInstanceIndexes.push(thinInstanceIndex);\r\n                                            pickedPixelCoordinates.push({ x: scanX + offsetX, y: scanMaxY - offsetY });\r\n                                        } else {\r\n                                            const pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n                                            pickedMeshes.push(pickedMesh);\r\n                                            thinInstanceIndexes.push(0);\r\n                                            pickedPixelCoordinates.push({ x: scanX + offsetX, y: scanMaxY - offsetY });\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        let pickedPoints: Nullable<Vector3>[] | undefined;\r\n                        let normals: Nullable<Vector3>[] | undefined;\r\n                        if (this._useDepthPicking) {\r\n                            pickedPoints = new Array(pickedMeshes.length).fill(null);\r\n                            normals = new Array(pickedMeshes.length).fill(null);\r\n                        }\r\n\r\n                        if (pickedPoints && normals && pickedMeshes.length > 0) {\r\n                            const camera = this._cachedScene!.activeCamera;\r\n                            const depthPixels = await this._readDepthTexturePixelsAsync(readX, readY, readW, readH);\r\n                            if (camera && depthPixels) {\r\n                                const viewport = camera.viewport.toGlobal(rttSizeW, rttSizeH);\r\n                                const view = this._cachedScene!.getViewMatrix().clone();\r\n                                const projection = this._cachedScene!.getProjectionMatrix().clone();\r\n                                const cameraPosition = camera.globalPosition.clone();\r\n\r\n                                for (let i = 0; i < pickedPixelCoordinates.length; i++) {\r\n                                    const point = pickedPixelCoordinates[i];\r\n                                    const pointY = rttSizeH - point.y - 1;\r\n                                    const depthPickingInfo = this._getDepthPickingInfoFromBuffer(\r\n                                        depthPixels,\r\n                                        point.x,\r\n                                        pointY,\r\n                                        readX,\r\n                                        readY,\r\n                                        readW,\r\n                                        readH,\r\n                                        rttSizeH,\r\n                                        view,\r\n                                        projection,\r\n                                        cameraPosition,\r\n                                        viewport\r\n                                    );\r\n                                    pickedPoints[i] = depthPickingInfo?.pickedPoint ?? null;\r\n                                    normals[i] = depthPickingInfo?.normal ?? null;\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        if (disposeWhenDone) {\r\n                            this.dispose();\r\n                        }\r\n\r\n                        this._pickingInProgress = false;\r\n                        resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes, pickedPoints, normals });\r\n                    } catch (error) {\r\n                        this._removePickingTextureFromRenderTargets();\r\n                        this._pickingInProgress = false;\r\n                        reject(error instanceof Error ? error : new Error(`${error}`));\r\n                    }\r\n                }\r\n            };\r\n        });\r\n    }\r\n\r\n    private _enableScissor(x: number, y: number, w = 1, h = 1): void {\r\n        if ((this._engine as WebGPUEngine | Engine).enableScissor) {\r\n            const scissorY = this._engine?.isWebGPU && this._pickingTexture ? this._pickingTexture.getSize().height - y - h : y;\r\n            (this._engine as WebGPUEngine | Engine).enableScissor(x, scissorY, w, h);\r\n        }\r\n    }\r\n    private _disableScissor(): void {\r\n        if ((this._engine as WebGPUEngine | Engine).disableScissor) {\r\n            (this._engine as WebGPUEngine | Engine).disableScissor();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns true if rendering if the picking texture has finished, otherwise false\r\n     */\r\n    private _checkRenderStatus(): boolean {\r\n        const wasSuccessful = this._meshRenderingCount > 0;\r\n        if (wasSuccessful) {\r\n            // Remove from the active RTTs\r\n            const index = this._cachedScene!.customRenderTargets.indexOf(this._pickingTexture!);\r\n            if (index > -1) {\r\n                this._cachedScene!.customRenderTargets.splice(index, 1);\r\n                this._renderPickingTexture = false;\r\n            }\r\n            return true;\r\n        }\r\n\r\n        this._meshRenderingCount = 0;\r\n        return false; // Wait for shaders to be ready\r\n    }\r\n\r\n    /**\r\n     * Polls the picking material variant for every mesh in the render list until every\r\n     * variant is ready. Picking materials use parallel shader compilation, and a single\r\n     * ShaderMaterial may produce different effect variants per mesh (instances, thin\r\n     * instances, vertex colors, ...). If we render the picking texture before all variants\r\n     * are compiled, the renderer silently skips meshes whose effect is not yet ready, which\r\n     * can leave the click pixel cleared (0,0,0,0) and cause pickAsync to incorrectly return\r\n     * null. Once compiled, effects are cached by define string in the engine, so this\r\n     * polling only blocks on the very first pick (or whenever the render list changes to\r\n     * include meshes with new define combinations).\r\n     */\r\n    private async _waitForPickingMaterialsReadyAsync(): Promise<void> {\r\n        const renderList = this._pickingTexture?.renderList;\r\n        if (!renderList || renderList.length === 0) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._cachedScene!.getEngine();\r\n\r\n        // Cap the number of polling attempts to avoid hanging forever if a shader fails to compile.\r\n        const maxAttempts = 200;\r\n        for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n            let allReady = true;\r\n            // Compile picking effects under the picking texture's render pass id so per-pass effect caches\r\n            // (e.g. GaussianSplattingMaterial) don't stamp them onto the main pass draw wrapper.\r\n            const previousRenderPassId = engine.currentRenderPassId;\r\n            engine.currentRenderPassId = this._pickingTexture!.renderPassId;\r\n            try {\r\n                // Iterate every mesh (do not break early): each isReady call kicks off compilation\r\n                // of that mesh's effect variant if not yet started, so visiting them all on the first\r\n                // attempt lets the compiles run in parallel (KHR_parallel_shader_compile) instead of\r\n                // being serialized one variant per render frame.\r\n                for (let i = 0; i < renderList.length; i++) {\r\n                    const mesh = renderList[i];\r\n                    const material = this._meshMaterialMap.get(mesh);\r\n                    // Match the canonical \"uses instanced shader variant\" check used elsewhere in this file\r\n                    // (see addPickingList) — InstancedMesh entries report isAnInstance=true while\r\n                    // hasInstances=false, so omitting isAnInstance would validate the wrong shader variant.\r\n                    const useInstances = mesh.hasInstances || mesh.isAnInstance || mesh.hasThinInstances;\r\n                    if (material && !material.isReady(mesh, useInstances)) {\r\n                        allReady = false;\r\n                    }\r\n                }\r\n            } finally {\r\n                engine.currentRenderPassId = previousRenderPassId;\r\n            }\r\n            if (allReady) {\r\n                return;\r\n            }\r\n            // Wait for the next scene render before re-checking. Effect compilation status\r\n            // (especially with KHR_parallel_shader_compile) is typically observed between\r\n            // frames, so tying the poll to the render loop is more efficient than a fixed timer.\r\n            // eslint-disable-next-line no-await-in-loop\r\n            await new Promise<void>((resolve) => {\r\n                this._cachedScene!.onAfterRenderObservable.addOnce(() => resolve());\r\n            });\r\n        }\r\n\r\n        Logger.Warn(`GPUPicker: gave up waiting for picking materials to compile after ${maxAttempts} attempts; picking results may be incorrect.`);\r\n    }\r\n\r\n    private _getMeshFromMultiplePoints(\r\n        x: number,\r\n        y: number,\r\n        readX: number,\r\n        readY: number,\r\n        renderHeight: number,\r\n        readWidth: number,\r\n        readHeight: number\r\n    ): { pickedMesh: Nullable<AbstractMesh>; thinInstanceIndex: number | undefined } {\r\n        const bufferX = x - readX;\r\n        const bufferY = renderHeight - y - 1 - readY;\r\n        let pickedMesh: Nullable<AbstractMesh> = null;\r\n        let thinInstanceIndex: number | undefined;\r\n\r\n        if (bufferX < 0 || bufferY < 0 || bufferX >= readWidth || bufferY >= readHeight) {\r\n            return { pickedMesh, thinInstanceIndex };\r\n        }\r\n\r\n        const colorId = this._getColorIdFromReadBuffer(this._getReadBufferOffset(bufferX, bufferY, readWidth, readHeight));\r\n\r\n        if (colorId > 0) {\r\n            if (this._thinIdMap[colorId]) {\r\n                pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n                thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n            } else {\r\n                pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n            }\r\n        }\r\n\r\n        return { pickedMesh, thinInstanceIndex };\r\n    }\r\n\r\n    private _getMeshFromReadBuffer(offset: number): { pickedMesh: Nullable<AbstractMesh>; thinInstanceIndex: number | undefined } {\r\n        const colorId = this._getColorIdFromReadBuffer(offset);\r\n        let pickedMesh: Nullable<AbstractMesh> = null;\r\n        let thinInstanceIndex: number | undefined;\r\n\r\n        if (colorId > 0) {\r\n            if (this._thinIdMap[colorId]) {\r\n                pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];\r\n                thinInstanceIndex = this._thinIdMap[colorId].thinId;\r\n            } else {\r\n                pickedMesh = this._pickableMeshes[this._idMap[colorId]];\r\n            }\r\n        }\r\n\r\n        return { pickedMesh, thinInstanceIndex };\r\n    }\r\n\r\n    /**\r\n     * Updates the render list with the current pickable meshes.\r\n     */\r\n    private _updateRenderList(): void {\r\n        this._pickingTexture!.renderList = [];\r\n        for (const mesh of this._pickableMeshes) {\r\n            const className = mesh.getClassName();\r\n            // Part proxies don't render directly - their compound renders for them\r\n            if (className === \"GaussianSplattingPartProxyMesh\") {\r\n                continue;\r\n            }\r\n            this._pickingTexture!.setMaterialForRendering(mesh, this._meshMaterialMap.get(mesh));\r\n            this._pickingTexture!.renderList.push(mesh);\r\n        }\r\n        // Also add compound GS meshes that render on behalf of part proxies\r\n        for (const mesh of this._gsCompoundRenderMeshes) {\r\n            this._pickingTexture!.setMaterialForRendering(mesh, this._meshMaterialMap.get(mesh));\r\n            this._pickingTexture!.renderList.push(mesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a GaussianSplattingMaterial configured for GPU picking by attaching\r\n     * a GaussianSplattingGpuPickingMaterialPlugin. The plugin injects picking ID\r\n     * encoding into the existing Gaussian Splatting shaders via material plugin hooks.\r\n     * @param scene The scene\r\n     * @param gsMesh The Gaussian Splatting mesh (used to set the source mesh on the material)\r\n     * @returns A GaussianSplattingMaterial with the picking plugin attached\r\n     */\r\n    private _createGaussianSplattingPickingMaterial(scene: Scene, gsMesh: AbstractMesh): GaussianSplattingMaterial {\r\n        const gsPickingMaterial = new GaussianSplattingMaterial(\"gaussianSplattingGpuPicking\", scene);\r\n        gsPickingMaterial.setSourceMesh(gsMesh as any);\r\n        gsPickingMaterial.needAlphaBlending = () => false;\r\n        gsPickingMaterial.backFaceCulling = false;\r\n\r\n        // Attach the GPU picking plugin\r\n        const plugin = new GaussianSplattingGpuPickingMaterialPlugin(gsPickingMaterial);\r\n        plugin.enableDepthPicking = this._useDepthPicking;\r\n        plugin.enablePackedDepthPicking = this._isDepthTexturePacked;\r\n\r\n        return gsPickingMaterial;\r\n    }\r\n\r\n    private async _readTexturePixelsAsync(x: number, y: number, w = 1, h = 1): Promise<boolean> {\r\n        if (!this._cachedScene || !this._pickingTexture) {\r\n            return false;\r\n        }\r\n        const engine = this._cachedScene.getEngine();\r\n        const texture = this._isUsingDepthPickingRenderTarget ? (this._pickingTexture as MultiRenderTarget).textures[0]._texture : this._pickingTexture._texture;\r\n        if (!texture) {\r\n            return false;\r\n        }\r\n\r\n        const readY = engine.isWebGPU ? texture.height - y - h : y;\r\n        await engine._readTexturePixels(texture, w, h, -1, 0, this._readbuffer, true, true, x, readY);\r\n\r\n        return true;\r\n    }\r\n\r\n    private async _readDepthTexturePixelsAsync(x: number, y: number, w: number, h: number): Promise<Nullable<ArrayBufferView>> {\r\n        if (!this._cachedScene || !this._isUsingDepthPickingRenderTarget || !(this._pickingTexture instanceof MultiRenderTarget)) {\r\n            return null;\r\n        }\r\n\r\n        const texture = this._pickingTexture.textures[1]._texture;\r\n        if (!texture) {\r\n            return null;\r\n        }\r\n\r\n        const engine = this._cachedScene.getEngine();\r\n        const requiredByteLength = engine.isWebGPU ? (4 * 4 * w * h + 255) & ~255 : 4 * 4 * w * h;\r\n        if (!this._depthReadbuffer || this._depthReadbuffer.byteLength < requiredByteLength) {\r\n            this._depthReadbuffer = this._depthTextureType === Constants.TEXTURETYPE_UNSIGNED_BYTE ? new Uint8Array(requiredByteLength) : new Float32Array(requiredByteLength / 4);\r\n        }\r\n\r\n        const readY = engine.isWebGPU ? texture.height - y - h : y;\r\n        return await engine._readTexturePixels(texture, w, h, -1, 0, this._depthReadbuffer, true, false, x, readY);\r\n    }\r\n\r\n    private async _getDepthPickingInfoAsync(\r\n        x: number,\r\n        y: number,\r\n        renderWidth: number,\r\n        renderHeight: number,\r\n        view: Matrix,\r\n        projection: Matrix,\r\n        cameraPosition: Vector3,\r\n        viewport: { x: number; y: number; width: number; height: number }\r\n    ): Promise<Nullable<{ pickedPoint?: Vector3; normal?: Vector3 }>> {\r\n        const radius = GPUPicker._DepthPixelRadius;\r\n        const left = Math.max(x - radius, 0);\r\n        const bottom = Math.max(y - radius, 0);\r\n        const right = Math.min(x + radius, renderWidth - 1);\r\n        const top = Math.min(y + radius, renderHeight - 1);\r\n        const width = right - left + 1;\r\n        const height = top - bottom + 1;\r\n\r\n        const pixels = await this._readDepthTexturePixelsAsync(left, bottom, width, height);\r\n        if (!pixels) {\r\n            return null;\r\n        }\r\n\r\n        return this._getDepthPickingInfoFromBuffer(pixels, x, y, left, bottom, width, height, renderHeight, view, projection, cameraPosition, viewport);\r\n    }\r\n\r\n    private _getDepthPickingInfoFromBuffer(\r\n        pixels: ArrayBufferView,\r\n        x: number,\r\n        y: number,\r\n        bufferLeft: number,\r\n        bufferBottom: number,\r\n        bufferWidth: number,\r\n        bufferHeight: number,\r\n        renderHeight: number,\r\n        view: Matrix,\r\n        projection: Matrix,\r\n        cameraPosition: Vector3,\r\n        viewport: { x: number; y: number; width: number; height: number }\r\n    ): Nullable<{ pickedPoint?: Vector3; normal?: Vector3 }> {\r\n        let centerBufferX = x - bufferLeft;\r\n        let centerBufferY = y - bufferBottom;\r\n        let centerDepth = this._getDepthFromBuffer(pixels, centerBufferX, centerBufferY, bufferWidth, bufferHeight);\r\n        if (centerDepth === null) {\r\n            let closestDistanceSquared = Infinity;\r\n            for (let yy = 0; yy < bufferHeight; yy++) {\r\n                for (let xx = 0; xx < bufferWidth; xx++) {\r\n                    const depth = this._getDepthFromBuffer(pixels, xx, yy, bufferWidth, bufferHeight);\r\n                    if (depth === null) {\r\n                        continue;\r\n                    }\r\n\r\n                    const dx = xx - centerBufferX;\r\n                    const dy = yy - centerBufferY;\r\n                    const distanceSquared = dx * dx + dy * dy;\r\n                    if (distanceSquared < closestDistanceSquared) {\r\n                        closestDistanceSquared = distanceSquared;\r\n                        centerBufferX = xx;\r\n                        centerBufferY = yy;\r\n                        centerDepth = depth;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        if (centerDepth === null) {\r\n            return null;\r\n        }\r\n\r\n        x = bufferLeft + centerBufferX;\r\n        y = bufferBottom + centerBufferY;\r\n\r\n        const viewportTop = renderHeight - viewport.y - viewport.height;\r\n        const centerViewportX = x - viewport.x;\r\n        const centerViewportY = renderHeight - y - 1 - viewportTop;\r\n        if (centerViewportX < 0 || centerViewportY < 0 || centerViewportX >= viewport.width || centerViewportY >= viewport.height) {\r\n            return null;\r\n        }\r\n\r\n        const pickedPoint = Vector3.UnprojectFloatsToRef(\r\n            centerViewportX,\r\n            centerViewportY,\r\n            centerDepth,\r\n            viewport.width,\r\n            viewport.height,\r\n            Matrix.IdentityReadOnly,\r\n            view,\r\n            projection,\r\n            new Vector3()\r\n        );\r\n        const fallbackNormal = (): Vector3 => cameraPosition.subtractToRef(pickedPoint, new Vector3()).normalize();\r\n        let bestOffsetA: Nullable<(typeof GPUPicker._DepthNeighborOffsets)[number]> = null;\r\n        let bestOffsetB: Nullable<(typeof GPUPicker._DepthNeighborOffsets)[number]> = null;\r\n        let bestDepthDelta = Infinity;\r\n        const offsets = GPUPicker._DepthNeighborOffsets;\r\n        const depthNeighbors: { offset: (typeof GPUPicker._DepthNeighborOffsets)[number]; depth: number; depthDelta: number }[] = [];\r\n\r\n        const epsilonSquared = Epsilon * Epsilon;\r\n        for (let i = 0; i < offsets.length; i++) {\r\n            const offset = offsets[i];\r\n            const depth = this._getDepthFromBuffer(pixels, centerBufferX + offset[0], centerBufferY + offset[1], bufferWidth, bufferHeight);\r\n            if (\r\n                depth === null ||\r\n                !this._getDepthPointFromBufferToRef(\r\n                    pixels,\r\n                    x,\r\n                    y,\r\n                    offset[0],\r\n                    offset[1],\r\n                    bufferLeft,\r\n                    bufferBottom,\r\n                    bufferWidth,\r\n                    bufferHeight,\r\n                    renderHeight,\r\n                    view,\r\n                    projection,\r\n                    viewport,\r\n                    TmpVectors.Vector3[3]\r\n                )\r\n            ) {\r\n                continue;\r\n            }\r\n\r\n            depthNeighbors.push({ offset, depth, depthDelta: Math.abs(centerDepth - depth) });\r\n        }\r\n\r\n        depthNeighbors.sort((a, b) => a.depthDelta - b.depthDelta);\r\n\r\n        for (let i = 0; i < depthNeighbors.length; i++) {\r\n            const neighborA = depthNeighbors[i];\r\n            this._getDepthPointFromBufferToRef(\r\n                pixels,\r\n                x,\r\n                y,\r\n                neighborA.offset[0],\r\n                neighborA.offset[1],\r\n                bufferLeft,\r\n                bufferBottom,\r\n                bufferWidth,\r\n                bufferHeight,\r\n                renderHeight,\r\n                view,\r\n                projection,\r\n                viewport,\r\n                TmpVectors.Vector3[3]\r\n            );\r\n\r\n            for (let j = i + 1; j < depthNeighbors.length; j++) {\r\n                const neighborB = depthNeighbors[j];\r\n                this._getDepthPointFromBufferToRef(\r\n                    pixels,\r\n                    x,\r\n                    y,\r\n                    neighborB.offset[0],\r\n                    neighborB.offset[1],\r\n                    bufferLeft,\r\n                    bufferBottom,\r\n                    bufferWidth,\r\n                    bufferHeight,\r\n                    renderHeight,\r\n                    view,\r\n                    projection,\r\n                    viewport,\r\n                    TmpVectors.Vector3[4]\r\n                );\r\n\r\n                const toA = TmpVectors.Vector3[3].subtractToRef(pickedPoint, TmpVectors.Vector3[0]);\r\n                const toB = TmpVectors.Vector3[4].subtractToRef(pickedPoint, TmpVectors.Vector3[1]);\r\n                if (toA.lengthSquared() < epsilonSquared || toB.lengthSquared() < epsilonSquared) {\r\n                    continue;\r\n                }\r\n\r\n                Vector3.CrossToRef(toB, toA, TmpVectors.Vector3[5]);\r\n                if (TmpVectors.Vector3[5].lengthSquared() < epsilonSquared) {\r\n                    continue;\r\n                }\r\n\r\n                const depthDelta = neighborA.depthDelta + neighborB.depthDelta + Math.abs(neighborA.depth - neighborB.depth);\r\n                if (depthDelta < bestDepthDelta) {\r\n                    bestDepthDelta = depthDelta;\r\n                    bestOffsetA = neighborA.offset;\r\n                    bestOffsetB = neighborB.offset;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!bestOffsetA || !bestOffsetB) {\r\n            return { pickedPoint, normal: fallbackNormal() };\r\n        }\r\n\r\n        this._getDepthPointFromBufferToRef(\r\n            pixels,\r\n            x,\r\n            y,\r\n            bestOffsetA[0],\r\n            bestOffsetA[1],\r\n            bufferLeft,\r\n            bufferBottom,\r\n            bufferWidth,\r\n            bufferHeight,\r\n            renderHeight,\r\n            view,\r\n            projection,\r\n            viewport,\r\n            TmpVectors.Vector3[3]\r\n        );\r\n        this._getDepthPointFromBufferToRef(\r\n            pixels,\r\n            x,\r\n            y,\r\n            bestOffsetB[0],\r\n            bestOffsetB[1],\r\n            bufferLeft,\r\n            bufferBottom,\r\n            bufferWidth,\r\n            bufferHeight,\r\n            renderHeight,\r\n            view,\r\n            projection,\r\n            viewport,\r\n            TmpVectors.Vector3[4]\r\n        );\r\n\r\n        const toA = TmpVectors.Vector3[3].subtractToRef(pickedPoint, TmpVectors.Vector3[0]);\r\n        const toB = TmpVectors.Vector3[4].subtractToRef(pickedPoint, TmpVectors.Vector3[1]);\r\n        if (toA.lengthSquared() < epsilonSquared || toB.lengthSquared() < epsilonSquared) {\r\n            return { pickedPoint, normal: fallbackNormal() };\r\n        }\r\n\r\n        toA.normalize();\r\n        toB.normalize();\r\n\r\n        const normal = Vector3.CrossToRef(toB, toA, new Vector3());\r\n        if (normal.lengthSquared() < epsilonSquared) {\r\n            return { pickedPoint, normal: fallbackNormal() };\r\n        }\r\n\r\n        normal.normalize();\r\n        const cameraDirection = pickedPoint.subtractToRef(cameraPosition, TmpVectors.Vector3[2]).normalize();\r\n        if (Vector3.Dot(normal, cameraDirection) > 0) {\r\n            normal.negateInPlace();\r\n        }\r\n\r\n        return { pickedPoint, normal };\r\n    }\r\n\r\n    private _getDepthPointFromBufferToRef(\r\n        pixels: ArrayBufferView,\r\n        x: number,\r\n        y: number,\r\n        offsetX: number,\r\n        offsetY: number,\r\n        left: number,\r\n        bottom: number,\r\n        bufferWidth: number,\r\n        bufferHeight: number,\r\n        renderHeight: number,\r\n        view: Matrix,\r\n        projection: Matrix,\r\n        viewport: { x: number; y: number; width: number; height: number },\r\n        result: Vector3\r\n    ): boolean {\r\n        const bufferX = x + offsetX - left;\r\n        const bufferY = y + offsetY - bottom;\r\n        const depth = this._getDepthFromBuffer(pixels, bufferX, bufferY, bufferWidth, bufferHeight);\r\n        if (depth === null) {\r\n            return false;\r\n        }\r\n\r\n        const viewportTop = renderHeight - viewport.y - viewport.height;\r\n        const viewportX = x + offsetX - viewport.x;\r\n        const viewportY = renderHeight - (y + offsetY) - 1 - viewportTop;\r\n        if (viewportX < 0 || viewportY < 0 || viewportX >= viewport.width || viewportY >= viewport.height) {\r\n            return false;\r\n        }\r\n\r\n        Vector3.UnprojectFloatsToRef(viewportX, viewportY, depth, viewport.width, viewport.height, Matrix.IdentityReadOnly, view, projection, result);\r\n        return true;\r\n    }\r\n\r\n    private _getDepthFromBuffer(pixels: ArrayBufferView, x: number, y: number, width: number, height: number): Nullable<number> {\r\n        if (x < 0 || y < 0 || x >= width || y >= height) {\r\n            return null;\r\n        }\r\n\r\n        const index = this._getReadBufferOffset(x, y, width, height);\r\n        let depth: number;\r\n        if (pixels instanceof Uint8Array || pixels instanceof Uint8ClampedArray) {\r\n            if (this._isDepthTexturePacked) {\r\n                depth = pixels[index] / (255 * 255 * 255 * 255) + pixels[index + 1] / (255 * 255 * 255) + pixels[index + 2] / (255 * 255) + pixels[index + 3] / 255;\r\n            } else {\r\n                depth = pixels[index] / 255;\r\n            }\r\n        } else {\r\n            depth = (pixels as Float32Array)[index];\r\n        }\r\n\r\n        if (!Number.isFinite(depth) || depth <= 0 || depth >= 1) {\r\n            return null;\r\n        }\r\n\r\n        return depth;\r\n    }\r\n\r\n    /** Release the resources */\r\n    public dispose(): void {\r\n        this.setPickingList(null);\r\n        this._cachedScene = null;\r\n\r\n        // Cleaning up\r\n        this._pickingTexture?.dispose();\r\n        this._pickingTexture = null;\r\n        this._clearPickingMaterials();\r\n        this._sceneBeforeRenderObserver?.remove();\r\n        this._sceneBeforeRenderObserver = null;\r\n        this._pickingTextureClearObserver?.remove();\r\n        this._pickingTextureClearObserver = null;\r\n        this._pickingTextureAfterRenderObserver?.remove();\r\n        this._pickingTextureAfterRenderObserver = null;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"packingFunctions\";\nconst shader = `vec4 pack(float depth)\n{const vec4 bit_shift=vec4(255.0*255.0*255.0,255.0*255.0,255.0,1.0);const vec4 bit_mask=vec4(0.0,1.0/255.0,1.0/255.0,1.0/255.0);vec4 res=fract(depth*bit_shift);res-=res.xxyz*bit_mask;return res;}\nfloat unpack(vec4 color)\n{const vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);return dot(color,bit_shift);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const packingFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { packingFunctions } from \"./ShadersInclude/packingFunctions\";\n\nconst name = \"pickingPixelShader\";\nconst shader = `#ifdef GPUPICKER_DEPTH\n#extension GL_EXT_draw_buffers : require\n#endif\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nprecision highp int;\n#endif\n#ifdef GPUPICKER_DEPTH\nlayout(location=0) out highp vec4 glFragData[2];\n#endif\n#ifdef GPUPICKER_PACK_DEPTH\n#include<packingFunctions>\n#endif\n#if defined(INSTANCES)\nflat varying float vMeshID;\n#else\nuniform float meshID;\n#endif\nvoid main(void) {float id;\n#if defined(INSTANCES)\nid=vMeshID;\n#else\nid=meshID;\n#endif\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nint castedId=int(id);vec3 color=vec3(\nfloat((castedId>>16) & 0xFF),\nfloat((castedId>>8) & 0xFF),\nfloat(castedId & 0xFF)\n)/255.0;\n#ifdef GPUPICKER_DEPTH\nglFragData[0]=vec4(color,1.0);\n#ifdef GPUPICKER_PACK_DEPTH\nglFragData[1]=pack(gl_FragCoord.z);\n#else\nglFragData[1]=vec4(gl_FragCoord.z,0.0,0.0,1.0);\n#endif\n#else\ngl_FragColor=vec4(color,1.0);\n#endif\n#else\nfloat castedId=floor(id+0.5);vec3 color=vec3(\nfloor(mod(castedId,16777216.0)/65536.0),\nfloor(mod(castedId,65536.0)/256.0),\nmod(castedId,256.0)\n)/255.0;\n#ifdef GPUPICKER_DEPTH\nglFragData[0]=vec4(color,1.0);\n#ifdef GPUPICKER_PACK_DEPTH\nglFragData[1]=pack(gl_FragCoord.z);\n#else\nglFragData[1]=vec4(gl_FragCoord.z,0.0,0.0,1.0);\n#endif\n#else\ngl_FragColor=vec4(color,1.0);\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [packingFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pickingPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bonesDeclaration\";\nconst shader = `#if NUM_BONE_INFLUENCERS>0\nattribute vec4 matricesIndices;attribute vec4 matricesWeights;\n#if NUM_BONE_INFLUENCERS>4\nattribute vec4 matricesIndicesExtra;attribute vec4 matricesWeightsExtra;\n#endif\n#ifndef BAKED_VERTEX_ANIMATION_TEXTURE\n#ifdef BONETEXTURE\nuniform highp sampler2D boneSampler;uniform vec2 boneTextureInfo;\n#else\nuniform mat4 mBones[BonesPerMesh];\n#endif\n#ifdef BONES_VELOCITY_ENABLED\nuniform mat4 mPreviousBones[BonesPerMesh];\n#endif\n#ifdef BONETEXTURE\n#define inline\nmat4 readMatrixFromRawSampler(sampler2D smp,float index)\n{\n#if defined(WEBGL2) || defined(WEBGPU)\nint offset=int(index)*4; \nint textureWidth=int(boneTextureInfo.x);int y=int(offset)/textureWidth;int x=int(offset) % textureWidth;vec4 m0=texelFetch(smp,ivec2(x+0,y),0);vec4 m1=texelFetch(smp,ivec2(x+1,y),0);vec4 m2=texelFetch(smp,ivec2(x+2,y),0);vec4 m3=texelFetch(smp,ivec2(x+3,y),0);return mat4(m0,m1,m2,m3);\n#else\nfloat offset=index*4.0;float y=floor(offset/boneTextureInfo.x);float x=offset-y*boneTextureInfo.x;float dy=1.0/boneTextureInfo.y;float dx=1.0/boneTextureInfo.x;vec4 m0=texture2D(smp,vec2(dx*(x+0.5),dy*(y+0.5)));vec4 m1=texture2D(smp,vec2(dx*(x+1.5),dy*(y+0.5)));vec4 m2=texture2D(smp,vec2(dx*(x+2.5),dy*(y+0.5)));vec4 m3=texture2D(smp,vec2(dx*(x+3.5),dy*(y+0.5))); \nreturn mat4(m0,m1,m2,m3);\n#endif\n}\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bonesDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bakedVertexAnimationDeclaration\";\nconst shader = `#ifdef BAKED_VERTEX_ANIMATION_TEXTURE\nuniform float bakedVertexAnimationTime;\n#if !defined(WEBGL2) && !defined(WEBGPU)\nuniform vec2 bakedVertexAnimationTextureSizeInverted;\n#endif\nuniform vec4 bakedVertexAnimationSettings;uniform sampler2D bakedVertexAnimationTexture;\n#ifdef INSTANCES\nattribute vec4 bakedVertexAnimationSettingsInstanced;\n#endif\n#define inline\nmat4 readMatrixFromRawSamplerVAT(sampler2D smp,float index,float frame)\n{\n#if defined(WEBGL2) || defined(WEBGPU)\nint offset=int(index)*4;int frameUV=int(frame);vec4 m0=texelFetch(smp,ivec2(offset+0,frameUV),0);vec4 m1=texelFetch(smp,ivec2(offset+1,frameUV),0);vec4 m2=texelFetch(smp,ivec2(offset+2,frameUV),0);vec4 m3=texelFetch(smp,ivec2(offset+3,frameUV),0);return mat4(m0,m1,m2,m3);\n#else\nfloat offset=index*4.0;float frameUV=(frame+0.5)*bakedVertexAnimationTextureSizeInverted.y;float dx=bakedVertexAnimationTextureSizeInverted.x;vec4 m0=texture2D(smp,vec2(dx*(offset+0.5),frameUV));vec4 m1=texture2D(smp,vec2(dx*(offset+1.5),frameUV));vec4 m2=texture2D(smp,vec2(dx*(offset+2.5),frameUV));vec4 m3=texture2D(smp,vec2(dx*(offset+3.5),frameUV));return mat4(m0,m1,m2,m3);\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bakedVertexAnimationDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertexGlobalDeclaration\";\nconst shader = `#ifdef MORPHTARGETS\nuniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];\n#ifdef MORPHTARGETS_TEXTURE \nuniform float morphTargetTextureIndices[NUM_MORPH_INFLUENCERS];uniform vec3 morphTargetTextureInfo;uniform highp sampler2DArray morphTargets;vec3 readVector3FromRawSampler(int targetIndex,float vertexIndex)\n{ \n#if defined(WEBGL2) || defined(WEBGPU)\nint textureWidth=int(morphTargetTextureInfo.y);int y=int(vertexIndex)/textureWidth;int x=int(vertexIndex) % textureWidth;return texelFetch(morphTargets,ivec3(x,y,int(morphTargetTextureIndices[targetIndex])),0).xyz;\n#else\nfloat y=floor(vertexIndex/morphTargetTextureInfo.y);float x=vertexIndex-y*morphTargetTextureInfo.y;vec3 textureUV=vec3((x+0.5)/morphTargetTextureInfo.y,(y+0.5)/morphTargetTextureInfo.z,morphTargetTextureIndices[targetIndex]);return texture(morphTargets,textureUV).xyz;\n#endif\n}\nvec4 readVector4FromRawSampler(int targetIndex,float vertexIndex)\n{ \n#if defined(WEBGL2) || defined(WEBGPU)\nint textureWidth=int(morphTargetTextureInfo.y);int y=int(vertexIndex)/textureWidth;int x=int(vertexIndex) % textureWidth;return texelFetch(morphTargets,ivec3(x,y,int(morphTargetTextureIndices[targetIndex])),0);\n#else\nfloat y=floor(vertexIndex/morphTargetTextureInfo.y);float x=vertexIndex-y*morphTargetTextureInfo.y;vec3 textureUV=vec3((x+0.5)/morphTargetTextureInfo.y,(y+0.5)/morphTargetTextureInfo.z,morphTargetTextureIndices[targetIndex]);return texture(morphTargets,textureUV);\n#endif\n}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexGlobalDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertexDeclaration\";\nconst shader = `#ifdef MORPHTARGETS\n#ifndef MORPHTARGETS_TEXTURE\n#ifdef MORPHTARGETS_POSITION\nattribute vec3 position{X};\n#endif\n#ifdef MORPHTARGETS_NORMAL\nattribute vec3 normal{X};\n#endif\n#ifdef MORPHTARGETS_TANGENT\nattribute vec3 tangent{X};\n#endif\n#ifdef MORPHTARGETS_UV\nattribute vec2 uv_{X};\n#endif\n#ifdef MORPHTARGETS_UV2\nattribute vec2 uv2_{X};\n#endif\n#ifdef MORPHTARGETS_COLOR\nattribute vec4 color{X};\n#endif\n#elif {X}==0\nuniform float morphTargetCount;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"instancesDeclaration\";\nconst shader = `#ifdef INSTANCES\nattribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;\n#ifdef INSTANCESCOLOR\nattribute vec4 instanceColor;\n#endif\n#if defined(THIN_INSTANCES) && !defined(WORLD_UBO)\nuniform mat4 world;\n#endif\n#if defined(VELOCITY) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nattribute vec4 previousWorld0;attribute vec4 previousWorld1;attribute vec4 previousWorld2;attribute vec4 previousWorld3;\n#ifdef THIN_INSTANCES\nuniform mat4 previousWorld;\n#endif\n#endif\n#else\n#if !defined(WORLD_UBO)\nuniform mat4 world;\n#endif\n#if defined(VELOCITY) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nuniform mat4 previousWorld;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const instancesDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertexGlobal\";\nconst shader = `#ifdef MORPHTARGETS\n#ifdef MORPHTARGETS_TEXTURE\nfloat vertexID;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexGlobal = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertex\";\nconst shader = `#ifdef MORPHTARGETS\n#ifdef MORPHTARGETS_TEXTURE\n#if {X}==0\nfor (int i=0; i<NUM_MORPH_INFLUENCERS; i++) {if (float(i)>=morphTargetCount) break;vertexID=float(gl_VertexID)*morphTargetTextureInfo.x;\n#ifdef MORPHTARGETS_POSITION\npositionUpdated+=(readVector3FromRawSampler(i,vertexID)-position)*morphTargetInfluences[i];\n#endif\n#ifdef MORPHTARGETTEXTURE_HASPOSITIONS\nvertexID+=1.0;\n#endif\n#ifdef MORPHTARGETS_NORMAL\nnormalUpdated+=(readVector3FromRawSampler(i,vertexID) -normal)*morphTargetInfluences[i];\n#endif\n#ifdef MORPHTARGETTEXTURE_HASNORMALS\nvertexID+=1.0;\n#endif\n#ifdef MORPHTARGETS_UV\nuvUpdated+=(readVector3FromRawSampler(i,vertexID).xy-uv)*morphTargetInfluences[i];\n#endif\n#ifdef MORPHTARGETTEXTURE_HASUVS\nvertexID+=1.0;\n#endif\n#ifdef MORPHTARGETS_TANGENT\ntangentUpdated.xyz+=(readVector3FromRawSampler(i,vertexID) -tangent.xyz)*morphTargetInfluences[i];\n#endif\n#ifdef MORPHTARGETTEXTURE_HASTANGENTS\nvertexID+=1.0;\n#endif\n#ifdef MORPHTARGETS_UV2\nuv2Updated+=(readVector3FromRawSampler(i,vertexID).xy-uv2)*morphTargetInfluences[i];\n#endif\n#ifdef MORPHTARGETTEXTURE_HASUV2S\nvertexID+=1.0;\n#endif\n#ifdef MORPHTARGETS_COLOR\ncolorUpdated+=(readVector4FromRawSampler(i,vertexID)-color)*morphTargetInfluences[i];\n#endif\n}\n#endif\n#else\n#ifdef MORPHTARGETS_POSITION\npositionUpdated+=(position{X}-position)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_NORMAL\nnormalUpdated+=(normal{X}-normal)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_TANGENT\ntangentUpdated.xyz+=(tangent{X}-tangent.xyz)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_UV\nuvUpdated+=(uv_{X}-uv)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_UV2\nuv2Updated+=(uv2_{X}-uv2)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_COLOR\ncolorUpdated+=(color{X}-color)*morphTargetInfluences[{X}];\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"instancesVertex\";\nconst shader = `#ifdef INSTANCES\nmat4 finalWorld=mat4(world0,world1,world2,world3);\n#if defined(PREPASS_VELOCITY) || defined(VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nmat4 finalPreviousWorld=mat4(previousWorld0,previousWorld1,\npreviousWorld2,previousWorld3);\n#endif\n#ifdef THIN_INSTANCES\nfinalWorld=world*finalWorld;\n#if defined(PREPASS_VELOCITY) || defined(VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nfinalPreviousWorld=previousWorld*finalPreviousWorld;\n#endif\n#endif\n#else\nmat4 finalWorld=world;\n#if defined(PREPASS_VELOCITY) || defined(VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nmat4 finalPreviousWorld=previousWorld;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const instancesVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bonesVertex\";\nconst shader = `#ifndef BAKED_VERTEX_ANIMATION_TEXTURE\n#if NUM_BONE_INFLUENCERS>0\nmat4 influence;\n#ifdef BONETEXTURE\ninfluence=readMatrixFromRawSampler(boneSampler,matricesIndices[0])*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndices[1])*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndices[2])*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndices[3])*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[0])*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[1])*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[2])*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[3])*matricesWeightsExtra[3];\n#endif\n#else\ninfluence=mBones[int(matricesIndices[0])]*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence+=mBones[int(matricesIndices[1])]*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\ninfluence+=mBones[int(matricesIndices[2])]*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\ninfluence+=mBones[int(matricesIndices[3])]*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\ninfluence+=mBones[int(matricesIndicesExtra[0])]*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\ninfluence+=mBones[int(matricesIndicesExtra[1])]*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\ninfluence+=mBones[int(matricesIndicesExtra[2])]*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\ninfluence+=mBones[int(matricesIndicesExtra[3])]*matricesWeightsExtra[3];\n#endif\n#endif\nfinalWorld=finalWorld*influence;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bonesVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bakedVertexAnimation\";\nconst shader = `#ifdef BAKED_VERTEX_ANIMATION_TEXTURE\n{\n#ifdef INSTANCES\n#define BVASNAME bakedVertexAnimationSettingsInstanced\n#else\n#define BVASNAME bakedVertexAnimationSettings\n#endif\nfloat VATStartFrame=BVASNAME.x;float VATEndFrame=BVASNAME.y;float VATOffsetFrame=BVASNAME.z;float VATSpeed=BVASNAME.w;float totalFrames=VATEndFrame-VATStartFrame+1.0;float time=bakedVertexAnimationTime*VATSpeed/totalFrames;float frameCorrection=time<1.0 ? 0.0 : 1.0;float numOfFrames=totalFrames-frameCorrection;float VATFrameNum=fract(time)*numOfFrames;VATFrameNum=mod(VATFrameNum+VATOffsetFrame,numOfFrames);VATFrameNum=floor(VATFrameNum);VATFrameNum+=VATStartFrame+frameCorrection;mat4 VATInfluence;VATInfluence=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndices[0],VATFrameNum)*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndices[1],VATFrameNum)*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndices[2],VATFrameNum)*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndices[3],VATFrameNum)*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndicesExtra[0],VATFrameNum)*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndicesExtra[1],VATFrameNum)*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndicesExtra[2],VATFrameNum)*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\nVATInfluence+=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,matricesIndicesExtra[3],VATFrameNum)*matricesWeightsExtra[3];\n#endif\nfinalWorld=finalWorld*VATInfluence;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bakedVertexAnimation = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"pickingVertexShader\";\nconst shader = `attribute vec3 position;\n#if defined(INSTANCES)\nattribute float instanceMeshID;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\n#if defined(INSTANCES)\nflat varying float vMeshID;\n#endif\nvoid main(void) {vec3 positionUpdated=position;\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);gl_Position=viewProjection*worldPos;\n#if defined(INSTANCES)\nvMeshID=instanceMeshID;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, instancesDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pickingVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"packingFunctions\";\nconst shader = `fn pack(depth: f32)->vec4f\n{const bit_shift: vec4f= vec4f(255.0*255.0*255.0,255.0*255.0,255.0,1.0);const bit_mask: vec4f= vec4f(0.0,1.0/255.0,1.0/255.0,1.0/255.0);var res: vec4f=fract(depth*bit_shift);res-=res.xxyz*bit_mask;return res;}\nfn unpack(color: vec4f)->f32\n{const bit_shift: vec4f= vec4f(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);return dot(color,bit_shift);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const packingFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { packingFunctionsWGSL } from \"./ShadersInclude/packingFunctions\";\n\nconst name = \"pickingPixelShader\";\nconst shader = `#if defined(INSTANCES)\nflat varying vMeshID: f32;\n#else\nuniform meshID: f32;\n#endif\n#ifdef GPUPICKER_PACK_DEPTH\n#include<packingFunctions>\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var id: i32;\n#if defined(INSTANCES)\nid=i32(input.vMeshID);\n#else\nid=i32(uniforms.meshID);\n#endif\nvar color=vec3f(\nf32((id>>16) & 0xFF),\nf32((id>>8) & 0xFF),\nf32(id & 0xFF),\n)/255.0;\n#ifdef GPUPICKER_DEPTH\nfragmentOutputs.fragData0=vec4f(color,1.0);\n#ifdef GPUPICKER_PACK_DEPTH\nfragmentOutputs.fragData1=pack(fragmentInputs.position.z);\n#else\nfragmentOutputs.fragData1=vec4f(fragmentInputs.position.z,0.0,0.0,1.0);\n#endif\n#else\nfragmentOutputs.color=vec4f(color,1.0);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [packingFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pickingPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bonesDeclaration\";\nconst shader = `#if NUM_BONE_INFLUENCERS>0\n#ifndef USE_VERTEX_PULLING\nattribute matricesIndices : vec4f;attribute matricesWeights : vec4f;\n#if NUM_BONE_INFLUENCERS>4\nattribute matricesIndicesExtra : vec4f;attribute matricesWeightsExtra : vec4f;\n#endif\n#endif\n#ifndef BAKED_VERTEX_ANIMATION_TEXTURE\n#ifdef BONETEXTURE\nvar boneSampler : texture_2d<f32>;uniform boneTextureInfo : vec2f;\n#else\nuniform mBones : array<mat4x4f,BonesPerMesh>;\n#endif\n#ifdef BONES_VELOCITY_ENABLED\nuniform mPreviousBones : array<mat4x4f,BonesPerMesh>;\n#endif\n#ifdef BONETEXTURE\nfn readMatrixFromRawSampler(smp : texture_2d<f32>,index : f32)->mat4x4f\n{let offset=i32(index)*4; \nlet textureWidth=i32(uniforms.boneTextureInfo.x);let y=offset/textureWidth;let x=offset % textureWidth;let m0=textureLoad(smp,vec2<i32>(x+0,y),0);let m1=textureLoad(smp,vec2<i32>(x+1,y),0);let m2=textureLoad(smp,vec2<i32>(x+2,y),0);let m3=textureLoad(smp,vec2<i32>(x+3,y),0);return mat4x4f(m0,m1,m2,m3);}\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bonesDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bakedVertexAnimationDeclaration\";\nconst shader = `#ifdef BAKED_VERTEX_ANIMATION_TEXTURE\nuniform bakedVertexAnimationTime: f32;uniform bakedVertexAnimationSettings: vec4<f32>;var bakedVertexAnimationTexture : texture_2d<f32>;\n#ifdef INSTANCES\nattribute bakedVertexAnimationSettingsInstanced : vec4<f32>;\n#endif\nfn readMatrixFromRawSamplerVAT(smp : texture_2d<f32>,index : f32,frame : f32)->mat4x4<f32>\n{let offset=i32(index)*4;let frameUV=i32(frame);let m0=textureLoad(smp,vec2<i32>(offset+0,frameUV),0);let m1=textureLoad(smp,vec2<i32>(offset+1,frameUV),0);let m2=textureLoad(smp,vec2<i32>(offset+2,frameUV),0);let m3=textureLoad(smp,vec2<i32>(offset+3,frameUV),0);return mat4x4<f32>(m0,m1,m2,m3);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bakedVertexAnimationDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertexGlobalDeclaration\";\nconst shader = `#ifdef MORPHTARGETS\nuniform morphTargetInfluences : array<f32,NUM_MORPH_INFLUENCERS>;\n#ifdef MORPHTARGETS_TEXTURE \nuniform morphTargetTextureIndices : array<f32,NUM_MORPH_INFLUENCERS>;uniform morphTargetTextureInfo : vec3<f32>;var morphTargets : texture_2d_array<f32>;fn readVector3FromRawSampler(targetIndex : i32,vertexIndex : f32)->vec3<f32>\n{ \nlet textureWidth: i32=i32(uniforms.morphTargetTextureInfo.y);let y: i32=i32(vertexIndex)/textureWidth;let x: i32=i32(vertexIndex) % textureWidth;return textureLoad(morphTargets,vec2i(x,y),i32(uniforms.morphTargetTextureIndices[targetIndex]),0).xyz;}\nfn readVector4FromRawSampler(targetIndex : i32,vertexIndex : f32)->vec4<f32>\n{ \nlet textureWidth: i32=i32(uniforms.morphTargetTextureInfo.y); \nlet y: i32=i32(vertexIndex)/textureWidth;let x: i32=i32(vertexIndex) % textureWidth;return textureLoad(morphTargets,vec2i(x,y),i32(uniforms.morphTargetTextureIndices[targetIndex]),0);}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexGlobalDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertexDeclaration\";\nconst shader = `#ifdef MORPHTARGETS\n#ifndef MORPHTARGETS_TEXTURE\n#ifdef MORPHTARGETS_POSITION\nattribute position{X} : vec3<f32>;\n#endif\n#ifdef MORPHTARGETS_NORMAL\nattribute normal{X} : vec3<f32>;\n#endif\n#ifdef MORPHTARGETS_TANGENT\nattribute tangent{X} : vec3<f32>;\n#endif\n#ifdef MORPHTARGETS_UV\nattribute uv_{X} : vec2<f32>;\n#endif\n#ifdef MORPHTARGETS_UV2\nattribute uv2_{X} : vec2<f32>;\n#endif\n#ifdef MORPHTARGETS_COLOR\nattribute color{X} : vec4<f32>;\n#endif\n#elif {X}==0\nuniform morphTargetCount: f32;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"instancesDeclaration\";\nconst shader = `#ifdef INSTANCES\nattribute world0 : vec4<f32>;attribute world1 : vec4<f32>;attribute world2 : vec4<f32>;attribute world3 : vec4<f32>;\n#ifdef INSTANCESCOLOR\nattribute instanceColor : vec4<f32>;\n#endif\n#if defined(THIN_INSTANCES) && !defined(WORLD_UBO)\nuniform world : mat4x4<f32>;\n#endif\n#if defined(VELOCITY) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nattribute previousWorld0 : vec4<f32>;attribute previousWorld1 : vec4<f32>;attribute previousWorld2 : vec4<f32>;attribute previousWorld3 : vec4<f32>;\n#ifdef THIN_INSTANCES\nuniform previousWorld : mat4x4<f32>;\n#endif\n#endif\n#else\n#if !defined(WORLD_UBO)\nuniform world : mat4x4<f32>;\n#endif\n#if defined(VELOCITY) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nuniform previousWorld : mat4x4<f32>;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const instancesDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertexGlobal\";\nconst shader = `#ifdef MORPHTARGETS\n#ifdef MORPHTARGETS_TEXTURE\nvar vertexID : f32;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexGlobalWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"morphTargetsVertex\";\nconst shader = `#ifdef MORPHTARGETS\n#ifdef MORPHTARGETS_TEXTURE\n#if {X}==0\nfor (var i=0; i<NUM_MORPH_INFLUENCERS; i=i+1) {if (f32(i)>=uniforms.morphTargetCount) {break;}\n#ifdef USE_VERTEX_PULLING\nvertexID=f32(vpVertexIndex)*uniforms.morphTargetTextureInfo.x;\n#else\nvertexID=f32(vertexInputs.vertexIndex)*uniforms.morphTargetTextureInfo.x;\n#endif\n#ifdef MORPHTARGETS_POSITION\n#ifdef USE_VERTEX_PULLING\npositionUpdated=positionUpdated+(readVector3FromRawSampler(i,vertexID)-vp_basePosition)*uniforms.morphTargetInfluences[i];\n#else\npositionUpdated=positionUpdated+(readVector3FromRawSampler(i,vertexID)-vertexInputs.position)*uniforms.morphTargetInfluences[i];\n#endif\n#endif\n#ifdef MORPHTARGETTEXTURE_HASPOSITIONS\nvertexID=vertexID+1.0;\n#endif\n#ifdef MORPHTARGETS_NORMAL\n#ifdef USE_VERTEX_PULLING\nnormalUpdated=normalUpdated+(readVector3FromRawSampler(i,vertexID) -vp_baseNormal)*uniforms.morphTargetInfluences[i];\n#else\nnormalUpdated=normalUpdated+(readVector3FromRawSampler(i,vertexID) -vertexInputs.normal)*uniforms.morphTargetInfluences[i];\n#endif\n#endif\n#ifdef MORPHTARGETTEXTURE_HASNORMALS\nvertexID=vertexID+1.0;\n#endif\n#ifdef MORPHTARGETS_UV\n#ifdef USE_VERTEX_PULLING\nuvUpdated=uvUpdated+(readVector3FromRawSampler(i,vertexID).xy-vp_baseUV)*uniforms.morphTargetInfluences[i];\n#else\nuvUpdated=uvUpdated+(readVector3FromRawSampler(i,vertexID).xy-vertexInputs.uv)*uniforms.morphTargetInfluences[i];\n#endif\n#endif\n#ifdef MORPHTARGETTEXTURE_HASUVS\nvertexID=vertexID+1.0;\n#endif\n#ifdef MORPHTARGETS_TANGENT\n#ifdef USE_VERTEX_PULLING\ntangentUpdated=vec4f(tangentUpdated.xyz+(readVector3FromRawSampler(i,vertexID) -vp_baseTangent.xyz)*uniforms.morphTargetInfluences[i],tangentUpdated.a);\n#else\ntangentUpdated=vec4f(tangentUpdated.xyz+(readVector3FromRawSampler(i,vertexID) -vertexInputs.tangent.xyz)*uniforms.morphTargetInfluences[i],tangentUpdated.a);\n#endif\n#endif\n#ifdef MORPHTARGETTEXTURE_HASTANGENTS\nvertexID=vertexID+1.0;\n#endif\n#ifdef MORPHTARGETS_UV2\n#ifdef USE_VERTEX_PULLING\nuv2Updated=uv2Updated+(readVector3FromRawSampler(i,vertexID).xy-vp_baseUV2)*uniforms.morphTargetInfluences[i];\n#else\nuv2Updated=uv2Updated+(readVector3FromRawSampler(i,vertexID).xy-vertexInputs.uv2)*uniforms.morphTargetInfluences[i];\n#endif\n#endif\n#ifdef MORPHTARGETS_COLOR\n#ifdef USE_VERTEX_PULLING\ncolorUpdated=colorUpdated+(readVector4FromRawSampler(i,vertexID)-vp_baseColor)*uniforms.morphTargetInfluences[i];\n#else\ncolorUpdated=colorUpdated+(readVector4FromRawSampler(i,vertexID)-vertexInputs.color)*uniforms.morphTargetInfluences[i];\n#endif\n#endif\n}\n#endif\n#else\n#ifdef MORPHTARGETS_POSITION\n#ifdef USE_VERTEX_PULLING\npositionUpdated=positionUpdated+(vertexInputs.position{X}-vp_basePosition)*uniforms.morphTargetInfluences[{X}];\n#else\npositionUpdated=positionUpdated+(vertexInputs.position{X}-vertexInputs.position)*uniforms.morphTargetInfluences[{X}];\n#endif\n#endif\n#ifdef MORPHTARGETS_NORMAL\n#ifdef USE_VERTEX_PULLING\nnormalUpdated=normalUpdated+(vertexInputs.normal{X}-vp_baseNormal)*uniforms.morphTargetInfluences[{X}];\n#else\nnormalUpdated=normalUpdated+(vertexInputs.normal{X}-vertexInputs.normal)*uniforms.morphTargetInfluences[{X}];\n#endif\n#endif\n#ifdef MORPHTARGETS_TANGENT\n#ifdef USE_VERTEX_PULLING\ntangentUpdated=vec4f(tangentUpdated.xyz+(vertexInputs.tangent{X}-vp_baseTangent.xyz)*uniforms.morphTargetInfluences[{X}],tangentUpdated.a);\n#else\ntangentUpdated=vec4f(tangentUpdated.xyz+(vertexInputs.tangent{X}-vertexInputs.tangent.xyz)*uniforms.morphTargetInfluences[{X}],tangentUpdated.a);\n#endif\n#endif\n#ifdef MORPHTARGETS_UV\n#ifdef USE_VERTEX_PULLING\nuvUpdated=uvUpdated+(vertexInputs.uv_{X}-vp_baseUV)*uniforms.morphTargetInfluences[{X}];\n#else\nuvUpdated=uvUpdated+(vertexInputs.uv_{X}-vertexInputs.uv)*uniforms.morphTargetInfluences[{X}];\n#endif\n#endif\n#ifdef MORPHTARGETS_UV2\n#ifdef USE_VERTEX_PULLING\nuv2Updated=uv2Updated+(vertexInputs.uv2_{X}-vp_baseUV2)*uniforms.morphTargetInfluences[{X}];\n#else\nuv2Updated=uv2Updated+(vertexInputs.uv2_{X}-vertexInputs.uv2)*uniforms.morphTargetInfluences[{X}];\n#endif\n#endif\n#ifdef MORPHTARGETS_COLOR\n#ifdef USE_VERTEX_PULLING\ncolorUpdated=colorUpdated+(vertexInputs.color{X}-vp_baseColor)*uniforms.morphTargetInfluences[{X}];\n#else\ncolorUpdated=colorUpdated+(vertexInputs.color{X}-vertexInputs.color)*uniforms.morphTargetInfluences[{X}];\n#endif\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const morphTargetsVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"instancesVertex\";\nconst shader = `#ifdef INSTANCES\nvar finalWorld=mat4x4<f32>(vertexInputs.world0,vertexInputs.world1,vertexInputs.world2,vertexInputs.world3);\n#if defined(PREPASS_VELOCITY) || defined(VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nvar finalPreviousWorld=mat4x4<f32>(\nvertexInputs.previousWorld0,vertexInputs.previousWorld1,\nvertexInputs.previousWorld2,vertexInputs.previousWorld3);\n#endif\n#ifdef THIN_INSTANCES\n#if !defined(WORLD_UBO)\nfinalWorld=uniforms.world*finalWorld;\n#else\nfinalWorld=mesh.world*finalWorld;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nfinalPreviousWorld=uniforms.previousWorld*finalPreviousWorld;\n#endif\n#endif\n#else\n#if !defined(WORLD_UBO)\nvar finalWorld=uniforms.world;\n#else\nvar finalWorld=mesh.world;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(VELOCITY) || defined(PREPASS_VELOCITY_LINEAR) || defined(VELOCITY_LINEAR)\nvar finalPreviousWorld=uniforms.previousWorld;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const instancesVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bonesVertex\";\nconst shader = `#ifndef BAKED_VERTEX_ANIMATION_TEXTURE\n#if NUM_BONE_INFLUENCERS>0\nvar influence : mat4x4<f32>;\n#ifdef BONETEXTURE\ninfluence=readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndices[0])*vertexInputs.matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndices[1])*vertexInputs.matricesWeights[1];\n#endif \n#if NUM_BONE_INFLUENCERS>2\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndices[2])*vertexInputs.matricesWeights[2];\n#endif \n#if NUM_BONE_INFLUENCERS>3\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndices[3])*vertexInputs.matricesWeights[3];\n#endif \n#if NUM_BONE_INFLUENCERS>4\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndicesExtra[0])*vertexInputs.matricesWeightsExtra[0];\n#endif \n#if NUM_BONE_INFLUENCERS>5\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndicesExtra[1])*vertexInputs.matricesWeightsExtra[1];\n#endif \n#if NUM_BONE_INFLUENCERS>6\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndicesExtra[2])*vertexInputs.matricesWeightsExtra[2];\n#endif \n#if NUM_BONE_INFLUENCERS>7\ninfluence=influence+readMatrixFromRawSampler(boneSampler,vertexInputs.matricesIndicesExtra[3])*vertexInputs.matricesWeightsExtra[3];\n#endif \n#else \ninfluence=uniforms.mBones[i32(vertexInputs.matricesIndices[0])]*vertexInputs.matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndices[1])]*vertexInputs.matricesWeights[1];\n#endif \n#if NUM_BONE_INFLUENCERS>2\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndices[2])]*vertexInputs.matricesWeights[2];\n#endif \n#if NUM_BONE_INFLUENCERS>3\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndices[3])]*vertexInputs.matricesWeights[3];\n#endif \n#if NUM_BONE_INFLUENCERS>4\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndicesExtra[0])]*vertexInputs.matricesWeightsExtra[0];\n#endif \n#if NUM_BONE_INFLUENCERS>5\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndicesExtra[1])]*vertexInputs.matricesWeightsExtra[1];\n#endif \n#if NUM_BONE_INFLUENCERS>6\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndicesExtra[2])]*vertexInputs.matricesWeightsExtra[2];\n#endif \n#if NUM_BONE_INFLUENCERS>7\ninfluence=influence+uniforms.mBones[i32(vertexInputs.matricesIndicesExtra[3])]*vertexInputs.matricesWeightsExtra[3];\n#endif \n#endif\nfinalWorld=finalWorld*influence;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bonesVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bakedVertexAnimation\";\nconst shader = `#ifdef BAKED_VERTEX_ANIMATION_TEXTURE\n{\n#ifdef INSTANCES\nlet VATStartFrame: f32=vertexInputs.bakedVertexAnimationSettingsInstanced.x;let VATEndFrame: f32=vertexInputs.bakedVertexAnimationSettingsInstanced.y;let VATOffsetFrame: f32=vertexInputs.bakedVertexAnimationSettingsInstanced.z;let VATSpeed: f32=vertexInputs.bakedVertexAnimationSettingsInstanced.w;\n#else\nlet VATStartFrame: f32=uniforms.bakedVertexAnimationSettings.x;let VATEndFrame: f32=uniforms.bakedVertexAnimationSettings.y;let VATOffsetFrame: f32=uniforms.bakedVertexAnimationSettings.z;let VATSpeed: f32=uniforms.bakedVertexAnimationSettings.w;\n#endif\nlet totalFrames: f32=VATEndFrame-VATStartFrame+1.0;let time: f32=uniforms.bakedVertexAnimationTime*VATSpeed/totalFrames;let frameCorrection: f32=select(1.0,0.0,time<1.0);let numOfFrames: f32=totalFrames-frameCorrection;var VATFrameNum: f32=fract(time)*numOfFrames;VATFrameNum=(VATFrameNum+VATOffsetFrame) % numOfFrames;VATFrameNum=floor(VATFrameNum);VATFrameNum=VATFrameNum+VATStartFrame+frameCorrection;var VATInfluence : mat4x4<f32>;VATInfluence=readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndices[0],VATFrameNum)*vertexInputs.matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndices[1],VATFrameNum)*vertexInputs.matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndices[2],VATFrameNum)*vertexInputs.matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndices[3],VATFrameNum)*vertexInputs.matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndicesExtra[0],VATFrameNum)*vertexInputs.matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndicesExtra[1],VATFrameNum)*vertexInputs.matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndicesExtra[2],VATFrameNum)*vertexInputs.matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\nVATInfluence=VATInfluence+readMatrixFromRawSamplerVAT(bakedVertexAnimationTexture,vertexInputs.matricesIndicesExtra[3],VATFrameNum)*vertexInputs.matricesWeightsExtra[3];\n#endif\nfinalWorld=finalWorld*VATInfluence;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bakedVertexAnimationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"pickingVertexShader\";\nconst shader = `attribute position: vec3f;\n#if defined(INSTANCES)\nattribute instanceMeshID: f32;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;\n#if defined(INSTANCES)\nflat varying vMeshID: f32;\n#endif\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld*vec4f(positionUpdated,1.0);vertexOutputs.position=uniforms.viewProjection*worldPos;\n#if defined(INSTANCES)\nvertexOutputs.vMeshID=vertexInputs.instanceMeshID;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, instancesDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pickingVertexShaderWGSL = { name, shader };\n","import { Logger } from \"../Misc/logger\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type IComputePipelineContext } from \"./IComputePipelineContext\";\r\nimport { GetDOMTextContent, IsWindowObjectExist } from \"../Misc/domManagement\";\r\nimport { Finalize, Initialize, PreProcess } from \"../Engines/Processors/shaderProcessor\";\r\nimport { type _IProcessingOptions } from \"../Engines/Processors/shaderProcessingOptions\";\r\nimport { ShaderStore } from \"../Engines/shaderStore\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\n\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type ComputeCompilationMessages } from \"../Engines/Extensions/engine.computeShader\";\r\nimport { _RetryWithInterval } from \"core/Misc/timingTools\";\r\n\r\n/**\r\n * Defines the route to the shader code. The priority is as follows:\r\n *  * object: `{ computeSource: \"compute shader code string\"}` for directly passing the shader code\r\n *  * object: `{ computeElement: \"vertexShaderCode\" }`, used with shader code in script tags\r\n *  * object: `{ compute: \"custom\" }`, used with `Effect.ShadersStore[\"customVertexShader\"]` and `Effect.ShadersStore[\"customFragmentShader\"]`\r\n *  * string: `\"./COMMON_NAME\"`, used with external files COMMON_NAME.vertex.fx and COMMON_NAME.fragment.fx in index.html folder.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type IComputeShaderPath = {\r\n    /**\r\n     * Directly pass the shader code\r\n     */\r\n    computeSource?: string;\r\n    /**\r\n     * Used with Effect.ShadersStore. If the `vertex` is set to `\"custom`, then\r\n     * Babylon.js will read from Effect.ShadersStore[\"customVertexShader\"]\r\n     */\r\n    compute?: string;\r\n    /**\r\n     * Used with shader code in script tags\r\n     */\r\n    computeElement?: string;\r\n};\r\n\r\n/**\r\n * Options to be used when creating a compute effect.\r\n */\r\nexport interface IComputeEffectCreationOptions {\r\n    /**\r\n     * Define statements that will be set in the shader.\r\n     */\r\n    defines: any;\r\n    /**\r\n     * The name of the entry point in the shader source (default: \"main\")\r\n     */\r\n    entryPoint?: string;\r\n    /**\r\n     * Callback that will be called when the shader is compiled.\r\n     */\r\n    onCompiled: Nullable<(effect: ComputeEffect) => void>;\r\n    /**\r\n     * Callback that will be called if an error occurs during shader compilation.\r\n     */\r\n    onError: Nullable<(effect: ComputeEffect, errors: string) => void>;\r\n    /**\r\n     * If provided, will be called with the shader code so that this code can be updated before it is compiled by the GPU\r\n     */\r\n    processFinalCode?: Nullable<(code: string) => string>;\r\n    /**\r\n     * If true, the engine should create an explicit pipeline layout for the compute effect instead of using an automatic layout.\r\n     */\r\n    useExplicitComputePipelineLayout?: boolean;\r\n}\r\n\r\n/**\r\n * Effect wrapping a compute shader and let execute (dispatch) the shader\r\n */\r\nexport class ComputeEffect {\r\n    private static _UniqueIdSeed = 0;\r\n\r\n    /**\r\n     * Enable logging of the shader code when a compilation error occurs\r\n     */\r\n    public static LogShaderCodeOnCompilationError = true;\r\n    /**\r\n     * Name of the effect.\r\n     */\r\n    public name: IComputeShaderPath | string;\r\n    /**\r\n     * String container all the define statements that should be set on the shader.\r\n     */\r\n    public defines: string = \"\";\r\n    /**\r\n     * Callback that will be called when the shader is compiled.\r\n     */\r\n    public onCompiled: Nullable<(effect: ComputeEffect) => void> = null;\r\n    /**\r\n     * Callback that will be called if an error occurs during shader compilation.\r\n     */\r\n    public onError: Nullable<(effect: ComputeEffect, errors: string) => void> = null;\r\n    /**\r\n     * Unique ID of the effect.\r\n     */\r\n    public uniqueId = 0;\r\n    /**\r\n     * Observable that will be called when the shader is compiled.\r\n     * It is recommended to use executeWhenCompile() or to make sure that scene.isReady() is called to get this observable raised.\r\n     */\r\n    public onCompileObservable = new Observable<ComputeEffect>();\r\n    /**\r\n     * Observable that will be called if an error occurs during shader compilation.\r\n     */\r\n    public onErrorObservable = new Observable<ComputeEffect>();\r\n    /**\r\n     * Observable that will be called when effect is bound.\r\n     */\r\n    public onBindObservable = new Observable<ComputeEffect>();\r\n\r\n    /**\r\n     * @internal\r\n     * Specifies if the effect was previously ready\r\n     */\r\n    public _wasPreviouslyReady = false;\r\n\r\n    private _engine: AbstractEngine;\r\n    private _isReady = false;\r\n    private _compilationError = \"\";\r\n    /** @internal */\r\n    public _key: string = \"\";\r\n    private _computeSourceCodeOverride: string = \"\";\r\n    /** @internal */\r\n    public _pipelineContext: Nullable<IComputePipelineContext> = null;\r\n    /** @internal */\r\n    public _computeSourceCode: string = \"\";\r\n    /** @internal */\r\n    public _useExplicitComputePipelineLayout = false;\r\n    private _rawComputeSourceCode: string = \"\";\r\n    private _entryPoint: string;\r\n    private _shaderLanguage = ShaderLanguage.WGSL;\r\n    private _shaderStore: { [key: string]: string };\r\n    private _shaderRepository: string;\r\n    private _includeShaderStore: { [key: string]: string };\r\n\r\n    /**\r\n     * Creates a compute effect that can be used to execute a compute shader\r\n     * @param baseName Name of the effect\r\n     * @param options Set of all options to create the effect\r\n     * @param engine The engine the effect is created for\r\n     * @param key Effect Key identifying uniquely compiled shader variants\r\n     */\r\n    constructor(baseName: IComputeShaderPath | string, options: IComputeEffectCreationOptions, engine: AbstractEngine, key = \"\") {\r\n        this.name = baseName;\r\n        this._key = key;\r\n\r\n        this._engine = engine;\r\n        this.uniqueId = ComputeEffect._UniqueIdSeed++;\r\n\r\n        this.defines = options.defines ?? \"\";\r\n        this.onError = options.onError;\r\n        this.onCompiled = options.onCompiled;\r\n        this._entryPoint = options.entryPoint ?? \"main\";\r\n        this._useExplicitComputePipelineLayout = !!options.useExplicitComputePipelineLayout;\r\n\r\n        this._shaderStore = ShaderStore.GetShadersStore(this._shaderLanguage);\r\n        this._shaderRepository = ShaderStore.GetShadersRepository(this._shaderLanguage);\r\n        this._includeShaderStore = ShaderStore.GetIncludesShadersStore(this._shaderLanguage);\r\n\r\n        let computeSource: IComputeShaderPath | HTMLElement | string;\r\n\r\n        const hostDocument = IsWindowObjectExist() ? this._engine.getHostDocument() : null;\r\n\r\n        if (typeof baseName === \"string\") {\r\n            computeSource = baseName;\r\n        } else if (typeof baseName.computeSource === \"string\") {\r\n            computeSource = \"source:\" + baseName.computeSource;\r\n        } else if (typeof baseName.computeElement === \"string\") {\r\n            computeSource = hostDocument?.getElementById(baseName.computeElement) || baseName.computeElement;\r\n        } else {\r\n            computeSource = baseName.compute || baseName;\r\n        }\r\n\r\n        const processorOptions: _IProcessingOptions = {\r\n            defines: this.defines.split(\"\\n\"),\r\n            indexParameters: undefined,\r\n            isFragment: false,\r\n            shouldUseHighPrecisionShader: false,\r\n            processor: null,\r\n            supportsUniformBuffers: this._engine.supportsUniformBuffers,\r\n            shadersRepository: this._shaderRepository,\r\n            includesShadersStore: this._includeShaderStore,\r\n            version: (this._engine.version * 100).toString(),\r\n            platformName: this._engine.shaderPlatformName,\r\n            processingContext: null,\r\n            isNDCHalfZRange: this._engine.isNDCHalfZRange,\r\n            useReverseDepthBuffer: this._engine.useReverseDepthBuffer,\r\n            processCodeAfterIncludes: (shaderType: string, code: string, defines?: string[]) => {\r\n                if (!defines) {\r\n                    return code;\r\n                }\r\n                // We need to convert #define key value to a const\r\n                for (const define of defines) {\r\n                    const keyValue = define.replace(\"#define\", \"\").replace(\";\", \"\").trim();\r\n                    const split = keyValue.split(\" \");\r\n                    if (split.length === 2) {\r\n                        const key = split[0];\r\n                        const value = split[1];\r\n                        if (!isNaN(parseInt(value)) || !isNaN(parseFloat(value))) {\r\n                            code = `const ${key} = ${value};\\n` + code;\r\n                        }\r\n                    }\r\n                }\r\n                return code;\r\n            },\r\n        };\r\n\r\n        this._loadShader(computeSource, \"Compute\", \"\", (computeCode) => {\r\n            Initialize(processorOptions);\r\n            PreProcess(\r\n                computeCode,\r\n                processorOptions,\r\n                (migratedComputeCode) => {\r\n                    this._rawComputeSourceCode = computeCode;\r\n                    if (options.processFinalCode) {\r\n                        migratedComputeCode = options.processFinalCode(migratedComputeCode);\r\n                    }\r\n                    const finalShaders = Finalize(migratedComputeCode, \"\", processorOptions);\r\n                    this._useFinalCode(finalShaders.vertexCode, baseName);\r\n                },\r\n                this._engine\r\n            );\r\n        });\r\n    }\r\n\r\n    private _useFinalCode(migratedCommputeCode: string, baseName: any) {\r\n        if (baseName) {\r\n            const compute = baseName.computeElement || baseName.compute || baseName.spectorName || baseName;\r\n\r\n            this._computeSourceCode = \"//#define SHADER_NAME compute:\" + compute + \"\\n\" + migratedCommputeCode;\r\n        } else {\r\n            this._computeSourceCode = migratedCommputeCode;\r\n        }\r\n        this._prepareEffect();\r\n    }\r\n\r\n    /**\r\n     * Unique key for this effect\r\n     */\r\n    public get key(): string {\r\n        return this._key;\r\n    }\r\n\r\n    /**\r\n     * If the effect has been compiled and prepared.\r\n     * @returns if the effect is compiled and prepared.\r\n     */\r\n    public isReady(): boolean {\r\n        try {\r\n            return this._isReadyInternal();\r\n        } catch {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    private _isReadyInternal(): boolean {\r\n        if (this._isReady) {\r\n            return true;\r\n        }\r\n        if (this._pipelineContext) {\r\n            return this._pipelineContext.isReady;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * The engine the effect was initialized with.\r\n     * @returns the engine.\r\n     */\r\n    public getEngine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * The pipeline context for this effect\r\n     * @returns the associated pipeline context\r\n     */\r\n    public getPipelineContext(): Nullable<IComputePipelineContext> {\r\n        return this._pipelineContext;\r\n    }\r\n\r\n    /**\r\n     * The error from the last compilation.\r\n     * @returns the error string.\r\n     */\r\n    public getCompilationError(): string {\r\n        return this._compilationError;\r\n    }\r\n\r\n    /**\r\n     * Adds a callback to the onCompiled observable and call the callback immediately if already ready.\r\n     * @param func The callback to be used.\r\n     */\r\n    public executeWhenCompiled(func: (effect: ComputeEffect) => void): void {\r\n        if (this.isReady()) {\r\n            func(this);\r\n            return;\r\n        }\r\n\r\n        this.onCompileObservable.add((effect) => {\r\n            func(effect);\r\n        });\r\n\r\n        if (!this._pipelineContext || this._pipelineContext.isAsync) {\r\n            this._checkIsReady(null);\r\n        }\r\n    }\r\n\r\n    private _checkIsReady(previousPipelineContext: Nullable<IComputePipelineContext>) {\r\n        _RetryWithInterval(\r\n            () => this._isReadyInternal(),\r\n            () => {\r\n                // no-op, all work is done in _isReadyInternal\r\n            },\r\n            (e) => {\r\n                this._processCompilationErrors(e, previousPipelineContext);\r\n            },\r\n            undefined,\r\n            undefined,\r\n            false\r\n        );\r\n    }\r\n\r\n    private _loadShader(shader: any, key: string, optionalKey: string, callback: (data: any) => void): void {\r\n        if (typeof HTMLElement !== \"undefined\") {\r\n            // DOM element ?\r\n            if (shader instanceof HTMLElement) {\r\n                const shaderCode = GetDOMTextContent(shader);\r\n                callback(shaderCode);\r\n                return;\r\n            }\r\n        }\r\n\r\n        // Direct source ?\r\n        if (shader.substring(0, 7) === \"source:\") {\r\n            callback(shader.substring(7));\r\n            return;\r\n        }\r\n\r\n        // Base64 encoded ?\r\n        if (shader.substring(0, 7) === \"base64:\") {\r\n            const shaderBinary = window.atob(shader.substring(7));\r\n            callback(shaderBinary);\r\n            return;\r\n        }\r\n\r\n        // Is in local store ?\r\n        if (this._shaderStore[shader + key + \"Shader\"]) {\r\n            callback(this._shaderStore[shader + key + \"Shader\"]);\r\n            return;\r\n        }\r\n\r\n        if (optionalKey && this._shaderStore[shader + optionalKey + \"Shader\"]) {\r\n            callback(this._shaderStore[shader + optionalKey + \"Shader\"]);\r\n            return;\r\n        }\r\n\r\n        let shaderUrl;\r\n\r\n        if (shader[0] === \".\" || shader[0] === \"/\" || shader.indexOf(\"http\") > -1) {\r\n            shaderUrl = shader;\r\n        } else {\r\n            shaderUrl = this._shaderRepository + shader;\r\n        }\r\n\r\n        this._engine._loadFile(shaderUrl + \".\" + key.toLowerCase() + \".fx\", callback);\r\n    }\r\n\r\n    /**\r\n     * Gets the compute shader source code of this effect\r\n     */\r\n    public get computeSourceCode(): string {\r\n        return this._computeSourceCodeOverride ? this._computeSourceCodeOverride : (this._pipelineContext?._getComputeShaderCode() ?? this._computeSourceCode);\r\n    }\r\n\r\n    /**\r\n     * Gets the compute shader source code before it has been processed by the preprocessor\r\n     */\r\n    public get rawComputeSourceCode(): string {\r\n        return this._rawComputeSourceCode;\r\n    }\r\n\r\n    /**\r\n     * Prepares the effect\r\n     * @internal\r\n     */\r\n    public _prepareEffect() {\r\n        const defines = this.defines;\r\n\r\n        const previousPipelineContext = this._pipelineContext;\r\n\r\n        this._isReady = false;\r\n\r\n        try {\r\n            const engine = this._engine;\r\n\r\n            this._pipelineContext = engine.createComputePipelineContext();\r\n            this._pipelineContext._name = this._key;\r\n\r\n            engine._prepareComputePipelineContext(\r\n                this._pipelineContext,\r\n                this._computeSourceCodeOverride ? this._computeSourceCodeOverride : this._computeSourceCode,\r\n                this._rawComputeSourceCode,\r\n                this._computeSourceCodeOverride ? null : defines,\r\n                this._entryPoint\r\n            );\r\n\r\n            engine._executeWhenComputeStateIsCompiled(this._pipelineContext, (messages: Nullable<ComputeCompilationMessages>) => {\r\n                if (messages && messages.numErrors > 0) {\r\n                    this._processCompilationErrors(messages, previousPipelineContext);\r\n                    return;\r\n                }\r\n                this._compilationError = \"\";\r\n                this._isReady = true;\r\n                if (this.onCompiled) {\r\n                    this.onCompiled(this);\r\n                }\r\n                this.onCompileObservable.notifyObservers(this);\r\n                this.onCompileObservable.clear();\r\n\r\n                if (previousPipelineContext) {\r\n                    this.getEngine()._deleteComputePipelineContext(previousPipelineContext);\r\n                }\r\n            });\r\n\r\n            if (this._pipelineContext.isAsync) {\r\n                this._checkIsReady(previousPipelineContext);\r\n            }\r\n        } catch (e) {\r\n            let err = \"\" + e;\r\n            if (e instanceof Error && e.stack) {\r\n                err = e.stack;\r\n            }\r\n            this._processCompilationErrors(err, previousPipelineContext);\r\n        }\r\n    }\r\n\r\n    private _processCompilationErrors(e: ComputeCompilationMessages | string, previousPipelineContext: Nullable<IComputePipelineContext> = null) {\r\n        this._compilationError = \"\";\r\n\r\n        Logger.Error(\"Unable to compile compute effect:\");\r\n        if (this.defines) {\r\n            Logger.Error(\"Defines:\\n\" + this.defines);\r\n        }\r\n\r\n        if (ComputeEffect.LogShaderCodeOnCompilationError) {\r\n            const code = this._pipelineContext?._getComputeShaderCode();\r\n            if (code) {\r\n                Logger.Error(\"Compute code:\");\r\n                Logger.Error(code);\r\n            }\r\n        }\r\n\r\n        if (typeof e === \"string\") {\r\n            this._compilationError = e;\r\n            Logger.Error(\"Error: \" + this._compilationError);\r\n        } else {\r\n            for (const message of e.messages) {\r\n                let msg = \"\";\r\n                if (message.line !== undefined) {\r\n                    msg += \"Line \" + message.line + \", \";\r\n                }\r\n                if (message.offset !== undefined) {\r\n                    msg += \"Offset \" + message.offset + \", \";\r\n                }\r\n                if (message.length !== undefined) {\r\n                    msg += \"Length \" + message.length + \", \";\r\n                }\r\n                msg += message.type + \": \" + message.text;\r\n\r\n                if (this._compilationError) {\r\n                    this._compilationError += \"\\n\";\r\n                }\r\n                this._compilationError += msg;\r\n                Logger.Error(msg);\r\n            }\r\n        }\r\n\r\n        if (previousPipelineContext) {\r\n            this._pipelineContext = previousPipelineContext;\r\n            this._isReady = true;\r\n        }\r\n\r\n        if (this.onError) {\r\n            this.onError(this, this._compilationError);\r\n        }\r\n        this.onErrorObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources.\r\n     **/\r\n    public dispose() {\r\n        if (this._pipelineContext) {\r\n            this._pipelineContext.dispose();\r\n        }\r\n        this._engine._releaseComputeEffect(this);\r\n    }\r\n\r\n    /**\r\n     * This function will add a new compute shader to the shader store\r\n     * @param name the name of the shader\r\n     * @param computeShader compute shader content\r\n     */\r\n    public static RegisterShader(name: string, computeShader: string) {\r\n        ShaderStore.GetShadersStore(ShaderLanguage.WGSL)[`${name}ComputeShader`] = computeShader;\r\n    }\r\n}\r\n","import { PerfCounter } from \"../../Misc/perfCounter\";\r\n\r\n/**\r\n * Class used to define a WebGPU performance counter\r\n */\r\nexport class WebGPUPerfCounter {\r\n    private _gpuTimeInFrameId = -1;\r\n\r\n    /**\r\n     * The GPU time in nanoseconds spent in the last frame\r\n     */\r\n    public counter = new PerfCounter();\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _addDuration(currentFrameId: number, duration: number) {\r\n        if (currentFrameId < this._gpuTimeInFrameId) {\r\n            return;\r\n        }\r\n        if (this._gpuTimeInFrameId !== currentFrameId) {\r\n            this.counter._fetchResult();\r\n            this.counter.fetchNewFrame();\r\n            this.counter.addCount(duration, false);\r\n            this._gpuTimeInFrameId = currentFrameId;\r\n        } else {\r\n            this.counter.addCount(duration, false);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type UniformBuffer } from \"../Materials/uniformBuffer\";\nimport { type WebGPUEngine } from \"../Engines/webgpuEngine.pure\";\nimport { type Scene } from \"../scene.pure\";\nimport { type Nullable } from \"../types\";\nimport { serialize } from \"../Misc/decorators\";\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\nimport { type ComputeEffect, type IComputeEffectCreationOptions, type IComputeShaderPath } from \"./computeEffect\";\nimport { type ComputeBindingMapping, ComputeBindingType } from \"../Engines/Extensions/engine.computeShader.pure\";\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\nimport { Texture } from \"../Materials/Textures/texture.pure\";\nimport { UniqueIdGenerator } from \"../Misc/uniqueIdGenerator\";\nimport { type IComputeContext } from \"./IComputeContext\";\nimport { type StorageBuffer } from \"../Buffers/storageBuffer\";\nimport { Logger } from \"../Misc/logger\";\nimport { TextureSampler } from \"../Materials/Textures/textureSampler\";\nimport { type DataBuffer } from \"core/Buffers/dataBuffer\";\nimport { type ExternalTexture } from \"core/Materials/Textures/externalTexture\";\nimport { type VideoTexture } from \"core/Materials/Textures/videoTexture.pure\";\nimport { WebGPUPerfCounter } from \"core/Engines/WebGPU/webgpuPerfCounter\";\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\nimport { _RetryWithInterval } from \"core/Misc/timingTools\";\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\nimport { RegisterClass } from \"../Misc/typeStore\";\n\n/**\n * Defines the options associated with the creation of a compute shader.\n */\nexport interface IComputeShaderOptions {\n    /**\n     * list of bindings mapping (key is property name, value is binding location)\n     * Must be provided because browsers don't support reflection for wgsl shaders yet (so there's no way to query the binding/group from a variable name)\n     * TODO: remove this when browsers support reflection for wgsl shaders\n     */\n    bindingsMapping: ComputeBindingMapping;\n\n    /**\n     * The list of defines used in the shader\n     */\n    defines?: string[];\n\n    /**\n     * The name of the entry point in the shader source (default: \"main\")\n     */\n    entryPoint?: string;\n\n    /**\n     * If provided, will be called with the shader code so that this code can be updated before it is compiled by the GPU\n     */\n    processFinalCode?: Nullable<(code: string) => string>;\n\n    /**\n     * If true, the engine should create an explicit pipeline layout for this compute shader instead of using an automatic layout.\n     */\n    useExplicitComputePipelineLayout?: boolean;\n}\n\ntype ComputeBindingListInternal = { [key: string]: { type: ComputeBindingType; object: any; indexInGroupEntries?: number; buffer?: Nullable<DataBuffer> } };\n\n/**\n * The ComputeShader object lets you execute a compute shader on your GPU (if supported by the engine)\n */\nexport class ComputeShader {\n    private _engine: AbstractEngine;\n    private _shaderPath: IComputeShaderPath | string;\n    private _options: IComputeShaderOptions;\n    private _effect: ComputeEffect;\n    private _cachedDefines: string;\n    private _bindings: ComputeBindingListInternal = {};\n    private _samplers: { [key: string]: TextureSampler } = {};\n    private _context: IComputeContext;\n    private _contextIsDirty = false;\n\n    /**\n     * Gets the unique id of the compute shader\n     */\n    public readonly uniqueId: number;\n\n    /**\n     * The name of the shader\n     */\n    @serialize()\n    public name: string;\n\n    /**\n     * The options used to create the shader\n     */\n    public get options() {\n        return this._options;\n    }\n\n    /**\n     * The shaderPath used to create the shader\n     */\n    public get shaderPath() {\n        return this._shaderPath;\n    }\n\n    /**\n     * When set to true, dispatch won't call isReady anymore and won't check if the underlying GPU resources should be (re)created because of a change in the inputs (texture, uniform buffer, etc.)\n     * If you know that your inputs did not change since last time dispatch was called and that isReady() returns true, set this flag to true to improve performance\n     */\n    @serialize()\n    public fastMode = false;\n\n    /**\n     * Callback triggered when the shader is compiled\n     */\n    public onCompiled: Nullable<(effect: ComputeEffect) => void> = null;\n\n    /**\n     * Callback triggered when an error occurs\n     */\n    public onError: Nullable<(effect: ComputeEffect, errors: string) => void> = null;\n\n    /**\n     * Gets the GPU time spent running the compute shader for the last frame rendered (in nanoseconds).\n     * You have to enable the \"timestamp-query\" extension in the engine constructor options and set engine.enableGPUTimingMeasurements = true.\n     */\n    public readonly gpuTimeInFrame?: WebGPUPerfCounter;\n\n    /**\n     * If set to true, the compute context will be rebuilt at the next dispatch even if in fast mode\n     */\n    public triggerContextRebuild = false;\n\n    /**\n     * Instantiates a new compute shader.\n     * @param name Defines the name of the compute shader in the scene\n     * @param engine Defines the engine the compute shader belongs to\n     * @param shaderPath Defines the route to the shader code in one of three ways:\n     *  * object: \\{ compute: \"custom\" \\}, used with ShaderStore.ShadersStoreWGSL[\"customComputeShader\"]\n     *  * object: \\{ computeElement: \"HTMLElementId\" \\}, used with shader code in script tags\n     *  * object: \\{ computeSource: \"compute shader code string\" \\}, where the string contains the shader code\n     *  * string: try first to find the code in ShaderStore.ShadersStoreWGSL[shaderPath + \"ComputeShader\"]. If not, assumes it is a file with name shaderPath.compute.fx in index.html folder.\n     * @param options Define the options used to create the shader\n     */\n    constructor(name: string, engine: AbstractEngine, shaderPath: IComputeShaderPath | string, options: Partial<IComputeShaderOptions> = {}) {\n        this.name = name;\n        this._engine = engine;\n        this.uniqueId = UniqueIdGenerator.UniqueId;\n        if ((engine as WebGPUEngine).enableGPUTimingMeasurements) {\n            this.gpuTimeInFrame = new WebGPUPerfCounter();\n        }\n\n        if (!this._engine.getCaps().supportComputeShaders) {\n            Logger.Error(\"This engine does not support compute shaders!\");\n            return;\n        }\n        if (!options.bindingsMapping) {\n            Logger.Error(\"You must provide the binding mappings as browsers don't support reflection for wgsl shaders yet!\");\n            return;\n        }\n\n        this._context = engine.createComputeContext()!;\n        this._shaderPath = shaderPath;\n        this._options = {\n            bindingsMapping: {},\n            defines: [],\n            entryPoint: \"main\",\n            ...options,\n        };\n    }\n\n    /**\n     * Gets the current class name of the material e.g. \"ComputeShader\"\n     * Mainly use in serialization.\n     * @returns the class name\n     */\n    public getClassName(): string {\n        return \"ComputeShader\";\n    }\n\n    /**\n     * Binds a texture to the shader\n     * @param name Binding name of the texture\n     * @param texture Texture to bind\n     * @param bindSampler Bind the sampler corresponding to the texture (default: true). The sampler will be bound just before the binding index of the texture\n     */\n    public setTexture(name: string, texture: BaseTexture, bindSampler = true): void {\n        const current = this._bindings[name];\n\n        this._bindings[name] = {\n            type: bindSampler ? ComputeBindingType.Texture : ComputeBindingType.TextureWithoutSampler,\n            object: texture,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n\n        this._contextIsDirty ||= !current || current.object !== texture || current.type !== this._bindings[name].type;\n    }\n\n    /**\n     * Binds an internal texture to the shader\n     * @param name Binding name of the texture\n     * @param texture Texture to bind\n     */\n    public setInternalTexture(name: string, texture: InternalTexture): void {\n        const current = this._bindings[name];\n\n        this._bindings[name] = {\n            type: ComputeBindingType.InternalTexture,\n            object: texture,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n\n        this._contextIsDirty ||= !current || current.object !== texture || current.type !== this._bindings[name].type;\n    }\n\n    /**\n     * Binds a storage texture to the shader\n     * @param name Binding name of the texture\n     * @param texture Texture to bind\n     */\n    public setStorageTexture(name: string, texture: BaseTexture): void {\n        const current = this._bindings[name];\n\n        this._contextIsDirty ||= !current || current.object !== texture;\n\n        this._bindings[name] = {\n            type: ComputeBindingType.StorageTexture,\n            object: texture,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n    }\n\n    /**\n     * Binds an external texture to the shader\n     * @param name Binding name of the texture\n     * @param texture Texture to bind\n     */\n    public setExternalTexture(name: string, texture: ExternalTexture): void {\n        const current = this._bindings[name];\n\n        this._contextIsDirty ||= !current || current.object !== texture;\n\n        this._bindings[name] = {\n            type: ComputeBindingType.ExternalTexture,\n            object: texture,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n    }\n\n    /**\n     * Binds a video texture to the shader (by binding the external texture attached to this video)\n     * @param name Binding name of the texture\n     * @param texture Texture to bind\n     * @returns true if the video texture was successfully bound, else false. false will be returned if the current engine does not support external textures\n     */\n    public setVideoTexture(name: string, texture: VideoTexture) {\n        if (texture.externalTexture) {\n            this.setExternalTexture(name, texture.externalTexture);\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Binds a uniform buffer to the shader\n     * @param name Binding name of the buffer\n     * @param buffer Buffer to bind\n     */\n    public setUniformBuffer(name: string, buffer: UniformBuffer | DataBuffer): void {\n        const current = this._bindings[name];\n\n        this._contextIsDirty ||= !current || current.object !== buffer;\n\n        this._bindings[name] = {\n            type: ComputeShader._BufferIsDataBuffer(buffer) ? ComputeBindingType.DataBuffer : ComputeBindingType.UniformBuffer,\n            object: buffer,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n    }\n\n    /**\n     * Binds a storage buffer to the shader\n     * @param name Binding name of the buffer\n     * @param buffer Buffer to bind\n     */\n    public setStorageBuffer(name: string, buffer: StorageBuffer | DataBuffer): void {\n        const current = this._bindings[name];\n\n        this._contextIsDirty ||= !current || current.object !== buffer;\n\n        this._bindings[name] = {\n            type: ComputeShader._BufferIsDataBuffer(buffer) ? ComputeBindingType.DataBuffer : ComputeBindingType.StorageBuffer,\n            object: buffer,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n    }\n\n    /**\n     * Binds a texture sampler to the shader\n     * @param name Binding name of the sampler\n     * @param sampler Sampler to bind\n     */\n    public setTextureSampler(name: string, sampler: TextureSampler): void {\n        const current = this._bindings[name];\n\n        this._contextIsDirty ||= !current || !sampler.compareSampler(current.object);\n\n        this._bindings[name] = {\n            type: ComputeBindingType.Sampler,\n            object: sampler,\n            indexInGroupEntries: current?.indexInGroupEntries,\n        };\n    }\n\n    /**\n     * Specifies that the compute shader is ready to be executed (the compute effect and all the resources are ready)\n     * @returns true if the compute shader is ready to be executed\n     */\n    public isReady(): boolean {\n        let effect = this._effect;\n\n        for (const key in this._bindings) {\n            const binding = this._bindings[key],\n                type = binding.type,\n                object = binding.object;\n\n            switch (type) {\n                case ComputeBindingType.Texture:\n                case ComputeBindingType.TextureWithoutSampler:\n                case ComputeBindingType.StorageTexture: {\n                    const texture = object as BaseTexture;\n                    if (!texture.isReady()) {\n                        return false;\n                    }\n                    break;\n                }\n                case ComputeBindingType.ExternalTexture: {\n                    const texture = object as ExternalTexture;\n                    if (!texture.isReady()) {\n                        return false;\n                    }\n                    break;\n                }\n            }\n        }\n\n        const defines = [\"#define \" + this._options.entryPoint];\n\n        const shaderName = this._shaderPath;\n\n        if (this._options.defines) {\n            for (let index = 0; index < this._options.defines.length; index++) {\n                defines.push(this._options.defines[index]);\n            }\n        }\n\n        const join = defines.join(\"\\n\");\n\n        if (this._cachedDefines !== join) {\n            this._cachedDefines = join;\n\n            effect = this._engine.createComputeEffect(shaderName, <IComputeEffectCreationOptions>{\n                defines: join,\n                entryPoint: this._options.entryPoint,\n                onCompiled: this.onCompiled,\n                onError: this.onError,\n                useExplicitComputePipelineLayout: this._options.useExplicitComputePipelineLayout,\n            });\n\n            this._effect = effect;\n        }\n\n        if (!effect.isReady()) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Dispatches (executes) the compute shader\n     * @param x Number of workgroups to execute on the X dimension\n     * @param y Number of workgroups to execute on the Y dimension (default: 1)\n     * @param z Number of workgroups to execute on the Z dimension (default: 1)\n     * @returns True if the dispatch could be done, else false (meaning either the compute effect or at least one of the bound resources was not ready)\n     */\n    public dispatch(x: number, y?: number, z?: number): boolean {\n        if ((!this.fastMode || this.triggerContextRebuild) && !this._checkContext()) {\n            return false;\n        }\n        this._engine.computeDispatch(this._effect, this._context, this._bindings, x, y, z, this._options.bindingsMapping, this.gpuTimeInFrame);\n\n        return true;\n    }\n\n    /**\n     * Dispatches (executes) the compute shader.\n     * @param buffer Buffer containing the number of workgroups to execute on the X, Y and Z dimensions\n     * @param offset Offset in the buffer where the workgroup counts are stored (default: 0)\n     * @returns True if the dispatch could be done, else false (meaning either the compute effect or at least one of the bound resources was not ready)\n     */\n    public dispatchIndirect(buffer: StorageBuffer | DataBuffer, offset: number = 0): boolean {\n        if ((!this.fastMode || this.triggerContextRebuild) && !this._checkContext()) {\n            return false;\n        }\n        const dataBuffer = ComputeShader._BufferIsDataBuffer(buffer) ? buffer : buffer.getBuffer();\n        this._engine.computeDispatchIndirect(this._effect, this._context, this._bindings, dataBuffer, offset, this._options.bindingsMapping, this.gpuTimeInFrame);\n        return true;\n    }\n\n    private _checkContext(): boolean {\n        if (!this.isReady()) {\n            return false;\n        }\n\n        // If the sampling parameters of a texture bound to the shader have changed, we must clear the compute context so that it is recreated with the updated values\n        // Also, if the actual (gpu) buffer used by a uniform buffer has changed, we must clear the compute context so that it is recreated with the updated value\n        for (const key in this._bindings) {\n            const binding = this._bindings[key];\n\n            if (!this._options.bindingsMapping[key]) {\n                throw new Error(\"ComputeShader ('\" + this.name + \"'): No binding mapping has been provided for the property '\" + key + \"'\");\n            }\n\n            switch (binding.type) {\n                case ComputeBindingType.Texture: {\n                    const sampler = this._samplers[key];\n                    const texture = binding.object as BaseTexture;\n\n                    if (!sampler || !texture._texture || !sampler.compareSampler(texture._texture)) {\n                        this._samplers[key] = new TextureSampler().setParameters(\n                            texture.wrapU,\n                            texture.wrapV,\n                            texture.wrapR,\n                            texture.anisotropicFilteringLevel,\n                            texture._texture!.samplingMode,\n                            texture._texture?._comparisonFunction\n                        );\n                        this._contextIsDirty = true;\n                    }\n                    break;\n                }\n                case ComputeBindingType.ExternalTexture: {\n                    // we must recreate the bind groups each time if there's an external texture, because device.importExternalTexture must be called each frame\n                    this._contextIsDirty = true;\n                    break;\n                }\n                case ComputeBindingType.UniformBuffer: {\n                    const ubo = binding.object as UniformBuffer;\n                    if (ubo.getBuffer() !== binding.buffer) {\n                        binding.buffer = ubo.getBuffer();\n                        this._contextIsDirty = true;\n                    }\n                    break;\n                }\n            }\n        }\n\n        if (this._contextIsDirty) {\n            this.triggerContextRebuild = false;\n            this._contextIsDirty = false;\n            this._context.clear();\n        }\n        return true;\n    }\n\n    /**\n     * Waits for the compute shader to be ready and executes it\n     * @param x Number of workgroups to execute on the X dimension\n     * @param y Number of workgroups to execute on the Y dimension (default: 1)\n     * @param z Number of workgroups to execute on the Z dimension (default: 1)\n     * @param delay Delay between the retries while the shader is not ready (in milliseconds - 10 by default)\n     * @returns A promise that is resolved once the shader has been sent to the GPU. Note that it does not mean that the shader execution itself is finished!\n     */\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    public async dispatchWhenReady(x: number, y?: number, z?: number, delay = 10): Promise<void> {\n        return await new Promise((resolve) => {\n            _RetryWithInterval(() => this.dispatch(x, y, z), resolve, undefined, delay);\n        });\n    }\n\n    /**\n     * Serializes this compute shader in a JSON representation\n     * @returns the serialized compute shader object\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n\n        serializationObject.options = this._options;\n        serializationObject.shaderPath = this._shaderPath;\n        serializationObject.bindings = {};\n        serializationObject.textures = {};\n\n        for (const key in this._bindings) {\n            const binding = this._bindings[key];\n            const object = binding.object;\n\n            switch (binding.type) {\n                case ComputeBindingType.Texture:\n                case ComputeBindingType.TextureWithoutSampler:\n                case ComputeBindingType.StorageTexture: {\n                    const serializedData = (object as BaseTexture).serialize();\n                    if (serializedData) {\n                        serializationObject.textures[key] = serializedData;\n                        serializationObject.bindings[key] = {\n                            type: binding.type,\n                        };\n                    }\n                    break;\n                }\n\n                case ComputeBindingType.InternalTexture:\n                case ComputeBindingType.UniformBuffer: {\n                    break;\n                }\n            }\n        }\n\n        return serializationObject;\n    }\n\n    protected static _BufferIsDataBuffer(buffer: UniformBuffer | StorageBuffer | DataBuffer): buffer is DataBuffer {\n        return (buffer as DataBuffer).underlyingResource !== undefined;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Creates a compute shader from parsed compute shader data\n * @param source defines the JSON representation of the compute shader\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @returns a new compute shader\n */\nexport function ComputeShaderParse(source: any, scene: Scene, rootUrl: string): ComputeShader {\n    const compute = SerializationHelper.Parse(() => new ComputeShader(source.name, scene.getEngine() as WebGPUEngine, source.shaderPath, source.options), source, scene, rootUrl);\n\n    for (const key in source.textures) {\n        const binding = source.bindings[key];\n        const texture = <Texture>Texture.Parse(source.textures[key], scene, rootUrl);\n\n        if (binding.type === ComputeBindingType.Texture) {\n            compute.setTexture(key, texture);\n        } else if (binding.type === ComputeBindingType.TextureWithoutSampler) {\n            compute.setTexture(key, texture, false);\n        } else {\n            compute.setStorageTexture(key, texture);\n        }\n    }\n\n    return compute;\n}\n\n/**\n * Register side effects for computeShader.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterComputeShader(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    ComputeShader.Parse = ComputeShaderParse;\n\n    RegisterClass(\"BABYLON.ComputeShader\", ComputeShader);\n}\n","import { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type IBoundingInfoHelperPlatform } from \"./IBoundingInfoHelperPlatform\";\r\nimport { type ThinEngine } from \"core/Engines\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Utility class to help with bounding info management\r\n * Warning: using the BoundingInfoHelper class may be slower than executing calculations on the CPU!\r\n * This will happen if there are a lot of meshes / few vertices (like with the BrainStem model)\r\n * The BoundingInfoHelper will perform better if there are few meshes / a lot of vertices\r\n *  https://playground.babylonjs.com/#QPOERJ#9 : WebGL\r\n *  https://playground.babylonjs.com/#QPOERJ#10 : WebGPU\r\n */\r\nexport class BoundingInfoHelper {\r\n    private _platform: IBoundingInfoHelperPlatform;\r\n    private _engine: AbstractEngine;\r\n\r\n    /**\r\n     * Creates a new BoundingInfoHelper\r\n     * @param engine defines the engine to use\r\n     */\r\n    public constructor(engine: AbstractEngine) {\r\n        this._engine = engine;\r\n    }\r\n\r\n    private async _initializePlatformAsync() {\r\n        if (!this._platform) {\r\n            if (this._engine.getCaps().supportComputeShaders) {\r\n                const [{ ComputeShaderBoundingHelper }] = await Promise.all([import(\"./computeShaderBoundingHelper.pure\"), import(\"../../ShadersWGSL/boundingInfo.compute\")]);\r\n                this._platform = new ComputeShaderBoundingHelper(this._engine);\r\n            } else if (this._engine.getCaps().supportTransformFeedbacks) {\r\n                const [{ TransformFeedbackBoundingHelper }] = await Promise.all([\r\n                    import(\"./transformFeedbackBoundingHelper.pure\"),\r\n                    import(\"../../Shaders/gpuTransform.vertex\"),\r\n                    import(\"../../Shaders/gpuTransform.fragment\"),\r\n                ]);\r\n                this._platform = new TransformFeedbackBoundingHelper(this._engine as ThinEngine);\r\n            } else {\r\n                throw new Error(\"Your engine does not support Compute Shaders or Transform Feedbacks\");\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Compute the bounding info of a mesh / array of meshes using shaders\r\n     * @param target defines the mesh(es) to update\r\n     * @returns a promise that resolves when the bounding info is/are computed\r\n     */\r\n    public async computeAsync(target: AbstractMesh | AbstractMesh[]): Promise<void> {\r\n        await this._initializePlatformAsync();\r\n        return await this._platform.processAsync(target);\r\n    }\r\n\r\n    /**\r\n     * Register a mesh / array of meshes to be processed per batch\r\n     * This method must be called before calling batchProcess (which can be called several times) and batchFetchResultsAsync\r\n     * @param target defines the mesh(es) to be processed per batch\r\n     * @returns a promise that resolves when the initialization is done\r\n     */\r\n    public async batchInitializeAsync(target: AbstractMesh | AbstractMesh[]): Promise<void> {\r\n        await this._initializePlatformAsync();\r\n        return await this._platform.registerMeshListAsync(target);\r\n    }\r\n\r\n    /**\r\n     * Processes meshes registered with batchRegisterAsync\r\n     * If called multiple times, the second, third, etc calls will perform a union of the bounding boxes calculated in the previous calls\r\n     */\r\n    public batchProcess(): void {\r\n        if (!this._platform) {\r\n            Logger.Warn(\"Helper is not initialized. Skipping batch.\");\r\n            return;\r\n        }\r\n        this._platform.processMeshList();\r\n    }\r\n\r\n    /**\r\n     * Update the bounding info of the meshes registered with batchRegisterAsync, after batchProcess has been called once or several times\r\n     * @returns a promise that resolves when the bounding info is/are computed\r\n     */\r\n    public async batchFetchResultsAsync(): Promise<void> {\r\n        await this._initializePlatformAsync();\r\n        return await this._platform.fetchResultsForMeshListAsync();\r\n    }\r\n\r\n    /**\r\n     * Dispose and release associated resources\r\n     */\r\n    public dispose(): void {\r\n        if (this._platform) {\r\n            this._platform.dispose();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { type ThinEngine } from \"core/Engines/thinEngine.pure\";\r\nimport { VertexBuffer, Buffer } from \"core/Buffers/buffer.pure\";\r\nimport { type Engine } from \"core/Engines/engine.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport {\r\n    BindBonesParameters,\r\n    BindMorphTargetParameters,\r\n    PrepareAttributesForBakedVertexAnimation,\r\n    PrepareDefinesAndAttributesForMorphTargets,\r\n} from \"core/Materials/materialHelper.functions\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { type IBoundingInfoHelperPlatform } from \"./IBoundingInfoHelperPlatform\";\r\nimport { extractMinAndMax } from \"core/Maths/math.functions\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\n\r\n/** @internal */\r\nexport class TransformFeedbackBoundingHelper implements IBoundingInfoHelperPlatform {\r\n    private static _Min = /*#__PURE__*/ new Vector3();\r\n    private static _Max = /*#__PURE__*/ new Vector3();\r\n\r\n    private _engine: Nullable<ThinEngine>;\r\n    private _buffers: { [key: number]: Buffer } = {};\r\n    private _effects: { [key: string]: Effect } = {};\r\n    private _meshList: AbstractMesh[];\r\n    private _meshListCounter = 0;\r\n\r\n    /**\r\n     * Creates a new TransformFeedbackBoundingHelper\r\n     * @param engine defines the engine to use\r\n     */\r\n    constructor(engine: ThinEngine) {\r\n        this._engine = engine;\r\n    }\r\n\r\n    /** @internal */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public processAsync(meshes: AbstractMesh | AbstractMesh[]): Promise<void> {\r\n        if (!Array.isArray(meshes)) {\r\n            meshes = [meshes];\r\n        }\r\n\r\n        this._meshListCounter = 0;\r\n\r\n        this._processMeshList(meshes);\r\n\r\n        return Promise.resolve();\r\n    }\r\n\r\n    private _processMeshList(meshes: AbstractMesh[]) {\r\n        const parallelShaderCompile = this._engine!.getCaps().parallelShaderCompile;\r\n\r\n        this._engine!.getCaps().parallelShaderCompile = undefined;\r\n\r\n        for (let i = 0; i < meshes.length; ++i) {\r\n            const mesh = meshes[i];\r\n            const vertexCount = mesh.getTotalVertices();\r\n\r\n            if (vertexCount === 0 || !(mesh as Mesh).getVertexBuffer || !(mesh as Mesh).getVertexBuffer(VertexBuffer.PositionKind)) {\r\n                continue;\r\n            }\r\n\r\n            // Get correct effect\r\n            let computeEffect: Effect;\r\n            const defines: string[] = [];\r\n            const attribs = [VertexBuffer.PositionKind];\r\n\r\n            // Bones\r\n            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n                attribs.push(VertexBuffer.MatricesIndicesKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsKind);\r\n                if (mesh.numBoneInfluencers > 4) {\r\n                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n                }\r\n                defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n                defines.push(\"#define BONETEXTURE \" + mesh.skeleton.isUsingTextureForMatrices);\r\n                defines.push(\"#define BonesPerMesh \" + (mesh.skeleton.bones.length + 1));\r\n            } else {\r\n                defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n            }\r\n\r\n            // Morph\r\n            const numMorphInfluencers = mesh.morphTargetManager\r\n                ? PrepareDefinesAndAttributesForMorphTargets(\r\n                      mesh.morphTargetManager,\r\n                      defines,\r\n                      attribs,\r\n                      mesh,\r\n                      true, // usePositionMorph\r\n                      false, // useNormalMorph\r\n                      false, // useTangentMorph\r\n                      false, // useUVMorph\r\n                      false, // useUV2Morph\r\n                      false // useColorMorph\r\n                  )\r\n                : 0;\r\n\r\n            // Baked Vertex Animation\r\n            const bvaManager = (<Mesh>mesh).bakedVertexAnimationManager;\r\n            if (bvaManager && bvaManager.isEnabled) {\r\n                defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\r\n                PrepareAttributesForBakedVertexAnimation(attribs, mesh, defines);\r\n            }\r\n\r\n            const join = defines.join(\"\\n\");\r\n            if (!this._effects[join]) {\r\n                const uniforms = [\r\n                    \"boneTextureInfo\",\r\n                    \"mBones\",\r\n                    \"morphTargetInfluences\",\r\n                    \"morphTargetCount\",\r\n                    \"morphTargetTextureInfo\",\r\n                    \"morphTargetTextureIndices\",\r\n                    \"bakedVertexAnimationSettings\",\r\n                    \"bakedVertexAnimationTextureSizeInverted\",\r\n                    \"bakedVertexAnimationTime\",\r\n                ];\r\n                const samplers = [\"boneSampler\", \"morphTargets\", \"bakedVertexAnimationTexture\"];\r\n\r\n                const computeEffectOptions = {\r\n                    attributes: attribs,\r\n                    uniformsNames: uniforms,\r\n                    uniformBuffersNames: [],\r\n                    samplers: samplers,\r\n                    defines: join,\r\n                    fallbacks: null,\r\n                    onCompiled: null,\r\n                    onError: null,\r\n                    indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                    maxSimultaneousLights: 0,\r\n                    transformFeedbackVaryings: [\"outPosition\"],\r\n                };\r\n                computeEffect = this._engine!.createEffect(\"gpuTransform\", computeEffectOptions, this._engine!);\r\n                this._effects[join] = computeEffect;\r\n            } else {\r\n                computeEffect = this._effects[join];\r\n            }\r\n\r\n            this._compute(mesh, computeEffect);\r\n        }\r\n\r\n        this._engine!.getCaps().parallelShaderCompile = parallelShaderCompile;\r\n    }\r\n\r\n    private _compute(mesh: AbstractMesh, effect: Effect): void {\r\n        const engine = this._engine as Engine;\r\n\r\n        // Buffer\r\n        let targetBuffer: Buffer;\r\n        const vertexCount = mesh.getTotalVertices();\r\n\r\n        if (!this._buffers[mesh.uniqueId]) {\r\n            const targetData = new Float32Array(vertexCount * 3);\r\n            targetBuffer = new Buffer(mesh.getEngine(), targetData, true, 3);\r\n            this._buffers[mesh.uniqueId] = targetBuffer;\r\n        } else {\r\n            targetBuffer = this._buffers[mesh.uniqueId];\r\n        }\r\n\r\n        // Bind\r\n        effect.getEngine().enableEffect(effect);\r\n        (mesh as Mesh)._bindDirect(effect, null, true);\r\n\r\n        // Bones\r\n        BindBonesParameters(mesh, effect);\r\n\r\n        // Morph targets\r\n        BindMorphTargetParameters(mesh, effect);\r\n        if (mesh.morphTargetManager && mesh.morphTargetManager.isUsingTextureForTargets) {\r\n            mesh.morphTargetManager._bind(effect);\r\n        }\r\n\r\n        // BVA\r\n        const bvaManager = (<Mesh>mesh).bakedVertexAnimationManager;\r\n\r\n        if (bvaManager && bvaManager.isEnabled) {\r\n            mesh.bakedVertexAnimationManager?.bind(effect, false);\r\n        }\r\n\r\n        // Update\r\n        const arrayBuffer = targetBuffer.getData()! as Float32Array;\r\n        engine.bindTransformFeedbackBuffer(targetBuffer.getBuffer());\r\n        engine.setRasterizerState(false);\r\n        engine.beginTransformFeedback(true);\r\n        engine.drawArraysType(Constants.MATERIAL_PointFillMode, 0, vertexCount);\r\n        engine.endTransformFeedback();\r\n        engine.setRasterizerState(true);\r\n        engine.readTransformFeedbackBuffer(arrayBuffer);\r\n        engine.bindTransformFeedbackBuffer(null);\r\n\r\n        // Update mesh\r\n        if (this._meshListCounter === 0) {\r\n            mesh._refreshBoundingInfo(arrayBuffer, null);\r\n        } else {\r\n            const bb = mesh.getBoundingInfo().boundingBox;\r\n            const extend = extractMinAndMax(arrayBuffer, 0, vertexCount);\r\n\r\n            TransformFeedbackBoundingHelper._Min.copyFrom(bb.minimum).minimizeInPlace(extend.minimum);\r\n            TransformFeedbackBoundingHelper._Max.copyFrom(bb.maximum).maximizeInPlace(extend.maximum);\r\n\r\n            mesh._refreshBoundingInfoDirect({ minimum: TransformFeedbackBoundingHelper._Min, maximum: TransformFeedbackBoundingHelper._Max });\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public registerMeshListAsync(meshes: AbstractMesh | AbstractMesh[]): Promise<void> {\r\n        if (!Array.isArray(meshes)) {\r\n            meshes = [meshes];\r\n        }\r\n\r\n        this._meshList = meshes;\r\n        this._meshListCounter = 0;\r\n\r\n        return Promise.resolve();\r\n    }\r\n\r\n    /** @internal */\r\n    public processMeshList(): void {\r\n        if (this._meshList.length === 0) {\r\n            return;\r\n        }\r\n\r\n        this._processMeshList(this._meshList);\r\n        this._meshListCounter++;\r\n    }\r\n\r\n    /** @internal */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public fetchResultsForMeshListAsync(): Promise<void> {\r\n        this._meshListCounter = 0;\r\n\r\n        return Promise.resolve();\r\n    }\r\n\r\n    /** @internal */\r\n    public dispose(): void {\r\n        for (const key in this._buffers) {\r\n            this._buffers[key].dispose();\r\n        }\r\n        this._buffers = {};\r\n        this._effects = {};\r\n        this._engine = null;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"gpuTransformVertexShader\";\nconst shader = `attribute vec3 position;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\nout vec3 outPosition;const mat4 identity=mat4(\nvec4(1.0,0.0,0.0,0.0),\nvec4(0.0,1.0,0.0,0.0),\nvec4(0.0,0.0,1.0,0.0),\nvec4(0.0,0.0,0.0,1.0)\n);void main(void) {vec3 positionUpdated=position;\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\nmat4 finalWorld=identity;\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);outPosition=worldPos.xyz;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, bonesVertex, bakedVertexAnimation];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gpuTransformVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuTransformPixelShader\";\nconst shader = `#version 300 es\nvoid main() {discard;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const gpuTransformPixelShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IBoundingInfoHelperPlatform } from \"./IBoundingInfoHelperPlatform\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { ComputeShader } from \"core/Compute/computeShader.pure\";\r\nimport { StorageBuffer } from \"core/Buffers/storageBuffer\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { type DataBuffer } from \"core/Buffers/dataBuffer\";\r\nimport { type ComputeBindingMapping } from \"core/Engines/Extensions/engine.computeShader.pure\";\r\n\r\nimport { _RetryWithInterval } from \"core/Misc/timingTools\";\r\n\r\n/** @internal */\r\nexport class ComputeShaderBoundingHelper implements IBoundingInfoHelperPlatform {\r\n    private _engine: AbstractEngine;\r\n    private _computeShadersCache: { [key: string]: ComputeShader } = {};\r\n    private _positionBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _indexBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _weightBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _indexExtraBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _weightExtraBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _morphTargetInfluenceBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _morphTargetTextureIndexBuffers: { [key: number]: StorageBuffer } = {};\r\n    private _ubos: UniformBuffer[] = [];\r\n    private _uboIndex: number = 0;\r\n    private _processedMeshes: AbstractMesh[] = [];\r\n    private _computeShaders: ComputeShader[][] = [];\r\n    private _uniqueComputeShaders: Set<ComputeShader> = new Set();\r\n    private _resultBuffers: StorageBuffer[] = [];\r\n\r\n    /**\r\n     * Creates a new ComputeShaderBoundingHelper\r\n     * @param engine defines the engine to use\r\n     */\r\n    constructor(engine: AbstractEngine) {\r\n        this._engine = engine;\r\n    }\r\n\r\n    private _getComputeShader(defines: string[], hasBones: boolean, hasMorphs: boolean) {\r\n        let computeShader: ComputeShader;\r\n        const join = defines.join(\"\\n\");\r\n\r\n        if (!this._computeShadersCache[join]) {\r\n            const bindingsMapping: ComputeBindingMapping = {\r\n                positionBuffer: { group: 0, binding: 0 },\r\n                resultBuffer: { group: 0, binding: 1 },\r\n                settings: { group: 0, binding: 7 },\r\n            };\r\n\r\n            if (hasBones) {\r\n                bindingsMapping.boneSampler = { group: 0, binding: 2 };\r\n                bindingsMapping.indexBuffer = { group: 0, binding: 3 };\r\n                bindingsMapping.weightBuffer = { group: 0, binding: 4 };\r\n                bindingsMapping.indexExtraBuffer = { group: 0, binding: 5 };\r\n                bindingsMapping.weightExtraBuffer = { group: 0, binding: 6 };\r\n            }\r\n            if (hasMorphs) {\r\n                bindingsMapping.morphTargets = { group: 0, binding: 8 };\r\n                bindingsMapping.morphTargetInfluences = { group: 0, binding: 9 };\r\n                bindingsMapping.morphTargetTextureIndices = { group: 0, binding: 10 };\r\n            }\r\n\r\n            computeShader = new ComputeShader(`boundingInfoCompute${hasBones ? \"_bones\" : \"\"}${hasMorphs ? \"_morphs\" : \"\"}`, this._engine, \"boundingInfo\", {\r\n                bindingsMapping,\r\n                defines: defines,\r\n            });\r\n            this._computeShadersCache[join] = computeShader;\r\n        } else {\r\n            computeShader = this._computeShadersCache[join];\r\n        }\r\n\r\n        return computeShader;\r\n    }\r\n\r\n    private _getUBO() {\r\n        if (this._uboIndex >= this._ubos.length) {\r\n            const ubo = new UniformBuffer(this._engine);\r\n            ubo.addFloat2(\"boneTextureInfo\", 0, 0);\r\n            ubo.addFloat3(\"morphTargetTextureInfo\", 0, 0, 0);\r\n            ubo.addUniform(\"morphTargetCount\", 1);\r\n            ubo.addUniform(\"indexResult\", 1);\r\n            this._ubos.push(ubo);\r\n        }\r\n\r\n        return this._ubos[this._uboIndex++];\r\n    }\r\n\r\n    private _extractDataAndLink(computeShader: ComputeShader, mesh: Mesh, kind: string, stride: number, name: string, storageUnit: { [key: number]: StorageBuffer }) {\r\n        let buffer: StorageBuffer;\r\n        const vertexCount = mesh.getTotalVertices();\r\n        if (!storageUnit[mesh.uniqueId]) {\r\n            const dataArray = mesh.getVertexBuffer(kind)?.getFloatData(vertexCount);\r\n            buffer = new StorageBuffer(this._engine as WebGPUEngine, Float32Array.BYTES_PER_ELEMENT * vertexCount * stride);\r\n            buffer.update(dataArray!);\r\n\r\n            storageUnit[mesh.uniqueId] = buffer;\r\n        } else {\r\n            buffer = storageUnit[mesh.uniqueId];\r\n        }\r\n\r\n        computeShader.setStorageBuffer(name, buffer);\r\n    }\r\n\r\n    private _prepareStorage(computeShader: ComputeShader, name: string, id: number, storageUnit: { [key: number]: StorageBuffer }, numInfluencers: number, data: Float32Array) {\r\n        let buffer: StorageBuffer;\r\n        if (!storageUnit[id]) {\r\n            buffer = new StorageBuffer(this._engine as WebGPUEngine, Float32Array.BYTES_PER_ELEMENT * numInfluencers);\r\n\r\n            storageUnit[id] = buffer;\r\n        } else {\r\n            buffer = storageUnit[id];\r\n        }\r\n        buffer.update(data);\r\n\r\n        computeShader.setStorageBuffer(name, buffer);\r\n    }\r\n\r\n    /** @internal */\r\n    public async processAsync(meshes: AbstractMesh | AbstractMesh[]): Promise<void> {\r\n        await this.registerMeshListAsync(meshes);\r\n        this.processMeshList();\r\n        await this.fetchResultsForMeshListAsync();\r\n    }\r\n\r\n    /** @internal */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public registerMeshListAsync(meshes: AbstractMesh | AbstractMesh[]): Promise<void> {\r\n        this._disposeForMeshList();\r\n\r\n        if (!Array.isArray(meshes)) {\r\n            meshes = [meshes];\r\n        }\r\n\r\n        let maxNumInfluencers = 0;\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const mesh = meshes[i];\r\n            const vertexCount = mesh.getTotalVertices();\r\n\r\n            if (vertexCount === 0 || !(mesh as Mesh).getVertexBuffer || !(mesh as Mesh).getVertexBuffer(VertexBuffer.PositionKind)) {\r\n                continue;\r\n            }\r\n\r\n            this._processedMeshes.push(mesh);\r\n\r\n            const manager = (<Mesh>mesh).morphTargetManager;\r\n            if (manager && manager.supportsPositions) {\r\n                maxNumInfluencers = Math.max(maxNumInfluencers, manager.numTargets);\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < this._processedMeshes.length; i++) {\r\n            const mesh = this._processedMeshes[i];\r\n            let defines = [\"\"];\r\n\r\n            let hasBones = false;\r\n            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n                defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n                hasBones = true;\r\n            }\r\n\r\n            const computeShaderWithoutMorph = this._getComputeShader(defines, hasBones, false);\r\n\r\n            this._uniqueComputeShaders.add(computeShaderWithoutMorph);\r\n\r\n            const manager = (<Mesh>mesh).morphTargetManager;\r\n            if (manager && manager.supportsPositions) {\r\n                defines = defines.slice();\r\n                defines.push(\"#define MORPHTARGETS\");\r\n                defines.push(\"#define NUM_MORPH_INFLUENCERS \" + maxNumInfluencers);\r\n\r\n                const computeShaderWithMorph = this._getComputeShader(defines, hasBones, true);\r\n\r\n                this._uniqueComputeShaders.add(computeShaderWithMorph);\r\n                this._computeShaders.push([computeShaderWithoutMorph, computeShaderWithMorph]);\r\n            } else {\r\n                this._computeShaders.push([computeShaderWithoutMorph, computeShaderWithoutMorph]);\r\n            }\r\n\r\n            // Pre-build the ubos, as they won't change if there's no morph targets\r\n            const ubo = this._getUBO();\r\n            ubo.updateUInt(\"indexResult\", i);\r\n\r\n            ubo.update();\r\n        }\r\n\r\n        return new Promise((resolve) => {\r\n            _RetryWithInterval(() => {\r\n                const iterator = this._uniqueComputeShaders.keys();\r\n                for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                    const computeShader = key.value;\r\n                    if (!computeShader.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n                return true;\r\n            }, resolve);\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public processMeshList(): void {\r\n        if (this._processedMeshes.length === 0) {\r\n            return;\r\n        }\r\n\r\n        this._uboIndex = 0;\r\n\r\n        const resultDataSize = 8 * this._processedMeshes.length;\r\n        const resultData = new Float32Array(resultDataSize);\r\n\r\n        const resultBuffer = new StorageBuffer(this._engine as WebGPUEngine, Float32Array.BYTES_PER_ELEMENT * resultDataSize);\r\n        this._resultBuffers.push(resultBuffer);\r\n\r\n        for (let i = 0; i < this._processedMeshes.length; i++) {\r\n            resultData[i * 8 + 0] = Number.POSITIVE_INFINITY;\r\n            resultData[i * 8 + 1] = Number.POSITIVE_INFINITY;\r\n            resultData[i * 8 + 2] = Number.POSITIVE_INFINITY;\r\n\r\n            resultData[i * 8 + 3] = Number.NEGATIVE_INFINITY;\r\n            resultData[i * 8 + 4] = Number.NEGATIVE_INFINITY;\r\n            resultData[i * 8 + 5] = Number.NEGATIVE_INFINITY;\r\n        }\r\n\r\n        resultBuffer.update(resultData);\r\n\r\n        for (let i = 0; i < this._processedMeshes.length; i++) {\r\n            const mesh = this._processedMeshes[i];\r\n            const vertexCount = mesh.getTotalVertices();\r\n\r\n            const [computeShaderWithoutMorph, computeShaderWithMorph] = this._computeShaders[i];\r\n\r\n            const manager = (<Mesh>mesh).morphTargetManager;\r\n            const hasMorphs = manager && manager.numInfluencers > 0 && manager.supportsPositions;\r\n            const computeShader = hasMorphs ? computeShaderWithMorph : computeShaderWithoutMorph;\r\n\r\n            this._extractDataAndLink(computeShader, mesh as Mesh, VertexBuffer.PositionKind, 3, \"positionBuffer\", this._positionBuffers);\r\n\r\n            const ubo = this._getUBO();\r\n            let uboNeedsUpdate = false;\r\n\r\n            // Bones\r\n            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton && mesh.skeleton.useTextureToStoreBoneMatrices) {\r\n                this._extractDataAndLink(computeShader, mesh as Mesh, VertexBuffer.MatricesIndicesKind, 4, \"indexBuffer\", this._indexBuffers);\r\n                this._extractDataAndLink(computeShader, mesh as Mesh, VertexBuffer.MatricesWeightsKind, 4, \"weightBuffer\", this._weightBuffers);\r\n                const boneSampler = mesh.skeleton.getTransformMatrixTexture(mesh);\r\n                computeShader.setTexture(\"boneSampler\", boneSampler!, false);\r\n                ubo.updateFloat2(\"boneTextureInfo\", mesh.skeleton._textureWidth, mesh.skeleton._textureHeight);\r\n                uboNeedsUpdate = true;\r\n                if (mesh.numBoneInfluencers > 4) {\r\n                    this._extractDataAndLink(computeShader, mesh as Mesh, VertexBuffer.MatricesIndicesExtraKind, 4, \"indexExtraBuffer\", this._indexExtraBuffers);\r\n                    this._extractDataAndLink(computeShader, mesh as Mesh, VertexBuffer.MatricesWeightsExtraKind, 4, \"weightExtraBuffer\", this._weightExtraBuffers);\r\n                }\r\n            }\r\n\r\n            // Morphs\r\n            if (hasMorphs) {\r\n                const morphTargets = manager._targetStoreTexture;\r\n                computeShader.setTexture(\"morphTargets\", morphTargets!, false);\r\n\r\n                this._prepareStorage(computeShader, \"morphTargetInfluences\", mesh.uniqueId, this._morphTargetInfluenceBuffers, manager.numInfluencers, manager.influences);\r\n                this._prepareStorage(\r\n                    computeShader,\r\n                    \"morphTargetTextureIndices\",\r\n                    mesh.uniqueId,\r\n                    this._morphTargetTextureIndexBuffers,\r\n                    manager.numInfluencers,\r\n                    manager._morphTargetTextureIndices\r\n                );\r\n\r\n                ubo.updateFloat3(\"morphTargetTextureInfo\", manager._textureVertexStride, manager._textureWidth, manager._textureHeight);\r\n                ubo.updateFloat(\"morphTargetCount\", manager.numInfluencers);\r\n                uboNeedsUpdate = true;\r\n            }\r\n\r\n            if (uboNeedsUpdate) {\r\n                ubo.update();\r\n            }\r\n\r\n            computeShader.setStorageBuffer(\"resultBuffer\", resultBuffer);\r\n\r\n            computeShader.setUniformBuffer(\"settings\", ubo);\r\n\r\n            // Dispatch\r\n            computeShader.dispatch(Math.ceil(vertexCount / 256));\r\n\r\n            this._engine.flushFramebuffer();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public async fetchResultsForMeshListAsync(): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            const buffers: DataBuffer[] = [];\r\n            let size = 0;\r\n            for (let i = 0; i < this._resultBuffers.length; i++) {\r\n                const buffer = this._resultBuffers[i].getBuffer();\r\n                buffers.push(buffer);\r\n                size += buffer.capacity;\r\n            }\r\n\r\n            const resultData = new Float32Array(size / Float32Array.BYTES_PER_ELEMENT);\r\n\r\n            const minimum = Vector3.Zero();\r\n            const maximum = Vector3.Zero();\r\n\r\n            const minmax = { minimum, maximum };\r\n\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            (this._engine as WebGPUEngine).readFromMultipleStorageBuffers(buffers, 0, undefined, resultData, true).then(() => {\r\n                let resultDataOffset = 0;\r\n                for (let j = 0; j < this._resultBuffers.length; j++) {\r\n                    for (let i = 0; i < this._processedMeshes.length; i++) {\r\n                        const mesh = this._processedMeshes[i];\r\n\r\n                        Vector3.FromArrayToRef(resultData, resultDataOffset + i * 8, minimum);\r\n                        Vector3.FromArrayToRef(resultData, resultDataOffset + i * 8 + 3, maximum);\r\n\r\n                        if (j > 0) {\r\n                            minimum.minimizeInPlace(mesh.getBoundingInfo().minimum);\r\n                            maximum.maximizeInPlace(mesh.getBoundingInfo().maximum);\r\n                        }\r\n\r\n                        mesh._refreshBoundingInfoDirect(minmax);\r\n                    }\r\n\r\n                    resultDataOffset += 8 * this._processedMeshes.length;\r\n                }\r\n\r\n                for (const resultBuffer of this._resultBuffers) {\r\n                    resultBuffer.dispose();\r\n                }\r\n\r\n                this._resultBuffers = [];\r\n                this._uboIndex = 0;\r\n\r\n                resolve();\r\n            });\r\n        });\r\n    }\r\n\r\n    private _disposeCache(storageUnit: { [key: number]: StorageBuffer }) {\r\n        for (const key in storageUnit) {\r\n            storageUnit[key].dispose();\r\n        }\r\n    }\r\n\r\n    private _disposeForMeshList() {\r\n        for (const resultBuffer of this._resultBuffers) {\r\n            resultBuffer.dispose();\r\n        }\r\n        this._resultBuffers = [];\r\n        this._processedMeshes = [];\r\n        this._computeShaders = [];\r\n        this._uniqueComputeShaders = new Set();\r\n    }\r\n\r\n    /** @internal */\r\n    public dispose(): void {\r\n        this._disposeCache(this._positionBuffers);\r\n        this._positionBuffers = {};\r\n        this._disposeCache(this._indexBuffers);\r\n        this._indexBuffers = {};\r\n        this._disposeCache(this._weightBuffers);\r\n        this._weightBuffers = {};\r\n        this._disposeCache(this._morphTargetInfluenceBuffers);\r\n        this._morphTargetInfluenceBuffers = {};\r\n        this._disposeCache(this._morphTargetTextureIndexBuffers);\r\n        this._morphTargetTextureIndexBuffers = {};\r\n        for (const ubo of this._ubos) {\r\n            ubo.dispose();\r\n        }\r\n        this._ubos = [];\r\n        this._computeShadersCache = {};\r\n        this._engine = undefined!;\r\n        this._disposeForMeshList();\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"boundingInfoComputeShader\";\nconst shader = `struct Results {minX : atomic<i32>,\nminY : atomic<i32>,\nminZ : atomic<i32>,\nmaxX : atomic<i32>,\nmaxY : atomic<i32>,\nmaxZ : atomic<i32>,\ndummy1 : i32,\ndummy2 : i32,};fn floatToBits(value: f32)->i32 {return bitcast<i32>(value);}\nfn bitsToFloat(value: i32)->f32 {return bitcast<f32>(value);}\nfn atomicMinFloat(atomicVar: ptr<storage,atomic<i32>,read_write>,value: f32) {let intValue=floatToBits(value);loop {let oldIntValue=atomicLoad(atomicVar);let oldValue=bitsToFloat(oldIntValue);if (value>=oldValue) {break;}\nif (atomicCompareExchangeWeak(atomicVar,oldIntValue,intValue).old_value==oldIntValue) {break;}}}\nfn atomicMaxFloat(atomicVar: ptr<storage,atomic<i32>,read_write>,value: f32) {let intValue=floatToBits(value);loop {let oldIntValue=atomicLoad(atomicVar);let oldValue=bitsToFloat(oldIntValue);if (value<=oldValue) {break;}\nif (atomicCompareExchangeWeak(atomicVar,oldIntValue,intValue).old_value==oldIntValue) {break;}}}\nfn readMatrixFromRawSampler(smp : texture_2d<f32>,index : f32)->mat4x4<f32>\n{let offset=i32(index)*4; \nlet textureWidth=i32(settings.boneTextureInfo.x);let y=offset/textureWidth;let x=offset % textureWidth;let m0=textureLoad(smp,vec2<i32>(x+0,y),0);let m1=textureLoad(smp,vec2<i32>(x+1,y),0);let m2=textureLoad(smp,vec2<i32>(x+2,y),0);let m3=textureLoad(smp,vec2<i32>(x+3,y),0);return mat4x4<f32>(m0,m1,m2,m3);}\nconst identity=mat4x4f(\nvec4f(1.0,0.0,0.0,0.0),\nvec4f(0.0,1.0,0.0,0.0),\nvec4f(0.0,0.0,1.0,0.0),\nvec4f(0.0,0.0,0.0,1.0)\n);struct Settings {boneTextureInfo: vec2f,\nmorphTargetTextureInfo: vec3f,\nmorphTargetCount: f32,\nindexResult : u32,};@group(0) @binding(0) var<storage,read> positionBuffer : array<f32>;@group(0) @binding(1) var<storage,read_write> resultBuffer : array<Results>;@group(0) @binding(7) var<uniform> settings : Settings;\n#if NUM_BONE_INFLUENCERS>0\n@group(0) @binding(2) var boneSampler : texture_2d<f32>;@group(0) @binding(3) var<storage,read> indexBuffer : array<vec4f>;@group(0) @binding(4) var<storage,read> weightBuffer : array<vec4f>;\n#if NUM_BONE_INFLUENCERS>4\n@group(0) @binding(5) var<storage,read> indexExtraBuffer : array<vec4f>;@group(0) @binding(6) var<storage,read> weightExtraBuffer : array<vec4f>;\n#endif\n#endif\n#ifdef MORPHTARGETS\n@group(0) @binding(8) var morphTargets : texture_2d_array<f32>;@group(0) @binding(9) var<storage,read> morphTargetInfluences : array<f32>;@group(0) @binding(10) var<storage,read> morphTargetTextureIndices : array<f32>;\n#endif\n#ifdef MORPHTARGETS\nfn readVector3FromRawSampler(targetIndex : i32,vertexIndex : u32)->vec3f\n{ \nlet vertexID: u32=vertexIndex*u32(settings.morphTargetTextureInfo.x);let textureWidth: u32=u32(settings.morphTargetTextureInfo.y);let y: u32=vertexID/textureWidth;let x: u32=vertexID % textureWidth;return textureLoad(morphTargets,vec2u(x,y),u32(morphTargetTextureIndices[targetIndex]),0).xyz;}\nfn readVector4FromRawSampler(targetIndex : i32,vertexIndex : u32)->vec4f\n{ \nlet vertexID: u32=vertexIndex*u32(settings.morphTargetTextureInfo.x);let textureWidth: u32=u32(settings.morphTargetTextureInfo.y);let y: u32=vertexID/textureWidth;let x: u32=vertexID % textureWidth;return textureLoad(morphTargets,vec2u(x,y),u32(morphTargetTextureIndices[targetIndex]),0);}\n#endif\n@compute @workgroup_size(256,1,1)\nfn main(@builtin(global_invocation_id) global_id : vec3<u32>) {let index=global_id.x;if (index>=arrayLength(&positionBuffer)/3) {return;}\nlet position=vec3f(positionBuffer[index*3],positionBuffer[index*3+1],positionBuffer[index*3+2]);var finalWorld=identity;var positionUpdated=position;\n#if NUM_BONE_INFLUENCERS>0\nvar influence : mat4x4<f32>;let matricesIndices=indexBuffer[index];let matricesWeights=weightBuffer[index];influence=readMatrixFromRawSampler(boneSampler,matricesIndices[0])*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence=influence+readMatrixFromRawSampler(boneSampler,matricesIndices[1])*matricesWeights[1];\n#endif \n#if NUM_BONE_INFLUENCERS>2\ninfluence=influence+readMatrixFromRawSampler(boneSampler,matricesIndices[2])*matricesWeights[2];\n#endif \n#if NUM_BONE_INFLUENCERS>3\ninfluence=influence+readMatrixFromRawSampler(boneSampler,matricesIndices[3])*matricesWeights[3];\n#endif \n#if NUM_BONE_INFLUENCERS>4\nlet matricesIndicesExtra=indexExtraBuffer[index];let matricesWeightsExtra=weightExtraBuffer[index];influence=influence+readMatrixFromRawSampler(boneSampler,matricesIndicesExtra.x)*matricesWeightsExtra.x;\n#if NUM_BONE_INFLUENCERS>5\ninfluence=influence+readMatrixFromRawSampler(boneSampler,matricesIndicesExtra.y)*matricesWeightsExtra.y;\n#endif \n#if NUM_BONE_INFLUENCERS>6\ninfluence=influence+readMatrixFromRawSampler(boneSampler,matricesIndicesExtra.z)*matricesWeightsExtra.z;\n#endif \n#if NUM_BONE_INFLUENCERS>7\ninfluence=influence+readMatrixFromRawSampler(boneSampler,matricesIndicesExtra.w)*matricesWeightsExtra.w;\n#endif \n#endif \nfinalWorld=finalWorld*influence;\n#endif\n#ifdef MORPHTARGETS\nfor (var i=0; i<NUM_MORPH_INFLUENCERS; i=i+1) {if (f32(i)>=settings.morphTargetCount) {break;}\npositionUpdated=positionUpdated+(readVector3FromRawSampler(i,index)-position)*morphTargetInfluences[i];}\n#endif\nvar worldPos=finalWorld*vec4f(positionUpdated.x,positionUpdated.y,positionUpdated.z,1.0);atomicMinFloat(&resultBuffer[settings.indexResult].minX,worldPos.x);atomicMinFloat(&resultBuffer[settings.indexResult].minY,worldPos.y);atomicMinFloat(&resultBuffer[settings.indexResult].minZ,worldPos.z);atomicMaxFloat(&resultBuffer[settings.indexResult].maxX,worldPos.x);atomicMaxFloat(&resultBuffer[settings.indexResult].maxY,worldPos.y);atomicMaxFloat(&resultBuffer[settings.indexResult].maxZ,worldPos.z);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const boundingInfoComputeShaderWGSL = { name, shader };\n","import { type SmartArrayNoDuplicate } from \"../../Misc/smartArray\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Ray } from \"../../Culling/ray\";\r\nimport { BoundingBox } from \"../../Culling/boundingBox\";\r\nimport { type Plane } from \"../../Maths/math.plane\";\r\n\r\n/**\r\n * Contains an array of blocks representing the octree\r\n */\r\nexport interface IOctreeContainer<T> {\r\n    /**\r\n     * Blocks within the octree\r\n     */\r\n    blocks: Array<OctreeBlock<T>>;\r\n}\r\n\r\n/**\r\n * Class used to store a cell in an octree\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimizeOctrees\r\n */\r\nexport class OctreeBlock<T> {\r\n    /**\r\n     * Gets the content of the current block\r\n     */\r\n    public entries: T[] = [];\r\n\r\n    /**\r\n     * Gets the list of block children\r\n     */\r\n    public blocks: Array<OctreeBlock<T>>;\r\n\r\n    private _depth: number;\r\n    private _maxDepth: number;\r\n    private _capacity: number;\r\n    private _minPoint: Vector3;\r\n    private _maxPoint: Vector3;\r\n    private _boundingVectors = new Array<Vector3>();\r\n    private _creationFunc: (entry: T, block: OctreeBlock<T>) => void;\r\n\r\n    /**\r\n     * Creates a new block\r\n     * @param minPoint defines the minimum vector (in world space) of the block's bounding box\r\n     * @param maxPoint defines the maximum vector (in world space) of the block's bounding box\r\n     * @param capacity defines the maximum capacity of this block (if capacity is reached the block will be split into sub blocks)\r\n     * @param depth defines the current depth of this block in the octree\r\n     * @param maxDepth defines the maximal depth allowed (beyond this value, the capacity is ignored)\r\n     * @param creationFunc defines a callback to call when an element is added to the block\r\n     */\r\n    constructor(minPoint: Vector3, maxPoint: Vector3, capacity: number, depth: number, maxDepth: number, creationFunc: (entry: T, block: OctreeBlock<T>) => void) {\r\n        this._capacity = capacity;\r\n        this._depth = depth;\r\n        this._maxDepth = maxDepth;\r\n        this._creationFunc = creationFunc;\r\n\r\n        this._minPoint = minPoint;\r\n        this._maxPoint = maxPoint;\r\n\r\n        this._boundingVectors.push(minPoint.clone());\r\n        this._boundingVectors.push(maxPoint.clone());\r\n\r\n        this._boundingVectors.push(minPoint.clone());\r\n        this._boundingVectors[2].x = maxPoint.x;\r\n\r\n        this._boundingVectors.push(minPoint.clone());\r\n        this._boundingVectors[3].y = maxPoint.y;\r\n\r\n        this._boundingVectors.push(minPoint.clone());\r\n        this._boundingVectors[4].z = maxPoint.z;\r\n\r\n        this._boundingVectors.push(maxPoint.clone());\r\n        this._boundingVectors[5].z = minPoint.z;\r\n\r\n        this._boundingVectors.push(maxPoint.clone());\r\n        this._boundingVectors[6].x = minPoint.x;\r\n\r\n        this._boundingVectors.push(maxPoint.clone());\r\n        this._boundingVectors[7].y = minPoint.y;\r\n    }\r\n\r\n    // Property\r\n\r\n    /**\r\n     * Gets the maximum capacity of this block (if capacity is reached the block will be split into sub blocks)\r\n     */\r\n    public get capacity(): number {\r\n        return this._capacity;\r\n    }\r\n\r\n    /**\r\n     * Gets the minimum vector (in world space) of the block's bounding box\r\n     */\r\n    public get minPoint(): Vector3 {\r\n        return this._minPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum vector (in world space) of the block's bounding box\r\n     */\r\n    public get maxPoint(): Vector3 {\r\n        return this._maxPoint;\r\n    }\r\n\r\n    // Methods\r\n\r\n    /**\r\n     * Add a new element to this block\r\n     * @param entry defines the element to add\r\n     */\r\n    public addEntry(entry: T): void {\r\n        if (this.blocks) {\r\n            for (let index = 0; index < this.blocks.length; index++) {\r\n                const block = this.blocks[index];\r\n                block.addEntry(entry);\r\n            }\r\n            return;\r\n        }\r\n\r\n        this._creationFunc(entry, this);\r\n\r\n        if (this.entries.length > this.capacity && this._depth < this._maxDepth) {\r\n            this.createInnerBlocks();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove an element from this block\r\n     * @param entry defines the element to remove\r\n     */\r\n    public removeEntry(entry: T): void {\r\n        if (this.blocks) {\r\n            for (let index = 0; index < this.blocks.length; index++) {\r\n                const block = this.blocks[index];\r\n                block.removeEntry(entry);\r\n            }\r\n            return;\r\n        }\r\n\r\n        const entryIndex = this.entries.indexOf(entry);\r\n\r\n        if (entryIndex > -1) {\r\n            this.entries.splice(entryIndex, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add an array of elements to this block\r\n     * @param entries defines the array of elements to add\r\n     */\r\n    public addEntries(entries: T[]): void {\r\n        for (let index = 0; index < entries.length; index++) {\r\n            const mesh = entries[index];\r\n            this.addEntry(mesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Test if the current block intersects the frustum planes and if yes, then add its content to the selection array\r\n     * @param frustumPlanes defines the frustum planes to test\r\n     * @param selection defines the array to store current content if selection is positive\r\n     * @param allowDuplicate defines if the selection array can contains duplicated entries\r\n     */\r\n    public select(frustumPlanes: Plane[], selection: SmartArrayNoDuplicate<T>, allowDuplicate?: boolean): void {\r\n        if (BoundingBox.IsInFrustum(this._boundingVectors, frustumPlanes)) {\r\n            if (this.blocks) {\r\n                for (let index = 0; index < this.blocks.length; index++) {\r\n                    const block = this.blocks[index];\r\n                    block.select(frustumPlanes, selection, allowDuplicate);\r\n                }\r\n                return;\r\n            }\r\n\r\n            if (allowDuplicate) {\r\n                selection.concat(this.entries);\r\n            } else {\r\n                selection.concatWithNoDuplicate(this.entries);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Test if the current block intersect with the given bounding sphere and if yes, then add its content to the selection array\r\n     * @param sphereCenter defines the bounding sphere center\r\n     * @param sphereRadius defines the bounding sphere radius\r\n     * @param selection defines the array to store current content if selection is positive\r\n     * @param allowDuplicate defines if the selection array can contains duplicated entries\r\n     */\r\n    public intersects(sphereCenter: Vector3, sphereRadius: number, selection: SmartArrayNoDuplicate<T>, allowDuplicate?: boolean): void {\r\n        if (BoundingBox.IntersectsSphere(this._minPoint, this._maxPoint, sphereCenter, sphereRadius)) {\r\n            if (this.blocks) {\r\n                for (let index = 0; index < this.blocks.length; index++) {\r\n                    const block = this.blocks[index];\r\n                    block.intersects(sphereCenter, sphereRadius, selection, allowDuplicate);\r\n                }\r\n                return;\r\n            }\r\n\r\n            if (allowDuplicate) {\r\n                selection.concat(this.entries);\r\n            } else {\r\n                selection.concatWithNoDuplicate(this.entries);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Test if the current block intersect with the given ray and if yes, then add its content to the selection array\r\n     * @param ray defines the ray to test with\r\n     * @param selection defines the array to store current content if selection is positive\r\n     */\r\n    public intersectsRay(ray: Ray, selection: SmartArrayNoDuplicate<T>): void {\r\n        if (ray.intersectsBoxMinMax(this._minPoint, this._maxPoint)) {\r\n            if (this.blocks) {\r\n                for (let index = 0; index < this.blocks.length; index++) {\r\n                    const block = this.blocks[index];\r\n                    block.intersectsRay(ray, selection);\r\n                }\r\n                return;\r\n            }\r\n            selection.concatWithNoDuplicate(this.entries);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Subdivide the content into child blocks (this block will then be empty)\r\n     */\r\n    public createInnerBlocks(): void {\r\n        OctreeBlock._CreateBlocks(this._minPoint, this._maxPoint, this.entries, this._capacity, this._depth, this._maxDepth, this, this._creationFunc);\r\n        this.entries.splice(0);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _CreateBlocks<T>(\r\n        worldMin: Vector3,\r\n        worldMax: Vector3,\r\n        entries: T[],\r\n        maxBlockCapacity: number,\r\n        currentDepth: number,\r\n        maxDepth: number,\r\n        target: IOctreeContainer<T>,\r\n        creationFunc: (entry: T, block: OctreeBlock<T>) => void\r\n    ): void {\r\n        target.blocks = new Array<OctreeBlock<T>>();\r\n        const blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);\r\n\r\n        // Segmenting space\r\n        for (let x = 0; x < 2; x++) {\r\n            for (let y = 0; y < 2; y++) {\r\n                for (let z = 0; z < 2; z++) {\r\n                    const localMin = worldMin.add(blockSize.multiplyByFloats(x, y, z));\r\n                    const localMax = worldMin.add(blockSize.multiplyByFloats(x + 1, y + 1, z + 1));\r\n\r\n                    const block = new OctreeBlock<T>(localMin, localMax, maxBlockCapacity, currentDepth + 1, maxDepth, creationFunc);\r\n                    block.addEntries(entries);\r\n                    target.blocks.push(block);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type SmartArray, SmartArrayNoDuplicate } from \"../../Misc/smartArray\";\r\nimport { type Vector3 } from \"../../Maths/math.vector\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Ray } from \"../../Culling/ray\";\r\nimport { OctreeBlock } from \"./octreeBlock\";\r\nimport { type Plane } from \"../../Maths/math.plane\";\r\n\r\n/**\r\n * Octrees are a really powerful data structure that can quickly select entities based on space coordinates.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimizeOctrees\r\n */\r\nexport class Octree<T> {\r\n    /**\r\n     * Blocks within the octree containing objects\r\n     */\r\n    public blocks: Array<OctreeBlock<T>>;\r\n    /**\r\n     * Content stored in the octree\r\n     */\r\n    public dynamicContent: T[] = [];\r\n\r\n    private _maxBlockCapacity: number;\r\n    private _selectionContent: SmartArrayNoDuplicate<T>;\r\n    private _creationFunc: (entry: T, block: OctreeBlock<T>) => void;\r\n\r\n    /**\r\n     * Creates a octree\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimizeOctrees\r\n     * @param creationFunc function to be used to instantiate the octree\r\n     * @param maxBlockCapacity defines the maximum number of meshes you want on your octree's leaves (default: 64)\r\n     * @param maxDepth defines the maximum depth (sub-levels) for your octree. Default value is 2, which means 8 8 8 = 512 blocks :) (This parameter takes precedence over capacity.)\r\n     */\r\n    constructor(\r\n        creationFunc: (entry: T, block: OctreeBlock<T>) => void,\r\n        maxBlockCapacity?: number,\r\n        /** [2] Defines the maximum depth (sub-levels) for your octree. Default value is 2, which means 8 8 8 = 512 blocks :) (This parameter takes precedence over capacity.) */\r\n        public maxDepth = 2\r\n    ) {\r\n        this._maxBlockCapacity = maxBlockCapacity || 64;\r\n        this._selectionContent = new SmartArrayNoDuplicate<T>(1024);\r\n        this._creationFunc = creationFunc;\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Updates the octree by adding blocks for the passed in meshes within the min and max world parameters\r\n     * @param worldMin worldMin for the octree blocks var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);\r\n     * @param worldMax worldMax for the octree blocks var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);\r\n     * @param entries meshes to be added to the octree blocks\r\n     */\r\n    public update(worldMin: Vector3, worldMax: Vector3, entries: T[]): void {\r\n        OctreeBlock._CreateBlocks(worldMin, worldMax, entries, this._maxBlockCapacity, 0, this.maxDepth, this, this._creationFunc);\r\n    }\r\n\r\n    /**\r\n     * Adds a mesh to the octree\r\n     * @param entry Mesh to add to the octree\r\n     */\r\n    public addMesh(entry: T): void {\r\n        for (let index = 0; index < this.blocks.length; index++) {\r\n            const block = this.blocks[index];\r\n            block.addEntry(entry);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove an element from the octree\r\n     * @param entry defines the element to remove\r\n     */\r\n    public removeMesh(entry: T): void {\r\n        for (let index = 0; index < this.blocks.length; index++) {\r\n            const block = this.blocks[index];\r\n            block.removeEntry(entry);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Selects an array of meshes within the frustum\r\n     * @param frustumPlanes The frustum planes to use which will select all meshes within it\r\n     * @param allowDuplicate If duplicate objects are allowed in the resulting object array\r\n     * @returns array of meshes within the frustum\r\n     */\r\n    public select(frustumPlanes: Plane[], allowDuplicate?: boolean): SmartArray<T> {\r\n        this._selectionContent.reset();\r\n\r\n        for (let index = 0; index < this.blocks.length; index++) {\r\n            const block = this.blocks[index];\r\n            block.select(frustumPlanes, this._selectionContent, allowDuplicate);\r\n        }\r\n\r\n        if (allowDuplicate) {\r\n            this._selectionContent.concat(this.dynamicContent);\r\n        } else {\r\n            this._selectionContent.concatWithNoDuplicate(this.dynamicContent);\r\n        }\r\n\r\n        return this._selectionContent;\r\n    }\r\n\r\n    /**\r\n     * Test if the octree intersect with the given bounding sphere and if yes, then add its content to the selection array\r\n     * @param sphereCenter defines the bounding sphere center\r\n     * @param sphereRadius defines the bounding sphere radius\r\n     * @param allowDuplicate defines if the selection array can contains duplicated entries\r\n     * @returns an array of objects that intersect the sphere\r\n     */\r\n    public intersects(sphereCenter: Vector3, sphereRadius: number, allowDuplicate?: boolean): SmartArray<T> {\r\n        this._selectionContent.reset();\r\n\r\n        for (let index = 0; index < this.blocks.length; index++) {\r\n            const block = this.blocks[index];\r\n            block.intersects(sphereCenter, sphereRadius, this._selectionContent, allowDuplicate);\r\n        }\r\n\r\n        if (allowDuplicate) {\r\n            this._selectionContent.concat(this.dynamicContent);\r\n        } else {\r\n            this._selectionContent.concatWithNoDuplicate(this.dynamicContent);\r\n        }\r\n\r\n        return this._selectionContent;\r\n    }\r\n\r\n    /**\r\n     * Test if the octree intersect with the given ray and if yes, then add its content to resulting array\r\n     * @param ray defines the ray to test with\r\n     * @returns array of intersected objects\r\n     */\r\n    public intersectsRay(ray: Ray): SmartArray<T> {\r\n        this._selectionContent.reset();\r\n\r\n        for (let index = 0; index < this.blocks.length; index++) {\r\n            const block = this.blocks[index];\r\n            block.intersectsRay(ray, this._selectionContent);\r\n        }\r\n\r\n        this._selectionContent.concatWithNoDuplicate(this.dynamicContent);\r\n\r\n        return this._selectionContent;\r\n    }\r\n\r\n    /**\r\n     * Adds a mesh into the octree block if it intersects the block\r\n     * @param entry defines the mesh to try to add to the block\r\n     * @param block defines the block where the mesh should be added\r\n     */\r\n    public static CreationFuncForMeshes = (entry: AbstractMesh, block: OctreeBlock<AbstractMesh>): void => {\r\n        const boundingInfo = entry.getBoundingInfo();\r\n        if (!entry.isBlocked && boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {\r\n            block.entries.push(entry);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Adds a submesh into the octree block if it intersects the block\r\n     * @param entry defines the submesh to try to add to the block\r\n     * @param block defines the block where the submesh should be added\r\n     */\r\n    public static CreationFuncForSubMeshes = (entry: SubMesh, block: OctreeBlock<SubMesh>): void => {\r\n        const boundingInfo = entry.getBoundingInfo();\r\n        if (boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {\r\n            block.entries.push(entry);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ISmartArrayLike } from \"../../Misc/smartArray\";\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { Ray } from \"../../Culling/ray.pure\";\r\nimport { SceneComponentConstants } from \"../../sceneComponent\";\r\n\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { type Collider } from \"../../Collisions/collider\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { Octree } from \"./octree\";\r\n\r\n/**\r\n * Defines the octree scene component responsible to manage any octrees\r\n * in a given scene.\r\n */\r\nexport class OctreeSceneComponent {\r\n    /**\r\n     * The component name help to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_OCTREE;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Indicates if the meshes have been checked to make sure they are isEnabled()\r\n     */\r\n    public readonly checksIsEnabled = true;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene?: Scene) {\r\n        scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        this.scene = scene;\r\n\r\n        this.scene.getActiveMeshCandidates = () => this.getActiveMeshCandidates();\r\n        this.scene.getActiveSubMeshCandidates = (mesh: AbstractMesh) => this.getActiveSubMeshCandidates(mesh);\r\n        this.scene.getCollidingSubMeshCandidates = (mesh: AbstractMesh, collider: Collider) => this.getCollidingSubMeshCandidates(mesh, collider);\r\n        this.scene.getIntersectingSubMeshCandidates = (mesh: AbstractMesh, localRay: Ray) => this.getIntersectingSubMeshCandidates(mesh, localRay);\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene.onMeshRemovedObservable.add((mesh: AbstractMesh) => {\r\n            const sceneOctree = this.scene.selectionOctree;\r\n            if (sceneOctree !== undefined && sceneOctree !== null) {\r\n                const index = sceneOctree.dynamicContent.indexOf(mesh);\r\n\r\n                if (index !== -1) {\r\n                    sceneOctree.dynamicContent.splice(index, 1);\r\n                }\r\n            }\r\n        });\r\n\r\n        this.scene.onMeshImportedObservable.add((mesh: AbstractMesh) => {\r\n            const sceneOctree = this.scene.selectionOctree;\r\n            if (sceneOctree !== undefined && sceneOctree !== null) {\r\n                sceneOctree.addMesh(mesh);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Return the list of active meshes\r\n     * @returns the list of active meshes\r\n     */\r\n    public getActiveMeshCandidates(): ISmartArrayLike<AbstractMesh> {\r\n        return this.scene._selectionOctree?.select(this.scene.frustumPlanes) || this.scene._getDefaultMeshCandidates();\r\n    }\r\n\r\n    /**\r\n     * Return the list of active sub meshes\r\n     * @param mesh The mesh to get the candidates sub meshes from\r\n     * @returns the list of active sub meshes\r\n     */\r\n    public getActiveSubMeshCandidates(mesh: AbstractMesh): ISmartArrayLike<SubMesh> {\r\n        if (mesh._submeshesOctree && mesh.useOctreeForRenderingSelection) {\r\n            const intersections = mesh._submeshesOctree.select(this.scene.frustumPlanes);\r\n            return intersections;\r\n        }\r\n        return this.scene._getDefaultSubMeshCandidates(mesh);\r\n    }\r\n\r\n    private _tempRay = new Ray(Vector3.Zero(), new Vector3(1, 1, 1));\r\n    /**\r\n     * Return the list of sub meshes intersecting with a given local ray\r\n     * @param mesh defines the mesh to find the submesh for\r\n     * @param localRay defines the ray in local space\r\n     * @returns the list of intersecting sub meshes\r\n     */\r\n    public getIntersectingSubMeshCandidates(mesh: AbstractMesh, localRay: Ray): ISmartArrayLike<SubMesh> {\r\n        if (mesh._submeshesOctree && mesh.useOctreeForPicking) {\r\n            Ray.TransformToRef(localRay, mesh.getWorldMatrix(), this._tempRay);\r\n            const intersections = mesh._submeshesOctree.intersectsRay(this._tempRay);\r\n\r\n            return intersections;\r\n        }\r\n        return this.scene._getDefaultSubMeshCandidates(mesh);\r\n    }\r\n\r\n    /**\r\n     * Return the list of sub meshes colliding with a collider\r\n     * @param mesh defines the mesh to find the submesh for\r\n     * @param collider defines the collider to evaluate the collision against\r\n     * @returns the list of colliding sub meshes\r\n     */\r\n    public getCollidingSubMeshCandidates(mesh: AbstractMesh, collider: Collider): ISmartArrayLike<SubMesh> {\r\n        if (mesh._submeshesOctree && mesh.useOctreeForCollisions) {\r\n            const radius = collider._velocityWorldLength + Math.max(collider._radius.x, collider._radius.y, collider._radius.z);\r\n            const intersections = mesh._submeshesOctree.intersects(collider._basePointWorld, radius);\r\n\r\n            return intersections;\r\n        }\r\n        return this.scene._getDefaultSubMeshCandidates(mesh);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do here.\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        // Nothing to do here.\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for octreeSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterOctreeSceneComponent(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.createOrUpdateSelectionOctree = function (maxCapacity = 64, maxDepth = 2): Octree<AbstractMesh> {\r\n        let component = this._getComponent(SceneComponentConstants.NAME_OCTREE);\r\n        if (!component) {\r\n            component = new OctreeSceneComponent(this);\r\n            this._addComponent(component);\r\n        }\r\n\r\n        if (!this._selectionOctree) {\r\n            this._selectionOctree = new Octree<AbstractMesh>(Octree.CreationFuncForMeshes, maxCapacity, maxDepth);\r\n        }\r\n\r\n        const worldExtends = this.getWorldExtends();\r\n\r\n        // Update octree\r\n        this._selectionOctree.update(worldExtends.min, worldExtends.max, this.meshes);\r\n\r\n        return this._selectionOctree;\r\n    };\r\n\r\n    Object.defineProperty(Scene.prototype, \"selectionOctree\", {\r\n        get: function (this: Scene) {\r\n            return this._selectionOctree;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    /**\r\n     * This function will create an octree to help to select the right submeshes for rendering, picking and collision computations.\r\n     * Please note that you must have a decent number of submeshes to get performance improvements when using an octree\r\n     * @param maxCapacity defines the maximum size of each block (64 by default)\r\n     * @param maxDepth defines the maximum depth to use (no more than 2 levels by default)\r\n     * @returns the new octree\r\n     * @see https://www.babylonjs-playground.com/#NA4OQ#12\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimizeOctrees\r\n     */\r\n    AbstractMesh.prototype.createOrUpdateSubmeshesOctree = function (maxCapacity = 64, maxDepth = 2): Octree<SubMesh> {\r\n        const scene = this.getScene();\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_OCTREE);\r\n        if (!component) {\r\n            component = new OctreeSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n\r\n        if (!this._submeshesOctree) {\r\n            this._submeshesOctree = new Octree<SubMesh>(Octree.CreationFuncForSubMeshes, maxCapacity, maxDepth);\r\n        }\r\n\r\n        this.computeWorldMatrix(true);\r\n\r\n        const boundingInfo = this.getBoundingInfo();\r\n\r\n        // Update octree\r\n        const bbox = boundingInfo.boundingBox;\r\n        this._submeshesOctree.update(bbox.minimumWorld, bbox.maximumWorld, this.subMeshes);\r\n\r\n        return this._submeshesOctree;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serializeAsColor3, serializeAsVector3 } from \"../Misc/decorators\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Light } from \"./light\";\r\nimport { type IShadowGenerator } from \"./Shadows/shadowGenerator\";\r\nimport { Node } from \"../node\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The HemisphericLight simulates the ambient environment light,\r\n * so the passed direction is the light reflection direction, not the incoming direction.\r\n */\r\nexport class HemisphericLight extends Light {\r\n    /**\r\n     * The groundColor is the light in the opposite direction to the one specified during creation.\r\n     * You can think of the diffuse and specular light as coming from the centre of the object in the given direction and the groundColor light in the opposite direction.\r\n     */\r\n    @serializeAsColor3()\r\n    public groundColor = new Color3(0.0, 0.0, 0.0);\r\n\r\n    /**\r\n     * The light reflection direction, not the incoming direction.\r\n     */\r\n    @serializeAsVector3()\r\n    public direction: Vector3;\r\n\r\n    /**\r\n     * Creates a HemisphericLight object in the scene according to the passed direction (Vector3).\r\n     * The HemisphericLight simulates the ambient environment light, so the passed direction is the light reflection direction, not the incoming direction.\r\n     * The HemisphericLight can't cast shadows.\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     * @param name The friendly name of the light\r\n     * @param direction The direction of the light reflection\r\n     * @param scene The scene the light belongs to\r\n     * @param dontAddToScene True to not add the light to the scene\r\n     */\r\n    constructor(name: string, direction: Vector3, scene?: Scene, dontAddToScene?: boolean) {\r\n        super(name, scene, dontAddToScene);\r\n        this.direction = direction || Vector3.Up();\r\n    }\r\n\r\n    protected _buildUniformLayout(): void {\r\n        this._uniformBuffer.addUniform(\"vLightData\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightGround\", 3);\r\n        this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\r\n        this._uniformBuffer.addUniform(\"depthValues\", 2);\r\n        this._uniformBuffer.create();\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"HemisphericLight\".\r\n     * @returns The class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"HemisphericLight\";\r\n    }\r\n\r\n    /**\r\n     * Sets the HemisphericLight direction towards the passed target (Vector3).\r\n     * Returns the updated direction.\r\n     * @param target The target the direction should point to\r\n     * @returns The computed direction\r\n     */\r\n    public setDirectionToTarget(target: Vector3): Vector3 {\r\n        this.direction = Vector3.Normalize(target.subtract(Vector3.Zero()));\r\n        return this.direction;\r\n    }\r\n\r\n    /**\r\n     * Returns the shadow generator associated to the light.\r\n     * @returns Always null for hemispheric lights because it does not support shadows.\r\n     */\r\n    public override getShadowGenerator(): Nullable<IShadowGenerator> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the passed Effect object with the HemisphericLight normalized direction and color and the passed name (string).\r\n     * @param _effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The hemispheric light\r\n     */\r\n    public transferToEffect(_effect: Effect, lightIndex: string): HemisphericLight {\r\n        const normalizeDirection = Vector3.Normalize(this.direction);\r\n        this._uniformBuffer.updateFloat4(\"vLightData\", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, 0.0, lightIndex);\r\n        this._uniformBuffer.updateColor3(\"vLightGround\", this.groundColor.scale(this.intensity), lightIndex);\r\n        return this;\r\n    }\r\n\r\n    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {\r\n        const normalizeDirection = Vector3.Normalize(this.direction);\r\n        effect.setFloat3(lightDataUniformName, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Computes the world matrix of the node\r\n     * @returns the world matrix\r\n     */\r\n    public override computeWorldMatrix(): Matrix {\r\n        if (!this._worldMatrix) {\r\n            this._worldMatrix = Matrix.Identity();\r\n        }\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    /**\r\n     * Returns the integer 3.\r\n     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public override getTypeID(): number {\r\n        return Light.LIGHTTYPEID_HEMISPHERICLIGHT;\r\n    }\r\n\r\n    /**\r\n     * Prepares the list of defines specific to the light type.\r\n     * @param defines the list of defines\r\n     * @param lightIndex defines the index of the light for the effect\r\n     */\r\n    public prepareLightSpecificDefines(defines: any, lightIndex: number): void {\r\n        defines[\"HEMILIGHT\" + lightIndex] = true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for hemisphericLight.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterHemisphericLight(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"Light_Type_3\", (name, scene) => {\r\n        return () => new HemisphericLight(name, Vector3.Zero(), scene);\r\n    });\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.HemisphericLight\", HemisphericLight);\r\n}\r\n","import { type IDisposable, Scene } from \"../scene.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type PointerInfoPre, PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { HemisphericLight } from \"../Lights/hemisphericLight.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type IPointerEvent } from \"../Events/deviceInputEvents\";\r\n\r\n/**\r\n * Renders a layer on top of an existing scene\r\n */\r\nexport class UtilityLayerRenderer implements IDisposable {\r\n    private _pointerCaptures: { [pointerId: number]: boolean } = {};\r\n    private _lastPointerEvents: { [pointerId: number]: boolean } = {};\r\n    /** @internal */\r\n    public static _DefaultUtilityLayer: Nullable<UtilityLayerRenderer> = null;\r\n    /** @internal */\r\n    public static _DefaultKeepDepthUtilityLayer: Nullable<UtilityLayerRenderer> = null;\r\n    private _sharedGizmoLight: Nullable<HemisphericLight> = null;\r\n\r\n    private _renderCamera: Nullable<Camera> = null;\r\n\r\n    /**\r\n     * Gets the camera that is used to render the utility layer (when not set, this will be the last active camera)\r\n     * @param getRigParentIfPossible if the current active camera is a rig camera, should its parent camera be returned\r\n     * @returns the camera that is used when rendering the utility layer\r\n     */\r\n    public getRenderCamera(getRigParentIfPossible?: boolean) {\r\n        if (this._renderCamera) {\r\n            return this._renderCamera;\r\n        } else {\r\n            let activeCam: Camera;\r\n            if (this.originalScene.activeCameras && this.originalScene.activeCameras.length > 1) {\r\n                activeCam = this.originalScene.activeCameras[this.originalScene.activeCameras.length - 1];\r\n            } else {\r\n                activeCam = this.originalScene.activeCamera!;\r\n            }\r\n\r\n            if (getRigParentIfPossible && activeCam && activeCam.isRigCamera) {\r\n                return activeCam.rigParent!;\r\n            }\r\n            return activeCam;\r\n        }\r\n    }\r\n    /**\r\n     * Sets the camera that should be used when rendering the utility layer (If set to null the last active camera will be used)\r\n     * @param cam the camera that should be used when rendering the utility layer\r\n     */\r\n    public setRenderCamera(cam: Nullable<Camera>) {\r\n        this._renderCamera = cam;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Light which used by gizmos to get light shading\r\n     */\r\n    public _getSharedGizmoLight(): HemisphericLight {\r\n        if (!this._sharedGizmoLight) {\r\n            this._sharedGizmoLight = new HemisphericLight(\"shared gizmo light\", new Vector3(0, 1, 0), this.utilityLayerScene);\r\n            this._sharedGizmoLight.intensity = 2;\r\n            this._sharedGizmoLight.groundColor = Color3.Gray();\r\n        }\r\n        return this._sharedGizmoLight;\r\n    }\r\n\r\n    /**\r\n     * If the picking should be done on the utility layer prior to the actual scene (Default: true)\r\n     */\r\n    public pickUtilitySceneFirst = true;\r\n    /**\r\n     * A shared utility layer that can be used to overlay objects into a scene (Depth map of the previous scene is cleared before drawing on top of it)\r\n     */\r\n    public static get DefaultUtilityLayer(): UtilityLayerRenderer {\r\n        if (UtilityLayerRenderer._DefaultUtilityLayer == null) {\r\n            return UtilityLayerRenderer._CreateDefaultUtilityLayerFromScene(EngineStore.LastCreatedScene!);\r\n        }\r\n\r\n        return UtilityLayerRenderer._DefaultUtilityLayer;\r\n    }\r\n\r\n    /**\r\n     * Creates an utility layer, and set it as a default utility layer\r\n     * @param scene associated scene\r\n     * @internal\r\n     */\r\n    public static _CreateDefaultUtilityLayerFromScene(scene: Scene): UtilityLayerRenderer {\r\n        UtilityLayerRenderer._DefaultUtilityLayer = new UtilityLayerRenderer(scene);\r\n        UtilityLayerRenderer._DefaultUtilityLayer.originalScene.onDisposeObservable.addOnce(() => {\r\n            UtilityLayerRenderer._DefaultUtilityLayer = null;\r\n        });\r\n\r\n        return UtilityLayerRenderer._DefaultUtilityLayer;\r\n    }\r\n    /**\r\n     * A shared utility layer that can be used to embed objects into a scene (Depth map of the previous scene is not cleared before drawing on top of it)\r\n     */\r\n    public static get DefaultKeepDepthUtilityLayer(): UtilityLayerRenderer {\r\n        if (UtilityLayerRenderer._DefaultKeepDepthUtilityLayer == null) {\r\n            return UtilityLayerRenderer._CreateDefaultKeepUtilityLayerFromScene(EngineStore.LastCreatedScene!);\r\n        }\r\n        return UtilityLayerRenderer._DefaultKeepDepthUtilityLayer;\r\n    }\r\n\r\n    /**\r\n     * Creates an utility layer, and set it as a default utility layer (Depth map of the previous scene is not cleared before drawing on top of it)\r\n     * @param scene associated scene\r\n     * @internal\r\n     */\r\n    public static _CreateDefaultKeepUtilityLayerFromScene(scene: Scene): UtilityLayerRenderer {\r\n        UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = new UtilityLayerRenderer(scene);\r\n        UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;\r\n        UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.originalScene.onDisposeObservable.addOnce(() => {\r\n            UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = null;\r\n        });\r\n\r\n        return UtilityLayerRenderer._DefaultKeepDepthUtilityLayer;\r\n    }\r\n\r\n    /**\r\n     * The scene that is rendered on top of the original scene\r\n     */\r\n    public utilityLayerScene: Scene;\r\n\r\n    /**\r\n     *  If the utility layer should automatically be rendered on top of existing scene\r\n     */\r\n    public shouldRender: boolean = true;\r\n    /**\r\n     * If set to true, only pointer down onPointerObservable events will be blocked when picking is occluded by original scene\r\n     */\r\n    public onlyCheckPointerDownEvents = true;\r\n\r\n    /**\r\n     * If set to false, only pointerUp, pointerDown and pointerMove will be sent to the utilityLayerScene (false by default)\r\n     */\r\n    public processAllEvents = false;\r\n\r\n    /**\r\n     * Set to false to disable picking\r\n     */\r\n    public pickingEnabled = true;\r\n\r\n    /**\r\n     * Observable raised when the pointer moves from the utility layer scene to the main scene\r\n     */\r\n    public onPointerOutObservable = new Observable<number>();\r\n\r\n    /** Gets or sets a predicate that will be used to indicate utility meshes present in the main scene */\r\n    public mainSceneTrackerPredicate: (mesh: Nullable<AbstractMesh>) => boolean;\r\n\r\n    private _afterRenderObserver: Nullable<Observer<Camera>>;\r\n    private _sceneDisposeObserver: Nullable<Observer<Scene>>;\r\n    private _originalPointerObserver: Nullable<Observer<PointerInfoPre>>;\r\n    /**\r\n     * Instantiates a UtilityLayerRenderer\r\n     * @param originalScene the original scene that will be rendered on top of\r\n     * @param handleEvents boolean indicating if the utility layer should handle events\r\n     * @param manualRender boolean indicating if the utility layer should render manually.\r\n     */\r\n    constructor(\r\n        /** the original scene that will be rendered on top of */\r\n        public originalScene: Scene,\r\n        public readonly handleEvents: boolean = true,\r\n        manualRender = false\r\n    ) {\r\n        // Create scene which will be rendered in the foreground and remove it from being referenced by engine to avoid interfering with existing app\r\n        this.utilityLayerScene = new Scene(originalScene.getEngine(), { virtual: true, useFloatingOrigin: originalScene.floatingOriginMode });\r\n        this.utilityLayerScene.useRightHandedSystem = originalScene.useRightHandedSystem;\r\n        this.utilityLayerScene._allowPostProcessClearColor = false;\r\n\r\n        // Deactivate post processes\r\n        this.utilityLayerScene.postProcessesEnabled = false;\r\n\r\n        // Detach controls on utility scene, events will be fired by logic below to handle picking priority\r\n        this.utilityLayerScene.detachControl();\r\n\r\n        if (handleEvents) {\r\n            this._originalPointerObserver = originalScene.onPrePointerObservable.add((prePointerInfo) => {\r\n                if (!this.utilityLayerScene.activeCamera) {\r\n                    return;\r\n                }\r\n                if (!this.pickingEnabled) {\r\n                    return;\r\n                }\r\n\r\n                if (!this.processAllEvents) {\r\n                    if (\r\n                        prePointerInfo.type !== PointerEventTypes.POINTERMOVE &&\r\n                        prePointerInfo.type !== PointerEventTypes.POINTERUP &&\r\n                        prePointerInfo.type !== PointerEventTypes.POINTERDOWN &&\r\n                        prePointerInfo.type !== PointerEventTypes.POINTERDOUBLETAP\r\n                    ) {\r\n                        return;\r\n                    }\r\n                }\r\n                this.utilityLayerScene.pointerX = originalScene.pointerX;\r\n                this.utilityLayerScene.pointerY = originalScene.pointerY;\r\n                const pointerEvent = <IPointerEvent>prePointerInfo.event;\r\n                if (originalScene.isPointerCaptured(pointerEvent.pointerId)) {\r\n                    this._pointerCaptures[pointerEvent.pointerId] = false;\r\n                    return;\r\n                }\r\n\r\n                const getNearPickDataForScene = (scene: Scene) => {\r\n                    let scenePick: Nullable<PickingInfo>;\r\n\r\n                    if (prePointerInfo.nearInteractionPickingInfo) {\r\n                        if (prePointerInfo.nearInteractionPickingInfo.pickedMesh!.getScene() == scene) {\r\n                            scenePick = prePointerInfo.nearInteractionPickingInfo;\r\n                        } else {\r\n                            scenePick = new PickingInfo();\r\n                        }\r\n                    } else if (scene !== this.utilityLayerScene && prePointerInfo.originalPickingInfo) {\r\n                        scenePick = prePointerInfo.originalPickingInfo;\r\n                    } else {\r\n                        let previousActiveCamera: Nullable<Camera> = null;\r\n                        // If a camera is set for rendering with this layer\r\n                        // it will also be used for the ray computation\r\n                        // To preserve back compat and because scene.pick always use activeCamera\r\n                        // it's substituted temporarily and a new scenePick is forced.\r\n                        // otherwise, the ray with previously active camera is always used.\r\n                        // It's set back to previous activeCamera after operation.\r\n                        if (this._renderCamera) {\r\n                            previousActiveCamera = scene._activeCamera;\r\n                            scene._activeCamera = this._renderCamera;\r\n                            prePointerInfo.ray = null;\r\n                        }\r\n                        scenePick = prePointerInfo.ray ? scene.pickWithRay(prePointerInfo.ray) : scene.pick(originalScene.pointerX, originalScene.pointerY);\r\n                        if (previousActiveCamera) {\r\n                            scene._activeCamera = previousActiveCamera;\r\n                        }\r\n                    }\r\n\r\n                    return scenePick;\r\n                };\r\n\r\n                const utilityScenePick = getNearPickDataForScene(this.utilityLayerScene);\r\n\r\n                if (!prePointerInfo.ray && utilityScenePick) {\r\n                    prePointerInfo.ray = utilityScenePick.ray;\r\n                }\r\n\r\n                if (prePointerInfo.originalPickingInfo?.aimTransform && utilityScenePick) {\r\n                    utilityScenePick.aimTransform = prePointerInfo.originalPickingInfo.aimTransform;\r\n                    utilityScenePick.gripTransform = prePointerInfo.originalPickingInfo.gripTransform;\r\n                }\r\n\r\n                // always fire the prepointer observable\r\n                this.utilityLayerScene.onPrePointerObservable.notifyObservers(prePointerInfo);\r\n\r\n                // allow every non pointer down event to flow to the utility layer\r\n                if (this.onlyCheckPointerDownEvents && prePointerInfo.type != PointerEventTypes.POINTERDOWN) {\r\n                    if (!prePointerInfo.skipOnPointerObservable) {\r\n                        this.utilityLayerScene.onPointerObservable.notifyObservers(\r\n                            new PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick),\r\n                            prePointerInfo.type\r\n                        );\r\n                    }\r\n                    if (prePointerInfo.type === PointerEventTypes.POINTERUP && this._pointerCaptures[pointerEvent.pointerId]) {\r\n                        this._pointerCaptures[pointerEvent.pointerId] = false;\r\n                    }\r\n                    return;\r\n                }\r\n\r\n                if (this.utilityLayerScene.autoClearDepthAndStencil || this.pickUtilitySceneFirst) {\r\n                    // If this layer is an overlay, check if this layer was hit and if so, skip pointer events for the main scene\r\n                    if (utilityScenePick && utilityScenePick.hit) {\r\n                        if (!prePointerInfo.skipOnPointerObservable) {\r\n                            this.utilityLayerScene.onPointerObservable.notifyObservers(\r\n                                new PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick),\r\n                                prePointerInfo.type\r\n                            );\r\n                        }\r\n                        prePointerInfo.skipOnPointerObservable = true;\r\n                    }\r\n                } else {\r\n                    const originalScenePick = getNearPickDataForScene(originalScene);\r\n                    const pointerEvent = <IPointerEvent>prePointerInfo.event;\r\n\r\n                    // If the layer can be occluded by the original scene, only fire pointer events to the first layer that hit they ray\r\n                    if (originalScenePick && utilityScenePick) {\r\n                        // No pick in utility scene\r\n                        if (utilityScenePick.distance === 0 && originalScenePick.pickedMesh) {\r\n                            if (this.mainSceneTrackerPredicate && this.mainSceneTrackerPredicate(originalScenePick.pickedMesh)) {\r\n                                // We touched an utility mesh present in the main scene\r\n                                this._notifyObservers(prePointerInfo, originalScenePick, pointerEvent);\r\n                                prePointerInfo.skipOnPointerObservable = true;\r\n                            } else if (prePointerInfo.type === PointerEventTypes.POINTERDOWN) {\r\n                                this._pointerCaptures[pointerEvent.pointerId] = true;\r\n                                this._notifyObservers(prePointerInfo, originalScenePick, pointerEvent);\r\n                            } else if (prePointerInfo.type === PointerEventTypes.POINTERMOVE || prePointerInfo.type === PointerEventTypes.POINTERUP) {\r\n                                if (this._lastPointerEvents[pointerEvent.pointerId]) {\r\n                                    // We need to send a last pointerup to the utilityLayerScene to make sure animations can complete\r\n                                    this.onPointerOutObservable.notifyObservers(pointerEvent.pointerId);\r\n                                    delete this._lastPointerEvents[pointerEvent.pointerId];\r\n                                }\r\n                                this._notifyObservers(prePointerInfo, originalScenePick, pointerEvent);\r\n                            }\r\n                        } else if (!this._pointerCaptures[pointerEvent.pointerId] && (utilityScenePick.distance < originalScenePick.distance || originalScenePick.distance === 0)) {\r\n                            // We pick something in utility scene or the pick in utility is closer than the one in main scene\r\n                            this._notifyObservers(prePointerInfo, utilityScenePick, pointerEvent);\r\n                            // If a previous utility layer set this, do not unset this\r\n                            if (!prePointerInfo.skipOnPointerObservable) {\r\n                                prePointerInfo.skipOnPointerObservable = utilityScenePick.distance > 0;\r\n                            }\r\n                        } else if (!this._pointerCaptures[pointerEvent.pointerId] && utilityScenePick.distance >= originalScenePick.distance) {\r\n                            // We have a pick in both scenes but main is closer than utility\r\n\r\n                            // We touched an utility mesh present in the main scene\r\n                            if (this.mainSceneTrackerPredicate && this.mainSceneTrackerPredicate(originalScenePick.pickedMesh)) {\r\n                                this._notifyObservers(prePointerInfo, originalScenePick, pointerEvent);\r\n                                prePointerInfo.skipOnPointerObservable = true;\r\n                            } else {\r\n                                if (prePointerInfo.type === PointerEventTypes.POINTERMOVE || prePointerInfo.type === PointerEventTypes.POINTERUP) {\r\n                                    if (this._lastPointerEvents[pointerEvent.pointerId]) {\r\n                                        // We need to send a last pointerup to the utilityLayerScene to make sure animations can complete\r\n                                        this.onPointerOutObservable.notifyObservers(pointerEvent.pointerId);\r\n                                        delete this._lastPointerEvents[pointerEvent.pointerId];\r\n                                    }\r\n                                }\r\n                                this._notifyObservers(prePointerInfo, utilityScenePick, pointerEvent);\r\n                            }\r\n                        }\r\n\r\n                        if (prePointerInfo.type === PointerEventTypes.POINTERUP && this._pointerCaptures[pointerEvent.pointerId]) {\r\n                            this._pointerCaptures[pointerEvent.pointerId] = false;\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n\r\n            // As a newly added utility layer will be rendered over the screen last, it's pointer events should be processed first\r\n            if (this._originalPointerObserver) {\r\n                originalScene.onPrePointerObservable.makeObserverTopPriority(this._originalPointerObserver);\r\n            }\r\n        }\r\n\r\n        // Render directly on top of existing scene without clearing\r\n        this.utilityLayerScene.autoClear = false;\r\n\r\n        if (!manualRender) {\r\n            this._afterRenderObserver = this.originalScene.onAfterRenderCameraObservable.add((camera) => {\r\n                // Only render when the render camera finishes rendering\r\n                if (this.shouldRender && camera == this.getRenderCamera()) {\r\n                    this.render();\r\n                }\r\n            });\r\n        }\r\n\r\n        this._sceneDisposeObserver = this.originalScene.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n\r\n        this._updateCamera();\r\n    }\r\n\r\n    private _notifyObservers(prePointerInfo: PointerInfoPre, pickInfo: PickingInfo, pointerEvent: IPointerEvent) {\r\n        if (!prePointerInfo.skipOnPointerObservable) {\r\n            this.utilityLayerScene.onPointerObservable.notifyObservers(new PointerInfo(prePointerInfo.type, prePointerInfo.event, pickInfo), prePointerInfo.type);\r\n            this._lastPointerEvents[pointerEvent.pointerId] = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Renders the utility layers scene on top of the original scene\r\n     */\r\n    public render() {\r\n        this._updateCamera();\r\n        if (this.utilityLayerScene.activeCamera) {\r\n            // Set the camera's scene to utility layers scene\r\n            const oldScene = this.utilityLayerScene.activeCamera.getScene();\r\n            const camera = this.utilityLayerScene.activeCamera;\r\n            camera._scene = this.utilityLayerScene;\r\n            if (camera.leftCamera) {\r\n                camera.leftCamera._scene = this.utilityLayerScene;\r\n            }\r\n            if (camera.rightCamera) {\r\n                camera.rightCamera._scene = this.utilityLayerScene;\r\n            }\r\n\r\n            this.utilityLayerScene.render(false);\r\n\r\n            // Reset camera's scene back to original\r\n            camera._scene = oldScene;\r\n            if (camera.leftCamera) {\r\n                camera.leftCamera._scene = oldScene;\r\n            }\r\n            if (camera.rightCamera) {\r\n                camera.rightCamera._scene = oldScene;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the renderer\r\n     */\r\n    public dispose() {\r\n        this.onPointerOutObservable.clear();\r\n\r\n        if (this._afterRenderObserver) {\r\n            this.originalScene.onAfterRenderCameraObservable.remove(this._afterRenderObserver);\r\n        }\r\n        if (this._sceneDisposeObserver) {\r\n            this.originalScene.onDisposeObservable.remove(this._sceneDisposeObserver);\r\n        }\r\n        if (this._originalPointerObserver) {\r\n            this.originalScene.onPrePointerObservable.remove(this._originalPointerObserver);\r\n        }\r\n        this.utilityLayerScene.dispose();\r\n    }\r\n\r\n    private _updateCamera() {\r\n        this.utilityLayerScene.cameraToUseForPointers = this.getRenderCamera();\r\n        this.utilityLayerScene.activeCamera = this.getRenderCamera();\r\n    }\r\n}\r\n","import { type Observer } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { Quaternion, Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { type TargetCamera } from \"../Cameras/targetCamera\";\r\nimport { type Node } from \"../node\";\r\nimport { type Bone } from \"../Bones/bone\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type StandardMaterial } from \"../Materials/standardMaterial\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type LinesMesh } from \"../Meshes/linesMesh\";\r\nimport { type PointerDragBehavior } from \"../Behaviors/Meshes/pointerDragBehavior\";\r\nimport { type ShadowLight } from \"../Lights/shadowLight\";\r\nimport { Light } from \"../Lights/light\";\r\n\r\n/**\r\n * Cache built by each axis. Used for managing state between all elements of gizmo for enhanced UI\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GizmoAxisCache {\r\n    /** Mesh used to render the Gizmo */\r\n    gizmoMeshes: Mesh[];\r\n    /** Mesh used to detect user interaction with Gizmo */\r\n    colliderMeshes: Mesh[];\r\n    /** Material used to indicate color of gizmo mesh */\r\n    material: StandardMaterial;\r\n    /** Material used to indicate hover state of the Gizmo */\r\n    hoverMaterial: StandardMaterial;\r\n    /** Material used to indicate disabled state of the Gizmo */\r\n    disableMaterial: StandardMaterial;\r\n    /** Used to indicate Active state of the Gizmo */\r\n    active: boolean;\r\n    /** DragBehavior */\r\n    dragBehavior: PointerDragBehavior;\r\n}\r\n\r\n/**\r\n * Anchor options where the Gizmo can be positioned in relation to its anchored node\r\n */\r\nexport const enum GizmoAnchorPoint {\r\n    /** The origin of the attached node */\r\n    Origin,\r\n    /** The pivot point of the attached node */\r\n    Pivot,\r\n}\r\n\r\n/**\r\n * Coordinates mode: Local or World. Defines how axis is aligned: either on world axis or transform local axis\r\n */\r\nexport const enum GizmoCoordinatesMode {\r\n    World,\r\n    Local,\r\n}\r\n\r\n/**\r\n * Interface for basic gizmo\r\n */\r\nexport interface IGizmo extends IDisposable {\r\n    /** True when the mouse pointer is hovered a gizmo mesh */\r\n    readonly isHovered: boolean;\r\n    /** The root mesh of the gizmo */\r\n    _rootMesh: Mesh;\r\n    /** Ratio for the scale of the gizmo */\r\n    scaleRatio: number;\r\n    /**\r\n     * Mesh that the gizmo will be attached to. (eg. on a drag gizmo the mesh that will be dragged)\r\n     * * When set, interactions will be enabled\r\n     */\r\n    attachedMesh: Nullable<AbstractMesh>;\r\n    /**\r\n     * Node that the gizmo will be attached to. (eg. on a drag gizmo the mesh, bone or NodeTransform that will be dragged)\r\n     * * When set, interactions will be enabled\r\n     */\r\n    attachedNode: Nullable<Node>;\r\n    /**\r\n     * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)\r\n     */\r\n    updateGizmoRotationToMatchAttachedMesh: boolean;\r\n    /** The utility layer the gizmo will be added to */\r\n    gizmoLayer: UtilityLayerRenderer;\r\n    /**\r\n     * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)\r\n     */\r\n    updateGizmoPositionToMatchAttachedMesh: boolean;\r\n    /**\r\n     * Defines where the gizmo will be positioned if `updateGizmoPositionToMatchAttachedMesh` is enabled.\r\n     * (Default: GizmoAnchorPoint.Origin)\r\n     */\r\n    anchorPoint: GizmoAnchorPoint;\r\n\r\n    /**\r\n     * Set the coordinate mode to use. By default it's local.\r\n     */\r\n    coordinatesMode: GizmoCoordinatesMode;\r\n\r\n    /**\r\n     * When set, the gizmo will always appear the same size no matter where the camera is (default: true)\r\n     */\r\n    updateScale: boolean;\r\n    /**\r\n     * Orientation that the gizmo will be displayed with.\r\n     * When set null, default value will be used (Quaternion(0, 0, 0, 1))\r\n     */\r\n    customRotationQuaternion: Nullable<Quaternion>;\r\n    /**\r\n     * Disposes and replaces the current meshes in the gizmo with the specified mesh\r\n     * @param mesh The mesh to replace the default mesh of the gizmo\r\n     */\r\n    setCustomMesh(mesh: Mesh): void;\r\n\r\n    /**\r\n     * Additional transform applied to the gizmo.\r\n     * It's useful when the gizmo is attached to a bone: if the bone is part of a skeleton attached to a mesh, you should define the mesh as additionalTransformNode if you want the gizmo to be displayed at the bone's correct location.\r\n     * Otherwise, as the gizmo is relative to the skeleton root, the mesh transformation will not be taken into account.\r\n     */\r\n    additionalTransformNode?: TransformNode | undefined;\r\n}\r\n/**\r\n * Renders gizmos on top of an existing scene which provide controls for position, rotation, etc.\r\n */\r\nexport class Gizmo implements IGizmo {\r\n    /**\r\n     * The root mesh of the gizmo\r\n     */\r\n    public _rootMesh: Mesh;\r\n    protected _attachedMesh: Nullable<AbstractMesh> = null;\r\n    protected _attachedNode: Nullable<Node> = null;\r\n    protected _customRotationQuaternion: Nullable<Quaternion> = null;\r\n    protected _additionalTransformNode?: TransformNode;\r\n    /**\r\n     * Ratio for the scale of the gizmo (Default: 1)\r\n     */\r\n    protected _scaleRatio = 1;\r\n\r\n    /**\r\n     * boolean updated by pointermove when a gizmo mesh is hovered\r\n     */\r\n    protected _isHovered = false;\r\n\r\n    /**\r\n     * When enabled, any gizmo operation will preserve scaling sign. Default is off.\r\n     * Only valid for TransformNode derived classes (Mesh, AbstractMesh, ...)\r\n     */\r\n    public static PreserveScaling = false;\r\n\r\n    /**\r\n     * There are 2 ways to preserve scaling: using mesh scaling or absolute scaling. Depending of hierarchy, non uniform scaling and LH or RH coordinates. One is preferable than the other.\r\n     * If the scaling to be preserved is the local scaling, then set this value to false.\r\n     * Default is true which means scaling to be preserved is absolute one (with hierarchy applied)\r\n     */\r\n    public static UseAbsoluteScaling = true;\r\n\r\n    /**\r\n     * Ratio for the scale of the gizmo (Default: 1)\r\n     */\r\n    public set scaleRatio(value: number) {\r\n        this._scaleRatio = value;\r\n    }\r\n\r\n    public get scaleRatio() {\r\n        return this._scaleRatio;\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is hovered a gizmo mesh\r\n     */\r\n    public get isHovered() {\r\n        return this._isHovered;\r\n    }\r\n\r\n    /**\r\n     * If a custom mesh has been set (Default: false)\r\n     */\r\n    protected _customMeshSet = false;\r\n    /**\r\n     * Mesh that the gizmo will be attached to. (eg. on a drag gizmo the mesh that will be dragged)\r\n     * * When set, interactions will be enabled\r\n     */\r\n    public get attachedMesh() {\r\n        return this._attachedMesh;\r\n    }\r\n    public set attachedMesh(value) {\r\n        this._attachedMesh = value;\r\n        if (value) {\r\n            this._attachedNode = value;\r\n        }\r\n        this._rootMesh.setEnabled(value ? true : false);\r\n        this._attachedNodeChanged(value);\r\n    }\r\n    /**\r\n     * Node that the gizmo will be attached to. (eg. on a drag gizmo the mesh, bone or NodeTransform that will be dragged)\r\n     * * When set, interactions will be enabled\r\n     */\r\n    public get attachedNode() {\r\n        return this._attachedNode;\r\n    }\r\n    public set attachedNode(value) {\r\n        this._attachedNode = value;\r\n        this._attachedMesh = null;\r\n        this._rootMesh.setEnabled(value ? true : false);\r\n        this._attachedNodeChanged(value);\r\n    }\r\n\r\n    /**\r\n     * Disposes and replaces the current meshes in the gizmo with the specified mesh\r\n     * @param mesh The mesh to replace the default mesh of the gizmo\r\n     */\r\n    public setCustomMesh(mesh: Mesh) {\r\n        if (mesh.getScene() != this.gizmoLayer.utilityLayerScene) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"When setting a custom mesh on a gizmo, the custom meshes scene must be the same as the gizmos (eg. gizmo.gizmoLayer.utilityLayerScene)\";\r\n        }\r\n        const children = this._rootMesh.getChildMeshes();\r\n        for (const c of children) {\r\n            c.dispose();\r\n        }\r\n        mesh.parent = this._rootMesh;\r\n        this._customMeshSet = true;\r\n    }\r\n\r\n    /**\r\n     * Additional transform applied to the gizmo.\r\n     * It's useful when the gizmo is attached to a bone: if the bone is part of a skeleton attached to a mesh, you should define the mesh as additionalTransformNode if you want the gizmo to be displayed at the bone's correct location.\r\n     * Otherwise, as the gizmo is relative to the skeleton root, the mesh transformation will not be taken into account.\r\n     */\r\n    public get additionalTransformNode() {\r\n        return this._additionalTransformNode;\r\n    }\r\n\r\n    public set additionalTransformNode(value: TransformNode | undefined) {\r\n        this._additionalTransformNode = value;\r\n    }\r\n\r\n    protected _updateGizmoRotationToMatchAttachedMesh = true;\r\n    protected _updateGizmoPositionToMatchAttachedMesh = true;\r\n    protected _anchorPoint = GizmoAnchorPoint.Origin;\r\n    protected _updateScale = true;\r\n    protected _coordinatesMode = GizmoCoordinatesMode.Local;\r\n\r\n    /**\r\n     * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)\r\n     * NOTE: This is only possible for meshes with uniform scaling, as otherwise it's not possible to decompose the rotation\r\n     */\r\n    public set updateGizmoRotationToMatchAttachedMesh(value: boolean) {\r\n        this._updateGizmoRotationToMatchAttachedMesh = value;\r\n    }\r\n    public get updateGizmoRotationToMatchAttachedMesh() {\r\n        return this._updateGizmoRotationToMatchAttachedMesh;\r\n    }\r\n    /**\r\n     * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)\r\n     */\r\n    public set updateGizmoPositionToMatchAttachedMesh(value: boolean) {\r\n        this._updateGizmoPositionToMatchAttachedMesh = value;\r\n    }\r\n    public get updateGizmoPositionToMatchAttachedMesh() {\r\n        return this._updateGizmoPositionToMatchAttachedMesh;\r\n    }\r\n\r\n    /**\r\n     * Defines where the gizmo will be positioned if `updateGizmoPositionToMatchAttachedMesh` is enabled.\r\n     * (Default: GizmoAnchorPoint.Origin)\r\n     */\r\n    public set anchorPoint(value: GizmoAnchorPoint) {\r\n        this._anchorPoint = value;\r\n    }\r\n    public get anchorPoint() {\r\n        return this._anchorPoint;\r\n    }\r\n\r\n    /**\r\n     * Set the coordinate system to use. By default it's local.\r\n     * But it's possible for a user to tweak so its local for translation and world for rotation.\r\n     * In that case, setting the coordinate system will change `updateGizmoRotationToMatchAttachedMesh` and `updateGizmoPositionToMatchAttachedMesh`\r\n     */\r\n    public set coordinatesMode(coordinatesMode: GizmoCoordinatesMode) {\r\n        this._coordinatesMode = coordinatesMode;\r\n        const local = coordinatesMode == GizmoCoordinatesMode.Local;\r\n        this.updateGizmoRotationToMatchAttachedMesh = local;\r\n        this.updateGizmoPositionToMatchAttachedMesh = true;\r\n    }\r\n\r\n    public get coordinatesMode() {\r\n        return this._coordinatesMode;\r\n    }\r\n\r\n    /**\r\n     * When set, the gizmo will always appear the same size no matter where the camera is (default: true)\r\n     */\r\n\r\n    public set updateScale(value: boolean) {\r\n        this._updateScale = value;\r\n    }\r\n    public get updateScale() {\r\n        return this._updateScale;\r\n    }\r\n    protected _interactionsEnabled = true;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _attachedNodeChanged(value: Nullable<Node>) {}\r\n\r\n    protected _beforeRenderObserver: Nullable<Observer<Scene>>;\r\n    private _rightHandtoLeftHandMatrix = Matrix.RotationY(Math.PI);\r\n\r\n    /**\r\n     * Creates a gizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     */\r\n    constructor(\r\n        /** [Object] The utility layer the gizmo will be added to */\r\n        public gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer\r\n    ) {\r\n        this._rootMesh = new Mesh(\"gizmoRootNode\", gizmoLayer.utilityLayerScene);\r\n        this._rootMesh.rotationQuaternion = Quaternion.Identity();\r\n\r\n        this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(() => {\r\n            this._update();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Orientation that the gizmo will be displayed with.\r\n     * When set null, default value will be used (Quaternion(0, 0, 0, 1))\r\n     */\r\n    public get customRotationQuaternion(): Nullable<Quaternion> {\r\n        return this._customRotationQuaternion;\r\n    }\r\n\r\n    public set customRotationQuaternion(customRotationQuaternion: Nullable<Quaternion>) {\r\n        this._customRotationQuaternion = customRotationQuaternion;\r\n    }\r\n\r\n    /**\r\n     * Updates the gizmo to match the attached mesh's position/rotation\r\n     */\r\n    protected _update() {\r\n        if (this.attachedNode) {\r\n            let effectiveNode = this.attachedNode;\r\n            if (this.attachedMesh) {\r\n                effectiveNode = this.attachedMesh;\r\n            }\r\n\r\n            // Position\r\n            if (this.updateGizmoPositionToMatchAttachedMesh) {\r\n                if (this.anchorPoint == GizmoAnchorPoint.Pivot && (<TransformNode>effectiveNode).getAbsolutePivotPoint) {\r\n                    const position = (<TransformNode>effectiveNode).getAbsolutePivotPoint();\r\n                    this._rootMesh.position.copyFrom(position);\r\n                } else {\r\n                    const row = effectiveNode.getWorldMatrix().getRow(3);\r\n                    const position = row ? row.toVector3() : new Vector3(0, 0, 0);\r\n                    this._rootMesh.position.copyFrom(position);\r\n                }\r\n            }\r\n\r\n            // Rotation\r\n            if (this.updateGizmoRotationToMatchAttachedMesh) {\r\n                const supportedNode =\r\n                    (<Mesh>effectiveNode)._isMesh ||\r\n                    effectiveNode.getClassName() === \"AbstractMesh\" ||\r\n                    effectiveNode.getClassName() === \"TransformNode\" ||\r\n                    effectiveNode.getClassName() === \"InstancedMesh\";\r\n                const transformNode = supportedNode ? (effectiveNode as TransformNode) : undefined;\r\n                effectiveNode.getWorldMatrix().decompose(undefined, this._rootMesh.rotationQuaternion!, undefined, Gizmo.PreserveScaling ? transformNode : undefined);\r\n                this._rootMesh.rotationQuaternion!.normalize();\r\n            } else {\r\n                if (this._customRotationQuaternion) {\r\n                    this._rootMesh.rotationQuaternion!.copyFrom(this._customRotationQuaternion);\r\n                } else {\r\n                    this._rootMesh.rotationQuaternion!.set(0, 0, 0, 1);\r\n                }\r\n            }\r\n\r\n            // Scale\r\n            if (this.updateScale) {\r\n                const activeCamera = this.gizmoLayer.utilityLayerScene.activeCamera!;\r\n                const cameraPosition = activeCamera.globalPosition;\r\n                const offsetToCamera = TmpVectors.Vector3[0];\r\n                this._rootMesh.absolutePosition.subtractToRef(cameraPosition, offsetToCamera);\r\n                let scale = this.scaleRatio;\r\n                if (activeCamera.mode == Camera.ORTHOGRAPHIC_CAMERA) {\r\n                    if (activeCamera.orthoTop && activeCamera.orthoBottom) {\r\n                        const orthoHeight = activeCamera.orthoTop - activeCamera.orthoBottom;\r\n                        scale *= orthoHeight;\r\n                    }\r\n                } else {\r\n                    const camForward = activeCamera.getScene().useRightHandedSystem ? Vector3.RightHandedForwardReadOnly : Vector3.LeftHandedForwardReadOnly;\r\n                    const direction = activeCamera.getDirection(camForward);\r\n                    scale *= Vector3.Dot(offsetToCamera, direction);\r\n                }\r\n                if (this.additionalTransformNode) {\r\n                    this.additionalTransformNode.getWorldMatrix().decompose(TmpVectors.Vector3[1]);\r\n                    const maxScale = Math.max(Math.abs(TmpVectors.Vector3[1].x), Math.abs(TmpVectors.Vector3[1].y), Math.abs(TmpVectors.Vector3[1].z));\r\n                    scale *= 1 / maxScale;\r\n                }\r\n                this._rootMesh.scaling.setAll(scale);\r\n\r\n                // Account for handedness, similar to Matrix.decompose\r\n                if (effectiveNode._getWorldMatrixDeterminant() < 0 && !Gizmo.PreserveScaling) {\r\n                    this._rootMesh.scaling.y *= -1;\r\n                }\r\n            } else {\r\n                this._rootMesh.scaling.setAll(this.scaleRatio);\r\n            }\r\n        }\r\n\r\n        if (this.additionalTransformNode) {\r\n            this._rootMesh.computeWorldMatrix(true);\r\n            this._rootMesh.getWorldMatrix().multiplyToRef(this.additionalTransformNode.getWorldMatrix(), TmpVectors.Matrix[0]);\r\n            TmpVectors.Matrix[0].decompose(this._rootMesh.scaling, this._rootMesh.rotationQuaternion!, this._rootMesh.position);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * if transform has a pivot and is not using PostMultiplyPivotMatrix, then the worldMatrix contains the pivot matrix (it's not cancelled at the end)\r\n     * so, when extracting the world matrix component, the translation (and other components) is containing the pivot translation.\r\n     * And the pivot is applied each frame. Removing it anyway here makes it applied only in computeWorldMatrix.\r\n     * @param transform local transform that needs to be transform by the pivot inverse matrix\r\n     * @param localMatrix local matrix that needs to be transform by the pivot inverse matrix\r\n     * @param result resulting matrix transformed by pivot inverse if the transform node is using pivot without using post Multiply Pivot Matrix\r\n     */\r\n    protected _handlePivotMatrixInverse(transform: TransformNode, localMatrix: Matrix, result: Matrix): void {\r\n        if (transform.isUsingPivotMatrix() && !transform.isUsingPostMultiplyPivotMatrix()) {\r\n            transform.getPivotMatrix().invertToRef(TmpVectors.Matrix[5]);\r\n            TmpVectors.Matrix[5].multiplyToRef(localMatrix, result);\r\n            return;\r\n        }\r\n        result.copyFrom(localMatrix);\r\n    }\r\n    /**\r\n     * computes the rotation/scaling/position of the transform once the Node world matrix has changed.\r\n     */\r\n    protected _matrixChanged() {\r\n        if (!this._attachedNode) {\r\n            return;\r\n        }\r\n\r\n        if ((<Camera>this._attachedNode)._isCamera) {\r\n            const camera = this._attachedNode as Camera;\r\n            let worldMatrix;\r\n            let worldMatrixUc;\r\n            if (camera.parent) {\r\n                const parentInv = TmpVectors.Matrix[1];\r\n                camera.parent._worldMatrix.invertToRef(parentInv);\r\n                this._attachedNode._worldMatrix.multiplyToRef(parentInv, TmpVectors.Matrix[0]);\r\n                worldMatrix = TmpVectors.Matrix[0];\r\n            } else {\r\n                worldMatrix = this._attachedNode._worldMatrix;\r\n            }\r\n\r\n            if (camera.getScene().useRightHandedSystem) {\r\n                // avoid desync with RH matrix computation. Otherwise, rotation of PI around Y axis happens each frame resulting in axis flipped because worldMatrix is computed as inverse of viewMatrix.\r\n                this._rightHandtoLeftHandMatrix.multiplyToRef(worldMatrix, TmpVectors.Matrix[1]);\r\n                worldMatrixUc = TmpVectors.Matrix[1];\r\n            } else {\r\n                worldMatrixUc = worldMatrix;\r\n            }\r\n\r\n            worldMatrixUc.decompose(TmpVectors.Vector3[1], TmpVectors.Quaternion[0], TmpVectors.Vector3[0]);\r\n\r\n            const inheritsTargetCamera =\r\n                this._attachedNode.getClassName() === \"FreeCamera\" ||\r\n                this._attachedNode.getClassName() === \"FlyCamera\" ||\r\n                this._attachedNode.getClassName() === \"ArcFollowCamera\" ||\r\n                this._attachedNode.getClassName() === \"TargetCamera\" ||\r\n                this._attachedNode.getClassName() === \"TouchCamera\" ||\r\n                this._attachedNode.getClassName() === \"UniversalCamera\";\r\n\r\n            if (inheritsTargetCamera) {\r\n                const targetCamera = this._attachedNode as TargetCamera;\r\n                targetCamera.rotation = TmpVectors.Quaternion[0].toEulerAngles();\r\n\r\n                if (targetCamera.rotationQuaternion) {\r\n                    targetCamera.rotationQuaternion.copyFrom(TmpVectors.Quaternion[0]);\r\n                    targetCamera.rotationQuaternion.normalize();\r\n                }\r\n            }\r\n\r\n            camera.position.copyFrom(TmpVectors.Vector3[0]);\r\n        } else if (\r\n            (<Mesh>this._attachedNode)._isMesh ||\r\n            this._attachedNode.getClassName() === \"AbstractMesh\" ||\r\n            this._attachedNode.getClassName() === \"TransformNode\" ||\r\n            this._attachedNode.getClassName() === \"InstancedMesh\"\r\n        ) {\r\n            const transform = this._attachedNode as TransformNode;\r\n            if (transform.parent) {\r\n                const parentInv = TmpVectors.Matrix[0];\r\n                const localMat = TmpVectors.Matrix[1];\r\n                transform.parent.getWorldMatrix().invertToRef(parentInv);\r\n                this._attachedNode.getWorldMatrix().multiplyToRef(parentInv, localMat);\r\n                const matrixToDecompose = TmpVectors.Matrix[4];\r\n                this._handlePivotMatrixInverse(transform, localMat, matrixToDecompose);\r\n                matrixToDecompose.decompose(\r\n                    TmpVectors.Vector3[0],\r\n                    TmpVectors.Quaternion[0],\r\n                    transform.position,\r\n                    Gizmo.PreserveScaling ? transform : undefined,\r\n                    Gizmo.UseAbsoluteScaling\r\n                );\r\n                TmpVectors.Quaternion[0].normalize();\r\n                if (transform.isUsingPivotMatrix()) {\r\n                    // Calculate the local matrix without the translation.\r\n                    // Copied from TranslateNode.computeWorldMatrix\r\n                    const r = TmpVectors.Quaternion[1];\r\n                    Quaternion.RotationYawPitchRollToRef(transform.rotation.y, transform.rotation.x, transform.rotation.z, r);\r\n\r\n                    const scaleMatrix = TmpVectors.Matrix[2];\r\n                    Matrix.ScalingToRef(transform.scaling.x, transform.scaling.y, transform.scaling.z, scaleMatrix);\r\n\r\n                    const rotationMatrix = TmpVectors.Matrix[7];\r\n                    r.toRotationMatrix(rotationMatrix);\r\n\r\n                    const pivotMatrix = transform.getPivotMatrix();\r\n                    const invPivotMatrix = TmpVectors.Matrix[3];\r\n                    pivotMatrix.invertToRef(invPivotMatrix);\r\n\r\n                    pivotMatrix.multiplyToRef(scaleMatrix, TmpVectors.Matrix[4]);\r\n                    TmpVectors.Matrix[4].multiplyToRef(rotationMatrix, TmpVectors.Matrix[5]);\r\n                    TmpVectors.Matrix[5].multiplyToRef(invPivotMatrix, TmpVectors.Matrix[6]);\r\n\r\n                    TmpVectors.Matrix[6].getTranslationToRef(TmpVectors.Vector3[1]);\r\n\r\n                    transform.position.subtractInPlace(TmpVectors.Vector3[1]);\r\n                }\r\n            } else {\r\n                const matrixToDecompose = TmpVectors.Matrix[4];\r\n                this._handlePivotMatrixInverse(transform, this._attachedNode._worldMatrix, matrixToDecompose);\r\n                matrixToDecompose.decompose(\r\n                    TmpVectors.Vector3[0],\r\n                    TmpVectors.Quaternion[0],\r\n                    transform.position,\r\n                    Gizmo.PreserveScaling ? transform : undefined,\r\n                    Gizmo.UseAbsoluteScaling\r\n                );\r\n            }\r\n            TmpVectors.Vector3[0].scaleInPlace(1.0 / transform.scalingDeterminant);\r\n            transform.scaling.copyFrom(TmpVectors.Vector3[0]);\r\n            if (!transform.billboardMode) {\r\n                if (transform.rotationQuaternion) {\r\n                    transform.rotationQuaternion.copyFrom(TmpVectors.Quaternion[0]);\r\n                    transform.rotationQuaternion.normalize();\r\n                } else {\r\n                    transform.rotation = TmpVectors.Quaternion[0].toEulerAngles();\r\n                }\r\n            }\r\n        } else if (this._attachedNode.getClassName() === \"Bone\") {\r\n            const bone = this._attachedNode as Bone;\r\n            const parent = bone.getParent();\r\n\r\n            if (parent) {\r\n                const invParent = TmpVectors.Matrix[0];\r\n                const boneLocalMatrix = TmpVectors.Matrix[1];\r\n                parent.getFinalMatrix().invertToRef(invParent);\r\n                bone.getFinalMatrix().multiplyToRef(invParent, boneLocalMatrix);\r\n                const lmat = bone.getLocalMatrix();\r\n                lmat.copyFrom(boneLocalMatrix);\r\n            } else {\r\n                const lmat = bone.getLocalMatrix();\r\n                lmat.copyFrom(bone.getFinalMatrix());\r\n            }\r\n            bone.markAsDirty();\r\n        } else {\r\n            const light = this._attachedNode as ShadowLight;\r\n            if (light.getTypeID) {\r\n                const type = light.getTypeID();\r\n                if (type === Light.LIGHTTYPEID_DIRECTIONALLIGHT || type === Light.LIGHTTYPEID_SPOTLIGHT || type === Light.LIGHTTYPEID_POINTLIGHT) {\r\n                    const parent = light.parent;\r\n\r\n                    if (parent) {\r\n                        const invParent = TmpVectors.Matrix[0];\r\n                        const nodeLocalMatrix = TmpVectors.Matrix[1];\r\n                        parent.getWorldMatrix().invertToRef(invParent);\r\n                        light.getWorldMatrix().multiplyToRef(invParent, nodeLocalMatrix);\r\n                        nodeLocalMatrix.decompose(undefined, TmpVectors.Quaternion[0], TmpVectors.Vector3[0]);\r\n                    } else {\r\n                        this._attachedNode._worldMatrix.decompose(undefined, TmpVectors.Quaternion[0], TmpVectors.Vector3[0]);\r\n                    }\r\n                    // setter doesn't copy values. Need a new Vector3\r\n                    light.position = new Vector3(TmpVectors.Vector3[0].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[0].z);\r\n                    if (light.direction) {\r\n                        light.direction = new Vector3(light.direction.x, light.direction.y, light.direction.z);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * refresh gizmo mesh material\r\n     * @param gizmoMeshes\r\n     * @param material material to apply\r\n     */\r\n    protected _setGizmoMeshMaterial(gizmoMeshes: Mesh[], material: StandardMaterial) {\r\n        if (gizmoMeshes) {\r\n            for (const m of gizmoMeshes) {\r\n                m.material = material;\r\n                if ((<LinesMesh>m).color) {\r\n                    (<LinesMesh>m).color = material.diffuseColor;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Subscribes to pointer up, down, and hover events. Used for responsive gizmos.\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param gizmoAxisCache Gizmo axis definition used for reactive gizmo UI\r\n     * @returns {Observer<PointerInfo>} pointerObserver\r\n     */\r\n    public static GizmoAxisPointerObserver(gizmoLayer: UtilityLayerRenderer, gizmoAxisCache: Map<Mesh, GizmoAxisCache>): Observer<PointerInfo> {\r\n        let dragging = false;\r\n        let activeDragButton = -1;\r\n        let forcePointerUp = false;\r\n\r\n        const pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (pointerInfo.pickInfo) {\r\n                // If we are dragging and the user presses another button, end the drag.\r\n                // Otherwise, tracking when the drag should end becomes very complex.\r\n                // pointerDragBehavior.ts has similar logic.\r\n                forcePointerUp = dragging && pointerInfo.event.button !== -1 && pointerInfo.event.button !== activeDragButton;\r\n\r\n                if (forcePointerUp || pointerInfo.type === PointerEventTypes.POINTERUP) {\r\n                    // On Mouse Up\r\n\r\n                    gizmoAxisCache.forEach((cache) => {\r\n                        cache.active = false;\r\n                        dragging = false;\r\n                        activeDragButton = -1;\r\n                        for (const m of cache.gizmoMeshes) {\r\n                            m.material = cache.dragBehavior.enabled ? cache.material : cache.disableMaterial;\r\n                            if ((m as LinesMesh).color) {\r\n                                (m as LinesMesh).color = cache.material.diffuseColor;\r\n                            }\r\n                        }\r\n                    });\r\n                } else if (pointerInfo.type === PointerEventTypes.POINTERMOVE) {\r\n                    // On Hover Logic\r\n                    if (dragging) {\r\n                        return;\r\n                    }\r\n                    gizmoAxisCache.forEach((cache) => {\r\n                        if (cache.colliderMeshes && cache.gizmoMeshes) {\r\n                            const isHovered = cache.colliderMeshes?.indexOf(pointerInfo?.pickInfo?.pickedMesh as Mesh) != -1;\r\n                            const material = cache.dragBehavior.enabled ? (isHovered || cache.active ? cache.hoverMaterial : cache.material) : cache.disableMaterial;\r\n                            for (const m of cache.gizmoMeshes) {\r\n                                m.material = material;\r\n                                if ((m as LinesMesh).color) {\r\n                                    (m as LinesMesh).color = material.diffuseColor;\r\n                                }\r\n                            }\r\n                        }\r\n                    });\r\n                } else if (pointerInfo.type === PointerEventTypes.POINTERDOWN) {\r\n                    // On Mouse Down\r\n                    // If user Clicked Gizmo\r\n                    if (gizmoAxisCache.has(pointerInfo.pickInfo.pickedMesh?.parent as Mesh)) {\r\n                        dragging = true;\r\n                        activeDragButton = pointerInfo.event.button;\r\n                        const statusMap = gizmoAxisCache.get(pointerInfo.pickInfo.pickedMesh?.parent as Mesh);\r\n                        statusMap!.active = true;\r\n                        gizmoAxisCache.forEach((cache) => {\r\n                            const isHovered = cache.colliderMeshes?.indexOf(pointerInfo?.pickInfo?.pickedMesh as Mesh) != -1;\r\n                            const material = (isHovered || cache.active) && cache.dragBehavior.enabled ? cache.hoverMaterial : cache.disableMaterial;\r\n                            for (const m of cache.gizmoMeshes) {\r\n                                m.material = material;\r\n                                if ((m as LinesMesh).color) {\r\n                                    (m as LinesMesh).color = material.diffuseColor;\r\n                                }\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            }\r\n        });\r\n\r\n        return pointerObserver;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public dispose() {\r\n        this._rootMesh.dispose();\r\n        if (this._beforeRenderObserver) {\r\n            this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.remove(this._beforeRenderObserver);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IInspectable } from \"../Misc/iInspectable\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n\r\n// declare INSPECTOR namespace for compilation issue\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare let INSPECTOR: any;\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare let BABYLON: any;\r\n// load the inspector using require, if not present in the global namespace.\r\n\r\n/**\r\n * Interface used to define scene explorer extensibility option\r\n */\r\nexport interface IExplorerExtensibilityOption {\r\n    /**\r\n     * Define the option label\r\n     */\r\n    label: string;\r\n    /**\r\n     * Defines the action to execute on click\r\n     */\r\n    action: (entity: any) => void;\r\n    /**\r\n     * Keep popup open after click\r\n     */\r\n    keepOpenAfterClick?: boolean;\r\n}\r\n\r\n/**\r\n * Defines a group of actions associated with a predicate to use when extending the Inspector scene explorer\r\n */\r\nexport interface IExplorerExtensibilityGroup {\r\n    /**\r\n     * Defines a predicate to test if a given type mut be extended\r\n     */\r\n    predicate: (entity: any) => boolean;\r\n    /**\r\n     * Gets the list of options added to a type\r\n     */\r\n    entries: IExplorerExtensibilityOption[];\r\n}\r\n\r\n/**\r\n * Defines a new node that will be displayed as top level node in the explorer\r\n */\r\nexport interface IExplorerAdditionalChild {\r\n    /**\r\n     * Gets the name of the additional node\r\n     */\r\n    name: string;\r\n    /**\r\n     * Function used to return the class name of the child node\r\n     */\r\n    getClassName(): string;\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    inspectableCustomProperties: IInspectable[];\r\n}\r\n\r\n/**\r\n * Defines a new node that will be displayed as top level node in the explorer\r\n */\r\nexport interface IExplorerAdditionalNode {\r\n    /**\r\n     * Gets the name of the additional node\r\n     */\r\n    name: string;\r\n    /**\r\n     * Function used to return the list of child entries\r\n     */\r\n    getContent(): IExplorerAdditionalChild[];\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type IInspectorContextMenuType = \"pipeline\" | \"node\" | \"materials\" | \"spriteManagers\" | \"particleSystems\" | \"frameGraphs\";\r\n\r\n/**\r\n * Context menu item\r\n */\r\nexport interface IInspectorContextMenuItem {\r\n    /**\r\n     * Display label - menu item\r\n     */\r\n    label: string;\r\n    /**\r\n     * Callback function that will be called when the menu item is selected\r\n     * @param entity the entity that is currently selected in the scene explorer\r\n     */\r\n    action: (entity?: unknown) => void;\r\n}\r\n\r\n/**\r\n * Interface used to define the options to use to create the Inspector\r\n */\r\nexport interface IInspectorOptions {\r\n    /**\r\n     * Display in overlay mode (default: false)\r\n     */\r\n    overlay?: boolean;\r\n    /**\r\n     * HTML element to use as root (the parent of the rendering canvas will be used as default value)\r\n     */\r\n    globalRoot?: HTMLElement;\r\n    /**\r\n     * Display the Scene explorer\r\n     */\r\n    showExplorer?: boolean;\r\n    /**\r\n     * Display the property inspector\r\n     */\r\n    showInspector?: boolean;\r\n    /**\r\n     * Display in embed mode (both panes on the right)\r\n     */\r\n    embedMode?: boolean;\r\n    /**\r\n     * let the Inspector handles resize of the canvas when panes are resized (default to true)\r\n     */\r\n    handleResize?: boolean;\r\n    /**\r\n     * Allow the panes to popup (default: true)\r\n     */\r\n    enablePopup?: boolean;\r\n    /**\r\n     * Allow the panes to be closed by users (default: true)\r\n     */\r\n    enableClose?: boolean;\r\n    /**\r\n     * Optional list of extensibility entries\r\n     */\r\n    explorerExtensibility?: IExplorerExtensibilityGroup[];\r\n    /**\r\n     * Optional list of additional top level nodes\r\n     */\r\n    additionalNodes?: IExplorerAdditionalNode[];\r\n    /**\r\n     * Optional URL to get the inspector script from (by default it uses the babylonjs CDN).\r\n     */\r\n    inspectorURL?: string;\r\n    /**\r\n     * Optional initial tab (default to DebugLayerTab.Properties)\r\n     */\r\n    initialTab?: DebugLayerTab;\r\n    /**\r\n     * Optional camera to use to render the gizmos from the inspector (default to the scene.activeCamera or the latest from scene.activeCameras)\r\n     */\r\n    gizmoCamera?: Camera;\r\n    /**\r\n     * Context menu for inspector tools such as \"Post Process\", \"Nodes\", \"Materials\", etc.\r\n     */\r\n    contextMenu?: Partial<Record<IInspectorContextMenuType, IInspectorContextMenuItem[]>>;\r\n    /**\r\n     * List of context menu items that should be completely overridden by custom items from the contextMenu property.\r\n     */\r\n    contextMenuOverride?: IInspectorContextMenuType[];\r\n\r\n    /**\r\n     * Should the default font loading be skipped\r\n     */\r\n    skipDefaultFontLoading?: boolean;\r\n}\r\n\r\n/**\r\n * Enum of inspector action tab\r\n */\r\nexport const enum DebugLayerTab {\r\n    /**\r\n     * Properties tag (default)\r\n     */\r\n    Properties = 0,\r\n    /**\r\n     * Debug tab\r\n     */\r\n    Debug = 1,\r\n    /**\r\n     * Statistics tab\r\n     */\r\n    Statistics = 2,\r\n    /**\r\n     * Tools tab\r\n     */\r\n    Tools = 3,\r\n    /**\r\n     * Settings tab\r\n     */\r\n    Settings = 4,\r\n}\r\n\r\n/**\r\n * The debug layer (aka Inspector) is the go to tool in order to better understand\r\n * what is happening in your scene\r\n * @see https://doc.babylonjs.com/toolsAndResources/inspector\r\n */\r\nexport class DebugLayer {\r\n    /**\r\n     * Define the url to get the inspector script from.\r\n     * By default it uses the babylonjs CDN.\r\n     * @ignoreNaming\r\n     */\r\n    public static InspectorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/inspector/babylon.inspector.bundle.js`;\r\n\r\n    /**\r\n     * The default configuration of the inspector\r\n     */\r\n    public static Config: IInspectorOptions = {\r\n        overlay: false,\r\n        showExplorer: true,\r\n        showInspector: true,\r\n        embedMode: false,\r\n        handleResize: true,\r\n        enablePopup: true,\r\n    };\r\n\r\n    private _scene: Scene;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected BJSINSPECTOR = this._getGlobalInspector();\r\n\r\n    private _onPropertyChangedObservable?: Observable<{ object: any; property: string; value: any; initialValue: any }>;\r\n    /**\r\n     * Observable triggered when a property is changed through the inspector.\r\n     */\r\n    public get onPropertyChangedObservable() {\r\n        if (this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector) {\r\n            return this.BJSINSPECTOR.Inspector.OnPropertyChangedObservable;\r\n        }\r\n\r\n        if (!this._onPropertyChangedObservable) {\r\n            this._onPropertyChangedObservable = new Observable<{ object: any; property: string; value: any; initialValue: any }>();\r\n        }\r\n\r\n        return this._onPropertyChangedObservable;\r\n    }\r\n\r\n    private _onSelectionChangedObservable?: Observable<any>;\r\n    /**\r\n     * Observable triggered when the selection is changed through the inspector.\r\n     */\r\n    public get onSelectionChangedObservable() {\r\n        if (this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector) {\r\n            return this.BJSINSPECTOR.Inspector.OnSelectionChangeObservable;\r\n        }\r\n\r\n        if (!this._onSelectionChangedObservable) {\r\n            this._onSelectionChangedObservable = new Observable<any>();\r\n        }\r\n\r\n        return this._onSelectionChangedObservable;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new debug layer.\r\n     * The debug layer (aka Inspector) is the go to tool in order to better understand\r\n     * what is happening in your scene\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector\r\n     * @param scene Defines the scene to inspect\r\n     */\r\n    constructor(scene?: Scene) {\r\n        this._scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n        this._scene.onDisposeObservable.add(() => {\r\n            // Debug layer\r\n            if (this._scene._debugLayer) {\r\n                this._scene._debugLayer.hide();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates the inspector window.\r\n     * @param config\r\n     */\r\n    private _createInspector(config?: Partial<IInspectorOptions>) {\r\n        if (this.isVisible()) {\r\n            return;\r\n        }\r\n\r\n        if (this._onPropertyChangedObservable) {\r\n            for (const observer of this._onPropertyChangedObservable.observers) {\r\n                this.BJSINSPECTOR.Inspector.OnPropertyChangedObservable.add(observer);\r\n            }\r\n            this._onPropertyChangedObservable.clear();\r\n            this._onPropertyChangedObservable = undefined;\r\n        }\r\n\r\n        if (this._onSelectionChangedObservable) {\r\n            for (const observer of this._onSelectionChangedObservable.observers) {\r\n                this.BJSINSPECTOR.Inspector.OnSelectionChangedObservable.add(observer);\r\n            }\r\n            this._onSelectionChangedObservable.clear();\r\n            this._onSelectionChangedObservable = undefined;\r\n        }\r\n\r\n        const userOptions: IInspectorOptions = {\r\n            ...DebugLayer.Config,\r\n            ...config,\r\n        };\r\n\r\n        this.BJSINSPECTOR = this.BJSINSPECTOR || this._getGlobalInspector();\r\n\r\n        this.BJSINSPECTOR.Inspector.Show(this._scene, userOptions);\r\n    }\r\n\r\n    /**\r\n     * Select a specific entity in the scene explorer and highlight a specific block in that entity property grid\r\n     * @param entity defines the entity to select\r\n     * @param lineContainerTitles defines the specific blocks to highlight (could be a string or an array of strings)\r\n     */\r\n    public select(entity: any, lineContainerTitles?: string | string[]) {\r\n        if (this.BJSINSPECTOR) {\r\n            if (lineContainerTitles) {\r\n                if (Object.prototype.toString.call(lineContainerTitles) == \"[object String]\") {\r\n                    this.BJSINSPECTOR.Inspector.MarkLineContainerTitleForHighlighting(lineContainerTitles);\r\n                } else {\r\n                    this.BJSINSPECTOR.Inspector.MarkMultipleLineContainerTitlesForHighlighting(lineContainerTitles);\r\n                }\r\n            }\r\n            if (!this.BJSINSPECTOR.Inspector.IsVisible) {\r\n                const waitAndCheck = () => {\r\n                    setTimeout(() => {\r\n                        if (this.BJSINSPECTOR.Inspector.IsVisible) {\r\n                            this.select(entity, lineContainerTitles);\r\n                        } else {\r\n                            waitAndCheck();\r\n                        }\r\n                    }, 100);\r\n                };\r\n                waitAndCheck();\r\n            } else {\r\n                this.BJSINSPECTOR.Inspector.OnSelectionChangeObservable.notifyObservers(entity);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the inspector from bundle or global\r\n     * @returns the inspector instance if found otherwise, null\r\n     */\r\n    private _getGlobalInspector(): any {\r\n        // UMD global name detection from bundle metadata.\r\n        if (typeof INSPECTOR !== \"undefined\") {\r\n            return INSPECTOR;\r\n        }\r\n\r\n        // In case of module let s check the global emitted from the Inspector entry point.\r\n        if (typeof BABYLON !== \"undefined\" && typeof BABYLON.Inspector !== \"undefined\") {\r\n            return BABYLON;\r\n        }\r\n\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Get if the inspector is visible or not.\r\n     * @returns true if visible otherwise, false\r\n     */\r\n    public isVisible(): boolean {\r\n        return this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector.IsVisible;\r\n    }\r\n\r\n    /**\r\n     * Hide the inspector and close its window.\r\n     */\r\n    public hide() {\r\n        if (this.BJSINSPECTOR) {\r\n            this.BJSINSPECTOR.Inspector.Hide();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the number of opened panes in the inspector\r\n     */\r\n    public get openedPanes() {\r\n        if (this.BJSINSPECTOR) {\r\n            return this.BJSINSPECTOR.Inspector._OpenedPane;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Update the scene in the inspector\r\n     */\r\n    public setAsActiveScene() {\r\n        if (this.BJSINSPECTOR) {\r\n            this.BJSINSPECTOR.Inspector._SetNewScene(this._scene);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Pop up the scene explorer in a separate window\r\n     */\r\n    public popupSceneExplorer() {\r\n        if (this.BJSINSPECTOR) {\r\n            this.BJSINSPECTOR.Inspector.PopupSceneExplorer();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Pop up the inspector in a separate window\r\n     */\r\n    public popupInspector() {\r\n        if (this.BJSINSPECTOR) {\r\n            this.BJSINSPECTOR.Inspector.PopupInspector();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Pop up the embedded inspector panel\r\n     */\r\n    public popupEmbed() {\r\n        if (this.BJSINSPECTOR) {\r\n            this.BJSINSPECTOR.Inspector.PopupEmbed();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Launch the debugLayer.\r\n     * @param config Define the configuration of the inspector\r\n     * @returns a promise fulfilled when the debug layer is visible\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async show(config?: IInspectorOptions): Promise<DebugLayer> {\r\n        return await new Promise((resolve) => {\r\n            if (typeof this.BJSINSPECTOR == \"undefined\") {\r\n                const inspectorUrl = config && config.inspectorURL ? config.inspectorURL : DebugLayer.InspectorURL;\r\n\r\n                // Load inspector and add it to the DOM\r\n                Tools.LoadBabylonScript(inspectorUrl, () => {\r\n                    this._createInspector(config);\r\n                    resolve(this);\r\n                });\r\n            } else {\r\n                // Otherwise creates the inspector\r\n                this._createInspector(config);\r\n                resolve(this);\r\n            }\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for debugLayer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDebugLayer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"debugLayer\", {\r\n        get: function (this: Scene) {\r\n            if (!this._debugLayer) {\r\n                this._debugLayer = new DebugLayer(this);\r\n            }\r\n            return this._debugLayer;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { PointerDragBehavior } from \"../Behaviors/Meshes/pointerDragBehavior\";\r\nimport { type GizmoAxisCache, type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type PositionGizmo } from \"./positionGizmo\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Interface for axis drag gizmo\r\n */\r\nexport interface IAxisDragGizmo extends IGizmo {\r\n    /** Drag behavior responsible for the gizmos dragging interactions */\r\n    dragBehavior: PointerDragBehavior;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in distance\r\n     */\r\n    onSnapObservable: Observable<{ snapDistance: number }>;\r\n    /** If the gizmo is enabled */\r\n    isEnabled: boolean;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    coloredMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    hoverMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    disableMaterial: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Single axis drag gizmo\r\n */\r\nexport class AxisDragGizmo extends Gizmo implements IAxisDragGizmo {\r\n    /**\r\n     * Drag behavior responsible for the gizmos dragging interactions\r\n     */\r\n    public dragBehavior: PointerDragBehavior;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)\r\n     */\r\n    public snapDistance = 0;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in distance\r\n     */\r\n    public onSnapObservable = new Observable<{ snapDistance: number }>();\r\n\r\n    protected _isEnabled: boolean = true;\r\n    protected _parent: Nullable<PositionGizmo> = null;\r\n\r\n    protected _gizmoMesh: Mesh;\r\n    protected _coloredMaterial: StandardMaterial;\r\n    protected _hoverMaterial: StandardMaterial;\r\n    protected _disableMaterial: StandardMaterial;\r\n    protected _dragging: boolean = false;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    public get coloredMaterial() {\r\n        return this._coloredMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    public get hoverMaterial() {\r\n        return this._hoverMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    public get disableMaterial() {\r\n        return this._disableMaterial;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _CreateArrow(scene: Scene, material: StandardMaterial, thickness: number = 1, isCollider = false): TransformNode {\r\n        const arrow = new TransformNode(\"arrow\", scene);\r\n        const cylinder = CreateCylinder(\r\n            \"cylinder\",\r\n            {\r\n                diameterTop: 0,\r\n                height: 0.075,\r\n                diameterBottom: 0.0375 * (1 + (thickness - 1) / 4),\r\n                tessellation: 96,\r\n            },\r\n            scene\r\n        );\r\n        const line = CreateCylinder(\r\n            \"cylinder\",\r\n            {\r\n                diameterTop: 0.005 * thickness,\r\n                height: 0.275,\r\n                diameterBottom: 0.005 * thickness,\r\n                tessellation: 96,\r\n            },\r\n            scene\r\n        );\r\n\r\n        // Position arrow pointing in its drag axis\r\n        cylinder.parent = arrow;\r\n        cylinder.material = material;\r\n        cylinder.rotation.x = Math.PI / 2;\r\n        cylinder.position.z += 0.3;\r\n\r\n        line.parent = arrow;\r\n        line.material = material;\r\n        line.position.z += 0.275 / 2;\r\n        line.rotation.x = Math.PI / 2;\r\n\r\n        if (isCollider) {\r\n            line.visibility = 0;\r\n            cylinder.visibility = 0;\r\n        }\r\n        return arrow;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _CreateArrowInstance(scene: Scene, arrow: TransformNode): TransformNode {\r\n        const instance = new TransformNode(\"arrow\", scene);\r\n        for (const mesh of arrow.getChildMeshes()) {\r\n            const childInstance = (mesh as Mesh).createInstance(mesh.name);\r\n            childInstance.parent = instance;\r\n        }\r\n        return instance;\r\n    }\r\n\r\n    /**\r\n     * Creates an AxisDragGizmo\r\n     * @param dragAxis The axis which the gizmo will be able to drag on\r\n     * @param color The color of the gizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param parent\r\n     * @param thickness display gizmo axis thickness\r\n     * @param hoverColor The color of the gizmo when hovering over and dragging\r\n     * @param disableColor The Color of the gizmo when its disabled\r\n     */\r\n    constructor(\r\n        dragAxis: Vector3,\r\n        color: Color3 = Color3.Gray(),\r\n        gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer,\r\n        parent: Nullable<PositionGizmo> = null,\r\n        thickness: number = 1,\r\n        hoverColor: Color3 = Color3.Yellow(),\r\n        disableColor: Color3 = Color3.Gray()\r\n    ) {\r\n        super(gizmoLayer);\r\n        this._parent = parent;\r\n\r\n        // Create Material\r\n        this._coloredMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._coloredMaterial.diffuseColor = color;\r\n        this._coloredMaterial.specularColor = color.subtract(new Color3(0.1, 0.1, 0.1));\r\n\r\n        this._hoverMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._hoverMaterial.diffuseColor = hoverColor;\r\n\r\n        this._disableMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._disableMaterial.diffuseColor = disableColor;\r\n        this._disableMaterial.alpha = 0.4;\r\n\r\n        // Build Mesh + Collider\r\n        const arrow = AxisDragGizmo._CreateArrow(gizmoLayer.utilityLayerScene, this._coloredMaterial, thickness);\r\n        const collider = AxisDragGizmo._CreateArrow(gizmoLayer.utilityLayerScene, this._coloredMaterial, thickness + 4, true);\r\n\r\n        // Add to Root Node\r\n        this._gizmoMesh = new Mesh(\"\", gizmoLayer.utilityLayerScene);\r\n        this._gizmoMesh.addChild(arrow as Mesh);\r\n        this._gizmoMesh.addChild(collider as Mesh);\r\n\r\n        this._gizmoMesh.lookAt(this._rootMesh.position.add(dragAxis));\r\n        this._gizmoMesh.scaling.scaleInPlace(1 / 3);\r\n        this._gizmoMesh.parent = this._rootMesh;\r\n\r\n        let currentSnapDragDistance = 0;\r\n        const tmpSnapEvent = { snapDistance: 0 };\r\n        // Add drag behavior to handle events when the gizmo is dragged\r\n        this.dragBehavior = new PointerDragBehavior({ dragAxis: dragAxis });\r\n        this.dragBehavior.moveAttached = false;\r\n        this.dragBehavior.updateDragPlane = false;\r\n        this._rootMesh.addBehavior(this.dragBehavior);\r\n\r\n        this.dragBehavior.onDragObservable.add((event) => {\r\n            if (this.attachedNode) {\r\n                // Keep world translation and use it to update world transform\r\n                // if the node has parent, the local transform properties (position, rotation, scale)\r\n                // will be recomputed in _matrixChanged function\r\n\r\n                let matrixChanged: boolean = false;\r\n                // Transform delta by additionalTransformNode world matrix if present\r\n                let delta = event.delta;\r\n                if (this._additionalTransformNode) {\r\n                    const additionalInverseMatrix = TmpVectors.Matrix[0];\r\n                    this._additionalTransformNode.getWorldMatrix().invertToRef(additionalInverseMatrix);\r\n                    Vector3.TransformNormalToRef(event.delta, additionalInverseMatrix, TmpVectors.Vector3[3]);\r\n                    delta = TmpVectors.Vector3[3];\r\n                }\r\n                // Snapping logic\r\n                if (this.snapDistance == 0) {\r\n                    this.attachedNode.getWorldMatrix().getTranslationToRef(TmpVectors.Vector3[2]);\r\n                    TmpVectors.Vector3[2].addInPlace(delta);\r\n                    if (this.dragBehavior.validateDrag(TmpVectors.Vector3[2])) {\r\n                        if ((this.attachedNode as any).position) {\r\n                            // Required for nodes like lights\r\n                            (this.attachedNode as any).position.addInPlaceFromFloats(delta.x, delta.y, delta.z);\r\n                        }\r\n\r\n                        // use _worldMatrix to not force a matrix update when calling GetWorldMatrix especially with Cameras\r\n                        this.attachedNode.getWorldMatrix().addTranslationFromFloats(delta.x, delta.y, delta.z);\r\n                        this.attachedNode.updateCache();\r\n                        matrixChanged = true;\r\n                    }\r\n                } else {\r\n                    currentSnapDragDistance += event.dragDistance;\r\n                    if (Math.abs(currentSnapDragDistance) > this.snapDistance) {\r\n                        const dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / this.snapDistance);\r\n                        currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;\r\n                        delta.normalizeToRef(TmpVectors.Vector3[1]);\r\n                        TmpVectors.Vector3[1].scaleInPlace(this.snapDistance * dragSteps);\r\n\r\n                        this.attachedNode.getWorldMatrix().getTranslationToRef(TmpVectors.Vector3[2]);\r\n                        TmpVectors.Vector3[2].addInPlace(TmpVectors.Vector3[1]);\r\n                        if (this.dragBehavior.validateDrag(TmpVectors.Vector3[2])) {\r\n                            this.attachedNode.getWorldMatrix().addTranslationFromFloats(TmpVectors.Vector3[1].x, TmpVectors.Vector3[1].y, TmpVectors.Vector3[1].z);\r\n                            this.attachedNode.updateCache();\r\n                            tmpSnapEvent.snapDistance = this.snapDistance * dragSteps * Math.sign(currentSnapDragDistance);\r\n                            this.onSnapObservable.notifyObservers(tmpSnapEvent);\r\n                            matrixChanged = true;\r\n                        }\r\n                    }\r\n                }\r\n                if (matrixChanged) {\r\n                    this._matrixChanged();\r\n                }\r\n            }\r\n        });\r\n        this.dragBehavior.onDragStartObservable.add(() => {\r\n            this._dragging = true;\r\n        });\r\n        this.dragBehavior.onDragEndObservable.add(() => {\r\n            this._dragging = false;\r\n        });\r\n\r\n        const light = gizmoLayer._getSharedGizmoLight();\r\n        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(this._rootMesh.getChildMeshes(false));\r\n\r\n        const cache: GizmoAxisCache = {\r\n            gizmoMeshes: arrow.getChildMeshes(),\r\n            colliderMeshes: collider.getChildMeshes(),\r\n            material: this._coloredMaterial,\r\n            hoverMaterial: this._hoverMaterial,\r\n            disableMaterial: this._disableMaterial,\r\n            active: false,\r\n            dragBehavior: this.dragBehavior,\r\n        };\r\n        this._parent?.addToAxisCache(collider as Mesh, cache);\r\n\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (this._customMeshSet) {\r\n                return;\r\n            }\r\n            this._isHovered = !!(cache.colliderMeshes.indexOf(<Mesh>pointerInfo?.pickInfo?.pickedMesh) != -1);\r\n            if (!this._parent) {\r\n                const material = this.dragBehavior.enabled ? (this._isHovered || this._dragging ? this._hoverMaterial : this._coloredMaterial) : this._disableMaterial;\r\n                this._setGizmoMeshMaterial(cache.gizmoMeshes, material);\r\n            }\r\n        });\r\n\r\n        this.dragBehavior.onEnabledObservable.add((newState) => {\r\n            this._setGizmoMeshMaterial(cache.gizmoMeshes, newState ? cache.material : cache.disableMaterial);\r\n        });\r\n    }\r\n\r\n    protected override _attachedNodeChanged(value: Nullable<Node>) {\r\n        if (this.dragBehavior) {\r\n            this.dragBehavior.enabled = value ? true : false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the gizmo is enabled\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        this._isEnabled = value;\r\n        if (!value) {\r\n            this.attachedMesh = null;\r\n            this.attachedNode = null;\r\n        } else {\r\n            if (this._parent) {\r\n                this.attachedMesh = this._parent.attachedMesh;\r\n                this.attachedNode = this._parent.attachedNode;\r\n            }\r\n        }\r\n    }\r\n\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        this.onSnapObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this.dragBehavior.detach();\r\n        if (this._gizmoMesh) {\r\n            this._gizmoMesh.dispose();\r\n        }\r\n        const mats = [this._coloredMaterial, this._hoverMaterial, this._disableMaterial];\r\n        for (const matl of mats) {\r\n            if (matl) {\r\n                matl.dispose();\r\n            }\r\n        }\r\n        super.dispose();\r\n    }\r\n}\r\n","import { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { AxisDragGizmo } from \"../Gizmos/axisDragGizmo\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * The Axes viewer will show 3 axes in a specific point in space\r\n * @see https://doc.babylonjs.com/toolsAndResources/utilities/World_Axes\r\n */\r\nexport class AxesViewer {\r\n    private _xAxis: TransformNode;\r\n    private _yAxis: TransformNode;\r\n    private _zAxis: TransformNode;\r\n    private _scaleLinesFactor = 4;\r\n    private _instanced = false;\r\n\r\n    /**\r\n     * Gets the hosting scene\r\n     */\r\n    public scene: Nullable<Scene> = null;\r\n\r\n    private _scaleLines = 1;\r\n    /**\r\n     * Gets or sets a number used to scale line length\r\n     */\r\n    public get scaleLines() {\r\n        return this._scaleLines;\r\n    }\r\n\r\n    public set scaleLines(value: number) {\r\n        this._scaleLines = value;\r\n        this._xAxis.scaling.setAll(this._scaleLines * this._scaleLinesFactor);\r\n        this._yAxis.scaling.setAll(this._scaleLines * this._scaleLinesFactor);\r\n        this._zAxis.scaling.setAll(this._scaleLines * this._scaleLinesFactor);\r\n    }\r\n\r\n    /** Gets the node hierarchy used to render x-axis */\r\n    public get xAxis(): TransformNode {\r\n        return this._xAxis;\r\n    }\r\n\r\n    /** Gets the node hierarchy used to render y-axis */\r\n    public get yAxis(): TransformNode {\r\n        return this._yAxis;\r\n    }\r\n\r\n    /** Gets the node hierarchy used to render z-axis */\r\n    public get zAxis(): TransformNode {\r\n        return this._zAxis;\r\n    }\r\n\r\n    /**\r\n     * Creates a new AxesViewer\r\n     * @param scene defines the hosting scene\r\n     * @param scaleLines defines a number used to scale line length (1 by default)\r\n     * @param renderingGroupId defines a number used to set the renderingGroupId of the meshes (2 by default)\r\n     * @param xAxis defines the node hierarchy used to render the x-axis\r\n     * @param yAxis defines the node hierarchy used to render the y-axis\r\n     * @param zAxis defines the node hierarchy used to render the z-axis\r\n     * @param lineThickness The line thickness to use when creating the arrow. defaults to 1.\r\n     */\r\n    constructor(scene?: Scene, scaleLines = 1, renderingGroupId: Nullable<number> = 2, xAxis?: TransformNode, yAxis?: TransformNode, zAxis?: TransformNode, lineThickness = 1) {\r\n        scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        if (!xAxis) {\r\n            const redColoredMaterial = new StandardMaterial(\"xAxisMaterial\", scene);\r\n            redColoredMaterial.disableLighting = true;\r\n            redColoredMaterial.emissiveColor = Color3.Red().scale(0.5);\r\n            xAxis = AxisDragGizmo._CreateArrow(scene, redColoredMaterial, lineThickness);\r\n        }\r\n\r\n        if (!yAxis) {\r\n            const greenColoredMaterial = new StandardMaterial(\"yAxisMaterial\", scene);\r\n            greenColoredMaterial.disableLighting = true;\r\n            greenColoredMaterial.emissiveColor = Color3.Green().scale(0.5);\r\n            yAxis = AxisDragGizmo._CreateArrow(scene, greenColoredMaterial, lineThickness);\r\n        }\r\n\r\n        if (!zAxis) {\r\n            const blueColoredMaterial = new StandardMaterial(\"zAxisMaterial\", scene);\r\n            blueColoredMaterial.disableLighting = true;\r\n            blueColoredMaterial.emissiveColor = Color3.Blue().scale(0.5);\r\n            zAxis = AxisDragGizmo._CreateArrow(scene, blueColoredMaterial, lineThickness);\r\n        }\r\n\r\n        this._xAxis = xAxis;\r\n        this._yAxis = yAxis;\r\n        this._zAxis = zAxis;\r\n\r\n        this.scaleLines = scaleLines;\r\n\r\n        if (renderingGroupId != null) {\r\n            AxesViewer._SetRenderingGroupId(this._xAxis, renderingGroupId);\r\n            AxesViewer._SetRenderingGroupId(this._yAxis, renderingGroupId);\r\n            AxesViewer._SetRenderingGroupId(this._zAxis, renderingGroupId);\r\n        }\r\n\r\n        this.scene = scene;\r\n        this.update(new Vector3(), Vector3.Right(), Vector3.Up(), Vector3.Forward());\r\n    }\r\n\r\n    /**\r\n     * Force the viewer to update\r\n     * @param position defines the position of the viewer\r\n     * @param xaxis defines the x axis of the viewer\r\n     * @param yaxis defines the y axis of the viewer\r\n     * @param zaxis defines the z axis of the viewer\r\n     */\r\n    public update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void {\r\n        this._xAxis.position.copyFrom(position);\r\n        this._xAxis.setDirection(xaxis);\r\n\r\n        this._yAxis.position.copyFrom(position);\r\n        this._yAxis.setDirection(yaxis);\r\n\r\n        this._zAxis.position.copyFrom(position);\r\n        this._zAxis.setDirection(zaxis);\r\n    }\r\n\r\n    /**\r\n     * Creates an instance of this axes viewer.\r\n     * @returns a new axes viewer with instanced meshes\r\n     */\r\n    public createInstance(): AxesViewer {\r\n        const xAxis = AxisDragGizmo._CreateArrowInstance(this.scene!, this._xAxis);\r\n        const yAxis = AxisDragGizmo._CreateArrowInstance(this.scene!, this._yAxis);\r\n        const zAxis = AxisDragGizmo._CreateArrowInstance(this.scene!, this._zAxis);\r\n        const axesViewer = new AxesViewer(this.scene!, this.scaleLines, null, xAxis, yAxis, zAxis);\r\n        axesViewer._instanced = true;\r\n        return axesViewer;\r\n    }\r\n\r\n    /** Releases resources */\r\n    public dispose() {\r\n        if (this._xAxis) {\r\n            this._xAxis.dispose(false, !this._instanced);\r\n        }\r\n\r\n        if (this._yAxis) {\r\n            this._yAxis.dispose(false, !this._instanced);\r\n        }\r\n\r\n        if (this._zAxis) {\r\n            this._zAxis.dispose(false, !this._instanced);\r\n        }\r\n\r\n        this.scene = null;\r\n    }\r\n\r\n    private static _SetRenderingGroupId(node: TransformNode, id: number) {\r\n        const meshes = node.getChildMeshes();\r\n        for (const mesh of meshes) {\r\n            mesh.renderingGroupId = id;\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { AxesViewer } from \"../Debug/axesViewer\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type Bone } from \"../Bones/bone\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Axis } from \"../Maths/math.axis\";\r\n\r\n/**\r\n * The BoneAxesViewer will attach 3 axes to a specific bone of a specific mesh\r\n * @see demo here: https://www.babylonjs-playground.com/#0DE8F4#8\r\n */\r\nexport class BoneAxesViewer extends AxesViewer {\r\n    /**\r\n     * Gets or sets the target mesh where to display the axes viewer\r\n     */\r\n    public mesh: Nullable<Mesh>;\r\n    /**\r\n     * Gets or sets the target bone where to display the axes viewer\r\n     */\r\n    public bone: Nullable<Bone>;\r\n\r\n    /** Gets current position */\r\n    public pos = Vector3.Zero();\r\n    /** Gets direction of X axis */\r\n    public xaxis = Vector3.Zero();\r\n    /** Gets direction of Y axis */\r\n    public yaxis = Vector3.Zero();\r\n    /** Gets direction of Z axis */\r\n    public zaxis = Vector3.Zero();\r\n\r\n    /**\r\n     * Creates a new BoneAxesViewer\r\n     * @param scene defines the hosting scene\r\n     * @param bone defines the target bone\r\n     * @param mesh defines the target mesh\r\n     * @param scaleLines defines a scaling factor for line length (1 by default)\r\n     */\r\n    constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines = 1) {\r\n        super(scene, scaleLines);\r\n\r\n        this.mesh = mesh;\r\n        this.bone = bone;\r\n    }\r\n\r\n    /**\r\n     * Force the viewer to update\r\n     */\r\n    public override update(): void {\r\n        if (!this.mesh || !this.bone) {\r\n            return;\r\n        }\r\n\r\n        const bone = this.bone;\r\n        bone.getAbsolutePositionToRef(this.mesh, this.pos);\r\n        bone.getDirectionToRef(Axis.X, this.mesh, this.xaxis);\r\n        bone.getDirectionToRef(Axis.Y, this.mesh, this.yaxis);\r\n        bone.getDirectionToRef(Axis.Z, this.mesh, this.zaxis);\r\n\r\n        super.update(this.pos, this.xaxis, this.yaxis, this.zaxis);\r\n    }\r\n\r\n    /** Releases resources */\r\n    public override dispose() {\r\n        if (this.mesh) {\r\n            this.mesh = null;\r\n            this.bone = null;\r\n\r\n            super.dispose();\r\n        }\r\n    }\r\n}\r\n","import { type Vector3 } from \"../../Maths/math.vector\";\r\nimport { type IPhysicsEnginePlugin } from \"./IPhysicsEnginePlugin\";\r\n/**\r\n * Interface for Physics-Joint data\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsJointData {\r\n    //Important for some engines, optional!\r\n    /**\r\n     * The main pivot of the joint\r\n     */\r\n    mainPivot?: Vector3;\r\n    /**\r\n     * The connected pivot of the joint\r\n     */\r\n    connectedPivot?: Vector3;\r\n    /**\r\n     * The main axis of the joint\r\n     */\r\n    mainAxis?: Vector3;\r\n    /**\r\n     * The connected axis of the joint\r\n     */\r\n    connectedAxis?: Vector3;\r\n    /**\r\n     * The collision of the joint\r\n     */\r\n    collision?: boolean;\r\n    /**\r\n     * Native Oimo/Cannon/Energy data\r\n     */\r\n    nativeParams?: any;\r\n}\r\n\r\n/**\r\n * This is a holder class for the physics joint created by the physics plugin\r\n * It holds a set of functions to control the underlying joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class PhysicsJoint {\r\n    private _physicsJoint: any;\r\n    protected _physicsPlugin: IPhysicsEnginePlugin;\r\n\r\n    /**\r\n     * Initializes the physics joint\r\n     * @param type The type of the physics joint\r\n     * @param jointData The data for the physics joint\r\n     */\r\n    constructor(\r\n        /**\r\n         * The type of the physics joint\r\n         */\r\n        public type: number,\r\n        /**\r\n         * The data for the physics joint\r\n         */\r\n        public jointData: PhysicsJointData\r\n    ) {\r\n        jointData.nativeParams = jointData.nativeParams || {};\r\n    }\r\n\r\n    /**\r\n     * Gets the physics joint\r\n     */\r\n    public get physicsJoint(): any {\r\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\r\n        return this._physicsJoint;\r\n    }\r\n\r\n    /**\r\n     * Sets the physics joint\r\n     */\r\n    public set physicsJoint(newJoint: any) {\r\n        this._physicsJoint = newJoint;\r\n    }\r\n\r\n    /**\r\n     * Sets the physics plugin\r\n     */\r\n    public set physicsPlugin(physicsPlugin: IPhysicsEnginePlugin) {\r\n        this._physicsPlugin = physicsPlugin;\r\n    }\r\n\r\n    /**\r\n     * Execute a function that is physics-plugin specific.\r\n     * @param {Function} func the function that will be executed.\r\n     *                        It accepts two parameters: the physics world and the physics joint\r\n     */\r\n    public executeNativeFunction(func: (world: any, physicsJoint: any) => void) {\r\n        func(this._physicsPlugin.world, this._physicsJoint);\r\n    }\r\n\r\n    //TODO check if the native joints are the same\r\n\r\n    //Joint Types\r\n    /**\r\n     * Distance-Joint type\r\n     */\r\n    public static DistanceJoint = 0;\r\n    /**\r\n     * Hinge-Joint type\r\n     */\r\n    public static HingeJoint = 1;\r\n    /**\r\n     * Ball-and-Socket joint type\r\n     */\r\n    public static BallAndSocketJoint = 2;\r\n    /**\r\n     * Wheel-Joint type\r\n     */\r\n    public static WheelJoint = 3;\r\n    /**\r\n     * Slider-Joint type\r\n     */\r\n    public static SliderJoint = 4;\r\n    //OIMO\r\n    /**\r\n     * Prismatic-Joint type\r\n     */\r\n    public static PrismaticJoint = 5;\r\n    //\r\n    /**\r\n     * Universal-Joint type\r\n     * ENERGY FTW! (compare with this - @see http://ode-wiki.org/wiki/index.php?title=Manual:_Joint_Types_and_Functions)\r\n     */\r\n    public static UniversalJoint = 6;\r\n    /**\r\n     * Hinge-Joint 2 type\r\n     */\r\n    public static Hinge2Joint = PhysicsJoint.WheelJoint;\r\n    //Cannon\r\n    /**\r\n     * Point to Point Joint type.  Similar to a Ball-Joint.  Different in parameters\r\n     */\r\n    public static PointToPointJoint = 8;\r\n    //Cannon only at the moment\r\n    /**\r\n     * Spring-Joint type\r\n     */\r\n    public static SpringJoint = 9;\r\n    /**\r\n     * Lock-Joint type\r\n     */\r\n    public static LockJoint = 10;\r\n}\r\n\r\n/**\r\n * A class representing a physics distance joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class DistanceJoint extends PhysicsJoint {\r\n    /**\r\n     *\r\n     * @param jointData The data for the Distance-Joint\r\n     */\r\n    constructor(jointData: DistanceJointData) {\r\n        super(PhysicsJoint.DistanceJoint, jointData);\r\n    }\r\n\r\n    /**\r\n     * Update the predefined distance.\r\n     * @param maxDistance The maximum preferred distance\r\n     * @param minDistance The minimum preferred distance\r\n     */\r\n    public updateDistance(maxDistance: number, minDistance?: number) {\r\n        this._physicsPlugin.updateDistanceJoint(this, maxDistance, minDistance);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a Motor-Enabled Joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class MotorEnabledJoint extends PhysicsJoint implements IMotorEnabledJoint {\r\n    /**\r\n     * Initializes the Motor-Enabled Joint\r\n     * @param type The type of the joint\r\n     * @param jointData The physical joint data for the joint\r\n     */\r\n    constructor(type: number, jointData: PhysicsJointData) {\r\n        super(type, jointData);\r\n    }\r\n\r\n    /**\r\n     * Set the motor values.\r\n     * Attention, this function is plugin specific. Engines won't react 100% the same.\r\n     * @param force the force to apply\r\n     * @param maxForce max force for this motor.\r\n     */\r\n    public setMotor(force?: number, maxForce?: number) {\r\n        this._physicsPlugin.setMotor(this, force || 0, maxForce);\r\n    }\r\n\r\n    /**\r\n     * Set the motor's limits.\r\n     * Attention, this function is plugin specific. Engines won't react 100% the same.\r\n     * @param upperLimit The upper limit of the motor\r\n     * @param lowerLimit The lower limit of the motor\r\n     */\r\n    public setLimit(upperLimit: number, lowerLimit?: number) {\r\n        this._physicsPlugin.setLimit(this, upperLimit, lowerLimit);\r\n    }\r\n}\r\n\r\n/**\r\n * This class represents a single physics Hinge-Joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class HingeJoint extends MotorEnabledJoint {\r\n    /**\r\n     * Initializes the Hinge-Joint\r\n     * @param jointData The joint data for the Hinge-Joint\r\n     */\r\n    constructor(jointData: PhysicsJointData) {\r\n        super(PhysicsJoint.HingeJoint, jointData);\r\n    }\r\n\r\n    /**\r\n     * Set the motor values.\r\n     * Attention, this function is plugin specific. Engines won't react 100% the same.\r\n     * @param {number} force the force to apply\r\n     * @param {number} maxForce max force for this motor.\r\n     */\r\n    public override setMotor(force?: number, maxForce?: number) {\r\n        this._physicsPlugin.setMotor(this, force || 0, maxForce);\r\n    }\r\n\r\n    /**\r\n     * Set the motor's limits.\r\n     * Attention, this function is plugin specific. Engines won't react 100% the same.\r\n     * @param upperLimit The upper limit of the motor\r\n     * @param lowerLimit The lower limit of the motor\r\n     */\r\n    public override setLimit(upperLimit: number, lowerLimit?: number) {\r\n        this._physicsPlugin.setLimit(this, upperLimit, lowerLimit);\r\n    }\r\n}\r\n\r\n/**\r\n * This class represents a dual hinge physics joint (same as wheel joint)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class Hinge2Joint extends MotorEnabledJoint {\r\n    /**\r\n     * Initializes the Hinge2-Joint\r\n     * @param jointData The joint data for the Hinge2-Joint\r\n     */\r\n    constructor(jointData: PhysicsJointData) {\r\n        super(PhysicsJoint.Hinge2Joint, jointData);\r\n    }\r\n\r\n    /**\r\n     * Set the motor values.\r\n     * Attention, this function is plugin specific. Engines won't react 100% the same.\r\n     * @param targetSpeed the speed the motor is to reach\r\n     * @param maxForce max force for this motor.\r\n     * @param motorIndex motor's index, 0 or 1.\r\n     */\r\n    public override setMotor(targetSpeed?: number, maxForce?: number, motorIndex: number = 0) {\r\n        this._physicsPlugin.setMotor(this, targetSpeed || 0, maxForce, motorIndex);\r\n    }\r\n\r\n    /**\r\n     * Set the motor limits.\r\n     * Attention, this function is plugin specific. Engines won't react 100% the same.\r\n     * @param upperLimit the upper limit\r\n     * @param lowerLimit lower limit\r\n     * @param motorIndex the motor's index, 0 or 1.\r\n     */\r\n    public override setLimit(upperLimit: number, lowerLimit?: number, motorIndex: number = 0) {\r\n        this._physicsPlugin.setLimit(this, upperLimit, lowerLimit, motorIndex);\r\n    }\r\n}\r\n\r\n/**\r\n * Interface for a motor enabled joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport interface IMotorEnabledJoint {\r\n    /**\r\n     * Physics joint\r\n     */\r\n    physicsJoint: any;\r\n    /**\r\n     * Sets the motor of the motor-enabled joint\r\n     * @param force The force of the motor\r\n     * @param maxForce The maximum force of the motor\r\n     * @param motorIndex The index of the motor\r\n     */\r\n    setMotor(force?: number, maxForce?: number, motorIndex?: number): void;\r\n    /**\r\n     * Sets the limit of the motor\r\n     * @param upperLimit The upper limit of the motor\r\n     * @param lowerLimit The lower limit of the motor\r\n     * @param motorIndex The index of the motor\r\n     */\r\n    setLimit(upperLimit: number, lowerLimit?: number, motorIndex?: number): void;\r\n}\r\n\r\n/**\r\n * Joint data for a Distance-Joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface DistanceJointData extends PhysicsJointData {\r\n    /**\r\n     * Max distance the 2 joint objects can be apart\r\n     */\r\n    maxDistance: number;\r\n    //Oimo - minDistance\r\n    //Cannon - maxForce\r\n}\r\n\r\n/**\r\n * Joint data from a spring joint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SpringJointData extends PhysicsJointData {\r\n    /**\r\n     * Length of the spring\r\n     */\r\n    length: number;\r\n    /**\r\n     * Stiffness of the spring\r\n     */\r\n    stiffness: number;\r\n    /**\r\n     * Damping of the spring\r\n     */\r\n    damping: number;\r\n    /** this callback will be called when applying the force to the impostors. */\r\n    forceApplicationCallback: () => void;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type IndicesArray, type FloatArray } from \"../../types\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { BuildArray } from \"../../Misc/arrayTools\";\r\nimport { Vector3, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type Matrix } from \"../../Maths/math.vector\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Bone } from \"../../Bones/bone.pure\";\r\nimport { type BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type PhysicsEngine as PhysicsEngineV1 } from \"./physicsEngine\";\r\nimport { PhysicsJoint, type PhysicsJointData } from \"./physicsJoint\";\r\n\r\nimport { Space } from \"../../Maths/math.axis\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unsafe-return */\r\n\r\n/**\r\n * The interface for the physics imposter parameters\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsImpostorParameters {\r\n    /**\r\n     * The mass of the physics imposter\r\n     */\r\n    mass: number;\r\n    /**\r\n     * The friction of the physics imposter\r\n     */\r\n    friction?: number;\r\n    /**\r\n     * The coefficient of restitution of the physics imposter\r\n     */\r\n    restitution?: number;\r\n    /**\r\n     * The native options of the physics imposter\r\n     */\r\n    nativeOptions?: any;\r\n    /**\r\n     * Specifies if the parent should be ignored\r\n     */\r\n    ignoreParent?: boolean;\r\n    /**\r\n     * Specifies if bi-directional transformations should be disabled\r\n     */\r\n    disableBidirectionalTransformation?: boolean;\r\n    /**\r\n     * The pressure inside the physics imposter, soft object only\r\n     */\r\n    pressure?: number;\r\n    /**\r\n     * The stiffness the physics imposter, soft object only\r\n     */\r\n    stiffness?: number;\r\n    /**\r\n     * The number of iterations used in maintaining consistent vertex velocities, soft object only\r\n     */\r\n    velocityIterations?: number;\r\n    /**\r\n     * The number of iterations used in maintaining consistent vertex positions, soft object only\r\n     */\r\n    positionIterations?: number;\r\n    /**\r\n     * The number used to fix points on a cloth (0, 1, 2, 4, 8) or rope (0, 1, 2) only\r\n     * 0 None, 1, back left or top, 2, back right or bottom, 4, front left, 8, front right\r\n     * Add to fix multiple points\r\n     */\r\n    fixedPoints?: number;\r\n    /**\r\n     * The collision margin around a soft object\r\n     */\r\n    margin?: number;\r\n    /**\r\n     * The collision margin around a soft object\r\n     */\r\n    damping?: number;\r\n    /**\r\n     * The path for a rope based on an extrusion\r\n     */\r\n    path?: any;\r\n    /**\r\n     * The shape of an extrusion used for a rope based on an extrusion\r\n     */\r\n    shape?: any;\r\n}\r\n\r\n/**\r\n * Interface for a physics-enabled object\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport interface IPhysicsEnabledObject {\r\n    /**\r\n     * The position of the physics-enabled object\r\n     */\r\n    position: Vector3;\r\n    /**\r\n     * The rotation of the physics-enabled object\r\n     */\r\n    rotationQuaternion: Nullable<Quaternion>;\r\n    /**\r\n     * The scale of the physics-enabled object\r\n     */\r\n    scaling: Vector3;\r\n    /**\r\n     * The rotation of the physics-enabled object\r\n     */\r\n    rotation?: Vector3;\r\n    /**\r\n     * The parent of the physics-enabled object\r\n     */\r\n    parent?: any;\r\n    /**\r\n     * The bounding info of the physics-enabled object\r\n     * @returns The bounding info of the physics-enabled object\r\n     */\r\n    getBoundingInfo(): BoundingInfo;\r\n    /**\r\n     * Computes the world matrix\r\n     * @param force Specifies if the world matrix should be computed by force\r\n     * @returns A world matrix\r\n     */\r\n    computeWorldMatrix(force: boolean): Matrix;\r\n    /**\r\n     * Gets the world matrix\r\n     * @returns A world matrix\r\n     */\r\n    getWorldMatrix?(): Matrix;\r\n    /**\r\n     * Gets the child meshes\r\n     * @param directDescendantsOnly Specifies if only direct-descendants should be obtained\r\n     * @returns An array of abstract meshes\r\n     */\r\n    getChildMeshes?(directDescendantsOnly?: boolean): Array<AbstractMesh>;\r\n    /**\r\n     * Gets the vertex data\r\n     * @param kind The type of vertex data\r\n     * @returns A nullable array of numbers, or a float32 array\r\n     */\r\n    getVerticesData(kind: string): Nullable<FloatArray>;\r\n    /**\r\n     * Gets the indices from the mesh\r\n     * @returns A nullable array of index arrays\r\n     */\r\n    getIndices?(): Nullable<IndicesArray>;\r\n    /**\r\n     * Gets the scene from the mesh\r\n     * @returns the indices array or null\r\n     */\r\n    getScene?(): Scene;\r\n    /**\r\n     * Gets the absolute position from the mesh\r\n     * @returns the absolute position\r\n     */\r\n    getAbsolutePosition(): Vector3;\r\n    /**\r\n     * Gets the absolute pivot point from the mesh\r\n     * @returns the absolute pivot point\r\n     */\r\n    getAbsolutePivotPoint(): Vector3;\r\n    /**\r\n     * Rotates the mesh\r\n     * @param axis The axis of rotation\r\n     * @param amount The amount of rotation\r\n     * @param space The space of the rotation\r\n     * @returns The rotation transform node\r\n     */\r\n    rotate(axis: Vector3, amount: number, space?: Space): TransformNode;\r\n    /**\r\n     * Translates the mesh\r\n     * @param axis The axis of translation\r\n     * @param distance The distance of translation\r\n     * @param space The space of the translation\r\n     * @returns The transform node\r\n     */\r\n    translate(axis: Vector3, distance: number, space?: Space): TransformNode;\r\n    /**\r\n     * Sets the absolute position of the mesh\r\n     * @param absolutePosition The absolute position of the mesh\r\n     * @returns The transform node\r\n     */\r\n    setAbsolutePosition(absolutePosition: Vector3): TransformNode;\r\n    /**\r\n     * Gets the class name of the mesh\r\n     * @returns The class name\r\n     */\r\n    getClassName(): string;\r\n}\r\n\r\n/**\r\n * Represents a physics imposter\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class PhysicsImpostor {\r\n    /**\r\n     * The default object size of the imposter\r\n     */\r\n    public static DEFAULT_OBJECT_SIZE: Vector3 = /*#__PURE__*/ new Vector3(1, 1, 1);\r\n\r\n    /**\r\n     * The identity quaternion of the imposter\r\n     */\r\n    public static IDENTITY_QUATERNION = /*#__PURE__*/ Quaternion.Identity();\r\n\r\n    /** @internal */\r\n    public _pluginData: any = {};\r\n\r\n    private _physicsEngine: Nullable<PhysicsEngineV1>;\r\n    //The native cannon/oimo/energy physics body object.\r\n    private _physicsBody: any;\r\n    private _bodyUpdateRequired: boolean = false;\r\n\r\n    private _onBeforePhysicsStepCallbacks = new Array<(impostor: PhysicsImpostor) => void>();\r\n    private _onAfterPhysicsStepCallbacks = new Array<(impostor: PhysicsImpostor) => void>();\r\n    /** @internal */\r\n    public _onPhysicsCollideCallbacks: Array<{\r\n        callback: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor, point: Nullable<Vector3>, distance: number, impulse: number, normal: Nullable<Vector3>) => void;\r\n        otherImpostors: Array<PhysicsImpostor>;\r\n    }> = [];\r\n\r\n    private _deltaPosition: Vector3 = Vector3.Zero();\r\n    private _deltaRotation: Quaternion;\r\n    private _deltaRotationConjugated: Quaternion;\r\n\r\n    /** @internal */\r\n    public _isFromLine: boolean;\r\n\r\n    //If set, this is this impostor's parent\r\n    private _parent: Nullable<PhysicsImpostor>;\r\n\r\n    private _isDisposed = false;\r\n\r\n    private static _TmpVecs: Vector3[] = /*#__PURE__*/ BuildArray(3, Vector3.Zero);\r\n    private static _TmpQuat: Quaternion = /*#__PURE__*/ Quaternion.Identity();\r\n\r\n    /**\r\n     * Specifies if the physics imposter is disposed\r\n     */\r\n    get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Gets the mass of the physics imposter\r\n     */\r\n    get mass(): number {\r\n        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyMass(this) : 0;\r\n    }\r\n\r\n    set mass(value: number) {\r\n        this.setMass(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the coefficient of friction\r\n     */\r\n    get friction(): number {\r\n        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyFriction(this) : 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the coefficient of friction\r\n     */\r\n    set friction(value: number) {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        this._physicsEngine.getPhysicsPlugin().setBodyFriction(this, value);\r\n    }\r\n\r\n    /**\r\n     * Gets the coefficient of restitution\r\n     */\r\n    get restitution(): number {\r\n        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this) : 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the coefficient of restitution\r\n     */\r\n    set restitution(value: number) {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        this._physicsEngine.getPhysicsPlugin().setBodyRestitution(this, value);\r\n    }\r\n\r\n    /**\r\n     * Gets the pressure of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    get pressure(): number {\r\n        if (!this._physicsEngine) {\r\n            return 0;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.setBodyPressure) {\r\n            return 0;\r\n        }\r\n        return plugin.getBodyPressure!(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the pressure of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    set pressure(value: number) {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.setBodyPressure) {\r\n            return;\r\n        }\r\n        plugin.setBodyPressure(this, value);\r\n    }\r\n\r\n    /**\r\n     * Gets the stiffness of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    get stiffness(): number {\r\n        if (!this._physicsEngine) {\r\n            return 0;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.getBodyStiffness) {\r\n            return 0;\r\n        }\r\n        return plugin.getBodyStiffness(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the stiffness of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    set stiffness(value: number) {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.setBodyStiffness) {\r\n            return;\r\n        }\r\n        plugin.setBodyStiffness(this, value);\r\n    }\r\n\r\n    /**\r\n     * Gets the velocityIterations of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    get velocityIterations(): number {\r\n        if (!this._physicsEngine) {\r\n            return 0;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.getBodyVelocityIterations) {\r\n            return 0;\r\n        }\r\n        return plugin.getBodyVelocityIterations(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the velocityIterations of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    set velocityIterations(value: number) {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.setBodyVelocityIterations) {\r\n            return;\r\n        }\r\n        plugin.setBodyVelocityIterations(this, value);\r\n    }\r\n\r\n    /**\r\n     * Gets the positionIterations of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    get positionIterations(): number {\r\n        if (!this._physicsEngine) {\r\n            return 0;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.getBodyPositionIterations) {\r\n            return 0;\r\n        }\r\n        return plugin.getBodyPositionIterations(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the positionIterations of a soft body; only supported by the AmmoJSPlugin\r\n     */\r\n    set positionIterations(value: number) {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.setBodyPositionIterations) {\r\n            return;\r\n        }\r\n        plugin.setBodyPositionIterations(this, value);\r\n    }\r\n\r\n    /**\r\n     * The unique id of the physics imposter\r\n     * set by the physics engine when adding this impostor to the array\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public soft: boolean = false;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public segments: number = 0;\r\n\r\n    private _joints: Array<{\r\n        joint: PhysicsJoint;\r\n        otherImpostor: PhysicsImpostor;\r\n    }>;\r\n\r\n    /**\r\n     * Initializes the physics imposter\r\n     * @param object The physics-enabled object used as the physics imposter\r\n     * @param type The type of the physics imposter. Types are available as static members of this class.\r\n     * @param _options The options for the physics imposter\r\n     * @param _scene The Babylon scene\r\n     */\r\n    constructor(\r\n        /**\r\n         * The physics-enabled object used as the physics imposter\r\n         */\r\n        public object: IPhysicsEnabledObject,\r\n        /**\r\n         * The type of the physics imposter\r\n         */\r\n        public type: number,\r\n        private _options: PhysicsImpostorParameters = { mass: 0 },\r\n        private _scene?: Scene\r\n    ) {\r\n        //sanity check!\r\n        if (!this.object) {\r\n            Logger.Error(\"No object was provided. A physics object is obligatory\");\r\n            return;\r\n        }\r\n        if (this.object.parent && _options.mass !== 0) {\r\n            Logger.Warn(\"A physics impostor has been created for an object which has a parent. Babylon physics currently works in local space so unexpected issues may occur.\");\r\n        }\r\n\r\n        // Legacy support for old syntax.\r\n        if (!this._scene && object.getScene) {\r\n            this._scene = object.getScene();\r\n        }\r\n\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n\r\n        if (this.type > 100) {\r\n            this.soft = true;\r\n        }\r\n\r\n        this._physicsEngine = this._scene.getPhysicsEngine() as any;\r\n        if (!this._physicsEngine) {\r\n            Logger.Error(\"Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.\");\r\n        } else {\r\n            //set the object's quaternion, if not set\r\n            if (!this.object.rotationQuaternion) {\r\n                if (this.object.rotation) {\r\n                    this.object.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.object.rotation.y, this.object.rotation.x, this.object.rotation.z);\r\n                } else {\r\n                    this.object.rotationQuaternion = new Quaternion();\r\n                }\r\n            }\r\n            //default options params\r\n            this._options.mass = _options.mass === void 0 ? 0 : _options.mass;\r\n            this._options.friction = _options.friction === void 0 ? 0.2 : _options.friction;\r\n            this._options.restitution = _options.restitution === void 0 ? 0.2 : _options.restitution;\r\n            if (this.soft) {\r\n                //softbody mass must be above 0;\r\n                this._options.mass = this._options.mass > 0 ? this._options.mass : 1;\r\n                this._options.pressure = _options.pressure === void 0 ? 200 : _options.pressure;\r\n                this._options.stiffness = _options.stiffness === void 0 ? 1 : _options.stiffness;\r\n                this._options.velocityIterations = _options.velocityIterations === void 0 ? 20 : _options.velocityIterations;\r\n                this._options.positionIterations = _options.positionIterations === void 0 ? 20 : _options.positionIterations;\r\n                this._options.fixedPoints = _options.fixedPoints === void 0 ? 0 : _options.fixedPoints;\r\n                this._options.margin = _options.margin === void 0 ? 0 : _options.margin;\r\n                this._options.damping = _options.damping === void 0 ? 0 : _options.damping;\r\n                this._options.path = _options.path === void 0 ? null : _options.path;\r\n                this._options.shape = _options.shape === void 0 ? null : _options.shape;\r\n            }\r\n            this._joints = [];\r\n            //If the mesh has a parent, don't initialize the physicsBody. Instead wait for the parent to do that.\r\n            if (!this.object.parent || this._options.ignoreParent) {\r\n                this._init();\r\n            } else if (this.object.parent.physicsImpostor) {\r\n                Logger.Warn(\"You must affect impostors to children before affecting impostor to parent.\");\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This function will completely initialize this impostor.\r\n     * It will create a new body - but only if this mesh has no parent.\r\n     * If it has, this impostor will not be used other than to define the impostor\r\n     * of the child mesh.\r\n     * @internal\r\n     */\r\n    public _init() {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n\r\n        this._physicsEngine.removeImpostor(this);\r\n        this.physicsBody = null;\r\n        this._parent = this._parent || this._getPhysicsParent();\r\n        if (!this._isDisposed && (!this.parent || this._options.ignoreParent)) {\r\n            this._physicsEngine.addImpostor(this);\r\n        }\r\n    }\r\n\r\n    private _getPhysicsParent(): Nullable<PhysicsImpostor> {\r\n        if (this.object.parent instanceof AbstractMesh) {\r\n            const parentMesh: AbstractMesh = this.object.parent;\r\n            return parentMesh.physicsImpostor;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Should a new body be generated.\r\n     * @returns boolean specifying if body initialization is required\r\n     */\r\n    public isBodyInitRequired(): boolean {\r\n        return this._bodyUpdateRequired || (!this._physicsBody && (!this._parent || !!this._options.ignoreParent));\r\n    }\r\n\r\n    /**\r\n     * Sets the updated scaling\r\n     */\r\n    public setScalingUpdated() {\r\n        this.forceUpdate();\r\n    }\r\n\r\n    /**\r\n     * Force a regeneration of this or the parent's impostor's body.\r\n     * Use with caution - This will remove all previously-instantiated joints.\r\n     */\r\n    public forceUpdate() {\r\n        this._init();\r\n        if (this.parent && !this._options.ignoreParent) {\r\n            this.parent.forceUpdate();\r\n        }\r\n    }\r\n\r\n    /*public get mesh(): AbstractMesh {\r\n        return this._mesh;\r\n    }*/\r\n\r\n    /**\r\n     * Gets the body that holds this impostor. Either its own, or its parent.\r\n     */\r\n    public get physicsBody(): any {\r\n        return this._parent && !this._options.ignoreParent ? this._parent.physicsBody : this._physicsBody;\r\n    }\r\n\r\n    /**\r\n     * Get the parent of the physics imposter\r\n     * @returns Physics imposter or null\r\n     */\r\n    public get parent(): Nullable<PhysicsImpostor> {\r\n        return !this._options.ignoreParent && this._parent ? this._parent : null;\r\n    }\r\n\r\n    /**\r\n     * Sets the parent of the physics imposter\r\n     */\r\n    public set parent(value: Nullable<PhysicsImpostor>) {\r\n        this._parent = value;\r\n    }\r\n\r\n    /**\r\n     * Set the physics body. Used mainly by the physics engine/plugin\r\n     */\r\n    public set physicsBody(physicsBody: any) {\r\n        if (this._physicsBody && this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);\r\n        }\r\n        this._physicsBody = physicsBody;\r\n        this.resetUpdateFlags();\r\n    }\r\n\r\n    /**\r\n     * Resets the update flags\r\n     */\r\n    public resetUpdateFlags() {\r\n        this._bodyUpdateRequired = false;\r\n    }\r\n\r\n    /**\r\n     * Gets the object extents\r\n     * @returns the object extents\r\n     */\r\n    public getObjectExtents(): Vector3 {\r\n        if (this.object.getBoundingInfo) {\r\n            const q = this.object.rotationQuaternion;\r\n            const scaling = this.object.scaling.clone();\r\n            //reset rotation\r\n            this.object.rotationQuaternion = PhysicsImpostor.IDENTITY_QUATERNION;\r\n            //calculate the world matrix with no rotation\r\n            const worldMatrix = this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);\r\n            if (worldMatrix) {\r\n                worldMatrix.decompose(scaling, undefined, undefined);\r\n            }\r\n            const boundingInfo = this.object.getBoundingInfo();\r\n            // get the global scaling of the object\r\n            const size = boundingInfo.boundingBox.extendSize.scale(2).multiplyInPlace(scaling);\r\n            size.x = Math.abs(size.x);\r\n            size.y = Math.abs(size.y);\r\n            size.z = Math.abs(size.z);\r\n            //bring back the rotation\r\n            this.object.rotationQuaternion = q;\r\n            //calculate the world matrix with the new rotation\r\n            if (this.object.computeWorldMatrix) {\r\n                this.object.computeWorldMatrix(true);\r\n            }\r\n            return size;\r\n        } else {\r\n            return PhysicsImpostor.DEFAULT_OBJECT_SIZE;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the object center\r\n     * @returns The object center\r\n     */\r\n    public getObjectCenter(): Vector3 {\r\n        if (this.object.getBoundingInfo) {\r\n            const boundingInfo = this.object.getBoundingInfo();\r\n            return boundingInfo.boundingBox.centerWorld;\r\n        } else {\r\n            return this.object.position;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get a specific parameter from the options parameters\r\n     * @param paramName The object parameter name\r\n     * @returns The object parameter\r\n     */\r\n    public getParam(paramName: string): any {\r\n        return (<any>this._options)[paramName];\r\n    }\r\n\r\n    /**\r\n     * Sets a specific parameter in the options given to the physics plugin\r\n     * @param paramName The parameter name\r\n     * @param value The value of the parameter\r\n     */\r\n    public setParam(paramName: string, value: number) {\r\n        (<any>this._options)[paramName] = value;\r\n        this._bodyUpdateRequired = true;\r\n    }\r\n\r\n    /**\r\n     * Specifically change the body's mass. Won't recreate the physics body object\r\n     * @param mass The mass of the physics imposter\r\n     */\r\n    public setMass(mass: number) {\r\n        if (this.getParam(\"mass\") !== mass) {\r\n            this.setParam(\"mass\", mass);\r\n        }\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the linear velocity\r\n     * @returns  linear velocity or null\r\n     */\r\n    public getLinearVelocity(): Nullable<Vector3> {\r\n        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : Vector3.Zero();\r\n    }\r\n\r\n    /**\r\n     * Sets the linear velocity\r\n     * @param velocity  linear velocity or null\r\n     */\r\n    public setLinearVelocity(velocity: Nullable<Vector3>) {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the angular velocity\r\n     * @returns angular velocity or null\r\n     */\r\n    public getAngularVelocity(): Nullable<Vector3> {\r\n        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : Vector3.Zero();\r\n    }\r\n\r\n    /**\r\n     * Sets the angular velocity\r\n     * @param velocity The velocity or null\r\n     */\r\n    public setAngularVelocity(velocity: Nullable<Vector3>) {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Execute a function with the physics plugin native code\r\n     * Provide a function the will have two variables - the world object and the physics body object\r\n     * @param func The function to execute with the physics plugin native code\r\n     */\r\n    public executeNativeFunction(func: (world: any, physicsBody: any) => void) {\r\n        if (this._physicsEngine) {\r\n            func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Register a function that will be executed before the physics world is stepping forward\r\n     * @param func The function to execute before the physics world is stepped forward\r\n     */\r\n    public registerBeforePhysicsStep(func: (impostor: PhysicsImpostor) => void): void {\r\n        this._onBeforePhysicsStepCallbacks.push(func);\r\n    }\r\n\r\n    /**\r\n     * Unregister a function that will be executed before the physics world is stepping forward\r\n     * @param func The function to execute before the physics world is stepped forward\r\n     */\r\n    public unregisterBeforePhysicsStep(func: (impostor: PhysicsImpostor) => void): void {\r\n        const index = this._onBeforePhysicsStepCallbacks.indexOf(func);\r\n\r\n        if (index > -1) {\r\n            this._onBeforePhysicsStepCallbacks.splice(index, 1);\r\n        } else {\r\n            Logger.Warn(\"Function to remove was not found\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Register a function that will be executed after the physics step\r\n     * @param func The function to execute after physics step\r\n     */\r\n    public registerAfterPhysicsStep(func: (impostor: PhysicsImpostor) => void): void {\r\n        this._onAfterPhysicsStepCallbacks.push(func);\r\n    }\r\n\r\n    /**\r\n     * Unregisters a function that will be executed after the physics step\r\n     * @param func The function to execute after physics step\r\n     */\r\n    public unregisterAfterPhysicsStep(func: (impostor: PhysicsImpostor) => void): void {\r\n        const index = this._onAfterPhysicsStepCallbacks.indexOf(func);\r\n\r\n        if (index > -1) {\r\n            this._onAfterPhysicsStepCallbacks.splice(index, 1);\r\n        } else {\r\n            Logger.Warn(\"Function to remove was not found\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * register a function that will be executed when this impostor collides against a different body\r\n     * @param collideAgainst Physics imposter, or array of physics imposters to collide against\r\n     * @param func Callback that is executed on collision\r\n     */\r\n    public registerOnPhysicsCollide(\r\n        collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>,\r\n        func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor, point: Nullable<Vector3>) => void\r\n    ): void {\r\n        const collidedAgainstList: Array<PhysicsImpostor> = collideAgainst instanceof Array ? collideAgainst : [collideAgainst];\r\n        this._onPhysicsCollideCallbacks.push({ callback: func, otherImpostors: collidedAgainstList });\r\n    }\r\n\r\n    /**\r\n     * Unregisters the physics imposter's collision callback\r\n     * @param collideAgainst The physics object to collide against\r\n     * @param func Callback to execute on collision\r\n     */\r\n    public unregisterOnPhysicsCollide(\r\n        collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>,\r\n        func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor | Array<PhysicsImpostor>, point: Nullable<Vector3>) => void\r\n    ): void {\r\n        const collidedAgainstList: Array<PhysicsImpostor> = collideAgainst instanceof Array ? collideAgainst : [collideAgainst];\r\n        let index = -1;\r\n        const found = this._onPhysicsCollideCallbacks.some((cbDef, idx) => {\r\n            if (cbDef.callback === func && cbDef.otherImpostors.length === collidedAgainstList.length) {\r\n                // chcek the arrays match\r\n                const sameList = cbDef.otherImpostors.every((impostor) => {\r\n                    return collidedAgainstList.indexOf(impostor) > -1;\r\n                });\r\n                if (sameList) {\r\n                    index = idx;\r\n                }\r\n                return sameList;\r\n            }\r\n            return false;\r\n        });\r\n\r\n        if (found) {\r\n            this._onPhysicsCollideCallbacks.splice(index, 1);\r\n        } else {\r\n            Logger.Warn(\"Function to remove was not found\");\r\n        }\r\n    }\r\n\r\n    //temp variables for parent rotation calculations\r\n    //private _mats: Array<Matrix> = [new Matrix(), new Matrix()];\r\n    private _tmpQuat: Quaternion = new Quaternion();\r\n    private _tmpQuat2: Quaternion = new Quaternion();\r\n\r\n    /**\r\n     * Get the parent rotation\r\n     * @returns The parent rotation\r\n     */\r\n    public getParentsRotation(): Quaternion {\r\n        let parent = this.object.parent;\r\n        this._tmpQuat.copyFromFloats(0, 0, 0, 1);\r\n        while (parent) {\r\n            if (parent.rotationQuaternion) {\r\n                this._tmpQuat2.copyFrom(parent.rotationQuaternion);\r\n            } else {\r\n                Quaternion.RotationYawPitchRollToRef(parent.rotation.y, parent.rotation.x, parent.rotation.z, this._tmpQuat2);\r\n            }\r\n            this._tmpQuat.multiplyToRef(this._tmpQuat2, this._tmpQuat);\r\n            parent = parent.parent;\r\n        }\r\n        return this._tmpQuat;\r\n    }\r\n\r\n    /**\r\n     * this function is executed by the physics engine.\r\n     */\r\n    public beforeStep = () => {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n\r\n        this.object.translate(this._deltaPosition, -1);\r\n        if (this._deltaRotationConjugated && this.object.rotationQuaternion) {\r\n            this.object.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this.object.rotationQuaternion);\r\n        }\r\n        this.object.computeWorldMatrix(false);\r\n        if (this.object.parent && this.object.rotationQuaternion) {\r\n            this.getParentsRotation();\r\n            this._tmpQuat.multiplyToRef(this.object.rotationQuaternion, this._tmpQuat);\r\n        } else {\r\n            this._tmpQuat.copyFrom(this.object.rotationQuaternion || new Quaternion());\r\n        }\r\n        if (!this._options.disableBidirectionalTransformation) {\r\n            if (this.object.rotationQuaternion) {\r\n                this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(this, /*bInfo.boundingBox.centerWorld*/ this.object.getAbsolutePosition(), this._tmpQuat);\r\n            }\r\n        }\r\n\r\n        for (const func of this._onBeforePhysicsStepCallbacks) {\r\n            func(this);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * this function is executed by the physics engine\r\n     */\r\n    public afterStep = () => {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n\r\n        for (const func of this._onAfterPhysicsStepCallbacks) {\r\n            func(this);\r\n        }\r\n\r\n        this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);\r\n        // object has now its world rotation. needs to be converted to local.\r\n        if (this.object.parent && this.object.rotationQuaternion) {\r\n            this.getParentsRotation();\r\n            this._tmpQuat.conjugateInPlace();\r\n            this._tmpQuat.multiplyToRef(this.object.rotationQuaternion, this.object.rotationQuaternion);\r\n        }\r\n        // take the position set and make it the absolute position of this object.\r\n        this.object.setAbsolutePosition(this.object.position);\r\n        if (this._deltaRotation) {\r\n            if (this.object.rotationQuaternion) {\r\n                this.object.rotationQuaternion.multiplyToRef(this._deltaRotation, this.object.rotationQuaternion);\r\n            }\r\n            this._deltaPosition.applyRotationQuaternionToRef(this._deltaRotation, PhysicsImpostor._TmpVecs[0]);\r\n            this.object.translate(PhysicsImpostor._TmpVecs[0], 1);\r\n        } else {\r\n            this.object.translate(this._deltaPosition, 1);\r\n        }\r\n        this.object.computeWorldMatrix(true);\r\n    };\r\n\r\n    /**\r\n     * Legacy collision detection event support\r\n     */\r\n    public onCollideEvent: Nullable<(collider: PhysicsImpostor, collidedWith: PhysicsImpostor) => void> = null;\r\n\r\n    /**\r\n     *  define an onCollide function to call when this impostor collides against a different body\r\n     * @param e collide event data\r\n     */\r\n    public onCollide = (e: { body: any; point: Nullable<Vector3>; distance: number; impulse: number; normal: Nullable<Vector3> }) => {\r\n        if (!this._onPhysicsCollideCallbacks.length && !this.onCollideEvent) {\r\n            return;\r\n        }\r\n\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n        const otherImpostor = this._physicsEngine.getImpostorWithPhysicsBody(e.body);\r\n        if (otherImpostor) {\r\n            // Legacy collision detection event support\r\n            if (this.onCollideEvent) {\r\n                this.onCollideEvent(this, otherImpostor);\r\n            }\r\n            const callbacks = this._onPhysicsCollideCallbacks.filter((obj) => {\r\n                return obj.otherImpostors.indexOf(<PhysicsImpostor>otherImpostor) !== -1;\r\n            });\r\n\r\n            for (const obj of callbacks) {\r\n                obj.callback(this, <PhysicsImpostor>otherImpostor, e.point, e.distance, e.impulse, e.normal);\r\n            }\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Apply a force\r\n     * @param force The force to apply\r\n     * @param contactPoint The contact point for the force\r\n     * @returns The physics imposter\r\n     */\r\n    public applyForce(force: Vector3, contactPoint: Vector3): PhysicsImpostor {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Apply an impulse\r\n     * @param force The impulse force\r\n     * @param contactPoint The contact point for the impulse force\r\n     * @returns The physics imposter\r\n     */\r\n    public applyImpulse(force: Vector3, contactPoint: Vector3): PhysicsImpostor {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * A help function to create a joint\r\n     * @param otherImpostor A physics imposter used to create a joint\r\n     * @param jointType The type of joint\r\n     * @param jointData The data for the joint\r\n     * @returns The physics imposter\r\n     */\r\n    public createJoint(otherImpostor: PhysicsImpostor, jointType: number, jointData: PhysicsJointData): PhysicsImpostor {\r\n        const joint = new PhysicsJoint(jointType, jointData);\r\n        this.addJoint(otherImpostor, joint);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add a joint to this impostor with a different impostor\r\n     * @param otherImpostor A physics imposter used to add a joint\r\n     * @param joint The joint to add\r\n     * @returns The physics imposter\r\n     */\r\n    public addJoint(otherImpostor: PhysicsImpostor, joint: PhysicsJoint): PhysicsImpostor {\r\n        this._joints.push({\r\n            otherImpostor: otherImpostor,\r\n            joint: joint,\r\n        });\r\n\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.addJoint(this, otherImpostor, joint);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add an anchor to a cloth impostor\r\n     * @param otherImpostor rigid impostor to anchor to\r\n     * @param width ratio across width from 0 to 1\r\n     * @param height ratio up height from 0 to 1\r\n     * @param influence the elasticity between cloth impostor and anchor from 0, very stretchy to 1, little stretch\r\n     * @param noCollisionBetweenLinkedBodies when true collisions between cloth impostor and anchor are ignored; default false\r\n     * @returns impostor the soft imposter\r\n     */\r\n    public addAnchor(otherImpostor: PhysicsImpostor, width: number, height: number, influence: number, noCollisionBetweenLinkedBodies: boolean): PhysicsImpostor {\r\n        if (!this._physicsEngine) {\r\n            return this;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.appendAnchor) {\r\n            return this;\r\n        }\r\n        if (this._physicsEngine) {\r\n            plugin.appendAnchor(this, otherImpostor, width, height, influence, noCollisionBetweenLinkedBodies);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add a hook to a rope impostor\r\n     * @param otherImpostor rigid impostor to anchor to\r\n     * @param length ratio across rope from 0 to 1\r\n     * @param influence the elasticity between rope impostor and anchor from 0, very stretchy to 1, little stretch\r\n     * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false\r\n     * @returns impostor the rope imposter\r\n     */\r\n    public addHook(otherImpostor: PhysicsImpostor, length: number, influence: number, noCollisionBetweenLinkedBodies: boolean): PhysicsImpostor {\r\n        if (!this._physicsEngine) {\r\n            return this;\r\n        }\r\n        const plugin = this._physicsEngine.getPhysicsPlugin();\r\n        if (!plugin.appendAnchor) {\r\n            return this;\r\n        }\r\n        if (this._physicsEngine) {\r\n            plugin.appendHook!(this, otherImpostor, length, influence, noCollisionBetweenLinkedBodies);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Will keep this body still, in a sleep mode.\r\n     * @returns the physics imposter\r\n     */\r\n    public sleep(): PhysicsImpostor {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().sleepBody(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Wake the body up.\r\n     * @returns The physics imposter\r\n     */\r\n    public wakeUp(): PhysicsImpostor {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Clones the physics imposter\r\n     * @param newObject The physics imposter clones to this physics-enabled object\r\n     * @returns A nullable physics imposter\r\n     */\r\n    public clone(newObject: IPhysicsEnabledObject): Nullable<PhysicsImpostor> {\r\n        if (!newObject) {\r\n            return null;\r\n        }\r\n        return new PhysicsImpostor(newObject, this.type, this._options, this._scene);\r\n    }\r\n\r\n    /**\r\n     * Disposes the physics imposter\r\n     */\r\n    public dispose(/*disposeChildren: boolean = true*/) {\r\n        //no dispose if no physics engine is available.\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n\r\n        for (const j of this._joints) {\r\n            if (this._physicsEngine) {\r\n                this._physicsEngine.removeJoint(this, j.otherImpostor, j.joint);\r\n            }\r\n        }\r\n        //dispose the physics body\r\n        this._physicsEngine.removeImpostor(this);\r\n        if (this.parent) {\r\n            this.parent.forceUpdate();\r\n        }\r\n\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    /**\r\n     * Sets the delta position\r\n     * @param position The delta position amount\r\n     */\r\n    public setDeltaPosition(position: Vector3) {\r\n        this._deltaPosition.copyFrom(position);\r\n    }\r\n\r\n    /**\r\n     * Sets the delta rotation\r\n     * @param rotation The delta rotation amount\r\n     */\r\n    public setDeltaRotation(rotation: Quaternion) {\r\n        if (!this._deltaRotation) {\r\n            this._deltaRotation = new Quaternion();\r\n        }\r\n        this._deltaRotation.copyFrom(rotation);\r\n        this._deltaRotationConjugated = this._deltaRotation.conjugate();\r\n    }\r\n\r\n    /**\r\n     * Gets the box size of the physics imposter and stores the result in the input parameter\r\n     * @param result Stores the box size\r\n     * @returns The physics imposter\r\n     */\r\n    public getBoxSizeToRef(result: Vector3): PhysicsImpostor {\r\n        if (this._physicsEngine) {\r\n            this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the radius of the physics imposter\r\n     * @returns Radius of the physics imposter\r\n     */\r\n    public getRadius(): number {\r\n        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getRadius(this) : 0;\r\n    }\r\n\r\n    /**\r\n     * Sync a bone with this impostor\r\n     * @param bone The bone to sync to the impostor.\r\n     * @param boneMesh The mesh that the bone is influencing.\r\n     * @param jointPivot The pivot of the joint / bone in local space.\r\n     * @param distToJoint Optional distance from the impostor to the joint.\r\n     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.\r\n     */\r\n    public syncBoneWithImpostor(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion) {\r\n        const tempVec = PhysicsImpostor._TmpVecs[0];\r\n        const mesh = <AbstractMesh>this.object;\r\n\r\n        if (mesh.rotationQuaternion) {\r\n            if (adjustRotation) {\r\n                const tempQuat = PhysicsImpostor._TmpQuat;\r\n                mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);\r\n                bone.setRotationQuaternion(tempQuat, Space.WORLD, boneMesh);\r\n            } else {\r\n                bone.setRotationQuaternion(mesh.rotationQuaternion, Space.WORLD, boneMesh);\r\n            }\r\n        }\r\n\r\n        tempVec.x = 0;\r\n        tempVec.y = 0;\r\n        tempVec.z = 0;\r\n\r\n        if (jointPivot) {\r\n            tempVec.x = jointPivot.x;\r\n            tempVec.y = jointPivot.y;\r\n            tempVec.z = jointPivot.z;\r\n\r\n            bone.getDirectionToRef(tempVec, boneMesh, tempVec);\r\n\r\n            if (distToJoint === undefined || distToJoint === null) {\r\n                distToJoint = jointPivot.length();\r\n            }\r\n\r\n            tempVec.x *= distToJoint;\r\n            tempVec.y *= distToJoint;\r\n            tempVec.z *= distToJoint;\r\n        }\r\n\r\n        if (bone.getParent()) {\r\n            tempVec.addInPlace(mesh.getAbsolutePosition());\r\n            bone.setAbsolutePosition(tempVec, boneMesh);\r\n        } else {\r\n            boneMesh.setAbsolutePosition(mesh.getAbsolutePosition());\r\n            boneMesh.position.x -= tempVec.x;\r\n            boneMesh.position.y -= tempVec.y;\r\n            boneMesh.position.z -= tempVec.z;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sync impostor to a bone\r\n     * @param bone The bone that the impostor will be synced to.\r\n     * @param boneMesh The mesh that the bone is influencing.\r\n     * @param jointPivot The pivot of the joint / bone in local space.\r\n     * @param distToJoint Optional distance from the impostor to the joint.\r\n     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.\r\n     * @param boneAxis Optional vector3 axis the bone is aligned with\r\n     */\r\n    public syncImpostorWithBone(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion, boneAxis?: Vector3) {\r\n        const mesh = <AbstractMesh>this.object;\r\n\r\n        if (mesh.rotationQuaternion) {\r\n            if (adjustRotation) {\r\n                const tempQuat = PhysicsImpostor._TmpQuat;\r\n                bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, tempQuat);\r\n                tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);\r\n            } else {\r\n                bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, mesh.rotationQuaternion);\r\n            }\r\n        }\r\n\r\n        const pos = PhysicsImpostor._TmpVecs[0];\r\n        const boneDir = PhysicsImpostor._TmpVecs[1];\r\n\r\n        if (!boneAxis) {\r\n            boneAxis = PhysicsImpostor._TmpVecs[2];\r\n            boneAxis.x = 0;\r\n            boneAxis.y = 1;\r\n            boneAxis.z = 0;\r\n        }\r\n\r\n        bone.getDirectionToRef(boneAxis, boneMesh, boneDir);\r\n        bone.getAbsolutePositionToRef(boneMesh, pos);\r\n\r\n        if ((distToJoint === undefined || distToJoint === null) && jointPivot) {\r\n            distToJoint = jointPivot.length();\r\n        }\r\n\r\n        if (distToJoint !== undefined && distToJoint !== null) {\r\n            pos.x += boneDir.x * distToJoint;\r\n            pos.y += boneDir.y * distToJoint;\r\n            pos.z += boneDir.z * distToJoint;\r\n        }\r\n\r\n        mesh.setAbsolutePosition(pos);\r\n    }\r\n\r\n    //Impostor types\r\n    /**\r\n     * No-Imposter type\r\n     */\r\n    public static NoImpostor = 0;\r\n    /**\r\n     * Sphere-Imposter type\r\n     */\r\n    public static SphereImpostor = 1;\r\n    /**\r\n     * Box-Imposter type\r\n     */\r\n    public static BoxImpostor = 2;\r\n    /**\r\n     * Plane-Imposter type\r\n     */\r\n    public static PlaneImpostor = 3;\r\n    /**\r\n     * Mesh-imposter type (Only available to objects with vertices data)\r\n     */\r\n    public static MeshImpostor = 4;\r\n    /**\r\n     * Capsule-Impostor type (Ammo.js plugin only)\r\n     */\r\n    public static CapsuleImpostor = 6;\r\n    /**\r\n     * Cylinder-Imposter type\r\n     */\r\n    public static CylinderImpostor = 7;\r\n    /**\r\n     * Particle-Imposter type\r\n     */\r\n    public static ParticleImpostor = 8;\r\n    /**\r\n     * Heightmap-Imposter type\r\n     */\r\n    public static HeightmapImpostor = 9;\r\n    /**\r\n     * ConvexHull-Impostor type (Ammo.js plugin only)\r\n     */\r\n    public static ConvexHullImpostor = 10;\r\n    /**\r\n     * Custom-Imposter type (Ammo.js plugin only)\r\n     */\r\n    public static CustomImpostor = 100;\r\n    /**\r\n     * Rope-Imposter type\r\n     */\r\n    public static RopeImpostor = 101;\r\n    /**\r\n     * Cloth-Imposter type\r\n     */\r\n    public static ClothImpostor = 102;\r\n    /**\r\n     * Softbody-Imposter type\r\n     */\r\n    public static SoftbodyImpostor = 103;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for physicsImpostor.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPhysicsImpostor(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._PhysicsImpostorParser = function (scene: Scene, physicObject: IPhysicsEnabledObject, jsonObject: any): PhysicsImpostor {\r\n        return new PhysicsImpostor(\r\n            physicObject,\r\n            jsonObject.physicsImpostor,\r\n            {\r\n                mass: jsonObject.physicsMass,\r\n                friction: jsonObject.physicsFriction,\r\n                restitution: jsonObject.physicsRestitution,\r\n            },\r\n            scene\r\n        );\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { CreateBox } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { Matrix, Quaternion, TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type IPhysicsEnginePlugin as IPhysicsEnginePluginV1 } from \"../Physics/v1/IPhysicsEnginePlugin\";\r\nimport { PhysicsConstraintAxis, PhysicsConstraintAxisLimitMode, type IPhysicsEnginePluginV2, type PhysicsMassProperties } from \"../Physics/v2/IPhysicsEnginePlugin\";\r\nimport { PhysicsImpostor } from \"../Physics/v1/physicsImpostor.pure\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { type ICreateCapsuleOptions, CreateCapsule } from \"../Meshes/Builders/capsuleBuilder.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type PhysicsBody } from \"../Physics/v2/physicsBody\";\r\nimport { VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { MeshBuilder } from \"../Meshes/meshBuilder.pure\";\r\nimport { type PhysicsConstraint } from \"../Physics/v2/physicsConstraint\";\r\nimport { AxesViewer } from \"./axesViewer\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\n\r\n/**\r\n * Used to show the physics impostor around the specific mesh\r\n */\r\nexport class PhysicsViewer {\r\n    /** @internal */\r\n    protected _impostors: Array<Nullable<PhysicsImpostor>> = [];\r\n    /** @internal */\r\n    protected _meshes: Array<Nullable<AbstractMesh>> = [];\r\n    /** @internal */\r\n    protected _bodies: Array<Nullable<PhysicsBody>> = [];\r\n    /** @internal */\r\n    protected _inertiaBodies: Array<Nullable<PhysicsBody>> = [];\r\n    /** @internal */\r\n    protected _constraints: Array<Nullable<PhysicsConstraint>> = [];\r\n    /** @internal */\r\n    protected _bodyMeshes: Array<Nullable<AbstractMesh>> = [];\r\n    /** @internal */\r\n    protected _inertiaMeshes: Array<Nullable<AbstractMesh>> = [];\r\n    /** @internal */\r\n    protected _constraintMeshes: Array<Nullable<Array<AbstractMesh>>> = [];\r\n    /** @internal */\r\n    protected _scene: Nullable<Scene>;\r\n    /** @internal */\r\n    protected _numMeshes = 0;\r\n    /** @internal */\r\n    protected _numBodies = 0;\r\n    /** @internal */\r\n    protected _numInertiaBodies = 0;\r\n    /** @internal */\r\n    protected _numConstraints = 0;\r\n    /** @internal */\r\n    protected _physicsEnginePlugin: IPhysicsEnginePluginV1 | IPhysicsEnginePluginV2 | null;\r\n    private _renderFunction: () => void;\r\n    private _inertiaRenderFunction: () => void;\r\n    private _constraintRenderFunction: () => void;\r\n    private _utilityLayer: Nullable<UtilityLayerRenderer>;\r\n    private _ownUtilityLayer = false;\r\n\r\n    private _debugBoxMesh: Mesh;\r\n    private _debugSphereMesh: Mesh;\r\n    private _debugCapsuleMesh: Mesh;\r\n    private _debugCylinderMesh: Mesh;\r\n    private _debugMaterial: StandardMaterial;\r\n    private _debugInertiaMaterial: StandardMaterial;\r\n    private _debugMeshMeshes = new Array<Mesh>();\r\n\r\n    private _constraintAxesSize = 0.4;\r\n    private _constraintAngularSize = 0.4;\r\n\r\n    /**\r\n     * Creates a new PhysicsViewer\r\n     * @param scene defines the hosting scene\r\n     * @param size Physics V2 size scalar\r\n     * @param utilityLayer The utility layer the viewer will be added to\r\n     */\r\n    constructor(scene?: Scene, size?: number, utilityLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer) {\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n        const physicEngine = this._scene.getPhysicsEngine();\r\n\r\n        if (physicEngine) {\r\n            this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();\r\n        }\r\n\r\n        if (utilityLayer) {\r\n            this._utilityLayer = utilityLayer;\r\n        } else {\r\n            this._utilityLayer = new UtilityLayerRenderer(this._scene, false);\r\n            this._utilityLayer.pickUtilitySceneFirst = false;\r\n            this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = true;\r\n            this._ownUtilityLayer = true;\r\n        }\r\n        if (size) {\r\n            this._constraintAxesSize = 0.4 * size;\r\n            this._constraintAngularSize = 0.4 * size;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the debug meshes of the physics engine.\r\n     *\r\n     * This code is useful for synchronizing the debug meshes of the physics engine with the physics impostor and mesh.\r\n     * It checks if the impostor is disposed and if the plugin version is 1, then it syncs the mesh with the impostor.\r\n     * This ensures that the debug meshes are up to date with the physics engine.\r\n     */\r\n    protected _updateDebugMeshes(): void {\r\n        const plugin = this._physicsEnginePlugin;\r\n\r\n        if (plugin?.getPluginVersion() === 1) {\r\n            this._updateDebugMeshesV1();\r\n        } else {\r\n            this._updateDebugMeshesV2();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the debug meshes of the physics engine.\r\n     *\r\n     * This method is useful for synchronizing the debug meshes with the physics impostors.\r\n     * It iterates through the impostors and meshes, and if the plugin version is 1, it syncs the mesh with the impostor.\r\n     * This ensures that the debug meshes accurately reflect the physics impostors, which is important for debugging the physics engine.\r\n     */\r\n    protected _updateDebugMeshesV1(): void {\r\n        const plugin = this._physicsEnginePlugin as IPhysicsEnginePluginV1;\r\n        for (let i = 0; i < this._numMeshes; i++) {\r\n            const impostor = this._impostors[i];\r\n\r\n            if (!impostor) {\r\n                continue;\r\n            }\r\n\r\n            if (impostor.isDisposed) {\r\n                this.hideImpostor(this._impostors[i--]);\r\n            } else {\r\n                if (impostor.type === PhysicsImpostor.MeshImpostor) {\r\n                    continue;\r\n                }\r\n                const mesh = this._meshes[i];\r\n\r\n                if (mesh && plugin) {\r\n                    plugin.syncMeshWithImpostor(mesh, impostor);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the debug meshes of the physics engine for V2 plugin.\r\n     *\r\n     * This method is useful for synchronizing the debug meshes of the physics engine with the current state of the bodies.\r\n     * It iterates through the bodies array and updates the debug meshes with the current transform of each body.\r\n     * This ensures that the debug meshes accurately reflect the current state of the physics engine.\r\n     */\r\n    protected _updateDebugMeshesV2(): void {\r\n        const plugin = this._physicsEnginePlugin as IPhysicsEnginePluginV2;\r\n        for (let i = 0; i < this._numBodies;) {\r\n            const body = this._bodies[i];\r\n            if (body && body.isDisposed && this.hideBody(body)) {\r\n                continue;\r\n            }\r\n            const transform = this._bodyMeshes[i];\r\n            if (body && transform) {\r\n                plugin.syncTransform(body, transform);\r\n            }\r\n            i++;\r\n        }\r\n    }\r\n\r\n    protected _updateInertiaMeshes(): void {\r\n        for (let i = 0; i < this._numInertiaBodies;) {\r\n            const body = this._inertiaBodies[i];\r\n            if (body && body.isDisposed && this.hideInertia(body)) {\r\n                continue;\r\n            }\r\n            const mesh = this._inertiaMeshes[i];\r\n            if (body && mesh) {\r\n                this._updateDebugInertia(body, mesh);\r\n            }\r\n            i++;\r\n        }\r\n    }\r\n\r\n    protected _updateDebugInertia(body: PhysicsBody, inertiaMesh: AbstractMesh): void {\r\n        const inertiaMatrixRef = Matrix.Identity();\r\n        const transformMatrixRef = Matrix.Identity();\r\n        const finalMatrixRef = Matrix.Identity();\r\n        if (body._pluginDataInstances.length) {\r\n            const inertiaAsMesh = inertiaMesh as Mesh;\r\n            const inertiaMeshMatrixData = inertiaAsMesh._thinInstanceDataStorage.matrixData!;\r\n            const bodyTransformMatrixData = (body.transformNode as Mesh)._thinInstanceDataStorage.matrixData!;\r\n            for (let i = 0; i < body._pluginDataInstances.length; i++) {\r\n                const props = body.getMassProperties(i);\r\n                this._getMeshDebugInertiaMatrixToRef(props, inertiaMatrixRef);\r\n                Matrix.FromArrayToRef(bodyTransformMatrixData, i * 16, transformMatrixRef);\r\n                inertiaMatrixRef.multiplyToRef(transformMatrixRef, finalMatrixRef);\r\n                finalMatrixRef.copyToArray(inertiaMeshMatrixData, i * 16);\r\n            }\r\n            inertiaAsMesh.thinInstanceBufferUpdated(\"matrix\");\r\n        } else {\r\n            const props = body.getMassProperties();\r\n            this._getMeshDebugInertiaMatrixToRef(props, inertiaMatrixRef);\r\n            body.transformNode.rotationQuaternion?.toRotationMatrix(transformMatrixRef);\r\n            transformMatrixRef.setTranslation(body.transformNode.position);\r\n            if (body.transformNode.parent) {\r\n                const parentTransform = body.transformNode.parent.computeWorldMatrix(true);\r\n                transformMatrixRef.multiplyToRef(parentTransform, transformMatrixRef);\r\n            }\r\n            inertiaMatrixRef.multiplyToRef(transformMatrixRef, inertiaMatrixRef);\r\n            inertiaMatrixRef.decomposeToTransformNode(inertiaMesh);\r\n        }\r\n    }\r\n\r\n    protected _updateDebugConstraints() {\r\n        for (let i = 0; i < this._numConstraints; i++) {\r\n            const constraint = this._constraints[i];\r\n            const mesh = this._constraintMeshes[i];\r\n            if (constraint && mesh) {\r\n                this._updateDebugConstraint(constraint, mesh[0]);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Given a scaling vector, make all of its components\r\n     * 1, preserving the sign\r\n     * @param scaling\r\n     */\r\n    protected _makeScalingUnitInPlace(scaling: Vector3) {\r\n        if (Math.abs(scaling.x - 1) > Epsilon) {\r\n            scaling.x = 1 * Math.sign(scaling.x);\r\n        }\r\n        if (Math.abs(scaling.y - 1) > Epsilon) {\r\n            scaling.y = 1 * Math.sign(scaling.y);\r\n        }\r\n        if (Math.abs(scaling.z - 1) > Epsilon) {\r\n            scaling.z = 1 * Math.sign(scaling.z);\r\n        }\r\n    }\r\n\r\n    protected _updateDebugConstraint(constraint: PhysicsConstraint, parentingMesh: AbstractMesh) {\r\n        if (!constraint._initOptions) {\r\n            return;\r\n        }\r\n\r\n        // Get constraint pivot and axes\r\n        const { pivotA, pivotB, axisA, axisB, perpAxisA, perpAxisB } = constraint._initOptions;\r\n\r\n        if (!pivotA || !pivotB || !axisA || !axisB || !perpAxisA || !perpAxisB) {\r\n            return;\r\n        }\r\n\r\n        const descendants = parentingMesh.getDescendants(true);\r\n        for (const parentConstraintMesh of descendants) {\r\n            // Get the parent transform\r\n            const parentCoordSystemNode = parentConstraintMesh.getDescendants(true)[0] as TransformNode;\r\n            const childCoordSystemNode = parentConstraintMesh.getDescendants(true)[1] as TransformNode;\r\n\r\n            const { parentBody, parentBodyIndex } = parentCoordSystemNode.metadata;\r\n            const { childBody, childBodyIndex } = childCoordSystemNode.metadata;\r\n\r\n            const parentTransform = this._getTransformFromBodyToRef(parentBody, TmpVectors.Matrix[0], parentBodyIndex);\r\n            const childTransform = this._getTransformFromBodyToRef(childBody, TmpVectors.Matrix[1], childBodyIndex);\r\n\r\n            parentTransform.decomposeToTransformNode(parentCoordSystemNode);\r\n            this._makeScalingUnitInPlace(parentCoordSystemNode.scaling);\r\n\r\n            childTransform.decomposeToTransformNode(childCoordSystemNode);\r\n            this._makeScalingUnitInPlace(childCoordSystemNode.scaling);\r\n\r\n            // Create a transform node and set its matrix\r\n            const parentTransformNode = parentCoordSystemNode.getDescendants(true)[0] as TransformNode;\r\n            parentTransformNode.position.copyFrom(pivotA);\r\n\r\n            const childTransformNode = childCoordSystemNode.getDescendants(true)[0] as TransformNode;\r\n            childTransformNode.position.copyFrom(pivotB);\r\n\r\n            // Get the transform to align the XYZ axes to the constraint axes\r\n            Quaternion.FromRotationMatrixToRef(\r\n                Matrix.FromXYZAxesToRef(axisA, perpAxisA, Vector3.CrossToRef(axisA, perpAxisA, TmpVectors.Vector3[0]), TmpVectors.Matrix[0]),\r\n                parentTransformNode.rotationQuaternion!\r\n            );\r\n            Quaternion.FromRotationMatrixToRef(\r\n                Matrix.FromXYZAxesToRef(axisB, perpAxisB, Vector3.CrossToRef(axisB, perpAxisB, TmpVectors.Vector3[1]), TmpVectors.Matrix[1]),\r\n                childTransformNode.rotationQuaternion!\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Renders a specified physic impostor\r\n     * @param impostor defines the impostor to render\r\n     * @param targetMesh defines the mesh represented by the impostor\r\n     * @returns the new debug mesh used to render the impostor\r\n     */\r\n    public showImpostor(impostor: PhysicsImpostor, targetMesh?: Mesh): Nullable<AbstractMesh> {\r\n        if (!this._scene) {\r\n            return null;\r\n        }\r\n\r\n        for (let i = 0; i < this._numMeshes; i++) {\r\n            if (this._impostors[i] == impostor) {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        const debugMesh = this._getDebugMesh(impostor, targetMesh);\r\n\r\n        if (debugMesh) {\r\n            this._impostors[this._numMeshes] = impostor;\r\n            this._meshes[this._numMeshes] = debugMesh;\r\n\r\n            if (this._numMeshes === 0) {\r\n                this._renderFunction = () => this._updateDebugMeshes();\r\n                this._scene.registerBeforeRender(this._renderFunction);\r\n            }\r\n\r\n            this._numMeshes++;\r\n        }\r\n\r\n        return debugMesh;\r\n    }\r\n\r\n    /**\r\n     * Shows a debug mesh for a given physics body.\r\n     * @param body The physics body to show.\r\n     * @returns The debug mesh, or null if the body is already shown.\r\n     *\r\n     * This function is useful for visualizing the physics body in the scene.\r\n     * It creates a debug mesh for the given body and adds it to the scene.\r\n     * It also registers a before render function to update the debug mesh position and rotation.\r\n     */\r\n    public showBody(body: PhysicsBody): Nullable<AbstractMesh> {\r\n        if (!this._scene) {\r\n            return null;\r\n        }\r\n\r\n        for (let i = 0; i < this._numBodies; i++) {\r\n            if (this._bodies[i] == body) {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        const debugMesh = this._getDebugBodyMesh(body);\r\n\r\n        if (debugMesh) {\r\n            this._bodies[this._numBodies] = body;\r\n            this._bodyMeshes[this._numBodies] = debugMesh;\r\n\r\n            if (this._numBodies === 0) {\r\n                this._renderFunction = () => this._updateDebugMeshes();\r\n                this._scene.registerBeforeRender(this._renderFunction);\r\n            }\r\n\r\n            this._numBodies++;\r\n        }\r\n\r\n        return debugMesh;\r\n    }\r\n\r\n    /**\r\n     * Shows a debug box corresponding to the inertia of a given body\r\n     * @param body the physics body used to get the inertia\r\n     * @returns the debug mesh used to show the inertia, or null if the body is already shown\r\n     */\r\n    public showInertia(body: PhysicsBody): Nullable<AbstractMesh> {\r\n        if (!this._scene) {\r\n            return null;\r\n        }\r\n\r\n        for (let i = 0; i < this._numInertiaBodies; i++) {\r\n            if (this._inertiaBodies[i] == body) {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        const debugMesh = this._getDebugInertiaMesh(body);\r\n        if (debugMesh) {\r\n            this._inertiaBodies[this._numInertiaBodies] = body;\r\n            this._inertiaMeshes[this._numInertiaBodies] = debugMesh;\r\n\r\n            if (this._numInertiaBodies === 0) {\r\n                this._inertiaRenderFunction = () => this._updateInertiaMeshes();\r\n                this._scene.registerBeforeRender(this._inertiaRenderFunction);\r\n            }\r\n\r\n            this._numInertiaBodies++;\r\n        }\r\n\r\n        return debugMesh;\r\n    }\r\n\r\n    /**\r\n     * Shows a debug mesh for a given physics constraint.\r\n     * @param constraint the physics constraint to show\r\n     * @returns the debug mesh, or null if the constraint is already shown\r\n     */\r\n    public showConstraint(constraint: PhysicsConstraint): Nullable<AbstractMesh> {\r\n        if (!this._scene) {\r\n            return null;\r\n        }\r\n\r\n        for (let i = 0; i < this._numConstraints; i++) {\r\n            if (this._constraints[i] == constraint) {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        const debugMesh = this._getDebugConstraintMesh(constraint);\r\n        if (debugMesh) {\r\n            this._constraints[this._numConstraints] = constraint;\r\n            this._constraintMeshes[this._numConstraints] = debugMesh;\r\n\r\n            if (this._numConstraints === 0) {\r\n                this._constraintRenderFunction = () => this._updateDebugConstraints();\r\n                this._scene.registerBeforeRender(this._constraintRenderFunction);\r\n            }\r\n\r\n            this._numConstraints++;\r\n        }\r\n\r\n        return debugMesh ? debugMesh[0] : null;\r\n    }\r\n\r\n    /**\r\n     * Hides an impostor from the scene.\r\n     * @param impostor - The impostor to hide.\r\n     *\r\n     * This method is useful for hiding an impostor from the scene. It removes the\r\n     * impostor from the utility layer scene, disposes the mesh, and removes the\r\n     * impostor from the list of impostors. If the impostor is the last one in the\r\n     * list, it also unregisters the render function.\r\n     */\r\n    public hideImpostor(impostor: Nullable<PhysicsImpostor>) {\r\n        if (!impostor || !this._scene || !this._utilityLayer) {\r\n            return;\r\n        }\r\n\r\n        let removed = false;\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        for (let i = 0; i < this._numMeshes; i++) {\r\n            if (this._impostors[i] == impostor) {\r\n                const mesh = this._meshes[i];\r\n\r\n                if (!mesh) {\r\n                    continue;\r\n                }\r\n\r\n                utilityLayerScene.removeMesh(mesh);\r\n                mesh.dispose();\r\n\r\n                const index = this._debugMeshMeshes.indexOf(mesh as Mesh);\r\n                if (index > -1) {\r\n                    this._debugMeshMeshes.splice(index, 1);\r\n                }\r\n\r\n                this._numMeshes--;\r\n                if (this._numMeshes > 0) {\r\n                    this._meshes[i] = this._meshes[this._numMeshes];\r\n                    this._impostors[i] = this._impostors[this._numMeshes];\r\n                    this._meshes[this._numMeshes] = null;\r\n                    this._impostors[this._numMeshes] = null;\r\n                } else {\r\n                    this._meshes[0] = null;\r\n                    this._impostors[0] = null;\r\n                }\r\n                removed = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (removed && this._numMeshes === 0) {\r\n            this._scene.unregisterBeforeRender(this._renderFunction);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Hides a body from the physics engine.\r\n     * @param body - The body to hide.\r\n     * @returns true if body actually removed\r\n     *\r\n     * This function is useful for hiding a body from the physics engine.\r\n     * It removes the body from the utility layer scene and disposes the mesh associated with it.\r\n     * It also unregisters the render function if the number of bodies is 0.\r\n     * This is useful for hiding a body from the physics engine without deleting it.\r\n     */\r\n    public hideBody(body: Nullable<PhysicsBody>): boolean {\r\n        if (!body || !this._scene || !this._utilityLayer) {\r\n            return false;\r\n        }\r\n\r\n        let removed = false;\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        for (let i = 0; i < this._numBodies; i++) {\r\n            if (this._bodies[i] === body) {\r\n                const mesh = this._bodyMeshes[i];\r\n\r\n                if (!mesh) {\r\n                    continue;\r\n                }\r\n\r\n                utilityLayerScene.removeMesh(mesh);\r\n                mesh.dispose();\r\n\r\n                this._numBodies--;\r\n                if (this._numBodies > 0) {\r\n                    this._bodyMeshes[i] = this._bodyMeshes[this._numBodies];\r\n                    this._bodies[i] = this._bodies[this._numBodies];\r\n                    this._bodyMeshes[this._numBodies] = null;\r\n                    this._bodies[this._numBodies] = null;\r\n                } else {\r\n                    this._bodyMeshes[0] = null;\r\n                    this._bodies[0] = null;\r\n                }\r\n                removed = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (removed && this._numBodies === 0) {\r\n            this._scene.unregisterBeforeRender(this._renderFunction);\r\n        }\r\n        return removed;\r\n    }\r\n\r\n    /**\r\n     * Hides a body's inertia from the viewer utility layer\r\n     * @param body the body to hide\r\n     * @returns true if inertia actually removed\r\n     */\r\n    public hideInertia(body: Nullable<PhysicsBody>): boolean {\r\n        if (!body || !this._scene || !this._utilityLayer) {\r\n            return false;\r\n        }\r\n        let removed = false;\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        for (let i = 0; i < this._numInertiaBodies; i++) {\r\n            if (this._inertiaBodies[i] === body) {\r\n                const mesh = this._inertiaMeshes[i];\r\n\r\n                if (!mesh) {\r\n                    continue;\r\n                }\r\n\r\n                utilityLayerScene.removeMesh(mesh);\r\n                mesh.dispose();\r\n\r\n                this._inertiaBodies.splice(i, 1);\r\n                this._inertiaMeshes.splice(i, 1);\r\n\r\n                this._numInertiaBodies--;\r\n\r\n                removed = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (removed && this._numInertiaBodies === 0) {\r\n            this._scene.unregisterBeforeRender(this._inertiaRenderFunction);\r\n        }\r\n        return removed;\r\n    }\r\n\r\n    /**\r\n     * Hide a physics constraint from the viewer utility layer\r\n     * @param constraint the constraint to hide\r\n     */\r\n    public hideConstraint(constraint: Nullable<PhysicsConstraint>) {\r\n        if (!constraint || !this._scene || !this._utilityLayer) {\r\n            return;\r\n        }\r\n        let removed = false;\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        for (let i = 0; i < this._numConstraints; i++) {\r\n            if (this._constraints[i] === constraint) {\r\n                const meshes = this._constraintMeshes[i];\r\n\r\n                if (!meshes) {\r\n                    continue;\r\n                }\r\n\r\n                for (const mesh of meshes) {\r\n                    utilityLayerScene.removeMesh(mesh);\r\n                    mesh.dispose();\r\n                }\r\n\r\n                this._constraints.splice(i, 1);\r\n                this._constraintMeshes.splice(i, 1);\r\n\r\n                this._numConstraints--;\r\n\r\n                if (this._numConstraints > 0) {\r\n                    this._constraints[i] = this._constraints[this._numConstraints];\r\n                    this._constraintMeshes[i] = this._constraintMeshes[this._numConstraints];\r\n                    this._constraints[this._numConstraints] = null;\r\n                    this._constraintMeshes[this._numConstraints] = null;\r\n                } else {\r\n                    this._constraints[0] = null;\r\n                    this._constraintMeshes[0] = null;\r\n                }\r\n\r\n                removed = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (removed && this._numConstraints === 0) {\r\n            this._scene.unregisterBeforeRender(this._constraintRenderFunction);\r\n        }\r\n    }\r\n\r\n    private _getDebugMaterial(scene: Scene): Material {\r\n        if (!this._debugMaterial) {\r\n            this._debugMaterial = new StandardMaterial(\"\", scene);\r\n            this._debugMaterial.wireframe = true;\r\n            this._debugMaterial.emissiveColor = Color3.White();\r\n            this._debugMaterial.disableLighting = true;\r\n        }\r\n\r\n        return this._debugMaterial;\r\n    }\r\n\r\n    private _getDebugInertiaMaterial(scene: Scene): Material {\r\n        if (!this._debugInertiaMaterial) {\r\n            this._debugInertiaMaterial = new StandardMaterial(\"\", scene);\r\n            this._debugInertiaMaterial.disableLighting = true;\r\n            this._debugInertiaMaterial.alpha = 0.0;\r\n        }\r\n\r\n        return this._debugInertiaMaterial;\r\n    }\r\n\r\n    private _getDebugAxisColoredMaterial(axisNumber: number, scene: Scene): Material {\r\n        const material = new StandardMaterial(\"\", scene);\r\n        material.emissiveColor = axisNumber == 0 ? Color3.Red() : axisNumber == 1 ? Color3.Green() : Color3.Blue();\r\n        material.disableLighting = true;\r\n        return material;\r\n    }\r\n\r\n    private _getDebugBoxMesh(scene: Scene): AbstractMesh {\r\n        if (!this._debugBoxMesh) {\r\n            this._debugBoxMesh = CreateBox(\"physicsBodyBoxViewMesh\", { size: 1 }, scene);\r\n            this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();\r\n            this._debugBoxMesh.material = this._getDebugMaterial(scene);\r\n            this._debugBoxMesh.setEnabled(false);\r\n        }\r\n\r\n        return this._debugBoxMesh.createInstance(\"physicsBodyBoxViewInstance\");\r\n    }\r\n\r\n    private _getDebugSphereMesh(scene: Scene): AbstractMesh {\r\n        if (!this._debugSphereMesh) {\r\n            this._debugSphereMesh = CreateSphere(\"physicsBodySphereViewMesh\", { diameter: 1 }, scene);\r\n            this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();\r\n            this._debugSphereMesh.material = this._getDebugMaterial(scene);\r\n            this._debugSphereMesh.setEnabled(false);\r\n        }\r\n\r\n        return this._debugSphereMesh.createInstance(\"physicsBodySphereViewInstance\");\r\n    }\r\n\r\n    private _getDebugCapsuleMesh(scene: Scene): AbstractMesh {\r\n        if (!this._debugCapsuleMesh) {\r\n            this._debugCapsuleMesh = CreateCapsule(\"physicsBodyCapsuleViewMesh\", { height: 1 } as ICreateCapsuleOptions, scene);\r\n            this._debugCapsuleMesh.rotationQuaternion = Quaternion.Identity();\r\n            this._debugCapsuleMesh.material = this._getDebugMaterial(scene);\r\n            this._debugCapsuleMesh.setEnabled(false);\r\n        }\r\n\r\n        return this._debugCapsuleMesh.createInstance(\"physicsBodyCapsuleViewInstance\");\r\n    }\r\n\r\n    private _getDebugCylinderMesh(scene: Scene): AbstractMesh {\r\n        if (!this._debugCylinderMesh) {\r\n            this._debugCylinderMesh = CreateCylinder(\"physicsBodyCylinderViewMesh\", { diameterTop: 1, diameterBottom: 1, height: 1 }, scene);\r\n            this._debugCylinderMesh.rotationQuaternion = Quaternion.Identity();\r\n            this._debugCylinderMesh.material = this._getDebugMaterial(scene);\r\n            this._debugCylinderMesh.setEnabled(false);\r\n        }\r\n\r\n        return this._debugCylinderMesh.createInstance(\"physicsBodyCylinderViewInstance\");\r\n    }\r\n\r\n    private _getDebugMeshMesh(mesh: Mesh, scene: Scene): AbstractMesh {\r\n        const wireframeOver = new Mesh(mesh.name, scene, null, mesh);\r\n        wireframeOver.setParent(mesh);\r\n        wireframeOver.position = Vector3.Zero();\r\n        wireframeOver.material = this._getDebugMaterial(scene);\r\n\r\n        this._debugMeshMeshes.push(wireframeOver);\r\n\r\n        return wireframeOver;\r\n    }\r\n\r\n    private _getDebugMesh(impostor: PhysicsImpostor, targetMesh?: Mesh): Nullable<AbstractMesh> {\r\n        if (!this._utilityLayer) {\r\n            return null;\r\n        }\r\n\r\n        // Only create child impostor debug meshes when evaluating the parent\r\n        if (targetMesh && targetMesh.parent && (targetMesh.parent as Mesh).physicsImpostor) {\r\n            return null;\r\n        }\r\n\r\n        let mesh: Nullable<AbstractMesh> = null;\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n        if (!impostor.physicsBody) {\r\n            Logger.Warn(\"Unable to get physicsBody of impostor. It might be initialized later by its parent's impostor.\");\r\n            return null;\r\n        }\r\n        switch (impostor.type) {\r\n            case PhysicsImpostor.BoxImpostor:\r\n                mesh = this._getDebugBoxMesh(utilityLayerScene);\r\n                impostor.getBoxSizeToRef(mesh.scaling);\r\n                break;\r\n            case PhysicsImpostor.SphereImpostor: {\r\n                mesh = this._getDebugSphereMesh(utilityLayerScene);\r\n                const radius = impostor.getRadius();\r\n                mesh.scaling.x = radius * 2;\r\n                mesh.scaling.y = radius * 2;\r\n                mesh.scaling.z = radius * 2;\r\n                break;\r\n            }\r\n            case PhysicsImpostor.CapsuleImpostor: {\r\n                mesh = this._getDebugCapsuleMesh(utilityLayerScene);\r\n                const bi = impostor.object.getBoundingInfo();\r\n                mesh.scaling.x = (bi.boundingBox.maximum.x - bi.boundingBox.minimum.x) * 2 * impostor.object.scaling.x;\r\n                mesh.scaling.y = (bi.boundingBox.maximum.y - bi.boundingBox.minimum.y) * impostor.object.scaling.y;\r\n                mesh.scaling.z = (bi.boundingBox.maximum.z - bi.boundingBox.minimum.z) * 2 * impostor.object.scaling.z;\r\n                break;\r\n            }\r\n            case PhysicsImpostor.MeshImpostor:\r\n                if (targetMesh) {\r\n                    mesh = this._getDebugMeshMesh(targetMesh, utilityLayerScene);\r\n                }\r\n                break;\r\n            case PhysicsImpostor.NoImpostor:\r\n                if (targetMesh) {\r\n                    // Handle compound impostors\r\n                    const childMeshes = targetMesh.getChildMeshes().filter((c) => {\r\n                        return c.physicsImpostor ? 1 : 0;\r\n                    });\r\n                    for (const m of childMeshes) {\r\n                        if (m.physicsImpostor && m.getClassName() === \"Mesh\") {\r\n                            const boundingInfo = m.getBoundingInfo();\r\n                            const min = boundingInfo.boundingBox.minimum;\r\n                            const max = boundingInfo.boundingBox.maximum;\r\n                            switch (m.physicsImpostor.type) {\r\n                                case PhysicsImpostor.BoxImpostor:\r\n                                    mesh = this._getDebugBoxMesh(utilityLayerScene);\r\n                                    mesh.position.copyFrom(min);\r\n                                    mesh.position.addInPlace(max);\r\n                                    mesh.position.scaleInPlace(0.5);\r\n                                    break;\r\n                                case PhysicsImpostor.SphereImpostor:\r\n                                    mesh = this._getDebugSphereMesh(utilityLayerScene);\r\n                                    break;\r\n                                case PhysicsImpostor.CylinderImpostor:\r\n                                    mesh = this._getDebugCylinderMesh(utilityLayerScene);\r\n                                    break;\r\n                                default:\r\n                                    mesh = null;\r\n                                    break;\r\n                            }\r\n                            if (mesh) {\r\n                                mesh.scaling.x = max.x - min.x;\r\n                                mesh.scaling.y = max.y - min.y;\r\n                                mesh.scaling.z = max.z - min.z;\r\n                                mesh.parent = m;\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    Logger.Warn(\"No target mesh parameter provided for NoImpostor. Skipping.\");\r\n                }\r\n                mesh = null;\r\n                break;\r\n            case PhysicsImpostor.CylinderImpostor: {\r\n                mesh = this._getDebugCylinderMesh(utilityLayerScene);\r\n                const bi = impostor.object.getBoundingInfo();\r\n                mesh.scaling.x = (bi.boundingBox.maximum.x - bi.boundingBox.minimum.x) * impostor.object.scaling.x;\r\n                mesh.scaling.y = (bi.boundingBox.maximum.y - bi.boundingBox.minimum.y) * impostor.object.scaling.y;\r\n                mesh.scaling.z = (bi.boundingBox.maximum.z - bi.boundingBox.minimum.z) * impostor.object.scaling.z;\r\n                break;\r\n            }\r\n        }\r\n        return mesh;\r\n    }\r\n\r\n    /**\r\n     * Creates a debug mesh for a given physics body\r\n     * @param body The physics body to create the debug mesh for\r\n     * @returns The created debug mesh or null if the utility layer is not available\r\n     *\r\n     * This code is useful for creating a debug mesh for a given physics body.\r\n     * It creates a Mesh object with a VertexData object containing the positions and indices\r\n     * of the geometry of the body. The mesh is then assigned a debug material from the utility layer scene.\r\n     * This allows for visualizing the physics body in the scene.\r\n     */\r\n    private _getDebugBodyMesh(body: PhysicsBody): Nullable<AbstractMesh> {\r\n        if (!this._utilityLayer) {\r\n            return null;\r\n        }\r\n\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        const mesh = new Mesh(\"custom\", utilityLayerScene);\r\n        const vertexData = new VertexData();\r\n        const geometry = body.getGeometry() as any;\r\n        vertexData.positions = geometry.positions;\r\n        vertexData.indices = geometry.indices;\r\n        vertexData.applyToMesh(mesh);\r\n        if (body._pluginDataInstances) {\r\n            const instanceBuffer = new Float32Array(body._pluginDataInstances.length * 16);\r\n            mesh.thinInstanceSetBuffer(\"matrix\", instanceBuffer, 16, false);\r\n        }\r\n        mesh.material = this._getDebugMaterial(utilityLayerScene);\r\n        return mesh;\r\n    }\r\n\r\n    private _getMeshDebugInertiaMatrixToRef(massProps: PhysicsMassProperties, matrix: Matrix) {\r\n        const orientation = massProps.inertiaOrientation ?? Quaternion.Identity();\r\n        const inertiaLocal = massProps.inertia ?? Vector3.Zero();\r\n        const center = massProps.centerOfMass ?? Vector3.Zero();\r\n\r\n        const betaSqrd = (inertiaLocal.x - inertiaLocal.y + inertiaLocal.z) * 6;\r\n        const beta = Math.sqrt(Math.max(betaSqrd, 0)); // Safety check for zeroed elements!\r\n\r\n        const gammaSqrd = inertiaLocal.x * 12 - betaSqrd;\r\n        const gamma = Math.sqrt(Math.max(gammaSqrd, 0)); // Safety check for zeroed elements!\r\n\r\n        const alphaSqrd = inertiaLocal.z * 12 - betaSqrd;\r\n        const alpha = Math.sqrt(Math.max(alphaSqrd, 0)); // Safety check for zeroed elements!\r\n\r\n        const extents = TmpVectors.Vector3[0];\r\n        extents.set(alpha, beta, gamma);\r\n\r\n        const scaling = Matrix.ScalingToRef(extents.x, extents.y, extents.z, TmpVectors.Matrix[0]);\r\n        const rotation = orientation.toRotationMatrix(TmpVectors.Matrix[1]);\r\n        const translation = Matrix.TranslationToRef(center.x, center.y, center.z, TmpVectors.Matrix[2]);\r\n\r\n        scaling.multiplyToRef(rotation, matrix);\r\n        matrix.multiplyToRef(translation, matrix);\r\n\r\n        return matrix;\r\n    }\r\n\r\n    private _getDebugInertiaMesh(body: PhysicsBody): Nullable<AbstractMesh> {\r\n        if (!this._utilityLayer) {\r\n            return null;\r\n        }\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        // The base inertia mesh is going to be a 1x1 cube that's scaled and rotated according to the inertia\r\n        const inertiaBoxMesh = MeshBuilder.CreateBox(\"custom\", { size: 1 }, utilityLayerScene);\r\n        const matrixRef = Matrix.Identity();\r\n        if (body._pluginDataInstances.length) {\r\n            const instanceBuffer = new Float32Array(body._pluginDataInstances.length * 16);\r\n            for (let i = 0; i < body._pluginDataInstances.length; ++i) {\r\n                const props = body.getMassProperties(i);\r\n                this._getMeshDebugInertiaMatrixToRef(props, matrixRef);\r\n                matrixRef.copyToArray(instanceBuffer, i * 16);\r\n            }\r\n            inertiaBoxMesh.thinInstanceSetBuffer(\"matrix\", instanceBuffer, 16, false);\r\n        } else {\r\n            const props = body.getMassProperties();\r\n            this._getMeshDebugInertiaMatrixToRef(props, matrixRef);\r\n            matrixRef.decomposeToTransformNode(inertiaBoxMesh);\r\n        }\r\n        inertiaBoxMesh.enableEdgesRendering();\r\n        inertiaBoxMesh.edgesWidth = 2.0;\r\n        inertiaBoxMesh.edgesColor = new Color4(1, 0, 1, 1);\r\n        inertiaBoxMesh.material = this._getDebugInertiaMaterial(utilityLayerScene);\r\n\r\n        return inertiaBoxMesh;\r\n    }\r\n\r\n    private _getTransformFromBodyToRef(body: PhysicsBody, matrix: Matrix, instanceIndex?: number) {\r\n        const tnode = body.transformNode;\r\n        if (instanceIndex && instanceIndex >= 0) {\r\n            return Matrix.FromArrayToRef((tnode as Mesh)._thinInstanceDataStorage.matrixData!, instanceIndex, matrix);\r\n        } else {\r\n            return matrix.copyFrom(tnode.getWorldMatrix());\r\n        }\r\n    }\r\n\r\n    private _createAngularConstraintMesh(minLimit: number, maxLimit: number, axisNumber: number, parent: TransformNode, scene: Scene): AbstractMesh {\r\n        const arcAngle = (maxLimit - minLimit) / (Math.PI * 2);\r\n        const mesh = MeshBuilder.CreateCylinder(\"ConstraintCylinder\", { height: 0.0001, diameter: 3 * this._constraintAngularSize, arc: arcAngle }, scene);\r\n        mesh.material = this._getDebugAxisColoredMaterial(axisNumber, scene);\r\n        mesh.parent = parent;\r\n        const parentScaling = parent.absoluteScaling;\r\n        const sc = (parentScaling.x + parentScaling.y + parentScaling.z) / 3;\r\n        mesh.scaling.set(1 / sc, 1 / sc, 1 / sc);\r\n        switch (axisNumber) {\r\n            case 0:\r\n                mesh.rotation.z = Math.PI * 0.5;\r\n                mesh.rotation.x = -minLimit + Math.PI * 0.5;\r\n                break;\r\n            case 1:\r\n                mesh.rotation.y = Math.PI * 1.5 + minLimit;\r\n                break;\r\n            case 2:\r\n                mesh.rotation.x = Math.PI * 0.5;\r\n                break;\r\n        }\r\n        return mesh;\r\n    }\r\n\r\n    private _createCage(parent: TransformNode, scene: Scene): AbstractMesh {\r\n        const cage = MeshBuilder.CreateBox(\"cage\", { size: 1 }, scene);\r\n        cage.setPivotPoint(new Vector3(-0.5, -0.5, -0.5));\r\n        const transparentMaterial = new StandardMaterial(\"cage_material\", scene);\r\n        transparentMaterial.alpha = 0; // Fully transparent\r\n        cage.material = transparentMaterial;\r\n\r\n        cage.enableEdgesRendering();\r\n        cage.edgesWidth = 4.0;\r\n        cage.edgesColor = new Color4(1, 1, 1, 1);\r\n        cage.parent = parent;\r\n        return cage;\r\n    }\r\n\r\n    private _getDebugConstraintMesh(constraint: PhysicsConstraint): Nullable<Array<AbstractMesh>> {\r\n        if (!this._utilityLayer) {\r\n            return null;\r\n        }\r\n        const utilityLayerScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        if (!constraint._initOptions) {\r\n            return null;\r\n        }\r\n\r\n        // Get constraint pivot and axes\r\n        const { pivotA, pivotB, axisA, axisB, perpAxisA, perpAxisB } = constraint._initOptions;\r\n\r\n        if (!pivotA || !pivotB || !axisA || !axisB || !perpAxisA || !perpAxisB) {\r\n            return null;\r\n        }\r\n\r\n        // Create a mesh to parent all the constraint debug meshes to\r\n        const parentingMesh = new Mesh(\"parentingDebugConstraint\", utilityLayerScene);\r\n\r\n        // First, get a reference to all physic bodies that are using this constraint\r\n        const bodiesUsingConstraint = constraint.getBodiesUsingConstraint();\r\n\r\n        const parentedConstraintMeshes = [];\r\n        parentedConstraintMeshes.push(parentingMesh);\r\n\r\n        for (const bodyPairInfo of bodiesUsingConstraint) {\r\n            // Create a mesh to keep the pair of constraint axes\r\n            const parentOfPair = new TransformNode(\"parentOfPair\", utilityLayerScene);\r\n            parentOfPair.parent = parentingMesh;\r\n\r\n            const { parentBody, parentBodyIndex, childBody, childBodyIndex } = bodyPairInfo;\r\n            // Get the parent transform\r\n\r\n            const parentTransform = this._getTransformFromBodyToRef(parentBody, TmpVectors.Matrix[0], parentBodyIndex);\r\n            const childTransform = this._getTransformFromBodyToRef(childBody, TmpVectors.Matrix[1], childBodyIndex);\r\n\r\n            const parentCoordSystemNode = new TransformNode(\"parentCoordSystem\", utilityLayerScene);\r\n            // parentCoordSystemNode.parent = parentingMesh;\r\n            parentCoordSystemNode.parent = parentOfPair;\r\n            // Save parent and index here to be able to get the transform on update\r\n            parentCoordSystemNode.metadata = { parentBody, parentBodyIndex };\r\n            parentTransform.decomposeToTransformNode(parentCoordSystemNode);\r\n\r\n            const childCoordSystemNode = new TransformNode(\"childCoordSystem\", utilityLayerScene);\r\n            // childCoordSystemNode.parent = parentingMesh;\r\n            childCoordSystemNode.parent = parentOfPair;\r\n            // Save child and index here to be able to get the transform on update\r\n            childCoordSystemNode.metadata = { childBody, childBodyIndex };\r\n            childTransform.decomposeToTransformNode(childCoordSystemNode);\r\n\r\n            // Get the transform to align the XYZ axes to the constraint axes\r\n            const rotTransformParent = Quaternion.FromRotationMatrix(Matrix.FromXYZAxesToRef(axisA, perpAxisA, axisA.cross(perpAxisA), TmpVectors.Matrix[0]));\r\n            const rotTransformChild = Quaternion.FromRotationMatrix(Matrix.FromXYZAxesToRef(axisB, perpAxisB, axisB.cross(perpAxisB), TmpVectors.Matrix[0]));\r\n\r\n            const translateTransformParent = pivotA;\r\n            const translateTransformChild = pivotB;\r\n\r\n            // Create a transform node and set its matrix\r\n            const parentTransformNode = new TransformNode(\"constraint_parent\", utilityLayerScene);\r\n            parentTransformNode.position.copyFrom(translateTransformParent);\r\n            parentTransformNode.rotationQuaternion = rotTransformParent;\r\n            parentTransformNode.parent = parentCoordSystemNode;\r\n\r\n            const childTransformNode = new TransformNode(\"constraint_child\", utilityLayerScene);\r\n            childTransformNode.parent = childCoordSystemNode;\r\n            childTransformNode.position.copyFrom(translateTransformChild);\r\n            childTransformNode.rotationQuaternion = rotTransformChild;\r\n\r\n            // Create axes for the constraint\r\n            const parentAxes = new AxesViewer(utilityLayerScene, this._constraintAxesSize);\r\n            parentAxes.xAxis.parent = parentTransformNode;\r\n            parentAxes.yAxis.parent = parentTransformNode;\r\n            parentAxes.zAxis.parent = parentTransformNode;\r\n\r\n            const childAxes = new AxesViewer(utilityLayerScene, this._constraintAxesSize);\r\n            childAxes.xAxis.parent = childTransformNode;\r\n            childAxes.yAxis.parent = childTransformNode;\r\n            childAxes.zAxis.parent = childTransformNode;\r\n\r\n            // constrain vis\r\n            const engine = this._physicsEnginePlugin! as IPhysicsEnginePluginV2;\r\n\r\n            const constraintAxisAngular = [PhysicsConstraintAxis.ANGULAR_X, PhysicsConstraintAxis.ANGULAR_Y, PhysicsConstraintAxis.ANGULAR_Z];\r\n            const constraintAxisLinear = [PhysicsConstraintAxis.LINEAR_X, PhysicsConstraintAxis.LINEAR_Y, PhysicsConstraintAxis.LINEAR_Z];\r\n            const constraintAxis = [constraintAxisAngular, constraintAxisLinear];\r\n\r\n            // count axis. Angular and Linear\r\n            const lockCount = [0, 0];\r\n            for (let angularLinear = 0; angularLinear < 2; angularLinear++) {\r\n                for (let axis = 0; axis < 3; axis++) {\r\n                    const constraintAxisValue = constraintAxis[angularLinear][axis];\r\n                    const axisMode = engine.getAxisMode(constraint, constraintAxisValue);\r\n                    if (axisMode == PhysicsConstraintAxisLimitMode.LOCKED) {\r\n                        lockCount[angularLinear]++;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Any free/limited Linear axis\r\n            if (lockCount[1] != 3) {\r\n                const cage = this._createCage(parentTransformNode, utilityLayerScene);\r\n\r\n                const min = TmpVectors.Vector3[0];\r\n                const max = TmpVectors.Vector3[1];\r\n                const limited = [false, false, false];\r\n\r\n                limited[0] = engine.getAxisMode(constraint, PhysicsConstraintAxis.LINEAR_X) == PhysicsConstraintAxisLimitMode.LIMITED;\r\n                limited[1] = engine.getAxisMode(constraint, PhysicsConstraintAxis.LINEAR_Y) == PhysicsConstraintAxisLimitMode.LIMITED;\r\n                limited[2] = engine.getAxisMode(constraint, PhysicsConstraintAxis.LINEAR_Z) == PhysicsConstraintAxisLimitMode.LIMITED;\r\n\r\n                min.x = limited[0] ? engine.getAxisMinLimit(constraint, PhysicsConstraintAxis.LINEAR_X)! : 0;\r\n                max.x = limited[0] ? engine.getAxisMaxLimit(constraint, PhysicsConstraintAxis.LINEAR_X)! : 0;\r\n                min.y = limited[1] ? engine.getAxisMinLimit(constraint, PhysicsConstraintAxis.LINEAR_Y)! : 0;\r\n                max.y = limited[1] ? engine.getAxisMaxLimit(constraint, PhysicsConstraintAxis.LINEAR_Y)! : 0;\r\n                min.z = limited[2] ? engine.getAxisMinLimit(constraint, PhysicsConstraintAxis.LINEAR_Z)! : 0;\r\n                max.z = limited[2] ? engine.getAxisMaxLimit(constraint, PhysicsConstraintAxis.LINEAR_Z)! : 0;\r\n\r\n                cage.position.x = min.x + 0.5;\r\n                cage.position.y = min.y + 0.5;\r\n                cage.position.z = min.z + 0.5;\r\n\r\n                cage.scaling.x = max.x - min.x + Epsilon;\r\n                cage.scaling.y = max.y - min.y + Epsilon;\r\n                cage.scaling.z = max.z - min.z + Epsilon;\r\n                parentedConstraintMeshes.push(cage);\r\n            }\r\n\r\n            // Angular\r\n            if (lockCount[0] != 3) {\r\n                for (let axisIndex = 0; axisIndex < 3; axisIndex++) {\r\n                    const axis = constraintAxisAngular[axisIndex];\r\n                    const axisMode = engine.getAxisMode(constraint, axis);\r\n                    let minLimit = 0;\r\n                    let maxLimit = Math.PI * 2;\r\n                    if (axisMode == PhysicsConstraintAxisLimitMode.LIMITED) {\r\n                        minLimit = engine.getAxisMinLimit(constraint, axis)!;\r\n                        maxLimit = engine.getAxisMaxLimit(constraint, axis)!;\r\n                    }\r\n                    if (axisMode != PhysicsConstraintAxisLimitMode.LOCKED && constraint.options.pivotB) {\r\n                        const mesh = this._createAngularConstraintMesh(minLimit, maxLimit, axisIndex, childBody.transformNode, utilityLayerScene);\r\n                        mesh.position.copyFrom(constraint.options.pivotB);\r\n                        parentedConstraintMeshes.push(mesh);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return parentedConstraintMeshes;\r\n    }\r\n\r\n    /**\r\n     * Clean up physics debug display\r\n     */\r\n    public dispose() {\r\n        // impostors\r\n        for (let index = this._numMeshes - 1; index >= 0; index--) {\r\n            this.hideImpostor(this._impostors[0]);\r\n        }\r\n        // bodies\r\n        for (let index = this._numBodies - 1; index >= 0; index--) {\r\n            this.hideBody(this._bodies[0]);\r\n        }\r\n        // inertia\r\n        for (let index = this._numInertiaBodies - 1; index >= 0; index--) {\r\n            this.hideInertia(this._inertiaBodies[0]);\r\n        }\r\n\r\n        if (this._debugBoxMesh) {\r\n            this._debugBoxMesh.dispose();\r\n        }\r\n        if (this._debugSphereMesh) {\r\n            this._debugSphereMesh.dispose();\r\n        }\r\n        if (this._debugCylinderMesh) {\r\n            this._debugCylinderMesh.dispose();\r\n        }\r\n        if (this._debugMaterial) {\r\n            this._debugMaterial.dispose();\r\n        }\r\n\r\n        this._impostors.length = 0;\r\n        this._scene = null;\r\n        this._physicsEnginePlugin = null;\r\n\r\n        if (this._ownUtilityLayer && this._utilityLayer) {\r\n            this._utilityLayer.dispose();\r\n            this._utilityLayer = null;\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type PhysicsImpostorJoint, type IPhysicsEnginePlugin } from \"./IPhysicsEnginePlugin\";\r\nimport { type IPhysicsEngine } from \"../IPhysicsEngine\";\r\nimport { type PhysicsImpostor, type IPhysicsEnabledObject } from \"./physicsImpostor\";\r\nimport { type PhysicsJoint } from \"./physicsJoint\";\r\nimport { type PhysicsRaycastResult } from \"../physicsRaycastResult\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\n\r\n/**\r\n * Class used to control physics engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class PhysicsEngine implements IPhysicsEngine {\r\n    /**\r\n     * Global value used to control the smallest number supported by the simulation\r\n     */\r\n    private _impostors: Array<PhysicsImpostor> = [];\r\n    private _joints: Array<PhysicsImpostorJoint> = [];\r\n    private _subTimeStep: number = 0;\r\n    private _uniqueIdCounter = 0;\r\n\r\n    /**\r\n     * Gets the gravity vector used by the simulation\r\n     */\r\n    public gravity: Vector3;\r\n\r\n    /**\r\n     *\r\n     * @returns version\r\n     */\r\n    public getPluginVersion(): number {\r\n        return this._physicsPlugin.getPluginVersion();\r\n    }\r\n    /**\r\n     * @virtual\r\n     * Factory used to create the default physics plugin.\r\n     * @returns The default physics plugin\r\n     */\r\n    public static DefaultPluginFactory(): IPhysicsEnginePlugin {\r\n        throw _WarnImport(\"CannonJSPlugin\");\r\n    }\r\n\r\n    /**\r\n     * Creates a new Physics Engine\r\n     * @param gravity defines the gravity vector used by the simulation\r\n     * @param _physicsPlugin defines the plugin to use (CannonJS by default)\r\n     */\r\n    constructor(\r\n        gravity: Nullable<Vector3>,\r\n        private _physicsPlugin: IPhysicsEnginePlugin = PhysicsEngine.DefaultPluginFactory()\r\n    ) {\r\n        if (!this._physicsPlugin.isSupported()) {\r\n            throw new Error(\"Physics Engine \" + this._physicsPlugin.name + \" cannot be found. \" + \"Please make sure it is included.\");\r\n        }\r\n        gravity = gravity || new Vector3(0, -9.807, 0);\r\n        this.setGravity(gravity);\r\n        this.setTimeStep();\r\n    }\r\n\r\n    /**\r\n     * Sets the gravity vector used by the simulation\r\n     * @param gravity defines the gravity vector to use\r\n     */\r\n    public setGravity(gravity: Vector3): void {\r\n        this.gravity = gravity;\r\n        this._physicsPlugin.setGravity(this.gravity);\r\n    }\r\n\r\n    /**\r\n     * Set the time step of the physics engine.\r\n     * Default is 1/60.\r\n     * To slow it down, enter 1/600 for example.\r\n     * To speed it up, 1/30\r\n     * @param newTimeStep defines the new timestep to apply to this world.\r\n     */\r\n    public setTimeStep(newTimeStep: number = 1 / 60) {\r\n        this._physicsPlugin.setTimeStep(newTimeStep);\r\n    }\r\n\r\n    /**\r\n     * Get the time step of the physics engine.\r\n     * @returns the current time step\r\n     */\r\n    public getTimeStep(): number {\r\n        return this._physicsPlugin.getTimeStep();\r\n    }\r\n\r\n    /**\r\n     * Set the sub time step of the physics engine.\r\n     * Default is 0 meaning there is no sub steps\r\n     * To increase physics resolution precision, set a small value (like 1 ms)\r\n     * @param subTimeStep defines the new sub timestep used for physics resolution.\r\n     */\r\n    public setSubTimeStep(subTimeStep: number = 0) {\r\n        this._subTimeStep = subTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Get the sub time step of the physics engine.\r\n     * @returns the current sub time step\r\n     */\r\n    public getSubTimeStep() {\r\n        return this._subTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Release all resources\r\n     */\r\n    public dispose(): void {\r\n        for (const impostor of this._impostors) {\r\n            impostor.dispose();\r\n        }\r\n        this._physicsPlugin.dispose();\r\n    }\r\n\r\n    /**\r\n     * Gets the name of the current physics plugin\r\n     * @returns the name of the plugin\r\n     */\r\n    public getPhysicsPluginName(): string {\r\n        return this._physicsPlugin.name;\r\n    }\r\n\r\n    /**\r\n     * Adding a new impostor for the impostor tracking.\r\n     * This will be done by the impostor itself.\r\n     * @param impostor the impostor to add\r\n     */\r\n    public addImpostor(impostor: PhysicsImpostor) {\r\n        this._impostors.push(impostor);\r\n        impostor.uniqueId = this._uniqueIdCounter++;\r\n        //if no parent, generate the body\r\n        if (!impostor.parent) {\r\n            this._physicsPlugin.generatePhysicsBody(impostor);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove an impostor from the engine.\r\n     * This impostor and its mesh will not longer be updated by the physics engine.\r\n     * @param impostor the impostor to remove\r\n     */\r\n    public removeImpostor(impostor: PhysicsImpostor) {\r\n        const index = this._impostors.indexOf(impostor);\r\n        if (index > -1) {\r\n            const removed = this._impostors.splice(index, 1);\r\n            //Is it needed?\r\n            if (removed.length) {\r\n                this.getPhysicsPlugin().removePhysicsBody(impostor);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add a joint to the physics engine\r\n     * @param mainImpostor defines the main impostor to which the joint is added.\r\n     * @param connectedImpostor defines the impostor that is connected to the main impostor using this joint\r\n     * @param joint defines the joint that will connect both impostors.\r\n     */\r\n    public addJoint(mainImpostor: PhysicsImpostor, connectedImpostor: PhysicsImpostor, joint: PhysicsJoint) {\r\n        const impostorJoint = {\r\n            mainImpostor: mainImpostor,\r\n            connectedImpostor: connectedImpostor,\r\n            joint: joint,\r\n        };\r\n        joint.physicsPlugin = this._physicsPlugin;\r\n        this._joints.push(impostorJoint);\r\n        this._physicsPlugin.generateJoint(impostorJoint);\r\n    }\r\n\r\n    /**\r\n     * Removes a joint from the simulation\r\n     * @param mainImpostor defines the impostor used with the joint\r\n     * @param connectedImpostor defines the other impostor connected to the main one by the joint\r\n     * @param joint defines the joint to remove\r\n     */\r\n    public removeJoint(mainImpostor: PhysicsImpostor, connectedImpostor: PhysicsImpostor, joint: PhysicsJoint) {\r\n        const matchingJoints = this._joints.filter(function (impostorJoint) {\r\n            return impostorJoint.connectedImpostor === connectedImpostor && impostorJoint.joint === joint && impostorJoint.mainImpostor === mainImpostor;\r\n        });\r\n        if (matchingJoints.length) {\r\n            this._physicsPlugin.removeJoint(matchingJoints[0]);\r\n            //TODO remove it from the list as well\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called by the scene. No need to call it.\r\n     * @param delta defines the timespan between frames\r\n     */\r\n    public _step(delta: number) {\r\n        //check if any mesh has no body / requires an update\r\n        for (const impostor of this._impostors) {\r\n            if (impostor.isBodyInitRequired()) {\r\n                this._physicsPlugin.generatePhysicsBody(impostor);\r\n            }\r\n        }\r\n\r\n        if (delta > 0.1) {\r\n            delta = 0.1;\r\n        } else if (delta <= 0) {\r\n            delta = 1.0 / 60.0;\r\n        }\r\n\r\n        this._physicsPlugin.executeStep(delta, this._impostors);\r\n    }\r\n\r\n    /**\r\n     * Gets the current plugin used to run the simulation\r\n     * @returns current plugin\r\n     */\r\n    public getPhysicsPlugin(): IPhysicsEnginePlugin {\r\n        return this._physicsPlugin;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of physic impostors\r\n     * @returns an array of PhysicsImpostor\r\n     */\r\n    public getImpostors(): Array<PhysicsImpostor> {\r\n        return this._impostors;\r\n    }\r\n\r\n    /**\r\n     * Gets the impostor for a physics enabled object\r\n     * @param object defines the object impersonated by the impostor\r\n     * @returns the PhysicsImpostor or null if not found\r\n     */\r\n    public getImpostorForPhysicsObject(object: IPhysicsEnabledObject): Nullable<PhysicsImpostor> {\r\n        for (let i = 0; i < this._impostors.length; ++i) {\r\n            if (this._impostors[i].object === object) {\r\n                return this._impostors[i];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the impostor for a physics body object\r\n     * @param body defines physics body used by the impostor\r\n     * @returns the PhysicsImpostor or null if not found\r\n     */\r\n    public getImpostorWithPhysicsBody(body: any): Nullable<PhysicsImpostor> {\r\n        for (let i = 0; i < this._impostors.length; ++i) {\r\n            if (this._impostors[i].physicsBody === body) {\r\n                return this._impostors[i];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @returns PhysicsRaycastResult\r\n     */\r\n    public raycast(from: Vector3, to: Vector3): PhysicsRaycastResult {\r\n        return this._physicsPlugin.raycast(from, to);\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param result resulting PhysicsRaycastResult\r\n     * @returns true if the ray hits an impostor, else false\r\n     */\r\n    public raycastToRef(from: Vector3, to: Vector3, result: PhysicsRaycastResult) {\r\n        return this._physicsPlugin.raycastToRef(from, to, result);\r\n    }\r\n}\r\n","import { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type PhysicsShape } from \"./v2/physicsShape\";\r\nimport { type PhysicsBody } from \"./v2/physicsBody\";\r\n\r\n/**\r\n * Base class for results of casts.\r\n */\r\nexport class CastingResult {\r\n    private _hasHit: boolean = false;\r\n    protected _hitNormal: Vector3 = Vector3.Zero();\r\n    protected _hitPoint: Vector3 = Vector3.Zero();\r\n    private _triangleIndex: number = -1;\r\n\r\n    /**\r\n     * The Physics body that the query hit.\r\n     */\r\n    public body?: PhysicsBody;\r\n    /**\r\n     * The body Index in case the Physics body is using instances\r\n     */\r\n    public bodyIndex?: number;\r\n\r\n    /**\r\n     * The shape hit by the query.\r\n     */\r\n    public shape?: PhysicsShape;\r\n\r\n    /**\r\n     * Gets the hit point.\r\n     */\r\n    get hitPoint(): Vector3 {\r\n        return this._hitPoint;\r\n    }\r\n    /**\r\n     * Gets the hit normal.\r\n     */\r\n    get hitNormal(): Vector3 {\r\n        return this._hitNormal;\r\n    }\r\n    /**\r\n     * Gets if there was a hit\r\n     */\r\n    get hasHit(): boolean {\r\n        return this._hasHit;\r\n    }\r\n\r\n    /**\r\n     * The index of the original triangle which was hit. Will be -1 if contact point is not on a mesh shape\r\n     */\r\n    get triangleIndex(): number {\r\n        return this._triangleIndex;\r\n    }\r\n\r\n    /**\r\n     * Sets the hit data\r\n     * @param hitNormal defines the normal in world space\r\n     * @param hitPoint defines the point in world space\r\n     * @param triangleIndex defines the index of the triangle in case of mesh shape\r\n     */\r\n    public setHitData(hitNormal: IXYZ, hitPoint: IXYZ, triangleIndex?: number) {\r\n        this._hasHit = true;\r\n        this._hitNormal.set(hitNormal.x, hitNormal.y, hitNormal.z);\r\n        this._hitPoint.set(hitPoint.x, hitPoint.y, hitPoint.z);\r\n        this._triangleIndex = triangleIndex ?? -1;\r\n    }\r\n\r\n    /**\r\n     * Resets all the values to default\r\n     */\r\n    public reset() {\r\n        this._hasHit = false;\r\n\r\n        this._hitNormal.setAll(0);\r\n        this._hitPoint.setAll(0);\r\n        this._triangleIndex = -1;\r\n\r\n        this.body = undefined;\r\n        this.bodyIndex = undefined;\r\n\r\n        this.shape = undefined;\r\n    }\r\n}\r\n\r\n/**\r\n * Interface for 3D coordinates\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ninterface IXYZ {\r\n    /**\r\n     * X\r\n     */\r\n    x: number;\r\n\r\n    /**\r\n     * Y\r\n     */\r\n    y: number;\r\n\r\n    /**\r\n     * Z\r\n     */\r\n    z: number;\r\n}\r\n","import { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { CastingResult } from \"./castingResult\";\r\nimport { type PhysicsBody } from \"./v2/physicsBody\";\r\n\r\n/**\r\n * Interface for query parameters in the raycast function.\r\n * @see the \"Collision Filtering\" section in https://github.com/eoineoineoin/glTF/tree/MSFT_RigidBodies/extensions/2.0/Vendor/MSFT_collision_primitives\r\n */\r\nexport interface IRaycastQuery {\r\n    /** Membership mask */\r\n    membership?: number;\r\n    /** CollideWith mask */\r\n    collideWith?: number;\r\n    /** Should trigger collisions be considered in the query? */\r\n    shouldHitTriggers?: boolean;\r\n    /** Ignores the body passed if it is in the query */\r\n    ignoreBody?: PhysicsBody;\r\n}\r\n\r\n/**\r\n * Holds the data for the raycast result\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class PhysicsRaycastResult extends CastingResult {\r\n    private _hitDistance: number = 0;\r\n    private _rayFromWorld: Vector3 = Vector3.Zero();\r\n    private _rayToWorld: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Gets the distance from the hit\r\n     */\r\n    get hitDistance(): number {\r\n        return this._hitDistance;\r\n    }\r\n\r\n    /**\r\n     * Gets the hit normal/direction in the world\r\n     */\r\n    get hitNormalWorld(): Vector3 {\r\n        return this._hitNormal;\r\n    }\r\n\r\n    /**\r\n     * Gets the hit point in the world\r\n     */\r\n    get hitPointWorld(): Vector3 {\r\n        return this._hitPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the ray \"start point\" of the ray in the world\r\n     */\r\n    get rayFromWorld(): Vector3 {\r\n        return this._rayFromWorld;\r\n    }\r\n\r\n    /**\r\n     * Gets the ray \"end point\" of the ray in the world\r\n     */\r\n    get rayToWorld(): Vector3 {\r\n        return this._rayToWorld;\r\n    }\r\n\r\n    /**\r\n     * Sets the distance from the start point to the hit point\r\n     * @param distance defines the distance to set\r\n     */\r\n    public setHitDistance(distance: number) {\r\n        this._hitDistance = distance;\r\n    }\r\n\r\n    /**\r\n     * Calculates the distance manually\r\n     */\r\n    public calculateHitDistance() {\r\n        this._hitDistance = Vector3.Distance(this._rayFromWorld, this._hitPoint);\r\n    }\r\n\r\n    /**\r\n     * Resets all the values to default\r\n     * @param from The from point on world space\r\n     * @param to The to point on world space\r\n     */\r\n    public override reset(from: Vector3 = Vector3.Zero(), to: Vector3 = Vector3.Zero()) {\r\n        super.reset();\r\n        this._rayFromWorld.copyFrom(from);\r\n        this._rayToWorld.copyFrom(to);\r\n\r\n        this._hitDistance = 0;\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type IPhysicsEngine } from \"../IPhysicsEngine\";\r\nimport { type IPhysicsEnginePluginV2 } from \"./IPhysicsEnginePlugin\";\r\nimport { type IRaycastQuery, PhysicsRaycastResult } from \"../physicsRaycastResult\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\nimport { type PhysicsBody } from \"./physicsBody\";\r\n\r\n/**\r\n * Class used to control physics engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class PhysicsEngine implements IPhysicsEngine {\r\n    /** @internal */\r\n    private _physicsBodies: Array<PhysicsBody> = [];\r\n    private _subTimeStep: number = 0;\r\n\r\n    /**\r\n     * Gets the gravity vector used by the simulation\r\n     */\r\n    public gravity: Vector3;\r\n\r\n    /**\r\n     *\r\n     * @returns physics plugin version\r\n     */\r\n    public getPluginVersion(): number {\r\n        return this._physicsPlugin.getPluginVersion();\r\n    }\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Factory used to create the default physics plugin.\r\n     * @returns The default physics plugin\r\n     */\r\n    public static DefaultPluginFactory(): IPhysicsEnginePluginV2 {\r\n        throw _WarnImport(\"\");\r\n    }\r\n\r\n    /**\r\n     * Creates a new Physics Engine\r\n     * @param gravity defines the gravity vector used by the simulation\r\n     * @param _physicsPlugin defines the plugin to use (CannonJS by default)\r\n     */\r\n    constructor(\r\n        gravity: Nullable<Vector3>,\r\n        private _physicsPlugin: IPhysicsEnginePluginV2 = PhysicsEngine.DefaultPluginFactory()\r\n    ) {\r\n        gravity = gravity || new Vector3(0, -9.807, 0);\r\n        this.setGravity(gravity);\r\n        this.setTimeStep();\r\n    }\r\n\r\n    /**\r\n     * Sets the gravity vector used by the simulation\r\n     * @param gravity defines the gravity vector to use\r\n     */\r\n    public setGravity(gravity: Vector3): void {\r\n        this.gravity = gravity;\r\n        this._physicsPlugin.setGravity(this.gravity);\r\n    }\r\n\r\n    /**\r\n     * Set the time step of the physics engine.\r\n     * Default is 1/60.\r\n     * To slow it down, enter 1/600 for example.\r\n     * To speed it up, 1/30\r\n     * Unit is seconds.\r\n     * @param newTimeStep defines the new timestep to apply to this world.\r\n     */\r\n    public setTimeStep(newTimeStep: number = 1 / 60) {\r\n        this._physicsPlugin.setTimeStep(newTimeStep);\r\n    }\r\n\r\n    /**\r\n     * Get the time step of the physics engine.\r\n     * @returns the current time step\r\n     */\r\n    public getTimeStep(): number {\r\n        return this._physicsPlugin.getTimeStep();\r\n    }\r\n\r\n    /**\r\n     * Set the sub time step of the physics engine.\r\n     * Default is 0 meaning there is no sub steps\r\n     * To increase physics resolution precision, set a small value (like 1 ms)\r\n     * @param subTimeStep defines the new sub timestep used for physics resolution.\r\n     */\r\n    public setSubTimeStep(subTimeStep: number = 0) {\r\n        this._subTimeStep = subTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Get the sub time step of the physics engine.\r\n     * @returns the current sub time step\r\n     */\r\n    public getSubTimeStep() {\r\n        return this._subTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Release all resources\r\n     */\r\n    public dispose(): void {\r\n        this._physicsPlugin.dispose();\r\n    }\r\n\r\n    /**\r\n     * Gets the name of the current physics plugin\r\n     * @returns the name of the plugin\r\n     */\r\n    public getPhysicsPluginName(): string {\r\n        return this._physicsPlugin.name;\r\n    }\r\n\r\n    /**\r\n     * Set the maximum allowed linear and angular velocities\r\n     * @param maxLinearVelocity maximum allowed linear velocity\r\n     * @param maxAngularVelocity maximum allowed angular velocity\r\n     */\r\n    setVelocityLimits(maxLinearVelocity: number, maxAngularVelocity: number): void {\r\n        this._physicsPlugin.setVelocityLimits(maxLinearVelocity, maxAngularVelocity);\r\n    }\r\n\r\n    /**\r\n     * @returns maximum allowed linear velocity\r\n     */\r\n    getMaxLinearVelocity(): number {\r\n        return this._physicsPlugin.getMaxLinearVelocity();\r\n    }\r\n\r\n    /**\r\n     * @returns maximum allowed angular velocity\r\n     */\r\n    getMaxAngularVelocity(): number {\r\n        return this._physicsPlugin.getMaxAngularVelocity();\r\n    }\r\n\r\n    /**\r\n     * Called by the scene. No need to call it.\r\n     * @param delta defines the timespan between frames\r\n     */\r\n    public _step(delta: number) {\r\n        if (delta > 0.1) {\r\n            delta = 0.1;\r\n        } else if (delta <= 0) {\r\n            delta = 1.0 / 60.0;\r\n        }\r\n\r\n        this._physicsPlugin.executeStep(delta, this._physicsBodies);\r\n    }\r\n\r\n    /**\r\n     * Add a body as an active component of this engine\r\n     * @param physicsBody The body to add\r\n     */\r\n    public addBody(physicsBody: PhysicsBody): void {\r\n        this._physicsBodies.push(physicsBody);\r\n    }\r\n    /**\r\n     * Removes a particular body from this engine\r\n     * @param physicsBody The body to remove from the simulation\r\n     */\r\n    public removeBody(physicsBody: PhysicsBody): void {\r\n        const index = this._physicsBodies.indexOf(physicsBody);\r\n        if (index > -1) {\r\n            /*const removed =*/ this._physicsBodies.splice(index, 1);\r\n        }\r\n    }\r\n    /**\r\n     * @returns an array of bodies added to this engine\r\n     */\r\n    public getBodies(): Array<PhysicsBody> {\r\n        return this._physicsBodies;\r\n    }\r\n\r\n    /**\r\n     * Gets the current plugin used to run the simulation\r\n     * @returns current plugin\r\n     */\r\n    public getPhysicsPlugin(): IPhysicsEnginePluginV2 {\r\n        return this._physicsPlugin;\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param result resulting PhysicsRaycastResult or array of PhysicsRaycastResults\r\n     * @param query raycast query object\r\n     * If result is an empty array, it will be populated with every detected raycast hit.\r\n     * If result is a populated array, it will only fill the PhysicsRaycastResults present in the array.\r\n     */\r\n    public raycastToRef(from: Vector3, to: Vector3, result: PhysicsRaycastResult | Array<PhysicsRaycastResult>, query?: IRaycastQuery): void {\r\n        this._physicsPlugin.raycast(from, to, result, query);\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param query raycast query object\r\n     * @returns PhysicsRaycastResult\r\n     */\r\n    public raycast(from: Vector3, to: Vector3, query?: IRaycastQuery): PhysicsRaycastResult {\r\n        const result = new PhysicsRaycastResult();\r\n        this._physicsPlugin.raycast(from, to, result, query);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Does a raycast through multiple objects in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param query raycast query object\r\n     * @returns array of PhysicsRaycastResult\r\n     */\r\n    public raycastMulti(from: Vector3, to: Vector3, query?: IRaycastQuery): Array<PhysicsRaycastResult> {\r\n        const result: Array<PhysicsRaycastResult> = [];\r\n        this._physicsPlugin.raycast(from, to, result, query);\r\n        return result;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type IPhysicsEngine } from \"./IPhysicsEngine\";\r\nimport { type IPhysicsEnginePlugin as IPhysicsEnginePluginV1 } from \"./v1/IPhysicsEnginePlugin\";\r\nimport { type IPhysicsEnginePluginV2 } from \"./v2/IPhysicsEnginePlugin\";\r\nimport { PhysicsEngine as PhysicsEngineV1 } from \"./v1/physicsEngine\";\r\nimport { PhysicsEngine as PhysicsEngineV2 } from \"./v2/physicsEngine\";\r\n\r\n/**\r\n * Defines the physics engine scene component responsible to manage a physics engine\r\n */\r\nexport class PhysicsEngineSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_PHYSICSENGINE;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n        this.scene.onBeforePhysicsObservable = new Observable<Scene>();\r\n        this.scene.onAfterPhysicsObservable = new Observable<Scene>();\r\n\r\n        // Replace the function used to get the deterministic frame time\r\n        this.scene.getDeterministicFrameTime = () => {\r\n            if (this.scene._physicsEngine) {\r\n                return this.scene._physicsEngine.getTimeStep() * 1000;\r\n            }\r\n\r\n            return 1000.0 / 60.0;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {}\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        this.scene.onBeforePhysicsObservable.clear();\r\n        this.scene.onAfterPhysicsObservable.clear();\r\n\r\n        if (this.scene._physicsEngine) {\r\n            this.scene.disablePhysicsEngine();\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for joinedPhysicsEngineComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterJoinedPhysicsEngineComponent(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Gets the current physics engine\r\n     * @returns a IPhysicsEngine or null if none attached\r\n     */\r\n    Scene.prototype.getPhysicsEngine = function (): Nullable<IPhysicsEngine> {\r\n        return this._physicsEngine ?? null;\r\n    };\r\n\r\n    /**\r\n     * Enables physics to the current scene\r\n     * @param gravity defines the scene's gravity for the physics engine\r\n     * @param plugin defines the physics engine to be used. defaults to CannonJS.\r\n     * @returns a boolean indicating if the physics engine was initialized\r\n     */\r\n    Scene.prototype.enablePhysics = function (gravity: Nullable<Vector3> = null, plugin?: IPhysicsEnginePluginV1 | IPhysicsEnginePluginV2): boolean {\r\n        if (this._physicsEngine) {\r\n            return true;\r\n        }\r\n\r\n        // Register the component to the scene\r\n        let component = this._getComponent(SceneComponentConstants.NAME_PHYSICSENGINE) as PhysicsEngineSceneComponent;\r\n        if (!component) {\r\n            component = new PhysicsEngineSceneComponent(this);\r\n            this._addComponent(component);\r\n        }\r\n\r\n        try {\r\n            if (!plugin || plugin?.getPluginVersion() === 1) {\r\n                this._physicsEngine = new PhysicsEngineV1(gravity, plugin as IPhysicsEnginePluginV1);\r\n            } else if (plugin?.getPluginVersion() === 2) {\r\n                this._physicsEngine = new PhysicsEngineV2(gravity, plugin as IPhysicsEnginePluginV2);\r\n            } else {\r\n                throw new Error(\"Unsupported Physics plugin version.\");\r\n            }\r\n            this._physicsTimeAccumulator = 0;\r\n            return true;\r\n        } catch (e) {\r\n            Logger.Error(e.message);\r\n            return false;\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Disables and disposes the physics engine associated with the scene\r\n     */\r\n    Scene.prototype.disablePhysicsEngine = function (): void {\r\n        if (!this._physicsEngine) {\r\n            return;\r\n        }\r\n\r\n        this._physicsEngine.dispose();\r\n        this._physicsEngine = null;\r\n    };\r\n\r\n    /**\r\n     * Gets a boolean indicating if there is an active physics engine\r\n     * @returns a boolean indicating if there is an active physics engine\r\n     */\r\n    Scene.prototype.isPhysicsEnabled = function (): boolean {\r\n        return !!this._physicsEngine;\r\n    };\r\n\r\n    /**\r\n     * Deletes a physics compound impostor\r\n     * @param compound defines the compound to delete\r\n     */\r\n    Scene.prototype.deleteCompoundImpostor = function (compound: any): void {\r\n        const mesh: AbstractMesh = compound.parts[0].mesh;\r\n\r\n        if (mesh.physicsImpostor) {\r\n            mesh.physicsImpostor.dispose(/*true*/);\r\n            mesh.physicsImpostor = null;\r\n        }\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    Scene.prototype._advancePhysicsEngineStep = function (step: number) {\r\n        if (this._physicsEngine) {\r\n            const subTime = this._physicsEngine.getSubTimeStep();\r\n            if (subTime > 0) {\r\n                this._physicsTimeAccumulator += step;\r\n                while (this._physicsTimeAccumulator > subTime) {\r\n                    this.onBeforePhysicsObservable.notifyObservers(this);\r\n                    this._physicsEngine._step(subTime / 1000);\r\n                    this.onAfterPhysicsObservable.notifyObservers(this);\r\n                    this._physicsTimeAccumulator -= subTime;\r\n                }\r\n            } else {\r\n                this.onBeforePhysicsObservable.notifyObservers(this);\r\n                this._physicsEngine._step(step / 1000);\r\n                this.onAfterPhysicsObservable.notifyObservers(this);\r\n            }\r\n        }\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Ray } from \"../Culling/ray\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Color3 } from \"../Maths/math.color\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type LinesMesh } from \"../Meshes/linesMesh\";\r\n\r\nimport { CreateLines } from \"../Meshes/Builders/linesBuilder.pure\";\r\nimport { type Observer } from \"../Misc/observable\";\r\n\r\n/**\r\n * As raycast might be hard to debug, the RayHelper can help rendering the different rays\r\n * in order to better appreciate the issue one might have.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions#debugging\r\n */\r\nexport class RayHelper {\r\n    /**\r\n     * Defines the ray we are currently trying to visualize.\r\n     */\r\n    public ray: Nullable<Ray>;\r\n\r\n    private _renderPoints: Vector3[];\r\n    private _renderLine: Nullable<LinesMesh>;\r\n    private _renderFunction: Nullable<() => void>;\r\n    private _scene: Nullable<Scene>;\r\n\r\n    private _onAfterRenderObserver: Nullable<Observer<Scene>>;\r\n    private _onAfterStepObserver: Nullable<Observer<Scene>>;\r\n    private _attachedToMesh: Nullable<AbstractMesh>;\r\n    private _meshSpaceDirection: Vector3;\r\n    private _meshSpaceOrigin: Vector3;\r\n\r\n    /**\r\n     * Helper function to create a colored helper in a scene in one line.\r\n     * @param ray Defines the ray we are currently trying to visualize\r\n     * @param scene Defines the scene the ray is used in\r\n     * @param color Defines the color we want to see the ray in\r\n     * @returns The newly created ray helper.\r\n     */\r\n    public static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper {\r\n        const helper = new RayHelper(ray);\r\n\r\n        helper.show(scene, color);\r\n\r\n        return helper;\r\n    }\r\n\r\n    /**\r\n     * Instantiate a new ray helper.\r\n     * As raycast might be hard to debug, the RayHelper can help rendering the different rays\r\n     * in order to better appreciate the issue one might have.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions#debugging\r\n     * @param ray Defines the ray we are currently trying to visualize\r\n     */\r\n    constructor(ray: Ray) {\r\n        this.ray = ray;\r\n    }\r\n\r\n    /**\r\n     * Shows the ray we are willing to debug.\r\n     * @param scene Defines the scene the ray needs to be rendered in\r\n     * @param color Defines the color the ray needs to be rendered in\r\n     */\r\n    public show(scene: Scene, color?: Color3): void {\r\n        if (!this._renderFunction && this.ray) {\r\n            const ray = this.ray;\r\n\r\n            this._renderFunction = () => this._render();\r\n            this._scene = scene;\r\n            this._renderPoints = [ray.origin, ray.origin.add(ray.direction.scale(ray.length))];\r\n            this._renderLine = CreateLines(\"ray\", { points: this._renderPoints, updatable: true }, scene);\r\n            this._renderLine.isPickable = false;\r\n\r\n            if (this._renderFunction) {\r\n                this._scene.registerBeforeRender(this._renderFunction);\r\n            }\r\n        }\r\n\r\n        if (color && this._renderLine) {\r\n            this._renderLine.color.copyFrom(color);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Hides the ray we are debugging.\r\n     */\r\n    public hide(): void {\r\n        if (this._renderFunction && this._scene) {\r\n            this._scene.unregisterBeforeRender(this._renderFunction);\r\n            this._scene = null;\r\n            this._renderFunction = null;\r\n            if (this._renderLine) {\r\n                this._renderLine.dispose();\r\n                this._renderLine = null;\r\n            }\r\n\r\n            this._renderPoints = [];\r\n        }\r\n    }\r\n\r\n    private _render(): void {\r\n        const ray = this.ray;\r\n\r\n        if (!ray) {\r\n            return;\r\n        }\r\n\r\n        const point = this._renderPoints[1];\r\n        const len = Math.min(ray.length, 1000000);\r\n\r\n        point.copyFrom(ray.direction);\r\n        point.scaleInPlace(len);\r\n        point.addInPlace(ray.origin);\r\n\r\n        this._renderPoints[0].copyFrom(ray.origin);\r\n\r\n        CreateLines(\"ray\", { points: this._renderPoints, updatable: true, instance: this._renderLine }, this._scene);\r\n\r\n        this._renderLine?.refreshBoundingInfo();\r\n    }\r\n\r\n    /**\r\n     * Attach a ray helper to a mesh so that we can easily see its orientation for instance or information like its normals.\r\n     * @param mesh Defines the mesh we want the helper attached to\r\n     * @param meshSpaceDirection Defines the direction of the Ray in mesh space (local space of the mesh node)\r\n     * @param meshSpaceOrigin Defines the origin of the Ray in mesh space (local space of the mesh node)\r\n     * @param length Defines the length of the ray\r\n     */\r\n    public attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void {\r\n        this._attachedToMesh = mesh;\r\n\r\n        const ray = this.ray;\r\n\r\n        if (!ray) {\r\n            return;\r\n        }\r\n\r\n        if (!ray.direction) {\r\n            ray.direction = Vector3.Zero();\r\n        }\r\n\r\n        if (!ray.origin) {\r\n            ray.origin = Vector3.Zero();\r\n        }\r\n\r\n        if (length) {\r\n            ray.length = length;\r\n        }\r\n\r\n        if (!meshSpaceOrigin) {\r\n            meshSpaceOrigin = Vector3.Zero();\r\n        }\r\n\r\n        if (!meshSpaceDirection) {\r\n            // -1 so that this will work with Mesh.lookAt\r\n            meshSpaceDirection = new Vector3(0, 0, -1);\r\n        }\r\n\r\n        if (!this._scene) {\r\n            this._scene = mesh.getScene();\r\n        }\r\n\r\n        if (!this._meshSpaceDirection) {\r\n            this._meshSpaceDirection = meshSpaceDirection.clone();\r\n            this._meshSpaceOrigin = meshSpaceOrigin.clone();\r\n        } else {\r\n            this._meshSpaceDirection.copyFrom(meshSpaceDirection);\r\n            this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);\r\n        }\r\n\r\n        if (!this._onAfterRenderObserver) {\r\n            this._onAfterRenderObserver = this._scene.onBeforeRenderObservable.add(() => this._updateToMesh());\r\n            this._onAfterStepObserver = this._scene.onAfterStepObservable.add(() => this._updateToMesh());\r\n        }\r\n\r\n        // force world matrix computation before the first ray helper computation\r\n        this._attachedToMesh.computeWorldMatrix(true);\r\n\r\n        this._updateToMesh();\r\n    }\r\n\r\n    /**\r\n     * Detach the ray helper from the mesh it has previously been attached to.\r\n     */\r\n    public detachFromMesh(): void {\r\n        if (this._attachedToMesh && this._scene) {\r\n            if (this._onAfterRenderObserver) {\r\n                this._scene.onBeforeRenderObservable.remove(this._onAfterRenderObserver);\r\n                this._scene.onAfterStepObservable.remove(this._onAfterStepObserver);\r\n            }\r\n            this._attachedToMesh = null;\r\n            this._onAfterRenderObserver = null;\r\n            this._onAfterStepObserver = null;\r\n            this._scene = null;\r\n        }\r\n    }\r\n\r\n    private _updateToMesh(): void {\r\n        const ray = this.ray;\r\n\r\n        if (!this._attachedToMesh || !ray) {\r\n            return;\r\n        }\r\n\r\n        if (this._attachedToMesh.isDisposed()) {\r\n            this.detachFromMesh();\r\n            return;\r\n        }\r\n\r\n        this._attachedToMesh.getDirectionToRef(this._meshSpaceDirection, ray.direction);\r\n        Vector3.TransformCoordinatesToRef(this._meshSpaceOrigin, this._attachedToMesh.getWorldMatrix(), ray.origin);\r\n    }\r\n\r\n    /**\r\n     * Dispose the helper and release its associated resources.\r\n     */\r\n    public dispose(): void {\r\n        this.hide();\r\n        this.detachFromMesh();\r\n        this.ray = null;\r\n    }\r\n}\r\n","import { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Bone } from \"../Bones/bone\";\r\nimport { type Skeleton } from \"../Bones/skeleton\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type LinesMesh } from \"../Meshes/linesMesh\";\r\nimport { CreateLineSystem } from \"../Meshes/Builders/linesBuilder.pure\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { ShaderMaterial } from \"../Materials/shaderMaterial.pure\";\r\nimport { DynamicTexture } from \"../Materials/Textures/dynamicTexture.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Effect } from \"../Materials/effect\";\r\n\r\nimport {\r\n    type ISkeletonViewerOptions,\r\n    type IBoneWeightShaderOptions,\r\n    type ISkeletonMapShaderOptions,\r\n    type ISkeletonMapShaderColorMapKnot,\r\n    type ISkeletonViewerDisplayOptions,\r\n} from \"./ISkeletonViewer\";\r\nimport { type Observer } from \"../Misc/observable\";\r\n\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { ExtrudeShapeCustom } from \"../Meshes/Builders/shapeBuilder.pure\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Class used to render a debug view of a given skeleton\r\n * @see http://www.babylonjs-playground.com/#1BZJVJ#8\r\n */\r\nexport class SkeletonViewer {\r\n    /** public Display constants BABYLON.SkeletonViewer.DISPLAY_LINES */\r\n    public static readonly DISPLAY_LINES = 0;\r\n    /** public Display constants BABYLON.SkeletonViewer.DISPLAY_SPHERES */\r\n    public static readonly DISPLAY_SPHERES = 1;\r\n    /** public Display constants BABYLON.SkeletonViewer.DISPLAY_SPHERE_AND_SPURS */\r\n    public static readonly DISPLAY_SPHERE_AND_SPURS = 2;\r\n\r\n    /** public static method to create a BoneWeight Shader\r\n     * @param options The constructor options\r\n     * @param scene The scene that the shader is scoped to\r\n     * @returns The created ShaderMaterial\r\n     * @see http://www.babylonjs-playground.com/#1BZJVJ#395\r\n     */\r\n    static CreateBoneWeightShader(options: IBoneWeightShaderOptions, scene: Scene): ShaderMaterial {\r\n        const skeleton: Skeleton = options.skeleton;\r\n        const colorBase: Color3 = options.colorBase ?? Color3.Black();\r\n        const colorZero: Color3 = options.colorZero ?? Color3.Blue();\r\n        const colorQuarter: Color3 = options.colorQuarter ?? Color3.Green();\r\n        const colorHalf: Color3 = options.colorHalf ?? Color3.Yellow();\r\n        const colorFull: Color3 = options.colorFull ?? Color3.Red();\r\n        const targetBoneIndex: number = options.targetBoneIndex ?? 0;\r\n\r\n        Effect.ShadersStore[\"boneWeights:\" + skeleton.name + \"VertexShader\"] = `precision highp float;\r\n\r\n        attribute vec3 position;\r\n        attribute vec2 uv;\r\n\r\n        uniform mat4 view;\r\n        uniform mat4 projection;\r\n        uniform mat4 worldViewProjection;\r\n\r\n        #include<bonesDeclaration>\r\n        #if NUM_BONE_INFLUENCERS == 0\r\n            attribute vec4 matricesIndices;\r\n            attribute vec4 matricesWeights;\r\n        #endif\r\n        #include<bakedVertexAnimationDeclaration>\r\n\r\n        #include<instancesDeclaration>\r\n\r\n        varying vec3 vColor;\r\n\r\n        uniform vec3 colorBase;\r\n        uniform vec3 colorZero;\r\n        uniform vec3 colorQuarter;\r\n        uniform vec3 colorHalf;\r\n        uniform vec3 colorFull;\r\n\r\n        uniform float targetBoneIndex;\r\n\r\n        void main() {\r\n            vec3 positionUpdated = position;\r\n\r\n            #include<instancesVertex>\r\n            #include<bonesVertex>\r\n            #include<bakedVertexAnimation>\r\n\r\n            vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);\r\n\r\n            vec3 color = colorBase;\r\n            float totalWeight = 0.;\r\n            if(matricesIndices[0] == targetBoneIndex && matricesWeights[0] > 0.){\r\n                totalWeight += matricesWeights[0];\r\n            }\r\n            if(matricesIndices[1] == targetBoneIndex && matricesWeights[1] > 0.){\r\n                totalWeight += matricesWeights[1];\r\n            }\r\n            if(matricesIndices[2] == targetBoneIndex && matricesWeights[2] > 0.){\r\n                totalWeight += matricesWeights[2];\r\n            }\r\n            if(matricesIndices[3] == targetBoneIndex && matricesWeights[3] > 0.){\r\n                totalWeight += matricesWeights[3];\r\n            }\r\n\r\n            color = mix(color, colorZero, smoothstep(0., 0.25, totalWeight));\r\n            color = mix(color, colorQuarter, smoothstep(0.25, 0.5, totalWeight));\r\n            color = mix(color, colorHalf, smoothstep(0.5, 0.75, totalWeight));\r\n            color = mix(color, colorFull, smoothstep(0.75, 1.0, totalWeight));\r\n            vColor = color;\r\n\r\n        gl_Position = projection * view * worldPos;\r\n        }`;\r\n        Effect.ShadersStore[\"boneWeights:\" + skeleton.name + \"FragmentShader\"] = `\r\n            precision highp float;\r\n            varying vec3 vPosition;\r\n\r\n            varying vec3 vColor;\r\n\r\n            void main() {\r\n                vec4 color = vec4(vColor, 1.0);\r\n                gl_FragColor = color;\r\n            }\r\n        `;\r\n        const shader: ShaderMaterial = new ShaderMaterial(\r\n            \"boneWeight:\" + skeleton.name,\r\n            scene,\r\n            {\r\n                vertex: \"boneWeights:\" + skeleton.name,\r\n                fragment: \"boneWeights:\" + skeleton.name,\r\n            },\r\n            {\r\n                attributes: [\"position\", \"normal\", \"matricesIndices\", \"matricesWeights\"],\r\n                uniforms: [\r\n                    \"world\",\r\n                    \"worldView\",\r\n                    \"worldViewProjection\",\r\n                    \"view\",\r\n                    \"projection\",\r\n                    \"viewProjection\",\r\n                    \"colorBase\",\r\n                    \"colorZero\",\r\n                    \"colorQuarter\",\r\n                    \"colorHalf\",\r\n                    \"colorFull\",\r\n                    \"targetBoneIndex\",\r\n                ],\r\n            }\r\n        );\r\n\r\n        shader.setColor3(\"colorBase\", colorBase);\r\n        shader.setColor3(\"colorZero\", colorZero);\r\n        shader.setColor3(\"colorQuarter\", colorQuarter);\r\n        shader.setColor3(\"colorHalf\", colorHalf);\r\n        shader.setColor3(\"colorFull\", colorFull);\r\n        shader.setFloat(\"targetBoneIndex\", targetBoneIndex);\r\n\r\n        shader.getClassName = (): string => {\r\n            return \"BoneWeightShader\";\r\n        };\r\n\r\n        shader.transparencyMode = Material.MATERIAL_OPAQUE;\r\n\r\n        return shader;\r\n    }\r\n\r\n    /** public static method to create a BoneWeight Shader\r\n     * @param options The constructor options\r\n     * @param scene The scene that the shader is scoped to\r\n     * @returns The created ShaderMaterial\r\n     */\r\n    static CreateSkeletonMapShader(options: ISkeletonMapShaderOptions, scene: Scene) {\r\n        const skeleton: Skeleton = options.skeleton;\r\n        const colorMap: ISkeletonMapShaderColorMapKnot[] = options.colorMap ?? [\r\n            {\r\n                color: new Color3(1, 0.38, 0.18),\r\n                location: 0,\r\n            },\r\n            {\r\n                color: new Color3(0.59, 0.18, 1.0),\r\n                location: 0.2,\r\n            },\r\n            {\r\n                color: new Color3(0.59, 1, 0.18),\r\n                location: 0.4,\r\n            },\r\n            {\r\n                color: new Color3(1, 0.87, 0.17),\r\n                location: 0.6,\r\n            },\r\n            {\r\n                color: new Color3(1, 0.17, 0.42),\r\n                location: 0.8,\r\n            },\r\n            {\r\n                color: new Color3(0.17, 0.68, 1.0),\r\n                location: 1.0,\r\n            },\r\n        ];\r\n\r\n        const bufferWidth: number = skeleton.bones.length + 1;\r\n        const colorMapBuffer: number[] = SkeletonViewer._CreateBoneMapColorBuffer(bufferWidth, colorMap, scene);\r\n        const shader = new ShaderMaterial(\r\n            \"boneWeights:\" + skeleton.name,\r\n            scene,\r\n            {\r\n                vertexSource:\r\n                    `precision highp float;\r\n\r\n            attribute vec3 position;\r\n            attribute vec2 uv;\r\n\r\n            uniform mat4 view;\r\n            uniform mat4 projection;\r\n            uniform mat4 worldViewProjection;\r\n            uniform float colorMap[` +\r\n                    skeleton.bones.length * 4 +\r\n                    `];\r\n\r\n            #include<bonesDeclaration>\r\n            #if NUM_BONE_INFLUENCERS == 0\r\n                attribute vec4 matricesIndices;\r\n                attribute vec4 matricesWeights;\r\n            #endif\r\n            #include<bakedVertexAnimationDeclaration>\r\n            #include<instancesDeclaration>\r\n\r\n            varying vec3 vColor;\r\n\r\n            void main() {\r\n                vec3 positionUpdated = position;\r\n\r\n                #include<instancesVertex>\r\n                #include<bonesVertex>\r\n                #include<bakedVertexAnimation>\r\n\r\n                vec3 color = vec3(0.);\r\n                bool first = true;\r\n\r\n                for (int i = 0; i < 4; i++) {\r\n                    int boneIdx = int(matricesIndices[i]);\r\n                    float boneWgt = matricesWeights[i];\r\n\r\n                    vec3 c = vec3(colorMap[boneIdx * 4 + 0], colorMap[boneIdx * 4 + 1], colorMap[boneIdx * 4 + 2]);\r\n\r\n                    if (boneWgt > 0.) {\r\n                        if (first) {\r\n                            first = false;\r\n                            color = c;\r\n                        } else {\r\n                            color = mix(color, c, boneWgt);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                vColor = color;\r\n\r\n                vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);\r\n\r\n                gl_Position = projection * view * worldPos;\r\n            }`,\r\n                fragmentSource: `\r\n            precision highp float;\r\n            varying vec3 vColor;\r\n\r\n            void main() {\r\n                vec4 color = vec4( vColor, 1.0 );\r\n                gl_FragColor = color;\r\n            }\r\n            `,\r\n            },\r\n            {\r\n                attributes: [\"position\", \"normal\", \"matricesIndices\", \"matricesWeights\"],\r\n                uniforms: [\"world\", \"worldView\", \"worldViewProjection\", \"view\", \"projection\", \"viewProjection\", \"colorMap\"],\r\n            }\r\n        );\r\n\r\n        shader.setFloats(\"colorMap\", colorMapBuffer);\r\n\r\n        shader.getClassName = (): string => {\r\n            return \"SkeletonMapShader\";\r\n        };\r\n\r\n        shader.transparencyMode = Material.MATERIAL_OPAQUE;\r\n\r\n        return shader;\r\n    }\r\n\r\n    /** private static method to create a BoneWeight Shader\r\n     * @param size The size of the buffer to create (usually the bone count)\r\n     * @param colorMap The gradient data to generate\r\n     * @param scene The scene that the shader is scoped to\r\n     * @returns an Array of floats from the color gradient values\r\n     */\r\n    private static _CreateBoneMapColorBuffer(size: number, colorMap: ISkeletonMapShaderColorMapKnot[], scene: Scene) {\r\n        const tempGrad = new DynamicTexture(\"temp\", { width: size, height: 1 }, scene, false);\r\n        const ctx = tempGrad.getContext();\r\n        const grad = ctx.createLinearGradient(0, 0, size, 0);\r\n\r\n        for (const stop of colorMap) {\r\n            grad.addColorStop(stop.location, stop.color.toHexString());\r\n        }\r\n\r\n        ctx.fillStyle = grad;\r\n        ctx.fillRect(0, 0, size, 1);\r\n        tempGrad.update();\r\n        const buffer: number[] = [];\r\n        const data: Uint8ClampedArray = ctx.getImageData(0, 0, size, 1).data;\r\n        const rUnit = 1 / 255;\r\n        for (let i = 0; i < data.length; i++) {\r\n            buffer.push(data[i] * rUnit);\r\n        }\r\n        tempGrad.dispose();\r\n        return buffer;\r\n    }\r\n\r\n    /** If SkeletonViewer scene scope. */\r\n    private _scene: Scene;\r\n\r\n    /** Gets or sets the color used to render the skeleton */\r\n    public color: Color3 = Color3.White();\r\n\r\n    /** Array of the points of the skeleton fo the line view. */\r\n    private _debugLines = new Array<Array<Vector3>>();\r\n\r\n    /** The SkeletonViewers Mesh. */\r\n    private _debugMesh: Nullable<LinesMesh>;\r\n\r\n    /** The local axes Meshes. */\r\n    private _localAxes: Nullable<LinesMesh> = null;\r\n\r\n    /** If SkeletonViewer is enabled. */\r\n    private _isEnabled = true;\r\n\r\n    /** If SkeletonViewer is ready. */\r\n    private _ready: boolean;\r\n\r\n    /** SkeletonViewer render observable. */\r\n    private _obs: Nullable<Observer<Scene>> = null;\r\n\r\n    /** The Utility Layer to render the gizmos in. */\r\n    private _utilityLayer: Nullable<UtilityLayerRenderer>;\r\n\r\n    private _boneIndices: Set<number>;\r\n\r\n    /** Gets the Scene. */\r\n    get scene(): Scene {\r\n        return this._scene;\r\n    }\r\n    /** Gets the utilityLayer. */\r\n    get utilityLayer(): Nullable<UtilityLayerRenderer> {\r\n        return this._utilityLayer;\r\n    }\r\n    /** Checks Ready Status. */\r\n    get isReady(): boolean {\r\n        return this._ready;\r\n    }\r\n    /** Sets Ready Status. */\r\n    set ready(value: boolean) {\r\n        this._ready = value;\r\n    }\r\n    /** Gets the debugMesh */\r\n    get debugMesh(): Nullable<AbstractMesh> | Nullable<LinesMesh> {\r\n        return this._debugMesh;\r\n    }\r\n    /** Sets the debugMesh */\r\n    set debugMesh(value: Nullable<AbstractMesh> | Nullable<LinesMesh>) {\r\n        this._debugMesh = value as any;\r\n    }\r\n    /** Gets the local axes mesh */\r\n    get debugLocalAxesMesh(): Nullable<LinesMesh> {\r\n        return this._localAxes;\r\n    }\r\n    /** Gets the displayMode */\r\n    get displayMode(): number {\r\n        return this.options.displayMode || SkeletonViewer.DISPLAY_LINES;\r\n    }\r\n    /** Sets the displayMode */\r\n    set displayMode(value: number) {\r\n        if (value > SkeletonViewer.DISPLAY_SPHERE_AND_SPURS) {\r\n            value = SkeletonViewer.DISPLAY_LINES;\r\n        }\r\n        this.options.displayMode = value;\r\n    }\r\n    /**\r\n     * Creates a new SkeletonViewer\r\n     * @param skeleton defines the skeleton to render\r\n     * @param mesh defines the mesh attached to the skeleton\r\n     * @param scene defines the hosting scene\r\n     * @param autoUpdateBonesMatrices defines a boolean indicating if bones matrices must be forced to update before rendering (true by default)\r\n     * @param renderingGroupId defines the rendering group id to use with the viewer\r\n     * @param options All of the extra constructor options for the SkeletonViewer\r\n     */\r\n    constructor(\r\n        /** defines the skeleton to render */\r\n        public skeleton: Skeleton,\r\n        /** defines the mesh attached to the skeleton */\r\n        public mesh: Nullable<AbstractMesh>,\r\n        /** The Scene scope*/\r\n        scene: Scene,\r\n        /** [true] defines a boolean indicating if bones matrices must be forced to update before rendering (true by default)  */\r\n        public autoUpdateBonesMatrices: boolean = true,\r\n        /** [2] defines the rendering group id to use with the viewer */\r\n        public renderingGroupId: number = 2,\r\n        /** [Object] is the options for the viewer */\r\n        public options: Partial<ISkeletonViewerOptions> = {}\r\n    ) {\r\n        this._scene = scene;\r\n        this._ready = false;\r\n\r\n        //Defaults\r\n        options.pauseAnimations = options.pauseAnimations ?? true;\r\n        options.returnToRest = options.returnToRest ?? false;\r\n        options.displayMode = options.displayMode ?? SkeletonViewer.DISPLAY_LINES;\r\n        options.displayOptions = options.displayOptions ?? {};\r\n        options.displayOptions.midStep = options.displayOptions.midStep ?? 0.235;\r\n        options.displayOptions.midStepFactor = options.displayOptions.midStepFactor ?? 0.155;\r\n        options.displayOptions.sphereBaseSize = options.displayOptions.sphereBaseSize ?? 0.15;\r\n        options.displayOptions.sphereScaleUnit = options.displayOptions.sphereScaleUnit ?? 2;\r\n        options.displayOptions.sphereFactor = options.displayOptions.sphereFactor ?? 0.865;\r\n        options.displayOptions.spurFollowsChild = options.displayOptions.spurFollowsChild ?? false;\r\n        options.displayOptions.showLocalAxes = options.displayOptions.showLocalAxes ?? false;\r\n        options.displayOptions.localAxesSize = options.displayOptions.localAxesSize ?? 0.075;\r\n        options.computeBonesUsingShaders = options.computeBonesUsingShaders ?? true;\r\n        options.useAllBones = options.useAllBones ?? true;\r\n\r\n        this._boneIndices = new Set();\r\n\r\n        if (!options.useAllBones) {\r\n            const initialMeshBoneIndices = mesh?.getVerticesData(VertexBuffer.MatricesIndicesKind);\r\n            const initialMeshBoneWeights = mesh?.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n\r\n            if (initialMeshBoneIndices && initialMeshBoneWeights) {\r\n                for (let i = 0; i < initialMeshBoneIndices.length; ++i) {\r\n                    const index = initialMeshBoneIndices[i],\r\n                        weight = initialMeshBoneWeights[i];\r\n                    if (weight !== 0) {\r\n                        this._boneIndices.add(index);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        /* Create Utility Layer */\r\n        this._utilityLayer = new UtilityLayerRenderer(this._scene, false);\r\n        this._utilityLayer.pickUtilitySceneFirst = false;\r\n        this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = true;\r\n\r\n        let displayMode = this.options.displayMode || 0;\r\n        if (displayMode > SkeletonViewer.DISPLAY_SPHERE_AND_SPURS) {\r\n            displayMode = SkeletonViewer.DISPLAY_LINES;\r\n        }\r\n        this.displayMode = displayMode;\r\n        //Prep the Systems\r\n        this.update();\r\n        this._bindObs();\r\n    }\r\n\r\n    /** The Dynamic bindings for the update functions */\r\n    private _bindObs(): void {\r\n        switch (this.displayMode) {\r\n            case SkeletonViewer.DISPLAY_LINES: {\r\n                this._obs = this.scene.onBeforeRenderObservable.add(() => {\r\n                    this._displayLinesUpdate();\r\n                });\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    /** Update the viewer to sync with current skeleton state, only used to manually update. */\r\n    public update(): void {\r\n        switch (this.displayMode) {\r\n            case SkeletonViewer.DISPLAY_LINES: {\r\n                this._displayLinesUpdate();\r\n                break;\r\n            }\r\n            case SkeletonViewer.DISPLAY_SPHERES: {\r\n                this._buildSpheresAndSpurs(true);\r\n                break;\r\n            }\r\n            case SkeletonViewer.DISPLAY_SPHERE_AND_SPURS: {\r\n                this._buildSpheresAndSpurs(false);\r\n                break;\r\n            }\r\n        }\r\n\r\n        this._buildLocalAxes();\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the viewer is enabled */\r\n    public set isEnabled(value: boolean) {\r\n        if (this.isEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._isEnabled = value;\r\n\r\n        if (this.debugMesh) {\r\n            this.debugMesh.setEnabled(value);\r\n        }\r\n\r\n        this._localAxes?.setEnabled(value);\r\n\r\n        if (value && !this._obs) {\r\n            this._bindObs();\r\n        } else if (!value && this._obs) {\r\n            this.scene.onBeforeRenderObservable.remove(this._obs);\r\n            this._obs = null;\r\n        }\r\n    }\r\n\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    private _getBonePosition(position: Vector3, bone: Bone, meshMat: Matrix, x = 0, y = 0, z = 0): void {\r\n        const tmat = TmpVectors.Matrix[0];\r\n        const parentBone = bone.getParent();\r\n        tmat.copyFrom(bone.getLocalMatrix());\r\n\r\n        if (x !== 0 || y !== 0 || z !== 0) {\r\n            const tmat2 = TmpVectors.Matrix[1];\r\n            Matrix.IdentityToRef(tmat2);\r\n            tmat2.setTranslationFromFloats(x, y, z);\r\n            tmat2.multiplyToRef(tmat, tmat);\r\n        }\r\n\r\n        if (parentBone) {\r\n            tmat.multiplyToRef(parentBone.getAbsoluteMatrix(), tmat);\r\n        }\r\n\r\n        tmat.multiplyToRef(meshMat, tmat);\r\n\r\n        position.x = tmat.m[12];\r\n        position.y = tmat.m[13];\r\n        position.z = tmat.m[14];\r\n    }\r\n\r\n    private _getLinesForBonesWithLength(bones: Bone[], mesh: Nullable<AbstractMesh>): void {\r\n        const len = bones.length;\r\n\r\n        let matrix;\r\n        let meshPos;\r\n        if (mesh) {\r\n            matrix = mesh.getWorldMatrix();\r\n            meshPos = mesh.position;\r\n        } else {\r\n            matrix = new Matrix();\r\n            meshPos = bones[0].position;\r\n        }\r\n        let idx = 0;\r\n        for (let i = 0; i < len; i++) {\r\n            const bone = bones[i];\r\n            let points = this._debugLines[idx];\r\n\r\n            if (bone._index === -1 || (!this._boneIndices.has(bone.getIndex()) && !this.options.useAllBones)) {\r\n                continue;\r\n            }\r\n            if (!points) {\r\n                points = [Vector3.Zero(), Vector3.Zero()];\r\n                this._debugLines[idx] = points;\r\n            }\r\n            this._getBonePosition(points[0], bone, matrix);\r\n            this._getBonePosition(points[1], bone, matrix, 0, bone.length, 0);\r\n            points[0].subtractInPlace(meshPos);\r\n            points[1].subtractInPlace(meshPos);\r\n            idx++;\r\n        }\r\n    }\r\n\r\n    private _getLinesForBonesNoLength(bones: Bone[]): void {\r\n        const len = bones.length;\r\n        let boneNum = 0;\r\n\r\n        const mesh = this.mesh;\r\n        let transformNode;\r\n        let meshPos;\r\n        if (mesh) {\r\n            transformNode = mesh;\r\n            meshPos = mesh.position;\r\n        } else {\r\n            transformNode = new TransformNode(\"\");\r\n            meshPos = bones[0].position;\r\n        }\r\n        for (let i = len - 1; i >= 0; i--) {\r\n            const childBone = bones[i];\r\n            const parentBone = childBone.getParent();\r\n            if (!parentBone || (!this._boneIndices.has(childBone.getIndex()) && !this.options.useAllBones)) {\r\n                continue;\r\n            }\r\n            let points = this._debugLines[boneNum];\r\n            if (!points) {\r\n                points = [Vector3.Zero(), Vector3.Zero()];\r\n                this._debugLines[boneNum] = points;\r\n            }\r\n            childBone.getAbsolutePositionToRef(transformNode, points[0]);\r\n            parentBone.getAbsolutePositionToRef(transformNode, points[1]);\r\n            points[0].subtractInPlace(meshPos);\r\n            points[1].subtractInPlace(meshPos);\r\n            boneNum++;\r\n        }\r\n        if (!mesh) {\r\n            transformNode.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * function to revert the mesh and scene back to the initial state.\r\n     * @param animationState\r\n     */\r\n    private _revert(animationState: boolean): void {\r\n        if (this.options.pauseAnimations) {\r\n            this.scene.animationsEnabled = animationState;\r\n            this.utilityLayer!.utilityLayerScene.animationsEnabled = animationState;\r\n        }\r\n    }\r\n\r\n    private _createSpur(anchorPoint: Vector3, bone: Bone, childPoint: Vector3, childBone: Nullable<Bone>, displayOptions: ISkeletonViewerDisplayOptions, utilityLayerScene: Scene) {\r\n        const dir = childPoint.subtract(anchorPoint);\r\n        const h = dir.length();\r\n        const up = dir.normalize().scale(h);\r\n\r\n        const midStep = displayOptions.midStep || 0.165;\r\n        const midStepFactor = displayOptions.midStepFactor || 0.215;\r\n\r\n        const up0 = up.scale(midStep);\r\n\r\n        const spur = ExtrudeShapeCustom(\r\n            \"skeletonViewer\",\r\n            {\r\n                shape: [new Vector3(1, -1, 0), new Vector3(1, 1, 0), new Vector3(-1, 1, 0), new Vector3(-1, -1, 0), new Vector3(1, -1, 0)],\r\n                path: [Vector3.Zero(), up0, up],\r\n                scaleFunction: (i: number) => {\r\n                    switch (i) {\r\n                        case 0:\r\n                        case 2:\r\n                            return 0;\r\n                        case 1:\r\n                            return h * midStepFactor;\r\n                    }\r\n                    return 0;\r\n                },\r\n                sideOrientation: Mesh.DEFAULTSIDE,\r\n                updatable: false,\r\n            },\r\n            utilityLayerScene\r\n        );\r\n\r\n        const numVertices = spur.getTotalVertices();\r\n        const mwk: number[] = [],\r\n            mik: number[] = [];\r\n\r\n        for (let i = 0; i < numVertices; i++) {\r\n            mwk.push(1, 0, 0, 0);\r\n\r\n            // Select verts at end of spur (ie vert 10 to 14) and bind to child\r\n            // bone if spurFollowsChild is enabled.\r\n            if (childBone && displayOptions.spurFollowsChild && i > 9) {\r\n                mik.push(childBone.getIndex(), 0, 0, 0);\r\n            } else {\r\n                mik.push(bone.getIndex(), 0, 0, 0);\r\n            }\r\n        }\r\n\r\n        spur.position = anchorPoint.clone();\r\n\r\n        spur.setVerticesData(VertexBuffer.MatricesWeightsKind, mwk, false);\r\n        spur.setVerticesData(VertexBuffer.MatricesIndicesKind, mik, false);\r\n        spur.convertToFlatShadedMesh();\r\n\r\n        return spur;\r\n    }\r\n\r\n    private _getBoundingSphereForBone(boneIndex: number) {\r\n        if (!this.mesh) {\r\n            return null;\r\n        }\r\n\r\n        const positions = this.mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const indices = this.mesh.getIndices();\r\n        const boneWeights = this.mesh.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n        const boneIndices = this.mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);\r\n        if (!positions || !indices || !boneWeights || !boneIndices) {\r\n            return null;\r\n        }\r\n\r\n        const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n        let found = 0;\r\n        for (let i = 0; i < indices.length; ++i) {\r\n            const vertexIndex = indices[i];\r\n\r\n            for (let b = 0; b < 4; ++b) {\r\n                const bIndex = boneIndices[vertexIndex * 4 + b];\r\n                const bWeight = boneWeights[vertexIndex * 4 + b];\r\n\r\n                if (bIndex === boneIndex && bWeight > 1e-5) {\r\n                    Vector3.FromArrayToRef(positions, vertexIndex * 3, TmpVectors.Vector3[0]);\r\n                    min.minimizeInPlace(TmpVectors.Vector3[0]);\r\n                    max.maximizeInPlace(TmpVectors.Vector3[0]);\r\n                    found++;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        return found > 1\r\n            ? {\r\n                  center: Vector3.Center(min, max),\r\n                  radius: Vector3.Distance(min, max) / 2,\r\n              }\r\n            : null;\r\n    }\r\n\r\n    /**\r\n     * function to build and bind sphere joint points and spur bone representations.\r\n     * @param spheresOnly\r\n     */\r\n    private _buildSpheresAndSpurs(spheresOnly = true): void {\r\n        if (this._debugMesh) {\r\n            this._debugMesh.dispose();\r\n            this._debugMesh = null;\r\n            this.ready = false;\r\n        }\r\n\r\n        this._ready = false;\r\n        const utilityLayerScene = this.utilityLayer?.utilityLayerScene as Scene;\r\n        const bones: Bone[] = this.skeleton.bones;\r\n        const spheres: Array<[Mesh, Bone]> = [];\r\n        const spurs: Mesh[] = [];\r\n\r\n        const animationState = this.scene.animationsEnabled;\r\n\r\n        try {\r\n            if (this.options.pauseAnimations) {\r\n                this.scene.animationsEnabled = false;\r\n                utilityLayerScene.animationsEnabled = false;\r\n            }\r\n\r\n            if (this.options.returnToRest) {\r\n                this.skeleton.returnToRest();\r\n            }\r\n\r\n            if (this.autoUpdateBonesMatrices) {\r\n                this.skeleton.computeAbsoluteMatrices();\r\n            }\r\n\r\n            let longestBoneLength = Number.NEGATIVE_INFINITY;\r\n            const displayOptions = this.options.displayOptions || {};\r\n\r\n            for (let i = 0; i < bones.length; i++) {\r\n                const bone = bones[i];\r\n\r\n                if (bone._index === -1 || (!this._boneIndices.has(bone.getIndex()) && !this.options.useAllBones)) {\r\n                    continue;\r\n                }\r\n\r\n                const boneAbsoluteBindPoseTransform = new Matrix();\r\n                bone.getAbsoluteInverseBindMatrix().invertToRef(boneAbsoluteBindPoseTransform);\r\n\r\n                const anchorPoint = new Vector3();\r\n\r\n                boneAbsoluteBindPoseTransform.decompose(undefined, undefined, anchorPoint);\r\n\r\n                if (bone.children.length > 0) {\r\n                    for (const bc of bone.children) {\r\n                        const childAbsoluteBindPoseTransform: Matrix = new Matrix();\r\n                        bc.getLocalMatrix().multiplyToRef(boneAbsoluteBindPoseTransform, childAbsoluteBindPoseTransform);\r\n                        const childPoint = new Vector3();\r\n                        childAbsoluteBindPoseTransform.decompose(undefined, undefined, childPoint);\r\n                        const distanceFromParent = Vector3.Distance(anchorPoint, childPoint);\r\n                        if (distanceFromParent > longestBoneLength) {\r\n                            longestBoneLength = distanceFromParent;\r\n                        }\r\n                        if (!spheresOnly) {\r\n                            spurs.push(this._createSpur(anchorPoint, bone, childPoint, bc, displayOptions, utilityLayerScene));\r\n                        }\r\n                    }\r\n                } else {\r\n                    const boundingSphere = this._getBoundingSphereForBone(bone.getIndex());\r\n                    if (boundingSphere) {\r\n                        if (boundingSphere.radius > longestBoneLength) {\r\n                            longestBoneLength = boundingSphere.radius;\r\n                        }\r\n                        if (!spheresOnly) {\r\n                            let childPoint;\r\n                            const parentBone = bone.getParent();\r\n                            if (parentBone) {\r\n                                parentBone.getAbsoluteInverseBindMatrix().invertToRef(boneAbsoluteBindPoseTransform);\r\n                                boneAbsoluteBindPoseTransform.decompose(undefined, undefined, TmpVectors.Vector3[0]);\r\n                                childPoint = anchorPoint.subtract(TmpVectors.Vector3[0]).normalize().scale(boundingSphere.radius).add(anchorPoint);\r\n                            } else {\r\n                                childPoint = boundingSphere.center.subtract(anchorPoint).normalize().scale(boundingSphere.radius).add(anchorPoint);\r\n                            }\r\n                            spurs.push(this._createSpur(anchorPoint, bone, childPoint, null, displayOptions, utilityLayerScene));\r\n                        }\r\n                    }\r\n                }\r\n\r\n                const sphereBaseSize = displayOptions.sphereBaseSize || 0.2;\r\n\r\n                const sphere = CreateSphere(\r\n                    \"skeletonViewer\",\r\n                    {\r\n                        segments: 6,\r\n                        diameter: sphereBaseSize,\r\n                        updatable: true,\r\n                    },\r\n                    utilityLayerScene\r\n                );\r\n\r\n                const numVertices = sphere.getTotalVertices();\r\n\r\n                const mwk: number[] = [],\r\n                    mik: number[] = [];\r\n\r\n                for (let i = 0; i < numVertices; i++) {\r\n                    mwk.push(1, 0, 0, 0);\r\n                    mik.push(bone.getIndex(), 0, 0, 0);\r\n                }\r\n\r\n                sphere.setVerticesData(VertexBuffer.MatricesWeightsKind, mwk, false);\r\n                sphere.setVerticesData(VertexBuffer.MatricesIndicesKind, mik, false);\r\n\r\n                sphere.position = anchorPoint.clone();\r\n                spheres.push([sphere, bone]);\r\n            }\r\n\r\n            const sphereScaleUnit = displayOptions.sphereScaleUnit || 2;\r\n            const sphereFactor = displayOptions.sphereFactor || 0.85;\r\n\r\n            const meshes = [];\r\n            for (let i = 0; i < spheres.length; i++) {\r\n                const [sphere, bone] = spheres[i];\r\n                const scale = 1 / (sphereScaleUnit / longestBoneLength);\r\n\r\n                let _stepsOut = 0;\r\n                let _b = bone;\r\n\r\n                while (_b.getParent() && (_b.getParent() as Bone).getIndex() !== -1) {\r\n                    _stepsOut++;\r\n                    _b = _b.getParent() as Bone;\r\n                }\r\n                sphere.scaling.scaleInPlace(scale * Math.pow(sphereFactor, _stepsOut));\r\n                meshes.push(sphere);\r\n            }\r\n\r\n            this.debugMesh = Mesh.MergeMeshes(meshes.concat(spurs), true, true);\r\n            if (this.debugMesh) {\r\n                this.debugMesh.renderingGroupId = this.renderingGroupId;\r\n                this.debugMesh.skeleton = this.skeleton;\r\n                this.debugMesh.parent = this.mesh;\r\n                this.debugMesh.computeBonesUsingShaders = this.options.computeBonesUsingShaders ?? true;\r\n                this.debugMesh.alwaysSelectAsActiveMesh = true;\r\n            }\r\n\r\n            const light = this.utilityLayer!._getSharedGizmoLight();\r\n            light.intensity = 0.7;\r\n\r\n            this._revert(animationState);\r\n            this.ready = true;\r\n        } catch (err) {\r\n            Logger.Error(err);\r\n            this._revert(animationState);\r\n            this.dispose();\r\n        }\r\n    }\r\n\r\n    private _buildLocalAxes(): void {\r\n        if (this._localAxes) {\r\n            this._localAxes.dispose();\r\n        }\r\n\r\n        this._localAxes = null;\r\n\r\n        const displayOptions = this.options.displayOptions || {};\r\n\r\n        if (!displayOptions.showLocalAxes) {\r\n            return;\r\n        }\r\n\r\n        const targetScene = this._utilityLayer!.utilityLayerScene;\r\n        const size = displayOptions.localAxesSize || 0.075;\r\n        const lines = [];\r\n        const colors = [];\r\n        const red = new Color4(1, 0, 0, 1);\r\n        const green = new Color4(0, 1, 0, 1);\r\n        const blue = new Color4(0, 0, 1, 1);\r\n\r\n        const mwk: number[] = [];\r\n        const mik: number[] = [];\r\n        const vertsPerBone = 6;\r\n\r\n        for (const i in this.skeleton.bones) {\r\n            const bone = this.skeleton.bones[i];\r\n\r\n            if (bone._index === -1 || (!this._boneIndices.has(bone.getIndex()) && !this.options.useAllBones)) {\r\n                continue;\r\n            }\r\n\r\n            const boneAbsoluteBindPoseTransform = new Matrix();\r\n            const boneOrigin = new Vector3();\r\n\r\n            bone.getAbsoluteInverseBindMatrix().invertToRef(boneAbsoluteBindPoseTransform);\r\n            boneAbsoluteBindPoseTransform.decompose(undefined, TmpVectors.Quaternion[0], boneOrigin);\r\n\r\n            const m = new Matrix();\r\n            TmpVectors.Quaternion[0].toRotationMatrix(m);\r\n\r\n            const boneAxisX = Vector3.TransformCoordinates(new Vector3(0 + size, 0, 0), m);\r\n            const boneAxisY = Vector3.TransformCoordinates(new Vector3(0, 0 + size, 0), m);\r\n            const boneAxisZ = Vector3.TransformCoordinates(new Vector3(0, 0, 0 + size), m);\r\n\r\n            const axisX = [boneOrigin, boneOrigin.add(boneAxisX)];\r\n            const axisY = [boneOrigin, boneOrigin.add(boneAxisY)];\r\n            const axisZ = [boneOrigin, boneOrigin.add(boneAxisZ)];\r\n\r\n            const linePoints = [axisX, axisY, axisZ];\r\n            const lineColors = [\r\n                [red, red],\r\n                [green, green],\r\n                [blue, blue],\r\n            ];\r\n\r\n            lines.push(...linePoints);\r\n            colors.push(...lineColors);\r\n\r\n            for (let j = 0; j < vertsPerBone; j++) {\r\n                mwk.push(1, 0, 0, 0);\r\n                mik.push(bone.getIndex(), 0, 0, 0);\r\n            }\r\n        }\r\n\r\n        this._localAxes = CreateLineSystem(\"localAxes\", { lines: lines, colors: colors, updatable: true }, targetScene);\r\n        this._localAxes.setVerticesData(VertexBuffer.MatricesWeightsKind, mwk, false);\r\n        this._localAxes.setVerticesData(VertexBuffer.MatricesIndicesKind, mik, false);\r\n        this._localAxes.skeleton = this.skeleton;\r\n        this._localAxes.renderingGroupId = this.renderingGroupId + 1;\r\n        this._localAxes.parent = this.mesh;\r\n        this._localAxes.computeBonesUsingShaders = this.options.computeBonesUsingShaders ?? true;\r\n    }\r\n\r\n    /** Update the viewer to sync with current skeleton state, only used for the line display. */\r\n    private _displayLinesUpdate(): void {\r\n        if (!this._utilityLayer) {\r\n            return;\r\n        }\r\n\r\n        if (this.autoUpdateBonesMatrices) {\r\n            this.skeleton.computeAbsoluteMatrices();\r\n        }\r\n\r\n        if (this.skeleton.bones[0].length === undefined) {\r\n            this._getLinesForBonesNoLength(this.skeleton.bones);\r\n        } else {\r\n            this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh);\r\n        }\r\n\r\n        const targetScene = this._utilityLayer.utilityLayerScene;\r\n\r\n        if (targetScene) {\r\n            if (!this._debugMesh) {\r\n                this._debugMesh = CreateLineSystem(\"\", { lines: this._debugLines, updatable: true, instance: null }, targetScene);\r\n                this._debugMesh.renderingGroupId = this.renderingGroupId;\r\n            } else {\r\n                CreateLineSystem(\"\", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, targetScene);\r\n            }\r\n            if (this.mesh) {\r\n                this._debugMesh.position.copyFrom(this.mesh.position);\r\n            } else {\r\n                this._debugMesh.position.copyFrom(this.skeleton.bones[0].position);\r\n            }\r\n            this._debugMesh.color = this.color;\r\n        }\r\n    }\r\n    /** Changes the displayMode of the skeleton viewer\r\n     * @param mode The displayMode numerical value\r\n     */\r\n    public changeDisplayMode(mode: number): void {\r\n        const wasEnabled = this.isEnabled ? true : false;\r\n        if (this.displayMode !== mode) {\r\n            this.isEnabled = false;\r\n            if (this._debugMesh) {\r\n                this._debugMesh.dispose();\r\n                this._debugMesh = null;\r\n                this.ready = false;\r\n            }\r\n            this.displayMode = mode;\r\n\r\n            this.update();\r\n            this._bindObs();\r\n            this.isEnabled = wasEnabled;\r\n        }\r\n    }\r\n\r\n    /** Sets a display option of the skeleton viewer\r\n     *\r\n     * | Option           | Type    | Default | Description |\r\n     * | ---------------- | ------- | ------- | ----------- |\r\n     * | midStep          | float   | 0.235   | A percentage between a bone and its child that determines the widest part of a spur. Only used when `displayMode` is set to `DISPLAY_SPHERE_AND_SPURS`. |\r\n     * | midStepFactor    | float   | 0.15    | Mid step width expressed as a factor of the length. A value of 0.5 makes the spur width half of the spur length. Only used when `displayMode` is set to `DISPLAY_SPHERE_AND_SPURS`. |\r\n     * | sphereBaseSize   | float   | 2       | Sphere base size. Only used when `displayMode` is set to `DISPLAY_SPHERE_AND_SPURS`. |\r\n     * | sphereScaleUnit  | float   | 0.865   | Sphere scale factor used to scale spheres in relation to the longest bone. Only used when `displayMode` is set to `DISPLAY_SPHERE_AND_SPURS`. |\r\n     * | spurFollowsChild | boolean | false   | Whether a spur should attach its far end to the child bone. |\r\n     * | showLocalAxes    | boolean | false   | Displays local axes on all bones. |\r\n     * | localAxesSize    | float   | 0.075   | Determines the length of each local axis. |\r\n     *\r\n     * @param option String of the option name\r\n     * @param value The numerical option value\r\n     */\r\n    public changeDisplayOptions(option: string, value: number | boolean): void {\r\n        const wasEnabled = this.isEnabled ? true : false;\r\n        (this.options.displayOptions as any)[option] = value;\r\n        this.isEnabled = false;\r\n        if (this._debugMesh) {\r\n            this._debugMesh.dispose();\r\n            this._debugMesh = null;\r\n            this.ready = false;\r\n        }\r\n        this.update();\r\n        this._bindObs();\r\n        this._isEnabled = undefined as any; // force the isEnabled setter to reapply (next line)\r\n        this.isEnabled = wasEnabled;\r\n    }\r\n\r\n    /** Release associated resources */\r\n    public dispose(): void {\r\n        this.isEnabled = false;\r\n        if (this._debugMesh) {\r\n            this._debugMesh.dispose();\r\n            this._debugMesh = null;\r\n        }\r\n\r\n        if (this._utilityLayer) {\r\n            this._utilityLayer.dispose();\r\n            this._utilityLayer = null;\r\n        }\r\n\r\n        this.ready = false;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Camera, type FrameGraph, type Nullable, type FrameGraphObjectRendererTask } from \"core/index\";\r\nimport { UtilityLayerRenderer } from \"core/Rendering/utilityLayerRenderer\";\r\n\r\n/**\r\n * Looks for the main camera used by the frame graph.\r\n * By default, this is the camera used by the main object renderer task.\r\n * If no such task, we try to find a camera in either a geometry renderer or a utility layer renderer tasks.\r\n * @param frameGraph The frame graph to search in\r\n * @returns The main camera used by the frame graph, or null if not found\r\n */\r\nexport function FindMainCamera(frameGraph: FrameGraph): Nullable<Camera> {\r\n    return frameGraph.findMainCamera();\r\n}\r\n\r\n/**\r\n * Looks for the main object renderer task in the frame graph.\r\n * By default, this is the object/geometry renderer task with isMainObjectRenderer set to true.\r\n * If no such task, we return the last object/geometry renderer task that has an object list with meshes (or null if none found).\r\n * @param frameGraph The frame graph to search in\r\n * @returns The main object renderer of the frame graph, or null if not found\r\n */\r\nexport function FindMainObjectRenderer(frameGraph: FrameGraph): Nullable<FrameGraphObjectRendererTask> {\r\n    return frameGraph.findMainObjectRenderer();\r\n}\r\n\r\n/**\r\n * Creates a utility layer renderer compatible with the given frame graph.\r\n * @param frameFraph The frame graph to create the utility layer renderer for\r\n * @param handleEvents True if the utility layer renderer should handle events, false otherwise (default is true)\r\n * @returns The created utility layer renderer\r\n */\r\nexport function CreateUtilityLayerRenderer(frameFraph: FrameGraph, handleEvents = true): UtilityLayerRenderer {\r\n    const scene = frameFraph.scene;\r\n    const layer = new UtilityLayerRenderer(scene, handleEvents, true);\r\n\r\n    layer.utilityLayerScene.activeCamera = scene.activeCamera;\r\n\r\n    let camera = FrameGraphUtils.FindMainCamera(scene.frameGraph!);\r\n\r\n    if (!camera && scene.cameras.length > 0) {\r\n        camera = scene.cameras[0];\r\n    }\r\n\r\n    if (camera) {\r\n        layer.setRenderCamera(camera);\r\n        layer.utilityLayerScene.activeCamera = camera;\r\n    }\r\n\r\n    const gizmoLayerRenderObserver = scene.onAfterRenderObservable.add(() => {\r\n        layer.render();\r\n    });\r\n\r\n    layer.utilityLayerScene.onDisposeObservable.addOnce(() => {\r\n        scene.onAfterRenderObservable.remove(gizmoLayerRenderObserver);\r\n    });\r\n\r\n    return layer;\r\n}\r\n\r\n/**\r\n * Class used to host frame graph specific utilities\r\n */\r\nexport const FrameGraphUtils = {\r\n    /**\r\n     * Looks for the main camera used by the frame graph.\r\n     * We assume that the camera used by the the last rendering task in the graph is the main camera.\r\n     * @param frameGraph The frame graph to search in\r\n     * @returns The main camera used by the frame graph, or null if not found\r\n     */\r\n    FindMainCamera,\r\n\r\n    /**\r\n     * Looks for the main object renderer task in the frame graph.\r\n     * We assume that the last object renderer task that has an object list with meshes is the main object renderer.\r\n     * @param frameGraph The frame graph to search in\r\n     * @returns The main object renderer of the frame graph, or null if not found\r\n     */\r\n    FindMainObjectRenderer,\r\n\r\n    /**\r\n     * Creates a utility layer renderer compatible with the given frame graph.\r\n     * @param frameFraph The frame graph to create the utility layer renderer for\r\n     * @param handleEvents True if the utility layer renderer should handle events, false otherwise\r\n     * @returns The created utility layer renderer\r\n     */\r\n    CreateUtilityLayerRenderer,\r\n};\r\n","import { type Nullable } from \"core/types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type DirectionalLight } from \"../Lights/directionalLight\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { CreateLines } from \"../Meshes/Builders/linesBuilder.pure\";\r\nimport { type LinesMesh } from \"../Meshes/linesMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type FrameGraph } from \"core/FrameGraph/frameGraph\";\r\nimport { FrameGraphUtils } from \"core/FrameGraph/frameGraphUtils\";\r\n\r\n/**\r\n * Class used to render a debug view of the frustum for a directional light\r\n * @see https://playground.babylonjs.com/#7EFGSG#4\r\n * @since 5.0.0\r\n */\r\nexport class DirectionalLightFrustumViewer {\r\n    private _scene: Scene;\r\n    private _light: DirectionalLight;\r\n    private _camera: Nullable<Camera>;\r\n    private _inverseViewMatrix: Matrix;\r\n    private _visible: boolean;\r\n\r\n    private _rootNode: TransformNode;\r\n    private _lightHelperFrustumMeshes: Mesh[];\r\n\r\n    private _nearLinesPoints: Vector3[];\r\n    private _farLinesPoints: Vector3[];\r\n    private _trLinesPoints: Vector3[];\r\n    private _brLinesPoints: Vector3[];\r\n    private _tlLinesPoints: Vector3[];\r\n    private _blLinesPoints: Vector3[];\r\n\r\n    private _nearPlaneVertices: number[];\r\n    private _farPlaneVertices: number[];\r\n    private _rightPlaneVertices: number[];\r\n    private _leftPlaneVertices: number[];\r\n    private _topPlaneVertices: number[];\r\n    private _bottomPlaneVertices: number[];\r\n\r\n    private _oldPosition: Vector3 = new Vector3(Number.NaN, Number.NaN, Number.NaN);\r\n    private _oldDirection: Vector3 = new Vector3(Number.NaN, Number.NaN, Number.NaN);\r\n    private _oldAutoCalc: boolean;\r\n    private _oldMinZ: number;\r\n    private _oldMaxZ: number;\r\n    private _oldOrthoLeft: number;\r\n    private _oldOrthoRight: number;\r\n    private _oldOrthoTop: number;\r\n    private _oldOrthoBottom: number;\r\n\r\n    private _transparency = 0.3;\r\n    /**\r\n     * Gets or sets the transparency of the frustum planes\r\n     */\r\n    public get transparency(): number {\r\n        return this._transparency;\r\n    }\r\n\r\n    public set transparency(alpha: number) {\r\n        this._transparency = alpha;\r\n        for (let i = 6; i < 12; ++i) {\r\n            this._lightHelperFrustumMeshes[i].material!.alpha = alpha;\r\n        }\r\n    }\r\n\r\n    private _showLines = true;\r\n    /**\r\n     * true to display the edges of the frustum\r\n     */\r\n    public get showLines(): boolean {\r\n        return this._showLines;\r\n    }\r\n\r\n    public set showLines(show: boolean) {\r\n        if (this._showLines === show) {\r\n            return;\r\n        }\r\n        this._showLines = show;\r\n        for (let i = 0; i < 6; ++i) {\r\n            this._lightHelperFrustumMeshes[i].setEnabled(show);\r\n        }\r\n    }\r\n\r\n    private _showPlanes = true;\r\n    /**\r\n     * true to display the planes of the frustum\r\n     */\r\n    public get showPlanes(): boolean {\r\n        return this._showPlanes;\r\n    }\r\n\r\n    public set showPlanes(show: boolean) {\r\n        if (this._showPlanes === show) {\r\n            return;\r\n        }\r\n        this._showPlanes = show;\r\n        for (let i = 6; i < 12; ++i) {\r\n            this._lightHelperFrustumMeshes[i].setEnabled(show);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new frustum viewer\r\n     * @param light directional light to display the frustum for\r\n     * @param camera camera used to retrieve the minZ / maxZ values if the shadowMinZ/shadowMaxZ values of the light are not setup\r\n     */\r\n    constructor(light: DirectionalLight, camera: Nullable<Camera> = null) {\r\n        this._scene = light.getScene();\r\n        this._light = light;\r\n        this._camera = camera;\r\n        this._inverseViewMatrix = Matrix.Identity();\r\n        this._lightHelperFrustumMeshes = [];\r\n        this._createGeometry();\r\n        this.show();\r\n        this.update();\r\n    }\r\n\r\n    /**\r\n     * Shows the frustum\r\n     */\r\n    public show() {\r\n        if (this._scene.frameGraph) {\r\n            this._removeMeshesFromFrameGraph(this._scene.frameGraph);\r\n            this._addMeshesToFrameGraph(this._scene.frameGraph);\r\n        }\r\n        this._lightHelperFrustumMeshes.forEach((mesh, index) => {\r\n            mesh.setEnabled((index < 6 && this._showLines) || (index >= 6 && this._showPlanes));\r\n        });\r\n        this._oldPosition.set(Number.NaN, Number.NaN, Number.NaN);\r\n        this._visible = true;\r\n    }\r\n\r\n    /**\r\n     * Hides the frustum\r\n     */\r\n    public hide() {\r\n        if (this._scene.frameGraph) {\r\n            this._removeMeshesFromFrameGraph(this._scene.frameGraph);\r\n        }\r\n        for (const mesh of this._lightHelperFrustumMeshes) {\r\n            mesh.setEnabled(false);\r\n        }\r\n        this._visible = false;\r\n    }\r\n\r\n    private _addMeshesToFrameGraph(frameGraph: FrameGraph) {\r\n        const objectRenderer = FrameGraphUtils.FindMainObjectRenderer(frameGraph);\r\n        if (objectRenderer && objectRenderer.objectList.meshes) {\r\n            for (const mesh of this._lightHelperFrustumMeshes) {\r\n                objectRenderer.objectList.meshes.push(mesh);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _removeMeshesFromFrameGraph(frameGraph: FrameGraph) {\r\n        const objectRenderer = FrameGraphUtils.FindMainObjectRenderer(frameGraph);\r\n        if (objectRenderer && objectRenderer.objectList.meshes) {\r\n            for (const mesh of this._lightHelperFrustumMeshes) {\r\n                const index = objectRenderer.objectList.meshes!.indexOf(mesh);\r\n                if (index !== -1) {\r\n                    objectRenderer.objectList.meshes.splice(index, 1);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the frustum.\r\n     * Call this method to update the frustum view if the light has changed position/direction\r\n     */\r\n    public update() {\r\n        if (!this._visible) {\r\n            return;\r\n        }\r\n\r\n        if (\r\n            this._oldPosition.equals(this._light.position) &&\r\n            this._oldDirection.equals(this._light.direction) &&\r\n            this._oldAutoCalc === this._light.autoCalcShadowZBounds &&\r\n            this._oldMinZ === this._light.shadowMinZ &&\r\n            this._oldMaxZ === this._light.shadowMaxZ &&\r\n            this._oldOrthoLeft === this._light.orthoLeft &&\r\n            this._oldOrthoRight === this._light.orthoRight &&\r\n            this._oldOrthoTop === this._light.orthoTop &&\r\n            this._oldOrthoBottom === this._light.orthoBottom\r\n        ) {\r\n            return;\r\n        }\r\n\r\n        this._oldPosition.copyFrom(this._light.position);\r\n        this._oldDirection.copyFrom(this._light.direction);\r\n        this._oldAutoCalc = this._light.autoCalcShadowZBounds;\r\n        this._oldMinZ = this._light.shadowMinZ;\r\n        this._oldMaxZ = this._light.shadowMaxZ;\r\n        this._oldOrthoLeft = this._light.orthoLeft;\r\n        this._oldOrthoRight = this._light.orthoRight;\r\n        this._oldOrthoTop = this._light.orthoTop;\r\n        this._oldOrthoBottom = this._light.orthoBottom;\r\n\r\n        TmpVectors.Vector3[0].set(\r\n            this._light.orthoLeft,\r\n            this._light.orthoBottom,\r\n            this._light.shadowMinZ !== undefined ? this._light.shadowMinZ : (this._camera?.minZ ?? Constants.ShadowMinZ)\r\n        ); // min light extents\r\n        TmpVectors.Vector3[1].set(\r\n            this._light.orthoRight,\r\n            this._light.orthoTop,\r\n            this._light.shadowMaxZ !== undefined ? this._light.shadowMaxZ : (this._camera?.maxZ ?? Constants.ShadowMaxZ)\r\n        ); // max light extents\r\n\r\n        const invLightView = this._getInvertViewMatrix();\r\n\r\n        TmpVectors.Vector3[2].copyFromFloats(TmpVectors.Vector3[1].x, TmpVectors.Vector3[1].y, TmpVectors.Vector3[0].z); // n1\r\n        TmpVectors.Vector3[3].copyFromFloats(TmpVectors.Vector3[1].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[0].z); // n2\r\n        TmpVectors.Vector3[4].copyFromFloats(TmpVectors.Vector3[0].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[0].z); // n3\r\n        TmpVectors.Vector3[5].copyFromFloats(TmpVectors.Vector3[0].x, TmpVectors.Vector3[1].y, TmpVectors.Vector3[0].z); // n4\r\n\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[2], invLightView, TmpVectors.Vector3[2]); // near1\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[3], invLightView, TmpVectors.Vector3[3]); // near2\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[4], invLightView, TmpVectors.Vector3[4]); // near3\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[5], invLightView, TmpVectors.Vector3[5]); // near4\r\n\r\n        TmpVectors.Vector3[6].copyFromFloats(TmpVectors.Vector3[1].x, TmpVectors.Vector3[1].y, TmpVectors.Vector3[1].z); // f1\r\n        TmpVectors.Vector3[7].copyFromFloats(TmpVectors.Vector3[1].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[1].z); // f2\r\n        TmpVectors.Vector3[8].copyFromFloats(TmpVectors.Vector3[0].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[1].z); // f3\r\n        TmpVectors.Vector3[9].copyFromFloats(TmpVectors.Vector3[0].x, TmpVectors.Vector3[1].y, TmpVectors.Vector3[1].z); // f4\r\n\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[6], invLightView, TmpVectors.Vector3[6]); // far1\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[7], invLightView, TmpVectors.Vector3[7]); // far2\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[8], invLightView, TmpVectors.Vector3[8]); // far3\r\n        Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[9], invLightView, TmpVectors.Vector3[9]); // far4\r\n\r\n        CreateLines(\"nearlines\", { updatable: true, points: this._nearLinesPoints, instance: this._lightHelperFrustumMeshes[0] as LinesMesh }, this._scene);\r\n\r\n        CreateLines(\"farlines\", { updatable: true, points: this._farLinesPoints, instance: this._lightHelperFrustumMeshes[1] as LinesMesh }, this._scene);\r\n\r\n        CreateLines(\"trlines\", { updatable: true, points: this._trLinesPoints, instance: this._lightHelperFrustumMeshes[2] as LinesMesh }, this._scene);\r\n\r\n        CreateLines(\"brlines\", { updatable: true, points: this._brLinesPoints, instance: this._lightHelperFrustumMeshes[3] as LinesMesh }, this._scene);\r\n\r\n        CreateLines(\"tllines\", { updatable: true, points: this._tlLinesPoints, instance: this._lightHelperFrustumMeshes[4] as LinesMesh }, this._scene);\r\n\r\n        CreateLines(\"bllines\", { updatable: true, points: this._blLinesPoints, instance: this._lightHelperFrustumMeshes[5] as LinesMesh }, this._scene);\r\n\r\n        TmpVectors.Vector3[2].toArray(this._nearPlaneVertices, 0);\r\n        TmpVectors.Vector3[3].toArray(this._nearPlaneVertices, 3);\r\n        TmpVectors.Vector3[4].toArray(this._nearPlaneVertices, 6);\r\n        TmpVectors.Vector3[5].toArray(this._nearPlaneVertices, 9);\r\n        this._lightHelperFrustumMeshes[6].geometry?.updateVerticesDataDirectly(\"position\", this._nearPlaneVertices, 0);\r\n\r\n        TmpVectors.Vector3[6].toArray(this._farPlaneVertices, 0);\r\n        TmpVectors.Vector3[7].toArray(this._farPlaneVertices, 3);\r\n        TmpVectors.Vector3[8].toArray(this._farPlaneVertices, 6);\r\n        TmpVectors.Vector3[9].toArray(this._farPlaneVertices, 9);\r\n        this._lightHelperFrustumMeshes[7].geometry?.updateVerticesDataDirectly(\"position\", this._farPlaneVertices, 0);\r\n\r\n        TmpVectors.Vector3[2].toArray(this._rightPlaneVertices, 0);\r\n        TmpVectors.Vector3[6].toArray(this._rightPlaneVertices, 3);\r\n        TmpVectors.Vector3[7].toArray(this._rightPlaneVertices, 6);\r\n        TmpVectors.Vector3[3].toArray(this._rightPlaneVertices, 9);\r\n        this._lightHelperFrustumMeshes[8].geometry?.updateVerticesDataDirectly(\"position\", this._rightPlaneVertices, 0);\r\n\r\n        TmpVectors.Vector3[5].toArray(this._leftPlaneVertices, 0);\r\n        TmpVectors.Vector3[9].toArray(this._leftPlaneVertices, 3);\r\n        TmpVectors.Vector3[8].toArray(this._leftPlaneVertices, 6);\r\n        TmpVectors.Vector3[4].toArray(this._leftPlaneVertices, 9);\r\n        this._lightHelperFrustumMeshes[9].geometry?.updateVerticesDataDirectly(\"position\", this._leftPlaneVertices, 0);\r\n\r\n        TmpVectors.Vector3[2].toArray(this._topPlaneVertices, 0);\r\n        TmpVectors.Vector3[6].toArray(this._topPlaneVertices, 3);\r\n        TmpVectors.Vector3[9].toArray(this._topPlaneVertices, 6);\r\n        TmpVectors.Vector3[5].toArray(this._topPlaneVertices, 9);\r\n        this._lightHelperFrustumMeshes[10].geometry?.updateVerticesDataDirectly(\"position\", this._topPlaneVertices, 0);\r\n\r\n        TmpVectors.Vector3[3].toArray(this._bottomPlaneVertices, 0);\r\n        TmpVectors.Vector3[7].toArray(this._bottomPlaneVertices, 3);\r\n        TmpVectors.Vector3[8].toArray(this._bottomPlaneVertices, 6);\r\n        TmpVectors.Vector3[4].toArray(this._bottomPlaneVertices, 9);\r\n        this._lightHelperFrustumMeshes[11].geometry?.updateVerticesDataDirectly(\"position\", this._bottomPlaneVertices, 0);\r\n    }\r\n\r\n    /**\r\n     * Dispose of the class / remove the frustum view\r\n     */\r\n    public dispose() {\r\n        if (this._scene.frameGraph) {\r\n            this._removeMeshesFromFrameGraph(this._scene.frameGraph);\r\n        }\r\n        for (const mesh of this._lightHelperFrustumMeshes) {\r\n            mesh.material?.dispose();\r\n            mesh.dispose();\r\n        }\r\n        this._rootNode.dispose();\r\n    }\r\n\r\n    protected _createGeometry() {\r\n        this._rootNode = new TransformNode(\"directionalLightHelperRoot_\" + this._light.name, this._scene);\r\n        this._rootNode.parent = this._light.parent;\r\n\r\n        this._nearLinesPoints = [TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2], TmpVectors.Vector3[3], TmpVectors.Vector3[4]];\r\n        const nearLines = CreateLines(\"nearlines\", { updatable: true, points: this._nearLinesPoints }, this._scene);\r\n        nearLines.parent = this._rootNode;\r\n        nearLines.alwaysSelectAsActiveMesh = true;\r\n\r\n        this._farLinesPoints = [TmpVectors.Vector3[5], TmpVectors.Vector3[6], TmpVectors.Vector3[7], TmpVectors.Vector3[8], TmpVectors.Vector3[9]];\r\n        const farLines = CreateLines(\"farlines\", { updatable: true, points: this._farLinesPoints }, this._scene);\r\n        farLines.parent = this._rootNode;\r\n        farLines.alwaysSelectAsActiveMesh = true;\r\n\r\n        this._trLinesPoints = [TmpVectors.Vector3[10], TmpVectors.Vector3[11]];\r\n        const trLines = CreateLines(\"trlines\", { updatable: true, points: this._trLinesPoints }, this._scene);\r\n        trLines.parent = this._rootNode;\r\n        trLines.alwaysSelectAsActiveMesh = true;\r\n\r\n        this._brLinesPoints = [TmpVectors.Vector3[12], TmpVectors.Vector3[0]];\r\n        const brLines = CreateLines(\"brlines\", { updatable: true, points: this._brLinesPoints }, this._scene);\r\n        brLines.parent = this._rootNode;\r\n        brLines.alwaysSelectAsActiveMesh = true;\r\n\r\n        this._tlLinesPoints = [TmpVectors.Vector3[1], TmpVectors.Vector3[2]];\r\n        const tlLines = CreateLines(\"tllines\", { updatable: true, points: this._tlLinesPoints }, this._scene);\r\n        tlLines.parent = this._rootNode;\r\n        tlLines.alwaysSelectAsActiveMesh = true;\r\n\r\n        this._blLinesPoints = [TmpVectors.Vector3[3], TmpVectors.Vector3[4]];\r\n        const blLines = CreateLines(\"bllines\", { updatable: true, points: this._blLinesPoints }, this._scene);\r\n        blLines.parent = this._rootNode;\r\n        blLines.alwaysSelectAsActiveMesh = true;\r\n\r\n        this._lightHelperFrustumMeshes.push(nearLines, farLines, trLines, brLines, tlLines, blLines);\r\n\r\n        const makePlane = (name: string, color: Color3, positions: number[]) => {\r\n            const plane = new Mesh(name + \"plane\", this._scene);\r\n            const mat = new StandardMaterial(name + \"PlaneMat\", this._scene);\r\n\r\n            plane.material = mat;\r\n            plane.parent = this._rootNode;\r\n            plane.alwaysSelectAsActiveMesh = true;\r\n\r\n            mat.emissiveColor = color;\r\n            mat.alpha = this.transparency;\r\n            mat.backFaceCulling = false;\r\n            mat.disableLighting = true;\r\n\r\n            const indices = [0, 1, 2, 0, 2, 3];\r\n\r\n            const vertexData = new VertexData();\r\n\r\n            vertexData.positions = positions;\r\n            vertexData.indices = indices;\r\n\r\n            vertexData.applyToMesh(plane, true);\r\n\r\n            this._lightHelperFrustumMeshes.push(plane);\r\n        };\r\n\r\n        this._nearPlaneVertices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        this._farPlaneVertices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        this._rightPlaneVertices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        this._leftPlaneVertices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        this._topPlaneVertices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        this._bottomPlaneVertices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n\r\n        makePlane(\"near\", new Color3(1, 0, 0), this._nearPlaneVertices);\r\n        makePlane(\"far\", new Color3(0.3, 0, 0), this._farPlaneVertices);\r\n        makePlane(\"right\", new Color3(0, 1, 0), this._rightPlaneVertices);\r\n        makePlane(\"left\", new Color3(0, 0.3, 0), this._leftPlaneVertices);\r\n        makePlane(\"top\", new Color3(0, 0, 1), this._topPlaneVertices);\r\n        makePlane(\"bottom\", new Color3(0, 0, 0.3), this._bottomPlaneVertices);\r\n\r\n        this._nearLinesPoints[0] = TmpVectors.Vector3[2];\r\n        this._nearLinesPoints[1] = TmpVectors.Vector3[3];\r\n        this._nearLinesPoints[2] = TmpVectors.Vector3[4];\r\n        this._nearLinesPoints[3] = TmpVectors.Vector3[5];\r\n        this._nearLinesPoints[4] = TmpVectors.Vector3[2];\r\n\r\n        this._farLinesPoints[0] = TmpVectors.Vector3[6];\r\n        this._farLinesPoints[1] = TmpVectors.Vector3[7];\r\n        this._farLinesPoints[2] = TmpVectors.Vector3[8];\r\n        this._farLinesPoints[3] = TmpVectors.Vector3[9];\r\n        this._farLinesPoints[4] = TmpVectors.Vector3[6];\r\n\r\n        this._trLinesPoints[0] = TmpVectors.Vector3[2];\r\n        this._trLinesPoints[1] = TmpVectors.Vector3[6];\r\n\r\n        this._brLinesPoints[0] = TmpVectors.Vector3[3];\r\n        this._brLinesPoints[1] = TmpVectors.Vector3[7];\r\n\r\n        this._tlLinesPoints[0] = TmpVectors.Vector3[4];\r\n        this._tlLinesPoints[1] = TmpVectors.Vector3[8];\r\n\r\n        this._blLinesPoints[0] = TmpVectors.Vector3[5];\r\n        this._blLinesPoints[1] = TmpVectors.Vector3[9];\r\n    }\r\n\r\n    protected _getInvertViewMatrix(): Matrix {\r\n        Matrix.LookAtLHToRef(this._light.position, this._light.position.add(this._light.direction), Vector3.UpReadOnly, this._inverseViewMatrix);\r\n        this._inverseViewMatrix.invertToRef(this._inverseViewMatrix);\r\n        return this._inverseViewMatrix;\r\n    }\r\n}\r\n","/**\r\n * Extracts the characters between two markers (for eg, between \"(\" and \")\"). The function handles nested markers as well as markers inside strings (delimited by \", ' or `) and comments\r\n * @param markerOpen opening marker\r\n * @param markerClose closing marker\r\n * @param block code block to parse\r\n * @param startIndex starting index in block where the extraction must start. The character at block[startIndex] should be the markerOpen character!\r\n * @returns index of the last character for the extraction (or -1 if the string is invalid - no matching closing marker found). The string to extract (without the markers) is the string between startIndex + 1 and the returned value (exclusive)\r\n */\r\nexport function ExtractBetweenMarkers(markerOpen: string, markerClose: string, block: string, startIndex: number): number {\r\n    let currPos = startIndex,\r\n        openMarkers = 0,\r\n        waitForChar = \"\";\r\n\r\n    while (currPos < block.length) {\r\n        const currChar = block.charAt(currPos);\r\n\r\n        if (!waitForChar) {\r\n            switch (currChar) {\r\n                case markerOpen:\r\n                    openMarkers++;\r\n                    break;\r\n                case markerClose:\r\n                    openMarkers--;\r\n                    break;\r\n                case '\"':\r\n                case \"'\":\r\n                case \"`\":\r\n                    waitForChar = currChar;\r\n                    break;\r\n                case \"/\":\r\n                    if (currPos + 1 < block.length) {\r\n                        const nextChar = block.charAt(currPos + 1);\r\n                        if (nextChar === \"/\") {\r\n                            waitForChar = \"\\n\";\r\n                        } else if (nextChar === \"*\") {\r\n                            waitForChar = \"*/\";\r\n                        }\r\n                    }\r\n                    break;\r\n            }\r\n        } else {\r\n            if (currChar === waitForChar) {\r\n                if (waitForChar === '\"' || waitForChar === \"'\") {\r\n                    block.charAt(currPos - 1) !== \"\\\\\" && (waitForChar = \"\");\r\n                } else {\r\n                    waitForChar = \"\";\r\n                }\r\n            } else if (waitForChar === \"*/\" && currChar === \"*\" && currPos + 1 < block.length) {\r\n                block.charAt(currPos + 1) === \"/\" && (waitForChar = \"\");\r\n                if (waitForChar === \"\") {\r\n                    currPos++;\r\n                }\r\n            }\r\n        }\r\n\r\n        currPos++;\r\n        if (openMarkers === 0) {\r\n            break;\r\n        }\r\n    }\r\n\r\n    return openMarkers === 0 ? currPos - 1 : -1;\r\n}\r\n\r\n/**\r\n * Parses a string and skip whitespaces\r\n * @param s string to parse\r\n * @param index index where to start parsing\r\n * @returns the index after all whitespaces have been skipped\r\n */\r\nexport function SkipWhitespaces(s: string, index: number): number {\r\n    while (index < s.length) {\r\n        const c = s[index];\r\n        if (c !== \" \" && c !== \"\\n\" && c !== \"\\r\" && c !== \"\\t\" && c !== \"\\u000a\" && c !== \"\\u00a0\") {\r\n            break;\r\n        }\r\n        index++;\r\n    }\r\n\r\n    return index;\r\n}\r\n\r\n/**\r\n * Checks if a character is an identifier character (meaning, if it is 0-9, A-Z, a-z or _)\r\n * @param c character to check\r\n * @returns true if the character is an identifier character\r\n */\r\nexport function IsIdentifierChar(c: string): boolean {\r\n    const v = c.charCodeAt(0);\r\n    return (\r\n        (v >= 48 && v <= 57) || // 0-9\r\n        (v >= 65 && v <= 90) || // A-Z\r\n        (v >= 97 && v <= 122) || // a-z\r\n        v == 95\r\n    ); // _\r\n}\r\n\r\n/**\r\n * Removes the comments of a code block\r\n * @param block code block to parse\r\n * @returns block with the comments removed\r\n */\r\nexport function RemoveComments(block: string): string {\r\n    let currPos = 0,\r\n        waitForChar = \"\",\r\n        inComments = false;\r\n    const s = [];\r\n\r\n    while (currPos < block.length) {\r\n        const currChar = block.charAt(currPos);\r\n\r\n        if (!waitForChar) {\r\n            switch (currChar) {\r\n                case '\"':\r\n                case \"'\":\r\n                case \"`\":\r\n                    waitForChar = currChar;\r\n                    break;\r\n                case \"/\":\r\n                    if (currPos + 1 < block.length) {\r\n                        const nextChar = block.charAt(currPos + 1);\r\n                        if (nextChar === \"/\") {\r\n                            waitForChar = \"\\n\";\r\n                            inComments = true;\r\n                        } else if (nextChar === \"*\") {\r\n                            waitForChar = \"*/\";\r\n                            inComments = true;\r\n                        }\r\n                    }\r\n                    break;\r\n            }\r\n            if (!inComments) {\r\n                s.push(currChar);\r\n            }\r\n        } else {\r\n            if (currChar === waitForChar) {\r\n                if (waitForChar === '\"' || waitForChar === \"'\") {\r\n                    block.charAt(currPos - 1) !== \"\\\\\" && (waitForChar = \"\");\r\n                    s.push(currChar);\r\n                } else {\r\n                    waitForChar = \"\";\r\n                    inComments = false;\r\n                }\r\n            } else if (waitForChar === \"*/\" && currChar === \"*\" && currPos + 1 < block.length) {\r\n                block.charAt(currPos + 1) === \"/\" && (waitForChar = \"\");\r\n                if (waitForChar === \"\") {\r\n                    inComments = false;\r\n                    currPos++;\r\n                }\r\n            } else {\r\n                if (!inComments) {\r\n                    s.push(currChar);\r\n                }\r\n            }\r\n        }\r\n\r\n        currPos++;\r\n    }\r\n\r\n    return s.join(\"\");\r\n}\r\n\r\n/**\r\n * Finds the first occurrence of a character in a string going backward\r\n * @param s the string to parse\r\n * @param index starting index in the string\r\n * @param c the character to find\r\n * @param c2 an optional second character to find\r\n * @returns the index of the character if found, else -1\r\n */\r\nexport function FindBackward(s: string, index: number, c: string, c2?: string): number {\r\n    while (index >= 0 && s.charAt(index) !== c && (!c2 || s.charAt(index) !== c2)) {\r\n        index--;\r\n    }\r\n\r\n    return index;\r\n}\r\n\r\n/**\r\n * Escapes a string so that it is usable as a regular expression\r\n * @param s string to escape\r\n * @returns escaped string\r\n */\r\nexport function EscapeRegExp(s: string): string {\r\n    return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\n/**\r\n * Injects code at the beginning and/or end of a function.\r\n * The function is identified by \"mainFuncDecl\". The starting code is injected just after the first \"\\{\" found after the mainFuncDecl.\r\n * The ending code is injected just before the last \"\\}\" of the whole block of code (so, it is assumed that the function is the last of the block of code).\r\n * @param code code to inject into\r\n * @param mainFuncDecl Function declaration to find in the code (for eg: \"void main\")\r\n * @param startingCode The code to inject at the beginning of the function\r\n * @param endingCode The code to inject at the end of the function\r\n * @returns The code with the injected code\r\n */\r\nexport function InjectStartingAndEndingCode(code: string, mainFuncDecl: string, startingCode?: string, endingCode?: string): string {\r\n    let idx = code.indexOf(mainFuncDecl);\r\n    if (idx < 0) {\r\n        return code;\r\n    }\r\n    if (startingCode) {\r\n        // eslint-disable-next-line no-empty\r\n        while (idx++ < code.length && code.charAt(idx) != \"{\") {}\r\n        if (idx < code.length) {\r\n            const part1 = code.substring(0, idx + 1);\r\n            const part2 = code.substring(idx + 1);\r\n            code = part1 + startingCode + part2;\r\n        }\r\n    }\r\n\r\n    if (endingCode) {\r\n        const lastClosingCurly = code.lastIndexOf(\"}\");\r\n        code = code.substring(0, lastClosingCurly);\r\n        code += endingCode + \"\\n}\";\r\n    }\r\n\r\n    return code;\r\n}\r\n","import { Logger } from \"core/Misc/logger\";\r\nimport { EscapeRegExp, ExtractBetweenMarkers, FindBackward, IsIdentifierChar, RemoveComments, SkipWhitespaces } from \"../../Misc/codeStringParsingTools\";\r\n\r\ninterface IInlineFunctionDescr {\r\n    name: string;\r\n    type: string;\r\n    parameters: string[];\r\n    body: string;\r\n    callIndex: number;\r\n}\r\n\r\n/**\r\n * Class used to inline functions in shader code\r\n */\r\nexport class ShaderCodeInliner {\r\n    private static readonly _RegexpFindFunctionNameAndType = /((\\s+?)(\\w+)\\s+(\\w+)\\s*?)$/;\r\n\r\n    private _sourceCode: string;\r\n    private _functionDescr: IInlineFunctionDescr[];\r\n    private _numMaxIterations: number;\r\n\r\n    /** Gets or sets the token used to mark the functions to inline */\r\n    public inlineToken: string;\r\n\r\n    /** Gets or sets the debug mode */\r\n    public debug: boolean = false;\r\n\r\n    /** Gets the code after the inlining process */\r\n    public get code(): string {\r\n        return this._sourceCode;\r\n    }\r\n\r\n    /**\r\n     * Initializes the inliner\r\n     * @param sourceCode shader code source to inline\r\n     * @param numMaxIterations maximum number of iterations (used to detect recursive calls)\r\n     */\r\n    constructor(sourceCode: string, numMaxIterations = 20) {\r\n        this._sourceCode = sourceCode;\r\n        this._numMaxIterations = numMaxIterations;\r\n        this._functionDescr = [];\r\n        this.inlineToken = \"#define inline\";\r\n    }\r\n\r\n    /**\r\n     * Start the processing of the shader code\r\n     */\r\n    public processCode() {\r\n        if (this.debug) {\r\n            Logger.Log(`Start inlining process (code size=${this._sourceCode.length})...`);\r\n        }\r\n        this._collectFunctions();\r\n        this._processInlining(this._numMaxIterations);\r\n        if (this.debug) {\r\n            Logger.Log(\"End of inlining process.\");\r\n        }\r\n    }\r\n\r\n    private _collectFunctions() {\r\n        let startIndex = 0;\r\n\r\n        while (startIndex < this._sourceCode.length) {\r\n            // locate the function to inline and extract its name\r\n            const inlineTokenIndex = this._sourceCode.indexOf(this.inlineToken, startIndex);\r\n            if (inlineTokenIndex < 0) {\r\n                break;\r\n            }\r\n\r\n            const funcParamsStartIndex = this._sourceCode.indexOf(\"(\", inlineTokenIndex + this.inlineToken.length);\r\n            if (funcParamsStartIndex < 0) {\r\n                if (this.debug) {\r\n                    Logger.Warn(`Could not find the opening parenthesis after the token. startIndex=${startIndex}`);\r\n                }\r\n                startIndex = inlineTokenIndex + this.inlineToken.length;\r\n                continue;\r\n            }\r\n\r\n            const funcNameMatch = ShaderCodeInliner._RegexpFindFunctionNameAndType.exec(\r\n                this._sourceCode.substring(inlineTokenIndex + this.inlineToken.length, funcParamsStartIndex)\r\n            );\r\n            if (!funcNameMatch) {\r\n                if (this.debug) {\r\n                    Logger.Warn(\r\n                        `Could not extract the name/type of the function from: ${this._sourceCode.substring(inlineTokenIndex + this.inlineToken.length, funcParamsStartIndex)}`\r\n                    );\r\n                }\r\n                startIndex = inlineTokenIndex + this.inlineToken.length;\r\n                continue;\r\n            }\r\n            const [funcType, funcName] = [funcNameMatch[3], funcNameMatch[4]];\r\n\r\n            // extract the parameters of the function as a whole string (without the leading / trailing parenthesis)\r\n            const funcParamsEndIndex = ExtractBetweenMarkers(\"(\", \")\", this._sourceCode, funcParamsStartIndex);\r\n            if (funcParamsEndIndex < 0) {\r\n                if (this.debug) {\r\n                    Logger.Warn(`Could not extract the parameters the function '${funcName}' (type=${funcType}). funcParamsStartIndex=${funcParamsStartIndex}`);\r\n                }\r\n                startIndex = inlineTokenIndex + this.inlineToken.length;\r\n                continue;\r\n            }\r\n            const funcParams = this._sourceCode.substring(funcParamsStartIndex + 1, funcParamsEndIndex);\r\n\r\n            // extract the body of the function (with the curly brackets)\r\n            const funcBodyStartIndex = SkipWhitespaces(this._sourceCode, funcParamsEndIndex + 1);\r\n            if (funcBodyStartIndex === this._sourceCode.length) {\r\n                if (this.debug) {\r\n                    Logger.Warn(`Could not extract the body of the function '${funcName}' (type=${funcType}). funcParamsEndIndex=${funcParamsEndIndex}`);\r\n                }\r\n                startIndex = inlineTokenIndex + this.inlineToken.length;\r\n                continue;\r\n            }\r\n\r\n            const funcBodyEndIndex = ExtractBetweenMarkers(\"{\", \"}\", this._sourceCode, funcBodyStartIndex);\r\n            if (funcBodyEndIndex < 0) {\r\n                if (this.debug) {\r\n                    Logger.Warn(`Could not extract the body of the function '${funcName}' (type=${funcType}). funcBodyStartIndex=${funcBodyStartIndex}`);\r\n                }\r\n                startIndex = inlineTokenIndex + this.inlineToken.length;\r\n                continue;\r\n            }\r\n            const funcBody = this._sourceCode.substring(funcBodyStartIndex, funcBodyEndIndex + 1);\r\n\r\n            // process the parameters: extract each names\r\n            const params = RemoveComments(funcParams).split(\",\");\r\n            const paramNames = [];\r\n\r\n            for (let p = 0; p < params.length; ++p) {\r\n                const param = params[p].trim();\r\n                const idx = param.lastIndexOf(\" \");\r\n\r\n                if (idx >= 0) {\r\n                    paramNames.push(param.substring(idx + 1));\r\n                }\r\n            }\r\n\r\n            if (funcType !== \"void\") {\r\n                // for functions that return a value, we will replace \"return\" by \"tempvarname = \", tempvarname being a unique generated name\r\n                paramNames.push(\"return\");\r\n            }\r\n\r\n            // collect the function\r\n            this._functionDescr.push({\r\n                name: funcName,\r\n                type: funcType,\r\n                parameters: paramNames,\r\n                body: funcBody,\r\n                callIndex: 0,\r\n            });\r\n\r\n            startIndex = funcBodyEndIndex + 1;\r\n\r\n            // remove the function from the source code\r\n            const partBefore = inlineTokenIndex > 0 ? this._sourceCode.substring(0, inlineTokenIndex) : \"\";\r\n            const partAfter = funcBodyEndIndex + 1 < this._sourceCode.length - 1 ? this._sourceCode.substring(funcBodyEndIndex + 1) : \"\";\r\n\r\n            this._sourceCode = partBefore + partAfter;\r\n\r\n            startIndex -= funcBodyEndIndex + 1 - inlineTokenIndex;\r\n        }\r\n\r\n        if (this.debug) {\r\n            Logger.Log(`Collect functions: ${this._functionDescr.length} functions found. functionDescr=${this._functionDescr}`);\r\n        }\r\n    }\r\n\r\n    private _processInlining(numMaxIterations: number = 20): boolean {\r\n        while (numMaxIterations-- >= 0) {\r\n            if (!this._replaceFunctionCallsByCode()) {\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (this.debug) {\r\n            Logger.Log(`numMaxIterations is ${numMaxIterations} after inlining process`);\r\n        }\r\n\r\n        return numMaxIterations >= 0;\r\n    }\r\n\r\n    private _replaceFunctionCallsByCode(): boolean {\r\n        let doAgain = false;\r\n\r\n        for (const func of this._functionDescr) {\r\n            const { name, type, parameters, body } = func;\r\n\r\n            let startIndex = 0;\r\n\r\n            while (startIndex < this._sourceCode.length) {\r\n                // Look for the function name in the source code\r\n                const functionCallIndex = this._sourceCode.indexOf(name, startIndex);\r\n\r\n                if (functionCallIndex < 0) {\r\n                    break;\r\n                }\r\n\r\n                // Make sure \"name\" is not part of a bigger string\r\n                if (functionCallIndex === 0 || IsIdentifierChar(this._sourceCode.charAt(functionCallIndex - 1))) {\r\n                    startIndex = functionCallIndex + name.length;\r\n                    continue;\r\n                }\r\n\r\n                // Find the opening parenthesis\r\n                const callParamsStartIndex = SkipWhitespaces(this._sourceCode, functionCallIndex + name.length);\r\n                if (callParamsStartIndex === this._sourceCode.length || this._sourceCode.charAt(callParamsStartIndex) !== \"(\") {\r\n                    startIndex = functionCallIndex + name.length;\r\n                    continue;\r\n                }\r\n\r\n                // extract the parameters of the function call as a whole string (without the leading / trailing parenthesis)\r\n                const callParamsEndIndex = ExtractBetweenMarkers(\"(\", \")\", this._sourceCode, callParamsStartIndex);\r\n                if (callParamsEndIndex < 0) {\r\n                    if (this.debug) {\r\n                        Logger.Warn(`Could not extract the parameters of the function call. Function '${name}' (type=${type}). callParamsStartIndex=${callParamsStartIndex}`);\r\n                    }\r\n                    startIndex = functionCallIndex + name.length;\r\n                    continue;\r\n                }\r\n                const callParams = this._sourceCode.substring(callParamsStartIndex + 1, callParamsEndIndex);\r\n\r\n                // process the parameter call: extract each names\r\n\r\n                // this function split the parameter list used in the function call at ',' boundaries by taking care of potential parenthesis like in:\r\n                //      myfunc(a, vec2(1., 0.), 4.)\r\n                const splitParameterCall = (s: string) => {\r\n                    const parameters = [];\r\n                    let curIdx = 0,\r\n                        startParamIdx = 0;\r\n                    while (curIdx < s.length) {\r\n                        if (s.charAt(curIdx) === \"(\") {\r\n                            const idx2 = ExtractBetweenMarkers(\"(\", \")\", s, curIdx);\r\n                            if (idx2 < 0) {\r\n                                return null;\r\n                            }\r\n                            curIdx = idx2;\r\n                        } else if (s.charAt(curIdx) === \",\") {\r\n                            parameters.push(s.substring(startParamIdx, curIdx));\r\n                            startParamIdx = curIdx + 1;\r\n                        }\r\n                        curIdx++;\r\n                    }\r\n                    if (startParamIdx < curIdx) {\r\n                        parameters.push(s.substring(startParamIdx, curIdx));\r\n                    }\r\n                    return parameters;\r\n                };\r\n\r\n                const params = splitParameterCall(RemoveComments(callParams));\r\n\r\n                if (params === null) {\r\n                    if (this.debug) {\r\n                        Logger.Warn(\r\n                            `Invalid function call: can't extract the parameters of the function call. Function '${name}' (type=${type}). callParamsStartIndex=${callParamsStartIndex}, callParams=` +\r\n                                callParams\r\n                        );\r\n                    }\r\n                    startIndex = functionCallIndex + name.length;\r\n                    continue;\r\n                }\r\n\r\n                const paramNames = [];\r\n\r\n                for (let p = 0; p < params.length; ++p) {\r\n                    const param = params[p].trim();\r\n                    paramNames.push(param);\r\n                }\r\n\r\n                const retParamName = type !== \"void\" ? name + \"_\" + func.callIndex++ : null;\r\n\r\n                if (retParamName) {\r\n                    paramNames.push(retParamName + \" =\");\r\n                }\r\n\r\n                if (paramNames.length !== parameters.length) {\r\n                    if (this.debug) {\r\n                        Logger.Warn(\r\n                            `Invalid function call: not the same number of parameters for the call than the number expected by the function. Function '${name}' (type=${type}). function parameters=${parameters}, call parameters=${paramNames}`\r\n                        );\r\n                    }\r\n                    startIndex = functionCallIndex + name.length;\r\n                    continue;\r\n                }\r\n\r\n                startIndex = callParamsEndIndex + 1;\r\n\r\n                // replace the function call by the body function\r\n                const funcBody = this._replaceNames(body, parameters, paramNames);\r\n\r\n                let partBefore = functionCallIndex > 0 ? this._sourceCode.substring(0, functionCallIndex) : \"\";\r\n                const partAfter = callParamsEndIndex + 1 < this._sourceCode.length - 1 ? this._sourceCode.substring(callParamsEndIndex + 1) : \"\";\r\n\r\n                if (retParamName) {\r\n                    // case where the function returns a value. We generate:\r\n                    // FUNCTYPE retParamName;\r\n                    // {function body}\r\n                    // and replace the function call by retParamName\r\n                    const injectDeclarationIndex = FindBackward(this._sourceCode, functionCallIndex - 1, \"\\n\", \"{\");\r\n\r\n                    partBefore = this._sourceCode.substring(0, injectDeclarationIndex + 1);\r\n                    const partBetween = this._sourceCode.substring(injectDeclarationIndex + 1, functionCallIndex);\r\n\r\n                    this._sourceCode = partBefore + type + \" \" + retParamName + \";\\n\" + funcBody + \"\\n\" + partBetween + retParamName + partAfter;\r\n\r\n                    if (this.debug) {\r\n                        Logger.Log(\r\n                            `Replace function call by code. Function '${name}' (type=${type}). injectDeclarationIndex=${injectDeclarationIndex}, call parameters=${paramNames}`\r\n                        );\r\n                    }\r\n                } else {\r\n                    // simple case where the return value of the function is \"void\"\r\n                    this._sourceCode = partBefore + funcBody + partAfter;\r\n\r\n                    startIndex += funcBody.length - (callParamsEndIndex + 1 - functionCallIndex);\r\n\r\n                    if (this.debug) {\r\n                        Logger.Log(`Replace function call by code. Function '${name}' (type=${type}). functionCallIndex=${functionCallIndex}, call parameters=${paramNames}`);\r\n                    }\r\n                }\r\n\r\n                doAgain = true;\r\n            }\r\n        }\r\n\r\n        return doAgain;\r\n    }\r\n\r\n    private _replaceNames(code: string, sources: string[], destinations: string[]): string {\r\n        for (let i = 0; i < sources.length; ++i) {\r\n            const source = new RegExp(EscapeRegExp(sources[i]), \"g\"),\r\n                sourceLen = sources[i].length,\r\n                destination = destinations[i];\r\n\r\n            code = code.replace(source, (match, ...args) => {\r\n                const offset: number = args[0];\r\n                // Make sure \"source\" is not part of a bigger identifier (for eg, if source=view and we matched it with viewDirection)\r\n                if (IsIdentifierChar(code.charAt(offset - 1)) || IsIdentifierChar(code.charAt(offset + sourceLen))) {\r\n                    return sources[i];\r\n                }\r\n                return destination;\r\n            });\r\n        }\r\n\r\n        return code;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { type Nullable } from \"core/types\";\r\nimport { type IShaderProcessor } from \"../Processors/iShaderProcessor\";\r\nimport { type NativeShaderProcessingContext } from \"./nativeShaderProcessingContext\";\r\nimport { type _IShaderProcessingContext } from \"../Processors/shaderProcessingOptions\";\r\nimport { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\nimport { InjectStartingAndEndingCode } from \"../../Misc/codeStringParsingTools\";\r\n\r\nconst VaryingRegex = /(flat\\s)?\\s*varying\\s*.*/;\r\n\r\n/** @internal */\r\nexport class NativeShaderProcessor implements IShaderProcessor {\r\n    public shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    protected _nativeProcessingContext: Nullable<NativeShaderProcessingContext>;\r\n\r\n    public initializeShaders(processingContext: Nullable<_IShaderProcessingContext>): void {\r\n        this._nativeProcessingContext = processingContext as Nullable<NativeShaderProcessingContext>;\r\n        if (this._nativeProcessingContext) {\r\n            this._nativeProcessingContext.remappedAttributeNames = {};\r\n            this._nativeProcessingContext.injectInVertexMain = \"\";\r\n        }\r\n    }\r\n\r\n    public attributeProcessor(attribute: string) {\r\n        if (!this._nativeProcessingContext) {\r\n            return attribute.replace(\"attribute\", \"in\");\r\n        }\r\n\r\n        const attribRegex = /\\s*(?:attribute|in)\\s+(\\S+)\\s+(\\S+)\\s*;/gm;\r\n        const match = attribRegex.exec(attribute);\r\n        if (match !== null) {\r\n            const attributeType = match[1];\r\n            const name = match[2];\r\n\r\n            const numComponents = this._nativeProcessingContext.vertexBufferKindToNumberOfComponents[name];\r\n            if (numComponents !== undefined) {\r\n                // Special case for an int/ivecX vertex buffer that is used as a float/vecX attribute in the shader.\r\n                const newType = numComponents < 0 ? (numComponents === -1 ? \"int\" : \"ivec\" + -numComponents) : numComponents === 1 ? \"uint\" : \"uvec\" + numComponents;\r\n                const newName = `_int_${name}_`;\r\n\r\n                attribute = attribute.replace(match[0], `in ${newType} ${newName}; ${attributeType} ${name};`);\r\n\r\n                this._nativeProcessingContext.injectInVertexMain += `${name} = ${attributeType}(${newName});\\n`;\r\n                this._nativeProcessingContext.remappedAttributeNames[name] = newName;\r\n            } else {\r\n                attribute = attribute.replace(match[0], `in ${attributeType} ${name};`);\r\n            }\r\n        }\r\n        return attribute;\r\n    }\r\n\r\n    public varyingCheck(varying: string, _isFragment: boolean) {\r\n        return VaryingRegex.test(varying);\r\n    }\r\n\r\n    public varyingProcessor(varying: string, isFragment: boolean) {\r\n        return varying.replace(\"varying\", isFragment ? \"in\" : \"out\");\r\n    }\r\n\r\n    public postProcessor(code: string, defines: string[], isFragment: boolean) {\r\n        const hasDrawBuffersExtension = code.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;\r\n\r\n        // Remove extensions\r\n        const regex = /#extension.+(GL_OVR_multiview2|GL_OES_standard_derivatives|GL_EXT_shader_texture_lod|GL_EXT_frag_depth|GL_EXT_draw_buffers).+(enable|require)/g;\r\n        code = code.replace(regex, \"\");\r\n\r\n        // Replace instructions\r\n        code = code.replace(/texture2D\\s*\\(/g, \"texture(\");\r\n        if (isFragment) {\r\n            const hasOutput = code.search(/layout *\\(location *= *0\\) *out/g) !== -1;\r\n\r\n            code = code.replace(/texture2DLodEXT\\s*\\(/g, \"textureLod(\");\r\n            code = code.replace(/textureCubeLodEXT\\s*\\(/g, \"textureLod(\");\r\n            code = code.replace(/textureCube\\s*\\(/g, \"texture(\");\r\n            code = code.replace(/gl_FragDepthEXT/g, \"gl_FragDepth\");\r\n            code = code.replace(/gl_FragColor/g, \"glFragColor\");\r\n            code = code.replace(/gl_FragData/g, \"glFragData\");\r\n            code = code.replace(/void\\s+?main\\s*\\(/g, (hasDrawBuffersExtension || hasOutput ? \"\" : \"layout(location = 0) out vec4 glFragColor;\\n\") + \"void main(\");\r\n        } else {\r\n            if (defines.indexOf(\"#define VERTEXOUTPUT_INVARIANT\") >= 0) {\r\n                code = \"invariant gl_Position;\\n\" + code;\r\n            }\r\n            if (this._nativeProcessingContext?.injectInVertexMain) {\r\n                code = InjectStartingAndEndingCode(code, \"void main\", this._nativeProcessingContext.injectInVertexMain);\r\n            }\r\n            const hasMultiviewExtension = defines.indexOf(\"#define MULTIVIEW\") !== -1;\r\n            if (hasMultiviewExtension) {\r\n                return \"#extension GL_OVR_multiview2 : require\\nlayout (num_views = 2) in;\\n\" + code;\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n}\r\n","import { type DeepImmutable, type FloatArray } from \"../../types\";\r\nimport { type INative, type INativeDataStream } from \"./nativeInterfaces\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const _native: INative;\r\n\r\n/** @internal */\r\nexport type NativeData = Uint32Array<ArrayBuffer>;\r\n\r\n/** @internal */\r\nexport class NativeDataStream {\r\n    private readonly _uint32s: Uint32Array<ArrayBuffer>;\r\n    private readonly _int32s: Int32Array<ArrayBuffer>;\r\n    private readonly _float32s: Float32Array<ArrayBuffer>;\r\n    private readonly _length: number;\r\n    private _position: number;\r\n    private readonly _nativeDataStream: INativeDataStream;\r\n\r\n    // Must be multiple of 4!\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private static readonly DEFAULT_BUFFER_SIZE = 65536;\r\n\r\n    constructor() {\r\n        const buffer = new ArrayBuffer(NativeDataStream.DEFAULT_BUFFER_SIZE);\r\n        this._uint32s = new Uint32Array(buffer);\r\n        this._int32s = new Int32Array(buffer);\r\n        this._float32s = new Float32Array(buffer);\r\n\r\n        this._length = NativeDataStream.DEFAULT_BUFFER_SIZE / 4;\r\n        this._position = 0;\r\n\r\n        this._nativeDataStream = new _native.NativeDataStream(() => {\r\n            this._flush();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Writes a uint32 to the stream\r\n     * @param value the value to write\r\n     */\r\n    public writeUint32(value: number): void {\r\n        this._flushIfNecessary(1);\r\n        this._uint32s[this._position++] = value;\r\n    }\r\n\r\n    /**\r\n     * Writes an int32 to the stream\r\n     * @param value the value to write\r\n     */\r\n    public writeInt32(value: number): void {\r\n        this._flushIfNecessary(1);\r\n        this._int32s[this._position++] = value;\r\n    }\r\n\r\n    /**\r\n     * Writes a float32 to the stream\r\n     * @param value the value to write\r\n     */\r\n    public writeFloat32(value: number): void {\r\n        this._flushIfNecessary(1);\r\n        this._float32s[this._position++] = value;\r\n    }\r\n\r\n    /**\r\n     * Writes a uint32 array to the stream\r\n     * @param values the values to write\r\n     */\r\n    public writeUint32Array(values: Uint32Array): void {\r\n        this._flushIfNecessary(1 + values.length);\r\n        this._uint32s[this._position++] = values.length;\r\n        this._uint32s.set(values, this._position);\r\n        this._position += values.length;\r\n    }\r\n\r\n    /**\r\n     * Writes an int32 array to the stream\r\n     * @param values the values to write\r\n     */\r\n    public writeInt32Array(values: Int32Array): void {\r\n        this._flushIfNecessary(1 + values.length);\r\n        this._uint32s[this._position++] = values.length;\r\n        this._int32s.set(values, this._position);\r\n        this._position += values.length;\r\n    }\r\n\r\n    /**\r\n     * Writes a float32 array to the stream\r\n     * @param values the values to write\r\n     */\r\n    public writeFloat32Array(values: DeepImmutable<FloatArray>): void {\r\n        this._flushIfNecessary(1 + values.length);\r\n        this._uint32s[this._position++] = values.length;\r\n        this._float32s.set(values, this._position);\r\n        this._position += values.length;\r\n    }\r\n\r\n    /**\r\n     * Writes native data to the stream\r\n     * @param handle the handle to the native data\r\n     */\r\n    public writeNativeData(handle: NativeData) {\r\n        this._flushIfNecessary(handle.length);\r\n        this._uint32s.set(handle, this._position);\r\n        this._position += handle.length;\r\n    }\r\n\r\n    /**\r\n     * Writes a boolean to the stream\r\n     * @param value the value to write\r\n     */\r\n    public writeBoolean(value: boolean) {\r\n        this.writeUint32(value ? 1 : 0);\r\n    }\r\n\r\n    private _flushIfNecessary(required: number): void {\r\n        if (this._position + required > this._length) {\r\n            this._flush();\r\n        }\r\n    }\r\n\r\n    private _flush(): void {\r\n        this._nativeDataStream.writeBuffer(this._uint32s.buffer, this._position);\r\n        this._position = 0;\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type Effect } from \"../../Materials/effect\";\r\nimport { type IMatrixLike, type IVector2Like, type IVector3Like, type IVector4Like, type IColor3Like, type IColor4Like, type IQuaternionLike } from \"../../Maths/math.like\";\r\nimport { type IPipelineContext } from \"../IPipelineContext\";\r\nimport { type NativeProgram } from \"./nativeInterfaces\";\r\nimport { type AbstractEngine } from \"../abstractEngine\";\r\nimport { type NativeShaderProcessingContext } from \"./nativeShaderProcessingContext\";\r\nimport { type ThinNativeEngine } from \"../thinNativeEngine\";\r\n\r\nexport class NativePipelineContext implements IPipelineContext {\r\n    public isCompiled: boolean = false;\r\n    public compilationError?: Error;\r\n\r\n    public readonly isAsync: boolean;\r\n\r\n    public program: NativeProgram;\r\n\r\n    public vertexBufferKindToType: { [kind: string]: number } = {};\r\n    public shaderProcessingContext: Nullable<NativeShaderProcessingContext>;\r\n\r\n    public get isReady(): boolean {\r\n        if (this.compilationError) {\r\n            const message = this.compilationError.message;\r\n            throw new Error(\"SHADER ERROR\" + (typeof message === \"string\" ? \"\\n\" + message : \"\"));\r\n        }\r\n        return this.isCompiled;\r\n    }\r\n\r\n    public onCompiled?: () => void;\r\n\r\n    public _getVertexShaderCode(): string | null {\r\n        return null;\r\n    }\r\n\r\n    public _getFragmentShaderCode(): string | null {\r\n        return null;\r\n    }\r\n\r\n    private _engine: ThinNativeEngine;\r\n    private _valueCache: { [key: string]: any } = {};\r\n    private _uniforms: { [key: string]: Nullable<WebGLUniformLocation> };\r\n\r\n    constructor(engine: ThinNativeEngine, isAsync: boolean, shaderProcessingContext: Nullable<NativeShaderProcessingContext>) {\r\n        this._engine = engine;\r\n        this.isAsync = isAsync;\r\n        this.shaderProcessingContext = shaderProcessingContext;\r\n    }\r\n\r\n    public _fillEffectInformation(\r\n        effect: Effect,\r\n        uniformBuffersNames: { [key: string]: number },\r\n        uniformsNames: string[],\r\n        uniforms: { [key: string]: Nullable<WebGLUniformLocation> },\r\n        samplerList: string[],\r\n        samplers: { [key: string]: number },\r\n        attributesNames: string[],\r\n        attributes: number[]\r\n    ) {\r\n        const engine = this._engine;\r\n        if (engine.supportsUniformBuffers) {\r\n            for (const name in uniformBuffersNames) {\r\n                effect.bindUniformBlock(name, uniformBuffersNames[name]);\r\n            }\r\n        }\r\n\r\n        const effectAvailableUniforms = this._engine.getUniforms(this, uniformsNames);\r\n        effectAvailableUniforms.forEach((uniform, index) => {\r\n            uniforms[uniformsNames[index]] = uniform;\r\n        });\r\n        this._uniforms = uniforms;\r\n\r\n        let index: number;\r\n        for (index = 0; index < samplerList.length; index++) {\r\n            const sampler = effect.getUniform(samplerList[index]);\r\n            if (sampler == null) {\r\n                samplerList.splice(index, 1);\r\n                index--;\r\n            }\r\n        }\r\n\r\n        samplerList.forEach((name, index) => {\r\n            samplers[name] = index;\r\n        });\r\n\r\n        attributes.push(...engine.getAttributes(this, attributesNames));\r\n    }\r\n\r\n    public setEngine(engine: AbstractEngine): void {\r\n        this._engine = engine as ThinNativeEngine;\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources.\r\n     **/\r\n    public dispose() {\r\n        this._uniforms = {};\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheMatrix(uniformName: string, matrix: IMatrixLike): boolean {\r\n        const cache = this._valueCache[uniformName];\r\n        const flag = matrix.updateFlag;\r\n        if (cache !== undefined && cache === flag) {\r\n            return false;\r\n        }\r\n\r\n        this._valueCache[uniformName] = flag;\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheFloat2(uniformName: string, x: number, y: number): boolean {\r\n        let cache = this._valueCache[uniformName];\r\n        if (!cache) {\r\n            cache = [x, y];\r\n            this._valueCache[uniformName] = cache;\r\n            return true;\r\n        }\r\n\r\n        let changed = false;\r\n        if (cache[0] !== x) {\r\n            cache[0] = x;\r\n            changed = true;\r\n        }\r\n        if (cache[1] !== y) {\r\n            cache[1] = y;\r\n            changed = true;\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheFloat3(uniformName: string, x: number, y: number, z: number): boolean {\r\n        let cache = this._valueCache[uniformName];\r\n        if (!cache) {\r\n            cache = [x, y, z];\r\n            this._valueCache[uniformName] = cache;\r\n            return true;\r\n        }\r\n\r\n        let changed = false;\r\n        if (cache[0] !== x) {\r\n            cache[0] = x;\r\n            changed = true;\r\n        }\r\n        if (cache[1] !== y) {\r\n            cache[1] = y;\r\n            changed = true;\r\n        }\r\n        if (cache[2] !== z) {\r\n            cache[2] = z;\r\n            changed = true;\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _cacheFloat4(uniformName: string, x: number, y: number, z: number, w: number): boolean {\r\n        let cache = this._valueCache[uniformName];\r\n        if (!cache) {\r\n            cache = [x, y, z, w];\r\n            this._valueCache[uniformName] = cache;\r\n            return true;\r\n        }\r\n\r\n        let changed = false;\r\n        if (cache[0] !== x) {\r\n            cache[0] = x;\r\n            changed = true;\r\n        }\r\n        if (cache[1] !== y) {\r\n            cache[1] = y;\r\n            changed = true;\r\n        }\r\n        if (cache[2] !== z) {\r\n            cache[2] = z;\r\n            changed = true;\r\n        }\r\n        if (cache[3] !== w) {\r\n            cache[3] = w;\r\n            changed = true;\r\n        }\r\n\r\n        return changed;\r\n    }\r\n\r\n    /**\r\n     * Sets an integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     */\r\n    public setInt(uniformName: string, value: number): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === value) {\r\n            return;\r\n        }\r\n\r\n        if (this._engine.setInt(this._uniforms[uniformName]!, value)) {\r\n            this._valueCache[uniformName] = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a int2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int2.\r\n     * @param y Second int in int2.\r\n     */\r\n    public setInt2(uniformName: string, x: number, y: number): void {\r\n        if (this._cacheFloat2(uniformName, x, y)) {\r\n            if (!this._engine.setInt2(this._uniforms[uniformName], x, y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a int3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int3.\r\n     * @param y Second int in int3.\r\n     * @param z Third int in int3.\r\n     */\r\n    public setInt3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (this._cacheFloat3(uniformName, x, y, z)) {\r\n            if (!this._engine.setInt3(this._uniforms[uniformName], x, y, z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a int4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int4.\r\n     * @param y Second int in int4.\r\n     * @param z Third int in int4.\r\n     * @param w Fourth int in int4.\r\n     */\r\n    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (this._cacheFloat4(uniformName, x, y, z, w)) {\r\n            if (!this._engine.setInt4(this._uniforms[uniformName], x, y, z, w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setIntArray(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray2(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setIntArray2(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray3(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setIntArray3(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray4(uniformName: string, array: Int32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setIntArray4(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     */\r\n    public setUInt(uniformName: string, value: number): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === value) {\r\n            return;\r\n        }\r\n\r\n        if (this._engine.setUInt(this._uniforms[uniformName], value)) {\r\n            this._valueCache[uniformName] = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a unsigned int2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint2.\r\n     * @param y Second unsigned int in uint2.\r\n     */\r\n    public setUInt2(uniformName: string, x: number, y: number): void {\r\n        if (this._cacheFloat2(uniformName, x, y)) {\r\n            if (!this._engine.setUInt2(this._uniforms[uniformName], x, y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a unsigned int3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint3.\r\n     * @param y Second unsigned int in uint3.\r\n     * @param z Third unsigned int in uint3.\r\n     */\r\n    public setUInt3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (this._cacheFloat3(uniformName, x, y, z)) {\r\n            if (!this._engine.setUInt3(this._uniforms[uniformName], x, y, z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a unsigned int4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint4.\r\n     * @param y Second unsigned int in uint4.\r\n     * @param z Third unsigned int in uint4.\r\n     * @param w Fourth unsigned int in uint4.\r\n     */\r\n    public setUInt4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (this._cacheFloat4(uniformName, x, y, z, w)) {\r\n            if (!this._engine.setUInt4(this._uniforms[uniformName], x, y, z, w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setUIntArray(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray2(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setUIntArray2(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray3(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setUIntArray3(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray4(uniformName: string, array: Uint32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setUIntArray4(this._uniforms[uniformName], array);\r\n    }\r\n\r\n    /**\r\n     * Sets an float array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setFloatArray(uniformName: string, array: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setFloatArray(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an float array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setFloatArray2(uniformName: string, array: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setFloatArray2(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an float array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setFloatArray3(uniformName: string, array: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setFloatArray3(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an float array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setFloatArray4(uniformName: string, array: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setFloatArray4(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setArray(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray2(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setArray2(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray3(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setArray3(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray4(uniformName: string, array: number[]): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setArray4(this._uniforms[uniformName]!, array);\r\n    }\r\n\r\n    /**\r\n     * Sets matrices on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrices matrices to be set.\r\n     */\r\n    public setMatrices(uniformName: string, matrices: Float32Array): void {\r\n        if (!matrices) {\r\n            return;\r\n        }\r\n\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setMatrices(this._uniforms[uniformName]!, matrices);\r\n    }\r\n\r\n    /**\r\n     * Sets matrix on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix(uniformName: string, matrix: IMatrixLike): void {\r\n        if (this._cacheMatrix(uniformName, matrix)) {\r\n            if (!this._engine.setMatrices(this._uniforms[uniformName]!, matrix.asArray())) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a 3x3 matrix on a uniform variable. (Specified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix3x3(uniformName: string, matrix: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setMatrix3x3(this._uniforms[uniformName]!, matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a 2x2 matrix on a uniform variable. (Specified as [1,2,3,4] will result in [1,2][3,4] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix2x2(uniformName: string, matrix: Float32Array): void {\r\n        this._valueCache[uniformName] = null;\r\n        this._engine.setMatrix2x2(this._uniforms[uniformName]!, matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a float on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value value to be set.\r\n     */\r\n    public setFloat(uniformName: string, value: number): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === value) {\r\n            return;\r\n        }\r\n\r\n        if (this._engine.setFloat(this._uniforms[uniformName]!, value)) {\r\n            this._valueCache[uniformName] = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a boolean on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param bool value to be set.\r\n     */\r\n    public setBool(uniformName: string, bool: boolean): void {\r\n        const cache = this._valueCache[uniformName];\r\n        if (cache !== undefined && cache === bool) {\r\n            return;\r\n        }\r\n\r\n        if (this._engine.setInt(this._uniforms[uniformName]!, bool ? 1 : 0)) {\r\n            this._valueCache[uniformName] = bool ? 1 : 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector2 vector2 to be set.\r\n     */\r\n    public setVector2(uniformName: string, vector2: IVector2Like): void {\r\n        if (this._cacheFloat2(uniformName, vector2.x, vector2.y)) {\r\n            if (!this._engine.setFloat2(this._uniforms[uniformName]!, vector2.x, vector2.y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a float2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float2.\r\n     * @param y Second float in float2.\r\n     */\r\n    public setFloat2(uniformName: string, x: number, y: number): void {\r\n        if (this._cacheFloat2(uniformName, x, y)) {\r\n            if (!this._engine.setFloat2(this._uniforms[uniformName]!, x, y)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector3 Value to be set.\r\n     */\r\n    public setVector3(uniformName: string, vector3: IVector3Like): void {\r\n        if (this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z)) {\r\n            if (!this._engine.setFloat3(this._uniforms[uniformName]!, vector3.x, vector3.y, vector3.z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a float3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float3.\r\n     * @param y Second float in float3.\r\n     * @param z Third float in float3.\r\n     */\r\n    public setFloat3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (this._cacheFloat3(uniformName, x, y, z)) {\r\n            if (!this._engine.setFloat3(this._uniforms[uniformName]!, x, y, z)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector4 Value to be set.\r\n     */\r\n    public setVector4(uniformName: string, vector4: IVector4Like): void {\r\n        if (this._cacheFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w)) {\r\n            if (!this._engine.setFloat4(this._uniforms[uniformName]!, vector4.x, vector4.y, vector4.z, vector4.w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Quaternion on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param quaternion Value to be set.\r\n     */\r\n    public setQuaternion(uniformName: string, quaternion: IQuaternionLike): void {\r\n        if (this._cacheFloat4(uniformName, quaternion.x, quaternion.y, quaternion.z, quaternion.w)) {\r\n            if (!this._engine.setFloat4(this._uniforms[uniformName]!, quaternion.x, quaternion.y, quaternion.z, quaternion.w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a float4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float4.\r\n     * @param y Second float in float4.\r\n     * @param z Third float in float4.\r\n     * @param w Fourth float in float4.\r\n     */\r\n    public setFloat4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (this._cacheFloat4(uniformName, x, y, z, w)) {\r\n            if (!this._engine.setFloat4(this._uniforms[uniformName]!, x, y, z, w)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Color3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     */\r\n    public setColor3(uniformName: string, color3: IColor3Like): void {\r\n        if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {\r\n            if (!this._engine.setFloat3(this._uniforms[uniformName]!, color3.r, color3.g, color3.b)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     * @param alpha Alpha value to be set.\r\n     */\r\n    public setColor4(uniformName: string, color3: IColor3Like, alpha: number): void {\r\n        if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {\r\n            if (!this._engine.setFloat4(this._uniforms[uniformName]!, color3.r, color3.g, color3.b, alpha)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable\r\n     * @param uniformName defines the name of the variable\r\n     * @param color4 defines the value to be set\r\n     */\r\n    public setDirectColor4(uniformName: string, color4: IColor4Like): void {\r\n        if (this._cacheFloat4(uniformName, color4.r, color4.g, color4.b, color4.a)) {\r\n            if (!this._engine.setFloat4(this._uniforms[uniformName]!, color4.r, color4.g, color4.b, color4.a)) {\r\n                this._valueCache[uniformName] = null;\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { type RenderTargetCreationOptions, type TextureSize } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Constants } from \"./constants\";\r\nimport { type AbstractEngine } from \"./abstractEngine\";\r\nimport { type IMultiRenderTargetOptions } from \"../Materials/Textures/multiRenderTarget\";\r\nimport { HasStencilAspect } from \"core/Materials/Textures/textureHelper.functions\";\r\n\r\n/**\r\n * An interface enforcing the renderTarget accessor to used by render target textures.\r\n */\r\nexport interface IRenderTargetTexture {\r\n    /**\r\n     * Entry point to access the wrapper on a texture.\r\n     */\r\n    renderTarget: Nullable<RenderTargetWrapper>;\r\n}\r\n\r\n/**\r\n * Wrapper around a render target (either single or multi textures)\r\n */\r\nexport class RenderTargetWrapper {\r\n    protected _engine: AbstractEngine;\r\n    private _size: TextureSize;\r\n    private _isCube: boolean;\r\n    private _isMulti: boolean;\r\n    private _textures: Nullable<InternalTexture[]> = null;\r\n    private _faceIndices: Nullable<number[]> = null;\r\n    private _layerIndices: Nullable<number[]> = null;\r\n    private _depthStencilTextureLabel?: string;\r\n    /** @internal */\r\n    public _samples = 1;\r\n\r\n    /** @internal */\r\n    public _attachments: Nullable<number[]> = null;\r\n    /** @internal */\r\n    public _generateStencilBuffer: boolean = false;\r\n    /** @internal */\r\n    public _generateDepthBuffer: boolean = false;\r\n\r\n    /** @internal */\r\n    public _depthStencilTexture: Nullable<InternalTexture>;\r\n    /** @internal */\r\n    public _depthStencilTextureWithStencil: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets the label of the render target wrapper (optional, for debugging purpose)\r\n     */\r\n    public label?: string;\r\n\r\n    /**\r\n     * Gets the depth/stencil texture\r\n     */\r\n    public get depthStencilTexture() {\r\n        return this._depthStencilTexture;\r\n    }\r\n\r\n    /**\r\n     * Sets the depth/stencil texture\r\n     * @param texture The depth/stencil texture to set\r\n     * @param disposeExisting True to dispose the existing depth/stencil texture (if any) before replacing it (default: true)\r\n     */\r\n    public setDepthStencilTexture(texture: Nullable<InternalTexture>, disposeExisting = true) {\r\n        if (disposeExisting && this._depthStencilTexture) {\r\n            this._depthStencilTexture.dispose();\r\n        }\r\n\r\n        this._depthStencilTexture = texture;\r\n\r\n        this._generateDepthBuffer = this._generateStencilBuffer = this._depthStencilTextureWithStencil = false;\r\n\r\n        if (texture) {\r\n            this._generateDepthBuffer = true;\r\n            this._generateStencilBuffer = this._depthStencilTextureWithStencil = HasStencilAspect(texture.format);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates if the depth/stencil texture has a stencil aspect\r\n     */\r\n    public get depthStencilTextureWithStencil() {\r\n        return this._depthStencilTextureWithStencil;\r\n    }\r\n\r\n    /**\r\n     * Defines if the render target wrapper is for a cube texture or if false a 2d texture\r\n     */\r\n    public get isCube(): boolean {\r\n        return this._isCube;\r\n    }\r\n\r\n    /**\r\n     * Defines if the render target wrapper is for a single or multi target render wrapper\r\n     */\r\n    public get isMulti(): boolean {\r\n        return this._isMulti;\r\n    }\r\n\r\n    /**\r\n     * Defines if the render target wrapper is for a single or an array of textures\r\n     */\r\n    public get is2DArray(): boolean {\r\n        return this.layers > 0;\r\n    }\r\n\r\n    /**\r\n     * Defines if the render target wrapper is for a 3D texture\r\n     */\r\n    public get is3D(): boolean {\r\n        return this.depth > 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the size of the render target wrapper (used for cubes, as width=height in this case)\r\n     */\r\n    public get size(): number {\r\n        return this.width;\r\n    }\r\n\r\n    /**\r\n     * Gets the width of the render target wrapper\r\n     */\r\n    public get width(): number {\r\n        return (<{ width: number; height: number }>this._size).width ?? <number>this._size;\r\n    }\r\n\r\n    /**\r\n     * Gets the height of the render target wrapper\r\n     */\r\n    public get height(): number {\r\n        return (<{ width: number; height: number }>this._size).height ?? <number>this._size;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of layers of the render target wrapper (only used if is2DArray is true and wrapper is not a multi render target)\r\n     */\r\n    public get layers(): number {\r\n        return (<{ width: number; height: number; depth?: number; layers?: number }>this._size).layers || 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the depth of the render target wrapper (only used if is3D is true and wrapper is not a multi render target)\r\n     */\r\n    public get depth(): number {\r\n        return (<{ width: number; height: number; depth?: number; layers?: number }>this._size).depth || 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the render texture. If this is a multi render target, gets the first texture\r\n     */\r\n    public get texture(): Nullable<InternalTexture> {\r\n        return this._textures?.[0] ?? null;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of render textures. If we are not in a multi render target, the list will be null (use the texture getter instead)\r\n     */\r\n    public get textures(): Nullable<InternalTexture[]> {\r\n        return this._textures;\r\n    }\r\n\r\n    /**\r\n     * Gets the face indices that correspond to the list of render textures. If we are not in a multi render target, the list will be null\r\n     */\r\n    public get faceIndices(): Nullable<number[]> {\r\n        return this._faceIndices;\r\n    }\r\n\r\n    /**\r\n     * Gets the layer indices that correspond to the list of render textures. If we are not in a multi render target, the list will be null\r\n     */\r\n    public get layerIndices(): Nullable<number[]> {\r\n        return this._layerIndices;\r\n    }\r\n\r\n    /**\r\n     * Sets this property to true to disable the automatic MSAA resolve that happens when the render target wrapper is unbound (default is false)\r\n     */\r\n    public disableAutomaticMSAAResolve = false;\r\n\r\n    /**\r\n     * Indicates if MSAA color texture(s) should be resolved when a resolve occur (either automatically by the engine or manually by the user) (default is true)\r\n     * Note that you can trigger a MSAA resolve at any time by calling resolveMSAATextures()\r\n     */\r\n    public resolveMSAAColors = true;\r\n\r\n    /**\r\n     * Indicates if MSAA depth texture should be resolved when a resolve occur (either automatically by the engine or manually by the user) (default is false)\r\n     */\r\n    public resolveMSAADepth = false;\r\n\r\n    /**\r\n     * Indicates if MSAA stencil texture should be resolved when a resolve occur (either automatically by the engine or manually by the user) (default is false)\r\n     */\r\n    public resolveMSAAStencil = false;\r\n\r\n    /**\r\n     * Indicates if the depth texture is in read-only mode (may allow some optimizations in WebGPU)\r\n     */\r\n    public depthReadOnly = false;\r\n\r\n    /**\r\n     * Indicates if the stencil texture is in read-only mode (may allow some optimizations in WebGPU)\r\n     */\r\n    public stencilReadOnly = false;\r\n\r\n    /**\r\n     * Gets the base array layer of a texture in the textures array\r\n     * This is an number that is calculated based on the layer and face indices set for this texture at that index\r\n     * @param index The index of the texture in the textures array to get the base array layer for\r\n     * @returns the base array layer of the texture at the given index\r\n     */\r\n    public getBaseArrayLayer(index: number): number {\r\n        if (!this._textures) {\r\n            return -1;\r\n        }\r\n\r\n        const texture = this._textures[index];\r\n        const layerIndex = this._layerIndices?.[index] ?? 0;\r\n        const faceIndex = this._faceIndices?.[index] ?? 0;\r\n\r\n        return texture.isCube ? layerIndex * 6 + faceIndex : texture.is3D ? 0 : layerIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the sample count of the render target\r\n     */\r\n    public get samples(): number {\r\n        return this._samples;\r\n    }\r\n\r\n    /**\r\n     * Sets the sample count of the render target\r\n     * @param value sample count\r\n     * @param initializeBuffers If set to true, the engine will make an initializing call to drawBuffers (only used when isMulti=true).\r\n     * @param force true to force calling the update sample count engine function even if the current sample count is equal to value\r\n     * @returns the sample count that has been set\r\n     */\r\n    public setSamples(value: number, initializeBuffers = true, force = false): number {\r\n        if (this.samples === value && !force) {\r\n            return value;\r\n        }\r\n\r\n        const result = this._isMulti\r\n            ? this._engine.updateMultipleRenderTargetTextureSampleCount(this, value, initializeBuffers)\r\n            : this._engine.updateRenderTargetTextureSampleCount(this, value);\r\n        this._samples = value;\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Resolves the MSAA textures into their non-MSAA version.\r\n     * Note that if samples equals 1 (no MSAA), no resolve is performed.\r\n     */\r\n    public resolveMSAATextures(): void {\r\n        if (this.isMulti) {\r\n            this._engine.resolveMultiFramebuffer(this);\r\n        } else {\r\n            this._engine.resolveFramebuffer(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Generates mipmaps for each texture of the render target\r\n     */\r\n    public generateMipMaps(): void {\r\n        if (this._engine._currentRenderTarget === this) {\r\n            if (this.isMulti) {\r\n                this._engine.unBindMultiColorAttachmentFramebuffer(this, true);\r\n            } else {\r\n                this._engine.unBindFramebuffer(this, true);\r\n            }\r\n        }\r\n        if (this.isMulti) {\r\n            this._engine.generateMipMapsMultiFramebuffer(this);\r\n        } else {\r\n            this._engine.generateMipMapsFramebuffer(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Initializes the render target wrapper\r\n     * @param isMulti true if the wrapper is a multi render target\r\n     * @param isCube true if the wrapper should render to a cube texture\r\n     * @param size size of the render target (width/height/layers)\r\n     * @param engine engine used to create the render target\r\n     * @param label defines the label to use for the wrapper (for debugging purpose only)\r\n     */\r\n    constructor(isMulti: boolean, isCube: boolean, size: TextureSize, engine: AbstractEngine, label?: string) {\r\n        this._isMulti = isMulti;\r\n        this._isCube = isCube;\r\n        this._size = size;\r\n        this._engine = engine;\r\n        this._depthStencilTexture = null;\r\n        this.label = label;\r\n    }\r\n\r\n    /**\r\n     * Sets the render target texture(s)\r\n     * @param textures texture(s) to set\r\n     */\r\n    public setTextures(textures: Nullable<InternalTexture> | Nullable<InternalTexture[]>): void {\r\n        if (Array.isArray(textures)) {\r\n            this._textures = textures;\r\n        } else if (textures) {\r\n            this._textures = [textures];\r\n        } else {\r\n            this._textures = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set a texture in the textures array\r\n     * @param texture The texture to set\r\n     * @param index The index in the textures array to set\r\n     * @param disposePrevious If this function should dispose the previous texture\r\n     */\r\n    public setTexture(texture: InternalTexture, index: number = 0, disposePrevious: boolean = true): void {\r\n        if (!this._textures) {\r\n            this._textures = [];\r\n        }\r\n        if (this._textures[index] === texture) {\r\n            return;\r\n        }\r\n\r\n        if (this._textures[index] && disposePrevious) {\r\n            this._textures[index].dispose();\r\n        }\r\n\r\n        this._textures[index] = texture;\r\n    }\r\n\r\n    /**\r\n     * Sets the layer and face indices of every render target texture bound to each color attachment\r\n     * @param layers The layers of each texture to be set\r\n     * @param faces The faces of each texture to be set\r\n     */\r\n    public setLayerAndFaceIndices(layers: number[], faces: number[]) {\r\n        this._layerIndices = layers;\r\n        this._faceIndices = faces;\r\n    }\r\n\r\n    /**\r\n     * Sets the layer and face indices of a texture in the textures array that should be bound to each color attachment\r\n     * @param index The index of the texture in the textures array to modify\r\n     * @param layer The layer of the texture to be set\r\n     * @param face The face of the texture to be set\r\n     */\r\n    public setLayerAndFaceIndex(index: number = 0, layer?: number, face?: number): void {\r\n        if (!this._layerIndices) {\r\n            this._layerIndices = [];\r\n        }\r\n        if (!this._faceIndices) {\r\n            this._faceIndices = [];\r\n        }\r\n\r\n        if (layer !== undefined && layer >= 0) {\r\n            this._layerIndices[index] = layer;\r\n        }\r\n        if (face !== undefined && face >= 0) {\r\n            this._faceIndices[index] = face;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates the depth/stencil texture\r\n     * @param comparisonFunction Comparison function to use for the texture\r\n     * @param bilinearFiltering true if bilinear filtering should be used when sampling the texture\r\n     * @param generateStencil Not used anymore. \"format\" will be used to determine if stencil should be created\r\n     * @param samples sample count to use when creating the texture (default: 1)\r\n     * @param format format of the depth texture (default: Constants.TEXTUREFORMAT_DEPTH32_FLOAT)\r\n     * @param label defines the label to use for the texture (for debugging purpose only)\r\n     * @returns the depth/stencil created texture\r\n     */\r\n    public createDepthStencilTexture(\r\n        comparisonFunction: number = 0,\r\n        bilinearFiltering: boolean = true,\r\n        generateStencil: boolean = false,\r\n        samples: number = 1,\r\n        format: number = Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n        label?: string\r\n    ): InternalTexture {\r\n        this._depthStencilTexture?.dispose();\r\n\r\n        this._depthStencilTextureWithStencil = generateStencil;\r\n        this._depthStencilTextureLabel = label;\r\n        this._depthStencilTexture = this._engine.createDepthStencilTexture(\r\n            this._size,\r\n            {\r\n                bilinearFiltering,\r\n                comparisonFunction,\r\n                generateStencil,\r\n                isCube: this._isCube,\r\n                samples,\r\n                depthTextureFormat: format,\r\n                label,\r\n            },\r\n            this\r\n        );\r\n\r\n        return this._depthStencilTexture;\r\n    }\r\n\r\n    /**\r\n     * @deprecated Use shareDepth instead\r\n     * @param renderTarget Destination renderTarget\r\n     */\r\n    public _shareDepth(renderTarget: RenderTargetWrapper): void {\r\n        this.shareDepth(renderTarget);\r\n    }\r\n\r\n    /**\r\n     * Shares the depth buffer of this render target with another render target.\r\n     * @param renderTarget Destination renderTarget\r\n     */\r\n    public shareDepth(renderTarget: RenderTargetWrapper): void {\r\n        if (this._depthStencilTexture) {\r\n            if (renderTarget._depthStencilTexture) {\r\n                renderTarget._depthStencilTexture.dispose();\r\n            }\r\n\r\n            renderTarget._depthStencilTexture = this._depthStencilTexture;\r\n            renderTarget._depthStencilTextureWithStencil = this._depthStencilTextureWithStencil;\r\n            this._depthStencilTexture.incrementReferences();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _swapAndDie(target: InternalTexture): void {\r\n        if (this.texture) {\r\n            this.texture._swapAndDie(target);\r\n        }\r\n        this._textures = null;\r\n        this.dispose(true);\r\n    }\r\n\r\n    protected _cloneRenderTargetWrapper(): Nullable<RenderTargetWrapper> {\r\n        let rtw: Nullable<RenderTargetWrapper> = null;\r\n\r\n        if (this._isMulti) {\r\n            const textureArray = this.textures;\r\n            if (textureArray && textureArray.length > 0) {\r\n                let generateDepthTexture = false;\r\n                let textureCount = textureArray.length;\r\n                let depthTextureFormat = -1;\r\n\r\n                const lastTextureSource = textureArray[textureArray.length - 1]._source;\r\n                if (lastTextureSource === InternalTextureSource.Depth || lastTextureSource === InternalTextureSource.DepthStencil) {\r\n                    generateDepthTexture = true;\r\n                    depthTextureFormat = textureArray[textureArray.length - 1].format;\r\n                    textureCount--;\r\n                }\r\n\r\n                const samplingModes: number[] = [];\r\n                const types: number[] = [];\r\n                const formats: number[] = [];\r\n                const targetTypes: number[] = [];\r\n                const faceIndex: number[] = [];\r\n                const layerIndex: number[] = [];\r\n                const layerCounts: number[] = [];\r\n                const internalTexture2Index: { [id: number]: number } = {};\r\n\r\n                for (let i = 0; i < textureCount; ++i) {\r\n                    const texture = textureArray[i];\r\n\r\n                    samplingModes.push(texture.samplingMode);\r\n                    types.push(texture.type);\r\n                    formats.push(texture.format);\r\n\r\n                    const index = internalTexture2Index[texture.uniqueId];\r\n                    if (index !== undefined) {\r\n                        targetTypes.push(-1);\r\n                        layerCounts.push(0);\r\n                    } else {\r\n                        internalTexture2Index[texture.uniqueId] = i;\r\n                        if (texture.is2DArray) {\r\n                            targetTypes.push(Constants.TEXTURE_2D_ARRAY);\r\n                            layerCounts.push(texture.depth);\r\n                        } else if (texture.isCube) {\r\n                            targetTypes.push(Constants.TEXTURE_CUBE_MAP);\r\n                            layerCounts.push(0);\r\n                        } /*else if (texture.isCubeArray) {\r\n                            targetTypes.push(Constants.TEXTURE_CUBE_MAP_ARRAY);\r\n                            layerCounts.push(texture.depth);\r\n                        }*/ else if (texture.is3D) {\r\n                            targetTypes.push(Constants.TEXTURE_3D);\r\n                            layerCounts.push(texture.depth);\r\n                        } else {\r\n                            targetTypes.push(Constants.TEXTURE_2D);\r\n                            layerCounts.push(0);\r\n                        }\r\n                    }\r\n\r\n                    if (this._faceIndices) {\r\n                        faceIndex.push(this._faceIndices[i] ?? 0);\r\n                    }\r\n                    if (this._layerIndices) {\r\n                        layerIndex.push(this._layerIndices[i] ?? 0);\r\n                    }\r\n                }\r\n\r\n                const optionsMRT: IMultiRenderTargetOptions = {\r\n                    samplingModes,\r\n                    generateMipMaps: textureArray[0].generateMipMaps,\r\n                    generateDepthBuffer: this._generateDepthBuffer,\r\n                    generateStencilBuffer: this._generateStencilBuffer,\r\n                    generateDepthTexture,\r\n                    depthTextureFormat,\r\n                    types,\r\n                    formats,\r\n                    textureCount,\r\n                    targetTypes,\r\n                    faceIndex,\r\n                    layerIndex,\r\n                    layerCounts,\r\n                    label: this.label,\r\n                };\r\n                const size = {\r\n                    width: this.width,\r\n                    height: this.height,\r\n                    depth: this.depth,\r\n                };\r\n\r\n                rtw = this._engine.createMultipleRenderTarget(size, optionsMRT);\r\n\r\n                for (let i = 0; i < textureCount; ++i) {\r\n                    if (targetTypes[i] !== -1) {\r\n                        continue;\r\n                    }\r\n                    const index = internalTexture2Index[textureArray[i].uniqueId];\r\n                    rtw.setTexture(rtw.textures![index], i);\r\n                }\r\n            }\r\n        } else {\r\n            const options: RenderTargetCreationOptions = {};\r\n\r\n            options.generateDepthBuffer = this._generateDepthBuffer;\r\n            options.generateMipMaps = this.texture?.generateMipMaps ?? false;\r\n            options.generateStencilBuffer = this._generateStencilBuffer;\r\n            options.samplingMode = this.texture?.samplingMode;\r\n            options.type = this.texture?.type;\r\n            options.format = this.texture?.format;\r\n            options.noColorAttachment = !this._textures;\r\n            options.label = this.label;\r\n\r\n            if (this.isCube) {\r\n                rtw = this._engine.createRenderTargetCubeTexture(this.width, options);\r\n            } else {\r\n                const size = {\r\n                    width: this.width,\r\n                    height: this.height,\r\n                    layers: this.is2DArray || this.is3D ? this.texture?.depth : undefined,\r\n                };\r\n\r\n                rtw = this._engine.createRenderTargetTexture(size, options);\r\n            }\r\n            if (rtw.texture) {\r\n                rtw.texture.isReady = true;\r\n            }\r\n        }\r\n\r\n        return rtw;\r\n    }\r\n\r\n    protected _swapRenderTargetWrapper(target: RenderTargetWrapper): void {\r\n        if (this._textures && target._textures) {\r\n            for (let i = 0; i < this._textures.length; ++i) {\r\n                this._textures[i]._swapAndDie(target._textures[i], false);\r\n                target._textures[i].isReady = true;\r\n            }\r\n        }\r\n        if (this._depthStencilTexture && target._depthStencilTexture) {\r\n            this._depthStencilTexture._swapAndDie(target._depthStencilTexture);\r\n            target._depthStencilTexture.isReady = true;\r\n        }\r\n\r\n        this._textures = null;\r\n        this._depthStencilTexture = null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        const rtw = this._cloneRenderTargetWrapper();\r\n        if (!rtw) {\r\n            return;\r\n        }\r\n\r\n        if (this._depthStencilTexture) {\r\n            const samplingMode = this._depthStencilTexture.samplingMode;\r\n            const format = this._depthStencilTexture.format;\r\n            const bilinear =\r\n                samplingMode === Constants.TEXTURE_BILINEAR_SAMPLINGMODE ||\r\n                samplingMode === Constants.TEXTURE_TRILINEAR_SAMPLINGMODE ||\r\n                samplingMode === Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST;\r\n\r\n            rtw.createDepthStencilTexture(\r\n                this._depthStencilTexture._comparisonFunction,\r\n                bilinear,\r\n                this._depthStencilTextureWithStencil,\r\n                this._depthStencilTexture.samples,\r\n                format,\r\n                this._depthStencilTextureLabel\r\n            );\r\n        }\r\n\r\n        if (this.samples > 1) {\r\n            rtw.setSamples(this.samples);\r\n        }\r\n\r\n        rtw._swapRenderTargetWrapper(this);\r\n        rtw.dispose();\r\n    }\r\n\r\n    /**\r\n     * Releases the internal render textures\r\n     */\r\n    public releaseTextures(): void {\r\n        if (this._textures) {\r\n            for (let i = 0; i < this._textures.length; ++i) {\r\n                this._textures[i].dispose();\r\n            }\r\n        }\r\n        this._textures = null;\r\n    }\r\n\r\n    /**\r\n     * Disposes the whole render target wrapper\r\n     * @param disposeOnlyFramebuffers true if only the frame buffers should be released (used for the WebGL engine). If false, all the textures will also be released\r\n     */\r\n    public dispose(disposeOnlyFramebuffers = false): void {\r\n        if (!disposeOnlyFramebuffers) {\r\n            this._depthStencilTexture?.dispose();\r\n            this._depthStencilTexture = null;\r\n            this.releaseTextures();\r\n        }\r\n\r\n        this._engine._releaseRenderTargetWrapper(this);\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { type NativeFramebuffer } from \"./nativeInterfaces\";\r\nimport { type ThinNativeEngine } from \"../thinNativeEngine\";\r\n\r\nexport class NativeRenderTargetWrapper extends RenderTargetWrapper {\r\n    public override readonly _engine: ThinNativeEngine;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private __framebuffer: Nullable<NativeFramebuffer> = null;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private __framebufferDepthStencil: Nullable<NativeFramebuffer> = null;\r\n    // Per-face framebuffers for cube render targets (index = cube face 0..5).\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private __framebuffers: Nullable<NativeFramebuffer[]> = null;\r\n\r\n    public get _framebuffer(): Nullable<NativeFramebuffer> {\r\n        return this.__framebuffer;\r\n    }\r\n\r\n    public set _framebuffer(framebuffer: Nullable<NativeFramebuffer>) {\r\n        if (this.__framebuffer) {\r\n            this._engine._releaseFramebufferObjects(this.__framebuffer);\r\n        }\r\n        this.__framebuffer = framebuffer;\r\n    }\r\n\r\n    public get _framebuffers(): Nullable<NativeFramebuffer[]> {\r\n        return this.__framebuffers;\r\n    }\r\n\r\n    public set _framebuffers(framebuffers: Nullable<NativeFramebuffer[]>) {\r\n        if (this.__framebuffers) {\r\n            for (const framebuffer of this.__framebuffers) {\r\n                this._engine._releaseFramebufferObjects(framebuffer);\r\n            }\r\n        }\r\n        this.__framebuffers = framebuffers;\r\n        // Keep _framebuffer pointing at face 0 so single-target code paths still work.\r\n        this.__framebuffer = framebuffers ? framebuffers[0] : null;\r\n    }\r\n\r\n    public get _framebufferDepthStencil(): Nullable<NativeFramebuffer> {\r\n        return this.__framebufferDepthStencil;\r\n    }\r\n\r\n    public set _framebufferDepthStencil(framebufferDepthStencil: Nullable<NativeFramebuffer>) {\r\n        if (this.__framebufferDepthStencil) {\r\n            this._engine._releaseFramebufferObjects(this.__framebufferDepthStencil);\r\n        }\r\n        this.__framebufferDepthStencil = framebufferDepthStencil;\r\n    }\r\n\r\n    constructor(isMulti: boolean, isCube: boolean, size: TextureSize, engine: ThinNativeEngine) {\r\n        super(isMulti, isCube, size, engine);\r\n        this._engine = engine;\r\n    }\r\n\r\n    public override setTexture(texture: InternalTexture, index: number = 0, disposePrevious: boolean = true): void {\r\n        const previous = this.textures?.[index];\r\n        super.setTexture(texture, index, disposePrevious);\r\n\r\n        // bgfx binds a fixed attachment set when a framebuffer is created and cannot re-point an individual\r\n        // attachment the way GL's framebufferTexture2D can. When a multi render target attachment is swapped\r\n        // after creation (e.g. the OIT depth-peeling renderer replaces every attachment via\r\n        // MultiRenderTarget.setInternalTexture), recreate the whole framebuffer from the new attachment set.\r\n        if (this.isMulti && this.textures?.[index] !== previous) {\r\n            this._engine._createMultiRenderTargetFramebuffer(this);\r\n        }\r\n    }\r\n\r\n    public override dispose(disposeOnlyFramebuffers = false): void {\r\n        if (this.__framebuffers) {\r\n            // Releases all six per-face framebuffers (face 0 is aliased by __framebuffer, so\r\n            // clear that alias here without releasing it again).\r\n            this._framebuffers = null;\r\n        } else {\r\n            this._framebuffer = null;\r\n        }\r\n        this._framebufferDepthStencil = null;\r\n\r\n        super.dispose(disposeOnlyFramebuffers);\r\n    }\r\n}\r\n","import { type IHardwareTextureWrapper } from \"../../Materials/Textures/hardwareTextureWrapper\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type INativeEngine, type NativeTexture } from \"./nativeInterfaces\";\r\n\r\n/** @internal */\r\nexport class NativeHardwareTexture implements IHardwareTextureWrapper {\r\n    private readonly _engine: INativeEngine;\r\n    private _nativeTexture: Nullable<NativeTexture>;\r\n\r\n    public get underlyingResource(): Nullable<NativeTexture> {\r\n        return this._nativeTexture;\r\n    }\r\n\r\n    constructor(existingTexture: NativeTexture, engine: INativeEngine) {\r\n        this._engine = engine;\r\n        this.set(existingTexture);\r\n    }\r\n\r\n    public setUsage(): void {}\r\n\r\n    public set(hardwareTexture: NativeTexture) {\r\n        this._nativeTexture = hardwareTexture;\r\n    }\r\n\r\n    public reset() {\r\n        this._nativeTexture = null;\r\n    }\r\n\r\n    public release() {\r\n        if (this._nativeTexture) {\r\n            this._engine.deleteTexture(this._nativeTexture);\r\n        }\r\n\r\n        this.reset();\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { ErrorCodes, RuntimeError } from \"core/Misc/error\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Constants } from \"../constants\";\r\nimport { type INative } from \"./nativeInterfaces\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\n\r\ndeclare const _native: INative;\r\n\r\nexport function getNativeTextureFormat(format: number, type: number): number {\r\n    switch (format) {\r\n        // Depth (type is ignored)\r\n        case Constants.TEXTUREFORMAT_DEPTH16:\r\n            return _native.Engine.TEXTURE_FORMAT_D16;\r\n        case Constants.TEXTUREFORMAT_DEPTH24:\r\n            return _native.Engine.TEXTURE_FORMAT_D24;\r\n        case Constants.TEXTUREFORMAT_DEPTH24_STENCIL8:\r\n            return _native.Engine.TEXTURE_FORMAT_D24S8;\r\n        case Constants.TEXTUREFORMAT_DEPTH32_FLOAT:\r\n            return _native.Engine.TEXTURE_FORMAT_D32F;\r\n\r\n        // Compressed (type is ignored)\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n            return _native.Engine.TEXTURE_FORMAT_BC7;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:\r\n            return _native.Engine.TEXTURE_FORMAT_BC6H;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n            return _native.Engine.TEXTURE_FORMAT_BC3;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3:\r\n            return _native.Engine.TEXTURE_FORMAT_BC2;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n            return _native.Engine.TEXTURE_FORMAT_BC1;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n            return _native.Engine.TEXTURE_FORMAT_BC1;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC4x4;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC5x4;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC5x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC6x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC6x6;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC8x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC8x6;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC8x8;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC10x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC10x6;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC10x8;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC10x10;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC12x10;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12:\r\n            return _native.Engine.TEXTURE_FORMAT_ASTC12x12;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n            return _native.Engine.TEXTURE_FORMAT_ETC1;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n            return _native.Engine.TEXTURE_FORMAT_ETC2;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n            return _native.Engine.TEXTURE_FORMAT_ETC2A;\r\n\r\n        case Constants.TEXTUREFORMAT_RGB: {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGB8;\r\n                case Constants.TEXTURETYPE_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGB8S;\r\n                case Constants.TEXTURETYPE_INT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGB8I;\r\n                case Constants.TEXTURETYPE_UNSIGNED_INTEGER:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGB8U;\r\n            }\r\n            break;\r\n        }\r\n\r\n        case Constants.TEXTUREFORMAT_RGBA_INTEGER: {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_UNSIGNED_INTEGER:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA32U;\r\n            }\r\n            break;\r\n        }\r\n\r\n        case Constants.TEXTUREFORMAT_RGBA: {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA8;\r\n                case Constants.TEXTURETYPE_FLOAT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA32F;\r\n                case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA16F;\r\n                case Constants.TEXTURETYPE_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA8S;\r\n                case Constants.TEXTURETYPE_SHORT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA16I;\r\n                case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA16U;\r\n                case Constants.TEXTURETYPE_INT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA32I;\r\n                case Constants.TEXTURETYPE_UNSIGNED_INTEGER:\r\n                    return _native.Engine.TEXTURE_FORMAT_RGBA32U;\r\n            }\r\n            break;\r\n        }\r\n        case Constants.TEXTUREFORMAT_R: {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_R8;\r\n                case Constants.TEXTURETYPE_FLOAT:\r\n                    return _native.Engine.TEXTURE_FORMAT_R32F;\r\n                case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                    return _native.Engine.TEXTURE_FORMAT_R16F;\r\n                case Constants.TEXTURETYPE_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_R8S;\r\n                case Constants.TEXTURETYPE_SHORT:\r\n                    return _native.Engine.TEXTURE_FORMAT_R16S;\r\n                case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                    return _native.Engine.TEXTURE_FORMAT_R16U;\r\n                case Constants.TEXTURETYPE_INT:\r\n                    return _native.Engine.TEXTURE_FORMAT_R32I;\r\n                case Constants.TEXTURETYPE_UNSIGNED_INTEGER:\r\n                    return _native.Engine.TEXTURE_FORMAT_R32U;\r\n            }\r\n            break;\r\n        }\r\n        case Constants.TEXTUREFORMAT_RG: {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG8;\r\n                case Constants.TEXTURETYPE_FLOAT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG32F;\r\n                case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG16F;\r\n                case Constants.TEXTURETYPE_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG8S;\r\n                case Constants.TEXTURETYPE_SHORT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG16S;\r\n                case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG16U;\r\n                case Constants.TEXTURETYPE_INT:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG32I;\r\n                case Constants.TEXTURETYPE_UNSIGNED_INTEGER:\r\n                    return _native.Engine.TEXTURE_FORMAT_RG32U;\r\n            }\r\n            break;\r\n        }\r\n        case Constants.TEXTUREFORMAT_BGRA: {\r\n            switch (type) {\r\n                case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                    return _native.Engine.TEXTURE_FORMAT_BGRA8;\r\n            }\r\n            break;\r\n        }\r\n    }\r\n\r\n    throw new RuntimeError(`Unsupported texture format or type: format ${format}, type ${type}.`, ErrorCodes.UnsupportedTextureError);\r\n}\r\n\r\nexport function getNativeSamplingMode(samplingMode: number): number {\r\n    switch (samplingMode) {\r\n        case Constants.TEXTURE_NEAREST_NEAREST:\r\n            return _native.Engine.TEXTURE_NEAREST_NEAREST;\r\n        case Constants.TEXTURE_LINEAR_LINEAR:\r\n            return _native.Engine.TEXTURE_LINEAR_LINEAR;\r\n        case Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR:\r\n            return _native.Engine.TEXTURE_LINEAR_LINEAR_MIPLINEAR;\r\n        case Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST:\r\n            return _native.Engine.TEXTURE_NEAREST_NEAREST_MIPNEAREST;\r\n        case Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST:\r\n            return _native.Engine.TEXTURE_NEAREST_LINEAR_MIPNEAREST;\r\n        case Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR:\r\n            return _native.Engine.TEXTURE_NEAREST_LINEAR_MIPLINEAR;\r\n        case Constants.TEXTURE_NEAREST_LINEAR:\r\n            return _native.Engine.TEXTURE_NEAREST_LINEAR;\r\n        case Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR:\r\n            return _native.Engine.TEXTURE_NEAREST_NEAREST_MIPLINEAR;\r\n        case Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST:\r\n            return _native.Engine.TEXTURE_LINEAR_NEAREST_MIPNEAREST;\r\n        case Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR:\r\n            return _native.Engine.TEXTURE_LINEAR_NEAREST_MIPLINEAR;\r\n        case Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST:\r\n            return _native.Engine.TEXTURE_LINEAR_LINEAR_MIPNEAREST;\r\n        case Constants.TEXTURE_LINEAR_NEAREST:\r\n            return _native.Engine.TEXTURE_LINEAR_NEAREST;\r\n        default:\r\n            throw new Error(`Unsupported sampling mode: ${samplingMode}.`);\r\n    }\r\n}\r\n\r\nexport function getNativeAddressMode(wrapMode: number): number {\r\n    switch (wrapMode) {\r\n        case Constants.TEXTURE_WRAP_ADDRESSMODE:\r\n            return _native.Engine.ADDRESS_MODE_WRAP;\r\n        case Constants.TEXTURE_CLAMP_ADDRESSMODE:\r\n            return _native.Engine.ADDRESS_MODE_CLAMP;\r\n        case Constants.TEXTURE_MIRROR_ADDRESSMODE:\r\n            return _native.Engine.ADDRESS_MODE_MIRROR;\r\n        default:\r\n            throw new Error(\"Unexpected wrap mode: \" + wrapMode + \".\");\r\n    }\r\n}\r\n\r\nexport function getNativeStencilFunc(func: number): number {\r\n    switch (func) {\r\n        case Constants.LESS:\r\n            return _native.Engine.STENCIL_TEST_LESS;\r\n        case Constants.LEQUAL:\r\n            return _native.Engine.STENCIL_TEST_LEQUAL;\r\n        case Constants.EQUAL:\r\n            return _native.Engine.STENCIL_TEST_EQUAL;\r\n        case Constants.GEQUAL:\r\n            return _native.Engine.STENCIL_TEST_GEQUAL;\r\n        case Constants.GREATER:\r\n            return _native.Engine.STENCIL_TEST_GREATER;\r\n        case Constants.NOTEQUAL:\r\n            return _native.Engine.STENCIL_TEST_NOTEQUAL;\r\n        case Constants.NEVER:\r\n            return _native.Engine.STENCIL_TEST_NEVER;\r\n        case Constants.ALWAYS:\r\n            return _native.Engine.STENCIL_TEST_ALWAYS;\r\n        default:\r\n            throw new Error(`Unsupported stencil func mode: ${func}.`);\r\n    }\r\n}\r\n\r\nexport function getNativeStencilOpFail(opFail: number): number {\r\n    switch (opFail) {\r\n        case Constants.KEEP:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_KEEP;\r\n        case Constants.ZERO:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_ZERO;\r\n        case Constants.REPLACE:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_REPLACE;\r\n        case Constants.INCR:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_INCR;\r\n        case Constants.DECR:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_DECR;\r\n        case Constants.INVERT:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_INVERT;\r\n        case Constants.INCR_WRAP:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_INCRSAT;\r\n        case Constants.DECR_WRAP:\r\n            return _native.Engine.STENCIL_OP_FAIL_S_DECRSAT;\r\n        default:\r\n            throw new Error(`Unsupported stencil OpFail mode: ${opFail}.`);\r\n    }\r\n}\r\n\r\nexport function getNativeStencilDepthFail(depthFail: number): number {\r\n    switch (depthFail) {\r\n        case Constants.KEEP:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_KEEP;\r\n        case Constants.ZERO:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_ZERO;\r\n        case Constants.REPLACE:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_REPLACE;\r\n        case Constants.INCR:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_INCR;\r\n        case Constants.DECR:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_DECR;\r\n        case Constants.INVERT:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_INVERT;\r\n        case Constants.INCR_WRAP:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_INCRSAT;\r\n        case Constants.DECR_WRAP:\r\n            return _native.Engine.STENCIL_OP_FAIL_Z_DECRSAT;\r\n        default:\r\n            throw new Error(`Unsupported stencil depthFail mode: ${depthFail}.`);\r\n    }\r\n}\r\n\r\nexport function getNativeStencilDepthPass(opPass: number): number {\r\n    switch (opPass) {\r\n        case Constants.KEEP:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_KEEP;\r\n        case Constants.ZERO:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_ZERO;\r\n        case Constants.REPLACE:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_REPLACE;\r\n        case Constants.INCR:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_INCR;\r\n        case Constants.DECR:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_DECR;\r\n        case Constants.INVERT:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_INVERT;\r\n        case Constants.INCR_WRAP:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_INCRSAT;\r\n        case Constants.DECR_WRAP:\r\n            return _native.Engine.STENCIL_OP_PASS_Z_DECRSAT;\r\n        default:\r\n            throw new Error(`Unsupported stencil opPass mode: ${opPass}.`);\r\n    }\r\n}\r\n\r\nconst _warnedUnsupportedAlphaModes = new Set<number>();\r\n\r\n// Some alpha modes were introduced alongside newer Babylon Native features. When running against an older\r\n// native binary the corresponding _native.Engine constant is undefined; warn once and use a supported fallback.\r\nfunction _getFallbackAlphaMode(mode: number, unsupportedName: string, fallback = _native.Engine.ALPHA_ONEONE, fallbackName = \"ALPHA_ONEONE\"): number {\r\n    if (!_warnedUnsupportedAlphaModes.has(mode)) {\r\n        _warnedUnsupportedAlphaModes.add(mode);\r\n        Logger.Warn(`Alpha mode ${unsupportedName} is not supported by this version of Babylon Native; falling back to ${fallbackName}.`);\r\n    }\r\n    return fallback;\r\n}\r\n\r\nexport function getNativeAlphaMode(mode: number): number {\r\n    switch (mode) {\r\n        // AbstractEngine initializes/resets _alphaMode to -1 as an \"unset\" sentinel (see\r\n        // abstractEngine.pure.ts). WebGL/WebGPU tolerate restoring that sentinel via setAlphaMode(-1)\r\n        // (e.g. OutlineRenderer._afterRenderingMesh saving/restoring getAlphaMode()); treat it as\r\n        // ALPHA_DISABLE here so the native path doesn't throw on the transient reset value.\r\n        case -1:\r\n        case Constants.ALPHA_DISABLE:\r\n            return _native.Engine.ALPHA_DISABLE;\r\n        case Constants.ALPHA_ADD:\r\n            return _native.Engine.ALPHA_ADD;\r\n        case Constants.ALPHA_COMBINE:\r\n            return _native.Engine.ALPHA_COMBINE;\r\n        case Constants.ALPHA_SUBTRACT:\r\n            return _native.Engine.ALPHA_SUBTRACT;\r\n        case Constants.ALPHA_MULTIPLY:\r\n            return _native.Engine.ALPHA_MULTIPLY;\r\n        case Constants.ALPHA_MAXIMIZED:\r\n            return _native.Engine.ALPHA_MAXIMIZED;\r\n        case Constants.ALPHA_ONEONE:\r\n            return _native.Engine.ALPHA_ONEONE;\r\n        case Constants.ALPHA_ONEONE_ONEONE:\r\n            return _native.Engine.ALPHA_ONEONE_ONEONE ?? _getFallbackAlphaMode(mode, \"ALPHA_ONEONE_ONEONE\");\r\n        case Constants.ALPHA_LAYER_ACCUMULATE:\r\n            return _native.Engine.ALPHA_LAYER_ACCUMULATE ?? _getFallbackAlphaMode(mode, \"ALPHA_LAYER_ACCUMULATE\");\r\n        case Constants.ALPHA_PREMULTIPLIED:\r\n            return _native.Engine.ALPHA_PREMULTIPLIED;\r\n        case Constants.ALPHA_PREMULTIPLIED_PORTERDUFF:\r\n            return _native.Engine.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n        case Constants.ALPHA_INTERPOLATE:\r\n            return _native.Engine.ALPHA_INTERPOLATE;\r\n        case Constants.ALPHA_SCREENMODE:\r\n            return _native.Engine.ALPHA_SCREENMODE;\r\n        case Constants.ALPHA_REPLACE_COLOR:\r\n            return _native.Engine.ALPHA_REPLACE_COLOR ?? _getFallbackAlphaMode(mode, \"ALPHA_REPLACE_COLOR\", _native.Engine.ALPHA_COMBINE, \"ALPHA_COMBINE\");\r\n        default:\r\n            throw new Error(`Unsupported alpha mode: ${mode}.`);\r\n    }\r\n}\r\n\r\nexport function getNativeAttribType(type: number): number {\r\n    switch (type) {\r\n        case VertexBuffer.BYTE:\r\n            return _native.Engine.ATTRIB_TYPE_INT8;\r\n        case VertexBuffer.UNSIGNED_BYTE:\r\n            return _native.Engine.ATTRIB_TYPE_UINT8;\r\n        case VertexBuffer.SHORT:\r\n            return _native.Engine.ATTRIB_TYPE_INT16;\r\n        case VertexBuffer.UNSIGNED_SHORT:\r\n            return _native.Engine.ATTRIB_TYPE_UINT16;\r\n        case VertexBuffer.FLOAT:\r\n            return _native.Engine.ATTRIB_TYPE_FLOAT;\r\n        // HALF_FLOAT (as well as INT and UNSIGNED_INT) has no equivalent in the native bindings, which only\r\n        // expose ATTRIB_TYPE_INT8/UINT8/INT16/UINT16/FLOAT. Those vertex attribute types are therefore\r\n        // WebGL/WebGPU only and intentionally fall through to the throw below on the Babylon Native engine.\r\n        default:\r\n            throw new Error(`Unsupported attribute type: ${type}.`);\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type _IShaderProcessingContext } from \"../Engines/Processors/shaderProcessingOptions\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { VertexBuffer } from \"../Meshes/buffer\";\r\nimport { VertexBufferDeduceStride } from \"./buffer.pure\";\r\n\r\nconst VertexBufferKindForNonFloatProcessing: { [kind: string]: boolean } = {\r\n    [VertexBuffer.PositionKind]: true,\r\n    [VertexBuffer.NormalKind]: true,\r\n    [VertexBuffer.TangentKind]: true,\r\n    [VertexBuffer.UVKind]: true,\r\n    [VertexBuffer.UV2Kind]: true,\r\n    [VertexBuffer.UV3Kind]: true,\r\n    [VertexBuffer.UV4Kind]: true,\r\n    [VertexBuffer.UV5Kind]: true,\r\n    [VertexBuffer.UV6Kind]: true,\r\n    [VertexBuffer.ColorKind]: true,\r\n    [VertexBuffer.ColorInstanceKind]: true,\r\n    [VertexBuffer.MatricesIndicesKind]: true,\r\n    [VertexBuffer.MatricesWeightsKind]: true,\r\n    [VertexBuffer.MatricesIndicesExtraKind]: true,\r\n    [VertexBuffer.MatricesWeightsExtraKind]: true,\r\n};\r\n\r\n/**\r\n * Indicates if the type is a signed or unsigned type\r\n * @param type Type to check\r\n * @returns True if it is a signed type\r\n */\r\nfunction IsSignedType(type: number): boolean {\r\n    switch (type) {\r\n        case VertexBuffer.BYTE:\r\n        case VertexBuffer.SHORT:\r\n        case VertexBuffer.INT:\r\n        case VertexBuffer.FLOAT:\r\n        case VertexBuffer.HALF_FLOAT:\r\n            return true;\r\n        case VertexBuffer.UNSIGNED_BYTE:\r\n        case VertexBuffer.UNSIGNED_SHORT:\r\n        case VertexBuffer.UNSIGNED_INT:\r\n            return false;\r\n        default:\r\n            throw new Error(`Invalid type '${type}'`);\r\n    }\r\n}\r\n\r\n/**\r\n * Checks whether some vertex buffers that should be of type float are of a different type (int, byte...).\r\n * If so, trigger a shader recompilation to give the shader processor the opportunity to update the code accordingly.\r\n * @param vertexBuffers List of vertex buffers to check\r\n * @param effect The effect (shaders) that should be recompiled if needed\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function checkNonFloatVertexBuffers(vertexBuffers: { [key: string]: Nullable<VertexBuffer> }, effect: Effect): void {\r\n    const engine = effect.getEngine();\r\n    const pipelineContext = effect._pipelineContext;\r\n\r\n    if (!pipelineContext?.vertexBufferKindToType) {\r\n        return;\r\n    }\r\n\r\n    let shaderProcessingContext: Nullable<_IShaderProcessingContext> = null;\r\n\r\n    for (const kind in vertexBuffers) {\r\n        const currentVertexBuffer = vertexBuffers[kind];\r\n\r\n        if (!currentVertexBuffer || !VertexBufferKindForNonFloatProcessing[kind]) {\r\n            continue;\r\n        }\r\n\r\n        const currentVertexBufferType = currentVertexBuffer.normalized || currentVertexBuffer.type === VertexBuffer.HALF_FLOAT ? VertexBuffer.FLOAT : currentVertexBuffer.type;\r\n        const vertexBufferType = pipelineContext.vertexBufferKindToType[kind];\r\n\r\n        if (\r\n            (currentVertexBufferType !== VertexBuffer.FLOAT && vertexBufferType === undefined) ||\r\n            (vertexBufferType !== undefined && vertexBufferType !== currentVertexBufferType)\r\n        ) {\r\n            if (!shaderProcessingContext) {\r\n                shaderProcessingContext = engine._getShaderProcessingContext(effect.shaderLanguage, false)!;\r\n            }\r\n            pipelineContext.vertexBufferKindToType[kind] = currentVertexBufferType;\r\n            if (currentVertexBufferType !== VertexBuffer.FLOAT) {\r\n                shaderProcessingContext.vertexBufferKindToNumberOfComponents![kind] = VertexBufferDeduceStride(kind);\r\n                if (IsSignedType(currentVertexBufferType)) {\r\n                    shaderProcessingContext.vertexBufferKindToNumberOfComponents![kind] *= -1;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    if (shaderProcessingContext) {\r\n        // We temporarily disable parallel compilation of shaders because we want new shaders to be compiled after the _processShaderCode call, so that they are in effect for the rest of the frame.\r\n        // There is no additional call to async so the _processShaderCodeAsync will execute synchronously.\r\n        const parallelShaderCompile = engine._caps.parallelShaderCompile;\r\n        engine._caps.parallelShaderCompile = undefined;\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        effect._processShaderCodeAsync(null, engine._features._checkNonFloatVertexBuffersDontRecreatePipelineContext, shaderProcessingContext);\r\n\r\n        engine._caps.parallelShaderCompile = parallelShaderCompile;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { type _IShaderProcessingContext } from \"../Processors/shaderProcessingOptions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class NativeShaderProcessingContext implements _IShaderProcessingContext {\r\n    public vertexBufferKindToNumberOfComponents: { [kind: string]: number } = {};\r\n    public remappedAttributeNames: { [name: string]: string } = {};\r\n    public injectInVertexMain = \"\";\r\n}\r\n","import { type Nullable } from \"../types\";\r\n/**\r\n * @internal\r\n **/\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _TimeToken {\r\n    public _startTimeQuery: Nullable<WebGLQuery>;\r\n    public _endTimeQuery: Nullable<WebGLQuery>;\r\n    public _timeElapsedQuery: Nullable<WebGLQuery>;\r\n    public _timeElapsedQueryEnded = false;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable, type IndicesArray, type DataArray, type FloatArray, type DeepImmutable, type int } from \"../types\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { RegisterBufferAlign } from \"../Buffers/buffer.align.pure\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type VideoTexture } from \"../Materials/Textures/videoTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport {\r\n    type RenderTargetCreationOptions,\r\n    type TextureSize,\r\n    type DepthTextureCreationOptions,\r\n    type InternalTextureCreationOptions,\r\n} from \"../Materials/Textures/textureCreationOptions\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { type IMultiRenderTargetOptions } from \"../Materials/Textures/multiRenderTarget.pure\";\r\nimport { type IColor3Like, type IColor4Like, type IViewportLike } from \"../Maths/math.like\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Constants } from \"./constants\";\r\nimport { AbstractEngine, type ISceneLike } from \"./abstractEngine.pure\";\r\nimport { ThinEngine } from \"./thinEngine.pure\";\r\nimport { type IWebRequest } from \"../Misc/interfaces/iWebRequest\";\r\nimport { EngineStore } from \"./engineStore\";\r\nimport { ShaderCodeInliner } from \"./Processors/shaderCodeInliner\";\r\nimport { NativeShaderProcessor } from \"./Native/nativeShaderProcessors\";\r\nimport { type IMaterialContext } from \"./IMaterialContext\";\r\nimport { type IDrawContext } from \"./IDrawContext\";\r\nimport { type ICanvas, type IImage, type IPath2D } from \"./ICanvas\";\r\nimport { type IStencilState } from \"../States/IStencilState\";\r\nimport { type RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { type NativeData, NativeDataStream } from \"./Native/nativeDataStream\";\r\nimport {\r\n    type INative,\r\n    type INativeCamera,\r\n    type INativeEngine,\r\n    type NativeFramebuffer,\r\n    type NativeFrameStats,\r\n    type NativeProgram,\r\n    type NativeTexture,\r\n    type NativeUniform,\r\n    type NativeVertexArrayObject,\r\n} from \"./Native/nativeInterfaces\";\r\nimport { NativePipelineContext } from \"./Native/nativePipelineContext\";\r\nimport { NativeRenderTargetWrapper } from \"./Native/nativeRenderTargetWrapper\";\r\nimport { NativeHardwareTexture } from \"./Native/nativeHardwareTexture\";\r\nimport { type IHardwareTextureWrapper } from \"../Materials/Textures/hardwareTextureWrapper\";\r\nimport {\r\n    getNativeAlphaMode,\r\n    getNativeAttribType,\r\n    getNativeSamplingMode,\r\n    getNativeTextureFormat,\r\n    getNativeStencilDepthFail,\r\n    getNativeStencilDepthPass,\r\n    getNativeStencilFunc,\r\n    getNativeStencilOpFail,\r\n    getNativeAddressMode,\r\n} from \"./Native/nativeHelpers\";\r\nimport { checkNonFloatVertexBuffers } from \"../Buffers/buffer.nonFloatVertexBuffers\";\r\nimport { type _IShaderProcessingContext } from \"./Processors/shaderProcessingOptions\";\r\nimport { NativeShaderProcessingContext } from \"./Native/nativeShaderProcessingContext\";\r\nimport { type ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { type WebGLHardwareTexture } from \"./WebGL/webGLHardwareTexture\";\r\n\r\nimport { _TimeToken } from \"../Instrumentation/timeToken\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport { DecodeBase64UrlToBinary } from \"../Misc/fileTools.pure\";\r\n\r\ndeclare const _native: INative;\r\n\r\nconst onNativeObjectInitialized = /*#__PURE__*/ new Observable<INative>();\r\nif (typeof self !== \"undefined\" && !Object.prototype.hasOwnProperty.call(self, \"_native\")) {\r\n    let __native: INative;\r\n    Object.defineProperty(self, \"_native\", {\r\n        get: () => __native,\r\n        set: (value: INative) => {\r\n            __native = value;\r\n            if (__native) {\r\n                onNativeObjectInitialized.notifyObservers(__native);\r\n            }\r\n        },\r\n    });\r\n}\r\n\r\n/**\r\n * Returns _native only after it has been defined by BabylonNative.\r\n * @internal\r\n */\r\nexport async function AcquireNativeObjectAsync(): Promise<INative> {\r\n    return await new Promise((resolve) => {\r\n        if (typeof _native === \"undefined\") {\r\n            onNativeObjectInitialized.addOnce((nativeObject) => resolve(nativeObject));\r\n        } else {\r\n            resolve(_native);\r\n        }\r\n    });\r\n}\r\n\r\n/**\r\n * Registers a constructor on the _native object. See NativeXRFrame for an example.\r\n * @internal\r\n */\r\nexport async function RegisterNativeTypeAsync<Type>(typeName: string, constructor: Type) {\r\n    ((await AcquireNativeObjectAsync()) as any)[typeName] = constructor;\r\n}\r\n\r\n/**\r\n * Container for accessors for natively-stored mesh data buffers.\r\n */\r\nclass NativeDataBuffer extends DataBuffer {\r\n    /**\r\n     * Accessor value used to identify/retrieve a natively-stored index buffer.\r\n     */\r\n    public nativeIndexBuffer?: NativeData;\r\n\r\n    /**\r\n     * Accessor value used to identify/retrieve a natively-stored vertex buffer.\r\n     */\r\n    public nativeVertexBuffer?: NativeData;\r\n}\r\n\r\n/**\r\n * Options to create the Native engine\r\n */\r\nexport interface ThinNativeEngineOptions {\r\n    /**\r\n     * defines whether to adapt to the device's viewport characteristics (default: false)\r\n     */\r\n    adaptToDeviceRatio?: boolean;\r\n}\r\n\r\n/** @internal */\r\nclass CommandBufferEncoder {\r\n    private readonly _commandStream: NativeDataStream;\r\n    private readonly _pending = new Array<NativeData>();\r\n    private _isCommandBufferScopeActive = false;\r\n\r\n    public constructor(private readonly _engine: INativeEngine) {\r\n        this._commandStream = ThinNativeEngine._createNativeDataStream();\r\n        this._engine.setCommandDataStream(this._commandStream);\r\n    }\r\n\r\n    public beginCommandScope() {\r\n        if (this._isCommandBufferScopeActive) {\r\n            throw new Error(\"Command scope already active.\");\r\n        }\r\n\r\n        this._isCommandBufferScopeActive = true;\r\n    }\r\n\r\n    public endCommandScope() {\r\n        if (!this._isCommandBufferScopeActive) {\r\n            throw new Error(\"Command scope is not active.\");\r\n        }\r\n\r\n        this._isCommandBufferScopeActive = false;\r\n        this._submit();\r\n    }\r\n\r\n    public startEncodingCommand(command: NativeData) {\r\n        this._commandStream.writeNativeData(command);\r\n    }\r\n\r\n    public encodeCommandArgAsUInt32(commandArg: number) {\r\n        this._commandStream.writeUint32(commandArg);\r\n    }\r\n\r\n    public encodeCommandArgAsUInt32s(commandArg: Uint32Array) {\r\n        this._commandStream.writeUint32Array(commandArg);\r\n    }\r\n\r\n    public encodeCommandArgAsInt32(commandArg: number) {\r\n        this._commandStream.writeInt32(commandArg);\r\n    }\r\n\r\n    public encodeCommandArgAsInt32s(commandArg: Int32Array) {\r\n        this._commandStream.writeInt32Array(commandArg);\r\n    }\r\n\r\n    public encodeCommandArgAsFloat32(commandArg: number) {\r\n        this._commandStream.writeFloat32(commandArg);\r\n    }\r\n\r\n    public encodeCommandArgAsFloat32s(commandArg: DeepImmutable<FloatArray>) {\r\n        this._commandStream.writeFloat32Array(commandArg);\r\n    }\r\n\r\n    public encodeCommandArgAsNativeData(commandArg: NativeData) {\r\n        this._commandStream.writeNativeData(commandArg);\r\n        this._pending.push(commandArg);\r\n    }\r\n\r\n    public finishEncodingCommand() {\r\n        if (!this._isCommandBufferScopeActive) {\r\n            this._submit();\r\n        }\r\n    }\r\n\r\n    private _submit() {\r\n        this._engine.submitCommands();\r\n        this._pending.length = 0;\r\n    }\r\n}\r\n\r\nconst remappedAttributesNames: string[] = [];\r\n\r\n/** @internal */\r\nexport class ThinNativeEngine extends ThinEngine {\r\n    // This must match the protocol version in NativeEngine.cpp\r\n    private static readonly PROTOCOL_VERSION = 9;\r\n\r\n    /** @internal */\r\n    public static _createNativeDataStream(): NativeDataStream {\r\n        return new NativeDataStream();\r\n    }\r\n\r\n    /////////// No assignment allowed in constructor           ///////////\r\n    /////////// They should all be in _initializeNativeEngine  ///////////\r\n    /////////// To ensure a correct sharing with NativeEngine  ///////////\r\n    protected _engine: INativeEngine;\r\n    private _camera: Nullable<INativeCamera>;\r\n    private _commandBufferEncoder: CommandBufferEncoder;\r\n    private _frameStats: NativeFrameStats;\r\n    private _boundBuffersVertexArray: any;\r\n    private _currentDepthTest: number;\r\n    private _depthTestEnabled: boolean;\r\n    private _stencilTest: boolean;\r\n    private _stencilMask: number;\r\n    private _stencilFunc: number;\r\n    private _stencilFuncRef: number;\r\n    private _stencilFuncMask: number;\r\n    private _stencilOpStencilFail: number;\r\n    private _stencilOpDepthFail: number;\r\n    private _stencilOpStencilDepthPass: number;\r\n    private _zOffset: number;\r\n    private _zOffsetUnits: number;\r\n    private _cachedCulling: boolean;\r\n    private _cachedReverseSide: boolean;\r\n    private _cachedCullBackFaces: boolean;\r\n    private _cachedZOffset: number;\r\n    private _cachedZOffsetUnits: number;\r\n    private _depthWrite: boolean;\r\n    // warning for non supported fill mode has already been displayed\r\n    private _fillModeWarningDisplayed: boolean;\r\n\r\n    public constructor(options: ThinNativeEngineOptions = {}) {\r\n        super(null, false, undefined, options.adaptToDeviceRatio);\r\n        this._initializeNativeEngine(options.adaptToDeviceRatio ?? false);\r\n    }\r\n    //////////////////////////////////////////////////////////////////////\r\n\r\n    /**\r\n     * Keeps as a separate function to use in NativeEngine\r\n     * @internal\r\n     */\r\n    protected _initializeNativeEngine(adaptToDeviceRatio: boolean): void {\r\n        // ThinNativeEngine relies on VertexBuffer.effective{Buffer,ByteOffset,ByteStride}\r\n        // (defined in Buffers/buffer.align.pure) to bind vertex attributes through\r\n        // recordVertexBuffer. Register the side effect here so the engine is usable\r\n        // on its own without callers having to remember to import the wrapper module.\r\n        // The registration is idempotent.\r\n        RegisterBufferAlign();\r\n\r\n        this._engine = new _native.Engine({\r\n            version: AbstractEngine.Version,\r\n            nonFloatVertexBuffers: true,\r\n        });\r\n        this._camera = _native.Camera ? new _native.Camera() : null;\r\n        this._commandBufferEncoder = new CommandBufferEncoder(this._engine);\r\n        this._frameStats = { gpuTimeNs: Number.NaN };\r\n        this._boundBuffersVertexArray = null;\r\n        this._currentDepthTest = _native.Engine.DEPTH_TEST_LEQUAL;\r\n        this._depthTestEnabled = true;\r\n        this._stencilTest = false;\r\n        this._stencilMask = 255;\r\n        this._stencilFunc = Constants.ALWAYS;\r\n        this._stencilFuncRef = 0;\r\n        this._stencilFuncMask = 255;\r\n        this._stencilOpStencilFail = Constants.KEEP;\r\n        this._stencilOpDepthFail = Constants.KEEP;\r\n        this._stencilOpStencilDepthPass = Constants.REPLACE;\r\n        this._zOffset = 0;\r\n        this._zOffsetUnits = 0;\r\n        this._cachedCulling = true;\r\n        this._cachedReverseSide = false;\r\n        this._cachedCullBackFaces = true;\r\n        this._cachedZOffset = 0;\r\n        this._cachedZOffsetUnits = 0;\r\n        this._depthWrite = true;\r\n        // warning for non supported fill mode has already been displayed\r\n        this._fillModeWarningDisplayed = false;\r\n\r\n        this._drawCalls = new PerfCounter();\r\n\r\n        if (_native.Engine.PROTOCOL_VERSION !== ThinNativeEngine.PROTOCOL_VERSION) {\r\n            throw new Error(`Protocol version mismatch: ${_native.Engine.PROTOCOL_VERSION} (Native) !== ${ThinNativeEngine.PROTOCOL_VERSION} (JS)`);\r\n        }\r\n\r\n        // Prefer setRenderResetCallback (accurate name -- fires when bgfx is (re)initialized,\r\n        // i.e. on device restore). Fall back to the legacy setDeviceLostCallback for backward\r\n        // compatibility with older BabylonNative builds. See BabylonNative #1722.\r\n        const renderResetCallback = () => {\r\n            this.onContextLostObservable.notifyObservers(this);\r\n            this._contextWasLost = true;\r\n            this._restoreEngineAfterContextLost();\r\n        };\r\n        if (this._engine.setRenderResetCallback) {\r\n            this._engine.setRenderResetCallback(renderResetCallback);\r\n        } else if (this._engine.setDeviceLostCallback) {\r\n            this._engine.setDeviceLostCallback(renderResetCallback);\r\n        }\r\n\r\n        this._webGLVersion = 2;\r\n        this.disableUniformBuffers = true;\r\n        this._shaderPlatformName = \"NATIVE\";\r\n        // Babylon Native is not WebGL and has no _gl context. Report a distinct engine name (like\r\n        // WebGPU reports \"WebGPU\") so application/feature code that branches on engine.name === \"WebGL\"\r\n        // to touch the WebGL-only _gl context skips the native engine instead of dereferencing null.\r\n        this._name = \"Native\";\r\n\r\n        // TODO: Initialize this more correctly based on the hardware capabilities.\r\n        // Init caps\r\n\r\n        this._caps = {\r\n            maxTexturesImageUnits: 16,\r\n            maxVertexTextureImageUnits: 16,\r\n            maxCombinedTexturesImageUnits: 32,\r\n            maxTextureSize: _native.Engine.CAPS_LIMITS_MAX_TEXTURE_SIZE,\r\n            maxCubemapTextureSize: 512,\r\n            maxRenderTextureSize: 512,\r\n            maxVertexAttribs: 16,\r\n            maxVaryingVectors: 16,\r\n            maxDrawBuffers: 8,\r\n            maxFragmentUniformVectors: 16,\r\n            maxVertexUniformVectors: 256,\r\n            shaderFloatPrecision: 23, // TODO: is this correct?\r\n            standardDerivatives: true,\r\n            astc: null,\r\n            pvrtc: null,\r\n            etc1: null,\r\n            etc2: null,\r\n            bptc: null,\r\n            maxAnisotropy: 16, // TODO: Retrieve this smartly. Currently set to D3D11 maximum allowable value.\r\n            uintIndices: true,\r\n            fragmentDepthSupported: false,\r\n            highPrecisionShaderSupported: true,\r\n            colorBufferFloat: true,\r\n            blendFloat: true,\r\n            supportFloatTexturesResolve: false,\r\n            rg11b10ufColorRenderable: false,\r\n            textureFloat: true,\r\n            textureFloatLinearFiltering: true,\r\n            textureFloatRender: true,\r\n            textureHalfFloat: true,\r\n            textureHalfFloatLinearFiltering: true,\r\n            textureHalfFloatRender: true,\r\n            textureLOD: true,\r\n            texelFetch: true,\r\n            drawBuffersExtension: true,\r\n            depthTextureExtension: false,\r\n            vertexArrayObject: true,\r\n            instancedArrays: true,\r\n            supportOcclusionQuery: false,\r\n            canUseTimestampForTimerQuery: false,\r\n            blendMinMax: false,\r\n            maxMSAASamples: 16,\r\n            canUseGLInstanceID: true,\r\n            canUseGLVertexID: true,\r\n            supportComputeShaders: false,\r\n            supportSRGBBuffers: true,\r\n            supportTransformFeedbacks: false,\r\n            textureMaxLevel: false,\r\n            texture2DArrayMaxLayerCount: _native.Engine.CAPS_LIMITS_MAX_TEXTURE_LAYERS,\r\n            disableMorphTargetTexture: false,\r\n            parallelShaderCompile: { COMPLETION_STATUS_KHR: 0 },\r\n            textureNorm16: false,\r\n            blendParametersPerTarget: false,\r\n            dualSourceBlending: false,\r\n            supportReadWriteStorageTextures: false,\r\n        };\r\n\r\n        this._features = {\r\n            forceBitmapOverHTMLImageElement: true,\r\n            supportRenderAndCopyToLodForFloatTextures: false,\r\n            supportDepthStencilTexture: false,\r\n            supportShadowSamplers: false,\r\n            uniformBufferHardCheckMatrix: false,\r\n            allowTexturePrefiltering: false,\r\n            trackUbosInFrame: false,\r\n            checkUbosContentBeforeUpload: false,\r\n            supportCSM: false,\r\n            basisNeedsPOT: false,\r\n            support3DTextures: false,\r\n            needTypeSuffixInShaderConstants: false,\r\n            supportMSAA: true,\r\n            supportSSAO2: false,\r\n            supportIBLShadows: false,\r\n            supportExtendedTextureFormats: false,\r\n            supportSwitchCaseInShader: false,\r\n            supportSyncTextureRead: false,\r\n            needsInvertingBitmap: true,\r\n            useUBOBindingCache: true,\r\n            needShaderCodeInlining: true,\r\n            needToAlwaysBindUniformBuffers: false,\r\n            supportRenderPasses: true,\r\n            supportSpriteInstancing: false,\r\n            forceVertexBufferStrideAndOffsetMultiple4Bytes: true,\r\n            _checkNonFloatVertexBuffersDontRecreatePipelineContext: false,\r\n        };\r\n\r\n        Logger.Log(\"Babylon Native (v\" + AbstractEngine.Version + \") launched\");\r\n\r\n        // Wrappers\r\n        if (typeof URL === \"undefined\") {\r\n            (window.URL as any) = {\r\n                createObjectURL: function () {},\r\n                revokeObjectURL: function () {},\r\n            };\r\n        }\r\n\r\n        // TODO: Remove in next protocol version update\r\n        if (typeof Blob === \"undefined\") {\r\n            (window.Blob as any) = function (v: any) {\r\n                return v;\r\n            };\r\n        }\r\n\r\n        // polyfill for Chakra\r\n        if (!Array.prototype.flat) {\r\n            Object.defineProperty(Array.prototype, \"flat\", {\r\n                configurable: true,\r\n                value: function flat(this: any[], depth?: number) {\r\n                    depth = isNaN(depth as any) ? 1 : Number(depth);\r\n\r\n                    return depth\r\n                        ? Array.prototype.reduce.call(\r\n                              this,\r\n                              function (acc: any, cur: any) {\r\n                                  if (Array.isArray(cur)) {\r\n                                      // eslint-disable-next-line prefer-spread\r\n                                      acc.push.apply(acc, flat.call(cur, depth - 1));\r\n                                  } else {\r\n                                      acc.push(cur);\r\n                                  }\r\n                                  return acc;\r\n                              },\r\n                              []\r\n                          )\r\n                        : Array.prototype.slice.call(this);\r\n                },\r\n                writable: true,\r\n            });\r\n        }\r\n\r\n        // Currently we do not fully configure the ThinEngine on construction of NativeEngine.\r\n        // Setup resolution scaling based on display settings.\r\n        const devicePixelRatio = window ? window.devicePixelRatio || 1.0 : 1.0;\r\n        this._hardwareScalingLevel = adaptToDeviceRatio ? 1.0 / devicePixelRatio : 1.0;\r\n        this._engine.setHardwareScalingLevel(this._hardwareScalingLevel);\r\n        this._lastDevicePixelRatio = devicePixelRatio;\r\n        this.resize();\r\n\r\n        const currentDepthFunction = this.getDepthFunction();\r\n        if (currentDepthFunction) {\r\n            this.setDepthFunction(currentDepthFunction);\r\n        }\r\n\r\n        // Shader processor\r\n        this._shaderProcessor = new NativeShaderProcessor();\r\n\r\n        this.onNewSceneAddedObservable.add((scene) => {\r\n            this._wrapSceneRenderWithCommandScope(scene);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Brackets a scene's render with a command scope, so the commands it encodes are submitted together.\r\n     * @param scene the scene whose render should be wrapped\r\n     */\r\n    private _wrapSceneRenderWithCommandScope(scene: Scene): void {\r\n        const originalRender = scene.render;\r\n        scene.render = (...args: Parameters<typeof originalRender>) => {\r\n            this._commandBufferEncoder.beginCommandScope();\r\n            try {\r\n                originalRender.apply(scene, args);\r\n            } catch (renderException) {\r\n                // The scope must be closed even when the render throws. Otherwise it stays\r\n                // open forever and every later frame fails with \"Command scope already\r\n                // active.\", so one recoverable error permanently breaks the engine instead\r\n                // of affecting just this frame.\r\n                try {\r\n                    this._commandBufferEncoder.endCommandScope();\r\n                } catch (endException) {\r\n                    // Never let this replace the root cause; report it separately instead.\r\n                    Logger.Error(`Failed to end the command scope while unwinding a render error: ${endException}`);\r\n                }\r\n                throw renderException;\r\n            }\r\n\r\n            this._commandBufferEncoder.endCommandScope();\r\n        };\r\n    }\r\n\r\n    public override setHardwareScalingLevel(level: number): void {\r\n        super.setHardwareScalingLevel(level);\r\n        this._engine.setHardwareScalingLevel(level);\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        if (this._boundBuffersVertexArray) {\r\n            this._deleteVertexArray(this._boundBuffersVertexArray);\r\n        }\r\n        this._engine.dispose();\r\n    }\r\n\r\n    /**\r\n     * Enable scissor test on a specific rectangle (ie. render will only be executed on a specific portion of the screen)\r\n     * @param x defines the x-coordinate of the bottom left corner of the clear rectangle\r\n     * @param y defines the y-coordinate of the corner of the clear rectangle\r\n     * @param width defines the width of the clear rectangle\r\n     * @param height defines the height of the clear rectangle\r\n     */\r\n    public override enableScissor(x: number, y: number, width: number, height: number): void {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETSCISSOR);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(x);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(y);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(width);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(height);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    /**\r\n     * Disable previously set scissor test rectangle\r\n     */\r\n    public override disableScissor() {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETSCISSOR);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(0);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    /**\r\n     * Can be used to override the current requestAnimationFrame requester.\r\n     * @internal\r\n     */\r\n    protected override _queueNewFrame(bindedRenderFunction: any, requester?: any): number {\r\n        // Use the provided requestAnimationFrame, unless the requester is the window. In that case, we will default to the Babylon Native version of requestAnimationFrame.\r\n        if (requester?.requestAnimationFrame && requester !== this.getHostWindow()) {\r\n            return requester.requestAnimationFrame(bindedRenderFunction);\r\n        } else {\r\n            this._engine.requestAnimationFrame(bindedRenderFunction);\r\n        }\r\n        return 0;\r\n    }\r\n\r\n    protected override _restoreEngineAfterContextLost(): void {\r\n        this._clearEmptyResources();\r\n\r\n        const depthTest = this._depthCullingState.depthTest; // backup those values because the call to initEngine / wipeCaches will reset them\r\n        const depthFunc = this._depthCullingState.depthFunc;\r\n        const depthMask = this._depthCullingState.depthMask;\r\n        const stencilTest = this._stencilState.stencilTest;\r\n\r\n        this._rebuildGraphicsResources();\r\n\r\n        this._depthCullingState.depthTest = depthTest;\r\n        this._depthCullingState.depthFunc = depthFunc;\r\n        this._depthCullingState.depthMask = depthMask;\r\n        this._stencilState.stencilTest = stencilTest;\r\n\r\n        this._flagContextRestored();\r\n    }\r\n\r\n    /**\r\n     * Override default engine behavior.\r\n     * @param framebuffer\r\n     */\r\n    public override _bindUnboundFramebuffer(framebuffer: Nullable<WebGLFramebuffer>) {\r\n        if (this._currentFramebuffer !== framebuffer) {\r\n            if (this._currentFramebuffer) {\r\n                this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_UNBINDFRAMEBUFFER);\r\n                this._commandBufferEncoder.encodeCommandArgAsNativeData(this._currentFramebuffer as NativeFramebuffer);\r\n                this._commandBufferEncoder.finishEncodingCommand();\r\n            }\r\n\r\n            if (framebuffer) {\r\n                this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_BINDFRAMEBUFFER);\r\n                this._commandBufferEncoder.encodeCommandArgAsNativeData(framebuffer as NativeFramebuffer);\r\n                this._commandBufferEncoder.finishEncodingCommand();\r\n            }\r\n\r\n            this._currentFramebuffer = framebuffer;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets host document\r\n     * @returns the host document object\r\n     */\r\n    public override getHostDocument(): Nullable<Document> {\r\n        return null;\r\n    }\r\n\r\n    public override clear(color: Nullable<IColor4Like>, backBuffer: boolean, depth: boolean, stencil: boolean = false, stencilClearValue = 0): void {\r\n        if (depth && this.useReverseDepthBuffer) {\r\n            // Reverse-Z: the scene is rendered with a flipped projection (near maps to 1, far to 0), so the\r\n            // depth buffer is cleared to 0 and the comparison must accept greater values. The WebGL engine\r\n            // sets depthCullingState.depthFunc = GEQUAL here and relies on applyStates() running the depth\r\n            // comparison to the GL context before each draw. The native draw path does not call applyStates()\r\n            // (only depth-test enable/disable is reconciled in _flushDepthTestState()), so setting the shared\r\n            // state alone would never reach the backend. Route the comparison through the native command path\r\n            // as well -- mirroring the WebGPU engine's clear path, which calls setDepthFunctionToGreaterOrEqual().\r\n            this._depthCullingState.depthFunc = Constants.GEQUAL;\r\n            this.setDepthFunction(Constants.GEQUAL);\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_CLEAR);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(backBuffer && color ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(color ? color.r : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(color ? color.g : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(color ? color.b : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(color ? color.a : 1);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(depth ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(depth && this.useReverseDepthBuffer ? 0 : 1);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(stencil ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(stencilClearValue);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    public override createIndexBuffer(indices: IndicesArray, updateable?: boolean, _label?: string): NativeDataBuffer {\r\n        const data = this._normalizeIndexData(indices);\r\n        const buffer = new NativeDataBuffer();\r\n        buffer.references = 1;\r\n        buffer.is32Bits = data.BYTES_PER_ELEMENT === 4;\r\n        if (data.byteLength) {\r\n            buffer.nativeIndexBuffer = this._engine.createIndexBuffer(data.buffer, data.byteOffset, data.byteLength, buffer.is32Bits, updateable ?? false);\r\n        }\r\n        return buffer;\r\n    }\r\n\r\n    public override createVertexBuffer(vertices: DataArray, updateable?: boolean, _label?: string): NativeDataBuffer {\r\n        const data = ArrayBuffer.isView(vertices) ? vertices : new Float32Array(vertices);\r\n        const buffer = new NativeDataBuffer();\r\n        buffer.references = 1;\r\n        if (data.byteLength) {\r\n            buffer.nativeVertexBuffer = this._engine.createVertexBuffer(data.buffer, data.byteOffset, data.byteLength, updateable ?? false);\r\n        }\r\n        return buffer;\r\n    }\r\n\r\n    private _recordVertexArrayObject(\r\n        vertexArray: any,\r\n        vertexBuffers: { [key: string]: VertexBuffer },\r\n        indexBuffer: Nullable<NativeDataBuffer>,\r\n        effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): void {\r\n        if (!effect._checkedNonFloatVertexBuffers) {\r\n            checkNonFloatVertexBuffers(vertexBuffers, effect);\r\n            effect._checkedNonFloatVertexBuffers = true;\r\n        }\r\n\r\n        if (indexBuffer) {\r\n            this._engine.recordIndexBuffer(vertexArray, indexBuffer.nativeIndexBuffer!);\r\n        }\r\n\r\n        const attributes = effect.getAttributesNames();\r\n        for (let index = 0; index < attributes.length; index++) {\r\n            const location = effect.getAttributeLocation(index);\r\n            if (location >= 0) {\r\n                const kind = attributes[index];\r\n                let vertexBuffer: Nullable<VertexBuffer> = null;\r\n\r\n                if (overrideVertexBuffers) {\r\n                    vertexBuffer = overrideVertexBuffers[kind];\r\n                }\r\n                if (!vertexBuffer) {\r\n                    vertexBuffer = vertexBuffers[kind];\r\n                }\r\n\r\n                if (vertexBuffer) {\r\n                    const buffer = vertexBuffer.effectiveBuffer as Nullable<NativeDataBuffer>;\r\n                    if (buffer && buffer.nativeVertexBuffer) {\r\n                        this._engine.recordVertexBuffer(\r\n                            vertexArray,\r\n                            buffer.nativeVertexBuffer,\r\n                            location,\r\n                            vertexBuffer.effectiveByteOffset,\r\n                            vertexBuffer.effectiveByteStride,\r\n                            vertexBuffer.getSize(),\r\n                            getNativeAttribType(vertexBuffer.type),\r\n                            vertexBuffer.normalized,\r\n                            vertexBuffer.getInstanceDivisor()\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public override bindBuffers(vertexBuffers: { [key: string]: VertexBuffer }, indexBuffer: Nullable<NativeDataBuffer>, effect: Effect): void {\r\n        if (this._boundBuffersVertexArray) {\r\n            this._deleteVertexArray(this._boundBuffersVertexArray);\r\n        }\r\n        this._boundBuffersVertexArray = this._engine.createVertexArray();\r\n        this._recordVertexArrayObject(this._boundBuffersVertexArray, vertexBuffers, indexBuffer, effect);\r\n        this.bindVertexArrayObject(this._boundBuffersVertexArray);\r\n    }\r\n\r\n    public override recordVertexArrayObject(\r\n        vertexBuffers: { [key: string]: VertexBuffer },\r\n        indexBuffer: Nullable<NativeDataBuffer>,\r\n        effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): WebGLVertexArrayObject {\r\n        const vertexArray = this._engine.createVertexArray();\r\n        this._recordVertexArrayObject(vertexArray, vertexBuffers, indexBuffer, effect, overrideVertexBuffers);\r\n        return vertexArray;\r\n    }\r\n\r\n    private _deleteVertexArray(vertexArray: NativeVertexArrayObject) {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DELETEVERTEXARRAY);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(vertexArray);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    public override bindVertexArrayObject(vertexArray: WebGLVertexArrayObject): void {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_BINDVERTEXARRAY);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(vertexArray as NativeVertexArrayObject);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    public override releaseVertexArrayObject(vertexArray: WebGLVertexArrayObject) {\r\n        this._deleteVertexArray(vertexArray as NativeVertexArrayObject);\r\n    }\r\n\r\n    public override getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[] {\r\n        const nativePipelineContext = pipelineContext as NativePipelineContext;\r\n        const nativeShaderProcessingContext = nativePipelineContext.shaderProcessingContext!;\r\n\r\n        remappedAttributesNames.length = 0;\r\n        for (let index = 0; index < attributesNames.length; index++) {\r\n            const origAttributeName = attributesNames[index];\r\n            const attributeName = nativeShaderProcessingContext.remappedAttributeNames[origAttributeName] ?? origAttributeName;\r\n            remappedAttributesNames[index] = attributeName;\r\n        }\r\n        return this._engine.getAttributes(nativePipelineContext.program, remappedAttributesNames);\r\n    }\r\n\r\n    /**\r\n     * Triangle Fan and Line Loop are not supported by modern rendering API\r\n     * @param fillMode  defines the primitive to use\r\n     * @returns true if supported\r\n     */\r\n    private _checkSupportedFillMode(fillMode: number): boolean {\r\n        if (fillMode == Constants.MATERIAL_LineLoopDrawMode || fillMode == Constants.MATERIAL_TriangleFanDrawMode) {\r\n            if (!this._fillModeWarningDisplayed) {\r\n                Logger.Warn(\"Line Loop and Triangle Fan are not supported fill modes with Babylon Native. Elements with these fill mode will not be visible.\");\r\n                this._fillModeWarningDisplayed = true;\r\n            }\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Draw a list of indexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public override drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void {\r\n        if (!this._checkSupportedFillMode(fillMode)) {\r\n            return;\r\n        }\r\n        // Apply states\r\n        this._flushDepthTestState();\r\n        this._drawCalls.addCount(1, false);\r\n\r\n        if (instancesCount) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DRAWINDEXEDINSTANCED);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(fillMode);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(indexStart);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(indexCount);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(instancesCount);\r\n        } else {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DRAWINDEXED);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(fillMode);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(indexStart);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(indexCount);\r\n        }\r\n\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    /**\r\n     * Draw a list of unindexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public override drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void {\r\n        if (!this._checkSupportedFillMode(fillMode)) {\r\n            return;\r\n        }\r\n        // Apply states\r\n        this._flushDepthTestState();\r\n        this._drawCalls.addCount(1, false);\r\n\r\n        if (instancesCount) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DRAWINSTANCED);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(fillMode);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(verticesStart);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(verticesCount);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(instancesCount);\r\n        } else {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DRAW);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(fillMode);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(verticesStart);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(verticesCount);\r\n        }\r\n\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    public override createPipelineContext(shaderProcessingContext: Nullable<_IShaderProcessingContext>): IPipelineContext {\r\n        const isAsync = !!this._caps.parallelShaderCompile;\r\n        return new NativePipelineContext(this, isAsync, shaderProcessingContext as Nullable<NativeShaderProcessingContext>);\r\n    }\r\n\r\n    public override createMaterialContext(): IMaterialContext | undefined {\r\n        return undefined;\r\n    }\r\n\r\n    public override createDrawContext(): IDrawContext | undefined {\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Function is not technically Async\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public override _preparePipelineContextAsync(\r\n        pipelineContext: IPipelineContext,\r\n        vertexSourceCode: string,\r\n        fragmentSourceCode: string,\r\n        createAsRaw: boolean,\r\n        _rawVertexSourceCode: string,\r\n        _rawFragmentSourceCode: string,\r\n        _rebuildRebind: any,\r\n        defines: Nullable<string>,\r\n        _transformFeedbackVaryings: Nullable<string[]>,\r\n        _key: string,\r\n        onReady: () => void\r\n    ) {\r\n        if (createAsRaw) {\r\n            this.createRawShaderProgram();\r\n        } else {\r\n            this.createShaderProgram(pipelineContext, vertexSourceCode, fragmentSourceCode, defines);\r\n        }\r\n\r\n        onReady();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _getShaderProcessingContext(_shaderLanguage: ShaderLanguage): Nullable<_IShaderProcessingContext> {\r\n        return new NativeShaderProcessingContext();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void) {\r\n        const nativePipelineContext = pipelineContext as NativePipelineContext;\r\n        if (nativePipelineContext.isAsync) {\r\n            if (nativePipelineContext.onCompiled) {\r\n                const oldHandler = nativePipelineContext.onCompiled;\r\n                nativePipelineContext.onCompiled = () => {\r\n                    oldHandler();\r\n                    action();\r\n                };\r\n            } else {\r\n                nativePipelineContext.onCompiled = action;\r\n            }\r\n        } else {\r\n            action();\r\n        }\r\n    }\r\n\r\n    public override createRawShaderProgram(): WebGLProgram {\r\n        throw new Error(\"Not Supported\");\r\n    }\r\n\r\n    public override createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>): WebGLProgram {\r\n        const nativePipelineContext = pipelineContext as NativePipelineContext;\r\n\r\n        this.onBeforeShaderCompilationObservable.notifyObservers(this);\r\n\r\n        const vertexInliner = new ShaderCodeInliner(vertexCode);\r\n        vertexInliner.processCode();\r\n        vertexCode = vertexInliner.code;\r\n\r\n        const fragmentInliner = new ShaderCodeInliner(fragmentCode);\r\n        fragmentInliner.processCode();\r\n        fragmentCode = fragmentInliner.code;\r\n\r\n        vertexCode = ThinEngine._ConcatenateShader(vertexCode, defines);\r\n        fragmentCode = ThinEngine._ConcatenateShader(fragmentCode, defines);\r\n\r\n        const onSuccess = () => {\r\n            nativePipelineContext.isCompiled = true;\r\n            nativePipelineContext.onCompiled?.();\r\n            this.onAfterShaderCompilationObservable.notifyObservers(this);\r\n        };\r\n\r\n        if (pipelineContext.isAsync) {\r\n            nativePipelineContext.program = this._engine.createProgramAsync(vertexCode, fragmentCode, onSuccess, (error: Error) => {\r\n                nativePipelineContext.compilationError = error;\r\n            });\r\n        } else {\r\n            try {\r\n                nativePipelineContext.program = this._engine.createProgram(vertexCode, fragmentCode);\r\n                onSuccess();\r\n            } catch (e) {\r\n                const message = e?.message;\r\n                throw new Error(\"SHADER ERROR\" + (typeof message === \"string\" ? \"\\n\" + message : \"\"), { cause: e });\r\n            }\r\n        }\r\n\r\n        return nativePipelineContext.program as WebGLProgram;\r\n    }\r\n\r\n    /**\r\n     * Inline functions in shader code that are marked to be inlined\r\n     * @param code code to inline\r\n     * @returns inlined code\r\n     */\r\n    public override inlineShaderCode(code: string): string {\r\n        const sci = new ShaderCodeInliner(code);\r\n        sci.debug = false;\r\n        sci.processCode();\r\n        return sci.code;\r\n    }\r\n\r\n    protected override _setProgram(program: WebGLProgram): void {\r\n        if (this._currentProgram !== program) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETPROGRAM);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(program as NativeProgram);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n            this._currentProgram = program;\r\n        }\r\n    }\r\n\r\n    public override _deletePipelineContext(pipelineContext: IPipelineContext): void {\r\n        const nativePipelineContext = pipelineContext as NativePipelineContext;\r\n        if (nativePipelineContext && nativePipelineContext.program) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DELETEPROGRAM);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(nativePipelineContext.program);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n        }\r\n    }\r\n\r\n    public override getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): WebGLUniformLocation[] {\r\n        const nativePipelineContext = pipelineContext as NativePipelineContext;\r\n        return this._engine.getUniforms(nativePipelineContext.program, uniformsNames);\r\n    }\r\n\r\n    public override bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void {\r\n        // TODO\r\n        throw new Error(\"Not Implemented\");\r\n    }\r\n\r\n    public override bindSamplers(effect: Effect): void {\r\n        const nativePipelineContext = effect.getPipelineContext() as NativePipelineContext;\r\n        this._setProgram(nativePipelineContext.program as WebGLProgram);\r\n\r\n        // TODO: share this with engine?\r\n        const samplers = effect.getSamplers();\r\n        for (let index = 0; index < samplers.length; index++) {\r\n            const uniform = effect.getUniform(samplers[index]);\r\n\r\n            if (uniform) {\r\n                this._boundUniforms[index] = uniform;\r\n            }\r\n        }\r\n        this._currentEffect = null;\r\n    }\r\n\r\n    public override getRenderWidth(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.width;\r\n        }\r\n\r\n        return this._engine.getRenderWidth();\r\n    }\r\n\r\n    public override getRenderHeight(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.height;\r\n        }\r\n\r\n        return this._engine.getRenderHeight();\r\n    }\r\n\r\n    public override setViewport(viewport: IViewportLike, requiredWidth?: number, requiredHeight?: number): void {\r\n        this._cachedViewport = viewport;\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETVIEWPORT);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(viewport.x);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(viewport.y);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(viewport.width);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(viewport.height);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    public override setStateCullFaceType(cullBackFaces?: boolean, force?: boolean): void {\r\n        const cullBack = this.cullBackFaces ?? cullBackFaces ?? true;\r\n        if (this._cachedCullBackFaces === cullBack && !force) {\r\n            return;\r\n        }\r\n        this._cachedCullBackFaces = cullBack;\r\n\r\n        // Native uses an immediate command-buffer state model (no lazy _depthCullingState), so\r\n        // re-issue the last COMMAND_SETSTATE payload with only the cull face changed. The zOffset\r\n        // values are the ones that command actually encoded rather than the live _zOffset fields,\r\n        // which setZOffset()/setZOffsetUnits() can update independently (and encode with the\r\n        // opposite sign under a reverse depth buffer).\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETSTATE);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(this._cachedCulling ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(this._cachedZOffset);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(this._cachedZOffsetUnits);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(cullBack ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(this._cachedReverseSide ? 1 : 0);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    public override setState(\r\n        culling: boolean,\r\n        zOffset: number = 0,\r\n        force?: boolean,\r\n        reverseSide = false,\r\n        cullBackFaces?: boolean,\r\n        stencil?: IStencilState,\r\n        zOffsetUnits: number = 0\r\n    ): void {\r\n        this._zOffset = zOffset;\r\n        this._zOffsetUnits = zOffsetUnits;\r\n        if (this._zOffset !== 0) {\r\n            Logger.Warn(\"zOffset is not supported in Native engine.\");\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETSTATE);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(culling ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(zOffset);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(zOffsetUnits);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32((this.cullBackFaces ?? cullBackFaces ?? true) ? 1 : 0);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(reverseSide ? 1 : 0);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n\r\n        // Cache the resolved state so setStateCullFaceType() can re-issue it with a new cull face.\r\n        this._cachedCulling = culling;\r\n        this._cachedReverseSide = reverseSide;\r\n        this._cachedCullBackFaces = this.cullBackFaces ?? cullBackFaces ?? true;\r\n        this._cachedZOffset = zOffset;\r\n        this._cachedZOffsetUnits = zOffsetUnits;\r\n    }\r\n\r\n    /**\r\n     * Gets the client rect of native canvas.  Needed for InputManager.\r\n     * @returns a client rectangle\r\n     */\r\n    public override getInputElementClientRect(): Nullable<DOMRect> {\r\n        const rect = {\r\n            bottom: this.getRenderHeight(),\r\n            height: this.getRenderHeight(),\r\n            left: 0,\r\n            right: this.getRenderWidth(),\r\n            top: 0,\r\n            width: this.getRenderWidth(),\r\n            x: 0,\r\n            y: 0,\r\n            toJSON: () => {},\r\n        };\r\n        return rect;\r\n    }\r\n\r\n    /**\r\n     * Set the z offset Factor to apply to current rendering\r\n     * @param value defines the offset to apply\r\n     */\r\n    public override setZOffset(value: number): void {\r\n        if (value !== this._zOffset) {\r\n            this._zOffset = value;\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETZOFFSET);\r\n            this._commandBufferEncoder.encodeCommandArgAsFloat32(this.useReverseDepthBuffer ? -value : value);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the zOffset Factor\r\n     * @returns the current zOffset Factor state\r\n     */\r\n    public override getZOffset(): number {\r\n        return this._zOffset;\r\n    }\r\n\r\n    /**\r\n     * Set the z offset Units to apply to current rendering\r\n     * @param value defines the offset to apply\r\n     */\r\n    public override setZOffsetUnits(value: number): void {\r\n        if (value !== this._zOffsetUnits) {\r\n            this._zOffsetUnits = value;\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETZOFFSETUNITS);\r\n            this._commandBufferEncoder.encodeCommandArgAsFloat32(this.useReverseDepthBuffer ? -value : value);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the current value of the zOffset Units\r\n     * @returns the current zOffset Units state\r\n     */\r\n    public override getZOffsetUnits(): number {\r\n        return this._zOffsetUnits;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable depth buffering\r\n     * @param enable defines the state to set\r\n     */\r\n    public override setDepthBuffer(enable: boolean): void {\r\n        // Keep the shared depth-culling state in sync so that code paths which toggle\r\n        // depth testing through engine.depthCullingState.depthTest (for example\r\n        // EffectRenderer.applyEffectWrapper) are also honored on the native side. The\r\n        // native draw path does not go through the WebGL applyStates() flush, so the\r\n        // value is reconciled in _flushDepthTestState() right before each draw.\r\n        this._depthCullingState.depthTest = enable;\r\n        this._encodeDepthTest(enable);\r\n    }\r\n\r\n    private _encodeDepthTest(enable: boolean): void {\r\n        this._depthTestEnabled = enable;\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETDEPTHTEST);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(enable ? this._currentDepthTest : _native.Engine.DEPTH_TEST_ALWAYS);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    private _flushDepthTestState(): void {\r\n        // Unlike the WebGL engine, the native engine does not call applyStates() before\r\n        // a draw, so depth-test toggles made directly on engine.depthCullingState are\r\n        // flushed here to match the cross-engine contract.\r\n        if (this._depthCullingState.depthTest !== this._depthTestEnabled) {\r\n            this._encodeDepthTest(this._depthCullingState.depthTest);\r\n        }\r\n    }\r\n\r\n    public override applyStates(): void {\r\n        // The base ThinEngine.applyStates() drives the WebGL context (this._gl) directly, which is null on\r\n        // Native. Flush the depth-culling state through the native command path instead, so callers that\r\n        // mutate engine.depthCullingState directly and then call applyStates() (e.g. the depth-peeling / OIT\r\n        // renderer) take effect. Alpha and stencil state are applied on Native via their dedicated setters\r\n        // (setAlphaMode / setStencil*), which encode their commands when called.\r\n        const depthCullingState = this._depthCullingState;\r\n        if (depthCullingState.depthFunc !== null && depthCullingState.depthFunc !== undefined) {\r\n            this.setDepthFunction(depthCullingState.depthFunc);\r\n        }\r\n        this.setDepthBuffer(depthCullingState.depthTest);\r\n        this.setDepthWrite(depthCullingState.depthMask);\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if depth writing is enabled\r\n     * @returns the current depth writing state\r\n     */\r\n    public override getDepthWrite(): boolean {\r\n        return this._depthWrite;\r\n    }\r\n\r\n    public override getDepthFunction(): Nullable<number> {\r\n        switch (this._currentDepthTest) {\r\n            case _native.Engine.DEPTH_TEST_NEVER:\r\n                return Constants.NEVER;\r\n            case _native.Engine.DEPTH_TEST_ALWAYS:\r\n                return Constants.ALWAYS;\r\n            case _native.Engine.DEPTH_TEST_GREATER:\r\n                return Constants.GREATER;\r\n            case _native.Engine.DEPTH_TEST_GEQUAL:\r\n                return Constants.GEQUAL;\r\n            case _native.Engine.DEPTH_TEST_NOTEQUAL:\r\n                return Constants.NOTEQUAL;\r\n            case _native.Engine.DEPTH_TEST_EQUAL:\r\n                return Constants.EQUAL;\r\n            case _native.Engine.DEPTH_TEST_LESS:\r\n                return Constants.LESS;\r\n            case _native.Engine.DEPTH_TEST_LEQUAL:\r\n                return Constants.LEQUAL;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public override setDepthFunction(depthFunc: number) {\r\n        let nativeDepthFunc = 0;\r\n        switch (depthFunc) {\r\n            case Constants.NEVER:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_NEVER;\r\n                break;\r\n            case Constants.ALWAYS:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_ALWAYS;\r\n                break;\r\n            case Constants.GREATER:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_GREATER;\r\n                break;\r\n            case Constants.GEQUAL:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_GEQUAL;\r\n                break;\r\n            case Constants.NOTEQUAL:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_NOTEQUAL;\r\n                break;\r\n            case Constants.EQUAL:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_EQUAL;\r\n                break;\r\n            case Constants.LESS:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_LESS;\r\n                break;\r\n            case Constants.LEQUAL:\r\n                nativeDepthFunc = _native.Engine.DEPTH_TEST_LEQUAL;\r\n                break;\r\n        }\r\n\r\n        this._currentDepthTest = nativeDepthFunc;\r\n        // Route through _encodeDepthTest so the tracked _depthTestEnabled state stays in\r\n        // sync with the encoded command. Because COMMAND_SETDEPTHTEST conflates the\r\n        // compare function and the enable bit (DEPTH_TEST_ALWAYS == disabled), encoding\r\n        // the new function directly here would silently re-enable depth testing while\r\n        // depth testing is logically disabled; _encodeDepthTest honors the current\r\n        // depthCullingState.depthTest and only emits the new function when enabled.\r\n        this._encodeDepthTest(this._depthCullingState.depthTest);\r\n    }\r\n\r\n    /**\r\n     * Enable or disable depth writing\r\n     * @param enable defines the state to set\r\n     */\r\n    public override setDepthWrite(enable: boolean): void {\r\n        this._depthWrite = enable;\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETDEPTHWRITE);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(Number(enable));\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    /**\r\n     * Enable or disable color writing\r\n     * @param enable defines the state to set\r\n     */\r\n    public override setColorWrite(enable: boolean): void {\r\n        this._colorWrite = enable;\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETCOLORWRITE);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(Number(enable));\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if color writing is enabled\r\n     * @returns the current color writing state\r\n     */\r\n    public override getColorWrite(): boolean {\r\n        return this._colorWrite;\r\n    }\r\n\r\n    private applyStencil(): void {\r\n        this._setStencil(\r\n            this._stencilMask,\r\n            getNativeStencilOpFail(this._stencilOpStencilFail),\r\n            getNativeStencilDepthFail(this._stencilOpDepthFail),\r\n            getNativeStencilDepthPass(this._stencilOpStencilDepthPass),\r\n            getNativeStencilFunc(this._stencilFunc),\r\n            this._stencilFuncRef\r\n        );\r\n    }\r\n\r\n    private _setStencil(mask: number, stencilOpFail: number, depthOpFail: number, depthOpPass: number, func: number, ref: number) {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETSTENCIL);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(mask);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(stencilOpFail);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(depthOpFail);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(depthOpPass);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(func);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(ref);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the stencil buffer\r\n     * @param enable defines if the stencil buffer must be enabled or disabled\r\n     */\r\n    public override setStencilBuffer(enable: boolean): void {\r\n        this._stencilTest = enable;\r\n        if (enable) {\r\n            this.applyStencil();\r\n        } else {\r\n            this._setStencil(\r\n                255,\r\n                _native.Engine.STENCIL_OP_FAIL_S_KEEP,\r\n                _native.Engine.STENCIL_OP_FAIL_Z_KEEP,\r\n                _native.Engine.STENCIL_OP_PASS_Z_KEEP,\r\n                _native.Engine.STENCIL_TEST_ALWAYS,\r\n                0\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if stencil buffer is enabled\r\n     * @returns the current stencil buffer state\r\n     */\r\n    public override getStencilBuffer(): boolean {\r\n        return this._stencilTest;\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil operation when stencil passes\r\n     * @returns a number defining stencil operation to use when stencil passes\r\n     */\r\n    public override getStencilOperationPass(): number {\r\n        return this._stencilOpStencilDepthPass;\r\n    }\r\n\r\n    /**\r\n     * Sets the stencil operation to use when stencil passes\r\n     * @param operation defines the stencil operation to use when stencil passes\r\n     */\r\n    public override setStencilOperationPass(operation: number): void {\r\n        this._stencilOpStencilDepthPass = operation;\r\n        this.applyStencil();\r\n    }\r\n\r\n    /**\r\n     * Sets the current stencil mask\r\n     * @param mask defines the new stencil mask to use\r\n     */\r\n    public override setStencilMask(mask: number): void {\r\n        this._stencilMask = mask;\r\n        this.applyStencil();\r\n    }\r\n\r\n    /**\r\n     * Sets the current stencil function\r\n     * @param stencilFunc defines the new stencil function to use\r\n     */\r\n    public override setStencilFunction(stencilFunc: number) {\r\n        this._stencilFunc = stencilFunc;\r\n        this.applyStencil();\r\n    }\r\n\r\n    /**\r\n     * Sets the current stencil reference\r\n     * @param reference defines the new stencil reference to use\r\n     */\r\n    public override setStencilFunctionReference(reference: number) {\r\n        this._stencilFuncRef = reference;\r\n        this.applyStencil();\r\n    }\r\n\r\n    /**\r\n     * Sets the current stencil mask\r\n     * @param mask defines the new stencil mask to use\r\n     */\r\n    public override setStencilFunctionMask(mask: number) {\r\n        this._stencilFuncMask = mask;\r\n    }\r\n\r\n    /**\r\n     * Sets the stencil operation to use when stencil fails\r\n     * @param operation defines the stencil operation to use when stencil fails\r\n     */\r\n    public override setStencilOperationFail(operation: number): void {\r\n        this._stencilOpStencilFail = operation;\r\n        this.applyStencil();\r\n    }\r\n\r\n    /**\r\n     * Sets the stencil operation to use when depth fails\r\n     * @param operation defines the stencil operation to use when depth fails\r\n     */\r\n    public override setStencilOperationDepthFail(operation: number): void {\r\n        this._stencilOpDepthFail = operation;\r\n        this.applyStencil();\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil mask\r\n     * @returns a number defining the new stencil mask to use\r\n     */\r\n    public override getStencilMask(): number {\r\n        return this._stencilMask;\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil function\r\n     * @returns a number defining the stencil function to use\r\n     */\r\n    public override getStencilFunction(): number {\r\n        return this._stencilFunc;\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil reference value\r\n     * @returns a number defining the stencil reference value to use\r\n     */\r\n    public override getStencilFunctionReference(): number {\r\n        return this._stencilFuncRef;\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil mask\r\n     * @returns a number defining the stencil mask to use\r\n     */\r\n    public override getStencilFunctionMask(): number {\r\n        return this._stencilFuncMask;\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil operation when stencil fails\r\n     * @returns a number defining stencil operation to use when stencil fails\r\n     */\r\n    public override getStencilOperationFail(): number {\r\n        return this._stencilOpStencilFail;\r\n    }\r\n\r\n    /**\r\n     * Gets the current stencil operation when depth fails\r\n     * @returns a number defining stencil operation to use when depth fails\r\n     */\r\n    public override getStencilOperationDepthFail(): number {\r\n        return this._stencilOpDepthFail;\r\n    }\r\n\r\n    /**\r\n     * Sets alpha constants used by some alpha blending modes\r\n     * @param r defines the red component\r\n     * @param g defines the green component\r\n     * @param b defines the blue component\r\n     * @param a defines the alpha component\r\n     */\r\n    public override setAlphaConstants(r: number, g: number, b: number, a: number) {\r\n        throw new Error(\"Setting alpha blend constant color not yet implemented.\");\r\n    }\r\n\r\n    /**\r\n     * Sets the current alpha mode\r\n     * @param mode defines the mode to use (one of the BABYLON.Constants.ALPHA_XXX)\r\n     * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)\r\n     * @param targetIndex defines the index of the target to set the alpha mode for (default is 0)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering\r\n     */\r\n    public override setAlphaMode(mode: number, noDepthWriteChange: boolean = false, targetIndex = 0): void {\r\n        if (this._alphaMode[targetIndex] === mode) {\r\n            return;\r\n        }\r\n\r\n        const nativeMode = getNativeAlphaMode(mode);\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETBLENDMODE);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(nativeMode);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n\r\n        if (!noDepthWriteChange) {\r\n            this.setDepthWrite(mode === Constants.ALPHA_DISABLE);\r\n        }\r\n\r\n        this._alphaMode[targetIndex] = mode;\r\n    }\r\n\r\n    public override setInt(uniform: WebGLUniformLocation, int: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETINT);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsInt32(int);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setIntArray(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETINTARRAY);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsInt32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setIntArray2(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETINTARRAY2);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsInt32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setIntArray3(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETINTARRAY3);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsInt32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setIntArray4(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETINTARRAY4);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsInt32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public setFloatArray(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOATARRAY);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public setFloatArray2(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOATARRAY2);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public setFloatArray3(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOATARRAY3);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public setFloatArray4(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOATARRAY4);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(array);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setArray(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        return this.setFloatArray(uniform, new Float32Array(array));\r\n    }\r\n\r\n    public override setArray2(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        return this.setFloatArray2(uniform, new Float32Array(array));\r\n    }\r\n\r\n    public override setArray3(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        return this.setFloatArray3(uniform, new Float32Array(array));\r\n    }\r\n\r\n    public override setArray4(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        return this.setFloatArray4(uniform, new Float32Array(array));\r\n    }\r\n\r\n    public override setMatrices(uniform: WebGLUniformLocation, matrices: DeepImmutable<FloatArray>): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETMATRICES);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(matrices);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n\r\n        return true;\r\n    }\r\n\r\n    public override setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETMATRIX3X3);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(matrix);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setMatrix2x2(uniform: WebGLUniformLocation, matrix: Float32Array): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETMATRIX2X2);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32s(matrix);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setFloat(uniform: WebGLUniformLocation, value: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOAT);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(value);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setFloat2(uniform: WebGLUniformLocation, x: number, y: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOAT2);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(x);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(y);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setFloat3(uniform: WebGLUniformLocation, x: number, y: number, z: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOAT3);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(x);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(y);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(z);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public override setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETFLOAT4);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform as any as NativeData);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(x);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(y);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(z);\r\n        this._commandBufferEncoder.encodeCommandArgAsFloat32(w);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n        return true;\r\n    }\r\n\r\n    public setColor3(uniform: WebGLUniformLocation, color3: IColor3Like): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this.setFloat3(uniform, color3.r, color3.g, color3.b);\r\n        return true;\r\n    }\r\n\r\n    public setColor4(uniform: WebGLUniformLocation, color3: IColor3Like, alpha: number): boolean {\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        this.setFloat4(uniform, color3.r, color3.g, color3.b, alpha);\r\n        return true;\r\n    }\r\n\r\n    public override wipeCaches(bruteForce?: boolean): void {\r\n        if (this.preventCacheWipeBetweenFrames) {\r\n            return;\r\n        }\r\n        this.resetTextureCache();\r\n        this._currentEffect = null;\r\n\r\n        if (bruteForce) {\r\n            this._currentProgram = null;\r\n\r\n            this._stencilStateComposer.reset();\r\n            this._depthCullingState.reset();\r\n            this._alphaState.reset();\r\n        }\r\n\r\n        this._cachedVertexBuffers = null;\r\n        this._cachedIndexBuffer = null;\r\n        this._cachedEffectForVertexBuffers = null;\r\n    }\r\n\r\n    protected override _createTexture(): WebGLTexture {\r\n        return this._engine.createTexture();\r\n    }\r\n\r\n    protected override _deleteTexture(texture: Nullable<WebGLHardwareTexture>): void {\r\n        if (texture) {\r\n            this._engine.deleteTexture(texture.underlyingResource as NativeTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the content of a dynamic texture\r\n     * @param texture defines the texture to update\r\n     * @param canvas defines the canvas containing the source\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param premulAlpha defines if alpha is stored as premultiplied\r\n     * @param format defines the format of the data\r\n     */\r\n    public override updateDynamicTexture(texture: Nullable<InternalTexture>, canvas: any, invertY: boolean, premulAlpha: boolean = false, format?: number): void {\r\n        if (!!texture && !!texture._hardwareTexture) {\r\n            const destination = texture._hardwareTexture.underlyingResource;\r\n            const context = canvas.getContext();\r\n            // flush need to happen before getCanvasTexture: flush will create the render target synchronously (if it's not been created before)\r\n            context.flush();\r\n            const source = canvas.getCanvasTexture();\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_COPYTEXTURE);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(source as NativeData);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(destination as NativeData);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n            texture.isReady = true;\r\n        }\r\n    }\r\n\r\n    public override createDynamicTexture(width: number, height: number, generateMipMaps: boolean, samplingMode: number): InternalTexture {\r\n        // Canvas dimensions are integral in browsers. Coerce before allocating so the native dimensions and byte length agree.\r\n        // Keep at least 1x1 because many bgfx methods assume a non-zero texture size.\r\n        width = Math.max(Math.floor(width), 1);\r\n        height = Math.max(Math.floor(height), 1);\r\n        return this.createRawTexture(new Uint8Array(width * height * 4), width, height, Constants.TEXTUREFORMAT_RGBA, false, false, samplingMode);\r\n    }\r\n\r\n    public override createVideoElement(constraints: MediaTrackConstraints): any {\r\n        // create native object depending on stream. Only NativeCamera is supported for now.\r\n        if (this._camera) {\r\n            return this._camera.createVideo(constraints);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public override updateVideoTexture(texture: Nullable<InternalTexture>, video: HTMLVideoElement, invertY: boolean): void {\r\n        if (texture && texture._hardwareTexture && this._camera) {\r\n            const webGLTexture = texture._hardwareTexture.underlyingResource;\r\n            this._camera.updateVideoTexture(webGLTexture, video, invertY);\r\n        }\r\n    }\r\n\r\n    public override createRawTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags: number = 0,\r\n        useSRGBBuffer: boolean = false\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Raw);\r\n\r\n        texture.format = format;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = texture.baseWidth;\r\n        texture.height = texture.baseHeight;\r\n        texture._compression = compression;\r\n        texture.type = type;\r\n        texture._useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, !generateMipMaps);\r\n\r\n        this.updateRawTexture(texture, data, format, invertY, compression, type, texture._useSRGBBuffer);\r\n\r\n        if (texture._hardwareTexture) {\r\n            const webGLTexture = texture._hardwareTexture.underlyingResource;\r\n            const filter = getNativeSamplingMode(samplingMode);\r\n            this._setTextureSampling(webGLTexture, filter);\r\n        }\r\n\r\n        this._internalTexturesCache.push(texture);\r\n        return texture;\r\n    }\r\n\r\n    public override createRawTexture2DArray(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Raw2DArray);\r\n\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.baseDepth = depth;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.depth = depth;\r\n        texture.format = format;\r\n        texture.type = textureType;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.is2DArray = true;\r\n\r\n        if (texture._hardwareTexture) {\r\n            const nativeTexture = texture._hardwareTexture.underlyingResource;\r\n            this._engine.loadRawTexture2DArray(nativeTexture, data, width, height, depth, getNativeTextureFormat(format, textureType), generateMipMaps, invertY);\r\n\r\n            const filter = getNativeSamplingMode(samplingMode);\r\n            this._setTextureSampling(nativeTexture, filter);\r\n        }\r\n\r\n        texture.isReady = true;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n        return texture;\r\n    }\r\n\r\n    public override updateRawTexture(\r\n        texture: Nullable<InternalTexture>,\r\n        bufferView: Nullable<ArrayBufferView>,\r\n        format: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        useSRGBBuffer: boolean = false\r\n    ): void {\r\n        if (!texture) {\r\n            return;\r\n        }\r\n\r\n        if (bufferView && texture._hardwareTexture) {\r\n            const underlyingResource = texture._hardwareTexture.underlyingResource;\r\n            this._engine.loadRawTexture(\r\n                underlyingResource,\r\n                bufferView,\r\n                texture.width,\r\n                texture.height,\r\n                getNativeTextureFormat(format, type),\r\n                texture.generateMipMaps,\r\n                texture.invertY\r\n            );\r\n        }\r\n\r\n        texture.isReady = true;\r\n    }\r\n\r\n    // TODO: Refactor to share more logic with babylon.engine.ts version.\r\n    /**\r\n     * Usually called from Texture.ts.\r\n     * Passed information to create a NativeTexture\r\n     * @param url defines a value which contains one of the following:\r\n     * * A conventional http URL, e.g. 'http://...' or 'file://...'\r\n     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'\r\n     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'\r\n     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file\r\n     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)\r\n     * @param scene needed for loading to the correct scene\r\n     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)\r\n     * @param onLoad optional callback to be called upon successful completion\r\n     * @param onError optional callback to be called upon failure\r\n     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob\r\n     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities\r\n     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @param mimeType defines an optional mime type\r\n     * @param loaderOptions options to be passed to the loader\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns a InternalTexture for assignment back into BABYLON.Texture\r\n     */\r\n    public override createTexture(\r\n        url: Nullable<string>,\r\n        noMipmap: boolean,\r\n        invertY: boolean,\r\n        scene: Nullable<ISceneLike>,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<(texture: InternalTexture) => void> = null,\r\n        onError: Nullable<(message: string, exception: any) => void> = null,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        format: Nullable<number> = null,\r\n        forcedExtension: Nullable<string> = null,\r\n        mimeType?: string,\r\n        loaderOptions?: any,\r\n        creationFlags?: number,\r\n        useSRGBBuffer = false\r\n    ): InternalTexture {\r\n        url = url || \"\";\r\n        const fromData = url.substring(0, 5) === \"data:\";\r\n        //const fromBlob = url.substring(0, 5) === \"blob:\";\r\n        const isBase64 = fromData && url.indexOf(\";base64,\") !== -1;\r\n\r\n        const texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Url);\r\n\r\n        const originalUrl = url;\r\n        if (this._transformTextureUrl && !isBase64 && !fallback && !buffer) {\r\n            url = this._transformTextureUrl(url);\r\n        }\r\n\r\n        // establish the file extension, if possible\r\n        const lastDot = url.lastIndexOf(\".\");\r\n        const extension = forcedExtension ? forcedExtension : lastDot > -1 ? url.substring(lastDot).toLowerCase() : \"\";\r\n\r\n        // some formats are already supported by bimg, no need to try to load them with JS\r\n        // leaving TextureLoader extension check for future use\r\n        let loaderPromise = null;\r\n        if (extension.endsWith(\".basis\") || extension.endsWith(\".ktx\") || extension.endsWith(\".ktx2\") || mimeType === \"image/ktx\" || mimeType === \"image/ktx2\") {\r\n            loaderPromise = AbstractEngine.GetCompatibleTextureLoader(extension);\r\n        }\r\n\r\n        if (scene) {\r\n            scene.addPendingData(texture);\r\n        }\r\n        texture.url = url;\r\n        texture.generateMipMaps = !noMipmap;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture._useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, noMipmap);\r\n\r\n        if (!this.doNotHandleContextLost) {\r\n            // Keep a link to the buffer only if we plan to handle context lost\r\n            texture._buffer = buffer;\r\n        }\r\n\r\n        let onLoadObserver: Nullable<Observer<InternalTexture>> = null;\r\n        if (onLoad && !fallback) {\r\n            onLoadObserver = texture.onLoadedObservable.add(onLoad);\r\n        }\r\n\r\n        if (!fallback) {\r\n            this._internalTexturesCache.push(texture);\r\n        }\r\n\r\n        const onInternalError = (message?: string, exception?: any) => {\r\n            if (scene) {\r\n                scene.removePendingData(texture);\r\n            }\r\n\r\n            if (url === originalUrl) {\r\n                if (onLoadObserver) {\r\n                    texture.onLoadedObservable.remove(onLoadObserver);\r\n                }\r\n\r\n                if (EngineStore.UseFallbackTexture) {\r\n                    this.createTexture(EngineStore.FallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);\r\n                }\r\n\r\n                if (onError) {\r\n                    onError((message || \"Unknown error\") + (EngineStore.UseFallbackTexture ? \" - Fallback texture was used\" : \"\"), exception);\r\n                }\r\n            } else {\r\n                // fall back to the original url if the transformed url fails to load\r\n                Logger.Warn(`Failed to load ${url}, falling back to ${originalUrl}`);\r\n                this.createTexture(originalUrl, noMipmap, texture.invertY, scene, samplingMode, onLoad, onError, buffer, texture, format, forcedExtension, mimeType, loaderOptions);\r\n            }\r\n        };\r\n\r\n        // processing for non-image formats\r\n        if (loaderPromise) {\r\n            throw new Error(\"Loading textures from IInternalTextureLoader not yet implemented.\");\r\n        } else {\r\n            const onload = (data: ArrayBufferView) => {\r\n                if (!texture._hardwareTexture) {\r\n                    if (scene) {\r\n                        scene.removePendingData(texture);\r\n                    }\r\n\r\n                    return;\r\n                }\r\n\r\n                const underlyingResource = texture._hardwareTexture.underlyingResource;\r\n\r\n                this._engine.loadTexture(\r\n                    underlyingResource,\r\n                    data,\r\n                    !noMipmap,\r\n                    invertY,\r\n                    texture._useSRGBBuffer,\r\n                    () => {\r\n                        texture.baseWidth = this._engine.getTextureWidth(underlyingResource);\r\n                        texture.baseHeight = this._engine.getTextureHeight(underlyingResource);\r\n                        texture.width = texture.baseWidth;\r\n                        texture.height = texture.baseHeight;\r\n                        texture.isReady = true;\r\n\r\n                        const filter = getNativeSamplingMode(samplingMode);\r\n                        this._setTextureSampling(underlyingResource, filter);\r\n\r\n                        if (scene) {\r\n                            scene.removePendingData(texture);\r\n                        }\r\n\r\n                        texture.onLoadedObservable.notifyObservers(texture);\r\n                        texture.onLoadedObservable.clear();\r\n                    },\r\n                    () => {\r\n                        throw new Error(\"Could not load a native texture.\");\r\n                    }\r\n                );\r\n            };\r\n\r\n            if (fromData && buffer) {\r\n                if (buffer instanceof ArrayBuffer) {\r\n                    onload(new Uint8Array(buffer));\r\n                } else if (ArrayBuffer.isView(buffer)) {\r\n                    onload(buffer);\r\n                } else if (typeof buffer === \"string\") {\r\n                    onload(new Uint8Array(DecodeBase64UrlToBinary(buffer)));\r\n                } else {\r\n                    throw new Error(\"Unsupported buffer type\");\r\n                }\r\n            } else {\r\n                if (isBase64) {\r\n                    onload(new Uint8Array(DecodeBase64UrlToBinary(url)));\r\n                } else {\r\n                    this._loadFile(\r\n                        url,\r\n                        (data) => onload(new Uint8Array(data as ArrayBuffer)),\r\n                        undefined,\r\n                        undefined,\r\n                        true,\r\n                        (request?: IWebRequest, exception?: any) => {\r\n                            onInternalError(\"Unable to load \" + (request ? request.responseURL : url, exception));\r\n                        }\r\n                    );\r\n                }\r\n            }\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Wraps an external native texture in a Babylon texture.\r\n     * @param texture defines the external texture\r\n     * @param hasMipMaps defines whether the external texture has mip maps\r\n     * @param samplingMode defines the sampling mode for the external texture (default: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE)\r\n     * @returns the babylon internal texture\r\n     */\r\n    public wrapNativeTexture(texture: NativeTexture, hasMipMaps: boolean = false, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE): InternalTexture {\r\n        const hardwareTexture = new NativeHardwareTexture(texture, this._engine);\r\n        const internalTexture = new InternalTexture(this, InternalTextureSource.External, true);\r\n        internalTexture._hardwareTexture = hardwareTexture;\r\n        internalTexture.baseWidth = this._engine.getTextureWidth(texture);\r\n        internalTexture.baseHeight = this._engine.getTextureHeight(texture);\r\n        internalTexture.width = internalTexture.baseWidth;\r\n        internalTexture.height = internalTexture.baseHeight;\r\n        if (this._engine.getTextureLayerCount) {\r\n            const layerCount = this._engine.getTextureLayerCount(texture);\r\n            if (layerCount > 1) {\r\n                internalTexture.is2DArray = true;\r\n                internalTexture.baseDepth = internalTexture.depth = layerCount;\r\n            }\r\n        }\r\n        internalTexture.isReady = true;\r\n        internalTexture.useMipMaps = hasMipMaps;\r\n        this.updateTextureSamplingMode(samplingMode, internalTexture);\r\n        return internalTexture;\r\n    }\r\n\r\n    /**\r\n     * Replaces the underlying native texture handle of a texture previously created via {@link wrapNativeTexture},\r\n     * preserving the InternalTexture identity.\r\n     *\r\n     * Intended for the device-loss / device-restored flow (a DisableRendering / EnableRendering cycle from the host\r\n     * application): when the host recreates its external resource on the new graphics device, it calls this method to\r\n     * repoint Babylon's wrapper at the new handle without losing references held by materials, render-target wrappers,\r\n     * particle systems, etc.\r\n     *\r\n     * The new handle must match the wrapped texture's recorded dimensions. To change dimensions, dispose the wrapped\r\n     * texture and call {@link wrapNativeTexture} again. Sampling mode and mip-map flag are properties of the logical\r\n     * wrapped texture and are re-applied to the new resource. Any render-target wrapper holding this texture as its\r\n     * color attachment has its framebuffer rebuilt with the new handle.\r\n     *\r\n     * Throws if the target was not produced by {@link wrapNativeTexture}, if the new handle's dimensions don't match,\r\n     * if the wrapped texture is part of a multi render-target, or if the wrapper has a depth/stencil texture (these\r\n     * are not supported in this version; dispose and re-wrap).\r\n     * @param internalTexture defines the wrapped InternalTexture to repoint\r\n     * @param texture defines the new native texture handle to wrap\r\n     */\r\n    public updateWrappedNativeTexture(internalTexture: InternalTexture, texture: NativeTexture): void {\r\n        if (internalTexture.source !== InternalTextureSource.External) {\r\n            throw new Error(\"updateWrappedNativeTexture: target InternalTexture was not produced by wrapNativeTexture.\");\r\n        }\r\n\r\n        const newWidth = this._engine.getTextureWidth(texture);\r\n        const newHeight = this._engine.getTextureHeight(texture);\r\n        if (newWidth !== internalTexture.baseWidth || newHeight !== internalTexture.baseHeight) {\r\n            throw new Error(\r\n                `updateWrappedNativeTexture: new handle dimensions (${newWidth}x${newHeight}) must match the wrapped texture's dimensions (${internalTexture.baseWidth}x${internalTexture.baseHeight}).`\r\n            );\r\n        }\r\n        if (this._engine.getTextureLayerCount) {\r\n            const newLayerCount = this._engine.getTextureLayerCount(texture);\r\n            const oldLayerCount = internalTexture.is2DArray ? internalTexture.depth : 1;\r\n            if (newLayerCount !== oldLayerCount) {\r\n                throw new Error(`updateWrappedNativeTexture: new handle layer count (${newLayerCount}) must match the wrapped texture's layer count (${oldLayerCount}).`);\r\n            }\r\n        }\r\n\r\n        // Pre-validate before mutating any state so a thrown precondition leaves the InternalTexture untouched.\r\n        // Note: rtWrapper.texture only returns _textures[0]; walk every attachment to catch the multi-RT case where\r\n        // the wrapped texture is at index > 0.\r\n        for (const rtWrapper of this._renderTargetWrapperCache) {\r\n            if (!rtWrapper.textures?.includes(internalTexture)) {\r\n                continue;\r\n            }\r\n            if (rtWrapper.isMulti) {\r\n                throw new Error(\"updateWrappedNativeTexture: wrapped texture is part of a multi render-target; not supported. Dispose and re-wrap.\");\r\n            }\r\n            if (rtWrapper._depthStencilTexture) {\r\n                // After a DisableRendering / EnableRendering cycle the bgfx framebuffer + the depth/stencil texture's\r\n                // bgfx handle are both stale. Rebuilding the depth/stencil texture from the wrapper's stored settings\r\n                // is feasible but non-trivial; v1 rejects and asks the caller to dispose + re-wrap.\r\n                throw new Error(\"updateWrappedNativeTexture: wrapped texture's render-target wrapper has a depth/stencil texture; not supported. Dispose and re-wrap.\");\r\n            }\r\n        }\r\n\r\n        internalTexture._hardwareTexture = new NativeHardwareTexture(texture, this._engine);\r\n        internalTexture.isReady = true;\r\n        this.updateTextureSamplingMode(internalTexture.samplingMode, internalTexture);\r\n\r\n        // Rebuild the framebuffer of any render-target wrapper holding this wrapped texture as its color attachment.\r\n        // After a DisableRendering / EnableRendering cycle the bgfx framebuffer handle is stale; the consumer-supplied\r\n        // new texture is the moment we have a fresh handle to rebuild against.\r\n        for (const rtWrapper of this._renderTargetWrapperCache) {\r\n            if (rtWrapper.texture !== internalTexture) {\r\n                continue;\r\n            }\r\n            const nativeRTWrapper = rtWrapper as NativeRenderTargetWrapper;\r\n            // NativeRenderTargetWrapper._framebuffer setter releases the old framebuffer before assigning,\r\n            // so no manual _releaseFramebufferObjects call is needed (and would double-delete the handle).\r\n            nativeRTWrapper._framebuffer = this._engine.createFrameBuffer(\r\n                texture,\r\n                rtWrapper.width,\r\n                rtWrapper.height,\r\n                rtWrapper._generateStencilBuffer,\r\n                rtWrapper._generateDepthBuffer,\r\n                rtWrapper.samples ?? 1\r\n            );\r\n        }\r\n    }\r\n\r\n    public override _createDepthStencilTexture(size: TextureSize, options: DepthTextureCreationOptions, rtWrapper: RenderTargetWrapper): InternalTexture {\r\n        // TODO: handle other options?\r\n        const generateStencil = options.generateStencil || false;\r\n        const samples = options.samples || 1;\r\n\r\n        const nativeRTWrapper = rtWrapper as NativeRenderTargetWrapper;\r\n        const texture = new InternalTexture(this, InternalTextureSource.DepthStencil);\r\n\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>size).layers || 0;\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>size).depth || 0;\r\n\r\n        // Populate the standard depth/stencil texture metadata, mirroring ThinEngine._setupDepthStencilTexture.\r\n        // In particular `samples` must be set so consumers such as the FrameGraph texture manager report the\r\n        // correct sample count; leaving it at the InternalTexture default (0) breaks FrameGraph MSAA\r\n        // depth/output sample-count validation. `is2DArray`/`depth` matter for the texture-array depth targets\r\n        // used by cascaded shadow maps.\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.is2DArray = layers > 0;\r\n        texture.depth = layers || depth;\r\n        texture.isReady = true;\r\n        texture.samples = samples;\r\n        texture.generateMipMaps = false;\r\n        texture.samplingMode = options.bilinearFiltering ? Constants.TEXTURE_BILINEAR_SAMPLINGMODE : Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        texture._comparisonFunction = options.comparisonFunction ?? 0;\r\n\r\n        const framebuffer = this._engine.createFrameBuffer(texture._hardwareTexture!.underlyingResource, width, height, generateStencil, true, samples);\r\n        nativeRTWrapper._framebufferDepthStencil = framebuffer;\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseFramebufferObjects(framebuffer: Nullable<NativeFramebuffer>): void {\r\n        if (framebuffer) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DELETEFRAMEBUFFER);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(framebuffer);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal Engine abstraction for loading and creating an image bitmap from a given source string.\r\n     * @param imageSource source to load the image from.\r\n     * @param _options An object that sets options for the image's extraction.\r\n     * @returns ImageBitmap\r\n     */\r\n    public override async _createImageBitmapFromSource(imageSource: string, _options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n        const promise = new Promise<ImageBitmap>((resolve, reject) => {\r\n            const image = this.createCanvasImage();\r\n            image.onload = () => {\r\n                try {\r\n                    const imageBitmap = this._engine.createImageBitmap(image);\r\n                    resolve(imageBitmap);\r\n                } catch (error) {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(`Error loading image ${image.src} with exception: ${error}`);\r\n                }\r\n            };\r\n            image.onerror = (error) => {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                reject(`Error loading image ${image.src} with exception: ${error}`);\r\n            };\r\n\r\n            image.src = imageSource;\r\n        });\r\n\r\n        return await promise;\r\n    }\r\n\r\n    /**\r\n     * Engine abstraction for createImageBitmap\r\n     * @param image source for image\r\n     * @param options An object that sets options for the image's extraction.\r\n     * @returns ImageBitmap\r\n     */\r\n    public override async createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n        // Back-compat: Because of the previous Blob hack, this could be an array of BlobParts.\r\n        if (Array.isArray(image)) {\r\n            const arr = <Array<ArrayBuffer>>image;\r\n            if (arr.length) {\r\n                return this._engine.createImageBitmap(arr[0]);\r\n            }\r\n        }\r\n\r\n        if (image instanceof Blob) {\r\n            const data = await image.arrayBuffer();\r\n            return this._engine.createImageBitmap(data);\r\n        }\r\n\r\n        throw new Error(\"Unsupported data for createImageBitmap.\");\r\n    }\r\n\r\n    /**\r\n     * Resize an image and returns the image data as an uint8array\r\n     * @param image image to resize\r\n     * @param bufferWidth destination buffer width\r\n     * @param bufferHeight destination buffer height\r\n     * @returns an uint8array containing RGBA values of bufferWidth * bufferHeight size\r\n     */\r\n    public override resizeImageBitmap(image: ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n        return this._engine.resizeImageBitmap(image, bufferWidth, bufferHeight);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _createHardwareTexture(): IHardwareTextureWrapper {\r\n        return new NativeHardwareTexture(this._createTexture() as NativeTexture, this._engine);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _createHardwareRenderTargetWrapper(isMulti: boolean, isCube: boolean, size: TextureSize): RenderTargetWrapper {\r\n        const rtWrapper = new NativeRenderTargetWrapper(isMulti, isCube, size, this);\r\n        this._renderTargetWrapperCache.push(rtWrapper);\r\n        return rtWrapper;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _createInternalTexture(\r\n        size: TextureSize,\r\n        options: boolean | InternalTextureCreationOptions,\r\n        _delayGPUTextureCreation = true,\r\n        source = InternalTextureSource.Unknown\r\n    ): InternalTexture {\r\n        let generateMipMaps: boolean;\r\n        let type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        let samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n        let format = Constants.TEXTUREFORMAT_RGBA;\r\n        let useSRGBBuffer = false;\r\n        let samples = 1;\r\n        let label: string | undefined;\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            generateMipMaps = !!options.generateMipMaps;\r\n            type = options.type === undefined ? Constants.TEXTURETYPE_UNSIGNED_BYTE : options.type;\r\n            samplingMode = options.samplingMode === undefined ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;\r\n            format = options.format === undefined ? Constants.TEXTUREFORMAT_RGBA : options.format;\r\n            useSRGBBuffer = options.useSRGBBuffer === undefined ? false : options.useSRGBBuffer;\r\n            samples = options.samples ?? 1;\r\n            label = options.label;\r\n        } else {\r\n            generateMipMaps = !!options;\r\n        }\r\n\r\n        useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, !generateMipMaps);\r\n\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n            type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            Logger.Warn(\"Float textures are not supported. Type forced to TEXTURETYPE_UNSIGNED_BYTE\");\r\n        }\r\n\r\n        const texture = new InternalTexture(this, source);\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n\r\n        const layers = (<{ width: number; height: number; layers?: number }>size).layers || 0;\r\n        if (layers !== 0) {\r\n            throw new Error(\"Texture layers are not supported in Babylon Native\");\r\n        }\r\n\r\n        const nativeTexture = texture._hardwareTexture!.underlyingResource;\r\n        const nativeTextureFormat = getNativeTextureFormat(format, type);\r\n        // TODO(bgfx-msaa-mips): stopgap workaround for a bgfx bug -- D3D11/D3D12/Vulkan backends share one\r\n        // texture descriptor between the MSAA render target and the non-MSAA resolve target, so requesting\r\n        // both mips > 1 and samples > 1 makes the API (D3D11 E_INVALIDARG, Vulkan VUID-02257, ...) reject the\r\n        // MSAA texture creation. Force hasMips = false here to keep the combo from reaching bgfx. The fix\r\n        // belongs in bgfx (separate descs per target, like OpenGL/WebGL do with a non-mipped renderbuffer);\r\n        // this guard should be removed once a fixed bgfx ships in a stable BabylonNative npm release. Tracked\r\n        // in BabylonNative#1714. Cost: MSAA RTs on Native lose post-resolve auto-mipgen and diverge from\r\n        // WebGL/WebGPU semantics -- texture.generateMipMaps stays true on the InternalTexture but the\r\n        // underlying bgfx resource has 1 mip.\r\n        const hasMips = samples > 1 ? false : generateMipMaps;\r\n        // REVIEW: We are always setting the renderTarget flag as we don't know whether the texture will be used as a render target.\r\n        this._engine.initializeTexture(nativeTexture, width, height, hasMips, nativeTextureFormat, true, useSRGBBuffer, samples);\r\n        this._setTextureSampling(nativeTexture, getNativeSamplingMode(samplingMode));\r\n\r\n        texture._useSRGBBuffer = useSRGBBuffer;\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.depth = layers;\r\n        texture.isReady = true;\r\n        texture.samples = samples;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.type = type;\r\n        texture.format = format;\r\n        texture.label = label;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    }\r\n\r\n    public override createRenderTargetTexture(\r\n        size: number | { width: number; height: number; depth: number },\r\n        options: boolean | RenderTargetCreationOptions\r\n    ): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, false, size) as NativeRenderTargetWrapper;\r\n\r\n        let generateDepthBuffer = true;\r\n        let generateStencilBuffer = false;\r\n        let noColorAttachment = false;\r\n        let colorAttachment: InternalTexture | undefined = undefined;\r\n        let samples = 1;\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n            generateStencilBuffer = !!options.generateStencilBuffer;\r\n            noColorAttachment = !!options.noColorAttachment;\r\n            colorAttachment = options.colorAttachment;\r\n            samples = options.samples ?? 1;\r\n        }\r\n\r\n        const texture = colorAttachment || (noColorAttachment ? null : this._createInternalTexture(size, options, true, InternalTextureSource.RenderTarget));\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n\r\n        const framebuffer = this._engine.createFrameBuffer(\r\n            texture ? texture._hardwareTexture!.underlyingResource : null,\r\n            width,\r\n            height,\r\n            generateStencilBuffer,\r\n            generateDepthBuffer,\r\n            samples\r\n        );\r\n\r\n        rtWrapper._framebuffer = framebuffer;\r\n        rtWrapper._generateDepthBuffer = generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = generateStencilBuffer;\r\n        rtWrapper._samples = samples;\r\n\r\n        rtWrapper.setTextures(texture);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    public override createRenderTargetCubeTexture(size: number, options?: RenderTargetCreationOptions): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, true, size) as NativeRenderTargetWrapper;\r\n\r\n        let generateDepthBuffer = true;\r\n        let generateStencilBuffer = false;\r\n        let generateMipMaps = false;\r\n        let type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        let samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n        let format = Constants.TEXTUREFORMAT_RGBA;\r\n        let samples = 1;\r\n        let label: string | undefined;\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n            generateStencilBuffer = !!options.generateStencilBuffer;\r\n            generateMipMaps = !!options.generateMipMaps;\r\n            type = options.type ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            samplingMode = options.samplingMode ?? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n            format = options.format ?? Constants.TEXTUREFORMAT_RGBA;\r\n            samples = options.samples ?? 1;\r\n            label = options.label;\r\n        }\r\n\r\n        // Match _createInternalTexture: float/half-float RTTs that the platform can't linearly filter fall\r\n        // back to NEAREST so the cube RTT never carries an unsupported sampling mode.\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n            type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            Logger.Warn(\"Float textures are not supported. Type forced to TEXTURETYPE_UNSIGNED_BYTE\");\r\n        }\r\n\r\n        const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);\r\n        texture.isCube = true;\r\n        texture.baseWidth = size;\r\n        texture.baseHeight = size;\r\n        texture.width = size;\r\n        texture.height = size;\r\n        texture.isReady = true;\r\n        texture.samples = samples;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.type = type;\r\n        texture.format = format;\r\n        texture.label = label;\r\n\r\n        const nativeTexture = texture._hardwareTexture!.underlyingResource;\r\n        const nativeTextureFormat = getNativeTextureFormat(format, type);\r\n        // See the createRenderTargetTexture MSAA/mips note: avoid the mips + samples combo on bgfx.\r\n        const hasMips = samples > 1 ? false : generateMipMaps;\r\n        this._engine.initializeTexture(nativeTexture, size, size, hasMips, nativeTextureFormat, /*renderTarget*/ true, /*srgb*/ false, samples, /*isCube*/ true);\r\n        this._setTextureSampling(nativeTexture, getNativeSamplingMode(samplingMode));\r\n\r\n        // The native engine cannot render to all six faces through one framebuffer, so create one\r\n        // framebuffer per face (the C++ side binds the matching cube layer); bindFramebuffer(faceIndex)\r\n        // then selects the right one.\r\n        const framebuffers: NativeFramebuffer[] = [];\r\n        for (let face = 0; face < 6; face++) {\r\n            framebuffers.push(this._engine.createFrameBuffer(nativeTexture, size, size, generateStencilBuffer, generateDepthBuffer, samples, face));\r\n        }\r\n\r\n        rtWrapper._framebuffers = framebuffers;\r\n        rtWrapper._generateDepthBuffer = generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = generateStencilBuffer;\r\n        rtWrapper._samples = samples;\r\n\r\n        rtWrapper.setTextures(texture);\r\n\r\n        // Track the hand-built cube RTT texture the same way _createInternalTexture tracks 2D textures so it\r\n        // participates in engine-wide lifecycle management (dispose iteration, context rebuild, stats).\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    public override createMultipleRenderTarget(size: TextureSize, options: IMultiRenderTargetOptions, _initializeBuffers = true): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(true, false, size) as NativeRenderTargetWrapper;\r\n\r\n        let generateMipMaps = false;\r\n        let generateDepthBuffer = true;\r\n        let generateStencilBuffer = false;\r\n        let generateDepthTexture = false;\r\n        let textureCount = 1;\r\n        let samples = 1;\r\n        let types: number[] = [];\r\n        let samplingModes: number[] = [];\r\n        let formats: number[] = [];\r\n        let targets: number[] = [];\r\n        let faceIndex: number[] = [];\r\n        let layerIndex: number[] = [];\r\n        let labels: string[] = [];\r\n        let dontCreateTextures = false;\r\n\r\n        if (options !== undefined) {\r\n            generateMipMaps = options.generateMipMaps ?? false;\r\n            generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n            generateStencilBuffer = options.generateStencilBuffer ?? false;\r\n            generateDepthTexture = options.generateDepthTexture ?? false;\r\n            textureCount = options.textureCount ?? 1;\r\n            samples = options.samples ?? 1;\r\n            types = options.types || types;\r\n            samplingModes = options.samplingModes || samplingModes;\r\n            formats = options.formats || formats;\r\n            targets = options.targetTypes || targets;\r\n            faceIndex = options.faceIndex || faceIndex;\r\n            layerIndex = options.layerIndex || layerIndex;\r\n            labels = options.labels || labels;\r\n            dontCreateTextures = options.dontCreateTextures ?? false;\r\n        }\r\n\r\n        rtWrapper.label = options?.label ?? \"MultiRenderTargetWrapper\";\r\n\r\n        const width = (<{ width: number; height: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number }>size).height ?? <number>size;\r\n\r\n        const textures: InternalTexture[] = [];\r\n        const attachments: number[] = [];\r\n\r\n        for (let i = 0; i < textureCount; i++) {\r\n            const samplingMode = samplingModes[i] || Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n            let type = types[i] || Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            const format = formats[i] || Constants.TEXTUREFORMAT_RGBA;\r\n            const target = targets[i] || Constants.TEXTURE_2D;\r\n\r\n            attachments.push(i);\r\n\r\n            // target === -1 marks an attachment with no engine-created texture; dontCreateTextures defers them.\r\n            if (target === -1 || dontCreateTextures) {\r\n                continue;\r\n            }\r\n\r\n            if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n                type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                Logger.Warn(\"Float textures are not supported. Multi render target attachment forced to TEXTURETYPE_UNSIGNED_BYTE type\");\r\n            }\r\n\r\n            const texture = new InternalTexture(this, InternalTextureSource.MultiRenderTarget);\r\n            const nativeTexture = texture._hardwareTexture!.underlyingResource;\r\n            if (target !== Constants.TEXTURE_2D) {\r\n                // Native multi render targets currently only attach 2D color textures; cube / 2D-array\r\n                // attachments are created as 2D so the attachment still exists and mrt.textures[i] is populated.\r\n                Logger.Warn(\"Multi render target attachment target \" + target + \" is not supported on Native; using a 2D texture.\");\r\n            }\r\n            // bgfx auto-generates the mip chain on resolve; avoid the mips + MSAA combo (see createRenderTargetTexture).\r\n            const hasMips = samples > 1 ? false : generateMipMaps;\r\n            this._engine.initializeTexture(nativeTexture, width, height, hasMips, getNativeTextureFormat(format, type), /*renderTarget*/ true, /*srgb*/ false, samples);\r\n            this._setTextureSampling(nativeTexture, getNativeSamplingMode(samplingMode));\r\n\r\n            texture.baseWidth = width;\r\n            texture.baseHeight = height;\r\n            texture.width = width;\r\n            texture.height = height;\r\n            texture.isReady = true;\r\n            texture.samples = samples;\r\n            texture.generateMipMaps = generateMipMaps;\r\n            texture.samplingMode = samplingMode;\r\n            texture.type = type;\r\n            texture.format = format;\r\n            texture.label = labels[i] ?? rtWrapper.label + \"-Texture\" + i;\r\n\r\n            textures[i] = texture;\r\n            this._internalTexturesCache.push(texture);\r\n        }\r\n\r\n        rtWrapper._generateDepthBuffer = generateDepthBuffer || generateDepthTexture;\r\n        rtWrapper._generateStencilBuffer = generateStencilBuffer;\r\n        rtWrapper._samples = samples;\r\n        rtWrapper._attachments = attachments;\r\n\r\n        rtWrapper.setTextures(textures);\r\n        rtWrapper.setLayerAndFaceIndices(layerIndex, faceIndex);\r\n\r\n        // The native engine creates one framebuffer with all the color attachments (bgfx writes to every\r\n        // attachment of the bound framebuffer, so there is no drawBuffers equivalent to issue per draw).\r\n        this._createMultiRenderTargetFramebuffer(rtWrapper);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    /**\r\n     * Creates (or recreates) the native framebuffer of a multi render target from the color attachment\r\n     * textures currently held by the wrapper. bgfx binds a fixed attachment set when a framebuffer is\r\n     * created and cannot re-point an individual attachment the way GL's framebufferTexture2D can, so the\r\n     * whole framebuffer has to be recreated whenever an attachment is swapped after creation (e.g. the OIT\r\n     * depth-peeling renderer replaces every attachment via MultiRenderTarget.setInternalTexture).\r\n     * @param rtWrapper The multi render target wrapper to build the framebuffer for.\r\n     * @internal\r\n     */\r\n    public _createMultiRenderTargetFramebuffer(rtWrapper: NativeRenderTargetWrapper): void {\r\n        const textures = rtWrapper.textures;\r\n        if (!textures) {\r\n            return;\r\n        }\r\n\r\n        const colorHandles: NativeTexture[] = [];\r\n        for (const texture of textures) {\r\n            const handle = texture?._hardwareTexture?.underlyingResource;\r\n            if (handle) {\r\n                colorHandles.push(handle);\r\n            }\r\n        }\r\n\r\n        // bgfx framebuffers use a dense, ordered attachment list, so only (re)build once every expected color\r\n        // attachment is present. Building from a partial set (e.g. attachments deferred via dontCreateTextures /\r\n        // targetTypes[i] === -1, or filled out of order) would compress the attachment indices -- attachment 2\r\n        // would become attachment 1, etc. -- and produce a framebuffer that does not match the MRT layout. The\r\n        // count match guarantees the collected handles are contiguous and in attachment order.\r\n        const expectedCount = rtWrapper._attachments ? rtWrapper._attachments.length : colorHandles.length;\r\n        if (colorHandles.length === 0 || colorHandles.length !== expectedCount) {\r\n            return;\r\n        }\r\n\r\n        const width = rtWrapper.width;\r\n        const height = rtWrapper.height;\r\n\r\n        if (this._engine.createMultiFrameBuffer) {\r\n            rtWrapper._framebuffer = this._engine.createMultiFrameBuffer(\r\n                colorHandles,\r\n                width,\r\n                height,\r\n                rtWrapper._generateStencilBuffer,\r\n                rtWrapper._generateDepthBuffer,\r\n                rtWrapper._samples\r\n            );\r\n        } else {\r\n            // Older Babylon Native binaries (predating multi render target support) do not expose createMultiFrameBuffer.\r\n            // Fall back to a single-attachment framebuffer bound to the first color target so the scene keeps rendering.\r\n            // Warn once (limit 1): the framebuffer can be rebuilt many times during attachment setup/swaps.\r\n            Logger.Warn(\r\n                \"createMultiFrameBuffer is not supported by this version of Babylon Native; multi render targets are unavailable. Falling back to a single-attachment framebuffer bound to the first color target.\",\r\n                1\r\n            );\r\n            rtWrapper._framebuffer = this._engine.createFrameBuffer(\r\n                colorHandles[0],\r\n                width,\r\n                height,\r\n                rtWrapper._generateStencilBuffer,\r\n                rtWrapper._generateDepthBuffer,\r\n                rtWrapper._samples\r\n            );\r\n        }\r\n    }\r\n\r\n    public override generateMipMapsForCubemap(_texture: InternalTexture, _unbind = true): void {\r\n        // The WebGL path rebinds gl.TEXTURE_CUBE_MAP and calls gl.generateMipmap; both deref _gl, which is\r\n        // null on Native. bgfx auto-generates the mip chain when a render target texture created with mips is\r\n        // resolved (the same way 2D RTTs get their mips here -- unBindFramebuffer issues no explicit mipgen),\r\n        // so this is a no-op on Native.\r\n    }\r\n\r\n    public override bindAttachments(_attachments: number[]): void {\r\n        // No-op on Native: bgfx renders to every color attachment of the bound framebuffer, so there is\r\n        // no gl.drawBuffers equivalent to select a subset.\r\n    }\r\n\r\n    public override clearAttachments(\r\n        color: Nullable<IColor4Like>,\r\n        attachments: number[],\r\n        clearColor: boolean,\r\n        clearDepth: boolean,\r\n        clearStencil = false,\r\n        stencilClearValue = 0\r\n    ): void {\r\n        this.bindAttachments(attachments);\r\n        this.clear(color, clearColor, clearDepth, clearStencil, stencilClearValue);\r\n    }\r\n\r\n    public override buildTextureLayout(textureStatus: boolean[], _backBufferLayout = false): number[] {\r\n        // Native has no gl draw-buffer enums; return a per-attachment index list (consumers only use the\r\n        // length/order, and bindAttachments is a no-op).\r\n        const result: number[] = [];\r\n        for (let i = 0; i < textureStatus.length; i++) {\r\n            result.push(textureStatus[i] ? i : -1);\r\n        }\r\n        return result;\r\n    }\r\n\r\n    public override restoreSingleAttachment(): void {\r\n        // No-op on Native (see bindAttachments).\r\n    }\r\n\r\n    public override restoreSingleAttachmentForRenderTarget(): void {\r\n        // No-op on Native (see bindAttachments).\r\n    }\r\n\r\n    public override generateMipMapsMultiFramebuffer(_texture: RenderTargetWrapper): void {\r\n        // No-op on Native: bgfx auto-generates mips on render-target resolve (as for 2D/cube RTTs).\r\n    }\r\n\r\n    public override resolveMultiFramebuffer(_texture: RenderTargetWrapper): void {\r\n        // No-op on Native: bgfx resolves MSAA render targets automatically.\r\n    }\r\n\r\n    public override unBindMultiColorAttachmentFramebuffer(_rtWrapper: RenderTargetWrapper, _disableGenerateMipMaps = false, onBeforeUnbind?: () => void): void {\r\n        this._currentRenderTarget = null;\r\n        if (onBeforeUnbind) {\r\n            onBeforeUnbind();\r\n        }\r\n        this._bindUnboundFramebuffer(null);\r\n    }\r\n\r\n    public override updateMultipleRenderTargetTextureSampleCount(rtWrapper: Nullable<RenderTargetWrapper>, samples: number, _initializeBuffers = true): number {\r\n        if (!rtWrapper || rtWrapper.samples === samples) {\r\n            return samples;\r\n        }\r\n\r\n        const textures = rtWrapper.textures;\r\n        if (!textures) {\r\n            return rtWrapper.samples;\r\n        }\r\n\r\n        const nativeRTWrapper = rtWrapper as NativeRenderTargetWrapper;\r\n\r\n        // bgfx couples MSAA to the texture creation flags (see updateRenderTargetTextureSampleCount), so\r\n        // changing the sample count after the fact requires reissuing every color attachment's underlying\r\n        // bgfx handle with the new MSAA flag. initializeTexture disposes the old handle and allocates a fresh\r\n        // one while preserving the InternalTexture / Graphics::Texture identity; only the internal bgfx handle\r\n        // rotates. Afterwards the framebuffer is recreated so its attachment list refers to the new handles.\r\n        for (const texture of textures) {\r\n            // Wrapped (External-source) textures own an opaque external handle (format=-1); reinitializing\r\n            // would destroy it and getNativeTextureFormat would throw, so leave those attachments untouched.\r\n            if (!texture?._hardwareTexture || texture.source === InternalTextureSource.External) {\r\n                continue;\r\n            }\r\n\r\n            const nativeTexture = texture._hardwareTexture.underlyingResource;\r\n            // See the bgfx-msaa-mips workaround in updateRenderTargetTextureSampleCount (BabylonNative#1714).\r\n            const hasMips = samples > 1 ? false : texture.generateMipMaps;\r\n            this._engine.initializeTexture(\r\n                nativeTexture,\r\n                texture.baseWidth,\r\n                texture.baseHeight,\r\n                hasMips,\r\n                getNativeTextureFormat(texture.format, texture.type),\r\n                /*renderTarget*/ true,\r\n                texture._useSRGBBuffer,\r\n                samples\r\n            );\r\n            texture.samples = samples;\r\n        }\r\n\r\n        nativeRTWrapper._samples = samples;\r\n        this._createMultiRenderTargetFramebuffer(nativeRTWrapper);\r\n\r\n        return samples;\r\n    }\r\n\r\n    public override updateRenderTargetTextureSampleCount(rtWrapper: RenderTargetWrapper, samples: number): number {\r\n        if (rtWrapper.samples === samples) {\r\n            return samples;\r\n        }\r\n\r\n        const texture = rtWrapper.texture;\r\n        if (!texture?._hardwareTexture) {\r\n            return rtWrapper.samples;\r\n        }\r\n\r\n        // Wrapped (External-source) textures carry an opaque external handle with unknown format/type.\r\n        // Recreating the underlying bgfx texture here would destroy the wrapped handle, breaking the\r\n        // consumer's ownership contract, and getNativeTextureFormat would throw on format=-1 anyway.\r\n        // Reject the request explicitly with a targeted error rather than failing deeper in the stack.\r\n        if (texture.source === InternalTextureSource.External) {\r\n            throw new Error(\r\n                \"updateRenderTargetTextureSampleCount: changing MSAA samples is not supported on wrapped (External-source) textures. Dispose and re-wrap with the desired samples.\"\r\n            );\r\n        }\r\n\r\n        const nativeRTWrapper = rtWrapper as NativeRenderTargetWrapper;\r\n        const nativeTexture = texture._hardwareTexture.underlyingResource;\r\n\r\n        // bgfx couples MSAA to the texture creation flags, so changing samples after the fact requires\r\n        // recreating the underlying bgfx texture handle with the new MSAA flag. initializeTexture on the\r\n        // Native side calls Graphics::Texture::Create2D, which disposes the existing bgfx handle and\r\n        // allocates a fresh one. The Graphics::Texture / InternalTexture wrapper identity is preserved --\r\n        // only the internal bgfx handle rotates. After the texture is reissued we also recreate the\r\n        // framebuffer so its attachment list refers to the new handle.\r\n        //\r\n        // TODO(bgfx-msaa-mips): stopgap workaround for a bgfx bug. D3D11 forbids MipLevels > 1 on\r\n        // multisampled textures (E_INVALIDARG on CreateTexture2D); D3D12/Vulkan have equivalent rules. bgfx's\r\n        // D3D11 backend uses one D3D11_TEXTURE2D_DESC for both the MSAA render texture (m_rt2d) and the\r\n        // non-MSAA sample target (m_texture2d) and doesn't reset desc.MipLevels between them -- so requesting\r\n        // samples > 1 with hasMips = true crashes at m_rt2d creation. The trigger in practice is the glTF\r\n        // transmission helper, which creates an `opaqueSceneTexture` RTT with generateMipmaps: true and\r\n        // immediately sets samples = 4. WebGL2 sidesteps this with a separate non-mipped multisample\r\n        // renderbuffer; bgfx D3D11 conflates the two-stage pattern. The proper fix lives in bgfx (per-backend\r\n        // patches reset MipLevels=1 for the MSAA target). Tracked in BabylonNative#1714. Until that ships\r\n        // through bgfx -> bgfx.cmake -> BabylonNative -> stable npm, force hasMips = false here so the bad\r\n        // combo never reaches bgfx. Cost: MSAA RTs on Native lose post-resolve auto-mipgen and diverge from\r\n        // WebGL/WebGPU semantics -- texture.generateMipMaps still reads true on the JS side, but the\r\n        // underlying bgfx resource has 1 mip level. Remove this guard once a fixed bgfx is in stable BN npm.\r\n        const hasMips = samples > 1 ? false : texture.generateMipMaps;\r\n        const nativeTextureFormat = getNativeTextureFormat(texture.format, texture.type);\r\n        const isCube = texture.isCube;\r\n        this._engine.initializeTexture(\r\n            nativeTexture,\r\n            texture.baseWidth,\r\n            texture.baseHeight,\r\n            hasMips,\r\n            nativeTextureFormat,\r\n            /*renderTarget*/ true,\r\n            texture._useSRGBBuffer,\r\n            samples,\r\n            isCube\r\n        );\r\n\r\n        if (isCube) {\r\n            // Cube RTTs render through one framebuffer per face (see createRenderTargetCubeTexture). The\r\n            // underlying bgfx handle was just rotated, so recreate all six attachments; the _framebuffers\r\n            // setter releases the stale ones and keeps _framebuffer aliased to face 0 for single-target paths.\r\n            const framebuffers: NativeFramebuffer[] = [];\r\n            for (let face = 0; face < 6; face++) {\r\n                framebuffers.push(\r\n                    this._engine.createFrameBuffer(\r\n                        nativeTexture,\r\n                        texture.baseWidth,\r\n                        texture.baseHeight,\r\n                        rtWrapper._generateStencilBuffer,\r\n                        rtWrapper._generateDepthBuffer,\r\n                        samples,\r\n                        face\r\n                    )\r\n                );\r\n            }\r\n            nativeRTWrapper._framebuffers = framebuffers;\r\n        } else {\r\n            // NativeRenderTargetWrapper._framebuffer setter releases the old framebuffer before assigning,\r\n            // so no manual _releaseFramebufferObjects call is needed (and would double-delete the handle).\r\n            nativeRTWrapper._framebuffer = this._engine.createFrameBuffer(\r\n                nativeTexture,\r\n                texture.baseWidth,\r\n                texture.baseHeight,\r\n                rtWrapper._generateStencilBuffer,\r\n                rtWrapper._generateDepthBuffer,\r\n                samples\r\n            );\r\n        }\r\n\r\n        rtWrapper._samples = samples;\r\n        texture.samples = samples;\r\n        return samples;\r\n    }\r\n\r\n    public override updateTextureSamplingMode(samplingMode: number, texture: InternalTexture): void {\r\n        if (texture._hardwareTexture) {\r\n            const filter = getNativeSamplingMode(samplingMode);\r\n            this._setTextureSampling(texture._hardwareTexture.underlyingResource, filter);\r\n        }\r\n\r\n        texture.samplingMode = samplingMode;\r\n    }\r\n\r\n    public override bindFramebuffer(texture: RenderTargetWrapper, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void {\r\n        const nativeRTWrapper = texture as NativeRenderTargetWrapper;\r\n\r\n        if (this._currentRenderTarget) {\r\n            this.unBindFramebuffer(this._currentRenderTarget);\r\n        }\r\n\r\n        this._currentRenderTarget = texture;\r\n\r\n        if (requiredWidth || requiredHeight) {\r\n            throw new Error(\"Required width/height for frame buffers not yet supported in NativeEngine.\");\r\n        }\r\n\r\n        if (nativeRTWrapper._framebuffers) {\r\n            // Cube render target: bind the framebuffer for the requested face.\r\n            this._bindUnboundFramebuffer(nativeRTWrapper._framebuffers[faceIndex ?? 0]);\r\n        } else if (faceIndex) {\r\n            throw new Error(\"Cuboid frame buffers are not yet supported in NativeEngine.\");\r\n        } else if (nativeRTWrapper._framebufferDepthStencil) {\r\n            this._bindUnboundFramebuffer(nativeRTWrapper._framebufferDepthStencil);\r\n        } else {\r\n            this._bindUnboundFramebuffer(nativeRTWrapper._framebuffer);\r\n        }\r\n    }\r\n\r\n    public override unBindFramebuffer(texture: RenderTargetWrapper, disableGenerateMipMaps = false, onBeforeUnbind?: () => void): void {\r\n        // NOTE: Disabling mipmap generation is not yet supported in NativeEngine.\r\n\r\n        this._currentRenderTarget = null;\r\n\r\n        if (onBeforeUnbind) {\r\n            onBeforeUnbind();\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(null);\r\n    }\r\n\r\n    public override createDynamicVertexBuffer(data: DataArray): DataBuffer {\r\n        return this.createVertexBuffer(data, true);\r\n    }\r\n\r\n    public override updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset: number = 0): void {\r\n        const buffer = indexBuffer as NativeDataBuffer;\r\n        const data = this._normalizeIndexData(indices);\r\n        buffer.is32Bits = data.BYTES_PER_ELEMENT === 4;\r\n        this._engine.updateDynamicIndexBuffer(buffer.nativeIndexBuffer!, data.buffer, data.byteOffset, data.byteLength, offset);\r\n    }\r\n\r\n    public override updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset = 0, byteLength?: number): void {\r\n        const buffer = vertexBuffer as NativeDataBuffer;\r\n        const dataView = data instanceof Array ? new Float32Array(data) : ArrayBuffer.isView(data) ? data : new Uint8Array(data);\r\n        const byteView = new Uint8Array(dataView.buffer, dataView.byteOffset, byteLength ?? dataView.byteLength);\r\n        this._engine.updateDynamicVertexBuffer(buffer.nativeVertexBuffer!, byteView.buffer, byteView.byteOffset, byteView.byteLength, byteOffset);\r\n    }\r\n\r\n    // TODO: Refactor to share more logic with base Engine implementation.\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false, depthStencilTexture = false): boolean {\r\n        const uniform = this._boundUniforms[channel] as unknown as NativeUniform;\r\n        if (!uniform) {\r\n            return false;\r\n        }\r\n\r\n        // Not ready?\r\n        if (!texture) {\r\n            if (this._boundTexturesCache[channel] != null) {\r\n                this._activeChannel = channel;\r\n                this._boundTexturesCache[channel] = null;\r\n                this._unsetNativeTexture(uniform);\r\n            }\r\n            return false;\r\n        }\r\n\r\n        // Video\r\n        if ((<VideoTexture>texture).video) {\r\n            this._activeChannel = channel;\r\n            (<VideoTexture>texture).update();\r\n        } else if (texture.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            // Delay loading\r\n            texture.delayLoad();\r\n            return false;\r\n        }\r\n\r\n        let internalTexture: InternalTexture;\r\n        if (depthStencilTexture) {\r\n            internalTexture = (<RenderTargetTexture>texture).depthStencilTexture!;\r\n        } else if (texture.isReady()) {\r\n            internalTexture = <InternalTexture>texture.getInternalTexture();\r\n        } else if (texture.isCube) {\r\n            internalTexture = this.emptyCubeTexture;\r\n        } else if (texture.is3D) {\r\n            internalTexture = this.emptyTexture3D;\r\n        } else if (texture.is2DArray) {\r\n            internalTexture = this.emptyTexture2DArray;\r\n        } else {\r\n            internalTexture = this.emptyTexture;\r\n        }\r\n\r\n        this._activeChannel = channel;\r\n\r\n        if (!internalTexture || !internalTexture._hardwareTexture) {\r\n            return false;\r\n        }\r\n\r\n        this._setTextureWrapMode(\r\n            internalTexture._hardwareTexture.underlyingResource,\r\n            getNativeAddressMode(texture.wrapU),\r\n            getNativeAddressMode(texture.wrapV),\r\n            getNativeAddressMode(texture.wrapR)\r\n        );\r\n        this._updateAnisotropicLevel(texture);\r\n\r\n        this._setNativeTexture(uniform, internalTexture._hardwareTexture.underlyingResource);\r\n\r\n        return true;\r\n    }\r\n\r\n    // filter is a NativeFilter.XXXX value.\r\n    private _setTextureSampling(texture: NativeTexture, filter: number) {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETTEXTURESAMPLING);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(texture);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(filter);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    // addressModes are NativeAddressMode.XXXX values.\r\n    private _setTextureWrapMode(texture: NativeTexture, addressModeU: number, addressModeV: number, addressModeW: number) {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETTEXTUREWRAPMODE);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(texture);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(addressModeU);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(addressModeV);\r\n        this._commandBufferEncoder.encodeCommandArgAsUInt32(addressModeW);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    private _setNativeTexture(uniform: NativeUniform, texture: NativeTexture) {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETTEXTURE);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(texture);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    private _unsetNativeTexture(uniform: NativeUniform) {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_UNSETTEXTURE);\r\n        this._commandBufferEncoder.encodeCommandArgAsNativeData(uniform);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    // TODO: Share more of this logic with the base implementation.\r\n    // TODO: Rename to match naming in base implementation once refactoring allows different parameters.\r\n    private _updateAnisotropicLevel(texture: BaseTexture) {\r\n        const internalTexture = texture.getInternalTexture();\r\n        const value = texture.anisotropicFilteringLevel;\r\n\r\n        if (!internalTexture || !internalTexture._hardwareTexture) {\r\n            return;\r\n        }\r\n\r\n        if (internalTexture._cachedAnisotropicFilteringLevel !== value) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_SETTEXTUREANISOTROPICLEVEL);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(internalTexture._hardwareTexture.underlyingResource);\r\n            this._commandBufferEncoder.encodeCommandArgAsUInt32(value);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n            internalTexture._cachedAnisotropicFilteringLevel = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _bindTexture(channel: number, texture: Nullable<InternalTexture>): void {\r\n        const uniform = this._boundUniforms[channel] as unknown as NativeUniform;\r\n        if (!uniform) {\r\n            return;\r\n        }\r\n\r\n        if (texture && texture._hardwareTexture) {\r\n            const underlyingResource = texture._hardwareTexture.underlyingResource;\r\n            this._setNativeTexture(uniform, underlyingResource);\r\n        } else {\r\n            this._unsetNativeTexture(uniform);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Unbind all textures\r\n     */\r\n    public override unbindAllTextures(): void {\r\n        this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DISCARDALLTEXTURES);\r\n        this._commandBufferEncoder.finishEncodingCommand();\r\n    }\r\n\r\n    protected override _deleteBuffer(buffer: NativeDataBuffer): void {\r\n        if (buffer.nativeIndexBuffer) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DELETEINDEXBUFFER);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(buffer.nativeIndexBuffer);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n            delete buffer.nativeIndexBuffer;\r\n        }\r\n\r\n        if (buffer.nativeVertexBuffer) {\r\n            this._commandBufferEncoder.startEncodingCommand(_native.Engine.COMMAND_DELETEVERTEXBUFFER);\r\n            this._commandBufferEncoder.encodeCommandArgAsNativeData(buffer.nativeVertexBuffer);\r\n            this._commandBufferEncoder.finishEncodingCommand();\r\n            delete buffer.nativeVertexBuffer;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a canvas\r\n     * @param width width\r\n     * @param height height\r\n     * @returns ICanvas interface\r\n     */\r\n    public override createCanvas(width: number, height: number): ICanvas {\r\n        if (!_native.Canvas) {\r\n            throw new Error(\"Native Canvas plugin not available.\");\r\n        }\r\n        const canvas = new _native.Canvas();\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        return canvas;\r\n    }\r\n\r\n    /**\r\n     * Create an image to use with canvas\r\n     * @returns IImage interface\r\n     */\r\n    public override createCanvasImage(): IImage {\r\n        if (!_native.Image) {\r\n            throw new Error(\"Native Canvas plugin not available.\");\r\n        }\r\n        const image = new _native.Image();\r\n        return image;\r\n    }\r\n\r\n    /**\r\n     * Create a 2D path to use with canvas\r\n     * @returns IPath2D interface\r\n     * @param d SVG path string\r\n     */\r\n    public override createCanvasPath2D(d?: string): IPath2D {\r\n        if (!_native.Path2D) {\r\n            throw new Error(\"Native Canvas plugin not available.\");\r\n        }\r\n        const path2d = new _native.Path2D(d);\r\n        return path2d;\r\n    }\r\n\r\n    /**\r\n     * Update a portion of an internal texture\r\n     * @param texture defines the texture to update\r\n     * @param imageData defines the data to store into the texture\r\n     * @param xOffset defines the x coordinates of the update rectangle\r\n     * @param yOffset defines the y coordinates of the update rectangle\r\n     * @param width defines the width of the update rectangle\r\n     * @param height defines the height of the update rectangle\r\n     * @param faceIndex defines the face index if texture is a cube (0 by default)\r\n     * @param lod defines the lod level to update (0 by default)\r\n     * @param generateMipMaps defines whether to generate mipmaps or not\r\n     */\r\n    public override updateTextureData(\r\n        texture: InternalTexture,\r\n        imageData: ArrayBufferView,\r\n        xOffset: number,\r\n        yOffset: number,\r\n        width: number,\r\n        height: number,\r\n        faceIndex: number = 0,\r\n        lod: number = 0,\r\n        generateMipMaps = false\r\n    ): void {\r\n        if (!texture._hardwareTexture) {\r\n            return;\r\n        }\r\n\r\n        if (!this._engine.updateTextureData) {\r\n            throw new Error(\"updateTextureData not implemented.\");\r\n        }\r\n\r\n        // bgfx updates the requested sub-rectangle of the existing texture (faceIndex selects the cube\r\n        // face / array layer, lod selects the mip level). invertY is forwarded so the native side can match\r\n        // the vertical orientation the base texture upload uses. Mip regeneration after a partial update is\r\n        // not supported on Native, so generateMipMaps is ignored (consistent with the other raw-texture paths).\r\n        this._engine.updateTextureData(texture._hardwareTexture.underlyingResource, imageData, xOffset, yOffset, width, height, faceIndex, lod, texture.invertY);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadCompressedDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        internalFormat: number,\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        faceIndex: number = 0,\r\n        lod: number = 0\r\n    ) {\r\n        throw new Error(\"_uploadCompressedDataToTextureDirectly not implemented.\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadDataToTextureDirectly(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {\r\n        throw new Error(\"_uploadDataToTextureDirectly not implemented.\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {\r\n        throw new Error(\"_uploadArrayBufferViewToTexture not implemented.\");\r\n    }\r\n\r\n    public override getFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n        // TODO\r\n        const result = { ascent: 0, height: 0, descent: 0 };\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * No equivalent for native. Do nothing.\r\n     */\r\n    public override flushFramebuffer(): void {}\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public override _readTexturePixels(\r\n        texture: InternalTexture,\r\n        width: number,\r\n        height: number,\r\n        faceIndex?: number,\r\n        level?: number,\r\n        buffer?: Nullable<ArrayBufferView<ArrayBuffer>>,\r\n        _flushRenderer?: boolean,\r\n        _noDataConversion?: boolean,\r\n        x?: number,\r\n        y?: number\r\n    ): Promise<ArrayBufferView> {\r\n        if (faceIndex !== undefined && faceIndex !== -1) {\r\n            throw new Error(`Reading cubemap faces is not supported, but faceIndex is ${faceIndex}.`);\r\n        }\r\n\r\n        return (\r\n            this._engine\r\n                .readTexture(\r\n                    texture._hardwareTexture?.underlyingResource,\r\n                    level ?? 0,\r\n                    x ?? 0,\r\n                    y ?? 0,\r\n                    width,\r\n                    height,\r\n                    buffer?.buffer ?? null,\r\n                    buffer?.byteOffset ?? 0,\r\n                    buffer?.byteLength ?? 0\r\n                )\r\n                // eslint-disable-next-line github/no-then\r\n                .then((rawBuffer) => {\r\n                    if (!buffer) {\r\n                        buffer = new Uint8Array(rawBuffer);\r\n                    }\r\n\r\n                    return buffer;\r\n                })\r\n        );\r\n    }\r\n\r\n    override startTimeQuery(): Nullable<_TimeToken> {\r\n        if (!this._gpuFrameTimeToken) {\r\n            this._gpuFrameTimeToken = new _TimeToken();\r\n        }\r\n\r\n        // Always return the same time token. For native, we don't need a start marker, we just query for native frame stats.\r\n        return this._gpuFrameTimeToken;\r\n    }\r\n\r\n    override endTimeQuery(token: _TimeToken): int {\r\n        this._engine.populateFrameStats(this._frameStats);\r\n        return this._frameStats.gpuTimeNs;\r\n    }\r\n}\r\n","import { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { Constants } from \"../constants\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineAlpha.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineAlpha(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.setAlphaMode = function (mode: number, noDepthWriteChange: boolean = false, targetIndex: number = 0): void {\r\n        if (this._alphaMode[targetIndex] === mode) {\r\n            if (!noDepthWriteChange) {\r\n                // Make sure we still have the correct depth mask according to the alpha mode (a transparent material could have forced writting to the depth buffer, for instance)\r\n                const depthMask = mode === Constants.ALPHA_DISABLE;\r\n                if (this.depthCullingState.depthMask !== depthMask) {\r\n                    this.depthCullingState.depthMask = depthMask;\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        const alphaBlendDisabled = mode === Constants.ALPHA_DISABLE;\r\n\r\n        this._alphaState.setAlphaBlend(!alphaBlendDisabled, targetIndex);\r\n        this._alphaState.setAlphaMode(mode, targetIndex);\r\n\r\n        if (!noDepthWriteChange) {\r\n            this.depthCullingState.depthMask = alphaBlendDisabled;\r\n        }\r\n        this._alphaMode[targetIndex] = mode;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinEngine } from \"../thinEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Registers alpha-to-coverage support for WebGL engines.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineAlphaToCoverage(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    const alphaToCoverageState = new WeakMap<ThinEngine, boolean>();\r\n    const alphaToCoverageContext = new WeakMap<ThinEngine, WebGLRenderingContext>();\r\n    const mainPassSampleCount = new WeakMap<ThinEngine, number>();\r\n    const mainPassSampleCountContext = new WeakMap<ThinEngine, WebGLRenderingContext>();\r\n\r\n    ThinEngine.prototype.getAlphaToCoverage = function (): boolean {\r\n        return alphaToCoverageState.get(this) ?? false;\r\n    };\r\n\r\n    ThinEngine.prototype.setAlphaToCoverage = function (enable: boolean): void {\r\n        if (alphaToCoverageState.get(this) === enable && (!this._gl || alphaToCoverageContext.get(this) === this._gl)) {\r\n            return;\r\n        }\r\n\r\n        alphaToCoverageState.set(this, enable);\r\n\r\n        if (!this._gl) {\r\n            return;\r\n        }\r\n\r\n        if (enable) {\r\n            this._gl.enable(this._gl.SAMPLE_ALPHA_TO_COVERAGE);\r\n        } else {\r\n            this._gl.disable(this._gl.SAMPLE_ALPHA_TO_COVERAGE);\r\n        }\r\n        alphaToCoverageContext.set(this, this._gl);\r\n    };\r\n\r\n    Object.defineProperty(ThinEngine.prototype, \"currentSampleCount\", {\r\n        get: function (this: ThinEngine): number {\r\n            if (this._currentRenderTarget) {\r\n                return this._currentRenderTarget.samples;\r\n            }\r\n\r\n            if (!this._gl) {\r\n                return 1;\r\n            }\r\n\r\n            if (mainPassSampleCountContext.get(this) !== this._gl) {\r\n                mainPassSampleCount.set(this, this._gl.getContextAttributes()?.antialias ? Math.max(1, this._gl.getParameter(this._gl.SAMPLES)) : 1);\r\n                mainPassSampleCountContext.set(this, this._gl);\r\n            }\r\n\r\n            return mainPassSampleCount.get(this)!;\r\n        },\r\n        enumerable: false,\r\n        configurable: true,\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { InternalTextureSource, InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Constants } from \"../constants\";\r\nimport { ThinEngine } from \"../thinEngine.pure\";\r\nimport { type IWebRequest } from \"../../Misc/interfaces/iWebRequest\";\r\nimport { IsExponentOfTwo } from \"../../Misc/tools.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\n\r\n/**\r\n * Create a function for createRawTexture3D/createRawTexture2DArray\r\n * @param is3D true for TEXTURE_3D and false for TEXTURE_2D_ARRAY\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\n\r\n/**\r\n * Create a function for updateRawTexture3D/updateRawTexture2DArray\r\n * @param is3D true for TEXTURE_3D and false for TEXTURE_2D_ARRAY\r\n * @internal\r\n */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineRawTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineRawTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function ConvertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView {\r\n        // Create new RGBA data container.\r\n        let rgbaData: any;\r\n        let val1 = 1;\r\n        if (textureType === Constants.TEXTURETYPE_FLOAT) {\r\n            rgbaData = new Float32Array(width * height * 4);\r\n        } else if (textureType === Constants.TEXTURETYPE_HALF_FLOAT) {\r\n            rgbaData = new Uint16Array(width * height * 4);\r\n            val1 = 15360; // 15360 is the encoding of 1 in half float\r\n        } else if (textureType === Constants.TEXTURETYPE_UNSIGNED_INTEGER) {\r\n            rgbaData = new Uint32Array(width * height * 4);\r\n        } else {\r\n            rgbaData = new Uint8Array(width * height * 4);\r\n        }\r\n\r\n        // Convert each pixel.\r\n        for (let x = 0; x < width; x++) {\r\n            for (let y = 0; y < height; y++) {\r\n                const index = (y * width + x) * 3;\r\n                const newIndex = (y * width + x) * 4;\r\n\r\n                // Map Old Value to new value.\r\n                rgbaData[newIndex + 0] = rgbData[index + 0];\r\n                rgbaData[newIndex + 1] = rgbData[index + 1];\r\n                rgbaData[newIndex + 2] = rgbData[index + 2];\r\n\r\n                // Add fully opaque alpha channel.\r\n                rgbaData[newIndex + 3] = val1;\r\n            }\r\n        }\r\n\r\n        return rgbaData;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function MakeCreateRawTextureFunction(is3D: boolean) {\r\n        return function (\r\n            this: ThinEngine,\r\n            data: Nullable<ArrayBufferView>,\r\n            width: number,\r\n            height: number,\r\n            depth: number,\r\n            format: number,\r\n            generateMipMaps: boolean,\r\n            invertY: boolean,\r\n            samplingMode: number,\r\n            compression: Nullable<string> = null,\r\n            textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        ): InternalTexture {\r\n            const target = is3D ? this._gl.TEXTURE_3D : this._gl.TEXTURE_2D_ARRAY;\r\n            const source = is3D ? InternalTextureSource.Raw3D : InternalTextureSource.Raw2DArray;\r\n            const texture = new InternalTexture(this, source);\r\n            texture.baseWidth = width;\r\n            texture.baseHeight = height;\r\n            texture.baseDepth = depth;\r\n            texture.width = width;\r\n            texture.height = height;\r\n            texture.depth = depth;\r\n            texture.format = format;\r\n            texture.type = textureType;\r\n            texture.generateMipMaps = generateMipMaps;\r\n            texture.samplingMode = samplingMode;\r\n            if (is3D) {\r\n                texture.is3D = true;\r\n            } else {\r\n                texture.is2DArray = true;\r\n            }\r\n\r\n            if (!this._doNotHandleContextLost) {\r\n                texture._bufferView = data;\r\n            }\r\n\r\n            if (is3D) {\r\n                this.updateRawTexture3D(texture, data, format, invertY, compression, textureType);\r\n            } else {\r\n                this.updateRawTexture2DArray(texture, data, format, invertY, compression, textureType);\r\n            }\r\n            this._bindTextureDirectly(target, texture, true);\r\n\r\n            // Filters\r\n            const filters = this._getSamplingParameters(samplingMode, generateMipMaps);\r\n\r\n            this._gl.texParameteri(target, this._gl.TEXTURE_MAG_FILTER, filters.mag);\r\n            this._gl.texParameteri(target, this._gl.TEXTURE_MIN_FILTER, filters.min);\r\n\r\n            if (generateMipMaps) {\r\n                this._gl.generateMipmap(target);\r\n            }\r\n\r\n            this._bindTextureDirectly(target, null);\r\n\r\n            this._internalTexturesCache.push(texture);\r\n\r\n            return texture;\r\n        };\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function MakeUpdateRawTextureFunction(is3D: boolean) {\r\n        return function (\r\n            this: ThinEngine,\r\n            texture: InternalTexture,\r\n            data: Nullable<ArrayBufferView>,\r\n            format: number,\r\n            invertY: boolean,\r\n            compression: Nullable<string> = null,\r\n            textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        ): void {\r\n            const target = is3D ? this._gl.TEXTURE_3D : this._gl.TEXTURE_2D_ARRAY;\r\n            const internalType = this._getWebGLTextureType(textureType);\r\n            const internalFormat = this._getInternalFormat(format);\r\n            const internalSizedFomat = this._getRGBABufferInternalSizedFormat(textureType, format);\r\n\r\n            this._bindTextureDirectly(target, texture, true);\r\n            this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);\r\n\r\n            if (!this._doNotHandleContextLost) {\r\n                texture._bufferView = data;\r\n                texture.format = format;\r\n                texture.invertY = invertY;\r\n                texture._compression = compression;\r\n            }\r\n\r\n            if (texture.width % 4 !== 0) {\r\n                this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);\r\n            }\r\n\r\n            if (compression && data) {\r\n                this._gl.compressedTexImage3D(target, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, texture.depth, 0, data);\r\n            } else {\r\n                this._gl.texImage3D(target, 0, internalSizedFomat, texture.width, texture.height, texture.depth, 0, internalFormat, internalType, data);\r\n            }\r\n\r\n            if (texture.generateMipMaps) {\r\n                this._gl.generateMipmap(target);\r\n            }\r\n            this._bindTextureDirectly(target, null);\r\n            // this.resetTextureCache();\r\n            texture.isReady = true;\r\n        };\r\n    }\r\n\r\n    ThinEngine.prototype.updateRawTexture = function (\r\n        texture: Nullable<InternalTexture>,\r\n        data: Nullable<ArrayBufferView>,\r\n        format: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        useSRGBBuffer: boolean = false\r\n    ): void {\r\n        if (!texture) {\r\n            return;\r\n        }\r\n        // Babylon's internalSizedFomat but gl's texImage2D internalFormat\r\n        const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type, format, useSRGBBuffer);\r\n\r\n        // Babylon's internalFormat but gl's texImage2D format\r\n        const internalFormat = this._getInternalFormat(format);\r\n        const textureType = this._getWebGLTextureType(type);\r\n        this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);\r\n        this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = data;\r\n            texture.format = format;\r\n            texture.type = type;\r\n            texture.invertY = invertY;\r\n            texture._compression = compression;\r\n        }\r\n\r\n        if (texture.width % 4 !== 0) {\r\n            this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);\r\n        }\r\n\r\n        if (compression && data) {\r\n            this._gl.compressedTexImage2D(this._gl.TEXTURE_2D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, 0, <DataView>data);\r\n        } else {\r\n            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, data);\r\n        }\r\n\r\n        if (texture.generateMipMaps) {\r\n            this._gl.generateMipmap(this._gl.TEXTURE_2D);\r\n        }\r\n        this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n        //  this.resetTextureCache();\r\n        texture.isReady = true;\r\n    };\r\n\r\n    ThinEngine.prototype.createRawTexture = function (\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        creationFlags = 0,\r\n        useSRGBBuffer = false\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Raw);\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.format = format;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n        texture.type = type;\r\n        texture._useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, !generateMipMaps);\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = data;\r\n        }\r\n\r\n        this.updateRawTexture(texture, data, format, invertY, compression, type, texture._useSRGBBuffer);\r\n        this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);\r\n\r\n        // Filters\r\n        const filters = this._getSamplingParameters(samplingMode, generateMipMaps);\r\n\r\n        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag);\r\n        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);\r\n\r\n        if (generateMipMaps) {\r\n            this._gl.generateMipmap(this._gl.TEXTURE_2D);\r\n        }\r\n\r\n        this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinEngine.prototype.createRawCubeTexture = function (\r\n        data: Nullable<ArrayBufferView[]>,\r\n        size: number,\r\n        format: number,\r\n        type: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null\r\n    ): InternalTexture {\r\n        const gl = this._gl;\r\n        const texture = new InternalTexture(this, InternalTextureSource.CubeRaw);\r\n        texture.isCube = true;\r\n        texture.format = format;\r\n        texture.type = type;\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferViewArray = data;\r\n        }\r\n\r\n        const textureType = this._getWebGLTextureType(type);\r\n        let internalFormat = this._getInternalFormat(format);\r\n\r\n        if (internalFormat === gl.RGB) {\r\n            internalFormat = gl.RGBA;\r\n        }\r\n\r\n        // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable\r\n        if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            generateMipMaps = false;\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            Logger.Warn(\"Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.\");\r\n        } else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {\r\n            generateMipMaps = false;\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            Logger.Warn(\"Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.\");\r\n        } else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {\r\n            generateMipMaps = false;\r\n            Logger.Warn(\"Render to float textures is not supported. Mipmap generation forced to false.\");\r\n        } else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {\r\n            generateMipMaps = false;\r\n            Logger.Warn(\"Render to half float textures is not supported. Mipmap generation forced to false.\");\r\n        }\r\n\r\n        const width = size;\r\n        const height = width;\r\n\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n\r\n        // Double check on POT to generate Mips.\r\n        const isPot = !this.needPOTTextures || (IsExponentOfTwo(texture.width) && IsExponentOfTwo(texture.height));\r\n        if (!isPot) {\r\n            generateMipMaps = false;\r\n        }\r\n\r\n        // Upload data if needed. The texture won't be ready until then.\r\n        if (data) {\r\n            this.updateRawCubeTexture(texture, data, format, type, invertY, compression);\r\n        } else {\r\n            const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);\r\n            const level = 0;\r\n\r\n            this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n\r\n            for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\r\n                if (compression) {\r\n                    gl.compressedTexImage2D(\r\n                        gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex,\r\n                        level,\r\n                        (<any>this.getCaps().s3tc)[compression],\r\n                        texture.width,\r\n                        texture.height,\r\n                        0,\r\n                        undefined as any\r\n                    );\r\n                } else {\r\n                    gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, null);\r\n                }\r\n            }\r\n\r\n            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);\r\n        }\r\n\r\n        this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);\r\n\r\n        // Filters\r\n        if (data && generateMipMaps) {\r\n            this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);\r\n        }\r\n\r\n        const filters = this._getSamplingParameters(samplingMode, generateMipMaps);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);\r\n\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.isReady = true;\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinEngine.prototype.updateRawCubeTexture = function (\r\n        texture: InternalTexture,\r\n        data: ArrayBufferView[],\r\n        format: number,\r\n        type: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        level: number = 0\r\n    ): void {\r\n        texture._bufferViewArray = data;\r\n        texture.format = format;\r\n        texture.type = type;\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n\r\n        const gl = this._gl;\r\n        const textureType = this._getWebGLTextureType(type);\r\n        let internalFormat = this._getInternalFormat(format);\r\n        const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);\r\n\r\n        let needConversion = false;\r\n        if (internalFormat === gl.RGB) {\r\n            internalFormat = gl.RGBA;\r\n            needConversion = true;\r\n        }\r\n\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n        this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);\r\n\r\n        if (texture.width % 4 !== 0) {\r\n            gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\r\n        }\r\n\r\n        // Data are known to be in +X +Y +Z -X -Y -Z\r\n        for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\r\n            let faceData = data[faceIndex];\r\n\r\n            if (compression) {\r\n                gl.compressedTexImage2D(\r\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex,\r\n                    level,\r\n                    (<any>this.getCaps().s3tc)[compression],\r\n                    texture.width,\r\n                    texture.height,\r\n                    0,\r\n                    <DataView>faceData\r\n                );\r\n            } else {\r\n                if (needConversion) {\r\n                    faceData = ConvertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);\r\n                }\r\n                gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, faceData);\r\n            }\r\n        }\r\n\r\n        const isPot = !this.needPOTTextures || (IsExponentOfTwo(texture.width) && IsExponentOfTwo(texture.height));\r\n        if (isPot && texture.generateMipMaps && level === 0) {\r\n            this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);\r\n        }\r\n        this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);\r\n\r\n        // this.resetTextureCache();\r\n        texture.isReady = true;\r\n    };\r\n\r\n    ThinEngine.prototype.createRawCubeTextureFromUrl = function (\r\n        url: string,\r\n        scene: Nullable<Scene>,\r\n        size: number,\r\n        format: number,\r\n        type: number,\r\n        noMipmap: boolean,\r\n        callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[] | Promise<ArrayBufferView[]>>,\r\n        mipmapGenerator: Nullable<(faces: ArrayBufferView[]) => ArrayBufferView[][]>,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        invertY: boolean = false\r\n    ): InternalTexture {\r\n        const gl = this._gl;\r\n        const texture = this.createRawCubeTexture(null, size, format, type, !noMipmap, invertY, samplingMode, null);\r\n        scene?.addPendingData(texture);\r\n        texture.url = url;\r\n        texture.isReady = false;\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        const onerror = (request?: IWebRequest, exception?: any) => {\r\n            scene?.removePendingData(texture);\r\n            if (onError) {\r\n                onError(request ? request.status + \" \" + request.statusText : \"Failed to parse texture data\", exception);\r\n            }\r\n        };\r\n\r\n        const internalCallbackAsync = async (data: any) => {\r\n            // If the texture has been disposed\r\n            if (!texture._hardwareTexture) {\r\n                return;\r\n            }\r\n\r\n            const faceDataArraysResult = callback(data);\r\n            if (!faceDataArraysResult) {\r\n                return;\r\n            }\r\n\r\n            const faceDataArrays: any = faceDataArraysResult instanceof Promise ? await faceDataArraysResult : faceDataArraysResult;\r\n            const width = texture.width;\r\n\r\n            if (mipmapGenerator) {\r\n                const textureType = this._getWebGLTextureType(type);\r\n                let internalFormat = this._getInternalFormat(format);\r\n                const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);\r\n\r\n                let needConversion = false;\r\n                if (internalFormat === gl.RGB) {\r\n                    internalFormat = gl.RGBA;\r\n                    needConversion = true;\r\n                }\r\n\r\n                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n                this._unpackFlipY(false);\r\n\r\n                const mipData = mipmapGenerator(faceDataArrays);\r\n                for (let level = 0; level < mipData.length; level++) {\r\n                    const mipSize = width >> level;\r\n\r\n                    for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\r\n                        let mipFaceData = mipData[level][faceIndex];\r\n                        if (needConversion) {\r\n                            mipFaceData = ConvertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);\r\n                        }\r\n                        gl.texImage2D(faceIndex, level, internalSizedFomat, mipSize, mipSize, 0, internalFormat, textureType, mipFaceData);\r\n                    }\r\n                }\r\n\r\n                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n            } else {\r\n                this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);\r\n            }\r\n\r\n            texture.isReady = true;\r\n            // this.resetTextureCache();\r\n            scene?.removePendingData(texture);\r\n\r\n            texture.onLoadedObservable.notifyObservers(texture);\r\n            texture.onLoadedObservable.clear();\r\n\r\n            if (onLoad) {\r\n                onLoad();\r\n            }\r\n        };\r\n\r\n        this._loadFile(\r\n            url,\r\n            (data) => {\r\n                // eslint-disable-next-line github/no-then\r\n                internalCallbackAsync(data).catch((err) => {\r\n                    onerror(undefined, err);\r\n                });\r\n            },\r\n            undefined,\r\n            scene?.offlineProvider,\r\n            true,\r\n            onerror\r\n        );\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinEngine.prototype.createRawTexture2DArray = MakeCreateRawTextureFunction(false);\r\n\r\n    ThinEngine.prototype.createRawTexture3D = MakeCreateRawTextureFunction(true);\r\n\r\n    ThinEngine.prototype.updateRawTexture2DArray = MakeUpdateRawTextureFunction(false);\r\n\r\n    ThinEngine.prototype.updateRawTexture3D = MakeUpdateRawTextureFunction(true);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { allocateAndCopyTypedBuffer } from \"../../Engines/abstractEngine.functions\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n// back-compat\r\nexport { allocateAndCopyTypedBuffer };\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineReadTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineReadTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype._readTexturePixelsSync = function (\r\n        texture: InternalTexture,\r\n        width: number,\r\n        height: number,\r\n        faceIndex = -1,\r\n        level = 0,\r\n        buffer: Nullable<ArrayBufferView> = null,\r\n        flushRenderer = true,\r\n        noDataConversion = false,\r\n        x = 0,\r\n        y = 0\r\n    ): ArrayBufferView {\r\n        const gl = this._gl;\r\n        if (!gl) {\r\n            throw new Error(\"Engine does not have gl rendering context.\");\r\n        }\r\n        if (!this._dummyFramebuffer) {\r\n            const dummy = gl.createFramebuffer();\r\n\r\n            if (!dummy) {\r\n                throw new Error(\"Unable to create dummy framebuffer\");\r\n            }\r\n\r\n            this._dummyFramebuffer = dummy;\r\n        }\r\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);\r\n\r\n        if (faceIndex > -1 && (texture.is2DArray || texture.is3D)) {\r\n            gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture._hardwareTexture?.underlyingResource, level, faceIndex);\r\n        } else if (faceIndex > -1) {\r\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._hardwareTexture?.underlyingResource, level);\r\n        } else {\r\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._hardwareTexture?.underlyingResource, level);\r\n        }\r\n\r\n        let readType = texture.type !== undefined ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;\r\n\r\n        if (!noDataConversion) {\r\n            switch (readType) {\r\n                case gl.UNSIGNED_BYTE:\r\n                    if (!buffer) {\r\n                        buffer = new Uint8Array(4 * width * height);\r\n                    }\r\n                    readType = gl.UNSIGNED_BYTE;\r\n                    break;\r\n                default:\r\n                    if (!buffer) {\r\n                        buffer = new Float32Array(4 * width * height);\r\n                    }\r\n                    readType = gl.FLOAT;\r\n                    break;\r\n            }\r\n        } else if (!buffer) {\r\n            buffer = allocateAndCopyTypedBuffer(texture.type, 4 * width * height);\r\n        }\r\n\r\n        if (flushRenderer) {\r\n            this.flushFramebuffer();\r\n        }\r\n\r\n        gl.readPixels(x, y, width, height, gl.RGBA, readType, <DataView>buffer);\r\n        gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer);\r\n\r\n        return buffer;\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    ThinEngine.prototype._readTexturePixels = function (\r\n        texture: InternalTexture,\r\n        width: number,\r\n        height: number,\r\n        faceIndex = -1,\r\n        level = 0,\r\n        buffer: Nullable<ArrayBufferView> = null,\r\n        flushRenderer = true,\r\n        noDataConversion = false,\r\n        x = 0,\r\n        y = 0\r\n    ): Promise<ArrayBufferView> {\r\n        return Promise.resolve(this._readTexturePixelsSync(texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion, x, y));\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { InternalTextureSource, InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Constants } from \"../constants\";\r\nimport { type DepthTextureCreationOptions } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { GetExponentOfTwo } from \"../../Misc/tools.functions\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype._createDepthStencilCubeTexture = function (size: number, options: DepthTextureCreationOptions): InternalTexture {\r\n        const internalTexture = new InternalTexture(this, InternalTextureSource.DepthStencil);\r\n        internalTexture.isCube = true;\r\n\r\n        if (this.webGLVersion === 1) {\r\n            Logger.Error(\"Depth cube texture is not supported by WebGL 1.\");\r\n            return internalTexture;\r\n        }\r\n\r\n        const internalOptions = {\r\n            bilinearFiltering: false,\r\n            comparisonFunction: 0,\r\n            generateStencil: false,\r\n            ...options,\r\n        };\r\n\r\n        const gl = this._gl;\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, internalTexture, true);\r\n\r\n        this._setupDepthStencilTexture(internalTexture, size, internalOptions.bilinearFiltering, internalOptions.comparisonFunction);\r\n\r\n        // Create the depth/stencil buffer\r\n        for (let face = 0; face < 6; face++) {\r\n            if (internalOptions.generateStencil) {\r\n                gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.DEPTH24_STENCIL8, size, size, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);\r\n            } else {\r\n                gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.DEPTH_COMPONENT24, size, size, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);\r\n            }\r\n        }\r\n\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n\r\n        this._internalTexturesCache.push(internalTexture);\r\n\r\n        return internalTexture;\r\n    };\r\n\r\n    ThinEngine.prototype._setCubeMapTextureParams = function (texture: InternalTexture, loadMipmap: boolean, maxLevel?: number): void {\r\n        const gl = this._gl;\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, loadMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n        texture.samplingMode = loadMipmap ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : Constants.TEXTURE_LINEAR_LINEAR;\r\n\r\n        if (loadMipmap && this.getCaps().textureMaxLevel && maxLevel !== undefined && maxLevel > 0) {\r\n            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL, maxLevel);\r\n            texture._maxLodLevel = maxLevel;\r\n        }\r\n\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n    };\r\n\r\n    ThinEngine.prototype.createCubeTexture = function (\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        files: Nullable<string[]>,\r\n        noMipmap?: boolean,\r\n        onLoad: Nullable<(data?: any) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials: boolean = false,\r\n        lodScale: number = 0,\r\n        lodOffset: number = 0,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        loaderOptions?: any,\r\n        useSRGBBuffer = false,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        const gl = this._gl;\r\n\r\n        return this.createCubeTextureBase(\r\n            rootUrl,\r\n            scene,\r\n            files,\r\n            !!noMipmap,\r\n            onLoad,\r\n            onError,\r\n            format,\r\n            forcedExtension,\r\n            createPolynomials,\r\n            lodScale,\r\n            lodOffset,\r\n            fallback,\r\n            (texture: InternalTexture) => this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true),\r\n            (texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => {\r\n                const width = this.needPOTTextures ? GetExponentOfTwo(imgs[0].width, this._caps.maxCubemapTextureSize) : imgs[0].width;\r\n                const height = width;\r\n\r\n                const faces = [\r\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_X,\r\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\r\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\r\n                    gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\r\n                    gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\r\n                    gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,\r\n                ];\r\n\r\n                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n                this._unpackFlipY(false);\r\n\r\n                const internalFormat = format\r\n                    ? this._getInternalFormat(format, texture._useSRGBBuffer)\r\n                    : texture._useSRGBBuffer\r\n                      ? this._glSRGBExtensionValues.SRGB8_ALPHA8\r\n                      : gl.RGBA;\r\n                let texelFormat = format ? this._getInternalFormat(format) : gl.RGBA;\r\n\r\n                if (texture._useSRGBBuffer && this.webGLVersion === 1) {\r\n                    texelFormat = internalFormat;\r\n                }\r\n\r\n                for (let index = 0; index < faces.length; index++) {\r\n                    if (imgs[index].width !== width || imgs[index].height !== height) {\r\n                        this._prepareWorkingCanvas();\r\n\r\n                        if (!this._workingCanvas || !this._workingContext) {\r\n                            Logger.Warn(\"Cannot create canvas to resize texture.\");\r\n                            return;\r\n                        }\r\n                        this._workingCanvas.width = width;\r\n                        this._workingCanvas.height = height;\r\n\r\n                        this._workingContext.drawImage(imgs[index], 0, 0, imgs[index].width, imgs[index].height, 0, 0, width, height);\r\n                        gl.texImage2D(faces[index], 0, internalFormat, texelFormat, gl.UNSIGNED_BYTE, this._workingCanvas as TexImageSource);\r\n                    } else {\r\n                        gl.texImage2D(faces[index], 0, internalFormat, texelFormat, gl.UNSIGNED_BYTE, imgs[index]);\r\n                    }\r\n                }\r\n\r\n                if (!noMipmap) {\r\n                    gl.generateMipmap(gl.TEXTURE_CUBE_MAP);\r\n                }\r\n\r\n                this._setCubeMapTextureParams(texture, !noMipmap);\r\n\r\n                texture.width = width;\r\n                texture.height = height;\r\n                texture.isReady = true;\r\n                if (format) {\r\n                    texture.format = format;\r\n                }\r\n\r\n                texture.onLoadedObservable.notifyObservers(texture);\r\n                texture.onLoadedObservable.clear();\r\n\r\n                if (onLoad) {\r\n                    onLoad();\r\n                }\r\n            },\r\n            !!useSRGBBuffer,\r\n            buffer\r\n        );\r\n    };\r\n\r\n    ThinEngine.prototype.generateMipMapsForCubemap = function (texture: InternalTexture, unbind = true) {\r\n        if (texture.generateMipMaps) {\r\n            const gl = this._gl;\r\n            this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n            gl.generateMipmap(gl.TEXTURE_CUBE_MAP);\r\n            if (unbind) {\r\n                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n            }\r\n        }\r\n    };\r\n}\r\n","import { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../constants\";\r\nimport { type Engine } from \"../engine\";\r\nimport { RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { type ThinEngine } from \"../thinEngine\";\r\nimport { type WebGLHardwareTexture } from \"./webGLHardwareTexture\";\r\nimport { HasStencilAspect } from \"core/Materials/Textures/textureHelper.functions\";\r\n\r\n/** @internal */\r\nexport class WebGLRenderTargetWrapper extends RenderTargetWrapper {\r\n    private _context: WebGLRenderingContext;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _framebuffer: Nullable<WebGLFramebuffer> = null;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _depthStencilBuffer: Nullable<WebGLRenderbuffer> = null;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public _MSAAFramebuffer: Nullable<WebGLFramebuffer> = null;\r\n\r\n    // Multiview\r\n    /**\r\n     * @internal\r\n     */\r\n    public _colorTextureArray: Nullable<WebGLTexture> = null;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _depthStencilTextureArray: Nullable<WebGLTexture> = null;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _disposeOnlyFramebuffers = false;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _currentLOD = 0;\r\n\r\n    public override setDepthStencilTexture(texture: Nullable<InternalTexture>, disposeExisting = true) {\r\n        super.setDepthStencilTexture(texture, disposeExisting);\r\n\r\n        if (!texture) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._engine as ThinEngine;\r\n        const gl = this._context as WebGL2RenderingContext;\r\n        const hardwareTexture = texture._hardwareTexture as Nullable<WebGLHardwareTexture>;\r\n\r\n        if (hardwareTexture && texture._autoMSAAManagement && this._MSAAFramebuffer) {\r\n            const currentFb = engine._currentFramebuffer;\r\n            engine._bindUnboundFramebuffer(this._MSAAFramebuffer);\r\n            gl.framebufferRenderbuffer(\r\n                gl.FRAMEBUFFER,\r\n                HasStencilAspect(texture.format) ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT,\r\n                gl.RENDERBUFFER,\r\n                hardwareTexture.getMSAARenderBuffer()\r\n            );\r\n            engine._bindUnboundFramebuffer(currentFb);\r\n        }\r\n    }\r\n\r\n    constructor(isMulti: boolean, isCube: boolean, size: TextureSize, engine: ThinEngine, context: WebGLRenderingContext) {\r\n        super(isMulti, isCube, size, engine);\r\n\r\n        this._context = context;\r\n    }\r\n\r\n    protected override _cloneRenderTargetWrapper(): Nullable<RenderTargetWrapper> {\r\n        let rtw: Nullable<RenderTargetWrapper>;\r\n\r\n        if (this._colorTextureArray && this._depthStencilTextureArray) {\r\n            rtw = (this._engine as Engine).createMultiviewRenderTargetTexture(this.width, this.height);\r\n            rtw.texture!.isReady = true;\r\n        } else {\r\n            rtw = super._cloneRenderTargetWrapper();\r\n        }\r\n\r\n        return rtw;\r\n    }\r\n\r\n    protected override _swapRenderTargetWrapper(target: WebGLRenderTargetWrapper): void {\r\n        super._swapRenderTargetWrapper(target);\r\n\r\n        target._framebuffer = this._framebuffer;\r\n        target._depthStencilBuffer = this._depthStencilBuffer;\r\n        target._MSAAFramebuffer = this._MSAAFramebuffer;\r\n        target._colorTextureArray = this._colorTextureArray;\r\n        target._depthStencilTextureArray = this._depthStencilTextureArray;\r\n\r\n        this._framebuffer = this._depthStencilBuffer = this._MSAAFramebuffer = this._colorTextureArray = this._depthStencilTextureArray = null;\r\n    }\r\n\r\n    /**\r\n     * Creates the depth/stencil texture\r\n     * @param comparisonFunction Comparison function to use for the texture\r\n     * @param bilinearFiltering true if bilinear filtering should be used when sampling the texture\r\n     * @param generateStencil true if the stencil aspect should also be created\r\n     * @param samples sample count to use when creating the texture\r\n     * @param format format of the depth texture\r\n     * @param label defines the label to use for the texture (for debugging purpose only)\r\n     * @returns the depth/stencil created texture\r\n     */\r\n    public override createDepthStencilTexture(\r\n        comparisonFunction: number = 0,\r\n        bilinearFiltering: boolean = true,\r\n        generateStencil: boolean = false,\r\n        samples: number = 1,\r\n        format: number = Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n        label?: string\r\n    ): InternalTexture {\r\n        if (this._depthStencilBuffer) {\r\n            const engine = this._engine as ThinEngine;\r\n            // Dispose previous depth/stencil render buffers and clear the corresponding attachment.\r\n            // Next time this framebuffer is bound, the new depth/stencil texture will be attached.\r\n            const currentFrameBuffer = engine._currentFramebuffer;\r\n            const gl = this._context;\r\n\r\n            engine._bindUnboundFramebuffer(this._framebuffer);\r\n            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);\r\n            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);\r\n            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);\r\n            engine._bindUnboundFramebuffer(currentFrameBuffer);\r\n            gl.deleteRenderbuffer(this._depthStencilBuffer);\r\n\r\n            this._depthStencilBuffer = null;\r\n        }\r\n\r\n        return super.createDepthStencilTexture(comparisonFunction, bilinearFiltering, generateStencil, samples, format, label);\r\n    }\r\n\r\n    /**\r\n     * Shares the depth buffer of this render target with another render target.\r\n     * @param renderTarget Destination renderTarget\r\n     */\r\n    public override shareDepth(renderTarget: WebGLRenderTargetWrapper): void {\r\n        super.shareDepth(renderTarget);\r\n\r\n        const gl = this._context;\r\n        const depthbuffer = this._depthStencilBuffer;\r\n        const framebuffer = renderTarget._MSAAFramebuffer || renderTarget._framebuffer;\r\n        const engine = this._engine as ThinEngine;\r\n\r\n        if (renderTarget._depthStencilBuffer && renderTarget._depthStencilBuffer !== depthbuffer) {\r\n            gl.deleteRenderbuffer(renderTarget._depthStencilBuffer);\r\n        }\r\n        renderTarget._depthStencilBuffer = depthbuffer;\r\n        const attachment = renderTarget._generateStencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;\r\n        engine._bindUnboundFramebuffer(framebuffer);\r\n        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, depthbuffer);\r\n        engine._bindUnboundFramebuffer(null);\r\n    }\r\n\r\n    /**\r\n     * Binds a texture to this render target on a specific attachment\r\n     * @param texture The texture to bind to the framebuffer\r\n     * @param attachmentIndex Index of the attachment\r\n     * @param faceIndexOrLayer The face or layer of the texture to render to in case of cube texture or array texture\r\n     * @param lodLevel defines the lod level to bind to the frame buffer\r\n     */\r\n    private _bindTextureRenderTarget(texture: InternalTexture, attachmentIndex: number = 0, faceIndexOrLayer?: number, lodLevel: number = 0) {\r\n        const hardwareTexture = texture._hardwareTexture as WebGLHardwareTexture;\r\n        if (!hardwareTexture) {\r\n            return;\r\n        }\r\n\r\n        const framebuffer = this._framebuffer;\r\n        const engine = this._engine as ThinEngine;\r\n        const currentFb = engine._currentFramebuffer;\r\n        engine._bindUnboundFramebuffer(framebuffer);\r\n\r\n        let attachment: any;\r\n        if (engine.webGLVersion > 1) {\r\n            const gl = this._context as WebGL2RenderingContext;\r\n\r\n            attachment = (<any>gl)[\"COLOR_ATTACHMENT\" + attachmentIndex];\r\n            if (texture.is2DArray || texture.is3D) {\r\n                faceIndexOrLayer = faceIndexOrLayer ?? this.layerIndices?.[attachmentIndex] ?? 0;\r\n                gl.framebufferTextureLayer(gl.FRAMEBUFFER, attachment, hardwareTexture.underlyingResource, lodLevel, faceIndexOrLayer);\r\n            } else if (texture.isCube) {\r\n                // if face index is not specified, try to query it from faceIndices\r\n                // default is face 0\r\n                faceIndexOrLayer = faceIndexOrLayer ?? this.faceIndices?.[attachmentIndex] ?? 0;\r\n                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndexOrLayer, hardwareTexture.underlyingResource, lodLevel);\r\n            } else {\r\n                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, hardwareTexture.underlyingResource, lodLevel);\r\n            }\r\n        } else {\r\n            // Default behavior (WebGL)\r\n            const gl = this._context;\r\n\r\n            attachment = (<any>gl)[\"COLOR_ATTACHMENT\" + attachmentIndex + \"_WEBGL\"];\r\n            const target = faceIndexOrLayer !== undefined ? gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndexOrLayer : gl.TEXTURE_2D;\r\n\r\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, target, hardwareTexture.underlyingResource, lodLevel);\r\n        }\r\n\r\n        if (texture._autoMSAAManagement && this._MSAAFramebuffer) {\r\n            const gl = this._context;\r\n            engine._bindUnboundFramebuffer(this._MSAAFramebuffer);\r\n            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, hardwareTexture.getMSAARenderBuffer());\r\n        }\r\n\r\n        engine._bindUnboundFramebuffer(currentFb);\r\n    }\r\n\r\n    /**\r\n     * Set a texture in the textures array\r\n     * @param texture the texture to set\r\n     * @param index the index in the textures array to set\r\n     * @param disposePrevious If this function should dispose the previous texture\r\n     */\r\n    public override setTexture(texture: InternalTexture, index: number = 0, disposePrevious: boolean = true) {\r\n        super.setTexture(texture, index, disposePrevious);\r\n        this._bindTextureRenderTarget(texture, index);\r\n    }\r\n\r\n    /**\r\n     * Sets the layer and face indices of every render target texture\r\n     * @param layers The layer of the texture to be set (make negative to not modify)\r\n     * @param faces The face of the texture to be set (make negative to not modify)\r\n     */\r\n    public override setLayerAndFaceIndices(layers: number[], faces: number[]) {\r\n        super.setLayerAndFaceIndices(layers, faces);\r\n\r\n        if (!this.textures || !this.layerIndices || !this.faceIndices) {\r\n            return;\r\n        }\r\n\r\n        // the length of this._attachments is the right one as it does not count the depth texture, in case we generated it\r\n        const textureCount = this._attachments?.length ?? this.textures.length;\r\n        for (let index = 0; index < textureCount; index++) {\r\n            const texture = this.textures[index];\r\n            if (!texture) {\r\n                // The target type was probably -1 at creation time and setTexture has not been called yet for this index\r\n                continue;\r\n            }\r\n            if (texture.is2DArray || texture.is3D) {\r\n                this._bindTextureRenderTarget(texture, index, this.layerIndices[index]);\r\n            } else if (texture.isCube) {\r\n                this._bindTextureRenderTarget(texture, index, this.faceIndices[index]);\r\n            } else {\r\n                this._bindTextureRenderTarget(texture, index);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the face and layer indices of a texture in the textures array\r\n     * @param index The index of the texture in the textures array to modify\r\n     * @param layer The layer of the texture to be set\r\n     * @param face The face of the texture to be set\r\n     */\r\n    public override setLayerAndFaceIndex(index: number = 0, layer?: number, face?: number): void {\r\n        super.setLayerAndFaceIndex(index, layer, face);\r\n\r\n        if (!this.textures || !this.layerIndices || !this.faceIndices) {\r\n            return;\r\n        }\r\n\r\n        const texture = this.textures[index];\r\n        if (texture.is2DArray || texture.is3D) {\r\n            this._bindTextureRenderTarget(this.textures[index], index, this.layerIndices[index]);\r\n        } else if (texture.isCube) {\r\n            this._bindTextureRenderTarget(this.textures[index], index, this.faceIndices[index]);\r\n        }\r\n    }\r\n\r\n    public override resolveMSAATextures(): void {\r\n        const engine = this._engine as ThinEngine;\r\n        const currentFramebuffer = engine._currentFramebuffer;\r\n\r\n        engine._bindUnboundFramebuffer(this._MSAAFramebuffer);\r\n\r\n        super.resolveMSAATextures();\r\n\r\n        engine._bindUnboundFramebuffer(currentFramebuffer);\r\n    }\r\n\r\n    public override dispose(disposeOnlyFramebuffers = this._disposeOnlyFramebuffers): void {\r\n        const gl = this._context;\r\n\r\n        if (!disposeOnlyFramebuffers) {\r\n            if (this._colorTextureArray) {\r\n                this._context.deleteTexture(this._colorTextureArray);\r\n                this._colorTextureArray = null;\r\n            }\r\n            if (this._depthStencilTextureArray) {\r\n                this._context.deleteTexture(this._depthStencilTextureArray);\r\n                this._depthStencilTextureArray = null;\r\n            }\r\n        }\r\n\r\n        if (this._framebuffer) {\r\n            gl.deleteFramebuffer(this._framebuffer);\r\n            this._framebuffer = null;\r\n        }\r\n\r\n        if (this._depthStencilBuffer) {\r\n            gl.deleteRenderbuffer(this._depthStencilBuffer);\r\n            this._depthStencilBuffer = null;\r\n        }\r\n\r\n        if (this._MSAAFramebuffer) {\r\n            gl.deleteFramebuffer(this._MSAAFramebuffer);\r\n            this._MSAAFramebuffer = null;\r\n        }\r\n\r\n        super.dispose(disposeOnlyFramebuffers);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type RenderTargetCreationOptions, type DepthTextureCreationOptions, type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { ThinEngine } from \"../thinEngine.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { WebGLRenderTargetWrapper } from \"../WebGL/webGLRenderTargetWrapper\";\r\nimport { type WebGLHardwareTexture } from \"../WebGL/webGLHardwareTexture\";\r\nimport { HasStencilAspect } from \"core/Materials/Textures/textureHelper.functions\";\r\nimport { Constants } from \"../constants\";\r\n\r\n/**\r\n * Type used to define a texture size (either with a number or with a rect width and height)\r\n * @deprecated please use TextureSize instead\r\n */\r\nexport type RenderTargetTextureSize = TextureSize;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineRenderTarget.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineRenderTarget(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype._createHardwareRenderTargetWrapper = function (isMulti: boolean, isCube: boolean, size: TextureSize): RenderTargetWrapper {\r\n        const rtWrapper = new WebGLRenderTargetWrapper(isMulti, isCube, size, this, this._gl);\r\n        this._renderTargetWrapperCache.push(rtWrapper);\r\n        return rtWrapper;\r\n    };\r\n\r\n    ThinEngine.prototype.createRenderTargetTexture = function (this: ThinEngine, size: TextureSize, options: boolean | RenderTargetCreationOptions): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, false, size) as WebGLRenderTargetWrapper;\r\n\r\n        let generateDepthBuffer = true;\r\n        let generateStencilBuffer = false;\r\n        let noColorAttachment = false;\r\n        let colorAttachment: InternalTexture | undefined = undefined;\r\n        let samples = 1;\r\n        let label: string | undefined = undefined;\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n            generateStencilBuffer = !!options.generateStencilBuffer;\r\n            noColorAttachment = !!options.noColorAttachment;\r\n            colorAttachment = options.colorAttachment;\r\n            samples = options.samples ?? 1;\r\n            label = options.label;\r\n        }\r\n\r\n        const texture = colorAttachment || (noColorAttachment ? null : this._createInternalTexture(size, options, true, InternalTextureSource.RenderTarget));\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width || <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height || <number>size;\r\n\r\n        const currentFrameBuffer = this._currentFramebuffer;\r\n        const gl = this._gl;\r\n\r\n        // Create the framebuffer\r\n        const framebuffer = gl.createFramebuffer();\r\n        this._bindUnboundFramebuffer(framebuffer);\r\n        rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(generateStencilBuffer, generateDepthBuffer, width, height);\r\n\r\n        // No need to rebind on every frame\r\n        if (texture && !texture.is2DArray && !texture.is3D) {\r\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._hardwareTexture!.underlyingResource, 0);\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(currentFrameBuffer);\r\n\r\n        rtWrapper.label = label ?? \"RenderTargetWrapper\";\r\n        rtWrapper._framebuffer = framebuffer;\r\n        rtWrapper._generateDepthBuffer = generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = generateStencilBuffer;\r\n\r\n        rtWrapper.setTextures(texture);\r\n\r\n        if (!colorAttachment) {\r\n            this.updateRenderTargetTextureSampleCount(rtWrapper, samples);\r\n        } else {\r\n            rtWrapper._samples = colorAttachment.samples;\r\n            if (colorAttachment.samples > 1) {\r\n                const msaaRenderBuffer = (colorAttachment._hardwareTexture as WebGLHardwareTexture).getMSAARenderBuffer(0);\r\n\r\n                rtWrapper._MSAAFramebuffer = gl.createFramebuffer();\r\n\r\n                this._bindUnboundFramebuffer(rtWrapper._MSAAFramebuffer);\r\n                gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaRenderBuffer);\r\n                this._bindUnboundFramebuffer(null);\r\n            }\r\n        }\r\n\r\n        return rtWrapper;\r\n    };\r\n\r\n    ThinEngine.prototype._createDepthStencilTexture = function (size: TextureSize, options: DepthTextureCreationOptions, rtWrapper: WebGLRenderTargetWrapper): InternalTexture {\r\n        const gl = this._gl;\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>size).layers || 0;\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>size).depth || 0;\r\n        let target: number = gl.TEXTURE_2D;\r\n        if (layers !== 0) {\r\n            target = gl.TEXTURE_2D_ARRAY;\r\n        } else if (depth !== 0) {\r\n            target = gl.TEXTURE_3D;\r\n        }\r\n        const internalTexture = new InternalTexture(this, InternalTextureSource.DepthStencil);\r\n        internalTexture.label = options.label;\r\n        if (!this._caps.depthTextureExtension) {\r\n            Logger.Error(\"Depth texture is not supported by your browser or hardware.\");\r\n            return internalTexture;\r\n        }\r\n\r\n        const internalOptions = {\r\n            bilinearFiltering: false,\r\n            comparisonFunction: 0,\r\n            generateStencil: false,\r\n            ...options,\r\n        };\r\n\r\n        this._bindTextureDirectly(target, internalTexture, true);\r\n\r\n        this._setupDepthStencilTexture(\r\n            internalTexture,\r\n            size,\r\n            internalOptions.comparisonFunction === 0 ? false : internalOptions.bilinearFiltering,\r\n            internalOptions.comparisonFunction,\r\n            internalOptions.samples\r\n        );\r\n\r\n        if (internalOptions.depthTextureFormat !== undefined) {\r\n            if (\r\n                internalOptions.depthTextureFormat !== Constants.TEXTUREFORMAT_DEPTH16 &&\r\n                internalOptions.depthTextureFormat !== Constants.TEXTUREFORMAT_DEPTH24 &&\r\n                internalOptions.depthTextureFormat !== Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 &&\r\n                internalOptions.depthTextureFormat !== Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 &&\r\n                internalOptions.depthTextureFormat !== Constants.TEXTUREFORMAT_DEPTH32_FLOAT &&\r\n                internalOptions.depthTextureFormat !== Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8\r\n            ) {\r\n                Logger.Error(`Depth texture ${internalOptions.depthTextureFormat} format is not supported.`);\r\n                return internalTexture;\r\n            }\r\n            internalTexture.format = internalOptions.depthTextureFormat;\r\n        } else {\r\n            internalTexture.format = internalOptions.generateStencil ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH24;\r\n        }\r\n\r\n        const hasStencil = HasStencilAspect(internalTexture.format);\r\n        const type = this._getWebGLTextureTypeFromDepthTextureFormat(internalTexture.format);\r\n        const format = hasStencil ? gl.DEPTH_STENCIL : gl.DEPTH_COMPONENT;\r\n        const internalFormat = this._getInternalFormatFromDepthTextureFormat(internalTexture.format, true, hasStencil);\r\n\r\n        if (internalTexture.is2DArray) {\r\n            gl.texImage3D(target, 0, internalFormat, internalTexture.width, internalTexture.height, layers, 0, format, type, null);\r\n        } else if (internalTexture.is3D) {\r\n            gl.texImage3D(target, 0, internalFormat, internalTexture.width, internalTexture.height, depth, 0, format, type, null);\r\n        } else {\r\n            gl.texImage2D(target, 0, internalFormat, internalTexture.width, internalTexture.height, 0, format, type, null);\r\n        }\r\n\r\n        this._bindTextureDirectly(target, null);\r\n\r\n        this._internalTexturesCache.push(internalTexture);\r\n\r\n        if (rtWrapper._depthStencilBuffer) {\r\n            gl.deleteRenderbuffer(rtWrapper._depthStencilBuffer);\r\n            rtWrapper._depthStencilBuffer = null;\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(rtWrapper._MSAAFramebuffer ?? rtWrapper._framebuffer);\r\n\r\n        rtWrapper._generateStencilBuffer = hasStencil;\r\n        rtWrapper._depthStencilTextureWithStencil = hasStencil;\r\n\r\n        rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(\r\n            rtWrapper._generateStencilBuffer,\r\n            rtWrapper._generateDepthBuffer,\r\n            rtWrapper.width,\r\n            rtWrapper.height,\r\n            rtWrapper.samples,\r\n            internalTexture.format\r\n        );\r\n\r\n        this._bindUnboundFramebuffer(null);\r\n\r\n        return internalTexture;\r\n    };\r\n\r\n    ThinEngine.prototype.updateRenderTargetTextureSampleCount = function (rtWrapper: Nullable<WebGLRenderTargetWrapper>, samples: number): number {\r\n        if (this.webGLVersion < 2 || !rtWrapper) {\r\n            return 1;\r\n        }\r\n\r\n        if (rtWrapper.samples === samples) {\r\n            return samples;\r\n        }\r\n\r\n        const gl = this._gl;\r\n\r\n        samples = Math.min(samples, this.getCaps().maxMSAASamples);\r\n\r\n        // Dispose previous render buffers\r\n        if (rtWrapper._depthStencilBuffer) {\r\n            gl.deleteRenderbuffer(rtWrapper._depthStencilBuffer);\r\n            rtWrapper._depthStencilBuffer = null;\r\n        }\r\n\r\n        if (rtWrapper._MSAAFramebuffer) {\r\n            gl.deleteFramebuffer(rtWrapper._MSAAFramebuffer);\r\n            rtWrapper._MSAAFramebuffer = null;\r\n        }\r\n\r\n        const hardwareTexture = rtWrapper.texture?._hardwareTexture as Nullable<WebGLHardwareTexture>;\r\n        hardwareTexture?.releaseMSAARenderBuffers();\r\n\r\n        if (rtWrapper.texture && samples > 1 && typeof gl.renderbufferStorageMultisample === \"function\") {\r\n            const framebuffer = gl.createFramebuffer();\r\n\r\n            if (!framebuffer) {\r\n                throw new Error(\"Unable to create multi sampled framebuffer\");\r\n            }\r\n\r\n            rtWrapper._MSAAFramebuffer = framebuffer;\r\n            this._bindUnboundFramebuffer(rtWrapper._MSAAFramebuffer);\r\n\r\n            const colorRenderbuffer = this._createRenderBuffer(\r\n                rtWrapper.texture.width,\r\n                rtWrapper.texture.height,\r\n                samples,\r\n                -1 /* not used */,\r\n                this._getRGBABufferInternalSizedFormat(rtWrapper.texture.type, rtWrapper.texture.format, rtWrapper.texture._useSRGBBuffer),\r\n                gl.COLOR_ATTACHMENT0,\r\n                false\r\n            );\r\n\r\n            if (!colorRenderbuffer) {\r\n                throw new Error(\"Unable to create multi sampled framebuffer\");\r\n            }\r\n\r\n            hardwareTexture?.addMSAARenderBuffer(colorRenderbuffer);\r\n        }\r\n\r\n        this._bindUnboundFramebuffer(rtWrapper._MSAAFramebuffer ?? rtWrapper._framebuffer);\r\n\r\n        if (rtWrapper.texture) {\r\n            rtWrapper.texture.samples = samples;\r\n        }\r\n\r\n        rtWrapper._samples = samples;\r\n\r\n        const depthFormat = rtWrapper._depthStencilTexture ? rtWrapper._depthStencilTexture.format : undefined;\r\n\r\n        rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(\r\n            rtWrapper._generateStencilBuffer,\r\n            rtWrapper._generateDepthBuffer,\r\n            rtWrapper.width,\r\n            rtWrapper.height,\r\n            samples,\r\n            depthFormat\r\n        );\r\n\r\n        this._bindUnboundFramebuffer(null);\r\n\r\n        return samples;\r\n    };\r\n\r\n    ThinEngine.prototype._setupDepthStencilTexture = function (\r\n        internalTexture: InternalTexture,\r\n        size: TextureSize,\r\n        bilinearFiltering: boolean,\r\n        comparisonFunction: number,\r\n        samples = 1\r\n    ) {\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>size).layers || 0;\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>size).depth || 0;\r\n\r\n        internalTexture.baseWidth = width;\r\n        internalTexture.baseHeight = height;\r\n        internalTexture.width = width;\r\n        internalTexture.height = height;\r\n        internalTexture.is2DArray = layers > 0;\r\n        internalTexture.depth = layers || depth;\r\n        internalTexture.isReady = true;\r\n        internalTexture.samples = samples;\r\n        internalTexture.generateMipMaps = false;\r\n        internalTexture.samplingMode = bilinearFiltering ? Constants.TEXTURE_BILINEAR_SAMPLINGMODE : Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        internalTexture._comparisonFunction = comparisonFunction;\r\n\r\n        const gl = this._gl;\r\n        const target = this._getTextureTarget(internalTexture);\r\n        const samplingParameters = this._getSamplingParameters(internalTexture.samplingMode, false);\r\n        gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, samplingParameters.mag);\r\n        gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, samplingParameters.min);\r\n        gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n        gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n        // TEXTURE_COMPARE_FUNC/MODE are only availble in WebGL2.\r\n        if (this.webGLVersion > 1) {\r\n            if (comparisonFunction === 0) {\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_FUNC, Constants.LEQUAL);\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.NONE);\r\n            } else {\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);\r\n                gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);\r\n            }\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineRenderTargetTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineRenderTargetTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.setDepthStencilTexture = function (channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<RenderTargetTexture>, name?: string): void {\r\n        if (channel === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (uniform) {\r\n            this._boundUniforms[channel] = uniform;\r\n        }\r\n\r\n        if (!texture || !texture.depthStencilTexture) {\r\n            this._setTexture(channel, null, undefined, undefined, name);\r\n        } else {\r\n            this._setTexture(channel, texture, false, true, name);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Constants } from \"../constants\";\r\nimport { ThinEngine } from \"../thinEngine.pure\";\r\nimport { type RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { type WebGLRenderTargetWrapper } from \"../WebGL/webGLRenderTargetWrapper\";\r\nimport { type RenderTargetCreationOptions } from \"../../Materials/Textures/textureCreationOptions\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineRenderTargetCube.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineRenderTargetCube(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.createRenderTargetCubeTexture = function (size: number, options?: RenderTargetCreationOptions): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, true, size) as WebGLRenderTargetWrapper;\r\n\r\n        const fullOptions = {\r\n            generateMipMaps: true,\r\n            generateDepthBuffer: true,\r\n            generateStencilBuffer: false,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            ...options,\r\n        };\r\n        fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && fullOptions.generateStencilBuffer;\r\n\r\n        if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (fullOptions.type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        const gl = this._gl;\r\n\r\n        const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n\r\n        const filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps);\r\n\r\n        if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n            fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            Logger.Warn(\"Float textures are not supported. Cube render target forced to TEXTURETYPE_UNESIGNED_BYTE type\");\r\n        }\r\n\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n        for (let face = 0; face < 6; face++) {\r\n            gl.texImage2D(\r\n                gl.TEXTURE_CUBE_MAP_POSITIVE_X + face,\r\n                0,\r\n                this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format),\r\n                size,\r\n                size,\r\n                0,\r\n                this._getInternalFormat(fullOptions.format),\r\n                this._getWebGLTextureType(fullOptions.type),\r\n                null\r\n            );\r\n        }\r\n\r\n        // Create the framebuffer\r\n        const framebuffer = gl.createFramebuffer();\r\n        this._bindUnboundFramebuffer(framebuffer);\r\n\r\n        rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(fullOptions.generateStencilBuffer, fullOptions.generateDepthBuffer, size, size);\r\n\r\n        // MipMaps\r\n        if (fullOptions.generateMipMaps) {\r\n            gl.generateMipmap(gl.TEXTURE_CUBE_MAP);\r\n        }\r\n\r\n        // Unbind\r\n        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n        this._bindUnboundFramebuffer(null);\r\n\r\n        rtWrapper._framebuffer = framebuffer;\r\n        rtWrapper._generateDepthBuffer = fullOptions.generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = fullOptions.generateStencilBuffer;\r\n\r\n        texture.width = size;\r\n        texture.height = size;\r\n        texture.isReady = true;\r\n        texture.isCube = true;\r\n        texture.samples = 1;\r\n        texture.generateMipMaps = fullOptions.generateMipMaps;\r\n        texture.samplingMode = fullOptions.samplingMode;\r\n        texture.type = fullOptions.type;\r\n        texture.format = fullOptions.format;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n        rtWrapper.setTextures(texture);\r\n\r\n        return rtWrapper;\r\n    };\r\n}\r\n","import { Vector3, Vector2 } from \"./math.vector.pure\";\r\n\r\n/**\r\n * Contains position and normal vectors for a vertex\r\n */\r\nexport class PositionNormalVertex {\r\n    /**\r\n     * Creates a PositionNormalVertex\r\n     * @param position the position of the vertex (defaut: 0,0,0)\r\n     * @param normal the normal of the vertex (defaut: 0,1,0)\r\n     */\r\n    constructor(\r\n        /** [Vector3.Zero()] the position of the vertex (defaut: 0,0,0) */\r\n        public position: Vector3 = Vector3.Zero(),\r\n        /** [Vector3.Up()] the normal of the vertex (defaut: 0,1,0) */\r\n        public normal: Vector3 = Vector3.Up()\r\n    ) {}\r\n\r\n    /**\r\n     * Clones the PositionNormalVertex\r\n     * @returns the cloned PositionNormalVertex\r\n     */\r\n    public clone(): PositionNormalVertex {\r\n        return new PositionNormalVertex(this.position.clone(), this.normal.clone());\r\n    }\r\n}\r\n\r\n/**\r\n * Contains position, normal and uv vectors for a vertex\r\n */\r\nexport class PositionNormalTextureVertex {\r\n    /**\r\n     * Creates a PositionNormalTextureVertex\r\n     * @param position the position of the vertex (defaut: 0,0,0)\r\n     * @param normal the normal of the vertex (defaut: 0,1,0)\r\n     * @param uv the uv of the vertex (default: 0,0)\r\n     */\r\n    constructor(\r\n        /** [Vector3.Zero()] the position of the vertex (defaut: 0,0,0) */\r\n        public position: Vector3 = Vector3.Zero(),\r\n        /** [Vector3.Up()] the normal of the vertex (defaut: 0,1,0) */\r\n        public normal: Vector3 = Vector3.Up(),\r\n        /** [Vector3.Zero()] the uv of the vertex (default: 0,0) */\r\n        public uv: Vector2 = Vector2.Zero()\r\n    ) {}\r\n    /**\r\n     * Clones the PositionNormalTextureVertex\r\n     * @returns the cloned PositionNormalTextureVertex\r\n     */\r\n    public clone(): PositionNormalTextureVertex {\r\n        return new PositionNormalTextureVertex(this.position.clone(), this.normal.clone(), this.uv.clone());\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Color3 } from \"../Maths/math.color.pure\";\r\nimport { TmpVectors } from \"./math\";\r\n\r\n// https://dickyjim.wordpress.com/2013/09/04/spherical-harmonics-for-beginners/\r\n// http://silviojemma.com/public/papers/lighting/spherical-harmonic-lighting.pdf\r\n// https://www.ppsloan.org/publications/StupidSH36.pdf\r\n// http://cseweb.ucsd.edu/~ravir/papers/envmap/envmap.pdf\r\n// https://www.ppsloan.org/publications/SHJCGT.pdf\r\n// https://www.ppsloan.org/publications/shdering.pdf\r\n// https://google.github.io/filament/Filament.md.html#annex/sphericalharmonics\r\n// https://patapom.com/blog/SHPortal/\r\n// https://imdoingitwrong.wordpress.com/2011/04/14/spherical-harmonics-wtf/\r\n\r\n// Using real SH basis:\r\n//  m>0             m   m\r\n// y   = sqrt(2) * K * P * cos(m*phi) * cos(theta)\r\n//  l               l   l\r\n//\r\n//  m<0             m   |m|\r\n// y   = sqrt(2) * K * P * sin(m*phi) * cos(theta)\r\n//  l               l   l\r\n//\r\n//  m=0   0   0\r\n// y   = K * P * trigono terms\r\n//  l     l   l\r\n//\r\n//  m       (2l + 1)(l - |m|)!\r\n// K = sqrt(------------------)\r\n//  l           4pi(l + |m|)!\r\n//\r\n// and P by recursion:\r\n//\r\n// P00(x) = 1\r\n// P01(x) = x\r\n// Pll(x) = (-1^l)(2l - 1)!!(1-x*x)^(1/2)\r\n//          ((2l - 1)x[Pl-1/m]-(l + m - 1)[Pl-2/m])\r\n// Plm(x) = ---------------------------------------\r\n//                         l - m\r\n// Leaving the trigonometric terms aside we can precompute the constants to :\r\nconst SH3ylmBasisConstants = [\r\n    Math.sqrt(1 / (4 * Math.PI)), // l00\r\n\r\n    -Math.sqrt(3 / (4 * Math.PI)), // l1_1\r\n    Math.sqrt(3 / (4 * Math.PI)), // l10\r\n    -Math.sqrt(3 / (4 * Math.PI)), // l11\r\n\r\n    Math.sqrt(15 / (4 * Math.PI)), // l2_2\r\n    -Math.sqrt(15 / (4 * Math.PI)), // l2_1\r\n    Math.sqrt(5 / (16 * Math.PI)), // l20\r\n    -Math.sqrt(15 / (4 * Math.PI)), // l21\r\n    Math.sqrt(15 / (16 * Math.PI)), // l22\r\n];\r\n\r\n// cm = cos(m * phi)\r\n// sm = sin(m * phi)\r\n// {x,y,z} = {cos(phi)sin(theta), sin(phi)sin(theta), cos(theta)}\r\n// By recursion on using trigo identities:\r\nconst SH3ylmBasisTrigonometricTerms = [\r\n    () => 1, // l00\r\n\r\n    (direction: Vector3) => direction.y, // l1_1\r\n    (direction: Vector3) => direction.z, // l10\r\n    (direction: Vector3) => direction.x, // l11\r\n\r\n    (direction: Vector3) => direction.x * direction.y, // l2_2\r\n    (direction: Vector3) => direction.y * direction.z, // l2_1\r\n    (direction: Vector3) => 3 * direction.z * direction.z - 1, // l20\r\n    (direction: Vector3) => direction.x * direction.z, // l21\r\n    (direction: Vector3) => direction.x * direction.x - direction.y * direction.y, // l22\r\n];\r\n\r\n// Wrap the full compute\r\nconst applySH3 = (lm: number, direction: Vector3) => {\r\n    return SH3ylmBasisConstants[lm] * SH3ylmBasisTrigonometricTerms[lm](direction);\r\n};\r\n\r\n// Derived from the integration of the a kernel convolution to SH.\r\n// Great explanation here: https://patapom.com/blog/SHPortal/#about-distant-radiance-and-irradiance-environments\r\nconst SHCosKernelConvolution = [Math.PI, (2 * Math.PI) / 3, (2 * Math.PI) / 3, (2 * Math.PI) / 3, Math.PI / 4, Math.PI / 4, Math.PI / 4, Math.PI / 4, Math.PI / 4];\r\n\r\n/**\r\n * Class representing spherical harmonics coefficients to the 3rd degree\r\n */\r\nexport class SphericalHarmonics {\r\n    /**\r\n     * Defines whether or not the harmonics have been prescaled for rendering.\r\n     */\r\n    public preScaled = false;\r\n\r\n    /**\r\n     * The l0,0 coefficients of the spherical harmonics\r\n     */\r\n    public l00: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l1,-1 coefficients of the spherical harmonics\r\n     */\r\n    public l1_1: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l1,0 coefficients of the spherical harmonics\r\n     */\r\n    public l10: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l1,1 coefficients of the spherical harmonics\r\n     */\r\n    public l11: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l2,-2 coefficients of the spherical harmonics\r\n     */\r\n    public l2_2: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l2,-1 coefficients of the spherical harmonics\r\n     */\r\n    public l2_1: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l2,0 coefficients of the spherical harmonics\r\n     */\r\n    public l20: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l2,1 coefficients of the spherical harmonics\r\n     */\r\n    public l21: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The l2,2 coefficients of the spherical harmonics\r\n     */\r\n    public l22: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Adds a light to the spherical harmonics\r\n     * @param direction the direction of the light\r\n     * @param color the color of the light\r\n     * @param deltaSolidAngle the delta solid angle of the light\r\n     */\r\n    public addLight(direction: Vector3, color: Color3, deltaSolidAngle: number): void {\r\n        TmpVectors.Vector3[0].set(color.r, color.g, color.b);\r\n        const colorVector = TmpVectors.Vector3[0];\r\n        const c = TmpVectors.Vector3[1];\r\n        colorVector.scaleToRef(deltaSolidAngle, c);\r\n\r\n        c.scaleToRef(applySH3(0, direction), TmpVectors.Vector3[2]);\r\n        this.l00.addInPlace(TmpVectors.Vector3[2]);\r\n\r\n        c.scaleToRef(applySH3(1, direction), TmpVectors.Vector3[2]);\r\n        this.l1_1.addInPlace(TmpVectors.Vector3[2]);\r\n        c.scaleToRef(applySH3(2, direction), TmpVectors.Vector3[2]);\r\n        this.l10.addInPlace(TmpVectors.Vector3[2]);\r\n        c.scaleToRef(applySH3(3, direction), TmpVectors.Vector3[2]);\r\n        this.l11.addInPlace(TmpVectors.Vector3[2]);\r\n\r\n        c.scaleToRef(applySH3(4, direction), TmpVectors.Vector3[2]);\r\n        this.l2_2.addInPlace(TmpVectors.Vector3[2]);\r\n        c.scaleToRef(applySH3(5, direction), TmpVectors.Vector3[2]);\r\n        this.l2_1.addInPlace(TmpVectors.Vector3[2]);\r\n        c.scaleToRef(applySH3(6, direction), TmpVectors.Vector3[2]);\r\n        this.l20.addInPlace(TmpVectors.Vector3[2]);\r\n        c.scaleToRef(applySH3(7, direction), TmpVectors.Vector3[2]);\r\n        this.l21.addInPlace(TmpVectors.Vector3[2]);\r\n        c.scaleToRef(applySH3(8, direction), TmpVectors.Vector3[2]);\r\n        this.l22.addInPlace(TmpVectors.Vector3[2]);\r\n    }\r\n\r\n    /**\r\n     * Scales the spherical harmonics by the given amount\r\n     * @param scale the amount to scale\r\n     */\r\n    public scaleInPlace(scale: number): void {\r\n        this.l00.scaleInPlace(scale);\r\n        this.l1_1.scaleInPlace(scale);\r\n        this.l10.scaleInPlace(scale);\r\n        this.l11.scaleInPlace(scale);\r\n        this.l2_2.scaleInPlace(scale);\r\n        this.l2_1.scaleInPlace(scale);\r\n        this.l20.scaleInPlace(scale);\r\n        this.l21.scaleInPlace(scale);\r\n        this.l22.scaleInPlace(scale);\r\n    }\r\n\r\n    /**\r\n     * Convert from incident radiance (Li) to irradiance (E) by applying convolution with the cosine-weighted hemisphere.\r\n     *\r\n     * ```\r\n     * E_lm = A_l * L_lm\r\n     * ```\r\n     *\r\n     * In spherical harmonics this convolution amounts to scaling factors for each frequency band.\r\n     * This corresponds to equation 5 in \"An Efficient Representation for Irradiance Environment Maps\", where\r\n     * the scaling factors are given in equation 9.\r\n     */\r\n    public convertIncidentRadianceToIrradiance(): void {\r\n        // Constant (Band 0)\r\n        this.l00.scaleInPlace(SHCosKernelConvolution[0]);\r\n\r\n        // Linear (Band 1)\r\n        this.l1_1.scaleInPlace(SHCosKernelConvolution[1]);\r\n        this.l10.scaleInPlace(SHCosKernelConvolution[2]);\r\n        this.l11.scaleInPlace(SHCosKernelConvolution[3]);\r\n\r\n        // Quadratic (Band 2)\r\n        this.l2_2.scaleInPlace(SHCosKernelConvolution[4]);\r\n        this.l2_1.scaleInPlace(SHCosKernelConvolution[5]);\r\n        this.l20.scaleInPlace(SHCosKernelConvolution[6]);\r\n        this.l21.scaleInPlace(SHCosKernelConvolution[7]);\r\n        this.l22.scaleInPlace(SHCosKernelConvolution[8]);\r\n    }\r\n\r\n    /**\r\n     * Convert from irradiance to outgoing radiance for Lambertian BDRF, suitable for efficient shader evaluation.\r\n     *\r\n     * ```\r\n     * L = (1/pi) * E * rho\r\n     * ```\r\n     *\r\n     * This is done by an additional scale by 1/pi, so is a fairly trivial operation but important conceptually.\r\n     */\r\n    public convertIrradianceToLambertianRadiance(): void {\r\n        this.scaleInPlace(1.0 / Math.PI);\r\n\r\n        // The resultant SH now represents outgoing radiance, so includes the Lambert 1/pi normalisation factor but without albedo (rho) applied\r\n        // (The pixel shader must apply albedo after texture fetches, etc).\r\n    }\r\n\r\n    /**\r\n     * Integrates the reconstruction coefficients directly in to the SH preventing further\r\n     * required operations at run time.\r\n     *\r\n     * This is simply done by scaling back the SH with Ylm constants parameter.\r\n     * The trigonometric part being applied by the shader at run time.\r\n     */\r\n    public preScaleForRendering(): void {\r\n        this.preScaled = true;\r\n\r\n        this.l00.scaleInPlace(SH3ylmBasisConstants[0]);\r\n\r\n        this.l1_1.scaleInPlace(SH3ylmBasisConstants[1]);\r\n        this.l10.scaleInPlace(SH3ylmBasisConstants[2]);\r\n        this.l11.scaleInPlace(SH3ylmBasisConstants[3]);\r\n\r\n        this.l2_2.scaleInPlace(SH3ylmBasisConstants[4]);\r\n        this.l2_1.scaleInPlace(SH3ylmBasisConstants[5]);\r\n        this.l20.scaleInPlace(SH3ylmBasisConstants[6]);\r\n        this.l21.scaleInPlace(SH3ylmBasisConstants[7]);\r\n        this.l22.scaleInPlace(SH3ylmBasisConstants[8]);\r\n    }\r\n\r\n    /**\r\n     * update the spherical harmonics coefficients from the given array\r\n     * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)\r\n     * @returns the spherical harmonics (this)\r\n     */\r\n    public updateFromArray(data: ArrayLike<ArrayLike<number>>): SphericalHarmonics {\r\n        Vector3.FromArrayToRef(data[0], 0, this.l00);\r\n        Vector3.FromArrayToRef(data[1], 0, this.l1_1);\r\n        Vector3.FromArrayToRef(data[2], 0, this.l10);\r\n        Vector3.FromArrayToRef(data[3], 0, this.l11);\r\n        Vector3.FromArrayToRef(data[4], 0, this.l2_2);\r\n        Vector3.FromArrayToRef(data[5], 0, this.l2_1);\r\n        Vector3.FromArrayToRef(data[6], 0, this.l20);\r\n        Vector3.FromArrayToRef(data[7], 0, this.l21);\r\n        Vector3.FromArrayToRef(data[8], 0, this.l22);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * update the spherical harmonics coefficients from the given floats array\r\n     * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)\r\n     * @returns the spherical harmonics (this)\r\n     */\r\n    public updateFromFloatsArray(data: ArrayLike<number>): SphericalHarmonics {\r\n        Vector3.FromFloatsToRef(data[0], data[1], data[2], this.l00);\r\n        Vector3.FromFloatsToRef(data[3], data[4], data[5], this.l1_1);\r\n        Vector3.FromFloatsToRef(data[6], data[7], data[8], this.l10);\r\n        Vector3.FromFloatsToRef(data[9], data[10], data[11], this.l11);\r\n        Vector3.FromFloatsToRef(data[12], data[13], data[14], this.l2_2);\r\n        Vector3.FromFloatsToRef(data[15], data[16], data[17], this.l2_1);\r\n        Vector3.FromFloatsToRef(data[18], data[19], data[20], this.l20);\r\n        Vector3.FromFloatsToRef(data[21], data[22], data[23], this.l21);\r\n        Vector3.FromFloatsToRef(data[24], data[25], data[26], this.l22);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Constructs a spherical harmonics from an array.\r\n     * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)\r\n     * @returns the spherical harmonics\r\n     */\r\n    public static FromArray(data: ArrayLike<ArrayLike<number>>): SphericalHarmonics {\r\n        const sh = new SphericalHarmonics();\r\n        return sh.updateFromArray(data);\r\n    }\r\n\r\n    // Keep for references.\r\n    /**\r\n     * Gets the spherical harmonics from polynomial\r\n     * @param polynomial the spherical polynomial\r\n     * @returns the spherical harmonics\r\n     */\r\n    public static FromPolynomial(polynomial: SphericalPolynomial): SphericalHarmonics {\r\n        const result = new SphericalHarmonics();\r\n\r\n        result.l00 = polynomial.xx.scale(0.376127).add(polynomial.yy.scale(0.376127)).add(polynomial.zz.scale(0.376126));\r\n        result.l1_1 = polynomial.y.scale(0.977204);\r\n        result.l10 = polynomial.z.scale(0.977204);\r\n        result.l11 = polynomial.x.scale(0.977204);\r\n        result.l2_2 = polynomial.xy.scale(1.16538);\r\n        result.l2_1 = polynomial.yz.scale(1.16538);\r\n        result.l20 = polynomial.zz.scale(1.34567).subtract(polynomial.xx.scale(0.672834)).subtract(polynomial.yy.scale(0.672834));\r\n        result.l21 = polynomial.zx.scale(1.16538);\r\n        result.l22 = polynomial.xx.scale(1.16538).subtract(polynomial.yy.scale(1.16538));\r\n\r\n        result.l1_1.scaleInPlace(-1);\r\n        result.l11.scaleInPlace(-1);\r\n        result.l2_1.scaleInPlace(-1);\r\n        result.l21.scaleInPlace(-1);\r\n\r\n        result.scaleInPlace(Math.PI);\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\n/**\r\n * Class representing spherical polynomial coefficients to the 3rd degree\r\n */\r\nexport class SphericalPolynomial {\r\n    private _harmonics: Nullable<SphericalHarmonics>;\r\n\r\n    /**\r\n     * The spherical harmonics used to create the polynomials.\r\n     */\r\n    public get preScaledHarmonics(): SphericalHarmonics {\r\n        if (!this._harmonics) {\r\n            this._harmonics = SphericalHarmonics.FromPolynomial(this);\r\n        }\r\n        if (!this._harmonics.preScaled) {\r\n            this._harmonics.preScaleForRendering();\r\n        }\r\n        return this._harmonics;\r\n    }\r\n\r\n    /**\r\n     * The x coefficients of the spherical polynomial\r\n     */\r\n    public x: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The y coefficients of the spherical polynomial\r\n     */\r\n    public y: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The z coefficients of the spherical polynomial\r\n     */\r\n    public z: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The xx coefficients of the spherical polynomial\r\n     */\r\n    public xx: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The yy coefficients of the spherical polynomial\r\n     */\r\n    public yy: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The zz coefficients of the spherical polynomial\r\n     */\r\n    public zz: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The xy coefficients of the spherical polynomial\r\n     */\r\n    public xy: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The yz coefficients of the spherical polynomial\r\n     */\r\n    public yz: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * The zx coefficients of the spherical polynomial\r\n     */\r\n    public zx: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Adds an ambient color to the spherical polynomial\r\n     * @param color the color to add\r\n     */\r\n    public addAmbient(color: Color3): void {\r\n        TmpVectors.Vector3[0].copyFromFloats(color.r, color.g, color.b);\r\n        const colorVector = TmpVectors.Vector3[0];\r\n        this.xx.addInPlace(colorVector);\r\n        this.yy.addInPlace(colorVector);\r\n        this.zz.addInPlace(colorVector);\r\n    }\r\n\r\n    /**\r\n     * Scales the spherical polynomial by the given amount\r\n     * @param scale the amount to scale\r\n     */\r\n    public scaleInPlace(scale: number) {\r\n        this.x.scaleInPlace(scale);\r\n        this.y.scaleInPlace(scale);\r\n        this.z.scaleInPlace(scale);\r\n        this.xx.scaleInPlace(scale);\r\n        this.yy.scaleInPlace(scale);\r\n        this.zz.scaleInPlace(scale);\r\n        this.yz.scaleInPlace(scale);\r\n        this.zx.scaleInPlace(scale);\r\n        this.xy.scaleInPlace(scale);\r\n    }\r\n\r\n    /**\r\n     * Updates the spherical polynomial from harmonics\r\n     * @param harmonics the spherical harmonics\r\n     * @returns the spherical polynomial\r\n     */\r\n    public updateFromHarmonics(harmonics: SphericalHarmonics): SphericalPolynomial {\r\n        this._harmonics = harmonics;\r\n\r\n        this.x.copyFrom(harmonics.l11);\r\n        this.x.scaleInPlace(1.02333).scaleInPlace(-1);\r\n        this.y.copyFrom(harmonics.l1_1);\r\n        this.y.scaleInPlace(1.02333).scaleInPlace(-1);\r\n        this.z.copyFrom(harmonics.l10);\r\n        this.z.scaleInPlace(1.02333);\r\n\r\n        this.xx.copyFrom(harmonics.l00);\r\n        TmpVectors.Vector3[0].copyFrom(harmonics.l20).scaleInPlace(0.247708);\r\n        TmpVectors.Vector3[1].copyFrom(harmonics.l22).scaleInPlace(0.429043);\r\n        this.xx.scaleInPlace(0.886277).subtractInPlace(TmpVectors.Vector3[0]).addInPlace(TmpVectors.Vector3[1]);\r\n        this.yy.copyFrom(harmonics.l00);\r\n        this.yy.scaleInPlace(0.886277).subtractInPlace(TmpVectors.Vector3[0]).subtractInPlace(TmpVectors.Vector3[1]);\r\n        this.zz.copyFrom(harmonics.l00);\r\n        TmpVectors.Vector3[0].copyFrom(harmonics.l20).scaleInPlace(0.495417);\r\n        this.zz.scaleInPlace(0.886277).addInPlace(TmpVectors.Vector3[0]);\r\n\r\n        this.yz.copyFrom(harmonics.l2_1);\r\n        this.yz.scaleInPlace(0.858086).scaleInPlace(-1);\r\n        this.zx.copyFrom(harmonics.l21);\r\n        this.zx.scaleInPlace(0.858086).scaleInPlace(-1);\r\n        this.xy.copyFrom(harmonics.l2_2);\r\n        this.xy.scaleInPlace(0.858086);\r\n\r\n        this.scaleInPlace(1.0 / Math.PI);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the spherical polynomial from harmonics\r\n     * @param harmonics the spherical harmonics\r\n     * @returns the spherical polynomial\r\n     */\r\n    public static FromHarmonics(harmonics: SphericalHarmonics): SphericalPolynomial {\r\n        const result = new SphericalPolynomial();\r\n        return result.updateFromHarmonics(harmonics);\r\n    }\r\n\r\n    /**\r\n     * Constructs a spherical polynomial from an array.\r\n     * @param data defines the 9x3 coefficients (x, y, z, xx, yy, zz, yz, zx, xy)\r\n     * @returns the spherical polynomial\r\n     */\r\n    public static FromArray(data: ArrayLike<ArrayLike<number>>): SphericalPolynomial {\r\n        const sp = new SphericalPolynomial();\r\n        Vector3.FromArrayToRef(data[0], 0, sp.x);\r\n        Vector3.FromArrayToRef(data[1], 0, sp.y);\r\n        Vector3.FromArrayToRef(data[2], 0, sp.z);\r\n        Vector3.FromArrayToRef(data[3], 0, sp.xx);\r\n        Vector3.FromArrayToRef(data[4], 0, sp.yy);\r\n        Vector3.FromArrayToRef(data[5], 0, sp.zz);\r\n        Vector3.FromArrayToRef(data[6], 0, sp.yz);\r\n        Vector3.FromArrayToRef(data[7], 0, sp.zx);\r\n        Vector3.FromArrayToRef(data[8], 0, sp.xy);\r\n        return sp;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { InternalTextureSource, InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Constants } from \"../constants\";\r\nimport { SphericalPolynomial } from \"core/Maths/sphericalPolynomial.pure\";\r\nimport { BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\r\nimport { type DDSInfo } from \"core/Misc/dds.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginePrefilteredCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginePrefilteredCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.createPrefilteredCubeTexture = function (\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        lodScale: number,\r\n        lodOffset: number,\r\n        onLoad: Nullable<(internalTexture: Nullable<InternalTexture>) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials: boolean = true,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        const callbackAsync = async (loadData: any) => {\r\n            if (!loadData) {\r\n                if (onLoad) {\r\n                    onLoad(null);\r\n                }\r\n                return;\r\n            }\r\n\r\n            const texture = loadData.texture as InternalTexture;\r\n            if (!createPolynomials) {\r\n                texture._sphericalPolynomial = texture._sphericalPolynomial ?? new SphericalPolynomial();\r\n            } else if (loadData.info.sphericalPolynomial) {\r\n                texture._sphericalPolynomial = loadData.info.sphericalPolynomial;\r\n            }\r\n            texture._source = InternalTextureSource.CubePrefiltered;\r\n\r\n            if (this.getCaps().textureLOD) {\r\n                // Do not add extra process if texture lod is supported.\r\n                if (onLoad) {\r\n                    onLoad(texture);\r\n                }\r\n                return;\r\n            }\r\n\r\n            const mipSlices = 3;\r\n\r\n            const gl = this._gl;\r\n            const width = loadData.width;\r\n            if (!width) {\r\n                return;\r\n            }\r\n\r\n            const { DDSTools } = await import(\"core/Misc/dds.pure\");\r\n\r\n            const textures: BaseTexture[] = [];\r\n            for (let i = 0; i < mipSlices; i++) {\r\n                //compute LOD from even spacing in smoothness (matching shader calculation)\r\n                const smoothness = i / (mipSlices - 1);\r\n                const roughness = 1 - smoothness;\r\n\r\n                const minLODIndex = lodOffset; // roughness = 0\r\n                const maxLODIndex = Math.log2(width) * lodScale + lodOffset; // roughness = 1\r\n\r\n                const lodIndex = minLODIndex + (maxLODIndex - minLODIndex) * roughness;\r\n                const mipmapIndex = Math.round(Math.min(Math.max(lodIndex, 0), maxLODIndex));\r\n\r\n                const glTextureFromLod = new InternalTexture(this, InternalTextureSource.Temp);\r\n                glTextureFromLod.type = texture.type;\r\n                glTextureFromLod.format = texture.format;\r\n                glTextureFromLod.width = Math.pow(2, Math.max(Math.log2(width) - mipmapIndex, 0));\r\n                glTextureFromLod.height = glTextureFromLod.width;\r\n                glTextureFromLod.isCube = true;\r\n                glTextureFromLod._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                glTextureFromLod._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, glTextureFromLod, true);\r\n\r\n                glTextureFromLod.samplingMode = Constants.TEXTURE_LINEAR_LINEAR;\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n                if (loadData.isDDS) {\r\n                    const info: DDSInfo = loadData.info;\r\n                    const data: any = loadData.data;\r\n                    this._unpackFlipY(info.isCompressed);\r\n\r\n                    DDSTools.UploadDDSLevels(this, glTextureFromLod, data, info, true, 6, mipmapIndex);\r\n                } else {\r\n                    Logger.Warn(\"DDS is the only prefiltered cube map supported so far.\");\r\n                }\r\n\r\n                this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n\r\n                // Wrap in a base texture for easy binding.\r\n                const lodTexture = new BaseTexture(scene);\r\n                lodTexture._isCube = true;\r\n                lodTexture._texture = glTextureFromLod;\r\n\r\n                glTextureFromLod.isReady = true;\r\n                textures.push(lodTexture);\r\n            }\r\n\r\n            texture._lodTextureHigh = textures[2];\r\n            texture._lodTextureMid = textures[1];\r\n            texture._lodTextureLow = textures[0];\r\n\r\n            if (onLoad) {\r\n                onLoad(texture);\r\n            }\r\n        };\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n        return this.createCubeTexture(\r\n            rootUrl,\r\n            scene,\r\n            null,\r\n            false,\r\n            callbackAsync,\r\n            onError,\r\n            format,\r\n            forcedExtension,\r\n            createPolynomials,\r\n            lodScale,\r\n            lodOffset,\r\n            null,\r\n            undefined,\r\n            false,\r\n            buffer\r\n        );\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FloatArray, type Nullable } from \"../../types\";\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { WebGLDataBuffer } from \"../../Meshes/WebGL/webGLDataBuffer\";\r\nimport { type IPipelineContext } from \"../IPipelineContext\";\r\nimport { type WebGLPipelineContext } from \"../WebGL/webGLPipelineContext\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for engineUniformBuffer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEngineUniformBuffer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.createUniformBuffer = function (elements: FloatArray, _label?: string): DataBuffer {\r\n        const ubo = this._gl.createBuffer();\r\n\r\n        if (!ubo) {\r\n            throw new Error(\"Unable to create uniform buffer\");\r\n        }\r\n        const result = new WebGLDataBuffer(ubo);\r\n\r\n        this.bindUniformBuffer(result);\r\n\r\n        if (elements instanceof Float32Array) {\r\n            this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.STATIC_DRAW);\r\n        } else {\r\n            this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(elements), this._gl.STATIC_DRAW);\r\n        }\r\n\r\n        this.bindUniformBuffer(null);\r\n\r\n        result.references = 1;\r\n        return result;\r\n    };\r\n\r\n    ThinEngine.prototype.createDynamicUniformBuffer = function (elements: FloatArray, _label?: string): DataBuffer {\r\n        const ubo = this._gl.createBuffer();\r\n\r\n        if (!ubo) {\r\n            throw new Error(\"Unable to create dynamic uniform buffer\");\r\n        }\r\n\r\n        const result = new WebGLDataBuffer(ubo);\r\n        this.bindUniformBuffer(result);\r\n\r\n        if (elements instanceof Float32Array) {\r\n            this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.DYNAMIC_DRAW);\r\n        } else {\r\n            this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(elements), this._gl.DYNAMIC_DRAW);\r\n        }\r\n\r\n        this.bindUniformBuffer(null);\r\n\r\n        result.references = 1;\r\n        return result;\r\n    };\r\n\r\n    ThinEngine.prototype.updateUniformBuffer = function (uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void {\r\n        this.bindUniformBuffer(uniformBuffer);\r\n\r\n        if (offset === undefined) {\r\n            offset = 0;\r\n        }\r\n\r\n        if (count === undefined) {\r\n            if (elements instanceof Float32Array) {\r\n                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, <Float32Array>elements);\r\n            } else {\r\n                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, new Float32Array(elements));\r\n            }\r\n        } else {\r\n            if (elements instanceof Float32Array) {\r\n                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, elements.subarray(offset, offset + count));\r\n            } else {\r\n                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, new Float32Array(elements).subarray(offset, offset + count));\r\n            }\r\n        }\r\n\r\n        this.bindUniformBuffer(null);\r\n    };\r\n\r\n    ThinEngine.prototype.bindUniformBuffer = function (buffer: Nullable<DataBuffer>): void {\r\n        this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer ? buffer.underlyingResource : null);\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    ThinEngine.prototype.bindUniformBufferBase = function (buffer: DataBuffer, location: number, name: string): void {\r\n        this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer ? buffer.underlyingResource : null);\r\n    };\r\n\r\n    ThinEngine.prototype.bindUniformBlock = function (pipelineContext: IPipelineContext, blockName: string, index: number): void {\r\n        const program = (pipelineContext as WebGLPipelineContext).program!;\r\n\r\n        const uniformLocation = this._gl.getUniformBlockIndex(program, blockName);\r\n\r\n        if (uniformLocation !== 0xffffffff) {\r\n            this._gl.uniformBlockBinding(program, uniformLocation, index);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { IsWindowObjectExist } from \"../../Misc/domManagement\";\r\nimport { type ILoadingScreen } from \"../../Loading/loadingScreen.pure\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineLoadingScreen.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineLoadingScreen(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.displayLoadingUI = function (): void {\r\n        if (!IsWindowObjectExist()) {\r\n            return;\r\n        }\r\n        const loadingScreen = this.loadingScreen;\r\n        if (loadingScreen) {\r\n            loadingScreen.displayLoadingUI();\r\n        }\r\n    };\r\n\r\n    AbstractEngine.prototype.hideLoadingUI = function (): void {\r\n        if (!IsWindowObjectExist()) {\r\n            return;\r\n        }\r\n        const loadingScreen = this._loadingScreen;\r\n        if (loadingScreen) {\r\n            loadingScreen.hideLoadingUI();\r\n        }\r\n    };\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"loadingScreen\", {\r\n        get: function (this: AbstractEngine) {\r\n            if (!this._loadingScreen && this._renderingCanvas) {\r\n                this._loadingScreen = AbstractEngine.DefaultLoadingScreenFactory(this._renderingCanvas);\r\n            }\r\n            return this._loadingScreen;\r\n        },\r\n        set: function (this: AbstractEngine, value: ILoadingScreen) {\r\n            this._loadingScreen = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"loadingUIText\", {\r\n        set: function (this: AbstractEngine, value: string) {\r\n            this.loadingScreen.loadingUIText = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"loadingUIBackgroundColor\", {\r\n        set: function (this: AbstractEngine, value: string) {\r\n            this.loadingScreen.loadingUIBackgroundColor = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../constants\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineStates.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineStates(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.getInputElement = function (): Nullable<HTMLElement> {\r\n        return this._renderingCanvas;\r\n    };\r\n\r\n    AbstractEngine.prototype.getDepthFunction = function (): Nullable<number> {\r\n        return this._depthCullingState.depthFunc;\r\n    };\r\n\r\n    AbstractEngine.prototype.setDepthFunction = function (depthFunc: number) {\r\n        this._depthCullingState.depthFunc = depthFunc;\r\n    };\r\n\r\n    AbstractEngine.prototype.setDepthFunctionToGreater = function (): void {\r\n        this.setDepthFunction(Constants.GREATER);\r\n    };\r\n\r\n    AbstractEngine.prototype.setDepthFunctionToGreaterOrEqual = function (): void {\r\n        this.setDepthFunction(Constants.GEQUAL);\r\n    };\r\n\r\n    AbstractEngine.prototype.setDepthFunctionToLess = function (): void {\r\n        this.setDepthFunction(Constants.LESS);\r\n    };\r\n\r\n    AbstractEngine.prototype.setDepthFunctionToLessOrEqual = function (): void {\r\n        this.setDepthFunction(Constants.LEQUAL);\r\n    };\r\n\r\n    AbstractEngine.prototype.getDepthWrite = function (): boolean {\r\n        return this._depthCullingState.depthMask;\r\n    };\r\n\r\n    AbstractEngine.prototype.setDepthWrite = function (enable: boolean): void {\r\n        this._depthCullingState.depthMask = enable;\r\n    };\r\n\r\n    AbstractEngine.prototype.setAlphaConstants = function (r: number, g: number, b: number, a: number): void {\r\n        this._alphaState.setAlphaBlendConstants(r, g, b, a);\r\n    };\r\n\r\n    AbstractEngine.prototype.getAlphaMode = function (targetIndex = 0): number {\r\n        return this._alphaMode[targetIndex];\r\n    };\r\n\r\n    AbstractEngine.prototype.getAlphaEquation = function (targetIndex = 0): number {\r\n        return this._alphaEquation[targetIndex];\r\n    };\r\n}\r\n","import { AbstractEngine } from \"../abstractEngine.pure\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineStencil.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineStencil(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.getStencilBuffer = function (): boolean {\r\n        return this._stencilState.stencilTest;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilBuffer = function (enable: boolean): void {\r\n        this._stencilState.stencilTest = enable;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilMask = function (): number {\r\n        return this._stencilState.stencilMask;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilMask = function (mask: number): void {\r\n        this._stencilState.stencilMask = mask;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilFunction = function (): number {\r\n        return this._stencilState.stencilFunc;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilBackFunction = function (): number {\r\n        return this._stencilState.stencilBackFunc;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilFunctionReference = function (): number {\r\n        return this._stencilState.stencilFuncRef;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilFunctionMask = function (): number {\r\n        return this._stencilState.stencilFuncMask;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilFunction = function (stencilFunc: number) {\r\n        this._stencilState.stencilFunc = stencilFunc;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilBackFunction = function (stencilFunc: number) {\r\n        this._stencilState.stencilBackFunc = stencilFunc;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilFunctionReference = function (reference: number): void {\r\n        this._stencilState.stencilFuncRef = reference;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilFunctionMask = function (mask: number): void {\r\n        this._stencilState.stencilFuncMask = mask;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilOperationFail = function (): number {\r\n        return this._stencilState.stencilOpStencilFail;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilBackOperationFail = function (): number {\r\n        return this._stencilState.stencilBackOpStencilFail;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilOperationDepthFail = function (): number {\r\n        return this._stencilState.stencilOpDepthFail;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilBackOperationDepthFail = function (): number {\r\n        return this._stencilState.stencilBackOpDepthFail;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilOperationPass = function (): number {\r\n        return this._stencilState.stencilOpStencilDepthPass;\r\n    };\r\n\r\n    AbstractEngine.prototype.getStencilBackOperationPass = function (): number {\r\n        return this._stencilState.stencilBackOpStencilDepthPass;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilOperationFail = function (operation: number): void {\r\n        this._stencilState.stencilOpStencilFail = operation;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilBackOperationFail = function (operation: number): void {\r\n        this._stencilState.stencilBackOpStencilFail = operation;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilOperationDepthFail = function (operation: number): void {\r\n        this._stencilState.stencilOpDepthFail = operation;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilBackOperationDepthFail = function (operation: number): void {\r\n        this._stencilState.stencilBackOpDepthFail = operation;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilOperationPass = function (operation: number): void {\r\n        this._stencilState.stencilOpStencilDepthPass = operation;\r\n    };\r\n\r\n    AbstractEngine.prototype.setStencilBackOperationPass = function (operation: number): void {\r\n        this._stencilState.stencilBackOpStencilDepthPass = operation;\r\n    };\r\n\r\n    AbstractEngine.prototype.cacheStencilState = function (): void {\r\n        this._cachedStencilBuffer = this.getStencilBuffer();\r\n        this._cachedStencilFunction = this.getStencilFunction();\r\n        this._cachedStencilMask = this.getStencilMask();\r\n        this._cachedStencilOperationPass = this.getStencilOperationPass();\r\n        this._cachedStencilOperationFail = this.getStencilOperationFail();\r\n        this._cachedStencilOperationDepthFail = this.getStencilOperationDepthFail();\r\n        this._cachedStencilReference = this.getStencilFunctionReference();\r\n    };\r\n\r\n    AbstractEngine.prototype.restoreStencilState = function (): void {\r\n        this.setStencilFunction(this._cachedStencilFunction);\r\n        this.setStencilMask(this._cachedStencilMask);\r\n        this.setStencilBuffer(this._cachedStencilBuffer);\r\n        this.setStencilOperationPass(this._cachedStencilOperationPass);\r\n        this.setStencilOperationFail(this._cachedStencilOperationFail);\r\n        this.setStencilOperationDepthFail(this._cachedStencilOperationDepthFail);\r\n        this.setStencilFunctionReference(this._cachedStencilReference);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IOfflineProvider } from \"../../Offline/IOfflineProvider\";\r\nimport { AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { RegisterFileTools } from \"../../Misc/fileTools.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineLoadFile.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineLoadFile(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // File loading requires the fileTools implementation (LoadFile / LoadImage).\r\n    // These are injected lazily through EngineFunctionContext so that engines\r\n    // that never load files (e.g. the minimal thin engine) do not force-link\r\n    // fileTools. Any consumer of the loadFile extension — the full Engine\r\n    // side-effect wrapper and RegisterStandardEngineExtensions — reaches this\r\n    // registration, which wires the fileTools loaders in.\r\n    RegisterFileTools();\r\n\r\n    AbstractEngine.prototype._loadFileAsync = async function (url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean): Promise<any> {\r\n        return await new Promise<string | ArrayBuffer>((resolve, reject) => {\r\n            this._loadFile(\r\n                url,\r\n                (data) => {\r\n                    resolve(data);\r\n                },\r\n                undefined,\r\n                offlineProvider,\r\n                useArrayBuffer,\r\n                (request, exception) => {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(exception);\r\n                }\r\n            );\r\n        });\r\n    };\r\n}\r\n","/* eslint-disable github/no-then */\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst RegisteredTextureLoaders = new Map<string, (mimeType?: string) => IInternalTextureLoader | Promise<IInternalTextureLoader>>();\r\n\r\n/**\r\n * Registers a texture loader.\r\n * If a loader for the extension exists in the registry, it will be replaced.\r\n * @param extension The name of the loader extension.\r\n * @param loaderFactory The factory function that creates the loader extension.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function registerTextureLoader(extension: string, loaderFactory: (mimeType?: string) => IInternalTextureLoader | Promise<IInternalTextureLoader>): void {\r\n    if (unregisterTextureLoader(extension)) {\r\n        Logger.Warn(`Extension with the name '${extension}' already exists`);\r\n    }\r\n    RegisteredTextureLoaders.set(extension, loaderFactory);\r\n}\r\n\r\n/**\r\n * Unregisters a texture loader.\r\n * @param extension The name of the loader extension.\r\n * @returns A boolean indicating whether the extension has been unregistered\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function unregisterTextureLoader(extension: string): boolean {\r\n    return RegisteredTextureLoaders.delete(extension);\r\n}\r\n\r\n/**\r\n * Function used to get the correct texture loader for a specific extension.\r\n * @param extension defines the file extension of the file being loaded\r\n * @param mimeType defines the optional mime type of the file being loaded\r\n * @returns the IInternalTextureLoader or null if it wasn't found\r\n */\r\nexport function _GetCompatibleTextureLoader(extension: string, mimeType?: string): Nullable<Promise<IInternalTextureLoader>> {\r\n    if (mimeType === \"image/ktx\" || mimeType === \"image/ktx2\") {\r\n        extension = \".ktx\";\r\n    }\r\n    if (!RegisteredTextureLoaders.has(extension)) {\r\n        if (extension.endsWith(\".ies\")) {\r\n            registerTextureLoader(\".ies\", async () => await import(\"./iesTextureLoader\").then((module) => new module._IESTextureLoader()));\r\n        }\r\n        if (extension.endsWith(\".dds\")) {\r\n            registerTextureLoader(\".dds\", async () => await import(\"./ddsTextureLoader\").then((module) => new module._DDSTextureLoader()));\r\n        }\r\n        if (extension.endsWith(\".basis\")) {\r\n            registerTextureLoader(\".basis\", async () => await import(\"./basisTextureLoader\").then((module) => new module._BasisTextureLoader()));\r\n        }\r\n        if (extension.endsWith(\".env\")) {\r\n            registerTextureLoader(\".env\", async () => await import(\"./envTextureLoader\").then((module) => new module._ENVTextureLoader()));\r\n        }\r\n        if (extension.endsWith(\".hdr\")) {\r\n            registerTextureLoader(\".hdr\", async () => await import(\"./hdrTextureLoader\").then((module) => new module._HDRTextureLoader()));\r\n        }\r\n        // The \".ktx2\" file extension is still up for debate: https://github.com/KhronosGroup/KTX-Specification/issues/18\r\n        if (extension.endsWith(\".ktx\") || extension.endsWith(\".ktx2\")) {\r\n            registerTextureLoader(\".ktx\", async () => await import(\"./ktxTextureLoader\").then((module) => new module._KTXTextureLoader()));\r\n            registerTextureLoader(\".ktx2\", async () => await import(\"./ktxTextureLoader\").then((module) => new module._KTXTextureLoader()));\r\n        }\r\n        if (extension.endsWith(\".tga\")) {\r\n            registerTextureLoader(\".tga\", async () => await import(\"./tgaTextureLoader\").then((module) => new module._TGATextureLoader()));\r\n        }\r\n        if (extension.endsWith(\".exr\")) {\r\n            registerTextureLoader(\".exr\", async () => await import(\"./exrTextureLoader\").then((module) => new module._ExrTextureLoader()));\r\n        }\r\n    }\r\n    const registered = RegisteredTextureLoaders.get(extension);\r\n    return registered ? Promise.resolve(registered(mimeType)) : null;\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { _GetCompatibleTextureLoader } from \"../../Materials/Textures/Loaders/textureLoaderManager\";\nimport { AbstractEngine } from \"../abstractEngine.pure\";\n\nlet _Registered = false;\n\n/**\n * Registers the texture loader implementation on AbstractEngine.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterAbstractEngineTextureLoaders(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    AbstractEngine.GetCompatibleTextureLoader = _GetCompatibleTextureLoader;\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinEngine } from \"./thinEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Registers the WebGL scissor implementation on ThinEngine.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterThinEngineScissor(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.enableScissor = function (x: number, y: number, width: number, height: number): void {\r\n        const gl = this._gl;\r\n\r\n        // Change state\r\n        gl.enable(gl.SCISSOR_TEST);\r\n        gl.scissor(x, y, width, height);\r\n    };\r\n\r\n    ThinEngine.prototype.disableScissor = function (): void {\r\n        const gl = this._gl;\r\n\r\n        gl.disable(gl.SCISSOR_TEST);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Nullable, type FloatArray, type IndicesArray } from \"../types\";\r\nimport { Engine } from \"../Engines/engine.pure\";\r\nimport { type RenderTargetCreationOptions } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { type VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Constants } from \"./constants\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type IColor4Like, type IViewportLike } from \"../Maths/math.like\";\r\nimport { type ISceneLike } from \"./abstractEngine.pure\";\r\nimport { PerformanceConfigurator } from \"./performanceConfigurator\";\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { type IStencilState } from \"../States/IStencilState\";\r\nimport { IsWrapper } from \"../Materials/drawWrapper.functions\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const global: any;\r\n\r\n/**\r\n * Options to create the null engine\r\n */\r\nexport class NullEngineOptions {\r\n    /**\r\n     * Render width (Default: 512)\r\n     */\r\n    public renderWidth = 512;\r\n    /**\r\n     * Render height (Default: 256)\r\n     */\r\n    public renderHeight = 256;\r\n\r\n    /**\r\n     * Texture size (Default: 512)\r\n     */\r\n    public textureSize = 512;\r\n\r\n    /**\r\n     * If delta time between frames should be constant\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     */\r\n    public deterministicLockstep = false;\r\n\r\n    /** Defines the seconds between each deterministic lock step */\r\n    timeStep?: number;\r\n\r\n    /**\r\n     * Maximum about of steps between frames (Default: 4)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     */\r\n    public lockstepMaxSteps = 4;\r\n\r\n    /**\r\n     * Make the matrix computations to be performed in 64 bits instead of 32 bits. False by default\r\n     */\r\n    useHighPrecisionMatrix?: boolean;\r\n\r\n    /**\r\n     * If supplied, the HTMLCanvasElement to use (e.g. as the inputElement)\r\n     */\r\n    renderingCanvas?: HTMLCanvasElement;\r\n\r\n    /**\r\n     * Enables headless multiview render-target support for CPU-side render-state tests. Does NOT\r\n     * emulate GPU multiview rendering.\r\n     *\r\n     * Enabling this also makes {@link NullEngine.supportsUniformBuffers} report true. The coupling is\r\n     * intentional and intrinsic, not an incidental side effect: the per-eye `viewProjectionR` matrix\r\n     * is carried ONLY by the multiview scene UBO, and `Scene` writes it only while that UBO is active\r\n     * (`useUbo`, which requires uniform-buffer support). It also mirrors real engines — multiview is\r\n     * an OVR_multiview2 / WebGL2 feature and WebGL2 always provides uniform buffers — so\r\n     * `enableMultiview` without uniform-buffer support is not a coherent state.\r\n     */\r\n    enableMultiview?: boolean;\r\n}\r\n\r\n/**\r\n * The null engine class provides support for headless version of babylon.js.\r\n * This can be used in server side scenario or for testing purposes\r\n */\r\nexport class NullEngine extends Engine {\r\n    private _options: NullEngineOptions;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the engine is running in deterministic lock step mode\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @returns true if engine is in deterministic lock step mode\r\n     */\r\n    public override isDeterministicLockStep(): boolean {\r\n        return this._options.deterministicLockstep;\r\n    }\r\n\r\n    /**\r\n     * Gets the max steps when engine is running in deterministic lock step\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep\r\n     * @returns the max steps\r\n     */\r\n    public override getLockstepMaxSteps(): number {\r\n        return this._options.lockstepMaxSteps;\r\n    }\r\n\r\n    /**\r\n     * Gets the current hardware scaling level.\r\n     * By default the hardware scaling level is computed from the window device ratio.\r\n     * if level = 1 then the engine will render at the exact resolution of the canvas. If level = 0.5 then the engine will render at twice the size of the canvas.\r\n     * @returns a number indicating the current hardware scaling level\r\n     */\r\n    public override getHardwareScalingLevel(): number {\r\n        return 1.0;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the engine supports uniform buffers.\r\n     * Reports true when {@link NullEngineOptions.enableMultiview} is set: the multiview scene UBO is\r\n     * the only path that uploads the per-eye `viewProjectionR` matrix, so multiview is meaningless\r\n     * without uniform-buffer support. This mirrors real engines, where multiview (OVR_multiview2)\r\n     * implies WebGL2, which always supports uniform buffers.\r\n     */\r\n    public override get supportsUniformBuffers(): boolean {\r\n        // The base computation (`this.webGLVersion > 1 && !this.disableUniformBuffers`) is inlined rather\r\n        // than read through `super.supportsUniformBuffers`: ES5 downleveling of `super` inside a decorated\r\n        // accessor mis-compiles to `undefined` in the shipped UMD bundle. See the `babylonjs/no-super-in-accessor`\r\n        // lint rule.\r\n        return !!this._options?.enableMultiview || (this.webGLVersion > 1 && !this.disableUniformBuffers);\r\n    }\r\n\r\n    public constructor(options: NullEngineOptions = new NullEngineOptions()) {\r\n        super(null);\r\n\r\n        if (options.deterministicLockstep === undefined) {\r\n            options.deterministicLockstep = false;\r\n        }\r\n\r\n        if (options.timeStep !== undefined) {\r\n            this._timeStep = options.timeStep;\r\n        }\r\n\r\n        if (options.lockstepMaxSteps === undefined) {\r\n            options.lockstepMaxSteps = 4;\r\n        }\r\n\r\n        this._options = options;\r\n\r\n        PerformanceConfigurator.SetMatrixPrecision(!!options.useHighPrecisionMatrix);\r\n\r\n        // Init caps\r\n        // We consider we are on a webgl1 capable device\r\n\r\n        this._caps = {\r\n            maxTexturesImageUnits: 16,\r\n            maxVertexTextureImageUnits: 16,\r\n            maxCombinedTexturesImageUnits: 32,\r\n            maxTextureSize: 512,\r\n            maxCubemapTextureSize: 512,\r\n            maxDrawBuffers: 0,\r\n            maxRenderTextureSize: 512,\r\n            maxVertexAttribs: 16,\r\n            maxVaryingVectors: 16,\r\n            maxFragmentUniformVectors: 16,\r\n            maxVertexUniformVectors: 16,\r\n            shaderFloatPrecision: 10, // Minimum precision for mediump floats WebGL 1\r\n            standardDerivatives: false,\r\n            astc: null,\r\n            pvrtc: null,\r\n            etc1: null,\r\n            etc2: null,\r\n            bptc: null,\r\n            maxAnisotropy: 0,\r\n            uintIndices: false,\r\n            fragmentDepthSupported: false,\r\n            highPrecisionShaderSupported: true,\r\n            colorBufferFloat: false,\r\n            blendFloat: false,\r\n            supportFloatTexturesResolve: false,\r\n            rg11b10ufColorRenderable: false,\r\n            textureFloat: false,\r\n            textureFloatLinearFiltering: false,\r\n            textureFloatRender: false,\r\n            textureHalfFloat: false,\r\n            textureHalfFloatLinearFiltering: false,\r\n            textureHalfFloatRender: false,\r\n            textureLOD: false,\r\n            texelFetch: false,\r\n            drawBuffersExtension: false,\r\n            depthTextureExtension: false,\r\n            vertexArrayObject: false,\r\n            instancedArrays: false,\r\n            supportOcclusionQuery: false,\r\n            canUseTimestampForTimerQuery: false,\r\n            maxMSAASamples: 1,\r\n            blendMinMax: false,\r\n            canUseGLInstanceID: false,\r\n            canUseGLVertexID: false,\r\n            supportComputeShaders: false,\r\n            supportSRGBBuffers: false,\r\n            supportTransformFeedbacks: false,\r\n            textureMaxLevel: false,\r\n            texture2DArrayMaxLayerCount: 128,\r\n            disableMorphTargetTexture: false,\r\n            textureNorm16: false,\r\n            blendParametersPerTarget: false,\r\n            dualSourceBlending: false,\r\n            supportReadWriteStorageTextures: false,\r\n        };\r\n\r\n        if (options.enableMultiview) {\r\n            this._caps.multiview = { framebufferTextureMultiviewOVR: () => {} };\r\n        }\r\n\r\n        this._features = {\r\n            forceBitmapOverHTMLImageElement: false,\r\n            supportRenderAndCopyToLodForFloatTextures: false,\r\n            supportDepthStencilTexture: false,\r\n            supportShadowSamplers: false,\r\n            uniformBufferHardCheckMatrix: false,\r\n            allowTexturePrefiltering: false,\r\n            trackUbosInFrame: false,\r\n            checkUbosContentBeforeUpload: false,\r\n            supportCSM: false,\r\n            basisNeedsPOT: false,\r\n            support3DTextures: false,\r\n            needTypeSuffixInShaderConstants: false,\r\n            supportMSAA: false,\r\n            supportSSAO2: false,\r\n            supportIBLShadows: false,\r\n            supportExtendedTextureFormats: false,\r\n            supportSwitchCaseInShader: false,\r\n            supportSyncTextureRead: false,\r\n            needsInvertingBitmap: false,\r\n            useUBOBindingCache: false,\r\n            needShaderCodeInlining: false,\r\n            needToAlwaysBindUniformBuffers: false,\r\n            supportRenderPasses: true,\r\n            supportSpriteInstancing: false,\r\n            forceVertexBufferStrideAndOffsetMultiple4Bytes: false,\r\n            _checkNonFloatVertexBuffersDontRecreatePipelineContext: false,\r\n        };\r\n\r\n        if (options.renderingCanvas) {\r\n            this._renderingCanvas = options.renderingCanvas;\r\n        }\r\n\r\n        Logger.Log(`Babylon.js v${Engine.Version} - Null engine`);\r\n\r\n        // Wrappers\r\n        const theCurrentGlobal = typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : window;\r\n        if (typeof URL === \"undefined\") {\r\n            theCurrentGlobal.URL = {\r\n                createObjectURL: function () {},\r\n                revokeObjectURL: function () {},\r\n            };\r\n        }\r\n        if (typeof Blob === \"undefined\") {\r\n            theCurrentGlobal.Blob = function () {};\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a vertex buffer\r\n     * @param vertices the data for the vertex buffer\r\n     * @returns the new WebGL static buffer\r\n     */\r\n    public override createVertexBuffer(vertices: FloatArray): DataBuffer {\r\n        const buffer = new DataBuffer();\r\n        buffer.references = 1;\r\n        return buffer;\r\n    }\r\n\r\n    /**\r\n     * Creates a new index buffer\r\n     * @param indices defines the content of the index buffer\r\n     * @returns a new webGL buffer\r\n     */\r\n    public override createIndexBuffer(indices: IndicesArray): DataBuffer {\r\n        const buffer = new DataBuffer();\r\n        buffer.references = 1;\r\n        return buffer;\r\n    }\r\n\r\n    /**\r\n     * Clear the current render buffer or the current render target (if any is set up)\r\n     * @param color defines the color to use\r\n     * @param backBuffer defines if the back buffer must be cleared\r\n     * @param depth defines if the depth buffer must be cleared\r\n     * @param stencil defines if the stencil buffer must be cleared\r\n     */\r\n    public override clear(color: IColor4Like, backBuffer: boolean, depth: boolean, stencil: boolean = false): void {}\r\n\r\n    /**\r\n     * Gets the current render width\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render width\r\n     */\r\n    public override getRenderWidth(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.width;\r\n        }\r\n\r\n        return this._options.renderWidth;\r\n    }\r\n\r\n    /**\r\n     * Gets the current render height\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render height\r\n     */\r\n    public override getRenderHeight(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.height;\r\n        }\r\n\r\n        return this._options.renderHeight;\r\n    }\r\n\r\n    /**\r\n     * Set the WebGL's viewport\r\n     * @param viewport defines the viewport element to be used\r\n     * @param requiredWidth defines the width required for rendering. If not provided the rendering canvas' width is used\r\n     * @param requiredHeight defines the height required for rendering. If not provided the rendering canvas' height is used\r\n     */\r\n    public override setViewport(viewport: IViewportLike, requiredWidth?: number, requiredHeight?: number): void {\r\n        this._cachedViewport = viewport;\r\n    }\r\n\r\n    /**\r\n     * Creates a uniform buffer.\r\n     * @param elements defines the content of the uniform buffer\r\n     * @returns a new data buffer\r\n     */\r\n    public override createUniformBuffer(elements: FloatArray): DataBuffer {\r\n        const buffer = new DataBuffer();\r\n        buffer.references = 1;\r\n        buffer.capacity = elements instanceof Array ? elements.length * Float32Array.BYTES_PER_ELEMENT : elements.byteLength;\r\n        return buffer;\r\n    }\r\n\r\n    /**\r\n     * Creates a dynamic uniform buffer.\r\n     * @param elements defines the content of the dynamic uniform buffer\r\n     * @returns a new data buffer\r\n     */\r\n    public override createDynamicUniformBuffer(elements: FloatArray): DataBuffer {\r\n        return this.createUniformBuffer(elements);\r\n    }\r\n\r\n    // NullEngine is headless: GPU-side uniform-buffer storage is intentionally not emulated, and that\r\n    // is correct rather than a contract gap. Babylon's UniformBuffer is write-only toward the engine —\r\n    // the source of truth is the JS-side Float32Array (UniformBuffer._bufferData, read via getData())\r\n    // plus Scene matrices (e.g. _transformMatrixR). Values reach the engine only through\r\n    // updateUniformBuffer() as a one-way push to the GPU; no Babylon codepath reads bytes back out of\r\n    // the engine's DataBuffer, so these no-ops cannot diverge from real-engine behavior for any\r\n    // CPU-observable state. supportsUniformBuffers must stay true (see the getter above) so\r\n    // UniformBuffer.useUbo remains on and updateMatrix() routes through _bufferData instead of the\r\n    // per-uniform Effect fallback.\r\n    /**\r\n     * Updates a uniform buffer.\r\n     * @param _uniformBuffer defines the target uniform buffer\r\n     * @param _elements defines the content to update\r\n     * @param _offset defines the offset in the uniform buffer where update should start\r\n     * @param _count defines the size of the data to update\r\n     */\r\n    public override updateUniformBuffer(_uniformBuffer: DataBuffer, _elements: FloatArray, _offset?: number, _count?: number): void {}\r\n\r\n    /**\r\n     * Binds a uniform buffer to the current draw context.\r\n     * @param _buffer defines the buffer to bind\r\n     * @param _location not used in NullEngine\r\n     * @param _name name of the uniform variable to bind\r\n     */\r\n    public override bindUniformBufferBase(_buffer: DataBuffer, _location: number, _name: string): void {}\r\n\r\n    /**\r\n     * Binds a uniform block to a specific index.\r\n     * @param _pipelineContext defines the pipeline context to use\r\n     * @param _blockName defines the block name\r\n     * @param _index defines the index where to bind the block\r\n     */\r\n    public override bindUniformBlock(_pipelineContext: IPipelineContext, _blockName: string, _index: number): void {}\r\n\r\n    public override createShaderProgram(\r\n        pipelineContext: IPipelineContext,\r\n        vertexCode: string,\r\n        fragmentCode: string,\r\n        defines: string,\r\n        context?: WebGLRenderingContext\r\n    ): WebGLProgram {\r\n        return {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            __SPECTOR_rebuildProgram: null,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the list of webGL uniform locations associated with a specific program based on a list of uniform names\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param uniformsNames defines the list of uniform names\r\n     * @returns an array of webGL uniform locations\r\n     */\r\n    public override getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[] {\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Gets the lsit of active attributes for a given webGL program\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param attributesNames defines the list of attribute names to get\r\n     * @returns an array of indices indicating the offset of each attribute\r\n     */\r\n    public override getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[] {\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Binds an effect to the webGL context\r\n     * @param effect defines the effect to bind\r\n     */\r\n    public override bindSamplers(effect: Effect): void {\r\n        this._currentEffect = null;\r\n    }\r\n\r\n    /**\r\n     * Activates an effect, making it the current one (ie. the one used for rendering)\r\n     * @param effect defines the effect to activate\r\n     */\r\n    public override enableEffect(effect: Nullable<Effect | DrawWrapper>): void {\r\n        effect = effect !== null && IsWrapper(effect) ? effect.effect : effect; // get only the effect, we don't need a Wrapper in the WebGL engine\r\n\r\n        this._currentEffect = effect as Nullable<Effect>;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        if (effect.onBind) {\r\n            effect.onBind(effect);\r\n        }\r\n        if (effect._onBindObservable) {\r\n            effect._onBindObservable.notifyObservers(effect);\r\n        }\r\n    }\r\n\r\n    public override setStateCullFaceType(cullBackFaces?: boolean, force?: boolean): void {}\r\n\r\n    /**\r\n     * Set various states to the webGL context\r\n     * @param culling defines culling state: true to enable culling, false to disable it\r\n     * @param zOffset defines the value to apply to zOffset (0 by default)\r\n     * @param force defines if states must be applied even if cache is up to date\r\n     * @param reverseSide defines if culling must be reversed (CCW if false, CW if true)\r\n     * @param cullBackFaces true to cull back faces, false to cull front faces (if culling is enabled)\r\n     * @param stencil stencil states to set\r\n     * @param zOffsetUnits defines the value to apply to zOffsetUnits (0 by default)\r\n     */\r\n    public override setState(\r\n        culling: boolean,\r\n        zOffset: number = 0,\r\n        force?: boolean,\r\n        reverseSide = false,\r\n        cullBackFaces?: boolean,\r\n        stencil?: IStencilState,\r\n        zOffsetUnits: number = 0\r\n    ): void {}\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setIntArray(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32 (stored as vec2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setIntArray2(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32 (stored as vec3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setIntArray3(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of int32 (stored as vec4)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of int32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setIntArray4(uniform: WebGLUniformLocation, array: Int32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of float32\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of float32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public setFloatArray(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of float32 (stored as vec2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of float32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public setFloatArray2(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of float32 (stored as vec3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of float32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public setFloatArray3(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of float32 (stored as vec4)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of float32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public setFloatArray4(uniform: WebGLUniformLocation, array: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setArray(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number (stored as vec2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setArray2(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number (stored as vec3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setArray3(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of number (stored as vec4)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param array defines the array of number to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setArray4(uniform: WebGLUniformLocation, array: number[]): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to an array of float32 (stored as matrices)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param matrices defines the array of float32 to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a matrix (3x3)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param matrix defines the Float32Array representing the 3x3 matrix to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a matrix (2x2)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param matrix defines the Float32Array representing the 2x2 matrix to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setMatrix2x2(uniform: WebGLUniformLocation, matrix: Float32Array): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a number (float)\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param value defines the float number to store\r\n     * @returns true if value was set\r\n     */\r\n    public override setFloat(uniform: WebGLUniformLocation, value: number): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a vec2\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @returns true if value was set\r\n     */\r\n    public override setFloat2(uniform: WebGLUniformLocation, x: number, y: number): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a vec3\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @returns true if value was set\r\n     */\r\n    public override setFloat3(uniform: WebGLUniformLocation, x: number, y: number, z: number): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a boolean\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param bool defines the boolean to store\r\n     * @returns true if value was set\r\n     */\r\n    public setBool(uniform: WebGLUniformLocation, bool: number): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Set the value of an uniform to a vec4\r\n     * @param uniform defines the webGL uniform location where to store the value\r\n     * @param x defines the 1st component of the value\r\n     * @param y defines the 2nd component of the value\r\n     * @param z defines the 3rd component of the value\r\n     * @param w defines the 4th component of the value\r\n     * @returns true if value was set\r\n     */\r\n    public override setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Sets the current alpha mode\r\n     * @param mode defines the mode to use (one of the Engine.ALPHA_XXX)\r\n     * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)\r\n     * @param targetIndex defines the index of the target to set the alpha mode for (default is 0)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering\r\n     */\r\n    public override setAlphaMode(mode: number, noDepthWriteChange: boolean = false, targetIndex = 0): void {\r\n        if (this._alphaMode[targetIndex] === mode) {\r\n            return;\r\n        }\r\n\r\n        this.alphaState.setAlphaBlend(mode !== Constants.ALPHA_DISABLE, 0);\r\n\r\n        if (!noDepthWriteChange) {\r\n            this.setDepthWrite(mode === Constants.ALPHA_DISABLE);\r\n        }\r\n        this._alphaMode[targetIndex] = mode;\r\n    }\r\n\r\n    /**\r\n     * Bind webGl buffers directly to the webGL context\r\n     * @param vertexBuffers defines the vertex buffer to bind\r\n     * @param indexBuffer defines the index buffer to bind\r\n     * @param effect defines the effect associated with the vertex buffer\r\n     */\r\n    public override bindBuffers(vertexBuffers: { [key: string]: VertexBuffer }, indexBuffer: DataBuffer, effect: Effect): void {}\r\n\r\n    /**\r\n     * Force the entire cache to be cleared\r\n     * You should not have to use this function unless your engine needs to share the webGL context with another engine\r\n     * @param bruteForce defines a boolean to force clearing ALL caches (including stencil, detoh and alpha states)\r\n     */\r\n    public override wipeCaches(bruteForce?: boolean): void {\r\n        if (this.preventCacheWipeBetweenFrames) {\r\n            return;\r\n        }\r\n        this.resetTextureCache();\r\n        this._currentEffect = null;\r\n\r\n        if (bruteForce) {\r\n            this._currentProgram = null;\r\n\r\n            this._stencilStateComposer.reset();\r\n            this.depthCullingState.reset();\r\n            this.alphaState.reset();\r\n        }\r\n\r\n        this._cachedVertexBuffers = null;\r\n        this._cachedIndexBuffer = null;\r\n        this._cachedEffectForVertexBuffers = null;\r\n    }\r\n\r\n    /**\r\n     * Send a draw order\r\n     * @param useTriangles defines if triangles must be used to draw (else wireframe will be used)\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public override draw(useTriangles: boolean, indexStart: number, indexCount: number, instancesCount?: number): void {}\r\n\r\n    /**\r\n     * Draw a list of indexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public override drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void {}\r\n\r\n    /**\r\n     * Draw a list of unindexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public override drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void {}\r\n\r\n    /** @internal */\r\n    protected override _createTexture(): WebGLTexture {\r\n        return {};\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _releaseTexture(texture: InternalTexture): void {}\r\n\r\n    /**\r\n     * Usually called from Texture.ts.\r\n     * Passed information to create a WebGLTexture\r\n     * @param urlArg defines a value which contains one of the following:\r\n     * * A conventional http URL, e.g. 'http://...' or 'file://...'\r\n     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'\r\n     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'\r\n     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file\r\n     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)\r\n     * @param scene needed for loading to the correct scene\r\n     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)\r\n     * @param onLoad optional callback to be called upon successful completion\r\n     * @param onError optional callback to be called upon failure\r\n     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob\r\n     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities\r\n     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @param mimeType defines an optional mime type\r\n     * @returns a InternalTexture for assignment back into BABYLON.Texture\r\n     */\r\n    public override createTexture(\r\n        urlArg: Nullable<string>,\r\n        noMipmap: boolean,\r\n        invertY: boolean,\r\n        scene: Nullable<ISceneLike>,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<(texture: InternalTexture) => void> = null,\r\n        onError: Nullable<(message: string, exception: any) => void> = null,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        format: Nullable<number> = null,\r\n        forcedExtension: Nullable<string> = null,\r\n        mimeType?: string\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Url);\r\n        const url = String(urlArg);\r\n\r\n        texture.url = url;\r\n        texture.generateMipMaps = !noMipmap;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture.baseWidth = this._options.textureSize;\r\n        texture.baseHeight = this._options.textureSize;\r\n        texture.width = this._options.textureSize;\r\n        texture.height = this._options.textureSize;\r\n        if (format) {\r\n            texture.format = format;\r\n        }\r\n        // Store buffer to support export/serialization and other operations.\r\n        if (buffer) {\r\n            texture._buffer = buffer;\r\n        }\r\n\r\n        texture.isReady = true;\r\n\r\n        if (onLoad) {\r\n            setTimeout(() => {\r\n                onLoad(texture);\r\n            });\r\n        }\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _createHardwareRenderTargetWrapper(\r\n        isMulti: boolean,\r\n        isCube: boolean,\r\n        size: number | { width: number; height: number; depth?: number; layers?: number }\r\n    ): RenderTargetWrapper {\r\n        const rtWrapper = new RenderTargetWrapper(isMulti, isCube, size, this);\r\n        this._renderTargetWrapperCache.push(rtWrapper);\r\n        return rtWrapper;\r\n    }\r\n\r\n    /**\r\n     * Creates a new render target wrapper\r\n     * @param size defines the size of the texture\r\n     * @param options defines the options used to create the texture\r\n     * @returns a new render target wrapper\r\n     */\r\n    public override createRenderTargetTexture(size: any, options: boolean | RenderTargetCreationOptions): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, false, size);\r\n\r\n        const fullOptions: RenderTargetCreationOptions = {};\r\n\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            fullOptions.generateMipMaps = options.generateMipMaps;\r\n            fullOptions.generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;\r\n            fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && options.generateStencilBuffer;\r\n            fullOptions.type = options.type === undefined ? Constants.TEXTURETYPE_UNSIGNED_BYTE : options.type;\r\n            fullOptions.samplingMode = options.samplingMode === undefined ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;\r\n        } else {\r\n            fullOptions.generateMipMaps = options;\r\n            fullOptions.generateDepthBuffer = true;\r\n            fullOptions.generateStencilBuffer = false;\r\n            fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            fullOptions.samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n        }\r\n        const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);\r\n        rtWrapper.setTexture(texture);\r\n\r\n        const width = size.width || size;\r\n        const height = size.height || size;\r\n\r\n        rtWrapper._generateDepthBuffer = fullOptions.generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;\r\n\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.isReady = true;\r\n        texture.samples = 1;\r\n        texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;\r\n        texture.samplingMode = fullOptions.samplingMode;\r\n        texture.type = fullOptions.type;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    /**\r\n     * Creates a new multiview render target wrapper for headless render-state tests.\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @returns a new multiview render target wrapper\r\n     */\r\n    public override createMultiviewRenderTargetTexture(width: number, height: number): RenderTargetWrapper {\r\n        if (!this.getCaps().multiview) {\r\n            throw new Error(\"Multiview is not supported\");\r\n        }\r\n\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, false, { width, height });\r\n        const texture = new InternalTexture(this, InternalTextureSource.RenderTarget, true);\r\n\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.isMultiview = true;\r\n        texture.isReady = true;\r\n        texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n        texture.samples = 1;\r\n\r\n        rtWrapper.setTextures(texture);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    /**\r\n     * Binds a multiview framebuffer for headless render-state tests.\r\n     * @param multiviewTexture render target wrapper to bind\r\n     */\r\n    public override bindMultiviewFramebuffer(multiviewTexture: RenderTargetWrapper): void {\r\n        this.bindFramebuffer(multiviewTexture, undefined, undefined, undefined, true);\r\n    }\r\n\r\n    /**\r\n     * Creates a new render target wrapper\r\n     * @param size defines the size of the texture\r\n     * @param options defines the options used to create the texture\r\n     * @returns a new render target wrapper\r\n     */\r\n    public override createRenderTargetCubeTexture(size: number, options?: RenderTargetCreationOptions): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, true, size);\r\n\r\n        const fullOptions = {\r\n            generateMipMaps: true,\r\n            generateDepthBuffer: true,\r\n            generateStencilBuffer: false,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            ...options,\r\n        };\r\n        fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && fullOptions.generateStencilBuffer;\r\n\r\n        if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (fullOptions.type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n\r\n        rtWrapper._generateDepthBuffer = fullOptions.generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;\r\n\r\n        const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);\r\n        texture.baseWidth = size;\r\n        texture.baseHeight = size;\r\n        texture.width = size;\r\n        texture.height = size;\r\n        texture.isReady = true;\r\n        texture.isCube = true;\r\n        texture.samples = 1;\r\n        texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;\r\n        texture.samplingMode = fullOptions.samplingMode;\r\n        texture.type = fullOptions.type;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param samplingMode defines the required sampling mode\r\n     * @param texture defines the texture to update\r\n     */\r\n    public override updateTextureSamplingMode(samplingMode: number, texture: InternalTexture): void {\r\n        texture.samplingMode = samplingMode;\r\n    }\r\n\r\n    /**\r\n     * Creates a raw texture\r\n     * @param data defines the data to store in the texture\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @param format defines the format of the data\r\n     * @param generateMipMaps defines if the engine should generate the mip levels\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)\r\n     * @param compression defines the compression used (null by default)\r\n     * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_BYTE by default)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns the raw texture inside an InternalTexture\r\n     */\r\n    public override createRawTexture(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags = 0,\r\n        useSRGBBuffer = false\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Raw);\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.format = format;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n        texture.type = type;\r\n        texture._useSRGBBuffer = useSRGBBuffer;\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = data;\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Update a raw texture\r\n     * @param texture defines the texture to update\r\n     * @param data defines the data to store in the texture\r\n     * @param format defines the format of the data\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param compression defines the compression used (null by default)\r\n     * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_BYTE by default)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     */\r\n    public override updateRawTexture(\r\n        texture: Nullable<InternalTexture>,\r\n        data: Nullable<ArrayBufferView>,\r\n        format: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        useSRGBBuffer: boolean = false\r\n    ): void {\r\n        if (texture) {\r\n            texture._bufferView = data;\r\n            texture.format = format;\r\n            texture.invertY = invertY;\r\n            texture._compression = compression;\r\n            texture.type = type;\r\n            texture._useSRGBBuffer = useSRGBBuffer;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the frame buffer to the specified texture.\r\n     * @param rtWrapper The render target wrapper to render to\r\n     * @param faceIndex The face of the texture to render to in case of cube texture\r\n     * @param requiredWidth The width of the target to render to\r\n     * @param requiredHeight The height of the target to render to\r\n     * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true\r\n     */\r\n    public override bindFramebuffer(rtWrapper: RenderTargetWrapper, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void {\r\n        if (this._currentRenderTarget) {\r\n            this.unBindFramebuffer(this._currentRenderTarget);\r\n        }\r\n        this._currentRenderTarget = rtWrapper;\r\n        this._currentFramebuffer = null;\r\n        if (this._cachedViewport && !forceFullscreenViewport) {\r\n            this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Unbind the current render target texture from the webGL context\r\n     * @param rtWrapper defines the render target wrapper to unbind\r\n     * @param disableGenerateMipMaps defines a boolean indicating that mipmaps must not be generated\r\n     * @param onBeforeUnbind defines a function which will be called before the effective unbind\r\n     */\r\n    public override unBindFramebuffer(rtWrapper: RenderTargetWrapper, disableGenerateMipMaps = false, onBeforeUnbind?: () => void): void {\r\n        this._currentRenderTarget = null;\r\n\r\n        if (onBeforeUnbind) {\r\n            onBeforeUnbind();\r\n        }\r\n        this._currentFramebuffer = null;\r\n    }\r\n\r\n    /**\r\n     * Creates a dynamic vertex buffer\r\n     * @param vertices the data for the dynamic vertex buffer\r\n     * @returns the new WebGL dynamic buffer\r\n     */\r\n    public override createDynamicVertexBuffer(vertices: FloatArray): DataBuffer {\r\n        const buffer = new DataBuffer();\r\n        buffer.references = 1;\r\n        buffer.capacity = 1;\r\n        return buffer;\r\n    }\r\n\r\n    /**\r\n     * Update the content of a dynamic texture\r\n     * @param texture defines the texture to update\r\n     * @param canvas defines the canvas containing the source\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param premulAlpha defines if alpha is stored as premultiplied\r\n     * @param format defines the format of the data\r\n     */\r\n    public override updateDynamicTexture(texture: Nullable<InternalTexture>, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha: boolean = false, format?: number): void {}\r\n\r\n    /**\r\n     * Gets a boolean indicating if all created effects are ready\r\n     * @returns true if all effects are ready\r\n     */\r\n    public override areAllEffectsReady(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Get the current error code of the webGL context\r\n     * @returns the error code\r\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getError\r\n     */\r\n    public override getError(): number {\r\n        return 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _getUnpackAlignement(): number {\r\n        return 1;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _unpackFlipY(value: boolean) {}\r\n\r\n    /**\r\n     * Update a dynamic index buffer\r\n     * @param indexBuffer defines the target index buffer\r\n     * @param indices defines the data to update\r\n     * @param offset defines the offset in the target index buffer where update should start\r\n     */\r\n    public override updateDynamicIndexBuffer(indexBuffer: WebGLBuffer, indices: IndicesArray, offset: number = 0): void {}\r\n\r\n    /**\r\n     * Updates a dynamic vertex buffer.\r\n     * @param vertexBuffer the vertex buffer to update\r\n     * @param vertices the data used to update the vertex buffer\r\n     * @param byteOffset the byte offset of the data (optional)\r\n     * @param byteLength the byte length of the data (optional)\r\n     */\r\n    public override updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, byteOffset?: number, byteLength?: number): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _bindTextureDirectly(target: number, texture: InternalTexture): boolean {\r\n        if (this._boundTexturesCache[this._activeChannel] !== texture) {\r\n            this._boundTexturesCache[this._activeChannel] = texture;\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _bindTexture(channel: number, texture: InternalTexture): void {\r\n        if (channel < 0) {\r\n            return;\r\n        }\r\n\r\n        this._bindTextureDirectly(0, texture);\r\n    }\r\n\r\n    protected override _deleteBuffer(buffer: WebGLBuffer): void {}\r\n\r\n    /**\r\n     * Force the engine to release all cached effects. This means that next effect compilation will have to be done completely even if a similar effect was already compiled\r\n     */\r\n    public override releaseEffects() {}\r\n\r\n    public override displayLoadingUI(): void {}\r\n\r\n    public override hideLoadingUI(): void {}\r\n\r\n    public override set loadingUIText(_: string) {}\r\n\r\n    public override flushFramebuffer(): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadCompressedDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        internalFormat: number,\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        faceIndex: number = 0,\r\n        lod: number = 0\r\n    ) {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadDataToTextureDirectly(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement, faceIndex: number = 0, lod: number = 0) {}\r\n}\r\n","/**\r\n * Gets the file extension from a URL.\r\n * @param url The URL to get the file extension from.\r\n * @returns The file extension, or an empty string if no extension is found.\r\n */\r\nexport function GetExtensionFromUrl(url: string) {\r\n    const urlWithoutUriParams = url.split(\"?\")[0];\r\n    const lastDot = urlWithoutUriParams.lastIndexOf(\".\");\r\n    const extension = lastDot > -1 ? urlWithoutUriParams.substring(lastDot).toLowerCase() : \"\";\r\n    return extension;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { LoadImage } from \"../../Misc/fileTools.pure\";\r\nimport { RandomGUID } from \"../../Misc/guid\";\r\nimport { type IWebRequest } from \"../../Misc/interfaces/iWebRequest\";\r\nimport { _GetCompatibleTextureLoader } from \"core/Materials/Textures/Loaders/textureLoaderManager\";\r\nimport { GetExtensionFromUrl } from \"core/Misc/urlTools\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype._partialLoadFile = function (\r\n        url: string,\r\n        index: number,\r\n        loadedFiles: ArrayBuffer[],\r\n        onfinish: (files: ArrayBuffer[]) => void,\r\n        onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null\r\n    ): void {\r\n        const onload = (data: ArrayBuffer) => {\r\n            loadedFiles[index] = data;\r\n            (<any>loadedFiles)._internalCount++;\r\n\r\n            if ((<any>loadedFiles)._internalCount === 6) {\r\n                onfinish(loadedFiles);\r\n            }\r\n        };\r\n\r\n        const onerror = (request?: IWebRequest, exception?: any) => {\r\n            if (onErrorCallBack && request) {\r\n                onErrorCallBack(request.status + \" \" + request.statusText, exception);\r\n            }\r\n        };\r\n\r\n        this._loadFile(url, onload as (data: string | ArrayBuffer) => void, undefined, undefined, true, onerror);\r\n    };\r\n\r\n    AbstractEngine.prototype._cascadeLoadFiles = function (\r\n        scene: Nullable<Scene>,\r\n        onfinish: (images: ArrayBuffer[]) => void,\r\n        files: string[],\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null\r\n    ): void {\r\n        const loadedFiles: ArrayBuffer[] = [];\r\n        (<any>loadedFiles)._internalCount = 0;\r\n\r\n        for (let index = 0; index < 6; index++) {\r\n            this._partialLoadFile(files[index], index, loadedFiles, onfinish, onError);\r\n        }\r\n    };\r\n\r\n    AbstractEngine.prototype._cascadeLoadImgs = function (\r\n        scene: Nullable<Scene>,\r\n        texture: InternalTexture,\r\n        onfinish: Nullable<(texture: InternalTexture, images: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n        files: string[],\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        mimeType?: string\r\n    ) {\r\n        const loadedImages: HTMLImageElement[] | ImageBitmap[] = [];\r\n        (<any>loadedImages)._internalCount = 0;\r\n\r\n        for (let index = 0; index < 6; index++) {\r\n            this._partialLoadImg(files[index], index, loadedImages, scene, texture, onfinish, onError, mimeType);\r\n        }\r\n    };\r\n\r\n    AbstractEngine.prototype._partialLoadImg = function (\r\n        url: string,\r\n        index: number,\r\n        loadedImages: HTMLImageElement[] | ImageBitmap[],\r\n        scene: Nullable<Scene>,\r\n        texture: InternalTexture,\r\n        onfinish: Nullable<(texture: InternalTexture, images: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n        onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null,\r\n        mimeType?: string\r\n    ) {\r\n        const tokenPendingData = RandomGUID();\r\n\r\n        const onload = (img: HTMLImageElement | ImageBitmap) => {\r\n            loadedImages[index] = img;\r\n            (<any>loadedImages)._internalCount++;\r\n\r\n            if (scene) {\r\n                scene.removePendingData(tokenPendingData);\r\n            }\r\n\r\n            if ((<any>loadedImages)._internalCount === 6 && onfinish) {\r\n                onfinish(texture, loadedImages);\r\n            }\r\n        };\r\n\r\n        const onerror = (message?: string, exception?: any) => {\r\n            if (scene) {\r\n                scene.removePendingData(tokenPendingData);\r\n            }\r\n\r\n            if (onErrorCallBack) {\r\n                onErrorCallBack(message, exception);\r\n            }\r\n        };\r\n\r\n        LoadImage(url, onload, onerror, scene ? scene.offlineProvider : null, mimeType);\r\n        if (scene) {\r\n            scene.addPendingData(tokenPendingData);\r\n        }\r\n    };\r\n\r\n    AbstractEngine.prototype.createCubeTextureBase = function (\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        files: Nullable<string[]>,\r\n        noMipmap?: boolean,\r\n        onLoad: Nullable<(data?: any) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials: boolean = false,\r\n        lodScale: number = 0,\r\n        lodOffset: number = 0,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        beforeLoadCubeDataCallback: Nullable<(texture: InternalTexture, data: ArrayBufferView | ArrayBufferView[]) => void> = null,\r\n        imageHandler: Nullable<(texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => void> = null,\r\n        useSRGBBuffer = false,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        const texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);\r\n        texture.isCube = true;\r\n        texture.url = rootUrl;\r\n        texture.generateMipMaps = !noMipmap;\r\n        texture._lodGenerationScale = lodScale;\r\n        texture._lodGenerationOffset = lodOffset;\r\n        texture._useSRGBBuffer = !!useSRGBBuffer && this._caps.supportSRGBBuffers && (this.version > 1 || this.isWebGPU || !!noMipmap);\r\n        if (texture !== fallback) {\r\n            texture.label = rootUrl.substring(0, 60); // default label, can be overriden by the caller\r\n        }\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._extension = forcedExtension;\r\n            texture._files = files;\r\n            texture._buffer = buffer;\r\n        }\r\n\r\n        const originalRootUrl = rootUrl;\r\n        if (this._transformTextureUrl && !fallback) {\r\n            rootUrl = this._transformTextureUrl(rootUrl);\r\n        }\r\n\r\n        const extension = forcedExtension ?? GetExtensionFromUrl(rootUrl);\r\n\r\n        const loaderPromise = _GetCompatibleTextureLoader(extension);\r\n\r\n        const localOnError = (message?: string, exception?: any) => {\r\n            // if an error was thrown during load, dispose the texture, otherwise it will stay in the cache\r\n            texture.dispose();\r\n            if (onError) {\r\n                onError(message, exception);\r\n            } else if (message) {\r\n                Logger.Warn(message);\r\n            }\r\n        };\r\n\r\n        const onInternalError = (request?: IWebRequest, exception?: any) => {\r\n            if (rootUrl === originalRootUrl) {\r\n                if (request) {\r\n                    localOnError(request.status + \" \" + request.statusText, exception);\r\n                }\r\n            } else {\r\n                // fall back to the original url if the transformed url fails to load\r\n                Logger.Warn(`Failed to load ${rootUrl}, falling back to the ${originalRootUrl}`);\r\n                this.createCubeTextureBase(\r\n                    originalRootUrl,\r\n                    scene,\r\n                    files,\r\n                    !!noMipmap,\r\n                    onLoad,\r\n                    localOnError,\r\n                    format,\r\n                    forcedExtension,\r\n                    createPolynomials,\r\n                    lodScale,\r\n                    lodOffset,\r\n                    texture,\r\n                    beforeLoadCubeDataCallback,\r\n                    imageHandler,\r\n                    useSRGBBuffer,\r\n                    buffer\r\n                );\r\n            }\r\n        };\r\n\r\n        if (loaderPromise) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            loaderPromise.then((loader) => {\r\n                const onLoadData = (data: ArrayBufferView | ArrayBufferView[]) => {\r\n                    if (beforeLoadCubeDataCallback) {\r\n                        beforeLoadCubeDataCallback(texture, data);\r\n                    }\r\n                    loader.loadCubeData(data, texture, createPolynomials, onLoad, (message?: string, exception?: any) => {\r\n                        localOnError(message, exception);\r\n                    });\r\n                };\r\n                if (buffer) {\r\n                    onLoadData(buffer);\r\n                } else if (files && files.length === 6) {\r\n                    if (loader.supportCascades) {\r\n                        this._cascadeLoadFiles(scene, (images) => onLoadData(images.map((image) => new Uint8Array(image))), files, localOnError);\r\n                    } else {\r\n                        localOnError(\"Textures type does not support cascades.\");\r\n                    }\r\n                } else {\r\n                    this._loadFile(\r\n                        rootUrl,\r\n                        (data) => onLoadData(new Uint8Array(data as ArrayBuffer)),\r\n                        undefined,\r\n                        scene ? scene.offlineProvider || null : undefined,\r\n                        true,\r\n                        onInternalError\r\n                    );\r\n                }\r\n            });\r\n        } else {\r\n            if (!files || files.length === 0) {\r\n                throw new Error(\"Cannot load cubemap because files were not defined, or the correct loader was not found.\");\r\n            }\r\n\r\n            this._cascadeLoadImgs(\r\n                scene,\r\n                texture,\r\n                (texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => {\r\n                    if (imageHandler) {\r\n                        imageHandler(texture, imgs);\r\n                    }\r\n                },\r\n                files,\r\n                localOnError\r\n            );\r\n        }\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\nimport { PerfCounter } from \"../../Misc/perfCounter\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineTimeQuery.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineTimeQuery(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.getGPUFrameTimeCounter = function () {\r\n        if (!this._gpuFrameTime) {\r\n            this._gpuFrameTime = new PerfCounter();\r\n        }\r\n        return this._gpuFrameTime;\r\n    };\r\n\r\n    AbstractEngine.prototype.captureGPUFrameTime = function (value: boolean): void {\r\n        // Do nothing. Must be implemented by child classes\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\n/** @internal */\r\nexport type OcclusionQuery = WebGLQuery | number;\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _OcclusionDataStorage {\r\n    /** @internal */\r\n    public occlusionInternalRetryCounter = 0;\r\n\r\n    /** @internal */\r\n    public isOcclusionQueryInProgress = false;\r\n\r\n    /** @internal */\r\n    public isOccluded = false;\r\n\r\n    /** @internal */\r\n    public occlusionRetryCount = -1;\r\n\r\n    /** @internal */\r\n    public occlusionType = AbstractMesh.OCCLUSION_TYPE_NONE;\r\n\r\n    /** @internal */\r\n    public occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;\r\n\r\n    /** @internal */\r\n    public forceRenderingWhenOccluded = false;\r\n\r\n    /** @internal */\r\n    public occlusionForRenderPassId = -1;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineQuery.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineQuery(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.createQuery = function (): Nullable<OcclusionQuery> {\r\n        return null;\r\n    };\r\n\r\n    AbstractEngine.prototype.deleteQuery = function (query: OcclusionQuery): AbstractEngine {\r\n        // Do nothing. Must be implemented by child classes\r\n        return this;\r\n    };\r\n\r\n    AbstractEngine.prototype.isQueryResultAvailable = function (query: OcclusionQuery): boolean {\r\n        // Do nothing. Must be implemented by child classes\r\n        return false;\r\n    };\r\n\r\n    AbstractEngine.prototype.getQueryResult = function (query: OcclusionQuery): number {\r\n        // Do nothing. Must be implemented by child classes\r\n        return 0;\r\n    };\r\n\r\n    AbstractEngine.prototype.isOcclusionQueryVisible = function (query: OcclusionQuery): boolean {\r\n        return this.getQueryResult(query) > 0;\r\n    };\r\n\r\n    AbstractEngine.prototype.beginOcclusionQuery = function (algorithmType: number, query: OcclusionQuery): boolean {\r\n        // Do nothing. Must be implemented by child classes\r\n        return false;\r\n    };\r\n\r\n    AbstractEngine.prototype.endOcclusionQuery = function (algorithmType: number): AbstractEngine {\r\n        // Do nothing. Must be implemented by child classes\r\n        return this;\r\n    };\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"isOcclusionQueryInProgress\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.isOcclusionQueryInProgress;\r\n        },\r\n        set: function (this: AbstractMesh, value: boolean) {\r\n            this._occlusionDataStorage.isOcclusionQueryInProgress = value;\r\n        },\r\n        enumerable: false,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"_occlusionDataStorage\", {\r\n        get: function (this: AbstractMesh) {\r\n            if (!this.__occlusionDataStorage) {\r\n                this.__occlusionDataStorage = new _OcclusionDataStorage();\r\n            }\r\n            return this.__occlusionDataStorage;\r\n        },\r\n        enumerable: false,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"isOccluded\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.isOccluded;\r\n        },\r\n        set: function (this: AbstractMesh, value: boolean) {\r\n            this._occlusionDataStorage.isOccluded = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionQueryAlgorithmType\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.occlusionQueryAlgorithmType;\r\n        },\r\n        set: function (this: AbstractMesh, value: number) {\r\n            this._occlusionDataStorage.occlusionQueryAlgorithmType = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionType\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.occlusionType;\r\n        },\r\n        set: function (this: AbstractMesh, value: number) {\r\n            this._occlusionDataStorage.occlusionType = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionRetryCount\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.occlusionRetryCount;\r\n        },\r\n        set: function (this: AbstractMesh, value: number) {\r\n            this._occlusionDataStorage.occlusionRetryCount = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"forceRenderingWhenOccluded\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.forceRenderingWhenOccluded;\r\n        },\r\n        set: function (this: AbstractMesh, value: boolean) {\r\n            this._occlusionDataStorage.forceRenderingWhenOccluded = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"occlusionForRenderPassId\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._occlusionDataStorage.occlusionForRenderPassId;\r\n        },\r\n        set: function (this: AbstractMesh, value: number) {\r\n            this._occlusionDataStorage.occlusionForRenderPassId = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    // We also need to update AbstractMesh as there is a portion of the code there\r\n    AbstractMesh.prototype._checkOcclusionQuery = function (checkOnly: boolean) {\r\n        const dataStorage = this._occlusionDataStorage;\r\n\r\n        if (dataStorage.occlusionType === AbstractMesh.OCCLUSION_TYPE_NONE) {\r\n            dataStorage.isOccluded = false;\r\n            return false;\r\n        }\r\n\r\n        const engine = this.getEngine();\r\n\r\n        if (!engine.getCaps().supportOcclusionQuery) {\r\n            dataStorage.isOccluded = false;\r\n            return false;\r\n        }\r\n\r\n        if (!engine.isQueryResultAvailable) {\r\n            // Occlusion query where not referenced\r\n            dataStorage.isOccluded = false;\r\n            return false;\r\n        }\r\n\r\n        if (this.isOcclusionQueryInProgress && this._occlusionQuery !== null && this._occlusionQuery !== undefined) {\r\n            const isOcclusionQueryAvailable = engine.isQueryResultAvailable(this._occlusionQuery);\r\n            if (isOcclusionQueryAvailable) {\r\n                dataStorage.isOcclusionQueryInProgress = false;\r\n                dataStorage.occlusionInternalRetryCounter = 0;\r\n                dataStorage.isOccluded = !engine.isOcclusionQueryVisible(this._occlusionQuery);\r\n            } else {\r\n                dataStorage.occlusionInternalRetryCounter++;\r\n\r\n                if (dataStorage.occlusionRetryCount !== -1 && dataStorage.occlusionInternalRetryCounter > dataStorage.occlusionRetryCount) {\r\n                    dataStorage.isOcclusionQueryInProgress = false;\r\n                    dataStorage.occlusionInternalRetryCounter = 0;\r\n\r\n                    // if optimistic set isOccluded to false regardless of the status of isOccluded. (Render in the current render loop)\r\n                    // if strict continue the last state of the object.\r\n                    dataStorage.isOccluded = dataStorage.occlusionType === AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC ? false : dataStorage.isOccluded;\r\n                } else {\r\n                    return dataStorage.occlusionType === AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC ? false : dataStorage.isOccluded;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (checkOnly) {\r\n            return dataStorage.isOccluded;\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        if (scene.getBoundingBoxRenderer) {\r\n            const occlusionBoundingBoxRenderer = scene.getBoundingBoxRenderer();\r\n\r\n            if (this._occlusionQuery === null) {\r\n                this._occlusionQuery = engine.createQuery();\r\n            }\r\n\r\n            if (this._occlusionQuery && engine.beginOcclusionQuery(dataStorage.occlusionQueryAlgorithmType, this._occlusionQuery)) {\r\n                occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);\r\n                engine.endOcclusionQuery(dataStorage.occlusionQueryAlgorithmType);\r\n                this._occlusionDataStorage.isOcclusionQueryInProgress = true;\r\n            }\r\n        }\r\n\r\n        return dataStorage.isOccluded;\r\n    };\r\n}\r\n","import { Constants } from \"../constants\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineAlpha.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineAlpha(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype.setAlphaEquation = function (equation: number, targetIndex: number = 0): void {\r\n        if (this._alphaEquation[targetIndex] === equation) {\r\n            return;\r\n        }\r\n\r\n        switch (equation) {\r\n            case Constants.ALPHA_EQUATION_ADD:\r\n                this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_ADD, Constants.GL_ALPHA_EQUATION_ADD, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_EQUATION_SUBSTRACT:\r\n                this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_SUBTRACT, Constants.GL_ALPHA_EQUATION_SUBTRACT, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_EQUATION_REVERSE_SUBTRACT:\r\n                this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_REVERSE_SUBTRACT, Constants.GL_ALPHA_EQUATION_REVERSE_SUBTRACT, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_EQUATION_MAX:\r\n                this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_MAX, Constants.GL_ALPHA_EQUATION_MAX, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_EQUATION_MIN:\r\n                this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_MIN, Constants.GL_ALPHA_EQUATION_MIN, targetIndex);\r\n                break;\r\n            case Constants.ALPHA_EQUATION_DARKEN:\r\n                this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_MIN, Constants.GL_ALPHA_EQUATION_ADD, targetIndex);\r\n                break;\r\n        }\r\n        this._alphaEquation[targetIndex] = equation;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\n/**\r\n * Class used to define an additional view for the engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/multiCanvas\r\n */\r\nexport class EngineView {\r\n    /**\r\n     * A randomly generated unique id\r\n     */\r\n    readonly id: string;\r\n    /** Defines the canvas where to render the view */\r\n    target: HTMLCanvasElement;\r\n    /**\r\n     * Defines an optional camera or array of cameras used to render the view (will use active camera / cameras else)\r\n     * Support for array of cameras @since\r\n     */\r\n    camera?: Camera | Camera[];\r\n    /** Indicates if the destination view canvas should be cleared before copying the parent canvas. Can help if the scene clear color has alpha < 1 */\r\n    clearBeforeCopy?: boolean;\r\n    /** Indicates if the view is enabled (true by default) */\r\n    enabled: boolean;\r\n    /** Defines a custom function to handle canvas size changes. (the canvas to render into is provided to the callback) */\r\n    customResize?: (canvas: HTMLCanvasElement) => void;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineViews.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineViews(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const OnBeforeViewRenderObservable = new Observable<EngineView>();\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const OnAfterViewRenderObservable = new Observable<EngineView>();\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"onBeforeViewRenderObservable\", {\r\n        get: function (this: AbstractEngine) {\r\n            return OnBeforeViewRenderObservable;\r\n        },\r\n    });\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"onAfterViewRenderObservable\", {\r\n        get: function (this: AbstractEngine) {\r\n            return OnAfterViewRenderObservable;\r\n        },\r\n    });\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"inputElement\", {\r\n        get: function (this: AbstractEngine) {\r\n            return this._inputElement;\r\n        },\r\n        set: function (this: AbstractEngine, value: HTMLElement) {\r\n            if (this._inputElement !== value) {\r\n                this._inputElement = value;\r\n                this._onEngineViewChanged?.();\r\n            }\r\n        },\r\n    });\r\n\r\n    AbstractEngine.prototype.getInputElement = function (): Nullable<HTMLElement> {\r\n        return this.inputElement || this.getRenderingCanvas();\r\n    };\r\n\r\n    AbstractEngine.prototype.registerView = function (canvas: HTMLCanvasElement, camera?: Camera | Camera[], clearBeforeCopy?: boolean): EngineView {\r\n        if (!this.views) {\r\n            this.views = [];\r\n        }\r\n\r\n        for (const view of this.views) {\r\n            if (view.target === canvas) {\r\n                return view;\r\n            }\r\n        }\r\n\r\n        const masterCanvas = this.getRenderingCanvas();\r\n        if (masterCanvas) {\r\n            canvas.width = masterCanvas.width;\r\n            canvas.height = masterCanvas.height;\r\n        }\r\n\r\n        const newView = { target: canvas, camera, clearBeforeCopy, enabled: true, id: (Math.random() * 100000).toFixed() };\r\n        this.views.push(newView);\r\n\r\n        if (camera && !Array.isArray(camera)) {\r\n            camera.onDisposeObservable.add(() => {\r\n                this.unRegisterView(canvas);\r\n            });\r\n        }\r\n\r\n        return newView;\r\n    };\r\n\r\n    AbstractEngine.prototype.unRegisterView = function (canvas: HTMLCanvasElement): AbstractEngine {\r\n        if (!this.views || this.views.length === 0) {\r\n            return this;\r\n        }\r\n\r\n        for (const view of this.views) {\r\n            if (view.target === canvas) {\r\n                const index = this.views.indexOf(view);\r\n\r\n                if (index !== -1) {\r\n                    this.views.splice(index, 1);\r\n                }\r\n                break;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    };\r\n\r\n    AbstractEngine.prototype._renderViewStep = function (view: EngineView): boolean {\r\n        const canvas = view.target;\r\n        const context = canvas.getContext(\"2d\");\r\n        if (!context) {\r\n            return true;\r\n        }\r\n        const parent = this.getRenderingCanvas()!;\r\n\r\n        OnBeforeViewRenderObservable.notifyObservers(view);\r\n        const camera = view.camera;\r\n        let previewCamera: Nullable<Camera> = null;\r\n        let previewCameras: Nullable<Camera[]> = null;\r\n        let scene: Nullable<Scene> = null;\r\n        if (camera) {\r\n            scene = Array.isArray(camera) ? camera[0].getScene() : camera.getScene();\r\n\r\n            previewCamera = scene.activeCamera;\r\n            previewCameras = scene.activeCameras;\r\n\r\n            if (Array.isArray(camera)) {\r\n                scene.activeCameras = camera;\r\n            } else {\r\n                scene.activeCamera = camera;\r\n                scene.activeCameras = null;\r\n            }\r\n        }\r\n        this.activeView = view;\r\n\r\n        if (view.customResize) {\r\n            view.customResize(canvas);\r\n        } else {\r\n            // Set sizes\r\n            const width = Math.floor(canvas.clientWidth / this._hardwareScalingLevel);\r\n            const height = Math.floor(canvas.clientHeight / this._hardwareScalingLevel);\r\n\r\n            const dimsChanged = width !== canvas.width || parent.width !== canvas.width || height !== canvas.height || parent.height !== canvas.height;\r\n            if (canvas.clientWidth && canvas.clientHeight && dimsChanged) {\r\n                canvas.width = width;\r\n                canvas.height = height;\r\n                this.setSize(width, height);\r\n            }\r\n        }\r\n\r\n        if (!parent.width || !parent.height) {\r\n            return false;\r\n        }\r\n\r\n        // Render the frame\r\n        this._renderFrame();\r\n\r\n        this.flushFramebuffer();\r\n\r\n        // Copy to target\r\n        if (view.clearBeforeCopy) {\r\n            context.clearRect(0, 0, parent.width, parent.height);\r\n        }\r\n        context.drawImage(parent, 0, 0);\r\n\r\n        // Restore\r\n        if (scene) {\r\n            scene.activeCameras = previewCameras;\r\n            scene.activeCamera = previewCamera;\r\n        }\r\n        OnAfterViewRenderObservable.notifyObservers(view);\r\n        return true;\r\n    };\r\n\r\n    AbstractEngine.prototype._renderViews = function () {\r\n        if (!this.views || this.views.length === 0) {\r\n            return false;\r\n        }\r\n\r\n        const parent = this.getRenderingCanvas();\r\n\r\n        if (!parent) {\r\n            return false;\r\n        }\r\n\r\n        let inputElementView;\r\n        for (const view of this.views) {\r\n            if (!view.enabled) {\r\n                continue;\r\n            }\r\n            const canvas = view.target;\r\n            // Always render the view correspondent to the inputElement for last\r\n            if (canvas === this.inputElement) {\r\n                inputElementView = view;\r\n                continue;\r\n            }\r\n\r\n            if (!this._renderViewStep(view)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (inputElementView) {\r\n            if (!this._renderViewStep(inputElementView)) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        this.activeView = null;\r\n\r\n        return true;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineTextureSelector.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineTextureSelector(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function TransformTextureUrl(this: AbstractEngine, url: string): string {\r\n        const excludeFn = (entry: string) => {\r\n            const strRegExPattern: string = \"\\\\b\" + entry + \"\\\\b\";\r\n            return url && (url === entry || url.match(new RegExp(strRegExPattern, \"g\")));\r\n        };\r\n\r\n        if (this._excludedCompressedTextures && this._excludedCompressedTextures.some(excludeFn)) {\r\n            return url;\r\n        }\r\n\r\n        const lastDot = url.lastIndexOf(\".\");\r\n        const lastQuestionMark = url.lastIndexOf(\"?\");\r\n        const querystring = lastQuestionMark > -1 ? url.substring(lastQuestionMark, url.length) : \"\";\r\n        return (lastDot > -1 ? url.substring(0, lastDot) : url) + this._textureFormatInUse + querystring;\r\n    }\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"texturesSupported\", {\r\n        get: function (this: AbstractEngine) {\r\n            // Intelligently add supported compressed formats in order to check for.\r\n            // Check for ASTC support first as it is most powerful and to be very cross platform.\r\n            // Next PVRTC & DXT, which are probably superior to ETC1/2.\r\n            // Likely no hardware which supports both PVR & DXT, so order matters little.\r\n            // ETC2 is newer and handles ETC1 (no alpha capability), so check for first.\r\n            const texturesSupported: string[] = [];\r\n            if (this._caps.astc) {\r\n                texturesSupported.push(\"-astc.ktx\");\r\n            }\r\n            if (this._caps.s3tc) {\r\n                texturesSupported.push(\"-dxt.ktx\");\r\n            }\r\n            if (this._caps.pvrtc) {\r\n                texturesSupported.push(\"-pvrtc.ktx\");\r\n            }\r\n            if (this._caps.etc2) {\r\n                texturesSupported.push(\"-etc2.ktx\");\r\n            }\r\n            if (this._caps.etc1) {\r\n                texturesSupported.push(\"-etc1.ktx\");\r\n            }\r\n            return texturesSupported;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(AbstractEngine.prototype, \"textureFormatInUse\", {\r\n        get: function (this: AbstractEngine) {\r\n            return this._textureFormatInUse || null;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    AbstractEngine.prototype.setCompressedTextureExclusions = function (skippedFiles: Array<string>): void {\r\n        this._excludedCompressedTextures = skippedFiles;\r\n    };\r\n\r\n    AbstractEngine.prototype.setTextureFormatToUse = function (formatsAvailable: Array<string>): Nullable<string> {\r\n        const texturesSupported = this.texturesSupported;\r\n        for (let i = 0, len1 = texturesSupported.length; i < len1; i++) {\r\n            for (let j = 0, len2 = formatsAvailable.length; j < len2; j++) {\r\n                if (texturesSupported[i] === formatsAvailable[j].toLowerCase()) {\r\n                    this._transformTextureUrl = (url: string) => TransformTextureUrl.call(this, url);\r\n                    return (this._textureFormatInUse = texturesSupported[i]);\r\n                }\r\n            }\r\n        }\r\n        // actively set format to nothing, to allow this to be called more than once\r\n        // and possibly fail the 2nd time\r\n        this._textureFormatInUse = \"\";\r\n        this._transformTextureUrl = null;\r\n        return null;\r\n    };\r\n}\r\n","import { AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for engineDebugging.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEngineDebugging(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractEngine.prototype._debugPushGroup = function (groupName: string): void {};\r\n\r\n    AbstractEngine.prototype._debugPopGroup = function (): void {};\r\n\r\n    AbstractEngine.prototype._debugInsertMarker = function (text: string): void {};\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type int } from \"../../types\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type OcclusionQuery } from \"../AbstractEngine/abstractEngine.query.pure\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { _TimeToken } from \"../../Instrumentation/timeToken\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineQuery.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineQuery(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.createQuery = function (): OcclusionQuery {\r\n        const query = this._gl.createQuery();\r\n        if (!query) {\r\n            throw new Error(\"Unable to create Occlusion Query\");\r\n        }\r\n        return query;\r\n    };\r\n\r\n    ThinEngine.prototype.deleteQuery = function (query: OcclusionQuery): ThinEngine {\r\n        this._gl.deleteQuery(query);\r\n\r\n        return this;\r\n    };\r\n\r\n    ThinEngine.prototype.isQueryResultAvailable = function (query: OcclusionQuery): boolean {\r\n        return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT_AVAILABLE) as boolean;\r\n    };\r\n\r\n    ThinEngine.prototype.getQueryResult = function (query: OcclusionQuery): number {\r\n        return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT) as number;\r\n    };\r\n\r\n    ThinEngine.prototype.beginOcclusionQuery = function (algorithmType: number, query: OcclusionQuery): boolean {\r\n        const glAlgorithm = this._getGlAlgorithmType(algorithmType);\r\n        this._gl.beginQuery(glAlgorithm, query);\r\n\r\n        return true;\r\n    };\r\n\r\n    ThinEngine.prototype.endOcclusionQuery = function (algorithmType: number): ThinEngine {\r\n        const glAlgorithm = this._getGlAlgorithmType(algorithmType);\r\n        this._gl.endQuery(glAlgorithm);\r\n\r\n        return this;\r\n    };\r\n\r\n    ThinEngine.prototype._createTimeQuery = function (): Nullable<WebGLQuery> {\r\n        const timerQuery = <EXT_disjoint_timer_query>this.getCaps().timerQuery;\r\n\r\n        if (timerQuery.createQueryEXT) {\r\n            return timerQuery.createQueryEXT();\r\n        }\r\n\r\n        return this.createQuery();\r\n    };\r\n\r\n    ThinEngine.prototype._deleteTimeQuery = function (query: WebGLQuery): void {\r\n        const timerQuery = <EXT_disjoint_timer_query>this.getCaps().timerQuery;\r\n\r\n        if (timerQuery.deleteQueryEXT) {\r\n            timerQuery.deleteQueryEXT(query);\r\n            return;\r\n        }\r\n\r\n        this.deleteQuery(query);\r\n    };\r\n\r\n    ThinEngine.prototype._getTimeQueryResult = function (query: WebGLQuery): any {\r\n        const timerQuery = <EXT_disjoint_timer_query>this.getCaps().timerQuery;\r\n\r\n        if (timerQuery.getQueryObjectEXT) {\r\n            return timerQuery.getQueryObjectEXT(query, timerQuery.QUERY_RESULT_EXT);\r\n        }\r\n        return this.getQueryResult(query);\r\n    };\r\n\r\n    ThinEngine.prototype._getTimeQueryAvailability = function (query: WebGLQuery): any {\r\n        const timerQuery = <EXT_disjoint_timer_query>this.getCaps().timerQuery;\r\n\r\n        if (timerQuery.getQueryObjectEXT) {\r\n            return timerQuery.getQueryObjectEXT(query, timerQuery.QUERY_RESULT_AVAILABLE_EXT);\r\n        }\r\n        return this.isQueryResultAvailable(query);\r\n    };\r\n\r\n    ThinEngine.prototype.startTimeQuery = function (): Nullable<_TimeToken> {\r\n        const caps = this.getCaps();\r\n        const timerQuery = caps.timerQuery;\r\n        if (!timerQuery) {\r\n            return null;\r\n        }\r\n\r\n        const token = new _TimeToken();\r\n        this._gl.getParameter(timerQuery.GPU_DISJOINT_EXT);\r\n        if (caps.canUseTimestampForTimerQuery) {\r\n            token._startTimeQuery = this._createTimeQuery();\r\n\r\n            if (token._startTimeQuery) {\r\n                timerQuery.queryCounterEXT(token._startTimeQuery, timerQuery.TIMESTAMP_EXT);\r\n            }\r\n        } else {\r\n            if (this._currentNonTimestampToken) {\r\n                return this._currentNonTimestampToken;\r\n            }\r\n\r\n            token._timeElapsedQuery = this._createTimeQuery();\r\n            if (token._timeElapsedQuery) {\r\n                if (timerQuery.beginQueryEXT) {\r\n                    timerQuery.beginQueryEXT(timerQuery.TIME_ELAPSED_EXT, token._timeElapsedQuery);\r\n                } else {\r\n                    this._gl.beginQuery(timerQuery.TIME_ELAPSED_EXT, token._timeElapsedQuery);\r\n                }\r\n            }\r\n\r\n            this._currentNonTimestampToken = token;\r\n        }\r\n        return token;\r\n    };\r\n\r\n    ThinEngine.prototype.endTimeQuery = function (token: _TimeToken): int {\r\n        const caps = this.getCaps();\r\n        const timerQuery = caps.timerQuery;\r\n        if (!timerQuery || !token) {\r\n            return -1;\r\n        }\r\n\r\n        if (caps.canUseTimestampForTimerQuery) {\r\n            if (!token._startTimeQuery) {\r\n                return -1;\r\n            }\r\n            if (!token._endTimeQuery) {\r\n                token._endTimeQuery = this._createTimeQuery();\r\n                if (token._endTimeQuery) {\r\n                    timerQuery.queryCounterEXT(token._endTimeQuery, timerQuery.TIMESTAMP_EXT);\r\n                }\r\n            }\r\n        } else if (!token._timeElapsedQueryEnded) {\r\n            if (!token._timeElapsedQuery) {\r\n                return -1;\r\n            }\r\n            if (timerQuery.endQueryEXT) {\r\n                timerQuery.endQueryEXT(timerQuery.TIME_ELAPSED_EXT);\r\n            } else {\r\n                this._gl.endQuery(timerQuery.TIME_ELAPSED_EXT);\r\n                this._currentNonTimestampToken = null;\r\n            }\r\n            token._timeElapsedQueryEnded = true;\r\n        }\r\n\r\n        const disjoint = this._gl.getParameter(timerQuery.GPU_DISJOINT_EXT);\r\n        let available: boolean = false;\r\n        if (token._endTimeQuery) {\r\n            available = this._getTimeQueryAvailability(token._endTimeQuery);\r\n        } else if (token._timeElapsedQuery) {\r\n            available = this._getTimeQueryAvailability(token._timeElapsedQuery);\r\n        }\r\n\r\n        if (available && !disjoint) {\r\n            let result: number;\r\n            if (caps.canUseTimestampForTimerQuery) {\r\n                if (!token._startTimeQuery || !token._endTimeQuery) {\r\n                    return -1;\r\n                }\r\n                const timeStart = this._getTimeQueryResult(token._startTimeQuery);\r\n                const timeEnd = this._getTimeQueryResult(token._endTimeQuery);\r\n\r\n                result = timeEnd - timeStart;\r\n                this._deleteTimeQuery(token._startTimeQuery);\r\n                this._deleteTimeQuery(token._endTimeQuery);\r\n                token._startTimeQuery = null;\r\n                token._endTimeQuery = null;\r\n            } else {\r\n                if (!token._timeElapsedQuery) {\r\n                    return -1;\r\n                }\r\n\r\n                result = this._getTimeQueryResult(token._timeElapsedQuery);\r\n                this._deleteTimeQuery(token._timeElapsedQuery);\r\n                token._timeElapsedQuery = null;\r\n                token._timeElapsedQueryEnded = false;\r\n            }\r\n            return result;\r\n        }\r\n\r\n        return -1;\r\n    };\r\n\r\n    ThinEngine.prototype.captureGPUFrameTime = function (value: boolean) {\r\n        if (value === this._captureGPUFrameTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureGPUFrameTime = value;\r\n\r\n        if (value) {\r\n            const gpuFrameTime = this.getGPUFrameTimeCounter();\r\n\r\n            this._onBeginFrameObserver = this.onBeginFrameObservable.add(() => {\r\n                if (!this._gpuFrameTimeToken) {\r\n                    this._gpuFrameTimeToken = this.startTimeQuery();\r\n                }\r\n            });\r\n\r\n            this._onEndFrameObserver = this.onEndFrameObservable.add(() => {\r\n                if (!this._gpuFrameTimeToken) {\r\n                    return;\r\n                }\r\n                const time = this.endTimeQuery(this._gpuFrameTimeToken);\r\n\r\n                if (time > -1) {\r\n                    this._gpuFrameTimeToken = null;\r\n                    gpuFrameTime.fetchNewFrame();\r\n                    gpuFrameTime.addCount(time, true);\r\n                }\r\n            });\r\n        } else {\r\n            this.onBeginFrameObservable.remove(this._onBeginFrameObserver);\r\n            this._onBeginFrameObserver = null;\r\n            this.onEndFrameObservable.remove(this._onEndFrameObserver);\r\n            this._onEndFrameObserver = null;\r\n        }\r\n    };\r\n\r\n    ThinEngine.prototype._getGlAlgorithmType = function (algorithmType: number): number {\r\n        return algorithmType === AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE ? this._gl.ANY_SAMPLES_PASSED_CONSERVATIVE : this._gl.ANY_SAMPLES_PASSED;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { Engine } from \"../../Engines/engine.pure\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var _forceTransformFeedbackToBundle = true;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for engineTransformFeedback.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEngineTransformFeedback(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Engine.prototype.createTransformFeedback = function (): WebGLTransformFeedback {\r\n        const transformFeedback = this._gl.createTransformFeedback();\r\n        if (!transformFeedback) {\r\n            throw new Error(\"Unable to create Transform Feedback\");\r\n        }\r\n        return transformFeedback;\r\n    };\r\n\r\n    Engine.prototype.deleteTransformFeedback = function (value: WebGLTransformFeedback): void {\r\n        this._gl.deleteTransformFeedback(value);\r\n    };\r\n\r\n    Engine.prototype.bindTransformFeedback = function (value: Nullable<WebGLTransformFeedback>): void {\r\n        this._gl.bindTransformFeedback(this._gl.TRANSFORM_FEEDBACK, value);\r\n    };\r\n\r\n    Engine.prototype.beginTransformFeedback = function (usePoints: boolean = true): void {\r\n        this._gl.beginTransformFeedback(usePoints ? this._gl.POINTS : this._gl.TRIANGLES);\r\n    };\r\n\r\n    Engine.prototype.endTransformFeedback = function (): void {\r\n        this._gl.endTransformFeedback();\r\n    };\r\n\r\n    Engine.prototype.setTranformFeedbackVaryings = function (program: WebGLProgram, value: string[]): void {\r\n        this._gl.transformFeedbackVaryings(program, value, this._gl.INTERLEAVED_ATTRIBS);\r\n    };\r\n\r\n    Engine.prototype.bindTransformFeedbackBuffer = function (value: Nullable<DataBuffer>): void {\r\n        this._gl.bindBufferBase(this._gl.TRANSFORM_FEEDBACK_BUFFER, 0, value ? value.underlyingResource : null);\r\n    };\r\n\r\n    Engine.prototype.readTransformFeedbackBuffer = function (target: ArrayBufferView): void {\r\n        this._gl.getBufferSubData(this._gl.TRANSFORM_FEEDBACK_BUFFER, 0, target);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../constants\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineVideoTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineVideoTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.updateVideoTexture = function (texture: Nullable<InternalTexture>, video: HTMLVideoElement, invertY: boolean): void {\r\n        if (!texture || texture._isDisabled) {\r\n            return;\r\n        }\r\n\r\n        const glformat = this._getInternalFormat(texture.format);\r\n        const internalFormat = this._getRGBABufferInternalSizedFormat(Constants.TEXTURETYPE_UNSIGNED_BYTE, texture.format);\r\n\r\n        const wasPreviouslyBound = this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);\r\n        this._unpackFlipY(!invertY); // Video are upside down by default\r\n\r\n        try {\r\n            // Testing video texture support\r\n            if (this._videoTextureSupported === undefined) {\r\n                // clear old errors just in case.\r\n                this._gl.getError();\r\n\r\n                this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, glformat, this._gl.UNSIGNED_BYTE, video);\r\n\r\n                if (this._gl.getError() !== 0) {\r\n                    this._videoTextureSupported = false;\r\n                } else {\r\n                    this._videoTextureSupported = true;\r\n                }\r\n            }\r\n\r\n            // Copy video through the current working canvas if video texture is not supported\r\n            if (!this._videoTextureSupported) {\r\n                if (!texture._workingCanvas) {\r\n                    texture._workingCanvas = this.createCanvas(texture.width, texture.height);\r\n                    const context = texture._workingCanvas.getContext(\"2d\");\r\n\r\n                    if (!context) {\r\n                        throw new Error(\"Unable to get 2d context\");\r\n                    }\r\n\r\n                    texture._workingContext = context;\r\n                    texture._workingCanvas.width = texture.width;\r\n                    texture._workingCanvas.height = texture.height;\r\n                }\r\n\r\n                texture._workingContext!.clearRect(0, 0, texture.width, texture.height);\r\n                texture._workingContext!.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, texture.width, texture.height);\r\n\r\n                this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, glformat, this._gl.UNSIGNED_BYTE, texture._workingCanvas as TexImageSource);\r\n            } else {\r\n                this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, glformat, this._gl.UNSIGNED_BYTE, video);\r\n            }\r\n\r\n            if (texture.generateMipMaps) {\r\n                this._gl.generateMipmap(this._gl.TEXTURE_2D);\r\n            }\r\n\r\n            if (!wasPreviouslyBound) {\r\n                this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n            }\r\n            //    this.resetTextureCache();\r\n            texture.isReady = true;\r\n        } catch (ex) {\r\n            // Something unexpected\r\n            // Let's disable the texture\r\n            texture._isDisabled = true;\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ImageSource } from \"../../types\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { ThinEngine } from \"../thinEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineTexture2DArrayImageSource.\r\n * Adds AbstractEngine.updateTextureArrayLayerFromImageSource on the WebGL2 engine.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineTexture2DArrayImageSource(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.updateTextureArrayLayerFromImageSource = function (\r\n        this: ThinEngine,\r\n        texture: InternalTexture,\r\n        source: ImageSource,\r\n        layer: number,\r\n        invertY: boolean = false,\r\n        premultiplyAlpha: boolean = false\r\n    ): void {\r\n        if (this.webGLVersion < 2) {\r\n            Logger.Error(\"updateTextureArrayLayerFromImageSource is only supported in WebGL2.\");\r\n            return;\r\n        }\r\n\r\n        const gl = this._gl as WebGL2RenderingContext;\r\n        const target = gl.TEXTURE_2D_ARRAY;\r\n\r\n        const textureType = this._getWebGLTextureType(texture.type);\r\n        const glFormat = this._getInternalFormat(texture.format);\r\n\r\n        this._bindTextureDirectly(target, texture, true);\r\n        this._unpackFlipY(invertY);\r\n\r\n        if (premultiplyAlpha) {\r\n            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);\r\n        }\r\n\r\n        gl.texSubImage3D(target, 0, 0, 0, layer, texture.width, texture.height, 1, glFormat, textureType, source as TexImageSource);\r\n\r\n        if (texture.generateMipMaps) {\r\n            gl.generateMipmap(target);\r\n        }\r\n\r\n        if (premultiplyAlpha) {\r\n            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\r\n        }\r\n\r\n        this._bindTextureDirectly(target, null);\r\n\r\n        texture.isReady = true;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ComputeEffect, type IComputeEffectCreationOptions, type IComputeShaderPath } from \"../../Compute/computeEffect\";\r\nimport { type IComputeContext } from \"../../Compute/IComputeContext\";\r\nimport { type IComputePipelineContext } from \"../../Compute/IComputePipelineContext\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n/**\r\n * Type used to locate a resource in a compute shader.\r\n * TODO: remove this when browsers support reflection for wgsl shaders\r\n */\r\nexport type ComputeBindingLocation = { group: number; binding: number };\r\n\r\n/**\r\n * Type used to lookup a resource and retrieve its binding location\r\n * TODO: remove this when browsers support reflection for wgsl shaders\r\n */\r\nexport type ComputeBindingMapping = { [key: string]: ComputeBindingLocation };\r\n\r\n/**\r\n * Types of messages that can be generated during compilation\r\n */\r\nexport type ComputeCompilationMessageType = \"error\" | \"warning\" | \"info\";\r\n\r\n/**\r\n * Messages generated during compilation\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface ComputeCompilationMessages {\r\n    /**\r\n     * Number of errors generated during compilation\r\n     */\r\n    numErrors: number;\r\n    /**\r\n     * List of messages generated during compilation\r\n     */\r\n    messages: {\r\n        type: ComputeCompilationMessageType;\r\n        text: string;\r\n        line?: number;\r\n        column?: number;\r\n        length?: number;\r\n        offset?: number;\r\n    }[];\r\n}\r\n\r\n/** @internal */\r\nexport const enum ComputeBindingType {\r\n    Texture = 0,\r\n    StorageTexture = 1,\r\n    UniformBuffer = 2,\r\n    StorageBuffer = 3,\r\n    TextureWithoutSampler = 4,\r\n    Sampler = 5,\r\n    ExternalTexture = 6,\r\n    DataBuffer = 7,\r\n    InternalTexture = 8,\r\n}\r\n\r\n/** @internal */\r\nexport type ComputeBindingList = { [key: string]: { type: ComputeBindingType; object: any; indexInGroupEntries?: number } };\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesExtensionsEngineComputeShader.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesExtensionsEngineComputeShader(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinEngine.prototype.createComputeEffect = function (baseName: IComputeShaderPath & { computeToken?: string }, options: IComputeEffectCreationOptions): ComputeEffect {\r\n        throw new Error(\"createComputeEffect: This engine does not support compute shaders!\");\r\n    };\r\n\r\n    ThinEngine.prototype.createComputePipelineContext = function (): IComputePipelineContext {\r\n        throw new Error(\"createComputePipelineContext: This engine does not support compute shaders!\");\r\n    };\r\n\r\n    ThinEngine.prototype.createComputeContext = function (): IComputeContext | undefined {\r\n        return undefined;\r\n    };\r\n\r\n    ThinEngine.prototype.computeDispatch = function (\r\n        effect: ComputeEffect,\r\n        context: IComputeContext,\r\n        bindings: ComputeBindingList,\r\n        x: number,\r\n        y?: number,\r\n        z?: number,\r\n        bindingsMapping?: ComputeBindingMapping\r\n    ): void {\r\n        throw new Error(\"computeDispatch: This engine does not support compute shaders!\");\r\n    };\r\n\r\n    ThinEngine.prototype.computeDispatchIndirect = function (\r\n        effect: ComputeEffect,\r\n        context: IComputeContext,\r\n        bindings: ComputeBindingList,\r\n        buffer: DataBuffer,\r\n        offset?: number,\r\n        bindingsMapping?: ComputeBindingMapping\r\n    ): void {\r\n        throw new Error(\"computeDispatchIndirect: This engine does not support compute shaders!\");\r\n    };\r\n\r\n    ThinEngine.prototype.areAllComputeEffectsReady = function (): boolean {\r\n        return true;\r\n    };\r\n\r\n    ThinEngine.prototype.releaseComputeEffects = function (): void {};\r\n\r\n    ThinEngine.prototype._prepareComputePipelineContext = function (\r\n        pipelineContext: IComputePipelineContext,\r\n        computeSourceCode: string,\r\n        rawComputeSourceCode: string,\r\n        defines: Nullable<string>,\r\n        entryPoint: string\r\n    ): void {};\r\n\r\n    ThinEngine.prototype._rebuildComputeEffects = function (): void {};\r\n\r\n    AbstractEngine.prototype._executeWhenComputeStateIsCompiled = function (\r\n        pipelineContext: IComputePipelineContext,\r\n        action: (messages: Nullable<ComputeCompilationMessages>) => void\r\n    ): void {\r\n        action(null);\r\n    };\r\n\r\n    ThinEngine.prototype._releaseComputeEffect = function (effect: ComputeEffect): void {};\r\n\r\n    ThinEngine.prototype._deleteComputePipelineContext = function (pipelineContext: IComputePipelineContext): void {};\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NativeDataStream, type NativeData } from \"./nativeDataStream\";\r\n\r\nimport { type INative } from \"./nativeInterfaces\";\r\nimport { ThinNativeEngine } from \"../thinNativeEngine.pure\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const _native: INative;\r\n\r\n/**\r\n * Validated Native Data Stream\r\n */\r\nexport class ValidatedNativeDataStream extends NativeDataStream {\r\n    constructor() {\r\n        super();\r\n    }\r\n\r\n    public override writeUint32(value: number): void {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_UINT_32);\r\n        super.writeUint32(value);\r\n    }\r\n\r\n    public override writeInt32(value: number): void {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_INT_32);\r\n        super.writeInt32(value);\r\n    }\r\n\r\n    public override writeFloat32(value: number): void {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_FLOAT_32);\r\n        super.writeFloat32(value);\r\n    }\r\n\r\n    public override writeUint32Array(values: Uint32Array): void {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_UINT_32_ARRAY);\r\n        super.writeUint32Array(values);\r\n    }\r\n\r\n    public override writeInt32Array(values: Int32Array): void {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_INT_32_ARRAY);\r\n        super.writeInt32Array(values);\r\n    }\r\n\r\n    public override writeFloat32Array(values: Float32Array): void {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_FLOAT_32_ARRAY);\r\n        super.writeFloat32Array(values);\r\n    }\r\n\r\n    public override writeNativeData(handle: NativeData) {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_NATIVE_DATA);\r\n        super.writeNativeData(handle);\r\n    }\r\n\r\n    public override writeBoolean(value: boolean) {\r\n        super.writeUint32(_native.NativeDataStream.VALIDATION_BOOLEAN);\r\n        super.writeBoolean(value);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for validatedNativeDataStream.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterValidatedNativeDataStream(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinNativeEngine._createNativeDataStream = function () {\r\n        if (_native.NativeDataStream.VALIDATION_ENABLED) {\r\n            return new ValidatedNativeDataStream();\r\n        } else {\r\n            return new NativeDataStream();\r\n        }\r\n    };\r\n}\r\n","import { Constants } from \"../Engines/constants\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess.pure\";\r\n\r\nimport { ApplyPostProcess } from \"./textureTools\";\r\n\r\nimport { type Texture } from \"../Materials/Textures/texture\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type Scene } from \"../scene\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Class used to host RGBD texture specific utilities\r\n */\r\nexport class RGBDTextureTools {\r\n    /**\r\n     * Expand the RGBD Texture from RGBD to Half Float if possible.\r\n     * @param texture the texture to expand.\r\n     */\r\n    public static ExpandRGBDTexture(texture: Texture) {\r\n        const internalTexture = texture._texture;\r\n        if (!internalTexture || !texture.isRGBD) {\r\n            return;\r\n        }\r\n\r\n        // Gets everything ready.\r\n        const engine = internalTexture.getEngine();\r\n        const caps = engine.getCaps();\r\n        const isReady = internalTexture.isReady;\r\n        let expandTexture = false;\r\n\r\n        // If half float available we can uncompress the texture\r\n        if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {\r\n            expandTexture = true;\r\n            internalTexture.type = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        }\r\n        // If full float available we can uncompress the texture\r\n        else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {\r\n            expandTexture = true;\r\n            internalTexture.type = Constants.TEXTURETYPE_FLOAT;\r\n        }\r\n\r\n        if (expandTexture) {\r\n            // Do not use during decode.\r\n            internalTexture.isReady = false;\r\n            internalTexture._isRGBD = false;\r\n            internalTexture.invertY = false;\r\n        }\r\n\r\n        const expandRgbdTextureAsync = async () => {\r\n            const isWebGpu = engine.isWebGPU;\r\n            const shaderLanguage = isWebGpu ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n            internalTexture.isReady = false;\r\n\r\n            if (isWebGpu) {\r\n                await import(\"../ShadersWGSL/rgbdDecode.fragment\");\r\n            } else {\r\n                await import(\"../Shaders/rgbdDecode.fragment\");\r\n            }\r\n\r\n            // Expand the texture if possible\r\n            // Simply run through the decode PP.\r\n            const rgbdPostProcess = new PostProcess(\r\n                \"rgbdDecode\",\r\n                \"rgbdDecode\",\r\n                null,\r\n                null,\r\n                1,\r\n                null,\r\n                Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                false,\r\n                undefined,\r\n                internalTexture.type,\r\n                undefined,\r\n                null,\r\n                false,\r\n                undefined,\r\n                shaderLanguage\r\n            );\r\n            rgbdPostProcess.externalTextureSamplerBinding = true;\r\n\r\n            // Hold the output of the decoding.\r\n            const expandedTexture = engine.createRenderTargetTexture(internalTexture.width, {\r\n                generateDepthBuffer: false,\r\n                generateMipMaps: false,\r\n                generateStencilBuffer: false,\r\n                samplingMode: internalTexture.samplingMode,\r\n                type: internalTexture.type,\r\n                format: Constants.TEXTUREFORMAT_RGBA,\r\n            });\r\n\r\n            rgbdPostProcess.onEffectCreatedObservable.addOnce((e) => {\r\n                e.executeWhenCompiled(() => {\r\n                    // PP Render Pass\r\n                    rgbdPostProcess.onApply = (effect) => {\r\n                        effect._bindTexture(\"textureSampler\", internalTexture);\r\n                        effect.setFloat2(\"scale\", 1, 1);\r\n                    };\r\n                    texture.getScene()?.postProcessManager.directRender([rgbdPostProcess], expandedTexture, true);\r\n\r\n                    // Cleanup\r\n                    engine.restoreDefaultFramebuffer();\r\n                    engine._releaseTexture(internalTexture);\r\n                    if (rgbdPostProcess) {\r\n                        rgbdPostProcess.dispose();\r\n                    }\r\n\r\n                    // Internal Swap\r\n                    expandedTexture._swapAndDie(internalTexture);\r\n\r\n                    // Ready to get rolling again.\r\n                    internalTexture.isReady = true;\r\n                });\r\n            });\r\n        };\r\n\r\n        if (expandTexture) {\r\n            if (isReady) {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n                expandRgbdTextureAsync();\r\n            } else {\r\n                // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n                texture.onLoadObservable.addOnce(expandRgbdTextureAsync);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Encode the texture to RGBD if possible.\r\n     * @param internalTexture the texture to encode\r\n     * @param scene the scene hosting the texture\r\n     * @param outputTextureType type of the texture in which the encoding is performed\r\n     * @returns a promise with the internalTexture having its texture replaced by the result of the processing\r\n     */\r\n    // Should have \"Async\" in the name but this is a breaking change.\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public static async EncodeTextureToRGBD(internalTexture: InternalTexture, scene: Scene, outputTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE): Promise<InternalTexture> {\r\n        if (!scene.getEngine().isWebGPU) {\r\n            await import(\"../Shaders/rgbdEncode.fragment\");\r\n        } else {\r\n            await import(\"../ShadersWGSL/rgbdEncode.fragment\");\r\n        }\r\n        return await ApplyPostProcess(\"rgbdEncode\", internalTexture, scene, outputTextureType, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTUREFORMAT_RGBA);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { _WarnImport } from \"./devTools\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EffectRenderer, EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Logger } from \"./logger\";\r\nimport { EncodeArrayBufferToBase64 } from \"./stringTools\";\r\nimport { nativeOverride } from \"./decorators\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\ntype DumpResources = {\r\n    canvas: HTMLCanvasElement | OffscreenCanvas;\r\n    dumpEngine: {\r\n        engine: ThinEngine;\r\n        renderer: EffectRenderer;\r\n        wrapper: EffectWrapper;\r\n    };\r\n};\r\n\r\nlet ResourcesPromise: Promise<DumpResources> | null = null;\r\n\r\nasync function _CreateDumpResourcesAsync(): Promise<DumpResources> {\r\n    // Create a compatible canvas. Prefer an HTMLCanvasElement if possible to avoid alpha issues with OffscreenCanvas + WebGL in many browsers.\r\n    const canvas = (EngineStore.LastCreatedEngine?.createCanvas(100, 100) ?? new OffscreenCanvas(100, 100)) as HTMLCanvasElement | OffscreenCanvas; // will be resized later\r\n    if (canvas instanceof OffscreenCanvas) {\r\n        Logger.Warn(\"DumpData: OffscreenCanvas will be used for dumping data. This may result in lossy alpha values.\");\r\n    }\r\n\r\n    // If WebGL via ThinEngine is not available, we cannot encode the data.\r\n    // If https://github.com/whatwg/html/issues/10142 is resolved, we can migrate to just BitmapRenderer and avoid an engine dependency altogether.\r\n    const { ThinEngine: thinEngineClass } = await import(\"../Engines/thinEngine.pure\");\r\n    if (!thinEngineClass.IsSupported) {\r\n        throw new Error(\"DumpData: No WebGL context available. Cannot dump data.\");\r\n    }\r\n\r\n    const options = {\r\n        preserveDrawingBuffer: true,\r\n        depth: false,\r\n        stencil: false,\r\n        alpha: true,\r\n        premultipliedAlpha: false,\r\n        antialias: false,\r\n        failIfMajorPerformanceCaveat: false,\r\n    };\r\n    const engine = new thinEngineClass(canvas, false, options);\r\n\r\n    // remove this engine from the list of instances to avoid using it for other purposes\r\n    EngineStore.Instances.pop();\r\n    // However, make sure to dispose it when no other engines are left\r\n    EngineStore.OnEnginesDisposedObservable.add((e) => {\r\n        // guaranteed to run when no other instances are left\r\n        // only dispose if it's not the current engine\r\n        if (engine && e !== engine && !engine.isDisposed && EngineStore.Instances.length === 0) {\r\n            // Dump the engine and the associated resources\r\n            Dispose();\r\n        }\r\n    });\r\n\r\n    engine.getCaps().parallelShaderCompile = undefined;\r\n\r\n    const renderer = new EffectRenderer(engine);\r\n    const { passPixelShader } = await import(\"../Shaders/pass.fragment\");\r\n    const wrapper = new EffectWrapper({\r\n        engine,\r\n        name: passPixelShader.name,\r\n        fragmentShader: passPixelShader.shader,\r\n        samplerNames: [\"textureSampler\"],\r\n    });\r\n\r\n    return {\r\n        canvas: canvas,\r\n        dumpEngine: { engine, renderer, wrapper },\r\n    };\r\n}\r\n\r\nasync function _GetDumpResourcesAsync() {\r\n    if (!ResourcesPromise) {\r\n        ResourcesPromise = _CreateDumpResourcesAsync();\r\n    }\r\n    return await ResourcesPromise;\r\n}\r\n\r\nclass EncodingHelper {\r\n    /**\r\n     * Encodes image data to the given mime type.\r\n     * This is put into a helper class so we can apply the nativeOverride decorator to it.\r\n     * @internal\r\n     */\r\n    @nativeOverride\r\n    public static async EncodeImageAsync(pixelData: ArrayBufferView, width: number, height: number, mimeType?: string, invertY?: boolean, quality?: number): Promise<Blob> {\r\n        const resources = await _GetDumpResourcesAsync();\r\n\r\n        const dumpEngine = resources.dumpEngine;\r\n        dumpEngine.engine.setSize(width, height, true);\r\n\r\n        // Create the image\r\n        const texture = dumpEngine.engine.createRawTexture(pixelData, width, height, Constants.TEXTUREFORMAT_RGBA, false, !invertY, Constants.TEXTURE_NEAREST_NEAREST);\r\n\r\n        dumpEngine.renderer.setViewport();\r\n        dumpEngine.renderer.applyEffectWrapper(dumpEngine.wrapper);\r\n        dumpEngine.wrapper.effect._bindTexture(\"textureSampler\", texture);\r\n        dumpEngine.renderer.draw();\r\n\r\n        texture.dispose();\r\n\r\n        return await new Promise<Blob>((resolve, reject) => {\r\n            Tools.ToBlob(\r\n                resources.canvas,\r\n                (blob) => {\r\n                    if (!blob) {\r\n                        reject(new Error(\"EncodeImageAsync: Failed to convert canvas to blob.\"));\r\n                    } else {\r\n                        resolve(blob);\r\n                    }\r\n                },\r\n                mimeType,\r\n                quality\r\n            );\r\n        });\r\n    }\r\n}\r\n\r\n/**\r\n * Encodes pixel data to an image\r\n * @param pixelData 8-bit RGBA pixel data\r\n * @param width the width of the image\r\n * @param height the height of the image\r\n * @param mimeType the requested MIME type\r\n * @param invertY true to invert the image in the Y direction\r\n * @param quality the quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @returns a promise that resolves to the encoded image data. Note that the `blob.type` may differ from `mimeType` if it was not supported.\r\n */\r\nexport const EncodeImageAsync = EncodingHelper.EncodeImageAsync;\r\n\r\n/**\r\n * Dumps the current bound framebuffer\r\n * @param width defines the rendering width\r\n * @param height defines the rendering height\r\n * @param engine defines the hosting engine\r\n * @param successCallback defines the callback triggered once the data are available\r\n * @param mimeType defines the mime type of the result\r\n * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @returns a void promise\r\n */\r\n// Should have \"Async\" in the name but this is a public API and we can't break it now\r\n// eslint-disable-next-line no-restricted-syntax\r\nexport async function DumpFramebuffer(\r\n    width: number,\r\n    height: number,\r\n    engine: AbstractEngine,\r\n    successCallback?: (data: string) => void,\r\n    mimeType = \"image/png\",\r\n    fileName?: string,\r\n    quality?: number\r\n) {\r\n    // Read the contents of the framebuffer\r\n    const bufferView = await engine.readPixels(0, 0, width, height);\r\n\r\n    const data = new Uint8Array(bufferView.buffer);\r\n\r\n    DumpData(width, height, data, successCallback as (data: string | ArrayBuffer) => void, mimeType, fileName, true, undefined, quality);\r\n}\r\n\r\nexport async function DumpDataAsync(\r\n    width: number,\r\n    height: number,\r\n    data: ArrayBufferView,\r\n    mimeType: string | undefined,\r\n    fileName: string | undefined,\r\n    invertY: boolean | undefined,\r\n    toArrayBuffer: true,\r\n    quality?: number\r\n): Promise<ArrayBuffer>;\r\nexport async function DumpDataAsync(\r\n    width: number,\r\n    height: number,\r\n    data: ArrayBufferView,\r\n    mimeType?: string,\r\n    fileName?: string,\r\n    invertY?: boolean,\r\n    toArrayBuffer?: boolean,\r\n    quality?: number\r\n): Promise<string>;\r\n/**\r\n * Dumps an array buffer\r\n * @param width defines the rendering width\r\n * @param height defines the rendering height\r\n * @param data the data array\r\n * @param mimeType defines the mime type of the result\r\n * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n * @param invertY true to invert the picture in the Y dimension\r\n * @param toArrayBuffer true to convert the data to an ArrayBuffer (encoded as `mimeType`) instead of a base64 string\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @returns a promise that resolve to the final data\r\n */\r\nexport async function DumpDataAsync(\r\n    width: number,\r\n    height: number,\r\n    data: ArrayBufferView,\r\n    mimeType = \"image/png\",\r\n    fileName?: string,\r\n    invertY = false,\r\n    toArrayBuffer = false,\r\n    quality?: number\r\n): Promise<string | ArrayBuffer> {\r\n    // Convert if data are float32\r\n    if (data instanceof Float32Array) {\r\n        const data2 = new Uint8Array(data.length);\r\n        let n = data.length;\r\n        while (n--) {\r\n            const v = data[n];\r\n            data2[n] = Math.round(Clamp(v) * 255);\r\n        }\r\n        data = data2;\r\n    }\r\n\r\n    const blob = await EncodingHelper.EncodeImageAsync(data, width, height, mimeType, invertY, quality);\r\n\r\n    if (fileName !== undefined) {\r\n        Tools.DownloadBlob(blob, fileName);\r\n    }\r\n\r\n    if (blob.type !== mimeType) {\r\n        Logger.Warn(`DumpData: The requested mimeType '${mimeType}' is not supported. The result has mimeType '${blob.type}' instead.`);\r\n    }\r\n\r\n    const buffer = await blob.arrayBuffer();\r\n\r\n    if (toArrayBuffer) {\r\n        return buffer;\r\n    }\r\n\r\n    return `data:${mimeType};base64,${EncodeArrayBufferToBase64(buffer)}`;\r\n}\r\n\r\n/**\r\n * Dumps an array buffer\r\n * @param width defines the rendering width\r\n * @param height defines the rendering height\r\n * @param data the data array\r\n * @param successCallback defines the callback triggered once the data are available\r\n * @param mimeType defines the mime type of the result\r\n * @param fileName The name of the file to download. If present, the result will automatically be downloaded. If not defined, and `successCallback` is also not defined, the result will automatically be downloaded with an auto-generated file name.\r\n * @param invertY true to invert the picture in the Y dimension\r\n * @param toArrayBuffer true to convert the data to an ArrayBuffer (encoded as `mimeType`) instead of a base64 string\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n */\r\nexport function DumpData(\r\n    width: number,\r\n    height: number,\r\n    data: ArrayBufferView,\r\n    successCallback?: (data: string | ArrayBuffer) => void,\r\n    mimeType = \"image/png\",\r\n    fileName?: string,\r\n    invertY = false,\r\n    toArrayBuffer = false,\r\n    quality?: number\r\n): void {\r\n    // For back-compat: if no fileName and no callback, force download the result\r\n    if (fileName === undefined && !successCallback) {\r\n        fileName = \"\";\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n    DumpDataAsync(width, height, data, mimeType, fileName, invertY, toArrayBuffer, quality)\r\n        // eslint-disable-next-line github/no-then\r\n        .then((result) => {\r\n            if (successCallback) {\r\n                successCallback(result);\r\n            }\r\n        });\r\n}\r\n\r\n/**\r\n * Dispose the dump tools associated resources\r\n */\r\nexport function Dispose() {\r\n    if (!ResourcesPromise) {\r\n        return;\r\n    }\r\n\r\n    // in cases where the engine is not yet created, we need to wait for it to dispose it\r\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n    ResourcesPromise?.then((resources) => {\r\n        if (resources.canvas instanceof HTMLCanvasElement) {\r\n            resources.canvas.remove();\r\n        }\r\n        if (resources.dumpEngine) {\r\n            resources.dumpEngine.engine.dispose();\r\n            resources.dumpEngine.renderer.dispose();\r\n            resources.dumpEngine.wrapper.dispose();\r\n        }\r\n    });\r\n\r\n    ResourcesPromise = null;\r\n}\r\n\r\n/**\r\n * Object containing a set of static utilities functions to dump data from a canvas\r\n * @deprecated use functions\r\n */\r\nexport const DumpTools = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    DumpData,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    DumpDataAsync,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    DumpFramebuffer,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    Dispose,\r\n};\r\n\r\n/**\r\n * This will be executed automatically for UMD and es5.\r\n * If esm dev wants the side effects to execute they will have to run it manually\r\n * Once we build native modules those need to be exported.\r\n * @internal\r\n */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for dumpTools.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDumpTools(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const InitSideEffects = () => {\r\n        // References the dependencies.\r\n        Tools.DumpData = DumpData;\r\n        Tools.DumpDataAsync = DumpDataAsync;\r\n        Tools.DumpFramebuffer = DumpFramebuffer;\r\n    };\r\n\r\n    InitSideEffects();\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { IsExponentOfTwo } from \"./tools.functions\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { ILog2 } from \"../Maths/math.scalar.functions\";\r\nimport { SphericalPolynomial } from \"../Maths/sphericalPolynomial.pure\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { RGBDTextureTools } from \"./rgbdTextureTools\";\r\nimport { DumpDataAsync } from \"../Misc/dumpTools.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\nimport { type RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { type Engine, type WebGPUEngine } from \"core/Engines\";\r\n\r\nimport { GetBlobBufferSource } from \"../Buffers/bufferUtils\";\r\n\r\nconst DefaultEnvironmentTextureImageType = \"image/png\";\r\nconst CurrentVersion = 2;\r\n\r\n/**\r\n * Raw texture data and descriptor sufficient for WebGL texture upload\r\n */\r\nexport type EnvironmentTextureInfo = EnvironmentTextureInfoV1 | EnvironmentTextureInfoV2;\r\n\r\n/**\r\n * v1 of EnvironmentTextureInfo\r\n */\r\ninterface EnvironmentTextureInfoV1 {\r\n    /**\r\n     * Version of the environment map\r\n     */\r\n    version: 1;\r\n\r\n    /**\r\n     * Width of image\r\n     */\r\n    width: number;\r\n\r\n    /**\r\n     * Irradiance information stored in the file.\r\n     */\r\n    irradiance: Nullable<EnvironmentTextureIrradianceInfoV1>;\r\n\r\n    /**\r\n     * Specular information stored in the file.\r\n     */\r\n    specular: EnvironmentTextureSpecularInfoV1;\r\n}\r\n\r\n/**\r\n * v2 of EnvironmentTextureInfo\r\n */\r\ninterface EnvironmentTextureInfoV2 {\r\n    /**\r\n     * Version of the environment map\r\n     */\r\n    version: 2;\r\n\r\n    /**\r\n     * Width of image\r\n     */\r\n    width: number;\r\n\r\n    /**\r\n     * Irradiance information stored in the file.\r\n     */\r\n    irradiance: Nullable<EnvironmentTextureIrradianceInfoV1>;\r\n\r\n    /**\r\n     * Specular information stored in the file.\r\n     */\r\n    specular: EnvironmentTextureSpecularInfoV1;\r\n\r\n    /**\r\n     * The mime type used to encode the image data.\r\n     */\r\n    imageType: string;\r\n\r\n    /**\r\n     * Defines where the specular Payload is located. It is a runtime value only not stored in the file.\r\n     */\r\n    binaryDataPosition?: number;\r\n}\r\n\r\n/**\r\n * Defines One Image in the file. It requires only the position in the file\r\n * as well as the length.\r\n */\r\ninterface BufferImageData {\r\n    /**\r\n     * Length of the image data.\r\n     */\r\n    length: number;\r\n    /**\r\n     * Position of the data from the null terminator delimiting the end of the JSON.\r\n     */\r\n    position: number;\r\n}\r\n\r\n/**\r\n * Defines the diffuse data enclosed in the file.\r\n * This corresponds to the version 1 of the data.\r\n */\r\nexport interface EnvironmentTextureIrradianceTextureInfoV1 {\r\n    /**\r\n     * Size of the texture faces.\r\n     */\r\n    size: number;\r\n    /**\r\n     * This contains all the images data needed to reconstruct the cubemap.\r\n     */\r\n    faces: Array<BufferImageData>;\r\n\r\n    /**\r\n     * The dominant direction of light in the environment texture.\r\n     */\r\n    dominantDirection?: Array<number>;\r\n}\r\n\r\n/**\r\n * Defines the specular data enclosed in the file.\r\n * This corresponds to the version 1 of the data.\r\n */\r\nexport interface EnvironmentTextureSpecularInfoV1 {\r\n    /**\r\n     * This contains all the images data needed to reconstruct the cubemap.\r\n     */\r\n    mipmaps: Array<BufferImageData>;\r\n\r\n    /**\r\n     * Defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness.\r\n     */\r\n    lodGenerationScale: number;\r\n}\r\n\r\n/**\r\n * Defines the required storage to save the environment irradiance information.\r\n */\r\ninterface EnvironmentTextureIrradianceInfoV1 {\r\n    x: Array<number>;\r\n    y: Array<number>;\r\n    z: Array<number>;\r\n\r\n    xx: Array<number>;\r\n    yy: Array<number>;\r\n    zz: Array<number>;\r\n\r\n    yz: Array<number>;\r\n    zx: Array<number>;\r\n    xy: Array<number>;\r\n\r\n    irradianceTexture?: EnvironmentTextureIrradianceTextureInfoV1 | undefined;\r\n}\r\n\r\n/**\r\n * Options for creating environment textures\r\n */\r\nexport interface CreateEnvTextureOptions {\r\n    /**\r\n     * The mime type of encoded images.\r\n     */\r\n    imageType?: string;\r\n\r\n    /**\r\n     * the image quality of encoded WebP images.\r\n     */\r\n    imageQuality?: number;\r\n\r\n    /**\r\n     * Disables the generation of irradiance texture even if present on the source.\r\n     */\r\n    disableIrradianceTexture?: boolean;\r\n}\r\n\r\n/**\r\n * Magic number identifying the env file.\r\n */\r\nconst MagicBytes = [0x86, 0x16, 0x87, 0x96, 0xf6, 0xd6, 0x96, 0x36];\r\n\r\n/**\r\n * Gets the environment info from an env file.\r\n * @param data The array buffer containing the .env bytes.\r\n * @returns the environment file info (the json header) if successfully parsed, normalized to the latest supported version.\r\n */\r\nexport function GetEnvInfo(data: ArrayBufferView): Nullable<EnvironmentTextureInfoV2> {\r\n    const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\r\n    let pos = 0;\r\n\r\n    for (let i = 0; i < MagicBytes.length; i++) {\r\n        if (dataView.getUint8(pos++) !== MagicBytes[i]) {\r\n            Logger.Error(\"Not a babylon environment map\");\r\n            return null;\r\n        }\r\n    }\r\n\r\n    // Read json manifest - collect characters up to null terminator\r\n    let manifestString = \"\";\r\n    let charCode: number;\r\n    while ((charCode = dataView.getUint8(pos++))) {\r\n        manifestString += String.fromCharCode(charCode);\r\n    }\r\n\r\n    let manifest: EnvironmentTextureInfo = JSON.parse(manifestString);\r\n    manifest = normalizeEnvInfo(manifest);\r\n    // Extend the header with the position of the payload.\r\n    manifest.binaryDataPosition = pos;\r\n\r\n    if (manifest.specular) {\r\n        // Fallback to 0.8 exactly if lodGenerationScale is not defined for backward compatibility.\r\n        manifest.specular.lodGenerationScale = manifest.specular.lodGenerationScale || 0.8;\r\n    }\r\n\r\n    return manifest;\r\n}\r\n\r\n/**\r\n * Normalizes any supported version of the environment file info to the latest version\r\n * @param info environment file info on any supported version\r\n * @returns environment file info in the latest supported version\r\n * @private\r\n */\r\nexport function normalizeEnvInfo(info: EnvironmentTextureInfo): EnvironmentTextureInfoV2 {\r\n    if (info.version > CurrentVersion) {\r\n        throw new Error(`Unsupported babylon environment map version \"${info.version}\". Latest supported version is \"${CurrentVersion}\".`);\r\n    }\r\n\r\n    if (info.version === 2) {\r\n        return info;\r\n    }\r\n\r\n    // Migrate a v1 info to v2\r\n    info = { ...info, version: 2, imageType: DefaultEnvironmentTextureImageType };\r\n\r\n    return info;\r\n}\r\n\r\n/**\r\n * Creates an environment texture from a loaded cube texture.\r\n * @param texture defines the cube texture to convert in env file\r\n * @param options options for the conversion process\r\n * @returns a promise containing the environment data if successful.\r\n */\r\nexport async function CreateEnvTextureAsync(texture: BaseTexture, options: CreateEnvTextureOptions = {}): Promise<ArrayBuffer> {\r\n    const internalTexture = texture.getInternalTexture();\r\n    if (!internalTexture) {\r\n        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n        return await Promise.reject(\"The cube texture is invalid.\");\r\n    }\r\n\r\n    const engine = internalTexture.getEngine();\r\n\r\n    if (\r\n        texture.textureType !== Constants.TEXTURETYPE_HALF_FLOAT &&\r\n        texture.textureType !== Constants.TEXTURETYPE_FLOAT &&\r\n        texture.textureType !== Constants.TEXTURETYPE_UNSIGNED_BYTE &&\r\n        texture.textureType !== Constants.TEXTURETYPE_UNSIGNED_BYTE &&\r\n        texture.textureType !== Constants.TEXTURETYPE_UNSIGNED_INTEGER &&\r\n        texture.textureType !== -1\r\n    ) {\r\n        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n        return await Promise.reject(\"The cube texture should allow HDR (Full Float or Half Float).\");\r\n    }\r\n\r\n    let textureType = Constants.TEXTURETYPE_FLOAT;\r\n    if (!engine.getCaps().textureFloatRender) {\r\n        textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        if (!engine.getCaps().textureHalfFloatRender) {\r\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n            return await Promise.reject(\"Env texture can only be created when the browser supports half float or full float rendering.\");\r\n        }\r\n    }\r\n\r\n    // sphericalPolynomial is lazy loaded so simply accessing it should trigger the computation.\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-expressions\r\n    texture.sphericalPolynomial;\r\n\r\n    // Lets keep track of the polynomial promise so we can wait for it to be ready before generating the pixels.\r\n    const sphericalPolynomialPromise = texture.getInternalTexture()?._sphericalPolynomialPromise;\r\n\r\n    const cubeWidth = internalTexture.width;\r\n    const hostingScene = new Scene(engine);\r\n    const specularTextures: { [key: number]: ArrayBuffer } = {};\r\n    const diffuseTextures: { [key: number]: ArrayBuffer } = {};\r\n\r\n    // As we are going to readPixels the faces of the cube, make sure the drawing/update commands for the cube texture are fully sent to the GPU in case it is drawn for the first time in this very frame!\r\n    engine.flushFramebuffer();\r\n\r\n    const imageType = options.imageType ?? DefaultEnvironmentTextureImageType;\r\n\r\n    // Read and collect all mipmaps data from the cube.\r\n    const mipmapsCount = ILog2(internalTexture.width);\r\n    for (let i = 0; i <= mipmapsCount; i++) {\r\n        const faceWidth = Math.pow(2, mipmapsCount - i);\r\n\r\n        // All faces of the cube.\r\n        for (let face = 0; face < 6; face++) {\r\n            // eslint-disable-next-line no-await-in-loop\r\n            specularTextures[i * 6 + face] = await _GetTextureEncodedDataAsync(hostingScene, texture, textureType, face, i, faceWidth, imageType, options.imageQuality);\r\n        }\r\n    }\r\n\r\n    // Read and collect all irradiance data from the cube.\r\n    const irradianceTexture = options.disableIrradianceTexture ? null : texture.irradianceTexture;\r\n    if (irradianceTexture) {\r\n        const faceWidth = irradianceTexture.getSize().width;\r\n\r\n        // All faces of the cube.\r\n        for (let face = 0; face < 6; face++) {\r\n            // eslint-disable-next-line no-await-in-loop\r\n            diffuseTextures[face] = await _GetTextureEncodedDataAsync(hostingScene, irradianceTexture, textureType, face, 0, faceWidth, imageType, options.imageQuality);\r\n        }\r\n    }\r\n\r\n    // We can delete the hosting scene keeping track of all the creation objects\r\n    hostingScene.dispose();\r\n\r\n    // Ensure completion of the polynomial creation promise.\r\n    if (sphericalPolynomialPromise) {\r\n        await sphericalPolynomialPromise;\r\n    }\r\n\r\n    // Creates the json header for the env texture\r\n    const info: EnvironmentTextureInfo = {\r\n        version: CurrentVersion,\r\n        width: cubeWidth,\r\n        imageType,\r\n        irradiance: CreateEnvTextureIrradiance(texture),\r\n        specular: {\r\n            mipmaps: [],\r\n            lodGenerationScale: texture.lodGenerationScale,\r\n        },\r\n    };\r\n\r\n    // Sets the specular image data information\r\n    let position = 0;\r\n    for (let i = 0; i <= mipmapsCount; i++) {\r\n        for (let face = 0; face < 6; face++) {\r\n            const byteLength = specularTextures[i * 6 + face].byteLength;\r\n            info.specular.mipmaps.push({\r\n                length: byteLength,\r\n                position: position,\r\n            });\r\n            position += byteLength;\r\n        }\r\n    }\r\n\r\n    // Sets the irradiance image data information\r\n    if (irradianceTexture) {\r\n        info.irradiance = info.irradiance || {\r\n            x: [0, 0, 0],\r\n            xx: [0, 0, 0],\r\n            y: [0, 0, 0],\r\n            yy: [0, 0, 0],\r\n            z: [0, 0, 0],\r\n            zz: [0, 0, 0],\r\n            yz: [0, 0, 0],\r\n            zx: [0, 0, 0],\r\n            xy: [0, 0, 0],\r\n        };\r\n        info.irradiance.irradianceTexture = {\r\n            size: irradianceTexture.getSize().width,\r\n            faces: [],\r\n            dominantDirection: irradianceTexture._dominantDirection?.asArray(),\r\n        };\r\n\r\n        for (let face = 0; face < 6; face++) {\r\n            const byteLength = diffuseTextures[face].byteLength;\r\n            info.irradiance.irradianceTexture.faces.push({\r\n                length: byteLength,\r\n                position: position,\r\n            });\r\n            position += byteLength;\r\n        }\r\n    }\r\n\r\n    // Encode the JSON as an array buffer\r\n    const infoString = JSON.stringify(info);\r\n    const infoBuffer = new ArrayBuffer(infoString.length + 1);\r\n    const infoView = new Uint8Array(infoBuffer); // Limited to ascii subset matching unicode.\r\n    for (let i = 0, strLen = infoString.length; i < strLen; i++) {\r\n        infoView[i] = infoString.charCodeAt(i);\r\n    }\r\n    // Ends up with a null terminator for easier parsing\r\n    infoView[infoString.length] = 0x00;\r\n\r\n    // Computes the final required size and creates the storage\r\n    const totalSize = MagicBytes.length + position + infoBuffer.byteLength;\r\n    const finalBuffer = new ArrayBuffer(totalSize);\r\n    const finalBufferView = new Uint8Array(finalBuffer);\r\n    const dataView = new DataView(finalBuffer);\r\n\r\n    // Copy the magic bytes identifying the file in\r\n    let pos = 0;\r\n    for (let i = 0; i < MagicBytes.length; i++) {\r\n        dataView.setUint8(pos++, MagicBytes[i]);\r\n    }\r\n\r\n    // Add the json info\r\n    finalBufferView.set(new Uint8Array(infoBuffer), pos);\r\n    pos += infoBuffer.byteLength;\r\n\r\n    // Finally inserts the radiance texture data\r\n    for (let i = 0; i <= mipmapsCount; i++) {\r\n        for (let face = 0; face < 6; face++) {\r\n            const dataBuffer = specularTextures[i * 6 + face];\r\n            finalBufferView.set(new Uint8Array(dataBuffer), pos);\r\n            pos += dataBuffer.byteLength;\r\n        }\r\n    }\r\n\r\n    // Finally inserts the irradiance texture data\r\n    if (irradianceTexture) {\r\n        for (let face = 0; face < 6; face++) {\r\n            const dataBuffer = diffuseTextures[face];\r\n            finalBufferView.set(new Uint8Array(dataBuffer), pos);\r\n            pos += dataBuffer.byteLength;\r\n        }\r\n    }\r\n\r\n    // Voila\r\n    return finalBuffer;\r\n}\r\n\r\n/**\r\n * Get the texture encoded data from the current texture\r\n * @internal\r\n */\r\nasync function _GetTextureEncodedDataAsync(\r\n    hostingScene: Scene,\r\n    texture: BaseTexture,\r\n    textureType: number,\r\n    face: number,\r\n    i: number,\r\n    size: number,\r\n    imageType: string,\r\n    imageQuality?: number\r\n) {\r\n    let faceData = await texture.readPixels(face, i, undefined, false);\r\n    if (faceData && faceData.byteLength === (faceData as Uint8Array).length) {\r\n        const faceDataFloat = new Float32Array(faceData.byteLength * 4);\r\n        for (let i = 0; i < faceData.byteLength; i++) {\r\n            faceDataFloat[i] = (faceData as Uint8Array)[i] / 255;\r\n            // Gamma to linear\r\n            faceDataFloat[i] = Math.pow(faceDataFloat[i], 2.2);\r\n        }\r\n        faceData = faceDataFloat;\r\n    } else if (faceData && texture.gammaSpace) {\r\n        const floatData = faceData as Float32Array;\r\n        for (let i = 0; i < floatData.length; i++) {\r\n            // Gamma to linear\r\n            floatData[i] = Math.pow(floatData[i], 2.2);\r\n        }\r\n    }\r\n\r\n    const engine = hostingScene.getEngine();\r\n    const tempTexture = engine.createRawTexture(faceData, size, size, Constants.TEXTUREFORMAT_RGBA, false, true, Constants.TEXTURE_NEAREST_SAMPLINGMODE, null, textureType);\r\n\r\n    await RGBDTextureTools.EncodeTextureToRGBD(tempTexture, hostingScene, textureType);\r\n\r\n    const rgbdEncodedData = await engine._readTexturePixels(tempTexture, size, size);\r\n\r\n    const imageEncodedData = await DumpDataAsync(size, size, rgbdEncodedData, imageType, undefined, false, true, imageQuality);\r\n\r\n    tempTexture.dispose();\r\n\r\n    return imageEncodedData as ArrayBuffer;\r\n}\r\n\r\n/**\r\n * Creates a JSON representation of the spherical data.\r\n * @param texture defines the texture containing the polynomials\r\n * @returns the JSON representation of the spherical info\r\n */\r\nfunction CreateEnvTextureIrradiance(texture: BaseTexture): Nullable<EnvironmentTextureIrradianceInfoV1> {\r\n    const polynmials = texture.sphericalPolynomial;\r\n    if (polynmials == null) {\r\n        return null;\r\n    }\r\n\r\n    return {\r\n        x: [polynmials.x.x, polynmials.x.y, polynmials.x.z],\r\n        y: [polynmials.y.x, polynmials.y.y, polynmials.y.z],\r\n        z: [polynmials.z.x, polynmials.z.y, polynmials.z.z],\r\n\r\n        xx: [polynmials.xx.x, polynmials.xx.y, polynmials.xx.z],\r\n        yy: [polynmials.yy.x, polynmials.yy.y, polynmials.yy.z],\r\n        zz: [polynmials.zz.x, polynmials.zz.y, polynmials.zz.z],\r\n\r\n        yz: [polynmials.yz.x, polynmials.yz.y, polynmials.yz.z],\r\n        zx: [polynmials.zx.x, polynmials.zx.y, polynmials.zx.z],\r\n        xy: [polynmials.xy.x, polynmials.xy.y, polynmials.xy.z],\r\n    };\r\n}\r\n\r\n/**\r\n * Creates the ArrayBufferViews used for initializing environment texture image data.\r\n * @param data the image data\r\n * @param info parameters that determine what views will be created for accessing the underlying buffer\r\n * @returns the views described by info providing access to the underlying buffer\r\n */\r\nexport function CreateRadianceImageDataArrayBufferViews(data: ArrayBufferView, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>> {\r\n    info = normalizeEnvInfo(info);\r\n\r\n    const specularInfo = info.specular;\r\n\r\n    // Double checks the enclosed info\r\n    let mipmapsCount = Math.log2(info.width);\r\n    mipmapsCount = Math.round(mipmapsCount) + 1;\r\n    if (specularInfo.mipmaps.length !== 6 * mipmapsCount) {\r\n        throw new Error(`Unsupported specular mipmaps number \"${specularInfo.mipmaps.length}\"`);\r\n    }\r\n\r\n    const imageData = new Array<Array<ArrayBufferView>>(mipmapsCount);\r\n    for (let i = 0; i < mipmapsCount; i++) {\r\n        imageData[i] = new Array<ArrayBufferView>(6);\r\n        for (let face = 0; face < 6; face++) {\r\n            const imageInfo = specularInfo.mipmaps[i * 6 + face];\r\n            imageData[i][face] = new Uint8Array(data.buffer, data.byteOffset + info.binaryDataPosition! + imageInfo.position, imageInfo.length);\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * Creates the ArrayBufferViews used for initializing environment texture image data.\r\n * @param data the image data\r\n * @param info parameters that determine what views will be created for accessing the underlying buffer\r\n * @returns the views described by info providing access to the underlying buffer\r\n */\r\nexport function CreateIrradianceImageDataArrayBufferViews(data: ArrayBufferView, info: EnvironmentTextureInfo): Array<ArrayBufferView> {\r\n    info = normalizeEnvInfo(info);\r\n\r\n    const imageData = new Array<ArrayBufferView>(6);\r\n\r\n    const irradianceTexture = info.irradiance?.irradianceTexture;\r\n    if (irradianceTexture) {\r\n        if (irradianceTexture.faces.length !== 6) {\r\n            throw new Error(`Incorrect irradiance texture faces number \"${irradianceTexture.faces.length}\"`);\r\n        }\r\n\r\n        for (let face = 0; face < 6; face++) {\r\n            const imageInfo = irradianceTexture.faces[face];\r\n            imageData[face] = new Uint8Array(data.buffer, data.byteOffset + info.binaryDataPosition! + imageInfo.position, imageInfo.length);\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * Uploads the texture info contained in the env file to the GPU.\r\n * @param texture defines the internal texture to upload to\r\n * @param data defines the data to load\r\n * @param info defines the texture info retrieved through the GetEnvInfo method\r\n * @returns a promise\r\n */\r\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\nexport function UploadEnvLevelsAsync(texture: InternalTexture, data: ArrayBufferView, info: EnvironmentTextureInfo): Promise<void[]> {\r\n    info = normalizeEnvInfo(info);\r\n\r\n    const specularInfo = info.specular;\r\n    if (!specularInfo) {\r\n        // Nothing else parsed so far\r\n        return Promise.resolve([]);\r\n    }\r\n\r\n    texture._lodGenerationScale = specularInfo.lodGenerationScale;\r\n\r\n    const promises: Promise<void>[] = [];\r\n\r\n    const radianceImageData = CreateRadianceImageDataArrayBufferViews(data, info);\r\n    promises.push(UploadRadianceLevelsAsync(texture, radianceImageData, info.imageType));\r\n\r\n    const irradianceTexture = info.irradiance?.irradianceTexture;\r\n    if (irradianceTexture) {\r\n        const irradianceImageData = CreateIrradianceImageDataArrayBufferViews(data, info);\r\n        let dominantDirection = null;\r\n        if (info.irradiance?.irradianceTexture?.dominantDirection) {\r\n            dominantDirection = Vector3.FromArray(info.irradiance.irradianceTexture.dominantDirection);\r\n        }\r\n        promises.push(UploadIrradianceLevelsAsync(texture, irradianceImageData, irradianceTexture.size, info.imageType, dominantDirection));\r\n    }\r\n\r\n    return Promise.all(promises);\r\n}\r\n\r\nasync function _OnImageReadyAsync(\r\n    image: HTMLImageElement | ImageBitmap,\r\n    engine: Engine | WebGPUEngine,\r\n    expandTexture: boolean,\r\n    rgbdPostProcess: Nullable<PostProcess>,\r\n    url: string,\r\n    face: number,\r\n    i: number,\r\n    generateNonLODTextures: boolean,\r\n    lodTextures: Nullable<{ [lod: number]: BaseTexture }>,\r\n    cubeRtt: Nullable<RenderTargetWrapper>,\r\n    texture: InternalTexture\r\n): Promise<void> {\r\n    return await new Promise((resolve, reject) => {\r\n        if (expandTexture) {\r\n            const tempTexture = engine.createTexture(\r\n                null,\r\n                true,\r\n                true,\r\n                null,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                null,\r\n                (message) => {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(message);\r\n                },\r\n                image\r\n            );\r\n\r\n            rgbdPostProcess?.onEffectCreatedObservable.addOnce((effect) => {\r\n                effect.executeWhenCompiled(() => {\r\n                    // Uncompress the data to a RTT\r\n                    rgbdPostProcess.externalTextureSamplerBinding = true;\r\n                    rgbdPostProcess.onApply = (effect) => {\r\n                        effect._bindTexture(\"textureSampler\", tempTexture);\r\n                        effect.setFloat2(\"scale\", 1, engine._features.needsInvertingBitmap && image instanceof ImageBitmap ? -1 : 1);\r\n                    };\r\n\r\n                    if (!engine.scenes.length) {\r\n                        return;\r\n                    }\r\n\r\n                    engine.scenes[0].postProcessManager.directRender([rgbdPostProcess], cubeRtt, true, face, i);\r\n\r\n                    // Cleanup\r\n                    engine.restoreDefaultFramebuffer();\r\n                    tempTexture.dispose();\r\n                    URL.revokeObjectURL(url);\r\n                    resolve();\r\n                });\r\n            });\r\n        } else {\r\n            engine._uploadImageToTexture(texture, image, face, i);\r\n\r\n            // Upload the face to the non lod texture support\r\n            if (generateNonLODTextures) {\r\n                const lodTexture = lodTextures![i];\r\n                if (lodTexture) {\r\n                    engine._uploadImageToTexture(lodTexture._texture!, image, face, 0);\r\n                }\r\n            }\r\n            resolve();\r\n        }\r\n    });\r\n}\r\n\r\n/**\r\n * Uploads the levels of image data to the GPU.\r\n * @param texture defines the internal texture to upload to\r\n * @param imageData defines the array buffer views of image data [mipmap][face]\r\n * @param imageType the mime type of the image data\r\n * @returns a promise\r\n */\r\nexport async function UploadRadianceLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][], imageType: string = DefaultEnvironmentTextureImageType): Promise<void> {\r\n    const engine = texture.getEngine() as Engine;\r\n    texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n    texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    texture.generateMipMaps = true;\r\n    texture._cachedAnisotropicFilteringLevel = null;\r\n    engine.updateTextureSamplingMode(Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, texture);\r\n\r\n    await _UploadLevelsAsync(texture, imageData, true, imageType);\r\n\r\n    // Flag internal texture as ready in case they are in use.\r\n    texture.isReady = true;\r\n}\r\n\r\n/**\r\n * Uploads the levels of image data to the GPU.\r\n * @param mainTexture defines the internal texture to upload to\r\n * @param imageData defines the array buffer views of image data [mipmap][face]\r\n * @param size defines the size of the texture faces\r\n * @param imageType the mime type of the image data\r\n * @param dominantDirection the dominant direction of light in the environment texture, if available\r\n * @returns a promise\r\n */\r\nexport async function UploadIrradianceLevelsAsync(\r\n    mainTexture: InternalTexture,\r\n    imageData: ArrayBufferView[],\r\n    size: number,\r\n    imageType: string = DefaultEnvironmentTextureImageType,\r\n    dominantDirection: Nullable<Vector3> = null\r\n): Promise<void> {\r\n    // Gets everything ready.\r\n    const engine = mainTexture.getEngine() as Engine;\r\n    const texture = new InternalTexture(engine, InternalTextureSource.RenderTarget);\r\n    const baseTexture = new BaseTexture(engine, texture);\r\n    mainTexture._irradianceTexture = baseTexture;\r\n    baseTexture._dominantDirection = dominantDirection;\r\n    texture.isCube = true;\r\n    texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n    texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    texture.generateMipMaps = true;\r\n    texture._cachedAnisotropicFilteringLevel = null;\r\n    texture.generateMipMaps = true;\r\n    texture.width = size;\r\n    texture.height = size;\r\n    engine.updateTextureSamplingMode(Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, texture);\r\n\r\n    await _UploadLevelsAsync(texture, [imageData], false, imageType);\r\n\r\n    engine.generateMipMapsForCubemap(texture);\r\n\r\n    // Flag internal texture as ready in case they are in use.\r\n    texture.isReady = true;\r\n}\r\n\r\n/**\r\n * Uploads the levels of image data to the GPU.\r\n * @param texture defines the internal texture to upload to\r\n * @param imageData defines the array buffer views of image data [mipmap][face]\r\n * @param canGenerateNonLODTextures defines whether or not to generate non lod textures\r\n * @param imageType the mime type of the image data\r\n * @returns a promise\r\n */\r\nasync function _UploadLevelsAsync(\r\n    texture: InternalTexture,\r\n    imageData: ArrayBufferView[][],\r\n    canGenerateNonLODTextures: boolean,\r\n    imageType: string = DefaultEnvironmentTextureImageType\r\n) {\r\n    if (!IsExponentOfTwo(texture.width)) {\r\n        throw new Error(\"Texture size must be a power of two\");\r\n    }\r\n\r\n    const mipmapsCount = ILog2(texture.width) + 1;\r\n\r\n    // Gets everything ready.\r\n    const engine = texture.getEngine() as Engine;\r\n    let expandTexture = false;\r\n    let generateNonLODTextures = false;\r\n    let rgbdPostProcess: Nullable<PostProcess> = null;\r\n    let cubeRtt: Nullable<RenderTargetWrapper> = null;\r\n    let lodTextures: Nullable<{ [lod: number]: BaseTexture }> = null;\r\n    const caps = engine.getCaps();\r\n\r\n    if (!caps.textureLOD) {\r\n        expandTexture = false;\r\n        generateNonLODTextures = canGenerateNonLODTextures;\r\n    } else if (!engine._features.supportRenderAndCopyToLodForFloatTextures) {\r\n        expandTexture = false;\r\n    }\r\n    // If half float available we can uncompress the texture\r\n    else if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {\r\n        expandTexture = true;\r\n        texture.type = Constants.TEXTURETYPE_HALF_FLOAT;\r\n    }\r\n    // If full float available we can uncompress the texture\r\n    else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {\r\n        expandTexture = true;\r\n        texture.type = Constants.TEXTURETYPE_FLOAT;\r\n    }\r\n\r\n    // Expand the texture if possible\r\n    let shaderLanguage = ShaderLanguage.GLSL;\r\n    if (expandTexture) {\r\n        if (engine.isWebGPU) {\r\n            shaderLanguage = ShaderLanguage.WGSL;\r\n            await import(\"../ShadersWGSL/rgbdDecode.fragment\");\r\n        } else {\r\n            await import(\"../Shaders/rgbdDecode.fragment\");\r\n        }\r\n\r\n        // Simply run through the decode PP\r\n        rgbdPostProcess = new PostProcess(\r\n            \"rgbdDecode\",\r\n            \"rgbdDecode\",\r\n            null,\r\n            null,\r\n            1,\r\n            null,\r\n            Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            false,\r\n            undefined,\r\n            texture.type,\r\n            undefined,\r\n            null,\r\n            false,\r\n            undefined,\r\n            shaderLanguage\r\n        );\r\n\r\n        texture._isRGBD = false;\r\n        texture.invertY = false;\r\n        cubeRtt = engine.createRenderTargetCubeTexture(texture.width, {\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: true,\r\n            generateStencilBuffer: false,\r\n            samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n            type: texture.type,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n        });\r\n    } else {\r\n        texture._isRGBD = true;\r\n        texture.invertY = true;\r\n\r\n        // In case of missing support, applies the same patch than DDS files.\r\n        if (generateNonLODTextures) {\r\n            const mipSlices = 3;\r\n            lodTextures = {};\r\n            const scale = texture._lodGenerationScale;\r\n            const offset = texture._lodGenerationOffset;\r\n\r\n            for (let i = 0; i < mipSlices; i++) {\r\n                //compute LOD from even spacing in smoothness (matching shader calculation)\r\n                const smoothness = i / (mipSlices - 1);\r\n                const roughness = 1 - smoothness;\r\n\r\n                const minLODIndex = offset; // roughness = 0\r\n                const maxLODIndex = (mipmapsCount - 1) * scale + offset; // roughness = 1 (mipmaps start from 0)\r\n\r\n                const lodIndex = minLODIndex + (maxLODIndex - minLODIndex) * roughness;\r\n                const mipmapIndex = Math.round(Math.min(Math.max(lodIndex, 0), maxLODIndex));\r\n\r\n                //compute LOD from even spacing in smoothness (matching shader calculation)\r\n                const glTextureFromLod = new InternalTexture(engine, InternalTextureSource.Temp);\r\n                glTextureFromLod.isCube = true;\r\n                glTextureFromLod.invertY = true;\r\n                glTextureFromLod.generateMipMaps = false;\r\n                engine.updateTextureSamplingMode(Constants.TEXTURE_LINEAR_LINEAR, glTextureFromLod);\r\n\r\n                // Wrap in a base texture for easy binding.\r\n                const lodTexture = new BaseTexture(null);\r\n                lodTexture._isCube = true;\r\n                lodTexture._texture = glTextureFromLod;\r\n                lodTextures[mipmapIndex] = lodTexture;\r\n\r\n                switch (i) {\r\n                    case 0:\r\n                        texture._lodTextureLow = lodTexture;\r\n                        break;\r\n                    case 1:\r\n                        texture._lodTextureMid = lodTexture;\r\n                        break;\r\n                    case 2:\r\n                        texture._lodTextureHigh = lodTexture;\r\n                        break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    const promises: Promise<void>[] = [];\r\n    // All mipmaps up to provided number of images\r\n    for (let i = 0; i < imageData.length; i++) {\r\n        // All faces\r\n        for (let face = 0; face < 6; face++) {\r\n            // Constructs an image element from image data\r\n            const bytes = imageData[i][face];\r\n            const buffer = GetBlobBufferSource(bytes);\r\n            const blob = new Blob([buffer], { type: imageType });\r\n            const url = URL.createObjectURL(blob);\r\n            let promise: Promise<void>;\r\n\r\n            if (engine._features.forceBitmapOverHTMLImageElement) {\r\n                // eslint-disable-next-line github/no-then\r\n                promise = engine.createImageBitmap(blob, { premultiplyAlpha: \"none\", colorSpaceConversion: \"none\" }).then(async (img) => {\r\n                    return await _OnImageReadyAsync(img, engine, expandTexture, rgbdPostProcess, url, face, i, generateNonLODTextures, lodTextures, cubeRtt, texture);\r\n                });\r\n            } else {\r\n                const image = new Image();\r\n                image.src = url;\r\n\r\n                // Enqueue promise to upload to the texture.\r\n                promise = new Promise<void>((resolve, reject) => {\r\n                    image.onload = () => {\r\n                        _OnImageReadyAsync(image, engine, expandTexture, rgbdPostProcess, url, face, i, generateNonLODTextures, lodTextures, cubeRtt, texture)\r\n                            // eslint-disable-next-line github/no-then\r\n                            .then(() => resolve())\r\n                            // eslint-disable-next-line github/no-then\r\n                            .catch((reason) => {\r\n                                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                                reject(reason);\r\n                            });\r\n                    };\r\n                    image.onerror = (error) => {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(error);\r\n                    };\r\n                });\r\n            }\r\n            promises.push(promise);\r\n        }\r\n    }\r\n\r\n    await Promise.all(promises);\r\n\r\n    // Fill remaining mipmaps with black textures.\r\n    if (imageData.length < mipmapsCount) {\r\n        let data: ArrayBufferView;\r\n        const size = Math.pow(2, mipmapsCount - 1 - imageData.length);\r\n        const dataLength = size * size * 4;\r\n        switch (texture.type) {\r\n            case Constants.TEXTURETYPE_UNSIGNED_BYTE: {\r\n                data = new Uint8Array(dataLength);\r\n                break;\r\n            }\r\n            case Constants.TEXTURETYPE_HALF_FLOAT: {\r\n                data = new Uint16Array(dataLength);\r\n                break;\r\n            }\r\n            case Constants.TEXTURETYPE_FLOAT: {\r\n                data = new Float32Array(dataLength);\r\n                break;\r\n            }\r\n        }\r\n        for (let i = imageData.length; i < mipmapsCount; i++) {\r\n            for (let face = 0; face < 6; face++) {\r\n                engine._uploadArrayBufferViewToTexture(cubeRtt?.texture || texture, data!, face, i);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Release temp RTT.\r\n    if (cubeRtt) {\r\n        const irradiance = texture._irradianceTexture;\r\n        texture._irradianceTexture = null;\r\n        engine._releaseTexture(texture);\r\n        cubeRtt._swapAndDie(texture);\r\n        texture._irradianceTexture = irradiance;\r\n    }\r\n    // Release temp Post Process.\r\n    if (rgbdPostProcess) {\r\n        rgbdPostProcess.dispose();\r\n    }\r\n    // Flag internal texture as ready in case they are in use.\r\n    if (generateNonLODTextures) {\r\n        if (texture._lodTextureHigh && texture._lodTextureHigh._texture) {\r\n            texture._lodTextureHigh._texture.isReady = true;\r\n        }\r\n        if (texture._lodTextureMid && texture._lodTextureMid._texture) {\r\n            texture._lodTextureMid._texture.isReady = true;\r\n        }\r\n        if (texture._lodTextureLow && texture._lodTextureLow._texture) {\r\n            texture._lodTextureLow._texture.isReady = true;\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Uploads spherical polynomials information to the texture.\r\n * @param texture defines the texture we are trying to upload the information to\r\n * @param info defines the environment texture info retrieved through the GetEnvInfo method\r\n */\r\nexport function UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void {\r\n    info = normalizeEnvInfo(info);\r\n\r\n    const irradianceInfo = info.irradiance as EnvironmentTextureIrradianceInfoV1;\r\n    if (!irradianceInfo) {\r\n        return;\r\n    }\r\n\r\n    const sp = new SphericalPolynomial();\r\n    Vector3.FromArrayToRef(irradianceInfo.x, 0, sp.x);\r\n    Vector3.FromArrayToRef(irradianceInfo.y, 0, sp.y);\r\n    Vector3.FromArrayToRef(irradianceInfo.z, 0, sp.z);\r\n    Vector3.FromArrayToRef(irradianceInfo.xx, 0, sp.xx);\r\n    Vector3.FromArrayToRef(irradianceInfo.yy, 0, sp.yy);\r\n    Vector3.FromArrayToRef(irradianceInfo.zz, 0, sp.zz);\r\n    Vector3.FromArrayToRef(irradianceInfo.yz, 0, sp.yz);\r\n    Vector3.FromArrayToRef(irradianceInfo.zx, 0, sp.zx);\r\n    Vector3.FromArrayToRef(irradianceInfo.xy, 0, sp.xy);\r\n    texture._sphericalPolynomial = sp;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\nexport function _UpdateRGBDAsync(\r\n    internalTexture: InternalTexture,\r\n    data: ArrayBufferView[][],\r\n    sphericalPolynomial: Nullable<SphericalPolynomial>,\r\n    lodScale: number,\r\n    lodOffset: number\r\n): Promise<InternalTexture> {\r\n    const proxy = internalTexture\r\n        .getEngine()\r\n        .createRawCubeTexture(\r\n            null,\r\n            internalTexture.width,\r\n            internalTexture.format,\r\n            internalTexture.type,\r\n            internalTexture.generateMipMaps,\r\n            internalTexture.invertY,\r\n            internalTexture.samplingMode,\r\n            internalTexture._compression\r\n        );\r\n    // eslint-disable-next-line github/no-then\r\n    const proxyPromise = UploadRadianceLevelsAsync(proxy, data).then(() => internalTexture);\r\n    internalTexture.onRebuildCallback = (_internalTexture) => {\r\n        return {\r\n            proxy: proxyPromise,\r\n            isReady: true,\r\n            isAsync: true,\r\n        };\r\n    };\r\n    internalTexture._source = InternalTextureSource.CubeRawRGBD;\r\n    internalTexture._bufferViewArrayArray = data;\r\n    internalTexture._lodGenerationScale = lodScale;\r\n    internalTexture._lodGenerationOffset = lodOffset;\r\n    internalTexture._sphericalPolynomial = sphericalPolynomial;\r\n\r\n    // eslint-disable-next-line github/no-then\r\n    return UploadRadianceLevelsAsync(internalTexture, data).then(() => {\r\n        internalTexture.isReady = true;\r\n        return internalTexture;\r\n    });\r\n}\r\n\r\n/**\r\n * Sets of helpers addressing the serialization and deserialization of environment texture\r\n * stored in a BabylonJS env file.\r\n * Those files are usually stored as .env files.\r\n */\r\nexport const EnvironmentTextureTools = {\r\n    /**\r\n     * Gets the environment info from an env file.\r\n     * @param data The array buffer containing the .env bytes.\r\n     * @returns the environment file info (the json header) if successfully parsed, normalized to the latest supported version.\r\n     */\r\n    GetEnvInfo,\r\n\r\n    /**\r\n     * Creates an environment texture from a loaded cube texture.\r\n     * @param texture defines the cube texture to convert in env file\r\n     * @param options options for the conversion process\r\n     * @param options.imageType the mime type for the encoded images, with support for \"image/png\" (default) and \"image/webp\"\r\n     * @param options.imageQuality the image quality of encoded WebP images.\r\n     * @returns a promise containing the environment data if successful.\r\n     */\r\n    CreateEnvTextureAsync,\r\n\r\n    /**\r\n     * Creates the ArrayBufferViews used for initializing environment texture image data.\r\n     * @param data the image data\r\n     * @param info parameters that determine what views will be created for accessing the underlying buffer\r\n     * @returns the views described by info providing access to the underlying buffer\r\n     */\r\n    CreateRadianceImageDataArrayBufferViews,\r\n\r\n    /**\r\n     * Creates the ArrayBufferViews used for initializing environment texture image data.\r\n     * @param data the image data\r\n     * @param info parameters that determine what views will be created for accessing the underlying buffer\r\n     * @returns the views described by info providing access to the underlying buffer\r\n     */\r\n    CreateIrradianceImageDataArrayBufferViews,\r\n\r\n    /**\r\n     * Uploads the texture info contained in the env file to the GPU.\r\n     * @param texture defines the internal texture to upload to\r\n     * @param data defines the data to load\r\n     * @param info defines the texture info retrieved through the GetEnvInfo method\r\n     * @returns a promise\r\n     */\r\n    UploadEnvLevelsAsync,\r\n\r\n    /**\r\n     * Uploads the levels of image data to the GPU.\r\n     * @param texture defines the internal texture to upload to\r\n     * @param imageData defines the array buffer views of image data [mipmap][face]\r\n     * @param imageType the mime type of the image data\r\n     * @returns a promise\r\n     */\r\n    UploadRadianceLevelsAsync,\r\n\r\n    /**\r\n     * Uploads the levels of image data to the GPU.\r\n     * @param texture defines the internal texture to upload to\r\n     * @param imageData defines the array buffer views of image data [mipmap][face]\r\n     * @param imageType the mime type of the image data\r\n     * @param dominantDirection the dominant direction of light in the environment texture, if available\r\n     * @returns a promise\r\n     */\r\n    UploadIrradianceLevelsAsync,\r\n\r\n    /**\r\n     * Uploads spherical polynomials information to the texture.\r\n     * @param texture defines the texture we are trying to upload the information to\r\n     * @param info defines the environment texture info retrieved through the GetEnvInfo method\r\n     */\r\n    UploadEnvSpherical,\r\n};\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\r\nimport { CreateRadianceImageDataArrayBufferViews, GetEnvInfo, UploadEnvSpherical } from \"../../../Misc/environmentTextureTools.pure\";\r\nimport { type IWebRequest } from \"../../../Misc/interfaces/iWebRequest\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { SphericalPolynomial } from \"../../../Maths/sphericalPolynomial.pure\";\r\nimport { Constants } from \"../../constants\";\r\nimport { ThinNativeEngine } from \"../../thinNativeEngine.pure\";\r\n\r\nfunction ApplySphericalPolynomialFromNative(texture: InternalTexture, sphericalPolynomial: ArrayLike<number> | undefined): void {\r\n    if (!sphericalPolynomial || sphericalPolynomial.length < 27) {\r\n        return;\r\n    }\r\n\r\n    const sp = new SphericalPolynomial();\r\n    sp.x.copyFromFloats(sphericalPolynomial[0], sphericalPolynomial[1], sphericalPolynomial[2]);\r\n    sp.y.copyFromFloats(sphericalPolynomial[3], sphericalPolynomial[4], sphericalPolynomial[5]);\r\n    sp.z.copyFromFloats(sphericalPolynomial[6], sphericalPolynomial[7], sphericalPolynomial[8]);\r\n    sp.xx.copyFromFloats(sphericalPolynomial[9], sphericalPolynomial[10], sphericalPolynomial[11]);\r\n    sp.yy.copyFromFloats(sphericalPolynomial[12], sphericalPolynomial[13], sphericalPolynomial[14]);\r\n    sp.zz.copyFromFloats(sphericalPolynomial[15], sphericalPolynomial[16], sphericalPolynomial[17]);\r\n    sp.yz.copyFromFloats(sphericalPolynomial[18], sphericalPolynomial[19], sphericalPolynomial[20]);\r\n    sp.zx.copyFromFloats(sphericalPolynomial[21], sphericalPolynomial[22], sphericalPolynomial[23]);\r\n    sp.xy.copyFromFloats(sphericalPolynomial[24], sphericalPolynomial[25], sphericalPolynomial[26]);\r\n    texture._sphericalPolynomial = sp;\r\n}\r\n\r\nfunction SyncCubeTextureSizeFromNative(\r\n    nativeEngine: { getTextureWidth(texture: unknown): number; getTextureHeight(texture: unknown): number },\r\n    texture: InternalTexture,\r\n    fallbackSize?: number\r\n): void {\r\n    const hardware = texture._hardwareTexture?.underlyingResource;\r\n    if (hardware) {\r\n        const width = nativeEngine.getTextureWidth(hardware);\r\n        const height = nativeEngine.getTextureHeight(hardware);\r\n        if (width > 0 && height > 0) {\r\n            texture.width = width;\r\n            texture.height = height;\r\n            texture.baseWidth = width;\r\n            texture.baseHeight = height;\r\n            return;\r\n        }\r\n    }\r\n\r\n    if (fallbackSize && fallbackSize > 0) {\r\n        texture.width = fallbackSize;\r\n        texture.height = fallbackSize;\r\n        texture.baseWidth = fallbackSize;\r\n        texture.baseHeight = fallbackSize;\r\n    }\r\n}\r\n\r\nfunction NotifyCubeTextureLoaded(texture: InternalTexture, onLoad: Nullable<(data?: any) => void>, loadData?: any): void {\r\n    // Native cannot read cube faces for lazy irradiance generation. Preserve supplied\r\n    // coefficients, or publish an empty polynomial before observers (including clones) run.\r\n    texture._sphericalPolynomial ??= new SphericalPolynomial();\r\n    texture.isReady = true;\r\n    texture.onLoadedObservable.notifyObservers(texture);\r\n    texture.onLoadedObservable.clear();\r\n    if (onLoad) {\r\n        onLoad(loadData);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for nativeEngineCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNativeEngineCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinNativeEngine.prototype.createCubeTexture = function (\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        files: Nullable<string[]>,\r\n        noMipmap?: boolean,\r\n        onLoad: Nullable<(data?: any) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials = false,\r\n        lodScale: number = 0,\r\n        lodOffset: number = 0,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        loaderOptions?: any,\r\n        useSRGBBuffer = false,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        const texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);\r\n        texture.isCube = true;\r\n        texture.url = rootUrl;\r\n        texture.generateMipMaps = !noMipmap;\r\n        texture._lodGenerationScale = lodScale;\r\n        texture._lodGenerationOffset = lodOffset;\r\n        texture._useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, !!noMipmap);\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._extension = forcedExtension;\r\n            texture._files = files;\r\n            texture._buffer = buffer;\r\n        }\r\n\r\n        const lastDot = rootUrl.lastIndexOf(\".\");\r\n        const extension = forcedExtension ? forcedExtension : lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : \"\";\r\n\r\n        // TODO: use texture loader to load env files?\r\n        if (extension === \".env\") {\r\n            const onloaddata = (data: ArrayBufferView) => {\r\n                const info = GetEnvInfo(data)!;\r\n                texture.width = info.width;\r\n                texture.height = info.width;\r\n                texture.baseWidth = info.width;\r\n                texture.baseHeight = info.width;\r\n\r\n                UploadEnvSpherical(texture, info);\r\n\r\n                const specularInfo = info.specular;\r\n                if (!specularInfo) {\r\n                    throw new Error(`Nothing else parsed so far`);\r\n                }\r\n\r\n                texture._lodGenerationScale = specularInfo.lodGenerationScale;\r\n                const imageData = CreateRadianceImageDataArrayBufferViews(data, info);\r\n\r\n                texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n                texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                texture.generateMipMaps = true;\r\n                texture.getEngine().updateTextureSamplingMode(Texture.TRILINEAR_SAMPLINGMODE, texture);\r\n                texture._isRGBD = true;\r\n                texture.invertY = true;\r\n\r\n                this._engine.loadCubeTextureWithMips(\r\n                    texture._hardwareTexture!.underlyingResource,\r\n                    imageData,\r\n                    false,\r\n                    texture._useSRGBBuffer,\r\n                    () => {\r\n                        SyncCubeTextureSizeFromNative(this._engine, texture, info.width);\r\n                        NotifyCubeTextureLoaded(texture, onLoad);\r\n                    },\r\n                    () => {\r\n                        throw new Error(\"Could not load a native cube texture.\");\r\n                    }\r\n                );\r\n            };\r\n\r\n            if (buffer) {\r\n                onloaddata(buffer);\r\n            } else if (files && files.length === 6) {\r\n                throw new Error(`Multi-file loading not allowed on env files.`);\r\n            } else {\r\n                const onInternalError = (request?: IWebRequest, exception?: any) => {\r\n                    if (onError && request) {\r\n                        onError(request.status + \" \" + request.statusText, exception);\r\n                    }\r\n                };\r\n\r\n                this._loadFile(\r\n                    rootUrl,\r\n                    (data) => {\r\n                        onloaddata(new Uint8Array(data as ArrayBuffer, 0, (data as ArrayBuffer).byteLength));\r\n                    },\r\n                    undefined,\r\n                    undefined,\r\n                    true,\r\n                    onInternalError\r\n                );\r\n            }\r\n        } else if (files && files.length === 6) {\r\n            // Reorder from [+X, +Y, +Z, -X, -Y, -Z] to [+X, -X, +Y, -Y, +Z, -Z].\r\n            const reorderedFiles = [files[0], files[3], files[1], files[4], files[2], files[5]];\r\n            // eslint-disable-next-line github/no-then\r\n            Promise.all(reorderedFiles.map(async (file) => await this._loadFileAsync(file, undefined, true).then((data) => new Uint8Array(data, 0, data.byteLength))))\r\n                // eslint-disable-next-line github/no-then\r\n                .then(async (data) => {\r\n                    return await new Promise<void>((resolve, reject) => {\r\n                        this._engine.loadCubeTexture(\r\n                            texture._hardwareTexture!.underlyingResource,\r\n                            data,\r\n                            !noMipmap,\r\n                            true,\r\n                            texture._useSRGBBuffer,\r\n                            () => resolve(),\r\n                            () => reject(new Error(\"Native engine failed to load the cubemap faces\"))\r\n                        );\r\n                    });\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .then(\r\n                    () => {\r\n                        SyncCubeTextureSizeFromNative(this._engine, texture);\r\n                        NotifyCubeTextureLoaded(texture, onLoad);\r\n                    },\r\n                    (error) => {\r\n                        if (onError) {\r\n                            onError(`Failed to load cubemap: ${error?.message ?? String(error)}`, error);\r\n                        }\r\n                    }\r\n                );\r\n        } else if (extension.indexOf(\".dds\") === 0 && (buffer || !files || files.length <= 1)) {\r\n            // DDS containers hold all six faces and can provide diffuse SH coefficients.\r\n            // Prefer the supplied buffer to loading the single URL.\r\n            const singleUrl = files && files.length > 0 ? files[0] : rootUrl;\r\n            const sourceLabel = buffer ? rootUrl || singleUrl : singleUrl;\r\n\r\n            const loadContainerBufferAsync = async (data: ArrayBufferView) => {\r\n                const view = data instanceof Uint8Array ? data : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\r\n                await new Promise<void>((resolve, reject) => {\r\n                    this._engine.loadCubeTexture(\r\n                        texture._hardwareTexture!.underlyingResource,\r\n                        [view],\r\n                        !noMipmap,\r\n                        false,\r\n                        texture._useSRGBBuffer,\r\n                        (sphericalPolynomial?: ArrayLike<number>) => {\r\n                            if (createPolynomials) {\r\n                                ApplySphericalPolynomialFromNative(texture, sphericalPolynomial);\r\n                            }\r\n                            resolve();\r\n                        },\r\n                        () => reject(new Error(`Native engine failed to parse the cubemap container '${sourceLabel}'`))\r\n                    );\r\n                });\r\n            };\r\n\r\n            const loadPromise = buffer\r\n                ? loadContainerBufferAsync(buffer)\r\n                : // eslint-disable-next-line github/no-then\r\n                  this._loadFileAsync(singleUrl, undefined, true).then(async (data) => {\r\n                      await loadContainerBufferAsync(new Uint8Array(data, 0, data.byteLength));\r\n                  });\r\n\r\n            // eslint-disable-next-line github/no-then\r\n            loadPromise.then(\r\n                () => {\r\n                    SyncCubeTextureSizeFromNative(this._engine, texture);\r\n                    NotifyCubeTextureLoaded(texture, onLoad);\r\n                },\r\n                (error) => {\r\n                    if (onError) {\r\n                        onError(`Failed to load cubemap: ${error?.message ?? String(error)}`, error);\r\n                    }\r\n                }\r\n            );\r\n        } else {\r\n            throw new Error(\"Cannot load cubemap because 6 files were not defined\");\r\n        }\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n\r\n    // Native has no WebGL DDS loadData. Initialize prefiltered state before loading so observers\r\n    // cannot trigger unsupported cube-face readback when polynomial generation is disabled.\r\n    ThinNativeEngine.prototype.createPrefilteredCubeTexture = function (\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        lodScale: number,\r\n        lodOffset: number,\r\n        onLoad: Nullable<(internalTexture: Nullable<InternalTexture>) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials: boolean = true,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.CubePrefiltered);\r\n        if (!createPolynomials) {\r\n            texture._sphericalPolynomial = new SphericalPolynomial();\r\n        }\r\n\r\n        return this.createCubeTexture(\r\n            rootUrl,\r\n            scene,\r\n            null,\r\n            false,\r\n            () => {\r\n                if (onLoad) {\r\n                    onLoad(texture);\r\n                }\r\n            },\r\n            onError,\r\n            format,\r\n            forcedExtension,\r\n            createPolynomials,\r\n            lodScale,\r\n            lodOffset,\r\n            texture,\r\n            undefined,\r\n            false,\r\n            buffer\r\n        );\r\n    };\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { ILog2 } from \"../../Maths/math.scalar.functions\";\r\nimport { Constants } from \"../constants\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type IHardwareTextureWrapper } from \"../../Materials/Textures/hardwareTextureWrapper\";\r\n\r\n/** @internal */\r\nexport class WebGPUTextureHelper {\r\n    public static ComputeNumMipmapLevels(width: number, height: number) {\r\n        return ILog2(Math.max(width, height)) + 1;\r\n    }\r\n\r\n    public static GetTextureTypeFromFormat(format: GPUTextureFormat): number {\r\n        switch (format) {\r\n            // One Component = 8 bits unsigned\r\n            case WebGPUConstants.TextureFormat.R8Unorm:\r\n            case WebGPUConstants.TextureFormat.R8Uint:\r\n            case WebGPUConstants.TextureFormat.RG8Unorm:\r\n            case WebGPUConstants.TextureFormat.RG8Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGBA8Uint:\r\n            case WebGPUConstants.TextureFormat.BGRA8Unorm:\r\n            case WebGPUConstants.TextureFormat.BGRA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGB10A2UINT: // composite format - let's say it's byte...\r\n            case WebGPUConstants.TextureFormat.RGB10A2Unorm: // composite format - let's say it's byte...\r\n            case WebGPUConstants.TextureFormat.RGB9E5UFloat: // composite format - let's say it's byte...\r\n            case WebGPUConstants.TextureFormat.RG11B10UFloat: // composite format - let's say it's byte...\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBUFloat:\r\n            case WebGPUConstants.TextureFormat.BC5RGUnorm:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC4RUnorm:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.EACR11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACRG11Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.Stencil8:\r\n                return Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n            // One Component = 8 bits signed\r\n            case WebGPUConstants.TextureFormat.R8Snorm:\r\n            case WebGPUConstants.TextureFormat.R8Sint:\r\n            case WebGPUConstants.TextureFormat.RG8Snorm:\r\n            case WebGPUConstants.TextureFormat.RG8Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA8Snorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8Sint:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBFloat:\r\n            case WebGPUConstants.TextureFormat.BC5RGSnorm:\r\n            case WebGPUConstants.TextureFormat.BC4RSnorm:\r\n            case WebGPUConstants.TextureFormat.EACR11Snorm:\r\n            case WebGPUConstants.TextureFormat.EACRG11Snorm:\r\n                return Constants.TEXTURETYPE_BYTE;\r\n\r\n            // One component = 16 bits unsigned\r\n            case WebGPUConstants.TextureFormat.R16Uint:\r\n            case WebGPUConstants.TextureFormat.R16Unorm:\r\n            case WebGPUConstants.TextureFormat.RG16Unorm:\r\n            case WebGPUConstants.TextureFormat.RGBA16Unorm:\r\n            case WebGPUConstants.TextureFormat.RG16Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA16Uint:\r\n            case WebGPUConstants.TextureFormat.Depth16Unorm:\r\n                return Constants.TEXTURETYPE_UNSIGNED_SHORT;\r\n\r\n            // One component = 16 bits signed\r\n            case WebGPUConstants.TextureFormat.R16Sint:\r\n            case WebGPUConstants.TextureFormat.R16Snorm:\r\n            case WebGPUConstants.TextureFormat.RG16Snorm:\r\n            case WebGPUConstants.TextureFormat.RGBA16Snorm:\r\n            case WebGPUConstants.TextureFormat.RG16Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA16Sint:\r\n                return Constants.TEXTURETYPE_SHORT;\r\n\r\n            case WebGPUConstants.TextureFormat.R16Float:\r\n            case WebGPUConstants.TextureFormat.RG16Float:\r\n            case WebGPUConstants.TextureFormat.RGBA16Float:\r\n                return Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n            // One component = 32 bits unsigned\r\n            case WebGPUConstants.TextureFormat.R32Uint:\r\n            case WebGPUConstants.TextureFormat.RG32Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA32Uint:\r\n                return Constants.TEXTURETYPE_UNSIGNED_INTEGER;\r\n\r\n            // One component = 32 bits signed\r\n            case WebGPUConstants.TextureFormat.R32Sint:\r\n            case WebGPUConstants.TextureFormat.RG32Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA32Sint:\r\n                return Constants.TEXTURETYPE_UNSIGNED_INTEGER;\r\n\r\n            case WebGPUConstants.TextureFormat.R32Float:\r\n            case WebGPUConstants.TextureFormat.RG32Float:\r\n            case WebGPUConstants.TextureFormat.RGBA32Float:\r\n            case WebGPUConstants.TextureFormat.Depth32Float:\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n            case WebGPUConstants.TextureFormat.Depth24Plus:\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n                return Constants.TEXTURETYPE_FLOAT;\r\n        }\r\n\r\n        return Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n    }\r\n\r\n    public static GetBlockInformationFromFormat(format: GPUTextureFormat): { width: number; height: number; length: number } {\r\n        switch (format) {\r\n            // 8 bits formats\r\n            case WebGPUConstants.TextureFormat.R8Unorm:\r\n            case WebGPUConstants.TextureFormat.R8Snorm:\r\n            case WebGPUConstants.TextureFormat.R8Uint:\r\n            case WebGPUConstants.TextureFormat.R8Sint:\r\n                return { width: 1, height: 1, length: 1 };\r\n\r\n            // 16 bits formats\r\n            case WebGPUConstants.TextureFormat.R16Uint:\r\n            case WebGPUConstants.TextureFormat.R16Sint:\r\n            case WebGPUConstants.TextureFormat.R16Unorm:\r\n            case WebGPUConstants.TextureFormat.R16Snorm:\r\n            case WebGPUConstants.TextureFormat.R16Float:\r\n            case WebGPUConstants.TextureFormat.RG8Unorm:\r\n            case WebGPUConstants.TextureFormat.RG8Snorm:\r\n            case WebGPUConstants.TextureFormat.RG8Uint:\r\n            case WebGPUConstants.TextureFormat.RG8Sint:\r\n                return { width: 1, height: 1, length: 2 };\r\n\r\n            // 32 bits formats\r\n            case WebGPUConstants.TextureFormat.R32Uint:\r\n            case WebGPUConstants.TextureFormat.R32Sint:\r\n            case WebGPUConstants.TextureFormat.R32Float:\r\n            case WebGPUConstants.TextureFormat.RG16Uint:\r\n            case WebGPUConstants.TextureFormat.RG16Sint:\r\n            case WebGPUConstants.TextureFormat.RG16Float:\r\n            case WebGPUConstants.TextureFormat.RG16Unorm:\r\n            case WebGPUConstants.TextureFormat.RG16Snorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGBA8Snorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA8Sint:\r\n            case WebGPUConstants.TextureFormat.BGRA8Unorm:\r\n            case WebGPUConstants.TextureFormat.BGRA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGB9E5UFloat:\r\n            case WebGPUConstants.TextureFormat.RGB10A2UINT:\r\n            case WebGPUConstants.TextureFormat.RGB10A2Unorm:\r\n            case WebGPUConstants.TextureFormat.RG11B10UFloat:\r\n                return { width: 1, height: 1, length: 4 };\r\n\r\n            // 64 bits formats\r\n            case WebGPUConstants.TextureFormat.RG32Uint:\r\n            case WebGPUConstants.TextureFormat.RG32Sint:\r\n            case WebGPUConstants.TextureFormat.RG32Float:\r\n            case WebGPUConstants.TextureFormat.RGBA16Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA16Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA16Float:\r\n            case WebGPUConstants.TextureFormat.RGBA16Unorm:\r\n            case WebGPUConstants.TextureFormat.RGBA16Snorm:\r\n                return { width: 1, height: 1, length: 8 };\r\n\r\n            // 128 bits formats\r\n            case WebGPUConstants.TextureFormat.RGBA32Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA32Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA32Float:\r\n                return { width: 1, height: 1, length: 16 };\r\n\r\n            // Depth and stencil formats\r\n            case WebGPUConstants.TextureFormat.Stencil8:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"No fixed size for Stencil8 format!\";\r\n            case WebGPUConstants.TextureFormat.Depth16Unorm:\r\n                return { width: 1, height: 1, length: 2 };\r\n            case WebGPUConstants.TextureFormat.Depth24Plus:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"No fixed size for Depth24Plus format!\";\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"No fixed size for Depth24PlusStencil8 format!\";\r\n            case WebGPUConstants.TextureFormat.Depth32Float:\r\n                return { width: 1, height: 1, length: 4 };\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n                return { width: 1, height: 1, length: 5 };\r\n\r\n            // BC compressed formats usable if \"texture-compression-bc\" is both\r\n            // supported by the device/user agent and enabled in requestDevice.\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBUFloat:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBFloat:\r\n            case WebGPUConstants.TextureFormat.BC5RGUnorm:\r\n            case WebGPUConstants.TextureFormat.BC5RGSnorm:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnormSRGB:\r\n                return { width: 4, height: 4, length: 16 };\r\n\r\n            case WebGPUConstants.TextureFormat.BC4RUnorm:\r\n            case WebGPUConstants.TextureFormat.BC4RSnorm:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnormSRGB:\r\n                return { width: 4, height: 4, length: 8 };\r\n\r\n            // ETC2 compressed formats usable if \"texture-compression-etc2\" is both\r\n            // supported by the device/user agent and enabled in requestDevice.\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.EACR11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACR11Snorm:\r\n                return { width: 4, height: 4, length: 8 };\r\n\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.EACRG11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACRG11Snorm:\r\n                return { width: 4, height: 4, length: 16 };\r\n\r\n            // ASTC compressed formats usable if \"texture-compression-astc\" is both\r\n            // supported by the device/user agent and enabled in requestDevice.\r\n            case WebGPUConstants.TextureFormat.ASTC4x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4UnormSRGB:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC5x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4UnormSRGB:\r\n                return { width: 5, height: 4, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC5x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5UnormSRGB:\r\n                return { width: 5, height: 5, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC6x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5UnormSRGB:\r\n                return { width: 6, height: 5, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC6x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6UnormSRGB:\r\n                return { width: 6, height: 6, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC8x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5UnormSRGB:\r\n                return { width: 8, height: 5, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC8x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6UnormSRGB:\r\n                return { width: 8, height: 6, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC8x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8UnormSRGB:\r\n                return { width: 8, height: 8, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC10x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5UnormSRGB:\r\n                return { width: 10, height: 5, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC10x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6UnormSRGB:\r\n                return { width: 10, height: 6, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC10x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8UnormSRGB:\r\n                return { width: 10, height: 8, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC10x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10UnormSRGB:\r\n                return { width: 10, height: 10, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC12x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10UnormSRGB:\r\n                return { width: 12, height: 10, length: 16 };\r\n            case WebGPUConstants.TextureFormat.ASTC12x12Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12UnormSRGB:\r\n                return { width: 12, height: 12, length: 16 };\r\n        }\r\n\r\n        return { width: 1, height: 1, length: 4 };\r\n    }\r\n\r\n    public static IsHardwareTexture(texture: IHardwareTextureWrapper | GPUTexture): texture is IHardwareTextureWrapper {\r\n        return !!(texture as IHardwareTextureWrapper).release;\r\n    }\r\n\r\n    public static IsInternalTexture(texture: InternalTexture | GPUTexture): texture is InternalTexture {\r\n        return !!(texture as InternalTexture).dispose;\r\n    }\r\n\r\n    public static IsImageBitmap(imageBitmap: ImageBitmap | { width: number; height: number }): imageBitmap is ImageBitmap {\r\n        return (imageBitmap as ImageBitmap).close !== undefined;\r\n    }\r\n\r\n    public static IsImageBitmapArray(imageBitmap: ImageBitmap[] | { width: number; height: number }): imageBitmap is ImageBitmap[] {\r\n        return Array.isArray(imageBitmap as ImageBitmap[]) && (imageBitmap as ImageBitmap[])[0].close !== undefined;\r\n    }\r\n\r\n    public static IsCompressedFormat(format: GPUTextureFormat): boolean {\r\n        switch (format) {\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBFloat:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBUFloat:\r\n            case WebGPUConstants.TextureFormat.BC5RGSnorm:\r\n            case WebGPUConstants.TextureFormat.BC5RGUnorm:\r\n            case WebGPUConstants.TextureFormat.BC4RSnorm:\r\n            case WebGPUConstants.TextureFormat.BC4RUnorm:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.EACR11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACR11Snorm:\r\n            case WebGPUConstants.TextureFormat.EACRG11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACRG11Snorm:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12UnormSRGB:\r\n                return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public static GetWebGPUTextureFormat(type: number, format: number, useSRGBBuffer = false): GPUTextureFormat {\r\n        switch (format) {\r\n            case Constants.TEXTUREFORMAT_DEPTH16:\r\n                return WebGPUConstants.TextureFormat.Depth16Unorm;\r\n            case Constants.TEXTUREFORMAT_DEPTH24:\r\n                return WebGPUConstants.TextureFormat.Depth24Plus;\r\n            case Constants.TEXTUREFORMAT_DEPTH24_STENCIL8:\r\n                return WebGPUConstants.TextureFormat.Depth24PlusStencil8;\r\n            case Constants.TEXTUREFORMAT_DEPTH32_FLOAT:\r\n                return WebGPUConstants.TextureFormat.Depth32Float;\r\n            case Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8:\r\n                return WebGPUConstants.TextureFormat.Depth32FloatStencil8;\r\n            case Constants.TEXTUREFORMAT_STENCIL8:\r\n                return WebGPUConstants.TextureFormat.Stencil8;\r\n\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.BC7RGBAUnormSRGB : WebGPUConstants.TextureFormat.BC7RGBAUnorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:\r\n                return WebGPUConstants.TextureFormat.BC6HRGBUFloat;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:\r\n                return WebGPUConstants.TextureFormat.BC6HRGBFloat;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.BC3RGBAUnormSRGB : WebGPUConstants.TextureFormat.BC3RGBAUnorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.BC2RGBAUnormSRGB : WebGPUConstants.TextureFormat.BC2RGBAUnorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.BC1RGBAUnormSRGB : WebGPUConstants.TextureFormat.BC1RGBAUnorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC4x4UnormSRGB : WebGPUConstants.TextureFormat.ASTC4x4Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC5x4UnormSRGB : WebGPUConstants.TextureFormat.ASTC5x4Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC5x5UnormSRGB : WebGPUConstants.TextureFormat.ASTC5x5Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC6x5UnormSRGB : WebGPUConstants.TextureFormat.ASTC6x5Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC6x6UnormSRGB : WebGPUConstants.TextureFormat.ASTC6x6Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC8x5UnormSRGB : WebGPUConstants.TextureFormat.ASTC8x5Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC8x6UnormSRGB : WebGPUConstants.TextureFormat.ASTC8x6Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC8x8UnormSRGB : WebGPUConstants.TextureFormat.ASTC8x8Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC10x5UnormSRGB : WebGPUConstants.TextureFormat.ASTC10x5Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC10x6UnormSRGB : WebGPUConstants.TextureFormat.ASTC10x6Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC10x8UnormSRGB : WebGPUConstants.TextureFormat.ASTC10x8Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC10x10UnormSRGB : WebGPUConstants.TextureFormat.ASTC10x10Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC12x10UnormSRGB : WebGPUConstants.TextureFormat.ASTC12x10Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ASTC12x12UnormSRGB : WebGPUConstants.TextureFormat.ASTC12x12Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ETC2RGB8UnormSRGB : WebGPUConstants.TextureFormat.ETC2RGB8Unorm;\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n                return useSRGBBuffer ? WebGPUConstants.TextureFormat.ETC2RGBA8UnormSRGB : WebGPUConstants.TextureFormat.ETC2RGBA8Unorm;\r\n        }\r\n\r\n        switch (type) {\r\n            case Constants.TEXTURETYPE_BYTE:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return WebGPUConstants.TextureFormat.R8Snorm;\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return WebGPUConstants.TextureFormat.RG8Snorm;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"RGB format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.R8Sint;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RG8Sint;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"RGB_INTEGER format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGBA8Sint;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA8Snorm;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return WebGPUConstants.TextureFormat.R8Unorm;\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return WebGPUConstants.TextureFormat.RG8Unorm;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return useSRGBBuffer ? WebGPUConstants.TextureFormat.RGBA8UnormSRGB : WebGPUConstants.TextureFormat.RGBA8Unorm;\r\n                    case Constants.TEXTUREFORMAT_BGRA:\r\n                        return useSRGBBuffer ? WebGPUConstants.TextureFormat.BGRA8UnormSRGB : WebGPUConstants.TextureFormat.BGRA8Unorm;\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.R8Uint;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RG8Uint;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"RGB_INTEGER format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGBA8Uint;\r\n                    case Constants.TEXTUREFORMAT_ALPHA:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_ALPHA format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_LUMINANCE format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE_ALPHA:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_LUMINANCE_ALPHA format not supported in WebGPU\";\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA8Unorm;\r\n                }\r\n            case Constants.TEXTURETYPE_SHORT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.R16Sint;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RG16Sint;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB_INTEGER format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGBA16Sint;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA16Sint;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.R16Uint;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RG16Uint;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB_INTEGER format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGBA16Uint;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA16Uint;\r\n                }\r\n            case Constants.TEXTURETYPE_INT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.R32Sint;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RG32Sint;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB_INTEGER format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGBA32Sint;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA32Sint;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_INTEGER: // Refers to UNSIGNED_INT\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.R32Uint;\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RG32Uint;\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB_INTEGER format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGBA32Uint;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA32Uint;\r\n                }\r\n            case Constants.TEXTURETYPE_FLOAT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return WebGPUConstants.TextureFormat.R32Float; // By default. Other possibility is R16Float.\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return WebGPUConstants.TextureFormat.RG32Float; // By default. Other possibility is RG16Float.\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return WebGPUConstants.TextureFormat.RGBA32Float; // By default. Other possibility is RGBA16Float.\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA32Float;\r\n                }\r\n            case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return WebGPUConstants.TextureFormat.R16Float;\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return WebGPUConstants.TextureFormat.RG16Float;\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGB format not supported in WebGPU\";\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return WebGPUConstants.TextureFormat.RGBA16Float;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGBA16Float;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"TEXTURETYPE_UNSIGNED_SHORT_5_6_5 format not supported in WebGPU\";\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return WebGPUConstants.TextureFormat.RG11B10UFloat;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGBA_INTEGER format not supported in WebGPU when type is TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV\";\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RG11B10UFloat;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return WebGPUConstants.TextureFormat.RGB9E5UFloat;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"TEXTUREFORMAT_RGBA_INTEGER format not supported in WebGPU when type is TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV\";\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGB9E5UFloat;\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 format not supported in WebGPU\";\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 format not supported in WebGPU\";\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return WebGPUConstants.TextureFormat.RGB10A2Unorm;\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return WebGPUConstants.TextureFormat.RGB10A2UINT;\r\n                    default:\r\n                        return WebGPUConstants.TextureFormat.RGB10A2Unorm;\r\n                }\r\n        }\r\n\r\n        return useSRGBBuffer ? WebGPUConstants.TextureFormat.RGBA8UnormSRGB : WebGPUConstants.TextureFormat.RGBA8Unorm;\r\n    }\r\n\r\n    public static GetNumChannelsFromWebGPUTextureFormat(format: GPUTextureFormat): number {\r\n        switch (format) {\r\n            case WebGPUConstants.TextureFormat.R8Unorm:\r\n            case WebGPUConstants.TextureFormat.R8Snorm:\r\n            case WebGPUConstants.TextureFormat.R8Uint:\r\n            case WebGPUConstants.TextureFormat.R8Sint:\r\n            case WebGPUConstants.TextureFormat.BC4RUnorm:\r\n            case WebGPUConstants.TextureFormat.BC4RSnorm:\r\n            case WebGPUConstants.TextureFormat.R16Uint:\r\n            case WebGPUConstants.TextureFormat.R16Sint:\r\n            case WebGPUConstants.TextureFormat.Depth16Unorm:\r\n            case WebGPUConstants.TextureFormat.R16Float:\r\n            case WebGPUConstants.TextureFormat.R16Unorm:\r\n            case WebGPUConstants.TextureFormat.R16Snorm:\r\n            case WebGPUConstants.TextureFormat.R32Uint:\r\n            case WebGPUConstants.TextureFormat.R32Sint:\r\n            case WebGPUConstants.TextureFormat.R32Float:\r\n            case WebGPUConstants.TextureFormat.Depth32Float:\r\n            case WebGPUConstants.TextureFormat.Stencil8:\r\n            case WebGPUConstants.TextureFormat.Depth24Plus:\r\n            case WebGPUConstants.TextureFormat.EACR11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACR11Snorm:\r\n                return 1;\r\n\r\n            case WebGPUConstants.TextureFormat.RG8Unorm:\r\n            case WebGPUConstants.TextureFormat.RG8Snorm:\r\n            case WebGPUConstants.TextureFormat.RG8Uint:\r\n            case WebGPUConstants.TextureFormat.RG8Sint:\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n            case WebGPUConstants.TextureFormat.BC5RGUnorm:\r\n            case WebGPUConstants.TextureFormat.BC5RGSnorm:\r\n            case WebGPUConstants.TextureFormat.RG16Uint:\r\n            case WebGPUConstants.TextureFormat.RG16Sint:\r\n            case WebGPUConstants.TextureFormat.RG16Float:\r\n            case WebGPUConstants.TextureFormat.RG16Unorm:\r\n            case WebGPUConstants.TextureFormat.RG16Snorm:\r\n            case WebGPUConstants.TextureFormat.RG32Uint:\r\n            case WebGPUConstants.TextureFormat.RG32Sint:\r\n            case WebGPUConstants.TextureFormat.RG32Float:\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n            case WebGPUConstants.TextureFormat.EACRG11Unorm:\r\n            case WebGPUConstants.TextureFormat.EACRG11Snorm:\r\n                return 2;\r\n\r\n            case WebGPUConstants.TextureFormat.RGB9E5UFloat:\r\n            case WebGPUConstants.TextureFormat.RG11B10UFloat:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBUFloat:\r\n            case WebGPUConstants.TextureFormat.BC6HRGBFloat:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8UnormSRGB:\r\n                return 3;\r\n\r\n            case WebGPUConstants.TextureFormat.RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGBA8Snorm:\r\n            case WebGPUConstants.TextureFormat.RGBA8Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA8Sint:\r\n            case WebGPUConstants.TextureFormat.BGRA8Unorm:\r\n            case WebGPUConstants.TextureFormat.BGRA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGBA16Unorm:\r\n            case WebGPUConstants.TextureFormat.RGBA16Snorm:\r\n            case WebGPUConstants.TextureFormat.RGB10A2UINT:\r\n            case WebGPUConstants.TextureFormat.RGB10A2Unorm:\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC7RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC3RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC2RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnorm:\r\n            case WebGPUConstants.TextureFormat.BC1RGBAUnormSRGB:\r\n            case WebGPUConstants.TextureFormat.RGBA16Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA16Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA16Float:\r\n            case WebGPUConstants.TextureFormat.RGBA32Uint:\r\n            case WebGPUConstants.TextureFormat.RGBA32Sint:\r\n            case WebGPUConstants.TextureFormat.RGBA32Float:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGB8A1UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8Unorm:\r\n            case WebGPUConstants.TextureFormat.ETC2RGBA8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC4x4UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x4UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC5x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC6x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC8x8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x5UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x6UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x8UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC10x10UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x10UnormSRGB:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12Unorm:\r\n            case WebGPUConstants.TextureFormat.ASTC12x12UnormSRGB:\r\n                return 4;\r\n        }\r\n\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw `Unknown format ${format}!`;\r\n    }\r\n\r\n    public static HasStencilAspect(format: GPUTextureFormat): boolean {\r\n        switch (format) {\r\n            case WebGPUConstants.TextureFormat.Stencil8:\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n                return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public static HasDepthAspect(format: GPUTextureFormat): boolean {\r\n        switch (format) {\r\n            case WebGPUConstants.TextureFormat.Depth16Unorm:\r\n            case WebGPUConstants.TextureFormat.Depth24Plus:\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n            case WebGPUConstants.TextureFormat.Depth32Float:\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n                return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public static HasDepthAndStencilAspects(format: GPUTextureFormat): boolean {\r\n        switch (format) {\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n                return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public static GetDepthFormatOnly(format: GPUTextureFormat): GPUTextureFormat {\r\n        switch (format) {\r\n            case WebGPUConstants.TextureFormat.Depth16Unorm:\r\n                return WebGPUConstants.TextureFormat.Depth16Unorm;\r\n            case WebGPUConstants.TextureFormat.Depth24Plus:\r\n                return WebGPUConstants.TextureFormat.Depth24Plus;\r\n            case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n                return WebGPUConstants.TextureFormat.Depth24Plus;\r\n            case WebGPUConstants.TextureFormat.Depth32Float:\r\n                return WebGPUConstants.TextureFormat.Depth32Float;\r\n            case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n                return WebGPUConstants.TextureFormat.Depth32Float;\r\n        }\r\n\r\n        return format;\r\n    }\r\n\r\n    public static GetSample(sampleCount: number) {\r\n        // WebGPU only supports 1 or 4\r\n        return sampleCount > 1 ? 4 : 1;\r\n    }\r\n}\r\n","import { type InternalTexture, InternalTextureSource } from \"core/Materials/Textures/internalTexture\";\r\nimport { AbstractEngine } from \"./abstractEngine\";\r\nimport { type WebGPUCacheRenderPipeline } from \"./WebGPU/webgpuCacheRenderPipeline\";\r\nimport { type WebGPUTextureManager } from \"./WebGPU/webgpuTextureManager\";\r\nimport { type WebGPUHardwareTexture } from \"./WebGPU/webgpuHardwareTexture\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { WebGPUTextureHelper } from \"./WebGPU/webgpuTextureHelper\";\r\nimport { type WebGPURenderTargetWrapper } from \"./WebGPU/webgpuRenderTargetWrapper\";\r\nimport { WebGPUPerfCounter } from \"./WebGPU/webgpuPerfCounter\";\r\nimport { type WebGPUSnapshotRendering } from \"./WebGPU/webgpuSnapshotRendering\";\r\nimport { Constants } from \"./constants\";\r\nimport { type WebGPUBundleList } from \"./WebGPU/webgpuBundleList\";\r\nimport { type WebGPUTimestampQuery } from \"./WebGPU/webgpuTimestampQuery\";\r\nimport { type WebGPUOcclusionQuery } from \"./WebGPU/webgpuOcclusionQuery\";\r\n\r\n/**\r\n * The base engine class for WebGPU\r\n */\r\nexport abstract class ThinWebGPUEngine extends AbstractEngine {\r\n    // TODO WEBGPU remove those variables when code stabilized\r\n    /** @internal */\r\n    public dbgShowShaderCode = false;\r\n    /** @internal */\r\n    public dbgSanityChecks = true;\r\n    /** @internal */\r\n    public dbgLogIfNotDrawWrapper = true;\r\n    /** @internal */\r\n    public dbgShowEmptyEnableEffectCalls = true;\r\n\r\n    /** @internal */\r\n    public _textureHelper: WebGPUTextureManager;\r\n    /** @internal */\r\n    public _cacheRenderPipeline: WebGPUCacheRenderPipeline;\r\n    /** @internal */\r\n    public _occlusionQuery: WebGPUOcclusionQuery;\r\n    /** @internal */\r\n    public _occlusionQueryActive = false;\r\n\r\n    // Frame Life Cycle (recreated each frame)\r\n    /** @internal */\r\n    public _renderEncoder: GPUCommandEncoder;\r\n    /** @internal */\r\n    public _uploadEncoder: GPUCommandEncoder;\r\n\r\n    /** @internal */\r\n    public _currentRenderPass: Nullable<GPURenderPassEncoder> = null;\r\n\r\n    /** @internal */\r\n    public _getCurrentRenderPass(): Nullable<GPURenderPassEncoder> {\r\n        return this._currentRenderPass;\r\n    }\r\n\r\n    protected _snapshotRendering: WebGPUSnapshotRendering;\r\n    protected _snapshotRenderingMode = Constants.SNAPSHOTRENDERING_STANDARD;\r\n\r\n    /** @internal */\r\n    public _timestampQuery: WebGPUTimestampQuery;\r\n    /** @internal */\r\n    public _timestampIndex = 0;\r\n\r\n    /** @internal */\r\n    public _showGPUDebugMarkersLog = false;\r\n    /** @internal */\r\n    public _debugMarkersEncoderGroups: string[] = [];\r\n    /** @internal */\r\n    public _debugMarkersPassGroups: string[] = [];\r\n    /** @internal */\r\n    public _debugMarkersPendingEncoderPops = 0;\r\n\r\n    /**\r\n     * Gets the GPU time spent in the main render pass for the last frame rendered (in nanoseconds).\r\n     * You have to enable the \"timestamp-query\" extension in the engine constructor options and set engine.enableGPUTimingMeasurements = true.\r\n     * It will only return time spent in the main pass, not additional render target / compute passes (if any)!\r\n     */\r\n    public readonly gpuTimeInFrameForMainPass?: WebGPUPerfCounter;\r\n\r\n    /**\r\n     * Used for both the compatibilityMode=false and the snapshot rendering modes (as both can't be enabled at the same time)\r\n     * @internal\r\n     */\r\n    public _bundleList: WebGPUBundleList;\r\n\r\n    /**\r\n     * Enables or disables GPU timing measurements.\r\n     * Note that this is only supported if the \"timestamp-query\" extension is enabled in the options.\r\n     */\r\n    public get enableGPUTimingMeasurements(): boolean {\r\n        return this._timestampQuery.enable;\r\n    }\r\n\r\n    public set enableGPUTimingMeasurements(enable: boolean) {\r\n        if (this._timestampQuery.enable === enable) {\r\n            return;\r\n        }\r\n        (this.gpuTimeInFrameForMainPass as any) = enable ? new WebGPUPerfCounter() : undefined;\r\n        this._timestampQuery.enable = enable;\r\n    }\r\n\r\n    protected _currentPassIsMainPass() {\r\n        return this._currentRenderTarget === null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _endCurrentRenderPass(): number {\r\n        if (!this._currentRenderPass) {\r\n            return 0;\r\n        }\r\n\r\n        this._debugPopBeforeEndOfEncoder();\r\n\r\n        const currentPassIndex = this._currentPassIsMainPass() ? 2 : 1;\r\n\r\n        if (!this._snapshotRendering.endRenderPass(this._currentRenderPass) && !this.compatibilityMode) {\r\n            this._bundleList.run(this._currentRenderPass);\r\n            this._bundleList.reset();\r\n        }\r\n        this._currentRenderPass.end();\r\n\r\n        this._timestampQuery.endPass(\r\n            this._timestampIndex,\r\n            (this._currentRenderTarget && (this._currentRenderTarget as WebGPURenderTargetWrapper).gpuTimeInFrame\r\n                ? (this._currentRenderTarget as WebGPURenderTargetWrapper).gpuTimeInFrame\r\n                : this.gpuTimeInFrameForMainPass) as WebGPUPerfCounter\r\n        );\r\n        this._timestampIndex += 2;\r\n\r\n        this._debugPendingPop(this._currentRenderPass);\r\n\r\n        this._currentRenderPass = null;\r\n\r\n        return currentPassIndex;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _generateMipmaps(texture: InternalTexture, commandEncoder?: GPUCommandEncoder) {\r\n        commandEncoder = commandEncoder ?? this._renderEncoder;\r\n\r\n        const gpuHardwareTexture = texture._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n\r\n        if (!gpuHardwareTexture) {\r\n            return;\r\n        }\r\n\r\n        if (commandEncoder === this._renderEncoder) {\r\n            // We must close the current pass (if any) because we are going to use the render encoder to generate the mipmaps (so, we are going to create a new render pass)\r\n            this._endCurrentRenderPass();\r\n        }\r\n\r\n        const mipmapCount = WebGPUTextureHelper.ComputeNumMipmapLevels(texture.width, texture.height);\r\n\r\n        if (texture.isCube) {\r\n            this._textureHelper.generateCubeMipmaps(gpuHardwareTexture, mipmapCount, commandEncoder);\r\n        } else if (texture._source === InternalTextureSource.Raw || texture._source === InternalTextureSource.Raw2DArray) {\r\n            this._textureHelper.generateMipmaps(gpuHardwareTexture, texture.mipLevelCount, 0, commandEncoder);\r\n        } else {\r\n            this._textureHelper.generateMipmaps(gpuHardwareTexture, mipmapCount, 0, commandEncoder);\r\n        }\r\n    }\r\n\r\n    protected _debugPopBeforeEndOfEncoder() {\r\n        if (!this._enableGPUDebugMarkers) {\r\n            return;\r\n        }\r\n\r\n        // When a render pass is active, pop its groups; otherwise pop encoder-level groups.\r\n        // Pass-level groups are never pushed on the encoder, so we never pop them from it.\r\n        const groups = this._currentRenderPass ? this._debugMarkersPassGroups : this._debugMarkersEncoderGroups;\r\n        const target = this._currentRenderPass ?? this._renderEncoder;\r\n\r\n        for (let i = groups.length - 1; i >= 0; --i) {\r\n            if (this._showGPUDebugMarkersLog) {\r\n                Logger.Log(\r\n                    `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] [automatic] Popping debug group '${groups[i]}' on '${target.label}'.`\r\n                );\r\n            }\r\n            target.popDebugGroup();\r\n        }\r\n    }\r\n\r\n    protected _debugPushAfterStartOfEncoder() {\r\n        if (!this._enableGPUDebugMarkers) {\r\n            return;\r\n        }\r\n\r\n        // When a render pass is active, re-push its floating groups onto it; otherwise re-push\r\n        // encoder-level groups onto the new render encoder.\r\n        // Pass-level groups stay floating until the next render pass starts.\r\n        const groups = this._currentRenderPass ? this._debugMarkersPassGroups : this._debugMarkersEncoderGroups;\r\n        const target = this._currentRenderPass ?? this._renderEncoder;\r\n\r\n        for (const groupName of groups) {\r\n            if (this._showGPUDebugMarkersLog) {\r\n                Logger.Log(\r\n                    `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] [automatic] Pushing debug group '${groupName}' on '${target.label}'.`\r\n                );\r\n            }\r\n            target.pushDebugGroup(groupName);\r\n        }\r\n    }\r\n\r\n    protected _debugPendingPop(currentRenderPass: GPURenderPassEncoder) {\r\n        if (!this._enableGPUDebugMarkers) {\r\n            return;\r\n        }\r\n\r\n        // The user popped encoder-level groups while a render pass was active (the pass was the live\r\n        // object, so the pops were deferred). Now that the pass has ended we replay them on the render\r\n        // encoder. Because _debugMarkersEncoderGroups only ever contains encoder-level entries, popping\r\n        // from it here can never accidentally consume a pass-level group.\r\n        while (this._debugMarkersPendingEncoderPops-- > 0) {\r\n            const groupName = this._debugMarkersEncoderGroups.pop();\r\n\r\n            if (this._showGPUDebugMarkersLog) {\r\n                Logger.Log(\r\n                    `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] [automatic] Popping debug group '${groupName}' on render encoder '${this._renderEncoder.label}' after the end of render pass '${currentRenderPass.label}'.`\r\n                );\r\n            }\r\n\r\n            this._renderEncoder.popDebugGroup();\r\n        }\r\n\r\n        this._debugMarkersPendingEncoderPops = 0;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/** @internal */\r\n// eslint-disable-next-line import/export\r\nexport const enum PowerPreference {\r\n    LowPower = \"low-power\",\r\n    HighPerformance = \"high-performance\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum FeatureName {\r\n    CoreFeaturesAndLimits = \"core-features-and-limits\",\r\n    DepthClipControl = \"depth-clip-control\",\r\n    Depth32FloatStencil8 = \"depth32float-stencil8\",\r\n    TextureCompressionBC = \"texture-compression-bc\",\r\n    TextureCompressionBCSliced3D = \"texture-compression-bc-sliced-3d\",\r\n    TextureCompressionETC2 = \"texture-compression-etc2\",\r\n    TextureCompressionASTC = \"texture-compression-astc\",\r\n    TextureCompressionASTCSliced3D = \"texture-compression-astc-sliced-3d\",\r\n    TimestampQuery = \"timestamp-query\",\r\n    IndirectFirstInstance = \"indirect-first-instance\",\r\n    ShaderF16 = \"shader-f16\",\r\n    RG11B10UFloatRenderable = \"rg11b10ufloat-renderable\",\r\n    BGRA8UnormStorage = \"bgra8unorm-storage\",\r\n    Float32Filterable = \"float32-filterable\",\r\n    Float32Blendable = \"float32-blendable\",\r\n    ClipDistances = \"clip-distances\",\r\n    DualSourceBlending = \"dual-source-blending\",\r\n    Subgroups = \"subgroups\",\r\n    TextureFormatsTier1 = \"texture-formats-tier1\",\r\n    TextureFormatsTier2 = \"texture-formats-tier2\",\r\n    PrimitiveIndex = \"primitive-index\",\r\n    TextureComponentSwizzle = \"texture-component-swizzle\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum BufferMapState {\r\n    Unmapped = \"unmapped\",\r\n    Pending = \"pending\",\r\n    Mapped = \"mapped\",\r\n}\r\n\r\n/** @internal */\r\nexport enum BufferUsage {\r\n    MapRead = 1,\r\n    MapWrite = 2,\r\n    CopySrc = 4,\r\n    CopyDst = 8,\r\n    Index = 16,\r\n    Vertex = 32,\r\n    Uniform = 64,\r\n    Storage = 128,\r\n    Indirect = 256,\r\n    QueryResolve = 512,\r\n}\r\n\r\n/** @internal */\r\nexport const enum MapMode {\r\n    Read = 1,\r\n    Write = 2,\r\n}\r\n\r\n/** @internal */\r\nexport const enum TextureDimension {\r\n    E1d = \"1d\",\r\n    E2d = \"2d\",\r\n    E3d = \"3d\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum TextureUsage {\r\n    CopySrc = 1,\r\n    CopyDst = 2,\r\n    TextureBinding = 4,\r\n    StorageBinding = 8,\r\n    RenderAttachment = 16,\r\n    TransientAttachment = 32,\r\n}\r\n\r\n/** @internal */\r\nexport const enum TextureViewDimension {\r\n    E1d = \"1d\",\r\n    E2d = \"2d\",\r\n    E2dArray = \"2d-array\",\r\n    Cube = \"cube\",\r\n    CubeArray = \"cube-array\",\r\n    E3d = \"3d\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum TextureAspect {\r\n    All = \"all\",\r\n    StencilOnly = \"stencil-only\",\r\n    DepthOnly = \"depth-only\",\r\n}\r\n\r\n/**\r\n * Comments taken from https://github.com/gfx-rs/wgpu/blob/master/wgpu-types/src/lib.rs\r\n * @internal\r\n */\r\nexport const enum TextureFormat {\r\n    // 8-bit formats\r\n    R8Unorm = \"r8unorm\", // Red channel only. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.\r\n    R8Snorm = \"r8snorm\", // Red channel only. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.\r\n    R8Uint = \"r8uint\", // Red channel only. 8 bit integer per channel. Unsigned in shader.\r\n    R8Sint = \"r8sint\", // Red channel only. 8 bit integer per channel. Signed in shader.\r\n\r\n    // 16-bit formats\r\n    R16Uint = \"r16uint\", // Red channel only. 16 bit integer per channel. Unsigned in shader.\r\n    R16Sint = \"r16sint\", // Red channel only. 16 bit integer per channel. Signed in shader.\r\n    R16Float = \"r16float\", // Red channel only. 16 bit float per channel. Float in shader.\r\n    RG8Unorm = \"rg8unorm\", // Red and green channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.\r\n    RG8Snorm = \"rg8snorm\", // Red and green channels. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.\r\n    RG8Uint = \"rg8uint\", // Red and green channels. 8 bit integer per channel. Unsigned in shader.\r\n    RG8Sint = \"rg8sint\", // Red and green channels. 8 bit integer per channel. Signed in shader.\r\n    R16Unorm = \"r16unorm\", // Red channel only. 16 bit integer per channel. [0, 65535] converted to float [0, 1] in shader.\r\n    R16Snorm = \"r16snorm\", // Red channel only. 16 bit integer per channel. [-32768, 32767] converted to float [-1, 1] in shader.\r\n\r\n    // 32-bit formats\r\n    R32Uint = \"r32uint\", // Red channel only. 32 bit integer per channel. Unsigned in shader.\r\n    R32Sint = \"r32sint\", // Red channel only. 32 bit integer per channel. Signed in shader.\r\n    R32Float = \"r32float\", // Red channel only. 32 bit float per channel. Float in shader.\r\n    RG16Uint = \"rg16uint\", // Red and green channels. 16 bit integer per channel. Unsigned in shader.\r\n    RG16Sint = \"rg16sint\", // Red and green channels. 16 bit integer per channel. Signed in shader.\r\n    RG16Float = \"rg16float\", // Red and green channels. 16 bit float per channel. Float in shader.\r\n    RGBA8Unorm = \"rgba8unorm\", // Red, green, blue, and alpha channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.\r\n    RGBA8UnormSRGB = \"rgba8unorm-srgb\", // Red, green, blue, and alpha channels. 8 bit integer per channel. Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.\r\n    RGBA8Snorm = \"rgba8snorm\", // Red, green, blue, and alpha channels. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.\r\n    RGBA8Uint = \"rgba8uint\", // Red, green, blue, and alpha channels. 8 bit integer per channel. Unsigned in shader.\r\n    RGBA8Sint = \"rgba8sint\", // Red, green, blue, and alpha channels. 8 bit integer per channel. Signed in shader.\r\n    BGRA8Unorm = \"bgra8unorm\", // Blue, green, red, and alpha channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.\r\n    BGRA8UnormSRGB = \"bgra8unorm-srgb\", // Blue, green, red, and alpha channels. 8 bit integer per channel. Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.\r\n    RG16Unorm = \"rg16unorm\", // Red and green channels. 16 bit integer per channel. [0, 65535] converted to float [0, 1] in shader.\r\n    RG16Snorm = \"rg16snorm\", // Red and green channels. 16 bit integer per channel. [-32768, 32767] converted to float [-1, 1] in shader.\r\n    // Packed 32-bit formats\r\n    RGB9E5UFloat = \"rgb9e5ufloat\", // Packed unsigned float with 9 bits mantisa for each RGB component, then a common 5 bits exponent\r\n    RGB10A2UINT = \"rgb10a2uint\", // Red, green, blue, and alpha channels. 10 bit integer for RGB channels, 2 bit integer for alpha channel. [0, 1023] ([0, 3] for alpha).\r\n    RGB10A2Unorm = \"rgb10a2unorm\", // Red, green, blue, and alpha channels. 10 bit integer for RGB channels, 2 bit integer for alpha channel. [0, 1023] ([0, 3] for alpha) converted to/from float [0, 1] in shader.\r\n    RG11B10UFloat = \"rg11b10ufloat\", // Red, green, and blue channels. 11 bit float with no sign bit for RG channels. 10 bit float with no sign bit for blue channel. Float in shader.\r\n\r\n    // 64-bit formats\r\n    RG32Uint = \"rg32uint\", // Red and green channels. 32 bit integer per channel. Unsigned in shader.\r\n    RG32Sint = \"rg32sint\", // Red and green channels. 32 bit integer per channel. Signed in shader.\r\n    RG32Float = \"rg32float\", // Red and green channels. 32 bit float per channel. Float in shader.\r\n    RGBA16Uint = \"rgba16uint\", // Red, green, blue, and alpha channels. 16 bit integer per channel. Unsigned in shader.\r\n    RGBA16Sint = \"rgba16sint\", // Red, green, blue, and alpha channels. 16 bit integer per channel. Signed in shader.\r\n    RGBA16Float = \"rgba16float\", // Red, green, blue, and alpha channels. 16 bit float per channel. Float in shader.\r\n    RGBA16Unorm = \"rgba16unorm\", // Red, green, blue, and alpha channels. 16 bit integer per channel. [0, 65535] converted to float [0, 1] in shader.\r\n    RGBA16Snorm = \"rgba16snorm\", // Red, green, blue, and alpha channels. 16 bit integer per channel. [-32768, 32767] converted to float [-1, 1] in shader.\r\n\r\n    // 128-bit formats\r\n    RGBA32Uint = \"rgba32uint\", // Red, green, blue, and alpha channels. 32 bit integer per channel. Unsigned in shader.\r\n    RGBA32Sint = \"rgba32sint\", // Red, green, blue, and alpha channels. 32 bit integer per channel. Signed in shader.\r\n    RGBA32Float = \"rgba32float\", // Red, green, blue, and alpha channels. 32 bit float per channel. Float in shader.\r\n\r\n    // Depth and stencil formats\r\n    Stencil8 = \"stencil8\",\r\n    Depth16Unorm = \"depth16unorm\",\r\n    Depth24Plus = \"depth24plus\", // Special depth format with at least 24 bit integer depth.\r\n    Depth24PlusStencil8 = \"depth24plus-stencil8\", // Special depth/stencil format with at least 24 bit integer depth and 8 bits integer stencil.\r\n    Depth32Float = \"depth32float\", // Special depth format with 32 bit floating point depth.\r\n\r\n    // BC compressed formats usable if \"texture-compression-bc\" is both\r\n    // supported by the device/user agent and enabled in requestDevice.\r\n    BC1RGBAUnorm = \"bc1-rgba-unorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha. Also known as DXT1.\r\n    BC1RGBAUnormSRGB = \"bc1-rgba-unorm-srgb\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha. Also known as DXT1.\r\n    BC2RGBAUnorm = \"bc2-rgba-unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet. 5 bit R + 6 bit G + 5 bit B + 4 bit alpha. Also known as DXT3.\r\n    BC2RGBAUnormSRGB = \"bc2-rgba-unorm-srgb\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet. 5 bit R + 6 bit G + 5 bit B + 4 bit alpha. Also known as DXT3.\r\n    BC3RGBAUnorm = \"bc3-rgba-unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet + 8 alpha pallet. 5 bit R + 6 bit G + 5 bit B + 8 bit alpha. Also known as DXT5.\r\n    BC3RGBAUnormSRGB = \"bc3-rgba-unorm-srgb\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet + 8 alpha pallet. 5 bit R + 6 bit G + 5 bit B + 8 bit alpha. Also known as DXT5.\r\n    BC4RUnorm = \"bc4-r-unorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). 8 color pallet. 8 bit R. Also known as RGTC1.\r\n    BC4RSnorm = \"bc4-r-snorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). 8 color pallet. 8 bit R. Also known as RGTC1.\r\n    BC5RGUnorm = \"bc5-rg-unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). 8 color red pallet + 8 color green pallet. 8 bit RG. Also known as RGTC2.\r\n    BC5RGSnorm = \"bc5-rg-snorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). 8 color red pallet + 8 color green pallet. 8 bit RG. Also known as RGTC2.\r\n    BC6HRGBUFloat = \"bc6h-rgb-ufloat\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 16 bit unsigned float RGB. Float in shader. Also known as BPTC (float).\r\n    BC6HRGBFloat = \"bc6h-rgb-float\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 16 bit signed float RGB. Float in shader. Also known as BPTC (float).\r\n    BC7RGBAUnorm = \"bc7-rgba-unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 8 bit integer RGBA. Also known as BPTC (unorm).\r\n    BC7RGBAUnormSRGB = \"bc7-rgba-unorm-srgb\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 8 bit integer RGBA. Also known as BPTC (unorm).\r\n\r\n    // ETC2 compressed formats usable if \"texture-compression-etc2\" is both\r\n    // supported by the device/user agent and enabled in requestDevice.\r\n    ETC2RGB8Unorm = \"etc2-rgb8unorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB.\r\n    ETC2RGB8UnormSRGB = \"etc2-rgb8unorm-srgb\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB.\r\n    ETC2RGB8A1Unorm = \"etc2-rgb8a1unorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB + 1 bit alpha.\r\n    ETC2RGB8A1UnormSRGB = \"etc2-rgb8a1unorm-srgb\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB + 1 bit alpha.\r\n    ETC2RGBA8Unorm = \"etc2-rgba8unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGB + 8 bit alpha.\r\n    ETC2RGBA8UnormSRGB = \"etc2-rgba8unorm-srgb\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGB + 8 bit alpha.\r\n    EACR11Unorm = \"eac-r11unorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 11 bit integer R.\r\n    EACR11Snorm = \"eac-r11snorm\", // 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 11 bit integer R.\r\n    EACRG11Unorm = \"eac-rg11unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 11 bit integer R + 11 bit integer G.\r\n    EACRG11Snorm = \"eac-rg11snorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 11 bit integer R + 11 bit integer G.\r\n\r\n    // ASTC compressed formats usable if \"texture-compression-astc\" is both\r\n    // supported by the device/user agent and enabled in requestDevice.\r\n    ASTC4x4Unorm = \"astc-4x4-unorm\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC4x4UnormSRGB = \"astc-4x4-unorm-srgb\", // 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC5x4Unorm = \"astc-5x4-unorm\", // 5x4 block compressed texture. 16 bytes per block (6.4 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC5x4UnormSRGB = \"astc-5x4-unorm-srgb\", // 5x4 block compressed texture. 16 bytes per block (6.4 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC5x5Unorm = \"astc-5x5-unorm\", // 5x5 block compressed texture. 16 bytes per block (5.12 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC5x5UnormSRGB = \"astc-5x5-unorm-srgb\", // 5x5 block compressed texture. 16 bytes per block (5.12 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC6x5Unorm = \"astc-6x5-unorm\", // 6x5 block compressed texture. 16 bytes per block (4.27 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC6x5UnormSRGB = \"astc-6x5-unorm-srgb\", // 6x5 block compressed texture. 16 bytes per block (4.27 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC6x6Unorm = \"astc-6x6-unorm\", // 6x6 block compressed texture. 16 bytes per block (3.56 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC6x6UnormSRGB = \"astc-6x6-unorm-srgb\", // 6x6 block compressed texture. 16 bytes per block (3.56 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC8x5Unorm = \"astc-8x5-unorm\", // 8x5 block compressed texture. 16 bytes per block (3.2 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC8x5UnormSRGB = \"astc-8x5-unorm-srgb\", // 8x5 block compressed texture. 16 bytes per block (3.2 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC8x6Unorm = \"astc-8x6-unorm\", // 8x6 block compressed texture. 16 bytes per block (2.67 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC8x6UnormSRGB = \"astc-8x6-unorm-srgb\", // 8x6 block compressed texture. 16 bytes per block (2.67 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC8x8Unorm = \"astc-8x8-unorm\", // 8x8 block compressed texture. 16 bytes per block (2 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC8x8UnormSRGB = \"astc-8x8-unorm-srgb\", // 8x8 block compressed texture. 16 bytes per block (2 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x5Unorm = \"astc-10x5-unorm\", // 10x5 block compressed texture. 16 bytes per block (2.56 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x5UnormSRGB = \"astc-10x5-unorm-srgb\", // 10x5 block compressed texture. 16 bytes per block (2.56 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x6Unorm = \"astc-10x6-unorm\", // 10x6 block compressed texture. 16 bytes per block (2.13 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x6UnormSRGB = \"astc-10x6-unorm-srgb\", // 10x6 block compressed texture. 16 bytes per block (2.13 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x8Unorm = \"astc-10x8-unorm\", // 10x8 block compressed texture. 16 bytes per block (1.6 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x8UnormSRGB = \"astc-10x8-unorm-srgb\", // 10x8 block compressed texture. 16 bytes per block (1.6 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x10Unorm = \"astc-10x10-unorm\", // 10x10 block compressed texture. 16 bytes per block (1.28 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC10x10UnormSRGB = \"astc-10x10-unorm-srgb\", // 10x10 block compressed texture. 16 bytes per block (1.28 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC12x10Unorm = \"astc-12x10-unorm\", // 12x10 block compressed texture. 16 bytes per block (1.07 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC12x10UnormSRGB = \"astc-12x10-unorm-srgb\", // 12x10 block compressed texture. 16 bytes per block (1.07 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC12x12Unorm = \"astc-12x12-unorm\", // 12x12 block compressed texture. 16 bytes per block (0.89 bit/px). Complex pallet. 8 bit integer RGBA.\r\n    ASTC12x12UnormSRGB = \"astc-12x12-unorm-srgb\", // 12x12 block compressed texture. 16 bytes per block (0.89 bit/px). Complex pallet. 8 bit integer RGBA.\r\n\r\n    // \"depth32float-stencil8\" feature\r\n    Depth32FloatStencil8 = \"depth32float-stencil8\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum AddressMode {\r\n    ClampToEdge = \"clamp-to-edge\",\r\n    Repeat = \"repeat\",\r\n    MirrorRepeat = \"mirror-repeat\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum FilterMode {\r\n    Nearest = \"nearest\",\r\n    Linear = \"linear\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum MipmapFilterMode {\r\n    Nearest = \"nearest\",\r\n    Linear = \"linear\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum CompareFunction {\r\n    Never = \"never\",\r\n    Less = \"less\",\r\n    Equal = \"equal\",\r\n    LessEqual = \"less-equal\",\r\n    Greater = \"greater\",\r\n    NotEqual = \"not-equal\",\r\n    GreaterEqual = \"greater-equal\",\r\n    Always = \"always\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum ShaderStage {\r\n    Vertex = 1,\r\n    Fragment = 2,\r\n    Compute = 4,\r\n}\r\n\r\n/** @internal */\r\nexport const enum BufferBindingType {\r\n    Uniform = \"uniform\",\r\n    Storage = \"storage\",\r\n    ReadOnlyStorage = \"read-only-storage\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum SamplerBindingType {\r\n    Filtering = \"filtering\",\r\n    NonFiltering = \"non-filtering\",\r\n    Comparison = \"comparison\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum TextureSampleType {\r\n    Float = \"float\",\r\n    UnfilterableFloat = \"unfilterable-float\",\r\n    Depth = \"depth\",\r\n    Sint = \"sint\",\r\n    Uint = \"uint\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum StorageTextureAccess {\r\n    WriteOnly = \"write-only\",\r\n    ReadOnly = \"read-only\",\r\n    ReadWrite = \"read-write\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum CompilationMessageType {\r\n    Error = \"error\",\r\n    Warning = \"warning\",\r\n    Info = \"info\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum PipelineErrorReason {\r\n    Validation = \"validation\",\r\n    Internal = \"internal\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum AutoLayoutMode {\r\n    Auto = \"auto\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum PrimitiveTopology {\r\n    PointList = \"point-list\",\r\n    LineList = \"line-list\",\r\n    LineStrip = \"line-strip\",\r\n    TriangleList = \"triangle-list\",\r\n    TriangleStrip = \"triangle-strip\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum FrontFace {\r\n    CCW = \"ccw\",\r\n    CW = \"cw\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum CullMode {\r\n    None = \"none\",\r\n    Front = \"front\",\r\n    Back = \"back\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum ColorWrite {\r\n    Red = 1,\r\n    Green = 2,\r\n    Blue = 4,\r\n    Alpha = 8,\r\n    All = 15,\r\n}\r\n\r\n/** @internal */\r\nexport const enum BlendFactor {\r\n    Zero = \"zero\",\r\n    One = \"one\",\r\n    Src = \"src\",\r\n    OneMinusSrc = \"one-minus-src\",\r\n    SrcAlpha = \"src-alpha\",\r\n    OneMinusSrcAlpha = \"one-minus-src-alpha\",\r\n    Dst = \"dst\",\r\n    OneMinusDst = \"one-minus-dst\",\r\n    DstAlpha = \"dst-alpha\",\r\n    OneMinusDstAlpha = \"one-minus-dst-alpha\",\r\n    SrcAlphaSaturated = \"src-alpha-saturated\",\r\n    Constant = \"constant\",\r\n    OneMinusConstant = \"one-minus-constant\",\r\n    Src1 = \"src1\",\r\n    OneMinusSrc1 = \"one-minus-src1\",\r\n    Src1Alpha = \"src1-alpha\",\r\n    OneMinusSrc1Alpha = \"one-minus-src1-alpha\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum BlendOperation {\r\n    Add = \"add\",\r\n    Subtract = \"subtract\",\r\n    ReverseSubtract = \"reverse-subtract\",\r\n    Min = \"min\",\r\n    Max = \"max\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum StencilOperation {\r\n    Keep = \"keep\",\r\n    Zero = \"zero\",\r\n    Replace = \"replace\",\r\n    Invert = \"invert\",\r\n    IncrementClamp = \"increment-clamp\",\r\n    DecrementClamp = \"decrement-clamp\",\r\n    IncrementWrap = \"increment-wrap\",\r\n    DecrementWrap = \"decrement-wrap\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum IndexFormat {\r\n    Uint16 = \"uint16\",\r\n    Uint32 = \"uint32\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum VertexFormat {\r\n    Uint8 = \"uint8\",\r\n    Uint8x2 = \"uint8x2\",\r\n    Uint8x4 = \"uint8x4\",\r\n    Sint8 = \"sint8\",\r\n    Sint8x2 = \"sint8x2\",\r\n    Sint8x4 = \"sint8x4\",\r\n    Unorm8 = \"unorm8\",\r\n    Unorm8x2 = \"unorm8x2\",\r\n    Unorm8x4 = \"unorm8x4\",\r\n    Snorm8 = \"snorm8\",\r\n    Snorm8x2 = \"snorm8x2\",\r\n    Snorm8x4 = \"snorm8x4\",\r\n    Uint16 = \"uint16\",\r\n    Uint16x2 = \"uint16x2\",\r\n    Uint16x4 = \"uint16x4\",\r\n    Sint16 = \"sint16\",\r\n    Sint16x2 = \"sint16x2\",\r\n    Sint16x4 = \"sint16x4\",\r\n    Unorm16 = \"unorm16\",\r\n    Unorm16x2 = \"unorm16x2\",\r\n    Unorm16x4 = \"unorm16x4\",\r\n    Snorm16 = \"snorm16\",\r\n    Snorm16x2 = \"snorm16x2\",\r\n    Snorm16x4 = \"snorm16x4\",\r\n    Float16 = \"float16\",\r\n    Float16x2 = \"float16x2\",\r\n    Float16x4 = \"float16x4\",\r\n    Float32 = \"float32\",\r\n    Float32x2 = \"float32x2\",\r\n    Float32x3 = \"float32x3\",\r\n    Float32x4 = \"float32x4\",\r\n    Uint32 = \"uint32\",\r\n    Uint32x2 = \"uint32x2\",\r\n    Uint32x3 = \"uint32x3\",\r\n    Uint32x4 = \"uint32x4\",\r\n    Sint32 = \"sint32\",\r\n    Sint32x2 = \"sint32x2\",\r\n    Sint32x3 = \"sint32x3\",\r\n    Sint32x4 = \"sint32x4\",\r\n    UNORM10x10x10x2 = \"unorm10-10-10-2\",\r\n    UNORM8x4BGRA = \"unorm8x4-bgra\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum VertexStepMode {\r\n    Vertex = \"vertex\",\r\n    Instance = \"instance\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum ComputePassTimestampLocation {\r\n    Beginning = \"beginning\",\r\n    End = \"end\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum RenderPassTimestampLocation {\r\n    Beginning = \"beginning\",\r\n    End = \"end\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum LoadOp {\r\n    Load = \"load\",\r\n    Clear = \"clear\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum StoreOp {\r\n    Store = \"store\",\r\n    Discard = \"discard\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum QueryType {\r\n    Occlusion = \"occlusion\",\r\n    Timestamp = \"timestamp\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum CanvasAlphaMode {\r\n    Opaque = \"opaque\",\r\n    Premultiplied = \"premultiplied\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum CanvasToneMappingMode {\r\n    Standard = \"standard\",\r\n    Extended = \"extended\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum DeviceLostReason {\r\n    Unknown = \"unknown\",\r\n    Destroyed = \"destroyed\",\r\n}\r\n\r\n/** @internal */\r\nexport const enum ErrorFilter {\r\n    Validation = \"validation\",\r\n    OutOfMemory = \"out-of-memory\",\r\n    Internal = \"internal\",\r\n}\r\n","/* eslint-disable jsdoc/require-jsdoc */\r\n/* eslint-disable babylonjs/available */\r\nimport { type IHardwareTextureWrapper } from \"../../Materials/Textures/hardwareTextureWrapper\";\r\nimport { ILog2 } from \"../../Maths/math.scalar.functions\";\r\nimport { type Nullable } from \"../../types\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { WebGPUTextureHelper } from \"./webgpuTextureHelper\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\n\r\n/** @internal */\r\nexport class WebGPUHardwareTexture implements IHardwareTextureWrapper {\r\n    /**\r\n     * Cache of RenderPassDescriptor and BindGroup used when generating mipmaps (see WebGPUTextureHelper.generateMipmaps)\r\n     * @internal\r\n     */\r\n    public _mipmapGenRenderPassDescr: GPURenderPassDescriptor[][];\r\n    /** @internal */\r\n    public _mipmapGenBindGroup: GPUBindGroup[][];\r\n\r\n    /**\r\n     * Cache for the invertYPreMultiplyAlpha function (see WebGPUTextureHelper)\r\n     * @internal\r\n     */\r\n    public _copyInvertYTempTexture?: GPUTexture;\r\n    /** @internal */\r\n    public _copyInvertYRenderPassDescr: GPURenderPassDescriptor;\r\n    /** @internal */\r\n    public _copyInvertYBindGroup: GPUBindGroup;\r\n    /** @internal */\r\n    public _copyInvertYBindGroupWithOfst: GPUBindGroup;\r\n\r\n    /** @internal */\r\n    public _originalFormatIsRGB = false;\r\n\r\n    private _webgpuTexture: Nullable<GPUTexture>;\r\n    // There can be multiple MSAA textures for a single WebGPU texture because different layers of a 2DArrayTexture / 3DTexture\r\n    // or different faces of a cube texture can be bound to different render targets at the same time (in a multi RenderTargetWrapper)\r\n    private _webgpuMSAATexture: GPUTexture[];\r\n\r\n    public get underlyingResource(): Nullable<GPUTexture> {\r\n        return this._webgpuTexture;\r\n    }\r\n\r\n    // index is the index of the layer for a 2DArrayTexture / 3DTexture, the face index for a cube texture or the layer * 6 + face index for a cube array texture.\r\n    // In single render target case, index is 0.\r\n    public getMSAATexture(sampleCount: number, index = 0): GPUTexture {\r\n        const texture = this._webgpuMSAATexture[index];\r\n        if (!texture) {\r\n            this._createMSAATexture(sampleCount, index);\r\n        }\r\n        return this._webgpuMSAATexture[index];\r\n    }\r\n\r\n    public releaseMSAATextures(): void {\r\n        for (const texture of this._webgpuMSAATexture) {\r\n            if (texture) {\r\n                this._engine._textureHelper.releaseTexture(texture);\r\n            }\r\n        }\r\n        this._webgpuMSAATexture.length = 0;\r\n    }\r\n\r\n    public view: Nullable<GPUTextureView>;\r\n    public viewForWriting: Nullable<GPUTextureView>;\r\n    public format: GPUTextureFormat = WebGPUConstants.TextureFormat.RGBA8Unorm;\r\n    // This is the original format requested. It can be different from \"format\" in case original format is a depth/stencil format and MSAA is requested.\r\n    // In that case, format will be a R16 or R32 format, because the texture will be used as the resolve texture.\r\n    public originalFormat: GPUTextureFormat = WebGPUConstants.TextureFormat.RGBA8Unorm;\r\n    public textureUsages = 0;\r\n    public textureAdditionalUsages = 0;\r\n\r\n    constructor(\r\n        private _engine: WebGPUEngine,\r\n        existingTexture: Nullable<GPUTexture> = null\r\n    ) {\r\n        this._webgpuTexture = existingTexture;\r\n        this._webgpuMSAATexture = [];\r\n        this.view = null;\r\n        this.viewForWriting = null;\r\n    }\r\n\r\n    public set(hardwareTexture: GPUTexture): void {\r\n        this._webgpuTexture = hardwareTexture;\r\n    }\r\n\r\n    public setUsage(_textureSource: number, generateMipMaps: boolean, is2DArray: boolean, isCube: boolean, is3D: boolean, width: number, height: number, depth: number): void {\r\n        let viewDimension: GPUTextureViewDimension = WebGPUConstants.TextureViewDimension.E2d;\r\n        let arrayLayerCount = 1;\r\n        if (isCube) {\r\n            viewDimension = is2DArray ? WebGPUConstants.TextureViewDimension.CubeArray : WebGPUConstants.TextureViewDimension.Cube;\r\n            arrayLayerCount = 6 * (depth || 1);\r\n        } else if (is3D) {\r\n            viewDimension = WebGPUConstants.TextureViewDimension.E3d;\r\n            arrayLayerCount = 1;\r\n        } else if (is2DArray) {\r\n            viewDimension = WebGPUConstants.TextureViewDimension.E2dArray;\r\n            arrayLayerCount = depth;\r\n        }\r\n\r\n        const format = WebGPUTextureHelper.GetDepthFormatOnly(this.format);\r\n        const aspect = WebGPUTextureHelper.HasDepthAndStencilAspects(this.format) ? WebGPUConstants.TextureAspect.DepthOnly : WebGPUConstants.TextureAspect.All;\r\n\r\n        this.createView({\r\n            label: `TextureView${is3D ? \"3D\" : isCube ? \"Cube\" : \"2D\"}${is2DArray ? \"_Array\" + arrayLayerCount : \"\"}_${width}x${height}_${generateMipMaps ? \"wmips\" : \"womips\"}_${\r\n                this.format\r\n            }_${viewDimension}`,\r\n            format,\r\n            dimension: viewDimension,\r\n            mipLevelCount: generateMipMaps ? ILog2(Math.max(width, height)) + 1 : 1,\r\n            baseArrayLayer: 0,\r\n            baseMipLevel: 0,\r\n            arrayLayerCount,\r\n            aspect,\r\n        });\r\n    }\r\n\r\n    public createView(descriptor?: GPUTextureViewDescriptor, createViewForWriting = false): void {\r\n        this.view = this._webgpuTexture!.createView(descriptor);\r\n        if (createViewForWriting && descriptor) {\r\n            const saveNumMipMaps = descriptor.mipLevelCount;\r\n            descriptor.mipLevelCount = 1;\r\n            this.viewForWriting = this._webgpuTexture!.createView(descriptor);\r\n            descriptor.mipLevelCount = saveNumMipMaps;\r\n        }\r\n    }\r\n\r\n    public reset(): void {\r\n        this._webgpuTexture = null;\r\n        this._webgpuMSAATexture.length = 0;\r\n        this.view = null;\r\n        this.viewForWriting = null;\r\n    }\r\n\r\n    public release(): void {\r\n        this._webgpuTexture?.destroy();\r\n        this.releaseMSAATextures();\r\n        this._copyInvertYTempTexture?.destroy();\r\n        this.reset();\r\n    }\r\n\r\n    private _createMSAATexture(samples: number, index: number): void {\r\n        if (!this._webgpuTexture) {\r\n            throw new Error(\"Cannot create GPU MSAA texture because underlying GPU texture is not created yet.\");\r\n        }\r\n\r\n        if (!this._webgpuMSAATexture) {\r\n            this._webgpuMSAATexture = [];\r\n        }\r\n\r\n        this._webgpuMSAATexture[index] = this._engine._textureHelper.createMSAATexture(this._webgpuTexture, this.originalFormat, samples);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\n// License for the mipmap generation code:\r\n//\r\n// Copyright 2020 Brandon Jones\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a copy\r\n// of this software and associated documentation files (the \"Software\"), to deal\r\n// in the Software without restriction, including without limitation the rights\r\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n// copies of the Software, and to permit persons to whom the Software is\r\n// furnished to do so, subject to the following conditions:\r\n\r\n// The above copyright notice and this permission notice shall be included in\r\n// all copies or substantial portions of the Software.\r\n\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n// SOFTWARE.\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { type WebGPUBufferManager } from \"./webgpuBufferManager\";\r\nimport { Constants } from \"../constants\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { type IHardwareTextureWrapper } from \"../../Materials/Textures/hardwareTextureWrapper\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { WebGPUHardwareTexture } from \"./webgpuHardwareTexture\";\r\nimport { type ExternalTexture } from \"../../Materials/Textures/externalTexture\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { WebGPUTextureHelper } from \"./webgpuTextureHelper\";\r\nimport { type _IProcessingOptions } from \"../Processors/shaderProcessingOptions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Finalize, Initialize, Process } from \"../Processors/shaderProcessor\";\r\nimport { type WebGPUShaderProcessorWGSL } from \"./webgpuShaderProcessorsWGSL\";\r\n\r\n// TODO WEBGPU improve mipmap generation by using compute shaders\r\n\r\nconst mipmapVertexSource = `\r\n    const pos = array<vec2<f32>, 4>( vec2f(-1.0f, 1.0f),  vec2f(1.0f, 1.0f),  vec2f(-1.0f, -1.0f),  vec2f(1.0f, -1.0f));\r\n    const tex = array<vec2<f32>, 4>( vec2f(0.0f, 0.0f),  vec2f(1.0f, 0.0f),  vec2f(0.0f, 1.0f),  vec2f(1.0f, 1.0f));\r\n\r\n    varying vTex: vec2f;\r\n\r\n    @vertex\r\n    fn main(input : VertexInputs) -> FragmentInputs {\r\n        vertexOutputs.vTex = tex[input.vertexIndex];\r\n        vertexOutputs.position = vec4f(pos[input.vertexIndex], 0.0, 1.0);\r\n    }\r\n    `;\r\n\r\nconst mipmapFragmentSource = `\r\n    var imgSampler: sampler;\r\n    var img: texture_2d<f32>;\r\n\r\n    varying vTex: vec2f;\r\n\r\n    @fragment\r\n    fn main(input: FragmentInputs) -> FragmentOutputs {\r\n        fragmentOutputs.color = textureSample(img, imgSampler, input.vTex);\r\n    }\r\n    `;\r\n\r\nconst invertYPreMultiplyAlphaVertexSource = `\r\n    const pos = array<vec2<f32>, 4>( vec2f(-1.0f, 1.0f),  vec2f(1.0f, 1.0f),  vec2f(-1.0f, -1.0f),  vec2f(1.0f, -1.0f));\r\n    const tex = array<vec2<f32>, 4>( vec2f(0.0f, 0.0f),  vec2f(1.0f, 0.0f),  vec2f(0.0f, 1.0f),  vec2f(1.0f, 1.0f));\r\n\r\n    var img: texture_2d<f32>;\r\n\r\n    #ifdef INVERTY\r\n        varying vTextureSize: vec2f;\r\n    #endif\r\n\r\n    @vertex\r\n    fn main(input : VertexInputs) -> FragmentInputs {\r\n        #ifdef INVERTY\r\n            vertexOutputs.vTextureSize = vec2f(textureDimensions(img, 0));\r\n        #endif\r\n        vertexOutputs.position =  vec4f(pos[input.vertexIndex], 0.0, 1.0);\r\n    }\r\n    `;\r\n\r\nconst invertYPreMultiplyAlphaFragmentSource = `\r\n    var img: texture_2d<f32>;\r\n\r\n    #ifdef INVERTY\r\n        varying vTextureSize: vec2f;\r\n    #endif\r\n\r\n    @fragment\r\n    fn main(input: FragmentInputs) -> FragmentOutputs {\r\n    #ifdef INVERTY\r\n        var color: vec4f = textureLoad(img, vec2i(i32(input.position.x), i32(input.vTextureSize.y - input.position.y)), 0);\r\n    #else\r\n        var color: vec4f = textureLoad(img, vec2i(input.position.xy), 0);\r\n    #endif\r\n    #ifdef PREMULTIPLYALPHA\r\n        color = vec4f(color.rgb * color.a, color.a);\r\n    #endif\r\n        fragmentOutputs.color = color;\r\n    }\r\n    `;\r\n\r\nconst invertYPreMultiplyAlphaWithOfstVertexSource = invertYPreMultiplyAlphaVertexSource;\r\n\r\nconst invertYPreMultiplyAlphaWithOfstFragmentSource = `\r\n    var img: texture_2d<f32>;\r\n    uniform ofstX: f32;\r\n    uniform ofstY: f32;\r\n    uniform width: f32;\r\n    uniform height: f32;\r\n\r\n    #ifdef INVERTY\r\n        varying vTextureSize: vec2f;\r\n    #endif\r\n\r\n    @fragment\r\n    fn main(input: FragmentInputs) -> FragmentOutputs {\r\n        if (input.position.x < uniforms.ofstX || input.position.x >= uniforms.ofstX + uniforms.width) {\r\n            discard;\r\n        }\r\n        if (input.position.y < uniforms.ofstY || input.position.y >= uniforms.ofstY + uniforms.height) {\r\n            discard;\r\n        }\r\n    #ifdef INVERTY\r\n        var color: vec4f = textureLoad(img, vec2i(i32(input.position.x), i32(uniforms.ofstY + uniforms.height - (input.position.y - uniforms.ofstY))), 0);\r\n    #else\r\n        var color: vec4f = textureLoad(img, vec2i(input.position.xy), 0);\r\n    #endif\r\n    #ifdef PREMULTIPLYALPHA\r\n        color = vec4f(color.rgb * color.a, color.a);\r\n    #endif\r\n        fragmentOutputs.color = color;\r\n    }\r\n    `;\r\n\r\nconst clearVertexSource = `\r\n    const pos = array<vec2<f32>, 4>( vec2f(-1.0f, 1.0f),  vec2f(1.0f, 1.0f),  vec2f(-1.0f, -1.0f),  vec2f(1.0f, -1.0f));\r\n\r\n    @vertex\r\n    fn main(input : VertexInputs) -> FragmentInputs {\r\n        vertexOutputs.position =  vec4f(pos[input.vertexIndex], 0.0, 1.0);\r\n    }\r\n    `;\r\n\r\nconst clearFragmentSource = `\r\n    uniform color: vec4f;\r\n\r\n    @fragment\r\n    fn main(input: FragmentInputs) -> FragmentOutputs {\r\n        fragmentOutputs.color = uniforms.color;\r\n    }\r\n    `;\r\n\r\nconst copyVideoToTextureVertexSource = `\r\n    struct VertexOutput {\r\n        @builtin(position) Position : vec4<f32>,\r\n        @location(0) fragUV : vec2<f32>\r\n    }\r\n\r\n    @vertex\r\n    fn main(\r\n        @builtin(vertex_index) VertexIndex : u32\r\n    ) -> VertexOutput {\r\n        var pos = array<vec2<f32>, 4>(\r\n            vec2(-1.0,  1.0),\r\n            vec2( 1.0,  1.0),\r\n            vec2(-1.0, -1.0),\r\n            vec2( 1.0, -1.0)\r\n        );\r\n        var tex = array<vec2<f32>, 4>(\r\n            vec2(0.0, 0.0),\r\n            vec2(1.0, 0.0),\r\n            vec2(0.0, 1.0),\r\n            vec2(1.0, 1.0)\r\n        );\r\n\r\n        var output: VertexOutput;\r\n\r\n        output.Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);\r\n        output.fragUV = tex[VertexIndex];\r\n\r\n        return output;\r\n    }\r\n    `;\r\n\r\nconst copyVideoToTextureFragmentSource = `\r\n    @group(0) @binding(0) var videoSampler: sampler;\r\n    @group(0) @binding(1) var videoTexture: texture_external;\r\n\r\n    @fragment\r\n    fn main(\r\n        @location(0) fragUV: vec2<f32>\r\n    ) -> @location(0) vec4<f32> {\r\n        return textureSampleBaseClampToEdge(videoTexture, videoSampler, fragUV);\r\n    }\r\n    `;\r\n\r\nconst copyVideoToTextureInvertYFragmentSource = `\r\n    @group(0) @binding(0) var videoSampler: sampler;\r\n    @group(0) @binding(1) var videoTexture: texture_external;\r\n\r\n    @fragment\r\n    fn main(\r\n        @location(0) fragUV: vec2<f32>\r\n    ) -> @location(0) vec4<f32> {\r\n        return textureSampleBaseClampToEdge(videoTexture, videoSampler, vec2<f32>(fragUV.x, 1.0 - fragUV.y));\r\n    }\r\n    `;\r\n\r\nconst resolveDepthVertexSource = `\r\n    const pos = array<vec2<f32>, 4>( vec2f(-1.0f, 1.0f),  vec2f(1.0f, 1.0f),  vec2f(-1.0f, -1.0f),  vec2f(1.0f, -1.0f));\r\n\r\n    @vertex\r\n    fn main(input : VertexInputs) -> FragmentInputs {\r\n        vertexOutputs.position = vec4f(pos[input.vertexIndex], 0.0, 1.0);\r\n    }\r\n    `;\r\n\r\nconst resolveDepthFragmentSource = `\r\n    var msaaDepthTexture: texture_depth_multisampled_2d;\r\n\r\n    @fragment\r\n    fn main(input: FragmentInputs) -> FragmentOutputs {\r\n    #ifdef USE_MIN\r\n        let numSamples = textureNumSamples(msaaDepthTexture);\r\n        var depth = 1.0;\r\n\r\n        for (var i = 0u; i < numSamples; i = i + 1u) {\r\n            depth = min(depth, textureLoad(msaaDepthTexture, vec2u(input.position.xy), i));\r\n        }\r\n\r\n        fragmentOutputs.color = vec4f(depth);\r\n    #else\r\n        fragmentOutputs.color = vec4f(textureLoad(msaaDepthTexture, vec2u(input.position.xy), 0)); // do like WebGL, take the first sample\r\n    #endif\r\n    }\r\n    `;\r\n\r\nenum PipelineType {\r\n    MipMap = 0,\r\n    InvertYPremultiplyAlpha = 1,\r\n    Clear = 2,\r\n    InvertYPremultiplyAlphaWithOfst = 3,\r\n    ResolveDepth = 4,\r\n}\r\n\r\nenum VideoPipelineType {\r\n    DontInvertY = 0,\r\n    InvertY = 1,\r\n}\r\n\r\ninterface IPipelineParameters {\r\n    invertY?: boolean;\r\n    premultiplyAlpha?: boolean;\r\n}\r\n\r\nconst shadersForPipelineType = [\r\n    { vertex: mipmapVertexSource, fragment: mipmapFragmentSource },\r\n    { vertex: invertYPreMultiplyAlphaVertexSource, fragment: invertYPreMultiplyAlphaFragmentSource },\r\n    { vertex: clearVertexSource, fragment: clearFragmentSource },\r\n    { vertex: invertYPreMultiplyAlphaWithOfstVertexSource, fragment: invertYPreMultiplyAlphaWithOfstFragmentSource },\r\n    { vertex: resolveDepthVertexSource, fragment: resolveDepthFragmentSource },\r\n];\r\n\r\n/**\r\n * Map a (renderable) texture format (GPUTextureFormat) to an index for fast lookup (in caches for eg)\r\n * The number of entries should not go over 64! Else, the code in WebGPUCacheRenderPipeline.setMRT should be updated\r\n */\r\nexport const renderableTextureFormatToIndex: { [name: string]: number } = {\r\n    \"\": 0,\r\n    r8unorm: 1,\r\n    r8uint: 2,\r\n    r8sint: 3,\r\n\r\n    r16uint: 4,\r\n    r16sint: 5,\r\n    r16float: 6,\r\n    rg8unorm: 7,\r\n    rg8uint: 8,\r\n    rg8sint: 9,\r\n\r\n    r32uint: 10,\r\n    r32sint: 11,\r\n    r32float: 12,\r\n    rg16uint: 13,\r\n    rg16sint: 14,\r\n    rg16float: 15,\r\n    rgba8unorm: 16,\r\n    \"rgba8unorm-srgb\": 17,\r\n    rgba8uint: 18,\r\n    rgba8sint: 19,\r\n    bgra8unorm: 20,\r\n    \"bgra8unorm-srgb\": 21,\r\n\r\n    rgb10a2uint: 22,\r\n    rgb10a2unorm: 23,\r\n    /* rg11b10ufloat: this entry is dynamically added if the \"RG11B10UFloatRenderable\" extension is supported */\r\n\r\n    rg32uint: 24,\r\n    rg32sint: 25,\r\n    rg32float: 26,\r\n    rgba16uint: 27,\r\n    rgba16sint: 28,\r\n    rgba16float: 29,\r\n\r\n    rgba32uint: 30,\r\n    rgba32sint: 31,\r\n    rgba32float: 32,\r\n\r\n    stencil8: 33,\r\n    depth16unorm: 34,\r\n    depth24plus: 35,\r\n    \"depth24plus-stencil8\": 36,\r\n    depth32float: 37,\r\n\r\n    \"depth32float-stencil8\": 38,\r\n\r\n    r16unorm: 39,\r\n    rg16unorm: 40,\r\n    rgba16unorm: 41,\r\n    r16snorm: 42,\r\n    rg16snorm: 43,\r\n    rgba16snorm: 44,\r\n};\r\n\r\n/** @internal */\r\nexport class WebGPUTextureManager {\r\n    private _engine: WebGPUEngine;\r\n    private _device: GPUDevice;\r\n    private _bufferManager: WebGPUBufferManager;\r\n    private _mipmapSampler: GPUSampler;\r\n    private _videoSampler: GPUSampler;\r\n    private _ubCopyWithOfst: GPUBuffer;\r\n    private _pipelines: { [format: string]: Array<[GPURenderPipeline, GPUBindGroupLayout]> } = {};\r\n    private _compiledShaders: GPUShaderModule[][] = [];\r\n    private _videoPipelines: { [format: string]: Array<[GPURenderPipeline, GPUBindGroupLayout]> } = {};\r\n    private _videoCompiledShaders: GPUShaderModule[][] = [];\r\n    private _deferredReleaseTextures: Array<[Nullable<IHardwareTextureWrapper | GPUTexture>, Nullable<BaseTexture>]> = [];\r\n    private _commandEncoderForCreation: GPUCommandEncoder;\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                         Initialization / Helpers\r\n    //------------------------------------------------------------------------------\r\n\r\n    constructor(engine: WebGPUEngine, device: GPUDevice, bufferManager: WebGPUBufferManager, enabledExtensions: GPUFeatureName[]) {\r\n        this._engine = engine;\r\n        this._device = device;\r\n        this._bufferManager = bufferManager;\r\n\r\n        if (enabledExtensions.indexOf(WebGPUConstants.FeatureName.RG11B10UFloatRenderable) !== -1) {\r\n            const keys = Object.keys(renderableTextureFormatToIndex);\r\n            renderableTextureFormatToIndex[WebGPUConstants.TextureFormat.RG11B10UFloat] = renderableTextureFormatToIndex[keys[keys.length - 1]] + 1;\r\n        }\r\n\r\n        this._mipmapSampler = device.createSampler({ minFilter: WebGPUConstants.FilterMode.Linear });\r\n        this._videoSampler = device.createSampler({ minFilter: WebGPUConstants.FilterMode.Linear });\r\n        this._ubCopyWithOfst = this._bufferManager.createBuffer(\r\n            4 * 4,\r\n            WebGPUConstants.BufferUsage.Uniform | WebGPUConstants.BufferUsage.CopyDst,\r\n            \"UBCopyWithOffset\"\r\n        ).underlyingResource;\r\n\r\n        this._getPipeline(WebGPUConstants.TextureFormat.RGBA8Unorm);\r\n        this._getVideoPipeline(WebGPUConstants.TextureFormat.RGBA8Unorm);\r\n    }\r\n\r\n    private _getPipeline(format: GPUTextureFormat, type: PipelineType = PipelineType.MipMap, params?: IPipelineParameters): [GPURenderPipeline, GPUBindGroupLayout] {\r\n        const index =\r\n            type === PipelineType.MipMap\r\n                ? 1 << 0\r\n                : type === PipelineType.InvertYPremultiplyAlpha\r\n                  ? ((params!.invertY ? 1 : 0) << 1) + ((params!.premultiplyAlpha ? 1 : 0) << 2)\r\n                  : type === PipelineType.Clear\r\n                    ? 1 << 3\r\n                    : type === PipelineType.InvertYPremultiplyAlphaWithOfst\r\n                      ? ((params!.invertY ? 1 : 0) << 4) + ((params!.premultiplyAlpha ? 1 : 0) << 5)\r\n                      : type === PipelineType.ResolveDepth\r\n                        ? 1 << 6\r\n                        : 0;\r\n\r\n        if (!this._pipelines[format]) {\r\n            this._pipelines[format] = [];\r\n        }\r\n\r\n        let pipelineAndBGL = this._pipelines[format][index];\r\n        if (!pipelineAndBGL) {\r\n            let defines = \"\";\r\n            if (type === PipelineType.InvertYPremultiplyAlpha || type === PipelineType.InvertYPremultiplyAlphaWithOfst) {\r\n                if (params!.invertY) {\r\n                    defines += \"#define INVERTY\\n\";\r\n                }\r\n                if (params!.premultiplyAlpha) {\r\n                    defines += \"#define PREMULTIPLYALPHA\\n\";\r\n                }\r\n            }\r\n\r\n            let modules = this._compiledShaders[index];\r\n            if (!modules) {\r\n                let vertexCode = shadersForPipelineType[type].vertex;\r\n                let fragmentCode = shadersForPipelineType[type].fragment;\r\n\r\n                const processorOptions: _IProcessingOptions = {\r\n                    defines: defines.split(\"\\n\"),\r\n                    indexParameters: null,\r\n                    isFragment: false,\r\n                    shouldUseHighPrecisionShader: true,\r\n                    processor: this._engine._getShaderProcessor(ShaderLanguage.WGSL),\r\n                    supportsUniformBuffers: true,\r\n                    shadersRepository: \"\",\r\n                    includesShadersStore: {},\r\n                    version: (this._engine.version * 100).toString(),\r\n                    platformName: this._engine.shaderPlatformName,\r\n                    processingContext: this._engine._getShaderProcessingContext(ShaderLanguage.WGSL, true),\r\n                    isNDCHalfZRange: this._engine.isNDCHalfZRange,\r\n                    useReverseDepthBuffer: this._engine.useReverseDepthBuffer,\r\n                };\r\n\r\n                Initialize(processorOptions);\r\n\r\n                // Disable special additions not needed here\r\n                (processorOptions.processor as WebGPUShaderProcessorWGSL).pureMode = true;\r\n\r\n                Process(\r\n                    vertexCode,\r\n                    processorOptions,\r\n                    (migratedVertexCode) => {\r\n                        vertexCode = migratedVertexCode;\r\n                    },\r\n                    this._engine\r\n                );\r\n\r\n                processorOptions.isFragment = true;\r\n\r\n                Process(\r\n                    fragmentCode,\r\n                    processorOptions,\r\n                    (migratedFragmentCode) => {\r\n                        fragmentCode = migratedFragmentCode;\r\n                    },\r\n                    this._engine\r\n                );\r\n\r\n                const final = Finalize(vertexCode, fragmentCode, processorOptions);\r\n\r\n                // Restore\r\n                (processorOptions.processor as WebGPUShaderProcessorWGSL).pureMode = false;\r\n\r\n                const vertexModule = this._device.createShaderModule({\r\n                    label: `BabylonWebGPUDevice${this._engine.uniqueId}_InternalVertexShader_${index}`,\r\n                    code: final.vertexCode,\r\n                });\r\n                const fragmentModule = this._device.createShaderModule({\r\n                    label: `BabylonWebGPUDevice${this._engine.uniqueId}_InternalFragmentShader_${index}`,\r\n                    code: final.fragmentCode,\r\n                });\r\n                modules = this._compiledShaders[index] = [vertexModule, fragmentModule];\r\n            }\r\n\r\n            const pipeline = this._device.createRenderPipeline({\r\n                label: `BabylonWebGPUDevice${this._engine.uniqueId}_InternalPipeline_${format}_${index}`,\r\n                layout: WebGPUConstants.AutoLayoutMode.Auto,\r\n                vertex: {\r\n                    module: modules[0],\r\n                    entryPoint: \"main\",\r\n                },\r\n                fragment: {\r\n                    module: modules[1],\r\n                    entryPoint: \"main\",\r\n                    targets: [\r\n                        {\r\n                            format,\r\n                        },\r\n                    ],\r\n                },\r\n                primitive: {\r\n                    topology: WebGPUConstants.PrimitiveTopology.TriangleStrip,\r\n                    stripIndexFormat: WebGPUConstants.IndexFormat.Uint16,\r\n                },\r\n            });\r\n\r\n            pipelineAndBGL = this._pipelines[format][index] = [pipeline, pipeline.getBindGroupLayout(0)];\r\n        }\r\n\r\n        return pipelineAndBGL;\r\n    }\r\n\r\n    private _getVideoPipeline(format: GPUTextureFormat, type: VideoPipelineType = VideoPipelineType.DontInvertY): [GPURenderPipeline, GPUBindGroupLayout] {\r\n        const index = type === VideoPipelineType.InvertY ? 1 << 0 : 0;\r\n\r\n        if (!this._videoPipelines[format]) {\r\n            this._videoPipelines[format] = [];\r\n        }\r\n\r\n        let pipelineAndBGL = this._videoPipelines[format][index];\r\n        if (!pipelineAndBGL) {\r\n            let modules = this._videoCompiledShaders[index];\r\n            if (!modules) {\r\n                const vertexModule = this._device.createShaderModule({\r\n                    code: copyVideoToTextureVertexSource,\r\n                    label: `BabylonWebGPUDevice${this._engine.uniqueId}_CopyVideoToTexture_VertexShader`,\r\n                });\r\n                const fragmentModule = this._device.createShaderModule({\r\n                    code: index === 0 ? copyVideoToTextureFragmentSource : copyVideoToTextureInvertYFragmentSource,\r\n                    label: `BabylonWebGPUDevice${this._engine.uniqueId}_CopyVideoToTexture_FragmentShader_${index === 0 ? \"DontInvertY\" : \"InvertY\"}`,\r\n                });\r\n                modules = this._videoCompiledShaders[index] = [vertexModule, fragmentModule];\r\n            }\r\n\r\n            const pipeline = this._device.createRenderPipeline({\r\n                label: `BabylonWebGPUDevice${this._engine.uniqueId}_InternalVideoPipeline_${format}_${index === 0 ? \"DontInvertY\" : \"InvertY\"}`,\r\n                layout: WebGPUConstants.AutoLayoutMode.Auto,\r\n                vertex: {\r\n                    module: modules[0],\r\n                    entryPoint: \"main\",\r\n                },\r\n                fragment: {\r\n                    module: modules[1],\r\n                    entryPoint: \"main\",\r\n                    targets: [\r\n                        {\r\n                            format,\r\n                        },\r\n                    ],\r\n                },\r\n                primitive: {\r\n                    topology: WebGPUConstants.PrimitiveTopology.TriangleStrip,\r\n                    stripIndexFormat: WebGPUConstants.IndexFormat.Uint16,\r\n                },\r\n            });\r\n\r\n            pipelineAndBGL = this._videoPipelines[format][index] = [pipeline, pipeline.getBindGroupLayout(0)];\r\n        }\r\n\r\n        return pipelineAndBGL;\r\n    }\r\n\r\n    public setCommandEncoder(encoder: GPUCommandEncoder): void {\r\n        this._commandEncoderForCreation = encoder;\r\n    }\r\n\r\n    public copyVideoToTexture(video: ExternalTexture, texture: InternalTexture, format: GPUTextureFormat, invertY = false, commandEncoder?: GPUCommandEncoder): void {\r\n        const useOwnCommandEncoder = commandEncoder === undefined;\r\n        const [pipeline, bindGroupLayout] = this._getVideoPipeline(format, invertY ? VideoPipelineType.InvertY : VideoPipelineType.DontInvertY);\r\n\r\n        if (useOwnCommandEncoder) {\r\n            commandEncoder = this._device.createCommandEncoder({});\r\n        }\r\n\r\n        commandEncoder!.pushDebugGroup(`copy video to texture (invertY=${invertY})`);\r\n\r\n        const webgpuHardwareTexture = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        const renderPassDescriptor: GPURenderPassDescriptor = {\r\n            label: `BabylonWebGPUDevice${this._engine.uniqueId}_copyVideoToTexture_${format}_${invertY ? \"InvertY\" : \"DontInvertY\"}${texture.label ? \"_\" + texture.label : \"\"}`,\r\n            colorAttachments: [\r\n                {\r\n                    view: webgpuHardwareTexture.underlyingResource!.createView({\r\n                        format,\r\n                        dimension: WebGPUConstants.TextureViewDimension.E2d,\r\n                        mipLevelCount: 1,\r\n                        baseArrayLayer: 0,\r\n                        baseMipLevel: 0,\r\n                        arrayLayerCount: 1,\r\n                        aspect: WebGPUConstants.TextureAspect.All,\r\n                    }),\r\n                    loadOp: WebGPUConstants.LoadOp.Load,\r\n                    storeOp: WebGPUConstants.StoreOp.Store,\r\n                },\r\n            ],\r\n        };\r\n        const passEncoder = commandEncoder!.beginRenderPass(renderPassDescriptor);\r\n\r\n        const descriptor: GPUBindGroupDescriptor = {\r\n            layout: bindGroupLayout,\r\n            entries: [\r\n                {\r\n                    binding: 0,\r\n                    resource: this._videoSampler,\r\n                },\r\n                {\r\n                    binding: 1,\r\n                    resource: this._device.importExternalTexture({\r\n                        source: video.underlyingResource,\r\n                    }),\r\n                },\r\n            ],\r\n        };\r\n\r\n        const bindGroup = this._device.createBindGroup(descriptor);\r\n\r\n        passEncoder.setPipeline(pipeline);\r\n        passEncoder.setBindGroup(0, bindGroup);\r\n        passEncoder.draw(4, 1, 0, 0);\r\n        passEncoder.end();\r\n\r\n        commandEncoder!.popDebugGroup();\r\n\r\n        if (useOwnCommandEncoder) {\r\n            this._device.queue.submit([commandEncoder!.finish()]);\r\n            // eslint-disable-next-line no-useless-assignment\r\n            commandEncoder = null as any;\r\n        }\r\n    }\r\n\r\n    public invertYPreMultiplyAlpha(\r\n        gpuOrHdwTexture: GPUTexture | WebGPUHardwareTexture,\r\n        width: number,\r\n        height: number,\r\n        format: GPUTextureFormat,\r\n        invertY = false,\r\n        premultiplyAlpha = false,\r\n        faceIndex = 0,\r\n        mipLevel = 0,\r\n        layers = 1,\r\n        ofstX = 0,\r\n        ofstY = 0,\r\n        rectWidth = 0,\r\n        rectHeight = 0,\r\n        commandEncoder?: GPUCommandEncoder,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        allowGPUOptimization?: boolean\r\n    ): void {\r\n        const useRect = rectWidth !== 0;\r\n        const useOwnCommandEncoder = commandEncoder === undefined;\r\n        const [pipeline, bindGroupLayout] = this._getPipeline(format, useRect ? PipelineType.InvertYPremultiplyAlphaWithOfst : PipelineType.InvertYPremultiplyAlpha, {\r\n            invertY,\r\n            premultiplyAlpha,\r\n        });\r\n\r\n        faceIndex = Math.max(faceIndex, 0);\r\n\r\n        if (useOwnCommandEncoder) {\r\n            commandEncoder = this._device.createCommandEncoder({});\r\n        }\r\n\r\n        let gpuTexture: Nullable<GPUTexture>;\r\n        if (WebGPUTextureHelper.IsHardwareTexture(gpuOrHdwTexture)) {\r\n            gpuTexture = gpuOrHdwTexture.underlyingResource;\r\n            if (!(invertY && !premultiplyAlpha && layers === 1 && faceIndex === 0)) {\r\n                // we optimize only for the most likely case (invertY=true, premultiplyAlpha=false, layers=1, faceIndex=0) to avoid dealing with big caches\r\n                gpuOrHdwTexture = undefined as any;\r\n            }\r\n        } else {\r\n            gpuTexture = gpuOrHdwTexture;\r\n            gpuOrHdwTexture = undefined as any;\r\n        }\r\n        if (!gpuTexture) {\r\n            return;\r\n        }\r\n\r\n        commandEncoder!.pushDebugGroup(`internal process texture \"${gpuTexture.label}\" (invertY=${invertY} premultiplyAlpha=${premultiplyAlpha})`);\r\n\r\n        if (useRect) {\r\n            this._bufferManager.setRawData(this._ubCopyWithOfst, 0, new Float32Array([ofstX, ofstY, rectWidth, rectHeight]), 0, 4 * 4);\r\n        }\r\n\r\n        const webgpuHardwareTexture = gpuOrHdwTexture as Nullable<WebGPUHardwareTexture>;\r\n\r\n        const outputTexture =\r\n            webgpuHardwareTexture?._copyInvertYTempTexture ??\r\n            this.createTexture(\r\n                { width, height, layers: 1 },\r\n                false,\r\n                false,\r\n                false,\r\n                false,\r\n                false,\r\n                format,\r\n                1,\r\n                commandEncoder,\r\n                WebGPUConstants.TextureUsage.CopySrc | WebGPUConstants.TextureUsage.RenderAttachment | WebGPUConstants.TextureUsage.TextureBinding,\r\n                undefined,\r\n                \"TempTextureForCopyWithInvertY\"\r\n            );\r\n\r\n        const renderPassDescriptor = webgpuHardwareTexture?._copyInvertYRenderPassDescr ?? {\r\n            label: `BabylonWebGPUDevice${this._engine.uniqueId}_invertYPreMultiplyAlpha_${format}_${invertY ? \"InvertY\" : \"DontInvertY\"}_${\r\n                premultiplyAlpha ? \"PremultiplyAlpha\" : \"DontPremultiplyAlpha\"\r\n            }`,\r\n            colorAttachments: [\r\n                {\r\n                    view: outputTexture.createView({\r\n                        format,\r\n                        dimension: WebGPUConstants.TextureViewDimension.E2d,\r\n                        baseMipLevel: 0,\r\n                        mipLevelCount: 1,\r\n                        arrayLayerCount: 1,\r\n                        baseArrayLayer: 0,\r\n                    }),\r\n                    loadOp: WebGPUConstants.LoadOp.Load,\r\n                    storeOp: WebGPUConstants.StoreOp.Store,\r\n                },\r\n            ],\r\n        };\r\n        const passEncoder = commandEncoder!.beginRenderPass(renderPassDescriptor);\r\n\r\n        let bindGroup = useRect ? webgpuHardwareTexture?._copyInvertYBindGroupWithOfst : webgpuHardwareTexture?._copyInvertYBindGroup;\r\n        if (!bindGroup) {\r\n            const descriptor: GPUBindGroupDescriptor = {\r\n                layout: bindGroupLayout,\r\n                entries: [\r\n                    {\r\n                        binding: 0,\r\n                        resource: gpuTexture.createView({\r\n                            format,\r\n                            dimension: WebGPUConstants.TextureViewDimension.E2d,\r\n                            baseMipLevel: mipLevel,\r\n                            mipLevelCount: 1,\r\n                            arrayLayerCount: layers,\r\n                            baseArrayLayer: faceIndex,\r\n                        }),\r\n                    },\r\n                ],\r\n            };\r\n            if (useRect) {\r\n                descriptor.entries.push({\r\n                    binding: 1,\r\n                    resource: {\r\n                        buffer: this._ubCopyWithOfst,\r\n                    },\r\n                });\r\n            }\r\n            bindGroup = this._device.createBindGroup(descriptor);\r\n        }\r\n\r\n        passEncoder.setPipeline(pipeline);\r\n        passEncoder.setBindGroup(0, bindGroup);\r\n        passEncoder.draw(4, 1, 0, 0);\r\n        passEncoder.end();\r\n\r\n        commandEncoder!.copyTextureToTexture(\r\n            {\r\n                texture: outputTexture,\r\n            },\r\n            {\r\n                texture: gpuTexture,\r\n                mipLevel,\r\n                origin: {\r\n                    x: 0,\r\n                    y: 0,\r\n                    z: faceIndex,\r\n                },\r\n            },\r\n            {\r\n                width: rectWidth || width,\r\n                height: rectHeight || height,\r\n                depthOrArrayLayers: 1,\r\n            }\r\n        );\r\n\r\n        if (webgpuHardwareTexture) {\r\n            webgpuHardwareTexture._copyInvertYTempTexture = outputTexture;\r\n            webgpuHardwareTexture._copyInvertYRenderPassDescr = renderPassDescriptor;\r\n            if (useRect) {\r\n                webgpuHardwareTexture._copyInvertYBindGroupWithOfst = bindGroup;\r\n            } else {\r\n                webgpuHardwareTexture._copyInvertYBindGroup = bindGroup;\r\n            }\r\n        } else {\r\n            this._deferredReleaseTextures.push([outputTexture, null]);\r\n        }\r\n\r\n        commandEncoder!.popDebugGroup();\r\n\r\n        if (useOwnCommandEncoder) {\r\n            this._device.queue.submit([commandEncoder!.finish()]);\r\n            // eslint-disable-next-line no-useless-assignment\r\n            commandEncoder = null as any;\r\n        }\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                               Creation\r\n    //------------------------------------------------------------------------------\r\n\r\n    public createTexture(\r\n        imageBitmap: ImageBitmap | { width: number; height: number; layers: number },\r\n        hasMipmaps = false,\r\n        generateMipmaps = false,\r\n        invertY = false,\r\n        premultiplyAlpha = false,\r\n        is3D = false,\r\n        format: GPUTextureFormat = WebGPUConstants.TextureFormat.RGBA8Unorm,\r\n        sampleCount = 1,\r\n        commandEncoder?: GPUCommandEncoder,\r\n        usage = -1,\r\n        additionalUsages = 0,\r\n        label?: string,\r\n        mipLevelCount?: number\r\n    ): GPUTexture {\r\n        sampleCount = WebGPUTextureHelper.GetSample(sampleCount);\r\n\r\n        const layerCount = (imageBitmap as any).layers || 1;\r\n        const textureSize = {\r\n            width: imageBitmap.width,\r\n            height: imageBitmap.height,\r\n            depthOrArrayLayers: layerCount,\r\n        };\r\n\r\n        const renderAttachmentFlag = renderableTextureFormatToIndex[format] ? WebGPUConstants.TextureUsage.RenderAttachment : 0;\r\n        const isCompressedFormat = WebGPUTextureHelper.IsCompressedFormat(format);\r\n        const maxNumMipLevels = WebGPUTextureHelper.ComputeNumMipmapLevels(imageBitmap.width, imageBitmap.height);\r\n        const effectiveMipLevelCount = hasMipmaps ? Math.min(mipLevelCount ?? maxNumMipLevels, maxNumMipLevels) : 1;\r\n        const usages = usage >= 0 ? usage : WebGPUConstants.TextureUsage.CopySrc | WebGPUConstants.TextureUsage.CopyDst | WebGPUConstants.TextureUsage.TextureBinding;\r\n\r\n        additionalUsages |= hasMipmaps && !isCompressedFormat ? WebGPUConstants.TextureUsage.CopySrc | renderAttachmentFlag : 0;\r\n\r\n        if (!isCompressedFormat && !is3D) {\r\n            // we don't know in advance if the texture will be updated with copyExternalImageToTexture (which requires to have those flags), so we need to force the flags all the times\r\n            additionalUsages |= renderAttachmentFlag | WebGPUConstants.TextureUsage.CopyDst;\r\n        }\r\n\r\n        const gpuTexture = this._device.createTexture({\r\n            label: `BabylonWebGPUDevice${this._engine.uniqueId}_Texture${is3D ? \"3D\" : \"2D\"}_${label ? label + \"_\" : \"\"}${textureSize.width}x${textureSize.height}x${\r\n                textureSize.depthOrArrayLayers\r\n            }_${hasMipmaps ? \"wmips\" : \"womips\"}_${format}_samples${sampleCount}`,\r\n            size: textureSize,\r\n            dimension: is3D ? WebGPUConstants.TextureDimension.E3d : WebGPUConstants.TextureDimension.E2d,\r\n            format,\r\n            usage: usages | additionalUsages,\r\n            sampleCount,\r\n            mipLevelCount: effectiveMipLevelCount,\r\n        });\r\n\r\n        if (WebGPUTextureHelper.IsImageBitmap(imageBitmap)) {\r\n            this.updateTexture(imageBitmap, gpuTexture, imageBitmap.width, imageBitmap.height, layerCount, format, 0, 0, invertY, premultiplyAlpha, 0, 0);\r\n\r\n            if (hasMipmaps && generateMipmaps) {\r\n                this.generateMipmaps(gpuTexture, effectiveMipLevelCount, 0, commandEncoder);\r\n            }\r\n        }\r\n\r\n        return gpuTexture;\r\n    }\r\n\r\n    public createCubeTexture(\r\n        imageBitmaps: ImageBitmap[] | { width: number; height: number; layers: number },\r\n        hasMipmaps = false,\r\n        generateMipmaps = false,\r\n        invertY = false,\r\n        premultiplyAlpha = false,\r\n        format: GPUTextureFormat = WebGPUConstants.TextureFormat.RGBA8Unorm,\r\n        sampleCount = 1,\r\n        commandEncoder?: GPUCommandEncoder,\r\n        usage = -1,\r\n        additionalUsages = 0,\r\n        label?: string\r\n    ): GPUTexture {\r\n        sampleCount = WebGPUTextureHelper.GetSample(sampleCount);\r\n\r\n        const width = WebGPUTextureHelper.IsImageBitmapArray(imageBitmaps) ? imageBitmaps[0].width : imageBitmaps.width;\r\n        const height = WebGPUTextureHelper.IsImageBitmapArray(imageBitmaps) ? imageBitmaps[0].height : imageBitmaps.height;\r\n        const layerCount = WebGPUTextureHelper.IsImageBitmapArray(imageBitmaps) ? 1 : imageBitmaps.layers;\r\n\r\n        const renderAttachmentFlag = renderableTextureFormatToIndex[format] ? WebGPUConstants.TextureUsage.RenderAttachment : 0;\r\n        const isCompressedFormat = WebGPUTextureHelper.IsCompressedFormat(format);\r\n        const mipLevelCount = hasMipmaps ? WebGPUTextureHelper.ComputeNumMipmapLevels(width, height) : 1;\r\n        const usages = usage >= 0 ? usage : WebGPUConstants.TextureUsage.CopySrc | WebGPUConstants.TextureUsage.CopyDst | WebGPUConstants.TextureUsage.TextureBinding;\r\n\r\n        additionalUsages |= hasMipmaps && !isCompressedFormat ? WebGPUConstants.TextureUsage.CopySrc | renderAttachmentFlag : 0;\r\n\r\n        if (!isCompressedFormat) {\r\n            // we don't know in advance if the texture will be updated with copyExternalImageToTexture (which requires to have those flags), so we need to force the flags all the times\r\n            additionalUsages |= renderAttachmentFlag | WebGPUConstants.TextureUsage.CopyDst;\r\n        }\r\n\r\n        const gpuTexture = this._device.createTexture({\r\n            label: `BabylonWebGPUDevice${this._engine.uniqueId}_TextureCube_${label ? label + \"_\" : \"\"}${width}x${height}x${layerCount}_${\r\n                hasMipmaps ? \"wmips\" : \"womips\"\r\n            }_${format}_samples${sampleCount}`,\r\n            size: {\r\n                width,\r\n                height,\r\n                depthOrArrayLayers: 6 * layerCount,\r\n            },\r\n            dimension: WebGPUConstants.TextureDimension.E2d,\r\n            format,\r\n            usage: usages | additionalUsages,\r\n            sampleCount,\r\n            mipLevelCount,\r\n        });\r\n\r\n        if (WebGPUTextureHelper.IsImageBitmapArray(imageBitmaps)) {\r\n            this.updateCubeTextures(imageBitmaps, gpuTexture, width, height, format, invertY, premultiplyAlpha, 0, 0);\r\n\r\n            if (hasMipmaps && generateMipmaps) {\r\n                this.generateCubeMipmaps(gpuTexture, mipLevelCount, commandEncoder);\r\n            }\r\n        }\r\n\r\n        return gpuTexture;\r\n    }\r\n\r\n    public generateCubeMipmaps(gpuOrHdwTexture: GPUTexture | WebGPUHardwareTexture, mipLevelCount: number, commandEncoder?: GPUCommandEncoder): void {\r\n        const useOwnCommandEncoder = commandEncoder === undefined;\r\n        const gpuTexture = WebGPUTextureHelper.IsHardwareTexture(gpuOrHdwTexture) ? gpuOrHdwTexture.underlyingResource! : (gpuOrHdwTexture as GPUTexture);\r\n\r\n        if (useOwnCommandEncoder) {\r\n            commandEncoder = this._device.createCommandEncoder({});\r\n        }\r\n\r\n        commandEncoder!.pushDebugGroup(`create cube mipmaps for \"${gpuTexture.label}\" (${mipLevelCount} levels)`);\r\n\r\n        for (let f = 0; f < gpuTexture.depthOrArrayLayers; ++f) {\r\n            this.generateMipmaps(gpuOrHdwTexture, mipLevelCount, f, commandEncoder);\r\n        }\r\n\r\n        commandEncoder!.popDebugGroup();\r\n\r\n        if (useOwnCommandEncoder) {\r\n            this._device.queue.submit([commandEncoder!.finish()]);\r\n            // eslint-disable-next-line no-useless-assignment\r\n            commandEncoder = null as any;\r\n        }\r\n    }\r\n\r\n    public generateMipmaps(gpuOrHdwTexture: GPUTexture | WebGPUHardwareTexture, mipLevelCount: number, faceIndex = 0, commandEncoder?: GPUCommandEncoder): void {\r\n        const useOwnCommandEncoder = commandEncoder === undefined;\r\n\r\n        faceIndex = Math.max(faceIndex, 0);\r\n\r\n        if (useOwnCommandEncoder) {\r\n            commandEncoder = this._device.createCommandEncoder({});\r\n        }\r\n\r\n        let gpuTexture: Nullable<GPUTexture>;\r\n        if (WebGPUTextureHelper.IsHardwareTexture(gpuOrHdwTexture)) {\r\n            gpuTexture = gpuOrHdwTexture.underlyingResource;\r\n            gpuOrHdwTexture._mipmapGenRenderPassDescr = gpuOrHdwTexture._mipmapGenRenderPassDescr || [];\r\n            gpuOrHdwTexture._mipmapGenBindGroup = gpuOrHdwTexture._mipmapGenBindGroup || [];\r\n        } else {\r\n            gpuTexture = gpuOrHdwTexture;\r\n            gpuOrHdwTexture = undefined as any;\r\n        }\r\n        if (!gpuTexture) {\r\n            return;\r\n        }\r\n\r\n        commandEncoder!.pushDebugGroup(`create mipmaps for \"${gpuTexture.label}\" (face #${faceIndex} - ${mipLevelCount} levels)`);\r\n\r\n        const format = gpuTexture.format;\r\n        const [pipeline, bindGroupLayout] = this._getPipeline(format);\r\n\r\n        const is3D = gpuTexture.dimension === WebGPUConstants.TextureDimension.E3d;\r\n        const webgpuHardwareTexture = gpuOrHdwTexture as Nullable<WebGPUHardwareTexture>;\r\n        for (let i = 1; i < mipLevelCount; ++i) {\r\n            const renderPassDescriptor = webgpuHardwareTexture?._mipmapGenRenderPassDescr[faceIndex]?.[i - 1] ?? {\r\n                label: `BabylonWebGPUDevice${this._engine.uniqueId}_generateMipmaps_${format}_faceIndex${faceIndex}_level${i}`,\r\n                colorAttachments: [\r\n                    {\r\n                        view: gpuTexture.createView({\r\n                            format,\r\n                            dimension: is3D ? WebGPUConstants.TextureViewDimension.E3d : WebGPUConstants.TextureViewDimension.E2d,\r\n                            baseMipLevel: i,\r\n                            mipLevelCount: 1,\r\n                            arrayLayerCount: 1,\r\n                            baseArrayLayer: faceIndex,\r\n                        }),\r\n                        loadOp: WebGPUConstants.LoadOp.Load,\r\n                        storeOp: WebGPUConstants.StoreOp.Store,\r\n                    },\r\n                ],\r\n            };\r\n            if (webgpuHardwareTexture) {\r\n                webgpuHardwareTexture._mipmapGenRenderPassDescr[faceIndex] = webgpuHardwareTexture._mipmapGenRenderPassDescr[faceIndex] || [];\r\n                webgpuHardwareTexture._mipmapGenRenderPassDescr[faceIndex][i - 1] = renderPassDescriptor;\r\n            }\r\n            const passEncoder = commandEncoder!.beginRenderPass(renderPassDescriptor);\r\n\r\n            const bindGroup =\r\n                webgpuHardwareTexture?._mipmapGenBindGroup[faceIndex]?.[i - 1] ??\r\n                this._device.createBindGroup({\r\n                    layout: bindGroupLayout,\r\n                    entries: [\r\n                        {\r\n                            binding: 0,\r\n                            resource: gpuTexture.createView({\r\n                                format,\r\n                                dimension: is3D ? WebGPUConstants.TextureViewDimension.E3d : WebGPUConstants.TextureViewDimension.E2d,\r\n                                baseMipLevel: i - 1,\r\n                                mipLevelCount: 1,\r\n                                arrayLayerCount: 1,\r\n                                baseArrayLayer: faceIndex,\r\n                            }),\r\n                        },\r\n                        {\r\n                            binding: 1,\r\n                            resource: this._mipmapSampler,\r\n                        },\r\n                    ],\r\n                });\r\n            if (webgpuHardwareTexture) {\r\n                webgpuHardwareTexture._mipmapGenBindGroup[faceIndex] = webgpuHardwareTexture._mipmapGenBindGroup[faceIndex] || [];\r\n                webgpuHardwareTexture._mipmapGenBindGroup[faceIndex][i - 1] = bindGroup;\r\n            }\r\n\r\n            passEncoder.setPipeline(pipeline);\r\n            passEncoder.setBindGroup(0, bindGroup);\r\n            passEncoder.draw(4, 1, 0, 0);\r\n            passEncoder.end();\r\n        }\r\n\r\n        commandEncoder!.popDebugGroup();\r\n\r\n        if (useOwnCommandEncoder) {\r\n            this._device.queue.submit([commandEncoder!.finish()]);\r\n            // eslint-disable-next-line no-useless-assignment\r\n            commandEncoder = null as any;\r\n        }\r\n    }\r\n\r\n    public createGPUTextureForInternalTexture(texture: InternalTexture, width?: number, height?: number, depth?: number, creationFlags?: number): WebGPUHardwareTexture {\r\n        if (!texture._hardwareTexture) {\r\n            texture._hardwareTexture = new WebGPUHardwareTexture(this._engine);\r\n        }\r\n\r\n        if (width === undefined) {\r\n            width = texture.width;\r\n        }\r\n        if (height === undefined) {\r\n            height = texture.height;\r\n        }\r\n        if (depth === undefined) {\r\n            depth = texture.depth;\r\n        }\r\n\r\n        texture.width = texture.baseWidth = width;\r\n        texture.height = texture.baseHeight = height;\r\n        texture.depth = texture.baseDepth = depth;\r\n\r\n        const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n        const isStorageTexture = ((creationFlags ?? 0) & Constants.TEXTURE_CREATIONFLAG_STORAGE) !== 0;\r\n        const label = texture.label ? texture.label + \"_InternalUniqueId\" + texture.uniqueId : \"InternalUniqueId\" + texture.uniqueId;\r\n\r\n        gpuTextureWrapper.format = gpuTextureWrapper.originalFormat = WebGPUTextureHelper.GetWebGPUTextureFormat(texture.type, texture.format, texture._useSRGBBuffer);\r\n\r\n        if (texture.samples > 1) {\r\n            // In case of a MSAA texture, the current texture will be the \"resolve\" texture, which cannot have a depth format\r\n            switch (gpuTextureWrapper.format) {\r\n                case WebGPUConstants.TextureFormat.Depth16Unorm:\r\n                    gpuTextureWrapper.format = WebGPUConstants.TextureFormat.R16Unorm;\r\n                    break;\r\n                case WebGPUConstants.TextureFormat.Depth24Plus:\r\n                case WebGPUConstants.TextureFormat.Depth24PlusStencil8:\r\n                case WebGPUConstants.TextureFormat.Depth32Float:\r\n                case WebGPUConstants.TextureFormat.Depth32FloatStencil8:\r\n                    gpuTextureWrapper.format = WebGPUConstants.TextureFormat.R32Float;\r\n                    break;\r\n            }\r\n        }\r\n\r\n        gpuTextureWrapper.textureUsages =\r\n            texture._source === InternalTextureSource.RenderTarget || texture.source === InternalTextureSource.MultiRenderTarget\r\n                ? WebGPUConstants.TextureUsage.TextureBinding | WebGPUConstants.TextureUsage.CopySrc | WebGPUConstants.TextureUsage.RenderAttachment\r\n                : texture._source === InternalTextureSource.DepthStencil\r\n                  ? WebGPUConstants.TextureUsage.TextureBinding | WebGPUConstants.TextureUsage.RenderAttachment\r\n                  : -1;\r\n\r\n        gpuTextureWrapper.textureAdditionalUsages = isStorageTexture ? WebGPUConstants.TextureUsage.StorageBinding : 0;\r\n\r\n        const hasMipMaps = texture.generateMipMaps;\r\n        const layerCount = depth || 1;\r\n        let mipmapCount;\r\n        if (texture._maxLodLevel !== null) {\r\n            mipmapCount = texture._maxLodLevel;\r\n        } else {\r\n            mipmapCount = hasMipMaps ? WebGPUTextureHelper.ComputeNumMipmapLevels(width, height) : 1;\r\n        }\r\n        if (texture.isCube) {\r\n            const gpuTexture = this.createCubeTexture(\r\n                { width, height, layers: layerCount },\r\n                texture.generateMipMaps,\r\n                texture.generateMipMaps,\r\n                texture.invertY,\r\n                false,\r\n                gpuTextureWrapper.format,\r\n                1,\r\n                this._commandEncoderForCreation,\r\n                gpuTextureWrapper.textureUsages,\r\n                gpuTextureWrapper.textureAdditionalUsages,\r\n                label\r\n            );\r\n\r\n            gpuTextureWrapper.set(gpuTexture);\r\n\r\n            const format = WebGPUTextureHelper.GetDepthFormatOnly(gpuTextureWrapper.format);\r\n            const aspect = WebGPUTextureHelper.HasDepthAndStencilAspects(gpuTextureWrapper.format) ? WebGPUConstants.TextureAspect.DepthOnly : WebGPUConstants.TextureAspect.All;\r\n            const dimension = texture.is2DArray ? WebGPUConstants.TextureViewDimension.CubeArray : WebGPUConstants.TextureViewDimension.Cube;\r\n\r\n            gpuTextureWrapper.createView(\r\n                {\r\n                    label: `BabylonWebGPUDevice${this._engine.uniqueId}_TextureViewCube${texture.is2DArray ? \"_Array\" + layerCount : \"\"}_${width}x${height}_${\r\n                        hasMipMaps ? \"wmips\" : \"womips\"\r\n                    }_${format}_${dimension}_${aspect}_${label}`,\r\n                    format,\r\n                    dimension,\r\n                    mipLevelCount: mipmapCount,\r\n                    baseArrayLayer: 0,\r\n                    baseMipLevel: 0,\r\n                    arrayLayerCount: 6 * layerCount,\r\n                    aspect,\r\n                },\r\n                isStorageTexture\r\n            );\r\n        } else {\r\n            const gpuTexture = this.createTexture(\r\n                { width, height, layers: layerCount },\r\n                hasMipMaps,\r\n                texture.generateMipMaps,\r\n                texture.invertY,\r\n                false,\r\n                texture.is3D,\r\n                gpuTextureWrapper.format,\r\n                1,\r\n                this._commandEncoderForCreation,\r\n                gpuTextureWrapper.textureUsages,\r\n                gpuTextureWrapper.textureAdditionalUsages,\r\n                label\r\n            );\r\n\r\n            gpuTextureWrapper.set(gpuTexture);\r\n\r\n            const arrayLayerCount = texture.is3D ? 1 : layerCount;\r\n            const format = WebGPUTextureHelper.GetDepthFormatOnly(gpuTextureWrapper.format);\r\n            const aspect = WebGPUTextureHelper.HasDepthAndStencilAspects(gpuTextureWrapper.format) ? WebGPUConstants.TextureAspect.DepthOnly : WebGPUConstants.TextureAspect.All;\r\n            const dimension = texture.is2DArray\r\n                ? WebGPUConstants.TextureViewDimension.E2dArray\r\n                : texture.is3D\r\n                  ? WebGPUConstants.TextureDimension.E3d\r\n                  : WebGPUConstants.TextureViewDimension.E2d;\r\n\r\n            gpuTextureWrapper.createView(\r\n                {\r\n                    label: `BabylonWebGPUDevice${this._engine.uniqueId}_TextureView${texture.is3D ? \"3D\" : \"2D\"}${\r\n                        texture.is2DArray ? \"_Array\" + arrayLayerCount : \"\"\r\n                    }_${width}x${height}${texture.is3D ? \"x\" + layerCount : \"\"}_${hasMipMaps ? \"wmips\" : \"womips\"}_${format}_${dimension}_${aspect}_${label}`,\r\n                    format,\r\n                    dimension,\r\n                    mipLevelCount: mipmapCount,\r\n                    baseArrayLayer: 0,\r\n                    baseMipLevel: 0,\r\n                    arrayLayerCount,\r\n                    aspect,\r\n                },\r\n                isStorageTexture\r\n            );\r\n        }\r\n\r\n        return gpuTextureWrapper;\r\n    }\r\n\r\n    public createMSAATexture(gpuTexture: GPUTexture, format: GPUTextureFormat, samples: number) {\r\n        return this.createTexture(\r\n            { width: gpuTexture.width, height: gpuTexture.height, layers: 1 },\r\n            false,\r\n            false,\r\n            false,\r\n            false,\r\n            false,\r\n            format,\r\n            samples,\r\n            this._commandEncoderForCreation,\r\n            WebGPUConstants.TextureUsage.RenderAttachment | WebGPUConstants.TextureUsage.TextureBinding,\r\n            0,\r\n            gpuTexture.label ? gpuTexture.label + \" (MSAA)\" : \"MSAA\"\r\n        );\r\n    }\r\n\r\n    public resolveMSAADepthTexture(msaaTexture: GPUTexture, outputTexture: GPUTexture, commandEncoder?: GPUCommandEncoder): void {\r\n        const format = outputTexture.format;\r\n\r\n        const useOwnCommandEncoder = commandEncoder === undefined;\r\n        const [pipeline, bindGroupLayout] = this._getPipeline(format, PipelineType.ResolveDepth);\r\n\r\n        if (useOwnCommandEncoder) {\r\n            commandEncoder = this._device.createCommandEncoder({});\r\n        }\r\n\r\n        commandEncoder!.pushDebugGroup(`resolve MSAA Depth texture \"${msaaTexture.label}\" to \"${outputTexture.label}\"`);\r\n\r\n        const renderPassDescriptor: GPURenderPassDescriptor = {\r\n            label: `BabylonWebGPUDevice${this._engine.uniqueId}_resolveMSAADepthTexture${msaaTexture.label ? \"_\" + msaaTexture.label : \"\"}`,\r\n            colorAttachments: [\r\n                {\r\n                    // Note: the WebGPU spec allows passing a GPUTexture directly as the view, but Safari rejects it (non-compliant).\r\n                    // We explicitly create a GPUTextureView to work around this Safari bug.\r\n                    view: outputTexture.createView({\r\n                        format,\r\n                        dimension: WebGPUConstants.TextureViewDimension.E2d,\r\n                        baseMipLevel: 0,\r\n                        mipLevelCount: 1,\r\n                        arrayLayerCount: 1,\r\n                        baseArrayLayer: 0,\r\n                    }),\r\n                    loadOp: WebGPUConstants.LoadOp.Load,\r\n                    storeOp: WebGPUConstants.StoreOp.Store,\r\n                },\r\n            ],\r\n        };\r\n        const passEncoder = commandEncoder!.beginRenderPass(renderPassDescriptor);\r\n\r\n        const descriptor: GPUBindGroupDescriptor = {\r\n            layout: bindGroupLayout,\r\n            entries: [\r\n                {\r\n                    binding: 0,\r\n                    resource: msaaTexture.createView({\r\n                        format: WebGPUTextureHelper.GetDepthFormatOnly(msaaTexture.format),\r\n                        dimension: WebGPUConstants.TextureViewDimension.E2d,\r\n                        mipLevelCount: 1,\r\n                        baseArrayLayer: 0,\r\n                        baseMipLevel: 0,\r\n                        arrayLayerCount: 1,\r\n                        aspect: WebGPUConstants.TextureAspect.DepthOnly,\r\n                    }),\r\n                },\r\n            ],\r\n        };\r\n\r\n        const bindGroup = this._device.createBindGroup(descriptor);\r\n\r\n        passEncoder.setPipeline(pipeline);\r\n        passEncoder.setBindGroup(0, bindGroup);\r\n        passEncoder.draw(4, 1, 0, 0);\r\n        passEncoder.end();\r\n\r\n        commandEncoder!.popDebugGroup();\r\n\r\n        if (useOwnCommandEncoder) {\r\n            this._device.queue.submit([commandEncoder!.finish()]);\r\n            // eslint-disable-next-line no-useless-assignment\r\n            commandEncoder = null as any;\r\n        }\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                                  Update\r\n    //------------------------------------------------------------------------------\r\n\r\n    public updateCubeTextures(\r\n        imageBitmaps: ImageBitmap[] | Uint8Array[],\r\n        texture: GPUTexture | InternalTexture,\r\n        width: number,\r\n        height: number,\r\n        format: GPUTextureFormat,\r\n        invertY = false,\r\n        premultiplyAlpha = false,\r\n        offsetX = 0,\r\n        offsetY = 0\r\n    ): void {\r\n        const faces = [0, 3, 1, 4, 2, 5];\r\n\r\n        for (let f = 0; f < faces.length; ++f) {\r\n            const imageBitmap = imageBitmaps[faces[f]];\r\n\r\n            // Prefer InternalTexture when available: updateTexture needs it to run invertY/premultiplyAlpha\r\n            // GPU post-processing on raw (Uint8Array) uploads. Passing only a GPUTexture throws in that path.\r\n            this.updateTexture(imageBitmap, texture, width, height, 1, format, f, 0, invertY, premultiplyAlpha, offsetX, offsetY);\r\n        }\r\n    }\r\n    // TODO WEBGPU handle data source not being in the same format than the destination texture?\r\n    public updateTexture(\r\n        imageBitmap: ImageBitmap | Uint8Array | ImageData | HTMLImageElement | HTMLVideoElement | VideoFrame | HTMLCanvasElement | OffscreenCanvas,\r\n        texture: GPUTexture | InternalTexture,\r\n        width: number,\r\n        height: number,\r\n        layers: number,\r\n        format: GPUTextureFormat,\r\n        faceIndex: number = 0,\r\n        mipLevel: number = 0,\r\n        invertY = false,\r\n        premultiplyAlpha = false,\r\n        offsetX = 0,\r\n        offsetY = 0,\r\n        allowGPUOptimization?: boolean\r\n    ): void {\r\n        const gpuTexture = WebGPUTextureHelper.IsInternalTexture(texture) ? (texture._hardwareTexture as WebGPUHardwareTexture).underlyingResource! : texture;\r\n        const blockInformation = WebGPUTextureHelper.GetBlockInformationFromFormat(format);\r\n        const gpuOrHdwTexture = WebGPUTextureHelper.IsInternalTexture(texture) ? (texture._hardwareTexture as WebGPUHardwareTexture) : texture;\r\n\r\n        const textureCopyView: GPUCopyExternalImageDestInfo = {\r\n            texture: gpuTexture,\r\n            origin: {\r\n                x: offsetX,\r\n                y: offsetY,\r\n                z: Math.max(faceIndex, 0),\r\n            },\r\n            mipLevel: mipLevel,\r\n            premultipliedAlpha: premultiplyAlpha,\r\n        };\r\n\r\n        const textureExtent = {\r\n            width: Math.ceil(width / blockInformation.width) * blockInformation.width,\r\n            height: Math.ceil(height / blockInformation.height) * blockInformation.height,\r\n            depthOrArrayLayers: layers || 1,\r\n        };\r\n\r\n        if ((imageBitmap as Uint8Array).byteLength !== undefined) {\r\n            imageBitmap = imageBitmap as Uint8Array;\r\n\r\n            const bytesPerRow = Math.ceil(width / blockInformation.width) * blockInformation.length;\r\n            const aligned = Math.ceil(bytesPerRow / 256) * 256 === bytesPerRow;\r\n\r\n            if (aligned) {\r\n                const commandEncoder = this._device.createCommandEncoder({});\r\n\r\n                const buffer = this._bufferManager.createRawBuffer(\r\n                    imageBitmap.byteLength,\r\n                    WebGPUConstants.BufferUsage.MapWrite | WebGPUConstants.BufferUsage.CopySrc,\r\n                    true,\r\n                    \"TempBufferForUpdateTexture\" + (gpuTexture ? \"_\" + gpuTexture.label : \"\")\r\n                );\r\n\r\n                const arrayBuffer = buffer.getMappedRange();\r\n\r\n                new Uint8Array(arrayBuffer).set(imageBitmap);\r\n\r\n                buffer.unmap();\r\n\r\n                commandEncoder.copyBufferToTexture(\r\n                    {\r\n                        buffer: buffer,\r\n                        offset: 0,\r\n                        bytesPerRow,\r\n                        rowsPerImage: textureExtent.height / blockInformation.height,\r\n                    },\r\n                    textureCopyView,\r\n                    textureExtent\r\n                );\r\n\r\n                this._device.queue.submit([commandEncoder.finish()]);\r\n\r\n                this._bufferManager.releaseBuffer(buffer);\r\n            } else {\r\n                this._device.queue.writeTexture(\r\n                    textureCopyView,\r\n                    imageBitmap,\r\n                    {\r\n                        offset: 0,\r\n                        bytesPerRow,\r\n                        rowsPerImage: textureExtent.height / blockInformation.height,\r\n                    },\r\n                    textureExtent\r\n                );\r\n            }\r\n\r\n            if (invertY || premultiplyAlpha) {\r\n                if (WebGPUTextureHelper.IsInternalTexture(texture)) {\r\n                    const dontUseRect = offsetX === 0 && offsetY === 0 && width === texture.width && height === texture.height;\r\n                    this.invertYPreMultiplyAlpha(\r\n                        gpuOrHdwTexture,\r\n                        texture.width,\r\n                        texture.height,\r\n                        format,\r\n                        invertY,\r\n                        premultiplyAlpha,\r\n                        faceIndex,\r\n                        mipLevel,\r\n                        layers || 1,\r\n                        offsetX,\r\n                        offsetY,\r\n                        dontUseRect ? 0 : width,\r\n                        dontUseRect ? 0 : height,\r\n                        undefined,\r\n                        allowGPUOptimization\r\n                    );\r\n                } else {\r\n                    // we should never take this code path\r\n                    // eslint-disable-next-line no-throw-literal\r\n                    throw \"updateTexture: Can't process the texture data because a GPUTexture was provided instead of an InternalTexture!\";\r\n                }\r\n            }\r\n        } else {\r\n            imageBitmap = imageBitmap as ImageBitmap | ImageData | HTMLImageElement | HTMLVideoElement | VideoFrame | HTMLCanvasElement | OffscreenCanvas;\r\n            this._device.queue.copyExternalImageToTexture({ source: imageBitmap, flipY: invertY }, textureCopyView, textureExtent);\r\n        }\r\n    }\r\n\r\n    public updateMipLevelCountForInternalTexture(texture: InternalTexture, mipLevelCount?: number) {\r\n        const maxNumMipLevels = WebGPUTextureHelper.ComputeNumMipmapLevels(texture.width, texture.height);\r\n        if (mipLevelCount !== undefined) {\r\n            texture.mipLevelCount = Math.min(Math.max(1, mipLevelCount), maxNumMipLevels);\r\n        } else if (texture.generateMipMaps) {\r\n            texture.mipLevelCount = maxNumMipLevels;\r\n        } else {\r\n            texture.mipLevelCount = 1;\r\n        }\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public readPixels(\r\n        texture: GPUTexture,\r\n        x: number,\r\n        y: number,\r\n        width: number,\r\n        height: number,\r\n        format: GPUTextureFormat,\r\n        faceIndex: number = 0,\r\n        mipLevel: number = 0,\r\n        buffer: Nullable<ArrayBufferView> = null,\r\n        noDataConversion = false\r\n    ): Promise<ArrayBufferView> {\r\n        const blockInformation = WebGPUTextureHelper.GetBlockInformationFromFormat(format);\r\n\r\n        const bytesPerRow = Math.ceil(width / blockInformation.width) * blockInformation.length;\r\n\r\n        const bytesPerRowAligned = Math.ceil(bytesPerRow / 256) * 256;\r\n\r\n        const size = bytesPerRowAligned * height;\r\n\r\n        const gpuBuffer = this._bufferManager.createRawBuffer(\r\n            size,\r\n            WebGPUConstants.BufferUsage.MapRead | WebGPUConstants.BufferUsage.CopyDst,\r\n            undefined,\r\n            \"TempBufferForReadPixels\" + (texture.label ? \"_\" + texture.label : \"\")\r\n        );\r\n\r\n        const commandEncoder = this._device.createCommandEncoder({});\r\n\r\n        commandEncoder.copyTextureToBuffer(\r\n            {\r\n                texture,\r\n                mipLevel,\r\n                origin: {\r\n                    x,\r\n                    y,\r\n                    z: Math.max(faceIndex, 0),\r\n                },\r\n            },\r\n            {\r\n                buffer: gpuBuffer,\r\n                offset: 0,\r\n                bytesPerRow: bytesPerRowAligned,\r\n            },\r\n            {\r\n                width,\r\n                height,\r\n                depthOrArrayLayers: 1,\r\n            }\r\n        );\r\n\r\n        this._device.queue.submit([commandEncoder.finish()]);\r\n\r\n        return this._bufferManager.readDataFromBuffer(\r\n            gpuBuffer,\r\n            size,\r\n            width,\r\n            height,\r\n            bytesPerRow,\r\n            bytesPerRowAligned,\r\n            WebGPUTextureHelper.GetTextureTypeFromFormat(format),\r\n            0,\r\n            buffer,\r\n            true,\r\n            noDataConversion\r\n        );\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Dispose\r\n    //------------------------------------------------------------------------------\r\n\r\n    public releaseTexture(texture: InternalTexture | GPUTexture): void {\r\n        if (WebGPUTextureHelper.IsInternalTexture(texture)) {\r\n            const hardwareTexture = texture._hardwareTexture;\r\n            const irradianceTexture = texture._irradianceTexture;\r\n\r\n            // We can't destroy the objects just now because they could be used in the current frame - we delay the destroying after the end of the frame\r\n            this._deferredReleaseTextures.push([hardwareTexture, irradianceTexture]);\r\n        } else {\r\n            this._deferredReleaseTextures.push([texture, null]);\r\n        }\r\n    }\r\n\r\n    public destroyDeferredTextures(): void {\r\n        for (let i = 0; i < this._deferredReleaseTextures.length; ++i) {\r\n            const [hardwareTexture, irradianceTexture] = this._deferredReleaseTextures[i];\r\n\r\n            if (hardwareTexture) {\r\n                if (WebGPUTextureHelper.IsHardwareTexture(hardwareTexture)) {\r\n                    hardwareTexture.release();\r\n                } else {\r\n                    hardwareTexture.destroy();\r\n                }\r\n            }\r\n            irradianceTexture?.dispose();\r\n        }\r\n\r\n        this._deferredReleaseTextures.length = 0;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { Constants } from \"../constants\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { type Effect } from \"../../Materials/effect\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebGPUHardwareTexture } from \"./webgpuHardwareTexture\";\r\nimport { type WebGPUPipelineContext } from \"./webgpuPipelineContext\";\r\nimport { WebGPUTextureHelper } from \"./webgpuTextureHelper\";\r\nimport { renderableTextureFormatToIndex } from \"./webgpuTextureManager\";\r\nimport { checkNonFloatVertexBuffers } from \"core/Buffers/buffer.nonFloatVertexBuffers\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nenum StatePosition {\r\n    StencilReadMask = 0,\r\n    StencilWriteMask = 1,\r\n    //DepthBiasClamp = 1, // not used, so remove it to improve perf\r\n    DepthBias = 2,\r\n    DepthBiasSlopeScale = 3,\r\n    DepthStencilState = 4,\r\n    MRTAttachments = 5,\r\n    RasterizationState = 6,\r\n    ColorStates1 = 7,\r\n    ColorStates2 = 8,\r\n    ColorStates3 = 9,\r\n    ColorStates4 = 10,\r\n    ShaderStage = 11,\r\n    TextureStage = 12,\r\n    VertexState = 13, // vertex state will consume positions 13, 14, ... depending on the number of vertex inputs\r\n\r\n    NumStates = 14,\r\n}\r\n\r\nconst alphaBlendFactorToIndex: { [name: number]: number } = {\r\n    0: 1, // Zero\r\n    1: 2, // One\r\n    0x0300: 3, // SrcColor\r\n    0x0301: 4, // OneMinusSrcColor\r\n    0x0302: 5, // SrcAlpha\r\n    0x0303: 6, // OneMinusSrcAlpha\r\n    0x0304: 7, // DstAlpha\r\n    0x0305: 8, // OneMinusDstAlpha\r\n    0x0306: 9, // DstColor\r\n    0x0307: 10, // OneMinusDstColor\r\n    0x0308: 11, // SrcAlphaSaturated\r\n    0x8001: 12, // BlendColor\r\n    0x8002: 13, // OneMinusBlendColor\r\n    0x8003: 14, // BlendColor (alpha)\r\n    0x8004: 15, // OneMinusBlendColor (alpha)\r\n    0x88f9: 16, // Src1Color\r\n    0x88fa: 17, // OneMinusSrc1Color\r\n    0x8589: 18, // Src1Alpha\r\n    0x88fb: 19, // OneMinusSrc1Alpha\r\n};\r\n\r\nconst alphaBlendEquationToIndex: { [name: number]: number } = {\r\n    0x8006: 0, // Add\r\n    0x8007: 1, // Min\r\n    0x8008: 2, // Max\r\n    0x800a: 3, // Subtract\r\n    0x800b: 4, // ReverseSubtract\r\n};\r\n\r\nconst stencilOpToIndex: { [name: number]: number } = {\r\n    0x0000: 0, // ZERO\r\n    0x1e00: 1, // KEEP\r\n    0x1e01: 2, // REPLACE\r\n    0x1e02: 3, // INCR\r\n    0x1e03: 4, // DECR\r\n    0x150a: 5, // INVERT\r\n    0x8507: 6, // INCR_WRAP\r\n    0x8508: 7, // DECR_WRAP\r\n};\r\n\r\nconst colorStates = [0, 0, 0, 0];\r\n// VertexBuffer.hashCode uses at most bit 23 for WebGPU's maximum 2048-byte stride.\r\nconst vertexBufferLayoutContinuation = 1 << 26;\r\n\r\n/** @internal */\r\nexport abstract class WebGPUCacheRenderPipeline {\r\n    public static LogErrorIfNoVertexBuffer = false;\r\n\r\n    public static NumCacheHitWithoutHash = 0;\r\n    public static NumCacheHitWithHash = 0;\r\n    public static NumCacheMiss = 0;\r\n    public static NumPipelineCreationLastFrame = 0;\r\n\r\n    public disabled: boolean;\r\n\r\n    private static _NumPipelineCreationCurrentFrame = 0;\r\n\r\n    protected _states: number[];\r\n    protected _statesLength: number;\r\n    protected _stateDirtyLowestIndex: number;\r\n    public lastStateDirtyLowestIndex: number; // for stats only\r\n\r\n    private _device: GPUDevice;\r\n    private _isDirty: boolean;\r\n    private _emptyVertexBuffer: VertexBuffer;\r\n    private _parameter: { token: any; pipeline: Nullable<GPURenderPipeline> };\r\n    private _kMaxVertexBufferStride;\r\n\r\n    private _shaderId: number;\r\n    private _alphaToCoverageEnabled: boolean;\r\n    private _frontFace: number;\r\n    private _cullEnabled: boolean;\r\n    private _cullFace: number;\r\n    private _clampDepth: boolean;\r\n    private _rasterizationState: number;\r\n    private _depthBias: number;\r\n    private _depthBiasClamp: number = 0;\r\n    private _depthBiasSlopeScale: number;\r\n    private _colorFormat: number;\r\n    private _webgpuColorFormat: (GPUTextureFormat | null)[];\r\n    private _mrtAttachments: number;\r\n    private _mrtFormats: (GPUTextureFormat | null)[];\r\n    private _mrtEnabledMask: number;\r\n    private _alphaBlendEnabled: boolean[];\r\n    private _numAlphaBlendTargetsEnabled: number;\r\n    private _alphaBlendFuncParams: Array<Nullable<number>>;\r\n    private _alphaBlendEqParams: Array<Nullable<number>>;\r\n    private _writeMask: number;\r\n    private _depthStencilFormat: number;\r\n    private _webgpuDepthStencilFormat: GPUTextureFormat | undefined;\r\n    private _depthTestEnabled: boolean;\r\n    private _depthWriteEnabled: boolean;\r\n    private _depthCompare: number;\r\n    private _stencilEnabled: boolean;\r\n    private _stencilFrontCompare: number;\r\n    private _stencilFrontDepthFailOp: number;\r\n    private _stencilFrontPassOp: number;\r\n    private _stencilFrontFailOp: number;\r\n    private _stencilBackCompare: number;\r\n    private _stencilBackDepthFailOp: number;\r\n    private _stencilBackPassOp: number;\r\n    private _stencilBackFailOp: number;\r\n    private _stencilReadMask: number;\r\n    private _stencilWriteMask: number;\r\n    private _depthStencilState: number;\r\n    private _vertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }>;\r\n    private _overrideVertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }>;\r\n    private _textureState: number;\r\n    private _useTextureStage: boolean;\r\n\r\n    constructor(device: GPUDevice, emptyVertexBuffer: VertexBuffer) {\r\n        this._device = device;\r\n        this._useTextureStage = true; // we force usage because we must handle depth textures with \"float\" filtering, which can't be fixed by a caps (like \"textureFloatLinearFiltering\" can for float textures)\r\n        // Each attribute can add a format state and a non-zero descriptor offset state.\r\n        this._states = new Array(StatePosition.VertexState + 2 * (device.limits.maxVertexAttributes || 16));\r\n        this._statesLength = 0;\r\n        this._stateDirtyLowestIndex = 0;\r\n        this._emptyVertexBuffer = emptyVertexBuffer;\r\n        this._mrtFormats = [];\r\n        this._parameter = { token: undefined, pipeline: null };\r\n        this.disabled = false;\r\n        this.vertexBuffers = [];\r\n        this._kMaxVertexBufferStride = device.limits.maxVertexBufferArrayStride || 2048;\r\n        this.reset();\r\n    }\r\n\r\n    public reset(): void {\r\n        this._isDirty = true;\r\n        this.vertexBuffers.length = 0;\r\n        this.setAlphaToCoverage(false);\r\n        this.resetDepthCullingState();\r\n        this.setClampDepth(false);\r\n        this.setDepthBias(0);\r\n        //this.setDepthBiasClamp(0);\r\n        this._webgpuColorFormat = [WebGPUConstants.TextureFormat.BGRA8Unorm];\r\n        this.setColorFormat(WebGPUConstants.TextureFormat.BGRA8Unorm);\r\n        this.setMRT([]);\r\n        this.setAlphaBlendEnabled([false], 1);\r\n        this.setAlphaBlendFactors([null, null, null, null], [null, null]);\r\n        this.setWriteMask(0xf);\r\n        this.setDepthStencilFormat(WebGPUConstants.TextureFormat.Depth24PlusStencil8);\r\n        this.setStencilEnabled(false);\r\n        this.resetStencilState();\r\n        this.setBuffers(null, null, null);\r\n        this._setTextureState(0);\r\n    }\r\n\r\n    protected abstract _getRenderPipeline(param: { token: any; pipeline: Nullable<GPURenderPipeline> }): void;\r\n    protected abstract _setRenderPipeline(param: { token: any; pipeline: Nullable<GPURenderPipeline> }): void;\r\n\r\n    public readonly vertexBuffers: VertexBuffer[];\r\n    public readonly indexBuffer: Nullable<DataBuffer>;\r\n\r\n    public get colorFormats(): (GPUTextureFormat | null)[] {\r\n        return this._mrtAttachments > 0 ? this._mrtFormats : this._webgpuColorFormat;\r\n    }\r\n\r\n    public readonly mrtAttachments: number[];\r\n    public readonly mrtTextureArray: InternalTexture[];\r\n    public readonly mrtTextureCount: number = 0;\r\n\r\n    /**\r\n     * Performs the cache state setup and lookup for a render pipeline.\r\n     * @param fillMode defines the fill mode used to configure the rasterization state\r\n     * @param effect defines the effect containing the shader and vertex input layout\r\n     * @param sampleCount defines the number of samples to use for MSAA\r\n     * @param textureState defines the encoded texture state used for the pipeline cache key\r\n     * @returns the cached pipeline on hit, or null on miss (with cache state ready for creation)\r\n     */\r\n    private _lookupRenderPipeline(fillMode: number, effect: Effect, sampleCount: number, textureState: number): Nullable<GPURenderPipeline> {\r\n        this._setShaderStage(effect.uniqueId);\r\n        this._setRasterizationState(fillMode, sampleCount);\r\n        this._setColorStates();\r\n        this._setDepthStencilState();\r\n        this._setVertexState(effect);\r\n        this._setTextureState(textureState);\r\n\r\n        this.lastStateDirtyLowestIndex = this._stateDirtyLowestIndex;\r\n\r\n        if (!this._isDirty && this._parameter.pipeline) {\r\n            this._stateDirtyLowestIndex = this._statesLength;\r\n            WebGPUCacheRenderPipeline.NumCacheHitWithoutHash++;\r\n            return this._parameter.pipeline;\r\n        }\r\n\r\n        this._getRenderPipeline(this._parameter);\r\n\r\n        this._isDirty = false;\r\n        this._stateDirtyLowestIndex = this._statesLength;\r\n\r\n        if (this._parameter.pipeline) {\r\n            WebGPUCacheRenderPipeline.NumCacheHitWithHash++;\r\n            return this._parameter.pipeline;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    public getRenderPipeline(fillMode: number, effect: Effect, sampleCount: number, textureState = 0): GPURenderPipeline {\r\n        sampleCount = WebGPUTextureHelper.GetSample(sampleCount);\r\n\r\n        if (this.disabled) {\r\n            const topology = WebGPUCacheRenderPipeline._GetTopology(fillMode);\r\n\r\n            this._setVertexState(effect); // to fill this.vertexBuffers with correct data\r\n            this._setTextureState(textureState);\r\n\r\n            this._parameter.pipeline = this._createRenderPipeline(effect, topology, sampleCount);\r\n\r\n            WebGPUCacheRenderPipeline.NumCacheMiss++;\r\n            WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame++;\r\n\r\n            return this._parameter.pipeline;\r\n        }\r\n\r\n        const cached = this._lookupRenderPipeline(fillMode, effect, sampleCount, textureState);\r\n        if (cached) {\r\n            return cached;\r\n        }\r\n\r\n        const topology = WebGPUCacheRenderPipeline._GetTopology(fillMode);\r\n\r\n        this._parameter.pipeline = this._createRenderPipeline(effect, topology, sampleCount);\r\n        this._setRenderPipeline(this._parameter);\r\n\r\n        WebGPUCacheRenderPipeline.NumCacheMiss++;\r\n        WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame++;\r\n\r\n        return this._parameter.pipeline;\r\n    }\r\n\r\n    public endFrame(): void {\r\n        WebGPUCacheRenderPipeline.NumPipelineCreationLastFrame = WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame;\r\n        WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame = 0;\r\n    }\r\n\r\n    public setAlphaToCoverage(enabled: boolean): void {\r\n        this._alphaToCoverageEnabled = enabled;\r\n    }\r\n\r\n    public setFrontFace(frontFace: number): void {\r\n        this._frontFace = frontFace;\r\n    }\r\n\r\n    public setCullEnabled(enabled: boolean): void {\r\n        this._cullEnabled = enabled;\r\n    }\r\n\r\n    public setCullFace(cullFace: number): void {\r\n        this._cullFace = cullFace;\r\n    }\r\n\r\n    public setClampDepth(clampDepth: boolean): void {\r\n        this._clampDepth = clampDepth;\r\n    }\r\n\r\n    public resetDepthCullingState(): void {\r\n        this.setDepthCullingState(false, 2, 1, 0, 0, true, true, Constants.ALWAYS);\r\n    }\r\n\r\n    public setDepthCullingState(\r\n        cullEnabled: boolean,\r\n        frontFace: number,\r\n        cullFace: number,\r\n        zOffset: number,\r\n        zOffsetUnits: number,\r\n        depthTestEnabled: boolean,\r\n        depthWriteEnabled: boolean,\r\n        depthCompare: Nullable<number>\r\n    ): void {\r\n        this._depthWriteEnabled = depthWriteEnabled;\r\n        this._depthTestEnabled = depthTestEnabled;\r\n        this._depthCompare = (depthCompare ?? Constants.ALWAYS) - 0x0200;\r\n        this._cullFace = cullFace;\r\n        this._cullEnabled = cullEnabled;\r\n        this._frontFace = frontFace;\r\n        this.setDepthBiasSlopeScale(zOffset);\r\n        this.setDepthBias(zOffsetUnits);\r\n    }\r\n\r\n    public setDepthBias(depthBias: number): void {\r\n        if (this._depthBias !== depthBias) {\r\n            this._depthBias = depthBias;\r\n            this._states[StatePosition.DepthBias] = depthBias;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.DepthBias);\r\n        }\r\n    }\r\n\r\n    /*public setDepthBiasClamp(depthBiasClamp: number): void {\r\n        if (this._depthBiasClamp !== depthBiasClamp) {\r\n            this._depthBiasClamp = depthBiasClamp;\r\n            this._states[StatePosition.DepthBiasClamp] = depthBiasClamp.toString();\r\n            this._isDirty = true;\r\n        }\r\n    }*/\r\n\r\n    public setDepthBiasSlopeScale(depthBiasSlopeScale: number): void {\r\n        if (this._depthBiasSlopeScale !== depthBiasSlopeScale) {\r\n            this._depthBiasSlopeScale = depthBiasSlopeScale;\r\n            this._states[StatePosition.DepthBiasSlopeScale] = depthBiasSlopeScale;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.DepthBiasSlopeScale);\r\n        }\r\n    }\r\n\r\n    public setColorFormat(format: GPUTextureFormat | null): void {\r\n        this._webgpuColorFormat[0] = format;\r\n        this._colorFormat = renderableTextureFormatToIndex[format ?? \"\"];\r\n    }\r\n\r\n    // Must be called after setMRT!\r\n    public setMRTAttachments(attachments: number[]): void {\r\n        (this.mrtAttachments as any) = attachments;\r\n        let mask = 0;\r\n        for (let i = 0; i < attachments.length; ++i) {\r\n            if (attachments[i] !== 0) {\r\n                mask += 1 << i;\r\n            }\r\n        }\r\n        if (this._mrtEnabledMask !== mask) {\r\n            this._mrtEnabledMask = mask;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.MRTAttachments);\r\n        }\r\n    }\r\n\r\n    public setMRT(textureArray: InternalTexture[], textureCount?: number): void {\r\n        textureCount = textureCount ?? textureArray.length;\r\n        if (textureCount > 8) {\r\n            // We only support 8 MRTs in WebGPU, so we throw an error if we try to set more than that.\r\n            throw new Error(\"Can't handle more than 8 attachments for a MRT in cache render pipeline!\");\r\n        }\r\n        (this.mrtTextureArray as any) = textureArray;\r\n        (this.mrtTextureCount as any) = textureCount;\r\n\r\n        // Since we need approximately 45 different values per texture format (see WebGPUTextureManager.renderableTextureFormatToIndex), we use 6 bits to encode a texture format,\r\n        // which means we can encode 8 texture formats in 48 bits (a double can represent integers exactly up until 2^53, so 48 bits is ok).\r\n\r\n        this._mrtEnabledMask = 0xffff; // all textures are enabled at start (meaning we can write to them). Calls to setMRTAttachments may disable some\r\n\r\n        let mrtAttachments = 0;\r\n        let mask = 0;\r\n\r\n        for (let i = 0; i < textureCount; ++i) {\r\n            const texture = textureArray[i];\r\n            const gpuWrapper = texture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n\r\n            this._mrtFormats[i] = gpuWrapper?.format ?? this._webgpuColorFormat[0];\r\n\r\n            mrtAttachments += renderableTextureFormatToIndex[this._mrtFormats[i] ?? \"\"] * 2 ** mask;\r\n            mask += 6;\r\n        }\r\n        this._mrtFormats.length = textureCount;\r\n        if (this._mrtAttachments !== mrtAttachments) {\r\n            this._mrtAttachments = mrtAttachments;\r\n            this._states[StatePosition.MRTAttachments] = mrtAttachments;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.MRTAttachments);\r\n        }\r\n    }\r\n\r\n    public setAlphaBlendEnabled(enabled: boolean[], numAlphaBlendTargetsEnabled: number): void {\r\n        this._alphaBlendEnabled = enabled;\r\n        this._numAlphaBlendTargetsEnabled = numAlphaBlendTargetsEnabled;\r\n    }\r\n\r\n    public setAlphaBlendFactors(factors: Array<Nullable<number>>, operations: Array<Nullable<number>>): void {\r\n        this._alphaBlendFuncParams = factors;\r\n        this._alphaBlendEqParams = operations;\r\n    }\r\n\r\n    public setWriteMask(mask: number): void {\r\n        this._writeMask = mask;\r\n    }\r\n\r\n    public setDepthStencilFormat(format: GPUTextureFormat | undefined): void {\r\n        this._webgpuDepthStencilFormat = format;\r\n        this._depthStencilFormat = format === undefined ? 0 : renderableTextureFormatToIndex[format];\r\n    }\r\n\r\n    public setDepthTestEnabled(enabled: boolean): void {\r\n        this._depthTestEnabled = enabled;\r\n    }\r\n\r\n    public setDepthWriteEnabled(enabled: boolean): void {\r\n        this._depthWriteEnabled = enabled;\r\n    }\r\n\r\n    public setDepthCompare(func: Nullable<number>): void {\r\n        this._depthCompare = (func ?? Constants.ALWAYS) - 0x0200;\r\n    }\r\n\r\n    public setStencilEnabled(enabled: boolean): void {\r\n        this._stencilEnabled = enabled;\r\n    }\r\n\r\n    public setStencilCompare(func: Nullable<number>): void {\r\n        this._stencilFrontCompare = (func ?? Constants.ALWAYS) - 0x0200;\r\n    }\r\n\r\n    public setStencilDepthFailOp(op: Nullable<number>): void {\r\n        this._stencilFrontDepthFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];\r\n    }\r\n\r\n    public setStencilPassOp(op: Nullable<number>): void {\r\n        this._stencilFrontPassOp = op === null ? 2 /* REPLACE */ : stencilOpToIndex[op];\r\n    }\r\n\r\n    public setStencilFailOp(op: Nullable<number>): void {\r\n        this._stencilFrontFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];\r\n    }\r\n\r\n    public setStencilBackCompare(func: Nullable<number>): void {\r\n        this._stencilBackCompare = (func ?? Constants.ALWAYS) - 0x0200;\r\n    }\r\n\r\n    public setStencilBackDepthFailOp(op: Nullable<number>): void {\r\n        this._stencilBackDepthFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];\r\n    }\r\n\r\n    public setStencilBackPassOp(op: Nullable<number>): void {\r\n        this._stencilBackPassOp = op === null ? 2 /* REPLACE */ : stencilOpToIndex[op];\r\n    }\r\n\r\n    public setStencilBackFailOp(op: Nullable<number>): void {\r\n        this._stencilBackFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];\r\n    }\r\n\r\n    public setStencilReadMask(mask: number): void {\r\n        if (this._stencilReadMask !== mask) {\r\n            this._stencilReadMask = mask;\r\n            this._states[StatePosition.StencilReadMask] = mask;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.StencilReadMask);\r\n        }\r\n    }\r\n\r\n    public setStencilWriteMask(mask: number): void {\r\n        if (this._stencilWriteMask !== mask) {\r\n            this._stencilWriteMask = mask;\r\n            this._states[StatePosition.StencilWriteMask] = mask;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.StencilWriteMask);\r\n        }\r\n    }\r\n\r\n    public resetStencilState(): void {\r\n        this.setStencilState(false, Constants.ALWAYS, Constants.KEEP, Constants.REPLACE, Constants.KEEP, 0xff, 0xff);\r\n    }\r\n\r\n    public setStencilState(\r\n        stencilEnabled: boolean,\r\n        compare: Nullable<number>,\r\n        depthFailOp: Nullable<number>,\r\n        passOp: Nullable<number>,\r\n        failOp: Nullable<number>,\r\n        readMask: number,\r\n        writeMask: number,\r\n        backCompare: Nullable<number> = null,\r\n        backDepthFailOp: Nullable<number> = null,\r\n        backPassOp: Nullable<number> = null,\r\n        backFailOp: Nullable<number> = null\r\n    ): void {\r\n        this._stencilEnabled = stencilEnabled;\r\n        this._stencilFrontCompare = (compare ?? Constants.ALWAYS) - 0x0200;\r\n        this._stencilFrontDepthFailOp = depthFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[depthFailOp];\r\n        this._stencilFrontPassOp = passOp === null ? 2 /* REPLACE */ : stencilOpToIndex[passOp];\r\n        this._stencilFrontFailOp = failOp === null ? 1 /* KEEP */ : stencilOpToIndex[failOp];\r\n        this._stencilBackCompare = (backCompare ?? Constants.ALWAYS) - 0x0200;\r\n        this._stencilBackDepthFailOp = backDepthFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[backDepthFailOp];\r\n        this._stencilBackPassOp = backPassOp === null ? 2 /* REPLACE */ : stencilOpToIndex[backPassOp];\r\n        this._stencilBackFailOp = backFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[backFailOp];\r\n        this.setStencilReadMask(readMask);\r\n        this.setStencilWriteMask(writeMask);\r\n    }\r\n\r\n    public setBuffers(\r\n        vertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }>,\r\n        indexBuffer: Nullable<DataBuffer>,\r\n        overrideVertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }>\r\n    ): void {\r\n        this._vertexBuffers = vertexBuffers;\r\n        this._overrideVertexBuffers = overrideVertexBuffers;\r\n        (this.indexBuffer as Nullable<DataBuffer>) = indexBuffer;\r\n    }\r\n\r\n    private static _GetTopology(fillMode: number): GPUPrimitiveTopology {\r\n        switch (fillMode) {\r\n            // Triangle views\r\n            case Constants.MATERIAL_TriangleFillMode:\r\n                return WebGPUConstants.PrimitiveTopology.TriangleList;\r\n            case Constants.MATERIAL_PointFillMode:\r\n                return WebGPUConstants.PrimitiveTopology.PointList;\r\n            case Constants.MATERIAL_WireFrameFillMode:\r\n                return WebGPUConstants.PrimitiveTopology.LineList;\r\n            // Draw modes\r\n            case Constants.MATERIAL_PointListDrawMode:\r\n                return WebGPUConstants.PrimitiveTopology.PointList;\r\n            case Constants.MATERIAL_LineListDrawMode:\r\n                return WebGPUConstants.PrimitiveTopology.LineList;\r\n            case Constants.MATERIAL_LineLoopDrawMode:\r\n                // return this._gl.LINE_LOOP;\r\n                // TODO WEBGPU. Line Loop Mode Fallback at buffer load time.\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"LineLoop is an unsupported fillmode in WebGPU\";\r\n            case Constants.MATERIAL_LineStripDrawMode:\r\n                return WebGPUConstants.PrimitiveTopology.LineStrip;\r\n            case Constants.MATERIAL_TriangleStripDrawMode:\r\n                return WebGPUConstants.PrimitiveTopology.TriangleStrip;\r\n            case Constants.MATERIAL_TriangleFanDrawMode:\r\n                // return this._gl.TRIANGLE_FAN;\r\n                // TODO WEBGPU. Triangle Fan Mode Fallback at buffer load time.\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"TriangleFan is an unsupported fillmode in WebGPU\";\r\n            default:\r\n                return WebGPUConstants.PrimitiveTopology.TriangleList;\r\n        }\r\n    }\r\n\r\n    private static _GetAphaBlendOperation(operation: Nullable<number>): GPUBlendOperation {\r\n        switch (operation) {\r\n            case Constants.GL_ALPHA_EQUATION_ADD:\r\n                return WebGPUConstants.BlendOperation.Add;\r\n            case Constants.GL_ALPHA_EQUATION_SUBTRACT:\r\n                return WebGPUConstants.BlendOperation.Subtract;\r\n            case Constants.GL_ALPHA_EQUATION_REVERSE_SUBTRACT:\r\n                return WebGPUConstants.BlendOperation.ReverseSubtract;\r\n            case Constants.GL_ALPHA_EQUATION_MIN:\r\n                return WebGPUConstants.BlendOperation.Min;\r\n            case Constants.GL_ALPHA_EQUATION_MAX:\r\n                return WebGPUConstants.BlendOperation.Max;\r\n            default:\r\n                return WebGPUConstants.BlendOperation.Add;\r\n        }\r\n    }\r\n\r\n    private static _GetAphaBlendFactor(factor: Nullable<number>): GPUBlendFactor {\r\n        switch (factor) {\r\n            case 0:\r\n                return WebGPUConstants.BlendFactor.Zero;\r\n            case 1:\r\n                return WebGPUConstants.BlendFactor.One;\r\n            case Constants.GL_ALPHA_FUNCTION_SRC:\r\n                return WebGPUConstants.BlendFactor.Src;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR:\r\n                return WebGPUConstants.BlendFactor.OneMinusSrc;\r\n            case Constants.GL_ALPHA_FUNCTION_SRC_ALPHA:\r\n                return WebGPUConstants.BlendFactor.SrcAlpha;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA:\r\n                return WebGPUConstants.BlendFactor.OneMinusSrcAlpha;\r\n            case Constants.GL_ALPHA_FUNCTION_DST_ALPHA:\r\n                return WebGPUConstants.BlendFactor.DstAlpha;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_DST_ALPHA:\r\n                return WebGPUConstants.BlendFactor.OneMinusDstAlpha;\r\n            case Constants.GL_ALPHA_FUNCTION_DST_COLOR:\r\n                return WebGPUConstants.BlendFactor.Dst;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_DST_COLOR:\r\n                return WebGPUConstants.BlendFactor.OneMinusDst;\r\n            case Constants.GL_ALPHA_FUNCTION_SRC_ALPHA_SATURATED:\r\n                return WebGPUConstants.BlendFactor.SrcAlphaSaturated;\r\n            case Constants.GL_ALPHA_FUNCTION_CONSTANT_COLOR:\r\n            case Constants.GL_ALPHA_FUNCTION_CONSTANT_ALPHA:\r\n                return WebGPUConstants.BlendFactor.Constant;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_COLOR:\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_ALPHA:\r\n                return WebGPUConstants.BlendFactor.OneMinusConstant;\r\n            case Constants.GL_ALPHA_FUNCTION_SRC1_COLOR:\r\n                return WebGPUConstants.BlendFactor.Src1 as GPUBlendFactor;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC1_COLOR:\r\n                return WebGPUConstants.BlendFactor.OneMinusSrc1 as GPUBlendFactor;\r\n            case Constants.GL_ALPHA_FUNCTION_SRC1_ALPHA:\r\n                return WebGPUConstants.BlendFactor.Src1Alpha as GPUBlendFactor;\r\n            case Constants.GL_ALPHA_FUNCTION_ONE_MINUS_SRC1_ALPHA:\r\n                return WebGPUConstants.BlendFactor.OneMinusSrc1Alpha as GPUBlendFactor;\r\n            default:\r\n                return WebGPUConstants.BlendFactor.One;\r\n        }\r\n    }\r\n\r\n    private static _GetCompareFunction(compareFunction: number): GPUCompareFunction {\r\n        switch (compareFunction) {\r\n            case 0: // NEVER\r\n                return WebGPUConstants.CompareFunction.Never;\r\n            case 1: // LESS\r\n                return WebGPUConstants.CompareFunction.Less;\r\n            case 2: // EQUAL\r\n                return WebGPUConstants.CompareFunction.Equal;\r\n            case 3: // LEQUAL\r\n                return WebGPUConstants.CompareFunction.LessEqual;\r\n            case 4: // GREATER\r\n                return WebGPUConstants.CompareFunction.Greater;\r\n            case 5: // NOTEQUAL\r\n                return WebGPUConstants.CompareFunction.NotEqual;\r\n            case 6: // GEQUAL\r\n                return WebGPUConstants.CompareFunction.GreaterEqual;\r\n            case 7: // ALWAYS\r\n                return WebGPUConstants.CompareFunction.Always;\r\n        }\r\n        return WebGPUConstants.CompareFunction.Never;\r\n    }\r\n\r\n    private static _GetStencilOpFunction(operation: number): GPUStencilOperation {\r\n        switch (operation) {\r\n            case 0:\r\n                return WebGPUConstants.StencilOperation.Zero;\r\n            case 1:\r\n                return WebGPUConstants.StencilOperation.Keep;\r\n            case 2:\r\n                return WebGPUConstants.StencilOperation.Replace;\r\n            case 3:\r\n                return WebGPUConstants.StencilOperation.IncrementClamp;\r\n            case 4:\r\n                return WebGPUConstants.StencilOperation.DecrementClamp;\r\n            case 5:\r\n                return WebGPUConstants.StencilOperation.Invert;\r\n            case 6:\r\n                return WebGPUConstants.StencilOperation.IncrementWrap;\r\n            case 7:\r\n                return WebGPUConstants.StencilOperation.DecrementWrap;\r\n        }\r\n        return WebGPUConstants.StencilOperation.Keep;\r\n    }\r\n\r\n    private static _GetVertexInputDescriptorFormat(vertexBuffer: VertexBuffer): GPUVertexFormat {\r\n        const type = vertexBuffer.type;\r\n        const normalized = vertexBuffer.normalized;\r\n        const size = vertexBuffer.getSize();\r\n\r\n        switch (type) {\r\n            case VertexBuffer.BYTE:\r\n                switch (size) {\r\n                    case 1:\r\n                    case 2:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Snorm8x2 : WebGPUConstants.VertexFormat.Sint8x2;\r\n                    case 3:\r\n                    case 4:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Snorm8x4 : WebGPUConstants.VertexFormat.Sint8x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.UNSIGNED_BYTE:\r\n                switch (size) {\r\n                    case 1:\r\n                    case 2:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Unorm8x2 : WebGPUConstants.VertexFormat.Uint8x2;\r\n                    case 3:\r\n                    case 4:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Unorm8x4 : WebGPUConstants.VertexFormat.Uint8x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.SHORT:\r\n                switch (size) {\r\n                    case 1:\r\n                    case 2:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Snorm16x2 : WebGPUConstants.VertexFormat.Sint16x2;\r\n                    case 3:\r\n                    case 4:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Snorm16x4 : WebGPUConstants.VertexFormat.Sint16x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.UNSIGNED_SHORT:\r\n                switch (size) {\r\n                    case 1:\r\n                    case 2:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Unorm16x2 : WebGPUConstants.VertexFormat.Uint16x2;\r\n                    case 3:\r\n                    case 4:\r\n                        return normalized ? WebGPUConstants.VertexFormat.Unorm16x4 : WebGPUConstants.VertexFormat.Uint16x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.HALF_FLOAT:\r\n                switch (size) {\r\n                    case 1:\r\n                    case 2:\r\n                        return WebGPUConstants.VertexFormat.Float16x2;\r\n                    case 3:\r\n                    case 4:\r\n                        return WebGPUConstants.VertexFormat.Float16x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.INT:\r\n                switch (size) {\r\n                    case 1:\r\n                        return WebGPUConstants.VertexFormat.Sint32;\r\n                    case 2:\r\n                        return WebGPUConstants.VertexFormat.Sint32x2;\r\n                    case 3:\r\n                        return WebGPUConstants.VertexFormat.Sint32x3;\r\n                    case 4:\r\n                        return WebGPUConstants.VertexFormat.Sint32x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.UNSIGNED_INT:\r\n                switch (size) {\r\n                    case 1:\r\n                        return WebGPUConstants.VertexFormat.Uint32;\r\n                    case 2:\r\n                        return WebGPUConstants.VertexFormat.Uint32x2;\r\n                    case 3:\r\n                        return WebGPUConstants.VertexFormat.Uint32x3;\r\n                    case 4:\r\n                        return WebGPUConstants.VertexFormat.Uint32x4;\r\n                }\r\n                break;\r\n            case VertexBuffer.FLOAT:\r\n                switch (size) {\r\n                    case 1:\r\n                        return WebGPUConstants.VertexFormat.Float32;\r\n                    case 2:\r\n                        return WebGPUConstants.VertexFormat.Float32x2;\r\n                    case 3:\r\n                        return WebGPUConstants.VertexFormat.Float32x3;\r\n                    case 4:\r\n                        return WebGPUConstants.VertexFormat.Float32x4;\r\n                }\r\n                break;\r\n        }\r\n\r\n        throw new Error(`Invalid Format '${vertexBuffer.getKind()}' - type=${type}, normalized=${normalized}, size=${size}`);\r\n    }\r\n\r\n    private _getAphaBlendState(targetIndex: number): Nullable<GPUBlendComponent> {\r\n        if (!this._alphaBlendEnabled[targetIndex]) {\r\n            return null;\r\n        }\r\n\r\n        return {\r\n            srcFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 2]),\r\n            dstFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 3]),\r\n            operation: WebGPUCacheRenderPipeline._GetAphaBlendOperation(this._alphaBlendEqParams[targetIndex * 2 + 1]),\r\n        };\r\n    }\r\n\r\n    private _getColorBlendState(targetIndex: number): Nullable<GPUBlendComponent> {\r\n        if (!this._alphaBlendEnabled) {\r\n            return null;\r\n        }\r\n\r\n        return {\r\n            srcFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 0]),\r\n            dstFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 1]),\r\n            operation: WebGPUCacheRenderPipeline._GetAphaBlendOperation(this._alphaBlendEqParams[targetIndex * 2 + 0]),\r\n        };\r\n    }\r\n\r\n    private _setShaderStage(id: number): void {\r\n        if (this._shaderId !== id) {\r\n            this._shaderId = id;\r\n            this._states[StatePosition.ShaderStage] = id;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.ShaderStage);\r\n        }\r\n    }\r\n\r\n    private _setRasterizationState(topology: number, sampleCount: number): void {\r\n        const frontFace = this._frontFace;\r\n        const cullMode = this._cullEnabled ? this._cullFace : 0;\r\n        const clampDepth = this._clampDepth ? 1 : 0;\r\n        const alphaToCoverage = this._alphaToCoverageEnabled && sampleCount > 1 ? 1 : 0;\r\n        const rasterizationState = frontFace - 1 + (cullMode << 1) + (clampDepth << 3) + (alphaToCoverage << 4) + (topology << 5) + (sampleCount << 8);\r\n\r\n        if (this._rasterizationState !== rasterizationState) {\r\n            this._rasterizationState = rasterizationState;\r\n            this._states[StatePosition.RasterizationState] = this._rasterizationState;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.RasterizationState);\r\n        }\r\n    }\r\n\r\n    private _setColorStates(): void {\r\n        // Note that _depthWriteEnabled state has been moved from depthStencilState here because alpha and depth are related (generally when alpha is on, depth write is off and the other way around)\r\n\r\n        // We need 4 color states because we will be grouping 2 blend targets in each state (and WebGPU supports up to 8 targets).\r\n        // Integers can only be represented exactly in 53 bits with a double, so we can only use 53 bits for each state.\r\n        // We use 25 bits for each blend target (5 bits for the 2 (color/alpha) equations and 4*5 bits for the 4 factors (src/dst color and src/dst alpha)).\r\n        // This means that we need 25*2=50 bits to pack 2 blend targets, and we can use the remaining 3 bits for other states (write mask, depth write, color format).\r\n        // The color format is encoded on 6 bits, so we dispatch it over 3 bits to the last two color states.\r\n\r\n        colorStates[0] = (this._writeMask ? 1 : 0) * 2 ** 53;\r\n        colorStates[1] = (this._depthWriteEnabled ? 1 : 0) * 2 ** 53;\r\n        colorStates[2] = (this._colorFormat & 0x07) * 2 ** 50;\r\n        colorStates[3] = (this._colorFormat & 0x38) * 2 ** 47;\r\n\r\n        let colorStateIndex = 0;\r\n        let isDirty = false;\r\n\r\n        for (let i = 0; i < 8; i++) {\r\n            if (this._alphaBlendEnabled[i]) {\r\n                const index0 = i * 4 + 0;\r\n                const index1 = i * 4 + 1;\r\n                const index2 = i * 4 + 2;\r\n                const index3 = i * 4 + 3;\r\n                const indexEq0 = i * 2 + 0;\r\n                const indexEq1 = i * 2 + 1;\r\n                const eq0 = this._alphaBlendEqParams[indexEq0] === null ? 0 : alphaBlendEquationToIndex[this._alphaBlendEqParams[indexEq0]];\r\n                const eq1 = this._alphaBlendEqParams[indexEq1] === null ? 0 : alphaBlendEquationToIndex[this._alphaBlendEqParams[indexEq1]];\r\n\r\n                colorStates[colorStateIndex] +=\r\n                    ((this._alphaBlendFuncParams[index0] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index0]]) << 0) +\r\n                    ((this._alphaBlendFuncParams[index1] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index1]]) << 5) +\r\n                    ((this._alphaBlendFuncParams[index2] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index2]]) << 10) +\r\n                    ((this._alphaBlendFuncParams[index3] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index3]]) << 15) +\r\n                    (eq0 + eq1 * 5) * (1 << 20);\r\n            }\r\n\r\n            if (i & 1) {\r\n                isDirty = isDirty || this._states[StatePosition.ColorStates1 + colorStateIndex] !== colorStates[colorStateIndex];\r\n                this._states[StatePosition.ColorStates1 + colorStateIndex] = colorStates[colorStateIndex];\r\n                colorStateIndex++;\r\n            }\r\n        }\r\n\r\n        if (isDirty) {\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.ColorStates1);\r\n        }\r\n    }\r\n\r\n    private _setDepthStencilState(): void {\r\n        const stencilState = !this._stencilEnabled\r\n            ? 7 /* ALWAYS */ +\r\n              (1 /* KEEP */ << 3) +\r\n              (1 /* KEEP */ << 6) +\r\n              (1 /* KEEP */ << 9) + // front\r\n              (7 /* ALWAYS */ << 12) +\r\n              (1 /* KEEP */ << 15) +\r\n              (1 /* KEEP */ << 18) +\r\n              (1 /* KEEP */ << 21) // back\r\n            : this._stencilFrontCompare +\r\n              (this._stencilFrontDepthFailOp << 3) +\r\n              (this._stencilFrontPassOp << 6) +\r\n              (this._stencilFrontFailOp << 9) + // front\r\n              (this._stencilBackCompare << 12) +\r\n              (this._stencilBackDepthFailOp << 15) +\r\n              (this._stencilBackPassOp << 18) +\r\n              (this._stencilBackFailOp << 21); // back\r\n\r\n        const depthStencilState = this._depthStencilFormat + ((this._depthTestEnabled ? this._depthCompare : 7) /* ALWAYS */ << 6) + stencilState * (1 << 10); // stencil front + back\r\n\r\n        if (this._depthStencilState !== depthStencilState) {\r\n            this._depthStencilState = depthStencilState;\r\n            this._states[StatePosition.DepthStencilState] = this._depthStencilState;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.DepthStencilState);\r\n        }\r\n    }\r\n\r\n    private _setVertexState(effect: Effect): void {\r\n        const currStateLen = this._statesLength;\r\n        let newNumStates = StatePosition.VertexState;\r\n\r\n        const webgpuPipelineContext = effect._pipelineContext as WebGPUPipelineContext;\r\n        const attributes = webgpuPipelineContext.shaderProcessingContext.attributeNamesFromEffect;\r\n        const locations = webgpuPipelineContext.shaderProcessingContext.attributeLocationsFromEffect;\r\n\r\n        let currentGPUBuffer;\r\n        let numVertexBuffers = 0;\r\n        for (let index = 0; index < attributes.length; index++) {\r\n            const location = locations[index];\r\n            let vertexBuffer = (this._overrideVertexBuffers && this._overrideVertexBuffers[attributes[index]]) ?? this._vertexBuffers![attributes[index]];\r\n            if (!vertexBuffer) {\r\n                // In WebGL it's valid to not bind a vertex buffer to an attribute, but it's not valid in WebGPU\r\n                // So we must bind a dummy buffer when we are not given one for a specific attribute\r\n                vertexBuffer = this._emptyVertexBuffer;\r\n                if (WebGPUCacheRenderPipeline.LogErrorIfNoVertexBuffer) {\r\n                    Logger.Error(\r\n                        `No vertex buffer is provided for the \"${attributes[index]}\" attribute. A default empty vertex buffer will be used, but this may generate errors in some browsers.`\r\n                    );\r\n                }\r\n            }\r\n\r\n            const buffer = vertexBuffer.effectiveBuffer?.underlyingResource;\r\n\r\n            // We optimize usage of GPUVertexBufferLayout: we will create a single GPUVertexBufferLayout for all the attributes which follow each other and which use the same GPU buffer\r\n            // However, there are some constraints in the attribute.offset value range, so we must check for them before being able to reuse the same GPUVertexBufferLayout\r\n            // See _getVertexInputDescriptor() below\r\n            if (vertexBuffer._validOffsetRange === undefined) {\r\n                const offset = vertexBuffer.effectiveByteOffset;\r\n                const formatSize = vertexBuffer.getSize(true);\r\n                const byteStride = vertexBuffer.effectiveByteStride;\r\n\r\n                vertexBuffer._validOffsetRange =\r\n                    (offset + formatSize <= this._kMaxVertexBufferStride && byteStride === 0) || (byteStride !== 0 && offset + formatSize <= byteStride);\r\n            }\r\n\r\n            const canMergeWithCurrentBuffer = WebGPUCacheRenderPipeline._CanMergeVertexBuffer(currentGPUBuffer, buffer, vertexBuffer);\r\n            if (!canMergeWithCurrentBuffer) {\r\n                // we can't combine the previous vertexBuffer with the current one\r\n                this.vertexBuffers[numVertexBuffers++] = vertexBuffer;\r\n                currentGPUBuffer = vertexBuffer._validOffsetRange ? buffer : null;\r\n            }\r\n\r\n            const vid = vertexBuffer.hashCode + (location << 7) + (canMergeWithCurrentBuffer ? vertexBufferLayoutContinuation : 0);\r\n            const descriptorOffset = vertexBuffer._validOffsetRange ? vertexBuffer.effectiveByteOffset : 0;\r\n\r\n            this._isDirty = this._isDirty || this._states[newNumStates] !== vid;\r\n            this._states[newNumStates++] = vid;\r\n            if (descriptorOffset !== 0) {\r\n                // Offset states are negative so they cannot collide with vertex format states.\r\n                const offsetState = -descriptorOffset;\r\n                this._isDirty = this._isDirty || this._states[newNumStates] !== offsetState;\r\n                this._states[newNumStates++] = offsetState;\r\n            }\r\n        }\r\n\r\n        this.vertexBuffers.length = numVertexBuffers;\r\n\r\n        this._statesLength = newNumStates;\r\n        this._isDirty = this._isDirty || newNumStates !== currStateLen;\r\n        if (this._isDirty) {\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.VertexState);\r\n        }\r\n    }\r\n\r\n    private _setTextureState(textureState: number): void {\r\n        if (this._textureState !== textureState) {\r\n            this._textureState = textureState;\r\n            this._states[StatePosition.TextureStage] = this._textureState;\r\n            this._isDirty = true;\r\n            this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.TextureStage);\r\n        }\r\n    }\r\n\r\n    private _createPipelineLayout(webgpuPipelineContext: WebGPUPipelineContext): GPUPipelineLayout {\r\n        if (this._useTextureStage) {\r\n            return this._createPipelineLayoutWithTextureStage(webgpuPipelineContext);\r\n        }\r\n\r\n        const bindGroupLayouts: GPUBindGroupLayout[] = [];\r\n        const bindGroupLayoutEntries = webgpuPipelineContext.shaderProcessingContext.bindGroupLayoutEntries;\r\n\r\n        for (let i = 0; i < bindGroupLayoutEntries.length; i++) {\r\n            const setDefinition = bindGroupLayoutEntries[i];\r\n\r\n            bindGroupLayouts[i] = this._device.createBindGroupLayout({\r\n                entries: setDefinition,\r\n            });\r\n        }\r\n\r\n        webgpuPipelineContext.bindGroupLayouts[0] = bindGroupLayouts;\r\n\r\n        return this._device.createPipelineLayout({ bindGroupLayouts });\r\n    }\r\n\r\n    private _createPipelineLayoutWithTextureStage(webgpuPipelineContext: WebGPUPipelineContext): GPUPipelineLayout {\r\n        const shaderProcessingContext = webgpuPipelineContext.shaderProcessingContext;\r\n        const bindGroupLayoutEntries = shaderProcessingContext.bindGroupLayoutEntries;\r\n\r\n        let bitVal = 1;\r\n        for (let i = 0; i < bindGroupLayoutEntries.length; i++) {\r\n            const setDefinition = bindGroupLayoutEntries[i];\r\n\r\n            for (let j = 0; j < setDefinition.length; j++) {\r\n                const entry = bindGroupLayoutEntries[i][j];\r\n\r\n                if (entry.texture) {\r\n                    const name = shaderProcessingContext.bindGroupLayoutEntryInfo[i][entry.binding].name;\r\n                    const textureInfo = shaderProcessingContext.availableTextures[name];\r\n                    const samplerInfo = textureInfo.autoBindSampler ? shaderProcessingContext.availableSamplers[name + Constants.AUTOSAMPLERSUFFIX] : null;\r\n\r\n                    let sampleType = textureInfo.sampleType;\r\n                    let samplerType = samplerInfo?.type ?? WebGPUConstants.SamplerBindingType.Filtering;\r\n\r\n                    if (this._textureState & bitVal && sampleType !== WebGPUConstants.TextureSampleType.Depth) {\r\n                        // The texture is a 32 bits float texture but the system does not support linear filtering for them OR the texture is a depth texture with \"float\" filtering:\r\n                        // we set the sampler to \"non-filtering\" and the texture sample type to \"unfilterable-float\"\r\n                        if (textureInfo.autoBindSampler) {\r\n                            samplerType = WebGPUConstants.SamplerBindingType.NonFiltering;\r\n                        }\r\n                        sampleType = WebGPUConstants.TextureSampleType.UnfilterableFloat;\r\n                    }\r\n\r\n                    entry.texture.sampleType = sampleType;\r\n\r\n                    if (samplerInfo) {\r\n                        const binding = shaderProcessingContext.bindGroupLayoutEntryInfo[samplerInfo.binding.groupIndex][samplerInfo.binding.bindingIndex].index;\r\n                        bindGroupLayoutEntries[samplerInfo.binding.groupIndex][binding].sampler!.type = samplerType;\r\n                    }\r\n\r\n                    bitVal = bitVal << 1;\r\n                }\r\n            }\r\n        }\r\n\r\n        const bindGroupLayouts: GPUBindGroupLayout[] = [];\r\n\r\n        for (let i = 0; i < bindGroupLayoutEntries.length; ++i) {\r\n            bindGroupLayouts[i] = this._device.createBindGroupLayout({\r\n                entries: bindGroupLayoutEntries[i],\r\n            });\r\n        }\r\n\r\n        webgpuPipelineContext.bindGroupLayouts[this._textureState] = bindGroupLayouts;\r\n\r\n        return this._device.createPipelineLayout({ bindGroupLayouts });\r\n    }\r\n\r\n    private _getVertexInputDescriptor(effect: Effect): GPUVertexBufferLayout[] {\r\n        const descriptors: GPUVertexBufferLayout[] = [];\r\n        const webgpuPipelineContext = effect._pipelineContext as WebGPUPipelineContext;\r\n        const attributes = webgpuPipelineContext.shaderProcessingContext.attributeNamesFromEffect;\r\n        const locations = webgpuPipelineContext.shaderProcessingContext.attributeLocationsFromEffect;\r\n\r\n        let currentGPUBuffer;\r\n        let currentGPUAttributes: GPUVertexAttribute[] | undefined;\r\n        for (let index = 0; index < attributes.length; index++) {\r\n            const location = locations[index];\r\n            let vertexBuffer = (this._overrideVertexBuffers && this._overrideVertexBuffers[attributes[index]]) ?? this._vertexBuffers![attributes[index]];\r\n            if (!vertexBuffer) {\r\n                // In WebGL it's valid to not bind a vertex buffer to an attribute, but it's not valid in WebGPU\r\n                // So we must bind a dummy buffer when we are not given one for a specific attribute\r\n                vertexBuffer = this._emptyVertexBuffer;\r\n            }\r\n\r\n            let buffer = vertexBuffer.effectiveBuffer?.underlyingResource;\r\n\r\n            // We reuse the same GPUVertexBufferLayout for all attributes that use the same underlying GPU buffer (and for attributes that follow each other in the attributes array)\r\n            let offset = vertexBuffer.effectiveByteOffset;\r\n            const invalidOffsetRange = !vertexBuffer._validOffsetRange;\r\n            if (!WebGPUCacheRenderPipeline._CanMergeVertexBuffer(currentGPUBuffer, buffer, vertexBuffer)) {\r\n                const vertexBufferDescriptor: GPUVertexBufferLayout = {\r\n                    arrayStride: vertexBuffer.effectiveByteStride,\r\n                    stepMode: vertexBuffer.getIsInstanced() ? WebGPUConstants.VertexStepMode.Instance : WebGPUConstants.VertexStepMode.Vertex,\r\n                    attributes: [],\r\n                };\r\n\r\n                descriptors.push(vertexBufferDescriptor);\r\n                currentGPUAttributes = vertexBufferDescriptor.attributes;\r\n                if (invalidOffsetRange) {\r\n                    offset = 0; // the offset will be set directly in the setVertexBuffer call\r\n                    buffer = null; // buffer can't be reused\r\n                }\r\n            }\r\n\r\n            currentGPUAttributes!.push({\r\n                shaderLocation: location,\r\n                offset,\r\n                format: WebGPUCacheRenderPipeline._GetVertexInputDescriptorFormat(vertexBuffer),\r\n            });\r\n\r\n            currentGPUBuffer = buffer;\r\n        }\r\n\r\n        return descriptors;\r\n    }\r\n\r\n    private static _CanMergeVertexBuffer(currentGPUBuffer: unknown, buffer: unknown, vertexBuffer: VertexBuffer): boolean {\r\n        return !!currentGPUBuffer && currentGPUBuffer === buffer && vertexBuffer._validOffsetRange;\r\n    }\r\n\r\n    private _buildRenderPipelineDescriptor(effect: Effect, topology: GPUPrimitiveTopology, sampleCount: number): GPURenderPipelineDescriptor {\r\n        const webgpuPipelineContext = effect._pipelineContext as WebGPUPipelineContext;\r\n        const inputStateDescriptor = this._getVertexInputDescriptor(effect);\r\n        const pipelineLayout = this._createPipelineLayout(webgpuPipelineContext);\r\n\r\n        const colorStates: Array<GPUColorTargetState | null> = [];\r\n\r\n        if (this._vertexBuffers) {\r\n            checkNonFloatVertexBuffers(this._vertexBuffers, effect);\r\n        }\r\n\r\n        if (this._mrtAttachments > 0) {\r\n            for (let i = 0; i < this._mrtFormats.length; ++i) {\r\n                const format = this._mrtFormats[i];\r\n                if (format) {\r\n                    const descr: GPUColorTargetState = {\r\n                        format,\r\n                        writeMask: (this._mrtEnabledMask & (1 << i)) !== 0 ? this._writeMask : 0,\r\n                    };\r\n                    const alphaBlend = this._getAphaBlendState(i < this._numAlphaBlendTargetsEnabled ? i : 0);\r\n                    const colorBlend = this._getColorBlendState(i < this._numAlphaBlendTargetsEnabled ? i : 0);\r\n\r\n                    const isIntegerFormat = format.endsWith(\"uint\") || format.endsWith(\"sint\");\r\n                    if (descr.writeMask !== 0 && !isIntegerFormat && alphaBlend && colorBlend) {\r\n                        descr.blend = {\r\n                            alpha: alphaBlend,\r\n                            color: colorBlend,\r\n                        };\r\n                    }\r\n                    colorStates.push(descr);\r\n                } else {\r\n                    colorStates.push(null);\r\n                }\r\n            }\r\n        } else {\r\n            if (this._webgpuColorFormat[0]) {\r\n                const descr: GPUColorTargetState = {\r\n                    format: this._webgpuColorFormat[0],\r\n                    writeMask: this._writeMask,\r\n                };\r\n                const alphaBlend = this._getAphaBlendState(0);\r\n                const colorBlend = this._getColorBlendState(0);\r\n\r\n                const format = this._webgpuColorFormat[0];\r\n                const isIntegerFormat = format.endsWith(\"uint\") || format.endsWith(\"sint\");\r\n                if (!isIntegerFormat && alphaBlend && colorBlend) {\r\n                    descr.blend = {\r\n                        alpha: alphaBlend,\r\n                        color: colorBlend,\r\n                    };\r\n                }\r\n                colorStates.push(descr);\r\n            } else {\r\n                colorStates.push(null);\r\n            }\r\n        }\r\n\r\n        const stencilFront: GPUStencilFaceState = {\r\n            compare: WebGPUCacheRenderPipeline._GetCompareFunction(this._stencilEnabled ? this._stencilFrontCompare : 7 /* ALWAYS */),\r\n            depthFailOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilFrontDepthFailOp : 1 /* KEEP */),\r\n            failOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilFrontFailOp : 1 /* KEEP */),\r\n            passOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilFrontPassOp : 1 /* KEEP */),\r\n        };\r\n\r\n        const stencilBack: GPUStencilFaceState = {\r\n            compare: WebGPUCacheRenderPipeline._GetCompareFunction(this._stencilEnabled ? this._stencilBackCompare : 7 /* ALWAYS */),\r\n            depthFailOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilBackDepthFailOp : 1 /* KEEP */),\r\n            failOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilBackFailOp : 1 /* KEEP */),\r\n            passOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilBackPassOp : 1 /* KEEP */),\r\n        };\r\n\r\n        const topologyIsTriangle = topology === WebGPUConstants.PrimitiveTopology.TriangleList || topology === WebGPUConstants.PrimitiveTopology.TriangleStrip;\r\n\r\n        let stripIndexFormat: GPUIndexFormat | undefined = undefined;\r\n        if (topology === WebGPUConstants.PrimitiveTopology.LineStrip || topology === WebGPUConstants.PrimitiveTopology.TriangleStrip) {\r\n            stripIndexFormat = !this.indexBuffer || this.indexBuffer.is32Bits ? WebGPUConstants.IndexFormat.Uint32 : WebGPUConstants.IndexFormat.Uint16;\r\n        }\r\n\r\n        const depthStencilFormatHasStencil = this._webgpuDepthStencilFormat ? WebGPUTextureHelper.HasStencilAspect(this._webgpuDepthStencilFormat) : false;\r\n\r\n        const primitiveState: GPUPrimitiveState = {\r\n            topology,\r\n            frontFace: this._frontFace === 1 ? WebGPUConstants.FrontFace.CCW : WebGPUConstants.FrontFace.CW,\r\n            cullMode: !this._cullEnabled ? WebGPUConstants.CullMode.None : this._cullFace === 2 ? WebGPUConstants.CullMode.Front : WebGPUConstants.CullMode.Back,\r\n        };\r\n\r\n        if (stripIndexFormat) {\r\n            primitiveState.stripIndexFormat = stripIndexFormat;\r\n        }\r\n\r\n        return {\r\n            label: `RenderPipeline_${colorStates[0]?.format ?? \"nooutput\"}_${this._webgpuDepthStencilFormat ?? \"nodepth\"}_samples${sampleCount}_textureState${this._textureState}`,\r\n            layout: pipelineLayout,\r\n            vertex: {\r\n                module: webgpuPipelineContext.stages!.vertexStage.module,\r\n                entryPoint: webgpuPipelineContext.stages!.vertexStage.entryPoint,\r\n                buffers: inputStateDescriptor,\r\n            },\r\n            primitive: primitiveState,\r\n            fragment: !webgpuPipelineContext.stages!.fragmentStage\r\n                ? undefined\r\n                : {\r\n                      module: webgpuPipelineContext.stages!.fragmentStage.module,\r\n                      entryPoint: webgpuPipelineContext.stages!.fragmentStage.entryPoint,\r\n                      targets: colorStates,\r\n                  },\r\n\r\n            multisample: {\r\n                count: sampleCount,\r\n            },\r\n            depthStencil:\r\n                this._webgpuDepthStencilFormat === undefined\r\n                    ? undefined\r\n                    : {\r\n                          depthWriteEnabled: this._depthWriteEnabled,\r\n                          depthCompare: this._depthTestEnabled ? WebGPUCacheRenderPipeline._GetCompareFunction(this._depthCompare) : WebGPUConstants.CompareFunction.Always,\r\n                          format: this._webgpuDepthStencilFormat,\r\n                          stencilFront: this._stencilEnabled && depthStencilFormatHasStencil ? stencilFront : undefined,\r\n                          stencilBack: this._stencilEnabled && depthStencilFormatHasStencil ? stencilBack : undefined,\r\n                          stencilReadMask: this._stencilEnabled && depthStencilFormatHasStencil ? this._stencilReadMask : 0xffffffff,\r\n                          stencilWriteMask: this._stencilEnabled && depthStencilFormatHasStencil ? this._stencilWriteMask : 0xffffffff,\r\n                          depthBias: this._depthBias,\r\n                          depthBiasClamp: topologyIsTriangle ? this._depthBiasClamp : 0,\r\n                          depthBiasSlopeScale: topologyIsTriangle ? this._depthBiasSlopeScale : 0,\r\n                      },\r\n        };\r\n    }\r\n\r\n    private _createRenderPipeline(effect: Effect, topology: GPUPrimitiveTopology, sampleCount: number): GPURenderPipeline {\r\n        return this._device.createRenderPipeline(this._buildRenderPipelineDescriptor(effect, topology, sampleCount));\r\n    }\r\n\r\n    /**\r\n     * Pre-warms a render pipeline asynchronously. Sets up the cache state,\r\n     * checks for a cache hit, and on miss starts an async pipeline compilation.\r\n     * @param fillMode - the fill mode (triangle list, wireframe, etc.)\r\n     * @param effect - the effect to create the pipeline for\r\n     * @param sampleCount - the MSAA sample count\r\n     * @param textureState - the texture state bitmask\r\n     * @returns a Promise that resolves when the pipeline is compiled and cached, or null if already cached\r\n     */\r\n    public preWarmPipeline(fillMode: number, effect: Effect, sampleCount: number, textureState: number = 0): Nullable<Promise<GPURenderPipeline>> {\r\n        sampleCount = WebGPUTextureHelper.GetSample(sampleCount);\r\n\r\n        const cached = this._lookupRenderPipeline(fillMode, effect, sampleCount, textureState);\r\n        if (cached) {\r\n            return null;\r\n        }\r\n\r\n        const topology = WebGPUCacheRenderPipeline._GetTopology(fillMode);\r\n\r\n        // Capture the cache token before any subsequent cache operations overwrite it\r\n        const capturedParam = { token: this._parameter.token, pipeline: null as Nullable<GPURenderPipeline> };\r\n\r\n        const promise = this._device.createRenderPipelineAsync(this._buildRenderPipelineDescriptor(effect, topology, sampleCount));\r\n\r\n        // eslint-disable-next-line github/no-then\r\n        return promise.then((pipeline) => {\r\n            capturedParam.pipeline = pipeline;\r\n            this._setRenderPipeline(capturedParam);\r\n\r\n            WebGPUCacheRenderPipeline.NumCacheMiss++;\r\n\r\n            return pipeline;\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinWebGPUEngine } from \"../../thinWebGPUEngine\";\r\nimport { WebGPUCacheRenderPipeline } from \"../webgpuCacheRenderPipeline\";\r\nimport { type Effect } from \"../../../Materials/effect.pure\";\r\n\r\ninterface IWebGPUCacheRenderPipelineInternals {\r\n    _alphaToCoverageEnabled: boolean;\r\n    _buildRenderPipelineDescriptor(effect: Effect, topology: GPUPrimitiveTopology, sampleCount: number): GPURenderPipelineDescriptor;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Registers alpha-to-coverage support for WebGPU engines.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineAlphaToCoverage(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    const alphaToCoverageState = new WeakMap<ThinWebGPUEngine, boolean>();\r\n\r\n    ThinWebGPUEngine.prototype.getAlphaToCoverage = function (): boolean {\r\n        return alphaToCoverageState.get(this) ?? false;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.setAlphaToCoverage = function (enable: boolean): void {\r\n        const pipelineCache = this._cacheRenderPipeline as unknown as IWebGPUCacheRenderPipelineInternals;\r\n        if ((alphaToCoverageState.get(this) ?? false) === enable && pipelineCache._alphaToCoverageEnabled === enable) {\r\n            return;\r\n        }\r\n\r\n        alphaToCoverageState.set(this, enable);\r\n        this._cacheRenderPipeline.setAlphaToCoverage(enable);\r\n    };\r\n\r\n    const pipelinePrototype = WebGPUCacheRenderPipeline.prototype as unknown as IWebGPUCacheRenderPipelineInternals;\r\n    const buildRenderPipelineDescriptor = pipelinePrototype._buildRenderPipelineDescriptor;\r\n\r\n    pipelinePrototype._buildRenderPipelineDescriptor = function (effect: Effect, topology: GPUPrimitiveTopology, sampleCount: number): GPURenderPipelineDescriptor {\r\n        const descriptor = buildRenderPipelineDescriptor.call(this, effect, topology, sampleCount);\r\n        descriptor.multisample!.alphaToCoverageEnabled = this._alphaToCoverageEnabled && sampleCount > 1;\r\n        return descriptor;\r\n    };\r\n}\r\n","import { Constants } from \"../../constants\";\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineAlpha.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineAlpha(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype.setAlphaMode = function (mode: number, noDepthWriteChange: boolean = false, targetIndex: number = 0): void {\r\n        const alphaBlend = this._alphaState._alphaBlend[targetIndex];\r\n\r\n        if (this._alphaMode[targetIndex] === mode && ((mode === Constants.ALPHA_DISABLE && !alphaBlend) || (mode !== Constants.ALPHA_DISABLE && alphaBlend))) {\r\n            if (!noDepthWriteChange) {\r\n                // Make sure we still have the correct depth mask according to the alpha mode (a transparent material could have forced writting to the depth buffer, for instance)\r\n                const depthMask = mode === Constants.ALPHA_DISABLE;\r\n                if (this.depthCullingState.depthMask !== depthMask) {\r\n                    this.setDepthWrite(depthMask);\r\n                    this._cacheRenderPipeline.setDepthWriteEnabled(depthMask);\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        const alphaBlendDisabled = mode === Constants.ALPHA_DISABLE;\r\n\r\n        this._alphaState.setAlphaBlend(!alphaBlendDisabled, targetIndex);\r\n        this._alphaState.setAlphaMode(mode, targetIndex);\r\n\r\n        if (!noDepthWriteChange) {\r\n            this.setDepthWrite(alphaBlendDisabled);\r\n            this._cacheRenderPipeline.setDepthWriteEnabled(alphaBlendDisabled);\r\n        }\r\n        this._alphaMode[targetIndex] = mode;\r\n        this._cacheRenderPipeline.setAlphaBlendEnabled(this._alphaState._alphaBlend, this._alphaState._numTargetEnabled);\r\n        this._cacheRenderPipeline.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.setAlphaEquation = function (equation: number, targetIndex: number = 0): void {\r\n        AbstractEngine.prototype.setAlphaEquation.call(this, equation, targetIndex);\r\n\r\n        this._cacheRenderPipeline.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);\r\n    };\r\n}\r\n","import { type DataBuffer } from \"core/Buffers/dataBuffer\";\r\nimport { type StorageBuffer } from \"../../Buffers/storageBuffer\";\r\nimport { type IComputeContext } from \"../../Compute/IComputeContext\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type TextureSampler } from \"../../Materials/Textures/textureSampler\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type ComputeBindingList, type ComputeBindingMapping, ComputeBindingType } from \"../Extensions/engine.computeShader.pure\";\r\nimport { type WebGPUCacheSampler } from \"./webgpuCacheSampler\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { type WebGPUHardwareTexture } from \"./webgpuHardwareTexture\";\r\nimport { type ExternalTexture } from \"core/Materials/Textures/externalTexture\";\r\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\n\r\n/** @internal */\r\nexport class WebGPUComputeContext implements IComputeContext {\r\n    private static _Counter = 0;\r\n\r\n    public readonly uniqueId: number;\r\n\r\n    private _device: GPUDevice;\r\n    private _cacheSampler: WebGPUCacheSampler;\r\n    private _bindGroups: GPUBindGroup[];\r\n    private _bindGroupEntries: GPUBindGroupEntry[][];\r\n\r\n    public getBindGroups(bindings: ComputeBindingList, computePipeline: GPUComputePipeline, bindingsMapping?: ComputeBindingMapping): GPUBindGroup[] {\r\n        if (!bindingsMapping) {\r\n            throw new Error(\"WebGPUComputeContext.getBindGroups: bindingsMapping is required until browsers support reflection for wgsl shaders!\");\r\n        }\r\n        if (this._bindGroups.length === 0) {\r\n            const bindGroupEntriesExist = this._bindGroupEntries.length > 0;\r\n            for (const key in bindings) {\r\n                const binding = bindings[key],\r\n                    location = bindingsMapping[key],\r\n                    group = location.group,\r\n                    index = location.binding,\r\n                    type = binding.type,\r\n                    object = binding.object;\r\n                let indexInGroupEntries = binding.indexInGroupEntries;\r\n\r\n                let entries = this._bindGroupEntries[group];\r\n                if (!entries) {\r\n                    entries = this._bindGroupEntries[group] = [];\r\n                }\r\n\r\n                switch (type) {\r\n                    case ComputeBindingType.Sampler: {\r\n                        const sampler = object as TextureSampler;\r\n                        if (indexInGroupEntries !== undefined && bindGroupEntriesExist) {\r\n                            entries[indexInGroupEntries].resource = this._cacheSampler.getSampler(sampler);\r\n                        } else {\r\n                            binding.indexInGroupEntries = entries.length;\r\n                            entries.push({\r\n                                binding: index,\r\n                                resource: this._cacheSampler.getSampler(sampler),\r\n                            });\r\n                        }\r\n                        break;\r\n                    }\r\n\r\n                    case ComputeBindingType.Texture:\r\n                    case ComputeBindingType.TextureWithoutSampler: {\r\n                        const texture = object as BaseTexture;\r\n                        const hardwareTexture = texture._texture!._hardwareTexture as WebGPUHardwareTexture;\r\n                        if (indexInGroupEntries !== undefined && bindGroupEntriesExist) {\r\n                            if (type === ComputeBindingType.Texture) {\r\n                                entries[indexInGroupEntries++].resource = this._cacheSampler.getSampler(texture._texture!);\r\n                            }\r\n                            entries[indexInGroupEntries].resource = hardwareTexture.view!;\r\n                        } else {\r\n                            binding.indexInGroupEntries = entries.length;\r\n                            if (type === ComputeBindingType.Texture) {\r\n                                entries.push({\r\n                                    binding: index - 1,\r\n                                    resource: this._cacheSampler.getSampler(texture._texture!),\r\n                                });\r\n                            }\r\n                            entries.push({\r\n                                binding: index,\r\n                                resource: hardwareTexture.view!,\r\n                            });\r\n                        }\r\n                        break;\r\n                    }\r\n\r\n                    case ComputeBindingType.InternalTexture: {\r\n                        const texture = object as InternalTexture;\r\n                        const hardwareTexture = texture._hardwareTexture as WebGPUHardwareTexture;\r\n                        if (indexInGroupEntries !== undefined && bindGroupEntriesExist) {\r\n                            entries[indexInGroupEntries].resource = hardwareTexture.view!;\r\n                        } else {\r\n                            binding.indexInGroupEntries = entries.length;\r\n                            entries.push({\r\n                                binding: index,\r\n                                resource: hardwareTexture.view!,\r\n                            });\r\n                        }\r\n                        break;\r\n                    }\r\n\r\n                    case ComputeBindingType.StorageTexture: {\r\n                        const texture = object as BaseTexture;\r\n                        const hardwareTexture = texture._texture!._hardwareTexture as WebGPUHardwareTexture;\r\n                        if ((hardwareTexture.textureAdditionalUsages & WebGPUConstants.TextureUsage.StorageBinding) === 0) {\r\n                            Logger.Error(`computeDispatch: The texture (name=${texture.name}, uniqueId=${texture.uniqueId}) is not a storage texture!`, 50);\r\n                        }\r\n                        if (indexInGroupEntries !== undefined && bindGroupEntriesExist) {\r\n                            entries[indexInGroupEntries].resource = hardwareTexture.viewForWriting!;\r\n                        } else {\r\n                            binding.indexInGroupEntries = entries.length;\r\n                            entries.push({\r\n                                binding: index,\r\n                                resource: hardwareTexture.viewForWriting!,\r\n                            });\r\n                        }\r\n                        break;\r\n                    }\r\n\r\n                    case ComputeBindingType.ExternalTexture: {\r\n                        const texture = object as ExternalTexture;\r\n                        const externalTexture = texture.underlyingResource;\r\n                        if (indexInGroupEntries !== undefined && bindGroupEntriesExist) {\r\n                            entries[indexInGroupEntries].resource = this._device.importExternalTexture({ source: externalTexture });\r\n                        } else {\r\n                            binding.indexInGroupEntries = entries.length;\r\n                            entries.push({\r\n                                binding: index,\r\n                                resource: this._device.importExternalTexture({ source: externalTexture }),\r\n                            });\r\n                        }\r\n                        break;\r\n                    }\r\n\r\n                    case ComputeBindingType.UniformBuffer:\r\n                    case ComputeBindingType.StorageBuffer:\r\n                    case ComputeBindingType.DataBuffer: {\r\n                        const dataBuffer =\r\n                            type === ComputeBindingType.DataBuffer\r\n                                ? (object as DataBuffer)\r\n                                : type === ComputeBindingType.UniformBuffer\r\n                                  ? (object as UniformBuffer).getBuffer()!\r\n                                  : (object as StorageBuffer).getBuffer();\r\n                        const webgpuBuffer = dataBuffer.underlyingResource as GPUBuffer;\r\n                        if (indexInGroupEntries !== undefined && bindGroupEntriesExist) {\r\n                            (entries[indexInGroupEntries].resource as GPUBufferBinding).buffer = webgpuBuffer;\r\n                            (entries[indexInGroupEntries].resource as GPUBufferBinding).size = dataBuffer.capacity;\r\n                        } else {\r\n                            binding.indexInGroupEntries = entries.length;\r\n                            entries.push({\r\n                                binding: index,\r\n                                resource: {\r\n                                    buffer: webgpuBuffer,\r\n                                    offset: 0,\r\n                                    size: dataBuffer.capacity,\r\n                                },\r\n                            });\r\n                        }\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            for (let i = 0; i < this._bindGroupEntries.length; ++i) {\r\n                const entries = this._bindGroupEntries[i];\r\n                if (!entries) {\r\n                    this._bindGroups[i] = undefined as any;\r\n                    continue;\r\n                }\r\n                this._bindGroups[i] = this._device.createBindGroup({\r\n                    layout: computePipeline.getBindGroupLayout(i),\r\n                    entries,\r\n                });\r\n            }\r\n\r\n            this._bindGroups.length = this._bindGroupEntries.length;\r\n        }\r\n\r\n        return this._bindGroups;\r\n    }\r\n\r\n    constructor(device: GPUDevice, cacheSampler: WebGPUCacheSampler) {\r\n        this._device = device;\r\n        this._cacheSampler = cacheSampler;\r\n        this.uniqueId = WebGPUComputeContext._Counter++;\r\n        this._bindGroupEntries = [];\r\n        this.clear();\r\n    }\r\n\r\n    public clear(): void {\r\n        this._bindGroups = [];\r\n        // Don't reset _bindGroupEntries if they have already been created, they are still ok even if we have to clear _bindGroups (the layout of the compute shader can't change once created)\r\n    }\r\n}\r\n","import { type IComputePipelineContext } from \"../../Compute/IComputePipelineContext\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\n\r\n/** @internal */\r\nexport class WebGPUComputePipelineContext implements IComputePipelineContext {\r\n    public engine: WebGPUEngine;\r\n\r\n    public sources: {\r\n        compute: string;\r\n        rawCompute: string;\r\n    };\r\n\r\n    public stage: Nullable<GPUProgrammableStage>;\r\n\r\n    public computePipeline: GPUComputePipeline;\r\n\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public get isAsync() {\r\n        return false;\r\n    }\r\n\r\n    public get isReady(): boolean {\r\n        if (this.isAsync) {\r\n            // When async mode is implemented, this should return true if the pipeline is ready\r\n            return false;\r\n        }\r\n\r\n        // In synchronous mode, we return false, the readiness being determined by ComputeEffect\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _name: string;\r\n\r\n    constructor(engine: WebGPUEngine) {\r\n        this._name = \"unnamed\";\r\n        this.engine = engine;\r\n    }\r\n\r\n    public _getComputeShaderCode(): string | null {\r\n        return this.sources?.compute;\r\n    }\r\n\r\n    public dispose(): void {}\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IShaderProcessor } from \"../Processors/iShaderProcessor\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { type WebGPUSamplerDescription, type WebGPUShaderProcessingContext, type WebGPUTextureDescription, type WebGPUBufferDescription } from \"./webgpuShaderProcessingContext\";\r\n\r\n/** @internal */\r\nexport abstract class WebGPUShaderProcessor implements IShaderProcessor {\r\n    public static readonly LeftOvertUBOName = \"LeftOver\";\r\n    public static readonly InternalsUBOName = \"Internals\";\r\n\r\n    public static UniformSizes: { [type: string]: number } = {\r\n        // GLSL types\r\n        bool: 1,\r\n        int: 1,\r\n        float: 1,\r\n        vec2: 2,\r\n        ivec2: 2,\r\n        uvec2: 2,\r\n        vec3: 3,\r\n        ivec3: 3,\r\n        uvec3: 3,\r\n        vec4: 4,\r\n        ivec4: 4,\r\n        uvec4: 4,\r\n        mat2: 4,\r\n        mat3: 12,\r\n        mat4: 16,\r\n\r\n        // WGSL types\r\n        i32: 1,\r\n        u32: 1,\r\n        f32: 1,\r\n        mat2x2: 4,\r\n        mat3x3: 12,\r\n        mat4x4: 16,\r\n        mat2x2f: 4,\r\n        mat3x3f: 12,\r\n        mat4x4f: 16,\r\n        vec2i: 2,\r\n        vec3i: 3,\r\n        vec4i: 4,\r\n        vec2u: 2,\r\n        vec3u: 3,\r\n        vec4u: 4,\r\n        vec2f: 2,\r\n        vec3f: 3,\r\n        vec4f: 4,\r\n        vec2h: 1,\r\n        vec3h: 2,\r\n        vec4h: 2,\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected static _SamplerFunctionByWebGLSamplerType: { [key: string]: string } = {\r\n        sampler2D: \"sampler2D\",\r\n        sampler2DArray: \"sampler2DArray\",\r\n        sampler2DShadow: \"sampler2DShadow\",\r\n        sampler2DArrayShadow: \"sampler2DArrayShadow\",\r\n        samplerCube: \"samplerCube\",\r\n        sampler3D: \"sampler3D\",\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected static _TextureTypeByWebGLSamplerType: { [key: string]: string } = {\r\n        sampler2D: \"texture2D\",\r\n        sampler2DArray: \"texture2DArray\",\r\n        sampler2DShadow: \"texture2D\",\r\n        sampler2DArrayShadow: \"texture2DArray\",\r\n        samplerCube: \"textureCube\",\r\n        samplerCubeArray: \"textureCubeArray\",\r\n        sampler3D: \"texture3D\",\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected static _GpuTextureViewDimensionByWebGPUTextureType: { [key: string]: GPUTextureViewDimension } = {\r\n        textureCube: WebGPUConstants.TextureViewDimension.Cube,\r\n        textureCubeArray: WebGPUConstants.TextureViewDimension.CubeArray,\r\n        texture2D: WebGPUConstants.TextureViewDimension.E2d,\r\n        texture2DArray: WebGPUConstants.TextureViewDimension.E2dArray,\r\n        texture3D: WebGPUConstants.TextureViewDimension.E3d,\r\n    };\r\n\r\n    // if the webgl sampler type is not listed in this array, \"sampler\" is taken by default\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected static _SamplerTypeByWebGLSamplerType: { [key: string]: string } = {\r\n        sampler2DShadow: \"samplerShadow\",\r\n        sampler2DArrayShadow: \"samplerShadow\",\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected static _IsComparisonSamplerByWebGPUSamplerType: { [key: string]: boolean } = {\r\n        samplerShadow: true,\r\n        samplerArrayShadow: true,\r\n        sampler: false,\r\n    };\r\n\r\n    public shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    protected _webgpuProcessingContext: WebGPUShaderProcessingContext;\r\n\r\n    protected abstract _getArraySize(name: string, type: string, preProcessors: { [key: string]: string }): [string, string, number];\r\n    protected abstract _generateLeftOverUBOCode(name: string, uniformBufferDescription: WebGPUBufferDescription): string;\r\n\r\n    protected _addUniformToLeftOverUBO(name: string, uniformType: string, preProcessors: { [key: string]: string }): void {\r\n        let length: number;\r\n\r\n        [name, uniformType, length] = this._getArraySize(name, uniformType, preProcessors);\r\n\r\n        for (let i = 0; i < this._webgpuProcessingContext.leftOverUniforms.length; i++) {\r\n            if (this._webgpuProcessingContext.leftOverUniforms[i].name === name) {\r\n                return;\r\n            }\r\n        }\r\n\r\n        this._webgpuProcessingContext.leftOverUniforms.push({\r\n            name,\r\n            type: uniformType,\r\n            length,\r\n        });\r\n    }\r\n\r\n    protected _buildLeftOverUBO(): string {\r\n        if (!this._webgpuProcessingContext.leftOverUniforms.length) {\r\n            return \"\";\r\n        }\r\n        const name = WebGPUShaderProcessor.LeftOvertUBOName;\r\n        let availableUBO = this._webgpuProcessingContext.availableBuffers[name];\r\n        if (!availableUBO) {\r\n            availableUBO = {\r\n                binding: this._webgpuProcessingContext.getNextFreeUBOBinding(),\r\n            };\r\n            this._webgpuProcessingContext.availableBuffers[name] = availableUBO;\r\n            this._addBufferBindingDescription(name, availableUBO, WebGPUConstants.BufferBindingType.Uniform, true);\r\n            this._addBufferBindingDescription(name, availableUBO, WebGPUConstants.BufferBindingType.Uniform, false);\r\n        }\r\n\r\n        return this._generateLeftOverUBOCode(name, availableUBO);\r\n    }\r\n\r\n    protected _collectBindingNames(): void {\r\n        // collect all the binding names for faster processing in WebGPUCacheBindGroup\r\n        for (let i = 0; i < this._webgpuProcessingContext.bindGroupLayoutEntries.length; i++) {\r\n            const setDefinition = this._webgpuProcessingContext.bindGroupLayoutEntries[i];\r\n            if (setDefinition === undefined) {\r\n                this._webgpuProcessingContext.bindGroupLayoutEntries[i] = [];\r\n                continue;\r\n            }\r\n            for (let j = 0; j < setDefinition.length; j++) {\r\n                const entry = this._webgpuProcessingContext.bindGroupLayoutEntries[i][j];\r\n                const name = this._webgpuProcessingContext.bindGroupLayoutEntryInfo[i][entry.binding].name;\r\n                const nameInArrayOfTexture = this._webgpuProcessingContext.bindGroupLayoutEntryInfo[i][entry.binding].nameInArrayOfTexture;\r\n                if (entry) {\r\n                    if (entry.texture || entry.externalTexture || entry.storageTexture) {\r\n                        this._webgpuProcessingContext.textureNames.push(nameInArrayOfTexture!);\r\n                    } else if (entry.sampler) {\r\n                        this._webgpuProcessingContext.samplerNames.push(name);\r\n                    } else if (entry.buffer) {\r\n                        this._webgpuProcessingContext.bufferNames.push(name);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _preCreateBindGroupEntries(): void {\r\n        const bindGroupEntries = this._webgpuProcessingContext.bindGroupEntries;\r\n\r\n        for (let i = 0; i < this._webgpuProcessingContext.bindGroupLayoutEntries.length; i++) {\r\n            const setDefinition = this._webgpuProcessingContext.bindGroupLayoutEntries[i];\r\n\r\n            const entries: GPUBindGroupEntry[] = [];\r\n            for (let j = 0; j < setDefinition.length; j++) {\r\n                const entry = this._webgpuProcessingContext.bindGroupLayoutEntries[i][j];\r\n\r\n                if (entry.sampler || entry.texture || entry.storageTexture || entry.externalTexture) {\r\n                    entries.push({\r\n                        binding: entry.binding,\r\n                        resource: undefined as any,\r\n                    });\r\n                } else if (entry.buffer) {\r\n                    entries.push({\r\n                        binding: entry.binding,\r\n                        resource: {\r\n                            buffer: undefined as any,\r\n                            offset: 0,\r\n                            size: 0,\r\n                        },\r\n                    });\r\n                }\r\n            }\r\n\r\n            bindGroupEntries[i] = entries;\r\n        }\r\n    }\r\n\r\n    protected _addTextureBindingDescription(\r\n        name: string,\r\n        textureInfo: WebGPUTextureDescription,\r\n        textureIndex: number,\r\n        dimension: Nullable<GPUTextureViewDimension>,\r\n        format: Nullable<GPUTextureFormat>,\r\n        isVertex: boolean,\r\n        storageTextureAccess: GPUStorageTextureAccess = WebGPUConstants.StorageTextureAccess.WriteOnly\r\n    ): void {\r\n        // eslint-disable-next-line prefer-const\r\n        let { groupIndex, bindingIndex } = textureInfo.textures[textureIndex];\r\n        if (!this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex]) {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex] = [];\r\n            this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex] = [];\r\n        }\r\n        if (!this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex]) {\r\n            let len;\r\n            if (dimension === null) {\r\n                len = this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex].push({\r\n                    binding: bindingIndex,\r\n                    visibility: 0,\r\n                    externalTexture: {},\r\n                });\r\n            } else if (format) {\r\n                len = this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex].push({\r\n                    binding: bindingIndex,\r\n                    visibility: 0,\r\n                    storageTexture: {\r\n                        access: storageTextureAccess,\r\n                        format,\r\n                        viewDimension: dimension,\r\n                    },\r\n                });\r\n            } else {\r\n                len = this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex].push({\r\n                    binding: bindingIndex,\r\n                    visibility: 0,\r\n                    texture: {\r\n                        sampleType: textureInfo.sampleType,\r\n                        viewDimension: dimension,\r\n                        multisampled: false,\r\n                    },\r\n                });\r\n            }\r\n            const textureName = textureInfo.isTextureArray ? name + textureIndex : name;\r\n            this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex] = { name, index: len - 1, nameInArrayOfTexture: textureName };\r\n        }\r\n\r\n        bindingIndex = this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex].index;\r\n        if (isVertex) {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex][bindingIndex].visibility |= WebGPUConstants.ShaderStage.Vertex;\r\n        } else {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex][bindingIndex].visibility |= WebGPUConstants.ShaderStage.Fragment;\r\n        }\r\n    }\r\n\r\n    protected _addSamplerBindingDescription(name: string, samplerInfo: WebGPUSamplerDescription, isVertex: boolean): void {\r\n        // eslint-disable-next-line prefer-const\r\n        let { groupIndex, bindingIndex } = samplerInfo.binding;\r\n        if (!this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex]) {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex] = [];\r\n            this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex] = [];\r\n        }\r\n        if (!this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex]) {\r\n            const len = this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex].push({\r\n                binding: bindingIndex,\r\n                visibility: 0,\r\n                sampler: {\r\n                    type: samplerInfo.type,\r\n                },\r\n            });\r\n            this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex] = { name, index: len - 1 };\r\n        }\r\n\r\n        bindingIndex = this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex].index;\r\n        if (isVertex) {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex][bindingIndex].visibility |= WebGPUConstants.ShaderStage.Vertex;\r\n        } else {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex][bindingIndex].visibility |= WebGPUConstants.ShaderStage.Fragment;\r\n        }\r\n    }\r\n\r\n    protected _addBufferBindingDescription(name: string, uniformBufferInfo: WebGPUBufferDescription, bufferType: GPUBufferBindingType, isVertex: boolean): void {\r\n        // eslint-disable-next-line prefer-const\r\n        let { groupIndex, bindingIndex } = uniformBufferInfo.binding;\r\n        if (!this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex]) {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex] = [];\r\n            this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex] = [];\r\n        }\r\n        if (!this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex]) {\r\n            const len = this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex].push({\r\n                binding: bindingIndex,\r\n                visibility: 0,\r\n                buffer: {\r\n                    type: bufferType,\r\n                },\r\n            });\r\n            this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex] = { name, index: len - 1 };\r\n        }\r\n\r\n        bindingIndex = this._webgpuProcessingContext.bindGroupLayoutEntryInfo[groupIndex][bindingIndex].index;\r\n        if (isVertex) {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex][bindingIndex].visibility |= WebGPUConstants.ShaderStage.Vertex;\r\n        } else {\r\n            this._webgpuProcessingContext.bindGroupLayoutEntries[groupIndex][bindingIndex].visibility |= WebGPUConstants.ShaderStage.Fragment;\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { type IPipelineContext } from \"../IPipelineContext\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { type Effect } from \"../../Materials/effect\";\r\nimport { type WebGPUShaderProcessingContext } from \"./webgpuShaderProcessingContext\";\r\nimport { UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { type IMatrixLike, type IVector2Like, type IVector3Like, type IVector4Like, type IColor3Like, type IColor4Like, type IQuaternionLike } from \"../../Maths/math.like\";\r\nimport { WebGPUShaderProcessor } from \"./webgpuShaderProcessor\";\r\nimport { type AbstractEngine } from \"../abstractEngine\";\r\n\r\n/** @internal */\r\nexport interface IWebGPURenderPipelineStageDescriptor {\r\n    vertexStage: GPUProgrammableStage;\r\n    fragmentStage?: GPUProgrammableStage;\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUPipelineContext implements IPipelineContext {\r\n    public engine: WebGPUEngine;\r\n\r\n    public shaderProcessingContext: WebGPUShaderProcessingContext;\r\n\r\n    protected _leftOverUniformsByName: { [name: string]: string };\r\n\r\n    // Property used to handle vertex buffers with int values when the shader code expect float values.\r\n    public vertexBufferKindToType: { [kind: string]: number };\r\n\r\n    public sources: {\r\n        vertex: string;\r\n        fragment: string;\r\n        rawVertex: string;\r\n        rawFragment: string;\r\n    };\r\n\r\n    public stages: Nullable<IWebGPURenderPipelineStageDescriptor>;\r\n\r\n    // The field is indexed by textureState. See @WebGPUMaterialContext.textureState for more information.\r\n    public bindGroupLayouts: { [textureState: number]: GPUBindGroupLayout[] } = {};\r\n\r\n    /**\r\n     * Stores the left-over uniform buffer\r\n     */\r\n    public uniformBuffer: Nullable<UniformBuffer>;\r\n\r\n    // Default implementation.\r\n    public onCompiled?: () => void;\r\n\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public get isAsync() {\r\n        return false;\r\n    }\r\n\r\n    public get isReady(): boolean {\r\n        if (this.stages) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _name: string;\r\n\r\n    constructor(shaderProcessingContext: WebGPUShaderProcessingContext, engine: WebGPUEngine) {\r\n        this._name = \"unnamed\";\r\n        this.shaderProcessingContext = shaderProcessingContext;\r\n        this._leftOverUniformsByName = {};\r\n        this.engine = engine;\r\n        this.vertexBufferKindToType = {};\r\n    }\r\n\r\n    public _handlesSpectorRebuildCallback(): void {\r\n        // Nothing to do yet for spector.\r\n    }\r\n\r\n    public _fillEffectInformation(\r\n        effect: Effect,\r\n        uniformBuffersNames: { [key: string]: number },\r\n        uniformsNames: string[],\r\n        uniforms: { [key: string]: Nullable<WebGLUniformLocation> },\r\n        samplerList: string[],\r\n        samplers: { [key: string]: number },\r\n        attributesNames: string[],\r\n        attributes: number[]\r\n    ) {\r\n        const engine = this.engine;\r\n\r\n        if (engine._doNotHandleContextLost) {\r\n            effect._fragmentSourceCode = \"\";\r\n            effect._vertexSourceCode = \"\";\r\n        }\r\n\r\n        const foundSamplers = this.shaderProcessingContext.availableTextures;\r\n        let index: number;\r\n        for (index = 0; index < samplerList.length; index++) {\r\n            const name = samplerList[index];\r\n            const sampler = foundSamplers[samplerList[index]];\r\n\r\n            if (sampler == null || sampler == undefined) {\r\n                samplerList.splice(index, 1);\r\n                index--;\r\n            } else {\r\n                samplers[name] = index;\r\n            }\r\n        }\r\n\r\n        for (const attr of engine.getAttributes(this, attributesNames)) {\r\n            attributes.push(attr);\r\n        }\r\n\r\n        // Build the uniform layout for the left over uniforms.\r\n        this.buildUniformLayout();\r\n\r\n        const attributeNamesFromEffect: string[] = [];\r\n        const attributeLocationsFromEffect: number[] = [];\r\n        for (index = 0; index < attributesNames.length; index++) {\r\n            const location = attributes[index];\r\n            if (location >= 0) {\r\n                attributeNamesFromEffect.push(attributesNames[index]);\r\n                attributeLocationsFromEffect.push(location);\r\n            }\r\n        }\r\n        this.shaderProcessingContext.attributeNamesFromEffect = attributeNamesFromEffect;\r\n        this.shaderProcessingContext.attributeLocationsFromEffect = attributeLocationsFromEffect;\r\n    }\r\n\r\n    /** @internal */\r\n    /**\r\n     * Build the uniform buffer used in the material.\r\n     */\r\n    public buildUniformLayout(): void {\r\n        if (!this.shaderProcessingContext.leftOverUniforms.length) {\r\n            return;\r\n        }\r\n\r\n        this.uniformBuffer?.dispose();\r\n        this.uniformBuffer = new UniformBuffer(this.engine, undefined, undefined, \"leftOver-\" + this._name);\r\n\r\n        for (const leftOverUniform of this.shaderProcessingContext.leftOverUniforms) {\r\n            const type = leftOverUniform.type.replace(/^(.*?)(<.*>)?$/, \"$1\");\r\n            const size = WebGPUShaderProcessor.UniformSizes[type];\r\n            this.uniformBuffer.addUniform(leftOverUniform.name, size, leftOverUniform.length);\r\n            this._leftOverUniformsByName[leftOverUniform.name] = leftOverUniform.type;\r\n        }\r\n\r\n        this.uniformBuffer.create();\r\n    }\r\n\r\n    public setEngine(engine: AbstractEngine): void {\r\n        this.engine = engine as WebGPUEngine;\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources.\r\n     **/\r\n    public dispose() {\r\n        if (this.uniformBuffer) {\r\n            this.uniformBuffer.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     */\r\n    public setInt(uniformName: string, value: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateInt(uniformName, value);\r\n    }\r\n\r\n    /**\r\n     * Sets an int2 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int2.\r\n     * @param y Second int in int2.\r\n     */\r\n    public setInt2(uniformName: string, x: number, y: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateInt2(uniformName, x, y);\r\n    }\r\n\r\n    /**\r\n     * Sets an int3 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int3.\r\n     * @param y Second int in int3.\r\n     * @param z Third int in int3.\r\n     */\r\n    public setInt3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateInt3(uniformName, x, y, z);\r\n    }\r\n\r\n    /**\r\n     * Sets an int4 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First int in int4.\r\n     * @param y Second int in int4.\r\n     * @param z Third int in int4.\r\n     * @param w Fourth int in int4.\r\n     */\r\n    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateInt4(uniformName, x, y, z, w);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray(uniformName: string, array: Int32Array): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray2(uniformName: string, array: Int32Array): void {\r\n        this.setIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray3(uniformName: string, array: Int32Array): void {\r\n        this.setIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setIntArray4(uniformName: string, array: Int32Array): void {\r\n        this.setIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned integer value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value Value to be set.\r\n     */\r\n    public setUInt(uniformName: string, value: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateUInt(uniformName, value);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int2 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint2.\r\n     * @param y Second unsigned int in uint2.\r\n     */\r\n    public setUInt2(uniformName: string, x: number, y: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateUInt2(uniformName, x, y);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int3 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint3.\r\n     * @param y Second unsigned int in uint3.\r\n     * @param z Third unsigned int in uint3.\r\n     */\r\n    public setUInt3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateUInt3(uniformName, x, y, z);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int4 value on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First unsigned int in uint4.\r\n     * @param y Second unsigned int in uint4.\r\n     * @param z Third unsigned int in uint4.\r\n     * @param w Fourth unsigned int in uint4.\r\n     */\r\n    public setUInt4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateUInt4(uniformName, x, y, z, w);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray(uniformName: string, array: Uint32Array): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateUIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray2(uniformName: string, array: Uint32Array): void {\r\n        this.setUIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray3(uniformName: string, array: Uint32Array): void {\r\n        this.setUIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an unsigned int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setUIntArray4(uniformName: string, array: Uint32Array): void {\r\n        this.setUIntArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray(uniformName: string, array: number[]): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray2(uniformName: string, array: number[]): void {\r\n        this.setArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray3(uniformName: string, array: number[]): void {\r\n        this.setArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)\r\n     * @param uniformName Name of the variable.\r\n     * @param array array to be set.\r\n     */\r\n    public setArray4(uniformName: string, array: number[]): void {\r\n        this.setArray(uniformName, array);\r\n    }\r\n\r\n    /**\r\n     * Sets matrices on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrices matrices to be set.\r\n     */\r\n    public setMatrices(uniformName: string, matrices: Float32Array): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateMatrices(uniformName, matrices);\r\n    }\r\n\r\n    /**\r\n     * Sets matrix on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix(uniformName: string, matrix: IMatrixLike): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateMatrix(uniformName, matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a 3x3 matrix on a uniform variable. (Specified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix3x3(uniformName: string, matrix: Float32Array): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateMatrix3x3(uniformName, matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a 2x2 matrix on a uniform variable. (Specified as [1,2,3,4] will result in [1,2][3,4] matrix)\r\n     * @param uniformName Name of the variable.\r\n     * @param matrix matrix to be set.\r\n     */\r\n    public setMatrix2x2(uniformName: string, matrix: Float32Array): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateMatrix2x2(uniformName, matrix);\r\n    }\r\n\r\n    /**\r\n     * Sets a float on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param value value to be set.\r\n     */\r\n    public setFloat(uniformName: string, value: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateFloat(uniformName, value);\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector2 vector2 to be set.\r\n     */\r\n    public setVector2(uniformName: string, vector2: IVector2Like): void {\r\n        this.setFloat2(uniformName, vector2.x, vector2.y);\r\n    }\r\n\r\n    /**\r\n     * Sets a float2 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float2.\r\n     * @param y Second float in float2.\r\n     */\r\n    public setFloat2(uniformName: string, x: number, y: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateFloat2(uniformName, x, y);\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector3 Value to be set.\r\n     */\r\n    public setVector3(uniformName: string, vector3: IVector3Like): void {\r\n        this.setFloat3(uniformName, vector3.x, vector3.y, vector3.z);\r\n    }\r\n\r\n    /**\r\n     * Sets a float3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float3.\r\n     * @param y Second float in float3.\r\n     * @param z Third float in float3.\r\n     */\r\n    public setFloat3(uniformName: string, x: number, y: number, z: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateFloat3(uniformName, x, y, z);\r\n    }\r\n\r\n    /**\r\n     * Sets a Vector4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param vector4 Value to be set.\r\n     */\r\n    public setVector4(uniformName: string, vector4: IVector4Like): void {\r\n        this.setFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w);\r\n    }\r\n\r\n    /**\r\n     * Sets a Quaternion on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param quaternion Value to be set.\r\n     */\r\n    public setQuaternion(uniformName: string, quaternion: IQuaternionLike): void {\r\n        this.setFloat4(uniformName, quaternion.x, quaternion.y, quaternion.z, quaternion.w);\r\n    }\r\n\r\n    /**\r\n     * Sets a float4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param x First float in float4.\r\n     * @param y Second float in float4.\r\n     * @param z Third float in float4.\r\n     * @param w Fourth float in float4.\r\n     */\r\n    public setFloat4(uniformName: string, x: number, y: number, z: number, w: number): void {\r\n        if (!this.uniformBuffer || !this._leftOverUniformsByName[uniformName]) {\r\n            return;\r\n        }\r\n        this.uniformBuffer.updateFloat4(uniformName, x, y, z, w);\r\n    }\r\n\r\n    /**\r\n     * Sets a Color3 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     */\r\n    public setColor3(uniformName: string, color3: IColor3Like): void {\r\n        this.setFloat3(uniformName, color3.r, color3.g, color3.b);\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable.\r\n     * @param uniformName Name of the variable.\r\n     * @param color3 Value to be set.\r\n     * @param alpha Alpha value to be set.\r\n     */\r\n    public setColor4(uniformName: string, color3: IColor3Like, alpha: number): void {\r\n        this.setFloat4(uniformName, color3.r, color3.g, color3.b, alpha);\r\n    }\r\n\r\n    /**\r\n     * Sets a Color4 on a uniform variable\r\n     * @param uniformName defines the name of the variable\r\n     * @param color4 defines the value to be set\r\n     */\r\n    public setDirectColor4(uniformName: string, color4: IColor4Like): void {\r\n        this.setFloat4(uniformName, color4.r, color4.g, color4.b, color4.a);\r\n    }\r\n\r\n    public _getVertexShaderCode(): string | null {\r\n        return this.sources?.vertex;\r\n    }\r\n\r\n    public _getFragmentShaderCode(): string | null {\r\n        return this.sources?.fragment;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { type ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\nimport { type _IShaderProcessingContext } from \"../Processors/shaderProcessingOptions\";\r\n\r\nconst MaxGroups = 4;\r\nconst MaxBindingsPerGroup = 1 << 16;\r\n\r\n// all types not listed are assumed to consume 1 location\r\nconst TypeToLocationSize: { [key: string]: number } = {\r\n    // GLSL types\r\n    mat2: 2,\r\n    mat3: 3,\r\n    mat4: 4,\r\n\r\n    // WGSL types\r\n    mat2x2: 2,\r\n    mat3x3: 3,\r\n    mat4x4: 4,\r\n};\r\n\r\n/** @internal */\r\nexport interface WebGPUBindingInfo {\r\n    groupIndex: number;\r\n    bindingIndex: number;\r\n}\r\n\r\n/** @internal */\r\nexport interface WebGPUTextureDescription {\r\n    autoBindSampler?: boolean;\r\n    isTextureArray: boolean;\r\n    isStorageTexture: boolean;\r\n    storageTextureAccess?: GPUStorageTextureAccess; // \"write-only\", \"read-only\", or \"read-write\"\r\n    textures: Array<WebGPUBindingInfo>;\r\n    sampleType?: GPUTextureSampleType; // not used if the texture is a storage texture\r\n}\r\n\r\n/** @internal */\r\nexport interface WebGPUSamplerDescription {\r\n    binding: WebGPUBindingInfo;\r\n    type: GPUSamplerBindingType;\r\n}\r\n\r\n/** @internal */\r\nexport interface WebGPUBufferDescription {\r\n    binding: WebGPUBindingInfo;\r\n}\r\n\r\n/** @internal */\r\nexport interface WebGPUBindGroupLayoutEntryInfo {\r\n    name: string;\r\n    index: number; // index of the entry (GPUBindGroupLayoutEntry) in the bindGroupLayoutEntries[group] array\r\n    nameInArrayOfTexture?: string; // something like texture0, texture1, ... if texture is an array, else same thing as \"name\"\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class WebGPUShaderProcessingContext implements _IShaderProcessingContext {\r\n    /** @internal */\r\n    public static _SimplifiedKnownBindings = true; // if true, use only group=0,binding=0 as a known group/binding for the Scene ubo and use group=1,binding=X for all other bindings\r\n    // if false, see _KnownUBOs for the known groups/bindings used\r\n\r\n    protected static _SimplifiedKnownUBOs: { [key: string]: WebGPUBufferDescription } = {\r\n        Scene: { binding: { groupIndex: 0, bindingIndex: 0 } },\r\n        Light0: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light1: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light2: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light3: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light4: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light5: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light6: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light7: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light8: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light9: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light10: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light11: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light12: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light13: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light14: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light15: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light16: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light17: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light18: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light19: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light20: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light21: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light22: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light23: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light24: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light25: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light26: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light27: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light28: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light29: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light30: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Light31: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Material: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Mesh: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n        Internals: { binding: { groupIndex: -1, bindingIndex: -1 } },\r\n    };\r\n\r\n    protected static _KnownUBOs: { [key: string]: WebGPUBufferDescription } = {\r\n        Scene: { binding: { groupIndex: 0, bindingIndex: 0 } },\r\n\r\n        Light0: { binding: { groupIndex: 1, bindingIndex: 0 } },\r\n        Light1: { binding: { groupIndex: 1, bindingIndex: 1 } },\r\n        Light2: { binding: { groupIndex: 1, bindingIndex: 2 } },\r\n        Light3: { binding: { groupIndex: 1, bindingIndex: 3 } },\r\n        Light4: { binding: { groupIndex: 1, bindingIndex: 4 } },\r\n        Light5: { binding: { groupIndex: 1, bindingIndex: 5 } },\r\n        Light6: { binding: { groupIndex: 1, bindingIndex: 6 } },\r\n        Light7: { binding: { groupIndex: 1, bindingIndex: 7 } },\r\n        Light8: { binding: { groupIndex: 1, bindingIndex: 8 } },\r\n        Light9: { binding: { groupIndex: 1, bindingIndex: 9 } },\r\n        Light10: { binding: { groupIndex: 1, bindingIndex: 10 } },\r\n        Light11: { binding: { groupIndex: 1, bindingIndex: 11 } },\r\n        Light12: { binding: { groupIndex: 1, bindingIndex: 12 } },\r\n        Light13: { binding: { groupIndex: 1, bindingIndex: 13 } },\r\n        Light14: { binding: { groupIndex: 1, bindingIndex: 14 } },\r\n        Light15: { binding: { groupIndex: 1, bindingIndex: 15 } },\r\n        Light16: { binding: { groupIndex: 1, bindingIndex: 16 } },\r\n        Light17: { binding: { groupIndex: 1, bindingIndex: 17 } },\r\n        Light18: { binding: { groupIndex: 1, bindingIndex: 18 } },\r\n        Light19: { binding: { groupIndex: 1, bindingIndex: 19 } },\r\n        Light20: { binding: { groupIndex: 1, bindingIndex: 20 } },\r\n        Light21: { binding: { groupIndex: 1, bindingIndex: 21 } },\r\n        Light22: { binding: { groupIndex: 1, bindingIndex: 22 } },\r\n        Light23: { binding: { groupIndex: 1, bindingIndex: 23 } },\r\n        Light24: { binding: { groupIndex: 1, bindingIndex: 24 } },\r\n        Light25: { binding: { groupIndex: 1, bindingIndex: 25 } },\r\n        Light26: { binding: { groupIndex: 1, bindingIndex: 26 } },\r\n        Light27: { binding: { groupIndex: 1, bindingIndex: 27 } },\r\n        Light28: { binding: { groupIndex: 1, bindingIndex: 28 } },\r\n        Light29: { binding: { groupIndex: 1, bindingIndex: 29 } },\r\n        Light30: { binding: { groupIndex: 1, bindingIndex: 30 } },\r\n        Light31: { binding: { groupIndex: 1, bindingIndex: 31 } },\r\n\r\n        Material: { binding: { groupIndex: 2, bindingIndex: 0 } },\r\n        Mesh: { binding: { groupIndex: 2, bindingIndex: 1 } },\r\n        Internals: { binding: { groupIndex: 2, bindingIndex: 2 } },\r\n    };\r\n\r\n    public static get KnownUBOs() {\r\n        return WebGPUShaderProcessingContext._SimplifiedKnownBindings ? WebGPUShaderProcessingContext._SimplifiedKnownUBOs : WebGPUShaderProcessingContext._KnownUBOs;\r\n    }\r\n\r\n    public shaderLanguage: ShaderLanguage;\r\n\r\n    public uboNextBindingIndex: number;\r\n    public freeGroupIndex: number;\r\n    public freeBindingIndex: number;\r\n\r\n    public availableVaryings: { [key: string]: number };\r\n    public availableAttributes: { [key: string]: number };\r\n    public availableBuffers: { [key: string]: WebGPUBufferDescription };\r\n    public availableTextures: { [key: string]: WebGPUTextureDescription };\r\n    public availableSamplers: { [key: string]: WebGPUSamplerDescription };\r\n\r\n    public leftOverUniforms: { name: string; type: string; length: number }[];\r\n\r\n    public orderedAttributes: string[];\r\n    public bindGroupLayoutEntries: GPUBindGroupLayoutEntry[][];\r\n    public bindGroupLayoutEntryInfo: WebGPUBindGroupLayoutEntryInfo[][];\r\n    public bindGroupEntries: GPUBindGroupEntry[][];\r\n    public bufferNames: string[]; // list of all uniform/storage buffer names used in the shader\r\n    public textureNames: string[]; // list of all texture names used in the shader\r\n    public samplerNames: string[]; // list of all sampler names used in the shader\r\n    public attributeNamesFromEffect: string[];\r\n    public attributeLocationsFromEffect: number[];\r\n\r\n    public vertexBufferKindToNumberOfComponents: { [kind: string]: number } = {};\r\n\r\n    private _attributeNextLocation: number;\r\n    private _varyingNextLocation: number;\r\n\r\n    constructor(shaderLanguage: ShaderLanguage, pureMode = false) {\r\n        this.shaderLanguage = shaderLanguage;\r\n\r\n        this._attributeNextLocation = 0;\r\n        this._varyingNextLocation = 0;\r\n        this.freeGroupIndex = 0;\r\n        this.freeBindingIndex = 0;\r\n\r\n        this.availableVaryings = {};\r\n        this.availableAttributes = {};\r\n        this.availableBuffers = {};\r\n        this.availableTextures = {};\r\n        this.availableSamplers = {};\r\n\r\n        this.orderedAttributes = [];\r\n        this.bindGroupLayoutEntries = [];\r\n        this.bindGroupLayoutEntryInfo = [];\r\n        this.bindGroupEntries = [];\r\n        this.bufferNames = [];\r\n        this.textureNames = [];\r\n        this.samplerNames = [];\r\n\r\n        this.leftOverUniforms = [];\r\n\r\n        if (!pureMode) {\r\n            this._findStartingGroupBinding();\r\n        }\r\n    }\r\n\r\n    private _findStartingGroupBinding(): void {\r\n        const knownUBOs = WebGPUShaderProcessingContext.KnownUBOs;\r\n\r\n        const groups: number[] = [];\r\n        for (const name in knownUBOs) {\r\n            const binding = knownUBOs[name].binding;\r\n            if (binding.groupIndex === -1) {\r\n                continue;\r\n            }\r\n            if (groups[binding.groupIndex] === undefined) {\r\n                groups[binding.groupIndex] = binding.bindingIndex;\r\n            } else {\r\n                groups[binding.groupIndex] = Math.max(groups[binding.groupIndex], binding.bindingIndex);\r\n            }\r\n        }\r\n\r\n        this.freeGroupIndex = groups.length - 1;\r\n        if (this.freeGroupIndex === 0) {\r\n            this.freeGroupIndex++;\r\n            this.freeBindingIndex = 0;\r\n        } else {\r\n            this.freeBindingIndex = groups[groups.length - 1] + 1;\r\n        }\r\n    }\r\n\r\n    public getAttributeNextLocation(dataType: string, arrayLength: number = 0): number {\r\n        const index = this._attributeNextLocation;\r\n\r\n        this._attributeNextLocation += (TypeToLocationSize[dataType] ?? 1) * (arrayLength || 1);\r\n\r\n        return index;\r\n    }\r\n\r\n    public getVaryingNextLocation(dataType: string, arrayLength: number = 0): number {\r\n        const index = this._varyingNextLocation;\r\n\r\n        this._varyingNextLocation += (TypeToLocationSize[dataType] ?? 1) * (arrayLength || 1);\r\n\r\n        return index;\r\n    }\r\n\r\n    public getNextFreeUBOBinding() {\r\n        return this._getNextFreeBinding(1);\r\n    }\r\n\r\n    private _getNextFreeBinding(bindingCount: number) {\r\n        if (this.freeBindingIndex > MaxBindingsPerGroup - bindingCount) {\r\n            this.freeGroupIndex++;\r\n            this.freeBindingIndex = 0;\r\n        }\r\n\r\n        if (this.freeGroupIndex === MaxGroups) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Too many textures or UBOs have been declared and it is not supported in WebGPU.\";\r\n        }\r\n\r\n        const returnValue = {\r\n            groupIndex: this.freeGroupIndex,\r\n            bindingIndex: this.freeBindingIndex,\r\n        };\r\n\r\n        this.freeBindingIndex += bindingCount;\r\n\r\n        return returnValue;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { type Nullable } from \"../../types\";\r\nimport { type _IShaderProcessingContext } from \"../Processors/shaderProcessingOptions\";\r\nimport { type WebGPUBufferDescription, WebGPUShaderProcessingContext } from \"./webgpuShaderProcessingContext\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { WebGPUShaderProcessor } from \"./webgpuShaderProcessor\";\r\nimport { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\nimport { InjectStartingAndEndingCode } from \"../../Misc/codeStringParsingTools\";\r\nimport { Constants } from \"../constants\";\r\n\r\n/** @internal */\r\nexport class WebGPUShaderProcessorGLSL extends WebGPUShaderProcessor {\r\n    protected _missingVaryings: Array<string> = [];\r\n    protected _textureArrayProcessing: Array<string> = [];\r\n    protected _preProcessors: { [key: string]: string };\r\n    protected _vertexIsGLES3: boolean = false;\r\n    protected _fragmentIsGLES3: boolean = false;\r\n\r\n    public override shaderLanguage = ShaderLanguage.GLSL;\r\n    public parseGLES3 = true;\r\n    public attributeKeywordName: string | undefined;\r\n    public varyingVertexKeywordName: string | undefined;\r\n    public varyingFragmentKeywordName: string | undefined;\r\n\r\n    protected _getArraySize(name: string, type: string, preProcessors: { [key: string]: string }): [string, string, number] {\r\n        let length = 0;\r\n        const startArray = name.indexOf(\"[\");\r\n        const endArray = name.indexOf(\"]\");\r\n        if (startArray > 0 && endArray > 0) {\r\n            const lengthInString = name.substring(startArray + 1, endArray);\r\n            length = +lengthInString;\r\n            if (isNaN(length)) {\r\n                length = +preProcessors[lengthInString.trim()];\r\n            }\r\n            name = name.substring(0, startArray);\r\n        }\r\n        return [name, type, length];\r\n    }\r\n\r\n    public initializeShaders(processingContext: Nullable<_IShaderProcessingContext>): void {\r\n        this._webgpuProcessingContext = processingContext as WebGPUShaderProcessingContext;\r\n\r\n        this._missingVaryings.length = 0;\r\n        this._textureArrayProcessing.length = 0;\r\n        this.attributeKeywordName = undefined;\r\n        this.varyingVertexKeywordName = undefined;\r\n        this.varyingFragmentKeywordName = undefined;\r\n    }\r\n\r\n    public preProcessShaderCode(code: string, isFragment: boolean): string {\r\n        const ubDeclaration = `// Internals UBO\\nuniform ${WebGPUShaderProcessor.InternalsUBOName} {\\nfloat yFactor_;\\nfloat textureOutputHeight_;\\n};\\n`;\r\n        const alreadyInjected = code.indexOf(\"// Internals UBO\") !== -1;\r\n\r\n        if (isFragment) {\r\n            this._fragmentIsGLES3 = code.indexOf(\"#version 3\") !== -1;\r\n            if (this._fragmentIsGLES3) {\r\n                this.varyingFragmentKeywordName = \"in\";\r\n            }\r\n            return alreadyInjected ? code : ubDeclaration + \"##INJECTCODE##\\n\" + code;\r\n        }\r\n\r\n        this._vertexIsGLES3 = code.indexOf(\"#version 3\") !== -1;\r\n        if (this._vertexIsGLES3) {\r\n            this.attributeKeywordName = \"in\";\r\n            this.varyingVertexKeywordName = \"out\";\r\n        }\r\n        return alreadyInjected ? code : ubDeclaration + code;\r\n    }\r\n\r\n    public varyingCheck(varying: string, isFragment: boolean) {\r\n        const outRegex = /(flat\\s)?\\s*\\bout\\b/;\r\n        const inRegex = /(flat\\s)?\\s*\\bin\\b/;\r\n        const varyingRegex = /(flat\\s)?\\s*\\bvarying\\b/;\r\n\r\n        const regex = isFragment && this._fragmentIsGLES3 ? inRegex : !isFragment && this._vertexIsGLES3 ? outRegex : varyingRegex;\r\n\r\n        return regex.test(varying);\r\n    }\r\n\r\n    public varyingProcessor(varying: string, isFragment: boolean, preProcessors: { [key: string]: string }) {\r\n        this._preProcessors = preProcessors;\r\n\r\n        const outRegex = /\\s*(flat)?\\s*out\\s+(?:(?:highp)?|(?:lowp)?)\\s*(\\S+)\\s+(\\S+)\\s*;/gm;\r\n        const inRegex = /\\s*(flat)?\\s*in\\s+(?:(?:highp)?|(?:lowp)?)\\s*(\\S+)\\s+(\\S+)\\s*;/gm;\r\n        const varyingRegex = /\\s*(flat)?\\s*varying\\s+(?:(?:highp)?|(?:lowp)?)\\s*(\\S+)\\s+(\\S+)\\s*;/gm;\r\n\r\n        const regex = isFragment && this._fragmentIsGLES3 ? inRegex : !isFragment && this._vertexIsGLES3 ? outRegex : varyingRegex;\r\n        const match = regex.exec(varying);\r\n        if (match !== null) {\r\n            const interpolationQualifier = match[1] ?? \"\";\r\n            const varyingType = match[2];\r\n            const name = match[3];\r\n            let location: number;\r\n            if (isFragment) {\r\n                location = this._webgpuProcessingContext.availableVaryings[name];\r\n                this._missingVaryings[location] = \"\";\r\n                if (location === undefined) {\r\n                    Logger.Warn(`Invalid fragment shader: The varying named \"${name}\" is not declared in the vertex shader! This declaration will be ignored.`);\r\n                }\r\n            } else {\r\n                location = this._webgpuProcessingContext.getVaryingNextLocation(varyingType, this._getArraySize(name, varyingType, preProcessors)[2]);\r\n                this._webgpuProcessingContext.availableVaryings[name] = location;\r\n                this._missingVaryings[location] = `layout(location = ${location}) ${interpolationQualifier} in ${varyingType} ${name};`;\r\n            }\r\n\r\n            varying = varying.replace(\r\n                match[0],\r\n                location === undefined ? \"\" : `layout(location = ${location}) ${interpolationQualifier} ${isFragment ? \"in\" : \"out\"} ${varyingType} ${name};`\r\n            );\r\n        }\r\n        return varying;\r\n    }\r\n\r\n    public attributeProcessor(attribute: string, preProcessors: { [key: string]: string }) {\r\n        this._preProcessors = preProcessors;\r\n\r\n        const inRegex = /\\s*in\\s+(\\S+)\\s+(\\S+)\\s*;/gm;\r\n        const attribRegex = /\\s*attribute\\s+(\\S+)\\s+(\\S+)\\s*;/gm;\r\n\r\n        const regex = this._vertexIsGLES3 ? inRegex : attribRegex;\r\n        const match = regex.exec(attribute);\r\n        if (match !== null) {\r\n            const attributeType = match[1];\r\n            const name = match[2];\r\n            const location = this._webgpuProcessingContext.getAttributeNextLocation(attributeType, this._getArraySize(name, attributeType, preProcessors)[2]);\r\n\r\n            this._webgpuProcessingContext.availableAttributes[name] = location;\r\n            this._webgpuProcessingContext.orderedAttributes[location] = name;\r\n\r\n            const numComponents = this._webgpuProcessingContext.vertexBufferKindToNumberOfComponents[name];\r\n            if (numComponents !== undefined) {\r\n                // Special case for an int/ivecX vertex buffer that is used as a float/vecX attribute in the shader.\r\n                const newType = numComponents < 0 ? (numComponents === -1 ? \"int\" : \"ivec\" + -numComponents) : numComponents === 1 ? \"uint\" : \"uvec\" + numComponents;\r\n                const newName = `_int_${name}_`;\r\n\r\n                attribute = attribute.replace(match[0], `layout(location = ${location}) in ${newType} ${newName}; ${attributeType} ${name} = ${attributeType}(${newName});`);\r\n            } else {\r\n                attribute = attribute.replace(match[0], `layout(location = ${location}) in ${attributeType} ${name};`);\r\n            }\r\n        }\r\n        return attribute;\r\n    }\r\n\r\n    public uniformProcessor(uniform: string, isFragment: boolean, preProcessors: { [key: string]: string }): string {\r\n        this._preProcessors = preProcessors;\r\n\r\n        const uniformRegex = /\\s*uniform\\s+(?:(?:highp)?|(?:lowp)?)\\s*(\\S+)\\s+(\\S+)\\s*;/gm;\r\n\r\n        const match = uniformRegex.exec(uniform);\r\n        if (match !== null) {\r\n            let uniformType = match[1];\r\n            let name = match[2];\r\n\r\n            if (uniformType.indexOf(\"sampler\") === 0 || uniformType.indexOf(\"sampler\") === 1) {\r\n                let arraySize: number; // 0 means the texture is not declared as an array\r\n\r\n                [name, uniformType, arraySize] = this._getArraySize(name, uniformType, preProcessors);\r\n\r\n                let textureInfo = this._webgpuProcessingContext.availableTextures[name];\r\n                if (!textureInfo) {\r\n                    textureInfo = {\r\n                        autoBindSampler: true,\r\n                        isTextureArray: arraySize > 0,\r\n                        isStorageTexture: false,\r\n                        textures: [],\r\n                        sampleType: WebGPUConstants.TextureSampleType.Float,\r\n                    };\r\n                    for (let i = 0; i < (arraySize || 1); ++i) {\r\n                        textureInfo.textures.push(this._webgpuProcessingContext.getNextFreeUBOBinding());\r\n                    }\r\n                }\r\n\r\n                const samplerType = WebGPUShaderProcessor._SamplerTypeByWebGLSamplerType[uniformType] ?? \"sampler\";\r\n                const isComparisonSampler = !!WebGPUShaderProcessor._IsComparisonSamplerByWebGPUSamplerType[samplerType];\r\n                const samplerBindingType = isComparisonSampler ? WebGPUConstants.SamplerBindingType.Comparison : WebGPUConstants.SamplerBindingType.Filtering;\r\n                const samplerName = name + Constants.AUTOSAMPLERSUFFIX;\r\n\r\n                let samplerInfo = this._webgpuProcessingContext.availableSamplers[samplerName];\r\n                if (!samplerInfo) {\r\n                    samplerInfo = {\r\n                        binding: this._webgpuProcessingContext.getNextFreeUBOBinding(),\r\n                        type: samplerBindingType,\r\n                    };\r\n                }\r\n\r\n                const componentType = uniformType.charAt(0) === \"u\" ? \"u\" : uniformType.charAt(0) === \"i\" ? \"i\" : \"\";\r\n\r\n                if (componentType) {\r\n                    uniformType = uniformType.substring(1);\r\n                }\r\n\r\n                const sampleType = isComparisonSampler\r\n                    ? WebGPUConstants.TextureSampleType.Depth\r\n                    : componentType === \"u\"\r\n                      ? WebGPUConstants.TextureSampleType.Uint\r\n                      : componentType === \"i\"\r\n                        ? WebGPUConstants.TextureSampleType.Sint\r\n                        : WebGPUConstants.TextureSampleType.Float;\r\n\r\n                textureInfo.sampleType = sampleType;\r\n\r\n                const isTextureArray = arraySize > 0;\r\n                const samplerGroupIndex = samplerInfo.binding.groupIndex;\r\n                const samplerBindingIndex = samplerInfo.binding.bindingIndex;\r\n                const samplerFunction = WebGPUShaderProcessor._SamplerFunctionByWebGLSamplerType[uniformType];\r\n                const textureType = WebGPUShaderProcessor._TextureTypeByWebGLSamplerType[uniformType];\r\n                const textureDimension = WebGPUShaderProcessor._GpuTextureViewDimensionByWebGPUTextureType[textureType];\r\n\r\n                // Manage textures and samplers.\r\n                if (!isTextureArray) {\r\n                    arraySize = 1;\r\n                    uniform = `layout(set = ${samplerGroupIndex}, binding = ${samplerBindingIndex}) uniform ${samplerType} ${samplerName};\r\n                        layout(set = ${textureInfo.textures[0].groupIndex}, binding = ${textureInfo.textures[0].bindingIndex}) uniform ${componentType}${textureType} ${name}Texture;\r\n                        #define ${name} ${componentType}${samplerFunction}(${name}Texture, ${samplerName})`;\r\n                } else {\r\n                    const layouts = [];\r\n                    layouts.push(`layout(set = ${samplerGroupIndex}, binding = ${samplerBindingIndex}) uniform ${componentType}${samplerType} ${samplerName};`);\r\n                    uniform = `\\n`;\r\n                    for (let i = 0; i < arraySize; ++i) {\r\n                        const textureSetIndex = textureInfo.textures[i].groupIndex;\r\n                        const textureBindingIndex = textureInfo.textures[i].bindingIndex;\r\n\r\n                        layouts.push(`layout(set = ${textureSetIndex}, binding = ${textureBindingIndex}) uniform ${textureType} ${name}Texture${i};`);\r\n\r\n                        uniform += `${i > 0 ? \"\\n\" : \"\"}#define ${name}${i} ${componentType}${samplerFunction}(${name}Texture${i}, ${samplerName})`;\r\n                    }\r\n                    uniform = layouts.join(\"\\n\") + uniform;\r\n                    this._textureArrayProcessing.push(name);\r\n                }\r\n\r\n                this._webgpuProcessingContext.availableTextures[name] = textureInfo;\r\n                this._webgpuProcessingContext.availableSamplers[samplerName] = samplerInfo;\r\n\r\n                this._addSamplerBindingDescription(samplerName, samplerInfo, !isFragment);\r\n\r\n                for (let i = 0; i < arraySize; ++i) {\r\n                    this._addTextureBindingDescription(name, textureInfo, i, textureDimension, null, !isFragment);\r\n                }\r\n            } else {\r\n                this._addUniformToLeftOverUBO(name, uniformType, preProcessors);\r\n                uniform = \"\";\r\n            }\r\n        }\r\n        return uniform;\r\n    }\r\n\r\n    public uniformBufferProcessor(uniformBuffer: string, isFragment: boolean): string {\r\n        const uboRegex = /uniform\\s+(\\w+)/gm;\r\n\r\n        const match = uboRegex.exec(uniformBuffer);\r\n        if (match !== null) {\r\n            const name = match[1];\r\n\r\n            let uniformBufferInfo = this._webgpuProcessingContext.availableBuffers[name];\r\n            if (!uniformBufferInfo) {\r\n                const knownUBO = WebGPUShaderProcessingContext.KnownUBOs[name];\r\n\r\n                let binding;\r\n                if (knownUBO && knownUBO.binding.groupIndex !== -1) {\r\n                    binding = knownUBO.binding;\r\n                } else {\r\n                    binding = this._webgpuProcessingContext.getNextFreeUBOBinding();\r\n                }\r\n\r\n                uniformBufferInfo = { binding };\r\n                this._webgpuProcessingContext.availableBuffers[name] = uniformBufferInfo;\r\n            }\r\n\r\n            this._addBufferBindingDescription(name, uniformBufferInfo, WebGPUConstants.BufferBindingType.Uniform, !isFragment);\r\n\r\n            uniformBuffer = uniformBuffer.replace(\"uniform\", `layout(set = ${uniformBufferInfo.binding.groupIndex}, binding = ${uniformBufferInfo.binding.bindingIndex}) uniform`);\r\n        }\r\n        return uniformBuffer;\r\n    }\r\n\r\n    public postProcessor(\r\n        code: string,\r\n        defines: string[],\r\n        isFragment: boolean,\r\n        _processingContext: Nullable<_IShaderProcessingContext>,\r\n        _parameters: { [key: string]: number | string | boolean | undefined },\r\n        preProcessors: { [key: string]: string }\r\n    ): string {\r\n        const hasDrawBuffersExtension = code.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;\r\n\r\n        // Remove extensions\r\n        const regex = /#extension.+(GL_OVR_multiview2|GL_OES_standard_derivatives|GL_EXT_shader_texture_lod|GL_EXT_frag_depth|GL_EXT_draw_buffers).+(enable|require)/g;\r\n        code = code.replace(regex, \"\");\r\n\r\n        // Replace instructions\r\n        code = code.replace(/texture2D\\s*\\(/g, \"texture(\");\r\n        if (isFragment) {\r\n            const hasFragCoord = code.indexOf(\"gl_FragCoord\") >= 0;\r\n            const fragCoordCode = `\r\n                glFragCoord_ = gl_FragCoord;\r\n                if (yFactor_ == 1.) {\r\n                    glFragCoord_.y = textureOutputHeight_ - glFragCoord_.y;\r\n                }\r\n            `;\r\n\r\n            const injectCode = hasFragCoord ? \"vec4 glFragCoord_;\\n\" : \"\";\r\n            const hasOutput = code.search(/layout *\\(location *= *0\\) *out/g) !== -1;\r\n\r\n            code = code.replace(/texture2DLodEXT\\s*\\(/g, \"textureLod(\");\r\n            code = code.replace(/textureCubeLodEXT\\s*\\(/g, \"textureLod(\");\r\n            code = code.replace(/textureCube\\s*\\(/g, \"texture(\");\r\n            code = code.replace(/gl_FragDepthEXT/g, \"gl_FragDepth\");\r\n            code = code.replace(/gl_FragColor/g, \"glFragColor\");\r\n            code = code.replace(/gl_FragData/g, \"glFragData\");\r\n            code = code.replace(/gl_FragCoord/g, \"glFragCoord_\");\r\n            if (!this._fragmentIsGLES3) {\r\n                code = code.replace(/void\\s+?main\\s*\\(/g, (hasDrawBuffersExtension || hasOutput ? \"\" : \"layout(location = 0) out vec4 glFragColor;\\n\") + \"void main(\");\r\n            } else {\r\n                const match = /^\\s*out\\s+\\S+\\s+\\S+\\s*;/gm.exec(code);\r\n                if (match !== null) {\r\n                    code = code.substring(0, match.index) + \"layout(location = 0) \" + code.substring(match.index);\r\n                }\r\n            }\r\n            code = code.replace(/dFdy/g, \"(-yFactor_)*dFdy\"); // will also handle dFdyCoarse and dFdyFine\r\n            code = code.replace(\"##INJECTCODE##\", injectCode);\r\n\r\n            if (hasFragCoord) {\r\n                code = InjectStartingAndEndingCode(code, \"void main\", fragCoordCode);\r\n            }\r\n        } else {\r\n            if (\"VERTEXOUTPUT_INVARIANT\" in preProcessors) {\r\n                code = \"invariant gl_Position;\\n\" + code;\r\n            }\r\n            code = code.replace(/gl_InstanceID/g, \"gl_InstanceIndex\");\r\n            code = code.replace(/gl_VertexID/g, \"gl_VertexIndex\");\r\n            const hasMultiviewExtension = defines.indexOf(\"#define MULTIVIEW\") !== -1;\r\n            if (hasMultiviewExtension) {\r\n                return \"#extension GL_OVR_multiview2 : require\\nlayout (num_views = 2) in;\\n\" + code;\r\n            }\r\n        }\r\n\r\n        // Flip Y + convert z range from [-1,1] to [0,1]\r\n        if (!isFragment) {\r\n            const lastClosingCurly = code.lastIndexOf(\"}\");\r\n            code = code.substring(0, lastClosingCurly);\r\n            code += \"gl_Position.y *= yFactor_;\\n\";\r\n            // isNDCHalfZRange is always true in WebGPU\r\n            code += \"}\";\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    private _applyTextureArrayProcessing(code: string, name: string): string {\r\n        // Replaces the occurrences of name[XX] by nameXX\r\n        const regex = new RegExp(name + \"\\\\s*\\\\[(.+)?\\\\]\", \"gm\");\r\n        let match = regex.exec(code);\r\n\r\n        while (match !== null) {\r\n            const index = match[1];\r\n            let iindex = +index;\r\n            if (this._preProcessors && isNaN(iindex)) {\r\n                iindex = +this._preProcessors[index.trim()];\r\n            }\r\n            code = code.replace(match[0], name + iindex);\r\n            match = regex.exec(code);\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    protected _generateLeftOverUBOCode(name: string, uniformBufferDescription: WebGPUBufferDescription): string {\r\n        let ubo = `layout(set = ${uniformBufferDescription.binding.groupIndex}, binding = ${uniformBufferDescription.binding.bindingIndex}) uniform ${name} {\\n    `;\r\n        for (const leftOverUniform of this._webgpuProcessingContext.leftOverUniforms) {\r\n            if (leftOverUniform.length > 0) {\r\n                ubo += `    ${leftOverUniform.type} ${leftOverUniform.name}[${leftOverUniform.length}];\\n`;\r\n            } else {\r\n                ubo += `    ${leftOverUniform.type} ${leftOverUniform.name};\\n`;\r\n            }\r\n        }\r\n        ubo += \"};\\n\\n\";\r\n\r\n        return ubo;\r\n    }\r\n\r\n    public finalizeShaders(vertexCode: string, fragmentCode: string): { vertexCode: string; fragmentCode: string } {\r\n        // make replacements for texture names in the texture array case\r\n        for (let i = 0; i < this._textureArrayProcessing.length; ++i) {\r\n            const name = this._textureArrayProcessing[i];\r\n            vertexCode = this._applyTextureArrayProcessing(vertexCode, name);\r\n            fragmentCode = this._applyTextureArrayProcessing(fragmentCode, name);\r\n        }\r\n\r\n        // inject the missing varying in the fragment shader\r\n        for (let i = 0; i < this._missingVaryings.length; ++i) {\r\n            const decl = this._missingVaryings[i];\r\n            if (decl && decl.length > 0) {\r\n                fragmentCode = decl + \"\\n\" + fragmentCode;\r\n            }\r\n        }\r\n\r\n        // Builds the leftover UBOs.\r\n        const leftOverUBO = this._buildLeftOverUBO();\r\n\r\n        vertexCode = leftOverUBO + vertexCode;\r\n        fragmentCode = leftOverUBO + fragmentCode;\r\n\r\n        this._collectBindingNames();\r\n        this._preCreateBindGroupEntries();\r\n\r\n        this._preProcessors = null as any;\r\n        this._webgpuProcessingContext.vertexBufferKindToNumberOfComponents = {};\r\n\r\n        return { vertexCode, fragmentCode };\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { type Nullable } from \"../../types\";\r\nimport { type _IShaderProcessingContext } from \"../Processors/shaderProcessingOptions\";\r\nimport { type WebGPUBufferDescription, WebGPUShaderProcessingContext } from \"./webgpuShaderProcessingContext\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { WebGPUShaderProcessor } from \"./webgpuShaderProcessor\";\r\nimport { RemoveComments, InjectStartingAndEndingCode } from \"../../Misc/codeStringParsingTools\";\r\nimport { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\n\r\nimport { Constants } from \"../constants\";\r\n\r\nconst builtInName_frag_depth = \"fragmentOutputs.fragDepth\";\r\n\r\nconst leftOverVarName = \"uniforms\";\r\nconst internalsVarName = \"internals\";\r\n\r\nconst gpuTextureViewDimensionByWebGPUTextureFunction: { [key: string]: Nullable<GPUTextureViewDimension> } = {\r\n    texture_1d: WebGPUConstants.TextureViewDimension.E1d,\r\n    texture_2d: WebGPUConstants.TextureViewDimension.E2d,\r\n    texture_2d_array: WebGPUConstants.TextureViewDimension.E2dArray,\r\n    texture_3d: WebGPUConstants.TextureViewDimension.E3d,\r\n    texture_cube: WebGPUConstants.TextureViewDimension.Cube,\r\n    texture_cube_array: WebGPUConstants.TextureViewDimension.CubeArray,\r\n    texture_multisampled_2d: WebGPUConstants.TextureViewDimension.E2d,\r\n    texture_depth_2d: WebGPUConstants.TextureViewDimension.E2d,\r\n    texture_depth_2d_array: WebGPUConstants.TextureViewDimension.E2dArray,\r\n    texture_depth_cube: WebGPUConstants.TextureViewDimension.Cube,\r\n    texture_depth_cube_array: WebGPUConstants.TextureViewDimension.CubeArray,\r\n    texture_depth_multisampled_2d: WebGPUConstants.TextureViewDimension.E2d,\r\n    texture_storage_1d: WebGPUConstants.TextureViewDimension.E1d,\r\n    texture_storage_2d: WebGPUConstants.TextureViewDimension.E2d,\r\n    texture_storage_2d_array: WebGPUConstants.TextureViewDimension.E2dArray,\r\n    texture_storage_3d: WebGPUConstants.TextureViewDimension.E3d,\r\n    texture_external: null,\r\n};\r\n\r\n/** @internal */\r\nexport class WebGPUShaderProcessorWGSL extends WebGPUShaderProcessor {\r\n    protected _attributesInputWGSL: string[];\r\n    protected _attributesWGSL: string[];\r\n    protected _attributesConversionCodeWGSL: string[];\r\n    protected _hasNonFloatAttribute: boolean;\r\n    protected _varyingsWGSL: string[];\r\n    protected _varyingNamesWGSL: string[];\r\n    protected _stridedUniformArrays: string[];\r\n\r\n    public override shaderLanguage = ShaderLanguage.WGSL;\r\n    public uniformRegexp = /uniform\\s+(\\w+)\\s*:\\s*(.+)\\s*;/;\r\n    public textureRegexp = /var\\s+(\\w+)\\s*:\\s*((array<\\s*)?(texture_\\w+)\\s*(<\\s*(.+)\\s*>)?\\s*(,\\s*\\w+\\s*>\\s*)?);/;\r\n    public noPrecision = true;\r\n    public pureMode = false;\r\n\r\n    protected _getArraySize(name: string, uniformType: string, preProcessors: { [key: string]: string }): [string, string, number] {\r\n        let length = 0;\r\n\r\n        const endArray = uniformType.lastIndexOf(\">\");\r\n        if (uniformType.indexOf(\"array\") >= 0 && endArray > 0) {\r\n            let startArray = endArray;\r\n            while (startArray > 0 && uniformType.charAt(startArray) !== \" \" && uniformType.charAt(startArray) !== \",\") {\r\n                startArray--;\r\n            }\r\n            const lengthInString = uniformType.substring(startArray + 1, endArray);\r\n            length = +lengthInString;\r\n            if (isNaN(length)) {\r\n                length = +preProcessors[lengthInString.trim()];\r\n            }\r\n            while (startArray > 0 && (uniformType.charAt(startArray) === \" \" || uniformType.charAt(startArray) === \",\")) {\r\n                startArray--;\r\n            }\r\n            uniformType = uniformType.substring(uniformType.indexOf(\"<\") + 1, startArray + 1);\r\n        }\r\n\r\n        return [name, uniformType, length];\r\n    }\r\n\r\n    public initializeShaders(processingContext: Nullable<_IShaderProcessingContext>): void {\r\n        this._webgpuProcessingContext = processingContext as WebGPUShaderProcessingContext;\r\n\r\n        this._attributesInputWGSL = [];\r\n        this._attributesWGSL = [];\r\n        this._attributesConversionCodeWGSL = [];\r\n        this._hasNonFloatAttribute = false;\r\n        this._varyingsWGSL = [];\r\n        this._varyingNamesWGSL = [];\r\n        this._stridedUniformArrays = [];\r\n    }\r\n\r\n    public preProcessShaderCode(code: string): string {\r\n        // Same check as in webgpuShaderProcessorsGLSL to avoid same ubDelcaration to be injected twice.\r\n        const ubDeclaration = this.pureMode\r\n            ? \"\"\r\n            : `struct ${WebGPUShaderProcessor.InternalsUBOName} {\\n  yFactor_: f32,\\n  textureOutputHeight_: f32,\\n};\\nvar<uniform> ${internalsVarName} : ${WebGPUShaderProcessor.InternalsUBOName};\\n`;\r\n        const alreadyInjected = code.indexOf(ubDeclaration) !== -1;\r\n        return alreadyInjected ? code : ubDeclaration + RemoveComments(code);\r\n    }\r\n\r\n    public varyingCheck(varying: string): boolean {\r\n        const regex = /(flat|linear|perspective)?\\s*(center|centroid|sample)?\\s*\\bvarying\\b/;\r\n\r\n        return regex.test(varying);\r\n    }\r\n\r\n    public varyingProcessor(varying: string, isFragment: boolean, preProcessors: { [key: string]: string }) {\r\n        const varyingRegex = /\\s*(flat|linear|perspective)?\\s*(center|centroid|sample)?\\s*varying\\s+(?:(?:highp)?|(?:lowp)?)\\s*(\\S+)\\s*:\\s*(.+)\\s*;/gm;\r\n        const match = varyingRegex.exec(varying);\r\n        if (match !== null) {\r\n            const interpolationType = match[1] ?? \"perspective\";\r\n            const interpolationSampling = match[2] ?? \"center\";\r\n            const varyingType = match[4];\r\n            const name = match[3];\r\n            const interpolation = interpolationType === \"flat\" ? `@interpolate(${interpolationType})` : `@interpolate(${interpolationType}, ${interpolationSampling})`;\r\n            let location: number;\r\n            if (isFragment) {\r\n                location = this._webgpuProcessingContext.availableVaryings[name];\r\n                if (location === undefined) {\r\n                    Logger.Warn(`Invalid fragment shader: The varying named \"${name}\" is not declared in the vertex shader! This declaration will be ignored.`);\r\n                }\r\n            } else {\r\n                location = this._webgpuProcessingContext.getVaryingNextLocation(varyingType, this._getArraySize(name, varyingType, preProcessors)[2]);\r\n                this._webgpuProcessingContext.availableVaryings[name] = location;\r\n                this._varyingsWGSL.push(`  @location(${location}) ${interpolation} ${name} : ${varyingType},`);\r\n                this._varyingNamesWGSL.push(name);\r\n            }\r\n\r\n            varying = \"\";\r\n        }\r\n        return varying;\r\n    }\r\n\r\n    public attributeProcessor(attribute: string, preProcessors: { [key: string]: string }) {\r\n        const attribRegex = /\\s*attribute\\s+(\\S+)\\s*:\\s*(.+)\\s*;/gm;\r\n        const match = attribRegex.exec(attribute);\r\n        if (match !== null) {\r\n            const attributeType = match[2];\r\n            const name = match[1];\r\n            const location = this._webgpuProcessingContext.getAttributeNextLocation(attributeType, this._getArraySize(name, attributeType, preProcessors)[2]);\r\n\r\n            this._webgpuProcessingContext.availableAttributes[name] = location;\r\n            this._webgpuProcessingContext.orderedAttributes[location] = name;\r\n\r\n            const numComponents = this._webgpuProcessingContext.vertexBufferKindToNumberOfComponents[name];\r\n            if (numComponents !== undefined) {\r\n                // Special case for an int/ivecX vertex buffer that is used as a float/vecX attribute in the shader.\r\n                const newType =\r\n                    numComponents < 0 ? (numComponents === -1 ? \"i32\" : \"vec\" + -numComponents + \"<i32>\") : numComponents === 1 ? \"u32\" : \"vec\" + numComponents + \"<u32>\";\r\n                const newName = `_int_${name}_`;\r\n\r\n                this._attributesInputWGSL.push(`@location(${location}) ${newName} : ${newType},`);\r\n                this._attributesWGSL.push(`${name} : ${attributeType},`);\r\n                this._attributesConversionCodeWGSL.push(`vertexInputs.${name} = ${attributeType}(vertexInputs_.${newName});`);\r\n                this._hasNonFloatAttribute = true;\r\n            } else {\r\n                this._attributesInputWGSL.push(`@location(${location}) ${name} : ${attributeType},`);\r\n                this._attributesWGSL.push(`${name} : ${attributeType},`);\r\n                this._attributesConversionCodeWGSL.push(`vertexInputs.${name} = vertexInputs_.${name};`);\r\n            }\r\n            attribute = \"\";\r\n        }\r\n        return attribute;\r\n    }\r\n\r\n    public uniformProcessor(uniform: string, isFragment: boolean, preProcessors: { [key: string]: string }): string {\r\n        const match = this.uniformRegexp.exec(uniform);\r\n        if (match !== null) {\r\n            const uniformType = match[2];\r\n            const name = match[1];\r\n\r\n            this._addUniformToLeftOverUBO(name, uniformType, preProcessors);\r\n\r\n            uniform = \"\";\r\n        }\r\n        return uniform;\r\n    }\r\n\r\n    public textureProcessor(texture: string, isFragment: boolean, preProcessors: { [key: string]: string }): string {\r\n        const match = this.textureRegexp.exec(texture);\r\n        if (match !== null) {\r\n            const name = match[1]; // name of the variable\r\n            const type = match[2]; // texture_2d<f32> or array<texture_2d_array<f32>, 5> for eg\r\n            const isArrayOfTexture = !!match[3];\r\n            const textureFunc = match[4]; // texture_2d, texture_depth_2d, etc\r\n            const isStorageTexture = textureFunc.indexOf(\"storage\") > 0;\r\n            const componentType = match[6]; // f32 or i32 or u32 or undefined\r\n            let storageTextureFormat: GPUTextureFormat | null = null;\r\n            let storageTextureAccess = WebGPUConstants.StorageTextureAccess.WriteOnly as GPUStorageTextureAccess;\r\n\r\n            if (isStorageTexture) {\r\n                const commaIndex = componentType.indexOf(\",\");\r\n                storageTextureFormat = componentType.substring(0, commaIndex).trim() as GPUTextureFormat;\r\n                const accessMode = componentType.substring(commaIndex + 1).trim();\r\n                switch (accessMode) {\r\n                    case \"read\":\r\n                        storageTextureAccess = WebGPUConstants.StorageTextureAccess.ReadOnly;\r\n                        break;\r\n                    case \"read_write\":\r\n                        storageTextureAccess = WebGPUConstants.StorageTextureAccess.ReadWrite;\r\n                        break;\r\n                    default:\r\n                        storageTextureAccess = WebGPUConstants.StorageTextureAccess.WriteOnly;\r\n                        break;\r\n                }\r\n            }\r\n\r\n            let arraySize = isArrayOfTexture ? this._getArraySize(name, type, preProcessors)[2] : 0;\r\n            let textureInfo = this._webgpuProcessingContext.availableTextures[name];\r\n            if (!textureInfo) {\r\n                textureInfo = {\r\n                    isTextureArray: arraySize > 0,\r\n                    isStorageTexture,\r\n                    storageTextureAccess: isStorageTexture ? storageTextureAccess : undefined,\r\n                    textures: [],\r\n                    sampleType: WebGPUConstants.TextureSampleType.Float,\r\n                };\r\n                arraySize = arraySize || 1;\r\n                for (let i = 0; i < arraySize; ++i) {\r\n                    textureInfo.textures.push(this._webgpuProcessingContext.getNextFreeUBOBinding());\r\n                }\r\n            } else {\r\n                arraySize = textureInfo.textures.length;\r\n            }\r\n\r\n            this._webgpuProcessingContext.availableTextures[name] = textureInfo;\r\n\r\n            const isDepthTexture = textureFunc.indexOf(\"depth\") > 0;\r\n            const textureDimension = gpuTextureViewDimensionByWebGPUTextureFunction[textureFunc];\r\n            const sampleType = isDepthTexture\r\n                ? WebGPUConstants.TextureSampleType.Depth\r\n                : componentType === \"u32\"\r\n                  ? WebGPUConstants.TextureSampleType.Uint\r\n                  : componentType === \"i32\"\r\n                    ? WebGPUConstants.TextureSampleType.Sint\r\n                    : WebGPUConstants.TextureSampleType.Float;\r\n\r\n            textureInfo.sampleType = sampleType;\r\n\r\n            if (textureDimension === undefined) {\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw `Can't get the texture dimension corresponding to the texture function \"${textureFunc}\"!`;\r\n            }\r\n\r\n            for (let i = 0; i < arraySize; ++i) {\r\n                const { groupIndex, bindingIndex } = textureInfo.textures[i];\r\n\r\n                if (i === 0) {\r\n                    texture = `@group(${groupIndex}) @binding(${bindingIndex}) ${texture}`;\r\n                }\r\n\r\n                this._addTextureBindingDescription(name, textureInfo, i, textureDimension, storageTextureFormat, !isFragment, storageTextureAccess);\r\n            }\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    private _convertDefinesToConst(preProcessors: { [key: string]: string }) {\r\n        let code = \"\";\r\n        for (const key in preProcessors) {\r\n            const value = preProcessors[key];\r\n            if (key.startsWith(\"__\")) {\r\n                continue;\r\n            }\r\n            if (!isNaN(parseInt(value)) || !isNaN(parseFloat(value))) {\r\n                code += `const ${key} = ${value};\\n`;\r\n            } else if (key && value === \"\") {\r\n                code += `const ${key} = true;\\n`;\r\n            }\r\n        }\r\n        return code;\r\n    }\r\n\r\n    public postProcessor(\r\n        code: string,\r\n        _defines: string[],\r\n        _isFragment: boolean,\r\n        _processingContext: Nullable<_IShaderProcessingContext>,\r\n        _parameters: {\r\n            [key: string]: number | string | boolean | undefined;\r\n        },\r\n        preProcessors: { [key: string]: string },\r\n        preProcessorsFromCode: { [key: string]: string }\r\n    ) {\r\n        // Collect the preprocessor names (coming from a \"#define NAME VALUE\" declaration) directly defined in the shader code (preProcessorsFromCode) and not defined at the material level (preProcessors).\r\n        // This is because we will have to perform a replace on the code to replace the defines with their values.\r\n        //\r\n        // We don't have to do it for preprocessor names defined at the material level because replacing them by \"const NAME = VALUE;\" will take care of it (see _convertDefinesToConst()) and is faster than doing a search/replace for each of them.\r\n        //\r\n        // The reason why doing \"const NAME = VALUE;\" doesn't work for preprocessor names defined in the code is that VALUE can be any string and not only numbers or booleans.\r\n        // So, if we have this code:\r\n        //\r\n        //      #define vDiffuseUV vMainUV\r\n        //      textureSample(..., fragmentInputs.vDiffuseUV)\r\n        ///\r\n        // only a search/replace will work, 'const vDiffuseUV = \"vMainUV\";' will not work\r\n        //\r\n        // Note that the search/replace text processing will also apply to the \"#define NAME VALUE\" definition itself, so it will become \"#define VALUE VALUE\"\r\n        // It's not a problem, though, because all #define XXX will be commented out in the final code.\r\n        const defineList: string[] = [];\r\n\r\n        for (const key in preProcessorsFromCode) {\r\n            const value = preProcessorsFromCode[key];\r\n\r\n            // Excludes the defines that are booleans (note that there aren't \"false\" booleans: we simply don't add them in the preProcessorsFromCode object).\r\n            // That's because we need (at least some of) them to stay untouched, like #define DISABLE_UNIFORMTY_ANALYSIS or #define CUSTOM_VERTEX_BEGIN (else, they would be replaced with \"#define true\" after the search/replace processing)\r\n            if (value !== \"true\") {\r\n                defineList.push(key);\r\n            }\r\n        }\r\n\r\n        // We must sort the define names by length to avoid replacing a define with a longer name (ex: #define A 1 and #define AB 2, if we replace A with 1, we will have #define 1B 2)\r\n        // So, we start by longest names and we finish with the shortest ones.\r\n        defineList.sort((a, b) => (a.length - b.length > 0 ? -1 : a.length === b.length ? 0 : 1));\r\n\r\n        for (const name of defineList) {\r\n            // Let's retrieve the value of the define from the code\r\n            // Note that we can't use the value from preProcessorsFromCode[name] because this value could have been changed from a previous replace\r\n            // For example:\r\n            //      #define IOR 1.333\r\n            //      #define ETA 1.0/IOR\r\n            //\r\n            // After IOR replacement is performed, we will have:\r\n            //      #define 1.333 1.333\r\n            //      #define ETA 1.0/1.333\r\n            //\r\n            // but preProcessorsFromCode[\"ETA\"] is still \"1.0/IOR\" and not \"1.0/1.333\", so we must retrieve the value for ETA from the current code\r\n            const i0 = code.indexOf(\"#define \" + name);\r\n\r\n            let i1 = code.indexOf(\"\\n\", i0);\r\n            if (i1 === -1) {\r\n                i1 = code.length;\r\n            }\r\n\r\n            const value = code.substring(i0 + 8 + name.length + 1, i1);\r\n\r\n            code = code.replace(new RegExp(name, \"g\"), value);\r\n        }\r\n\r\n        code = this._convertDefinesToConst(preProcessors) + code;\r\n\r\n        if (\"VERTEXOUTPUT_INVARIANT\" in preProcessors) {\r\n            code = \"#define VERTEXOUTPUT_INVARIANT\\n\" + code;\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    public finalizeShaders(vertexCode: string, fragmentCode: string): { vertexCode: string; fragmentCode: string } {\r\n        const enabledExtensions: string[] = [];\r\n\r\n        const fragCoordCode =\r\n            fragmentCode.indexOf(\"fragmentInputs.position\") >= 0 && !this.pureMode\r\n                ? `\r\n            if (internals.yFactor_ == 1.) {\r\n                fragmentInputs.position.y = internals.textureOutputHeight_ - fragmentInputs.position.y;\r\n            }\r\n        `\r\n                : \"\";\r\n\r\n        // Add the group/binding info to the sampler declaration (var xxx: sampler|sampler_comparison)\r\n        vertexCode = this._processSamplers(vertexCode, true);\r\n        fragmentCode = this._processSamplers(fragmentCode, false);\r\n\r\n        // Add the group/binding info to the uniform/storage buffer declarations (var<uniform> XXX:YYY or var<storage(,read_write|read)> XXX:YYY)\r\n        vertexCode = this._processCustomBuffers(vertexCode, true);\r\n        fragmentCode = this._processCustomBuffers(fragmentCode, false);\r\n\r\n        // Builds the leftover UBOs.\r\n        const leftOverUBO = this._buildLeftOverUBO();\r\n\r\n        vertexCode = leftOverUBO + vertexCode;\r\n        fragmentCode = leftOverUBO + fragmentCode;\r\n\r\n        // Vertex code\r\n        vertexCode = vertexCode.replace(/#define /g, \"//#define \");\r\n        vertexCode = this._processStridedUniformArrays(vertexCode);\r\n\r\n        let vertexInputs = \"struct VertexInputs {\\n  @builtin(vertex_index) vertexIndex : u32,\\n  @builtin(instance_index) instanceIndex : u32,\\n\";\r\n        if (this._attributesInputWGSL.length > 0) {\r\n            vertexInputs += this._attributesInputWGSL.join(\"\\n\");\r\n        }\r\n        vertexInputs += \"\\n};\\nvar<private> vertexInputs\" + (this._hasNonFloatAttribute ? \"_\" : \"\") + \" : VertexInputs;\\n\";\r\n        if (this._hasNonFloatAttribute) {\r\n            vertexInputs += \"struct VertexInputs_ {\\n  vertexIndex : u32, instanceIndex : u32,\\n\";\r\n            vertexInputs += this._attributesWGSL.join(\"\\n\");\r\n            vertexInputs += \"\\n};\\nvar<private> vertexInputs : VertexInputs_;\\n\";\r\n        }\r\n\r\n        let vertexOutputs =\r\n            \"struct FragmentInputs {\\n  @builtin(position)\" + (vertexCode.indexOf(\"#define VERTEXOUTPUT_INVARIANT\") >= 0 ? \" @invariant\" : \"\") + \" position : vec4<f32>,\\n\";\r\n        if (this._varyingsWGSL.length > 0) {\r\n            vertexOutputs += this._varyingsWGSL.join(\"\\n\");\r\n        }\r\n        vertexOutputs += \"\\n};\\nvar<private> vertexOutputs : FragmentInputs;\\n\";\r\n\r\n        vertexCode = vertexInputs + vertexOutputs + vertexCode;\r\n\r\n        let vertexMainStartingCode = `\\n  vertexInputs${this._hasNonFloatAttribute ? \"_\" : \"\"} = input;\\n`;\r\n        if (this._hasNonFloatAttribute) {\r\n            vertexMainStartingCode += \"vertexInputs.vertexIndex = vertexInputs_.vertexIndex;\\nvertexInputs.instanceIndex = vertexInputs_.instanceIndex;\\n\";\r\n            vertexMainStartingCode += this._attributesConversionCodeWGSL.join(\"\\n\");\r\n            vertexMainStartingCode += \"\\n\";\r\n        }\r\n        const vertexMainEndingCode = this.pureMode\r\n            ? `  return vertexOutputs;`\r\n            : `  vertexOutputs.position.y = vertexOutputs.position.y * internals.yFactor_;\\n  return vertexOutputs;`;\r\n        let needDiagnosticOff = vertexCode.indexOf(Constants.DISABLEUA) !== -1;\r\n\r\n        vertexCode =\r\n            (needDiagnosticOff ? \"diagnostic(off, derivative_uniformity);\\n\" : \"\") +\r\n            \"diagnostic(off, chromium.unreachable_code);\\n\" +\r\n            InjectStartingAndEndingCode(vertexCode, \"fn main\", vertexMainStartingCode, vertexMainEndingCode);\r\n\r\n        // fragment code\r\n        fragmentCode = fragmentCode.replace(/#define /g, \"//#define \");\r\n        fragmentCode = this._processStridedUniformArrays(fragmentCode);\r\n        if (!this.pureMode) {\r\n            fragmentCode = fragmentCode.replace(/dpdy/g, \"(-internals.yFactor_)*dpdy\"); // will also handle dpdyCoarse and dpdyFine\r\n        }\r\n\r\n        let fragmentInputs = \"struct FragmentInputs {\\n  @builtin(position) position : vec4<f32>,\\n  @builtin(front_facing) frontFacing : bool,\\n\";\r\n        if (this._varyingsWGSL.length > 0) {\r\n            fragmentInputs += this._varyingsWGSL.join(\"\\n\");\r\n        }\r\n        fragmentInputs += \"\\n};\\nvar<private> fragmentInputs : FragmentInputs;\\n\";\r\n\r\n        let fragmentOutputs = \"struct FragmentOutputs {\\n\";\r\n\r\n        // A fragData location is float (vec4<f32>) unless the shader writes an integer vector to it — a shader\r\n        // rendering into an integer color target (e.g. RGBA_INTEGER u32) must declare a matching integer output.\r\n        // Detect the integer type from the assignment's right-hand side: an inline vec4<u32>/vec4<i32> constructor,\r\n        // or a plain identifier whose declaration is an integer vec4. Defaults to vec4<f32> (backward compatible).\r\n        // LIMITATION: this is a lightweight regex scan, not a type checker. Any other RHS shape — a function call, a\r\n        // `select(...)`, or a conditional expression that yields an integer vec4 — is NOT recognized and defaults to\r\n        // vec4<f32>; that surfaces later as a WGSL \"cannot assign vec4<u32> to vec4<f32>\" compile error rather than\r\n        // here. Shaders that render to integer targets should assign an inline vec4<u32>/vec4<i32> (constructor or a\r\n        // directly-typed local) so the output type is detected. Extend the patterns below if new forms are needed.\r\n        // Scan a comment-stripped copy so a commented-out integer write can't flip a real float output.\r\n        const scanCode = fragmentCode.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \" \").replace(/\\/\\/[^\\n]*/g, \" \");\r\n        // fragData writes are in `fn main`; scope the RHS-identifier declaration lookup there so a same-named integer\r\n        // local in a helper function can't win. Match the entry point exactly (not a substring, which `fn mainHelper`\r\n        // would satisfy); a no-match (-1) bails to the vec4<f32> default rather than scanning the whole source.\r\n        const mainBodyStart = scanCode.search(/\\bfn\\s+main\\s*\\(/);\r\n        const detectIntVec = (expr: string): Nullable<string> => {\r\n            if (/^\\s*(vec4<u32>|vec4u\\s*\\()/.test(expr)) {\r\n                return \"vec4<u32>\";\r\n            }\r\n            if (/^\\s*(vec4<i32>|vec4i\\s*\\()/.test(expr)) {\r\n                return \"vec4<i32>\";\r\n            }\r\n            return null;\r\n        };\r\n        const fragDataOutputType = (index: number): string => {\r\n            const assign = scanCode.match(new RegExp(`fragmentOutputs\\\\.fragData${index}\\\\s*=\\\\s*([^;]+);`));\r\n            if (!assign) {\r\n                return \"vec4<f32>\";\r\n            }\r\n            const rhs = assign[1].trim();\r\n            const direct = detectIntVec(rhs);\r\n            if (direct) {\r\n                return direct;\r\n            }\r\n            // Bare identifier RHS (e.g. `fragData0 = computedUintColor;`): resolve its type from a `var/let NAME :\r\n            // vec4<u32>` or `var/let NAME = vec4<u32>(...)` declaration, searched only in main up to this write.\r\n            const id = rhs.match(/^([A-Za-z_]\\w*)$/);\r\n            if (id && mainBodyStart >= 0) {\r\n                const declScope = scanCode.slice(mainBodyStart, assign.index ?? scanCode.length);\r\n                const typed = declScope.match(new RegExp(`(?:var|let)\\\\s+${id[1]}\\\\s*:\\\\s*(vec4<u32>|vec4<i32>)`));\r\n                if (typed) {\r\n                    return typed[1];\r\n                }\r\n                const inited = declScope.match(new RegExp(`(?:var|let)\\\\s+${id[1]}\\\\s*=\\\\s*([^;]+);`));\r\n                if (inited) {\r\n                    const t = detectIntVec(inited[1].trim());\r\n                    if (t) {\r\n                        return t;\r\n                    }\r\n                }\r\n            }\r\n            return \"vec4<f32>\";\r\n        };\r\n\r\n        // Adding fragData output locations\r\n        const regexRoot = \"fragmentOutputs\\\\.fragData\";\r\n        let match = scanCode.match(new RegExp(regexRoot + \"0\", \"g\"));\r\n        let indexLocation = 0;\r\n\r\n        if (match) {\r\n            fragmentOutputs += ` @location(${indexLocation}) fragData0 : ${fragDataOutputType(0)},\\n`;\r\n            indexLocation++;\r\n            for (let index = 1; index < 8; index++) {\r\n                match = scanCode.match(new RegExp(regexRoot + index, \"g\"));\r\n                if (match) {\r\n                    fragmentOutputs += ` @location(${indexLocation}) fragData${indexLocation} : ${fragDataOutputType(index)},\\n`;\r\n                    indexLocation++;\r\n                }\r\n            }\r\n            if (fragmentCode.indexOf(\"MRT_AND_COLOR\") !== -1) {\r\n                fragmentOutputs += `  @location(${indexLocation}) color : vec4<f32>,\\n`;\r\n                indexLocation++;\r\n            }\r\n        }\r\n\r\n        // Adding fragData output locations\r\n        const regex = /oitDepthSampler/;\r\n        match = fragmentCode.match(regex);\r\n\r\n        if (match) {\r\n            fragmentOutputs += ` @location(${indexLocation++}) depth : vec2<f32>,\\n`;\r\n            fragmentOutputs += ` @location(${indexLocation++}) frontColor : vec4<f32>,\\n`;\r\n            fragmentOutputs += ` @location(${indexLocation++}) backColor : vec4<f32>,\\n`;\r\n        }\r\n\r\n        if (indexLocation === 0) {\r\n            const useDualSourceBlending = fragmentCode.indexOf(\"DUAL_SOURCE_BLENDING\") !== -1;\r\n\r\n            if (useDualSourceBlending) {\r\n                enabledExtensions.push(\"dual_source_blending\");\r\n\r\n                fragmentOutputs += \"  @location(0) @blend_src(0) color : vec4<f32>,\\n\";\r\n                fragmentOutputs += \"  @location(0) @blend_src(1) color2 : vec4<f32>,\\n\";\r\n            } else {\r\n                fragmentOutputs += \"  @location(0) color : vec4<f32>,\\n\";\r\n            }\r\n            // indexLocation++; // if you need this variable after this block, uncomment this\r\n        }\r\n\r\n        // FragDepth\r\n        let hasFragDepth = false;\r\n        let idx = 0;\r\n        while (!hasFragDepth) {\r\n            idx = fragmentCode.indexOf(builtInName_frag_depth, idx);\r\n            if (idx < 0) {\r\n                break;\r\n            }\r\n            const saveIndex = idx;\r\n            hasFragDepth = true;\r\n            while (idx > 1 && fragmentCode.charAt(idx) !== \"\\n\") {\r\n                if (fragmentCode.charAt(idx) === \"/\" && fragmentCode.charAt(idx - 1) === \"/\") {\r\n                    hasFragDepth = false;\r\n                    break;\r\n                }\r\n                idx--;\r\n            }\r\n            idx = saveIndex + builtInName_frag_depth.length;\r\n        }\r\n\r\n        if (hasFragDepth) {\r\n            fragmentOutputs += \"  @builtin(frag_depth) fragDepth: f32,\\n\";\r\n        }\r\n\r\n        fragmentOutputs += \"};\\nvar<private> fragmentOutputs : FragmentOutputs;\\n\";\r\n\r\n        fragmentCode = fragmentInputs + fragmentOutputs + fragmentCode;\r\n\r\n        const fragmentStartingCode = \"  fragmentInputs = input;\\n  \" + fragCoordCode;\r\n        const fragmentEndingCode = \"  return fragmentOutputs;\";\r\n        needDiagnosticOff = fragmentCode.indexOf(Constants.DISABLEUA) !== -1;\r\n\r\n        if (enabledExtensions.length > 0) {\r\n            fragmentCode = \"enable \" + enabledExtensions.join(\";\\nenable \") + \";\\n\" + fragmentCode;\r\n        }\r\n\r\n        fragmentCode =\r\n            (needDiagnosticOff ? \"diagnostic(off, derivative_uniformity);\\n\" : \"\") +\r\n            \"diagnostic(off, chromium.unreachable_code);\\n\" +\r\n            InjectStartingAndEndingCode(fragmentCode, \"fn main\", fragmentStartingCode, fragmentEndingCode);\r\n\r\n        this._collectBindingNames();\r\n        this._preCreateBindGroupEntries();\r\n\r\n        this._webgpuProcessingContext.vertexBufferKindToNumberOfComponents = {};\r\n\r\n        return { vertexCode, fragmentCode };\r\n    }\r\n\r\n    protected _generateLeftOverUBOCode(name: string, uniformBufferDescription: WebGPUBufferDescription): string {\r\n        let stridedArrays = \"\";\r\n        let ubo = `struct ${name} {\\n`;\r\n        for (const leftOverUniform of this._webgpuProcessingContext.leftOverUniforms) {\r\n            const type = leftOverUniform.type.replace(/^(.*?)(<.*>)?$/, \"$1\");\r\n            const size = WebGPUShaderProcessor.UniformSizes[type];\r\n\r\n            if (leftOverUniform.length > 0) {\r\n                if (size <= 2) {\r\n                    const stridedArrayType = `${name}_${this._stridedUniformArrays.length}_strided_arr`;\r\n                    stridedArrays += `struct ${stridedArrayType} {\r\n                        @size(16)\r\n                        el: ${type},\r\n                    }`;\r\n                    this._stridedUniformArrays.push(leftOverUniform.name);\r\n\r\n                    ubo += ` @align(16) ${leftOverUniform.name} : array<${stridedArrayType}, ${leftOverUniform.length}>,\\n`;\r\n                } else {\r\n                    ubo += ` ${leftOverUniform.name} : array<${leftOverUniform.type}, ${leftOverUniform.length}>,\\n`;\r\n                }\r\n            } else {\r\n                ubo += `  ${leftOverUniform.name} : ${leftOverUniform.type},\\n`;\r\n            }\r\n        }\r\n        ubo += \"};\\n\";\r\n        ubo = `${stridedArrays}\\n${ubo}`;\r\n        ubo += `@group(${uniformBufferDescription.binding.groupIndex}) @binding(${uniformBufferDescription.binding.bindingIndex}) var<uniform> ${leftOverVarName} : ${name};\\n`;\r\n\r\n        return ubo;\r\n    }\r\n\r\n    private _processSamplers(code: string, isVertex: boolean): string {\r\n        const samplerRegexp = /var\\s+(\\w+Sampler)\\s*:\\s*(sampler|sampler_comparison)\\s*;/gm;\r\n\r\n        // eslint-disable-next-line no-constant-condition\r\n        while (true) {\r\n            const match = samplerRegexp.exec(code);\r\n            if (match === null) {\r\n                break;\r\n            }\r\n\r\n            const name = match[1]; // name of the variable\r\n            const samplerType = match[2]; // sampler or sampler_comparison\r\n            const suffixLessLength = name.length - Constants.AUTOSAMPLERSUFFIX.length;\r\n            const textureName = name.lastIndexOf(Constants.AUTOSAMPLERSUFFIX) === suffixLessLength ? name.substring(0, suffixLessLength) : null;\r\n            const samplerBindingType = samplerType === \"sampler_comparison\" ? WebGPUConstants.SamplerBindingType.Comparison : WebGPUConstants.SamplerBindingType.Filtering;\r\n\r\n            if (textureName) {\r\n                const textureInfo = this._webgpuProcessingContext.availableTextures[textureName];\r\n                if (textureInfo) {\r\n                    textureInfo.autoBindSampler = true;\r\n                }\r\n            }\r\n\r\n            let samplerInfo = this._webgpuProcessingContext.availableSamplers[name];\r\n            if (!samplerInfo) {\r\n                samplerInfo = {\r\n                    binding: this._webgpuProcessingContext.getNextFreeUBOBinding(),\r\n                    type: samplerBindingType,\r\n                };\r\n                this._webgpuProcessingContext.availableSamplers[name] = samplerInfo;\r\n            }\r\n\r\n            this._addSamplerBindingDescription(name, samplerInfo, isVertex);\r\n\r\n            const part1 = code.substring(0, match.index);\r\n            const insertPart = `@group(${samplerInfo.binding.groupIndex}) @binding(${samplerInfo.binding.bindingIndex}) `;\r\n            const part2 = code.substring(match.index);\r\n\r\n            code = part1 + insertPart + part2;\r\n\r\n            samplerRegexp.lastIndex += insertPart.length;\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    private _processCustomBuffers(code: string, isVertex: boolean): string {\r\n        const instantiateBufferRegexp = /var<\\s*(uniform|storage)\\s*(,\\s*(read|read_write)\\s*)?>\\s+(\\S+)\\s*:\\s*(\\S+)\\s*;/gm;\r\n\r\n        // eslint-disable-next-line no-constant-condition\r\n        while (true) {\r\n            const match = instantiateBufferRegexp.exec(code);\r\n            if (match === null) {\r\n                break;\r\n            }\r\n\r\n            const type = match[1];\r\n            const decoration = match[3];\r\n            let name = match[4];\r\n            const structName = match[5];\r\n\r\n            let bufferInfo = this._webgpuProcessingContext.availableBuffers[name];\r\n            if (!bufferInfo) {\r\n                const knownUBO = type === \"uniform\" ? WebGPUShaderProcessingContext.KnownUBOs[structName] : null;\r\n\r\n                let binding;\r\n                if (knownUBO) {\r\n                    name = structName;\r\n                    binding = knownUBO.binding;\r\n                    if (binding.groupIndex === -1) {\r\n                        binding = this._webgpuProcessingContext.availableBuffers[name]?.binding;\r\n                        if (!binding) {\r\n                            binding = this._webgpuProcessingContext.getNextFreeUBOBinding();\r\n                        }\r\n                    }\r\n                } else {\r\n                    binding = this._webgpuProcessingContext.getNextFreeUBOBinding();\r\n                }\r\n\r\n                bufferInfo = { binding };\r\n                this._webgpuProcessingContext.availableBuffers[name] = bufferInfo;\r\n            }\r\n\r\n            this._addBufferBindingDescription(\r\n                name,\r\n                this._webgpuProcessingContext.availableBuffers[name],\r\n                decoration === \"read_write\"\r\n                    ? WebGPUConstants.BufferBindingType.Storage\r\n                    : type === \"storage\"\r\n                      ? WebGPUConstants.BufferBindingType.ReadOnlyStorage\r\n                      : WebGPUConstants.BufferBindingType.Uniform,\r\n                isVertex\r\n            );\r\n\r\n            const groupIndex = bufferInfo.binding.groupIndex;\r\n            const bindingIndex = bufferInfo.binding.bindingIndex;\r\n\r\n            const part1 = code.substring(0, match.index);\r\n            const insertPart = `@group(${groupIndex}) @binding(${bindingIndex}) `;\r\n            const part2 = code.substring(match.index);\r\n\r\n            code = part1 + insertPart + part2;\r\n\r\n            instantiateBufferRegexp.lastIndex += insertPart.length;\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    private _processStridedUniformArrays(code: string): string {\r\n        for (const uniformArrayName of this._stridedUniformArrays) {\r\n            code = code.replace(new RegExp(`${uniformArrayName}\\\\s*\\\\[(.*?)\\\\]`, \"g\"), `${uniformArrayName}[$1].el`);\r\n        }\r\n        return code;\r\n    }\r\n}\r\n","import { DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/** @internal */\r\nexport class WebGPUDataBuffer extends DataBuffer {\r\n    private _buffer: Nullable<GPUBuffer>;\r\n\r\n    // Used to make sure the buffer is not recreated twice after a context loss/restoration\r\n    /** @internal */\r\n    public engineId = -1;\r\n\r\n    /** @internal */\r\n    public set buffer(buffer: Nullable<GPUBuffer>) {\r\n        this._buffer = buffer;\r\n    }\r\n\r\n    /** @internal */\r\n    public constructor(resource?: GPUBuffer, capacity = 0) {\r\n        super();\r\n        this.capacity = capacity;\r\n        if (resource) {\r\n            this._buffer = resource;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override get underlyingResource(): any {\r\n        return this._buffer;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { WebGPUDataBuffer } from \"../../Meshes/WebGPU/webgpuDataBuffer\";\r\nimport { FromHalfFloat } from \"../../Misc/textureTools\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { allocateAndCopyTypedBuffer } from \"../abstractEngine.functions\";\r\nimport { Constants } from \"../constants\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\n\r\n/** @internal */\r\nexport class WebGPUBufferManager {\r\n    private _engine: WebGPUEngine;\r\n    private _device: GPUDevice;\r\n    private _deferredReleaseBuffers: Array<GPUBuffer> = [];\r\n\r\n    private static _IsGPUBuffer(buffer: DataBuffer | GPUBuffer): buffer is GPUBuffer {\r\n        return (buffer as DataBuffer).underlyingResource === undefined;\r\n    }\r\n\r\n    private static _FlagsToString(flags: GPUBufferUsageFlags, suffix = \"\") {\r\n        let result = suffix;\r\n\r\n        for (let i = 0; i <= 9; ++i) {\r\n            if (flags & (1 << i)) {\r\n                if (result) {\r\n                    result += \"_\";\r\n                }\r\n                result += WebGPUConstants.BufferUsage[1 << i];\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    constructor(engine: WebGPUEngine, device: GPUDevice) {\r\n        this._engine = engine;\r\n        this._device = device;\r\n    }\r\n\r\n    public createRawBuffer(viewOrSize: ArrayBufferView | number, flags: GPUBufferUsageFlags, mappedAtCreation = false, label?: string): GPUBuffer {\r\n        const alignedLength = (viewOrSize as ArrayBufferView).byteLength !== undefined ? ((viewOrSize as ArrayBufferView).byteLength + 3) & ~3 : ((viewOrSize as number) + 3) & ~3; // 4 bytes alignments (because of the upload which requires this)\r\n        const verticesBufferDescriptor = {\r\n            label: \"BabylonWebGPUDevice\" + this._engine.uniqueId + \"_\" + WebGPUBufferManager._FlagsToString(flags, label ?? \"Buffer\") + \"_size\" + alignedLength,\r\n            mappedAtCreation,\r\n            size: alignedLength,\r\n            usage: flags,\r\n        };\r\n\r\n        return this._device.createBuffer(verticesBufferDescriptor);\r\n    }\r\n\r\n    public createBuffer(viewOrSize: ArrayBufferView | number, flags: GPUBufferUsageFlags, label?: string): WebGPUDataBuffer {\r\n        const isView = (viewOrSize as ArrayBufferView).byteLength !== undefined;\r\n        const dataBuffer = new WebGPUDataBuffer();\r\n        const labelId = \"DataBufferUniqueId=\" + dataBuffer.uniqueId;\r\n        dataBuffer.buffer = this.createRawBuffer(viewOrSize, flags, undefined, label ? labelId + \"-\" + label : labelId);\r\n        dataBuffer.references = 1;\r\n        // Next line should work, because the \"size\" property of GPUBuffer is required by the spec, but it seems that it fails in the CI / in playwright tests. So, we will recalculate the aligned size ourselves.\r\n        //dataBuffer.capacity = dataBuffer.buffer.size;\r\n        dataBuffer.capacity = (viewOrSize as ArrayBufferView).byteLength !== undefined ? ((viewOrSize as ArrayBufferView).byteLength + 3) & ~3 : ((viewOrSize as number) + 3) & ~3; // 4 bytes alignments (because of the upload which requires this)\r\n        dataBuffer.engineId = this._engine.uniqueId;\r\n\r\n        if (isView) {\r\n            this.setSubData(dataBuffer, 0, viewOrSize as ArrayBufferView);\r\n        }\r\n\r\n        return dataBuffer;\r\n    }\r\n\r\n    // This calls GPUBuffer.writeBuffer() with no alignment corrections\r\n    // dstByteOffset and byteLength must both be aligned to 4 bytes and bytes moved must be within src and dst arrays\r\n    public setRawData(buffer: GPUBuffer, dstByteOffset: number, src: ArrayBufferView, srcByteOffset: number, byteLength: number): void {\r\n        srcByteOffset += src.byteOffset;\r\n\r\n        this._device.queue.writeBuffer(buffer, dstByteOffset, src.buffer, srcByteOffset, byteLength);\r\n    }\r\n\r\n    // This calls GPUBuffer.writeBuffer() with alignment corrections (dstByteOffset and byteLength will be aligned to 4 byte boundaries)\r\n    // If alignment is needed, src must be a full copy of dataBuffer, or at least should be large enough to cope with the additional bytes copied because of alignment!\r\n    public setSubData(dataBuffer: WebGPUDataBuffer, dstByteOffset: number, src: ArrayBufferView, srcByteOffset = 0, byteLength = 0): void {\r\n        const buffer = dataBuffer.underlyingResource as GPUBuffer;\r\n\r\n        byteLength = byteLength || src.byteLength - srcByteOffset;\r\n\r\n        // Make sure the dst offset is aligned to 4 bytes\r\n        const startPre = dstByteOffset & 3;\r\n\r\n        srcByteOffset -= startPre;\r\n        dstByteOffset -= startPre;\r\n\r\n        // Make sure the byte length is aligned to 4 bytes\r\n        const originalByteLength = byteLength;\r\n\r\n        byteLength = (byteLength + startPre + 3) & ~3;\r\n\r\n        // Check if the backing buffer of src is large enough to cope with the additional bytes copied because of alignment\r\n        const backingBufferSize = src.buffer.byteLength - src.byteOffset;\r\n\r\n        if (backingBufferSize < byteLength) {\r\n            // Not enough place in the backing buffer for the aligned copy.\r\n            // Creates a new buffer and copy the source data to it.\r\n            // The buffer will have byteLength - originalByteLength zeros at the end.\r\n            const tmpBuffer = new Uint8Array(byteLength);\r\n            tmpBuffer.set(new Uint8Array(src.buffer, src.byteOffset + srcByteOffset, originalByteLength));\r\n            src = tmpBuffer;\r\n            srcByteOffset = 0;\r\n        }\r\n\r\n        this.setRawData(buffer, dstByteOffset, src, srcByteOffset, byteLength);\r\n    }\r\n\r\n    private _getHalfFloatAsFloatRGBAArrayBuffer(dataLength: number, arrayBuffer: ArrayBuffer, destArray?: Float32Array): Float32Array {\r\n        if (!destArray) {\r\n            destArray = new Float32Array(dataLength);\r\n        } else {\r\n            dataLength = Math.min(dataLength, destArray.length);\r\n        }\r\n        const srcData = new Uint16Array(arrayBuffer);\r\n        while (dataLength--) {\r\n            destArray[dataLength] = FromHalfFloat(srcData[dataLength]);\r\n        }\r\n\r\n        return destArray;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n    public readDataFromBuffer(\r\n        gpuBuffer: GPUBuffer,\r\n        size: number,\r\n        width: number,\r\n        height: number,\r\n        bytesPerRow: number,\r\n        bytesPerRowAligned: number,\r\n        type = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        offset = 0,\r\n        buffer: Nullable<ArrayBufferView> = null,\r\n        destroyBuffer = true,\r\n        noDataConversion = false\r\n    ): Promise<ArrayBufferView> {\r\n        const floatFormat = type === Constants.TEXTURETYPE_FLOAT ? 2 : type === Constants.TEXTURETYPE_HALF_FLOAT ? 1 : 0;\r\n        const engineId = this._engine.uniqueId;\r\n        return new Promise((resolve, reject) => {\r\n            // eslint-disable-next-line github/no-then\r\n            gpuBuffer.mapAsync(WebGPUConstants.MapMode.Read, offset, size).then(\r\n                () => {\r\n                    const copyArrayBuffer = gpuBuffer.getMappedRange(offset, size);\r\n                    let data: Nullable<ArrayBufferView> | Uint8Array | Float32Array = buffer;\r\n                    if (noDataConversion) {\r\n                        if (data === null) {\r\n                            data = allocateAndCopyTypedBuffer(type, size, true, copyArrayBuffer);\r\n                        } else {\r\n                            data = allocateAndCopyTypedBuffer(type, data.buffer, undefined, copyArrayBuffer);\r\n                        }\r\n                    } else {\r\n                        if (data === null) {\r\n                            switch (floatFormat) {\r\n                                case 0: // byte format\r\n                                    data = new Uint8Array(size);\r\n                                    (data as Uint8Array).set(new Uint8Array(copyArrayBuffer));\r\n                                    break;\r\n                                case 1: // half float\r\n                                    // TODO WEBGPU use computer shaders (or render pass) to make the conversion?\r\n                                    data = this._getHalfFloatAsFloatRGBAArrayBuffer(size / 2, copyArrayBuffer);\r\n                                    break;\r\n                                case 2: // float\r\n                                    data = new Float32Array(size / 4);\r\n                                    (data as Float32Array).set(new Float32Array(copyArrayBuffer));\r\n                                    break;\r\n                            }\r\n                        } else {\r\n                            switch (floatFormat) {\r\n                                case 0: // byte format\r\n                                    data = new Uint8Array(data.buffer);\r\n                                    (data as Uint8Array).set(new Uint8Array(copyArrayBuffer, 0, Math.min(data.byteLength, size)));\r\n                                    break;\r\n                                case 1: // half float\r\n                                    // TODO WEBGPU use computer shaders (or render pass) to make the conversion?\r\n                                    data = this._getHalfFloatAsFloatRGBAArrayBuffer(size / 2, copyArrayBuffer, buffer as Float32Array);\r\n                                    break;\r\n                                case 2: // float\r\n                                    data = new Float32Array(data.buffer);\r\n                                    (data as Float32Array).set(new Float32Array(copyArrayBuffer, 0, data.byteLength / 4));\r\n                                    break;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (bytesPerRow !== bytesPerRowAligned) {\r\n                        // TODO WEBGPU use computer shaders (or render pass) to build the final buffer data?\r\n                        if (floatFormat === 1 && !noDataConversion) {\r\n                            // half float have been converted to float above\r\n                            bytesPerRow *= 2;\r\n                            bytesPerRowAligned *= 2;\r\n                        }\r\n                        const data2 = new Uint8Array(data.buffer);\r\n                        let offset = bytesPerRow,\r\n                            offset2: number;\r\n                        for (let y = 1; y < height; ++y) {\r\n                            offset2 = y * bytesPerRowAligned;\r\n                            for (let x = 0; x < bytesPerRow; ++x) {\r\n                                data2[offset++] = data2[offset2++];\r\n                            }\r\n                        }\r\n                        if (floatFormat !== 0 && !noDataConversion) {\r\n                            data = new Float32Array(data2.buffer, 0, offset / 4);\r\n                        } else {\r\n                            data = new Uint8Array(data2.buffer, 0, offset);\r\n                        }\r\n                    }\r\n                    gpuBuffer.unmap();\r\n                    if (destroyBuffer) {\r\n                        this.releaseBuffer(gpuBuffer);\r\n                    }\r\n                    resolve(data);\r\n                },\r\n                (reason) => {\r\n                    if (this._engine.isDisposed || this._engine.uniqueId !== engineId) {\r\n                        // The engine was disposed while waiting for the promise, or a context loss/restoration has occurred: don't reject\r\n                        resolve(new Uint8Array());\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(reason);\r\n                    }\r\n                }\r\n            );\r\n        });\r\n    }\r\n\r\n    public releaseBuffer(buffer: DataBuffer | GPUBuffer): boolean {\r\n        if (WebGPUBufferManager._IsGPUBuffer(buffer)) {\r\n            this._deferredReleaseBuffers.push(buffer);\r\n            return true;\r\n        }\r\n\r\n        buffer.references--;\r\n\r\n        if (buffer.references === 0) {\r\n            this._deferredReleaseBuffers.push(buffer.underlyingResource as GPUBuffer);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public destroyDeferredBuffers(): void {\r\n        for (let i = 0; i < this._deferredReleaseBuffers.length; ++i) {\r\n            this._deferredReleaseBuffers[i].destroy();\r\n        }\r\n\r\n        this._deferredReleaseBuffers.length = 0;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { Constants } from \"../constants\";\r\nimport { type TextureSampler } from \"../../Materials/Textures/textureSampler\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Note: we don't make a difference between mipmaps enabled or not when computing these bits (so, TEXTURE_NEAREST_NEAREST and TEXTURE_NEAREST_NEAREST_MIPNEAREST have the same bits, for example).\r\n * There's another bit in the hash code for that (see FilterNoMipToBits).\r\n */\r\nconst FilterToBits = [\r\n    0 | (0 << 1) | (0 << 2), // not used\r\n    0 | (0 << 1) | (0 << 2), // TEXTURE_NEAREST_SAMPLINGMODE / TEXTURE_NEAREST_NEAREST\r\n    1 | (1 << 1) | (0 << 2), // TEXTURE_BILINEAR_SAMPLINGMODE / TEXTURE_LINEAR_LINEAR\r\n    1 | (1 << 1) | (1 << 2), // TEXTURE_TRILINEAR_SAMPLINGMODE / TEXTURE_LINEAR_LINEAR_MIPLINEAR\r\n    0 | (0 << 1) | (0 << 2), // TEXTURE_NEAREST_NEAREST_MIPNEAREST\r\n    0 | (1 << 1) | (0 << 2), // TEXTURE_NEAREST_LINEAR_MIPNEAREST\r\n    0 | (1 << 1) | (1 << 2), // TEXTURE_NEAREST_LINEAR_MIPLINEAR\r\n    0 | (1 << 1) | (0 << 2), // TEXTURE_NEAREST_LINEAR\r\n    0 | (0 << 1) | (1 << 2), // TEXTURE_NEAREST_NEAREST_MIPLINEAR\r\n    1 | (0 << 1) | (0 << 2), // TEXTURE_LINEAR_NEAREST_MIPNEAREST\r\n    1 | (0 << 1) | (1 << 2), // TEXTURE_LINEAR_NEAREST_MIPLINEAR\r\n    1 | (1 << 1) | (0 << 2), // TEXTURE_LINEAR_LINEAR_MIPNEAREST\r\n    1 | (0 << 1) | (0 << 2), // TEXTURE_LINEAR_NEAREST\r\n];\r\n\r\n// subtract 0x01FF from the comparison function value before indexing this array!\r\nconst ComparisonFunctionToBits = [\r\n    (0 << 3) | (0 << 4) | (0 << 5) | (0 << 6), // undefined\r\n    (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6), // NEVER\r\n    (0 << 3) | (0 << 4) | (1 << 5) | (0 << 6), // LESS\r\n    (0 << 3) | (0 << 4) | (1 << 5) | (1 << 6), // EQUAL\r\n    (0 << 3) | (1 << 4) | (0 << 5) | (0 << 6), // LEQUAL\r\n    (0 << 3) | (1 << 4) | (0 << 5) | (1 << 6), // GREATER\r\n    (0 << 3) | (1 << 4) | (1 << 5) | (0 << 6), // NOTEQUAL\r\n    (0 << 3) | (1 << 4) | (1 << 5) | (1 << 6), // GEQUAL\r\n    (1 << 3) | (0 << 4) | (0 << 5) | (0 << 6), // ALWAYS\r\n];\r\n\r\nconst FilterNoMipToBits = [\r\n    0 << 7, // not used\r\n    1 << 7, // TEXTURE_NEAREST_SAMPLINGMODE / TEXTURE_NEAREST_NEAREST\r\n    1 << 7, // TEXTURE_BILINEAR_SAMPLINGMODE / TEXTURE_LINEAR_LINEAR\r\n    0 << 7, // TEXTURE_TRILINEAR_SAMPLINGMODE / TEXTURE_LINEAR_LINEAR_MIPLINEAR\r\n    0 << 7, // TEXTURE_NEAREST_NEAREST_MIPNEAREST\r\n    0 << 7, // TEXTURE_NEAREST_LINEAR_MIPNEAREST\r\n    0 << 7, // TEXTURE_NEAREST_LINEAR_MIPLINEAR\r\n    1 << 7, // TEXTURE_NEAREST_LINEAR\r\n    0 << 7, // TEXTURE_NEAREST_NEAREST_MIPLINEAR\r\n    0 << 7, // TEXTURE_LINEAR_NEAREST_MIPNEAREST\r\n    0 << 7, // TEXTURE_LINEAR_NEAREST_MIPLINEAR\r\n    0 << 7, // TEXTURE_LINEAR_LINEAR_MIPNEAREST\r\n    1 << 7, // TEXTURE_LINEAR_NEAREST\r\n];\r\n\r\n/** @internal */\r\nexport class WebGPUCacheSampler {\r\n    private _samplers: { [hash: number]: GPUSampler } = {};\r\n    private _device: GPUDevice;\r\n\r\n    public disabled: boolean;\r\n\r\n    constructor(device: GPUDevice) {\r\n        this._device = device;\r\n        this.disabled = false;\r\n    }\r\n\r\n    public static GetSamplerHashCode(sampler: TextureSampler): number {\r\n        // The WebGPU spec currently only allows values 1 and 4 for anisotropy\r\n        const anisotropy = sampler._cachedAnisotropicFilteringLevel ? sampler._cachedAnisotropicFilteringLevel : 1;\r\n        const code =\r\n            FilterToBits[sampler.samplingMode] +\r\n            ComparisonFunctionToBits[(sampler._comparisonFunction || 0x0202) - 0x0200 + 1] +\r\n            FilterNoMipToBits[sampler.samplingMode] + // handle the lodMinClamp = lodMaxClamp = 0 case when no filter used for mip mapping\r\n            ((sampler._cachedWrapU ?? 1) << 8) +\r\n            ((sampler._cachedWrapV ?? 1) << 10) +\r\n            ((sampler._cachedWrapR ?? 1) << 12) +\r\n            ((sampler.useMipMaps ? 1 : 0) << 14) + // need to factor this in because _getSamplerFilterDescriptor depends on samplingMode AND useMipMaps!\r\n            (anisotropy << 15);\r\n\r\n        return code;\r\n    }\r\n\r\n    private static _GetSamplerFilterDescriptor(\r\n        sampler: TextureSampler,\r\n        anisotropy: number\r\n    ): {\r\n        magFilter: GPUFilterMode;\r\n        minFilter: GPUFilterMode;\r\n        mipmapFilter: GPUFilterMode;\r\n        lodMinClamp?: number;\r\n        lodMaxClamp?: number;\r\n        anisotropyEnabled?: boolean;\r\n    } {\r\n        let magFilter: GPUFilterMode, minFilter: GPUFilterMode, mipmapFilter: GPUFilterMode, lodMinClamp: number | undefined, lodMaxClamp: number | undefined;\r\n        const useMipMaps = sampler.useMipMaps;\r\n        switch (sampler.samplingMode) {\r\n            case Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST:\r\n                magFilter = WebGPUConstants.FilterMode.Linear;\r\n                minFilter = WebGPUConstants.FilterMode.Linear;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                if (!useMipMaps) {\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                }\r\n                break;\r\n            /* case Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR: */ // same value as below\r\n            case Constants.TEXTURE_TRILINEAR_SAMPLINGMODE:\r\n                magFilter = WebGPUConstants.FilterMode.Linear;\r\n                minFilter = WebGPUConstants.FilterMode.Linear;\r\n                if (!useMipMaps) {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                } else {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Linear;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                if (!useMipMaps) {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                } else {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Linear;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                if (!useMipMaps) {\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Linear;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                if (!useMipMaps) {\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Linear;\r\n                if (!useMipMaps) {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                } else {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Linear;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_NEAREST_LINEAR:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Linear;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                lodMinClamp = lodMaxClamp = 0;\r\n                break;\r\n            /* case Constants.TEXTURE_NEAREST_NEAREST: */ // same value as below\r\n            case Constants.TEXTURE_NEAREST_SAMPLINGMODE:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                lodMinClamp = lodMaxClamp = 0;\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST:\r\n                magFilter = WebGPUConstants.FilterMode.Linear;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                if (!useMipMaps) {\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR:\r\n                magFilter = WebGPUConstants.FilterMode.Linear;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                if (!useMipMaps) {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                } else {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Linear;\r\n                }\r\n                break;\r\n            /* case Constants.TEXTURE_LINEAR_LINEAR: */ // same value as below\r\n            case Constants.TEXTURE_BILINEAR_SAMPLINGMODE:\r\n                magFilter = WebGPUConstants.FilterMode.Linear;\r\n                minFilter = WebGPUConstants.FilterMode.Linear;\r\n                // In WebGL, if sampling mode is TEXTURE_BILINEAR_SAMPLINGMODE and anisotropy is greater than 1, anisotropy is enabled for the sampler\r\n                if (anisotropy > 1) {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Linear;\r\n                } else {\r\n                    mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                    lodMinClamp = lodMaxClamp = 0;\r\n                }\r\n                break;\r\n            case Constants.TEXTURE_LINEAR_NEAREST:\r\n                magFilter = WebGPUConstants.FilterMode.Linear;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                lodMinClamp = lodMaxClamp = 0;\r\n                break;\r\n            default:\r\n                magFilter = WebGPUConstants.FilterMode.Nearest;\r\n                minFilter = WebGPUConstants.FilterMode.Nearest;\r\n                mipmapFilter = WebGPUConstants.FilterMode.Nearest;\r\n                lodMinClamp = lodMaxClamp = 0;\r\n                break;\r\n        }\r\n\r\n        if (anisotropy > 1 && (lodMinClamp !== 0 || lodMaxClamp !== 0)) {\r\n            return {\r\n                magFilter: WebGPUConstants.FilterMode.Linear,\r\n                minFilter: WebGPUConstants.FilterMode.Linear,\r\n                mipmapFilter: WebGPUConstants.FilterMode.Linear,\r\n                anisotropyEnabled: true,\r\n            };\r\n        }\r\n\r\n        return {\r\n            magFilter,\r\n            minFilter,\r\n            mipmapFilter,\r\n            lodMinClamp,\r\n            lodMaxClamp,\r\n        };\r\n    }\r\n\r\n    private static _GetWrappingMode(mode: number): GPUAddressMode {\r\n        switch (mode) {\r\n            case Constants.TEXTURE_WRAP_ADDRESSMODE:\r\n                return WebGPUConstants.AddressMode.Repeat;\r\n            case Constants.TEXTURE_CLAMP_ADDRESSMODE:\r\n                return WebGPUConstants.AddressMode.ClampToEdge;\r\n            case Constants.TEXTURE_MIRROR_ADDRESSMODE:\r\n                return WebGPUConstants.AddressMode.MirrorRepeat;\r\n        }\r\n        return WebGPUConstants.AddressMode.Repeat;\r\n    }\r\n\r\n    private static _GetSamplerWrappingDescriptor(sampler: TextureSampler): {\r\n        addressModeU: GPUAddressMode;\r\n        addressModeV: GPUAddressMode;\r\n        addressModeW: GPUAddressMode;\r\n    } {\r\n        return {\r\n            addressModeU: this._GetWrappingMode(sampler._cachedWrapU!),\r\n            addressModeV: this._GetWrappingMode(sampler._cachedWrapV!),\r\n            addressModeW: this._GetWrappingMode(sampler._cachedWrapR!),\r\n        };\r\n    }\r\n\r\n    private static _GetSamplerDescriptor(sampler: TextureSampler, label?: string): GPUSamplerDescriptor {\r\n        // The check with Constants.TEXTURE_LINEAR_LINEAR is to be iso with the WebGL implementation\r\n        let anisotropy =\r\n            (sampler.useMipMaps || sampler.samplingMode === Constants.TEXTURE_LINEAR_LINEAR) && sampler._cachedAnisotropicFilteringLevel\r\n                ? sampler._cachedAnisotropicFilteringLevel\r\n                : 1;\r\n        // To be iso with the WebGL implementation\r\n        if (\r\n            sampler.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST &&\r\n            sampler.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR &&\r\n            sampler.samplingMode !== Constants.TEXTURE_LINEAR_LINEAR\r\n        ) {\r\n            anisotropy = 1;\r\n        }\r\n        const filterDescriptor = this._GetSamplerFilterDescriptor(sampler, anisotropy);\r\n        return {\r\n            label,\r\n            ...filterDescriptor,\r\n            ...this._GetSamplerWrappingDescriptor(sampler),\r\n            compare: sampler._comparisonFunction ? WebGPUCacheSampler.GetCompareFunction(sampler._comparisonFunction) : undefined,\r\n            maxAnisotropy: filterDescriptor.anisotropyEnabled ? anisotropy : 1,\r\n        };\r\n    }\r\n\r\n    public static GetCompareFunction(compareFunction: Nullable<number>): GPUCompareFunction {\r\n        switch (compareFunction) {\r\n            case Constants.ALWAYS:\r\n                return WebGPUConstants.CompareFunction.Always;\r\n            case Constants.EQUAL:\r\n                return WebGPUConstants.CompareFunction.Equal;\r\n            case Constants.GREATER:\r\n                return WebGPUConstants.CompareFunction.Greater;\r\n            case Constants.GEQUAL:\r\n                return WebGPUConstants.CompareFunction.GreaterEqual;\r\n            case Constants.LESS:\r\n                return WebGPUConstants.CompareFunction.Less;\r\n            case Constants.LEQUAL:\r\n                return WebGPUConstants.CompareFunction.LessEqual;\r\n            case Constants.NEVER:\r\n                return WebGPUConstants.CompareFunction.Never;\r\n            case Constants.NOTEQUAL:\r\n                return WebGPUConstants.CompareFunction.NotEqual;\r\n            default:\r\n                return WebGPUConstants.CompareFunction.Less;\r\n        }\r\n    }\r\n\r\n    public getSampler(sampler: TextureSampler, bypassCache = false, hash = 0, label?: string): GPUSampler {\r\n        if (this.disabled) {\r\n            return this._device.createSampler(WebGPUCacheSampler._GetSamplerDescriptor(sampler, label));\r\n        }\r\n\r\n        if (bypassCache) {\r\n            hash = 0;\r\n        } else if (hash === 0) {\r\n            hash = WebGPUCacheSampler.GetSamplerHashCode(sampler);\r\n        }\r\n\r\n        let gpuSampler = bypassCache ? undefined : this._samplers[hash];\r\n        if (!gpuSampler) {\r\n            gpuSampler = this._device.createSampler(WebGPUCacheSampler._GetSamplerDescriptor(sampler, label));\r\n            if (!bypassCache) {\r\n                this._samplers[hash] = gpuSampler;\r\n            }\r\n        }\r\n\r\n        return gpuSampler;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\nimport { type Nullable } from \"../../types\";\r\nimport { WebGPUCacheRenderPipeline } from \"./webgpuCacheRenderPipeline\";\r\n\r\n/** @internal */\r\nclass NodeState {\r\n    public values: { [id: number]: NodeState };\r\n    public pipeline: GPURenderPipeline;\r\n\r\n    constructor() {\r\n        this.values = {};\r\n    }\r\n\r\n    public count(): [number, number] {\r\n        let countNode = 0,\r\n            countPipeline = this.pipeline ? 1 : 0;\r\n        for (const value in this.values) {\r\n            const node = this.values[value];\r\n            const [childCountNodes, childCoundPipeline] = node.count();\r\n            countNode += childCountNodes;\r\n            countPipeline += childCoundPipeline;\r\n            countNode++;\r\n        }\r\n        return [countNode, countPipeline];\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUCacheRenderPipelineTree extends WebGPUCacheRenderPipeline {\r\n    private static _Cache: NodeState = new NodeState();\r\n\r\n    private _nodeStack: NodeState[];\r\n\r\n    public static GetNodeCounts(): { nodeCount: number; pipelineCount: number } {\r\n        const counts = WebGPUCacheRenderPipelineTree._Cache.count();\r\n\r\n        return { nodeCount: counts[0], pipelineCount: counts[1] };\r\n    }\r\n\r\n    public static _GetPipelines(node: NodeState, pipelines: Array<Array<number>>, curPath: Array<number>, curPathLen: number): void {\r\n        if (node.pipeline) {\r\n            const path = curPath.slice();\r\n            path.length = curPathLen;\r\n            pipelines.push(path);\r\n        }\r\n        for (const value in node.values) {\r\n            const nnode = node.values[value];\r\n            curPath[curPathLen] = parseInt(value);\r\n            WebGPUCacheRenderPipelineTree._GetPipelines(nnode, pipelines, curPath, curPathLen + 1);\r\n        }\r\n    }\r\n\r\n    public static GetPipelines(): Array<Array<number>> {\r\n        const pipelines: Array<Array<number>> = [];\r\n        WebGPUCacheRenderPipelineTree._GetPipelines(WebGPUCacheRenderPipelineTree._Cache, pipelines, [], 0);\r\n        return pipelines;\r\n    }\r\n\r\n    public static ResetCache() {\r\n        WebGPUCacheRenderPipelineTree._Cache = new NodeState();\r\n    }\r\n\r\n    public override reset(): void {\r\n        this._nodeStack = [];\r\n        this._nodeStack[0] = WebGPUCacheRenderPipelineTree._Cache;\r\n        super.reset();\r\n    }\r\n\r\n    protected _getRenderPipeline(param: { token: any; pipeline: Nullable<GPURenderPipeline> }): void {\r\n        let node = this._nodeStack[this._stateDirtyLowestIndex];\r\n        for (let i = this._stateDirtyLowestIndex; i < this._statesLength; ++i) {\r\n            let nn: NodeState | undefined = node.values[this._states[i]];\r\n            if (!nn) {\r\n                nn = new NodeState();\r\n                node.values[this._states[i]] = nn;\r\n            }\r\n            node = nn;\r\n            this._nodeStack[i + 1] = node;\r\n        }\r\n\r\n        param.token = node;\r\n        param.pipeline = node.pipeline;\r\n    }\r\n\r\n    protected _setRenderPipeline(param: { token: NodeState; pipeline: Nullable<GPURenderPipeline> }): void {\r\n        param.token.pipeline = param.pipeline!;\r\n    }\r\n}\r\n","import { type WebGPUCacheRenderPipeline } from \"./webgpuCacheRenderPipeline\";\r\nimport { StencilStateComposer } from \"../../States/stencilStateComposer\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class WebGPUStencilStateComposer extends StencilStateComposer {\r\n    private _cache: WebGPUCacheRenderPipeline;\r\n\r\n    public constructor(cache: WebGPUCacheRenderPipeline) {\r\n        super(false);\r\n        this._cache = cache;\r\n        this.reset();\r\n    }\r\n\r\n    public override get func(): number {\r\n        return this._func;\r\n    }\r\n\r\n    public override set func(value: number) {\r\n        if (this._func === value) {\r\n            return;\r\n        }\r\n\r\n        this._func = value;\r\n        this._cache.setStencilCompare(value);\r\n    }\r\n\r\n    public override get backFunc(): number {\r\n        return this._backFunc;\r\n    }\r\n\r\n    public override set backFunc(value: number) {\r\n        if (this._backFunc === value) {\r\n            return;\r\n        }\r\n\r\n        this._backFunc = value;\r\n        this._cache.setStencilBackCompare(value);\r\n    }\r\n\r\n    public override get funcMask(): number {\r\n        return this._funcMask;\r\n    }\r\n\r\n    public override set funcMask(value: number) {\r\n        if (this._funcMask === value) {\r\n            return;\r\n        }\r\n\r\n        this._funcMask = value;\r\n        this._cache.setStencilReadMask(value);\r\n    }\r\n\r\n    public override get opStencilFail(): number {\r\n        return this._opStencilFail;\r\n    }\r\n\r\n    public override set opStencilFail(value: number) {\r\n        if (this._opStencilFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._opStencilFail = value;\r\n        this._cache.setStencilFailOp(value);\r\n    }\r\n\r\n    public override get opDepthFail(): number {\r\n        return this._opDepthFail;\r\n    }\r\n\r\n    public override set opDepthFail(value: number) {\r\n        if (this._opDepthFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._opDepthFail = value;\r\n        this._cache.setStencilDepthFailOp(value);\r\n    }\r\n\r\n    public override get opStencilDepthPass(): number {\r\n        return this._opStencilDepthPass;\r\n    }\r\n\r\n    public override set opStencilDepthPass(value: number) {\r\n        if (this._opStencilDepthPass === value) {\r\n            return;\r\n        }\r\n\r\n        this._opStencilDepthPass = value;\r\n        this._cache.setStencilPassOp(value);\r\n    }\r\n\r\n    public override get backOpStencilFail(): number {\r\n        return this._backOpStencilFail;\r\n    }\r\n\r\n    public override set backOpStencilFail(value: number) {\r\n        if (this._backOpStencilFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._backOpStencilFail = value;\r\n        this._cache.setStencilBackFailOp(value);\r\n    }\r\n\r\n    public override get backOpDepthFail(): number {\r\n        return this._backOpDepthFail;\r\n    }\r\n\r\n    public override set backOpDepthFail(value: number) {\r\n        if (this._backOpDepthFail === value) {\r\n            return;\r\n        }\r\n\r\n        this._backOpDepthFail = value;\r\n        this._cache.setStencilBackDepthFailOp(value);\r\n    }\r\n\r\n    public override get backOpStencilDepthPass(): number {\r\n        return this._backOpStencilDepthPass;\r\n    }\r\n\r\n    public override set backOpStencilDepthPass(value: number) {\r\n        if (this._backOpStencilDepthPass === value) {\r\n            return;\r\n        }\r\n\r\n        this._backOpStencilDepthPass = value;\r\n        this._cache.setStencilBackPassOp(value);\r\n    }\r\n\r\n    public override get mask(): number {\r\n        return this._mask;\r\n    }\r\n\r\n    public override set mask(value: number) {\r\n        if (this._mask === value) {\r\n            return;\r\n        }\r\n\r\n        this._mask = value;\r\n        this._cache.setStencilWriteMask(value);\r\n    }\r\n\r\n    public override get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public override set enabled(value: boolean) {\r\n        if (this._enabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._enabled = value;\r\n        this._cache.setStencilEnabled(value);\r\n    }\r\n\r\n    public override reset() {\r\n        super.reset();\r\n        this._cache.resetStencilState();\r\n    }\r\n\r\n    public override apply() {\r\n        const stencilMaterialEnabled = !this.useStencilGlobalOnly && !!this.stencilMaterial?.enabled;\r\n\r\n        this.enabled = stencilMaterialEnabled ? this.stencilMaterial!.enabled : this.stencilGlobal.enabled;\r\n        if (!this.enabled) {\r\n            return;\r\n        }\r\n\r\n        this.mask = stencilMaterialEnabled ? this.stencilMaterial!.mask : this.stencilGlobal.mask;\r\n        this.funcRef = stencilMaterialEnabled ? this.stencilMaterial!.funcRef : this.stencilGlobal.funcRef;\r\n        this.funcMask = stencilMaterialEnabled ? this.stencilMaterial!.funcMask : this.stencilGlobal.funcMask;\r\n        this.func = stencilMaterialEnabled ? this.stencilMaterial!.func : this.stencilGlobal.func;\r\n        this.opStencilFail = stencilMaterialEnabled ? this.stencilMaterial!.opStencilFail : this.stencilGlobal.opStencilFail;\r\n        this.opDepthFail = stencilMaterialEnabled ? this.stencilMaterial!.opDepthFail : this.stencilGlobal.opDepthFail;\r\n        this.opStencilDepthPass = stencilMaterialEnabled ? this.stencilMaterial!.opStencilDepthPass : this.stencilGlobal.opStencilDepthPass;\r\n        this.backFunc = stencilMaterialEnabled ? this.stencilMaterial!.backFunc : this.stencilGlobal.backFunc;\r\n        this.backOpStencilFail = stencilMaterialEnabled ? this.stencilMaterial!.backOpStencilFail : this.stencilGlobal.backOpStencilFail;\r\n        this.backOpDepthFail = stencilMaterialEnabled ? this.stencilMaterial!.backOpDepthFail : this.stencilGlobal.backOpDepthFail;\r\n        this.backOpStencilDepthPass = stencilMaterialEnabled ? this.stencilMaterial!.backOpStencilDepthPass : this.stencilGlobal.backOpStencilDepthPass;\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type WebGPUCacheRenderPipeline } from \"./webgpuCacheRenderPipeline\";\r\nimport { DepthCullingState } from \"../../States/depthCullingState\";\r\n\r\n/**\r\n * @internal\r\n **/\r\nexport class WebGPUDepthCullingState extends DepthCullingState {\r\n    private _cache: WebGPUCacheRenderPipeline;\r\n\r\n    /**\r\n     * Initializes the state.\r\n     * @param cache\r\n     */\r\n    public constructor(cache: WebGPUCacheRenderPipeline) {\r\n        super(false);\r\n        this._cache = cache;\r\n        this.reset();\r\n    }\r\n\r\n    public override get zOffset(): number {\r\n        return this._zOffset;\r\n    }\r\n\r\n    public override set zOffset(value: number) {\r\n        if (this._zOffset === value) {\r\n            return;\r\n        }\r\n\r\n        this._zOffset = value;\r\n        this._isZOffsetDirty = true;\r\n        this._cache.setDepthBiasSlopeScale(value);\r\n    }\r\n\r\n    public override get zOffsetUnits(): number {\r\n        return this._zOffsetUnits;\r\n    }\r\n\r\n    public override set zOffsetUnits(value: number) {\r\n        if (this._zOffsetUnits === value) {\r\n            return;\r\n        }\r\n\r\n        this._zOffsetUnits = value;\r\n        this._isZOffsetDirty = true;\r\n        this._cache.setDepthBias(value);\r\n    }\r\n\r\n    public override get cullFace(): Nullable<number> {\r\n        return this._cullFace;\r\n    }\r\n\r\n    public override set cullFace(value: Nullable<number>) {\r\n        if (this._cullFace === value) {\r\n            return;\r\n        }\r\n\r\n        this._cullFace = value;\r\n        this._isCullFaceDirty = true;\r\n        this._cache.setCullFace(value ?? 1);\r\n    }\r\n\r\n    public override get cull(): Nullable<boolean> {\r\n        return this._cull;\r\n    }\r\n\r\n    public override set cull(value: Nullable<boolean>) {\r\n        if (this._cull === value) {\r\n            return;\r\n        }\r\n\r\n        this._cull = value;\r\n        this._isCullDirty = true;\r\n        this._cache.setCullEnabled(!!value);\r\n    }\r\n\r\n    public override get depthFunc(): Nullable<number> {\r\n        return this._depthFunc;\r\n    }\r\n\r\n    public override set depthFunc(value: Nullable<number>) {\r\n        if (this._depthFunc === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthFunc = value;\r\n        this._isDepthFuncDirty = true;\r\n        this._cache.setDepthCompare(value);\r\n    }\r\n\r\n    public override get depthMask(): boolean {\r\n        return this._depthMask;\r\n    }\r\n\r\n    public override set depthMask(value: boolean) {\r\n        if (this._depthMask === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthMask = value;\r\n        this._isDepthMaskDirty = true;\r\n        this._cache.setDepthWriteEnabled(value);\r\n    }\r\n\r\n    public override get depthTest(): boolean {\r\n        return this._depthTest;\r\n    }\r\n\r\n    public override set depthTest(value: boolean) {\r\n        if (this._depthTest === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthTest = value;\r\n        this._isDepthTestDirty = true;\r\n        this._cache.setDepthTestEnabled(value);\r\n    }\r\n\r\n    public override get frontFace(): Nullable<number> {\r\n        return this._frontFace;\r\n    }\r\n\r\n    public override set frontFace(value: Nullable<number>) {\r\n        if (this._frontFace === value) {\r\n            return;\r\n        }\r\n\r\n        this._frontFace = value;\r\n        this._isFrontFaceDirty = true;\r\n        this._cache.setFrontFace(value ?? 2);\r\n    }\r\n\r\n    public override reset() {\r\n        super.reset();\r\n        this._cache.resetDepthCullingState();\r\n    }\r\n\r\n    public override apply() {\r\n        // nothing to do\r\n    }\r\n}\r\n","import { Constants } from \"../../Engines/constants\";\r\nimport { InternalTexture } from \"./internalTexture\";\r\n\r\n/**\r\n * Class used to store an external texture (like GPUExternalTexture in WebGPU)\r\n */\r\nexport class ExternalTexture {\r\n    /**\r\n     * Checks if a texture is an external or internal texture\r\n     * @param texture the external or internal texture\r\n     * @returns true if the texture is an external texture, else false\r\n     */\r\n    public static IsExternalTexture(texture: ExternalTexture | InternalTexture): texture is ExternalTexture {\r\n        return (texture as ExternalTexture).underlyingResource !== undefined;\r\n    }\r\n\r\n    private _video: HTMLVideoElement;\r\n\r\n    /**\r\n     * Get the class name of the texture.\r\n     * @returns \"ExternalTexture\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"ExternalTexture\";\r\n    }\r\n\r\n    /**\r\n     * Gets the underlying texture object\r\n     */\r\n    public get underlyingResource(): any {\r\n        return this._video;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the texture uses mipmaps\r\n     */\r\n    public useMipMaps: boolean = false;\r\n\r\n    /**\r\n     * The type of the underlying texture is implementation dependent, so return \"UNDEFINED\" for the type\r\n     */\r\n    public readonly type = Constants.TEXTURETYPE_UNDEFINED;\r\n\r\n    /**\r\n     * The format of the underlying texture is implementation dependent, so return \"UNDEFINED\" for the format\r\n     */\r\n    public readonly format = Constants.TEXTUREFORMAT_UNDEFINED;\r\n\r\n    /**\r\n     * Gets the unique id of this texture\r\n     */\r\n    public readonly uniqueId: number;\r\n\r\n    /**\r\n     * Constructs the texture\r\n     * @param video The video the texture should be wrapped around\r\n     */\r\n    constructor(video: HTMLVideoElement) {\r\n        this._video = video;\r\n        this.uniqueId = InternalTexture._Counter++;\r\n    }\r\n\r\n    /**\r\n     * Get if the texture is ready to be used (downloaded, converted, mip mapped...).\r\n     * @returns true if fully ready\r\n     */\r\n    public isReady(): boolean {\r\n        return this._video.readyState >= this._video.HAVE_CURRENT_DATA;\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public dispose(): void {}\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { ExternalTexture } from \"../../Materials/Textures/externalTexture\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type TextureSampler } from \"../../Materials/Textures/textureSampler\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../constants\";\r\nimport { type IMaterialContext } from \"../IMaterialContext\";\r\nimport { WebGPUCacheSampler } from \"./webgpuCacheSampler\";\r\n\r\n/** @internal */\r\ninterface IWebGPUMaterialContextSamplerCache {\r\n    sampler: Nullable<TextureSampler>;\r\n    hashCode: number;\r\n}\r\n\r\n/** @internal */\r\ninterface IWebGPUMaterialContextTextureCache {\r\n    texture: Nullable<InternalTexture | ExternalTexture>;\r\n    isFloatOrDepthTexture: boolean;\r\n    isExternalTexture: boolean;\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUMaterialContext implements IMaterialContext {\r\n    private static _Counter = 0;\r\n\r\n    public uniqueId: number;\r\n    public updateId: number;\r\n    public isDirty: boolean;\r\n    public samplers: { [name: string]: Nullable<IWebGPUMaterialContextSamplerCache> };\r\n    public textures: { [name: string]: Nullable<IWebGPUMaterialContextTextureCache> };\r\n\r\n    // The texture state is a bitfield where each bit is set if the texture is a float32 texture (calculated in @WebGPUEngine._draw).\r\n    // Float32 textures must be handled differently because float filtering may not be supported by the underlying browser implementation.\r\n    // In this case, we must configure the sampler as \"non filtering\", as well as set the texture sample type to \"unfilterable-float\" when creating the bind group layout.\r\n    // When that happens, we end up with different bind group layouts (depending on which type of textures have been set in the material), that we must all store\r\n    // in the WebGPUPipelineContext (see @WebGPUPipelineContext.bindGroupLayouts) for later retrieval in the bind group cache implementation (see @WebGPUCacheBindGroups.getBindGroups), thanks to this property.\r\n    // There's the same problem with depth textures, where \"float\" filtering is not supported either.\r\n    public textureState: number;\r\n\r\n    public useVertexPulling = false;\r\n\r\n    public get forceBindGroupCreation() {\r\n        // If there is at least one external texture to bind, we must recreate the bind groups each time\r\n        // because we need to retrieve a new texture each frame (by calling device.importExternalTexture)\r\n        return this._numExternalTextures > 0;\r\n    }\r\n\r\n    public get hasFloatOrDepthTextures() {\r\n        return this._numFloatOrDepthTextures > 0;\r\n    }\r\n\r\n    protected _numFloatOrDepthTextures: number;\r\n    protected _numExternalTextures: number;\r\n\r\n    constructor() {\r\n        this.uniqueId = WebGPUMaterialContext._Counter++;\r\n        this.updateId = 0;\r\n        this.textureState = 0;\r\n        this.reset();\r\n    }\r\n\r\n    public reset(): void {\r\n        this.samplers = {};\r\n        this.textures = {};\r\n        this.isDirty = true;\r\n        this._numFloatOrDepthTextures = 0;\r\n        this._numExternalTextures = 0;\r\n    }\r\n\r\n    public setSampler(name: string, sampler: Nullable<TextureSampler>): void {\r\n        let samplerCache = this.samplers[name];\r\n        let currentHashCode = -1;\r\n        if (!samplerCache) {\r\n            this.samplers[name] = samplerCache = { sampler, hashCode: 0 };\r\n        } else {\r\n            currentHashCode = samplerCache.hashCode;\r\n        }\r\n\r\n        samplerCache.sampler = sampler;\r\n        samplerCache.hashCode = sampler ? WebGPUCacheSampler.GetSamplerHashCode(sampler) : 0;\r\n\r\n        const isDirty = currentHashCode !== samplerCache.hashCode;\r\n        if (isDirty) {\r\n            this.updateId++;\r\n        }\r\n\r\n        this.isDirty ||= isDirty;\r\n    }\r\n\r\n    public setTexture(name: string, texture: Nullable<InternalTexture | ExternalTexture>): void {\r\n        let textureCache = this.textures[name];\r\n        let currentTextureId = -1;\r\n        if (!textureCache) {\r\n            this.textures[name] = textureCache = { texture, isFloatOrDepthTexture: false, isExternalTexture: false };\r\n        } else {\r\n            currentTextureId = textureCache.texture?.uniqueId ?? -1;\r\n        }\r\n\r\n        if (textureCache.isExternalTexture) {\r\n            this._numExternalTextures--;\r\n        }\r\n        if (textureCache.isFloatOrDepthTexture) {\r\n            this._numFloatOrDepthTextures--;\r\n        }\r\n\r\n        if (texture) {\r\n            textureCache.isFloatOrDepthTexture =\r\n                texture.type === Constants.TEXTURETYPE_FLOAT ||\r\n                (texture.format >= Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 && texture.format <= Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8);\r\n            textureCache.isExternalTexture = ExternalTexture.IsExternalTexture(texture);\r\n            if (textureCache.isFloatOrDepthTexture) {\r\n                this._numFloatOrDepthTextures++;\r\n            }\r\n            if (textureCache.isExternalTexture) {\r\n                this._numExternalTextures++;\r\n            }\r\n        } else {\r\n            textureCache.isFloatOrDepthTexture = false;\r\n            textureCache.isExternalTexture = false;\r\n        }\r\n\r\n        textureCache.texture = texture;\r\n\r\n        const isDirty = currentTextureId !== (texture?.uniqueId ?? -1);\r\n        if (isDirty) {\r\n            this.updateId++;\r\n        }\r\n\r\n        this.isDirty ||= isDirty;\r\n    }\r\n}\r\n","import { type VertexBuffer } from \"../../Buffers/buffer\";\r\nimport { type DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { type WebGPUDataBuffer } from \"../../Meshes/WebGPU/webgpuDataBuffer\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IDrawContext } from \"../IDrawContext\";\r\nimport { type WebGPUBufferManager } from \"./webgpuBufferManager\";\r\nimport { type WebGPUPipelineContext } from \"./webgpuPipelineContext\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\n\r\n/**\r\n * WebGPU implementation of the IDrawContext interface.\r\n * This class manages the draw context for WebGPU, including buffers and indirect draw data.\r\n */\r\nexport class WebGPUDrawContext implements IDrawContext {\r\n    private static _Counter = 0;\r\n\r\n    /**\r\n     * Bundle used in fast mode (when compatibilityMode==false)\r\n     */\r\n    public fastBundle?: GPURenderBundle;\r\n    /**\r\n     * Cache of the bind groups. Will be reused for the next draw if isDirty==false (and materialContext.isDirty==false)\r\n     */\r\n    public bindGroups?: GPUBindGroup[];\r\n\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * @internal\r\n     * By default, indirect draws are enabled in NON compatibility mode only\r\n     * To enable indirect draws in compatibility mode (done by the end user), enableIndirectDraw must be set to true\r\n     */\r\n    public _enableIndirectDrawInCompatMode = false;\r\n\r\n    /**\r\n     * Buffers (uniform / storage) used for the draw call\r\n     */\r\n    public buffers: { [name: string]: Nullable<WebGPUDataBuffer> };\r\n\r\n    public indirectDrawBuffer?: GPUBuffer;\r\n\r\n    private _materialContextUpdateId: number;\r\n    private _bufferManager: WebGPUBufferManager;\r\n    private _useInstancing: boolean;\r\n    private _indirectDrawData?: Uint32Array;\r\n    private _currentInstanceCount: number;\r\n    private _isDirty: boolean;\r\n    private _enableIndirectDraw: boolean;\r\n    private _vertexPullingEnabled: boolean;\r\n\r\n    /**\r\n     * Uniform buffers in which this context owns a slot. Filled by the buffers themselves.\r\n     * @internal\r\n     */\r\n    public _uniformBuffersWithOwnedSlot?: UniformBuffer[];\r\n\r\n    /**\r\n     * Checks if the draw context is dirty.\r\n     * @param materialContextUpdateId The update ID of the material context associated with the draw context.\r\n     * @returns True if the draw or material context is dirty, false otherwise.\r\n     */\r\n    public isDirty(materialContextUpdateId: number): boolean {\r\n        return this._isDirty || this._materialContextUpdateId !== materialContextUpdateId;\r\n    }\r\n\r\n    /**\r\n     * Resets the dirty state of the draw context.\r\n     * @param materialContextUpdateId The update ID of the material context associated with the draw context.\r\n     */\r\n    public resetIsDirty(materialContextUpdateId: number): void {\r\n        this._isDirty = false;\r\n        this._materialContextUpdateId = materialContextUpdateId;\r\n    }\r\n\r\n    public get enableIndirectDraw() {\r\n        return this._enableIndirectDraw;\r\n    }\r\n\r\n    public set enableIndirectDraw(enable: boolean) {\r\n        this._enableIndirectDrawInCompatMode = true;\r\n\r\n        if (this._enableIndirectDraw === enable) {\r\n            return;\r\n        }\r\n\r\n        this._enableIndirectDraw = enable;\r\n\r\n        if (!enable && !this._useInstancing && this.indirectDrawBuffer) {\r\n            this._bufferManager.releaseBuffer(this.indirectDrawBuffer);\r\n            this.indirectDrawBuffer = undefined;\r\n            this._indirectDrawData = undefined;\r\n        } else if (enable && !this.indirectDrawBuffer) {\r\n            this.indirectDrawBuffer = this._bufferManager.createRawBuffer(\r\n                20,\r\n                WebGPUConstants.BufferUsage.CopyDst | WebGPUConstants.BufferUsage.Indirect | WebGPUConstants.BufferUsage.Storage,\r\n                undefined,\r\n                \"IndirectDrawBuffer\"\r\n            );\r\n            this._indirectDrawData = new Uint32Array(5);\r\n            this._indirectDrawData[3] = 0;\r\n            this._indirectDrawData[4] = 0;\r\n        }\r\n    }\r\n\r\n    public get useInstancing() {\r\n        return this._useInstancing;\r\n    }\r\n\r\n    public set useInstancing(use: boolean) {\r\n        if (this._useInstancing === use) {\r\n            return;\r\n        }\r\n\r\n        this._useInstancing = use;\r\n        this._currentInstanceCount = -1;\r\n\r\n        const enableIndirectDrawInCompatMode = this._enableIndirectDrawInCompatMode;\r\n\r\n        this.enableIndirectDraw = use;\r\n\r\n        this._enableIndirectDrawInCompatMode = enableIndirectDrawInCompatMode;\r\n    }\r\n\r\n    /**\r\n     * Creates a new WebGPUDrawContext.\r\n     * @param bufferManager The buffer manager used to manage WebGPU buffers.\r\n     * @param _dummyIndexBuffer A dummy index buffer to be bound as the \"indices\"\r\n     * storage buffer when no index buffer is provided.\r\n     */\r\n    constructor(\r\n        bufferManager: WebGPUBufferManager,\r\n        private _dummyIndexBuffer: WebGPUDataBuffer\r\n    ) {\r\n        this._bufferManager = bufferManager;\r\n        this.uniqueId = WebGPUDrawContext._Counter++;\r\n        this._useInstancing = false;\r\n        this._currentInstanceCount = 0;\r\n        this._enableIndirectDraw = false;\r\n        this._vertexPullingEnabled = false;\r\n        this.reset();\r\n    }\r\n\r\n    public reset(): void {\r\n        this._releaseUniformBufferSlots();\r\n        this.buffers = {};\r\n        this._isDirty = true;\r\n        this._materialContextUpdateId = 0;\r\n        this.fastBundle = undefined;\r\n        this.bindGroups = undefined;\r\n        this._vertexPullingEnabled = false;\r\n    }\r\n\r\n    /**\r\n     * Associates a buffer to the draw context.\r\n     * @param name The name of the buffer.\r\n     * @param buffer The buffer to set.\r\n     */\r\n    public setBuffer(name: string, buffer: Nullable<WebGPUDataBuffer>): void {\r\n        this._isDirty ||= buffer?.uniqueId !== this.buffers[name]?.uniqueId;\r\n\r\n        this.buffers[name] = buffer;\r\n    }\r\n\r\n    public setIndirectData(indexOrVertexCount: number, instanceCount: number, firstIndexOrVertex: number, forceUpdate = false): void {\r\n        if ((!forceUpdate && instanceCount === this._currentInstanceCount) || !this.indirectDrawBuffer || !this._indirectDrawData) {\r\n            // The current buffer is already up to date so do nothing\r\n            // Note that we only check for instanceCount and not indexOrVertexCount nor firstIndexOrVertex because those values\r\n            // are supposed to not change during the lifetime of a draw context\r\n            return;\r\n        }\r\n        this._currentInstanceCount = instanceCount;\r\n\r\n        this._indirectDrawData[0] = indexOrVertexCount;\r\n        this._indirectDrawData[1] = instanceCount;\r\n        this._indirectDrawData[2] = firstIndexOrVertex;\r\n\r\n        this._bufferManager.setRawData(this.indirectDrawBuffer, 0, this._indirectDrawData, 0, 20);\r\n    }\r\n\r\n    /**\r\n     * Setup or disable vertex pulling as needed.\r\n     * @param useVertexPulling Use vertex pulling or not\r\n     * @param webgpuPipelineContext The WebGPU pipeline context\r\n     * @param vertexBuffers The current vertex buffers\r\n     * @param indexBuffer The current index buffer\r\n     * @param overrideVertexBuffers The vertex buffers to override\r\n     */\r\n    public setVertexPulling(\r\n        useVertexPulling: boolean,\r\n        webgpuPipelineContext: WebGPUPipelineContext,\r\n        vertexBuffers: { [key: string]: Nullable<VertexBuffer> },\r\n        indexBuffer: Nullable<DataBuffer>,\r\n        overrideVertexBuffers: Nullable<{ [kind: string]: Nullable<VertexBuffer> }>\r\n    ): void {\r\n        if (this._vertexPullingEnabled === useVertexPulling) {\r\n            return;\r\n        }\r\n\r\n        this._vertexPullingEnabled = useVertexPulling;\r\n        this._isDirty = true;\r\n\r\n        const bufferNames = webgpuPipelineContext.shaderProcessingContext.bufferNames;\r\n\r\n        if (overrideVertexBuffers) {\r\n            for (const attributeName in overrideVertexBuffers) {\r\n                const vertexBuffer = overrideVertexBuffers[attributeName];\r\n                if (!vertexBuffer || bufferNames.indexOf(attributeName) === -1) {\r\n                    continue;\r\n                }\r\n\r\n                const buffer = vertexBuffer.effectiveBuffer as Nullable<WebGPUDataBuffer>;\r\n\r\n                this.setBuffer(attributeName, useVertexPulling ? buffer : null);\r\n            }\r\n        }\r\n\r\n        for (const attributeName in vertexBuffers) {\r\n            if (overrideVertexBuffers && attributeName in overrideVertexBuffers) {\r\n                continue;\r\n            }\r\n\r\n            const vertexBuffer = vertexBuffers[attributeName];\r\n            if (!vertexBuffer || bufferNames.indexOf(attributeName) === -1) {\r\n                continue;\r\n            }\r\n\r\n            const buffer = vertexBuffer.effectiveBuffer as Nullable<WebGPUDataBuffer>;\r\n\r\n            this.setBuffer(attributeName, useVertexPulling ? buffer : null);\r\n        }\r\n\r\n        if (bufferNames.indexOf(\"indices\") !== -1) {\r\n            this.setBuffer(\"indices\", !useVertexPulling ? null : ((indexBuffer as WebGPUDataBuffer) ?? this._dummyIndexBuffer));\r\n        }\r\n    }\r\n\r\n    public dispose(): void {\r\n        this._releaseUniformBufferSlots();\r\n        if (this.indirectDrawBuffer) {\r\n            this._bufferManager.releaseBuffer(this.indirectDrawBuffer);\r\n            this.indirectDrawBuffer = undefined;\r\n            this._indirectDrawData = undefined;\r\n        }\r\n        this.fastBundle = undefined;\r\n        this.bindGroups = undefined;\r\n        this.buffers = undefined as any;\r\n        this._enableIndirectDraw = false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _releaseUniformBufferSlots(): void {\r\n        const buffers = this._uniformBuffersWithOwnedSlot;\r\n        if (!buffers) {\r\n            return;\r\n        }\r\n        // _releaseOwnerSlot removes its reciprocal entry; pop first to avoid skipping\r\n        // entries when several buffers were registered on this context.\r\n        while (buffers.length) {\r\n            buffers.pop()!._releaseOwnerSlot(this);\r\n        }\r\n        this._uniformBuffersWithOwnedSlot = undefined;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type WebGPUCacheSampler } from \"./webgpuCacheSampler\";\r\nimport { type WebGPUMaterialContext } from \"./webgpuMaterialContext\";\r\nimport { type WebGPUPipelineContext } from \"./webgpuPipelineContext\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { type WebGPUHardwareTexture } from \"./webgpuHardwareTexture\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type ExternalTexture } from \"../../Materials/Textures/externalTexture\";\r\nimport { type WebGPUDrawContext } from \"./webgpuDrawContext\";\r\n\r\n/**\r\n * Sampler hash codes are 19 bits long, so using a start value of 2^20 for buffer ids will ensure we can't have any collision with the sampler hash codes\r\n */\r\nconst BufferIdStart = 1 << 20;\r\n\r\n/**\r\n * textureIdStart is added to texture ids to ensure we can't have any collision with the buffer ids / sampler hash codes.\r\n * 2^35 for textureIdStart means we can have:\r\n * - 2^(35-20) = 2^15 = 32768 possible buffer ids\r\n * - 2^(53-35) = 2^18 = 524288 possible texture ids\r\n */\r\nconst TextureIdStart = 2 ** 35;\r\n\r\nclass WebGPUBindGroupCacheNode {\r\n    public values: { [id: number]: WebGPUBindGroupCacheNode };\r\n    public bindGroups: GPUBindGroup[];\r\n\r\n    constructor() {\r\n        this.values = {};\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUCacheBindGroups {\r\n    public static NumBindGroupsCreatedTotal = 0;\r\n    public static NumBindGroupsCreatedLastFrame = 0;\r\n    public static NumBindGroupsLookupLastFrame = 0;\r\n    public static NumBindGroupsNoLookupLastFrame = 0;\r\n\r\n    private static _Cache: WebGPUBindGroupCacheNode = new WebGPUBindGroupCacheNode();\r\n\r\n    private static _NumBindGroupsCreatedCurrentFrame = 0;\r\n    private static _NumBindGroupsLookupCurrentFrame = 0;\r\n    private static _NumBindGroupsNoLookupCurrentFrame = 0;\r\n\r\n    private _device: GPUDevice;\r\n    private _cacheSampler: WebGPUCacheSampler;\r\n    private _engine: WebGPUEngine;\r\n\r\n    public disabled = false;\r\n\r\n    public static get Statistics() {\r\n        return {\r\n            totalCreated: WebGPUCacheBindGroups.NumBindGroupsCreatedTotal,\r\n            lastFrameCreated: WebGPUCacheBindGroups.NumBindGroupsCreatedLastFrame,\r\n            lookupLastFrame: WebGPUCacheBindGroups.NumBindGroupsLookupLastFrame,\r\n            noLookupLastFrame: WebGPUCacheBindGroups.NumBindGroupsNoLookupLastFrame,\r\n        };\r\n    }\r\n\r\n    public static ResetCache() {\r\n        WebGPUCacheBindGroups._Cache = new WebGPUBindGroupCacheNode();\r\n        WebGPUCacheBindGroups.NumBindGroupsCreatedTotal = 0;\r\n        WebGPUCacheBindGroups.NumBindGroupsCreatedLastFrame = 0;\r\n        WebGPUCacheBindGroups.NumBindGroupsLookupLastFrame = 0;\r\n        WebGPUCacheBindGroups.NumBindGroupsNoLookupLastFrame = 0;\r\n        WebGPUCacheBindGroups._NumBindGroupsCreatedCurrentFrame = 0;\r\n        WebGPUCacheBindGroups._NumBindGroupsLookupCurrentFrame = 0;\r\n        WebGPUCacheBindGroups._NumBindGroupsNoLookupCurrentFrame = 0;\r\n    }\r\n\r\n    constructor(device: GPUDevice, cacheSampler: WebGPUCacheSampler, engine: WebGPUEngine) {\r\n        this._device = device;\r\n        this._cacheSampler = cacheSampler;\r\n        this._engine = engine;\r\n    }\r\n\r\n    public endFrame(): void {\r\n        WebGPUCacheBindGroups.NumBindGroupsCreatedLastFrame = WebGPUCacheBindGroups._NumBindGroupsCreatedCurrentFrame;\r\n        WebGPUCacheBindGroups.NumBindGroupsLookupLastFrame = WebGPUCacheBindGroups._NumBindGroupsLookupCurrentFrame;\r\n        WebGPUCacheBindGroups.NumBindGroupsNoLookupLastFrame = WebGPUCacheBindGroups._NumBindGroupsNoLookupCurrentFrame;\r\n        WebGPUCacheBindGroups._NumBindGroupsCreatedCurrentFrame = 0;\r\n        WebGPUCacheBindGroups._NumBindGroupsLookupCurrentFrame = 0;\r\n        WebGPUCacheBindGroups._NumBindGroupsNoLookupCurrentFrame = 0;\r\n    }\r\n\r\n    /**\r\n     * Cache is currently based on the uniform/storage buffers, samplers and textures used by the binding groups.\r\n     * Note that all uniform buffers have an offset of 0 in Babylon and we don't have a use case where we would have the same buffer used with different capacity values:\r\n     * that means we don't need to factor in the offset/size of the buffer in the cache, only the id\r\n     * @param webgpuPipelineContext\r\n     * @param drawContext\r\n     * @param materialContext\r\n     * @returns a bind group array\r\n     */\r\n    public getBindGroups(webgpuPipelineContext: WebGPUPipelineContext, drawContext: WebGPUDrawContext, materialContext: WebGPUMaterialContext): GPUBindGroup[] {\r\n        let bindGroups: GPUBindGroup[] | undefined = undefined;\r\n        let node = WebGPUCacheBindGroups._Cache;\r\n\r\n        const cacheIsDisabled = this.disabled || materialContext.forceBindGroupCreation;\r\n        if (!cacheIsDisabled) {\r\n            if (!drawContext.isDirty(materialContext.updateId) && !materialContext.isDirty) {\r\n                WebGPUCacheBindGroups._NumBindGroupsNoLookupCurrentFrame++;\r\n                return drawContext.bindGroups!;\r\n            }\r\n\r\n            for (const bufferName of webgpuPipelineContext.shaderProcessingContext.bufferNames) {\r\n                const uboId = (drawContext.buffers[bufferName]?.uniqueId ?? 0) + BufferIdStart;\r\n                let nextNode = node.values[uboId];\r\n                if (!nextNode) {\r\n                    nextNode = new WebGPUBindGroupCacheNode();\r\n                    node.values[uboId] = nextNode;\r\n                }\r\n                node = nextNode;\r\n            }\r\n\r\n            for (const samplerName of webgpuPipelineContext.shaderProcessingContext.samplerNames) {\r\n                const samplerHashCode = materialContext.samplers[samplerName]?.hashCode ?? 0;\r\n                let nextNode = node.values[samplerHashCode];\r\n                if (!nextNode) {\r\n                    nextNode = new WebGPUBindGroupCacheNode();\r\n                    node.values[samplerHashCode] = nextNode;\r\n                }\r\n                node = nextNode;\r\n            }\r\n\r\n            for (const textureName of webgpuPipelineContext.shaderProcessingContext.textureNames) {\r\n                const textureId = (materialContext.textures[textureName]?.texture?.uniqueId ?? 0) + TextureIdStart;\r\n                let nextNode = node.values[textureId];\r\n                if (!nextNode) {\r\n                    nextNode = new WebGPUBindGroupCacheNode();\r\n                    node.values[textureId] = nextNode;\r\n                }\r\n                node = nextNode;\r\n            }\r\n\r\n            bindGroups = node.bindGroups;\r\n        }\r\n\r\n        drawContext.resetIsDirty(materialContext.updateId);\r\n        materialContext.isDirty = false;\r\n\r\n        if (bindGroups) {\r\n            drawContext.bindGroups = bindGroups;\r\n            WebGPUCacheBindGroups._NumBindGroupsLookupCurrentFrame++;\r\n            return bindGroups;\r\n        }\r\n\r\n        bindGroups = [];\r\n        drawContext.bindGroups = bindGroups;\r\n\r\n        if (!cacheIsDisabled) {\r\n            node.bindGroups = bindGroups;\r\n        }\r\n\r\n        WebGPUCacheBindGroups.NumBindGroupsCreatedTotal++;\r\n        WebGPUCacheBindGroups._NumBindGroupsCreatedCurrentFrame++;\r\n\r\n        const bindGroupLayouts = webgpuPipelineContext.bindGroupLayouts[materialContext.textureState];\r\n        for (let i = 0; i < webgpuPipelineContext.shaderProcessingContext.bindGroupLayoutEntries.length; i++) {\r\n            const setDefinition = webgpuPipelineContext.shaderProcessingContext.bindGroupLayoutEntries[i];\r\n\r\n            const entries = webgpuPipelineContext.shaderProcessingContext.bindGroupEntries[i];\r\n            for (let j = 0; j < setDefinition.length; j++) {\r\n                const entry = webgpuPipelineContext.shaderProcessingContext.bindGroupLayoutEntries[i][j];\r\n                const entryInfo = webgpuPipelineContext.shaderProcessingContext.bindGroupLayoutEntryInfo[i][entry.binding];\r\n                const name = entryInfo.nameInArrayOfTexture ?? entryInfo.name;\r\n\r\n                if (entry.sampler) {\r\n                    const bindingInfo = materialContext.samplers[name];\r\n                    if (bindingInfo) {\r\n                        const sampler = bindingInfo.sampler;\r\n                        if (!sampler) {\r\n                            if (this._engine.dbgSanityChecks) {\r\n                                Logger.Error(\r\n                                    `Trying to bind a null sampler! entry=${JSON.stringify(entry)}, name=${name}, bindingInfo=${JSON.stringify(\r\n                                        bindingInfo,\r\n                                        (key: string, value: any) => (key === \"texture\" ? \"<no dump>\" : value)\r\n                                    )}, materialContext.uniqueId=${materialContext.uniqueId}`,\r\n                                    50\r\n                                );\r\n                            }\r\n                            continue;\r\n                        }\r\n                        entries[j].resource = this._cacheSampler.getSampler(sampler, false, bindingInfo.hashCode, sampler.label);\r\n                    } else {\r\n                        Logger.Error(\r\n                            `Sampler \"${name}\" not found in the material context. Make sure you bound it. entry=${JSON.stringify(entry)}, materialContext=${JSON.stringify(\r\n                                materialContext,\r\n                                (key: string, value: any) => (key === \"texture\" || key === \"sampler\" ? \"<no dump>\" : value)\r\n                            )}`,\r\n                            50\r\n                        );\r\n                    }\r\n                } else if (entry.texture || entry.storageTexture) {\r\n                    const bindingInfo = materialContext.textures[name];\r\n                    if (bindingInfo) {\r\n                        if (this._engine.dbgSanityChecks && bindingInfo.texture === null) {\r\n                            Logger.Error(\r\n                                `Trying to bind a null texture! name=\"${name}\", entry=${JSON.stringify(entry)}, bindingInfo=${JSON.stringify(\r\n                                    bindingInfo,\r\n                                    (key: string, value: any) => (key === \"texture\" ? \"<no dump>\" : value)\r\n                                )}, materialContext.uniqueId=${materialContext.uniqueId}`,\r\n                                50\r\n                            );\r\n                            continue;\r\n                        }\r\n                        const hardwareTexture = (bindingInfo.texture as InternalTexture)._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n                        if (\r\n                            this._engine.dbgSanityChecks &&\r\n                            (!hardwareTexture || (entry.texture && !hardwareTexture.view) || (entry.storageTexture && !hardwareTexture.viewForWriting))\r\n                        ) {\r\n                            Logger.Error(\r\n                                `Trying to bind a null gpu texture or view! entry=${JSON.stringify(entry)}, name=${name}, bindingInfo=${JSON.stringify(\r\n                                    bindingInfo,\r\n                                    (key: string, value: any) => (key === \"texture\" ? \"<no dump>\" : value)\r\n                                )}, isReady=${bindingInfo.texture?.isReady}, materialContext.uniqueId=${materialContext.uniqueId}`,\r\n                                50\r\n                            );\r\n                            continue;\r\n                        }\r\n\r\n                        entries[j].resource = entry.storageTexture ? hardwareTexture.viewForWriting! : hardwareTexture.view!;\r\n                    } else {\r\n                        Logger.Error(\r\n                            `Texture \"${name}\" not found in the material context. Make sure you bound it (something like effect.setTexture(\"${name}\", texture)). entry=${JSON.stringify(entry)}, materialContext=${JSON.stringify(\r\n                                materialContext,\r\n                                (key: string, value: any) => (key === \"texture\" || key === \"sampler\" ? \"<no dump>\" : value)\r\n                            )}`,\r\n                            50\r\n                        );\r\n                    }\r\n                } else if (entry.externalTexture) {\r\n                    const bindingInfo = materialContext.textures[name];\r\n                    if (bindingInfo) {\r\n                        if (this._engine.dbgSanityChecks && bindingInfo.texture === null) {\r\n                            Logger.Error(\r\n                                `Trying to bind a null external texture! entry=${JSON.stringify(entry)}, name=${name}, bindingInfo=${JSON.stringify(\r\n                                    bindingInfo,\r\n                                    (key: string, value: any) => (key === \"texture\" ? \"<no dump>\" : value)\r\n                                )}, materialContext.uniqueId=${materialContext.uniqueId}`,\r\n                                50\r\n                            );\r\n                            continue;\r\n                        }\r\n                        const externalTexture = (bindingInfo.texture as ExternalTexture).underlyingResource;\r\n\r\n                        if (this._engine.dbgSanityChecks && !externalTexture) {\r\n                            Logger.Error(\r\n                                `Trying to bind a null gpu external texture! entry=${JSON.stringify(entry)}, name=${name}, bindingInfo=${JSON.stringify(\r\n                                    bindingInfo,\r\n                                    (key: string, value: any) => (key === \"texture\" ? \"<no dump>\" : value)\r\n                                )}, isReady=${bindingInfo.texture?.isReady}, materialContext.uniqueId=${materialContext.uniqueId}`,\r\n                                50\r\n                            );\r\n                            continue;\r\n                        }\r\n\r\n                        entries[j].resource = this._device.importExternalTexture({ source: externalTexture });\r\n                    } else {\r\n                        Logger.Error(\r\n                            `External texture \"${name}\" not found in the material context. Make sure you bound it. entry=${JSON.stringify(entry)}, materialContext=${JSON.stringify(\r\n                                materialContext,\r\n                                (key: string, value: any) => (key === \"texture\" || key === \"sampler\" ? \"<no dump>\" : value)\r\n                            )}`,\r\n                            50\r\n                        );\r\n                    }\r\n                } else if (entry.buffer) {\r\n                    const dataBuffer = drawContext.buffers[name];\r\n                    if (dataBuffer) {\r\n                        const webgpuBuffer = dataBuffer.underlyingResource as GPUBuffer;\r\n                        (entries[j].resource as GPUBufferBinding).buffer = webgpuBuffer;\r\n                        (entries[j].resource as GPUBufferBinding).size = dataBuffer.capacity;\r\n                    } else {\r\n                        Logger.Error(\r\n                            `Can't find buffer \"${name}\" in the draw context. Make sure you bound it. entry=${JSON.stringify(entry)}, buffers=${JSON.stringify(drawContext.buffers)}, drawContext.uniqueId=${\r\n                                drawContext.uniqueId\r\n                            }`,\r\n                            50\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n\r\n            const groupLayout = bindGroupLayouts[i];\r\n            bindGroups[i] = this._device.createBindGroup({\r\n                layout: groupLayout,\r\n                entries,\r\n            });\r\n        }\r\n\r\n        return bindGroups;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\n\n/**\n * Caches GPUTextureView objects so that render-pass attachments (color, MSAA resolve, depth/stencil)\n * don't recreate a fresh view every time a render target is bound/cleared.\n * Views are keyed on the live GPUTexture object via a WeakMap: once a texture is recreated (e.g. on resize)\n * the old texture becomes unreachable and its cached views are collected along with it, so no manual\n * invalidation is required.\n * @internal\n */\nexport class WebGPUCacheTextureView {\n    private _cache = new WeakMap<GPUTexture, Map<string, GPUTextureView>>();\n\n    public getView(texture: GPUTexture, descriptor: GPUTextureViewDescriptor): GPUTextureView {\n        let viewsForTexture = this._cache.get(texture);\n        if (!viewsForTexture) {\n            viewsForTexture = new Map();\n            this._cache.set(texture, viewsForTexture);\n        }\n\n        const key = WebGPUCacheTextureView._GetKey(descriptor);\n        let view = viewsForTexture.get(key);\n        if (!view) {\n            view = texture.createView(descriptor);\n            viewsForTexture.set(key, view);\n        }\n\n        return view;\n    }\n\n    private static _GetKey(descriptor: GPUTextureViewDescriptor): string {\n        return `${descriptor.format}_${descriptor.dimension}_${descriptor.baseMipLevel}_${descriptor.mipLevelCount}_${descriptor.baseArrayLayer}_${descriptor.arrayLayerCount}_${descriptor.aspect}_${descriptor.usage}_${descriptor.swizzle}`;\n    }\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Effect } from \"../../Materials/effect.pure\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type IColor4Like } from \"../../Maths/math.like\";\r\nimport { type VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { type WebGPUDataBuffer } from \"../../Meshes/WebGPU/webgpuDataBuffer\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../constants\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine.pure\";\r\nimport { type WebGPUCacheRenderPipeline } from \"./webgpuCacheRenderPipeline\";\r\nimport { WebGPUCacheRenderPipelineTree } from \"./webgpuCacheRenderPipelineTree\";\r\nimport { type WebGPUPipelineContext } from \"./webgpuPipelineContext\";\r\nimport { WebGPUShaderProcessingContext } from \"./webgpuShaderProcessingContext\";\r\nimport { WebGPUTextureHelper } from \"./webgpuTextureHelper\";\r\nimport { renderableTextureFormatToIndex } from \"./webgpuTextureManager\";\r\n\r\nimport { ShaderLanguage } from \"../../Materials/shaderLanguage\";\r\n\r\n/** @internal */\r\nexport class WebGPUClearQuad {\r\n    private _device: GPUDevice;\r\n    private _engine: WebGPUEngine;\r\n    private _cacheRenderPipeline: WebGPUCacheRenderPipeline;\r\n    private _effect: Effect;\r\n    private _bindGroups: { [id: string]: GPUBindGroup[] } = {};\r\n    private _depthTextureFormat: GPUTextureFormat | undefined;\r\n    private _bundleCache: { [key: string]: GPURenderBundle } = {};\r\n    private _keyTemp: number[] = [];\r\n\r\n    public setDepthStencilFormat(format: GPUTextureFormat | undefined): void {\r\n        this._depthTextureFormat = format;\r\n        this._cacheRenderPipeline.setDepthStencilFormat(format);\r\n    }\r\n\r\n    public setColorFormat(format: GPUTextureFormat | null): void {\r\n        this._cacheRenderPipeline.setColorFormat(format);\r\n    }\r\n\r\n    public setMRTAttachments(attachments: number[], textureArray: InternalTexture[], textureCount: number): void {\r\n        this._cacheRenderPipeline.setMRT(textureArray, textureCount);\r\n        this._cacheRenderPipeline.setMRTAttachments(attachments);\r\n    }\r\n\r\n    constructor(device: GPUDevice, engine: WebGPUEngine, emptyVertexBuffer: VertexBuffer) {\r\n        this._device = device;\r\n        this._engine = engine;\r\n\r\n        this._cacheRenderPipeline = new WebGPUCacheRenderPipelineTree(this._device, emptyVertexBuffer);\r\n        this._cacheRenderPipeline.setDepthTestEnabled(false);\r\n        this._cacheRenderPipeline.setStencilReadMask(0xff);\r\n\r\n        this._effect = engine.createEffect(\r\n            \"clearQuad\",\r\n            [],\r\n            [\"color\", \"depthValue\"],\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            ShaderLanguage.WGSL,\r\n            // On the pure import path the wrapper modules that eagerly register the clearQuad shaders are not in the\r\n            // module graph, so load the generated shader modules here to guarantee they are present in the ShaderStore\r\n            // before the effect compiles (otherwise the engine falls back to fetching clearQuad.*.fx and 404s).\r\n            async () => {\r\n                await Promise.all([import(\"../../ShadersWGSL/clearQuad.vertex\"), import(\"../../ShadersWGSL/clearQuad.fragment\")]);\r\n            }\r\n        );\r\n    }\r\n\r\n    public clear(\r\n        renderPass: Nullable<GPURenderPassEncoder>,\r\n        clearColor?: Nullable<IColor4Like>,\r\n        clearDepth?: boolean,\r\n        clearStencil?: boolean,\r\n        sampleCount = 1\r\n    ): Nullable<GPURenderBundle> {\r\n        let renderPass2: GPURenderPassEncoder | GPURenderBundleEncoder;\r\n        let bundle: Nullable<GPURenderBundle> = null;\r\n        let bundleKey: string;\r\n\r\n        const isRTTPass = !!this._engine._currentRenderTarget;\r\n\r\n        if (renderPass) {\r\n            renderPass2 = renderPass;\r\n        } else {\r\n            let idx = 0;\r\n            this._keyTemp.length = 0;\r\n            for (let i = 0; i < this._cacheRenderPipeline.colorFormats.length; ++i) {\r\n                this._keyTemp[idx++] = renderableTextureFormatToIndex[this._cacheRenderPipeline.colorFormats[i] ?? \"\"];\r\n            }\r\n\r\n            const depthStencilFormatIndex = renderableTextureFormatToIndex[this._depthTextureFormat ?? 0];\r\n\r\n            this._keyTemp[idx] =\r\n                (clearColor ? clearColor.r + clearColor.g * 256 + clearColor.b * 256 * 256 + clearColor.a * 256 * 256 * 256 : 0) +\r\n                (clearDepth ? 2 ** 32 : 0) +\r\n                (clearStencil ? 2 ** 33 : 0) +\r\n                (this._engine.useReverseDepthBuffer ? 2 ** 34 : 0) +\r\n                (isRTTPass ? 2 ** 35 : 0) +\r\n                (sampleCount > 1 ? 2 ** 36 : 0) +\r\n                depthStencilFormatIndex * 2 ** 37;\r\n\r\n            bundleKey = this._keyTemp.join(\"_\");\r\n            bundle = this._bundleCache[bundleKey];\r\n\r\n            if (bundle) {\r\n                return bundle;\r\n            }\r\n\r\n            renderPass2 = this._device.createRenderBundleEncoder({\r\n                label: \"clearQuadRenderBundle\",\r\n                colorFormats: this._cacheRenderPipeline.colorFormats,\r\n                depthStencilFormat: this._depthTextureFormat,\r\n                sampleCount: WebGPUTextureHelper.GetSample(sampleCount),\r\n            });\r\n        }\r\n\r\n        this._cacheRenderPipeline.setDepthWriteEnabled(!!clearDepth);\r\n        this._cacheRenderPipeline.setStencilEnabled(!!clearStencil && !!this._depthTextureFormat && WebGPUTextureHelper.HasStencilAspect(this._depthTextureFormat));\r\n        this._cacheRenderPipeline.setStencilWriteMask(clearStencil ? 0xff : 0);\r\n        this._cacheRenderPipeline.setStencilCompare(clearStencil ? Constants.ALWAYS : Constants.NEVER);\r\n        this._cacheRenderPipeline.setStencilPassOp(clearStencil ? Constants.REPLACE : Constants.KEEP);\r\n        this._cacheRenderPipeline.setWriteMask(clearColor ? 0xf : 0);\r\n\r\n        const pipeline = this._cacheRenderPipeline.getRenderPipeline(Constants.MATERIAL_TriangleStripDrawMode, this._effect, sampleCount);\r\n\r\n        const webgpuPipelineContext = this._effect._pipelineContext as WebGPUPipelineContext;\r\n\r\n        if (clearColor) {\r\n            this._effect.setDirectColor4(\"color\", clearColor);\r\n        }\r\n\r\n        this._effect.setFloat(\"depthValue\", this._engine.useReverseDepthBuffer ? this._engine._clearReverseDepthValue : this._engine._clearDepthValue);\r\n\r\n        webgpuPipelineContext.uniformBuffer!.update();\r\n\r\n        const bufferInternals = isRTTPass ? this._engine._ubInvertY : this._engine._ubDontInvertY;\r\n        const bufferLeftOver = webgpuPipelineContext.uniformBuffer!.getBuffer() as WebGPUDataBuffer;\r\n\r\n        const key = bufferLeftOver.uniqueId + \"-\" + bufferInternals.uniqueId;\r\n\r\n        let bindGroups = this._bindGroups[key];\r\n\r\n        if (!bindGroups) {\r\n            const bindGroupLayouts = webgpuPipelineContext.bindGroupLayouts[0];\r\n            bindGroups = this._bindGroups[key] = [];\r\n            bindGroups.push(\r\n                this._device.createBindGroup({\r\n                    label: `clearQuadBindGroup0-${key}`,\r\n                    layout: bindGroupLayouts[0],\r\n                    entries: [],\r\n                })\r\n            );\r\n            if (!WebGPUShaderProcessingContext._SimplifiedKnownBindings) {\r\n                bindGroups.push(\r\n                    this._device.createBindGroup({\r\n                        label: `clearQuadBindGroup1-${key}`,\r\n                        layout: bindGroupLayouts[1],\r\n                        entries: [],\r\n                    })\r\n                );\r\n            }\r\n            bindGroups.push(\r\n                this._device.createBindGroup({\r\n                    label: `clearQuadBindGroup${WebGPUShaderProcessingContext._SimplifiedKnownBindings ? 1 : 2}-${key}`,\r\n                    layout: bindGroupLayouts[WebGPUShaderProcessingContext._SimplifiedKnownBindings ? 1 : 2],\r\n                    entries: [\r\n                        {\r\n                            binding: 0,\r\n                            resource: {\r\n                                buffer: bufferInternals.underlyingResource,\r\n                                size: bufferInternals.capacity,\r\n                            },\r\n                        },\r\n                        {\r\n                            binding: 1,\r\n                            resource: {\r\n                                buffer: bufferLeftOver.underlyingResource,\r\n                                size: bufferLeftOver.capacity,\r\n                            },\r\n                        },\r\n                    ],\r\n                })\r\n            );\r\n        }\r\n\r\n        renderPass2.setPipeline(pipeline);\r\n        for (let i = 0; i < bindGroups.length; ++i) {\r\n            renderPass2.setBindGroup(i, bindGroups[i]);\r\n        }\r\n        renderPass2.draw(4, 1, 0, 0);\r\n\r\n        if (!renderPass) {\r\n            bundle = (renderPass2 as GPURenderBundleEncoder).finish();\r\n            this._bundleCache[bundleKey!] = bundle;\r\n        }\r\n\r\n        return bundle;\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { WebGPUTextureHelper } from \"./webgpuTextureHelper\";\r\n\r\n/** @internal */\r\ninterface IWebGPURenderItem {\r\n    run(renderPass: GPURenderPassEncoder): void;\r\n    clone(): IWebGPURenderItem;\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPURenderItemViewport implements IWebGPURenderItem {\r\n    public x: number;\r\n    public y: number;\r\n    public w: number;\r\n    public h: number;\r\n\r\n    public constructor(x: number, y: number, w: number, h: number) {\r\n        this.x = Math.floor(x);\r\n        this.y = Math.floor(y);\r\n        this.w = Math.floor(w);\r\n        this.h = Math.floor(h);\r\n    }\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.setViewport(this.x, this.y, this.w, this.h, 0, 1);\r\n    }\r\n\r\n    public clone(): WebGPURenderItemViewport {\r\n        return new WebGPURenderItemViewport(this.x, this.y, this.w, this.h);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPURenderItemScissor implements IWebGPURenderItem {\r\n    public constructor(\r\n        public x: number,\r\n        public y: number,\r\n        public w: number,\r\n        public h: number\r\n    ) {}\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.setScissorRect(this.x, this.y, this.w, this.h);\r\n    }\r\n\r\n    public clone(): WebGPURenderItemScissor {\r\n        return new WebGPURenderItemScissor(this.x, this.y, this.w, this.h);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPURenderItemStencilRef implements IWebGPURenderItem {\r\n    public constructor(public ref: number) {}\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.setStencilReference(this.ref);\r\n    }\r\n\r\n    public clone(): WebGPURenderItemStencilRef {\r\n        return new WebGPURenderItemStencilRef(this.ref);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPURenderItemBlendColor implements IWebGPURenderItem {\r\n    public constructor(public color: Nullable<number>[]) {}\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.setBlendConstant(this.color as GPUColor);\r\n    }\r\n\r\n    public clone(): WebGPURenderItemBlendColor {\r\n        return new WebGPURenderItemBlendColor(this.color);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPURenderItemBeginOcclusionQuery implements IWebGPURenderItem {\r\n    public constructor(public query: number) {}\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.beginOcclusionQuery(this.query);\r\n    }\r\n\r\n    public clone(): WebGPURenderItemBeginOcclusionQuery {\r\n        return new WebGPURenderItemBeginOcclusionQuery(this.query);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPURenderItemEndOcclusionQuery implements IWebGPURenderItem {\r\n    public constructor() {}\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.endOcclusionQuery();\r\n    }\r\n\r\n    public clone(): WebGPURenderItemEndOcclusionQuery {\r\n        return new WebGPURenderItemEndOcclusionQuery();\r\n    }\r\n}\r\n\r\nclass WebGPURenderItemBundles implements IWebGPURenderItem {\r\n    public bundles: GPURenderBundle[];\r\n\r\n    public constructor() {\r\n        this.bundles = [];\r\n    }\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        renderPass.executeBundles(this.bundles);\r\n    }\r\n\r\n    public clone(): WebGPURenderItemBundles {\r\n        const cloned = new WebGPURenderItemBundles();\r\n        cloned.bundles = this.bundles;\r\n        return cloned;\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUBundleList {\r\n    private _device: GPUDevice;\r\n    private _bundleEncoder: GPURenderBundleEncoder | undefined;\r\n\r\n    private _list: IWebGPURenderItem[];\r\n    private _listLength: number;\r\n\r\n    private _currentItemIsBundle: boolean;\r\n    private _currentBundleList: GPURenderBundle[];\r\n\r\n    public numDrawCalls = 0;\r\n\r\n    /** @internal */\r\n    public get isEmpty(): boolean {\r\n        return this._listLength === 0 && !this._bundleEncoder;\r\n    }\r\n\r\n    public constructor(device: GPUDevice) {\r\n        this._device = device;\r\n        this._list = new Array(10);\r\n        this._listLength = 0;\r\n    }\r\n\r\n    public addBundle(bundle?: GPURenderBundle): void {\r\n        if (!this._currentItemIsBundle) {\r\n            const item = new WebGPURenderItemBundles();\r\n\r\n            this._list[this._listLength++] = item;\r\n            this._currentBundleList = item.bundles;\r\n            this._currentItemIsBundle = true;\r\n        }\r\n        if (bundle) {\r\n            this._currentBundleList.push(bundle);\r\n        }\r\n    }\r\n\r\n    private _finishBundle(): void {\r\n        if (this._currentItemIsBundle && this._bundleEncoder) {\r\n            this._currentBundleList.push(this._bundleEncoder.finish());\r\n            this._bundleEncoder = undefined;\r\n            this._currentItemIsBundle = false;\r\n        }\r\n    }\r\n\r\n    public addItem(item: IWebGPURenderItem) {\r\n        this._finishBundle();\r\n        this._list[this._listLength++] = item;\r\n        this._currentItemIsBundle = false;\r\n    }\r\n\r\n    public getBundleEncoder(colorFormats: (GPUTextureFormat | null)[], depthStencilFormat: GPUTextureFormat | undefined, sampleCount: number): GPURenderBundleEncoder {\r\n        if (!this._currentItemIsBundle) {\r\n            this.addBundle();\r\n            this._bundleEncoder = this._device.createRenderBundleEncoder({\r\n                colorFormats,\r\n                depthStencilFormat,\r\n                sampleCount: WebGPUTextureHelper.GetSample(sampleCount),\r\n            });\r\n        }\r\n        return this._bundleEncoder!;\r\n    }\r\n\r\n    public close(): void {\r\n        this._finishBundle();\r\n    }\r\n\r\n    public run(renderPass: GPURenderPassEncoder) {\r\n        this.close();\r\n        for (let i = 0; i < this._listLength; ++i) {\r\n            this._list[i].run(renderPass);\r\n        }\r\n    }\r\n\r\n    public reset() {\r\n        this._listLength = 0;\r\n        this._currentItemIsBundle = false;\r\n        this.numDrawCalls = 0;\r\n    }\r\n\r\n    public clone(): WebGPUBundleList {\r\n        this.close();\r\n\r\n        const cloned = new WebGPUBundleList(this._device);\r\n\r\n        cloned._list = new Array(this._listLength);\r\n        cloned._listLength = this._listLength;\r\n        cloned.numDrawCalls = this.numDrawCalls;\r\n\r\n        for (let i = 0; i < this._listLength; ++i) {\r\n            cloned._list[i] = this._list[i].clone();\r\n        }\r\n\r\n        return cloned;\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { type WebGPUBufferManager } from \"./webgpuBufferManager\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { type QueryType } from \"./webgpuConstants\";\r\n\r\n/** @internal */\r\nexport class WebGPUQuerySet {\r\n    private _engine: WebGPUEngine;\r\n    private _device: GPUDevice;\r\n    private _bufferManager: WebGPUBufferManager;\r\n\r\n    private _count: number;\r\n    private _canUseMultipleBuffers: boolean;\r\n    private _querySet: GPUQuerySet;\r\n    private _queryBuffer: GPUBuffer;\r\n    private _dstBuffers: GPUBuffer[] = [];\r\n\r\n    public get querySet(): GPUQuerySet {\r\n        return this._querySet;\r\n    }\r\n\r\n    constructor(engine: WebGPUEngine, count: number, type: QueryType, device: GPUDevice, bufferManager: WebGPUBufferManager, canUseMultipleBuffers = true, label?: string) {\r\n        this._engine = engine;\r\n        this._device = device;\r\n        this._bufferManager = bufferManager;\r\n        this._count = count;\r\n        this._canUseMultipleBuffers = canUseMultipleBuffers;\r\n\r\n        this._querySet = device.createQuerySet({\r\n            label: label ?? \"QuerySet\",\r\n            type,\r\n            count,\r\n        });\r\n\r\n        this._queryBuffer = bufferManager.createRawBuffer(8 * count, WebGPUConstants.BufferUsage.QueryResolve | WebGPUConstants.BufferUsage.CopySrc, undefined, \"QueryBuffer\");\r\n\r\n        if (!canUseMultipleBuffers) {\r\n            this._dstBuffers.push(\r\n                this._bufferManager.createRawBuffer(\r\n                    8 * this._count,\r\n                    WebGPUConstants.BufferUsage.MapRead | WebGPUConstants.BufferUsage.CopyDst,\r\n                    undefined,\r\n                    \"QueryBufferNoMultipleBuffers\"\r\n                )\r\n            );\r\n        }\r\n    }\r\n\r\n    private _getBuffer(firstQuery: number, queryCount: number): GPUBuffer | null {\r\n        if (!this._canUseMultipleBuffers && this._dstBuffers.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        const encoderResult = this._device.createCommandEncoder();\r\n\r\n        let buffer: GPUBuffer;\r\n        if (this._dstBuffers.length === 0) {\r\n            buffer = this._bufferManager.createRawBuffer(\r\n                8 * this._count,\r\n                WebGPUConstants.BufferUsage.MapRead | WebGPUConstants.BufferUsage.CopyDst,\r\n                undefined,\r\n                \"QueryBufferAdditionalBuffer\"\r\n            );\r\n        } else {\r\n            buffer = this._dstBuffers[this._dstBuffers.length - 1];\r\n            this._dstBuffers.length--;\r\n        }\r\n\r\n        encoderResult.resolveQuerySet(this._querySet, firstQuery, queryCount, this._queryBuffer, 0);\r\n        encoderResult.copyBufferToBuffer(this._queryBuffer, 0, buffer, 0, 8 * queryCount);\r\n\r\n        this._device.queue.submit([encoderResult.finish()]);\r\n\r\n        return buffer;\r\n    }\r\n\r\n    public async readValues(firstQuery = 0, queryCount = 1): Promise<BigUint64Array | null> {\r\n        const buffer = this._getBuffer(firstQuery, queryCount);\r\n        if (buffer === null) {\r\n            return null;\r\n        }\r\n        const engineId = this._engine.uniqueId;\r\n\r\n        try {\r\n            await buffer.mapAsync(WebGPUConstants.MapMode.Read);\r\n            const arrayBuf = new BigUint64Array(buffer.getMappedRange()).slice();\r\n\r\n            buffer.unmap();\r\n\r\n            this._dstBuffers[this._dstBuffers.length] = buffer;\r\n\r\n            return arrayBuf;\r\n        } catch (err) {\r\n            if (this._engine.isDisposed || this._engine.uniqueId !== engineId) {\r\n                // Engine disposed or context loss/restoration\r\n                return null;\r\n            }\r\n            throw err;\r\n        }\r\n    }\r\n\r\n    public async readValue(firstQuery = 0): Promise<number | null> {\r\n        const buffer = this._getBuffer(firstQuery, 1);\r\n        if (buffer === null) {\r\n            return null;\r\n        }\r\n        const engineId = this._engine.uniqueId;\r\n\r\n        try {\r\n            await buffer.mapAsync(WebGPUConstants.MapMode.Read);\r\n            const arrayBuf = new BigUint64Array(buffer.getMappedRange());\r\n            const value = Number(arrayBuf[0]);\r\n\r\n            buffer.unmap();\r\n\r\n            this._dstBuffers[this._dstBuffers.length] = buffer;\r\n\r\n            return value;\r\n        } catch (err) {\r\n            if (this._engine.isDisposed || this._engine.uniqueId !== engineId) {\r\n                // Engine disposed or context loss/restoration\r\n                return 0;\r\n            }\r\n            throw err;\r\n        }\r\n    }\r\n\r\n    public async readTwoValuesAndSubtract(firstQuery = 0): Promise<number | null> {\r\n        const buffer = this._getBuffer(firstQuery, 2);\r\n        if (buffer === null) {\r\n            return null;\r\n        }\r\n        const engineId = this._engine.uniqueId;\r\n\r\n        try {\r\n            await buffer.mapAsync(WebGPUConstants.MapMode.Read);\r\n            const arrayBuf = new BigUint64Array(buffer.getMappedRange());\r\n            const value = Number(arrayBuf[1] - arrayBuf[0]);\r\n\r\n            buffer.unmap();\r\n\r\n            this._dstBuffers[this._dstBuffers.length] = buffer;\r\n\r\n            return value;\r\n        } catch (err) {\r\n            if (this._engine.isDisposed || this._engine.uniqueId !== engineId) {\r\n                // Engine disposed or context loss/restoration\r\n                return 0;\r\n            }\r\n            throw err;\r\n        }\r\n    }\r\n\r\n    public dispose() {\r\n        this._querySet.destroy();\r\n        this._bufferManager.releaseBuffer(this._queryBuffer);\r\n        for (let i = 0; i < this._dstBuffers.length; ++i) {\r\n            this._bufferManager.releaseBuffer(this._dstBuffers[i]);\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable babylonjs/available */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n// writeTimestamp is an experimental Chrome extension not yet part of the WebGPU spec typings\r\ninterface GPUCommandEncoderWithTimestamp extends GPUCommandEncoder {\r\n    writeTimestamp?(querySet: GPUQuerySet, queryIndex: number): void;\r\n}\r\n\r\nimport { type WebGPUBufferManager } from \"./webgpuBufferManager\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { PerfCounter } from \"../../Misc/perfCounter\";\r\nimport { WebGPUQuerySet } from \"./webgpuQuerySet\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { type WebGPUPerfCounter } from \"./webgpuPerfCounter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/** @internal */\r\nexport class WebGPUTimestampQuery {\r\n    private _engine: WebGPUEngine;\r\n    private _device: GPUDevice;\r\n    private _bufferManager: WebGPUBufferManager;\r\n\r\n    private _enabled = false;\r\n    private _gpuFrameTimeCounter: PerfCounter = new PerfCounter();\r\n    private _measureDuration: WebGPUDurationMeasure;\r\n    private _measureDurationState = 0;\r\n\r\n    public get gpuFrameTimeCounter() {\r\n        return this._gpuFrameTimeCounter;\r\n    }\r\n\r\n    constructor(engine: WebGPUEngine, device: GPUDevice, bufferManager: WebGPUBufferManager) {\r\n        this._engine = engine;\r\n        this._device = device;\r\n        this._bufferManager = bufferManager;\r\n    }\r\n\r\n    public get enable(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public set enable(value: boolean) {\r\n        if (this._enabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._enabled = value;\r\n        this._measureDurationState = 0;\r\n        if (value) {\r\n            try {\r\n                this._measureDuration = new WebGPUDurationMeasure(this._engine, this._device, this._bufferManager, 2000, \"QuerySet_TimestampQuery\");\r\n            } catch (e) {\r\n                this._enabled = false;\r\n                Logger.Error(\"Could not create a WebGPUDurationMeasure!\\nError: \" + e.message + \"\\nMake sure timestamp query is supported and enabled in your browser.\");\r\n                return;\r\n            }\r\n        } else {\r\n            this._measureDuration.dispose();\r\n        }\r\n    }\r\n\r\n    public startFrame(commandEncoder: GPUCommandEncoder): void {\r\n        if (this._enabled && this._measureDurationState === 0) {\r\n            this._measureDuration.start(commandEncoder);\r\n            this._measureDurationState = 1;\r\n        }\r\n    }\r\n\r\n    public endFrame(commandEncoder: GPUCommandEncoder): void {\r\n        if (this._measureDurationState === 1) {\r\n            this._measureDurationState = 2;\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            this._measureDuration.stop(commandEncoder).then((duration) => {\r\n                if (duration !== null && duration >= 0) {\r\n                    this._gpuFrameTimeCounter.fetchNewFrame();\r\n                    this._gpuFrameTimeCounter.addCount(duration, true);\r\n                }\r\n                this._measureDurationState = 0;\r\n            });\r\n        }\r\n    }\r\n\r\n    public startPass(descriptor: GPURenderPassDescriptor | GPUComputePassDescriptor, index: number): void {\r\n        if (this._enabled) {\r\n            this._measureDuration.startPass(descriptor, index);\r\n        } else {\r\n            descriptor.timestampWrites = undefined;\r\n        }\r\n    }\r\n\r\n    public endPass(index: number, gpuPerfCounter?: WebGPUPerfCounter): void {\r\n        if (!this._enabled || !gpuPerfCounter) {\r\n            return;\r\n        }\r\n\r\n        const currentFrameId = this._engine.frameId;\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        this._measureDuration.stopPass(index).then((duration_) => {\r\n            gpuPerfCounter._addDuration(currentFrameId, duration_ !== null && duration_ > 0 ? duration_ : 0);\r\n        });\r\n    }\r\n\r\n    public dispose() {\r\n        this._measureDuration?.dispose();\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUDurationMeasure {\r\n    private _querySet: WebGPUQuerySet;\r\n    private _count: number;\r\n\r\n    constructor(engine: WebGPUEngine, device: GPUDevice, bufferManager: WebGPUBufferManager, count = 2, querySetLabel?: string) {\r\n        this._count = count;\r\n        this._querySet = new WebGPUQuerySet(engine, count, WebGPUConstants.QueryType.Timestamp, device, bufferManager, true, querySetLabel);\r\n    }\r\n\r\n    public start(encoder: GPUCommandEncoder): void {\r\n        (encoder as GPUCommandEncoderWithTimestamp).writeTimestamp?.(this._querySet.querySet, 0);\r\n    }\r\n\r\n    public async stop(encoder: GPUCommandEncoder): Promise<number | null> {\r\n        (encoder as GPUCommandEncoderWithTimestamp).writeTimestamp?.(this._querySet.querySet, 1);\r\n\r\n        return (encoder as GPUCommandEncoderWithTimestamp).writeTimestamp ? await this._querySet.readTwoValuesAndSubtract(0) : 0;\r\n    }\r\n\r\n    public startPass(descriptor: GPURenderPassDescriptor | GPUComputePassDescriptor, index: number): void {\r\n        if (index + 3 > this._count) {\r\n            throw new Error(\"WebGPUDurationMeasure: index out of range (\" + index + \")\");\r\n        }\r\n\r\n        descriptor.timestampWrites = {\r\n            querySet: this._querySet.querySet,\r\n            beginningOfPassWriteIndex: index + 2,\r\n            endOfPassWriteIndex: index + 3,\r\n        };\r\n    }\r\n\r\n    public async stopPass(index: number): Promise<number | null> {\r\n        return await this._querySet.readTwoValuesAndSubtract(index + 2);\r\n    }\r\n\r\n    public dispose() {\r\n        this._querySet.dispose();\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { type WebGPUBufferManager } from \"./webgpuBufferManager\";\r\nimport * as WebGPUConstants from \"./webgpuConstants\";\r\nimport { WebGPUQuerySet } from \"./webgpuQuerySet\";\r\n\r\n/** @internal */\r\nexport class WebGPUOcclusionQuery {\r\n    private _engine: WebGPUEngine;\r\n    private _device: GPUDevice;\r\n    private _bufferManager: WebGPUBufferManager;\r\n\r\n    private _currentTotalIndices: number;\r\n    private _countIncrement: number;\r\n    private _querySet: WebGPUQuerySet;\r\n    private _availableIndices: number[] = [];\r\n    private _lastBuffer: Nullable<BigUint64Array>;\r\n    private _frameLastBuffer: number;\r\n    private _frameQuerySetIsDirty = -1;\r\n    private _queryFrameId: number[] = [];\r\n\r\n    public get querySet(): GPUQuerySet {\r\n        return this._querySet.querySet;\r\n    }\r\n\r\n    public get hasQueries(): boolean {\r\n        return this._currentTotalIndices !== this._availableIndices.length;\r\n    }\r\n\r\n    public canBeginQuery(index: number): boolean {\r\n        if (this._frameQuerySetIsDirty === this._engine.frameId || this._queryFrameId[index] === this._engine.frameId) {\r\n            return false;\r\n        }\r\n\r\n        const canBegin = this._engine._getCurrentRenderPassWrapper().renderPassDescriptor!.occlusionQuerySet !== undefined;\r\n\r\n        if (canBegin) {\r\n            this._queryFrameId[index] = this._engine.frameId;\r\n        }\r\n\r\n        return canBegin;\r\n    }\r\n\r\n    constructor(engine: WebGPUEngine, device: GPUDevice, bufferManager: WebGPUBufferManager, startCount = 50, incrementCount = 100) {\r\n        this._engine = engine;\r\n        this._device = device;\r\n        this._bufferManager = bufferManager;\r\n\r\n        this._frameLastBuffer = -1;\r\n        this._currentTotalIndices = 0;\r\n        this._countIncrement = incrementCount;\r\n\r\n        this._allocateNewIndices(startCount);\r\n    }\r\n\r\n    public createQuery(): number {\r\n        if (this._availableIndices.length === 0) {\r\n            this._allocateNewIndices();\r\n        }\r\n\r\n        const index = this._availableIndices[this._availableIndices.length - 1];\r\n        this._availableIndices.length--;\r\n\r\n        return index;\r\n    }\r\n\r\n    public deleteQuery(index: number): void {\r\n        this._availableIndices[this._availableIndices.length] = index;\r\n    }\r\n\r\n    public isQueryResultAvailable(index: number): boolean {\r\n        this._retrieveQueryBuffer();\r\n\r\n        return !!this._lastBuffer && index < this._lastBuffer.length;\r\n    }\r\n\r\n    public getQueryResult(index: number): number {\r\n        return Number(this._lastBuffer?.[index] ?? -1);\r\n    }\r\n\r\n    private _retrieveQueryBuffer(): void {\r\n        if (this._lastBuffer && this._frameLastBuffer === this._engine.frameId) {\r\n            return;\r\n        }\r\n\r\n        if (this._frameLastBuffer !== this._engine.frameId) {\r\n            this._frameLastBuffer = this._engine.frameId;\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            this._querySet.readValues(0, this._currentTotalIndices).then((arrayBuffer) => {\r\n                this._lastBuffer = arrayBuffer;\r\n            });\r\n        }\r\n    }\r\n\r\n    private _allocateNewIndices(numIndices?: number): void {\r\n        numIndices = numIndices ?? this._countIncrement;\r\n\r\n        this._delayQuerySetDispose();\r\n\r\n        for (let i = 0; i < numIndices; ++i) {\r\n            this._availableIndices.push(this._currentTotalIndices + i);\r\n        }\r\n\r\n        this._currentTotalIndices += numIndices;\r\n        this._querySet = new WebGPUQuerySet(\r\n            this._engine,\r\n            this._currentTotalIndices,\r\n            WebGPUConstants.QueryType.Occlusion,\r\n            this._device,\r\n            this._bufferManager,\r\n            false,\r\n            \"QuerySet_OcclusionQuery_count_\" + this._currentTotalIndices\r\n        );\r\n\r\n        this._frameQuerySetIsDirty = this._engine.frameId;\r\n    }\r\n\r\n    private _delayQuerySetDispose(): void {\r\n        const querySet = this._querySet;\r\n        if (querySet) {\r\n            // Wait a bit before disposing of the queryset, in case some queries are still running for it\r\n            setTimeout(() => querySet.dispose(), 1000);\r\n        }\r\n    }\r\n\r\n    public dispose(): void {\r\n        this._querySet?.dispose();\r\n        this._availableIndices.length = 0;\r\n    }\r\n}\r\n","import { Logger } from \"core/Misc/logger\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\n\r\n/**\r\n * Options to load the associated Twgsl library\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface TwgslOptions {\r\n    /**\r\n     * Defines an existing instance of Twgsl (useful in modules who do not access the global instance).\r\n     */\r\n    twgsl?: any;\r\n    /**\r\n     * Defines the URL of the twgsl JS File.\r\n     */\r\n    jsPath?: string;\r\n    /**\r\n     * Defines the URL of the twgsl WASM File.\r\n     */\r\n    wasmPath?: string;\r\n}\r\n\r\n/** @internal */\r\nexport class WebGPUTintWASM {\r\n    // Default twgsl options.\r\n    private static readonly _TwgslDefaultOptions: TwgslOptions = {\r\n        jsPath: `${Tools._DefaultCdnUrl}/twgsl/twgsl.js`,\r\n        wasmPath: `${Tools._DefaultCdnUrl}/twgsl/twgsl.wasm`,\r\n    };\r\n\r\n    public static ShowWGSLShaderCode = false;\r\n\r\n    public static DisableUniformityAnalysis = false;\r\n\r\n    private static _Twgsl: any = null;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async initTwgsl(twgslOptions?: TwgslOptions): Promise<void> {\r\n        if (WebGPUTintWASM._Twgsl) {\r\n            return;\r\n        }\r\n\r\n        twgslOptions = twgslOptions || {};\r\n        twgslOptions = {\r\n            ...WebGPUTintWASM._TwgslDefaultOptions,\r\n            ...twgslOptions,\r\n        };\r\n\r\n        if (twgslOptions.twgsl) {\r\n            WebGPUTintWASM._Twgsl = twgslOptions.twgsl;\r\n            return;\r\n        }\r\n\r\n        if (twgslOptions.jsPath && twgslOptions.wasmPath) {\r\n            await Tools.LoadBabylonScriptAsync(twgslOptions.jsPath);\r\n        }\r\n\r\n        if ((self as any).twgsl) {\r\n            // eslint-disable-next-line require-atomic-updates\r\n            WebGPUTintWASM._Twgsl = await (self as any).twgsl(Tools.GetBabylonScriptURL(twgslOptions.wasmPath!));\r\n            return;\r\n        }\r\n\r\n        throw new Error(\"twgsl is not available.\");\r\n    }\r\n\r\n    public convertSpirV2WGSL(code: Uint32Array, disableUniformityAnalysis = false): string {\r\n        const ccode = WebGPUTintWASM._Twgsl.convertSpirV2WGSL(code, WebGPUTintWASM.DisableUniformityAnalysis || disableUniformityAnalysis);\r\n        if (WebGPUTintWASM.ShowWGSLShaderCode) {\r\n            Logger.Log(ccode);\r\n            Logger.Log(\"***********************************************\");\r\n        }\r\n        return WebGPUTintWASM.DisableUniformityAnalysis || disableUniformityAnalysis ? \"diagnostic(off, derivative_uniformity);\\n\" + ccode : ccode;\r\n    }\r\n}\r\n","import { type Nullable } from \"core/types\";\r\nimport { Constants } from \"../constants\";\r\nimport { type WebGPUEngine } from \"../webgpuEngine\";\r\nimport { type WebGPUBundleList } from \"./webgpuBundleList\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/** @internal */\r\nexport class WebGPUSnapshotRendering {\r\n    private _engine: WebGPUEngine;\r\n\r\n    private _record = false;\r\n    private _play = false;\r\n    private _playBundleListIndex = 0;\r\n    private _allBundleLists: WebGPUBundleList[] = [];\r\n    private _recordingInvalidated = false;\r\n    private _skipNextRenderPass = false;\r\n    private _modeSaved: number;\r\n    private _bundleList: WebGPUBundleList;\r\n\r\n    private _enabled = false;\r\n    private _mode: number;\r\n\r\n    constructor(engine: WebGPUEngine, renderingMode: number, bundleList: WebGPUBundleList) {\r\n        this._engine = engine;\r\n        this._mode = renderingMode;\r\n        this._bundleList = bundleList;\r\n    }\r\n\r\n    public showDebugLogs = false;\r\n\r\n    public get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public get play() {\r\n        return this._play;\r\n    }\r\n\r\n    public get record() {\r\n        return this._record;\r\n    }\r\n\r\n    public set enabled(activate: boolean) {\r\n        this._log(\"enabled\", `activate=${activate}, mode=${this._mode}`);\r\n\r\n        this._allBundleLists.length = 0;\r\n        this._recordingInvalidated = false;\r\n        this._skipNextRenderPass = false;\r\n        if (this._record) {\r\n            // A recording pass is in flight: _mode is temporarily SNAPSHOTRENDERING_STANDARD and is normally\r\n            // restored to _modeSaved at the next endFrame(). Restore it now so that flipping _record off\r\n            // doesn't leave _mode stuck on STANDARD — otherwise the next \"enabled = true\" would save STANDARD\r\n            // as the user-requested mode and the engine would permanently fall back to STANDARD (forum #63365).\r\n            this._mode = this._modeSaved;\r\n        }\r\n        this._record = this._enabled = activate;\r\n        this._play = false;\r\n        if (activate) {\r\n            this._modeSaved = this._mode;\r\n            this._mode = Constants.SNAPSHOTRENDERING_STANDARD; // need to reset to standard for the recording pass to avoid some code being bypassed\r\n        }\r\n    }\r\n\r\n    public get mode(): number {\r\n        return this._mode;\r\n    }\r\n\r\n    public set mode(mode: number) {\r\n        if (this._record) {\r\n            this._modeSaved = mode;\r\n        } else {\r\n            this._mode = mode;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public handleRenderPassRestart(): void {\r\n        if (!this._record) {\r\n            return;\r\n        }\r\n\r\n        if (this._bundleList.isEmpty) {\r\n            this._skipNextRenderPass = true;\r\n        } else {\r\n            this._allBundleLists.length = 0;\r\n            this._recordingInvalidated = true;\r\n        }\r\n    }\r\n\r\n    public endRenderPass(currentRenderPass: GPURenderPassEncoder): boolean {\r\n        if (!this._record && !this._play) {\r\n            // Snapshot rendering mode is not enabled\r\n            return false;\r\n        }\r\n\r\n        let bundleList: Nullable<WebGPUBundleList> = null;\r\n\r\n        if (this._record) {\r\n            bundleList = this._bundleList.clone();\r\n            this._bundleList.reset();\r\n            if (this._skipNextRenderPass) {\r\n                this._skipNextRenderPass = false;\r\n                this._log(\"endRenderPass\", \"bundleList omitted for a restarted empty pass\");\r\n            } else if (this._recordingInvalidated) {\r\n                this._log(\"endRenderPass\", \"bundleList discarded from an invalidated recording\");\r\n            } else {\r\n                this._allBundleLists.push(bundleList);\r\n                this._log(\"endRenderPass\", `bundleList recorded at position #${this._allBundleLists.length - 1}`);\r\n            }\r\n        } else {\r\n            // We are playing the snapshot\r\n            if (this._playBundleListIndex >= this._allBundleLists.length) {\r\n                this._log(\r\n                    \"endRenderPass\",\r\n                    `empty or out-of-sync bundleList (_allBundleLists.length=${this._allBundleLists.length}, playBundleListIndex=${this._playBundleListIndex})`\r\n                );\r\n            } else {\r\n                this._log(\"endRenderPass\", `run bundleList #${this._playBundleListIndex}`);\r\n                bundleList = this._allBundleLists[this._playBundleListIndex++];\r\n            }\r\n        }\r\n\r\n        if (bundleList) {\r\n            bundleList.run(currentRenderPass);\r\n\r\n            if (this._mode === Constants.SNAPSHOTRENDERING_FAST) {\r\n                this._engine._reportDrawCall(bundleList.numDrawCalls);\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    public endFrame(): void {\r\n        if (this._record) {\r\n            if (this._recordingInvalidated) {\r\n                this._recordingInvalidated = false;\r\n                this._allBundleLists.length = 0;\r\n                this._log(\"endFrame\", \"recording invalidated, recording the next frame\");\r\n            } else {\r\n                // We stop recording and switch to replay mode for the next frames\r\n                this._record = false;\r\n                this._play = true;\r\n                this._mode = this._modeSaved;\r\n                this._log(\"endFrame\", \"bundles recorded, switching to play mode\");\r\n            }\r\n        }\r\n\r\n        this._playBundleListIndex = 0;\r\n    }\r\n\r\n    public reset(): void {\r\n        this._log(\"reset\", \"called\");\r\n        this.enabled = false;\r\n        this.enabled = true;\r\n    }\r\n\r\n    private _log(funcName: string, message: string) {\r\n        if (this.showDebugLogs) {\r\n            Logger.Log(`[Frame: ${this._engine.frameId}] WebGPUSnapshotRendering:${funcName} - ${message}`);\r\n        }\r\n    }\r\n}\r\n","import { ExternalTexture } from \"../../Materials/Textures/externalTexture\";\r\n\r\n/**\r\n * Nothing specific to WebGPU in this class, but the spec is not final yet so let's remove it later on\r\n * if it is not needed\r\n * @internal\r\n **/\r\nexport class WebGPUExternalTexture extends ExternalTexture {\r\n    public constructor(video: HTMLVideoElement) {\r\n        super(video);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable babylonjs/available */\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { ThinWebGPUEngine } from \"./thinWebGPUEngine\";\r\nimport { type Nullable, type DataArray, type IndicesArray, type Immutable, type FloatArray } from \"../types\";\r\nimport { Color4 } from \"../Maths/math\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { type IEffectCreationOptions, type IShaderPath, Effect } from \"../Materials/effect.pure\";\r\nimport { type EffectFallbacks } from \"../Materials/effectFallbacks\";\r\nimport { Constants } from \"./constants\";\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nimport * as WebGPUConstants from \"./WebGPU/webgpuConstants\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type IWebGPURenderPipelineStageDescriptor, WebGPUPipelineContext } from \"./WebGPU/webgpuPipelineContext\";\r\nimport { type IPipelineContext } from \"./IPipelineContext\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type IShaderProcessor } from \"./Processors/iShaderProcessor\";\r\nimport { WebGPUShaderProcessorGLSL } from \"./WebGPU/webgpuShaderProcessorsGLSL\";\r\nimport { WebGPUShaderProcessorWGSL } from \"./WebGPU/webgpuShaderProcessorsWGSL.pure\";\r\nimport { type _IShaderProcessingContext } from \"./Processors/shaderProcessingOptions\";\r\nimport { WebGPUShaderProcessingContext } from \"./WebGPU/webgpuShaderProcessingContext\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { WebGPUTextureHelper } from \"./WebGPU/webgpuTextureHelper\";\r\nimport { WebGPUTextureManager } from \"./WebGPU/webgpuTextureManager\";\r\nimport { AbstractEngine, type ISceneLike, type AbstractEngineOptions } from \"./abstractEngine.pure\";\r\nimport { WebGPUBufferManager } from \"./WebGPU/webgpuBufferManager\";\r\nimport { type IHardwareTextureWrapper } from \"../Materials/Textures/hardwareTextureWrapper\";\r\nimport { WebGPUHardwareTexture } from \"./WebGPU/webgpuHardwareTexture\";\r\nimport { type IColor4Like } from \"../Maths/math.like\";\r\nimport { type UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { WebGPUCacheSampler } from \"./WebGPU/webgpuCacheSampler\";\r\nimport { WebGPUCacheRenderPipelineTree } from \"./WebGPU/webgpuCacheRenderPipelineTree\";\r\nimport { WebGPUStencilStateComposer } from \"./WebGPU/webgpuStencilStateComposer\";\r\nimport { WebGPUDepthCullingState } from \"./WebGPU/webgpuDepthCullingState\";\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { WebGPUMaterialContext } from \"./WebGPU/webgpuMaterialContext\";\r\nimport { WebGPUDrawContext } from \"./WebGPU/webgpuDrawContext\";\r\nimport { WebGPUCacheBindGroups } from \"./WebGPU/webgpuCacheBindGroups\";\r\nimport { WebGPUCacheTextureView } from \"./WebGPU/webgpuCacheTextureView\";\r\nimport { WebGPUClearQuad } from \"./WebGPU/webgpuClearQuad.pure\";\r\nimport { type IStencilState } from \"../States/IStencilState\";\r\nimport { WebGPURenderItemBlendColor, WebGPURenderItemScissor, WebGPURenderItemStencilRef, WebGPURenderItemViewport, WebGPUBundleList } from \"./WebGPU/webgpuBundleList\";\r\nimport { WebGPUTimestampQuery } from \"./WebGPU/webgpuTimestampQuery\";\r\nimport { type ComputeEffect } from \"../Compute/computeEffect\";\r\nimport { WebGPUOcclusionQuery } from \"./WebGPU/webgpuOcclusionQuery\";\r\nimport { ShaderCodeInliner } from \"./Processors/shaderCodeInliner\";\r\nimport { type TwgslOptions, WebGPUTintWASM } from \"./WebGPU/webgpuTintWASM\";\r\nimport { type ExternalTexture } from \"../Materials/Textures/externalTexture\";\r\nimport { WebGPUShaderProcessor } from \"./WebGPU/webgpuShaderProcessor\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { type InternalTextureCreationOptions, type TextureSize } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { WebGPUSnapshotRendering } from \"./WebGPU/webgpuSnapshotRendering\";\r\nimport { type WebGPUDataBuffer } from \"../Meshes/WebGPU/webgpuDataBuffer\";\r\nimport { type WebGPURenderTargetWrapper } from \"./WebGPU/webgpuRenderTargetWrapper\";\r\nimport { AlphaState } from \"../States/alphaCullingState\";\r\nimport { IsIntegerTextureFormat, IsUnsignedIntegerTextureType } from \"../Materials/Textures/textureHelper.functions\";\r\n\r\nimport { type VideoTexture } from \"../Materials/Textures/videoTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\n\r\nimport { SphericalPolynomial } from \"../Maths/sphericalPolynomial.pure\";\r\nimport { PerformanceMonitor } from \"../Misc/performanceMonitor\";\r\nimport {\r\n    CreateImageBitmapFromSource,\r\n    ExitFullscreen,\r\n    ExitPointerlock,\r\n    GetFontOffset,\r\n    RequestFullscreen,\r\n    RequestPointerlock,\r\n    ResizeImageBitmap,\r\n    _CommonDispose,\r\n    _CommonInit,\r\n} from \"./engine.common\";\r\nimport { IsWrapper } from \"../Materials/drawWrapper.functions\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport { resetCachedPipeline } from \"../Materials/effect.functions\";\r\nimport { RegisterAbstractEngineDom } from \"./AbstractEngine/abstractEngine.dom.pure\";\r\nimport { RegisterAbstractEngineRenderPass } from \"./AbstractEngine/abstractEngine.renderPass.pure\";\r\n\r\nimport { WebGPUExternalTexture } from \"./WebGPU/webgpuExternalTexture\";\r\nimport { type TextureSampler } from \"../Materials/Textures/textureSampler\";\r\nimport { type StorageBuffer } from \"../Buffers/storageBuffer\";\r\n\r\nconst ViewDescriptorSwapChainAntialiasing: GPUTextureViewDescriptor = {\r\n    label: `TextureView_SwapChain_ResolveTarget`,\r\n    dimension: WebGPUConstants.TextureDimension.E2d,\r\n    format: undefined as any, // will be updated with the right value\r\n    mipLevelCount: 1,\r\n    arrayLayerCount: 1,\r\n};\r\n\r\nconst ViewDescriptorSwapChain: GPUTextureViewDescriptor = {\r\n    label: `TextureView_SwapChain`,\r\n    dimension: WebGPUConstants.TextureDimension.E2d,\r\n    format: undefined as any, // will be updated with the right value\r\n    mipLevelCount: 1,\r\n    arrayLayerCount: 1,\r\n};\r\nconst TempColor4 = /*#__PURE__*/ new Color4();\r\nconst TempColor4SignedInteger = /*#__PURE__*/ new Color4();\r\n\r\n/** @internal */\r\ninterface IWebGPURenderPassWrapper {\r\n    renderPassDescriptor: Nullable<GPURenderPassDescriptor>;\r\n\r\n    colorAttachmentViewDescriptor: Nullable<GPUTextureViewDescriptor>;\r\n    colorAttachmentDepthSlice: number | undefined;\r\n    depthAttachmentViewDescriptor: Nullable<GPUTextureViewDescriptor>;\r\n    colorAttachmentGPUTextures: (WebGPUHardwareTexture | null)[];\r\n    depthTextureFormat: GPUTextureFormat | undefined;\r\n}\r\n\r\n/**\r\n * Options to load the associated Glslang library\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GlslangOptions {\r\n    /**\r\n     * Defines an existing instance of Glslang (useful in modules who do not access the global instance).\r\n     */\r\n    glslang?: any;\r\n    /**\r\n     * Defines the URL of the glslang JS File.\r\n     */\r\n    jsPath?: string;\r\n    /**\r\n     * Defines the URL of the glslang WASM File.\r\n     */\r\n    wasmPath?: string;\r\n}\r\n\r\n/**\r\n * Options to create the WebGPU engine\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface WebGPUEngineOptions extends AbstractEngineOptions, GPURequestAdapterOptions {\r\n    /**\r\n     * The featureLevel property of the GPURequestAdapterOptions interface\r\n     */\r\n    featureLevel?: string;\r\n\r\n    /**\r\n     * Defines the category of adapter to use.\r\n     * Is it the discrete or integrated device.\r\n     */\r\n    powerPreference?: GPUPowerPreference;\r\n\r\n    /**\r\n     * When set to true, indicates that only a fallback adapter may be returned when requesting an adapter.\r\n     * If the user agent does not support a fallback adapter, will cause requestAdapter() to resolve to null.\r\n     * Default: false\r\n     */\r\n    forceFallbackAdapter?: boolean;\r\n\r\n    /**\r\n     * When set to true, requests a GPU adapter that is compatible with the user agent's XR device,\r\n     * as required to create a WebGPU-compatible WebXR session (see the WebXR/WebGPU binding spec).\r\n     * This mirrors the WebGL `xrCompatible` context attribute and must be set when the engine is\r\n     * created (adapter-request time): WebGPU has no post-hoc \"make XR compatible\" step, so it cannot\r\n     * be toggled on later. Leave unset/false for the default non-XR path.\r\n     * Default: false\r\n     * @experimental WebGPU-XR support is experimental and may change.\r\n     */\r\n    xrCompatible?: boolean;\r\n\r\n    /**\r\n     * Defines the device descriptor used to create a device once we have retrieved an appropriate adapter\r\n     */\r\n    deviceDescriptor?: GPUDeviceDescriptor;\r\n\r\n    /**\r\n     * When requesting the device, enable all the features supported by the adapter. Default: false\r\n     * Note that this setting is ignored if you explicitely set deviceDescriptor.requiredFeatures\r\n     */\r\n    enableAllFeatures?: boolean;\r\n\r\n    /**\r\n     * When requesting the device, set the required limits to the maximum possible values (the ones from adapter.limits). Default: false\r\n     * Note that this setting is ignored if you explicitely set deviceDescriptor.requiredLimits\r\n     */\r\n    setMaximumLimits?: boolean;\r\n\r\n    /**\r\n     * Defines the requested Swap Chain Format.\r\n     */\r\n    swapChainFormat?: GPUTextureFormat;\r\n\r\n    /**\r\n     * Defines whether we should generate debug markers in the gpu command lists (can be seen with PIX for eg). Default: false\r\n     */\r\n    enableGPUDebugMarkers?: boolean;\r\n\r\n    /**\r\n     * Options to load the associated Glslang library\r\n     */\r\n    glslangOptions?: GlslangOptions;\r\n\r\n    /**\r\n     * Options to load the associated Twgsl library\r\n     */\r\n    twgslOptions?: TwgslOptions;\r\n}\r\n\r\n/**\r\n * Options for pre-warming a render pipeline asynchronously.\r\n * All render state properties are optional and default to the most common opaque rendering state.\r\n */\r\nexport interface IWebGPURenderPipelineAsyncCreationOptions {\r\n    /**\r\n     * The compiled effect (shader stages) for the pipeline.\r\n     */\r\n    effect: Effect;\r\n    /**\r\n     * The mesh whose vertex buffer layout to use.\r\n     */\r\n    mesh: AbstractMesh;\r\n    /**\r\n     * The fill mode / primitive topology. Defaults to Constants.MATERIAL_TriangleFillMode.\r\n     */\r\n    fillMode?: number;\r\n    /**\r\n     * The MSAA sample count. Defaults to the engine's current sample count.\r\n     */\r\n    sampleCount?: number;\r\n    /**\r\n     * The color render target format. Defaults to the engine's current canvas color format.\r\n     */\r\n    colorFormat?: GPUTextureFormat;\r\n    /**\r\n     * The depth-stencil render target format. Defaults to the engine's current depth format.\r\n     */\r\n    depthStencilFormat?: GPUTextureFormat;\r\n    /**\r\n     * The alpha blending mode (e.g. Constants.ALPHA_DISABLE, Constants.ALPHA_COMBINE).\r\n     * Defaults to Constants.ALPHA_DISABLE.\r\n     */\r\n    alphaMode?: number;\r\n    /**\r\n     * Whether depth writing is enabled. Defaults to true.\r\n     */\r\n    depthWrite?: boolean;\r\n    /**\r\n     * Whether depth testing is enabled. Defaults to true.\r\n     */\r\n    depthTest?: boolean;\r\n    /**\r\n     * The depth comparison function (e.g. Constants.LEQUAL). Defaults to Constants.LEQUAL.\r\n     */\r\n    depthCompare?: number;\r\n    /**\r\n     * Whether back-face culling is enabled. Defaults to true.\r\n     */\r\n    cullEnabled?: boolean;\r\n    /**\r\n     * Which face to cull (1 = back, 2 = front). Defaults to 1 (back).\r\n     */\r\n    cullFace?: number;\r\n    /**\r\n     * Front face winding order (1 = CCW, 2 = CW). Defaults to 2 (CW).\r\n     */\r\n    frontFace?: number;\r\n    /**\r\n     * Color channel write mask (bitmask of RGBA channels). Defaults to 0xF (all channels).\r\n     */\r\n    writeMask?: number;\r\n    /**\r\n     * Whether stencil testing is enabled. Defaults to false.\r\n     */\r\n    stencilEnabled?: boolean;\r\n}\r\n\r\n/**\r\n * The web GPU engine class provides support for WebGPU version of babylon.js.\r\n * @since 5.0.0\r\n */\r\nexport class WebGPUEngine extends ThinWebGPUEngine {\r\n    // Default glslang options.\r\n    private static readonly _GlslangDefaultOptions: GlslangOptions = {\r\n        jsPath: `${Tools._DefaultCdnUrl}/glslang/glslang.js`,\r\n        wasmPath: `${Tools._DefaultCdnUrl}/glslang/glslang.wasm`,\r\n    };\r\n\r\n    private static _InstanceId = 0;\r\n\r\n    /** A unique id to identify this instance */\r\n    public readonly uniqueId = -1;\r\n\r\n    // Page Life cycle and constants\r\n    private readonly _uploadEncoderDescriptor = { label: \"upload\" };\r\n    private readonly _renderEncoderDescriptor = { label: \"render\" };\r\n    /** @internal */\r\n    public readonly _clearDepthValue = 1;\r\n    /** @internal */\r\n    public readonly _clearReverseDepthValue = 0;\r\n    /** @internal */\r\n    public _clearStencilValue = 0;\r\n    private readonly _defaultSampleCount = 4; // Only supported value for now.\r\n\r\n    // Engine Life Cycle\r\n    /** @internal */\r\n    public _options: WebGPUEngineOptions;\r\n    private _glslang: any = null;\r\n    private _tintWASM: Nullable<WebGPUTintWASM> = null;\r\n    private _glslangAndTintAreFullyLoaded = false;\r\n    private _adapter: GPUAdapter;\r\n    private _adapterSupportedExtensions: GPUFeatureName[];\r\n    private _adapterInfo: GPUAdapterInfo = {\r\n        vendor: \"\",\r\n        architecture: \"\",\r\n        device: \"\",\r\n        description: \"\",\r\n        subgroupMinSize: 0,\r\n        subgroupMaxSize: 0,\r\n        isFallbackAdapter: false,\r\n    };\r\n    private _adapterSupportedLimits: GPUSupportedLimits;\r\n    /** @internal */\r\n    public _device: GPUDevice;\r\n    private _deviceEnabledExtensions: GPUFeatureName[];\r\n    private _deviceLimits: GPUSupportedLimits;\r\n    private _context: GPUCanvasContext;\r\n    private _mainPassSampleCount: number;\r\n    private _glslangOptions?: GlslangOptions;\r\n    private _twgslOptions?: TwgslOptions;\r\n    /** @internal */\r\n    public _bufferManager: WebGPUBufferManager;\r\n    private _clearQuad: WebGPUClearQuad;\r\n    /** @internal */\r\n    public _cacheSampler: WebGPUCacheSampler;\r\n    private _cacheBindGroups: WebGPUCacheBindGroups;\r\n    private _cacheTextureViews: WebGPUCacheTextureView;\r\n    private _emptyVertexBuffer: VertexBuffer;\r\n    /** @internal */\r\n    public _mrtAttachments: number[];\r\n    /** @internal */\r\n    public _compiledComputeEffects: { [key: string]: ComputeEffect } = {};\r\n    /** @internal */\r\n    public _counters: {\r\n        numEnableEffects: number;\r\n        numEnableDrawWrapper: number;\r\n        numBundleCreationNonCompatMode: number;\r\n        numBundleReuseNonCompatMode: number;\r\n    } = {\r\n        numEnableEffects: 0,\r\n        numEnableDrawWrapper: 0,\r\n        numBundleCreationNonCompatMode: 0,\r\n        numBundleReuseNonCompatMode: 0,\r\n    };\r\n    /**\r\n     * Counters from last frame\r\n     */\r\n    public readonly countersLastFrame: {\r\n        numEnableEffects: number;\r\n        numEnableDrawWrapper: number;\r\n        numBundleCreationNonCompatMode: number;\r\n        numBundleReuseNonCompatMode: number;\r\n    } = {\r\n        numEnableEffects: 0,\r\n        numEnableDrawWrapper: 0,\r\n        numBundleCreationNonCompatMode: 0,\r\n        numBundleReuseNonCompatMode: 0,\r\n    };\r\n    /**\r\n     * Max number of uncaptured error messages to log\r\n     */\r\n    public numMaxUncapturedErrors = 20;\r\n\r\n    /**\r\n     * Gets the list of created scenes\r\n     */\r\n    public override scenes: Scene[] = [];\r\n\r\n    /** @internal */\r\n    public override _virtualScenes = new Array<Scene>();\r\n\r\n    // Some of the internal state might change during the render pass.\r\n    // This happens mainly during clear for the state\r\n    // And when the frame starts to swap the target texture from the swap chain\r\n    private _mainTexture: GPUTexture;\r\n    private _depthTexture: GPUTexture;\r\n    private _mainTextureExtends: GPUExtent3D;\r\n    private _depthTextureFormat: GPUTextureFormat | undefined;\r\n    private _colorFormat: GPUTextureFormat | null;\r\n    /** @internal */\r\n    public _ubInvertY: WebGPUDataBuffer;\r\n    /** @internal */\r\n    public _ubDontInvertY: WebGPUDataBuffer;\r\n\r\n    private _commandBuffers: GPUCommandBuffer[] = [null as any, null as any];\r\n\r\n    // Frame Buffer Life Cycle (recreated for each render target pass)\r\n\r\n    private _mainRenderPassWrapper: IWebGPURenderPassWrapper = {\r\n        renderPassDescriptor: null,\r\n        colorAttachmentViewDescriptor: null,\r\n        colorAttachmentDepthSlice: undefined,\r\n        depthAttachmentViewDescriptor: null,\r\n        colorAttachmentGPUTextures: [],\r\n        depthTextureFormat: undefined,\r\n    };\r\n    private _rttRenderPassWrapper: IWebGPURenderPassWrapper = {\r\n        renderPassDescriptor: null,\r\n        colorAttachmentViewDescriptor: null,\r\n        colorAttachmentDepthSlice: undefined,\r\n        depthAttachmentViewDescriptor: null,\r\n        colorAttachmentGPUTextures: [],\r\n        depthTextureFormat: undefined,\r\n    };\r\n\r\n    // DrawCall Life Cycle\r\n    // Effect is on the parent class\r\n    // protected _currentEffect: Nullable<Effect> = null;\r\n    private _defaultDrawContext: WebGPUDrawContext;\r\n    private _defaultMaterialContext: WebGPUMaterialContext;\r\n    /** @internal */\r\n    public override _currentDrawContext: WebGPUDrawContext;\r\n    /** @internal */\r\n    public override _currentMaterialContext: WebGPUMaterialContext;\r\n    private _currentVertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private _currentOverrideVertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }> = null;\r\n    private _currentIndexBuffer: Nullable<DataBuffer> = null;\r\n    private _dummyIndexBuffer: WebGPUDataBuffer;\r\n    private _colorWriteLocal = true;\r\n    private _forceEnableEffect = false;\r\n    private _internalFrameCounter = 0;\r\n\r\n    /**\r\n     * Gets or sets the snapshot rendering mode\r\n     */\r\n    public override get snapshotRenderingMode(): number {\r\n        return this._snapshotRendering.mode;\r\n    }\r\n\r\n    public override set snapshotRenderingMode(mode: number) {\r\n        this._snapshotRendering.mode = mode;\r\n    }\r\n\r\n    /**\r\n     * Creates a new snapshot at the next frame using the current snapshotRenderingMode\r\n     */\r\n    public snapshotRenderingReset(): void {\r\n        this._snapshotRendering.reset();\r\n    }\r\n\r\n    /**\r\n     * Enables or disables the snapshot rendering mode\r\n     * Note that the WebGL engine does not support snapshot rendering so setting the value won't have any effect for this engine\r\n     */\r\n    public override get snapshotRendering(): boolean {\r\n        return this._snapshotRendering.enabled;\r\n    }\r\n\r\n    public override set snapshotRendering(activate) {\r\n        this._snapshotRendering.enabled = activate;\r\n    }\r\n\r\n    /**\r\n     * Sets this to true to disable the cache for the samplers. You should do it only for testing purpose!\r\n     */\r\n    public get disableCacheSamplers(): boolean {\r\n        return this._cacheSampler ? this._cacheSampler.disabled : false;\r\n    }\r\n\r\n    public set disableCacheSamplers(disable: boolean) {\r\n        if (this._cacheSampler) {\r\n            this._cacheSampler.disabled = disable;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets this to true to disable the cache for the render pipelines. You should do it only for testing purpose!\r\n     */\r\n    public get disableCacheRenderPipelines(): boolean {\r\n        return this._cacheRenderPipeline ? this._cacheRenderPipeline.disabled : false;\r\n    }\r\n\r\n    public set disableCacheRenderPipelines(disable: boolean) {\r\n        if (this._cacheRenderPipeline) {\r\n            this._cacheRenderPipeline.disabled = disable;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * When true (default), the \"leftover\" uniform buffer of an effect (the buffer that holds the uniforms not declared in a named\r\n     * uniform block) keeps one GPU buffer per draw context, so a given draw call always binds the same buffer for a given effect.\r\n     * When false, the GPU buffers are assigned in draw order: the buffer bound by a draw call then changes with the order in which\r\n     * meshes are drawn, and every new (draw context, buffer) pair is a new entry in the bind group cache.\r\n     * Change it before rendering the first frame. You should set it to false only for testing purpose!\r\n     * @internal\r\n     */\r\n    public _useOwnerKeyedUniformBufferSlots = true;\r\n\r\n    /**\r\n     * Sets this to true to disable the cache for the bind groups. You should do it only for testing purpose!\r\n     */\r\n    public get disableCacheBindGroups(): boolean {\r\n        return this._cacheBindGroups ? this._cacheBindGroups.disabled : false;\r\n    }\r\n\r\n    public set disableCacheBindGroups(disable: boolean) {\r\n        if (this._cacheBindGroups) {\r\n            this._cacheBindGroups.disabled = disable;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if all created effects are ready\r\n     * @returns true if all effects are ready\r\n     */\r\n    public areAllEffectsReady(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Get Font size information\r\n     * @param font font name\r\n     * @returns an object containing ascent, height and descent\r\n     */\r\n    public override getFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n        return GetFontOffset(font);\r\n    }\r\n\r\n    /**\r\n     * Gets a Promise<boolean> indicating if the engine can be instantiated (ie. if a WebGPU context can be found)\r\n     */\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public static get IsSupportedAsync(): Promise<boolean> {\r\n        return !navigator.gpu\r\n            ? Promise.resolve(false)\r\n            : navigator.gpu\r\n                  .requestAdapter()\r\n                  // eslint-disable-next-line github/no-then\r\n                  .then(\r\n                      (adapter: GPUAdapter | null | undefined) => !!adapter,\r\n                      () => false\r\n                  )\r\n                  // eslint-disable-next-line github/no-then\r\n                  .catch(() => false);\r\n    }\r\n\r\n    /**\r\n     * Not supported by WebGPU, you should call IsSupportedAsync instead!\r\n     */\r\n    public static get IsSupported(): boolean {\r\n        Logger.Warn(\"You must call IsSupportedAsync for WebGPU!\");\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the engine supports uniform buffers\r\n     */\r\n    public get supportsUniformBuffers(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /** Gets the supported extensions by the WebGPU adapter */\r\n    public get supportedExtensions(): Immutable<GPUFeatureName[]> {\r\n        return this._adapterSupportedExtensions;\r\n    }\r\n\r\n    /** Gets the currently enabled extensions on the WebGPU device */\r\n    public get enabledExtensions(): Immutable<GPUFeatureName[]> {\r\n        return this._deviceEnabledExtensions;\r\n    }\r\n\r\n    /** Gets the supported limits by the WebGPU adapter */\r\n    public get supportedLimits(): GPUSupportedLimits {\r\n        return this._adapterSupportedLimits;\r\n    }\r\n\r\n    /** Gets the current limits of the WebGPU device */\r\n    public get currentLimits() {\r\n        return this._deviceLimits;\r\n    }\r\n\r\n    /**\r\n     * Returns a string describing the current engine\r\n     */\r\n    public override get description(): string {\r\n        const description = this.name + this.version;\r\n\r\n        return description;\r\n    }\r\n\r\n    /**\r\n     * Returns the version of the engine\r\n     */\r\n    public get version(): number {\r\n        return 1;\r\n    }\r\n\r\n    /**\r\n     * Gets an object containing information about the current engine context\r\n     * @returns an object containing the vendor, the renderer and the version of the current engine context\r\n     */\r\n    public getInfo() {\r\n        return {\r\n            vendor: this._adapterInfo.vendor || \"unknown vendor\",\r\n            renderer: this._adapterInfo.architecture || \"unknown renderer\",\r\n            version: this._adapterInfo.description || \"unknown version\",\r\n        };\r\n    }\r\n\r\n    /**\r\n     * (WebGPU only) True (default) to be in compatibility mode, meaning rendering all existing scenes without artifacts (same rendering than WebGL).\r\n     * Setting the property to false will improve performances but may not work in some scenes if some precautions are not taken.\r\n     * See https://doc.babylonjs.com/setup/support/webGPU/webGPUOptimization/webGPUNonCompatibilityMode for more details\r\n     */\r\n    public override get compatibilityMode() {\r\n        return this._compatibilityMode;\r\n    }\r\n\r\n    public override set compatibilityMode(mode: boolean) {\r\n        this._compatibilityMode = mode;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of samples used by the current render target\r\n     * @returns the current sample count, or 1 when multisampling is disabled\r\n     */\r\n    public get currentSampleCount(): number {\r\n        return this._currentRenderTarget ? this._currentRenderTarget.samples : this._mainPassSampleCount;\r\n    }\r\n\r\n    /**\r\n     * Create a new instance of the gpu engine asynchronously\r\n     * @param canvas Defines the canvas to use to display the result\r\n     * @param options Defines the options passed to the engine to create the GPU context dependencies\r\n     * @returns a promise that resolves with the created engine\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static CreateAsync(canvas: HTMLCanvasElement, options: WebGPUEngineOptions = {}): Promise<WebGPUEngine> {\r\n        const engine = new WebGPUEngine(canvas, options);\r\n\r\n        return new Promise((resolve) => {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            engine.initAsync(options.glslangOptions, options.twgslOptions).then(() => resolve(engine));\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Indicates if the z range in NDC space is 0..1 (value: true) or -1..1 (value: false)\r\n     */\r\n    public override readonly isNDCHalfZRange: boolean = true;\r\n\r\n    /**\r\n     * Indicates that the origin of the texture/framebuffer space is the bottom left corner. If false, the origin is top left\r\n     */\r\n    public override readonly hasOriginBottomLeft: boolean = false;\r\n\r\n    /**\r\n     * Create a new instance of the gpu engine.\r\n     * @param canvas Defines the canvas to use to display the result\r\n     * @param options Defines the options passed to the engine to create the GPU context dependencies\r\n     */\r\n    public constructor(canvas: HTMLCanvasElement | OffscreenCanvas, options: WebGPUEngineOptions = {}) {\r\n        RegisterAbstractEngineDom();\r\n        RegisterAbstractEngineRenderPass();\r\n        super(options.antialias ?? true, options);\r\n        this._name = \"WebGPU\";\r\n\r\n        this._drawCalls = new PerfCounter();\r\n\r\n        options.deviceDescriptor = options.deviceDescriptor || {};\r\n        options.enableGPUDebugMarkers = options.enableGPUDebugMarkers ?? false;\r\n\r\n        this._enableGPUDebugMarkers = options.enableGPUDebugMarkers;\r\n\r\n        Logger.Log(`Babylon.js v${AbstractEngine.Version} - ${this.description} engine`);\r\n        if (!navigator.gpu) {\r\n            Logger.Error(\"WebGPU is not supported by your browser.\");\r\n            return;\r\n        }\r\n\r\n        options.swapChainFormat = options.swapChainFormat || navigator.gpu.getPreferredCanvasFormat();\r\n\r\n        this._isWebGPU = true;\r\n        this._shaderPlatformName = \"WEBGPU\";\r\n\r\n        this._renderingCanvas = canvas as HTMLCanvasElement;\r\n        this._options = options;\r\n\r\n        this._mainPassSampleCount = options.antialias ? this._defaultSampleCount : 1;\r\n\r\n        if (navigator && navigator.userAgent) {\r\n            this._setupMobileChecks();\r\n        }\r\n\r\n        this._sharedInit(this._renderingCanvas);\r\n\r\n        this._shaderProcessor = new WebGPUShaderProcessorGLSL();\r\n        this._shaderProcessorWGSL = new WebGPUShaderProcessorWGSL();\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Initialization\r\n    //------------------------------------------------------------------------------\r\n    private _workingGlslangAndTintPromise: Nullable<Promise<void>> = null;\r\n\r\n    /**\r\n     * Load the glslang and tintWASM libraries and prepare them for use.\r\n     * @returns a promise that resolves when the engine is ready to use the glslang and tintWASM\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public prepareGlslangAndTintAsync(): Promise<void> {\r\n        if (!this._workingGlslangAndTintPromise) {\r\n            this._workingGlslangAndTintPromise = new Promise<void>((resolve) => {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                this._initGlslangAsync(this._glslangOptions ?? this._options?.glslangOptions).then((glslang: any) => {\r\n                    this._glslang = glslang;\r\n                    this._tintWASM = new WebGPUTintWASM();\r\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                    this._tintWASM.initTwgsl(this._twgslOptions ?? this._options?.twgslOptions).then(() => {\r\n                        this._glslangAndTintAreFullyLoaded = true;\r\n                        resolve();\r\n                    });\r\n                });\r\n            });\r\n        }\r\n\r\n        return this._workingGlslangAndTintPromise;\r\n    }\r\n\r\n    /**\r\n     * Initializes the WebGPU context and dependencies.\r\n     * @param glslangOptions Defines the GLSLang compiler options if necessary\r\n     * @param twgslOptions Defines the Twgsl compiler options if necessary\r\n     * @returns a promise notifying the readiness of the engine.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public initAsync(glslangOptions?: GlslangOptions, twgslOptions?: TwgslOptions): Promise<void> {\r\n        (this.uniqueId as number) = WebGPUEngine._InstanceId++;\r\n        this._glslangOptions = glslangOptions;\r\n        this._twgslOptions = twgslOptions;\r\n        return (\r\n            navigator\r\n                .gpu!.requestAdapter(this._options)\r\n                // eslint-disable-next-line github/no-then\r\n                .then(async (adapter: GPUAdapter | null | undefined) => {\r\n                    if (!adapter) {\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"Could not retrieve a WebGPU adapter (adapter is null or undefined).\";\r\n                    } else {\r\n                        this._adapter = adapter!;\r\n                        this._adapterSupportedExtensions = [];\r\n                        this._adapter.features?.forEach((feature) => {\r\n                            this._adapterSupportedExtensions.push(feature as GPUFeatureName);\r\n                        });\r\n                        this._adapterSupportedLimits = this._adapter.limits;\r\n                        this._adapterInfo = this._adapter.info;\r\n\r\n                        const deviceDescriptor = this._options.deviceDescriptor ?? {};\r\n                        const requiredFeatures = deviceDescriptor?.requiredFeatures ?? (this._options.enableAllFeatures ? this._adapterSupportedExtensions : undefined);\r\n\r\n                        if (requiredFeatures) {\r\n                            const requestedExtensions = requiredFeatures;\r\n                            const validExtensions: GPUFeatureName[] = [];\r\n\r\n                            for (const extension of requestedExtensions) {\r\n                                if (this._adapterSupportedExtensions.indexOf(extension) !== -1) {\r\n                                    validExtensions.push(extension);\r\n                                }\r\n                            }\r\n\r\n                            deviceDescriptor.requiredFeatures = validExtensions;\r\n                        }\r\n\r\n                        if (this._options.setMaximumLimits && !deviceDescriptor.requiredLimits) {\r\n                            deviceDescriptor.requiredLimits = {};\r\n                            for (const name in this._adapterSupportedLimits) {\r\n                                if (name === \"minSubgroupSize\" || name === \"maxSubgroupSize\") {\r\n                                    // Chrome exposes these limits in \"webgpu developer\" mode, but these can't be set on the device.\r\n                                    continue;\r\n                                }\r\n                                deviceDescriptor.requiredLimits[name] = this._adapterSupportedLimits[name];\r\n                            }\r\n                        }\r\n\r\n                        deviceDescriptor.label = `BabylonWebGPUDevice${this.uniqueId}`;\r\n\r\n                        return await this._adapter.requestDevice(deviceDescriptor);\r\n                    }\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .then((device: GPUDevice) => {\r\n                    this._device = device;\r\n                    this._deviceEnabledExtensions = [];\r\n                    this._device.features?.forEach((feature) => {\r\n                        this._deviceEnabledExtensions.push(feature as GPUFeatureName);\r\n                    });\r\n                    this._deviceLimits = device.limits;\r\n\r\n                    let numUncapturedErrors = -1;\r\n                    this._device.addEventListener(\"uncapturederror\", (event) => {\r\n                        if (++numUncapturedErrors < this.numMaxUncapturedErrors) {\r\n                            Logger.Warn(\r\n                                `[Frame ${this._frameId}] WebGPU uncaptured error (${numUncapturedErrors + 1}): ${(<GPUUncapturedErrorEvent>event).error} - ${(<any>event).error.message}`\r\n                            );\r\n                        } else if (numUncapturedErrors++ === this.numMaxUncapturedErrors) {\r\n                            Logger.Warn(\r\n                                `[Frame ${this._frameId}] WebGPU uncaptured error: too many warnings (${this.numMaxUncapturedErrors}), no more warnings will be reported to the console for this engine.`\r\n                            );\r\n                        }\r\n                    });\r\n\r\n                    if (!this._doNotHandleContextLost) {\r\n                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                        this._device.lost?.then((info) => {\r\n                            if (this._isDisposed) {\r\n                                return;\r\n                            }\r\n                            this._contextWasLost = true;\r\n                            Logger.Warn(\"WebGPU context lost. \" + info);\r\n                            this.onContextLostObservable.notifyObservers(this);\r\n                            // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n                            this._restoreEngineAfterContextLost(async () => {\r\n                                const snapshotRenderingMode = this.snapshotRenderingMode;\r\n                                const snapshotRendering = this.snapshotRendering;\r\n                                const disableCacheSamplers = this.disableCacheSamplers;\r\n                                const disableCacheRenderPipelines = this.disableCacheRenderPipelines;\r\n                                const disableCacheBindGroups = this.disableCacheBindGroups;\r\n                                const enableGPUTimingMeasurements = this.enableGPUTimingMeasurements;\r\n\r\n                                await this.initAsync(this._glslangOptions ?? this._options?.glslangOptions, this._twgslOptions ?? this._options?.twgslOptions);\r\n\r\n                                this.snapshotRenderingMode = snapshotRenderingMode;\r\n                                this.snapshotRendering = snapshotRendering;\r\n                                this.disableCacheSamplers = disableCacheSamplers;\r\n                                this.disableCacheRenderPipelines = disableCacheRenderPipelines;\r\n                                this.disableCacheBindGroups = disableCacheBindGroups;\r\n                                this.enableGPUTimingMeasurements = enableGPUTimingMeasurements;\r\n                                this._currentRenderPass = null;\r\n                            });\r\n                        });\r\n                    }\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .then(() => {\r\n                    this._initializeLimits();\r\n\r\n                    this._bufferManager = new WebGPUBufferManager(this, this._device);\r\n                    this._textureHelper = new WebGPUTextureManager(this, this._device, this._bufferManager, this._deviceEnabledExtensions);\r\n                    this._cacheSampler = new WebGPUCacheSampler(this._device);\r\n                    this._cacheBindGroups = new WebGPUCacheBindGroups(this._device, this._cacheSampler, this);\r\n                    this._cacheTextureViews = new WebGPUCacheTextureView();\r\n                    this._timestampQuery = new WebGPUTimestampQuery(this, this._device, this._bufferManager);\r\n                    this._occlusionQuery = (this._device as any).createQuerySet ? new WebGPUOcclusionQuery(this, this._device, this._bufferManager) : (undefined as any);\r\n                    this._bundleList = new WebGPUBundleList(this._device);\r\n                    this._snapshotRendering = new WebGPUSnapshotRendering(this, this._snapshotRenderingMode, this._bundleList);\r\n\r\n                    this._ubInvertY = this._bufferManager.createBuffer(\r\n                        new Float32Array([-1, 0]),\r\n                        WebGPUConstants.BufferUsage.Uniform | WebGPUConstants.BufferUsage.CopyDst,\r\n                        \"UBInvertY\"\r\n                    );\r\n                    this._ubDontInvertY = this._bufferManager.createBuffer(\r\n                        new Float32Array([1, 0]),\r\n                        WebGPUConstants.BufferUsage.Uniform | WebGPUConstants.BufferUsage.CopyDst,\r\n                        \"UBDontInvertY\"\r\n                    );\r\n\r\n                    const frameCounter = this._internalFrameCounter++;\r\n\r\n                    this._uploadEncoderDescriptor.label = `[${this.frameId}|${frameCounter}] - UploadEncoder`;\r\n                    this._renderEncoderDescriptor.label = `[${this.frameId}|${frameCounter}] - RenderEncoder`;\r\n\r\n                    this._uploadEncoder = this._device.createCommandEncoder(this._uploadEncoderDescriptor);\r\n                    this._renderEncoder = this._device.createCommandEncoder(this._renderEncoderDescriptor);\r\n\r\n                    this._emptyVertexBuffer = new VertexBuffer(this, [0], \"\", {\r\n                        stride: 1,\r\n                        offset: 0,\r\n                        size: 1,\r\n                        label: \"EmptyVertexBuffer\",\r\n                    });\r\n\r\n                    this._dummyIndexBuffer = this._bufferManager.createBuffer(\r\n                        new Uint16Array([0, 0, 0, 0]),\r\n                        WebGPUConstants.BufferUsage.Storage | WebGPUConstants.BufferUsage.CopyDst,\r\n                        \"DummyIndices\"\r\n                    );\r\n\r\n                    this._cacheRenderPipeline = new WebGPUCacheRenderPipelineTree(this._device, this._emptyVertexBuffer);\r\n\r\n                    this._depthCullingState = new WebGPUDepthCullingState(this._cacheRenderPipeline);\r\n                    this._stencilStateComposer = new WebGPUStencilStateComposer(this._cacheRenderPipeline);\r\n                    this._stencilStateComposer.stencilGlobal = this._stencilState;\r\n\r\n                    this._depthCullingState.depthTest = true;\r\n                    this._depthCullingState.depthFunc = Constants.LEQUAL;\r\n                    this._depthCullingState.depthMask = true;\r\n\r\n                    this._textureHelper.setCommandEncoder(this._uploadEncoder);\r\n\r\n                    this._clearQuad = new WebGPUClearQuad(this._device, this, this._emptyVertexBuffer);\r\n                    this._defaultDrawContext = this.createDrawContext()!;\r\n                    this._currentDrawContext = this._defaultDrawContext;\r\n                    this._defaultMaterialContext = this.createMaterialContext()!;\r\n                    this._currentMaterialContext = this._defaultMaterialContext;\r\n\r\n                    this._initializeContextAndSwapChain();\r\n                    this._initializeMainAttachments();\r\n                    this.resize();\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .catch((e: any) => {\r\n                    Logger.Error(\"A fatal error occurred during WebGPU creation/initialization.\");\r\n                    throw e;\r\n                })\r\n        );\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    private _initGlslangAsync(glslangOptions?: GlslangOptions): Promise<any> {\r\n        glslangOptions = glslangOptions || {};\r\n        glslangOptions = {\r\n            ...WebGPUEngine._GlslangDefaultOptions,\r\n            ...glslangOptions,\r\n        };\r\n\r\n        if (glslangOptions.glslang) {\r\n            return glslangOptions.glslang;\r\n        }\r\n\r\n        if ((self as any).glslang) {\r\n            return (self as any).glslang(glslangOptions.wasmPath);\r\n        }\r\n\r\n        if (glslangOptions.jsPath && glslangOptions.wasmPath) {\r\n            // eslint-disable-next-line github/no-then\r\n            return Tools.LoadBabylonScriptAsync(glslangOptions.jsPath).then(() => {\r\n                return (self as any).glslang(Tools.GetBabylonScriptURL(glslangOptions.wasmPath!));\r\n            });\r\n        }\r\n\r\n        throw new Error(\"glslang is not available\");\r\n    }\r\n\r\n    private _initializeLimits(): void {\r\n        // Init caps\r\n        const textureFormatsTier1 = this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.TextureFormatsTier1) >= 0;\r\n\r\n        this._caps = {\r\n            maxTexturesImageUnits: this._deviceLimits.maxSampledTexturesPerShaderStage,\r\n            maxVertexTextureImageUnits: this._deviceLimits.maxSampledTexturesPerShaderStage,\r\n            maxCombinedTexturesImageUnits: this._deviceLimits.maxSampledTexturesPerShaderStage * 2,\r\n            maxTextureSize: this._deviceLimits.maxTextureDimension2D,\r\n            maxCubemapTextureSize: this._deviceLimits.maxTextureDimension2D,\r\n            maxRenderTextureSize: this._deviceLimits.maxTextureDimension2D,\r\n            maxVertexAttribs: this._deviceLimits.maxVertexAttributes,\r\n            maxDrawBuffers: 8,\r\n            maxVaryingVectors: this._deviceLimits.maxInterStageShaderVariables,\r\n            maxFragmentUniformVectors: Math.floor(this._deviceLimits.maxUniformBufferBindingSize / 4),\r\n            maxVertexUniformVectors: Math.floor(this._deviceLimits.maxUniformBufferBindingSize / 4),\r\n            maxUniformBuffersPerShaderStage: this._deviceLimits.maxUniformBuffersPerShaderStage,\r\n            shaderFloatPrecision: 23, // WGSL always uses IEEE-754 binary32 floats (which have 23 bits of significand)\r\n            standardDerivatives: true,\r\n            astc: (this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.TextureCompressionASTC) >= 0 ? true : undefined) as any,\r\n            s3tc: (this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.TextureCompressionBC) >= 0 ? true : undefined) as any,\r\n            pvrtc: null,\r\n            etc1: null,\r\n            etc2: (this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.TextureCompressionETC2) >= 0 ? true : undefined) as any,\r\n            bptc: this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.TextureCompressionBC) >= 0 ? true : undefined,\r\n            maxAnisotropy: 16, // Most implementations support maxAnisotropy values in range between 1 and 16, inclusive. The used value of maxAnisotropy will be clamped to the maximum value that the platform supports.\r\n            uintIndices: true,\r\n            fragmentDepthSupported: true,\r\n            highPrecisionShaderSupported: true,\r\n            colorBufferFloat: true,\r\n            blendFloat: this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.Float32Blendable) >= 0,\r\n            supportFloatTexturesResolve: false, // See https://github.com/gpuweb/gpuweb/issues/3844\r\n            rg11b10ufColorRenderable: this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.RG11B10UFloatRenderable) >= 0,\r\n            textureFloat: true,\r\n            textureFloatLinearFiltering: this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.Float32Filterable) >= 0,\r\n            textureFloatRender: true,\r\n            textureHalfFloat: true,\r\n            textureHalfFloatLinearFiltering: true,\r\n            textureHalfFloatRender: true,\r\n            textureLOD: true,\r\n            texelFetch: true,\r\n            drawBuffersExtension: true,\r\n            depthTextureExtension: true,\r\n            vertexArrayObject: false,\r\n            instancedArrays: true,\r\n            timerQuery:\r\n                typeof BigUint64Array !== \"undefined\" && this._deviceEnabledExtensions.indexOf(WebGPUConstants.FeatureName.TimestampQuery) !== -1 ? (true as any) : undefined,\r\n            supportOcclusionQuery: typeof BigUint64Array !== \"undefined\",\r\n            canUseTimestampForTimerQuery: true,\r\n            multiview: false,\r\n            oculusMultiview: false,\r\n            parallelShaderCompile: undefined,\r\n            blendMinMax: true,\r\n            maxMSAASamples: 4, // the spec only supports values of 1 and 4\r\n            canUseGLInstanceID: true,\r\n            canUseGLVertexID: true,\r\n            supportComputeShaders: true,\r\n            supportSRGBBuffers: true,\r\n            supportTransformFeedbacks: false,\r\n            textureMaxLevel: true,\r\n            texture2DArrayMaxLayerCount: this._deviceLimits.maxTextureArrayLayers,\r\n            disableMorphTargetTexture: false,\r\n            textureNorm16: textureFormatsTier1,\r\n            blendParametersPerTarget: true,\r\n            dualSourceBlending: this._deviceEnabledExtensions.includes(WebGPUConstants.FeatureName.DualSourceBlending),\r\n            supportReadWriteStorageTextures: typeof navigator !== \"undefined\" && navigator.gpu?.wgslLanguageFeatures?.has(\"readonly_and_readwrite_storage_textures\") === true,\r\n        };\r\n\r\n        this._features = {\r\n            forceBitmapOverHTMLImageElement: true,\r\n            supportRenderAndCopyToLodForFloatTextures: true,\r\n            supportDepthStencilTexture: true,\r\n            supportShadowSamplers: true,\r\n            uniformBufferHardCheckMatrix: false,\r\n            allowTexturePrefiltering: true,\r\n            trackUbosInFrame: true,\r\n            checkUbosContentBeforeUpload: true,\r\n            supportCSM: true,\r\n            basisNeedsPOT: false,\r\n            support3DTextures: true,\r\n            needTypeSuffixInShaderConstants: true,\r\n            supportMSAA: true,\r\n            supportSSAO2: true,\r\n            supportIBLShadows: true,\r\n            supportExtendedTextureFormats: true,\r\n            supportSwitchCaseInShader: true,\r\n            supportSyncTextureRead: false,\r\n            needsInvertingBitmap: false,\r\n            useUBOBindingCache: false,\r\n            needShaderCodeInlining: true,\r\n            needToAlwaysBindUniformBuffers: true,\r\n            supportRenderPasses: true,\r\n            supportSpriteInstancing: true,\r\n            forceVertexBufferStrideAndOffsetMultiple4Bytes: true,\r\n            _checkNonFloatVertexBuffersDontRecreatePipelineContext: true,\r\n        };\r\n\r\n        this._alphaState = new AlphaState(this._caps.blendParametersPerTarget);\r\n    }\r\n\r\n    private _initializeContextAndSwapChain(): void {\r\n        if (!this._renderingCanvas) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"The rendering canvas has not been set!\";\r\n        }\r\n        this._context = this._renderingCanvas.getContext(\"webgpu\") as unknown as GPUCanvasContext;\r\n        this._configureContext();\r\n        this._colorFormat = this._options.swapChainFormat!;\r\n        this._mainRenderPassWrapper.colorAttachmentGPUTextures = [new WebGPUHardwareTexture(this)];\r\n        this._mainRenderPassWrapper.colorAttachmentGPUTextures[0]!.format = this._colorFormat;\r\n        this._setColorFormat(this._mainRenderPassWrapper);\r\n    }\r\n\r\n    // Set default values as WebGL with depth and stencil attachment for the broadest Compat.\r\n    private _initializeMainAttachments(): void {\r\n        if (!this._bufferManager) {\r\n            return;\r\n        }\r\n\r\n        this.flushFramebuffer();\r\n\r\n        this._mainTextureExtends = {\r\n            width: this.getRenderWidth(true),\r\n            height: this.getRenderHeight(true),\r\n            depthOrArrayLayers: 1,\r\n        };\r\n\r\n        const bufferDataUpdate = new Float32Array([this.getRenderHeight(true)]);\r\n\r\n        this._bufferManager.setSubData(this._ubInvertY, 4, bufferDataUpdate);\r\n        this._bufferManager.setSubData(this._ubDontInvertY, 4, bufferDataUpdate);\r\n\r\n        let mainColorAttachments: GPURenderPassColorAttachment[];\r\n\r\n        if (this._options.antialias) {\r\n            const mainTextureDescriptor: GPUTextureDescriptor = {\r\n                label: `Texture_MainColor_${this._mainTextureExtends.width}x${this._mainTextureExtends.height}_antialiasing`,\r\n                size: this._mainTextureExtends,\r\n                mipLevelCount: 1,\r\n                sampleCount: this._mainPassSampleCount,\r\n                dimension: WebGPUConstants.TextureDimension.E2d,\r\n                format: this._options.swapChainFormat!,\r\n                usage: WebGPUConstants.TextureUsage.RenderAttachment,\r\n            };\r\n\r\n            if (this._mainTexture) {\r\n                this._textureHelper.releaseTexture(this._mainTexture);\r\n            }\r\n            this._mainTexture = this._device.createTexture(mainTextureDescriptor);\r\n            mainColorAttachments = [\r\n                {\r\n                    view: this._mainTexture.createView({\r\n                        label: \"TextureView_MainColor_antialiasing\",\r\n                        dimension: WebGPUConstants.TextureDimension.E2d,\r\n                        format: this._options.swapChainFormat!,\r\n                        mipLevelCount: 1,\r\n                        arrayLayerCount: 1,\r\n                    }),\r\n                    clearValue: new Color4(0, 0, 0, 1),\r\n                    loadOp: WebGPUConstants.LoadOp.Clear,\r\n                    storeOp: WebGPUConstants.StoreOp.Store, // don't use StoreOp.Discard, else using several cameras with different viewports or using scissors will fail because we call beginRenderPass / endPass several times for the same color attachment!\r\n                },\r\n            ];\r\n        } else {\r\n            mainColorAttachments = [\r\n                {\r\n                    view: undefined as any,\r\n                    clearValue: new Color4(0, 0, 0, 1),\r\n                    loadOp: WebGPUConstants.LoadOp.Clear,\r\n                    storeOp: WebGPUConstants.StoreOp.Store,\r\n                },\r\n            ];\r\n        }\r\n\r\n        this._mainRenderPassWrapper.depthTextureFormat = this.isStencilEnable ? WebGPUConstants.TextureFormat.Depth24PlusStencil8 : WebGPUConstants.TextureFormat.Depth32Float;\r\n\r\n        this._setDepthTextureFormat(this._mainRenderPassWrapper);\r\n        this._setColorFormat(this._mainRenderPassWrapper);\r\n\r\n        const depthTextureDescriptor: GPUTextureDescriptor = {\r\n            label: `Texture_MainDepthStencil_${this._mainTextureExtends.width}x${this._mainTextureExtends.height}`,\r\n            size: this._mainTextureExtends,\r\n            mipLevelCount: 1,\r\n            sampleCount: this._mainPassSampleCount,\r\n            dimension: WebGPUConstants.TextureDimension.E2d,\r\n            format: this._mainRenderPassWrapper.depthTextureFormat,\r\n            usage: WebGPUConstants.TextureUsage.RenderAttachment,\r\n        };\r\n\r\n        if (this._depthTexture) {\r\n            this._textureHelper.releaseTexture(this._depthTexture);\r\n        }\r\n        this._depthTexture = this._device.createTexture(depthTextureDescriptor);\r\n        const mainDepthAttachment: GPURenderPassDepthStencilAttachment = {\r\n            view: this._depthTexture.createView({\r\n                label: `TextureView_MainDepthStencil_${this._mainTextureExtends.width}x${this._mainTextureExtends.height}`,\r\n                dimension: WebGPUConstants.TextureDimension.E2d,\r\n                format: this._depthTexture.format,\r\n                mipLevelCount: 1,\r\n                arrayLayerCount: 1,\r\n            }),\r\n\r\n            depthClearValue: this._clearDepthValue,\r\n            depthLoadOp: WebGPUConstants.LoadOp.Clear,\r\n            depthStoreOp: WebGPUConstants.StoreOp.Store,\r\n            stencilClearValue: this._clearStencilValue,\r\n            stencilLoadOp: !this.isStencilEnable ? undefined : WebGPUConstants.LoadOp.Clear,\r\n            stencilStoreOp: !this.isStencilEnable ? undefined : WebGPUConstants.StoreOp.Store,\r\n        };\r\n\r\n        const frameCounter = this._internalFrameCounter++;\r\n\r\n        this._mainRenderPassWrapper.renderPassDescriptor = {\r\n            label: `[${this.frameId}|${frameCounter}] - MainRenderPass`,\r\n            colorAttachments: mainColorAttachments,\r\n            depthStencilAttachment: mainDepthAttachment,\r\n        };\r\n\r\n        this.beginFrame();\r\n        this._startMainRenderPass(true, null, true, false);\r\n        this._endCurrentRenderPass();\r\n        this._frameId--; // We don't want to count the frame as a real frame, because it was only used to initialize the depth texture\r\n        this.endFrame();\r\n    }\r\n\r\n    /**\r\n     * Shared initialization across engines types.\r\n     * @param canvas The canvas associated with this instance of the engine.\r\n     */\r\n    protected override _sharedInit(canvas: HTMLCanvasElement) {\r\n        super._sharedInit(canvas);\r\n\r\n        _CommonInit(this, canvas, this._creationOptions);\r\n    }\r\n\r\n    private _configureContext(): void {\r\n        this._context.configure({\r\n            device: this._device,\r\n            format: this._options.swapChainFormat!,\r\n            usage: WebGPUConstants.TextureUsage.RenderAttachment | WebGPUConstants.TextureUsage.CopySrc,\r\n            alphaMode: this.premultipliedAlpha ? WebGPUConstants.CanvasAlphaMode.Premultiplied : WebGPUConstants.CanvasAlphaMode.Opaque,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Resize an image and returns the image data as an uint8array\r\n     * @param image image to resize\r\n     * @param bufferWidth destination buffer width\r\n     * @param bufferHeight destination buffer height\r\n     * @returns an uint8array containing RGBA values of bufferWidth * bufferHeight size\r\n     */\r\n    public override resizeImageBitmap(image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n        return ResizeImageBitmap(this, image, bufferWidth, bufferHeight);\r\n    }\r\n\r\n    /**\r\n     * Engine abstraction for loading and creating an image bitmap from a given source string.\r\n     * @param imageSource source to load the image from.\r\n     * @param options An object that sets options for the image's extraction.\r\n     * @returns ImageBitmap\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public override async _createImageBitmapFromSource(imageSource: string, options?: ImageBitmapOptions): Promise<ImageBitmap> {\r\n        return await CreateImageBitmapFromSource(this, imageSource, options);\r\n    }\r\n\r\n    /**\r\n     * Toggle full screen mode\r\n     * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n     */\r\n    public override switchFullscreen(requestPointerLock: boolean): void {\r\n        if (this.isFullscreen) {\r\n            this.exitFullscreen();\r\n        } else {\r\n            this.enterFullscreen(requestPointerLock);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enters full screen mode\r\n     * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n     */\r\n    public override enterFullscreen(requestPointerLock: boolean): void {\r\n        if (!this.isFullscreen) {\r\n            this._pointerLockRequested = requestPointerLock;\r\n            if (this._renderingCanvas) {\r\n                RequestFullscreen(this._renderingCanvas);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Exits full screen mode\r\n     */\r\n    public override exitFullscreen(): void {\r\n        if (this.isFullscreen) {\r\n            ExitFullscreen();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enters Pointerlock mode\r\n     */\r\n    public enterPointerlock(): void {\r\n        if (this._renderingCanvas) {\r\n            RequestPointerlock(this._renderingCanvas);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Exits Pointerlock mode\r\n     */\r\n    public exitPointerlock(): void {\r\n        ExitPointerlock();\r\n    }\r\n\r\n    protected override _rebuildBuffers(): void {\r\n        super._rebuildBuffers();\r\n\r\n        for (const storageBuffer of this._storageBuffers) {\r\n            // The buffer can already be rebuilt by the call to _rebuildGeometries(), which recreates the storage buffers for the ComputeShaderParticleSystem\r\n            if ((storageBuffer.getBuffer() as WebGPUDataBuffer).engineId !== this.uniqueId) {\r\n                storageBuffer._rebuild();\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _restoreEngineAfterContextLost(initEngine: () => void) {\r\n        WebGPUCacheRenderPipelineTree.ResetCache();\r\n        WebGPUCacheBindGroups.ResetCache();\r\n\r\n        // Clear the draw wrappers and material contexts\r\n        const cleanScenes = (scenes: Scene[]) => {\r\n            for (const scene of scenes) {\r\n                for (const mesh of scene.meshes) {\r\n                    const subMeshes = mesh.subMeshes;\r\n                    if (!subMeshes) {\r\n                        continue;\r\n                    }\r\n                    for (const subMesh of subMeshes) {\r\n                        subMesh._drawWrappers = [];\r\n                    }\r\n                }\r\n\r\n                for (const material of scene.materials) {\r\n                    material._materialContext?.reset();\r\n                }\r\n            }\r\n        };\r\n\r\n        cleanScenes(this.scenes);\r\n        cleanScenes(this._virtualScenes);\r\n\r\n        // The leftOver uniform buffers are removed from the list because they will be recreated when we rebuild the effects\r\n        const uboList: UniformBuffer[] = [];\r\n        for (const uniformBuffer of this._uniformBuffers) {\r\n            if (uniformBuffer.name.indexOf(\"leftOver\") < 0) {\r\n                uboList.push(uniformBuffer);\r\n            }\r\n        }\r\n        this._uniformBuffers = uboList;\r\n\r\n        super._restoreEngineAfterContextLost(initEngine);\r\n    }\r\n\r\n    /**\r\n     * Force a specific size of the canvas\r\n     * @param width defines the new canvas' width\r\n     * @param height defines the new canvas' height\r\n     * @param forceSetSize true to force setting the sizes of the underlying canvas\r\n     * @returns true if the size was changed\r\n     */\r\n    public override setSize(width: number, height: number, forceSetSize = false): boolean {\r\n        if (!super.setSize(width, height, forceSetSize)) {\r\n            return false;\r\n        }\r\n\r\n        this._initializeMainAttachments();\r\n\r\n        if (this.snapshotRendering) {\r\n            // reset snapshot rendering so that the next frame will record a new list of bundles\r\n            this.snapshotRenderingReset();\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _shaderProcessorWGSL: Nullable<IShaderProcessor>;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _getShaderProcessor(shaderLanguage: ShaderLanguage): Nullable<IShaderProcessor> {\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return this._shaderProcessorWGSL;\r\n        }\r\n        return this._shaderProcessor;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getShaderProcessingContext(shaderLanguage: ShaderLanguage, pureMode: boolean): Nullable<_IShaderProcessingContext> {\r\n        return new WebGPUShaderProcessingContext(shaderLanguage, pureMode);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _getCurrentRenderPass(): GPURenderPassEncoder {\r\n        let depthFunction: Nullable<number> | undefined;\r\n\r\n        if (\r\n            this.compatibilityMode &&\r\n            this._currentRenderPass &&\r\n            !this._occlusionQueryActive &&\r\n            !this._snapshotRendering.play &&\r\n            this._occlusionQuery?.hasQueries &&\r\n            this._getCurrentRenderPassWrapper().renderPassDescriptor?.occlusionQuerySet !== this._occlusionQuery.querySet\r\n        ) {\r\n            depthFunction = this._depthCullingState.depthFunc;\r\n            this._snapshotRendering.handleRenderPassRestart();\r\n            this._endCurrentRenderPass();\r\n        }\r\n\r\n        if (this._currentRenderTarget && !this._currentRenderPass) {\r\n            // delayed creation of the render target pass, but we now need to create it as we are requested the render pass\r\n            this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);\r\n        } else if (!this._currentRenderPass) {\r\n            this._startMainRenderPass(false);\r\n        }\r\n\r\n        if (depthFunction !== undefined) {\r\n            this._depthCullingState.depthFunc = depthFunction;\r\n        }\r\n\r\n        return this._currentRenderPass!;\r\n    }\r\n\r\n    /** @internal */\r\n    public _getCurrentRenderPassWrapper() {\r\n        return this._currentRenderTarget ? this._rttRenderPassWrapper : this._mainRenderPassWrapper;\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                          Static Pipeline WebGPU States\r\n    //------------------------------------------------------------------------------\r\n\r\n    /** @internal */\r\n    public applyStates() {\r\n        this._stencilStateComposer.apply();\r\n        this._cacheRenderPipeline.setAlphaBlendEnabled(this._alphaState._alphaBlend, this._alphaState._numTargetEnabled);\r\n    }\r\n\r\n    /**\r\n     * Force the entire cache to be cleared\r\n     * You should not have to use this function unless your engine needs to share the WebGPU context with another engine\r\n     * @param bruteForce defines a boolean to force clearing ALL caches (including stencil, detoh and alpha states)\r\n     */\r\n    public wipeCaches(bruteForce?: boolean): void {\r\n        if (this.preventCacheWipeBetweenFrames && !bruteForce) {\r\n            return;\r\n        }\r\n\r\n        //this._currentEffect = null; // can't reset _currentEffect, else some crashes can occur (for eg in ProceduralTexture which calls bindFrameBuffer (which calls wipeCaches) after having called enableEffect and before drawing into the texture)\r\n        // _forceEnableEffect = true assumes the role of _currentEffect = null\r\n        this._forceEnableEffect = true;\r\n        this._currentIndexBuffer = null;\r\n        this._currentOverrideVertexBuffers = null;\r\n        this._cacheRenderPipeline.setBuffers(null, null, null);\r\n\r\n        if (bruteForce) {\r\n            this._stencilStateComposer.reset();\r\n\r\n            this._depthCullingState.reset();\r\n            this._depthCullingState.depthFunc = Constants.LEQUAL;\r\n\r\n            this._alphaState.reset();\r\n            this._resetAlphaMode();\r\n            this._cacheRenderPipeline.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);\r\n            this._cacheRenderPipeline.setAlphaBlendEnabled(this._alphaState._alphaBlend, this._alphaState._numTargetEnabled);\r\n\r\n            this.setColorWrite(true);\r\n        }\r\n\r\n        this._cachedVertexBuffers = null;\r\n        this._cachedIndexBuffer = null;\r\n        this._cachedEffectForVertexBuffers = null;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable color writing\r\n     * @param enable defines the state to set\r\n     */\r\n    public override setColorWrite(enable: boolean): void {\r\n        this._colorWriteLocal = enable;\r\n        this._cacheRenderPipeline.setWriteMask(enable ? 0xf : 0);\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if color writing is enabled\r\n     * @returns the current color writing state\r\n     */\r\n    public override getColorWrite(): boolean {\r\n        return this._colorWriteLocal;\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Dynamic WebGPU States\r\n    //------------------------------------------------------------------------------\r\n\r\n    // index 0 is for main render pass, 1 for RTT render pass\r\n    private _viewportsCurrent: { x: number; y: number; w: number; h: number } = { x: 0, y: 0, w: 0, h: 0 };\r\n\r\n    private _mustUpdateViewport(): boolean {\r\n        const x = this._viewportCached.x,\r\n            y = this._viewportCached.y,\r\n            w = this._viewportCached.z,\r\n            h = this._viewportCached.w;\r\n\r\n        const update = this._viewportsCurrent.x !== x || this._viewportsCurrent.y !== y || this._viewportsCurrent.w !== w || this._viewportsCurrent.h !== h;\r\n\r\n        if (update) {\r\n            this._viewportsCurrent.x = this._viewportCached.x;\r\n            this._viewportsCurrent.y = this._viewportCached.y;\r\n            this._viewportsCurrent.w = this._viewportCached.z;\r\n            this._viewportsCurrent.h = this._viewportCached.w;\r\n        }\r\n\r\n        return update;\r\n    }\r\n\r\n    private _applyViewport(bundleList: Nullable<WebGPUBundleList>): void {\r\n        const x = Math.floor(this._viewportCached.x);\r\n        const w = Math.floor(this._viewportCached.z);\r\n        const h = Math.floor(this._viewportCached.w);\r\n\r\n        let y = Math.floor(this._viewportCached.y);\r\n\r\n        if (!this._currentRenderTarget) {\r\n            y = this.getRenderHeight(true) - y - h;\r\n        }\r\n\r\n        if (bundleList) {\r\n            bundleList.addItem(new WebGPURenderItemViewport(x, y, w, h));\r\n        } else {\r\n            this._getCurrentRenderPass().setViewport(x, y, w, h, 0, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _viewport(x: number, y: number, width: number, height: number): void {\r\n        this._viewportCached.x = x;\r\n        this._viewportCached.y = y;\r\n        this._viewportCached.z = width;\r\n        this._viewportCached.w = height;\r\n    }\r\n\r\n    private _scissorsCurrent: { x: number; y: number; w: number; h: number } = { x: 0, y: 0, w: 0, h: 0 };\r\n    protected _scissorCached = { x: 0, y: 0, z: 0, w: 0 };\r\n\r\n    private _mustUpdateScissor(): boolean {\r\n        const x = this._scissorCached.x,\r\n            y = this._scissorCached.y,\r\n            w = this._scissorCached.z,\r\n            h = this._scissorCached.w;\r\n\r\n        const update = this._scissorsCurrent.x !== x || this._scissorsCurrent.y !== y || this._scissorsCurrent.w !== w || this._scissorsCurrent.h !== h;\r\n\r\n        if (update) {\r\n            this._scissorsCurrent.x = this._scissorCached.x;\r\n            this._scissorsCurrent.y = this._scissorCached.y;\r\n            this._scissorsCurrent.w = this._scissorCached.z;\r\n            this._scissorsCurrent.h = this._scissorCached.w;\r\n        }\r\n\r\n        return update;\r\n    }\r\n\r\n    private _applyScissor(bundleList: Nullable<WebGPUBundleList>): void {\r\n        const y = this._currentRenderTarget ? this._scissorCached.y : this.getRenderHeight() - this._scissorCached.w - this._scissorCached.y;\r\n\r\n        if (bundleList) {\r\n            bundleList.addItem(new WebGPURenderItemScissor(this._scissorCached.x, y, this._scissorCached.z, this._scissorCached.w));\r\n        } else {\r\n            this._getCurrentRenderPass().setScissorRect(this._scissorCached.x, y, this._scissorCached.z, this._scissorCached.w);\r\n        }\r\n    }\r\n\r\n    private _scissorIsActive() {\r\n        return this._scissorCached.x !== 0 || this._scissorCached.y !== 0 || this._scissorCached.z !== 0 || this._scissorCached.w !== 0;\r\n    }\r\n\r\n    /**\r\n     * Enable scissor test on a specific rectangle\r\n     * @param x defines left coordinate of the rectangle\r\n     * @param y defines top coordinate of the rectangle\r\n     * @param width defines width of the rectangle\r\n     * @param height defines height of the rectangle\r\n     */\r\n    public override enableScissor(x: number, y: number, width: number, height: number): void {\r\n        this._scissorCached.x = x;\r\n        this._scissorCached.y = y;\r\n        this._scissorCached.z = width;\r\n        this._scissorCached.w = height;\r\n    }\r\n\r\n    /**\r\n     * Disable previously set scissor test rectangle\r\n     */\r\n    public override disableScissor() {\r\n        this._scissorCached.x = this._scissorCached.y = this._scissorCached.z = this._scissorCached.w = 0;\r\n        this._scissorsCurrent.x = this._scissorsCurrent.y = this._scissorsCurrent.w = this._scissorsCurrent.h = 0;\r\n    }\r\n\r\n    private _stencilRefsCurrent = -1;\r\n\r\n    private _mustUpdateStencilRef(): boolean {\r\n        const update = this._stencilStateComposer.funcRef !== this._stencilRefsCurrent;\r\n        if (update) {\r\n            this._stencilRefsCurrent = this._stencilStateComposer.funcRef;\r\n        }\r\n        return update;\r\n    }\r\n\r\n    private _applyStencilRef(bundleList: Nullable<WebGPUBundleList>): void {\r\n        if (bundleList) {\r\n            bundleList.addItem(new WebGPURenderItemStencilRef(this._stencilStateComposer.funcRef ?? 0));\r\n        } else {\r\n            this._getCurrentRenderPass().setStencilReference(this._stencilStateComposer.funcRef ?? 0);\r\n        }\r\n    }\r\n\r\n    private _blendColorsCurrent: Array<Nullable<number>> = [null, null, null, null];\r\n\r\n    private _mustUpdateBlendColor(): boolean {\r\n        const colorBlend = this._alphaState._blendConstants;\r\n\r\n        const update =\r\n            colorBlend[0] !== this._blendColorsCurrent[0] ||\r\n            colorBlend[1] !== this._blendColorsCurrent[1] ||\r\n            colorBlend[2] !== this._blendColorsCurrent[2] ||\r\n            colorBlend[3] !== this._blendColorsCurrent[3];\r\n\r\n        if (update) {\r\n            this._blendColorsCurrent[0] = colorBlend[0];\r\n            this._blendColorsCurrent[1] = colorBlend[1];\r\n            this._blendColorsCurrent[2] = colorBlend[2];\r\n            this._blendColorsCurrent[3] = colorBlend[3];\r\n        }\r\n\r\n        return update;\r\n    }\r\n\r\n    private _applyBlendColor(bundleList: Nullable<WebGPUBundleList>): void {\r\n        if (bundleList) {\r\n            bundleList.addItem(new WebGPURenderItemBlendColor(this._alphaState._blendConstants.slice()));\r\n        } else {\r\n            this._getCurrentRenderPass().setBlendConstant(this._alphaState._blendConstants as GPUColor);\r\n        }\r\n    }\r\n\r\n    private _resetRenderPassStates() {\r\n        this._viewportsCurrent.x = this._viewportsCurrent.y = this._viewportsCurrent.w = this._viewportsCurrent.h = 0;\r\n        this._scissorsCurrent.x = this._scissorsCurrent.y = this._scissorsCurrent.w = this._scissorsCurrent.h = 0;\r\n        this._stencilRefsCurrent = -1;\r\n        this._blendColorsCurrent[0] = this._blendColorsCurrent[1] = this._blendColorsCurrent[2] = this._blendColorsCurrent[3] = null;\r\n    }\r\n\r\n    /**\r\n     * Clear the current render buffer or the current render target (if any is set up)\r\n     * @param color defines the color to use\r\n     * @param backBuffer defines if the back buffer must be cleared\r\n     * @param depth defines if the depth buffer must be cleared\r\n     * @param stencil defines if the stencil buffer must be cleared\r\n     * @param stencilClearValue defines the value to use to clear the stencil buffer (default is 0)\r\n     */\r\n    public clear(color: Nullable<IColor4Like>, backBuffer: boolean, depth: boolean, stencil: boolean = false, stencilClearValue = 0): void {\r\n        // Some PGs are using color3...\r\n        if (color && color.a === undefined) {\r\n            color.a = 1;\r\n        }\r\n\r\n        if (stencil) {\r\n            this._clearStencilValue = stencilClearValue;\r\n        }\r\n\r\n        const hasScissor = this._scissorIsActive();\r\n\r\n        if (backBuffer && color && hasScissor && this._currentRenderTarget) {\r\n            const textures = this._currentRenderTarget.textures;\r\n            const attachments = this._mrtAttachments;\r\n            if (textures) {\r\n                for (let index = 0; index < textures.length; index++) {\r\n                    if ((!attachments || attachments[index] !== 0) && IsIntegerTextureFormat(textures[index].format)) {\r\n                        throw new Error(\"WebGPUEngine.clear: scissored clears of integer color attachments are not supported\");\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // We need to recreate the render pass so that the new parameters for clear color / depth / stencil are taken into account\r\n        if (this._currentRenderTarget) {\r\n            if (hasScissor) {\r\n                if (!this._currentRenderPass) {\r\n                    this._startRenderTargetRenderPass(this._currentRenderTarget, false, backBuffer ? color : null, depth, stencil);\r\n                }\r\n                this._applyScissor(!this.compatibilityMode ? this._bundleList : null);\r\n                this._clearFullQuad(backBuffer ? color : null, depth, stencil);\r\n            } else {\r\n                if (this._currentRenderPass) {\r\n                    this._endCurrentRenderPass();\r\n                }\r\n                this._startRenderTargetRenderPass(this._currentRenderTarget, true, backBuffer ? color : null, depth, stencil);\r\n            }\r\n        } else {\r\n            if (!this._currentRenderPass || !hasScissor) {\r\n                this._startMainRenderPass(!hasScissor, backBuffer ? color : null, depth, stencil);\r\n            }\r\n            if (hasScissor) {\r\n                this._applyScissor(!this.compatibilityMode ? this._bundleList : null);\r\n                this._clearFullQuad(backBuffer ? color : null, depth, stencil);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _clearFullQuad(clearColor?: Nullable<IColor4Like>, clearDepth?: boolean, clearStencil?: boolean): void {\r\n        const renderPass = !this.compatibilityMode ? null : this._getCurrentRenderPass();\r\n\r\n        this._clearQuad.setColorFormat(this._colorFormat);\r\n        this._clearQuad.setDepthStencilFormat(this._depthTextureFormat);\r\n        this._clearQuad.setMRTAttachments(\r\n            this._cacheRenderPipeline.mrtAttachments ?? [],\r\n            this._cacheRenderPipeline.mrtTextureArray ?? [],\r\n            this._cacheRenderPipeline.mrtTextureCount\r\n        );\r\n\r\n        if (!this.compatibilityMode) {\r\n            this._bundleList.addItem(new WebGPURenderItemStencilRef(this._clearStencilValue));\r\n        } else {\r\n            renderPass!.setStencilReference(this._clearStencilValue);\r\n        }\r\n\r\n        const bundle = this._clearQuad.clear(renderPass, clearColor, clearDepth, clearStencil, this.currentSampleCount);\r\n\r\n        if (!this.compatibilityMode) {\r\n            this._bundleList.addBundle(bundle!);\r\n            this._applyStencilRef(this._bundleList);\r\n            this._reportDrawCall();\r\n        } else {\r\n            this._applyStencilRef(null);\r\n        }\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Vertex/Index/Storage Buffers\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Creates a vertex buffer\r\n     * @param data the data or the size for the vertex buffer\r\n     * @param _updatable whether the buffer should be created as updatable\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     * @returns the new buffer\r\n     */\r\n    public createVertexBuffer(data: DataArray | number, _updatable?: boolean, label?: string): DataBuffer {\r\n        let view: ArrayBufferView | number;\r\n\r\n        if (data instanceof Array) {\r\n            view = new Float32Array(data);\r\n        } else if (ArrayBuffer.isView(data)) {\r\n            view = data;\r\n        } else {\r\n            view = new Uint8Array(data);\r\n        }\r\n\r\n        const dataBuffer = this._bufferManager.createBuffer(\r\n            view,\r\n            WebGPUConstants.BufferUsage.Vertex | WebGPUConstants.BufferUsage.CopyDst | WebGPUConstants.BufferUsage.Storage,\r\n            label\r\n        );\r\n        return dataBuffer;\r\n    }\r\n\r\n    /**\r\n     * Creates a vertex buffer\r\n     * @param data the data for the dynamic vertex buffer\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     * @returns the new buffer\r\n     */\r\n    public createDynamicVertexBuffer(data: DataArray, label?: string): DataBuffer {\r\n        return this.createVertexBuffer(data, undefined, label);\r\n    }\r\n\r\n    /**\r\n     * Creates a new index buffer\r\n     * @param indices defines the content of the index buffer\r\n     * @param _updatable defines if the index buffer must be updatable\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     * @returns a new buffer\r\n     */\r\n    public createIndexBuffer(indices: IndicesArray, _updatable?: boolean, label?: string): DataBuffer {\r\n        let is32Bits = true;\r\n        let view: ArrayBufferView | undefined;\r\n\r\n        if (indices instanceof Uint32Array || indices instanceof Int32Array) {\r\n            view = indices;\r\n        } else if (indices instanceof Uint16Array) {\r\n            view = indices;\r\n            is32Bits = false;\r\n        } else {\r\n            for (let index = 0; index < indices.length; index++) {\r\n                if (indices[index] > 65535) {\r\n                    view = new Uint32Array(indices);\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (!view) {\r\n                view = new Uint16Array(indices);\r\n                is32Bits = false;\r\n            }\r\n        }\r\n\r\n        const dataBuffer = this._bufferManager.createBuffer(\r\n            view,\r\n            WebGPUConstants.BufferUsage.Index | WebGPUConstants.BufferUsage.CopyDst | WebGPUConstants.BufferUsage.Storage,\r\n            label\r\n        );\r\n        dataBuffer.is32Bits = is32Bits;\r\n        return dataBuffer;\r\n    }\r\n\r\n    /**\r\n     * Update a dynamic index buffer\r\n     * @param indexBuffer defines the target index buffer\r\n     * @param indices defines the data to update\r\n     * @param offset defines the offset in the target index buffer where update should start\r\n     */\r\n    public override updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset: number = 0): void {\r\n        const gpuBuffer = indexBuffer as WebGPUDataBuffer;\r\n\r\n        let view: ArrayBufferView;\r\n        if (indexBuffer.is32Bits) {\r\n            view = indices instanceof Uint32Array ? indices : new Uint32Array(indices);\r\n        } else {\r\n            view = indices instanceof Uint16Array ? indices : new Uint16Array(indices);\r\n        }\r\n\r\n        this._bufferManager.setSubData(gpuBuffer, offset, view);\r\n    }\r\n\r\n    /**\r\n     * Updates a dynamic vertex buffer.\r\n     * @param vertexBuffer the vertex buffer to update\r\n     * @param data the data used to update the vertex buffer\r\n     * @param byteOffset the byte offset of the data\r\n     * @param byteLength the byte length of the data\r\n     */\r\n    public override updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void {\r\n        const dataBuffer = vertexBuffer as WebGPUDataBuffer;\r\n        if (byteOffset === undefined) {\r\n            byteOffset = 0;\r\n        }\r\n\r\n        let view: ArrayBufferView;\r\n        if (byteLength === undefined) {\r\n            if (data instanceof Array) {\r\n                view = new Float32Array(data);\r\n            } else if (ArrayBuffer.isView(data)) {\r\n                view = data;\r\n            } else {\r\n                view = new Uint8Array(data);\r\n            }\r\n            byteLength = view.byteLength;\r\n        } else {\r\n            if (data instanceof Array) {\r\n                view = new Float32Array(data);\r\n            } else if (ArrayBuffer.isView(data)) {\r\n                view = data;\r\n            } else {\r\n                view = new Uint8Array(data);\r\n            }\r\n        }\r\n\r\n        this._bufferManager.setSubData(dataBuffer, byteOffset, view, 0, byteLength);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _createBuffer(data: DataArray | number, creationFlags: number, label?: string): DataBuffer {\r\n        let view: ArrayBufferView | number;\r\n\r\n        if (data instanceof Array) {\r\n            view = new Float32Array(data);\r\n        } else if (ArrayBuffer.isView(data)) {\r\n            view = data;\r\n        } else {\r\n            view = new Uint8Array(data);\r\n        }\r\n\r\n        let flags = 0;\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_READ) {\r\n            flags |= WebGPUConstants.BufferUsage.CopySrc;\r\n        }\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_WRITE) {\r\n            flags |= WebGPUConstants.BufferUsage.CopyDst;\r\n        }\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_UNIFORM) {\r\n            flags |= WebGPUConstants.BufferUsage.Uniform;\r\n        }\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_VERTEX) {\r\n            flags |= WebGPUConstants.BufferUsage.Vertex;\r\n        }\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_INDEX) {\r\n            flags |= WebGPUConstants.BufferUsage.Index;\r\n        }\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_STORAGE) {\r\n            flags |= WebGPUConstants.BufferUsage.Storage;\r\n        }\r\n        if (creationFlags & Constants.BUFFER_CREATIONFLAG_INDIRECT) {\r\n            flags |= WebGPUConstants.BufferUsage.Indirect;\r\n        }\r\n\r\n        return this._bufferManager.createBuffer(view, flags, label);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public bindBuffersDirectly(): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"Not implemented on WebGPU\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public updateAndBindInstancesBuffer(): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"Not implemented on WebGPU\";\r\n    }\r\n\r\n    /**\r\n     * Unbind all instance attributes\r\n     */\r\n    public unbindInstanceAttributes(): void {\r\n        // Does nothing\r\n    }\r\n\r\n    /**\r\n     * Bind a list of vertex buffers with the engine\r\n     * @param vertexBuffers defines the list of vertex buffers to bind\r\n     * @param indexBuffer defines the index buffer to bind\r\n     * @param _effect defines the effect associated with the vertex buffers\r\n     * @param overrideVertexBuffers defines optional list of avertex buffers that overrides the entries in vertexBuffers\r\n     */\r\n    public bindBuffers(\r\n        vertexBuffers: { [key: string]: Nullable<VertexBuffer> },\r\n        indexBuffer: Nullable<DataBuffer>,\r\n        _effect: Effect,\r\n        overrideVertexBuffers?: { [kind: string]: Nullable<VertexBuffer> }\r\n    ): void {\r\n        this._currentVertexBuffers = vertexBuffers;\r\n        this._currentIndexBuffer = indexBuffer;\r\n        this._currentOverrideVertexBuffers = overrideVertexBuffers ?? null;\r\n        this._cacheRenderPipeline.setBuffers(this._currentVertexBuffers, this._currentIndexBuffer, this._currentOverrideVertexBuffers);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseBuffer(buffer: DataBuffer): boolean {\r\n        return this._bufferManager.releaseBuffer(buffer);\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Uniform Buffers\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Create an uniform buffer\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     * @param elements defines the content of the uniform buffer\r\n     * @param label defines a name for the buffer (for debugging purpose)\r\n     * @returns the webGL uniform buffer\r\n     */\r\n    public createUniformBuffer(elements: FloatArray, label?: string): DataBuffer {\r\n        let view: Float32Array;\r\n        if (elements instanceof Array) {\r\n            view = new Float32Array(elements);\r\n        } else {\r\n            view = elements;\r\n        }\r\n\r\n        const dataBuffer = this._bufferManager.createBuffer(view, WebGPUConstants.BufferUsage.Uniform | WebGPUConstants.BufferUsage.CopyDst, label);\r\n        return dataBuffer;\r\n    }\r\n\r\n    /**\r\n     * Create a dynamic uniform buffer (no different from a non dynamic uniform buffer in WebGPU)\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     * @param elements defines the content of the uniform buffer\r\n     * @param label defines a name for the buffer (for debugging purpose)\r\n     * @returns the webGL uniform buffer\r\n     */\r\n    public createDynamicUniformBuffer(elements: FloatArray, label?: string): DataBuffer {\r\n        return this.createUniformBuffer(elements, label);\r\n    }\r\n\r\n    /**\r\n     * Update an existing uniform buffer\r\n     * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n     * @param uniformBuffer defines the target uniform buffer\r\n     * @param elements defines the content to update\r\n     * @param offset defines the offset in the uniform buffer where update should start\r\n     * @param count defines the size of the data to update\r\n     */\r\n    public updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void {\r\n        if (offset === undefined) {\r\n            offset = 0;\r\n        }\r\n\r\n        const dataBuffer = uniformBuffer as WebGPUDataBuffer;\r\n        let view: Float32Array;\r\n        if (count === undefined) {\r\n            if (elements instanceof Float32Array) {\r\n                view = elements;\r\n            } else {\r\n                view = new Float32Array(elements);\r\n            }\r\n            count = view.byteLength;\r\n        } else {\r\n            if (elements instanceof Float32Array) {\r\n                view = elements;\r\n            } else {\r\n                view = new Float32Array(elements);\r\n            }\r\n        }\r\n\r\n        this._bufferManager.setSubData(dataBuffer, offset, view, 0, count);\r\n    }\r\n\r\n    /**\r\n     * Bind a buffer to the current draw context\r\n     * @param buffer defines the buffer to bind\r\n     * @param _location not used in WebGPU\r\n     * @param name Name of the uniform variable to bind\r\n     */\r\n    public bindUniformBufferBase(buffer: DataBuffer, _location: number, name: string): void {\r\n        this._currentDrawContext.setBuffer(name, buffer as WebGPUDataBuffer);\r\n    }\r\n\r\n    /**\r\n     * Unused in WebGPU\r\n     */\r\n    public bindUniformBlock(): void {}\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Effects\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Create a new effect (used to store vertex/fragment shaders)\r\n     * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)\r\n     * @param attributesNamesOrOptions defines either a list of attribute names or an IEffectCreationOptions object\r\n     * @param uniformsNamesOrEngine defines either a list of uniform names or the engine to use\r\n     * @param samplers defines an array of string used to represent textures\r\n     * @param defines defines the string containing the defines to use to compile the shaders\r\n     * @param fallbacks defines the list of potential fallbacks to use if shader compilation fails\r\n     * @param onCompiled defines a function to call when the effect creation is successful\r\n     * @param onError defines a function to call when the effect creation has failed\r\n     * @param indexParameters defines an object containing the index values to use to compile shaders (like the maximum number of simultaneous lights)\r\n     * @param shaderLanguage the language the shader is written in (default: GLSL)\r\n     * @param extraInitializationsAsync additional async code to run before preparing the effect\r\n     * @returns the new Effect\r\n     */\r\n    public createEffect(\r\n        baseName: string | (IShaderPath & { vertexToken?: string; fragmentToken?: string }),\r\n        attributesNamesOrOptions: string[] | IEffectCreationOptions,\r\n        uniformsNamesOrEngine: string[] | AbstractEngine,\r\n        samplers?: string[],\r\n        defines?: string,\r\n        fallbacks?: EffectFallbacks,\r\n        onCompiled?: Nullable<(effect: Effect) => void>,\r\n        onError?: Nullable<(effect: Effect, errors: string) => void>,\r\n        indexParameters?: any,\r\n        shaderLanguage = ShaderLanguage.GLSL,\r\n        extraInitializationsAsync?: () => Promise<void>\r\n    ): Effect {\r\n        const vertex = typeof baseName === \"string\" ? baseName : baseName.vertexToken || baseName.vertexSource || baseName.vertexElement || baseName.vertex;\r\n        const fragment = typeof baseName === \"string\" ? baseName : baseName.fragmentToken || baseName.fragmentSource || baseName.fragmentElement || baseName.fragment;\r\n        const globalDefines = this._getGlobalDefines()!;\r\n\r\n        const isOptions = (attributesNamesOrOptions as IEffectCreationOptions).attributes !== undefined;\r\n\r\n        let fullDefines = defines ?? (<IEffectCreationOptions>attributesNamesOrOptions).defines ?? \"\";\r\n\r\n        if (globalDefines) {\r\n            fullDefines += \"\\n\" + globalDefines;\r\n        }\r\n\r\n        const name = vertex + \"+\" + fragment + \"@\" + fullDefines;\r\n        if (this._compiledEffects[name]) {\r\n            const compiledEffect = this._compiledEffects[name];\r\n            if (onCompiled && compiledEffect.isReady()) {\r\n                onCompiled(compiledEffect);\r\n            }\r\n            compiledEffect._refCount++;\r\n            return compiledEffect;\r\n        }\r\n        const effect = new Effect(\r\n            baseName,\r\n            attributesNamesOrOptions,\r\n            isOptions ? this : uniformsNamesOrEngine,\r\n            samplers,\r\n            this,\r\n            defines,\r\n            fallbacks,\r\n            onCompiled,\r\n            onError,\r\n            indexParameters,\r\n            name,\r\n            (<IEffectCreationOptions>attributesNamesOrOptions).shaderLanguage ?? shaderLanguage,\r\n            (<IEffectCreationOptions>attributesNamesOrOptions).extraInitializationsAsync ?? extraInitializationsAsync\r\n        );\r\n        this._compiledEffects[name] = effect;\r\n\r\n        return effect;\r\n    }\r\n\r\n    private _compileRawShaderToSpirV(source: string, type: string): Uint32Array {\r\n        return this._glslang.compileGLSL(source, type);\r\n    }\r\n\r\n    private _compileShaderToSpirV(source: string, type: string, defines: Nullable<string>, shaderVersion: string): Uint32Array {\r\n        return this._compileRawShaderToSpirV(shaderVersion + (defines ? defines + \"\\n\" : \"\") + source, type);\r\n    }\r\n\r\n    private _getWGSLShader(source: string, type: string, defines: Nullable<string>): string {\r\n        if (defines) {\r\n            defines = \"//\" + defines.split(\"\\n\").join(\"\\n//\") + \"\\n\";\r\n        } else {\r\n            defines = \"\";\r\n        }\r\n        return defines + source;\r\n    }\r\n\r\n    private _createPipelineStageDescriptor(\r\n        vertexShader: Uint32Array | string,\r\n        fragmentShader: Uint32Array | string,\r\n        shaderLanguage: ShaderLanguage,\r\n        disableUniformityAnalysisInVertex: boolean,\r\n        disableUniformityAnalysisInFragment: boolean\r\n    ): IWebGPURenderPipelineStageDescriptor {\r\n        if (this._tintWASM && shaderLanguage === ShaderLanguage.GLSL) {\r\n            vertexShader = this._tintWASM.convertSpirV2WGSL(vertexShader as Uint32Array, disableUniformityAnalysisInVertex);\r\n            fragmentShader = this._tintWASM.convertSpirV2WGSL(fragmentShader as Uint32Array, disableUniformityAnalysisInFragment);\r\n        }\r\n\r\n        return {\r\n            vertexStage: {\r\n                module: this._device.createShaderModule({\r\n                    label: \"vertex\",\r\n                    code: vertexShader as string,\r\n                }),\r\n                entryPoint: \"main\",\r\n            },\r\n            fragmentStage: {\r\n                module: this._device.createShaderModule({\r\n                    label: \"fragment\",\r\n                    code: fragmentShader as string,\r\n                }),\r\n                entryPoint: \"main\",\r\n            },\r\n        };\r\n    }\r\n\r\n    private _compileRawPipelineStageDescriptor(vertexCode: string, fragmentCode: string, shaderLanguage: ShaderLanguage): IWebGPURenderPipelineStageDescriptor {\r\n        const disableUniformityAnalysisInVertex = vertexCode.indexOf(Constants.DISABLEUA) >= 0;\r\n        const disableUniformityAnalysisInFragment = fragmentCode.indexOf(Constants.DISABLEUA) >= 0;\r\n\r\n        const vertexShader = shaderLanguage === ShaderLanguage.GLSL ? this._compileRawShaderToSpirV(vertexCode, \"vertex\") : vertexCode;\r\n        const fragmentShader = shaderLanguage === ShaderLanguage.GLSL ? this._compileRawShaderToSpirV(fragmentCode, \"fragment\") : fragmentCode;\r\n\r\n        return this._createPipelineStageDescriptor(vertexShader, fragmentShader, shaderLanguage, disableUniformityAnalysisInVertex, disableUniformityAnalysisInFragment);\r\n    }\r\n\r\n    private _compilePipelineStageDescriptor(\r\n        vertexCode: string,\r\n        fragmentCode: string,\r\n        defines: Nullable<string>,\r\n        shaderLanguage: ShaderLanguage\r\n    ): IWebGPURenderPipelineStageDescriptor {\r\n        this.onBeforeShaderCompilationObservable.notifyObservers(this);\r\n\r\n        const disableUniformityAnalysisInVertex = vertexCode.indexOf(Constants.DISABLEUA) >= 0;\r\n        const disableUniformityAnalysisInFragment = fragmentCode.indexOf(Constants.DISABLEUA) >= 0;\r\n\r\n        const shaderVersion = \"#version 450\\n\";\r\n        const vertexShader =\r\n            shaderLanguage === ShaderLanguage.GLSL ? this._compileShaderToSpirV(vertexCode, \"vertex\", defines, shaderVersion) : this._getWGSLShader(vertexCode, \"vertex\", defines);\r\n        const fragmentShader =\r\n            shaderLanguage === ShaderLanguage.GLSL\r\n                ? this._compileShaderToSpirV(fragmentCode, \"fragment\", defines, shaderVersion)\r\n                : this._getWGSLShader(fragmentCode, \"fragment\", defines);\r\n\r\n        const program = this._createPipelineStageDescriptor(vertexShader, fragmentShader, shaderLanguage, disableUniformityAnalysisInVertex, disableUniformityAnalysisInFragment);\r\n\r\n        this.onAfterShaderCompilationObservable.notifyObservers(this);\r\n\r\n        return program;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public createRawShaderProgram(): WebGLProgram {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"Not available on WebGPU\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public createShaderProgram(): WebGLProgram {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"Not available on WebGPU\";\r\n    }\r\n\r\n    /**\r\n     * Inline functions in shader code that are marked to be inlined\r\n     * @param code code to inline\r\n     * @returns inlined code\r\n     */\r\n    public inlineShaderCode(code: string): string {\r\n        const sci = new ShaderCodeInliner(code);\r\n        sci.debug = false;\r\n        sci.processCode();\r\n        return sci.code;\r\n    }\r\n\r\n    /**\r\n     * Creates a new pipeline context\r\n     * @param shaderProcessingContext defines the shader processing context used during the processing if available\r\n     * @returns the new pipeline\r\n     */\r\n    public createPipelineContext(shaderProcessingContext: Nullable<_IShaderProcessingContext>): IPipelineContext {\r\n        return new WebGPUPipelineContext(shaderProcessingContext! as WebGPUShaderProcessingContext, this);\r\n    }\r\n\r\n    /**\r\n     * Creates a new material context\r\n     * @returns the new context\r\n     */\r\n    public createMaterialContext(): WebGPUMaterialContext | undefined {\r\n        return new WebGPUMaterialContext();\r\n    }\r\n\r\n    /**\r\n     * Creates a new draw context\r\n     * @returns the new context\r\n     */\r\n    public createDrawContext(): WebGPUDrawContext | undefined {\r\n        return new WebGPUDrawContext(this._bufferManager, this._dummyIndexBuffer);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n    public async _preparePipelineContextAsync(\r\n        pipelineContext: IPipelineContext,\r\n        vertexSourceCode: string,\r\n        fragmentSourceCode: string,\r\n        createAsRaw: boolean,\r\n        rawVertexSourceCode: string,\r\n        rawFragmentSourceCode: string,\r\n        _rebuildRebind: any,\r\n        defines: Nullable<string>,\r\n        _transformFeedbackVaryings: Nullable<string[]>,\r\n        _key: string,\r\n        onReady: () => void\r\n    ) {\r\n        const webGpuContext = pipelineContext as WebGPUPipelineContext;\r\n        const shaderLanguage = webGpuContext.shaderProcessingContext.shaderLanguage;\r\n\r\n        if (shaderLanguage === ShaderLanguage.GLSL && !this._glslangAndTintAreFullyLoaded) {\r\n            await this.prepareGlslangAndTintAsync();\r\n        }\r\n\r\n        if (this.dbgShowShaderCode) {\r\n            Logger.Log([\"defines\", defines]);\r\n            Logger.Log(vertexSourceCode);\r\n            Logger.Log(fragmentSourceCode);\r\n            Logger.Log(\"***********************************************\");\r\n        }\r\n\r\n        webGpuContext.sources = {\r\n            fragment: fragmentSourceCode,\r\n            vertex: vertexSourceCode,\r\n            rawVertex: rawVertexSourceCode,\r\n            rawFragment: rawFragmentSourceCode,\r\n        };\r\n\r\n        if (createAsRaw) {\r\n            webGpuContext.stages = this._compileRawPipelineStageDescriptor(vertexSourceCode, fragmentSourceCode, shaderLanguage);\r\n        } else {\r\n            webGpuContext.stages = this._compilePipelineStageDescriptor(vertexSourceCode, fragmentSourceCode, defines, shaderLanguage);\r\n        }\r\n\r\n        onReady();\r\n    }\r\n\r\n    /**\r\n     * Gets the list of active attributes for a given WebGPU program\r\n     * @param pipelineContext defines the pipeline context to use\r\n     * @param attributesNames defines the list of attribute names to get\r\n     * @returns an array of indices indicating the offset of each attribute\r\n     */\r\n    public getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[] {\r\n        const results = new Array(attributesNames.length);\r\n        const gpuPipelineContext = pipelineContext as WebGPUPipelineContext;\r\n\r\n        for (let i = 0; i < attributesNames.length; i++) {\r\n            const attributeName = attributesNames[i];\r\n            const attributeLocation = gpuPipelineContext.shaderProcessingContext.availableAttributes[attributeName];\r\n            if (attributeLocation === undefined) {\r\n                continue;\r\n            }\r\n\r\n            results[i] = attributeLocation;\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Activates an effect, making it the current one (ie. the one used for rendering)\r\n     * @param effect defines the effect to activate\r\n     */\r\n    public enableEffect(effect: Nullable<Effect | DrawWrapper>): void {\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        if (!IsWrapper(effect)) {\r\n            this._currentEffect = effect;\r\n            this._currentMaterialContext = this._defaultMaterialContext;\r\n            this._currentDrawContext = this._defaultDrawContext;\r\n            this._counters.numEnableEffects++;\r\n            if (this.dbgLogIfNotDrawWrapper) {\r\n                Logger.Warn(\r\n                    `enableEffect has been called with an Effect and not a Wrapper! effect.uniqueId=${effect.uniqueId}, effect.name=${effect.name}, effect.name.vertex=${typeof effect.name === \"string\" ? \"\" : effect.name.vertex}, effect.name.fragment=${typeof effect.name === \"string\" ? \"\" : effect.name.fragment}`,\r\n                    10\r\n                );\r\n            }\r\n        } else if (\r\n            !effect.effect ||\r\n            (effect.effect === this._currentEffect &&\r\n                effect.materialContext === this._currentMaterialContext &&\r\n                effect.drawContext === this._currentDrawContext &&\r\n                !this._forceEnableEffect)\r\n        ) {\r\n            if (!effect.effect && this.dbgShowEmptyEnableEffectCalls) {\r\n                Logger.Log([\"drawWrapper=\", effect]);\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"Invalid call to enableEffect: the effect property is empty!\";\r\n            }\r\n            return;\r\n        } else {\r\n            this._currentEffect = effect.effect;\r\n            this._currentMaterialContext = effect.materialContext as WebGPUMaterialContext;\r\n            this._currentDrawContext = effect.drawContext as WebGPUDrawContext;\r\n            this._counters.numEnableDrawWrapper++;\r\n            if (!this._currentMaterialContext) {\r\n                Logger.Log([\"drawWrapper=\", effect]);\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw `Invalid call to enableEffect: the materialContext property is empty!`;\r\n            }\r\n        }\r\n\r\n        this._stencilStateComposer.stencilMaterial = undefined;\r\n\r\n        this._forceEnableEffect = false;\r\n\r\n        if (this._currentEffect.onBind) {\r\n            this._currentEffect.onBind(this._currentEffect);\r\n        }\r\n        if (this._currentEffect._onBindObservable) {\r\n            this._currentEffect._onBindObservable.notifyObservers(this._currentEffect);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseEffect(effect: Effect): void {\r\n        if (this._compiledEffects[effect._key]) {\r\n            delete this._compiledEffects[effect._key];\r\n\r\n            this._deletePipelineContext(effect.getPipelineContext() as WebGPUPipelineContext);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Force the engine to release all cached effects. This means that next effect compilation will have to be done completely even if a similar effect was already compiled\r\n     */\r\n    public releaseEffects() {\r\n        for (const name in this._compiledEffects) {\r\n            const webGPUPipelineContext = this._compiledEffects[name].getPipelineContext() as WebGPUPipelineContext;\r\n            this._deletePipelineContext(webGPUPipelineContext);\r\n        }\r\n\r\n        this._compiledEffects = {};\r\n\r\n        this.onReleaseEffectsObservable.notifyObservers(this);\r\n    }\r\n\r\n    public _deletePipelineContext(pipelineContext: IPipelineContext): void {\r\n        const webgpuPipelineContext = pipelineContext as WebGPUPipelineContext;\r\n        if (webgpuPipelineContext) {\r\n            resetCachedPipeline(webgpuPipelineContext);\r\n        }\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Textures\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Gets a boolean indicating that only power of 2 textures are supported\r\n     * Please note that you can still use non power of 2 textures but in this case the engine will forcefully convert them\r\n     */\r\n    public get needPOTTextures(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _createHardwareTexture(): IHardwareTextureWrapper {\r\n        return new WebGPUHardwareTexture(this);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _releaseTexture(texture: InternalTexture): void {\r\n        const index = this._internalTexturesCache.indexOf(texture);\r\n        if (index !== -1) {\r\n            this._internalTexturesCache.splice(index, 1);\r\n        }\r\n\r\n        this._textureHelper.releaseTexture(texture);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getRGBABufferInternalSizedFormat(): number {\r\n        return Constants.TEXTUREFORMAT_RGBA;\r\n    }\r\n\r\n    /**\r\n     * Update the comparison function of a texture\r\n     * @param texture defines the texture to update\r\n     * @param comparisonFunction defines the comparison function to set\r\n     */\r\n    public updateTextureComparisonFunction(texture: InternalTexture, comparisonFunction: number): void {\r\n        texture._comparisonFunction = comparisonFunction;\r\n    }\r\n\r\n    /**\r\n     * Creates an internal texture without binding it to a framebuffer\r\n     * @internal\r\n     * @param size defines the size of the texture\r\n     * @param options defines the options used to create the texture\r\n     * @param delayGPUTextureCreation true to delay the texture creation the first time it is really needed. false to create it right away\r\n     * @param source source type of the texture\r\n     * @returns a new internal texture\r\n     */\r\n    public _createInternalTexture(\r\n        size: TextureSize,\r\n        options: boolean | InternalTextureCreationOptions,\r\n        delayGPUTextureCreation = true,\r\n        source = InternalTextureSource.Unknown\r\n    ): InternalTexture {\r\n        const fullOptions: InternalTextureCreationOptions = {};\r\n\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            fullOptions.generateMipMaps = options.generateMipMaps;\r\n            fullOptions.createMipMaps = options.createMipMaps;\r\n            fullOptions.type = options.type === undefined ? Constants.TEXTURETYPE_UNSIGNED_BYTE : options.type;\r\n            fullOptions.samplingMode = options.samplingMode === undefined ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;\r\n            fullOptions.format = options.format === undefined ? Constants.TEXTUREFORMAT_RGBA : options.format;\r\n            fullOptions.samples = options.samples ?? 1;\r\n            fullOptions.creationFlags = options.creationFlags ?? 0;\r\n            fullOptions.useSRGBBuffer = options.useSRGBBuffer ?? false;\r\n            fullOptions.label = options.label;\r\n            fullOptions.isCube = !!options.isCube;\r\n        } else {\r\n            fullOptions.generateMipMaps = options;\r\n            fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            fullOptions.samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n            fullOptions.format = Constants.TEXTUREFORMAT_RGBA;\r\n            fullOptions.samples = 1;\r\n            fullOptions.creationFlags = 0;\r\n            fullOptions.useSRGBBuffer = false;\r\n            fullOptions.isCube = false;\r\n        }\r\n\r\n        if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (fullOptions.type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n            fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            Logger.Warn(\"Float textures are not supported. Type forced to TEXTURETYPE_UNSIGNED_BYTE\");\r\n        }\r\n\r\n        const texture = new InternalTexture(this, source);\r\n\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>size).depth ?? 0;\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>size).layers ?? 0;\r\n\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.depth = depth || layers;\r\n        texture.isReady = true;\r\n        texture.samples = fullOptions.samples;\r\n        texture.generateMipMaps = !!fullOptions.generateMipMaps;\r\n        texture.samplingMode = fullOptions.samplingMode;\r\n        texture.type = fullOptions.type;\r\n        texture.format = fullOptions.format;\r\n        texture.is2DArray = layers > 0;\r\n        texture.is3D = depth > 0;\r\n        texture.isCube = fullOptions.isCube;\r\n        texture._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        texture._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        texture._useSRGBBuffer = fullOptions.useSRGBBuffer;\r\n        texture.label = fullOptions.label;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        if (!delayGPUTextureCreation) {\r\n            const createMipMapsOnly = !fullOptions.generateMipMaps && fullOptions.createMipMaps;\r\n\r\n            if (createMipMapsOnly) {\r\n                // So that the call to createGPUTextureForInternalTexture creates the mipmaps\r\n                texture.generateMipMaps = true;\r\n            }\r\n\r\n            this._textureHelper.createGPUTextureForInternalTexture(texture, width, height, texture.depth || 1, fullOptions.creationFlags);\r\n\r\n            if (createMipMapsOnly) {\r\n                // So that we don't automatically generate mipmaps when the render target is unbound\r\n                texture.generateMipMaps = false;\r\n            }\r\n        }\r\n\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Usually called from Texture.ts.\r\n     * Passed information to create a hardware texture\r\n     * @param url defines a value which contains one of the following:\r\n     * * A conventional http URL, e.g. 'http://...' or 'file://...'\r\n     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'\r\n     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'\r\n     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file\r\n     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)\r\n     * @param scene needed for loading to the correct scene\r\n     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)\r\n     * @param onLoad optional callback to be called upon successful completion\r\n     * @param onError optional callback to be called upon failure\r\n     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob\r\n     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities\r\n     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @param mimeType defines an optional mime type\r\n     * @param loaderOptions options to be passed to the loader\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n     * @returns a InternalTexture for assignment back into BABYLON.Texture\r\n     */\r\n    public createTexture(\r\n        url: Nullable<string>,\r\n        noMipmap: boolean,\r\n        invertY: boolean,\r\n        scene: Nullable<ISceneLike>,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        onLoad: Nullable<(texture: InternalTexture) => void> = null,\r\n        onError: Nullable<(message: string, exception: any) => void> = null,\r\n        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        format: Nullable<number> = null,\r\n        forcedExtension: Nullable<string> = null,\r\n        mimeType?: string,\r\n        loaderOptions?: any,\r\n        creationFlags?: number,\r\n        useSRGBBuffer?: boolean\r\n    ): InternalTexture {\r\n        return this._createTextureBase(\r\n            url,\r\n            noMipmap,\r\n            invertY,\r\n            scene,\r\n            samplingMode,\r\n            onLoad,\r\n            onError,\r\n            (\r\n                texture: InternalTexture,\r\n                extension: string,\r\n                scene: Nullable<ISceneLike>,\r\n                img: HTMLImageElement | ImageBitmap | { width: number; height: number },\r\n                invertY: boolean,\r\n                noMipmap: boolean,\r\n                isCompressed: boolean,\r\n                processFunction: (\r\n                    width: number,\r\n                    height: number,\r\n                    img: HTMLImageElement | ImageBitmap | { width: number; height: number },\r\n                    extension: string,\r\n                    texture: InternalTexture,\r\n                    continuationCallback: () => void\r\n                ) => boolean\r\n            ) => {\r\n                const imageBitmap = img as ImageBitmap | { width: number; height: number }; // we will never get an HTMLImageElement in WebGPU\r\n\r\n                texture.baseWidth = imageBitmap.width;\r\n                texture.baseHeight = imageBitmap.height;\r\n                texture.width = imageBitmap.width;\r\n                texture.height = imageBitmap.height;\r\n                texture.format = texture.format !== -1 ? texture.format : (format ?? Constants.TEXTUREFORMAT_RGBA);\r\n                texture.type = texture.type !== -1 ? texture.type : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                texture._creationFlags = creationFlags ?? 0;\r\n\r\n                processFunction(texture.width, texture.height, imageBitmap, extension, texture, () => {});\r\n\r\n                if (!texture._hardwareTexture?.underlyingResource) {\r\n                    // the texture could have been created before reaching this point so don't recreate it if already existing\r\n                    const gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture, imageBitmap.width, imageBitmap.height, undefined, creationFlags);\r\n\r\n                    if (WebGPUTextureHelper.IsImageBitmap(imageBitmap)) {\r\n                        this._textureHelper.updateTexture(\r\n                            imageBitmap,\r\n                            texture,\r\n                            imageBitmap.width,\r\n                            imageBitmap.height,\r\n                            texture.depth,\r\n                            gpuTextureWrapper.format,\r\n                            0,\r\n                            0,\r\n                            invertY,\r\n                            false,\r\n                            0,\r\n                            0\r\n                        );\r\n                        if (!noMipmap && !isCompressed) {\r\n                            this._generateMipmaps(texture, this._uploadEncoder);\r\n                        }\r\n                    }\r\n                } else if (!noMipmap && !isCompressed) {\r\n                    this._generateMipmaps(texture, this._uploadEncoder);\r\n                }\r\n\r\n                if (scene) {\r\n                    scene.removePendingData(texture);\r\n                }\r\n\r\n                texture.isReady = true;\r\n\r\n                texture.onLoadedObservable.notifyObservers(texture);\r\n                texture.onLoadedObservable.clear();\r\n            },\r\n            () => false,\r\n            buffer,\r\n            fallback,\r\n            format,\r\n            forcedExtension,\r\n            mimeType,\r\n            loaderOptions,\r\n            useSRGBBuffer\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Wraps an external web gpu texture in a Babylon texture.\r\n     * @param texture defines the external texture\r\n     * @returns the babylon internal texture\r\n     */\r\n    public wrapWebGPUTexture(texture: GPUTexture): InternalTexture {\r\n        const hardwareTexture = new WebGPUHardwareTexture(this, texture);\r\n        // Report the real format of the wrapped texture. The hardware texture otherwise keeps its\r\n        // default (RGBA8Unorm); the render-pass color attachment view + pipeline color target are\r\n        // built from hardwareTexture.format (see _setColorFormat / bindFramebuffer), so an external\r\n        // texture created with any other format (e.g. bgra8unorm or an *-srgb variant, as returned by\r\n        // XRGPUBinding.getPreferredColorFormat()) would otherwise get a mismatched view and fail to render.\r\n        hardwareTexture.format = texture.format;\r\n        hardwareTexture.originalFormat = texture.format;\r\n        const internalTexture = new InternalTexture(this, InternalTextureSource.External, true);\r\n        internalTexture._hardwareTexture = hardwareTexture;\r\n        internalTexture.baseWidth = texture.width;\r\n        internalTexture.baseHeight = texture.height;\r\n        internalTexture.width = texture.width;\r\n        internalTexture.height = texture.height;\r\n        internalTexture.isReady = true;\r\n        return internalTexture;\r\n    }\r\n\r\n    /**\r\n     * Replaces the underlying GPUTexture of a texture previously created via {@link wrapWebGPUTexture}, preserving the\r\n     * InternalTexture identity.\r\n     *\r\n     * Intended for the device-loss / device-restored flow: when the host recreates its external resource on the new\r\n     * GPU device, it calls this method to repoint Babylon's wrapper at the new handle without losing references held\r\n     * by materials, render-target wrappers, particle systems, etc.\r\n     *\r\n     * The new GPUTexture must have the same dimensions as the original. To change dimensions, dispose the wrapped\r\n     * texture and call {@link wrapWebGPUTexture} again.\r\n     *\r\n     * Throws if the target was not produced by {@link wrapWebGPUTexture}, or if the new GPUTexture's dimensions don't\r\n     * match.\r\n     * @param internalTexture defines the wrapped InternalTexture to repoint\r\n     * @param texture defines the new GPUTexture to wrap\r\n     */\r\n    public updateWrappedWebGPUTexture(internalTexture: InternalTexture, texture: GPUTexture): void {\r\n        if (internalTexture.source !== InternalTextureSource.External) {\r\n            throw new Error(\"updateWrappedWebGPUTexture: target InternalTexture was not produced by wrapWebGPUTexture.\");\r\n        }\r\n        if (texture.width !== internalTexture.baseWidth || texture.height !== internalTexture.baseHeight) {\r\n            throw new Error(\r\n                `updateWrappedWebGPUTexture: new GPUTexture dimensions (${texture.width}x${texture.height}) must match the wrapped texture's dimensions (${internalTexture.baseWidth}x${internalTexture.baseHeight}).`\r\n            );\r\n        }\r\n\r\n        // Reuse the existing WebGPUHardwareTexture rather than replacing it. The wrapper carries `textureUsages`,\r\n        // `format`, and the `view` / `viewForWriting` set up the first time the texture was bound; the views point\r\n        // at the old (now-destroyed) GPUTexture, so we swap the underlying resource and re-issue views via setUsage,\r\n        // which uses the InternalTexture's flags + dimensions to pick the right view dimension and recreate the views.\r\n        const hardwareTexture = internalTexture._hardwareTexture as WebGPUHardwareTexture;\r\n        hardwareTexture.set(texture);\r\n        hardwareTexture.setUsage(\r\n            InternalTextureSource.External,\r\n            internalTexture.generateMipMaps,\r\n            internalTexture.is2DArray,\r\n            internalTexture.isCube,\r\n            internalTexture.is3D,\r\n            texture.width,\r\n            texture.height,\r\n            internalTexture.depth\r\n        );\r\n        internalTexture.isReady = true;\r\n\r\n        // WebGPUMaterialContext and WebGPUCacheBindGroups key on InternalTexture.uniqueId; bump it so caches detect\r\n        // the new resource and re-resolve bind groups against the new GPUTexture / GPUTextureView.\r\n        internalTexture._setUniqueId(InternalTexture._Counter++);\r\n    }\r\n\r\n    // eslint-disable-next-line jsdoc/require-returns-check\r\n    /**\r\n     * Wraps an external web gl texture in a Babylon texture.\r\n     * @returns the babylon internal texture\r\n     */\r\n    public wrapWebGLTexture(): InternalTexture {\r\n        throw new Error(\"wrapWebGLTexture is not supported, use wrapWebGPUTexture instead.\");\r\n    }\r\n\r\n    /**\r\n     * Throws because the engine is WebGPU. Use {@link updateWrappedWebGPUTexture} instead.\r\n     */\r\n    public updateWrappedWebGLTexture(): void {\r\n        throw new Error(\"updateWrappedWebGLTexture is not supported, use updateWrappedWebGPUTexture instead.\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getUseSRGBBuffer(useSRGBBuffer: boolean, _noMipmap: boolean): boolean {\r\n        return useSRGBBuffer && this._caps.supportSRGBBuffers;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _unpackFlipY(_value: boolean) {}\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param samplingMode defines the required sampling mode\r\n     * @param texture defines the texture to update\r\n     * @param generateMipMaps defines whether to generate mipmaps for the texture\r\n     */\r\n    public updateTextureSamplingMode(samplingMode: number, texture: InternalTexture, generateMipMaps: boolean = false): void {\r\n        if (generateMipMaps) {\r\n            texture.generateMipMaps = true;\r\n            this._generateMipmaps(texture);\r\n        }\r\n\r\n        texture.samplingMode = samplingMode;\r\n    }\r\n\r\n    /**\r\n     * Update the sampling mode of a given texture\r\n     * @param texture defines the texture to update\r\n     * @param wrapU defines the texture wrap mode of the u coordinates\r\n     * @param wrapV defines the texture wrap mode of the v coordinates\r\n     * @param wrapR defines the texture wrap mode of the r coordinates\r\n     */\r\n    public updateTextureWrappingMode(texture: InternalTexture, wrapU: Nullable<number>, wrapV: Nullable<number> = null, wrapR: Nullable<number> = null): void {\r\n        if (wrapU !== null) {\r\n            texture._cachedWrapU = wrapU;\r\n        }\r\n        if (wrapV !== null) {\r\n            texture._cachedWrapV = wrapV;\r\n        }\r\n        if ((texture.is2DArray || texture.is3D) && wrapR !== null) {\r\n            texture._cachedWrapR = wrapR;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the dimensions of a texture\r\n     * @param texture texture to update\r\n     * @param width new width of the texture\r\n     * @param height new height of the texture\r\n     * @param depth new depth of the texture\r\n     */\r\n    public updateTextureDimensions(texture: InternalTexture, width: number, height: number, depth: number = 1): void {\r\n        if (!texture._hardwareTexture) {\r\n            // the gpu texture is not created yet, so when it is it will be created with the right dimensions\r\n            return;\r\n        }\r\n\r\n        if (texture.width === width && texture.height === height && texture.depth === depth) {\r\n            return;\r\n        }\r\n\r\n        const additionalUsages = (texture._hardwareTexture as WebGPUHardwareTexture).textureAdditionalUsages;\r\n\r\n        texture._hardwareTexture.release(); // don't defer the releasing! Else we will release at the end of this frame the gpu texture we are about to create in the next line...\r\n\r\n        this._textureHelper.createGPUTextureForInternalTexture(texture, width, height, depth, additionalUsages);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setInternalTexture(name: string, texture: Nullable<InternalTexture | ExternalTexture>, baseName?: string): void {\r\n        baseName = baseName ?? name;\r\n        if (this._currentEffect) {\r\n            const webgpuPipelineContext = this._currentEffect._pipelineContext as WebGPUPipelineContext;\r\n            const availableTexture = webgpuPipelineContext.shaderProcessingContext.availableTextures[baseName];\r\n\r\n            this._currentMaterialContext.setTexture(name, texture);\r\n\r\n            if (availableTexture && availableTexture.autoBindSampler) {\r\n                const samplerName = baseName + Constants.AUTOSAMPLERSUFFIX;\r\n                this._currentMaterialContext.setSampler(samplerName, texture as InternalTexture); // we can safely cast to InternalTexture because ExternalTexture always has autoBindSampler = false\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a cube texture from prefiltered data (ie. the mipmaps contain ready to use data for PBR reflection)\r\n     * @param rootUrl defines the url where the file to load is located\r\n     * @param scene defines the current scene\r\n     * @param lodScale defines scale to apply to the mip map selection\r\n     * @param lodOffset defines offset to apply to the mip map selection\r\n     * @param onLoad defines an optional callback raised when the texture is loaded\r\n     * @param onError defines an optional callback raised if there is an issue to load the texture\r\n     * @param format defines the format of the data\r\n     * @param forcedExtension defines the extension to use to pick the right loader\r\n     * @param createPolynomials defines wheter or not to create polynomails harmonics for the texture\r\n     * @param buffer defines the data buffer to load instead of loading the rootUrl\r\n     * @returns the cube texture as an InternalTexture\r\n     */\r\n    public override createPrefilteredCubeTexture(\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        lodScale: number,\r\n        lodOffset: number,\r\n        onLoad: Nullable<(internalTexture: Nullable<InternalTexture>) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials: boolean = true,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        const callback = (loadData: any) => {\r\n            if (!loadData) {\r\n                if (onLoad) {\r\n                    onLoad(null);\r\n                }\r\n                return;\r\n            }\r\n\r\n            const texture = loadData.texture as InternalTexture;\r\n            if (!createPolynomials) {\r\n                texture._sphericalPolynomial = texture._sphericalPolynomial ?? new SphericalPolynomial();\r\n            } else if (loadData.info.sphericalPolynomial) {\r\n                texture._sphericalPolynomial = loadData.info.sphericalPolynomial;\r\n            }\r\n            texture._source = InternalTextureSource.CubePrefiltered;\r\n\r\n            if (onLoad) {\r\n                onLoad(texture);\r\n            }\r\n        };\r\n\r\n        return this.createCubeTexture(\r\n            rootUrl,\r\n            scene,\r\n            null,\r\n            false,\r\n            callback,\r\n            onError,\r\n            format,\r\n            forcedExtension,\r\n            createPolynomials,\r\n            lodScale,\r\n            lodOffset,\r\n            null,\r\n            undefined,\r\n            false,\r\n            buffer\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Sets a texture to the according uniform.\r\n     * @param channel The texture channel\r\n     * @param unused unused parameter\r\n     * @param texture The texture to apply\r\n     * @param name The name of the uniform in the effect\r\n     */\r\n    public setTexture(channel: number, unused: Nullable<WebGLUniformLocation>, texture: Nullable<BaseTexture>, name: string): void {\r\n        this._setTexture(channel, texture, false, false, name, name);\r\n    }\r\n\r\n    /**\r\n     * Sets an array of texture to the WebGPU context\r\n     * @param channel defines the channel where the texture array must be set\r\n     * @param unused unused parameter\r\n     * @param textures defines the array of textures to bind\r\n     * @param name name of the channel\r\n     */\r\n    public setTextureArray(channel: number, unused: Nullable<WebGLUniformLocation>, textures: BaseTexture[], name: string): void {\r\n        for (let index = 0; index < textures.length; index++) {\r\n            this._setTexture(-1, textures[index], true, false, name + index.toString(), name);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _setTexture(\r\n        channel: number,\r\n        texture: Nullable<BaseTexture>,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        isPartOfTextureArray = false,\r\n        depthStencilTexture = false,\r\n        name = \"\",\r\n        baseName?: string\r\n    ): boolean {\r\n        // name == baseName for a texture that is not part of a texture array\r\n        // Else, name is something like 'myTexture0' / 'myTexture1' / ... and baseName is 'myTexture'\r\n        // baseName is used to look up the texture in the shaderProcessingContext.availableTextures map\r\n        // name is used to look up the texture in the _currentMaterialContext.textures map\r\n        baseName = baseName ?? name;\r\n        if (this._currentEffect) {\r\n            if (!texture) {\r\n                this._currentMaterialContext.setTexture(name, null);\r\n                return false;\r\n            }\r\n\r\n            // Video\r\n            if ((<VideoTexture>texture).video) {\r\n                (<VideoTexture>texture).update();\r\n            } else if (texture.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n                // Delay loading\r\n                texture.delayLoad();\r\n                return false;\r\n            }\r\n\r\n            let internalTexture: Nullable<InternalTexture>;\r\n            if (depthStencilTexture) {\r\n                internalTexture = (<RenderTargetTexture>texture).depthStencilTexture!;\r\n            } else if (texture.isReady()) {\r\n                internalTexture = <InternalTexture>texture.getInternalTexture();\r\n            } else if (texture.isCube) {\r\n                internalTexture = this.emptyCubeTexture;\r\n            } else if (texture.is3D) {\r\n                internalTexture = this.emptyTexture3D;\r\n            } else if (texture.is2DArray) {\r\n                internalTexture = this.emptyTexture2DArray;\r\n            } else {\r\n                internalTexture = this.emptyTexture;\r\n            }\r\n\r\n            if (internalTexture && !internalTexture.isMultiview) {\r\n                // CUBIC_MODE and SKYBOX_MODE both require CLAMP_TO_EDGE.  All other modes use REPEAT.\r\n                if (internalTexture.isCube && internalTexture._cachedCoordinatesMode !== texture.coordinatesMode) {\r\n                    internalTexture._cachedCoordinatesMode = texture.coordinatesMode;\r\n\r\n                    const textureWrapMode =\r\n                        texture.coordinatesMode !== Constants.TEXTURE_CUBIC_MODE && texture.coordinatesMode !== Constants.TEXTURE_SKYBOX_MODE\r\n                            ? Constants.TEXTURE_WRAP_ADDRESSMODE\r\n                            : Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                    texture.wrapU = textureWrapMode;\r\n                    texture.wrapV = textureWrapMode;\r\n                }\r\n\r\n                internalTexture._cachedWrapU = texture.wrapU;\r\n                internalTexture._cachedWrapV = texture.wrapV;\r\n                if (internalTexture.is3D) {\r\n                    internalTexture._cachedWrapR = texture.wrapR;\r\n                }\r\n\r\n                this._setAnisotropicLevel(0, internalTexture, texture.anisotropicFilteringLevel);\r\n            }\r\n\r\n            this._setInternalTexture(name, internalTexture, baseName);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setAnisotropicLevel(target: number, internalTexture: InternalTexture, anisotropicFilteringLevel: number) {\r\n        if (internalTexture._cachedAnisotropicFilteringLevel !== anisotropicFilteringLevel) {\r\n            internalTexture._cachedAnisotropicFilteringLevel = Math.min(anisotropicFilteringLevel, this._caps.maxAnisotropy);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindTexture(channel: number, texture: Nullable<InternalTexture>, name: string): void {\r\n        if (channel === undefined) {\r\n            return;\r\n        }\r\n\r\n        this._setInternalTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Generates the mipmaps for a texture\r\n     * @param texture texture to generate the mipmaps for\r\n     */\r\n    public generateMipmaps(texture: InternalTexture): void {\r\n        this._generateMipmaps(texture);\r\n    }\r\n\r\n    /**\r\n     * Update a portion of an internal texture\r\n     * @param texture defines the texture to update\r\n     * @param imageData defines the data to store into the texture\r\n     * @param xOffset defines the x coordinates of the update rectangle\r\n     * @param yOffset defines the y coordinates of the update rectangle\r\n     * @param width defines the width of the update rectangle\r\n     * @param height defines the height of the update rectangle\r\n     * @param faceIndex defines the face index if texture is a cube (0 by default)\r\n     * @param lod defines the lod level to update (0 by default)\r\n     * @param generateMipMaps defines whether to generate mipmaps or not\r\n     */\r\n    public updateTextureData(\r\n        texture: InternalTexture,\r\n        imageData: ArrayBufferView,\r\n        xOffset: number,\r\n        yOffset: number,\r\n        width: number,\r\n        height: number,\r\n        faceIndex: number = 0,\r\n        lod: number = 0,\r\n        generateMipMaps = false\r\n    ): void {\r\n        let gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (!texture._hardwareTexture?.underlyingResource) {\r\n            gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture);\r\n        }\r\n\r\n        const data = new Uint8Array(imageData.buffer, imageData.byteOffset, imageData.byteLength);\r\n\r\n        this._textureHelper.updateTexture(data, texture, width, height, texture.depth, gpuTextureWrapper.format, faceIndex, lod, texture.invertY, false, xOffset, yOffset);\r\n\r\n        if (generateMipMaps) {\r\n            this._generateMipmaps(texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadCompressedDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        internalFormat: number,\r\n        width: number,\r\n        height: number,\r\n        imageData: ArrayBufferView,\r\n        faceIndex: number = 0,\r\n        lod: number = 0\r\n    ) {\r\n        let gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (!texture._hardwareTexture?.underlyingResource) {\r\n            texture.format = internalFormat;\r\n            gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture, width, height);\r\n        }\r\n\r\n        const data = new Uint8Array(imageData.buffer, imageData.byteOffset, imageData.byteLength);\r\n\r\n        this._textureHelper.updateTexture(data, texture, width, height, texture.depth, gpuTextureWrapper.format, faceIndex, lod, false, false, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadDataToTextureDirectly(\r\n        texture: InternalTexture,\r\n        imageData: ArrayBufferView,\r\n        faceIndex: number = 0,\r\n        lod: number = 0,\r\n        babylonInternalFormat?: number,\r\n        useTextureWidthAndHeight = false\r\n    ): void {\r\n        const lodMaxWidth = Math.round(Math.log(texture.width) * Math.LOG2E);\r\n        const lodMaxHeight = Math.round(Math.log(texture.height) * Math.LOG2E);\r\n\r\n        const width = useTextureWidthAndHeight ? texture.width : Math.pow(2, Math.max(lodMaxWidth - lod, 0));\r\n        const height = useTextureWidthAndHeight ? texture.height : Math.pow(2, Math.max(lodMaxHeight - lod, 0));\r\n\r\n        let gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (!texture._hardwareTexture?.underlyingResource) {\r\n            gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture, width, height);\r\n        }\r\n\r\n        const data = new Uint8Array(imageData.buffer, imageData.byteOffset, imageData.byteLength);\r\n\r\n        this._textureHelper.updateTexture(data, texture, width, height, texture.depth, gpuTextureWrapper.format, faceIndex, lod, texture.invertY, false, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {\r\n        this._uploadDataToTextureDirectly(texture, imageData, faceIndex, lod);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement | ImageBitmap, faceIndex: number = 0, lod: number = 0) {\r\n        let gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (!texture._hardwareTexture?.underlyingResource) {\r\n            gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture);\r\n        }\r\n\r\n        if (image instanceof HTMLImageElement) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"WebGPU engine: HTMLImageElement not supported in _uploadImageToTexture!\";\r\n        }\r\n\r\n        const bitmap = image; // in WebGPU we will always get an ImageBitmap, not an HTMLImageElement\r\n\r\n        const width = Math.ceil(texture.width / (1 << lod));\r\n        const height = Math.ceil(texture.height / (1 << lod));\r\n\r\n        this._textureHelper.updateTexture(bitmap, texture, width, height, texture.depth, gpuTextureWrapper.format, faceIndex, lod, texture.invertY, false, 0, 0);\r\n    }\r\n\r\n    /**\r\n     * Reads pixels from the current frame buffer. Please note that this function can be slow\r\n     * @param x defines the x coordinate of the rectangle where pixels must be read\r\n     * @param y defines the y coordinate of the rectangle where pixels must be read\r\n     * @param width defines the width of the rectangle where pixels must be read\r\n     * @param height defines the height of the rectangle where pixels must be read\r\n     * @param _hasAlpha defines whether the output should have alpha or not (defaults to true)\r\n     * @param flushRenderer true to flush the renderer from the pending commands before reading the pixels\r\n     * @param data defines the data to fill with the read pixels (if not provided, a new one will be created)\r\n     * @returns a ArrayBufferView promise (Uint8Array) containing RGBA colors\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public readPixels(x: number, y: number, width: number, height: number, _hasAlpha = true, flushRenderer = true, data: Nullable<Uint8Array> = null): Promise<ArrayBufferView> {\r\n        const renderPassWrapper = this._getCurrentRenderPassWrapper();\r\n        const hardwareTexture = renderPassWrapper.colorAttachmentGPUTextures[0];\r\n        if (!hardwareTexture) {\r\n            // we are calling readPixels for a render pass with no color texture bound\r\n            return Promise.resolve(new Uint8Array(0));\r\n        }\r\n        const gpuTexture = hardwareTexture.underlyingResource;\r\n        const gpuTextureFormat = hardwareTexture.format;\r\n        if (!gpuTexture) {\r\n            // we are calling readPixels before startMainRenderPass has been called and no RTT is bound, so swapChainTexture is not setup yet!\r\n            return Promise.resolve(new Uint8Array(0));\r\n        }\r\n        if (flushRenderer) {\r\n            this.flushFramebuffer();\r\n        }\r\n        return this._textureHelper.readPixels(gpuTexture, x, y, width, height, gpuTextureFormat, undefined, undefined, data);\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Frame management\r\n    //------------------------------------------------------------------------------\r\n\r\n    private _measureFps(): void {\r\n        this._performanceMonitor.sampleFrame();\r\n        this._fps = this._performanceMonitor.averageFPS;\r\n        this._deltaTime = this._performanceMonitor.instantaneousFrameTime || 0;\r\n    }\r\n\r\n    private _performanceMonitor = new PerformanceMonitor();\r\n    /**\r\n     * Gets the performance monitor attached to this engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n     */\r\n    public get performanceMonitor(): PerformanceMonitor {\r\n        return this._performanceMonitor;\r\n    }\r\n\r\n    /**\r\n     * Begin a new frame\r\n     */\r\n    public override beginFrame(): void {\r\n        this._measureFps();\r\n        super.beginFrame();\r\n    }\r\n\r\n    /**\r\n     * End the current frame\r\n     */\r\n    public override endFrame() {\r\n        this._endCurrentRenderPass();\r\n\r\n        this._snapshotRendering.endFrame();\r\n\r\n        this._timestampQuery.endFrame(this._renderEncoder);\r\n        this._timestampIndex = 0;\r\n        this._internalFrameCounter = 0;\r\n\r\n        this.flushFramebuffer(true);\r\n\r\n        this._textureHelper.destroyDeferredTextures();\r\n        this._bufferManager.destroyDeferredBuffers();\r\n\r\n        this.countersLastFrame.numEnableEffects = this._counters.numEnableEffects;\r\n        this.countersLastFrame.numEnableDrawWrapper = this._counters.numEnableDrawWrapper;\r\n        this.countersLastFrame.numBundleCreationNonCompatMode = this._counters.numBundleCreationNonCompatMode;\r\n        this.countersLastFrame.numBundleReuseNonCompatMode = this._counters.numBundleReuseNonCompatMode;\r\n        this._counters.numEnableEffects = 0;\r\n        this._counters.numEnableDrawWrapper = 0;\r\n        this._counters.numBundleCreationNonCompatMode = 0;\r\n        this._counters.numBundleReuseNonCompatMode = 0;\r\n\r\n        this._cacheRenderPipeline.endFrame();\r\n        this._cacheBindGroups.endFrame();\r\n\r\n        super.endFrame();\r\n    }\r\n\r\n    /**Gets driver info if available */\r\n    public extractDriverInfo() {\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * Force a WebGPU flush (ie. a flush of all waiting commands)\r\n     * @internal @param _fromEndFrame defines whether the flush is triggered from endFrame or not (default: false)\r\n     */\r\n    public flushFramebuffer(_fromEndFrame = false): void {\r\n        // we need to end the current render pass (main or rtt) if any as we are not allowed to submit the command buffers when being in a pass\r\n        this._endCurrentRenderPass();\r\n\r\n        this._debugPopBeforeEndOfEncoder();\r\n\r\n        this._commandBuffers[0] = this._uploadEncoder.finish();\r\n        this._commandBuffers[1] = this._renderEncoder.finish();\r\n\r\n        this._device.queue.submit(this._commandBuffers);\r\n\r\n        const frameCounter = this._internalFrameCounter++;\r\n\r\n        // If flushFramebuffer is called from endFrame, it means the encoders are created for the next frame, but because frameId is not yet incremented at the time of the call, we use frameId + 1\r\n        this._uploadEncoderDescriptor.label = `[${_fromEndFrame ? this.frameId + 1 : this.frameId}|${frameCounter}] - UploadEncoder`;\r\n        this._renderEncoderDescriptor.label = `[${_fromEndFrame ? this.frameId + 1 : this.frameId}|${frameCounter}] - RenderEncoder`;\r\n\r\n        this._uploadEncoder = this._device.createCommandEncoder(this._uploadEncoderDescriptor);\r\n        this._renderEncoder = this._device.createCommandEncoder(this._renderEncoderDescriptor);\r\n\r\n        if (_fromEndFrame) {\r\n            this._debugMarkersEncoderGroups.length = 0;\r\n            this._debugMarkersPassGroups.length = 0;\r\n        } else {\r\n            this._debugPushAfterStartOfEncoder();\r\n        }\r\n\r\n        this._timestampQuery.startFrame(this._uploadEncoder);\r\n\r\n        this._textureHelper.setCommandEncoder(this._uploadEncoder);\r\n\r\n        this._bundleList.reset();\r\n    }\r\n\r\n    /** @internal */\r\n    public _currentFrameBufferIsDefaultFrameBuffer() {\r\n        return this._currentPassIsMainPass();\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Render Pass\r\n    //------------------------------------------------------------------------------\r\n\r\n    /** @internal */\r\n    public _startRenderTargetRenderPass(\r\n        renderTargetWrapper: RenderTargetWrapper,\r\n        setClearStates: boolean,\r\n        clearColor: Nullable<IColor4Like>,\r\n        clearDepth: boolean,\r\n        clearStencil: boolean\r\n    ) {\r\n        this._endCurrentRenderPass();\r\n\r\n        const rtWrapper = renderTargetWrapper as WebGPURenderTargetWrapper;\r\n        const sampleCount = renderTargetWrapper.samples;\r\n        const useMSAA = sampleCount > 1;\r\n\r\n        const depthStencilTexture = rtWrapper._depthStencilTexture;\r\n        const gpuDepthStencilWrapper = depthStencilTexture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n        const gpuDepthStencilTexture = gpuDepthStencilWrapper?.underlyingResource;\r\n\r\n        // We use the MSAA texture format first (if available) to determine if it has a stencil aspect or not because, for MSAA depth textures,\r\n        // the format of the \"resolve\" texture (gpuDepthStencilWrapper.format) is a single red channel format, not a depth-stencil format.\r\n\r\n        let depthStencilView: GPUTextureView | undefined;\r\n        let format: GPUTextureFormat | undefined;\r\n\r\n        if (useMSAA) {\r\n            const gpuMSAATexture = gpuDepthStencilWrapper?.getMSAATexture(sampleCount);\r\n\r\n            depthStencilView = gpuMSAATexture ? this._cacheTextureViews.getView(gpuMSAATexture, this._rttRenderPassWrapper.depthAttachmentViewDescriptor!) : undefined;\r\n            format = gpuMSAATexture?.format;\r\n        }\r\n\r\n        if (!depthStencilView && gpuDepthStencilTexture) {\r\n            depthStencilView = this._cacheTextureViews.getView(gpuDepthStencilTexture, this._rttRenderPassWrapper.depthAttachmentViewDescriptor!);\r\n        }\r\n\r\n        if (!format && gpuDepthStencilWrapper) {\r\n            format = gpuDepthStencilWrapper.format;\r\n        }\r\n\r\n        const depthTextureHasStencil = format ? WebGPUTextureHelper.HasStencilAspect(format) : false;\r\n        const depthTextureHasDepth = format ? WebGPUTextureHelper.HasDepthAspect(format) : false;\r\n\r\n        const colorAttachments: (GPURenderPassColorAttachment | null)[] = [];\r\n\r\n        if (this.useReverseDepthBuffer) {\r\n            this.setDepthFunctionToGreaterOrEqual();\r\n        }\r\n\r\n        const clearColorForIntegerRt = TempColor4;\r\n        const clearColorForSignedIntegerRt = TempColor4SignedInteger;\r\n        if (clearColor) {\r\n            clearColorForIntegerRt.r = clearColor.r * 255;\r\n            clearColorForIntegerRt.g = clearColor.g * 255;\r\n            clearColorForIntegerRt.b = clearColor.b * 255;\r\n            clearColorForIntegerRt.a = clearColor.a * 255;\r\n            clearColorForSignedIntegerRt.r = Math.round(clearColor.r);\r\n            clearColorForSignedIntegerRt.g = Math.round(clearColor.g);\r\n            clearColorForSignedIntegerRt.b = Math.round(clearColor.b);\r\n            clearColorForSignedIntegerRt.a = Math.round(clearColor.a);\r\n        }\r\n\r\n        const mustClearColor = setClearStates && clearColor;\r\n        const mustClearDepth = setClearStates && clearDepth;\r\n        const mustClearStencil = setClearStates && clearStencil;\r\n\r\n        if (rtWrapper._attachments && rtWrapper.isMulti) {\r\n            // multi render targets\r\n            if (!this._mrtAttachments || this._mrtAttachments.length === 0) {\r\n                this._mrtAttachments = rtWrapper._defaultAttachments;\r\n            }\r\n            for (let i = 0; i < this._mrtAttachments.length; ++i) {\r\n                const index = this._mrtAttachments[i]; // if index == 0 it means the texture should not be written to => at render pass creation time, it means we should not clear it\r\n                const mrtTexture = rtWrapper.textures![i];\r\n                const gpuMRTWrapper = mrtTexture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n                const gpuMRTTexture = gpuMRTWrapper?.underlyingResource;\r\n                if (gpuMRTWrapper && gpuMRTTexture) {\r\n                    const depthSlice = mrtTexture.is3D ? (rtWrapper.layerIndices?.[i] ?? 0) : undefined;\r\n                    const baseArrayLayer = rtWrapper.getBaseArrayLayer(i);\r\n                    const gpuMSAATexture = useMSAA ? gpuMRTWrapper.getMSAATexture(sampleCount, mrtTexture.is3D ? depthSlice : baseArrayLayer) : undefined;\r\n\r\n                    const viewDescriptor = {\r\n                        ...this._rttRenderPassWrapper.colorAttachmentViewDescriptor!,\r\n                        dimension: mrtTexture.is3D ? WebGPUConstants.TextureViewDimension.E3d : WebGPUConstants.TextureViewDimension.E2d,\r\n                        format: gpuMRTWrapper.format,\r\n                        baseArrayLayer,\r\n                    };\r\n                    const msaaViewDescriptor = {\r\n                        ...this._rttRenderPassWrapper.colorAttachmentViewDescriptor!,\r\n                        dimension: mrtTexture.is3D ? WebGPUConstants.TextureViewDimension.E3d : WebGPUConstants.TextureViewDimension.E2d,\r\n                        format: gpuMRTWrapper.format,\r\n                        baseArrayLayer: 0,\r\n                    };\r\n                    const isRtInteger = IsIntegerTextureFormat(mrtTexture.format);\r\n                    const isRtUnsignedInteger = IsUnsignedIntegerTextureType(mrtTexture.type);\r\n\r\n                    const colorTextureView = this._cacheTextureViews.getView(gpuMRTTexture, viewDescriptor);\r\n                    const colorMSAATextureView = gpuMSAATexture ? this._cacheTextureViews.getView(gpuMSAATexture, msaaViewDescriptor) : undefined;\r\n\r\n                    colorAttachments.push({\r\n                        view: colorMSAATextureView ? colorMSAATextureView : colorTextureView,\r\n                        resolveTarget: gpuMSAATexture && !rtWrapper.disableAutomaticMSAAResolve && rtWrapper.resolveMSAAColors ? colorTextureView : undefined,\r\n                        depthSlice,\r\n                        clearValue:\r\n                            index !== 0 && mustClearColor ? (isRtInteger ? (isRtUnsignedInteger ? clearColorForIntegerRt : clearColorForSignedIntegerRt) : clearColor) : undefined,\r\n                        loadOp: index !== 0 && mustClearColor ? WebGPUConstants.LoadOp.Clear : WebGPUConstants.LoadOp.Load,\r\n                        storeOp: WebGPUConstants.StoreOp.Store,\r\n                    });\r\n                }\r\n            }\r\n            this._cacheRenderPipeline.setMRT(rtWrapper.textures!, this._mrtAttachments.length);\r\n            this._cacheRenderPipeline.setMRTAttachments(this._mrtAttachments);\r\n        } else {\r\n            // single render target\r\n            const internalTexture = rtWrapper.texture;\r\n            if (internalTexture) {\r\n                const gpuWrapper = internalTexture._hardwareTexture as WebGPUHardwareTexture;\r\n                const gpuTexture = gpuWrapper.underlyingResource!;\r\n                const depthSlice = rtWrapper.is3D ? this._rttRenderPassWrapper.colorAttachmentDepthSlice : undefined;\r\n                const layerIndex = depthSlice ?? this._rttRenderPassWrapper.colorAttachmentViewDescriptor!.baseArrayLayer;\r\n\r\n                const gpuMSAATexture = useMSAA ? gpuWrapper.getMSAATexture(sampleCount, layerIndex) : undefined;\r\n                const colorTextureView = this._cacheTextureViews.getView(gpuTexture, this._rttRenderPassWrapper.colorAttachmentViewDescriptor!);\r\n                const colorMSAATextureView = gpuMSAATexture\r\n                    ? this._cacheTextureViews.getView(gpuMSAATexture, this._rttRenderPassWrapper.colorAttachmentViewDescriptor!)\r\n                    : undefined;\r\n                const isRtInteger = IsIntegerTextureFormat(internalTexture.format);\r\n                const isRtUnsignedInteger = IsUnsignedIntegerTextureType(internalTexture.type);\r\n\r\n                colorAttachments.push({\r\n                    view: colorMSAATextureView ? colorMSAATextureView : colorTextureView,\r\n                    resolveTarget: gpuMSAATexture && !rtWrapper.disableAutomaticMSAAResolve && rtWrapper.resolveMSAAColors ? colorTextureView : undefined,\r\n                    depthSlice,\r\n                    clearValue: mustClearColor ? (isRtInteger ? (isRtUnsignedInteger ? clearColorForIntegerRt : clearColorForSignedIntegerRt) : clearColor) : undefined,\r\n                    loadOp: mustClearColor ? WebGPUConstants.LoadOp.Clear : WebGPUConstants.LoadOp.Load,\r\n                    storeOp: WebGPUConstants.StoreOp.Store,\r\n                });\r\n            } else {\r\n                colorAttachments.push(null);\r\n            }\r\n        }\r\n\r\n        const frameCounter = this._internalFrameCounter++;\r\n\r\n        this._rttRenderPassWrapper.renderPassDescriptor = {\r\n            label: `[${this.frameId}|${frameCounter}] - ` + (renderTargetWrapper.label ?? \"RTT\") + \" - RenderPass\",\r\n            colorAttachments,\r\n            depthStencilAttachment:\r\n                depthStencilTexture && gpuDepthStencilTexture\r\n                    ? {\r\n                          view: depthStencilView!,\r\n                          depthClearValue: mustClearDepth ? (this.useReverseDepthBuffer ? this._clearReverseDepthValue : this._clearDepthValue) : undefined,\r\n                          depthLoadOp: rtWrapper.depthReadOnly || !depthTextureHasDepth ? undefined : mustClearDepth ? WebGPUConstants.LoadOp.Clear : WebGPUConstants.LoadOp.Load,\r\n                          depthStoreOp: rtWrapper.depthReadOnly || !depthTextureHasDepth ? undefined : WebGPUConstants.StoreOp.Store,\r\n                          depthReadOnly: rtWrapper.depthReadOnly,\r\n                          stencilClearValue: rtWrapper._depthStencilTextureWithStencil && mustClearStencil ? this._clearStencilValue : undefined,\r\n                          stencilLoadOp:\r\n                              rtWrapper.stencilReadOnly || !depthTextureHasStencil\r\n                                  ? undefined\r\n                                  : rtWrapper._depthStencilTextureWithStencil && mustClearStencil\r\n                                    ? WebGPUConstants.LoadOp.Clear\r\n                                    : WebGPUConstants.LoadOp.Load,\r\n                          stencilStoreOp: rtWrapper.stencilReadOnly || !depthTextureHasStencil ? undefined : WebGPUConstants.StoreOp.Store,\r\n                          stencilReadOnly: rtWrapper.stencilReadOnly,\r\n                      }\r\n                    : undefined,\r\n            occlusionQuerySet: this._occlusionQuery?.hasQueries ? this._occlusionQuery.querySet : undefined,\r\n        };\r\n        this._timestampQuery.startPass(this._rttRenderPassWrapper.renderPassDescriptor, this._timestampIndex);\r\n        this._currentRenderPass = this._renderEncoder.beginRenderPass(this._rttRenderPassWrapper.renderPassDescriptor);\r\n\r\n        this._debugPushAfterStartOfEncoder();\r\n\r\n        this._resetRenderPassStates();\r\n\r\n        if (!gpuDepthStencilWrapper || !WebGPUTextureHelper.HasStencilAspect(gpuDepthStencilWrapper.format)) {\r\n            this._stencilStateComposer.enabled = false;\r\n        }\r\n    }\r\n\r\n    private _startMainRenderPass(setClearStates: boolean, clearColor?: Nullable<IColor4Like>, clearDepth?: boolean, clearStencil?: boolean): void {\r\n        this._endCurrentRenderPass();\r\n\r\n        if (this.useReverseDepthBuffer) {\r\n            this.setDepthFunctionToGreaterOrEqual();\r\n        }\r\n\r\n        const mustClearColor = setClearStates && clearColor;\r\n        const mustClearDepth = setClearStates && clearDepth;\r\n        const mustClearStencil = setClearStates && clearStencil;\r\n\r\n        const frameCounter = this._internalFrameCounter++;\r\n\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.label = `[${this.frameId}|${frameCounter}] - MainRenderPass`;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.colorAttachments[0]!.clearValue = mustClearColor ? clearColor : undefined;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.colorAttachments[0]!.loadOp = mustClearColor ? WebGPUConstants.LoadOp.Clear : WebGPUConstants.LoadOp.Load;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.depthStencilAttachment!.depthClearValue = mustClearDepth\r\n            ? this.useReverseDepthBuffer\r\n                ? this._clearReverseDepthValue\r\n                : this._clearDepthValue\r\n            : undefined;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.depthStencilAttachment!.depthLoadOp = mustClearDepth ? WebGPUConstants.LoadOp.Clear : WebGPUConstants.LoadOp.Load;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.depthStencilAttachment!.stencilClearValue = mustClearStencil ? this._clearStencilValue : undefined;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.depthStencilAttachment!.stencilLoadOp = !this.isStencilEnable\r\n            ? undefined\r\n            : mustClearStencil\r\n              ? WebGPUConstants.LoadOp.Clear\r\n              : WebGPUConstants.LoadOp.Load;\r\n        this._mainRenderPassWrapper.renderPassDescriptor!.occlusionQuerySet = this._occlusionQuery?.hasQueries ? this._occlusionQuery.querySet : undefined;\r\n\r\n        const swapChainTexture = this._context.getCurrentTexture();\r\n        this._mainRenderPassWrapper.colorAttachmentGPUTextures[0]!.set(swapChainTexture);\r\n\r\n        // Resolve in case of MSAA\r\n        if (this._options.antialias) {\r\n            ViewDescriptorSwapChainAntialiasing.format = swapChainTexture.format;\r\n            this._mainRenderPassWrapper.renderPassDescriptor!.colorAttachments[0]!.resolveTarget = swapChainTexture.createView(ViewDescriptorSwapChainAntialiasing);\r\n        } else {\r\n            ViewDescriptorSwapChain.format = swapChainTexture.format;\r\n            this._mainRenderPassWrapper.renderPassDescriptor!.colorAttachments[0]!.view = swapChainTexture.createView(ViewDescriptorSwapChain);\r\n        }\r\n\r\n        this._timestampQuery.startPass(this._mainRenderPassWrapper.renderPassDescriptor!, this._timestampIndex);\r\n        this._currentRenderPass = this._renderEncoder.beginRenderPass(this._mainRenderPassWrapper.renderPassDescriptor!);\r\n\r\n        this._debugPushAfterStartOfEncoder();\r\n\r\n        this._setDepthTextureFormat(this._mainRenderPassWrapper);\r\n        this._setColorFormat(this._mainRenderPassWrapper);\r\n\r\n        this._resetRenderPassStates();\r\n\r\n        if (!this._isStencilEnable) {\r\n            this._stencilStateComposer.enabled = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the frame buffer to the specified texture.\r\n     * @param texture The render target wrapper to render to\r\n     * @param faceIndex The face of the texture to render to in case of cube texture\r\n     * @param requiredWidth The width of the target to render to\r\n     * @param requiredHeight The height of the target to render to\r\n     * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true\r\n     * @param lodLevel defines the lod level to bind to the frame buffer\r\n     * @param layer defines the 2d array index to bind to frame buffer to\r\n     */\r\n    public bindFramebuffer(\r\n        texture: RenderTargetWrapper,\r\n        faceIndex: number = 0,\r\n        requiredWidth?: number,\r\n        requiredHeight?: number,\r\n        forceFullscreenViewport?: boolean,\r\n        lodLevel = 0,\r\n        layer = 0\r\n    ): void {\r\n        const hardwareTexture = texture.texture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n\r\n        if (this._currentRenderTarget) {\r\n            this.unBindFramebuffer(this._currentRenderTarget);\r\n        } else {\r\n            this._endCurrentRenderPass();\r\n        }\r\n        this._currentRenderTarget = texture;\r\n\r\n        const depthStencilTexture = this._currentRenderTarget._depthStencilTexture;\r\n\r\n        this._rttRenderPassWrapper.colorAttachmentGPUTextures[0] = hardwareTexture;\r\n        this._rttRenderPassWrapper.depthTextureFormat = depthStencilTexture ? WebGPUTextureHelper.GetWebGPUTextureFormat(-1, depthStencilTexture.format) : undefined;\r\n\r\n        this._setDepthTextureFormat(this._rttRenderPassWrapper);\r\n        this._setColorFormat(this._rttRenderPassWrapper);\r\n\r\n        this._rttRenderPassWrapper.colorAttachmentViewDescriptor = {\r\n            label: texture.label ? texture.label + \" - Color Attachment View\" : \"RTT - Color Attachment View\",\r\n            format: this._colorFormat as GPUTextureFormat,\r\n            dimension: texture.is3D ? WebGPUConstants.TextureViewDimension.E3d : WebGPUConstants.TextureViewDimension.E2d,\r\n            mipLevelCount: 1,\r\n            baseArrayLayer: texture.is3D ? 0 : texture.isCube ? layer * 6 + faceIndex : layer,\r\n            baseMipLevel: lodLevel,\r\n            arrayLayerCount: 1,\r\n            aspect: WebGPUConstants.TextureAspect.All,\r\n        };\r\n        this._rttRenderPassWrapper.colorAttachmentDepthSlice = texture.is3D ? layer : undefined;\r\n\r\n        this._rttRenderPassWrapper.depthAttachmentViewDescriptor = {\r\n            label: texture.label ? texture.label + \" - Depth Attachment View\" : \"RTT - Depth Attachment View\",\r\n            format: this._depthTextureFormat!,\r\n            dimension: depthStencilTexture && depthStencilTexture.is3D ? WebGPUConstants.TextureViewDimension.E3d : WebGPUConstants.TextureViewDimension.E2d,\r\n            mipLevelCount: 1,\r\n            baseArrayLayer: depthStencilTexture ? (depthStencilTexture.isCube ? layer * 6 + faceIndex : layer) : 0,\r\n            baseMipLevel: 0,\r\n            arrayLayerCount: 1,\r\n            aspect: WebGPUConstants.TextureAspect.All,\r\n        };\r\n\r\n        // We don't create the render pass just now, we do a lazy creation of the render pass, hoping the render pass will be created by a call to clear()...\r\n        // However, if snapshot rendering is enabled, we need to create the render pass immediately, to be sure currentRenderPass is not null when _endCurrentRenderPass() is called.\r\n        // (as in snapshot rendering mode, we may not have a call to clear() before _endCurrentRenderPass(), so lazy creation would not work)\r\n        if (this._snapshotRendering.play || this._snapshotRendering.record) {\r\n            this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);\r\n        }\r\n\r\n        if (this._cachedViewport && !forceFullscreenViewport) {\r\n            this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);\r\n        } else {\r\n            if (!requiredWidth) {\r\n                requiredWidth = texture.width;\r\n                if (lodLevel) {\r\n                    requiredWidth = requiredWidth / Math.pow(2, lodLevel);\r\n                }\r\n            }\r\n            if (!requiredHeight) {\r\n                requiredHeight = texture.height;\r\n                if (lodLevel) {\r\n                    requiredHeight = requiredHeight / Math.pow(2, lodLevel);\r\n                }\r\n            }\r\n\r\n            this._viewport(0, 0, requiredWidth, requiredHeight);\r\n        }\r\n\r\n        this.wipeCaches();\r\n    }\r\n\r\n    /**\r\n     * Unbind the current render target texture from the WebGPU context\r\n     * @param texture defines the render target wrapper to unbind\r\n     * @param disableGenerateMipMaps defines a boolean indicating that mipmaps must not be generated\r\n     * @param onBeforeUnbind defines a function which will be called before the effective unbind\r\n     */\r\n    public unBindFramebuffer(texture: RenderTargetWrapper, disableGenerateMipMaps = false, onBeforeUnbind?: () => void): void {\r\n        const saveCrt = this._currentRenderTarget;\r\n\r\n        this._currentRenderTarget = null; // to be iso with abstractEngine, this._currentRenderTarget must be null when onBeforeUnbind is called\r\n\r\n        if (onBeforeUnbind) {\r\n            onBeforeUnbind();\r\n        }\r\n\r\n        this._currentRenderTarget = saveCrt;\r\n\r\n        this._endCurrentRenderPass();\r\n\r\n        this._resolveAndGenerateMipMapsFramebuffer(texture, disableGenerateMipMaps);\r\n\r\n        this._currentRenderTarget = null;\r\n\r\n        this._mrtAttachments = [];\r\n        this._cacheRenderPipeline.setMRT([]);\r\n        this._cacheRenderPipeline.setMRTAttachments(this._mrtAttachments);\r\n    }\r\n\r\n    private _resolveAndGenerateMipMapsFramebuffer(texture: RenderTargetWrapper, disableGenerateMipMaps = false): void {\r\n        const webglRtWrapper = texture;\r\n\r\n        if (!webglRtWrapper.disableAutomaticMSAAResolve) {\r\n            // we pass false as the second parameter because the color resolve has already been done automatically when the render pass ended\r\n            this.resolveFramebuffer(texture, false);\r\n        }\r\n\r\n        if (!disableGenerateMipMaps) {\r\n            if (texture.isMulti) {\r\n                this.generateMipMapsMultiFramebuffer(texture);\r\n            } else {\r\n                this.generateMipMapsFramebuffer(texture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Generates mipmaps for the texture of the (single) render target\r\n     * @param texture The render target containing the texture to generate the mipmaps for\r\n     */\r\n    public generateMipMapsFramebuffer(texture: RenderTargetWrapper): void {\r\n        if (!texture.isMulti && texture.texture?.generateMipMaps && !texture.isCube) {\r\n            this._generateMipmaps(texture.texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resolves the MSAA texture of the render target into its non-MSAA version.\r\n     * Note that if \"texture\" is not a MSAA render target, no resolve is performed.\r\n     * @param texture The render target texture containing the MSAA texture to resolve\r\n     * @param resolveColors If true, resolve the color textures (default: true) - still subject to texture.resolveMSAAColors\r\n     */\r\n    public resolveFramebuffer(texture: RenderTargetWrapper, resolveColors = true): void {\r\n        if (texture.samples <= 1) {\r\n            return;\r\n        }\r\n\r\n        if (texture.resolveMSAAColors && resolveColors) {\r\n            const disableAutomaticMSAAResolve = texture.disableAutomaticMSAAResolve;\r\n\r\n            texture.disableAutomaticMSAAResolve = false;\r\n\r\n            // Simply bind and unbind the framebuffer to trigger the resolve\r\n            this.bindFramebuffer(texture);\r\n            this._startRenderTargetRenderPass(this._currentRenderTarget!, false, null, false, false);\r\n            this.unBindFramebuffer(texture);\r\n\r\n            texture.disableAutomaticMSAAResolve = disableAutomaticMSAAResolve;\r\n        }\r\n\r\n        if (texture.resolveMSAADepth && texture._depthStencilTexture) {\r\n            const gpuTextureWrapper = texture._depthStencilTexture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n            this._textureHelper.resolveMSAADepthTexture(gpuTextureWrapper.getMSAATexture(texture.samples)!, gpuTextureWrapper.underlyingResource!, this._renderEncoder);\r\n        }\r\n    }\r\n\r\n    public restoreDefaultFramebuffer(unbindOnly?: boolean): void {\r\n        if (this._currentRenderTarget) {\r\n            this.unBindFramebuffer(this._currentRenderTarget);\r\n        } else {\r\n            if (!this._currentRenderPass && !unbindOnly) {\r\n                this._startMainRenderPass(false);\r\n            } else {\r\n                this._endCurrentRenderPass();\r\n            }\r\n        }\r\n\r\n        if (this._cachedViewport) {\r\n            this.setViewport(this._cachedViewport);\r\n        }\r\n\r\n        this.wipeCaches();\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Render\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setColorFormat(wrapper: IWebGPURenderPassWrapper): void {\r\n        const format = wrapper.colorAttachmentGPUTextures[0]?.format ?? null;\r\n        this._cacheRenderPipeline.setColorFormat(format);\r\n        if (this._colorFormat === format) {\r\n            return;\r\n        }\r\n        this._colorFormat = format;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setDepthTextureFormat(wrapper: IWebGPURenderPassWrapper): void {\r\n        this._cacheRenderPipeline.setDepthStencilFormat(wrapper.depthTextureFormat);\r\n        if (this._depthTextureFormat === wrapper.depthTextureFormat) {\r\n            return;\r\n        }\r\n        this._depthTextureFormat = wrapper.depthTextureFormat;\r\n    }\r\n\r\n    /**\r\n     * Set the dithering state (not applicable in WebGPU)\r\n     */\r\n    public setDitheringState(): void {\r\n        // Does not exist in WebGPU\r\n    }\r\n\r\n    /**\r\n     * Set the rasterizer state (not applicable in WebGPU)\r\n     */\r\n    public setRasterizerState(): void {\r\n        // Does not exist in WebGPU\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void) {\r\n        // No parallel shader compilation.\r\n        // No Async, so direct launch\r\n        action();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public bindSamplers(): void {}\r\n\r\n    /** @internal */\r\n    public _getUnpackAlignement(): number {\r\n        return 1;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bindTextureDirectly(): boolean {\r\n        return false;\r\n    }\r\n\r\n    public setStateCullFaceType(cullBackFaces?: boolean, force = false) {\r\n        const cullFace = (this.cullBackFaces ?? cullBackFaces ?? true) ? 1 : 2;\r\n        if (this._depthCullingState.cullFace !== cullFace || force) {\r\n            this._depthCullingState.cullFace = cullFace;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set various states to the webGL context\r\n     * @param culling defines culling state: true to enable culling, false to disable it\r\n     * @param zOffset defines the value to apply to zOffset (0 by default)\r\n     * @param force defines if states must be applied even if cache is up to date\r\n     * @param reverseSide defines if culling must be reversed (CCW if false, CW if true)\r\n     * @param cullBackFaces true to cull back faces, false to cull front faces (if culling is enabled)\r\n     * @param stencil stencil states to set\r\n     * @param zOffsetUnits defines the value to apply to zOffsetUnits (0 by default)\r\n     */\r\n    public setState(culling: boolean, zOffset: number = 0, force?: boolean, reverseSide = false, cullBackFaces?: boolean, stencil?: IStencilState, zOffsetUnits: number = 0): void {\r\n        // Culling\r\n        if (this._depthCullingState.cull !== culling || force) {\r\n            this._depthCullingState.cull = culling;\r\n        }\r\n\r\n        // Cull face\r\n        this.setStateCullFaceType(cullBackFaces, force);\r\n\r\n        // Z offset\r\n        this.setZOffset(zOffset);\r\n        this.setZOffsetUnits(zOffsetUnits);\r\n\r\n        // Front face\r\n        // Render targets are drawn Y-flipped (see the InternalsUBO yFactor in _draw), so their triangle\r\n        // winding is reversed here to compensate and keep the same faces visible. XR projection-layer targets\r\n        // opt out of that flip (_disableEngineYFlip) because the compositor presents them directly, so they\r\n        // keep the main-framebuffer winding.\r\n        const invertYRenderTarget = !!this._currentRenderTarget && !(this._currentRenderTarget as WebGPURenderTargetWrapper)._disableEngineYFlip;\r\n        const frontFace = reverseSide ? (invertYRenderTarget ? 1 : 2) : invertYRenderTarget ? 2 : 1;\r\n        if (this._depthCullingState.frontFace !== frontFace || force) {\r\n            this._depthCullingState.frontFace = frontFace;\r\n        }\r\n\r\n        this._stencilStateComposer.stencilMaterial = stencil;\r\n    }\r\n\r\n    private _applyRenderPassChanges(bundleList: Nullable<WebGPUBundleList>): void {\r\n        const mustUpdateStencilRef = !this._stencilStateComposer.enabled ? false : this._mustUpdateStencilRef();\r\n        const mustUpdateBlendColor = !this._alphaState.alphaBlend ? false : this._mustUpdateBlendColor();\r\n\r\n        if (this._mustUpdateViewport()) {\r\n            this._applyViewport(bundleList);\r\n        }\r\n        if (this._mustUpdateScissor()) {\r\n            this._applyScissor(bundleList);\r\n        }\r\n        if (mustUpdateStencilRef) {\r\n            this._applyStencilRef(bundleList);\r\n        }\r\n        if (mustUpdateBlendColor) {\r\n            this._applyBlendColor(bundleList);\r\n        }\r\n    }\r\n\r\n    private _draw(drawType: number, fillMode: number, start: number, count: number, instancesCount: number): void {\r\n        const renderPass = this._getCurrentRenderPass();\r\n        const bundleList = this._bundleList;\r\n\r\n        this.applyStates();\r\n\r\n        const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;\r\n\r\n        // Render targets are rendered Y-flipped (yFactor = -1) so a later-sampled RTT matches the WebGL\r\n        // texture-space convention. XR projection-layer targets (_disableEngineYFlip) are presented directly by\r\n        // the compositor and must be rendered upright, so they use the non-inverting UBO like the canvas.\r\n        const invertYRenderTarget = !!this._currentRenderTarget && !(this._currentRenderTarget as WebGPURenderTargetWrapper)._disableEngineYFlip;\r\n        this.bindUniformBufferBase(invertYRenderTarget ? this._ubInvertY : this._ubDontInvertY, 0, WebGPUShaderProcessor.InternalsUBOName);\r\n\r\n        this._currentDrawContext.setVertexPulling(\r\n            this._currentMaterialContext.useVertexPulling,\r\n            webgpuPipelineContext,\r\n            this._currentVertexBuffers,\r\n            this._cacheRenderPipeline.indexBuffer, // don't use this._currentIndexBuffer, it will have been set to null by _drawArraysType!\r\n            this._currentOverrideVertexBuffers\r\n        );\r\n\r\n        if (webgpuPipelineContext.uniformBuffer) {\r\n            if (this._useOwnerKeyedUniformBufferSlots) {\r\n                webgpuPipelineContext.uniformBuffer._updateOwnerKeyed(this._currentDrawContext);\r\n            } else {\r\n                webgpuPipelineContext.uniformBuffer.update();\r\n            }\r\n            this.bindUniformBufferBase(webgpuPipelineContext.uniformBuffer.getBuffer()!, 0, WebGPUShaderProcessor.LeftOvertUBOName);\r\n        }\r\n\r\n        if (this._snapshotRendering.play) {\r\n            this._reportDrawCall();\r\n            return;\r\n        }\r\n\r\n        if (\r\n            !this.compatibilityMode &&\r\n            (this._currentDrawContext.isDirty(this._currentMaterialContext.updateId) || this._currentMaterialContext.isDirty || this._currentMaterialContext.forceBindGroupCreation)\r\n        ) {\r\n            this._currentDrawContext.fastBundle = undefined;\r\n        }\r\n\r\n        const useFastPath = !this.compatibilityMode && this._currentDrawContext.fastBundle;\r\n        let renderPass2: GPURenderPassEncoder | GPURenderBundleEncoder = renderPass;\r\n\r\n        if (useFastPath || this._snapshotRendering.record) {\r\n            this._applyRenderPassChanges(bundleList);\r\n            if (!this._snapshotRendering.record) {\r\n                this._counters.numBundleReuseNonCompatMode++;\r\n                if (this._currentDrawContext.indirectDrawBuffer) {\r\n                    this._currentDrawContext.setIndirectData(count, instancesCount || 1, start);\r\n                }\r\n                bundleList.addBundle(this._currentDrawContext.fastBundle);\r\n                this._reportDrawCall();\r\n                return;\r\n            }\r\n\r\n            renderPass2 = bundleList.getBundleEncoder(this._cacheRenderPipeline.colorFormats, this._depthTextureFormat, this.currentSampleCount); // for snapshot recording mode\r\n            bundleList.numDrawCalls++;\r\n        }\r\n\r\n        let textureState = 0;\r\n        if (this._currentMaterialContext.hasFloatOrDepthTextures) {\r\n            let bitVal = 1;\r\n            for (let i = 0; i < webgpuPipelineContext.shaderProcessingContext.textureNames.length; ++i) {\r\n                const textureName = webgpuPipelineContext.shaderProcessingContext.textureNames[i];\r\n                const texture = this._currentMaterialContext.textures[textureName]?.texture;\r\n                const textureIsDepth = texture && texture.format >= Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 && texture.format <= Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8;\r\n                if ((texture?.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) || textureIsDepth) {\r\n                    textureState |= bitVal;\r\n                }\r\n                bitVal = bitVal << 1;\r\n            }\r\n        }\r\n\r\n        this._currentMaterialContext.textureState = textureState;\r\n\r\n        const pipeline = this._cacheRenderPipeline.getRenderPipeline(fillMode, this._currentEffect!, this.currentSampleCount, textureState);\r\n\r\n        const bindGroups = this._cacheBindGroups.getBindGroups(webgpuPipelineContext, this._currentDrawContext, this._currentMaterialContext);\r\n\r\n        if (!this._snapshotRendering.record) {\r\n            this._applyRenderPassChanges(!this.compatibilityMode ? bundleList : null);\r\n            if (!this.compatibilityMode) {\r\n                this._counters.numBundleCreationNonCompatMode++;\r\n                renderPass2 = this._device.createRenderBundleEncoder({\r\n                    colorFormats: this._cacheRenderPipeline.colorFormats,\r\n                    depthStencilFormat: this._depthTextureFormat,\r\n                    sampleCount: WebGPUTextureHelper.GetSample(this.currentSampleCount),\r\n                });\r\n            }\r\n        }\r\n\r\n        // bind pipeline\r\n        renderPass2.setPipeline(pipeline);\r\n\r\n        // bind index/vertex buffers\r\n        if (this._currentIndexBuffer) {\r\n            renderPass2.setIndexBuffer(\r\n                this._currentIndexBuffer.underlyingResource,\r\n                this._currentIndexBuffer.is32Bits ? WebGPUConstants.IndexFormat.Uint32 : WebGPUConstants.IndexFormat.Uint16,\r\n                0\r\n            );\r\n        }\r\n\r\n        const vertexBuffers = this._cacheRenderPipeline.vertexBuffers;\r\n        for (let index = 0; index < vertexBuffers.length; index++) {\r\n            const vertexBuffer = vertexBuffers[index];\r\n\r\n            const buffer = vertexBuffer.effectiveBuffer;\r\n            if (buffer) {\r\n                renderPass2.setVertexBuffer(index, buffer.underlyingResource, vertexBuffer._validOffsetRange ? 0 : vertexBuffer.byteOffset);\r\n            }\r\n        }\r\n\r\n        // bind bind groups\r\n        for (let i = 0; i < bindGroups.length; i++) {\r\n            renderPass2.setBindGroup(i, bindGroups[i]);\r\n        }\r\n\r\n        // draw\r\n        const nonCompatMode = !this.compatibilityMode && !this._snapshotRendering.record;\r\n\r\n        if ((nonCompatMode || this._currentDrawContext._enableIndirectDrawInCompatMode) && this._currentDrawContext.indirectDrawBuffer) {\r\n            this._currentDrawContext.setIndirectData(count, instancesCount || 1, start);\r\n            if (drawType === 0) {\r\n                renderPass2.drawIndexedIndirect(this._currentDrawContext.indirectDrawBuffer, 0);\r\n            } else {\r\n                renderPass2.drawIndirect(this._currentDrawContext.indirectDrawBuffer, 0);\r\n            }\r\n        } else if (drawType === 0) {\r\n            renderPass2.drawIndexed(count, instancesCount || 1, start, 0, 0);\r\n        } else {\r\n            renderPass2.draw(count, instancesCount || 1, start, 0);\r\n        }\r\n\r\n        if (nonCompatMode) {\r\n            this._currentDrawContext.fastBundle = (renderPass2 as GPURenderBundleEncoder).finish();\r\n            bundleList.addBundle(this._currentDrawContext.fastBundle);\r\n        }\r\n\r\n        this._reportDrawCall();\r\n    }\r\n\r\n    /**\r\n     * Draw a list of indexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param indexStart defines the starting index\r\n     * @param indexCount defines the number of index to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount: number = 1): void {\r\n        this._draw(0, fillMode, indexStart, indexCount, instancesCount);\r\n    }\r\n\r\n    /**\r\n     * Draw a list of unindexed primitives\r\n     * @param fillMode defines the primitive to use\r\n     * @param verticesStart defines the index of first vertex to draw\r\n     * @param verticesCount defines the count of vertices to draw\r\n     * @param instancesCount defines the number of instances to draw (if instantiation is enabled)\r\n     */\r\n    public drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount: number = 1): void {\r\n        this._currentIndexBuffer = null;\r\n        this._draw(1, fillMode, verticesStart, verticesCount, instancesCount);\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                        Async Pipeline Pre-Warming\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Asynchronously pre-creates one or more render pipelines so they are cached and ready\r\n     * to use without any compilation hitch when first rendered.\r\n     *\r\n     * Call this for effects and meshes that are not yet rendering but will be soon\r\n     * (e.g. streaming content, predicted material changes, pre-loading the next level).\r\n     *\r\n     * When passing an array, cache state is set once per entry and restored only at the end,\r\n     * making batch pre-warming efficient.\r\n     *\r\n     * @param options - a single options object, an array of options objects,\r\n     *                  or a raw GPURenderPipelineDescriptor for complete control\r\n     * @returns an array of Promises for the pipelines that had cache misses (empty if all were cached).\r\n     *          When a raw GPURenderPipelineDescriptor is provided, always returns a single-element array.\r\n     */\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public createRenderPipelineAsync(\r\n        options: IWebGPURenderPipelineAsyncCreationOptions | IWebGPURenderPipelineAsyncCreationOptions[] | GPURenderPipelineDescriptor\r\n    ): Promise<GPURenderPipeline>[] {\r\n        // Raw GPURenderPipelineDescriptor: bypass the cache and create directly\r\n        if (\"vertex\" in options) {\r\n            return [this._device.createRenderPipelineAsync(options as GPURenderPipelineDescriptor)];\r\n        }\r\n\r\n        const entries = Array.isArray(options) ? options : [options];\r\n        const promises: Promise<GPURenderPipeline>[] = [];\r\n        const cache = this._cacheRenderPipeline;\r\n\r\n        for (const entry of entries) {\r\n            // Render target formats\r\n            cache.setColorFormat(entry.colorFormat ?? this._colorFormat);\r\n            cache.setDepthStencilFormat(entry.depthStencilFormat ?? this._depthTextureFormat);\r\n\r\n            // Vertex / index buffers from mesh\r\n            const geometry = entry.mesh.geometry;\r\n            if (!geometry) {\r\n                throw new Error(\"WebGPUEngine.createRenderPipelineAsync: mesh has no geometry to derive vertex/index buffers from.\");\r\n            }\r\n            cache.setBuffers(geometry.getVertexBuffers(), geometry.getIndexBuffer(), null);\r\n\r\n            // Alpha / blend state\r\n            const alphaMode = entry.alphaMode ?? Constants.ALPHA_DISABLE;\r\n            if (alphaMode === Constants.ALPHA_DISABLE) {\r\n                cache.setAlphaBlendEnabled([false], 0);\r\n            } else {\r\n                const prevAlphaMode = this._alphaMode[0];\r\n                this.setAlphaMode(alphaMode);\r\n                cache.setAlphaBlendEnabled(this._alphaState._alphaBlend, this._alphaState._numTargetEnabled);\r\n                cache.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);\r\n                this.setAlphaMode(prevAlphaMode);\r\n            }\r\n\r\n            // Depth / stencil state\r\n            cache.setDepthWriteEnabled(entry.depthWrite ?? true);\r\n            cache.setDepthTestEnabled(entry.depthTest ?? true);\r\n            cache.setDepthCompare(entry.depthCompare ?? Constants.LEQUAL);\r\n\r\n            // Rasterization state\r\n            cache.setCullEnabled(entry.cullEnabled ?? true);\r\n            cache.setCullFace(entry.cullFace ?? 1);\r\n            cache.setFrontFace(entry.frontFace ?? 2);\r\n\r\n            // Write mask\r\n            cache.setWriteMask(entry.writeMask ?? 0xf);\r\n\r\n            // Stencil\r\n            cache.setStencilEnabled(entry.stencilEnabled ?? false);\r\n\r\n            const fillMode = entry.fillMode ?? Constants.MATERIAL_TriangleFillMode;\r\n            const sampleCount = entry.sampleCount ?? this.currentSampleCount;\r\n\r\n            const promise = cache.preWarmPipeline(fillMode, entry.effect, sampleCount, 0);\r\n            if (promise) {\r\n                promises.push(promise);\r\n            }\r\n        }\r\n\r\n        // Restore the cache state to the engine's current tracked state once after the entire batch\r\n        cache.setColorFormat(this._colorFormat);\r\n        cache.setDepthStencilFormat(this._depthTextureFormat);\r\n        cache.setBuffers(this._currentVertexBuffers ?? null, this._currentIndexBuffer, this._currentOverrideVertexBuffers ?? null);\r\n        cache.setDepthCullingState(\r\n            this._depthCullingState.cull ?? false,\r\n            this._depthCullingState.frontFace ?? 2,\r\n            this._depthCullingState.cullFace ?? 1,\r\n            this._depthCullingState.zOffset,\r\n            this._depthCullingState.zOffsetUnits,\r\n            this._depthCullingState.depthTest ?? true,\r\n            this._depthCullingState.depthMask ?? true,\r\n            this._depthCullingState.depthFunc\r\n        );\r\n        cache.setAlphaBlendEnabled(this._alphaState._alphaBlend, this._alphaState._numTargetEnabled);\r\n        cache.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);\r\n        cache.setStencilEnabled(this._stencilStateComposer.enabled ?? false);\r\n        cache.setWriteMask(this._colorWrite ? 0xf : 0);\r\n\r\n        return promises;\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Dispose\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Dispose and release all associated resources\r\n     */\r\n    public override dispose(): void {\r\n        this._isDisposed = true;\r\n        this.hideLoadingUI?.();\r\n        this._timestampQuery.dispose();\r\n        this._mainTexture?.destroy();\r\n        this._depthTexture?.destroy();\r\n        this._textureHelper.destroyDeferredTextures();\r\n        this._bufferManager.destroyDeferredBuffers();\r\n        this._device.destroy();\r\n\r\n        _CommonDispose(this, this._renderingCanvas);\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Misc\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Gets the current render width\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render width\r\n     */\r\n    public getRenderWidth(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.width;\r\n        }\r\n\r\n        return this._renderingCanvas?.width ?? 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current render height\r\n     * @param useScreen defines if screen size must be used (or the current render target if any)\r\n     * @returns a number defining the current render height\r\n     */\r\n    public getRenderHeight(useScreen = false): number {\r\n        if (!useScreen && this._currentRenderTarget) {\r\n            return this._currentRenderTarget.height;\r\n        }\r\n\r\n        return this._renderingCanvas?.height ?? 0;\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Errors\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Get the current error code of the WebGPU context\r\n     * @returns the error code\r\n     */\r\n    public getError(): number {\r\n        // TODO WEBGPU. from the webgpu errors.\r\n        return 0;\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              External Textures\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Creates an external texture\r\n     * @param video video element\r\n     * @returns the external texture, or null if external textures are not supported by the engine\r\n     */\r\n    public createExternalTexture(video: HTMLVideoElement): Nullable<ExternalTexture> {\r\n        const texture = new WebGPUExternalTexture(video);\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Sets an internal texture to the according uniform.\r\n     * @param name The name of the uniform in the effect\r\n     * @param texture The texture to apply\r\n     */\r\n    public setExternalTexture(name: string, texture: Nullable<ExternalTexture>): void {\r\n        if (!texture) {\r\n            this._currentMaterialContext.setTexture(name, null);\r\n            return;\r\n        }\r\n        this._setInternalTexture(name, texture);\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Samplers\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Sets a texture sampler to the according uniform.\r\n     * @param name The name of the uniform in the effect\r\n     * @param sampler The sampler to apply\r\n     */\r\n    public setTextureSampler(name: string, sampler: Nullable<TextureSampler>): void {\r\n        this._currentMaterialContext?.setSampler(name, sampler);\r\n    }\r\n\r\n    //------------------------------------------------------------------------------\r\n    //                              Storage Buffers\r\n    //------------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Creates a storage buffer\r\n     * @param data the data for the storage buffer or the size of the buffer\r\n     * @param creationFlags flags to use when creating the buffer (see Constants.BUFFER_CREATIONFLAG_XXX). The BUFFER_CREATIONFLAG_STORAGE flag will be automatically added\r\n     * @param label defines the label of the buffer (for debug purpose)\r\n     * @returns the new buffer\r\n     */\r\n    public createStorageBuffer(data: DataArray | number, creationFlags: number, label?: string): DataBuffer {\r\n        return this._createBuffer(data, creationFlags | Constants.BUFFER_CREATIONFLAG_STORAGE, label);\r\n    }\r\n\r\n    /**\r\n     * Clears a storage buffer to zeroes\r\n     * @param storageBuffer the storage buffer to clear\r\n     * @param byteOffset the byte offset to start clearing (optional)\r\n     * @param byteLength the byte length to clear (optional)\r\n     */\r\n    public clearStorageBuffer(storageBuffer: DataBuffer, byteOffset?: number, byteLength?: number): void {\r\n        // clearBuffer is a command encoder operation and cannot be recorded while a render pass is open on the same encoder.\r\n        this._endCurrentRenderPass();\r\n        this._renderEncoder.clearBuffer(storageBuffer.underlyingResource, byteOffset, byteLength);\r\n    }\r\n\r\n    /**\r\n     * Updates a storage buffer\r\n     * @param buffer the storage buffer to update\r\n     * @param data the data used to update the storage buffer\r\n     * @param byteOffset the byte offset of the data\r\n     * @param byteLength the byte length of the data\r\n     */\r\n    public updateStorageBuffer(buffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void {\r\n        const dataBuffer = buffer as WebGPUDataBuffer;\r\n        if (byteOffset === undefined) {\r\n            byteOffset = 0;\r\n        }\r\n\r\n        let view: ArrayBufferView;\r\n        if (byteLength === undefined) {\r\n            if (data instanceof Array) {\r\n                view = new Float32Array(data);\r\n            } else if (ArrayBuffer.isView(data)) {\r\n                view = data;\r\n            } else {\r\n                view = new Uint8Array(data);\r\n            }\r\n            byteLength = view.byteLength;\r\n        } else {\r\n            if (data instanceof Array) {\r\n                view = new Float32Array(data);\r\n            } else if (ArrayBuffer.isView(data)) {\r\n                view = data;\r\n            } else {\r\n                view = new Uint8Array(data);\r\n            }\r\n        }\r\n\r\n        this._bufferManager.setSubData(dataBuffer, byteOffset, view, 0, byteLength);\r\n    }\r\n\r\n    private async _readFromGPUBuffer(gpuBuffer: GPUBuffer, size: number, buffer?: ArrayBufferView, noDelay?: boolean): Promise<ArrayBufferView> {\r\n        return await new Promise((resolve, reject) => {\r\n            const readFromBuffer = () => {\r\n                // eslint-disable-next-line github/no-then\r\n                gpuBuffer.mapAsync(WebGPUConstants.MapMode.Read, 0, size).then(\r\n                    () => {\r\n                        const copyArrayBuffer = gpuBuffer.getMappedRange(0, size);\r\n                        let data: ArrayBufferView | undefined = buffer;\r\n                        if (data === undefined) {\r\n                            data = new Uint8Array(size);\r\n                            (data as Uint8Array).set(new Uint8Array(copyArrayBuffer));\r\n                        } else {\r\n                            const ctor = data.constructor as any; // we want to create result data with the same type as buffer (Uint8Array, Float32Array, ...)\r\n                            data = new ctor(data.buffer);\r\n                            (data as any).set(new ctor(copyArrayBuffer));\r\n                        }\r\n                        gpuBuffer.unmap();\r\n                        this._bufferManager.releaseBuffer(gpuBuffer);\r\n                        resolve(data!);\r\n                    },\r\n                    (reason) => {\r\n                        if (this.isDisposed) {\r\n                            resolve(new Uint8Array());\r\n                        } else {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            reject(reason);\r\n                        }\r\n                    }\r\n                );\r\n            };\r\n\r\n            if (noDelay) {\r\n                this.flushFramebuffer();\r\n                readFromBuffer();\r\n            } else {\r\n                // we are using onEndFrameObservable because we need to map the gpuBuffer AFTER the command buffers\r\n                // have been submitted, else we get the error: \"Buffer used in a submit while mapped\"\r\n                this.onEndFrameObservable.addOnce(() => {\r\n                    readFromBuffer();\r\n                });\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Read data from a storage buffer\r\n     * @param storageBuffer The storage buffer to read from\r\n     * @param offset The offset in the storage buffer to start reading from (default: 0)\r\n     * @param size  The number of bytes to read from the storage buffer (default: capacity of the buffer)\r\n     * @param buffer The buffer to write the data we have read from the storage buffer to (optional)\r\n     * @param noDelay If true, a call to flushFramebuffer will be issued so that the data can be read back immediately and not in engine.onEndFrameObservable. This can speed up data retrieval, at the cost of a small perf penalty (default: false).\r\n     * @returns If not undefined, returns the (promise) buffer (as provided by the 4th parameter) filled with the data, else it returns a (promise) Uint8Array with the data read from the storage buffer\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n    public readFromStorageBuffer(storageBuffer: DataBuffer, offset?: number, size?: number, buffer?: ArrayBufferView, noDelay?: boolean): Promise<ArrayBufferView> {\r\n        size = size || storageBuffer.capacity;\r\n\r\n        const gpuBuffer = this._bufferManager.createRawBuffer(\r\n            size,\r\n            WebGPUConstants.BufferUsage.MapRead | WebGPUConstants.BufferUsage.CopyDst,\r\n            undefined,\r\n            \"TempReadFromStorageBuffer\"\r\n        );\r\n\r\n        this._renderEncoder.copyBufferToBuffer(storageBuffer.underlyingResource, offset ?? 0, gpuBuffer, 0, size);\r\n\r\n        return this._readFromGPUBuffer(gpuBuffer, size, buffer, noDelay);\r\n    }\r\n\r\n    /**\r\n     * Read data from multiple storage buffers\r\n     * @param storageBuffers The list of storage buffers to read from\r\n     * @param offset The offset in the storage buffer to start reading from (default: 0). This is the same offset for all storage buffers!\r\n     * @param size  The number of bytes to read from each storage buffer (default: capacity of the first buffer)\r\n     * @param buffer The buffer to write the data we have read from the storage buffers to (optional). If provided, the buffer should be large enough to hold the data from all storage buffers!\r\n     * @param noDelay If true, a call to flushFramebuffer will be issued so that the data can be read back immediately and not in engine.onEndFrameObservable. This can speed up data retrieval, at the cost of a small perf penalty (default: false).\r\n     * @returns If not undefined, returns the (promise) buffer (as provided by the 4th parameter) filled with the data, else it returns a (promise) Uint8Array with the data read from the storage buffer\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n    public readFromMultipleStorageBuffers(storageBuffers: DataBuffer[], offset?: number, size?: number, buffer?: ArrayBufferView, noDelay?: boolean): Promise<ArrayBufferView> {\r\n        size = size || storageBuffers[0].capacity;\r\n\r\n        const gpuBuffer = this._bufferManager.createRawBuffer(\r\n            size * storageBuffers.length,\r\n            WebGPUConstants.BufferUsage.MapRead | WebGPUConstants.BufferUsage.CopyDst,\r\n            undefined,\r\n            \"TempReadFromMultipleStorageBuffers\"\r\n        );\r\n\r\n        for (let i = 0; i < storageBuffers.length; i++) {\r\n            this._renderEncoder.copyBufferToBuffer(storageBuffers[i].underlyingResource, offset ?? 0, gpuBuffer, i * size, size);\r\n        }\r\n\r\n        return this._readFromGPUBuffer(gpuBuffer, size * storageBuffers.length, buffer, noDelay);\r\n    }\r\n\r\n    /**\r\n     * Sets a storage buffer in the shader\r\n     * @param name Defines the name of the storage buffer as defined in the shader\r\n     * @param buffer Defines the value to give to the uniform\r\n     */\r\n    public setStorageBuffer(name: string, buffer: Nullable<StorageBuffer>): void {\r\n        this._currentDrawContext?.setBuffer(name, (buffer?.getBuffer() as WebGPUDataBuffer) ?? null);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport * as WebGPUConstants from \"../webgpuConstants\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type IComputeEffectCreationOptions, type IComputeShaderPath, ComputeEffect } from \"../../../Compute/computeEffect\";\r\nimport { type IComputeContext } from \"../../../Compute/IComputeContext\";\r\nimport { type IComputePipelineContext } from \"../../../Compute/IComputePipelineContext\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { ComputeBindingType, type ComputeBindingList, type ComputeBindingMapping, type ComputeCompilationMessages } from \"../../Extensions/engine.computeShader.pure\";\r\nimport { Constants } from \"../../constants\";\r\nimport { WebGPUComputeContext } from \"../webgpuComputeContext\";\r\nimport { WebGPUComputePipelineContext } from \"../webgpuComputePipelineContext\";\r\nimport { type WebGPUPerfCounter } from \"../webgpuPerfCounter\";\r\nimport { type DataBuffer } from \"../../../Buffers/dataBuffer\";\r\nimport { WebGPUEngine } from \"../../webgpuEngine.pure\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type BaseTexture } from \"../../../Materials/Textures/baseTexture.pure\";\r\n\r\nlet _Registered = false;\r\n\r\nconst _GetComputeStorageBufferType = (source: string, group: number, binding: number): WebGPUConstants.BufferBindingType => {\r\n    const bindingPattern = `@binding\\\\(${binding}\\\\)\\\\s*@group\\\\(${group}\\\\)`;\r\n    const groupPattern = `@group\\\\(${group}\\\\)\\\\s*@binding\\\\(${binding}\\\\)`;\r\n    const declarationPattern = `(?:${bindingPattern}|${groupPattern})\\\\s*var<storage\\\\s*,\\\\s*(read|read_write)>`;\r\n    const access = source.match(new RegExp(declarationPattern))?.[1];\r\n\r\n    return access === \"read\" ? WebGPUConstants.BufferBindingType.ReadOnlyStorage : WebGPUConstants.BufferBindingType.Storage;\r\n};\r\n\r\nconst _GetComputeTextureViewDimension = (source: string, group: number, binding: number): WebGPUConstants.TextureViewDimension => {\r\n    const bindingPattern = `@binding\\\\(${binding}\\\\)\\\\s*@group\\\\(${group}\\\\)`;\r\n    const groupPattern = `@group\\\\(${group}\\\\)\\\\s*@binding\\\\(${binding}\\\\)`;\r\n    const declaration = source.match(new RegExp(`(?:${bindingPattern}|${groupPattern})\\\\s*var\\\\s+\\\\w+\\\\s*:\\\\s*(texture_\\\\w+)`))?.[1];\r\n\r\n    switch (declaration) {\r\n        case \"texture_2d_array\":\r\n        case \"texture_depth_2d_array\":\r\n            return WebGPUConstants.TextureViewDimension.E2dArray;\r\n        case \"texture_cube\":\r\n            return WebGPUConstants.TextureViewDimension.Cube;\r\n        case \"texture_cube_array\":\r\n            return WebGPUConstants.TextureViewDimension.CubeArray;\r\n        case \"texture_3d\":\r\n            return WebGPUConstants.TextureViewDimension.E3d;\r\n        default:\r\n            return WebGPUConstants.TextureViewDimension.E2d;\r\n    }\r\n};\r\n\r\nconst _GetInternalTexture = (texture: BaseTexture | InternalTexture): Nullable<InternalTexture> => {\r\n    const internalTexture = texture as InternalTexture;\r\n    if (internalTexture._hardwareTexture !== undefined) {\r\n        return internalTexture;\r\n    }\r\n\r\n    return (texture as BaseTexture)._texture;\r\n};\r\n\r\nconst _GetComputeTextureSampleType = (texture: BaseTexture | InternalTexture, textureFloatLinearFiltering: boolean): WebGPUConstants.TextureSampleType => {\r\n    const internalTexture = _GetInternalTexture(texture);\r\n\r\n    if (!internalTexture) {\r\n        return WebGPUConstants.TextureSampleType.Float;\r\n    }\r\n\r\n    const textureIsDepth = internalTexture.format >= Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 && internalTexture.format <= Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8;\r\n    if (textureIsDepth) {\r\n        return WebGPUConstants.TextureSampleType.Depth;\r\n    }\r\n\r\n    if (internalTexture.type === Constants.TEXTURETYPE_FLOAT && !textureFloatLinearFiltering) {\r\n        return WebGPUConstants.TextureSampleType.UnfilterableFloat;\r\n    }\r\n\r\n    return WebGPUConstants.TextureSampleType.Float;\r\n};\r\n\r\nconst _GetComputePipelineLayout = (\r\n    device: GPUDevice,\r\n    bindings: ComputeBindingList,\r\n    bindingsMapping: ComputeBindingMapping | undefined,\r\n    shaderSource: string,\r\n    textureFloatLinearFiltering: boolean\r\n): Nullable<GPUPipelineLayout> => {\r\n    if (!bindingsMapping) {\r\n        return null;\r\n    }\r\n\r\n    const bindGroupLayoutEntries: GPUBindGroupLayoutEntry[][] = [];\r\n\r\n    const addEntry = (group: number, entry: GPUBindGroupLayoutEntry) => {\r\n        const entries = (bindGroupLayoutEntries[group] ??= []);\r\n        const existingIndex = entries.findIndex((item) => item.binding === entry.binding);\r\n        if (existingIndex >= 0) {\r\n            entries[existingIndex] = entry;\r\n        } else {\r\n            entries.push(entry);\r\n        }\r\n    };\r\n\r\n    for (const key in bindings) {\r\n        const binding = bindings[key];\r\n        const location = bindingsMapping[key];\r\n        if (!location) {\r\n            continue;\r\n        }\r\n\r\n        const group = location.group;\r\n        const bindingIndex = location.binding;\r\n\r\n        switch (binding.type) {\r\n            case ComputeBindingType.Texture:\r\n            case ComputeBindingType.TextureWithoutSampler:\r\n            case ComputeBindingType.InternalTexture: {\r\n                const sampleType = _GetComputeTextureSampleType(binding.object as BaseTexture | InternalTexture, textureFloatLinearFiltering);\r\n\r\n                if (binding.type === ComputeBindingType.Texture) {\r\n                    addEntry(group, {\r\n                        binding: bindingIndex - 1,\r\n                        visibility: WebGPUConstants.ShaderStage.Compute,\r\n                        sampler: {\r\n                            type:\r\n                                sampleType === WebGPUConstants.TextureSampleType.UnfilterableFloat\r\n                                    ? WebGPUConstants.SamplerBindingType.NonFiltering\r\n                                    : WebGPUConstants.SamplerBindingType.Filtering,\r\n                        },\r\n                    });\r\n                }\r\n\r\n                addEntry(group, {\r\n                    binding: bindingIndex,\r\n                    visibility: WebGPUConstants.ShaderStage.Compute,\r\n                    texture: {\r\n                        sampleType,\r\n                        viewDimension: _GetComputeTextureViewDimension(shaderSource, group, bindingIndex),\r\n                        multisampled: false,\r\n                    },\r\n                });\r\n                break;\r\n            }\r\n            case ComputeBindingType.StorageTexture: {\r\n                addEntry(group, {\r\n                    binding: bindingIndex,\r\n                    visibility: WebGPUConstants.ShaderStage.Compute,\r\n                    storageTexture: {\r\n                        access: WebGPUConstants.StorageTextureAccess.WriteOnly,\r\n                        format: ((binding.object as BaseTexture)._texture!._hardwareTexture as any).format,\r\n                        viewDimension: _GetComputeTextureViewDimension(shaderSource, group, bindingIndex),\r\n                    },\r\n                });\r\n                break;\r\n            }\r\n            case ComputeBindingType.UniformBuffer:\r\n                addEntry(group, {\r\n                    binding: bindingIndex,\r\n                    visibility: WebGPUConstants.ShaderStage.Compute,\r\n                    buffer: { type: WebGPUConstants.BufferBindingType.Uniform },\r\n                });\r\n                break;\r\n            case ComputeBindingType.StorageBuffer:\r\n            case ComputeBindingType.DataBuffer:\r\n                addEntry(group, {\r\n                    binding: bindingIndex,\r\n                    visibility: WebGPUConstants.ShaderStage.Compute,\r\n                    buffer: { type: _GetComputeStorageBufferType(shaderSource, group, bindingIndex) },\r\n                });\r\n                break;\r\n            case ComputeBindingType.Sampler:\r\n                addEntry(group, {\r\n                    binding: bindingIndex,\r\n                    visibility: WebGPUConstants.ShaderStage.Compute,\r\n                    sampler: { type: WebGPUConstants.SamplerBindingType.Filtering },\r\n                });\r\n                break;\r\n            case ComputeBindingType.ExternalTexture:\r\n                addEntry(group, {\r\n                    binding: bindingIndex,\r\n                    visibility: WebGPUConstants.ShaderStage.Compute,\r\n                    externalTexture: {},\r\n                });\r\n                break;\r\n        }\r\n    }\r\n\r\n    const bindGroupLayouts: GPUBindGroupLayout[] = [];\r\n    for (let i = 0; i < bindGroupLayoutEntries.length; i++) {\r\n        const entries = bindGroupLayoutEntries[i] ?? [];\r\n        entries.sort((a, b) => a.binding - b.binding);\r\n        bindGroupLayouts[i] = device.createBindGroupLayout({ entries });\r\n    }\r\n\r\n    return device.createPipelineLayout({ bindGroupLayouts });\r\n};\r\n\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineComputeShader.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineComputeShader(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const ComputePassDescriptor: GPUComputePassDescriptor = {};\r\n\r\n    WebGPUEngine.prototype.createComputeContext = function (): IComputeContext | undefined {\r\n        return new WebGPUComputeContext(this._device, this._cacheSampler);\r\n    };\r\n\r\n    WebGPUEngine.prototype.createComputeEffect = function (\r\n        baseName: string | (IComputeShaderPath & { computeToken?: string }),\r\n        options: IComputeEffectCreationOptions\r\n    ): ComputeEffect {\r\n        const compute = typeof baseName === \"string\" ? baseName : baseName.computeToken || baseName.computeSource || baseName.computeElement || baseName.compute;\r\n\r\n        const name = compute + \"@\" + options.defines + (options.useExplicitComputePipelineLayout ? \"@explicitComputePipelineLayout\" : \"\");\r\n        if (this._compiledComputeEffects[name]) {\r\n            const compiledEffect = this._compiledComputeEffects[name];\r\n            if (options.onCompiled && compiledEffect.isReady()) {\r\n                options.onCompiled(compiledEffect);\r\n            }\r\n\r\n            return compiledEffect;\r\n        }\r\n        const effect = new ComputeEffect(baseName, options, this, name);\r\n        this._compiledComputeEffects[name] = effect;\r\n\r\n        return effect;\r\n    };\r\n\r\n    WebGPUEngine.prototype.createComputePipelineContext = function (): IComputePipelineContext {\r\n        return new WebGPUComputePipelineContext(this);\r\n    };\r\n\r\n    WebGPUEngine.prototype.areAllComputeEffectsReady = function (): boolean {\r\n        for (const key in this._compiledComputeEffects) {\r\n            const effect = this._compiledComputeEffects[key];\r\n\r\n            if (!effect.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    };\r\n\r\n    WebGPUEngine.prototype.computeDispatch = function (\r\n        effect: ComputeEffect,\r\n        context: IComputeContext,\r\n        bindings: ComputeBindingList,\r\n        x: number,\r\n        y = 1,\r\n        z = 1,\r\n        bindingsMapping?: ComputeBindingMapping,\r\n        gpuPerfCounter?: WebGPUPerfCounter\r\n    ): void {\r\n        this._computeDispatch(effect, context, bindings, x, y, z, undefined, undefined, bindingsMapping, gpuPerfCounter);\r\n    };\r\n\r\n    WebGPUEngine.prototype.computeDispatchIndirect = function (\r\n        effect: ComputeEffect,\r\n        context: IComputeContext,\r\n        bindings: ComputeBindingList,\r\n        buffer: DataBuffer,\r\n        offset: number = 0,\r\n        bindingsMapping?: ComputeBindingMapping,\r\n        gpuPerfCounter?: WebGPUPerfCounter\r\n    ): void {\r\n        this._computeDispatch(effect, context, bindings, undefined, undefined, undefined, buffer, offset, bindingsMapping, gpuPerfCounter);\r\n    };\r\n\r\n    WebGPUEngine.prototype._computeDispatch = function (\r\n        effect: ComputeEffect,\r\n        context: IComputeContext,\r\n        bindings: ComputeBindingList,\r\n        x?: number,\r\n        y?: number,\r\n        z?: number,\r\n        buffer?: DataBuffer,\r\n        offset?: number,\r\n        bindingsMapping?: ComputeBindingMapping,\r\n        gpuPerfCounter?: WebGPUPerfCounter\r\n    ): void {\r\n        this._endCurrentRenderPass();\r\n\r\n        const contextPipeline = effect._pipelineContext as WebGPUComputePipelineContext;\r\n        const computeContext = context as WebGPUComputeContext;\r\n\r\n        if (!contextPipeline.computePipeline) {\r\n            const explicitLayout = effect._useExplicitComputePipelineLayout\r\n                ? _GetComputePipelineLayout(this._device, bindings, bindingsMapping, contextPipeline.sources?.compute ?? \"\", this._caps.textureFloatLinearFiltering)\r\n                : null;\r\n            computeContext.clear();\r\n            contextPipeline.computePipeline = this._device.createComputePipeline({\r\n                layout: explicitLayout ?? WebGPUConstants.AutoLayoutMode.Auto,\r\n                compute: contextPipeline.stage!,\r\n            });\r\n        }\r\n\r\n        if (gpuPerfCounter) {\r\n            this._timestampQuery.startPass(ComputePassDescriptor, this._timestampIndex);\r\n        }\r\n\r\n        const computePass = this._renderEncoder.beginComputePass(ComputePassDescriptor);\r\n\r\n        computePass.setPipeline(contextPipeline.computePipeline);\r\n\r\n        const bindGroups = computeContext.getBindGroups(bindings, contextPipeline.computePipeline, bindingsMapping);\r\n        for (let i = 0; i < bindGroups.length; ++i) {\r\n            const bindGroup = bindGroups[i];\r\n            if (!bindGroup) {\r\n                continue;\r\n            }\r\n            computePass.setBindGroup(i, bindGroup);\r\n        }\r\n\r\n        if (buffer !== undefined) {\r\n            computePass.dispatchWorkgroupsIndirect(buffer.underlyingResource, <number>offset);\r\n        } else {\r\n            if (<number>x + <number>y + <number>z > 0) {\r\n                computePass.dispatchWorkgroups(<number>x, <number>y, <number>z);\r\n            }\r\n        }\r\n        computePass.end();\r\n\r\n        if (gpuPerfCounter) {\r\n            this._timestampQuery.endPass(this._timestampIndex, gpuPerfCounter);\r\n            this._timestampIndex += 2;\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype.releaseComputeEffects = function () {\r\n        for (const name in this._compiledComputeEffects) {\r\n            const webGPUPipelineContextCompute = this._compiledComputeEffects[name].getPipelineContext() as WebGPUComputePipelineContext;\r\n            this._deleteComputePipelineContext(webGPUPipelineContextCompute);\r\n        }\r\n\r\n        this._compiledComputeEffects = {};\r\n    };\r\n\r\n    WebGPUEngine.prototype._prepareComputePipelineContext = function (\r\n        pipelineContext: IComputePipelineContext,\r\n        computeSourceCode: string,\r\n        rawComputeSourceCode: string,\r\n        defines: Nullable<string>,\r\n        entryPoint: string\r\n    ): void {\r\n        const webGpuContext = pipelineContext as WebGPUComputePipelineContext;\r\n\r\n        if (this.dbgShowShaderCode) {\r\n            Logger.Log(defines!);\r\n            Logger.Log(computeSourceCode);\r\n        }\r\n\r\n        webGpuContext.sources = {\r\n            compute: computeSourceCode,\r\n            rawCompute: rawComputeSourceCode,\r\n        };\r\n\r\n        webGpuContext.stage = this._createComputePipelineStageDescriptor(computeSourceCode, defines, entryPoint);\r\n    };\r\n\r\n    WebGPUEngine.prototype._releaseComputeEffect = function (effect: ComputeEffect): void {\r\n        if (this._compiledComputeEffects[effect._key]) {\r\n            delete this._compiledComputeEffects[effect._key];\r\n\r\n            this._deleteComputePipelineContext(effect.getPipelineContext() as WebGPUComputePipelineContext);\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype._rebuildComputeEffects = function (): void {\r\n        for (const key in this._compiledComputeEffects) {\r\n            const effect = this._compiledComputeEffects[key];\r\n\r\n            effect._pipelineContext = null;\r\n            effect._wasPreviouslyReady = false;\r\n            effect._prepareEffect();\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype._executeWhenComputeStateIsCompiled = function (\r\n        pipelineContext: WebGPUComputePipelineContext,\r\n        action: (messages: Nullable<ComputeCompilationMessages>) => void\r\n    ): void {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        pipelineContext.stage!.module.getCompilationInfo().then((info) => {\r\n            const compilationMessages: ComputeCompilationMessages = {\r\n                numErrors: 0,\r\n                messages: [],\r\n            };\r\n            for (const message of info.messages) {\r\n                if (message.type === \"error\") {\r\n                    compilationMessages.numErrors++;\r\n                }\r\n                compilationMessages.messages.push({\r\n                    type: message.type,\r\n                    text: message.message,\r\n                    line: message.lineNum,\r\n                    column: message.linePos,\r\n                    length: message.length,\r\n                    offset: message.offset,\r\n                });\r\n            }\r\n            action(compilationMessages);\r\n        });\r\n    };\r\n\r\n    WebGPUEngine.prototype._deleteComputePipelineContext = function (pipelineContext: IComputePipelineContext): void {\r\n        const webgpuPipelineContext = pipelineContext as WebGPUComputePipelineContext;\r\n        if (webgpuPipelineContext) {\r\n            pipelineContext.dispose();\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype._createComputePipelineStageDescriptor = function (computeShader: string, defines: Nullable<string>, entryPoint: string): GPUProgrammableStage {\r\n        if (defines) {\r\n            defines = \"//\" + defines.split(\"\\n\").join(\"\\n//\") + \"\\n\";\r\n        } else {\r\n            defines = \"\";\r\n        }\r\n        return {\r\n            module: this._device.createShaderModule({\r\n                code: defines + computeShader,\r\n            }),\r\n            entryPoint,\r\n        };\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Constants } from \"../../constants\";\r\nimport { type DepthTextureCreationOptions } from \"../../../Materials/Textures/textureCreationOptions\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\nimport { WebGPUTextureHelper } from \"../webgpuTextureHelper\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype._createDepthStencilCubeTexture = function (size: number, options: DepthTextureCreationOptions): InternalTexture {\r\n        const internalTexture = new InternalTexture(this, options.generateStencil ? InternalTextureSource.DepthStencil : InternalTextureSource.Depth);\r\n\r\n        internalTexture.isCube = true;\r\n        internalTexture.label = options.label;\r\n\r\n        const internalOptions = {\r\n            bilinearFiltering: false,\r\n            comparisonFunction: 0,\r\n            generateStencil: false,\r\n            samples: 1,\r\n            depthTextureFormat: options.generateStencil ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n            ...options,\r\n        };\r\n\r\n        internalTexture.format = internalOptions.depthTextureFormat;\r\n\r\n        this._setupDepthStencilTexture(internalTexture, size, internalOptions.bilinearFiltering, internalOptions.comparisonFunction, internalOptions.samples);\r\n\r\n        this._textureHelper.createGPUTextureForInternalTexture(internalTexture);\r\n\r\n        // Now that the hardware texture is created, we can retrieve the GPU format and set the right type to the internal texture\r\n        const gpuTextureWrapper = internalTexture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        internalTexture.type = WebGPUTextureHelper.GetTextureTypeFromFormat(gpuTextureWrapper.format);\r\n\r\n        this._internalTexturesCache.push(internalTexture);\r\n\r\n        return internalTexture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createCubeTexture = function (\r\n        rootUrl: string,\r\n        scene: Nullable<Scene>,\r\n        files: Nullable<string[]>,\r\n        noMipmap?: boolean,\r\n        onLoad: Nullable<(data?: any) => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        format?: number,\r\n        forcedExtension: any = null,\r\n        createPolynomials: boolean = false,\r\n        lodScale: number = 0,\r\n        lodOffset: number = 0,\r\n        fallback: Nullable<InternalTexture> = null,\r\n        loaderOptions?: any,\r\n        useSRGBBuffer = false,\r\n        buffer: Nullable<ArrayBufferView> = null\r\n    ): InternalTexture {\r\n        return this.createCubeTextureBase(\r\n            rootUrl,\r\n            scene,\r\n            files,\r\n            !!noMipmap,\r\n            onLoad,\r\n            onError,\r\n            format,\r\n            forcedExtension,\r\n            createPolynomials,\r\n            lodScale,\r\n            lodOffset,\r\n            fallback,\r\n            null,\r\n            (texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => {\r\n                const imageBitmaps = imgs as ImageBitmap[]; // we will always get an ImageBitmap array in WebGPU\r\n                const width = imageBitmaps[0].width;\r\n                const height = width;\r\n\r\n                this._setCubeMapTextureParams(texture, !noMipmap);\r\n                texture.format = format ?? -1;\r\n\r\n                const gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture, width, height);\r\n\r\n                this._textureHelper.updateCubeTextures(imageBitmaps, texture, width, height, gpuTextureWrapper.format, false, false, 0, 0);\r\n\r\n                if (!noMipmap) {\r\n                    this._generateMipmaps(texture, this._uploadEncoder);\r\n                }\r\n\r\n                texture.isReady = true;\r\n\r\n                texture.onLoadedObservable.notifyObservers(texture);\r\n                texture.onLoadedObservable.clear();\r\n\r\n                if (onLoad) {\r\n                    onLoad();\r\n                }\r\n            },\r\n            !!useSRGBBuffer,\r\n            buffer\r\n        );\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype._setCubeMapTextureParams = function (texture: InternalTexture, loadMipmap: boolean, maxLevel?: number) {\r\n        texture.samplingMode = loadMipmap ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n        texture._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        texture._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        if (maxLevel) {\r\n            texture._maxLodLevel = maxLevel;\r\n        }\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.generateMipMapsForCubemap = function (texture: InternalTexture) {\r\n        if (texture.generateMipMaps) {\r\n            const gpuTexture = texture._hardwareTexture?.underlyingResource;\r\n\r\n            if (!gpuTexture) {\r\n                this._textureHelper.createGPUTextureForInternalTexture(texture);\r\n            }\r\n\r\n            this._generateMipmaps(texture);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * # WebGPU Debug Marker Implementation — Problem Statement\r\n *\r\n * ## Background\r\n *\r\n * WebGPU exposes `pushDebugGroup` / `popDebugGroup` on two distinct objects:\r\n *   - The **render encoder** (`GPUCommandEncoder`), which lives for the lifetime of an entire\r\n *     submission (one call to `flushFramebuffer`).\r\n *   - The **render pass encoder** (`GPURenderPassEncoder`), which lives only for the duration of\r\n *     a single render pass.\r\n *\r\n * WebGPU requires that every push/pop pair is issued on the **same** object, and that all open\r\n * groups are closed before the object ends. Violating either rule is a validation error.\r\n *\r\n * ## The Core Problem\r\n *\r\n * From the Babylon.js side, the user calls `_debugPushGroup` / `_debugPopGroup` at arbitrary\r\n * points in time — completely independently of whether a render pass is currently active or not.\r\n * This creates several mismatched-context scenarios that must be handled transparently.\r\n *\r\n * ## Scenario 1 — Push on render encoder, pop inside a render pass\r\n *\r\n *   1. User calls `_debugPushGroup` while no render pass is active → group is pushed on the\r\n *      render encoder and recorded in `_debugMarkersEncoderGroups`.\r\n *   2. A render pass starts (`_currentRenderPass` becomes non-null).\r\n *   3. User calls `_debugPopGroup` while the render pass is active. The pop must logically target\r\n *      the render encoder group, but we cannot call `popDebugGroup` on the render encoder while a\r\n *      render pass is active (the pass is the live object).\r\n *   4. We detect this mismatch because `_debugMarkersPassGroups` is empty (no group was pushed\r\n *      during this render pass), so we increment `_debugMarkersPendingEncoderPops` instead of\r\n *      issuing the pop immediately.\r\n *   5. When the render pass ends (`_endCurrentRenderPass`), `_debugPendingPop` drains the\r\n *      `_debugMarkersPendingEncoderPops` counter and issues the deferred pops on the render encoder.\r\n *\r\n *   **Edge case — deferred pop followed by a render-pass push:** if the user pushes another group\r\n *   during the same render pass *after* the deferred pop was recorded, that new group goes into\r\n *   `_debugMarkersPassGroups`. When the pass ends, `_debugPopBeforeEndOfEncoder` auto-pops the\r\n *   pass-level group, leaving it floating in `_debugMarkersPassGroups`. `_debugPendingPop` then\r\n *   pops from `_debugMarkersEncoderGroups` — a separate array that can never contain pass-level\r\n *   entries — so the floating pass-level group is preserved intact and will be re-pushed on the\r\n *   next render pass by `_debugPushAfterStartOfEncoder`.\r\n *\r\n * ## Scenario 2 — Push inside a render pass, render pass ends before pop\r\n *\r\n *   1. User calls `_debugPushGroup` while a render pass is active → group is pushed on the render\r\n *      pass encoder and recorded in `_debugMarkersPassGroups`.\r\n *   2. The render pass ends (e.g. a new render target is bound) before the user calls\r\n *      `_debugPopGroup`. All open render-pass groups must be closed before\r\n *      `GPURenderPassEncoder.end()` is called.\r\n *   3. `_debugPopBeforeEndOfEncoder` auto-pops every group in `_debugMarkersPassGroups` from the\r\n *      render pass encoder. The names remain in `_debugMarkersPassGroups` (the array is not\r\n *      cleared) so the logical nesting is preserved and the groups are now \"floating\".\r\n *   4. After the next render pass is created, `_debugPushAfterStartOfEncoder` re-pushes all\r\n *      floating pass groups onto it, so that when the user eventually calls `_debugPopGroup`\r\n *      there is always a matching push on the current live object.\r\n *\r\n * ## Scenario 3 — `flushFramebuffer` called mid-frame (multiple times per frame)\r\n *\r\n *   `flushFramebuffer` submits all recorded GPU commands and creates a brand-new pair of encoders.\r\n *   It can be called more than once during a single Babylon.js frame (e.g. for read-back\r\n *   operations, multi-view rendering, or explicit flushes). Each call:\r\n *   1. Ends the current render pass if any (`_endCurrentRenderPass`), which triggers the\r\n *      render-pass auto-pop and pending-pop handling described above.\r\n *   2. Calls `_debugPopBeforeEndOfEncoder` to close every still-open group on the render encoder\r\n *      before it is finalised and submitted. Only encoder-level groups (`_debugMarkersEncoderGroups`)\r\n *      are popped from the encoder; pass-level groups (`_debugMarkersPassGroups`) are already\r\n *      floating after step 1 and were never pushed on the encoder, so they are left alone.\r\n *   3. Creates new `_uploadEncoder` / `_renderEncoder` instances.\r\n *   4. Calls `_debugPushAfterStartOfEncoder` to re-open the encoder-level groups on the new render\r\n *      encoder, so the user's subsequent pops still find a matching push.\r\n *   When `flushFramebuffer` is called from `endFrame` (the last flush of the frame), both arrays\r\n *   are cleared (`_debugMarkersEncoderGroups` and `_debugMarkersPassGroups`) because any groups\r\n *   still open at end-of-frame are considered abandoned.\r\n *\r\n * ## State variables\r\n *\r\n *   - `_debugMarkersEncoderGroups` — names of groups currently open on the render encoder (pushed\r\n *     while no render pass was active). These are re-pushed on the new render encoder after each\r\n *     mid-frame flush.\r\n *   - `_debugMarkersPassGroups` — names of groups pushed while a render pass was active. While a\r\n *     pass is live these are open on that pass encoder. When a pass ends they become \"floating\" —\r\n *     auto-popped from the finished pass but not yet on any GPU object — and remain here until the\r\n *     next render pass starts and `_debugPushAfterStartOfEncoder` re-opens them on it.\r\n *   - `_debugMarkersPendingEncoderPops` — count of user pops that arrived while a render pass was\r\n *     active but whose matching push lived on the render encoder. These pops are deferred and\r\n *     replayed on the render encoder once the render pass ends.\r\n */\r\n\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { WebGPUEngine } from \"../../webgpuEngine.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register WebGPU debug marker methods on WebGPUEngine.\r\n * @internal\r\n */\r\nexport function RegisterWebGPUDebugging(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebGPUEngine.prototype._debugPushGroup = function (groupName: string): void {\r\n        if (!this._enableGPUDebugMarkers) {\r\n            return;\r\n        }\r\n\r\n        const debugCommands = this._currentRenderPass ?? this._renderEncoder;\r\n\r\n        debugCommands.pushDebugGroup(groupName);\r\n\r\n        if (this._currentRenderPass) {\r\n            this._debugMarkersPassGroups.push(groupName);\r\n        } else {\r\n            this._debugMarkersEncoderGroups.push(groupName);\r\n        }\r\n\r\n        if (this._showGPUDebugMarkersLog) {\r\n            Logger.Log(\r\n                `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] Pushing debug group '${groupName}' on '${debugCommands.label}'.`\r\n            );\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype._debugPopGroup = function (): void {\r\n        if (!this._enableGPUDebugMarkers) {\r\n            return;\r\n        }\r\n\r\n        const debugCommands = this._currentRenderPass ?? this._renderEncoder;\r\n\r\n        if (this._currentRenderPass) {\r\n            if (this._debugMarkersPassGroups.length > 0) {\r\n                // Normal case: pop the most-recent pass-level group from the active render pass.\r\n                const groupName = this._debugMarkersPassGroups.pop();\r\n                debugCommands.popDebugGroup();\r\n                if (this._showGPUDebugMarkersLog) {\r\n                    Logger.Log(\r\n                        `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] Popping debug group '${groupName}' on '${debugCommands.label}'.`\r\n                    );\r\n                }\r\n            } else {\r\n                // The group was pushed on the render encoder (before this pass started); we cannot pop\r\n                // it while the pass is active, so defer it until the pass ends.\r\n                this._debugMarkersPendingEncoderPops++;\r\n                if (this._showGPUDebugMarkersLog) {\r\n                    Logger.Log(\r\n                        `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] Deferring pop of encoder-level group on '${debugCommands.label}' (pending: ${this._debugMarkersPendingEncoderPops}).`\r\n                    );\r\n                }\r\n            }\r\n        } else {\r\n            if (this._debugMarkersPassGroups.length > 0) {\r\n                // The group was pushed during a render pass that has since ended (floating). No GPU\r\n                // object currently holds this push, so we just discard the name without any GPU call.\r\n                const groupName = this._debugMarkersPassGroups.pop();\r\n                if (this._showGPUDebugMarkersLog) {\r\n                    Logger.Log(\r\n                        `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] Popping floating pass-level debug group '${groupName}' (no GPU pop needed).`\r\n                    );\r\n                }\r\n            } else {\r\n                // Normal case: pop the most-recent encoder-level group from the render encoder.\r\n                const groupName = this._debugMarkersEncoderGroups.pop();\r\n                debugCommands.popDebugGroup();\r\n                if (this._showGPUDebugMarkersLog) {\r\n                    Logger.Log(\r\n                        `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] Popping debug group '${groupName}' on '${debugCommands.label}'.`\r\n                    );\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype._debugInsertMarker = function (text: string): void {\r\n        if (!this._enableGPUDebugMarkers) {\r\n            return;\r\n        }\r\n\r\n        const debugCommands = this._currentRenderPass ?? this._renderEncoder;\r\n\r\n        if (this._showGPUDebugMarkersLog) {\r\n            Logger.Log(\r\n                `[${this.frameId}] [E${this._debugMarkersEncoderGroups.length}|P${this._debugMarkersPassGroups.length}] Inserting debug marker '${text}' on '${debugCommands.label}'`\r\n            );\r\n        }\r\n\r\n        debugCommands.insertDebugMarker(text);\r\n    };\r\n} // end RegisterWebGPUDebugging\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type ImageSource, type Nullable } from \"../../../types\";\r\nimport { WebGPUEngine } from \"../../webgpuEngine.pure\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\nimport { GetExponentOfTwo } from \"../../../Misc/tools.functions\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineDynamicTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineDynamicTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebGPUEngine.prototype.createDynamicTexture = function (width: number, height: number, generateMipMaps: boolean, samplingMode: number): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Dynamic);\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n\r\n        if (generateMipMaps) {\r\n            width = this.needPOTTextures ? GetExponentOfTwo(width, this._caps.maxTextureSize) : width;\r\n            height = this.needPOTTextures ? GetExponentOfTwo(height, this._caps.maxTextureSize) : height;\r\n        }\r\n\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.isReady = false;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n\r\n        this.updateTextureSamplingMode(samplingMode, texture);\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        if (width && height) {\r\n            this._textureHelper.createGPUTextureForInternalTexture(texture, width, height);\r\n        }\r\n\r\n        return texture;\r\n    };\r\n\r\n    WebGPUEngine.prototype.updateDynamicTexture = function (\r\n        texture: Nullable<InternalTexture>,\r\n        source: ImageSource,\r\n        invertY: boolean,\r\n        premulAlpha: boolean = false,\r\n        format?: number,\r\n        forceBindTexture?: boolean,\r\n        allowGPUOptimization?: boolean\r\n    ): void {\r\n        if (!texture) {\r\n            return;\r\n        }\r\n\r\n        const width = source.width,\r\n            height = source.height;\r\n\r\n        let gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (!texture._hardwareTexture?.underlyingResource) {\r\n            gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture, width, height);\r\n        }\r\n\r\n        this._textureHelper.updateTexture(source, texture, width, height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, premulAlpha, 0, 0, allowGPUOptimization);\r\n        if (texture.generateMipMaps) {\r\n            this._generateMipmaps(texture);\r\n        }\r\n\r\n        texture._dynamicTextureSource = source;\r\n        texture._premulAlpha = premulAlpha;\r\n        texture.invertY = invertY || false;\r\n        texture.isReady = true;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTexture, InternalTextureSource } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IMultiRenderTargetOptions } from \"../../../Materials/Textures/multiRenderTarget.pure\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Constants } from \"../../constants\";\r\nimport { type TextureSize } from \"../../../Materials/Textures/textureCreationOptions\";\r\nimport { type RenderTargetWrapper } from \"../../renderTargetWrapper\";\r\nimport { WebGPUEngine } from \"../../webgpuEngine.pure\";\r\nimport { type WebGPURenderTargetWrapper } from \"../webgpuRenderTargetWrapper\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineMultiRender.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineMultiRender(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebGPUEngine.prototype.unBindMultiColorAttachmentFramebuffer = function (\r\n        rtWrapper: RenderTargetWrapper,\r\n        disableGenerateMipMaps: boolean = false,\r\n        onBeforeUnbind?: () => void\r\n    ): void {\r\n        if (onBeforeUnbind) {\r\n            onBeforeUnbind();\r\n        }\r\n\r\n        this._endCurrentRenderPass();\r\n\r\n        if (!rtWrapper.disableAutomaticMSAAResolve) {\r\n            this.resolveMultiFramebuffer(rtWrapper, false);\r\n        }\r\n\r\n        if (!disableGenerateMipMaps) {\r\n            this.generateMipMapsMultiFramebuffer(rtWrapper);\r\n        }\r\n\r\n        this._currentRenderTarget = null;\r\n\r\n        this._mrtAttachments = [];\r\n        this._cacheRenderPipeline.setMRT([]);\r\n        this._cacheRenderPipeline.setMRTAttachments(this._mrtAttachments);\r\n    };\r\n\r\n    WebGPUEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, options: IMultiRenderTargetOptions, initializeBuffers?: boolean): RenderTargetWrapper {\r\n        let generateMipMaps = false;\r\n        let generateDepthBuffer = true;\r\n        let generateStencilBuffer = false;\r\n        let generateDepthTexture = false;\r\n        let depthTextureFormat = Constants.TEXTUREFORMAT_DEPTH16;\r\n        let textureCount = 1;\r\n        let samples = 1;\r\n\r\n        const defaultType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        const defaultSamplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n        const defaultUseSRGBBuffer = false;\r\n        const defaultFormat = Constants.TEXTUREFORMAT_RGBA;\r\n        const defaultTarget = Constants.TEXTURE_2D;\r\n\r\n        let types: number[] = [];\r\n        let samplingModes: number[] = [];\r\n        let useSRGBBuffers: boolean[] = [];\r\n        let formats: number[] = [];\r\n        let targets: number[] = [];\r\n        let faceIndex: number[] = [];\r\n        let layerIndex: number[] = [];\r\n        let layers: number[] = [];\r\n        let labels: string[] = [];\r\n        let creationFlags: number[] = [];\r\n        let dontCreateTextures = false;\r\n\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(true, false, size) as WebGPURenderTargetWrapper;\r\n\r\n        if (options !== undefined) {\r\n            generateMipMaps = options.generateMipMaps ?? false;\r\n            generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n            generateStencilBuffer = options.generateStencilBuffer ?? false;\r\n            generateDepthTexture = options.generateDepthTexture ?? false;\r\n            textureCount = options.textureCount ?? 1;\r\n            depthTextureFormat = options.depthTextureFormat ?? Constants.TEXTUREFORMAT_DEPTH16;\r\n            types = options.types || types;\r\n            samplingModes = options.samplingModes || samplingModes;\r\n            useSRGBBuffers = options.useSRGBBuffers || useSRGBBuffers;\r\n            formats = options.formats || formats;\r\n            targets = options.targetTypes || targets;\r\n            faceIndex = options.faceIndex || faceIndex;\r\n            layerIndex = options.layerIndex || layerIndex;\r\n            layers = options.layerCounts || layers;\r\n            labels = options.labels || labels;\r\n            creationFlags = options.creationFlags || creationFlags;\r\n            samples = options.samples ?? samples;\r\n            dontCreateTextures = options.dontCreateTextures ?? false;\r\n        }\r\n\r\n        const width = (<{ width: number; height: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number }>size).height ?? <number>size;\r\n\r\n        const textures: InternalTexture[] = [];\r\n        const attachments: number[] = [];\r\n        const defaultAttachments: number[] = [];\r\n\r\n        rtWrapper.label = options?.label ?? \"MultiRenderTargetWrapper\";\r\n        rtWrapper._generateDepthBuffer = generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = generateStencilBuffer;\r\n        rtWrapper._attachments = attachments;\r\n        rtWrapper._defaultAttachments = defaultAttachments;\r\n\r\n        let depthStencilTexture: Nullable<InternalTexture> = null;\r\n        if ((generateDepthBuffer || generateStencilBuffer || generateDepthTexture) && !dontCreateTextures) {\r\n            if (!generateDepthTexture) {\r\n                // The caller doesn't want a depth texture, so we are free to use the depth texture format we want.\r\n                // So, we will align with what the WebGL engine does\r\n                if (generateDepthBuffer && generateStencilBuffer) {\r\n                    depthTextureFormat = Constants.TEXTUREFORMAT_DEPTH24_STENCIL8;\r\n                } else if (generateDepthBuffer) {\r\n                    depthTextureFormat = Constants.TEXTUREFORMAT_DEPTH32_FLOAT;\r\n                } else {\r\n                    depthTextureFormat = Constants.TEXTUREFORMAT_STENCIL8;\r\n                }\r\n            }\r\n            depthStencilTexture = rtWrapper.createDepthStencilTexture(0, false, generateStencilBuffer, 1, depthTextureFormat, rtWrapper.label + \"-DepthStencil\");\r\n        }\r\n\r\n        const mipmapsCreationOnly = options !== undefined && typeof options === \"object\" && options.createMipMaps && !generateMipMaps;\r\n\r\n        for (let i = 0; i < textureCount; i++) {\r\n            let samplingMode = samplingModes[i] || defaultSamplingMode;\r\n            let type = types[i] || defaultType;\r\n\r\n            const format = formats[i] || defaultFormat;\r\n            const useSRGBBuffer = (useSRGBBuffers[i] || defaultUseSRGBBuffer) && this._caps.supportSRGBBuffers;\r\n\r\n            const target = targets[i] || defaultTarget;\r\n            const layerCount = layers[i] ?? 1;\r\n            const creationFlag = creationFlags[i];\r\n\r\n            if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n                // if floating point linear (FLOAT) then force to NEAREST_SAMPLINGMODE\r\n                samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n                // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n                samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            }\r\n\r\n            if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n                type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                Logger.Warn(\"Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type\");\r\n            }\r\n\r\n            attachments.push(i + 1);\r\n            defaultAttachments.push(initializeBuffers ? i + 1 : i === 0 ? 1 : 0);\r\n\r\n            if (target === -1 || dontCreateTextures) {\r\n                continue;\r\n            }\r\n\r\n            const texture = new InternalTexture(this, InternalTextureSource.MultiRenderTarget);\r\n            textures[i] = texture;\r\n\r\n            switch (target) {\r\n                case Constants.TEXTURE_CUBE_MAP:\r\n                    texture.isCube = true;\r\n                    break;\r\n                case Constants.TEXTURE_3D:\r\n                    texture.is3D = true;\r\n                    texture.baseDepth = texture.depth = layerCount;\r\n                    break;\r\n                case Constants.TEXTURE_2D_ARRAY:\r\n                    texture.is2DArray = true;\r\n                    texture.baseDepth = texture.depth = layerCount;\r\n                    break;\r\n            }\r\n\r\n            texture.baseWidth = width;\r\n            texture.baseHeight = height;\r\n            texture.width = width;\r\n            texture.height = height;\r\n            texture.isReady = true;\r\n            texture.samples = 1;\r\n            texture.generateMipMaps = generateMipMaps;\r\n            texture.samplingMode = samplingMode;\r\n            texture.type = type;\r\n            texture._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n            texture._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n            texture._useSRGBBuffer = useSRGBBuffer;\r\n            texture.format = format;\r\n            texture.label = labels[i] ?? rtWrapper.label + \"-Texture\" + i;\r\n\r\n            this._internalTexturesCache.push(texture);\r\n\r\n            if (mipmapsCreationOnly) {\r\n                // createGPUTextureForInternalTexture will only create a texture with mipmaps if generateMipMaps is true, as InternalTexture has no createMipMaps property, separate from generateMipMaps.\r\n                texture.generateMipMaps = true;\r\n            }\r\n\r\n            this._textureHelper.createGPUTextureForInternalTexture(texture, undefined, undefined, undefined, creationFlag);\r\n\r\n            if (mipmapsCreationOnly) {\r\n                texture.generateMipMaps = false;\r\n            }\r\n        }\r\n\r\n        if (depthStencilTexture) {\r\n            depthStencilTexture.incrementReferences();\r\n            textures[textureCount] = depthStencilTexture;\r\n            this._internalTexturesCache.push(depthStencilTexture);\r\n        }\r\n\r\n        rtWrapper.setTextures(textures);\r\n        rtWrapper.setLayerAndFaceIndices(layerIndex, faceIndex);\r\n\r\n        if (!dontCreateTextures) {\r\n            this.updateMultipleRenderTargetTextureSampleCount(rtWrapper, samples);\r\n        } else {\r\n            rtWrapper._samples = samples;\r\n        }\r\n\r\n        return rtWrapper;\r\n    };\r\n\r\n    WebGPUEngine.prototype.updateMultipleRenderTargetTextureSampleCount = function (rtWrapper: Nullable<RenderTargetWrapper>, samples: number): number {\r\n        if (!rtWrapper || !rtWrapper.textures || rtWrapper.textures.length === 0 || rtWrapper.textures[0].samples === samples) {\r\n            return samples;\r\n        }\r\n\r\n        const count = rtWrapper.textures.length;\r\n\r\n        if (count === 0) {\r\n            return 1;\r\n        }\r\n\r\n        samples = Math.min(samples, this.getCaps().maxMSAASamples);\r\n\r\n        // Release existing MSAA textures\r\n        for (let i = 0; i < count; ++i) {\r\n            const texture = rtWrapper.textures[i];\r\n            const gpuTextureWrapper = texture._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n\r\n            gpuTextureWrapper?.releaseMSAATextures();\r\n        }\r\n\r\n        // Sets new sample count. The MSAA textures will be created on demand.\r\n        for (let i = 0; i < count; ++i) {\r\n            const texture = rtWrapper.textures[i];\r\n            texture.samples = samples;\r\n        }\r\n\r\n        if (rtWrapper._depthStencilTexture) {\r\n            rtWrapper._depthStencilTexture.samples = samples;\r\n        }\r\n\r\n        rtWrapper._samples = samples;\r\n\r\n        return samples;\r\n    };\r\n\r\n    WebGPUEngine.prototype.generateMipMapsMultiFramebuffer = function (texture: RenderTargetWrapper): void {\r\n        const rtWrapper = texture as WebGPURenderTargetWrapper;\r\n\r\n        if (!rtWrapper.isMulti) {\r\n            return;\r\n        }\r\n\r\n        const attachments = rtWrapper._attachments!;\r\n        const count = attachments.length;\r\n\r\n        for (let i = 0; i < count; i++) {\r\n            const texture = rtWrapper.textures![i];\r\n            if (texture.generateMipMaps && !texture.isCube && !texture.is3D) {\r\n                this._generateMipmaps(texture);\r\n            }\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype.resolveMultiFramebuffer = function (texture: RenderTargetWrapper, resolveColors: boolean = true): void {\r\n        this.resolveFramebuffer(texture, resolveColors);\r\n    };\r\n\r\n    WebGPUEngine.prototype.bindAttachments = function (attachments: number[]): void {\r\n        if (attachments.length === 0 || !this._currentRenderTarget) {\r\n            return;\r\n        }\r\n\r\n        this._mrtAttachments = attachments;\r\n        if (this._currentRenderPass) {\r\n            // the render pass has already been created, we need to call setMRTAttachments to update the state of the attachments\r\n            this._cacheRenderPipeline.setMRTAttachments(attachments);\r\n        } else {\r\n            // the render pass is not created yet so we don't need to call setMRTAttachments: it will be called as part of the render pass creation (see WebGPUEngine._startRenderTargetRenderPass)\r\n        }\r\n    };\r\n\r\n    WebGPUEngine.prototype.clearAttachments = function (color, attachments, clearColor, clearDepth, clearStencil = false, stencilClearValue = 0): void {\r\n        this.bindAttachments(attachments);\r\n        this.clear(color, clearColor, clearDepth, clearStencil, stencilClearValue);\r\n    };\r\n\r\n    WebGPUEngine.prototype.buildTextureLayout = function (textureStatus: boolean[], backBufferLayout = false): number[] {\r\n        const result = [];\r\n\r\n        if (backBufferLayout) {\r\n            result.push(1);\r\n        } else {\r\n            for (let i = 0; i < textureStatus.length; i++) {\r\n                if (textureStatus[i]) {\r\n                    result.push(i + 1);\r\n                } else {\r\n                    result.push(0);\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    WebGPUEngine.prototype.restoreSingleAttachment = function (): void {\r\n        // not sure what to do, probably nothing... This function and restoreSingleAttachmentForRenderTarget are not called in Babylon.js so it's hard to know the use case\r\n    };\r\n\r\n    WebGPUEngine.prototype.restoreSingleAttachmentForRenderTarget = function (): void {\r\n        // not sure what to do, probably nothing... This function and restoreSingleAttachment are not called in Babylon.js so it's hard to know the use case\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\nimport { WebGPURenderItemBeginOcclusionQuery, WebGPURenderItemEndOcclusionQuery } from \"../webgpuBundleList\";\r\nimport { type PerfCounter } from \"../../../Misc/perfCounter\";\r\nimport { type OcclusionQuery } from \"../../../Engines/AbstractEngine/abstractEngine.query.pure\";\r\n\r\n// eslint-disable-next-line import/no-duplicates\r\n\r\n// eslint-disable-next-line import/no-duplicates\r\n\r\nexport {};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineQuery.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineQuery(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype.getGPUFrameTimeCounter = function (): PerfCounter {\r\n        return this._timestampQuery.gpuFrameTimeCounter;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.captureGPUFrameTime = function (value: boolean) {\r\n        this._timestampQuery.enable = value && !!this._caps.timerQuery;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createQuery = function (): OcclusionQuery {\r\n        return this._occlusionQuery.createQuery();\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.deleteQuery = function (query: OcclusionQuery): ThinWebGPUEngine {\r\n        this._occlusionQuery.deleteQuery(query as number);\r\n\r\n        return this;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.isQueryResultAvailable = function (query: OcclusionQuery): boolean {\r\n        return this._occlusionQuery.isQueryResultAvailable(query as number);\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.getQueryResult = function (query: OcclusionQuery): number {\r\n        return this._occlusionQuery.getQueryResult(query as number);\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.beginOcclusionQuery = function (algorithmType: number, query: OcclusionQuery): boolean {\r\n        if (this.compatibilityMode) {\r\n            if (this._occlusionQueryActive) {\r\n                return false;\r\n            }\r\n\r\n            const renderPass = this._getCurrentRenderPass();\r\n            if (renderPass && this._occlusionQuery.canBeginQuery(query as number)) {\r\n                renderPass.beginOcclusionQuery(query as number);\r\n                this._occlusionQueryActive = true;\r\n                return true;\r\n            }\r\n        } else {\r\n            this._bundleList.addItem(new WebGPURenderItemBeginOcclusionQuery(query as number));\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.endOcclusionQuery = function (): ThinWebGPUEngine {\r\n        if (this.compatibilityMode) {\r\n            if (this._occlusionQueryActive) {\r\n                this._currentRenderPass?.endOcclusionQuery();\r\n                this._occlusionQueryActive = false;\r\n            }\r\n        } else {\r\n            this._bundleList.addItem(new WebGPURenderItemEndOcclusionQuery());\r\n        }\r\n        return this;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IWebRequest } from \"../../../Misc/interfaces/iWebRequest\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Constants } from \"../../constants\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\n\r\n/**\r\n * @internal\r\n */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineRawTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineRawTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function ConvertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView {\r\n        // Create new RGBA data container.\r\n        let rgbaData: any;\r\n        let val1 = 1;\r\n        if (textureType === Constants.TEXTURETYPE_FLOAT) {\r\n            rgbaData = new Float32Array(width * height * 4);\r\n        } else if (textureType === Constants.TEXTURETYPE_HALF_FLOAT) {\r\n            rgbaData = new Uint16Array(width * height * 4);\r\n            val1 = 15360; // 15360 is the encoding of 1 in half float\r\n        } else if (textureType === Constants.TEXTURETYPE_UNSIGNED_INTEGER) {\r\n            rgbaData = new Uint32Array(width * height * 4);\r\n        } else {\r\n            rgbaData = new Uint8Array(width * height * 4);\r\n        }\r\n\r\n        // Convert each pixel.\r\n        for (let x = 0; x < width; x++) {\r\n            for (let y = 0; y < height; y++) {\r\n                const index = (y * width + x) * 3;\r\n                const newIndex = (y * width + x) * 4;\r\n\r\n                // Map Old Value to new value.\r\n                rgbaData[newIndex + 0] = rgbData[index + 0];\r\n                rgbaData[newIndex + 1] = rgbData[index + 1];\r\n                rgbaData[newIndex + 2] = rgbData[index + 2];\r\n\r\n                // Add fully opaque alpha channel.\r\n                rgbaData[newIndex + 3] = val1;\r\n            }\r\n        }\r\n\r\n        return rgbaData;\r\n    }\r\n\r\n    ThinWebGPUEngine.prototype.createRawTexture = function (\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags: number = 0,\r\n        useSRGBBuffer: boolean = false,\r\n        mipLevelCount?: number\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.Raw);\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.format = format;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n        texture.type = type;\r\n        texture._creationFlags = creationFlags;\r\n        texture._useSRGBBuffer = useSRGBBuffer;\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = data;\r\n        }\r\n\r\n        this._textureHelper.updateMipLevelCountForInternalTexture(texture, mipLevelCount);\r\n        this._textureHelper.createGPUTextureForInternalTexture(texture, width, height, undefined, creationFlags);\r\n\r\n        this.updateRawTexture(texture, data, format, invertY, compression, type, useSRGBBuffer);\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.updateRawTexture = function (\r\n        texture: Nullable<InternalTexture>,\r\n        bufferView: Nullable<ArrayBufferView>,\r\n        format: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        useSRGBBuffer: boolean = false,\r\n        mipLevel?: number\r\n    ): void {\r\n        if (!texture) {\r\n            return;\r\n        }\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = bufferView;\r\n            texture.invertY = invertY;\r\n            texture._compression = compression;\r\n            texture._useSRGBBuffer = useSRGBBuffer;\r\n            if (mipLevel !== undefined && bufferView) {\r\n                if (!texture._bufferViewArray) {\r\n                    texture._bufferViewArray = new Array(texture.mipLevelCount);\r\n                }\r\n                texture._bufferViewArray[mipLevel] = bufferView;\r\n            }\r\n        }\r\n\r\n        if (bufferView) {\r\n            const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n            const needConversion = format === Constants.TEXTUREFORMAT_RGB;\r\n\r\n            if (needConversion) {\r\n                bufferView = ConvertRGBtoRGBATextureData(bufferView, texture.width, texture.height, type);\r\n            }\r\n\r\n            const data = new Uint8Array(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);\r\n\r\n            const mipWidth = Math.max(1, texture.width >> (mipLevel ?? 0));\r\n            const mipHeight = Math.max(1, texture.height >> (mipLevel ?? 0));\r\n            this._textureHelper.updateTexture(data, texture, mipWidth, mipHeight, texture.depth, gpuTextureWrapper.format, 0, mipLevel ?? 0, invertY, false, 0, 0);\r\n            if (texture.generateMipMaps && !mipLevel) {\r\n                this._generateMipmaps(texture, this._uploadEncoder);\r\n            }\r\n        }\r\n\r\n        texture.isReady = true;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createRawCubeTexture = function (\r\n        data: Nullable<ArrayBufferView[]>,\r\n        size: number,\r\n        format: number,\r\n        type: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null\r\n    ): InternalTexture {\r\n        const texture = new InternalTexture(this, InternalTextureSource.CubeRaw);\r\n\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            generateMipMaps = false;\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            Logger.Warn(\"Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.\");\r\n        } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            generateMipMaps = false;\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n            Logger.Warn(\"Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.\");\r\n        } else if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatRender) {\r\n            generateMipMaps = false;\r\n            Logger.Warn(\"Render to float textures is not supported. Mipmap generation forced to false.\");\r\n        } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.colorBufferFloat) {\r\n            generateMipMaps = false;\r\n            Logger.Warn(\"Render to half float textures is not supported. Mipmap generation forced to false.\");\r\n        }\r\n\r\n        texture.isCube = true;\r\n        texture._originalFormat = format;\r\n        texture.format = format === Constants.TEXTUREFORMAT_RGB ? Constants.TEXTUREFORMAT_RGBA : format;\r\n        texture.type = type;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.width = size;\r\n        texture.height = size;\r\n        texture.samplingMode = samplingMode;\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferViewArray = data;\r\n        }\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n        texture._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        texture._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n\r\n        this._textureHelper.createGPUTextureForInternalTexture(texture);\r\n\r\n        if (format === Constants.TEXTUREFORMAT_RGB) {\r\n            const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n            gpuTextureWrapper._originalFormatIsRGB = true;\r\n        }\r\n\r\n        if (data) {\r\n            this.updateRawCubeTexture(texture, data, format, type, invertY, compression);\r\n        }\r\n\r\n        texture.isReady = true;\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.updateRawCubeTexture = function (\r\n        texture: InternalTexture,\r\n        bufferView: ArrayBufferView[],\r\n        _format: number,\r\n        type: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null\r\n    ): void {\r\n        texture._bufferViewArray = bufferView;\r\n        texture.invertY = invertY;\r\n        texture._compression = compression;\r\n\r\n        const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n        const needConversion = gpuTextureWrapper._originalFormatIsRGB;\r\n\r\n        const faces = [0, 2, 4, 1, 3, 5];\r\n\r\n        const data = [];\r\n        for (let i = 0; i < bufferView.length; ++i) {\r\n            let faceData = bufferView[faces[i]];\r\n            if (needConversion) {\r\n                faceData = ConvertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);\r\n            }\r\n            data.push(new Uint8Array(faceData.buffer, faceData.byteOffset, faceData.byteLength));\r\n        }\r\n\r\n        this._textureHelper.updateCubeTextures(data, texture, texture.width, texture.height, gpuTextureWrapper.format, invertY, false, 0, 0);\r\n        if (texture.generateMipMaps) {\r\n            this._generateMipmaps(texture, this._uploadEncoder);\r\n        }\r\n\r\n        texture.isReady = true;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createRawCubeTextureFromUrl = function (\r\n        url: string,\r\n        scene: Nullable<Scene>,\r\n        size: number,\r\n        format: number,\r\n        type: number,\r\n        noMipmap: boolean,\r\n        callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[] | Promise<ArrayBufferView[]>>,\r\n        mipmapGenerator: Nullable<(faces: ArrayBufferView[]) => ArrayBufferView[][]>,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        invertY: boolean = false\r\n    ): InternalTexture {\r\n        const texture = this.createRawCubeTexture(null, size, format, type, !noMipmap, invertY, samplingMode, null);\r\n        scene?.addPendingData(texture);\r\n        texture.url = url;\r\n        texture.isReady = false;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        const onerror = (request?: IWebRequest, exception?: any) => {\r\n            scene?.removePendingData(texture);\r\n            if (onError && request) {\r\n                onError(request.status + \" \" + request.statusText, exception);\r\n            }\r\n        };\r\n\r\n        const internalCallbackAsync = async (data: any) => {\r\n            const faceDataArraysResult = callback(data);\r\n            if (!faceDataArraysResult) {\r\n                return;\r\n            }\r\n\r\n            const faceDataArrays: any = faceDataArraysResult instanceof Promise ? await faceDataArraysResult : faceDataArraysResult;\r\n            const width = texture.width;\r\n\r\n            if (mipmapGenerator) {\r\n                const needConversion = format === Constants.TEXTUREFORMAT_RGB;\r\n                const mipData = mipmapGenerator(faceDataArrays);\r\n                const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n                const faces = [0, 1, 2, 3, 4, 5];\r\n                for (let level = 0; level < mipData.length; level++) {\r\n                    const mipSize = width >> level;\r\n                    const allFaces = [];\r\n                    for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\r\n                        let mipFaceData = mipData[level][faces[faceIndex]];\r\n                        if (needConversion) {\r\n                            mipFaceData = ConvertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);\r\n                        }\r\n                        allFaces.push(new Uint8Array(mipFaceData.buffer, mipFaceData.byteOffset, mipFaceData.byteLength));\r\n                    }\r\n                    this._textureHelper.updateCubeTextures(allFaces, texture, mipSize, mipSize, gpuTextureWrapper.format, invertY, false, 0, 0);\r\n                }\r\n            } else {\r\n                this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);\r\n            }\r\n\r\n            texture.isReady = true;\r\n            scene?.removePendingData(texture);\r\n\r\n            if (onLoad) {\r\n                onLoad();\r\n            }\r\n        };\r\n\r\n        this._loadFile(\r\n            url,\r\n            (data) => {\r\n                // eslint-disable-next-line github/no-then\r\n                internalCallbackAsync(data).catch((err) => {\r\n                    onerror(undefined, err);\r\n                });\r\n            },\r\n            undefined,\r\n            scene?.offlineProvider,\r\n            true,\r\n            onerror\r\n        );\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createRawTexture3D = function (\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags: number = 0\r\n    ): InternalTexture {\r\n        const source = InternalTextureSource.Raw3D;\r\n        const texture = new InternalTexture(this, source);\r\n\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.baseDepth = depth;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.depth = depth;\r\n        texture.format = format;\r\n        texture.type = textureType;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.is3D = true;\r\n        texture._creationFlags = creationFlags;\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = data;\r\n        }\r\n\r\n        this._textureHelper.createGPUTextureForInternalTexture(texture, width, height, undefined, creationFlags);\r\n\r\n        this.updateRawTexture3D(texture, data, format, invertY, compression, textureType);\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.updateRawTexture3D = function (\r\n        texture: InternalTexture,\r\n        bufferView: Nullable<ArrayBufferView>,\r\n        format: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ): void {\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = bufferView;\r\n            texture.format = format;\r\n            texture.invertY = invertY;\r\n            texture._compression = compression;\r\n        }\r\n\r\n        if (bufferView) {\r\n            const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n            const needConversion = format === Constants.TEXTUREFORMAT_RGB;\r\n\r\n            if (needConversion) {\r\n                bufferView = ConvertRGBtoRGBATextureData(bufferView, texture.width, texture.height, textureType);\r\n            }\r\n\r\n            const data = new Uint8Array(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);\r\n\r\n            this._textureHelper.updateTexture(data, texture, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0);\r\n            if (texture.generateMipMaps) {\r\n                this._generateMipmaps(texture, this._uploadEncoder);\r\n            }\r\n        }\r\n\r\n        texture.isReady = true;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createRawTexture2DArray = function (\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        format: number,\r\n        generateMipMaps: boolean,\r\n        invertY: boolean,\r\n        samplingMode: number,\r\n        compression: Nullable<string> = null,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags: number = 0,\r\n        mipLevelCount?: number\r\n    ): InternalTexture {\r\n        const source = InternalTextureSource.Raw2DArray;\r\n        const texture = new InternalTexture(this, source);\r\n\r\n        texture.baseWidth = width;\r\n        texture.baseHeight = height;\r\n        texture.baseDepth = depth;\r\n        texture.width = width;\r\n        texture.height = height;\r\n        texture.depth = depth;\r\n        texture.format = format;\r\n        texture.type = textureType;\r\n        texture.generateMipMaps = generateMipMaps;\r\n        texture.samplingMode = samplingMode;\r\n        texture.is2DArray = true;\r\n        texture._creationFlags = creationFlags;\r\n\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = data;\r\n        }\r\n\r\n        this._textureHelper.updateMipLevelCountForInternalTexture(texture, mipLevelCount);\r\n        this._textureHelper.createGPUTextureForInternalTexture(texture, width, height, depth, creationFlags);\r\n\r\n        this.updateRawTexture2DArray(texture, data, format, invertY, compression, textureType);\r\n\r\n        this._internalTexturesCache.push(texture);\r\n\r\n        return texture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.updateRawTexture2DArray = function (\r\n        texture: InternalTexture,\r\n        bufferView: Nullable<ArrayBufferView>,\r\n        format: number,\r\n        invertY: boolean,\r\n        compression: Nullable<string> = null,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        mipLevel?: number\r\n    ): void {\r\n        if (!this._doNotHandleContextLost) {\r\n            texture._bufferView = bufferView;\r\n            texture.format = format;\r\n            texture.invertY = invertY;\r\n            texture._compression = compression;\r\n            if (mipLevel !== undefined && bufferView) {\r\n                if (!texture._bufferViewArray) {\r\n                    texture._bufferViewArray = new Array(texture.mipLevelCount);\r\n                }\r\n                texture._bufferViewArray[mipLevel] = bufferView;\r\n            }\r\n        }\r\n\r\n        if (bufferView) {\r\n            const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n            const needConversion = format === Constants.TEXTUREFORMAT_RGB;\r\n\r\n            if (needConversion) {\r\n                bufferView = ConvertRGBtoRGBATextureData(bufferView, texture.width, texture.height, textureType);\r\n            }\r\n\r\n            const data = new Uint8Array(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);\r\n\r\n            const mipWidth = Math.max(1, texture.width >> (mipLevel ?? 0));\r\n            const mipHeight = Math.max(1, texture.height >> (mipLevel ?? 0));\r\n            this._textureHelper.updateTexture(data, texture, mipWidth, mipHeight, texture.depth, gpuTextureWrapper.format, 0, mipLevel ?? 0, invertY, false, 0, 0);\r\n            if (texture.generateMipMaps && !mipLevel) {\r\n                this._generateMipmaps(texture, this._uploadEncoder);\r\n            }\r\n        }\r\n\r\n        texture.isReady = true;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineReadTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineReadTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    ThinWebGPUEngine.prototype._readTexturePixels = function (\r\n        texture: InternalTexture,\r\n        width: number,\r\n        height: number,\r\n        faceIndex = -1,\r\n        level = 0,\r\n        buffer: Nullable<ArrayBufferView> = null,\r\n        flushRenderer = true,\r\n        noDataConversion = false,\r\n        x = 0,\r\n        y = 0\r\n    ): Promise<ArrayBufferView> {\r\n        const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (flushRenderer) {\r\n            this.flushFramebuffer();\r\n        }\r\n\r\n        return this._textureHelper.readPixels(gpuTextureWrapper.underlyingResource!, x, y, width, height, gpuTextureWrapper.format, faceIndex, level, buffer, noDataConversion);\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype._readTexturePixelsSync = function (): ArrayBufferView {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"_readTexturePixelsSync is unsupported in WebGPU!\";\r\n    };\r\n}\r\n","import { type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport { WebGPUPerfCounter } from \"./webgpuPerfCounter\";\r\nimport { type ThinWebGPUEngine } from \"../thinWebGPUEngine\";\r\n\r\n/**\r\n * Specialized class used to store a render target of a WebGPU engine\r\n */\r\nexport class WebGPURenderTargetWrapper extends RenderTargetWrapper {\r\n    /** @internal */\r\n    public _defaultAttachments: number[];\r\n\r\n    /**\r\n     * When true, the engine skips its render-target Y-flip when drawing into this target: it binds the\r\n     * non-inverting internals UBO (yFactor = +1) and keeps the main-framebuffer front-face winding, exactly\r\n     * as if rendering to the canvas. This is set for XR projection-layer targets, whose textures are handed\r\n     * directly to the XR compositor (top-left origin, presented as-is, never re-sampled by Babylon) and must\r\n     * therefore be rendered upright. Defaults to false so every other render target keeps the standard flip\r\n     * that keeps a later-sampled RTT consistent with the WebGL texture-space convention.\r\n     * @internal\r\n     */\r\n    public _disableEngineYFlip = false;\r\n\r\n    /**\r\n     * Gets the GPU time spent rendering this render target in the last frame (in nanoseconds).\r\n     * You have to enable the \"timestamp-query\" extension in the engine constructor options and set engine.enableGPUTimingMeasurements = true.\r\n     */\r\n    public readonly gpuTimeInFrame?: WebGPUPerfCounter;\r\n\r\n    /**\r\n     * Initializes the render target wrapper\r\n     * @param isMulti true if the wrapper is a multi render target\r\n     * @param isCube true if the wrapper should render to a cube texture\r\n     * @param size size of the render target (width/height/layers)\r\n     * @param engine engine used to create the render target\r\n     * @param label defines the label to use for the wrapper (for debugging purpose only)\r\n     */\r\n    constructor(isMulti: boolean, isCube: boolean, size: TextureSize, engine: ThinWebGPUEngine, label?: string) {\r\n        super(isMulti, isCube, size, engine, label);\r\n\r\n        if (engine.enableGPUTimingMeasurements) {\r\n            this.gpuTimeInFrame = new WebGPUPerfCounter();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { InternalTextureSource, InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type RenderTargetCreationOptions, type DepthTextureCreationOptions, type TextureSize } from \"../../../Materials/Textures/textureCreationOptions\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Constants } from \"../../constants\";\r\nimport { type RenderTargetWrapper } from \"../../renderTargetWrapper\";\r\nimport { WebGPURenderTargetWrapper } from \"../webgpuRenderTargetWrapper\";\r\nimport { GetTypeForDepthTexture, HasStencilAspect } from \"core/Materials/Textures/textureHelper.functions\";\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineRenderTarget.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineRenderTarget(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype._createHardwareRenderTargetWrapper = function (isMulti: boolean, isCube: boolean, size: TextureSize): WebGPURenderTargetWrapper {\r\n        const rtWrapper = new WebGPURenderTargetWrapper(isMulti, isCube, size, this);\r\n        this._renderTargetWrapperCache.push(rtWrapper);\r\n        return rtWrapper;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.createRenderTargetTexture = function (size: TextureSize, options: boolean | RenderTargetCreationOptions): WebGPURenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, false, size) as WebGPURenderTargetWrapper;\r\n\r\n        const fullOptions: RenderTargetCreationOptions = {};\r\n\r\n        if (options !== undefined && typeof options === \"object\") {\r\n            fullOptions.generateMipMaps = options.generateMipMaps;\r\n            fullOptions.generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;\r\n            fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && options.generateStencilBuffer;\r\n            fullOptions.samplingMode = options.samplingMode === undefined ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;\r\n            fullOptions.creationFlags = options.creationFlags ?? 0;\r\n            fullOptions.noColorAttachment = !!options.noColorAttachment;\r\n            fullOptions.colorAttachment = options.colorAttachment;\r\n            fullOptions.samples = options.samples;\r\n            fullOptions.label = options.label;\r\n            fullOptions.format = options.format;\r\n            fullOptions.type = options.type;\r\n        } else {\r\n            fullOptions.generateMipMaps = options;\r\n            fullOptions.generateDepthBuffer = true;\r\n            fullOptions.generateStencilBuffer = false;\r\n            fullOptions.samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n            fullOptions.creationFlags = 0;\r\n            fullOptions.noColorAttachment = false;\r\n        }\r\n\r\n        const texture =\r\n            fullOptions.colorAttachment || (fullOptions.noColorAttachment ? null : this._createInternalTexture(size, fullOptions, true, InternalTextureSource.RenderTarget));\r\n\r\n        rtWrapper.label = fullOptions.label ?? \"RenderTargetWrapper\";\r\n        rtWrapper._samples = fullOptions.colorAttachment?.samples ?? fullOptions.samples ?? 1;\r\n        rtWrapper._generateDepthBuffer = fullOptions.generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;\r\n\r\n        rtWrapper.setTextures(texture);\r\n\r\n        if (rtWrapper._generateDepthBuffer || rtWrapper._generateStencilBuffer) {\r\n            rtWrapper.createDepthStencilTexture(\r\n                0,\r\n                false, // force false as filtering is not supported for depth textures\r\n                rtWrapper._generateStencilBuffer,\r\n                rtWrapper.samples,\r\n                fullOptions.generateStencilBuffer ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n                fullOptions.label ? fullOptions.label + \"-DepthStencil\" : undefined\r\n            );\r\n        }\r\n\r\n        if (texture && !fullOptions.colorAttachment) {\r\n            if (options !== undefined && typeof options === \"object\" && options.createMipMaps && !fullOptions.generateMipMaps) {\r\n                texture.generateMipMaps = true;\r\n            }\r\n\r\n            this._textureHelper.createGPUTextureForInternalTexture(texture, undefined, undefined, undefined, fullOptions.creationFlags);\r\n\r\n            if (options !== undefined && typeof options === \"object\" && options.createMipMaps && !fullOptions.generateMipMaps) {\r\n                texture.generateMipMaps = false;\r\n            }\r\n        }\r\n\r\n        return rtWrapper;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype._createDepthStencilTexture = function (\r\n        size: TextureSize,\r\n        options: DepthTextureCreationOptions,\r\n        wrapper: WebGPURenderTargetWrapper\r\n    ): InternalTexture {\r\n        const internalOptions = {\r\n            bilinearFiltering: false,\r\n            comparisonFunction: 0,\r\n            generateStencil: false,\r\n            samples: 1,\r\n            depthTextureFormat: options.generateStencil ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n            ...options,\r\n        };\r\n\r\n        const hasStencil = HasStencilAspect(internalOptions.depthTextureFormat);\r\n\r\n        wrapper._depthStencilTextureWithStencil = hasStencil;\r\n\r\n        const internalTexture = new InternalTexture(this, hasStencil ? InternalTextureSource.DepthStencil : InternalTextureSource.Depth);\r\n\r\n        internalTexture.label = options.label;\r\n\r\n        internalTexture.format = internalOptions.depthTextureFormat;\r\n        internalTexture.type = GetTypeForDepthTexture(internalTexture.format);\r\n\r\n        this._setupDepthStencilTexture(internalTexture, size, internalOptions.bilinearFiltering, internalOptions.comparisonFunction, internalOptions.samples);\r\n\r\n        this._textureHelper.createGPUTextureForInternalTexture(internalTexture);\r\n\r\n        this._internalTexturesCache.push(internalTexture);\r\n\r\n        return internalTexture;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype._setupDepthStencilTexture = function (\r\n        internalTexture: InternalTexture,\r\n        size: TextureSize,\r\n        bilinearFiltering: boolean,\r\n        comparisonFunction: number,\r\n        samples = 1\r\n    ): void {\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n        const layers = (<{ width: number; height: number; depth?: number; layers?: number }>size).layers || 0;\r\n        const depth = (<{ width: number; height: number; depth?: number; layers?: number }>size).depth || 0;\r\n\r\n        internalTexture.baseWidth = width;\r\n        internalTexture.baseHeight = height;\r\n        internalTexture.width = width;\r\n        internalTexture.height = height;\r\n        internalTexture.is2DArray = layers > 0;\r\n        internalTexture.is3D = depth > 0;\r\n        internalTexture.depth = layers || depth;\r\n        internalTexture.isReady = true;\r\n        internalTexture.samples = samples;\r\n        internalTexture.generateMipMaps = false;\r\n        internalTexture.samplingMode = bilinearFiltering ? Constants.TEXTURE_BILINEAR_SAMPLINGMODE : Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        internalTexture.type = Constants.TEXTURETYPE_FLOAT; // the right type will be set later\r\n        internalTexture._comparisonFunction = comparisonFunction;\r\n        internalTexture._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        internalTexture._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n    };\r\n\r\n    ThinWebGPUEngine.prototype.updateRenderTargetTextureSampleCount = function (rtWrapper: Nullable<RenderTargetWrapper>, samples: number): number {\r\n        if (!rtWrapper || !rtWrapper.texture || rtWrapper.samples === samples) {\r\n            return samples;\r\n        }\r\n\r\n        samples = Math.min(samples, this.getCaps().maxMSAASamples);\r\n\r\n        // Releases existing MSAA textures. New ones will be created on demand.\r\n        const gpuTexture = rtWrapper.texture._hardwareTexture as Nullable<WebGPUHardwareTexture>;\r\n\r\n        gpuTexture?.releaseMSAATextures();\r\n\r\n        if (rtWrapper._depthStencilTexture) {\r\n            (rtWrapper._depthStencilTexture._hardwareTexture as Nullable<WebGPUHardwareTexture>)?.releaseMSAATextures();\r\n            rtWrapper._depthStencilTexture.samples = samples;\r\n        }\r\n\r\n        rtWrapper._samples = samples;\r\n        rtWrapper.texture.samples = samples;\r\n\r\n        return samples;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\nimport { InternalTexture, InternalTextureSource } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type RenderTargetCreationOptions } from \"../../../Materials/Textures/textureCreationOptions\";\r\nimport { Constants } from \"../../constants\";\r\nimport { type RenderTargetWrapper } from \"../../renderTargetWrapper\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineRenderTargetCube.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineRenderTargetCube(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype.createRenderTargetCubeTexture = function (size: number, options?: RenderTargetCreationOptions): RenderTargetWrapper {\r\n        const rtWrapper = this._createHardwareRenderTargetWrapper(false, true, size);\r\n\r\n        const fullOptions = {\r\n            generateMipMaps: true,\r\n            generateDepthBuffer: true,\r\n            generateStencilBuffer: false,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            samples: 1,\r\n            ...options,\r\n        };\r\n        fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && fullOptions.generateStencilBuffer;\r\n\r\n        rtWrapper.label = fullOptions.label ?? \"RenderTargetWrapper\";\r\n        rtWrapper._generateDepthBuffer = fullOptions.generateDepthBuffer;\r\n        rtWrapper._generateStencilBuffer = fullOptions.generateStencilBuffer;\r\n\r\n        const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);\r\n\r\n        texture.width = size;\r\n        texture.height = size;\r\n        texture.depth = 0;\r\n        texture.isReady = true;\r\n        texture.isCube = true;\r\n        texture.samples = fullOptions.samples;\r\n        texture.generateMipMaps = fullOptions.generateMipMaps;\r\n        texture.samplingMode = fullOptions.samplingMode;\r\n        texture.type = fullOptions.type;\r\n        texture.format = fullOptions.format;\r\n\r\n        this._internalTexturesCache.push(texture);\r\n        rtWrapper.setTextures(texture);\r\n\r\n        if (rtWrapper._generateDepthBuffer || rtWrapper._generateStencilBuffer) {\r\n            rtWrapper.createDepthStencilTexture(\r\n                0,\r\n                fullOptions.samplingMode === undefined ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_BILINEAR_SAMPLINGMODE ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_LINEAR_LINEAR ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_TRILINEAR_SAMPLINGMODE ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_NEAREST_LINEAR ||\r\n                    fullOptions.samplingMode === Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST,\r\n                rtWrapper._generateStencilBuffer,\r\n                rtWrapper.samples\r\n            );\r\n        }\r\n\r\n        if (options && options.createMipMaps && !fullOptions.generateMipMaps) {\r\n            texture.generateMipMaps = true;\r\n        }\r\n\r\n        this._textureHelper.createGPUTextureForInternalTexture(texture);\r\n\r\n        if (options && options.createMipMaps && !fullOptions.generateMipMaps) {\r\n            texture.generateMipMaps = false;\r\n        }\r\n\r\n        return rtWrapper;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type RenderTargetTexture } from \"../../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineRenderTargetTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineRenderTargetTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype.setDepthStencilTexture = function (\r\n        channel: number,\r\n        uniform: Nullable<WebGLUniformLocation>,\r\n        texture: Nullable<RenderTargetTexture>,\r\n        name?: string\r\n    ): void {\r\n        if (!texture || !texture.depthStencilTexture) {\r\n            this._setTexture(channel, null, undefined, undefined, name);\r\n        } else {\r\n            this._setTexture(channel, texture, false, true, name);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ImageSource } from \"../../../types\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\nimport { ThinWebGPUEngine } from \"core/Engines/thinWebGPUEngine\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineTexture2DArrayImageSource.\r\n * Adds AbstractEngine.updateTextureArrayLayerFromImageSource on the WebGPU engine.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineTexture2DArrayImageSource(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ThinWebGPUEngine.prototype.updateTextureArrayLayerFromImageSource = function (\r\n        this: ThinWebGPUEngine,\r\n        texture: InternalTexture,\r\n        source: ImageSource,\r\n        layer: number,\r\n        invertY: boolean = false,\r\n        premultiplyAlpha: boolean = false\r\n    ): void {\r\n        const gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        this._textureHelper.updateTexture(source, texture, texture.width, texture.height, 1, gpuTextureWrapper.format, layer, 0, invertY, premultiplyAlpha, 0, 0);\r\n\r\n        if (texture.generateMipMaps) {\r\n            this._generateMipmaps(texture, this._uploadEncoder);\r\n        }\r\n\r\n        texture.isReady = true;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { WebGPUEngine } from \"../../webgpuEngine.pure\";\r\nimport { type WebGPUHardwareTexture } from \"../webgpuHardwareTexture\";\r\nimport { type ExternalTexture } from \"../../../Materials/Textures/externalTexture\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for enginesWebGPUExtensionsEngineVideoTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEnginesWebGPUExtensionsEngineVideoTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function IsExternalTexture(texture: Nullable<ExternalTexture> | HTMLVideoElement): texture is ExternalTexture {\r\n        return texture && (texture as ExternalTexture).underlyingResource !== undefined ? true : false;\r\n    }\r\n\r\n    WebGPUEngine.prototype.updateVideoTexture = function (texture: Nullable<InternalTexture>, video: HTMLVideoElement | Nullable<ExternalTexture>, invertY: boolean): void {\r\n        if (!texture || texture._isDisabled) {\r\n            return;\r\n        }\r\n\r\n        if (this._videoTextureSupported === undefined) {\r\n            this._videoTextureSupported = true;\r\n        }\r\n\r\n        let gpuTextureWrapper = texture._hardwareTexture as WebGPUHardwareTexture;\r\n\r\n        if (!texture._hardwareTexture?.underlyingResource) {\r\n            gpuTextureWrapper = this._textureHelper.createGPUTextureForInternalTexture(texture);\r\n        }\r\n\r\n        if (IsExternalTexture(video)) {\r\n            if (video.isReady()) {\r\n                try {\r\n                    if (this.snapshotRendering) {\r\n                        // Under snapshot rendering the main render encoder is reserved for recording/replaying\r\n                        // bundles, and _generateMipmaps()'s _endCurrentRenderPass() would corrupt the bundle. Run the\r\n                        // copy (and mipmap generation, if any) on a single dedicated, immediately-submitted encoder.\r\n                        const commandEncoder = this._device.createCommandEncoder();\r\n                        this._textureHelper.copyVideoToTexture(video, texture, gpuTextureWrapper.format, !invertY, commandEncoder);\r\n                        if (texture.generateMipMaps) {\r\n                            this._generateMipmaps(texture, commandEncoder);\r\n                        }\r\n                        this._device.queue.submit([commandEncoder.finish()]);\r\n                    } else {\r\n                        this._textureHelper.copyVideoToTexture(video, texture, gpuTextureWrapper.format, !invertY);\r\n                        if (texture.generateMipMaps) {\r\n                            this._generateMipmaps(texture);\r\n                        }\r\n                    }\r\n                } catch (e) {\r\n                    // WebGPU doesn't support video element who are not playing so far\r\n                    // Ignore this error ensures we can start a video texture in a paused state\r\n                }\r\n                texture.isReady = true;\r\n            }\r\n        } else if (video) {\r\n            this.createImageBitmap(video)\r\n                // eslint-disable-next-line github/no-then\r\n                .then((bitmap) => {\r\n                    this._textureHelper.updateTexture(bitmap, texture, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, !invertY, false, 0, 0);\r\n                    if (texture.generateMipMaps) {\r\n                        this._generateMipmaps(texture);\r\n                    }\r\n\r\n                    texture.isReady = true;\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .catch(() => {\r\n                    // Sometimes createImageBitmap(video) fails with \"Failed to execute 'createImageBitmap' on 'Window': The provided element's player has no current data.\"\r\n                    // Just keep going on\r\n                    texture.isReady = true;\r\n                });\r\n        }\r\n    };\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"clearQuadVertexShader\";\nconst shader = `uniform depthValue: f32;const pos=array(\nvec2f(-1.0,1.0),\nvec2f(1.0,1.0),\nvec2f(-1.0,-1.0),\nvec2f(1.0,-1.0)\n);\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.position=vec4f(pos[vertexInputs.vertexIndex],uniforms.depthValue,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const clearQuadVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"clearQuadPixelShader\";\nconst shader = `uniform color: vec4f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=uniforms.color;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const clearQuadPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"helperFunctions\";\nconst shader = `const PI: f32=3.1415926535897932384626433832795;const TWO_PI: f32=6.283185307179586;const HALF_PI: f32=1.5707963267948966;const RECIPROCAL_PI: f32=0.3183098861837907;const RECIPROCAL_PI2: f32=0.15915494309189535;const RECIPROCAL_PI4: f32=0.07957747154594767;const HALF_MIN: f32=5.96046448e-08; \nconst LinearEncodePowerApprox: f32=2.2;const GammaEncodePowerApprox: f32=1.0/LinearEncodePowerApprox;const LuminanceEncodeApprox: vec3f=vec3f(0.2126,0.7152,0.0722);const Epsilon:f32=0.0000001;fn square(x: f32)->f32 {return x*x;}\nfn saturate(x: f32)->f32 {return clamp(x,0.0,1.0);}\nfn saturateVec3(x: vec3f)->vec3f {return clamp(x,vec3f(),vec3f(1.0));}\nfn saturateEps(x: f32)->f32 {return clamp(x,Epsilon,1.0);}\nfn maxEps(x: f32)->f32 {return max(x,Epsilon);}\nfn maxEpsVec3(x: vec3f)->vec3f {return max(x,vec3f(Epsilon));}\nfn absEps(x: f32)->f32 {return abs(x)+Epsilon;}\nfn transposeMat3(inMatrix: mat3x3f)->mat3x3f {let i0: vec3f=inMatrix[0];let i1: vec3f=inMatrix[1];let i2: vec3f=inMatrix[2];let outMatrix:mat3x3f=mat3x3f(\nvec3(i0.x,i1.x,i2.x),\nvec3(i0.y,i1.y,i2.y),\nvec3(i0.z,i1.z,i2.z)\n);return outMatrix;}\nfn inverseMat3(inMatrix: mat3x3f)->mat3x3f {let a00: f32=inMatrix[0][0];let a01: f32=inMatrix[0][1];let a02: f32=inMatrix[0][2];let a10: f32=inMatrix[1][0];let a11: f32=inMatrix[1][1];let a12: f32=inMatrix[1][2];let a20: f32=inMatrix[2][0];let a21: f32=inMatrix[2][1];let a22: f32=inMatrix[2][2];let b01: f32=a22*a11-a12*a21;let b11: f32=-a22*a10+a12*a20;let b21: f32=a21*a10-a11*a20;let det: f32=a00*b01+a01*b11+a02*b21;return mat3x3f(b01/det,(-a22*a01+a02*a21)/det,(a12*a01-a02*a11)/det,\nb11/det,(a22*a00-a02*a20)/det,(-a12*a00+a02*a10)/det,\nb21/det,(-a21*a00+a01*a20)/det,(a11*a00-a01*a10)/det);}\n#if USE_EXACT_SRGB_CONVERSIONS\nfn toLinearSpaceExact(color: vec3f)->vec3f\n{let nearZeroSection: vec3f=0.0773993808*color;let remainingSection: vec3f=pow(0.947867299*(color+vec3f(0.055)),vec3f(2.4));return select(remainingSection,nearZeroSection,color<=vec3f(0.04045));}\nfn toGammaSpaceExact(color: vec3f)->vec3f\n{let nearZeroSection: vec3f=12.92*color;let remainingSection: vec3f=1.055*pow(color,vec3f(0.41666))-vec3f(0.055);return select(remainingSection,nearZeroSection,color<=vec3f(0.0031308));}\n#endif\nfn toLinearSpace(color: f32)->f32\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nvar nearZeroSection=0.0773993808*color;var remainingSection=pow(0.947867299*(color+0.055),2.4);return select(remainingSection,nearZeroSection,color<=0.04045);\n#else\nreturn pow(color,LinearEncodePowerApprox);\n#endif\n}\nfn toLinearSpaceVec3(color: vec3f)->vec3f\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toLinearSpaceExact(color);\n#else\nreturn pow(color,vec3f(LinearEncodePowerApprox));\n#endif\n}\nfn toLinearSpaceVec4(color: vec4<f32>)->vec4<f32>\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4f(toLinearSpaceExact(color.rgb),color.a);\n#else\nreturn vec4f(pow(color.rgb,vec3f(LinearEncodePowerApprox)),color.a);\n#endif\n}\nfn toGammaSpace(color: vec4<f32>)->vec4<f32>\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4<f32>(toGammaSpaceExact(color.rgb),color.a);\n#else\nreturn vec4<f32>(pow(color.rgb,vec3f(GammaEncodePowerApprox)),color.a);\n#endif\n}\nfn toGammaSpaceVec3(color: vec3f)->vec3f\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toGammaSpaceExact(color);\n#else\nreturn pow(color,vec3f(GammaEncodePowerApprox));\n#endif\n}\nfn squareVec3(value: vec3f)->vec3f\n{return value*value;}\nfn pow5(value: f32)->f32 {let sq: f32=value*value;return sq*sq*value;}\nfn double_refract(I: vec3f,N: vec3f,eta: f32)->vec3f {let Tfront: vec3f=refract(I,N,1.0/eta);let Nback: vec3f=normalize(reflect(N,Tfront));return refract(Tfront,-Nback,eta);}\nfn getLuminanceUnclamped(color: vec3f)->f32\n{return dot(color,LuminanceEncodeApprox);}\nfn getLuminance(color: vec3f)->f32\n{return saturate(getLuminanceUnclamped(color));}\nfn getRand(seed: vec2<f32>)->f32 {return fract(sin(dot(seed.xy ,vec2<f32>(12.9898,78.233)))*43758.5453);}\nfn dither(seed: vec2<f32>,varianceAmount: f32)->f32 {let rand: f32=getRand(seed);let normVariance: f32=varianceAmount/255.0;let dither: f32=mix(-normVariance,normVariance,rand);return dither;}\nconst rgbdMaxRange: f32=255.0;fn toRGBD(color: vec3f)->vec4<f32> {let maxRGB: f32=max(max(color.r,max(color.g,color.b)),Epsilon);var D: f32 =max(rgbdMaxRange/maxRGB,1.);D =clamp(floor(D)/255.0,0.,1.);var rgb: vec3f =color.rgb*D;rgb=toGammaSpaceVec3(rgb);return vec4<f32>(saturateVec3(rgb),D);}\nfn fromRGBD(rgbd: vec4<f32>)->vec3f {let rgb=toLinearSpaceVec3(rgbd.rgb);return rgb/rgbd.a;}\nfn parallaxCorrectNormal(vertexPos: vec3f,origVec: vec3f,cubeSize: vec3f,cubePos: vec3f)->vec3f {let invOrigVec: vec3f=vec3f(1.)/origVec;let halfSize: vec3f=cubeSize*0.5;let intersecAtMaxPlane: vec3f=(cubePos+halfSize-vertexPos)*invOrigVec;let intersecAtMinPlane: vec3f=(cubePos-halfSize-vertexPos)*invOrigVec;let largestIntersec: vec3f=max(intersecAtMaxPlane,intersecAtMinPlane);let distance: f32=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);let intersectPositionWS: vec3f=vertexPos+origVec*distance;return intersectPositionWS-cubePos;}\nfn equirectangularToCubemapDirection(uv : vec2f)->vec3f {var longitude : f32=uv.x*TWO_PI-PI;var latitude : f32=HALF_PI-uv.y*PI;var direction : vec3f;direction.x=cos(latitude)*sin(longitude);direction.y=sin(latitude);direction.z=cos(latitude)*cos(longitude);return direction;}\nfn sqrtClamped(value: f32)->f32 {return sqrt(max(value,0.));}\nfn avg(value: vec3f)->f32 {return dot(value,vec3f(0.333333333));}\nfn singleScatterToMultiScatterAlbedo(rho_ss: vec3f)->vec3f {let s: vec3f=sqrt(max(vec3f(1.0)-rho_ss,vec3f(0.0)));return (vec3f(1.0)-s)*(vec3f(1.0)-vec3f(0.139)*s)/(vec3f(1.0)+vec3f(1.17)*s);}\nfn multiScatterToSingleScatterAlbedo(rho_ms: vec3f)->vec3f {let s: vec3f=4.09712f+4.20863f*rho_ms-sqrt(9.59217f+41.6808f*rho_ms+17.7126f*rho_ms*rho_ms);return 1.0f-s*s;}\nfn multiScatterToSingleScatterAlbedoWithAniso(rho_ms: vec3f,aniso: f32)->vec3f {let s: vec3f=4.09712+4.20863f*rho_ms-sqrt(9.59217f+41.6808f*rho_ms+17.7126f*rho_ms*rho_ms);return (vec3f(1.0f)-s*s)/maxEpsVec3(vec3f(1.0f)-vec3f(aniso)*s*s);}\nfn min3(v: vec3f)->f32 {return min(v.x,min(v.y,v.z));}\nfn max3(v: vec3f)->f32 {return max(v.x,max(v.y,v.z));}\nfn uint2float(i: u32)->f32 {return bitcast<f32>(0x3F800000u | (i>>9u))-1.0;}\nfn plasticSequence(rstate: u32)->vec2f {return vec2f(uint2float(rstate*3242174889u),\nuint2float(rstate*2447445414u));}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const helperFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fresnelFunction\";\nconst shader = `#ifdef FRESNEL\nfn computeFresnelTerm(viewDirection: vec3f,worldNormal: vec3f,bias: f32,power: f32)->f32\n{let fresnelTerm: f32=pow(bias+abs(dot(viewDirection,worldNormal)),power);return clamp(fresnelTerm,0.,1.);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const fresnelFunctionWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"meshUboDeclaration\";\nconst shader = `struct Mesh {world : mat4x4<f32>,\nvisibility : f32,};var<uniform> mesh : Mesh;\n#define WORLD_UBO\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const meshUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"sceneUboDeclaration\";\nconst shader = `struct Scene {viewProjection : mat4x4<f32>,\n#ifdef MULTIVIEW\nviewProjectionR : mat4x4<f32>,\n#endif \nview : mat4x4<f32>,\nprojection : mat4x4<f32>,\nvEyePosition : vec4<f32>,\ninverseProjection : mat4x4<f32>,};\n#define SCENE_UBO\nvar<uniform> scene : Scene;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const sceneUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"decalFragment\";\nconst shader = `#ifdef DECAL\nvar decalTempColor=decalColor.rgb;var decalTempAlpha=decalColor.a;\n#ifdef GAMMADECAL\ndecalTempColor=toLinearSpaceVec3(decalColor.rgb);\n#endif\n#ifdef DECAL_SMOOTHALPHA\ndecalTempAlpha=decalColor.a*decalColor.a;\n#endif\nsurfaceAlbedo=mix(surfaceAlbedo.rgb,decalTempColor,decalTempAlpha);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const decalFragmentWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { Engine } from \"./engine.pure\";\r\nimport { ThinNativeEngine } from \"./thinNativeEngine.pure\";\r\nimport { type ThinNativeEngineOptions } from \"./thinNativeEngine\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * Options to create the Native engine\r\n */\r\nexport interface NativeEngineOptions extends ThinNativeEngineOptions {}\r\n\r\n/** @internal */\r\nexport class NativeEngine extends Engine {\r\n    /**\r\n     * @internal\r\n     * Will be overriden by the Thin Native engine implementation\r\n     * No code should be placed here\r\n     */\r\n    protected _initializeNativeEngine(_adaptToDeviceRatio: boolean): void {}\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public constructor(options: NativeEngineOptions = {}) {\r\n        super(null, false, undefined, options.adaptToDeviceRatio);\r\n\r\n        this._initializeNativeEngine(options.adaptToDeviceRatio ?? false);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override wrapWebGLTexture(): InternalTexture {\r\n        throw new Error(\"wrapWebGLTexture is not supported, use wrapNativeTexture instead.\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override updateWrappedWebGLTexture(): void {\r\n        throw new Error(\"updateWrappedWebGLTexture is not supported, use updateWrappedNativeTexture instead.\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement, _faceIndex: number = 0, _lod: number = 0) {\r\n        throw new Error(\"_uploadArrayBufferViewToTexture not implemented.\");\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n * Augments the NativeEngine type to include ThinNativeEngine methods and preventing dupplicate TS errors\r\n */\r\nexport interface NativeEngine extends Omit<ThinNativeEngine, keyof Engine> {}\r\n\r\n/**\r\n * @internal\r\n * Applies the functionality of one or more base constructors to a derived constructor.\r\n */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for nativeEngine.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNativeEngine(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    function applyMixins(derivedCtor: any, constructors: any[]) {\r\n        constructors.forEach((baseCtor) => {\r\n            Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {\r\n                if (name !== \"constructor\") {\r\n                    derivedCtor.prototype[name] = baseCtor.prototype[name];\r\n                }\r\n            });\r\n        });\r\n    }\r\n\r\n    // Apply the ThinNativeEngine mixins to the NativeEngine.\r\n    applyMixins(NativeEngine, [ThinNativeEngine]);\r\n}\r\n","import { type AbstractEngine } from \"./abstractEngine\";\r\nimport { Engine } from \"./engine.pure\";\r\nimport { NullEngine, type NullEngineOptions } from \"./nullEngine.pure\";\r\nimport { WebGPUEngine, type WebGPUEngineOptions } from \"./webgpuEngine.pure\";\r\nimport { type EngineOptions } from \"./thinEngine\";\r\n\r\n/**\r\n * Helper class to create the best engine depending on the current hardware\r\n */\r\nexport class EngineFactory {\r\n    /**\r\n     * Creates an engine based on the capabilities of the underlying hardware\r\n     * @param canvas Defines the canvas to use to display the result\r\n     * @param options Defines the options passed to the engine to create the context dependencies\r\n     * @returns a promise that resolves with the created engine\r\n     */\r\n    public static async CreateAsync(canvas: HTMLCanvasElement, options?: WebGPUEngineOptions | EngineOptions | NullEngineOptions): Promise<AbstractEngine> {\r\n        const supported = await WebGPUEngine.IsSupportedAsync;\r\n        if (supported) {\r\n            return await WebGPUEngine.CreateAsync(canvas, options as WebGPUEngineOptions);\r\n        }\r\n        if (Engine.IsSupported) {\r\n            return new Engine(canvas, undefined, options as EngineOptions);\r\n        }\r\n        return new NullEngine(options as NullEngineOptions);\r\n    }\r\n}\r\n","/**\r\n * Gather the list of clipboard event types as constants.\r\n */\r\nexport class ClipboardEventTypes {\r\n    /**\r\n     * The clipboard event is fired when a copy command is active (pressed).\r\n     */\r\n    public static readonly COPY = 0x01; //\r\n    /**\r\n     *  The clipboard event is fired when a cut command is active (pressed).\r\n     */\r\n    public static readonly CUT = 0x02;\r\n\r\n    /**\r\n     * The clipboard event is fired when a paste command is active (pressed).\r\n     */\r\n    public static readonly PASTE = 0x03;\r\n}\r\n/**\r\n * This class is used to store clipboard related info for the onClipboardObservable event.\r\n */\r\nexport class ClipboardInfo {\r\n    /**\r\n     *Creates an instance of ClipboardInfo.\r\n     * @param type Defines the type of event (BABYLON.ClipboardEventTypes)\r\n     * @param event Defines the related dom event\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the type of event (BABYLON.ClipboardEventTypes)\r\n         */\r\n        public type: number,\r\n        /**\r\n         * Defines the related dom event\r\n         */\r\n        public event: ClipboardEvent\r\n    ) {}\r\n\r\n    /**\r\n     *  Get the clipboard event's type from the keycode.\r\n     * @param keyCode Defines the keyCode for the current keyboard event.\r\n     * @returns {number}\r\n     */\r\n    public static GetTypeFromCharacter(keyCode: number): number {\r\n        const charCode = keyCode;\r\n        //TODO: add codes for extended ASCII\r\n        switch (charCode) {\r\n            case 67:\r\n                return ClipboardEventTypes.COPY;\r\n            case 86:\r\n                return ClipboardEventTypes.PASTE;\r\n            case 88:\r\n                return ClipboardEventTypes.CUT;\r\n            default:\r\n                return -1;\r\n        }\r\n    }\r\n}\r\n","import { RegisterClass } from \"../../Misc/typeStore\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Class that represents an integer value.\r\n */\r\nexport class FlowGraphInteger {\r\n    /**\r\n     * The value of the integer. Its type\r\n     * is a javascript number. Shouldn't be\r\n     * directly modified - it is populated by\r\n     * the constructor.\r\n     */\r\n    readonly value: number;\r\n\r\n    constructor(value: number) {\r\n        this.value = this._toInt(value);\r\n    }\r\n\r\n    /**\r\n     * Converts a float to an integer.\r\n     * @param n the float to convert\r\n     * @returns the result of n | 0 - converting it to a int\r\n     */\r\n    private _toInt(n: number): number {\r\n        return n | 0;\r\n    }\r\n\r\n    /**\r\n     * Adds two integers together.\r\n     * @param other the other integer to add\r\n     * @returns a FlowGraphInteger with the result of the addition\r\n     */\r\n    public add(other: FlowGraphInteger): FlowGraphInteger {\r\n        return new FlowGraphInteger(this.value + other.value);\r\n    }\r\n\r\n    /**\r\n     * Subtracts two integers.\r\n     * @param other the other integer to subtract\r\n     * @returns a FlowGraphInteger with the result of the subtraction\r\n     */\r\n    public subtract(other: FlowGraphInteger): FlowGraphInteger {\r\n        return new FlowGraphInteger(this.value - other.value);\r\n    }\r\n\r\n    /**\r\n     * Multiplies two integers.\r\n     * @param other the other integer to multiply\r\n     * @returns a FlowGraphInteger with the result of the multiplication\r\n     */\r\n    public multiply(other: FlowGraphInteger): FlowGraphInteger {\r\n        return new FlowGraphInteger(Math.imul(this.value, other.value));\r\n    }\r\n\r\n    /**\r\n     * Divides two integers.\r\n     * @param other the other integer to divide\r\n     * @returns a FlowGraphInteger with the result of the division\r\n     */\r\n    public divide(other: FlowGraphInteger): FlowGraphInteger {\r\n        return new FlowGraphInteger(this.value / other.value);\r\n    }\r\n\r\n    /**\r\n     * The class name of this type.\r\n     * @returns\r\n     */\r\n    public getClassName() {\r\n        return FlowGraphInteger.ClassName;\r\n    }\r\n\r\n    /**\r\n     * Compares two integers for equality.\r\n     * @param other the other integer to compare\r\n     * @returns true if the integers are equal\r\n     */\r\n    public equals(other: FlowGraphInteger): boolean {\r\n        return this.value === other.value;\r\n    }\r\n\r\n    /** The class name of this type */\r\n    public static ClassName = \"FlowGraphInteger\";\r\n\r\n    /**\r\n     * Parses a FlowGraphInteger from a serialization object.\r\n     * @param value te number to parse\r\n     * @returns a new FlowGraphInteger\r\n     */\r\n    public static FromValue(value: number): FlowGraphInteger {\r\n        return new FlowGraphInteger(value);\r\n    }\r\n\r\n    /**\r\n     * Returns a string representation of this integer\r\n     * @returns the string representation\r\n     */\r\n    public toString(): string {\r\n        return this.value.toString();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphInteger.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphInteger(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"FlowGraphInteger\", FlowGraphInteger);\r\n}\r\n","import { Vector3, Vector2 } from \"core/Maths/math.vector.pure\";\n\n/**\n * Interface representing a generic flow graph matrix.\n *\n * BREAKING (since the KHR_interactivity work): {@link FlowGraphMatrix2D} and {@link FlowGraphMatrix3D}\n * now store their elements in column-major order, matching core {@link Matrix} and the\n * glTF/KHR_interactivity convention. Previous releases stored them row-major. This changes the result\n * of building a matrix from a flat array (`fromArray`/`set`), of `transformVector`/`transformVectorToRef`,\n * and of `multiply`/`multiplyToRef` (which now computes `this * other` rather than `other * this`).\n * There is no compile error — graphs that relied on the old ordering or operand order get silently\n * different numbers, so any code constructing these from raw arrays should be re-checked.\n */\nexport interface IFlowGraphMatrix<VectorType> {\n    /**\n     * The matrix elements stored in column-major order.\n     */\n    m: number[];\n\n    /**\n     * Transforms a vector using this matrix.\n     *\n     * @param v - The vector to transform.\n     * @returns The transformed vector.\n     */\n    transformVector(v: VectorType): VectorType;\n\n    /**\n     * Transforms a vector using this matrix and stores the result in a reference vector.\n     *\n     * @param v - The vector to transform.\n     * @param result - The vector to store the result.\n     * @returns The transformed vector.\n     */\n    transformVectorToRef(v: VectorType, result: VectorType): VectorType;\n\n    /**\n     * Returns the matrix elements as an array.\n     *\n     * @returns The matrix elements as an array.\n     */\n    asArray(): number[];\n\n    /**\n     * Copies the matrix elements to an array.\n     *\n     * @param emptyArray - The array to copy the elements to.\n     * @returns The array with the matrix elements.\n     */\n    toArray(emptyArray: number[]): number[];\n\n    /**\n     * Sets the matrix elements from an array.\n     *\n     * @param array - The array containing the matrix elements.\n     * @returns The updated matrix.\n     */\n    fromArray(array: number[]): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Multiplies this matrix with another matrix and stores the result in a reference matrix.\n     *\n     * @param other - The matrix to multiply with.\n     * @param result - The matrix to store the result.\n     * @returns The result matrix.\n     */\n    multiplyToRef(other: IFlowGraphMatrix<VectorType>, result: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Multiplies this matrix with another matrix.\n     * To staz conform with the Matrix class, this does B * A\n     *\n     * @param other - The matrix to multiply with.\n     * @returns The result matrix.\n     */\n    multiply(other: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Divides this matrix by another matrix and stores the result in a reference matrix.\n     *\n     * @param other - The matrix to divide by.\n     * @param result - The matrix to store the result.\n     * @returns The result matrix.\n     */\n    divideToRef(other: IFlowGraphMatrix<VectorType>, result: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Divides this matrix by another matrix.\n     *\n     * @param other - The matrix to divide by.\n     * @returns The result matrix.\n     */\n    divide(other: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Adds another matrix to this matrix and stores the result in a reference matrix.\n     *\n     * @param other - The matrix to add.\n     * @param result - The matrix to store the result.\n     * @returns The result matrix.\n     */\n    addToRef(other: IFlowGraphMatrix<VectorType>, result: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Adds another matrix to this matrix.\n     *\n     * @param other - The matrix to add.\n     * @returns The result matrix.\n     */\n    add(other: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Subtracts another matrix from this matrix and stores the result in a reference matrix.\n     *\n     * @param other - The matrix to subtract.\n     * @param result - The matrix to store the result.\n     * @returns The result matrix.\n     */\n    subtractToRef(other: IFlowGraphMatrix<VectorType>, result: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Subtracts another matrix from this matrix.\n     *\n     * @param other - The matrix to subtract.\n     * @returns The result matrix.\n     */\n    subtract(other: IFlowGraphMatrix<VectorType>): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Transposes this matrix.\n     *\n     * @returns The transposed matrix.\n     */\n    transpose(): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Computes the determinant of this matrix.\n     *\n     * @returns The determinant of the matrix.\n     */\n    determinant(): number;\n\n    /**\n     * Computes the inverse of this matrix.\n     *\n     * @returns The inverse of the matrix.\n     * @throws Error if the matrix is not invertible.\n     */\n    inverse(): IFlowGraphMatrix<VectorType>;\n\n    /**\n     * Gets the class name of this matrix.\n     *\n     * @returns The class name.\n     */\n    getClassName(): string;\n\n    /**\n     * Checks if this matrix is equal to another matrix within an optional epsilon.\n     *\n     * @param other - The matrix to compare with.\n     * @param epsilon - The optional epsilon for comparison.\n     * @returns True if the matrices are equal, false otherwise.\n     */\n    equals(other: IFlowGraphMatrix<VectorType>, epsilon?: number): boolean;\n}\n\n// Note - the matrix classes are basically column-major, and work similarly to Babylon.js' Matrix class.\n\n/**\n * A 2x2 matrix, stored in column-major order.\n *\n * BREAKING: this class was row-major in earlier releases — see {@link IFlowGraphMatrix} for the full\n * behaviour change (flat-array construction, transform, and multiply operand order).\n */\nexport class FlowGraphMatrix2D implements IFlowGraphMatrix<Vector2> {\n    /**\n     * @internal\n     */\n    public _m: number[];\n\n    constructor(m: number[] = [1, 0, 0, 1]) {\n        this._m = m;\n    }\n\n    public get m(): number[] {\n        return this._m;\n    }\n\n    public transformVector(v: Vector2): Vector2 {\n        return this.transformVectorToRef(v, new Vector2());\n    }\n\n    public transformVectorToRef(v: Vector2, result: Vector2): Vector2 {\n        result.x = v.x * this._m[0] + v.y * this._m[2];\n        result.y = v.x * this._m[1] + v.y * this._m[3];\n        return result;\n    }\n\n    public asArray(): number[] {\n        return this.toArray();\n    }\n\n    public toArray(emptyArray: number[] = []): number[] {\n        for (let i = 0; i < 4; i++) {\n            emptyArray[i] = this._m[i];\n        }\n        return emptyArray;\n    }\n\n    public fromArray(array: number[]): FlowGraphMatrix2D {\n        for (let i = 0; i < 4; i++) {\n            this._m[i] = array[i];\n        }\n        return this;\n    }\n\n    public multiplyToRef(other: FlowGraphMatrix2D, result: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        const otherMatrix = other._m;\n        const thisMatrix = this._m;\n        const r = result._m;\n        // this * other, column-major (matches core Matrix and the glTF/KHR_interactivity convention)\n        r[0] = thisMatrix[0] * otherMatrix[0] + thisMatrix[1] * otherMatrix[2];\n        r[1] = thisMatrix[0] * otherMatrix[1] + thisMatrix[1] * otherMatrix[3];\n        r[2] = thisMatrix[2] * otherMatrix[0] + thisMatrix[3] * otherMatrix[2];\n        r[3] = thisMatrix[2] * otherMatrix[1] + thisMatrix[3] * otherMatrix[3];\n\n        return result;\n    }\n\n    public multiply(other: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        return this.multiplyToRef(other, new FlowGraphMatrix2D());\n    }\n\n    public divideToRef(other: FlowGraphMatrix2D, result: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        const m = this._m;\n        const o = other._m;\n        const r = result._m;\n\n        r[0] = m[0] / o[0];\n        r[1] = m[1] / o[1];\n        r[2] = m[2] / o[2];\n        r[3] = m[3] / o[3];\n\n        return result;\n    }\n\n    public divide(other: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        return this.divideToRef(other, new FlowGraphMatrix2D());\n    }\n\n    public addToRef(other: FlowGraphMatrix2D, result: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        const m = this._m;\n        const o = other.m;\n        const r = result.m;\n\n        r[0] = m[0] + o[0];\n        r[1] = m[1] + o[1];\n        r[2] = m[2] + o[2];\n        r[3] = m[3] + o[3];\n\n        return result;\n    }\n\n    public add(other: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        return this.addToRef(other, new FlowGraphMatrix2D());\n    }\n\n    public subtractToRef(other: FlowGraphMatrix2D, result: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        const m = this._m;\n        const o = other.m;\n        const r = result.m;\n\n        r[0] = m[0] - o[0];\n        r[1] = m[1] - o[1];\n        r[2] = m[2] - o[2];\n        r[3] = m[3] - o[3];\n\n        return result;\n    }\n\n    public subtract(other: FlowGraphMatrix2D): FlowGraphMatrix2D {\n        return this.subtractToRef(other, new FlowGraphMatrix2D());\n    }\n\n    public transpose(): FlowGraphMatrix2D {\n        const m = this._m;\n        return new FlowGraphMatrix2D([m[0], m[2], m[1], m[3]]);\n    }\n\n    public determinant(): number {\n        const m = this._m;\n        return m[0] * m[3] - m[1] * m[2];\n    }\n\n    public inverse(): FlowGraphMatrix2D {\n        const det = this.determinant();\n        if (det === 0) {\n            throw new Error(\"Matrix is not invertible\");\n        }\n        const m = this._m;\n        const invDet = 1 / det;\n        return new FlowGraphMatrix2D([m[3] * invDet, -m[1] * invDet, -m[2] * invDet, m[0] * invDet]);\n    }\n\n    public equals(other: IFlowGraphMatrix<Vector2>, epsilon: number = 0): boolean {\n        const m = this._m;\n        const o = other.m;\n        if (epsilon === 0) {\n            return m[0] === o[0] && m[1] === o[1] && m[2] === o[2] && m[3] === o[3];\n        }\n        return Math.abs(m[0] - o[0]) < epsilon && Math.abs(m[1] - o[1]) < epsilon && Math.abs(m[2] - o[2]) < epsilon && Math.abs(m[3] - o[3]) < epsilon;\n    }\n\n    public getClassName(): string {\n        return \"FlowGraphMatrix2D\";\n    }\n\n    public toString(): string {\n        return `FlowGraphMatrix2D(${this._m.join(\", \")})`;\n    }\n}\n\n/**\n * A 3x3 matrix, stored in column-major order.\n *\n * BREAKING: this class was row-major in earlier releases — see {@link IFlowGraphMatrix} for the full\n * behaviour change (flat-array construction, transform, and multiply operand order).\n */\nexport class FlowGraphMatrix3D implements IFlowGraphMatrix<Vector3> {\n    /**\n     * @internal\n     */\n    public _m: number[];\n\n    constructor(array: number[] = [1, 0, 0, 0, 1, 0, 0, 0, 1]) {\n        this._m = array;\n    }\n\n    public get m(): number[] {\n        return this._m;\n    }\n\n    public transformVector(v: Vector3): Vector3 {\n        return this.transformVectorToRef(v, new Vector3());\n    }\n\n    public transformVectorToRef(v: Vector3, result: Vector3): Vector3 {\n        const m = this._m;\n        result.x = v.x * m[0] + v.y * m[3] + v.z * m[6];\n        result.y = v.x * m[1] + v.y * m[4] + v.z * m[7];\n        result.z = v.x * m[2] + v.y * m[5] + v.z * m[8];\n        return result;\n    }\n\n    public multiplyToRef(other: FlowGraphMatrix3D, result: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        const otherMatrix = other._m;\n        const thisMatrix = this._m;\n        const r = result.m;\n\n        r[0] = thisMatrix[0] * otherMatrix[0] + thisMatrix[1] * otherMatrix[3] + thisMatrix[2] * otherMatrix[6];\n        r[1] = thisMatrix[0] * otherMatrix[1] + thisMatrix[1] * otherMatrix[4] + thisMatrix[2] * otherMatrix[7];\n        r[2] = thisMatrix[0] * otherMatrix[2] + thisMatrix[1] * otherMatrix[5] + thisMatrix[2] * otherMatrix[8];\n\n        r[3] = thisMatrix[3] * otherMatrix[0] + thisMatrix[4] * otherMatrix[3] + thisMatrix[5] * otherMatrix[6];\n        r[4] = thisMatrix[3] * otherMatrix[1] + thisMatrix[4] * otherMatrix[4] + thisMatrix[5] * otherMatrix[7];\n        r[5] = thisMatrix[3] * otherMatrix[2] + thisMatrix[4] * otherMatrix[5] + thisMatrix[5] * otherMatrix[8];\n\n        r[6] = thisMatrix[6] * otherMatrix[0] + thisMatrix[7] * otherMatrix[3] + thisMatrix[8] * otherMatrix[6];\n        r[7] = thisMatrix[6] * otherMatrix[1] + thisMatrix[7] * otherMatrix[4] + thisMatrix[8] * otherMatrix[7];\n        r[8] = thisMatrix[6] * otherMatrix[2] + thisMatrix[7] * otherMatrix[5] + thisMatrix[8] * otherMatrix[8];\n\n        return result;\n    }\n\n    public multiply(other: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        return this.multiplyToRef(other, new FlowGraphMatrix3D());\n    }\n\n    public divideToRef(other: FlowGraphMatrix3D, result: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        const m = this._m;\n        const o = other.m;\n        const r = result.m;\n\n        r[0] = m[0] / o[0];\n        r[1] = m[1] / o[1];\n        r[2] = m[2] / o[2];\n        r[3] = m[3] / o[3];\n        r[4] = m[4] / o[4];\n        r[5] = m[5] / o[5];\n        r[6] = m[6] / o[6];\n        r[7] = m[7] / o[7];\n        r[8] = m[8] / o[8];\n\n        return result;\n    }\n\n    public divide(other: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        return this.divideToRef(other, new FlowGraphMatrix3D());\n    }\n\n    public addToRef(other: FlowGraphMatrix3D, result: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        const m = this._m;\n        const o = other.m;\n        const r = result.m;\n\n        r[0] = m[0] + o[0];\n        r[1] = m[1] + o[1];\n        r[2] = m[2] + o[2];\n        r[3] = m[3] + o[3];\n        r[4] = m[4] + o[4];\n        r[5] = m[5] + o[5];\n        r[6] = m[6] + o[6];\n        r[7] = m[7] + o[7];\n        r[8] = m[8] + o[8];\n\n        return result;\n    }\n\n    public add(other: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        return this.addToRef(other, new FlowGraphMatrix3D());\n    }\n\n    public subtractToRef(other: FlowGraphMatrix3D, result: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        const m = this._m;\n        const o = other.m;\n        const r = result.m;\n\n        r[0] = m[0] - o[0];\n        r[1] = m[1] - o[1];\n        r[2] = m[2] - o[2];\n        r[3] = m[3] - o[3];\n        r[4] = m[4] - o[4];\n        r[5] = m[5] - o[5];\n        r[6] = m[6] - o[6];\n        r[7] = m[7] - o[7];\n        r[8] = m[8] - o[8];\n\n        return result;\n    }\n\n    public subtract(other: FlowGraphMatrix3D): FlowGraphMatrix3D {\n        return this.subtractToRef(other, new FlowGraphMatrix3D());\n    }\n\n    public toArray(emptyArray: number[] = []): number[] {\n        for (let i = 0; i < 9; i++) {\n            emptyArray[i] = this._m[i];\n        }\n        return emptyArray;\n    }\n\n    public asArray(): number[] {\n        return this.toArray();\n    }\n\n    public fromArray(array: number[]): FlowGraphMatrix3D {\n        for (let i = 0; i < 9; i++) {\n            this._m[i] = array[i];\n        }\n        return this;\n    }\n\n    public transpose(): FlowGraphMatrix3D {\n        const m = this._m;\n        return new FlowGraphMatrix3D([m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]]);\n    }\n\n    public determinant(): number {\n        const m = this._m;\n        return m[0] * (m[4] * m[8] - m[5] * m[7]) - m[1] * (m[3] * m[8] - m[5] * m[6]) + m[2] * (m[3] * m[7] - m[4] * m[6]);\n    }\n\n    public inverse(): FlowGraphMatrix3D {\n        const det = this.determinant();\n        if (det === 0) {\n            throw new Error(\"Matrix is not invertible\");\n        }\n        const m = this._m;\n        const invDet = 1 / det;\n        return new FlowGraphMatrix3D([\n            (m[4] * m[8] - m[5] * m[7]) * invDet,\n            (m[2] * m[7] - m[1] * m[8]) * invDet,\n            (m[1] * m[5] - m[2] * m[4]) * invDet,\n            (m[5] * m[6] - m[3] * m[8]) * invDet,\n            (m[0] * m[8] - m[2] * m[6]) * invDet,\n            (m[2] * m[3] - m[0] * m[5]) * invDet,\n            (m[3] * m[7] - m[4] * m[6]) * invDet,\n            (m[1] * m[6] - m[0] * m[7]) * invDet,\n            (m[0] * m[4] - m[1] * m[3]) * invDet,\n        ]);\n    }\n\n    public equals(other: IFlowGraphMatrix<Vector3>, epsilon: number = 0): boolean {\n        const m = this._m;\n        const o = other.m;\n        // performance shortcut\n        if (epsilon === 0) {\n            return m[0] === o[0] && m[1] === o[1] && m[2] === o[2] && m[3] === o[3] && m[4] === o[4] && m[5] === o[5] && m[6] === o[6] && m[7] === o[7] && m[8] === o[8];\n        }\n        return (\n            Math.abs(m[0] - o[0]) < epsilon &&\n            Math.abs(m[1] - o[1]) < epsilon &&\n            Math.abs(m[2] - o[2]) < epsilon &&\n            Math.abs(m[3] - o[3]) < epsilon &&\n            Math.abs(m[4] - o[4]) < epsilon &&\n            Math.abs(m[5] - o[5]) < epsilon &&\n            Math.abs(m[6] - o[6]) < epsilon &&\n            Math.abs(m[7] - o[7]) < epsilon &&\n            Math.abs(m[8] - o[8]) < epsilon\n        );\n    }\n\n    public getClassName(): string {\n        return \"FlowGraphMatrix3D\";\n    }\n\n    public toString(): string {\n        return `FlowGraphMatrix3D(${this._m.join(\", \")})`;\n    }\n}\n","import { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Matrix, Quaternion, Vector2, Vector3, Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { FlowGraphBlockNames } from \"./Blocks/flowGraphBlockNames\";\r\nimport { FlowGraphInteger } from \"./CustomTypes/flowGraphInteger.pure\";\r\nimport { FlowGraphTypes } from \"./flowGraphRichTypes.pure\";\r\nimport { type Node } from \"core/node\";\r\nimport { FlowGraphMatrix2D, FlowGraphMatrix3D } from \"./CustomTypes/flowGraphMatrix\";\r\n\r\nconst _DefaultEventDataParseCounts = new WeakMap<object, number>();\r\n\r\n/** @internal */\r\nexport function _GetDefaultEventDataParseCount(value: unknown): number {\r\n    return value !== null && typeof value === \"object\" ? (_DefaultEventDataParseCounts.get(value) ?? 0) : 0;\r\n}\r\n\r\nfunction IsVectorClassName(className: string) {\r\n    return (\r\n        className === FlowGraphTypes.Vector2 ||\r\n        className === FlowGraphTypes.Vector3 ||\r\n        className === FlowGraphTypes.Vector4 ||\r\n        className === FlowGraphTypes.Quaternion ||\r\n        className === FlowGraphTypes.Color3 ||\r\n        className === FlowGraphTypes.Color4\r\n    );\r\n}\r\n\r\nfunction IsMatrixClassName(className: string) {\r\n    return className === FlowGraphTypes.Matrix || className === FlowGraphTypes.Matrix2D || className === FlowGraphTypes.Matrix3D;\r\n}\r\n\r\nfunction IsAnimationGroupClassName(className: string) {\r\n    return className === \"AnimationGroup\";\r\n}\r\n\r\n/**\r\n * Resolves a serialized node reference (`{ id, name, className, uniqueId }`) to an actual scene node.\r\n * Matching prefers `id` (falling back to `name`), then narrows by class name, then by `uniqueId`.\r\n * Because `uniqueId` is reassigned every time a scene is built, it is only used as a tie-breaker so\r\n * that references still resolve after a scene is reloaded (e.g. an editor preview).\r\n * @param serializedReference the serialized reference to resolve\r\n * @param scene the scene to resolve the reference against\r\n * @returns the matching node, or undefined when none is found\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function GetSceneNodeFromSerializedReference(serializedReference: any, scene: Scene): Node | undefined {\r\n    if (!serializedReference || (!serializedReference.id && !serializedReference.name)) {\r\n        return undefined;\r\n    }\r\n\r\n    const nodes = scene.getNodes().filter((node) => (serializedReference.id ? node.id === serializedReference.id : node.name === serializedReference.name));\r\n    if (nodes.length === 0) {\r\n        return undefined;\r\n    }\r\n\r\n    const className = serializedReference.type ?? serializedReference.className;\r\n    const classMatches = className ? nodes.filter((node) => node.getClassName() === className) : [];\r\n    const candidates = classMatches.length > 0 ? classMatches : nodes;\r\n    return (serializedReference.uniqueId ? candidates.find((node) => node.uniqueId === serializedReference.uniqueId) : undefined) ?? candidates[0];\r\n}\r\n\r\nfunction ParseVector(className: string, value: Array<number>, flipHandedness = false) {\r\n    if (className === FlowGraphTypes.Vector2) {\r\n        return Vector2.FromArray(value);\r\n    } else if (className === FlowGraphTypes.Vector3) {\r\n        if (flipHandedness) {\r\n            value[2] *= -1;\r\n        }\r\n        return Vector3.FromArray(value);\r\n    } else if (className === FlowGraphTypes.Vector4) {\r\n        return Vector4.FromArray(value);\r\n    } else if (className === FlowGraphTypes.Quaternion) {\r\n        if (flipHandedness) {\r\n            value[2] *= -1;\r\n            value[3] *= -1;\r\n        }\r\n        return Quaternion.FromArray(value);\r\n    } else if (className === FlowGraphTypes.Color3) {\r\n        return new Color3(value[0], value[1], value[2]);\r\n    } else if (className === FlowGraphTypes.Color4) {\r\n        return new Color4(value[0], value[1], value[2], value[3]);\r\n    } else {\r\n        throw new Error(`Unknown vector class name ${className}`);\r\n    }\r\n}\r\n\r\n/**\r\n * The default function that serializes values in a context object to a serialization object\r\n * @param key the key where the value should be stored in the serialization object\r\n * @param value the value to store\r\n * @param serializationObject the object where the value will be stored\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function defaultValueSerializationFunction(key: string, value: any, serializationObject: any) {\r\n    const className = value?.getClassName?.() ?? \"\";\r\n    if (IsVectorClassName(className) || IsMatrixClassName(className)) {\r\n        serializationObject[key] = {\r\n            value: value.asArray(),\r\n            className,\r\n        };\r\n    } else if (className === FlowGraphTypes.Integer) {\r\n        serializationObject[key] = {\r\n            value: value.value,\r\n            className,\r\n        };\r\n    } else {\r\n        if (className && (value.id || value.name)) {\r\n            serializationObject[key] = {\r\n                id: value.id,\r\n                name: value.name,\r\n                className,\r\n                uniqueId: value.uniqueId,\r\n            };\r\n        } else {\r\n            if (typeof value !== \"object\" || value === null) {\r\n                serializationObject[key] = value;\r\n            } else {\r\n                // Skip known non-serializable keys immediately to avoid\r\n                // expensive JSON.stringify attempts on large object trees\r\n                // (e.g. pathConverter holds the entire glTF parse tree).\r\n                if (key === \"pathConverter\") {\r\n                    return;\r\n                }\r\n                // Quick check: if any own property is a function, the object\r\n                // is not JSON-safe and stringify would be wasteful.\r\n                const hasFunction = Object.values(value).some((v) => typeof v === \"function\");\r\n                if (hasFunction) {\r\n                    return;\r\n                }\r\n                // Plain object (e.g. parsed event config) — store it if JSON-safe.\r\n                try {\r\n                    serializationObject[key] = JSON.parse(JSON.stringify(value));\r\n                } catch {\r\n                    Logger.Warn(`FlowGraph serialization: value for key \"${key}\" is not JSON-serializable and was skipped.`);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * The default function that parses values stored in a serialization object\r\n * @param key the key to the value that will be parsed\r\n * @param serializationObject the object that will be parsed\r\n * @param assetsContainer the assets container that will be used to find the objects\r\n * @param scene\r\n * @returns\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function defaultValueParseFunction(key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) {\r\n    const intermediateValue = serializationObject[key];\r\n    let finalValue;\r\n    const className = intermediateValue?.type ?? intermediateValue?.className;\r\n    const sceneNode = GetSceneNodeFromSerializedReference(intermediateValue, scene);\r\n    if (sceneNode) {\r\n        finalValue = sceneNode;\r\n    } else if (IsVectorClassName(className)) {\r\n        finalValue = ParseVector(className, intermediateValue.value);\r\n    } else if (IsAnimationGroupClassName(className)) {\r\n        // do not use the scene.getAnimationGroupByName because it is possible that two AGs will have the same name\r\n        const ags = scene.animationGroups.filter((ag) => ag.name === intermediateValue.name);\r\n        // uniqueId changes on each load. this is used for the glTF loader, that uses serialization after the scene was loaded.\r\n        finalValue = ags.length === 1 ? ags[0] : ags.find((ag) => ag.uniqueId === intermediateValue.uniqueId);\r\n    } else if (className === FlowGraphTypes.Matrix) {\r\n        finalValue = Matrix.FromArray(intermediateValue.value);\r\n    } else if (className === FlowGraphTypes.Matrix2D) {\r\n        finalValue = new FlowGraphMatrix2D(intermediateValue.value);\r\n    } else if (className === FlowGraphTypes.Matrix3D) {\r\n        finalValue = new FlowGraphMatrix3D(intermediateValue.value);\r\n    } else if (className === FlowGraphTypes.Integer) {\r\n        finalValue = FlowGraphInteger.FromValue(intermediateValue.value);\r\n    } else if (className === FlowGraphTypes.Number || className === FlowGraphTypes.String || className === FlowGraphTypes.Boolean) {\r\n        finalValue = intermediateValue.value[0];\r\n    } else if (key === \"eventData\" && intermediateValue !== null && typeof intermediateValue === \"object\") {\r\n        _DefaultEventDataParseCounts.set(intermediateValue, _GetDefaultEventDataParseCount(intermediateValue) + 1);\r\n        finalValue = intermediateValue;\r\n    } else if (intermediateValue && intermediateValue.value !== undefined) {\r\n        finalValue = intermediateValue.value;\r\n    } else {\r\n        if (Array.isArray(intermediateValue)) {\r\n            finalValue = intermediateValue;\r\n        } else {\r\n            finalValue = intermediateValue;\r\n        }\r\n    }\r\n    return finalValue;\r\n}\r\n\r\n/**\r\n * Given a name of a flow graph block class, return if this\r\n * class needs to be created with a path converter. Used in\r\n * parsing.\r\n * @param className the name of the flow graph block class\r\n * @returns a boolean indicating if the class needs a path converter\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function needsPathConverter(className: string) {\r\n    // I am not using the ClassName property here because it was causing a circular dependency\r\n    return className === FlowGraphBlockNames.JsonPointerParser;\r\n}\r\n","import { type AnimationGroup } from \"core/Animations/animationGroup\";\nimport { type Animation } from \"core/Animations/animation\";\nimport { type Nullable } from \"core/types\";\nimport { type Mesh } from \"core/Meshes/mesh\";\nimport { type Material } from \"core/Materials/material\";\nimport { type Camera } from \"core/Cameras/camera\";\nimport { type Light } from \"core/Lights/light\";\nimport { type IAssetContainer } from \"core/IAssetContainer\";\n\n/**\n * The type of the assets that flow graph supports\n */\nexport const enum FlowGraphAssetType {\n    Animation = \"Animation\",\n    AnimationGroup = \"AnimationGroup\",\n    Mesh = \"Mesh\",\n    Material = \"Material\",\n    Camera = \"Camera\",\n    Light = \"Light\",\n    // Further asset types will be added here when needed.\n}\n\nexport type AssetType<T extends FlowGraphAssetType> = T extends FlowGraphAssetType.Animation\n    ? Animation\n    : T extends FlowGraphAssetType.AnimationGroup\n      ? AnimationGroup\n      : T extends FlowGraphAssetType.Mesh\n        ? Mesh\n        : T extends FlowGraphAssetType.Material\n          ? Material\n          : T extends FlowGraphAssetType.Camera\n            ? Camera\n            : T extends FlowGraphAssetType.Light\n              ? Light\n              : never;\n\n/**\n * Returns the asset with the given index and type from the assets context.\n * @param assetsContext The assets context to get the asset from\n * @param type The type of the asset\n * @param index The index of the asset\n * @param useIndexAsUniqueId If set to true, instead of the index in the array it will search for the unique id of the asset.\n * @returns The asset or null if not found\n */\nexport function GetFlowGraphAssetWithType<T extends FlowGraphAssetType>(\n    assetsContext: IAssetContainer,\n    type: T,\n    index: number,\n    useIndexAsUniqueId?: boolean\n): Nullable<AssetType<T>> {\n    switch (type) {\n        case FlowGraphAssetType.Animation:\n            return useIndexAsUniqueId\n                ? ((assetsContext.animations.find((a) => a.uniqueId === index) as AssetType<typeof type>) ?? null)\n                : ((assetsContext.animations[index] as AssetType<typeof type>) ?? null);\n        case FlowGraphAssetType.AnimationGroup:\n            return useIndexAsUniqueId\n                ? ((assetsContext.animationGroups.find((a) => a.uniqueId === index) as AssetType<typeof type>) ?? null)\n                : ((assetsContext.animationGroups[index] as AssetType<typeof type>) ?? null);\n        case FlowGraphAssetType.Mesh:\n            return useIndexAsUniqueId\n                ? ((assetsContext.meshes.find((a) => a.uniqueId === index) as AssetType<typeof type>) ?? null)\n                : ((assetsContext.meshes[index] as AssetType<typeof type>) ?? null);\n        case FlowGraphAssetType.Material:\n            return useIndexAsUniqueId\n                ? ((assetsContext.materials.find((a) => a.uniqueId === index) as AssetType<typeof type>) ?? null)\n                : ((assetsContext.materials[index] as AssetType<typeof type>) ?? null);\n        case FlowGraphAssetType.Camera:\n            return useIndexAsUniqueId\n                ? ((assetsContext.cameras.find((a) => a.uniqueId === index) as AssetType<typeof type>) ?? null)\n                : ((assetsContext.cameras[index] as AssetType<typeof type>) ?? null);\n        case FlowGraphAssetType.Light:\n            return useIndexAsUniqueId\n                ? ((assetsContext.lights.find((a) => a.uniqueId === index) as AssetType<typeof type>) ?? null)\n                : ((assetsContext.lights[index] as AssetType<typeof type>) ?? null);\n        default:\n            return null;\n    }\n}\n","import { Logger } from \"core/Misc/logger\";\n\nexport const enum FlowGraphAction {\n    ExecuteBlock = \"ExecuteBlock\",\n    ExecuteEvent = \"ExecuteEvent\",\n    TriggerConnection = \"TriggerConnection\",\n    ContextVariableSet = \"ContextVariableSet\",\n    GlobalVariableSet = \"GlobalVariableSet\",\n    GlobalVariableDelete = \"GlobalVariableDelete\",\n    GlobalVariableGet = \"GlobalVariableGet\",\n    AddConnection = \"AddConnection\",\n    GetConnectionValue = \"GetConnectionValue\",\n    SetConnectionValue = \"SetConnectionValue\",\n    ActivateSignal = \"ActivateSignal\",\n    ContextVariableGet = \"ContextVariableGet\",\n}\n\n/**\n * An item in the flow graph log.\n */\nexport interface IFlowGraphLogItem {\n    /**\n     * The time of the log item.\n     */\n    time?: number;\n    /**\n     * The class that triggered the log.\n     */\n    className: string;\n    /**\n     * The unique id of the block/module that triggered the log.\n     */\n    uniqueId: string;\n    /**\n     * The action that was logged.\n     */\n    action: FlowGraphAction;\n    /**\n     * The payload of the log\n     * This can be any data that is relevant to the action.\n     * For example, the value of a connection, the value of a variable, etc.\n     * This is optional.\n     */\n    payload?: any;\n}\n\n/**\n * This class will be responsible of logging the flow graph activity.\n * Note that using this class might reduce performance, as it will log every action, according to the configuration.\n * It attaches to a flow graph and uses meta-programming to replace the methods of the flow graph to add logging abilities.\n */\nexport class FlowGraphLogger {\n    /**\n     * Whether to log to the console.\n     */\n    public logToConsole: boolean = false;\n\n    /**\n     * The log cache of the flow graph.\n     * Each item is a logged item, in order of execution.\n     */\n    public log: IFlowGraphLogItem[] = [];\n\n    public addLogItem(item: IFlowGraphLogItem) {\n        if (!item.time) {\n            item.time = Date.now();\n        }\n        this.log.push(item);\n        if (this.logToConsole) {\n            const value = item.payload?.value;\n            if (typeof value === \"object\" && value.getClassName) {\n                Logger.Log(`[FGLog] ${item.className}:${item.uniqueId.split(\"-\")[0]} ${item.action} - ${JSON.stringify(value.getClassName())}: ${value.toString()}`);\n            } else {\n                Logger.Log(`[FGLog] ${item.className}:${item.uniqueId.split(\"-\")[0]} ${item.action} - ${JSON.stringify(item.payload)}`);\n            }\n        }\n    }\n\n    public getItemsOfType(action: FlowGraphAction): IFlowGraphLogItem[] {\n        return this.log.filter((i) => i.action === action);\n    }\n}\n","import { serialize } from \"../Misc/decorators\";\r\nimport { RandomGUID } from \"../Misc/guid\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type FlowGraphAsyncExecutionBlock } from \"./flowGraphAsyncExecutionBlock\";\r\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { type FlowGraphDataConnection } from \"./flowGraphDataConnection\";\r\nimport { type FlowGraph } from \"./flowGraph\";\r\nimport { defaultValueSerializationFunction } from \"./serialization\";\r\nimport { type FlowGraphCoordinator } from \"./flowGraphCoordinator\";\r\nimport { type FlowGraphSceneEventCoordinator } from \"./flowGraphSceneEventCoordinator\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type AssetType, type FlowGraphAssetType, GetFlowGraphAssetWithType } from \"./flowGraphAssetsContext\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { FlowGraphAction, FlowGraphLogger } from \"./flowGraphLogger\";\r\nimport { type IFlowGraphOnTickEventPayload } from \"./Blocks/Event/flowGraphSceneTickEventBlock\";\r\nimport { type FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\r\nimport { type FlowGraphSignalConnection } from \"./flowGraphSignalConnection\";\r\n\r\n/**\r\n * Represents a pending signal activation that was paused by a breakpoint.\r\n */\r\nexport interface IFlowGraphPendingActivation {\r\n    /** The block that was about to execute */\r\n    readonly block: FlowGraphExecutionBlock;\r\n    /** The context in which execution was paused */\r\n    readonly context: FlowGraphContext;\r\n    /** The signal connection that triggered the execution */\r\n    readonly signal: FlowGraphSignalConnection;\r\n}\r\n/**\r\n * Construction parameters for the context.\r\n */\r\nexport interface IFlowGraphContextConfiguration {\r\n    /**\r\n     * The scene that the flow graph context belongs to.\r\n     */\r\n    readonly scene: Scene;\r\n    /**\r\n     * The event coordinator used by the flow graph context.\r\n     */\r\n    readonly coordinator: FlowGraphCoordinator;\r\n\r\n    /**\r\n     * The scene event coordinator that tracks runtime event state\r\n     * (e.g. currently pressed keyboard keys).\r\n     * When not provided, keyboard polling blocks (e.g. IsKeyPressed) will\r\n     * report no keys pressed.\r\n     */\r\n    readonly sceneEventCoordinator?: FlowGraphSceneEventCoordinator;\r\n\r\n    /**\r\n     * The assets context used by the flow graph context.\r\n     * If none is provided, a default one will be created.\r\n     */\r\n    readonly assetsContext?: IAssetContainer;\r\n}\r\n\r\n/**\r\n * Options for parsing a context.\r\n */\r\nexport interface IFlowGraphContextParseOptions {\r\n    /**\r\n     * A function that parses a value from a serialization object.\r\n     * @param key the key of the value\r\n     * @param serializationObject the object containing the value\r\n     * @param assetsContainer the assets container\r\n     * @param scene the current scene\r\n     * @returns\r\n     */\r\n    readonly valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n    /**\r\n     * The graph that the context is being parsed in.\r\n     */\r\n    readonly graph: FlowGraph;\r\n}\r\n/**\r\n * The context represents the current state and execution of the flow graph.\r\n * It contains both user-defined variables, which are derived from\r\n * a more general variable definition, and execution variables that\r\n * are set by the blocks.\r\n */\r\nexport class FlowGraphContext {\r\n    /**\r\n     * A randomly generated GUID for each context.\r\n     */\r\n    @serialize()\r\n    public uniqueId = RandomGUID();\r\n    /**\r\n     * An optional user-facing name for the context.\r\n     * Defaults to an empty string; the editor may assign a label like \"Context 0\".\r\n     */\r\n    @serialize()\r\n    public name: string = \"\";\r\n    /**\r\n     * These are the variables defined by a user.\r\n     */\r\n    private _userVariables: { [key: string]: any } = {};\r\n    /**\r\n     * Optional type annotations for user variables.\r\n     * Keys are variable names; values are type name strings (e.g. \"number\", \"Vector3\", \"Mesh\").\r\n     * This map is maintained by the editor and persisted through serialization so\r\n     * that a variable's declared type survives even when its value is undefined.\r\n     */\r\n    private _variableTypes: { [key: string]: string } = {};\r\n    /**\r\n     * These are the variables set by the blocks.\r\n     */\r\n    private _executionVariables: { [key: string]: any } = {};\r\n\r\n    /**\r\n     * A context-specific global variables, available to all blocks in the context.\r\n     */\r\n    private _globalContextVariables: { [key: string]: any } = {};\r\n    /**\r\n     * These are the values for the data connection points\r\n     */\r\n    private _connectionValues: { [key: string]: any } = {};\r\n    /**\r\n     * These are the variables set by the graph.\r\n     */\r\n    private readonly _configuration: IFlowGraphContextConfiguration;\r\n    /**\r\n     * These are blocks that have currently pending tasks/listeners that need to be cleaned up.\r\n     */\r\n    private _pendingBlocks: FlowGraphAsyncExecutionBlock[] = [];\r\n    /**\r\n     * A monotonically increasing ID for each execution.\r\n     * Incremented for every block executed.\r\n     */\r\n    private _executionId = 0;\r\n    /**\r\n     * Observable that is triggered when a node is executed.\r\n     */\r\n    public onNodeExecutedObservable: Observable<FlowGraphBlock> = new Observable<FlowGraphBlock>();\r\n\r\n    /**\r\n     * Observable triggered when a breakpoint is hit.\r\n     * Observers receive the pending activation (block, context, signal) that was paused.\r\n     */\r\n    public onBreakpointHitObservable: Observable<IFlowGraphPendingActivation> = new Observable<IFlowGraphPendingActivation>();\r\n\r\n    /**\r\n     * A predicate called before each execution block runs.\r\n     * If it returns true, execution is paused before the block and a\r\n     * pending activation is stored, which can be resumed via\r\n     * {@link continueExecution} or {@link stepExecution}.\r\n     *\r\n     * Set to `null` to disable breakpoint checking.\r\n     */\r\n    public breakpointPredicate: Nullable<(block: FlowGraphExecutionBlock) => boolean> = null;\r\n\r\n    /**\r\n     * The activation that is currently paused due to a breakpoint hit.\r\n     * `null` when execution is not paused on a breakpoint.\r\n     */\r\n    private _pendingActivation: Nullable<IFlowGraphPendingActivation> = null;\r\n\r\n    /**\r\n     * When true, the next activation will pause regardless of the breakpoint predicate.\r\n     * Set by {@link stepExecution}.\r\n     */\r\n    private _stepMode: boolean = false;\r\n\r\n    /**\r\n     * When set, the breakpoint check is skipped for this specific block uniqueId\r\n     * on the very next call to {@link _shouldBreak}. Used by continue/step to avoid\r\n     * immediately re-hitting the breakpoint on the block being resumed.\r\n     */\r\n    private _skipBreakpointForBlockId: Nullable<string> = null;\r\n\r\n    /**\r\n     * The assets context used by the flow graph context.\r\n     * Note that it can be shared between flow graph contexts.\r\n     */\r\n    public assetsContext: IAssetContainer;\r\n\r\n    /**\r\n     * Whether to treat data as right-handed.\r\n     * This is used when serializing data from a right-handed system, while running the context in a left-handed system, for example in glTF parsing.\r\n     * Default is false.\r\n     */\r\n    public treatDataAsRightHanded = false;\r\n\r\n    private _enableLogging = false;\r\n\r\n    /**\r\n     * The logger used by the context to log actions.\r\n     */\r\n    public logger: Nullable<FlowGraphLogger>;\r\n\r\n    /**\r\n     * Enable logging on this context\r\n     */\r\n    public get enableLogging() {\r\n        return this._enableLogging;\r\n    }\r\n\r\n    public set enableLogging(value: boolean) {\r\n        if (this._enableLogging === value) {\r\n            return;\r\n        }\r\n        this._enableLogging = value;\r\n        if (this._enableLogging) {\r\n            this.logger = new FlowGraphLogger();\r\n            this.logger.logToConsole = true;\r\n        } else {\r\n            this.logger = null;\r\n        }\r\n    }\r\n\r\n    constructor(params: IFlowGraphContextConfiguration) {\r\n        this._configuration = params;\r\n        this.assetsContext = params.assetsContext ?? params.scene;\r\n    }\r\n\r\n    /**\r\n     * Check if a user-defined variable is defined.\r\n     * @param name the name of the variable\r\n     * @returns true if the variable is defined\r\n     */\r\n    public hasVariable(name: string) {\r\n        return name in this._userVariables;\r\n    }\r\n\r\n    /**\r\n     * Set a user-defined variable.\r\n     * @param name the name of the variable\r\n     * @param value the value of the variable\r\n     */\r\n    public setVariable(name: string, value: any) {\r\n        this._userVariables[name] = value;\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.ContextVariableSet,\r\n            payload: {\r\n                name,\r\n                value,\r\n            },\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Get an assets from the assets context based on its type and index in the array\r\n     * @param type The type of the asset\r\n     * @param index The index of the asset\r\n     * @returns The asset or null if not found\r\n     */\r\n    public getAsset<T extends FlowGraphAssetType>(type: T, index: number): Nullable<AssetType<T>> {\r\n        return GetFlowGraphAssetWithType(this.assetsContext, type, index);\r\n    }\r\n\r\n    /**\r\n     * Get a user-defined variable.\r\n     * @param name the name of the variable\r\n     * @returns the value of the variable\r\n     */\r\n    public getVariable(name: string): any {\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.ContextVariableGet,\r\n            payload: {\r\n                name,\r\n                value: this._userVariables[name],\r\n            },\r\n        });\r\n        return this._userVariables[name];\r\n    }\r\n\r\n    /**\r\n     * Gets all user variables map\r\n     */\r\n    public get userVariables() {\r\n        return this._userVariables;\r\n    }\r\n\r\n    /**\r\n     * Set the declared type annotation for a user variable.\r\n     * @param name - the variable name\r\n     * @param typeName - the type name string (e.g. \"number\", \"Vector3\", \"Mesh\")\r\n     */\r\n    public setVariableType(name: string, typeName: string): void {\r\n        this._variableTypes[name] = typeName;\r\n    }\r\n\r\n    /**\r\n     * Get the declared type annotation for a user variable.\r\n     * @param name - the variable name\r\n     * @returns the type name string, or undefined if no type was declared\r\n     */\r\n    public getVariableType(name: string): string | undefined {\r\n        return this._variableTypes[name];\r\n    }\r\n\r\n    /**\r\n     * Gets all variable type annotations.\r\n     */\r\n    public get variableTypes(): { [key: string]: string } {\r\n        return this._variableTypes;\r\n    }\r\n\r\n    /**\r\n     * Get the scene that the context belongs to.\r\n     * @returns the scene\r\n     */\r\n    public getScene() {\r\n        return this._configuration.scene;\r\n    }\r\n\r\n    /**\r\n     * Encodes an event source key as the opaque reference exposed by event blocks on their `event`\r\n     * output. Delegates to the {@link IFlowGraphHostResolver} configured on the coordinator, so the\r\n     * reference format is owned by the environment hosting the graph.\r\n     * @param key the event source key (e.g. `\"sceneReady\"`, `\"sceneTick\"`, or a custom event id)\r\n     * @returns the event reference\r\n     */\r\n    public getEventReference(key: string): string {\r\n        return this._configuration.coordinator._getEventReference(key);\r\n    }\r\n\r\n    /**\r\n     * Decodes the array index denoted by a reference. Returns `undefined` when no host resolver is\r\n     * configured or the host does not recognise the value as an indexed reference.\r\n     * @param reference the reference to decode\r\n     * @param collection optional host collection the reference must address\r\n     * @returns the index the reference denotes, or `undefined` when it does not denote one\r\n     */\r\n    public decodeIndexReference(reference: string, collection?: string): number | undefined {\r\n        return this._configuration.coordinator.config.hostResolver?.decodeIndexReference?.(reference, collection);\r\n    }\r\n\r\n    /**\r\n     * Maps a runtime object to the reference the host addresses it by. Returns `undefined` when no\r\n     * host resolver is configured or the host cannot address the object.\r\n     * @param object the runtime object to address\r\n     * @param hint optional disambiguation hint telling the host which kind of reference is wanted\r\n     * @returns the reference for the object, or `undefined` when it cannot be addressed\r\n     */\r\n    public getObjectReference(object: object, hint?: string): string | undefined {\r\n        return this._configuration.coordinator.config.hostResolver?.getObjectReference?.(object, hint);\r\n    }\r\n\r\n    private _getUniqueIdPrefixedName(obj: FlowGraphBlock, name: string): string {\r\n        return `${obj.uniqueId}_${name}`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * @param name name of the variable\r\n     * @param defaultValue default value to return if the variable is not defined\r\n     * @returns the variable value or the default value if the variable is not defined\r\n     */\r\n    public _getGlobalContextVariable<T>(name: string, defaultValue: T): T {\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.GlobalVariableGet,\r\n            payload: {\r\n                name,\r\n                defaultValue,\r\n                possibleValue: this._globalContextVariables[name],\r\n            },\r\n        });\r\n        if (this._hasGlobalContextVariable(name)) {\r\n            return this._globalContextVariables[name];\r\n        } else {\r\n            return defaultValue;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set a global context variable\r\n     * @internal\r\n     * @param name the name of the variable\r\n     * @param value the value of the variable\r\n     */\r\n    public _setGlobalContextVariable<T>(name: string, value: T) {\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.GlobalVariableSet,\r\n            payload: { name, value },\r\n        });\r\n        this._globalContextVariables[name] = value;\r\n    }\r\n\r\n    /**\r\n     * Delete a global context variable\r\n     * @internal\r\n     * @param name the name of the variable\r\n     */\r\n    public _deleteGlobalContextVariable(name: string) {\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.GlobalVariableDelete,\r\n            payload: { name },\r\n        });\r\n        delete this._globalContextVariables[name];\r\n    }\r\n\r\n    /**\r\n     * Check if a global context variable is defined\r\n     * @internal\r\n     * @param name the name of the variable\r\n     * @returns true if the variable is defined\r\n     */\r\n    public _hasGlobalContextVariable(name: string) {\r\n        return name in this._globalContextVariables;\r\n    }\r\n\r\n    /**\r\n     * Set an internal execution variable\r\n     * @internal\r\n     * @param name\r\n     * @param value\r\n     */\r\n    public _setExecutionVariable(block: FlowGraphBlock, name: string, value: any) {\r\n        this._executionVariables[this._getUniqueIdPrefixedName(block, name)] = value;\r\n    }\r\n\r\n    /**\r\n     * Get an internal execution variable\r\n     * @internal\r\n     * @param name\r\n     * @returns\r\n     */\r\n    public _getExecutionVariable<T>(block: FlowGraphBlock, name: string, defaultValue: T): T {\r\n        if (this._hasExecutionVariable(block, name)) {\r\n            return this._executionVariables[this._getUniqueIdPrefixedName(block, name)];\r\n        } else {\r\n            return defaultValue;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Delete an internal execution variable\r\n     * @internal\r\n     * @param block\r\n     * @param name\r\n     */\r\n    public _deleteExecutionVariable(block: FlowGraphBlock, name: string) {\r\n        delete this._executionVariables[this._getUniqueIdPrefixedName(block, name)];\r\n    }\r\n\r\n    /**\r\n     * Check if an internal execution variable is defined\r\n     * @internal\r\n     * @param block\r\n     * @param name\r\n     * @returns\r\n     */\r\n    public _hasExecutionVariable(block: FlowGraphBlock, name: string) {\r\n        return this._getUniqueIdPrefixedName(block, name) in this._executionVariables;\r\n    }\r\n\r\n    /**\r\n     * Check if a connection value is defined\r\n     * @internal\r\n     * @param connectionPoint\r\n     * @returns\r\n     */\r\n    public _hasConnectionValue(connectionPoint: FlowGraphDataConnection<any>) {\r\n        return connectionPoint.uniqueId in this._connectionValues;\r\n    }\r\n\r\n    /**\r\n     * Set a connection value\r\n     * @internal\r\n     * @param connectionPoint\r\n     * @param value\r\n     */\r\n    public _setConnectionValue<T>(connectionPoint: FlowGraphDataConnection<T>, value: T) {\r\n        this._connectionValues[connectionPoint.uniqueId] = value;\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.SetConnectionValue,\r\n            payload: {\r\n                connectionPointId: connectionPoint.uniqueId,\r\n                value,\r\n            },\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Set a connection value by key\r\n     * @internal\r\n     * @param key the key of the connection value\r\n     * @param value the value of the connection\r\n     */\r\n    public _setConnectionValueByKey<T>(key: string, value: T) {\r\n        this._connectionValues[key] = value;\r\n    }\r\n\r\n    /**\r\n     * Get a connection value\r\n     * @internal\r\n     * @param connectionPoint\r\n     * @returns\r\n     */\r\n    public _getConnectionValue<T>(connectionPoint: FlowGraphDataConnection<T>): T {\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n            action: FlowGraphAction.GetConnectionValue,\r\n            payload: {\r\n                connectionPointId: connectionPoint.uniqueId,\r\n                value: this._connectionValues[connectionPoint.uniqueId],\r\n            },\r\n        });\r\n        return this._connectionValues[connectionPoint.uniqueId];\r\n    }\r\n\r\n    /**\r\n     * Get the configuration\r\n     * @internal\r\n     * @param name\r\n     * @param value\r\n     */\r\n    public get configuration() {\r\n        return this._configuration;\r\n    }\r\n\r\n    /**\r\n     * Check if there are any pending blocks in this context\r\n     * @returns true if there are pending blocks\r\n     */\r\n    public get hasPendingBlocks() {\r\n        return this._pendingBlocks.length > 0;\r\n    }\r\n\r\n    /**\r\n     * Add a block to the list of blocks that have pending tasks.\r\n     * @internal\r\n     * @param block\r\n     */\r\n    public _addPendingBlock(block: FlowGraphAsyncExecutionBlock) {\r\n        // check if block is already in the array\r\n        if (this._pendingBlocks.includes(block)) {\r\n            return;\r\n        }\r\n        this._pendingBlocks.push(block);\r\n        // sort pending blocks by priority\r\n        this._pendingBlocks.sort((a, b) => a.priority - b.priority);\r\n    }\r\n\r\n    /**\r\n     * Remove a block from the list of blocks that have pending tasks.\r\n     * @internal\r\n     * @param block\r\n     */\r\n    public _removePendingBlock(block: FlowGraphAsyncExecutionBlock) {\r\n        const index = this._pendingBlocks.indexOf(block);\r\n        if (index !== -1) {\r\n            this._pendingBlocks.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear all pending blocks.\r\n     * @internal\r\n     */\r\n    public _clearPendingBlocks() {\r\n        for (const block of this._pendingBlocks.slice()) {\r\n            block._cancelPendingTasks(this);\r\n        }\r\n        this._pendingBlocks.length = 0;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Function that notifies the node executed observable\r\n     * @param node\r\n     */\r\n    public _notifyExecuteNode(node: FlowGraphBlock) {\r\n        this.onNodeExecutedObservable.notifyObservers(node);\r\n        this.logger?.addLogItem({\r\n            time: Date.now(),\r\n            className: node.getClassName(),\r\n            uniqueId: node.uniqueId,\r\n            action: FlowGraphAction.ExecuteBlock,\r\n        });\r\n    }\r\n\r\n    public _notifyOnTick(framePayload: IFlowGraphOnTickEventPayload) {\r\n        // set the values as global variables\r\n        this._setGlobalContextVariable(\"timeSinceStart\", framePayload.timeSinceStart);\r\n        this._setGlobalContextVariable(\"deltaTime\", framePayload.deltaTime);\r\n        // iterate the pending blocks and run each one's onFrame function\r\n        for (const block of this._pendingBlocks) {\r\n            block._executeOnTick?.(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _increaseExecutionId() {\r\n        this._executionId++;\r\n    }\r\n    /**\r\n     * A monotonically increasing ID for each execution.\r\n     * Incremented for every block executed.\r\n     */\r\n    public get executionId() {\r\n        return this._executionId;\r\n    }\r\n\r\n    // ── Breakpoint API ─────────────────────────────────────────────────\r\n\r\n    /**\r\n     * Check whether the given block should break before executing.\r\n     * Called by the signal connection infrastructure.\r\n     * @internal\r\n     * @param block the block about to execute\r\n     * @param signal the signal that is triggering the execution\r\n     * @returns true if execution should be paused (breakpoint hit)\r\n     */\r\n    public _shouldBreak(block: FlowGraphExecutionBlock, signal: FlowGraphSignalConnection): boolean {\r\n        // If continue/step just resumed this specific block, let it through\r\n        if (this._skipBreakpointForBlockId === block.uniqueId) {\r\n            this._skipBreakpointForBlockId = null;\r\n            return false;\r\n        }\r\n\r\n        // If already paused on a breakpoint, silently block further execution\r\n        // without overwriting the pending activation or re-notifying observers.\r\n        if (this._pendingActivation) {\r\n            return true;\r\n        }\r\n\r\n        if (this._stepMode) {\r\n            this._stepMode = false;\r\n            this._pendingActivation = { block, context: this, signal };\r\n            this.onBreakpointHitObservable.notifyObservers(this._pendingActivation);\r\n            return true;\r\n        }\r\n        if (this.breakpointPredicate && this.breakpointPredicate(block)) {\r\n            this._pendingActivation = { block, context: this, signal };\r\n            this.onBreakpointHitObservable.notifyObservers(this._pendingActivation);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns the currently paused activation, or null if not paused.\r\n     */\r\n    public get pendingActivation(): Nullable<IFlowGraphPendingActivation> {\r\n        return this._pendingActivation;\r\n    }\r\n\r\n    /**\r\n     * Resume execution from a breakpoint hit.\r\n     * The paused block and all downstream blocks will execute normally until\r\n     * the next breakpoint (if any) is hit.\r\n     */\r\n    public continueExecution(): void {\r\n        const pending = this._pendingActivation;\r\n        if (!pending) {\r\n            return;\r\n        }\r\n        this._pendingActivation = null;\r\n        // Tell _shouldBreak to skip the breakpoint for this block on re-entry\r\n        this._skipBreakpointForBlockId = pending.block.uniqueId;\r\n        pending.signal._activateSignal(this);\r\n        // Clear in case no re-entry happened (shouldn't linger)\r\n        this._skipBreakpointForBlockId = null;\r\n    }\r\n\r\n    /**\r\n     * Execute exactly the paused block and then pause again before the next\r\n     * execution block fires. If no activation is pending, this is a no-op.\r\n     */\r\n    public stepExecution(): void {\r\n        const pending = this._pendingActivation;\r\n        if (!pending) {\r\n            return;\r\n        }\r\n        this._pendingActivation = null;\r\n        // Enable step mode so the very next input-signal activation will pause\r\n        this._stepMode = true;\r\n        // Tell _shouldBreak to skip the breakpoint for this block on re-entry\r\n        this._skipBreakpointForBlockId = pending.block.uniqueId;\r\n        pending.signal._activateSignal(this);\r\n        // If nothing further executed (end of chain), clear step mode\r\n        this._stepMode = false;\r\n        this._skipBreakpointForBlockId = null;\r\n    }\r\n\r\n    /**\r\n     * Discard any pending breakpoint activation without resuming.\r\n     * Used when stopping or resetting the graph.\r\n     * @internal\r\n     */\r\n    public _clearPendingActivation(): void {\r\n        this._pendingActivation = null;\r\n        this._stepMode = false;\r\n        this._skipBreakpointForBlockId = null;\r\n    }\r\n\r\n    /**\r\n     * Serializes a context\r\n     * @param serializationObject the object to write the values in\r\n     * @param valueSerializationFunction a function to serialize complex values\r\n     */\r\n    public serialize(serializationObject: any = {}, valueSerializationFunction: (key: string, value: any, serializationObject: any) => void = defaultValueSerializationFunction) {\r\n        serializationObject.uniqueId = this.uniqueId;\r\n        serializationObject.name = this.name;\r\n        serializationObject._userVariables = {};\r\n        for (const key in this._userVariables) {\r\n            valueSerializationFunction(key, this._userVariables[key], serializationObject._userVariables);\r\n        }\r\n        // Persist variable type annotations (editor metadata)\r\n        if (Object.keys(this._variableTypes).length > 0) {\r\n            serializationObject._variableTypes = { ...this._variableTypes };\r\n        }\r\n        serializationObject._connectionValues = {};\r\n        for (const key in this._connectionValues) {\r\n            valueSerializationFunction(key, this._connectionValues[key], serializationObject._connectionValues);\r\n        }\r\n        // serialize assets context, if not scene\r\n        if (this.assetsContext !== this.getScene()) {\r\n            serializationObject._assetsContext = {\r\n                meshes: this.assetsContext.meshes.map((m) => m.id),\r\n                materials: this.assetsContext.materials.map((m) => m.id),\r\n                textures: this.assetsContext.textures.map((m) => m.name),\r\n                animations: this.assetsContext.animations.map((m) => m.name),\r\n                lights: this.assetsContext.lights.map((m) => m.id),\r\n                cameras: this.assetsContext.cameras.map((m) => m.id),\r\n                sounds: this.assetsContext.sounds?.map((m) => m.name),\r\n                skeletons: this.assetsContext.skeletons.map((m) => m.id),\r\n                particleSystems: this.assetsContext.particleSystems.map((m) => m.name),\r\n                geometries: this.assetsContext.geometries.map((m) => m.id),\r\n                multiMaterials: this.assetsContext.multiMaterials.map((m) => m.id),\r\n                transformNodes: this.assetsContext.transformNodes.map((m) => m.id),\r\n            };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns the class name of the object.\r\n     */\r\n    public getClassName() {\r\n        return \"FlowGraphContext\";\r\n    }\r\n}\r\n","import { RandomGUID } from \"../Misc/guid\";\r\n\r\n/**\r\n * The type of a connection point - input or output.\r\n */\r\nexport const enum FlowGraphConnectionType {\r\n    Input,\r\n    Output,\r\n}\r\n\r\n/**\r\n * An interface for a connectable point in the flow graph.\r\n */\r\nexport interface IConnectable {\r\n    /**\r\n     * A uniquely identifying string for the connection.\r\n     */\r\n    uniqueId: string;\r\n    /**\r\n     * An array of the points that this point is connected to.\r\n     */\r\n    _connectedPoint: Array<IConnectable>;\r\n    /**\r\n     * Returns if the connection can only be connected to one other point.\r\n     */\r\n    _isSingularConnection(): boolean;\r\n    /**\r\n     * The type of the connection\r\n     */\r\n    _connectionType: FlowGraphConnectionType;\r\n    /**\r\n     * Connect this point to another point.\r\n     * @param point the point to connect to.\r\n     */\r\n    connectTo(point: IConnectable): void;\r\n}\r\n\r\n/**\r\n * The base connection class.\r\n */\r\nexport class FlowGraphConnection<BlockT, ConnectedToT extends IConnectable> implements IConnectable {\r\n    /** @internal */\r\n    public _connectedPoint: Array<ConnectedToT> = [];\r\n    /**\r\n     * A uniquely identifying string for the connection.\r\n     */\r\n    public uniqueId = RandomGUID();\r\n\r\n    /**\r\n     * Optional host-format metadata associated with this connection.\r\n     */\r\n    public metadata?: any;\r\n\r\n    /**\r\n     * The name of the connection.\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _connectionType: FlowGraphConnectionType;\r\n\r\n    /**\r\n     * Used for parsing connections.\r\n     * @internal\r\n     */\r\n    // disable warning as this is used for parsing\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public connectedPointIds: any[] = [];\r\n\r\n    public constructor(\r\n        name: string,\r\n        _connectionType: FlowGraphConnectionType,\r\n        /* @internal */ public _ownerBlock: BlockT\r\n    ) {\r\n        this.name = name;\r\n        this._connectionType = _connectionType;\r\n    }\r\n\r\n    /**\r\n     * The type of the connection\r\n     */\r\n    public get connectionType() {\r\n        return this._connectionType;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Override this to indicate if a point can connect to more than one point.\r\n     */\r\n    public _isSingularConnection(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns if a point is connected to any other point.\r\n     * @returns boolean indicating if the point is connected.\r\n     */\r\n    public isConnected(): boolean {\r\n        return this._connectedPoint.length > 0;\r\n    }\r\n\r\n    /**\r\n     * Connects two connections together.\r\n     * @param point the connection to connect to.\r\n     */\r\n    public connectTo(point: ConnectedToT): void {\r\n        if (this._connectionType === point._connectionType) {\r\n            throw new Error(`Cannot connect two points of type ${this.connectionType}`);\r\n        }\r\n        if ((this._isSingularConnection() && this._connectedPoint.length > 0) || (point._isSingularConnection() && point._connectedPoint.length > 0)) {\r\n            throw new Error(\"Max number of connections for point reached\");\r\n        }\r\n        this._connectedPoint.push(point);\r\n        point._connectedPoint.push(this);\r\n    }\r\n\r\n    /**\r\n     * Disconnects two connections.\r\n     * @param point the connection to disconnect from.\r\n     * @param removeFromLocal if true, the connection will be removed from the local connection list.\r\n     */\r\n    public disconnectFrom(point: ConnectedToT, removeFromLocal = true): void {\r\n        const indexLocal = this._connectedPoint.indexOf(point);\r\n        const indexConnected = point._connectedPoint.indexOf(this);\r\n        if (indexLocal === -1 || indexConnected === -1) {\r\n            return;\r\n        }\r\n        if (removeFromLocal) {\r\n            this._connectedPoint.splice(indexLocal, 1);\r\n        }\r\n        point._connectedPoint.splice(indexConnected, 1);\r\n    }\r\n\r\n    /**\r\n     * Disconnects all connected points.\r\n     */\r\n    public disconnectFromAll() {\r\n        for (const point of this._connectedPoint) {\r\n            this.disconnectFrom(point, false);\r\n        }\r\n        this._connectedPoint.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Disconnects this point from every connected point.\r\n     */\r\n    public dispose() {\r\n        for (const point of this._connectedPoint) {\r\n            this.disconnectFrom(point);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Saves the connection to a JSON object.\r\n     * @param serializationObject the object to serialize to.\r\n     */\r\n    public serialize(serializationObject: any = {}) {\r\n        serializationObject.uniqueId = this.uniqueId;\r\n        serializationObject.name = this.name;\r\n        serializationObject._connectionType = this._connectionType;\r\n        serializationObject.connectedPointIds = [];\r\n        serializationObject.className = this.getClassName();\r\n        if (this.metadata !== undefined) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n        for (const point of this._connectedPoint) {\r\n            serializationObject.connectedPointIds.push(point.uniqueId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the connection.\r\n     */\r\n    public getClassName(): string {\r\n        return \"FGConnection\";\r\n    }\r\n\r\n    /**\r\n     * Deserialize from a object into this\r\n     * @param serializationObject the object to deserialize from.\r\n     */\r\n    deserialize(serializationObject: any) {\r\n        this.uniqueId = serializationObject.uniqueId;\r\n        this.name = serializationObject.name;\r\n        this._connectionType = serializationObject._connectionType;\r\n        this.connectedPointIds = serializationObject.connectedPointIds;\r\n        this.metadata = serializationObject.metadata;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { FlowGraphConnection, FlowGraphConnectionType } from \"./flowGraphConnection\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { type RichType } from \"./flowGraphRichTypes.pure\";\r\nimport { Observable } from \"core/Misc/observable.pure\";\r\nimport { defaultValueSerializationFunction, GetSceneNodeFromSerializedReference } from \"./serialization\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport { type Scene } from \"core/scene\";\r\n/**\r\n * Represents a connection point for data.\r\n * An unconnected input point can have a default value.\r\n * An output point will only have a value if it is connected to an input point. Furthermore,\r\n * if the point belongs to a \"function\" node, the node will run its function to update the value.\r\n */\r\nexport class FlowGraphDataConnection<T> extends FlowGraphConnection<FlowGraphBlock, FlowGraphDataConnection<T>> {\r\n    private _isDisabled: boolean = false;\r\n    /**\r\n     * This is used for debugging purposes! It is the last value that was set to this connection with ANY context.\r\n     * Do not use this value for anything else, as it might be wrong if used in a different context.\r\n     */\r\n    private _lastValue: Nullable<T> = null;\r\n\r\n    /**\r\n     * a data transformer function, if needed.\r\n     * This can be used, for example, to force seconds into milliseconds output, if it makes sense in your case.\r\n     */\r\n    public dataTransformer: Nullable<(value: T) => T> = null;\r\n\r\n    /**\r\n     * An observable that is triggered when the value of the connection changes.\r\n     */\r\n    public onValueChangedObservable = new Observable<T>();\r\n    /**\r\n     * Create a new data connection point.\r\n     * @param name the name of the connection\r\n     * @param connectionType the type of the connection\r\n     * @param ownerBlock the block that owns this connection\r\n     * @param richType the type of the data in this block\r\n     * @param _defaultValue the default value of the connection\r\n     * @param _optional if the connection is optional\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        connectionType: FlowGraphConnectionType,\r\n        ownerBlock: FlowGraphBlock,\r\n        /**\r\n         * the type of the data in this block\r\n         */\r\n        public richType: RichType<T>,\r\n        /**\r\n         * [any] the default value of the connection\r\n         */\r\n        private _defaultValue: T = richType.defaultValue,\r\n        /**\r\n         * [false] if the connection is optional\r\n         */\r\n        private _optional: boolean = false\r\n    ) {\r\n        super(name, connectionType, ownerBlock);\r\n    }\r\n\r\n    /**\r\n     * Whether or not the connection is optional.\r\n     * Currently only used for UI control.\r\n     */\r\n    public get optional(): boolean {\r\n        return this._optional;\r\n    }\r\n\r\n    /**\r\n     * is this connection disabled\r\n     * If the connection is disabled you will not be able to connect anything to it.\r\n     */\r\n    public get isDisabled(): boolean {\r\n        return this._isDisabled;\r\n    }\r\n\r\n    public set isDisabled(value: boolean) {\r\n        if (this._isDisabled === value) {\r\n            return;\r\n        }\r\n        this._isDisabled = value;\r\n        if (this._isDisabled) {\r\n            this.disconnectFromAll();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * An output data block can connect to multiple input data blocks,\r\n     * but an input data block can only connect to one output data block.\r\n     * @returns true if the connection is singular\r\n     */\r\n    public override _isSingularConnection(): boolean {\r\n        return this.connectionType === FlowGraphConnectionType.Input;\r\n    }\r\n\r\n    /**\r\n     * Set the value of the connection in a specific context.\r\n     * @param value the value to set\r\n     * @param context the context to which the value is set\r\n     */\r\n    public setValue(value: T, context: FlowGraphContext): void {\r\n        // check if the value is different\r\n        if (context._getConnectionValue(this) === value) {\r\n            return;\r\n        }\r\n        context._setConnectionValue(this, value);\r\n        this.onValueChangedObservable.notifyObservers(value);\r\n    }\r\n\r\n    /**\r\n     * Reset the value of the connection to the default value.\r\n     * @param context the context in which the value is reset\r\n     */\r\n    public resetToDefaultValue(context: FlowGraphContext): void {\r\n        context._setConnectionValue(this, this._defaultValue);\r\n    }\r\n\r\n    /**\r\n     * Re-resolves this input's default value against a (new) scene when the value is a node reference.\r\n     * This handles two cases that occur when a graph is moved to a different scene (see\r\n     * {@link FlowGraph.setScene}):\r\n     * - the value is still an unresolved serialized reference (`{ id, name, className, uniqueId }`)\r\n     *   because the node did not yet exist in the scene at parse time, or\r\n     * - the value is a node that belongs to a different (e.g. disposed) scene.\r\n     * Values that are not node references (numbers, vectors, matrices, etc.) are left untouched, and\r\n     * the default value is only replaced when a matching node is found in the new scene.\r\n     * @param scene the scene to resolve the reference against\r\n     * @internal\r\n     */\r\n    public _reresolveDefaultValueForScene(scene: Scene): void {\r\n        const value = this._defaultValue as any;\r\n        if (!value || typeof value !== \"object\") {\r\n            return;\r\n        }\r\n\r\n        let reference: { id?: string; name?: string; className?: string; uniqueId?: number } | undefined;\r\n        if (typeof value.getClassName === \"function\" && typeof value.getScene === \"function\") {\r\n            // A scene node — only rebind when it belongs to a different scene.\r\n            if (value.getScene() === scene) {\r\n                return;\r\n            }\r\n            reference = { id: value.id, name: value.name, className: value.getClassName(), uniqueId: value.uniqueId };\r\n        } else if (typeof value.className === \"string\" && (value.id || value.name) && value.value === undefined) {\r\n            // An unresolved serialized node reference left by the parser.\r\n            reference = value;\r\n        } else {\r\n            return;\r\n        }\r\n\r\n        const node = GetSceneNodeFromSerializedReference(reference, scene);\r\n        if (node) {\r\n            this._defaultValue = node as unknown as T;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Connect this point to another point.\r\n     * @param point the point to connect to.\r\n     */\r\n    public override connectTo(point: FlowGraphDataConnection<T>): void {\r\n        if (this._isDisabled) {\r\n            return;\r\n        }\r\n        super.connectTo(point);\r\n    }\r\n\r\n    private _getValueOrDefault(context: FlowGraphContext): T {\r\n        const val = context._getConnectionValue(this) ?? this._defaultValue;\r\n        return this.dataTransformer ? this.dataTransformer(val) : val;\r\n    }\r\n\r\n    /**\r\n     * Gets the value of the connection in a specific context.\r\n     * @param context the context from which the value is retrieved\r\n     * @returns the value of the connection\r\n     */\r\n    public getValue(context: FlowGraphContext): T {\r\n        if (this.connectionType === FlowGraphConnectionType.Output) {\r\n            context._notifyExecuteNode(this._ownerBlock);\r\n            this._ownerBlock._updateOutputs(context);\r\n            const value = this._getValueOrDefault(context);\r\n            this._lastValue = value;\r\n            return this.richType.typeTransformer ? this.richType.typeTransformer(value) : value;\r\n        }\r\n        const value = !this.isConnected() ? this._getValueOrDefault(context) : this._connectedPoint[0].getValue(context);\r\n        this._lastValue = value;\r\n        return this.richType.typeTransformer ? this.richType.typeTransformer(value) : value;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getLastValue(): Nullable<T> {\r\n        return this._lastValue;\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the object.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FlowGraphDataConnection\";\r\n    }\r\n\r\n    /**\r\n     * Serializes this object.\r\n     * @param serializationObject the object to serialize to\r\n     */\r\n    public override serialize(serializationObject: any = {}) {\r\n        super.serialize(serializationObject);\r\n        serializationObject.richType = {};\r\n        this.richType.serialize(serializationObject.richType);\r\n        serializationObject.optional = this._optional;\r\n        defaultValueSerializationFunction(\"defaultValue\", this._defaultValue, serializationObject);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphDataConnection.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphDataConnection(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"FlowGraphDataConnection\", FlowGraphDataConnection);\r\n}\r\n","import { RandomGUID } from \"../Misc/guid\";\r\nimport { FlowGraphConnectionType } from \"./flowGraphConnection\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { FlowGraphDataConnection } from \"./flowGraphDataConnection.pure\";\r\nimport { type RichType } from \"./flowGraphRichTypes\";\r\nimport { type ISerializedFlowGraphBlock, type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { defaultValueSerializationFunction } from \"./serialization\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type FlowGraphAction } from \"./flowGraphLogger\";\r\n\r\n/**\r\n * Options for parsing a block.\r\n */\r\nexport interface IFlowGraphBlockParseOptions {\r\n    /**\r\n     * A function that parses a value from a serialization object.\r\n     * @param key the key of the property\r\n     * @param serializationObject the serialization object where the property is located\r\n     * @param assetsContainer the assets container\r\n     * @param scene the scene that the block is being parsed in\r\n     * @returns the parsed value\r\n     */\r\n    valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n    /**\r\n     * The assets container to use when loading assets.\r\n     */\r\n    assetsContainer?: IAssetContainer;\r\n    /**\r\n     * The scene that the block is being parsed in.\r\n     */\r\n    scene: Scene;\r\n    /**\r\n     * The path converter to use to convert the path to an object accessor.\r\n     */\r\n    pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n}\r\n\r\n/**\r\n * Configuration for a block.\r\n */\r\nexport interface IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The name of the block.\r\n     */\r\n    name?: string;\r\n    [extraPropertyKey: string]: any;\r\n}\r\n\r\n/**\r\n * A block in a flow graph. The most basic form\r\n * of a block has inputs and outputs that contain\r\n * data.\r\n */\r\nexport class FlowGraphBlock {\r\n    /**\r\n     * A randomly generated GUID for each block.\r\n     */\r\n    public uniqueId = RandomGUID();\r\n    /**\r\n     * The name of the block.\r\n     */\r\n    public name: string;\r\n    /**\r\n     * The data inputs of the block.\r\n     */\r\n    public dataInputs: FlowGraphDataConnection<any>[];\r\n    /**\r\n     * The data outputs of the block.\r\n     */\r\n    public dataOutputs: FlowGraphDataConnection<any>[];\r\n\r\n    /**\r\n     * Metadata that can be used by the block.\r\n     */\r\n    public metadata: any;\r\n\r\n    /** Constructor is protected so only subclasses can be instantiated\r\n     * @param config optional configuration for this block\r\n     * @internal - do not use directly. Extend this class instead.\r\n     */\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public config?: IFlowGraphBlockConfiguration\r\n    ) {\r\n        this.name = this.config?.name ?? this.getClassName();\r\n        this.dataInputs = [];\r\n        this.dataOutputs = [];\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * This function is called when the block needs to update its output flows.\r\n     * @param _context the context in which it is running\r\n     */\r\n    public _updateOutputs(_context: FlowGraphContext): void {\r\n        // empty by default, overridden in data blocks\r\n    }\r\n\r\n    /**\r\n     * Registers a data input on the block.\r\n     * @param name the name of the input\r\n     * @param richType the type of the input\r\n     * @param defaultValue optional default value of the input. If not set, the rich type's default value will be used.\r\n     * @returns the created connection\r\n     */\r\n    public registerDataInput<T>(name: string, richType: RichType<T>, defaultValue?: T): FlowGraphDataConnection<T> {\r\n        const input = new FlowGraphDataConnection(name, FlowGraphConnectionType.Input, this, richType, defaultValue);\r\n        this.dataInputs.push(input);\r\n        return input;\r\n    }\r\n\r\n    /**\r\n     * Registers a data output on the block.\r\n     * @param name the name of the input\r\n     * @param richType the type of the input\r\n     * @param defaultValue optional default value of the input. If not set, the rich type's default value will be used.\r\n     * @returns the created connection\r\n     */\r\n    public registerDataOutput<T>(name: string, richType: RichType<T>, defaultValue?: T): FlowGraphDataConnection<T> {\r\n        const output = new FlowGraphDataConnection(name, FlowGraphConnectionType.Output, this, richType, defaultValue);\r\n        this.dataOutputs.push(output);\r\n        return output;\r\n    }\r\n\r\n    /**\r\n     * Given the name of a data input, returns the connection if it exists\r\n     * @param name the name of the input\r\n     * @returns the connection if it exists, undefined otherwise\r\n     */\r\n    public getDataInput(name: string): FlowGraphDataConnection<any> | undefined {\r\n        return this.dataInputs.find((i) => i.name === name);\r\n    }\r\n\r\n    /**\r\n     * Given the name of a data output, returns the connection if it exists\r\n     * @param name the name of the output\r\n     * @returns the connection if it exists, undefined otherwise\r\n     */\r\n    public getDataOutput(name: string): FlowGraphDataConnection<any> | undefined {\r\n        return this.dataOutputs.find((i) => i.name === name);\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @param serializationObject the object to serialize to\r\n     * @param _valueSerializeFunction a function that serializes a specific value\r\n     */\r\n    public serialize(serializationObject: any = {}, _valueSerializeFunction: (key: string, value: any, serializationObject: any) => any = defaultValueSerializationFunction) {\r\n        serializationObject.uniqueId = this.uniqueId;\r\n        if (this.metadata !== undefined) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n        serializationObject.config = {};\r\n        if (this.config) {\r\n            const config = this.config;\r\n            const keys = Object.keys(config);\r\n            for (const key of keys) {\r\n                _valueSerializeFunction(key, config[key], serializationObject.config);\r\n            }\r\n        }\r\n        serializationObject.dataInputs = [];\r\n        serializationObject.dataOutputs = [];\r\n        serializationObject.className = this.getClassName();\r\n        for (const input of this.dataInputs) {\r\n            const serializedInput: any = {};\r\n            input.serialize(serializedInput);\r\n            serializationObject.dataInputs.push(serializedInput);\r\n        }\r\n        for (const output of this.dataOutputs) {\r\n            const serializedOutput: any = {};\r\n            output.serialize(serializedOutput);\r\n            serializationObject.dataOutputs.push(serializedOutput);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Deserializes this block\r\n     * @param _serializationObject the object to deserialize from\r\n     */\r\n    public deserialize(_serializationObject: ISerializedFlowGraphBlock) {\r\n        // no-op by default\r\n    }\r\n\r\n    protected _log(context: FlowGraphContext, action: FlowGraphAction, payload?: any) {\r\n        context.logger?.addLogItem({\r\n            action,\r\n            payload,\r\n            className: this.getClassName(),\r\n            uniqueId: this.uniqueId,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public getClassName() {\r\n        return \"FlowGraphBlock\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\r\nimport { FlowGraphConnection, FlowGraphConnectionType } from \"./flowGraphConnection\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { FlowGraphAction } from \"./flowGraphLogger\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Represents a connection point for a signal.\r\n * When an output point is activated, it will activate the connected input point.\r\n * When an input point is activated, it will execute the block it belongs to.\r\n */\r\nexport class FlowGraphSignalConnection extends FlowGraphConnection<FlowGraphExecutionBlock, FlowGraphSignalConnection> {\r\n    /**\r\n     * Optional payload. Can be used, for example, when an error is thrown to pass additional information.\r\n     */\r\n    public payload: any;\r\n\r\n    /**\r\n     * The priority of the signal. Signals with higher priority will be executed first.\r\n     * Set priority before adding the connection as sorting happens only when the connection is added.\r\n     */\r\n    public priority: number = 0;\r\n\r\n    public override _isSingularConnection(): boolean {\r\n        return false;\r\n    }\r\n\r\n    public override connectTo(point: FlowGraphSignalConnection): void {\r\n        super.connectTo(point);\r\n        // sort according to priority to handle execution order\r\n        this._connectedPoint.sort((a, b) => b.priority - a.priority);\r\n    }\r\n\r\n    /**\r\n     * Timestamp of the last activation (set on output signals when they fire).\r\n     * @internal\r\n     */\r\n    public _lastActivationTime: number = -1;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _activateSignal(context: FlowGraphContext): void {\r\n        this._lastActivationTime = performance.now();\r\n        context.logger?.addLogItem({\r\n            action: FlowGraphAction.ActivateSignal,\r\n            className: this._ownerBlock.getClassName(),\r\n            uniqueId: this._ownerBlock.uniqueId,\r\n            payload: {\r\n                connectionType: this.connectionType,\r\n                name: this.name,\r\n            },\r\n        });\r\n        if (this.connectionType === FlowGraphConnectionType.Input) {\r\n            // Check breakpoint before executing\r\n            if (context._shouldBreak(this._ownerBlock, this)) {\r\n                return; // Execution paused — stored as pending activation\r\n            }\r\n            // Start a new execution frame BEFORE executing the node: an output value socket (a random\r\n            // value, for instance) retains its value until a node with one or more flow sockets is\r\n            // executed, after which it is recomputed on the next access. Because flow execution is\r\n            // synchronous and nested, the id must be increased before the block runs so each flow\r\n            // socket activation (including loop self-activations) observes a fresh frame, while\r\n            // staying constant within a single block execution so per-frame value caching still works.\r\n            context._increaseExecutionId();\r\n            context._notifyExecuteNode(this._ownerBlock);\r\n            const startTime = performance.now();\r\n            this._ownerBlock._execute(context, this);\r\n            this._ownerBlock._lastExecutionTime = performance.now() - startTime;\r\n        } else {\r\n            for (const connectedPoint of this._connectedPoint) {\r\n                connectedPoint._activateSignal(context);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphSignalConnection.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphSignalConnection(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"FlowGraphSignalConnection\", FlowGraphSignalConnection);\r\n}\r\n","import { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { FlowGraphConnectionType } from \"./flowGraphConnection\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { FlowGraphSignalConnection } from \"./flowGraphSignalConnection.pure\";\r\n\r\n/**\r\n * A block that executes some action. Always has an input signal (which is not used by event blocks).\r\n * Can have one or more output signals.\r\n */\r\nexport abstract class FlowGraphExecutionBlock extends FlowGraphBlock {\r\n    /**\r\n     * Input connection: The input signal of the block.\r\n     */\r\n    public readonly in: FlowGraphSignalConnection;\r\n\r\n    /**\r\n     * An output connection that can be used to signal an error, if the block defines it.\r\n     */\r\n    public readonly error: FlowGraphSignalConnection;\r\n    /**\r\n     * Input connections that activate the block.\r\n     */\r\n    public signalInputs: FlowGraphSignalConnection[];\r\n    /**\r\n     * Output connections that can activate downstream blocks.\r\n     */\r\n    public signalOutputs: FlowGraphSignalConnection[];\r\n\r\n    /**\r\n     * The priority of the block. Higher priority blocks will be executed first.\r\n     * Note that priority cannot be change AFTER the block was added as sorting happens when the block is added to the execution queue.\r\n     */\r\n    public readonly priority: number = 0;\r\n\r\n    /**\r\n     * The last measured execution time in milliseconds.\r\n     * Updated by the signal connection when the block is executed.\r\n     * A value of -1 means no measurement has been taken yet.\r\n     * @internal\r\n     */\r\n    public _lastExecutionTime: number = -1;\r\n\r\n    protected constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.signalInputs = [];\r\n        this.signalOutputs = [];\r\n        this.in = this._registerSignalInput(\"in\");\r\n        this.error = this._registerSignalOutput(\"error\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Executes the flow graph execution block.\r\n     */\r\n    public abstract _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void;\r\n\r\n    protected _registerSignalInput(name: string): FlowGraphSignalConnection {\r\n        const input = new FlowGraphSignalConnection(name, FlowGraphConnectionType.Input, this);\r\n        this.signalInputs.push(input);\r\n        return input;\r\n    }\r\n\r\n    protected _registerSignalOutput(name: string): FlowGraphSignalConnection {\r\n        const output = new FlowGraphSignalConnection(name, FlowGraphConnectionType.Output, this);\r\n        this.signalOutputs.push(output);\r\n        return output;\r\n    }\r\n\r\n    protected _unregisterSignalInput(name: string): void {\r\n        const index = this.signalInputs.findIndex((input) => input.name === name);\r\n        if (index !== -1) {\r\n            this.signalInputs[index].dispose();\r\n            this.signalInputs.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    protected _unregisterSignalOutput(name: string): void {\r\n        const index = this.signalOutputs.findIndex((output) => output.name === name);\r\n        if (index !== -1) {\r\n            this.signalOutputs[index].dispose();\r\n            this.signalOutputs.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    protected _reportError(context: FlowGraphContext, error: Error | string) {\r\n        this.error.payload = typeof error === \"string\" ? new Error(error) : error;\r\n        this.error._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * Given a name of a signal input, return that input if it exists\r\n     * @param name the name of the input\r\n     * @returns if the input exists, the input. Otherwise, undefined.\r\n     */\r\n    public getSignalInput(name: string): FlowGraphSignalConnection | undefined {\r\n        return this.signalInputs.find((input) => input.name === name);\r\n    }\r\n\r\n    /**\r\n     * Given a name of a signal output, return that input if it exists\r\n     * @param name the name of the input\r\n     * @returns if the input exists, the input. Otherwise, undefined.\r\n     */\r\n    public getSignalOutput(name: string): FlowGraphSignalConnection | undefined {\r\n        return this.signalOutputs.find((output) => output.name === name);\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @param serializationObject the object to serialize in\r\n     */\r\n    public override serialize(serializationObject: any = {}) {\r\n        super.serialize(serializationObject);\r\n        serializationObject.signalInputs = [];\r\n        serializationObject.signalOutputs = [];\r\n        for (const input of this.signalInputs) {\r\n            const serializedInput: any = {};\r\n            input.serialize(serializedInput);\r\n            serializationObject.signalInputs.push(serializedInput);\r\n        }\r\n        for (const output of this.signalOutputs) {\r\n            const serializedOutput: any = {};\r\n            output.serialize(serializedOutput);\r\n            serializationObject.signalOutputs.push(serializedOutput);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Deserializes from an object\r\n     * @param serializationObject the object to deserialize from\r\n     */\r\n    public override deserialize(serializationObject: any) {\r\n        for (let i = 0; i < serializationObject.signalInputs.length; i++) {\r\n            const signalInput = this.getSignalInput(serializationObject.signalInputs[i].name);\r\n            if (signalInput) {\r\n                signalInput.deserialize(serializationObject.signalInputs[i]);\r\n            } else {\r\n                throw new Error(\"Could not find signal input with name \" + serializationObject.signalInputs[i].name + \" in block \" + serializationObject.className);\r\n            }\r\n        }\r\n        for (let i = 0; i < serializationObject.signalOutputs.length; i++) {\r\n            const signalOutput = this.getSignalOutput(serializationObject.signalOutputs[i].name);\r\n            if (signalOutput) {\r\n                signalOutput.deserialize(serializationObject.signalOutputs[i]);\r\n            } else {\r\n                throw new Error(\"Could not find signal output with name \" + serializationObject.signalOutputs[i].name + \" in block \" + serializationObject.className);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FlowGraphExecutionBlock\";\r\n    }\r\n}\r\n","import { type IFlowGraphBlockConfiguration } from \"./flowGraphBlock\";\r\nimport { FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\r\nimport { type FlowGraphSignalConnection } from \"./flowGraphSignalConnection\";\r\n\r\n/**\r\n * An execution block that has an out signal. This signal is triggered when the synchronous execution of this block is done.\r\n * Most execution blocks will inherit from this, except for the ones that have multiple signals to be triggered.\r\n * (such as if blocks)\r\n */\r\nexport abstract class FlowGraphExecutionBlockWithOutSignal extends FlowGraphExecutionBlock {\r\n    /**\r\n     * Output connection: The signal that is synchronous triggered when the execution of this block is done.\r\n     * Note that is case of events or async you might want to use the `done` signal instead.\r\n     */\r\n    public readonly out: FlowGraphSignalConnection;\r\n\r\n    protected constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.out = this._registerSignalOutput(\"out\");\r\n    }\r\n}\r\n","import { type IFlowGraphBlockConfiguration } from \"./flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"./flowGraphExecutionBlockWithOutSignal\";\r\nimport { type FlowGraphSignalConnection } from \"./flowGraphSignalConnection\";\r\n\r\n/**\r\n * An async execution block can start tasks that will be executed asynchronously.\r\n * It should also be responsible for clearing it in _cancelPendingTasks.\r\n */\r\nexport abstract class FlowGraphAsyncExecutionBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Output connection: The signal that is triggered when the asynchronous execution of this block is done.\r\n     */\r\n    public done: FlowGraphSignalConnection;\r\n\r\n    protected _eventsSignalOutputs: { [eventName: string]: FlowGraphSignalConnection } = {};\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration, events?: string[]) {\r\n        super(config);\r\n        this.done = this._registerSignalOutput(\"done\");\r\n        if (events) {\r\n            for (const eventName of events) {\r\n                this._eventsSignalOutputs[eventName] = this._registerSignalOutput(eventName + \"Event\");\r\n            }\r\n        }\r\n    }\r\n    /**\r\n     * @internal\r\n     * This function can be overridden to start any\r\n     * pending tasks this node might have, such as\r\n     * timeouts and playing animations.\r\n     * @param context\r\n     */\r\n    public abstract _preparePendingTasks(context: FlowGraphContext): void;\r\n\r\n    /**\r\n     * @internal\r\n     * This function can be overridden to execute any\r\n     * logic that should be executed on every frame\r\n     * while the async task is pending.\r\n     * @param context the context in which it is running\r\n     */\r\n    public _executeOnTick(_context: FlowGraphContext): void {}\r\n\r\n    /**\r\n     * @internal\r\n     * @param context\r\n     */\r\n    public _startPendingTasks(context: FlowGraphContext) {\r\n        if (context._getExecutionVariable(this, \"_initialized\", false)) {\r\n            this._cancelPendingTasks(context);\r\n            this._resetAfterCanceled(context);\r\n        }\r\n\r\n        this._preparePendingTasks(context);\r\n        context._addPendingBlock(this);\r\n        this.out._activateSignal(context);\r\n        context._setExecutionVariable(this, \"_initialized\", true);\r\n    }\r\n\r\n    public _resetAfterCanceled(context: FlowGraphContext) {\r\n        context._deleteExecutionVariable(this, \"_initialized\");\r\n        context._removePendingBlock(this);\r\n    }\r\n\r\n    public abstract _cancelPendingTasks(context: FlowGraphContext): void;\r\n}\r\n","import { type Matrix, type Quaternion, type Vector2, type Vector3, type Vector4 } from \"core/Maths/math.vector\";\r\nimport { type Node } from \"../node\";\r\nimport { type FlowGraphInteger } from \"./CustomTypes/flowGraphInteger\";\r\nimport { type FlowGraphMatrix2D, type FlowGraphMatrix3D } from \"./CustomTypes/flowGraphMatrix\";\r\nimport { FlowGraphTypes } from \"./flowGraphRichTypes.pure\";\r\nimport { IsNavigatorAvailable } from \"core/Misc/domManagement\";\r\n\r\n/**\r\n * Whether the current platform is macOS / iOS.\r\n * Used by keyboard blocks to resolve the platform-appropriate\r\n * \"command or control\" modifier (Cmd on Mac, Ctrl elsewhere).\r\n * @internal\r\n */\r\nexport const _IsMacPlatform: boolean = IsNavigatorAvailable() && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);\r\n\r\n/**\r\n * @internal\r\n * Returns if mesh1 is a descendant of mesh2\r\n * @param mesh1\r\n * @param mesh2\r\n * @returns\r\n */\r\nexport function _IsDescendantOf(mesh1: Node, mesh2: Node): boolean {\r\n    return !!(mesh1.parent && (mesh1.parent === mesh2 || _IsDescendantOf(mesh1.parent, mesh2)));\r\n}\r\n\r\nexport type FlowGraphNumber = number | FlowGraphInteger;\r\nexport type FlowGraphVector = Vector2 | Vector3 | Vector4 | Quaternion;\r\nexport type FlowGraphMatrix = Matrix | FlowGraphMatrix2D | FlowGraphMatrix3D;\r\nexport type FlowGraphMathOperationType = FlowGraphNumber | FlowGraphVector | FlowGraphMatrix | boolean;\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _GetClassNameOf(v: any) {\r\n    if (v.getClassName) {\r\n        return v.getClassName();\r\n    }\r\n    return;\r\n}\r\n\r\n/**\r\n * @internal\r\n * Check if two classname are the same and are vector or quaternion classes.\r\n * @param className the first class name\r\n * @param className2 the second class name\r\n * @returns whether the two class names are the same and are vector or quaternion classes.\r\n */\r\nexport function _AreSameVectorOrQuaternionClass(className: string, className2: string) {\r\n    return (\r\n        className === className2 &&\r\n        (className === FlowGraphTypes.Vector2 || className === FlowGraphTypes.Vector3 || className === FlowGraphTypes.Vector4 || className === FlowGraphTypes.Quaternion)\r\n    );\r\n}\r\n\r\n/**\r\n * @internal\r\n * Check if two classname are the same and are matrix classes.\r\n * @param className the first class name\r\n * @param className2 the second class name\r\n * @returns whether the two class names are the same and are matrix classes.\r\n */\r\nexport function _AreSameMatrixClass(className: string, className2: string) {\r\n    return className === className2 && (className === FlowGraphTypes.Matrix || className === FlowGraphTypes.Matrix2D || className === FlowGraphTypes.Matrix3D);\r\n}\r\n\r\n/**\r\n * @internal\r\n * Check if two classname are the same and are integer classes.\r\n * @param className the first class name\r\n * @param className2 the second class name\r\n * @returns whether the two class names are the same and are integer classes.\r\n */\r\nexport function _AreSameIntegerClass(className: string, className2: string) {\r\n    return className === \"FlowGraphInteger\" && className2 === \"FlowGraphInteger\";\r\n}\r\n\r\n/**\r\n * Check if an object has a numeric value.\r\n * @param a the object to check if it is a number.\r\n * @param validIfNaN whether to consider NaN as a valid number.\r\n * @returns whether a is a FlowGraphNumber (Integer or number).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function isNumeric(a: FlowGraphMathOperationType, validIfNaN?: boolean): a is FlowGraphNumber {\r\n    const isNumeric = typeof a === \"number\" || typeof (a as FlowGraphInteger)?.value === \"number\";\r\n    if (isNumeric && !validIfNaN) {\r\n        return !isNaN(getNumericValue(a as FlowGraphNumber));\r\n    }\r\n    return isNumeric;\r\n}\r\n\r\n/**\r\n * Get the numeric value of a FlowGraphNumber.\r\n * @param a the object to get the numeric value from.\r\n * @returns the numeric value.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getNumericValue(a: FlowGraphNumber): number {\r\n    return typeof a === \"number\" ? a : a.value;\r\n}\r\n","import { type PointerInfo, PointerEventTypes } from \"core/Events/pointerEvents\";\nimport { type KeyboardInfo, KeyboardEventTypes } from \"core/Events/keyboardEvents\";\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\nimport { type Observer, Observable } from \"core/Misc/observable\";\nimport { type Scene } from \"core/scene\";\nimport { type Nullable } from \"core/types\";\nimport { FlowGraphEventType } from \"./flowGraphEventType\";\nimport { _IsMacPlatform } from \"./utils\";\n\n/**\n * the interface of the object the scene event coordinator will trigger.\n */\nexport interface IFlowGraphEventTrigger {\n    /**\n     * The type of the event\n     */\n    type: FlowGraphEventType;\n    /**\n     * The data of the event\n     */\n    payload?: any;\n}\n\n/**\n * This class is responsible for coordinating the events that are triggered in the scene.\n * It registers all observers needed to track certain events and triggers the blocks that are listening to them.\n * Abstracting the events from the class will allow us to easily change the events that are being listened to, and trigger them in any order.\n */\nexport class FlowGraphSceneEventCoordinator {\n    /**\n     * @internal\n     */\n    public readonly _scene: Scene;\n\n    /**\n     * register to this observable to get flow graph event notifications.\n     */\n    public onEventTriggeredObservable: Observable<IFlowGraphEventTrigger> = new Observable();\n\n    /**\n     * Was scene-ready already triggered?\n     */\n    public sceneReadyTriggered: boolean = false;\n\n    private _sceneDisposeObserver: Nullable<Observer<Scene>>;\n    private _sceneReadyObserver: Nullable<Observer<Scene>>;\n    private _sceneOnBeforeRenderObserver: Nullable<Observer<Scene>>;\n    private _meshPickedObserver: Nullable<Observer<PointerInfo>>;\n    private _meshUnderPointerObserver: Nullable<Observer<{ mesh: Nullable<AbstractMesh>; pointerId: number }>>;\n    private _pointerDownObserver: Nullable<Observer<PointerInfo>>;\n    private _pointerUpObserver: Nullable<Observer<PointerInfo>>;\n    private _pointerMoveObserver: Nullable<Observer<PointerInfo>>;\n    private _pointerUnderMeshState: { [pointerId: number]: Nullable<AbstractMesh> } = {};\n    private _keyDownObserver: Nullable<Observer<KeyboardInfo>>;\n    private _keyUpObserver: Nullable<Observer<KeyboardInfo>>;\n    private _onBlurHandler: (() => void) | null = null;\n\n    /**\n     * The set of keys currently pressed, keyed by `event.code`.\n     * Keyboard event blocks use this to determine whether a key is held.\n     *\n     * In addition to physical key codes, a virtual `\"CommandOrControl\"` entry\n     * is maintained: it tracks Meta (Cmd) on macOS and Ctrl on Windows/Linux,\n     * enabling platform-agnostic shortcut checks via the IsKeyPressed block.\n     */\n    public readonly pressedKeys: Set<string> = new Set<string>();\n\n    /** The physical key codes that map to the virtual CommandOrControl key on this platform. */\n    private static readonly _COMMAND_OR_CTRL_CODES: ReadonlySet<string> = _IsMacPlatform ? new Set([\"MetaLeft\", \"MetaRight\"]) : new Set([\"ControlLeft\", \"ControlRight\"]);\n\n    private _startingTime: number = 0;\n\n    constructor(scene: Scene) {\n        this._scene = scene;\n        this._initialize();\n    }\n\n    private _initialize() {\n        this._sceneReadyObserver = this._scene.onReadyObservable.addOnce(() => {\n            if (!this.sceneReadyTriggered) {\n                this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\n                this.sceneReadyTriggered = true;\n            }\n        });\n\n        this._sceneDisposeObserver = this._scene.onDisposeObservable.add(() => {\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneDispose });\n        });\n        this._sceneOnBeforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\n            const deltaTime = this._scene.getEngine().getDeltaTime() / 1000; // set in seconds\n            this.onEventTriggeredObservable.notifyObservers({\n                type: FlowGraphEventType.SceneBeforeRender,\n                payload: {\n                    timeSinceStart: this._startingTime,\n                    deltaTime,\n                },\n            });\n            this._startingTime += deltaTime;\n        });\n\n        this._meshPickedObserver = this._scene.onPointerObservable.add((pointerInfo) => {\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.MeshPick, payload: pointerInfo });\n        }, PointerEventTypes.POINTERPICK); // should it be pointerdown?\n\n        this._pointerDownObserver = this._scene.onPointerObservable.add((pointerInfo) => {\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerDown, payload: pointerInfo });\n        }, PointerEventTypes.POINTERDOWN);\n\n        this._pointerUpObserver = this._scene.onPointerObservable.add((pointerInfo) => {\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerUp, payload: pointerInfo });\n        }, PointerEventTypes.POINTERUP);\n\n        this._pointerMoveObserver = this._scene.onPointerObservable.add((pointerInfo) => {\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerMove, payload: pointerInfo });\n        }, PointerEventTypes.POINTERMOVE);\n\n        this._meshUnderPointerObserver = this._scene.onMeshUnderPointerUpdatedObservable.add((data) => {\n            // check if the data has changed. Check the state of the last change and see if it is a mesh or null.\n            // if it is a mesh and the previous state was null, trigger over event. If it is null and the previous state was a mesh, trigger out event.\n            // if it is a mesh and the previous state was a mesh, trigger out from the old mesh and over the new mesh\n            // if it is null and the previous state was null, do nothing.\n            const pointerId = data.pointerId;\n            const mesh = data.mesh;\n            const previousState = this._pointerUnderMeshState[pointerId];\n            if (!previousState && mesh) {\n                this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerOver, payload: { pointerId, mesh } });\n            } else if (previousState && !mesh) {\n                this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerOut, payload: { pointerId, mesh: previousState } });\n            } else if (previousState && mesh && previousState !== mesh) {\n                this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerOut, payload: { pointerId, mesh: previousState, over: mesh } });\n                this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.PointerOver, payload: { pointerId, mesh, out: previousState } });\n            }\n            this._pointerUnderMeshState[pointerId] = mesh;\n        }, PointerEventTypes.POINTERMOVE);\n\n        this._keyDownObserver = this._scene.onKeyboardObservable.add((keyboardInfo) => {\n            const code = keyboardInfo.event.code;\n            this.pressedKeys.add(code);\n            if (FlowGraphSceneEventCoordinator._COMMAND_OR_CTRL_CODES.has(code)) {\n                this.pressedKeys.add(\"CommandOrControl\");\n            }\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.KeyDown, payload: keyboardInfo });\n        }, KeyboardEventTypes.KEYDOWN);\n\n        this._keyUpObserver = this._scene.onKeyboardObservable.add((keyboardInfo) => {\n            const code = keyboardInfo.event.code;\n            this.pressedKeys.delete(code);\n            if (FlowGraphSceneEventCoordinator._COMMAND_OR_CTRL_CODES.has(code)) {\n                // Only remove CommandOrControl if neither left nor right is still held\n                let stillHeld = false;\n                for (const c of Array.from(FlowGraphSceneEventCoordinator._COMMAND_OR_CTRL_CODES)) {\n                    if (c !== code && this.pressedKeys.has(c)) {\n                        stillHeld = true;\n                        break;\n                    }\n                }\n                if (!stillHeld) {\n                    this.pressedKeys.delete(\"CommandOrControl\");\n                }\n            }\n            this.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.KeyUp, payload: keyboardInfo });\n        }, KeyboardEventTypes.KEYUP);\n\n        // Clear all tracked keys when the window/tab loses focus.\n        // Without this, held keys would appear \"stuck\" after an Alt-Tab\n        // because the keyup event fires in the other window.\n        const canvas = this._scene.getEngine().getRenderingCanvas();\n        if (canvas) {\n            this._onBlurHandler = () => this.pressedKeys.clear();\n            canvas.addEventListener(\"blur\", this._onBlurHandler);\n        }\n    }\n\n    public dispose() {\n        this._sceneDisposeObserver?.remove();\n        this._sceneReadyObserver?.remove();\n        this._sceneOnBeforeRenderObserver?.remove();\n        this._meshPickedObserver?.remove();\n        this._meshUnderPointerObserver?.remove();\n        this._pointerDownObserver?.remove();\n        this._pointerUpObserver?.remove();\n        this._pointerMoveObserver?.remove();\n        this._keyDownObserver?.remove();\n        this._keyUpObserver?.remove();\n        if (this._onBlurHandler) {\n            const canvas = this._scene.getEngine().getRenderingCanvas();\n            canvas?.removeEventListener(\"blur\", this._onBlurHandler);\n            this._onBlurHandler = null;\n        }\n        this.pressedKeys.clear();\n        this.onEventTriggeredObservable.clear();\n    }\n}\n","import { FlowGraphAsyncExecutionBlock } from \"./flowGraphAsyncExecutionBlock\";\r\nimport { type IFlowGraphBlockConfiguration } from \"./flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { FlowGraphEventType } from \"./flowGraphEventType\";\r\n\r\n/**\r\n * A type of block that listens to an event observable and activates\r\n * its output signal when the event is triggered.\r\n */\r\nexport abstract class FlowGraphEventBlock extends FlowGraphAsyncExecutionBlock {\r\n    /**\r\n     * the priority of initialization of this block.\r\n     * For example, scene start should have a negative priority because it should be initialized last.\r\n     */\r\n    public initPriority: number = 0;\r\n\r\n    /**\r\n     * Creates a new event block.\r\n     * @param config optional configuration\r\n     */\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        // Event blocks are driven by scene events, not by an incoming signal.\r\n        // Remove the inherited `in` port so it is not shown in the editor UI\r\n        // and cannot be accidentally wired.\r\n        this._unregisterSignalInput(\"in\");\r\n    }\r\n\r\n    /**\r\n     * Deserializes from an object.\r\n     * Filters out the legacy \"in\" signal input that existed before event blocks\r\n     * stopped exposing it, so old serialized graphs load without error.\r\n     * @param serializationObject the object to deserialize from\r\n     */\r\n    public override deserialize(serializationObject: any) {\r\n        const filtered = { ...serializationObject };\r\n        filtered.signalInputs = (serializationObject.signalInputs ?? []).filter((s: any) => s.name !== \"in\");\r\n        super.deserialize(filtered);\r\n    }\r\n\r\n    /**\r\n     * The type of the event\r\n     */\r\n    public readonly type: FlowGraphEventType = FlowGraphEventType.NoTrigger;\r\n\r\n    /**\r\n     * Stable key used to represent this event during propagation.\r\n     * Event blocks with equivalent event sources should return the same key.\r\n     */\r\n    public get eventKey(): string {\r\n        return (this.config as { eventKey?: string } | undefined)?.eventKey ?? this.type;\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public _execute(context: FlowGraphContext): void {\r\n        context._notifyExecuteNode(this);\r\n        // Fire both signals: KHR_interactivity graphs connect to `done`,\r\n        // while editor-authored graphs typically connect to `out`.\r\n        // Both must fire so that either wiring style works correctly.\r\n        this.done._activateSignal(context);\r\n        this.out._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Override _startPendingTasks so that event blocks do NOT fire the\r\n     * `out` signal at graph-start time.  The base FlowGraphAsyncExecutionBlock\r\n     * fires `out` immediately in _startPendingTasks (useful for async blocks\r\n     * like PlayAnimation that start a task and let sync flow continue).\r\n     * Event blocks should only fire their output signals when the actual\r\n     * event occurs, which is handled by _execute.\r\n     */\r\n    public override _startPendingTasks(context: FlowGraphContext): void {\r\n        if (context._getExecutionVariable(this, \"_initialized\", false)) {\r\n            this._cancelPendingTasks(context);\r\n            this._resetAfterCanceled(context);\r\n        }\r\n        this._preparePendingTasks(context);\r\n        context._addPendingBlock(this);\r\n        // Do NOT fire out._activateSignal — event blocks fire both out and\r\n        // done in _execute when the actual event triggers.\r\n        context._setExecutionVariable(this, \"_initialized\", true);\r\n    }\r\n\r\n    /**\r\n     * Execute the event. This function should be called by the flow graph when the event is triggered.\r\n     * @param context the context in which the event is executed\r\n     * @param payload the payload of the event\r\n     * @returns a boolean indicating if the event should stop propagation. if false, the event will stop propagating.\r\n     */\r\n    public abstract _executeEvent(context: FlowGraphContext, payload: any): boolean;\r\n}\r\n","import { type FlowGraph } from \"./flowGraph\";\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\nimport { FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\nimport { type FlowGraphDataConnection } from \"./flowGraphDataConnection\";\nimport { FlowGraphTypes } from \"./flowGraphRichTypes.pure\";\nimport { FlowGraphEventBlock } from \"./flowGraphEventBlock\";\nimport { type FlowGraphEventType } from \"./flowGraphEventType\";\n\n/**\n * Severity level for a validation issue.\n */\nexport const enum FlowGraphValidationSeverity {\n    /** A critical issue that will cause runtime failure. */\n    Error,\n    /** A potential issue that may indicate a mistake. */\n    Warning,\n}\n\n/**\n * A single validation issue found in the flow graph.\n */\nexport interface IFlowGraphValidationIssue {\n    /** The severity level. */\n    severity: FlowGraphValidationSeverity;\n    /** Human-readable description of the issue. */\n    message: string;\n    /** The block where the issue was found (if applicable). */\n    block?: FlowGraphBlock;\n    /** The connection name involved (if applicable). */\n    connectionName?: string;\n}\n\n/**\n * The result of validating a flow graph.\n */\nexport interface IFlowGraphValidationResult {\n    /** Whether the graph passed validation with no errors. */\n    isValid: boolean;\n    /** All issues found, ordered by severity (errors first). */\n    issues: IFlowGraphValidationIssue[];\n    /** Convenience: number of error-level issues. */\n    errorCount: number;\n    /** Convenience: number of warning-level issues. */\n    warningCount: number;\n    /** Map from block uniqueId to the issues affecting that block. */\n    issuesByBlock: Map<string, IFlowGraphValidationIssue[]>;\n}\n\n// Types that are mutually coercible and should not produce type-mismatch warnings\nconst NumericLikeTypes = new Set<string>([FlowGraphTypes.Number, FlowGraphTypes.Integer, FlowGraphTypes.Boolean]);\nconst VectorLikeTypes = new Set<string>([FlowGraphTypes.Vector4, FlowGraphTypes.Quaternion]);\nconst ColorLikeTypes = new Set<string>([FlowGraphTypes.Color3, FlowGraphTypes.Color4]);\n\n/**\n * @internal\n */\nfunction _AreTypesCompatible(sourceType: string, targetType: string): boolean {\n    if (sourceType === targetType) {\n        return true;\n    }\n    // \"any\" is compatible with everything\n    if (sourceType === FlowGraphTypes.Any || targetType === FlowGraphTypes.Any) {\n        return true;\n    }\n    // Numeric coercion group\n    if (NumericLikeTypes.has(sourceType) && NumericLikeTypes.has(targetType)) {\n        return true;\n    }\n    // Vector4 / Quaternion are interchangeable\n    if (VectorLikeTypes.has(sourceType) && VectorLikeTypes.has(targetType)) {\n        return true;\n    }\n    // Color3 → Color4 widening is safe\n    if (ColorLikeTypes.has(sourceType) && ColorLikeTypes.has(targetType)) {\n        return true;\n    }\n    return false;\n}\n\n/**\n * Validates a flow graph and returns all issues found.\n *\n * The following checks are performed:\n * 1. **No event blocks** — the graph has no entry points.\n * 2. **Unconnected required data inputs** — a non-optional data input with no connection.\n * 3. **Unconnected signal inputs** — an execution block whose `in` signal has no connection and\n *    that is not an event block (entry point).\n * 4. **Data type mismatches** — a data connection whose source richType is incompatible with the\n *    target richType.\n * 5. **Unreachable blocks** — blocks not reachable from any event block via signal/data traversal.\n * 6. **Data dependency cycles** — circular data-only connections that would cause infinite recursion.\n *\n * @param flowGraph - The flow graph to validate.\n * @returns The validation result.\n */\nexport function ValidateFlowGraph(flowGraph: FlowGraph): IFlowGraphValidationResult {\n    const issues: IFlowGraphValidationIssue[] = [];\n    const issuesByBlock = new Map<string, IFlowGraphValidationIssue[]>();\n\n    const addIssue = (issue: IFlowGraphValidationIssue) => {\n        issues.push(issue);\n        if (issue.block) {\n            let arr = issuesByBlock.get(issue.block.uniqueId);\n            if (!arr) {\n                arr = [];\n                issuesByBlock.set(issue.block.uniqueId, arr);\n            }\n            arr.push(issue);\n        }\n    };\n\n    // Collect ALL blocks via visitAllBlocks\n    const allBlocks: FlowGraphBlock[] = [];\n    flowGraph.visitAllBlocks((block) => {\n        allBlocks.push(block);\n    });\n\n    // ── Check 1: No event blocks ───────────────────────────────────────\n    const eventBlocks = _GetEventBlocks(flowGraph);\n    if (eventBlocks.length === 0) {\n        addIssue({\n            severity: FlowGraphValidationSeverity.Error,\n            message: \"Graph has no event blocks — nothing will trigger execution.\",\n        });\n    }\n\n    // ── Check 2: Unconnected required data inputs ──────────────────────\n    for (const block of allBlocks) {\n        for (const input of block.dataInputs) {\n            if (!input.optional && !input.isDisabled && !input.isConnected()) {\n                addIssue({\n                    severity: FlowGraphValidationSeverity.Warning,\n                    message: `\"${input.name}\" is not connected and will use its default value.`,\n                    block,\n                    connectionName: input.name,\n                });\n            }\n        }\n    }\n\n    // ── Check 3: Unconnected signal inputs on non-event execution blocks\n    for (const block of allBlocks) {\n        if (block instanceof FlowGraphExecutionBlock) {\n            // Skip event blocks — they are entry points and don't need an incoming signal.\n            if (_IsEventBlock(block)) {\n                continue;\n            }\n            const inSignal = block.signalInputs.find((s) => s.name === \"in\");\n            if (inSignal && !inSignal.isConnected()) {\n                addIssue({\n                    severity: FlowGraphValidationSeverity.Error,\n                    message: `Execution block has no incoming signal — it will never execute.`,\n                    block,\n                    connectionName: \"in\",\n                });\n            }\n        }\n    }\n\n    // ── Check 4: Data type mismatches ──────────────────────────────────\n    for (const block of allBlocks) {\n        for (const input of block.dataInputs) {\n            if (!input.isConnected()) {\n                continue;\n            }\n            const source = input._connectedPoint[0] as FlowGraphDataConnection<any>;\n            const srcType = source.richType?.typeName;\n            const tgtType = input.richType?.typeName;\n            if (srcType && tgtType && !_AreTypesCompatible(srcType, tgtType)) {\n                // If either side has a typeTransformer, it's intentionally converted\n                if (source.richType.typeTransformer !== undefined || input.richType.typeTransformer !== undefined) {\n                    continue;\n                }\n                addIssue({\n                    severity: FlowGraphValidationSeverity.Warning,\n                    message: `Type mismatch: \"${source._ownerBlock.name}.${source.name}\" (${srcType}) → \"${block.name}.${input.name}\" (${tgtType}).`,\n                    block,\n                    connectionName: input.name,\n                });\n            }\n        }\n    }\n\n    // ── Check 5: Unreachable blocks ────────────────────────────────────\n    const reachableIds = new Set<string>();\n    flowGraph.visitAllBlocks((block) => {\n        reachableIds.add(block.uniqueId);\n    });\n    // We need to also check standalone data blocks not visited by visitAllBlocks.\n    // visitAllBlocks starts from event blocks; any block not found is unreachable.\n    // Since we can only iterate blocks we know about, the allBlocks list IS\n    // from visitAllBlocks, so everything in it IS reachable.\n    // There's no separate registry of \"all added blocks\" in the FlowGraph.\n    // So: unreachable blocks are blocks that exist but aren't visited.\n    // Currently visitAllBlocks IS our source, so this check is a no-op for\n    // blocks added via the graph. However, the editor creates nodes and adds\n    // execution blocks, so we should compare against the editor's full list.\n    // For the core validator, we expose a variant that accepts an external block list.\n\n    // ── Check 6: Data dependency cycles ────────────────────────────────\n    _DetectDataCycles(allBlocks, addIssue);\n\n    // Sort: errors first, then warnings\n    issues.sort((a, b) => a.severity - b.severity);\n\n    return {\n        isValid: issues.every((i) => i.severity !== FlowGraphValidationSeverity.Error),\n        issues,\n        errorCount: issues.filter((i) => i.severity === FlowGraphValidationSeverity.Error).length,\n        warningCount: issues.filter((i) => i.severity === FlowGraphValidationSeverity.Warning).length,\n        issuesByBlock,\n    };\n}\n\n/**\n * Extended validation that also checks for unreachable blocks.\n * Requires a full list of all blocks in the graph (including those not reachable\n * from event blocks via the normal traversal).\n *\n * @param flowGraph - The flow graph to validate.\n * @param allKnownBlocks - Complete list of all blocks (e.g., from the editor's node set).\n * @returns The validation result.\n */\nexport function ValidateFlowGraphWithBlockList(flowGraph: FlowGraph, allKnownBlocks: FlowGraphBlock[]): IFlowGraphValidationResult {\n    const result = ValidateFlowGraph(flowGraph);\n\n    // Check for unreachable blocks\n    const reachableIds = new Set<string>();\n    flowGraph.visitAllBlocks((block) => {\n        reachableIds.add(block.uniqueId);\n    });\n\n    for (const block of allKnownBlocks) {\n        if (!reachableIds.has(block.uniqueId)) {\n            const issue: IFlowGraphValidationIssue = {\n                severity: FlowGraphValidationSeverity.Warning,\n                message: `Block is unreachable from any event block.`,\n                block,\n            };\n            result.issues.push(issue);\n            result.warningCount++;\n            let arr = result.issuesByBlock.get(block.uniqueId);\n            if (!arr) {\n                arr = [];\n                result.issuesByBlock.set(block.uniqueId, arr);\n            }\n            arr.push(issue);\n\n            // Also run Check 2 and Check 3 on unreachable blocks so the editor\n            // can display all issues, not just reachability ones.\n            for (const input of block.dataInputs) {\n                if (!input.optional && !input.isDisabled && !input.isConnected()) {\n                    const dataIssue: IFlowGraphValidationIssue = {\n                        severity: FlowGraphValidationSeverity.Warning,\n                        message: `\"${input.name}\" is not connected and will use its default value.`,\n                        block,\n                        connectionName: input.name,\n                    };\n                    result.issues.push(dataIssue);\n                    result.warningCount++;\n                    arr.push(dataIssue);\n                }\n            }\n\n            if (block instanceof FlowGraphExecutionBlock && !_IsEventBlock(block)) {\n                const inSignal = block.signalInputs.find((s) => s.name === \"in\");\n                if (inSignal && !inSignal.isConnected()) {\n                    const signalIssue: IFlowGraphValidationIssue = {\n                        severity: FlowGraphValidationSeverity.Error,\n                        message: `Execution block has no incoming signal — it will never execute.`,\n                        block,\n                        connectionName: \"in\",\n                    };\n                    result.issues.push(signalIssue);\n                    result.errorCount++;\n                    arr.push(signalIssue);\n                }\n            }\n        }\n    }\n\n    result.isValid = result.issues.every((i) => i.severity !== FlowGraphValidationSeverity.Error);\n    result.issues.sort((a, b) => a.severity - b.severity);\n    return result;\n}\n\n/**\n * Get all event blocks from a flow graph.\n * @param flowGraph - the flow graph\n * @returns the event blocks\n */\nfunction _GetEventBlocks(flowGraph: FlowGraph): FlowGraphEventBlock[] {\n    const eventBlocks: FlowGraphEventBlock[] = [];\n    for (const type in flowGraph._eventBlocks) {\n        for (const block of flowGraph._eventBlocks[type as FlowGraphEventType]) {\n            eventBlocks.push(block);\n        }\n    }\n    return eventBlocks;\n}\n\n/**\n * Detect whether a block is an event block (entry point).\n * @param block - the block to check\n * @returns true if it is an event block\n */\nfunction _IsEventBlock(block: FlowGraphBlock): boolean {\n    return block instanceof FlowGraphEventBlock;\n}\n\n/**\n * Detects cycles among data-only blocks.\n * A data cycle means that block A's output feeds into block B's input, and\n * block B's output feeds back into block A (directly or indirectly).\n * This would cause infinite recursion during getValue().\n * @param allBlocks - all blocks to check\n * @param addIssue - callback to report issues\n */\nfunction _DetectDataCycles(allBlocks: FlowGraphBlock[], addIssue: (issue: IFlowGraphValidationIssue) => void): void {\n    // Build adjacency: for each block, which blocks do its data inputs depend on?\n    // (Data inputs pull values from connected output blocks.)\n    const white = 0; // unvisited\n    const gray = 1; // in current DFS path\n    const black = 2; // fully explored\n    const color = new Map<string, number>();\n\n    for (const block of allBlocks) {\n        color.set(block.uniqueId, white);\n    }\n\n    const blockMap = new Map<string, FlowGraphBlock>();\n    for (const block of allBlocks) {\n        blockMap.set(block.uniqueId, block);\n    }\n\n    const reportedCycleBlocks = new Set<string>();\n\n    function dfs(block: FlowGraphBlock): boolean {\n        color.set(block.uniqueId, gray);\n        for (const input of block.dataInputs) {\n            if (!input.isConnected()) {\n                continue;\n            }\n            for (const connected of input._connectedPoint) {\n                const dep = (connected as FlowGraphDataConnection<any>)._ownerBlock;\n                // Only consider data-only blocks (not execution blocks which are driven by signals)\n                if (dep instanceof FlowGraphExecutionBlock) {\n                    continue;\n                }\n                const depColor = color.get(dep.uniqueId);\n                if (depColor === gray) {\n                    // Cycle found\n                    if (!reportedCycleBlocks.has(block.uniqueId)) {\n                        reportedCycleBlocks.add(block.uniqueId);\n                        addIssue({\n                            severity: FlowGraphValidationSeverity.Error,\n                            message: `Data dependency cycle detected — getValue() will recurse infinitely.`,\n                            block,\n                        });\n                    }\n                    if (!reportedCycleBlocks.has(dep.uniqueId)) {\n                        reportedCycleBlocks.add(dep.uniqueId);\n                        addIssue({\n                            severity: FlowGraphValidationSeverity.Error,\n                            message: `Data dependency cycle detected — getValue() will recurse infinitely.`,\n                            block: dep,\n                        });\n                    }\n                    return true;\n                }\n                if (depColor === white) {\n                    dfs(dep);\n                }\n            }\n        }\n        color.set(block.uniqueId, black);\n        return false;\n    }\n\n    for (const block of allBlocks) {\n        if (color.get(block.uniqueId) === white) {\n            dfs(block);\n        }\n    }\n}\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type FlowGraphEventBlock } from \"./flowGraphEventBlock\";\r\nimport { FlowGraphContext } from \"./flowGraphContext\";\r\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"./flowGraphAsyncExecutionBlock\";\r\nimport { type FlowGraphCoordinator } from \"./flowGraphCoordinator\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { FlowGraphEventType } from \"./flowGraphEventType\";\r\nimport { type IFlowGraphEventTrigger, FlowGraphSceneEventCoordinator } from \"./flowGraphSceneEventCoordinator\";\r\nimport { type FlowGraphMeshPickEventBlock } from \"./Blocks/Event/flowGraphMeshPickEventBlock\";\r\nimport { _IsDescendantOf } from \"./utils\";\r\nimport { type IFlowGraphValidationResult, ValidateFlowGraphWithBlockList } from \"./flowGraphValidator\";\r\nimport { RandomGUID } from \"../Misc/guid\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\n\r\n// UMD global names for the flow graph editor bundle (mirrors nodeGeometry.ts / nodeRenderGraph.ts).\r\ndeclare let FLOWGRAPHEDITOR: any;\r\ndeclare let BABYLON: any;\r\n\r\n/**\r\n * Interface used to configure the launch of the flow graph editor.\r\n */\r\nexport interface IFlowGraphEditorLaunchOptions {\r\n    /** Define the URL to load the flow graph editor script from */\r\n    editorURL?: string;\r\n    /** Additional configuration forwarded to `FlowGraphEditor.Show()` (e.g. hostScene, hostElement) */\r\n    flowGraphEditorConfig?: {\r\n        hostScene?: Scene;\r\n        hostElement?: HTMLElement;\r\n        attachToLiveScene?: boolean;\r\n    };\r\n}\r\n\r\nexport const enum FlowGraphState {\r\n    /**\r\n     * The graph is stopped\r\n     */\r\n    Stopped,\r\n    /**\r\n     * The graph is running\r\n     */\r\n    Started,\r\n    /**\r\n     * The graph is paused (contexts kept, pending tasks cancelled)\r\n     */\r\n    Paused,\r\n}\r\n\r\n/**\r\n * Parameters used to create a flow graph.\r\n */\r\nexport interface IFlowGraphParams {\r\n    /**\r\n     * The scene that the flow graph belongs to.\r\n     */\r\n    scene: Scene;\r\n    /**\r\n     * The event coordinator used by the flow graph.\r\n     */\r\n    coordinator: FlowGraphCoordinator;\r\n    /**\r\n     * Optional human-readable name for the graph.\r\n     * Defaults to \"Graph\" if not provided.\r\n     */\r\n    name?: string;\r\n    /**\r\n     * Optional unique identifier for the graph.\r\n     * If not provided, a random UUID is generated.\r\n     */\r\n    uniqueId?: string;\r\n}\r\n\r\n/**\r\n * Options for parsing a flow graph.\r\n */\r\nexport interface IFlowGraphParseOptions {\r\n    /**\r\n     * A function that parses complex values in a scene.\r\n     * @param key the key of the value\r\n     * @param serializationObject the object to read the value from\r\n     * @param assetsContainer the assets container to read assets from\r\n     * @param scene the scene to read the value from\r\n     */\r\n    valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n    /**\r\n     * The flow graph coordinator.\r\n     */\r\n    coordinator: FlowGraphCoordinator;\r\n    /**\r\n     * A function that converts a path to an object accessor.\r\n     */\r\n    pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n}\r\n/**\r\n * Class used to represent a flow graph.\r\n * A flow graph is a graph of blocks that can be used to create complex logic.\r\n * Blocks can be added to the graph and connected to each other.\r\n * The graph can then be started, which will init and start all of its event blocks.\r\n *\r\n * @experimental FlowGraph is still in development and is subject to change.\r\n */\r\nexport class FlowGraph {\r\n    /**\r\n     * A human-readable name for this graph.\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * A unique identifier for this graph. Auto-generated if not provided.\r\n     */\r\n    public uniqueId: string;\r\n\r\n    /**\r\n     * Optional host-format metadata associated with this graph.\r\n     */\r\n    public metadata?: any;\r\n\r\n    /**\r\n     * Define the URL to load the flow graph editor script from.\r\n     */\r\n    public static EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/flowGraphEditor/babylon.flowGraphEditor.js`;\r\n\r\n    private _BJSFLOWGRAPHEDITOR = this._getGlobalFlowGraphEditor();\r\n\r\n    /** @returns the flow graph editor from a UMD bundle or the BABYLON global, or undefined if not loaded */\r\n    private _getGlobalFlowGraphEditor(): any {\r\n        // UMD global name detection from bundle metadata. rollup-built UMD bundles may expose the\r\n        // editor class on `.default.FlowGraphEditor`, so unwrap that case before falling back to\r\n        // the BABYLON global emitted from the editor entry point.\r\n        if (typeof FLOWGRAPHEDITOR !== \"undefined\") {\r\n            if ((FLOWGRAPHEDITOR as any).FlowGraphEditor) {\r\n                return FLOWGRAPHEDITOR;\r\n            }\r\n            if ((FLOWGRAPHEDITOR as any).default?.FlowGraphEditor) {\r\n                return (FLOWGRAPHEDITOR as any).default;\r\n            }\r\n        }\r\n\r\n        if (typeof BABYLON !== \"undefined\" && typeof BABYLON.FlowGraphEditor !== \"undefined\") {\r\n            return BABYLON;\r\n        }\r\n\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * An observable that is triggered when the state of the graph changes.\r\n     */\r\n    public onStateChangedObservable: Observable<FlowGraphState> = new Observable();\r\n    /** @internal */\r\n    public _eventBlocks: { [keyof in FlowGraphEventType]: FlowGraphEventBlock[] } = {\r\n        [FlowGraphEventType.SceneReady]: [],\r\n        [FlowGraphEventType.SceneDispose]: [],\r\n        [FlowGraphEventType.SceneBeforeRender]: [],\r\n        [FlowGraphEventType.MeshPick]: [],\r\n        [FlowGraphEventType.PointerDown]: [],\r\n        [FlowGraphEventType.PointerUp]: [],\r\n        [FlowGraphEventType.PointerMove]: [],\r\n        [FlowGraphEventType.PointerOver]: [],\r\n        [FlowGraphEventType.PointerOut]: [],\r\n        [FlowGraphEventType.KeyDown]: [],\r\n        [FlowGraphEventType.KeyUp]: [],\r\n        [FlowGraphEventType.SceneAfterRender]: [],\r\n        [FlowGraphEventType.NoTrigger]: [],\r\n    };\r\n\r\n    /**\r\n     * All blocks that belong to this graph, including unreachable ones.\r\n     * @internal\r\n     */\r\n    public _allBlocks: FlowGraphBlock[] = [];\r\n    /**\r\n     * @internal\r\n     */\r\n    public readonly _scene: Scene;\r\n\r\n    /**\r\n     * The scene associated with this flow graph.\r\n     */\r\n    public get scene(): Scene {\r\n        return this._scene;\r\n    }\r\n    private _coordinator: FlowGraphCoordinator;\r\n\r\n    /**\r\n     * The coordinator that owns this flow graph.\r\n     */\r\n    public get coordinator(): FlowGraphCoordinator {\r\n        return this._coordinator;\r\n    }\r\n    private _executionContexts: FlowGraphContext[] = [];\r\n    private _sceneEventCoordinator: FlowGraphSceneEventCoordinator;\r\n\r\n    /**\r\n     * The scene event coordinator for this graph.\r\n     * Provides access to runtime event state such as currently pressed keys.\r\n     */\r\n    public get sceneEventCoordinator(): FlowGraphSceneEventCoordinator {\r\n        return this._sceneEventCoordinator;\r\n    }\r\n\r\n    private _eventObserver: Nullable<Observer<IFlowGraphEventTrigger>>;\r\n\r\n    /**\r\n     * The state of the graph\r\n     */\r\n    private _state: FlowGraphState = FlowGraphState.Stopped;\r\n\r\n    /**\r\n     * The state of the graph\r\n     */\r\n    public get state() {\r\n        return this._state;\r\n    }\r\n\r\n    /**\r\n     * The state of the graph\r\n     */\r\n    public set state(value: FlowGraphState) {\r\n        this._state = value;\r\n        this.onStateChangedObservable.notifyObservers(value);\r\n    }\r\n\r\n    /**\r\n     * Construct a Flow Graph\r\n     * @param params construction parameters. currently only the scene\r\n     */\r\n    public constructor(params: IFlowGraphParams) {\r\n        this._scene = params.scene;\r\n        this._sceneEventCoordinator = new FlowGraphSceneEventCoordinator(this._scene);\r\n        this._coordinator = params.coordinator;\r\n        this.name = params.name ?? \"Graph\";\r\n        this.uniqueId = params.uniqueId ?? RandomGUID();\r\n    }\r\n\r\n    private _attachEventObserver() {\r\n        if (this._eventObserver) {\r\n            return;\r\n        }\r\n        this._eventObserver = this._sceneEventCoordinator.onEventTriggeredObservable.add((event, eventState) => {\r\n            if (event.type === FlowGraphEventType.SceneDispose) {\r\n                this.dispose();\r\n                return;\r\n            }\r\n\r\n            if (this.state !== FlowGraphState.Started) {\r\n                return;\r\n            }\r\n\r\n            const propagationStops =\r\n                event.type === FlowGraphEventType.MeshPick || event.type === FlowGraphEventType.PointerOver || event.type === FlowGraphEventType.PointerOut\r\n                    ? ([] as AbstractMesh[])\r\n                    : undefined;\r\n            const payload = event.payload as { mesh?: AbstractMesh; pickInfo?: { pickedMesh?: AbstractMesh } } | undefined;\r\n            const source = payload?.pickInfo?.pickedMesh ?? payload?.mesh;\r\n            for (const context of this._executionContexts) {\r\n                const order = this._getContextualOrder(event.type, context);\r\n                for (const block of order) {\r\n                    const eventBlock = block as FlowGraphEventBlock & {\r\n                        _getReferencedMesh?: (context: FlowGraphContext) => AbstractMesh | undefined;\r\n                    };\r\n                    const target = eventBlock._getReferencedMesh?.(context);\r\n                    if (source && target && propagationStops?.some((stoppedTarget) => stoppedTarget !== target && _IsDescendantOf(source, target))) {\r\n                        continue;\r\n                    }\r\n                    const eventKey = eventBlock.eventKey;\r\n                    this._coordinator._beginEventDispatch(eventKey, eventState);\r\n                    let shouldContinue: boolean;\r\n                    let dispatch: ReturnType<FlowGraphCoordinator[\"_endEventDispatch\"]>;\r\n                    try {\r\n                        shouldContinue = block._executeEvent(context, event.payload);\r\n                    } finally {\r\n                        dispatch = this._coordinator._endEventDispatch();\r\n                    }\r\n                    if (dispatch?.propagationStopped && target) {\r\n                        propagationStops?.push(target);\r\n                    }\r\n                    if (eventState.skipNextObservers || !shouldContinue) {\r\n                        break;\r\n                    }\r\n                }\r\n                if (eventState.skipNextObservers) {\r\n                    break;\r\n                }\r\n            }\r\n            // custom behavior(s) of specific events\r\n            switch (event.type) {\r\n                case FlowGraphEventType.SceneReady:\r\n                    this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n                    break;\r\n                case FlowGraphEventType.SceneBeforeRender:\r\n                    for (const context of this._executionContexts) {\r\n                        context._notifyOnTick(event.payload);\r\n                    }\r\n                    break;\r\n            }\r\n        });\r\n    }\r\n\r\n    private _detachEventObserver() {\r\n        this._eventObserver?.remove();\r\n        this._eventObserver = null;\r\n    }\r\n\r\n    /**\r\n     * Sets a new scene for this flow graph, re-wiring all event listeners.\r\n     * This is useful when the scene the flow graph should listen to changes\r\n     * (e.g. when a new scene is loaded in an editor preview).\r\n     * If the graph is currently running, it will be stopped first and must be\r\n     * restarted manually after calling this method.\r\n     * @param scene the new scene to attach to\r\n     */\r\n    public setScene(scene: Scene): void {\r\n        if (scene === this._scene) {\r\n            return;\r\n        }\r\n        if (this.state === FlowGraphState.Started) {\r\n            this.stop();\r\n        }\r\n        // Tear down old event coordinator\r\n        this._detachEventObserver();\r\n        this._sceneEventCoordinator.dispose();\r\n        // Clear execution contexts so start() creates fresh ones with the new scene.\r\n        // NOTE: This intentionally discards user variables and connection values.\r\n        // Callers that need to preserve them (e.g. the Flow Graph Editor) should\r\n        // snapshot context state BEFORE calling setScene() and restore it in a\r\n        // wrapped createContext() callback after start() re-creates contexts.\r\n        this._executionContexts.length = 0;\r\n        // Rebuild with the new scene\r\n        (this as { _scene: Scene })._scene = scene;\r\n        this._scene.constantlyUpdateMeshUnderPointer = true; // ensure pointer info is always up to date for event blocks that need it\r\n        // Re-resolve node references (e.g. meshes targeted by Get/Set property blocks) against the\r\n        // new scene. This is required when the graph was parsed before its scene was populated (for\r\n        // example an editor that loads a graph from a snippet first and the referenced scene second):\r\n        // the references would otherwise stay bound to nodes from the old/disposed scene.\r\n        for (const block of this._allBlocks) {\r\n            for (const input of block.dataInputs) {\r\n                input._reresolveDefaultValueForScene(scene);\r\n            }\r\n        }\r\n        this._sceneEventCoordinator = new FlowGraphSceneEventCoordinator(this._scene);\r\n        // Pre-attach the event observer so that events from the new\r\n        // coordinator are routed to the graph immediately.  The handler\r\n        // guards against processing events while the graph is stopped,\r\n        // but having the observer in place ensures no events are lost\r\n        // when start() is called shortly after.\r\n        this._attachEventObserver();\r\n    }\r\n\r\n    /**\r\n     * Create a context. A context represents one self contained execution for the graph, with its own variables.\r\n     * @returns the context, where you can get and set variables\r\n     */\r\n    public createContext() {\r\n        const context = new FlowGraphContext({ scene: this._scene, coordinator: this._coordinator, sceneEventCoordinator: this._sceneEventCoordinator });\r\n        this._executionContexts.push(context);\r\n        return context;\r\n    }\r\n\r\n    /**\r\n     * Returns the execution context at a given index\r\n     * @param index the index of the context\r\n     * @returns the execution context at that index\r\n     */\r\n    public getContext(index: number) {\r\n        return this._executionContexts[index];\r\n    }\r\n\r\n    /**\r\n     * Returns the number of execution contexts currently attached to this graph.\r\n     */\r\n    public get contextCount(): number {\r\n        return this._executionContexts.length;\r\n    }\r\n\r\n    /**\r\n     * Remove an execution context by index. Any pending async blocks on\r\n     * the context are cleared before removal.\r\n     * @param index the index of the context to remove\r\n     * @returns the removed context, or undefined if the index was out of range\r\n     */\r\n    public removeContext(index: number): FlowGraphContext | undefined {\r\n        if (index < 0 || index >= this._executionContexts.length) {\r\n            return undefined;\r\n        }\r\n        const [removed] = this._executionContexts.splice(index, 1);\r\n        removed._clearPendingBlocks();\r\n        return removed;\r\n    }\r\n\r\n    /**\r\n     * Returns all blocks registered in this graph, including disconnected ones.\r\n     * @returns a read-only array of all blocks\r\n     */\r\n    public getAllBlocks(): readonly FlowGraphBlock[] {\r\n        return this._allBlocks;\r\n    }\r\n\r\n    /**\r\n     * Register a block with the graph. This does not wire any connections;\r\n     * it simply ensures the block is tracked so that serialization, editor\r\n     * display, and validation see it even when it is not reachable from an\r\n     * event block.\r\n     * @param block the block to register\r\n     */\r\n    public addBlock(block: FlowGraphBlock): void {\r\n        if (this._allBlocks.indexOf(block) === -1) {\r\n            this._allBlocks.push(block);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a block from the graph. Disconnects all of its ports and, if it\r\n     * is an event block, unregisters it from the event-block lists.\r\n     * @param block the block to remove\r\n     */\r\n    public removeBlock(block: FlowGraphBlock): void {\r\n        const idx = this._allBlocks.indexOf(block);\r\n        if (idx !== -1) {\r\n            this._allBlocks.splice(idx, 1);\r\n        }\r\n        // If it is an event block, remove from the event-block registry\r\n        if (block instanceof FlowGraphExecutionBlock && \"type\" in block) {\r\n            const eventBlock = block as unknown as FlowGraphEventBlock;\r\n            const list = this._eventBlocks[eventBlock.type];\r\n            if (list) {\r\n                const eIdx = list.indexOf(eventBlock);\r\n                if (eIdx !== -1) {\r\n                    list.splice(eIdx, 1);\r\n                }\r\n            }\r\n        }\r\n        // If the block has pending async tasks (e.g. event subscriptions),\r\n        // cancel them in all active execution contexts so deletion takes\r\n        // effect immediately even while the graph is running.\r\n        if (block instanceof FlowGraphAsyncExecutionBlock) {\r\n            for (const context of this._executionContexts) {\r\n                block._cancelPendingTasks(context);\r\n                block._resetAfterCanceled(context);\r\n            }\r\n        }\r\n        // Disconnect all ports\r\n        for (const input of block.dataInputs) {\r\n            input.disconnectFromAll();\r\n        }\r\n        for (const output of block.dataOutputs) {\r\n            output.disconnectFromAll();\r\n        }\r\n        if (block instanceof FlowGraphExecutionBlock) {\r\n            for (const signalIn of block.signalInputs) {\r\n                signalIn.disconnectFromAll();\r\n            }\r\n            for (const signalOut of block.signalOutputs) {\r\n                signalOut.disconnectFromAll();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add an event block. When the graph is started, it will start listening to events\r\n     * from the block and execute the graph when they are triggered.\r\n     * @param block the event block to be added\r\n     */\r\n    public addEventBlock(block: FlowGraphEventBlock): void {\r\n        this.addBlock(block);\r\n        if (block.type === FlowGraphEventType.PointerOver || block.type === FlowGraphEventType.PointerOut) {\r\n            this._scene.constantlyUpdateMeshUnderPointer = true;\r\n        }\r\n\r\n        this._eventBlocks[block.type].push(block);\r\n\r\n        // if already started, sort and add to the pending\r\n        if (this.state === FlowGraphState.Started) {\r\n            for (const context of this._executionContexts) {\r\n                block._startPendingTasks(context);\r\n            }\r\n        } else {\r\n            this.onStateChangedObservable.addOnce((state) => {\r\n                if (state === FlowGraphState.Started) {\r\n                    for (const context of this._executionContexts) {\r\n                        block._startPendingTasks(context);\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stops the flow graph. Cancels all pending tasks and clears execution contexts,\r\n     * but keeps event blocks so the graph can be restarted.\r\n     */\r\n    public stop() {\r\n        if (this.state === FlowGraphState.Stopped) {\r\n            return;\r\n        }\r\n        this._detachEventObserver();\r\n        this.state = FlowGraphState.Stopped;\r\n        for (const context of this._executionContexts) {\r\n            context._clearPendingBlocks();\r\n            context._clearPendingActivation();\r\n        }\r\n        this._executionContexts.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Pauses the flow graph. Cancels pending tasks but keeps execution contexts and event blocks.\r\n     * Call start() to resume.\r\n     */\r\n    public pause() {\r\n        if (this.state !== FlowGraphState.Started) {\r\n            return;\r\n        }\r\n        this._detachEventObserver();\r\n        this.state = FlowGraphState.Paused;\r\n        for (const context of this._executionContexts) {\r\n            context._clearPendingBlocks();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Starts the flow graph. Initializes the event blocks and starts listening to events.\r\n     * Can also be called to resume from a paused state.\r\n     */\r\n    public start() {\r\n        if (this.state === FlowGraphState.Started) {\r\n            return;\r\n        }\r\n        const resumingFromPause = this.state === FlowGraphState.Paused;\r\n        if (this._executionContexts.length === 0) {\r\n            this.createContext();\r\n        }\r\n        this._attachEventObserver();\r\n        this.state = FlowGraphState.Started;\r\n        this._startPendingEvents();\r\n        // On a fresh start (not resume), fire the SceneReady event.\r\n        // The coordinator's own scene-ready observer may have already\r\n        // fired (and been lost) while the graph was stopped, so reset\r\n        // the flag and handle the ready state ourselves.\r\n        if (!resumingFromPause) {\r\n            this._sceneEventCoordinator.sceneReadyTriggered = false;\r\n            if (this._scene.isReady(true)) {\r\n                this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n                this._sceneEventCoordinator.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\r\n            } else {\r\n                // Scene isn't ready yet (e.g. pending shader compilations after\r\n                // a scene swap).  Use executeWhenReady(true) which restarts the\r\n                // readiness check loop — a plain addOnce on onReadyObservable\r\n                // may never fire if the check loop already completed.\r\n                this._scene.executeWhenReady(() => {\r\n                    if (this.state === FlowGraphState.Started && !this._sceneEventCoordinator.sceneReadyTriggered) {\r\n                        this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n                        this._sceneEventCoordinator.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\r\n                    }\r\n                }, true);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _startPendingEvents() {\r\n        for (const context of this._executionContexts) {\r\n            for (const type in this._eventBlocks) {\r\n                const order = this._getContextualOrder(type as FlowGraphEventType, context);\r\n                for (const block of order) {\r\n                    block._startPendingTasks(context);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getContextualOrder(type: FlowGraphEventType, context: FlowGraphContext): FlowGraphEventBlock[] {\r\n        const order = this._eventBlocks[type].sort((a, b) => b.initPriority - a.initPriority);\r\n\r\n        if (type === FlowGraphEventType.MeshPick || type === FlowGraphEventType.PointerOver || type === FlowGraphEventType.PointerOut) {\r\n            const meshPickOrder = [] as FlowGraphEventBlock[];\r\n            for (const block1 of order) {\r\n                const mesh1 =\r\n                    type === FlowGraphEventType.MeshPick\r\n                        ? (block1 as FlowGraphMeshPickEventBlock).asset.getValue(context)\r\n                        : (\r\n                              block1 as FlowGraphEventBlock & {\r\n                                  _getReferencedMesh: (context: FlowGraphContext) => AbstractMesh;\r\n                              }\r\n                          )._getReferencedMesh(context);\r\n                let i = 0;\r\n                for (; i < order.length; i++) {\r\n                    const block2 = order[i];\r\n                    const mesh2 =\r\n                        type === FlowGraphEventType.MeshPick\r\n                            ? (block2 as FlowGraphMeshPickEventBlock).asset.getValue(context)\r\n                            : (\r\n                                  block2 as FlowGraphEventBlock & {\r\n                                      _getReferencedMesh: (context: FlowGraphContext) => AbstractMesh;\r\n                                  }\r\n                              )._getReferencedMesh(context);\r\n                    if (mesh1 && mesh2 && _IsDescendantOf(mesh1, mesh2)) {\r\n                        break;\r\n                    }\r\n                }\r\n                meshPickOrder.splice(i, 0, block1);\r\n            }\r\n            return meshPickOrder;\r\n        }\r\n        return order;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the flow graph. Cancels any pending tasks and removes all event listeners.\r\n     */\r\n    public dispose() {\r\n        // Always release the scene-event wiring, even for a stopped or never-started graph.\r\n        // The scene event coordinator attaches per-frame, pointer and keyboard observers to the\r\n        // scene in its constructor, so a graph that is removed from its coordinator (or disposed)\r\n        // while stopped would otherwise leak those observers and keep incurring per-frame overhead.\r\n        this._detachEventObserver();\r\n        this._sceneEventCoordinator.dispose();\r\n        if (this.state === FlowGraphState.Stopped) {\r\n            // Nothing is executing, so there is no run state to clear. Authored blocks are left\r\n            // intact on purpose: the editor re-points a stopped graph across preview scenes via\r\n            // setScene(), and each preview scene disposal raises a SceneDispose event that calls\r\n            // dispose() here. Wiping the blocks would destroy the user's graph on every reset.\r\n            return;\r\n        }\r\n        this.state = FlowGraphState.Stopped;\r\n        for (const context of this._executionContexts) {\r\n            context._clearPendingBlocks();\r\n            context._clearPendingActivation();\r\n        }\r\n        this._executionContexts.length = 0;\r\n        for (const type in this._eventBlocks) {\r\n            this._eventBlocks[type as FlowGraphEventType].length = 0;\r\n        }\r\n        this._allBlocks.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Executes a function in all blocks of a flow graph, starting with the event blocks.\r\n     * @param visitor the function to execute.\r\n     */\r\n    public visitAllBlocks(visitor: (block: FlowGraphBlock) => void) {\r\n        const visitList: FlowGraphBlock[] = [];\r\n        const idsAddedToVisitList = new Set<string>();\r\n        for (const type in this._eventBlocks) {\r\n            for (const block of this._eventBlocks[type as FlowGraphEventType]) {\r\n                visitList.push(block);\r\n                idsAddedToVisitList.add(block.uniqueId);\r\n            }\r\n        }\r\n\r\n        while (visitList.length > 0) {\r\n            const block = visitList.pop()!;\r\n            visitor(block);\r\n\r\n            for (const dataIn of block.dataInputs) {\r\n                for (const connection of dataIn._connectedPoint) {\r\n                    if (!idsAddedToVisitList.has(connection._ownerBlock.uniqueId)) {\r\n                        visitList.push(connection._ownerBlock);\r\n                        idsAddedToVisitList.add(connection._ownerBlock.uniqueId);\r\n                    }\r\n                }\r\n            }\r\n            if (block instanceof FlowGraphExecutionBlock) {\r\n                for (const signalOut of block.signalOutputs) {\r\n                    for (const connection of signalOut._connectedPoint) {\r\n                        if (!idsAddedToVisitList.has(connection._ownerBlock.uniqueId)) {\r\n                            visitList.push(connection._ownerBlock);\r\n                            idsAddedToVisitList.add(connection._ownerBlock.uniqueId);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Validates the flow graph and returns all issues found.\r\n     * Uses the tracked block list for complete validation including unreachable block detection.\r\n     * @returns The validation result containing errors and warnings.\r\n     */\r\n    public validate(): IFlowGraphValidationResult {\r\n        return ValidateFlowGraphWithBlockList(this, this._allBlocks);\r\n    }\r\n\r\n    /**\r\n     * Serializes a graph\r\n     * @param serializationObject the object to write the values in\r\n     * @param valueSerializeFunction a function to serialize complex values\r\n     */\r\n    public serialize(serializationObject: any = {}, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void) {\r\n        serializationObject.name = this.name;\r\n        serializationObject.uniqueId = this.uniqueId;\r\n        if (this.metadata !== undefined) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n        serializationObject.allBlocks = [];\r\n        // Collect all blocks: traversal-reachable ones plus any registered\r\n        // orphans in _allBlocks (e.g. disconnected blocks in the editor).\r\n        const seen = new Set<string>();\r\n        const serializeBlock = (block: FlowGraphBlock) => {\r\n            if (seen.has(block.uniqueId)) {\r\n                return;\r\n            }\r\n            seen.add(block.uniqueId);\r\n            const serializedBlock: any = {};\r\n            block.serialize(serializedBlock);\r\n            serializationObject.allBlocks.push(serializedBlock);\r\n        };\r\n        this.visitAllBlocks(serializeBlock);\r\n        for (const block of this._allBlocks) {\r\n            serializeBlock(block);\r\n        }\r\n        serializationObject.executionContexts = [];\r\n        for (const context of this._executionContexts) {\r\n            const serializedContext: any = {};\r\n            context.serialize(serializedContext, valueSerializeFunction);\r\n            serializationObject.executionContexts.push(serializedContext);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Launches the flow graph editor for this graph.\r\n     * The editor is lazy-loaded from {@link FlowGraph.EditorURL} the first time it is used.\r\n     * @param config defines the configuration of the editor\r\n     * @returns a promise fulfilled when the editor is visible\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async edit(config?: IFlowGraphEditorLaunchOptions): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            this._BJSFLOWGRAPHEDITOR = this._BJSFLOWGRAPHEDITOR || this._getGlobalFlowGraphEditor();\r\n            if (typeof this._BJSFLOWGRAPHEDITOR === \"undefined\") {\r\n                const editorUrl = config && config.editorURL ? config.editorURL : FlowGraph.EditorURL;\r\n\r\n                // Load the editor bundle and add it to the DOM.\r\n                Tools.LoadBabylonScript(editorUrl, () => {\r\n                    this._BJSFLOWGRAPHEDITOR = this._BJSFLOWGRAPHEDITOR || this._getGlobalFlowGraphEditor();\r\n                    this._createFlowGraphEditor(config?.flowGraphEditorConfig);\r\n                    resolve();\r\n                });\r\n            } else {\r\n                this._createFlowGraphEditor(config?.flowGraphEditorConfig);\r\n                resolve();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates the flow graph editor window.\r\n     * @param additionalConfig additional configuration forwarded to `FlowGraphEditor.Show()`\r\n     */\r\n    private _createFlowGraphEditor(additionalConfig?: any) {\r\n        const editorConfig: any = {\r\n            flowGraph: this,\r\n            hostScene: this._scene,\r\n            // edit() always targets the developer's own live graph and scene, so the editor should\r\n            // attach to that scene instead of spinning up a throwaway preview scene. A caller can\r\n            // still override this via additionalConfig.\r\n            attachToLiveScene: true,\r\n            ...additionalConfig,\r\n        };\r\n        this._BJSFLOWGRAPHEDITOR.FlowGraphEditor.Show(editorConfig);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4, Matrix, Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { FlowGraphInteger } from \"./CustomTypes/flowGraphInteger.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FlowGraphMatrix2D, FlowGraphMatrix3D } from \"./CustomTypes/flowGraphMatrix\";\r\n\r\n/**\r\n * The types supported by the flow graph.\r\n */\r\nexport const enum FlowGraphTypes {\r\n    Any = \"any\",\r\n    String = \"string\",\r\n    Number = \"number\",\r\n    Boolean = \"boolean\",\r\n    Object = \"object\",\r\n    Integer = \"FlowGraphInteger\",\r\n    Vector2 = \"Vector2\",\r\n    Vector3 = \"Vector3\",\r\n    Vector4 = \"Vector4\",\r\n    Quaternion = \"Quaternion\",\r\n    Matrix = \"Matrix\",\r\n    Matrix2D = \"Matrix2D\",\r\n    Matrix3D = \"Matrix3D\",\r\n    Color3 = \"Color3\",\r\n    Color4 = \"Color4\",\r\n}\r\n\r\n/**\r\n * A rich type represents extra information about a type,\r\n * such as its name and a default value constructor.\r\n */\r\nexport class RichType<T> {\r\n    /**\r\n     * A function that can be used to transform a value of any type into a value of this rich type.\r\n     * This can be used, for example, between vector4 and quaternion.\r\n     */\r\n    public typeTransformer: (value: any) => T;\r\n\r\n    constructor(\r\n        /**\r\n         * The name given to the type.\r\n         */\r\n        public typeName: string,\r\n        /**\r\n         * The default value of the type.\r\n         */\r\n        public defaultValue: T,\r\n\r\n        /**\r\n         * [-1] The ANIMATIONTYPE of the type, if available\r\n         */\r\n        public animationType: number = -1\r\n    ) {}\r\n\r\n    /**\r\n     * Serializes this rich type into a serialization object.\r\n     * @param serializationObject the object to serialize to\r\n     */\r\n    serialize(serializationObject: any) {\r\n        serializationObject.typeName = this.typeName;\r\n        serializationObject.defaultValue = this.defaultValue;\r\n    }\r\n}\r\n\r\nexport const RichTypeAny: RichType<any> = new RichType(FlowGraphTypes.Any, undefined);\r\n\r\nexport const RichTypeString: RichType<string> = new RichType(FlowGraphTypes.String, \"\");\r\n\r\nexport const RichTypeNumber: RichType<number> = new RichType(FlowGraphTypes.Number, 0, Constants.ANIMATIONTYPE_FLOAT);\r\n\r\nexport const RichTypeBoolean: RichType<boolean> = new RichType(FlowGraphTypes.Boolean, false);\r\n\r\nexport const RichTypeVector2: RichType<Vector2> = new RichType(FlowGraphTypes.Vector2, Vector2.Zero(), Constants.ANIMATIONTYPE_VECTOR2);\r\n\r\nexport const RichTypeVector3: RichType<Vector3> = new RichType(FlowGraphTypes.Vector3, Vector3.Zero(), Constants.ANIMATIONTYPE_VECTOR3);\r\n\r\nexport const RichTypeVector4: RichType<Vector4> = new RichType(FlowGraphTypes.Vector4, Vector4.Zero());\r\n\r\nexport const RichTypeMatrix: RichType<Matrix> = new RichType(FlowGraphTypes.Matrix, Matrix.Identity(), Constants.ANIMATIONTYPE_MATRIX);\r\n\r\nexport const RichTypeMatrix2D: RichType<FlowGraphMatrix2D> = new RichType(FlowGraphTypes.Matrix2D, new FlowGraphMatrix2D());\r\n\r\nexport const RichTypeMatrix3D: RichType<FlowGraphMatrix3D> = new RichType(FlowGraphTypes.Matrix3D, new FlowGraphMatrix3D());\r\n\r\nexport const RichTypeColor3: RichType<Color3> = new RichType(FlowGraphTypes.Color3, Color3.Black(), Constants.ANIMATIONTYPE_COLOR3);\r\n\r\nexport const RichTypeColor4: RichType<Color4> = new RichType(FlowGraphTypes.Color4, new Color4(0, 0, 0, 0), Constants.ANIMATIONTYPE_COLOR4);\r\n\r\nexport const RichTypeQuaternion: RichType<Quaternion> = new RichType(FlowGraphTypes.Quaternion, Quaternion.Identity(), Constants.ANIMATIONTYPE_QUATERNION);\r\nexport const RichTypeFlowGraphInteger: RichType<FlowGraphInteger> = new RichType(FlowGraphTypes.Integer, new FlowGraphInteger(0), Constants.ANIMATIONTYPE_FLOAT);\r\n\r\n/**\r\n * Given a value, try to deduce its rich type.\r\n * @param value the value to deduce the rich type from\r\n * @returns the value's rich type, or RichTypeAny if the type could not be deduced.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getRichTypeFromValue<T>(value: T): RichType<T> {\r\n    const anyValue = value as any;\r\n    switch (typeof value) {\r\n        case FlowGraphTypes.String:\r\n            return RichTypeString as RichType<T>;\r\n        case FlowGraphTypes.Number:\r\n            return RichTypeNumber as RichType<T>;\r\n        case FlowGraphTypes.Boolean:\r\n            return RichTypeBoolean as RichType<T>;\r\n        case FlowGraphTypes.Object:\r\n            if (anyValue.getClassName) {\r\n                switch (anyValue.getClassName() as string) {\r\n                    case FlowGraphTypes.Vector2:\r\n                        return RichTypeVector2 as RichType<T>;\r\n                    case FlowGraphTypes.Vector3:\r\n                        return RichTypeVector3 as RichType<T>;\r\n                    case FlowGraphTypes.Vector4:\r\n                        return RichTypeVector4 as RichType<T>;\r\n                    case FlowGraphTypes.Matrix:\r\n                        return RichTypeMatrix as RichType<T>;\r\n                    case FlowGraphTypes.Color3:\r\n                        return RichTypeColor3 as RichType<T>;\r\n                    case FlowGraphTypes.Color4:\r\n                        return RichTypeColor4 as RichType<T>;\r\n                    case FlowGraphTypes.Quaternion:\r\n                        return RichTypeQuaternion as RichType<T>;\r\n                    case FlowGraphTypes.Integer:\r\n                        return RichTypeFlowGraphInteger as RichType<T>;\r\n                    case FlowGraphTypes.Matrix2D:\r\n                        return RichTypeMatrix2D as RichType<T>;\r\n                    case FlowGraphTypes.Matrix3D:\r\n                        return RichTypeMatrix3D as RichType<T>;\r\n                }\r\n            }\r\n            return RichTypeAny as RichType<T>;\r\n        default:\r\n            return RichTypeAny as RichType<T>;\r\n    }\r\n}\r\n\r\n/**\r\n * Given a flow graph type, return the rich type that corresponds to it.\r\n * @param flowGraphType the flow graph type\r\n * @returns the rich type that corresponds to the flow graph type\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getRichTypeByFlowGraphType(flowGraphType?: string): RichType<any> {\r\n    switch (flowGraphType) {\r\n        case FlowGraphTypes.String:\r\n            return RichTypeString;\r\n        case FlowGraphTypes.Number:\r\n            return RichTypeNumber;\r\n        case FlowGraphTypes.Boolean:\r\n            return RichTypeBoolean;\r\n        case FlowGraphTypes.Vector2:\r\n            return RichTypeVector2;\r\n        case FlowGraphTypes.Vector3:\r\n            return RichTypeVector3;\r\n        case FlowGraphTypes.Vector4:\r\n            return RichTypeVector4;\r\n        case FlowGraphTypes.Matrix:\r\n            return RichTypeMatrix;\r\n        case FlowGraphTypes.Color3:\r\n            return RichTypeColor3;\r\n        case FlowGraphTypes.Color4:\r\n            return RichTypeColor4;\r\n        case FlowGraphTypes.Quaternion:\r\n            return RichTypeQuaternion;\r\n        case FlowGraphTypes.Integer:\r\n            return RichTypeFlowGraphInteger;\r\n        case FlowGraphTypes.Matrix2D:\r\n            return RichTypeMatrix2D;\r\n        case FlowGraphTypes.Matrix3D:\r\n            return RichTypeMatrix3D;\r\n        default:\r\n            return RichTypeAny;\r\n    }\r\n}\r\n\r\n/**\r\n * get the animation type for a given flow graph type\r\n * @param flowGraphType the flow graph type\r\n * @returns the animation type for this flow graph type\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getAnimationTypeByFlowGraphType(flowGraphType: FlowGraphTypes): number {\r\n    switch (flowGraphType) {\r\n        case FlowGraphTypes.Number:\r\n            return Constants.ANIMATIONTYPE_FLOAT;\r\n        case FlowGraphTypes.Vector2:\r\n            return Constants.ANIMATIONTYPE_VECTOR2;\r\n        case FlowGraphTypes.Vector3:\r\n            return Constants.ANIMATIONTYPE_VECTOR3;\r\n        case FlowGraphTypes.Matrix:\r\n            return Constants.ANIMATIONTYPE_MATRIX;\r\n        case FlowGraphTypes.Color3:\r\n            return Constants.ANIMATIONTYPE_COLOR3;\r\n        case FlowGraphTypes.Color4:\r\n            return Constants.ANIMATIONTYPE_COLOR4;\r\n        case FlowGraphTypes.Quaternion:\r\n            return Constants.ANIMATIONTYPE_QUATERNION;\r\n        default:\r\n            return Constants.ANIMATIONTYPE_FLOAT;\r\n    }\r\n}\r\n\r\n/**\r\n * Given an animation type, return the rich type that corresponds to it.\r\n * @param animationType the animation type\r\n * @returns the rich type that corresponds to the animation type\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function getRichTypeByAnimationType(animationType: number): RichType<any> {\r\n    switch (animationType) {\r\n        case Constants.ANIMATIONTYPE_FLOAT:\r\n            return RichTypeNumber;\r\n        case Constants.ANIMATIONTYPE_VECTOR2:\r\n            return RichTypeVector2;\r\n        case Constants.ANIMATIONTYPE_VECTOR3:\r\n            return RichTypeVector3;\r\n        case Constants.ANIMATIONTYPE_MATRIX:\r\n            return RichTypeMatrix;\r\n        case Constants.ANIMATIONTYPE_COLOR3:\r\n            return RichTypeColor3;\r\n        case Constants.ANIMATIONTYPE_COLOR4:\r\n            return RichTypeColor4;\r\n        case Constants.ANIMATIONTYPE_QUATERNION:\r\n            return RichTypeQuaternion;\r\n        default:\r\n            return RichTypeAny;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphRichTypes.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphRichTypes(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RichTypeQuaternion.typeTransformer = (value: any) => {\r\n        if (value.getClassName) {\r\n            if (value.getClassName() === FlowGraphTypes.Vector4) {\r\n                return Quaternion.FromArray(value.asArray());\r\n            } else if (value.getClassName() === FlowGraphTypes.Vector3) {\r\n                return Quaternion.FromEulerVector(value);\r\n            } else if (value.getClassName() === FlowGraphTypes.Matrix) {\r\n                return Quaternion.FromRotationMatrix(value);\r\n            }\r\n        }\r\n        return value;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Prefix used by the default event-reference format.\r\n *\r\n * A host that maps behavior graphs onto its own object model (for example the glTF\r\n * `KHR_interactivity` loader) supplies its own format through {@link IFlowGraphHostResolver}.\r\n */\r\nexport const FlowGraphDefaultEventReferencePrefix = \"flowgraph://events/\";\r\n\r\n/**\r\n * Builds the default reference for an event source key.\r\n * @param key the event source key (e.g. `\"sceneReady\"`, `\"sceneTick\"`, or a custom event id)\r\n * @returns the event reference\r\n */\r\nexport function GetDefaultEventReference(key: string): string {\r\n    return FlowGraphDefaultEventReferencePrefix + key;\r\n}\r\n\r\n/**\r\n * Extracts the event source key from a default-format event reference.\r\n * @param reference the value to decode\r\n * @returns the event source key, or `undefined` when the value is not an event reference\r\n */\r\nexport function GetDefaultEventReferenceKey(reference: string): string | undefined {\r\n    return reference.startsWith(FlowGraphDefaultEventReferencePrefix) ? reference.substring(FlowGraphDefaultEventReferencePrefix.length) : undefined;\r\n}\r\n\r\n/**\r\n * Lets the environment hosting a flow graph decide how runtime entities are represented as opaque\r\n * reference values, so the graph engine itself stays agnostic of the host's object model.\r\n *\r\n * A host (e.g. a glTF loader extension) provides an implementation through\r\n * {@link IFlowGraphCoordinatorConfiguration.hostResolver}. Every member is optional; the engine\r\n * falls back to a neutral built-in representation for anything the host does not provide.\r\n */\r\nexport interface IFlowGraphHostResolver {\r\n    /**\r\n     * Encodes an event source key as the opaque reference exposed by event blocks on their\r\n     * `event` output.\r\n     *\r\n     * References must be stable: two calls with the same key must produce equal values so that\r\n     * equality comparisons of two `event` outputs of the same source succeed.\r\n     * @param key the event source key\r\n     * @returns the reference representing the event source\r\n     */\r\n    encodeEventReference?(key: string): string;\r\n\r\n    /**\r\n     * Decodes an event reference produced by {@link IFlowGraphHostResolver.encodeEventReference}\r\n     * back into its event source key. Must return `undefined` for values that are not event\r\n     * references.\r\n     * @param reference the reference to decode\r\n     * @returns the event source key, or `undefined` when the value is not an event reference\r\n     */\r\n    decodeEventReference?(reference: string): string | undefined;\r\n\r\n    /**\r\n     * Decodes the array index denoted by a reference, for cases where a reference addresses an\r\n     * element of one of the host's collections. Must return `undefined` for values the host does\r\n     * not recognise as an indexed reference.\r\n     * @param reference the reference to decode\r\n     * @param collection optional host collection the decoded reference must address\r\n     * @returns the index the reference denotes, or `undefined` when it does not denote one\r\n     */\r\n    decodeIndexReference?(reference: string, collection?: string): number | undefined;\r\n\r\n    /**\r\n     * Maps a runtime object to the reference the host addresses it by, for example the JSON\r\n     * Pointer of the resource a loaded object originates from.\r\n     *\r\n     * Used when an object value is supplied to a templated path input. Returning `undefined`\r\n     * means the host cannot address the object, and the value is rejected.\r\n     * @param object the runtime object to address\r\n     * @param hint optional disambiguation hint, taken from the path segment preceding the template\r\n     * parameter being resolved. A single object may be addressable in several ways, and the hint\r\n     * tells the host which kind of reference the graph is asking for.\r\n     * @returns the reference for the object, or `undefined` when it cannot be addressed\r\n     */\r\n    getObjectReference?(object: object, hint?: string): string | undefined;\r\n}\r\n","import { type EventState, type IReadonlyObservable, type Observer, Observable } from \"core/Misc/observable\";\r\nimport { type Scene } from \"../scene\";\r\nimport { FlowGraph } from \"./flowGraph\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type IFlowGraphHostResolver, GetDefaultEventReferenceKey, GetDefaultEventReference } from \"./flowGraphHostResolver\";\r\n\r\n/**\r\n * Parameters used to create a flow graph engine.\r\n */\r\nexport interface IFlowGraphCoordinatorConfiguration {\r\n    /**\r\n     * The scene that the flow graph engine belongs to.\r\n     */\r\n    scene: Scene;\r\n    /**\r\n     * Optional resolver letting the environment hosting the graphs decide how runtime entities are\r\n     * represented as opaque reference values. When omitted, a neutral built-in representation is used.\r\n     */\r\n    hostResolver?: IFlowGraphHostResolver;\r\n}\r\n\r\n/**\r\n * Parameters used to parse a flow graph coordinator.\r\n */\r\nexport interface IFlowGraphCoordinatorParseOptions {\r\n    /**\r\n     * A function that will be called to parse the value of a property.\r\n     * @param key the key of the property\r\n     * @param serializationObject the serialization object where the property is located\r\n     * @param assetsContainer the assets container\r\n     * @param scene the scene that the block is being parsed in\r\n     */\r\n    valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n    /**\r\n     * The path converter to use to convert the path to an object accessor.\r\n     */\r\n    pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n    /**\r\n     * The scene that the flow graph coordinator belongs to.\r\n     */\r\n    scene: Scene;\r\n}\r\n/**\r\n * This class holds all of the existing flow graphs and is responsible for creating new ones.\r\n * It also handles starting/stopping multiple graphs and communication between them through an Event Coordinator\r\n * This is the entry point for the flow graph system.\r\n * @experimental This class is still in development and is subject to change.\r\n */\r\nexport class FlowGraphCoordinator {\r\n    /**\r\n     * The maximum number of events per type.\r\n     * This is used to limit the number of events that can be created in a single scene.\r\n     * This is to prevent infinite loops.\r\n     */\r\n    public static MaxEventsPerType: number = 30;\r\n\r\n    /**\r\n     * The maximum number of execution of a specific event in a single frame.\r\n     */\r\n    public static MaxEventTypeExecutionPerFrame: number = 30;\r\n    /**\r\n     * @internal\r\n     * A list of all the coordinators per scene. Will be used by the inspector\r\n     */\r\n    public static readonly SceneCoordinators: Map<Scene, FlowGraphCoordinator[]> = new Map();\r\n\r\n    /**\r\n     * Observable raised when a flow graph is added to any coordinator. Used by the inspector to keep\r\n     * the flow graph list in sync. The payload is the newly added flow graph.\r\n     */\r\n    public static get OnFlowGraphAddedObservable(): IReadonlyObservable<FlowGraph> {\r\n        return this._OnFlowGraphAddedObservable;\r\n    }\r\n    private static readonly _OnFlowGraphAddedObservable = new Observable<FlowGraph>();\r\n\r\n    /**\r\n     * Observable raised when a flow graph is removed from any coordinator. Used by the inspector to keep\r\n     * the flow graph list in sync. The payload is the removed flow graph.\r\n     */\r\n    public static get OnFlowGraphRemovedObservable(): IReadonlyObservable<FlowGraph> {\r\n        return this._OnFlowGraphRemovedObservable;\r\n    }\r\n    private static readonly _OnFlowGraphRemovedObservable = new Observable<FlowGraph>();\r\n\r\n    /**\r\n     * When set to true (default) custom events will be dispatched synchronously.\r\n     * This means that the events will be dispatched immediately when they are triggered.\r\n     */\r\n    public dispatchEventsSynchronously: boolean = true;\r\n\r\n    private readonly _flowGraphs: FlowGraph[] = [];\r\n\r\n    private _customEventsMap: Map<string, Observable<any>> = new Map();\r\n\r\n    private _eventExecutionCounter: Map<string, number> = new Map();\r\n\r\n    private _disposeObserver!: Observer<Scene>;\r\n    private _onBeforeRenderObserver!: Observer<Scene>;\r\n    private _executeOnNextFrame: { id: string; data?: any; uniqueId: number }[] = [];\r\n    private _eventUniqueId: number = 0;\r\n\r\n    /**\r\n     * Stack of custom-event dispatches currently in progress. Each entry pairs the\r\n     * dispatched event id with the Observable's EventState so that\r\n     * `event/stopPropagation` can stop the remaining handlers of an in-flight\r\n     * dispatch. A stack (rather than a single value) tolerates re-entrant\r\n     * dispatching, e.g. an event handler synchronously sending another event.\r\n     * @internal\r\n     */\r\n    public _eventDispatchStack: { eventId: string; state: EventState; propagationStopped: boolean }[] = [];\r\n\r\n    public constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public config: IFlowGraphCoordinatorConfiguration\r\n    ) {\r\n        this._attachToScene(this.config.scene);\r\n    }\r\n\r\n    private _attachToScene(scene: Scene): void {\r\n        // When the scene is disposed, dispose all graphs currently running on it.\r\n        this._disposeObserver = scene.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n\r\n        this._onBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {\r\n            // Reset the event execution counter at the beginning of each frame.\r\n            this._eventExecutionCounter.clear();\r\n            // duplicate the _executeOnNextFrame array to avoid modifying it while iterating over it\r\n            const executeOnNextFrame = this._executeOnNextFrame.slice(0);\r\n            if (executeOnNextFrame.length) {\r\n                // Execute the events that were triggered on the next frame.\r\n                for (const event of executeOnNextFrame) {\r\n                    this.notifyCustomEvent(event.id, event.data, false);\r\n                    // remove the event from the array\r\n                    const index = this._executeOnNextFrame.findIndex((e) => e.uniqueId === event.uniqueId);\r\n                    if (index !== -1) {\r\n                        this._executeOnNextFrame.splice(index, 1);\r\n                    }\r\n                }\r\n            }\r\n        });\r\n\r\n        // Add itself to the SceneCoordinators list for the Inspector.\r\n        let coordinators = FlowGraphCoordinator.SceneCoordinators.get(scene);\r\n        if (!coordinators) {\r\n            coordinators = [];\r\n            FlowGraphCoordinator.SceneCoordinators.set(scene, coordinators);\r\n        }\r\n        coordinators.push(this);\r\n    }\r\n\r\n    private _detachFromScene(scene: Scene): void {\r\n        this._disposeObserver.remove();\r\n        this._onBeforeRenderObserver.remove();\r\n        const coordinators = FlowGraphCoordinator.SceneCoordinators.get(scene);\r\n        if (!coordinators) {\r\n            return;\r\n        }\r\n        const index = coordinators.indexOf(this);\r\n        if (index !== -1) {\r\n            coordinators.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reattaches this coordinator's lifecycle observers to another scene.\r\n     * @param scene new scene owned by the coordinator\r\n     * @param updateGraphs whether existing graphs should also be reattached\r\n     * @internal\r\n     */\r\n    public _setScene(scene: Scene, updateGraphs = true): void {\r\n        const previousScene = this.config.scene;\r\n        if (scene === previousScene) {\r\n            return;\r\n        }\r\n        this._detachFromScene(previousScene);\r\n        this.config.scene = scene;\r\n        if (updateGraphs) {\r\n            for (const graph of this._flowGraphs) {\r\n                graph.setScene(scene);\r\n            }\r\n        }\r\n        this._attachToScene(scene);\r\n    }\r\n\r\n    /**\r\n     * Creates a new flow graph and adds it to the list of existing flow graphs\r\n     * @param name - optional name for the new graph. If not provided, an auto-generated name is used.\r\n     * @returns a new flow graph\r\n     */\r\n    public createGraph(name?: string): FlowGraph {\r\n        const graphName = name ?? `Graph ${this._flowGraphs.length + 1}`;\r\n        const graph = new FlowGraph({ scene: this.config.scene, coordinator: this, name: graphName });\r\n        this._flowGraphs.push(graph);\r\n        FlowGraphCoordinator._OnFlowGraphAddedObservable.notifyObservers(graph);\r\n        return graph;\r\n    }\r\n\r\n    /**\r\n     * Removes a flow graph from the list of existing flow graphs and disposes it\r\n     * @param graph the graph to remove\r\n     */\r\n    public removeGraph(graph: FlowGraph) {\r\n        const index = this._flowGraphs.indexOf(graph);\r\n        if (index !== -1) {\r\n            graph.dispose();\r\n            this._flowGraphs.splice(index, 1);\r\n            FlowGraphCoordinator._OnFlowGraphRemovedObservable.notifyObservers(graph);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Starts all graphs\r\n     */\r\n    public start() {\r\n        for (const graph of this._flowGraphs) {\r\n            graph.start();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes all graphs\r\n     */\r\n    public dispose() {\r\n        for (const graph of this._flowGraphs) {\r\n            graph.dispose();\r\n            FlowGraphCoordinator._OnFlowGraphRemovedObservable.notifyObservers(graph);\r\n        }\r\n        this._flowGraphs.length = 0;\r\n        this._detachFromScene(this.config.scene);\r\n    }\r\n\r\n    /**\r\n     * Serializes this coordinator to a JSON object.\r\n     * @param serializationObject the object to serialize to\r\n     * @param valueSerializeFunction the function to use to serialize the value\r\n     */\r\n    public serialize(serializationObject: any, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void) {\r\n        serializationObject._flowGraphs = [];\r\n        for (const graph of this._flowGraphs) {\r\n            const serializedGraph = {};\r\n            graph.serialize(serializedGraph, valueSerializeFunction);\r\n            serializationObject._flowGraphs.push(serializedGraph);\r\n        }\r\n        serializationObject.dispatchEventsSynchronously = this.dispatchEventsSynchronously;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of flow graphs\r\n     */\r\n    public get flowGraphs() {\r\n        return this._flowGraphs;\r\n    }\r\n\r\n    /**\r\n     * Get an observable that will be notified when the event with the given id is fired.\r\n     * @param id the id of the event\r\n     * @returns the observable for the event\r\n     */\r\n    public getCustomEventObservable(id: string): Observable<any> {\r\n        let observable = this._customEventsMap.get(id);\r\n        if (!observable) {\r\n            // receive event is initialized before scene start, so no need to notify if triggered. but possible!\r\n            observable = new Observable<any>(/*undefined, true*/);\r\n            this._customEventsMap.set(id, observable);\r\n        }\r\n        return observable;\r\n    }\r\n\r\n    /**\r\n     * Notifies the observable for the given event id with the given data.\r\n     * @param id the id of the event\r\n     * @param data the data to send with the event\r\n     * @param async if true, the event will be dispatched asynchronously\r\n     */\r\n    public notifyCustomEvent(id: string, data: any, async: boolean = !this.dispatchEventsSynchronously) {\r\n        if (async) {\r\n            this._executeOnNextFrame.push({ id, data, uniqueId: this._eventUniqueId++ });\r\n            return;\r\n        }\r\n        // check if we are not exceeding the max number of events\r\n        if (this._eventExecutionCounter.has(id)) {\r\n            const count = this._eventExecutionCounter.get(id)!;\r\n            this._eventExecutionCounter.set(id, count + 1);\r\n            if (count >= FlowGraphCoordinator.MaxEventTypeExecutionPerFrame) {\r\n                if (count === FlowGraphCoordinator.MaxEventTypeExecutionPerFrame) {\r\n                    Logger.Warn(`FlowGraphCoordinator: Too many executions of event \"${id}\".`);\r\n                }\r\n                return;\r\n            }\r\n        } else {\r\n            this._eventExecutionCounter.set(id, 1);\r\n        }\r\n        const observable = this._customEventsMap.get(id);\r\n        if (observable) {\r\n            observable.notifyObservers(data);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Marks the beginning of a custom-event dispatch. Called by event receiver\r\n     * blocks from within their Observable callback so that the dispatch's\r\n     * EventState becomes reachable by `event/stopPropagation` while the receiver\r\n     * flow executes synchronously.\r\n     * @param eventId the id of the event being dispatched\r\n     * @param state the Observable EventState for this dispatch\r\n     */\r\n    public _beginEventDispatch(eventId: string, state: EventState): void {\r\n        this._eventDispatchStack.push({ eventId, state, propagationStopped: false });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Marks the end of the most recent custom-event dispatch started with\r\n     * {@link _beginEventDispatch}.\r\n     */\r\n    public _endEventDispatch(): { eventId: string; state: EventState; propagationStopped: boolean } | undefined {\r\n        return this._eventDispatchStack.pop();\r\n    }\r\n\r\n    /**\r\n     * Stops the propagation of an in-flight custom event, preventing any event\r\n     * handler nodes that have not been activated yet from running for the current\r\n     * dispatch.\r\n     *\r\n     * The `event` argument is the opaque event reference produced by an event block on its `event`\r\n     * output. If it does not reference an event that is currently being dispatched, this is a no-op.\r\n     *\r\n     * Babylon custom events have no scene-graph propagation layer, so there are\r\n     * no transitive activations to cancel when `stopImmediate` is false. When it\r\n     * is true, the remaining handlers in the Observable dispatch are skipped.\r\n     * @param event the event reference to stop propagation for\r\n     * @param stopImmediate whether to also stop remaining immediate handlers\r\n     */\r\n    public stopEventPropagation(event: string, stopImmediate: boolean): void {\r\n        if (typeof event !== \"string\") {\r\n            return;\r\n        }\r\n        const decode = this.config.hostResolver?.decodeEventReference ?? GetDefaultEventReferenceKey;\r\n        const eventId = decode(event);\r\n        if (eventId === undefined) {\r\n            return;\r\n        }\r\n        // Find the most recent matching in-flight dispatch and skip its remaining observers.\r\n        for (let i = this._eventDispatchStack.length - 1; i >= 0; i--) {\r\n            if (this._eventDispatchStack[i].eventId === eventId) {\r\n                this._eventDispatchStack[i].propagationStopped = true;\r\n                if (stopImmediate) {\r\n                    this._eventDispatchStack[i].state.skipNextObservers = true;\r\n                }\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Encodes an event source key as the opaque reference exposed on an event block's `event`\r\n     * output, delegating to the host resolver when one is configured.\r\n     * @param key the event source key\r\n     * @returns the event reference\r\n     */\r\n    public _getEventReference(key: string): string {\r\n        const encode = this.config.hostResolver?.encodeEventReference;\r\n        return encode ? encode(key) : GetDefaultEventReference(key);\r\n    }\r\n}\r\n","import { FlowGraphBlock } from \"../flowGraphBlock\";\nimport { FlowGraphBlockNames } from \"./flowGraphBlockNames\";\n\n/**\n * Any external module that wishes to add a new block to the flow graph can add to this object using the helper function.\n */\nconst CustomBlocks: Record<string, () => Promise<typeof FlowGraphBlock>> = {};\n/**\n * Reverse lookup: short block name → full \"module/blockName\" key, for O(1) fallback.\n */\nconst ShortNameToFullKey: Record<string, string> = {};\n\n/**\n * If you want to add a new block to the block factory, you should use this function.\n * Please be sure to choose a unique name and define the responsible module.\n * @param module the name of the module that is responsible for the block\n * @param blockName the name of the block. This should be unique.\n * @param factory an async factory function to generate the block\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function addToBlockFactory(module: string, blockName: string, factory: () => Promise<typeof FlowGraphBlock>): void {\n    const fullKey = `${module}/${blockName}`;\n    CustomBlocks[fullKey] = factory;\n    ShortNameToFullKey[blockName] = fullKey;\n}\n\nfunction _IsFlowGraphBlockConstructor(value: unknown): value is typeof FlowGraphBlock {\n    return typeof value === \"function\" && value.prototype instanceof FlowGraphBlock;\n}\n\nasync function _LoadBlock(modulePromise: Promise<object>, blockName: string): Promise<typeof FlowGraphBlock> {\n    const module = await modulePromise;\n    let block: typeof FlowGraphBlock | undefined;\n    let register: (() => void) | undefined;\n\n    for (const [exportName, value] of Object.entries(module)) {\n        if (exportName === blockName && _IsFlowGraphBlockConstructor(value)) {\n            block = value;\n        } else if (exportName.startsWith(\"RegisterFlowGraph\") && typeof value === \"function\") {\n            register = value;\n        }\n    }\n\n    if (!block || !register) {\n        throw new Error(`Invalid FlowGraph block module for ${blockName}`);\n    }\n\n    register();\n    if (blockName === \"FlowGraphPlayAnimationBlock\") {\n        const { RegisterAnimationGroup } = await import(\"../../Animations/animationGroup.pure\");\n        RegisterAnimationGroup();\n    }\n\n    return block;\n}\n\n/**\n * a function to get a factory function for a block.\n * @param blockName the block name to initialize. If the block comes from an external module, the name should be in the format \"module/blockName\"\n * @returns an async factory function that will return the block class when called.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function blockFactory(blockName: FlowGraphBlockNames | string): () => Promise<typeof FlowGraphBlock> {\n    switch (blockName) {\n        case FlowGraphBlockNames.PlayAnimation:\n            return async () => await _LoadBlock(import(\"./Execution/Animation/flowGraphPlayAnimationBlock.pure\"), \"FlowGraphPlayAnimationBlock\");\n        case FlowGraphBlockNames.StopAnimation:\n            return async () => await _LoadBlock(import(\"./Execution/Animation/flowGraphStopAnimationBlock.pure\"), \"FlowGraphStopAnimationBlock\");\n        case FlowGraphBlockNames.PauseAnimation:\n            return async () => await _LoadBlock(import(\"./Execution/Animation/flowGraphPauseAnimationBlock.pure\"), \"FlowGraphPauseAnimationBlock\");\n        case FlowGraphBlockNames.ValueInterpolation:\n            return async () => await _LoadBlock(import(\"./Execution/Animation/flowGraphInterpolationBlock.pure\"), \"FlowGraphInterpolationBlock\");\n        case FlowGraphBlockNames.SceneReadyEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphSceneReadyEventBlock.pure\"), \"FlowGraphSceneReadyEventBlock\");\n        case FlowGraphBlockNames.SceneTickEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphSceneTickEventBlock.pure\"), \"FlowGraphSceneTickEventBlock\");\n        case FlowGraphBlockNames.SendCustomEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphSendCustomEventBlock.pure\"), \"FlowGraphSendCustomEventBlock\");\n        case FlowGraphBlockNames.ReceiveCustomEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphReceiveCustomEventBlock.pure\"), \"FlowGraphReceiveCustomEventBlock\");\n        case FlowGraphBlockNames.StopEventPropagation:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphStopEventPropagationBlock.pure\"), \"FlowGraphStopEventPropagationBlock\");\n        case FlowGraphBlockNames.MeshPickEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphMeshPickEventBlock.pure\"), \"FlowGraphMeshPickEventBlock\");\n        case FlowGraphBlockNames.E:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphEBlock\");\n        case FlowGraphBlockNames.PI:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphPiBlock\");\n        case FlowGraphBlockNames.Tau:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphTauBlock\");\n        case FlowGraphBlockNames.Inf:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphInfBlock\");\n        case FlowGraphBlockNames.NaN:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphNaNBlock\");\n        case FlowGraphBlockNames.Random:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphRandomBlock\");\n        case FlowGraphBlockNames.Add:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAddBlock\");\n        case FlowGraphBlockNames.Subtract:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphSubtractBlock\");\n        case FlowGraphBlockNames.Multiply:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphMultiplyBlock\");\n        case FlowGraphBlockNames.Divide:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphDivideBlock\");\n        case FlowGraphBlockNames.Abs:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAbsBlock\");\n        case FlowGraphBlockNames.Sign:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphSignBlock\");\n        case FlowGraphBlockNames.Trunc:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphTruncBlock\");\n        case FlowGraphBlockNames.Floor:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphFloorBlock\");\n        case FlowGraphBlockNames.Ceil:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphCeilBlock\");\n        case FlowGraphBlockNames.Round:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphRoundBlock\");\n        case FlowGraphBlockNames.Fraction:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphFractionBlock\");\n        case FlowGraphBlockNames.Negation:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphNegationBlock\");\n        case FlowGraphBlockNames.Modulo:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphModuloBlock\");\n        case FlowGraphBlockNames.Min:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphMinBlock\");\n        case FlowGraphBlockNames.Max:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphMaxBlock\");\n        case FlowGraphBlockNames.Clamp:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphClampBlock\");\n        case FlowGraphBlockNames.Saturate:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphSaturateBlock\");\n        case FlowGraphBlockNames.MathInterpolation:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphMathInterpolationBlock\");\n        case FlowGraphBlockNames.MathSlerp:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphMathSlerpBlock\");\n        case FlowGraphBlockNames.SmoothStep:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphMathSmoothStepBlock\");\n        case FlowGraphBlockNames.RGBToOkLCh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphRGBToOkLChBlock\");\n        case FlowGraphBlockNames.RGBFromOkLCh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphRGBFromOkLChBlock\");\n        case FlowGraphBlockNames.Equality:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphEqualityBlock\");\n        case FlowGraphBlockNames.LessThan:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphLessThanBlock\");\n        case FlowGraphBlockNames.LessThanOrEqual:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphLessThanOrEqualBlock\");\n        case FlowGraphBlockNames.GreaterThan:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphGreaterThanBlock\");\n        case FlowGraphBlockNames.GreaterThanOrEqual:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphGreaterThanOrEqualBlock\");\n        case FlowGraphBlockNames.IsNaN:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphIsNanBlock\");\n        case FlowGraphBlockNames.IsInfinity:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphIsInfinityBlock\");\n        case FlowGraphBlockNames.DegToRad:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphDegToRadBlock\");\n        case FlowGraphBlockNames.RadToDeg:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphRadToDegBlock\");\n        case FlowGraphBlockNames.Sin:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphSinBlock\");\n        case FlowGraphBlockNames.Cos:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphCosBlock\");\n        case FlowGraphBlockNames.Tan:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphTanBlock\");\n        case FlowGraphBlockNames.Asin:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAsinBlock\");\n        case FlowGraphBlockNames.Acos:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAcosBlock\");\n        case FlowGraphBlockNames.Atan:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAtanBlock\");\n        case FlowGraphBlockNames.Atan2:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAtan2Block\");\n        case FlowGraphBlockNames.Sinh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphSinhBlock\");\n        case FlowGraphBlockNames.Cosh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphCoshBlock\");\n        case FlowGraphBlockNames.Tanh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphTanhBlock\");\n        case FlowGraphBlockNames.Asinh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAsinhBlock\");\n        case FlowGraphBlockNames.Acosh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAcoshBlock\");\n        case FlowGraphBlockNames.Atanh:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphAtanhBlock\");\n        case FlowGraphBlockNames.Exponential:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphExpBlock\");\n        case FlowGraphBlockNames.Log:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphLogBlock\");\n        case FlowGraphBlockNames.Log2:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphLog2Block\");\n        case FlowGraphBlockNames.Log10:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphLog10Block\");\n        case FlowGraphBlockNames.SquareRoot:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphSquareRootBlock\");\n        case FlowGraphBlockNames.Power:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphPowerBlock\");\n        case FlowGraphBlockNames.CubeRoot:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphCubeRootBlock\");\n        case FlowGraphBlockNames.BitwiseAnd:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphBitwiseAndBlock\");\n        case FlowGraphBlockNames.BitwiseOr:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphBitwiseOrBlock\");\n        case FlowGraphBlockNames.BitwiseNot:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphBitwiseNotBlock\");\n        case FlowGraphBlockNames.BitwiseXor:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphBitwiseXorBlock\");\n        case FlowGraphBlockNames.BitwiseLeftShift:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphBitwiseLeftShiftBlock\");\n        case FlowGraphBlockNames.BitwiseRightShift:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphBitwiseRightShiftBlock\");\n        case FlowGraphBlockNames.Length:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphLengthBlock\");\n        case FlowGraphBlockNames.Normalize:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphNormalizeBlock\");\n        case FlowGraphBlockNames.Dot:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphDotBlock\");\n        case FlowGraphBlockNames.Cross:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphCrossBlock\");\n        case FlowGraphBlockNames.Rotate2D:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphRotate2DBlock\");\n        case FlowGraphBlockNames.Rotate3D:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphRotate3DBlock\");\n        case FlowGraphBlockNames.Transpose:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMatrixMathBlocks.pure\"), \"FlowGraphTransposeBlock\");\n        case FlowGraphBlockNames.Determinant:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMatrixMathBlocks.pure\"), \"FlowGraphDeterminantBlock\");\n        case FlowGraphBlockNames.InvertMatrix:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMatrixMathBlocks.pure\"), \"FlowGraphInvertMatrixBlock\");\n        case FlowGraphBlockNames.MatrixMultiplication:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMatrixMathBlocks.pure\"), \"FlowGraphMatrixMultiplicationBlock\");\n        case FlowGraphBlockNames.Branch:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphBranchBlock.pure\"), \"FlowGraphBranchBlock\");\n        case FlowGraphBlockNames.SetDelay:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphSetDelayBlock.pure\"), \"FlowGraphSetDelayBlock\");\n        case FlowGraphBlockNames.CancelDelay:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphCancelDelayBlock.pure\"), \"FlowGraphCancelDelayBlock\");\n        case FlowGraphBlockNames.CallCounter:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphCounterBlock.pure\"), \"FlowGraphCallCounterBlock\");\n        case FlowGraphBlockNames.Debounce:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphDebounceBlock.pure\"), \"FlowGraphDebounceBlock\");\n        case FlowGraphBlockNames.Throttle:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphThrottleBlock.pure\"), \"FlowGraphThrottleBlock\");\n        case FlowGraphBlockNames.DoN:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphDoNBlock.pure\"), \"FlowGraphDoNBlock\");\n        case FlowGraphBlockNames.FlipFlop:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphFlipFlopBlock.pure\"), \"FlowGraphFlipFlopBlock\");\n        case FlowGraphBlockNames.ForLoop:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphForLoopBlock.pure\"), \"FlowGraphForLoopBlock\");\n        case FlowGraphBlockNames.MultiGate:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphMultiGateBlock.pure\"), \"FlowGraphMultiGateBlock\");\n        case FlowGraphBlockNames.Sequence:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphSequenceBlock.pure\"), \"FlowGraphSequenceBlock\");\n        case FlowGraphBlockNames.Switch:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphSwitchBlock.pure\"), \"FlowGraphSwitchBlock\");\n        case FlowGraphBlockNames.WaitAll:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphWaitAllBlock.pure\"), \"FlowGraphWaitAllBlock\");\n        case FlowGraphBlockNames.WhileLoop:\n            return async () => await _LoadBlock(import(\"./Execution/ControlFlow/flowGraphWhileLoopBlock.pure\"), \"FlowGraphWhileLoopBlock\");\n        case FlowGraphBlockNames.ConsoleLog:\n            return async () => await _LoadBlock(import(\"./Execution/flowGraphConsoleLogBlock.pure\"), \"FlowGraphConsoleLogBlock\");\n        case FlowGraphBlockNames.Conditional:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphConditionalDataBlock.pure\"), \"FlowGraphConditionalDataBlock\");\n        case FlowGraphBlockNames.Constant:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphConstantBlock.pure\"), \"FlowGraphConstantBlock\");\n        case FlowGraphBlockNames.TransformCoordinatesSystem:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphTransformCoordinatesSystemBlock.pure\"), \"FlowGraphTransformCoordinatesSystemBlock\");\n        case FlowGraphBlockNames.GetAsset:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphGetAssetBlock.pure\"), \"FlowGraphGetAssetBlock\");\n        case FlowGraphBlockNames.GetProperty:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphGetPropertyBlock.pure\"), \"FlowGraphGetPropertyBlock\");\n        case FlowGraphBlockNames.SetProperty:\n            return async () => await _LoadBlock(import(\"./Execution/flowGraphSetPropertyBlock.pure\"), \"FlowGraphSetPropertyBlock\");\n        case FlowGraphBlockNames.GetVariable:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphGetVariableBlock.pure\"), \"FlowGraphGetVariableBlock\");\n        case FlowGraphBlockNames.SetVariable:\n            return async () => await _LoadBlock(import(\"./Execution/flowGraphSetVariableBlock.pure\"), \"FlowGraphSetVariableBlock\");\n        case FlowGraphBlockNames.JsonPointerParser:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphJsonPointerParserBlock.pure\"), \"FlowGraphJsonPointerParserBlock\");\n        case FlowGraphBlockNames.LeadingZeros:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphLeadingZerosBlock\");\n        case FlowGraphBlockNames.TrailingZeros:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphTrailingZerosBlock\");\n        case FlowGraphBlockNames.OneBitsCounter:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathBlocks.pure\"), \"FlowGraphOneBitsCounterBlock\");\n        case FlowGraphBlockNames.CombineVector2:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphCombineVector2Block\");\n        case FlowGraphBlockNames.CombineVector3:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphCombineVector3Block\");\n        case FlowGraphBlockNames.CombineVector4:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphCombineVector4Block\");\n        case FlowGraphBlockNames.CombineMatrix:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphCombineMatrixBlock\");\n        case FlowGraphBlockNames.CombineMatrix2D:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphCombineMatrix2DBlock\");\n        case FlowGraphBlockNames.CombineMatrix3D:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphCombineMatrix3DBlock\");\n        case FlowGraphBlockNames.ExtractVector2:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphExtractVector2Block\");\n        case FlowGraphBlockNames.ExtractVector3:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphExtractVector3Block\");\n        case FlowGraphBlockNames.ExtractVector4:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphExtractVector4Block\");\n        case FlowGraphBlockNames.ExtractMatrix:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphExtractMatrixBlock\");\n        case FlowGraphBlockNames.ExtractMatrix2D:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphExtractMatrix2DBlock\");\n        case FlowGraphBlockNames.ExtractMatrix3D:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMathCombineExtractBlocks.pure\"), \"FlowGraphExtractMatrix3DBlock\");\n        case FlowGraphBlockNames.TransformVector:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphTransformBlock\");\n        case FlowGraphBlockNames.TransformCoordinates:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphTransformCoordinatesBlock\");\n        case FlowGraphBlockNames.Conjugate:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphConjugateBlock\");\n        case FlowGraphBlockNames.AngleBetween:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphAngleBetweenBlock\");\n        case FlowGraphBlockNames.QuaternionFromAxisAngle:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphQuaternionFromAxisAngleBlock\");\n        case FlowGraphBlockNames.AxisAngleFromQuaternion:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphAxisAngleFromQuaternionBlock\");\n        case FlowGraphBlockNames.QuaternionFromDirections:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphQuaternionFromDirectionsBlock\");\n        case FlowGraphBlockNames.QuaternionFromUpForward:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphQuaternionFromUpForwardBlock\");\n        case FlowGraphBlockNames.QuaternionFromAngles:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphQuaternionFromAnglesBlock\");\n        case FlowGraphBlockNames.VectorSlerp:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphVectorMathBlocks.pure\"), \"FlowGraphVectorSlerpBlock\");\n        case FlowGraphBlockNames.MatrixDecompose:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMatrixMathBlocks.pure\"), \"FlowGraphMatrixDecomposeBlock\");\n        case FlowGraphBlockNames.MatrixCompose:\n            return async () => await _LoadBlock(import(\"./Data/Math/flowGraphMatrixMathBlocks.pure\"), \"FlowGraphMatrixComposeBlock\");\n        case FlowGraphBlockNames.BooleanToFloat:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphTypeToTypeBlocks.pure\"), \"FlowGraphBooleanToFloat\");\n        case FlowGraphBlockNames.BooleanToInt:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphTypeToTypeBlocks.pure\"), \"FlowGraphBooleanToInt\");\n        case FlowGraphBlockNames.FloatToBoolean:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphTypeToTypeBlocks.pure\"), \"FlowGraphFloatToBoolean\");\n        case FlowGraphBlockNames.IntToBoolean:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphTypeToTypeBlocks.pure\"), \"FlowGraphIntToBoolean\");\n        case FlowGraphBlockNames.IntToFloat:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphTypeToTypeBlocks.pure\"), \"FlowGraphIntToFloat\");\n        case FlowGraphBlockNames.FloatToInt:\n            return async () => await _LoadBlock(import(\"./Data/Transformers/flowGraphTypeToTypeBlocks.pure\"), \"FlowGraphFloatToInt\");\n        case FlowGraphBlockNames.Easing:\n            return async () => await _LoadBlock(import(\"./Execution/Animation/flowGraphEasingBlock.pure\"), \"FlowGraphEasingBlock\");\n        case FlowGraphBlockNames.BezierCurveEasing:\n            return async () => await _LoadBlock(import(\"./Execution/Animation/flowGraphBezierCurveEasingBlock.pure\"), \"FlowGraphBezierCurveEasingBlock\");\n        case FlowGraphBlockNames.PointerOverEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphPointerOverEventBlock.pure\"), \"FlowGraphPointerOverEventBlock\");\n        case FlowGraphBlockNames.PointerOutEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphPointerOutEventBlock.pure\"), \"FlowGraphPointerOutEventBlock\");\n        case FlowGraphBlockNames.PointerDownEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphPointerDownEventBlock.pure\"), \"FlowGraphPointerDownEventBlock\");\n        case FlowGraphBlockNames.PointerUpEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphPointerUpEventBlock.pure\"), \"FlowGraphPointerUpEventBlock\");\n        case FlowGraphBlockNames.PointerMoveEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphPointerMoveEventBlock.pure\"), \"FlowGraphPointerMoveEventBlock\");\n        // Keyboard\n        case FlowGraphBlockNames.KeyDownEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphKeyDownEventBlock.pure\"), \"FlowGraphKeyDownEventBlock\");\n        case FlowGraphBlockNames.KeyUpEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphKeyUpEventBlock.pure\"), \"FlowGraphKeyUpEventBlock\");\n        case FlowGraphBlockNames.IsKeyPressed:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphIsKeyPressedBlock.pure\"), \"FlowGraphIsKeyPressedBlock\");\n        case FlowGraphBlockNames.Context:\n            return async () => await _LoadBlock(import(\"./Data/Utils/flowGraphContextBlock.pure\"), \"FlowGraphContextBlock\");\n        case FlowGraphBlockNames.ArrayIndex:\n            return async () => await _LoadBlock(import(\"./Data/Utils/flowGraphArrayIndexBlock.pure\"), \"FlowGraphArrayIndexBlock\");\n        case FlowGraphBlockNames.CodeExecution:\n            return async () => (await import(\"./Data/Utils/flowGraphCodeExecutionBlock\")).FlowGraphCodeExecutionBlock;\n        case FlowGraphBlockNames.IndexOf:\n            return async () => await _LoadBlock(import(\"./Data/Utils/flowGraphIndexOfBlock.pure\"), \"FlowGraphIndexOfBlock\");\n        case FlowGraphBlockNames.FunctionReference:\n            return async () => await _LoadBlock(import(\"./Data/Utils/flowGraphFunctionReferenceBlock.pure\"), \"FlowGraphFunctionReferenceBlock\");\n        case FlowGraphBlockNames.DataSwitch:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphDataSwitchBlock.pure\"), \"FlowGraphDataSwitchBlock\");\n        case FlowGraphBlockNames.DebugBlock:\n            return async () => await _LoadBlock(import(\"./Data/flowGraphDebugBlock.pure\"), \"FlowGraphDebugBlock\");\n        // Physics\n        case FlowGraphBlockNames.PhysicsCollisionEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphPhysicsCollisionEventBlock.pure\"), \"FlowGraphPhysicsCollisionEventBlock\");\n        case FlowGraphBlockNames.PhysicsApplyForce:\n            return async () => await _LoadBlock(import(\"./Execution/Physics/flowGraphApplyForceBlock.pure\"), \"FlowGraphApplyForceBlock\");\n        case FlowGraphBlockNames.PhysicsApplyImpulse:\n            return async () => await _LoadBlock(import(\"./Execution/Physics/flowGraphApplyImpulseBlock.pure\"), \"FlowGraphApplyImpulseBlock\");\n        case FlowGraphBlockNames.PhysicsSetLinearVelocity:\n            return async () => await _LoadBlock(import(\"./Execution/Physics/flowGraphSetLinearVelocityBlock.pure\"), \"FlowGraphSetLinearVelocityBlock\");\n        case FlowGraphBlockNames.PhysicsSetAngularVelocity:\n            return async () => await _LoadBlock(import(\"./Execution/Physics/flowGraphSetAngularVelocityBlock.pure\"), \"FlowGraphSetAngularVelocityBlock\");\n        case FlowGraphBlockNames.PhysicsSetMotionType:\n            return async () => await _LoadBlock(import(\"./Execution/Physics/flowGraphSetPhysicsMotionTypeBlock.pure\"), \"FlowGraphSetPhysicsMotionTypeBlock\");\n        case FlowGraphBlockNames.PhysicsGetLinearVelocity:\n            return async () => await _LoadBlock(import(\"./Data/Physics/flowGraphGetLinearVelocityBlock.pure\"), \"FlowGraphGetLinearVelocityBlock\");\n        case FlowGraphBlockNames.PhysicsGetAngularVelocity:\n            return async () => await _LoadBlock(import(\"./Data/Physics/flowGraphGetAngularVelocityBlock.pure\"), \"FlowGraphGetAngularVelocityBlock\");\n        case FlowGraphBlockNames.PhysicsGetMassProperties:\n            return async () => await _LoadBlock(import(\"./Data/Physics/flowGraphGetPhysicsMassPropertiesBlock.pure\"), \"FlowGraphGetPhysicsMassPropertiesBlock\");\n        // Audio\n        case FlowGraphBlockNames.AudioPlaySound:\n            return async () => await _LoadBlock(import(\"./Execution/Audio/flowGraphPlaySoundBlock.pure\"), \"FlowGraphPlaySoundBlock\");\n        case FlowGraphBlockNames.AudioStopSound:\n            return async () => await _LoadBlock(import(\"./Execution/Audio/flowGraphStopSoundBlock.pure\"), \"FlowGraphStopSoundBlock\");\n        case FlowGraphBlockNames.AudioPauseSound:\n            return async () => await _LoadBlock(import(\"./Execution/Audio/flowGraphPauseSoundBlock.pure\"), \"FlowGraphPauseSoundBlock\");\n        case FlowGraphBlockNames.AudioSetVolume:\n            return async () => await _LoadBlock(import(\"./Execution/Audio/flowGraphSetSoundVolumeBlock.pure\"), \"FlowGraphSetSoundVolumeBlock\");\n        case FlowGraphBlockNames.AudioSoundEndedEvent:\n            return async () => await _LoadBlock(import(\"./Event/flowGraphSoundEndedEventBlock.pure\"), \"FlowGraphSoundEndedEventBlock\");\n        case FlowGraphBlockNames.AudioGetVolume:\n            return async () => await _LoadBlock(import(\"./Data/Audio/flowGraphGetSoundVolumeBlock.pure\"), \"FlowGraphGetSoundVolumeBlock\");\n        case FlowGraphBlockNames.AudioIsSoundPlaying:\n            return async () => await _LoadBlock(import(\"./Data/Audio/flowGraphIsSoundPlayingBlock.pure\"), \"FlowGraphIsSoundPlayingBlock\");\n        default:\n            // check if the block is a custom block\n            if (CustomBlocks[blockName]) {\n                return CustomBlocks[blockName];\n            }\n            // Fallback: O(1) reverse lookup by short name (e.g. \"FlowGraphGLTFDataProvider\" → \"KHR_interactivity/FlowGraphGLTFDataProvider\")\n            if (!blockName.includes(\"/\")) {\n                const fullKey = ShortNameToFullKey[blockName];\n                if (fullKey && CustomBlocks[fullKey]) {\n                    return CustomBlocks[fullKey];\n                }\n            }\n            throw new Error(`Unknown block name ${blockName}`);\n    }\n}\n","import { type IAssetContainer } from \"core/IAssetContainer\";\nimport { blockFactory } from \"./Blocks/flowGraphBlockFactory\";\nimport { FlowGraphBlockNames } from \"./Blocks/flowGraphBlockNames\";\nimport { type FlowGraph, type IFlowGraphParseOptions } from \"./flowGraph\";\nimport { type FlowGraphBlock, type IFlowGraphBlockParseOptions } from \"./flowGraphBlock\";\nimport { type FlowGraphContext, type IFlowGraphContextParseOptions } from \"./flowGraphContext\";\nimport { type IFlowGraphCoordinatorParseOptions, FlowGraphCoordinator } from \"./flowGraphCoordinator\";\nimport { type FlowGraphDataConnection } from \"./flowGraphDataConnection\";\nimport { FlowGraphEventBlock } from \"./flowGraphEventBlock\";\nimport { FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\nimport { type FlowGraphSignalConnection } from \"./flowGraphSignalConnection\";\nimport { _GetDefaultEventDataParseCount, defaultValueParseFunction, needsPathConverter } from \"./serialization\";\nimport { type ISerializedFlowGraph, type ISerializedFlowGraphBlock, type ISerializedFlowGraphContext } from \"./typeDefinitions\";\nimport { type Node } from \"core/node\";\nimport { type Scene } from \"core/scene\";\nimport { getRichTypeByFlowGraphType, RichType } from \"./flowGraphRichTypes.pure\";\nimport { type FlowGraphConnection } from \"./flowGraphConnection\";\nimport { Constants } from \"core/Engines/constants\";\nimport { WebRequest } from \"core/Misc/webRequest\";\n\nfunction ParseCustomEventData(\n    serializedEventData: unknown,\n    valueParseFunction: NonNullable<IFlowGraphBlockParseOptions[\"valueParseFunction\"]>,\n    assetsContainer: IAssetContainer,\n    scene: Scene\n): Record<string, { type: unknown; value?: unknown }> {\n    const eventData: Record<string, { type: unknown; value?: unknown }> = Object.create(null);\n    if (Array.isArray(serializedEventData)) {\n        for (const serializedEntry of serializedEventData) {\n            if (!serializedEntry?.eventData) {\n                continue;\n            }\n            const entry: { type: unknown; value?: unknown } = { type: getRichTypeByFlowGraphType(serializedEntry.type) };\n            if (serializedEntry.value !== undefined) {\n                entry.value = serializedEntry.value?.getClassName?.() ? serializedEntry.value : valueParseFunction(\"value\", serializedEntry, assetsContainer, scene);\n            }\n            Object.defineProperty(eventData, serializedEntry.id, {\n                configurable: true,\n                enumerable: true,\n                value: entry,\n                writable: true,\n            });\n        }\n        return eventData;\n    }\n    if (serializedEventData === null || typeof serializedEventData !== \"object\") {\n        return eventData;\n    }\n    for (const eventKey of Object.keys(serializedEventData)) {\n        const serializedEntry = (serializedEventData as Record<string, unknown>)[eventKey] as { type?: unknown; value?: unknown };\n        if (serializedEntry === null || typeof serializedEntry !== \"object\") {\n            continue;\n        }\n        const entry: { type: unknown; value?: unknown } = { type: serializedEntry.type };\n        if (serializedEntry.value !== undefined) {\n            entry.value = (serializedEntry.value as any)?.getClassName?.() ? serializedEntry.value : valueParseFunction(\"value\", serializedEntry, assetsContainer, scene);\n        }\n        Object.defineProperty(eventData, eventKey, {\n            configurable: true,\n            enumerable: true,\n            value: entry,\n            writable: true,\n        });\n    }\n    return eventData;\n}\n\nasync function GetSerializedFlowGraphFromSnippetAsync(snippetId: string): Promise<any> {\n    const response = await WebRequest.FetchAsync(Constants.SnippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\n    if (!response.ok) {\n        throw new Error(\"Unable to load the snippet \" + snippetId);\n    }\n\n    const text = new TextDecoder().decode(await response.arrayBuffer());\n    const snippet = JSON.parse(text);\n    const snippetPayload = JSON.parse(snippet.jsonPayload);\n    const flowGraphPayload = snippetPayload.flowGraph;\n    if (!flowGraphPayload) {\n        throw new Error(\"Snippet \" + snippetId + \" does not contain a flow graph\");\n    }\n\n    return typeof flowGraphPayload === \"string\" ? JSON.parse(flowGraphPayload) : flowGraphPayload;\n}\n\nfunction ApplyCoordinatorSerializationSettings(serializedObject: any, coordinator: FlowGraphCoordinator): void {\n    if (serializedObject.dispatchEventsSynchronously !== undefined) {\n        coordinator.dispatchEventsSynchronously = serializedObject.dispatchEventsSynchronously;\n    }\n\n    if (serializedObject._defaultValues) {\n        for (const key in serializedObject._defaultValues) {\n            getRichTypeByFlowGraphType(key).defaultValue = serializedObject._defaultValues[key];\n        }\n    }\n}\n\n/**\n * Given a list of blocks, find an output data connection that has a specific unique id\n * @param blocks a list of flow graph blocks\n * @param uniqueId the unique id of a connection\n * @returns the connection that has this unique id. throws an error if none was found\n */\nexport function GetDataOutConnectionByUniqueId(blocks: FlowGraphBlock[], uniqueId: string): FlowGraphDataConnection<any> {\n    for (const block of blocks) {\n        for (const dataOut of block.dataOutputs) {\n            if (dataOut.uniqueId === uniqueId) {\n                return dataOut;\n            }\n        }\n    }\n    throw new Error(\"Could not find data out connection with unique id \" + uniqueId);\n}\n\n/**\n * Given a list of blocks, find an input signal connection that has a specific unique id\n * @param blocks a list of flow graph blocks\n * @param uniqueId the unique id of a connection\n * @returns the connection that has this unique id. throws an error if none was found\n */\nexport function GetSignalInConnectionByUniqueId(blocks: FlowGraphBlock[], uniqueId: string): FlowGraphSignalConnection {\n    for (const block of blocks) {\n        if (block instanceof FlowGraphExecutionBlock) {\n            for (const signalIn of block.signalInputs) {\n                if (signalIn.uniqueId === uniqueId) {\n                    return signalIn;\n                }\n            }\n        }\n    }\n    throw new Error(\"Could not find signal in connection with unique id \" + uniqueId);\n}\n\n/**\n * Parses a serialized coordinator.\n * @param serializedObject the object to parse\n * @param options the options to use when parsing\n * @returns the parsed coordinator\n */\nexport async function ParseCoordinatorAsync(serializedObject: any, options: IFlowGraphCoordinatorParseOptions) {\n    const valueParseFunction = options.valueParseFunction ?? defaultValueParseFunction;\n    const coordinator = new FlowGraphCoordinator({ scene: options.scene });\n\n    ApplyCoordinatorSerializationSettings(serializedObject, coordinator);\n\n    await options.scene.whenReadyAsync();\n    // async-parse the flow graphs. This can be done in parallel\n    await Promise.all(\n        serializedObject._flowGraphs?.map(\n            async (serializedGraph: any) => await ParseFlowGraphAsync(serializedGraph, { coordinator, valueParseFunction, pathConverter: options.pathConverter })\n        )\n    );\n    return coordinator;\n}\n\n/**\n * Parses a flow graph coordinator from a snippet saved by the Flow Graph Editor.\n * @param snippetId the snippet id to load. Versioned ids such as \"ABC123#4\" are supported.\n * @param options options for parsing the coordinator.\n * @returns the parsed flow graph coordinator.\n */\nexport async function ParseFlowGraphCoordinatorFromSnippetAsync(snippetId: string, options: IFlowGraphCoordinatorParseOptions): Promise<FlowGraphCoordinator> {\n    const serializedObject = await GetSerializedFlowGraphFromSnippetAsync(snippetId);\n    if (serializedObject._flowGraphs) {\n        return await ParseCoordinatorAsync(serializedObject, options);\n    }\n\n    const valueParseFunction = options.valueParseFunction ?? defaultValueParseFunction;\n    const coordinator = new FlowGraphCoordinator({ scene: options.scene });\n    await options.scene.whenReadyAsync();\n    await ParseFlowGraphAsync(serializedObject, { coordinator, valueParseFunction, pathConverter: options.pathConverter });\n    return coordinator;\n}\n\n/**\n * Parses a flow graph from a snippet saved by the Flow Graph Editor.\n * If the snippet contains multiple graphs, all graphs are parsed into the provided coordinator and the active graph is returned.\n * @param snippetId the snippet id to load. Versioned ids such as \"ABC123#4\" are supported.\n * @param options options for parsing the graph.\n * @returns the parsed flow graph.\n */\nexport async function ParseFlowGraphFromSnippetAsync(snippetId: string, options: IFlowGraphParseOptions): Promise<FlowGraph> {\n    const serializedObject = await GetSerializedFlowGraphFromSnippetAsync(snippetId);\n    const valueParseFunction = options.valueParseFunction ?? defaultValueParseFunction;\n\n    if (!serializedObject._flowGraphs) {\n        return await ParseFlowGraphAsync(serializedObject, options);\n    }\n\n    ApplyCoordinatorSerializationSettings(serializedObject, options.coordinator);\n    const parsedGraphs: FlowGraph[] = [];\n    for (const serializedGraph of serializedObject._flowGraphs) {\n        // eslint-disable-next-line no-await-in-loop -- graph order matters for the active graph index.\n        parsedGraphs.push(await ParseFlowGraphAsync(serializedGraph, { coordinator: options.coordinator, valueParseFunction, pathConverter: options.pathConverter }));\n    }\n\n    const activeGraphIndex = serializedObject.activeGraphIndex ?? 0;\n    return parsedGraphs[activeGraphIndex] ?? parsedGraphs[0];\n}\n\n/**\n * Parses a graph from a given serialization object\n * @param serializationObject the object where the values are written\n * @param options options for parsing the graph\n * @returns the parsed graph\n */\nexport async function ParseFlowGraphAsync(serializationObject: ISerializedFlowGraph, options: IFlowGraphParseOptions): Promise<FlowGraph> {\n    // get all classes types needed for the blocks using the block factory\n    const resolvedClasses = await Promise.all(\n        serializationObject.allBlocks.map(async (serializedBlock) => {\n            const classFactory = blockFactory(serializedBlock.className as FlowGraphBlockNames);\n            return await classFactory();\n        })\n    );\n    // async will be used when we start using the block async factory\n    return ParseFlowGraph(serializationObject, options, resolvedClasses);\n}\n\n/**\n * Parses a graph from a given serialization object\n * @param serializationObject the object where the values are written\n * @param options options for parsing the graph\n * @param resolvedClasses the resolved classes for the blocks\n * @returns the parsed graph\n */\nexport function ParseFlowGraph(serializationObject: ISerializedFlowGraph, options: IFlowGraphParseOptions, resolvedClasses: (typeof FlowGraphBlock)[]) {\n    const graph = options.coordinator.createGraph();\n    // Restore graph identity from serialized data\n    if (serializationObject.name) {\n        graph.name = serializationObject.name;\n    }\n    if (serializationObject.uniqueId) {\n        graph.uniqueId = serializationObject.uniqueId;\n    }\n    graph.metadata = serializationObject.metadata;\n    const blocks: FlowGraphBlock[] = [];\n    const valueParseFunction = options.valueParseFunction ?? defaultValueParseFunction;\n    // Parse all blocks\n    // for (const serializedBlock of serializationObject.allBlocks) {\n    for (let i = 0; i < serializationObject.allBlocks.length; i++) {\n        const serializedBlock = serializationObject.allBlocks[i];\n        const block = ParseFlowGraphBlockWithClassType(\n            serializedBlock,\n            { scene: options.coordinator.config.scene, pathConverter: options.pathConverter, assetsContainer: options.coordinator.config.scene, valueParseFunction },\n            resolvedClasses[i]\n        );\n        blocks.push(block);\n        graph.addBlock(block);\n        if (block instanceof FlowGraphEventBlock) {\n            graph.addEventBlock(block);\n        }\n    }\n    // After parsing all blocks, connect them.\n    // Build lookup maps for O(1) connection resolution instead of O(B*P) linear scans.\n    const dataInMap = new Map<string, FlowGraphDataConnection<any>>();\n    const dataOutMap = new Map<string, FlowGraphDataConnection<any>>();\n    const signalInMap = new Map<string, FlowGraphSignalConnection>();\n    const signalOutMap = new Map<string, FlowGraphSignalConnection>();\n    for (const block of blocks) {\n        for (const dataIn of block.dataInputs) {\n            dataInMap.set(dataIn.uniqueId, dataIn);\n        }\n        for (const dataOut of block.dataOutputs) {\n            dataOutMap.set(dataOut.uniqueId, dataOut);\n        }\n        if (block instanceof FlowGraphExecutionBlock) {\n            for (const signalIn of block.signalInputs) {\n                signalInMap.set(signalIn.uniqueId, signalIn);\n            }\n            for (const signalOut of block.signalOutputs) {\n                signalOutMap.set(signalOut.uniqueId, signalOut);\n            }\n        }\n    }\n    const connectIfNeeded = <ConnectionT extends FlowGraphConnection<any, any>>(connection: ConnectionT, connectedConnection: ConnectionT) => {\n        if (connection._connectedPoint.indexOf(connectedConnection) !== -1) {\n            return;\n        }\n        connection.connectTo(connectedConnection);\n    };\n    for (const block of blocks) {\n        for (const dataIn of block.dataInputs) {\n            for (const serializedConnection of dataIn.connectedPointIds) {\n                const connection = dataOutMap.get(serializedConnection);\n                if (!connection) {\n                    throw new Error(\"Could not find data out connection with unique id \" + serializedConnection);\n                }\n                connectIfNeeded(dataIn, connection);\n            }\n        }\n        for (const dataOut of block.dataOutputs) {\n            for (const serializedConnection of dataOut.connectedPointIds) {\n                const connection = dataInMap.get(serializedConnection);\n                if (!connection) {\n                    throw new Error(\"Could not find data in connection with unique id \" + serializedConnection);\n                }\n                connectIfNeeded(dataOut, connection);\n            }\n        }\n        if (block instanceof FlowGraphExecutionBlock) {\n            for (const signalOut of block.signalOutputs) {\n                for (const serializedConnection of signalOut.connectedPointIds) {\n                    const connection = signalInMap.get(serializedConnection);\n                    if (!connection) {\n                        throw new Error(\"Could not find signal in connection with unique id \" + serializedConnection);\n                    }\n                    connectIfNeeded(signalOut, connection);\n                }\n            }\n            for (const signalIn of block.signalInputs) {\n                for (const serializedConnection of signalIn.connectedPointIds) {\n                    const connection = signalOutMap.get(serializedConnection);\n                    if (!connection) {\n                        throw new Error(\"Could not find signal out connection with unique id \" + serializedConnection);\n                    }\n                    connectIfNeeded(connection, signalIn);\n                }\n            }\n        }\n    }\n    for (const serializedContext of serializationObject.executionContexts ?? []) {\n        ParseFlowGraphContext(serializedContext, { graph, valueParseFunction }, serializationObject.rightHanded);\n    }\n    return graph;\n}\n\n/**\n * Parses a context\n * @param serializationObject the object containing the context serialization values\n * @param options the options for parsing the context\n * @param rightHanded whether the serialized data is right handed\n * @returns\n */\nexport function ParseFlowGraphContext(serializationObject: ISerializedFlowGraphContext, options: IFlowGraphContextParseOptions, rightHanded?: boolean): FlowGraphContext {\n    const result = options.graph.createContext();\n    if (serializationObject.enableLogging) {\n        result.enableLogging = true;\n    }\n    result.treatDataAsRightHanded = rightHanded || false;\n    const valueParseFunction = options.valueParseFunction ?? defaultValueParseFunction;\n    result.uniqueId = serializationObject.uniqueId;\n    result.name = serializationObject.name ?? \"\";\n    const scene = result.getScene();\n    // check if assets context is available\n    if (serializationObject._assetsContext) {\n        const ac = serializationObject._assetsContext;\n        const assetsContext: IAssetContainer = {\n            meshes: ac.meshes?.map((m: string) => scene.getMeshById(m)),\n            lights: ac.lights?.map((l: string) => scene.getLightByName(l)),\n            cameras: ac.cameras?.map((c: string) => scene.getCameraByName(c)),\n            materials: ac.materials?.map((m: string) => scene.getMaterialById(m)),\n            textures: ac.textures?.map((t: string) => scene.getTextureByName(t)),\n            animations: ac.animations?.map((a: string) => scene.animations.find((anim) => anim.name === a)),\n            skeletons: ac.skeletons?.map((s: string) => scene.getSkeletonByName(s)),\n            particleSystems: ac.particleSystems?.map((ps: string) => scene.getParticleSystemById(ps)),\n            animationGroups: ac.animationGroups?.map((ag: string) => scene.getAnimationGroupByName(ag)),\n            transformNodes: ac.transformNodes?.map((tn: string) => scene.getTransformNodeById(tn)),\n            rootNodes: [],\n            multiMaterials: [],\n            morphTargetManagers: [],\n            geometries: [],\n            actionManagers: [],\n            environmentTexture: null,\n            postProcesses: [],\n            sounds: null,\n            effectLayers: [],\n            layers: [],\n            reflectionProbes: [],\n            lensFlareSystems: [],\n            proceduralTextures: [],\n            getNodes: function (): Array<Node> {\n                throw new Error(\"Function not implemented.\");\n            },\n        };\n        result.assetsContext = assetsContext;\n    }\n    for (const key in serializationObject._userVariables) {\n        const value = valueParseFunction(key, serializationObject._userVariables, result.assetsContext, scene);\n        result.userVariables[key] = value;\n    }\n    // Restore variable type annotations\n    if (serializationObject._variableTypes) {\n        for (const key in serializationObject._variableTypes) {\n            result.setVariableType(key, serializationObject._variableTypes[key]);\n        }\n    }\n    for (const key in serializationObject._connectionValues) {\n        const value = valueParseFunction(key, serializationObject._connectionValues, result.assetsContext, scene);\n        result._setConnectionValueByKey(key, value);\n    }\n\n    return result;\n}\n\n/**\n * Parses a block from a serialization object\n * This function is async due to the factory method that is used to create the block's class. If you load the class externally use ParseBlockWithClassType\n * @param serializationObject the object to parse from\n * @param parseOptions options for parsing the block\n * @returns the parsed block\n */\nexport async function ParseBlockAsync(serializationObject: ISerializedFlowGraphBlock, parseOptions: IFlowGraphBlockParseOptions): Promise<FlowGraphBlock> {\n    const classFactory = blockFactory(serializationObject.className as FlowGraphBlockNames);\n    const classType = await classFactory();\n    return ParseFlowGraphBlockWithClassType(serializationObject, parseOptions, classType);\n}\n\n/**\n * Parses a block from a serialization object\n * @param serializationObject the object to parse from\n * @param parseOptions options for parsing the block\n * @param classType the class type of the block. This is used when the class is not loaded asynchronously\n * @returns the parsed block\n */\nexport function ParseFlowGraphBlockWithClassType(\n    serializationObject: ISerializedFlowGraphBlock,\n    parseOptions: IFlowGraphBlockParseOptions,\n    classType: typeof FlowGraphBlock\n): FlowGraphBlock {\n    const parsedConfig: any = {};\n    const valueParseFunction = parseOptions.valueParseFunction ?? defaultValueParseFunction;\n    const customValueParseFunction = parseOptions.valueParseFunction === defaultValueParseFunction ? undefined : parseOptions.valueParseFunction;\n    if (serializationObject.config) {\n        for (const key in serializationObject.config) {\n            const assetsContainer = parseOptions.assetsContainer || parseOptions.scene;\n            const isCustomEventData =\n                key === \"eventData\" &&\n                (serializationObject.className === FlowGraphBlockNames.SendCustomEvent || serializationObject.className === FlowGraphBlockNames.ReceiveCustomEvent);\n            if (isCustomEventData) {\n                const eventData = serializationObject.config[key];\n                const defaultParseCount = _GetDefaultEventDataParseCount(eventData);\n                const customParsedEventData = customValueParseFunction?.(key, serializationObject.config, assetsContainer, parseOptions.scene);\n                const delegatedToDefault = _GetDefaultEventDataParseCount(eventData) > defaultParseCount;\n                parsedConfig[key] =\n                    customValueParseFunction && (!delegatedToDefault || customParsedEventData !== eventData)\n                        ? customParsedEventData\n                        : ParseCustomEventData(eventData, valueParseFunction, assetsContainer, parseOptions.scene);\n            } else {\n                parsedConfig[key] = valueParseFunction(key, serializationObject.config, assetsContainer, parseOptions.scene);\n            }\n        }\n    }\n    if (needsPathConverter(serializationObject.className)) {\n        if (!parseOptions.pathConverter) {\n            throw new Error(\"Block \" + serializationObject.className + \" requires a path converter to be provided in parse options.\");\n        }\n        parsedConfig.pathConverter = parseOptions.pathConverter;\n    }\n    const obj = new classType(parsedConfig);\n    obj.uniqueId = serializationObject.uniqueId;\n    for (let i = 0; i < serializationObject.dataInputs.length; i++) {\n        const dataInput = obj.getDataInput(serializationObject.dataInputs[i].name);\n        if (dataInput) {\n            dataInput.deserialize(serializationObject.dataInputs[i]);\n            // Restore _defaultValue if it was serialized.  Without this, the\n            // user-set inline value (e.g. \"2\" on an Add input, or \"position\"\n            // on a GetProperty's propertyName) is lost during round-trips.\n            if (serializationObject.dataInputs[i].defaultValue !== undefined) {\n                (dataInput as any)._defaultValue = valueParseFunction(\n                    \"defaultValue\",\n                    serializationObject.dataInputs[i],\n                    parseOptions.assetsContainer || parseOptions.scene,\n                    parseOptions.scene\n                );\n            }\n        } else {\n            throw new Error(\"Could not find data input with name \" + serializationObject.dataInputs[i].name + \" in block \" + serializationObject.className);\n        }\n    }\n    for (let i = 0; i < serializationObject.dataOutputs.length; i++) {\n        const dataOutput = obj.getDataOutput(serializationObject.dataOutputs[i].name);\n        if (dataOutput) {\n            dataOutput.deserialize(serializationObject.dataOutputs[i]);\n        } else {\n            throw new Error(\"Could not find data output with name \" + serializationObject.dataOutputs[i].name + \" in block \" + serializationObject.className);\n        }\n    }\n    obj.metadata = serializationObject.metadata;\n    obj.deserialize && obj.deserialize(serializationObject);\n    return obj;\n}\n\n/**\n * Parses a connection from an object\n * @param serializationObject the object to parse from.\n * @param ownerBlock the block that owns the connection.\n * @param classType the class type of the connection.\n * @returns the parsed connection.\n */\nexport function ParseGraphConnectionWithClassType<BlockT extends FlowGraphBlock>(serializationObject: any = {}, ownerBlock: BlockT, classType: typeof FlowGraphConnection) {\n    const connection = new classType(serializationObject.name, serializationObject._connectionType, ownerBlock);\n    connection.deserialize(serializationObject);\n    return connection;\n}\n\n/**\n * Parses a data connection from a serialized object.\n * @param serializationObject the object to parse from\n * @param ownerBlock the block that owns the connection\n * @param classType the class type of the data connection\n * @returns the parsed connection\n */\nexport function ParseGraphDataConnection(serializationObject: any, ownerBlock: FlowGraphBlock, classType: typeof FlowGraphDataConnection): FlowGraphDataConnection<any> {\n    const richType = ParseRichType(serializationObject.richType);\n    const defaultValue = serializationObject.defaultValue;\n    const connection = new classType(serializationObject.name, serializationObject._connectionType, ownerBlock, richType, defaultValue, !!serializationObject._optional);\n    connection.deserialize(serializationObject);\n    return connection;\n}\n\n/**\n * Parses a rich type from a serialization object.\n * @param serializationObject a serialization object\n * @returns the parsed rich type\n */\nfunction ParseRichType(serializationObject: any): RichType<any> {\n    return new RichType(serializationObject.typeName, serializationObject.defaultValue);\n}\n","import { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { type IPathToObjectConverter, type IObjectInfo } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\n\r\n/**\r\n * @deprecated Avoid using this on the flow-graph (glTF only)\r\n * A path converter that converts a path on the flow graph context variables to an object accessor.\r\n */\r\nexport class FlowGraphPathConverter implements IPathToObjectConverter<IObjectAccessor> {\r\n    public constructor(\r\n        private _context: FlowGraphContext,\r\n        private _separator: string = \"/\"\r\n    ) {}\r\n\r\n    public convert(path: string): IObjectInfo<IObjectAccessor> {\r\n        const parts = path.split(this._separator);\r\n        if (parts.length < 2) {\r\n            throw new Error(`Path ${path} is invalid`);\r\n        }\r\n        let currentObject = this._context.getVariable(parts[0]);\r\n        const property = parts[parts.length - 1];\r\n        for (let i = 1; i < parts.length - 1; i++) {\r\n            currentObject = currentObject[parts[i]];\r\n        }\r\n        return {\r\n            object: currentObject,\r\n            info: {\r\n                type: \"object\",\r\n                get: () => currentObject[property],\r\n                set: (value: any) => (currentObject[property] = value),\r\n                getTarget: () => currentObject,\r\n                getPropertyName: [() => property],\r\n            },\r\n        };\r\n    }\r\n}\r\n","import { type IObjectInfo, type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"./flowGraphDataConnection\";\r\nimport { FlowGraphInteger } from \"./CustomTypes/flowGraphInteger.pure\";\r\nimport { RichTypeAny } from \"./flowGraphRichTypes.pure\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\n\r\n// JSON Pointer templates may use either bracket style:\r\n//   {name}  → a reference template parameter.\r\n//   [name]  → an integer template parameter.\r\n// Real-world assets mix both conventions, so the bracket style by itself is not enough to determine\r\n// the input's type. We therefore accept both and decide how to substitute at resolution time based\r\n// on the runtime value supplied to the input socket (FlowGraphInteger / number → int substitution,\r\n// string → reference substitution by extracting the matching JSON-Pointer segment).\r\n// These are constructed per scan rather than shared, because a global regex carries `lastIndex`\r\n// state across calls and a scan that throws part-way would otherwise leave it set for the next one.\r\nconst CreateRefTemplateRegex = () => new RegExp(/\\/\\{(\\w+)\\}(?=\\/|$)/g);\r\nconst CreateIntTemplateRegex = () => new RegExp(/\\/\\[(\\w+)\\](?=\\/|$)/g);\r\n\r\ninterface IPathTemplateInfo {\r\n    /** Template variable name (without surrounding brackets). */\r\n    name: string;\r\n    /** Bracket style used in the source path; preserved so we replace the right placeholder. */\r\n    style: \"curly\" | \"square\";\r\n    /** The connection that supplies the runtime value for substitution. */\r\n    connection: FlowGraphDataConnection<any>;\r\n}\r\n\r\n/**\r\n * @experimental\r\n * A component that converts a path to an object accessor.\r\n */\r\nexport class FlowGraphPathConverterComponent {\r\n    /**\r\n     * The templated inputs for the provided path. Values may be FlowGraphInteger, number, or\r\n     * string (an opaque reference encoded as a JSON Pointer).\r\n     */\r\n    public readonly templatedInputs: FlowGraphDataConnection<any>[] = [];\r\n\r\n    /** Per-template metadata (name + bracket style + input connection). */\r\n    public readonly templateInfos: IPathTemplateInfo[] = [];\r\n\r\n    public constructor(\r\n        public path: string,\r\n        public ownerBlock: FlowGraphBlock\r\n    ) {\r\n        const templateSet = new Set<string>();\r\n\r\n        const collect = (regex: RegExp, style: \"curly\" | \"square\") => {\r\n            let match = regex.exec(path);\r\n            while (match) {\r\n                const [, name] = match;\r\n                if (templateSet.has(name)) {\r\n                    throw new Error(\"Duplicate template variable detected.\");\r\n                }\r\n                templateSet.add(name);\r\n                // Use RichTypeAny so the same socket can receive either an integer (legacy /\r\n                // [name] style) or a string ref (post-ref-update {name} style); the value's\r\n                // runtime type drives the substitution behaviour in getAccessor. Default to\r\n                // FlowGraphInteger(0) — not undefined — so an unconnected index input still\r\n                // resolves to index 0 (the natural default) instead of throwing at path resolution.\r\n                const conn = ownerBlock.registerDataInput(name, RichTypeAny, new FlowGraphInteger(0));\r\n                this.templatedInputs.push(conn);\r\n                this.templateInfos.push({ name, style, connection: conn });\r\n                match = regex.exec(path);\r\n            }\r\n        };\r\n\r\n        collect(CreateRefTemplateRegex(), \"curly\");\r\n        collect(CreateIntTemplateRegex(), \"square\");\r\n    }\r\n\r\n    /**\r\n     * Get the accessor for the path.\r\n     * @param pathConverter the path converter to use to convert the path to an object accessor.\r\n     * @param context the context to use.\r\n     * @returns the accessor for the path.\r\n     * @throws if the value for a templated input is invalid.\r\n     */\r\n    public getAccessor(pathConverter: IPathToObjectConverter<IObjectAccessor>, context: FlowGraphContext): IObjectInfo<IObjectAccessor> {\r\n        let finalPath = this.path;\r\n        for (const info of this.templateInfos) {\r\n            const raw = info.connection.getValue(context);\r\n            const placeholder = info.style === \"curly\" ? `{${info.name}}` : `[${info.name}]`;\r\n            const substitution = ResolveTemplateSubstitution(this.path, info.name, raw, context);\r\n            finalPath = finalPath.replace(placeholder, substitution);\r\n        }\r\n        return pathConverter.convert(finalPath);\r\n    }\r\n}\r\n\r\n/**\r\n * Decide what string to splice into a templated path for a given runtime value.\r\n *\r\n * - FlowGraphInteger / number → use the integer's decimal representation.\r\n * - string → treat as a JSON Pointer to an object and pull the segment whose position\r\n *   in the ref matches the position of `{name}` (or `[name]`) in the surrounding template.\r\n *   Falls back to the last non-empty segment, then to the raw ref string.\r\n * - object → ask the host environment for the reference addressing it, then substitute as above.\r\n * @param template the original templated path (used to locate the placeholder position)\r\n * @param name the name of the template parameter being resolved\r\n * @param raw the runtime value supplied for the template parameter\r\n * @param context the context used to reach the host resolver for object values\r\n * @returns the substring to splice into the templated path in place of the placeholder\r\n */\r\nfunction ResolveTemplateSubstitution(template: string, name: string, raw: any, context: FlowGraphContext): string {\r\n    if (raw instanceof FlowGraphInteger) {\r\n        AssertNonNegativeInt(raw.value, name);\r\n        return raw.value.toString();\r\n    }\r\n    if (typeof raw === \"number\") {\r\n        AssertNonNegativeInt(raw, name);\r\n        return raw.toString();\r\n    }\r\n    if (typeof raw === \"string\") {\r\n        if (raw === \"\") {\r\n            throw new Error(`Templated reference input \"${name}\" is null.`);\r\n        }\r\n        return ExtractRefSubstitution(template, name, raw);\r\n    }\r\n    // A runtime object (e.g. a Mesh delivered by a selection event). Mapping it back to a\r\n    // reference is knowledge the host environment owns, so it is delegated to the host resolver.\r\n    // The segment preceding the placeholder (e.g. \"nodes\" in `/nodes/{nodeRef}/globalMatrix`) is\r\n    // passed as a hint, because an object may be addressable in more than one way.\r\n    if (raw && typeof raw === \"object\") {\r\n        const pointer = context.getObjectReference(raw as object, GetPlaceholderParentSegment(template, name));\r\n        if (pointer) {\r\n            return ExtractRefSubstitution(template, name, pointer);\r\n        }\r\n    }\r\n    throw new Error(`Invalid value for templated input \"${name}\": got ${typeof raw}.`);\r\n}\r\n\r\nfunction GetPlaceholderIndex(template: string, name: string): number {\r\n    const placeholders = [`{${name}}`, `[${name}]`];\r\n    return template.split(\"/\").findIndex((segment) => placeholders.indexOf(segment) >= 0);\r\n}\r\n\r\nfunction GetPlaceholderParentSegment(template: string, name: string): string | undefined {\r\n    const placeholderIndex = GetPlaceholderIndex(template, name);\r\n    return placeholderIndex > 0 ? template.split(\"/\")[placeholderIndex - 1] : undefined;\r\n}\r\n\r\nfunction AssertNonNegativeInt(value: number, name: string): void {\r\n    if (typeof value !== \"number\" || value < 0 || !Number.isFinite(value)) {\r\n        throw new Error(`Invalid value for templated input \"${name}\": ${value}.`);\r\n    }\r\n}\r\n\r\nfunction ExtractRefSubstitution(template: string, name: string, refValue: string): string {\r\n    const templateSegments = template.split(\"/\");\r\n    const placeholders = [`{${name}}`, `[${name}]`];\r\n    const placeholderIndex = templateSegments.findIndex((s) => placeholders.indexOf(s) >= 0);\r\n    const refSegments = refValue.split(\"/\");\r\n    if (placeholderIndex >= 0 && placeholderIndex < refSegments.length && refSegments[placeholderIndex] !== \"\") {\r\n        return refSegments[placeholderIndex];\r\n    }\r\n    for (let i = refSegments.length - 1; i >= 0; i--) {\r\n        if (refSegments[i] !== \"\") {\r\n            return refSegments[i];\r\n        }\r\n    }\r\n    return refValue;\r\n}\r\n","/**\r\n * Tracking of the delays that are currently scheduled in a flow graph context.\r\n *\r\n * `flow/setDelay` produces a unique integer handle for every delayed activation it schedules.\r\n * This module records which of those handles are still pending — i.e. scheduled and not yet fired\r\n * or cancelled — per {@link FlowGraphContext}, so that a host can answer \"is this delay handle\r\n * still valid?\" for a reference it was handed earlier.\r\n */\r\n\r\nimport { type FlowGraphContext } from \"./flowGraphContext\";\r\n\r\n/**\r\n * Name of the global context variable holding the set of active delay handles.\r\n * @internal\r\n */\r\nconst ActiveDelayIndicesKey = \"activeDelayIndices\";\r\n\r\nfunction GetActiveDelaySet(context: FlowGraphContext): Set<number> {\r\n    let set = context._getGlobalContextVariable<Set<number> | null>(ActiveDelayIndicesKey, null);\r\n    if (!set) {\r\n        set = new Set<number>();\r\n        context._setGlobalContextVariable(ActiveDelayIndicesKey, set);\r\n    }\r\n    return set;\r\n}\r\n\r\n/**\r\n * Marks the given delay handle as active (scheduled and pending) in the context.\r\n * Called by `flow/setDelay` when it schedules a new delayed activation.\r\n * @param context the flow graph context owning the delay.\r\n * @param index the unique delay handle produced by `flow/setDelay`.\r\n */\r\nexport function MarkDelayActive(context: FlowGraphContext, index: number): void {\r\n    GetActiveDelaySet(context).add(index);\r\n}\r\n\r\n/**\r\n * Marks the given delay handle as no longer active. Called when a delay fires, is cancelled via\r\n * the `cancel` input, or is cancelled by `flow/cancelDelay`.\r\n * @param context the flow graph context owning the delay.\r\n * @param index the unique delay handle to clear.\r\n */\r\nexport function MarkDelayInactive(context: FlowGraphContext, index: number): void {\r\n    context._getGlobalContextVariable<Set<number> | null>(ActiveDelayIndicesKey, null)?.delete(index);\r\n}\r\n\r\n/**\r\n * Returns whether the given delay handle is currently active, i.e. scheduled and not yet fired or\r\n * cancelled.\r\n * @param context the flow graph context to query.\r\n * @param index the delay handle to test.\r\n * @returns true if the delay is currently scheduled and has not yet fired or been cancelled.\r\n */\r\nexport function IsDelayActive(context: FlowGraphContext, index: number): boolean {\r\n    return context._getGlobalContextVariable<Set<number> | null>(ActiveDelayIndicesKey, null)?.has(index) ?? false;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { RichTypeAny, RichTypeString } from \"../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Configuration for the console log block.\r\n */\r\nexport interface IFlowGraphConsoleLogBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * An optional message template to use for the log message.\r\n     * If provided, the template can hold placeholders for the message value.\r\n     * For example, if the template is \"The message is: \\{data\\}\", a new data input called \"data\" will be created.\r\n     * The value of the message input will be used to replace the placeholder in the template.\r\n     */\r\n    messageTemplate?: string;\r\n}\r\n\r\n/**\r\n * Block that logs a message to the console.\r\n */\r\nexport class FlowGraphConsoleLogBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input connection: The message to log.\r\n     * Will be ignored if a message template is provided.\r\n     */\r\n    public readonly message: FlowGraphDataConnection<any>;\r\n\r\n    /**\r\n     * Input connection: The log type.\r\n     */\r\n    public readonly logType: FlowGraphDataConnection<\"log\" | \"warn\" | \"error\">;\r\n\r\n    /**\r\n     * Creates a new console log block.\r\n     * @param config optional configuration\r\n     */\r\n    public constructor(config?: IFlowGraphConsoleLogBlockConfiguration) {\r\n        super(config);\r\n        this.message = this.registerDataInput(\"message\", RichTypeAny);\r\n        this.logType = this.registerDataInput(\"logType\", RichTypeString, \"log\") as FlowGraphDataConnection<\"log\" | \"warn\" | \"error\">;\r\n        if (typeof config?.messageTemplate === \"string\") {\r\n            const matches = this._getTemplateMatches(config.messageTemplate);\r\n            const registered = new Set<string>();\r\n            for (const match of matches) {\r\n                if (!registered.has(match.name)) {\r\n                    registered.add(match.name);\r\n                    this.registerDataInput(match.name, RichTypeAny);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _execute(context: FlowGraphContext): void {\r\n        const typeValue = this.logType.getValue(context);\r\n        const messageValue = this._getMessageValue(context);\r\n        if (typeValue === \"warn\") {\r\n            Logger.Warn(messageValue);\r\n        } else if (typeValue === \"error\") {\r\n            Logger.Error(messageValue);\r\n        } else {\r\n            Logger.Log(messageValue);\r\n        }\r\n        // activate the output flow block\r\n        this.out._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.ConsoleLog;\r\n    }\r\n\r\n    private _serializeValue(value: any): string {\r\n        if (value === null || value === undefined) {\r\n            return String(value);\r\n        }\r\n        if (typeof value === \"object\") {\r\n            // Prefer the object's own toString() (e.g. Vector3 → \"{X:1 Y:2 Z:3}\").\r\n            // Only fall back to JSON.stringify when toString() is the unhelpful default.\r\n            const str = value.toString();\r\n            if (str === \"[object Object]\") {\r\n                try {\r\n                    return JSON.stringify(value);\r\n                } catch {\r\n                    return str;\r\n                }\r\n            }\r\n            return str;\r\n        }\r\n        return String(value);\r\n    }\r\n\r\n    private _getMessageValue(context: FlowGraphContext): string {\r\n        if (typeof this.config?.messageTemplate === \"string\") {\r\n            let template: string = this.config.messageTemplate;\r\n            const matches = this._getTemplateMatches(template);\r\n            // If the message input is an object, use its keys as the primary\r\n            // source for template placeholders, falling back to named data inputs.\r\n            const messageValue = this.message.getValue(context);\r\n            const messageObj = messageValue !== null && messageValue !== undefined && typeof messageValue === \"object\" ? messageValue : null;\r\n            const replacements = new Map<string, string | undefined>();\r\n            for (const match of matches) {\r\n                if (replacements.has(match.name)) {\r\n                    continue;\r\n                }\r\n                let value: any;\r\n                if (messageObj !== null && match.name in messageObj) {\r\n                    value = messageObj[match.name];\r\n                } else {\r\n                    value = this.getDataInput(match.name)?.getValue(context);\r\n                }\r\n                replacements.set(match.name, value === undefined ? undefined : this._serializeValue(value).replace(/[{}]/g, \"$&$&\"));\r\n            }\r\n            for (let index = matches.length - 1; index >= 0; index--) {\r\n                const match = matches[index];\r\n                const serialized = replacements.get(match.name);\r\n                if (serialized !== undefined) {\r\n                    template = template.substring(0, match.start) + serialized + template.substring(match.end + 1);\r\n                }\r\n            }\r\n            return template.replace(/\\{\\{/g, \"{\").replace(/\\}\\}/g, \"}\");\r\n        } else {\r\n            // No template — pass the raw value directly so Logger receives the original\r\n            // object (e.g. Vector3) rather than a stringified representation.\r\n            return this.message.getValue(context);\r\n        }\r\n    }\r\n\r\n    private _getTemplateMatches(template: string): { name: string; start: number; end: number }[] {\r\n        let state = 0;\r\n        let parameterStart = -1;\r\n        const matches: { name: string; start: number; end: number }[] = [];\r\n        for (let index = 0; index < template.length; index++) {\r\n            const character = template[index];\r\n            if (character === \"{\") {\r\n                if (state === 0) {\r\n                    state = 1;\r\n                } else if (state === 1) {\r\n                    state = 0;\r\n                } else {\r\n                    return [];\r\n                }\r\n            } else if (character === \"}\") {\r\n                if (state === 0) {\r\n                    state = 3;\r\n                } else if (state === 3) {\r\n                    state = 0;\r\n                } else if (state === 2) {\r\n                    matches.push({\r\n                        name: template.substring(parameterStart + 1, index),\r\n                        start: parameterStart,\r\n                        end: index,\r\n                    });\r\n                    state = 0;\r\n                } else {\r\n                    return [];\r\n                }\r\n            } else if (state === 1) {\r\n                parameterStart = index - 1;\r\n                state = 2;\r\n            } else if (state === 3) {\r\n                return [];\r\n            }\r\n        }\r\n        return state === 0 ? matches : [];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphConsoleLogBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphConsoleLogBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.ConsoleLog, FlowGraphConsoleLogBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { RichTypeBoolean } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlock } from \"../../../flowGraphExecutionBlock\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * A block that evaluates a condition and activates one of two branches.\r\n */\r\nexport class FlowGraphBranchBlock extends FlowGraphExecutionBlock {\r\n    /**\r\n     * Input connection: The condition to evaluate.\r\n     */\r\n    public readonly condition: FlowGraphDataConnection<boolean>;\r\n    /**\r\n     * Output connection: The branch to execute if the condition is true.\r\n     */\r\n    public readonly onTrue: FlowGraphSignalConnection;\r\n    /**\r\n     * Output connection: The branch to execute if the condition is false.\r\n     */\r\n    public readonly onFalse: FlowGraphSignalConnection;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n\r\n        this.condition = this.registerDataInput(\"condition\", RichTypeBoolean);\r\n\r\n        this.onTrue = this._registerSignalOutput(\"onTrue\");\r\n        this.onFalse = this._registerSignalOutput(\"onFalse\");\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext): void {\r\n        if (this.condition.getValue(context)) {\r\n            this.onTrue._activateSignal(context);\r\n        } else {\r\n            this.onFalse._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Branch;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphBranchBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphBranchBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Branch, FlowGraphBranchBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeFlowGraphInteger } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphInteger } from \"../../../CustomTypes/flowGraphInteger.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Configuration for the DoN block.\r\n */\r\nexport interface IFlowGraphDoNBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The start index for the counter.\r\n     */\r\n    startIndex?: FlowGraphInteger;\r\n}\r\n/**\r\n * A block that executes a branch a set number of times.\r\n */\r\nexport class FlowGraphDoNBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input connection: Resets the counter\r\n     */\r\n    public readonly reset: FlowGraphSignalConnection;\r\n    /**\r\n     * Input connection: The maximum number of times the block can be executed.\r\n     */\r\n    public readonly maxExecutions: FlowGraphDataConnection<FlowGraphInteger>;\r\n    /**\r\n     * Output connection: The number of times the block has been executed.\r\n     */\r\n    public readonly executionCount: FlowGraphDataConnection<FlowGraphInteger>;\r\n\r\n    constructor(\r\n        /**\r\n         * [Object] the configuration of the block\r\n         */\r\n        public override config: IFlowGraphDoNBlockConfiguration = {}\r\n    ) {\r\n        super(config);\r\n        this.config.startIndex = config.startIndex ?? new FlowGraphInteger(0);\r\n        this.reset = this._registerSignalInput(\"reset\");\r\n        this.maxExecutions = this.registerDataInput(\"maxExecutions\", RichTypeFlowGraphInteger);\r\n        this.executionCount = this.registerDataOutput(\"executionCount\", RichTypeFlowGraphInteger, new FlowGraphInteger(0));\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\r\n        if (callingSignal === this.reset) {\r\n            this.executionCount.setValue(this.config.startIndex!, context);\r\n        } else {\r\n            const currentCountValue = this.executionCount.getValue(context);\r\n            if (currentCountValue.value < this.maxExecutions.getValue(context).value) {\r\n                this.executionCount.setValue(new FlowGraphInteger(currentCountValue.value + 1), context);\r\n                this.out._activateSignal(context);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.DoN;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphDoNBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphDoNBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.DoN, FlowGraphDoNBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"core/FlowGraph/flowGraphExecutionBlockWithOutSignal\";\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { RichTypeAny, RichTypeFlowGraphInteger, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { type FlowGraphNumber, getNumericValue } from \"core/FlowGraph/utils\";\r\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Configuration for the For Loop block.\r\n */\r\nexport interface IFlowGraphForLoopBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The initial index of the loop.\r\n     * if not set will default to 0\r\n     */\r\n    initialIndex?: FlowGraphNumber;\r\n\r\n    /**\r\n     * If set to true, the index of the case will be incremented when the loop is done.\r\n     * This will result that the index will equal endIndex when the loop finished its work.\r\n     * This is the default behavior in glTF interactivity\r\n     */\r\n    incrementIndexWhenLoopDone?: boolean;\r\n\r\n    /**\r\n     * Overrides {@link FlowGraphForLoopBlock.MaxLoopIterations} for this block only.\r\n     * Lets a single graph opt into a higher (or lower) runaway-loop guard without changing the\r\n     * process-wide default that every other FlowGraph relies on.\r\n     */\r\n    maxLoopIterations?: number;\r\n}\r\n/**\r\n * Block that executes an action in a loop.\r\n */\r\nexport class FlowGraphForLoopBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * The default maximum number of iterations allowed for the loop, used as a safety net against\r\n     * runaway loops. Kept conservative so a runaway loop is caught before it can freeze the tab.\r\n     * A single graph that legitimately needs more iterations should set the per-block\r\n     * {@link IFlowGraphForLoopBlockConfiguration.maxLoopIterations} rather than raising this\r\n     * process-wide default that every other FlowGraph relies on.\r\n     */\r\n    public static MaxLoopIterations = 1000;\r\n    /**\r\n     * Input connection: The start index of the loop.\r\n     */\r\n    public readonly startIndex: FlowGraphDataConnection<FlowGraphNumber>;\r\n    /**\r\n     * Input connection: The end index of the loop.\r\n     */\r\n    public readonly endIndex: FlowGraphDataConnection<FlowGraphNumber>;\r\n    /**\r\n     * Input connection: The step of the loop.\r\n     */\r\n    public readonly step: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: The current index of the loop.\r\n     */\r\n    public readonly index: FlowGraphDataConnection<FlowGraphInteger>;\r\n    /**\r\n     * Output connection: The signal that is activated when the loop body is executed.\r\n     */\r\n    public readonly executionFlow: FlowGraphSignalConnection;\r\n\r\n    /**\r\n     * Output connection: The completed signal. Triggered when condition is false.\r\n     * No out signal is available.\r\n     */\r\n    public readonly completed: FlowGraphSignalConnection;\r\n\r\n    public constructor(config?: IFlowGraphForLoopBlockConfiguration) {\r\n        super(config);\r\n\r\n        this.startIndex = this.registerDataInput(\"startIndex\", RichTypeAny, 0);\r\n        this.endIndex = this.registerDataInput(\"endIndex\", RichTypeAny);\r\n        this.step = this.registerDataInput(\"step\", RichTypeNumber, 1);\r\n\r\n        this.index = this.registerDataOutput(\"index\", RichTypeFlowGraphInteger, new FlowGraphInteger(getNumericValue(config?.initialIndex ?? 0)));\r\n        this.executionFlow = this._registerSignalOutput(\"executionFlow\");\r\n        this.completed = this._registerSignalOutput(\"completed\");\r\n\r\n        this._unregisterSignalOutput(\"out\");\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _execute(context: FlowGraphContext): void {\r\n        const index = getNumericValue(this.startIndex.getValue(context));\r\n        const step = this.step.getValue(context);\r\n        let endIndex = getNumericValue(this.endIndex.getValue(context));\r\n        // Per-block override of the runaway-loop guard, falling back to the process-wide default.\r\n        const maxIterations = (this.config as IFlowGraphForLoopBlockConfiguration | undefined)?.maxLoopIterations ?? FlowGraphForLoopBlock.MaxLoopIterations;\r\n        let iterations = 0;\r\n        let truncated = false;\r\n        for (let i = index; i < endIndex; i += step) {\r\n            this.index.setValue(new FlowGraphInteger(i), context);\r\n            this.executionFlow._activateSignal(context);\r\n            endIndex = getNumericValue(this.endIndex.getValue(context));\r\n            // Safety net against runaway loops. The cap counts iterations (not the index value) so it\r\n            // behaves correctly regardless of startIndex/step.\r\n            if (++iterations >= maxIterations) {\r\n                truncated = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (truncated) {\r\n            // The loop hit its safety cap before its range completed, so the outputs below are for a\r\n            // truncated run, not a natural finish. Warn so a genuinely runaway asset is diagnosable\r\n            // rather than silently producing wrong numbers (the completed signal still fires, and\r\n            // incrementIndexWhenLoopDone will not land on endIndex).\r\n            Logger.Warn(`FlowGraphForLoopBlock: loop stopped after reaching the ${maxIterations}-iteration safety cap before its range completed.`);\r\n        }\r\n\r\n        if (this.config?.incrementIndexWhenLoopDone) {\r\n            this.index.setValue(new FlowGraphInteger(getNumericValue(this.index.getValue(context)) + step), context);\r\n        }\r\n\r\n        this.completed._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.ForLoop;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphForLoopBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphForLoopBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.ForLoop, FlowGraphForLoopBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * A block that throttles the execution of its output flow.\r\n */\r\nexport class FlowGraphThrottleBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input connection: The duration of the throttle, in seconds.\r\n     */\r\n    public readonly duration: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: Resets the throttle.\r\n     */\r\n    public readonly reset: FlowGraphSignalConnection;\r\n    /**\r\n     * Output connection: The time remaining before the throttle is triggering again, in seconds.\r\n     */\r\n    public readonly lastRemainingTime: FlowGraphDataConnection<number>;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.reset = this._registerSignalInput(\"reset\");\r\n        this.duration = this.registerDataInput(\"duration\", RichTypeNumber);\r\n        this.lastRemainingTime = this.registerDataOutput(\"lastRemainingTime\", RichTypeNumber, NaN);\r\n    }\r\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\r\n        if (callingSignal === this.reset) {\r\n            this.lastRemainingTime.setValue(NaN, context);\r\n            context._setExecutionVariable(this, \"lastRemainingTime\", NaN);\r\n            context._setExecutionVariable(this, \"timestamp\", 0);\r\n            return;\r\n        }\r\n        // in seconds\r\n        const durationValue = this.duration.getValue(context);\r\n        if (durationValue <= 0 || isNaN(durationValue) || !isFinite(durationValue)) {\r\n            return this._reportError(context, \"Invalid duration in Throttle block\");\r\n        }\r\n        const lastRemainingTime = context._getExecutionVariable(this, \"lastRemainingTime\", NaN);\r\n        // Using Date.now() to get ms since epoch. not using performance.now() because its precision is not needed here\r\n        const currentTime = Date.now();\r\n        if (isNaN(lastRemainingTime)) {\r\n            this.lastRemainingTime.setValue(0, context);\r\n            context._setExecutionVariable(this, \"lastRemainingTime\", 0);\r\n            context._setExecutionVariable(this, \"timestamp\", currentTime);\r\n            // according to glTF interactivity specs\r\n            return this.out._activateSignal(context);\r\n        } else {\r\n            const elapsedTime = currentTime - context._getExecutionVariable(this, \"timestamp\", 0);\r\n            // duration is in seconds, so we need to multiply by 1000\r\n            const durationInMs = durationValue * 1000;\r\n            if (durationInMs <= elapsedTime) {\r\n                this.lastRemainingTime.setValue(0, context);\r\n                context._setExecutionVariable(this, \"lastRemainingTime\", 0);\r\n                context._setExecutionVariable(this, \"timestamp\", currentTime);\r\n                return this.out._activateSignal(context);\r\n            } else {\r\n                const remainingTime = durationInMs - elapsedTime;\r\n                // output is in seconds\r\n                this.lastRemainingTime.setValue(remainingTime / 1000, context);\r\n                context._setExecutionVariable(this, \"lastRemainingTime\", remainingTime);\r\n            }\r\n        }\r\n    }\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Throttle;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphThrottleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphThrottleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Throttle, FlowGraphThrottleBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlock } from \"../../../flowGraphExecutionBlock\";\r\nimport { RichTypeFlowGraphInteger } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Configuration for the multi gate block.\r\n */\r\nexport interface IFlowGraphMultiGateBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The number of output signals. Required.\r\n     */\r\n    outputSignalCount: number;\r\n    /**\r\n     * If the block should pick a random output flow from the ones that haven't been executed. Default to false.\r\n     */\r\n    isRandom?: boolean;\r\n    /**\r\n     * If the block should loop back to the first output flow after executing the last one. Default to false.\r\n     */\r\n    isLoop?: boolean;\r\n}\r\n\r\n/**\r\n * A block that has an input flow and routes it to any potential output flows, randomly or sequentially\r\n */\r\nexport class FlowGraphMultiGateBlock extends FlowGraphExecutionBlock {\r\n    /**\r\n     * Input connection: Resets the gate.\r\n     */\r\n    public readonly reset: FlowGraphSignalConnection;\r\n    /**\r\n     * Output connections: The output signals.\r\n     */\r\n    public readonly outputSignals: FlowGraphSignalConnection[] = [];\r\n    /**\r\n     * Output connection: The index of the current output flow.\r\n     */\r\n    public readonly lastIndex: FlowGraphDataConnection<FlowGraphInteger>;\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphMultiGateBlockConfiguration\r\n    ) {\r\n        super(config);\r\n        this.reset = this._registerSignalInput(\"reset\");\r\n        this.lastIndex = this.registerDataOutput(\"lastIndex\", RichTypeFlowGraphInteger, new FlowGraphInteger(-1));\r\n        this.setNumberOfOutputSignals(config?.outputSignalCount);\r\n    }\r\n\r\n    private _getNextIndex(indexesUsed: boolean[]): number {\r\n        // find the next index available from the indexes used array\r\n\r\n        // if all outputs were used, reset the indexes used array if we are in a loop multi gate\r\n        if (!indexesUsed.includes(false)) {\r\n            if (this.config.isLoop) {\r\n                indexesUsed.fill(false);\r\n            }\r\n        }\r\n        if (!this.config.isRandom) {\r\n            return indexesUsed.indexOf(false);\r\n        } else {\r\n            const unusedIndexes = indexesUsed.map((used, index) => (used ? -1 : index)).filter((index) => index !== -1);\r\n            return unusedIndexes.length ? unusedIndexes[Math.floor(Math.random() * unusedIndexes.length)] : -1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the block's output signals. Would usually be passed from the constructor but can be changed afterwards.\r\n     * @param numberOutputSignals the number of output flows\r\n     */\r\n    public setNumberOfOutputSignals(numberOutputSignals: number = 1) {\r\n        // check the size of the outFlow Array, see if it is not larger than needed\r\n        while (this.outputSignals.length > numberOutputSignals) {\r\n            const flow = this.outputSignals.pop();\r\n            if (flow) {\r\n                flow.disconnectFromAll();\r\n                this._unregisterSignalOutput(flow.name);\r\n            }\r\n        }\r\n\r\n        while (this.outputSignals.length < numberOutputSignals) {\r\n            this.outputSignals.push(this._registerSignalOutput(`out_${this.outputSignals.length}`));\r\n        }\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\r\n        // set the state(s) of the block\r\n        if (!context._hasExecutionVariable(this, \"indexesUsed\")) {\r\n            context._setExecutionVariable(\r\n                this,\r\n                \"indexesUsed\",\r\n                this.outputSignals.map(() => false)\r\n            );\r\n        }\r\n\r\n        if (callingSignal === this.reset) {\r\n            context._deleteExecutionVariable(this, \"indexesUsed\");\r\n            this.lastIndex.setValue(new FlowGraphInteger(-1), context);\r\n            return;\r\n        }\r\n        const indexesUsed = context._getExecutionVariable(this, \"indexesUsed\", [] as boolean[]);\r\n        const nextIndex = this._getNextIndex(indexesUsed);\r\n        if (nextIndex > -1) {\r\n            this.lastIndex.setValue(new FlowGraphInteger(nextIndex), context);\r\n            indexesUsed[nextIndex] = true;\r\n            context._setExecutionVariable(this, \"indexesUsed\", indexesUsed);\r\n            this.outputSignals[nextIndex]._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.MultiGate;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block.\r\n     * @param serializationObject the object to serialize to.\r\n     */\r\n    public override serialize(serializationObject?: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.config.outputSignalCount = this.config.outputSignalCount;\r\n        serializationObject.config.isRandom = this.config.isRandom;\r\n        serializationObject.config.loop = this.config.isLoop;\r\n        serializationObject.config.startIndex = this.config.startIndex;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphMultiGateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphMultiGateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.MultiGate, FlowGraphMultiGateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlock } from \"../../../flowGraphExecutionBlock\";\r\nimport { RichTypeAny } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { type FlowGraphNumber, getNumericValue, isNumeric } from \"core/FlowGraph/utils\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Configuration for a switch block.\r\n */\r\nexport interface IFlowGraphSwitchBlockConfiguration<T> extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The possible values for the selection.\r\n     */\r\n    cases: T[];\r\n}\r\n\r\n/**\r\n * A block that executes a branch based on a selection.\r\n */\r\nexport class FlowGraphSwitchBlock<T extends FlowGraphNumber> extends FlowGraphExecutionBlock {\r\n    /**\r\n     * Input connection: The value of the selection.\r\n     */\r\n    public readonly case: FlowGraphDataConnection<T>;\r\n\r\n    /**\r\n     * The default case to execute if no other case is found.\r\n     */\r\n    public readonly default: FlowGraphSignalConnection = this._registerSignalOutput(\"default\");\r\n\r\n    private _caseToOutputFlow: Map<T, FlowGraphSignalConnection> = new Map();\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphSwitchBlockConfiguration<T>\r\n    ) {\r\n        super(config);\r\n\r\n        this.case = this.registerDataInput(\"case\", RichTypeAny);\r\n\r\n        // iterate the set not using for of\r\n        const array = this.config.cases || [];\r\n        for (const caseValue of array) {\r\n            this._caseToOutputFlow.set(caseValue, this._registerSignalOutput(`out_${caseValue}`));\r\n        }\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\r\n        const selectionValue = this.case.getValue(context);\r\n        let outputFlow: FlowGraphSignalConnection | undefined;\r\n        if (isNumeric(selectionValue)) {\r\n            outputFlow = this._getOutputFlowForCase(getNumericValue(selectionValue) as T);\r\n        } else {\r\n            outputFlow = this._getOutputFlowForCase(selectionValue);\r\n        }\r\n\r\n        if (outputFlow) {\r\n            outputFlow._activateSignal(context);\r\n        } else {\r\n            this.default._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a new case to the switch block.\r\n     * @param newCase the new case to add.\r\n     */\r\n    public addCase(newCase: T): void {\r\n        if (this.config.cases.includes(newCase)) {\r\n            return;\r\n        }\r\n        this.config.cases.push(newCase);\r\n        this._caseToOutputFlow.set(newCase, this._registerSignalOutput(`out_${newCase}`));\r\n    }\r\n\r\n    /**\r\n     * Removes a case from the switch block.\r\n     * @param caseToRemove the case to remove.\r\n     */\r\n    public removeCase(caseToRemove: T): void {\r\n        if (!this.config.cases.includes(caseToRemove)) {\r\n            return;\r\n        }\r\n        const index = this.config.cases.indexOf(caseToRemove);\r\n        this.config.cases.splice(index, 1);\r\n        this._caseToOutputFlow.delete(caseToRemove);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getOutputFlowForCase(caseValue: T) {\r\n        return this._caseToOutputFlow.get(caseValue);\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Switch;\r\n    }\r\n\r\n    /**\r\n     * Serialize the block to a JSON representation.\r\n     * @param serializationObject the object to serialize to.\r\n     */\r\n    public override serialize(serializationObject?: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.cases = this.config.cases;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphSwitchBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphSwitchBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Switch, FlowGraphSwitchBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { RichTypeFlowGraphInteger } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Configuration for the wait all block.\r\n */\r\nexport interface IFlowGraphWaitAllBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The number of input signals. There will always be at least one input flow.\r\n     * glTF interactivity has a max of 64 input flows.\r\n     */\r\n    inputSignalCount: number;\r\n}\r\n\r\n/**\r\n * A block that waits for all input flows to be activated before activating its output flow.\r\n */\r\nexport class FlowGraphWaitAllBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input connection: Resets the block.\r\n     */\r\n    public reset: FlowGraphSignalConnection;\r\n\r\n    /**\r\n     * Output connection:When the last missing flow is activated\r\n     */\r\n    public completed: FlowGraphSignalConnection;\r\n\r\n    /**\r\n     * Output connection: The number of remaining inputs to be activated.\r\n     */\r\n    public remainingInputs: FlowGraphDataConnection<FlowGraphInteger>;\r\n    /**\r\n     * An array of input signals\r\n     */\r\n    public readonly inFlows: FlowGraphSignalConnection[] = [];\r\n    private _cachedActivationState: boolean[] = [];\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphWaitAllBlockConfiguration\r\n    ) {\r\n        super(config);\r\n\r\n        this.reset = this._registerSignalInput(\"reset\");\r\n        this.completed = this._registerSignalOutput(\"completed\");\r\n        this.remainingInputs = this.registerDataOutput(\"remainingInputs\", RichTypeFlowGraphInteger, new FlowGraphInteger(this.config.inputSignalCount || 0));\r\n        // The first inFlow is the default input signal all execution blocks have\r\n        for (let i = 0; i < this.config.inputSignalCount; i++) {\r\n            this.inFlows.push(this._registerSignalInput(`in_${i}`));\r\n        }\r\n        // no need for in\r\n        this._unregisterSignalInput(\"in\");\r\n    }\r\n\r\n    private _getCurrentActivationState(context: FlowGraphContext) {\r\n        const activationState = this._cachedActivationState;\r\n        activationState.length = 0;\r\n        if (!context._hasExecutionVariable(this, \"activationState\")) {\r\n            for (let i = 0; i < this.config.inputSignalCount; i++) {\r\n                activationState.push(false);\r\n            }\r\n        } else {\r\n            const contextActivationState = context._getExecutionVariable(this, \"activationState\", [] as boolean[]);\r\n            for (let i = 0; i < contextActivationState.length; i++) {\r\n                activationState.push(contextActivationState[i]);\r\n            }\r\n        }\r\n        return activationState;\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\r\n        const activationState = this._getCurrentActivationState(context);\r\n        if (callingSignal === this.reset) {\r\n            for (let i = 0; i < this.config.inputSignalCount; i++) {\r\n                activationState[i] = false;\r\n            }\r\n        } else {\r\n            const index = this.inFlows.indexOf(callingSignal);\r\n            if (index >= 0) {\r\n                activationState[index] = true;\r\n            }\r\n        }\r\n        this.remainingInputs.setValue(new FlowGraphInteger(activationState.filter((v) => !v).length), context);\r\n\r\n        context._setExecutionVariable(this, \"activationState\", activationState.slice());\r\n\r\n        if (!activationState.includes(false)) {\r\n            this.completed._activateSignal(context);\r\n            for (let i = 0; i < this.config.inputSignalCount; i++) {\r\n                activationState[i] = false;\r\n            }\r\n        } else {\r\n            callingSignal !== this.reset && this.out._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.WaitAll;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block into a object\r\n     * @param serializationObject the object to serialize to\r\n     */\r\n    public override serialize(serializationObject?: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.config.inputFlows = this.config.inputSignalCount;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphWaitAllBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphWaitAllBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.WaitAll, FlowGraphWaitAllBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * A block that counts the number of times it has been called.\r\n * Afterwards it activates its out signal.\r\n */\r\nexport class FlowGraphCallCounterBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Output connection: The number of times the block has been called.\r\n     */\r\n    public readonly count: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: Resets the counter.\r\n     */\r\n    public readonly reset: FlowGraphSignalConnection;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n\r\n        this.count = this.registerDataOutput(\"count\", RichTypeNumber);\r\n        this.reset = this._registerSignalInput(\"reset\");\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\r\n        if (callingSignal === this.reset) {\r\n            context._setExecutionVariable(this, \"count\", 0);\r\n            this.count.setValue(0, context);\r\n            return;\r\n        }\r\n        const countValue = context._getExecutionVariable(this, \"count\", 0) + 1;\r\n\r\n        context._setExecutionVariable(this, \"count\", countValue);\r\n        this.count.setValue(countValue, context);\r\n        this.out._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.CallCounter;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphCounterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphCounterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.CallCounter, FlowGraphCallCounterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeBoolean } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Configuration for the while loop block.\r\n */\r\nexport interface IFlowGraphWhileLoopBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * If true, the loop body will be executed at least once.\r\n     */\r\n    doWhile?: boolean;\r\n}\r\n\r\n/**\r\n * A block that executes a branch while a condition is true.\r\n */\r\nexport class FlowGraphWhileLoopBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * The maximum number of iterations allowed in a loop.\r\n     * This can be set to avoid an infinite loop.\r\n     */\r\n    public static MaxLoopCount = 1000;\r\n\r\n    /**\r\n     * Input connection: The condition to evaluate.\r\n     */\r\n    public readonly condition: FlowGraphDataConnection<boolean>;\r\n    /**\r\n     * Output connection: The loop body.\r\n     */\r\n    public readonly executionFlow: FlowGraphSignalConnection;\r\n\r\n    /**\r\n     * Output connection: The completed signal. Triggered when condition is false.\r\n     * No out signal is available.\r\n     */\r\n    public readonly completed: FlowGraphSignalConnection;\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config?: IFlowGraphWhileLoopBlockConfiguration\r\n    ) {\r\n        super(config);\r\n\r\n        this.condition = this.registerDataInput(\"condition\", RichTypeBoolean);\r\n        this.executionFlow = this._registerSignalOutput(\"executionFlow\");\r\n        this.completed = this._registerSignalOutput(\"completed\");\r\n        // unregister \"out\" signal\r\n        this._unregisterSignalOutput(\"out\");\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\r\n        let conditionValue = this.condition.getValue(context);\r\n        if (this.config?.doWhile && !conditionValue) {\r\n            this.executionFlow._activateSignal(context);\r\n        }\r\n        let i = 0;\r\n        while (conditionValue) {\r\n            this.executionFlow._activateSignal(context);\r\n            ++i;\r\n            if (i >= FlowGraphWhileLoopBlock.MaxLoopCount) {\r\n                Logger.Warn(\"FlowGraphWhileLoopBlock: Max loop count reached. Breaking.\");\r\n                break;\r\n            }\r\n            conditionValue = this.condition.getValue(context);\r\n        }\r\n        // out is not triggered - completed is triggered\r\n        this.completed._activateSignal(context);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.WhileLoop;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphWhileLoopBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphWhileLoopBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.WhileLoop, FlowGraphWhileLoopBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"core/FlowGraph/flowGraphSignalConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"core/FlowGraph/flowGraphExecutionBlockWithOutSignal\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * This block debounces the execution of a input, i.e. ensures that the input is only executed once every X times\r\n */\r\nexport class FlowGraphDebounceBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input: The number of times the input must be executed before the onDone signal is activated\r\n     */\r\n    public readonly count: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input: Resets the debounce counter\r\n     */\r\n    public readonly reset: FlowGraphSignalConnection;\r\n    /**\r\n     * Output: The current count of the debounce counter\r\n     */\r\n    public readonly currentCount: FlowGraphDataConnection<number>;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.count = this.registerDataInput(\"count\", RichTypeNumber);\r\n        this.reset = this._registerSignalInput(\"reset\");\r\n        this.currentCount = this.registerDataOutput(\"currentCount\", RichTypeNumber);\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\r\n        if (callingSignal === this.reset) {\r\n            context._setExecutionVariable(this, \"debounceCount\", 0);\r\n            return;\r\n        }\r\n        const count = this.count.getValue(context);\r\n        const currentCount = context._getExecutionVariable(this, \"debounceCount\", 0);\r\n        const newCount = currentCount + 1;\r\n\r\n        this.currentCount.setValue(newCount, context);\r\n        context._setExecutionVariable(this, \"debounceCount\", newCount);\r\n        if (newCount >= count) {\r\n            this.out._activateSignal(context);\r\n            context._setExecutionVariable(this, \"debounceCount\", 0);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Debounce;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphDebounceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphDebounceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Debounce, FlowGraphDebounceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlock } from \"core/FlowGraph/flowGraphExecutionBlock\";\r\nimport { RichTypeBoolean } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { type FlowGraphSignalConnection } from \"core/FlowGraph/flowGraphSignalConnection.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Configuration for the flip flop block.\r\n */\r\nexport interface IFlowGraphFlipFlopBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The starting value of the flip flop switch\r\n     */\r\n    startValue?: boolean;\r\n}\r\n\r\n/**\r\n * This block flip flops between two outputs.\r\n */\r\nexport class FlowGraphFlipFlopBlock extends FlowGraphExecutionBlock {\r\n    /**\r\n     * Output connection: The signal to execute when the variable is on.\r\n     */\r\n    public readonly onOn: FlowGraphSignalConnection;\r\n    /**\r\n     * Output connection: The signal to execute when the variable is off.\r\n     */\r\n    public readonly onOff: FlowGraphSignalConnection;\r\n    /**\r\n     * Output connection: If the variable is on.\r\n     */\r\n    public readonly value: FlowGraphDataConnection<boolean>;\r\n\r\n    constructor(config?: IFlowGraphFlipFlopBlockConfiguration) {\r\n        super(config);\r\n\r\n        this.onOn = this._registerSignalOutput(\"onOn\");\r\n        this.onOff = this._registerSignalOutput(\"onOff\");\r\n        this.value = this.registerDataOutput(\"value\", RichTypeBoolean);\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\r\n        let value = context._getExecutionVariable(this, \"value\", typeof this.config?.startValue === \"boolean\" ? !this.config.startValue : false);\r\n\r\n        value = !value;\r\n        context._setExecutionVariable(this, \"value\", value);\r\n        this.value.setValue(value, context);\r\n        if (value) {\r\n            this.onOn._activateSignal(context);\r\n        } else {\r\n            this.onOff._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.FlipFlop;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphFlipFlopBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphFlipFlopBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.FlipFlop, FlowGraphFlipFlopBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { FlowGraphExecutionBlock } from \"../../../flowGraphExecutionBlock\";\r\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Configuration for the sequence block.\r\n */\r\nexport interface IFlowGraphSequenceBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The number of output signals. Defaults to 1.\r\n     */\r\n    outputSignalCount?: number;\r\n}\r\n\r\n/**\r\n * A block that executes its output flows in sequence.\r\n */\r\nexport class FlowGraphSequenceBlock extends FlowGraphExecutionBlock {\r\n    /**\r\n     * The output flows.\r\n     */\r\n    public executionSignals: FlowGraphSignalConnection[] = [];\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphSequenceBlockConfiguration\r\n    ) {\r\n        super(config);\r\n        this.setNumberOfOutputSignals(this.config.outputSignalCount);\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext) {\r\n        for (let i = 0; i < this.executionSignals.length; i++) {\r\n            this.executionSignals[i]._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the block's output flows. Would usually be passed from the constructor but can be changed afterwards.\r\n     * @param outputSignalCount the number of output flows\r\n     */\r\n    public setNumberOfOutputSignals(outputSignalCount: number = 1) {\r\n        // check the size of the outFlow Array, see if it is not larger than needed\r\n        while (this.executionSignals.length > outputSignalCount) {\r\n            const flow = this.executionSignals.pop();\r\n            if (flow) {\r\n                flow.disconnectFromAll();\r\n                this._unregisterSignalOutput(flow.name);\r\n            }\r\n        }\r\n\r\n        while (this.executionSignals.length < outputSignalCount) {\r\n            this.executionSignals.push(this._registerSignalOutput(`out_${this.executionSignals.length}`));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Sequence;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphSequenceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphSequenceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Sequence, FlowGraphSequenceBlock);\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type IDisposable } from \"../scene\";\r\n\r\n/**\r\n * Construction options for a timer\r\n */\r\nexport interface ITimerOptions<T> {\r\n    /**\r\n     * Time-to-end\r\n     */\r\n    timeout: number;\r\n    /**\r\n     * The context observable is used to calculate time deltas and provides the context of the timer's callbacks. Will usually be OnBeforeRenderObservable.\r\n     * Countdown calculation is done ONLY when the observable is notifying its observers, meaning that if\r\n     * you choose an observable that doesn't trigger too often, the wait time might extend further than the requested max time\r\n     */\r\n    contextObservable: Observable<T>;\r\n    /**\r\n     * Optional parameters when adding an observer to the observable\r\n     */\r\n    observableParameters?: {\r\n        mask?: number;\r\n        insertFirst?: boolean;\r\n        scope?: any;\r\n    };\r\n    /**\r\n     * An optional break condition that will stop the times prematurely. In this case onEnded will not be triggered!\r\n     */\r\n    breakCondition?: (data?: ITimerData<T>) => boolean;\r\n    /**\r\n     * Will be triggered when the time condition has met\r\n     */\r\n    onEnded?: (data: ITimerData<any>) => void;\r\n    /**\r\n     * Will be triggered when the break condition has met (prematurely ended)\r\n     */\r\n    onAborted?: (data: ITimerData<any>) => void;\r\n    /**\r\n     * Optional function to execute on each tick (or count)\r\n     */\r\n    onTick?: (data: ITimerData<any>) => void;\r\n}\r\n\r\n/**\r\n * An interface defining the data sent by the timer\r\n */\r\nexport interface ITimerData<T> {\r\n    /**\r\n     * When did it start\r\n     */\r\n    startTime: number;\r\n    /**\r\n     * Time now\r\n     */\r\n    currentTime: number;\r\n    /**\r\n     * Time passed since started\r\n     */\r\n    deltaTime: number;\r\n    /**\r\n     * How much is completed, in [0.0...1.0].\r\n     * Note that this CAN be higher than 1 due to the fact that we don't actually measure time but delta between observable calls\r\n     */\r\n    completeRate: number;\r\n    /**\r\n     * What the registered observable sent in the last count\r\n     */\r\n    payload: T;\r\n}\r\n\r\n/**\r\n * The current state of the timer\r\n */\r\nexport const enum TimerState {\r\n    /**\r\n     * Timer initialized, not yet started\r\n     */\r\n    INIT,\r\n    /**\r\n     * Timer started and counting\r\n     */\r\n    STARTED,\r\n    /**\r\n     * Timer ended (whether aborted or time reached)\r\n     */\r\n    ENDED,\r\n}\r\n\r\n/**\r\n * A simple version of the timer. Will take options and start the timer immediately after calling it\r\n *\r\n * @param options options with which to initialize this timer\r\n * @returns an observer that can be used to stop the timer\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function setAndStartTimer<T = any>(options: ITimerOptions<T>): Nullable<Observer<T>> {\r\n    let timer = 0;\r\n    const startTime = Date.now();\r\n    options.observableParameters = options.observableParameters ?? {};\r\n    const observer = options.contextObservable.add(\r\n        (payload: any) => {\r\n            const now = Date.now();\r\n            timer = now - startTime;\r\n            const data: ITimerData<any> = {\r\n                startTime,\r\n                currentTime: now,\r\n                deltaTime: timer,\r\n                completeRate: timer / options.timeout,\r\n                payload,\r\n            };\r\n            if (options.breakCondition && options.breakCondition(data)) {\r\n                options.contextObservable.remove(observer);\r\n                options.onAborted && options.onAborted(data);\r\n                return;\r\n            }\r\n            if (timer >= options.timeout) {\r\n                options.contextObservable.remove(observer);\r\n                options.onEnded && options.onEnded(data);\r\n                return;\r\n            }\r\n            options.onTick && options.onTick(data);\r\n        },\r\n        options.observableParameters.mask,\r\n        options.observableParameters.insertFirst,\r\n        options.observableParameters.scope\r\n    );\r\n    return observer;\r\n}\r\n\r\n/**\r\n * An advanced implementation of a timer class\r\n */\r\nexport class AdvancedTimer<T = any> implements IDisposable {\r\n    /**\r\n     * Will notify each time the timer calculates the remaining time\r\n     */\r\n    public onEachCountObservable: Observable<ITimerData<T>> = new Observable();\r\n    /**\r\n     * Will trigger when the timer was aborted due to the break condition\r\n     */\r\n    public onTimerAbortedObservable: Observable<ITimerData<T>> = new Observable();\r\n    /**\r\n     * Will trigger when the timer ended successfully\r\n     */\r\n    public onTimerEndedObservable: Observable<ITimerData<T>> = new Observable();\r\n    /**\r\n     * Will trigger when the timer state has changed\r\n     */\r\n    public onStateChangedObservable: Observable<TimerState> = new Observable();\r\n\r\n    private _observer: Nullable<Observer<T>> = null;\r\n    private _contextObservable: Observable<T>;\r\n    private _observableParameters: {\r\n        mask?: number;\r\n        insertFirst?: boolean;\r\n        scope?: any;\r\n    };\r\n    private _startTime: number;\r\n    private _timer: number;\r\n    private _state: TimerState;\r\n    private _breakCondition: (data: ITimerData<T>) => boolean;\r\n    private _timeToEnd: number;\r\n    private _breakOnNextTick: boolean = false;\r\n\r\n    /**\r\n     * Will construct a new advanced timer based on the options provided. Timer will not start until start() is called.\r\n     * @param options construction options for this advanced timer\r\n     */\r\n    constructor(options: ITimerOptions<T>) {\r\n        this._setState(TimerState.INIT);\r\n        this._contextObservable = options.contextObservable;\r\n        this._observableParameters = options.observableParameters ?? {};\r\n        this._breakCondition = options.breakCondition ?? (() => false);\r\n        this._timeToEnd = options.timeout;\r\n        if (options.onEnded) {\r\n            this.onTimerEndedObservable.add(options.onEnded);\r\n        }\r\n        if (options.onTick) {\r\n            this.onEachCountObservable.add(options.onTick);\r\n        }\r\n        if (options.onAborted) {\r\n            this.onTimerAbortedObservable.add(options.onAborted);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * set a breaking condition for this timer. Default is to never break during count\r\n     * @param predicate the new break condition. Returns true to break, false otherwise\r\n     */\r\n    public set breakCondition(predicate: (data: ITimerData<T>) => boolean) {\r\n        this._breakCondition = predicate;\r\n    }\r\n\r\n    /**\r\n     * Reset ALL associated observables in this advanced timer\r\n     */\r\n    public clearObservables() {\r\n        this.onEachCountObservable.clear();\r\n        this.onTimerAbortedObservable.clear();\r\n        this.onTimerEndedObservable.clear();\r\n        this.onStateChangedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Will start a new iteration of this timer. Only one instance of this timer can run at a time.\r\n     *\r\n     * @param timeToEnd how much time to measure until timer ended\r\n     */\r\n    public start(timeToEnd: number = this._timeToEnd) {\r\n        if (this._state === TimerState.STARTED) {\r\n            throw new Error(\"Timer already started. Please stop it before starting again\");\r\n        }\r\n        this._timeToEnd = timeToEnd;\r\n        this._startTime = Date.now();\r\n        this._timer = 0;\r\n        this._observer = this._contextObservable.add(this._tick, this._observableParameters.mask, this._observableParameters.insertFirst, this._observableParameters.scope);\r\n        this._setState(TimerState.STARTED);\r\n    }\r\n\r\n    /**\r\n     * Will force a stop on the next tick.\r\n     */\r\n    public stop() {\r\n        if (this._state !== TimerState.STARTED) {\r\n            return;\r\n        }\r\n        this._breakOnNextTick = true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this timer, clearing all resources\r\n     */\r\n    public dispose() {\r\n        if (this._observer) {\r\n            this._contextObservable.remove(this._observer);\r\n        }\r\n        this.clearObservables();\r\n    }\r\n\r\n    private _setState(newState: TimerState) {\r\n        this._state = newState;\r\n        this.onStateChangedObservable.notifyObservers(this._state);\r\n    }\r\n\r\n    private _tick = (payload: T) => {\r\n        const now = Date.now();\r\n        this._timer = now - this._startTime;\r\n        const data: ITimerData<T> = {\r\n            startTime: this._startTime,\r\n            currentTime: now,\r\n            deltaTime: this._timer,\r\n            completeRate: this._timer / this._timeToEnd,\r\n            payload,\r\n        };\r\n        const shouldBreak = this._breakOnNextTick || this._breakCondition(data);\r\n        if (shouldBreak || this._timer >= this._timeToEnd) {\r\n            this._stop(data, shouldBreak);\r\n        } else {\r\n            this.onEachCountObservable.notifyObservers(data);\r\n        }\r\n    };\r\n\r\n    private _stop(data: ITimerData<T>, aborted: boolean = false) {\r\n        this._contextObservable.remove(this._observer);\r\n        this._setState(TimerState.ENDED);\r\n        if (aborted) {\r\n            this.onTimerAbortedObservable.notifyObservers(data);\r\n        } else {\r\n            this.onTimerEndedObservable.notifyObservers(data);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphAsyncExecutionBlock } from \"../../../flowGraphAsyncExecutionBlock\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { RichTypeFlowGraphInteger, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { AdvancedTimer } from \"../../../../Misc/timer\";\nimport { Logger } from \"../../../../Misc/logger\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { IsDelayActive, MarkDelayActive, MarkDelayInactive } from \"core/FlowGraph/flowGraphDelayRegistry\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Block that sets a delay in seconds before activating the output signal.\n */\nexport class FlowGraphSetDelayBlock extends FlowGraphAsyncExecutionBlock {\n    /**\n     * The maximum number of parallel delays that can be set per node.\n     */\n    public static MaxParallelDelayCount = 100;\n    /**\n     * Input signal: If activated the delayed activations set by this block will be canceled.\n     */\n    public readonly cancel: FlowGraphSignalConnection;\n\n    /**\n     * Input connection: The duration of the delay in seconds.\n     */\n    public readonly duration: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: The last delay index that was set.\n     */\n    public readonly lastDelayIndex: FlowGraphDataConnection<FlowGraphInteger>;\n\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.cancel = this._registerSignalInput(\"cancel\");\n        this.duration = this.registerDataInput(\"duration\", RichTypeNumber);\n        this.lastDelayIndex = this.registerDataOutput(\"lastDelayIndex\", RichTypeFlowGraphInteger, new FlowGraphInteger(-1));\n    }\n\n    public override _preparePendingTasks(context: FlowGraphContext): void {\n        const duration = this.duration.getValue(context);\n        if (duration < 0 || isNaN(duration) || !isFinite(duration)) {\n            return this._reportError(context, \"Invalid duration in SetDelay block\");\n        }\n\n        // active delays are global to the context\n        const activeDelays: number = context._getGlobalContextVariable(\"activeDelays\", 0);\n        if (activeDelays >= FlowGraphSetDelayBlock.MaxParallelDelayCount) {\n            return this._reportError(context, \"Max parallel delays reached\");\n        }\n        // get the last global delay index\n        const lastDelayIndex: number = context._getGlobalContextVariable(\"lastDelayIndex\", -1);\n\n        // these are block-specific and not global\n        const timers = context._getExecutionVariable(this, \"pendingDelays\", [] as AdvancedTimer[]);\n        const scene = context.configuration.scene;\n        const timer: AdvancedTimer = new AdvancedTimer({\n            timeout: duration * 1000, // duration is in seconds\n            contextObservable: scene.onBeforeRenderObservable,\n            onEnded: () => this._onEnded(timer, context),\n        });\n        timer.start();\n        const newIndex = lastDelayIndex + 1;\n        this.lastDelayIndex.setValue(new FlowGraphInteger(newIndex), context);\n        context._setGlobalContextVariable(\"lastDelayIndex\", newIndex);\n        // Track the delay as active so a host can report the handle as valid until it fires or\n        // is cancelled.\n        MarkDelayActive(context, newIndex);\n\n        timers[newIndex] = timer;\n        context._setExecutionVariable(this, \"pendingDelays\", timers);\n        this._updateGlobalTimers(context);\n    }\n\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\n        const timers = context._getExecutionVariable(this, \"pendingDelays\", [] as AdvancedTimer[]);\n        const globalTimers = context._getGlobalContextVariable(\"pendingDelays\", [] as AdvancedTimer[]);\n        for (let index = 0; index < timers.length; index++) {\n            const timer = timers[index];\n            if (timer) {\n                timer.dispose();\n                // The delay is no longer scheduled, so drop it from the active set.\n                MarkDelayInactive(context, index);\n                delete globalTimers[index];\n            }\n        }\n        context._setGlobalContextVariable(\"pendingDelays\", globalTimers);\n        context._deleteExecutionVariable(this, \"pendingDelays\");\n        this.lastDelayIndex.setValue(new FlowGraphInteger(-1), context);\n        this._updateGlobalTimers(context);\n    }\n\n    public _execute(context: FlowGraphContext, callingSignal: FlowGraphSignalConnection): void {\n        if (callingSignal === this.cancel) {\n            this._cancelPendingTasks(context);\n            return;\n        } else {\n            this._preparePendingTasks(context);\n            this.out._activateSignal(context);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.SetDelay;\n    }\n\n    private _onEnded(timer: AdvancedTimer, context: FlowGraphContext) {\n        const timers = context._getExecutionVariable(this, \"pendingDelays\", [] as AdvancedTimer[]);\n        const index = timers.indexOf(timer);\n        if (index !== -1) {\n            delete timers[index];\n            const globalTimers = context._getGlobalContextVariable(\"pendingDelays\", [] as AdvancedTimer[]);\n            delete globalTimers[index];\n            context._setGlobalContextVariable(\"pendingDelays\", globalTimers);\n            // The delay has fired and is no longer scheduled.\n            MarkDelayInactive(context, index);\n        } else {\n            Logger.Warn(\"FlowGraphTimerBlock: Timer ended but was not found in the running timers list\");\n        }\n        context._removePendingBlock(this);\n        this.done._activateSignal(context);\n\n        this._updateGlobalTimers(context);\n    }\n\n    private _updateGlobalTimers(context: FlowGraphContext) {\n        const timers = context._getExecutionVariable(this, \"pendingDelays\", [] as AdvancedTimer[]);\n        const globalTimers = context._getGlobalContextVariable(\"pendingDelays\", [] as AdvancedTimer[]);\n        // there should NEVER be the same index in the global and local timers, unless they are equal\n        for (let i = 0; i < timers.length; i++) {\n            // A hole in this block's local timers array (an index owned by a different delay block) or an\n            // index whose delay is no longer active must be skipped. Only `continue` here — never\n            // `delete globalTimers[i]`, because for a hole index `i` the global slot belongs to another\n            // block and deleting it would silently drop that block's still-pending delay.\n            if (!timers[i] || !IsDelayActive(context, i)) {\n                continue;\n            }\n            const timer = timers[i];\n            if (globalTimers[i] && globalTimers[i] !== timer) {\n                Logger.Warn(\"FlowGraphTimerBlock: Timer ended but was not found in the running timers list\");\n            } else {\n                globalTimers[i] = timer;\n            }\n        }\n        context._setGlobalContextVariable(\"pendingDelays\", globalTimers);\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetDelayBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetDelayBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.SetDelay, FlowGraphSetDelayBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type AdvancedTimer } from \"../../../../Misc/timer\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeFlowGraphInteger } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { getNumericValue } from \"core/FlowGraph/utils\";\nimport { MarkDelayInactive } from \"core/FlowGraph/flowGraphDelayRegistry\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * This block cancels a delay that was previously scheduled.\n */\nexport class FlowGraphCancelDelayBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The index value of the scheduled activation to be cancelled.\n     */\n    public readonly delayIndex: FlowGraphDataConnection<FlowGraphInteger>;\n\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.delayIndex = this.registerDataInput(\"delayIndex\", RichTypeFlowGraphInteger);\n    }\n\n    public _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const delayIndex = getNumericValue(this.delayIndex.getValue(context));\n        if (delayIndex < 0 || isNaN(delayIndex) || !isFinite(delayIndex)) {\n            return this._reportError(context, \"Invalid delay index\");\n        }\n        const timers = context._getGlobalContextVariable(\"pendingDelays\", [] as AdvancedTimer[]);\n        const timer = timers[delayIndex];\n        if (timer) {\n            timer.dispose();\n            delete timers[delayIndex];\n            context._setGlobalContextVariable(\"pendingDelays\", timers);\n        }\n        // The delay is cancelled, so drop it from the active set used by handle validity checks.\n        MarkDelayInactive(context, delayIndex);\n        // activate the out output flow\n        this.out._activateSignal(context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CancelDelay;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphCancelDelayBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphCancelDelayBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.CancelDelay, FlowGraphCancelDelayBlock);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"../../../flowGraphAsyncExecutionBlock\";\r\nimport { RichTypeAny, RichTypeNumber, RichTypeBoolean } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { type Animation } from \"core/Animations/animation.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\n\r\n/**\r\n * Configuration for playing an animation.\r\n */\r\nexport interface IFlowGraphPlayAnimationBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * Whether animation-group playback uses the unbounded KHR_interactivity timeline.\r\n     */\r\n    useVirtualTimeline?: boolean;\r\n}\r\n\r\ntype AnimationObserverSet = {\r\n    block: FlowGraphPlayAnimationBlock;\r\n    groupEnd: Observer<AnimationGroup>;\r\n    animationEnd: Observer<any>;\r\n    animationLoop: Observer<any>;\r\n    groupLoop: Observer<AnimationGroup>;\r\n};\r\n\r\n/**\r\n * Removes observers owned by the play block that started an animation group.\r\n * @param context active FlowGraph context\r\n * @param animationGroup animation group being replaced or stopped\r\n * @returns the owning play block, when one was registered\r\n */\r\nexport function RemoveFlowGraphAnimationGroupObservers(context: FlowGraphContext, animationGroup: AnimationGroup): FlowGraphPlayAnimationBlock | undefined {\r\n    const observerSets = context._getGlobalContextVariable(\"animationGroupObserverSets\", new Map<number, AnimationObserverSet>()) as Map<number, AnimationObserverSet>;\r\n    const observers = observerSets.get(animationGroup.uniqueId);\r\n    if (!observers) {\r\n        return undefined;\r\n    }\r\n    animationGroup.onAnimationGroupEndObservable.remove(observers.groupEnd);\r\n    animationGroup.onAnimationEndObservable.remove(observers.animationEnd);\r\n    animationGroup.onAnimationLoopObservable.remove(observers.animationLoop);\r\n    animationGroup.onAnimationGroupLoopObservable.remove(observers.groupLoop);\r\n    observerSets.delete(animationGroup.uniqueId);\r\n    context._setGlobalContextVariable(\"animationGroupObserverSets\", observerSets);\r\n    return observers.block;\r\n}\r\n\r\n/**\r\n * @experimental\r\n * A block that plays an animation on an animatable object.\r\n */\r\nexport class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {\r\n    /**\r\n     * Input connection: The speed of the animation.\r\n     */\r\n    public readonly speed: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: Should the animation loop?\r\n     * Not in glTF specs, but useful for the engine.\r\n     */\r\n    public readonly loop: FlowGraphDataConnection<boolean>;\r\n    /**\r\n     * Input connection: The starting frame of the animation.\r\n     */\r\n    public readonly from: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: The ending frame of the animation.\r\n     */\r\n    public readonly to: FlowGraphDataConnection<number>;\r\n\r\n    /**\r\n     * Output connection: The current frame of the animation.\r\n     */\r\n    public readonly currentFrame: FlowGraphDataConnection<number>;\r\n\r\n    /**\r\n     * Output connection: The current time of the animation.\r\n     */\r\n    public readonly currentTime: FlowGraphDataConnection<number>;\r\n\r\n    /**\r\n     * Output connection: The animatable that is currently running.\r\n     */\r\n    public readonly currentAnimationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n    /**\r\n     * Input: Will be initialized if no animation group was provided in the configuration.\r\n     */\r\n    public readonly animationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n    /**\r\n     * Input: If provided this animation will be used. Priority will be given to the animation group input.\r\n     */\r\n    public readonly animation: FlowGraphDataConnection<Animation | Animation[]>;\r\n\r\n    /**\r\n     * Input connection: The target object that will be animated. If animation group is provided this input will be ignored.\r\n     */\r\n    public readonly object: FlowGraphDataConnection<any>;\r\n\r\n    public constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config?: IFlowGraphPlayAnimationBlockConfiguration\r\n    ) {\r\n        super(config, [\"animationLoop\", \"animationEnd\", \"animationGroupLoop\"]);\r\n\r\n        this.speed = this.registerDataInput(\"speed\", RichTypeNumber);\r\n        this.loop = this.registerDataInput(\"loop\", RichTypeBoolean);\r\n        this.from = this.registerDataInput(\"from\", RichTypeNumber, 0);\r\n        this.to = this.registerDataInput(\"to\", RichTypeNumber);\r\n\r\n        this.currentFrame = this.registerDataOutput(\"currentFrame\", RichTypeNumber);\r\n        this.currentTime = this.registerDataOutput(\"currentTime\", RichTypeNumber);\r\n\r\n        this.currentAnimationGroup = this.registerDataOutput(\"currentAnimationGroup\", RichTypeAny);\r\n        this.animationGroup = this.registerDataInput(\"animationGroup\", RichTypeAny, config?.animationGroup);\r\n        this.animation = this.registerDataInput(\"animation\", RichTypeAny);\r\n        this.object = this.registerDataInput(\"object\", RichTypeAny);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * @param context\r\n     */\r\n    public override _startPendingTasks(context: FlowGraphContext): void {\r\n        if (context._getExecutionVariable(this, \"_initialized\", false)) {\r\n            this._cancelPendingTasks(context);\r\n            this._resetAfterCanceled(context);\r\n        }\r\n\r\n        if (!this._tryPreparePendingTasks(context)) {\r\n            return;\r\n        }\r\n        context._addPendingBlock(this);\r\n        this.out._activateSignal(context);\r\n        context._setExecutionVariable(this, \"_initialized\", true);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * @param context the graph context\r\n     */\r\n    public override _preparePendingTasks(context: FlowGraphContext): void {\r\n        this._tryPreparePendingTasks(context);\r\n    }\r\n\r\n    /**\r\n     * Prepares and starts the animation, reporting whether it could be started. Invalid inputs\r\n     * activate `err` and return false, so the caller neither activates `out` nor registers the\r\n     * block as pending.\r\n     * @param context the graph context\r\n     * @returns whether the animation was prepared and started successfully\r\n     */\r\n    private _tryPreparePendingTasks(context: FlowGraphContext): boolean {\r\n        const ag = this.animationGroup.getValue(context);\r\n        const animation = this.animation.getValue(context);\r\n        if (!ag && !animation) {\r\n            this._reportError(context, \"No animation or animation group provided\");\r\n            return false;\r\n        } else if (ag && ag.targetedAnimations.length === 0) {\r\n            this._reportError(context, \"Animation group has no targeted animations\");\r\n            return false;\r\n        } else {\r\n            // if an animation group was already created, dispose it and create a new one\r\n            const currentAnimationGroup = this.currentAnimationGroup.getValue(context);\r\n            if (currentAnimationGroup && currentAnimationGroup !== ag) {\r\n                currentAnimationGroup.dispose();\r\n            }\r\n            let animationGroupToUse = ag;\r\n            let isInterpolation = false;\r\n            let interpolationAnimationsArray: Animation[] | undefined;\r\n            let interpolationTarget: any;\r\n            // check which animation to use. If no animationGroup was defined and an animation was provided, use the animation\r\n            if (animation && !animationGroupToUse) {\r\n                const target = this.object.getValue(context);\r\n                if (!target) {\r\n                    this._reportError(context, \"No target object provided\");\r\n                    return false;\r\n                }\r\n                const animationsArray = Array.isArray(animation) ? animation : [animation];\r\n                const name = animationsArray[0].name;\r\n                animationGroupToUse = new AnimationGroup(\"flowGraphAnimationGroup-\" + name + \"-\" + target.name, context.configuration.scene);\r\n                const interpolationAnimations = context._getGlobalContextVariable(\"interpolationAnimations\", []) as number[];\r\n                for (const anim of animationsArray) {\r\n                    animationGroupToUse.addTargetedAnimation(anim, target);\r\n                    if (interpolationAnimations.indexOf(anim.uniqueId) !== -1) {\r\n                        isInterpolation = true;\r\n                    }\r\n                }\r\n                interpolationAnimationsArray = animationsArray;\r\n                interpolationTarget = target;\r\n            }\r\n            // not accepting 0\r\n            const speed = this.speed.getValue(context) || 1;\r\n            const from = this.from.getValue(context) ?? 0;\r\n            // Read the raw end time before it is defaulted to the animation group's natural end, so that an\r\n            // explicitly provided NaN end time can still be detected by the animation/start validation below.\r\n            const rawTo = this.to.getValue(context);\r\n            const hasTo = this.to.isConnected() || context._hasConnectionValue(this.to);\r\n            const to = hasTo ? rawTo : animationGroupToUse.to;\r\n\r\n            // Input validation. Only applies to animation-group playback\r\n            // (animation/start); interpolation uses the `animation` input and has its own validation below.\r\n            // The operation activates its `err` flow when the speed is NaN, infinite, or <= 0, or\r\n            // when the end time is NaN. A NaN or infinite start time is caught by the finite check on `from`.\r\n            if (!animation) {\r\n                if (isNaN(rawTo)) {\r\n                    this._reportError(context, \"Invalid animation end time\");\r\n                    return false;\r\n                }\r\n                // Only validate a speed that was explicitly provided; an unconnected speed keeps the engine\r\n                // default of 1 (matching the historical Babylon behavior for animation/start without a speed).\r\n                if (this.speed.isConnected() || context._hasConnectionValue(this.speed)) {\r\n                    const providedSpeed = this.speed.getValue(context);\r\n                    if (!isFinite(providedSpeed) || providedSpeed <= 0) {\r\n                        this._reportError(context, \"Invalid animation speed\");\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // The start value (interpolation start frame / animation start time) must always be finite. For\r\n            // animation/start this also satisfies the spec requirement that a NaN or infinite start time\r\n            // activates the err flow.\r\n            if (!isFinite(from)) {\r\n                this._reportError(context, \"Invalid animation duration\");\r\n                return false;\r\n            }\r\n            // For interpolation the end value is the animation duration and must be a finite, non-negative number.\r\n            // Animation-group playback (animation/start) instead allows an infinite end time — it means \"play to\r\n            // the natural end / loop\" (see the `loop` computation below) — and its NaN end time was already\r\n            // rejected above, so the end value is only range-checked here for the interpolation case.\r\n            if (animation && (!isFinite(to) || to < 0)) {\r\n                this._reportError(context, \"Invalid animation duration\");\r\n                return false;\r\n            }\r\n\r\n            // CSS cubic-bezier control points must be finite, and the X components must be in [0, 1].\r\n            if (animation) {\r\n                const animationsArray = Array.isArray(animation) ? animation : [animation];\r\n                for (const anim of animationsArray) {\r\n                    const easing = anim.getEasingFunction?.();\r\n                    if (easing && \"x1\" in easing) {\r\n                        const bezier = easing as unknown as { x1: number; y1: number; x2: number; y2: number };\r\n                        if (\r\n                            !Number.isFinite(bezier.x1) ||\r\n                            !Number.isFinite(bezier.y1) ||\r\n                            !Number.isFinite(bezier.x2) ||\r\n                            !Number.isFinite(bezier.y2) ||\r\n                            bezier.x1 < 0 ||\r\n                            bezier.x1 > 1 ||\r\n                            bezier.x2 < 0 ||\r\n                            bezier.x2 > 1\r\n                        ) {\r\n                            this._reportError(context, \"Invalid bezier curve control points\");\r\n                            return false;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Stop any interpolation already running on the same target/property, but only after validation has\r\n            // passed. An invalid interpolation (bad duration or NaN control points) must report [err] without\r\n            // disturbing an interpolation that is already running on the same target.\r\n            if (isInterpolation && interpolationAnimationsArray && interpolationTarget !== undefined) {\r\n                this._checkInterpolationDuplications(context, interpolationAnimationsArray, interpolationTarget);\r\n            }\r\n\r\n            const loop = !isFinite(to) || this.loop.getValue(context);\r\n            this.currentAnimationGroup.setValue(animationGroupToUse, context);\r\n\r\n            const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n            // check if it already running\r\n            if (currentlyRunningAnimationGroups.indexOf(animationGroupToUse.uniqueId) !== -1) {\r\n                this._stopAnimationGroup(context, animationGroupToUse);\r\n            }\r\n            try {\r\n                if (this.config?.useVirtualTimeline) {\r\n                    animationGroupToUse.startWithVirtualTimeline(loop, speed, from, to);\r\n                } else {\r\n                    animationGroupToUse.start(loop, speed, from, to);\r\n                }\r\n                const observers: AnimationObserverSet = {\r\n                    block: this,\r\n                    groupEnd: animationGroupToUse.onAnimationGroupEndObservable.add(() => this._onAnimationGroupEnd(context, animationGroupToUse)),\r\n                    animationEnd: animationGroupToUse.onAnimationEndObservable.add(() => this._eventsSignalOutputs[\"animationEnd\"]._activateSignal(context)),\r\n                    animationLoop: animationGroupToUse.onAnimationLoopObservable.add(() => this._eventsSignalOutputs[\"animationLoop\"]._activateSignal(context)),\r\n                    groupLoop: animationGroupToUse.onAnimationGroupLoopObservable.add(() => this._eventsSignalOutputs[\"animationGroupLoop\"]._activateSignal(context)),\r\n                };\r\n                const observerSets = context._getGlobalContextVariable(\"animationGroupObserverSets\", new Map<number, AnimationObserverSet>()) as Map<number, AnimationObserverSet>;\r\n                observerSets.set(animationGroupToUse.uniqueId, observers);\r\n                context._setGlobalContextVariable(\"animationGroupObserverSets\", observerSets);\r\n                currentlyRunningAnimationGroups.push(animationGroupToUse.uniqueId);\r\n                context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\r\n            } catch (e) {\r\n                this._reportError(context, e);\r\n                return false;\r\n            }\r\n            return true;\r\n        }\r\n    }\r\n\r\n    protected override _reportError(context: FlowGraphContext, error: string | Error): void {\r\n        super._reportError(context, error);\r\n        this.currentFrame.setValue(-1, context);\r\n        this.currentTime.setValue(-1, context);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _executeOnTick(_context: FlowGraphContext): void {\r\n        const ag = this.currentAnimationGroup.getValue(_context);\r\n        if (ag) {\r\n            this.currentFrame.setValue(ag.getCurrentFrame(), _context);\r\n            this.currentTime.setValue(ag.animatables[0]?.elapsedTime ?? 0, _context);\r\n        }\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext): void {\r\n        this._startPendingTasks(context);\r\n    }\r\n\r\n    private _onAnimationGroupEnd(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n        RemoveFlowGraphAnimationGroupObservers(context, animationGroup);\r\n        this._removeFromCurrentlyRunning(context, animationGroup);\r\n        this._resetAfterCanceled(context);\r\n        this.done._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * The idea behind this function is to check every running animation group and check if the targeted animations it uses are interpolation animations.\r\n     * If they are, we want to see that they don't collide with the current interpolation animations that are starting to play.\r\n     * If they do, we want to stop the already-running animation group.\r\n     * @internal\r\n     */\r\n    private _checkInterpolationDuplications(context: FlowGraphContext, animation: Animation[], target: any) {\r\n        const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n        for (const uniqueId of currentlyRunningAnimationGroups) {\r\n            const ag = context.assetsContext.animationGroups.find((ag) => ag.uniqueId === uniqueId);\r\n            if (ag) {\r\n                for (const anim of ag.targetedAnimations) {\r\n                    for (const animToCheck of animation) {\r\n                        if (anim.animation.targetProperty === animToCheck.targetProperty && anim.target === target) {\r\n                            this._stopAnimationGroup(context, ag);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _stopAnimationGroup(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n        const owner = RemoveFlowGraphAnimationGroupObservers(context, animationGroup);\r\n        owner?._cleanupAfterExternalStop(context, animationGroup);\r\n        // stop, while skipping the on AnimationEndObservable to avoid the \"done\" signal\r\n        animationGroup.stop(true);\r\n        // Only dispose animation groups that were internally created by this block\r\n        // (i.e. built from individual animations). Scene-provided animation groups\r\n        // must not be disposed as that removes them from the scene catalog and\r\n        // breaks the editor dropdown / re-use on replay.\r\n        if (animationGroup.name.startsWith(\"flowGraphAnimationGroup-\")) {\r\n            animationGroup.dispose();\r\n        }\r\n        this._removeFromCurrentlyRunning(context, animationGroup);\r\n    }\r\n\r\n    /** @internal */\r\n    public _cleanupAfterExternalStop(context: FlowGraphContext, animationGroup: AnimationGroup): void {\r\n        this._removeFromCurrentlyRunning(context, animationGroup);\r\n        this._resetAfterCanceled(context);\r\n    }\r\n\r\n    private _removeFromCurrentlyRunning(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n        const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n        const idx = currentlyRunningAnimationGroups.indexOf(animationGroup.uniqueId);\r\n        if (idx !== -1) {\r\n            currentlyRunningAnimationGroups.splice(idx, 1);\r\n            context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Stop any currently running animations.\r\n     */\r\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n        const ag = this.currentAnimationGroup.getValue(context);\r\n        if (ag) {\r\n            this._stopAnimationGroup(context, ag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.PlayAnimation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphPlayAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphPlayAnimationBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.PlayAnimation, FlowGraphPlayAnimationBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeAny, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { type AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"core/FlowGraph/flowGraphAsyncExecutionBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\nimport { RemoveFlowGraphAnimationGroupObservers } from \"./flowGraphPlayAnimationBlock.pure\";\r\n\r\n/**\r\n * Configuration for stopping an animation.\r\n */\r\nexport interface IFlowGraphStopAnimationBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * Whether stopAtFrame uses the unbounded KHR_interactivity timeline.\r\n     * When false, the block retains its legacy positive-frame scheduling behavior.\r\n     */\r\n    useVirtualStopAt?: boolean;\r\n\r\n    /**\r\n     * Whether stopping suppresses the animation-group end notification.\r\n     * Defaults to true to preserve the historical StopAnimation behavior.\r\n     */\r\n    skipOnAnimationEnd?: boolean;\r\n}\r\n\r\n/**\r\n * @experimental\r\n * Block that stops a running animation\r\n */\r\nexport class FlowGraphStopAnimationBlock extends FlowGraphAsyncExecutionBlock {\r\n    /**\r\n     * Input connection: The animation to stop.\r\n     */\r\n    public readonly animationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n    /**\r\n     * Input connection - if defined (positive integer) the animation will stop at this frame.\r\n     */\r\n    public readonly stopAtFrame: FlowGraphDataConnection<number>;\r\n\r\n    constructor(config?: IFlowGraphStopAnimationBlockConfiguration) {\r\n        super(config);\r\n        this.animationGroup = this.registerDataInput(\"animationGroup\", RichTypeAny);\r\n        this.stopAtFrame = this.registerDataInput(\"stopAtFrame\", RichTypeNumber, -1);\r\n    }\r\n\r\n    public override _preparePendingTasks(context: FlowGraphContext): void {\r\n        const animationToStopValue = this.animationGroup.getValue(context);\r\n        const stopAtFrame = this.stopAtFrame.getValue(context) ?? -1;\r\n        // get the context variable\r\n        const pendingStopAnimations = context._getGlobalContextVariable(\r\n            \"pendingStopAnimations\",\r\n            [] as {\r\n                uniqueId: number;\r\n                stopAtFrame: number;\r\n                block: FlowGraphStopAnimationBlock;\r\n                useVirtualStopAt: boolean;\r\n            }[]\r\n        );\r\n        if (this.config?.useVirtualStopAt) {\r\n            const existing = pendingStopAnimations.find((entry) => entry.uniqueId === animationToStopValue.uniqueId && entry.useVirtualStopAt);\r\n            if (existing) {\r\n                if (existing.block !== this) {\r\n                    context._removePendingBlock(existing.block);\r\n                }\r\n                existing.stopAtFrame = stopAtFrame;\r\n                existing.block = this;\r\n            } else {\r\n                pendingStopAnimations.push({ uniqueId: animationToStopValue.uniqueId, stopAtFrame, block: this, useVirtualStopAt: true });\r\n            }\r\n        } else {\r\n            pendingStopAnimations.push({ uniqueId: animationToStopValue.uniqueId, stopAtFrame, block: this, useVirtualStopAt: false });\r\n        }\r\n        // set the global context variable\r\n        context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n    }\r\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n        // remove the animation from the list\r\n        const animationToStopValue = this.animationGroup.getValue(context);\r\n        const pendingStopAnimations = context._getGlobalContextVariable(\r\n            \"pendingStopAnimations\",\r\n            [] as {\r\n                uniqueId: number;\r\n                stopAtFrame: number;\r\n                block: FlowGraphStopAnimationBlock;\r\n                useVirtualStopAt: boolean;\r\n            }[]\r\n        );\r\n        for (let i = 0; i < pendingStopAnimations.length; i++) {\r\n            if (pendingStopAnimations[i].uniqueId === animationToStopValue.uniqueId && pendingStopAnimations[i].block === this) {\r\n                pendingStopAnimations.splice(i, 1);\r\n                // set the global context variable\r\n                context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext): void {\r\n        const animationToStopValue = this.animationGroup.getValue(context);\r\n        const stopTime = this.stopAtFrame.getValue(context) ?? -1;\r\n        // check the values\r\n        if (!animationToStopValue) {\r\n            Logger.Warn(\"No animation group provided to stop.\");\r\n            return this._reportError(context, \"No animation group provided to stop.\");\r\n        }\r\n        if (isNaN(stopTime)) {\r\n            return this._reportError(context, \"Invalid stop time.\");\r\n        }\r\n        const useVirtualStopAt = !!this.config?.useVirtualStopAt;\r\n        const hasScheduledStop = useVirtualStopAt ? this.stopAtFrame.isConnected() || context._hasConnectionValue(this.stopAtFrame) : stopTime > 0;\r\n        let activateDone = false;\r\n        if (hasScheduledStop) {\r\n            if (useVirtualStopAt && animationToStopValue.isValidVirtualStopFrame(stopTime) && animationToStopValue.isVirtualFrameReached(stopTime)) {\r\n                this._stopAnimation(animationToStopValue, context, stopTime);\r\n                activateDone = true;\r\n            } else {\r\n                this._startPendingTasks(context);\r\n            }\r\n        } else {\r\n            this._stopAnimation(animationToStopValue, context);\r\n        }\r\n        // note that out will not be triggered in case of an error\r\n        this.out._activateSignal(context);\r\n        if (activateDone) {\r\n            this.done._activateSignal(context);\r\n        }\r\n    }\r\n\r\n    public override _executeOnTick(context: FlowGraphContext): void {\r\n        const animationToStopValue = this.animationGroup.getValue(context);\r\n        // check each frame if any animation should be stopped\r\n        const pendingStopAnimations = context._getGlobalContextVariable(\r\n            \"pendingStopAnimations\",\r\n            [] as { uniqueId: number; stopAtFrame: number; block: FlowGraphStopAnimationBlock; useVirtualStopAt: boolean }[]\r\n        );\r\n        for (let i = 0; i < pendingStopAnimations.length; i++) {\r\n            // compare the uniqueId to the animation to stop\r\n            if (pendingStopAnimations[i].uniqueId === animationToStopValue.uniqueId && pendingStopAnimations[i].block === this) {\r\n                const useVirtualStopAt = pendingStopAnimations[i].useVirtualStopAt;\r\n                const shouldStop = useVirtualStopAt\r\n                    ? animationToStopValue.isValidVirtualStopFrame(pendingStopAnimations[i].stopAtFrame) &&\r\n                      animationToStopValue.isVirtualFrameReached(pendingStopAnimations[i].stopAtFrame)\r\n                    : animationToStopValue.getCurrentFrame() >= pendingStopAnimations[i].stopAtFrame;\r\n                if (shouldStop) {\r\n                    // stop the animation\r\n                    this._stopAnimation(animationToStopValue, context, useVirtualStopAt ? pendingStopAnimations[i].stopAtFrame : undefined);\r\n                    // remove the animation from the list\r\n                    pendingStopAnimations.splice(i, 1);\r\n                    // set the global context variable\r\n                    context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n                    this.done._activateSignal(context);\r\n                    context._removePendingBlock(this);\r\n                    break;\r\n                } else if (!animationToStopValue.isPlaying) {\r\n                    pendingStopAnimations.splice(i, 1);\r\n                    context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n                    context._removePendingBlock(this);\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.StopAnimation;\r\n    }\r\n\r\n    private _stopAnimation(animationGroup: AnimationGroup, context: FlowGraphContext, virtualStopFrame?: number): void {\r\n        const currentlyRunning = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n        const index = currentlyRunning.indexOf(animationGroup.uniqueId);\r\n        if (index !== -1) {\r\n            const suppressAnimationEnd = this.config?.skipOnAnimationEnd !== false;\r\n            const owner = suppressAnimationEnd ? RemoveFlowGraphAnimationGroupObservers(context, animationGroup) : undefined;\r\n            owner?._cleanupAfterExternalStop(context, animationGroup);\r\n            if (virtualStopFrame !== undefined) {\r\n                animationGroup.setVirtualCurrentFrame(virtualStopFrame);\r\n            }\r\n            // Skip the animation-end observable so that stopping does not activate the originating\r\n            // starting block's `done` flow. When an animation is\r\n            // stopped (animation/stop or animation/stopAt) the previously associated `done` flows MUST NOT be\r\n            // activated; only animation/stopAt's own `done` flow (fired from _executeOnTick) should run.\r\n            if (suppressAnimationEnd) {\r\n                animationGroup.stop(true);\r\n            } else {\r\n                animationGroup.stop();\r\n            }\r\n            const remainingIndex = currentlyRunning.indexOf(animationGroup.uniqueId);\r\n            if (remainingIndex !== -1) {\r\n                currentlyRunning.splice(remainingIndex, 1);\r\n                context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunning);\r\n            }\r\n        } else {\r\n            // Logger.Warn(\"Trying to stop an animation that is not running.\");\r\n            // no-op for now. Probably no need to log anything here.\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphStopAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphStopAnimationBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.StopAnimation, FlowGraphStopAnimationBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { RichTypeAny } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { type AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * @experimental\r\n * Block that pauses a running animation\r\n */\r\nexport class FlowGraphPauseAnimationBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input connection: The animation to pause.\r\n     */\r\n    public readonly animationToPause: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.animationToPause = this.registerDataInput(\"animationToPause\", RichTypeAny);\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext): void {\r\n        const animationToPauseValue = this.animationToPause.getValue(context);\r\n        animationToPauseValue.pause();\r\n        this.out._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.PauseAnimation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphPauseAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphPauseAnimationBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.PauseAnimation, FlowGraphPauseAnimationBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type EasingFunction } from \"core/Animations/easing\";\nimport { Constants } from \"core/Engines/constants\";\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { type FlowGraphTypes, getRichTypeByAnimationType, getRichTypeByFlowGraphType, RichTypeAny, RichTypeNumber, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Animation, AnimationCreateAnimation } from \"core/Animations/animation.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the interpolation block.\n */\nexport interface IFlowGraphInterpolationBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The number of keyframes to interpolate between.\n     * Will default to 1 if not provided (i.e. from currentValue to a provided value in the time provided)\n     */\n    keyFramesCount?: number;\n\n    /**\n     * The duration of the interpolation.\n     */\n    duration?: number;\n\n    /**\n     * The name of the property that will be interpolated.\n     */\n    propertyName?: string | string[];\n\n    /**\n     * The type of the animation to create.\n     * Default is ANIMATIONTYPE_FLOAT\n     * This cannot be changed after construction, so make sure to pass the right value.\n     */\n    animationType?: number | FlowGraphTypes;\n}\n\n/**\n * This block is responsible for interpolating between two values.\n * The babylon concept used is Animation, and it is the output of this block.\n *\n * Note that values will be parsed when the in connection is triggered. until then changing the value will not trigger a new interpolation.\n *\n * Internally this block uses the Animation class.\n *\n * Note that if the interpolation is already running a signal will be sent to stop the animation group running it.\n */\nexport class FlowGraphInterpolationBlock<T> extends FlowGraphBlock {\n    /**\n     * Input connection: The value to interpolate from.\n     * Optional. If not provided, the current value will be used.\n     * Note that if provided, every time the animation is created this value will be used!\n     */\n    public readonly initialValue: FlowGraphDataConnection<T>;\n\n    /**\n     * Input connection: The value to interpolate to.\n     * Optional. This can also be set using the KeyFrames input!\n     * If provided it will be set to the last keyframe value.\n     */\n    public readonly endValue: FlowGraphDataConnection<T>;\n\n    /**\n     * output connection: The animation that will be created when in is triggered.\n     */\n    public readonly animation: FlowGraphDataConnection<Animation | Animation[]>;\n\n    /**\n     * Input connection: An optional easing function to use for the interpolation.\n     */\n    public readonly easingFunction: FlowGraphDataConnection<EasingFunction>;\n\n    /**\n     * Input connection: The name of the property that will be set\n     */\n    public readonly propertyName: FlowGraphDataConnection<string | string[]>;\n\n    /**\n     * If provided, this function will be used to create the animation object(s).\n     */\n    public readonly customBuildAnimation: FlowGraphDataConnection<\n        (target: any, propertname: any, context: FlowGraphContext) => (keys: any[], fps: number, animationType: number, easingFunction?: EasingFunction) => Animation | Animation[]\n    >;\n\n    /**\n     * The keyframes to interpolate between.\n     * Each keyframe has a duration input and a value input.\n     */\n    public readonly keyFrames: {\n        duration: FlowGraphDataConnection<number>;\n        value: FlowGraphDataConnection<T>;\n    }[] = [];\n\n    constructor(config: IFlowGraphInterpolationBlockConfiguration = {}) {\n        super(config);\n        const type =\n            typeof config?.animationType === \"string\"\n                ? getRichTypeByFlowGraphType(config.animationType)\n                : getRichTypeByAnimationType(config?.animationType ?? Constants.ANIMATIONTYPE_FLOAT);\n\n        const numberOfKeyFrames = config?.keyFramesCount ?? 1;\n        const duration = this.registerDataInput(`duration_0`, RichTypeNumber, 0);\n        const value = this.registerDataInput(`value_0`, type);\n        this.keyFrames.push({ duration, value });\n        for (let i = 1; i < numberOfKeyFrames + 1; i++) {\n            const duration = this.registerDataInput(`duration_${i}`, RichTypeNumber, i === numberOfKeyFrames ? config.duration : undefined);\n            const value = this.registerDataInput(`value_${i}`, type);\n            this.keyFrames.push({ duration, value });\n        }\n        this.initialValue = this.keyFrames[0].value;\n        this.endValue = this.keyFrames[numberOfKeyFrames].value;\n        this.easingFunction = this.registerDataInput(\"easingFunction\", RichTypeAny);\n        this.animation = this.registerDataOutput(\"animation\", RichTypeAny);\n        this.propertyName = this.registerDataInput(\"propertyName\", RichTypeString, config?.propertyName);\n        this.customBuildAnimation = this.registerDataInput(\"customBuildAnimation\", RichTypeAny);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const interpolationAnimations = context._getGlobalContextVariable(\"interpolationAnimations\", []) as number[];\n        const propertyName = this.propertyName.getValue(context);\n        const easingFunction = this.easingFunction.getValue(context);\n        const animation = this._createAnimation(context, propertyName, easingFunction);\n        // If an old animation exists, it will be ignored here.\n        // This is because if the animation is running and they both have the same target, the old will be stopped.\n        // This doesn't happen here, it happens in the play animation block.\n        this.animation.setValue(animation, context);\n        // to make sure no 2 interpolations are running on the same target, we will mark the animation in the context\n        if (Array.isArray(animation)) {\n            for (const anim of animation) {\n                interpolationAnimations.push(anim.uniqueId);\n            }\n        } else {\n            interpolationAnimations.push(animation.uniqueId);\n        }\n        context._setGlobalContextVariable(\"interpolationAnimations\", interpolationAnimations);\n    }\n\n    private _createAnimation(context: FlowGraphContext, propertyName: string | string[], easingFunction: EasingFunction): Animation | Animation[] {\n        const type = this.initialValue.richType;\n        const keys: { frame: number; value: T }[] = [];\n        // add initial value\n        const currentValue = this.initialValue.getValue(context) || type.defaultValue;\n        keys.push({ frame: 0, value: currentValue });\n        const numberOfKeyFrames = this.config?.numberOfKeyFrames ?? 1;\n        for (let i = 1; i < numberOfKeyFrames + 1; i++) {\n            const duration = this.keyFrames[i].duration?.getValue(context);\n            let value = this.keyFrames[i].value?.getValue(context);\n            if (i === numberOfKeyFrames - 1) {\n                value = value || type.defaultValue;\n            }\n            if (duration !== undefined && value) {\n                // convert duration to frames, based on 60 fps\n                keys.push({ frame: duration * 60, value });\n            }\n        }\n        const customBuildAnimation = this.customBuildAnimation.getValue(context);\n        if (customBuildAnimation) {\n            return customBuildAnimation(null, null, context)(keys, 60, type.animationType, easingFunction);\n        }\n        if (typeof propertyName === \"string\") {\n            const animation = AnimationCreateAnimation(propertyName, type.animationType, 60, easingFunction);\n            animation.setKeys(keys);\n            return [animation];\n        } else {\n            const animations = propertyName.map((name) => {\n                const animation = AnimationCreateAnimation(name, type.animationType, 60, easingFunction);\n                animation.setKeys(keys);\n                return animation;\n            });\n            return animations;\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ValueInterpolation;\n    }\n}\n\n// #L54P2C\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphInterpolationBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphInterpolationBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.ValueInterpolation, FlowGraphInterpolationBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type EasingFunction, BackEase, BezierCurveEase, BounceEase, CircleEase, CubicEase, ElasticEase, ExponentialEase } from \"core/Animations/easing\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * The type of the easing function.\n */\nexport const enum EasingFunctionType {\n    CircleEase = 0,\n    BackEase = 1,\n    BounceEase = 2,\n    CubicEase = 3,\n    ElasticEase = 4,\n    ExponentialEase = 5,\n    PowerEase = 6,\n    QuadraticEase = 7,\n    QuarticEase = 8,\n    QuinticEase = 9,\n    SineEase = 10,\n    BezierCurveEase = 11,\n}\n\n/**\n * @internal\n * Creates an easing function object based on the type and parameters provided.\n * This is not tree-shaking friendly, so if you need cubic bezier, use the dedicated bezier block.\n * @param type The type of the easing function.\n * @param controlPoint1 The first control point for the bezier curve.\n * @param controlPoint2 The second control point for the bezier curve.\n * @returns The easing function object.\n */\nfunction CreateEasingFunction(type: EasingFunctionType, ...parameters: number[]): EasingFunction {\n    switch (type) {\n        case EasingFunctionType.BezierCurveEase:\n            return new BezierCurveEase(...parameters);\n        case EasingFunctionType.CircleEase:\n            return new CircleEase();\n        case EasingFunctionType.BackEase:\n            return new BackEase(...parameters);\n        case EasingFunctionType.BounceEase:\n            return new BounceEase(...parameters);\n        case EasingFunctionType.CubicEase:\n            return new CubicEase();\n        case EasingFunctionType.ElasticEase:\n            return new ElasticEase(...parameters);\n        case EasingFunctionType.ExponentialEase:\n            return new ExponentialEase(...parameters);\n        default:\n            throw new Error(\"Easing type not yet implemented\");\n    }\n}\n\n/**\n * An easing block that generates an easingFunction object based on the data provided.\n */\nexport class FlowGraphEasingBlock extends FlowGraphBlock {\n    /**\n     * Input connection: The type of the easing function.\n     */\n    public readonly type: FlowGraphDataConnection<EasingFunctionType>;\n\n    /**\n     * Input connection: The mode of the easing function.\n     * EasingFunction.EASINGMODE_EASEIN, EasingFunction.EASINGMODE_EASEOUT, EasingFunction.EASINGMODE_EASEINOUT\n     */\n    public readonly mode: FlowGraphDataConnection<number>;\n\n    /**\n     * Input connection:parameters for easing. for example control points for BezierCurveEase.\n     */\n    public readonly parameters: FlowGraphDataConnection<number[]>;\n\n    /**\n     * Output connection: The easing function object.\n     */\n    public readonly easingFunction: FlowGraphDataConnection<EasingFunction>;\n\n    /**\n     * Internal cache of reusable easing functions.\n     * key is type-mode-properties\n     */\n    private _easingFunctions: { [key: string]: EasingFunction } = {};\n\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config?: IFlowGraphBlockConfiguration\n    ) {\n        super(config);\n\n        this.type = this.registerDataInput(\"type\", RichTypeAny, 11);\n        this.mode = this.registerDataInput(\"mode\", RichTypeNumber, 0);\n        this.parameters = this.registerDataInput(\"parameters\", RichTypeAny, [1, 0, 0, 1]);\n\n        this.easingFunction = this.registerDataOutput(\"easingFunction\", RichTypeAny);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext) {\n        const type = this.type.getValue(context);\n        const mode = this.mode.getValue(context);\n        const parameters = this.parameters.getValue(context);\n\n        if (type === undefined || mode === undefined) {\n            return;\n        }\n\n        const key = `${type}-${mode}-${parameters.join(\"-\")}`;\n        if (!this._easingFunctions[key]) {\n            const easing = CreateEasingFunction(type, ...parameters);\n            easing.setEasingMode(mode);\n            this._easingFunctions[key] = easing;\n        }\n        this.easingFunction.setValue(this._easingFunctions[key], context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.Easing;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphEasingBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphEasingBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.Easing, FlowGraphEasingBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { BezierCurveEase, type EasingFunction } from \"core/Animations/easing\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber, RichTypeVector2 } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Vector2 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Solves the CSS cubic-bezier easing for input progress `t`: find the curve parameter `u` where the\n * X coordinate equals `t` (implicit endpoints P0=(0,0), P3=(1,1)), then return the Y coordinate at `u`.\n *\n * This is a local solver rather than the shared `BezierCurve.Interpolate` on purpose: KHR_interactivity\n * needs a root finder that stays finite at stationary derivatives (e.g. control points (1,1)/(0,1), where\n * dX/du is 0 at the root). The shared solver uses plain Newton iteration and returns NaN there, so it must\n * not be changed for this consumer. Newton steps are taken when they stay inside the bracketing interval and\n * the derivative is non-negligible; otherwise the step falls back to bisection, which always converges.\n * @param t the input progress in [0, 1]\n * @param x1 X of the first control point\n * @param y1 Y of the first control point\n * @param x2 X of the second control point\n * @param y2 Y of the second control point\n * @returns the eased output progress\n */\nfunction _SolveCssCubicBezier(t: number, x1: number, y1: number, x2: number, y2: number): number {\n    if (t <= 0) {\n        return 0;\n    }\n    if (t >= 1) {\n        return 1;\n    }\n    const fx0 = 1 - 3 * x2 + 3 * x1;\n    const fx1 = 3 * x2 - 6 * x1;\n    const fx2 = 3 * x1;\n\n    let lowerBound = 0;\n    let upperBound = 1;\n    let u = t;\n    for (let i = 0; i < 8; i++) {\n        const u2 = u * u;\n        const u3 = u2 * u;\n        const x = fx0 * u3 + fx1 * u2 + fx2 * u;\n        const error = x - t;\n        if (Math.abs(error) < 1e-7) {\n            break;\n        }\n        if (error > 0) {\n            upperBound = u;\n        } else {\n            lowerBound = u;\n        }\n        const derivative = 3 * fx0 * u2 + 2 * fx1 * u + fx2;\n        const newtonU = Math.abs(derivative) > 1e-7 ? u - error / derivative : NaN;\n        u = Number.isFinite(newtonU) && newtonU > lowerBound && newtonU < upperBound ? newtonU : (lowerBound + upperBound) * 0.5;\n    }\n\n    const fy0 = 1 - 3 * y2 + 3 * y1;\n    const fy1 = 3 * y2 - 6 * y1;\n    const fy2 = 3 * y1;\n    return fy0 * u * u * u + fy1 * u * u + fy2 * u;\n}\n\n/**\n * A {@link BezierCurveEase} that resolves the curve with {@link _SolveCssCubicBezier} so degenerate control\n * points (stationary X derivative) stay finite. It inherits the public `x1`/`y1`/`x2`/`y2` fields and the\n * easing-mode handling; only the core evaluation is replaced.\n */\nclass InteractivityBezierCurveEase extends BezierCurveEase {\n    public override easeInCore(gradient: number): number {\n        return _SolveCssCubicBezier(gradient, this.x1, this.y1, this.x2, this.y2);\n    }\n}\n\n/**\n * An easing block that generates a cubic Bézier easing function based on the data provided.\n *\n * Follows CSS cubic-bezier semantics: for input progress `t`, solve the curve parameter where X\n * equals `t`, then use the corresponding Y coordinate as the eased output progress.\n */\nexport class FlowGraphBezierCurveEasingBlock extends FlowGraphBlock {\n    /**\n     * Input connection: The mode of the easing function.\n     * EasingFunction.EASINGMODE_EASEIN, EasingFunction.EASINGMODE_EASEOUT, EasingFunction.EASINGMODE_EASEINOUT\n     */\n    public readonly mode: FlowGraphDataConnection<number>;\n\n    /**\n     * Input connection: Control point 1 for bezier curve.\n     */\n    public readonly controlPoint1: FlowGraphDataConnection<Vector2>;\n    /**\n     * Input connection: Control point 2 for bezier curve.\n     */\n    public readonly controlPoint2: FlowGraphDataConnection<Vector2>;\n\n    /**\n     * Output connection: The easing function object.\n     */\n    public readonly easingFunction: FlowGraphDataConnection<EasingFunction>;\n\n    /**\n     * Internal cache of reusable easing functions.\n     * key is type-mode-properties\n     */\n    private _easingFunctions: { [key: string]: EasingFunction } = {};\n\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config?: IFlowGraphBlockConfiguration\n    ) {\n        super(config);\n\n        this.mode = this.registerDataInput(\"mode\", RichTypeNumber, 0);\n        this.controlPoint1 = this.registerDataInput(\"controlPoint1\", RichTypeVector2);\n        this.controlPoint2 = this.registerDataInput(\"controlPoint2\", RichTypeVector2);\n\n        this.easingFunction = this.registerDataOutput(\"easingFunction\", RichTypeAny);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext) {\n        const mode = this.mode.getValue(context);\n        const controlPoint1 = this.controlPoint1.getValue(context);\n        const controlPoint2 = this.controlPoint2.getValue(context);\n\n        if (mode === undefined) {\n            return;\n        }\n\n        const key = `${mode}-${controlPoint1.x}-${controlPoint1.y}-${controlPoint2.x}-${controlPoint2.y}`;\n        if (!this._easingFunctions[key]) {\n            const easing = new InteractivityBezierCurveEase(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y);\n            easing.setEasingMode(mode);\n            this._easingFunctions[key] = easing;\n        }\n        this.easingFunction.setValue(this._easingFunctions[key], context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.BezierCurveEasing;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphBezierCurveEasingBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphBezierCurveEasingBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.BezierCurveEasing, FlowGraphBezierCurveEasingBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that applies a force to a physics body at a given location.\n */\nexport class FlowGraphApplyForceBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The physics body to apply the force to.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Input connection: The force vector to apply.\n     */\n    public readonly force: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Input connection: The world-space location at which to apply the force.\n     */\n    public readonly location: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Constructs a new FlowGraphApplyForceBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.force = this.registerDataInput(\"force\", RichTypeVector3);\n        this.location = this.registerDataInput(\"location\", RichTypeVector3);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            this._reportError(context, \"No physics body provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        const forceVec = this.force.getValue(context);\n        const locationVec = this.location.getValue(context);\n        physicsBody.applyForce(forceVec, locationVec);\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsApplyForce;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphApplyForceBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphApplyForceBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsApplyForce, FlowGraphApplyForceBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that applies an impulse to a physics body at a given location.\n * Unlike a force (which is applied over time), an impulse is an instantaneous\n * change in momentum.\n */\nexport class FlowGraphApplyImpulseBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The physics body to apply the impulse to.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Input connection: The impulse vector to apply.\n     */\n    public readonly impulse: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Input connection: The world-space location at which to apply the impulse.\n     */\n    public readonly location: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Constructs a new FlowGraphApplyImpulseBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.impulse = this.registerDataInput(\"impulse\", RichTypeVector3);\n        this.location = this.registerDataInput(\"location\", RichTypeVector3);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            this._reportError(context, \"No physics body provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        const impulseVec = this.impulse.getValue(context);\n        const locationVec = this.location.getValue(context);\n        physicsBody.applyImpulse(impulseVec, locationVec);\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsApplyImpulse;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphApplyImpulseBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphApplyImpulseBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsApplyImpulse, FlowGraphApplyImpulseBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that sets the linear velocity of a physics body.\n */\nexport class FlowGraphSetLinearVelocityBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The physics body whose velocity will be set.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Input connection: The linear velocity to set.\n     */\n    public readonly velocity: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Constructs a new FlowGraphSetLinearVelocityBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.velocity = this.registerDataInput(\"velocity\", RichTypeVector3);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            this._reportError(context, \"No physics body provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        physicsBody.setLinearVelocity(this.velocity.getValue(context));\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsSetLinearVelocity;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetLinearVelocityBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetLinearVelocityBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsSetLinearVelocity, FlowGraphSetLinearVelocityBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that sets the angular velocity of a physics body.\n */\nexport class FlowGraphSetAngularVelocityBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The physics body whose angular velocity will be set.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Input connection: The angular velocity vector to set.\n     */\n    public readonly velocity: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Constructs a new FlowGraphSetAngularVelocityBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.velocity = this.registerDataInput(\"velocity\", RichTypeVector3);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            this._reportError(context, \"No physics body provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        physicsBody.setAngularVelocity(this.velocity.getValue(context));\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsSetAngularVelocity;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetAngularVelocityBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetAngularVelocityBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsSetAngularVelocity, FlowGraphSetAngularVelocityBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { PhysicsMotionType } from \"../../../../Physics/v2/IPhysicsEnginePlugin\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that sets the motion type of a physics body.\n *\n * The motion type input is a number corresponding to the PhysicsMotionType enum:\n * - 0 = STATIC (not moving, not affected by forces)\n * - 1 = ANIMATED (not affected by other bodies, but pushes them)\n * - 2 = DYNAMIC (fully simulated, affected by forces and collisions)\n */\nexport class FlowGraphSetPhysicsMotionTypeBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The physics body whose motion type will be set.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Input connection: The motion type to set (0=STATIC, 1=ANIMATED, 2=DYNAMIC).\n     */\n    public readonly motionType: FlowGraphDataConnection<number>;\n\n    /**\n     * Constructs a new FlowGraphSetPhysicsMotionTypeBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.motionType = this.registerDataInput(\"motionType\", RichTypeNumber, PhysicsMotionType.DYNAMIC);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            this._reportError(context, \"No physics body provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        physicsBody.setMotionType(this.motionType.getValue(context));\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsSetMotionType;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetPhysicsMotionTypeBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetPhysicsMotionTypeBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsSetMotionType, FlowGraphSetPhysicsMotionTypeBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeBoolean, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type AbstractSound } from \"../../../../AudioV2/abstractAudio/abstractSound\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that plays an Audio V2 sound.\n */\nexport class FlowGraphPlaySoundBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The sound to play.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Input connection: The volume to play at (0–1). Defaults to 1.\n     */\n    public readonly volume: FlowGraphDataConnection<number>;\n\n    /**\n     * Input connection: The time offset in seconds to start playback from. Defaults to 0.\n     */\n    public readonly startOffset: FlowGraphDataConnection<number>;\n\n    /**\n     * Input connection: Whether the sound should loop. Defaults to false.\n     */\n    public readonly loop: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Constructs a new FlowGraphPlaySoundBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n        this.volume = this.registerDataInput(\"volume\", RichTypeNumber, 1);\n        this.startOffset = this.registerDataInput(\"startOffset\", RichTypeNumber, 0);\n        this.loop = this.registerDataInput(\"loop\", RichTypeBoolean, false);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            this._reportError(context, \"No sound provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        const vol = this.volume.getValue(context);\n        const offset = this.startOffset.getValue(context);\n        const loopVal = this.loop.getValue(context);\n        soundValue.play({ volume: vol, startOffset: offset, loop: loopVal });\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioPlaySound;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPlaySoundBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPlaySoundBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioPlaySound, FlowGraphPlaySoundBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type AbstractSound } from \"../../../../AudioV2/abstractAudio/abstractSound\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that stops an Audio V2 sound.\n */\nexport class FlowGraphStopSoundBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The sound to stop.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Constructs a new FlowGraphStopSoundBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            this._reportError(context, \"No sound provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        soundValue.stop();\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioStopSound;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphStopSoundBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphStopSoundBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioStopSound, FlowGraphStopSoundBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type AbstractSound } from \"../../../../AudioV2/abstractAudio/abstractSound\";\nimport { SoundState } from \"../../../../AudioV2/soundState\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that pauses an Audio V2 sound. If the sound is already paused, resumes it.\n */\nexport class FlowGraphPauseSoundBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The sound to pause or resume.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Constructs a new FlowGraphPauseSoundBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            this._reportError(context, \"No sound provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        if (soundValue.state === SoundState.Paused) {\n            soundValue.resume();\n        } else if (soundValue.state === SoundState.Starting || soundValue.state === SoundState.Started) {\n            soundValue.pause();\n        }\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioPauseSound;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPauseSoundBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPauseSoundBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioPauseSound, FlowGraphPauseSoundBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type AbstractSound } from \"../../../../AudioV2/abstractAudio/abstractSound\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A block that sets the volume of an Audio V2 sound.\n */\nexport class FlowGraphSetSoundVolumeBlock extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The sound to set the volume on.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Input connection: The target volume (0–1). Defaults to 1.\n     */\n    public readonly volume: FlowGraphDataConnection<number>;\n\n    /**\n     * Constructs a new FlowGraphSetSoundVolumeBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n        this.volume = this.registerDataInput(\"volume\", RichTypeNumber, 1);\n    }\n\n    /**\n     * @internal\n     */\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            this._reportError(context, \"No sound provided\");\n            this.out._activateSignal(context);\n            return;\n        }\n        const vol = this.volume.getValue(context);\n        soundValue.volume = vol;\n        this.out._activateSignal(context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioSetVolume;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetSoundVolumeBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetSoundVolumeBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioSetVolume, FlowGraphSetSoundVolumeBlock);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\r\nimport { RichTypeBoolean, RichTypeAny } from \"../../flowGraphRichTypes.pure\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that returns a value based on a condition.\r\n */\r\nexport class FlowGraphConditionalDataBlock<T> extends FlowGraphBlock {\r\n    /**\r\n     * Input connection: The condition to check.\r\n     */\r\n    public readonly condition: FlowGraphDataConnection<boolean>;\r\n    /**\r\n     * Input connection: The value to return if the condition is true.\r\n     */\r\n    public readonly onTrue: FlowGraphDataConnection<T>;\r\n    /**\r\n     * Input connection: The value to return if the condition is false.\r\n     */\r\n    public readonly onFalse: FlowGraphDataConnection<T>;\r\n\r\n    /**\r\n     * Output connection: The value that was returned.\r\n     */\r\n    public readonly output: FlowGraphDataConnection<T>;\r\n\r\n    /**\r\n     * Creates a new instance of the block\r\n     * @param config optional configuration for this block\r\n     */\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n\r\n        this.condition = this.registerDataInput(\"condition\", RichTypeBoolean);\r\n        this.onTrue = this.registerDataInput(\"onTrue\", RichTypeAny);\r\n        this.onFalse = this.registerDataInput(\"onFalse\", RichTypeAny);\r\n\r\n        this.output = this.registerDataOutput(\"output\", RichTypeAny);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        // get the value of the condition\r\n        const condition = this.condition.getValue(context);\r\n        // set the value based on the condition truth-ness.\r\n        this.output.setValue(condition ? this.onTrue.getValue(context) : this.onFalse.getValue(context), context);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Conditional;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphConditionalDataBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphConditionalDataBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Conditional, FlowGraphConditionalDataBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"../../flowGraphBlock\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\r\nimport { RichTypeAny } from \"../../flowGraphRichTypes.pure\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * The configuration of the FlowGraphGetVariableBlock.\r\n */\r\nexport interface IFlowGraphGetVariableBlockConfiguration<T> extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The name of the variable to get.\r\n     */\r\n    variable: string;\r\n\r\n    /**\r\n     * The initial value of the variable.\r\n     */\r\n    initialValue?: T;\r\n}\r\n\r\n/**\r\n * A block that gets the value of a variable.\r\n * Variables are an stored in the context of the flow graph.\r\n */\r\nexport class FlowGraphGetVariableBlock<T> extends FlowGraphBlock {\r\n    /**\r\n     * Output connection: The value of the variable.\r\n     */\r\n    public readonly value: FlowGraphDataConnection<T>;\r\n\r\n    /**\r\n     * Construct a FlowGraphGetVariableBlock.\r\n     * @param config construction parameters\r\n     */\r\n    constructor(public override config: IFlowGraphGetVariableBlockConfiguration<T>) {\r\n        super(config);\r\n\r\n        // The output connection has to have the name of the variable.\r\n        this.value = this.registerDataOutput(\"value\", RichTypeAny, config.initialValue);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        const variableNameValue = this.config.variable;\r\n        if (context.hasVariable(variableNameValue)) {\r\n            this.value.setValue(context.getVariable(variableNameValue), context);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @param serializationObject the object to serialize to\r\n     */\r\n    public override serialize(serializationObject?: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.config.variable = this.config.variable;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.GetVariable;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphGetVariableBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphGetVariableBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.GetVariable, FlowGraphGetVariableBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../flowGraphExecutionBlockWithOutSignal\";\nimport { type FlowGraphSignalConnection } from \"../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { RichTypeAny } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * The configuration of the FlowGraphGetVariableBlock.\n */\nexport interface IFlowGraphSetVariableBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The name of the variable to set.\n     */\n    variable?: string;\n\n    /**\n     * The name of the variables to set.\n     */\n    variables?: string[];\n}\n\n/**\n * This block will set a variable on the context.\n */\nexport class FlowGraphSetVariableBlock<T> extends FlowGraphExecutionBlockWithOutSignal {\n    constructor(config: IFlowGraphSetVariableBlockConfiguration) {\n        super(config);\n        // check if the variable is an array\n        if (config.variables && config.variable) {\n            throw new Error(\"FlowGraphSetVariableBlock: variable and variables are both defined\");\n        }\n        // check if we have either a variable or variables. If we have variables, set the inputs correctly\n        if (config.variables) {\n            for (const variable of config.variables) {\n                this.registerDataInput(variable, RichTypeAny);\n            }\n        } else {\n            this.registerDataInput(\"value\", RichTypeAny);\n        }\n    }\n\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        if (this.config?.variables) {\n            for (const variable of this.config.variables) {\n                this._saveVariable(context, variable);\n            }\n        } else {\n            this._saveVariable(context, this.config?.variable, \"value\");\n        }\n        this.out._activateSignal(context);\n    }\n\n    private _saveVariable(context: FlowGraphContext, variableName: string, inputName?: string): void {\n        // check if there is an animation(group) running on this variable. If there is, stop the animation - a value was force-set.\n        const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\n        for (const animationUniqueId of currentlyRunningAnimationGroups) {\n            const animationGroup = context.assetsContext.animationGroups.find((animationGroup) => animationGroup.uniqueId == animationUniqueId);\n            if (animationGroup) {\n                // check if there is a target animation that has the target set to be the context\n                for (const targetAnimation of animationGroup.targetedAnimations) {\n                    // check if the target property is the variable we are setting\n                    if (targetAnimation.target === context) {\n                        // check the variable name\n                        if (targetAnimation.animation.targetProperty === variableName) {\n                            // stop the animation\n                            animationGroup.stop();\n                            // remove the animation from the currently running animations\n                            const index = currentlyRunningAnimationGroups.indexOf(animationUniqueId);\n                            if (index > -1) {\n                                currentlyRunningAnimationGroups.splice(index, 1);\n                            }\n                            context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        const value = this.getDataInput(inputName || variableName)?.getValue(context);\n        context.setVariable(variableName, value);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.SetVariable;\n    }\n\n    public override serialize(serializationObject?: any): void {\n        super.serialize(serializationObject);\n        serializationObject.config.variable = this.config?.variable;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetVariableBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetVariableBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.SetVariable, FlowGraphSetVariableBlock);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\r\nimport { RichTypeAny, RichTypeVector3 } from \"../../flowGraphRichTypes.pure\";\r\nimport { TmpVectors, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../../../Meshes/transformNode.pure\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * This blocks transforms a vector from one coordinate system to another.\r\n */\r\nexport class FlowGraphTransformCoordinatesSystemBlock extends FlowGraphBlock {\r\n    /**\r\n     * Input connection: The source coordinate system.\r\n     */\r\n    public readonly sourceSystem: FlowGraphDataConnection<TransformNode>;\r\n    /**\r\n     * Input connection: The destination coordinate system.\r\n     */\r\n    public readonly destinationSystem: FlowGraphDataConnection<TransformNode>;\r\n    /**\r\n     * Input connection: The coordinates to transform.\r\n     */\r\n    public readonly inputCoordinates: FlowGraphDataConnection<Vector3>;\r\n    /**\r\n     * Output connection: The transformed coordinates.\r\n     */\r\n    public readonly outputCoordinates: FlowGraphDataConnection<Vector3>;\r\n\r\n    /**\r\n     * Creates a new FlowGraphCoordinateTransformBlock\r\n     * @param config optional configuration for this block\r\n     */\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n\r\n        this.sourceSystem = this.registerDataInput(\"sourceSystem\", RichTypeAny);\r\n        this.destinationSystem = this.registerDataInput(\"destinationSystem\", RichTypeAny);\r\n        this.inputCoordinates = this.registerDataInput(\"inputCoordinates\", RichTypeVector3);\r\n        this.outputCoordinates = this.registerDataOutput(\"outputCoordinates\", RichTypeVector3);\r\n    }\r\n\r\n    public override _updateOutputs(_context: FlowGraphContext): void {\r\n        const sourceSystemValue = this.sourceSystem.getValue(_context);\r\n        const destinationSystemValue = this.destinationSystem.getValue(_context);\r\n        const inputCoordinatesValue = this.inputCoordinates.getValue(_context);\r\n\r\n        // takes coordinates from source space to world space\r\n        const sourceWorld = sourceSystemValue.getWorldMatrix();\r\n        // takes coordinates from destination space to world space\r\n        const destinationWorld = destinationSystemValue.getWorldMatrix();\r\n        const destinationWorldInverse = TmpVectors.Matrix[0].copyFrom(destinationWorld);\r\n        // takes coordinates from world space to destination space\r\n        destinationWorldInverse.invert();\r\n\r\n        const sourceToDestination = TmpVectors.Matrix[1];\r\n        // takes coordinates from source space to world space to destination space\r\n        destinationWorldInverse.multiplyToRef(sourceWorld, sourceToDestination);\r\n        const outputCoordinatesValue = this.outputCoordinates.getValue(_context);\r\n\r\n        Vector3.TransformCoordinatesToRef(inputCoordinatesValue, sourceToDestination, outputCoordinatesValue);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.TransformCoordinatesSystem;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphTransformCoordinatesSystemBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphTransformCoordinatesSystemBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.TransformCoordinatesSystem, FlowGraphTransformCoordinatesSystemBlock);\r\n}\r\n","import { type Nullable } from \"../../../types\";\r\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"../../flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection\";\r\nimport { type RichType, RichTypeBoolean } from \"../../flowGraphRichTypes.pure\";\r\n\r\nconst CacheName = \"cachedOperationValue\";\r\nconst CacheExecIdName = \"cachedExecutionId\";\r\n\r\n/**\r\n * A block that will cache the result of an operation and deliver it as an output.\r\n */\r\nexport abstract class FlowGraphCachedOperationBlock<OutputT> extends FlowGraphBlock {\r\n    /**\r\n     * The output of the operation\r\n     */\r\n    public readonly value: FlowGraphDataConnection<OutputT>;\r\n\r\n    /**\r\n     * Output connection: Whether the value is valid.\r\n     */\r\n    public readonly isValid: FlowGraphDataConnection<boolean>;\r\n\r\n    private readonly _outputRichType: RichType<OutputT>;\r\n\r\n    constructor(outputRichType: RichType<OutputT>, config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n\r\n        this._outputRichType = outputRichType;\r\n        this.value = this.registerDataOutput(\"value\", outputRichType);\r\n        this.isValid = this.registerDataOutput(\"isValid\", RichTypeBoolean);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Operation to realize\r\n     * @param context the graph context\r\n     */\r\n    public abstract _doOperation(context: FlowGraphContext): OutputT | undefined;\r\n\r\n    /**\r\n     * The value delivered on the `value` output when the operation cannot produce a result.\r\n     *\r\n     * Defaults to the output type's default value. Override this when a block defines a different\r\n     * value for that case, for example a polymorphic block whose output type is only known from its\r\n     * inputs. Implementations must return a fresh value rather than a shared instance, because\r\n     * consumers may mutate the value they receive.\r\n     * @param _context the graph context\r\n     * @returns the value to deliver alongside `isValid = false`\r\n     */\r\n    protected _getInvalidOutputValue(_context: FlowGraphContext): OutputT {\r\n        const defaultValue = this._outputRichType.defaultValue;\r\n        // The rich type defaults for object types (vectors, matrices, ...) are shared instances, so\r\n        // hand out a copy to keep a consumer from mutating the default for every other block.\r\n        const clone = (defaultValue as unknown as { clone?: () => OutputT })?.clone;\r\n        return typeof clone === \"function\" ? clone.call(defaultValue) : defaultValue;\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext) {\r\n        const cachedExecutionId = context._getExecutionVariable(this, CacheExecIdName, -1);\r\n        const cachedValue = context._getExecutionVariable<Nullable<OutputT>>(this, CacheName, null);\r\n        if (cachedValue !== undefined && cachedValue !== null && cachedExecutionId === context.executionId) {\r\n            this.isValid.setValue(true, context);\r\n            this.value.setValue(cachedValue, context);\r\n        } else {\r\n            try {\r\n                const calculatedValue = this._doOperation(context);\r\n                if (calculatedValue === undefined || calculatedValue === null) {\r\n                    this._setInvalid(context);\r\n                    return;\r\n                }\r\n                context._setExecutionVariable(this, CacheName, calculatedValue);\r\n                context._setExecutionVariable(this, CacheExecIdName, context.executionId);\r\n                this.value.setValue(calculatedValue, context);\r\n                this.isValid.setValue(true, context);\r\n            } catch (e) {\r\n                this._setInvalid(context);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reports the operation as invalid. `value` is still assigned, so it never reports a stale\r\n     * result from an earlier execution nor an undefined value on the first one.\r\n     * @param context the graph context\r\n     */\r\n    private _setInvalid(context: FlowGraphContext): void {\r\n        this.isValid.setValue(false, context);\r\n        this.value.setValue(this._getInvalidOutputValue(context), context);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type AssetType, type FlowGraphAssetType } from \"core/FlowGraph/flowGraphAssetsContext\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { FlowGraphCachedOperationBlock } from \"./flowGraphCachedOperationBlock\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the FlowGraphGetPropertyBlock.\n */\nexport interface IFlowGraphGetPropertyBlockConfiguration<O extends FlowGraphAssetType> extends IFlowGraphBlockConfiguration {\n    /**\n     * The name of the property that will be set\n     */\n    propertyName?: string;\n\n    /**\n     * The target asset from which the property will be retrieved\n     */\n    object?: AssetType<O>;\n\n    /**\n     * If true, the block will reset the output to the default value when the target asset is undefined.\n     */\n    resetToDefaultWhenUndefined?: boolean;\n}\n\n/**\n * This block will deliver a property of an asset, based on the property name and an input asset.\n * The property name can include dots (\".\"), which will be interpreted as a path to the property.\n *\n * For example, with an input of a mesh asset, the property name \"position.x\" will deliver the x component of the position of the mesh.\n *\n * Note that it is recommended to input the object on which you are working on (i.e. a material) rather than providing a mesh as object and then getting the material from it.\n */\nexport class FlowGraphGetPropertyBlock<P extends any, O extends FlowGraphAssetType> extends FlowGraphCachedOperationBlock<P> {\n    /**\n     * Input connection: The asset from which the property will be retrieved\n     */\n    public readonly object: FlowGraphDataConnection<AssetType<O>>;\n\n    /**\n     * Input connection: The name of the property that will be set\n     */\n    public readonly propertyName: FlowGraphDataConnection<string>;\n\n    /**\n     * Input connection: A function that can be used to get the value of the property.\n     * This will be used if defined, instead of the default get function.\n     */\n    public readonly customGetFunction: FlowGraphDataConnection<(target: AssetType<O>, propertyName: string, context: FlowGraphContext) => P | undefined>;\n\n    /**\n     * Constructs a new FlowGraphGetPropertyBlock.\n     * @param config - the configuration of the block\n     */\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config: IFlowGraphGetPropertyBlockConfiguration<O>\n    ) {\n        super(RichTypeAny, config);\n        this.object = this.registerDataInput(\"object\", RichTypeAny, config.object);\n        this.propertyName = this.registerDataInput(\"propertyName\", RichTypeString, config.propertyName);\n        this.customGetFunction = this.registerDataInput(\"customGetFunction\", RichTypeAny);\n    }\n\n    /**\n     * Retrieves the property value from the target object.\n     * @param context - the flow graph context\n     * @returns the property value, or undefined if the target or property name is not set\n     */\n    public override _doOperation(context: FlowGraphContext): P | undefined {\n        const getter = this.customGetFunction.getValue(context);\n        let value;\n        if (getter) {\n            value = getter(this.object.getValue(context), this.propertyName.getValue(context), context);\n        } else {\n            const target = this.object.getValue(context);\n            const propertyName = this.propertyName.getValue(context);\n            value = target && propertyName ? this._getPropertyValue(target, propertyName) : undefined;\n        }\n        return value;\n    }\n\n    private _getPropertyValue(target: AssetType<O>, propertyName: string): P | undefined {\n        const path = propertyName.split(\".\");\n        let value: any = target;\n        for (const prop of path) {\n            value = value[prop];\n            if (value === undefined) {\n                return;\n            }\n        }\n        return value as P;\n    }\n\n    /**\n     * Returns the class name of this block.\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.GetProperty;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphGetPropertyBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphGetPropertyBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.GetProperty, FlowGraphGetPropertyBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type AssetType, type FlowGraphAssetType } from \"core/FlowGraph/flowGraphAssetsContext\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"core/FlowGraph/flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeAny, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"core/FlowGraph/flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the FlowGraphSetPropertyBlock\n */\nexport interface IFlowGraphSetPropertyBlockConfiguration<O extends FlowGraphAssetType> {\n    /**\n     * The name of the property that will be set\n     */\n    propertyName?: string;\n\n    /**\n     * The target asset from which the property will be retrieved\n     */\n    target?: AssetType<O>;\n}\n\n/**\n * This block will set a property on a given target asset.\n * The property name can include dots (\".\"), which will be interpreted as a path to the property.\n * The target asset is an input and can be changed at any time.\n * The value of the property is an input and can be changed at any time.\n *\n * For example, with an input of a mesh asset, the property name \"position.x\" will set the x component of the position of the mesh.\n *\n * Note that it is recommended to input the object on which you are working on (i.e. a material) than providing a mesh and then getting the material from it.\n */\nexport class FlowGraphSetPropertyBlock<P extends any, O extends FlowGraphAssetType> extends FlowGraphExecutionBlockWithOutSignal {\n    /**\n     * Input connection: The value to set on the property.\n     */\n    public readonly value: FlowGraphDataConnection<P>;\n\n    /**\n     * Input connection: The target asset from which the property will be retrieved\n     */\n    public readonly object: FlowGraphDataConnection<AssetType<O>>;\n\n    /**\n     * Input connection: The name of the property that will be set\n     */\n    public readonly propertyName: FlowGraphDataConnection<string>;\n\n    /**\n     * Input connection: A function that can be used to set the value of the property.\n     * If set it will be used instead of the default set function.\n     */\n    public readonly customSetFunction: FlowGraphDataConnection<(target: AssetType<O>, propertyName: string, value: P, context: FlowGraphContext) => void>;\n\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config: IFlowGraphSetPropertyBlockConfiguration<O>\n    ) {\n        super(config);\n        this.object = this.registerDataInput(\"object\", RichTypeAny, config.target);\n        this.value = this.registerDataInput(\"value\", RichTypeAny);\n        this.propertyName = this.registerDataInput(\"propertyName\", RichTypeString, config.propertyName);\n        this.customSetFunction = this.registerDataInput(\"customSetFunction\", RichTypeAny);\n    }\n    public override _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n        try {\n            const target = this.object.getValue(context);\n            const value = this.value.getValue(context);\n            const propertyName = this.propertyName.getValue(context);\n\n            this._stopRunningAnimations(context, target, propertyName);\n\n            const setFunction = this.customSetFunction.getValue(context);\n            if (setFunction) {\n                setFunction(target, propertyName, value, context);\n            } else {\n                this._setPropertyValue(target, propertyName, value);\n            }\n        } catch (e) {\n            this._reportError(context, e);\n        }\n        this.out._activateSignal(context);\n    }\n\n    private _stopRunningAnimations(context: FlowGraphContext, target: any, propertyName: string) {\n        const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\n        for (const uniqueId of currentlyRunningAnimationGroups) {\n            const animationGroup = context.assetsContext.animationGroups.find((animationGroup) => animationGroup.uniqueId === uniqueId);\n            if (animationGroup) {\n                for (const targetedAnimations of animationGroup.targetedAnimations) {\n                    if (targetedAnimations.target === target && targetedAnimations.animation.targetProperty === propertyName) {\n                        animationGroup.stop(true);\n                        animationGroup.dispose();\n\n                        const index = currentlyRunningAnimationGroups.indexOf(uniqueId);\n                        if (index !== -1) {\n                            currentlyRunningAnimationGroups.splice(index, 1);\n                            context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private _setPropertyValue(target: AssetType<O>, propertyName: string, value: P): void {\n        const path = propertyName.split(\".\");\n        let obj = target as any;\n        for (let i = 0; i < path.length - 1; i++) {\n            const prop = path[i];\n            if (obj[prop] === undefined) {\n                obj[prop] = {};\n            }\n            obj = obj[prop];\n        }\n        obj[path[path.length - 1]] = value;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.SetProperty;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSetPropertyBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSetPropertyBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.SetProperty, FlowGraphSetPropertyBlock);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\r\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { getRichTypeFromValue } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { defaultValueSerializationFunction } from \"core/FlowGraph/serialization\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Configuration for a constant block.\r\n */\r\nexport interface IFlowGraphConstantBlockConfiguration<T> extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The value of the constant.\r\n     */\r\n    value: T;\r\n}\r\n/**\r\n * Block that returns a constant value.\r\n */\r\nexport class FlowGraphConstantBlock<T> extends FlowGraphBlock {\r\n    /**\r\n     * Output connection: The constant value.\r\n     */\r\n    public readonly output: FlowGraphDataConnection<T>;\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphConstantBlockConfiguration<T>\r\n    ) {\r\n        super(config);\r\n\r\n        this.output = this.registerDataOutput(\"output\", getRichTypeFromValue(config.value));\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        this.output.setValue(this.config.value, context);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.Constant;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @param serializationObject the object to serialize to\r\n     * @param valueSerializeFunction the function to use to serialize the value\r\n     */\r\n    public override serialize(\r\n        serializationObject: any = {},\r\n        valueSerializeFunction: (key: string, value: any, serializationObject: any) => any = defaultValueSerializationFunction\r\n    ) {\r\n        super.serialize(serializationObject);\r\n        valueSerializeFunction(\"value\", this.config.value, serializationObject.config);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphConstantBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphConstantBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Constant, FlowGraphConstantBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type AssetType, type FlowGraphAssetType, GetFlowGraphAssetWithType } from \"core/FlowGraph/flowGraphAssetsContext\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Nullable } from \"core/types\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { type FlowGraphNumber, getNumericValue } from \"core/FlowGraph/utils\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the get asset block.\n */\nexport interface IFlowGraphGetAssetBlockConfiguration<T> extends IFlowGraphBlockConfiguration {\n    /**\n     * The type of the asset that will be retrieved.\n     */\n    type: T;\n    /**\n     * The index of the asset in the corresponding array in the assets context.\n     * If not provided you can still change it using the input connection.\n     */\n    index?: number | FlowGraphInteger;\n\n    /**\n     * If set to true, instead of the index in the array it will search for the unique id of the asset.\n     * The value of index will be used as the unique id.\n     */\n    useIndexAsUniqueId?: boolean;\n}\n\n/**\n * A block that will deliver an asset as an output, based on its type and place in the assets index.\n *\n * The assets are loaded from the assetsContext defined in the context running this block. The assetsContext is a class extending AbstractClass,\n * meaning it can be a Scene, an AssetsContainers, and any other class that extends AbstractClass.\n */\nexport class FlowGraphGetAssetBlock<T extends FlowGraphAssetType> extends FlowGraphBlock {\n    /**\n     * Output connection: The value of the property.\n     */\n    public readonly value: FlowGraphDataConnection<Nullable<AssetType<T>>>;\n\n    /**\n     * Input connection: The type of the asset.\n     */\n    public readonly type: FlowGraphDataConnection<T>;\n\n    /**\n     * Input connection: The index of the asset in the corresponding array in the assets context.\n     */\n    public readonly index: FlowGraphDataConnection<FlowGraphNumber>;\n\n    public constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config: IFlowGraphGetAssetBlockConfiguration<T>\n    ) {\n        super(config);\n        this.type = this.registerDataInput(\"type\", RichTypeAny, config.type);\n        this.value = this.registerDataOutput(\"value\", RichTypeAny);\n        this.index = this.registerDataInput(\"index\", RichTypeAny, new FlowGraphInteger(getNumericValue(config.index ?? -1)));\n    }\n\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const type = this.type.getValue(context);\n        const index = this.index.getValue(context);\n        // get the asset from the context\n        const asset = GetFlowGraphAssetWithType(context.assetsContext, type, getNumericValue(index), this.config.useIndexAsUniqueId);\n        this.value.setValue(asset, context);\n    }\n\n    /**\n     * Gets the class name of this block\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.GetAsset;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphGetAssetBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphGetAssetBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.GetAsset, FlowGraphGetAssetBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type FlowGraphNumber, getNumericValue, isNumeric } from \"core/FlowGraph/utils\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\nexport interface IFlowGraphDataSwitchBlockConfiguration<T> extends IFlowGraphBlockConfiguration {\n    /**\n     * The possible values for the selection.\n     *\n     */\n    cases: FlowGraphNumber[];\n\n    /**\n     * If true, the cases will be treated as integers, meaning 1.1, 1.0, 0.1e1  and 1 will a single case - \"1\".\n     * This is the default behavior in glTF interactivity.\n     */\n    treatCasesAsIntegers?: boolean;\n}\n/**\n * This block conditionally outputs one of its inputs, based on a condition and a list of cases.\n *\n * This of it as a passive (data) version of the switch statement in programming languages.\n */\nexport class FlowGraphDataSwitchBlock<T> extends FlowGraphBlock {\n    /**\n     * Current selection value.\n     */\n    public readonly case: FlowGraphDataConnection<FlowGraphNumber>;\n\n    /**\n     * Input: default value to output if no case is matched.\n     */\n    public readonly default: FlowGraphDataConnection<T>;\n\n    /**\n     * Output: the value that is output based on the selection.\n     */\n    public readonly value: FlowGraphDataConnection<T | undefined>;\n\n    private _inputCases: Map<number, FlowGraphDataConnection<T>> = new Map();\n\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config: IFlowGraphDataSwitchBlockConfiguration<T>\n    ) {\n        super(config);\n\n        this.case = this.registerDataInput(\"case\", RichTypeAny, NaN);\n        this.default = this.registerDataInput(\"default\", RichTypeAny);\n        this.value = this.registerDataOutput(\"value\", RichTypeAny);\n\n        // iterate the set not using for of\n        const array = this.config.cases || [];\n        for (let caseValue of array) {\n            // if treat as integers, make sure not to set it again if it exists\n            caseValue = getNumericValue(caseValue);\n            if (this.config.treatCasesAsIntegers) {\n                caseValue = caseValue | 0;\n                if (this._inputCases.has(caseValue)) {\n                    return;\n                }\n            }\n            this._inputCases.set(caseValue, this.registerDataInput(`in_${caseValue}`, RichTypeAny));\n        }\n    }\n\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const selectionValue = this.case.getValue(context);\n        let outputValue: T | undefined;\n        if (isNumeric(selectionValue)) {\n            outputValue = this._getOutputValueForCase(getNumericValue(selectionValue), context);\n        }\n        if (!outputValue) {\n            outputValue = this.default.getValue(context);\n        }\n\n        this.value.setValue(outputValue, context);\n    }\n\n    private _getOutputValueForCase(caseValue: number, context: FlowGraphContext): T | undefined {\n        return this._inputCases.get(caseValue)?.getValue(context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.DataSwitch;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphDataSwitchBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphDataSwitchBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.DataSwitch, FlowGraphDataSwitchBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeBoolean, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\n\n/**\n * A data block that outputs whether a specific keyboard key is currently pressed,\n * optionally requiring one or more modifier keys to also be held.\n *\n * This block queries the scene event coordinator's `pressedKeys` set,\n * which is updated in real-time by the keyboard observers. It is designed\n * to be polled every frame (e.g. from a Scene Tick event chain) but can\n * also be read on demand from any execution context.\n *\n * The `key` input uses `KeyboardEvent.code` values (e.g. \"KeyA\", \"Space\",\n * \"ShiftLeft\", \"ControlLeft\", \"AltLeft\", \"MetaLeft\" for Mac Cmd).\n *\n * Modifier inputs (`withShift`, `withCtrl`, `withAlt`, `withMeta`,\n * `withCommandOrCtrl`) default to false. Set any to true to require that\n * modifier to also be held for `isPressed` to be true.\n * For example, key = \"KeyA\" + withCommandOrCtrl = true checks for\n * Cmd+A on macOS or Ctrl+A on Windows/Linux.\n */\nexport class FlowGraphIsKeyPressedBlock extends FlowGraphBlock {\n    /**\n     * Input connection: the `KeyboardEvent.code` of the key to check\n     * (e.g. \"KeyA\", \"Space\", \"ShiftLeft\").\n     */\n    public readonly key: FlowGraphDataConnection<string>;\n\n    /**\n     * Input connection: when true, Shift must also be held.\n     */\n    public readonly withShift: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Input connection: when true, Ctrl must also be held.\n     */\n    public readonly withCtrl: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Input connection: when true, Alt (Option on macOS) must also be held.\n     */\n    public readonly withAlt: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Input connection: when true, Meta (Win key / Cmd) must also be held.\n     */\n    public readonly withMeta: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Input connection: when true, the platform-appropriate \"command\" modifier\n     * must also be held (Cmd on macOS, Ctrl on Windows/Linux).\n     * This uses the virtual \"CommandOrControl\" key tracked by the coordinator.\n     */\n    public readonly withCommandOrCtrl: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Output connection: true if the key (and all required modifiers) are currently held down.\n     */\n    public readonly isPressed: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Creates a new FlowGraphIsKeyPressedBlock.\n     * @param config optional configuration\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.key = this.registerDataInput(\"key\", RichTypeString);\n        this.withShift = this.registerDataInput(\"withShift\", RichTypeBoolean);\n        this.withCtrl = this.registerDataInput(\"withCtrl\", RichTypeBoolean);\n        this.withAlt = this.registerDataInput(\"withAlt\", RichTypeBoolean);\n        this.withMeta = this.registerDataInput(\"withMeta\", RichTypeBoolean);\n        this.withCommandOrCtrl = this.registerDataInput(\"withCommandOrCtrl\", RichTypeBoolean);\n        this.isPressed = this.registerDataOutput(\"isPressed\", RichTypeBoolean);\n    }\n\n    /** @internal */\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const coordinator = context.configuration.sceneEventCoordinator;\n        if (!coordinator) {\n            this.isPressed.setValue(false, context);\n            return;\n        }\n        const keys = coordinator.pressedKeys;\n        const keyCode = this.key.getValue(context);\n\n        // Primary key must be held (unless empty, in which case only modifiers are checked)\n        let pressed = keyCode ? keys.has(keyCode) : true;\n\n        // Check required modifiers\n        if (pressed && this.withShift.getValue(context)) {\n            pressed = keys.has(\"ShiftLeft\") || keys.has(\"ShiftRight\");\n        }\n        if (pressed && this.withCtrl.getValue(context)) {\n            pressed = keys.has(\"ControlLeft\") || keys.has(\"ControlRight\");\n        }\n        if (pressed && this.withAlt.getValue(context)) {\n            pressed = keys.has(\"AltLeft\") || keys.has(\"AltRight\");\n        }\n        if (pressed && this.withMeta.getValue(context)) {\n            pressed = keys.has(\"MetaLeft\") || keys.has(\"MetaRight\");\n        }\n        if (pressed && this.withCommandOrCtrl.getValue(context)) {\n            pressed = keys.has(\"CommandOrControl\");\n        }\n\n        this.isPressed.setValue(pressed, context);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.IsKeyPressed;\n    }\n}\n\nlet _Registered = false;\n/**\n * Registers the FlowGraphIsKeyPressedBlock class.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphIsKeyPressedBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.IsKeyPressed, FlowGraphIsKeyPressedBlock);\n}\n","import { type FlowGraphDataConnection } from \"../../flowGraphDataConnection\";\r\nimport { type RichType } from \"../../flowGraphRichTypes\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { FlowGraphCachedOperationBlock } from \"./flowGraphCachedOperationBlock\";\r\n/**\r\n * The base block for all binary operation blocks. Receives an input of type\r\n * LeftT, one of type RightT, and outputs a value of type ResultT.\r\n */\r\nexport class FlowGraphBinaryOperationBlock<LeftT, RightT, ResultT> extends FlowGraphCachedOperationBlock<ResultT> {\r\n    /**\r\n     * First input of this block\r\n     */\r\n    a: FlowGraphDataConnection<LeftT>;\r\n    /**\r\n     * Second input of this block\r\n     */\r\n    b: FlowGraphDataConnection<RightT>;\r\n\r\n    constructor(\r\n        leftRichType: RichType<LeftT>,\r\n        rightRichType: RichType<RightT>,\r\n        resultRichType: RichType<ResultT>,\r\n        private _operation: (left: LeftT, right: RightT) => ResultT,\r\n        private _className: string,\r\n        config?: IFlowGraphBlockConfiguration\r\n    ) {\r\n        super(resultRichType, config);\r\n        this.a = this.registerDataInput(\"a\", leftRichType);\r\n        this.b = this.registerDataInput(\"b\", rightRichType);\r\n    }\r\n\r\n    /**\r\n     * the operation performed by this block\r\n     * @param context the graph context\r\n     * @returns the result of the operation\r\n     */\r\n    public override _doOperation(context: FlowGraphContext): ResultT {\r\n        const a = this.a.getValue(context);\r\n        const b = this.b.getValue(context);\r\n        return this._operation(a, b);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return this._className;\r\n    }\r\n}\r\n","import { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type RichType } from \"../../flowGraphRichTypes\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { FlowGraphCachedOperationBlock } from \"./flowGraphCachedOperationBlock\";\r\n/**\r\n * Block that outputs a value of type ResultT, resulting of an operation with no inputs.\r\n * This block is being extended by some math operations and should not be used directly.\r\n * @internal\r\n */\r\nexport class FlowGraphConstantOperationBlock<ResultT> extends FlowGraphCachedOperationBlock<ResultT> {\r\n    constructor(\r\n        richType: RichType<ResultT>,\r\n        private _operation: (context: FlowGraphContext) => ResultT,\r\n        private _className: string,\r\n        config?: IFlowGraphBlockConfiguration\r\n    ) {\r\n        super(richType, config);\r\n    }\r\n\r\n    /**\r\n     * the operation performed by this block\r\n     * @param context the graph context\r\n     * @returns the result of the operation\r\n     */\r\n    public override _doOperation(context: FlowGraphContext): ResultT {\r\n        return this._operation(context);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return this._className;\r\n    }\r\n}\r\n","import { type FlowGraphDataConnection } from \"../../flowGraphDataConnection\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { type RichType } from \"../../flowGraphRichTypes\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { FlowGraphCachedOperationBlock } from \"./flowGraphCachedOperationBlock\";\r\n\r\n/**\r\n * @internal\r\n * The base block for all unary operation blocks. Receives an input of type InputT, and outputs a value of type ResultT.\r\n */\r\nexport class FlowGraphUnaryOperationBlock<InputT, ResultT> extends FlowGraphCachedOperationBlock<ResultT> {\r\n    /**\r\n     * the input of this block\r\n     */\r\n    a: FlowGraphDataConnection<InputT>;\r\n\r\n    constructor(\r\n        inputRichType: RichType<InputT>,\r\n        resultRichType: RichType<ResultT>,\r\n        private _operation: (input: InputT) => ResultT,\r\n        private _className: string,\r\n        config?: IFlowGraphBlockConfiguration\r\n    ) {\r\n        super(resultRichType, config);\r\n        this.a = this.registerDataInput(\"a\", inputRichType);\r\n    }\r\n\r\n    /**\r\n     * the operation performed by this block\r\n     * @param context the graph context\r\n     * @returns the result of the operation\r\n     */\r\n    public override _doOperation(context: FlowGraphContext): ResultT {\r\n        return this._operation(this.a.getValue(context));\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return this._className;\r\n    }\r\n}\r\n","import { type FlowGraphDataConnection } from \"../../flowGraphDataConnection\";\r\nimport { type RichType } from \"../../flowGraphRichTypes\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { FlowGraphCachedOperationBlock } from \"./flowGraphCachedOperationBlock\";\r\n/**\r\n * @internal\r\n * The base block for all ternary operation blocks.\r\n */\r\nexport class FlowGraphTernaryOperationBlock<T1, T2, T3, ResultT> extends FlowGraphCachedOperationBlock<ResultT> {\r\n    /**\r\n     * First input of this block\r\n     */\r\n    a: FlowGraphDataConnection<T1>;\r\n    /**\r\n     * Second input of this block\r\n     */\r\n    b: FlowGraphDataConnection<T2>;\r\n    /**\r\n     * Third input of this block\r\n     */\r\n    c: FlowGraphDataConnection<T3>;\r\n\r\n    constructor(\r\n        t1Type: RichType<T1>,\r\n        t2Type: RichType<T2>,\r\n        t3Type: RichType<T3>,\r\n        resultRichType: RichType<ResultT>,\r\n        private _operation: (a: T1, b: T2, c: T3) => ResultT,\r\n        private _className: string,\r\n        config?: IFlowGraphBlockConfiguration\r\n    ) {\r\n        super(resultRichType, config);\r\n        this.a = this.registerDataInput(\"a\", t1Type);\r\n        this.b = this.registerDataInput(\"b\", t2Type);\r\n        this.c = this.registerDataInput(\"c\", t3Type);\r\n    }\r\n\r\n    /**\r\n     * the operation performed by this block\r\n     * @param context the graph context\r\n     * @returns the result of the operation\r\n     */\r\n    public override _doOperation(context: FlowGraphContext): ResultT {\r\n        return this._operation(this.a.getValue(context), this.b.getValue(context), this.c.getValue(context));\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this block\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return this._className;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { FlowGraphTypes, getRichTypeByFlowGraphType, RichTypeAny, RichTypeBoolean, RichTypeFlowGraphInteger, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { FlowGraphBinaryOperationBlock } from \"../flowGraphBinaryOperationBlock\";\r\nimport { FlowGraphConstantOperationBlock } from \"../flowGraphConstantOperationBlock\";\r\nimport { Quaternion, Matrix, Vector2, Vector3, Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { FlowGraphUnaryOperationBlock } from \"../flowGraphUnaryOperationBlock\";\r\nimport { FlowGraphTernaryOperationBlock } from \"../flowGraphTernaryOperationBlock\";\r\nimport { FlowGraphInteger } from \"../../../CustomTypes/flowGraphInteger.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\r\nimport { FlowGraphMatrix2D, FlowGraphMatrix3D } from \"core/FlowGraph/CustomTypes/flowGraphMatrix\";\r\nimport {\r\n    type FlowGraphMathOperationType,\r\n    type FlowGraphNumber,\r\n    _AreSameIntegerClass,\r\n    _AreSameMatrixClass,\r\n    _AreSameVectorOrQuaternionClass,\r\n    _GetClassNameOf,\r\n    getNumericValue,\r\n    isNumeric,\r\n} from \"core/FlowGraph/utils\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * A configuration interface for math blocks\r\n */\r\nexport interface IFlowGraphMathBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * If true, the multiplication is done per component.\r\n     * This is the behavior in glTF interactivity.\r\n     */\r\n    useMatrixPerComponent?: boolean;\r\n\r\n    /**\r\n     * The type of the variable.\r\n     */\r\n    type?: FlowGraphTypes;\r\n\r\n    /**\r\n     * If true, the block will not allow integer and float arithmetic.\r\n     * This is the behavior in glTF interactivity.\r\n     */\r\n    preventIntegerFloatArithmetic?: boolean;\r\n}\r\n\r\n/**\r\n * Polymorphic add block.\r\n */\r\nexport class FlowGraphAddBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    /**\r\n     * Construct a new add block.\r\n     * @param config optional configuration\r\n     */\r\n    constructor(config?: IFlowGraphMathBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            (a, b) => this._polymorphicAdd(a, b),\r\n            FlowGraphBlockNames.Add,\r\n            config\r\n        );\r\n    }\r\n\r\n    private _polymorphicAdd(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        const aClassName = _GetClassNameOf(a);\r\n        const bClassName = _GetClassNameOf(b);\r\n        if (_AreSameVectorOrQuaternionClass(aClassName, bClassName) || _AreSameMatrixClass(aClassName, bClassName) || _AreSameIntegerClass(aClassName, bClassName)) {\r\n            // cast to vector3, but any other cast will be fine\r\n            return (a as Vector3).add(b as Vector3);\r\n        } else if (aClassName === FlowGraphTypes.Quaternion || bClassName === FlowGraphTypes.Vector4) {\r\n            return new Vector4((a as Quaternion).x, (a as Quaternion).y, (a as Quaternion).z, (a as Quaternion).w).addInPlace(b as Vector4);\r\n        } else if (aClassName === FlowGraphTypes.Vector4 || bClassName === FlowGraphTypes.Quaternion) {\r\n            return (a as Vector4).add(b as Quaternion);\r\n        } else {\r\n            // at this point at least one of the variables is a number.\r\n            if (this.config?.preventIntegerFloatArithmetic && typeof a !== typeof b) {\r\n                throw new Error(\"Cannot add different types of numbers.\");\r\n            }\r\n            return getNumericValue(a as number) + getNumericValue(b as number);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Polymorphic subtract block.\r\n */\r\nexport class FlowGraphSubtractBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    /**\r\n     * Construct a new subtract block.\r\n     * @param config optional configuration\r\n     */\r\n    constructor(config?: IFlowGraphMathBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            (a, b) => this._polymorphicSubtract(a, b),\r\n            FlowGraphBlockNames.Subtract,\r\n            config\r\n        );\r\n    }\r\n\r\n    private _polymorphicSubtract(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        const aClassName = _GetClassNameOf(a);\r\n        const bClassName = _GetClassNameOf(b);\r\n        if (_AreSameVectorOrQuaternionClass(aClassName, bClassName) || _AreSameIntegerClass(aClassName, bClassName) || _AreSameMatrixClass(aClassName, bClassName)) {\r\n            // cast to vector3, but it can be casted to any vector type\r\n            return (a as Vector3).subtract(b as Vector3);\r\n        } else if (aClassName === FlowGraphTypes.Quaternion || bClassName === FlowGraphTypes.Vector4) {\r\n            return new Vector4((a as Quaternion).x, (a as Quaternion).y, (a as Quaternion).z, (a as Quaternion).w).subtractInPlace(b as Vector4);\r\n        } else if (aClassName === FlowGraphTypes.Vector4 || bClassName === FlowGraphTypes.Quaternion) {\r\n            return (a as Vector4).subtract(b as Quaternion);\r\n        } else {\r\n            // at this point at least one of the variables is a number.\r\n            if (this.config?.preventIntegerFloatArithmetic && typeof a !== typeof b) {\r\n                throw new Error(\"Cannot add different types of numbers.\");\r\n            }\r\n            return getNumericValue(a as number) - getNumericValue(b as number);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Polymorphic multiply block.\r\n * In case of matrix, it is configurable whether the multiplication is done per component.\r\n */\r\nexport class FlowGraphMultiplyBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphMathBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            (a, b) => this._polymorphicMultiply(a, b),\r\n            FlowGraphBlockNames.Multiply,\r\n            config\r\n        );\r\n    }\r\n\r\n    private _polymorphicMultiply(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        const aClassName = _GetClassNameOf(a);\r\n        const bClassName = _GetClassNameOf(b);\r\n        if (_AreSameVectorOrQuaternionClass(aClassName, bClassName) || _AreSameIntegerClass(aClassName, bClassName)) {\r\n            // cast to vector3, but it can be casted to any vector type\r\n            return (a as Vector3).multiply(b as Vector3);\r\n        } else if (aClassName === FlowGraphTypes.Quaternion || bClassName === FlowGraphTypes.Vector4) {\r\n            return new Vector4((a as Quaternion).x, (a as Quaternion).y, (a as Quaternion).z, (a as Quaternion).w).multiplyInPlace(b as Vector4);\r\n        } else if (aClassName === FlowGraphTypes.Vector4 || bClassName === FlowGraphTypes.Quaternion) {\r\n            return (a as Vector4).multiply(b as Quaternion);\r\n        } else if (_AreSameMatrixClass(aClassName, bClassName)) {\r\n            if (this.config?.useMatrixPerComponent) {\r\n                // this is the definition of multiplication of glTF interactivity\r\n                // get a's m as array, and multiply each component with b's m\r\n                const aM = (a as FlowGraphMatrix2D).m;\r\n                for (let i = 0; i < aM.length; i++) {\r\n                    aM[i] *= (b as FlowGraphMatrix2D).m[i];\r\n                }\r\n                if (aClassName === FlowGraphTypes.Matrix2D) {\r\n                    return new FlowGraphMatrix2D(aM);\r\n                } else if (aClassName === FlowGraphTypes.Matrix3D) {\r\n                    return new FlowGraphMatrix3D(aM);\r\n                } else {\r\n                    return Matrix.FromArray(aM);\r\n                }\r\n            } else {\r\n                a = a as Matrix;\r\n                b = b as Matrix;\r\n                return b.multiply(a);\r\n            }\r\n        } else {\r\n            // at this point at least one of the variables is a number.\r\n            if (this.config?.preventIntegerFloatArithmetic && typeof a !== typeof b) {\r\n                throw new Error(\"Cannot add different types of numbers.\");\r\n            }\r\n            return getNumericValue(a as number) * getNumericValue(b as number);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Polymorphic division block.\r\n */\r\nexport class FlowGraphDivideBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    /**\r\n     * Construct a new divide block.\r\n     * @param config - Optional configuration\r\n     */\r\n    constructor(config?: IFlowGraphMathBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            getRichTypeByFlowGraphType(config?.type),\r\n            (a, b) => this._polymorphicDivide(a, b),\r\n            FlowGraphBlockNames.Divide,\r\n            config\r\n        );\r\n    }\r\n\r\n    private _polymorphicDivide(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        const aClassName = _GetClassNameOf(a);\r\n        const bClassName = _GetClassNameOf(b);\r\n        if (_AreSameVectorOrQuaternionClass(aClassName, bClassName) || _AreSameIntegerClass(aClassName, bClassName)) {\r\n            // cast to vector3, but it can be casted to any vector type\r\n            return (a as Vector3).divide(b as Vector3);\r\n        } else if (aClassName === FlowGraphTypes.Quaternion || bClassName === FlowGraphTypes.Quaternion) {\r\n            // this is a simple division (per component!), and should be also supported between Quat and Vector4. Therefore -\r\n            const aClone = (a as Quaternion).clone();\r\n            aClone.x /= (b as Quaternion).x;\r\n            aClone.y /= (b as Quaternion).y;\r\n            aClone.z /= (b as Quaternion).z;\r\n            aClone.w /= (b as Quaternion).w;\r\n            return aClone;\r\n        } else if (aClassName === FlowGraphTypes.Quaternion || bClassName === FlowGraphTypes.Vector4) {\r\n            return new Vector4((a as Quaternion).x, (a as Quaternion).y, (a as Quaternion).z, (a as Quaternion).w).divideInPlace(b as Vector4);\r\n        } else if (aClassName === FlowGraphTypes.Vector4 || bClassName === FlowGraphTypes.Quaternion) {\r\n            return (a as Vector4).divide(b as Quaternion);\r\n        } else if (_AreSameMatrixClass(aClassName, bClassName)) {\r\n            if (this.config?.useMatrixPerComponent) {\r\n                // get a's m as array, and divide each component with b's m\r\n                const aM = (a as FlowGraphMatrix2D).m;\r\n                for (let i = 0; i < aM.length; i++) {\r\n                    aM[i] /= (b as FlowGraphMatrix2D).m[i];\r\n                }\r\n                if (aClassName === FlowGraphTypes.Matrix2D) {\r\n                    return new FlowGraphMatrix2D(aM);\r\n                } else if (aClassName === FlowGraphTypes.Matrix3D) {\r\n                    return new FlowGraphMatrix3D(aM);\r\n                } else {\r\n                    return Matrix.FromArray(aM);\r\n                }\r\n            } else {\r\n                a = a as Matrix;\r\n                b = b as Matrix;\r\n                return a.divide(b);\r\n            }\r\n        } else {\r\n            // at this point at least one of the variables is a number.\r\n            if (this.config?.preventIntegerFloatArithmetic && typeof a !== typeof b) {\r\n                throw new Error(\"Cannot add different types of numbers.\");\r\n            }\r\n            return getNumericValue(a as number) / getNumericValue(b as number);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Configuration interface for the random block.\r\n */\r\nexport interface IFlowGraphRandomBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The minimum value. defaults to 0.\r\n     */\r\n    min?: number;\r\n    /**\r\n     * The maximum value. defaults to 1.\r\n     */\r\n    max?: number;\r\n\r\n    /**\r\n     * The seed for the random number generator for deterministic random values.\r\n     * If not set, Math.random() is used.\r\n     */\r\n    seed?: number;\r\n}\r\n\r\n/**\r\n * Random number between min and max (defaults to 0 to 1)\r\n *\r\n * This node will cache the result for he same node reference. i.e., a Math.eq that references the SAME random node will always return true.\r\n */\r\nexport class FlowGraphRandomBlock extends FlowGraphConstantOperationBlock<FlowGraphMathOperationType> {\r\n    /**\r\n     * The minimum value. defaults to 0.\r\n     */\r\n    public readonly min: FlowGraphDataConnection<number>;\r\n    /**\r\n     * The maximum value. defaults to 1.\r\n     */\r\n    public readonly max: FlowGraphDataConnection<number>;\r\n\r\n    private _seed?: number;\r\n\r\n    /**\r\n     * Construct a new random block.\r\n     * @param config optional configuration\r\n     */\r\n    constructor(config?: IFlowGraphRandomBlockConfiguration) {\r\n        super(RichTypeNumber, (context) => this._random(context), FlowGraphBlockNames.Random, config);\r\n        this.min = this.registerDataInput(\"min\", RichTypeNumber, config?.min ?? 0);\r\n        this.max = this.registerDataInput(\"max\", RichTypeNumber, config?.max ?? 1);\r\n        if (config?.seed) {\r\n            this._seed = config.seed;\r\n        }\r\n    }\r\n\r\n    private _isSeed(seed = this._seed): seed is number {\r\n        return seed !== undefined;\r\n    }\r\n\r\n    private _getRandomValue() {\r\n        if (this._isSeed(this._seed)) {\r\n            // compute seed-based random number, deterministic randomness!\r\n            const x = Math.sin(this._seed++) * 10000;\r\n            return x - Math.floor(x);\r\n        }\r\n        return Math.random();\r\n    }\r\n\r\n    private _random(context: FlowGraphContext) {\r\n        const min = this.min.getValue(context);\r\n        const max = this.max.getValue(context);\r\n        return this._getRandomValue() * (max - min) + min;\r\n    }\r\n}\r\n\r\n/**\r\n * E constant.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class FlowGraphEBlock extends FlowGraphConstantOperationBlock<number> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, () => Math.E, FlowGraphBlockNames.E, config);\r\n    }\r\n}\r\n\r\n/**\r\n * Pi constant.\r\n */\r\nexport class FlowGraphPiBlock extends FlowGraphConstantOperationBlock<number> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, () => Math.PI, FlowGraphBlockNames.PI, config);\r\n    }\r\n}\r\n\r\n/**\r\n * Tau constant (2 * Pi), the ratio of a circle's circumference to its radius.\r\n */\r\nexport class FlowGraphTauBlock extends FlowGraphConstantOperationBlock<number> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, () => 2 * Math.PI, FlowGraphBlockNames.Tau, config);\r\n    }\r\n}\r\n\r\n/**\r\n * Positive inf constant.\r\n */\r\nexport class FlowGraphInfBlock extends FlowGraphConstantOperationBlock<number> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, () => Number.POSITIVE_INFINITY, FlowGraphBlockNames.Inf, config);\r\n    }\r\n}\r\n\r\n/**\r\n * NaN constant.\r\n */\r\nexport class FlowGraphNaNBlock extends FlowGraphConstantOperationBlock<number> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, () => Number.NaN, FlowGraphBlockNames.NaN, config);\r\n    }\r\n}\r\n\r\nfunction ComponentWiseUnaryOperation(a: FlowGraphMathOperationType, op: (a: number) => number) {\r\n    const aClassName = _GetClassNameOf(a);\r\n    switch (aClassName) {\r\n        case \"FlowGraphInteger\":\r\n            a = a as FlowGraphInteger;\r\n            return new FlowGraphInteger(op(a.value));\r\n        case FlowGraphTypes.Vector2:\r\n            a = a as Vector2;\r\n            return new Vector2(op(a.x), op(a.y));\r\n        case FlowGraphTypes.Vector3:\r\n            a = a as Vector3;\r\n            return new Vector3(op(a.x), op(a.y), op(a.z));\r\n        case FlowGraphTypes.Vector4:\r\n            a = a as Vector4;\r\n            return new Vector4(op(a.x), op(a.y), op(a.z), op(a.w));\r\n        case FlowGraphTypes.Quaternion:\r\n            a = a as Quaternion;\r\n            return new Quaternion(op(a.x), op(a.y), op(a.z), op(a.w));\r\n        case FlowGraphTypes.Matrix:\r\n            a = a as Matrix;\r\n            return Matrix.FromArray(a.m.map(op));\r\n        case FlowGraphTypes.Matrix2D:\r\n            a = a as FlowGraphMatrix2D;\r\n            // reason for not using .map is performance\r\n            return new FlowGraphMatrix2D(a.m.map(op));\r\n        case FlowGraphTypes.Matrix3D:\r\n            a = a as FlowGraphMatrix3D;\r\n            return new FlowGraphMatrix3D(a.m.map(op));\r\n        default:\r\n            a = a as number;\r\n            return op(a);\r\n    }\r\n}\r\n\r\n/**\r\n * Absolute value block.\r\n */\r\nexport class FlowGraphAbsBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicAbs(a), FlowGraphBlockNames.Abs, config);\r\n    }\r\n\r\n    private _polymorphicAbs(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.abs);\r\n    }\r\n}\r\n\r\n/**\r\n * Sign block.\r\n */\r\nexport class FlowGraphSignBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicSign(a), FlowGraphBlockNames.Sign, config);\r\n    }\r\n\r\n    private _polymorphicSign(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.sign);\r\n    }\r\n}\r\n\r\n/**\r\n * Truncation block.\r\n */\r\nexport class FlowGraphTruncBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicTrunc(a), FlowGraphBlockNames.Trunc, config);\r\n    }\r\n\r\n    private _polymorphicTrunc(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.trunc);\r\n    }\r\n}\r\n\r\n/**\r\n * Floor block.\r\n */\r\nexport class FlowGraphFloorBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicFloor(a), FlowGraphBlockNames.Floor, config);\r\n    }\r\n\r\n    private _polymorphicFloor(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.floor);\r\n    }\r\n}\r\n\r\n/**\r\n * Ceiling block.\r\n */\r\nexport class FlowGraphCeilBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicCeiling(a), FlowGraphBlockNames.Ceil, config);\r\n    }\r\n\r\n    private _polymorphicCeiling(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.ceil);\r\n    }\r\n}\r\n\r\n/**\r\n * Configuration for the round block.\r\n */\r\nexport interface IFlowGraphRoundBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * If true, the rounding is away from zero, even when negative. i.e. -7.5 goes to -8, and not -7 as Math.round does (it rounds up).\r\n     * This is the default when using glTF\r\n     */\r\n    roundHalfAwayFromZero?: boolean;\r\n}\r\n/**\r\n * Round block.\r\n */\r\nexport class FlowGraphRoundBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphRoundBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicRound(a), FlowGraphBlockNames.Round, config);\r\n    }\r\n\r\n    private _polymorphicRound(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, (a) => (a < 0 && this.config?.roundHalfAwayFromZero ? -Math.round(-a) : Math.round(a)));\r\n    }\r\n}\r\n\r\n/**\r\n * A block that returns the fractional part of a number.\r\n */\r\nexport class FlowGraphFractionBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicFraction(a), FlowGraphBlockNames.Fraction, config);\r\n    }\r\n\r\n    private _polymorphicFraction(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, (a) => a - Math.floor(a));\r\n    }\r\n}\r\n\r\n/**\r\n * Negation block.\r\n */\r\nexport class FlowGraphNegationBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    /**\r\n     * construct a new negation block.\r\n     * @param config optional configuration\r\n     */\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicNeg(a), FlowGraphBlockNames.Negation, config);\r\n    }\r\n\r\n    private _polymorphicNeg(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, (a) => -a);\r\n    }\r\n}\r\n\r\nfunction ComponentWiseBinaryOperation(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType, op: (a: number, b: number) => number) {\r\n    const aClassName = _GetClassNameOf(a);\r\n    switch (aClassName) {\r\n        case \"FlowGraphInteger\":\r\n            a = a as FlowGraphInteger;\r\n            b = b as FlowGraphInteger;\r\n            return new FlowGraphInteger(op(a.value, b.value));\r\n        case FlowGraphTypes.Vector2:\r\n            a = a as Vector2;\r\n            b = b as Vector2;\r\n            return new Vector2(op(a.x, b.x), op(a.y, b.y));\r\n        case FlowGraphTypes.Vector3:\r\n            a = a as Vector3;\r\n            b = b as Vector3;\r\n            return new Vector3(op(a.x, b.x), op(a.y, b.y), op(a.z, b.z));\r\n        case FlowGraphTypes.Vector4:\r\n            a = a as Vector4;\r\n            b = b as Vector4;\r\n            return new Vector4(op(a.x, b.x), op(a.y, b.y), op(a.z, b.z), op(a.w, b.w));\r\n        case FlowGraphTypes.Quaternion:\r\n            a = a as Quaternion;\r\n            b = b as Quaternion;\r\n            return new Quaternion(op(a.x, b.x), op(a.y, b.y), op(a.z, b.z), op(a.w, b.w));\r\n        case FlowGraphTypes.Matrix:\r\n            a = a as Matrix;\r\n            return Matrix.FromArray(a.m.map((v, i) => op(v, (b as Matrix).m[i])));\r\n        case FlowGraphTypes.Matrix2D:\r\n            a = a as FlowGraphMatrix2D;\r\n            return new FlowGraphMatrix2D(a.m.map((v, i) => op(v, (b as FlowGraphMatrix2D).m[i])));\r\n        case FlowGraphTypes.Matrix3D:\r\n            a = a as FlowGraphMatrix3D;\r\n            return new FlowGraphMatrix3D(a.m.map((v, i) => op(v, (b as FlowGraphMatrix3D).m[i])));\r\n        default:\r\n            return op(getNumericValue(a as number), getNumericValue(b as number));\r\n    }\r\n}\r\n\r\n/**\r\n * Remainder block.\r\n */\r\nexport class FlowGraphModuloBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, (a, b) => this._polymorphicRemainder(a, b), FlowGraphBlockNames.Modulo, config);\r\n    }\r\n\r\n    private _polymorphicRemainder(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        return ComponentWiseBinaryOperation(a, b, (a, b) => a % b);\r\n    }\r\n}\r\n\r\n/**\r\n * Min block.\r\n */\r\nexport class FlowGraphMinBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, (a, b) => this._polymorphicMin(a, b), FlowGraphBlockNames.Min, config);\r\n    }\r\n\r\n    private _polymorphicMin(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        return ComponentWiseBinaryOperation(a, b, Math.min);\r\n    }\r\n}\r\n\r\n/**\r\n * Max block\r\n */\r\nexport class FlowGraphMaxBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, (a, b) => this._polymorphicMax(a, b), FlowGraphBlockNames.Max, config);\r\n    }\r\n\r\n    private _polymorphicMax(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        return ComponentWiseBinaryOperation(a, b, Math.max);\r\n    }\r\n}\r\n\r\nfunction Clamp(a: number, b: number, c: number) {\r\n    return Math.min(Math.max(a, Math.min(b, c)), Math.max(b, c));\r\n}\r\n\r\nfunction ComponentWiseTernaryOperation(\r\n    a: FlowGraphMathOperationType,\r\n    b: FlowGraphMathOperationType,\r\n    c: FlowGraphMathOperationType,\r\n    op: (a: number, b: number, c: number) => number\r\n) {\r\n    const aClassName = _GetClassNameOf(a);\r\n    switch (aClassName) {\r\n        case \"FlowGraphInteger\":\r\n            a = a as FlowGraphInteger;\r\n            b = b as FlowGraphInteger;\r\n            c = c as FlowGraphInteger;\r\n            return new FlowGraphInteger(op(a.value, b.value, c.value));\r\n        case FlowGraphTypes.Vector2:\r\n            a = a as Vector2;\r\n            b = b as Vector2;\r\n            c = c as Vector2;\r\n            return new Vector2(op(a.x, b.x, c.x), op(a.y, b.y, c.y));\r\n        case FlowGraphTypes.Vector3:\r\n            a = a as Vector3;\r\n            b = b as Vector3;\r\n            c = c as Vector3;\r\n            return new Vector3(op(a.x, b.x, c.x), op(a.y, b.y, c.y), op(a.z, b.z, c.z));\r\n        case FlowGraphTypes.Vector4:\r\n            a = a as Vector4;\r\n            b = b as Vector4;\r\n            c = c as Vector4;\r\n            return new Vector4(op(a.x, b.x, c.x), op(a.y, b.y, c.y), op(a.z, b.z, c.z), op(a.w, b.w, c.w));\r\n        case FlowGraphTypes.Quaternion:\r\n            a = a as Quaternion;\r\n            b = b as Quaternion;\r\n            c = c as Quaternion;\r\n            return new Quaternion(op(a.x, b.x, c.x), op(a.y, b.y, c.y), op(a.z, b.z, c.z), op(a.w, b.w, c.w));\r\n        case FlowGraphTypes.Matrix:\r\n            return Matrix.FromArray((a as Matrix).m.map((v, i) => op(v, (b as Matrix).m[i], (c as Matrix).m[i])));\r\n        case FlowGraphTypes.Matrix2D:\r\n            return new FlowGraphMatrix2D((a as FlowGraphMatrix2D).m.map((v, i) => op(v, (b as FlowGraphMatrix2D).m[i], (c as FlowGraphMatrix2D).m[i])));\r\n        case FlowGraphTypes.Matrix3D:\r\n            return new FlowGraphMatrix3D((a as FlowGraphMatrix3D).m.map((v, i) => op(v, (b as FlowGraphMatrix3D).m[i], (c as FlowGraphMatrix3D).m[i])));\r\n        default:\r\n            return op(getNumericValue(a as number), getNumericValue(b as number), getNumericValue(c as number));\r\n    }\r\n}\r\n\r\n/**\r\n * Clamp block.\r\n */\r\nexport class FlowGraphClampBlock extends FlowGraphTernaryOperationBlock<\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType\r\n> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, RichTypeAny, (a, b, c) => this._polymorphicClamp(a, b, c), FlowGraphBlockNames.Clamp, config);\r\n    }\r\n\r\n    private _polymorphicClamp(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType, c: FlowGraphMathOperationType) {\r\n        return ComponentWiseTernaryOperation(a, b, c, Clamp);\r\n    }\r\n}\r\n\r\nfunction Saturate(a: number): number {\r\n    return Math.min(Math.max(a, 0), 1);\r\n}\r\n\r\n/**\r\n * Saturate block.\r\n */\r\nexport class FlowGraphSaturateBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicSaturate(a), FlowGraphBlockNames.Saturate, config);\r\n    }\r\n\r\n    private _polymorphicSaturate(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Saturate);\r\n    }\r\n}\r\n\r\nfunction Interpolate(a: number, b: number, c: number) {\r\n    return (1 - c) * a + c * b;\r\n}\r\n\r\n/**\r\n * Smooth step (Hermite interpolation) coefficient.\r\n * Given the edges `a`/`b` and the value `c`, computes the smooth interpolation\r\n * coefficient `t * t * (3 - 2 * t)` where `t = saturate((c - min(a, b)) / |b - a|)`.\r\n * Note that this returns the coefficient in [0, 1]; it does not interpolate between `a` and `b`.\r\n * @param a first edge\r\n * @param b second edge\r\n * @param c value to interpolate\r\n * @returns the smooth-step interpolation coefficient\r\n */\r\nfunction SmoothStep(a: number, b: number, c: number) {\r\n    // Degenerate edges: with a === b the transition is instantaneous, so return a step rather than\r\n    // dividing by zero (which would yield NaN and poison downstream math).\r\n    if (a === b) {\r\n        return c < a ? 0 : 1;\r\n    }\r\n    const t = Saturate((c - Math.min(a, b)) / Math.abs(b - a));\r\n    return t * t * (3 - 2 * t);\r\n}\r\n\r\n/**\r\n * Interpolate block.\r\n */\r\nexport class FlowGraphMathInterpolationBlock extends FlowGraphTernaryOperationBlock<\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType\r\n> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, RichTypeAny, (a, b, c) => this._polymorphicInterpolate(a, b, c), FlowGraphBlockNames.MathInterpolation, config);\r\n    }\r\n\r\n    private _polymorphicInterpolate(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType, c: FlowGraphMathOperationType) {\r\n        return ComponentWiseTernaryOperation(a, b, c, Interpolate);\r\n    }\r\n}\r\n\r\n/**\r\n * Spherical linear interpolation between two unit quaternions, matching the\r\n * quaternion slerp operation. The two inputs are treated as\r\n * Babylon `Quaternion` values regardless of their concrete class (the spec\r\n * defines them as `float4`), and the output is a `Quaternion`.\r\n *\r\n * The underlying implementation is `Quaternion.Slerp`, whose algorithm matches\r\n * the spec step-for-step (dot product, conditional sign-flip on `b`, sin-based\r\n * weighting, and a near-identity short-circuit to a linear blend).\r\n */\r\nexport class FlowGraphMathSlerpBlock extends FlowGraphTernaryOperationBlock<Quaternion, Quaternion, number, Quaternion> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeNumber, RichTypeAny, (a, b, c) => Quaternion.Slerp(a, b, c), FlowGraphBlockNames.MathSlerp, config);\r\n    }\r\n}\r\n\r\n/**\r\n * Smooth-step block, returning the Hermite interpolation coefficient.\r\n * Operates component-wise over floatN inputs (the two edges `a`/`b` and the\r\n * value `c`).\r\n */\r\nexport class FlowGraphMathSmoothStepBlock extends FlowGraphTernaryOperationBlock<\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType,\r\n    FlowGraphMathOperationType\r\n> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, RichTypeAny, (a, b, c) => this._polymorphicSmoothStep(a, b, c), FlowGraphBlockNames.SmoothStep, config);\r\n    }\r\n\r\n    private _polymorphicSmoothStep(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType, c: FlowGraphMathOperationType) {\r\n        return ComponentWiseTernaryOperation(a, b, c, SmoothStep);\r\n    }\r\n}\r\n\r\n/**\r\n * Equals block.\r\n */\r\nexport class FlowGraphEqualityBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeBoolean, (a, b) => this._polymorphicEq(a, b), FlowGraphBlockNames.Equality, config);\r\n    }\r\n\r\n    private _polymorphicEq(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        const aClassName = _GetClassNameOf(a);\r\n        const bClassName = _GetClassNameOf(b);\r\n        // A rotation may arrive either as a Quaternion or as a four-component vector, so treat Quaternion and\r\n        // Vector4 (both four-component) as comparable so that, for example, a decomposed rotation can be compared\r\n        // against a float4 literal.\r\n        const isFourComponent = (className?: string) => className === FlowGraphTypes.Vector4 || className === FlowGraphTypes.Quaternion;\r\n        if (isFourComponent(aClassName) && isFourComponent(bClassName)) {\r\n            return (a as Vector4).equals(b as Vector4);\r\n        }\r\n        if (_AreSameVectorOrQuaternionClass(aClassName, bClassName) || _AreSameMatrixClass(aClassName, bClassName) || _AreSameIntegerClass(aClassName, bClassName)) {\r\n            return (a as Vector3).equals(b as Vector3);\r\n        }\r\n        // Handle mixed number/FlowGraphInteger comparison\r\n        if (isNumeric(a) && isNumeric(b)) {\r\n            return getNumericValue(a as FlowGraphNumber) === getNumericValue(b as FlowGraphNumber);\r\n        }\r\n        if (typeof a !== typeof b) {\r\n            return false;\r\n        }\r\n        return a === b;\r\n    }\r\n}\r\n\r\nfunction ComparisonOperators(a: FlowGraphNumber, b: FlowGraphNumber, op: (a: number, b: number) => boolean) {\r\n    if (isNumeric(a) && isNumeric(b)) {\r\n        return op(getNumericValue(a), getNumericValue(b));\r\n    } else {\r\n        throw new Error(`Cannot compare ${a} and ${b}`);\r\n    }\r\n}\r\n\r\n/**\r\n * Less than block.\r\n */\r\nexport class FlowGraphLessThanBlock extends FlowGraphBinaryOperationBlock<FlowGraphNumber, FlowGraphNumber, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeBoolean, (a, b) => this._polymorphicLessThan(a, b), FlowGraphBlockNames.LessThan, config);\r\n    }\r\n\r\n    private _polymorphicLessThan(a: FlowGraphNumber, b: FlowGraphNumber) {\r\n        return ComparisonOperators(a, b, (a, b) => a < b);\r\n    }\r\n}\r\n\r\n/**\r\n * Less than or equal block.\r\n */\r\nexport class FlowGraphLessThanOrEqualBlock extends FlowGraphBinaryOperationBlock<FlowGraphNumber, FlowGraphNumber, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeBoolean, (a, b) => this._polymorphicLessThanOrEqual(a, b), FlowGraphBlockNames.LessThanOrEqual, config);\r\n    }\r\n\r\n    private _polymorphicLessThanOrEqual(a: FlowGraphNumber, b: FlowGraphNumber) {\r\n        return ComparisonOperators(a, b, (a, b) => a <= b);\r\n    }\r\n}\r\n\r\n/**\r\n * Greater than block.\r\n */\r\nexport class FlowGraphGreaterThanBlock extends FlowGraphBinaryOperationBlock<FlowGraphNumber, FlowGraphNumber, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeBoolean, (a, b) => this._polymorphicGreaterThan(a, b), FlowGraphBlockNames.GreaterThan, config);\r\n    }\r\n\r\n    private _polymorphicGreaterThan(a: FlowGraphNumber, b: FlowGraphNumber) {\r\n        return ComparisonOperators(a, b, (a, b) => a > b);\r\n    }\r\n}\r\n\r\n/**\r\n * Greater than or equal block.\r\n */\r\nexport class FlowGraphGreaterThanOrEqualBlock extends FlowGraphBinaryOperationBlock<FlowGraphNumber, FlowGraphNumber, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeBoolean, (a, b) => this._polymorphicGreaterThanOrEqual(a, b), FlowGraphBlockNames.GreaterThanOrEqual, config);\r\n    }\r\n\r\n    private _polymorphicGreaterThanOrEqual(a: FlowGraphNumber, b: FlowGraphNumber) {\r\n        return ComparisonOperators(a, b, (a, b) => a >= b);\r\n    }\r\n}\r\n\r\n/**\r\n * Is NaN block.\r\n */\r\nexport class FlowGraphIsNanBlock extends FlowGraphUnaryOperationBlock<FlowGraphNumber, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeBoolean, (a) => this._polymorphicIsNan(a), FlowGraphBlockNames.IsNaN, config);\r\n    }\r\n\r\n    private _polymorphicIsNan(a: FlowGraphNumber) {\r\n        if (isNumeric(a, true)) {\r\n            return isNaN(getNumericValue(a));\r\n        } else {\r\n            throw new Error(`Cannot get NaN of ${a}`);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Is Inf block.\r\n */\r\nexport class FlowGraphIsInfinityBlock extends FlowGraphUnaryOperationBlock<FlowGraphNumber, boolean> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeBoolean, (a) => this._polymorphicIsInf(a), FlowGraphBlockNames.IsInfinity, config);\r\n    }\r\n\r\n    private _polymorphicIsInf(a: FlowGraphNumber) {\r\n        if (isNumeric(a)) {\r\n            return !isFinite(getNumericValue(a));\r\n        } else {\r\n            throw new Error(`Cannot get isInf of ${a}`);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Convert degrees to radians block.\r\n */\r\nexport class FlowGraphDegToRadBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    /**\r\n     * Constructs a new instance of the flow graph math block.\r\n     * @param config - Optional configuration for the flow graph block.\r\n     */\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicDegToRad(a), FlowGraphBlockNames.DegToRad, config);\r\n    }\r\n\r\n    private _degToRad(a: number) {\r\n        return (a * Math.PI) / 180;\r\n    }\r\n\r\n    private _polymorphicDegToRad(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, this._degToRad);\r\n    }\r\n}\r\n\r\n/**\r\n * Convert radians to degrees block.\r\n */\r\nexport class FlowGraphRadToDegBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicRadToDeg(a), FlowGraphBlockNames.RadToDeg, config);\r\n    }\r\n\r\n    private _radToDeg(a: number) {\r\n        return (a * 180) / Math.PI;\r\n    }\r\n\r\n    private _polymorphicRadToDeg(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, this._radToDeg);\r\n    }\r\n}\r\n\r\n/**\r\n * Sin block.\r\n */\r\nexport class FlowGraphSinBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicSin(a), FlowGraphBlockNames.Sin, config);\r\n    }\r\n\r\n    private _polymorphicSin(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.sin);\r\n    }\r\n}\r\n\r\n/**\r\n * Cos block.\r\n */\r\nexport class FlowGraphCosBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicCos(a), FlowGraphBlockNames.Cos, config);\r\n    }\r\n\r\n    private _polymorphicCos(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.cos);\r\n    }\r\n}\r\n\r\n/**\r\n * Tan block.\r\n */\r\nexport class FlowGraphTanBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicTan(a), FlowGraphBlockNames.Tan, config);\r\n    }\r\n\r\n    private _polymorphicTan(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.tan);\r\n    }\r\n}\r\n\r\n/**\r\n * Arcsin block.\r\n */\r\nexport class FlowGraphAsinBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicAsin(a), FlowGraphBlockNames.Asin, config);\r\n    }\r\n\r\n    private _polymorphicAsin(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.asin);\r\n    }\r\n}\r\n\r\n/**\r\n * Arccos block.\r\n */\r\nexport class FlowGraphAcosBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicAcos(a), FlowGraphBlockNames.Acos, config);\r\n    }\r\n\r\n    private _polymorphicAcos(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.acos);\r\n    }\r\n}\r\n\r\n/**\r\n * Arctan block.\r\n */\r\nexport class FlowGraphAtanBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeNumber, RichTypeNumber, (a) => this._polymorphicAtan(a), FlowGraphBlockNames.Atan, config);\r\n    }\r\n\r\n    private _polymorphicAtan(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.atan);\r\n    }\r\n}\r\n\r\n/**\r\n * Arctan2 block.\r\n */\r\nexport class FlowGraphAtan2Block extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, RichTypeAny, (a, b) => this._polymorphicAtan2(a, b), FlowGraphBlockNames.Atan2, config);\r\n    }\r\n\r\n    private _polymorphicAtan2(a: any, b: any) {\r\n        return ComponentWiseBinaryOperation(a, b, Math.atan2);\r\n    }\r\n}\r\n\r\n/**\r\n * Hyperbolic sin block.\r\n */\r\nexport class FlowGraphSinhBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicSinh(a), FlowGraphBlockNames.Sinh, config);\r\n    }\r\n\r\n    private _polymorphicSinh(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.sinh);\r\n    }\r\n}\r\n\r\n/**\r\n * Hyperbolic cos block.\r\n */\r\nexport class FlowGraphCoshBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicCosh(a), FlowGraphBlockNames.Cosh, config);\r\n    }\r\n\r\n    private _polymorphicCosh(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.cosh);\r\n    }\r\n}\r\n\r\n/**\r\n * Hyperbolic tan block.\r\n */\r\nexport class FlowGraphTanhBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeAny, (a) => this._polymorphicTanh(a), FlowGraphBlockNames.Tanh, config);\r\n    }\r\n\r\n    private _polymorphicTanh(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.tanh);\r\n    }\r\n}\r\n\r\n/**\r\n * Hyperbolic arcsin block.\r\n */\r\nexport class FlowGraphAsinhBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicAsinh(a), FlowGraphBlockNames.Asinh, config);\r\n    }\r\n\r\n    private _polymorphicAsinh(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.asinh);\r\n    }\r\n}\r\n\r\n/**\r\n * Hyperbolic arccos block.\r\n */\r\nexport class FlowGraphAcoshBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicAcosh(a), FlowGraphBlockNames.Acosh, config);\r\n    }\r\n\r\n    private _polymorphicAcosh(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.acosh);\r\n    }\r\n}\r\n\r\n/**\r\n * Hyperbolic arctan block.\r\n */\r\nexport class FlowGraphAtanhBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicAtanh(a), FlowGraphBlockNames.Atanh, config);\r\n    }\r\n\r\n    private _polymorphicAtanh(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.atanh);\r\n    }\r\n}\r\n\r\n/**\r\n * Exponential block.\r\n */\r\nexport class FlowGraphExpBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicExp(a), FlowGraphBlockNames.Exponential, config);\r\n    }\r\n\r\n    private _polymorphicExp(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.exp);\r\n    }\r\n}\r\n\r\n/**\r\n * Logarithm block.\r\n */\r\nexport class FlowGraphLogBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicLog(a), FlowGraphBlockNames.Log, config);\r\n    }\r\n\r\n    private _polymorphicLog(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.log);\r\n    }\r\n}\r\n\r\n/**\r\n * Base 2 logarithm block.\r\n */\r\nexport class FlowGraphLog2Block extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicLog2(a), FlowGraphBlockNames.Log2, config);\r\n    }\r\n\r\n    private _polymorphicLog2(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.log2);\r\n    }\r\n}\r\n\r\n/**\r\n * Base 10 logarithm block.\r\n */\r\nexport class FlowGraphLog10Block extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicLog10(a), FlowGraphBlockNames.Log10, config);\r\n    }\r\n\r\n    private _polymorphicLog10(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.log10);\r\n    }\r\n}\r\n\r\n/**\r\n * Square root block.\r\n */\r\nexport class FlowGraphSquareRootBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicSqrt(a), FlowGraphBlockNames.SquareRoot, config);\r\n    }\r\n\r\n    private _polymorphicSqrt(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.sqrt);\r\n    }\r\n}\r\n\r\n/**\r\n * Cube root block.\r\n */\r\nexport class FlowGraphCubeRootBlock extends FlowGraphUnaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicCubeRoot(a), FlowGraphBlockNames.CubeRoot, config);\r\n    }\r\n\r\n    private _polymorphicCubeRoot(a: FlowGraphMathOperationType) {\r\n        return ComponentWiseUnaryOperation(a, Math.cbrt);\r\n    }\r\n}\r\n\r\n/**\r\n * Power block.\r\n */\r\nexport class FlowGraphPowerBlock extends FlowGraphBinaryOperationBlock<FlowGraphMathOperationType, FlowGraphMathOperationType, FlowGraphMathOperationType> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeAny, RichTypeNumber, RichTypeNumber, (a, b) => this._polymorphicPow(a, b), FlowGraphBlockNames.Power, config);\r\n    }\r\n\r\n    private _polymorphicPow(a: FlowGraphMathOperationType, b: FlowGraphMathOperationType) {\r\n        return ComponentWiseBinaryOperation(a, b, Math.pow);\r\n    }\r\n}\r\n\r\n/**\r\n * Configuration for bitwise operators\r\n */\r\nexport interface IFlowGraphBitwiseBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The type of the values that will be operated on\r\n     * Defaults to FlowGraphInteger, but can be a number or boolean as well.\r\n     */\r\n    valueType: FlowGraphTypes;\r\n}\r\n\r\ntype FlowGraphBitwiseTypes = FlowGraphInteger | FlowGraphNumber | boolean;\r\n/**\r\n * Bitwise NOT operation\r\n */\r\nexport class FlowGraphBitwiseNotBlock extends FlowGraphUnaryOperationBlock<FlowGraphBitwiseTypes, FlowGraphBitwiseTypes> {\r\n    constructor(config?: IFlowGraphBitwiseBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            (a) => {\r\n                if (typeof a === \"boolean\") {\r\n                    return !a;\r\n                } else if (typeof a === \"number\") {\r\n                    return ~a;\r\n                }\r\n                return new FlowGraphInteger(~a.value);\r\n            },\r\n            FlowGraphBlockNames.BitwiseNot,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Bitwise AND operation\r\n */\r\nexport class FlowGraphBitwiseAndBlock extends FlowGraphBinaryOperationBlock<FlowGraphBitwiseTypes, FlowGraphBitwiseTypes, FlowGraphBitwiseTypes> {\r\n    constructor(config?: IFlowGraphBitwiseBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            (a, b) => {\r\n                if (typeof a === \"boolean\" && typeof b === \"boolean\") {\r\n                    return a && b;\r\n                } else if (typeof a === \"number\" && typeof b === \"number\") {\r\n                    return a & b;\r\n                } else if (typeof a === \"object\" && typeof b === \"object\") {\r\n                    return new FlowGraphInteger(a.value & b.value);\r\n                } else {\r\n                    throw new Error(`Cannot perform bitwise AND on ${a} and ${b}`);\r\n                }\r\n            },\r\n            FlowGraphBlockNames.BitwiseAnd,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Bitwise OR operation\r\n */\r\nexport class FlowGraphBitwiseOrBlock extends FlowGraphBinaryOperationBlock<FlowGraphBitwiseTypes, FlowGraphBitwiseTypes, FlowGraphBitwiseTypes> {\r\n    constructor(config?: IFlowGraphBitwiseBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            (a, b) => {\r\n                if (typeof a === \"boolean\" && typeof b === \"boolean\") {\r\n                    return a || b;\r\n                } else if (typeof a === \"number\" && typeof b === \"number\") {\r\n                    return a | b;\r\n                } else if (typeof a === \"object\" && typeof b === \"object\") {\r\n                    return new FlowGraphInteger(a.value | b.value);\r\n                } else {\r\n                    throw new Error(`Cannot perform bitwise OR on ${a} and ${b}`);\r\n                }\r\n            },\r\n            FlowGraphBlockNames.BitwiseOr,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Bitwise XOR operation\r\n */\r\nexport class FlowGraphBitwiseXorBlock extends FlowGraphBinaryOperationBlock<FlowGraphBitwiseTypes, FlowGraphBitwiseTypes, FlowGraphBitwiseTypes> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            (a, b) => {\r\n                if (typeof a === \"boolean\" && typeof b === \"boolean\") {\r\n                    return a !== b;\r\n                } else if (typeof a === \"number\" && typeof b === \"number\") {\r\n                    return a ^ b;\r\n                } else if (typeof a === \"object\" && typeof b === \"object\") {\r\n                    return new FlowGraphInteger(a.value ^ b.value);\r\n                } else {\r\n                    throw new Error(`Cannot perform bitwise XOR on ${a} and ${b}`);\r\n                }\r\n            },\r\n            FlowGraphBlockNames.BitwiseXor,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Bitwise left shift operation\r\n */\r\nexport class FlowGraphBitwiseLeftShiftBlock extends FlowGraphBinaryOperationBlock<FlowGraphInteger, FlowGraphInteger, FlowGraphInteger> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            (a, b) => new FlowGraphInteger(a.value << b.value),\r\n            FlowGraphBlockNames.BitwiseLeftShift,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Bitwise right shift operation\r\n */\r\nexport class FlowGraphBitwiseRightShiftBlock extends FlowGraphBinaryOperationBlock<FlowGraphInteger, FlowGraphInteger, FlowGraphInteger> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            (a, b) => new FlowGraphInteger(a.value >> b.value),\r\n            FlowGraphBlockNames.BitwiseRightShift,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Count leading zeros operation\r\n */\r\nexport class FlowGraphLeadingZerosBlock extends FlowGraphUnaryOperationBlock<FlowGraphInteger, FlowGraphInteger> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeFlowGraphInteger, RichTypeFlowGraphInteger, (a) => new FlowGraphInteger(Math.clz32(a.value)), FlowGraphBlockNames.LeadingZeros, config);\r\n    }\r\n}\r\n\r\n/**\r\n * Count trailing zeros operation\r\n */\r\nexport class FlowGraphTrailingZerosBlock extends FlowGraphUnaryOperationBlock<FlowGraphInteger, FlowGraphInteger> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            (a) => new FlowGraphInteger(a.value ? 31 - Math.clz32(a.value & -a.value) : 32),\r\n            FlowGraphBlockNames.TrailingZeros,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Given a number (which is converted to a 32-bit integer), return the\r\n * number of bits set to one on that number.\r\n * @param n the number to run the op on\r\n * @returns the number of bits set to one on that number\r\n */\r\nfunction CountOnes(n: number) {\r\n    let result = 0;\r\n    while (n) {\r\n        // This zeroes out all bits except for the least significant one.\r\n        // So if the bit is set, it will be 1, otherwise it will be 0.\r\n        result += n & 1;\r\n        // Unsigned shifting is required so negative int32 values converge to zero.\r\n        n >>>= 1;\r\n    }\r\n    return result;\r\n}\r\n\r\n/**\r\n * Count one bits operation\r\n */\r\nexport class FlowGraphOneBitsCounterBlock extends FlowGraphUnaryOperationBlock<FlowGraphInteger, FlowGraphInteger> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(RichTypeFlowGraphInteger, RichTypeFlowGraphInteger, (a) => new FlowGraphInteger(CountOnes(a.value)), FlowGraphBlockNames.OneBitsCounter, config);\r\n    }\r\n}\r\n\r\n/**\r\n * Converts a linear sRGB color to OkLCh (the polar form of the Oklab color space).\r\n * Uses Ottosson's original single-precision matrices.\r\n * The RGB inputs are treated as linear; hue is returned in radians.\r\n * @param r linear red component\r\n * @param g linear green component\r\n * @param b linear blue component\r\n * @returns the OkLCh lightness (l), chroma (c) and hue (h, radians)\r\n */\r\nfunction RgbToOkLch(r: number, g: number, b: number): { l: number; c: number; h: number } {\r\n    // Linear sRGB -> LMS cone responses.\r\n    const long = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;\r\n    const medium = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;\r\n    const short = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;\r\n    // Non-linearity (cube root) then LMS' -> Oklab.\r\n    const lRoot = Math.cbrt(long);\r\n    const mRoot = Math.cbrt(medium);\r\n    const sRoot = Math.cbrt(short);\r\n    const okL = 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;\r\n    const okA = 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;\r\n    const okB = 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;\r\n    // Oklab -> OkLCh (polar form).\r\n    return { l: okL, c: Math.hypot(okA, okB), h: Math.atan2(okB, okA) };\r\n}\r\n\r\n/**\r\n * Converts an OkLCh color to linear sRGB. Inverse of {@link RgbToOkLch}; hue is in radians.\r\n * @param l OkLCh lightness\r\n * @param c OkLCh chroma\r\n * @param h OkLCh hue in radians\r\n * @returns the linear sRGB red (r), green (g) and blue (b) components\r\n */\r\nfunction OkLchToRgb(l: number, c: number, h: number): { r: number; g: number; b: number } {\r\n    // OkLCh -> Oklab.\r\n    const okA = c * Math.cos(h);\r\n    const okB = c * Math.sin(h);\r\n    // Oklab -> LMS' then cube to LMS.\r\n    const lPrime = l + 0.3963377774 * okA + 0.2158037573 * okB;\r\n    const mPrime = l - 0.1055613458 * okA - 0.0638541728 * okB;\r\n    const sPrime = l - 0.0894841775 * okA - 1.291485548 * okB;\r\n    const long = lPrime * lPrime * lPrime;\r\n    const medium = mPrime * mPrime * mPrime;\r\n    const short = sPrime * sPrime * sPrime;\r\n    // LMS -> linear sRGB.\r\n    return {\r\n        r: 4.0767416621 * long - 3.3077115913 * medium + 0.2309699292 * short,\r\n        g: -1.2684380046 * long + 2.6097574011 * medium - 0.3413193965 * short,\r\n        b: -0.0041960863 * long - 0.7034186147 * medium + 1.707614701 * short,\r\n    };\r\n}\r\n\r\n/**\r\n * Block that converts a linear sRGB color (r, g, b) to OkLCh (l, c, h). Hue is in radians.\r\n */\r\nexport class FlowGraphRGBToOkLChBlock extends FlowGraphBlock {\r\n    /**\r\n     * Input connection: the linear red component.\r\n     */\r\n    public readonly r: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: the linear green component.\r\n     */\r\n    public readonly g: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: the linear blue component.\r\n     */\r\n    public readonly b: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: the OkLCh lightness.\r\n     */\r\n    public readonly l: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: the OkLCh chroma.\r\n     */\r\n    public readonly c: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: the OkLCh hue, in radians.\r\n     */\r\n    public readonly h: FlowGraphDataConnection<number>;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.r = this.registerDataInput(\"r\", RichTypeNumber, 0);\r\n        this.g = this.registerDataInput(\"g\", RichTypeNumber, 0);\r\n        this.b = this.registerDataInput(\"b\", RichTypeNumber, 0);\r\n        this.l = this.registerDataOutput(\"l\", RichTypeNumber, 0);\r\n        this.c = this.registerDataOutput(\"c\", RichTypeNumber, 0);\r\n        this.h = this.registerDataOutput(\"h\", RichTypeNumber, 0);\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        const { l, c, h } = RgbToOkLch(this.r.getValue(context), this.g.getValue(context), this.b.getValue(context));\r\n        this.l.setValue(l, context);\r\n        this.c.setValue(c, context);\r\n        this.h.setValue(h, context);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.RGBToOkLCh;\r\n    }\r\n}\r\n\r\n/**\r\n * Block that converts an OkLCh color (l, c, h) to linear sRGB (r, g, b). Hue is in radians.\r\n */\r\nexport class FlowGraphRGBFromOkLChBlock extends FlowGraphBlock {\r\n    /**\r\n     * Input connection: the OkLCh lightness.\r\n     */\r\n    public readonly l: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: the OkLCh chroma.\r\n     */\r\n    public readonly c: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Input connection: the OkLCh hue, in radians.\r\n     */\r\n    public readonly h: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: the linear red component.\r\n     */\r\n    public readonly r: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: the linear green component.\r\n     */\r\n    public readonly g: FlowGraphDataConnection<number>;\r\n    /**\r\n     * Output connection: the linear blue component.\r\n     */\r\n    public readonly b: FlowGraphDataConnection<number>;\r\n\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.l = this.registerDataInput(\"l\", RichTypeNumber, 0);\r\n        this.c = this.registerDataInput(\"c\", RichTypeNumber, 0);\r\n        this.h = this.registerDataInput(\"h\", RichTypeNumber, 0);\r\n        this.r = this.registerDataOutput(\"r\", RichTypeNumber, 0);\r\n        this.g = this.registerDataOutput(\"g\", RichTypeNumber, 0);\r\n        this.b = this.registerDataOutput(\"b\", RichTypeNumber, 0);\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        const { r, g, b } = OkLchToRgb(this.l.getValue(context), this.c.getValue(context), this.h.getValue(context));\r\n        this.r.setValue(r, context);\r\n        this.g.setValue(g, context);\r\n        this.b.setValue(b, context);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.RGBFromOkLCh;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphMathBlocks.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphMathBlocks(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.Add, FlowGraphAddBlock);\r\n    RegisterClass(FlowGraphBlockNames.Subtract, FlowGraphSubtractBlock);\r\n    RegisterClass(FlowGraphBlockNames.Multiply, FlowGraphMultiplyBlock);\r\n    RegisterClass(FlowGraphBlockNames.Divide, FlowGraphDivideBlock);\r\n    RegisterClass(FlowGraphBlockNames.Random, FlowGraphRandomBlock);\r\n    RegisterClass(FlowGraphBlockNames.E, FlowGraphEBlock);\r\n    RegisterClass(FlowGraphBlockNames.PI, FlowGraphPiBlock);\r\n    RegisterClass(FlowGraphBlockNames.Tau, FlowGraphTauBlock);\r\n    RegisterClass(FlowGraphBlockNames.Inf, FlowGraphInfBlock);\r\n    RegisterClass(FlowGraphBlockNames.NaN, FlowGraphNaNBlock);\r\n    RegisterClass(FlowGraphBlockNames.Abs, FlowGraphAbsBlock);\r\n    RegisterClass(FlowGraphBlockNames.Sign, FlowGraphSignBlock);\r\n    RegisterClass(FlowGraphBlockNames.Trunc, FlowGraphTruncBlock);\r\n    RegisterClass(FlowGraphBlockNames.Floor, FlowGraphFloorBlock);\r\n    RegisterClass(FlowGraphBlockNames.Ceil, FlowGraphCeilBlock);\r\n    RegisterClass(FlowGraphBlockNames.Round, FlowGraphRoundBlock);\r\n    RegisterClass(FlowGraphBlockNames.Fraction, FlowGraphFractionBlock);\r\n    RegisterClass(FlowGraphBlockNames.Negation, FlowGraphNegationBlock);\r\n    RegisterClass(FlowGraphBlockNames.Modulo, FlowGraphModuloBlock);\r\n    RegisterClass(FlowGraphBlockNames.Min, FlowGraphMinBlock);\r\n    RegisterClass(FlowGraphBlockNames.Max, FlowGraphMaxBlock);\r\n    RegisterClass(FlowGraphBlockNames.Clamp, FlowGraphClampBlock);\r\n    RegisterClass(FlowGraphBlockNames.Saturate, FlowGraphSaturateBlock);\r\n    RegisterClass(FlowGraphBlockNames.MathInterpolation, FlowGraphMathInterpolationBlock);\r\n    RegisterClass(FlowGraphBlockNames.MathSlerp, FlowGraphMathSlerpBlock);\r\n    RegisterClass(FlowGraphBlockNames.SmoothStep, FlowGraphMathSmoothStepBlock);\r\n    RegisterClass(FlowGraphBlockNames.RGBToOkLCh, FlowGraphRGBToOkLChBlock);\r\n    RegisterClass(FlowGraphBlockNames.RGBFromOkLCh, FlowGraphRGBFromOkLChBlock);\r\n    RegisterClass(FlowGraphBlockNames.Equality, FlowGraphEqualityBlock);\r\n    RegisterClass(FlowGraphBlockNames.LessThan, FlowGraphLessThanBlock);\r\n    RegisterClass(FlowGraphBlockNames.LessThanOrEqual, FlowGraphLessThanOrEqualBlock);\r\n    RegisterClass(FlowGraphBlockNames.GreaterThan, FlowGraphGreaterThanBlock);\r\n    RegisterClass(FlowGraphBlockNames.GreaterThanOrEqual, FlowGraphGreaterThanOrEqualBlock);\r\n    RegisterClass(FlowGraphBlockNames.IsNaN, FlowGraphIsNanBlock);\r\n    RegisterClass(FlowGraphBlockNames.IsInfinity, FlowGraphIsInfinityBlock);\r\n    RegisterClass(FlowGraphBlockNames.DegToRad, FlowGraphDegToRadBlock);\r\n    RegisterClass(FlowGraphBlockNames.RadToDeg, FlowGraphRadToDegBlock);\r\n    RegisterClass(FlowGraphBlockNames.Asin, FlowGraphAsinBlock);\r\n    RegisterClass(FlowGraphBlockNames.Acos, FlowGraphAcosBlock);\r\n    RegisterClass(FlowGraphBlockNames.Atan, FlowGraphAtanBlock);\r\n    RegisterClass(FlowGraphBlockNames.Atan2, FlowGraphAtan2Block);\r\n    RegisterClass(FlowGraphBlockNames.Sinh, FlowGraphSinhBlock);\r\n    RegisterClass(FlowGraphBlockNames.Cosh, FlowGraphCoshBlock);\r\n    RegisterClass(FlowGraphBlockNames.Tanh, FlowGraphTanhBlock);\r\n    RegisterClass(FlowGraphBlockNames.Asinh, FlowGraphAsinhBlock);\r\n    RegisterClass(FlowGraphBlockNames.Acosh, FlowGraphAcoshBlock);\r\n    RegisterClass(FlowGraphBlockNames.Atanh, FlowGraphAtanhBlock);\r\n    RegisterClass(FlowGraphBlockNames.Exponential, FlowGraphExpBlock);\r\n    RegisterClass(FlowGraphBlockNames.Log, FlowGraphLogBlock);\r\n    RegisterClass(FlowGraphBlockNames.Log2, FlowGraphLog2Block);\r\n    RegisterClass(FlowGraphBlockNames.Log10, FlowGraphLog10Block);\r\n    RegisterClass(FlowGraphBlockNames.SquareRoot, FlowGraphSquareRootBlock);\r\n    RegisterClass(FlowGraphBlockNames.CubeRoot, FlowGraphCubeRootBlock);\r\n    RegisterClass(FlowGraphBlockNames.Power, FlowGraphPowerBlock);\r\n    RegisterClass(FlowGraphBlockNames.BitwiseNot, FlowGraphBitwiseNotBlock);\r\n    RegisterClass(FlowGraphBlockNames.BitwiseAnd, FlowGraphBitwiseAndBlock);\r\n    RegisterClass(FlowGraphBlockNames.BitwiseOr, FlowGraphBitwiseOrBlock);\r\n    RegisterClass(FlowGraphBlockNames.BitwiseXor, FlowGraphBitwiseXorBlock);\r\n    RegisterClass(FlowGraphBlockNames.BitwiseLeftShift, FlowGraphBitwiseLeftShiftBlock);\r\n    RegisterClass(FlowGraphBlockNames.BitwiseRightShift, FlowGraphBitwiseRightShiftBlock);\r\n    RegisterClass(FlowGraphBlockNames.LeadingZeros, FlowGraphLeadingZerosBlock);\r\n    RegisterClass(FlowGraphBlockNames.TrailingZeros, FlowGraphTrailingZerosBlock);\r\n    RegisterClass(FlowGraphBlockNames.OneBitsCounter, FlowGraphOneBitsCounterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport {\n    RichTypeMatrix,\n    RichTypeMatrix2D,\n    RichTypeMatrix3D,\n    RichTypeNumber,\n    RichTypeVector2,\n    RichTypeVector3,\n    RichTypeVector4,\n    type RichType,\n} from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { Matrix, Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\nimport { type Nullable } from \"core/types\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphMatrix2D, FlowGraphMatrix3D } from \"core/FlowGraph/CustomTypes/flowGraphMatrix\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\nabstract class FlowGraphMathCombineBlock<ResultT> extends FlowGraphCachedOperationBlock<ResultT> {\n    /**\n     * Base class for blocks that combine multiple numeric inputs into a single result.\n     * Handles registering data inputs and managing cached outputs.\n     * @param numberOfInputs The number of input values to combine.\n     * @param type The type of the result.\n     * @param config The block configuration.\n     */\n    constructor(numberOfInputs: number, type: RichType<ResultT>, config?: IFlowGraphBlockConfiguration) {\n        super(type, config);\n        for (let i = 0; i < numberOfInputs; i++) {\n            this.registerDataInput(`input_${i}`, RichTypeNumber, 0);\n        }\n    }\n}\n\n/**\n * Abstract class representing a flow graph block that extracts multiple outputs from a single input.\n */\nabstract class FlowGraphMathExtractBlock<InputT> extends FlowGraphBlock {\n    /**\n     * Creates an instance of FlowGraphMathExtractBlock.\n     *\n     * @param numberOfOutputs - The number of outputs to be extracted from the input.\n     * @param type - The type of the input data.\n     * @param config - Optional configuration for the flow graph block.\n     */\n    constructor(numberOfOutputs: number, type: RichType<InputT>, config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.registerDataInput(\"input\", type);\n        for (let i = 0; i < numberOfOutputs; i++) {\n            this.registerDataOutput(`output_${i}`, RichTypeNumber, 0);\n        }\n    }\n}\n/**\n * Combines two floats into a new Vector2\n */\nexport class FlowGraphCombineVector2Block extends FlowGraphMathCombineBlock<Vector2> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(2, RichTypeVector2, config);\n    }\n\n    /**\n     * @internal\n     * Combines two floats into a new Vector2\n     */\n    public override _doOperation(context: FlowGraphContext): Vector2 {\n        if (!context._hasExecutionVariable(this, \"cachedVector\")) {\n            context._setExecutionVariable(this, \"cachedVector\", new Vector2());\n        }\n        const vector = context._getExecutionVariable<Nullable<Vector2>>(this, \"cachedVector\", null) as Vector2;\n        vector.set(this.getDataInput(\"input_0\")!.getValue(context), this.getDataInput(\"input_1\")!.getValue(context));\n        return vector;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CombineVector2;\n    }\n}\n\n/**\n * Combines three floats into a new Vector3\n */\nexport class FlowGraphCombineVector3Block extends FlowGraphMathCombineBlock<Vector3> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(3, RichTypeVector3, config);\n    }\n\n    public override _doOperation(context: FlowGraphContext): Vector3 {\n        if (!context._hasExecutionVariable(this, \"cachedVector\")) {\n            context._setExecutionVariable(this, \"cachedVector\", new Vector3());\n        }\n        const vector = context._getExecutionVariable<Nullable<Vector3>>(this, \"cachedVector\", null) as Vector3;\n        vector.set(this.getDataInput(\"input_0\")!.getValue(context), this.getDataInput(\"input_1\")!.getValue(context), this.getDataInput(\"input_2\")!.getValue(context));\n        return vector;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CombineVector3;\n    }\n}\n\n/**\n * Combines four floats into a new Vector4\n */\nexport class FlowGraphCombineVector4Block extends FlowGraphMathCombineBlock<Vector4> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(4, RichTypeVector4, config);\n    }\n\n    public override _doOperation(context: FlowGraphContext): Vector4 {\n        if (!context._hasExecutionVariable(this, \"cachedVector\")) {\n            context._setExecutionVariable(this, \"cachedVector\", new Vector4());\n        }\n        const vector = context._getExecutionVariable<Nullable<Vector4>>(this, \"cachedVector\", null) as Vector4;\n        vector.set(\n            this.getDataInput(\"input_0\")!.getValue(context),\n            this.getDataInput(\"input_1\")!.getValue(context),\n            this.getDataInput(\"input_2\")!.getValue(context),\n            this.getDataInput(\"input_3\")!.getValue(context)\n        );\n        return vector;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CombineVector4;\n    }\n}\n\n/**\n * Configuration for the matrix combine blocks.\n * @deprecated The matrix combine blocks now default to column-major input, matching Babylon's\n * {@link Matrix} storage and the glTF/KHR_interactivity convention. This interface is retained so the\n * `inputIsColumnMajor` option keeps being honoured; set it to `false` to feed row-major input.\n *\n * BREAKING: the meaning of `inputIsColumnMajor` is inverted from previous releases, not just its\n * default. Previously `inputIsColumnMajor: true` took the transposing path and the default (unset)\n * treated input as row-major. Now the default (unset) is column-major, `inputIsColumnMajor: false`\n * takes the transposing path, and `inputIsColumnMajor: true` is the straight (non-transposing) path.\n * The unset behaviour is unchanged for graphs that never set the flag, but anyone who explicitly set\n * `true` or `false` before now gets the opposite transform and should drop the flag (or flip it).\n */\nexport interface IFlowGraphCombineMatrixBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Whether the input is already in column-major order. Defaults to `true`.\n     * @deprecated Provide column-major input (the default) and omit this flag. Set to `false` only to\n     * keep feeding legacy row-major input, which is transposed into the matrix's column-major storage.\n     * Note the inverted meaning versus previous releases (see the interface deprecation note): a former\n     * `inputIsColumnMajor: true` no longer transposes, and a former `false` now does.\n     */\n    inputIsColumnMajor?: boolean;\n}\n\n/**\n * Combines 16 floats into a new Matrix.\n *\n * The inputs are in column-major order, matching Babylon's {@link Matrix} storage and the order used\n * by `Matrix.FromArray`, `Matrix.FromValues` and {@link FlowGraphExtractMatrixBlock}, so combining\n * and extracting round-trip.\n */\nexport class FlowGraphCombineMatrixBlock extends FlowGraphMathCombineBlock<Matrix> {\n    constructor(config?: IFlowGraphCombineMatrixBlockConfiguration) {\n        super(16, RichTypeMatrix, config);\n    }\n\n    public override _doOperation(context: FlowGraphContext): Matrix {\n        if (!context._hasExecutionVariable(this, \"cachedMatrix\")) {\n            context._setExecutionVariable(this, \"cachedMatrix\", new Matrix());\n        }\n        const matrix = context._getExecutionVariable<Nullable<Matrix>>(this, \"cachedMatrix\", null) as Matrix;\n        if ((this.config as IFlowGraphCombineMatrixBlockConfiguration | undefined)?.inputIsColumnMajor === false) {\n            // Legacy row-major input: transpose into the matrix's column-major storage.\n            matrix.set(\n                this.getDataInput(\"input_0\")!.getValue(context),\n                this.getDataInput(\"input_4\")!.getValue(context),\n                this.getDataInput(\"input_8\")!.getValue(context),\n                this.getDataInput(\"input_12\")!.getValue(context),\n                this.getDataInput(\"input_1\")!.getValue(context),\n                this.getDataInput(\"input_5\")!.getValue(context),\n                this.getDataInput(\"input_9\")!.getValue(context),\n                this.getDataInput(\"input_13\")!.getValue(context),\n                this.getDataInput(\"input_2\")!.getValue(context),\n                this.getDataInput(\"input_6\")!.getValue(context),\n                this.getDataInput(\"input_10\")!.getValue(context),\n                this.getDataInput(\"input_14\")!.getValue(context),\n                this.getDataInput(\"input_3\")!.getValue(context),\n                this.getDataInput(\"input_7\")!.getValue(context),\n                this.getDataInput(\"input_11\")!.getValue(context),\n                this.getDataInput(\"input_15\")!.getValue(context)\n            );\n            return matrix;\n        }\n        matrix.set(\n            this.getDataInput(\"input_0\")!.getValue(context),\n            this.getDataInput(\"input_1\")!.getValue(context),\n            this.getDataInput(\"input_2\")!.getValue(context),\n            this.getDataInput(\"input_3\")!.getValue(context),\n            this.getDataInput(\"input_4\")!.getValue(context),\n            this.getDataInput(\"input_5\")!.getValue(context),\n            this.getDataInput(\"input_6\")!.getValue(context),\n            this.getDataInput(\"input_7\")!.getValue(context),\n            this.getDataInput(\"input_8\")!.getValue(context),\n            this.getDataInput(\"input_9\")!.getValue(context),\n            this.getDataInput(\"input_10\")!.getValue(context),\n            this.getDataInput(\"input_11\")!.getValue(context),\n            this.getDataInput(\"input_12\")!.getValue(context),\n            this.getDataInput(\"input_13\")!.getValue(context),\n            this.getDataInput(\"input_14\")!.getValue(context),\n            this.getDataInput(\"input_15\")!.getValue(context)\n        );\n        return matrix;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CombineMatrix;\n    }\n}\n\n/**\n * Combines 4 floats into a new Matrix2D, in column-major order.\n */\nexport class FlowGraphCombineMatrix2DBlock extends FlowGraphMathCombineBlock<FlowGraphMatrix2D> {\n    constructor(config?: IFlowGraphCombineMatrixBlockConfiguration) {\n        super(4, RichTypeMatrix2D, config);\n    }\n\n    public override _doOperation(context: FlowGraphContext): FlowGraphMatrix2D {\n        if (!context._hasExecutionVariable(this, \"cachedMatrix\")) {\n            context._setExecutionVariable(this, \"cachedMatrix\", new FlowGraphMatrix2D());\n        }\n        const matrix = context._getExecutionVariable<Nullable<FlowGraphMatrix2D>>(this, \"cachedMatrix\", null) as FlowGraphMatrix2D;\n        const columnMajor = (this.config as IFlowGraphCombineMatrixBlockConfiguration | undefined)?.inputIsColumnMajor !== false;\n        matrix.fromArray(\n            columnMajor\n                ? [\n                      this.getDataInput(\"input_0\")!.getValue(context),\n                      this.getDataInput(\"input_1\")!.getValue(context),\n                      this.getDataInput(\"input_2\")!.getValue(context),\n                      this.getDataInput(\"input_3\")!.getValue(context),\n                  ]\n                : [\n                      // Legacy row-major input, transposed into column-major storage.\n                      this.getDataInput(\"input_0\")!.getValue(context),\n                      this.getDataInput(\"input_2\")!.getValue(context),\n                      this.getDataInput(\"input_1\")!.getValue(context),\n                      this.getDataInput(\"input_3\")!.getValue(context),\n                  ]\n        );\n        return matrix;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CombineMatrix2D;\n    }\n}\n\n/**\n * Combines 9 floats into a new Matrix3D, in column-major order.\n */\nexport class FlowGraphCombineMatrix3DBlock extends FlowGraphMathCombineBlock<FlowGraphMatrix3D> {\n    constructor(config?: IFlowGraphCombineMatrixBlockConfiguration) {\n        super(9, RichTypeMatrix3D, config);\n    }\n\n    public override _doOperation(context: FlowGraphContext): FlowGraphMatrix3D {\n        if (!context._hasExecutionVariable(this, \"cachedMatrix\")) {\n            context._setExecutionVariable(this, \"cachedMatrix\", new FlowGraphMatrix3D());\n        }\n        const matrix = context._getExecutionVariable<Nullable<FlowGraphMatrix3D>>(this, \"cachedMatrix\", null) as FlowGraphMatrix3D;\n        const columnMajor = (this.config as IFlowGraphCombineMatrixBlockConfiguration | undefined)?.inputIsColumnMajor !== false;\n        matrix.fromArray(\n            columnMajor\n                ? [\n                      this.getDataInput(\"input_0\")!.getValue(context),\n                      this.getDataInput(\"input_1\")!.getValue(context),\n                      this.getDataInput(\"input_2\")!.getValue(context),\n                      this.getDataInput(\"input_3\")!.getValue(context),\n                      this.getDataInput(\"input_4\")!.getValue(context),\n                      this.getDataInput(\"input_5\")!.getValue(context),\n                      this.getDataInput(\"input_6\")!.getValue(context),\n                      this.getDataInput(\"input_7\")!.getValue(context),\n                      this.getDataInput(\"input_8\")!.getValue(context),\n                  ]\n                : [\n                      // Legacy row-major input, transposed into column-major storage.\n                      this.getDataInput(\"input_0\")!.getValue(context),\n                      this.getDataInput(\"input_3\")!.getValue(context),\n                      this.getDataInput(\"input_6\")!.getValue(context),\n                      this.getDataInput(\"input_1\")!.getValue(context),\n                      this.getDataInput(\"input_4\")!.getValue(context),\n                      this.getDataInput(\"input_7\")!.getValue(context),\n                      this.getDataInput(\"input_2\")!.getValue(context),\n                      this.getDataInput(\"input_5\")!.getValue(context),\n                      this.getDataInput(\"input_8\")!.getValue(context),\n                  ]\n        );\n        return matrix;\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CombineMatrix3D;\n    }\n}\n\n/**\n * Extracts two floats from a Vector2\n */\nexport class FlowGraphExtractVector2Block extends FlowGraphMathExtractBlock<Vector2> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(2, RichTypeVector2, config);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext): void {\n        let input = this.getDataInput(\"input\")?.getValue(context) as Vector2;\n        if (!input) {\n            input = Vector2.Zero();\n            this.getDataInput(\"input\")!.setValue(input, context);\n        }\n        this.getDataOutput(\"output_0\")!.setValue(input.x, context);\n        this.getDataOutput(\"output_1\")!.setValue(input.y, context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ExtractVector2;\n    }\n}\n\n/**\n * Extracts three floats from a Vector3\n */\nexport class FlowGraphExtractVector3Block extends FlowGraphMathExtractBlock<Vector3> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(3, RichTypeVector3, config);\n    }\n    public override _updateOutputs(context: FlowGraphContext): void {\n        let input = this.getDataInput(\"input\")?.getValue(context) as Vector3;\n        if (!input) {\n            input = Vector3.Zero();\n            this.getDataInput(\"input\")!.setValue(input, context);\n        }\n        this.getDataOutput(\"output_0\")!.setValue(input.x, context);\n        this.getDataOutput(\"output_1\")!.setValue(input.y, context);\n        this.getDataOutput(\"output_2\")!.setValue(input.z, context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ExtractVector3;\n    }\n}\n\n/**\n * Extracts four floats from a Vector4\n */\nexport class FlowGraphExtractVector4Block extends FlowGraphMathExtractBlock<Vector4> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(4, RichTypeVector4, config);\n    }\n    public override _updateOutputs(context: FlowGraphContext): void {\n        let input = this.getDataInput(\"input\")?.getValue(context) as Vector4;\n        if (!input) {\n            input = Vector4.Zero();\n            this.getDataInput(\"input\")!.setValue(input, context);\n        }\n        this.getDataOutput(\"output_0\")!.setValue(input.x, context);\n        this.getDataOutput(\"output_1\")!.setValue(input.y, context);\n        this.getDataOutput(\"output_2\")!.setValue(input.z, context);\n        this.getDataOutput(\"output_3\")!.setValue(input.w, context);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ExtractVector4;\n    }\n}\n\n/**\n * Extracts 16 floats from a Matrix\n */\nexport class FlowGraphExtractMatrixBlock extends FlowGraphMathExtractBlock<Matrix> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(16, RichTypeMatrix, config);\n    }\n    public override _updateOutputs(context: FlowGraphContext): void {\n        let input = this.getDataInput(\"input\")?.getValue(context) as Matrix;\n        if (!input) {\n            input = Matrix.Identity();\n            this.getDataInput(\"input\")!.setValue(input, context);\n        }\n        for (let i = 0; i < 16; i++) {\n            this.getDataOutput(`output_${i}`)!.setValue(input.m[i], context);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ExtractMatrix;\n    }\n}\n\n/**\n * Extracts 4 floats from a Matrix2D\n */\nexport class FlowGraphExtractMatrix2DBlock extends FlowGraphMathExtractBlock<FlowGraphMatrix2D> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(4, RichTypeMatrix2D, config);\n    }\n    public override _updateOutputs(context: FlowGraphContext): void {\n        let input = this.getDataInput(\"input\")?.getValue(context) as FlowGraphMatrix2D;\n        if (!input) {\n            input = new FlowGraphMatrix2D();\n            this.getDataInput(\"input\")!.setValue(input, context);\n        }\n        for (let i = 0; i < 4; i++) {\n            this.getDataOutput(`output_${i}`)!.setValue(input.m[i], context);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ExtractMatrix2D;\n    }\n}\n\n/**\n * Extracts 4 floats from a Matrix2D\n */\nexport class FlowGraphExtractMatrix3DBlock extends FlowGraphMathExtractBlock<FlowGraphMatrix3D> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(9, RichTypeMatrix3D, config);\n    }\n    public override _updateOutputs(context: FlowGraphContext): void {\n        let input = this.getDataInput(\"input\")?.getValue(context) as FlowGraphMatrix3D;\n        if (!input) {\n            input = new FlowGraphMatrix3D();\n            this.getDataInput(\"input\")!.setValue(input, context);\n        }\n        for (let i = 0; i < 9; i++) {\n            this.getDataOutput(`output_${i}`)!.setValue(input.m[i], context);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ExtractMatrix3D;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphMathCombineExtractBlocks.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphMathCombineExtractBlocks(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.CombineVector2, FlowGraphCombineVector2Block);\n    RegisterClass(FlowGraphBlockNames.CombineVector3, FlowGraphCombineVector3Block);\n    RegisterClass(FlowGraphBlockNames.CombineVector4, FlowGraphCombineVector4Block);\n    RegisterClass(FlowGraphBlockNames.CombineMatrix, FlowGraphCombineMatrixBlock);\n    RegisterClass(FlowGraphBlockNames.CombineMatrix2D, FlowGraphCombineMatrix2DBlock);\n    RegisterClass(FlowGraphBlockNames.CombineMatrix3D, FlowGraphCombineMatrix3DBlock);\n    RegisterClass(FlowGraphBlockNames.ExtractVector2, FlowGraphExtractVector2Block);\n    RegisterClass(FlowGraphBlockNames.ExtractVector3, FlowGraphExtractVector3Block);\n    RegisterClass(FlowGraphBlockNames.ExtractVector4, FlowGraphExtractVector4Block);\n    RegisterClass(FlowGraphBlockNames.ExtractMatrix, FlowGraphExtractMatrixBlock);\n    RegisterClass(FlowGraphBlockNames.ExtractMatrix2D, FlowGraphExtractMatrix2DBlock);\n    RegisterClass(FlowGraphBlockNames.ExtractMatrix3D, FlowGraphExtractMatrix3DBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"core/types\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport {\n    FlowGraphTypes,\n    getRichTypeByFlowGraphType,\n    RichTypeBoolean,\n    RichTypeMatrix,\n    RichTypeNumber,\n    RichTypeQuaternion,\n    RichTypeVector3,\n} from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphUnaryOperationBlock } from \"../flowGraphUnaryOperationBlock\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { FlowGraphMatrix2D, FlowGraphMatrix3D } from \"core/FlowGraph/CustomTypes/flowGraphMatrix\";\nimport { FlowGraphBinaryOperationBlock } from \"../flowGraphBinaryOperationBlock\";\nimport { type FlowGraphMatrix } from \"core/FlowGraph/utils\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Threshold below which the determinant of the normalized 3x3 of a matrix is treated as zero, indicating a\n * degenerate (non-decomposable) matrix whose columns are linearly dependent.\n */\nconst MatrixDecomposeDegenerateEpsilon = 1e-6;\n\n/**\n * Builds a matrix of the given flow graph matrix type with every element set to zero.\n * @param matrixType the matrix type to build\n * @returns the zero matrix\n */\nfunction CreateZeroMatrix(matrixType: FlowGraphTypes): FlowGraphMatrix {\n    if (matrixType === FlowGraphTypes.Matrix2D) {\n        return new FlowGraphMatrix2D([0, 0, 0, 0]);\n    }\n    if (matrixType === FlowGraphTypes.Matrix3D) {\n        return new FlowGraphMatrix3D([0, 0, 0, 0, 0, 0, 0, 0, 0]);\n    }\n    return Matrix.FromArray(new Array(16).fill(0));\n}\n\n/**\n * Configuration for the matrix blocks.\n */\nexport interface IFlowGraphMatrixBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The type of the matrix. Default is Matrix (which is 4x4)\n     */\n    matrixType: FlowGraphTypes;\n}\n\n/**\n * Configuration for the matrix decompose block.\n */\nexport interface IFlowGraphMatrixDecomposeBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * When a matrix cannot be decomposed, output the translation and the raw column lengths that were\n     * extracted from the matrix instead of the type-default translation and scale. `isValid` is reported\n     * as `false` either way. Defaults to `false`.\n     *\n     * A host whose specification requires those components to be preserved can turn this on; it is\n     * opt-in so that the default block behaviour stays unchanged.\n     */\n    keepDegenerateComponents?: boolean;\n}\n/**\n * Transposes a matrix.\n */\nexport class FlowGraphTransposeBlock extends FlowGraphUnaryOperationBlock<FlowGraphMatrix, FlowGraphMatrix> {\n    /**\n     * Creates a new instance of the block.\n     * @param config the configuration of the block\n     */\n    constructor(config?: IFlowGraphMatrixBlockConfiguration) {\n        super(\n            getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix),\n            getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix),\n            (a) => (a.transpose ? a.transpose() : Matrix.Transpose(a as Matrix)),\n            FlowGraphBlockNames.Transpose,\n            config\n        );\n    }\n}\n\n/**\n * Gets the determinant of a matrix.\n */\nexport class FlowGraphDeterminantBlock extends FlowGraphUnaryOperationBlock<FlowGraphMatrix, number> {\n    /**\n     * Creates a new instance of the block.\n     * @param config the configuration of the block\n     */\n    constructor(config?: IFlowGraphMatrixBlockConfiguration) {\n        super(getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix), RichTypeNumber, (a) => a.determinant(), FlowGraphBlockNames.Determinant, config);\n    }\n}\n\n/**\n * Inverts a matrix.\n */\nexport class FlowGraphInvertMatrixBlock extends FlowGraphCachedOperationBlock<FlowGraphMatrix> {\n    /**\n     * The matrix to invert.\n     */\n    public readonly a: FlowGraphDataConnection<FlowGraphMatrix>;\n\n    private readonly _matrixType: FlowGraphTypes;\n\n    /**\n     * Creates a new instance of the inverse block.\n     * @param config the configuration of the block\n     */\n    constructor(config?: IFlowGraphMatrixBlockConfiguration) {\n        super(getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix), config);\n        this._matrixType = config?.matrixType || FlowGraphTypes.Matrix;\n        this.a = this.registerDataInput(\"a\", getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix));\n    }\n\n    public override _doOperation(context: FlowGraphContext): FlowGraphMatrix | undefined {\n        const a = this.a.getValue(context);\n        // A matrix is only invertible when its determinant is a finite, non-zero number. For a zero, NaN, or\n        // infinite determinant, returning undefined makes the cached base report isValid = false.\n        const determinant = a.determinant();\n        if (determinant === 0 || !Number.isFinite(determinant)) {\n            return undefined;\n        }\n        return (a as FlowGraphMatrix2D).inverse ? (a as FlowGraphMatrix2D).inverse() : Matrix.Invert(a as Matrix);\n    }\n\n    /**\n     * A matrix with no inverse reports an all-zero matrix rather than the identity default of the\n     * matrix type, so the output is not mistaken for a meaningful transform.\n     * @returns a matrix of the block's type with every element set to zero\n     */\n    protected override _getInvalidOutputValue(): FlowGraphMatrix {\n        return CreateZeroMatrix(this._matrixType);\n    }\n    public override getClassName(): string {\n        return FlowGraphBlockNames.InvertMatrix;\n    }\n}\n\n/**\n * Multiplies two matrices.\n */\nexport class FlowGraphMatrixMultiplicationBlock extends FlowGraphBinaryOperationBlock<FlowGraphMatrix, FlowGraphMatrix, FlowGraphMatrix> {\n    /**\n     * Creates a new instance of the multiplication block.\n     * Note - this is similar to the math multiplication if not using matrix per-component multiplication.\n     * @param config the configuration of the block\n     */\n    constructor(config?: IFlowGraphMatrixBlockConfiguration) {\n        super(\n            getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix),\n            getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix),\n            getRichTypeByFlowGraphType(config?.matrixType || FlowGraphTypes.Matrix),\n            (a, b) => b.multiply(a as any),\n            FlowGraphBlockNames.MatrixMultiplication,\n            config\n        );\n    }\n}\n\n/**\n * Matrix decompose block\n */\nexport class FlowGraphMatrixDecomposeBlock extends FlowGraphBlock {\n    /**\n     * The input of this block\n     */\n    public readonly input: FlowGraphDataConnection<Matrix>;\n\n    /**\n     * The position output of this block\n     */\n    public readonly position: FlowGraphDataConnection<Vector3>;\n    /**\n     * The rotation output of this block\n     */\n    public readonly rotationQuaternion: FlowGraphDataConnection<Quaternion>;\n    /**\n     * The scaling output of this block\n     */\n    public readonly scaling: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Is the matrix valid\n     */\n    public readonly isValid: FlowGraphDataConnection<boolean>;\n\n    constructor(config?: IFlowGraphMatrixDecomposeBlockConfiguration) {\n        super(config);\n        this.input = this.registerDataInput(\"input\", RichTypeMatrix);\n        this.position = this.registerDataOutput(\"position\", RichTypeVector3);\n        this.rotationQuaternion = this.registerDataOutput(\"rotationQuaternion\", RichTypeQuaternion);\n        this.scaling = this.registerDataOutput(\"scaling\", RichTypeVector3);\n        this.isValid = this.registerDataOutput(\"isValid\", RichTypeBoolean, false);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext) {\n        // _updateOutputs runs on every read of any of this block's four outputs. Cache the decomposition\n        // per executionId (matching FlowGraphMatrixComposeBlock below) so reading all four outputs in one\n        // frame does the work once instead of four times.\n        const cachedExecutionId = context._getExecutionVariable(this, \"executionId\", -1);\n        const cachedPosition = context._getExecutionVariable<Nullable<Vector3>>(this, \"cachedPosition\", null);\n        const cachedRotation = context._getExecutionVariable<Nullable<Quaternion>>(this, \"cachedRotation\", null);\n        const cachedScaling = context._getExecutionVariable<Nullable<Vector3>>(this, \"cachedScaling\", null);\n        const cachedIsValid = context._getExecutionVariable<Nullable<boolean>>(this, \"cachedIsValid\", null);\n        if (cachedExecutionId === context.executionId && cachedPosition && cachedRotation && cachedScaling && cachedIsValid !== null) {\n            this.isValid.setValue(cachedIsValid, context);\n            this.position.setValue(cachedPosition, context);\n            this.rotationQuaternion.setValue(cachedRotation, context);\n            this.scaling.setValue(cachedScaling, context);\n            return;\n        }\n\n        const matrix = this.input.getValue(context);\n        const m = matrix.m;\n        const keepDegenerateComponents = !!(this.config as IFlowGraphMatrixDecomposeBlockConfiguration | undefined)?.keepDegenerateComponents;\n\n        // The fourth row of the matrix is ignored: the translation comes from the first three elements of the\n        // fourth column, the scale from the lengths of the first three columns of the upper-left 3x3, and the\n        // rotation from that 3x3 once normalized.\n        const translation = new Vector3(m[12], m[13], m[14]);\n        const scaleX = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);\n        const scaleY = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);\n        const scaleZ = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);\n\n        // The matrix cannot be decomposed: the rotation is undefined, so report an identity rotation and either the\n        // components that were extracted from the matrix or the type defaults.\n        const degenerateOutputs = (keepComponents: boolean) => ({\n            isValid: false,\n            rotationQuaternion: Quaternion.Identity(),\n            position: keepComponents ? translation : Vector3.Zero(),\n            scaling: keepComponents ? new Vector3(scaleX, scaleY, scaleZ) : Vector3.One(),\n        });\n\n        let result: { isValid: boolean; position: Vector3; rotationQuaternion: Quaternion; scaling: Vector3 };\n\n        const areScalesFinite = Number.isFinite(scaleX) && Number.isFinite(scaleY) && Number.isFinite(scaleZ);\n        const isTranslationFinite = Number.isFinite(m[12]) && Number.isFinite(m[13]) && Number.isFinite(m[14]);\n        if (!areScalesFinite || (!keepDegenerateComponents && !isTranslationFinite)) {\n            result = degenerateOutputs(keepDegenerateComponents);\n        } else if (scaleX === 0 || scaleY === 0 || scaleZ === 0) {\n            // A zero scale component leaves the rotation undefined, but the translation and the (degenerate) scale\n            // are still well-defined, so they are reported as-is.\n            result = degenerateOutputs(true);\n        } else {\n            // The determinant of the upper-left 3x3 (the fourth row is ignored) gives the handedness; dividing by the\n            // product of the scales yields the determinant of the normalized 3x3, which is (close to) zero only when the\n            // columns are linearly dependent — a degenerate matrix that cannot represent a rotation.\n            const determinant = m[0] * (m[5] * m[10] - m[6] * m[9]) - m[4] * (m[1] * m[10] - m[2] * m[9]) + m[8] * (m[1] * m[6] - m[2] * m[5]);\n            const normalizedDeterminant = determinant / (scaleX * scaleY * scaleZ);\n            if (Math.abs(normalizedDeterminant) < MatrixDecomposeDegenerateEpsilon) {\n                result = degenerateOutputs(keepDegenerateComponents);\n            } else {\n                // The remaining matrix is well-formed, so the actual translation/rotation/scale extraction is delegated\n                // to the shared Matrix.decompose. That keeps the rotation and the handedness-sign convention identical to\n                // the rest of Babylon (a left-handed matrix negates the same scale component everywhere). The fourth row is\n                // reset to (0, 0, 0, 1) first because this operation ignores it, whereas Matrix.decompose's internal\n                // determinant would otherwise let a non-standard fourth row flip the handedness.\n                const normalized = Matrix.FromValues(m[0], m[1], m[2], 0, m[4], m[5], m[6], 0, m[8], m[9], m[10], 0, m[12], m[13], m[14], 1);\n                const outScaling = new Vector3();\n                const outRotation = new Quaternion();\n                const outPosition = new Vector3();\n                normalized.decompose(outScaling, outRotation, outPosition);\n                result = { isValid: true, position: outPosition, rotationQuaternion: outRotation, scaling: outScaling };\n            }\n        }\n\n        this.isValid.setValue(result.isValid, context);\n        this.position.setValue(result.position, context);\n        this.rotationQuaternion.setValue(result.rotationQuaternion, context);\n        this.scaling.setValue(result.scaling, context);\n        context._setExecutionVariable(this, \"cachedIsValid\", result.isValid);\n        context._setExecutionVariable(this, \"cachedPosition\", result.position);\n        context._setExecutionVariable(this, \"cachedRotation\", result.rotationQuaternion);\n        context._setExecutionVariable(this, \"cachedScaling\", result.scaling);\n        context._setExecutionVariable(this, \"executionId\", context.executionId);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.MatrixDecompose;\n    }\n}\n\n/**\n * Matrix compose block\n */\nexport class FlowGraphMatrixComposeBlock extends FlowGraphBlock {\n    /**\n     * The position input of this block\n     */\n    public readonly position: FlowGraphDataConnection<Vector3>;\n    /**\n     * The rotation input of this block\n     */\n    public readonly rotationQuaternion: FlowGraphDataConnection<Quaternion>;\n    /**\n     * The scaling input of this block\n     */\n    public readonly scaling: FlowGraphDataConnection<Vector3>;\n    /**\n     * The output of this block\n     */\n    public readonly value: FlowGraphDataConnection<Matrix>;\n\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.position = this.registerDataInput(\"position\", RichTypeVector3);\n        this.rotationQuaternion = this.registerDataInput(\"rotationQuaternion\", RichTypeQuaternion);\n        this.scaling = this.registerDataInput(\"scaling\", RichTypeVector3);\n        this.value = this.registerDataOutput(\"value\", RichTypeMatrix);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext) {\n        const cachedExecutionId = context._getExecutionVariable(this, \"executionId\", -1);\n        const cachedMatrix = context._getExecutionVariable(this, \"cachedMatrix\", null);\n        if (cachedExecutionId === context.executionId && cachedMatrix) {\n            this.value.setValue(cachedMatrix, context);\n        } else {\n            const matrix = Matrix.Compose(this.scaling.getValue(context), this.rotationQuaternion.getValue(context), this.position.getValue(context));\n            this.value.setValue(matrix, context);\n            context._setExecutionVariable(this, \"cachedMatrix\", matrix);\n            context._setExecutionVariable(this, \"executionId\", context.executionId);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.MatrixCompose;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphMatrixMathBlocks.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphMatrixMathBlocks(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.Transpose, FlowGraphTransposeBlock);\n    RegisterClass(FlowGraphBlockNames.Determinant, FlowGraphDeterminantBlock);\n    RegisterClass(FlowGraphBlockNames.InvertMatrix, FlowGraphInvertMatrixBlock);\n    RegisterClass(FlowGraphBlockNames.MatrixMultiplication, FlowGraphMatrixMultiplicationBlock);\n    RegisterClass(FlowGraphBlockNames.MatrixDecompose, FlowGraphMatrixDecomposeBlock);\n    RegisterClass(FlowGraphBlockNames.MatrixCompose, FlowGraphMatrixComposeBlock);\n}\n","import { type IQuaternionLike } from \"../Maths/math.like\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { Matrix, Quaternion, Vector2, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Vector3Dot, Vector4Dot } from \"../Maths/math.vector.functions\";\r\nimport { type DeepImmutable } from \"../types\";\r\n\r\n// *** NOTE ***\r\n// These functions should ideally go in math.vector.functions.ts, but they require math.vector.ts to\r\n// be imported which is big. To avoid the larger bundle size, they are kept inside flow graph for now.\r\n\r\n/**\r\n * Implementation-defined threshold used by the slerp and up/forward quaternion operations\r\n * to detect near-zero lengths and (anti)parallel vectors.\r\n */\r\nconst SlerpEpsilon = 1e-6;\r\n\r\n/**\r\n * Returns a unit vector perpendicular to the provided vector.\r\n * @param v the input vector (does not need to be unit length)\r\n * @returns a unit vector perpendicular to `v`\r\n */\r\nfunction GetAnyPerpendicularVector(v: DeepImmutable<Vector3>): Vector3 {\r\n    const absX = Math.abs(v.x);\r\n    const absY = Math.abs(v.y);\r\n    const absZ = Math.abs(v.z);\r\n    // Cross with whichever cardinal axis is least aligned with `v` to avoid a degenerate cross product.\r\n    let other: DeepImmutable<Vector3>;\r\n    if (absX <= absY && absX <= absZ) {\r\n        other = Vector3.RightReadOnly;\r\n    } else if (absY <= absZ) {\r\n        other = Vector3.UpReadOnly;\r\n    } else {\r\n        other = Vector3.LeftHandedForwardReadOnly;\r\n    }\r\n    return Vector3.Cross(v, other).normalize();\r\n}\r\n\r\n/**\r\n * Returns the angle in radians between two quaternions\r\n * @param q1 defines the first quaternion\r\n * @param q2 defines the second quaternion\r\n * @returns the angle in radians between the two quaternions\r\n */\r\nexport function GetAngleBetweenQuaternions(q1: DeepImmutable<IQuaternionLike>, q2: DeepImmutable<IQuaternionLike>): number {\r\n    return Math.acos(Clamp(Vector4Dot(q1, q2), -1, 1)) * 2;\r\n}\r\n\r\n/**\r\n * Creates a quaternion from two direction vectors\r\n * @param a defines the first direction vector\r\n * @param b defines the second direction vector\r\n * @returns the target quaternion\r\n */\r\nexport function GetQuaternionFromDirections<T extends Vector3>(a: DeepImmutable<T>, b: DeepImmutable<T>): Quaternion {\r\n    const result = new Quaternion();\r\n    GetQuaternionFromDirectionsToRef(a, b, result);\r\n    return result;\r\n}\r\n\r\n/**\r\n * Creates a quaternion from two direction vectors\r\n * @param a defines the first direction vector\r\n * @param b defines the second direction vector\r\n * @param result defines the target quaternion\r\n * @returns the target quaternion\r\n */\r\nexport function GetQuaternionFromDirectionsToRef<T extends Vector3, ResultT extends Quaternion>(a: DeepImmutable<T>, b: DeepImmutable<T>, result: ResultT): ResultT {\r\n    const dot = Vector3Dot(a, b);\r\n    if (Number.isFinite(dot) && dot > 1 - SlerpEpsilon) {\r\n        result.copyFromFloats(0, 0, 0, 1);\r\n        return result;\r\n    }\r\n    if (Number.isFinite(dot) && dot < -1 + SlerpEpsilon) {\r\n        const axis = GetAnyPerpendicularVector(a);\r\n        result.copyFromFloats(axis.x, axis.y, axis.z, 0);\r\n        return result;\r\n    }\r\n\r\n    const axis = Vector3.Cross(a, b).normalize();\r\n    const axisScale = Math.sqrt(0.5 - 0.5 * dot);\r\n    result.copyFromFloats(axis.x * axisScale, axis.y * axisScale, axis.z * axisScale, Math.sqrt(0.5 + 0.5 * dot));\r\n    return result;\r\n}\r\n\r\n/**\r\n * Spherical linear interpolation between two 2D vectors.\r\n * NaN and infinity values are propagated through the arithmetic.\r\n * @param a the first vector\r\n * @param b the second vector\r\n * @param c the (unclamped) interpolation coefficient\r\n * @returns the interpolated 2D vector\r\n */\r\nexport function GetVector2Slerp(a: DeepImmutable<Vector2>, b: DeepImmutable<Vector2>, c: number): Vector2 {\r\n    const lengthA = Math.sqrt(a.x * a.x + a.y * a.y);\r\n    const lengthB = Math.sqrt(b.x * b.x + b.y * b.y);\r\n    // If either vector is (close to) zero length the rotation is undefined; fall back to a linear interpolation.\r\n    if (lengthA < SlerpEpsilon || lengthB < SlerpEpsilon) {\r\n        return new Vector2((1 - c) * a.x + c * b.x, (1 - c) * a.y + c * b.y);\r\n    }\r\n    const aHatX = a.x / lengthA;\r\n    const aHatY = a.y / lengthA;\r\n    const bHatX = b.x / lengthB;\r\n    const bHatY = b.y / lengthB;\r\n    let theta = Math.acos(Clamp(aHatX * bHatX + aHatY * bHatY, -1, 1));\r\n    if (aHatX * bHatY - aHatY * bHatX < 0) {\r\n        theta = -theta;\r\n    }\r\n    const length = (1 - c) * lengthA + c * lengthB;\r\n    const cosCTheta = Math.cos(c * theta);\r\n    const sinCTheta = Math.sin(c * theta);\r\n    return new Vector2((aHatX * cosCTheta - aHatY * sinCTheta) * length, (aHatX * sinCTheta + aHatY * cosCTheta) * length);\r\n}\r\n\r\n/**\r\n * Spherical linear interpolation between two 3D vectors.\r\n * NaN and infinity values are propagated through the arithmetic.\r\n * @param a the first vector\r\n * @param b the second vector\r\n * @param c the (unclamped) interpolation coefficient\r\n * @returns the interpolated 3D vector\r\n */\r\nexport function GetVector3Slerp(a: DeepImmutable<Vector3>, b: DeepImmutable<Vector3>, c: number): Vector3 {\r\n    const lengthA = a.length();\r\n    const lengthB = b.length();\r\n    const lerp = () => new Vector3((1 - c) * a.x + c * b.x, (1 - c) * a.y + c * b.y, (1 - c) * a.z + c * b.z);\r\n    // If either vector is (close to) zero length the rotation is undefined; fall back to a linear interpolation.\r\n    if (lengthA < SlerpEpsilon || lengthB < SlerpEpsilon) {\r\n        return lerp();\r\n    }\r\n    const aHat = new Vector3(a.x / lengthA, a.y / lengthA, a.z / lengthA);\r\n    const bHat = new Vector3(b.x / lengthB, b.y / lengthB, b.z / lengthB);\r\n    const dot = Vector3Dot(aHat, bHat);\r\n    // Parallel vectors share a direction; a linear interpolation already produces the correct result.\r\n    if (dot > 1 - SlerpEpsilon) {\r\n        return lerp();\r\n    }\r\n    let rotationAxis: Vector3;\r\n    if (dot < -1 + SlerpEpsilon) {\r\n        // Anti-parallel vectors: any axis perpendicular to aHat is a valid rotation axis.\r\n        rotationAxis = GetAnyPerpendicularVector(aHat);\r\n    } else {\r\n        rotationAxis = Vector3.Cross(aHat, bHat).normalize();\r\n    }\r\n    const angle = c * Math.acos(Clamp(dot, -1, 1));\r\n    const rotation = Quaternion.RotationAxis(rotationAxis, angle);\r\n    const length = (1 - c) * lengthA + c * lengthB;\r\n    return aHat.applyRotationQuaternion(rotation).scaleInPlace(length);\r\n}\r\n\r\n/**\r\n * Creates a quaternion from the specified up and forward directions, as defined by the\r\n * up/forward quaternion operation. Both inputs are assumed to be unit length.\r\n * @param up the up direction\r\n * @param forward the forward direction\r\n * @returns the rotation quaternion\r\n */\r\nexport function GetQuaternionFromUpForward(up: DeepImmutable<Vector3>, forward: DeepImmutable<Vector3>): Quaternion {\r\n    const r = new Vector3(forward.x, forward.y, forward.z);\r\n    let s = Vector3.Cross(up, r);\r\n    if (s.lengthSquared() < SlerpEpsilon * SlerpEpsilon) {\r\n        // up and forward are colinear; pick any unit vector perpendicular to forward.\r\n        s = GetAnyPerpendicularVector(r);\r\n    } else {\r\n        s.normalize();\r\n    }\r\n    const t = Vector3.Cross(r, s);\r\n    // Build the rotation matrix with columns s, t and r (Babylon matrices are column-major) and convert it.\r\n    const matrix = Matrix.FromValues(s.x, s.y, s.z, 0, t.x, t.y, t.z, 0, r.x, r.y, r.z, 0, 0, 0, 0, 1);\r\n    return Quaternion.FromRotationMatrix(matrix);\r\n}\r\n\r\n/**\r\n * The rotation orders accepted by the Euler-angle quaternion operation\r\n * (and {@link GetQuaternionFromEulerAngles}). The default order is `yxz`.\r\n */\r\nexport const QuaternionEulerAngleOrders = [\"xyz\", \"xzy\", \"yxz\", \"yzx\", \"zxy\", \"zyx\"] as const;\r\n\r\n/**\r\n * Builds a rotation quaternion from three Tait–Bryan intrinsic Euler angles applied in the\r\n * specified order.\r\n *\r\n * Babylon only exposes the `yxz` order natively (via `Quaternion.RotationYawPitchRoll`), so the\r\n * result is composed from the individual per-axis rotations to support every order. For an\r\n * intrinsic order `o1o2o3` the result is the Hamilton product `q(o1) * q(o2) * q(o3)`, where each\r\n * `q(axis)` is a rotation about that axis; this matches the corresponding reference intrinsic\r\n * Tait–Bryan rotation matrices. NaN and infinite angle inputs propagate into the result.\r\n * @param order the rotation order, one of {@link QuaternionEulerAngleOrders}; any other value uses the default `yxz`\r\n * @param x rotation around the X axis, in radians\r\n * @param y rotation around the Y axis, in radians\r\n * @param z rotation around the Z axis, in radians\r\n * @returns the composed rotation quaternion\r\n */\r\nexport function GetQuaternionFromEulerAngles(order: string, x: number, y: number, z: number): Quaternion {\r\n    const qx = Quaternion.RotationAxis(Vector3.RightReadOnly, x);\r\n    const qy = Quaternion.RotationAxis(Vector3.UpReadOnly, y);\r\n    const qz = Quaternion.RotationAxis(Vector3.LeftHandedForwardReadOnly, z);\r\n    // `a.multiplyInPlace(b)` computes the Hamilton product `a * b` in place and returns `a`.\r\n    switch (order) {\r\n        case \"xyz\":\r\n            return qx.multiplyInPlace(qy).multiplyInPlace(qz);\r\n        case \"xzy\":\r\n            return qx.multiplyInPlace(qz).multiplyInPlace(qy);\r\n        case \"yzx\":\r\n            return qy.multiplyInPlace(qz).multiplyInPlace(qx);\r\n        case \"zxy\":\r\n            return qz.multiplyInPlace(qx).multiplyInPlace(qy);\r\n        case \"zyx\":\r\n            return qz.multiplyInPlace(qy).multiplyInPlace(qx);\r\n        case \"yxz\":\r\n        default:\r\n            // Default order.\r\n            return qy.multiplyInPlace(qx).multiplyInPlace(qz);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport {\n    RichTypeVector3,\n    FlowGraphTypes,\n    RichTypeNumber,\n    RichTypeAny,\n    RichTypeVector2,\n    RichTypeMatrix,\n    getRichTypeByFlowGraphType,\n    RichTypeQuaternion,\n    RichTypeBoolean,\n} from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphBinaryOperationBlock } from \"../flowGraphBinaryOperationBlock\";\nimport { FlowGraphUnaryOperationBlock } from \"../flowGraphUnaryOperationBlock\";\nimport { FlowGraphTernaryOperationBlock } from \"../flowGraphTernaryOperationBlock\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { Quaternion, Vector2, Vector3, Vector4, type Matrix } from \"core/Maths/math.vector.pure\";\nimport { type FlowGraphMatrix2D, type FlowGraphMatrix3D } from \"core/FlowGraph/CustomTypes\";\nimport { type FlowGraphMatrix, type FlowGraphVector, _GetClassNameOf } from \"core/FlowGraph/utils\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type Nullable } from \"../../../../types\";\nimport {\n    GetAngleBetweenQuaternions,\n    GetQuaternionFromDirections,\n    GetQuaternionFromEulerAngles,\n    GetQuaternionFromUpForward,\n    GetVector2Slerp,\n    GetVector3Slerp,\n    QuaternionEulerAngleOrders,\n} from \"core/FlowGraph/flowGraphMath\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\nconst AxisCacheName = \"cachedOperationAxis\";\nconst AngleCacheName = \"cachedOperationAngle\";\nconst CacheExecIdName = \"cachedExecutionId\";\n\n/**\n * Vector length block.\n */\nexport class FlowGraphLengthBlock extends FlowGraphUnaryOperationBlock<FlowGraphVector, number> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeAny, RichTypeNumber, (a) => this._polymorphicLength(a), FlowGraphBlockNames.Length, config);\n    }\n\n    private _polymorphicLength(a: FlowGraphVector) {\n        const aClassName = _GetClassNameOf(a);\n        switch (aClassName) {\n            case FlowGraphTypes.Vector2:\n            case FlowGraphTypes.Vector3:\n            case FlowGraphTypes.Vector4:\n            case FlowGraphTypes.Quaternion:\n                return (a as Vector3).length();\n            default:\n                throw new Error(`Cannot compute length of value ${a}`);\n        }\n    }\n}\n\n/**\n * Configuration for normalized vector\n */\nexport interface IFlowGraphNormalizeBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * If true, the block will return NaN if the input vector has a length of 0.\n     * This is the expected behavior for glTF interactivity graphs.\n     */\n    nanOnZeroLength?: boolean;\n}\n\n/**\n * Vector normalize block.\n */\nexport class FlowGraphNormalizeBlock extends FlowGraphCachedOperationBlock<FlowGraphVector> {\n    /**\n     * The vector to normalize.\n     */\n    public readonly a: FlowGraphDataConnection<FlowGraphVector>;\n\n    constructor(config?: IFlowGraphNormalizeBlockConfiguration) {\n        super(RichTypeAny, config);\n        this.a = this.registerDataInput(\"a\", RichTypeAny);\n    }\n\n    public override _doOperation(context: FlowGraphContext): FlowGraphVector | undefined {\n        return this._polymorphicNormalize(this.a.getValue(context));\n    }\n\n    /**\n     * A vector that cannot be normalized reports a vector of the same type with every component set\n     * to zero, so the output stays type-consistent with the input instead of being left undefined.\n     * @param context the graph context\n     * @returns a zero vector matching the input's type\n     */\n    protected override _getInvalidOutputValue(context: FlowGraphContext): FlowGraphVector {\n        const a = this.a.getValue(context);\n        switch (_GetClassNameOf(a)) {\n            case FlowGraphTypes.Vector2:\n                return new Vector2(0, 0);\n            case FlowGraphTypes.Vector4:\n                return new Vector4(0, 0, 0, 0);\n            case FlowGraphTypes.Quaternion:\n                return new Quaternion(0, 0, 0, 0);\n            default:\n                return new Vector3(0, 0, 0);\n        }\n    }\n\n    private _polymorphicNormalize(a: FlowGraphVector): FlowGraphVector | undefined {\n        const aClassName = _GetClassNameOf(a);\n        switch (aClassName) {\n            case FlowGraphTypes.Vector2:\n            case FlowGraphTypes.Vector3:\n            case FlowGraphTypes.Vector4:\n            case FlowGraphTypes.Quaternion: {\n                // Normalization is only valid when the length is a positive finite number. For zero, NaN, or\n                // +Infinity length the operation is invalid: returning undefined makes the cached base report\n                // isValid = false and deliver a zero vector of the same type on `value`.\n                const length = (a as Vector3).length();\n                if (length === 0 || !Number.isFinite(length)) {\n                    if (this.config?.nanOnZeroLength) {\n                        // Legacy behavior preserved for consumers that opt into NaN output.\n                        const nanVector = a.normalizeToNew();\n                        nanVector.setAll(NaN);\n                        return nanVector;\n                    }\n                    return undefined;\n                }\n                return a.normalizeToNew();\n            }\n            default:\n                throw new Error(`Cannot normalize value ${a}`);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.Normalize;\n    }\n}\n\n/**\n * Dot product block.\n */\nexport class FlowGraphDotBlock extends FlowGraphBinaryOperationBlock<FlowGraphVector, FlowGraphVector, number> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeAny, RichTypeAny, RichTypeNumber, (a, b) => this._polymorphicDot(a, b), FlowGraphBlockNames.Dot, config);\n    }\n\n    private _polymorphicDot(a: FlowGraphVector, b: FlowGraphVector) {\n        const className = _GetClassNameOf(a);\n        switch (className) {\n            case FlowGraphTypes.Vector2:\n            case FlowGraphTypes.Vector3:\n            case FlowGraphTypes.Vector4:\n            case FlowGraphTypes.Quaternion:\n                // casting is needed because dot requires both to be the same type\n                return (a as Vector3).dot(b as Vector3);\n            default:\n                throw new Error(`Cannot get dot product of ${a} and ${b}`);\n        }\n    }\n}\n\n/**\n * Cross product block.\n */\nexport class FlowGraphCrossBlock extends FlowGraphBinaryOperationBlock<Vector3, Vector3, Vector3> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeVector3, RichTypeVector3, (a, b) => Vector3.Cross(a, b), FlowGraphBlockNames.Cross, config);\n    }\n}\n\n/**\n * 2D rotation block.\n */\nexport class FlowGraphRotate2DBlock extends FlowGraphBinaryOperationBlock<Vector2, number, Vector2> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector2, RichTypeNumber, RichTypeVector2, (a, b) => a.rotate(b), FlowGraphBlockNames.Rotate2D, config);\n    }\n}\n\n/**\n * 3D rotation block.\n */\nexport class FlowGraphRotate3DBlock extends FlowGraphBinaryOperationBlock<Vector3, Quaternion, Vector3> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeQuaternion, RichTypeVector3, (a, b) => a.applyRotationQuaternion(b), FlowGraphBlockNames.Rotate3D, config);\n    }\n}\n\nfunction TransformVector(a: FlowGraphVector, b: FlowGraphMatrix): FlowGraphVector {\n    const className = _GetClassNameOf(a);\n    switch (className) {\n        case FlowGraphTypes.Vector2:\n            return (b as FlowGraphMatrix2D).transformVector(a as Vector2);\n        case FlowGraphTypes.Vector3:\n            return (b as FlowGraphMatrix3D).transformVector(a as Vector3);\n        case FlowGraphTypes.Vector4:\n            a = a as Vector4;\n            // transform the vector 4 with the matrix here. Vector4.TransformCoordinates transforms a 3D coordinate, not Vector4.\n            // Babylon's Matrix stores its elements column-major (m[0..3] is the first column), and the incoming\n            // float4x4 values are column-major as well, so M * a reads down the columns: value[i] = sum_j M[i][j] * a[j]\n            // with M[i][j] = m[j * 4 + i].\n            return new Vector4(\n                a.x * b.m[0] + a.y * b.m[4] + a.z * b.m[8] + a.w * b.m[12],\n                a.x * b.m[1] + a.y * b.m[5] + a.z * b.m[9] + a.w * b.m[13],\n                a.x * b.m[2] + a.y * b.m[6] + a.z * b.m[10] + a.w * b.m[14],\n                a.x * b.m[3] + a.y * b.m[7] + a.z * b.m[11] + a.w * b.m[15]\n            );\n        default:\n            throw new Error(`Cannot transform value ${a}`);\n    }\n}\n\n/**\n * Configuration for the transform block.\n */\nexport interface IFlowGraphTransformBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The vector type\n     */\n    vectorType: FlowGraphTypes;\n}\n\n/**\n * Transform a vector3 by a matrix.\n */\nexport class FlowGraphTransformBlock extends FlowGraphBinaryOperationBlock<FlowGraphVector, FlowGraphMatrix, FlowGraphVector> {\n    constructor(config?: IFlowGraphTransformBlockConfiguration) {\n        const vectorType = config?.vectorType || FlowGraphTypes.Vector3;\n        const matrixType =\n            vectorType === FlowGraphTypes.Vector2 ? FlowGraphTypes.Matrix2D : vectorType === FlowGraphTypes.Vector3 ? FlowGraphTypes.Matrix3D : FlowGraphTypes.Matrix;\n        super(\n            getRichTypeByFlowGraphType(vectorType),\n            getRichTypeByFlowGraphType(matrixType),\n            getRichTypeByFlowGraphType(vectorType),\n            TransformVector,\n            FlowGraphBlockNames.TransformVector,\n            config\n        );\n    }\n}\n\n/**\n * Transform a vector3 by a matrix.\n */\nexport class FlowGraphTransformCoordinatesBlock extends FlowGraphBinaryOperationBlock<Vector3, Matrix, Vector3> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeMatrix, RichTypeVector3, (a, b) => Vector3.TransformCoordinates(a, b), FlowGraphBlockNames.TransformCoordinates, config);\n    }\n}\n\n/**\n * Conjugate the quaternion.\n */\nexport class FlowGraphConjugateBlock extends FlowGraphUnaryOperationBlock<Quaternion, Quaternion> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeQuaternion, RichTypeQuaternion, (a) => a.conjugate(), FlowGraphBlockNames.Conjugate, config);\n    }\n}\n\n/**\n * Get the angle between two quaternions.\n */\nexport class FlowGraphAngleBetweenBlock extends FlowGraphBinaryOperationBlock<Quaternion, Quaternion, number> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeQuaternion, RichTypeQuaternion, RichTypeNumber, (a, b) => GetAngleBetweenQuaternions(a, b), FlowGraphBlockNames.AngleBetween, config);\n    }\n}\n\n/**\n * Get the quaternion from an axis and an angle.\n */\nexport class FlowGraphQuaternionFromAxisAngleBlock extends FlowGraphBinaryOperationBlock<Vector3, number, Quaternion> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeNumber, RichTypeQuaternion, (a, b) => Quaternion.RotationAxis(a, b), FlowGraphBlockNames.QuaternionFromAxisAngle, config);\n    }\n}\n\n/**\n * Get the axis and angle from a quaternion.\n */\nexport class FlowGraphAxisAngleFromQuaternionBlock extends FlowGraphBlock {\n    /**\n     * The input of this block.\n     */\n    public readonly a: FlowGraphDataConnection<Quaternion>;\n\n    /**\n     * The output axis of rotation.\n     */\n    public readonly axis: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * The output angle of rotation.\n     */\n    public readonly angle: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: Whether the value is valid.\n     */\n    public readonly isValid: FlowGraphDataConnection<boolean>;\n\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n\n        this.a = this.registerDataInput(\"a\", RichTypeQuaternion);\n\n        this.axis = this.registerDataOutput(\"axis\", RichTypeVector3);\n        this.angle = this.registerDataOutput(\"angle\", RichTypeNumber);\n\n        this.isValid = this.registerDataOutput(\"isValid\", RichTypeBoolean);\n    }\n\n    /** @override */\n    public override _updateOutputs(context: FlowGraphContext) {\n        const cachedExecutionId = context._getExecutionVariable(this, CacheExecIdName, -1);\n        const cachedAxis = context._getExecutionVariable<Nullable<Vector3>>(this, AxisCacheName, null);\n        const cachedAngle = context._getExecutionVariable<Nullable<number>>(this, AngleCacheName, null);\n        if (cachedAxis !== undefined && cachedAxis !== null && cachedAngle !== undefined && cachedAngle !== null && cachedExecutionId === context.executionId) {\n            this.axis.setValue(cachedAxis, context);\n            this.angle.setValue(cachedAngle, context);\n        } else {\n            try {\n                const { axis, angle } = this.a.getValue(context).toAxisAngle();\n                context._setExecutionVariable(this, AxisCacheName, axis);\n                context._setExecutionVariable(this, AngleCacheName, angle);\n                context._setExecutionVariable(this, CacheExecIdName, context.executionId);\n                this.axis.setValue(axis, context);\n                this.angle.setValue(angle, context);\n                this.isValid.setValue(true, context);\n            } catch (e) {\n                this.isValid.setValue(false, context);\n            }\n        }\n    }\n\n    /**\n     * Gets the class name\n     * @override\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AxisAngleFromQuaternion;\n    }\n}\n\n/**\n * Get the quaternion from two direction vectors.\n */\nexport class FlowGraphQuaternionFromDirectionsBlock extends FlowGraphBinaryOperationBlock<Vector3, Vector3, Quaternion> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeVector3, RichTypeQuaternion, (a, b) => GetQuaternionFromDirections(a, b), FlowGraphBlockNames.QuaternionFromDirections, config);\n    }\n}\n\n/**\n * Get a rotation quaternion from the specified up and forward directions.\n */\nexport class FlowGraphQuaternionFromUpForwardBlock extends FlowGraphBinaryOperationBlock<Vector3, Vector3, Quaternion> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeVector3, RichTypeQuaternion, (up, forward) => GetQuaternionFromUpForward(up, forward), FlowGraphBlockNames.QuaternionFromUpForward, config);\n    }\n}\n\n/**\n * Spherical linear interpolation between two vectors.\n * Supports float2 and float3 vectors; the interpolation coefficient is a number.\n */\nexport class FlowGraphVectorSlerpBlock extends FlowGraphTernaryOperationBlock<FlowGraphVector, FlowGraphVector, number, FlowGraphVector> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeAny, RichTypeAny, RichTypeNumber, RichTypeAny, (a, b, c) => this._polymorphicSlerp(a, b, c), FlowGraphBlockNames.VectorSlerp, config);\n    }\n\n    private _polymorphicSlerp(a: FlowGraphVector, b: FlowGraphVector, c: number): FlowGraphVector {\n        const className = _GetClassNameOf(a);\n        switch (className) {\n            case FlowGraphTypes.Vector2:\n                return GetVector2Slerp(a as Vector2, b as Vector2, c);\n            case FlowGraphTypes.Vector3:\n                return GetVector3Slerp(a as Vector3, b as Vector3, c);\n            default:\n                throw new Error(`Cannot slerp value ${a}`);\n        }\n    }\n}\n\n/**\n * The configuration of the FlowGraphQuaternionFromAnglesBlock.\n */\nexport interface IFlowGraphQuaternionFromAnglesBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The intrinsic Tait–Bryan rotation order, one of `xyz`, `xzy`, `yxz`, `yzx`, `zxy`, `zyx`.\n     * Any other (or missing) value falls back to the spec default `yxz`.\n     */\n    order?: string;\n}\n\n/**\n * Creates a rotation quaternion from three Tait–Bryan intrinsic Euler angles applied in a\n * configurable order.\n *\n * Inputs `a`, `b`, `c` are the rotations (in radians) around the X, Y and Z axes respectively.\n * The `order` configuration selects the intrinsic rotation order; NaN and infinite inputs\n * propagate into the resulting quaternion components.\n */\nexport class FlowGraphQuaternionFromAnglesBlock extends FlowGraphTernaryOperationBlock<number, number, number, Quaternion> {\n    /**\n     * The validated intrinsic rotation order used to compose the quaternion.\n     */\n    private readonly _order: string;\n\n    constructor(config?: IFlowGraphQuaternionFromAnglesBlockConfiguration) {\n        super(\n            RichTypeNumber,\n            RichTypeNumber,\n            RichTypeNumber,\n            RichTypeQuaternion,\n            (a, b, c) => GetQuaternionFromEulerAngles(this._order, a, b, c),\n            FlowGraphBlockNames.QuaternionFromAngles,\n            config\n        );\n        const order = config?.order;\n        // A missing, non-string or unrecognized order falls back to the default `yxz`.\n        this._order = typeof order === \"string\" && (QuaternionEulerAngleOrders as readonly string[]).indexOf(order) !== -1 ? order : \"yxz\";\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphVectorMathBlocks.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphVectorMathBlocks(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.Length, FlowGraphLengthBlock);\n    RegisterClass(FlowGraphBlockNames.Normalize, FlowGraphNormalizeBlock);\n    RegisterClass(FlowGraphBlockNames.Dot, FlowGraphDotBlock);\n    RegisterClass(FlowGraphBlockNames.Cross, FlowGraphCrossBlock);\n    RegisterClass(FlowGraphBlockNames.Rotate2D, FlowGraphRotate2DBlock);\n    RegisterClass(FlowGraphBlockNames.Rotate3D, FlowGraphRotate3DBlock);\n    RegisterClass(FlowGraphBlockNames.TransformVector, FlowGraphTransformBlock);\n    RegisterClass(FlowGraphBlockNames.TransformCoordinates, FlowGraphTransformCoordinatesBlock);\n    RegisterClass(FlowGraphBlockNames.Conjugate, FlowGraphConjugateBlock);\n    RegisterClass(FlowGraphBlockNames.AngleBetween, FlowGraphAngleBetweenBlock);\n    RegisterClass(FlowGraphBlockNames.QuaternionFromAxisAngle, FlowGraphQuaternionFromAxisAngleBlock);\n    RegisterClass(FlowGraphBlockNames.AxisAngleFromQuaternion, FlowGraphAxisAngleFromQuaternionBlock);\n    RegisterClass(FlowGraphBlockNames.QuaternionFromDirections, FlowGraphQuaternionFromDirectionsBlock);\n    RegisterClass(FlowGraphBlockNames.QuaternionFromUpForward, FlowGraphQuaternionFromUpForwardBlock);\n    RegisterClass(FlowGraphBlockNames.QuaternionFromAngles, FlowGraphQuaternionFromAnglesBlock);\n    RegisterClass(FlowGraphBlockNames.VectorSlerp, FlowGraphVectorSlerpBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphAssetType } from \"core/FlowGraph/flowGraphAssetsContext\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { FlowGraphPathConverterComponent } from \"core/FlowGraph/flowGraphPathConverterComponent\";\nimport { RichTypeAny } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type IObjectAccessor } from \"core/FlowGraph/typeDefinitions\";\nimport { type IPathToObjectConverter } from \"core/ObjectModel/objectModelInterfaces\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type Animation } from \"core/Animations/animation.pure\";\nimport { type EasingFunction } from \"core/Animations/easing\";\nimport { Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\nimport { Color3, Color4 } from \"core/Maths/math.color.pure\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the JSON pointer parser block.\n */\nexport interface IFlowGraphJsonPointerParserBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The JSON pointer to parse.\n     */\n    jsonPointer: string;\n    /**\n     * The path converter to use to convert the path to an object accessor.\n     */\n    pathConverter: IPathToObjectConverter<IObjectAccessor>;\n\n    /**\n     * Whether to output the value of the property.\n     */\n    outputValue?: boolean;\n}\n\n/**\n * This block will take a JSON pointer and parse it to get the value from the JSON object.\n * The output is an object and a property name.\n * Optionally, the block can also output the value of the property. This is configurable.\n */\nexport class FlowGraphJsonPointerParserBlock<P extends any, O extends FlowGraphAssetType> extends FlowGraphCachedOperationBlock<P> {\n    /**\n     * Output connection: The object that contains the property.\n     */\n    public readonly object: FlowGraphDataConnection<O>;\n\n    /**\n     * Output connection: The property name.\n     */\n    public readonly propertyName: FlowGraphDataConnection<string>;\n\n    /**\n     * Output connection: A function that can be used to update the value of the property.\n     */\n    public readonly setterFunction: FlowGraphDataConnection<(target: O, propertyName: string, value: P, context: FlowGraphContext) => void>;\n\n    /**\n     * Output connection: A function that can be used to get the value of the property.\n     */\n    public readonly getterFunction: FlowGraphDataConnection<(target: O, propertyName: string, context: FlowGraphContext) => P | undefined>;\n\n    /**\n     * Output connection: A function that can be used to get the interpolation animation property info.\n     */\n    public readonly generateAnimationsFunction: FlowGraphDataConnection<() => (keys: any[], fps: number, easingFunction?: EasingFunction) => Animation[]>;\n\n    /**\n     * The component with the templated inputs for the provided path.\n     */\n    public readonly templateComponent: FlowGraphPathConverterComponent;\n\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config: IFlowGraphJsonPointerParserBlockConfiguration\n    ) {\n        super(RichTypeAny, config);\n        this.object = this.registerDataOutput(\"object\", RichTypeAny);\n        this.propertyName = this.registerDataOutput(\"propertyName\", RichTypeAny);\n        this.setterFunction = this.registerDataOutput(\"setFunction\", RichTypeAny, this._setPropertyValue.bind(this));\n        this.getterFunction = this.registerDataOutput(\"getFunction\", RichTypeAny, this._getPropertyValue.bind(this));\n        this.generateAnimationsFunction = this.registerDataOutput(\"generateAnimationsFunction\", RichTypeAny, this._getInterpolationAnimationPropertyInfo.bind(this));\n        this.templateComponent = new FlowGraphPathConverterComponent(config.jsonPointer, this);\n    }\n\n    public override _doOperation(context: FlowGraphContext): P {\n        const accessorContainer = this.templateComponent.getAccessor(this.config.pathConverter, context);\n        // Pass the context as the accessor payload so context-aware object-model accessors, such as\n        // one validating a delay handle against the runtime active-delay set, can resolve.\n        const value = accessorContainer.info.get(accessorContainer.object, undefined, context) as P;\n        const object = accessorContainer.info.getTarget?.(accessorContainer.object);\n        const propertyName = accessorContainer.info.getPropertyName?.[0](accessorContainer.object);\n        if (!object) {\n            throw new Error(\"Object is undefined\");\n        } else {\n            this.object.setValue(object, context);\n            if (propertyName) {\n                this.propertyName.setValue(propertyName, context);\n            }\n        }\n        return value;\n    }\n\n    private _setPropertyValue(_target: O, _propertyName: string, value: P, context: FlowGraphContext): void {\n        const accessorContainer = this.templateComponent.getAccessor(this.config.pathConverter, context);\n        const type = accessorContainer.info.type;\n        if (type.startsWith(\"Color\")) {\n            value = ToColor(value as Vector4, type) as unknown as P;\n        }\n        // Unwrap FlowGraphInteger to plain number for numeric setters\n        if (typeof (value as any)?.value === \"number\" && (value as any)?.getClassName?.() === \"FlowGraphInteger\") {\n            value = (value as any).value as unknown as P;\n        }\n        accessorContainer.info.set?.(value, accessorContainer.object);\n    }\n\n    private _getPropertyValue(_target: O, _propertyName: string, context: FlowGraphContext): P | undefined {\n        const accessorContainer = this.templateComponent.getAccessor(this.config.pathConverter, context);\n        const type = accessorContainer.info.type;\n        // Pass the context as the accessor payload (see _doOperation) so context-aware accessors\n        // can resolve.\n        const value = accessorContainer.info.get(accessorContainer.object, undefined, context);\n        if (type.startsWith(\"Color\")) {\n            return FromColor(value as Color3 | Color4) as unknown as P;\n        }\n        return value as P | undefined;\n    }\n\n    private _getInterpolationAnimationPropertyInfo(\n        _target: O,\n        _propertyName: string,\n        context: FlowGraphContext\n    ): (keys: any[], fps: number, animationType: number, easingFunction?: EasingFunction) => Animation[] {\n        const accessorContainer = this.templateComponent.getAccessor(this.config.pathConverter, context);\n        return (keys: any[], fps: number, animationType: number, easingFunction?: EasingFunction) => {\n            const animations: Animation[] = [];\n            // make sure keys are of the right type (in case of float3 color/vector)\n            const type = accessorContainer.info.type;\n            if (type.startsWith(\"Color\")) {\n                keys = keys.map((key) => {\n                    return {\n                        frame: key.frame,\n                        value: ToColor(key.value, type),\n                    };\n                });\n            }\n            accessorContainer.info.interpolation?.forEach((info, index) => {\n                const name = accessorContainer.info.getPropertyName?.[index](accessorContainer.object) || \"Animation-interpolation-\" + index;\n                // generate the keys based on interpolation info\n                let newKeys: any[] = keys;\n                if (animationType !== info.type) {\n                    // convert the keys to the right type\n                    newKeys = keys.map((key) => {\n                        return {\n                            frame: key.frame,\n                            value: info.getValue(undefined, key.value.asArray ? key.value.asArray() : [key.value], 0, 1),\n                        };\n                    });\n                }\n                const animationData = info.buildAnimations(accessorContainer.object, name, 60, newKeys);\n                for (const animation of animationData) {\n                    if (easingFunction) {\n                        animation.babylonAnimation.setEasingFunction(easingFunction);\n                    }\n                    animations.push(animation.babylonAnimation);\n                }\n            });\n\n            return animations;\n        };\n    }\n\n    /**\n     * Gets the class name of this block\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.JsonPointerParser;\n    }\n}\n\nfunction ToColor(value: any, expectedValue: string) {\n    if (value.getClassName().startsWith(\"Color\")) {\n        return value as unknown as Color3 | Color4;\n    }\n    if (expectedValue === \"Color3\") {\n        return new Color3(value.x, value.y, value.z);\n    } else if (expectedValue === \"Color4\") {\n        return new Color4(value.x, value.y, value.z, value.w);\n    }\n    return value;\n}\n\nfunction FromColor(value: Color3 | Color4): Vector3 | Vector4 {\n    if (value instanceof Color3) {\n        return new Vector3(value.r, value.g, value.b);\n    } else if (value instanceof Color4) {\n        return new Vector4(value.r, value.g, value.b, value.a);\n    }\n    throw new Error(\"Invalid color type\");\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphJsonPointerParserBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphJsonPointerParserBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.JsonPointerParser, FlowGraphJsonPointerParserBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { FlowGraphUnaryOperationBlock } from \"../flowGraphUnaryOperationBlock\";\nimport { RichTypeBoolean, RichTypeFlowGraphInteger, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * A block that converts a boolean to a float.\n */\nexport class FlowGraphBooleanToFloat extends FlowGraphUnaryOperationBlock<boolean, number> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeBoolean, RichTypeNumber, (a) => +a, FlowGraphBlockNames.BooleanToFloat, config);\n    }\n}\n\n/**\n * A block that converts a boolean to an integer\n */\nexport class FlowGraphBooleanToInt extends FlowGraphUnaryOperationBlock<boolean, FlowGraphInteger> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeBoolean, RichTypeFlowGraphInteger, (a) => FlowGraphInteger.FromValue(+a), FlowGraphBlockNames.BooleanToInt, config);\n    }\n}\n\n/**\n * A block that converts a float to a boolean.\n */\nexport class FlowGraphFloatToBoolean extends FlowGraphUnaryOperationBlock<number, boolean> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeNumber, RichTypeBoolean, (a) => !!a, FlowGraphBlockNames.FloatToBoolean, config);\n    }\n}\n\n/**\n * A block that converts an integer to a boolean.\n */\nexport class FlowGraphIntToBoolean extends FlowGraphUnaryOperationBlock<FlowGraphInteger, boolean> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeFlowGraphInteger, RichTypeBoolean, (a) => !!a.value, FlowGraphBlockNames.IntToBoolean, config);\n    }\n}\n\n/**\n * A block that converts an integer to a float.\n */\nexport class FlowGraphIntToFloat extends FlowGraphUnaryOperationBlock<FlowGraphInteger, number> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeFlowGraphInteger, RichTypeNumber, (a) => a.value, FlowGraphBlockNames.IntToFloat, config);\n    }\n}\n\n/**\n * Configuration for the float to int block.\n */\nexport interface IFlowGraphFloatToIntConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * The rounding mode to use.\n     * if not defined, it will use the FlowGraphInteger default rounding ( a | 0 )\n     */\n    roundingMode?: \"floor\" | \"ceil\" | \"round\";\n}\n/**\n * A block that converts a float to an integer.\n */\nexport class FlowGraphFloatToInt extends FlowGraphUnaryOperationBlock<number, FlowGraphInteger> {\n    constructor(config?: IFlowGraphFloatToIntConfiguration) {\n        super(\n            RichTypeNumber,\n            RichTypeFlowGraphInteger,\n            (a) => {\n                const roundingMode = config?.roundingMode;\n                switch (roundingMode) {\n                    case \"floor\":\n                        return FlowGraphInteger.FromValue(Math.floor(a));\n                    case \"ceil\":\n                        return FlowGraphInteger.FromValue(Math.ceil(a));\n                    case \"round\":\n                        return FlowGraphInteger.FromValue(Math.round(a));\n                    default:\n                        return FlowGraphInteger.FromValue(a);\n                }\n            },\n            FlowGraphBlockNames.FloatToInt,\n            config\n        );\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphTypeToTypeBlocks.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphTypeToTypeBlocks(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.BooleanToFloat, FlowGraphBooleanToFloat);\n    RegisterClass(FlowGraphBlockNames.BooleanToInt, FlowGraphBooleanToInt);\n    RegisterClass(FlowGraphBlockNames.FloatToBoolean, FlowGraphFloatToBoolean);\n    RegisterClass(FlowGraphBlockNames.IntToBoolean, FlowGraphIntToBoolean);\n    RegisterClass(FlowGraphBlockNames.IntToFloat, FlowGraphIntToFloat);\n    RegisterClass(FlowGraphBlockNames.FloatToInt, FlowGraphFloatToInt);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphBlock, type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * A block that outputs elements from the context\n */\nexport class FlowGraphContextBlock extends FlowGraphBlock {\n    /**\n     * Output connection: The user variables from the context\n     */\n    public readonly userVariables: FlowGraphDataConnection<FlowGraphContext[\"userVariables\"]>;\n\n    /**\n     * Output connection: The execution id from the context\n     */\n    public readonly executionId: FlowGraphDataConnection<FlowGraphContext[\"executionId\"]>;\n\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n\n        this.userVariables = this.registerDataOutput(\"userVariables\", RichTypeAny);\n        this.executionId = this.registerDataOutput(\"executionId\", RichTypeNumber);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext): void {\n        this.userVariables.setValue(context.userVariables, context);\n        this.executionId.setValue(context.executionId, context);\n    }\n\n    public override serialize(serializationObject?: any): void {\n        super.serialize(serializationObject);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.Context;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphContextBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphContextBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.Context, FlowGraphContextBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { type FlowGraphNumber, getNumericValue } from \"core/FlowGraph/utils\";\nimport { type Nullable } from \"core/types\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for array-index reference resolution.\n */\nexport interface IFlowGraphArrayIndexBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Optional host collection name required when the index input is an opaque reference.\n     */\n    referenceCollection?: string;\n}\n\n/**\n * This simple Util block takes an array as input and selects a single element from it.\n */\nexport class FlowGraphArrayIndexBlock<T = any> extends FlowGraphBlock {\n    /**\n     * Input connection: The array to select from.\n     */\n    public readonly array: FlowGraphDataConnection<T[]>;\n\n    /**\n     * Input connection: The index to select.\n     */\n    public readonly index: FlowGraphDataConnection<FlowGraphNumber>;\n\n    /**\n     * Output connection: The selected element.\n     */\n    public readonly value: FlowGraphDataConnection<Nullable<T>>;\n\n    /**\n     * Construct a FlowGraphArrayIndexBlock.\n     * @param config construction parameters\n     */\n    constructor(public override config: IFlowGraphArrayIndexBlockConfiguration) {\n        super(config);\n\n        this.array = this.registerDataInput(\"array\", RichTypeAny);\n        this.index = this.registerDataInput(\"index\", RichTypeAny, new FlowGraphInteger(-1));\n        this.value = this.registerDataOutput(\"value\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const array = this.array.getValue(context);\n        const rawIndex = this.index.getValue(context);\n        // An undefined or unconnected input short-circuits to a null output rather than crashing\n        // `getNumericValue` on a missing `.value` property.\n        if (rawIndex === undefined || rawIndex === null) {\n            this.value.setValue(null, context);\n            return;\n        }\n        // A string index is an opaque reference whose format the host environment owns, so ask it\n        // which element the reference denotes.\n        let index: number;\n        if (typeof rawIndex === \"string\") {\n            const decoded = context.decodeIndexReference(rawIndex, this.config.referenceCollection);\n            if (decoded === undefined) {\n                this.value.setValue(null, context);\n                return;\n            }\n            index = decoded;\n        } else {\n            index = getNumericValue(rawIndex);\n        }\n        if (array && index >= 0 && index < array.length) {\n            this.value.setValue(array[index], context);\n        } else {\n            this.value.setValue(null, context);\n        }\n    }\n\n    /**\n     * Serializes this block\n     * @param serializationObject the object to serialize to\n     */\n    public override serialize(serializationObject?: any): void {\n        super.serialize(serializationObject);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.ArrayIndex;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphArrayIndexBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphArrayIndexBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.ArrayIndex, FlowGraphArrayIndexBlock);\n}\n","import { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection\";\nimport { RichTypeAny } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\n\nexport type CodeExecutionFunction = (value: any, context: FlowGraphContext) => any;\n\n/**\n * This block takes in a function that is defined OUTSIDE of the flow graph and executes it.\n * The function can be a normal function or an async function.\n * The function's arguments will be the value of the input connection as the first variable, and the flow graph context as the second variable.\n */\nexport class FlowGraphCodeExecutionBlock extends FlowGraphBlock {\n    /**\n     * Input connection: The function to execute.\n     */\n    public readonly executionFunction: FlowGraphDataConnection<CodeExecutionFunction>;\n\n    /**\n     * Input connection: The value to pass to the function.\n     */\n    public readonly value: FlowGraphDataConnection<any>;\n\n    /**\n     * Output connection: The result of the function.\n     */\n    public readonly result: FlowGraphDataConnection<any>;\n\n    /**\n     * Construct a FlowGraphCodeExecutionBlock.\n     * @param config construction parameters\n     */\n    constructor(public override config: IFlowGraphBlockConfiguration) {\n        super(config);\n\n        this.executionFunction = this.registerDataInput(\"function\", RichTypeAny);\n        this.value = this.registerDataInput(\"value\", RichTypeAny);\n        this.result = this.registerDataOutput(\"result\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const func = this.executionFunction.getValue(context);\n        const value = this.value.getValue(context);\n        if (func) {\n            this.result.setValue(func(value, context), context);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.CodeExecution;\n    }\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeFlowGraphInteger } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * This block takes an object as input and an array and returns the index of the object in the array.\n */\nexport class FlowGraphIndexOfBlock<T = any> extends FlowGraphBlock {\n    /**\n     * Input connection: The object to find in the array.\n     */\n    public readonly object: FlowGraphDataConnection<T>;\n\n    /**\n     * Input connection: The array to search in.\n     */\n    public readonly array: FlowGraphDataConnection<T[]>;\n\n    /**\n     * Output connection: The index of the object in the array.\n     * -1 if not found!\n     */\n    public readonly index: FlowGraphDataConnection<FlowGraphInteger>;\n\n    /**\n     * Construct a FlowGraphIndexOfBlock.\n     * @param config construction parameters\n     */\n    constructor(public override config: IFlowGraphBlockConfiguration) {\n        super(config);\n\n        this.object = this.registerDataInput(\"object\", RichTypeAny);\n        this.array = this.registerDataInput(\"array\", RichTypeAny);\n        this.index = this.registerDataOutput(\"index\", RichTypeFlowGraphInteger, new FlowGraphInteger(-1));\n    }\n\n    /**\n     * @internal\n     */\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const object = this.object.getValue(context);\n        const array = this.array.getValue(context);\n        if (array) {\n            this.index.setValue(new FlowGraphInteger(array.indexOf(object)), context);\n        }\n    }\n\n    /**\n     * Serializes this block\n     * @param serializationObject the object to serialize to\n     */\n    public override serialize(serializationObject?: any): void {\n        super.serialize(serializationObject);\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.IndexOf;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphIndexOfBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphIndexOfBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.IndexOf, FlowGraphIndexOfBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * A flow graph block that takes a function name, an object and an optional context as inputs and calls the function on the object.\n */\nexport class FlowGraphFunctionReferenceBlock extends FlowGraphBlock {\n    /**\n     * Input: The function name.\n     */\n    public readonly functionName: FlowGraphDataConnection<string>;\n    /**\n     * Input: The object to get the function from.\n     * This can be a constructed class or a collection of stand-alone functions.\n     */\n    public readonly object: FlowGraphDataConnection<any>;\n    /**\n     * Input: The context to call the function with.\n     * This is optional. If not provided, the function will be bound to null.\n     */\n    public readonly context: FlowGraphDataConnection<any>;\n    /**\n     * Output: The function referenced by functionName from the object, bound to the context.\n     */\n    public readonly output: FlowGraphDataConnection<Function>;\n\n    constructor(\n        /**\n         * the configuration of the block\n         */\n        config?: IFlowGraphBlockConfiguration\n    ) {\n        super(config);\n        this.functionName = this.registerDataInput(\"functionName\", RichTypeString);\n        this.object = this.registerDataInput(\"object\", RichTypeAny);\n        this.context = this.registerDataInput(\"context\", RichTypeAny, null);\n        this.output = this.registerDataOutput(\"output\", RichTypeAny);\n    }\n\n    public override _updateOutputs(context: FlowGraphContext) {\n        const functionName = this.functionName.getValue(context);\n        const object = this.object.getValue(context);\n        const contextValue = this.context.getValue(context);\n        if (object && functionName) {\n            const func = object[functionName];\n            if (func && typeof func === \"function\") {\n                this.output.setValue(func.bind(contextValue), context);\n            }\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.FunctionReference;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphFunctionReferenceBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphFunctionReferenceBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.FunctionReference, FlowGraphFunctionReferenceBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A data block that reads the linear velocity of a physics body.\n */\nexport class FlowGraphGetLinearVelocityBlock extends FlowGraphCachedOperationBlock<Vector3> {\n    /**\n     * Input connection: The physics body to read the velocity from.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Constructs a new FlowGraphGetLinearVelocityBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _doOperation(context: FlowGraphContext): Vector3 | undefined {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            return undefined;\n        }\n        let result = context._getExecutionVariable<Vector3 | null>(this, \"_cachedVelocity\", null);\n        if (!result) {\n            result = new Vector3();\n            context._setExecutionVariable(this, \"_cachedVelocity\", result);\n        }\n        physicsBody.getLinearVelocityToRef(result);\n        return result;\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsGetLinearVelocity;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphGetLinearVelocityBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphGetLinearVelocityBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsGetLinearVelocity, FlowGraphGetLinearVelocityBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A data block that reads the angular velocity of a physics body.\n */\nexport class FlowGraphGetAngularVelocityBlock extends FlowGraphCachedOperationBlock<Vector3> {\n    /**\n     * Input connection: The physics body to read the angular velocity from.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Constructs a new FlowGraphGetAngularVelocityBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _doOperation(context: FlowGraphContext): Vector3 | undefined {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            return undefined;\n        }\n        let result = context._getExecutionVariable<Vector3 | null>(this, \"_cachedVelocity\", null);\n        if (!result) {\n            result = new Vector3();\n            context._setExecutionVariable(this, \"_cachedVelocity\", result);\n        }\n        physicsBody.getAngularVelocityToRef(result);\n        return result;\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsGetAngularVelocity;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphGetAngularVelocityBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphGetAngularVelocityBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsGetAngularVelocity, FlowGraphGetAngularVelocityBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber, RichTypeVector3 } from \"../../../flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type PhysicsBody } from \"../../../../Physics/v2/physicsBody\";\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A data block that reads the mass properties of a physics body.\n * Outputs the mass, center of mass (local space), and principal inertia.\n */\nexport class FlowGraphGetPhysicsMassPropertiesBlock extends FlowGraphBlock {\n    /**\n     * Input connection: The physics body to read mass properties from.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Output connection: The total mass in kilograms.\n     */\n    public readonly mass: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: The center of mass in local space.\n     */\n    public readonly centerOfMass: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Output connection: The principal moments of inertia.\n     */\n    public readonly inertia: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Constructs a new FlowGraphGetPhysicsMassPropertiesBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.mass = this.registerDataOutput(\"mass\", RichTypeNumber);\n        this.centerOfMass = this.registerDataOutput(\"centerOfMass\", RichTypeVector3);\n        this.inertia = this.registerDataOutput(\"inertia\", RichTypeVector3);\n    }\n\n    /**\n     * @internal\n     */\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            return;\n        }\n        const props = physicsBody.getMassProperties();\n        if (props.mass !== undefined) {\n            this.mass.setValue(props.mass, context);\n        }\n        if (props.centerOfMass) {\n            this.centerOfMass.setValue(props.centerOfMass, context);\n        }\n        if (props.inertia) {\n            this.inertia.setValue(props.inertia, context);\n        }\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsGetMassProperties;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphGetPhysicsMassPropertiesBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphGetPhysicsMassPropertiesBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsGetMassProperties, FlowGraphGetPhysicsMassPropertiesBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { type AbstractSound } from \"../../../../AudioV2/abstractAudio/abstractSound\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A data block that reads the current volume of an Audio V2 sound.\n */\nexport class FlowGraphGetSoundVolumeBlock extends FlowGraphCachedOperationBlock<number> {\n    /**\n     * Input connection: The sound to read the volume from.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Constructs a new FlowGraphGetSoundVolumeBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeNumber, config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _doOperation(context: FlowGraphContext): number | undefined {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            return undefined;\n        }\n        return soundValue.volume;\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioGetVolume;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphGetSoundVolumeBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphGetSoundVolumeBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioGetVolume, FlowGraphGetSoundVolumeBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeBoolean } from \"../../../flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { FlowGraphCachedOperationBlock } from \"../flowGraphCachedOperationBlock\";\nimport { type AbstractSound } from \"../../../../AudioV2/abstractAudio/abstractSound\";\nimport { SoundState } from \"../../../../AudioV2/soundState\";\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\n\n/**\n * @experimental\n * A data block that checks whether an Audio V2 sound is currently playing.\n */\nexport class FlowGraphIsSoundPlayingBlock extends FlowGraphCachedOperationBlock<boolean> {\n    /**\n     * Input connection: The sound to check.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Constructs a new FlowGraphIsSoundPlayingBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeBoolean, config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _doOperation(context: FlowGraphContext): boolean | undefined {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            return undefined;\n        }\n        return soundValue.state === SoundState.Started || soundValue.state === SoundState.Starting;\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioIsSoundPlaying;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphIsSoundPlayingBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphIsSoundPlayingBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioIsSoundPlaying, FlowGraphIsSoundPlayingBlock);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh.pure\";\r\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../../../Events/pointerEvents\";\r\nimport { type IPointerEvent } from \"../../../Events/deviceInputEvents\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { _IsDescendantOf } from \"../../utils\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { RichTypeAny, RichTypeNumber, RichTypeVector3 } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Configuration for the mesh pick event block.\r\n */\r\nexport interface IFlowGraphMeshPickEventBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * Should this mesh block propagation of the event.\r\n     */\r\n    stopPropagation?: boolean;\r\n\r\n    /**\r\n     * The mesh to listen to. Can also be set by the asset input.\r\n     */\r\n    targetMesh?: AbstractMesh;\r\n    /**\r\n     * Whether unavailable selection vectors use NaN components.\r\n     */\r\n    useNaNDefaults?: boolean;\r\n    /**\r\n     * Initial pointer/controller id.\r\n     */\r\n    pointerIdDefault?: number;\r\n}\r\n/**\r\n * A block that activates when a mesh is picked.\r\n */\r\nexport class FlowGraphMeshPickEventBlock extends FlowGraphEventBlock {\r\n    /**\r\n     * Input connection: The mesh to listen to.\r\n     */\r\n    public readonly asset: FlowGraphDataConnection<AbstractMesh>;\r\n\r\n    /**\r\n     * Output connection: The picked point.\r\n     */\r\n    public readonly pickedPoint: FlowGraphDataConnection<Vector3>;\r\n\r\n    /**\r\n     * Output connection: The picked origin.\r\n     */\r\n    public readonly pickOrigin: FlowGraphDataConnection<Vector3>;\r\n\r\n    /**\r\n     * Output connection: The pointer id.\r\n     */\r\n    public readonly pointerId: FlowGraphDataConnection<number>;\r\n\r\n    /**\r\n     * Output connection: The picked mesh. Possibly NOT the same as the asset (could be a descendant).\r\n     */\r\n    public readonly pickedMesh: FlowGraphDataConnection<AbstractMesh>;\r\n\r\n    /**\r\n     * Input connection: The type of the pointer event.\r\n     */\r\n    public readonly pointerType: FlowGraphDataConnection<PointerEventTypes>;\r\n\r\n    /**\r\n     * the type of the event this block reacts to\r\n     */\r\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.MeshPick;\r\n\r\n    public constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config?: IFlowGraphMeshPickEventBlockConfiguration\r\n    ) {\r\n        super(config);\r\n        const vectorDefault = config?.useNaNDefaults ? new Vector3(NaN, NaN, NaN) : undefined;\r\n        this.asset = this.registerDataInput(\"asset\", RichTypeAny, config?.targetMesh);\r\n        this.pickedPoint = this.registerDataOutput(\"pickedPoint\", RichTypeVector3, vectorDefault);\r\n        this.pickOrigin = this.registerDataOutput(\"pickOrigin\", RichTypeVector3, vectorDefault);\r\n        this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber, config?.pointerIdDefault);\r\n        this.pickedMesh = this.registerDataOutput(\"pickedMesh\", RichTypeAny);\r\n        this.pointerType = this.registerDataInput(\"pointerType\", RichTypeAny, PointerEventTypes.POINTERPICK);\r\n    }\r\n\r\n    public _getReferencedMesh(context: FlowGraphContext): AbstractMesh {\r\n        return this.asset.getValue(context);\r\n    }\r\n\r\n    public override _executeEvent(context: FlowGraphContext, pickedInfo: PointerInfo): boolean {\r\n        // get the pointer type\r\n        const pointerType = this.pointerType.getValue(context);\r\n        if (pointerType !== pickedInfo.type) {\r\n            // returning true here to continue the propagation of the pointer event to the rest of the blocks\r\n            return true;\r\n        }\r\n        const mesh = this._getReferencedMesh(context);\r\n        const pickedMesh = pickedInfo.pickInfo?.pickedMesh;\r\n        // When no target mesh is configured, fire for any picked mesh.\r\n        // When a target is configured, require an exact match or descendant match.\r\n        const meshMatches = !mesh ? !!pickedMesh : !!(pickedMesh && (pickedMesh === mesh || _IsDescendantOf(pickedMesh, mesh)));\r\n        if (meshMatches && pickedMesh) {\r\n            this.pointerId.setValue((pickedInfo.event as IPointerEvent).pointerId, context);\r\n            this.pickOrigin.setValue(pickedInfo.pickInfo!.ray?.origin!, context);\r\n            this.pickedPoint.setValue(pickedInfo.pickInfo!.pickedPoint!, context);\r\n            this.pickedMesh.setValue(pickedMesh, context);\r\n            this._execute(context);\r\n            // stop the propagation if the configuration says so\r\n            return !this.config?.stopPropagation;\r\n        } else {\r\n            // reset the outputs\r\n            this.pointerId.resetToDefaultValue(context);\r\n            this.pickOrigin.resetToDefaultValue(context);\r\n            this.pickedPoint.resetToDefaultValue(context);\r\n            this.pickedMesh.resetToDefaultValue(context);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\r\n        // no-op\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\r\n        // no-op\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.MeshPickEvent;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphMeshPickEventBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphMeshPickEventBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.MeshPickEvent, FlowGraphMeshPickEventBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\r\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/** Event source key used to build this block's event reference. */\r\nconst EventKey = \"sceneReady\";\r\n\r\n/**\r\n * Block that triggers when a scene is ready.\r\n */\r\nexport class FlowGraphSceneReadyEventBlock extends FlowGraphEventBlock {\r\n    public override initPriority: number = -1;\r\n\r\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.SceneReady;\r\n    /** @returns the shared scene-ready event key */\r\n    public override get eventKey(): string {\r\n        return EventKey;\r\n    }\r\n\r\n    /**\r\n     * Output: the opaque reference identifying this event source.\r\n     * All instances of this block share the same reference, so comparing the `event` output of two\r\n     * of them for equality succeeds. The reference format is owned by the host environment.\r\n     */\r\n    public readonly eventRef: FlowGraphDataConnection<string>;\r\n\r\n    constructor() {\r\n        super();\r\n        this.eventRef = this.registerDataOutput(\"event\", RichTypeString);\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        this.eventRef.setValue(context.getEventReference(EventKey), context);\r\n    }\r\n\r\n    public override _executeEvent(context: FlowGraphContext, _payload: any): boolean {\r\n        this.eventRef.setValue(context.getEventReference(EventKey), context);\r\n        this._execute(context);\r\n        return true;\r\n    }\r\n    public override _preparePendingTasks(context: FlowGraphContext): void {\r\n        // no-op\r\n    }\r\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n        // no-op\r\n    }\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName() {\r\n        return FlowGraphBlockNames.SceneReadyEvent;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphSceneReadyEventBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphSceneReadyEventBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.SceneReadyEvent, FlowGraphSceneReadyEventBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Observer } from \"../../../Misc/observable.pure\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { type RichType, getRichTypeByFlowGraphType, RichTypeString } from \"../../flowGraphRichTypes.pure\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { FlowGraphCoordinator } from \"core/FlowGraph/flowGraphCoordinator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { defaultValueSerializationFunction } from \"../../serialization\";\r\n/**\r\n * Parameters used to create a FlowGraphReceiveCustomEventBlock.\r\n */\r\nexport interface IFlowGraphReceiveCustomEventBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The id of the event to receive.\r\n     * This event id is unique to the environment (not the context).\r\n     */\r\n    eventId: string;\r\n    /**\r\n     * The names of the data outputs for that event. Should be in the same order as the event data in\r\n     * SendCustomEvent\r\n     */\r\n    eventData: { [key: string]: { type: RichType<any>; value?: any } };\r\n}\r\n\r\n/**\r\n * Returns the event-dispatch key for an authored custom event id.\r\n * @param eventId authored custom event id\r\n * @returns namespaced event key\r\n */\r\nexport function GetFlowGraphCustomEventKey(eventId: string): string {\r\n    return `custom:${encodeURIComponent(eventId)}`;\r\n}\r\n\r\n/**\r\n * A block that receives a custom event.\r\n * It saves the event data in the data outputs, based on the provided eventData in the configuration. For example, if the event data is\r\n * `{ x: { type: RichTypeNumber }, y: { type: RichTypeNumber } }`, the block will have two data outputs: x and y.\r\n */\r\nexport class FlowGraphReceiveCustomEventBlock extends FlowGraphEventBlock {\r\n    public override initPriority: number = 1;\r\n\r\n    /**\r\n     * Output: the opaque reference identifying the received event source.\r\n     * Receivers configured with the same event id share the same reference, so comparing their\r\n     * `event` outputs for equality succeeds. The reference format is owned by the host environment.\r\n     */\r\n    public readonly eventRef: FlowGraphDataConnection<string>;\r\n\r\n    /** @returns the configured custom event id */\r\n    public override get eventKey(): string {\r\n        return GetFlowGraphCustomEventKey(this.config.eventId);\r\n    }\r\n\r\n    constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphReceiveCustomEventBlockConfiguration\r\n    ) {\r\n        super(config);\r\n        // use event data to register data outputs\r\n        for (const key of Object.keys(this.config.eventData ?? {})) {\r\n            const entry = this.config.eventData[key];\r\n            // Handle deserialized config where type may be a string typeName, a plain object\r\n            // with a typeName property (from old JSON serialization), or a proper RichType instance.\r\n            const typeKey = typeof entry.type === \"string\" ? entry.type : entry.type?.typeName;\r\n            const richType = typeof entry.type?.serialize === \"function\" ? entry.type : getRichTypeByFlowGraphType(typeKey);\r\n            entry.type = richType;\r\n            // Pass default value from event data schema so outputs have the correct initial value\r\n            this.registerDataOutput(key, richType, (entry as any).value);\r\n        }\r\n        // Reserved `event` output exposing the event reference. Guard against a\r\n        // (pathological) custom event value socket literally named \"event\".\r\n        this.eventRef =\r\n            this.config.eventData && Object.prototype.hasOwnProperty.call(this.config.eventData, \"event\")\r\n                ? this.getDataOutput(\"event\")!\r\n                : this.registerDataOutput(\"event\", RichTypeString);\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        this.eventRef.setValue(context.getEventReference(this.eventKey), context);\r\n    }\r\n\r\n    public override _preparePendingTasks(context: FlowGraphContext): void {\r\n        const observable = context.configuration.coordinator.getCustomEventObservable(this.config.eventId);\r\n        // check if we are not exceeding the max number of events\r\n        if (observable && observable.hasObservers() && observable.observers.length > FlowGraphCoordinator.MaxEventsPerType) {\r\n            this._reportError(context, `FlowGraphReceiveCustomEventBlock: Too many observers for event ${this.config.eventId}. Max is ${FlowGraphCoordinator.MaxEventsPerType}.`);\r\n            return;\r\n        }\r\n\r\n        const eventObserver = observable.add((eventData: { [key: string]: any }, eventState) => {\r\n            // Make this dispatch's EventState reachable by event/stopPropagation\r\n            // for the duration of the synchronous receiver flow.\r\n            context.configuration.coordinator._beginEventDispatch(this.eventKey, eventState);\r\n            try {\r\n                // Drive the outputs from the configured payload schema rather than from the incoming\r\n                // keys, so a key the sender omitted (or sent as undefined) resets to its configured\r\n                // default instead of retaining the value from a previous dispatch.\r\n                for (const key of Object.keys(this.config.eventData ?? {})) {\r\n                    const output = this.getDataOutput(key);\r\n                    if (!output) {\r\n                        continue;\r\n                    }\r\n                    const incoming = eventData?.[key];\r\n                    output.setValue(incoming === undefined ? this._getEventDataDefault(key) : incoming, context);\r\n                }\r\n                // Expose the event reference before activating downstream flow.\r\n                this.eventRef.setValue(context.getEventReference(this.eventKey), context);\r\n                this._execute(context);\r\n            } finally {\r\n                context.configuration.coordinator._endEventDispatch();\r\n            }\r\n        });\r\n        context._setExecutionVariable(this, \"_eventObserver\", eventObserver);\r\n    }\r\n\r\n    /**\r\n     * The value an output falls back to when the sender provides no value for it: the default\r\n     * declared by the payload schema, or the socket type's default when the schema declares none.\r\n     * @param key the payload key\r\n     * @returns the default value for that key\r\n     */\r\n    private _getEventDataDefault(key: string): any {\r\n        const entry =\r\n            this.config.eventData && Object.prototype.hasOwnProperty.call(this.config.eventData, key)\r\n                ? (this.config.eventData[key] as { type: RichType<any>; value?: any })\r\n                : undefined;\r\n        return entry?.value !== undefined ? entry.value : entry?.type?.defaultValue;\r\n    }\r\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n        const observable = context.configuration.coordinator.getCustomEventObservable(this.config.eventId);\r\n        if (observable) {\r\n            const eventObserver = context._getExecutionVariable<Nullable<Observer<any[]>>>(this, \"_eventObserver\", null);\r\n            observable.remove(eventObserver);\r\n        } else {\r\n            Logger.Warn(`FlowGraphReceiveCustomEventBlock: Missing observable for event ${this.config.eventId}`);\r\n        }\r\n    }\r\n\r\n    public override _executeEvent(_context: FlowGraphContext, _payload: any): boolean {\r\n        return true;\r\n    }\r\n\r\n    public override serialize(serializationObject: any = {}) {\r\n        super.serialize(serializationObject);\r\n        // Override the eventData in config to store typeName strings instead of RichType instances\r\n        const serializedEventData: any = Object.create(null);\r\n        for (const key of Object.keys(this.config.eventData ?? {})) {\r\n            const entry = this.config.eventData[key];\r\n            const serializedEntry: { type: string; value?: unknown } = { type: entry.type.typeName };\r\n            if (entry.value !== undefined) {\r\n                defaultValueSerializationFunction(\"value\", entry.value, serializedEntry);\r\n            }\r\n            Object.defineProperty(serializedEventData, key, {\r\n                configurable: true,\r\n                enumerable: true,\r\n                value: serializedEntry,\r\n                writable: true,\r\n            });\r\n        }\r\n        serializationObject.config.eventData = serializedEventData;\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.ReceiveCustomEvent;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphReceiveCustomEventBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphReceiveCustomEventBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.ReceiveCustomEvent, FlowGraphReceiveCustomEventBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\r\nimport { RichTypeBoolean, RichTypeString } from \"../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Stops the propagation of an in-flight custom event.\r\n *\r\n * When activated it asks the coordinator to skip the remaining handler nodes of\r\n * the currently-dispatching event referenced by the `event` input, then activates\r\n * its `out` flow. If the `event` input is not a valid, currently-dispatching event\r\n * reference, activating this block only fires `out` with no other effect.\r\n */\r\nexport class FlowGraphStopEventPropagationBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    /**\r\n     * Input: the event reference (produced by an event operation's `event` output)\r\n     * whose propagation should be stopped.\r\n     */\r\n    public readonly event: FlowGraphDataConnection<string>;\r\n\r\n    /**\r\n     * Input: whether to also stop remaining immediate handlers. See\r\n     * `FlowGraphCoordinator.stopEventPropagation` for how this maps onto the\r\n     * Babylon single-Observable dispatch model.\r\n     */\r\n    public readonly stopImmediate: FlowGraphDataConnection<boolean>;\r\n\r\n    public constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(config);\r\n        this.event = this.registerDataInput(\"event\", RichTypeString);\r\n        this.stopImmediate = this.registerDataInput(\"stopImmediate\", RichTypeBoolean, false);\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext): void {\r\n        const event = this.event.getValue(context);\r\n        const stopImmediate = this.stopImmediate.getValue(context);\r\n        context.configuration.coordinator.stopEventPropagation(event, stopImmediate);\r\n        this.out._activateSignal(context);\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.StopEventPropagation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphStopEventPropagationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphStopEventPropagationBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.StopEventPropagation, FlowGraphStopEventPropagationBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type RichType, getRichTypeByFlowGraphType } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../flowGraphExecutionBlockWithOutSignal\";\r\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { defaultValueSerializationFunction } from \"../../serialization\";\r\n\r\n/**\r\n * Parameters used to create a FlowGraphSendCustomEventBlock.\r\n */\r\nexport interface IFlowGraphSendCustomEventBlockConfiguration extends IFlowGraphBlockConfiguration {\r\n    /**\r\n     * The id of the event to send.\r\n     * Note - in the glTF specs this is an index to the event array (i.e. - a number)\r\n     */\r\n    eventId: string;\r\n    /**\r\n     * The names of the data inputs for that event.\r\n     */\r\n    eventData: { [key: string]: { type: RichType<any>; value?: any } };\r\n}\r\n/**\r\n * A block that sends a custom event.\r\n * To receive this event you need to use the ReceiveCustomEvent block.\r\n * This block has no output, but does have inputs based on the eventData from the configuration.\r\n * @see FlowGraphReceiveCustomEventBlock\r\n */\r\nexport class FlowGraphSendCustomEventBlock extends FlowGraphExecutionBlockWithOutSignal {\r\n    public constructor(\r\n        /**\r\n         * the configuration of the block\r\n         */\r\n        public override config: IFlowGraphSendCustomEventBlockConfiguration\r\n    ) {\r\n        super(config);\r\n        for (const key of Object.keys(this.config.eventData ?? {})) {\r\n            const entry = this.config.eventData[key];\r\n            // Handle deserialized config where type may be a string typeName, a plain object\r\n            // with a typeName property (from old JSON serialization), or a proper RichType instance.\r\n            const typeKey = typeof entry.type === \"string\" ? entry.type : entry.type?.typeName;\r\n            const richType = typeof entry.type?.serialize === \"function\" ? entry.type : getRichTypeByFlowGraphType(typeKey);\r\n            entry.type = richType;\r\n            this.registerDataInput(key, richType, entry.value);\r\n        }\r\n    }\r\n\r\n    public _execute(context: FlowGraphContext): void {\r\n        const eventId = this.config.eventId;\r\n        // eventData is a map with the key being the data input's name, and value being the data input's value\r\n        const eventData: any = Object.create(null);\r\n        for (const port of this.dataInputs) {\r\n            Object.defineProperty(eventData, port.name, {\r\n                configurable: true,\r\n                enumerable: true,\r\n                value: port.getValue(context),\r\n                writable: true,\r\n            });\r\n        }\r\n\r\n        context.configuration.coordinator.notifyCustomEvent(eventId, eventData);\r\n\r\n        this.out._activateSignal(context);\r\n    }\r\n\r\n    public override serialize(serializationObject: any = {}) {\r\n        super.serialize(serializationObject);\r\n        // Override the eventData in config to store typeName strings instead of RichType instances\r\n        const serializedEventData: any = Object.create(null);\r\n        for (const key of Object.keys(this.config.eventData ?? {})) {\r\n            const entry = this.config.eventData[key];\r\n            const serializedEntry: { type: string; value?: unknown } = { type: entry.type.typeName };\r\n            if (entry.value !== undefined) {\r\n                defaultValueSerializationFunction(\"value\", entry.value, serializedEntry);\r\n            }\r\n            Object.defineProperty(serializedEventData, key, {\r\n                configurable: true,\r\n                enumerable: true,\r\n                value: serializedEntry,\r\n                writable: true,\r\n            });\r\n        }\r\n        serializationObject.config.eventData = serializedEventData;\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.SendCustomEvent;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphSendCustomEventBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphSendCustomEventBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.SendCustomEvent, FlowGraphSendCustomEventBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\r\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\r\nimport { RichTypeNumber, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\r\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\r\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\r\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/** Event source key used to build this block's event reference. */\r\nconst EventKey = \"sceneTick\";\r\n\r\n/**\r\n * Payload for the scene tick event.\r\n */\r\nexport interface IFlowGraphOnTickEventPayload {\r\n    /**\r\n     * the time in seconds since the scene started.\r\n     */\r\n    timeSinceStart: number;\r\n    /**\r\n     * the time in seconds since the last frame.\r\n     */\r\n    deltaTime: number;\r\n}\r\n\r\n/**\r\n * Block that triggers on scene tick (before each render).\r\n */\r\nexport class FlowGraphSceneTickEventBlock extends FlowGraphEventBlock {\r\n    /**\r\n     * the time in seconds since the scene started.\r\n     */\r\n    public readonly timeSinceStart: FlowGraphDataConnection<number>;\r\n\r\n    /**\r\n     * the time in seconds since the last frame.\r\n     */\r\n    public readonly deltaTime: FlowGraphDataConnection<number>;\r\n\r\n    /**\r\n     * Output: the opaque reference identifying this event source.\r\n     * All instances of this block share the same reference, so comparing the `event` output of two\r\n     * of them for equality succeeds. The reference format is owned by the host environment.\r\n     */\r\n    public readonly eventRef: FlowGraphDataConnection<string>;\r\n\r\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.SceneBeforeRender;\r\n    /** @returns the shared scene-tick event key */\r\n    public override get eventKey(): string {\r\n        return EventKey;\r\n    }\r\n\r\n    constructor() {\r\n        super();\r\n        this.timeSinceStart = this.registerDataOutput(\"timeSinceStart\", RichTypeNumber);\r\n        this.deltaTime = this.registerDataOutput(\"deltaTime\", RichTypeNumber);\r\n        this.eventRef = this.registerDataOutput(\"event\", RichTypeString);\r\n    }\r\n\r\n    public override _updateOutputs(context: FlowGraphContext): void {\r\n        this.eventRef.setValue(context.getEventReference(EventKey), context);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\r\n        // no-op\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _executeEvent(context: FlowGraphContext, payload: IFlowGraphOnTickEventPayload): boolean {\r\n        this.timeSinceStart.setValue(payload.timeSinceStart, context);\r\n        this.deltaTime.setValue(payload.deltaTime, context);\r\n        this.eventRef.setValue(context.getEventReference(EventKey), context);\r\n        this._execute(context);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _cancelPendingTasks(_context: FlowGraphContext) {\r\n        // no-op\r\n    }\r\n\r\n    /**\r\n     * @returns class name of the block.\r\n     */\r\n    public override getClassName(): string {\r\n        return FlowGraphBlockNames.SceneTickEvent;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphSceneTickEventBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphSceneTickEventBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(FlowGraphBlockNames.SceneTickEvent, FlowGraphSceneTickEventBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { FlowGraphEventBlock } from \"core/FlowGraph/flowGraphEventBlock\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { _IsDescendantOf } from \"core/FlowGraph/utils\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the pointer out event block.\n */\nexport interface IFlowGraphPointerOutEventBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Should this mesh block propagation of the event.\n     */\n    stopPropagation?: boolean;\n\n    /**\n     * The mesh to listen to. Can also be set by the asset input.\n     */\n    targetMesh?: AbstractMesh;\n}\n\n/**\n * Payload for the pointer out event.\n */\nexport interface IFlowGraphPointerOutEventPayload {\n    /**\n     * The pointer id.\n     */\n    pointerId: number;\n    /**\n     * The mesh that was picked.\n     */\n    mesh: AbstractMesh;\n\n    /**\n     * If populated, the hover event moved to this mesh from the `mesh` variable\n     */\n    over?: AbstractMesh;\n}\n\n/**\n * A pointe out event block.\n * This block can be used as an entry pointer to when a pointer is out of a specific target mesh.\n */\nexport class FlowGraphPointerOutEventBlock extends FlowGraphEventBlock {\n    /**\n     * Output connection: The pointer id.\n     */\n    public readonly pointerId: FlowGraphDataConnection<number>;\n\n    /**\n     * Input connection: The mesh to listen to.\n     */\n    public readonly targetMesh: FlowGraphDataConnection<AbstractMesh>;\n\n    /**\n     * Output connection: The mesh that the pointer is out of.\n     */\n    public readonly meshOutOfPointer: FlowGraphDataConnection<AbstractMesh>;\n\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.PointerOut;\n\n    public constructor(config?: IFlowGraphPointerOutEventBlockConfiguration) {\n        super(config);\n        this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\n        this.targetMesh = this.registerDataInput(\"targetMesh\", RichTypeAny, config?.targetMesh);\n        this.meshOutOfPointer = this.registerDataOutput(\"meshOutOfPointer\", RichTypeAny);\n    }\n\n    public override _executeEvent(context: FlowGraphContext, payload: IFlowGraphPointerOutEventPayload): boolean {\n        const mesh = this.targetMesh.getValue(context);\n        this.meshOutOfPointer.setValue(payload.mesh, context);\n        this.pointerId.setValue(payload.pointerId, context);\n        const skipEvent = payload.over && (payload.over === mesh || _IsDescendantOf(payload.over, mesh));\n        if (!skipEvent && (payload.mesh === mesh || _IsDescendantOf(payload.mesh, mesh))) {\n            this._execute(context);\n            return !this.config?.stopPropagation;\n        }\n        return true;\n    }\n    /** @internal */\n    public _getReferencedMesh(context: FlowGraphContext): AbstractMesh {\n        return this.targetMesh.getValue(context);\n    }\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n    public override getClassName() {\n        return FlowGraphBlockNames.PointerOutEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPointerOutEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPointerOutEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PointerOutEvent, FlowGraphPointerOutEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { FlowGraphEventBlock } from \"core/FlowGraph/flowGraphEventBlock\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { _IsDescendantOf } from \"core/FlowGraph/utils\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the pointer over event block.\n */\nexport interface IFlowGraphPointerOverEventBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Should this mesh block propagation of the event.\n     */\n    stopPropagation?: boolean;\n\n    /**\n     * The mesh to listen to. Can also be set by the asset input.\n     */\n    targetMesh?: AbstractMesh;\n}\n\n/**\n * Payload for the pointer over event.\n */\nexport interface IFlowGraphPointerOverEventPayload {\n    /**\n     * The pointer id.\n     */\n    pointerId: number;\n    /**\n     * The mesh that was picked.\n     */\n    mesh: AbstractMesh;\n\n    /**\n     * If populated, the hover event moved from this mesh to the `mesh` variable\n     */\n    out?: AbstractMesh;\n}\n\n/**\n * A pointer over event block.\n * This block can be used as an entry pointer to when a pointer is over a specific target mesh.\n */\nexport class FlowGraphPointerOverEventBlock extends FlowGraphEventBlock {\n    /**\n     * Output connection: The pointer id.\n     */\n    public readonly pointerId: FlowGraphDataConnection<number>;\n\n    /**\n     * Input connection: The mesh to listen to.\n     */\n    public readonly targetMesh: FlowGraphDataConnection<AbstractMesh>;\n\n    /**\n     * Output connection: The mesh that is under the pointer.\n     */\n    public readonly meshUnderPointer: FlowGraphDataConnection<AbstractMesh>;\n\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.PointerOver;\n\n    public constructor(config?: IFlowGraphPointerOverEventBlockConfiguration) {\n        super(config);\n        this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\n        this.targetMesh = this.registerDataInput(\"targetMesh\", RichTypeAny, config?.targetMesh);\n        this.meshUnderPointer = this.registerDataOutput(\"meshUnderPointer\", RichTypeAny);\n    }\n\n    public override _executeEvent(context: FlowGraphContext, payload: IFlowGraphPointerOverEventPayload): boolean {\n        const mesh = this.targetMesh.getValue(context);\n        this.meshUnderPointer.setValue(payload.mesh, context);\n        // skip if we moved from a mesh that is under the hierarchy of the target mesh\n        const skipEvent = payload.out && (payload.out === mesh || _IsDescendantOf(payload.out, mesh));\n        this.pointerId.setValue(payload.pointerId, context);\n        if (!skipEvent && (payload.mesh === mesh || _IsDescendantOf(payload.mesh, mesh))) {\n            this._execute(context);\n            return !this.config?.stopPropagation;\n        }\n        return true;\n    }\n    /** @internal */\n    public _getReferencedMesh(context: FlowGraphContext): AbstractMesh {\n        return this.targetMesh.getValue(context);\n    }\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n    public override getClassName() {\n        return FlowGraphBlockNames.PointerOverEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPointerOverEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPointerOverEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PointerOverEvent, FlowGraphPointerOverEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber, RichTypeVector3 } from \"../../flowGraphRichTypes.pure\";\nimport { type Vector3 } from \"../../../Maths/math.vector.pure\";\nimport { type PhysicsBody } from \"../../../Physics/v2/physicsBody\";\nimport { type IPhysicsCollisionEvent } from \"../../../Physics/v2/IPhysicsEnginePlugin\";\nimport { type Observer } from \"../../../Misc/observable.pure\";\nimport { type Nullable } from \"../../../types\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\n\n/**\n * Configuration for the physics collision event block.\n */\nexport interface IFlowGraphPhysicsCollisionEventBlockConfiguration extends IFlowGraphBlockConfiguration {}\n\n/**\n * @experimental\n * An event block that fires when a physics collision occurs on the specified body.\n * Subscribes to the body's collision observable and exposes collision details\n * (the other body, contact point, normal, impulse, and distance) as data outputs.\n */\nexport class FlowGraphPhysicsCollisionEventBlock extends FlowGraphEventBlock {\n    /**\n     * Input connection: The physics body to monitor for collisions.\n     */\n    public readonly body: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Output connection: The other physics body involved in the collision.\n     */\n    public readonly otherBody: FlowGraphDataConnection<PhysicsBody>;\n\n    /**\n     * Output connection: The world-space contact point of the collision.\n     */\n    public readonly point: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Output connection: The world-space collision normal direction.\n     */\n    public readonly normal: FlowGraphDataConnection<Vector3>;\n\n    /**\n     * Output connection: The impulse magnitude computed by the physics solver.\n     */\n    public readonly impulse: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: The penetration distance of the collision.\n     */\n    public readonly distance: FlowGraphDataConnection<number>;\n\n    /**\n     * Constructs a new FlowGraphPhysicsCollisionEventBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(\n        /**\n         * the configuration of the block\n         */\n        public override config?: IFlowGraphPhysicsCollisionEventBlockConfiguration\n    ) {\n        super(config);\n        this.body = this.registerDataInput(\"body\", RichTypeAny);\n        this.otherBody = this.registerDataOutput(\"otherBody\", RichTypeAny);\n        this.point = this.registerDataOutput(\"point\", RichTypeVector3);\n        this.normal = this.registerDataOutput(\"normal\", RichTypeVector3);\n        this.impulse = this.registerDataOutput(\"impulse\", RichTypeNumber);\n        this.distance = this.registerDataOutput(\"distance\", RichTypeNumber);\n    }\n\n    /**\n     * @internal\n     */\n    public override _preparePendingTasks(context: FlowGraphContext): void {\n        const physicsBody = this.body.getValue(context);\n        if (!physicsBody) {\n            this._reportError(context, \"No physics body provided for collision event\");\n            return;\n        }\n        // Enable collision callbacks on the body\n        physicsBody.setCollisionCallbackEnabled(true);\n        const observer = physicsBody.getCollisionObservable().add((event) => {\n            this._onCollision(context, event);\n        });\n        // Store observer and subscribed body per-context so multi-context usage is safe\n        // and cleanup can target the original body even if the input changes.\n        context._setExecutionVariable(this, \"_collisionObserver\", observer);\n        context._setExecutionVariable(this, \"_subscribedBody\", physicsBody);\n    }\n\n    private _onCollision(context: FlowGraphContext, event: IPhysicsCollisionEvent): void {\n        const physicsBody = this.body.getValue(context);\n        // Determine the \"other\" body from the collision pair\n        const other = event.collider === physicsBody ? event.collidedAgainst : event.collider;\n        this.otherBody.setValue(other, context);\n        if (event.point) {\n            this.point.setValue(event.point, context);\n        }\n        if (event.normal) {\n            this.normal.setValue(event.normal, context);\n        }\n        this.impulse.setValue(event.impulse, context);\n        this.distance.setValue(event.distance, context);\n        this._execute(context);\n    }\n\n    /**\n     * @internal\n     */\n    public override _executeEvent(_context: FlowGraphContext, _payload: any): boolean {\n        // This block manages its own observable subscription, so the\n        // central event coordinator does not dispatch to it.\n        return true;\n    }\n\n    /**\n     * @internal\n     */\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\n        const observer = context._getExecutionVariable<Nullable<Observer<IPhysicsCollisionEvent>>>(this, \"_collisionObserver\", null);\n        const subscribedBody = context._getExecutionVariable<Nullable<PhysicsBody>>(this, \"_subscribedBody\", null);\n        if (observer && subscribedBody) {\n            const observable = subscribedBody.getCollisionObservable();\n            observable.remove(observer);\n            // Disable collision callbacks if no other observers remain\n            if (!observable.hasObservers()) {\n                subscribedBody.setCollisionCallbackEnabled(false);\n            }\n        }\n        context._setExecutionVariable(this, \"_collisionObserver\", null);\n        context._setExecutionVariable(this, \"_subscribedBody\", null);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PhysicsCollisionEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPhysicsCollisionEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPhysicsCollisionEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PhysicsCollisionEvent, FlowGraphPhysicsCollisionEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { FlowGraphEventBlock } from \"../../flowGraphEventBlock\";\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration } from \"../../flowGraphBlock\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\nimport { RichTypeAny } from \"../../flowGraphRichTypes.pure\";\nimport { type AbstractSound } from \"../../../AudioV2/abstractAudio/abstractSound\";\nimport { type Observer } from \"../../../Misc/observable.pure\";\nimport { type Nullable } from \"../../../types\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\n\n/**\n * @experimental\n * An event block that fires when an Audio V2 sound stops or ends.\n * Subscribes to the sound's onEndedObservable, which fires when playback\n * stops for any reason (natural completion or a manual call to stop()).\n * Does not fire when a looping sound naturally restarts, but will still\n * fire if a looping sound is explicitly stopped.\n */\nexport class FlowGraphSoundEndedEventBlock extends FlowGraphEventBlock {\n    /**\n     * Input connection: The sound to monitor for when playback stops or ends.\n     */\n    public readonly sound: FlowGraphDataConnection<AbstractSound>;\n\n    /**\n     * Constructs a new FlowGraphSoundEndedEventBlock.\n     * @param config - optional configuration for the block\n     */\n    public constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.sound = this.registerDataInput(\"sound\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _preparePendingTasks(context: FlowGraphContext): void {\n        const soundValue = this.sound.getValue(context);\n        if (!soundValue) {\n            this._reportError(context, \"No sound provided for sound-ended event\");\n            return;\n        }\n        const observer = soundValue.onEndedObservable.add(() => {\n            this._execute(context);\n        });\n        // Store observer and subscribed sound per-context for safe multi-context usage\n        context._setExecutionVariable(this, \"_soundEndedObserver\", observer);\n        context._setExecutionVariable(this, \"_subscribedSound\", soundValue);\n    }\n\n    /**\n     * @internal\n     */\n    public override _executeEvent(_context: FlowGraphContext, _payload: any): boolean {\n        // This block manages its own observable subscription, so the\n        // central event coordinator does not dispatch to it.\n        return true;\n    }\n\n    /**\n     * @internal\n     */\n    public override _cancelPendingTasks(context: FlowGraphContext): void {\n        const observer = context._getExecutionVariable<Nullable<Observer<AbstractSound>>>(this, \"_soundEndedObserver\", null);\n        const subscribedSound = context._getExecutionVariable<Nullable<AbstractSound>>(this, \"_subscribedSound\", null);\n        if (observer && subscribedSound) {\n            subscribedSound.onEndedObservable.remove(observer);\n        }\n        context._setExecutionVariable(this, \"_soundEndedObserver\", null);\n        context._setExecutionVariable(this, \"_subscribedSound\", null);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.AudioSoundEndedEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphSoundEndedEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphSoundEndedEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.AudioSoundEndedEvent, FlowGraphSoundEndedEventBlock);\n}\n","import { FlowGraphEventBlock } from \"core/FlowGraph/flowGraphEventBlock\";\nimport { type KeyboardInfo } from \"core/Events/keyboardEvents\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection\";\nimport { RichTypeBoolean, RichTypeString } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { _IsMacPlatform } from \"core/FlowGraph/utils\";\n\n/**\n * Configuration for keyboard event blocks.\n */\nexport interface IFlowGraphKeyboardEventBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * When true, prevent the event from propagating to other listeners.\n     */\n    stopPropagation?: boolean;\n}\n\n/**\n * Shared base class for keyboard event blocks (KeyDown / KeyUp).\n *\n * Provides a `key` input filter, output data connections for the key code,\n * key string, modifier states, and a platform-aware `commandOrCtrl` flag.\n * Subclasses only need to set their event type and class name.\n */\nexport abstract class FlowGraphKeyboardEventBlock extends FlowGraphEventBlock {\n    /**\n     * Input connection: optional key code to filter on (e.g. \"KeyA\", \"Space\", \"ShiftLeft\").\n     * Uses `KeyboardEvent.code` values. Leave empty / disconnected to fire on any key event.\n     */\n    public readonly key: FlowGraphDataConnection<string>;\n\n    /**\n     * Output connection: the `KeyboardEvent.code` of the key.\n     */\n    public readonly keyCode: FlowGraphDataConnection<string>;\n\n    /**\n     * Output connection: the `KeyboardEvent.key` string (printable character or key name).\n     */\n    public readonly keyValue: FlowGraphDataConnection<string>;\n\n    /**\n     * Output connection: whether the Shift key was held.\n     */\n    public readonly shiftKey: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Output connection: whether the Ctrl key was held.\n     */\n    public readonly ctrlKey: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Output connection: whether the Alt key (Option on macOS) was held.\n     */\n    public readonly altKey: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Output connection: whether the Meta key (Windows / Cmd) was held.\n     */\n    public readonly metaKey: FlowGraphDataConnection<boolean>;\n\n    /**\n     * Output connection: platform-aware \"command or control\" modifier.\n     * True when Meta (Cmd) is held on macOS, or Ctrl is held on Windows/Linux.\n     */\n    public readonly commandOrCtrl: FlowGraphDataConnection<boolean>;\n\n    protected constructor(config?: IFlowGraphKeyboardEventBlockConfiguration) {\n        super(config);\n        this.key = this.registerDataInput(\"key\", RichTypeString);\n        this.keyCode = this.registerDataOutput(\"keyCode\", RichTypeString);\n        this.keyValue = this.registerDataOutput(\"keyValue\", RichTypeString);\n        this.shiftKey = this.registerDataOutput(\"shiftKey\", RichTypeBoolean);\n        this.ctrlKey = this.registerDataOutput(\"ctrlKey\", RichTypeBoolean);\n        this.altKey = this.registerDataOutput(\"altKey\", RichTypeBoolean);\n        this.metaKey = this.registerDataOutput(\"metaKey\", RichTypeBoolean);\n        this.commandOrCtrl = this.registerDataOutput(\"commandOrCtrl\", RichTypeBoolean);\n    }\n\n    /** @internal */\n    public override _executeEvent(context: FlowGraphContext, keyboardInfo: KeyboardInfo): boolean {\n        const evt = keyboardInfo.event;\n        const filterKey = this.key.getValue(context);\n\n        // If a key filter is set, only fire when it matches.\n        if (filterKey && filterKey !== evt.code) {\n            return true;\n        }\n\n        this.keyCode.setValue(evt.code, context);\n        this.keyValue.setValue(evt.key, context);\n        this.shiftKey.setValue(evt.shiftKey, context);\n        this.ctrlKey.setValue(evt.ctrlKey, context);\n        this.altKey.setValue(evt.altKey, context);\n        this.metaKey.setValue(evt.metaKey, context);\n        this.commandOrCtrl.setValue(_IsMacPlatform ? evt.metaKey : evt.ctrlKey, context);\n\n        this._execute(context);\n        return !(this.config as IFlowGraphKeyboardEventBlockConfiguration)?.stopPropagation;\n    }\n\n    /** @internal */\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /** @internal */\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type KeyboardInfo } from \"core/Events/keyboardEvents\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeBoolean } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { FlowGraphKeyboardEventBlock, type IFlowGraphKeyboardEventBlockConfiguration } from \"./flowGraphKeyboardEventBlock\";\n\n/**\n * Configuration for the key down event block.\n */\nexport interface IFlowGraphKeyDownEventBlockConfiguration extends IFlowGraphKeyboardEventBlockConfiguration {\n    /**\n     * When true, auto-repeat key-down events (the user holding a key) are\n     * ignored and only the initial press fires the block. Defaults to false.\n     */\n    ignoreRepeat?: boolean;\n}\n\n/**\n * A keyboard event block that fires when a key is pressed down.\n * Extends {@link FlowGraphKeyboardEventBlock} with an `isRepeat` output\n * and an `ignoreRepeat` configuration option.\n */\nexport class FlowGraphKeyDownEventBlock extends FlowGraphKeyboardEventBlock {\n    /**\n     * Output connection: whether this is an auto-repeat event (key held down).\n     */\n    public readonly isRepeat: FlowGraphDataConnection<boolean>;\n\n    /** @internal */\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.KeyDown;\n\n    /**\n     * Creates a new FlowGraphKeyDownEventBlock.\n     * @param config optional configuration\n     */\n    public constructor(config?: IFlowGraphKeyDownEventBlockConfiguration) {\n        super(config);\n        this.isRepeat = this.registerDataOutput(\"isRepeat\", RichTypeBoolean);\n    }\n\n    /** @internal */\n    public override _executeEvent(context: FlowGraphContext, keyboardInfo: KeyboardInfo): boolean {\n        const repeat = keyboardInfo.event.repeat ?? false;\n\n        // Skip auto-repeat events when configured to do so.\n        if (repeat && (this.config as IFlowGraphKeyDownEventBlockConfiguration)?.ignoreRepeat) {\n            return true;\n        }\n\n        // Set the repeat output before delegating to the base class,\n        // which calls _execute() and fires signals — downstream blocks\n        // must see the correct value during that execution chain.\n        this.isRepeat.setValue(repeat, context);\n\n        // Delegate to the base class for key filtering, output population, and execution.\n        return super._executeEvent(context, keyboardInfo);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.KeyDownEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Registers the FlowGraphKeyDownEventBlock class.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphKeyDownEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.KeyDownEvent, FlowGraphKeyDownEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { RegisterClass } from \"core/Misc/typeStore\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { FlowGraphKeyboardEventBlock, type IFlowGraphKeyboardEventBlockConfiguration } from \"./flowGraphKeyboardEventBlock\";\n\n/**\n * A keyboard event block that fires when a key is released.\n * Inherits all inputs/outputs from {@link FlowGraphKeyboardEventBlock}.\n */\nexport class FlowGraphKeyUpEventBlock extends FlowGraphKeyboardEventBlock {\n    /** @internal */\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.KeyUp;\n\n    /**\n     * Creates a new FlowGraphKeyUpEventBlock.\n     * @param config optional configuration\n     */\n    public constructor(config?: IFlowGraphKeyboardEventBlockConfiguration) {\n        super(config);\n    }\n\n    /**\n     * @returns class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.KeyUpEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Registers the FlowGraphKeyUpEventBlock class.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphKeyUpEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.KeyUpEvent, FlowGraphKeyUpEventBlock);\n}\n","/**\n * Enum of all block names.\n * Note - if you add a new block, you must add it here, and must add it in the block factory!\n */\nexport const enum FlowGraphBlockNames {\n    PlayAnimation = \"FlowGraphPlayAnimationBlock\",\n    StopAnimation = \"FlowGraphStopAnimationBlock\",\n    PauseAnimation = \"FlowGraphPauseAnimationBlock\",\n    ValueInterpolation = \"FlowGraphInterpolationBlock\",\n    SceneReadyEvent = \"FlowGraphSceneReadyEventBlock\",\n    SceneTickEvent = \"FlowGraphSceneTickEventBlock\",\n    SendCustomEvent = \"FlowGraphSendCustomEventBlock\",\n    ReceiveCustomEvent = \"FlowGraphReceiveCustomEventBlock\",\n    StopEventPropagation = \"FlowGraphStopEventPropagationBlock\",\n    MeshPickEvent = \"FlowGraphMeshPickEventBlock\",\n    PointerEvent = \"FlowGraphPointerEventBlock\",\n    PointerDownEvent = \"FlowGraphPointerDownEventBlock\",\n    PointerUpEvent = \"FlowGraphPointerUpEventBlock\",\n    PointerMoveEvent = \"FlowGraphPointerMoveEventBlock\",\n    PointerOverEvent = \"FlowGraphPointerOverEventBlock\",\n    PointerOutEvent = \"FlowGraphPointerOutEventBlock\",\n    KeyDownEvent = \"FlowGraphKeyDownEventBlock\",\n    KeyUpEvent = \"FlowGraphKeyUpEventBlock\",\n    IsKeyPressed = \"FlowGraphIsKeyPressedBlock\",\n    E = \"FlowGraphEBlock\",\n    PI = \"FlowGraphPIBlock\",\n    Tau = \"FlowGraphTauBlock\",\n    Inf = \"FlowGraphInfBlock\",\n    NaN = \"FlowGraphNaNBlock\",\n    Random = \"FlowGraphRandomBlock\",\n    Add = \"FlowGraphAddBlock\",\n    Subtract = \"FlowGraphSubtractBlock\",\n    Multiply = \"FlowGraphMultiplyBlock\",\n    Divide = \"FlowGraphDivideBlock\",\n    Abs = \"FlowGraphAbsBlock\",\n    Sign = \"FlowGraphSignBlock\",\n    Trunc = \"FlowGraphTruncBlock\",\n    Floor = \"FlowGraphFloorBlock\",\n    Ceil = \"FlowGraphCeilBlock\",\n    Round = \"FlowGraphRoundBlock\",\n    Fraction = \"FlowGraphFractBlock\",\n    Negation = \"FlowGraphNegationBlock\",\n    Modulo = \"FlowGraphModuloBlock\",\n    Min = \"FlowGraphMinBlock\",\n    Max = \"FlowGraphMaxBlock\",\n    Clamp = \"FlowGraphClampBlock\",\n    Saturate = \"FlowGraphSaturateBlock\",\n    MathInterpolation = \"FlowGraphMathInterpolationBlock\",\n    MathSlerp = \"FlowGraphMathSlerpBlock\",\n    SmoothStep = \"FlowGraphSmoothStepBlock\",\n    RGBToOkLCh = \"FlowGraphRGBToOkLChBlock\",\n    RGBFromOkLCh = \"FlowGraphRGBFromOkLChBlock\",\n    Equality = \"FlowGraphEqualityBlock\",\n    LessThan = \"FlowGraphLessThanBlock\",\n    LessThanOrEqual = \"FlowGraphLessThanOrEqualBlock\",\n    GreaterThan = \"FlowGraphGreaterThanBlock\",\n    GreaterThanOrEqual = \"FlowGraphGreaterThanOrEqualBlock\",\n    IsNaN = \"FlowGraphIsNaNBlock\",\n    IsInfinity = \"FlowGraphIsInfBlock\",\n    DegToRad = \"FlowGraphDegToRadBlock\",\n    RadToDeg = \"FlowGraphRadToDegBlock\",\n    Sin = \"FlowGraphSinBlock\",\n    Cos = \"FlowGraphCosBlock\",\n    Tan = \"FlowGraphTanBlock\",\n    Asin = \"FlowGraphASinBlock\",\n    Acos = \"FlowGraphACosBlock\",\n    Atan = \"FlowGraphATanBlock\",\n    Atan2 = \"FlowGraphATan2Block\",\n    Sinh = \"FlowGraphSinhBlock\",\n    Cosh = \"FlowGraphCoshBlock\",\n    Tanh = \"FlowGraphTanhBlock\",\n    Asinh = \"FlowGraphASinhBlock\",\n    Acosh = \"FlowGraphACoshBlock\",\n    Atanh = \"FlowGraphATanhBlock\",\n    Exponential = \"FlowGraphExponentialBlock\",\n    Log = \"FlowGraphLogBlock\",\n    Log2 = \"FlowGraphLog2Block\",\n    Log10 = \"FlowGraphLog10Block\",\n    SquareRoot = \"FlowGraphSquareRootBlock\",\n    CubeRoot = \"FlowGraphCubeRootBlock\",\n    Power = \"FlowGraphPowerBlock\",\n    Length = \"FlowGraphLengthBlock\",\n    Normalize = \"FlowGraphNormalizeBlock\",\n    Dot = \"FlowGraphDotBlock\",\n    Cross = \"FlowGraphCrossBlock\",\n    Rotate2D = \"FlowGraphRotate2DBlock\",\n    Rotate3D = \"FlowGraphRotate3DBlock\",\n    Transpose = \"FlowGraphTransposeBlock\",\n    Determinant = \"FlowGraphDeterminantBlock\",\n    InvertMatrix = \"FlowGraphInvertMatrixBlock\",\n    MatrixMultiplication = \"FlowGraphMatrixMultiplicationBlock\",\n    BitwiseAnd = \"FlowGraphBitwiseAndBlock\",\n    BitwiseOr = \"FlowGraphBitwiseOrBlock\",\n    BitwiseXor = \"FlowGraphBitwiseXorBlock\",\n    BitwiseNot = \"FlowGraphBitwiseNotBlock\",\n    BitwiseLeftShift = \"FlowGraphBitwiseLeftShiftBlock\",\n    BitwiseRightShift = \"FlowGraphBitwiseRightShiftBlock\",\n    LeadingZeros = \"FlowGraphLeadingZerosBlock\",\n    TrailingZeros = \"FlowGraphTrailingZerosBlock\",\n    OneBitsCounter = \"FlowGraphOneBitsCounterBlock\",\n    Branch = \"FlowGraphBranchBlock\",\n    SetDelay = \"FlowGraphSetDelayBlock\",\n    CancelDelay = \"FlowGraphCancelDelayBlock\",\n    CallCounter = \"FlowGraphCallCounterBlock\",\n    Debounce = \"FlowGraphDebounceBlock\",\n    Throttle = \"FlowGraphThrottleBlock\",\n    DoN = \"FlowGraphDoNBlock\",\n    FlipFlop = \"FlowGraphFlipFlopBlock\",\n    ForLoop = \"FlowGraphForLoopBlock\",\n    MultiGate = \"FlowGraphMultiGateBlock\",\n    Sequence = \"FlowGraphSequenceBlock\",\n    Switch = \"FlowGraphSwitchBlock\",\n    WaitAll = \"FlowGraphWaitAllBlock\",\n    WhileLoop = \"FlowGraphWhileLoopBlock\",\n    ConsoleLog = \"FlowGraphConsoleLogBlock\",\n    Conditional = \"FlowGraphConditionalBlock\",\n    Constant = \"FlowGraphConstantBlock\",\n    TransformCoordinatesSystem = \"FlowGraphTransformCoordinatesSystemBlock\",\n    GetAsset = \"FlowGraphGetAssetBlock\",\n    GetProperty = \"FlowGraphGetPropertyBlock\",\n    SetProperty = \"FlowGraphSetPropertyBlock\",\n    GetVariable = \"FlowGraphGetVariableBlock\",\n    SetVariable = \"FlowGraphSetVariableBlock\",\n    JsonPointerParser = \"FlowGraphJsonPointerParserBlock\",\n    CombineVector2 = \"FlowGraphCombineVector2Block\",\n    CombineVector3 = \"FlowGraphCombineVector3Block\",\n    CombineVector4 = \"FlowGraphCombineVector4Block\",\n    CombineMatrix = \"FlowGraphCombineMatrixBlock\",\n    CombineMatrix2D = \"FlowGraphCombineMatrix2DBlock\",\n    CombineMatrix3D = \"FlowGraphCombineMatrix3DBlock\",\n    ExtractVector2 = \"FlowGraphExtractVector2Block\",\n    ExtractVector3 = \"FlowGraphExtractVector3Block\",\n    ExtractVector4 = \"FlowGraphExtractVector4Block\",\n    ExtractMatrix = \"FlowGraphExtractMatrixBlock\",\n    ExtractMatrix2D = \"FlowGraphExtractMatrix2DBlock\",\n    ExtractMatrix3D = \"FlowGraphExtractMatrix3DBlock\",\n    TransformVector = \"FlowGraphTransformVectorBlock\",\n    TransformCoordinates = \"FlowGraphTransformCoordinatesBlock\",\n    Conjugate = \"FlowGraphConjugateBlock\",\n    AngleBetween = \"FlowGraphAngleBetweenBlock\",\n    QuaternionFromAxisAngle = \"FlowGraphQuaternionFromAxisAngleBlock\",\n    AxisAngleFromQuaternion = \"FlowGraphAxisAngleFromQuaternionBlock\",\n    QuaternionFromDirections = \"FlowGraphQuaternionFromDirectionsBlock\",\n    QuaternionFromUpForward = \"FlowGraphQuaternionFromUpForwardBlock\",\n    QuaternionFromAngles = \"FlowGraphQuaternionFromAnglesBlock\",\n    VectorSlerp = \"FlowGraphVectorSlerpBlock\",\n    MatrixDecompose = \"FlowGraphMatrixDecompose\",\n    MatrixCompose = \"FlowGraphMatrixCompose\",\n    BooleanToFloat = \"FlowGraphBooleanToFloat\",\n    BooleanToInt = \"FlowGraphBooleanToInt\",\n    FloatToBoolean = \"FlowGraphFloatToBoolean\",\n    IntToBoolean = \"FlowGraphIntToBoolean\",\n    IntToFloat = \"FlowGraphIntToFloat\",\n    FloatToInt = \"FlowGraphFloatToInt\",\n    Easing = \"FlowGraphEasingBlock\",\n    Context = \"FlowGraphContextBlock\",\n    ArrayIndex = \"FlowGraphArrayIndexBlock\",\n    CodeExecution = \"FlowGraphCodeExecutionBlock\",\n    IndexOf = \"FlowGraphIndexOfBlock\",\n    FunctionReference = \"FlowGraphFunctionReference\",\n    BezierCurveEasing = \"FlowGraphBezierCurveEasing\",\n    DataSwitch = \"FlowGraphDataSwitchBlock\",\n    DebugBlock = \"FlowGraphDebugBlock\",\n    // Physics\n    PhysicsCollisionEvent = \"FlowGraphPhysicsCollisionEventBlock\",\n    PhysicsApplyForce = \"FlowGraphApplyForceBlock\",\n    PhysicsApplyImpulse = \"FlowGraphApplyImpulseBlock\",\n    PhysicsSetLinearVelocity = \"FlowGraphSetLinearVelocityBlock\",\n    PhysicsSetAngularVelocity = \"FlowGraphSetAngularVelocityBlock\",\n    PhysicsSetMotionType = \"FlowGraphSetPhysicsMotionTypeBlock\",\n    PhysicsGetLinearVelocity = \"FlowGraphGetLinearVelocityBlock\",\n    PhysicsGetAngularVelocity = \"FlowGraphGetAngularVelocityBlock\",\n    PhysicsGetMassProperties = \"FlowGraphGetPhysicsMassPropertiesBlock\",\n    // Audio\n    AudioPlaySound = \"FlowGraphPlaySoundBlock\",\n    AudioStopSound = \"FlowGraphStopSoundBlock\",\n    AudioPauseSound = \"FlowGraphPauseSoundBlock\",\n    AudioSetVolume = \"FlowGraphSetSoundVolumeBlock\",\n    AudioSoundEndedEvent = \"FlowGraphSoundEndedEventBlock\",\n    AudioGetVolume = \"FlowGraphGetSoundVolumeBlock\",\n    AudioIsSoundPlaying = \"FlowGraphIsSoundPlayingBlock\",\n}\n","import {\r\n    type Color4,\r\n    type Scene,\r\n    type FrameGraphTextureHandle,\r\n    type Camera,\r\n    type FrameGraphObjectList,\r\n    type IShadowLight,\r\n    type FrameGraphShadowGeneratorTask,\r\n    type FrameGraphObjectRendererTask,\r\n    type FrameGraph,\r\n    type NodeRenderGraphBlock,\r\n} from \"core/index\";\r\n\r\n/**\r\n * Description of a custom block to be used in the node render graph editor\r\n */\r\nexport interface INodeRenderGraphCustomBlockDescription {\r\n    /** Block name. It will be used as the block name in the left menu of the editor. Spaces must be replaced by underscores in the name. */\r\n    name: string;\r\n    /** Description (tooltip) of the block. */\r\n    description: string;\r\n    /** Category of the block. Spaces must be replaced by underscores in the category name. */\r\n    menu: string;\r\n    /** Factory function to create the block. */\r\n    factory: (frameGraph: FrameGraph, scene: Scene) => NodeRenderGraphBlock;\r\n}\r\n\r\n/**\r\n * Interface used to configure the node render graph editor\r\n */\r\nexport interface INodeRenderGraphEditorOptions {\r\n    /** Define the URL to load node editor script from */\r\n    editorURL?: string;\r\n    /** Additional configuration for the FGE */\r\n    nodeRenderGraphEditorConfig?: {\r\n        backgroundColor?: Color4;\r\n        hostScene?: Scene;\r\n        customBlockDescriptions?: INodeRenderGraphCustomBlockDescription[];\r\n    };\r\n}\r\n\r\n/**\r\n * Options that can be passed to the node render graph build method\r\n */\r\nexport interface INodeRenderGraphCreateOptions {\r\n    /** If true, textures created by the node render graph will be visible in the inspector, for easier debugging (default: false) */\r\n    debugTextures?: boolean;\r\n    /** Rebuild the node render graph when the screen is resized (default: true) */\r\n    rebuildGraphOnEngineResize?: boolean;\r\n    /** Defines if the build should log activity (default: false) */\r\n    verbose?: boolean;\r\n    /** Defines if the autoConfigure method should be called when initializing blocks (default: false) */\r\n    autoConfigure?: boolean;\r\n    /** If true, external inputs like object lists and cameras will be filled with default values, taken from the scene. Note that external textures are not concerned (default: true). */\r\n    autoFillExternalInputs?: boolean;\r\n}\r\n\r\n/**\r\n * Defines the kind of connection point for node render graph nodes\r\n */\r\nexport enum NodeRenderGraphBlockConnectionPointTypes {\r\n    /** General purpose texture */\r\n    Texture = 0x00000001,\r\n    /** Back buffer color texture */\r\n    TextureBackBuffer = 0x00000002,\r\n    /** Back buffer depth/stencil attachment */\r\n    TextureBackBufferDepthStencilAttachment = 0x00000004,\r\n    /** Depth/stencil attachment */\r\n    TextureDepthStencilAttachment = 0x00000008,\r\n    /** Depth (in view space) geometry texture */\r\n    TextureViewDepth = 0x00000010,\r\n    /** Normal (in view space) geometry texture */\r\n    TextureViewNormal = 0x00000020,\r\n    /** Albedo geometry texture */\r\n    TextureAlbedo = 0x00000040,\r\n    /** Reflectivity geometry texture */\r\n    TextureReflectivity = 0x00000080,\r\n    /** Position (in world space) geometry texture */\r\n    TextureWorldPosition = 0x00000100,\r\n    /** Velocity geometry texture */\r\n    TextureVelocity = 0x00000200,\r\n    /** Irradiance geometry texture */\r\n    TextureIrradiance = 0x00000400,\r\n    /** Albedo (sqrt) geometry texture */\r\n    TextureAlbedoSqrt = 0x00000800,\r\n    /** Depth (in screen space) geometry texture */\r\n    TextureScreenDepth = 0x00001000,\r\n    /** Normal (in world space) geometry texture, encoded from [-1, 1] to [0, 1] */\r\n    TextureWorldNormal = 0x00002000,\r\n    /** Position (in local space) geometry texture */\r\n    TextureLocalPosition = 0x00004000,\r\n    /** Linear velocity geometry texture */\r\n    TextureLinearVelocity = 0x00008000,\r\n    /** Normalied depth (in view space) geometry texture */\r\n    TextureNormalizedViewDepth = 0x00010000,\r\n    /** Object ID geometry texture */\r\n    TextureObjectId = 0x00020000,\r\n    /** Packed mesh-blending tag geometry texture */\r\n    TextureMeshBlendTag = 0x00040000,\r\n\r\n    /** Bit field for all textures but back buffer depth/stencil */\r\n    TextureAllButBackBufferDepthStencil = 0x000ffffb,\r\n    /** Bit field for all textures but back buffer color and depth/stencil */\r\n    TextureAllButBackBuffer = 0x000ffff9,\r\n    /** Bit field for all textures */\r\n    TextureAll = 0x000fffff,\r\n\r\n    /** Resource container */\r\n    ResourceContainer = 0x00100000,\r\n    /** Shadow generator */\r\n    ShadowGenerator = 0x00200000,\r\n    /** Light */\r\n    ShadowLight = 0x00400000,\r\n    /** Camera */\r\n    Camera = 0x01000000,\r\n    /** List of objects (meshes, particle systems, sprite managers) */\r\n    ObjectList = 0x02000000,\r\n\r\n    /** Detect type based on connection */\r\n    AutoDetect = 0x10000000,\r\n    /** Output type that will be defined by input type */\r\n    BasedOnInput = 0x20000000,\r\n    /** Undefined */\r\n    Undefined = 0x40000000,\r\n    /** Custom object */\r\n    Object = 0x80000000,\r\n    /** Bitmask of all types */\r\n    All = 0xffffffff,\r\n}\r\n\r\n/**\r\n * Enum used to define the compatibility state between two connection points\r\n */\r\nexport const enum NodeRenderGraphConnectionPointCompatibilityStates {\r\n    /** Points are compatibles */\r\n    Compatible,\r\n    /** Points are incompatible because of their types */\r\n    TypeIncompatible,\r\n    /** Points are incompatible because they are in the same hierarchy **/\r\n    HierarchyIssue,\r\n}\r\n\r\n/**\r\n * Defines the direction of a connection point\r\n */\r\nexport const enum NodeRenderGraphConnectionPointDirection {\r\n    /** Input */\r\n    Input,\r\n    /** Output */\r\n    Output,\r\n}\r\n\r\n/**\r\n * Defines the type of a connection point value\r\n */\r\nexport type NodeRenderGraphBlockConnectionPointValueType =\r\n    FrameGraphTextureHandle | Camera | FrameGraphObjectList | IShadowLight | FrameGraphShadowGeneratorTask | FrameGraphObjectRendererTask;\r\n","import {\r\n    type Nullable,\r\n    type NodeRenderGraphBlock,\r\n    type NodeRenderGraphBlockConnectionPointValueType,\r\n    type NodeRenderGraphInputBlock,\r\n    type IShadowLight,\r\n    type FrameGraphShadowGeneratorTask,\r\n} from \"core/index\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointCompatibilityStates, NodeRenderGraphConnectionPointDirection } from \"./Types/nodeRenderGraphTypes\";\r\n\r\n/**\r\n * Defines a connection point for a block\r\n */\r\nexport class NodeRenderGraphConnectionPoint {\r\n    private readonly _ownerBlock: NodeRenderGraphBlock;\r\n    private _connectedPoint: Nullable<NodeRenderGraphConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _acceptedConnectionPointType: Nullable<NodeRenderGraphConnectionPoint> = null;\r\n\r\n    private _endpoints = new Array<NodeRenderGraphConnectionPoint>();\r\n    private readonly _direction: NodeRenderGraphConnectionPointDirection;\r\n    private _type = NodeRenderGraphBlockConnectionPointTypes.Undefined;\r\n\r\n    /** @internal */\r\n    public _linkedConnectionSource: Nullable<NodeRenderGraphConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _isMainLinkSource = false;\r\n\r\n    /** @internal */\r\n    public _typeConnectionSource: Nullable<NodeRenderGraphConnectionPoint | (() => NodeRenderGraphConnectionPoint)> = null;\r\n\r\n    /** @internal */\r\n    public _defaultConnectionPointType: Nullable<NodeRenderGraphBlockConnectionPointTypes> = null;\r\n\r\n    /** Gets the direction of the point */\r\n    public get direction() {\r\n        return this._direction;\r\n    }\r\n\r\n    /**\r\n     * Checks if the value is a texture handle\r\n     * @param value The value to check\r\n     * @returns True if the value is a texture handle\r\n     */\r\n    public static IsTextureHandle(value: NodeRenderGraphBlockConnectionPointValueType | undefined): boolean {\r\n        return value !== undefined && Number.isFinite(value);\r\n    }\r\n\r\n    /**\r\n     * Checks if the value is a shadow generator task\r\n     * @param value The value to check\r\n     * @returns True if the value is a shadow generator\r\n     */\r\n    public static IsShadowGenerator(value: NodeRenderGraphBlockConnectionPointValueType | undefined): boolean {\r\n        return value !== undefined && (value as FrameGraphShadowGeneratorTask).mapSize !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Checks if the value is a shadow light\r\n     * @param value The value to check\r\n     * @returns True if the value is a shadow light\r\n     */\r\n    public static IsShadowLight(value: NodeRenderGraphBlockConnectionPointValueType | undefined): boolean {\r\n        return value !== undefined && (value as IShadowLight).setShadowProjectionMatrix !== undefined;\r\n    }\r\n\r\n    /**\r\n     * The value stored in this connection point\r\n     */\r\n    public value: NodeRenderGraphBlockConnectionPointValueType | undefined;\r\n\r\n    /** Indicates that this connection point needs dual validation before being connected to another point */\r\n    public needDualDirectionValidation: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets the additional types supported by this connection point\r\n     */\r\n    public acceptedConnectionPointTypes: NodeRenderGraphBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Gets or sets the additional types excluded by this connection point\r\n     */\r\n    public excludedConnectionPointTypes: NodeRenderGraphBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Observable triggered when this point is connected\r\n     */\r\n    public onConnectionObservable = new Observable<NodeRenderGraphConnectionPoint>();\r\n\r\n    /**\r\n     * Observable triggered when this point is disconnected\r\n     */\r\n    public onDisconnectionObservable = new Observable<NodeRenderGraphConnectionPoint>();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is exposed on a frame\r\n     */\r\n    public isExposedOnFrame: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets number indicating the position that the port is exposed to on a frame\r\n     */\r\n    public exposedPortPosition: number = -1;\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is Undefined)\r\n     */\r\n    public get type(): NodeRenderGraphBlockConnectionPointTypes {\r\n        if (this._type === NodeRenderGraphBlockConnectionPointTypes.AutoDetect) {\r\n            if (this._ownerBlock.isInput) {\r\n                return (this._ownerBlock as NodeRenderGraphInputBlock).type;\r\n            }\r\n\r\n            if (this._connectedPoint) {\r\n                return this._connectedPoint.type;\r\n            }\r\n\r\n            if (this._linkedConnectionSource) {\r\n                if (this._linkedConnectionSource.isConnected) {\r\n                    return this._linkedConnectionSource.type;\r\n                }\r\n                if (this._linkedConnectionSource._defaultConnectionPointType) {\r\n                    return this._linkedConnectionSource._defaultConnectionPointType;\r\n                }\r\n            }\r\n\r\n            if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        if (this._type === NodeRenderGraphBlockConnectionPointTypes.BasedOnInput) {\r\n            if (this._typeConnectionSource) {\r\n                const typeConnectionSource = typeof this._typeConnectionSource === \"function\" ? this._typeConnectionSource() : this._typeConnectionSource;\r\n                if (!typeConnectionSource.isConnected) {\r\n                    return this._defaultConnectionPointType ?? typeConnectionSource.type;\r\n                }\r\n                return typeConnectionSource._connectedPoint!.type;\r\n            } else if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    public set type(value: NodeRenderGraphBlockConnectionPointTypes) {\r\n        this._type = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the connection point name\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * Gets or sets the connection point display name\r\n     */\r\n    public displayName: string;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point can be omitted\r\n     */\r\n    public isOptional: boolean;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current point is connected to another NodeRenderGraphBlock\r\n     */\r\n    public get isConnected(): boolean {\r\n        return this.connectedPoint !== null || this.hasEndpoints;\r\n    }\r\n\r\n    /** Get the other side of the connection (if any) */\r\n    public get connectedPoint(): Nullable<NodeRenderGraphConnectionPoint> {\r\n        return this._connectedPoint;\r\n    }\r\n\r\n    /** Get the block that owns this connection point */\r\n    public get ownerBlock(): NodeRenderGraphBlock {\r\n        return this._ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the other side of this connection (if any) */\r\n    public get sourceBlock(): Nullable<NodeRenderGraphBlock> {\r\n        if (!this._connectedPoint) {\r\n            return null;\r\n        }\r\n\r\n        return this._connectedPoint.ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the endpoints of this connection (if any) */\r\n    public get connectedBlocks(): Array<NodeRenderGraphBlock> {\r\n        if (this._endpoints.length === 0) {\r\n            return [];\r\n        }\r\n\r\n        return this._endpoints.map((e) => e.ownerBlock);\r\n    }\r\n\r\n    /** Gets the list of connected endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /** Gets a boolean indicating if that output point is connected to at least one input */\r\n    public get hasEndpoints(): boolean {\r\n        return this._endpoints && this._endpoints.length > 0;\r\n    }\r\n\r\n    /** Get the inner type (ie AutoDetect for instance instead of the inferred one) */\r\n    public get innerType() {\r\n        if (this._linkedConnectionSource && !this._isMainLinkSource && this._linkedConnectionSource.isConnected) {\r\n            return this.type;\r\n        }\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Creates a block suitable to be used as an input for this input point.\r\n     * If null is returned, a block based on the point type will be created.\r\n     * @returns The returned string parameter is the name of the output point of NodeRenderGraphBlock (first parameter of the returned array) that can be connected to the input\r\n     */\r\n    public createCustomInputBlock(): Nullable<[NodeRenderGraphBlock, string]> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Creates a new connection point\r\n     * @param name defines the connection point name\r\n     * @param ownerBlock defines the block hosting this connection point\r\n     * @param direction defines the direction of the connection point\r\n     */\r\n    public constructor(name: string, ownerBlock: NodeRenderGraphBlock, direction: NodeRenderGraphConnectionPointDirection) {\r\n        this._ownerBlock = ownerBlock;\r\n        this.name = name;\r\n        this._direction = direction;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeRenderGraphConnectionPoint\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeRenderGraphConnectionPoint\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a boolean\r\n     */\r\n    public canConnectTo(connectionPoint: NodeRenderGraphConnectionPoint) {\r\n        return this.checkCompatibilityState(connectionPoint) === NodeRenderGraphConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Gets a number indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a number defining the compatibility state\r\n     */\r\n    public checkCompatibilityState(connectionPoint: NodeRenderGraphConnectionPoint): NodeRenderGraphConnectionPointCompatibilityStates {\r\n        const ownerBlock = this._ownerBlock;\r\n        const otherBlock = connectionPoint.ownerBlock;\r\n\r\n        if (this.type !== connectionPoint.type && connectionPoint.innerType !== NodeRenderGraphBlockConnectionPointTypes.AutoDetect) {\r\n            // Accepted types\r\n            if (connectionPoint.acceptedConnectionPointTypes && connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n                return NodeRenderGraphConnectionPointCompatibilityStates.Compatible;\r\n            } else {\r\n                return NodeRenderGraphConnectionPointCompatibilityStates.TypeIncompatible;\r\n            }\r\n        }\r\n\r\n        // Excluded\r\n        if (connectionPoint.excludedConnectionPointTypes && connectionPoint.excludedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n            return NodeRenderGraphConnectionPointCompatibilityStates.TypeIncompatible;\r\n        }\r\n\r\n        // Check hierarchy\r\n        let targetBlock = otherBlock;\r\n        let sourceBlock = ownerBlock;\r\n        if (this.direction === NodeRenderGraphConnectionPointDirection.Input) {\r\n            targetBlock = ownerBlock;\r\n            sourceBlock = otherBlock;\r\n        }\r\n\r\n        if (targetBlock.isAnAncestorOf(sourceBlock)) {\r\n            return NodeRenderGraphConnectionPointCompatibilityStates.HierarchyIssue;\r\n        }\r\n\r\n        return NodeRenderGraphConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Connect this point to another connection point\r\n     * @param connectionPoint defines the other connection point\r\n     * @param ignoreConstraints defines if the system will ignore connection type constraints (default is false)\r\n     * @returns the current connection point\r\n     */\r\n    public connectTo(connectionPoint: NodeRenderGraphConnectionPoint, ignoreConstraints = false): NodeRenderGraphConnectionPoint {\r\n        if (!ignoreConstraints && !this.canConnectTo(connectionPoint)) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw `Cannot connect these two connectors. source: \"${this.ownerBlock.name}\".${this.name}, target: \"${connectionPoint.ownerBlock.name}\".${connectionPoint.name}`;\r\n        }\r\n\r\n        this._endpoints.push(connectionPoint);\r\n        connectionPoint._connectedPoint = this;\r\n\r\n        this.onConnectionObservable.notifyObservers(connectionPoint);\r\n        connectionPoint.onConnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disconnect this point from one of his endpoint\r\n     * @param endpoint defines the other connection point\r\n     * @returns the current connection point\r\n     */\r\n    public disconnectFrom(endpoint: NodeRenderGraphConnectionPoint): NodeRenderGraphConnectionPoint {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index === -1) {\r\n            return this;\r\n        }\r\n\r\n        this._endpoints.splice(index, 1);\r\n        endpoint._connectedPoint = null;\r\n\r\n        this.onDisconnectionObservable.notifyObservers(endpoint);\r\n        endpoint.onDisconnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Fills the list of excluded connection point types with all types other than those passed in the parameter\r\n     * @param mask Types (ORed values of NodeRenderGraphBlockConnectionPointTypes) that are allowed, and thus will not be pushed to the excluded list\r\n     */\r\n    public addExcludedConnectionPointFromAllowedTypes(mask: number): void {\r\n        let bitmask = 0;\r\n        let val = 2 ** bitmask;\r\n        // Note: don't use 1 << bitmask instead of 2 ** bitmask, as it will cause an infinite loop because 1 << 31 is negative!\r\n        while (val < NodeRenderGraphBlockConnectionPointTypes.All) {\r\n            if (!(mask & val)) {\r\n                this.excludedConnectionPointTypes.push(val);\r\n            }\r\n            bitmask++;\r\n            val = 2 ** bitmask;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds accepted connection point types\r\n     * @param mask Types (ORed values of NodeRenderGraphBlockConnectionPointTypes) that are allowed to connect to this point\r\n     */\r\n    public addAcceptedConnectionPointTypes(mask: number): void {\r\n        let bitmask = 0;\r\n        let val = 2 ** bitmask;\r\n        // Note: don't use 1 << bitmask instead of 2 ** bitmask, as it will cause an infinite loop because 1 << 31 is negative!\r\n        while (val < NodeRenderGraphBlockConnectionPointTypes.All) {\r\n            if (mask & val && this.acceptedConnectionPointTypes.indexOf(val) === -1) {\r\n                this.acceptedConnectionPointTypes.push(val);\r\n            }\r\n            bitmask++;\r\n            val = 2 ** bitmask;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this point in a JSON representation\r\n     * @param isInput defines if the connection point is an input (default is true)\r\n     * @returns the serialized point object\r\n     */\r\n    public serialize(isInput = true): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.displayName = this.displayName;\r\n\r\n        if (isInput && this.connectedPoint) {\r\n            serializationObject.inputName = this.name;\r\n            serializationObject.targetBlockId = this.connectedPoint.ownerBlock.uniqueId;\r\n            serializationObject.targetConnectionName = this.connectedPoint.name;\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        if (this.isExposedOnFrame || this.exposedPortPosition >= 0) {\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        this.onConnectionObservable.clear();\r\n        this.onDisconnectionObservable.clear();\r\n    }\r\n}\r\n","import {\r\n    type NodeRenderGraphBuildState,\r\n    type Nullable,\r\n    type NodeRenderGraphInputBlock,\r\n    type AbstractEngine,\r\n    type Scene,\r\n    type FrameGraphTask,\r\n    type FrameGraph,\r\n    type NodeRenderGraphResourceContainerBlock,\r\n    type FrameGraphTextureHandle,\r\n} from \"core/index\";\r\nimport { GetClass } from \"../../Misc/typeStore\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { UniqueIdGenerator } from \"../../Misc/uniqueIdGenerator\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointDirection } from \"./Types/nodeRenderGraphTypes\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { NodeRenderGraphConnectionPoint } from \"./nodeRenderGraphBlockConnectionPoint\";\r\n\r\n/**\r\n * Defines a block that can be used inside a node render graph\r\n */\r\nexport class NodeRenderGraphBlock {\r\n    private _name = \"\";\r\n    private _buildId: number;\r\n    protected _isInput = false;\r\n    protected _isTeleportOut = false;\r\n    protected _isTeleportIn = false;\r\n    protected _isDebug = false;\r\n    protected _isUnique = false;\r\n    protected _scene: Scene;\r\n    protected _engine: AbstractEngine;\r\n    protected _frameGraph: FrameGraph;\r\n    protected _frameGraphTask?: FrameGraphTask;\r\n\r\n    /**\r\n     * Gets or sets the disable flag of the task associated with this block\r\n     */\r\n    public get disabled() {\r\n        return !!this._frameGraphTask?.disabled;\r\n    }\r\n\r\n    public set disabled(value: boolean) {\r\n        if (this._frameGraphTask) {\r\n            this._frameGraphTask.disabled = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Gets an observable raised when the block is built\r\n     */\r\n    public onBuildObservable = new Observable<NodeRenderGraphBlock>();\r\n\r\n    /** @internal */\r\n    public _inputs = new Array<NodeRenderGraphConnectionPoint>();\r\n\r\n    /** @internal */\r\n    public _outputs = new Array<NodeRenderGraphConnectionPoint>();\r\n\r\n    /** @internal */\r\n    public _codeVariableName = \"\";\r\n\r\n    /** @internal */\r\n    public _additionalConstructionParameters: Nullable<unknown[]> = null;\r\n\r\n    /**\r\n     * Gets the list of input points\r\n     */\r\n    public get inputs(): NodeRenderGraphConnectionPoint[] {\r\n        return this._inputs;\r\n    }\r\n\r\n    /** Gets the list of output points */\r\n    public get outputs(): NodeRenderGraphConnectionPoint[] {\r\n        return this._outputs;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the unique id of the node\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Gets or set the name of the block\r\n     */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is an input\r\n     */\r\n    public get isInput(): boolean {\r\n        return this._isInput;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport out\r\n     */\r\n    public get isTeleportOut(): boolean {\r\n        return this._isTeleportOut;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport in\r\n     */\r\n    public get isTeleportIn(): boolean {\r\n        return this._isTeleportIn;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a debug block\r\n     */\r\n    public get isDebug(): boolean {\r\n        return this._isDebug;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block can only be used once per node render graph\r\n     */\r\n    public get isUnique() {\r\n        return this._isUnique;\r\n    }\r\n\r\n    /**\r\n     * A free comment about the block\r\n     */\r\n    @serialize(\"comment\")\r\n    public comments: string;\r\n\r\n    /** Gets or sets a boolean indicating that this input can be edited from a collapsed frame */\r\n    public visibleOnFrame = false;\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeRenderGraphBlock\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName() {\r\n        return \"NodeRenderGraphBlock\";\r\n    }\r\n\r\n    protected _inputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    protected _outputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOf(block: NodeRenderGraphBlock): boolean {\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock === block) {\r\n                    return true;\r\n                }\r\n\r\n                if (endpoint.ownerBlock.isAnAncestorOf(block)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given type\r\n     * @param type defines the potential type to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOfType(type: string): boolean {\r\n        if (this.getClassName() === type) {\r\n            return true;\r\n        }\r\n\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock.isAnAncestorOfType(type)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Get the first descendant using a predicate\r\n     * @param predicate defines the predicate to check\r\n     * @returns descendant or null if none found\r\n     */\r\n    public getDescendantOfPredicate(predicate: (block: NodeRenderGraphBlock) => boolean): Nullable<NodeRenderGraphBlock> {\r\n        if (predicate(this)) {\r\n            return this;\r\n        }\r\n\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const descendant = endpoint.ownerBlock.getDescendantOfPredicate(predicate);\r\n                if (descendant) {\r\n                    return descendant;\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeRenderGraphBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param _additionalConstructionParameters defines additional parameters to pass to the block constructor\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, ..._additionalConstructionParameters: unknown[]) {\r\n        this._name = name;\r\n        this._frameGraph = frameGraph;\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this.uniqueId = UniqueIdGenerator.UniqueId;\r\n    }\r\n\r\n    /**\r\n     * Register a new input. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param isOptional defines a boolean indicating that this input can be omitted\r\n     * @param point an already created connection point. If not provided, create a new one\r\n     * @returns the current block\r\n     */\r\n    public registerInput(name: string, type: NodeRenderGraphBlockConnectionPointTypes, isOptional: boolean = false, point?: NodeRenderGraphConnectionPoint) {\r\n        point = point ?? new NodeRenderGraphConnectionPoint(name, this, NodeRenderGraphConnectionPointDirection.Input);\r\n        point.type = type;\r\n        point.isOptional = isOptional;\r\n\r\n        this._inputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Register a new output. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param point an already created connection point. If not provided, create a new one\r\n     * @returns the current block\r\n     */\r\n    public registerOutput(name: string, type: NodeRenderGraphBlockConnectionPointTypes, point?: NodeRenderGraphConnectionPoint) {\r\n        point = point ?? new NodeRenderGraphConnectionPoint(name, this, NodeRenderGraphConnectionPointDirection.Output);\r\n        point.type = type;\r\n\r\n        this._outputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    protected _addDependenciesInput(additionalAllowedTypes = 0) {\r\n        this.registerInput(\"dependencies\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        const dependencies = this.getInputByName(\"dependencies\")!;\r\n\r\n        Object.defineProperty(this, \"dependencies\", {\r\n            get: function (this: FrameGraphTask) {\r\n                return dependencies;\r\n            },\r\n            enumerable: true,\r\n            configurable: true,\r\n        });\r\n\r\n        dependencies.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer |\r\n                NodeRenderGraphBlockConnectionPointTypes.ResourceContainer |\r\n                NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator |\r\n                NodeRenderGraphBlockConnectionPointTypes.ObjectList |\r\n                NodeRenderGraphBlockConnectionPointTypes.ShadowLight |\r\n                NodeRenderGraphBlockConnectionPointTypes.Camera |\r\n                NodeRenderGraphBlockConnectionPointTypes.Object |\r\n                additionalAllowedTypes\r\n        );\r\n\r\n        return dependencies;\r\n    }\r\n\r\n    protected _buildBlock(_state: NodeRenderGraphBuildState) {\r\n        // Empty. Must be defined by child nodes\r\n    }\r\n\r\n    protected _customBuildStep(_state: NodeRenderGraphBuildState): void {\r\n        // Must be implemented by children\r\n    }\r\n\r\n    protected _propagateInputValueToOutput(inputConnectionPoint: NodeRenderGraphConnectionPoint, outputConnectionPoint: NodeRenderGraphConnectionPoint) {\r\n        if (inputConnectionPoint.connectedPoint) {\r\n            outputConnectionPoint.value = inputConnectionPoint.connectedPoint.value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Build the current node and generate the vertex data\r\n     * @param state defines the current generation state\r\n     * @returns true if already built\r\n     */\r\n    public build(state: NodeRenderGraphBuildState): boolean {\r\n        if (this._buildId === state.buildId) {\r\n            return true;\r\n        }\r\n\r\n        this._buildId = state.buildId;\r\n\r\n        // Check if \"parent\" blocks are compiled\r\n        for (const input of this._inputs) {\r\n            if (!input.connectedPoint) {\r\n                if (!input.isOptional) {\r\n                    // Emit a warning\r\n                    state._notConnectedNonOptionalInputs.push(input);\r\n                }\r\n                continue;\r\n            }\r\n\r\n            const block = input.connectedPoint.ownerBlock;\r\n            if (block && block !== this) {\r\n                block.build(state);\r\n            }\r\n        }\r\n\r\n        this._customBuildStep(state);\r\n\r\n        // Logs\r\n        if (state.verbose) {\r\n            Logger.Log(`Building ${this.name} [${this.getClassName()}]`);\r\n        }\r\n\r\n        if (this._frameGraphTask) {\r\n            this._frameGraphTask.name = this.name;\r\n        }\r\n\r\n        this._buildBlock(state);\r\n\r\n        if (this._frameGraphTask) {\r\n            this._frameGraphTask.dependencies = undefined;\r\n\r\n            const dependenciesConnectedPoint = this.getInputByName(\"dependencies\")?.connectedPoint;\r\n            if (dependenciesConnectedPoint) {\r\n                if (dependenciesConnectedPoint.type === NodeRenderGraphBlockConnectionPointTypes.ResourceContainer) {\r\n                    const container = dependenciesConnectedPoint.ownerBlock as NodeRenderGraphResourceContainerBlock;\r\n                    for (let i = 0; i < container.inputs.length; i++) {\r\n                        const input = container.inputs[i];\r\n                        if (input.connectedPoint && input.connectedPoint.value !== undefined && NodeRenderGraphConnectionPoint.IsTextureHandle(input.connectedPoint.value)) {\r\n                            this._frameGraphTask.dependencies = this._frameGraphTask.dependencies || new Set();\r\n                            this._frameGraphTask.dependencies.add(input.connectedPoint.value as FrameGraphTextureHandle);\r\n                        }\r\n                    }\r\n                } else if (NodeRenderGraphConnectionPoint.IsTextureHandle(dependenciesConnectedPoint.value)) {\r\n                    this._frameGraphTask.dependencies = this._frameGraphTask.dependencies || new Set();\r\n                    this._frameGraphTask.dependencies.add(dependenciesConnectedPoint.value as FrameGraphTextureHandle);\r\n                }\r\n            }\r\n            this._frameGraph.addTask(this._frameGraphTask);\r\n        }\r\n\r\n        this.onBuildObservable.notifyObservers(this);\r\n\r\n        return false;\r\n    }\r\n\r\n    protected _getConnectedTextures(targetConnectedPoint: Nullable<NodeRenderGraphConnectionPoint>) {\r\n        let textureHandles: FrameGraphTextureHandle | FrameGraphTextureHandle[] | undefined;\r\n        if (targetConnectedPoint) {\r\n            if (targetConnectedPoint.type === NodeRenderGraphBlockConnectionPointTypes.ResourceContainer) {\r\n                const container = targetConnectedPoint.ownerBlock as NodeRenderGraphResourceContainerBlock;\r\n                textureHandles = [];\r\n                for (let i = 0; i < container.inputs.length; i++) {\r\n                    const input = container.inputs[i];\r\n                    if (input.connectedPoint && input.connectedPoint.value !== undefined && NodeRenderGraphConnectionPoint.IsTextureHandle(input.connectedPoint.value)) {\r\n                        textureHandles.push(input.connectedPoint.value as FrameGraphTextureHandle);\r\n                    }\r\n                }\r\n            } else {\r\n                textureHandles = targetConnectedPoint.value as FrameGraphTextureHandle;\r\n            }\r\n        }\r\n\r\n        return textureHandles;\r\n    }\r\n\r\n    protected _linkConnectionTypes(inputIndex0: number, inputIndex1: number, looseCoupling = false) {\r\n        if (looseCoupling) {\r\n            this._inputs[inputIndex1]._acceptedConnectionPointType = this._inputs[inputIndex0];\r\n        } else {\r\n            this._inputs[inputIndex0]._linkedConnectionSource = this._inputs[inputIndex1];\r\n            this._inputs[inputIndex0]._isMainLinkSource = true;\r\n        }\r\n\r\n        this._inputs[inputIndex1]._linkedConnectionSource = this._inputs[inputIndex0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     */\r\n    public initialize() {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Lets the block try to connect some inputs automatically\r\n     */\r\n    public autoConfigure() {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Find an input by its name\r\n     * @param name defines the name of the input to look for\r\n     * @returns the input or null if not found\r\n     */\r\n    public getInputByName(name: string) {\r\n        const filter = this._inputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Find an output by its name\r\n     * @param name defines the name of the output to look for\r\n     * @returns the output or null if not found\r\n     */\r\n    public getOutputByName(name: string) {\r\n        const filter = this._outputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.customType = \"BABYLON.\" + this.getClassName();\r\n        serializationObject.id = this.uniqueId;\r\n        serializationObject.name = this.name;\r\n        serializationObject.comments = this.comments;\r\n        serializationObject.visibleOnFrame = this.visibleOnFrame;\r\n        serializationObject.disabled = this.disabled;\r\n        if (this._additionalConstructionParameters) {\r\n            serializationObject.additionalConstructionParameters = this._additionalConstructionParameters;\r\n        }\r\n\r\n        serializationObject.inputs = [];\r\n        serializationObject.outputs = [];\r\n\r\n        for (const input of this.inputs) {\r\n            serializationObject.inputs.push(input.serialize());\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            serializationObject.outputs.push(output.serialize(false));\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n    /**\r\n     * @internal\r\n     */\r\n    public _deserialize(serializationObject: any) {\r\n        this._name = serializationObject.name;\r\n        this.comments = serializationObject.comments;\r\n        this.visibleOnFrame = serializationObject.visibleOnFrame;\r\n        this.disabled = serializationObject.disabled;\r\n\r\n        this._deserializePortDisplayNamesAndExposedOnFrame(serializationObject);\r\n    }\r\n\r\n    private _deserializePortDisplayNamesAndExposedOnFrame(serializationObject: any) {\r\n        const serializedInputs = serializationObject.inputs;\r\n        const serializedOutputs = serializationObject.outputs;\r\n\r\n        if (serializedInputs) {\r\n            for (const port of serializedInputs) {\r\n                const input = this.inputs.find((i) => i.name === port.name);\r\n                if (!input) {\r\n                    continue;\r\n                }\r\n                if (port.displayName) {\r\n                    input.displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    input.isExposedOnFrame = port.isExposedOnFrame;\r\n                    input.exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (serializedOutputs) {\r\n            for (let i = 0; i < serializedOutputs.length; i++) {\r\n                const port = serializedOutputs[i];\r\n                if (port.displayName) {\r\n                    this.outputs[i].displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    this.outputs[i].isExposedOnFrame = port.isExposedOnFrame;\r\n                    this.outputs[i].exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _dumpPropertiesCode() {\r\n        const variableName = this._codeVariableName;\r\n        return `${variableName}.visibleOnFrame = ${this.visibleOnFrame};\\n${variableName}.disabled = ${this.disabled};\\n`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _dumpCodeForOutputConnections(alreadyDumped: NodeRenderGraphBlock[]) {\r\n        let codeString = \"\";\r\n\r\n        if (alreadyDumped.indexOf(this) !== -1) {\r\n            return codeString;\r\n        }\r\n\r\n        alreadyDumped.push(this);\r\n\r\n        for (const input of this.inputs) {\r\n            if (!input.isConnected) {\r\n                continue;\r\n            }\r\n\r\n            const connectedOutput = input.connectedPoint!;\r\n            const connectedBlock = connectedOutput.ownerBlock;\r\n\r\n            codeString += connectedBlock._dumpCodeForOutputConnections(alreadyDumped);\r\n            codeString += `${connectedBlock._codeVariableName}.${connectedBlock._outputRename(connectedOutput.name)}.connectTo(${this._codeVariableName}.${this._inputRename(\r\n                input.name\r\n            )});\\n`;\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _dumpCode(uniqueNames: string[], alreadyDumped: NodeRenderGraphBlock[]) {\r\n        alreadyDumped.push(this);\r\n\r\n        // Get unique name\r\n        const nameAsVariableName = this.name.replace(/[^A-Za-z_]+/g, \"\");\r\n        this._codeVariableName = nameAsVariableName || `${this.getClassName()}_${this.uniqueId}`;\r\n\r\n        if (uniqueNames.indexOf(this._codeVariableName) !== -1) {\r\n            let index = 0;\r\n            do {\r\n                index++;\r\n                this._codeVariableName = nameAsVariableName + index;\r\n            } while (uniqueNames.indexOf(this._codeVariableName) !== -1);\r\n        }\r\n\r\n        uniqueNames.push(this._codeVariableName);\r\n\r\n        // Declaration\r\n        let codeString = `\\n// ${this.getClassName()}\\n`;\r\n        if (this.comments) {\r\n            codeString += `// ${this.comments}\\n`;\r\n        }\r\n        const className = this.getClassName();\r\n        if (className === \"NodeRenderGraphInputBlock\") {\r\n            const block = this as unknown as NodeRenderGraphInputBlock;\r\n            const blockType = block.type;\r\n\r\n            codeString += `var ${this._codeVariableName} = new BABYLON.NodeRenderGraphInputBlock(\"${this.name}\", nodeRenderGraph.frameGraph, scene, BABYLON.NodeRenderGraphBlockConnectionPointTypes.${NodeRenderGraphBlockConnectionPointTypes[blockType]});\\n`;\r\n        } else {\r\n            if (this._additionalConstructionParameters) {\r\n                codeString += `var ${this._codeVariableName} = new BABYLON.${className}(\"${this.name}\", nodeRenderGraph.frameGraph, scene, ...${JSON.stringify(this._additionalConstructionParameters)});\\n`;\r\n            } else {\r\n                codeString += `var ${this._codeVariableName} = new BABYLON.${className}(\"${this.name}\", nodeRenderGraph.frameGraph, scene);\\n`;\r\n            }\r\n        }\r\n\r\n        // Properties\r\n        codeString += this._dumpPropertiesCode() + \"\\n\";\r\n\r\n        // Inputs\r\n        for (const input of this.inputs) {\r\n            if (!input.isConnected) {\r\n                continue;\r\n            }\r\n\r\n            const connectedOutput = input.connectedPoint!;\r\n            const connectedBlock = connectedOutput.ownerBlock;\r\n\r\n            if (alreadyDumped.indexOf(connectedBlock) === -1) {\r\n                codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        // Outputs\r\n        for (const output of this.outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const connectedBlock = endpoint.ownerBlock;\r\n                if (connectedBlock && alreadyDumped.indexOf(connectedBlock) === -1) {\r\n                    codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);\r\n                }\r\n            }\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @returns a copy of the current block\r\n     */\r\n    public clone() {\r\n        const serializationObject = this.serialize();\r\n        const blockType: typeof NodeRenderGraphBlock = GetClass(serializationObject.customType);\r\n\r\n        if (blockType) {\r\n            const additionalConstructionParameters = serializationObject.additionalConstructionParameters;\r\n            const block: NodeRenderGraphBlock = additionalConstructionParameters\r\n                ? new blockType(\"\", this._frameGraph, this._scene, ...additionalConstructionParameters)\r\n                : new blockType(\"\", this._frameGraph, this._scene);\r\n            block._deserialize(serializationObject);\r\n            return block;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        for (const input of this.inputs) {\r\n            input.dispose();\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            output.dispose();\r\n        }\r\n\r\n        this._frameGraphTask?.dispose();\r\n        this._frameGraphTask = undefined as any;\r\n\r\n        this.onBuildObservable.clear();\r\n    }\r\n}\r\n","import { type Nullable, type FrameGraphContext, type IFrameGraphPass, type FrameGraphTask } from \"core/index\";\r\n\r\n/**\r\n * Base class for a frame graph pass.\r\n */\r\nexport class FrameGraphPass<T extends FrameGraphContext> implements IFrameGraphPass {\r\n    private _executeFunc: (context: T) => void;\r\n    private _initFunc?: (context: T) => void;\r\n\r\n    /**\r\n     * Whether the pass is disabled. Disabled passes will be skipped during execution.\r\n     */\r\n    public disabled = false;\r\n\r\n    /** @internal */\r\n    constructor(\r\n        public name: string,\r\n        protected readonly _parentTask: FrameGraphTask,\r\n        protected readonly _context: T\r\n    ) {}\r\n\r\n    /**\r\n     * Initializes the pass.\r\n     * This function is called once after the frame graph has been built\r\n     * @param func The function to initialize the pass.\r\n     */\r\n    public setInitializeFunc(func: (context: T) => void) {\r\n        this._initFunc = func;\r\n    }\r\n\r\n    /**\r\n     * Sets the function to execute when the pass is executed\r\n     * @param func The function to execute when the pass is executed\r\n     */\r\n    public setExecuteFunc(func: (context: T) => void) {\r\n        this._executeFunc = func;\r\n    }\r\n\r\n    /** @internal */\r\n    public _execute() {\r\n        if (!this.disabled) {\r\n            this._executeFunc(this._context);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _initialize() {\r\n        this._initFunc?.(this._context);\r\n    }\r\n\r\n    /** @internal */\r\n    public _isValid(): Nullable<string> {\r\n        return this._executeFunc !== undefined ? null : \"Execute function is not set (call setExecuteFunc to set it)\";\r\n    }\r\n\r\n    /** @internal */\r\n    public _dispose() {}\r\n}\r\n","import { type Nullable, type AbstractEngine, type IFrameGraphPass, type FrameGraphContext, type FrameGraphObjectList, type FrameGraphTask } from \"core/index\";\r\nimport { FrameGraphPass } from \"./pass\";\r\n\r\n/**\r\n * Object list pass used to generate a list of objects.\r\n */\r\nexport class FrameGraphObjectListPass extends FrameGraphPass<FrameGraphContext> {\r\n    protected readonly _engine: AbstractEngine;\r\n    protected _objectList: FrameGraphObjectList;\r\n\r\n    /**\r\n     * Checks if a pass is an object list pass.\r\n     * @param pass The pass to check.\r\n     * @returns True if the pass is an object list pass, else false.\r\n     */\r\n    public static IsObjectListPass(pass: IFrameGraphPass): pass is FrameGraphObjectListPass {\r\n        return (pass as FrameGraphObjectListPass).setObjectList !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Gets the object list used by the pass.\r\n     */\r\n    public get objectList(): FrameGraphObjectList {\r\n        return this._objectList;\r\n    }\r\n\r\n    /**\r\n     * Sets the object list to use for the pass.\r\n     * @param objectList The object list to use for the pass.\r\n     */\r\n    public setObjectList(objectList: FrameGraphObjectList) {\r\n        this._objectList = objectList;\r\n    }\r\n\r\n    /** @internal */\r\n    constructor(name: string, parentTask: FrameGraphTask, context: FrameGraphContext, engine: AbstractEngine) {\r\n        super(name, parentTask, context);\r\n        this._engine = engine;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _isValid(): Nullable<string> {\r\n        const errMsg = super._isValid();\r\n        return errMsg ? errMsg : this._objectList !== undefined ? null : \"Object list is not set (call setObjectList to set it)\";\r\n    }\r\n}\r\n","import {\r\n    type Nullable,\r\n    type FrameGraphRenderContext,\r\n    type AbstractEngine,\r\n    type IFrameGraphPass,\r\n    type FrameGraphTextureHandle,\r\n    type FrameGraphTask,\r\n    type FrameGraphRenderTarget,\r\n} from \"core/index\";\r\nimport { FrameGraphPass } from \"./pass\";\r\n\r\n/**\r\n * Type used to define layer and face indices for multi-render target rendering scenarios.\r\n */\r\nexport type LayerAndFaceIndex = {\r\n    /** Index of the texture to update */\r\n    targetIndex: number;\r\n\r\n    /** Index of the layer to set (optional - not used if the texture is not an array or a 3D texture) */\r\n    layerIndex?: number;\r\n\r\n    /** Index of the cube face to set (optional - not used if the texture is not a cube texture) */\r\n    faceIndex?: number;\r\n};\r\n\r\n/**\r\n * Render pass used to render objects.\r\n */\r\nexport class FrameGraphRenderPass extends FrameGraphPass<FrameGraphRenderContext> {\r\n    protected readonly _engine: AbstractEngine;\r\n    protected _renderTarget: FrameGraphTextureHandle | FrameGraphTextureHandle[] | undefined;\r\n    protected _renderTargetDepth: FrameGraphTextureHandle | undefined;\r\n    protected _frameGraphRenderTarget: FrameGraphRenderTarget;\r\n    protected _dependencies: Set<FrameGraphTextureHandle> = new Set();\r\n\r\n    /**\r\n     * Checks if a pass is a render pass.\r\n     * @param pass The pass to check.\r\n     * @returns True if the pass is a render pass, else false.\r\n     */\r\n    public static IsRenderPass(pass: IFrameGraphPass): pass is FrameGraphRenderPass {\r\n        return (pass as FrameGraphRenderPass).setRenderTarget !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Gets the handle(s) of the render target(s) used by the render pass.\r\n     */\r\n    public get renderTarget(): FrameGraphTextureHandle | FrameGraphTextureHandle[] | undefined {\r\n        return this._renderTarget;\r\n    }\r\n\r\n    /**\r\n     * Gets the handle of the render target depth used by the render pass.\r\n     */\r\n    public get renderTargetDepth(): FrameGraphTextureHandle | undefined {\r\n        return this._renderTargetDepth;\r\n    }\r\n\r\n    /**\r\n     * Gets the frame graph render target used by the render pass.\r\n     */\r\n    public get frameGraphRenderTarget(): FrameGraphRenderTarget {\r\n        return this._frameGraphRenderTarget;\r\n    }\r\n\r\n    /**\r\n     * If true, the depth attachment will be read-only (may allow some optimizations in WebGPU)\r\n     */\r\n    public depthReadOnly = false;\r\n\r\n    /**\r\n     * If true, the stencil attachment will be read-only (may allow some optimizations in WebGPU)\r\n     */\r\n    public stencilReadOnly = false;\r\n\r\n    /** @internal */\r\n    constructor(name: string, parentTask: FrameGraphTask, context: FrameGraphRenderContext, engine: AbstractEngine) {\r\n        super(name, parentTask, context);\r\n        this._engine = engine;\r\n    }\r\n\r\n    /**\r\n     * Sets the render target(s) to use for rendering.\r\n     * @param renderTargetHandle The render target to use for rendering, or an array of render targets to use for multi render target rendering.\r\n     */\r\n    public setRenderTarget(renderTargetHandle?: FrameGraphTextureHandle | FrameGraphTextureHandle[]) {\r\n        this._renderTarget = renderTargetHandle;\r\n    }\r\n\r\n    /**\r\n     * Sets the render target depth to use for rendering.\r\n     * @param renderTargetHandle The render target depth to use for rendering.\r\n     */\r\n    public setRenderTargetDepth(renderTargetHandle?: FrameGraphTextureHandle) {\r\n        this._renderTargetDepth = renderTargetHandle;\r\n    }\r\n\r\n    /**\r\n     * Adds dependencies to the render pass.\r\n     * @param dependencies The dependencies to add.\r\n     */\r\n    public addDependencies(dependencies?: FrameGraphTextureHandle | FrameGraphTextureHandle[]) {\r\n        if (dependencies === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (Array.isArray(dependencies)) {\r\n            for (const dependency of dependencies) {\r\n                this._dependencies.add(dependency);\r\n            }\r\n        } else {\r\n            this._dependencies.add(dependencies);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Collects the dependencies of the render pass.\r\n     * @param dependencies The set of dependencies to update.\r\n     */\r\n    public collectDependencies(dependencies: Set<FrameGraphTextureHandle>): void {\r\n        const iterator = this._dependencies.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            dependencies.add(key.value);\r\n        }\r\n\r\n        if (this._renderTarget !== undefined) {\r\n            if (Array.isArray(this._renderTarget)) {\r\n                for (const handle of this._renderTarget) {\r\n                    if (handle !== undefined) {\r\n                        dependencies.add(handle);\r\n                    }\r\n                }\r\n            } else {\r\n                dependencies.add(this._renderTarget);\r\n            }\r\n        }\r\n\r\n        if (this._renderTargetDepth !== undefined) {\r\n            dependencies.add(this._renderTargetDepth);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the output layer and face indices for multi-render target rendering.\r\n     * @param indices The array of layer and face indices.\r\n     */\r\n    public setOutputLayerAndFaceIndices(indices: LayerAndFaceIndex[]): void {\r\n        const renderTargetWrapper = this.frameGraphRenderTarget.renderTargetWrapper;\r\n        if (renderTargetWrapper) {\r\n            for (const index of indices) {\r\n                renderTargetWrapper.setLayerAndFaceIndex(index.targetIndex, index.layerIndex, index.faceIndex);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _initialize() {\r\n        this._frameGraphRenderTarget = this._context.createRenderTarget(this.name, this._renderTarget, this._renderTargetDepth, this.depthReadOnly, this.stencilReadOnly);\r\n        super._initialize();\r\n    }\r\n\r\n    /** @internal */\r\n    public override _execute() {\r\n        this._context.bindRenderTarget(this._frameGraphRenderTarget);\r\n\r\n        super._execute();\r\n\r\n        this._context.restoreDefaultFramebuffer();\r\n    }\r\n\r\n    /** @internal */\r\n    public override _isValid(): Nullable<string> {\r\n        const errMsg = super._isValid();\r\n        return errMsg\r\n            ? errMsg\r\n            : this._renderTarget !== undefined || this.renderTargetDepth !== undefined\r\n              ? null\r\n              : \"Render target and render target depth cannot both be undefined.\";\r\n    }\r\n\r\n    /** @internal */\r\n    public override _dispose() {\r\n        this._frameGraphRenderTarget?.dispose();\r\n    }\r\n}\r\n","import {\r\n    type FrameGraph,\r\n    type FrameGraphObjectList,\r\n    type IFrameGraphPass,\r\n    type Nullable,\r\n    type FrameGraphTextureHandle,\r\n    type InternalTexture,\r\n    type FrameGraphRenderContext,\r\n} from \"core/index\";\r\nimport { FrameGraphObjectListPass } from \"./Passes/objectListPass\";\r\nimport { FrameGraphRenderPass } from \"./Passes/renderPass\";\r\nimport { Observable } from \"core/Misc/observable\";\r\n\r\n/**\r\n * Represents a task in a frame graph.\r\n */\r\nexport abstract class FrameGraphTask {\r\n    protected readonly _frameGraph: FrameGraph;\r\n\r\n    private readonly _passes: IFrameGraphPass[] = [];\r\n    private readonly _passesDisabled: IFrameGraphPass[] = [];\r\n\r\n    // Note: must be a getter/setter even if there's no specific processing, otherwise inherited classes can't make it a getter/setter!\r\n    // Same thing for the disabled property\r\n    protected _name: string;\r\n\r\n    /**\r\n     * The name of the task.\r\n     */\r\n    public get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    protected _disabled = false;\r\n\r\n    /**\r\n     * Whether the task is disabled.\r\n     */\r\n    public get disabled() {\r\n        return this._disabled;\r\n    }\r\n\r\n    public set disabled(value: boolean) {\r\n        this._disabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the passes of the task.\r\n     */\r\n    public get passes() {\r\n        return this._passes;\r\n    }\r\n\r\n    /**\r\n     * Gets the disabled passes of the task.\r\n     */\r\n    public get passesDisabled() {\r\n        return this._passesDisabled;\r\n    }\r\n\r\n    /**\r\n     * The (texture) dependencies of the task (optional).\r\n     */\r\n    public dependencies?: Set<FrameGraphTextureHandle>;\r\n\r\n    /**\r\n     * Records the task in the frame graph. Use this function to add content (render passes, ...) to the task.\r\n     * @param skipCreationOfDisabledPasses If true, the disabled passe(s) won't be created.\r\n     */\r\n    public abstract record(skipCreationOfDisabledPasses?: boolean): void;\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"FrameGraphTask\";\r\n    }\r\n\r\n    /**\r\n     * This function is called once after the task has been added to the frame graph and before the frame graph is built for the first time.\r\n     * This allows you to initialize asynchronous resources, which is not possible in the constructor.\r\n     * @returns A promise that resolves when the initialization is complete.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public initAsync(): Promise<unknown> {\r\n        return Promise.resolve();\r\n    }\r\n\r\n    /**\r\n     * An observable that is triggered after the textures have been allocated.\r\n     */\r\n    public onTexturesAllocatedObservable: Observable<FrameGraphRenderContext> = new Observable();\r\n\r\n    /**\r\n     * An observable that is triggered before the task is executed.\r\n     */\r\n    public onBeforeTaskExecute: Observable<FrameGraphTask> = new Observable();\r\n\r\n    /**\r\n     * An observable that is triggered after the task is executed.\r\n     */\r\n    public onAfterTaskExecute: Observable<FrameGraphTask> = new Observable();\r\n\r\n    /**\r\n     * Checks if the task is ready to be executed.\r\n     * @returns True if the task is ready to be executed, else false.\r\n     */\r\n    public isReady(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the task.\r\n     */\r\n    public dispose() {\r\n        this._reset();\r\n        this.onTexturesAllocatedObservable.clear();\r\n        this.onBeforeTaskExecute.clear();\r\n        this.onAfterTaskExecute.clear();\r\n    }\r\n\r\n    /**\r\n     * Constructs a new frame graph task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        this.name = name;\r\n        this._frameGraph = frameGraph;\r\n        this._reset();\r\n    }\r\n\r\n    /** @internal */\r\n    public _reset() {\r\n        for (const pass of this._passes) {\r\n            pass._dispose();\r\n        }\r\n        for (const pass of this._passesDisabled) {\r\n            pass._dispose();\r\n        }\r\n        this._passes.length = 0;\r\n        this._passesDisabled.length = 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public _addPass(pass: IFrameGraphPass, disabled: boolean) {\r\n        if (disabled) {\r\n            this._passesDisabled.push(pass);\r\n        } else {\r\n            this._passes.push(pass);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _checkTask() {\r\n        let outputTexture: Nullable<Nullable<InternalTexture>[]> = null;\r\n        let outputDepthTexture: Nullable<InternalTexture> = null;\r\n        let outputObjectList: FrameGraphObjectList | undefined;\r\n\r\n        for (const pass of this._passes) {\r\n            const errMsg = pass._isValid();\r\n            if (errMsg) {\r\n                throw new Error(`Pass \"${pass.name}\" is not valid. ${errMsg}`);\r\n            }\r\n            if (FrameGraphRenderPass.IsRenderPass(pass)) {\r\n                const handles = Array.isArray(pass.renderTarget) ? pass.renderTarget : [pass.renderTarget];\r\n                outputTexture = [];\r\n                for (const handle of handles) {\r\n                    if (handle !== undefined) {\r\n                        outputTexture.push(this._frameGraph.textureManager.getTextureFromHandle(handle));\r\n                    }\r\n                }\r\n                outputDepthTexture = pass.renderTargetDepth !== undefined ? this._frameGraph.textureManager.getTextureFromHandle(pass.renderTargetDepth) : null;\r\n            } else if (FrameGraphObjectListPass.IsObjectListPass(pass)) {\r\n                outputObjectList = pass.objectList;\r\n            }\r\n        }\r\n\r\n        let disabledOutputTexture: Nullable<Nullable<InternalTexture>[]> = null;\r\n        let disabledOutputTextureHandle: (FrameGraphTextureHandle | undefined)[] = [];\r\n        let disabledOutputDepthTexture: Nullable<InternalTexture> = null;\r\n        let disabledOutputObjectList: FrameGraphObjectList | undefined;\r\n\r\n        for (const pass of this._passesDisabled) {\r\n            const errMsg = pass._isValid();\r\n            if (errMsg) {\r\n                throw new Error(`Pass \"${pass.name}\" is not valid. ${errMsg}`);\r\n            }\r\n            if (FrameGraphRenderPass.IsRenderPass(pass)) {\r\n                const handles = Array.isArray(pass.renderTarget) ? pass.renderTarget : [pass.renderTarget];\r\n                disabledOutputTexture = [];\r\n                for (const handle of handles) {\r\n                    if (handle !== undefined) {\r\n                        disabledOutputTexture.push(this._frameGraph.textureManager.getTextureFromHandle(handle));\r\n                    }\r\n                }\r\n                disabledOutputTextureHandle = handles;\r\n                disabledOutputDepthTexture = pass.renderTargetDepth !== undefined ? this._frameGraph.textureManager.getTextureFromHandle(pass.renderTargetDepth) : null;\r\n            } else if (FrameGraphObjectListPass.IsObjectListPass(pass)) {\r\n                disabledOutputObjectList = pass.objectList;\r\n            }\r\n        }\r\n\r\n        if (this._passesDisabled.length > 0) {\r\n            if (!this._checkSameRenderTarget(outputTexture, disabledOutputTexture)) {\r\n                let ok = true;\r\n                for (const handle of disabledOutputTextureHandle) {\r\n                    if (handle !== undefined && !this._frameGraph.textureManager.isHistoryTexture(handle)) {\r\n                        ok = false;\r\n                        break;\r\n                    }\r\n                }\r\n                if (!ok) {\r\n                    throw new Error(`The output texture of the task \"${this.name}\" is different when it is enabled or disabled.`);\r\n                }\r\n            }\r\n            if (outputDepthTexture !== disabledOutputDepthTexture && disabledOutputDepthTexture !== null) {\r\n                throw new Error(`The output depth texture of the task \"${this.name}\" is different when it is enabled or disabled.`);\r\n            }\r\n            if (outputObjectList !== disabledOutputObjectList && disabledOutputObjectList !== null) {\r\n                throw new Error(`The output object list of the task \"${this.name}\" is different when it is enabled or disabled.`);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _execute() {\r\n        const passes = this._disabled && this._passesDisabled.length > 0 ? this._passesDisabled : this._passes;\r\n\r\n        this.onBeforeTaskExecute.notifyObservers(this);\r\n\r\n        this._frameGraph.engine._debugPushGroup?.(`${this.getClassName()} (${this.name})`);\r\n\r\n        try {\r\n            for (const pass of passes) {\r\n                pass._execute();\r\n            }\r\n        } finally {\r\n            this._frameGraph.engine._debugPopGroup?.();\r\n        }\r\n\r\n        this.onAfterTaskExecute.notifyObservers(this);\r\n    }\r\n\r\n    /** @internal */\r\n    public _initializePasses() {\r\n        this._frameGraph.engine._debugPushGroup?.(`${this.getClassName()} (${this.name})`);\r\n\r\n        try {\r\n            for (const pass of this._passes) {\r\n                pass._initialize();\r\n            }\r\n\r\n            for (const pass of this._passesDisabled) {\r\n                pass._initialize();\r\n            }\r\n        } finally {\r\n            this._frameGraph.engine._debugPopGroup?.();\r\n        }\r\n    }\r\n\r\n    private _checkSameRenderTarget(src: Nullable<Nullable<InternalTexture>[]>, dst: Nullable<Nullable<InternalTexture>[]>) {\r\n        if (src === null || dst === null) {\r\n            return src === dst;\r\n        }\r\n\r\n        if (src.length !== dst.length) {\r\n            return false;\r\n        }\r\n\r\n        for (let i = 0; i < src.length; i++) {\r\n            if (src[i] !== dst[i]) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n}\r\n","import { type FrameGraphTextureHandle } from \"core/index\";\r\nimport { backbufferColorTextureHandle } from \"../../frameGraphTypes\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Task which copies a texture to the backbuffer color texture.\r\n */\r\nexport class FrameGraphCopyToBackbufferColorTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to copy to the backbuffer color texture.\r\n     */\r\n    public sourceTexture: FrameGraphTextureHandle;\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphCopyToBackbufferColorTask\";\r\n    }\r\n\r\n    public record() {\r\n        if (this.sourceTexture === undefined) {\r\n            throw new Error(`FrameGraphCopyToBackbufferColorTask \"${this.name}\": sourceTexture is required`);\r\n        }\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.addDependencies(this.sourceTexture);\r\n\r\n        pass.setRenderTarget(backbufferColorTextureHandle);\r\n        pass.setExecuteFunc((context) => {\r\n            if (!context.isBackbuffer(this.sourceTexture)) {\r\n                context.copyTexture(this.sourceTexture);\r\n            }\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setRenderTarget(backbufferColorTextureHandle);\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n}\r\n","import { type Nullable, type TextureSize, type FrameGraphContext } from \"core/index\";\r\n\r\n/**\r\n * Represents a texture handle in the frame graph.\r\n */\r\nexport type FrameGraphTextureHandle = number;\r\n\r\n/**\r\n * Represents a texture handle for the backbuffer color texture.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const backbufferColorTextureHandle: FrameGraphTextureHandle = 0;\r\n\r\n/**\r\n * Represents a texture handle for the backbuffer depth/stencil texture.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const backbufferDepthStencilTextureHandle: FrameGraphTextureHandle = 1;\r\n\r\n/**\r\n * Options used to describe a texture to be created in the frame graph.\r\n */\r\nexport type FrameGraphTextureOptions = {\r\n    /** Specifies if mipmaps must be created for the textures (default: false) */\r\n    createMipMaps?: boolean;\r\n\r\n    /** Defines sample count (default: 1) */\r\n    samples?: number;\r\n\r\n    /**\r\n     * Define the type of the textures (of Constants.TEXTURE_2D, .TEXTURE_2D_ARRAY, .TEXTURE_CUBE_MAP, .TEXTURE_CUBE_MAP_ARRAY, .TEXTURE_3D).\r\n     */\r\n    targetTypes?: number[];\r\n\r\n    /**\r\n     * Define the number of layers of the textures (if applicable, given the corresponding targetType) (for Constants.TEXTURE_3D, .TEXTURE_2D_ARRAY, and .TEXTURE_CUBE_MAP_ARRAY)\r\n     */\r\n    layerCounts?: number[];\r\n\r\n    /** Defines the type of the texture channels (UNSIGNED_BYTE, FLOAT, etc.) */\r\n    types?: number[];\r\n\r\n    /** Defines the format of the textures (RED, RG, RGB, RGBA, ALPHA...) */\r\n    formats?: number[];\r\n\r\n    /** Defines if sRGB format should be used for each of texture */\r\n    useSRGBBuffers?: boolean[];\r\n\r\n    /** Defines the creation flags of the textures (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg) */\r\n    creationFlags?: number[];\r\n\r\n    /** Defines the names of the textures (used for debugging purpose) */\r\n    labels?: string[];\r\n};\r\n\r\n/**\r\n * Options used to create a texture / list of textures in the frame graph.\r\n */\r\nexport type FrameGraphTextureCreationOptions = {\r\n    /** Size of the textures. If sizeIsPercentage is true, these are percentages relative to the screen size (100 = 100%) */\r\n    size: TextureSize;\r\n\r\n    /** Options used to create the textures */\r\n    options: FrameGraphTextureOptions;\r\n\r\n    /** If true, indicates that \"size\" is percentages relative to the screen size */\r\n    sizeIsPercentage: boolean;\r\n\r\n    /** Indicates that the texture is a history texture (default: false) */\r\n    isHistoryTexture?: boolean;\r\n};\r\n\r\n/**\r\n * Represents a texture description in the frame graph.\r\n * This is basically the same thing than FrameGraphTextureCreationOptions, but the size is never in percentage and always in pixels.\r\n */\r\nexport type FrameGraphTextureDescription = {\r\n    /** Size of the texture */\r\n    size: { width: number; height: number };\r\n\r\n    /** Options used to create the texture */\r\n    options: FrameGraphTextureOptions;\r\n};\r\n\r\n/**\r\n * Defines a pass in the frame graph.\r\n */\r\nexport interface IFrameGraphPass {\r\n    /**\r\n     * The name of the pass.\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * Whether the pass is disabled.\r\n     */\r\n    disabled: boolean;\r\n\r\n    /**\r\n     * Initializes the pass.\r\n     * This function is called once before the first execution of the pass.\r\n     * @param func The function to initialize the pass.\r\n     */\r\n    setInitializeFunc(func: (context: FrameGraphContext) => void): void;\r\n\r\n    /**\r\n     * Sets the function to execute when the pass is executed\r\n     * @param func The function to execute when the pass is executed\r\n     */\r\n    setExecuteFunc(func: (context: FrameGraphContext) => void): void;\r\n\r\n    /** @internal */\r\n    _initialize(): void;\r\n\r\n    /** @internal */\r\n    _execute(): void;\r\n\r\n    /** @internal */\r\n    _isValid(): Nullable<string>;\r\n\r\n    /** @internal */\r\n    _dispose(): void;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraph, type NodeRenderGraphBuildState, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { FrameGraphCopyToBackbufferColorTask } from \"../../Tasks/Texture/copyToBackbufferColorTask\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to generate the final graph\r\n */\r\nexport class NodeRenderGraphOutputBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphCopyToBackbufferColorTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphOutputBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"texture\", NodeRenderGraphBlockConnectionPointTypes.Texture);\r\n        this._addDependenciesInput();\r\n\r\n        this.texture.addAcceptedConnectionPointTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAll);\r\n\r\n        this._frameGraphTask = new FrameGraphCopyToBackbufferColorTask(name, frameGraph);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphOutputBlock\";\r\n    }\r\n    /**\r\n     * Gets the texture input component\r\n     */\r\n    public get texture(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.name = this.name;\r\n\r\n        const textureConnectedPoint = this.texture.connectedPoint;\r\n        if (textureConnectedPoint) {\r\n            this._frameGraphTask.sourceTexture = textureConnectedPoint.value as FrameGraphTextureHandle;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for outputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterOutputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphOutputBlock\", NodeRenderGraphOutputBlock);\r\n}\r\n","import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { EffectRenderer, EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { type IRenderTargetTexture, type RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { type ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Nullable } from \"core/types\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Conversion modes available when copying a texture into another one\r\n */\r\nexport const enum ConversionMode {\r\n    None = 0,\r\n    ToLinearSpace = 1,\r\n    ToGammaSpace = 2,\r\n}\r\n\r\n/**\r\n * Class used for fast copy from one texture to another\r\n */\r\nexport class CopyTextureToTexture {\r\n    private _engine: AbstractEngine;\r\n    private _isDepthTexture: boolean;\r\n    private _renderer: EffectRenderer;\r\n    private _effectWrapper: EffectWrapper;\r\n    private _source: InternalTexture | ThinTexture;\r\n    private _conversion: number;\r\n    private _lodLevel: number;\r\n\r\n    /** Shader language used */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Gets the effect wrapper used for the copy\r\n     */\r\n    public get effectWrapper() {\r\n        return this._effectWrapper;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the source texture\r\n     */\r\n    public get source() {\r\n        return this._source;\r\n    }\r\n\r\n    public set source(texture: InternalTexture | ThinTexture) {\r\n        this._source = texture;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the LOD level to copy from the source texture\r\n     */\r\n    public get lodLevel(): number {\r\n        return this._lodLevel;\r\n    }\r\n\r\n    public set lodLevel(level: number) {\r\n        this._lodLevel = level;\r\n    }\r\n\r\n    private _textureIsInternal(texture: InternalTexture | ThinTexture): texture is InternalTexture {\r\n        return (texture as ThinTexture).getInternalTexture === undefined;\r\n    }\r\n\r\n    /**\r\n     * Constructs a new instance of the class\r\n     * @param engine The engine to use for the copy\r\n     * @param isDepthTexture True means that we should write (using gl_FragDepth) into the depth texture attached to the destination (default: false)\r\n     * @param sameSizeCopy True means that the copy will be done without any sampling (more efficient, but requires the source and destination to be of the same size) (default: false)\r\n     */\r\n    constructor(engine: AbstractEngine, isDepthTexture = false, sameSizeCopy = false) {\r\n        this._engine = engine;\r\n        this._isDepthTexture = isDepthTexture;\r\n        this._lodLevel = 0;\r\n        this._conversion = ConversionMode.None;\r\n\r\n        this._renderer = new EffectRenderer(engine);\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(isDepthTexture, sameSizeCopy);\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n    private async _initShaderSourceAsync(isDepthTexture: boolean, sameSizeCopy: boolean) {\r\n        const engine = this._engine;\r\n\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await import(\"../ShadersWGSL/copyTextureToTexture.fragment\");\r\n        } else {\r\n            await import(\"../Shaders/copyTextureToTexture.fragment\");\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n\r\n        const defines: string[] = [];\r\n\r\n        if (isDepthTexture) {\r\n            defines.push(\"#define DEPTH_TEXTURE\");\r\n        }\r\n        if (sameSizeCopy) {\r\n            defines.push(\"#define NO_SAMPLER\");\r\n        }\r\n\r\n        this._effectWrapper = new EffectWrapper({\r\n            engine: engine,\r\n            name: \"CopyTextureToTexture\",\r\n            fragmentShader: \"copyTextureToTexture\",\r\n            useShaderStore: true,\r\n            uniformNames: [\"conversion\", \"lodLevel\"],\r\n            samplerNames: [\"textureSampler\"],\r\n            defines,\r\n            shaderLanguage: this._shaderLanguage,\r\n        });\r\n\r\n        this._effectWrapper.onApplyObservable.add(() => {\r\n            if (isDepthTexture) {\r\n                engine.setState(false);\r\n                engine.setDepthBuffer(true);\r\n                engine.depthCullingState.depthMask = true;\r\n                engine.depthCullingState.depthFunc = Constants.ALWAYS;\r\n            } else {\r\n                engine.depthCullingState.depthMask = false;\r\n                // other states are already set by EffectRenderer.applyEffectWrapper\r\n            }\r\n\r\n            if (this._textureIsInternal(this._source)) {\r\n                this._effectWrapper.effect._bindTexture(\"textureSampler\", this._source);\r\n            } else {\r\n                this._effectWrapper.effect.setTexture(\"textureSampler\", this._source);\r\n            }\r\n            this._effectWrapper.effect.setFloat(\"conversion\", this._conversion);\r\n            this._effectWrapper.effect.setFloat(\"lodLevel\", this._lodLevel);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Indicates if the effect is ready to be used for the copy\r\n     * @returns true if \"copy\" can be called without delay, else false\r\n     */\r\n    public isReady(): boolean {\r\n        return this._shadersLoaded && !!this._effectWrapper?.effect?.isReady();\r\n    }\r\n\r\n    /**\r\n     * Copy one texture into another\r\n     * @param source The source texture\r\n     * @param destination The destination texture. If null, copy the source to the currently bound framebuffer\r\n     * @param conversion The conversion mode that should be applied when copying\r\n     * @param lod The LOD level to copy from the source texture\r\n     * @returns\r\n     */\r\n    public copy(\r\n        source: InternalTexture | ThinTexture,\r\n        destination: Nullable<RenderTargetWrapper | IRenderTargetTexture> = null,\r\n        conversion = ConversionMode.None,\r\n        lod = 0\r\n    ): boolean {\r\n        if (!this.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        this._source = source;\r\n        this._conversion = conversion;\r\n        this._lodLevel = lod;\r\n\r\n        const engineDepthFunc = this._engine.getDepthFunction();\r\n        const engineDepthMask = this._engine.getDepthWrite(); // for some reasons, depthWrite is not restored by EffectRenderer.restoreStates\r\n\r\n        this._renderer.render(this._effectWrapper, destination);\r\n\r\n        this._engine.setDepthWrite(engineDepthMask);\r\n\r\n        if (this._isDepthTexture && engineDepthFunc) {\r\n            this._engine.setDepthFunction(engineDepthFunc);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Releases all the resources used by the class\r\n     */\r\n    public dispose(): void {\r\n        this._effectWrapper?.dispose();\r\n        this._renderer.dispose();\r\n    }\r\n}\r\n","import { type AbstractEngine, type FrameGraphTextureManager, type Scene, type FrameGraphTextureHandle, type Nullable, type InternalTexture, type IViewportLike } from \"core/index\";\r\n\r\n/**\r\n * Base class for frame graph context.\r\n */\r\nexport class FrameGraphContext {\r\n    private _depthTest: boolean;\r\n    private _depthWrite: boolean;\r\n\r\n    /**\r\n     * If true, debug markers will be enabled in the context.\r\n     */\r\n    public enableDebugMarkers = true;\r\n\r\n    /** @internal */\r\n    constructor(\r\n        protected readonly _engine: AbstractEngine,\r\n        protected readonly _textureManager: FrameGraphTextureManager,\r\n        protected readonly _scene: Scene\r\n    ) {}\r\n\r\n    /**\r\n     * Renders a component without managing the render target.\r\n     * Use this method when you have a component that handles its own rendering logic which is not fully integrated into the frame graph system.\r\n     * @param component The component to render.\r\n     * @param intermediateRendering If true, the scene's intermediate rendering flag will be set to true during the render call (default: true)\r\n     */\r\n    public renderUnmanaged(component: { render: () => void }, intermediateRendering = true): void {\r\n        const currentRenderTarget = this._engine._currentRenderTarget;\r\n\r\n        this._scene.incrementRenderId();\r\n        this._scene.resetCachedMaterial();\r\n\r\n        this._scene._intermediateRendering = intermediateRendering;\r\n\r\n        component.render();\r\n\r\n        this._scene._intermediateRendering = false;\r\n\r\n        if (this._engine._currentRenderTarget !== currentRenderTarget) {\r\n            if (!currentRenderTarget) {\r\n                this._engine.restoreDefaultFramebuffer(true);\r\n            } else {\r\n                this._engine.bindFramebuffer(currentRenderTarget);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a texture from a handle.\r\n     * Note that if the texture is a history texture, the read texture for the current frame will be returned.\r\n     * @param handle The handle of the texture\r\n     * @returns The texture or null if not found\r\n     */\r\n    public getTextureFromHandle(handle: FrameGraphTextureHandle): Nullable<InternalTexture> {\r\n        return this._textureManager.getTextureFromHandle(handle);\r\n    }\r\n\r\n    /**\r\n     * Pushes a debug group to the engine's debug stack.\r\n     * @param name The name of the debug group\r\n     */\r\n    public pushDebugGroup(name: string) {\r\n        this.enableDebugMarkers && this._engine._debugPushGroup?.(name);\r\n    }\r\n\r\n    /**\r\n     * Pops a debug group from the engine's debug stack.\r\n     */\r\n    public popDebugGroup() {\r\n        this.enableDebugMarkers && this._engine._debugPopGroup?.();\r\n    }\r\n\r\n    /**\r\n     * Inserts a debug marker in the engine's debug stack.\r\n     * @param text The text of the debug marker\r\n     */\r\n    public insertDebugMarker(text: string) {\r\n        this.enableDebugMarkers && this._engine._debugInsertMarker?.(text);\r\n    }\r\n\r\n    /**\r\n     * Saves the current depth states (depth testing and depth writing)\r\n     */\r\n    public saveDepthStates(): void {\r\n        this._depthTest = this._engine.getDepthBuffer();\r\n        this._depthWrite = this._engine.getDepthWrite();\r\n    }\r\n\r\n    /**\r\n     * Restores the depth states saved by saveDepthStates\r\n     */\r\n    public restoreDepthStates(): void {\r\n        this._engine.setDepthBuffer(this._depthTest);\r\n        this._engine.setDepthWrite(this._depthWrite);\r\n    }\r\n\r\n    /**\r\n     * Sets the depth states for the current render target\r\n     * @param depthTest If true, depth testing is enabled\r\n     * @param depthWrite If true, depth writing is enabled\r\n     */\r\n    public setDepthStates(depthTest: boolean, depthWrite: boolean): void {\r\n        this._engine.setDepthBuffer(depthTest);\r\n        this._engine.setDepthWrite(depthWrite);\r\n    }\r\n\r\n    /**\r\n     * Sets the current viewport\r\n     * @param viewport defines the viewport element to be used\r\n     * @param requiredWidth defines the width required for rendering. If not provided, the width of the render texture is used.\r\n     * @param requiredHeight defines the height required for rendering. If not provided the height of the render texture is used.\r\n     */\r\n    public setViewport(viewport: IViewportLike, requiredWidth?: number, requiredHeight?: number): void {\r\n        this._engine.setViewport(viewport, requiredWidth, requiredHeight);\r\n    }\r\n}\r\n","import {\r\n    type Nullable,\r\n    type AbstractEngine,\r\n    type DrawWrapper,\r\n    type IColor4Like,\r\n    type Layer,\r\n    type FrameGraphTextureHandle,\r\n    type Effect,\r\n    type FrameGraphTextureManager,\r\n    type ObjectRenderer,\r\n    type Scene,\r\n    type FrameGraphRenderTarget,\r\n    type InternalTexture,\r\n    type UtilityLayerRenderer,\r\n    type IStencilState,\r\n    type IStencilStateProperties,\r\n} from \"core/index\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EffectRenderer } from \"../Materials/effectRenderer.pure\";\r\nimport { CopyTextureToTexture } from \"../Misc/copyTextureToTexture\";\r\nimport { FrameGraphContext } from \"./frameGraphContext\";\r\nimport { IsDepthTexture } from \"../Materials/Textures/textureHelper.functions\";\r\n\r\nconst SamplingModeHasMipMapFiltering = [\r\n    false, // not used\r\n    false, // TEXTURE_NEAREST_SAMPLINGMODE / TEXTURE_NEAREST_NEAREST\r\n    false, // TEXTURE_BILINEAR_SAMPLINGMODE / TEXTURE_LINEAR_LINEAR\r\n    true, // TEXTURE_TRILINEAR_SAMPLINGMODE / TEXTURE_LINEAR_LINEAR_MIPLINEAR\r\n    true, // TEXTURE_NEAREST_NEAREST_MIPNEAREST\r\n    true, // TEXTURE_NEAREST_LINEAR_MIPNEAREST\r\n    true, // TEXTURE_NEAREST_LINEAR_MIPLINEAR\r\n    false, // TEXTURE_NEAREST_LINEAR\r\n    true, // TEXTURE_NEAREST_NEAREST_MIPLINEAR\r\n    true, // TEXTURE_LINEAR_NEAREST_MIPNEAREST\r\n    true, // TEXTURE_LINEAR_NEAREST_MIPLINEAR\r\n    true, // TEXTURE_LINEAR_LINEAR_MIPNEAREST\r\n    false, // TEXTURE_LINEAR_NEAREST\r\n];\r\n\r\n/**\r\n * Frame graph context used render passes.\r\n */\r\nexport class FrameGraphRenderContext extends FrameGraphContext {\r\n    private readonly _effectRenderer: EffectRenderer;\r\n    private readonly _effectRendererBack: EffectRenderer;\r\n    private _currentRenderTarget: FrameGraphRenderTarget | undefined;\r\n    private _renderTargetIsBound = true;\r\n    private readonly _copyTexture: CopyTextureToTexture;\r\n    private readonly _copyDepthTexture: CopyTextureToTexture;\r\n\r\n    private static _IsObjectRenderer(value: Layer | ObjectRenderer | UtilityLayerRenderer): value is ObjectRenderer {\r\n        return (value as ObjectRenderer).initRender !== undefined;\r\n    }\r\n\r\n    /** @internal */\r\n    constructor(engine: AbstractEngine, textureManager: FrameGraphTextureManager, scene: Scene) {\r\n        super(engine, textureManager, scene);\r\n        this._effectRenderer = new EffectRenderer(this._engine);\r\n        this._effectRendererBack = new EffectRenderer(this._engine, {\r\n            positions: [1, 1, -1, 1, -1, -1, 1, -1],\r\n            indices: [0, 2, 1, 0, 3, 2],\r\n        });\r\n        this._copyTexture = new CopyTextureToTexture(this._engine);\r\n        this._copyDepthTexture = new CopyTextureToTexture(this._engine, true);\r\n    }\r\n\r\n    /**\r\n     * Checks whether a texture handle points to the backbuffer's color or depth texture\r\n     * @param handle The handle to check\r\n     * @returns True if the handle points to the backbuffer's color or depth texture, otherwise false\r\n     */\r\n    public isBackbuffer(handle: FrameGraphTextureHandle): boolean {\r\n        return this._textureManager._isBackbuffer(handle);\r\n    }\r\n\r\n    /**\r\n     * Checks whether a texture handle points to the backbuffer's color texture\r\n     * @param handle The handle to check\r\n     * @returns True if the handle points to the backbuffer's color texture, otherwise false\r\n     */\r\n    public isBackbufferColor(handle: FrameGraphTextureHandle): boolean {\r\n        return this._textureManager.isBackbufferColor(handle);\r\n    }\r\n\r\n    /**\r\n     * Checks whether a texture handle points to the backbuffer's depth texture\r\n     * @param handle The handle to check\r\n     * @returns True if the handle points to the backbuffer's depth texture, otherwise false\r\n     */\r\n    public isBackbufferDepthStencil(handle: FrameGraphTextureHandle): boolean {\r\n        return this._textureManager.isBackbufferDepthStencil(handle);\r\n    }\r\n\r\n    /**\r\n     * Creates a (frame graph) render target wrapper\r\n     * Note that renderTargets or renderTargetDepth can be undefined, but not both at the same time!\r\n     * @param name Name of the render target wrapper\r\n     * @param renderTargets Render target handles (textures) to use\r\n     * @param renderTargetDepth Render target depth handle (texture) to use\r\n     * @param depthReadOnly If true, the depth buffer will be read-only\r\n     * @param stencilReadOnly If true, the stencil buffer will be read-only\r\n     * @returns The created render target wrapper\r\n     */\r\n    public createRenderTarget(\r\n        name: string,\r\n        renderTargets?: FrameGraphTextureHandle | FrameGraphTextureHandle[],\r\n        renderTargetDepth?: FrameGraphTextureHandle,\r\n        depthReadOnly?: boolean,\r\n        stencilReadOnly?: boolean\r\n    ): FrameGraphRenderTarget {\r\n        return this._textureManager.createRenderTarget(name, renderTargets, renderTargetDepth, depthReadOnly, stencilReadOnly);\r\n    }\r\n\r\n    /**\r\n     * Clears the current render buffer or the current render target (if any is set up)\r\n     * @param color Defines the color to use\r\n     * @param backBuffer Defines if the back buffer must be cleared\r\n     * @param depth Defines if the depth buffer must be cleared\r\n     * @param stencil Defines if the stencil buffer must be cleared\r\n     * @param stencilClearValue Defines the value to use to clear the stencil buffer (default is 0)\r\n     */\r\n    public clear(color: Nullable<IColor4Like>, backBuffer: boolean, depth: boolean, stencil?: boolean, stencilClearValue = 0): void {\r\n        this._applyRenderTarget();\r\n        this._engine.clear(color, backBuffer, depth, stencil, stencilClearValue);\r\n    }\r\n\r\n    /**\r\n     * Clears the color attachments of the current render target.\r\n     *\r\n     * Float, signed-integer, and unsigned-integer attachments can be mixed in the same layout.\r\n     * @param color Defines the color to use\r\n     * @param attachments The attachments to clear\r\n     */\r\n    public clearColorAttachments(color: Nullable<IColor4Like>, attachments: number[]): void {\r\n        this._applyRenderTarget();\r\n        this._engine.clearAttachments(color, attachments, true, false, false);\r\n    }\r\n\r\n    /**\r\n     * Clears all attachments (color(s) + depth/stencil) of the current render target\r\n     * @param color Defines the color to use\r\n     * @param attachments The attachments to clear\r\n     * @param backBuffer Defines if the back buffer must be cleared\r\n     * @param depth Defines if the depth buffer must be cleared\r\n     * @param stencil Defines if the stencil buffer must be cleared\r\n     * @param stencilClearValue Defines the value to use to clear the stencil buffer (default is 0)\r\n     */\r\n    public clearAttachments(color: Nullable<IColor4Like>, attachments: number[], backBuffer: boolean, depth: boolean, stencil?: boolean, stencilClearValue = 0): void {\r\n        this._applyRenderTarget();\r\n        this._engine.clearAttachments(color, attachments, backBuffer, depth, stencil, stencilClearValue);\r\n    }\r\n\r\n    /**\r\n     * Binds the attachments to the current render target\r\n     * @param attachments The attachments to bind\r\n     */\r\n    public bindAttachments(attachments: number[]): void {\r\n        this._applyRenderTarget();\r\n        this._engine.bindAttachments(attachments);\r\n    }\r\n\r\n    /**\r\n     * Generates mipmaps for the current render target\r\n     * @param handle Optional handle of the texture to generate mipmaps for (if not provided, will generate mipmaps for all textures in the current render target)\r\n     */\r\n    public generateMipMaps(handle?: FrameGraphTextureHandle): void {\r\n        if (handle !== undefined) {\r\n            const internalTexture = this._textureManager.getTextureFromHandle(handle);\r\n            if (internalTexture) {\r\n                this._engine.generateMipmaps(internalTexture);\r\n            }\r\n            return;\r\n        }\r\n        if (this._currentRenderTarget?.renderTargetWrapper === undefined) {\r\n            return;\r\n        }\r\n\r\n        if (this._engine._currentRenderTarget && (!this._engine.isWebGPU || this._renderTargetIsBound)) {\r\n            // we can't generate the mipmaps if the render target (which is the texture we want to generate mipmaps for) is bound\r\n            // Also, for some reasons, on WebGL2, generating mipmaps doesn't work if a render target is bound, even if it's not the texture we want to generate mipmaps for...\r\n            this._engine.unBindFramebuffer(this._engine._currentRenderTarget);\r\n            this._renderTargetIsBound = false;\r\n        }\r\n\r\n        const textures = this._currentRenderTarget.renderTargetWrapper.textures;\r\n        if (textures) {\r\n            for (const texture of textures) {\r\n                this._engine.generateMipmaps(texture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the texture sampling mode for a given texture handle\r\n     * @param handle Handle of the texture to set the sampling mode for\r\n     * @param samplingMode Sampling mode to set\r\n     */\r\n    public setTextureSamplingMode(handle: FrameGraphTextureHandle, samplingMode: number): void {\r\n        const internalTexture = this._textureManager.getTextureFromHandle(handle);\r\n        if (internalTexture && internalTexture.samplingMode !== samplingMode) {\r\n            internalTexture.useMipMaps = SamplingModeHasMipMapFiltering[samplingMode];\r\n            this._engine.updateTextureSamplingMode(samplingMode, internalTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds a texture handle to a given effect (resolves the handle to a texture and binds it to the effect)\r\n     * @param effect The effect to bind the texture to\r\n     * @param name The name of the texture in the effect\r\n     * @param handle The handle of the texture to bind\r\n     */\r\n    public bindTextureHandle(effect: Effect, name: string, handle: FrameGraphTextureHandle): void {\r\n        let texture: Nullable<InternalTexture>;\r\n\r\n        const historyEntry = this._textureManager._historyTextures.get(handle);\r\n        if (historyEntry) {\r\n            texture = historyEntry.textures[historyEntry.index]; // texture we write to in this frame\r\n            if (\r\n                this._currentRenderTarget !== undefined &&\r\n                this._currentRenderTarget.renderTargetWrapper !== undefined &&\r\n                this._currentRenderTarget.renderTargetWrapper.textures!.includes(texture!)\r\n            ) {\r\n                // If the current render target renders to the history write texture, we bind the read texture instead\r\n                texture = historyEntry.textures[historyEntry.index ^ 1];\r\n            }\r\n        } else {\r\n            texture = this._textureManager._textures.get(handle)!.texture;\r\n        }\r\n\r\n        effect._bindTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Applies a full-screen effect to the current render target\r\n     * @param drawWrapper The draw wrapper containing the effect to apply\r\n     * @param customBindings The custom bindings to use when applying the effect (optional)\r\n     * @param stencilState The stencil state to use when applying the effect (optional)\r\n     * @param disableColorWrite If true, color write will be disabled when applying the effect (optional)\r\n     * @param drawBackFace If true, the fullscreen quad will be drawn as a back face (in CW - optional)\r\n     * @param depthTest If true, depth testing will be enabled when applying the effect (default is false)\r\n     * @param noViewport If true, the current viewport will be left unchanged (optional). If false or undefined, the viewport will be set to the full render target size.\r\n     * @param alphaMode The alpha mode to use when applying the effect (default is ALPHA_DISABLE)\r\n     * @returns True if the effect was applied, otherwise false (effect not ready)\r\n     */\r\n    public applyFullScreenEffect(\r\n        drawWrapper: DrawWrapper,\r\n        customBindings?: () => void,\r\n        stencilState?: IStencilState | IStencilStateProperties,\r\n        disableColorWrite?: boolean,\r\n        drawBackFace?: boolean,\r\n        depthTest?: boolean,\r\n        noViewport?: boolean,\r\n        alphaMode = Constants.ALPHA_DISABLE\r\n    ): boolean {\r\n        if (!drawWrapper.effect?.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        this._applyRenderTarget();\r\n\r\n        const engineDepthMask = this._engine.getDepthWrite(); // for some reasons, depthWrite is not restored by EffectRenderer.restoreStates\r\n        const engineDepthFunc = this._engine.getDepthFunction();\r\n\r\n        const effectRenderer = drawBackFace ? this._effectRendererBack : this._effectRenderer;\r\n\r\n        effectRenderer.saveStates();\r\n        if (!noViewport) {\r\n            effectRenderer.setViewport();\r\n        }\r\n\r\n        this._engine.enableEffect(drawWrapper);\r\n        this._engine.setState(false, undefined, undefined, undefined, undefined, stencilState);\r\n        this._engine.setDepthBuffer(!!depthTest);\r\n        if (disableColorWrite) {\r\n            this._engine.setColorWrite(false);\r\n        }\r\n        this._engine.setDepthWrite(false);\r\n        this._engine.setAlphaMode(alphaMode);\r\n\r\n        effectRenderer.bindBuffers(drawWrapper.effect);\r\n        customBindings?.();\r\n        effectRenderer.draw();\r\n        effectRenderer.restoreStates();\r\n        if (disableColorWrite) {\r\n            this._engine.setColorWrite(true);\r\n        }\r\n        this._engine.setDepthWrite(engineDepthMask);\r\n        if (engineDepthFunc) {\r\n            this._engine.setDepthFunction(engineDepthFunc);\r\n        }\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Copies a texture to the current render target\r\n     * @param sourceTexture The source texture to copy from\r\n     * @param forceCopyToBackbuffer If true, the copy will be done to the back buffer regardless of the current render target\r\n     * @param noViewport If true, the current viewport will be left unchanged (optional). If false or undefined, the viewport will be set to the full render target size.\r\n     * @param lodLevel The LOD level to use when copying the texture (default: 0).\r\n     */\r\n    public copyTexture(sourceTexture: FrameGraphTextureHandle, forceCopyToBackbuffer = false, noViewport?: boolean, lodLevel = 0): void {\r\n        if (forceCopyToBackbuffer) {\r\n            this.bindRenderTarget();\r\n        }\r\n\r\n        const texture = this._textureManager.getTextureFromHandle(sourceTexture, true)!;\r\n        const copyTexture = IsDepthTexture(texture.format) ? this._copyDepthTexture : this._copyTexture;\r\n\r\n        copyTexture.source = texture;\r\n        copyTexture.lodLevel = lodLevel;\r\n\r\n        this.applyFullScreenEffect(\r\n            copyTexture.effectWrapper.drawWrapper,\r\n            () => {\r\n                copyTexture.effectWrapper.onApplyObservable.notifyObservers({});\r\n            },\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            noViewport\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Renders a RenderTargetTexture or a layer\r\n     * @param object The RenderTargetTexture/Layer to render\r\n     * @param viewportWidth The width of the viewport (optional for Layer, but mandatory for ObjectRenderer)\r\n     * @param viewportHeight The height of the viewport (optional for Layer, but mandatory for ObjectRenderer)\r\n     * @param restoreDefaultFramebuffer If true, the default framebuffer will be restored after rendering (default: false)\r\n     */\r\n    public render(object: Layer | ObjectRenderer | UtilityLayerRenderer, viewportWidth?: number, viewportHeight?: number, restoreDefaultFramebuffer = false): void {\r\n        if (FrameGraphRenderContext._IsObjectRenderer(object)) {\r\n            this._scene._intermediateRendering = true;\r\n            if (object.shouldRender()) {\r\n                this._scene.incrementRenderId();\r\n                this._scene.resetCachedMaterial();\r\n\r\n                object.prepareRenderList();\r\n\r\n                object.initRender(viewportWidth!, viewportHeight!);\r\n\r\n                this._applyRenderTarget();\r\n\r\n                object.render();\r\n\r\n                object.finishRender();\r\n\r\n                if (restoreDefaultFramebuffer) {\r\n                    this.restoreDefaultFramebuffer();\r\n                }\r\n            }\r\n            this._scene._intermediateRendering = false;\r\n        } else {\r\n            this._applyRenderTarget();\r\n            object.render();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds a render target texture so that upcoming draw calls will render to it\r\n     * Note: it is a lazy operation, so the render target will only be bound when needed. This way, it is possible to call\r\n     *   this method several times with different render targets without incurring the cost of binding if no draw calls are made\r\n     * @param renderTarget The handle of the render target texture to bind (default: undefined, meaning \"back buffer\"). Pass an array for MRT rendering.\r\n     * @param applyImmediately If true, the render target will be applied immediately (otherwise it will be applied at first use). Default is false (delayed application).\r\n     */\r\n    public bindRenderTarget(renderTarget?: FrameGraphRenderTarget, applyImmediately = false): void {\r\n        this._currentRenderTarget = renderTarget?.renderTargetWrapper === undefined ? undefined : renderTarget;\r\n        this._renderTargetIsBound = false;\r\n        if (applyImmediately) {\r\n            this._applyRenderTarget();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Restores the default framebuffer (back buffer) as the current render target\r\n     */\r\n    public restoreDefaultFramebuffer(): void {\r\n        this._engine.restoreDefaultFramebuffer(true);\r\n        this._renderTargetIsBound = false;\r\n        this._currentRenderTarget = undefined;\r\n    }\r\n\r\n    /** @internal */\r\n    public _applyRenderTarget() {\r\n        if (this._renderTargetIsBound) {\r\n            return;\r\n        }\r\n\r\n        const renderTargetWrapper = this._currentRenderTarget?.renderTargetWrapper;\r\n\r\n        if (renderTargetWrapper === undefined) {\r\n            if (this._engine._currentRenderTarget) {\r\n                this._engine.restoreDefaultFramebuffer(true);\r\n            }\r\n        } else if (this._engine._currentRenderTarget !== renderTargetWrapper) {\r\n            if (this._engine._currentRenderTarget) {\r\n                this._engine.unBindFramebuffer(this._engine._currentRenderTarget);\r\n            }\r\n            this._engine.bindFramebuffer(renderTargetWrapper);\r\n        }\r\n\r\n        this._renderTargetIsBound = true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _isReady(): boolean {\r\n        return this._copyTexture.isReady() && this._copyDepthTexture.isReady();\r\n    }\r\n\r\n    /** @internal */\r\n    public _dispose() {\r\n        this._effectRenderer.dispose();\r\n        this._effectRendererBack.dispose();\r\n        this._copyTexture.dispose();\r\n        this._copyDepthTexture.dispose();\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type InternalTexture } from \"./internalTexture\";\r\n\r\n/**\r\n * Define options used to create an internal texture\r\n */\r\nexport interface InternalTextureCreationOptions {\r\n    /** Specifies if mipmaps must be created. If undefined, the value from generateMipMaps is taken instead */\r\n    createMipMaps?: boolean;\r\n    /** Specifies if mipmaps must be generated */\r\n    generateMipMaps?: boolean;\r\n    /** Defines texture type (unsigned byte by default) */\r\n    type?: number;\r\n    /** Defines sampling mode (trilinear by default) */\r\n    samplingMode?: number;\r\n    /** Defines format (RGBA by default) */\r\n    format?: number;\r\n    /** Defines sample count (1 by default) */\r\n    samples?: number;\r\n    /** Texture creation flags */\r\n    creationFlags?: number;\r\n    /** Creates the RTT in sRGB space */\r\n    useSRGBBuffer?: boolean;\r\n    /** Label of the texture (used for debugging only) */\r\n    label?: string;\r\n    /** If the MSAA texture must be created right away (default: false) */\r\n    createMSAATexture?: boolean;\r\n    /** Comparison function. Used only for depth textures (default: 0) */\r\n    comparisonFunction?: number;\r\n    /** If the created texture is a cube texture */\r\n    isCube?: boolean;\r\n}\r\n\r\n/**\r\n * Define options used to create a render target texture\r\n */\r\nexport interface RenderTargetCreationOptions extends InternalTextureCreationOptions {\r\n    /** Specifies whether or not a depth should be allocated in the texture (true by default) */\r\n    generateDepthBuffer?: boolean;\r\n    /** Specifies whether or not a stencil should be allocated in the texture (false by default)*/\r\n    generateStencilBuffer?: boolean;\r\n    /** Specifies that no color target should be bound to the render target (useful if you only want to write to the depth buffer, for eg) */\r\n    noColorAttachment?: boolean;\r\n    /** Specifies the internal texture to use directly instead of creating one (ignores `noColorAttachment` flag when set) **/\r\n    colorAttachment?: InternalTexture;\r\n}\r\n\r\n/**\r\n * Define options used to create a depth texture\r\n */\r\nexport interface DepthTextureCreationOptions {\r\n    /** Specifies whether or not a stencil should be allocated in the texture. Not used if depthTextureFormat is supplied, in which case stencil creation will depend on this value. */\r\n    generateStencil?: boolean;\r\n    /** Specifies whether or not bilinear filtering is enable on the texture */\r\n    bilinearFiltering?: boolean;\r\n    /** Specifies the comparison function to set on the texture. If 0 or undefined, the texture is not in comparison mode */\r\n    comparisonFunction?: number;\r\n    /** Specifies if the created texture is a cube texture */\r\n    isCube?: boolean;\r\n    /** Specifies the sample count of the depth/stencil texture texture */\r\n    samples?: number;\r\n    /** Specifies the depth texture format to use */\r\n    depthTextureFormat?: number;\r\n    /** Label of the texture (used for debugging only) */\r\n    label?: string;\r\n}\r\n\r\n/**\r\n * Type used to define a texture size (either with a number or with a rect width and height)\r\n */\r\nexport type TextureSize = number | { width: number; height: number; depth?: number; layers?: number };\r\n\r\n/**\r\n * Check if a TextureSize is an object\r\n * @param size The TextureSize to check\r\n * @returns True if the TextureSize is an object\r\n */\r\nexport function textureSizeIsObject(size: TextureSize): size is { width: number; height: number } {\r\n    return (size as { width: number }).width !== undefined;\r\n}\r\n\r\n/**\r\n * Get the width/height dimensions from a TextureSize\r\n * @param size The TextureSize to get the dimensions from\r\n * @returns The width and height as an object\r\n */\r\nexport function getDimensionsFromTextureSize(size: TextureSize): { width: number; height: number } {\r\n    if (textureSizeIsObject(size)) {\r\n        return { width: size.width, height: size.height };\r\n    }\r\n    return { width: size, height: size };\r\n}\r\n","import { type FrameGraphTextureHandle, type FrameGraphTextureManager, type IMultiRenderTargetOptions, type RenderTargetWrapper } from \"core/index\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphRenderTarget {\r\n    protected readonly _textureManager: FrameGraphTextureManager;\r\n    protected readonly _renderTargets: FrameGraphTextureHandle[] | undefined;\r\n    protected readonly _renderTargetDepth: FrameGraphTextureHandle | undefined;\r\n    protected _renderTargetWrapper: RenderTargetWrapper | undefined;\r\n    protected _isBackBuffer = false;\r\n\r\n    public readonly name: string;\r\n\r\n    constructor(\r\n        name: string,\r\n        textureManager: FrameGraphTextureManager,\r\n        renderTargets?: FrameGraphTextureHandle | FrameGraphTextureHandle[],\r\n        renderTargetDepth?: FrameGraphTextureHandle\r\n    ) {\r\n        this.name = name;\r\n        this._textureManager = textureManager;\r\n        this._renderTargets = renderTargets === undefined ? undefined : Array.isArray(renderTargets) ? renderTargets : [renderTargets];\r\n        this._renderTargetDepth = renderTargetDepth;\r\n    }\r\n\r\n    public get renderTargetWrapper() {\r\n        if (this._isBackBuffer) {\r\n            return undefined;\r\n        }\r\n\r\n        if (!this._renderTargetWrapper) {\r\n            const engine = this._textureManager.engine;\r\n\r\n            // _renderTargets and _renderTargetDepth cannot both be undefined\r\n            const textureHandle = this._renderTargets === undefined || this._renderTargets.length === 0 ? this._renderTargetDepth! : this._renderTargets[0];\r\n\r\n            if (this._textureManager.isBackbuffer(textureHandle)) {\r\n                this._isBackBuffer = true;\r\n                return undefined;\r\n            }\r\n\r\n            const textureDescription = this._textureManager.getTextureDescription(textureHandle);\r\n\r\n            const creationOptionsForTexture: IMultiRenderTargetOptions = {\r\n                textureCount: this._renderTargets?.length ?? 0,\r\n                generateDepthBuffer: false,\r\n                label: this.name,\r\n                samples: textureDescription.options.samples ?? 1,\r\n                dontCreateTextures: true,\r\n            };\r\n\r\n            this._renderTargetWrapper = engine.createMultipleRenderTarget(textureDescription.size, creationOptionsForTexture, true);\r\n\r\n            for (let i = 0; i < creationOptionsForTexture.textureCount!; i++) {\r\n                const handle = this._renderTargets![i];\r\n                const texture = this._textureManager.getTextureFromHandle(handle);\r\n\r\n                if (!texture) {\r\n                    throw new Error(\r\n                        `FrameGraphRenderTarget.renderTargetWrapper: Failed to get texture from handle. handle: ${handle}, name: ${this.name}, index: ${i}, renderTargets: ${this._renderTargets}`\r\n                    );\r\n                }\r\n\r\n                texture.incrementReferences();\r\n\r\n                this._renderTargetWrapper.setTexture(texture, i, false);\r\n            }\r\n\r\n            if (this._renderTargetDepth !== undefined) {\r\n                this._renderTargetWrapper.setDepthStencilTexture(this._textureManager.getTextureFromHandle(this._renderTargetDepth), false);\r\n            }\r\n        }\r\n\r\n        return this._renderTargetWrapper;\r\n    }\r\n\r\n    public equals(other: FrameGraphRenderTarget): boolean {\r\n        const src = this._renderTargets;\r\n        const dst = other._renderTargets;\r\n\r\n        if (src !== undefined && dst !== undefined) {\r\n            if (src.length !== dst.length) {\r\n                return false;\r\n            }\r\n\r\n            for (let i = 0; i < src.length; i++) {\r\n                if (src[i] !== dst[i]) {\r\n                    return false;\r\n                }\r\n            }\r\n        } else if ((src === undefined && dst !== undefined) || (src !== undefined && dst === undefined)) {\r\n            return false;\r\n        }\r\n\r\n        return this._renderTargetDepth === other._renderTargetDepth;\r\n    }\r\n\r\n    public dispose() {\r\n        this._renderTargetWrapper?.dispose();\r\n    }\r\n}\r\n","import {\r\n    type Scene,\r\n    type AbstractEngine,\r\n    type TextureSize,\r\n    type Nullable,\r\n    type FrameGraphTextureCreationOptions,\r\n    type FrameGraphTextureHandle,\r\n    type InternalTextureCreationOptions,\r\n    type InternalTexture,\r\n    type FrameGraphTextureOptions,\r\n    type FrameGraphTextureDescription,\r\n    type RenderTargetWrapper,\r\n    type FrameGraphTask,\r\n    type IFrameGraphPass,\r\n} from \"core/index\";\r\nimport { getDimensionsFromTextureSize, textureSizeIsObject } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { backbufferColorTextureHandle, backbufferDepthStencilTextureHandle } from \"./frameGraphTypes\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { FrameGraphRenderTarget } from \"./frameGraphRenderTarget\";\r\nimport { FrameGraphRenderPass } from \"./Passes/renderPass\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { GetTypeForDepthTexture, IsDepthTexture, HasStencilAspect } from \"core/Materials/Textures/textureHelper.functions\";\r\n\r\ntype HistoryTexture = {\r\n    textures: Array<Nullable<InternalTexture>>;\r\n    handles: Array<FrameGraphTextureHandle>;\r\n    index: number; // current index in textures array - in the current frame, textures[index] is the write texture, textures[index^1] is the read texture - index is flipped at the end of each frame\r\n    references: Array<{ renderTargetWrapper: RenderTargetWrapper; textureIndex: number }>; // render target wrappers that reference this history texture\r\n};\r\n\r\ntype TextureLifespan = {\r\n    firstTask: number;\r\n    lastTask: number;\r\n};\r\n\r\ntype TextureEntry = {\r\n    texture: Nullable<InternalTexture>;\r\n    name: string;\r\n    creationOptions: FrameGraphTextureCreationOptions; // in TextureEntry, creationOptions.size is always an object\r\n    namespace: FrameGraphTextureNamespace;\r\n    textureIndex?: number; // Index of the texture in the types, formats, etc array of FrameGraphTextureOptions (default: 0)\r\n    debug?: Texture;\r\n    refHandle?: FrameGraphTextureHandle; // Handle of the texture this one is referencing - used for dangling handles\r\n    textureDescriptionHash?: string; // a hash of the texture creation options\r\n    lifespan?: TextureLifespan;\r\n    aliasHandle?: FrameGraphTextureHandle; // Handle of the texture this one is aliasing - can be set after execution of texture allocation optimization\r\n    historyTexture?: boolean; // True if the texture is part of a history texture\r\n};\r\n\r\nenum FrameGraphTextureNamespace {\r\n    Task,\r\n    Graph,\r\n    External,\r\n}\r\n\r\n/**\r\n * Manages the textures used by a frame graph\r\n */\r\nexport class FrameGraphTextureManager {\r\n    private static _Counter = 2; // 0 and 1 are reserved for backbuffer textures\r\n\r\n    /** @internal */\r\n    public readonly _textures: Map<FrameGraphTextureHandle, TextureEntry> = new Map();\r\n\r\n    /** @internal */\r\n    public readonly _historyTextures: Map<FrameGraphTextureHandle, HistoryTexture> = new Map();\r\n\r\n    /** @internal */\r\n    public _isRecordingTask = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if debug logs should be shown when applying texture allocation optimization (default: false)\r\n     */\r\n    public showDebugLogsForTextureAllcationOptimization = false;\r\n\r\n    private _backBufferTextureEntry: Nullable<TextureEntry> = null;\r\n    private _backBufferDepthStencilTextureEntry: Nullable<TextureEntry> = null;\r\n    private _backBufferTextureOverriden = false;\r\n\r\n    /**\r\n     * Constructs a new instance of the texture manager\r\n     * @param engine The engine to use\r\n     * @param _debugTextures If true, debug textures will be created so that they are visible in the inspector\r\n     * @param _scene The scene the manager belongs to\r\n     */\r\n    constructor(\r\n        public readonly engine: AbstractEngine,\r\n        private readonly _debugTextures = false,\r\n        private readonly _scene: Scene\r\n    ) {\r\n        this._addSystemTextures();\r\n    }\r\n\r\n    /**\r\n     * Checks if a handle is a backbuffer handle (color or depth/stencil)\r\n     * @param handle The handle to check\r\n     * @returns True if the handle is a backbuffer handle\r\n     */\r\n    public isBackbuffer(handle: FrameGraphTextureHandle): boolean {\r\n        if (this._backBufferTextureOverriden) {\r\n            return false;\r\n        }\r\n\r\n        return this._isBackbuffer(handle);\r\n    }\r\n\r\n    /** @internal */\r\n    public _isBackbuffer(handle: FrameGraphTextureHandle): boolean {\r\n        if (handle === backbufferColorTextureHandle || handle === backbufferDepthStencilTextureHandle) {\r\n            return true;\r\n        }\r\n\r\n        const textureEntry = this._textures.get(handle);\r\n        if (!textureEntry) {\r\n            return false;\r\n        }\r\n\r\n        return textureEntry.refHandle === backbufferColorTextureHandle || textureEntry.refHandle === backbufferDepthStencilTextureHandle;\r\n    }\r\n\r\n    /**\r\n     * Checks if a handle is a backbuffer color handle\r\n     * @param handle The handle to check\r\n     * @returns True if the handle is a backbuffer color handle\r\n     */\r\n    public isBackbufferColor(handle: FrameGraphTextureHandle): boolean {\r\n        if (this._backBufferTextureOverriden) {\r\n            return false;\r\n        }\r\n\r\n        if (handle === backbufferColorTextureHandle) {\r\n            return true;\r\n        }\r\n\r\n        const textureEntry = this._textures.get(handle);\r\n        if (!textureEntry) {\r\n            return false;\r\n        }\r\n\r\n        return textureEntry.refHandle === backbufferColorTextureHandle;\r\n    }\r\n\r\n    /**\r\n     * Checks if a handle is a backbuffer depth/stencil handle\r\n     * @param handle The handle to check\r\n     * @returns True if the handle is a backbuffer depth/stencil handle\r\n     */\r\n    public isBackbufferDepthStencil(handle: FrameGraphTextureHandle): boolean {\r\n        if (this._backBufferTextureOverriden) {\r\n            return false;\r\n        }\r\n\r\n        if (handle === backbufferDepthStencilTextureHandle) {\r\n            return true;\r\n        }\r\n\r\n        const textureEntry = this._textures.get(handle);\r\n        if (!textureEntry) {\r\n            return false;\r\n        }\r\n\r\n        return textureEntry.refHandle === backbufferDepthStencilTextureHandle;\r\n    }\r\n\r\n    /**\r\n     * Checks if a handle is a history texture (or points to a history texture, for a dangling handle)\r\n     * @param handle The handle to check\r\n     * @param checkAllTextures If false (default), the function will check if the handle is the main handle of a history texture (the first handle of the history texture).\r\n     *   If true, the function will also check if the handle is one of the other handles of a history texture.\r\n     * @returns True if the handle is a history texture, otherwise false\r\n     */\r\n    public isHistoryTexture(handle: FrameGraphTextureHandle, checkAllTextures = false): boolean {\r\n        const entry = this._textures.get(handle);\r\n        if (!entry) {\r\n            return false;\r\n        }\r\n\r\n        handle = entry.refHandle ?? handle;\r\n\r\n        if (!checkAllTextures) {\r\n            return this._historyTextures.has(handle);\r\n        }\r\n\r\n        return this._textures.get(handle)?.historyTexture === true;\r\n    }\r\n\r\n    /**\r\n     * Gets the creation options of a texture\r\n     * @param handle Handle of the texture\r\n     * @param preserveHistoryTextureFlag If true, the isHistoryTexture flag in the returned creation options will be the same as when the texture was created (default: false)\r\n     * @returns The creation options of the texture\r\n     */\r\n    public getTextureCreationOptions(handle: FrameGraphTextureHandle, preserveHistoryTextureFlag = false): FrameGraphTextureCreationOptions {\r\n        handle = this._textures.get(handle)?.refHandle ?? handle;\r\n\r\n        const entry = this._textures.get(handle)!;\r\n        const creationOptions = entry.creationOptions;\r\n\r\n        return {\r\n            size: textureSizeIsObject(creationOptions.size) ? { ...creationOptions.size } : creationOptions.size,\r\n            sizeIsPercentage: creationOptions.sizeIsPercentage,\r\n            options: FrameGraphTextureManager.CloneTextureOptions(creationOptions.options, entry.textureIndex),\r\n            isHistoryTexture: preserveHistoryTextureFlag ? creationOptions.isHistoryTexture : false,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the description of a texture\r\n     * @param handle Handle of the texture\r\n     * @returns The description of the texture\r\n     */\r\n    public getTextureDescription(handle: FrameGraphTextureHandle): FrameGraphTextureDescription {\r\n        const creationOptions = this.getTextureCreationOptions(handle);\r\n\r\n        const size = !creationOptions.sizeIsPercentage\r\n            ? textureSizeIsObject(creationOptions.size)\r\n                ? creationOptions.size\r\n                : { width: creationOptions.size, height: creationOptions.size }\r\n            : this.getAbsoluteDimensions(creationOptions.size);\r\n\r\n        return {\r\n            size,\r\n            options: creationOptions.options,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets a texture handle or creates a new texture if the handle is not provided.\r\n     * If handle is not provided, newTextureName and creationOptions must be provided.\r\n     * @param handle If provided, will simply return the handle\r\n     * @param newTextureName Name of the new texture to create\r\n     * @param creationOptions Options to use when creating the new texture\r\n     * @returns The handle to the texture.\r\n     */\r\n    public getTextureHandleOrCreateTexture(handle?: FrameGraphTextureHandle, newTextureName?: string, creationOptions?: FrameGraphTextureCreationOptions): FrameGraphTextureHandle {\r\n        if (handle === undefined) {\r\n            if (newTextureName === undefined || creationOptions === undefined) {\r\n                throw new Error(\"getTextureHandleOrCreateTexture: Either handle or newTextureName and creationOptions must be provided.\");\r\n            }\r\n            return this.createRenderTargetTexture(newTextureName, creationOptions);\r\n        }\r\n        return handle;\r\n    }\r\n\r\n    /**\r\n     * Gets a texture from a handle.\r\n     * Note that if the texture is a history texture, the read texture for the current frame will be returned, except if historyGetWriteTexture is true.\r\n     * @param handle The handle of the texture\r\n     * @param historyGetWriteTexture If true and the texture is a history texture, the write texture for the current frame will be returned (default: false)\r\n     * @returns The texture or null if not found\r\n     */\r\n    public getTextureFromHandle(handle: FrameGraphTextureHandle, historyGetWriteTexture?: boolean): Nullable<InternalTexture> {\r\n        const entry = this._textures.get(handle);\r\n        const refHandle = entry?.refHandle;\r\n        const finalEntry = refHandle !== undefined ? this._textures.get(refHandle) : entry;\r\n        const finalHandle = refHandle !== undefined ? refHandle : handle;\r\n\r\n        const historyEntry = this._historyTextures.get(finalHandle);\r\n        if (historyEntry) {\r\n            return historyEntry.textures[historyGetWriteTexture ? historyEntry.index : historyEntry.index ^ 1];\r\n        }\r\n        return finalEntry!.texture;\r\n    }\r\n\r\n    /**\r\n     * Imports a texture into the texture manager\r\n     * @param name Name of the texture\r\n     * @param texture Texture to import\r\n     * @param handle Existing handle to use for the texture. If not provided (default), a new handle will be created.\r\n     * @returns The handle to the texture\r\n     */\r\n    public importTexture(name: string, texture: InternalTexture, handle?: FrameGraphTextureHandle): FrameGraphTextureHandle {\r\n        if (handle !== undefined) {\r\n            this._freeEntry(handle);\r\n        }\r\n\r\n        const creationOptions: FrameGraphTextureCreationOptions = {\r\n            size: { width: texture.width, height: texture.height },\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: false,\r\n            options: {\r\n                createMipMaps: texture.generateMipMaps,\r\n                samples: texture.samples,\r\n                types: [texture.type],\r\n                formats: [texture.format],\r\n                useSRGBBuffers: [texture._useSRGBBuffer],\r\n                creationFlags: [texture._creationFlags],\r\n                labels: texture.label ? [texture.label] : [\"imported\"],\r\n            },\r\n        };\r\n\r\n        return this._createHandleForTexture(name, texture, creationOptions, FrameGraphTextureNamespace.External, handle);\r\n    }\r\n\r\n    /**\r\n     * Creates a new render target texture\r\n     * If multiple textures are described in FrameGraphTextureCreationOptions, the handle of the first texture is returned, handle+1 is the handle of the second texture, etc.\r\n     * @param name Name of the texture\r\n     * @param creationOptions Options to use when creating the texture\r\n     * @param handle Existing handle to use for the texture. If not provided (default), a new handle will be created.\r\n     * @returns The handle to the texture\r\n     */\r\n    public createRenderTargetTexture(name: string, creationOptions: FrameGraphTextureCreationOptions, handle?: FrameGraphTextureHandle): FrameGraphTextureHandle {\r\n        return this._createHandleForTexture(\r\n            name,\r\n            null,\r\n            {\r\n                size: textureSizeIsObject(creationOptions.size) ? { ...creationOptions.size } : creationOptions.size,\r\n                sizeIsPercentage: creationOptions.sizeIsPercentage,\r\n                isHistoryTexture: creationOptions.isHistoryTexture,\r\n                options: FrameGraphTextureManager.CloneTextureOptions(creationOptions.options, undefined, true),\r\n            },\r\n            this._isRecordingTask ? FrameGraphTextureNamespace.Task : FrameGraphTextureNamespace.Graph,\r\n            handle\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a (frame graph) render target wrapper\r\n     * Note that renderTargets or renderTargetDepth can be undefined, but not both at the same time!\r\n     * @param name Name of the render target wrapper\r\n     * @param renderTargets Render target handles (textures) to use\r\n     * @param renderTargetDepth Render target depth handle (texture) to use\r\n     * @param depthReadOnly If true, the depth buffer will be read-only\r\n     * @param stencilReadOnly If true, the stencil buffer will be read-only\r\n     * @returns The created render target wrapper\r\n     */\r\n    public createRenderTarget(\r\n        name: string,\r\n        renderTargets?: FrameGraphTextureHandle | FrameGraphTextureHandle[],\r\n        renderTargetDepth?: FrameGraphTextureHandle,\r\n        depthReadOnly?: boolean,\r\n        stencilReadOnly?: boolean\r\n    ): FrameGraphRenderTarget {\r\n        const renderTarget = new FrameGraphRenderTarget(name, this, renderTargets, renderTargetDepth);\r\n\r\n        const rtw = renderTarget.renderTargetWrapper;\r\n\r\n        if (rtw !== undefined) {\r\n            rtw.depthReadOnly = !!depthReadOnly;\r\n            rtw.stencilReadOnly = !!stencilReadOnly;\r\n\r\n            if (renderTargets) {\r\n                const handles = Array.isArray(renderTargets) ? renderTargets : [renderTargets];\r\n\r\n                for (let i = 0; i < handles.length; i++) {\r\n                    let handle = handles[i];\r\n                    handle = this._textures.get(handle)?.refHandle ?? handle;\r\n\r\n                    const historyEntry = this._historyTextures.get(handle);\r\n                    if (historyEntry) {\r\n                        historyEntry.references.push({ renderTargetWrapper: rtw, textureIndex: i });\r\n\r\n                        rtw.setTexture(historyEntry.textures[historyEntry.index]!, i, false);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return renderTarget;\r\n    }\r\n\r\n    /**\r\n     * Creates a handle which is not associated with any texture.\r\n     * Call resolveDanglingHandle to associate the handle with a valid texture handle.\r\n     * @returns The dangling handle\r\n     */\r\n    public createDanglingHandle() {\r\n        return FrameGraphTextureManager._Counter++;\r\n    }\r\n\r\n    /**\r\n     * Associates a texture with a dangling handle\r\n     * @param danglingHandle The dangling handle\r\n     * @param handle The handle to associate with the dangling handle (if not provided, a new texture handle will be created, using the newTextureName and creationOptions parameters)\r\n     * @param newTextureName The name of the new texture to create (if handle is not provided)\r\n     * @param creationOptions The options to use when creating the new texture (if handle is not provided)\r\n     */\r\n    public resolveDanglingHandle(\r\n        danglingHandle: FrameGraphTextureHandle,\r\n        handle?: FrameGraphTextureHandle,\r\n        newTextureName?: string,\r\n        creationOptions?: FrameGraphTextureCreationOptions\r\n    ) {\r\n        if (handle === undefined) {\r\n            if (newTextureName === undefined || creationOptions === undefined) {\r\n                throw new Error(\"resolveDanglingHandle: Either handle or newTextureName and creationOptions must be provided.\");\r\n            }\r\n            this.createRenderTargetTexture(newTextureName, creationOptions, danglingHandle);\r\n            return;\r\n        }\r\n\r\n        const textureEntry = this._textures.get(handle);\r\n\r\n        if (textureEntry === undefined) {\r\n            throw new Error(`resolveDanglingHandle: Handle ${handle} does not exist!`);\r\n        }\r\n\r\n        handle = textureEntry.refHandle ?? handle; // gets the refHandle if handle is a (resolved) dangling handle itself\r\n\r\n        this._textures.set(danglingHandle, {\r\n            texture: textureEntry.texture,\r\n            refHandle: handle,\r\n            name: textureEntry.name,\r\n            creationOptions: {\r\n                size: { ...(textureEntry.creationOptions.size as { width: number; height: number; depth?: number; layers?: number }) },\r\n                options: FrameGraphTextureManager.CloneTextureOptions(textureEntry.creationOptions.options),\r\n                sizeIsPercentage: textureEntry.creationOptions.sizeIsPercentage,\r\n                isHistoryTexture: false,\r\n            },\r\n            namespace: textureEntry.namespace,\r\n            textureIndex: textureEntry.textureIndex,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the absolute dimensions of a texture.\r\n     * @param size The size of the texture. Width and height must be expressed as a percentage of the screen size (100=100%)!\r\n     * @param screenWidth The width of the screen (default: the width of the rendering canvas)\r\n     * @param screenHeight The height of the screen (default: the height of the rendering canvas)\r\n     * @returns The absolute dimensions of the texture\r\n     */\r\n    public getAbsoluteDimensions(size: TextureSize, screenWidth?: number, screenHeight?: number): { width: number; height: number } {\r\n        if (this._backBufferTextureOverriden) {\r\n            const backbufferColorTextureSize = this._textures.get(backbufferColorTextureHandle)!.creationOptions.size as { width: number; height: number };\r\n\r\n            screenWidth ??= backbufferColorTextureSize.width;\r\n            screenHeight ??= backbufferColorTextureSize.height;\r\n        } else {\r\n            screenWidth ??= this.engine.getRenderWidth(true);\r\n            screenHeight ??= this.engine.getRenderHeight(true);\r\n        }\r\n\r\n        const { width, height } = getDimensionsFromTextureSize(size);\r\n\r\n        return {\r\n            width: Math.floor((width * screenWidth) / 100),\r\n            height: Math.floor((height * screenHeight) / 100),\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the absolute dimensions of a texture from its handle or creation options.\r\n     * @param handleOrCreationOptions The handle or creation options of the texture\r\n     * @returns The absolute dimensions of the texture\r\n     */\r\n    public getTextureAbsoluteDimensions(handleOrCreationOptions: FrameGraphTextureHandle | FrameGraphTextureCreationOptions): { width: number; height: number } {\r\n        if (typeof handleOrCreationOptions === \"number\") {\r\n            handleOrCreationOptions = this.getTextureCreationOptions(handleOrCreationOptions);\r\n        }\r\n\r\n        return !handleOrCreationOptions.sizeIsPercentage\r\n            ? textureSizeIsObject(handleOrCreationOptions.size)\r\n                ? handleOrCreationOptions.size\r\n                : { width: handleOrCreationOptions.size, height: handleOrCreationOptions.size }\r\n            : this.getAbsoluteDimensions(handleOrCreationOptions.size);\r\n    }\r\n\r\n    /**\r\n     * Calculates the total byte size of all textures used by the frame graph texture manager (including external textures)\r\n     * @param optimizedSize True if the calculation should not factor in aliased textures\r\n     * @param outputWidth The output width of the frame graph. Will be used to calculate the size of percentage-based textures\r\n     * @param outputHeight The output height of the frame graph. Will be used to calculate the size of percentage-based textures\r\n     * @returns The total size of all textures\r\n     */\r\n    public computeTotalTextureSize(optimizedSize: boolean, outputWidth: number, outputHeight: number) {\r\n        let totalSize = 0;\r\n\r\n        this._textures.forEach((entry, handle) => {\r\n            if (\r\n                (!this._backBufferTextureOverriden && (handle === backbufferColorTextureHandle || handle === backbufferDepthStencilTextureHandle)) ||\r\n                entry.refHandle !== undefined\r\n            ) {\r\n                return;\r\n            }\r\n            if (optimizedSize && entry.aliasHandle !== undefined) {\r\n                return;\r\n            }\r\n\r\n            const options = entry.creationOptions;\r\n            const textureIndex = entry.textureIndex || 0;\r\n            const dimensions = options.sizeIsPercentage ? this.getAbsoluteDimensions(options.size, outputWidth, outputHeight) : getDimensionsFromTextureSize(options.size);\r\n\r\n            const blockInfo = FrameGraphTextureManager._GetTextureBlockInformation(\r\n                options.options.types?.[textureIndex] ?? Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                options.options.formats![textureIndex]\r\n            );\r\n\r\n            const textureByteSize = Math.ceil(dimensions.width / blockInfo.width) * Math.ceil(dimensions.height / blockInfo.height) * blockInfo.length;\r\n\r\n            let byteSize = textureByteSize;\r\n\r\n            if (options.options.createMipMaps) {\r\n                byteSize = Math.floor((byteSize * 4) / 3);\r\n            }\r\n\r\n            if ((options.options.samples || 1) > 1) {\r\n                // We need an additional texture in the case of MSAA\r\n                byteSize += textureByteSize;\r\n            }\r\n\r\n            totalSize += byteSize;\r\n        });\r\n\r\n        return totalSize;\r\n    }\r\n\r\n    /**\r\n     * True if the back buffer texture has been overriden by a call to setBackBufferTexture\r\n     */\r\n    public get backBufferTextureOverriden() {\r\n        return this._backBufferTextureOverriden;\r\n    }\r\n\r\n    /**\r\n     * Overrides the default back buffer color/depth-stencil textures used by the frame graph.\r\n     * Note that if both textureCreationOptions and depthStencilTextureCreationOptions are provided,\r\n     * the engine will use them to create the back buffer color and depth/stencil textures respectively.\r\n     * In that case, width and height are ignored.\r\n     * @param width The width of the back buffer color/depth-stencil texture (if 0, the engine's current back buffer color/depth-stencil texture width will be used)\r\n     * @param height The height of the back buffer color/depth-stencil texture (if 0, the engine's current back buffer color/depth-stencil texture height will be used)\r\n     * @param textureCreationOptions The color texture creation options (optional)\r\n     * @param depthStencilTextureCreationOptions The depth/stencil texture creation options (optional)\r\n     */\r\n    public setBackBufferTextures(\r\n        width: number,\r\n        height: number,\r\n        textureCreationOptions?: FrameGraphTextureCreationOptions,\r\n        depthStencilTextureCreationOptions?: FrameGraphTextureCreationOptions\r\n    ) {\r\n        if ((width === 0 || height === 0) && (!textureCreationOptions || !depthStencilTextureCreationOptions)) {\r\n            if (this._backBufferTextureOverriden) {\r\n                let entry = this._textures.get(backbufferColorTextureHandle)!;\r\n\r\n                entry.texture?.dispose();\r\n                entry.texture = null;\r\n                entry.debug?.dispose();\r\n                entry.debug = undefined;\r\n\r\n                entry = this._textures.get(backbufferDepthStencilTextureHandle)!;\r\n                entry.texture?.dispose();\r\n                entry.texture = null;\r\n                entry.debug?.dispose();\r\n                entry.debug = undefined;\r\n            }\r\n\r\n            this._backBufferTextureEntry = null;\r\n            this._backBufferDepthStencilTextureEntry = null;\r\n            this._backBufferTextureOverriden = false;\r\n\r\n            this._addSystemTextures();\r\n            return;\r\n        }\r\n\r\n        this._backBufferTextureOverriden = true;\r\n\r\n        const size = { width, height };\r\n\r\n        this._backBufferTextureEntry = {\r\n            name: \"backbuffer color\",\r\n            texture: null,\r\n            creationOptions: textureCreationOptions ?? {\r\n                size,\r\n                options: {\r\n                    createMipMaps: false,\r\n                    samples: this.engine.getCreationOptions().antialias ? 4 : 1,\r\n                    types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                    formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                    useSRGBBuffers: [false],\r\n                    creationFlags: [0],\r\n                    labels: [\"backbuffer color\"],\r\n                },\r\n                sizeIsPercentage: false,\r\n            },\r\n            namespace: FrameGraphTextureNamespace.Graph,\r\n            lifespan: {\r\n                firstTask: Number.MAX_VALUE,\r\n                lastTask: 0,\r\n            },\r\n        };\r\n        this._backBufferTextureEntry.textureDescriptionHash = this._createTextureDescriptionHash(this._backBufferTextureEntry.creationOptions);\r\n\r\n        this._backBufferDepthStencilTextureEntry = {\r\n            name: \"backbuffer depth/stencil\",\r\n            texture: null,\r\n            creationOptions: depthStencilTextureCreationOptions ?? {\r\n                size,\r\n                options: {\r\n                    createMipMaps: false,\r\n                    samples: this.engine.getCreationOptions().antialias ? 4 : 1,\r\n                    types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                    formats: [this.engine.isStencilEnable ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT],\r\n                    useSRGBBuffers: [false],\r\n                    creationFlags: [0],\r\n                    labels: [\"backbuffer depth/stencil\"],\r\n                },\r\n                sizeIsPercentage: false,\r\n            },\r\n            namespace: FrameGraphTextureNamespace.Graph,\r\n            lifespan: {\r\n                firstTask: Number.MAX_VALUE,\r\n                lastTask: 0,\r\n            },\r\n        };\r\n        this._backBufferDepthStencilTextureEntry.textureDescriptionHash = this._createTextureDescriptionHash(this._backBufferDepthStencilTextureEntry.creationOptions);\r\n\r\n        this._addSystemTextures();\r\n    }\r\n\r\n    /**\r\n     * Resets the back buffer color/depth-stencil textures to the default (the engine's current back buffer textures)\r\n     * It has no effect if setBackBufferTextures has not been called before.\r\n     */\r\n    public resetBackBufferTextures() {\r\n        this.setBackBufferTextures(0, 0);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the texture manager has at least one history texture\r\n     */\r\n    public get hasHistoryTextures() {\r\n        return this._historyTextures.size > 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public _dispose(): void {\r\n        this._releaseTextures();\r\n    }\r\n\r\n    /** @internal */\r\n    public _allocateTextures(tasks?: FrameGraphTask[]): void {\r\n        if (tasks) {\r\n            this._optimizeTextureAllocation(tasks);\r\n        }\r\n\r\n        this._textures.forEach((entry) => {\r\n            if (!entry.texture) {\r\n                if (entry.refHandle !== undefined) {\r\n                    // entry is a dangling handle which has been resolved to point to refHandle\r\n                    // We simply update the texture to point to the refHandle texture\r\n                    const refEntry = this._textures.get(entry.refHandle)!;\r\n\r\n                    entry.texture = refEntry.texture;\r\n                    entry.texture?.incrementReferences();\r\n\r\n                    if (refEntry.refHandle === backbufferColorTextureHandle) {\r\n                        entry.refHandle = backbufferColorTextureHandle;\r\n                    }\r\n                    if (refEntry.refHandle === backbufferDepthStencilTextureHandle) {\r\n                        entry.refHandle = backbufferDepthStencilTextureHandle;\r\n                    }\r\n                } else if (entry.namespace !== FrameGraphTextureNamespace.External) {\r\n                    if (entry.aliasHandle !== undefined) {\r\n                        const aliasEntry = this._textures.get(entry.aliasHandle)!;\r\n\r\n                        entry.texture = aliasEntry.texture!;\r\n                        entry.texture.incrementReferences();\r\n                    } else {\r\n                        const creationOptions = entry.creationOptions;\r\n                        const size = getDimensionsFromTextureSize(creationOptions.sizeIsPercentage ? this.getAbsoluteDimensions(creationOptions.size) : creationOptions.size);\r\n                        const textureIndex = entry.textureIndex || 0;\r\n                        const targetType = creationOptions.options.targetTypes?.[textureIndex] ?? Constants.TEXTURE_2D;\r\n                        const is3D = targetType === Constants.TEXTURE_3D;\r\n                        const isArray = targetType === Constants.TEXTURE_2D_ARRAY || targetType === Constants.TEXTURE_CUBE_MAP_ARRAY;\r\n                        const layerCount = creationOptions.options.layerCounts?.[textureIndex] ?? 0;\r\n\r\n                        const internalTextureCreationOptions: InternalTextureCreationOptions = {\r\n                            createMipMaps: creationOptions.options.createMipMaps,\r\n                            samples: creationOptions.options.samples,\r\n                            type: creationOptions.options.types?.[textureIndex],\r\n                            format: creationOptions.options.formats?.[textureIndex],\r\n                            useSRGBBuffer: creationOptions.options.useSRGBBuffers?.[textureIndex],\r\n                            creationFlags: creationOptions.options.creationFlags?.[textureIndex],\r\n                            label: creationOptions.options.labels?.[textureIndex] ?? `${entry.name}${textureIndex > 0 ? \"#\" + textureIndex : \"\"}`,\r\n                            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                            createMSAATexture: creationOptions.options.samples! > 1,\r\n                            isCube: targetType === Constants.TEXTURE_CUBE_MAP || targetType === Constants.TEXTURE_CUBE_MAP_ARRAY,\r\n                        };\r\n\r\n                        const isDepthTexture = IsDepthTexture(internalTextureCreationOptions.format!);\r\n                        const hasStencil = HasStencilAspect(internalTextureCreationOptions.format!);\r\n                        const source =\r\n                            isDepthTexture && hasStencil\r\n                                ? InternalTextureSource.DepthStencil\r\n                                : isDepthTexture || hasStencil\r\n                                  ? InternalTextureSource.Depth\r\n                                  : InternalTextureSource.RenderTarget;\r\n\r\n                        const internalTexture = this.engine._createInternalTexture(\r\n                            { width: size.width, height: size.height, depth: is3D ? layerCount : undefined, layers: isArray ? layerCount : undefined },\r\n                            internalTextureCreationOptions,\r\n                            false,\r\n                            source\r\n                        );\r\n\r\n                        if (isDepthTexture) {\r\n                            internalTexture.type = GetTypeForDepthTexture(internalTexture.format);\r\n                        }\r\n\r\n                        entry.texture = internalTexture;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (entry.texture && entry.refHandle === undefined) {\r\n                entry.debug?.dispose();\r\n                entry.debug = this._createDebugTexture(entry.name, entry.texture);\r\n            }\r\n        });\r\n\r\n        this._historyTextures.forEach((entry) => {\r\n            for (let i = 0; i < entry.handles.length; i++) {\r\n                entry.textures[i] = this._textures.get(entry.handles[i])!.texture;\r\n            }\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public _releaseTextures(releaseAll = true): void {\r\n        this._textures.forEach((entry, handle) => {\r\n            if (entry.lifespan) {\r\n                entry.lifespan.firstTask = Number.MAX_VALUE;\r\n                entry.lifespan.lastTask = 0;\r\n            }\r\n\r\n            entry.aliasHandle = undefined;\r\n\r\n            if (releaseAll || entry.namespace !== FrameGraphTextureNamespace.External) {\r\n                entry.debug?.dispose();\r\n                entry.debug = undefined;\r\n            }\r\n\r\n            if (entry.namespace === FrameGraphTextureNamespace.External) {\r\n                return;\r\n            }\r\n\r\n            // We dispose of \"Graph\" and \"Task\" textures:\r\n            // - \"Graph\" textures will be recreated by _allocateTextures because the entry still exists in this._textures, but entry.texture is null\r\n            // - \"Task\" textures will be re-added to this._textures when the task is recorded (by a call to FrameGraph.build): that's why we delete the entry from this._textures below\r\n            entry.texture?.dispose();\r\n            entry.texture = null;\r\n\r\n            if (releaseAll || entry.namespace === FrameGraphTextureNamespace.Task) {\r\n                this._textures.delete(handle);\r\n                this._historyTextures.delete(handle);\r\n            }\r\n        });\r\n\r\n        this._historyTextures.forEach((entry) => {\r\n            for (let i = 0; i < entry.handles.length; i++) {\r\n                entry.textures[i] = null;\r\n            }\r\n        });\r\n\r\n        if (releaseAll) {\r\n            this._textures.clear();\r\n            this._historyTextures.clear();\r\n            this._addSystemTextures();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateHistoryTextures(): void {\r\n        this._historyTextures.forEach((entry) => {\r\n            entry.index = entry.index ^ 1;\r\n            const currentTexture = entry.textures[entry.index];\r\n            if (currentTexture) {\r\n                for (const { renderTargetWrapper, textureIndex } of entry.references) {\r\n                    renderTargetWrapper.setTexture(currentTexture, textureIndex, false);\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    private _addSystemTextures() {\r\n        const size = { width: this.engine.getRenderWidth(true), height: this.engine.getRenderHeight(true) };\r\n\r\n        this._textures.set(\r\n            backbufferColorTextureHandle,\r\n            this._backBufferTextureEntry ?? {\r\n                name: \"backbuffer color\",\r\n                texture: null,\r\n                creationOptions: {\r\n                    size,\r\n                    options: {\r\n                        createMipMaps: false,\r\n                        samples: this.engine.getCreationOptions().antialias ? 4 : 1,\r\n                        types: [Constants.TEXTURETYPE_UNSIGNED_BYTE], // todo? get from engine\r\n                        formats: [Constants.TEXTUREFORMAT_RGBA], // todo? get from engine\r\n                        useSRGBBuffers: [false],\r\n                        creationFlags: [0],\r\n                        labels: [\"backbuffer color\"],\r\n                    },\r\n                    sizeIsPercentage: false,\r\n                },\r\n                namespace: FrameGraphTextureNamespace.External,\r\n            }\r\n        );\r\n\r\n        this._textures.set(\r\n            backbufferDepthStencilTextureHandle,\r\n            this._backBufferDepthStencilTextureEntry ?? {\r\n                name: \"backbuffer depth/stencil\",\r\n                texture: null,\r\n                creationOptions: {\r\n                    size,\r\n                    options: {\r\n                        createMipMaps: false,\r\n                        samples: this.engine.getCreationOptions().antialias ? 4 : 1,\r\n                        types: [Constants.TEXTURETYPE_UNSIGNED_BYTE], // todo? get from engine\r\n                        formats: [Constants.TEXTUREFORMAT_DEPTH24], // todo? get from engine\r\n                        useSRGBBuffers: [false],\r\n                        creationFlags: [0],\r\n                        labels: [\"backbuffer depth/stencil\"],\r\n                    },\r\n                    sizeIsPercentage: false,\r\n                },\r\n                namespace: FrameGraphTextureNamespace.External,\r\n            }\r\n        );\r\n    }\r\n\r\n    private _createDebugTexture(name: string, texture: InternalTexture): Texture | undefined {\r\n        if (!this._debugTextures) {\r\n            return;\r\n        }\r\n\r\n        const textureDebug = new Texture(null, this._scene);\r\n\r\n        textureDebug.name = name;\r\n        textureDebug._texture = texture;\r\n        textureDebug._texture.incrementReferences();\r\n\r\n        return textureDebug;\r\n    }\r\n\r\n    private _freeEntry(handle: number): void {\r\n        const entry = this._textures.get(handle);\r\n\r\n        if (entry) {\r\n            entry.debug?.dispose();\r\n            this._textures.delete(handle);\r\n        }\r\n    }\r\n\r\n    private _createHandleForTexture(\r\n        name: string,\r\n        texture: Nullable<InternalTexture>,\r\n        creationOptions: FrameGraphTextureCreationOptions,\r\n        namespace: FrameGraphTextureNamespace,\r\n        handle?: FrameGraphTextureHandle,\r\n        textureIndex?: number\r\n    ): FrameGraphTextureHandle {\r\n        handle = handle ?? FrameGraphTextureManager._Counter++;\r\n        textureIndex = textureIndex || 0;\r\n\r\n        const textureName = creationOptions.isHistoryTexture ? `${name} ping` : name;\r\n\r\n        let label = creationOptions.options.labels?.[textureIndex] ?? \"\";\r\n        if (label === textureName) {\r\n            label = \"\";\r\n        }\r\n\r\n        const textureEntry: TextureEntry = {\r\n            texture,\r\n            name: `${textureName}${label ? \" \" + label : \"\"}`,\r\n            creationOptions: {\r\n                size: textureSizeIsObject(creationOptions.size) ? creationOptions.size : { width: creationOptions.size, height: creationOptions.size },\r\n                options: creationOptions.options,\r\n                sizeIsPercentage: creationOptions.sizeIsPercentage,\r\n                isHistoryTexture: creationOptions.isHistoryTexture,\r\n            },\r\n            namespace,\r\n            textureIndex,\r\n            textureDescriptionHash: this._createTextureDescriptionHash(creationOptions),\r\n            lifespan: {\r\n                firstTask: Number.MAX_VALUE,\r\n                lastTask: 0,\r\n            },\r\n            historyTexture: creationOptions.isHistoryTexture,\r\n        };\r\n\r\n        this._textures.set(handle, textureEntry);\r\n\r\n        if (namespace === FrameGraphTextureNamespace.External) {\r\n            return handle;\r\n        }\r\n\r\n        if (creationOptions.isHistoryTexture) {\r\n            const pongCreationOptions: FrameGraphTextureCreationOptions = {\r\n                size: { ...(textureEntry.creationOptions.size as { width: number; height: number }) },\r\n                options: { ...textureEntry.creationOptions.options },\r\n                sizeIsPercentage: textureEntry.creationOptions.sizeIsPercentage,\r\n                isHistoryTexture: false,\r\n            };\r\n\r\n            const pongTexture = this._createHandleForTexture(`${name} pong`, null, pongCreationOptions, namespace);\r\n\r\n            this._textures.get(pongTexture)!.historyTexture = true;\r\n            this._historyTextures.set(handle, { textures: [null, null], handles: [handle, pongTexture], index: 0, references: [] });\r\n\r\n            return handle;\r\n        }\r\n\r\n        if (creationOptions.options.types && creationOptions.options.types.length > 1 && textureIndex === 0) {\r\n            const textureCount = creationOptions.options.types.length;\r\n            const creationOptionsForTexture: FrameGraphTextureCreationOptions = {\r\n                size: textureSizeIsObject(creationOptions.size) ? creationOptions.size : { width: creationOptions.size, height: creationOptions.size },\r\n                options: creationOptions.options,\r\n                sizeIsPercentage: creationOptions.sizeIsPercentage,\r\n            };\r\n\r\n            for (let i = 1; i < textureCount; i++) {\r\n                this._createHandleForTexture(textureName, null, creationOptionsForTexture, namespace, handle + i, i);\r\n            }\r\n\r\n            FrameGraphTextureManager._Counter += textureCount - 1;\r\n        }\r\n\r\n        return handle;\r\n    }\r\n\r\n    private _createTextureDescriptionHash(options: FrameGraphTextureCreationOptions): string {\r\n        const hash: string[] = [];\r\n\r\n        hash.push(textureSizeIsObject(options.size) ? `${options.size.width}_${options.size.height}` : `${options.size}`);\r\n        hash.push(options.sizeIsPercentage ? \"%\" : \"A\");\r\n        hash.push(options.options.createMipMaps ? \"M\" : \"N\");\r\n        hash.push(options.options.samples ? `${options.options.samples}` : \"S1\");\r\n        hash.push(options.options.targetTypes ? options.options.targetTypes.join(\"_\") : `${Constants.TEXTURE_2D}`);\r\n        hash.push(options.options.types ? options.options.types.join(\"_\") : `${Constants.TEXTURETYPE_UNSIGNED_BYTE}`);\r\n        hash.push(options.options.formats ? options.options.formats.join(\"_\") : `${Constants.TEXTUREFORMAT_RGBA}`);\r\n        hash.push(options.options.layerCounts ? options.options.layerCounts.join(\"_\") : `0`);\r\n        hash.push(options.options.useSRGBBuffers ? options.options.useSRGBBuffers.join(\"_\") : \"false\");\r\n        hash.push(options.options.creationFlags ? options.options.creationFlags.join(\"_\") : \"0\");\r\n\r\n        return hash.join(\"_\");\r\n    }\r\n\r\n    private _optimizeTextureAllocation(tasks: FrameGraphTask[]): void {\r\n        this._computeTextureLifespan(tasks);\r\n\r\n        if (this.showDebugLogsForTextureAllcationOptimization) {\r\n            Logger.Log(`================== Optimization of texture allocation ==================`);\r\n        }\r\n\r\n        const cache: Map<string, Array<[FrameGraphTextureHandle, Array<TextureLifespan>]>> = new Map();\r\n\r\n        const iterator = this._textures.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const textureHandle = key.value;\r\n            const textureEntry = this._textures.get(textureHandle)!;\r\n            if (textureEntry.refHandle !== undefined || textureEntry.namespace === FrameGraphTextureNamespace.External || this.isHistoryTexture(textureHandle, true)) {\r\n                continue;\r\n            }\r\n\r\n            const textureHash = textureEntry.textureDescriptionHash!;\r\n            const textureLifespan = textureEntry.lifespan!;\r\n\r\n            const cacheEntries = cache.get(textureHash);\r\n            if (cacheEntries) {\r\n                let cacheEntryFound = false;\r\n                for (const cacheEntry of cacheEntries) {\r\n                    const [sourceHandle, lifespanArray] = cacheEntry;\r\n\r\n                    let overlapped = false;\r\n                    for (const lifespan of lifespanArray) {\r\n                        if (lifespan.firstTask <= textureLifespan.lastTask && lifespan.lastTask >= textureLifespan.firstTask) {\r\n                            overlapped = true;\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (!overlapped) {\r\n                        // No overlap between texture lifespan and all lifespans in the array, this texture can reuse the same entry cache\r\n                        if (this.showDebugLogsForTextureAllcationOptimization) {\r\n                            Logger.Log(`Texture ${textureHandle} (${textureEntry.name}) reuses cache entry ${sourceHandle}`);\r\n                        }\r\n\r\n                        lifespanArray.push(textureLifespan);\r\n                        textureEntry.aliasHandle = sourceHandle;\r\n                        cacheEntryFound = true;\r\n                        break;\r\n                    }\r\n                }\r\n                if (!cacheEntryFound) {\r\n                    cacheEntries.push([textureHandle, [textureLifespan]]);\r\n                }\r\n            } else {\r\n                cache.set(textureHash, [[textureHandle, [textureLifespan]]]);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Loop through all task/pass dependencies and compute the lifespan of each texture (that is, the first task/pass that uses it and the last task/pass that uses it)\r\n    private _computeTextureLifespan(tasks: FrameGraphTask[]): void {\r\n        if (this.showDebugLogsForTextureAllcationOptimization) {\r\n            Logger.Log(`================== Dump of texture dependencies for all tasks/passes ==================`);\r\n        }\r\n\r\n        for (let t = 0; t < tasks.length; ++t) {\r\n            const task = tasks[t];\r\n\r\n            if (task.passes.length > 0) {\r\n                this._computeTextureLifespanForPasses(task, t, task.passes);\r\n            }\r\n\r\n            if (task.passesDisabled.length > 0) {\r\n                this._computeTextureLifespanForPasses(task, t, task.passesDisabled);\r\n            }\r\n\r\n            if (task.dependencies) {\r\n                if (this.showDebugLogsForTextureAllcationOptimization) {\r\n                    Logger.Log(`task#${t} (${task.name}), global dependencies`);\r\n                }\r\n\r\n                this._updateLifespan(t * 100 + 99, task.dependencies);\r\n            }\r\n        }\r\n\r\n        if (this.showDebugLogsForTextureAllcationOptimization) {\r\n            Logger.Log(`================== Texture lifespans ==================`);\r\n            const iterator = this._textures.keys();\r\n            for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                const textureHandle = key.value;\r\n                const textureEntry = this._textures.get(textureHandle)!;\r\n                if (textureEntry.refHandle !== undefined || textureEntry.namespace === FrameGraphTextureNamespace.External || this._historyTextures.has(textureHandle)) {\r\n                    continue;\r\n                }\r\n                Logger.Log(`${textureHandle} (${textureEntry.name}): ${textureEntry.lifespan!.firstTask} - ${textureEntry.lifespan!.lastTask}`);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _computeTextureLifespanForPasses(task: FrameGraphTask, taskIndex: number, passes: IFrameGraphPass[]): void {\r\n        for (let p = 0; p < passes.length; ++p) {\r\n            const dependencies = new Set<FrameGraphTextureHandle>();\r\n            const pass = passes[p];\r\n\r\n            if (!FrameGraphRenderPass.IsRenderPass(pass)) {\r\n                continue;\r\n            }\r\n\r\n            pass.collectDependencies(dependencies);\r\n\r\n            if (this.showDebugLogsForTextureAllcationOptimization) {\r\n                Logger.Log(`task#${taskIndex} (${task.name}), pass#${p} (${pass.name})`);\r\n            }\r\n\r\n            this._updateLifespan(taskIndex * 100 + p, dependencies);\r\n        }\r\n    }\r\n\r\n    private _updateLifespan(passOrderNum: number, dependencies: Set<FrameGraphTextureHandle>) {\r\n        const iterator = dependencies.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const textureHandle = key.value;\r\n            if (this.isBackbuffer(textureHandle)) {\r\n                continue;\r\n            }\r\n            let textureEntry = this._textures.get(textureHandle);\r\n            if (!textureEntry) {\r\n                throw new Error(\r\n                    `FrameGraph._computeTextureLifespan: Texture handle \"${textureHandle}\" not found in the texture manager. Make sure you didn't forget to add a task in the frame graph.`\r\n                );\r\n            }\r\n            let handle = textureHandle;\r\n            while (textureEntry.refHandle !== undefined) {\r\n                handle = textureEntry.refHandle;\r\n                textureEntry = this._textures.get(handle);\r\n                if (!textureEntry) {\r\n                    throw new Error(\r\n                        `FrameGraph._computeTextureLifespan: Texture handle \"${handle}\" not found in the texture manager (source handle=\"${textureHandle}\"). Make sure you didn't forget to add a task in the frame graph.`\r\n                    );\r\n                }\r\n            }\r\n            if (textureEntry.namespace === FrameGraphTextureNamespace.External || this._historyTextures.has(handle)) {\r\n                continue;\r\n            }\r\n\r\n            if (this.showDebugLogsForTextureAllcationOptimization) {\r\n                Logger.Log(`    ${handle} (${textureEntry.name})`);\r\n            }\r\n\r\n            textureEntry.lifespan!.firstTask = Math.min(textureEntry.lifespan!.firstTask, passOrderNum);\r\n            textureEntry.lifespan!.lastTask = Math.max(textureEntry.lifespan!.lastTask, passOrderNum);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clones a texture options\r\n     * @param options The options to clone\r\n     * @param textureIndex The index of the texture in the types, formats, etc array of FrameGraphTextureOptions. If not provided, all options are cloned.\r\n     * @param preserveLabels True if the labels should be preserved (default: false)\r\n     * @returns The cloned options\r\n     */\r\n    public static CloneTextureOptions(options: FrameGraphTextureOptions, textureIndex?: number, preserveLabels?: boolean): FrameGraphTextureOptions {\r\n        return textureIndex !== undefined\r\n            ? {\r\n                  createMipMaps: options.createMipMaps,\r\n                  samples: options.samples,\r\n                  targetTypes: options.targetTypes ? [options.targetTypes[textureIndex]] : undefined,\r\n                  types: options.types ? [options.types[textureIndex]] : undefined,\r\n                  formats: options.formats ? [options.formats[textureIndex]] : undefined,\r\n                  layerCounts: options.layerCounts ? [options.layerCounts[textureIndex]] : undefined,\r\n                  useSRGBBuffers: options.useSRGBBuffers ? [options.useSRGBBuffers[textureIndex]] : undefined,\r\n                  creationFlags: options.creationFlags ? [options.creationFlags[textureIndex]] : undefined,\r\n                  labels: options.labels ? [options.labels[textureIndex]] : undefined,\r\n              }\r\n            : {\r\n                  createMipMaps: options.createMipMaps,\r\n                  samples: options.samples,\r\n                  targetTypes: options.targetTypes ? [...options.targetTypes] : undefined,\r\n                  types: options.types ? [...options.types] : undefined,\r\n                  formats: options.formats ? [...options.formats] : undefined,\r\n                  layerCounts: options.layerCounts ? [...options.layerCounts] : undefined,\r\n                  useSRGBBuffers: options.useSRGBBuffers ? [...options.useSRGBBuffers] : undefined,\r\n                  creationFlags: options.creationFlags ? [...options.creationFlags] : undefined,\r\n                  labels: options.labels && preserveLabels ? [...options.labels] : undefined,\r\n              };\r\n    }\r\n\r\n    /**\r\n     * Gets the texture block information.\r\n     * @param type Type of the texture.\r\n     * @param format Format of the texture.\r\n     * @returns The texture block information. You can calculate the byte size of the texture by doing: Math.ceil(width / blockInfo.width) * Math.ceil(height / blockInfo.height) * blockInfo.length\r\n     */\r\n    private static _GetTextureBlockInformation(type: number, format: number): { width: number; height: number; length: number } {\r\n        switch (format) {\r\n            case Constants.TEXTUREFORMAT_DEPTH16:\r\n                return { width: 1, height: 1, length: 2 };\r\n            case Constants.TEXTUREFORMAT_DEPTH24:\r\n                return { width: 1, height: 1, length: 3 };\r\n            case Constants.TEXTUREFORMAT_DEPTH24_STENCIL8:\r\n                return { width: 1, height: 1, length: 4 };\r\n            case Constants.TEXTUREFORMAT_DEPTH32_FLOAT:\r\n                return { width: 1, height: 1, length: 4 };\r\n            case Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8:\r\n                return { width: 1, height: 1, length: 5 };\r\n            case Constants.TEXTUREFORMAT_STENCIL8:\r\n                return { width: 1, height: 1, length: 1 };\r\n\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n                return { width: 4, height: 4, length: 8 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n                return { width: 4, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4:\r\n                return { width: 5, height: 4, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5:\r\n                return { width: 5, height: 5, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5:\r\n                return { width: 6, height: 5, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6:\r\n                return { width: 6, height: 6, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5:\r\n                return { width: 8, height: 5, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6:\r\n                return { width: 8, height: 6, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8:\r\n                return { width: 8, height: 8, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5:\r\n                return { width: 10, height: 5, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6:\r\n                return { width: 10, height: 6, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8:\r\n                return { width: 10, height: 8, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10:\r\n                return { width: 10, height: 10, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10:\r\n                return { width: 12, height: 10, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12:\r\n                return { width: 12, height: 12, length: 16 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n                return { width: 4, height: 4, length: 8 };\r\n            case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n                return { width: 4, height: 4, length: 16 };\r\n        }\r\n\r\n        switch (type) {\r\n            case Constants.TEXTURETYPE_BYTE:\r\n            case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_R:\r\n                    case Constants.TEXTUREFORMAT_R_INTEGER:\r\n                    case Constants.TEXTUREFORMAT_ALPHA:\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE:\r\n                        return { width: 1, height: 1, length: 1 };\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                    case Constants.TEXTUREFORMAT_LUMINANCE_ALPHA:\r\n                        return { width: 1, height: 1, length: 2 };\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return { width: 1, height: 1, length: 3 };\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                }\r\n            case Constants.TEXTURETYPE_SHORT:\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return { width: 1, height: 1, length: 2 };\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return { width: 1, height: 1, length: 6 };\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return { width: 1, height: 1, length: 8 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 8 };\r\n                }\r\n            case Constants.TEXTURETYPE_INT:\r\n            case Constants.TEXTURETYPE_UNSIGNED_INTEGER: // Refers to UNSIGNED_INT\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED_INTEGER:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    case Constants.TEXTUREFORMAT_RG_INTEGER:\r\n                        return { width: 1, height: 1, length: 8 };\r\n                    case Constants.TEXTUREFORMAT_RGB_INTEGER:\r\n                        return { width: 1, height: 1, length: 12 };\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return { width: 1, height: 1, length: 16 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 16 };\r\n                }\r\n            case Constants.TEXTURETYPE_FLOAT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return { width: 1, height: 1, length: 8 };\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return { width: 1, height: 1, length: 12 };\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return { width: 1, height: 1, length: 16 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 16 };\r\n                }\r\n            case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RED:\r\n                        return { width: 1, height: 1, length: 2 };\r\n                    case Constants.TEXTUREFORMAT_RG:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    case Constants.TEXTUREFORMAT_RGB:\r\n                        return { width: 1, height: 1, length: 6 };\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return { width: 1, height: 1, length: 8 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 8 };\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:\r\n                return { width: 1, height: 1, length: 2 };\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                }\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:\r\n                return { width: 1, height: 1, length: 2 };\r\n            case Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:\r\n                return { width: 1, height: 1, length: 2 };\r\n            case Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:\r\n                switch (format) {\r\n                    case Constants.TEXTUREFORMAT_RGBA:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    case Constants.TEXTUREFORMAT_RGBA_INTEGER:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                    default:\r\n                        return { width: 1, height: 1, length: 4 };\r\n                }\r\n        }\r\n\r\n        return { width: 1, height: 1, length: 4 };\r\n    }\r\n}\r\n","import {\r\n    type Scene,\r\n    type AbstractEngine,\r\n    type FrameGraphTask,\r\n    type Nullable,\r\n    type NodeRenderGraph,\r\n    type IDisposable,\r\n    type Camera,\r\n    type FrameGraphObjectRendererTask,\r\n} from \"core/index\";\r\nimport { FrameGraphPass } from \"./Passes/pass\";\r\nimport { FrameGraphRenderPass } from \"./Passes/renderPass\";\r\nimport { FrameGraphObjectListPass } from \"./Passes/objectListPass\";\r\nimport { FrameGraphRenderContext } from \"./frameGraphRenderContext\";\r\nimport { FrameGraphContext } from \"./frameGraphContext\";\r\nimport { FrameGraphTextureManager } from \"./frameGraphTextureManager\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { _RetryWithInterval } from \"core/Misc/timingTools\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { UniqueIdGenerator } from \"core/Misc/uniqueIdGenerator\";\r\n\r\nenum FrameGraphPassType {\r\n    Normal = 0,\r\n    Render = 1,\r\n    ObjectList = 2,\r\n}\r\n\r\n/**\r\n * Class used to implement a frame graph\r\n */\r\nexport class FrameGraph implements IDisposable {\r\n    /**\r\n     * Gets the texture manager used by the frame graph\r\n     */\r\n    public readonly textureManager: FrameGraphTextureManager;\r\n\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _scene: Scene;\r\n    private readonly _tasks: FrameGraphTask[] = [];\r\n    private readonly _passContext: FrameGraphContext;\r\n    private readonly _renderContext: FrameGraphRenderContext;\r\n    private readonly _initAsyncPromises: Promise<unknown>[] = [];\r\n    private _currentProcessedTask: FrameGraphTask | null = null;\r\n    private _whenReadyAsyncCancel: Nullable<() => void> = null;\r\n    private _importPromise: Promise<void>;\r\n\r\n    /**\r\n     * Name of the frame graph\r\n     */\r\n    public name = \"Frame Graph\";\r\n\r\n    /**\r\n     * Gets the unique id of the frame graph\r\n     */\r\n    public readonly uniqueId = UniqueIdGenerator.UniqueId;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that texture allocation should be optimized (that is, reuse existing textures when possible to limit GPU memory usage) (default: true)\r\n     */\r\n    public optimizeTextureAllocation = true;\r\n\r\n    /**\r\n     * Observable raised when the node render graph is built\r\n     */\r\n    public onBuildObservable = new Observable<FrameGraph>();\r\n\r\n    /**\r\n     * Gets the engine used by the frame graph\r\n     */\r\n    public get engine() {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * Gets the scene used by the frame graph\r\n     */\r\n    public get scene() {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of tasks in the frame graph\r\n     */\r\n    public get tasks() {\r\n        return this._tasks;\r\n    }\r\n\r\n    /**\r\n     * Indicates whether the execution of the frame graph is paused (default is false)\r\n     */\r\n    public pausedExecution = false;\r\n\r\n    /**\r\n     * Gets the node render graph linked to the frame graph (if any)\r\n     * @returns the linked node render graph or null if none\r\n     */\r\n    public getLinkedNodeRenderGraph(): Nullable<NodeRenderGraph> {\r\n        return this._linkedNodeRenderGraph;\r\n    }\r\n\r\n    /**\r\n     * Constructs the frame graph\r\n     * @param scene defines the scene the frame graph is associated with\r\n     * @param debugTextures defines a boolean indicating that textures created by the frame graph should be visible in the inspector (default is false)\r\n     * @param _linkedNodeRenderGraph defines the linked node render graph (if any)\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        debugTextures = false,\r\n        private readonly _linkedNodeRenderGraph: Nullable<NodeRenderGraph> = null\r\n    ) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._importPromise = (async () => {\r\n            if (this._engine.isWebGPU) {\r\n                const module = await import(\"../Engines/WebGPU/Extensions/engine.multiRender.pure\");\r\n                module.RegisterEnginesWebGPUExtensionsEngineMultiRender();\r\n            } else {\r\n                const module = await import(\"../Engines/Extensions/engine.multiRender.pure\");\r\n                module.RegisterEnginesExtensionsEngineMultiRender();\r\n            }\r\n        })();\r\n        this.textureManager = new FrameGraphTextureManager(this._engine, debugTextures, scene);\r\n        this._passContext = new FrameGraphContext(this._engine, this.textureManager, scene);\r\n        this._renderContext = new FrameGraphRenderContext(this._engine, this.textureManager, scene);\r\n\r\n        this._scene.addFrameGraph(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the frame graph\r\n     * @returns the class name\r\n     */\r\n    public getClassName() {\r\n        return \"FrameGraph\";\r\n    }\r\n\r\n    /**\r\n     * Gets a task by name\r\n     * @param name Name of the task to get\r\n     * @returns The task or undefined if not found\r\n     */\r\n    public getTaskByName<T extends FrameGraphTask>(name: string): T | undefined {\r\n        return this._tasks.find((t) => t.name === name) as T;\r\n    }\r\n\r\n    /**\r\n     * Gets all tasks of a specific class name(s)\r\n     * @param name Class name(s) of the task to get\r\n     * @returns The list of tasks or an empty array if none found\r\n     */\r\n    public getTasksByClassNames<T extends FrameGraphTask>(name: string | string[]): T[] {\r\n        return this._tasks.filter((t) => (Array.isArray(name) ? name.includes(t.getClassName()) : t.getClassName() === name)) as T[];\r\n    }\r\n\r\n    /**\r\n     * Gets all tasks of a specific type\r\n     * @param taskType Type of the task(s) to get\r\n     * @returns The list of tasks of the specified type\r\n     */\r\n    public getTasksByType<T extends FrameGraphTask>(taskType: new (...args: any[]) => T): T[] {\r\n        return this._tasks.filter((t) => t instanceof taskType) as T[];\r\n    }\r\n\r\n    /**\r\n     * Gets all tasks of a specific type, based on their class name\r\n     * @param taskClassName Class name(s) of the task(s) to get\r\n     * @returns The list of tasks of the specified type\r\n     */\r\n    public getTasksByClassName<T extends FrameGraphTask>(taskClassName: string | string[]): T[] {\r\n        return Array.isArray(taskClassName)\r\n            ? (this._tasks.filter((t) => taskClassName.includes(t.getClassName())) as T[])\r\n            : (this._tasks.filter((t) => t.getClassName() === taskClassName) as T[]);\r\n    }\r\n\r\n    /**\r\n     * Adds a task to the frame graph\r\n     * @param task Task to add\r\n     */\r\n    public addTask(task: FrameGraphTask): void {\r\n        if (this._currentProcessedTask !== null) {\r\n            throw new Error(`FrameGraph.addTask: Can't add the task \"${task.name}\" while another task is currently building (task: ${this._currentProcessedTask.name}).`);\r\n        }\r\n\r\n        if (this._tasks.includes(task)) {\r\n            return;\r\n        }\r\n\r\n        this._tasks.push(task);\r\n        this._initAsyncPromises.push(task.initAsync());\r\n    }\r\n\r\n    /**\r\n     * Adds a pass to a task. This method can only be called during a Task.record execution.\r\n     * @param name The name of the pass\r\n     * @param whenTaskDisabled If true, the pass will be added to the list of passes to execute when the task is disabled (default is false)\r\n     * @returns The render pass created\r\n     */\r\n    public addPass(name: string, whenTaskDisabled = false): FrameGraphPass<FrameGraphContext> {\r\n        return this._addPass(name, FrameGraphPassType.Normal, whenTaskDisabled) as FrameGraphPass<FrameGraphContext>;\r\n    }\r\n\r\n    /**\r\n     * Adds a render pass to a task. This method can only be called during a Task.record execution.\r\n     * @param name The name of the pass\r\n     * @param whenTaskDisabled If true, the pass will be added to the list of passes to execute when the task is disabled (default is false)\r\n     * @returns The render pass created\r\n     */\r\n    public addRenderPass(name: string, whenTaskDisabled = false): FrameGraphRenderPass {\r\n        return this._addPass(name, FrameGraphPassType.Render, whenTaskDisabled) as FrameGraphRenderPass;\r\n    }\r\n\r\n    /**\r\n     * Adds an object list pass to a task. This method can only be called during a Task.record execution.\r\n     * @param name The name of the pass\r\n     * @param whenTaskDisabled If true, the pass will be added to the list of passes to execute when the task is disabled (default is false)\r\n     * @returns The object list pass created\r\n     */\r\n    public addObjectListPass(name: string, whenTaskDisabled = false): FrameGraphObjectListPass {\r\n        return this._addPass(name, FrameGraphPassType.ObjectList, whenTaskDisabled) as FrameGraphObjectListPass;\r\n    }\r\n\r\n    private _addPass(name: string, passType: FrameGraphPassType, whenTaskDisabled = false): FrameGraphPass<FrameGraphContext> | FrameGraphRenderPass {\r\n        if (!this._currentProcessedTask) {\r\n            throw new Error(\"FrameGraph: A pass must be created during a Task.record execution only.\");\r\n        }\r\n\r\n        let pass: FrameGraphPass<FrameGraphContext> | FrameGraphRenderPass;\r\n\r\n        switch (passType) {\r\n            case FrameGraphPassType.Render:\r\n                pass = new FrameGraphRenderPass(name, this._currentProcessedTask, this._renderContext, this._engine);\r\n                break;\r\n            case FrameGraphPassType.ObjectList:\r\n                pass = new FrameGraphObjectListPass(name, this._currentProcessedTask, this._passContext, this._engine);\r\n                break;\r\n            default:\r\n                pass = new FrameGraphPass(name, this._currentProcessedTask, this._passContext);\r\n                break;\r\n        }\r\n\r\n        this._currentProcessedTask._addPass(pass, whenTaskDisabled);\r\n\r\n        return pass;\r\n    }\r\n\r\n    /** @internal */\r\n    public async _whenAsynchronousInitializationDoneAsync(): Promise<void> {\r\n        if (this._initAsyncPromises.length > 0) {\r\n            await Promise.all(this._initAsyncPromises);\r\n            this._initAsyncPromises.length = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Builds the frame graph.\r\n     * This method should be called after all tasks have been added to the frame graph (FrameGraph.addTask) and before the graph is executed (FrameGraph.execute).\r\n     * @param waitForReadiness If true, the method will wait for the frame graph to be ready before returning (default is true)\r\n     */\r\n    public async buildAsync(waitForReadiness = true): Promise<void> {\r\n        this.textureManager._releaseTextures(false);\r\n\r\n        this.pausedExecution = true;\r\n\r\n        try {\r\n            await this._importPromise;\r\n\r\n            await this._whenAsynchronousInitializationDoneAsync();\r\n\r\n            for (const task of this._tasks) {\r\n                task._reset();\r\n\r\n                this._currentProcessedTask = task;\r\n                this.textureManager._isRecordingTask = true;\r\n\r\n                task.record();\r\n\r\n                this.textureManager._isRecordingTask = false;\r\n                this._currentProcessedTask = null;\r\n            }\r\n\r\n            this.textureManager._allocateTextures(this.optimizeTextureAllocation ? this._tasks : undefined);\r\n\r\n            for (const task of this._tasks) {\r\n                task._checkTask();\r\n            }\r\n\r\n            for (const task of this._tasks) {\r\n                task.onTexturesAllocatedObservable.notifyObservers(this._renderContext);\r\n            }\r\n\r\n            for (const task of this._tasks) {\r\n                task._initializePasses();\r\n            }\r\n\r\n            this.onBuildObservable.notifyObservers(this);\r\n\r\n            if (waitForReadiness) {\r\n                await this.whenReadyAsync();\r\n            }\r\n        } catch (e) {\r\n            this._tasks.length = 0;\r\n            this._currentProcessedTask = null;\r\n            this.textureManager._isRecordingTask = false;\r\n            throw e;\r\n        } finally {\r\n            this.pausedExecution = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if the frame graph is ready to be executed.\r\n     * Note that you can use the whenReadyAsync method to wait for the frame graph to be ready.\r\n     * @returns True if the frame graph is ready to be executed, else false\r\n     */\r\n    public isReady(): boolean {\r\n        let ready = this._renderContext._isReady();\r\n        for (const task of this._tasks) {\r\n            ready &&= task.isReady();\r\n        }\r\n        return ready;\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves when the frame graph is ready to be executed.\r\n     * In general, calling “await buildAsync()” should suffice, as this function also waits for readiness by default.\r\n     * @param timeStep Time step in ms between retries (default is 16)\r\n     * @param maxTimeout Maximum time in ms to wait for the graph to be ready (default is 10000)\r\n     * @returns The promise that resolves when the graph is ready\r\n     */\r\n    public async whenReadyAsync(timeStep = 16, maxTimeout = 10000): Promise<void> {\r\n        let firstNotReadyTask: FrameGraphTask | null = null;\r\n\r\n        return await new Promise((resolve, reject) => {\r\n            this._whenReadyAsyncCancel = _RetryWithInterval(\r\n                () => {\r\n                    firstNotReadyTask = null;\r\n                    let ready = this._renderContext._isReady();\r\n                    for (const task of this._tasks) {\r\n                        const taskIsReady = task.isReady();\r\n                        if (!taskIsReady && !firstNotReadyTask) {\r\n                            firstNotReadyTask = task;\r\n                        }\r\n                        ready &&= taskIsReady;\r\n                    }\r\n                    return ready;\r\n                },\r\n                () => {\r\n                    this._whenReadyAsyncCancel = null;\r\n                    resolve();\r\n                },\r\n                (err, isTimeout) => {\r\n                    this._whenReadyAsyncCancel = null;\r\n                    if (!isTimeout) {\r\n                        Logger.Error(\"FrameGraph: An unexpected error occurred while waiting for the frame graph to be ready.\");\r\n                        if (err) {\r\n                            Logger.Error(err);\r\n                            if (err.stack) {\r\n                                Logger.Error(err.stack);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        Logger.Error(\r\n                            `FrameGraph: Timeout while waiting for the frame graph to be ready.${firstNotReadyTask ? ` First task not ready: ${firstNotReadyTask.name}` : \"\"}`\r\n                        );\r\n                        if (err) {\r\n                            Logger.Error(err);\r\n                        }\r\n                    }\r\n                    reject(new Error(err));\r\n                },\r\n                timeStep,\r\n                maxTimeout\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Executes the frame graph.\r\n     */\r\n    public execute(): void {\r\n        if (this.pausedExecution) {\r\n            return;\r\n        }\r\n\r\n        this._renderContext.restoreDefaultFramebuffer();\r\n\r\n        this.textureManager._updateHistoryTextures();\r\n\r\n        for (const task of this._tasks) {\r\n            task._execute();\r\n        }\r\n\r\n        this._renderContext.restoreDefaultFramebuffer();\r\n    }\r\n\r\n    /**\r\n     * Clears the frame graph (remove the tasks and release the textures).\r\n     * The frame graph can be built again after this method is called.\r\n     */\r\n    public clear(): void {\r\n        this._whenReadyAsyncCancel?.();\r\n        this._whenReadyAsyncCancel = null;\r\n\r\n        for (const task of this._tasks) {\r\n            task._reset();\r\n        }\r\n\r\n        this._tasks.length = 0;\r\n        this.textureManager._releaseTextures();\r\n        this._currentProcessedTask = null;\r\n    }\r\n\r\n    /**\r\n     * Looks for the main camera used by the frame graph.\r\n     * By default, this is the camera used by the main object renderer task.\r\n     * If no such task, we try to find a camera in a utility layer renderer tasks.\r\n     * @returns The main camera used by the frame graph, or null if not found\r\n     */\r\n    public findMainCamera(): Nullable<Camera> {\r\n        const mainObjectRenderer = this.findMainObjectRenderer();\r\n        if (mainObjectRenderer) {\r\n            return mainObjectRenderer.camera;\r\n        }\r\n\r\n        // Try to find a camera in the utility layer renderer tasks\r\n        const tasks = this.tasks;\r\n\r\n        for (let i = tasks.length - 1; i >= 0; i--) {\r\n            const task = tasks[i];\r\n            if (task.getClassName() === \"FrameGraphUtilityLayerRendererTask\") {\r\n                return (task as unknown as { camera: Camera }).camera;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Looks for the main object renderer task in the frame graph.\r\n     * By default, this is the object/geometry renderer task with isMainObjectRenderer set to true.\r\n     * If no such task, we return the last object/geometry renderer task that has an object list with meshes (or null if none found).\r\n     * @returns The main object renderer of the frame graph, or null if not found\r\n     */\r\n    public findMainObjectRenderer(): Nullable<FrameGraphObjectRendererTask> {\r\n        const objectRenderers = this.getTasksByClassNames<FrameGraphObjectRendererTask>([\"FrameGraphObjectRendererTask\", \"FrameGraphGeometryRendererTask\"]);\r\n\r\n        let fallbackRenderer: Nullable<FrameGraphObjectRendererTask> = null;\r\n        for (let i = objectRenderers.length - 1; i >= 0; --i) {\r\n            const meshes = objectRenderers[i].objectList.meshes;\r\n            if (objectRenderers[i].isMainObjectRenderer) {\r\n                return objectRenderers[i];\r\n            }\r\n            if ((!meshes || meshes.length > 0) && !fallbackRenderer) {\r\n                fallbackRenderer = objectRenderers[i];\r\n            }\r\n        }\r\n        return fallbackRenderer;\r\n    }\r\n\r\n    /**\r\n     * Disposes the frame graph\r\n     */\r\n    public dispose(): void {\r\n        this._whenReadyAsyncCancel?.();\r\n        this._whenReadyAsyncCancel = null;\r\n        this.clear();\r\n        this.textureManager._dispose();\r\n        this._renderContext._dispose();\r\n\r\n        this._scene.removeFrameGraph(this);\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { MetadataSymbol } from \"../Misc/decorators.functions\";\r\n\r\n/**\r\n * Enum defining the type of properties that can be edited in the property pages in the node editor\r\n */\r\nexport const enum PropertyTypeForEdition {\r\n    /** property is a boolean */\r\n    Boolean,\r\n    /** property is a float */\r\n    Float,\r\n    /** property is a int */\r\n    Int,\r\n    /** property is a Vector2 */\r\n    Vector2,\r\n    /** property is a Vector3 */\r\n    Vector3,\r\n    /** property is a list of values */\r\n    List,\r\n    /** property is a Color3 */\r\n    Color3,\r\n    /** property is a Color4 */\r\n    Color4,\r\n    /** property (int) should be edited as a combo box with a list of sampling modes */\r\n    SamplingMode,\r\n    /** property (int) should be edited as a combo box with a list of texture formats */\r\n    TextureFormat,\r\n    /** property (int) should be edited as a combo box with a list of texture types */\r\n    TextureType,\r\n    /** property is a string */\r\n    String,\r\n    /** property is a matrix */\r\n    Matrix,\r\n    /** property is a viewport */\r\n    Viewport,\r\n}\r\n\r\n/**\r\n * Interface that defines an option in a variable of type list\r\n */\r\nexport interface IEditablePropertyListOption {\r\n    /** label of the option */\r\n    label: string;\r\n    /** value of the option */\r\n    value: number;\r\n}\r\n\r\n/**\r\n * Interface that defines the options available for an editable property\r\n */\r\nexport interface IEditablePropertyOption {\r\n    /**\r\n     * Define if the property is displayed inside the source block or in a separate property tab\r\n     */\r\n    embedded?: boolean;\r\n    /** min value */\r\n    min?: number;\r\n    /** max value */\r\n    max?: number;\r\n    /** notifiers: indicates which actions to take when the property is changed */\r\n    notifiers?: {\r\n        /** the entity should be rebuilt */\r\n        rebuild?: boolean;\r\n        /** the preview should be updated */\r\n        update?: boolean;\r\n        /** the onPreviewCommandActivated observer of the preview manager should be triggered */\r\n        activatePreviewCommand?: boolean;\r\n        /** a callback to trigger */\r\n        callback?: (scene: Nullable<Scene>, block: any) => boolean | undefined | void;\r\n        /** a callback to validate the property. Returns true if the property is ok, else false. If false, the rebuild/update/callback events won't be called */\r\n        onValidation?: (block: any, propertyName: string) => boolean;\r\n    };\r\n    /** list of the options for a variable of type list */\r\n    options?: IEditablePropertyListOption[];\r\n}\r\n\r\n/**\r\n * Interface that describes an editable property\r\n */\r\nexport interface IPropertyDescriptionForEdition {\r\n    /** name of the property */\r\n    propertyName: string;\r\n    /** display name of the property */\r\n    displayName: string;\r\n    /** type of the property */\r\n    type: PropertyTypeForEdition;\r\n    /** group of the property - all properties with the same group value will be displayed in a specific section */\r\n    groupName: string;\r\n    /** options for the property */\r\n    options: IEditablePropertyOption;\r\n    /** name of the class that contains the property */\r\n    className: string;\r\n}\r\n\r\n/**\r\n * Decorator that flags a property in a node block as being editable\r\n * @param displayName the display name of the property\r\n * @param propertyType the type of the property\r\n * @param groupName the group name of the property\r\n * @param options the options of the property\r\n * @returns the decorator\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function editableInPropertyPage(\r\n    displayName: string,\r\n    propertyType: PropertyTypeForEdition = PropertyTypeForEdition.Boolean,\r\n    groupName: string = \"PROPERTIES\",\r\n    options?: IEditablePropertyOption\r\n) {\r\n    return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => {\r\n        const meta = context.metadata as DecoratorMetadataObject | undefined;\r\n        if (!meta) {\r\n            // `context.metadata` is `void 0` when `Symbol.metadata` was not installed before this class\r\n            // was evaluated. Importing `MetadataSymbol` from decorators.functions runs the polyfill at\r\n            // module load (before this class body), so this should never happen; referencing it here also\r\n            // keeps that module-load polyfill anchored against bundler tree-shaking.\r\n            throw new Error(\r\n                `editableInPropertyPage: decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated.`\r\n            );\r\n        }\r\n        let propStore: IPropertyDescriptionForEdition[];\r\n        if (Object.prototype.hasOwnProperty.call(meta, __bjsPropStoreKey)) {\r\n            propStore = meta[__bjsPropStoreKey] as IPropertyDescriptionForEdition[];\r\n        } else {\r\n            propStore = [];\r\n            meta[__bjsPropStoreKey] = propStore;\r\n        }\r\n        propStore.push({\r\n            propertyName: String(context.name),\r\n            displayName: displayName,\r\n            type: propertyType,\r\n            groupName: groupName,\r\n            options: options ?? {},\r\n            className: \"\",\r\n        });\r\n    };\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst __bjsPropStoreKey = \"__bjs_prop_store__\";\r\n\r\n/**\r\n * Gets the editable properties for a given target using TC39 decorator metadata.\r\n * Walks the metadata prototype chain to include properties from parent classes.\r\n * @param target - the target object (instance or constructor)\r\n * @returns array of property descriptions\r\n */\r\nexport function GetEditableProperties(target: any): IPropertyDescriptionForEdition[] {\r\n    const ctor = typeof target === \"function\" ? target : target?.constructor;\r\n    const metadata: DecoratorMetadataObject | undefined = ctor?.[MetadataSymbol];\r\n    if (!metadata) {\r\n        return [];\r\n    }\r\n\r\n    const result: IPropertyDescriptionForEdition[] = [];\r\n    let currentMeta: any = metadata;\r\n    while (currentMeta) {\r\n        if (Object.prototype.hasOwnProperty.call(currentMeta, __bjsPropStoreKey)) {\r\n            const store = currentMeta[__bjsPropStoreKey] as IPropertyDescriptionForEdition[];\r\n            result.push(...store);\r\n        }\r\n        currentMeta = Object.getPrototypeOf(currentMeta);\r\n    }\r\n    return result;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type NodeRenderGraphConnectionPoint,\r\n    type Scene,\r\n    type FrameGraph,\r\n    type NodeRenderGraphBuildState,\r\n    type Camera,\r\n    type InternalTexture,\r\n    type Nullable,\r\n    type FrameGraphTextureCreationOptions,\r\n    type FrameGraphTextureHandle,\r\n    type FrameGraphObjectList,\r\n    type IShadowLight,\r\n} from \"core/index\";\r\nimport { Observable } from \"../../../Misc/observable.pure\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { backbufferColorTextureHandle, backbufferDepthStencilTextureHandle } from \"../../../FrameGraph/frameGraphTypes\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\nexport type NodeRenderGraphValueType = InternalTexture | Camera | FrameGraphObjectList | IShadowLight;\r\n\r\nexport type NodeRenderGraphInputCreationOptions = FrameGraphTextureCreationOptions;\r\n\r\n/**\r\n * Block used to expose an input value\r\n */\r\nexport class NodeRenderGraphInputBlock extends NodeRenderGraphBlock {\r\n    private _storedValue: Nullable<NodeRenderGraphValueType> = null;\r\n    private _type: NodeRenderGraphBlockConnectionPointTypes = NodeRenderGraphBlockConnectionPointTypes.Undefined;\r\n\r\n    /** Gets an observable raised when the value is changed */\r\n    public onValueChangedObservable = new Observable<NodeRenderGraphInputBlock>();\r\n\r\n    /** Indicates that the input is externally managed */\r\n    @editableInPropertyPage(\"Is external\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public isExternal = false;\r\n\r\n    /** Gets or sets the options to create the input value */\r\n    public creationOptions: NodeRenderGraphInputCreationOptions;\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is Undefined)\r\n     */\r\n    public get type(): NodeRenderGraphBlockConnectionPointTypes {\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeRenderGraphInputBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param type defines the type of the input (can be set to NodeRenderGraphBlockConnectionPointTypes.Undefined)\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, type: NodeRenderGraphBlockConnectionPointTypes = NodeRenderGraphBlockConnectionPointTypes.Undefined) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._type = type;\r\n        this._isInput = true;\r\n        this.registerOutput(\"output\", type);\r\n        this.setDefaultValue();\r\n    }\r\n\r\n    /**\r\n     * Set the input block to its default value (based on its type)\r\n     */\r\n    public setDefaultValue() {\r\n        switch (this.type) {\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureMeshBlendTag: {\r\n                const options: FrameGraphTextureCreationOptions = {\r\n                    size: { width: 100, height: 100 },\r\n                    options: {\r\n                        createMipMaps: false,\r\n                        targetTypes: [Constants.TEXTURE_2D],\r\n                        types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                        formats: [Constants.TEXTUREFORMAT_RED_INTEGER],\r\n                        layerCounts: [0],\r\n                        samples: 1,\r\n                        useSRGBBuffers: [false],\r\n                        creationFlags: [0],\r\n                    },\r\n                    sizeIsPercentage: true,\r\n                    isHistoryTexture: false,\r\n                };\r\n                this.creationOptions = options;\r\n                break;\r\n            }\r\n            case NodeRenderGraphBlockConnectionPointTypes.Texture:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureNormalizedViewDepth:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureViewNormal:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureWorldNormal:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureAlbedo:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureReflectivity:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureLocalPosition:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureWorldPosition:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureVelocity:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureLinearVelocity:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureIrradiance:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureAlbedoSqrt:\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureObjectId: {\r\n                const options: FrameGraphTextureCreationOptions = {\r\n                    size: { width: 100, height: 100 },\r\n                    options: {\r\n                        createMipMaps: false,\r\n                        targetTypes: [Constants.TEXTURE_2D],\r\n                        types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                        formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                        layerCounts: [0],\r\n                        samples: 1,\r\n                        useSRGBBuffers: [false],\r\n                        creationFlags: [0],\r\n                    },\r\n                    sizeIsPercentage: true,\r\n                    isHistoryTexture: false,\r\n                };\r\n                this.creationOptions = options;\r\n                break;\r\n            }\r\n            case NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment: {\r\n                const options: FrameGraphTextureCreationOptions = {\r\n                    size: { width: 100, height: 100 },\r\n                    options: {\r\n                        createMipMaps: false,\r\n                        targetTypes: [Constants.TEXTURE_2D],\r\n                        types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                        formats: [Constants.TEXTUREFORMAT_DEPTH24_STENCIL8],\r\n                        layerCounts: [0],\r\n                        useSRGBBuffers: [false],\r\n                        creationFlags: [0],\r\n                        labels: [this.name],\r\n                        samples: 1,\r\n                    },\r\n                    sizeIsPercentage: true,\r\n                    isHistoryTexture: false,\r\n                };\r\n                this.creationOptions = options;\r\n                break;\r\n            }\r\n            case NodeRenderGraphBlockConnectionPointTypes.ObjectList:\r\n                this.value = { meshes: null, particleSystems: null, spriteManagers: null };\r\n                this.isExternal = true;\r\n                break;\r\n            case NodeRenderGraphBlockConnectionPointTypes.Camera:\r\n                this.value = this._scene.cameras[0];\r\n                this.isExternal = true;\r\n                break;\r\n            default:\r\n                this.isExternal = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the value of that point.\r\n     */\r\n    public get value(): Nullable<NodeRenderGraphValueType> {\r\n        return this._storedValue;\r\n    }\r\n\r\n    public set value(value: Nullable<NodeRenderGraphValueType>) {\r\n        this._storedValue = value;\r\n        this.output.value = undefined;\r\n        this.onValueChangedObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the value as a specific type\r\n     * @returns the value as a specific type\r\n     */\r\n    public getTypedValue<T extends NodeRenderGraphValueType>(): T {\r\n        return this._storedValue as T;\r\n    }\r\n\r\n    /**\r\n     * Gets the value as an internal texture\r\n     * @returns The internal texture stored in value if value is an internal texture, otherwise null\r\n     */\r\n    public getInternalTextureFromValue(): Nullable<InternalTexture> {\r\n        if ((this._storedValue as InternalTexture)._swapAndDie) {\r\n            return this._storedValue as InternalTexture;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphInputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Check if the block is a texture of any type\r\n     * @returns true if the block is a texture\r\n     */\r\n    public isAnyTexture(): boolean {\r\n        return (this.type & NodeRenderGraphBlockConnectionPointTypes.TextureAll) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the connection point is the back buffer texture\r\n     * @returns true if the connection point is the back buffer texture\r\n     */\r\n    public isBackBuffer() {\r\n        return (this.type & NodeRenderGraphBlockConnectionPointTypes.TextureBackBuffer) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the connection point is a depth/stencil attachment texture\r\n     * @returns true if the connection point is a depth/stencil attachment texture\r\n     */\r\n    public isBackBufferDepthStencilAttachment() {\r\n        return (this.type & NodeRenderGraphBlockConnectionPointTypes.TextureBackBufferDepthStencilAttachment) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Check if the block is a camera\r\n     * @returns true if the block is a camera\r\n     */\r\n    public isCamera(): boolean {\r\n        return (this.type & NodeRenderGraphBlockConnectionPointTypes.Camera) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Check if the block is an object list\r\n     * @returns true if the block is an object list\r\n     */\r\n    public isObjectList(): boolean {\r\n        return (this.type & NodeRenderGraphBlockConnectionPointTypes.ObjectList) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Check if the block is a shadow light\r\n     * @returns true if the block is a shadow light\r\n     */\r\n    public isShadowLight(): boolean {\r\n        return (this.type & NodeRenderGraphBlockConnectionPointTypes.ShadowLight) !== 0;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (this.isExternal) {\r\n            if (this.isBackBuffer()) {\r\n                this.output.value = backbufferColorTextureHandle;\r\n            } else if (this.isBackBufferDepthStencilAttachment()) {\r\n                this.output.value = backbufferDepthStencilTextureHandle;\r\n            } else if (this.isCamera()) {\r\n                this.output.value = this.getTypedValue<Camera>();\r\n            } else if (this.isObjectList()) {\r\n                this.output.value = this.getTypedValue<FrameGraphObjectList>();\r\n            } else if (this.isShadowLight()) {\r\n                this.output.value = this.getTypedValue<IShadowLight>();\r\n            } else {\r\n                if (this._storedValue === undefined || this._storedValue === null) {\r\n                    throw new Error(`NodeRenderGraphInputBlock: External input \"${this.name}\" is not set`);\r\n                }\r\n                const texture = this.getInternalTextureFromValue();\r\n                if (texture) {\r\n                    this.output.value = this._frameGraph.textureManager.importTexture(this.name, texture, this.output.value as FrameGraphTextureHandle);\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        if ((this.type & NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer) !== 0) {\r\n            const textureCreateOptions = this.creationOptions;\r\n\r\n            if (!textureCreateOptions) {\r\n                throw new Error(`NodeRenderGraphInputBlock: Creation options are missing for texture \"${this.name}\"`);\r\n            }\r\n\r\n            this.output.value = this._frameGraph.textureManager.createRenderTargetTexture(this.name, textureCreateOptions);\r\n        }\r\n    }\r\n\r\n    public override dispose() {\r\n        this._storedValue = null;\r\n        this.onValueChangedObservable.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.isExternal = ${this.isExternal};`);\r\n        if (this.isAnyTexture()) {\r\n            if (!this.isExternal) {\r\n                codes.push(`${this._codeVariableName}.creationOptions = ${JSON.stringify(this.creationOptions)};`);\r\n            } else {\r\n                codes.push(`${this._codeVariableName}.value = EXTERNAL_TEXTURE; // TODO: set the external texture`);\r\n            }\r\n        } else if (this.isCamera()) {\r\n            codes.push(`${this._codeVariableName}.value = EXTERNAL_CAMERA; // TODO: set the external camera`);\r\n        } else if (this.isObjectList()) {\r\n            codes.push(`${this._codeVariableName}.value = EXTERNAL_OBJECT_LIST; // TODO: set the external object list`);\r\n        } else if (this.isShadowLight()) {\r\n            codes.push(`${this._codeVariableName}.value = EXTERNAL_SHADOW_LIGHT; // TODO: set the external shadow light`);\r\n        }\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.type = this.type;\r\n        serializationObject.isExternal = this.isExternal;\r\n        if (this.creationOptions) {\r\n            serializationObject.creationOptions = this.creationOptions;\r\n        }\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this._type = serializationObject.type;\r\n        this.output.type = this._type;\r\n        this.isExternal = serializationObject.isExternal;\r\n        if (serializationObject.creationOptions) {\r\n            if (serializationObject.creationOptions.options.depthTextureFormat !== undefined) {\r\n                // Backward compatibility - remove this code in the future\r\n                serializationObject.creationOptions.options.formats = [serializationObject.creationOptions.options.depthTextureFormat];\r\n            }\r\n            this.creationOptions = serializationObject.creationOptions;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for frameGraphNodeBlocksInputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFrameGraphNodeBlocksInputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphInputBlock\", NodeRenderGraphInputBlock);\r\n}\r\n","import { type FrameGraphRenderPass, type LayerAndFaceIndex } from \"core/index\";\r\nimport { FrameGraphTask } from \"./frameGraphTask\";\r\n\r\n/**\r\n * Base class for frame graph tasks that involve multi-target rendering.\r\n */\r\nexport abstract class FrameGraphTaskMultiRenderTarget extends FrameGraphTask {\r\n    private _outputLayerAndFaceIndices: LayerAndFaceIndex[];\r\n    private _layerAndFaceIndicesUpdated = false;\r\n\r\n    /**\r\n     * Sets the output layer and face indices for multi-target rendering.\r\n     * @param indices The array of layer and face indices.\r\n     */\r\n    public setOutputLayerAndFaceIndices(indices: LayerAndFaceIndex[]) {\r\n        this._outputLayerAndFaceIndices = indices;\r\n        this._layerAndFaceIndicesUpdated = indices.length > 0;\r\n    }\r\n\r\n    protected _updateLayerAndFaceIndices(pass: FrameGraphRenderPass) {\r\n        if (this._layerAndFaceIndicesUpdated) {\r\n            pass.setOutputLayerAndFaceIndices(this._outputLayerAndFaceIndices);\r\n            this._layerAndFaceIndicesUpdated = false;\r\n        }\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass } from \"core/index\";\r\nimport { Color4, TmpColors } from \"../../../Maths/math.color.pure\";\r\nimport { FrameGraphTaskMultiRenderTarget } from \"../../frameGraphTaskMultiRenderTarget\";\r\nimport { backbufferColorTextureHandle } from \"../../frameGraphTypes\";\r\n\r\n/**\r\n * Task used to clear a texture.\r\n */\r\nexport class FrameGraphClearTextureTask extends FrameGraphTaskMultiRenderTarget {\r\n    /**\r\n     * The color to clear the texture with.\r\n     */\r\n    public color = new Color4(0.2, 0.2, 0.3, 1);\r\n\r\n    /**\r\n     * If the color should be cleared.\r\n     */\r\n    public clearColor = true;\r\n\r\n    /**\r\n     * If the color should be converted to linear space (default: false).\r\n     */\r\n    public convertColorToLinearSpace = false;\r\n\r\n    /**\r\n     * If the depth should be cleared.\r\n     */\r\n    public clearDepth = false;\r\n\r\n    /**\r\n     * If the stencil should be cleared.\r\n     */\r\n    public clearStencil = false;\r\n\r\n    /**\r\n     * The value to use to clear the stencil buffer (default: 0).\r\n     */\r\n    public stencilValue = 0;\r\n\r\n    /**\r\n     * The color texture to clear.\r\n     */\r\n    public targetTexture?: FrameGraphTextureHandle | FrameGraphTextureHandle[];\r\n\r\n    /**\r\n     * The depth attachment texture to clear.\r\n     */\r\n    public depthTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture (same as targetTexture, but the handle will be different).\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output depth texture (same as depthTexture, but the handle will be different).\r\n     */\r\n    public readonly outputDepthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Constructs a new clear task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.outputDepthTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphClearTextureTask\";\r\n    }\r\n\r\n    public record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.targetTexture === undefined && this.depthTexture === undefined) {\r\n            throw new Error(`FrameGraphClearTextureTask ${this.name}: targetTexture and depthTexture can't both be undefined.`);\r\n        }\r\n\r\n        const textureManager = this._frameGraph.textureManager;\r\n        const targetTextures = this.targetTexture !== undefined ? (Array.isArray(this.targetTexture) ? this.targetTexture : [this.targetTexture]) : undefined;\r\n\r\n        if (this.targetTexture !== undefined) {\r\n            textureManager.resolveDanglingHandle(this.outputTexture, targetTextures![0]);\r\n        }\r\n        if (this.depthTexture !== undefined) {\r\n            textureManager.resolveDanglingHandle(this.outputDepthTexture, this.depthTexture);\r\n        }\r\n        if (this.targetTexture !== undefined && this.depthTexture !== undefined) {\r\n            const targetDescription = textureManager.getTextureDescription(targetTextures![0]);\r\n            const depthDescription = textureManager.getTextureDescription(this.depthTexture);\r\n\r\n            if (targetDescription.size.width !== depthDescription.size.width || targetDescription.size.height !== depthDescription.size.height) {\r\n                throw new Error(\r\n                    `FrameGraphClearTextureTask ${this.name}: the depth texture (size: ${depthDescription.size.width}x${depthDescription.size.height}) and the target texture (size: ${targetDescription.size.width}x${targetDescription.size.height}) must have the same dimensions.`\r\n                );\r\n            }\r\n\r\n            const textureSamples = targetDescription.options.samples || 1;\r\n            const depthSamples = depthDescription.options.samples || 1;\r\n\r\n            if (textureSamples !== depthSamples && textureSamples !== 0 && depthSamples !== 0) {\r\n                throw new Error(\r\n                    `FrameGraphClearTextureTask ${this.name}: the depth texture (${depthSamples} samples) and the target texture (${textureSamples} samples) must have the same number of samples.`\r\n                );\r\n            }\r\n        }\r\n\r\n        const attachments = this._frameGraph.engine.buildTextureLayout(\r\n            targetTextures ? Array(targetTextures.length).fill(true) : [],\r\n            this.targetTexture === backbufferColorTextureHandle && !this._frameGraph.textureManager.backBufferTextureOverriden\r\n        );\r\n\r\n        const color = TmpColors.Color4[0];\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.setRenderTarget(targetTextures);\r\n        pass.setRenderTargetDepth(this.depthTexture);\r\n        pass.setInitializeFunc(() => {\r\n            const renderTargetWrapper = pass.frameGraphRenderTarget.renderTargetWrapper;\r\n            if (renderTargetWrapper) {\r\n                renderTargetWrapper.disableAutomaticMSAAResolve = true;\r\n            }\r\n        });\r\n        pass.setExecuteFunc((context) => {\r\n            this._updateLayerAndFaceIndices(pass);\r\n\r\n            color.copyFrom(this.color);\r\n            if (this.convertColorToLinearSpace) {\r\n                color.toLinearSpaceToRef(color);\r\n            }\r\n\r\n            context.clearAttachments(color, attachments, !!this.clearColor, !!this.clearDepth, !!this.clearStencil, this.stencilValue);\r\n        });\r\n\r\n        if (!skipCreationOfDisabledPasses) {\r\n            const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n            passDisabled.setRenderTarget(targetTextures);\r\n            passDisabled.setRenderTargetDepth(this.depthTexture);\r\n            passDisabled.setExecuteFunc((_context) => {});\r\n        }\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraphTextureHandle, type FrameGraph, type NodeRenderGraphBuildState, type NodeRenderGraphConnectionPoint } from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { Color4 } from \"../../../../Maths/math.color.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphClearTextureTask } from \"../../../Tasks/Texture/clearTextureTask\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clear a texture\r\n */\r\nexport class NodeRenderGraphClearBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphClearTextureTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphClearBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"depth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n        this.registerOutput(\"outputDepth\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAll | NodeRenderGraphBlockConnectionPointTypes.ResourceContainer);\r\n        this.depth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment | NodeRenderGraphBlockConnectionPointTypes.TextureBackBufferDepthStencilAttachment\r\n        );\r\n\r\n        this.output._typeConnectionSource = this.target;\r\n        this.outputDepth._typeConnectionSource = this.depth;\r\n\r\n        this._frameGraphTask = new FrameGraphClearTextureTask(name, frameGraph);\r\n    }\r\n\r\n    /** Gets or sets the clear color */\r\n    @editableInPropertyPage(\"Color\", PropertyTypeForEdition.Color4)\r\n    public get color(): Color4 {\r\n        return this._frameGraphTask.color;\r\n    }\r\n\r\n    public set color(value: Color4) {\r\n        this._frameGraphTask.color = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating whether the color part of the texture should be cleared. */\r\n    @editableInPropertyPage(\"Clear color\", PropertyTypeForEdition.Boolean, undefined, { embedded: true })\r\n    public get clearColor(): boolean {\r\n        return !!this._frameGraphTask.clearColor;\r\n    }\r\n\r\n    public set clearColor(value: boolean) {\r\n        this._frameGraphTask.clearColor = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating whether the color should be converted to linear space. */\r\n    @editableInPropertyPage(\"Convert color to linear space\", PropertyTypeForEdition.Boolean)\r\n    public get convertColorToLinearSpace(): boolean {\r\n        return !!this._frameGraphTask.convertColorToLinearSpace;\r\n    }\r\n\r\n    public set convertColorToLinearSpace(value: boolean) {\r\n        this._frameGraphTask.convertColorToLinearSpace = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating whether the depth part of the texture should be cleared. */\r\n    @editableInPropertyPage(\"Clear depth\", PropertyTypeForEdition.Boolean, undefined, { embedded: true })\r\n    public get clearDepth(): boolean {\r\n        return !!this._frameGraphTask.clearDepth;\r\n    }\r\n\r\n    public set clearDepth(value: boolean) {\r\n        this._frameGraphTask.clearDepth = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating whether the stencil part of the texture should be cleared. */\r\n    @editableInPropertyPage(\"Clear stencil\", PropertyTypeForEdition.Boolean, undefined, { embedded: true })\r\n    public get clearStencil(): boolean {\r\n        return !!this._frameGraphTask.clearStencil;\r\n    }\r\n\r\n    public set clearStencil(value: boolean) {\r\n        this._frameGraphTask.clearStencil = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphClearBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth texture input component\r\n     */\r\n    public get depth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output depth component\r\n     */\r\n    public get outputDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n        this.outputDepth.value = this._frameGraphTask.outputDepthTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this._getConnectedTextures(this.target.connectedPoint);\r\n        this._frameGraphTask.depthTexture = this.depth.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.color = new BABYLON.Color4(${this.color.r}, ${this.color.g}, ${this.color.b}, ${this.color.a});`);\r\n        codes.push(`${this._codeVariableName}.clearColor = ${this.clearColor};`);\r\n        codes.push(`${this._codeVariableName}.convertColorToLinearSpace = ${this.convertColorToLinearSpace};`);\r\n        codes.push(`${this._codeVariableName}.clearDepth = ${this.clearDepth};`);\r\n        codes.push(`${this._codeVariableName}.clearStencil = ${this.clearStencil};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.color = this.color.asArray();\r\n        serializationObject.clearColor = this.clearColor;\r\n        serializationObject.convertColorToLinearSpace = this.convertColorToLinearSpace;\r\n        serializationObject.clearDepth = this.clearDepth;\r\n        serializationObject.clearStencil = this.clearStencil;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.color = Color4.FromArray(serializationObject.color);\r\n        this.clearColor = serializationObject.clearColor;\r\n        this.convertColorToLinearSpace = !!serializationObject.convertColorToLinearSpace;\r\n        this.clearDepth = serializationObject.clearDepth;\r\n        this.clearStencil = serializationObject.clearStencil;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for clearBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterClearBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphClearBlock\", NodeRenderGraphClearBlock);\r\n}\r\n","import { type NodeRenderGraphConnectionPointDirection, type NodeRenderGraphBlock, type Nullable } from \"core/index\";\r\nimport { NodeRenderGraphConnectionPoint } from \"./nodeRenderGraphBlockConnectionPoint\";\r\nimport { NodeRenderGraphConnectionPointCompatibilityStates } from \"./Types/nodeRenderGraphTypes\";\r\n\r\n/**\r\n * Defines a connection point to be used for points with a custom object type\r\n */\r\nexport class NodeRenderGraphConnectionPointCustomObject<T extends NodeRenderGraphBlock> extends NodeRenderGraphConnectionPoint {\r\n    /**\r\n     * Creates a new connection point\r\n     * @param name defines the connection point name\r\n     * @param ownerBlock defines the block hosting this connection point\r\n     * @param direction defines the direction of the connection point\r\n     * @param _blockType\r\n     * @param _blockName\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        ownerBlock: NodeRenderGraphBlock,\r\n        direction: NodeRenderGraphConnectionPointDirection,\r\n        // @internal\r\n        public _blockType: new (...args: any[]) => T,\r\n        private _blockName: string\r\n    ) {\r\n        super(name, ownerBlock, direction);\r\n\r\n        this.needDualDirectionValidation = true;\r\n    }\r\n\r\n    public override checkCompatibilityState(connectionPoint: NodeRenderGraphConnectionPoint): NodeRenderGraphConnectionPointCompatibilityStates {\r\n        return connectionPoint instanceof NodeRenderGraphConnectionPointCustomObject && connectionPoint._blockName === this._blockName\r\n            ? NodeRenderGraphConnectionPointCompatibilityStates.Compatible\r\n            : NodeRenderGraphConnectionPointCompatibilityStates.TypeIncompatible;\r\n    }\r\n\r\n    public override createCustomInputBlock(): Nullable<[NodeRenderGraphBlock, string]> {\r\n        return [new this._blockType(this._blockName), this.name];\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Implementation based on https://medium.com/@shrekshao_71662/dual-depth-peeling-implementation-in-webgl-11baa061ba4b\r\n */\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { MultiRenderTarget } from \"../Materials/Textures/multiRenderTarget.pure\";\r\nimport { type InternalTextureCreationOptions } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { EffectRenderer, EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { type PrePassRenderer } from \"./prePassRenderer.pure\";\r\nimport { type IMaterialContext } from \"../Engines/IMaterialContext\";\r\nimport { type DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { Material } from \"../Materials/material.pure\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinDepthPeelingRenderer {\r\n    protected _scene: Scene;\r\n    protected _engine: AbstractEngine;\r\n    protected _depthMrts: MultiRenderTarget[] = [];\r\n    protected _thinTextures: ThinTexture[] = [];\r\n    protected _colorMrts: MultiRenderTarget[] = [];\r\n    protected _blendBackMrt: MultiRenderTarget;\r\n\r\n    protected _blendBackEffectWrapper: EffectWrapper;\r\n    protected _blendBackEffectWrapperPingPong: EffectWrapper;\r\n    protected _finalEffectWrapper: EffectWrapper;\r\n    protected _effectRenderer: EffectRenderer;\r\n\r\n    protected _currentPingPongState: number = 0;\r\n\r\n    protected _layoutCacheFormat = [[true], [true, true], [true, true, true]];\r\n    protected _layoutCache: number[][] = [];\r\n    protected _renderPassIds: number[];\r\n    protected _candidateSubMeshes: SmartArray<SubMesh> = new SmartArray(10);\r\n    protected _excludedSubMeshes: SmartArray<SubMesh> = new SmartArray(10);\r\n    protected _excludedMeshes: number[] = [];\r\n\r\n    protected static _DEPTH_CLEAR_VALUE = -99999.0;\r\n    protected static _MIN_DEPTH = 0;\r\n    protected static _MAX_DEPTH = 1;\r\n\r\n    protected _colorCache = [\r\n        new Color4(ThinDepthPeelingRenderer._DEPTH_CLEAR_VALUE, ThinDepthPeelingRenderer._DEPTH_CLEAR_VALUE, 0, 0),\r\n        new Color4(-ThinDepthPeelingRenderer._MIN_DEPTH, ThinDepthPeelingRenderer._MAX_DEPTH, 0, 0),\r\n        new Color4(0, 0, 0, 0),\r\n    ];\r\n\r\n    protected _passCount: number;\r\n    /**\r\n     * Number of depth peeling passes. As we are using dual depth peeling, each pass two levels of transparency are processed.\r\n     */\r\n    public get passCount(): number {\r\n        return this._passCount;\r\n    }\r\n\r\n    public set passCount(count: number) {\r\n        if (this._passCount === count) {\r\n            return;\r\n        }\r\n        this._passCount = count;\r\n        this._createRenderPassIds();\r\n    }\r\n\r\n    protected _useRenderPasses: boolean;\r\n    /**\r\n     * Instructs the renderer to use render passes. It is an optimization that makes the rendering faster for some engines (like WebGPU) but that consumes more memory, so it is disabled by default.\r\n     */\r\n    public get useRenderPasses() {\r\n        return this._useRenderPasses;\r\n    }\r\n\r\n    public set useRenderPasses(usePasses: boolean) {\r\n        if (this._useRenderPasses === usePasses) {\r\n            return;\r\n        }\r\n        this._useRenderPasses = usePasses;\r\n        this._createRenderPassIds();\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the exclusion list to prevent it to be handled by the depth peeling renderer\r\n     * @param mesh The mesh to exclude from the depth peeling renderer\r\n     */\r\n    public addExcludedMesh(mesh: AbstractMesh): void {\r\n        if (this._excludedMeshes.indexOf(mesh.uniqueId) === -1) {\r\n            this._excludedMeshes.push(mesh.uniqueId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the exclusion list of the depth peeling renderer\r\n     * @param mesh The mesh to remove\r\n     */\r\n    public removeExcludedMesh(mesh: AbstractMesh): void {\r\n        const index = this._excludedMeshes.indexOf(mesh.uniqueId);\r\n        if (index !== -1) {\r\n            this._excludedMeshes.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /** Shader language used by the renderer */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this renderer\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    private _blendOutput: Nullable<RenderTargetWrapper>;\r\n    /**\r\n     * Sets the render target wrapper we will blend the transparent objects onto\r\n     */\r\n    public get blendOutput(): Nullable<RenderTargetWrapper> {\r\n        return this._blendOutput;\r\n    }\r\n\r\n    public set blendOutput(blendOutput: Nullable<RenderTargetWrapper>) {\r\n        this._blendOutput = blendOutput;\r\n        this._disposeTextures();\r\n        if (blendOutput) {\r\n            this._createTextures();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instanciates the depth peeling renderer\r\n     * @param scene Scene to attach to\r\n     * @param passCount Number of depth layers to peel\r\n     * @returns The depth peeling renderer\r\n     */\r\n    constructor(scene: Scene, passCount: number = 5) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._passCount = passCount;\r\n\r\n        for (let i = 0; i < this._layoutCacheFormat.length; ++i) {\r\n            this._layoutCache[i] = this._engine.buildTextureLayout(this._layoutCacheFormat[i]);\r\n        }\r\n\r\n        this._renderPassIds = [];\r\n        this.useRenderPasses = false;\r\n\r\n        if (this._engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        this._createEffects(\"oitFinalSimpleBlend\", [\"uFrontColor\"]);\r\n    }\r\n\r\n    private _createRenderPassIds(): void {\r\n        this._releaseRenderPassIds();\r\n        if (this._useRenderPasses) {\r\n            for (let i = 0; i < this._passCount + 1; ++i) {\r\n                if (!this._renderPassIds[i]) {\r\n                    this._renderPassIds[i] = this._engine.createRenderPassId(`DepthPeelingRenderer - pass #${i}`);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _releaseRenderPassIds(): void {\r\n        for (let i = 0; i < this._renderPassIds.length; ++i) {\r\n            this._engine.releaseRenderPassId(this._renderPassIds[i]);\r\n        }\r\n        this._renderPassIds = [];\r\n    }\r\n\r\n    protected _getTextureSize(): { width: number; height: number } {\r\n        if (this._blendOutput) {\r\n            return {\r\n                width: this._blendOutput.width,\r\n                height: this._blendOutput.height,\r\n            };\r\n        }\r\n        return { width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() };\r\n    }\r\n\r\n    // TODO : support multiview for WebXR stereo rendering.\r\n    // Currently, the MRTs created here are mono (2D textures), so depth peeling only produces correct\r\n    // order-independent transparency for one view. In XR with OVR_multiview2, transparent objects that\r\n    // partially overlap other transparent objects may render incorrectly in one or both eyes — fragments\r\n    // behind a transparent surface can disappear or flicker depending on camera angle.\r\n    // To fix this, the MultiRenderTargets should use 2-layer texture arrays when the active XR session\r\n    // uses multiview, and the peeling shaders (oitBackBlend, oitFinal) should be updated to read/write\r\n    // via gl_ViewID_OVR so both eyes are peeled in a single pass.\r\n    protected _createTextures() {\r\n        const size = this._getTextureSize();\r\n\r\n        // 2 for ping pong\r\n        this._depthMrts = [\r\n            new MultiRenderTarget(\"depthPeelingDepth0MRT\", size, 3, this._scene, undefined, [\r\n                \"depthPeelingDepth0MRT_depth\",\r\n                \"depthPeelingDepth0MRT_frontColor\",\r\n                \"depthPeelingDepth0MRT_backColor\",\r\n            ]),\r\n            new MultiRenderTarget(\"depthPeelingDepth1MRT\", size, 3, this._scene, undefined, [\r\n                \"depthPeelingDepth1MRT_depth\",\r\n                \"depthPeelingDepth1MRT_frontColor\",\r\n                \"depthPeelingDepth1MRT_backColor\",\r\n            ]),\r\n        ];\r\n        this._colorMrts = [\r\n            new MultiRenderTarget(\"depthPeelingColor0MRT\", size, 2, this._scene, { generateDepthBuffer: false }, [\r\n                \"depthPeelingColor0MRT_frontColor\",\r\n                \"depthPeelingColor0MRT_backColor\",\r\n            ]),\r\n            new MultiRenderTarget(\"depthPeelingColor1MRT\", size, 2, this._scene, { generateDepthBuffer: false }, [\r\n                \"depthPeelingColor1MRT_frontColor\",\r\n                \"depthPeelingColor1MRT_backColor\",\r\n            ]),\r\n        ];\r\n        this._blendBackMrt = new MultiRenderTarget(\"depthPeelingBackMRT\", size, 1, this._scene, { generateDepthBuffer: false }, [\"depthPeelingBackMRT_blendBack\"]);\r\n        if (this._blendOutput) {\r\n            this._blendBackMrt.setInternalTexture(this._blendOutput.texture!, 0);\r\n        }\r\n\r\n        // 0 is a depth texture\r\n        // 1 is a color texture\r\n        const optionsArray = [\r\n            {\r\n                format: Constants.TEXTUREFORMAT_RG,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                type: this._engine.getCaps().textureFloatLinearFiltering ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_HALF_FLOAT,\r\n                label: \"DepthPeelingRenderer-DepthTexture\",\r\n            } as InternalTextureCreationOptions,\r\n            {\r\n                format: Constants.TEXTUREFORMAT_RGBA,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n                label: \"DepthPeelingRenderer-ColorTexture\",\r\n            } as InternalTextureCreationOptions,\r\n        ];\r\n\r\n        for (let i = 0; i < 2; i++) {\r\n            const depthTexture = this._engine._createInternalTexture(size, optionsArray[0], false);\r\n            const frontColorTexture = this._engine._createInternalTexture(size, optionsArray[1], false);\r\n            const backColorTexture = this._engine._createInternalTexture(size, optionsArray[1], false);\r\n\r\n            this._depthMrts[i].setInternalTexture(depthTexture, 0);\r\n            this._depthMrts[i].setInternalTexture(frontColorTexture, 1);\r\n            this._depthMrts[i].setInternalTexture(backColorTexture, 2);\r\n            this._colorMrts[i].setInternalTexture(frontColorTexture, 0);\r\n            this._colorMrts[i].setInternalTexture(backColorTexture, 1);\r\n\r\n            this._thinTextures.push(new ThinTexture(depthTexture), new ThinTexture(frontColorTexture), new ThinTexture(backColorTexture));\r\n        }\r\n\r\n        if (this._blendOutput) {\r\n            this._blendOutput.shareDepth(this._depthMrts[0].renderTarget!);\r\n        }\r\n    }\r\n\r\n    protected _disposeTextures() {\r\n        for (let i = 0; i < this._thinTextures.length; i++) {\r\n            this._thinTextures[i].dispose();\r\n        }\r\n\r\n        for (let i = 0; i < this._depthMrts.length; i++) {\r\n            this._depthMrts[i].dispose(true);\r\n            this._colorMrts[i].dispose(true);\r\n            this._blendBackMrt.dispose(true);\r\n        }\r\n\r\n        this._thinTextures = [];\r\n        this._colorMrts = [];\r\n        this._depthMrts = [];\r\n    }\r\n\r\n    protected _createEffects(finalEffectFragmentShaderName: string, finalEffectSamplerNames: string[]) {\r\n        this._blendBackEffectWrapper = new EffectWrapper({\r\n            fragmentShader: \"oitBackBlend\",\r\n            useShaderStore: true,\r\n            engine: this._engine,\r\n            samplerNames: [\"uBackColor\"],\r\n            uniformNames: [],\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await import(\"../ShadersWGSL/oitBackBlend.fragment\");\r\n                } else {\r\n                    await import(\"../Shaders/oitBackBlend.fragment\");\r\n                }\r\n            },\r\n        });\r\n        this._blendBackEffectWrapperPingPong = new EffectWrapper({\r\n            fragmentShader: \"oitBackBlend\",\r\n            useShaderStore: true,\r\n            engine: this._engine,\r\n            samplerNames: [\"uBackColor\"],\r\n            uniformNames: [],\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await import(\"../ShadersWGSL/oitBackBlend.fragment\");\r\n                } else {\r\n                    await import(\"../Shaders/oitBackBlend.fragment\");\r\n                }\r\n            },\r\n        });\r\n\r\n        this._finalEffectWrapper = new EffectWrapper({\r\n            fragmentShader: finalEffectFragmentShaderName,\r\n            useShaderStore: true,\r\n            engine: this._engine,\r\n            samplerNames: finalEffectSamplerNames,\r\n            uniformNames: [],\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await import(\"../ShadersWGSL/oitFinalSimpleBlend.fragment\");\r\n                } else {\r\n                    await import(\"../Shaders/oitFinalSimpleBlend.fragment\");\r\n                }\r\n            },\r\n        });\r\n\r\n        this._effectRenderer = new EffectRenderer(this._engine);\r\n    }\r\n\r\n    /**\r\n     * Links to the prepass renderer\r\n     * @param _prePassRenderer The scene PrePassRenderer\r\n     */\r\n    public setPrePassRenderer(_prePassRenderer: PrePassRenderer) {}\r\n\r\n    /**\r\n     * Binds depth peeling textures on an effect\r\n     * @param effect The effect to bind textures on\r\n     */\r\n    public bind(effect: Effect) {\r\n        effect.setTexture(\"oitDepthSampler\", this._thinTextures[this._currentPingPongState * 3]);\r\n        effect.setTexture(\"oitFrontColorSampler\", this._thinTextures[this._currentPingPongState * 3 + 1]);\r\n    }\r\n\r\n    private _renderSubMeshes(transparentSubMeshes: SmartArray<SubMesh>) {\r\n        let mapMaterialContext: { [uniqueId: number]: IMaterialContext | undefined };\r\n        if (this._useRenderPasses) {\r\n            mapMaterialContext = {};\r\n        }\r\n        for (let j = 0; j < transparentSubMeshes.length; j++) {\r\n            const material = transparentSubMeshes.data[j].getMaterial();\r\n            let previousShaderHotSwapping = true;\r\n            let previousBFC = false;\r\n\r\n            const subMesh = transparentSubMeshes.data[j];\r\n            let drawWrapper: DrawWrapper | undefined;\r\n            let firstDraw = false;\r\n\r\n            if (this._useRenderPasses) {\r\n                drawWrapper = subMesh._getDrawWrapper();\r\n                firstDraw = !drawWrapper;\r\n            }\r\n\r\n            if (material) {\r\n                previousShaderHotSwapping = material.allowShaderHotSwapping;\r\n                previousBFC = material.backFaceCulling;\r\n                material.allowShaderHotSwapping = false;\r\n                material.backFaceCulling = false;\r\n            }\r\n\r\n            subMesh.render(false);\r\n\r\n            if (firstDraw) {\r\n                // first time we draw this submesh: we replace the material context\r\n                drawWrapper = subMesh._getDrawWrapper()!; // we are sure it is now non empty as we just rendered the submesh\r\n                if (drawWrapper.materialContext) {\r\n                    let newMaterialContext = mapMaterialContext![drawWrapper.materialContext.uniqueId];\r\n                    if (!newMaterialContext) {\r\n                        newMaterialContext = mapMaterialContext![drawWrapper.materialContext.uniqueId] = this._engine.createMaterialContext();\r\n                    }\r\n                    subMesh._getDrawWrapper()!.materialContext = newMaterialContext;\r\n                }\r\n            }\r\n\r\n            if (material) {\r\n                material.allowShaderHotSwapping = previousShaderHotSwapping;\r\n                material.backFaceCulling = previousBFC;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _finalCompose(writeId: number) {\r\n        this._engine.bindFramebuffer(this._blendOutput!);\r\n\r\n        this._engine.setAlphaMode(Constants.ALPHA_PREMULTIPLIED);\r\n        this._engine.depthCullingState.depthMask = false;\r\n        this._engine.depthCullingState.depthTest = false;\r\n        this._engine.applyStates();\r\n\r\n        this._engine.enableEffect(this._finalEffectWrapper.drawWrapper);\r\n        this._finalEffectWrapper.effect.setTexture(\"uFrontColor\", this._thinTextures[writeId * 3 + 1]);\r\n        this._effectRenderer.render(this._finalEffectWrapper);\r\n    }\r\n\r\n    /**\r\n     * Checks if the depth peeling renderer is ready to render transparent meshes\r\n     * @returns true if the depth peeling renderer is ready to render the transparent meshes\r\n     */\r\n    public isReady() {\r\n        return this._blendBackEffectWrapper.effect.isReady() && this._blendBackEffectWrapperPingPong.effect.isReady() && this._finalEffectWrapper.effect.isReady();\r\n    }\r\n\r\n    protected _beforeRender() {}\r\n\r\n    protected _afterRender() {}\r\n\r\n    protected _noTransparentMeshes() {}\r\n\r\n    /**\r\n     * Renders transparent submeshes with depth peeling\r\n     * @param transparentSubMeshes List of transparent meshes to render\r\n     * @returns The array of submeshes that could not be handled by this renderer\r\n     */\r\n    public render(transparentSubMeshes: SmartArray<SubMesh>): SmartArray<SubMesh> {\r\n        this._candidateSubMeshes.length = 0;\r\n        this._excludedSubMeshes.length = 0;\r\n        if (!this.isReady()) {\r\n            return this._excludedSubMeshes;\r\n        }\r\n\r\n        if (this._scene.activeCamera) {\r\n            this._engine.setViewport(this._scene.activeCamera.viewport);\r\n        }\r\n\r\n        for (let i = 0; i < transparentSubMeshes.length; i++) {\r\n            const subMesh = transparentSubMeshes.data[i];\r\n            const material = subMesh.getMaterial();\r\n            const fillMode = material && subMesh.getRenderingMesh()._getRenderingFillMode(material.fillMode);\r\n\r\n            if (\r\n                material &&\r\n                (fillMode === Material.TriangleFanDrawMode || fillMode === Material.TriangleFillMode || fillMode === Material.TriangleStripDrawMode) &&\r\n                this._excludedMeshes.indexOf(subMesh.getMesh().uniqueId) === -1\r\n            ) {\r\n                this._candidateSubMeshes.push(subMesh);\r\n            } else {\r\n                this._excludedSubMeshes.push(subMesh);\r\n            }\r\n        }\r\n\r\n        if (!this._candidateSubMeshes.length) {\r\n            this._noTransparentMeshes();\r\n            return this._excludedSubMeshes;\r\n        }\r\n\r\n        const currentRenderPassId = this._engine.currentRenderPassId;\r\n\r\n        this._beforeRender();\r\n\r\n        if (this._useRenderPasses) {\r\n            this._engine.currentRenderPassId = this._renderPassIds[0];\r\n        }\r\n\r\n        // Clears\r\n        this._engine.bindFramebuffer(this._depthMrts[0].renderTarget!);\r\n        this._engine.bindAttachments(this._layoutCache[0]);\r\n        this._engine.clear(this._colorCache[0], true, false, false);\r\n        this._engine.unBindFramebuffer(this._depthMrts[0].renderTarget!);\r\n\r\n        this._engine.bindFramebuffer(this._depthMrts[1].renderTarget!);\r\n        this._engine.bindAttachments(this._layoutCache[0]);\r\n        this._engine.clear(this._colorCache[1], true, false, false);\r\n        this._engine.unBindFramebuffer(this._depthMrts[1].renderTarget!);\r\n\r\n        this._engine.bindFramebuffer(this._colorMrts[0].renderTarget!);\r\n        this._engine.bindAttachments(this._layoutCache[1]);\r\n        this._engine.clear(this._colorCache[2], true, false, false);\r\n        this._engine.unBindFramebuffer(this._colorMrts[0].renderTarget!);\r\n\r\n        this._engine.bindFramebuffer(this._colorMrts[1].renderTarget!);\r\n        this._engine.bindAttachments(this._layoutCache[1]);\r\n        this._engine.clear(this._colorCache[2], true, false, false);\r\n        this._engine.unBindFramebuffer(this._colorMrts[1].renderTarget!);\r\n\r\n        // Draw depth for first pass\r\n        this._engine.bindFramebuffer(this._depthMrts[0].renderTarget!);\r\n        this._engine.bindAttachments(this._layoutCache[0]);\r\n\r\n        this._engine.setAlphaMode(Constants.ALPHA_ONEONE_ONEONE); // in WebGPU, when using MIN or MAX equation, the src / dst color factors should not use SRC_ALPHA and the src / dst alpha factors must be 1 else WebGPU will throw a validation error\r\n        this._engine.setAlphaEquation(Constants.ALPHA_EQUATION_MAX);\r\n        this._engine.depthCullingState.depthMask = false;\r\n        this._engine.depthCullingState.depthTest = true;\r\n        this._engine.applyStates();\r\n\r\n        this._currentPingPongState = 1;\r\n        // Render\r\n        this._renderSubMeshes(this._candidateSubMeshes);\r\n        this._engine.unBindFramebuffer(this._depthMrts[0].renderTarget!);\r\n\r\n        this._scene.resetCachedMaterial();\r\n\r\n        // depth peeling ping-pong\r\n        let readId: number;\r\n        let writeId: number = 0;\r\n\r\n        for (let i = 0; i < this._passCount; i++) {\r\n            readId = i % 2;\r\n            writeId = 1 - readId;\r\n            this._currentPingPongState = readId;\r\n\r\n            if (this._useRenderPasses) {\r\n                this._engine.currentRenderPassId = this._renderPassIds[i + 1];\r\n            }\r\n\r\n            if (this._scene.activeCamera) {\r\n                this._engine.setViewport(this._scene.activeCamera.viewport);\r\n            }\r\n\r\n            // Clears\r\n            this._engine.bindFramebuffer(this._depthMrts[writeId].renderTarget!);\r\n            this._engine.bindAttachments(this._layoutCache[0]);\r\n            this._engine.clear(this._colorCache[0], true, false, false);\r\n            this._engine.unBindFramebuffer(this._depthMrts[writeId].renderTarget!);\r\n\r\n            this._engine.bindFramebuffer(this._colorMrts[writeId].renderTarget!);\r\n            this._engine.bindAttachments(this._layoutCache[1]);\r\n            this._engine.clear(this._colorCache[2], true, false, false);\r\n            this._engine.unBindFramebuffer(this._colorMrts[writeId].renderTarget!);\r\n\r\n            this._engine.bindFramebuffer(this._depthMrts[writeId].renderTarget!);\r\n            this._engine.bindAttachments(this._layoutCache[2]);\r\n\r\n            this._engine.setAlphaMode(Constants.ALPHA_ONEONE_ONEONE); // the value does not matter (as MAX operation does not use them) but the src and dst color factors should not use SRC_ALPHA else WebGPU will throw a validation error\r\n            this._engine.setAlphaEquation(Constants.ALPHA_EQUATION_MAX);\r\n            this._engine.depthCullingState.depthTest = false;\r\n            this._engine.applyStates();\r\n\r\n            // Render\r\n            this._renderSubMeshes(this._candidateSubMeshes);\r\n            this._engine.unBindFramebuffer(this._depthMrts[writeId].renderTarget!);\r\n\r\n            this._scene.resetCachedMaterial();\r\n\r\n            // Back color\r\n            this._engine.bindFramebuffer(this._blendBackMrt.renderTarget!);\r\n            this._engine.bindAttachments(this._layoutCache[0]);\r\n            this._engine.setAlphaEquation(Constants.ALPHA_EQUATION_ADD);\r\n            this._engine.setAlphaMode(Constants.ALPHA_LAYER_ACCUMULATE);\r\n            this._engine.applyStates();\r\n\r\n            const blendBackEffectWrapper = writeId === 0 || !this._useRenderPasses ? this._blendBackEffectWrapper : this._blendBackEffectWrapperPingPong;\r\n            this._engine.enableEffect(blendBackEffectWrapper.drawWrapper);\r\n            blendBackEffectWrapper.effect.setTexture(\"uBackColor\", this._thinTextures[writeId * 3 + 2]);\r\n            this._effectRenderer.render(blendBackEffectWrapper);\r\n            this._engine.unBindFramebuffer(this._blendBackMrt.renderTarget!);\r\n        }\r\n\r\n        this._engine.currentRenderPassId = currentRenderPassId;\r\n\r\n        // Final composition on default FB\r\n        this._finalCompose(writeId);\r\n\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n        this._engine.depthCullingState.depthMask = true;\r\n        this._engine.depthCullingState.depthTest = true;\r\n\r\n        this._afterRender();\r\n\r\n        return this._excludedSubMeshes;\r\n    }\r\n\r\n    /**\r\n     * Disposes the depth peeling renderer and associated resources\r\n     */\r\n    public dispose() {\r\n        this._disposeTextures();\r\n        this._blendBackEffectWrapper.dispose();\r\n        this._finalEffectWrapper.dispose();\r\n        this._effectRenderer.dispose();\r\n        this._releaseRenderPassIds();\r\n    }\r\n}\r\n","import {\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type Scene,\r\n    type Camera,\r\n    type FrameGraphObjectList,\r\n    type FrameGraphRenderContext,\r\n    type ObjectRendererOptions,\r\n    type Light,\r\n    type Nullable,\r\n    type Observer,\r\n    type FrameGraphShadowGeneratorTask,\r\n    type FrameGraphRenderPass,\r\n    type AbstractEngine,\r\n    type BoundingBoxRenderer,\r\n    type ShadowLight,\r\n    type SmartArray,\r\n    type SubMesh,\r\n    type RenderingGroup,\r\n} from \"core/index\";\r\nimport { backbufferColorTextureHandle, backbufferDepthStencilTextureHandle } from \"../../frameGraphTypes\";\r\nimport { FrameGraphTaskMultiRenderTarget } from \"../../frameGraphTaskMultiRenderTarget\";\r\nimport { ObjectRenderer } from \"../../../Rendering/objectRenderer\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { ThinDepthPeelingRenderer } from \"../../../Rendering/thinDepthPeelingRenderer.pure\";\r\nimport { FrameGraphRenderTarget } from \"../../frameGraphRenderTarget\";\r\n\r\n/**\r\n * Task used to render objects to a texture.\r\n */\r\nexport class FrameGraphObjectRendererTask extends FrameGraphTaskMultiRenderTarget {\r\n    /**\r\n     * The target texture(s) where the objects will be rendered.\r\n     */\r\n    public targetTexture: FrameGraphTextureHandle | FrameGraphTextureHandle[];\r\n\r\n    /**\r\n     * The depth attachment texture where the objects will be rendered (optional).\r\n     */\r\n    public depthTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The shadow generators used to render the objects (optional).\r\n     */\r\n    public shadowGenerators?: FrameGraphShadowGeneratorTask[] = [];\r\n\r\n    private _camera: Camera;\r\n\r\n    /**\r\n     * Gets or sets the camera used to render the objects.\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(camera: Camera) {\r\n        this._camera = camera;\r\n        this._renderer.activeCamera = this.camera;\r\n    }\r\n\r\n    /**\r\n     * The list of objects to render.\r\n     */\r\n    public objectList: FrameGraphObjectList;\r\n\r\n    /**\r\n     * If depth testing should be enabled (default is true).\r\n     */\r\n    public depthTest = true;\r\n\r\n    /**\r\n     * If depth writing should be enabled (default is true).\r\n     */\r\n    public depthWrite = true;\r\n\r\n    /**\r\n     * If shadows should be disabled (default is false).\r\n     */\r\n    public disableShadows = false;\r\n\r\n    private _disableImageProcessing = false;\r\n    /**\r\n     * If image processing should be disabled (default is false).\r\n     * false means that the default image processing configuration will be applied (the one from the scene)\r\n     */\r\n    public get disableImageProcessing() {\r\n        return this._disableImageProcessing;\r\n    }\r\n\r\n    public set disableImageProcessing(value: boolean) {\r\n        if (value === this._disableImageProcessing) {\r\n            return;\r\n        }\r\n\r\n        this._disableImageProcessing = value;\r\n        this._renderer.disableImageProcessing = value;\r\n    }\r\n\r\n    /**\r\n     * Sets this property to true if this task is the main object renderer of the frame graph.\r\n     * It will help to locate the main object renderer in the frame graph when multiple object renderers are used.\r\n     * This is useful for the inspector to know which object renderer to use for additional rendering features like wireframe rendering or frustum light debugging.\r\n     * It is also used to determine the main camera used by the frame graph: this is the camera used by the main object renderer.\r\n     */\r\n    public isMainObjectRenderer = false;\r\n\r\n    private _renderMeshes = true;\r\n    /**\r\n     * Defines if meshes should be rendered (default is true).\r\n     */\r\n    public get renderMeshes() {\r\n        return this._renderMeshes;\r\n    }\r\n\r\n    public set renderMeshes(value: boolean) {\r\n        if (value === this._renderMeshes) {\r\n            return;\r\n        }\r\n\r\n        this._renderMeshes = value;\r\n        this._renderer.renderMeshes = value;\r\n    }\r\n\r\n    private _renderDepthOnlyMeshes = true;\r\n    /**\r\n     * Defines if depth only meshes should be rendered (default is true). Always subject to the renderMeshes property, though.\r\n     */\r\n    public get renderDepthOnlyMeshes() {\r\n        return this._renderDepthOnlyMeshes;\r\n    }\r\n\r\n    public set renderDepthOnlyMeshes(value: boolean) {\r\n        if (value === this._renderDepthOnlyMeshes) {\r\n            return;\r\n        }\r\n        this._renderDepthOnlyMeshes = value;\r\n        this._renderer.renderDepthOnlyMeshes = value;\r\n    }\r\n\r\n    private _renderOpaqueMeshes = true;\r\n    /**\r\n     * Defines if opaque meshes should be rendered (default is true). Always subject to the renderMeshes property, though.\r\n     */\r\n    public get renderOpaqueMeshes() {\r\n        return this._renderOpaqueMeshes;\r\n    }\r\n\r\n    public set renderOpaqueMeshes(value: boolean) {\r\n        if (value === this._renderOpaqueMeshes) {\r\n            return;\r\n        }\r\n        this._renderOpaqueMeshes = value;\r\n        this._renderer.renderOpaqueMeshes = value;\r\n    }\r\n\r\n    private _renderAlphaTestMeshes = true;\r\n    /**\r\n     * Defines if alpha test meshes should be rendered (default is true). Always subject to the renderMeshes property, though.\r\n     */\r\n    public get renderAlphaTestMeshes() {\r\n        return this._renderAlphaTestMeshes;\r\n    }\r\n\r\n    public set renderAlphaTestMeshes(value: boolean) {\r\n        if (value === this._renderAlphaTestMeshes) {\r\n            return;\r\n        }\r\n        this._renderAlphaTestMeshes = value;\r\n        this._renderer.renderAlphaTestMeshes = value;\r\n    }\r\n\r\n    private _renderTransparentMeshes = true;\r\n    /**\r\n     * Defines if transparent meshes should be rendered (default is true). Always subject to the renderMeshes property, though.\r\n     */\r\n    public get renderTransparentMeshes() {\r\n        return this._renderTransparentMeshes;\r\n    }\r\n\r\n    public set renderTransparentMeshes(value: boolean) {\r\n        if (value === this._renderTransparentMeshes) {\r\n            return;\r\n        }\r\n        this._renderTransparentMeshes = value;\r\n        this._renderer.renderTransparentMeshes = value;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _useOITForTransparentMeshes = false;\r\n    /**\r\n     * Defines if Order Independent Transparency should be used for transparent meshes (default is false).\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get useOITForTransparentMeshes() {\r\n        return this._useOITForTransparentMeshes;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set useOITForTransparentMeshes(value: boolean) {\r\n        if (value === this._useOITForTransparentMeshes) {\r\n            return;\r\n        }\r\n        this._useOITForTransparentMeshes = value;\r\n        this._renderer.customRenderTransparentSubMeshes = this._useOITForTransparentMeshes\r\n            ? (transparentSubMeshes: SmartArray<SubMesh>, renderingGroup?: RenderingGroup) => this._renderTransparentMeshesWithOIT(transparentSubMeshes, renderingGroup!)\r\n            : undefined;\r\n        this._oitRenderer.blendOutput = value && this._rtForOrderIndependentTransparency ? this._rtForOrderIndependentTransparency.renderTargetWrapper! : null;\r\n    }\r\n\r\n    /**\r\n     * Defines the number of passes to use for Order Independent Transparency (default is 5).\r\n     */\r\n    public get oitPassCount() {\r\n        return this._oitRenderer.passCount;\r\n    }\r\n\r\n    public set oitPassCount(value: number) {\r\n        if (value === this._oitRenderer.passCount) {\r\n            return;\r\n        }\r\n        this._oitRenderer.passCount = value;\r\n    }\r\n\r\n    private _renderParticles = true;\r\n    /**\r\n     * Defines if particles should be rendered (default is true).\r\n     */\r\n    public get renderParticles() {\r\n        return this._renderParticles;\r\n    }\r\n\r\n    public set renderParticles(value: boolean) {\r\n        if (value === this._renderParticles) {\r\n            return;\r\n        }\r\n\r\n        this._renderParticles = value;\r\n        this._renderer.renderParticles = value;\r\n    }\r\n\r\n    private _renderSprites = true;\r\n    /**\r\n     * Defines if sprites should be rendered (default is true).\r\n     */\r\n    public get renderSprites() {\r\n        return this._renderSprites;\r\n    }\r\n\r\n    public set renderSprites(value: boolean) {\r\n        if (value === this._renderSprites) {\r\n            return;\r\n        }\r\n\r\n        this._renderSprites = value;\r\n        this._renderer.renderSprites = value;\r\n    }\r\n\r\n    private _forceLayerMaskCheck = true;\r\n    /**\r\n     * Forces checking the layerMask property even if a custom list of meshes is provided (ie. if renderList is not undefined). Default is true.\r\n     */\r\n    public get forceLayerMaskCheck() {\r\n        return this._forceLayerMaskCheck;\r\n    }\r\n\r\n    public set forceLayerMaskCheck(value: boolean) {\r\n        if (value === this._forceLayerMaskCheck) {\r\n            return;\r\n        }\r\n\r\n        this._forceLayerMaskCheck = value;\r\n        this._renderer.forceLayerMaskCheck = value;\r\n    }\r\n\r\n    private _enableBoundingBoxRendering = true;\r\n    /**\r\n     * Enables the rendering of bounding boxes for meshes (still subject to Mesh.showBoundingBox or scene.forceShowBoundingBoxes). Default is true.\r\n     */\r\n    public get enableBoundingBoxRendering() {\r\n        return this._enableBoundingBoxRendering;\r\n    }\r\n\r\n    public set enableBoundingBoxRendering(value: boolean) {\r\n        if (value === this._enableBoundingBoxRendering) {\r\n            return;\r\n        }\r\n\r\n        this._enableBoundingBoxRendering = value;\r\n        this._renderer.enableBoundingBoxRendering = value;\r\n    }\r\n\r\n    private _enableOutlineRendering = true;\r\n    /**\r\n     * Enables the rendering of outlines/overlays for meshes (still subject to Mesh.renderOutline/Mesh.renderOverlay). Default is true.\r\n     */\r\n    public get enableOutlineRendering() {\r\n        return this._enableOutlineRendering;\r\n    }\r\n\r\n    public set enableOutlineRendering(value: boolean) {\r\n        if (value === this._enableOutlineRendering) {\r\n            return;\r\n        }\r\n\r\n        this._enableOutlineRendering = value;\r\n        this._renderer.enableOutlineRendering = value;\r\n    }\r\n\r\n    /**\r\n     * If true, targetTexture will be resolved at the end of the render pass, if this/these texture(s) is/are MSAA (default: true)\r\n     */\r\n    public resolveMSAAColors = true;\r\n\r\n    /**\r\n     * If true, depthTexture will be resolved at the end of the render pass, if this texture is provided and is MSAA (default: false).\r\n     */\r\n    public resolveMSAADepth = false;\r\n\r\n    /**\r\n     * The output texture.\r\n     * This texture will point to the same texture than the targetTexture property.\r\n     * Note, however, that the handle itself will be different!\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output depth attachment texture.\r\n     * This texture will point to the same texture than the depthTexture property if it is set.\r\n     * Note, however, that the handle itself will be different!\r\n     */\r\n    public readonly outputDepthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The object renderer used to render the objects.\r\n     */\r\n    public get objectRenderer() {\r\n        return this._renderer;\r\n    }\r\n\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(value: string) {\r\n        this._name = value;\r\n        if (this._renderer) {\r\n            this._renderer.name = value;\r\n        }\r\n    }\r\n\r\n    protected readonly _engine: AbstractEngine;\r\n    protected readonly _scene: Scene;\r\n    protected readonly _renderer: ObjectRenderer;\r\n    protected readonly _oitRenderer: ThinDepthPeelingRenderer;\r\n    protected _textureWidth: number;\r\n    protected _textureHeight: number;\r\n    protected _onBeforeRenderObservable: Nullable<Observer<number>> = null;\r\n    protected _onAfterRenderObservable: Nullable<Observer<number>> = null;\r\n    protected _externalObjectRenderer = false;\r\n    protected _rtForOrderIndependentTransparency: FrameGraphRenderTarget;\r\n\r\n    /**\r\n     * Constructs a new object renderer task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     * @param scene The scene the frame graph is associated with.\r\n     * @param options The options of the object renderer.\r\n     * @param existingObjectRenderer An existing object renderer to use (optional). If provided, the options parameter will be ignored.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene, options?: ObjectRendererOptions, existingObjectRenderer?: ObjectRenderer) {\r\n        super(name, frameGraph);\r\n\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._externalObjectRenderer = !!existingObjectRenderer;\r\n        this._renderer = existingObjectRenderer ?? new ObjectRenderer(name, scene, options);\r\n        this.name = name;\r\n\r\n        this._renderer.disableImageProcessing = this._disableImageProcessing;\r\n        this._renderer.renderParticles = this._renderParticles;\r\n        this._renderer.renderSprites = this._renderSprites;\r\n        this._renderer.enableBoundingBoxRendering = this._enableBoundingBoxRendering;\r\n        this._renderer.forceLayerMaskCheck = this._forceLayerMaskCheck;\r\n\r\n        if (!this._externalObjectRenderer) {\r\n            this._renderer.onBeforeRenderingManagerRenderObservable.add(() => {\r\n                if (!this._renderer.options.doNotChangeAspectRatio) {\r\n                    scene.updateTransformMatrix(true);\r\n                }\r\n            });\r\n        }\r\n\r\n        this._oitRenderer = new ThinDepthPeelingRenderer(scene);\r\n        this._oitRenderer.useRenderPasses = true;\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.outputDepthTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override isReady() {\r\n        this._renderer.renderList = this.objectList.meshes;\r\n        this._renderer.particleSystemList = this.objectList.particleSystems;\r\n        this._renderer.spriteManagerList = this.objectList.spriteManagers ?? null;\r\n\r\n        return this._renderer.isReadyForRendering(this._textureWidth, this._textureHeight);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphObjectRendererTask\";\r\n    }\r\n\r\n    /**\r\n     * Records the object renderer task into the frame graph.\r\n     * @param skipCreationOfDisabledPasses defines whether disabled passes should be skipped\r\n     * @param additionalExecute defines an optional callback executed by the pass\r\n     * @returns the recorded render pass\r\n     */\r\n    public record(skipCreationOfDisabledPasses = false, additionalExecute?: (context: FrameGraphRenderContext) => void): FrameGraphRenderPass {\r\n        this._checkParameters();\r\n\r\n        const targetTextures = this._getTargetHandles();\r\n\r\n        const depthEnabled = this._checkTextureCompatibility(targetTextures);\r\n\r\n        this._resolveDanglingHandles(targetTextures);\r\n        this._setLightsForShadow();\r\n\r\n        this._rtForOrderIndependentTransparency?.dispose();\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.setRenderTarget(targetTextures);\r\n        pass.setRenderTargetDepth(this.depthTexture);\r\n        pass.setInitializeFunc(() => {\r\n            // OIT composition targets only the caller's color textures, not the geometry attachments of the render pass.\r\n            this._rtForOrderIndependentTransparency = new FrameGraphRenderTarget(this.name + \"_oitRT\", this._frameGraph.textureManager, this.targetTexture, this.depthTexture);\r\n        });\r\n        pass.setExecuteFunc((context) => {\r\n            this._renderer.renderList = this.objectList.meshes;\r\n            this._renderer.particleSystemList = this.objectList.particleSystems;\r\n            this._renderer.spriteManagerList = this.objectList.spriteManagers ?? null;\r\n\r\n            this._updateLayerAndFaceIndices(pass);\r\n\r\n            const renderTargetWrapper = pass.frameGraphRenderTarget!.renderTargetWrapper;\r\n            if (renderTargetWrapper) {\r\n                renderTargetWrapper.resolveMSAAColors = this.resolveMSAAColors;\r\n                renderTargetWrapper.resolveMSAADepth = this.resolveMSAADepth;\r\n            }\r\n\r\n            if (this._useOITForTransparentMeshes && this._oitRenderer.blendOutput !== this._rtForOrderIndependentTransparency.renderTargetWrapper) {\r\n                this._oitRenderer.blendOutput = this._rtForOrderIndependentTransparency.renderTargetWrapper!;\r\n            }\r\n\r\n            // The cast to \"any\" is to avoid an error in ES6 in case you don't import boundingBoxRenderer\r\n            const boundingBoxRenderer = (this as any).getBoundingBoxRenderer?.() as Nullable<BoundingBoxRenderer>;\r\n\r\n            const currentBoundingBoxMeshList = boundingBoxRenderer && boundingBoxRenderer.renderList.length > 0 ? boundingBoxRenderer.renderList.data.slice() : [];\r\n            if (boundingBoxRenderer) {\r\n                currentBoundingBoxMeshList.length = boundingBoxRenderer.renderList.length;\r\n            }\r\n\r\n            const attachments = this._prepareRendering(context, depthEnabled);\r\n\r\n            const currentOITRenderer = this._scene._depthPeelingRenderer;\r\n            this._scene._depthPeelingRenderer = this._oitRenderer;\r\n\r\n            const camera = this._renderer.activeCamera;\r\n            if (camera && camera.cameraRigMode !== Constants.RIG_MODE_NONE && !camera._renderingMultiview) {\r\n                for (let index = 0; index < camera._rigCameras.length; index++) {\r\n                    const rigCamera = camera._rigCameras[index];\r\n\r\n                    rigCamera.rigParent = undefined; // for some reasons, ObjectRenderer uses the rigParent viewport if rigParent is defined (we want to use rigCamera.viewport instead)\r\n\r\n                    this._renderer.activeCamera = rigCamera;\r\n\r\n                    context.pushDebugGroup(`Render objects for camera rig ${index} \"${rigCamera.name}\"`);\r\n                    context.bindRenderTarget(pass.frameGraphRenderTarget);\r\n                    attachments && context.bindAttachments(attachments);\r\n                    context.render(this._renderer, this._textureWidth, this._textureHeight, true);\r\n                    context.popDebugGroup();\r\n\r\n                    rigCamera.rigParent = camera;\r\n                }\r\n                this._renderer.activeCamera = camera;\r\n            } else {\r\n                context.pushDebugGroup(`Render objects for camera \"${this._renderer.activeCamera?.name ?? \"undefined\"}\"`);\r\n                context.bindRenderTarget(pass.frameGraphRenderTarget);\r\n                attachments && context.bindAttachments(attachments);\r\n                context.render(this._renderer, this._textureWidth, this._textureHeight, true);\r\n                context.popDebugGroup();\r\n            }\r\n\r\n            additionalExecute?.(context);\r\n\r\n            this._scene._depthPeelingRenderer = currentOITRenderer;\r\n\r\n            if (boundingBoxRenderer) {\r\n                boundingBoxRenderer.renderList.data = currentBoundingBoxMeshList;\r\n                boundingBoxRenderer.renderList.length = currentBoundingBoxMeshList.length;\r\n            }\r\n        });\r\n\r\n        if (!skipCreationOfDisabledPasses) {\r\n            const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n            passDisabled.setRenderTarget(targetTextures);\r\n            passDisabled.setRenderTargetDepth(this.depthTexture);\r\n            passDisabled.setExecuteFunc((_context) => {});\r\n        }\r\n\r\n        return pass;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this._renderer.onBeforeRenderObservable.remove(this._onBeforeRenderObservable);\r\n        this._renderer.onAfterRenderObservable.remove(this._onAfterRenderObservable);\r\n        if (!this._externalObjectRenderer) {\r\n            this._renderer.dispose();\r\n        }\r\n        this._oitRenderer.dispose();\r\n        this._rtForOrderIndependentTransparency?.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    protected _resolveDanglingHandles(targetTextures: FrameGraphTextureHandle[]) {\r\n        if (targetTextures.length > 0) {\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, targetTextures[0]);\r\n        }\r\n\r\n        if (this.depthTexture !== undefined) {\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputDepthTexture, this.depthTexture);\r\n        }\r\n    }\r\n\r\n    protected _checkParameters() {\r\n        if (this.targetTexture === undefined || this.objectList === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphObjectRendererTask ${this.name}: targetTexture, objectList, and camera are required`);\r\n        }\r\n    }\r\n\r\n    protected _checkTextureCompatibility(targetTextures: FrameGraphTextureHandle[]): boolean {\r\n        const className = this.getClassName();\r\n\r\n        let outputTextureDescription = targetTextures.length > 0 ? this._frameGraph.textureManager.getTextureDescription(targetTextures[0]) : null;\r\n        let depthEnabled = false;\r\n\r\n        if (this.depthTexture !== undefined) {\r\n            if (outputTextureDescription && this.depthTexture !== backbufferDepthStencilTextureHandle && targetTextures[0] === backbufferColorTextureHandle) {\r\n                throw new Error(`${className} ${this.name}: the back buffer depth/stencil texture is the only depth texture allowed when the target is the back buffer color`);\r\n            }\r\n\r\n            const depthTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.depthTexture);\r\n            if (!outputTextureDescription) {\r\n                outputTextureDescription = depthTextureDescription;\r\n            }\r\n            if (depthTextureDescription.options.samples !== outputTextureDescription.options.samples) {\r\n                throw new Error(\r\n                    `${className} ${this.name}: the depth texture \"${depthTextureDescription.options.labels?.[0] ?? \"noname\"}\" (${depthTextureDescription.options.samples} samples) and the output texture \"${outputTextureDescription.options.labels?.[0] ?? \"noname\"}\" (${outputTextureDescription.options.samples} samples) must have the same number of samples`\r\n                );\r\n            }\r\n\r\n            if (depthTextureDescription.size.width !== outputTextureDescription.size.width || depthTextureDescription.size.height !== outputTextureDescription.size.height) {\r\n                throw new Error(\r\n                    `${className} ${this.name}: the depth texture (size: ${depthTextureDescription.size.width}x${depthTextureDescription.size.height}) and the target texture (size: ${outputTextureDescription.size.width}x${outputTextureDescription.size.height}) must have the same dimensions.`\r\n                );\r\n            }\r\n\r\n            depthEnabled = true;\r\n        }\r\n\r\n        this._textureWidth = outputTextureDescription?.size.width ?? 1;\r\n        this._textureHeight = outputTextureDescription?.size.height ?? 1;\r\n\r\n        return depthEnabled;\r\n    }\r\n\r\n    protected _getTargetHandles(): FrameGraphTextureHandle[] {\r\n        return Array.isArray(this.targetTexture) ? this.targetTexture : [this.targetTexture];\r\n    }\r\n\r\n    protected _prepareRendering(context: FrameGraphRenderContext, depthEnabled: boolean): Nullable<number[]> {\r\n        context.setDepthStates(this.depthTest && depthEnabled, this.depthWrite && depthEnabled);\r\n        return null;\r\n    }\r\n\r\n    protected _setLightsForShadow() {\r\n        const lightsForShadow: Set<Light> = new Set();\r\n        const shadowEnabled: Map<Light, boolean> = new Map();\r\n\r\n        if (this.shadowGenerators) {\r\n            for (const shadowGeneratorTask of this.shadowGenerators) {\r\n                const shadowGenerator = shadowGeneratorTask.shadowGenerator;\r\n                const light = shadowGenerator.getLight();\r\n                if (light.isEnabled() && light.shadowEnabled) {\r\n                    lightsForShadow.add(light);\r\n                    if (shadowGeneratorTask.getClassName() === \"FrameGraphCascadedShadowGeneratorTask\") {\r\n                        light._shadowGenerators!.set(shadowGeneratorTask.camera, shadowGenerator);\r\n                    } else {\r\n                        light._shadowGenerators!.set(null, shadowGenerator);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._renderer.onBeforeRenderObservable.remove(this._onBeforeRenderObservable);\r\n        this._onBeforeRenderObservable = this._renderer.onBeforeRenderObservable.add(() => {\r\n            for (let i = 0; i < this._scene.lights.length; i++) {\r\n                const light = this._scene.lights[i];\r\n                if (!(light as ShadowLight).setShadowProjectionMatrix) {\r\n                    continue; // Ignore lights that cannot cast shadows\r\n                }\r\n                shadowEnabled.set(light, light.shadowEnabled);\r\n                light.shadowEnabled = !this.disableShadows && lightsForShadow.has(light);\r\n            }\r\n        });\r\n\r\n        this._renderer.onAfterRenderObservable.remove(this._onAfterRenderObservable);\r\n        this._onAfterRenderObservable = this._renderer.onAfterRenderObservable.add(() => {\r\n            for (let i = 0; i < this._scene.lights.length; i++) {\r\n                const light = this._scene.lights[i];\r\n                if (!(light as ShadowLight).setShadowProjectionMatrix) {\r\n                    continue; // Ignore lights that cannot cast shadows\r\n                }\r\n                light.shadowEnabled = shadowEnabled.get(light)!;\r\n            }\r\n        });\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected _renderTransparentMeshesWithOIT(transparentSubMeshes: SmartArray<SubMesh>, renderingGroup: RenderingGroup): void {\r\n        const saveOIT = this._scene._useOrderIndependentTransparency;\r\n\r\n        this._scene._useOrderIndependentTransparency = true;\r\n\r\n        const excludedMeshes = this._oitRenderer.render(transparentSubMeshes);\r\n        if (excludedMeshes.length) {\r\n            // Render leftover meshes that could not be processed by depth peeling\r\n            renderingGroup._renderTransparent(excludedMeshes);\r\n        }\r\n\r\n        this._scene._useOrderIndependentTransparency = saveOIT;\r\n    }\r\n}\r\n","import {\r\n    type Scene,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type FrameGraphObjectList,\r\n    type Camera,\r\n    type NodeRenderGraphResourceContainerBlock,\r\n    type FrameGraphShadowGeneratorTask,\r\n} from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointDirection } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeRenderGraphConnectionPoint } from \"../../nodeRenderGraphBlockConnectionPoint\";\r\nimport { NodeRenderGraphConnectionPointCustomObject } from \"../../nodeRenderGraphConnectionPointCustomObject\";\r\nimport { FrameGraphObjectRendererTask } from \"core/FrameGraph/Tasks/Rendering/objectRendererTask\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class NodeRenderGraphBaseObjectRendererBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphObjectRendererTask;\r\n\r\n    public override _additionalConstructionParameters: [boolean, boolean];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphBaseObjectRendererBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param doNotChangeAspectRatio True (default) to not change the aspect ratio of the scene in the RTT\r\n     * @param enableClusteredLights True (default) to enable clustered lights\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, doNotChangeAspectRatio = true, enableClusteredLights = true) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [doNotChangeAspectRatio, enableClusteredLights];\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"depth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"objects\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n        this._addDependenciesInput();\r\n        this.registerInput(\"shadowGenerators\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n        this.registerOutput(\"outputDepth\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n        this.registerOutput(\r\n            \"objectRenderer\",\r\n            NodeRenderGraphBlockConnectionPointTypes.Object,\r\n            new NodeRenderGraphConnectionPointCustomObject(\r\n                \"objectRenderer\",\r\n                this,\r\n                NodeRenderGraphConnectionPointDirection.Output,\r\n                NodeRenderGraphBaseObjectRendererBlock,\r\n                \"NodeRenderGraphBaseObjectRendererBlock\"\r\n            )\r\n        );\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBufferDepthStencil | NodeRenderGraphBlockConnectionPointTypes.ResourceContainer\r\n        );\r\n        this.depth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment | NodeRenderGraphBlockConnectionPointTypes.TextureBackBufferDepthStencilAttachment\r\n        );\r\n        this.shadowGenerators.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator | NodeRenderGraphBlockConnectionPointTypes.ResourceContainer\r\n        );\r\n\r\n        this.output._typeConnectionSource = this.target;\r\n        this.outputDepth._typeConnectionSource = this.depth;\r\n\r\n        this._createFrameGraphObject();\r\n    }\r\n\r\n    protected _createFrameGraphObject(): void {\r\n        this._frameGraphTask?.dispose();\r\n        this._frameGraphTask = new FrameGraphObjectRendererTask(this.name, this._frameGraph, this._scene, {\r\n            doNotChangeAspectRatio: this._additionalConstructionParameters![0] as boolean,\r\n            enableClusteredLights: this._additionalConstructionParameters![1] as boolean,\r\n        });\r\n    }\r\n\r\n    protected _saveState(state: { [key: string]: any }) {\r\n        state.disabled = this._frameGraphTask.disabled;\r\n        state.isMainObjectRenderer = this.isMainObjectRenderer;\r\n        state.depthTest = this.depthTest;\r\n        state.depthWrite = this.depthWrite;\r\n        state.disableShadows = this.disableShadows;\r\n        state.renderInLinearSpace = this.renderInLinearSpace;\r\n        state.renderMeshes = this.renderMeshes;\r\n        state.renderDepthOnlyMeshes = this.renderDepthOnlyMeshes;\r\n        state.renderOpaqueMeshes = this.renderOpaqueMeshes;\r\n        state.renderAlphaTestMeshes = this.renderAlphaTestMeshes;\r\n        state.renderTransparentMeshes = this.renderTransparentMeshes;\r\n        state.useOITForTransparentMeshes = this.useOITForTransparentMeshes;\r\n        state.renderParticles = this.renderParticles;\r\n        state.renderSprites = this.renderSprites;\r\n        state.forceLayerMaskCheck = this.forceLayerMaskCheck;\r\n        state.enableBoundingBoxRendering = this.enableBoundingBoxRendering;\r\n        state.enableOutlineRendering = this.enableOutlineRendering;\r\n    }\r\n\r\n    protected _restoreState(state: { [key: string]: any }) {\r\n        this._frameGraphTask.disabled = state.disabled;\r\n        this.isMainObjectRenderer = state.isMainObjectRenderer;\r\n        this.depthTest = state.depthTest;\r\n        this.depthWrite = state.depthWrite;\r\n        this.disableShadows = state.disableShadows;\r\n        this.renderInLinearSpace = state.renderInLinearSpace;\r\n        this.renderMeshes = state.renderMeshes;\r\n        this.renderDepthOnlyMeshes = state.renderDepthOnlyMeshes;\r\n        this.renderOpaqueMeshes = state.renderOpaqueMeshes;\r\n        this.renderAlphaTestMeshes = state.renderAlphaTestMeshes;\r\n        this.renderTransparentMeshes = state.renderTransparentMeshes;\r\n        this.useOITForTransparentMeshes = state.useOITForTransparentMeshes;\r\n        this.renderParticles = state.renderParticles;\r\n        this.renderSprites = state.renderSprites;\r\n        this.forceLayerMaskCheck = state.forceLayerMaskCheck;\r\n        this.enableBoundingBoxRendering = state.enableBoundingBoxRendering;\r\n        this.enableOutlineRendering = state.enableOutlineRendering;\r\n    }\r\n\r\n    protected _createFrameGraphObjectWithState(doNotChangeAspectRatio: boolean, enableClusteredLights: boolean): void {\r\n        const state: { [key: string]: any } = {};\r\n\r\n        this._saveState(state);\r\n\r\n        this._additionalConstructionParameters = [doNotChangeAspectRatio, enableClusteredLights];\r\n\r\n        this._createFrameGraphObject();\r\n\r\n        this._restoreState(state);\r\n    }\r\n\r\n    /** Indicates that this object renderer is the main object renderer of the frame graph. */\r\n    @editableInPropertyPage(\"Is main object renderer\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get isMainObjectRenderer() {\r\n        return this._frameGraphTask.isMainObjectRenderer;\r\n    }\r\n\r\n    public set isMainObjectRenderer(value: boolean) {\r\n        this._frameGraphTask.isMainObjectRenderer = value;\r\n    }\r\n\r\n    /** Indicates if depth testing must be enabled or disabled */\r\n    @editableInPropertyPage(\"Depth test\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get depthTest() {\r\n        return this._frameGraphTask.depthTest;\r\n    }\r\n\r\n    public set depthTest(value: boolean) {\r\n        this._frameGraphTask.depthTest = value;\r\n    }\r\n\r\n    /** Indicates if depth writing must be enabled or disabled */\r\n    @editableInPropertyPage(\"Depth write\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get depthWrite() {\r\n        return this._frameGraphTask.depthWrite;\r\n    }\r\n\r\n    public set depthWrite(value: boolean) {\r\n        this._frameGraphTask.depthWrite = value;\r\n    }\r\n\r\n    /** Indicates if meshes should be rendered */\r\n    @editableInPropertyPage(\"Render meshes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderMeshes() {\r\n        return this._frameGraphTask.renderMeshes;\r\n    }\r\n\r\n    public set renderMeshes(value: boolean) {\r\n        this._frameGraphTask.renderMeshes = value;\r\n    }\r\n\r\n    /** Indicates if depth-only meshes should be rendered */\r\n    @editableInPropertyPage(\"    Render depth-only meshes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderDepthOnlyMeshes() {\r\n        return this._frameGraphTask.renderDepthOnlyMeshes;\r\n    }\r\n\r\n    public set renderDepthOnlyMeshes(value: boolean) {\r\n        this._frameGraphTask.renderDepthOnlyMeshes = value;\r\n    }\r\n\r\n    /** Indicates if opaque meshes should be rendered */\r\n    @editableInPropertyPage(\"    Render opaque meshes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderOpaqueMeshes() {\r\n        return this._frameGraphTask.renderOpaqueMeshes;\r\n    }\r\n\r\n    public set renderOpaqueMeshes(value: boolean) {\r\n        this._frameGraphTask.renderOpaqueMeshes = value;\r\n    }\r\n\r\n    /** Indicates if alpha tested meshes should be rendered */\r\n    @editableInPropertyPage(\"    Render alpha test meshes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderAlphaTestMeshes() {\r\n        return this._frameGraphTask.renderAlphaTestMeshes;\r\n    }\r\n\r\n    public set renderAlphaTestMeshes(value: boolean) {\r\n        this._frameGraphTask.renderAlphaTestMeshes = value;\r\n    }\r\n\r\n    /** Indicates if transparent meshes should be rendered */\r\n    @editableInPropertyPage(\"    Render transparent meshes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderTransparentMeshes() {\r\n        return this._frameGraphTask.renderTransparentMeshes;\r\n    }\r\n\r\n    public set renderTransparentMeshes(value: boolean) {\r\n        this._frameGraphTask.renderTransparentMeshes = value;\r\n    }\r\n\r\n    /** Indicates if use of Order Independent Transparency (OIT) for transparent meshes should be enabled */\r\n    @editableInPropertyPage(\"        Use OIT for transparent meshes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get useOITForTransparentMeshes() {\r\n        return this._frameGraphTask.useOITForTransparentMeshes;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set useOITForTransparentMeshes(value: boolean) {\r\n        this._frameGraphTask.useOITForTransparentMeshes = value;\r\n    }\r\n\r\n    /** Defines the number of passes to use for Order Independent Transparency */\r\n    @editableInPropertyPage(\"            Pass count\", PropertyTypeForEdition.Int, \"RENDERING\", { min: 1, max: 20 })\r\n    public get oitPassCount(): number {\r\n        return this._frameGraphTask.oitPassCount;\r\n    }\r\n\r\n    public set oitPassCount(value: number) {\r\n        this._frameGraphTask.oitPassCount = value;\r\n    }\r\n\r\n    /** Indicates if particles should be rendered */\r\n    @editableInPropertyPage(\"Render particles\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderParticles() {\r\n        return this._frameGraphTask.renderParticles;\r\n    }\r\n\r\n    public set renderParticles(value: boolean) {\r\n        this._frameGraphTask.renderParticles = value;\r\n    }\r\n\r\n    /** Indicates if sprites should be rendered */\r\n    @editableInPropertyPage(\"Render sprites\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get renderSprites() {\r\n        return this._frameGraphTask.renderSprites;\r\n    }\r\n\r\n    public set renderSprites(value: boolean) {\r\n        this._frameGraphTask.renderSprites = value;\r\n    }\r\n\r\n    /** Indicates if layer mask check must be forced */\r\n    @editableInPropertyPage(\"Force layer mask check\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get forceLayerMaskCheck() {\r\n        return this._frameGraphTask.forceLayerMaskCheck;\r\n    }\r\n\r\n    public set forceLayerMaskCheck(value: boolean) {\r\n        this._frameGraphTask.forceLayerMaskCheck = value;\r\n    }\r\n\r\n    /** Indicates if bounding boxes should be rendered */\r\n    @editableInPropertyPage(\"Render bounding boxes\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get enableBoundingBoxRendering() {\r\n        return this._frameGraphTask.enableBoundingBoxRendering;\r\n    }\r\n\r\n    public set enableBoundingBoxRendering(value: boolean) {\r\n        this._frameGraphTask.enableBoundingBoxRendering = value;\r\n    }\r\n\r\n    /** Indicates if outlines/overlays should be rendered */\r\n    @editableInPropertyPage(\"Render outlines/overlays\", PropertyTypeForEdition.Boolean, \"RENDERING\")\r\n    public get enableOutlineRendering() {\r\n        return this._frameGraphTask.enableOutlineRendering;\r\n    }\r\n\r\n    public set enableOutlineRendering(value: boolean) {\r\n        this._frameGraphTask.enableOutlineRendering = value;\r\n    }\r\n\r\n    /** Indicates if shadows must be enabled or disabled */\r\n    @editableInPropertyPage(\"Disable shadows\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get disableShadows() {\r\n        return this._frameGraphTask.disableShadows;\r\n    }\r\n\r\n    public set disableShadows(value: boolean) {\r\n        this._frameGraphTask.disableShadows = value;\r\n    }\r\n\r\n    /** If image processing should be disabled */\r\n    @editableInPropertyPage(\"Disable image processing\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get renderInLinearSpace() {\r\n        return this._frameGraphTask.disableImageProcessing;\r\n    }\r\n\r\n    public set renderInLinearSpace(value: boolean) {\r\n        this._frameGraphTask.disableImageProcessing = value;\r\n    }\r\n\r\n    /** True (default) to not change the aspect ratio of the scene in the RTT */\r\n    @editableInPropertyPage(\"Do not change aspect ratio\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get doNotChangeAspectRatio() {\r\n        return this._frameGraphTask.objectRenderer.options.doNotChangeAspectRatio;\r\n    }\r\n\r\n    public set doNotChangeAspectRatio(value: boolean) {\r\n        this._createFrameGraphObjectWithState(value, this.enableClusteredLights);\r\n    }\r\n\r\n    /** True (default) to enable clustered lights */\r\n    @editableInPropertyPage(\"Enable clustered lights\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get enableClusteredLights() {\r\n        return this._frameGraphTask.objectRenderer.options.enableClusteredLights;\r\n    }\r\n\r\n    public set enableClusteredLights(value: boolean) {\r\n        this._createFrameGraphObjectWithState(this.doNotChangeAspectRatio, value);\r\n    }\r\n\r\n    /** If true, MSAA color textures will be resolved at the end of the render pass (default: true) */\r\n    @editableInPropertyPage(\"Resolve MSAA colors\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get resolveMSAAColors() {\r\n        return this._frameGraphTask.resolveMSAAColors;\r\n    }\r\n\r\n    public set resolveMSAAColors(value: boolean) {\r\n        this._frameGraphTask.resolveMSAAColors = value;\r\n    }\r\n\r\n    /** If true, MSAA depth texture will be resolved at the end of the render pass (default: false) */\r\n    @editableInPropertyPage(\"Resolve MSAA depth\", PropertyTypeForEdition.Boolean, \"GENERAL\")\r\n    public get resolveMSAADepth() {\r\n        return this._frameGraphTask.resolveMSAADepth;\r\n    }\r\n\r\n    public set resolveMSAADepth(value: boolean) {\r\n        this._frameGraphTask.resolveMSAADepth = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBaseObjectRendererBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target texture input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth texture input component\r\n     */\r\n    public get depth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the objects input component\r\n     */\r\n    public get objects(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the dependencies input component\r\n     */\r\n    public get dependencies(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadowGenerators input component\r\n     */\r\n    public get shadowGenerators(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output depth component\r\n     */\r\n    public get outputDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the objectRenderer component\r\n     */\r\n    public get objectRenderer(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture; // the value of the output connection point is the \"output\" texture of the task\r\n        this.outputDepth.value = this._frameGraphTask.outputDepthTexture; // the value of the outputDepth connection point is the \"outputDepth\" texture of the task\r\n        this.objectRenderer.value = this._frameGraphTask; // the value of the objectRenderer connection point is the task itself\r\n\r\n        this._frameGraphTask.targetTexture = this._getConnectedTextures(this.target.connectedPoint)!; // Geometry renderer allows undefined for targetTexture\r\n        this._frameGraphTask.depthTexture = this.depth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n        this._frameGraphTask.objectList = this.objects.connectedPoint?.value as FrameGraphObjectList;\r\n\r\n        this._frameGraphTask.shadowGenerators = [];\r\n\r\n        const shadowGeneratorsConnectedPoint = this.shadowGenerators.connectedPoint;\r\n        if (shadowGeneratorsConnectedPoint) {\r\n            if (shadowGeneratorsConnectedPoint.type === NodeRenderGraphBlockConnectionPointTypes.ResourceContainer) {\r\n                const container = shadowGeneratorsConnectedPoint.ownerBlock as NodeRenderGraphResourceContainerBlock;\r\n                for (const input of container.inputs) {\r\n                    if (input.connectedPoint && input.connectedPoint.value !== undefined && NodeRenderGraphConnectionPoint.IsShadowGenerator(input.connectedPoint.value)) {\r\n                        this._frameGraphTask.shadowGenerators.push(input.connectedPoint.value as FrameGraphShadowGeneratorTask);\r\n                    }\r\n                }\r\n            } else if (NodeRenderGraphConnectionPoint.IsShadowGenerator(shadowGeneratorsConnectedPoint.value)) {\r\n                this._frameGraphTask.shadowGenerators[0] = shadowGeneratorsConnectedPoint.value as FrameGraphShadowGeneratorTask;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.isMainObjectRenderer = ${this.isMainObjectRenderer};`);\r\n        codes.push(`${this._codeVariableName}.depthTest = ${this.depthTest};`);\r\n        codes.push(`${this._codeVariableName}.depthWrite = ${this.depthWrite};`);\r\n        codes.push(`${this._codeVariableName}.renderMeshes = ${this.renderMeshes};`);\r\n        codes.push(`${this._codeVariableName}.renderDepthOnlyMeshes = ${this.renderDepthOnlyMeshes};`);\r\n        codes.push(`${this._codeVariableName}.renderOpaqueMeshes = ${this.renderOpaqueMeshes};`);\r\n        codes.push(`${this._codeVariableName}.renderAlphaTestMeshes = ${this.renderAlphaTestMeshes};`);\r\n        codes.push(`${this._codeVariableName}.renderTransparentMeshes = ${this.renderTransparentMeshes};`);\r\n        codes.push(`${this._codeVariableName}.useOITForTransparentMeshes = ${this.useOITForTransparentMeshes};`);\r\n        codes.push(`${this._codeVariableName}.oitPassCount = ${this.oitPassCount};`);\r\n        codes.push(`${this._codeVariableName}.renderParticles = ${this.renderParticles};`);\r\n        codes.push(`${this._codeVariableName}.renderSprites = ${this.renderSprites};`);\r\n        codes.push(`${this._codeVariableName}.forceLayerMaskCheck = ${this.forceLayerMaskCheck};`);\r\n        codes.push(`${this._codeVariableName}.enableBoundingBoxRendering = ${this.enableBoundingBoxRendering};`);\r\n        codes.push(`${this._codeVariableName}.enableOutlineRendering = ${this.enableOutlineRendering};`);\r\n        codes.push(`${this._codeVariableName}.disableShadows = ${this.disableShadows};`);\r\n        codes.push(`${this._codeVariableName}.renderInLinearSpace = ${this.renderInLinearSpace};`);\r\n        codes.push(`${this._codeVariableName}.resolveMSAAColors = ${this.resolveMSAAColors};`);\r\n        codes.push(`${this._codeVariableName}.resolveMSAADepth = ${this.resolveMSAADepth};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.isMainObjectRenderer = this.isMainObjectRenderer;\r\n        serializationObject.depthTest = this.depthTest;\r\n        serializationObject.depthWrite = this.depthWrite;\r\n        serializationObject.renderMeshes = this.renderMeshes;\r\n        serializationObject.renderDepthOnlyMeshes = this.renderDepthOnlyMeshes;\r\n        serializationObject.renderOpaqueMeshes = this.renderOpaqueMeshes;\r\n        serializationObject.renderAlphaTestMeshes = this.renderAlphaTestMeshes;\r\n        serializationObject.renderTransparentMeshes = this.renderTransparentMeshes;\r\n        serializationObject.useOITForTransparentMeshes = this.useOITForTransparentMeshes;\r\n        serializationObject.oitPassCount = this.oitPassCount;\r\n        serializationObject.renderParticles = this.renderParticles;\r\n        serializationObject.renderSprites = this.renderSprites;\r\n        serializationObject.forceLayerMaskCheck = this.forceLayerMaskCheck;\r\n        serializationObject.enableBoundingBoxRendering = this.enableBoundingBoxRendering;\r\n        serializationObject.enableOutlineRendering = this.enableOutlineRendering;\r\n        serializationObject.disableShadows = this.disableShadows;\r\n        serializationObject.renderInLinearSpace = this.renderInLinearSpace;\r\n        serializationObject.resolveMSAAColors = this.resolveMSAAColors;\r\n        serializationObject.resolveMSAADepth = this.resolveMSAADepth;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.isMainObjectRenderer = !!serializationObject.isMainObjectRenderer;\r\n        this.depthTest = serializationObject.depthTest;\r\n        this.depthWrite = serializationObject.depthWrite;\r\n        this.renderMeshes = serializationObject.renderMeshes ?? true;\r\n        this.renderDepthOnlyMeshes = serializationObject.renderDepthOnlyMeshes ?? true;\r\n        this.renderOpaqueMeshes = serializationObject.renderOpaqueMeshes ?? true;\r\n        this.renderAlphaTestMeshes = serializationObject.renderAlphaTestMeshes ?? true;\r\n        this.renderTransparentMeshes = serializationObject.renderTransparentMeshes ?? true;\r\n        this.useOITForTransparentMeshes = serializationObject.useOITForTransparentMeshes ?? false;\r\n        this.oitPassCount = serializationObject.oitPassCount ?? 5;\r\n        this.renderParticles = serializationObject.renderParticles ?? this.renderParticles;\r\n        this.renderSprites = serializationObject.renderSprites ?? this.renderSprites;\r\n        this.forceLayerMaskCheck = serializationObject.forceLayerMaskCheck ?? true;\r\n        this.enableBoundingBoxRendering = serializationObject.enableBoundingBoxRendering ?? this.enableBoundingBoxRendering;\r\n        this.enableOutlineRendering = serializationObject.enableOutlineRendering ?? this.enableOutlineRendering;\r\n        this.disableShadows = serializationObject.disableShadows;\r\n        this.renderInLinearSpace = !!serializationObject.renderInLinearSpace;\r\n        this.resolveMSAAColors = serializationObject.resolveMSAAColors ?? true;\r\n        this.resolveMSAADepth = serializationObject.resolveMSAADepth ?? false;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"./baseObjectRendererBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that render objects to a render target\r\n */\r\nexport class NodeRenderGraphObjectRendererBlock extends NodeRenderGraphBaseObjectRendererBlock {\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphObjectRendererBlock\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for objectRendererBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterObjectRendererBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphObjectRendererBlock\", NodeRenderGraphObjectRendererBlock);\r\n}\r\n","import { type Nullable, type NodeRenderGraphConnectionPoint, type Observable } from \"core/index\";\r\nimport { Logger } from \"../../Misc/logger\";\r\n\r\n/**\r\n * Class used to store node based render graph build state\r\n */\r\nexport class NodeRenderGraphBuildState {\r\n    /** Gets or sets the build identifier */\r\n    public buildId: number;\r\n\r\n    /** Gets or sets a boolean indicating that verbose mode is on */\r\n    public verbose = false;\r\n\r\n    /**\r\n     * Gets or sets the list of non connected mandatory inputs\r\n     * @internal\r\n     */\r\n    public _notConnectedNonOptionalInputs: NodeRenderGraphConnectionPoint[] = [];\r\n\r\n    /**\r\n     * Emits console errors and exceptions if there is a failing check\r\n     * @param errorObservable defines an Observable to send the error message\r\n     * @returns true if all checks pass\r\n     */\r\n    public emitErrors(errorObservable: Nullable<Observable<string>> = null): boolean {\r\n        let errorMessage = \"\";\r\n        for (const notConnectedInput of this._notConnectedNonOptionalInputs) {\r\n            errorMessage += `input \"${notConnectedInput.name}\" from block \"${\r\n                notConnectedInput.ownerBlock.name\r\n            }\"[${notConnectedInput.ownerBlock.getClassName()}] is not connected and is not optional.\\n`;\r\n        }\r\n        if (errorMessage) {\r\n            if (errorObservable) {\r\n                errorObservable.notifyObservers(errorMessage);\r\n            }\r\n            Logger.Error(\"Build of node render graph failed:\\n\" + errorMessage);\r\n\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n}\r\n","import { type Scene, type Camera, type FrameGraph, type FrameGraphObjectList } from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to cull objects that are not visible.\r\n */\r\nexport class FrameGraphCullObjectsTask extends FrameGraphTask {\r\n    /**\r\n     * The object list to cull.\r\n     */\r\n    public objectList: FrameGraphObjectList;\r\n\r\n    /**\r\n     * The camera to use for culling.\r\n     */\r\n    public camera: Camera;\r\n\r\n    /**\r\n     * The output object list containing the culled objects.\r\n     */\r\n    public readonly outputObjectList: FrameGraphObjectList;\r\n\r\n    private readonly _scene: Scene;\r\n\r\n    /**\r\n     * Creates a new cull objects task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     * @param scene The scene to cull objects from.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph);\r\n        this._scene = scene;\r\n        this.outputObjectList = {\r\n            meshes: null,\r\n            particleSystems: null,\r\n            spriteManagers: null,\r\n        };\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphCullObjectsTask\";\r\n    }\r\n\r\n    public record() {\r\n        if (this.objectList === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphCullObjectsTask ${this.name}: objectList and camera are required`);\r\n        }\r\n\r\n        // Initial output values\r\n        this.outputObjectList.meshes = this.objectList.meshes;\r\n        this.outputObjectList.particleSystems = this.objectList.particleSystems;\r\n        this.outputObjectList.spriteManagers = this.objectList.spriteManagers;\r\n\r\n        const pass = this._frameGraph.addObjectListPass(this.name);\r\n\r\n        pass.setObjectList(this.outputObjectList);\r\n        pass.setExecuteFunc((_context) => {\r\n            // No culling on particle systems or sprite managers\r\n            this.outputObjectList.particleSystems = this.objectList.particleSystems;\r\n            this.outputObjectList.spriteManagers = this.objectList.spriteManagers;\r\n\r\n            if (this._scene._activeMeshesFrozen) {\r\n                // If active meshes are frozen, we don't need culling: we keep the last list created before freezing\r\n                return;\r\n            }\r\n\r\n            this.outputObjectList.meshes = [];\r\n\r\n            this.camera._updateFrustumPlanes();\r\n\r\n            const frustumPlanes = this.camera._frustumPlanes;\r\n\r\n            const meshes = this.objectList.meshes || this._scene.meshes;\r\n            for (let i = 0; i < meshes.length; i++) {\r\n                const mesh = meshes[i];\r\n                if (mesh.isBlocked || !mesh.isReady() || !mesh.isEnabled() || mesh.scaling.hasAZeroComponent) {\r\n                    continue;\r\n                }\r\n\r\n                if (\r\n                    mesh.isVisible &&\r\n                    mesh.visibility > 0 &&\r\n                    (mesh.layerMask & this.camera.layerMask) !== 0 &&\r\n                    (this._scene.skipFrustumClipping || mesh.alwaysSelectAsActiveMesh || mesh.isInFrustum(frustumPlanes))\r\n                ) {\r\n                    this.outputObjectList.meshes.push(mesh);\r\n                }\r\n            }\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addObjectListPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setObjectList(this.outputObjectList);\r\n        passDisabled.setExecuteFunc((_context) => {\r\n            this.outputObjectList.meshes = this.objectList.meshes;\r\n            this.outputObjectList.particleSystems = this.objectList.particleSystems;\r\n            this.outputObjectList.spriteManagers = this.objectList.spriteManagers;\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { FrameGraphCullObjectsTask } from \"../../Tasks/Misc/cullObjectsTask\";\r\nimport { type Camera } from \"../../../Cameras/camera.pure\";\r\nimport { type FrameGraphObjectList } from \"core/FrameGraph/frameGraphObjectList\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that culls a list of objects\r\n */\r\nexport class NodeRenderGraphCullObjectsBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphCullObjectsTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphCullObjectsBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"objects\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n\r\n        this._frameGraphTask = new FrameGraphCullObjectsTask(this.name, frameGraph, scene);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphCullObjectsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the objects input component\r\n     */\r\n    public get objects(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputObjectList;\r\n\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n        this._frameGraphTask.objectList = this.objects.connectedPoint?.value as FrameGraphObjectList;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cullObjectsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCullObjectsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphCullObjectsBlock\", NodeRenderGraphCullObjectsBlock);\r\n}\r\n","import {\r\n    type Observer,\r\n    type Nullable,\r\n    type NodeRenderGraphBlock,\r\n    type NodeRenderGraphTeleportOutBlock,\r\n    type NodeRenderGraphTeleportInBlock,\r\n    type AbstractEngine,\r\n    type INodeRenderGraphCreateOptions,\r\n    type INodeRenderGraphEditorOptions,\r\n    type Scene,\r\n    type WritableObject,\r\n    type IShadowLight,\r\n    type INodeRenderGraphCustomBlockDescription,\r\n    type Immutable,\r\n    type Camera,\r\n} from \"core/index\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { NodeRenderGraphOutputBlock } from \"./Blocks/outputBlock.pure\";\r\nimport { FrameGraph } from \"../frameGraph\";\r\nimport { GetClass } from \"../../Misc/typeStore\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { WebRequest } from \"../../Misc/webRequest\";\r\nimport { NodeRenderGraphInputBlock } from \"./Blocks/inputBlock.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { Engine } from \"../../Engines/engine.pure\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"./Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphClearBlock } from \"./Blocks/Textures/clearBlock.pure\";\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"./Blocks/Rendering/baseObjectRendererBlock\";\r\nimport { NodeRenderGraphObjectRendererBlock } from \"./Blocks/Rendering/objectRendererBlock.pure\";\r\nimport { NodeRenderGraphBuildState } from \"./nodeRenderGraphBuildState\";\r\nimport { NodeRenderGraphCullObjectsBlock } from \"./Blocks/cullObjectsBlock.pure\";\r\n\r\n// declare NODERENDERGRAPHEDITOR namespace for compilation issue\r\ndeclare let NODERENDERGRAPHEDITOR: any;\r\ndeclare let BABYLON: any;\r\n\r\n/**\r\n * Defines a node render graph\r\n */\r\nexport class NodeRenderGraph {\r\n    private static _BuildIdGenerator: number = 0;\r\n\r\n    private _buildId: number = NodeRenderGraph._BuildIdGenerator++;\r\n\r\n    /** Define the Url to load node editor script */\r\n    public static EditorURL = `${Tools._DefaultCdnUrl}/v${Engine.Version}/nodeRenderGraphEditor/babylon.nodeRenderGraphEditor.js`;\r\n\r\n    /** Define the Url to load snippets */\r\n    public static SnippetUrl = Constants.SnippetUrl;\r\n\r\n    /** Description of custom blocks to use in the node render graph editor */\r\n    public static CustomBlockDescriptions: INodeRenderGraphCustomBlockDescription[] = [];\r\n\r\n    private BJSNODERENDERGRAPHEDITOR = this._getGlobalNodeRenderGraphEditor();\r\n\r\n    /** @returns the inspector from bundle or global */\r\n    private _getGlobalNodeRenderGraphEditor(): any {\r\n        // UMD global name detection from bundle metadata.\r\n        // Note: rollup-built UMD bundles do not expose the editor class\r\n        // directly on the namespace - it lives on `.default.NodeRenderGraphEditor` -\r\n        // so we unwrap that case before falling back to the BABYLON global.\r\n        if (typeof NODERENDERGRAPHEDITOR !== \"undefined\") {\r\n            if ((NODERENDERGRAPHEDITOR as any).NodeRenderGraphEditor) {\r\n                return NODERENDERGRAPHEDITOR;\r\n            }\r\n            if ((NODERENDERGRAPHEDITOR as any).default?.NodeRenderGraphEditor) {\r\n                return (NODERENDERGRAPHEDITOR as any).default;\r\n            }\r\n        }\r\n\r\n        // In case of module let's check the global emitted from the editor entry point.\r\n        if (typeof BABYLON !== \"undefined\" && typeof BABYLON.NodeRenderGraphEditor !== \"undefined\") {\r\n            return BABYLON;\r\n        }\r\n\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets data used by visual editor\r\n     * @see https://nrge.babylonjs.com\r\n     */\r\n    public editorData: any = null;\r\n\r\n    /**\r\n     * Gets an array of blocks that needs to be serialized even if they are not yet connected\r\n     */\r\n    public attachedBlocks: NodeRenderGraphBlock[] = [];\r\n\r\n    /**\r\n     * Observable raised before the node render graph is built\r\n     */\r\n    public onBeforeBuildObservable = new Observable<FrameGraph>();\r\n\r\n    /**\r\n     * Observable raised after the node render graph is built\r\n     * Note that this is the same observable as the one in the underlying FrameGraph!\r\n     */\r\n    public get onBuildObservable() {\r\n        return this._frameGraph.onBuildObservable;\r\n    }\r\n\r\n    /**\r\n     * Observable raised when an error is detected\r\n     */\r\n    public onBuildErrorObservable = new Observable<string>();\r\n\r\n    /** Gets or sets the RenderGraphOutputBlock used to gather the final node render graph data */\r\n    public outputBlock: Nullable<NodeRenderGraphOutputBlock> = null;\r\n\r\n    /**\r\n     * Snippet ID if the graph was created from the snippet server\r\n     */\r\n    public snippetId: string;\r\n\r\n    /**\r\n     * The name of the node render graph\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * A free comment about the graph\r\n     */\r\n    @serialize(\"comment\")\r\n    public comment: string;\r\n\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _scene: Scene;\r\n    private readonly _resizeObserver: Nullable<Observer<AbstractEngine>> = null;\r\n    private readonly _frameGraph: FrameGraph;\r\n    private readonly _options: INodeRenderGraphCreateOptions;\r\n\r\n    /**\r\n     * Gets the frame graph used by this node render graph\r\n     */\r\n    public get frameGraph() {\r\n        return this._frameGraph;\r\n    }\r\n\r\n    /**\r\n     * Gets the scene used by this node render graph\r\n     * @returns the scene used by this node render graph\r\n     */\r\n    public getScene() {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets the options used to create this node render graph\r\n     */\r\n    public get options(): Immutable<INodeRenderGraphCreateOptions> {\r\n        return this._options;\r\n    }\r\n\r\n    /**\r\n     * Creates a new node render graph\r\n     * @param name defines the name of the node render graph\r\n     * @param scene defines the scene to use to execute the graph\r\n     * @param options defines the options to use when creating the graph\r\n     */\r\n    public constructor(name: string, scene: Scene, options?: INodeRenderGraphCreateOptions) {\r\n        this.name = name;\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n\r\n        options = {\r\n            debugTextures: false,\r\n            autoConfigure: false,\r\n            verbose: false,\r\n            rebuildGraphOnEngineResize: true,\r\n            autoFillExternalInputs: true,\r\n            ...options,\r\n        };\r\n\r\n        this._options = options;\r\n\r\n        this._frameGraph = new FrameGraph(this._scene, options.debugTextures, this);\r\n        this._frameGraph.name = name;\r\n\r\n        if (options.rebuildGraphOnEngineResize) {\r\n            this._resizeObserver = this._engine.onResizeObservable.add(async () => {\r\n                await this.buildAsync(false, true, false);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name (\"NodeRenderGraph\")\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeRenderGraph\";\r\n    }\r\n\r\n    /**\r\n     * Gets a block by its name\r\n     * @param name defines the name of the block to retrieve\r\n     * @returns the required block or null if not found\r\n     */\r\n    public getBlockByName<T extends NodeRenderGraphBlock>(name: string): Nullable<T> {\r\n        let result: Nullable<T> = null;\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.name === name) {\r\n                if (!result) {\r\n                    result = block as T;\r\n                } else {\r\n                    Tools.Warn(\"More than one block was found with the name `\" + name + \"`\");\r\n                    return result;\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Get a block using a predicate\r\n     * @param predicate defines the predicate used to find the good candidate\r\n     * @returns the required block or null if not found\r\n     */\r\n    public getBlockByPredicate<T extends NodeRenderGraphBlock>(predicate: (block: NodeRenderGraphBlock) => boolean): Nullable<T> {\r\n        for (const block of this.attachedBlocks) {\r\n            if (predicate(block)) {\r\n                return block as T;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Get all blocks that match a predicate\r\n     * @param predicate defines the predicate used to find the good candidate(s)\r\n     * @returns the list of blocks found\r\n     */\r\n    public getBlocksByPredicate<T extends NodeRenderGraphBlock>(predicate: (block: NodeRenderGraphBlock) => boolean): T[] {\r\n        const blocks: T[] = [];\r\n        for (const block of this.attachedBlocks) {\r\n            if (predicate(block)) {\r\n                blocks.push(block as T);\r\n            }\r\n        }\r\n\r\n        return blocks;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of input blocks attached to this material\r\n     * @returns an array of InputBlocks\r\n     */\r\n    public getInputBlocks() {\r\n        const blocks: NodeRenderGraphInputBlock[] = [];\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isInput) {\r\n                blocks.push(block as NodeRenderGraphInputBlock);\r\n            }\r\n        }\r\n\r\n        return blocks;\r\n    }\r\n\r\n    /**\r\n     * Replaces a camera in all camera input blocks of this node render graph.\r\n     * If the current camera is found in any input block, it is replaced by the new camera,\r\n     * optionally updating the scene's pointer camera and rebuilding the graph.\r\n     * @param currentCamera The camera to replace.\r\n     * @param newCamera The new camera to assign to the matching input blocks.\r\n     * @param updateCameraToUseForPointers If true (default), updates `scene.cameraToUseForPointers` to the new camera when a replacement occurs.\r\n     * @param rebuildGraph If true (default), rebuilds the graph asynchronously after the replacement.\r\n     * @returns A promise that resolves to true if at least one input block was updated, false otherwise.\r\n     */\r\n    public async replaceCameraAsync(currentCamera: Nullable<Camera>, newCamera: Camera, updateCameraToUseForPointers = true, rebuildGraph = true) {\r\n        const inputBlocks = this.getInputBlocks();\r\n\r\n        let updated = false;\r\n        for (const block of inputBlocks) {\r\n            if (block.isCamera() && block.value === currentCamera) {\r\n                block.value = newCamera;\r\n                updated = true;\r\n            }\r\n        }\r\n\r\n        if (updated) {\r\n            if (updateCameraToUseForPointers) {\r\n                this._scene.cameraToUseForPointers = newCamera;\r\n            }\r\n\r\n            if (rebuildGraph) {\r\n                const currentAutoFill = this._options.autoFillExternalInputs;\r\n                try {\r\n                    this._options.autoFillExternalInputs = false; // makes sure that the camera input block(s) we just updated don't get overwritten by autoFillExternalInputs\r\n\r\n                    await this.buildAsync();\r\n                } finally {\r\n                    this._options.autoFillExternalInputs = currentAutoFill;\r\n                }\r\n            }\r\n        }\r\n\r\n        return updated;\r\n    }\r\n\r\n    /**\r\n     * Launch the node render graph editor\r\n     * @param config Define the configuration of the editor\r\n     * @returns a promise fulfilled when the node editor is visible\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async edit(config?: INodeRenderGraphEditorOptions): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            this.BJSNODERENDERGRAPHEDITOR = this.BJSNODERENDERGRAPHEDITOR || this._getGlobalNodeRenderGraphEditor();\r\n            if (typeof this.BJSNODERENDERGRAPHEDITOR == \"undefined\") {\r\n                const editorUrl = config && config.editorURL ? config.editorURL : NodeRenderGraph.EditorURL;\r\n\r\n                // Load editor and add it to the DOM\r\n                Tools.LoadBabylonScript(editorUrl, () => {\r\n                    this.BJSNODERENDERGRAPHEDITOR = this.BJSNODERENDERGRAPHEDITOR || this._getGlobalNodeRenderGraphEditor();\r\n                    this._createNodeEditor(config?.nodeRenderGraphEditorConfig);\r\n                    resolve();\r\n                });\r\n            } else {\r\n                // Otherwise creates the editor\r\n                this._createNodeEditor(config?.nodeRenderGraphEditorConfig);\r\n                resolve();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates the node editor window.\r\n     * @param additionalConfig Additional configuration for the FGE\r\n     */\r\n    private _createNodeEditor(additionalConfig?: any) {\r\n        const nodeEditorConfig: any = {\r\n            nodeRenderGraph: this,\r\n            customBlockDescriptions: NodeRenderGraph.CustomBlockDescriptions,\r\n            ...additionalConfig,\r\n        };\r\n        this.BJSNODERENDERGRAPHEDITOR.NodeRenderGraphEditor.Show(nodeEditorConfig);\r\n    }\r\n\r\n    /**\r\n     * Build the final list of blocks that will be executed by the \"execute\" method.\r\n     * It also builds the underlying frame graph unless specified otherwise.\r\n     * @param dontBuildFrameGraph If the underlying frame graph should not be built (default: false)\r\n     * @param waitForReadiness If the method should wait for the frame graph to be ready before resolving (default: true). Note that this parameter has no effect if \"dontBuildFrameGraph\" is true.\r\n     * @param setAsSceneFrameGraph If the built frame graph must be set as the scene's frame graph (default: true)\r\n     */\r\n    public async buildAsync(dontBuildFrameGraph = false, waitForReadiness = true, setAsSceneFrameGraph = true): Promise<void> {\r\n        if (!this.outputBlock) {\r\n            throw new Error(\"You must define the outputBlock property before building the node render graph\");\r\n        }\r\n\r\n        if (setAsSceneFrameGraph) {\r\n            this._scene.frameGraph = this._frameGraph;\r\n        }\r\n\r\n        this._initializeBlock(this.outputBlock);\r\n\r\n        this._frameGraph.clear();\r\n\r\n        const state = new NodeRenderGraphBuildState();\r\n\r\n        state.buildId = this._buildId;\r\n        state.verbose = this._options.verbose!;\r\n\r\n        if (this._options.autoFillExternalInputs) {\r\n            this._autoFillExternalInputs();\r\n        }\r\n\r\n        this.onBeforeBuildObservable.notifyObservers(this._frameGraph);\r\n\r\n        // Make sure that one of the object renderer is flagged as the main object renderer\r\n        const objectRendererBlocks = this.getBlocksByPredicate<NodeRenderGraphBaseObjectRendererBlock>((block) => block instanceof NodeRenderGraphBaseObjectRendererBlock);\r\n        if (objectRendererBlocks.length > 0 && !objectRendererBlocks.find((block) => block.isMainObjectRenderer)) {\r\n            objectRendererBlocks[0].isMainObjectRenderer = true;\r\n        }\r\n\r\n        try {\r\n            this.outputBlock.build(state);\r\n\r\n            if (!dontBuildFrameGraph) {\r\n                await this._frameGraph.buildAsync(waitForReadiness);\r\n            }\r\n        } finally {\r\n            this._buildId = NodeRenderGraph._BuildIdGenerator++;\r\n\r\n            state.emitErrors(this.onBuildErrorObservable);\r\n        }\r\n    }\r\n\r\n    private _autoFillExternalInputs() {\r\n        const allInputs = this.getInputBlocks();\r\n\r\n        const shadowLights: IShadowLight[] = [];\r\n        for (const light of this._scene.lights) {\r\n            if ((light as IShadowLight).setShadowProjectionMatrix !== undefined) {\r\n                shadowLights.push(light as IShadowLight);\r\n            }\r\n        }\r\n\r\n        let cameraIndex = 0;\r\n        let lightIndex = 0;\r\n        for (const input of allInputs) {\r\n            if (!input.isExternal) {\r\n                continue;\r\n            }\r\n            if (!input.isAnAncestorOfType(\"NodeRenderGraphOutputBlock\")) {\r\n                continue;\r\n            }\r\n            if ((input.type & NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer) !== 0) {\r\n                // nothing to do\r\n            } else if (input.isCamera()) {\r\n                const camera = this._scene.cameras[cameraIndex++] || this._scene.cameras[0];\r\n                if (!this._scene.cameraToUseForPointers) {\r\n                    this._scene.cameraToUseForPointers = camera;\r\n                }\r\n\r\n                input.value = camera;\r\n            } else if (input.isObjectList()) {\r\n                input.value = { meshes: this._scene.meshes, particleSystems: this._scene.particleSystems, spriteManagers: this._scene.spriteManagers };\r\n            } else if (input.isShadowLight()) {\r\n                if (lightIndex < shadowLights.length) {\r\n                    input.value = shadowLights[lightIndex++];\r\n                    lightIndex = lightIndex % shadowLights.length;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves when the node render graph is ready to be executed\r\n     * This method must be called after the graph has been built (NodeRenderGraph.build called)!\r\n     * @param timeStep Time step in ms between retries (default is 16)\r\n     * @param maxTimeout Maximum time in ms to wait for the graph to be ready (default is 10000)\r\n     * @returns The promise that resolves when the graph is ready\r\n     */\r\n    public async whenReadyAsync(timeStep = 16, maxTimeout = 10000): Promise<void> {\r\n        this._frameGraph.pausedExecution = true;\r\n        await this._frameGraph.whenReadyAsync(timeStep, maxTimeout);\r\n        this._frameGraph.pausedExecution = false;\r\n    }\r\n\r\n    /**\r\n     * Execute the graph (the graph must have been built before!)\r\n     */\r\n    public execute() {\r\n        this._frameGraph.execute();\r\n    }\r\n\r\n    private _initializeBlock(node: NodeRenderGraphBlock) {\r\n        node.initialize();\r\n        if (this._options.autoConfigure) {\r\n            node.autoConfigure();\r\n        }\r\n\r\n        if (this.attachedBlocks.indexOf(node) === -1) {\r\n            this.attachedBlocks.push(node);\r\n        }\r\n\r\n        for (const input of node.inputs) {\r\n            const connectedPoint = input.connectedPoint;\r\n            if (connectedPoint) {\r\n                const block = connectedPoint.ownerBlock;\r\n                if (block !== node) {\r\n                    this._initializeBlock(block);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current graph\r\n     */\r\n    public clear() {\r\n        this.outputBlock = null;\r\n        this.attachedBlocks.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Remove a block from the current graph\r\n     * @param block defines the block to remove\r\n     */\r\n    public removeBlock(block: NodeRenderGraphBlock) {\r\n        const attachedBlockIndex = this.attachedBlocks.indexOf(block);\r\n        if (attachedBlockIndex > -1) {\r\n            this.attachedBlocks.splice(attachedBlockIndex, 1);\r\n        }\r\n\r\n        if (block === this.outputBlock) {\r\n            this.outputBlock = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current graph and load a new one from a serialization object\r\n     * @param source defines the JSON representation of the graph\r\n     * @param merge defines whether or not the source must be merged or replace the current content\r\n     */\r\n    public parseSerializedObject(source: any, merge = false) {\r\n        if (!merge) {\r\n            this.clear();\r\n        }\r\n\r\n        const map: { [key: number]: NodeRenderGraphBlock } = {};\r\n\r\n        // Create blocks\r\n        for (const parsedBlock of source.blocks) {\r\n            const blockType: typeof NodeRenderGraphBlock = GetClass(parsedBlock.customType);\r\n            if (blockType) {\r\n                const additionalConstructionParameters = parsedBlock.additionalConstructionParameters;\r\n                const block: NodeRenderGraphBlock = additionalConstructionParameters\r\n                    ? new blockType(\"\", this._frameGraph, this._scene, ...additionalConstructionParameters)\r\n                    : new blockType(\"\", this._frameGraph, this._scene);\r\n                block._deserialize(parsedBlock);\r\n                map[parsedBlock.id] = block;\r\n\r\n                this.attachedBlocks.push(block);\r\n            }\r\n        }\r\n\r\n        // Reconnect teleportation\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isTeleportOut) {\r\n                const teleportOut = block as NodeRenderGraphTeleportOutBlock;\r\n                const id = teleportOut._tempEntryPointUniqueId;\r\n                if (id) {\r\n                    const source = map[id] as NodeRenderGraphTeleportInBlock;\r\n                    if (source) {\r\n                        source.attachToEndpoint(teleportOut);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Connections - Starts with input blocks only (except if in \"merge\" mode where we scan all blocks)\r\n        for (let blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {\r\n            const parsedBlock = source.blocks[blockIndex];\r\n            const block = map[parsedBlock.id];\r\n\r\n            if (!block) {\r\n                continue;\r\n            }\r\n\r\n            if (block.inputs.length && parsedBlock.inputs.some((i: any) => i.targetConnectionName) && !merge) {\r\n                continue;\r\n            }\r\n            this._restoreConnections(block, source, map);\r\n        }\r\n\r\n        // Outputs\r\n        if (source.outputNodeId) {\r\n            this.outputBlock = map[source.outputNodeId] as NodeRenderGraphOutputBlock;\r\n        }\r\n\r\n        // UI related info\r\n        if (source.locations || (source.editorData && source.editorData.locations)) {\r\n            const locations: {\r\n                blockId: number;\r\n                x: number;\r\n                y: number;\r\n                isCollapsed: boolean;\r\n            }[] = source.locations || source.editorData.locations;\r\n\r\n            for (const location of locations) {\r\n                if (map[location.blockId]) {\r\n                    location.blockId = map[location.blockId].uniqueId;\r\n                }\r\n            }\r\n\r\n            if (merge && this.editorData && this.editorData.locations) {\r\n                locations.concat(this.editorData.locations);\r\n            }\r\n\r\n            if (source.locations) {\r\n                this.editorData = {\r\n                    locations: locations,\r\n                };\r\n            } else {\r\n                this.editorData = source.editorData;\r\n                this.editorData.locations = locations;\r\n            }\r\n\r\n            const blockMap: { [key: number]: number } = {};\r\n\r\n            for (const key in map) {\r\n                blockMap[key] = map[key].uniqueId;\r\n            }\r\n\r\n            this.editorData.map = blockMap;\r\n        }\r\n\r\n        this.comment = source.comment;\r\n    }\r\n\r\n    private _restoreConnections(block: NodeRenderGraphBlock, source: any, map: { [key: number]: NodeRenderGraphBlock }) {\r\n        for (const outputPoint of block.outputs) {\r\n            for (const candidate of source.blocks) {\r\n                const target = map[candidate.id];\r\n\r\n                if (!target) {\r\n                    continue;\r\n                }\r\n\r\n                for (const input of candidate.inputs) {\r\n                    if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {\r\n                        const inputPoint = target.getInputByName(input.inputName);\r\n                        if (!inputPoint || inputPoint.isConnected) {\r\n                            continue;\r\n                        }\r\n\r\n                        outputPoint.connectTo(inputPoint, true);\r\n                        this._restoreConnections(target, source, map);\r\n                        continue;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Generate a string containing the code declaration required to create an equivalent of this node render graph\r\n     * @returns a string\r\n     */\r\n    public generateCode() {\r\n        let alreadyDumped: NodeRenderGraphBlock[] = [];\r\n        const blocks: NodeRenderGraphBlock[] = [];\r\n        const uniqueNames: string[] = [\"const\", \"var\", \"let\"];\r\n        // Gets active blocks\r\n        if (this.outputBlock) {\r\n            this._gatherBlocks(this.outputBlock, blocks);\r\n        }\r\n\r\n        // Generate\r\n        const options = JSON.stringify(this._options);\r\n        let codeString = `let nodeRenderGraph = new BABYLON.NodeRenderGraph(\"${this.name || \"render graph\"}\", scene, ${options});\\n`;\r\n        for (const node of blocks) {\r\n            if (node.isInput && alreadyDumped.indexOf(node) === -1) {\r\n                codeString += node._dumpCode(uniqueNames, alreadyDumped) + \"\\n\";\r\n            }\r\n        }\r\n\r\n        if (this.outputBlock) {\r\n            // Connections\r\n            alreadyDumped = [];\r\n            codeString += \"// Connections\\n\";\r\n            codeString += this.outputBlock._dumpCodeForOutputConnections(alreadyDumped);\r\n\r\n            // Output nodes\r\n            codeString += \"// Output nodes\\n\";\r\n            codeString += `nodeRenderGraph.outputBlock = ${this.outputBlock._codeVariableName};\\n`;\r\n            codeString += `nodeRenderGraph.build();\\n`;\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    private _gatherBlocks(rootNode: NodeRenderGraphBlock, list: NodeRenderGraphBlock[]) {\r\n        if (list.indexOf(rootNode) !== -1) {\r\n            return;\r\n        }\r\n        list.push(rootNode);\r\n\r\n        for (const input of rootNode.inputs) {\r\n            const connectedPoint = input.connectedPoint;\r\n            if (connectedPoint) {\r\n                const block = connectedPoint.ownerBlock;\r\n                if (block !== rootNode) {\r\n                    this._gatherBlocks(block, list);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Teleportation\r\n        if (rootNode.isTeleportOut) {\r\n            const block = rootNode as NodeRenderGraphTeleportOutBlock;\r\n            if (block.entryPoint) {\r\n                this._gatherBlocks(block.entryPoint, list);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current graph and set it to a default state\r\n     */\r\n    public setToDefault() {\r\n        this.clear();\r\n\r\n        this.editorData = null;\r\n\r\n        // Source textures\r\n        const colorTexture = new NodeRenderGraphInputBlock(\"Color Texture\", this._frameGraph, this._scene, NodeRenderGraphBlockConnectionPointTypes.Texture);\r\n        colorTexture.creationOptions.options.samples = 4;\r\n\r\n        const depthTexture = new NodeRenderGraphInputBlock(\"Depth Texture\", this._frameGraph, this._scene, NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment);\r\n        depthTexture.creationOptions.options.samples = 4;\r\n\r\n        // Clear texture\r\n        const clear = new NodeRenderGraphClearBlock(\"Clear\", this._frameGraph, this._scene);\r\n        clear.clearDepth = true;\r\n        clear.clearStencil = true;\r\n\r\n        colorTexture.output.connectTo(clear.target);\r\n        depthTexture.output.connectTo(clear.depth);\r\n\r\n        // Object list and culling\r\n        const camera = new NodeRenderGraphInputBlock(\"Camera\", this._frameGraph, this._scene, NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        const objectList = new NodeRenderGraphInputBlock(\"Object List\", this._frameGraph, this._scene, NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n        const cull = new NodeRenderGraphCullObjectsBlock(\"Cull\", this._frameGraph, this._scene);\r\n\r\n        camera.output.connectTo(cull.camera);\r\n        objectList.output.connectTo(cull.objects);\r\n\r\n        // Render objects\r\n        const mainRendering = new NodeRenderGraphObjectRendererBlock(\"Main Rendering\", this._frameGraph, this._scene);\r\n\r\n        camera.output.connectTo(mainRendering.camera);\r\n        cull.output.connectTo(mainRendering.objects);\r\n        clear.output.connectTo(mainRendering.target);\r\n        clear.outputDepth.connectTo(mainRendering.depth);\r\n\r\n        // Final output\r\n        const output = new NodeRenderGraphOutputBlock(\"Output\", this._frameGraph, this._scene);\r\n        mainRendering.output.connectTo(output.texture);\r\n\r\n        this.outputBlock = output;\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current node render graph.\r\n     * Note that you should call buildAsync() on the returned graph to make it usable.\r\n     * @param name defines the name to use for the new node render graph\r\n     * @returns the new node render graph\r\n     */\r\n    public clone(name: string): NodeRenderGraph {\r\n        const serializationObject = this.serialize();\r\n\r\n        const clone = SerializationHelper.Clone(() => new NodeRenderGraph(name, this._scene), this);\r\n        clone.name = name;\r\n\r\n        clone.parseSerializedObject(serializationObject);\r\n        clone._buildId = this._buildId;\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serializes this node render graph in a JSON representation\r\n     * @param selectedBlocks defines the list of blocks to save (if null the whole node render graph will be saved)\r\n     * @returns the serialized node render graph object\r\n     */\r\n    public serialize(selectedBlocks?: NodeRenderGraphBlock[]): any {\r\n        const serializationObject = selectedBlocks ? {} : SerializationHelper.Serialize(this);\r\n        serializationObject.editorData = JSON.parse(JSON.stringify(this.editorData)); // Copy\r\n\r\n        let blocks: NodeRenderGraphBlock[] = [];\r\n\r\n        if (selectedBlocks) {\r\n            blocks = selectedBlocks;\r\n        } else {\r\n            serializationObject.customType = \"BABYLON.NodeRenderGraph\";\r\n            if (this.outputBlock) {\r\n                serializationObject.outputNodeId = this.outputBlock.uniqueId;\r\n            }\r\n        }\r\n\r\n        // Blocks\r\n        serializationObject.blocks = [];\r\n\r\n        for (const block of blocks) {\r\n            serializationObject.blocks.push(block.serialize());\r\n        }\r\n\r\n        if (!selectedBlocks) {\r\n            for (const block of this.attachedBlocks) {\r\n                if (blocks.indexOf(block) !== -1) {\r\n                    continue;\r\n                }\r\n                serializationObject.blocks.push(block.serialize());\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources\r\n     */\r\n    public dispose(): void {\r\n        for (const block of this.attachedBlocks) {\r\n            block.dispose();\r\n        }\r\n\r\n        this._frameGraph.dispose();\r\n        (this._frameGraph as WritableObject<FrameGraph>) = undefined as any;\r\n\r\n        this._engine.onResizeObservable.remove(this._resizeObserver);\r\n        (this._resizeObserver as WritableObject<Nullable<Observer<AbstractEngine>>>) = null;\r\n\r\n        this.attachedBlocks.length = 0;\r\n        this.onBuildErrorObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Creates a new node render graph set to default basic configuration\r\n     * @param name defines the name of the node render graph\r\n     * @param scene defines the scene to use\r\n     * @param nodeRenderGraphOptions defines options to use when creating the node render graph\r\n     * @returns a new NodeRenderGraph\r\n     */\r\n    public static async CreateDefaultAsync(name: string, scene: Scene, nodeRenderGraphOptions?: INodeRenderGraphCreateOptions): Promise<NodeRenderGraph> {\r\n        const renderGraph = new NodeRenderGraph(name, scene, nodeRenderGraphOptions);\r\n\r\n        renderGraph.setToDefault();\r\n        await renderGraph.buildAsync(false, true, false);\r\n\r\n        return renderGraph;\r\n    }\r\n\r\n    /**\r\n     * Creates a node render graph from parsed graph data\r\n     * @param source defines the JSON representation of the node render graph\r\n     * @param scene defines the scene to use\r\n     * @param nodeRenderGraphOptions defines options to use when creating the node render\r\n     * @param skipBuild defines whether to skip building the node render graph (default is true)\r\n     * @returns a new node render graph\r\n     */\r\n    public static Parse(source: any, scene: Scene, nodeRenderGraphOptions?: INodeRenderGraphCreateOptions, skipBuild: boolean = true): NodeRenderGraph {\r\n        const renderGraph = SerializationHelper.Parse(() => new NodeRenderGraph(source.name, scene, nodeRenderGraphOptions), source, null);\r\n\r\n        renderGraph.parseSerializedObject(source);\r\n        if (!skipBuild) {\r\n            void renderGraph.buildAsync();\r\n        }\r\n\r\n        return renderGraph;\r\n    }\r\n\r\n    /**\r\n     * Creates a node render graph from a snippet saved by the node render graph editor\r\n     * @param snippetId defines the snippet to load\r\n     * @param scene defines the scene to use\r\n     * @param nodeRenderGraphOptions defines options to use when creating the node render graph\r\n     * @param nodeRenderGraph defines a node render graph to update (instead of creating a new one)\r\n     * @param skipBuild defines whether to skip building the node render graph (default is true)\r\n     * @returns a promise that will resolve to the new node render graph\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromSnippetAsync(\r\n        snippetId: string,\r\n        scene: Scene,\r\n        nodeRenderGraphOptions?: INodeRenderGraphCreateOptions,\r\n        nodeRenderGraph?: NodeRenderGraph,\r\n        skipBuild: boolean = true\r\n    ): Promise<NodeRenderGraph> {\r\n        if (snippetId === \"_BLANK\") {\r\n            return NodeRenderGraph.CreateDefaultAsync(\"blank\", scene, nodeRenderGraphOptions);\r\n        }\r\n\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", async () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n                        const serializationObject = JSON.parse(snippet.nodeRenderGraph);\r\n\r\n                        if (!nodeRenderGraph) {\r\n                            nodeRenderGraph = SerializationHelper.Parse(() => new NodeRenderGraph(snippetId, scene, nodeRenderGraphOptions), serializationObject, null);\r\n                        }\r\n\r\n                        nodeRenderGraph.parseSerializedObject(serializationObject);\r\n                        nodeRenderGraph.snippetId = snippetId;\r\n\r\n                        try {\r\n                            if (!skipBuild) {\r\n                                await nodeRenderGraph.buildAsync();\r\n                            }\r\n                            resolve(nodeRenderGraph);\r\n                        } catch (err) {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            reject(err);\r\n                        }\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the snippet \" + snippetId);\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", this.SnippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\r\n            request.send();\r\n        });\r\n    }\r\n}\r\n","import {\r\n    type BaseTexture,\r\n    type DataBuffer,\r\n    type ExternalTexture,\r\n    type FrameGraph,\r\n    type FrameGraphContext,\r\n    type FrameGraphPass,\r\n    type IComputeShaderOptions,\r\n    type IComputeShaderPath,\r\n    type InternalTexture,\r\n    type StorageBuffer,\r\n    type TextureSampler,\r\n    type VideoTexture,\r\n} from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { ComputeShader } from \"core/Compute/computeShader.pure\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Task used to execute a compute shader (WebGPU only)\r\n */\r\nexport class FrameGraphComputeShaderTask extends FrameGraphTask {\r\n    private readonly _notSupported: boolean;\r\n    private readonly _cs: ComputeShader;\r\n    private readonly _ubo: { [name: string]: { ubo: UniformBuffer; autoUpdate: boolean } };\r\n\r\n    /**\r\n     * Defines the dispatch size for the compute shader\r\n     */\r\n    public dispatchSize = new Vector3(1, 1, 1);\r\n\r\n    /**\r\n     * Defines an indirect dispatch buffer and offset.\r\n     * If set, this will be used instead of the dispatchSize property and an indirect dispatch will be performed.\r\n     * \"offset\" is the offset in the buffer where the workgroup counts are stored (default: 0)\r\n     */\r\n    public indirectDispatch?: { buffer: StorageBuffer | DataBuffer; offset?: number };\r\n\r\n    /**\r\n     * An optional execute function that will be called at the beginning of the task execution\r\n     */\r\n    public execute?: (context: FrameGraphContext) => void;\r\n\r\n    /**\r\n     * Gets the compute shader used by the task\r\n     */\r\n    public get computeShader(): ComputeShader {\r\n        return this._cs;\r\n    }\r\n\r\n    /**\r\n     * Gets a uniform buffer created by a call to createUniformBuffer()\r\n     * @param name Name of the uniform buffer\r\n     * @returns The uniform buffer\r\n     */\r\n    public getUniformBuffer(name: string): UniformBuffer {\r\n        return this._ubo[name]?.ubo;\r\n    }\r\n\r\n    /**\r\n     * Creates a new compute shader task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     * @param shaderPath Defines the route to the shader code in one of three ways:\r\n     *  * object: \\{ compute: \"custom\" \\}, used with ShaderStore.ShadersStoreWGSL[\"customComputeShader\"]\r\n     *  * object: \\{ computeElement: \"HTMLElementId\" \\}, used with shader code in script tags\r\n     *  * object: \\{ computeSource: \"compute shader code string\" \\}, where the string contains the shader code\r\n     *  * string: try first to find the code in ShaderStore.ShadersStoreWGSL[shaderPath + \"ComputeShader\"]. If not, assumes it is a file with name shaderPath.compute.fx in index.html folder.\r\n     * @param options Define the options used to create the shader\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, shaderPath: IComputeShaderPath | string, options: Partial<IComputeShaderOptions> = {}) {\r\n        super(name, frameGraph);\r\n\r\n        if (!frameGraph.engine.getCaps().supportComputeShaders) {\r\n            this._notSupported = true;\r\n            Logger.Error(\"This engine does not support compute shaders!\");\r\n            return;\r\n        }\r\n\r\n        this._notSupported = false;\r\n        this._cs = new ComputeShader(name + \"_cs\", frameGraph.engine, shaderPath, options);\r\n        this._ubo = {};\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return this._notSupported ? true : this._cs.isReady();\r\n    }\r\n\r\n    /**\r\n     * Creates a uniform buffer and binds it to the shader\r\n     * @param name Name of the uniform buffer\r\n     * @param description Description of the uniform buffer: names and sizes (in floats) of the uniforms\r\n     * @param autoUpdate If the UBO must be updated automatically before each dispatch (default: true)\r\n     * @returns The created uniform buffer\r\n     */\r\n    public createUniformBuffer(name: string, description: { [name: string]: number }, autoUpdate = true): UniformBuffer {\r\n        const uBuffer = new UniformBuffer(this._frameGraph.engine);\r\n\r\n        this._ubo[name] = { ubo: uBuffer, autoUpdate };\r\n\r\n        for (const key in description) {\r\n            uBuffer.addUniform(key, description[key]);\r\n        }\r\n\r\n        this._cs.setUniformBuffer(name, uBuffer);\r\n\r\n        return uBuffer;\r\n    }\r\n\r\n    /**\r\n     * Binds a texture to the shader\r\n     * @param name Binding name of the texture\r\n     * @param texture Texture to bind\r\n     * @param bindSampler Bind the sampler corresponding to the texture (default: true). The sampler will be bound just before the binding index of the texture\r\n     */\r\n    public setTexture(name: string, texture: BaseTexture, bindSampler = true): void {\r\n        this._cs.setTexture(name, texture, bindSampler);\r\n    }\r\n\r\n    /**\r\n     * Binds an internal texture to the shader\r\n     * @param name Binding name of the texture\r\n     * @param texture Texture to bind\r\n     */\r\n    public setInternalTexture(name: string, texture: InternalTexture): void {\r\n        this._cs.setInternalTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Binds a storage texture to the shader\r\n     * @param name Binding name of the texture\r\n     * @param texture Texture to bind\r\n     */\r\n    public setStorageTexture(name: string, texture: BaseTexture): void {\r\n        this._cs.setStorageTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Binds an external texture to the shader\r\n     * @param name Binding name of the texture\r\n     * @param texture Texture to bind\r\n     */\r\n    public setExternalTexture(name: string, texture: ExternalTexture): void {\r\n        this._cs.setExternalTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Binds a video texture to the shader (by binding the external texture attached to this video)\r\n     * @param name Binding name of the texture\r\n     * @param texture Texture to bind\r\n     * @returns true if the video texture was successfully bound, else false. false will be returned if the current engine does not support external textures\r\n     */\r\n    public setVideoTexture(name: string, texture: VideoTexture) {\r\n        return this._cs.setVideoTexture(name, texture);\r\n    }\r\n\r\n    /**\r\n     * Binds a uniform buffer to the shader\r\n     * @param name Binding name of the buffer\r\n     * @param buffer Buffer to bind\r\n     */\r\n    public setUniformBuffer(name: string, buffer: UniformBuffer | DataBuffer): void {\r\n        this._cs.setUniformBuffer(name, buffer);\r\n    }\r\n\r\n    /**\r\n     * Binds a storage buffer to the shader\r\n     * @param name Binding name of the buffer\r\n     * @param buffer Buffer to bind\r\n     */\r\n    public setStorageBuffer(name: string, buffer: StorageBuffer | DataBuffer): void {\r\n        this._cs.setStorageBuffer(name, buffer);\r\n    }\r\n\r\n    /**\r\n     * Binds a texture sampler to the shader\r\n     * @param name Binding name of the sampler\r\n     * @param sampler Sampler to bind\r\n     */\r\n    public setTextureSampler(name: string, sampler: TextureSampler): void {\r\n        this._cs.setTextureSampler(name, sampler);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphComputeShaderTask\";\r\n    }\r\n\r\n    public record(skipCreationOfDisabledPasses?: boolean): FrameGraphPass<FrameGraphContext> {\r\n        const pass = this._frameGraph.addPass(this.name);\r\n\r\n        if (this._notSupported) {\r\n            pass.setExecuteFunc(() => {});\r\n        } else {\r\n            pass.setExecuteFunc((context) => {\r\n                this.execute?.(context);\r\n\r\n                for (const key in this._ubo) {\r\n                    const uboEntry = this._ubo[key];\r\n                    if (uboEntry.autoUpdate) {\r\n                        uboEntry.ubo.update();\r\n                    }\r\n                }\r\n\r\n                if (this.indirectDispatch) {\r\n                    context.pushDebugGroup(`Indirect dispatch compute shader (${this.name})`);\r\n                    this._cs.dispatchIndirect(this.indirectDispatch.buffer, this.indirectDispatch.offset);\r\n                    context.popDebugGroup();\r\n                } else {\r\n                    context.pushDebugGroup(`Dispatch compute shader (${this.name})`);\r\n                    this._cs.dispatch(this.dispatchSize.x, this.dispatchSize.y, this.dispatchSize.z);\r\n                    context.popDebugGroup();\r\n                }\r\n            });\r\n        }\r\n\r\n        if (!skipCreationOfDisabledPasses) {\r\n            const passDisabled = this._frameGraph.addPass(this.name + \"_disabled\", true);\r\n\r\n            passDisabled.setExecuteFunc(() => {});\r\n        }\r\n\r\n        return pass;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        for (const key in this._ubo) {\r\n            this._ubo[key].ubo.dispose();\r\n        }\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraph, type IComputeShaderPath, type IComputeShaderOptions } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { FrameGraphComputeShaderTask } from \"../../Tasks/Misc/computeShaderTask\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to execute a compute shader in the frame graph\r\n */\r\nexport class NodeRenderGraphComputeShaderBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphComputeShaderTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeRenderGraphComputeShaderBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param computeShaderPath defines the compute shader path or source\r\n     * @param computeShaderOptions defines the compute shader options\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        frameGraph: FrameGraph,\r\n        scene: Scene,\r\n        computeShaderPath: string | IComputeShaderPath = \"@compute @workgroup_size(1, 1, 1)\\nfn main() {}\",\r\n        computeShaderOptions: IComputeShaderOptions = { bindingsMapping: {} }\r\n    ) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [computeShaderPath, computeShaderOptions];\r\n\r\n        this._addDependenciesInput(\r\n            NodeRenderGraphBlockConnectionPointTypes.Camera | NodeRenderGraphBlockConnectionPointTypes.ShadowLight | NodeRenderGraphBlockConnectionPointTypes.ObjectList\r\n        );\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.ResourceContainer);\r\n\r\n        this._frameGraphTask = new FrameGraphComputeShaderTask(name, frameGraph, computeShaderPath, computeShaderOptions);\r\n    }\r\n\r\n    private _createTask(shaderPath: string | IComputeShaderPath, shaderOptions?: IComputeShaderOptions) {\r\n        const dispatchSize = this._frameGraphTask.dispatchSize;\r\n        const indirectDispatch = this._frameGraphTask.indirectDispatch;\r\n        const execute = this._frameGraphTask.execute;\r\n\r\n        this._frameGraphTask.dispose();\r\n        this._frameGraphTask = new FrameGraphComputeShaderTask(this.name, this._frameGraph, shaderPath, shaderOptions);\r\n\r\n        this._frameGraphTask.dispatchSize = dispatchSize;\r\n        this._frameGraphTask.indirectDispatch = indirectDispatch;\r\n        this._frameGraphTask.execute = execute;\r\n\r\n        this._additionalConstructionParameters = [shaderPath, shaderOptions];\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the execute function\r\n     */\r\n    public get shaderPath(): string | IComputeShaderPath {\r\n        return this._frameGraphTask.computeShader.shaderPath;\r\n    }\r\n\r\n    public set shaderPath(path: string | IComputeShaderPath) {\r\n        this._createTask(path, this.shaderOptions);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the execute when task disabled function\r\n     */\r\n    public get shaderOptions(): IComputeShaderOptions {\r\n        return this._frameGraphTask.computeShader.options;\r\n    }\r\n\r\n    public set shaderOptions(options: IComputeShaderOptions) {\r\n        this._createTask(this.shaderPath, options);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphComputeShaderBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for computeShaderBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterComputeShaderBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphComputeShaderBlock\", NodeRenderGraphComputeShaderBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraph, type NodeRenderGraphBuildState } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used as a pass through\r\n */\r\nexport class NodeRenderGraphElbowBlock extends NodeRenderGraphBlock {\r\n    /**\r\n     * Creates a new NodeRenderGraphElbowBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"input\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphElbowBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input = this._inputs[0];\r\n\r\n        this._propagateInputValueToOutput(input, output);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for frameGraphNodeBlocksElbowBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFrameGraphNodeBlocksElbowBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphElbowBlock\", NodeRenderGraphElbowBlock);\r\n}\r\n","import { type FrameGraph, type FrameGraphContext, type FrameGraphPass } from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to execute a custom function.\r\n */\r\nexport class FrameGraphExecuteTask extends FrameGraphTask {\r\n    /**\r\n     * The function to execute.\r\n     */\r\n    public func: (context: FrameGraphContext) => void;\r\n\r\n    /**\r\n     * The function to execute when the task is disabled (optional).\r\n     */\r\n    public funcDisabled?: (context: FrameGraphContext) => void;\r\n\r\n    /**\r\n     * Custom readiness check (optional).\r\n     */\r\n    public customIsReady?: () => boolean;\r\n\r\n    public override isReady(): boolean {\r\n        return !this.customIsReady || this.customIsReady();\r\n    }\r\n\r\n    /**\r\n     * Creates a new execute task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphExecuteTask\";\r\n    }\r\n\r\n    public record(): FrameGraphPass<FrameGraphContext> {\r\n        if (!this.func) {\r\n            throw new Error(\"FrameGraphExecuteTask: Execute task must have a function.\");\r\n        }\r\n\r\n        const pass = this._frameGraph.addPass(this.name);\r\n\r\n        pass.setExecuteFunc((context) => {\r\n            this.func(context);\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setExecuteFunc((context) => {\r\n            this.funcDisabled?.(context);\r\n        });\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraph, type FrameGraphContext } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { FrameGraphExecuteTask } from \"../../Tasks/Misc/executeTask\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to execute a custom function in the frame graph\r\n */\r\nexport class NodeRenderGraphExecuteBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphExecuteTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeRenderGraphExecuteBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._addDependenciesInput(\r\n            NodeRenderGraphBlockConnectionPointTypes.Camera | NodeRenderGraphBlockConnectionPointTypes.ShadowLight | NodeRenderGraphBlockConnectionPointTypes.ObjectList\r\n        );\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.ResourceContainer);\r\n\r\n        this._frameGraphTask = new FrameGraphExecuteTask(name, frameGraph);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the execute function\r\n     */\r\n    public get func(): (context: FrameGraphContext) => void {\r\n        return this._frameGraphTask.func;\r\n    }\r\n\r\n    public set func(func: (context: FrameGraphContext) => void) {\r\n        this._frameGraphTask.func = func;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the execute when task disabled function\r\n     */\r\n    public get funcDisabled(): ((context: FrameGraphContext) => void) | undefined {\r\n        return this._frameGraphTask.funcDisabled;\r\n    }\r\n\r\n    public set funcDisabled(func: ((context: FrameGraphContext) => void) | undefined) {\r\n        this._frameGraphTask.funcDisabled = func;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphExecuteBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for executeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterExecuteBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphExecuteBlock\", NodeRenderGraphExecuteBlock);\r\n}\r\n","import { serialize, serializeAsVector3 } from \"../Misc/decorators\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Light } from \"./light\";\r\nimport { Axis } from \"../Maths/math.axis\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n/**\r\n * Interface describing all the common properties and methods a shadow light needs to implement.\r\n * This helps both the shadow generator and materials to generate the corresponding shadow maps\r\n * as well as binding the different shadow properties to the effects.\r\n */\r\nexport interface IShadowLight extends Light {\r\n    /**\r\n     * The light id in the scene (used in scene.getLightById for instance)\r\n     */\r\n    id: string;\r\n    /**\r\n     * The position the shadow will be casted from.\r\n     */\r\n    position: Vector3;\r\n    /**\r\n     * In 2d mode (needCube being false), the direction used to cast the shadow.\r\n     */\r\n    direction: Vector3;\r\n    /**\r\n     * The transformed position. Position of the light in world space taking parenting in account.\r\n     */\r\n    transformedPosition: Vector3;\r\n    /**\r\n     * The transformed direction. Direction of the light in world space taking parenting in account.\r\n     */\r\n    transformedDirection: Vector3;\r\n    /**\r\n     * The friendly name of the light in the scene.\r\n     */\r\n    name: string;\r\n    /**\r\n     * Defines the shadow projection clipping minimum z value.\r\n     */\r\n    shadowMinZ: number;\r\n    /**\r\n     * Defines the shadow projection clipping maximum z value.\r\n     */\r\n    shadowMaxZ: number;\r\n\r\n    /**\r\n     * Computes the transformed information (transformedPosition and transformedDirection in World space) of the current light\r\n     * @returns true if the information has been computed, false if it does not need to (no parenting)\r\n     */\r\n    computeTransformedInformation(): boolean;\r\n\r\n    /**\r\n     * Gets the scene the light belongs to.\r\n     * @returns The scene\r\n     */\r\n    getScene(): Scene;\r\n\r\n    /**\r\n     * Callback defining a custom Projection Matrix Builder.\r\n     * This can be used to override the default projection matrix computation.\r\n     */\r\n    customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;\r\n\r\n    /**\r\n     * Sets the shadow projection matrix in parameter to the generated projection matrix.\r\n     * @param matrix The matrix to update with the projection information\r\n     * @param viewMatrix The transform matrix of the light\r\n     * @param renderList The list of mesh to render in the map\r\n     * @returns The current light\r\n     */\r\n    setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): IShadowLight;\r\n\r\n    /**\r\n     * Gets the current depth scale used in ESM.\r\n     * @returns The scale\r\n     */\r\n    getDepthScale(): number;\r\n\r\n    /**\r\n     * Returns whether or not the shadow generation require a cube texture or a 2d texture.\r\n     * @returns true if a cube texture needs to be use\r\n     */\r\n    needCube(): boolean;\r\n\r\n    /**\r\n     * Detects if the projection matrix requires to be recomputed this frame.\r\n     * @returns true if it requires to be recomputed otherwise, false.\r\n     */\r\n    needProjectionMatrixCompute(): boolean;\r\n\r\n    /**\r\n     * Forces the shadow generator to recompute the projection matrix even if position and direction did not changed.\r\n     */\r\n    forceProjectionMatrixCompute(): void;\r\n\r\n    /**\r\n     * Get the direction to use to render the shadow map. In case of cube texture, the face index can be passed.\r\n     * @param faceIndex The index of the face we are computed the direction to generate shadow\r\n     * @returns The set direction in 2d mode otherwise the direction to the cubemap face if needCube() is true\r\n     */\r\n    getShadowDirection(faceIndex?: number): Vector3;\r\n\r\n    /**\r\n     * Gets the minZ used for shadow according to both the scene and the light.\r\n     * @param activeCamera The camera we are returning the min for\r\n     * @returns the depth min z\r\n     */\r\n    getDepthMinZ(activeCamera: Nullable<Camera>): number;\r\n\r\n    /**\r\n     * Gets the maxZ used for shadow according to both the scene and the light.\r\n     * @param activeCamera The camera we are returning the max for\r\n     * @returns the depth max z\r\n     */\r\n    getDepthMaxZ(activeCamera: Nullable<Camera>): number;\r\n}\r\n\r\n/**\r\n * Base implementation IShadowLight\r\n * It groups all the common behaviour in order to reduce duplication and better follow the DRY pattern.\r\n */\r\nexport abstract class ShadowLight extends Light implements IShadowLight {\r\n    protected abstract _setDefaultShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;\r\n\r\n    protected _position: Vector3;\r\n    protected _setPosition(value: Vector3) {\r\n        this._position = value;\r\n    }\r\n    /**\r\n     * Sets the position the shadow will be casted from. Also use as the light position for both\r\n     * point and spot lights.\r\n     */\r\n    @serializeAsVector3()\r\n    public get position(): Vector3 {\r\n        return this._position;\r\n    }\r\n    /**\r\n     * Sets the position the shadow will be casted from. Also use as the light position for both\r\n     * point and spot lights.\r\n     */\r\n    public set position(value: Vector3) {\r\n        this._setPosition(value);\r\n    }\r\n\r\n    protected _direction: Vector3;\r\n    protected _setDirection(value: Vector3) {\r\n        this._direction = value;\r\n    }\r\n    /**\r\n     * In 2d mode (needCube being false), gets the direction used to cast the shadow.\r\n     * Also use as the light direction on spot and directional lights.\r\n     */\r\n    @serializeAsVector3()\r\n    public get direction(): Vector3 {\r\n        return this._direction;\r\n    }\r\n    /**\r\n     * In 2d mode (needCube being false), sets the direction used to cast the shadow.\r\n     * Also use as the light direction on spot and directional lights.\r\n     */\r\n    public set direction(value: Vector3) {\r\n        this._setDirection(value);\r\n    }\r\n\r\n    protected _shadowMinZ: number;\r\n    /**\r\n     * Gets the shadow projection clipping minimum z value.\r\n     */\r\n    @serialize()\r\n    public get shadowMinZ(): number {\r\n        return this._shadowMinZ;\r\n    }\r\n    /**\r\n     * Sets the shadow projection clipping minimum z value.\r\n     */\r\n    public set shadowMinZ(value: number) {\r\n        this._shadowMinZ = value;\r\n        this.forceProjectionMatrixCompute();\r\n    }\r\n\r\n    protected _shadowMaxZ: number;\r\n    /**\r\n     * Sets the shadow projection clipping maximum z value.\r\n     */\r\n    @serialize()\r\n    public get shadowMaxZ(): number {\r\n        return this._shadowMaxZ;\r\n    }\r\n    /**\r\n     * Gets the shadow projection clipping maximum z value.\r\n     */\r\n    public set shadowMaxZ(value: number) {\r\n        this._shadowMaxZ = value;\r\n        this.forceProjectionMatrixCompute();\r\n    }\r\n\r\n    /**\r\n     * Callback defining a custom Projection Matrix Builder.\r\n     * This can be used to override the default projection matrix computation.\r\n     */\r\n    public customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;\r\n\r\n    /**\r\n     * The transformed position. Position of the light in world space taking parenting in account. Needs to be computed by calling computeTransformedInformation.\r\n     */\r\n    public transformedPosition: Vector3;\r\n\r\n    /**\r\n     * The transformed direction. Direction of the light in world space taking parenting in account.\r\n     */\r\n    public transformedDirection: Vector3;\r\n\r\n    private _needProjectionMatrixCompute: boolean = true;\r\n\r\n    /**\r\n     * Computes the transformed information (transformedPosition and transformedDirection in World space) of the current light\r\n     * @returns true if the information has been computed, false if it does not need to (no parenting)\r\n     */\r\n    public computeTransformedInformation(): boolean {\r\n        if (this.parent && this.parent.getWorldMatrix) {\r\n            if (!this.transformedPosition) {\r\n                this.transformedPosition = Vector3.Zero();\r\n            }\r\n            Vector3.TransformCoordinatesToRef(this.position, this.parent.getWorldMatrix(), this.transformedPosition);\r\n\r\n            // In case the direction is present.\r\n            if (this.direction) {\r\n                if (!this.transformedDirection) {\r\n                    this.transformedDirection = Vector3.Zero();\r\n                }\r\n                Vector3.TransformNormalToRef(this.direction, this.parent.getWorldMatrix(), this.transformedDirection);\r\n            }\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Return the depth scale used for the shadow map.\r\n     * @returns the depth scale.\r\n     */\r\n    public getDepthScale(): number {\r\n        return 50.0;\r\n    }\r\n\r\n    /**\r\n     * Get the direction to use to render the shadow map. In case of cube texture, the face index can be passed.\r\n     * @param faceIndex The index of the face we are computed the direction to generate shadow\r\n     * @returns The set direction in 2d mode otherwise the direction to the cubemap face if needCube() is true\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public getShadowDirection(faceIndex?: number): Vector3 {\r\n        return this.transformedDirection ? this.transformedDirection : this.direction;\r\n    }\r\n\r\n    /**\r\n     * If computeTransformedInformation has been called, returns the ShadowLight absolute position in the world. Otherwise, returns the local position.\r\n     * @returns the position vector in world space\r\n     */\r\n    public override getAbsolutePosition(): Vector3 {\r\n        return this.transformedPosition ? this.transformedPosition : this.position;\r\n    }\r\n\r\n    /**\r\n     * Sets the ShadowLight direction toward the passed target.\r\n     * @param target The point to target in local space\r\n     * @returns the updated ShadowLight direction\r\n     */\r\n    public setDirectionToTarget(target: Vector3): Vector3 {\r\n        this.direction = Vector3.Normalize(target.subtract(this.position));\r\n        return this.direction;\r\n    }\r\n\r\n    /**\r\n     * Returns the light rotation in euler definition.\r\n     * @returns the x y z rotation in local space.\r\n     */\r\n    public getRotation(): Vector3 {\r\n        this.direction.normalize();\r\n        const xaxis = Vector3.Cross(this.direction, Axis.Y);\r\n        const yaxis = Vector3.Cross(xaxis, this.direction);\r\n        return Vector3.RotationFromAxis(xaxis, yaxis, this.direction);\r\n    }\r\n\r\n    /**\r\n     * Returns whether or not the shadow generation require a cube texture or a 2d texture.\r\n     * @returns true if a cube texture needs to be use\r\n     */\r\n    public needCube(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Detects if the projection matrix requires to be recomputed this frame.\r\n     * @returns true if it requires to be recomputed otherwise, false.\r\n     */\r\n    public needProjectionMatrixCompute(): boolean {\r\n        return this._needProjectionMatrixCompute;\r\n    }\r\n\r\n    /**\r\n     * Forces the shadow generator to recompute the projection matrix even if position and direction did not changed.\r\n     */\r\n    public forceProjectionMatrixCompute(): void {\r\n        this._needProjectionMatrixCompute = true;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _initCache() {\r\n        super._initCache();\r\n\r\n        this._cache.position = Vector3.Zero();\r\n    }\r\n\r\n    /** @internal */\r\n    public override _isSynchronized(): boolean {\r\n        if (!this._cache.position.equals(this.position)) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Computes the world matrix of the node\r\n     * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch\r\n     * @returns the world matrix\r\n     */\r\n    public override computeWorldMatrix(force?: boolean): Matrix {\r\n        if (!force && this.isSynchronized()) {\r\n            this._currentRenderId = this.getScene().getRenderId();\r\n            return this._worldMatrix;\r\n        }\r\n\r\n        this._updateCache();\r\n        this._cache.position.copyFrom(this.position);\r\n\r\n        if (!this._worldMatrix) {\r\n            this._worldMatrix = Matrix.Identity();\r\n        }\r\n\r\n        Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._worldMatrix);\r\n\r\n        if (this.parent && this.parent.getWorldMatrix) {\r\n            this._worldMatrix.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);\r\n\r\n            this._markSyncedWithParent();\r\n        }\r\n\r\n        // Cache the determinant\r\n        this._worldMatrixDeterminantIsDirty = true;\r\n\r\n        return this._worldMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the minZ used for shadow according to both the scene and the light.\r\n     * @param activeCamera The camera we are returning the min for\r\n     * @returns the depth min z\r\n     */\r\n    public getDepthMinZ(activeCamera: Nullable<Camera>): number {\r\n        return this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera?.minZ || Constants.ShadowMinZ;\r\n    }\r\n\r\n    /**\r\n     * Gets the maxZ used for shadow according to both the scene and the light.\r\n     * @param activeCamera The camera we are returning the max for\r\n     * @returns the depth max z\r\n     */\r\n    public getDepthMaxZ(activeCamera: Nullable<Camera>): number {\r\n        return this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera?.maxZ || Constants.ShadowMaxZ;\r\n    }\r\n\r\n    /**\r\n     * Sets the shadow projection matrix in parameter to the generated projection matrix.\r\n     * @param matrix The matrix to updated with the projection information\r\n     * @param viewMatrix The transform matrix of the light\r\n     * @param renderList The list of mesh to render in the map\r\n     * @returns The current light\r\n     */\r\n    public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): IShadowLight {\r\n        if (this.customProjectionMatrixBuilder) {\r\n            this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);\r\n        } else {\r\n            this._setDefaultShadowProjectionMatrix(matrix, viewMatrix, renderList);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    protected override _syncParentEnabledState() {\r\n        super._syncParentEnabledState();\r\n        if (!this.parent || !this.parent.getWorldMatrix) {\r\n            (this.transformedPosition as any) = null;\r\n            (this.transformedDirection as any) = null;\r\n        }\r\n    }\r\n\r\n    protected _viewMatrix: Matrix = Matrix.Identity();\r\n    protected _projectionMatrix: Matrix = Matrix.Identity();\r\n\r\n    /**\r\n     * Returns the view matrix.\r\n     * @param faceIndex The index of the face for which we want to extract the view matrix. Only used for point light types.\r\n     * @returns The view matrix. Can be null, if a view matrix cannot be defined for the type of light considered (as for a hemispherical light, for example).\r\n     */\r\n    public override getViewMatrix(faceIndex?: number): Nullable<Matrix> {\r\n        const lightDirection = TmpVectors.Vector3[0];\r\n\r\n        let lightPosition = this.position;\r\n        if (this.computeTransformedInformation()) {\r\n            lightPosition = this.transformedPosition;\r\n        }\r\n\r\n        Vector3.NormalizeToRef(this.getShadowDirection(faceIndex), lightDirection);\r\n        if (Math.abs(Vector3.Dot(lightDirection, Vector3.Up())) === 1.0) {\r\n            lightDirection.z = 0.0000000000001; // Required to avoid perfectly perpendicular light\r\n        }\r\n\r\n        const lightTarget = TmpVectors.Vector3[1];\r\n        lightPosition.addToRef(lightDirection, lightTarget);\r\n\r\n        Matrix.LookAtLHToRef(lightPosition, lightTarget, Vector3.Up(), this._viewMatrix);\r\n\r\n        return this._viewMatrix;\r\n    }\r\n\r\n    /**\r\n     * Returns the projection matrix.\r\n     * Note that viewMatrix and renderList are optional and are only used by lights that calculate the projection matrix from a list of meshes (e.g. directional lights with automatic extents calculation).\r\n     * @param viewMatrix The view transform matrix of the light (optional).\r\n     * @param renderList The list of meshes to take into account when calculating the projection matrix (optional).\r\n     * @returns The projection matrix. Can be null, if a projection matrix cannot be defined for the type of light considered (as for a hemispherical light, for example).\r\n     */\r\n    public override getProjectionMatrix(viewMatrix?: Matrix, renderList?: Array<AbstractMesh>): Nullable<Matrix> {\r\n        this.setShadowProjectionMatrix(this._projectionMatrix, viewMatrix ?? this._viewMatrix, renderList ?? []);\r\n\r\n        return this._projectionMatrix;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Light } from \"./light\";\r\nimport { ShadowLight } from \"./shadowLight\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Node } from \"../node\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * A directional light is defined by a direction (what a surprise!).\r\n * The light is emitted from everywhere in the specified direction, and has an infinite range.\r\n * An example of a directional light is when a distance planet is lit by the apparently parallel lines of light from its sun. Light in a downward direction will light the top of an object.\r\n * Documentation: https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n */\r\nexport class DirectionalLight extends ShadowLight {\r\n    private _shadowFrustumSize = 0;\r\n    /**\r\n     * Fix frustum size for the shadow generation. This is disabled if the value is 0.\r\n     */\r\n    @serialize()\r\n    public get shadowFrustumSize(): number {\r\n        return this._shadowFrustumSize;\r\n    }\r\n    /**\r\n     * Specifies a fix frustum size for the shadow generation.\r\n     */\r\n    public set shadowFrustumSize(value: number) {\r\n        this._shadowFrustumSize = value;\r\n        this.forceProjectionMatrixCompute();\r\n    }\r\n\r\n    private _shadowOrthoScale = 0.1;\r\n    /**\r\n     * Gets the shadow projection scale against the optimal computed one.\r\n     * 0.1 by default which means that the projection window is increase by 10% from the optimal size.\r\n     * This does not impact in fixed frustum size (shadowFrustumSize being set)\r\n     */\r\n    @serialize()\r\n    public get shadowOrthoScale(): number {\r\n        return this._shadowOrthoScale;\r\n    }\r\n    /**\r\n     * Sets the shadow projection scale against the optimal computed one.\r\n     * 0.1 by default which means that the projection window is increase by 10% from the optimal size.\r\n     * This does not impact in fixed frustum size (shadowFrustumSize being set)\r\n     */\r\n    public set shadowOrthoScale(value: number) {\r\n        this._shadowOrthoScale = value;\r\n        this.forceProjectionMatrixCompute();\r\n    }\r\n\r\n    /**\r\n     * Automatically compute the projection matrix to best fit (including all the casters)\r\n     * on each frame.\r\n     */\r\n    @serialize()\r\n    public autoUpdateExtends = true;\r\n\r\n    /**\r\n     * Automatically compute the shadowMinZ and shadowMaxZ for the projection matrix to best fit (including all the casters)\r\n     * on each frame. autoUpdateExtends must be set to true for this to work\r\n     */\r\n    @serialize()\r\n    public autoCalcShadowZBounds = false;\r\n\r\n    // Cache\r\n    @serialize(\"orthoLeft\")\r\n    private _orthoLeft = Number.MAX_VALUE;\r\n    @serialize(\"orthoRight\")\r\n    private _orthoRight = Number.MIN_VALUE;\r\n    @serialize(\"orthoTop\")\r\n    private _orthoTop = Number.MIN_VALUE;\r\n    @serialize(\"orthoBottom\")\r\n    private _orthoBottom = Number.MAX_VALUE;\r\n\r\n    /**\r\n     * Gets or sets the orthoLeft property used to build the light frustum\r\n     */\r\n    public get orthoLeft(): number {\r\n        return this._orthoLeft;\r\n    }\r\n\r\n    public set orthoLeft(left: number) {\r\n        this._orthoLeft = left;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the orthoRight property used to build the light frustum\r\n     */\r\n    public get orthoRight(): number {\r\n        return this._orthoRight;\r\n    }\r\n\r\n    public set orthoRight(right: number) {\r\n        this._orthoRight = right;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the orthoTop property used to build the light frustum\r\n     */\r\n    public get orthoTop(): number {\r\n        return this._orthoTop;\r\n    }\r\n\r\n    public set orthoTop(top: number) {\r\n        this._orthoTop = top;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the orthoBottom property used to build the light frustum\r\n     */\r\n    public get orthoBottom(): number {\r\n        return this._orthoBottom;\r\n    }\r\n\r\n    public set orthoBottom(bottom: number) {\r\n        this._orthoBottom = bottom;\r\n    }\r\n\r\n    /**\r\n     * Creates a DirectionalLight object in the scene, oriented towards the passed direction (Vector3).\r\n     * The directional light is emitted from everywhere in the given direction.\r\n     * It can cast shadows.\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     * @param name The friendly name of the light\r\n     * @param direction The direction of the light\r\n     * @param scene The scene the light belongs to\r\n     * @param dontAddToScene True to not add the light to the scene\r\n     */\r\n    constructor(name: string, direction: Vector3, scene?: Scene, dontAddToScene?: boolean) {\r\n        super(name, scene, dontAddToScene);\r\n        this.position = direction.scale(-1.0);\r\n        this.direction = direction;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"DirectionalLight\".\r\n     * @returns The class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DirectionalLight\";\r\n    }\r\n\r\n    /**\r\n     * Returns the integer 1.\r\n     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public override getTypeID(): number {\r\n        return Light.LIGHTTYPEID_DIRECTIONALLIGHT;\r\n    }\r\n\r\n    /**\r\n     * Sets the passed matrix \"matrix\" as projection matrix for the shadows cast by the light according to the passed view matrix.\r\n     * Returns the DirectionalLight Shadow projection matrix.\r\n     * @param matrix\r\n     * @param viewMatrix\r\n     * @param renderList\r\n     */\r\n    protected _setDefaultShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void {\r\n        if (this.shadowFrustumSize > 0) {\r\n            this._setDefaultFixedFrustumShadowProjectionMatrix(matrix);\r\n        } else {\r\n            this._setDefaultAutoExtendShadowProjectionMatrix(matrix, viewMatrix, renderList);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the passed matrix \"matrix\" as fixed frustum projection matrix for the shadows cast by the light according to the passed view matrix.\r\n     * Returns the DirectionalLight Shadow projection matrix.\r\n     * @param matrix\r\n     */\r\n    protected _setDefaultFixedFrustumShadowProjectionMatrix(matrix: Matrix): void {\r\n        const activeCamera = this.getScene().activeCamera;\r\n\r\n        Matrix.OrthoLHToRef(\r\n            this.shadowFrustumSize,\r\n            this.shadowFrustumSize,\r\n            this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera ? activeCamera.minZ : Constants.ShadowMinZ,\r\n            this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera ? activeCamera.maxZ : Constants.ShadowMaxZ,\r\n            matrix,\r\n            this.getScene().getEngine().isNDCHalfZRange\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Sets the passed matrix \"matrix\" as auto extend projection matrix for the shadows cast by the light according to the passed view matrix.\r\n     * Returns the DirectionalLight Shadow projection matrix.\r\n     * @param matrix\r\n     * @param viewMatrix\r\n     * @param renderList\r\n     */\r\n    protected _setDefaultAutoExtendShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void {\r\n        const activeCamera = this.getScene().activeCamera;\r\n\r\n        // Check extends\r\n        if (this.autoUpdateExtends || this._orthoLeft === Number.MAX_VALUE) {\r\n            const tempVector3 = Vector3.Zero();\r\n\r\n            this._orthoLeft = Number.MAX_VALUE;\r\n            this._orthoRight = -Number.MAX_VALUE;\r\n            this._orthoTop = -Number.MAX_VALUE;\r\n            this._orthoBottom = Number.MAX_VALUE;\r\n\r\n            let shadowMinZ = Number.MAX_VALUE;\r\n            let shadowMaxZ = -Number.MAX_VALUE;\r\n\r\n            for (let meshIndex = 0; meshIndex < renderList.length; meshIndex++) {\r\n                const mesh = renderList[meshIndex];\r\n\r\n                if (!mesh) {\r\n                    continue;\r\n                }\r\n\r\n                const boundingInfo = mesh.getBoundingInfo();\r\n                const boundingBox = boundingInfo.boundingBox;\r\n\r\n                for (let index = 0; index < boundingBox.vectorsWorld.length; index++) {\r\n                    Vector3.TransformCoordinatesToRef(boundingBox.vectorsWorld[index], viewMatrix, tempVector3);\r\n\r\n                    if (tempVector3.x < this._orthoLeft) {\r\n                        this._orthoLeft = tempVector3.x;\r\n                    }\r\n                    if (tempVector3.y < this._orthoBottom) {\r\n                        this._orthoBottom = tempVector3.y;\r\n                    }\r\n\r\n                    if (tempVector3.x > this._orthoRight) {\r\n                        this._orthoRight = tempVector3.x;\r\n                    }\r\n                    if (tempVector3.y > this._orthoTop) {\r\n                        this._orthoTop = tempVector3.y;\r\n                    }\r\n                    if (this.autoCalcShadowZBounds) {\r\n                        if (tempVector3.z < shadowMinZ) {\r\n                            shadowMinZ = tempVector3.z;\r\n                        }\r\n                        if (tempVector3.z > shadowMaxZ) {\r\n                            shadowMaxZ = tempVector3.z;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.autoCalcShadowZBounds) {\r\n                this._shadowMinZ = shadowMinZ;\r\n                this._shadowMaxZ = shadowMaxZ;\r\n            }\r\n        }\r\n\r\n        const xOffset = this._orthoRight - this._orthoLeft;\r\n        const yOffset = this._orthoTop - this._orthoBottom;\r\n\r\n        const minZ = this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera?.minZ || Constants.ShadowMinZ;\r\n        const maxZ = this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera?.maxZ || Constants.ShadowMaxZ;\r\n\r\n        const useReverseDepthBuffer = this.getScene().getEngine().useReverseDepthBuffer;\r\n\r\n        Matrix.OrthoOffCenterLHToRef(\r\n            this._orthoLeft - xOffset * this.shadowOrthoScale,\r\n            this._orthoRight + xOffset * this.shadowOrthoScale,\r\n            this._orthoBottom - yOffset * this.shadowOrthoScale,\r\n            this._orthoTop + yOffset * this.shadowOrthoScale,\r\n            useReverseDepthBuffer ? maxZ : minZ,\r\n            useReverseDepthBuffer ? minZ : maxZ,\r\n            matrix,\r\n            this.getScene().getEngine().isNDCHalfZRange\r\n        );\r\n    }\r\n\r\n    protected _buildUniformLayout(): void {\r\n        this._uniformBuffer.addUniform(\"vLightData\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\r\n        this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\r\n        this._uniformBuffer.addUniform(\"depthValues\", 2);\r\n        this._uniformBuffer.create();\r\n    }\r\n\r\n    /**\r\n     * Sets the passed Effect object with the DirectionalLight transformed position (or position if not parented) and the passed name.\r\n     * @param effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The directional light\r\n     */\r\n    public transferToEffect(effect: Effect, lightIndex: string): DirectionalLight {\r\n        if (this.computeTransformedInformation()) {\r\n            this._uniformBuffer.updateFloat4(\"vLightData\", this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z, 1, lightIndex);\r\n            return this;\r\n        }\r\n        this._uniformBuffer.updateFloat4(\"vLightData\", this.direction.x, this.direction.y, this.direction.z, 1, lightIndex);\r\n        return this;\r\n    }\r\n\r\n    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light {\r\n        if (this.computeTransformedInformation()) {\r\n            effect.setFloat3(lightDataUniformName, this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z);\r\n            return this;\r\n        }\r\n\r\n        effect.setFloat3(lightDataUniformName, this.direction.x, this.direction.y, this.direction.z);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the minZ used for shadow according to both the scene and the light.\r\n     *\r\n     * Values are fixed on directional lights as it relies on an ortho projection hence the need to convert being\r\n     * -1 and 1 to 0 and 1 doing (depth + min) / (min + max) -> (depth + 1) / (1 + 1) -> (depth * 0.5) + 0.5.\r\n     * (when not using reverse depth buffer / NDC half Z range)\r\n     * @param _activeCamera The camera we are returning the min for (not used)\r\n     * @returns the depth min z\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public override getDepthMinZ(_activeCamera: Nullable<Camera>): number {\r\n        const engine = this._scene.getEngine();\r\n        return !engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\r\n    }\r\n\r\n    /**\r\n     * Gets the maxZ used for shadow according to both the scene and the light.\r\n     *\r\n     * Values are fixed on directional lights as it relies on an ortho projection hence the need to convert being\r\n     * -1 and 1 to 0 and 1 doing (depth + min) / (min + max) -> (depth + 1) / (1 + 1) -> (depth * 0.5) + 0.5.\r\n     * (when not using reverse depth buffer / NDC half Z range)\r\n     * @param _activeCamera The camera we are returning the max for\r\n     * @returns the depth max z\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public override getDepthMaxZ(_activeCamera: Nullable<Camera>): number {\r\n        const engine = this._scene.getEngine();\r\n        return engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\r\n    }\r\n\r\n    /**\r\n     * Prepares the list of defines specific to the light type.\r\n     * @param defines the list of defines\r\n     * @param lightIndex defines the index of the light for the effect\r\n     */\r\n    public prepareLightSpecificDefines(defines: any, lightIndex: number): void {\r\n        defines[\"DIRLIGHT\" + lightIndex] = true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for directionalLight.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDirectionalLight(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"Light_Type_1\", (name, scene) => {\r\n        return () => new DirectionalLight(name, Vector3.Zero(), scene);\r\n    });\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.DirectionalLight\", DirectionalLight);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type AbstractEngine, type Engine, type InternalTexture, type Nullable, type RenderTargetWrapper, type Scene, type ShadowGenerator, type WebGPUEngine } from \"core/index\";\r\nimport { AbortError } from \"core/Misc/error\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Matrix, Vector3, TmpVectors } from \"core/Maths/math.vector.pure\";\r\nimport { DirectionalLight } from \"core/Lights/directionalLight.pure\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { ComputeShader } from \"core/Compute/computeShader.pure\";\r\nimport { CopyTextureToTexture } from \"core/Misc/copyTextureToTexture\";\r\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { StorageBuffer } from \"core/Buffers/storageBuffer\";\r\nimport { BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\n\r\nconst TmpVec3 = /*#__PURE__*/ new Vector3();\r\n\r\n/**\r\n * Class used to create a lighting volume from a directional light's shadow generator.\r\n */\r\nexport class LightingVolume {\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _scene: Scene;\r\n    private readonly _mesh: Mesh;\r\n    private readonly _copyTexture?: CopyTextureToTexture;\r\n    private readonly _uBuffer?: UniformBuffer;\r\n    private readonly _buildFullVolume = true;\r\n    private _name: string;\r\n    private _cs?: ComputeShader;\r\n    private _cs2?: ComputeShader;\r\n    private _light?: DirectionalLight;\r\n    private _fallbackTexture?: BaseTexture;\r\n    private _storageBuffer?: StorageBuffer;\r\n    private _depthCopy?: RenderTargetWrapper;\r\n    private _readPixelPromise: Nullable<Promise<ArrayBufferView>> = null;\r\n    private _readPixelAbortController: Nullable<AbortController> = null;\r\n    private _numFrames = 0;\r\n    private _firstUpdate = true;\r\n    private _currentLightDirection = new Vector3();\r\n    private _positions: Float32Array;\r\n    private _indices: number[];\r\n    private _needFullUpdateUBO = true;\r\n    private _currentShadowDepthTexture: Nullable<InternalTexture>;\r\n\r\n    private _shadowGenerator?: ShadowGenerator;\r\n    /**\r\n     * The shadow generator used to create the lighting volume.\r\n     */\r\n    public get shadowGenerator() {\r\n        return this._shadowGenerator!;\r\n    }\r\n\r\n    public set shadowGenerator(sg: ShadowGenerator) {\r\n        const light = sg.getLight();\r\n\r\n        if (!(light instanceof DirectionalLight)) {\r\n            throw new Error(`LightingVolumeMesh ${this._name}: light must be a directional light`);\r\n        }\r\n\r\n        this._shadowGenerator = sg;\r\n        this._light = light;\r\n\r\n        this._updateGeometry();\r\n\r\n        if (!this._engine.isWebGPU) {\r\n            this._createFallbackTextures();\r\n        }\r\n\r\n        this._setComputeShaderInputs();\r\n    }\r\n\r\n    private _tesselation = 0;\r\n    /**\r\n     * The tesselation level of the lighting volume.\r\n     */\r\n    public get tesselation() {\r\n        return this._tesselation;\r\n    }\r\n\r\n    public set tesselation(n: number) {\r\n        this._tesselation = n;\r\n        this._createGeometry();\r\n    }\r\n\r\n    /**\r\n     * The mesh used as a support for the lighting volume.\r\n     * Note that this mesh is not automatically added to the scene's mesh array.\r\n     * If you want to render it, you need to add it manually.\r\n     */\r\n    public get mesh() {\r\n        return this._mesh;\r\n    }\r\n\r\n    private _frequency = 1;\r\n\r\n    /**\r\n     * The frequency (in number of times you call updateMesh) at which the lighting volume is updated.\r\n     */\r\n    public get frequency() {\r\n        return this._frequency;\r\n    }\r\n\r\n    public set frequency(value: number) {\r\n        this._frequency = value;\r\n        this._firstUpdate = true;\r\n    }\r\n\r\n    /**\r\n     * The name of the lighting volume.\r\n     */\r\n    public get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(name: string) {\r\n        this._name = name;\r\n        if (this._mesh) {\r\n            this._mesh.name = name;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates whether this is the first update of the lighting volume.\r\n     * If true, the volume has not yet been updated for the first time.\r\n     */\r\n    public get firstUpdate() {\r\n        return this._firstUpdate;\r\n    }\r\n\r\n    /** @internal */\r\n    public _setComputeShaderFastMode(enabled: boolean) {\r\n        if (this._cs) {\r\n            this._cs.fastMode = enabled;\r\n            this._cs.triggerContextRebuild = enabled;\r\n        }\r\n        if (this._cs2) {\r\n            this._cs2.fastMode = enabled;\r\n            this._cs2.triggerContextRebuild = enabled;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new LightingVolume.\r\n     * @param name The name of the lighting volume.\r\n     * @param scene The scene the lighting volume belongs to.\r\n     * @param shadowGenerator The shadow generator used to create the lighting volume. This is optional in the constructor, but must be set before calling updateMesh.\r\n     * @param tesselation The tesselation level of the lighting volume (default: 64).\r\n     */\r\n    constructor(name: string, scene: Scene, shadowGenerator?: ShadowGenerator, tesselation = 64) {\r\n        const light = shadowGenerator ? shadowGenerator.getLight() : undefined;\r\n\r\n        if (light && !(light instanceof DirectionalLight)) {\r\n            throw new Error(`LightingVolumeMesh ${name}: light must be a directional light`);\r\n        }\r\n\r\n        this._name = name;\r\n        this._shadowGenerator = shadowGenerator;\r\n        this._light = light as DirectionalLight;\r\n        this._indices = [];\r\n\r\n        this._engine = scene.getEngine();\r\n        this._scene = scene;\r\n\r\n        this._mesh = new Mesh(name, this._scene);\r\n        scene.meshes.splice(scene.meshes.indexOf(this._mesh), 1);\r\n\r\n        if (this._engine.isWebGPU) {\r\n            this._uBuffer = new UniformBuffer(this._engine);\r\n\r\n            this._uBuffer.addUniform(\"invViewProjMatrix\", 16);\r\n            this._uBuffer.addUniform(\"invViewMatrix\", 16);\r\n            this._uBuffer.addUniform(\"startVertexIndex\", 1);\r\n            this._uBuffer.addUniform(\"step\", 1);\r\n            this._uBuffer.addUniform(\"tesselation\", 1);\r\n            this._uBuffer.addUniform(\"orthoMin\", 3);\r\n            this._uBuffer.addUniform(\"orthoMax\", 3);\r\n            this._uBuffer.update();\r\n\r\n            this._createComputeShader();\r\n        } else {\r\n            this._copyTexture = new CopyTextureToTexture(this._engine, false, true);\r\n            this._createFallbackTextures();\r\n        }\r\n\r\n        this._tesselation = tesselation;\r\n        this._createGeometry();\r\n    }\r\n\r\n    /**\r\n     * Checks if the lighting volume is ready to be updated.\r\n     * @returns True if the volume is ready to be updated.\r\n     */\r\n    public isReady() {\r\n        let isReady = this._mesh.isReady(true);\r\n        if (this._cs) {\r\n            isReady = this._cs.isReady() && isReady;\r\n        }\r\n        if (this._cs2) {\r\n            isReady = this._cs2.isReady() && isReady;\r\n        }\r\n        return isReady;\r\n    }\r\n\r\n    /**\r\n     * Updates the lighting volume mesh.\r\n     * @param forceUpdate If true, forces the update even if the frequency condition is not met.\r\n     */\r\n    public update(forceUpdate = false) {\r\n        if (this._tesselation === 0 || !this._shadowGenerator) {\r\n            return;\r\n        }\r\n\r\n        if (!forceUpdate && !this._firstUpdate && (this.frequency === 0 || ++this._numFrames < this.frequency)) {\r\n            return;\r\n        }\r\n\r\n        this._numFrames = 0;\r\n\r\n        if (this._engine.isWebGPU) {\r\n            this._uBuffer!.updateMatrix(\"invViewProjMatrix\", this._shadowGenerator.getTransformMatrix().invertToRef(TmpVectors.Matrix[0]));\r\n\r\n            if (this._engine._enableGPUDebugMarkers) {\r\n                this._engine._debugPushGroup?.(`Update lighting volume (${this._name})`);\r\n            }\r\n\r\n            const depthTexture = this._shadowGenerator.getShadowMap()?.depthStencilTexture;\r\n            if (depthTexture && depthTexture !== this._currentShadowDepthTexture) {\r\n                this._currentShadowDepthTexture = depthTexture!;\r\n                this._cs!.triggerContextRebuild = this._cs!.fastMode;\r\n                this._cs2!.triggerContextRebuild = this._cs2!.fastMode;\r\n                this._cs!.setInternalTexture(\"shadowMap\", depthTexture);\r\n                this._cs2!.setInternalTexture(\"shadowMap\", depthTexture);\r\n            }\r\n\r\n            if (this._needUpdateGeometry()) {\r\n                this._fullUpdateUBO(true);\r\n\r\n                const dispatchSize = Math.ceil((this._tesselation + 1) / 32);\r\n\r\n                this._engine._debugPushGroup?.(`Update vertices of other planes`);\r\n                this._cs2!.dispatch(dispatchSize, 1, 1);\r\n                this._engine._debugPopGroup?.();\r\n            } else {\r\n                this._fullUpdateUBO();\r\n            }\r\n\r\n            const dispatchSize = Math.ceil((this._tesselation + 1) / 8);\r\n\r\n            this._engine._debugPushGroup?.(`Update vertices of far plane`);\r\n            this._cs!.dispatch(dispatchSize, dispatchSize, 1);\r\n            this._engine._debugPopGroup?.();\r\n\r\n            if (this._engine._enableGPUDebugMarkers) {\r\n                this._engine._debugPopGroup?.();\r\n            }\r\n\r\n            this._firstUpdate = false;\r\n        } else {\r\n            try {\r\n                void this._fallbackReadPixelAsync();\r\n            } catch {\r\n                this._readPixelPromise = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the lighting volume and associated resources.\r\n     */\r\n    public dispose() {\r\n        this._readPixelAbortController?.abort(new AbortError(\"LightingVolume is disposed\"));\r\n        this._readPixelAbortController = null;\r\n        this._mesh.dispose();\r\n        if (this._fallbackTexture) {\r\n            this._fallbackTexture._texture = null;\r\n        }\r\n        this._fallbackTexture?.dispose();\r\n        this._copyTexture?.dispose();\r\n        this._storageBuffer?.dispose();\r\n        this._uBuffer?.dispose();\r\n        this._depthCopy?.dispose();\r\n    }\r\n\r\n    private _needUpdateGeometry() {\r\n        if (this._cs?.triggerContextRebuild || (this._light && !this._currentLightDirection.equals(this._light.direction))) {\r\n            this._currentLightDirection.copyFrom(this._light!.direction);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    private _createComputeShader() {\r\n        this._cs = new ComputeShader(\"updateFarPlaneVertices\", this._engine, \"lightingVolume\", {\r\n            bindingsMapping: {\r\n                shadowMap: { group: 0, binding: 0 },\r\n                params: { group: 0, binding: 1 },\r\n                positions: { group: 0, binding: 2 },\r\n            },\r\n            defines: !this._buildFullVolume ? [\"#define KEEP_EDGES\", \"#define MOVE_FAR_DEPTH_TO_NEAR\"] : undefined,\r\n            entryPoint: \"updateFarPlaneVertices\",\r\n        });\r\n\r\n        this._cs2 = new ComputeShader(\"updatePlaneVertices\", this._engine, \"lightingVolume\", {\r\n            bindingsMapping: {\r\n                shadowMap: { group: 0, binding: 0 },\r\n                params: { group: 0, binding: 1 },\r\n                positions: { group: 0, binding: 2 },\r\n            },\r\n            entryPoint: \"updatePlaneVertices\",\r\n        });\r\n\r\n        this._setComputeShaderInputs();\r\n    }\r\n\r\n    private _setComputeShaderInputs() {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        if (this._shadowGenerator) {\r\n            const depthTexture = this._shadowGenerator.getShadowMap()?.depthStencilTexture;\r\n            this._currentShadowDepthTexture = depthTexture || null;\r\n            if (depthTexture) {\r\n                this._cs?.setInternalTexture(\"shadowMap\", depthTexture);\r\n                this._cs2?.setInternalTexture(\"shadowMap\", depthTexture);\r\n            }\r\n        }\r\n\r\n        if (this._uBuffer) {\r\n            this._cs?.setUniformBuffer(\"params\", this._uBuffer);\r\n            this._cs2?.setUniformBuffer(\"params\", this._uBuffer);\r\n        }\r\n        if (this._storageBuffer) {\r\n            this._cs?.setStorageBuffer(\"positions\", this._storageBuffer);\r\n            this._cs2?.setStorageBuffer(\"positions\", this._storageBuffer);\r\n        }\r\n    }\r\n\r\n    private _createFallbackTextures() {\r\n        if (!this._shadowGenerator) {\r\n            return;\r\n        }\r\n\r\n        this._readPixelAbortController?.abort(new AbortError(\"Fallback textures are being (re)created\"));\r\n        this._readPixelAbortController = new AbortController();\r\n\r\n        const mapSize = this._shadowGenerator.mapSize;\r\n\r\n        this._depthCopy?.dispose();\r\n        this._depthCopy = this._engine.createRenderTargetTexture(\r\n            { width: mapSize, height: mapSize },\r\n            {\r\n                type: Constants.TEXTURETYPE_FLOAT,\r\n                format: Constants.TEXTUREFORMAT_RED,\r\n                samples: 1,\r\n                label: `${this._name} - fallback internal texture`,\r\n                generateDepthBuffer: false,\r\n            }\r\n        );\r\n\r\n        this._fallbackTexture?.dispose();\r\n        this._fallbackTexture = new BaseTexture(this._scene, this._depthCopy.texture);\r\n        this._fallbackTexture.name = `${this._name} - fallback texture`;\r\n    }\r\n\r\n    private async _fallbackReadPixelAsync() {\r\n        if (this._readPixelPromise || !this._fallbackTexture || !this._copyTexture) {\r\n            return;\r\n        }\r\n\r\n        const abortController = this._readPixelAbortController;\r\n\r\n        abortController?.signal.throwIfAborted();\r\n\r\n        const engine = this._engine as Engine;\r\n\r\n        const shadowGenerator = this._shadowGenerator;\r\n        const shadowMapDepthTexture = shadowGenerator?.getShadowMap()?.depthStencilTexture;\r\n\r\n        if (!shadowMapDepthTexture) {\r\n            return;\r\n        }\r\n\r\n        // Copies the shadow map of the shadow generator into _depthCopy\r\n        // That's because we can't read from a depth attachment texture in WebGL. We must first copy it to a regular texture.\r\n        engine.updateTextureSamplingMode(Constants.TEXTURE_NEAREST_SAMPLINGMODE, shadowMapDepthTexture);\r\n        engine.updateTextureComparisonFunction(shadowMapDepthTexture, 0);\r\n\r\n        this._copyTexture.copy(shadowMapDepthTexture, this._depthCopy);\r\n\r\n        engine.updateTextureComparisonFunction(shadowMapDepthTexture, Constants.LESS);\r\n\r\n        // Gets the texture from GPU to CPU\r\n        this._readPixelPromise = this._fallbackTexture.readPixels(0, 0, undefined, true, false);\r\n        if (!this._readPixelPromise) {\r\n            return;\r\n        }\r\n\r\n        const buffer = await this._readPixelPromise;\r\n\r\n        abortController?.signal.throwIfAborted();\r\n\r\n        const depthValues = buffer as Float32Array;\r\n        const positions = this._mesh.getVerticesData(\"position\");\r\n        const numTesselation = this._tesselation;\r\n        const startPos = this._buildFullVolume ? (numTesselation + 1) * 4 * 3 : 4 * 3;\r\n        const mapSize = shadowGenerator.mapSize;\r\n        const step = (mapSize - 1) / numTesselation;\r\n\r\n        if (!positions) {\r\n            this._readPixelPromise = null;\r\n            return;\r\n        }\r\n\r\n        const halfTesselation = numTesselation / 2;\r\n\r\n        const invViewProjMatrix = shadowGenerator.getTransformMatrix().clone();\r\n        invViewProjMatrix.invertToRef(invViewProjMatrix);\r\n\r\n        const factor = 4;\r\n\r\n        if (this._needUpdateGeometry()) {\r\n            this._updateGeometry();\r\n        }\r\n\r\n        let posIndex = startPos;\r\n        let stepY = 0;\r\n        for (let y = 0; y < numTesselation + 1; ++y) {\r\n            for (let x = 0; x < numTesselation + 1; ++x) {\r\n                let depth = depthValues[Math.floor(mapSize * Math.floor(stepY) + x * step) * factor];\r\n                if (!this._buildFullVolume) {\r\n                    if (y === 0 || x === 0 || y === numTesselation || x === numTesselation) {\r\n                        posIndex += 3;\r\n                        continue;\r\n                    }\r\n                    if (depth === 1) {\r\n                        depth = 0;\r\n                    }\r\n                }\r\n\r\n                TmpVec3.set((x - halfTesselation) / halfTesselation, (y - halfTesselation) / halfTesselation, -1 + 2 * depth);\r\n\r\n                Vector3.TransformCoordinatesToRef(TmpVec3, invViewProjMatrix, TmpVec3);\r\n\r\n                positions[posIndex] = TmpVec3.x;\r\n                positions[posIndex + 1] = TmpVec3.y;\r\n                positions[posIndex + 2] = TmpVec3.z;\r\n                posIndex += 3;\r\n            }\r\n            stepY += step;\r\n        }\r\n\r\n        this._mesh.setVerticesData(\"position\", positions);\r\n\r\n        this._readPixelPromise = null;\r\n        this._firstUpdate = false;\r\n    }\r\n\r\n    private _fullUpdateUBO(force = false) {\r\n        const light = this._light;\r\n\r\n        if ((!force && !this._needFullUpdateUBO) || !light || !this._shadowGenerator) {\r\n            this._uBuffer!.update();\r\n            return;\r\n        }\r\n\r\n        this._needFullUpdateUBO = false;\r\n\r\n        const numTesselation = this._tesselation;\r\n        const min = TmpVectors.Vector3[0].set(light.orthoLeft, light.orthoBottom, light.shadowMinZ ?? Constants.ShadowMinZ);\r\n        const max = TmpVectors.Vector3[1].set(light.orthoRight, light.orthoTop, light.shadowMaxZ ?? Constants.ShadowMaxZ);\r\n\r\n        const invViewMatrix = this._shadowGenerator.viewMatrix.invertToRef(TmpVectors.Matrix[1]);\r\n\r\n        this._uBuffer!.updateUInt(\"startVertexIndex\", this._buildFullVolume ? (numTesselation + 1) * 4 * 3 : 4 * 3);\r\n        this._uBuffer!.updateFloat(\"step\", ((this._shadowGenerator?.mapSize ?? 128) - 1) / numTesselation);\r\n        this._uBuffer!.updateUInt(\"tesselation\", numTesselation);\r\n        this._uBuffer!.updateVector3(\"orthoMin\", min);\r\n        this._uBuffer!.updateVector3(\"orthoMax\", max);\r\n        this._uBuffer!.updateMatrix(\"invViewMatrix\", invViewMatrix);\r\n        this._uBuffer!.update();\r\n    }\r\n\r\n    private _createGeometry() {\r\n        const light = this._light;\r\n\r\n        if (!light) {\r\n            return;\r\n        }\r\n\r\n        this._tesselation = Math.max(Math.ceil(this._tesselation) & ~1, 2);\r\n\r\n        const numTesselation = this._tesselation;\r\n        const vertexNumber = (numTesselation + 1) * (numTesselation + 1) + (this._buildFullVolume ? (numTesselation + 1) * 4 : 4);\r\n\r\n        this._positions = new Float32Array(vertexNumber * 3);\r\n        this._indices.length = 0;\r\n\r\n        this._createIndices(light);\r\n\r\n        this._mesh.setIndices(this._indices, vertexNumber);\r\n\r\n        if (this._engine.isWebGPU) {\r\n            const webGPUEngine = this._engine as WebGPUEngine;\r\n\r\n            this._storageBuffer?.dispose();\r\n            this._storageBuffer = new StorageBuffer(webGPUEngine, vertexNumber * 3 * 4, Constants.BUFFER_CREATIONFLAG_VERTEX | Constants.BUFFER_CREATIONFLAG_READWRITE);\r\n\r\n            this._mesh.setVerticesBuffer(new VertexBuffer(webGPUEngine, this._storageBuffer.getBuffer(), \"position\", { takeBufferOwnership: false }), true, vertexNumber);\r\n\r\n            this._setComputeShaderInputs();\r\n\r\n            this._cs!.triggerContextRebuild = true;\r\n            this._cs2!.triggerContextRebuild = true;\r\n\r\n            this._needFullUpdateUBO = true;\r\n        }\r\n\r\n        this._updateGeometry();\r\n    }\r\n\r\n    private _updateGeometry() {\r\n        const light = this._light;\r\n\r\n        if (!light || !this._shadowGenerator) {\r\n            return;\r\n        }\r\n\r\n        if (this._indices.length === 0) {\r\n            this._createGeometry();\r\n            return;\r\n        }\r\n\r\n        if (this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        const numTesselation = this._tesselation;\r\n\r\n        const min = TmpVectors.Vector3[0].set(light.orthoLeft, light.orthoBottom, light.shadowMinZ ?? Constants.ShadowMinZ);\r\n        const max = TmpVectors.Vector3[1].set(light.orthoRight, light.orthoTop, light.shadowMaxZ ?? Constants.ShadowMaxZ);\r\n\r\n        const invViewMatrix = this._shadowGenerator.viewMatrix.invertToRef(TmpVectors.Matrix[1]);\r\n\r\n        const stepX = (max.x - min.x) / numTesselation;\r\n        const stepY = (max.y - min.y) / numTesselation;\r\n\r\n        let vIndex = 0;\r\n\r\n        if (this._buildFullVolume) {\r\n            // Right faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                TmpVec3.set(max.x, min.y + i * stepY, min.z);\r\n                Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n                this._positions[vIndex++] = TmpVec3.x;\r\n                this._positions[vIndex++] = TmpVec3.y;\r\n                this._positions[vIndex++] = TmpVec3.z;\r\n            }\r\n\r\n            // Left faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                TmpVec3.set(min.x, min.y + i * stepY, min.z);\r\n                Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n                this._positions[vIndex++] = TmpVec3.x;\r\n                this._positions[vIndex++] = TmpVec3.y;\r\n                this._positions[vIndex++] = TmpVec3.z;\r\n            }\r\n\r\n            // Bottom faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                TmpVec3.set(min.x + i * stepX, min.y, min.z);\r\n                Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n                this._positions[vIndex++] = TmpVec3.x;\r\n                this._positions[vIndex++] = TmpVec3.y;\r\n                this._positions[vIndex++] = TmpVec3.z;\r\n            }\r\n\r\n            // Top faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                TmpVec3.set(min.x + i * stepX, max.y, min.z);\r\n                Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n                this._positions[vIndex++] = TmpVec3.x;\r\n                this._positions[vIndex++] = TmpVec3.y;\r\n                this._positions[vIndex++] = TmpVec3.z;\r\n            }\r\n        } else {\r\n            // Closes the volume with two near triangles\r\n            TmpVec3.set(max.x, min.y, min.z);\r\n            Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n            this._positions[vIndex++] = TmpVec3.x;\r\n            this._positions[vIndex++] = TmpVec3.y;\r\n            this._positions[vIndex++] = TmpVec3.z;\r\n\r\n            TmpVec3.set(max.x, max.y, min.z);\r\n            Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n            this._positions[vIndex++] = TmpVec3.x;\r\n            this._positions[vIndex++] = TmpVec3.y;\r\n            this._positions[vIndex++] = TmpVec3.z;\r\n\r\n            TmpVec3.set(min.x, min.y, min.z);\r\n            Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n            this._positions[vIndex++] = TmpVec3.x;\r\n            this._positions[vIndex++] = TmpVec3.y;\r\n            this._positions[vIndex++] = TmpVec3.z;\r\n\r\n            TmpVec3.set(min.x, max.y, min.z);\r\n            Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);\r\n            this._positions[vIndex++] = TmpVec3.x;\r\n            this._positions[vIndex++] = TmpVec3.y;\r\n            this._positions[vIndex] = TmpVec3.z;\r\n        }\r\n\r\n        this._mesh.setVerticesData(\"position\", this._positions);\r\n    }\r\n\r\n    private _createIndices(light: DirectionalLight) {\r\n        const invViewMatrix = Matrix.LookAtLH(light.position, light.position.add(light.direction), Vector3.UpReadOnly);\r\n        invViewMatrix.invertToRef(invViewMatrix);\r\n\r\n        const numTesselation = this._tesselation;\r\n\r\n        const startFarIndices = this._buildFullVolume ? (numTesselation + 1) * 4 : 4;\r\n\r\n        if (this._buildFullVolume) {\r\n            const rightFaceStartIndex = 0;\r\n\r\n            // Right faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                if (i < numTesselation) {\r\n                    this._indices.push(\r\n                        rightFaceStartIndex + i,\r\n                        startFarIndices + numTesselation + (i + 1) * (numTesselation + 1),\r\n                        startFarIndices + numTesselation + i * (numTesselation + 1)\r\n                    );\r\n                    this._indices.push(rightFaceStartIndex + i, rightFaceStartIndex + i + 1, startFarIndices + numTesselation + (i + 1) * (numTesselation + 1));\r\n                }\r\n            }\r\n\r\n            const leftFaceStartIndex = rightFaceStartIndex + numTesselation + 1;\r\n\r\n            // Left faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                if (i < numTesselation) {\r\n                    this._indices.push(leftFaceStartIndex + i, startFarIndices + 0 + i * (numTesselation + 1), startFarIndices + 0 + (i + 1) * (numTesselation + 1));\r\n                    this._indices.push(leftFaceStartIndex + i, startFarIndices + 0 + (i + 1) * (numTesselation + 1), leftFaceStartIndex + i + 1);\r\n                }\r\n            }\r\n\r\n            const bottomFaceStartIndex = leftFaceStartIndex + numTesselation + 1;\r\n\r\n            // Bottom faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                if (i < numTesselation) {\r\n                    this._indices.push(bottomFaceStartIndex + i, bottomFaceStartIndex + i + 1, startFarIndices + i + 0 * (numTesselation + 1));\r\n                    this._indices.push(bottomFaceStartIndex + i + 1, startFarIndices + i + 1 + 0 * (numTesselation + 1), startFarIndices + i + 0 * (numTesselation + 1));\r\n                }\r\n            }\r\n\r\n            const topFaceStartIndex = bottomFaceStartIndex + numTesselation + 1;\r\n\r\n            // Top faces of the frustum\r\n            for (let i = 0; i <= numTesselation; ++i) {\r\n                if (i < numTesselation) {\r\n                    this._indices.push(topFaceStartIndex + i, startFarIndices + i + numTesselation * (numTesselation + 1), topFaceStartIndex + i + 1);\r\n                    this._indices.push(\r\n                        topFaceStartIndex + i + 1,\r\n                        startFarIndices + i + numTesselation * (numTesselation + 1),\r\n                        startFarIndices + i + 1 + numTesselation * (numTesselation + 1)\r\n                    );\r\n                }\r\n            }\r\n\r\n            // Near faces of the frustum\r\n            for (let i = 0; i < numTesselation; ++i) {\r\n                this._indices.push(leftFaceStartIndex + i, leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i);\r\n                if (i < numTesselation - 1) {\r\n                    this._indices.push(leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i - 1, topFaceStartIndex + numTesselation - i);\r\n                }\r\n            }\r\n\r\n            for (let i = 0; i < numTesselation; ++i) {\r\n                this._indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i, rightFaceStartIndex + numTesselation - i - 1);\r\n                if (i < numTesselation - 1) {\r\n                    this._indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i - 1, bottomFaceStartIndex + i + 1);\r\n                }\r\n            }\r\n        } else {\r\n            this._indices.push(0, 2, 1);\r\n            this._indices.push(2, 3, 1);\r\n        }\r\n\r\n        // Tesselate the far plane\r\n        for (let iy = 0; iy <= numTesselation; ++iy) {\r\n            for (let ix = 0; ix <= numTesselation; ++ix) {\r\n                if (ix < numTesselation && iy < numTesselation) {\r\n                    this._indices.push(\r\n                        startFarIndices + ix + iy * (numTesselation + 1),\r\n                        startFarIndices + ix + 1 + iy * (numTesselation + 1),\r\n                        startFarIndices + ix + 1 + (iy + 1) * (numTesselation + 1)\r\n                    );\r\n                    this._indices.push(\r\n                        startFarIndices + ix + iy * (numTesselation + 1),\r\n                        startFarIndices + ix + 1 + (iy + 1) * (numTesselation + 1),\r\n                        startFarIndices + ix + (iy + 1) * (numTesselation + 1)\r\n                    );\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphObjectList, type FrameGraphShadowGeneratorTask } from \"core/index\";\r\nimport { LightingVolume } from \"core/Lights/lightingVolume.pure\";\r\nimport { DirectionalLight } from \"core/Lights/directionalLight.pure\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to create a lighting volume from a directional light's shadow generator.\r\n */\r\nexport class FrameGraphLightingVolumeTask extends FrameGraphTask {\r\n    /**\r\n     * The shadow generator used to create the lighting volume.\r\n     */\r\n    public shadowGenerator: FrameGraphShadowGeneratorTask;\r\n\r\n    /**\r\n     * The output object list containing the lighting volume mesh.\r\n     * You can get the mesh by doing  outputMeshLightingVolume.meshes[0]\r\n     */\r\n    public readonly outputMeshLightingVolume: FrameGraphObjectList;\r\n\r\n    /**\r\n     * The lighting volume created by this task.\r\n     */\r\n    public readonly lightingVolume: LightingVolume;\r\n\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this.lightingVolume) {\r\n            this.lightingVolume.name = name;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new FrameGraphLightingVolumeTask.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph instance.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.lightingVolume = new LightingVolume(name, frameGraph.scene);\r\n\r\n        this.outputMeshLightingVolume = {\r\n            meshes: [this.lightingVolume.mesh],\r\n            particleSystems: [],\r\n            spriteManagers: [],\r\n        };\r\n    }\r\n\r\n    public override isReady() {\r\n        const isReady = this.lightingVolume.isReady();\r\n        if (isReady) {\r\n            this.lightingVolume._setComputeShaderFastMode(true);\r\n        }\r\n        return isReady;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphLightingVolumeTask\";\r\n    }\r\n\r\n    public record() {\r\n        if (this.shadowGenerator === undefined) {\r\n            throw new Error(`FrameGraphLightingVolumeTask ${this.name}: shadowGenerator is required`);\r\n        }\r\n\r\n        const light = this.shadowGenerator.light;\r\n\r\n        if (!(light instanceof DirectionalLight)) {\r\n            throw new Error(`FrameGraphLightingVolumeTask ${this.name}: light must be a directional light`);\r\n        }\r\n\r\n        this.lightingVolume.shadowGenerator = this.shadowGenerator.shadowGenerator;\r\n\r\n        const pass = this._frameGraph.addObjectListPass(this.name);\r\n\r\n        pass.setObjectList(this.outputMeshLightingVolume);\r\n        pass.setExecuteFunc(() => {\r\n            this.lightingVolume.update();\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addObjectListPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setObjectList(this.outputMeshLightingVolume);\r\n        passDisabled.setExecuteFunc(() => {});\r\n    }\r\n\r\n    public override dispose() {\r\n        super.dispose();\r\n        this.lightingVolume.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FrameGraph, type FrameGraphShadowGeneratorTask, type NodeRenderGraphBuildState, type NodeRenderGraphConnectionPoint, type Scene } from \"core/index\";\r\nimport { FrameGraphLightingVolumeTask } from \"core/FrameGraph/Tasks/Misc/lightingVolumeTask\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the lighting volume\r\n */\r\nexport class NodeRenderGraphLightingVolumeBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphLightingVolumeTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphLightingVolumeBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"shadowGenerator\", NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator);\r\n\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n\r\n        this._frameGraphTask = new FrameGraphLightingVolumeTask(name, frameGraph);\r\n    }\r\n\r\n    /** Gets or sets the tesselation parameter */\r\n    @editableInPropertyPage(\"Tesselation\", PropertyTypeForEdition.Int, \"PROPERTIES\", { min: 1, max: 4096 })\r\n    public get tesselation(): number {\r\n        return this._frameGraphTask.lightingVolume.tesselation;\r\n    }\r\n\r\n    public set tesselation(value: number) {\r\n        this._frameGraphTask.lightingVolume.tesselation = value;\r\n    }\r\n\r\n    /** Gets or sets the refresh frequency parameter */\r\n    @editableInPropertyPage(\"Refresh frequency\", PropertyTypeForEdition.Int, \"PROPERTIES\")\r\n    public get frequency(): number {\r\n        return this._frameGraphTask.lightingVolume.frequency;\r\n    }\r\n\r\n    public set frequency(value: number) {\r\n        this._frameGraphTask.lightingVolume.frequency = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphLightingVolumeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow generator input component\r\n     */\r\n    public get shadowGenerator(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputMeshLightingVolume;\r\n\r\n        this._frameGraphTask.shadowGenerator = this.shadowGenerator.connectedPoint?.value as FrameGraphShadowGeneratorTask;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.tesselation = ${this.tesselation};`);\r\n        codes.push(`${this._codeVariableName}.frequency = ${this.frequency};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.tesselation = this.tesselation;\r\n        serializationObject.frequency = this.frequency;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.tesselation = serializationObject.tesselation;\r\n        this.frequency = serializationObject.frequency;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for lightingVolumeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLightingVolumeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphLightingVolumeBlock\", NodeRenderGraphLightingVolumeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../nodeRenderGraphBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used as a resource (textures, buffers) container\r\n */\r\nexport class NodeRenderGraphResourceContainerBlock extends NodeRenderGraphBlock {\r\n    /**\r\n     * Creates a new NodeRenderGraphResourceContainerBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"resource0\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource1\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource2\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource3\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource4\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource5\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource6\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"resource7\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.ResourceContainer);\r\n\r\n        this.resource0.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource1.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource2.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource3.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource4.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource5.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource6.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n        this.resource7.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer | NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphResourceContainerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the resource0 component\r\n     */\r\n    public get resource0(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource1 component\r\n     */\r\n    public get resource1(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource2 component\r\n     */\r\n    public get resource2(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource3 component\r\n     */\r\n    public get resource3(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource4 component\r\n     */\r\n    public get resource4(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource5 component\r\n     */\r\n    public get resource5(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource6 component\r\n     */\r\n    public get resource6(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the resource7 component\r\n     */\r\n    public get resource7(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for resourceContainerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterResourceContainerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphResourceContainerBlock\", NodeRenderGraphResourceContainerBlock);\r\n}\r\n","import { type SmartArray } from \"../Misc/smartArray\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type EffectWrapperCreationOptions, EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { EffectFallbacks } from \"../Materials/effectFallbacks\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"../Materials/clipPlaneMaterialHelper\";\r\nimport { BindBonesParameters, BindMorphTargetParameters, PrepareDefinesAndAttributesForMorphTargets, PushAttributesForInstances } from \"../Materials/materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ObjectRenderer } from \"core/Rendering/objectRenderer\";\r\nimport { _IsSideEffectImplemented } from \"../Misc/devTools\";\r\nimport { type Vector2 } from \"../Maths/math.vector\";\r\n\r\n/**\r\n * Special Glow Blur post process only blurring the alpha channel\r\n * It enforces keeping the most luminous color in the color channel.\r\n * @internal\r\n */\r\nexport class ThinGlowBlurPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"glowBlurPostProcess\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"screenSize\", \"direction\", \"blurWidth\"];\r\n\r\n    constructor(\r\n        name: string,\r\n        engine: Nullable<AbstractEngine> = null,\r\n        public direction: Vector2,\r\n        public kernel: number,\r\n        options?: EffectWrapperCreationOptions\r\n    ) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinGlowBlurPostProcess.FragmentUrl,\r\n            uniforms: ThinGlowBlurPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/glowBlurPostProcess.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/glowBlurPostProcess.fragment\"));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    public textureWidth: number = 0;\r\n\r\n    public textureHeight: number = 0;\r\n\r\n    public override bind() {\r\n        super.bind();\r\n        this._drawWrapper.effect!.setFloat2(\"screenSize\", this.textureWidth, this.textureHeight);\r\n        this._drawWrapper.effect!.setVector2(\"direction\", this.direction);\r\n        this._drawWrapper.effect!.setFloat(\"blurWidth\", this.kernel);\r\n    }\r\n}\r\n\r\n/**\r\n * Effect layer options. This helps customizing the behaviour\r\n * of the effect layer.\r\n */\r\nexport interface IThinEffectLayerOptions {\r\n    /**\r\n     * Multiplication factor apply to the canvas size to compute the render target size\r\n     * used to generated the glowing objects (the smaller the faster). Default: 0.5\r\n     */\r\n    mainTextureRatio?: number;\r\n\r\n    /**\r\n     * Enforces a fixed size texture to ensure resize independent blur. Default: undefined\r\n     */\r\n    mainTextureFixedSize?: number;\r\n\r\n    /**\r\n     * The type of the main texture. Default: TEXTURETYPE_UNSIGNED_BYTE\r\n     */\r\n    mainTextureType?: number;\r\n\r\n    /**\r\n     * The format of the main texture. Default: TEXTUREFORMAT_RGBA\r\n     */\r\n    mainTextureFormat?: number;\r\n\r\n    /**\r\n     * Alpha blending mode used to apply the blur. Default depends of the implementation. Default: ALPHA_COMBINE\r\n     */\r\n    alphaBlendingMode?: number;\r\n\r\n    /**\r\n     * The camera attached to the layer. Default: null\r\n     */\r\n    camera?: Nullable<Camera>;\r\n\r\n    /**\r\n     * The rendering group to draw the layer in. Default: -1\r\n     */\r\n    renderingGroupId?: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinEffectLayer {\r\n    private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _mergeDrawWrapper: DrawWrapper[];\r\n    protected _dontCheckIfReady = false;\r\n\r\n    protected _scene: Scene;\r\n    protected _engine: AbstractEngine;\r\n    /** @internal */\r\n    public _options: Required<IThinEffectLayerOptions>;\r\n    protected _objectRenderer: ObjectRenderer;\r\n    /** @internal */\r\n    public _shouldRender = true;\r\n    /** @internal */\r\n    public _emissiveTextureAndColor: { texture: Nullable<BaseTexture>; color: Color4 } = { texture: null, color: new Color4() };\r\n    /** @internal */\r\n    public _effectIntensity: { [meshUniqueId: number]: number } = {};\r\n    /** @internal */\r\n    public _postProcesses: EffectWrapper[] = [];\r\n\r\n    /**\r\n     * Force all the effect layers to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * The name of the layer\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * The clear color of the texture used to generate the glow map.\r\n     */\r\n    public neutralColor: Color4 = new Color4();\r\n\r\n    /**\r\n     * Specifies whether the effect layer is enabled or not.\r\n     */\r\n    public isEnabled: boolean = true;\r\n\r\n    /**\r\n     * Gets/sets the camera attached to the layer.\r\n     */\r\n    public get camera(): Nullable<Camera> {\r\n        return this._options.camera;\r\n    }\r\n\r\n    public set camera(camera: Nullable<Camera>) {\r\n        this._options.camera = camera;\r\n    }\r\n\r\n    /**\r\n     * Gets the rendering group id the layer should render in.\r\n     */\r\n    public get renderingGroupId(): number {\r\n        return this._options.renderingGroupId;\r\n    }\r\n    public set renderingGroupId(renderingGroupId: number) {\r\n        this._options.renderingGroupId = renderingGroupId;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the bounding boxes should be rendered normally or if they should undergo the effect of the layer\r\n     */\r\n    public disableBoundingBoxesFromEffectLayer = false;\r\n\r\n    /**\r\n     * An event triggered when the effect layer has been disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<ThinEffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the effect layer is about rendering the main texture with the glowy parts.\r\n     */\r\n    public onBeforeRenderLayerObservable = new Observable<ThinEffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the generated texture is being merged in the scene.\r\n     */\r\n    public onBeforeComposeObservable = new Observable<ThinEffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the mesh is rendered into the effect render target.\r\n     */\r\n    public onBeforeRenderMeshToEffect = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * An event triggered after the mesh has been rendered into the effect render target.\r\n     */\r\n    public onAfterRenderMeshToEffect = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * An event triggered when the generated texture has been merged in the scene.\r\n     */\r\n    public onAfterComposeObservable = new Observable<ThinEffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the layer is being blurred.\r\n     */\r\n    public onBeforeBlurObservable = new Observable<ThinEffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the layer has been blurred.\r\n     */\r\n    public onAfterBlurObservable = new Observable<ThinEffectLayer>();\r\n\r\n    /**\r\n     * Gets the object renderer used to render objects in the layer\r\n     */\r\n    public get objectRenderer() {\r\n        return this._objectRenderer;\r\n    }\r\n\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    private _materialForRendering: { [id: string]: [AbstractMesh, Material] } = {};\r\n\r\n    /**\r\n     * Sets a specific material to be used to render a mesh/a list of meshes in the layer\r\n     * @param mesh mesh or array of meshes\r\n     * @param material material to use by the layer when rendering the mesh(es). If undefined is passed, the specific material created by the layer will be used.\r\n     */\r\n    public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material): void {\r\n        this._objectRenderer.setMaterialForRendering(mesh, material);\r\n        if (Array.isArray(mesh)) {\r\n            for (let i = 0; i < mesh.length; ++i) {\r\n                const currentMesh = mesh[i];\r\n                if (!material) {\r\n                    delete this._materialForRendering[currentMesh.uniqueId];\r\n                } else {\r\n                    this._materialForRendering[currentMesh.uniqueId] = [currentMesh, material];\r\n                }\r\n            }\r\n        } else {\r\n            if (!material) {\r\n                delete this._materialForRendering[mesh.uniqueId];\r\n            } else {\r\n                this._materialForRendering[mesh.uniqueId] = [mesh, material];\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity of the effect for a specific mesh.\r\n     * @param mesh The mesh to get the effect intensity for\r\n     * @returns The intensity of the effect for the mesh\r\n     */\r\n    public getEffectIntensity(mesh: AbstractMesh) {\r\n        return this._effectIntensity[mesh.uniqueId] ?? 1;\r\n    }\r\n\r\n    /**\r\n     * Sets the intensity of the effect for a specific mesh.\r\n     * @param mesh The mesh to set the effect intensity for\r\n     * @param intensity The intensity of the effect for the mesh\r\n     */\r\n    public setEffectIntensity(mesh: AbstractMesh, intensity: number): void {\r\n        this._effectIntensity[mesh.uniqueId] = intensity;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new effect Layer\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     * @param dontCheckIfReady Specifies if the layer should disable checking whether all the post processes are ready (default: false). To save performance, this should be set to true and you should call `isReady` manually before rendering to the layer.\r\n     * @param _additionalImportShadersAsync Additional shaders to import when the layer is created\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene?: Scene,\r\n        forceGLSL = false,\r\n        dontCheckIfReady = false,\r\n        private _additionalImportShadersAsync?: () => Promise<void>\r\n    ) {\r\n        this.name = name;\r\n        this._scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        this._dontCheckIfReady = dontCheckIfReady;\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        if (engine.isWebGPU && !forceGLSL && !ThinEffectLayer.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._mergeDrawWrapper = [];\r\n\r\n        // Generate Buffers\r\n        this._generateIndexBuffer();\r\n        this._generateVertexBuffer();\r\n    }\r\n\r\n    /** @internal */\r\n    public _shadersLoaded = false;\r\n\r\n    /**\r\n     * Get the effect name of the layer.\r\n     * @returns The effect name\r\n     */\r\n    public getEffectName(): string {\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * Checks for the readiness of the element composing the layer.\r\n     * @param _subMesh the mesh to check for\r\n     * @param _useInstances specify whether or not to use instances to render the mesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    public isReady(_subMesh: SubMesh, _useInstances: boolean): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns whether or not the layer needs stencil enabled during the mesh rendering.\r\n     * @returns true if the effect requires stencil during the main canvas render pass.\r\n     */\r\n    public needStencil(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _createMergeEffect(): Effect {\r\n        throw new Error(\"Effect Layer: no merge effect defined\");\r\n    }\r\n\r\n    /** @internal */\r\n    public _createTextureAndPostProcesses(): void {}\r\n\r\n    /** @internal */\r\n    public bindTexturesForCompose: (effect: Effect) => void;\r\n\r\n    /** @internal */\r\n    public _internalCompose(_effect: Effect, _renderIndex: number): void {}\r\n\r\n    /** @internal */\r\n    public _setEmissiveTextureAndColor(_mesh: Mesh, _subMesh: SubMesh, _material: Material): void {}\r\n\r\n    /** @internal */\r\n    public _numInternalDraws(): number {\r\n        return 1;\r\n    }\r\n\r\n    /** @internal */\r\n    public _init(options: IThinEffectLayerOptions): void {\r\n        // Adapt options\r\n        this._options = {\r\n            mainTextureRatio: 0.5,\r\n            mainTextureFixedSize: 0,\r\n            mainTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            mainTextureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            alphaBlendingMode: Constants.ALPHA_COMBINE,\r\n            camera: null,\r\n            renderingGroupId: -1,\r\n            ...options,\r\n        };\r\n\r\n        this._createObjectRenderer();\r\n    }\r\n\r\n    private _generateIndexBuffer(): void {\r\n        // Indices\r\n        const indices = [];\r\n        indices.push(0);\r\n        indices.push(1);\r\n        indices.push(2);\r\n\r\n        indices.push(0);\r\n        indices.push(2);\r\n        indices.push(3);\r\n\r\n        this._indexBuffer = this._engine.createIndexBuffer(indices);\r\n    }\r\n\r\n    private _generateVertexBuffer(): void {\r\n        // VBO\r\n        const vertices = [];\r\n        vertices.push(1, 1);\r\n        vertices.push(-1, 1);\r\n        vertices.push(-1, -1);\r\n        vertices.push(1, -1);\r\n\r\n        const vertexBuffer = new VertexBuffer(this._engine, vertices, VertexBuffer.PositionKind, false, false, 2);\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = vertexBuffer;\r\n    }\r\n\r\n    protected _createObjectRenderer(): void {\r\n        this._objectRenderer = new ObjectRenderer(`ObjectRenderer for thin effect layer ${this.name}`, this._scene, {\r\n            doNotChangeAspectRatio: true,\r\n        });\r\n        this._objectRenderer.activeCamera = this._options.camera;\r\n        this._objectRenderer.renderParticles = false;\r\n        this._objectRenderer.renderList = null;\r\n\r\n        // Prevent package size in es6 (getBoundingBoxRenderer might not be present)\r\n        const hasBoundingBoxRenderer = _IsSideEffectImplemented(this._scene.getBoundingBoxRenderer);\r\n\r\n        let boundingBoxRendererEnabled = false;\r\n        if (hasBoundingBoxRenderer) {\r\n            this._objectRenderer.onBeforeRenderObservable.add(() => {\r\n                boundingBoxRendererEnabled = this._scene.getBoundingBoxRenderer().enabled;\r\n                this._scene.getBoundingBoxRenderer().enabled = !this.disableBoundingBoxesFromEffectLayer && boundingBoxRendererEnabled;\r\n            });\r\n\r\n            this._objectRenderer.onAfterRenderObservable.add(() => {\r\n                this._scene.getBoundingBoxRenderer().enabled = boundingBoxRendererEnabled;\r\n            });\r\n        }\r\n\r\n        this._objectRenderer.customIsReadyFunction = (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => {\r\n            if ((preWarm || refreshRate === 0) && mesh.subMeshes) {\r\n                for (let i = 0; i < mesh.subMeshes.length; ++i) {\r\n                    const subMesh = mesh.subMeshes[i];\r\n                    const material = subMesh.getMaterial();\r\n                    const renderingMesh = subMesh.getRenderingMesh();\r\n\r\n                    if (!material) {\r\n                        continue;\r\n                    }\r\n\r\n                    const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n                    const hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id] || renderingMesh.hasThinInstances;\r\n\r\n                    this._setEmissiveTextureAndColor(renderingMesh, subMesh, material);\r\n\r\n                    if (!this._isSubMeshReady(subMesh, hardwareInstancedRendering, this._emissiveTextureAndColor.texture)) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return true;\r\n        };\r\n\r\n        // Custom render function\r\n        this._objectRenderer.customRenderFunction = (\r\n            opaqueSubMeshes: SmartArray<SubMesh>,\r\n            alphaTestSubMeshes: SmartArray<SubMesh>,\r\n            transparentSubMeshes: SmartArray<SubMesh>,\r\n            depthOnlySubMeshes: SmartArray<SubMesh>\r\n        ): void => {\r\n            this.onBeforeRenderLayerObservable.notifyObservers(this);\r\n\r\n            let index: number;\r\n\r\n            const engine = this._scene.getEngine();\r\n\r\n            if (depthOnlySubMeshes.length) {\r\n                engine.setColorWrite(false);\r\n                for (index = 0; index < depthOnlySubMeshes.length; index++) {\r\n                    this._renderSubMesh(depthOnlySubMeshes.data[index]);\r\n                }\r\n                engine.setColorWrite(true);\r\n            }\r\n\r\n            for (index = 0; index < opaqueSubMeshes.length; index++) {\r\n                this._renderSubMesh(opaqueSubMeshes.data[index]);\r\n            }\r\n\r\n            for (index = 0; index < alphaTestSubMeshes.length; index++) {\r\n                this._renderSubMesh(alphaTestSubMeshes.data[index]);\r\n            }\r\n\r\n            const previousAlphaMode = engine.getAlphaMode();\r\n\r\n            for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                const subMesh = transparentSubMeshes.data[index];\r\n                const material = subMesh.getMaterial();\r\n                if (material && material.needDepthPrePass) {\r\n                    const engine = material.getScene().getEngine();\r\n                    engine.setColorWrite(false);\r\n                    this._renderSubMesh(subMesh);\r\n                    engine.setColorWrite(true);\r\n                }\r\n                this._renderSubMesh(subMesh, true);\r\n            }\r\n\r\n            engine.setAlphaMode(previousAlphaMode);\r\n        };\r\n    }\r\n\r\n    /** @internal */\r\n    public _addCustomEffectDefines(_defines: string[]): void {}\r\n\r\n    /** @internal */\r\n    public _internalIsSubMeshReady(subMesh: SubMesh, useInstances: boolean, emissiveTexture: Nullable<BaseTexture>): boolean {\r\n        const engine = this._scene.getEngine();\r\n        const mesh = subMesh.getMesh();\r\n\r\n        const renderingMaterial = mesh._internalAbstractMeshDataInfo._materialForRenderPass?.[engine.currentRenderPassId];\r\n\r\n        if (renderingMaterial) {\r\n            return renderingMaterial.isReadyForSubMesh(mesh, subMesh, useInstances);\r\n        }\r\n\r\n        const material = subMesh.getMaterial();\r\n\r\n        if (!material) {\r\n            return false;\r\n        }\r\n\r\n        if (this._useMeshMaterial(subMesh.getRenderingMesh())) {\r\n            // Enable glow mode during readiness check so the material compiles the\r\n            // correct shader variant (e.g. the USEADDITIONALCOLOR define / useAdditionalColor\r\n            // uniform path for NodeMaterial).\r\n            // This mirrors what _renderSubMesh does when actually rendering.\r\n            material._glowModeEnabled = true;\r\n            const isReady = material.isReadyForSubMesh(subMesh.getMesh(), subMesh, useInstances);\r\n            material._glowModeEnabled = false;\r\n            return isReady;\r\n        }\r\n\r\n        const defines: string[] = [];\r\n\r\n        const attribs = [VertexBuffer.PositionKind];\r\n\r\n        let uv1 = false;\r\n        let uv2 = false;\r\n        const color = false;\r\n\r\n        // Diffuse\r\n        if (material) {\r\n            const needAlphaTest = material.needAlphaTestingForMesh(mesh);\r\n\r\n            const diffuseTexture = material.getAlphaTestTexture();\r\n            const needAlphaBlendFromDiffuse =\r\n                diffuseTexture && diffuseTexture.hasAlpha && ((material as any).useAlphaFromDiffuseTexture || (material as any)._useAlphaFromAlbedoTexture);\r\n\r\n            if (diffuseTexture && (needAlphaTest || needAlphaBlendFromDiffuse)) {\r\n                defines.push(\"#define DIFFUSE\");\r\n                if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind) && diffuseTexture.coordinatesIndex === 1) {\r\n                    defines.push(\"#define DIFFUSEUV2\");\r\n                    uv2 = true;\r\n                } else if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                    defines.push(\"#define DIFFUSEUV1\");\r\n                    uv1 = true;\r\n                }\r\n\r\n                if (needAlphaTest) {\r\n                    defines.push(\"#define ALPHATEST\");\r\n                    defines.push(\"#define ALPHATESTVALUE 0.4\");\r\n                }\r\n                if (!diffuseTexture.gammaSpace) {\r\n                    defines.push(\"#define DIFFUSE_ISLINEAR\");\r\n                }\r\n            }\r\n\r\n            const opacityTexture = (material as any).opacityTexture;\r\n            if (opacityTexture) {\r\n                defines.push(\"#define OPACITY\");\r\n                if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind) && opacityTexture.coordinatesIndex === 1) {\r\n                    defines.push(\"#define OPACITYUV2\");\r\n                    uv2 = true;\r\n                } else if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                    defines.push(\"#define OPACITYUV1\");\r\n                    uv1 = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Emissive\r\n        if (emissiveTexture) {\r\n            defines.push(\"#define EMISSIVE\");\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind) && emissiveTexture.coordinatesIndex === 1) {\r\n                defines.push(\"#define EMISSIVEUV2\");\r\n                uv2 = true;\r\n            } else if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                defines.push(\"#define EMISSIVEUV1\");\r\n                uv1 = true;\r\n            }\r\n            if (!emissiveTexture.gammaSpace) {\r\n                defines.push(\"#define EMISSIVE_ISLINEAR\");\r\n            }\r\n        }\r\n\r\n        // Vertex\r\n        if (mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind) && mesh.hasVertexAlpha && material.transparencyMode !== Material.MATERIAL_OPAQUE) {\r\n            attribs.push(VertexBuffer.ColorKind);\r\n            defines.push(\"#define VERTEXALPHA\");\r\n        }\r\n\r\n        if (uv1) {\r\n            attribs.push(VertexBuffer.UVKind);\r\n            defines.push(\"#define UV1\");\r\n        }\r\n        if (uv2) {\r\n            attribs.push(VertexBuffer.UV2Kind);\r\n            defines.push(\"#define UV2\");\r\n        }\r\n\r\n        // Bones\r\n        const fallbacks = new EffectFallbacks();\r\n        if (mesh.useBones && mesh.computeBonesUsingShaders) {\r\n            attribs.push(VertexBuffer.MatricesIndicesKind);\r\n            attribs.push(VertexBuffer.MatricesWeightsKind);\r\n            if (mesh.numBoneInfluencers > 4) {\r\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n            }\r\n\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n\r\n            const skeleton = mesh.skeleton;\r\n            if (skeleton && skeleton.isUsingTextureForMatrices) {\r\n                defines.push(\"#define BONETEXTURE\");\r\n            } else {\r\n                defines.push(\"#define BonesPerMesh \" + (skeleton ? skeleton.bones.length + 1 : 0));\r\n            }\r\n\r\n            if (mesh.numBoneInfluencers > 0) {\r\n                fallbacks.addCPUSkinningFallback(0, mesh);\r\n            }\r\n        } else {\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n        }\r\n\r\n        // Morph targets\r\n        const numMorphInfluencers = mesh.morphTargetManager\r\n            ? PrepareDefinesAndAttributesForMorphTargets(\r\n                  mesh.morphTargetManager,\r\n                  defines,\r\n                  attribs,\r\n                  mesh,\r\n                  true, // usePositionMorph\r\n                  false, // useNormalMorph\r\n                  false, // useTangentMorph\r\n                  uv1, // useUVMorph\r\n                  uv2, // useUV2Morph\r\n                  color // useColorMorph\r\n              )\r\n            : 0;\r\n\r\n        // Instances\r\n        if (useInstances) {\r\n            defines.push(\"#define INSTANCES\");\r\n            PushAttributesForInstances(attribs);\r\n            if (subMesh.getRenderingMesh().hasThinInstances) {\r\n                defines.push(\"#define THIN_INSTANCES\");\r\n            }\r\n        }\r\n\r\n        // Baked vertex animations\r\n        const bvaManager = mesh.bakedVertexAnimationManager;\r\n        if (bvaManager && bvaManager.isEnabled) {\r\n            defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\r\n            if (useInstances) {\r\n                attribs.push(\"bakedVertexAnimationSettingsInstanced\");\r\n            }\r\n        }\r\n\r\n        // ClipPlanes\r\n        PrepareStringDefinesForClipPlanes(material, this._scene, defines);\r\n\r\n        this._addCustomEffectDefines(defines);\r\n\r\n        // Get correct effect\r\n        const drawWrapper = subMesh._getDrawWrapper(undefined, true)!;\r\n        const cachedDefines = drawWrapper.defines as string;\r\n        const join = defines.join(\"\\n\");\r\n        if (cachedDefines !== join) {\r\n            const uniforms = [\r\n                \"world\",\r\n                \"mBones\",\r\n                \"viewProjection\",\r\n                \"glowColor\",\r\n                \"morphTargetInfluences\",\r\n                \"morphTargetCount\",\r\n                \"boneTextureInfo\",\r\n                \"diffuseMatrix\",\r\n                \"emissiveMatrix\",\r\n                \"opacityMatrix\",\r\n                \"opacityIntensity\",\r\n                \"morphTargetTextureInfo\",\r\n                \"morphTargetTextureIndices\",\r\n                \"bakedVertexAnimationSettings\",\r\n                \"bakedVertexAnimationTextureSizeInverted\",\r\n                \"bakedVertexAnimationTime\",\r\n                \"bakedVertexAnimationTexture\",\r\n                \"glowIntensity\",\r\n            ];\r\n\r\n            AddClipPlaneUniforms(uniforms);\r\n\r\n            drawWrapper.setEffect(\r\n                this._engine.createEffect(\r\n                    \"glowMapGeneration\",\r\n                    attribs,\r\n                    uniforms,\r\n                    [\"diffuseSampler\", \"emissiveSampler\", \"opacitySampler\", \"boneSampler\", \"morphTargets\", \"bakedVertexAnimationTexture\"],\r\n                    join,\r\n                    fallbacks,\r\n                    undefined,\r\n                    undefined,\r\n                    { maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                    this._shaderLanguage,\r\n                    this._shadersLoaded\r\n                        ? undefined\r\n                        : async () => {\r\n                              await this._importShadersAsync();\r\n                              this._shadersLoaded = true;\r\n                          }\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        const effectIsReady = drawWrapper.effect!.isReady();\r\n\r\n        return effectIsReady && (this._dontCheckIfReady || (!this._dontCheckIfReady && this.isLayerReady()));\r\n    }\r\n\r\n    /** @internal */\r\n    public _isSubMeshReady(subMesh: SubMesh, useInstances: boolean, emissiveTexture: Nullable<BaseTexture>): boolean {\r\n        return this._internalIsSubMeshReady(subMesh, useInstances, emissiveTexture);\r\n    }\r\n\r\n    protected async _importShadersAsync(): Promise<void> {\r\n        if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([import(\"../ShadersWGSL/glowMapGeneration.vertex\"), import(\"../ShadersWGSL/glowMapGeneration.fragment\")]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/glowMapGeneration.vertex\"), import(\"../Shaders/glowMapGeneration.fragment\")]);\r\n        }\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._additionalImportShadersAsync?.();\r\n    }\r\n\r\n    /** @internal */\r\n    public _internalIsLayerReady(): boolean {\r\n        let isReady = true;\r\n\r\n        for (let i = 0; i < this._postProcesses.length; i++) {\r\n            isReady = this._postProcesses[i].isReady() && isReady;\r\n        }\r\n\r\n        const numDraws = this._numInternalDraws();\r\n\r\n        for (let i = 0; i < numDraws; ++i) {\r\n            let currentEffect = this._mergeDrawWrapper[i];\r\n            if (!currentEffect) {\r\n                currentEffect = this._mergeDrawWrapper[i] = new DrawWrapper(this._engine);\r\n                currentEffect.setEffect(this._createMergeEffect());\r\n            }\r\n            isReady = currentEffect.effect!.isReady() && isReady;\r\n        }\r\n\r\n        return isReady;\r\n    }\r\n\r\n    protected _disposeMergeEffects(): void {\r\n        for (const drawWrapper of this._mergeDrawWrapper) {\r\n            drawWrapper.dispose();\r\n        }\r\n        this._mergeDrawWrapper = [];\r\n    }\r\n\r\n    /**\r\n     * Checks if the layer is ready to be used.\r\n     * @returns true if the layer is ready to be used\r\n     */\r\n    public isLayerReady(): boolean {\r\n        return this._internalIsLayerReady();\r\n    }\r\n\r\n    /**\r\n     * Renders the glowing part of the scene by blending the blurred glowing meshes on top of the rendered scene.\r\n     * @returns true if the rendering was successful\r\n     */\r\n    public compose(): boolean {\r\n        if (!this._dontCheckIfReady && !this.isLayerReady()) {\r\n            return false;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n        const numDraws = this._numInternalDraws();\r\n\r\n        this.onBeforeComposeObservable.notifyObservers(this);\r\n\r\n        const previousAlphaMode = engine.getAlphaMode();\r\n\r\n        for (let i = 0; i < numDraws; ++i) {\r\n            const currentEffect = this._mergeDrawWrapper[i];\r\n\r\n            // Render\r\n            engine.enableEffect(currentEffect);\r\n            engine.setState(false);\r\n\r\n            // VBOs\r\n            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, currentEffect.effect!);\r\n\r\n            // Go Blend.\r\n            engine.setAlphaMode(this._options.alphaBlendingMode);\r\n\r\n            // Blends the map on the main canvas.\r\n            this._internalCompose(currentEffect.effect!, i);\r\n        }\r\n\r\n        // Restore Alpha\r\n        engine.setAlphaMode(previousAlphaMode);\r\n\r\n        this.onAfterComposeObservable.notifyObservers(this);\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _internalHasMesh(mesh: AbstractMesh): boolean {\r\n        if (this.renderingGroupId === -1 || mesh.renderingGroupId === this.renderingGroupId) {\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Determine if a given mesh will be used in the current effect.\r\n     * @param mesh mesh to test\r\n     * @returns true if the mesh will be used\r\n     */\r\n    public hasMesh(mesh: AbstractMesh): boolean {\r\n        return this._internalHasMesh(mesh);\r\n    }\r\n\r\n    /** @internal */\r\n    public _internalShouldRender(): boolean {\r\n        return this.isEnabled && this._shouldRender;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the layer contains information to display, otherwise false.\r\n     * @returns true if the glow layer should be rendered\r\n     */\r\n    public shouldRender(): boolean {\r\n        return this._internalShouldRender();\r\n    }\r\n\r\n    /** @internal */\r\n    public _shouldRenderMesh(_mesh: AbstractMesh): boolean {\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _internalCanRenderMesh(mesh: AbstractMesh, material: Material): boolean {\r\n        return !material.needAlphaBlendingForMesh(mesh);\r\n    }\r\n\r\n    /** @internal */\r\n    public _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {\r\n        return this._internalCanRenderMesh(mesh, material);\r\n    }\r\n\r\n    protected _renderSubMesh(subMesh: SubMesh, enableAlphaMode: boolean = false): void {\r\n        if (!this._internalShouldRender()) {\r\n            return;\r\n        }\r\n\r\n        const material = subMesh.getMaterial();\r\n        const ownerMesh = subMesh.getMesh();\r\n        const replacementMesh = subMesh.getReplacementMesh();\r\n        const renderingMesh = subMesh.getRenderingMesh();\r\n        const effectiveMesh = subMesh.getEffectiveMesh();\r\n        const scene = this._scene;\r\n        const engine = scene.getEngine();\r\n\r\n        effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n\r\n        if (!material) {\r\n            return;\r\n        }\r\n\r\n        // Do not block in blend mode.\r\n        if (!this._canRenderMesh(renderingMesh, material)) {\r\n            return;\r\n        }\r\n\r\n        // Culling\r\n        let sideOrientation = material._getEffectiveOrientation(renderingMesh);\r\n        const mainDeterminant = effectiveMesh._getWorldMatrixDeterminant();\r\n        if (mainDeterminant < 0) {\r\n            sideOrientation = sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;\r\n        }\r\n\r\n        const reverse = sideOrientation === Material.ClockWiseSideOrientation;\r\n\r\n        // Managing instances\r\n        const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);\r\n        if (batch.mustReturn) {\r\n            return;\r\n        }\r\n\r\n        // Early Exit per mesh\r\n        if (!this._shouldRenderMesh(renderingMesh)) {\r\n            return;\r\n        }\r\n\r\n        const hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id] || renderingMesh.hasThinInstances;\r\n\r\n        this._setEmissiveTextureAndColor(renderingMesh, subMesh, material);\r\n\r\n        this.onBeforeRenderMeshToEffect.notifyObservers(ownerMesh);\r\n\r\n        if (this._useMeshMaterial(renderingMesh)) {\r\n            subMesh.getMaterial()!._glowModeEnabled = true;\r\n            renderingMesh.render(subMesh, enableAlphaMode, replacementMesh || undefined);\r\n            subMesh.getMaterial()!._glowModeEnabled = false;\r\n        } else if (this._isSubMeshReady(subMesh, hardwareInstancedRendering, this._emissiveTextureAndColor.texture)) {\r\n            const renderingMaterial = effectiveMesh._internalAbstractMeshDataInfo._materialForRenderPass?.[engine.currentRenderPassId];\r\n\r\n            let drawWrapper = subMesh._getDrawWrapper();\r\n            if (!drawWrapper && renderingMaterial) {\r\n                drawWrapper = renderingMaterial._getDrawWrapper();\r\n            }\r\n\r\n            if (!drawWrapper) {\r\n                return;\r\n            }\r\n\r\n            const effect = drawWrapper.effect!;\r\n\r\n            engine.enableEffect(drawWrapper);\r\n            engine.setState(material.backFaceCulling, material.zOffset, undefined, reverse, material.cullBackFaces, material.stencil, material.zOffsetUnits);\r\n\r\n            const currentDepthWrite = engine.getDepthWrite();\r\n            const currentColorWrite = engine.getColorWrite();\r\n            const currentDepthFunction = engine.getDepthFunction() || 0;\r\n\r\n            if (material.disableDepthWrite) {\r\n                engine.setDepthWrite(false);\r\n            } else if (material.forceDepthWrite) {\r\n                engine.setDepthWrite(true);\r\n            }\r\n            if (material.disableColorWrite) {\r\n                engine.setColorWrite(false);\r\n            }\r\n\r\n            if (material.depthFunction !== 0) {\r\n                engine.setDepthFunction(material.depthFunction);\r\n            }\r\n\r\n            if (!hardwareInstancedRendering) {\r\n                renderingMesh._bind(subMesh, effect, material.fillMode);\r\n            }\r\n\r\n            if (!renderingMaterial) {\r\n                effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\r\n                effect.setMatrix(\"world\", effectiveMesh.getWorldMatrix());\r\n                effect.setFloat4(\r\n                    \"glowColor\",\r\n                    this._emissiveTextureAndColor.color.r,\r\n                    this._emissiveTextureAndColor.color.g,\r\n                    this._emissiveTextureAndColor.color.b,\r\n                    this._emissiveTextureAndColor.color.a\r\n                );\r\n            } else {\r\n                renderingMaterial.bindForSubMesh(effectiveMesh.getWorldMatrix(), effectiveMesh as Mesh, subMesh);\r\n            }\r\n\r\n            if (!renderingMaterial) {\r\n                const needAlphaTest = material.needAlphaTestingForMesh(effectiveMesh);\r\n\r\n                const diffuseTexture = material.getAlphaTestTexture();\r\n                const needAlphaBlendFromDiffuse =\r\n                    diffuseTexture && diffuseTexture.hasAlpha && ((material as any).useAlphaFromDiffuseTexture || (material as any)._useAlphaFromAlbedoTexture);\r\n\r\n                if (diffuseTexture && (needAlphaTest || needAlphaBlendFromDiffuse)) {\r\n                    effect.setTexture(\"diffuseSampler\", diffuseTexture);\r\n                    const textureMatrix = diffuseTexture.getTextureMatrix();\r\n\r\n                    if (textureMatrix) {\r\n                        effect.setMatrix(\"diffuseMatrix\", textureMatrix);\r\n                    }\r\n                }\r\n\r\n                const opacityTexture = (material as any).opacityTexture;\r\n                if (opacityTexture) {\r\n                    effect.setTexture(\"opacitySampler\", opacityTexture);\r\n                    effect.setFloat(\"opacityIntensity\", opacityTexture.level);\r\n                    const textureMatrix = opacityTexture.getTextureMatrix();\r\n                    if (textureMatrix) {\r\n                        effect.setMatrix(\"opacityMatrix\", textureMatrix);\r\n                    }\r\n                }\r\n\r\n                // Glow emissive only\r\n                if (this._emissiveTextureAndColor.texture) {\r\n                    effect.setTexture(\"emissiveSampler\", this._emissiveTextureAndColor.texture);\r\n                    effect.setMatrix(\"emissiveMatrix\", this._emissiveTextureAndColor.texture.getTextureMatrix());\r\n                }\r\n\r\n                // Bones\r\n                BindBonesParameters(renderingMesh, effect);\r\n\r\n                // Morph targets\r\n                BindMorphTargetParameters(renderingMesh, effect);\r\n                if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\r\n                    renderingMesh.morphTargetManager._bind(effect);\r\n                }\r\n\r\n                // Baked vertex animations\r\n                const bvaManager = subMesh.getMesh().bakedVertexAnimationManager;\r\n                if (bvaManager && bvaManager.isEnabled) {\r\n                    bvaManager.bind(effect, hardwareInstancedRendering);\r\n                }\r\n\r\n                // Alpha mode\r\n                if (enableAlphaMode) {\r\n                    engine.setAlphaMode(material.alphaMode);\r\n                }\r\n\r\n                // Intensity of effect\r\n                effect.setFloat(\"glowIntensity\", this.getEffectIntensity(renderingMesh));\r\n\r\n                // Clip planes\r\n                BindClipPlane(effect, material, scene);\r\n            }\r\n\r\n            // Draw\r\n            renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, world) =>\r\n                effect.setMatrix(\"world\", world)\r\n            );\r\n\r\n            if (material.disableDepthWrite || material.forceDepthWrite) {\r\n                engine.setDepthWrite(currentDepthWrite);\r\n            }\r\n            if (material.disableColorWrite) {\r\n                engine.setColorWrite(currentColorWrite);\r\n            }\r\n            if (material.depthFunction !== 0) {\r\n                engine.setDepthFunction(currentDepthFunction);\r\n            }\r\n        } else {\r\n            // Need to reset refresh rate of the main map\r\n            this._objectRenderer.resetRefreshCounter();\r\n        }\r\n\r\n        this.onAfterRenderMeshToEffect.notifyObservers(ownerMesh);\r\n    }\r\n\r\n    /** @internal */\r\n    public _useMeshMaterial(_mesh: AbstractMesh): boolean {\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        const vb = this._vertexBuffers[VertexBuffer.PositionKind];\r\n\r\n        if (vb) {\r\n            vb._rebuild();\r\n        }\r\n\r\n        this._generateIndexBuffer();\r\n    }\r\n\r\n    /**\r\n     * Dispose the effect layer and free resources.\r\n     */\r\n    public dispose(): void {\r\n        const vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (vertexBuffer) {\r\n            vertexBuffer.dispose();\r\n            this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this._scene.getEngine()._releaseBuffer(this._indexBuffer);\r\n            this._indexBuffer = null;\r\n        }\r\n\r\n        this._disposeMergeEffects();\r\n\r\n        this._objectRenderer.dispose();\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n\r\n        this.onDisposeObservable.clear();\r\n        this.onBeforeRenderLayerObservable.clear();\r\n        this.onBeforeComposeObservable.clear();\r\n        this.onBeforeRenderMeshToEffect.clear();\r\n        this.onAfterRenderMeshToEffect.clear();\r\n        this.onAfterComposeObservable.clear();\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions, type Vector2, type Effect } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to apply a blur effect\r\n */\r\nexport class ThinBlurPostProcess extends EffectWrapper {\r\n    /**\r\n     * The vertex shader url\r\n     */\r\n    public static readonly VertexUrl = \"kernelBlur\";\r\n\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"kernelBlur\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"delta\", \"direction\"];\r\n\r\n    /**\r\n     * The list of samplers used by the effect\r\n     */\r\n    public static readonly Samplers = [\"circleOfConfusionSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/kernelBlur.fragment\"), import(\"../ShadersWGSL/kernelBlur.vertex\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/kernelBlur.fragment\"), import(\"../Shaders/kernelBlur.vertex\")]));\r\n        }\r\n    }\r\n\r\n    protected _kernel: number;\r\n    protected _idealKernel: number;\r\n    protected _packedFloat: boolean = false;\r\n    private _staticDefines: string = \"\";\r\n\r\n    /**\r\n     * Constructs a new blur post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param direction Direction in which to apply the blur\r\n     * @param kernel Kernel size of the blur\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, direction?: Vector2, kernel?: number, options?: EffectWrapperCreationOptions) {\r\n        const blockCompilationFinal = !!options?.blockCompilation;\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinBlurPostProcess.FragmentUrl,\r\n            uniforms: ThinBlurPostProcess.Uniforms,\r\n            samplers: ThinBlurPostProcess.Samplers,\r\n            vertexUrl: ThinBlurPostProcess.VertexUrl,\r\n            blockCompilation: true,\r\n        });\r\n\r\n        this._staticDefines = options ? (Array.isArray(options.defines) ? options.defines.join(\"\\n\") : options.defines || \"\") : \"\";\r\n\r\n        this.options.blockCompilation = blockCompilationFinal;\r\n\r\n        if (direction !== undefined) {\r\n            this.direction = direction;\r\n        }\r\n        if (kernel !== undefined) {\r\n            this.kernel = kernel;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Width of the texture to apply the blur on\r\n     */\r\n    public textureWidth: number = 0;\r\n\r\n    /**\r\n     * Height of the texture to apply the blur on\r\n     */\r\n    public textureHeight: number = 0;\r\n\r\n    /** The direction in which to blur the image. */\r\n    public direction: Vector2;\r\n\r\n    /**\r\n     * Sets the length in pixels of the blur sample region\r\n     */\r\n    public set kernel(v: number) {\r\n        if (this._idealKernel === v) {\r\n            return;\r\n        }\r\n\r\n        v = Math.max(v, 1);\r\n        this._idealKernel = v;\r\n        this._kernel = this._nearestBestKernel(v);\r\n        if (!this.options.blockCompilation) {\r\n            this._updateParameters();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the length in pixels of the blur sample region\r\n     */\r\n    public get kernel(): number {\r\n        return this._idealKernel;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not the blur needs to unpack/repack floats\r\n     */\r\n    public set packedFloat(v: boolean) {\r\n        if (this._packedFloat === v) {\r\n            return;\r\n        }\r\n        this._packedFloat = v;\r\n        if (!this.options.blockCompilation) {\r\n            this._updateParameters();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets whether or not the blur is unpacking/repacking floats\r\n     */\r\n    public get packedFloat(): boolean {\r\n        return this._packedFloat;\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setFloat2(\"delta\", (1 / this.textureWidth) * this.direction.x, (1 / this.textureHeight) * this.direction.y);\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateParameters(onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): void {\r\n        // Generate sampling offsets and weights\r\n        const n = this._kernel;\r\n        const centerIndex = (n - 1) / 2;\r\n\r\n        // Generate Gaussian sampling weights over kernel\r\n        let offsets = [];\r\n        let weights = [];\r\n        let totalWeight = 0;\r\n        for (let i = 0; i < n; i++) {\r\n            const u = i / (n - 1);\r\n            const w = this._gaussianWeight(u * 2.0 - 1);\r\n            offsets[i] = i - centerIndex;\r\n            weights[i] = w;\r\n            totalWeight += w;\r\n        }\r\n\r\n        // Normalize weights\r\n        for (let i = 0; i < weights.length; i++) {\r\n            weights[i] /= totalWeight;\r\n        }\r\n\r\n        // Optimize: combine samples to take advantage of hardware linear sampling\r\n        // Walk from left to center, combining pairs (symmetrically)\r\n        const linearSamplingWeights = [];\r\n        const linearSamplingOffsets = [];\r\n\r\n        const linearSamplingMap = [];\r\n\r\n        for (let i = 0; i <= centerIndex; i += 2) {\r\n            const j = Math.min(i + 1, Math.floor(centerIndex));\r\n\r\n            const singleCenterSample = i === j;\r\n\r\n            if (singleCenterSample) {\r\n                linearSamplingMap.push({ o: offsets[i], w: weights[i] });\r\n            } else {\r\n                const sharedCell = j === centerIndex;\r\n\r\n                const weightLinear = weights[i] + weights[j] * (sharedCell ? 0.5 : 1);\r\n                const offsetLinear = offsets[i] + 1 / (1 + weights[i] / weights[j]);\r\n\r\n                if (offsetLinear === 0) {\r\n                    linearSamplingMap.push({ o: offsets[i], w: weights[i] });\r\n                    linearSamplingMap.push({ o: offsets[i + 1], w: weights[i + 1] });\r\n                } else {\r\n                    linearSamplingMap.push({ o: offsetLinear, w: weightLinear });\r\n                    linearSamplingMap.push({ o: -offsetLinear, w: weightLinear });\r\n                }\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < linearSamplingMap.length; i++) {\r\n            linearSamplingOffsets[i] = linearSamplingMap[i].o;\r\n            linearSamplingWeights[i] = linearSamplingMap[i].w;\r\n        }\r\n\r\n        // Replace with optimized\r\n        offsets = linearSamplingOffsets;\r\n        weights = linearSamplingWeights;\r\n\r\n        // Generate shaders\r\n        const maxVaryingRows = this.options.engine.getCaps().maxVaryingVectors - (this.options.shaderLanguage === ShaderLanguage.WGSL ? 1 : 0); // Because of the additional builtins\r\n        const freeVaryingVec2 = Math.max(maxVaryingRows, 0) - 1; // Because of sampleCenter\r\n\r\n        let varyingCount = Math.min(offsets.length, freeVaryingVec2);\r\n\r\n        let defines = \"\";\r\n        defines += this._staticDefines;\r\n\r\n        // The DOF fragment should ignore the center pixel when looping as it is handled manually in the fragment shader.\r\n        if (this._staticDefines.indexOf(\"DOF\") != -1) {\r\n            defines += `#define CENTER_WEIGHT ${this._glslFloat(weights[varyingCount - 1])}\\n`;\r\n            varyingCount--;\r\n        }\r\n\r\n        for (let i = 0; i < varyingCount; i++) {\r\n            defines += `#define KERNEL_OFFSET${i} ${this._glslFloat(offsets[i])}\\n`;\r\n            defines += `#define KERNEL_WEIGHT${i} ${this._glslFloat(weights[i])}\\n`;\r\n        }\r\n\r\n        let depCount = 0;\r\n        for (let i = freeVaryingVec2; i < offsets.length; i++) {\r\n            defines += `#define KERNEL_DEP_OFFSET${depCount} ${this._glslFloat(offsets[i])}\\n`;\r\n            defines += `#define KERNEL_DEP_WEIGHT${depCount} ${this._glslFloat(weights[i])}\\n`;\r\n            depCount++;\r\n        }\r\n\r\n        if (this.packedFloat) {\r\n            defines += `#define PACKEDFLOAT 1`;\r\n        }\r\n\r\n        this.options.blockCompilation = false;\r\n\r\n        this.updateEffect(\r\n            defines,\r\n            null,\r\n            null,\r\n            {\r\n                varyingCount: varyingCount,\r\n                depCount: depCount,\r\n            },\r\n            onCompiled,\r\n            onError\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Best kernels are odd numbers that when divided by 2, their integer part is even, so 5, 9 or 13.\r\n     * Other odd kernels optimize correctly but require proportionally more samples, even kernels are\r\n     * possible but will produce minor visual artifacts. Since each new kernel requires a new shader we\r\n     * want to minimize kernel changes, having gaps between physical kernels is helpful in that regard.\r\n     * The gaps between physical kernels are compensated for in the weighting of the samples\r\n     * @param idealKernel Ideal blur kernel.\r\n     * @returns Nearest best kernel.\r\n     */\r\n    protected _nearestBestKernel(idealKernel: number): number {\r\n        const v = Math.round(idealKernel);\r\n        for (const k of [v, v - 1, v + 1, v - 2, v + 2]) {\r\n            if (k % 2 !== 0 && Math.floor(k / 2) % 2 === 0 && k > 0) {\r\n                return Math.max(k, 3);\r\n            }\r\n        }\r\n        return Math.max(v, 3);\r\n    }\r\n\r\n    /**\r\n     * Calculates the value of a Gaussian distribution with sigma 3 at a given point.\r\n     * @param x The point on the Gaussian distribution to sample.\r\n     * @returns the value of the Gaussian function at x.\r\n     */\r\n    protected _gaussianWeight(x: number): number {\r\n        //reference: Engines/ImageProcessingBlur.cpp #dcc760\r\n        // We are evaluating the Gaussian (normal) distribution over a kernel parameter space of [-1,1],\r\n        // so we truncate at three standard deviations by setting stddev (sigma) to 1/3.\r\n        // The choice of 3-sigma truncation is common but arbitrary, and means that the signal is\r\n        // truncated at around 1.3% of peak strength.\r\n\r\n        //the distribution is scaled to account for the difference between the actual kernel size and the requested kernel size\r\n        const sigma = 1 / 3;\r\n        const denominator = Math.sqrt(2.0 * Math.PI) * sigma;\r\n        const exponent = -((x * x) / (2.0 * sigma * sigma));\r\n        const weight = (1.0 / denominator) * Math.exp(exponent);\r\n        return weight;\r\n    }\r\n\r\n    /**\r\n     * Generates a string that can be used as a floating point number in GLSL.\r\n     * @param x Value to print.\r\n     * @param decimalFigures Number of decimal places to print the number to (excluding trailing 0s).\r\n     * @returns GLSL float string.\r\n     */\r\n    protected _glslFloat(x: number, decimalFigures = 8) {\r\n        return x.toFixed(decimalFigures).replace(/0+$/, \"\");\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type Scene } from \"../scene\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type Texture } from \"../Materials/Textures/texture\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { ThinEffectLayer, type IThinEffectLayerOptions } from \"./thinEffectLayer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type PBRMaterial } from \"../Materials/PBR/pbrMaterial\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ThinBlurPostProcess } from \"core/PostProcesses/thinBlurPostProcess\";\r\n\r\n/**\r\n * Glow layer options. This helps customizing the behaviour\r\n * of the glow layer.\r\n */\r\nexport interface IThinGlowLayerOptions extends IThinEffectLayerOptions {\r\n    /**\r\n     * How big is the kernel of the blur texture. Default: 32\r\n     */\r\n    blurKernelSize?: number;\r\n\r\n    /**\r\n     * Forces the merge step to be done in ldr (clamp values > 1). Default: false\r\n     */\r\n    ldrMerge?: boolean;\r\n\r\n    /**\r\n     * Exclude all meshes from the glow layer by default.\r\n     * This is useful if you have dynamic meshes and you want to control them specifically and\r\n     * make sure that there are no \"leaking\" glowing meshes.\r\n     * Default: false\r\n     */\r\n    excludeByDefault?: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinGlowLayer extends ThinEffectLayer {\r\n    /**\r\n     * Effect Name of the layer.\r\n     */\r\n    public static readonly EffectName = \"GlowLayer\";\r\n\r\n    /**\r\n     * The default blur kernel size used for the glow.\r\n     */\r\n    public static DefaultBlurKernelSize = 32;\r\n\r\n    /**\r\n     * Gets the ldrMerge option.\r\n     */\r\n    public get ldrMerge(): boolean {\r\n        return this._options.ldrMerge;\r\n    }\r\n\r\n    /**\r\n     * Sets the kernel size of the blur.\r\n     */\r\n    public set blurKernelSize(value: number) {\r\n        if (value === this._options.blurKernelSize) {\r\n            return;\r\n        }\r\n\r\n        this._options.blurKernelSize = value;\r\n\r\n        const effectiveKernel = this._getEffectiveBlurKernelSize();\r\n        this._horizontalBlurPostprocess1.kernel = effectiveKernel;\r\n        this._verticalBlurPostprocess1.kernel = effectiveKernel;\r\n        this._horizontalBlurPostprocess2.kernel = effectiveKernel;\r\n        this._verticalBlurPostprocess2.kernel = effectiveKernel;\r\n    }\r\n\r\n    /**\r\n     * Gets the kernel size of the blur.\r\n     */\r\n    public get blurKernelSize(): number {\r\n        return this._options.blurKernelSize;\r\n    }\r\n\r\n    /**\r\n     * Sets the glow intensity.\r\n     */\r\n    public set intensity(value: number) {\r\n        this._intensity = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the glow intensity.\r\n     */\r\n    public get intensity(): number {\r\n        return this._intensity;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _options: Required<IThinGlowLayerOptions>;\r\n\r\n    private _intensity: number = 1.0;\r\n    private _horizontalBlurPostprocess1: ThinBlurPostProcess;\r\n    private _verticalBlurPostprocess1: ThinBlurPostProcess;\r\n    private _horizontalBlurPostprocess2: ThinBlurPostProcess;\r\n    private _verticalBlurPostprocess2: ThinBlurPostProcess;\r\n\r\n    /** @internal */\r\n    public _includedOnlyMeshes: number[] = [];\r\n    /** @internal */\r\n    public _excludedMeshes: number[] = [];\r\n    private _meshesUsingTheirOwnMaterials: number[] = [];\r\n\r\n    /**\r\n     * Callback used to let the user override the color selection on a per mesh basis\r\n     */\r\n    public customEmissiveColorSelector: (mesh: Mesh, subMesh: SubMesh, material: Material, result: Color4) => void;\r\n    /**\r\n     * Callback used to let the user override the texture selection on a per mesh basis\r\n     */\r\n    public customEmissiveTextureSelector: (mesh: Mesh, subMesh: SubMesh, material: Material) => Texture;\r\n\r\n    /** @internal */\r\n    public _renderPassId = 0;\r\n\r\n    /**\r\n     * Instantiates a new glow Layer and references it to the scene.\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param options Sets of none mandatory options to use with the layer (see IGlowLayerOptions for more information)\r\n     * @param dontCheckIfReady Specifies if the layer should disable checking whether all the post processes are ready (default: false). To save performance, this should be set to true and you should call `isReady` manually before rendering to the layer.\r\n     */\r\n    constructor(name: string, scene?: Scene, options?: IThinGlowLayerOptions, dontCheckIfReady = false) {\r\n        super(name, scene, false, dontCheckIfReady);\r\n        this.neutralColor = new Color4(0, 0, 0, 1);\r\n\r\n        // Adapt options\r\n        this._options = {\r\n            mainTextureRatio: 0.5,\r\n            mainTextureFixedSize: 0,\r\n            mainTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            mainTextureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            blurKernelSize: 32,\r\n            camera: null,\r\n            renderingGroupId: -1,\r\n            ldrMerge: false,\r\n            alphaBlendingMode: Constants.ALPHA_ADD,\r\n            excludeByDefault: false,\r\n            ...options,\r\n        };\r\n\r\n        // Initialize the layer\r\n        this._init(this._options);\r\n\r\n        if (dontCheckIfReady) {\r\n            // When dontCheckIfReady is true, we are in the new ThinXXX layer mode, so we must call _createTextureAndPostProcesses ourselves (it is called by EffectLayer otherwise)\r\n            this._createTextureAndPostProcesses();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the thin glow layer\r\n     * @returns the string with the class name of the glow layer\r\n     */\r\n    public getClassName(): string {\r\n        return \"GlowLayer\";\r\n    }\r\n\r\n    protected override async _importShadersAsync() {\r\n        if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../ShadersWGSL/glowMapMerge.fragment\"),\r\n                import(\"../ShadersWGSL/glowMapMerge.vertex\"),\r\n                import(\"../ShadersWGSL/glowBlurPostProcess.fragment\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/glowMapMerge.fragment\"), import(\"../Shaders/glowMapMerge.vertex\"), import(\"../Shaders/glowBlurPostProcess.fragment\")]);\r\n        }\r\n\r\n        await super._importShadersAsync();\r\n    }\r\n\r\n    public override getEffectName(): string {\r\n        return ThinGlowLayer.EffectName;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _internalShouldRender(): boolean {\r\n        if (this._options.excludeByDefault && !this._includedOnlyMeshes.length) {\r\n            return false;\r\n        }\r\n        return super._internalShouldRender();\r\n    }\r\n\r\n    public override _createMergeEffect(): Effect {\r\n        let defines = \"#define EMISSIVE \\n\";\r\n        if (this._options.ldrMerge) {\r\n            defines += \"#define LDR \\n\";\r\n        }\r\n\r\n        // Effect\r\n        return this._engine.createEffect(\r\n            \"glowMapMerge\",\r\n            [VertexBuffer.PositionKind],\r\n            [\"offset\"],\r\n            [\"textureSampler\", \"textureSampler2\"],\r\n            defines,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            this.shaderLanguage,\r\n            this._shadersLoaded\r\n                ? undefined\r\n                : async () => {\r\n                      await this._importShadersAsync();\r\n                      this._shadersLoaded = true;\r\n                  }\r\n        );\r\n    }\r\n\r\n    public override _createTextureAndPostProcesses(): void {\r\n        const effectiveKernel = this._getEffectiveBlurKernelSize();\r\n        this._horizontalBlurPostprocess1 = new ThinBlurPostProcess(\"GlowLayerHBP1\", this._scene.getEngine(), new Vector2(1.0, 0), effectiveKernel);\r\n        this._verticalBlurPostprocess1 = new ThinBlurPostProcess(\"GlowLayerVBP1\", this._scene.getEngine(), new Vector2(0, 1.0), effectiveKernel);\r\n\r\n        this._horizontalBlurPostprocess2 = new ThinBlurPostProcess(\"GlowLayerHBP2\", this._scene.getEngine(), new Vector2(1.0, 0), effectiveKernel);\r\n        this._verticalBlurPostprocess2 = new ThinBlurPostProcess(\"GlowLayerVBP2\", this._scene.getEngine(), new Vector2(0, 1.0), effectiveKernel);\r\n\r\n        this._postProcesses = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1, this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];\r\n    }\r\n\r\n    private _getEffectiveBlurKernelSize() {\r\n        return this._options.blurKernelSize / 2;\r\n    }\r\n\r\n    public override isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        const material = subMesh.getMaterial();\r\n        const mesh = subMesh.getRenderingMesh();\r\n\r\n        if (!material || !mesh) {\r\n            return false;\r\n        }\r\n\r\n        const emissiveTexture = (<any>material).emissiveTexture;\r\n        return super._isSubMeshReady(subMesh, useInstances, emissiveTexture);\r\n    }\r\n\r\n    public override _canRenderMesh(_mesh: AbstractMesh, _material: Material): boolean {\r\n        return true;\r\n    }\r\n\r\n    public override _internalCompose(effect: Effect): void {\r\n        // Texture\r\n        this.bindTexturesForCompose(effect);\r\n        effect.setFloat(\"offset\", this._intensity);\r\n\r\n        // Cache\r\n        const engine = this._engine;\r\n        const previousStencilBuffer = engine.getStencilBuffer();\r\n\r\n        // Draw order\r\n        engine.setStencilBuffer(false);\r\n\r\n        engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n\r\n        // Draw order\r\n        engine.setStencilBuffer(previousStencilBuffer);\r\n    }\r\n\r\n    public override _setEmissiveTextureAndColor(mesh: Mesh, subMesh: SubMesh, material: Material): void {\r\n        let textureLevel = 1.0;\r\n\r\n        if (this.customEmissiveTextureSelector) {\r\n            this._emissiveTextureAndColor.texture = this.customEmissiveTextureSelector(mesh, subMesh, material);\r\n        } else {\r\n            if (material) {\r\n                this._emissiveTextureAndColor.texture = (<any>material).emissiveTexture;\r\n                if (this._emissiveTextureAndColor.texture) {\r\n                    textureLevel = this._emissiveTextureAndColor.texture.level;\r\n                }\r\n            } else {\r\n                this._emissiveTextureAndColor.texture = null;\r\n            }\r\n        }\r\n\r\n        if (this.customEmissiveColorSelector) {\r\n            this.customEmissiveColorSelector(mesh, subMesh, material, this._emissiveTextureAndColor.color);\r\n        } else {\r\n            if ((<any>material).emissiveColor) {\r\n                const emissiveIntensity = (<PBRMaterial>material).emissiveIntensity ?? 1;\r\n                textureLevel *= emissiveIntensity;\r\n                this._emissiveTextureAndColor.color.set(\r\n                    (<any>material).emissiveColor.r * textureLevel,\r\n                    (<any>material).emissiveColor.g * textureLevel,\r\n                    (<any>material).emissiveColor.b * textureLevel,\r\n                    material.alpha\r\n                );\r\n            } else {\r\n                this._emissiveTextureAndColor.color.set(this.neutralColor.r, this.neutralColor.g, this.neutralColor.b, this.neutralColor.a);\r\n            }\r\n        }\r\n    }\r\n\r\n    public override _shouldRenderMesh(mesh: Mesh): boolean {\r\n        return this.hasMesh(mesh);\r\n    }\r\n\r\n    public override _addCustomEffectDefines(defines: string[]): void {\r\n        defines.push(\"#define GLOW\");\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the exclusion list to prevent it to impact or being impacted by the glow layer.\r\n     * This will not have an effect if meshes are excluded by default (see setExcludedByDefault).\r\n     * @param mesh The mesh to exclude from the glow layer\r\n     */\r\n    public addExcludedMesh(mesh: Mesh): void {\r\n        if (this._excludedMeshes.indexOf(mesh.uniqueId) === -1) {\r\n            this._excludedMeshes.push(mesh.uniqueId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the exclusion list to let it impact or being impacted by the glow layer.\r\n     * This will not have an effect if meshes are excluded by default (see setExcludedByDefault).\r\n     * @param mesh The mesh to remove\r\n     */\r\n    public removeExcludedMesh(mesh: Mesh): void {\r\n        const index = this._excludedMeshes.indexOf(mesh.uniqueId);\r\n        if (index !== -1) {\r\n            this._excludedMeshes.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the inclusion list to impact or being impacted by the glow layer.\r\n     * @param mesh The mesh to include in the glow layer\r\n     */\r\n    public addIncludedOnlyMesh(mesh: Mesh): void {\r\n        if (this._includedOnlyMeshes.indexOf(mesh.uniqueId) === -1) {\r\n            this._includedOnlyMeshes.push(mesh.uniqueId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the Inclusion list to prevent it to impact or being impacted by the glow layer.\r\n     * @param mesh The mesh to remove\r\n     */\r\n    public removeIncludedOnlyMesh(mesh: Mesh): void {\r\n        const index = this._includedOnlyMeshes.indexOf(mesh.uniqueId);\r\n        if (index !== -1) {\r\n            this._includedOnlyMeshes.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the excluded by default option.\r\n     * If true, all meshes will be excluded by default unless they are added to the inclusion list.\r\n     * @param value The boolean value to set the excluded by default option to\r\n     */\r\n    public setExcludedByDefault(value: boolean): void {\r\n        this._options.excludeByDefault = value;\r\n    }\r\n\r\n    public override hasMesh(mesh: AbstractMesh): boolean {\r\n        if (!super.hasMesh(mesh)) {\r\n            return false;\r\n        }\r\n\r\n        // Included Mesh\r\n        if (this._includedOnlyMeshes.length) {\r\n            return this._includedOnlyMeshes.indexOf(mesh.uniqueId) !== -1;\r\n        }\r\n\r\n        // Excluded Mesh\r\n        if (this._excludedMeshes.length) {\r\n            return this._excludedMeshes.indexOf(mesh.uniqueId) === -1;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    public override _useMeshMaterial(mesh: AbstractMesh): boolean {\r\n        // Specific case of material supporting glow directly\r\n        if (mesh.material?._supportGlowLayer) {\r\n            return true;\r\n        }\r\n\r\n        if (this._meshesUsingTheirOwnMaterials.length == 0) {\r\n            return false;\r\n        }\r\n\r\n        return this._meshesUsingTheirOwnMaterials.indexOf(mesh.uniqueId) > -1;\r\n    }\r\n\r\n    /**\r\n     * Add a mesh to be rendered through its own material and not with emissive only.\r\n     * @param mesh The mesh for which we need to use its material\r\n     */\r\n    public referenceMeshToUseItsOwnMaterial(mesh: AbstractMesh): void {\r\n        mesh.resetDrawCache(this._renderPassId);\r\n\r\n        this._meshesUsingTheirOwnMaterials.push(mesh.uniqueId);\r\n\r\n        mesh.onDisposeObservable.add(() => {\r\n            this._disposeMesh(mesh as Mesh);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from being rendered through its own material and not with emissive only.\r\n     * @param mesh The mesh for which we need to not use its material\r\n     * @param renderPassId The render pass id used when rendering the mesh\r\n     */\r\n    public unReferenceMeshFromUsingItsOwnMaterial(mesh: AbstractMesh, renderPassId: number): void {\r\n        let index = this._meshesUsingTheirOwnMaterials.indexOf(mesh.uniqueId);\r\n        while (index >= 0) {\r\n            this._meshesUsingTheirOwnMaterials.splice(index, 1);\r\n            index = this._meshesUsingTheirOwnMaterials.indexOf(mesh.uniqueId);\r\n        }\r\n        mesh.resetDrawCache(renderPassId);\r\n    }\r\n\r\n    /** @internal */\r\n    public _disposeMesh(mesh: Mesh): void {\r\n        this.removeIncludedOnlyMesh(mesh);\r\n        this.removeExcludedMesh(mesh);\r\n    }\r\n}\r\n","import {\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type DrawWrapper,\r\n    type FrameGraphRenderPass,\r\n    type FrameGraphRenderContext,\r\n    type EffectWrapper,\r\n    type IViewportLike,\r\n    type Nullable,\r\n    type IStencilStateProperties,\r\n} from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Task which applies a post process.\r\n */\r\nexport class FrameGraphPostProcessTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to apply the post process on.\r\n     * It's allowed to be undefined if the post process does not require a source texture.\r\n     * In that case, targetTexture must be provided.\r\n     */\r\n    public sourceTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the source texture.\r\n     */\r\n    public sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The target texture to render the post process to.\r\n     * If not supplied, a texture with the same configuration as the source texture will be created.\r\n     */\r\n    public targetTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The stencil state to use for the post process (optional).\r\n     */\r\n    public stencilState?: IStencilStateProperties;\r\n\r\n    /**\r\n     * The depth attachment texture to use for the post process (optional).\r\n     * Note that a post-process task never writes to the depth buffer: attaching a depth texture is only useful if you want to test against the depth/stencil aspect or write to the stencil buffer.\r\n     */\r\n    public depthAttachmentTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * If true, the depth attachment will be read-only.\r\n     * This means that the post process will not write to the depth buffer.\r\n     * Setting depthReadOnly and stencilReadOnly to true is useful when you want to also be able to bind this same depth/stencil attachment to a shader.\r\n     * Note that it will only work in WebGPU, as WebGL does not support read-only depth/stencil attachments.\r\n     */\r\n    public depthReadOnly = false;\r\n\r\n    /**\r\n     * If true, the stencil attachment will be read-only.\r\n     * This means that the post process will not write to the stencil buffer.\r\n     * Setting depthReadOnly and stencilReadOnly to true is useful when you want to also be able to bind this same depth/stencil attachment to a shader.\r\n     * Note that it will only work in WebGPU, as WebGL does not support read-only depth/stencil attachments.\r\n     */\r\n    public stencilReadOnly = false;\r\n\r\n    /**\r\n     * If true, color write will be disabled when applying the post process.\r\n     * This means that the post process will not write to the color buffer.\r\n     */\r\n    public disableColorWrite = false;\r\n\r\n    /**\r\n     * If true, the post process will be generated by a back face full-screen quad (CW order).\r\n     */\r\n    public drawBackFace = false;\r\n\r\n    /**\r\n     * If depth testing should be enabled (default is true).\r\n     */\r\n    public depthTest = true;\r\n\r\n    /**\r\n     * The alpha mode to use when applying the post process (default is ALPHA_DISABLE).\r\n     */\r\n    public get alphaMode(): number {\r\n        return this.postProcess.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(value: number) {\r\n        this.postProcess.alphaMode = value;\r\n    }\r\n\r\n    /**\r\n     * The viewport to use when applying the post process.\r\n     * If set to null, the currently active viewport is used.\r\n     * If undefined (default), the viewport is reset to a full screen viewport before applying the post process.\r\n     */\r\n    public viewport?: Nullable<IViewportLike>;\r\n\r\n    /**\r\n     * The output texture of the post process.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output depth attachment texture.\r\n     * This texture will point to the same texture than the depthAttachmentTexture property if it is set.\r\n     * Note, however, that the handle itself will be different!\r\n     */\r\n    public readonly outputDepthAttachmentTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The post process to apply.\r\n     */\r\n    public readonly postProcess: EffectWrapper;\r\n\r\n    /**\r\n     * The draw wrapper used by the post process\r\n     */\r\n    public get drawWrapper() {\r\n        return this._postProcessDrawWrapper;\r\n    }\r\n\r\n    protected readonly _postProcessDrawWrapper: DrawWrapper;\r\n    protected _sourceWidth: number;\r\n    protected _sourceHeight: number;\r\n    protected _outputWidth: number;\r\n    protected _outputHeight: number;\r\n\r\n    /**\r\n     * Constructs a new post process task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param postProcess The post process to apply.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, postProcess: EffectWrapper) {\r\n        super(name, frameGraph);\r\n\r\n        this.postProcess = postProcess;\r\n        this._postProcessDrawWrapper = this.postProcess.drawWrapper;\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.outputDepthAttachmentTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override isReady() {\r\n        return this.postProcess.isReady();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphPostProcessTask\";\r\n    }\r\n\r\n    public record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined && this.targetTexture === undefined) {\r\n            throw new Error(`FrameGraphPostProcessTask \"${this.name}\": sourceTexture or targetTexture is required`);\r\n        }\r\n\r\n        const sourceTextureCreationOptions = this.sourceTexture !== undefined ? this._frameGraph.textureManager.getTextureCreationOptions(this.sourceTexture) : undefined;\r\n        if (sourceTextureCreationOptions) {\r\n            sourceTextureCreationOptions.options.samples = 1;\r\n        }\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture, this.name, sourceTextureCreationOptions);\r\n        if (this.depthAttachmentTexture !== undefined) {\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputDepthAttachmentTexture, this.depthAttachmentTexture);\r\n        }\r\n\r\n        if (sourceTextureCreationOptions) {\r\n            const sourceSize = this._frameGraph.textureManager.getTextureAbsoluteDimensions(sourceTextureCreationOptions);\r\n\r\n            this._sourceWidth = sourceSize.width;\r\n            this._sourceHeight = sourceSize.height;\r\n        }\r\n\r\n        const outputTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.outputTexture);\r\n\r\n        this._outputWidth = outputTextureDescription.size.width;\r\n        this._outputHeight = outputTextureDescription.size.height;\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.depthReadOnly = this.depthReadOnly;\r\n        pass.stencilReadOnly = this.stencilReadOnly;\r\n\r\n        pass.addDependencies(this.sourceTexture);\r\n\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setRenderTargetDepth(this.depthAttachmentTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            context.pushDebugGroup(`Apply post-process (${this.name})`);\r\n            if (this.sourceTexture !== undefined) {\r\n                context.setTextureSamplingMode(this.sourceTexture, this.sourceSamplingMode);\r\n            }\r\n            additionalExecute?.(context);\r\n            if (this.viewport) {\r\n                context.setViewport(this.viewport);\r\n            }\r\n            context.applyFullScreenEffect(\r\n                this._postProcessDrawWrapper,\r\n                () => {\r\n                    if (this.sourceTexture !== undefined) {\r\n                        context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"textureSampler\", this.sourceTexture);\r\n                    }\r\n                    additionalBindings?.(context);\r\n                    this.postProcess.bind();\r\n                },\r\n                this.stencilState,\r\n                this.disableColorWrite,\r\n                this.drawBackFace,\r\n                this.depthTest,\r\n                this.viewport !== undefined\r\n            );\r\n            context.restoreDefaultFramebuffer();\r\n            context.popDebugGroup();\r\n        });\r\n\r\n        if (!skipCreationOfDisabledPasses) {\r\n            const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n            passDisabled.depthReadOnly = this.depthReadOnly;\r\n            passDisabled.stencilReadOnly = this.stencilReadOnly;\r\n\r\n            passDisabled.addDependencies(this.sourceTexture);\r\n\r\n            passDisabled.setRenderTarget(this.outputTexture);\r\n            passDisabled.setRenderTargetDepth(this.depthAttachmentTexture);\r\n            passDisabled.setExecuteFunc((context) => {\r\n                if (this.sourceTexture !== undefined && this.alphaMode === Constants.ALPHA_DISABLE) {\r\n                    if (this.viewport) {\r\n                        context.setViewport(this.viewport);\r\n                    }\r\n                    context.copyTexture(this.sourceTexture, undefined, this.viewport !== undefined);\r\n                }\r\n            });\r\n        }\r\n\r\n        return pass;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.postProcess.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderContext, type FrameGraphRenderPass } from \"core/index\";\r\nimport { ThinBlurPostProcess } from \"core/PostProcesses/thinBlurPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * Task which applies a blur post process.\r\n */\r\nexport class FrameGraphBlurTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinBlurPostProcess;\r\n\r\n    /**\r\n     * Constructs a new blur task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph Frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the blur effect.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinBlurPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinBlurPostProcess(name, frameGraph.engine, new Vector2(1, 0), 10));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphBlurTask\";\r\n    }\r\n\r\n    /**\r\n     * Records the blur task into the frame graph.\r\n     * @param skipCreationOfDisabledPasses defines whether disabled passes should be skipped\r\n     * @param additionalExecute defines an optional callback executed by the pass\r\n     * @param additionalBindings defines an optional callback used to bind extra resources\r\n     * @returns the recorded render pass\r\n     */\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.textureWidth = this._outputWidth; // should be _sourceWidth, but to avoid a breaking change, we use _outputWidth (BlurPostProcess uses _outputTexture to get width/height)\r\n        this.postProcess.textureHeight = this._outputHeight; // same as above for height\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import {\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type Scene,\r\n    type FrameGraphTextureCreationOptions,\r\n    type Effect,\r\n    type ThinBlurPostProcess,\r\n    type AbstractEngine,\r\n    type Nullable,\r\n    type Observer,\r\n    type RenderingGroupInfo,\r\n    type ThinEffectLayer,\r\n    type FrameGraphRenderPass,\r\n    type FrameGraphRenderContext,\r\n    type FrameGraphPass,\r\n    type FrameGraphContext,\r\n} from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { FrameGraphObjectRendererTask } from \"../Rendering/objectRendererTask\";\r\nimport { FrameGraphClearTextureTask } from \"../Texture/clearTextureTask\";\r\nimport { FrameGraphBlurTask } from \"../PostProcesses/blurTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphTextureManager } from \"../../frameGraphTextureManager\";\r\nimport { getDimensionsFromTextureSize } from \"../../../Materials/Textures/textureCreationOptions\";\r\nimport { FrameGraphPostProcessTask } from \"../PostProcesses/postProcessTask\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { ThinGlowBlurPostProcess } from \"../../../Layers/thinEffectLayer\";\r\nimport { FrameGraphExecuteTask } from \"../Misc/executeTask\";\r\n\r\n/** @internal */\r\nexport const enum FrameGraphBaseLayerBlurType {\r\n    None = \"none\",\r\n    Standard = \"standard\",\r\n    Glow = \"glow\",\r\n}\r\n\r\nclass FrameGraphGlowBlurTask extends FrameGraphPostProcessTask {\r\n    /**\r\n     * The thin glow blur post process used by the task.\r\n     */\r\n    public override readonly postProcess: ThinGlowBlurPostProcess;\r\n\r\n    /**\r\n     * Constructs a new glow blur task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the glow blur effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinGlowBlurPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinGlowBlurPostProcess(name, frameGraph.engine, new Vector2(1, 0), 1));\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FrameGraphGlowBlurTask\";\r\n    }\r\n\r\n    /**\r\n     * Records the glow blur task into the frame graph.\r\n     * @param skipCreationOfDisabledPasses defines whether disabled passes should be skipped\r\n     * @param additionalExecute defines an optional callback executed by the pass\r\n     * @param additionalBindings defines an optional callback used to bind extra resources\r\n     * @returns the recorded render pass\r\n     */\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.textureWidth = this._outputWidth;\r\n        this.postProcess.textureHeight = this._outputHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphBaseLayerTask extends FrameGraphTask {\r\n    /**\r\n     * The target texture to apply the effect layer to.\r\n     * The effect will be blended with the contents of this texture.\r\n     */\r\n    public targetTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The object renderer task used to render the objects in the texture to which the layer will be applied.\r\n     * This is needed because the layer may have to inject code in the rendering manager used by object renderer task.\r\n     */\r\n    public objectRendererTask: FrameGraphObjectRendererTask;\r\n\r\n    /**\r\n     * The layer texture to render the effect into.\r\n     * If not provided, a default texture will be created.\r\n     */\r\n    public layerTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture of the task (same as targetTexture, but the handle will be different).\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The layer object. Use this object to update the layer properties.\r\n     */\r\n    public readonly layer: ThinEffectLayer;\r\n\r\n    /**\r\n     * The name of the task.\r\n     */\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this._blurX) {\r\n            for (let i = 0; i < this._blurX.length; i++) {\r\n                this._blurX[i].name = `${name} Blur X${i}`;\r\n                this._blurY[i].name = `${name} Blur Y${i}`;\r\n            }\r\n        }\r\n\r\n        if (this._clearLayerTextureTask) {\r\n            this._clearLayerTextureTask.name = name + \" Clear Layer\";\r\n        }\r\n\r\n        if (this._objectRendererForLayerTask) {\r\n            this._objectRendererForLayerTask.name = name + \" Render to Layer\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the object renderer used to render the layer.\r\n     */\r\n    public get objectRendererForLayer() {\r\n        return this._objectRendererForLayerTask;\r\n    }\r\n\r\n    protected readonly _scene: Scene;\r\n    protected readonly _engine: AbstractEngine;\r\n    protected readonly _clearLayerTextureTask: FrameGraphClearTextureTask;\r\n    protected readonly _objectRendererForLayerTask: FrameGraphObjectRendererTask;\r\n    protected readonly _blurX: Array<FrameGraphBlurTask | FrameGraphGlowBlurTask> = [];\r\n    protected readonly _blurY: Array<FrameGraphBlurTask | FrameGraphGlowBlurTask> = [];\r\n    protected _layerTextureDimensions: { width: number; height: number };\r\n    private readonly _onBeforeBlurTask: Nullable<FrameGraphExecuteTask> = null;\r\n    private readonly _onAfterBlurTask: Nullable<FrameGraphExecuteTask> = null;\r\n    private _onBeforeObservableObserver: Nullable<Observer<number>> = null;\r\n    private _onBeforeObservableObserver2: Nullable<Observer<number>> = null;\r\n    private _onAfterObservableObserver: Nullable<Observer<number>> = null;\r\n    private _onAfterRenderingGroupObserver: Nullable<Observer<RenderingGroupInfo>> = null;\r\n\r\n    /**\r\n     * Constructs a new layer task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param scene The scene to render the layer in.\r\n     * @param layer The layer.\r\n     * @param numBlurPasses The number of blur passes applied by the layer.\r\n     * @param _blurType The type of blur to use for the layer.\r\n     * @param _setRenderTargetDepth If true, the task will set the render target depth.\r\n     * @param _notifyBlurObservable If true, the task will notify before and after blurring occurs.\r\n     * @param _setObjectList If true, the object list of the object renderer for the layer will be set to the object list of the object renderer task.\r\n     */\r\n    constructor(\r\n        name: string,\r\n        frameGraph: FrameGraph,\r\n        scene: Scene,\r\n        layer: ThinEffectLayer,\r\n        numBlurPasses: number,\r\n        private _blurType: FrameGraphBaseLayerBlurType = FrameGraphBaseLayerBlurType.Standard,\r\n        private _setRenderTargetDepth = false,\r\n        private _notifyBlurObservable = false,\r\n        private _setObjectList = true\r\n    ) {\r\n        super(name, frameGraph);\r\n\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n\r\n        this.layer = layer;\r\n        if (this._blurType !== FrameGraphBaseLayerBlurType.None) {\r\n            for (let i = 0; i < numBlurPasses; i++) {\r\n                if (this._blurType === FrameGraphBaseLayerBlurType.Glow) {\r\n                    this._blurX.push(new FrameGraphGlowBlurTask(`${name} Blur X${i}`, this._frameGraph, this.layer._postProcesses[1 + i * 2 + 0] as ThinGlowBlurPostProcess));\r\n                    this._blurY.push(new FrameGraphGlowBlurTask(`${name} Blur Y${i}`, this._frameGraph, this.layer._postProcesses[1 + i * 2 + 1] as ThinGlowBlurPostProcess));\r\n                } else {\r\n                    this._blurX.push(new FrameGraphBlurTask(`${name} Blur X${i}`, this._frameGraph, this.layer._postProcesses[i * 2 + 0] as ThinBlurPostProcess));\r\n                    this._blurY.push(new FrameGraphBlurTask(`${name} Blur Y${i}`, this._frameGraph, this.layer._postProcesses[i * 2 + 1] as ThinBlurPostProcess));\r\n                }\r\n            }\r\n        }\r\n\r\n        this._clearLayerTextureTask = new FrameGraphClearTextureTask(name + \" Clear Layer\", frameGraph);\r\n        this._clearLayerTextureTask.clearColor = true;\r\n        this._clearLayerTextureTask.clearDepth = true;\r\n\r\n        this._objectRendererForLayerTask = new FrameGraphObjectRendererTask(name + \" Render to Layer\", frameGraph, scene, undefined, this.layer.objectRenderer);\r\n\r\n        if (this._blurType !== FrameGraphBaseLayerBlurType.None && this._notifyBlurObservable) {\r\n            this._onBeforeBlurTask = new FrameGraphExecuteTask(name + \" On Before Blur\", frameGraph);\r\n            this._onAfterBlurTask = new FrameGraphExecuteTask(name + \" On After Blur\", frameGraph);\r\n\r\n            this._onBeforeBlurTask.func = () => {\r\n                if (this.layer.onBeforeBlurObservable.hasObservers()) {\r\n                    this.layer.onBeforeBlurObservable.notifyObservers(this.layer);\r\n                }\r\n            };\r\n            this._onAfterBlurTask.func = () => {\r\n                if (this.layer.onAfterBlurObservable.hasObservers()) {\r\n                    this.layer.onAfterBlurObservable.notifyObservers(this.layer);\r\n                }\r\n            };\r\n        }\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    /**\r\n     * Checks whether the layer task is ready.\r\n     * @returns true if the layer task is ready\r\n     */\r\n    public override isReady() {\r\n        return this._objectRendererForLayerTask.isReady() && this.layer.isLayerReady();\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FrameGraphBaseLayerTask\";\r\n    }\r\n\r\n    /**\r\n     * Records the layer task into the frame graph.\r\n     * @param _skipCreationOfDisabledPasses defines whether disabled passes should be skipped\r\n     * @param additionalComposeBindings defines an optional callback used to bind extra compose resources\r\n     */\r\n    public record(_skipCreationOfDisabledPasses?: boolean, additionalComposeBindings?: (context: FrameGraphRenderContext, effect: Effect) => void) {\r\n        if (this.targetTexture === undefined || this.objectRendererTask === undefined) {\r\n            throw new Error(`${this.constructor.name} \"${this.name}\": targetTexture and objectRendererTask are required`);\r\n        }\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);\r\n\r\n        // Uses the layerTexture or creates a color texture to render the layer to\r\n        let textureSize: {\r\n            width: number;\r\n            height: number;\r\n        };\r\n        let textureCreationOptions: FrameGraphTextureCreationOptions;\r\n\r\n        let colorLayerOutput: FrameGraphTextureHandle;\r\n\r\n        if (this.layerTexture) {\r\n            colorLayerOutput = this.layerTexture;\r\n            textureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.layerTexture);\r\n            textureSize = getDimensionsFromTextureSize(textureCreationOptions.size);\r\n            textureCreationOptions.size = textureSize;\r\n        } else {\r\n            const targetTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.targetTexture);\r\n            const fixedTextureSize = this.layer._options.mainTextureFixedSize ? Math.max(2, this.layer._options.mainTextureFixedSize) : 0;\r\n\r\n            textureSize = getDimensionsFromTextureSize(targetTextureCreationOptions.size);\r\n            textureSize.width = fixedTextureSize || Math.floor(textureSize.width * (this.layer._options.mainTextureRatio || 0.1)) || 1;\r\n            textureSize.height = fixedTextureSize || Math.floor(textureSize.height * (this.layer._options.mainTextureRatio || 0.1)) || 1;\r\n\r\n            textureCreationOptions = {\r\n                size: textureSize,\r\n                options: {\r\n                    createMipMaps: false,\r\n                    types: [this.layer._options.mainTextureType],\r\n                    formats: [this.layer._options.mainTextureFormat],\r\n                    samples: 1,\r\n                    useSRGBBuffers: [false],\r\n                    creationFlags: [0],\r\n                },\r\n                sizeIsPercentage: this.layer._options.mainTextureFixedSize ? false : targetTextureCreationOptions.sizeIsPercentage,\r\n            };\r\n            colorLayerOutput = this._frameGraph.textureManager.createRenderTargetTexture(`${this.name} Color`, textureCreationOptions);\r\n        }\r\n\r\n        this._layerTextureDimensions = this._frameGraph.textureManager.getTextureAbsoluteDimensions(textureCreationOptions);\r\n\r\n        // Creates a depth texture, used to render objects to the layer\r\n        // We don't reuse the depth texture of the objectRendererTask, as the size of the layer texture will generally be different (smaller).\r\n        const textureDepthCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: textureSize,\r\n            options: FrameGraphTextureManager.CloneTextureOptions(textureCreationOptions.options),\r\n            sizeIsPercentage: textureCreationOptions.sizeIsPercentage,\r\n        };\r\n\r\n        textureDepthCreationOptions.options.formats![0] = Constants.TEXTUREFORMAT_DEPTH32_FLOAT;\r\n\r\n        const depthLayerOutput = this._frameGraph.textureManager.createRenderTargetTexture(`${this.name} Depth`, textureDepthCreationOptions);\r\n\r\n        // Clears the textures\r\n        this._clearLayerTextureTask.targetTexture = colorLayerOutput;\r\n        this._clearLayerTextureTask.depthTexture = depthLayerOutput;\r\n        this._clearLayerTextureTask.color = this.layer.neutralColor;\r\n        this._clearLayerTextureTask.clearDepth = true;\r\n\r\n        const clearTaskPass = this._clearLayerTextureTask.record(true);\r\n\r\n        // Renders the objects to the layer texture\r\n        this._objectRendererForLayerTask.targetTexture = this._clearLayerTextureTask.outputTexture;\r\n        this._objectRendererForLayerTask.depthTexture = this._clearLayerTextureTask.outputDepthTexture;\r\n        this._objectRendererForLayerTask.camera = this.objectRendererTask.camera;\r\n        if (this._setObjectList) {\r\n            this._objectRendererForLayerTask.objectList = this.objectRendererTask.objectList;\r\n        }\r\n        this._objectRendererForLayerTask.disableShadows = true;\r\n\r\n        const objectRendererForLayerTaskPass = this._objectRendererForLayerTask.record(true);\r\n\r\n        // Blurs the layer color texture\r\n        let onBeforeBlurPass: FrameGraphPass<FrameGraphContext> | undefined;\r\n        let onAfterBlurPass: FrameGraphPass<FrameGraphContext> | undefined;\r\n\r\n        if (this._blurType !== FrameGraphBaseLayerBlurType.None) {\r\n            let blurTextureType: number;\r\n            if (this._engine.getCaps().textureHalfFloatRender) {\r\n                blurTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else {\r\n                blurTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            }\r\n\r\n            textureCreationOptions.options.types![0] = blurTextureType;\r\n\r\n            const blurTextureSizeRatio = (this.layer._options as any).blurTextureSizeRatio !== undefined ? (this.layer._options as any).blurTextureSizeRatio || 0.1 : undefined;\r\n            if (blurTextureSizeRatio !== undefined) {\r\n                textureSize.width = Math.floor(textureSize.width * blurTextureSizeRatio) || 1;\r\n                textureSize.height = Math.floor(textureSize.height * blurTextureSizeRatio) || 1;\r\n            }\r\n\r\n            onBeforeBlurPass = this._onBeforeBlurTask?.record();\r\n\r\n            const blurPasses: FrameGraphRenderPass[] = [];\r\n\r\n            for (let i = 0; i < this._blurX.length; i++) {\r\n                const blurXTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._blurX[i].name, textureCreationOptions);\r\n\r\n                this._blurX[i].sourceTexture = i === 0 ? this._objectRendererForLayerTask.outputTexture : this._blurY[i - 1].outputTexture;\r\n                this._blurX[i].sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n                this._blurX[i].targetTexture = blurXTextureHandle;\r\n                blurPasses.push(this._blurX[i].record(true));\r\n\r\n                const blurYTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._blurY[i].name, textureCreationOptions);\r\n\r\n                this._blurY[i].sourceTexture = this._blurX[i].outputTexture;\r\n                this._blurY[i].sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n                this._blurY[i].targetTexture = blurYTextureHandle;\r\n                blurPasses.push(this._blurY[i].record(true));\r\n\r\n                textureSize.width = textureSize.width >> 1;\r\n                textureSize.height = textureSize.height >> 1;\r\n            }\r\n\r\n            onAfterBlurPass = this._onAfterBlurTask?.record();\r\n\r\n            this.objectRendererTask.objectRenderer.onBeforeRenderObservable.remove(this._onBeforeObservableObserver2);\r\n            this._onBeforeObservableObserver2 = this.objectRendererTask.objectRenderer.onBeforeRenderObservable.add(() => {\r\n                const shouldRender = this.layer.shouldRender();\r\n\r\n                if (onBeforeBlurPass) {\r\n                    onBeforeBlurPass.disabled = !shouldRender;\r\n                }\r\n                for (let i = 0; i < blurPasses.length; i++) {\r\n                    blurPasses[i].disabled = !shouldRender;\r\n                }\r\n                if (onAfterBlurPass) {\r\n                    onAfterBlurPass.disabled = !shouldRender;\r\n                }\r\n            });\r\n        }\r\n\r\n        // Enables stencil (if stencil is needed) when rendering objects to the main texture\r\n        // We also disable the internal passes if the layer should not render\r\n        this.objectRendererTask.objectRenderer.onBeforeRenderObservable.remove(this._onBeforeObservableObserver);\r\n        this._onBeforeObservableObserver = this.objectRendererTask.objectRenderer.onBeforeRenderObservable.add(() => {\r\n            const shouldRender = this.layer.shouldRender();\r\n\r\n            clearTaskPass.disabled = !shouldRender;\r\n            objectRendererForLayerTaskPass.disabled = !shouldRender;\r\n\r\n            if (shouldRender && this.layer.needStencil()) {\r\n                this._engine.setStencilBuffer(true);\r\n                this._engine.setStencilFunctionReference(1);\r\n            }\r\n        });\r\n\r\n        this.objectRendererTask.objectRenderer.onAfterRenderObservable.remove(this._onAfterObservableObserver);\r\n        this._onAfterObservableObserver = this.objectRendererTask.objectRenderer.onAfterRenderObservable.add(() => {\r\n            if (this.layer.shouldRender() && this.layer.needStencil()) {\r\n                this._engine.setStencilBuffer(false);\r\n            }\r\n        });\r\n\r\n        // Composes the layer with the target texture\r\n        this.layer.bindTexturesForCompose = undefined as any;\r\n\r\n        this._clearAfterRenderingGroupObserver();\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        for (let i = 0; i < this._blurY.length; i++) {\r\n            pass.addDependencies(this._blurY[i].outputTexture);\r\n        }\r\n\r\n        pass.setRenderTarget(this.outputTexture);\r\n        if (this._setRenderTargetDepth) {\r\n            pass.setRenderTargetDepth(this.objectRendererTask.depthTexture);\r\n        }\r\n        pass.setInitializeFunc((context) => {\r\n            this.layer.bindTexturesForCompose = (effect: Effect) => {\r\n                for (let i = 0; i < this._blurY.length; i++) {\r\n                    context.bindTextureHandle(effect, `textureSampler${i > 0 ? i + 1 : \"\"}`, this._blurY[i].outputTexture);\r\n                }\r\n                additionalComposeBindings?.(context, effect);\r\n            };\r\n\r\n            if (this.layer._options.renderingGroupId === -1) {\r\n                return;\r\n            }\r\n\r\n            this._onAfterRenderingGroupObserver = this._scene.onAfterRenderingGroupObservable.add((info) => {\r\n                if (\r\n                    !this.layer.shouldRender() ||\r\n                    info.renderingGroupId !== this.layer._options.renderingGroupId ||\r\n                    info.renderingManager !== this.objectRendererTask.objectRenderer.renderingManager\r\n                ) {\r\n                    return;\r\n                }\r\n                if (this._setObjectList) {\r\n                    this._objectRendererForLayerTask.objectList = this.objectRendererTask.objectList;\r\n                }\r\n                context.saveDepthStates();\r\n                context.setDepthStates(false, false);\r\n                context._applyRenderTarget();\r\n                this.layer.compose();\r\n                context.restoreDepthStates();\r\n            });\r\n        });\r\n        pass.setExecuteFunc((context) => {\r\n            if (this._blurY.length > 0) {\r\n                context.setTextureSamplingMode(this._blurY[this._blurY.length - 1].targetTexture!, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            }\r\n\r\n            if (this.layer._options.renderingGroupId === -1 && this.layer.shouldRender()) {\r\n                if (this._setObjectList) {\r\n                    this._objectRendererForLayerTask.objectList = this.objectRendererTask.objectList; // in case the object list has changed in objectRendererTask\r\n                }\r\n\r\n                context.setDepthStates(false, false);\r\n                context._applyRenderTarget();\r\n\r\n                this.layer.compose();\r\n            }\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        if (this._setRenderTargetDepth) {\r\n            passDisabled.setRenderTargetDepth(this.objectRendererTask.depthTexture);\r\n        }\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n\r\n    private _clearAfterRenderingGroupObserver() {\r\n        this._scene.onAfterRenderingGroupObservable.remove(this._onAfterRenderingGroupObserver);\r\n        this._onAfterRenderingGroupObserver = null;\r\n    }\r\n\r\n    /**\r\n     * Disposes the layer task and its dependent tasks.\r\n     */\r\n    public override dispose(): void {\r\n        this._clearAfterRenderingGroupObserver();\r\n        this._clearLayerTextureTask.dispose();\r\n        this._objectRendererForLayerTask.dispose();\r\n        this._onBeforeBlurTask?.dispose();\r\n        this._onAfterBlurTask?.dispose();\r\n        this.layer.dispose();\r\n        for (let i = 0; i < this._blurX.length; i++) {\r\n            this._blurX[i].dispose();\r\n            this._blurY[i].dispose();\r\n        }\r\n        super.dispose();\r\n    }\r\n}\r\n","import { type FrameGraph, type Scene, type IThinGlowLayerOptions } from \"core/index\";\r\nimport { ThinGlowLayer } from \"core/Layers/thinGlowLayer\";\r\nimport { FrameGraphBaseLayerTask } from \"./baseLayerTask\";\r\n\r\n/**\r\n * Task which applies a glowing effect to a texture.\r\n */\r\nexport class FrameGraphGlowLayerTask extends FrameGraphBaseLayerTask {\r\n    /**\r\n     * The glow layer object. Use this object to update the glow layer properties (e.g. intensity, blur kernel size).\r\n     */\r\n    public override readonly layer: ThinGlowLayer;\r\n\r\n    /**\r\n     * Constructs a new glow layer task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param scene The scene to render the glow layer in.\r\n     * @param options Options for the glow layer.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene, options?: IThinGlowLayerOptions) {\r\n        super(name, frameGraph, scene, new ThinGlowLayer(name, scene, options, true), 2);\r\n\r\n        this.layer._renderPassId = this._objectRendererForLayerTask.objectRenderer.renderPassId;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphGlowLayerTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type Scene,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type NodeRenderGraphConnectionPoint,\r\n    type FrameGraphObjectRendererTask,\r\n} from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointDirection } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphGlowLayerTask } from \"core/FrameGraph/Tasks/Layers/glowLayerTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { NodeRenderGraphConnectionPointCustomObject } from \"../../nodeRenderGraphConnectionPointCustomObject\";\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"../Rendering/baseObjectRendererBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the glow layer\r\n */\r\nexport class NodeRenderGraphGlowLayerBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphGlowLayerTask;\r\n\r\n    public override _additionalConstructionParameters: [boolean, number, number | undefined, number];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphGlowLayerBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param ldrMerge Forces the merge step to be done in ldr (clamp values &gt; 1). Default: false\r\n     * @param layerTextureRatio multiplication factor applied to the main texture size to compute the size of the layer render target texture (default: 0.5)\r\n     * @param layerTextureFixedSize defines the fixed size of the layer render target texture. Takes precedence over layerTextureRatio if provided (default: undefined)\r\n     * @param layerTextureType defines the type of the layer texture (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        frameGraph: FrameGraph,\r\n        scene: Scene,\r\n        ldrMerge = false,\r\n        layerTextureRatio = 0.5,\r\n        layerTextureFixedSize?: number,\r\n        layerTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [ldrMerge, layerTextureRatio, layerTextureFixedSize, layerTextureType];\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"layer\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\r\n            \"objectRenderer\",\r\n            NodeRenderGraphBlockConnectionPointTypes.Object,\r\n            false,\r\n            new NodeRenderGraphConnectionPointCustomObject(\r\n                \"objectRenderer\",\r\n                this,\r\n                NodeRenderGraphConnectionPointDirection.Input,\r\n                NodeRenderGraphBaseObjectRendererBlock,\r\n                \"NodeRenderGraphBaseObjectRendererBlock\"\r\n            )\r\n        );\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBufferDepthStencil);\r\n        this.layer.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n\r\n        this.output._typeConnectionSource = this.target;\r\n\r\n        this._frameGraphTask = new FrameGraphGlowLayerTask(this.name, this._frameGraph, this._scene, {\r\n            ldrMerge,\r\n            mainTextureRatio: layerTextureRatio,\r\n            mainTextureFixedSize: layerTextureFixedSize,\r\n            mainTextureType: layerTextureType,\r\n        });\r\n    }\r\n\r\n    private _createTask(ldrMerge: boolean, layerTextureRatio: number, layerTextureFixedSize: number, layerTextureType: number) {\r\n        const blurKernelSize = this.blurKernelSize;\r\n        const intensity = this.intensity;\r\n\r\n        this._frameGraphTask?.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphGlowLayerTask(this.name, this._frameGraph, this._scene, {\r\n            ldrMerge,\r\n            mainTextureRatio: layerTextureRatio,\r\n            mainTextureFixedSize: layerTextureFixedSize,\r\n            mainTextureType: layerTextureType,\r\n        });\r\n\r\n        this.blurKernelSize = blurKernelSize;\r\n        this.intensity = intensity;\r\n\r\n        this._additionalConstructionParameters = [ldrMerge, layerTextureRatio, layerTextureFixedSize, layerTextureType];\r\n    }\r\n\r\n    /** Forces the merge step to be done in ldr (clamp values &gt; 1). Default: false */\r\n    @editableInPropertyPage(\"LDR merge\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get ldrMerge() {\r\n        return this._frameGraphTask.layer.ldrMerge;\r\n    }\r\n\r\n    public set ldrMerge(value: boolean) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(value, options.mainTextureRatio, options.mainTextureFixedSize, options.mainTextureType);\r\n    }\r\n\r\n    /** Multiplication factor applied to the main texture size to compute the size of the layer render target texture */\r\n    @editableInPropertyPage(\"Layer texture ratio\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get layerTextureRatio() {\r\n        return this._frameGraphTask.layer._options.mainTextureRatio;\r\n    }\r\n\r\n    public set layerTextureRatio(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.ldrMerge, value, options.mainTextureFixedSize, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the fixed size of the layer render target texture. Takes precedence over layerTextureRatio if provided */\r\n    @editableInPropertyPage(\"Layer texture fixed size\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get layerTextureFixedSize() {\r\n        return this._frameGraphTask.layer._options.mainTextureFixedSize;\r\n    }\r\n\r\n    public set layerTextureFixedSize(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.ldrMerge, options.mainTextureRatio, value, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the type of the layer texture */\r\n    @editableInPropertyPage(\"Layer texture type\", PropertyTypeForEdition.TextureType, \"PROPERTIES\")\r\n    public get layerTextureType() {\r\n        return this._frameGraphTask.layer._options.mainTextureType;\r\n    }\r\n\r\n    public set layerTextureType(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.ldrMerge, options.mainTextureRatio, options.mainTextureFixedSize, value);\r\n    }\r\n\r\n    /** How big is the kernel of the blur texture */\r\n    @editableInPropertyPage(\"Blur kernel size\", PropertyTypeForEdition.Int, \"PROPERTIES\", { min: 1, max: 256 })\r\n    public get blurKernelSize() {\r\n        return this._frameGraphTask.layer.blurKernelSize;\r\n    }\r\n\r\n    public set blurKernelSize(value: number) {\r\n        this._frameGraphTask.layer.blurKernelSize = value;\r\n    }\r\n\r\n    /** The intensity of the glow */\r\n    @editableInPropertyPage(\"Intensity\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 5 })\r\n    public get intensity() {\r\n        return this._frameGraphTask.layer.intensity;\r\n    }\r\n\r\n    public set intensity(value: number) {\r\n        this._frameGraphTask.layer.intensity = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphGlowLayerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target texture input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the layer texture input component\r\n     */\r\n    public get layer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the objectRenderer input component\r\n     */\r\n    public get objectRenderer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.layerTexture = this.layer.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.objectRendererTask = this.objectRenderer.connectedPoint?.value as FrameGraphObjectRendererTask;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.blurKernelSize = ${this.blurKernelSize};`);\r\n        codes.push(`${this._codeVariableName}.intensity = ${this.intensity};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.blurKernelSize = this.blurKernelSize;\r\n        serializationObject.intensity = this.intensity;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.blurKernelSize = serializationObject.blurKernelSize;\r\n        this.intensity = serializationObject.intensity;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for glowLayerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGlowLayerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphGlowLayerBlock\", NodeRenderGraphGlowLayerBlock);\r\n}\r\n","import {\r\n    type Observer,\r\n    type Nullable,\r\n    type Scene,\r\n    type SubMesh,\r\n    type AbstractMesh,\r\n    type Mesh,\r\n    type Effect,\r\n    type IThinEffectLayerOptions,\r\n    type Color3,\r\n    type EffectWrapper,\r\n} from \"core/index\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { ThinPassPostProcess } from \"../PostProcesses/thinPassPostProcess\";\r\nimport { ThinEffectLayer, ThinGlowBlurPostProcess } from \"./thinEffectLayer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ThinBlurPostProcess } from \"core/PostProcesses/thinBlurPostProcess\";\r\n\r\ninterface IBlurPostProcess extends EffectWrapper {\r\n    kernel: number;\r\n}\r\n\r\n/**\r\n * Highlight layer options. This helps customizing the behaviour\r\n * of the highlight layer.\r\n */\r\nexport interface IThinHighlightLayerOptions extends IThinEffectLayerOptions {\r\n    /**\r\n     * Multiplication factor apply to the main texture size in the first step of the blur to reduce the size\r\n     * of the picture to blur (the smaller the faster). Default: 0.5\r\n     */\r\n    blurTextureSizeRatio?: number;\r\n\r\n    /**\r\n     * How big in texel of the blur texture is the vertical blur. Default: 1\r\n     */\r\n    blurVerticalSize?: number;\r\n\r\n    /**\r\n     * How big in texel of the blur texture is the horizontal blur. Default: 1\r\n     */\r\n    blurHorizontalSize?: number;\r\n\r\n    /**\r\n     * Should we display highlight as a solid stroke? Default: false\r\n     */\r\n    isStroke?: boolean;\r\n\r\n    /**\r\n     * Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    forceGLSL?: boolean;\r\n}\r\n\r\n/**\r\n * Storage interface grouping all the information required for glowing a mesh.\r\n */\r\ninterface IHighlightLayerMesh {\r\n    /**\r\n     * The glowy mesh\r\n     */\r\n    mesh: Mesh;\r\n    /**\r\n     * The color of the glow\r\n     */\r\n    color: Color3;\r\n    /**\r\n     * The mesh render callback use to insert stencil information\r\n     */\r\n    observerHighlight: Nullable<Observer<Mesh>>;\r\n    /**\r\n     * The mesh render callback use to come to the default behavior\r\n     */\r\n    observerDefault: Nullable<Observer<Mesh>>;\r\n    /**\r\n     * If it exists, the emissive color of the material will be used to generate the glow.\r\n     * Else it falls back to the current color.\r\n     */\r\n    glowEmissiveOnly: boolean;\r\n}\r\n\r\n/**\r\n * Storage interface grouping all the information required for an excluded mesh.\r\n */\r\ninterface IHighlightLayerExcludedMesh {\r\n    /**\r\n     * The glowy mesh\r\n     */\r\n    mesh: Mesh;\r\n    /**\r\n     * The mesh render callback use to prevent stencil use\r\n     */\r\n    beforeBind: Nullable<Observer<Mesh>>;\r\n    /**\r\n     * The mesh render callback use to restore previous stencil use\r\n     */\r\n    afterRender: Nullable<Observer<Mesh>>;\r\n    /**\r\n     * Current stencil state of the engine\r\n     */\r\n    stencilState: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinHighlightLayer extends ThinEffectLayer {\r\n    /**\r\n     * Effect Name of the highlight layer.\r\n     */\r\n    public static readonly EffectName = \"HighlightLayer\";\r\n\r\n    /**\r\n     * The neutral color used during the preparation of the glow effect.\r\n     * This is black by default as the blend operation is a blend operation.\r\n     */\r\n    public static NeutralColor: Color4 = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * Stencil value used for glowing meshes.\r\n     */\r\n    public static GlowingMeshStencilReference = 0x02;\r\n\r\n    /**\r\n     * Stencil value used for the other meshes in the scene.\r\n     */\r\n    public static NormalMeshStencilReference = 0x01;\r\n\r\n    /**\r\n     * Specifies whether or not the inner glow is ACTIVE in the layer.\r\n     */\r\n    public innerGlow: boolean = true;\r\n\r\n    /**\r\n     * Specifies whether or not the outer glow is ACTIVE in the layer.\r\n     */\r\n    public outerGlow: boolean = true;\r\n\r\n    /**\r\n     * Specifies the horizontal size of the blur.\r\n     */\r\n    public set blurHorizontalSize(value: number) {\r\n        this._horizontalBlurPostprocess.kernel = value;\r\n        this._options.blurHorizontalSize = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies the vertical size of the blur.\r\n     */\r\n    public set blurVerticalSize(value: number) {\r\n        this._verticalBlurPostprocess.kernel = value;\r\n        this._options.blurVerticalSize = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the horizontal size of the blur.\r\n     */\r\n    public get blurHorizontalSize(): number {\r\n        return this._horizontalBlurPostprocess.kernel;\r\n    }\r\n\r\n    /**\r\n     * Gets the vertical size of the blur.\r\n     */\r\n    public get blurVerticalSize(): number {\r\n        return this._verticalBlurPostprocess.kernel;\r\n    }\r\n\r\n    private _instanceGlowingMeshStencilReference = ThinHighlightLayer.GlowingMeshStencilReference++;\r\n\r\n    /** @internal */\r\n    public override _options: Required<IThinHighlightLayerOptions>;\r\n\r\n    private _downSamplePostprocess: ThinPassPostProcess;\r\n    private _horizontalBlurPostprocess: IBlurPostProcess;\r\n    private _verticalBlurPostprocess: IBlurPostProcess;\r\n\r\n    /** @internal */\r\n    public _meshes: Nullable<{ [id: string]: Nullable<IHighlightLayerMesh> }> = {};\r\n    /** @internal */\r\n    public _excludedMeshes: Nullable<{ [id: string]: Nullable<IHighlightLayerExcludedMesh> }> = {};\r\n\r\n    /** @internal */\r\n    public _mainObjectRendererRenderPassId = -1;\r\n\r\n    /**\r\n     * Gets the stencil reference value used for the meshes rendered by the highlight layer.\r\n     */\r\n    public get stencilReference(): number {\r\n        return this._instanceGlowingMeshStencilReference << (8 - this.numStencilBits);\r\n    }\r\n\r\n    /**\r\n     * Number of stencil bits used by the highlight layer (default: 8).\r\n     * The layer uses the numStencilBits highest bits of the stencil buffer.\r\n     */\r\n    public numStencilBits = 8;\r\n\r\n    /**\r\n     * Instantiates a new highlight Layer and references it to the scene..\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param options Sets of none mandatory options to use with the layer (see IHighlightLayerOptions for more information)\r\n     * @param dontCheckIfReady Specifies if the layer should disable checking whether all the post processes are ready (default: false). To save performance, this should be set to true and you should call `isReady` manually before rendering to the layer.\r\n     */\r\n    constructor(name: string, scene?: Scene, options?: Partial<IThinHighlightLayerOptions>, dontCheckIfReady = false) {\r\n        super(name, scene, options !== undefined ? !!options.forceGLSL : false);\r\n\r\n        this.neutralColor = ThinHighlightLayer.NeutralColor;\r\n\r\n        // Adapt options\r\n        this._options = {\r\n            mainTextureRatio: 0.5,\r\n            blurTextureSizeRatio: 0.5,\r\n            mainTextureFixedSize: 0,\r\n            blurHorizontalSize: 1.0,\r\n            blurVerticalSize: 1.0,\r\n            alphaBlendingMode: Constants.ALPHA_COMBINE,\r\n            camera: null,\r\n            renderingGroupId: -1,\r\n            forceGLSL: false,\r\n            mainTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            mainTextureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            isStroke: false,\r\n            ...options,\r\n        };\r\n\r\n        // Initialize the layer\r\n        this._init(this._options);\r\n\r\n        // Do not render as long as no meshes have been added\r\n        this._shouldRender = false;\r\n\r\n        if (dontCheckIfReady) {\r\n            // When dontCheckIfReady is true, we are in the new ThinXXX layer mode, so we must call _createTextureAndPostProcesses ourselves (it is called by EffectLayer otherwise)\r\n            this._createTextureAndPostProcesses();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the effect layer\r\n     * @returns the string with the class name of the effect layer\r\n     */\r\n    public getClassName(): string {\r\n        return \"HighlightLayer\";\r\n    }\r\n\r\n    protected override async _importShadersAsync() {\r\n        if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../ShadersWGSL/glowMapMerge.fragment\"),\r\n                import(\"../ShadersWGSL/glowMapMerge.vertex\"),\r\n                import(\"../ShadersWGSL/glowBlurPostProcess.fragment\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/glowMapMerge.fragment\"), import(\"../Shaders/glowMapMerge.vertex\"), import(\"../Shaders/glowBlurPostProcess.fragment\")]);\r\n        }\r\n\r\n        await super._importShadersAsync();\r\n    }\r\n\r\n    public override getEffectName(): string {\r\n        return ThinHighlightLayer.EffectName;\r\n    }\r\n\r\n    public override _numInternalDraws(): number {\r\n        return 2; // we need two rendering, one for the inner glow and the other for the outer glow\r\n    }\r\n\r\n    public override _createMergeEffect(): Effect {\r\n        return this._engine.createEffect(\r\n            \"glowMapMerge\",\r\n            [VertexBuffer.PositionKind],\r\n            [\"offset\"],\r\n            [\"textureSampler\"],\r\n            this._options.isStroke ? \"#define STROKE \\n\" : undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            this._shaderLanguage,\r\n            this._shadersLoaded\r\n                ? undefined\r\n                : async () => {\r\n                      await this._importShadersAsync();\r\n                      this._shadersLoaded = true;\r\n                  }\r\n        );\r\n    }\r\n\r\n    public override _createTextureAndPostProcesses(): void {\r\n        if (this._options.alphaBlendingMode === Constants.ALPHA_COMBINE) {\r\n            this._downSamplePostprocess = new ThinPassPostProcess(\"HighlightLayerPPP\", this._scene.getEngine());\r\n            this._horizontalBlurPostprocess = new ThinGlowBlurPostProcess(\"HighlightLayerHBP\", this._scene.getEngine(), new Vector2(1.0, 0), this._options.blurHorizontalSize);\r\n            this._verticalBlurPostprocess = new ThinGlowBlurPostProcess(\"HighlightLayerVBP\", this._scene.getEngine(), new Vector2(0, 1.0), this._options.blurVerticalSize);\r\n            this._postProcesses = [this._downSamplePostprocess, this._horizontalBlurPostprocess, this._verticalBlurPostprocess];\r\n        } else {\r\n            this._horizontalBlurPostprocess = new ThinBlurPostProcess(\"HighlightLayerHBP\", this._scene.getEngine(), new Vector2(1.0, 0), this._options.blurHorizontalSize / 2);\r\n            this._verticalBlurPostprocess = new ThinBlurPostProcess(\"HighlightLayerVBP\", this._scene.getEngine(), new Vector2(0, 1.0), this._options.blurVerticalSize / 2);\r\n            this._postProcesses = [this._horizontalBlurPostprocess, this._verticalBlurPostprocess];\r\n        }\r\n    }\r\n\r\n    public override needStencil(): boolean {\r\n        return true;\r\n    }\r\n\r\n    public override isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        const material = subMesh.getMaterial();\r\n        const mesh = subMesh.getRenderingMesh();\r\n\r\n        if (!material || !mesh || !this._meshes) {\r\n            return false;\r\n        }\r\n\r\n        let emissiveTexture: Nullable<any> = null;\r\n        const highlightLayerMesh = this._meshes[mesh.uniqueId];\r\n\r\n        if (highlightLayerMesh && highlightLayerMesh.glowEmissiveOnly && material) {\r\n            emissiveTexture = (<any>material).emissiveTexture;\r\n        }\r\n        return super._isSubMeshReady(subMesh, useInstances, emissiveTexture);\r\n    }\r\n\r\n    public override _canRenderMesh(_mesh: AbstractMesh, _material: Material): boolean {\r\n        // all meshes can be rendered in the highlight layer, even transparent ones\r\n        return true;\r\n    }\r\n\r\n    public override _internalCompose(effect: Effect, renderIndex: number): void {\r\n        // Texture\r\n        this.bindTexturesForCompose(effect);\r\n\r\n        // Cache\r\n        const engine = this._engine;\r\n        engine.cacheStencilState();\r\n\r\n        // Stencil operations\r\n        engine.setStencilOperationPass(Constants.REPLACE);\r\n        engine.setStencilOperationFail(Constants.KEEP);\r\n        engine.setStencilOperationDepthFail(Constants.KEEP);\r\n\r\n        // Draw order\r\n        engine.setStencilMask(0x00);\r\n        engine.setStencilBuffer(true);\r\n        engine.setStencilFunctionReference(this._instanceGlowingMeshStencilReference << (8 - this.numStencilBits));\r\n        engine.setStencilFunctionMask(255 - ((1 << (8 - this.numStencilBits)) - 1));\r\n\r\n        // 2 passes inner outer\r\n        if (this.outerGlow && renderIndex === 0) {\r\n            // the outer glow is rendered the first time _internalRender is called, so when renderIndex == 0 (and only if outerGlow is enabled)\r\n            effect.setFloat(\"offset\", 0);\r\n            engine.setStencilFunction(Constants.NOTEQUAL);\r\n            engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n        }\r\n        if (this.innerGlow && renderIndex === 1) {\r\n            // the inner glow is rendered the second time _internalRender is called, so when renderIndex == 1 (and only if innerGlow is enabled)\r\n            effect.setFloat(\"offset\", 1);\r\n            engine.setStencilFunction(Constants.EQUAL);\r\n            engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n        }\r\n\r\n        // Restore Cache\r\n        engine.restoreStencilState();\r\n    }\r\n\r\n    public override _setEmissiveTextureAndColor(mesh: Mesh, _subMesh: SubMesh, material: Material): void {\r\n        const highlightLayerMesh = this._meshes![mesh.uniqueId];\r\n        if (highlightLayerMesh) {\r\n            this._emissiveTextureAndColor.color.set(highlightLayerMesh.color.r, highlightLayerMesh.color.g, highlightLayerMesh.color.b, 1.0);\r\n        } else {\r\n            this._emissiveTextureAndColor.color.set(this.neutralColor.r, this.neutralColor.g, this.neutralColor.b, this.neutralColor.a);\r\n        }\r\n\r\n        if (highlightLayerMesh && highlightLayerMesh.glowEmissiveOnly && material) {\r\n            this._emissiveTextureAndColor.texture = (<any>material).emissiveTexture;\r\n            this._emissiveTextureAndColor.color.set(1.0, 1.0, 1.0, 1.0);\r\n        } else {\r\n            this._emissiveTextureAndColor.texture = null;\r\n        }\r\n    }\r\n\r\n    public override shouldRender(): boolean {\r\n        return this._meshes && super.shouldRender() ? true : false;\r\n    }\r\n\r\n    public override _shouldRenderMesh(mesh: Mesh): boolean {\r\n        if (this._excludedMeshes && this._excludedMeshes[mesh.uniqueId]) {\r\n            return false;\r\n        }\r\n\r\n        return super.hasMesh(mesh);\r\n    }\r\n\r\n    public override _addCustomEffectDefines(defines: string[]): void {\r\n        defines.push(\"#define HIGHLIGHT\");\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the exclusion list to prevent it to impact or being impacted by the highlight layer.\r\n     * @param mesh The mesh to exclude from the highlight layer\r\n     */\r\n    public addExcludedMesh(mesh: Mesh) {\r\n        if (!this._excludedMeshes) {\r\n            return;\r\n        }\r\n\r\n        const meshExcluded = this._excludedMeshes[mesh.uniqueId];\r\n        if (!meshExcluded) {\r\n            const obj: IHighlightLayerExcludedMesh = {\r\n                mesh: mesh,\r\n                beforeBind: null,\r\n                afterRender: null,\r\n                stencilState: false,\r\n            };\r\n\r\n            obj.beforeBind = mesh.onBeforeBindObservable.add((mesh: Mesh) => {\r\n                if (this._mainObjectRendererRenderPassId !== -1 && this._mainObjectRendererRenderPassId !== this._engine.currentRenderPassId) {\r\n                    return;\r\n                }\r\n                obj.stencilState = mesh.getEngine().getStencilBuffer();\r\n                mesh.getEngine().setStencilBuffer(false);\r\n            });\r\n\r\n            obj.afterRender = mesh.onAfterRenderObservable.add((mesh: Mesh) => {\r\n                if (this._mainObjectRendererRenderPassId !== -1 && this._mainObjectRendererRenderPassId !== this._engine.currentRenderPassId) {\r\n                    return;\r\n                }\r\n                mesh.getEngine().setStencilBuffer(obj.stencilState);\r\n            });\r\n\r\n            this._excludedMeshes[mesh.uniqueId] = obj;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the exclusion list to let it impact or being impacted by the highlight layer.\r\n     * @param mesh The mesh to highlight\r\n     */\r\n    public removeExcludedMesh(mesh: Mesh) {\r\n        if (!this._excludedMeshes) {\r\n            return;\r\n        }\r\n\r\n        const meshExcluded = this._excludedMeshes[mesh.uniqueId];\r\n        if (meshExcluded) {\r\n            if (meshExcluded.beforeBind) {\r\n                mesh.onBeforeBindObservable.remove(meshExcluded.beforeBind);\r\n            }\r\n\r\n            if (meshExcluded.afterRender) {\r\n                mesh.onAfterRenderObservable.remove(meshExcluded.afterRender);\r\n            }\r\n        }\r\n\r\n        this._excludedMeshes[mesh.uniqueId] = null;\r\n    }\r\n\r\n    public override hasMesh(mesh: AbstractMesh): boolean {\r\n        if (!this._meshes || !super.hasMesh(mesh)) {\r\n            return false;\r\n        }\r\n\r\n        return !!this._meshes[mesh.uniqueId];\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the highlight layer in order to make it glow with the chosen color.\r\n     * @param mesh The mesh to highlight\r\n     * @param color The color of the highlight\r\n     * @param glowEmissiveOnly Extract the glow from the emissive texture\r\n     */\r\n    public addMesh(mesh: Mesh, color: Color3, glowEmissiveOnly = false) {\r\n        if (!this._meshes) {\r\n            return;\r\n        }\r\n\r\n        const meshHighlight = this._meshes[mesh.uniqueId];\r\n        if (meshHighlight) {\r\n            meshHighlight.color = color;\r\n        } else {\r\n            this._meshes[mesh.uniqueId] = {\r\n                mesh: mesh,\r\n                color: color,\r\n                // Lambda required for capture due to Observable this context\r\n                observerHighlight: mesh.onBeforeBindObservable.add((mesh: Mesh) => {\r\n                    if (this._mainObjectRendererRenderPassId !== -1 && this._mainObjectRendererRenderPassId !== this._engine.currentRenderPassId) {\r\n                        return;\r\n                    }\r\n                    if (this.isEnabled) {\r\n                        if (this._excludedMeshes && this._excludedMeshes[mesh.uniqueId]) {\r\n                            this._defaultStencilReference(mesh);\r\n                        } else {\r\n                            mesh.getScene()\r\n                                .getEngine()\r\n                                .setStencilFunctionReference(this._instanceGlowingMeshStencilReference << (8 - this.numStencilBits));\r\n                        }\r\n                    }\r\n                }),\r\n                observerDefault: mesh.onAfterRenderObservable.add((mesh: Mesh) => {\r\n                    if (this._mainObjectRendererRenderPassId !== -1 && this._mainObjectRendererRenderPassId !== this._engine.currentRenderPassId) {\r\n                        return;\r\n                    }\r\n                    if (this.isEnabled) {\r\n                        this._defaultStencilReference(mesh);\r\n                    }\r\n                }),\r\n                glowEmissiveOnly: glowEmissiveOnly,\r\n            };\r\n\r\n            mesh.onDisposeObservable.add(() => {\r\n                this._disposeMesh(mesh);\r\n            });\r\n        }\r\n\r\n        this._shouldRender = true;\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the highlight layer in order to make it stop glowing.\r\n     * @param mesh The mesh to highlight\r\n     */\r\n    public removeMesh(mesh: Mesh) {\r\n        if (!this._meshes) {\r\n            return;\r\n        }\r\n\r\n        const meshHighlight = this._meshes[mesh.uniqueId];\r\n        if (meshHighlight) {\r\n            if (meshHighlight.observerHighlight) {\r\n                mesh.onBeforeBindObservable.remove(meshHighlight.observerHighlight);\r\n            }\r\n\r\n            if (meshHighlight.observerDefault) {\r\n                mesh.onAfterRenderObservable.remove(meshHighlight.observerDefault);\r\n            }\r\n            delete this._meshes[mesh.uniqueId];\r\n        }\r\n\r\n        this._shouldRender = false;\r\n        for (const meshHighlightToCheck in this._meshes) {\r\n            if (this._meshes[meshHighlightToCheck]) {\r\n                this._shouldRender = true;\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove all the meshes currently referenced in the highlight layer\r\n     */\r\n    public removeAllMeshes(): void {\r\n        if (!this._meshes) {\r\n            return;\r\n        }\r\n\r\n        for (const uniqueId in this._meshes) {\r\n            if (Object.prototype.hasOwnProperty.call(this._meshes, uniqueId)) {\r\n                const mesh = this._meshes[uniqueId];\r\n                if (mesh) {\r\n                    this.removeMesh(mesh.mesh);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _defaultStencilReference(mesh: Mesh) {\r\n        mesh.getScene()\r\n            .getEngine()\r\n            .setStencilFunctionReference(ThinHighlightLayer.NormalMeshStencilReference << (8 - this.numStencilBits));\r\n    }\r\n\r\n    public _disposeMesh(mesh: Mesh): void {\r\n        this.removeMesh(mesh);\r\n        this.removeExcludedMesh(mesh);\r\n    }\r\n\r\n    public override dispose(): void {\r\n        if (this._meshes) {\r\n            // Clean mesh references\r\n            for (const id in this._meshes) {\r\n                const meshHighlight = this._meshes[id];\r\n                if (meshHighlight && meshHighlight.mesh) {\r\n                    if (meshHighlight.observerHighlight) {\r\n                        meshHighlight.mesh.onBeforeBindObservable.remove(meshHighlight.observerHighlight);\r\n                    }\r\n\r\n                    if (meshHighlight.observerDefault) {\r\n                        meshHighlight.mesh.onAfterRenderObservable.remove(meshHighlight.observerDefault);\r\n                    }\r\n                }\r\n            }\r\n            this._meshes = null;\r\n        }\r\n\r\n        if (this._excludedMeshes) {\r\n            for (const id in this._excludedMeshes) {\r\n                const meshHighlight = this._excludedMeshes[id];\r\n                if (meshHighlight) {\r\n                    if (meshHighlight.beforeBind) {\r\n                        meshHighlight.mesh.onBeforeBindObservable.remove(meshHighlight.beforeBind);\r\n                    }\r\n\r\n                    if (meshHighlight.afterRender) {\r\n                        meshHighlight.mesh.onAfterRenderObservable.remove(meshHighlight.afterRender);\r\n                    }\r\n                }\r\n            }\r\n            this._excludedMeshes = null;\r\n        }\r\n\r\n        super.dispose();\r\n    }\r\n}\r\n","import { type FrameGraph, type Scene, type IThinHighlightLayerOptions } from \"core/index\";\r\nimport { ThinHighlightLayer } from \"core/Layers/thinHighlightLayer\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphBaseLayerTask, FrameGraphBaseLayerBlurType } from \"./baseLayerTask\";\r\nimport { HasStencilAspect } from \"core/Materials/Textures/textureHelper.functions\";\r\n\r\n/**\r\n * Task which applies a highlight effect to a texture.\r\n */\r\nexport class FrameGraphHighlightLayerTask extends FrameGraphBaseLayerTask {\r\n    /**\r\n     * The highlight layer object. Use this object to update the highlight layer properties.\r\n     */\r\n    public override readonly layer: ThinHighlightLayer;\r\n\r\n    /**\r\n     * Constructs a new highlight layer task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param scene The scene to render the highlight layer in.\r\n     * @param options Options for the highlight layer.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene, options?: IThinHighlightLayerOptions) {\r\n        const alphaBlendingMode = options?.alphaBlendingMode ?? Constants.ALPHA_COMBINE;\r\n\r\n        super(\r\n            name,\r\n            frameGraph,\r\n            scene,\r\n            new ThinHighlightLayer(name, scene, options, true),\r\n            1,\r\n            alphaBlendingMode === Constants.ALPHA_COMBINE ? FrameGraphBaseLayerBlurType.Glow : FrameGraphBaseLayerBlurType.Standard,\r\n            true,\r\n            true\r\n        );\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphHighlightLayerTask\";\r\n    }\r\n\r\n    public override record() {\r\n        if (!this.objectRendererTask.depthTexture) {\r\n            throw new Error(`FrameGraphHighlightLayerTask \"${this.name}\": objectRendererTask must have a depthTexture input`);\r\n        }\r\n\r\n        const depthTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.objectRendererTask.depthTexture);\r\n        if (!depthTextureCreationOptions.options.formats || !HasStencilAspect(depthTextureCreationOptions.options.formats[0])) {\r\n            throw new Error(`FrameGraphHighlightLayerTask \"${this.name}\": objectRendererTask depthTexture must have a stencil aspect`);\r\n        }\r\n\r\n        super.record();\r\n\r\n        this.layer._mainObjectRendererRenderPassId = this.objectRendererTask.objectRenderer.renderPassId;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type Scene,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type NodeRenderGraphConnectionPoint,\r\n    type FrameGraphObjectRendererTask,\r\n} from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointDirection } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphHighlightLayerTask } from \"core/FrameGraph/Tasks/Layers/highlightLayerTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { NodeRenderGraphConnectionPointCustomObject } from \"../../nodeRenderGraphConnectionPointCustomObject\";\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"../Rendering/baseObjectRendererBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the highlight layer\r\n */\r\nexport class NodeRenderGraphHighlightLayerBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphHighlightLayerTask;\r\n\r\n    public override _additionalConstructionParameters: [number, number | undefined, number, boolean, number];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphHighlightLayerBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param layerTextureRatio multiplication factor applied to the main texture size to compute the size of the layer render target texture (default: 0.5)\r\n     * @param layerTextureFixedSize defines the fixed size of the layer render target texture. Takes precedence over layerTextureRatio if provided (default: undefined)\r\n     * @param blurTextureSizeRatio defines the factor to apply to the layer texture size to create the blur textures (default: 0.5)\r\n     * @param isStroke should we display highlight as a solid stroke? (default: false)\r\n     * @param layerTextureType defines the type of the layer texture (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        frameGraph: FrameGraph,\r\n        scene: Scene,\r\n        layerTextureRatio = 0.5,\r\n        layerTextureFixedSize?: number,\r\n        blurTextureSizeRatio = 0.5,\r\n        isStroke = false,\r\n        layerTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [layerTextureRatio, layerTextureFixedSize, blurTextureSizeRatio, isStroke, layerTextureType];\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"layer\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\r\n            \"objectRenderer\",\r\n            NodeRenderGraphBlockConnectionPointTypes.Object,\r\n            true,\r\n            new NodeRenderGraphConnectionPointCustomObject(\r\n                \"objectRenderer\",\r\n                this,\r\n                NodeRenderGraphConnectionPointDirection.Input,\r\n                NodeRenderGraphBaseObjectRendererBlock,\r\n                \"NodeRenderGraphBaseObjectRendererBlock\"\r\n            )\r\n        );\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBufferDepthStencil);\r\n        this.layer.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n\r\n        this.output._typeConnectionSource = this.target;\r\n\r\n        this._frameGraphTask = new FrameGraphHighlightLayerTask(this.name, this._frameGraph, this._scene, {\r\n            mainTextureRatio: layerTextureRatio,\r\n            mainTextureFixedSize: layerTextureFixedSize,\r\n            blurTextureSizeRatio,\r\n            isStroke,\r\n            mainTextureType: layerTextureType,\r\n        });\r\n    }\r\n\r\n    private _createTask(layerTextureRatio: number, layerTextureFixedSize: number, blurTextureSizeRatio: number, isStroke: boolean, layerTextureType: number) {\r\n        const blurHorizontalSize = this.blurHorizontalSize;\r\n        const blurVerticalSize = this.blurVerticalSize;\r\n\r\n        this._frameGraphTask?.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphHighlightLayerTask(this.name, this._frameGraph, this._scene, {\r\n            mainTextureRatio: layerTextureRatio,\r\n            mainTextureFixedSize: layerTextureFixedSize,\r\n            blurTextureSizeRatio,\r\n            isStroke,\r\n            mainTextureType: layerTextureType,\r\n        });\r\n\r\n        this.blurHorizontalSize = blurHorizontalSize;\r\n        this.blurVerticalSize = blurVerticalSize;\r\n\r\n        this._additionalConstructionParameters = [layerTextureRatio, layerTextureFixedSize, blurTextureSizeRatio, isStroke, layerTextureType];\r\n    }\r\n\r\n    /** Multiplication factor applied to the main texture size to compute the size of the layer render target texture */\r\n    @editableInPropertyPage(\"Layer texture ratio\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get layerTextureRatio() {\r\n        return this._frameGraphTask.layer._options.mainTextureRatio;\r\n    }\r\n\r\n    public set layerTextureRatio(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(value, options.mainTextureFixedSize, options.blurTextureSizeRatio, options.isStroke, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the fixed size of the layer render target texture. Takes precedence over layerTextureRatio if provided */\r\n    @editableInPropertyPage(\"Layer texture fixed size\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get layerTextureFixedSize() {\r\n        return this._frameGraphTask.layer._options.mainTextureFixedSize;\r\n    }\r\n\r\n    public set layerTextureFixedSize(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.mainTextureRatio, value, options.blurTextureSizeRatio, options.isStroke, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the factor to apply to the layer texture size to create the blur textures */\r\n    @editableInPropertyPage(\"Blur texture size ratio\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get blurTextureSizeRatio() {\r\n        return this._frameGraphTask.layer._options.blurTextureSizeRatio;\r\n    }\r\n\r\n    public set blurTextureSizeRatio(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.mainTextureRatio, options.mainTextureFixedSize, value, options.isStroke, options.mainTextureType);\r\n    }\r\n\r\n    /** Should we display highlight as a solid stroke? */\r\n    @editableInPropertyPage(\"Is stroke\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get isStroke() {\r\n        return this._frameGraphTask.layer._options.isStroke;\r\n    }\r\n\r\n    public set isStroke(value: boolean) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.mainTextureRatio, options.mainTextureFixedSize, options.blurTextureSizeRatio, value, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the type of the layer texture */\r\n    @editableInPropertyPage(\"Layer texture type\", PropertyTypeForEdition.TextureType, \"PROPERTIES\")\r\n    public get layerTextureType() {\r\n        return this._frameGraphTask.layer._options.mainTextureType;\r\n    }\r\n\r\n    public set layerTextureType(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.mainTextureRatio, options.mainTextureFixedSize, options.blurTextureSizeRatio, options.isStroke, value);\r\n    }\r\n\r\n    /** How big is the horizontal kernel of the blur texture */\r\n    @editableInPropertyPage(\"Blur horizontal size\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 4 })\r\n    public get blurHorizontalSize() {\r\n        return this._frameGraphTask.layer.blurHorizontalSize;\r\n    }\r\n\r\n    public set blurHorizontalSize(value: number) {\r\n        this._frameGraphTask.layer.blurHorizontalSize = value;\r\n    }\r\n\r\n    /** How big is the vertical kernel of the blur texture */\r\n    @editableInPropertyPage(\"Blur vertical size\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 4 })\r\n    public get blurVerticalSize() {\r\n        return this._frameGraphTask.layer.blurVerticalSize;\r\n    }\r\n\r\n    public set blurVerticalSize(value: number) {\r\n        this._frameGraphTask.layer.blurVerticalSize = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphHighlightLayerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target texture input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the layer input component\r\n     */\r\n    public get layer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the objectRenderer input component\r\n     */\r\n    public get objectRenderer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.layerTexture = this.layer.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.objectRendererTask = this.objectRenderer.connectedPoint?.value as FrameGraphObjectRendererTask;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.blurHorizontalSize = ${this.blurHorizontalSize};`);\r\n        codes.push(`${this._codeVariableName}.blurVerticalSize = ${this.blurVerticalSize};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.blurHorizontalSize = this.blurHorizontalSize;\r\n        serializationObject.blurVerticalSize = this.blurVerticalSize;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.blurHorizontalSize = serializationObject.blurHorizontalSize;\r\n        this.blurVerticalSize = serializationObject.blurVerticalSize;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for highlightLayerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterHighlightLayerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphHighlightLayerBlock\", NodeRenderGraphHighlightLayerBlock);\r\n}\r\n","import { VertexBuffer } from \"../Buffers/buffer.pure\";\nimport { Camera } from \"../Cameras/camera.pure\";\nimport { RegisterAbstractEngineStates } from \"../Engines/AbstractEngine/abstractEngine.states.pure\";\nimport { RegisterAbstractEngineStencil } from \"../Engines/AbstractEngine/abstractEngine.stencil.pure\";\nimport { Constants } from \"../Engines/constants\";\nimport { type ThinEngine } from \"../Engines/thinEngine\";\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"../Materials/clipPlaneMaterialHelper\";\nimport { type Effect, type IEffectCreationOptions } from \"../Materials/effect\";\nimport { EffectFallbacks } from \"../Materials/effectFallbacks\";\nimport { Material } from \"../Materials/material\";\nimport { BindBonesParameters, BindMorphTargetParameters, PrepareDefinesAndAttributesForMorphTargets, PushAttributesForInstances } from \"../Materials/materialHelper.functions\";\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\nimport { type InstancedMesh } from \"../Meshes/instancedMesh\";\nimport { type Mesh } from \"../Meshes/mesh\";\nimport { type SubMesh } from \"../Meshes/subMesh\";\nimport { type Scene } from \"../scene\";\nimport { type Nullable } from \"../types\";\nimport { type IThinEffectLayerOptions, ThinEffectLayer } from \"./thinEffectLayer\";\n\n/**\n * Selection outline layer options. This helps customizing the behaviour\n * of the selection outline layer.\n */\nexport interface IThinSelectionOutlineLayerOptions extends IThinEffectLayerOptions {\n    /**\n     * Use the GLSL code generation for the shader (even on WebGPU). Default is false\n     */\n    forceGLSL?: boolean;\n\n    /**\n     * Specifies whether the depth stored is the Z coordinate in camera space.\n     */\n    storeCameraSpaceZ?: boolean;\n\n    /**\n     * Outline method to use (default: Constants.OUTLINELAYER_SAMPLING_TRIDIRECTIONAL)\n     *\n     * @see {@link Constants.OUTLINELAYER_SAMPLING_TRIDIRECTIONAL}\n     */\n    outlineMethod?: number;\n\n    /**\n     * Whether to use depth when drawing selection outlines. Disable this to avoid depth renderer usage and draw selected outlines without depth clipping.\n     */\n    useDepthOcclusion?: boolean;\n}\n\n/**\n * @internal\n */\nexport class ThinSelectionOutlineLayer extends ThinEffectLayer {\n    /**\n     * Effect Name of the layer.\n     */\n    public static readonly EffectName = \"SelectionOutlineLayer\";\n\n    /**\n     * Name of the instance selection ID attribute\n     * @internal\n     */\n    public static readonly InstanceSelectionIdAttributeName = \"instanceSelectionId\";\n\n    /**\n     * The outline color\n     */\n    public outlineColor: Color3 = new Color3(1, 0.5, 0);\n\n    /**\n     * The thickness of the edges\n     */\n    public outlineThickness: number = 2.0;\n\n    /**\n     * The occlusion threshold (default: 0.0001)\n     */\n    public occlusionThreshold: number = 0.0001;\n\n    private _occlusionStrength = 0.8;\n    private _useDepthOcclusion = true;\n\n    /**\n     * The strength of the occlusion effect (default: 0.8)\n     */\n    public get occlusionStrength(): number {\n        return this._occlusionStrength;\n    }\n\n    public set occlusionStrength(value: number) {\n        const wasUsingComposeDepthOcclusion = this._shouldUseComposeDepthOcclusion;\n        this._occlusionStrength = value;\n        if (wasUsingComposeDepthOcclusion !== this._shouldUseComposeDepthOcclusion) {\n            this._disposeMergeEffects();\n        }\n    }\n\n    /**\n     * Whether to use depth when drawing selection outlines.\n     * Disable this to avoid depth renderer usage; selected outlines will not be clipped by scene or selected geometry.\n     */\n    public get useDepthOcclusion(): boolean {\n        return this._useDepthOcclusion;\n    }\n\n    public set useDepthOcclusion(value: boolean) {\n        const wasUsingComposeDepthOcclusion = this._shouldUseComposeDepthOcclusion;\n        this._useDepthOcclusion = value;\n        this._options.useDepthOcclusion = value;\n        if (wasUsingComposeDepthOcclusion !== this._shouldUseComposeDepthOcclusion) {\n            this._disposeMergeEffects();\n        }\n    }\n\n    private get _shouldUseComposeDepthOcclusion(): boolean {\n        return this._useDepthOcclusion && this._occlusionStrength > 0;\n    }\n\n    /**\n     * The width of the source texture\n     */\n    public textureWidth: number = 0;\n\n    /**\n     * The height of the source texture\n     */\n    public textureHeight: number = 0;\n\n    /** @internal */\n    public override _options: Required<IThinSelectionOutlineLayerOptions>;\n\n    /** @internal */\n    public readonly _meshUniqueIdToSelectionId: number[] = [];\n    /** @internal */\n    public _selection: Nullable<AbstractMesh[]> = [];\n    private _instancedBufferSources: Set<Mesh> = new Set();\n    private _nextSelectionId = 1;\n\n    /**\n     * Instantiates a new selection outline Layer and references it to the scene..\n     * @param name The name of the layer\n     * @param scene The scene to use the layer in\n     * @param options Sets of none mandatory options to use with the layer (see IThinSelectionOutlineLayerOptions for more information)\n     * @param dontCheckIfReady Specifies if the layer should disable checking whether all the post processes are ready (default: false). To save performance, this should be set to true and you should call `isReady` manually before rendering to the layer.\n     */\n    public constructor(name: string, scene?: Scene, options?: Partial<IThinSelectionOutlineLayerOptions>, dontCheckIfReady = false) {\n        super(name, scene, options !== undefined ? !!options.forceGLSL : false);\n\n        RegisterAbstractEngineStates();\n        RegisterAbstractEngineStencil();\n\n        // Adapt options\n        this._options = {\n            mainTextureRatio: 1.0,\n            mainTextureFixedSize: 0,\n            alphaBlendingMode: Constants.ALPHA_COMBINE,\n            camera: null,\n            renderingGroupId: -1,\n            forceGLSL: false,\n            mainTextureType: Constants.TEXTURETYPE_FLOAT,\n            mainTextureFormat: Constants.TEXTUREFORMAT_RG,\n            storeCameraSpaceZ: false,\n            outlineMethod: Constants.OUTLINELAYER_SAMPLING_TRIDIRECTIONAL,\n            useDepthOcclusion: true,\n            ...options,\n        };\n        this._useDepthOcclusion = this._options.useDepthOcclusion;\n\n        // Fall back to a supported mask texture type if the device doesn't support rendering to float framebuffers\n        // or linear filtering of float textures (e.g. OES_texture_float_linear missing on some iOS versions)\n        if (this._options.mainTextureType === Constants.TEXTURETYPE_FLOAT && !(this._engine.getCaps().textureFloatRender && this._engine.getCaps().textureFloatLinearFiltering)) {\n            this._options.mainTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\n        }\n        if (\n            this._options.mainTextureType === Constants.TEXTURETYPE_HALF_FLOAT &&\n            !(this._engine.getCaps().textureHalfFloatRender && this._engine.getCaps().textureHalfFloatLinearFiltering)\n        ) {\n            this._options.mainTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\n        }\n\n        // When using an 8-bit render target, we cannot reliably store camera-space Z in the mask texture:\n        // depth would be clamped/quantized, breaking occlusion comparisons. In that case, force-disable\n        // storeCameraSpaceZ so the layer falls back to the supported behavior.\n        if (this._options.storeCameraSpaceZ && this._options.mainTextureType === Constants.TEXTURETYPE_UNSIGNED_BYTE) {\n            this._options.storeCameraSpaceZ = false;\n        }\n        // set clear color\n        this.neutralColor = new Color4(0.0, this._options.storeCameraSpaceZ ? 0.0 : 1.0, 0.0, 1.0);\n\n        // Initialize the layer\n        this._init(this._options);\n\n        // Do not render as long as no meshes have been added\n        this._shouldRender = false;\n\n        if (dontCheckIfReady) {\n            // When dontCheckIfReady is true, we are in the new ThinXXX layer mode, so we must call _createTextureAndPostProcesses ourselves (it is called by EffectLayer otherwise)\n            this._createTextureAndPostProcesses();\n        }\n    }\n\n    /**\n     * Gets the class name of the effect layer\n     * @returns the string with the class name of the effect layer\n     */\n    public getClassName(): string {\n        return \"SelectionOutlineLayer\";\n    }\n\n    /** @internal */\n    public override _internalIsSubMeshReady(subMesh: SubMesh, useInstances: boolean, _emissiveTexture: Nullable<BaseTexture>): boolean {\n        const engine = this._scene.getEngine();\n        const mesh = subMesh.getMesh();\n\n        const renderingMaterial = mesh._internalAbstractMeshDataInfo._materialForRenderPass?.[engine.currentRenderPassId];\n\n        if (renderingMaterial) {\n            return renderingMaterial.isReadyForSubMesh(mesh, subMesh, useInstances);\n        }\n\n        const material = subMesh.getMaterial();\n\n        if (!material) {\n            return false;\n        }\n\n        // selection outline layer is not compatible with custom materials\n        // if (this._useMeshMaterial(subMesh.getRenderingMesh())) {\n        //     return material.isReadyForSubMesh(subMesh.getMesh(), subMesh, useInstances);\n        // }\n\n        const defines: string[] = [];\n\n        const attribs = [VertexBuffer.PositionKind];\n\n        let uv1 = false;\n        let uv2 = false;\n        const color = false;\n\n        // Alpha test\n        const alphaTestTexture = material.needAlphaTestingForMesh(mesh) ? material.getAlphaTestTexture() : null;\n        if (alphaTestTexture) {\n            const hasUV1 = mesh.isVerticesDataPresent(VertexBuffer.UVKind);\n            const hasUV2 = mesh.isVerticesDataPresent(VertexBuffer.UV2Kind);\n            if (hasUV2 && (alphaTestTexture.coordinatesIndex === 1 || !hasUV1)) {\n                attribs.push(VertexBuffer.UV2Kind);\n                defines.push(\"#define UV2\");\n                uv2 = true;\n            } else if (hasUV1) {\n                attribs.push(VertexBuffer.UVKind);\n                defines.push(\"#define UV1\");\n                uv1 = true;\n            }\n            if (uv1 || uv2) {\n                defines.push(\"#define ALPHATEST\");\n            }\n        }\n\n        // Bones\n        const fallbacks = new EffectFallbacks();\n        if (mesh.useBones && mesh.computeBonesUsingShaders) {\n            attribs.push(VertexBuffer.MatricesIndicesKind);\n            attribs.push(VertexBuffer.MatricesWeightsKind);\n            if (mesh.numBoneInfluencers > 4) {\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\n            }\n\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\n\n            const skeleton = mesh.skeleton;\n            if (skeleton && skeleton.isUsingTextureForMatrices) {\n                defines.push(\"#define BONETEXTURE\");\n            } else {\n                defines.push(\"#define BonesPerMesh \" + (skeleton ? skeleton.bones.length + 1 : 0));\n            }\n\n            if (mesh.numBoneInfluencers > 0) {\n                fallbacks.addCPUSkinningFallback(0, mesh);\n            }\n        } else {\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\n        }\n\n        // Morph targets\n        const numMorphInfluencers = mesh.morphTargetManager\n            ? PrepareDefinesAndAttributesForMorphTargets(\n                  mesh.morphTargetManager,\n                  defines,\n                  attribs,\n                  mesh,\n                  true, // usePositionMorph\n                  false, // useNormalMorph\n                  false, // useTangentMorph\n                  uv1, // useUVMorph\n                  uv2, // useUV2Morph\n                  color // useColorMorph\n              )\n            : 0;\n\n        // Instances\n        if (useInstances) {\n            defines.push(\"#define INSTANCES\");\n            PushAttributesForInstances(attribs);\n            if (subMesh.getRenderingMesh().hasThinInstances) {\n                defines.push(\"#define THIN_INSTANCES\");\n            }\n        }\n\n        // Baked vertex animations\n        const bvaManager = mesh.bakedVertexAnimationManager;\n        if (bvaManager && bvaManager.isEnabled) {\n            defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\n            if (useInstances) {\n                attribs.push(\"bakedVertexAnimationSettingsInstanced\");\n            }\n        }\n\n        // ClipPlanes\n        PrepareStringDefinesForClipPlanes(material, this._scene, defines);\n\n        // Selection ID\n        if (useInstances) {\n            attribs.push(ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName);\n        }\n\n        this._addCustomEffectDefines(defines);\n\n        // Get correct effect\n        const drawWrapper = subMesh._getDrawWrapper(undefined, true)!;\n        const cachedDefines = drawWrapper.defines as string;\n        const join = defines.join(\"\\n\");\n        if (cachedDefines !== join) {\n            const uniforms = [\n                \"world\",\n                \"mBones\",\n                \"viewProjection\",\n                \"view\",\n                \"morphTargetInfluences\",\n                \"morphTargetCount\",\n                \"boneTextureInfo\",\n                \"diffuseMatrix\",\n                \"morphTargetTextureInfo\",\n                \"morphTargetTextureIndices\",\n                \"bakedVertexAnimationSettings\",\n                \"bakedVertexAnimationTextureSizeInverted\",\n                \"bakedVertexAnimationTime\",\n                \"bakedVertexAnimationTexture\",\n                \"depthValues\",\n                \"selectionId\",\n            ];\n\n            AddClipPlaneUniforms(uniforms);\n\n            drawWrapper.setEffect(\n                this._engine.createEffect(\n                    \"selection\",\n                    <IEffectCreationOptions>{\n                        attributes: attribs,\n                        uniformsNames: uniforms,\n                        uniformBuffersNames: [],\n                        samplers: [\"diffuseSampler\", \"boneSampler\", \"morphTargets\", \"bakedVertexAnimationTexture\"],\n                        defines: join,\n                        fallbacks: fallbacks,\n                        onCompiled: null,\n                        onError: null,\n                        indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },\n                        shaderLanguage: this._shaderLanguage,\n                        extraInitializationsAsync: this._shadersLoaded\n                            ? undefined\n                            : async () => {\n                                  await this._importShadersAsync();\n                                  this._shadersLoaded = true;\n                              },\n                    },\n                    this._engine\n                ),\n                join\n            );\n        }\n\n        const effectIsReady = drawWrapper.effect!.isReady();\n\n        return effectIsReady && (this._dontCheckIfReady || (!this._dontCheckIfReady && this.isLayerReady()));\n    }\n\n    protected override async _importShadersAsync(): Promise<void> {\n        if (this._shaderLanguage === ShaderLanguage.WGSL) {\n            await Promise.all([\n                import(\"../ShadersWGSL/selection.vertex\"),\n                import(\"../ShadersWGSL/selection.fragment\"),\n                import(\"../ShadersWGSL/glowMapMerge.vertex\"),\n                import(\"../ShadersWGSL/selectionOutline.fragment\"),\n            ]);\n        } else {\n            await Promise.all([\n                import(\"../Shaders/selection.vertex\"),\n                import(\"../Shaders/selection.fragment\"),\n                import(\"../Shaders/glowMapMerge.vertex\"),\n                import(\"../Shaders/selectionOutline.fragment\"),\n            ]);\n        }\n\n        await super._importShadersAsync();\n    }\n\n    /**\n     * Get the effect name of the layer.\n     * @returns The effect name\n     */\n    public override getEffectName(): string {\n        return ThinSelectionOutlineLayer.EffectName;\n    }\n\n    /** @internal */\n    public override _createMergeEffect(): Effect {\n        const defines: string[] = [];\n        const uniformsNames = [\"screenSize\", \"outlineColor\", \"outlineThickness\"];\n        const samplers = [\"maskSampler\"];\n\n        switch (this._options.outlineMethod) {\n            case Constants.OUTLINELAYER_SAMPLING_TRIDIRECTIONAL:\n                defines.push(\"#define OUTLINELAYER_SAMPLING_TRIDIRECTIONAL\");\n                break;\n            case Constants.OUTLINELAYER_SAMPLING_OCTADIRECTIONAL:\n                defines.push(\"#define OUTLINELAYER_SAMPLING_OCTADIRECTIONAL\");\n                break;\n        }\n\n        if (this._shouldUseComposeDepthOcclusion) {\n            defines.push(\"#define OUTLINELAYER_DEPTH_OCCLUSION\");\n            uniformsNames.push(\"occlusionStrength\", \"occlusionThreshold\");\n            samplers.push(\"depthSampler\");\n        }\n\n        const join = defines.join(\"\\n\");\n\n        return this._engine.createEffect(\n            {\n                // glowMapMerge vertex is just a basic vertex shader for drawing a quad. so we reuse it here\n                vertex: \"glowMapMerge\",\n                // selection outline fragment does computation of outline with alpha channel for blending\n                fragment: \"selectionOutline\",\n            },\n            <IEffectCreationOptions>{\n                attributes: [VertexBuffer.PositionKind],\n                uniformsNames,\n                samplers,\n                defines: join,\n                fallbacks: null,\n                onCompiled: null,\n                onError: null,\n                shaderLanguage: this._shaderLanguage,\n                extraInitializationsAsync: this._shadersLoaded\n                    ? undefined\n                    : async () => {\n                          await this._importShadersAsync();\n                          this._shadersLoaded = true;\n                      },\n            },\n            this._engine\n        );\n    }\n\n    /** @internal */\n    public override _createTextureAndPostProcesses(): void {\n        // we don't need to create a texture for this layer. since all computation is done in the merge effect\n    }\n\n    /**\n     * Checks for the readiness of the element composing the layer.\n     * @param subMesh the mesh to check for\n     * @param useInstances specify whether or not to use instances to render the mesh\n     * @returns true if ready otherwise, false\n     */\n    public override isReady(subMesh: SubMesh, useInstances: boolean): boolean {\n        const material = subMesh.getMaterial();\n        const mesh = subMesh.getRenderingMesh();\n\n        if (!material || !mesh || !this._selection) {\n            return false;\n        }\n\n        return super._isSubMeshReady(subMesh, useInstances, null);\n    }\n\n    /** @internal */\n    public override _canRenderMesh(_mesh: AbstractMesh, _material: Material): boolean {\n        return true;\n    }\n\n    protected override _renderSubMesh(subMesh: SubMesh, enableAlphaMode: boolean = false): void {\n        if (!this._internalShouldRender()) {\n            return;\n        }\n\n        const material = subMesh.getMaterial();\n        const ownerMesh = subMesh.getMesh();\n        const replacementMesh = subMesh.getReplacementMesh();\n        const renderingMesh = subMesh.getRenderingMesh();\n        const effectiveMesh = subMesh.getEffectiveMesh();\n        const scene = this._scene;\n        const engine = scene.getEngine();\n\n        effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;\n\n        if (!material) {\n            return;\n        }\n\n        // Do not block in blend mode.\n        if (!this._canRenderMesh(renderingMesh, material)) {\n            return;\n        }\n\n        // Culling\n        let sideOrientation = material._getEffectiveOrientation(renderingMesh);\n        const mainDeterminant = effectiveMesh._getWorldMatrixDeterminant();\n        if (mainDeterminant < 0) {\n            sideOrientation = sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;\n        }\n\n        const reverse = sideOrientation === Material.ClockWiseSideOrientation;\n        engine.setState(material.backFaceCulling, material.zOffset, undefined, reverse, material.cullBackFaces, undefined, material.zOffsetUnits);\n\n        // Managing instances\n        const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);\n        if (batch.mustReturn) {\n            return;\n        }\n\n        // Early Exit per mesh\n        if (!this._shouldRenderMesh(renderingMesh)) {\n            return;\n        }\n\n        const hardwareInstancedRendering =\n            batch.hardwareInstancedRendering[subMesh._id] ||\n            renderingMesh.hasThinInstances ||\n            (!!renderingMesh._userInstancedBuffersStorage &&\n                ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName in renderingMesh._userInstancedBuffersStorage.vertexBuffers);\n\n        // When LOD transitions cause a different mesh to render with hardware instancing,\n        // the LOD mesh's own instanceSelectionId must reflect the source mesh's value so\n        // the \"self\" draw (representing the source mesh) gets the correct selection ID.\n        if (hardwareInstancedRendering && renderingMesh._masterMesh && renderingMesh.instancedBuffers) {\n            renderingMesh.instancedBuffers[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] =\n                renderingMesh._masterMesh.instancedBuffers?.[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] ?? null;\n        }\n\n        this._setEmissiveTextureAndColor(renderingMesh, subMesh, material);\n\n        this.onBeforeRenderMeshToEffect.notifyObservers(ownerMesh);\n\n        // selection outline layer is not compatible with custom materials\n        // if (this._useMeshMaterial(renderingMesh)) {\n        //     subMesh.getMaterial()!._glowModeEnabled = true;\n        //     renderingMesh.render(subMesh, enableAlphaMode, replacementMesh || undefined);\n        //     subMesh.getMaterial()!._glowModeEnabled = false;\n        // } else\n        if (this._isSubMeshReady(subMesh, hardwareInstancedRendering, this._emissiveTextureAndColor.texture)) {\n            const renderingMaterial = effectiveMesh._internalAbstractMeshDataInfo._materialForRenderPass?.[engine.currentRenderPassId];\n\n            let drawWrapper = subMesh._getDrawWrapper();\n            if (!drawWrapper && renderingMaterial) {\n                drawWrapper = renderingMaterial._getDrawWrapper();\n            }\n\n            if (!drawWrapper) {\n                return;\n            }\n\n            const effect = drawWrapper.effect!;\n\n            engine.enableEffect(drawWrapper);\n            if (!hardwareInstancedRendering) {\n                renderingMesh._bind(subMesh, effect, material.fillMode);\n            }\n\n            if (!renderingMaterial) {\n                effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\n                if (this._options.storeCameraSpaceZ) {\n                    effect.setMatrix(\"view\", scene.getViewMatrix());\n                } else {\n                    const camera = this.camera || scene.activeCamera;\n                    if (camera) {\n                        const cameraIsOrtho = camera.mode === Camera.ORTHOGRAPHIC_CAMERA;\n\n                        let minZ: number, maxZ: number;\n\n                        if (cameraIsOrtho) {\n                            minZ = !engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\n                            maxZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\n                        } else {\n                            minZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? camera.minZ : engine.isNDCHalfZRange ? 0 : camera.minZ;\n                            maxZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : camera.maxZ;\n                        }\n\n                        effect.setFloat2(\"depthValues\", minZ, minZ + maxZ);\n                    }\n                }\n                effect.setMatrix(\"world\", effectiveMesh.getWorldMatrix());\n            } else {\n                renderingMaterial.bindForSubMesh(effectiveMesh.getWorldMatrix(), effectiveMesh as Mesh, subMesh);\n            }\n\n            if (!renderingMaterial) {\n                // Alpha test\n                if (material && material.needAlphaTestingForMesh(effectiveMesh)) {\n                    const alphaTexture = material.getAlphaTestTexture();\n                    if (alphaTexture) {\n                        effect.setTexture(\"diffuseSampler\", alphaTexture);\n                        effect.setMatrix(\"diffuseMatrix\", alphaTexture.getTextureMatrix());\n                    }\n                }\n\n                // Bones\n                BindBonesParameters(renderingMesh, effect);\n\n                // Morph targets\n                BindMorphTargetParameters(renderingMesh, effect);\n                if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\n                    renderingMesh.morphTargetManager._bind(effect);\n                }\n\n                // Baked vertex animations\n                const bvaManager = subMesh.getMesh().bakedVertexAnimationManager;\n                if (bvaManager && bvaManager.isEnabled) {\n                    bvaManager.bind(effect, hardwareInstancedRendering);\n                }\n\n                // Alpha mode\n                if (enableAlphaMode) {\n                    engine.setAlphaMode(material.alphaMode);\n                }\n\n                // Clip planes\n                BindClipPlane(effect, material, scene);\n\n                // Selection ID\n                let selectionId = this._meshUniqueIdToSelectionId[renderingMesh.uniqueId];\n                // When using LOD, the rendering mesh is the LOD mesh, not the source mesh.\n                // Look up the selection ID from the master (source) mesh.\n                if (selectionId === undefined && renderingMesh._masterMesh) {\n                    selectionId = this._meshUniqueIdToSelectionId[renderingMesh._masterMesh.uniqueId];\n                    if (selectionId === undefined) {\n                        // Prefer the ownerMesh (submesh owner) which is the actual instance\n                        // being rendered during LOD, then fall back to the master (source) mesh.\n                        selectionId =\n                            ownerMesh.instancedBuffers?.[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] ??\n                            renderingMesh._masterMesh.instancedBuffers?.[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName];\n                    }\n                }\n                if (!renderingMesh.hasInstances && !renderingMesh.hasThinInstances && !renderingMesh.isAnInstance && selectionId !== undefined) {\n                    effect.setFloat(\"selectionId\", selectionId);\n                }\n            }\n\n            if (!this._useDepthOcclusion) {\n                const previousDepthBuffer = engine.getDepthBuffer();\n                const previousDepthWrite = engine.getDepthWrite();\n                engine.setDepthBuffer(false);\n                engine.setDepthWrite(false);\n\n                try {\n                    // Draw\n                    renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, world) =>\n                        effect.setMatrix(\"world\", world)\n                    );\n                } finally {\n                    engine.setDepthBuffer(previousDepthBuffer);\n                    engine.setDepthWrite(previousDepthWrite);\n                }\n            } else {\n                // Draw\n                renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, world) =>\n                    effect.setMatrix(\"world\", world)\n                );\n            }\n        } else {\n            // Need to reset refresh rate of the main map\n            this._objectRenderer.resetRefreshCounter();\n        }\n\n        this.onAfterRenderMeshToEffect.notifyObservers(ownerMesh);\n    }\n\n    /** @internal */\n    public override _internalCompose(effect: Effect, _renderIndex: number): void {\n        // Texture\n        this.bindTexturesForCompose(effect);\n        effect.setFloat2(\"screenSize\", this.textureWidth, this.textureHeight);\n        effect.setColor3(\"outlineColor\", this.outlineColor);\n        effect.setFloat(\"outlineThickness\", this.outlineThickness);\n        if (this._shouldUseComposeDepthOcclusion) {\n            effect.setFloat(\"occlusionStrength\", this.occlusionStrength);\n            effect.setFloat(\"occlusionThreshold\", this.occlusionThreshold);\n        }\n\n        // Cache\n        const engine = this._engine;\n        const previousStencilBuffer = engine.getStencilBuffer();\n\n        // Draw order\n        engine.setStencilBuffer(false);\n\n        engine.drawElementsType(Material.TriangleFillMode, 0, 6);\n\n        // Draw order\n        engine.setStencilBuffer(previousStencilBuffer);\n    }\n\n    /** @internal */\n    public override _setEmissiveTextureAndColor(_mesh: Mesh, _subMesh: SubMesh, _material: Material): void {\n        // we don't use emissive texture or color for this layer\n    }\n\n    /**\n     * Returns true if the layer contains information to display, otherwise false.\n     * @returns true if the glow layer should be rendered\n     */\n    public override shouldRender(): boolean {\n        return this._selection && super.shouldRender() ? true : false;\n    }\n\n    /** @internal */\n    public override _shouldRenderMesh(mesh: Mesh): boolean {\n        // Use the base class check (renderingGroupId) rather than this.hasMesh,\n        // because LOD meshes won't be in _selection but still need to render.\n        return super.hasMesh(mesh);\n    }\n\n    /** @internal */\n    public override _addCustomEffectDefines(defines: string[]): void {\n        if (this._options.storeCameraSpaceZ) {\n            defines.push(\"#define STORE_CAMERASPACE_Z\");\n        }\n    }\n\n    /**\n     * Determine if a given mesh will be used in the current effect.\n     * @param mesh mesh to test\n     * @returns true if the mesh will be used\n     */\n    public override hasMesh(mesh: AbstractMesh): boolean {\n        if (!super.hasMesh(mesh) || !this._selection) {\n            return false;\n        }\n        return this._selection.indexOf(mesh) !== -1;\n    }\n\n    /** @internal */\n    public override _useMeshMaterial(_mesh: AbstractMesh): boolean {\n        return false;\n    }\n\n    /**\n     * Remove all the meshes currently referenced in the selection outline layer\n     */\n    public clearSelection(): void {\n        if (!this._selection) {\n            return;\n        }\n\n        for (let index = 0; index < this._selection.length; ++index) {\n            this._cleanUpInstanceSelectionId(this._selection[index] as Mesh);\n        }\n\n        // addSelection registers instanceSelectionId on the source mesh\n        // (via sourceMesh.registerInstancedBuffer), but _selection contains\n        // the instance, not the source. Clean up source meshes separately.\n        this._instancedBufferSources.forEach((sourceMesh) => this._cleanUpInstanceSelectionId(sourceMesh));\n        this._instancedBufferSources.clear();\n\n        this._selection.length = 0;\n        this._meshUniqueIdToSelectionId.length = 0;\n\n        this._nextSelectionId = 1;\n\n        this._shouldRender = false;\n    }\n\n    /**\n     * Remove instanceSelectionId instanced buffer registration from a mesh,\n     * including GPU resources (per-pass VBOs, vertex buffers, VAOs).\n     * @param mesh - The mesh to clean up\n     */\n    private _cleanUpInstanceSelectionId(mesh: Mesh): void {\n        if (mesh._userInstancedBuffersStorage) {\n            const kind = ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName;\n\n            // Dispose per-pass VBOs for ALL render passes (WebGPU).\n            // _processInstancedBuffers creates per-pass VBOs for every render pass\n            // that renders this mesh (main scene, depth renderer, etc.), not just\n            // this layer's own passes. We must clean them all up to avoid using\n            // a destroyed GPU buffer on the next submit.\n            if (mesh._userInstancedBuffersStorage.renderPasses) {\n                for (const passId in mesh._userInstancedBuffersStorage.renderPasses) {\n                    const renderPassId = Number(passId);\n                    const passVBOs = mesh._userInstancedBuffersStorage.renderPasses[renderPassId];\n                    if (passVBOs?.[kind]) {\n                        passVBOs[kind]!.dispose();\n                        delete passVBOs[kind];\n                    }\n                }\n            }\n\n            mesh._userInstancedBuffersStorage.vertexBuffers[kind]?.dispose();\n\n            const vao = mesh._userInstancedBuffersStorage.vertexArrayObjects?.[kind];\n            if (vao) {\n                // invalidate VAO is very important to keep sync between VAO and vertex buffers\n                (this._engine as ThinEngine).releaseVertexArrayObject(vao);\n                delete mesh._userInstancedBuffersStorage.vertexArrayObjects![kind];\n            }\n\n            delete mesh._userInstancedBuffersStorage.data[kind];\n            delete mesh._userInstancedBuffersStorage.vertexBuffers[kind];\n            delete mesh._userInstancedBuffersStorage.strides[kind];\n            delete mesh._userInstancedBuffersStorage.sizes[kind];\n\n            if (Object.keys(mesh._userInstancedBuffersStorage.vertexBuffers).length === 0) {\n                mesh._userInstancedBuffersStorage = undefined!;\n            }\n        }\n        if (mesh.instancedBuffers?.[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] !== undefined) {\n            delete mesh.instancedBuffers[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName];\n        }\n\n        // In WebGPU non-compat mode, cached render bundles (fastBundle) bake\n        // vertex-buffer GPU handles at record time. Because the new VBO has\n        // the same format (and thus the same hashCode), the pipeline cache\n        // won't detect the change and would replay the stale bundle.\n        // Resetting the draw cache forces new bundles to be recorded.\n        if (this._engine.isWebGPU && !this._engine.compatibilityMode) {\n            mesh.resetDrawCache();\n        }\n    }\n\n    /**\n     * Adds mesh or group of mesh to the current selection\n     *\n     * If a group of meshes is provided, they will outline as a single unit\n     * @param meshOrGroup Meshes to add to the selection\n     */\n    public addSelection(meshOrGroup: AbstractMesh | AbstractMesh[]): void {\n        if (!this._selection) {\n            return;\n        }\n\n        const nextId = this._nextSelectionId;\n\n        const group = Array.isArray(meshOrGroup) ? meshOrGroup : [meshOrGroup];\n        if (group.length === 0) {\n            return;\n        }\n\n        for (let meshIndex = 0; meshIndex < group.length; ++meshIndex) {\n            const mesh = group[meshIndex];\n\n            this._selection.push(mesh); // add to render list\n\n            if (mesh.hasInstances || mesh.isAnInstance) {\n                const sourceMesh = (mesh as InstancedMesh).sourceMesh ?? (mesh as Mesh);\n\n                if (sourceMesh.instancedBuffers?.[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] === undefined) {\n                    sourceMesh.registerInstancedBuffer(ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName, 1);\n                }\n                this._instancedBufferSources.add(sourceMesh);\n\n                mesh.instancedBuffers[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] = nextId;\n\n                // Also register instanceSelectionId on LOD meshes so hardware instancing\n                // works during LOD transitions (LOD meshes replace the source mesh as the\n                // renderingMesh, and _processInstancedBuffers only processes kinds that\n                // are registered on the rendering mesh).\n                const lodLevels = sourceMesh.getLODLevels();\n                for (const level of lodLevels) {\n                    if (level.mesh) {\n                        if (level.mesh.instancedBuffers?.[ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName] === undefined) {\n                            level.mesh.registerInstancedBuffer(ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName, 1);\n                        }\n                        this._instancedBufferSources.add(level.mesh);\n                    }\n                }\n            } else if (mesh.hasThinInstances) {\n                const thinInstanceCount = (mesh as Mesh).thinInstanceCount;\n                const selectionIdData = new Float32Array(thinInstanceCount);\n                for (let i = 0; i < thinInstanceCount; i++) {\n                    selectionIdData[i] = nextId;\n                }\n                (mesh as Mesh).thinInstanceSetBuffer(ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName, selectionIdData, 1);\n            } else {\n                this._meshUniqueIdToSelectionId[mesh.uniqueId] = nextId;\n            }\n        }\n        this._nextSelectionId += 1;\n\n        this._shouldRender = true;\n    }\n\n    /**\n     * Free any resources and references associated to a mesh.\n     * Internal use\n     * @param mesh The mesh to free.\n     * @internal\n     */\n    public _disposeMesh(mesh: Mesh): void {\n        const selection = this._selection;\n        if (!selection) {\n            return;\n        }\n\n        const index = selection.indexOf(mesh);\n        if (index !== -1) {\n            selection.splice(index, 1);\n\n            if (mesh.hasInstances) {\n                mesh.removeVerticesData(ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName);\n            } else if (mesh.hasThinInstances) {\n                (mesh as Mesh).thinInstanceSetBuffer(ThinSelectionOutlineLayer.InstanceSelectionIdAttributeName, null);\n            }\n\n            if (mesh.isAnInstance) {\n                const sourceMesh = (mesh as unknown as InstancedMesh).sourceMesh;\n                // Only remove the source from tracking if no other selected\n                // instance shares it, to avoid leaking its GPU resources.\n                if (sourceMesh && !selection.some((m) => m !== mesh && m.isAnInstance && (m as unknown as InstancedMesh).sourceMesh === sourceMesh)) {\n                    this._instancedBufferSources.delete(sourceMesh);\n                }\n            }\n\n            if (selection.length === 0) {\n                this._shouldRender = false;\n            }\n        }\n    }\n\n    /**\n     * Dispose the effect layer and free resources.\n     */\n    public override dispose(): void {\n        this.clearSelection();\n        this._selection = null;\n\n        super.dispose();\n    }\n}\n","import { type FrameGraph, type Scene, type IThinSelectionOutlineLayerOptions, type FrameGraphTextureHandle, type Effect, type FrameGraphRenderContext } from \"core/index\";\r\nimport { ThinSelectionOutlineLayer } from \"core/Layers/thinSelectionOutlineLayer\";\r\nimport { FrameGraphBaseLayerTask, FrameGraphBaseLayerBlurType } from \"./baseLayerTask\";\r\n\r\n/**\r\n * Task which applies a selection outline effect to a texture.\r\n */\r\nexport class FrameGraphSelectionOutlineLayerTask extends FrameGraphBaseLayerTask {\r\n    /**\r\n     * The selection outline layer object. Use this object to update the selection outline layer properties (e.g. intensity, blur kernel size).\r\n     */\r\n    public override readonly layer: ThinSelectionOutlineLayer;\r\n\r\n    /**\r\n     * The depth texture to use when rendering the selection outline layer.\r\n     * It must store the scene depth in camera view space Z, normalized or not.\r\n     * If not normalized, the storeCameraSpaceZ option must be passed to the constructor.\r\n     * Required only when layer.useDepthOcclusion is true and layer.occlusionStrength is greater than zero.\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle | undefined;\r\n\r\n    /**\r\n     * Constructs a new selection outline layer task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param scene The scene to render the selection outline layer in.\r\n     * @param options Options for the selection outline layer.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene, options?: IThinSelectionOutlineLayerOptions) {\r\n        super(name, frameGraph, scene, new ThinSelectionOutlineLayer(name, scene, options, true), 0, FrameGraphBaseLayerBlurType.None, false, false, false);\r\n\r\n        this._objectRendererForLayerTask.objectList = {\r\n            meshes: this.layer._selection || [],\r\n            particleSystems: [],\r\n            spriteManagers: [],\r\n        };\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSelectionOutlineLayerTask\";\r\n    }\r\n\r\n    public override record() {\r\n        const useDepthOcclusion = this.layer.useDepthOcclusion && this.layer.occlusionStrength > 0;\r\n\r\n        if (useDepthOcclusion && this.depthTexture === undefined) {\r\n            throw new Error(`FrameGraphSelectionOutlineLayerTask \"${this.name}\": depthTexture is required`);\r\n        }\r\n\r\n        super.record(false, (context: FrameGraphRenderContext, effect: Effect) => {\r\n            context.bindTextureHandle(effect, \"maskSampler\", this._objectRendererForLayerTask.outputTexture);\r\n            if (useDepthOcclusion) {\r\n                context.bindTextureHandle(effect, \"depthSampler\", this.depthTexture!);\r\n            }\r\n        });\r\n\r\n        this.layer.textureWidth = this._layerTextureDimensions.width;\r\n        this.layer.textureHeight = this._layerTextureDimensions.height;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type Scene,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraph,\r\n    type FrameGraphTextureHandle,\r\n    type NodeRenderGraphConnectionPoint,\r\n    type FrameGraphObjectRendererTask,\r\n} from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointDirection } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphSelectionOutlineLayerTask } from \"core/FrameGraph/Tasks/Layers/selectionOutlineTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { NodeRenderGraphConnectionPointCustomObject } from \"../../nodeRenderGraphConnectionPointCustomObject\";\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"../Rendering/baseObjectRendererBlock\";\r\nimport { Color3 } from \"core/Maths/math.color.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the selection outline layer\r\n */\r\nexport class NodeRenderGraphSelectionOutlineLayerBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphSelectionOutlineLayerTask;\r\n\r\n    public override _additionalConstructionParameters: [number, number | undefined, number];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphSelectionOutlineLayerBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param layerTextureRatio multiplication factor applied to the main texture size to compute the size of the layer render target texture (default: 1.0)\r\n     * @param layerTextureFixedSize defines the fixed size of the layer render target texture. Takes precedence over layerTextureRatio if provided (default: undefined)\r\n     * @param layerTextureType defines the type of the layer texture (default: Constants.TEXTURETYPE_HALF_FLOAT)\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        frameGraph: FrameGraph,\r\n        scene: Scene,\r\n        layerTextureRatio = 1.0,\r\n        layerTextureFixedSize?: number,\r\n        layerTextureType = Constants.TEXTURETYPE_HALF_FLOAT\r\n    ) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [layerTextureRatio, layerTextureFixedSize, layerTextureType];\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"layer\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\r\n            \"objectRenderer\",\r\n            NodeRenderGraphBlockConnectionPointTypes.Object,\r\n            false,\r\n            new NodeRenderGraphConnectionPointCustomObject(\r\n                \"objectRenderer\",\r\n                this,\r\n                NodeRenderGraphConnectionPointDirection.Input,\r\n                NodeRenderGraphBaseObjectRendererBlock,\r\n                \"NodeRenderGraphBaseObjectRendererBlock\"\r\n            )\r\n        );\r\n        this.registerInput(\"depth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.depth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth | NodeRenderGraphBlockConnectionPointTypes.TextureNormalizedViewDepth\r\n        );\r\n\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBufferDepthStencil);\r\n        this.layer.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n\r\n        this.output._typeConnectionSource = this.target;\r\n\r\n        this._frameGraphTask = new FrameGraphSelectionOutlineLayerTask(this.name, this._frameGraph, this._scene, {\r\n            mainTextureRatio: layerTextureRatio,\r\n            mainTextureFixedSize: layerTextureFixedSize,\r\n            mainTextureType: layerTextureType,\r\n        });\r\n    }\r\n\r\n    private _createTask(layerTextureRatio: number, layerTextureFixedSize: number, layerTextureType: number) {\r\n        const outlineColor = this.outlineColor;\r\n        const outlineThickness = this.outlineThickness;\r\n        const occlusionStrength = this.occlusionStrength;\r\n        const occlusionThreshold = this.occlusionThreshold;\r\n        const useDepthOcclusion = this.useDepthOcclusion;\r\n\r\n        this._frameGraphTask?.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphSelectionOutlineLayerTask(this.name, this._frameGraph, this._scene, {\r\n            mainTextureRatio: layerTextureRatio,\r\n            mainTextureFixedSize: layerTextureFixedSize,\r\n            mainTextureType: layerTextureType,\r\n        });\r\n\r\n        this.outlineColor = outlineColor;\r\n        this.outlineThickness = outlineThickness;\r\n        this.occlusionStrength = occlusionStrength;\r\n        this.occlusionThreshold = occlusionThreshold;\r\n        this.useDepthOcclusion = useDepthOcclusion;\r\n\r\n        this._additionalConstructionParameters = [layerTextureRatio, layerTextureFixedSize, layerTextureType];\r\n    }\r\n\r\n    /** Multiplication factor applied to the main texture size to compute the size of the layer render target texture */\r\n    @editableInPropertyPage(\"Layer texture ratio\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get layerTextureRatio() {\r\n        return this._frameGraphTask.layer._options.mainTextureRatio;\r\n    }\r\n\r\n    public set layerTextureRatio(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(value, options.mainTextureFixedSize, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the fixed size of the layer render target texture. Takes precedence over layerTextureRatio if provided */\r\n    @editableInPropertyPage(\"Layer texture fixed size\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get layerTextureFixedSize() {\r\n        return this._frameGraphTask.layer._options.mainTextureFixedSize;\r\n    }\r\n\r\n    public set layerTextureFixedSize(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.mainTextureRatio, value, options.mainTextureType);\r\n    }\r\n\r\n    /** Defines the type of the layer texture */\r\n    @editableInPropertyPage(\"Layer texture type\", PropertyTypeForEdition.TextureType, \"PROPERTIES\")\r\n    public get layerTextureType() {\r\n        return this._frameGraphTask.layer._options.mainTextureType;\r\n    }\r\n\r\n    public set layerTextureType(value: number) {\r\n        const options = this._frameGraphTask.layer._options;\r\n\r\n        this._createTask(options.mainTextureRatio, options.mainTextureFixedSize, value);\r\n    }\r\n\r\n    /** The outline color */\r\n    @editableInPropertyPage(\"Outline color\", PropertyTypeForEdition.Color3, \"PROPERTIES\")\r\n    public get outlineColor() {\r\n        return this._frameGraphTask.layer.outlineColor;\r\n    }\r\n\r\n    public set outlineColor(value: Color3) {\r\n        this._frameGraphTask.layer.outlineColor = value;\r\n    }\r\n\r\n    /** The thickness of the edges */\r\n    @editableInPropertyPage(\"Outline thickness\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 30 })\r\n    public get outlineThickness() {\r\n        return this._frameGraphTask.layer.outlineThickness;\r\n    }\r\n\r\n    public set outlineThickness(value: number) {\r\n        this._frameGraphTask.layer.outlineThickness = value;\r\n    }\r\n\r\n    /** The strength of the occlusion effect */\r\n    @editableInPropertyPage(\"Occlusion strength\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get occlusionStrength() {\r\n        return this._frameGraphTask.layer.occlusionStrength;\r\n    }\r\n\r\n    public set occlusionStrength(value: number) {\r\n        this._frameGraphTask.layer.occlusionStrength = value;\r\n    }\r\n\r\n    /** The occlusion threshold */\r\n    @editableInPropertyPage(\"Occlusion threshold\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get occlusionThreshold() {\r\n        return this._frameGraphTask.layer.occlusionThreshold;\r\n    }\r\n\r\n    public set occlusionThreshold(value: number) {\r\n        this._frameGraphTask.layer.occlusionThreshold = value;\r\n    }\r\n\r\n    /** Whether to use depth when drawing selection outlines */\r\n    @editableInPropertyPage(\"Use depth occlusion\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get useDepthOcclusion() {\r\n        return this._frameGraphTask.layer.useDepthOcclusion;\r\n    }\r\n\r\n    public set useDepthOcclusion(value: boolean) {\r\n        this._frameGraphTask.layer.useDepthOcclusion = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphSelectionOutlineLayerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target texture input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the layer texture input component\r\n     */\r\n    public get layer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the objectRenderer input component\r\n     */\r\n    public get objectRenderer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth input component\r\n     */\r\n    public get depth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.layerTexture = this.layer.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.objectRendererTask = this.objectRenderer.connectedPoint?.value as FrameGraphObjectRendererTask;\r\n        this._frameGraphTask.depthTexture = this.depth.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.outlineColor = new BABYLON.Color3(${this.outlineColor.r}, ${this.outlineColor.g}, ${this.outlineColor.b});`);\r\n        codes.push(`${this._codeVariableName}.outlineThickness = ${this.outlineThickness};`);\r\n        codes.push(`${this._codeVariableName}.occlusionStrength = ${this.occlusionStrength};`);\r\n        codes.push(`${this._codeVariableName}.occlusionThreshold = ${this.occlusionThreshold};`);\r\n        codes.push(`${this._codeVariableName}.useDepthOcclusion = ${this.useDepthOcclusion};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.outlineColor = this.outlineColor.asArray();\r\n        serializationObject.outlineThickness = this.outlineThickness;\r\n        serializationObject.occlusionStrength = this.occlusionStrength;\r\n        serializationObject.occlusionThreshold = this.occlusionThreshold;\r\n        serializationObject.useDepthOcclusion = this.useDepthOcclusion;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.outlineColor = Color3.FromArray(serializationObject.outlineColor);\r\n        this.outlineThickness = serializationObject.outlineThickness;\r\n        this.occlusionStrength = serializationObject.occlusionStrength;\r\n        this.occlusionThreshold = serializationObject.occlusionThreshold;\r\n        this.useDepthOcclusion = serializationObject.useDepthOcclusion ?? true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for selectionOutlineLayerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSelectionOutlineLayerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphSelectionOutlineLayerBlock\", NodeRenderGraphSelectionOutlineLayerBlock);\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderPass, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { ThinAnaglyphPostProcess } from \"core/PostProcesses/thinAnaglyphPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies an anaglyph post process.\r\n */\r\nexport class FrameGraphAnaglyphTask extends FrameGraphPostProcessTask {\r\n    /**\r\n     * The texture to use as the left texture.\r\n     */\r\n    public leftTexture: FrameGraphTextureHandle;\r\n\r\n    public override readonly postProcess: ThinAnaglyphPostProcess;\r\n\r\n    /**\r\n     * Constructs a new anaglyph task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the anaglyph effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinAnaglyphPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinAnaglyphPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphAnaglyphTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.leftTexture === undefined) {\r\n            throw new Error(`FrameGraphAnaglyphTask \"${this.name}\": sourceTexture and leftTexture are required`);\r\n        }\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {\r\n            context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"leftSampler\", this.leftTexture);\r\n        });\r\n\r\n        pass.addDependencies(this.leftTexture);\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type FrameGraph, type FrameGraphTask } from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\ninterface IPostProcessLike {\r\n    sourceSamplingMode: number;\r\n    get alphaMode(): number;\r\n    set alphaMode(mode: number);\r\n    sourceTexture?: FrameGraphTextureHandle;\r\n    targetTexture?: FrameGraphTextureHandle;\r\n    outputTexture: FrameGraphTextureHandle;\r\n}\r\n\r\n/**\r\n * Base class for post process like blocks.\r\n */\r\nexport class NodeRenderGraphBasePostProcessBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: IPostProcessLike & FrameGraphTask;\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphBasePostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"source\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.source.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAll);\r\n    }\r\n\r\n    protected _finalizeInputOutputRegistering() {\r\n        this._addDependenciesInput();\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = () => {\r\n            return this.target.isConnected ? this.target : this.source;\r\n        };\r\n    }\r\n\r\n    /** Sampling mode used to sample from the source texture */\r\n    @editableInPropertyPage(\"Source sampling mode\", PropertyTypeForEdition.SamplingMode, \"BASE PROPERTIES\")\r\n    public get sourceSamplingMode() {\r\n        return this._frameGraphTask.sourceSamplingMode;\r\n    }\r\n\r\n    public set sourceSamplingMode(value: number) {\r\n        this._frameGraphTask.sourceSamplingMode = value;\r\n    }\r\n\r\n    /** The alpha mode to use when applying the post process. */\r\n    @editableInPropertyPage(\"Alpha Mode\", PropertyTypeForEdition.List, \"BASE PROPERTIES\", {\r\n        options: [\r\n            { label: \"Disabled\", value: Constants.ALPHA_DISABLE },\r\n            { label: \"Combine\", value: Constants.ALPHA_COMBINE },\r\n            { label: \"One One\", value: Constants.ALPHA_ONEONE },\r\n            { label: \"Add\", value: Constants.ALPHA_ADD },\r\n            { label: \"Subtract\", value: Constants.ALPHA_SUBTRACT },\r\n            { label: \"Multiply\", value: Constants.ALPHA_MULTIPLY },\r\n            { label: \"Maximized\", value: Constants.ALPHA_MAXIMIZED },\r\n            { label: \"Pre-multiplied\", value: Constants.ALPHA_PREMULTIPLIED },\r\n            { label: \"Pre-multiplied Porter Duff\", value: Constants.ALPHA_PREMULTIPLIED_PORTERDUFF },\r\n            { label: \"Screen Mode\", value: Constants.ALPHA_SCREENMODE },\r\n            { label: \"OneOne OneOne\", value: Constants.ALPHA_ONEONE_ONEONE },\r\n            { label: \"Alpha to Color\", value: Constants.ALPHA_ALPHATOCOLOR },\r\n            { label: \"Reverse One Minus\", value: Constants.ALPHA_REVERSEONEMINUS },\r\n            { label: \"Source+Dest * (1 - SourceAlpha)\", value: Constants.ALPHA_SRC_DSTONEMINUSSRCALPHA },\r\n            { label: \"OneOne OneZero\", value: Constants.ALPHA_ONEONE_ONEZERO },\r\n            { label: \"Exclusion\", value: Constants.ALPHA_EXCLUSION },\r\n            { label: \"Layer Accumulate\", value: Constants.ALPHA_LAYER_ACCUMULATE },\r\n        ],\r\n    })\r\n    public get alphaMode(): number {\r\n        return this._frameGraphTask.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(value: number) {\r\n        this._frameGraphTask.alphaMode = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBasePostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the source input component\r\n     */\r\n    public get source(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.sourceTexture = this.source.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.sourceSamplingMode = ${this.sourceSamplingMode};`);\r\n        codes.push(`${this._codeVariableName}.alphaMode = ${this.alphaMode};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.sourceSamplingMode = this.sourceSamplingMode;\r\n        serializationObject.alphaMode = this.alphaMode;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.sourceSamplingMode = serializationObject.sourceSamplingMode;\r\n        this.alphaMode = serializationObject.alphaMode ?? Constants.ALPHA_DISABLE;\r\n    }\r\n}\r\n","import { type FrameGraphPostProcessTask, type IViewportLike } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeRenderGraphBasePostProcessBlock } from \"./basePostProcessBlock\";\r\n\r\n/**\r\n * Base class for post process blocks.\r\n */\r\nexport class NodeRenderGraphBaseWithPropertiesPostProcessBlock extends NodeRenderGraphBasePostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphPostProcessTask;\r\n\r\n    protected _useCurrentViewport = false;\r\n    protected _useFullScreenViewport = true;\r\n    protected _viewport: IViewportLike = { x: 0, y: 0, width: 1, height: 1 };\r\n\r\n    /** If true, the depth attachment will be read-only. */\r\n    @editableInPropertyPage(\"Depth Read Only\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get depthReadOnly(): boolean {\r\n        return this._frameGraphTask.depthReadOnly;\r\n    }\r\n\r\n    public set depthReadOnly(value: boolean) {\r\n        this._frameGraphTask.depthReadOnly = value;\r\n    }\r\n\r\n    /** If true, the stencil attachment will be read-only. */\r\n    @editableInPropertyPage(\"Stencil Read Only\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get stencilReadOnly(): boolean {\r\n        return this._frameGraphTask.stencilReadOnly;\r\n    }\r\n\r\n    public set stencilReadOnly(value: boolean) {\r\n        this._frameGraphTask.stencilReadOnly = value;\r\n    }\r\n\r\n    /** If true, color write will be disabled when applying the post process. */\r\n    @editableInPropertyPage(\"Disable Color Write\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get disableColorWrite(): boolean {\r\n        return this._frameGraphTask.disableColorWrite;\r\n    }\r\n\r\n    public set disableColorWrite(value: boolean) {\r\n        this._frameGraphTask.disableColorWrite = value;\r\n    }\r\n\r\n    /** If true, the post process will be generated by a back face full-screen quad (CW order). */\r\n    @editableInPropertyPage(\"Draw Back Face\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get drawBackFace(): boolean {\r\n        return this._frameGraphTask.drawBackFace;\r\n    }\r\n\r\n    public set drawBackFace(value: boolean) {\r\n        this._frameGraphTask.drawBackFace = value;\r\n    }\r\n\r\n    /** If depth testing should be enabled (default is true). */\r\n    @editableInPropertyPage(\"Depth Test\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get depthTest(): boolean {\r\n        return this._frameGraphTask.depthTest;\r\n    }\r\n\r\n    public set depthTest(value: boolean) {\r\n        this._frameGraphTask.depthTest = value;\r\n    }\r\n\r\n    private _setViewport() {\r\n        if (this._useCurrentViewport) {\r\n            this._frameGraphTask.viewport = null;\r\n        } else if (this._useFullScreenViewport) {\r\n            this._frameGraphTask.viewport = undefined;\r\n        } else {\r\n            this._frameGraphTask.viewport = this._viewport;\r\n        }\r\n    }\r\n\r\n    /** If true, the current viewport will be left unchanged. */\r\n    @editableInPropertyPage(\"Use currently active viewport\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get useCurrentViewport(): boolean {\r\n        return this._useCurrentViewport;\r\n    }\r\n\r\n    public set useCurrentViewport(value: boolean) {\r\n        this._useCurrentViewport = value;\r\n        this._setViewport();\r\n    }\r\n\r\n    /** If true, a full screen viewport will be used. */\r\n    @editableInPropertyPage(\"Use full screen viewport\", PropertyTypeForEdition.Boolean, \"BASE PROPERTIES\")\r\n    public get useFullScreenViewport(): boolean {\r\n        return this._useFullScreenViewport;\r\n    }\r\n\r\n    public set useFullScreenViewport(value: boolean) {\r\n        this._useFullScreenViewport = value;\r\n        this._setViewport();\r\n    }\r\n\r\n    /** The viewport to use. */\r\n    @editableInPropertyPage(\"    Viewport\", PropertyTypeForEdition.Viewport, \"BASE PROPERTIES\")\r\n    public get viewport(): IViewportLike {\r\n        return this._viewport;\r\n    }\r\n\r\n    public set viewport(value: IViewportLike) {\r\n        this._viewport = value;\r\n        this._setViewport();\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBaseWithPropertiesPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.depthReadOnly = ${this.depthReadOnly};`);\r\n        codes.push(`${this._codeVariableName}.stencilReadOnly = ${this.stencilReadOnly};`);\r\n        codes.push(`${this._codeVariableName}.disableColorWrite = ${this.disableColorWrite};`);\r\n        codes.push(`${this._codeVariableName}.drawBackFace = ${this.drawBackFace};`);\r\n        codes.push(`${this._codeVariableName}.depthTest = ${this.depthTest};`);\r\n        codes.push(`${this._codeVariableName}.viewport = ${this._useCurrentViewport ? \"null\" : this._useFullScreenViewport ? \"undefined\" : JSON.stringify(this._viewport)};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.depthReadOnly = this.depthReadOnly;\r\n        serializationObject.stencilReadOnly = this.stencilReadOnly;\r\n        serializationObject.disableColorWrite = this.disableColorWrite;\r\n        serializationObject.drawBackFace = this.drawBackFace;\r\n        serializationObject.depthTest = this.depthTest;\r\n        serializationObject.useCurrentViewport = this._useCurrentViewport;\r\n        serializationObject.useFullScreenViewport = this._useFullScreenViewport;\r\n        serializationObject.viewport = this._viewport;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.depthReadOnly = !!serializationObject.depthReadOnly;\r\n        this.stencilReadOnly = !!serializationObject.stencilReadOnly;\r\n        this.disableColorWrite = !!serializationObject.disableColorWrite;\r\n        this.drawBackFace = !!serializationObject.drawBackFace;\r\n        this.depthTest = serializationObject.depthTest ?? true;\r\n        if (serializationObject.useCurrentViewport !== undefined) {\r\n            this._useCurrentViewport = serializationObject.useCurrentViewport;\r\n            this._useFullScreenViewport = serializationObject.useFullScreenViewport;\r\n            this._viewport = serializationObject.viewport;\r\n        }\r\n        this._setViewport();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { FrameGraphAnaglyphTask } from \"core/FrameGraph/Tasks/PostProcesses/anaglyphTask\";\r\nimport { ThinAnaglyphPostProcess } from \"core/PostProcesses/thinAnaglyphPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the anaglyph post process\r\n */\r\nexport class NodeRenderGraphAnaglyphPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphAnaglyphTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderAnaglyphPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"leftTexture\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.leftTexture.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphAnaglyphTask(this.name, frameGraph, new ThinAnaglyphPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphAnaglyphPostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left texture input component\r\n     */\r\n    public get leftTexture(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.leftTexture = this.leftTexture.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anaglyphPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnaglyphPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphAnaglyphPostProcessBlock\", NodeRenderGraphAnaglyphPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to render in black and white\r\n */\r\nexport class ThinBlackAndWhitePostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"blackAndWhite\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"degree\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/blackAndWhite.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/blackAndWhite.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new black and white post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinBlackAndWhitePostProcess.FragmentUrl,\r\n            uniforms: ThinBlackAndWhitePostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Effect intensity (default: 1)\r\n     */\r\n    public degree = 1;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setFloat(\"degree\", this.degree);\r\n    }\r\n}\r\n","import { type FrameGraph } from \"core/FrameGraph/frameGraph\";\r\nimport { ThinBlackAndWhitePostProcess } from \"core/PostProcesses/thinBlackAndWhitePostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a black and white post process.\r\n */\r\nexport class FrameGraphBlackAndWhiteTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinBlackAndWhitePostProcess;\r\n\r\n    /**\r\n     * Constructs a new black and white task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the black and white effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinBlackAndWhitePostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinBlackAndWhitePostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphBlackAndWhiteTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphBlackAndWhiteTask } from \"core/FrameGraph/Tasks/PostProcesses/blackAndWhiteTask\";\r\nimport { ThinBlackAndWhitePostProcess } from \"core/PostProcesses/thinBlackAndWhitePostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the black and white post process\r\n */\r\nexport class NodeRenderGraphBlackAndWhitePostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphBlackAndWhiteTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new BlackAndWhitePostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphBlackAndWhiteTask(this.name, frameGraph, new ThinBlackAndWhitePostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** Degree of conversion to black and white (default: 1 - full b&w conversion) */\r\n    @editableInPropertyPage(\"Degree\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get degree(): number {\r\n        return this._frameGraphTask.postProcess.degree;\r\n    }\r\n\r\n    public set degree(value: number) {\r\n        this._frameGraphTask.postProcess.degree = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBlackAndWhitePostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.degree = ${this.degree};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.degree = this.degree;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.degree = serializationObject.degree;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for blackAndWhitePostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBlackAndWhitePostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphBlackAndWhitePostProcessBlock\", NodeRenderGraphBlackAndWhitePostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinBloomMergePostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"bloomMerge\";\r\n\r\n    public static readonly Uniforms = [\"bloomWeight\"];\r\n\r\n    public static readonly Samplers = [\"bloomBlur\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/bloomMerge.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/bloomMerge.fragment\"));\r\n        }\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinBloomMergePostProcess.FragmentUrl,\r\n            uniforms: ThinBloomMergePostProcess.Uniforms,\r\n            samplers: ThinBloomMergePostProcess.Samplers,\r\n        });\r\n    }\r\n\r\n    /** Weight of the bloom to be added to the original input. */\r\n    public weight = 1;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setFloat(\"bloomWeight\", this.weight);\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass } from \"core/index\";\r\nimport { ThinBloomMergePostProcess } from \"core/PostProcesses/thinBloomMergePostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphBloomMergeTask extends FrameGraphPostProcessTask {\r\n    public blurTexture: FrameGraphTextureHandle;\r\n\r\n    public override readonly postProcess: ThinBloomMergePostProcess;\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinBloomMergePostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinBloomMergePostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphBloomMergeTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.blurTexture === undefined) {\r\n            throw new Error(`FrameGraphBloomMergeTask \"${this.name}\": sourceTexture and blurTexture are required`);\r\n        }\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {\r\n            context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"bloomBlur\", this.blurTexture);\r\n        });\r\n\r\n        pass.addDependencies(this.blurTexture);\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { ToGammaSpace } from \"../Maths/math.constants\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to extract highlights.\r\n */\r\nexport class ThinExtractHighlightsPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"extractHighlights\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"threshold\", \"exposure\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/extractHighlights.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/extractHighlights.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new extract highlights post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinExtractHighlightsPostProcess.FragmentUrl,\r\n            uniforms: ThinExtractHighlightsPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The luminance threshold, pixels below this value will be set to black.\r\n     */\r\n    public threshold = 0.9;\r\n\r\n    /** @internal */\r\n    public _exposure = 1;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat(\"threshold\", Math.pow(this.threshold, ToGammaSpace));\r\n        effect.setFloat(\"exposure\", this._exposure);\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine } from \"core/index\";\r\nimport { ThinBloomMergePostProcess } from \"./thinBloomMergePostProcess\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { ThinBlurPostProcess } from \"./thinBlurPostProcess\";\r\nimport { ThinExtractHighlightsPostProcess } from \"./thinExtractHighlightsPostProcess\";\r\n\r\n/**\r\n * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras\r\n */\r\nexport class ThinBloomEffect {\r\n    /** @internal */\r\n    public _downscale: ThinExtractHighlightsPostProcess;\r\n    /** @internal */\r\n    public _blurX: ThinBlurPostProcess;\r\n    /** @internal */\r\n    public _blurY: ThinBlurPostProcess;\r\n    /** @internal */\r\n    public _merge: ThinBloomMergePostProcess;\r\n\r\n    /**\r\n     * The luminance threshold to find bright areas of the image to bloom.\r\n     */\r\n    public get threshold(): number {\r\n        return this._downscale.threshold;\r\n    }\r\n    public set threshold(value: number) {\r\n        this._downscale.threshold = value;\r\n    }\r\n\r\n    /**\r\n     * The strength of the bloom.\r\n     */\r\n    public get weight(): number {\r\n        return this._merge.weight;\r\n    }\r\n    public set weight(value: number) {\r\n        this._merge.weight = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies the size of the bloom blur kernel, relative to the final output size\r\n     */\r\n    public get kernel(): number {\r\n        return this._blurX.kernel / this.scale;\r\n    }\r\n    public set kernel(value: number) {\r\n        this._blurX.kernel = value * this.scale;\r\n        this._blurY.kernel = value * this.scale;\r\n    }\r\n\r\n    /**\r\n     * The ratio of the blur texture to the input texture that should be used to compute the bloom.\r\n     */\r\n    public readonly scale: number;\r\n\r\n    /**\r\n     * Creates a new instance of @see ThinBloomEffect\r\n     * @param name The name of the bloom render effect\r\n     * @param engine The engine which the render effect will be applied. (default: current engine)\r\n     * @param scale The ratio of the blur texture to the input texture that should be used to compute the bloom.\r\n     * @param blockCompilation If shaders should not be compiled when the effect is created (default: false)\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine>, scale: number, blockCompilation = false) {\r\n        this.scale = scale;\r\n        this._downscale = new ThinExtractHighlightsPostProcess(name + \"_downscale\", engine, { blockCompilation });\r\n        this._blurX = new ThinBlurPostProcess(name + \"_blurX\", engine, new Vector2(1, 0), 10, { blockCompilation });\r\n        this._blurY = new ThinBlurPostProcess(name + \"_blurY\", engine, new Vector2(0, 1), 10, { blockCompilation });\r\n        this._merge = new ThinBloomMergePostProcess(name + \"_merge\", engine, { blockCompilation });\r\n    }\r\n\r\n    /**\r\n     * Checks if the effect is ready to be used\r\n     * @returns if the effect is ready\r\n     */\r\n    public isReady() {\r\n        return this._downscale.isReady() && this._blurX.isReady() && this._blurY.isReady() && this._merge.isReady();\r\n    }\r\n}\r\n","import { type FrameGraph } from \"core/index\";\r\nimport { ThinExtractHighlightsPostProcess } from \"core/PostProcesses/thinExtractHighlightsPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task used to extract highlights from a scene.\r\n */\r\nexport class FrameGraphExtractHighlightsTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinExtractHighlightsPostProcess;\r\n\r\n    /**\r\n     * Constructs a new extract highlights task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinExtractHighlightsPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinExtractHighlightsPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphExtractHighlightsTask\";\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphBloomMergeTask } from \"./bloomMergeTask\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { ThinBloomEffect } from \"core/PostProcesses/thinBloomEffect\";\r\nimport { FrameGraphExtractHighlightsTask } from \"./extractHighlightsTask\";\r\nimport { FrameGraphBlurTask } from \"./blurTask\";\r\n\r\n/**\r\n * Task which applies a bloom render effect.\r\n */\r\nexport class FrameGraphBloomTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to apply the bloom effect on.\r\n     */\r\n    public sourceTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the source texture.\r\n     */\r\n    public sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The alpha mode to use when applying the bloom effect.\r\n     */\r\n    public get alphaMode() {\r\n        return this._merge.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(mode: number) {\r\n        this._merge.alphaMode = mode;\r\n    }\r\n\r\n    /**\r\n     * The target texture to render the bloom effect to.\r\n     * If not supplied, a texture with the same configuration as the source texture will be created.\r\n     */\r\n    public targetTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture of the bloom effect.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The bloom effect to apply.\r\n     */\r\n    public readonly bloom: ThinBloomEffect;\r\n\r\n    /**\r\n     * Whether the bloom effect is HDR.\r\n     * When true, the bloom effect will use a higher precision texture format (half float or float). Else, it will use unsigned byte.\r\n     */\r\n    public readonly hdr: boolean;\r\n\r\n    /**\r\n     * The name of the task.\r\n     */\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this._downscale) {\r\n            this._downscale.name = `${name} Downscale`;\r\n        }\r\n\r\n        if (this._blurX) {\r\n            this._blurX.name = `${name} Blur X`;\r\n        }\r\n\r\n        if (this._blurY) {\r\n            this._blurY.name = `${name} Blur Y`;\r\n        }\r\n\r\n        if (this._merge) {\r\n            this._merge.name = `${name} Merge`;\r\n        }\r\n    }\r\n\r\n    private readonly _downscale: FrameGraphExtractHighlightsTask;\r\n    private readonly _blurX: FrameGraphBlurTask;\r\n    private readonly _blurY: FrameGraphBlurTask;\r\n    private readonly _merge: FrameGraphBloomMergeTask;\r\n    private readonly _defaultPipelineTextureType: number;\r\n\r\n    /**\r\n     * Constructs a new bloom task.\r\n     * @param name Name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param weight Weight of the bloom effect.\r\n     * @param kernel Kernel size of the bloom effect.\r\n     * @param threshold Threshold of the bloom effect.\r\n     * @param hdr Whether the bloom effect is HDR.\r\n     * @param bloomScale The scale of the bloom effect. This value is multiplied by the source texture size to determine the bloom texture size.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, weight = 0.25, kernel = 64, threshold = 0.2, hdr = false, bloomScale = 0.5) {\r\n        super(name, frameGraph);\r\n\r\n        this.hdr = hdr;\r\n\r\n        this._defaultPipelineTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (hdr) {\r\n            const caps = frameGraph.engine.getCaps();\r\n            if (caps.textureHalfFloatRender) {\r\n                this._defaultPipelineTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else if (caps.textureFloatRender) {\r\n                this._defaultPipelineTextureType = Constants.TEXTURETYPE_FLOAT;\r\n            }\r\n        }\r\n\r\n        this.bloom = new ThinBloomEffect(name, frameGraph.engine, bloomScale);\r\n        this.bloom.threshold = threshold;\r\n        this.bloom.kernel = kernel;\r\n        this.bloom.weight = weight;\r\n\r\n        this._downscale = new FrameGraphExtractHighlightsTask(`${name} Downscale`, this._frameGraph, this.bloom._downscale);\r\n        this._blurX = new FrameGraphBlurTask(`${name} Blur X`, this._frameGraph, this.bloom._blurX);\r\n        this._blurY = new FrameGraphBlurTask(`${name} Blur Y`, this._frameGraph, this.bloom._blurY);\r\n        this._merge = new FrameGraphBloomMergeTask(`${name} Merge`, this._frameGraph, this.bloom._merge);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override isReady() {\r\n        return this.bloom.isReady();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphBloomTask\";\r\n    }\r\n\r\n    public record(): void {\r\n        if (this.sourceTexture === undefined) {\r\n            throw new Error(\"FrameGraphBloomTask: sourceTexture is required\");\r\n        }\r\n\r\n        const sourceTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.sourceTexture);\r\n\r\n        const textureCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: {\r\n                width: Math.floor(sourceTextureDescription.size.width * this.bloom.scale) || 1,\r\n                height: Math.floor(sourceTextureDescription.size.height * this.bloom.scale) || 1,\r\n            },\r\n            options: {\r\n                createMipMaps: false,\r\n                types: [this._defaultPipelineTextureType],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                samples: 1,\r\n                useSRGBBuffers: [false],\r\n                labels: [\"\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n        };\r\n\r\n        const downscaleTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._downscale.name, textureCreationOptions);\r\n\r\n        this._downscale.sourceTexture = this.sourceTexture;\r\n        this._downscale.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n        this._downscale.targetTexture = downscaleTextureHandle;\r\n        this._downscale.record(true);\r\n\r\n        const blurXTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._blurX.name, textureCreationOptions);\r\n\r\n        this._blurX.sourceTexture = downscaleTextureHandle;\r\n        this._blurX.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n        this._blurX.targetTexture = blurXTextureHandle;\r\n        this._blurX.record(true);\r\n\r\n        const blurYTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._blurY.name, textureCreationOptions);\r\n\r\n        this._blurY.sourceTexture = blurXTextureHandle;\r\n        this._blurY.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n        this._blurY.targetTexture = blurYTextureHandle;\r\n        this._blurY.record(true);\r\n\r\n        const sourceTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.sourceTexture);\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture, this._merge.name, sourceTextureCreationOptions);\r\n\r\n        this._merge.sourceTexture = this.sourceTexture;\r\n        this._merge.sourceSamplingMode = this.sourceSamplingMode;\r\n        this._merge.blurTexture = blurYTextureHandle;\r\n        this._merge.targetTexture = this.outputTexture;\r\n        this._merge.record(true);\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.addDependencies(this.sourceTexture);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((context) => {\r\n            if (this.alphaMode === Constants.ALPHA_DISABLE) {\r\n                context.copyTexture(this.sourceTexture);\r\n            }\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this._downscale.dispose();\r\n        this._blurX.dispose();\r\n        this._blurY.dispose();\r\n        this._merge.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphBloomTask } from \"../../../Tasks/PostProcesses/bloomTask\";\r\nimport { NodeRenderGraphBasePostProcessBlock } from \"./basePostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the bloom post process\r\n */\r\nexport class NodeRenderGraphBloomPostProcessBlock extends NodeRenderGraphBasePostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphBloomTask;\r\n\r\n    public override _additionalConstructionParameters: [boolean, number];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphBloomPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param hdr If high dynamic range textures should be used (default: false)\r\n     * @param bloomScale The scale of the bloom effect (default: 0.5)\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, hdr = false, bloomScale = 0.5) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [hdr, bloomScale];\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphBloomTask(this.name, frameGraph, 0.75, 64, 0.2, hdr, bloomScale);\r\n    }\r\n\r\n    private _createTask(bloomScale: number, hdr: boolean) {\r\n        const sourceSamplingMode = this._frameGraphTask.sourceSamplingMode;\r\n        const threshold = this._frameGraphTask.bloom.threshold;\r\n        const weight = this._frameGraphTask.bloom.weight;\r\n        const kernel = this._frameGraphTask.bloom.kernel;\r\n\r\n        this._frameGraphTask.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphBloomTask(this.name, this._frameGraph, weight, kernel, threshold, hdr, bloomScale);\r\n        this._frameGraphTask.sourceSamplingMode = sourceSamplingMode;\r\n\r\n        this._additionalConstructionParameters = [hdr, bloomScale];\r\n    }\r\n\r\n    /** The quality of the blur effect */\r\n    @editableInPropertyPage(\"Bloom scale\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get bloomScale() {\r\n        return this._frameGraphTask.bloom.scale;\r\n    }\r\n\r\n    public set bloomScale(value: number) {\r\n        this._createTask(value, this._frameGraphTask.hdr);\r\n    }\r\n\r\n    /** If high dynamic range textures should be used */\r\n    @editableInPropertyPage(\"HDR\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get hdr(): boolean {\r\n        return this._frameGraphTask.hdr;\r\n    }\r\n\r\n    public set hdr(value: boolean) {\r\n        this._createTask(this._frameGraphTask.bloom.scale, value);\r\n    }\r\n\r\n    /** The luminance threshold to find bright areas of the image to bloom. */\r\n    @editableInPropertyPage(\"Threshold\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get threshold(): number {\r\n        return this._frameGraphTask.bloom.threshold;\r\n    }\r\n\r\n    public set threshold(value: number) {\r\n        this._frameGraphTask.bloom.threshold = value;\r\n    }\r\n\r\n    /** The strength of the bloom. */\r\n    @editableInPropertyPage(\"Weight\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 10 })\r\n    public get weight(): number {\r\n        return this._frameGraphTask.bloom.weight;\r\n    }\r\n\r\n    public set weight(value: number) {\r\n        this._frameGraphTask.bloom.weight = value;\r\n    }\r\n\r\n    /** Specifies the size of the bloom blur kernel, relative to the final output size */\r\n    @editableInPropertyPage(\"Kernel\", PropertyTypeForEdition.Int, \"PROPERTIES\", { min: 1, max: 128 })\r\n    public get kernel(): number {\r\n        return this._frameGraphTask.bloom.kernel;\r\n    }\r\n\r\n    public set kernel(value: number) {\r\n        this._frameGraphTask.bloom.kernel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBloomPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.threshold = ${this.threshold};`);\r\n        codes.push(`${this._codeVariableName}.weight = ${this.weight};`);\r\n        codes.push(`${this._codeVariableName}.kernel = ${this.kernel};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.threshold = this.threshold;\r\n        serializationObject.weight = this.weight;\r\n        serializationObject.kernel = this.kernel;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.threshold = serializationObject.threshold;\r\n        this.weight = serializationObject.weight;\r\n        this.kernel = serializationObject.kernel;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for bloomPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBloomPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphBloomPostProcessBlock\", NodeRenderGraphBloomPostProcessBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphBlurTask } from \"core/FrameGraph/Tasks/PostProcesses/blurTask\";\r\nimport { ThinBlurPostProcess } from \"core/PostProcesses/thinBlurPostProcess\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the blur post process\r\n */\r\nexport class NodeRenderGraphBlurPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphBlurTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphBlurPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphBlurTask(this.name, frameGraph, new ThinBlurPostProcess(name, scene.getEngine(), new Vector2(1, 0), 32));\r\n    }\r\n\r\n    /** The direction in which to blur the image */\r\n    @editableInPropertyPage(\"Direction\", PropertyTypeForEdition.Vector2, \"PROPERTIES\")\r\n    public get direction(): Vector2 {\r\n        return this._frameGraphTask.postProcess.direction;\r\n    }\r\n\r\n    public set direction(value: Vector2) {\r\n        this._frameGraphTask.postProcess.direction = value;\r\n    }\r\n\r\n    /** Length in pixels of the blur sample region */\r\n    @editableInPropertyPage(\"Kernel\", PropertyTypeForEdition.Int, \"PROPERTIES\", { min: 1, max: 256 })\r\n    public get kernel(): number {\r\n        return this._frameGraphTask.postProcess.kernel;\r\n    }\r\n\r\n    public set kernel(value: number) {\r\n        this._frameGraphTask.postProcess.kernel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBlurPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.direction = new BABYLON.Vector2(${this.direction.x}, ${this.direction.y});`);\r\n        codes.push(`${this._codeVariableName}.kernel = ${this.kernel};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.direction = this.direction.asArray();\r\n        serializationObject.kernel = this.kernel;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.direction.fromArray(serializationObject.direction);\r\n        this.kernel = serializationObject.kernel;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for blurPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBlurPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphBlurPostProcessBlock\", NodeRenderGraphBlurPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * The ChromaticAberrationPostProcess separates the rgb channels in an image to produce chromatic distortion around the edges of the screen\r\n */\r\nexport class ThinChromaticAberrationPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"chromaticAberration\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"chromatic_aberration\", \"screen_width\", \"screen_height\", \"direction\", \"radialIntensity\", \"centerPosition\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/chromaticAberration.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/chromaticAberration.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new chromatic aberration post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinChromaticAberrationPostProcess.FragmentUrl,\r\n            uniforms: ThinChromaticAberrationPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The amount of separation of rgb channels (default: 30)\r\n     */\r\n    public aberrationAmount = 30;\r\n\r\n    /**\r\n     * The amount the effect will increase for pixels closer to the edge of the screen. (default: 0)\r\n     */\r\n    public radialIntensity = 0;\r\n\r\n    /**\r\n     * The normalized direction in which the rgb channels should be separated. If set to 0,0 radial direction will be used. (default: Vector2(0.707,0.707))\r\n     */\r\n    public direction = new Vector2(0.707, 0.707);\r\n\r\n    /**\r\n     * The center position where the radialIntensity should be around. [0.5,0.5 is center of screen, 1,1 is top right corner] (default: Vector2(0.5 ,0.5))\r\n     */\r\n    public centerPosition = new Vector2(0.5, 0.5);\r\n\r\n    /** The width of the source texture to which the effect is applied */\r\n    public screenWidth: number;\r\n\r\n    /** The height of the source texture to which the effect is applied */\r\n    public screenHeight: number;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat(\"chromatic_aberration\", this.aberrationAmount);\r\n        effect.setFloat(\"screen_width\", this.screenWidth);\r\n        effect.setFloat(\"screen_height\", this.screenHeight);\r\n        effect.setFloat(\"radialIntensity\", this.radialIntensity);\r\n        effect.setFloat2(\"direction\", this.direction.x, this.direction.y);\r\n        effect.setFloat2(\"centerPosition\", this.centerPosition.x, this.centerPosition.y);\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderContext, type FrameGraphRenderPass } from \"core/index\";\r\nimport { ThinChromaticAberrationPostProcess } from \"core/PostProcesses/thinChromaticAberrationPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a chromatic aberration post process.\r\n */\r\nexport class FrameGraphChromaticAberrationTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinChromaticAberrationPostProcess;\r\n\r\n    /**\r\n     * Constructs a new chromatic aberration task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the chromatic aberration effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinChromaticAberrationPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinChromaticAberrationPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphChromaticAberrationTask\";\r\n    }\r\n\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.screenWidth = this._sourceWidth;\r\n        this.postProcess.screenHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphChromaticAberrationTask } from \"core/FrameGraph/Tasks/PostProcesses/chromaticAberrationTask\";\r\nimport { ThinChromaticAberrationPostProcess } from \"core/PostProcesses/thinChromaticAberrationPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the chromatic aberration post process\r\n */\r\nexport class NodeRenderGraphChromaticAberrationPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphChromaticAberrationTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new chromatic aberration post process block\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphChromaticAberrationTask(this.name, frameGraph, new ThinChromaticAberrationPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** The amount of separation of rgb channels */\r\n    @editableInPropertyPage(\"Amount\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: -1000, max: 1000 })\r\n    public get aberrationAmount(): number {\r\n        return this._frameGraphTask.postProcess.aberrationAmount;\r\n    }\r\n\r\n    public set aberrationAmount(value: number) {\r\n        this._frameGraphTask.postProcess.aberrationAmount = value;\r\n    }\r\n\r\n    /** The amount the effect will increase for pixels closer to the edge of the screen */\r\n    @editableInPropertyPage(\"Radial intensity\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: -1, max: 5 })\r\n    public get radialIntensity(): number {\r\n        return this._frameGraphTask.postProcess.radialIntensity;\r\n    }\r\n\r\n    public set radialIntensity(value: number) {\r\n        this._frameGraphTask.postProcess.radialIntensity = value;\r\n    }\r\n\r\n    /** The normalized direction in which the rgb channels should be separated. If set to 0,0 radial direction will be used. */\r\n    @editableInPropertyPage(\"Direction\", PropertyTypeForEdition.Vector2, \"PROPERTIES\")\r\n    public get direction(): Vector2 {\r\n        return this._frameGraphTask.postProcess.direction;\r\n    }\r\n\r\n    public set direction(value: Vector2) {\r\n        this._frameGraphTask.postProcess.direction = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphChromaticAberrationPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.aberrationAmount = ${this.aberrationAmount};`);\r\n        codes.push(`${this._codeVariableName}.radialIntensity = ${this.radialIntensity};`);\r\n        codes.push(`${this._codeVariableName}.direction = new BABYLON.Vector2(${this.direction.x}, ${this.direction.y});`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.aberrationAmount = this.aberrationAmount;\r\n        serializationObject.radialIntensity = this.radialIntensity;\r\n        serializationObject.direction = this.direction.asArray();\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.aberrationAmount = serializationObject.aberrationAmount;\r\n        this.radialIntensity = serializationObject.radialIntensity;\r\n        this.direction = Vector2.FromArray(serializationObject.direction);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for chromaticAberrationPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterChromaticAberrationPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphChromaticAberrationPostProcessBlock\", NodeRenderGraphChromaticAberrationPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { type Camera } from \"core/Cameras/camera\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Options used to create a ThinCircleOfConfusionPostProcess.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface ThinCircleOfConfusionPostProcessOptions extends EffectWrapperCreationOptions {\r\n    /**\r\n     * If the (view) depth is normalized (0.0 to 1.0 from near to far) or not (0 to camera max distance)\r\n     */\r\n    depthNotNormalized?: boolean;\r\n}\r\n\r\n/**\r\n * Post process used to calculate the circle of confusion (used for depth of field, for example)\r\n */\r\nexport class ThinCircleOfConfusionPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"circleOfConfusion\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"cameraMinMaxZ\", \"focusDistance\", \"cocPrecalculation\"];\r\n\r\n    /**\r\n     * The list of samplers used by the effect\r\n     */\r\n    public static readonly Samplers = [\"depthSampler\"];\r\n\r\n    /**\r\n     * Defines if the depth is normalized or not\r\n     */\r\n    public static readonly DefinesDepthNotNormalized = \"#define COC_DEPTH_NOT_NORMALIZED\";\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/circleOfConfusion.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/circleOfConfusion.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new circle of confusion post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: ThinCircleOfConfusionPostProcessOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinCircleOfConfusionPostProcess.FragmentUrl,\r\n            uniforms: ThinCircleOfConfusionPostProcess.Uniforms,\r\n            samplers: ThinCircleOfConfusionPostProcess.Samplers,\r\n            defines: options?.depthNotNormalized ? ThinCircleOfConfusionPostProcess.DefinesDepthNotNormalized : undefined,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The camera to use to calculate the circle of confusion\r\n     */\r\n    public camera: Camera;\r\n\r\n    /**\r\n     * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diameter of the resulting aperture can be computed by lensSize/fStop.\r\n     */\r\n    public lensSize = 50;\r\n\r\n    /**\r\n     * F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)\r\n     */\r\n    public fStop = 1.4;\r\n\r\n    /**\r\n     * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)\r\n     */\r\n    public focusDistance = 2000;\r\n\r\n    /**\r\n     * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)\r\n     */\r\n    public focalLength = 50;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const options = this.options as ThinCircleOfConfusionPostProcessOptions;\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        if (!options.depthNotNormalized) {\r\n            effect.setFloat2(\"cameraMinMaxZ\", this.camera.minZ, this.camera.maxZ - this.camera.minZ);\r\n        }\r\n\r\n        // Circle of confusion calculation, See https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch23.html\r\n        const aperture = this.lensSize / this.fStop;\r\n        const cocPrecalculation = (aperture * this.focalLength) / (this.focusDistance - this.focalLength); // * ((this.focusDistance - pixelDistance)/pixelDistance) [This part is done in shader]\r\n\r\n        effect.setFloat(\"focusDistance\", this.focusDistance);\r\n        effect.setFloat(\"cocPrecalculation\", cocPrecalculation);\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass, type Camera } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { ThinCircleOfConfusionPostProcess } from \"core/PostProcesses/thinCircleOfConfusionPostProcess\";\r\n\r\n/**\r\n * Task which applies a circle of confusion post process.\r\n */\r\nexport class FrameGraphCircleOfConfusionTask extends FrameGraphPostProcessTask {\r\n    /**\r\n     * The depth texture to use for the circle of confusion effect.\r\n     * It must store camera space depth (Z coordinate)\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the depth texture.\r\n     */\r\n    public depthSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The camera to use for the circle of confusion effect.\r\n     */\r\n    public camera: Camera;\r\n\r\n    public override readonly postProcess: ThinCircleOfConfusionPostProcess;\r\n\r\n    /**\r\n     * Constructs a new circle of confusion task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinCircleOfConfusionPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinCircleOfConfusionPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphCircleOfConfusionTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphCircleOfConfusionTask \"${this.name}\": sourceTexture, depthTexture and camera are required`);\r\n        }\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                this.postProcess.camera = this.camera;\r\n                context.setTextureSamplingMode(this.depthTexture, this.depthSamplingMode);\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n            }\r\n        );\r\n\r\n        pass.addDependencies(this.depthTexture);\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type FrameGraph, type Camera } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphCircleOfConfusionTask } from \"core/FrameGraph/Tasks/PostProcesses/circleOfConfusionTask\";\r\nimport { ThinCircleOfConfusionPostProcess } from \"core/PostProcesses/thinCircleOfConfusionPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the circle of confusion post process\r\n */\r\nexport class NodeRenderGraphCircleOfConfusionPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphCircleOfConfusionTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphCircleOfConfusionPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"geomViewDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphCircleOfConfusionTask(\r\n            this.name,\r\n            frameGraph,\r\n            new ThinCircleOfConfusionPostProcess(name, scene.getEngine(), { depthNotNormalized: true })\r\n        );\r\n    }\r\n\r\n    /** Sampling mode used to sample from the depth texture */\r\n    @editableInPropertyPage(\"Depth sampling mode\", PropertyTypeForEdition.SamplingMode, \"PROPERTIES\")\r\n    public get depthSamplingMode() {\r\n        return this._frameGraphTask.depthSamplingMode;\r\n    }\r\n\r\n    public set depthSamplingMode(value: number) {\r\n        this._frameGraphTask.depthSamplingMode = value;\r\n    }\r\n\r\n    /** Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. The diameter of the resulting aperture can be computed by lensSize/fStop. */\r\n    @editableInPropertyPage(\"Lens size\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get lensSize(): number {\r\n        return this._frameGraphTask.postProcess.lensSize;\r\n    }\r\n\r\n    public set lensSize(value: number) {\r\n        this._frameGraphTask.postProcess.lensSize = value;\r\n    }\r\n\r\n    /** F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop */\r\n    @editableInPropertyPage(\"F-Stop\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get fStop(): number {\r\n        return this._frameGraphTask.postProcess.fStop;\r\n    }\r\n\r\n    public set fStop(value: number) {\r\n        this._frameGraphTask.postProcess.fStop = value;\r\n    }\r\n\r\n    /** Distance away from the camera to focus on in scene units/1000 (eg. millimeter) */\r\n    @editableInPropertyPage(\"Focus distance\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get focusDistance(): number {\r\n        return this._frameGraphTask.postProcess.focusDistance;\r\n    }\r\n\r\n    public set focusDistance(value: number) {\r\n        this._frameGraphTask.postProcess.focusDistance = value;\r\n    }\r\n\r\n    /** Focal length of the effect's camera in scene units/1000 (eg. millimeter) */\r\n    @editableInPropertyPage(\"Focal length\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get focalLength(): number {\r\n        return this._frameGraphTask.postProcess.focalLength;\r\n    }\r\n\r\n    public set focalLength(value: number) {\r\n        this._frameGraphTask.postProcess.focalLength = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphCircleOfConfusionPostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry view depth input component\r\n     */\r\n    public get geomViewDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.depthTexture = this.geomViewDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.lensSize = ${this.lensSize};`);\r\n        codes.push(`${this._codeVariableName}.fStop = ${this.fStop};`);\r\n        codes.push(`${this._codeVariableName}.focusDistance = ${this.focusDistance};`);\r\n        codes.push(`${this._codeVariableName}.focalLength = ${this.focalLength};`);\r\n        codes.push(`${this._codeVariableName}.depthSamplingMode = ${this.depthSamplingMode};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.lensSize = this.lensSize;\r\n        serializationObject.fStop = this.fStop;\r\n        serializationObject.focusDistance = this.focusDistance;\r\n        serializationObject.focalLength = this.focalLength;\r\n        serializationObject.depthSamplingMode = this.depthSamplingMode;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.lensSize = serializationObject.lensSize;\r\n        this.fStop = serializationObject.fStop;\r\n        this.focusDistance = serializationObject.focusDistance;\r\n        this.focalLength = serializationObject.focalLength;\r\n        this.depthSamplingMode = serializationObject.depthSamplingMode;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for circleOfConfusionPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCircleOfConfusionPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphCircleOfConfusionPostProcessBlock\", NodeRenderGraphCircleOfConfusionPostProcessBlock);\r\n}\r\n","import { type EffectWrapperCreationOptions, type Nullable, type Scene } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\n\r\n/**\r\n * Post process used to apply color correction\r\n */\r\nexport class ThinColorCorrectionPostProcess extends EffectWrapper {\r\n    private _colorTableTexture: Texture;\r\n\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"colorCorrection\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Samplers = [\"colorTable\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/colorCorrection.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/colorCorrection.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new black and white post process\r\n     * @param name Name of the effect\r\n     * @param scene The scene the effect belongs to\r\n     * @param colorTableUrl URL of the color table texture\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, scene: Nullable<Scene>, colorTableUrl: string, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: scene?.getEngine(),\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinColorCorrectionPostProcess.FragmentUrl,\r\n            samplers: ThinColorCorrectionPostProcess.Samplers,\r\n        });\r\n\r\n        this._colorTableTexture = new Texture(colorTableUrl, scene, true, false, Texture.TRILINEAR_SAMPLINGMODE);\r\n        this._colorTableTexture.anisotropicFilteringLevel = 1;\r\n        this._colorTableTexture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._colorTableTexture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n\r\n        this.colorTableUrl = colorTableUrl;\r\n    }\r\n\r\n    /**\r\n     * Gets the color table url used to create the LUT texture\r\n     */\r\n    public readonly colorTableUrl: string;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setTexture(\"colorTable\", this._colorTableTexture);\r\n    }\r\n}\r\n","import { type FrameGraph } from \"core/FrameGraph/frameGraph\";\r\nimport { ThinColorCorrectionPostProcess } from \"core/PostProcesses/thinColorCorrectionPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a color correction post process.\r\n */\r\nexport class FrameGraphColorCorrectionTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinColorCorrectionPostProcess;\r\n\r\n    /**\r\n     * Constructs a new color correction task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param colorTableUrl The URL of the color table to use for the color correction effect.\r\n     * @param thinPostProcess The thin post process to use for the color correction effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, colorTableUrl: string, thinPostProcess?: ThinColorCorrectionPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinColorCorrectionPostProcess(name, frameGraph.scene, colorTableUrl));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphColorCorrectionTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphColorCorrectionTask } from \"../../../Tasks/PostProcesses/colorCorrectionTask\";\r\nimport { ThinColorCorrectionPostProcess } from \"../../../../PostProcesses/thinColorCorrectionPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the color correction post process\r\n */\r\nexport class NodeRenderGraphColorCorrectionPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphColorCorrectionTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphColorCorrectionPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param colorTableUrl defines the URL of the color table\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, colorTableUrl: string = \"\") {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [colorTableUrl];\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphColorCorrectionTask(this.name, frameGraph, colorTableUrl, new ThinColorCorrectionPostProcess(name, frameGraph.scene, colorTableUrl));\r\n    }\r\n\r\n    private _createTask(colorTableUrl: string) {\r\n        const sourceSamplingMode = this._frameGraphTask.sourceSamplingMode;\r\n\r\n        this._frameGraphTask.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphColorCorrectionTask(\r\n            this.name,\r\n            this._frameGraph,\r\n            colorTableUrl,\r\n            new ThinColorCorrectionPostProcess(this.name, this._frameGraph.scene, colorTableUrl)\r\n        );\r\n        this._frameGraphTask.sourceSamplingMode = sourceSamplingMode;\r\n\r\n        this._additionalConstructionParameters = [colorTableUrl];\r\n    }\r\n\r\n    /** The color table URL */\r\n    @editableInPropertyPage(\"Color Table URL\", PropertyTypeForEdition.String, \"PROPERTIES\")\r\n    public get colorTableUrl(): string {\r\n        return this._frameGraphTask.postProcess.colorTableUrl;\r\n    }\r\n\r\n    public set colorTableUrl(value: string) {\r\n        this._createTask(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphColorCorrectionPostProcessBlock\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for colorCorrectionPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterColorCorrectionPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphColorCorrectionPostProcessBlock\", NodeRenderGraphColorCorrectionPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to apply a convolution effect\r\n */\r\nexport class ThinConvolutionPostProcess extends EffectWrapper {\r\n    // Statics\r\n    /**\r\n     * Edge detection 0 see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EdgeDetect0Kernel = [1, 0, -1, 0, 0, 0, -1, 0, 1];\r\n    /**\r\n     * Edge detection 1 see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EdgeDetect1Kernel = [0, 1, 0, 1, -4, 1, 0, 1, 0];\r\n    /**\r\n     * Edge detection 2 see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EdgeDetect2Kernel = [-1, -1, -1, -1, 8, -1, -1, -1, -1];\r\n    /**\r\n     * Kernel to sharpen an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static SharpenKernel = [0, -1, 0, -1, 5, -1, 0, -1, 0];\r\n    /**\r\n     * Kernel to emboss an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EmbossKernel = [-2, -1, 0, -1, 1, 1, 0, 1, 2];\r\n    /**\r\n     * Kernel to blur an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static GaussianKernel = [0, 1, 0, 1, 1, 1, 0, 1, 0];\r\n\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"convolution\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"kernel\", \"screenSize\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/convolution.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/convolution.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new convolution post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param kernel Array of 9 values corresponding to the 3x3 kernel to be applied\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, kernel: number[], options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinConvolutionPostProcess.FragmentUrl,\r\n            uniforms: ThinConvolutionPostProcess.Uniforms,\r\n        });\r\n\r\n        this.kernel = kernel;\r\n    }\r\n\r\n    /** Array of 9 values corresponding to the 3x3 kernel to be applied */\r\n    public kernel: number[];\r\n\r\n    /**\r\n     * The width of the source texture\r\n     */\r\n    public textureWidth: number = 0;\r\n\r\n    /**\r\n     * The height of the source texture\r\n     */\r\n    public textureHeight: number = 0;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat2(\"screenSize\", this.textureWidth, this.textureHeight);\r\n        effect.setArray(\"kernel\", this.kernel);\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderContext, type FrameGraphRenderPass } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinConvolutionPostProcess } from \"core/PostProcesses/thinConvolutionPostProcess\";\r\n\r\n/**\r\n * Task which applies a convolution post process.\r\n */\r\nexport class FrameGraphConvolutionTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinConvolutionPostProcess;\r\n\r\n    /**\r\n     * Constructs a new convolution task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinConvolutionPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinConvolutionPostProcess(name, frameGraph.engine, ThinConvolutionPostProcess.EmbossKernel));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphConvolutionTask\";\r\n    }\r\n\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphConvolutionTask } from \"../../../Tasks/PostProcesses/convolutionTask\";\r\nimport { ThinConvolutionPostProcess } from \"../../../../PostProcesses/thinConvolutionPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the convolution post process\r\n */\r\nexport class NodeRenderGraphConvolutionPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphConvolutionTask;\r\n\r\n    public override _additionalConstructionParameters: [number[]];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphConvolutionPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param kernel Array of 9 values corresponding to the 3x3 kernel to be applied\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, kernel: number[] = ThinConvolutionPostProcess.EmbossKernel) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [kernel];\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphConvolutionTask(this.name, frameGraph, new ThinConvolutionPostProcess(name, frameGraph.engine, kernel));\r\n    }\r\n\r\n    private _createTask(kernelIndex: number) {\r\n        const sourceSamplingMode = this._frameGraphTask.sourceSamplingMode;\r\n\r\n        this._frameGraphTask.dispose();\r\n\r\n        let kernel = ThinConvolutionPostProcess.EmbossKernel;\r\n        switch (kernelIndex) {\r\n            case 0:\r\n                kernel = ThinConvolutionPostProcess.EdgeDetect0Kernel;\r\n                break;\r\n            case 1:\r\n                kernel = ThinConvolutionPostProcess.EdgeDetect1Kernel;\r\n                break;\r\n            case 2:\r\n                kernel = ThinConvolutionPostProcess.EdgeDetect2Kernel;\r\n                break;\r\n            case 3:\r\n                kernel = ThinConvolutionPostProcess.SharpenKernel;\r\n                break;\r\n            case 4:\r\n                kernel = ThinConvolutionPostProcess.EmbossKernel;\r\n                break;\r\n            case 5:\r\n                kernel = ThinConvolutionPostProcess.GaussianKernel;\r\n                break;\r\n        }\r\n\r\n        this._frameGraphTask = new FrameGraphConvolutionTask(this.name, this._frameGraph, new ThinConvolutionPostProcess(this.name, this._frameGraph.engine, kernel));\r\n        this._frameGraphTask.sourceSamplingMode = sourceSamplingMode;\r\n\r\n        this._additionalConstructionParameters = [kernel];\r\n    }\r\n\r\n    /** The quality of the blur effect */\r\n    @editableInPropertyPage(\"Kernel\", PropertyTypeForEdition.List, \"PROPERTIES\", {\r\n        options: [\r\n            { label: \"EdgeDetect0\", value: 0 },\r\n            { label: \"EdgeDetect1\", value: 1 },\r\n            { label: \"EdgeDetect2\", value: 2 },\r\n            { label: \"Sharpen\", value: 3 },\r\n            { label: \"Emboss\", value: 4 },\r\n            { label: \"Gaussian\", value: 5 },\r\n        ],\r\n    })\r\n    public get kernel(): number {\r\n        const kernel = this._frameGraphTask.postProcess.kernel;\r\n\r\n        if (kernel.every((value, index) => value === ThinConvolutionPostProcess.EdgeDetect0Kernel[index])) {\r\n            return 0;\r\n        }\r\n        if (kernel.every((value, index) => value === ThinConvolutionPostProcess.EdgeDetect1Kernel[index])) {\r\n            return 1;\r\n        }\r\n        if (kernel.every((value, index) => value === ThinConvolutionPostProcess.EdgeDetect2Kernel[index])) {\r\n            return 2;\r\n        }\r\n        if (kernel.every((value, index) => value === ThinConvolutionPostProcess.SharpenKernel[index])) {\r\n            return 3;\r\n        }\r\n        if (kernel.every((value, index) => value === ThinConvolutionPostProcess.EmbossKernel[index])) {\r\n            return 4;\r\n        }\r\n        if (kernel.every((value, index) => value === ThinConvolutionPostProcess.GaussianKernel[index])) {\r\n            return 5;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    public set kernel(value: number) {\r\n        this._createTask(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphConvolutionPostProcessBlock\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for convolutionPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterConvolutionPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphConvolutionPostProcessBlock\", NodeRenderGraphConvolutionPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions, type Vector2 } from \"core/index\";\r\nimport { ThinBlurPostProcess } from \"./thinBlurPostProcess\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinDepthOfFieldBlurPostProcess extends ThinBlurPostProcess {\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, direction: Vector2, kernel: number, options?: EffectWrapperCreationOptions) {\r\n        super(name, engine, direction, kernel, {\r\n            ...options,\r\n            defines: `#define DOF 1\\n`,\r\n        });\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinDepthOfFieldMergePostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"depthOfFieldMerge\";\r\n\r\n    public static readonly Samplers = [\"circleOfConfusionSampler\", \"blurStep0\", \"blurStep1\", \"blurStep2\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/depthOfFieldMerge.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/depthOfFieldMerge.fragment\"));\r\n        }\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinDepthOfFieldMergePostProcess.FragmentUrl,\r\n            samplers: ThinDepthOfFieldMergePostProcess.Samplers,\r\n        });\r\n    }\r\n}\r\n","import { type Nullable } from \"core/types\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { ThinDepthOfFieldBlurPostProcess } from \"./thinDepthOfFieldBlurPostProcess\";\r\nimport { ThinCircleOfConfusionPostProcess } from \"./thinCircleOfConfusionPostProcess\";\r\nimport { ThinDepthOfFieldMergePostProcess } from \"./thinDepthOfFieldMergePostProcess\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * Specifies the level of blur that should be applied when using the depth of field effect\r\n */\r\nexport const enum ThinDepthOfFieldEffectBlurLevel {\r\n    /**\r\n     * Subtle blur\r\n     */\r\n    Low,\r\n    /**\r\n     * Medium blur\r\n     */\r\n    Medium,\r\n    /**\r\n     * Large blur\r\n     */\r\n    High,\r\n}\r\n\r\n/**\r\n * Thin depth of field effect composed of circle of confusion, blur, and merge post processes.\r\n */\r\nexport class ThinDepthOfFieldEffect {\r\n    /** @internal */\r\n    public readonly _circleOfConfusion: ThinCircleOfConfusionPostProcess;\r\n    /** @internal */\r\n    public readonly _depthOfFieldBlurX: Array<[ThinDepthOfFieldBlurPostProcess, number]> = [];\r\n    /** @internal */\r\n    public readonly _depthOfFieldBlurY: Array<[ThinDepthOfFieldBlurPostProcess, number]> = [];\r\n    /** @internal */\r\n    public readonly _dofMerge: ThinDepthOfFieldMergePostProcess;\r\n\r\n    /**\r\n     * The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter)\r\n     */\r\n    public set focalLength(value: number) {\r\n        this._circleOfConfusion.focalLength = value;\r\n    }\r\n    public get focalLength() {\r\n        return this._circleOfConfusion.focalLength;\r\n    }\r\n    /**\r\n     * F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)\r\n     */\r\n    public set fStop(value: number) {\r\n        this._circleOfConfusion.fStop = value;\r\n    }\r\n    public get fStop() {\r\n        return this._circleOfConfusion.fStop;\r\n    }\r\n    /**\r\n     * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)\r\n     */\r\n    public set focusDistance(value: number) {\r\n        this._circleOfConfusion.focusDistance = value;\r\n    }\r\n    public get focusDistance() {\r\n        return this._circleOfConfusion.focusDistance;\r\n    }\r\n    /**\r\n     * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diameter of the resulting aperture can be computed by lensSize/fStop.\r\n     */\r\n    public set lensSize(value: number) {\r\n        this._circleOfConfusion.lensSize = value;\r\n    }\r\n    public get lensSize() {\r\n        return this._circleOfConfusion.lensSize;\r\n    }\r\n\r\n    /**\r\n     * The quality of the effect.\r\n     */\r\n    public readonly blurLevel: ThinDepthOfFieldEffectBlurLevel;\r\n\r\n    /**\r\n     * Creates a new instance of @see ThinDepthOfFieldEffect\r\n     * @param name The name of the depth of field render effect\r\n     * @param engine The engine which the render effect will be applied. (default: current engine)\r\n     * @param blurLevel The quality of the effect. (default: DepthOfFieldEffectBlurLevel.Low)\r\n     * @param depthNotNormalized If the (view) depth used in circle of confusion post-process is normalized (0.0 to 1.0 from near to far) or not (0 to camera max distance) (default: false)\r\n     * @param blockCompilation If shaders should not be compiled when the effect is created (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        engine: Nullable<AbstractEngine>,\r\n        blurLevel: ThinDepthOfFieldEffectBlurLevel = ThinDepthOfFieldEffectBlurLevel.Low,\r\n        depthNotNormalized = false,\r\n        blockCompilation = false\r\n    ) {\r\n        this._circleOfConfusion = new ThinCircleOfConfusionPostProcess(name, engine, { depthNotNormalized, blockCompilation });\r\n        this.blurLevel = blurLevel;\r\n\r\n        let blurCount: number;\r\n        let kernelSize: number;\r\n        switch (blurLevel) {\r\n            case ThinDepthOfFieldEffectBlurLevel.High: {\r\n                blurCount = 3;\r\n                kernelSize = 51;\r\n                break;\r\n            }\r\n            case ThinDepthOfFieldEffectBlurLevel.Medium: {\r\n                blurCount = 2;\r\n                kernelSize = 31;\r\n                break;\r\n            }\r\n            default: {\r\n                kernelSize = 15;\r\n                blurCount = 1;\r\n                break;\r\n            }\r\n        }\r\n\r\n        const adjustedKernelSize = kernelSize / Math.pow(2, blurCount - 1);\r\n        let ratio = 1.0;\r\n        for (let i = 0; i < blurCount; i++) {\r\n            this._depthOfFieldBlurY.push([new ThinDepthOfFieldBlurPostProcess(name, engine, new Vector2(0, 1), adjustedKernelSize, { blockCompilation }), ratio]);\r\n            ratio = 0.75 / Math.pow(2, i);\r\n            this._depthOfFieldBlurX.push([new ThinDepthOfFieldBlurPostProcess(name, engine, new Vector2(1, 0), adjustedKernelSize, { blockCompilation }), ratio]);\r\n        }\r\n\r\n        this._dofMerge = new ThinDepthOfFieldMergePostProcess(name, engine, { blockCompilation });\r\n    }\r\n\r\n    /**\r\n     * Checks if the effect is ready to be used\r\n     * @returns if the effect is ready\r\n     */\r\n    public isReady() {\r\n        let isReady = this._circleOfConfusion.isReady() && this._dofMerge.isReady();\r\n        for (let i = 0; i < this._depthOfFieldBlurX.length; i++) {\r\n            isReady = isReady && this._depthOfFieldBlurX[i][0].isReady() && this._depthOfFieldBlurY[i][0].isReady();\r\n        }\r\n        return isReady;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass } from \"core/index\";\r\nimport { ThinDepthOfFieldMergePostProcess } from \"core/PostProcesses/thinDepthOfFieldMergePostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphDepthOfFieldMergeTask extends FrameGraphPostProcessTask {\r\n    public circleOfConfusionTexture: FrameGraphTextureHandle;\r\n\r\n    public blurSteps: FrameGraphTextureHandle[] = [];\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinDepthOfFieldMergePostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinDepthOfFieldMergePostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphDepthOfFieldMergeTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.circleOfConfusionTexture === undefined || this.blurSteps.length === 0) {\r\n            throw new Error(`FrameGraphBloomMergeTask \"${this.name}\": sourceTexture, circleOfConfusionTexture and blurSteps are required`);\r\n        }\r\n\r\n        this.postProcess.updateEffect(\"#define BLUR_LEVEL \" + (this.blurSteps.length - 1) + \"\\n\");\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                context.setTextureSamplingMode(this.blurSteps[this.blurSteps.length - 1], Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"circleOfConfusionSampler\", this.circleOfConfusionTexture);\r\n                for (let i = 0; i < this.blurSteps.length; i++) {\r\n                    const handle = this.blurSteps[i];\r\n                    context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"blurStep\" + (this.blurSteps.length - i - 1), handle);\r\n                }\r\n            }\r\n        );\r\n\r\n        pass.addDependencies(this.circleOfConfusionTexture);\r\n        pass.addDependencies(this.blurSteps);\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphBlurTask } from \"./blurTask\";\r\nimport { ThinDepthOfFieldBlurPostProcess } from \"core/PostProcesses/thinDepthOfFieldBlurPostProcess\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphDepthOfFieldBlurTask extends FrameGraphBlurTask {\r\n    public circleOfConfusionTexture: FrameGraphTextureHandle;\r\n\r\n    public circleOfConfusionSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinDepthOfFieldBlurPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinDepthOfFieldBlurPostProcess(name, frameGraph.engine, new Vector2(1, 0), 10));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphDepthOfFieldBlurTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.circleOfConfusionTexture === undefined) {\r\n            throw new Error(`FrameGraphDepthOfFieldBlurTask \"${this.name}\": sourceTexture and circleOfConfusionTexture are required`);\r\n        }\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                context.setTextureSamplingMode(this.circleOfConfusionTexture, this.circleOfConfusionSamplingMode);\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"circleOfConfusionSampler\", this.circleOfConfusionTexture);\r\n            }\r\n        );\r\n\r\n        pass.addDependencies(this.circleOfConfusionTexture);\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle, type AbstractEngine, type Camera } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { ThinDepthOfFieldEffectBlurLevel, ThinDepthOfFieldEffect } from \"core/PostProcesses/thinDepthOfFieldEffect\";\r\nimport { FrameGraphDepthOfFieldMergeTask } from \"./depthOfFieldMergeTask\";\r\nimport { FrameGraphCircleOfConfusionTask } from \"./circleOfConfusionTask\";\r\nimport { FrameGraphDepthOfFieldBlurTask } from \"./depthOfFieldBlurTask\";\r\n\r\n/**\r\n * Task which applies a depth of field effect.\r\n */\r\nexport class FrameGraphDepthOfFieldTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to apply the depth of field effect on.\r\n     */\r\n    public sourceTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the source texture.\r\n     */\r\n    public sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The alpha mode to use when applying the depth of field effect.\r\n     */\r\n    public get alphaMode() {\r\n        return this._merge.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(mode: number) {\r\n        this._merge.alphaMode = mode;\r\n    }\r\n\r\n    /**\r\n     * The depth texture to use for the depth of field effect.\r\n     * Should store camera space depth (Z coordinate).\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the depth texture.\r\n     */\r\n    public depthSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The camera used to render the scene.\r\n     */\r\n    public camera: Camera;\r\n\r\n    /**\r\n     * The target texture to render the depth of field effect to.\r\n     */\r\n    public targetTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture of the depth of field effect.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The depth of field effect.\r\n     */\r\n    public readonly depthOfField: ThinDepthOfFieldEffect;\r\n\r\n    /**\r\n     * Whether the depth of field effect is applied on HDR textures.\r\n     * When true, the depth of field effect will use a higher precision texture format (half float or float). Else, it will use unsigned byte.\r\n     */\r\n    public readonly hdr: boolean;\r\n\r\n    /**\r\n     * The name of the task.\r\n     */\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this._circleOfConfusion) {\r\n            this._circleOfConfusion.name = `${name} Circle of Confusion`;\r\n        }\r\n\r\n        if (this._blurX) {\r\n            for (let i = 0; i < this._blurX.length; i++) {\r\n                this._blurX[i].name = `${name} Blur X${i}`;\r\n                this._blurY[i].name = `${name} Blur Y${i}`;\r\n            }\r\n        }\r\n\r\n        if (this._merge) {\r\n            this._merge.name = `${name} Merge`;\r\n        }\r\n    }\r\n\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _circleOfConfusion: FrameGraphCircleOfConfusionTask;\r\n    private readonly _blurX: FrameGraphDepthOfFieldBlurTask[] = [];\r\n    private readonly _blurY: FrameGraphDepthOfFieldBlurTask[] = [];\r\n    private readonly _merge: FrameGraphDepthOfFieldMergeTask;\r\n    private readonly _defaultPipelineTextureType: number;\r\n\r\n    /**\r\n     * Constructs a depth of field task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param blurLevel The blur level of the depth of field effect (default: ThinDepthOfFieldEffectBlurLevel.Low).\r\n     * @param hdr Whether the depth of field effect is HDR.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, blurLevel: ThinDepthOfFieldEffectBlurLevel = ThinDepthOfFieldEffectBlurLevel.Low, hdr = false) {\r\n        super(name, frameGraph);\r\n\r\n        this._engine = frameGraph.engine;\r\n        this.hdr = hdr;\r\n\r\n        this._defaultPipelineTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (hdr) {\r\n            const caps = frameGraph.engine.getCaps();\r\n            if (caps.textureHalfFloatRender) {\r\n                this._defaultPipelineTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else if (caps.textureFloatRender) {\r\n                this._defaultPipelineTextureType = Constants.TEXTURETYPE_FLOAT;\r\n            }\r\n        }\r\n\r\n        this.depthOfField = new ThinDepthOfFieldEffect(name, frameGraph.engine, blurLevel, true);\r\n\r\n        this._circleOfConfusion = new FrameGraphCircleOfConfusionTask(`${name} Circle of Confusion`, this._frameGraph, this.depthOfField._circleOfConfusion);\r\n\r\n        const blurCount = this.depthOfField._depthOfFieldBlurX.length;\r\n\r\n        for (let i = 0; i < blurCount; i++) {\r\n            this._blurX.push(new FrameGraphDepthOfFieldBlurTask(`${name} Blur X${i}`, this._frameGraph, this.depthOfField._depthOfFieldBlurX[i][0]));\r\n            this._blurY.push(new FrameGraphDepthOfFieldBlurTask(`${name} Blur Y${i}`, this._frameGraph, this.depthOfField._depthOfFieldBlurY[i][0]));\r\n        }\r\n\r\n        this._merge = new FrameGraphDepthOfFieldMergeTask(`${name} Merge`, this._frameGraph, this.depthOfField._dofMerge);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override isReady() {\r\n        return this.depthOfField.isReady();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphDepthOfFieldTask\";\r\n    }\r\n\r\n    public record(): void {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined || this.camera === undefined) {\r\n            throw new Error(\"FrameGraphDepthOfFieldTask: sourceTexture, depthTexture and camera are required\");\r\n        }\r\n\r\n        const sourceTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.sourceTexture);\r\n\r\n        const textureSize = {\r\n            width: sourceTextureDescription.size.width,\r\n            height: sourceTextureDescription.size.height,\r\n        };\r\n        const circleOfConfusionTextureFormat = this._engine.isWebGPU || this._engine.version > 1 ? Constants.TEXTUREFORMAT_RED : Constants.TEXTUREFORMAT_RGBA;\r\n        const textureCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: textureSize,\r\n            options: {\r\n                createMipMaps: false,\r\n                types: [this._defaultPipelineTextureType],\r\n                formats: [circleOfConfusionTextureFormat],\r\n                samples: 1,\r\n                useSRGBBuffers: [false],\r\n                labels: [\"\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n        };\r\n\r\n        const circleOfConfusionTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._circleOfConfusion.name, textureCreationOptions);\r\n\r\n        this._circleOfConfusion.sourceTexture = this.sourceTexture; // texture not used by the CoC shader\r\n        this._circleOfConfusion.depthTexture = this.depthTexture;\r\n        this._circleOfConfusion.depthSamplingMode = this.depthSamplingMode;\r\n        this._circleOfConfusion.camera = this.camera;\r\n        this._circleOfConfusion.targetTexture = circleOfConfusionTextureHandle;\r\n        this._circleOfConfusion.record(true);\r\n\r\n        textureCreationOptions.options.formats = [Constants.TEXTUREFORMAT_RGBA];\r\n\r\n        const blurSteps: FrameGraphTextureHandle[] = [];\r\n\r\n        for (let i = 0; i < this._blurX.length; i++) {\r\n            const ratio = this.depthOfField._depthOfFieldBlurX[i][1];\r\n\r\n            textureSize.width = Math.floor(sourceTextureDescription.size.width * ratio) || 1;\r\n            textureSize.height = Math.floor(sourceTextureDescription.size.height * ratio) || 1;\r\n\r\n            textureCreationOptions.options.labels![0] = \"step \" + (i + 1);\r\n\r\n            const blurYTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._blurY[i].name, textureCreationOptions);\r\n\r\n            this._blurY[i].sourceTexture = i === 0 ? this.sourceTexture : this._blurX[i - 1].outputTexture;\r\n            this._blurY[i].sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n            this._blurY[i].circleOfConfusionTexture = circleOfConfusionTextureHandle;\r\n            this._blurY[i].targetTexture = blurYTextureHandle;\r\n            this._blurY[i].record(true);\r\n\r\n            const blurXTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._blurX[i].name, textureCreationOptions);\r\n\r\n            this._blurX[i].sourceTexture = this._blurY[i].outputTexture;\r\n            this._blurX[i].sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n            this._blurX[i].circleOfConfusionTexture = circleOfConfusionTextureHandle;\r\n            this._blurX[i].targetTexture = blurXTextureHandle;\r\n            this._blurX[i].record(true);\r\n\r\n            blurSteps.push(blurXTextureHandle);\r\n        }\r\n\r\n        const sourceTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.sourceTexture);\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture, this._merge.name, sourceTextureCreationOptions);\r\n\r\n        this._merge.sourceTexture = this.sourceTexture;\r\n        this._merge.sourceSamplingMode = this.sourceSamplingMode;\r\n        this._merge.circleOfConfusionTexture = circleOfConfusionTextureHandle;\r\n        this._merge.blurSteps = blurSteps;\r\n        this._merge.targetTexture = this.outputTexture;\r\n        this._merge.record(true);\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.addDependencies(this.sourceTexture);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((context) => {\r\n            if (this.alphaMode === Constants.ALPHA_DISABLE) {\r\n                context.copyTexture(this.sourceTexture);\r\n            }\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this._circleOfConfusion.dispose();\r\n        for (let i = 0; i < this._blurX.length; i++) {\r\n            this._blurX[i].dispose();\r\n            this._blurY[i].dispose();\r\n        }\r\n        this._merge.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type FrameGraph, type Camera } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphDepthOfFieldTask } from \"../../../Tasks/PostProcesses/depthOfFieldTask\";\r\nimport { ThinDepthOfFieldEffectBlurLevel } from \"core/PostProcesses/thinDepthOfFieldEffect\";\r\nimport { NodeRenderGraphBasePostProcessBlock } from \"./basePostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the depth of field post process\r\n */\r\nexport class NodeRenderGraphDepthOfFieldPostProcessBlock extends NodeRenderGraphBasePostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphDepthOfFieldTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphDepthOfFieldPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param blurLevel The quality of the depth of field effect (default: ThinDepthOfFieldEffectBlurLevel.Low)\r\n     * @param hdr If high dynamic range textures should be used (default: false)\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, blurLevel: ThinDepthOfFieldEffectBlurLevel = ThinDepthOfFieldEffectBlurLevel.Low, hdr = false) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [blurLevel, hdr];\r\n\r\n        this.registerInput(\"geomViewDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphDepthOfFieldTask(this.name, frameGraph, blurLevel, hdr);\r\n    }\r\n\r\n    private _createTask(blurLevel: ThinDepthOfFieldEffectBlurLevel, hdr: boolean) {\r\n        const sourceSamplingMode = this._frameGraphTask.sourceSamplingMode;\r\n        const depthSamplingMode = this._frameGraphTask.depthSamplingMode;\r\n        const focalLength = this._frameGraphTask.depthOfField.focalLength;\r\n        const fStop = this._frameGraphTask.depthOfField.fStop;\r\n        const focusDistance = this._frameGraphTask.depthOfField.focusDistance;\r\n        const lensSize = this._frameGraphTask.depthOfField.lensSize;\r\n\r\n        this._frameGraphTask.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphDepthOfFieldTask(this.name, this._frameGraph, blurLevel, hdr);\r\n        this._frameGraphTask.sourceSamplingMode = sourceSamplingMode;\r\n        this._frameGraphTask.depthSamplingMode = depthSamplingMode;\r\n        this._frameGraphTask.depthOfField.focalLength = focalLength;\r\n        this._frameGraphTask.depthOfField.fStop = fStop;\r\n        this._frameGraphTask.depthOfField.focusDistance = focusDistance;\r\n        this._frameGraphTask.depthOfField.lensSize = lensSize;\r\n\r\n        this._additionalConstructionParameters = [blurLevel, hdr];\r\n    }\r\n\r\n    /** The quality of the blur effect */\r\n    @editableInPropertyPage(\"Blur level\", PropertyTypeForEdition.List, \"PROPERTIES\", {\r\n        options: [\r\n            { label: \"Low\", value: ThinDepthOfFieldEffectBlurLevel.Low },\r\n            { label: \"Medium\", value: ThinDepthOfFieldEffectBlurLevel.Medium },\r\n            { label: \"High\", value: ThinDepthOfFieldEffectBlurLevel.High },\r\n        ],\r\n    })\r\n    public get blurLevel(): ThinDepthOfFieldEffectBlurLevel {\r\n        return this._frameGraphTask.depthOfField.blurLevel;\r\n    }\r\n\r\n    public set blurLevel(value: ThinDepthOfFieldEffectBlurLevel) {\r\n        this._createTask(value, this._frameGraphTask.hdr);\r\n    }\r\n\r\n    /** If high dynamic range textures should be used */\r\n    @editableInPropertyPage(\"HDR\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get hdr(): boolean {\r\n        return this._frameGraphTask.hdr;\r\n    }\r\n\r\n    public set hdr(value: boolean) {\r\n        this._createTask(this._frameGraphTask.depthOfField.blurLevel, value);\r\n    }\r\n\r\n    /** Sampling mode used to sample from the depth texture */\r\n    @editableInPropertyPage(\"Depth sampling mode\", PropertyTypeForEdition.SamplingMode, \"PROPERTIES\")\r\n    public get depthSamplingMode() {\r\n        return this._frameGraphTask.depthSamplingMode;\r\n    }\r\n\r\n    public set depthSamplingMode(value: number) {\r\n        this._frameGraphTask.depthSamplingMode = value;\r\n    }\r\n\r\n    /** The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter). */\r\n    @editableInPropertyPage(\"Focal length\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get focalLength(): number {\r\n        return this._frameGraphTask.depthOfField.focalLength;\r\n    }\r\n\r\n    public set focalLength(value: number) {\r\n        this._frameGraphTask.depthOfField.focalLength = value;\r\n    }\r\n\r\n    /** F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop. */\r\n    @editableInPropertyPage(\"F-Stop\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get fStop(): number {\r\n        return this._frameGraphTask.depthOfField.fStop;\r\n    }\r\n\r\n    public set fStop(value: number) {\r\n        this._frameGraphTask.depthOfField.fStop = value;\r\n    }\r\n\r\n    /** Distance away from the camera to focus on in scene units/1000 (eg. millimeter). */\r\n    @editableInPropertyPage(\"Focus distance\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get focusDistance(): number {\r\n        return this._frameGraphTask.depthOfField.focusDistance;\r\n    }\r\n\r\n    public set focusDistance(value: number) {\r\n        this._frameGraphTask.depthOfField.focusDistance = value;\r\n    }\r\n\r\n    /** Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. The diameter of the resulting aperture can be computed by lensSize/fStop. */\r\n    @editableInPropertyPage(\"Lens size\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get lensSize(): number {\r\n        return this._frameGraphTask.depthOfField.lensSize;\r\n    }\r\n\r\n    public set lensSize(value: number) {\r\n        this._frameGraphTask.depthOfField.lensSize = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphDepthOfFieldPostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry view depth input component\r\n     */\r\n    public get geomViewDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.depthTexture = this.geomViewDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.lensSize = ${this.lensSize};`);\r\n        codes.push(`${this._codeVariableName}.fStop = ${this.fStop};`);\r\n        codes.push(`${this._codeVariableName}.focusDistance = ${this.focusDistance};`);\r\n        codes.push(`${this._codeVariableName}.focalLength = ${this.focalLength};`);\r\n        codes.push(`${this._codeVariableName}.depthSamplingMode = ${this.depthSamplingMode};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.lensSize = this.lensSize;\r\n        serializationObject.fStop = this.fStop;\r\n        serializationObject.focusDistance = this.focusDistance;\r\n        serializationObject.focalLength = this.focalLength;\r\n        serializationObject.depthSamplingMode = this.depthSamplingMode;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.lensSize = serializationObject.lensSize;\r\n        this.fStop = serializationObject.fStop;\r\n        this.focusDistance = serializationObject.focusDistance;\r\n        this.focalLength = serializationObject.focalLength;\r\n        this.depthSamplingMode = serializationObject.depthSamplingMode;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for depthOfFieldPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDepthOfFieldPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphDepthOfFieldPostProcessBlock\", NodeRenderGraphDepthOfFieldPostProcessBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphExtractHighlightsTask } from \"core/FrameGraph/Tasks/PostProcesses/extractHighlightsTask\";\r\nimport { ThinExtractHighlightsPostProcess } from \"core/PostProcesses/thinExtractHighlightsPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the extract highlights post process\r\n */\r\nexport class NodeRenderGraphExtractHighlightsPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphExtractHighlightsTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new ExtractHighlightsPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphExtractHighlightsTask(this.name, frameGraph, new ThinExtractHighlightsPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** The luminance threshold, pixels below this value will be set to black. */\r\n    @editableInPropertyPage(\"Threshold\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get threshold(): number {\r\n        return this._frameGraphTask.postProcess.threshold;\r\n    }\r\n\r\n    public set threshold(value: number) {\r\n        this._frameGraphTask.postProcess.threshold = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphExtractHighlightsPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.threshold = ${this.threshold};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.threshold = this.threshold;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.threshold = serializationObject.threshold;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for extractHighlightsPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterExtractHighlightsPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphExtractHighlightsPostProcessBlock\", NodeRenderGraphExtractHighlightsPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Post process used to apply a kernel filter\r\n */\r\nexport class ThinFilterPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"filter\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"kernelMatrix\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/filter.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/filter.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new filter post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinFilterPostProcess.FragmentUrl,\r\n            uniforms: ThinFilterPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The matrix to be applied to the image\r\n     */\r\n    public kernelMatrix = Matrix.Identity();\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setMatrix(\"kernelMatrix\", this.kernelMatrix);\r\n    }\r\n}\r\n","import { type FrameGraph } from \"core/FrameGraph/frameGraph\";\r\nimport { ThinFilterPostProcess } from \"core/PostProcesses/thinFilterPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a kernel filter post process.\r\n */\r\nexport class FrameGraphFilterTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinFilterPostProcess;\r\n\r\n    /**\r\n     * Constructs a new filter task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the filter effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinFilterPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinFilterPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphFilterTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphFilterTask } from \"core/FrameGraph/Tasks/PostProcesses/filterTask\";\r\nimport { ThinFilterPostProcess } from \"core/PostProcesses/thinFilterPostProcess\";\r\nimport { Matrix } from \"../../../../Maths/math.vector.pure\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the kernel filter post process\r\n */\r\nexport class NodeRenderGraphFilterPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphFilterTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphFilterPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphFilterTask(this.name, frameGraph, new ThinFilterPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** The matrix to be applied to the image */\r\n    @editableInPropertyPage(\"Matrix\", PropertyTypeForEdition.Matrix, \"PROPERTIES\")\r\n    public get kernelMatrix(): Matrix {\r\n        return this._frameGraphTask.postProcess.kernelMatrix;\r\n    }\r\n\r\n    public set kernelMatrix(value: Matrix) {\r\n        this._frameGraphTask.postProcess.kernelMatrix = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphFilterPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.kernelMatrix = ${this.kernelMatrix};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.kernelMatrix = this.kernelMatrix.asArray();\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.kernelMatrix = Matrix.FromArray(serializationObject.kernelMatrix);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for filterPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFilterPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphFilterPostProcessBlock\", NodeRenderGraphFilterPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Postprocess used to apply FXAA (antialiasing) to the scene\r\n */\r\nexport class ThinFXAAPostProcess extends EffectWrapper {\r\n    private static _GetDefines(engine: AbstractEngine): Nullable<string> {\r\n        if (!engine) {\r\n            return null;\r\n        }\r\n\r\n        const driverInfo = engine.extractDriverInfo();\r\n        if (driverInfo.toLowerCase().indexOf(\"mali\") > -1) {\r\n            return \"#define MALI 1\\n\";\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * The vertex shader url\r\n     */\r\n    public static readonly VertexUrl = \"fxaa\";\r\n\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"fxaa\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"texelSize\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/fxaa.fragment\"), import(\"../ShadersWGSL/fxaa.vertex\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/fxaa.fragment\"), import(\"../Shaders/fxaa.vertex\")]));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new FXAA post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        const localOptions = {\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            vertexShader: ThinFXAAPostProcess.VertexUrl,\r\n            fragmentShader: ThinFXAAPostProcess.FragmentUrl,\r\n            uniforms: ThinFXAAPostProcess.Uniforms,\r\n        };\r\n\r\n        super({\r\n            ...localOptions,\r\n            defines: ThinFXAAPostProcess._GetDefines(localOptions.engine),\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The texel size of the texture to apply FXAA on\r\n     */\r\n    public texelSize = new Vector2(0, 0);\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setFloat2(\"texelSize\", this.texelSize.x, this.texelSize.y);\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderContext, type FrameGraphRenderPass } from \"core/index\";\r\nimport { ThinFXAAPostProcess } from \"core/PostProcesses/thinFXAAPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a FXAA post process.\r\n */\r\nexport class FrameGraphFXAATask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinFXAAPostProcess;\r\n\r\n    /**\r\n     * Constructs a new FXAA task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the FXAA effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinFXAAPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinFXAAPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphFXAATask\";\r\n    }\r\n\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.texelSize.x = 1 / this._sourceWidth;\r\n        this.postProcess.texelSize.y = 1 / this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { FrameGraphFXAATask } from \"core/FrameGraph/Tasks/PostProcesses/fxaaTask\";\r\nimport { ThinFXAAPostProcess } from \"core/PostProcesses/thinFXAAPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the FXAA post process\r\n */\r\nexport class NodeRenderGraphFXAAPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphFXAATask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new FXAA post-process block\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphFXAATask(this.name, frameGraph, new ThinFXAAPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphFXAAPostProcessBlock\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fxaaPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFxaaPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphFXAAPostProcessBlock\", NodeRenderGraphFXAAPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to render a grain effect\r\n */\r\nexport class ThinGrainPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"grain\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"intensity\", \"animatedSeed\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/grain.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/grain.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new grain post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinGrainPostProcess.FragmentUrl,\r\n            uniforms: ThinGrainPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The intensity of the grain added (default: 30)\r\n     */\r\n    public intensity = 30;\r\n\r\n    /**\r\n     * If the grain should be randomized on every frame\r\n     */\r\n    public animated = false;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setFloat(\"intensity\", this.intensity);\r\n        this._drawWrapper.effect!.setFloat(\"animatedSeed\", this.animated ? Math.random() + 1 : 1);\r\n    }\r\n}\r\n","import { type FrameGraph } from \"core/FrameGraph/frameGraph\";\r\nimport { ThinGrainPostProcess } from \"core/PostProcesses/thinGrainPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a grain post process.\r\n */\r\nexport class FrameGraphGrainTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinGrainPostProcess;\r\n\r\n    /**\r\n     * Constructs a new grain task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the grain effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinGrainPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinGrainPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphGrainTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphGrainTask } from \"core/FrameGraph/Tasks/PostProcesses/grainTask\";\r\nimport { ThinGrainPostProcess } from \"core/PostProcesses/thinGrainPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the grain post process\r\n */\r\nexport class NodeRenderGraphGrainPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphGrainTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new grain post process block\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphGrainTask(this.name, frameGraph, new ThinGrainPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** The intensity of the grain added */\r\n    @editableInPropertyPage(\"Intensity\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 200 })\r\n    public get intensity(): number {\r\n        return this._frameGraphTask.postProcess.intensity;\r\n    }\r\n\r\n    public set intensity(value: number) {\r\n        this._frameGraphTask.postProcess.intensity = value;\r\n    }\r\n\r\n    /** If the grain should be randomized on every frame */\r\n    @editableInPropertyPage(\"Animated\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get animated(): boolean {\r\n        return this._frameGraphTask.postProcess.animated;\r\n    }\r\n\r\n    public set animated(value: boolean) {\r\n        this._frameGraphTask.postProcess.animated = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphGrainPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.intensity = ${this.intensity};`);\r\n        codes.push(`${this._codeVariableName}.animated = ${this.animated};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.intensity = this.intensity;\r\n        serializationObject.animated = this.animated;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.intensity = serializationObject.intensity;\r\n        this.animated = serializationObject.animated;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for grainPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGrainPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphGrainPostProcessBlock\", NodeRenderGraphGrainPostProcessBlock);\r\n}\r\n","import {\r\n    type Nullable,\r\n    type AbstractEngine,\r\n    type EffectWrapperCreationOptions,\r\n    type Observer,\r\n    type NonNullableFields,\r\n    type Scene,\r\n    type ColorCurves,\r\n    type BaseTexture,\r\n    type Color4,\r\n} from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IImageProcessingConfigurationDefines } from \"../Materials/imageProcessingConfiguration.defines\";\r\nimport { ImageProcessingConfiguration } from \"../Materials/imageProcessingConfiguration.pure\";\r\n\r\n/**\r\n * Options used to create a ThinImageProcessingPostProcessOptions.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface ThinImageProcessingPostProcessOptions extends EffectWrapperCreationOptions {\r\n    /**\r\n     * An existing image processing configuration to use. If not provided, the scene one will be used.\r\n     */\r\n    imageProcessingConfiguration?: ImageProcessingConfiguration;\r\n\r\n    /**\r\n     * The scene to retrieve the image processing configuration from if not provided in the options.\r\n     * If not provided, the last created scene will be used.\r\n     */\r\n    scene?: Nullable<Scene>;\r\n\r\n    /**\r\n     * The correlated color temperature, in Kelvin, of the illuminant to neutralize via white balance, applied to\r\n     * the resolved image processing configuration - see `ImageProcessingConfiguration.temperature`. Providing\r\n     * this (or `tint`) also enables white balance. Defaults to 6500 K.\r\n     */\r\n    temperature?: number;\r\n\r\n    /**\r\n     * The white balance tint offset to apply, on the green/magenta axis, to the resolved image processing\r\n     * configuration - see `ImageProcessingConfiguration.tint`. Providing this (or `temperature`) also enables\r\n     * white balance. Defaults to 0 (no tint offset).\r\n     */\r\n    tint?: number;\r\n}\r\n\r\n/**\r\n * Applies the `temperature`/`tint` white balance options (if provided) to an image processing configuration,\r\n * enabling white balance if either was supplied. Exported (but internal) so it can be applied uniformly\r\n * regardless of how the configuration was resolved - in particular, `ImageProcessingPostProcess` also calls this\r\n * directly on `this.imageProcessingConfiguration` after construction, since a caller-supplied `effectWrapper`\r\n * bypasses `ThinImageProcessingPostProcess`'s own constructor (and thus its own call to this function) entirely.\r\n * @param configuration the image processing configuration to update\r\n * @param options the options object that may contain `temperature`/`tint`, or a plain size number (ignored)\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function _ApplyWhiteBalanceOptions(configuration: ImageProcessingConfiguration, options?: { temperature?: number; tint?: number } | number): void {\r\n    if (!options || typeof options === \"number\") {\r\n        return;\r\n    }\r\n\r\n    if (options.temperature === undefined && options.tint === undefined) {\r\n        return;\r\n    }\r\n\r\n    if (options.temperature !== undefined) {\r\n        configuration.temperature = options.temperature;\r\n    }\r\n    if (options.tint !== undefined) {\r\n        configuration.tint = options.tint;\r\n    }\r\n    configuration.whiteBalanceEnabled = true;\r\n}\r\n\r\n/**\r\n * Post process used to apply image processing to a scene\r\n */\r\nexport class ThinImageProcessingPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"imageProcessing\";\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/imageProcessing.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/imageProcessing.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Default configuration related to image processing available in the PBR Material.\r\n     */\r\n    protected _imageProcessingConfiguration: ImageProcessingConfiguration;\r\n\r\n    /**\r\n     * Gets the image processing configuration used either in this material.\r\n     */\r\n    public get imageProcessingConfiguration(): ImageProcessingConfiguration {\r\n        return this._imageProcessingConfiguration;\r\n    }\r\n\r\n    /**\r\n     * Sets the Default image processing configuration used either in the this material.\r\n     *\r\n     * If sets to null, the scene one is in use.\r\n     */\r\n    public set imageProcessingConfiguration(value: ImageProcessingConfiguration) {\r\n        // We are almost sure it is applied by post process as\r\n        // We are in the post process :-)\r\n        value.applyByPostProcess = true;\r\n        this._attachImageProcessingConfiguration(value);\r\n    }\r\n\r\n    /**\r\n     * Keep track of the image processing observer to allow dispose and replace.\r\n     */\r\n    private _imageProcessingObserver: Nullable<Observer<ImageProcessingConfiguration>>;\r\n\r\n    /**\r\n     * Attaches a new image processing configuration to the PBR Material.\r\n     * @param configuration\r\n     * @param doNotBuild\r\n     */\r\n    protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>, doNotBuild = false): void {\r\n        if (configuration === this._imageProcessingConfiguration) {\r\n            return;\r\n        }\r\n\r\n        // Detaches observer.\r\n        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n        }\r\n\r\n        // Pick the scene configuration if needed.\r\n        if (!configuration) {\r\n            let scene = this.options.scene;\r\n\r\n            if (!scene) {\r\n                const engine = this.options.engine;\r\n                if (engine && engine.scenes) {\r\n                    const scenes = engine.scenes;\r\n                    scene = scenes[scenes.length - 1];\r\n                } else {\r\n                    scene = EngineStore.LastCreatedScene!;\r\n                }\r\n            }\r\n\r\n            if (scene) {\r\n                this._imageProcessingConfiguration = scene.imageProcessingConfiguration;\r\n            } else {\r\n                this._imageProcessingConfiguration = new ImageProcessingConfiguration();\r\n            }\r\n        } else {\r\n            this._imageProcessingConfiguration = configuration;\r\n        }\r\n\r\n        // Attaches observer.\r\n        if (this._imageProcessingConfiguration) {\r\n            this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(() => {\r\n                this._updateParameters();\r\n            });\r\n        }\r\n\r\n        // Ensure the effect will be rebuilt.\r\n        if (!doNotBuild) {\r\n            this._updateParameters();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets Color curves setup used in the effect if colorCurvesEnabled is set to true .\r\n     */\r\n    public get colorCurves(): Nullable<ColorCurves> {\r\n        return this.imageProcessingConfiguration.colorCurves;\r\n    }\r\n    /**\r\n     * Sets Color curves setup used in the effect if colorCurvesEnabled is set to true .\r\n     */\r\n    public set colorCurves(value: Nullable<ColorCurves>) {\r\n        this.imageProcessingConfiguration.colorCurves = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the color curves effect is enabled.\r\n     */\r\n    public get colorCurvesEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.colorCurvesEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the color curves effect is enabled.\r\n     */\r\n    public set colorCurvesEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.colorCurvesEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Color grading LUT texture used in the effect if colorGradingEnabled is set to true.\r\n     */\r\n    public get colorGradingTexture(): Nullable<BaseTexture> {\r\n        return this.imageProcessingConfiguration.colorGradingTexture;\r\n    }\r\n    /**\r\n     * Sets Color grading LUT texture used in the effect if colorGradingEnabled is set to true.\r\n     */\r\n    public set colorGradingTexture(value: Nullable<BaseTexture>) {\r\n        this.imageProcessingConfiguration.colorGradingTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the color grading effect is enabled.\r\n     */\r\n    public get colorGradingEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.colorGradingEnabled;\r\n    }\r\n    /**\r\n     * Gets whether the color grading effect is enabled.\r\n     */\r\n    public set colorGradingEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.colorGradingEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets exposure used in the effect.\r\n     */\r\n    public get exposure(): number {\r\n        return this.imageProcessingConfiguration.exposure;\r\n    }\r\n    /**\r\n     * Sets exposure used in the effect.\r\n     */\r\n    public set exposure(value: number) {\r\n        this.imageProcessingConfiguration.exposure = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether tonemapping is enabled or not.\r\n     */\r\n    public get toneMappingEnabled(): boolean {\r\n        return this._imageProcessingConfiguration.toneMappingEnabled;\r\n    }\r\n    /**\r\n     * Sets whether tonemapping is enabled or not\r\n     */\r\n    public set toneMappingEnabled(value: boolean) {\r\n        this._imageProcessingConfiguration.toneMappingEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the type of tone mapping effect.\r\n     */\r\n    public get toneMappingType(): number {\r\n        return this._imageProcessingConfiguration.toneMappingType;\r\n    }\r\n    /**\r\n     * Sets the type of tone mapping effect.\r\n     */\r\n    public set toneMappingType(value: number) {\r\n        this._imageProcessingConfiguration.toneMappingType = value;\r\n    }\r\n\r\n    /**\r\n     * Gets contrast used in the effect.\r\n     */\r\n    public get contrast(): number {\r\n        return this.imageProcessingConfiguration.contrast;\r\n    }\r\n    /**\r\n     * Sets contrast used in the effect.\r\n     */\r\n    public set contrast(value: number) {\r\n        this.imageProcessingConfiguration.contrast = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the white balance effect is enabled.\r\n     */\r\n    public get whiteBalanceEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.whiteBalanceEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the white balance effect is enabled.\r\n     */\r\n    public set whiteBalanceEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.whiteBalanceEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the white balance correlated color temperature, in Kelvin, used in the effect.\r\n     */\r\n    public get temperature(): number {\r\n        return this.imageProcessingConfiguration.temperature;\r\n    }\r\n    /**\r\n     * Sets the white balance correlated color temperature, in Kelvin, used in the effect.\r\n     */\r\n    public set temperature(value: number) {\r\n        this.imageProcessingConfiguration.temperature = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the white balance tint offset used in the effect.\r\n     */\r\n    public get tint(): number {\r\n        return this.imageProcessingConfiguration.tint;\r\n    }\r\n    /**\r\n     * Sets the white balance tint offset used in the effect.\r\n     */\r\n    public set tint(value: number) {\r\n        this.imageProcessingConfiguration.tint = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette stretch size.\r\n     */\r\n    public get vignetteStretch(): number {\r\n        return this.imageProcessingConfiguration.vignetteStretch;\r\n    }\r\n    /**\r\n     * Sets Vignette stretch size.\r\n     */\r\n    public set vignetteStretch(value: number) {\r\n        this.imageProcessingConfiguration.vignetteStretch = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette center X Offset.\r\n     * @deprecated use vignetteCenterX instead\r\n     */\r\n    public get vignetteCentreX(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterX;\r\n    }\r\n    /**\r\n     * Sets Vignette center X Offset.\r\n     * @deprecated use vignetteCenterX instead\r\n     */\r\n    public set vignetteCentreX(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterX = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette center Y Offset.\r\n     * @deprecated use vignetteCenterY instead\r\n     */\r\n    public get vignetteCentreY(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterY;\r\n    }\r\n    /**\r\n     * Sets Vignette center Y Offset.\r\n     * @deprecated use vignetteCenterY instead\r\n     */\r\n    public set vignetteCentreY(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterY = value;\r\n    }\r\n\r\n    /**\r\n     * Vignette center Y Offset.\r\n     */\r\n    public get vignetteCenterY(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterY;\r\n    }\r\n    public set vignetteCenterY(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterY = value;\r\n    }\r\n\r\n    /**\r\n     * Vignette center X Offset.\r\n     */\r\n    public get vignetteCenterX(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterX;\r\n    }\r\n    public set vignetteCenterX(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterX = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette weight or intensity of the vignette effect.\r\n     */\r\n    public get vignetteWeight(): number {\r\n        return this.imageProcessingConfiguration.vignetteWeight;\r\n    }\r\n    /**\r\n     * Sets Vignette weight or intensity of the vignette effect.\r\n     */\r\n    public set vignetteWeight(value: number) {\r\n        this.imageProcessingConfiguration.vignetteWeight = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)\r\n     * if vignetteEnabled is set to true.\r\n     */\r\n    public get vignetteColor(): Color4 {\r\n        return this.imageProcessingConfiguration.vignetteColor;\r\n    }\r\n    /**\r\n     * Sets Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)\r\n     * if vignetteEnabled is set to true.\r\n     */\r\n    public set vignetteColor(value: Color4) {\r\n        this.imageProcessingConfiguration.vignetteColor = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Camera field of view used by the Vignette effect.\r\n     */\r\n    public get vignetteCameraFov(): number {\r\n        return this.imageProcessingConfiguration.vignetteCameraFov;\r\n    }\r\n    /**\r\n     * Sets Camera field of view used by the Vignette effect.\r\n     */\r\n    public set vignetteCameraFov(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCameraFov = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the vignette blend mode allowing different kind of effect.\r\n     */\r\n    public get vignetteBlendMode(): number {\r\n        return this.imageProcessingConfiguration.vignetteBlendMode;\r\n    }\r\n    /**\r\n     * Sets the vignette blend mode allowing different kind of effect.\r\n     */\r\n    public set vignetteBlendMode(value: number) {\r\n        this.imageProcessingConfiguration.vignetteBlendMode = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the vignette effect is enabled.\r\n     */\r\n    public get vignetteEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.vignetteEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the vignette effect is enabled.\r\n     */\r\n    public set vignetteEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.vignetteEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets intensity of the dithering effect.\r\n     */\r\n    public get ditheringIntensity(): number {\r\n        return this.imageProcessingConfiguration.ditheringIntensity;\r\n    }\r\n    /**\r\n     * Sets intensity of the dithering effect.\r\n     */\r\n    public set ditheringIntensity(value: number) {\r\n        this.imageProcessingConfiguration.ditheringIntensity = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the dithering effect is enabled.\r\n     */\r\n    public get ditheringEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.ditheringEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the dithering effect is enabled.\r\n     */\r\n    public set ditheringEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.ditheringEnabled = value;\r\n    }\r\n\r\n    private _fromLinearSpace = true;\r\n    /**\r\n     * Gets whether the input of the processing is in Gamma or Linear Space.\r\n     */\r\n    public get fromLinearSpace(): boolean {\r\n        return this._fromLinearSpace;\r\n    }\r\n    /**\r\n     * Sets whether the input of the processing is in Gamma or Linear Space.\r\n     */\r\n    public set fromLinearSpace(value: boolean) {\r\n        if (this._fromLinearSpace === value) {\r\n            return;\r\n        }\r\n\r\n        this._fromLinearSpace = value;\r\n        this._updateParameters();\r\n    }\r\n\r\n    /**\r\n     * * Gets the width of the output texture used to store the result of the post process.\r\n     */\r\n    public get outputTextureWidth() {\r\n        return this.imageProcessingConfiguration.outputTextureWidth;\r\n    }\r\n\r\n    /**\r\n     * * Sets the width of the output texture used to store the result of the post process.\r\n     */\r\n    public set outputTextureWidth(value: number) {\r\n        this.imageProcessingConfiguration.outputTextureWidth = value;\r\n    }\r\n\r\n    /**\r\n     * * Gets the height of the output texture used to store the result of the post process.\r\n     */\r\n    public get outputTextureHeight() {\r\n        return this.imageProcessingConfiguration.outputTextureHeight;\r\n    }\r\n\r\n    /**\r\n     * * Sets the height of the output texture used to store the result of the post process.\r\n     */\r\n    public set outputTextureHeight(value: number) {\r\n        this.imageProcessingConfiguration.outputTextureHeight = value;\r\n    }\r\n\r\n    /**\r\n     * Gets/sets the aspect ratio used to override the default one.\r\n     */\r\n    public overrideAspectRatio?: number;\r\n\r\n    /**\r\n     * Defines cache preventing GC.\r\n     */\r\n    private _defines: IImageProcessingConfigurationDefines & { FROMLINEARSPACE: boolean } = {\r\n        IMAGEPROCESSING: false,\r\n        WHITEBALANCE: false,\r\n        VIGNETTE: false,\r\n        VIGNETTEBLENDMODEMULTIPLY: false,\r\n        VIGNETTEBLENDMODEOPAQUE: false,\r\n        TONEMAPPING: 0,\r\n        CONTRAST: false,\r\n        COLORCURVES: false,\r\n        COLORGRADING: false,\r\n        COLORGRADING3D: false,\r\n        FROMLINEARSPACE: false,\r\n        SAMPLER3DGREENDEPTH: false,\r\n        SAMPLER3DBGRMAP: false,\r\n        DITHER: false,\r\n        IMAGEPROCESSINGPOSTPROCESS: false,\r\n        EXPOSURE: false,\r\n        SKIPFINALCOLORCLAMP: false,\r\n    };\r\n\r\n    public override readonly options: Required<NonNullableFields<ThinImageProcessingPostProcessOptions>>;\r\n\r\n    /**\r\n     * Constructs a new image processing post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: ThinImageProcessingPostProcessOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinImageProcessingPostProcess.FragmentUrl,\r\n        });\r\n\r\n        const imageProcessingConfiguration = options?.imageProcessingConfiguration;\r\n\r\n        // Setup the configuration as forced by the constructor. This would then not force the\r\n        // scene materials output in linear space and let untouched the default forward pass.\r\n        if (imageProcessingConfiguration) {\r\n            imageProcessingConfiguration.applyByPostProcess = true;\r\n            this._attachImageProcessingConfiguration(imageProcessingConfiguration, true);\r\n            _ApplyWhiteBalanceOptions(this.imageProcessingConfiguration, options);\r\n            // This will cause the shader to be compiled\r\n            this._updateParameters();\r\n        }\r\n        // Setup the default processing configuration to the scene.\r\n        else {\r\n            this._attachImageProcessingConfiguration(null, true);\r\n            _ApplyWhiteBalanceOptions(this.imageProcessingConfiguration, options);\r\n            this.imageProcessingConfiguration.applyByPostProcess = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _updateParameters(): void {\r\n        this._defines.FROMLINEARSPACE = this._fromLinearSpace;\r\n        this.imageProcessingConfiguration.prepareDefines(this._defines, true);\r\n        let defines = \"\";\r\n        for (const prop in this._defines) {\r\n            const value = (<any>this._defines)[prop];\r\n            const type = typeof value;\r\n\r\n            switch (type) {\r\n                case \"number\":\r\n                case \"string\":\r\n                    defines += `#define ${prop} ${value};\\n`;\r\n                    break;\r\n                default:\r\n                    if (value) {\r\n                        defines += `#define ${prop};\\n`;\r\n                    }\r\n                    break;\r\n            }\r\n        }\r\n\r\n        const samplers = [\"textureSampler\"];\r\n        const uniforms = [\"scale\"];\r\n\r\n        if (ImageProcessingConfiguration) {\r\n            ImageProcessingConfiguration.PrepareSamplers(samplers, this._defines);\r\n            ImageProcessingConfiguration.PrepareUniforms(uniforms, this._defines);\r\n        }\r\n\r\n        this.updateEffect(defines, uniforms, samplers);\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this.imageProcessingConfiguration.bind(this.effect, this.overrideAspectRatio);\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n        }\r\n\r\n        if (this._imageProcessingConfiguration) {\r\n            this.imageProcessingConfiguration.applyByPostProcess = false;\r\n        }\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderPass, type FrameGraphRenderContext } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinImageProcessingPostProcess } from \"core/PostProcesses/thinImageProcessingPostProcess\";\r\n\r\n/**\r\n * Task which applies an image processing post process.\r\n */\r\nexport class FrameGraphImageProcessingTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinImageProcessingPostProcess;\r\n\r\n    /**\r\n     * Constructs a new image processing task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinImageProcessingPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinImageProcessingPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphImageProcessingTask\";\r\n    }\r\n\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.outputTextureWidth = this._outputWidth;\r\n        this.postProcess.outputTextureHeight = this._outputHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphImageProcessingTask } from \"core/FrameGraph/Tasks/PostProcesses/imageProcessingTask\";\r\nimport { ThinImageProcessingPostProcess } from \"core/PostProcesses/thinImageProcessingPostProcess\";\r\nimport { ImageProcessingConfiguration } from \"core/Materials/imageProcessingConfiguration.pure\";\r\nimport { Color4 } from \"../../../../Maths/math.color.pure\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the image processing post process\r\n */\r\nexport class NodeRenderGraphImageProcessingPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphImageProcessingTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new image processing post process block\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphImageProcessingTask(\r\n            this.name,\r\n            frameGraph,\r\n            new ThinImageProcessingPostProcess(name, scene.getEngine(), {\r\n                scene,\r\n                imageProcessingConfiguration: new ImageProcessingConfiguration(),\r\n            })\r\n        );\r\n    }\r\n\r\n    /** Contrast used in the effect */\r\n    @editableInPropertyPage(\"Contrast\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 4 })\r\n    public get contrast(): number {\r\n        return this._frameGraphTask.postProcess.contrast;\r\n    }\r\n\r\n    public set contrast(value: number) {\r\n        this._frameGraphTask.postProcess.contrast = value;\r\n    }\r\n\r\n    /** Exposure used in the effect */\r\n    @editableInPropertyPage(\"Exposure\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 4 })\r\n    public get exposure(): number {\r\n        return this._frameGraphTask.postProcess.exposure;\r\n    }\r\n\r\n    public set exposure(value: number) {\r\n        this._frameGraphTask.postProcess.exposure = value;\r\n    }\r\n\r\n    /** Whether the tone mapping effect is enabled. */\r\n    @editableInPropertyPage(\"Enabled\", PropertyTypeForEdition.Boolean, \"TONE MAPPING\")\r\n    public get toneMappingEnabled(): boolean {\r\n        return this._frameGraphTask.postProcess.toneMappingEnabled;\r\n    }\r\n\r\n    public set toneMappingEnabled(value: boolean) {\r\n        this._frameGraphTask.postProcess.toneMappingEnabled = value;\r\n    }\r\n\r\n    /** Type of tone mapping effect. */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.List, \"TONE MAPPING\", {\r\n        options: [\r\n            { value: ImageProcessingConfiguration.TONEMAPPING_STANDARD, label: \"Standard\" },\r\n            { value: ImageProcessingConfiguration.TONEMAPPING_ACES, label: \"ACES\" },\r\n            { value: ImageProcessingConfiguration.TONEMAPPING_KHR_PBR_NEUTRAL, label: \"KHR PBR Neutral\" },\r\n        ],\r\n    })\r\n    public get toneMappingType(): number {\r\n        return this._frameGraphTask.postProcess.toneMappingType;\r\n    }\r\n\r\n    public set toneMappingType(value: number) {\r\n        this._frameGraphTask.postProcess.toneMappingType = value;\r\n    }\r\n\r\n    /** Whether the vignette effect is enabled. */\r\n    @editableInPropertyPage(\"Enabled\", PropertyTypeForEdition.Boolean, \"VIGNETTE\")\r\n    public get vignetteEnabled(): boolean {\r\n        return this._frameGraphTask.postProcess.vignetteEnabled;\r\n    }\r\n\r\n    public set vignetteEnabled(value: boolean) {\r\n        this._frameGraphTask.postProcess.vignetteEnabled = value;\r\n    }\r\n\r\n    /** Vignette weight or intensity of the vignette effect. */\r\n    @editableInPropertyPage(\"Weight\", PropertyTypeForEdition.Float, \"VIGNETTE\", { min: 0, max: 200 })\r\n    public get vignetteWeight(): number {\r\n        return this._frameGraphTask.postProcess.vignetteWeight;\r\n    }\r\n\r\n    public set vignetteWeight(value: number) {\r\n        this._frameGraphTask.postProcess.vignetteWeight = value;\r\n    }\r\n\r\n    /** Vignette stretch size. */\r\n    @editableInPropertyPage(\"Stretch\", PropertyTypeForEdition.Float, \"VIGNETTE\", { min: 0, max: 1 })\r\n    public get vignetteStretch(): number {\r\n        return this._frameGraphTask.postProcess.vignetteStretch;\r\n    }\r\n\r\n    public set vignetteStretch(value: number) {\r\n        this._frameGraphTask.postProcess.vignetteStretch = value;\r\n    }\r\n\r\n    /** Camera field of view used by the Vignette effect. */\r\n    @editableInPropertyPage(\"FOV\", PropertyTypeForEdition.Float, \"VIGNETTE\", { min: 0, max: 3.14159 })\r\n    public get vignetteCameraFov(): number {\r\n        return this._frameGraphTask.postProcess.vignetteCameraFov;\r\n    }\r\n\r\n    public set vignetteCameraFov(value: number) {\r\n        this._frameGraphTask.postProcess.vignetteCameraFov = value;\r\n    }\r\n\r\n    /** Vignette center X Offset. */\r\n    @editableInPropertyPage(\"Center X\", PropertyTypeForEdition.Float, \"VIGNETTE\", { min: 0, max: 1 })\r\n    public get vignetteCenterX(): number {\r\n        return this._frameGraphTask.postProcess.vignetteCenterX;\r\n    }\r\n\r\n    public set vignetteCenterX(value: number) {\r\n        this._frameGraphTask.postProcess.vignetteCenterX = value;\r\n    }\r\n\r\n    /** Vignette center Y Offset. */\r\n    @editableInPropertyPage(\"Center Y\", PropertyTypeForEdition.Float, \"VIGNETTE\", { min: 0, max: 1 })\r\n    public get vignetteCenterY(): number {\r\n        return this._frameGraphTask.postProcess.vignetteCenterY;\r\n    }\r\n\r\n    public set vignetteCenterY(value: number) {\r\n        this._frameGraphTask.postProcess.vignetteCenterY = value;\r\n    }\r\n\r\n    /** Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode) */\r\n    @editableInPropertyPage(\"Color\", PropertyTypeForEdition.Color4, \"VIGNETTE\")\r\n    public get vignetteColor(): Color4 {\r\n        return this._frameGraphTask.postProcess.vignetteColor;\r\n    }\r\n\r\n    public set vignetteColor(value: Color4) {\r\n        this._frameGraphTask.postProcess.vignetteColor = value;\r\n    }\r\n\r\n    /** Vignette blend mode allowing different kind of effect. */\r\n    @editableInPropertyPage(\"Blend mode\", PropertyTypeForEdition.List, \"VIGNETTE\", {\r\n        options: [\r\n            { value: ImageProcessingConfiguration.VIGNETTEMODE_MULTIPLY, label: \"Multiply\" },\r\n            { value: ImageProcessingConfiguration.VIGNETTEMODE_OPAQUE, label: \"Opaque\" },\r\n        ],\r\n    })\r\n    public get vignetteBlendMode(): number {\r\n        return this._frameGraphTask.postProcess.vignetteBlendMode;\r\n    }\r\n\r\n    public set vignetteBlendMode(value: number) {\r\n        this._frameGraphTask.postProcess.vignetteBlendMode = value;\r\n    }\r\n\r\n    /** Whether the dithering effect is enabled. */\r\n    @editableInPropertyPage(\"Enabed\", PropertyTypeForEdition.Boolean, \"DITHERING\")\r\n    public get ditheringEnabled(): boolean {\r\n        return this._frameGraphTask.postProcess.ditheringEnabled;\r\n    }\r\n\r\n    public set ditheringEnabled(value: boolean) {\r\n        this._frameGraphTask.postProcess.ditheringEnabled = value;\r\n    }\r\n\r\n    /** Sets whether the dithering effect is enabled. */\r\n    @editableInPropertyPage(\"Intensity\", PropertyTypeForEdition.Float, \"DITHERING\", { min: 0, max: 1 })\r\n    public get ditheringIntensity(): number {\r\n        return this._frameGraphTask.postProcess.ditheringIntensity;\r\n    }\r\n\r\n    public set ditheringIntensity(value: number) {\r\n        this._frameGraphTask.postProcess.ditheringIntensity = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphImageProcessingPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.contrast = ${this.contrast};`);\r\n        codes.push(`${this._codeVariableName}.exposure = ${this.exposure};`);\r\n        codes.push(`${this._codeVariableName}.toneMappingEnabled = ${this.toneMappingEnabled};`);\r\n        codes.push(`${this._codeVariableName}.toneMappingType = ${this.toneMappingType};`);\r\n        codes.push(`${this._codeVariableName}.vignetteEnabled = ${this.vignetteEnabled};`);\r\n        codes.push(`${this._codeVariableName}.vignetteWeight = ${this.vignetteWeight};`);\r\n        codes.push(`${this._codeVariableName}.vignetteStretch = ${this.vignetteStretch};`);\r\n        codes.push(`${this._codeVariableName}.vignetteCameraFov = ${this.vignetteCameraFov};`);\r\n        codes.push(`${this._codeVariableName}.vignetteCenterX = ${this.vignetteCenterX};`);\r\n        codes.push(`${this._codeVariableName}.vignetteCenterY = ${this.vignetteCenterY};`);\r\n        codes.push(`${this._codeVariableName}.vignetteColor = new BABYLON.Color4(${this.vignetteColor.r}, ${this.vignetteColor.g}, ${this.vignetteColor.b}, 1);`);\r\n        codes.push(`${this._codeVariableName}.vignetteBlendMode = ${this.vignetteBlendMode};`);\r\n        codes.push(`${this._codeVariableName}.ditheringEnabled = ${this.ditheringEnabled};`);\r\n        codes.push(`${this._codeVariableName}.ditheringIntensity = ${this.ditheringIntensity};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.contrast = this.contrast;\r\n        serializationObject.exposure = this.exposure;\r\n        serializationObject.toneMappingEnabled = this.toneMappingEnabled;\r\n        serializationObject.toneMappingType = this.toneMappingType;\r\n        serializationObject.vignetteEnabled = this.vignetteEnabled;\r\n        serializationObject.vignetteWeight = this.vignetteWeight;\r\n        serializationObject.vignetteStretch = this.vignetteStretch;\r\n        serializationObject.vignetteCameraFov = this.vignetteCameraFov;\r\n        serializationObject.vignetteCenterX = this.vignetteCenterX;\r\n        serializationObject.vignetteCenterY = this.vignetteCenterY;\r\n        serializationObject.vignetteColor = this.vignetteColor.asArray();\r\n        serializationObject.vignetteBlendMode = this.vignetteBlendMode;\r\n        serializationObject.ditheringEnabled = this.ditheringEnabled;\r\n        serializationObject.ditheringIntensity = this.ditheringIntensity;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.contrast = serializationObject.contrast;\r\n        this.exposure = serializationObject.exposure;\r\n        this.toneMappingEnabled = serializationObject.toneMappingEnabled;\r\n        this.toneMappingType = serializationObject.toneMappingType;\r\n        this.vignetteEnabled = serializationObject.vignetteEnabled;\r\n        this.vignetteWeight = serializationObject.vignetteWeight;\r\n        this.vignetteStretch = serializationObject.vignetteStretch;\r\n        this.vignetteCameraFov = serializationObject.vignetteCameraFov;\r\n        this.vignetteCenterX = serializationObject.vignetteCenterX;\r\n        this.vignetteCenterY = serializationObject.vignetteCenterY;\r\n        this.vignetteColor = Color4.FromArray(serializationObject.vignetteColor);\r\n        this.vignetteBlendMode = serializationObject.vignetteBlendMode;\r\n        this.ditheringEnabled = serializationObject.ditheringEnabled;\r\n        this.ditheringIntensity = serializationObject.ditheringIntensity;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for imageProcessingPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterImageProcessingPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphImageProcessingPostProcessBlock\", NodeRenderGraphImageProcessingPostProcessBlock);\r\n}\r\n","import { type EffectWrapperCreationOptions, type Scene } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Post process used to apply a motion blur post process\r\n */\r\nexport class ThinMotionBlurPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"motionBlur\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"motionStrength\", \"motionScale\", \"screenSize\", \"inverseViewProjection\", \"prevViewProjection\", \"projection\"];\r\n\r\n    /**\r\n     * The list of samplers used by the effect\r\n     */\r\n    public static readonly Samplers = [\"velocitySampler\", \"depthSampler\"];\r\n\r\n    /**\r\n     * The default defines used by the effect\r\n     */\r\n    public static readonly Defines = \"#define GEOMETRY_SUPPORTED\\n#define SAMPLES 64.0\\n#define OBJECT_BASED\";\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/motionBlur.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/motionBlur.fragment\"));\r\n        }\r\n    }\r\n\r\n    private _scene: Scene;\r\n    private _invViewProjection = Matrix.Identity();\r\n    private _previousViewProjection = Matrix.Identity();\r\n\r\n    /**\r\n     * Constructs a new motion blur post process\r\n     * @param name Name of the effect\r\n     * @param scene The scene the effect belongs to\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, scene: Scene, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: scene.getEngine(),\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinMotionBlurPostProcess.FragmentUrl,\r\n            uniforms: ThinMotionBlurPostProcess.Uniforms,\r\n            samplers: ThinMotionBlurPostProcess.Samplers,\r\n            defines: ThinMotionBlurPostProcess.Defines,\r\n        });\r\n\r\n        this._scene = scene;\r\n\r\n        this._applyMode();\r\n    }\r\n\r\n    /**\r\n     * Defines how much the image is blurred by the movement. Default value is equal to 1\r\n     */\r\n    public motionStrength: number = 1;\r\n\r\n    private _motionBlurSamples: number = 32;\r\n\r\n    /**\r\n     * Gets the number of iterations that are used for motion blur quality. Default value is equal to 32\r\n     */\r\n    public get motionBlurSamples(): number {\r\n        return this._motionBlurSamples;\r\n    }\r\n\r\n    /**\r\n     * Sets the number of iterations to be used for motion blur quality\r\n     */\r\n    public set motionBlurSamples(samples: number) {\r\n        this._motionBlurSamples = samples;\r\n        this._updateEffect();\r\n    }\r\n\r\n    private _isObjectBased: boolean = true;\r\n\r\n    /**\r\n     * Gets whether or not the motion blur post-process is in object based mode.\r\n     */\r\n    public get isObjectBased(): boolean {\r\n        return this._isObjectBased;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not the motion blur post-process is in object based mode.\r\n     */\r\n    public set isObjectBased(value: boolean) {\r\n        if (this._isObjectBased === value) {\r\n            return;\r\n        }\r\n\r\n        this._isObjectBased = value;\r\n        this._applyMode();\r\n    }\r\n\r\n    /**\r\n     * The width of the source texture\r\n     */\r\n    public textureWidth: number = 0;\r\n\r\n    /**\r\n     * The height of the source texture\r\n     */\r\n    public textureHeight: number = 0;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat2(\"screenSize\", this.textureWidth, this.textureHeight);\r\n        effect.setFloat(\"motionScale\", this._scene.getAnimationRatio());\r\n        effect.setFloat(\"motionStrength\", this.motionStrength);\r\n\r\n        if (!this.isObjectBased) {\r\n            const viewProjection = TmpVectors.Matrix[0];\r\n            viewProjection.copyFrom(this._scene.getTransformMatrix());\r\n\r\n            viewProjection.invertToRef(this._invViewProjection);\r\n            effect.setMatrix(\"inverseViewProjection\", this._invViewProjection);\r\n\r\n            effect.setMatrix(\"prevViewProjection\", this._previousViewProjection);\r\n            this._previousViewProjection.copyFrom(viewProjection);\r\n\r\n            effect.setMatrix(\"projection\", this._scene.getProjectionMatrix());\r\n        }\r\n    }\r\n\r\n    private _updateEffect(): void {\r\n        const defines: string[] = [\r\n            \"#define GEOMETRY_SUPPORTED\",\r\n            \"#define SAMPLES \" + this._motionBlurSamples.toFixed(1),\r\n            this._isObjectBased ? \"#define OBJECT_BASED\" : \"#define SCREEN_BASED\",\r\n        ];\r\n\r\n        this.updateEffect(defines.join(\"\\n\"));\r\n    }\r\n\r\n    private _applyMode() {\r\n        this._updateEffect();\r\n        this._previousViewProjection.copyFrom(this._scene.getTransformMatrix());\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinMotionBlurPostProcess } from \"core/PostProcesses/thinMotionBlurPostProcess\";\r\n\r\n/**\r\n * Task which applies a motion blur post process.\r\n */\r\nexport class FrameGraphMotionBlurTask extends FrameGraphPostProcessTask {\r\n    /**\r\n     * The velocity texture to use for the motion blur effect.\r\n     * Needed for object-based motion blur.\r\n     */\r\n    public velocityTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The (view) depth texture to use for the motion blur effect.\r\n     * Needed for screen-based motion blur.\r\n     */\r\n    public depthTexture?: FrameGraphTextureHandle;\r\n\r\n    public override readonly postProcess: ThinMotionBlurPostProcess;\r\n\r\n    /**\r\n     * Constructs a new motion blur task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinMotionBlurPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinMotionBlurPostProcess(name, frameGraph.scene));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphMotionBlurTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined) {\r\n            throw new Error(`FrameGraphMotionBlurTask \"${this.name}\": sourceTexture is required`);\r\n        }\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {\r\n            if (this.velocityTexture) {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"velocitySampler\", this.velocityTexture);\r\n            } else if (this.postProcess.isObjectBased) {\r\n                throw new Error(`FrameGraphMotionBlurTask \"${this.name}\": velocityTexture is required for object-based motion blur`);\r\n            }\r\n\r\n            if (this.depthTexture) {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n            } else if (!this.postProcess.isObjectBased) {\r\n                throw new Error(`FrameGraphMotionBlurTask \"${this.name}\": depthTexture is required for screen-based motion blur`);\r\n            }\r\n        });\r\n\r\n        pass.addDependencies(this.velocityTexture);\r\n        pass.addDependencies(this.depthTexture);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphMotionBlurTask } from \"core/FrameGraph/Tasks/PostProcesses/motionBlurTask\";\r\nimport { ThinMotionBlurPostProcess } from \"core/PostProcesses/thinMotionBlurPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the motion blur post process\r\n */\r\nexport class NodeRenderGraphMotionBlurPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphMotionBlurTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphMotionBlurPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"geomVelocity\", NodeRenderGraphBlockConnectionPointTypes.TextureVelocity, true);\r\n        this.registerInput(\"geomViewDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth, true);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphMotionBlurTask(this.name, frameGraph, new ThinMotionBlurPostProcess(name, frameGraph.scene));\r\n    }\r\n\r\n    /** Defines how much the image is blurred by the movement. */\r\n    @editableInPropertyPage(\"Strength\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get motionStrength(): number {\r\n        return this._frameGraphTask.postProcess.motionStrength;\r\n    }\r\n\r\n    public set motionStrength(value: number) {\r\n        this._frameGraphTask.postProcess.motionStrength = value;\r\n    }\r\n\r\n    /** Gets the number of iterations that are used for motion blur quality. */\r\n    @editableInPropertyPage(\"Samples\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get motionBlurSamples(): number {\r\n        return this._frameGraphTask.postProcess.motionBlurSamples;\r\n    }\r\n\r\n    public set motionBlurSamples(value: number) {\r\n        this._frameGraphTask.postProcess.motionBlurSamples = value;\r\n    }\r\n\r\n    /** Gets whether or not the motion blur post-process is in object based mode. */\r\n    @editableInPropertyPage(\"Object based\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get isObjectBased(): boolean {\r\n        return this._frameGraphTask.postProcess.isObjectBased;\r\n    }\r\n\r\n    public set isObjectBased(value: boolean) {\r\n        this._frameGraphTask.postProcess.isObjectBased = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphMotionBlurPostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry velocity input component\r\n     */\r\n    public get geomVelocity(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry view depth input component\r\n     */\r\n    public get geomViewDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.velocityTexture = this.geomVelocity.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.depthTexture = this.geomViewDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.motionStrength = ${this.motionStrength};`);\r\n        codes.push(`${this._codeVariableName}.motionBlurSamples = ${this.motionBlurSamples};`);\r\n        codes.push(`${this._codeVariableName}.isObjectBased = ${this.isObjectBased};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.motionStrength = this.motionStrength;\r\n        serializationObject.motionBlurSamples = this.motionBlurSamples;\r\n        serializationObject.isObjectBased = this.isObjectBased;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.motionStrength = serializationObject.motionStrength;\r\n        this.motionBlurSamples = serializationObject.motionBlurSamples;\r\n        this.isObjectBased = serializationObject.isObjectBased;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for motionBlurPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMotionBlurPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphMotionBlurPostProcessBlock\", NodeRenderGraphMotionBlurPostProcessBlock);\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine.pure\";\r\n\r\n/**\r\n * Checks whether an engine supports the render-target and shader features required by mesh blending.\r\n * @param engine Engine to check.\r\n * @returns True for WebGL2 and WebGPU engines, and false for Native and WebGL1 engines.\r\n * @internal\r\n */\r\nexport function _IsMeshBlendingSupported(engine: AbstractEngine): boolean {\r\n    return engine.shaderPlatformName !== \"NATIVE\" && (engine.isWebGPU || (engine as ThinEngine).webGLVersion === 2);\r\n}\r\n\r\n/**\r\n * Radius class stored in a packed mesh-blending tag.\r\n *\r\n * The selected class combines an authored world radius with a minimum projected radius. At a seam,\r\n * the smaller class from the two participating surfaces is used.\r\n */\r\nexport enum MeshBlendingRadiusClass {\r\n    /** Small blend radius. */\r\n    Small = 0,\r\n    /** Medium blend radius. */\r\n    Medium = 1,\r\n    /** Large blend radius. */\r\n    Large = 2,\r\n    /** Extra-large blend radius. */\r\n    ExtraLarge = 3,\r\n}\r\n\r\n/**\r\n * Decoded values stored in a packed mesh-blending tag.\r\n */\r\nexport interface IMeshBlendingTag {\r\n    /** Logical blend group. Group 0 disables mesh blending. */\r\n    groupId: number;\r\n    /** Radius class used to select the blend radius. */\r\n    radiusClass: MeshBlendingRadiusClass;\r\n}\r\n\r\n/**\r\n * Packs a mesh-blending group and radius class into one byte.\r\n * @param groupId Logical blend group. Use 0 to disable mesh blending, otherwise use a value from 1 to 63.\r\n * @param radiusClass Radius class from 0 to 3.\r\n * @returns The packed mesh-blending tag.\r\n * @see https://playground.babylonjs.com/?version=preview#XVZTSI#3\r\n */\r\nexport function PackMeshBlendingTag(groupId: number, radiusClass: MeshBlendingRadiusClass): number {\r\n    if (!Number.isInteger(groupId) || groupId < 0 || groupId > 63) {\r\n        throw new RangeError(\"Mesh-blending group ID must be an integer between 0 and 63.\");\r\n    }\r\n    if (groupId === 0) {\r\n        return 0;\r\n    }\r\n    if (!Number.isInteger(radiusClass) || radiusClass < MeshBlendingRadiusClass.Small || radiusClass > MeshBlendingRadiusClass.ExtraLarge) {\r\n        throw new RangeError(\"Mesh-blending radius class must be an integer between 0 and 3.\");\r\n    }\r\n\r\n    return (radiusClass << 6) | groupId;\r\n}\r\n\r\n/**\r\n * Decodes a packed mesh-blending tag.\r\n * @param tag Packed mesh-blending tag.\r\n * @returns The decoded group and radius class.\r\n */\r\nexport function UnpackMeshBlendingTag(tag: number): IMeshBlendingTag {\r\n    if (!Number.isInteger(tag) || tag < 0 || tag > 0xff) {\r\n        throw new RangeError(\"Mesh-blending tag must be an integer between 0 and 255.\");\r\n    }\r\n\r\n    const groupId = tag & 0x3f;\r\n    if (tag !== 0 && groupId === 0) {\r\n        throw new RangeError(\"A nonzero mesh-blending tag must contain a group ID between 1 and 63.\");\r\n    }\r\n\r\n    return {\r\n        groupId,\r\n        radiusClass: tag >> 6,\r\n    };\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\n\r\nconst _TextureSize = 128;\r\nlet _BlueNoiseData: Uint8Array | undefined;\r\n\r\nfunction _HashPixel(x: number, y: number, seed: number): number {\r\n    let value = Math.imul(x ^ seed, 0x45d9f3b) ^ Math.imul(y + seed, 0x119de1f3);\r\n    value = Math.imul(value ^ (value >>> 16), 0x45d9f3b);\r\n    value = Math.imul(value ^ (value >>> 16), 0x45d9f3b);\r\n    return ((value ^ (value >>> 16)) >>> 0) / 0x100000000;\r\n}\r\n\r\nfunction _FillBlueNoiseChannel(data: Uint8Array, channel: number, seed: number): void {\r\n    const pixelCount = _TextureSize * _TextureSize;\r\n    const whiteNoise = new Float32Array(pixelCount);\r\n    const highPassNoise = new Float32Array(pixelCount);\r\n    const rankedIndices = new Array<number>(pixelCount);\r\n\r\n    for (let y = 0; y < _TextureSize; y++) {\r\n        for (let x = 0; x < _TextureSize; x++) {\r\n            const index = y * _TextureSize + x;\r\n            whiteNoise[index] = _HashPixel(x, y, seed);\r\n            rankedIndices[index] = index;\r\n        }\r\n    }\r\n\r\n    for (let y = 0; y < _TextureSize; y++) {\r\n        const previousY = (y - 1) & (_TextureSize - 1);\r\n        const nextY = (y + 1) & (_TextureSize - 1);\r\n        for (let x = 0; x < _TextureSize; x++) {\r\n            const previousX = (x - 1) & (_TextureSize - 1);\r\n            const nextX = (x + 1) & (_TextureSize - 1);\r\n            const index = y * _TextureSize + x;\r\n            const neighborAverage =\r\n                (whiteNoise[y * _TextureSize + previousX] +\r\n                    whiteNoise[y * _TextureSize + nextX] +\r\n                    whiteNoise[previousY * _TextureSize + x] +\r\n                    whiteNoise[nextY * _TextureSize + x] +\r\n                    whiteNoise[previousY * _TextureSize + previousX] +\r\n                    whiteNoise[previousY * _TextureSize + nextX] +\r\n                    whiteNoise[nextY * _TextureSize + previousX] +\r\n                    whiteNoise[nextY * _TextureSize + nextX]) *\r\n                0.125;\r\n            highPassNoise[index] = whiteNoise[index] - neighborAverage;\r\n        }\r\n    }\r\n\r\n    // Ranking the toroidal high-pass signal preserves its spectral shape while restoring a uniform byte distribution.\r\n    rankedIndices.sort((left, right) => highPassNoise[left] - highPassNoise[right] || left - right);\r\n    for (let rank = 0; rank < pixelCount; rank++) {\r\n        data[rankedIndices[rank] * 2 + channel] = Math.floor((rank * 256) / pixelCount);\r\n    }\r\n}\r\n\r\n/**\r\n * Gets the deterministic RG8 blue-noise data used by mesh blending.\r\n * @returns The shared blue-noise byte data.\r\n * @internal\r\n */\r\nexport function _GetMeshBlendBlueNoiseData(): Uint8Array {\r\n    if (_BlueNoiseData) {\r\n        return _BlueNoiseData;\r\n    }\r\n\r\n    const data = new Uint8Array(_TextureSize * _TextureSize * 2);\r\n    _FillBlueNoiseChannel(data, 0, 0x68bc21eb);\r\n    _FillBlueNoiseChannel(data, 1, 0x2f6e2b1d);\r\n    _BlueNoiseData = data;\r\n    return data;\r\n}\r\n\r\n/**\r\n * Creates the deterministic, spatially stable RG8 blue-noise texture used by mesh blending.\r\n * @param engine Engine that owns the texture.\r\n * @returns The blue-noise texture.\r\n * @internal\r\n */\r\nexport function _CreateMeshBlendBlueNoiseTexture(engine: AbstractEngine): RawTexture {\r\n    const texture = new RawTexture(\r\n        _GetMeshBlendBlueNoiseData(),\r\n        _TextureSize,\r\n        _TextureSize,\r\n        Constants.TEXTUREFORMAT_RG,\r\n        engine,\r\n        false,\r\n        false,\r\n        Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n        Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    );\r\n    texture.name = \"MeshBlendStableBlueNoise\";\r\n    texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n    texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n    return texture;\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type EffectWrapperCreationOptions } from \"../Materials/effectRenderer\";\r\nimport { type RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport { _IsMeshBlendingSupported } from \"../Meshes/meshBlendingTag\";\r\nimport { _CreateMeshBlendBlueNoiseTexture } from \"./meshBlendingBlueNoise\";\r\n\r\n/**\r\n * Quality level used by mesh blending.\r\n *\r\n * Each value selects a separate compile-time shader variant. Medium is the default.\r\n */\r\nexport enum MeshBlendQuality {\r\n    /** Three search directions with the lowest refinement and exact-boundary sample counts, using sRGB color interpolation. */\r\n    Low = 0,\r\n    /** Three search directions with balanced refinement and exact-boundary sample counts, using OKLab color interpolation. */\r\n    Medium = 1,\r\n    /** Three search directions with OKLab interpolation, full rotation, close-neighbor fallback, tiny-object protection, and multi-target blending. */\r\n    High = 2,\r\n    /** Eight search directions with OKLab interpolation and the largest radial and exact-boundary sample counts. */\r\n    Cinematic = 3,\r\n}\r\n\r\n/**\r\n * Debug visualization produced by mesh blending.\r\n */\r\nexport enum MeshBlendDebugMode {\r\n    /** Render the blended scene color. */\r\n    Off = 0,\r\n    /** Visualize the packed group and radius-class tag. */\r\n    PackedTag = 1,\r\n    /** Visualize the refined candidate direction and normalized boundary distance. */\r\n    CandidateDirectionDistance = 2,\r\n    /** Visualize the selected radius class and the resulting seam fade. */\r\n    SeamFade = 3,\r\n    /** Visualize why a candidate was accepted or rejected by contact validation. */\r\n    RejectionReason = 4,\r\n    /** Visualize the approximate amount of shader work performed by each pixel. */\r\n    StageWork = 5,\r\n    /** Visualize target continuation success, fallback use, and rejection. */\r\n    Continuation = 6,\r\n    /** Visualize the effective-radius reduction applied to thin projected objects. */\r\n    TinyObject = 7,\r\n    /** Visualize primary-only and secondary-target selections at multi-mesh junctions. */\r\n    MultiTarget = 8,\r\n    /** Visualize the farther, boundary-plus-one, boundary-plus-two, and constructed target-color samples. */\r\n    TargetColor = 9,\r\n    /** Visualize the fade attenuation applied by the base-color shadow-transfer heuristic. Neutral when no base-color texture is provided. */\r\n    ShadowAttenuation = 10,\r\n    /** Visualize the active color-interpolation mode after target-color construction. */\r\n    ColorInterpolation = 11,\r\n    /** Visualize the reconstructed world position. */\r\n    WorldPosition = 12,\r\n}\r\n\r\n/**\r\n * Depth representation consumed by mesh blending.\r\n */\r\nexport enum MeshBlendDepthType {\r\n    /** Signed camera-space Z written by the geometry renderer's view-depth output. */\r\n    View = 0,\r\n    /** Hardware depth in the normalized screen-depth range. */\r\n    Screen = 1,\r\n}\r\n\r\n/**\r\n * Radius values associated with one mesh-blending radius class.\r\n */\r\nexport interface IMeshBlendRadiusDefinition {\r\n    /** Authored blend radius in Babylon world units. */\r\n    worldRadius: number;\r\n    /** Minimum search radius in physical render-target pixels. */\r\n    minimumProjectedRadius: number;\r\n}\r\n\r\n/**\r\n * The four radius definitions indexed by the packed mesh-blending radius class.\r\n */\r\nexport type MeshBlendRadiusDefinitions = readonly [IMeshBlendRadiusDefinition, IMeshBlendRadiusDefinition, IMeshBlendRadiusDefinition, IMeshBlendRadiusDefinition];\r\n\r\nconst _MeshBlendingEffectWrapperOwners = new WeakMap<ThinMeshBlendingPostProcess, object>();\r\n\r\n/**\r\n * Checks whether a thin mesh-blending wrapper is already exclusively owned.\r\n * @param wrapper Wrapper to check.\r\n * @returns Whether the wrapper already has an owner.\r\n * @internal\r\n */\r\nexport function _IsMeshBlendingEffectWrapperOwned(wrapper: ThinMeshBlendingPostProcess): boolean {\r\n    return _MeshBlendingEffectWrapperOwners.has(wrapper);\r\n}\r\n\r\n/**\r\n * Claims exclusive ownership of a thin mesh-blending wrapper.\r\n * @param wrapper Wrapper to claim.\r\n * @param owner Owner claiming the wrapper.\r\n * @internal\r\n */\r\nexport function _ClaimMeshBlendingEffectWrapper(wrapper: ThinMeshBlendingPostProcess, owner: object): void {\r\n    if (_MeshBlendingEffectWrapperOwners.has(wrapper)) {\r\n        throw new Error(\"ThinMeshBlendingPostProcess is already attached to another owner\");\r\n    }\r\n    _MeshBlendingEffectWrapperOwners.set(wrapper, owner);\r\n}\r\n\r\n/**\r\n * Releases exclusive ownership of a thin mesh-blending wrapper.\r\n * @param wrapper Wrapper to release.\r\n * @param owner Owner releasing the wrapper.\r\n * @internal\r\n */\r\nexport function _ReleaseMeshBlendingEffectWrapper(wrapper: ThinMeshBlendingPostProcess, owner: object): void {\r\n    if (_MeshBlendingEffectWrapperOwners.get(wrapper) === owner) {\r\n        _MeshBlendingEffectWrapperOwners.delete(wrapper);\r\n    }\r\n}\r\n\r\nfunction _ValidateWorldRadius(value: number): void {\r\n    if (!Number.isFinite(value) || value < 0) {\r\n        throw new RangeError(\"Mesh-blending world radii must be finite non-negative numbers.\");\r\n    }\r\n}\r\n\r\nfunction _ValidateMinimumProjectedRadius(value: number): void {\r\n    if (!Number.isFinite(value) || value < 0) {\r\n        throw new RangeError(\"Mesh-blending minimum projected radii must be finite non-negative numbers.\");\r\n    }\r\n}\r\n\r\nfunction _CreateValidatedRadiusDefinition(worldRadius: number, minimumProjectedRadius: number): IMeshBlendRadiusDefinition {\r\n    let validatedWorldRadius = 0;\r\n    let validatedMinimumProjectedRadius = 0;\r\n    const definition = {} as IMeshBlendRadiusDefinition;\r\n\r\n    Object.defineProperties(definition, {\r\n        worldRadius: {\r\n            enumerable: true,\r\n            get: () => validatedWorldRadius,\r\n            set: (value: number) => {\r\n                _ValidateWorldRadius(value);\r\n                validatedWorldRadius = value;\r\n            },\r\n        },\r\n        minimumProjectedRadius: {\r\n            enumerable: true,\r\n            get: () => validatedMinimumProjectedRadius,\r\n            set: (value: number) => {\r\n                _ValidateMinimumProjectedRadius(value);\r\n                validatedMinimumProjectedRadius = value;\r\n            },\r\n        },\r\n    });\r\n    definition.worldRadius = worldRadius;\r\n    definition.minimumProjectedRadius = minimumProjectedRadius;\r\n    return definition;\r\n}\r\n\r\n/**\r\n * Configurable mesh-blending values shared by the classic and frame-graph wrappers.\r\n */\r\nexport interface IMeshBlendConfiguration {\r\n    /** Compile-time quality variant. */\r\n    quality?: MeshBlendQuality;\r\n    /** Radius definitions indexed by packed radius class. Exactly four definitions are required. */\r\n    radiusClasses?: readonly [IMeshBlendRadiusDefinition, IMeshBlendRadiusDefinition, IMeshBlendRadiusDefinition, IMeshBlendRadiusDefinition];\r\n    /** Contact-slope narrowing factor. A value of 1 disables narrowing. */\r\n    slopeFactor?: number;\r\n    /** Representation stored in the depth texture. */\r\n    depthType?: MeshBlendDepthType;\r\n    /** Debug visualization to compile into the shader. Off renders the final blended result. */\r\n    debugMode?: MeshBlendDebugMode;\r\n}\r\n\r\n/**\r\n * Options used to create a thin mesh-blending post process.\r\n */\r\nexport interface IThinMeshBlendingPostProcessOptions extends EffectWrapperCreationOptions, IMeshBlendConfiguration {}\r\n\r\n/**\r\n * Creates a new set of default mesh-blending radius definitions.\r\n * @returns Four independently mutable radius definitions ordered from small to extra large.\r\n */\r\nexport function CreateDefaultMeshBlendRadiusDefinitions(): MeshBlendRadiusDefinitions {\r\n    return Object.freeze([\r\n        _CreateValidatedRadiusDefinition(0.06, 1.5),\r\n        _CreateValidatedRadiusDefinition(0.1, 3),\r\n        _CreateValidatedRadiusDefinition(0.2, 3),\r\n        _CreateValidatedRadiusDefinition(0.3, 5),\r\n    ]) as MeshBlendRadiusDefinitions;\r\n}\r\n\r\ninterface IMeshBlendQualitySettings {\r\n    directionCount: number;\r\n    radialSampleCount: number;\r\n    directionRefinementSampleCount: number;\r\n    directionRefinementStepCount: number;\r\n    exactEdgeSampleCount: number;\r\n    radiusScale: number;\r\n    fullRandomRotation: boolean;\r\n    searchJitterFactor: number;\r\n    immediateFourNeighborFallback: boolean;\r\n    tinyObjectSafeguard: boolean;\r\n    multiTargetSecondaryBlend: boolean;\r\n    colorInterpolation: \"sRGB\" | \"OKLab\";\r\n}\r\n\r\ntype MeshBlendColorTuple = readonly [number, number, number];\r\n\r\nfunction _MeshBlendLinearToSrgbChannel(value: number): number {\r\n    return value <= 0.0031308 ? value * 12.92 : 1.055 * Math.pow(value, 1 / 2.4) - 0.055;\r\n}\r\n\r\nfunction _MeshBlendSrgbToLinearChannel(value: number): number {\r\n    return value <= 0.04045 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4);\r\n}\r\n\r\n/**\r\n * Converts linear sRGB to Babylon mesh-blending OKLab coordinates.\r\n * @param color Linear sRGB color. HDR components are preserved.\r\n * @returns OKLab coordinates.\r\n * @see https://bottosson.github.io/posts/oklab/\r\n * @internal\r\n */\r\nexport function _LinearSrgbToMeshBlendOklab(color: MeshBlendColorTuple): [number, number, number] {\r\n    const long = 0.4122214708 * color[0] + 0.5363325363 * color[1] + 0.0514459929 * color[2];\r\n    const medium = 0.2119034982 * color[0] + 0.6806995451 * color[1] + 0.1073969566 * color[2];\r\n    const short = 0.0883024619 * color[0] + 0.2817188376 * color[1] + 0.6299787005 * color[2];\r\n    const longRoot = Math.cbrt(long);\r\n    const mediumRoot = Math.cbrt(medium);\r\n    const shortRoot = Math.cbrt(short);\r\n\r\n    return [\r\n        0.2104542553 * longRoot + 0.793617785 * mediumRoot - 0.0040720468 * shortRoot,\r\n        1.9779984951 * longRoot - 2.428592205 * mediumRoot + 0.4505937099 * shortRoot,\r\n        0.0259040371 * longRoot + 0.7827717662 * mediumRoot - 0.808675766 * shortRoot,\r\n    ];\r\n}\r\n\r\n/**\r\n * Converts Babylon mesh-blending OKLab coordinates to linear sRGB.\r\n * @param color OKLab coordinates.\r\n * @returns Linear sRGB color without gamut or HDR clamping.\r\n * @see https://bottosson.github.io/posts/oklab/\r\n * @internal\r\n */\r\nexport function _MeshBlendOklabToLinearSrgb(color: MeshBlendColorTuple): [number, number, number] {\r\n    const longRoot = color[0] + 0.3963377774 * color[1] + 0.2158037573 * color[2];\r\n    const mediumRoot = color[0] - 0.1055613458 * color[1] - 0.0638541728 * color[2];\r\n    const shortRoot = color[0] - 0.0894841775 * color[1] - 1.291485548 * color[2];\r\n    const long = longRoot * longRoot * longRoot;\r\n    const medium = mediumRoot * mediumRoot * mediumRoot;\r\n    const short = shortRoot * shortRoot * shortRoot;\r\n\r\n    return [\r\n        4.0767416621 * long - 3.3077115913 * medium + 0.2309699292 * short,\r\n        -1.2684380046 * long + 2.6097574011 * medium - 0.3413193965 * short,\r\n        -0.0041960863 * long - 0.7034186147 * medium + 1.707614701 * short,\r\n    ];\r\n}\r\n\r\n/**\r\n * Interpolates two linear SceneColor values using the selected mesh-blending quality policy.\r\n * @param current Current linear SceneColor.\r\n * @param target Target linear SceneColor.\r\n * @param amount Interpolation amount.\r\n * @param quality Mesh-blending quality that selects sRGB or OKLab interpolation.\r\n * @returns Interpolated linear SceneColor without HDR clamping.\r\n * @internal\r\n */\r\nexport function _InterpolateMeshBlendColor(current: MeshBlendColorTuple, target: MeshBlendColorTuple, amount: number, quality: MeshBlendQuality): [number, number, number] {\r\n    const settings = _GetMeshBlendQualitySettings(quality);\r\n    let currentColor: MeshBlendColorTuple;\r\n    let targetColor: MeshBlendColorTuple;\r\n\r\n    if (settings.colorInterpolation === \"sRGB\") {\r\n        currentColor = [_MeshBlendLinearToSrgbChannel(current[0]), _MeshBlendLinearToSrgbChannel(current[1]), _MeshBlendLinearToSrgbChannel(current[2])];\r\n        targetColor = [_MeshBlendLinearToSrgbChannel(target[0]), _MeshBlendLinearToSrgbChannel(target[1]), _MeshBlendLinearToSrgbChannel(target[2])];\r\n        return [\r\n            _MeshBlendSrgbToLinearChannel(currentColor[0] + (targetColor[0] - currentColor[0]) * amount),\r\n            _MeshBlendSrgbToLinearChannel(currentColor[1] + (targetColor[1] - currentColor[1]) * amount),\r\n            _MeshBlendSrgbToLinearChannel(currentColor[2] + (targetColor[2] - currentColor[2]) * amount),\r\n        ];\r\n    }\r\n\r\n    currentColor = _LinearSrgbToMeshBlendOklab(current);\r\n    targetColor = _LinearSrgbToMeshBlendOklab(target);\r\n    return _MeshBlendOklabToLinearSrgb([\r\n        currentColor[0] + (targetColor[0] - currentColor[0]) * amount,\r\n        currentColor[1] + (targetColor[1] - currentColor[1]) * amount,\r\n        currentColor[2] + (targetColor[2] - currentColor[2]) * amount,\r\n    ]);\r\n}\r\n\r\nconst _MeshBlendQualitySettings: readonly Readonly<IMeshBlendQualitySettings>[] = [\r\n    {\r\n        directionCount: 3,\r\n        radialSampleCount: 2,\r\n        directionRefinementSampleCount: 1,\r\n        directionRefinementStepCount: 2,\r\n        exactEdgeSampleCount: 5,\r\n        radiusScale: 0.5,\r\n        fullRandomRotation: false,\r\n        searchJitterFactor: 0.5,\r\n        immediateFourNeighborFallback: false,\r\n        tinyObjectSafeguard: false,\r\n        multiTargetSecondaryBlend: false,\r\n        colorInterpolation: \"sRGB\",\r\n    },\r\n    {\r\n        directionCount: 3,\r\n        radialSampleCount: 3,\r\n        directionRefinementSampleCount: 2,\r\n        directionRefinementStepCount: 4,\r\n        exactEdgeSampleCount: 8,\r\n        radiusScale: 0.9,\r\n        fullRandomRotation: false,\r\n        searchJitterFactor: 0.5,\r\n        immediateFourNeighborFallback: false,\r\n        tinyObjectSafeguard: false,\r\n        multiTargetSecondaryBlend: false,\r\n        colorInterpolation: \"OKLab\",\r\n    },\r\n    {\r\n        directionCount: 3,\r\n        radialSampleCount: 3,\r\n        directionRefinementSampleCount: 3,\r\n        directionRefinementStepCount: 5,\r\n        exactEdgeSampleCount: 10,\r\n        radiusScale: 1,\r\n        fullRandomRotation: true,\r\n        searchJitterFactor: 0.5,\r\n        immediateFourNeighborFallback: true,\r\n        tinyObjectSafeguard: true,\r\n        multiTargetSecondaryBlend: true,\r\n        colorInterpolation: \"OKLab\",\r\n    },\r\n    {\r\n        directionCount: 8,\r\n        radialSampleCount: 6,\r\n        directionRefinementSampleCount: 4,\r\n        directionRefinementStepCount: 5,\r\n        exactEdgeSampleCount: 50,\r\n        radiusScale: 0.95,\r\n        fullRandomRotation: true,\r\n        searchJitterFactor: 1,\r\n        immediateFourNeighborFallback: true,\r\n        tinyObjectSafeguard: true,\r\n        multiTargetSecondaryBlend: true,\r\n        colorInterpolation: \"OKLab\",\r\n    },\r\n];\r\n\r\n/**\r\n * Gets the complete quality settings used to compile a mesh-blending shader variant.\r\n * @param quality Quality to inspect.\r\n * @returns The immutable settings for the quality.\r\n * @internal\r\n */\r\nexport function _GetMeshBlendQualitySettings(quality: MeshBlendQuality): Readonly<IMeshBlendQualitySettings> {\r\n    const settings = _MeshBlendQualitySettings[quality];\r\n    if (!settings || !Number.isInteger(quality)) {\r\n        throw new RangeError(\"Mesh-blending quality must be Low, Medium, High, or Cinematic.\");\r\n    }\r\n    return settings;\r\n}\r\n\r\n/**\r\n * Gets the radius scale used by a mesh-blending quality level.\r\n * @param quality Quality to convert.\r\n * @returns The radius scale applied after projection and the minimum-pixel floor.\r\n * @internal\r\n */\r\nexport function _GetMeshBlendQualityRadiusScale(quality: MeshBlendQuality): number {\r\n    return _GetMeshBlendQualitySettings(quality).radiusScale;\r\n}\r\n\r\n/**\r\n * Projects a world-space mesh-blending radius to physical render-target pixels.\r\n * @param worldRadius Radius in Babylon world units.\r\n * @param viewDepth Positive distance from the camera.\r\n * @param renderTargetHeight Physical render-target height.\r\n * @param projectionYScale Absolute Y scale from the projection matrix.\r\n * @param isOrthographic Whether the projection is orthographic.\r\n * @returns The projected radius in physical pixels.\r\n * @internal\r\n */\r\nexport function _ProjectMeshBlendWorldRadiusToPixels(\r\n    worldRadius: number,\r\n    viewDepth: number,\r\n    renderTargetHeight: number,\r\n    projectionYScale: number,\r\n    isOrthographic: boolean\r\n): number {\r\n    const projectionScale = 0.5 * renderTargetHeight * Math.abs(projectionYScale);\r\n    return worldRadius * (isOrthographic ? projectionScale : projectionScale / Math.max(Math.abs(viewDepth), 1e-5));\r\n}\r\n\r\n/**\r\n * Calculates the final mesh-blending search radius.\r\n * @param definition Radius-class definition.\r\n * @param viewDepth Positive distance from the camera.\r\n * @param renderTargetHeight Physical render-target height.\r\n * @param projectionYScale Absolute Y scale from the projection matrix.\r\n * @param isOrthographic Whether the projection is orthographic.\r\n * @param quality Quality whose radius scale is applied.\r\n * @returns The final radius in physical pixels.\r\n * @internal\r\n */\r\nexport function _CalculateMeshBlendSearchRadius(\r\n    definition: IMeshBlendRadiusDefinition,\r\n    viewDepth: number,\r\n    renderTargetHeight: number,\r\n    projectionYScale: number,\r\n    isOrthographic: boolean,\r\n    quality: MeshBlendQuality\r\n): number {\r\n    const projectedRadius = _ProjectMeshBlendWorldRadiusToPixels(definition.worldRadius, viewDepth, renderTargetHeight, projectionYScale, isOrthographic);\r\n    const scaledRadius = Math.max(projectedRadius, definition.minimumProjectedRadius) * _GetMeshBlendQualityRadiusScale(quality);\r\n    return scaledRadius > 0 ? Math.max(1, scaledRadius) : 0;\r\n}\r\n\r\n/**\r\n * Calculates the mesh-blending fade for a candidate boundary.\r\n * @param distancePixels Distance from the current pixel center to the target pixel center.\r\n * @param searchRadiusPixels Effective search radius in physical pixels.\r\n * @returns Blend weight in the range 0 through 0.5.\r\n * @internal\r\n */\r\nexport function _CalculateMeshBlendFade(distancePixels: number, searchRadiusPixels: number): number {\r\n    const boundaryDistance = Math.max(distancePixels - 0.5, 0);\r\n    const normalizedDistance = Math.min(Math.max(boundaryDistance / Math.max(searchRadiusPixels, 0.00001), 0), 1);\r\n    const inverseDistance = 1 - normalizedDistance;\r\n    const fade = inverseDistance * inverseDistance + (inverseDistance - inverseDistance * inverseDistance) * Math.min(Math.max(inverseDistance - 0.75, 0), 1);\r\n    return fade * 0.5;\r\n}\r\n\r\n/**\r\n * Converts a physical-pixel radius back to the represented world-space radius.\r\n * @param radiusPixels Radius in physical render-target pixels.\r\n * @param viewDepth Positive distance from the camera.\r\n * @param renderTargetHeight Physical render-target height.\r\n * @param projectionYScale Absolute Y scale from the projection matrix.\r\n * @param isOrthographic Whether the projection is orthographic.\r\n * @returns The represented radius in Babylon world units.\r\n * @internal\r\n */\r\nexport function _CalculateMeshBlendEffectiveWorldRadius(\r\n    radiusPixels: number,\r\n    viewDepth: number,\r\n    renderTargetHeight: number,\r\n    projectionYScale: number,\r\n    isOrthographic: boolean\r\n): number {\r\n    const projectionScale = Math.max(0.5 * renderTargetHeight * Math.abs(projectionYScale), 1e-5);\r\n    return radiusPixels * (isOrthographic ? 1 / projectionScale : Math.max(Math.abs(viewDepth), 1e-5) / projectionScale);\r\n}\r\n\r\n/**\r\n * Calculates the contact-slope radius multiplier.\r\n * @param oppositeFacing Cosine-domain alignment of the two surface spans.\r\n * @param slopeFactor User-configurable narrowing factor.\r\n * @returns A multiplier in the range [0.25, 1].\r\n * @internal\r\n */\r\nexport function _CalculateMeshBlendSlopeScale(oppositeFacing: number, slopeFactor: number): number {\r\n    if (slopeFactor <= 1) {\r\n        return 1;\r\n    }\r\n    return 0.25 + 0.75 * Math.pow(Math.max(0, Math.min(oppositeFacing, 1)), slopeFactor - 1);\r\n}\r\n\r\n/**\r\n * Gets the compile-time shader define for a mesh-blending quality.\r\n * @param quality Quality to convert.\r\n * @returns The quality define.\r\n * @internal\r\n */\r\nexport function _GetMeshBlendQualityDefine(quality: MeshBlendQuality): string {\r\n    switch (quality) {\r\n        case MeshBlendQuality.Low:\r\n            return \"#define MESH_BLEND_QUALITY_LOW\";\r\n        case MeshBlendQuality.Medium:\r\n            return \"#define MESH_BLEND_QUALITY_MEDIUM\";\r\n        case MeshBlendQuality.High:\r\n            return \"#define MESH_BLEND_QUALITY_HIGH\";\r\n        case MeshBlendQuality.Cinematic:\r\n            return \"#define MESH_BLEND_QUALITY_CINEMATIC\";\r\n        default:\r\n            throw new RangeError(\"Mesh-blending quality must be Low, Medium, High, or Cinematic.\");\r\n    }\r\n}\r\n\r\n/**\r\n * Gets all compile-time defines for a mesh-blending quality variant.\r\n * @param quality Quality to convert.\r\n * @returns Newline-separated shader defines containing all quality-specific constants and feature switches.\r\n * @internal\r\n */\r\nexport function _GetMeshBlendQualityDefines(quality: MeshBlendQuality): string {\r\n    const settings = _GetMeshBlendQualitySettings(quality);\r\n    const defines = [\r\n        _GetMeshBlendQualityDefine(quality),\r\n        `#define MESH_BLEND_DIRECTION_COUNT ${settings.directionCount}`,\r\n        `#define MESH_BLEND_RADIAL_SAMPLE_COUNT ${settings.radialSampleCount}`,\r\n        `#define MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT ${settings.directionRefinementSampleCount}`,\r\n        `#define MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT ${settings.directionRefinementStepCount}`,\r\n        `#define MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT ${settings.exactEdgeSampleCount}`,\r\n        `#define MESH_BLEND_RADIUS_SCALE ${settings.radiusScale.toFixed(2)}`,\r\n        `#define MESH_BLEND_JITTER_FACTOR ${settings.searchJitterFactor.toFixed(2)}`,\r\n    ];\r\n\r\n    if (settings.fullRandomRotation) {\r\n        defines.push(\"#define MESH_BLEND_FULL_RANDOM_ROTATION\");\r\n    }\r\n    if (settings.immediateFourNeighborFallback) {\r\n        defines.push(\"#define MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\");\r\n    }\r\n    if (settings.tinyObjectSafeguard) {\r\n        defines.push(\"#define MESH_BLEND_TINY_OBJECT_SAFEGUARD\");\r\n    }\r\n    if (settings.multiTargetSecondaryBlend) {\r\n        defines.push(\"#define MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\");\r\n    }\r\n    defines.push(settings.colorInterpolation === \"sRGB\" ? \"#define MESH_BLEND_COLOR_INTERPOLATION_SRGB\" : \"#define MESH_BLEND_COLOR_INTERPOLATION_OKLAB\");\r\n\r\n    return defines.join(\"\\n\");\r\n}\r\n\r\nfunction _ValidateDebugMode(value: MeshBlendDebugMode): void {\r\n    if (value < MeshBlendDebugMode.Off || value > MeshBlendDebugMode.WorldPosition || !Number.isInteger(value)) {\r\n        throw new RangeError(\r\n            \"Mesh-blending debug mode must be Off, PackedTag, CandidateDirectionDistance, SeamFade, RejectionReason, StageWork, Continuation, TinyObject, MultiTarget, TargetColor, ShadowAttenuation, ColorInterpolation, or WorldPosition.\"\r\n        );\r\n    }\r\n}\r\n\r\nfunction _ValidateDepthType(value: MeshBlendDepthType): void {\r\n    if (value !== MeshBlendDepthType.View && value !== MeshBlendDepthType.Screen) {\r\n        throw new RangeError(\"Mesh-blending depthType must be View or Screen.\");\r\n    }\r\n}\r\n\r\nfunction _NormalizeDefines(defines: Nullable<string | string[]>): string {\r\n    return Array.isArray(defines) ? defines.join(\"\\n\") : (defines ?? \"\");\r\n}\r\n\r\nfunction _BuildMeshBlendDefines(quality: MeshBlendQuality, debugMode: MeshBlendDebugMode, depthType: MeshBlendDepthType, hasBaseColorTexture: boolean, customDefines = \"\"): string {\r\n    _ValidateDebugMode(debugMode);\r\n    _ValidateDepthType(depthType);\r\n\r\n    const defines = customDefines ? [customDefines, _GetMeshBlendQualityDefines(quality)] : [_GetMeshBlendQualityDefines(quality)];\r\n\r\n    if (debugMode !== MeshBlendDebugMode.Off) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_ENABLED\");\r\n    }\r\n\r\n    if (debugMode === MeshBlendDebugMode.PackedTag) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_PACKED_TAG\");\r\n    } else if (debugMode === MeshBlendDebugMode.CandidateDirectionDistance) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_CANDIDATE_DIRECTION_DISTANCE\");\r\n    } else if (debugMode === MeshBlendDebugMode.SeamFade) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_SEAM_FADE\");\r\n    } else if (debugMode === MeshBlendDebugMode.RejectionReason) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_REJECTION_REASON\");\r\n    } else if (debugMode === MeshBlendDebugMode.StageWork) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_STAGE_WORK\");\r\n    } else if (debugMode === MeshBlendDebugMode.Continuation) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_CONTINUATION\");\r\n    } else if (debugMode === MeshBlendDebugMode.TinyObject) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_TINY_OBJECT\");\r\n    } else if (debugMode === MeshBlendDebugMode.MultiTarget) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_MULTI_TARGET\");\r\n    } else if (debugMode === MeshBlendDebugMode.TargetColor) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_TARGET_COLOR\");\r\n    } else if (debugMode === MeshBlendDebugMode.ShadowAttenuation) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_SHADOW_ATTENUATION\");\r\n    } else if (debugMode === MeshBlendDebugMode.ColorInterpolation) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_COLOR_INTERPOLATION\");\r\n    } else if (debugMode === MeshBlendDebugMode.WorldPosition) {\r\n        defines.push(\"#define MESH_BLEND_DEBUG_WORLD_POSITION\");\r\n    }\r\n\r\n    if (depthType === MeshBlendDepthType.Screen) {\r\n        defines.push(\"#define MESH_BLEND_DEPTH_SCREEN\");\r\n    }\r\n    if (hasBaseColorTexture) {\r\n        defines.push(\"#define MESH_BLEND_SHADOW_ESTIMATION\");\r\n    }\r\n\r\n    return defines.join(\"\\n\");\r\n}\r\n\r\nfunction _ValidateRadiusDefinition(definition: IMeshBlendRadiusDefinition): void {\r\n    _ValidateWorldRadius(definition.worldRadius);\r\n    _ValidateMinimumProjectedRadius(definition.minimumProjectedRadius);\r\n}\r\n\r\n/**\r\n * Validates mesh-blending configuration without mutating an effect.\r\n * @param options Configuration to validate.\r\n * @internal\r\n */\r\nexport function _ValidateMeshBlendConfiguration(options?: IMeshBlendConfiguration): void {\r\n    if (!options) {\r\n        return;\r\n    }\r\n    if (options.quality !== undefined) {\r\n        _GetMeshBlendQualitySettings(options.quality);\r\n    }\r\n    if (options.debugMode !== undefined) {\r\n        _ValidateDebugMode(options.debugMode);\r\n    }\r\n    if (options.depthType !== undefined) {\r\n        _ValidateDepthType(options.depthType);\r\n    }\r\n    if (options.radiusClasses) {\r\n        if (options.radiusClasses.length !== 4) {\r\n            throw new RangeError(\"Mesh-blending radiusClasses must contain exactly four radius definitions.\");\r\n        }\r\n        for (const definition of options.radiusClasses) {\r\n            _ValidateRadiusDefinition(definition);\r\n        }\r\n    }\r\n    if (options.slopeFactor !== undefined && (!Number.isFinite(options.slopeFactor) || options.slopeFactor < 1)) {\r\n        throw new RangeError(\"Mesh-blending slopeFactor must be a finite number greater than or equal to 1.\");\r\n    }\r\n}\r\n\r\nfunction _CopyRadiusDefinitions(target: MeshBlendRadiusDefinitions, source: IMeshBlendConfiguration[\"radiusClasses\"]): void {\r\n    if (!source || source.length !== 4) {\r\n        throw new RangeError(\"Mesh blending requires exactly four radius definitions.\");\r\n    }\r\n\r\n    for (const definition of source) {\r\n        _ValidateRadiusDefinition(definition);\r\n    }\r\n    for (let index = 0; index < 4; index++) {\r\n        target[index]!.worldRadius = source[index]!.worldRadius;\r\n        target[index]!.minimumProjectedRadius = source[index]!.minimumProjectedRadius;\r\n    }\r\n}\r\n\r\n/**\r\n * Shared WebGL2 and WebGPU effect wrapper used to visually blend SceneColor across validated contacts between opaque or alpha-tested meshes.\r\n *\r\n * The effect does not modify geometry, depth, normals, collisions, or shadows. Transparent rendering is caller-controlled;\r\n * overlapping transparent surfaces can make SceneColor inconsistent with the single-layer geometry inputs. Meshes opt in\r\n * with a packed tag whose group is in the range 1..63; group 0 disables blending. Surfaces in the same nonzero group are\r\n * treated as one logical object and do not blend with one another. The four radius classes combine an authored world-space\r\n * radius with a minimum radius measured in physical render-target pixels.\r\n *\r\n * Perspective and orthographic cameras are supported. Search noise is spatially stable and never varies by frame.\r\n * Optional base-color input enables shadow estimation; without it, the related sampler and shader work are compiled out.\r\n * The effect does not require or implement TAA.\r\n */\r\nexport class ThinMeshBlendingPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader URL.\r\n     */\r\n    public static readonly FragmentUrl = \"meshBlending\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect.\r\n     */\r\n    public static readonly Uniforms = [\"projection\", \"inverseProjection\", \"inverseView\", \"blendWorldRadii\", \"minimumProjectedRadii\", \"meshBlendIsOrthographic\", \"slopeFactor\"];\r\n\r\n    /**\r\n     * The list of samplers used by the effect.\r\n     */\r\n    public static readonly Samplers = [\"meshBlendTagSampler\", \"meshBlendDepthSampler\", \"meshBlendBaseColorSampler\", \"meshBlendBlueNoiseSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/meshBlending.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/meshBlending.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The four configurable radius definitions indexed by packed radius class.\r\n     *\r\n     * Both values are projected against the active camera and the physical depth-texture height.\r\n     */\r\n    public readonly radiusClasses = CreateDefaultMeshBlendRadiusDefinitions();\r\n\r\n    /**\r\n     * Camera used to project radii and reconstruct view-space positions.\r\n     */\r\n    public camera: Nullable<Camera> = null;\r\n\r\n    private _slopeFactor = 2;\r\n\r\n    /**\r\n     * Contact-slope narrowing factor. A value of 1 disables narrowing.\r\n     */\r\n    public get slopeFactor(): number {\r\n        return this._slopeFactor;\r\n    }\r\n\r\n    public set slopeFactor(value: number) {\r\n        if (!Number.isFinite(value) || value < 1) {\r\n            throw new RangeError(\"Mesh-blending slopeFactor must be a finite number greater than or equal to 1.\");\r\n        }\r\n        this._slopeFactor = value;\r\n    }\r\n\r\n    private readonly _stableBlueNoiseTexture: RawTexture;\r\n    private readonly _customDefines: string;\r\n    private _quality = MeshBlendQuality.Medium;\r\n    private _debugMode = MeshBlendDebugMode.Off;\r\n    private _depthType = MeshBlendDepthType.View;\r\n    private _hasBaseColorTexture = false;\r\n    private readonly _inverseProjection = new Matrix();\r\n    private readonly _inverseView = new Matrix();\r\n    private _cachedProjection: Nullable<Matrix> = null;\r\n    private _cachedView: Nullable<Matrix> = null;\r\n    private _projectionUpdateFlag = -1;\r\n    private _viewUpdateFlag = -1;\r\n\r\n    /**\r\n     * Gets the compile-time quality variant.\r\n     */\r\n    public get quality(): MeshBlendQuality {\r\n        return this._quality;\r\n    }\r\n\r\n    public set quality(value: MeshBlendQuality) {\r\n        if (this._quality === value) {\r\n            return;\r\n        }\r\n        _GetMeshBlendQualitySettings(value);\r\n        this._quality = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    /**\r\n     * Gets the compiled debug visualization.\r\n     */\r\n    public get debugMode(): MeshBlendDebugMode {\r\n        return this._debugMode;\r\n    }\r\n\r\n    public set debugMode(value: MeshBlendDebugMode) {\r\n        if (this._debugMode === value) {\r\n            return;\r\n        }\r\n        _ValidateDebugMode(value);\r\n        this._debugMode = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    /**\r\n     * Gets the representation stored in the bound depth texture.\r\n     */\r\n    public get depthType(): MeshBlendDepthType {\r\n        return this._depthType;\r\n    }\r\n\r\n    public set depthType(value: MeshBlendDepthType) {\r\n        _ValidateDepthType(value);\r\n        if (this._depthType === value) {\r\n            return;\r\n        }\r\n        this._depthType = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    /**\r\n     * Whether a base-color texture is bound and shadow estimation should be compiled.\r\n     * @internal\r\n     */\r\n    public get hasBaseColorTexture(): boolean {\r\n        return this._hasBaseColorTexture;\r\n    }\r\n\r\n    public set hasBaseColorTexture(value: boolean) {\r\n        if (this._hasBaseColorTexture === value) {\r\n            return;\r\n        }\r\n        this._hasBaseColorTexture = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    /**\r\n     * Constructs a mesh-blending post process.\r\n     * @param name Name of the effect.\r\n     * @param engine Engine used to render the effect.\r\n     * @param options Options used to configure the effect.\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: IThinMeshBlendingPostProcessOptions) {\r\n        const resolvedEngine = engine || EngineStore.LastCreatedEngine!;\r\n        if (!_IsMeshBlendingSupported(resolvedEngine)) {\r\n            throw new Error(\"ThinMeshBlendingPostProcess requires WebGL2 or WebGPU\");\r\n        }\r\n        const quality = options?.quality ?? MeshBlendQuality.Medium;\r\n        const debugMode = options?.debugMode ?? MeshBlendDebugMode.Off;\r\n        const depthType = options?.depthType ?? MeshBlendDepthType.View;\r\n        const customDefines = _NormalizeDefines(options?.defines ?? null);\r\n        _ValidateMeshBlendConfiguration(options);\r\n\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: resolvedEngine,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinMeshBlendingPostProcess.FragmentUrl,\r\n            uniforms: ThinMeshBlendingPostProcess.Uniforms,\r\n            samplers: ThinMeshBlendingPostProcess.Samplers,\r\n            defines: _BuildMeshBlendDefines(quality, debugMode, depthType, false, customDefines),\r\n        });\r\n\r\n        this._customDefines = customDefines;\r\n        this._applyConfiguration(options);\r\n        this._stableBlueNoiseTexture = _CreateMeshBlendBlueNoiseTexture(resolvedEngine);\r\n    }\r\n\r\n    /**\r\n     * Applies shared mesh-blending configuration.\r\n     * @param options Values to apply. Omitted values retain their current settings.\r\n     */\r\n    public configure(options?: IMeshBlendConfiguration): void {\r\n        const definesChanged = this._applyConfiguration(options);\r\n        if (definesChanged) {\r\n            this._updateEffectDefines();\r\n        }\r\n    }\r\n\r\n    private _applyConfiguration(options?: IMeshBlendConfiguration): boolean {\r\n        if (!options) {\r\n            return false;\r\n        }\r\n        _ValidateMeshBlendConfiguration(options);\r\n\r\n        const previousQuality = this._quality;\r\n        const previousDebugMode = this._debugMode;\r\n        const previousDepthType = this._depthType;\r\n\r\n        if (options.radiusClasses) {\r\n            _CopyRadiusDefinitions(this.radiusClasses, options.radiusClasses);\r\n        }\r\n        if (options.slopeFactor !== undefined) {\r\n            this.slopeFactor = options.slopeFactor;\r\n        }\r\n        if (options.depthType !== undefined) {\r\n            _ValidateDepthType(options.depthType);\r\n            this._depthType = options.depthType;\r\n        }\r\n        const quality = options.quality ?? this._quality;\r\n        const debugMode = options.debugMode ?? this._debugMode;\r\n        _GetMeshBlendQualitySettings(quality);\r\n        _ValidateDebugMode(debugMode);\r\n        this._quality = quality;\r\n        this._debugMode = debugMode;\r\n        return previousQuality !== quality || previousDebugMode !== debugMode || previousDepthType !== this._depthType;\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false): void {\r\n        super.bind(noDefaultBindings);\r\n\r\n        if (!this.camera) {\r\n            throw new Error(\"ThinMeshBlendingPostProcess: camera is required before binding.\");\r\n        }\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n        const projection = this._updateInverseProjection();\r\n        for (const definition of this.radiusClasses) {\r\n            _ValidateRadiusDefinition(definition);\r\n        }\r\n\r\n        effect.setMatrix(\"projection\", projection);\r\n        effect.setMatrix(\"inverseProjection\", this._inverseProjection);\r\n        if (this._debugMode === MeshBlendDebugMode.WorldPosition) {\r\n            const view = this.camera.getViewMatrix();\r\n            if (this._cachedView !== view || this._viewUpdateFlag !== view.updateFlag) {\r\n                view.invertToRef(this._inverseView);\r\n                this._cachedView = view;\r\n                this._viewUpdateFlag = view.updateFlag;\r\n            }\r\n            effect.setMatrix(\"inverseView\", this._inverseView);\r\n        }\r\n        effect.setFloat4(\r\n            \"blendWorldRadii\",\r\n            this.radiusClasses[0].worldRadius,\r\n            this.radiusClasses[1].worldRadius,\r\n            this.radiusClasses[2].worldRadius,\r\n            this.radiusClasses[3].worldRadius\r\n        );\r\n        effect.setFloat4(\r\n            \"minimumProjectedRadii\",\r\n            this.radiusClasses[0].minimumProjectedRadius,\r\n            this.radiusClasses[1].minimumProjectedRadius,\r\n            this.radiusClasses[2].minimumProjectedRadius,\r\n            this.radiusClasses[3].minimumProjectedRadius\r\n        );\r\n        effect.setFloat(\"meshBlendIsOrthographic\", this.camera.mode === Constants.ORTHOGRAPHIC_CAMERA ? 1 : 0);\r\n        effect.setFloat(\"slopeFactor\", this._slopeFactor);\r\n        effect.setTexture(\"meshBlendBlueNoiseSampler\", this._stableBlueNoiseTexture);\r\n    }\r\n\r\n    private _updateInverseProjection(): Matrix {\r\n        const projection = this.camera!.getProjectionMatrix();\r\n        if (this._cachedProjection !== projection || this._projectionUpdateFlag !== projection.updateFlag) {\r\n            projection.invertToRef(this._inverseProjection);\r\n            this._cachedProjection = projection;\r\n            this._projectionUpdateFlag = projection.updateFlag;\r\n        }\r\n        return projection;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this._stableBlueNoiseTexture.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    private _updateEffectDefines(): void {\r\n        this.updateEffect(_BuildMeshBlendDefines(this._quality, this._debugMode, this._depthType, this._hasBaseColorTexture, this._customDefines));\r\n    }\r\n}\r\n","import { Constants } from \"../../../Engines/constants\";\r\nimport { type Camera } from \"../../../Cameras/camera.pure\";\r\nimport { type FrameGraph } from \"../../frameGraph\";\r\nimport { type FrameGraphRenderPass } from \"../../Passes/renderPass\";\r\nimport { type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle } from \"../../frameGraphTypes\";\r\nimport {\r\n    type IMeshBlendConfiguration,\r\n    type MeshBlendDebugMode,\r\n    MeshBlendDepthType,\r\n    type MeshBlendQuality,\r\n    type MeshBlendRadiusDefinitions,\r\n    ThinMeshBlendingPostProcess,\r\n    _ClaimMeshBlendingEffectWrapper,\r\n    _IsMeshBlendingEffectWrapperOwned,\r\n    _ReleaseMeshBlendingEffectWrapper,\r\n} from \"../../../PostProcesses/thinMeshBlendingPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { _IsMeshBlendingSupported } from \"../../../Meshes/meshBlendingTag\";\r\n\r\nfunction _Is2DTexture(creationOptions: FrameGraphTextureCreationOptions): boolean {\r\n    return (creationOptions.options.targetTypes?.[0] ?? Constants.TEXTURE_2D) === Constants.TEXTURE_2D;\r\n}\r\n\r\nfunction _GetTextureType(creationOptions: FrameGraphTextureCreationOptions): number {\r\n    return creationOptions.options.types?.[0] ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n}\r\n\r\nfunction _GetTextureFormat(creationOptions: FrameGraphTextureCreationOptions): number {\r\n    return creationOptions.options.formats?.[0] ?? Constants.TEXTUREFORMAT_RGBA;\r\n}\r\n\r\n/**\r\n * Frame-graph task which visually blends SceneColor across validated contacts between opaque or alpha-tested meshes.\r\n *\r\n * This WebGL2 and WebGPU task uses the same effect and configuration as MeshBlendingPostProcess. It does not modify\r\n * geometry, collision queries, depth, normals, or shadows. All source and geometry textures must have matching\r\n * physical dimensions and sample counts. Transparent rendering is caller-controlled; overlapping transparent\r\n * surfaces can make SceneColor inconsistent with the single-layer geometry inputs. On WebGL2, rendering transparent\r\n * meshes into the integer tag attachment requires per-target blend parameters.\r\n * @see https://playground.babylonjs.com/?version=preview#O05LI8#6\r\n */\r\nexport class FrameGraphMeshBlendingTask extends FrameGraphPostProcessTask {\r\n    /**\r\n     * The packed R8UI mesh-blending tag texture used to locate seams.\r\n     */\r\n    public meshBlendTagTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The view-depth or screen-depth texture aligned with the packed tag texture.\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Optional linear base-color/albedo geometry texture aligned with SceneColor.\r\n     *\r\n     * When omitted, shadow estimation is compiled out.\r\n     */\r\n    public baseColorTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Camera used to project radii and reconstruct view-space positions.\r\n     */\r\n    public camera: Camera;\r\n\r\n    /**\r\n     * The thin post process containing the shared quality variant and blend configuration.\r\n     */\r\n    public override readonly postProcess: ThinMeshBlendingPostProcess;\r\n\r\n    /** Gets or sets the compile-time mesh-blending quality variant. */\r\n    public get quality(): MeshBlendQuality {\r\n        return this.postProcess.quality;\r\n    }\r\n\r\n    public set quality(value: MeshBlendQuality) {\r\n        this.postProcess.quality = value;\r\n    }\r\n\r\n    /** Gets the four configurable radius definitions indexed by packed radius class. */\r\n    public get radiusClasses(): MeshBlendRadiusDefinitions {\r\n        return this.postProcess.radiusClasses;\r\n    }\r\n\r\n    /** Gets or sets the contact-slope narrowing factor. A value of 1 disables narrowing. */\r\n    public get slopeFactor(): number {\r\n        return this.postProcess.slopeFactor;\r\n    }\r\n\r\n    public set slopeFactor(value: number) {\r\n        this.postProcess.slopeFactor = value;\r\n    }\r\n\r\n    /** Gets or sets the representation stored in depthTexture. */\r\n    public get depthType(): MeshBlendDepthType {\r\n        return this.postProcess.depthType;\r\n    }\r\n\r\n    public set depthType(value: MeshBlendDepthType) {\r\n        this.postProcess.depthType = value;\r\n    }\r\n\r\n    /** Gets or sets the compiled debug visualization. */\r\n    public get debugMode(): MeshBlendDebugMode {\r\n        return this.postProcess.debugMode;\r\n    }\r\n\r\n    public set debugMode(value: MeshBlendDebugMode) {\r\n        this.postProcess.debugMode = value;\r\n    }\r\n\r\n    /**\r\n     * Constructs a mesh-blending task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use. A new one is created when omitted.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinMeshBlendingPostProcess) {\r\n        if (thinPostProcess && thinPostProcess.options.engine !== frameGraph.engine) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${name}\": thinPostProcess must use the frame graph engine`);\r\n        }\r\n        if (thinPostProcess && _IsMeshBlendingEffectWrapperOwned(thinPostProcess)) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${name}\": thinPostProcess is already attached to another owner`);\r\n        }\r\n        super(name, frameGraph, thinPostProcess || new ThinMeshBlendingPostProcess(name, frameGraph.engine));\r\n        _ClaimMeshBlendingEffectWrapper(this.postProcess, this);\r\n        this.sourceSamplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        _ReleaseMeshBlendingEffectWrapper(this.postProcess, this);\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Applies the same configuration accepted by the classic MeshBlendingPostProcess wrapper.\r\n     * @param options Values to apply. Omitted values retain their current settings.\r\n     */\r\n    public configure(options?: IMeshBlendConfiguration): void {\r\n        this.postProcess.configure(options);\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphMeshBlendingTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        this.sourceSamplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n\r\n        if (this.sourceTexture === undefined || this.meshBlendTagTexture === undefined || this.depthTexture === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": sourceTexture, meshBlendTagTexture, depthTexture and camera are required`);\r\n        }\r\n\r\n        const engine = this._frameGraph.engine;\r\n        if (!_IsMeshBlendingSupported(engine)) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": mesh blending requires WebGL2 or WebGPU`);\r\n        }\r\n        if (this.depthType !== MeshBlendDepthType.View && this.depthType !== MeshBlendDepthType.Screen) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": depthType must be View or Screen`);\r\n        }\r\n\r\n        const meshBlendTagCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.meshBlendTagTexture);\r\n        const meshBlendTagType = _GetTextureType(meshBlendTagCreationOptions);\r\n        const meshBlendTagFormat = _GetTextureFormat(meshBlendTagCreationOptions);\r\n        const meshBlendTagSamples = meshBlendTagCreationOptions.options.samples ?? 1;\r\n\r\n        if (meshBlendTagType !== Constants.TEXTURETYPE_UNSIGNED_BYTE || meshBlendTagFormat !== Constants.TEXTUREFORMAT_RED_INTEGER) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": meshBlendTagTexture must use TEXTURETYPE_UNSIGNED_BYTE with TEXTUREFORMAT_RED_INTEGER`);\r\n        }\r\n        if (!_Is2DTexture(meshBlendTagCreationOptions)) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": meshBlendTagTexture must be a 2D texture`);\r\n        }\r\n        if (meshBlendTagSamples !== 1) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": meshBlendTagTexture must be single-sampled`);\r\n        }\r\n        if (meshBlendTagCreationOptions.options.createMipMaps) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": meshBlendTagTexture must not use mipmaps`);\r\n        }\r\n\r\n        const depthCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.depthTexture);\r\n        const depthType = _GetTextureType(depthCreationOptions);\r\n        const depthFormat = _GetTextureFormat(depthCreationOptions);\r\n        const depthSamples = depthCreationOptions.options.samples ?? 1;\r\n        const validDepthFormat = depthFormat === Constants.TEXTUREFORMAT_RED || depthFormat === Constants.TEXTUREFORMAT_RG || depthFormat === Constants.TEXTUREFORMAT_RGBA;\r\n        const validDepthType =\r\n            depthType === Constants.TEXTURETYPE_FLOAT ||\r\n            depthType === Constants.TEXTURETYPE_HALF_FLOAT ||\r\n            (this.depthType === MeshBlendDepthType.Screen && depthType === Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n\r\n        if (!validDepthFormat || !validDepthType) {\r\n            throw new Error(\r\n                `FrameGraphMeshBlendingTask \"${this.name}\": ${this.depthType === MeshBlendDepthType.View ? \"view\" : \"screen\"} depthTexture has an incompatible type or format`\r\n            );\r\n        }\r\n        if (!_Is2DTexture(depthCreationOptions)) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": depthTexture must be a 2D texture`);\r\n        }\r\n        if (depthSamples !== 1) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": depthTexture must be single-sampled`);\r\n        }\r\n        if (depthCreationOptions.options.createMipMaps) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": depthTexture must not use mipmaps`);\r\n        }\r\n\r\n        let baseColorSamples: number | undefined;\r\n        if (this.baseColorTexture !== undefined) {\r\n            const baseColorCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.baseColorTexture);\r\n            const baseColorType = _GetTextureType(baseColorCreationOptions);\r\n            const baseColorFormat = _GetTextureFormat(baseColorCreationOptions);\r\n            baseColorSamples = baseColorCreationOptions.options.samples ?? 1;\r\n            const validBaseColorFormat = baseColorFormat === Constants.TEXTUREFORMAT_RGB || baseColorFormat === Constants.TEXTUREFORMAT_RGBA;\r\n            const validBaseColorType =\r\n                baseColorType === Constants.TEXTURETYPE_UNSIGNED_BYTE || baseColorType === Constants.TEXTURETYPE_HALF_FLOAT || baseColorType === Constants.TEXTURETYPE_FLOAT;\r\n            if (!validBaseColorFormat || !validBaseColorType) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": baseColorTexture must use a non-integer RGB or RGBA color format`);\r\n            }\r\n            if (!_Is2DTexture(baseColorCreationOptions)) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": baseColorTexture must be a 2D texture`);\r\n            }\r\n            if (baseColorCreationOptions.options.createMipMaps) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": baseColorTexture must not use mipmaps`);\r\n            }\r\n        }\r\n\r\n        const sourceCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.sourceTexture);\r\n        const sourceType = _GetTextureType(sourceCreationOptions);\r\n        const sourceFormat = _GetTextureFormat(sourceCreationOptions);\r\n        const sourceSamples = sourceCreationOptions.options.samples ?? 1;\r\n        const validSourceFormat = sourceFormat === Constants.TEXTUREFORMAT_RGB || sourceFormat === Constants.TEXTUREFORMAT_RGBA;\r\n        const validSourceType = sourceType === Constants.TEXTURETYPE_UNSIGNED_BYTE || sourceType === Constants.TEXTURETYPE_HALF_FLOAT || sourceType === Constants.TEXTURETYPE_FLOAT;\r\n        if (!validSourceFormat || !validSourceType) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": sourceTexture must use a non-integer RGB or RGBA color format`);\r\n        }\r\n        if (!_Is2DTexture(sourceCreationOptions)) {\r\n            throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": sourceTexture must be a 2D texture`);\r\n        }\r\n        if (sourceSamples !== meshBlendTagSamples || sourceSamples !== depthSamples || (baseColorSamples !== undefined && sourceSamples !== baseColorSamples)) {\r\n            throw new Error(\r\n                `FrameGraphMeshBlendingTask \"${this.name}\": sourceTexture, meshBlendTagTexture, depthTexture and baseColorTexture when provided must have matching sample counts`\r\n            );\r\n        }\r\n\r\n        const sourceSize = this._frameGraph.textureManager.getTextureDescription(this.sourceTexture).size;\r\n        const meshBlendTagSize = this._frameGraph.textureManager.getTextureDescription(this.meshBlendTagTexture).size;\r\n        const depthSize = this._frameGraph.textureManager.getTextureDescription(this.depthTexture).size;\r\n        const baseColorSize = this.baseColorTexture === undefined ? undefined : this._frameGraph.textureManager.getTextureDescription(this.baseColorTexture).size;\r\n        if (\r\n            sourceSize.width !== meshBlendTagSize.width ||\r\n            sourceSize.height !== meshBlendTagSize.height ||\r\n            sourceSize.width !== depthSize.width ||\r\n            sourceSize.height !== depthSize.height ||\r\n            (baseColorSize !== undefined && (sourceSize.width !== baseColorSize.width || sourceSize.height !== baseColorSize.height))\r\n        ) {\r\n            throw new Error(\r\n                `FrameGraphMeshBlendingTask \"${this.name}\": sourceTexture, meshBlendTagTexture, depthTexture and baseColorTexture when provided must have matching dimensions`\r\n            );\r\n        }\r\n\r\n        if (this.targetTexture !== undefined) {\r\n            const targetCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.targetTexture);\r\n            const targetType = _GetTextureType(targetCreationOptions);\r\n            const targetFormat = _GetTextureFormat(targetCreationOptions);\r\n            const targetSamples = targetCreationOptions.options.samples ?? 1;\r\n            const validTargetFormat = targetFormat === Constants.TEXTUREFORMAT_RGB || targetFormat === Constants.TEXTUREFORMAT_RGBA;\r\n            const validTargetType =\r\n                targetType === Constants.TEXTURETYPE_UNSIGNED_BYTE || targetType === Constants.TEXTURETYPE_HALF_FLOAT || targetType === Constants.TEXTURETYPE_FLOAT;\r\n            if (!validTargetFormat || !validTargetType) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": targetTexture must use a non-integer RGB or RGBA color format`);\r\n            }\r\n            if (!_Is2DTexture(targetCreationOptions)) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": targetTexture must be a 2D texture`);\r\n            }\r\n            if (targetSamples !== sourceSamples) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": targetTexture and sourceTexture must have matching sample counts`);\r\n            }\r\n\r\n            const targetSize = this._frameGraph.textureManager.getTextureDescription(this.targetTexture).size;\r\n            if (targetSize.width !== sourceSize.width || targetSize.height !== sourceSize.height) {\r\n                throw new Error(`FrameGraphMeshBlendingTask \"${this.name}\": targetTexture and sourceTexture must have matching dimensions`);\r\n            }\r\n        }\r\n\r\n        this.postProcess.camera = this.camera;\r\n        this.postProcess.hasBaseColorTexture = this.baseColorTexture !== undefined;\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                context.setTextureSamplingMode(this.meshBlendTagTexture, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n                context.setTextureSamplingMode(this.depthTexture, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n                if (this.baseColorTexture !== undefined) {\r\n                    context.setTextureSamplingMode(this.baseColorTexture, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n                }\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"meshBlendTagSampler\", this.meshBlendTagTexture);\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"meshBlendDepthSampler\", this.depthTexture);\r\n                if (this.baseColorTexture !== undefined) {\r\n                    context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"meshBlendBaseColorSampler\", this.baseColorTexture);\r\n                }\r\n            }\r\n        );\r\n\r\n        pass.addDependencies([this.meshBlendTagTexture, this.depthTexture]);\r\n        if (this.baseColorTexture !== undefined) {\r\n            pass.addDependencies(this.baseColorTexture);\r\n        }\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphMeshBlendingTask } from \"../../../Tasks/PostProcesses/meshBlendingTask\";\r\nimport { type FrameGraph } from \"../../../frameGraph\";\r\nimport { type FrameGraphTextureHandle } from \"../../../frameGraphTypes\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\nimport {\r\n    CreateDefaultMeshBlendRadiusDefinitions,\r\n    MeshBlendDebugMode,\r\n    MeshBlendDepthType,\r\n    MeshBlendQuality,\r\n    ThinMeshBlendingPostProcess,\r\n} from \"../../../../PostProcesses/thinMeshBlendingPostProcess\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type Camera } from \"../../../../Cameras/camera.pure\";\r\nimport { type NodeRenderGraphBuildState } from \"../../nodeRenderGraphBuildState\";\r\nimport { type NodeRenderGraphConnectionPoint } from \"../../nodeRenderGraphBlockConnectionPoint\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBasePostProcessBlock } from \"./basePostProcessBlock\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\n\r\n/**\r\n * Block that blends colors across seams between objects.\r\n */\r\nexport class NodeRenderGraphMeshBlendingPostProcessBlock extends NodeRenderGraphBasePostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphMeshBlendingTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block.\r\n     */\r\n    public override get task(): FrameGraphMeshBlendingTask {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    private _setRadiusValue(radiusClass: number, property: \"worldRadius\" | \"minimumProjectedRadius\", value: number): void {\r\n        const radiusClasses = this._frameGraphTask.postProcess.radiusClasses.map((definition) => ({ ...definition })) as [\r\n            { worldRadius: number; minimumProjectedRadius: number },\r\n            { worldRadius: number; minimumProjectedRadius: number },\r\n            { worldRadius: number; minimumProjectedRadius: number },\r\n            { worldRadius: number; minimumProjectedRadius: number },\r\n        ];\r\n        radiusClasses[radiusClass][property] = value;\r\n        this._frameGraphTask.configure({ radiusClasses });\r\n    }\r\n\r\n    /** Mesh blending always uses exact texel loads from SceneColor. */\r\n    public override get sourceSamplingMode(): number {\r\n        return Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n    }\r\n\r\n    public override set sourceSamplingMode(_value: number) {\r\n        if (this._frameGraphTask) {\r\n            this._frameGraphTask.sourceSamplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a mesh-blending post-process block.\r\n     * @param name The block name.\r\n     * @param frameGraph The hosting frame graph.\r\n     * @param scene The hosting scene.\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"geomDepth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"geomAlbedo\", NodeRenderGraphBlockConnectionPointTypes.TextureAlbedo, true);\r\n        this.registerInput(\"geomMeshBlendTag\", NodeRenderGraphBlockConnectionPointTypes.TextureMeshBlendTag);\r\n\r\n        this.geomDepth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth | NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth\r\n        );\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphMeshBlendingTask(this.name, frameGraph, new ThinMeshBlendingPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** Gets or sets the compile-time mesh-blending quality variant. */\r\n    @editableInPropertyPage(\"Quality\", PropertyTypeForEdition.List, \"MESH BLENDING\", {\r\n        options: [\r\n            { label: \"Low\", value: MeshBlendQuality.Low },\r\n            { label: \"Medium\", value: MeshBlendQuality.Medium },\r\n            { label: \"High\", value: MeshBlendQuality.High },\r\n            { label: \"Cinematic\", value: MeshBlendQuality.Cinematic },\r\n        ],\r\n    })\r\n    public get quality(): MeshBlendQuality {\r\n        return this._frameGraphTask.quality;\r\n    }\r\n\r\n    public set quality(value: MeshBlendQuality) {\r\n        this._frameGraphTask.quality = value;\r\n    }\r\n\r\n    /** Gets or sets the small-class authored world radius. */\r\n    @editableInPropertyPage(\"Small world radius\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get smallWorldRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[0].worldRadius;\r\n    }\r\n\r\n    public set smallWorldRadius(value: number) {\r\n        this._setRadiusValue(0, \"worldRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the small-class minimum projected radius in physical pixels. */\r\n    @editableInPropertyPage(\"Small minimum pixels\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get smallMinimumProjectedRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[0].minimumProjectedRadius;\r\n    }\r\n\r\n    public set smallMinimumProjectedRadius(value: number) {\r\n        this._setRadiusValue(0, \"minimumProjectedRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the medium-class authored world radius. */\r\n    @editableInPropertyPage(\"Medium world radius\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get mediumWorldRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[1].worldRadius;\r\n    }\r\n\r\n    public set mediumWorldRadius(value: number) {\r\n        this._setRadiusValue(1, \"worldRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the medium-class minimum projected radius in physical pixels. */\r\n    @editableInPropertyPage(\"Medium minimum pixels\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get mediumMinimumProjectedRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[1].minimumProjectedRadius;\r\n    }\r\n\r\n    public set mediumMinimumProjectedRadius(value: number) {\r\n        this._setRadiusValue(1, \"minimumProjectedRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the large-class authored world radius. */\r\n    @editableInPropertyPage(\"Large world radius\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get largeWorldRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[2].worldRadius;\r\n    }\r\n\r\n    public set largeWorldRadius(value: number) {\r\n        this._setRadiusValue(2, \"worldRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the large-class minimum projected radius in physical pixels. */\r\n    @editableInPropertyPage(\"Large minimum pixels\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get largeMinimumProjectedRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[2].minimumProjectedRadius;\r\n    }\r\n\r\n    public set largeMinimumProjectedRadius(value: number) {\r\n        this._setRadiusValue(2, \"minimumProjectedRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the extra-large-class authored world radius. */\r\n    @editableInPropertyPage(\"Extra large world radius\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get extraLargeWorldRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[3].worldRadius;\r\n    }\r\n\r\n    public set extraLargeWorldRadius(value: number) {\r\n        this._setRadiusValue(3, \"worldRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the extra-large-class minimum projected radius in physical pixels. */\r\n    @editableInPropertyPage(\"Extra large minimum pixels\", PropertyTypeForEdition.Float, \"RADIUS CLASSES\", { min: 0 })\r\n    public get extraLargeMinimumProjectedRadius(): number {\r\n        return this._frameGraphTask.postProcess.radiusClasses[3].minimumProjectedRadius;\r\n    }\r\n\r\n    public set extraLargeMinimumProjectedRadius(value: number) {\r\n        this._setRadiusValue(3, \"minimumProjectedRadius\", value);\r\n    }\r\n\r\n    /** Gets or sets the contact-slope narrowing factor. A value of 1 disables narrowing. */\r\n    @editableInPropertyPage(\"Slope factor\", PropertyTypeForEdition.Float, \"CONTACT VALIDATION\", { min: 1 })\r\n    public get slopeFactor(): number {\r\n        return this._frameGraphTask.postProcess.slopeFactor;\r\n    }\r\n\r\n    public set slopeFactor(value: number) {\r\n        this._frameGraphTask.postProcess.slopeFactor = value;\r\n    }\r\n\r\n    /** Gets or sets the compiled debug visualization. */\r\n    @editableInPropertyPage(\"Debug mode\", PropertyTypeForEdition.List, \"DEBUG\", {\r\n        options: [\r\n            { label: \"Off\", value: MeshBlendDebugMode.Off },\r\n            { label: \"Packed tag\", value: MeshBlendDebugMode.PackedTag },\r\n            { label: \"Candidate direction / distance\", value: MeshBlendDebugMode.CandidateDirectionDistance },\r\n            { label: \"Seam / fade\", value: MeshBlendDebugMode.SeamFade },\r\n            { label: \"Rejection reason\", value: MeshBlendDebugMode.RejectionReason },\r\n            { label: \"Approximate stage / work\", value: MeshBlendDebugMode.StageWork },\r\n            { label: \"Target continuation\", value: MeshBlendDebugMode.Continuation },\r\n            { label: \"Tiny-object radius\", value: MeshBlendDebugMode.TinyObject },\r\n            { label: \"Multi-target selection\", value: MeshBlendDebugMode.MultiTarget },\r\n            { label: \"Target-color samples\", value: MeshBlendDebugMode.TargetColor },\r\n            { label: \"Shadow attenuation\", value: MeshBlendDebugMode.ShadowAttenuation },\r\n            { label: \"Color interpolation\", value: MeshBlendDebugMode.ColorInterpolation },\r\n            { label: \"World position\", value: MeshBlendDebugMode.WorldPosition },\r\n        ],\r\n    })\r\n    public get debugMode(): MeshBlendDebugMode {\r\n        return this._frameGraphTask.debugMode;\r\n    }\r\n\r\n    public set debugMode(value: MeshBlendDebugMode) {\r\n        this._frameGraphTask.debugMode = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the camera used for world-radius projection and depth reconstruction.\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the view-depth or screen-depth input.\r\n     */\r\n    public get geomDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the optional linear geometry base-color/albedo input used for shadow estimation.\r\n     */\r\n    public get geomAlbedo(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the packed mesh-blending tag input.\r\n     */\r\n    public get geomMeshBlendTag(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"NodeRenderGraphMeshBlendingPostProcessBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState): void {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n        this._frameGraphTask.depthTexture = this.geomDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.depthType =\r\n            this.geomDepth.connectedPoint?.type === NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth ? MeshBlendDepthType.Screen : MeshBlendDepthType.View;\r\n        this._frameGraphTask.baseColorTexture = this.geomAlbedo.connectedPoint?.value as FrameGraphTextureHandle | undefined;\r\n        this._frameGraphTask.meshBlendTagTexture = this.geomMeshBlendTag.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode(): string {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.quality = ${this.quality};`);\r\n        codes.push(`${this._codeVariableName}.smallWorldRadius = ${this.smallWorldRadius};`);\r\n        codes.push(`${this._codeVariableName}.smallMinimumProjectedRadius = ${this.smallMinimumProjectedRadius};`);\r\n        codes.push(`${this._codeVariableName}.mediumWorldRadius = ${this.mediumWorldRadius};`);\r\n        codes.push(`${this._codeVariableName}.mediumMinimumProjectedRadius = ${this.mediumMinimumProjectedRadius};`);\r\n        codes.push(`${this._codeVariableName}.largeWorldRadius = ${this.largeWorldRadius};`);\r\n        codes.push(`${this._codeVariableName}.largeMinimumProjectedRadius = ${this.largeMinimumProjectedRadius};`);\r\n        codes.push(`${this._codeVariableName}.extraLargeWorldRadius = ${this.extraLargeWorldRadius};`);\r\n        codes.push(`${this._codeVariableName}.extraLargeMinimumProjectedRadius = ${this.extraLargeMinimumProjectedRadius};`);\r\n        codes.push(`${this._codeVariableName}.slopeFactor = ${this.slopeFactor};`);\r\n        codes.push(`${this._codeVariableName}.debugMode = ${this.debugMode};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.quality = this.quality;\r\n        serializationObject.radiusClasses = this._frameGraphTask.postProcess.radiusClasses.map((definition) => ({ ...definition }));\r\n        serializationObject.slopeFactor = this.slopeFactor;\r\n        serializationObject.debugMode = this.debugMode;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any): void {\r\n        super._deserialize(serializationObject);\r\n        const defaults = CreateDefaultMeshBlendRadiusDefinitions();\r\n        const radiusClasses = serializationObject.radiusClasses ?? defaults;\r\n        const resolvedRadiusClasses = [\r\n            {\r\n                worldRadius: radiusClasses[0]?.worldRadius ?? defaults[0].worldRadius,\r\n                minimumProjectedRadius: radiusClasses[0]?.minimumProjectedRadius ?? defaults[0].minimumProjectedRadius,\r\n            },\r\n            {\r\n                worldRadius: radiusClasses[1]?.worldRadius ?? defaults[1].worldRadius,\r\n                minimumProjectedRadius: radiusClasses[1]?.minimumProjectedRadius ?? defaults[1].minimumProjectedRadius,\r\n            },\r\n            {\r\n                worldRadius: radiusClasses[2]?.worldRadius ?? defaults[2].worldRadius,\r\n                minimumProjectedRadius: radiusClasses[2]?.minimumProjectedRadius ?? defaults[2].minimumProjectedRadius,\r\n            },\r\n            {\r\n                worldRadius: radiusClasses[3]?.worldRadius ?? defaults[3].worldRadius,\r\n                minimumProjectedRadius: radiusClasses[3]?.minimumProjectedRadius ?? defaults[3].minimumProjectedRadius,\r\n            },\r\n        ] as const;\r\n\r\n        this._frameGraphTask.configure({\r\n            quality: serializationObject.quality ?? MeshBlendQuality.Medium,\r\n            radiusClasses: resolvedRadiusClasses,\r\n            slopeFactor: serializationObject.slopeFactor ?? 2,\r\n            debugMode: serializationObject.debugMode ?? MeshBlendDebugMode.Off,\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n\r\n/**\r\n * Registers the mesh-blending post-process block.\r\n */\r\nexport function RegisterMeshBlendingPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphMeshBlendingPostProcessBlock\", NodeRenderGraphMeshBlendingPostProcessBlock);\r\n}\r\n","// eslint-disable-next-line import/no-internal-modules\r\nimport { type FrameGraph } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinPassCubePostProcess, ThinPassPostProcess } from \"core/PostProcesses/thinPassPostProcess\";\r\n\r\n/**\r\n * Task which applies a pass post process.\r\n */\r\nexport class FrameGraphPassTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinPassPostProcess;\r\n\r\n    /**\r\n     * Constructs a new pass task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the pass effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinPassPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinPassPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphPassTask\";\r\n    }\r\n}\r\n\r\n/**\r\n * Task which applies a pass cube post process.\r\n */\r\nexport class FrameGraphPassCubeTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinPassCubePostProcess;\r\n\r\n    /**\r\n     * Constructs a new pass cube task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the pass cube effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinPassCubePostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinPassCubePostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphPassCubeTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { FrameGraphPassCubeTask, FrameGraphPassTask } from \"core/FrameGraph/Tasks/PostProcesses/passTask\";\r\nimport { ThinPassCubePostProcess, ThinPassPostProcess } from \"core/PostProcesses/thinPassPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"././baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the pass post process\r\n */\r\nexport class NodeRenderGraphPassPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphPassTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphPassPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphPassTask(this.name, frameGraph, new ThinPassPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphPassPostProcessBlock\";\r\n    }\r\n}\r\n\r\n/**\r\n * Block that implements the pass cube post process\r\n */\r\nexport class NodeRenderGraphPassCubePostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphPassCubeTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphPassCubePostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphPassCubeTask(this.name, frameGraph, new ThinPassCubePostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphPassCubePostProcessBlock\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for passPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPassPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphPassPostProcessBlock\", NodeRenderGraphPassPostProcessBlock);\r\n    RegisterClass(\"BABYLON.NodeRenderGraphPassCubePostProcessBlock\", NodeRenderGraphPassCubePostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to apply a sharpen effect\r\n */\r\nexport class ThinSharpenPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"sharpen\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"sharpnessAmounts\", \"screenSize\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/sharpen.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/sharpen.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new sharpen post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSharpenPostProcess.FragmentUrl,\r\n            uniforms: ThinSharpenPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * How much of the original color should be applied. Setting this to 0 will display edge detection. (default: 1)\r\n     */\r\n    public colorAmount: number = 1.0;\r\n    /**\r\n     * How much sharpness should be applied (default: 0.3)\r\n     */\r\n    public edgeAmount: number = 0.3;\r\n\r\n    /**\r\n     * The width of the source texture\r\n     */\r\n    public textureWidth: number = 0;\r\n\r\n    /**\r\n     * The height of the source texture\r\n     */\r\n    public textureHeight: number = 0;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat2(\"screenSize\", this.textureWidth, this.textureHeight);\r\n        effect.setFloat2(\"sharpnessAmounts\", this.edgeAmount, this.colorAmount);\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderContext, type FrameGraphRenderPass } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinSharpenPostProcess } from \"core/PostProcesses/thinSharpenPostProcess\";\r\n\r\n/**\r\n * Task which applies a sharpen post process.\r\n */\r\nexport class FrameGraphSharpenTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinSharpenPostProcess;\r\n\r\n    /**\r\n     * Constructs a new sharpen task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinSharpenPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinSharpenPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSharpenTask\";\r\n    }\r\n\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphSharpenTask } from \"core/FrameGraph/Tasks/PostProcesses/sharpenTask\";\r\nimport { ThinSharpenPostProcess } from \"core/PostProcesses/thinSharpenPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the sharpen post process\r\n */\r\nexport class NodeRenderGraphSharpenPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphSharpenTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new sharpen post process block\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphSharpenTask(this.name, frameGraph, new ThinSharpenPostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** How much of the original color should be applied. Setting this to 0 will display edge detection. */\r\n    @editableInPropertyPage(\"Color Amount\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 3 })\r\n    public get colorAmount(): number {\r\n        return this._frameGraphTask.postProcess.colorAmount;\r\n    }\r\n\r\n    public set colorAmount(value: number) {\r\n        this._frameGraphTask.postProcess.colorAmount = value;\r\n    }\r\n\r\n    /** How much sharpness should be applied. */\r\n    @editableInPropertyPage(\"Edge Amount\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 5 })\r\n    public get edgeAmount(): number {\r\n        return this._frameGraphTask.postProcess.edgeAmount;\r\n    }\r\n\r\n    public set edgeAmount(value: number) {\r\n        this._frameGraphTask.postProcess.edgeAmount = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphSharpenPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.colorAmount = ${this.colorAmount};`);\r\n        codes.push(`${this._codeVariableName}.edgeAmount = ${this.edgeAmount};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.colorAmount = this.colorAmount;\r\n        serializationObject.edgeAmount = this.edgeAmount;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.colorAmount = serializationObject.colorAmount;\r\n        this.edgeAmount = serializationObject.edgeAmount;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sharpenPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSharpenPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphSharpenPostProcessBlock\", NodeRenderGraphSharpenPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * Post process used to apply a screen space curvature post process\r\n */\r\nexport class ThinScreenSpaceCurvaturePostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"screenSpaceCurvature\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"curvature_ridge\", \"curvature_valley\"];\r\n\r\n    /**\r\n     * The list of samplers used by the effect\r\n     */\r\n    public static readonly Samplers = [\"normalSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/screenSpaceCurvature.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/screenSpaceCurvature.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new screen space curvature post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinScreenSpaceCurvaturePostProcess.FragmentUrl,\r\n            uniforms: ThinScreenSpaceCurvaturePostProcess.Uniforms,\r\n            samplers: ThinScreenSpaceCurvaturePostProcess.Samplers,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Defines how much ridge the curvature effect displays.\r\n     */\r\n    public ridge: number = 1;\r\n\r\n    /**\r\n     * Defines how much valley the curvature effect displays.\r\n     */\r\n    public valley: number = 1;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat(\"curvature_ridge\", 0.5 / Math.max(this.ridge * this.ridge, 1e-4));\r\n        effect.setFloat(\"curvature_valley\", 0.7 / Math.max(this.valley * this.valley, 1e-4));\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type FrameGraphRenderPass } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinScreenSpaceCurvaturePostProcess } from \"core/PostProcesses/thinScreenSpaceCurvaturePostProcess\";\r\n\r\n/**\r\n * Task which applies a screen space curvature post process.\r\n */\r\nexport class FrameGraphScreenSpaceCurvatureTask extends FrameGraphPostProcessTask {\r\n    /**\r\n     * The normal texture to use for the screen space curvature effect.\r\n     * It must store normals in camera view space.\r\n     */\r\n    public normalTexture: FrameGraphTextureHandle;\r\n\r\n    public override readonly postProcess: ThinScreenSpaceCurvaturePostProcess;\r\n\r\n    /**\r\n     * Constructs a new circle of confusion task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinScreenSpaceCurvaturePostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinScreenSpaceCurvaturePostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphScreenSpaceCurvatureTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.normalTexture === undefined) {\r\n            throw new Error(`FrameGraphScreenSpaceCurvatureTask \"${this.name}\": sourceTexture and normalTexture are required`);\r\n        }\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {\r\n            context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"normalSampler\", this.normalTexture);\r\n        });\r\n\r\n        pass.addDependencies(this.normalTexture);\r\n\r\n        return pass;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphScreenSpaceCurvatureTask } from \"core/FrameGraph/Tasks/PostProcesses/screenSpaceCurvatureTask\";\r\nimport { ThinScreenSpaceCurvaturePostProcess } from \"core/PostProcesses/thinScreenSpaceCurvaturePostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the screen space curvature post process\r\n */\r\nexport class NodeRenderGraphScreenSpaceCurvaturePostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphScreenSpaceCurvatureTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphScreenSpaceCurvaturePostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"geomViewNormal\", NodeRenderGraphBlockConnectionPointTypes.TextureViewNormal);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphScreenSpaceCurvatureTask(this.name, frameGraph, new ThinScreenSpaceCurvaturePostProcess(name, scene.getEngine()));\r\n    }\r\n\r\n    /** Defines how much ridge the curvature effect displays. */\r\n    @editableInPropertyPage(\"Ridge\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get ridge(): number {\r\n        return this._frameGraphTask.postProcess.ridge;\r\n    }\r\n\r\n    public set ridge(value: number) {\r\n        this._frameGraphTask.postProcess.ridge = value;\r\n    }\r\n\r\n    /** Defines how much valley the curvature effect displays. */\r\n    @editableInPropertyPage(\"Valley\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get valley(): number {\r\n        return this._frameGraphTask.postProcess.valley;\r\n    }\r\n\r\n    public set valley(value: number) {\r\n        this._frameGraphTask.postProcess.valley = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphScreenSpaceCurvaturePostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry view normal input component\r\n     */\r\n    public get geomViewNormal(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.normalTexture = this.geomViewNormal.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.ridge = ${this.ridge};`);\r\n        codes.push(`${this._codeVariableName}.valley = ${this.valley};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.ridge = this.ridge;\r\n        serializationObject.valley = this.valley;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.ridge = serializationObject.ridge;\r\n        this.valley = serializationObject.valley;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for screenSpaceCurvaturePostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScreenSpaceCurvaturePostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphScreenSpaceCurvaturePostProcessBlock\", NodeRenderGraphScreenSpaceCurvaturePostProcessBlock);\r\n}\r\n","import { type Nullable, type Scene, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Matrix, Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Camera } from \"core/Cameras/camera.pure\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinSSAO2PostProcess extends EffectWrapper {\r\n    private static readonly ORTHO_DEPTH_PROJECTION = [1, 0, 0, 0, 1, 0, 0, 0, 1];\r\n\r\n    private static readonly PERSPECTIVE_DEPTH_PROJECTION = [0, 0, 0, 0, 0, 0, 1, 1, 1];\r\n\r\n    public static readonly FragmentUrl = \"ssao2\";\r\n\r\n    public static readonly Uniforms = [\r\n        \"sampleSphere\",\r\n        \"samplesFactor\",\r\n        \"randTextureTiles\",\r\n        \"totalStrength\",\r\n        \"radius\",\r\n        \"base\",\r\n        \"range\",\r\n        \"projection\",\r\n        \"near\",\r\n        \"texelSize\",\r\n        \"xViewport\",\r\n        \"yViewport\",\r\n        \"viewport\",\r\n        \"maxZ\",\r\n        \"minZAspect\",\r\n        \"depthProjection\",\r\n        \"normalWorldToView\",\r\n    ];\r\n\r\n    public static readonly Samplers = [\"randomSampler\", \"depthSampler\", \"normalSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/ssao2.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/ssao2.fragment\"));\r\n        }\r\n    }\r\n\r\n    public camera: Nullable<Camera> = null;\r\n\r\n    private _textureWidth = 0;\r\n\r\n    public get textureWidth() {\r\n        return this._textureWidth;\r\n    }\r\n\r\n    public set textureWidth(width: number) {\r\n        if (this._textureWidth === width) {\r\n            return;\r\n        }\r\n        this._textureWidth = width;\r\n    }\r\n\r\n    private _textureHeight = 0;\r\n\r\n    public get textureHeight() {\r\n        return this._textureHeight;\r\n    }\r\n\r\n    public set textureHeight(height: number) {\r\n        if (this._textureHeight === height) {\r\n            return;\r\n        }\r\n        this._textureHeight = height;\r\n    }\r\n\r\n    private _samples: number = 8;\r\n\r\n    public set samples(n: number) {\r\n        this._samples = n;\r\n        this.updateEffect();\r\n        this._sampleSphere = this._generateHemisphere();\r\n    }\r\n    public get samples(): number {\r\n        return this._samples;\r\n    }\r\n\r\n    public totalStrength: number = 1.0;\r\n\r\n    public radius: number = 2.0;\r\n\r\n    public maxZ: number = 100.0;\r\n\r\n    public minZAspect: number = 0.2;\r\n\r\n    public base: number = 0;\r\n\r\n    private _epsilon: number = 0.02;\r\n\r\n    private _normalsInWorldSpace = false;\r\n\r\n    public set normalsInWorldSpace(value: boolean) {\r\n        if (this._normalsInWorldSpace === value) {\r\n            return;\r\n        }\r\n        this._normalsInWorldSpace = value;\r\n        this.updateEffect();\r\n    }\r\n\r\n    public get normalsInWorldSpace(): boolean {\r\n        return this._normalsInWorldSpace;\r\n    }\r\n\r\n    public set epsilon(n: number) {\r\n        this._epsilon = n;\r\n        this.updateEffect();\r\n    }\r\n    public get epsilon(): number {\r\n        return this._epsilon;\r\n    }\r\n\r\n    public override updateEffect() {\r\n        super.updateEffect(this._getDefinesForSSAO());\r\n    }\r\n\r\n    private _scene: Scene;\r\n    private _randomTexture: Texture;\r\n    private _sampleSphere: number[];\r\n    private readonly _normalWorldToViewMatrix = new Matrix();\r\n    private readonly _normalWorldToView = new Float32Array(9);\r\n\r\n    constructor(name: string, scene: Scene, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: scene.getEngine(),\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSSAO2PostProcess.FragmentUrl,\r\n            uniforms: ThinSSAO2PostProcess.Uniforms,\r\n            samplers: ThinSSAO2PostProcess.Samplers,\r\n            defines: `#define SSAO\\n#define SAMPLES 8\\n#define EPSILON 0.0001`,\r\n            shaderLanguage: scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n\r\n        this._scene = scene;\r\n\r\n        this._createRandomTexture();\r\n\r\n        this.updateEffect();\r\n        this._sampleSphere = this._generateHemisphere();\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        const camera = this.camera;\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        const projectionMatrix = camera.getProjectionMatrix();\r\n\r\n        effect.setArray3(\"sampleSphere\", this._sampleSphere);\r\n        effect.setFloat(\"randTextureTiles\", 32.0);\r\n        effect.setFloat(\"samplesFactor\", 1 / this.samples);\r\n        effect.setFloat(\"totalStrength\", this.totalStrength);\r\n        effect.setFloat2(\"texelSize\", 1 / this.textureWidth, 1 / this.textureHeight);\r\n        effect.setFloat(\"radius\", this.radius);\r\n        effect.setFloat(\"maxZ\", this.maxZ);\r\n        effect.setFloat(\"minZAspect\", this.minZAspect);\r\n        effect.setFloat(\"base\", this.base);\r\n        effect.setFloat(\"near\", camera.minZ);\r\n        if (camera.mode === Camera.PERSPECTIVE_CAMERA) {\r\n            effect.setMatrix3x3(\"depthProjection\", ThinSSAO2PostProcess.PERSPECTIVE_DEPTH_PROJECTION);\r\n            const viewportSize = Math.tan(camera.fov / 2);\r\n            if (camera.fovMode === Camera.FOVMODE_VERTICAL_FIXED) {\r\n                effect.setFloat(\"xViewport\", viewportSize * this._scene.getEngine().getAspectRatio(camera, true));\r\n                effect.setFloat(\"yViewport\", viewportSize);\r\n            } else {\r\n                effect.setFloat(\"xViewport\", viewportSize);\r\n                effect.setFloat(\"yViewport\", viewportSize / this._scene.getEngine().getAspectRatio(camera, true));\r\n            }\r\n        } else {\r\n            const halfWidth = this._scene.getEngine().getRenderWidth() / 2.0;\r\n            const halfHeight = this._scene.getEngine().getRenderHeight() / 2.0;\r\n            const orthoLeft = camera.orthoLeft ?? -halfWidth;\r\n            const orthoRight = camera.orthoRight ?? halfWidth;\r\n            const orthoBottom = camera.orthoBottom ?? -halfHeight;\r\n            const orthoTop = camera.orthoTop ?? halfHeight;\r\n            effect.setMatrix3x3(\"depthProjection\", ThinSSAO2PostProcess.ORTHO_DEPTH_PROJECTION);\r\n            effect.setFloat4(\"viewport\", orthoLeft, orthoRight, orthoBottom, orthoTop);\r\n        }\r\n        effect.setMatrix(\"projection\", projectionMatrix);\r\n        if (this._normalsInWorldSpace) {\r\n            camera.getViewMatrix().toNormalMatrix(this._normalWorldToViewMatrix);\r\n            const viewMatrix = this._normalWorldToViewMatrix.m;\r\n            const normalWorldToView = this._normalWorldToView;\r\n            normalWorldToView[0] = viewMatrix[0];\r\n            normalWorldToView[1] = viewMatrix[1];\r\n            normalWorldToView[2] = viewMatrix[2];\r\n            normalWorldToView[3] = viewMatrix[4];\r\n            normalWorldToView[4] = viewMatrix[5];\r\n            normalWorldToView[5] = viewMatrix[6];\r\n            normalWorldToView[6] = viewMatrix[8];\r\n            normalWorldToView[7] = viewMatrix[9];\r\n            normalWorldToView[8] = viewMatrix[10];\r\n            effect.setMatrix3x3(\"normalWorldToView\", normalWorldToView);\r\n        }\r\n\r\n        effect.setTexture(\"randomSampler\", this._randomTexture);\r\n    }\r\n\r\n    public override dispose() {\r\n        this._randomTexture.dispose();\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    private _createRandomTexture(): void {\r\n        const size = 128;\r\n\r\n        const data = new Uint8Array(size * size * 4);\r\n        const randVector = Vector2.Zero();\r\n        for (let index = 0; index < data.length;) {\r\n            randVector.set(RandomRange(0, 1), RandomRange(0, 1)).normalize().scaleInPlace(255);\r\n            data[index++] = Math.floor(randVector.x);\r\n            data[index++] = Math.floor(randVector.y);\r\n            data[index++] = 0;\r\n            data[index++] = 255;\r\n        }\r\n\r\n        const texture = RawTexture.CreateRGBATexture(data, size, size, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n        texture.name = \"SSAORandomTexture\";\r\n        texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n        texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n        this._randomTexture = texture;\r\n    }\r\n\r\n    private _bits = new Uint32Array(1);\r\n\r\n    //Van der Corput radical inverse\r\n    private _radicalInverseVdC(i: number) {\r\n        this._bits[0] = i;\r\n        this._bits[0] = ((this._bits[0] << 16) | (this._bits[0] >> 16)) >>> 0;\r\n        this._bits[0] = ((this._bits[0] & 0x55555555) << 1) | (((this._bits[0] & 0xaaaaaaaa) >>> 1) >>> 0);\r\n        this._bits[0] = ((this._bits[0] & 0x33333333) << 2) | (((this._bits[0] & 0xcccccccc) >>> 2) >>> 0);\r\n        this._bits[0] = ((this._bits[0] & 0x0f0f0f0f) << 4) | (((this._bits[0] & 0xf0f0f0f0) >>> 4) >>> 0);\r\n        this._bits[0] = ((this._bits[0] & 0x00ff00ff) << 8) | (((this._bits[0] & 0xff00ff00) >>> 8) >>> 0);\r\n        return this._bits[0] * 2.3283064365386963e-10; // / 0x100000000 or / 4294967296\r\n    }\r\n\r\n    private _hammersley(i: number, n: number) {\r\n        return [i / n, this._radicalInverseVdC(i)];\r\n    }\r\n\r\n    private _hemisphereSampleUniform(u: number, v: number): Vector3 {\r\n        const phi = v * 2.0 * Math.PI;\r\n        // rejecting samples that are close to tangent plane to avoid z-fighting artifacts\r\n        const cosTheta = 1.0 - u * 0.85;\r\n        const sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta);\r\n        return new Vector3(Math.cos(phi) * sinTheta, Math.sin(phi) * sinTheta, cosTheta);\r\n    }\r\n\r\n    private _generateHemisphere(): number[] {\r\n        const numSamples = this.samples;\r\n        const result = [];\r\n        let vector;\r\n\r\n        let i = 0;\r\n        while (i < numSamples) {\r\n            if (numSamples < 16) {\r\n                vector = this._hemisphereSampleUniform(Math.random(), Math.random());\r\n            } else {\r\n                const rand = this._hammersley(i, numSamples);\r\n                vector = this._hemisphereSampleUniform(rand[0], rand[1]);\r\n            }\r\n\r\n            result.push(vector.x, vector.y, vector.z);\r\n            i++;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    private _getDefinesForSSAO() {\r\n        const epsilon = this._epsilon ?? 0.02;\r\n        const samples = this._samples ?? 8;\r\n\r\n        let defines = `#define SSAO\\n#define SAMPLES ${samples}\\n#define EPSILON ${epsilon.toFixed(4)}`;\r\n\r\n        if (this.camera?.mode === Camera.ORTHOGRAPHIC_CAMERA) {\r\n            defines += `\\n#define ORTHOGRAPHIC_CAMERA`;\r\n        }\r\n        if (this._normalsInWorldSpace) {\r\n            defines += `\\n#define NORMAL_WORLDSPACE`;\r\n        }\r\n\r\n        return defines;\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinSSAO2BlurPostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"ssao2\";\r\n\r\n    public static readonly Uniforms = [\"outSize\", \"samples\", \"soften\", \"tolerance\"];\r\n\r\n    public static readonly Samplers = [\"textureSampler\", \"depthSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/ssao2.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/ssao2.fragment\"));\r\n        }\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, isHorizontal: boolean, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSSAO2BlurPostProcess.FragmentUrl,\r\n            uniforms: ThinSSAO2BlurPostProcess.Uniforms,\r\n            samplers: ThinSSAO2BlurPostProcess.Samplers,\r\n            defines: \"#define BLUR\\n\" + (isHorizontal ? \"#define BLUR_H\\n\" : \"\"),\r\n        });\r\n\r\n        this._isHorizontal = isHorizontal;\r\n\r\n        const defines = this._getDefinesForBlur(this.expensiveBlur, this.bypassBlur);\r\n        const samplers = this._getSamplersForBlur(this.bypassBlur);\r\n\r\n        this.updateEffect(defines, null, samplers);\r\n    }\r\n\r\n    private readonly _isHorizontal: boolean;\r\n    private _bypassBlur: boolean = false;\r\n\r\n    public textureSize: number = 0;\r\n\r\n    public bilateralSamples: number = 16;\r\n\r\n    public bilateralSoften: number = 0;\r\n\r\n    public bilateralTolerance: number = 0;\r\n\r\n    public set bypassBlur(b: boolean) {\r\n        const defines = this._getDefinesForBlur(this.expensiveBlur, b);\r\n        const samplers = this._getSamplersForBlur(b);\r\n\r\n        this.updateEffect(defines, null, samplers);\r\n\r\n        this._bypassBlur = b;\r\n    }\r\n    public get bypassBlur(): boolean {\r\n        return this._bypassBlur;\r\n    }\r\n\r\n    private _expensiveBlur: boolean = true;\r\n\r\n    public set expensiveBlur(b: boolean) {\r\n        const defines = this._getDefinesForBlur(b, this._bypassBlur);\r\n\r\n        this.updateEffect(defines);\r\n\r\n        this._expensiveBlur = b;\r\n    }\r\n    public get expensiveBlur(): boolean {\r\n        return this._expensiveBlur;\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat(\"outSize\", this.textureSize);\r\n        effect.setInt(\"samples\", this.bilateralSamples);\r\n        effect.setFloat(\"soften\", this.bilateralSoften);\r\n        effect.setFloat(\"tolerance\", this.bilateralTolerance);\r\n    }\r\n\r\n    private _getSamplersForBlur(disabled: boolean): Array<string> {\r\n        return disabled ? [\"textureSampler\"] : [\"textureSampler\", \"depthSampler\"];\r\n    }\r\n\r\n    private _getDefinesForBlur(bilateral: boolean, disabled: boolean): string {\r\n        let define = \"#define BLUR\\n\";\r\n        if (disabled) {\r\n            define += \"#define BLUR_BYPASS\\n\";\r\n        }\r\n        if (!bilateral) {\r\n            define += \"#define BLUR_LEGACY\\n\";\r\n        }\r\n        return this._isHorizontal ? define + \"#define BLUR_H\\n\" : define;\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions, type Camera } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { TmpVectors } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinSSAO2CombinePostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"ssaoCombine\";\r\n\r\n    public static readonly Uniforms = [\"viewport\"];\r\n\r\n    public static readonly Samplers = [\"originalColor\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/ssaoCombine.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/ssaoCombine.fragment\"));\r\n        }\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSSAO2CombinePostProcess.FragmentUrl,\r\n            uniforms: ThinSSAO2CombinePostProcess.Uniforms,\r\n            samplers: ThinSSAO2CombinePostProcess.Samplers,\r\n        });\r\n    }\r\n\r\n    public camera: Nullable<Camera> = null;\r\n\r\n    public useViewportInCombineStage = true;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        if (this.camera) {\r\n            const viewport = this.camera.viewport;\r\n            if (this.useViewportInCombineStage) {\r\n                effect.setVector4(\"viewport\", TmpVectors.Vector4[0].copyFromFloats(viewport.x, viewport.y, viewport.width, viewport.height));\r\n            } else {\r\n                effect.setVector4(\"viewport\", TmpVectors.Vector4[0].copyFromFloats(0, 0, 1, 1));\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type Camera, type Nullable, type Scene } from \"core/index\";\r\nimport { ThinSSAO2PostProcess } from \"core/PostProcesses/thinSSAO2PostProcess\";\r\nimport { ThinSSAO2BlurPostProcess } from \"core/PostProcesses/thinSSAO2BlurPostProcess\";\r\nimport { ThinSSAO2CombinePostProcess } from \"core/PostProcesses/thinSSAO2CombinePostProcess\";\r\n\r\n/**\r\n * The SSAO2 rendering pipeline is used to generate ambient occlusion effects.\r\n */\r\nexport class ThinSSAO2RenderingPipeline {\r\n    /** @internal */\r\n    public readonly _ssaoPostProcess: ThinSSAO2PostProcess;\r\n    /** @internal */\r\n    public readonly _ssaoBlurXPostProcess: ThinSSAO2BlurPostProcess;\r\n    /** @internal */\r\n    public readonly _ssaoBlurYPostProcess: ThinSSAO2BlurPostProcess;\r\n    /** @internal */\r\n    public readonly _ssaoCombinePostProcess: ThinSSAO2CombinePostProcess;\r\n\r\n    /**\r\n     * Gets or sets the name of the rendering pipeline\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * The camera to which the rendering pipeline will be applied.\r\n     */\r\n    public get camera() {\r\n        return this._ssaoPostProcess.camera;\r\n    }\r\n\r\n    public set camera(camera: Nullable<Camera>) {\r\n        this._ssaoPostProcess.camera = camera;\r\n        this._ssaoCombinePostProcess.camera = camera;\r\n    }\r\n\r\n    /**\r\n     * Number of samples used for the SSAO calculations. Default value is 8.\r\n     */\r\n    public set samples(n: number) {\r\n        this._ssaoPostProcess.samples = n;\r\n    }\r\n    public get samples(): number {\r\n        return this._ssaoPostProcess.samples;\r\n    }\r\n\r\n    /**\r\n     * The output strength of the SSAO post-process. Default value is 1.0.\r\n     */\r\n    public get totalStrength() {\r\n        return this._ssaoPostProcess.totalStrength;\r\n    }\r\n\r\n    public set totalStrength(value: number) {\r\n        this._ssaoPostProcess.totalStrength = value;\r\n    }\r\n\r\n    /**\r\n     * The radius around the analyzed pixel used by the SSAO post-process. Default value is 2.0\r\n     */\r\n    public get radius() {\r\n        return this._ssaoPostProcess.radius;\r\n    }\r\n\r\n    public set radius(value: number) {\r\n        this._ssaoPostProcess.radius = value;\r\n    }\r\n\r\n    /**\r\n     * Maximum depth value to still render AO. A smooth falloff makes the dimming more natural, so there will be no abrupt shading change.\r\n     */\r\n    public get maxZ() {\r\n        return this._ssaoPostProcess.maxZ;\r\n    }\r\n\r\n    public set maxZ(value: number) {\r\n        this._ssaoPostProcess.maxZ = value;\r\n    }\r\n\r\n    /**\r\n     * In order to save performances, SSAO radius is clamped on close geometry. This ratio changes by how much.\r\n     */\r\n    public get minZAspect() {\r\n        return this._ssaoPostProcess.minZAspect;\r\n    }\r\n\r\n    public set minZAspect(value: number) {\r\n        this._ssaoPostProcess.minZAspect = value;\r\n    }\r\n\r\n    /**\r\n     * The base color of the SSAO post-process\r\n     * The final result is \"base + ssao\" between [0, 1]\r\n     */\r\n    public get base() {\r\n        return this._ssaoPostProcess.base;\r\n    }\r\n\r\n    public set base(value: number) {\r\n        this._ssaoPostProcess.base = value;\r\n    }\r\n\r\n    /**\r\n     * Used in SSAO calculations to compensate for accuracy issues with depth values. Default 0.02.\r\n     *\r\n     * Normally you do not need to change this value, but you can experiment with it if you get a lot of in false self-occlusion on flat surfaces when using fewer than 16 samples. Useful range is normally [0..0.1] but higher values is allowed.\r\n     */\r\n    public get epsilon(): number {\r\n        return this._ssaoPostProcess.epsilon;\r\n    }\r\n\r\n    public set epsilon(n: number) {\r\n        this._ssaoPostProcess.epsilon = n;\r\n    }\r\n\r\n    /**\r\n     * Skips the denoising (blur) stage of the SSAO calculations.\r\n     *\r\n     * Useful to temporarily set while experimenting with the other SSAO2 settings.\r\n     */\r\n    public set bypassBlur(b: boolean) {\r\n        this._ssaoBlurXPostProcess.bypassBlur = b;\r\n        this._ssaoBlurYPostProcess.bypassBlur = b;\r\n    }\r\n\r\n    public get bypassBlur(): boolean {\r\n        return this._ssaoBlurXPostProcess.bypassBlur;\r\n    }\r\n\r\n    /**\r\n     * Enables the configurable bilateral denoising (blurring) filter. Default is true.\r\n     * Set to false to instead use a legacy bilateral filter that can't be configured.\r\n     *\r\n     * The denoising filter runs after the SSAO calculations and is a very important step. Both options results in a so called bilateral being used, but the \"expensive\" one can be\r\n     * configured in several ways to fit your scene.\r\n     */\r\n    public set expensiveBlur(b: boolean) {\r\n        this._ssaoBlurXPostProcess.expensiveBlur = b;\r\n        this._ssaoBlurYPostProcess.expensiveBlur = b;\r\n    }\r\n\r\n    public get expensiveBlur(): boolean {\r\n        return this._ssaoBlurXPostProcess.expensiveBlur;\r\n    }\r\n\r\n    /**\r\n     * The number of samples the bilateral filter uses in both dimensions when denoising the SSAO calculations. Default value is 16.\r\n     *\r\n     * A higher value should result in smoother shadows but will use more processing time in the shaders.\r\n     *\r\n     * A high value can cause the shadows to get to blurry or create visible artifacts (bands) near sharp details in the geometry. The artifacts can sometimes be mitigated by increasing the bilateralSoften setting.\r\n     */\r\n    public get bilateralSamples() {\r\n        return this._ssaoBlurXPostProcess.bilateralSamples;\r\n    }\r\n\r\n    public set bilateralSamples(n: number) {\r\n        this._ssaoBlurXPostProcess.bilateralSamples = n;\r\n        this._ssaoBlurYPostProcess.bilateralSamples = n;\r\n    }\r\n\r\n    /**\r\n     * Controls the shape of the denoising kernel used by the bilateral filter. Default value is 0.\r\n     *\r\n     * By default the bilateral filter acts like a box-filter, treating all samples on the same depth with equal weights. This is effective to maximize the denoising effect given a limited set of samples. However, it also often results in visible ghosting around sharp shadow regions and can spread out lines over large areas so they are no longer visible.\r\n     *\r\n     * Increasing this setting will make the filter pay less attention to samples further away from the center sample, reducing many artifacts but at the same time increasing noise.\r\n     *\r\n     * Useful value range is [0..1].\r\n     */\r\n    public get bilateralSoften() {\r\n        return this._ssaoBlurXPostProcess.bilateralSoften;\r\n    }\r\n\r\n    public set bilateralSoften(n: number) {\r\n        this._ssaoBlurXPostProcess.bilateralSoften = n;\r\n        this._ssaoBlurYPostProcess.bilateralSoften = n;\r\n    }\r\n\r\n    /**\r\n     * How forgiving the bilateral denoiser should be when rejecting samples. Default value is 0.\r\n     *\r\n     * A higher value results in the bilateral filter being more forgiving and thus doing a better job at denoising slanted and curved surfaces, but can lead to shadows spreading out around corners or between objects that are close to each other depth wise.\r\n     *\r\n     * Useful value range is normally [0..1], but higher values are allowed.\r\n     */\r\n    public get bilateralTolerance() {\r\n        return this._ssaoBlurXPostProcess.bilateralTolerance;\r\n    }\r\n\r\n    public set bilateralTolerance(n: number) {\r\n        this._ssaoBlurXPostProcess.bilateralTolerance = n;\r\n        this._ssaoBlurYPostProcess.bilateralTolerance = n;\r\n    }\r\n\r\n    /**\r\n     * Indicates that the combine stage should use the current camera viewport to render the SSAO result on only a portion of the output texture (default: true).\r\n     */\r\n    public get useViewportInCombineStage() {\r\n        return this._ssaoCombinePostProcess.useViewportInCombineStage;\r\n    }\r\n\r\n    public set useViewportInCombineStage(b: boolean) {\r\n        this._ssaoCombinePostProcess.useViewportInCombineStage = b;\r\n    }\r\n\r\n    /**\r\n     * Checks if all the post processes in the pipeline are ready.\r\n     * @returns true if all the post processes in the pipeline are ready\r\n     */\r\n    public isReady(): boolean {\r\n        return this._ssaoPostProcess.isReady() && this._ssaoBlurXPostProcess.isReady() && this._ssaoBlurYPostProcess.isReady() && this._ssaoCombinePostProcess.isReady();\r\n    }\r\n\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Constructor of the SSR rendering pipeline\r\n     * @param name The rendering pipeline name\r\n     * @param scene The scene linked to this pipeline\r\n     */\r\n    constructor(name: string, scene: Scene) {\r\n        this.name = name;\r\n        this._scene = scene;\r\n\r\n        this._ssaoPostProcess = new ThinSSAO2PostProcess(this.name, this._scene);\r\n        this._ssaoBlurXPostProcess = new ThinSSAO2BlurPostProcess(this.name + \" BlurX\", this._scene.getEngine(), true);\r\n        this._ssaoBlurYPostProcess = new ThinSSAO2BlurPostProcess(this.name + \" BlurY\", this._scene.getEngine(), false);\r\n        this._ssaoCombinePostProcess = new ThinSSAO2CombinePostProcess(this.name + \" Combiner\", this._scene.getEngine());\r\n    }\r\n\r\n    /**\r\n     * Disposes of the pipeline\r\n     */\r\n    public dispose(): void {\r\n        this._ssaoPostProcess?.dispose();\r\n        this._ssaoBlurXPostProcess?.dispose();\r\n        this._ssaoBlurYPostProcess?.dispose();\r\n        this._ssaoCombinePostProcess?.dispose();\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderPass, type Camera, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinSSAO2PostProcess } from \"core/PostProcesses/thinSSAO2PostProcess\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphSSAO2Task extends FrameGraphPostProcessTask {\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    public normalTexture: FrameGraphTextureHandle;\r\n\r\n    public camera: Camera;\r\n\r\n    public override readonly postProcess: ThinSSAO2PostProcess;\r\n\r\n    private _currentCameraMode = -1;\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinSSAO2PostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinSSAO2PostProcess(name, frameGraph.scene));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSSAO2Task\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined || this.normalTexture === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphSSAO2Task \"${this.name}\": sourceTexture, depthTexture, normalTexture and camera are required`);\r\n        }\r\n\r\n        this._currentCameraMode = this.camera.mode;\r\n        this.postProcess.updateEffect();\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                this.postProcess.camera = this.camera;\r\n\r\n                if (this._currentCameraMode !== this.camera.mode) {\r\n                    this._currentCameraMode = this.camera.mode;\r\n                    this.postProcess.updateEffect();\r\n                }\r\n\r\n                context.setTextureSamplingMode(this.depthTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n                context.setTextureSamplingMode(this.normalTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"normalSampler\", this.normalTexture);\r\n            }\r\n        );\r\n\r\n        pass.addDependencies([this.depthTexture]);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderPass, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinSSAO2BlurPostProcess } from \"core/PostProcesses/thinSSAO2BlurPostProcess\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphSSAO2BlurTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinSSAO2BlurPostProcess;\r\n\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    constructor(\r\n        name: string,\r\n        frameGraph: FrameGraph,\r\n        private _isHorizontal: boolean,\r\n        thinPostProcess?: ThinSSAO2BlurPostProcess\r\n    ) {\r\n        super(name, frameGraph, thinPostProcess || new ThinSSAO2BlurPostProcess(name, frameGraph.engine, _isHorizontal));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSSAO2BlurTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined) {\r\n            throw new Error(`FrameGraphSSAO2BlurTask \"${this.name}\": sourceTexture and depthTexture are required`);\r\n        }\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                context.setTextureSamplingMode(this.depthTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n            }\r\n        );\r\n\r\n        this.postProcess.textureSize = this._isHorizontal ? this._outputWidth : this._outputHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type Camera, type FrameGraphTextureCreationOptions } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { ThinSSAO2RenderingPipeline } from \"core/PostProcesses/RenderPipeline/Pipelines/thinSSAO2RenderingPipeline\";\r\nimport { FrameGraphSSAO2Task } from \"./ssao2Task\";\r\nimport { FrameGraphSSAO2BlurTask } from \"./ssao2BlurTask\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a SSAO2 post process.\r\n */\r\nexport class FrameGraphSSAO2RenderingPipelineTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to apply the SSAO2 effect on.\r\n     */\r\n    public sourceTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the source texture.\r\n     */\r\n    public sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The alpha mode to use when applying the SSAO2 effect.\r\n     */\r\n    public get alphaMode() {\r\n        return this._ssaoCombine.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(mode: number) {\r\n        this._ssaoCombine.alphaMode = mode;\r\n    }\r\n\r\n    /**\r\n     * The depth texture used by the SSAO2 effect (Z coordinate in camera view space).\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The normal texture used by the SSAO2 effect (normal vector in camera view space).\r\n     */\r\n    public normalTexture: FrameGraphTextureHandle;\r\n\r\n    private _camera: Camera;\r\n\r\n    /**\r\n     * The camera used to render the scene.\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(camera: Camera) {\r\n        if (camera === this._camera) {\r\n            return;\r\n        }\r\n\r\n        this._camera = camera;\r\n\r\n        this.ssao.camera = camera;\r\n        if (this._ssao) {\r\n            this._ssao.camera = camera;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The target texture to render the SSAO2 effect to.\r\n     */\r\n    public targetTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture of the SSAO2 effect.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The SSAO2 Rendering pipeline.\r\n     */\r\n    public readonly ssao: ThinSSAO2RenderingPipeline;\r\n\r\n    /**\r\n     * The name of the task.\r\n     */\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this._ssao) {\r\n            this._ssao.name = `${name} SSAO2 main`;\r\n        }\r\n        if (this._ssaoBlurX) {\r\n            this._ssaoBlurX.name = `${name} SSAO2 Blur X`;\r\n        }\r\n        if (this._ssaoBlurY) {\r\n            this._ssaoBlurY.name = `${name} SSAO2 Blur Y`;\r\n        }\r\n        if (this._ssaoCombine) {\r\n            this._ssaoCombine.name = `${name} SSAO2 Combine`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The ratio between the SSAO texture size and the source texture size\r\n     */\r\n    public readonly ratioSSAO: number;\r\n\r\n    /**\r\n     * The ratio between the SSAO blur texture size and the source texture size\r\n     */\r\n    public readonly ratioBlur: number;\r\n\r\n    /**\r\n     * The texture type used by the different post processes created by SSAO2.\r\n     * It's a read-only property. If you want to change it, you must recreate the task and pass the appropriate texture type to the constructor.\r\n     */\r\n    public readonly textureType: number;\r\n\r\n    private readonly _ssao: FrameGraphSSAO2Task;\r\n    private readonly _ssaoBlurX: FrameGraphSSAO2BlurTask;\r\n    private readonly _ssaoBlurY: FrameGraphSSAO2BlurTask;\r\n    private readonly _ssaoCombine: FrameGraphPostProcessTask;\r\n\r\n    /**\r\n     * Constructs a SSAO2 rendering pipeline task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param ratioSSAO The ratio between the SSAO texture size and the source texture size\r\n     * @param ratioBlur The ratio between the SSAO blur texture size and the source texture size\r\n     * @param textureType The texture type used by the different post processes created by SSAO2 (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, ratioSSAO: number, ratioBlur: number, textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n        super(name, frameGraph);\r\n\r\n        this.ratioSSAO = ratioSSAO;\r\n        this.ratioBlur = ratioBlur;\r\n        this.textureType = textureType;\r\n\r\n        this.ssao = new ThinSSAO2RenderingPipeline(name, frameGraph.scene);\r\n\r\n        this._ssao = new FrameGraphSSAO2Task(`${name} SSAO2 main`, this._frameGraph, this.ssao._ssaoPostProcess);\r\n        this._ssaoBlurX = new FrameGraphSSAO2BlurTask(`${name} SSAO2 Blur X`, this._frameGraph, true, this.ssao._ssaoBlurXPostProcess);\r\n        this._ssaoBlurY = new FrameGraphSSAO2BlurTask(`${name} SSAO2 Blur Y`, this._frameGraph, false, this.ssao._ssaoBlurYPostProcess);\r\n        this._ssaoCombine = new FrameGraphPostProcessTask(`${name} SSAO2 Combine`, this._frameGraph, this.ssao._ssaoCombinePostProcess);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override isReady() {\r\n        return this.ssao.isReady();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSSAO2RenderingPipelineTask\";\r\n    }\r\n\r\n    public record(): void {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined || this.normalTexture === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphSSAO2RenderingPipelineTask \"${this.name}\": sourceTexture, depthTexture, normalTexture and camera are required`);\r\n        }\r\n\r\n        const sourceTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.sourceTexture);\r\n\r\n        this._ssao.sourceTexture = this.sourceTexture;\r\n        this._ssao.sourceSamplingMode = this.sourceSamplingMode;\r\n        this._ssao.camera = this.camera;\r\n        this._ssao.depthTexture = this.depthTexture;\r\n        this._ssao.normalTexture = this.normalTexture;\r\n\r\n        const textureSize = {\r\n            width: Math.floor(sourceTextureDescription.size.width * this.ratioSSAO) || 1,\r\n            height: Math.floor(sourceTextureDescription.size.height * this.ratioSSAO) || 1,\r\n        };\r\n        const textureCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: textureSize,\r\n            options: {\r\n                createMipMaps: false,\r\n                types: [this.textureType],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                samples: 1,\r\n                useSRGBBuffers: [false],\r\n                labels: [\"\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n        };\r\n\r\n        const ssaoTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._ssao.name, textureCreationOptions);\r\n\r\n        // SSAO main post process\r\n        this._ssao.targetTexture = ssaoTextureHandle;\r\n        this._ssao.record(true);\r\n\r\n        // SSAO Blur X & Y\r\n        textureSize.width = Math.floor(sourceTextureDescription.size.width * this.ratioBlur) || 1;\r\n        textureSize.height = Math.floor(sourceTextureDescription.size.height * this.ratioBlur) || 1;\r\n\r\n        const sourceTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.sourceTexture);\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture, this.name + \" Output\", sourceTextureCreationOptions);\r\n\r\n        const blurXTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._ssaoBlurX.name, textureCreationOptions);\r\n\r\n        this._ssaoBlurX.sourceTexture = ssaoTextureHandle!;\r\n        this._ssaoBlurX.depthTexture = this.depthTexture;\r\n        this._ssaoBlurX.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n        this._ssaoBlurX.targetTexture = blurXTextureHandle;\r\n        this._ssaoBlurX.record(true);\r\n\r\n        const blurYTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._ssaoBlurY.name, textureCreationOptions);\r\n\r\n        this._ssaoBlurY.sourceTexture = blurXTextureHandle;\r\n        this._ssaoBlurY.depthTexture = this.depthTexture;\r\n        this._ssaoBlurY.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n        this._ssaoBlurY.targetTexture = blurYTextureHandle;\r\n        this._ssaoBlurY.record(true);\r\n\r\n        // SSAO Combine\r\n        this._ssaoCombine.sourceTexture = this.sourceTexture;\r\n        this._ssaoCombine.sourceSamplingMode = this.sourceSamplingMode;\r\n        this._ssaoCombine.targetTexture = this.outputTexture;\r\n        const combinerPass = this._ssaoCombine.record(\r\n            true,\r\n            (context) => {\r\n                context.setTextureSamplingMode(this.sourceTexture, this.sourceSamplingMode);\r\n                context.setTextureSamplingMode(blurYTextureHandle, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._ssaoCombine.drawWrapper.effect!, \"textureSampler\", blurYTextureHandle);\r\n                context.bindTextureHandle(this._ssaoCombine.drawWrapper.effect!, \"originalColor\", this.sourceTexture);\r\n            }\r\n        );\r\n\r\n        combinerPass.addDependencies(blurYTextureHandle);\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.addDependencies(this.sourceTexture);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((context) => {\r\n            if (this.alphaMode === Constants.ALPHA_DISABLE) {\r\n                context.copyTexture(this.sourceTexture);\r\n            }\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this._ssao.dispose();\r\n        this._ssaoBlurX.dispose();\r\n        this._ssaoBlurY.dispose();\r\n        this._ssaoCombine.dispose();\r\n        this.ssao.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph, type NodeRenderGraphConnectionPoint, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type Camera } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphSSAO2RenderingPipelineTask } from \"../../../Tasks/PostProcesses/ssao2RenderingPipelineTask\";\r\nimport { NodeRenderGraphBasePostProcessBlock } from \"./basePostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the SSAO2 post process\r\n */\r\nexport class NodeRenderGraphSSAO2PostProcessBlock extends NodeRenderGraphBasePostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphSSAO2RenderingPipelineTask;\r\n\r\n    public override _additionalConstructionParameters: [number, number, number];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphSSAO2PostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param ratioSSAO The ratio between the SSAO texture size and the source texture size (default: 1)\r\n     * @param ratioBlur The ratio between the SSAO blur texture size and the source texture size (default: 1)\r\n     * @param textureType The texture type used by the different post processes created by SSAO2 (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, ratioSSAO = 1, ratioBlur = 1, textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [ratioSSAO, ratioBlur, textureType];\r\n\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"geomDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth);\r\n        this.registerInput(\"geomNormal\", NodeRenderGraphBlockConnectionPointTypes.TextureViewNormal);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphSSAO2RenderingPipelineTask(this.name, frameGraph, ratioSSAO, ratioBlur, textureType);\r\n    }\r\n\r\n    private _createTask(ratioSSAO: number, ratioBlur: number, textureType: number) {\r\n        const sourceSamplingMode = this.sourceSamplingMode;\r\n        const samples = this.samples;\r\n        const totalStrength = this.totalStrength;\r\n        const base = this.base;\r\n        const maxZ = this.maxZ;\r\n        const minZAspect = this.minZAspect;\r\n        const radius = this.radius;\r\n        const epsilon = this.epsilon;\r\n        const useViewportInCombineStage = this.useViewportInCombineStage;\r\n        const bypassBlur = this.bypassBlur;\r\n        const expensiveBlur = this.expensiveBlur;\r\n        const bilateralSoften = this.bilateralSoften;\r\n        const bilateralSamples = this.bilateralSamples;\r\n        const bilateralTolerance = this.bilateralTolerance;\r\n\r\n        this._frameGraphTask.dispose();\r\n        this._frameGraphTask = new FrameGraphSSAO2RenderingPipelineTask(this.name, this._frameGraph, ratioSSAO, ratioBlur, textureType);\r\n\r\n        this.sourceSamplingMode = sourceSamplingMode;\r\n        this.samples = samples;\r\n        this.totalStrength = totalStrength;\r\n        this.base = base;\r\n        this.maxZ = maxZ;\r\n        this.minZAspect = minZAspect;\r\n        this.radius = radius;\r\n        this.epsilon = epsilon;\r\n        this.useViewportInCombineStage = useViewportInCombineStage;\r\n        this.bypassBlur = bypassBlur;\r\n        this.expensiveBlur = expensiveBlur;\r\n        this.bilateralSoften = bilateralSoften;\r\n        this.bilateralSamples = bilateralSamples;\r\n        this.bilateralTolerance = bilateralTolerance;\r\n\r\n        this._additionalConstructionParameters = [ratioSSAO, ratioBlur, textureType];\r\n    }\r\n\r\n    /** The texture type used by the different post processes created by SSAO2 */\r\n    @editableInPropertyPage(\"Texture type\", PropertyTypeForEdition.TextureType, \"TEXTURE\")\r\n    public get textureType() {\r\n        return this._frameGraphTask.textureType;\r\n    }\r\n\r\n    public set textureType(value: number) {\r\n        this._createTask(this._frameGraphTask.ratioSSAO, this._frameGraphTask.ratioBlur, value);\r\n    }\r\n\r\n    /** The ratio between the SSAO texture size and the source texture size */\r\n    @editableInPropertyPage(\"SSAO texture ratio\", PropertyTypeForEdition.Float, \"TEXTURE\", { min: 0.1, max: 1 })\r\n    public get ratioSSAO() {\r\n        return this._frameGraphTask.ratioSSAO;\r\n    }\r\n\r\n    public set ratioSSAO(value: number) {\r\n        this._createTask(value, this._frameGraphTask.ratioBlur, this._frameGraphTask.textureType);\r\n    }\r\n\r\n    /** The ratio between the SSAO blur texture size and the source texture size */\r\n    @editableInPropertyPage(\"SSAO blur texture ratio\", PropertyTypeForEdition.Float, \"TEXTURE\", { min: 0.1, max: 1 })\r\n    public get ratioBlur() {\r\n        return this._frameGraphTask.ratioBlur;\r\n    }\r\n\r\n    public set ratioBlur(value: number) {\r\n        this._createTask(this._frameGraphTask.ratioSSAO, value, this._frameGraphTask.textureType);\r\n    }\r\n\r\n    /** Number of samples used for the SSAO calculations. Default value is 8. */\r\n    @editableInPropertyPage(\"Samples\", PropertyTypeForEdition.Int, \"SSAO\", { min: 1, max: 128 })\r\n    public get samples() {\r\n        return this._frameGraphTask.ssao.samples;\r\n    }\r\n\r\n    public set samples(value: number) {\r\n        this._frameGraphTask.ssao.samples = value;\r\n    }\r\n\r\n    /** The strength of the SSAO post-process. Default value is 1.0. */\r\n    @editableInPropertyPage(\"Strength\", PropertyTypeForEdition.Float, \"SSAO\", { min: 0, max: 3 })\r\n    public get totalStrength() {\r\n        return this._frameGraphTask.ssao.totalStrength;\r\n    }\r\n\r\n    public set totalStrength(value: number) {\r\n        this._frameGraphTask.ssao.totalStrength = value;\r\n    }\r\n\r\n    /** The base color of the SSAO post-process. The final result is \"base + ssao\" between [0, 1] */\r\n    @editableInPropertyPage(\"Base\", PropertyTypeForEdition.Float, \"SSAO\", { min: 0, max: 1 })\r\n    public get base() {\r\n        return this._frameGraphTask.ssao.base;\r\n    }\r\n\r\n    public set base(value: number) {\r\n        this._frameGraphTask.ssao.base = value;\r\n    }\r\n\r\n    /** Maximum depth value to still render AO. A smooth falloff makes the dimming more natural, so there will be no abrupt shading change. */\r\n    @editableInPropertyPage(\"Max Z\", PropertyTypeForEdition.Float, \"SSAO\", { min: 0, max: 10000 })\r\n    public get maxZ() {\r\n        return this._frameGraphTask.ssao.maxZ;\r\n    }\r\n\r\n    public set maxZ(value: number) {\r\n        this._frameGraphTask.ssao.maxZ = value;\r\n    }\r\n\r\n    /** In order to save performances, SSAO radius is clamped on close geometry. This ratio changes by how much. */\r\n    @editableInPropertyPage(\"Min Z aspect\", PropertyTypeForEdition.Float, \"SSAO\", { min: 0, max: 0.5 })\r\n    public get minZAspect() {\r\n        return this._frameGraphTask.ssao.minZAspect;\r\n    }\r\n\r\n    public set minZAspect(value: number) {\r\n        this._frameGraphTask.ssao.minZAspect = value;\r\n    }\r\n\r\n    /** The radius around the analyzed pixel used by the SSAO post-process. */\r\n    @editableInPropertyPage(\"Radius\", PropertyTypeForEdition.Float, \"SSAO\", { min: 0, max: 10 })\r\n    public get radius() {\r\n        return this._frameGraphTask.ssao.radius;\r\n    }\r\n\r\n    public set radius(value: number) {\r\n        this._frameGraphTask.ssao.radius = value;\r\n    }\r\n\r\n    /** Used in SSAO calculations to compensate for accuracy issues with depth values. */\r\n    @editableInPropertyPage(\"Epsilon\", PropertyTypeForEdition.Float, \"SSAO\", { min: 0, max: 1 })\r\n    public get epsilon() {\r\n        return this._frameGraphTask.ssao.epsilon;\r\n    }\r\n\r\n    public set epsilon(value: number) {\r\n        this._frameGraphTask.ssao.epsilon = value;\r\n    }\r\n\r\n    /** Indicates that the combine stage should use the current camera viewport to render the SSAO result on only a portion of the output texture. */\r\n    @editableInPropertyPage(\"Use viewport in combine stage\", PropertyTypeForEdition.Boolean, \"SSAO\")\r\n    public get useViewportInCombineStage() {\r\n        return this._frameGraphTask.ssao.useViewportInCombineStage;\r\n    }\r\n\r\n    public set useViewportInCombineStage(value: boolean) {\r\n        this._frameGraphTask.ssao.useViewportInCombineStage = value;\r\n    }\r\n\r\n    /** Skips the denoising (blur) stage of the SSAO calculations. */\r\n    @editableInPropertyPage(\"Bypass blur\", PropertyTypeForEdition.Boolean, \"Blur\")\r\n    public get bypassBlur() {\r\n        return this._frameGraphTask.ssao.bypassBlur;\r\n    }\r\n\r\n    public set bypassBlur(value: boolean) {\r\n        this._frameGraphTask.ssao.bypassBlur = value;\r\n    }\r\n\r\n    /** Enables the configurable bilateral denoising (blurring) filter. */\r\n    @editableInPropertyPage(\"Expensive blur\", PropertyTypeForEdition.Boolean, \"Blur\")\r\n    public get expensiveBlur() {\r\n        return this._frameGraphTask.ssao.expensiveBlur;\r\n    }\r\n\r\n    public set expensiveBlur(value: boolean) {\r\n        this._frameGraphTask.ssao.expensiveBlur = value;\r\n    }\r\n\r\n    /** The number of samples the bilateral filter uses in both dimensions when denoising the SSAO calculations. */\r\n    @editableInPropertyPage(\"Samples\", PropertyTypeForEdition.Int, \"Blur\", { min: 1, max: 128 })\r\n    public get bilateralSamples() {\r\n        return this._frameGraphTask.ssao.bilateralSamples;\r\n    }\r\n\r\n    public set bilateralSamples(value: number) {\r\n        this._frameGraphTask.ssao.bilateralSamples = value;\r\n    }\r\n\r\n    /** Controls the shape of the denoising kernel used by the bilateral filter. */\r\n    @editableInPropertyPage(\"Soften\", PropertyTypeForEdition.Float, \"Blur\", { min: 0, max: 1 })\r\n    public get bilateralSoften() {\r\n        return this._frameGraphTask.ssao.bilateralSoften;\r\n    }\r\n\r\n    public set bilateralSoften(value: number) {\r\n        this._frameGraphTask.ssao.bilateralSoften = value;\r\n    }\r\n\r\n    /** How forgiving the bilateral denoiser should be when rejecting samples. */\r\n    @editableInPropertyPage(\"Tolerance\", PropertyTypeForEdition.Float, \"Blur\", { min: 0, max: 1 })\r\n    public get bilateralTolerance() {\r\n        return this._frameGraphTask.ssao.bilateralTolerance;\r\n    }\r\n\r\n    public set bilateralTolerance(value: number) {\r\n        this._frameGraphTask.ssao.bilateralTolerance = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphSSAO2PostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry depth input component\r\n     */\r\n    public get geomDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry normal input component\r\n     */\r\n    public get geomNormal(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.normalTexture = this.geomNormal.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.depthTexture = this.geomDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.samples = ${this.samples};`);\r\n        codes.push(`${this._codeVariableName}.totalStrength = ${this.totalStrength};`);\r\n        codes.push(`${this._codeVariableName}.base = ${this.base};`);\r\n        codes.push(`${this._codeVariableName}.maxZ = ${this.maxZ};`);\r\n        codes.push(`${this._codeVariableName}.minZAspect = ${this.minZAspect};`);\r\n        codes.push(`${this._codeVariableName}.radius = ${this.radius};`);\r\n        codes.push(`${this._codeVariableName}.epsilon = ${this.epsilon};`);\r\n        codes.push(`${this._codeVariableName}.useViewportInCombineStage = ${this.useViewportInCombineStage};`);\r\n        codes.push(`${this._codeVariableName}.bypassBlur = ${this.bypassBlur};`);\r\n        codes.push(`${this._codeVariableName}.expensiveBlur = ${this.expensiveBlur};`);\r\n        codes.push(`${this._codeVariableName}.bilateralSamples = ${this.bilateralSamples};`);\r\n        codes.push(`${this._codeVariableName}.bilateralSoften = ${this.bilateralSoften};`);\r\n        codes.push(`${this._codeVariableName}.bilateralTolerance = ${this.bilateralTolerance};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.samples = this.samples;\r\n        serializationObject.totalStrength = this.totalStrength;\r\n        serializationObject.base = this.base;\r\n        serializationObject.maxZ = this.maxZ;\r\n        serializationObject.minZAspect = this.minZAspect;\r\n        serializationObject.radius = this.radius;\r\n        serializationObject.epsilon = this.epsilon;\r\n        serializationObject.useViewportInCombineStage = this.useViewportInCombineStage;\r\n        serializationObject.bypassBlur = this.bypassBlur;\r\n        serializationObject.expensiveBlur = this.expensiveBlur;\r\n        serializationObject.bilateralSoften = this.bilateralSoften;\r\n        serializationObject.bilateralSamples = this.bilateralSamples;\r\n        serializationObject.bilateralTolerance = this.bilateralTolerance;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.samples = serializationObject.samples;\r\n        this.totalStrength = serializationObject.totalStrength;\r\n        this.base = serializationObject.base;\r\n        this.maxZ = serializationObject.maxZ;\r\n        this.minZAspect = serializationObject.minZAspect;\r\n        this.radius = serializationObject.radius;\r\n        this.epsilon = serializationObject.epsilon;\r\n        this.useViewportInCombineStage = serializationObject.useViewportInCombineStage;\r\n        this.bypassBlur = serializationObject.bypassBlur;\r\n        this.expensiveBlur = serializationObject.expensiveBlur;\r\n        this.bilateralSoften = serializationObject.bilateralSoften;\r\n        this.bilateralSamples = serializationObject.bilateralSamples;\r\n        this.bilateralTolerance = serializationObject.bilateralTolerance;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ssao2PostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSsao2PostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphSSAO2PostProcessBlock\", NodeRenderGraphSSAO2PostProcessBlock);\r\n}\r\n","import { type Nullable, type Scene, type CubeTexture, type Camera, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Vector3, Matrix, Quaternion, TmpVectors } from \"core/Maths/math.vector.pure\";\r\n\r\nconst Trs = Matrix.Compose(new Vector3(0.5, 0.5, 0.5), Quaternion.Identity(), new Vector3(0.5, 0.5, 0.5));\r\nconst TrsWebGPU = Matrix.Compose(new Vector3(0.5, 0.5, 1), Quaternion.Identity(), new Vector3(0.5, 0.5, 0));\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinSSRPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"screenSpaceReflection2\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\r\n        \"projection\",\r\n        \"invProjectionMatrix\",\r\n        \"view\",\r\n        \"invView\",\r\n        \"thickness\",\r\n        \"reflectionSpecularFalloffExponent\",\r\n        \"strength\",\r\n        \"stepSize\",\r\n        \"maxSteps\",\r\n        \"roughnessFactor\",\r\n        \"projectionPixel\",\r\n        \"nearPlaneZ\",\r\n        \"farPlaneZ\",\r\n        \"maxDistance\",\r\n        \"selfCollisionNumSkip\",\r\n        \"vReflectionPosition\",\r\n        \"vReflectionSize\",\r\n        \"backSizeFactor\",\r\n        \"reflectivityThreshold\",\r\n    ];\r\n\r\n    public static readonly Samplers = [\"textureSampler\", \"normalSampler\", \"reflectivitySampler\", \"depthSampler\", \"envCubeSampler\", \"backDepthSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/screenSpaceReflection2.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/screenSpaceReflection2.fragment\"));\r\n        }\r\n    }\r\n\r\n    public isSSRSupported = true;\r\n\r\n    public maxDistance = 1000.0;\r\n\r\n    public step = 1.0;\r\n\r\n    public thickness = 0.5;\r\n\r\n    public strength = 1;\r\n\r\n    public reflectionSpecularFalloffExponent = 1;\r\n\r\n    public maxSteps = 1000.0;\r\n\r\n    public roughnessFactor = 0.2;\r\n\r\n    public selfCollisionNumSkip = 1;\r\n\r\n    private _reflectivityThreshold = 0.04;\r\n\r\n    public get reflectivityThreshold() {\r\n        return this._reflectivityThreshold;\r\n    }\r\n\r\n    public set reflectivityThreshold(threshold: number) {\r\n        if (threshold === this._reflectivityThreshold) {\r\n            return;\r\n        }\r\n\r\n        if ((threshold === 0 && this._reflectivityThreshold !== 0) || (threshold !== 0 && this._reflectivityThreshold === 0)) {\r\n            this._reflectivityThreshold = threshold;\r\n            this._updateEffectDefines();\r\n        } else {\r\n            this._reflectivityThreshold = threshold;\r\n        }\r\n    }\r\n\r\n    private _useBlur = false;\r\n\r\n    public get useBlur() {\r\n        return this._useBlur;\r\n    }\r\n\r\n    public set useBlur(blur: boolean) {\r\n        if (this._useBlur === blur) {\r\n            return;\r\n        }\r\n\r\n        this._useBlur = blur;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _enableSmoothReflections = false;\r\n\r\n    public get enableSmoothReflections(): boolean {\r\n        return this._enableSmoothReflections;\r\n    }\r\n\r\n    public set enableSmoothReflections(enabled: boolean) {\r\n        if (enabled === this._enableSmoothReflections) {\r\n            return;\r\n        }\r\n\r\n        this._enableSmoothReflections = enabled;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _environmentTexture: Nullable<CubeTexture>;\r\n\r\n    public get environmentTexture() {\r\n        return this._environmentTexture;\r\n    }\r\n\r\n    public set environmentTexture(texture: Nullable<CubeTexture>) {\r\n        this._environmentTexture = texture;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _environmentTextureIsProbe = false;\r\n\r\n    public get environmentTextureIsProbe(): boolean {\r\n        return this._environmentTextureIsProbe;\r\n    }\r\n\r\n    public set environmentTextureIsProbe(isProbe: boolean) {\r\n        this._environmentTextureIsProbe = isProbe;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _attenuateScreenBorders = true;\r\n\r\n    public get attenuateScreenBorders() {\r\n        return this._attenuateScreenBorders;\r\n    }\r\n\r\n    public set attenuateScreenBorders(attenuate: boolean) {\r\n        if (this._attenuateScreenBorders === attenuate) {\r\n            return;\r\n        }\r\n        this._attenuateScreenBorders = attenuate;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _attenuateIntersectionDistance = true;\r\n\r\n    public get attenuateIntersectionDistance() {\r\n        return this._attenuateIntersectionDistance;\r\n    }\r\n\r\n    public set attenuateIntersectionDistance(attenuate: boolean) {\r\n        if (this._attenuateIntersectionDistance === attenuate) {\r\n            return;\r\n        }\r\n        this._attenuateIntersectionDistance = attenuate;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _attenuateIntersectionIterations = true;\r\n\r\n    public get attenuateIntersectionIterations() {\r\n        return this._attenuateIntersectionIterations;\r\n    }\r\n\r\n    public set attenuateIntersectionIterations(attenuate: boolean) {\r\n        if (this._attenuateIntersectionIterations === attenuate) {\r\n            return;\r\n        }\r\n        this._attenuateIntersectionIterations = attenuate;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _attenuateFacingCamera = false;\r\n\r\n    public get attenuateFacingCamera() {\r\n        return this._attenuateFacingCamera;\r\n    }\r\n\r\n    public set attenuateFacingCamera(attenuate: boolean) {\r\n        if (this._attenuateFacingCamera === attenuate) {\r\n            return;\r\n        }\r\n        this._attenuateFacingCamera = attenuate;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _attenuateBackfaceReflection = false;\r\n\r\n    public get attenuateBackfaceReflection() {\r\n        return this._attenuateBackfaceReflection;\r\n    }\r\n\r\n    public set attenuateBackfaceReflection(attenuate: boolean) {\r\n        if (this._attenuateBackfaceReflection === attenuate) {\r\n            return;\r\n        }\r\n        this._attenuateBackfaceReflection = attenuate;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _clipToFrustum = true;\r\n\r\n    public get clipToFrustum() {\r\n        return this._clipToFrustum;\r\n    }\r\n\r\n    public set clipToFrustum(clip: boolean) {\r\n        if (this._clipToFrustum === clip) {\r\n            return;\r\n        }\r\n        this._clipToFrustum = clip;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _useFresnel = false;\r\n\r\n    public get useFresnel() {\r\n        return this._useFresnel;\r\n    }\r\n\r\n    public set useFresnel(fresnel: boolean) {\r\n        if (this._useFresnel === fresnel) {\r\n            return;\r\n        }\r\n        this._useFresnel = fresnel;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _enableAutomaticThicknessComputation = false;\r\n\r\n    public get enableAutomaticThicknessComputation(): boolean {\r\n        return this._enableAutomaticThicknessComputation;\r\n    }\r\n\r\n    public set enableAutomaticThicknessComputation(automatic: boolean) {\r\n        if (this._enableAutomaticThicknessComputation === automatic) {\r\n            return;\r\n        }\r\n\r\n        this._enableAutomaticThicknessComputation = automatic;\r\n\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _inputTextureColorIsInGammaSpace = true;\r\n\r\n    public get inputTextureColorIsInGammaSpace(): boolean {\r\n        return this._inputTextureColorIsInGammaSpace;\r\n    }\r\n\r\n    public set inputTextureColorIsInGammaSpace(gammaSpace: boolean) {\r\n        if (this._inputTextureColorIsInGammaSpace === gammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._inputTextureColorIsInGammaSpace = gammaSpace;\r\n\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _generateOutputInGammaSpace = true;\r\n\r\n    public get generateOutputInGammaSpace(): boolean {\r\n        return this._generateOutputInGammaSpace;\r\n    }\r\n\r\n    public set generateOutputInGammaSpace(gammaSpace: boolean) {\r\n        if (this._generateOutputInGammaSpace === gammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._generateOutputInGammaSpace = gammaSpace;\r\n\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _debug = false;\r\n\r\n    public get debug(): boolean {\r\n        return this._debug;\r\n    }\r\n\r\n    public set debug(value: boolean) {\r\n        if (this._debug === value) {\r\n            return;\r\n        }\r\n\r\n        this._debug = value;\r\n\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _textureWidth = 0;\r\n\r\n    public get textureWidth() {\r\n        return this._textureWidth;\r\n    }\r\n\r\n    public set textureWidth(width: number) {\r\n        if (this._textureWidth === width) {\r\n            return;\r\n        }\r\n        this._textureWidth = width;\r\n    }\r\n\r\n    private _textureHeight = 0;\r\n\r\n    public get textureHeight() {\r\n        return this._textureHeight;\r\n    }\r\n\r\n    public set textureHeight(height: number) {\r\n        if (this._textureHeight === height) {\r\n            return;\r\n        }\r\n        this._textureHeight = height;\r\n    }\r\n\r\n    public camera: Nullable<Camera> = null;\r\n\r\n    private _useScreenspaceDepth = false;\r\n\r\n    public get useScreenspaceDepth() {\r\n        return this._useScreenspaceDepth;\r\n    }\r\n\r\n    public set useScreenspaceDepth(value: boolean) {\r\n        if (this._useScreenspaceDepth === value) {\r\n            return;\r\n        }\r\n\r\n        this._useScreenspaceDepth = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _normalsAreInWorldSpace = false;\r\n\r\n    public get normalsAreInWorldSpace() {\r\n        return this._normalsAreInWorldSpace;\r\n    }\r\n\r\n    public set normalsAreInWorldSpace(value: boolean) {\r\n        if (this._normalsAreInWorldSpace === value) {\r\n            return;\r\n        }\r\n\r\n        this._normalsAreInWorldSpace = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _normalsAreUnsigned = false;\r\n\r\n    public get normalsAreUnsigned() {\r\n        return this._normalsAreUnsigned;\r\n    }\r\n\r\n    public set normalsAreUnsigned(value: boolean) {\r\n        if (this._normalsAreUnsigned === value) {\r\n            return;\r\n        }\r\n\r\n        this._normalsAreUnsigned = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _scene: Scene;\r\n\r\n    constructor(name: string, scene: Scene, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: scene.getEngine(),\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSSRPostProcess.FragmentUrl,\r\n            uniforms: ThinSSRPostProcess.Uniforms,\r\n            samplers: ThinSSRPostProcess.Samplers,\r\n            shaderLanguage: scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n\r\n        this._scene = scene;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        const camera = this.camera;\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        const viewMatrix = camera.getViewMatrix();\r\n        const projectionMatrix = camera.getProjectionMatrix();\r\n\r\n        projectionMatrix.invertToRef(TmpVectors.Matrix[0]);\r\n        viewMatrix.invertToRef(TmpVectors.Matrix[1]);\r\n\r\n        effect.setMatrix(\"projection\", projectionMatrix);\r\n        effect.setMatrix(\"view\", viewMatrix);\r\n        effect.setMatrix(\"invView\", TmpVectors.Matrix[1]);\r\n        effect.setMatrix(\"invProjectionMatrix\", TmpVectors.Matrix[0]);\r\n        effect.setFloat(\"thickness\", this.thickness);\r\n        effect.setFloat(\"reflectionSpecularFalloffExponent\", this.reflectionSpecularFalloffExponent);\r\n        effect.setFloat(\"strength\", this.strength);\r\n        effect.setFloat(\"stepSize\", this.step);\r\n        effect.setFloat(\"maxSteps\", this.maxSteps);\r\n        effect.setFloat(\"roughnessFactor\", this.roughnessFactor);\r\n        effect.setFloat(\"nearPlaneZ\", camera.minZ);\r\n        effect.setFloat(\"farPlaneZ\", camera.maxZ);\r\n        effect.setFloat(\"maxDistance\", this.maxDistance);\r\n        effect.setFloat(\"selfCollisionNumSkip\", this.selfCollisionNumSkip);\r\n        effect.setFloat(\"reflectivityThreshold\", this._reflectivityThreshold);\r\n\r\n        Matrix.ScalingToRef(this.textureWidth, this.textureHeight, 1, TmpVectors.Matrix[2]);\r\n\r\n        projectionMatrix.multiplyToRef(this._scene.getEngine().isWebGPU ? TrsWebGPU : Trs, TmpVectors.Matrix[3]);\r\n\r\n        TmpVectors.Matrix[3].multiplyToRef(TmpVectors.Matrix[2], TmpVectors.Matrix[4]);\r\n\r\n        effect.setMatrix(\"projectionPixel\", TmpVectors.Matrix[4]);\r\n\r\n        if (this._environmentTexture) {\r\n            effect.setTexture(\"envCubeSampler\", this._environmentTexture);\r\n\r\n            if (this._environmentTexture.boundingBoxSize) {\r\n                effect.setVector3(\"vReflectionPosition\", this._environmentTexture.boundingBoxPosition);\r\n                effect.setVector3(\"vReflectionSize\", this._environmentTexture.boundingBoxSize);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateEffectDefines() {\r\n        const defines: string[] = [];\r\n\r\n        if (this.isSSRSupported) {\r\n            defines.push(\"#define SSR_SUPPORTED\");\r\n        }\r\n        if (this._enableSmoothReflections) {\r\n            defines.push(\"#define SSRAYTRACE_ENABLE_REFINEMENT\");\r\n        }\r\n        if (this._scene.useRightHandedSystem) {\r\n            defines.push(\"#define SSRAYTRACE_RIGHT_HANDED_SCENE\");\r\n        }\r\n        if (this._useScreenspaceDepth) {\r\n            defines.push(\"#define SSRAYTRACE_SCREENSPACE_DEPTH\");\r\n        }\r\n        if (this._environmentTexture) {\r\n            defines.push(\"#define SSR_USE_ENVIRONMENT_CUBE\");\r\n            if (this._environmentTexture.boundingBoxSize) {\r\n                defines.push(\"#define SSR_USE_LOCAL_REFLECTIONMAP_CUBIC\");\r\n            }\r\n            if (this._environmentTexture.gammaSpace) {\r\n                defines.push(\"#define SSR_ENVIRONMENT_CUBE_IS_GAMMASPACE\");\r\n            }\r\n        }\r\n        if (this._environmentTextureIsProbe) {\r\n            defines.push(\"#define SSR_INVERTCUBICMAP\");\r\n        }\r\n        if (this._enableAutomaticThicknessComputation) {\r\n            defines.push(\"#define SSRAYTRACE_USE_BACK_DEPTHBUFFER\");\r\n        }\r\n        if (this._attenuateScreenBorders) {\r\n            defines.push(\"#define SSR_ATTENUATE_SCREEN_BORDERS\");\r\n        }\r\n        if (this._attenuateIntersectionDistance) {\r\n            defines.push(\"#define SSR_ATTENUATE_INTERSECTION_DISTANCE\");\r\n        }\r\n        if (this._attenuateIntersectionIterations) {\r\n            defines.push(\"#define SSR_ATTENUATE_INTERSECTION_NUMITERATIONS\");\r\n        }\r\n        if (this._attenuateFacingCamera) {\r\n            defines.push(\"#define SSR_ATTENUATE_FACING_CAMERA\");\r\n        }\r\n        if (this._attenuateBackfaceReflection) {\r\n            defines.push(\"#define SSR_ATTENUATE_BACKFACE_REFLECTION\");\r\n        }\r\n        if (this._clipToFrustum) {\r\n            defines.push(\"#define SSRAYTRACE_CLIP_TO_FRUSTUM\");\r\n        }\r\n        if (this.useBlur) {\r\n            defines.push(\"#define SSR_USE_BLUR\");\r\n        }\r\n        if (this._debug) {\r\n            defines.push(\"#define SSRAYTRACE_DEBUG\");\r\n        }\r\n        if (this._inputTextureColorIsInGammaSpace) {\r\n            defines.push(\"#define SSR_INPUT_IS_GAMMA_SPACE\");\r\n        }\r\n        if (this._generateOutputInGammaSpace) {\r\n            defines.push(\"#define SSR_OUTPUT_IS_GAMMA_SPACE\");\r\n        }\r\n        if (this._useFresnel) {\r\n            defines.push(\"#define SSR_BLEND_WITH_FRESNEL\");\r\n        }\r\n        if (this._reflectivityThreshold === 0) {\r\n            defines.push(\"#define SSR_DISABLE_REFLECTIVITY_TEST\");\r\n        }\r\n\r\n        if (this._normalsAreInWorldSpace) {\r\n            defines.push(\"#define SSR_NORMAL_IS_IN_WORLDSPACE\");\r\n        }\r\n\r\n        if (this._normalsAreUnsigned) {\r\n            defines.push(\"#define SSR_DECODE_NORMAL\");\r\n        }\r\n\r\n        if (this.camera && this.camera.mode === Constants.ORTHOGRAPHIC_CAMERA) {\r\n            defines.push(\"#define ORTHOGRAPHIC_CAMERA\");\r\n        }\r\n\r\n        this.updateEffect(defines.join(\"\\n\"));\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinSSRBlurPostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"screenSpaceReflection2Blur\";\r\n\r\n    public static readonly Uniforms = [\"texelOffsetScale\"];\r\n\r\n    public static readonly Samplers = [\"textureSampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/screenSpaceReflection2Blur.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/screenSpaceReflection2Blur.fragment\"));\r\n        }\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, direction?: Vector2, blurStrength?: number, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSSRBlurPostProcess.FragmentUrl,\r\n            uniforms: ThinSSRBlurPostProcess.Uniforms,\r\n            samplers: ThinSSRBlurPostProcess.Samplers,\r\n        });\r\n\r\n        if (direction !== undefined) {\r\n            this.direction = direction;\r\n        }\r\n\r\n        if (blurStrength !== undefined) {\r\n            this.blurStrength = blurStrength;\r\n        }\r\n    }\r\n\r\n    public textureWidth: number = 0;\r\n\r\n    public textureHeight: number = 0;\r\n\r\n    public direction = new Vector2(1, 0);\r\n\r\n    public blurStrength = 0.03;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        this._drawWrapper.effect!.setFloat2(\r\n            \"texelOffsetScale\",\r\n            (1 / this.textureWidth) * this.direction.x * this.blurStrength,\r\n            (1 / this.textureHeight) * this.direction.y * this.blurStrength\r\n        );\r\n    }\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions, type Camera } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { TmpVectors } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinSSRBlurCombinerPostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"screenSpaceReflection2BlurCombiner\";\r\n\r\n    public static readonly Uniforms = [\r\n        \"strength\",\r\n        \"reflectionSpecularFalloffExponent\",\r\n        \"reflectivityThreshold\",\r\n        \"projection\",\r\n        \"invProjectionMatrix\",\r\n        \"nearPlaneZ\",\r\n        \"farPlaneZ\",\r\n        \"view\",\r\n    ];\r\n\r\n    public static readonly Samplers = [\"textureSampler\", \"depthSampler\", \"normalSampler\", \"mainSampler\", \"reflectivitySampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/screenSpaceReflection2BlurCombiner.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/screenSpaceReflection2BlurCombiner.fragment\"));\r\n        }\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinSSRBlurCombinerPostProcess.FragmentUrl,\r\n            uniforms: ThinSSRBlurCombinerPostProcess.Uniforms,\r\n            samplers: ThinSSRBlurCombinerPostProcess.Samplers,\r\n        });\r\n\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    public strength = 1;\r\n\r\n    public reflectionSpecularFalloffExponent = 1;\r\n\r\n    public camera: Nullable<Camera> = null;\r\n\r\n    private _useFresnel = false;\r\n\r\n    public get useFresnel() {\r\n        return this._useFresnel;\r\n    }\r\n\r\n    public set useFresnel(fresnel: boolean) {\r\n        if (this._useFresnel === fresnel) {\r\n            return;\r\n        }\r\n\r\n        this._useFresnel = fresnel;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _useScreenspaceDepth = false;\r\n\r\n    public get useScreenspaceDepth() {\r\n        return this._useScreenspaceDepth;\r\n    }\r\n\r\n    public set useScreenspaceDepth(value: boolean) {\r\n        if (this._useScreenspaceDepth === value) {\r\n            return;\r\n        }\r\n\r\n        this._useScreenspaceDepth = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _inputTextureColorIsInGammaSpace = true;\r\n\r\n    public get inputTextureColorIsInGammaSpace(): boolean {\r\n        return this._inputTextureColorIsInGammaSpace;\r\n    }\r\n\r\n    public set inputTextureColorIsInGammaSpace(gammaSpace: boolean) {\r\n        if (this._inputTextureColorIsInGammaSpace === gammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._inputTextureColorIsInGammaSpace = gammaSpace;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _generateOutputInGammaSpace = true;\r\n\r\n    public get generateOutputInGammaSpace(): boolean {\r\n        return this._generateOutputInGammaSpace;\r\n    }\r\n\r\n    public set generateOutputInGammaSpace(gammaSpace: boolean) {\r\n        if (this._generateOutputInGammaSpace === gammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._generateOutputInGammaSpace = gammaSpace;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _debug = false;\r\n\r\n    public get debug(): boolean {\r\n        return this._debug;\r\n    }\r\n\r\n    public set debug(value: boolean) {\r\n        if (this._debug === value) {\r\n            return;\r\n        }\r\n\r\n        this._debug = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _reflectivityThreshold = 0.04;\r\n\r\n    public get reflectivityThreshold() {\r\n        return this._reflectivityThreshold;\r\n    }\r\n\r\n    public set reflectivityThreshold(threshold: number) {\r\n        if (threshold === this._reflectivityThreshold) {\r\n            return;\r\n        }\r\n\r\n        if ((threshold === 0 && this._reflectivityThreshold !== 0) || (threshold !== 0 && this._reflectivityThreshold === 0)) {\r\n            this._reflectivityThreshold = threshold;\r\n            this._updateEffectDefines();\r\n        } else {\r\n            this._reflectivityThreshold = threshold;\r\n        }\r\n    }\r\n\r\n    private _normalsAreInWorldSpace = false;\r\n\r\n    public get normalsAreInWorldSpace() {\r\n        return this._normalsAreInWorldSpace;\r\n    }\r\n\r\n    public set normalsAreInWorldSpace(value: boolean) {\r\n        if (this._normalsAreInWorldSpace === value) {\r\n            return;\r\n        }\r\n\r\n        this._normalsAreInWorldSpace = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _normalsAreUnsigned = false;\r\n\r\n    public get normalsAreUnsigned() {\r\n        return this._normalsAreUnsigned;\r\n    }\r\n\r\n    public set normalsAreUnsigned(value: boolean) {\r\n        if (this._normalsAreUnsigned === value) {\r\n            return;\r\n        }\r\n\r\n        this._normalsAreUnsigned = value;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat(\"strength\", this.strength);\r\n        effect.setFloat(\"reflectionSpecularFalloffExponent\", this.reflectionSpecularFalloffExponent);\r\n        effect.setFloat(\"reflectivityThreshold\", this.reflectivityThreshold);\r\n\r\n        if (this.useFresnel && this.camera) {\r\n            const projectionMatrix = this.camera.getProjectionMatrix();\r\n\r\n            projectionMatrix.invertToRef(TmpVectors.Matrix[0]);\r\n\r\n            effect.setMatrix(\"projection\", projectionMatrix);\r\n            effect.setMatrix(\"invProjectionMatrix\", TmpVectors.Matrix[0]);\r\n            effect.setMatrix(\"view\", this.camera.getViewMatrix());\r\n\r\n            if (this.useScreenspaceDepth) {\r\n                effect.setFloat(\"nearPlaneZ\", this.camera.minZ);\r\n                effect.setFloat(\"farPlaneZ\", this.camera.maxZ);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateEffectDefines() {\r\n        let defines = \"\";\r\n\r\n        if (this._debug) {\r\n            defines += \"#define SSRAYTRACE_DEBUG\\n\";\r\n        }\r\n        if (this._inputTextureColorIsInGammaSpace) {\r\n            defines += \"#define SSR_INPUT_IS_GAMMA_SPACE\\n\";\r\n        }\r\n        if (this._generateOutputInGammaSpace) {\r\n            defines += \"#define SSR_OUTPUT_IS_GAMMA_SPACE\\n\";\r\n        }\r\n        if (this._useFresnel) {\r\n            defines += \"#define SSR_BLEND_WITH_FRESNEL\\n\";\r\n        }\r\n        if (this._useScreenspaceDepth) {\r\n            defines += \"#define SSRAYTRACE_SCREENSPACE_DEPTH\\n\";\r\n        }\r\n        if (this._reflectivityThreshold === 0) {\r\n            defines += \"#define SSR_DISABLE_REFLECTIVITY_TEST\\n\";\r\n        }\r\n        if (this._normalsAreInWorldSpace) {\r\n            defines += \"#define SSR_NORMAL_IS_IN_WORLDSPACE\\n\";\r\n        }\r\n        if (this._normalsAreUnsigned) {\r\n            defines += \"#define SSR_DECODE_NORMAL\\n\";\r\n        }\r\n\r\n        this.updateEffect(defines);\r\n    }\r\n}\r\n","import { type Nullable, type CubeTexture, type Scene, type Camera } from \"core/index\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { ThinSSRPostProcess } from \"core/PostProcesses/thinSSRPostProcess\";\r\nimport { ThinSSRBlurPostProcess } from \"core/PostProcesses/thinSSRBlurPostProcess\";\r\nimport { ThinSSRBlurCombinerPostProcess } from \"core/PostProcesses/thinSSRBlurCombinerPostProcess\";\r\n\r\n/**\r\n * The SSR rendering pipeline is used to generate a reflection based on a flat mirror model.\r\n */\r\nexport class ThinSSRRenderingPipeline {\r\n    /** @internal */\r\n    public readonly _ssrPostProcess: ThinSSRPostProcess;\r\n    /** @internal */\r\n    public readonly _ssrBlurXPostProcess: ThinSSRBlurPostProcess;\r\n    /** @internal */\r\n    public readonly _ssrBlurYPostProcess: ThinSSRBlurPostProcess;\r\n    /** @internal */\r\n    public readonly _ssrBlurCombinerPostProcess: ThinSSRBlurCombinerPostProcess;\r\n\r\n    /**\r\n     * Gets or sets the name of the rendering pipeline\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the SSR rendering pipeline is supported\r\n     */\r\n    public get isSSRSupported(): boolean {\r\n        return this._ssrPostProcess.isSSRSupported;\r\n    }\r\n\r\n    public set isSSRSupported(supported: boolean) {\r\n        this._ssrPostProcess.isSSRSupported = supported;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the maxDistance used to define how far we look for reflection during the ray-marching on the reflected ray (default: 1000).\r\n     * Note that this value is a view (camera) space distance (not pixels!).\r\n     */\r\n    public get maxDistance() {\r\n        return this._ssrPostProcess.maxDistance;\r\n    }\r\n\r\n    public set maxDistance(distance: number) {\r\n        this._ssrPostProcess.maxDistance = distance;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the step size used to iterate until the effect finds the color of the reflection's pixel. Should be an integer \\>= 1 as it is the number of pixels we advance at each step (default: 1).\r\n     * Use higher values to improve performances (but at the expense of quality).\r\n     */\r\n    public get step() {\r\n        return this._ssrPostProcess.step;\r\n    }\r\n\r\n    public set step(step: number) {\r\n        this._ssrPostProcess.step = step;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the thickness value used as tolerance when computing the intersection between the reflected ray and the scene (default: 0.5).\r\n     * If setting \"enableAutomaticThicknessComputation\" to true, you can use lower values for \"thickness\" (even 0), as the geometry thickness\r\n     * is automatically computed thank to the regular depth buffer + the backface depth buffer\r\n     */\r\n    public get thickness() {\r\n        return this._ssrPostProcess.thickness;\r\n    }\r\n\r\n    public set thickness(thickness: number) {\r\n        this._ssrPostProcess.thickness = thickness;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current reflection strength. 1.0 is an ideal value but can be increased/decreased for particular results (default: 1).\r\n     */\r\n    public get strength() {\r\n        return this._ssrPostProcess.strength;\r\n    }\r\n\r\n    public set strength(strength: number) {\r\n        this._ssrPostProcess.strength = strength;\r\n        this._ssrBlurCombinerPostProcess.strength = strength;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the falloff exponent used to compute the reflection strength. Higher values lead to fainter reflections (default: 1).\r\n     */\r\n    public get reflectionSpecularFalloffExponent() {\r\n        return this._ssrPostProcess.reflectionSpecularFalloffExponent;\r\n    }\r\n\r\n    public set reflectionSpecularFalloffExponent(exponent: number) {\r\n        this._ssrPostProcess.reflectionSpecularFalloffExponent = exponent;\r\n        this._ssrBlurCombinerPostProcess.reflectionSpecularFalloffExponent = exponent;\r\n    }\r\n\r\n    /**\r\n     * Maximum number of steps during the ray marching process after which we consider an intersection could not be found (default: 1000).\r\n     * Should be an integer value.\r\n     */\r\n    public get maxSteps() {\r\n        return this._ssrPostProcess.maxSteps;\r\n    }\r\n\r\n    public set maxSteps(steps: number) {\r\n        this._ssrPostProcess.maxSteps = steps;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the factor applied when computing roughness. Default value is 0.2.\r\n     * When blurring based on roughness is enabled (meaning blurDispersionStrength \\> 0), roughnessFactor is used as a global roughness factor applied on all objects.\r\n     * If you want to disable this global roughness set it to 0.\r\n     */\r\n    public get roughnessFactor() {\r\n        return this._ssrPostProcess.roughnessFactor;\r\n    }\r\n\r\n    public set roughnessFactor(factor: number) {\r\n        this._ssrPostProcess.roughnessFactor = factor;\r\n    }\r\n\r\n    /**\r\n     * Number of steps to skip at start when marching the ray to avoid self collisions (default: 1)\r\n     * 1 should normally be a good value, depending on the scene you may need to use a higher value (2 or 3)\r\n     */\r\n    public get selfCollisionNumSkip() {\r\n        return this._ssrPostProcess.selfCollisionNumSkip;\r\n    }\r\n\r\n    public set selfCollisionNumSkip(skip: number) {\r\n        this._ssrPostProcess.selfCollisionNumSkip = skip;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the minimum value for one of the reflectivity component of the material to consider it for SSR (default: 0.04).\r\n     * If all r/g/b components of the reflectivity is below or equal this value, the pixel will not be considered reflective and SSR won't be applied.\r\n     */\r\n    public get reflectivityThreshold() {\r\n        return this._ssrPostProcess.reflectivityThreshold;\r\n    }\r\n\r\n    public set reflectivityThreshold(threshold: number) {\r\n        const currentThreshold = this._ssrPostProcess.reflectivityThreshold;\r\n\r\n        if (threshold === currentThreshold) {\r\n            return;\r\n        }\r\n\r\n        this._ssrPostProcess.reflectivityThreshold = threshold;\r\n        this._ssrBlurCombinerPostProcess.reflectivityThreshold = threshold;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the downsample factor used to reduce the size of the texture used to compute the SSR contribution (default: 0).\r\n     * Use 0 to render the SSR contribution at full resolution, 1 to render at half resolution, 2 to render at 1/3 resolution, etc.\r\n     * Note that it is used only when blurring is enabled (blurDispersionStrength \\> 0), because in that mode the SSR contribution is generated in a separate texture.\r\n     */\r\n    public ssrDownsample = 0;\r\n\r\n    /**\r\n     * Gets or sets the blur dispersion strength. Set this value to 0 to disable blurring (default: 0.03)\r\n     * The reflections are blurred based on the roughness of the surface and the distance between the pixel shaded and the reflected pixel: the higher the distance the more blurry the reflection is.\r\n     * blurDispersionStrength allows to increase or decrease this effect.\r\n     */\r\n    public get blurDispersionStrength() {\r\n        return this._ssrBlurXPostProcess.blurStrength;\r\n    }\r\n\r\n    public set blurDispersionStrength(strength: number) {\r\n        if (strength === this._ssrBlurXPostProcess.blurStrength) {\r\n            return;\r\n        }\r\n\r\n        this._ssrPostProcess.useBlur = strength > 0;\r\n\r\n        this._ssrBlurXPostProcess.blurStrength = strength;\r\n        this._ssrBlurYPostProcess.blurStrength = strength;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the downsample factor used to reduce the size of the textures used to blur the reflection effect (default: 0).\r\n     * Use 0 to blur at full resolution, 1 to render at half resolution, 2 to render at 1/3 resolution, etc.\r\n     */\r\n    public blurDownsample = 0;\r\n\r\n    /**\r\n     * Gets or sets whether or not smoothing reflections is enabled (default: false)\r\n     * Enabling smoothing will require more GPU power.\r\n     * Note that this setting has no effect if step = 1: it's only used if step \\> 1.\r\n     */\r\n    public get enableSmoothReflections(): boolean {\r\n        return this._ssrPostProcess.enableSmoothReflections;\r\n    }\r\n\r\n    public set enableSmoothReflections(enabled: boolean) {\r\n        this._ssrPostProcess.enableSmoothReflections = enabled;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the environment cube texture used to define the reflection when the reflected rays of SSR leave the view space or when the maxDistance/maxSteps is reached.\r\n     */\r\n    public get environmentTexture() {\r\n        return this._ssrPostProcess.environmentTexture;\r\n    }\r\n\r\n    public set environmentTexture(texture: Nullable<CubeTexture>) {\r\n        this._ssrPostProcess.environmentTexture = texture;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the boolean defining if the environment texture is a standard cubemap (false) or a probe (true). Default value is false.\r\n     * Note: a probe cube texture is treated differently than an ordinary cube texture because the Y axis is reversed.\r\n     */\r\n    public get environmentTextureIsProbe(): boolean {\r\n        return this._ssrPostProcess.environmentTextureIsProbe;\r\n    }\r\n\r\n    public set environmentTextureIsProbe(isProbe: boolean) {\r\n        this._ssrPostProcess.environmentTextureIsProbe = isProbe;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the reflections should be attenuated at the screen borders (default: true).\r\n     */\r\n    public get attenuateScreenBorders() {\r\n        return this._ssrPostProcess.attenuateScreenBorders;\r\n    }\r\n\r\n    public set attenuateScreenBorders(attenuate: boolean) {\r\n        this._ssrPostProcess.attenuateScreenBorders = attenuate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the reflections should be attenuated according to the distance of the intersection (default: true).\r\n     */\r\n    public get attenuateIntersectionDistance() {\r\n        return this._ssrPostProcess.attenuateIntersectionDistance;\r\n    }\r\n\r\n    public set attenuateIntersectionDistance(attenuate: boolean) {\r\n        this._ssrPostProcess.attenuateIntersectionDistance = attenuate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the reflections should be attenuated according to the number of iterations performed to find the intersection (default: true).\r\n     */\r\n    public get attenuateIntersectionIterations() {\r\n        return this._ssrPostProcess.attenuateIntersectionIterations;\r\n    }\r\n\r\n    public set attenuateIntersectionIterations(attenuate: boolean) {\r\n        this._ssrPostProcess.attenuateIntersectionIterations = attenuate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the reflections should be attenuated when the reflection ray is facing the camera (the view direction) (default: false).\r\n     */\r\n    public get attenuateFacingCamera() {\r\n        return this._ssrPostProcess.attenuateFacingCamera;\r\n    }\r\n\r\n    public set attenuateFacingCamera(attenuate: boolean) {\r\n        this._ssrPostProcess.attenuateFacingCamera = attenuate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the backface reflections should be attenuated (default: false).\r\n     */\r\n    public get attenuateBackfaceReflection() {\r\n        return this._ssrPostProcess.attenuateBackfaceReflection;\r\n    }\r\n\r\n    public set attenuateBackfaceReflection(attenuate: boolean) {\r\n        this._ssrPostProcess.attenuateBackfaceReflection = attenuate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the ray should be clipped to the frustum (default: true).\r\n     * You can try to set this parameter to false to save some performances: it may produce some artefacts in some cases, but generally they won't really be visible\r\n     */\r\n    public get clipToFrustum() {\r\n        return this._ssrPostProcess.clipToFrustum;\r\n    }\r\n\r\n    public set clipToFrustum(clip: boolean) {\r\n        this._ssrPostProcess.clipToFrustum = clip;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating whether the blending between the current color pixel and the reflection color should be done with a Fresnel coefficient (default: false).\r\n     * It is more physically accurate to use the Fresnel coefficient (otherwise it uses the reflectivity of the material for blending), but it is also more expensive when you use blur (when blurDispersionStrength \\> 0).\r\n     */\r\n    public get useFresnel() {\r\n        return this._ssrPostProcess.useFresnel;\r\n    }\r\n\r\n    public set useFresnel(fresnel: boolean) {\r\n        this._ssrPostProcess.useFresnel = fresnel;\r\n        this._ssrBlurCombinerPostProcess.useFresnel = fresnel;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean defining if geometry thickness should be computed automatically (default: false).\r\n     * When enabled, a depth renderer is created which will render the back faces of the scene to a depth texture (meaning additional work for the GPU).\r\n     * In that mode, the \"thickness\" property is still used as an offset to compute the ray intersection, but you can typically use a much lower\r\n     * value than when enableAutomaticThicknessComputation is false (it's even possible to use a value of 0 when using low values for \"step\")\r\n     * Note that for performance reasons, this option will only apply to the first camera to which the rendering pipeline is attached!\r\n     */\r\n    public get enableAutomaticThicknessComputation(): boolean {\r\n        return this._ssrPostProcess.enableAutomaticThicknessComputation;\r\n    }\r\n\r\n    public set enableAutomaticThicknessComputation(automatic: boolean) {\r\n        if (this._ssrPostProcess.enableAutomaticThicknessComputation === automatic) {\r\n            return;\r\n        }\r\n\r\n        this._ssrPostProcess.enableAutomaticThicknessComputation = automatic;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean defining if the input color texture is in gamma space (default: true)\r\n     * The SSR effect works in linear space, so if the input texture is in gamma space, we must convert the texture to linear space before applying the effect\r\n     */\r\n    public get inputTextureColorIsInGammaSpace(): boolean {\r\n        return this._ssrPostProcess.inputTextureColorIsInGammaSpace;\r\n    }\r\n\r\n    public set inputTextureColorIsInGammaSpace(gammaSpace: boolean) {\r\n        if (this._ssrPostProcess.inputTextureColorIsInGammaSpace === gammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._ssrPostProcess.inputTextureColorIsInGammaSpace = gammaSpace;\r\n        this._ssrBlurCombinerPostProcess.inputTextureColorIsInGammaSpace = gammaSpace;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean defining if the output color texture generated by the SSR pipeline should be in gamma space (default: true)\r\n     * If you have a post-process that comes after the SSR and that post-process needs the input to be in a linear space, you must disable generateOutputInGammaSpace\r\n     */\r\n    public get generateOutputInGammaSpace(): boolean {\r\n        return this._ssrPostProcess.generateOutputInGammaSpace;\r\n    }\r\n\r\n    public set generateOutputInGammaSpace(gammaSpace: boolean) {\r\n        if (this._ssrPostProcess.generateOutputInGammaSpace === gammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._ssrPostProcess.generateOutputInGammaSpace = gammaSpace;\r\n        this._ssrBlurCombinerPostProcess.generateOutputInGammaSpace = gammaSpace;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the effect should be rendered in debug mode (default: false).\r\n     * In this mode, colors have this meaning:\r\n     *   - blue: the ray hit the max distance (we reached maxDistance)\r\n     *   - red: the ray ran out of steps (we reached maxSteps)\r\n     *   - yellow: the ray went off screen\r\n     *   - green: the ray hit a surface. The brightness of the green color is proportional to the distance between the ray origin and the intersection point: A brighter green means more computation than a darker green.\r\n     * In the first 3 cases, the final color is calculated by mixing the skybox color with the pixel color (if environmentTexture is defined), otherwise the pixel color is not modified\r\n     * You should try to get as few blue/red/yellow pixels as possible, as this means that the ray has gone further than if it had hit a surface.\r\n     */\r\n    public get debug(): boolean {\r\n        return this._ssrPostProcess.debug;\r\n    }\r\n\r\n    public set debug(value: boolean) {\r\n        if (this._ssrPostProcess.debug === value) {\r\n            return;\r\n        }\r\n\r\n        this._ssrPostProcess.debug = value;\r\n        this._ssrBlurCombinerPostProcess.debug = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the camera to use to render the reflection\r\n     */\r\n    public get camera() {\r\n        return this._ssrPostProcess.camera;\r\n    }\r\n\r\n    public set camera(camera: Nullable<Camera>) {\r\n        this._ssrPostProcess.camera = camera;\r\n        this._ssrBlurCombinerPostProcess.camera = camera;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the depth buffer stores screen space depth instead of camera view space depth.\r\n     */\r\n    public get useScreenspaceDepth() {\r\n        return this._ssrPostProcess.useScreenspaceDepth;\r\n    }\r\n\r\n    public set useScreenspaceDepth(use: boolean) {\r\n        this._ssrPostProcess.useScreenspaceDepth = use;\r\n        this._ssrBlurCombinerPostProcess.useScreenspaceDepth = use;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the normals are in world space (false by default, meaning normals are in camera view space).\r\n     */\r\n    public get normalsAreInWorldSpace() {\r\n        return this._ssrPostProcess.normalsAreInWorldSpace;\r\n    }\r\n\r\n    public set normalsAreInWorldSpace(normalsAreInWorldSpace: boolean) {\r\n        this._ssrPostProcess.normalsAreInWorldSpace = normalsAreInWorldSpace;\r\n        this._ssrBlurCombinerPostProcess.normalsAreInWorldSpace = normalsAreInWorldSpace;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the normals are encoded as unsigned, that is normalUnsigned = normal*0.5+0.5 (false by default).\r\n     */\r\n    public get normalsAreUnsigned() {\r\n        return this._ssrPostProcess.normalsAreUnsigned;\r\n    }\r\n\r\n    public set normalsAreUnsigned(normalsAreUnsigned: boolean) {\r\n        this._ssrPostProcess.normalsAreUnsigned = normalsAreUnsigned;\r\n        this._ssrBlurCombinerPostProcess.normalsAreUnsigned = normalsAreUnsigned;\r\n    }\r\n\r\n    /**\r\n     * Checks if all the post processes in the pipeline are ready.\r\n     * @returns true if all the post processes in the pipeline are ready\r\n     */\r\n    public isReady(): boolean {\r\n        return this._ssrPostProcess.isReady() && this._ssrBlurXPostProcess.isReady() && this._ssrBlurYPostProcess.isReady() && this._ssrBlurCombinerPostProcess.isReady();\r\n    }\r\n\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Constructor of the SSR rendering pipeline\r\n     * @param name The rendering pipeline name\r\n     * @param scene The scene linked to this pipeline\r\n     */\r\n    constructor(name: string, scene: Scene) {\r\n        this.name = name;\r\n        this._scene = scene;\r\n\r\n        this._ssrPostProcess = new ThinSSRPostProcess(this.name, this._scene);\r\n        this._ssrBlurXPostProcess = new ThinSSRBlurPostProcess(this.name + \" BlurX\", this._scene.getEngine(), new Vector2(1, 0));\r\n        this._ssrBlurYPostProcess = new ThinSSRBlurPostProcess(this.name + \" BlurY\", this._scene.getEngine(), new Vector2(0, 1));\r\n        this._ssrBlurCombinerPostProcess = new ThinSSRBlurCombinerPostProcess(this.name + \" BlurCombiner\", this._scene.getEngine());\r\n\r\n        this._ssrPostProcess.useBlur = this._ssrBlurXPostProcess.blurStrength > 0;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the pipeline\r\n     */\r\n    public dispose(): void {\r\n        this._ssrPostProcess?.dispose();\r\n        this._ssrBlurXPostProcess?.dispose();\r\n        this._ssrBlurYPostProcess?.dispose();\r\n        this._ssrBlurCombinerPostProcess?.dispose();\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderPass, type Camera, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinSSRPostProcess } from \"core/PostProcesses/thinSSRPostProcess\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphSSRTask extends FrameGraphPostProcessTask {\r\n    public normalTexture: FrameGraphTextureHandle;\r\n\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    public reflectivityTexture: FrameGraphTextureHandle;\r\n\r\n    public backDepthTexture?: FrameGraphTextureHandle;\r\n\r\n    public camera: Camera;\r\n\r\n    public override readonly postProcess: ThinSSRPostProcess;\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinSSRPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinSSRPostProcess(name, frameGraph.scene));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSSRTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (\r\n            this.sourceTexture === undefined ||\r\n            this.normalTexture === undefined ||\r\n            this.depthTexture === undefined ||\r\n            this.reflectivityTexture === undefined ||\r\n            this.camera === undefined\r\n        ) {\r\n            throw new Error(`FrameGraphSSRTask \"${this.name}\": sourceTexture, normalTexture, depthTexture, reflectivityTexture and camera are required`);\r\n        }\r\n\r\n        const pass = super.record(\r\n            skipCreationOfDisabledPasses,\r\n            (context) => {\r\n                this.postProcess.camera = this.camera;\r\n\r\n                context.setTextureSamplingMode(this.normalTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n                context.setTextureSamplingMode(this.depthTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n                context.setTextureSamplingMode(this.reflectivityTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n                if (this.backDepthTexture) {\r\n                    context.setTextureSamplingMode(this.backDepthTexture, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n                }\r\n            },\r\n            (context) => {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"normalSampler\", this.normalTexture);\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"reflectivitySampler\", this.reflectivityTexture);\r\n                if (this.backDepthTexture) {\r\n                    context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"backDepthSampler\", this.backDepthTexture);\r\n                }\r\n                if (this.postProcess.enableAutomaticThicknessComputation) {\r\n                    this._postProcessDrawWrapper.effect!.setFloat(\"backSizeFactor\", 1);\r\n                }\r\n            }\r\n        );\r\n\r\n        pass.addDependencies([this.normalTexture, this.depthTexture, this.reflectivityTexture]);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphRenderPass, type FrameGraphRenderContext } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinSSRBlurPostProcess } from \"core/PostProcesses/thinSSRBlurPostProcess\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphSSRBlurTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinSSRBlurPostProcess;\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinSSRBlurPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinSSRBlurPostProcess(name, frameGraph.engine, new Vector2(1, 0), 0.03));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSSRBlurTask\";\r\n    }\r\n\r\n    public override record(\r\n        skipCreationOfDisabledPasses = false,\r\n        additionalExecute?: (context: FrameGraphRenderContext) => void,\r\n        additionalBindings?: (context: FrameGraphRenderContext) => void\r\n    ): FrameGraphRenderPass {\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute, additionalBindings);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type Camera, type FrameGraphTextureCreationOptions } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { ThinSSRRenderingPipeline } from \"core/PostProcesses/RenderPipeline/Pipelines/thinSSRRenderingPipeline\";\r\nimport { FrameGraphSSRTask } from \"./ssrTask\";\r\nimport { FrameGraphSSRBlurTask } from \"./ssrBlurTask\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a SSR post process.\r\n */\r\nexport class FrameGraphSSRRenderingPipelineTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to apply the SSR effect on.\r\n     */\r\n    public sourceTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use for the source texture.\r\n     */\r\n    public sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The alpha mode to use when applying the SSR effect.\r\n     */\r\n    public get alphaMode() {\r\n        return this._ssrBlurCombiner.alphaMode;\r\n    }\r\n\r\n    public set alphaMode(mode: number) {\r\n        this._ssrBlurCombiner.alphaMode = mode;\r\n    }\r\n\r\n    /**\r\n     * The normal texture used by the SSR effect.\r\n     */\r\n    public normalTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The depth texture used by the SSR effect.\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The back depth texture used by the SSR effect (optional).\r\n     * This is used when automatic thickness computation is enabled.\r\n     * The back depth texture is the depth texture of the scene rendered for the back side of the objects (that is, front faces are culled).\r\n     */\r\n    public backDepthTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The reflectivity texture used by the SSR effect\r\n     */\r\n    public reflectivityTexture: FrameGraphTextureHandle;\r\n\r\n    private _camera: Camera;\r\n\r\n    /**\r\n     * The camera used to render the scene.\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(camera: Camera) {\r\n        if (camera === this._camera) {\r\n            return;\r\n        }\r\n\r\n        this._camera = camera;\r\n\r\n        this.ssr.camera = camera;\r\n        if (this._ssr) {\r\n            this._ssr.camera = camera;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The target texture to render the SSR effect to.\r\n     */\r\n    public targetTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture of the SSR effect.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The SSR Rendering pipeline.\r\n     */\r\n    public readonly ssr: ThinSSRRenderingPipeline;\r\n\r\n    /**\r\n     * The name of the task.\r\n     */\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this._ssr) {\r\n            this._ssr.name = `${name} SSR main`;\r\n        }\r\n        if (this._ssrBlurX) {\r\n            this._ssrBlurX.name = `${name} SSR Blur X`;\r\n        }\r\n        if (this._ssrBlurY) {\r\n            this._ssrBlurY.name = `${name} SSR Blur Y`;\r\n        }\r\n        if (this._ssrBlurCombiner) {\r\n            this._ssrBlurCombiner.name = `${name} SSR Blur Combiner`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The texture type used by the different post processes created by SSR.\r\n     * It's a read-only property. If you want to change it, you must recreate the task and pass the appropriate texture type to the constructor.\r\n     */\r\n    public readonly textureType: number;\r\n\r\n    private readonly _ssr: FrameGraphSSRTask;\r\n    private readonly _ssrBlurX: FrameGraphSSRBlurTask;\r\n    private readonly _ssrBlurY: FrameGraphSSRBlurTask;\r\n    private readonly _ssrBlurCombiner: FrameGraphPostProcessTask;\r\n\r\n    /**\r\n     * Constructs a SSR rendering pipeline task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     * @param textureType The texture type used by the different post processes created by SSR (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n        super(name, frameGraph);\r\n\r\n        this.textureType = textureType;\r\n\r\n        this.ssr = new ThinSSRRenderingPipeline(name, frameGraph.scene);\r\n\r\n        this._ssr = new FrameGraphSSRTask(`${name} SSR main`, this._frameGraph, this.ssr._ssrPostProcess);\r\n        this._ssrBlurX = new FrameGraphSSRBlurTask(`${name} SSR Blur X`, this._frameGraph, this.ssr._ssrBlurXPostProcess);\r\n        this._ssrBlurY = new FrameGraphSSRBlurTask(`${name} SSR Blur Y`, this._frameGraph, this.ssr._ssrBlurYPostProcess);\r\n        this._ssrBlurCombiner = new FrameGraphPostProcessTask(`${name} SSR Blur Combiner`, this._frameGraph, this.ssr._ssrBlurCombinerPostProcess);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override isReady() {\r\n        return this.ssr.isReady();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphSSRRenderingPipelineTask\";\r\n    }\r\n\r\n    public record(): void {\r\n        if (\r\n            this.sourceTexture === undefined ||\r\n            this.normalTexture === undefined ||\r\n            this.depthTexture === undefined ||\r\n            this.reflectivityTexture === undefined ||\r\n            this.camera === undefined\r\n        ) {\r\n            throw new Error(`FrameGraphSSRRenderingPipelineTask \"${this.name}\": sourceTexture, normalTexture, depthTexture, reflectivityTexture and camera are required`);\r\n        }\r\n\r\n        const sourceTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.sourceTexture);\r\n\r\n        this._ssr.sourceTexture = this.sourceTexture;\r\n        this._ssr.sourceSamplingMode = this.sourceSamplingMode;\r\n        this._ssr.camera = this.camera;\r\n        this._ssr.normalTexture = this.normalTexture;\r\n        this._ssr.depthTexture = this.depthTexture;\r\n        this._ssr.backDepthTexture = this.backDepthTexture;\r\n        this._ssr.reflectivityTexture = this.reflectivityTexture;\r\n\r\n        let ssrTextureHandle: FrameGraphTextureHandle | undefined;\r\n\r\n        const textureSize = {\r\n            width: Math.floor(sourceTextureDescription.size.width / (this.ssr.ssrDownsample + 1)) || 1,\r\n            height: Math.floor(sourceTextureDescription.size.height / (this.ssr.ssrDownsample + 1)) || 1,\r\n        };\r\n        const textureCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: textureSize,\r\n            options: {\r\n                createMipMaps: false,\r\n                types: [this.textureType],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                samples: 1,\r\n                useSRGBBuffers: [false],\r\n                labels: [\"\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n        };\r\n\r\n        if (this.ssr.blurDispersionStrength > 0 || !this.targetTexture) {\r\n            ssrTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._ssr.name, textureCreationOptions);\r\n        }\r\n\r\n        if (this.ssr.blurDispersionStrength === 0) {\r\n            this._ssr.targetTexture = this.outputTexture;\r\n\r\n            if (ssrTextureHandle !== undefined) {\r\n                this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, ssrTextureHandle);\r\n            } else {\r\n                this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);\r\n            }\r\n\r\n            this._ssr.record(true);\r\n        } else {\r\n            this._ssr.targetTexture = ssrTextureHandle;\r\n            this._ssr.record(true);\r\n\r\n            textureSize.width = Math.floor(sourceTextureDescription.size.width / (this.ssr.blurDownsample + 1)) || 1;\r\n            textureSize.height = Math.floor(sourceTextureDescription.size.height / (this.ssr.blurDownsample + 1)) || 1;\r\n\r\n            const sourceTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.sourceTexture);\r\n\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture, this.name + \" Output\", sourceTextureCreationOptions);\r\n\r\n            const blurXTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._ssrBlurX.name, textureCreationOptions);\r\n\r\n            this._ssrBlurX.sourceTexture = ssrTextureHandle!;\r\n            this._ssrBlurX.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n            this._ssrBlurX.targetTexture = blurXTextureHandle;\r\n            this._ssrBlurX.record(true);\r\n\r\n            const blurYTextureHandle = this._frameGraph.textureManager.createRenderTargetTexture(this._ssrBlurY.name, textureCreationOptions);\r\n\r\n            this._ssrBlurY.sourceTexture = blurXTextureHandle;\r\n            this._ssrBlurY.sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n            this._ssrBlurY.targetTexture = blurYTextureHandle;\r\n            this._ssrBlurY.record(true);\r\n\r\n            this._ssrBlurCombiner.sourceTexture = this.sourceTexture;\r\n            this._ssrBlurCombiner.sourceSamplingMode = this.sourceSamplingMode;\r\n            this._ssrBlurCombiner.targetTexture = this.outputTexture;\r\n            const combinerPass = this._ssrBlurCombiner.record(true, undefined, (context) => {\r\n                context.bindTextureHandle(this._ssrBlurCombiner.drawWrapper.effect!, \"mainSampler\", this.sourceTexture);\r\n                context.bindTextureHandle(this._ssrBlurCombiner.drawWrapper.effect!, \"textureSampler\", blurYTextureHandle);\r\n                context.bindTextureHandle(this._ssrBlurCombiner.drawWrapper.effect!, \"reflectivitySampler\", this.reflectivityTexture);\r\n                if (this.ssr.useFresnel) {\r\n                    context.bindTextureHandle(this._ssrBlurCombiner.drawWrapper.effect!, \"normalSampler\", this.normalTexture);\r\n                    context.bindTextureHandle(this._ssrBlurCombiner.drawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n                }\r\n            });\r\n\r\n            combinerPass.addDependencies(blurYTextureHandle);\r\n        }\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.addDependencies(this.sourceTexture);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((context) => {\r\n            if (this.alphaMode === Constants.ALPHA_DISABLE) {\r\n                context.copyTexture(this.sourceTexture);\r\n            }\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this._ssr.dispose();\r\n        this._ssrBlurX.dispose();\r\n        this._ssrBlurY.dispose();\r\n        this._ssrBlurCombiner.dispose();\r\n        this.ssr.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type Scene,\r\n    type FrameGraph,\r\n    type NodeRenderGraphConnectionPoint,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraphTextureHandle,\r\n    type Camera,\r\n    type NodeRenderGraphGeometryRendererBlock,\r\n} from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphSSRRenderingPipelineTask } from \"../../../Tasks/PostProcesses/ssrRenderingPipelineTask\";\r\nimport { NodeRenderGraphBasePostProcessBlock } from \"./basePostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the SSR post process\r\n */\r\nexport class NodeRenderGraphSSRPostProcessBlock extends NodeRenderGraphBasePostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphSSRRenderingPipelineTask;\r\n\r\n    public override _additionalConstructionParameters: [number];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphSSRPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param textureType The texture type used by the different post processes created by SSR (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [textureType];\r\n\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"geomDepth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"geomNormal\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"geomReflectivity\", NodeRenderGraphBlockConnectionPointTypes.TextureReflectivity);\r\n        this.registerInput(\"geomBackDepth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.geomNormal.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureWorldNormal | NodeRenderGraphBlockConnectionPointTypes.TextureViewNormal\r\n        );\r\n        this.geomDepth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth | NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth\r\n        );\r\n        this.geomBackDepth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth | NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth\r\n        );\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphSSRRenderingPipelineTask(this.name, frameGraph, textureType);\r\n    }\r\n\r\n    private _createTask(textureType: number) {\r\n        const sourceSamplingMode = this.sourceSamplingMode;\r\n        const maxDistance = this.maxDistance;\r\n        const step = this.step;\r\n        const thickness = this.thickness;\r\n        const strength = this.strength;\r\n        const reflectionSpecularFalloffExponent = this.reflectionSpecularFalloffExponent;\r\n        const maxSteps = this.maxSteps;\r\n        const roughnessFactor = this.roughnessFactor;\r\n        const selfCollisionNumSkip = this.selfCollisionNumSkip;\r\n        const reflectivityThreshold = this.reflectivityThreshold;\r\n        const ssrDownsample = this.ssrDownsample;\r\n        const blurDispersionStrength = this.blurDispersionStrength;\r\n        const blurDownsample = this.blurDownsample;\r\n        const enableSmoothReflections = this.enableSmoothReflections;\r\n        const attenuateScreenBorders = this.attenuateScreenBorders;\r\n        const attenuateIntersectionDistance = this.attenuateIntersectionDistance;\r\n        const attenuateIntersectionIterations = this.attenuateIntersectionIterations;\r\n        const attenuateFacingCamera = this.attenuateFacingCamera;\r\n        const attenuateBackfaceReflection = this.attenuateBackfaceReflection;\r\n        const clipToFrustum = this.clipToFrustum;\r\n        const enableAutomaticThicknessComputation = this.enableAutomaticThicknessComputation;\r\n        const useFresnel = this.useFresnel;\r\n        const inputTextureColorIsInGammaSpace = this.inputTextureColorIsInGammaSpace;\r\n        const generateOutputInGammaSpace = this.generateOutputInGammaSpace;\r\n        const debug = this.debug;\r\n\r\n        this._frameGraphTask.dispose();\r\n        this._frameGraphTask = new FrameGraphSSRRenderingPipelineTask(this.name, this._frameGraph, textureType);\r\n\r\n        this.sourceSamplingMode = sourceSamplingMode;\r\n        this.maxDistance = maxDistance;\r\n        this.step = step;\r\n        this.thickness = thickness;\r\n        this.strength = strength;\r\n        this.reflectionSpecularFalloffExponent = reflectionSpecularFalloffExponent;\r\n        this.maxSteps = maxSteps;\r\n        this.roughnessFactor = roughnessFactor;\r\n        this.selfCollisionNumSkip = selfCollisionNumSkip;\r\n        this.reflectivityThreshold = reflectivityThreshold;\r\n        this.ssrDownsample = ssrDownsample;\r\n        this.blurDispersionStrength = blurDispersionStrength;\r\n        this.blurDownsample = blurDownsample;\r\n        this.enableSmoothReflections = enableSmoothReflections;\r\n        this.attenuateScreenBorders = attenuateScreenBorders;\r\n        this.attenuateIntersectionDistance = attenuateIntersectionDistance;\r\n        this.attenuateIntersectionIterations = attenuateIntersectionIterations;\r\n        this.attenuateFacingCamera = attenuateFacingCamera;\r\n        this.attenuateBackfaceReflection = attenuateBackfaceReflection;\r\n        this.clipToFrustum = clipToFrustum;\r\n        this.useFresnel = useFresnel;\r\n        this.enableAutomaticThicknessComputation = enableAutomaticThicknessComputation;\r\n        this.inputTextureColorIsInGammaSpace = inputTextureColorIsInGammaSpace;\r\n        this.generateOutputInGammaSpace = generateOutputInGammaSpace;\r\n        this.debug = debug;\r\n\r\n        this._additionalConstructionParameters = [textureType];\r\n    }\r\n\r\n    /** The texture type used by the different post processes created by SSR */\r\n    @editableInPropertyPage(\"Texture type\", PropertyTypeForEdition.TextureType, \"SSR\")\r\n    public get textureType() {\r\n        return this._frameGraphTask.textureType;\r\n    }\r\n\r\n    public set textureType(value: number) {\r\n        this._createTask(value);\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the effect should be rendered in debug mode */\r\n    @editableInPropertyPage(\"Debug\", PropertyTypeForEdition.Boolean, \"SSR\")\r\n    public get debug() {\r\n        return this._frameGraphTask.ssr.debug;\r\n    }\r\n\r\n    public set debug(value: boolean) {\r\n        this._frameGraphTask.ssr.debug = value;\r\n    }\r\n\r\n    /** Gets or sets the current reflection strength. 1.0 is an ideal value but can be increased/decreased for particular results */\r\n    @editableInPropertyPage(\"Strength\", PropertyTypeForEdition.Float, \"SSR\", { min: 0, max: 5 })\r\n    public get strength() {\r\n        return this._frameGraphTask.ssr.strength;\r\n    }\r\n\r\n    public set strength(value: number) {\r\n        this._frameGraphTask.ssr.strength = value;\r\n    }\r\n\r\n    /** Gets or sets the falloff exponent used to compute the reflection strength. Higher values lead to fainter reflections */\r\n    @editableInPropertyPage(\"Reflection exponent\", PropertyTypeForEdition.Float, \"SSR\", { min: 0, max: 5 })\r\n    public get reflectionSpecularFalloffExponent() {\r\n        return this._frameGraphTask.ssr.reflectionSpecularFalloffExponent;\r\n    }\r\n\r\n    public set reflectionSpecularFalloffExponent(value: number) {\r\n        this._frameGraphTask.ssr.reflectionSpecularFalloffExponent = value;\r\n    }\r\n\r\n    /** Gets or sets the minimum value for one of the reflectivity component of the material to consider it for SSR */\r\n    @editableInPropertyPage(\"Reflectivity threshold\", PropertyTypeForEdition.Float, \"SSR\", { min: 0, max: 1 })\r\n    public get reflectivityThreshold() {\r\n        return this._frameGraphTask.ssr.reflectivityThreshold;\r\n    }\r\n\r\n    public set reflectivityThreshold(value: number) {\r\n        this._frameGraphTask.ssr.reflectivityThreshold = value;\r\n    }\r\n\r\n    /** Gets or sets the thickness value used as tolerance when computing the intersection between the reflected ray and the scene */\r\n    @editableInPropertyPage(\"Thickness\", PropertyTypeForEdition.Float, \"SSR\", { min: 0, max: 10 })\r\n    public get thickness() {\r\n        return this._frameGraphTask.ssr.thickness;\r\n    }\r\n\r\n    public set thickness(value: number) {\r\n        this._frameGraphTask.ssr.thickness = value;\r\n    }\r\n\r\n    /** Gets or sets the step size used to iterate until the effect finds the color of the reflection's pixel */\r\n    @editableInPropertyPage(\"Step\", PropertyTypeForEdition.Int, \"SSR\", { min: 1, max: 50 })\r\n    public get step() {\r\n        return this._frameGraphTask.ssr.step;\r\n    }\r\n\r\n    public set step(value: number) {\r\n        this._frameGraphTask.ssr.step = value;\r\n    }\r\n\r\n    /** Gets or sets whether or not smoothing reflections is enabled */\r\n    @editableInPropertyPage(\"Smooth reflections\", PropertyTypeForEdition.Boolean, \"SSR\")\r\n    public get enableSmoothReflections() {\r\n        return this._frameGraphTask.ssr.enableSmoothReflections;\r\n    }\r\n\r\n    public set enableSmoothReflections(value: boolean) {\r\n        this._frameGraphTask.ssr.enableSmoothReflections = value;\r\n    }\r\n\r\n    /** Maximum number of steps during the ray marching process after which we consider an intersection could not be found */\r\n    @editableInPropertyPage(\"Max steps\", PropertyTypeForEdition.Int, \"SSR\", { min: 1, max: 3000 })\r\n    public get maxSteps() {\r\n        return this._frameGraphTask.ssr.maxSteps;\r\n    }\r\n\r\n    public set maxSteps(value: number) {\r\n        this._frameGraphTask.ssr.maxSteps = value;\r\n    }\r\n\r\n    /** Gets or sets the max distance used to define how far we look for reflection during the ray-marching on the reflected ray */\r\n    @editableInPropertyPage(\"Max distance\", PropertyTypeForEdition.Float, \"SSR\", { min: 1, max: 3000 })\r\n    public get maxDistance() {\r\n        return this._frameGraphTask.ssr.maxDistance;\r\n    }\r\n\r\n    public set maxDistance(value: number) {\r\n        this._frameGraphTask.ssr.maxDistance = value;\r\n    }\r\n\r\n    /** Gets or sets the factor applied when computing roughness */\r\n    @editableInPropertyPage(\"Roughness factor\", PropertyTypeForEdition.Float, \"SSR\", { min: 0, max: 1 })\r\n    public get roughnessFactor() {\r\n        return this._frameGraphTask.ssr.roughnessFactor;\r\n    }\r\n\r\n    public set roughnessFactor(value: number) {\r\n        this._frameGraphTask.ssr.roughnessFactor = value;\r\n    }\r\n\r\n    /** Number of steps to skip at start when marching the ray to avoid self collisions */\r\n    @editableInPropertyPage(\"Self collision skips\", PropertyTypeForEdition.Int, \"SSR\", { min: 1, max: 10 })\r\n    public get selfCollisionNumSkip() {\r\n        return this._frameGraphTask.ssr.selfCollisionNumSkip;\r\n    }\r\n\r\n    public set selfCollisionNumSkip(value: number) {\r\n        this._frameGraphTask.ssr.selfCollisionNumSkip = value;\r\n    }\r\n\r\n    /** Gets or sets the downsample factor used to reduce the size of the texture used to compute the SSR contribution */\r\n    @editableInPropertyPage(\"SSR downsample\", PropertyTypeForEdition.Int, \"SSR\", { min: 0, max: 5 })\r\n    public get ssrDownsample() {\r\n        return this._frameGraphTask.ssr.ssrDownsample;\r\n    }\r\n\r\n    public set ssrDownsample(value: number) {\r\n        this._frameGraphTask.ssr.ssrDownsample = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the ray should be clipped to the frustum */\r\n    @editableInPropertyPage(\"Clip to frustum\", PropertyTypeForEdition.Boolean, \"SSR\")\r\n    public get clipToFrustum() {\r\n        return this._frameGraphTask.ssr.clipToFrustum;\r\n    }\r\n\r\n    public set clipToFrustum(value: boolean) {\r\n        this._frameGraphTask.ssr.clipToFrustum = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean defining if geometry thickness should be computed automatically */\r\n    @editableInPropertyPage(\"Automatic thickness computation\", PropertyTypeForEdition.Boolean, \"SSR\")\r\n    public get enableAutomaticThicknessComputation() {\r\n        return this._frameGraphTask.ssr.enableAutomaticThicknessComputation;\r\n    }\r\n\r\n    public set enableAutomaticThicknessComputation(value: boolean) {\r\n        this._frameGraphTask.ssr.enableAutomaticThicknessComputation = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating whether the blending between the current color pixel and the reflection color should be done with a Fresnel coefficient */\r\n    @editableInPropertyPage(\"Use Fresnel\", PropertyTypeForEdition.Boolean, \"SSR\")\r\n    public get useFresnel() {\r\n        return this._frameGraphTask.ssr.useFresnel;\r\n    }\r\n\r\n    public set useFresnel(value: boolean) {\r\n        this._frameGraphTask.ssr.useFresnel = value;\r\n    }\r\n\r\n    /** Gets or sets the blur dispersion strength. Set this value to 0 to disable blurring */\r\n    @editableInPropertyPage(\"Strength\", PropertyTypeForEdition.Float, \"Blur\", { min: 0, max: 0.15 })\r\n    public get blurDispersionStrength() {\r\n        return this._frameGraphTask.ssr.blurDispersionStrength;\r\n    }\r\n\r\n    public set blurDispersionStrength(value: number) {\r\n        this._frameGraphTask.ssr.blurDispersionStrength = value;\r\n    }\r\n\r\n    /** Gets or sets the downsample factor used to reduce the size of the textures used to blur the reflection effect */\r\n    @editableInPropertyPage(\"Blur downsample\", PropertyTypeForEdition.Int, \"Blur\", { min: 0, max: 5 })\r\n    public get blurDownsample() {\r\n        return this._frameGraphTask.ssr.blurDownsample;\r\n    }\r\n\r\n    public set blurDownsample(value: number) {\r\n        this._frameGraphTask.ssr.blurDownsample = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the reflections should be attenuated at the screen borders */\r\n    @editableInPropertyPage(\"Screen borders\", PropertyTypeForEdition.Boolean, \"Attenuations\")\r\n    public get attenuateScreenBorders() {\r\n        return this._frameGraphTask.ssr.attenuateScreenBorders;\r\n    }\r\n\r\n    public set attenuateScreenBorders(value: boolean) {\r\n        this._frameGraphTask.ssr.attenuateScreenBorders = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the reflections should be attenuated according to the distance of the intersection */\r\n    @editableInPropertyPage(\"Distance\", PropertyTypeForEdition.Boolean, \"Attenuations\")\r\n    public get attenuateIntersectionDistance() {\r\n        return this._frameGraphTask.ssr.attenuateIntersectionDistance;\r\n    }\r\n\r\n    public set attenuateIntersectionDistance(value: boolean) {\r\n        this._frameGraphTask.ssr.attenuateIntersectionDistance = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the reflections should be attenuated according to the number of iterations performed to find the intersection */\r\n    @editableInPropertyPage(\"Step iterations\", PropertyTypeForEdition.Boolean, \"Attenuations\")\r\n    public get attenuateIntersectionIterations() {\r\n        return this._frameGraphTask.ssr.attenuateIntersectionIterations;\r\n    }\r\n\r\n    public set attenuateIntersectionIterations(value: boolean) {\r\n        this._frameGraphTask.ssr.attenuateIntersectionIterations = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the reflections should be attenuated when the reflection ray is facing the camera (the view direction) */\r\n    @editableInPropertyPage(\"Facing camera\", PropertyTypeForEdition.Boolean, \"Attenuations\")\r\n    public get attenuateFacingCamera() {\r\n        return this._frameGraphTask.ssr.attenuateFacingCamera;\r\n    }\r\n\r\n    public set attenuateFacingCamera(value: boolean) {\r\n        this._frameGraphTask.ssr.attenuateFacingCamera = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the backface reflections should be attenuated */\r\n    @editableInPropertyPage(\"Backface reflections\", PropertyTypeForEdition.Boolean, \"Attenuations\")\r\n    public get attenuateBackfaceReflection() {\r\n        return this._frameGraphTask.ssr.attenuateBackfaceReflection;\r\n    }\r\n\r\n    public set attenuateBackfaceReflection(value: boolean) {\r\n        this._frameGraphTask.ssr.attenuateBackfaceReflection = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean defining if the input color texture is in gamma space */\r\n    @editableInPropertyPage(\"Input is in gamma space\", PropertyTypeForEdition.Boolean, \"Color space\")\r\n    public get inputTextureColorIsInGammaSpace() {\r\n        return this._frameGraphTask.ssr.inputTextureColorIsInGammaSpace;\r\n    }\r\n\r\n    public set inputTextureColorIsInGammaSpace(value: boolean) {\r\n        this._frameGraphTask.ssr.inputTextureColorIsInGammaSpace = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean defining if the output color texture generated by the SSR pipeline should be in gamma space */\r\n    @editableInPropertyPage(\"Output to gamma space\", PropertyTypeForEdition.Boolean, \"Color space\")\r\n    public get generateOutputInGammaSpace() {\r\n        return this._frameGraphTask.ssr.generateOutputInGammaSpace;\r\n    }\r\n\r\n    public set generateOutputInGammaSpace(value: boolean) {\r\n        this._frameGraphTask.ssr.generateOutputInGammaSpace = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphSSRPostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry depth input component\r\n     */\r\n    public get geomDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry normal input component\r\n     */\r\n    public get geomNormal(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry reflectivity input component\r\n     */\r\n    public get geomReflectivity(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry back depth input component\r\n     */\r\n    public get geomBackDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.normalTexture = this.geomNormal.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.depthTexture = this.geomDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.reflectivityTexture = this.geomReflectivity.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.backDepthTexture = this.geomBackDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n\r\n        if (this.enableAutomaticThicknessComputation) {\r\n            if (!this._frameGraphTask.backDepthTexture) {\r\n                throw new Error(`SSR post process \"${this.name}\": Automatic thickness computation requires a back depth texture to be connected!`);\r\n            }\r\n\r\n            const geomBackDepthOwnerBlock = this.geomBackDepth.connectedPoint!.ownerBlock;\r\n            if (geomBackDepthOwnerBlock.getClassName() === \"NodeRenderGraphGeometryRendererBlock\") {\r\n                const geometryBackFaceRendererBlock = geomBackDepthOwnerBlock as NodeRenderGraphGeometryRendererBlock;\r\n                if (!geometryBackFaceRendererBlock.reverseCulling) {\r\n                    throw new Error(\r\n                        `SSR post process \"${this.name}\": Automatic thickness computation requires the geometry renderer block for the back depth texture to have reverse culling enabled!`\r\n                    );\r\n                }\r\n\r\n                if (this._frameGraphTask.depthTexture) {\r\n                    const geomDepthOwnerBlock = this.geomDepth.connectedPoint!.ownerBlock;\r\n                    if (geomDepthOwnerBlock.getClassName() === \"NodeRenderGraphGeometryRendererBlock\") {\r\n                        const geomDepthConnectionPointType = this.geomDepth.connectedPoint!.type;\r\n                        const geomBackDepthConnectionPointType = this.geomBackDepth.connectedPoint!.type;\r\n\r\n                        if (geomDepthConnectionPointType !== geomBackDepthConnectionPointType) {\r\n                            throw new Error(\r\n                                `SSR post process \"${this.name}\": Automatic thickness computation requires that geomDepth and geomBackDepth have the same type (view or screen space depth)!`\r\n                            );\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this.geomNormal.connectedPoint) {\r\n            if (this.geomNormal.connectedPoint.type === NodeRenderGraphBlockConnectionPointTypes.TextureWorldNormal) {\r\n                this._frameGraphTask.ssr.normalsAreInWorldSpace = true;\r\n                this._frameGraphTask.ssr.normalsAreUnsigned = true;\r\n            }\r\n        }\r\n        if (this.geomDepth.connectedPoint) {\r\n            if (this.geomDepth.connectedPoint.type === NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth) {\r\n                this._frameGraphTask.ssr.useScreenspaceDepth = true;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.debug = ${this.debug};`);\r\n        codes.push(`${this._codeVariableName}.strength = ${this.strength};`);\r\n        codes.push(`${this._codeVariableName}.reflectionSpecularFalloffExponent = ${this.reflectionSpecularFalloffExponent};`);\r\n        codes.push(`${this._codeVariableName}.reflectivityThreshold = ${this.reflectivityThreshold};`);\r\n        codes.push(`${this._codeVariableName}.thickness = ${this.thickness};`);\r\n        codes.push(`${this._codeVariableName}.step = ${this.step};`);\r\n        codes.push(`${this._codeVariableName}.enableSmoothReflections = ${this.enableSmoothReflections};`);\r\n        codes.push(`${this._codeVariableName}.maxSteps = ${this.maxSteps};`);\r\n        codes.push(`${this._codeVariableName}.maxDistance = ${this.maxDistance};`);\r\n        codes.push(`${this._codeVariableName}.roughnessFactor = ${this.roughnessFactor};`);\r\n        codes.push(`${this._codeVariableName}.selfCollisionNumSkip = ${this.selfCollisionNumSkip};`);\r\n        codes.push(`${this._codeVariableName}.ssrDownsample = ${this.ssrDownsample};`);\r\n        codes.push(`${this._codeVariableName}.clipToFrustum = ${this.clipToFrustum};`);\r\n        codes.push(`${this._codeVariableName}.useFresnel = ${this.useFresnel};`);\r\n        codes.push(`${this._codeVariableName}.enableAutomaticThicknessComputation = ${this.enableAutomaticThicknessComputation};`);\r\n        codes.push(`${this._codeVariableName}.blurDispersionStrength = ${this.blurDispersionStrength};`);\r\n        codes.push(`${this._codeVariableName}.blurDownsample = ${this.blurDownsample};`);\r\n        codes.push(`${this._codeVariableName}.attenuateScreenBorders = ${this.attenuateScreenBorders};`);\r\n        codes.push(`${this._codeVariableName}.attenuateIntersectionDistance = ${this.attenuateIntersectionDistance};`);\r\n        codes.push(`${this._codeVariableName}.attenuateIntersectionIterations = ${this.attenuateIntersectionIterations};`);\r\n        codes.push(`${this._codeVariableName}.attenuateFacingCamera = ${this.attenuateFacingCamera};`);\r\n        codes.push(`${this._codeVariableName}.attenuateBackfaceReflection = ${this.attenuateBackfaceReflection};`);\r\n        codes.push(`${this._codeVariableName}.inputTextureColorIsInGammaSpace = ${this.inputTextureColorIsInGammaSpace};`);\r\n        codes.push(`${this._codeVariableName}.generateOutputInGammaSpace = ${this.generateOutputInGammaSpace};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.debug = this.debug;\r\n        serializationObject.strength = this.strength;\r\n        serializationObject.reflectionSpecularFalloffExponent = this.reflectionSpecularFalloffExponent;\r\n        serializationObject.reflectivityThreshold = this.reflectivityThreshold;\r\n        serializationObject.thickness = this.thickness;\r\n        serializationObject.step = this.step;\r\n        serializationObject.enableSmoothReflections = this.enableSmoothReflections;\r\n        serializationObject.maxSteps = this.maxSteps;\r\n        serializationObject.maxDistance = this.maxDistance;\r\n        serializationObject.roughnessFactor = this.roughnessFactor;\r\n        serializationObject.selfCollisionNumSkip = this.selfCollisionNumSkip;\r\n        serializationObject.ssrDownsample = this.ssrDownsample;\r\n        serializationObject.clipToFrustum = this.clipToFrustum;\r\n        serializationObject.useFresnel = this.useFresnel;\r\n        serializationObject.enableAutomaticThicknessComputation = this.enableAutomaticThicknessComputation;\r\n        serializationObject.blurDispersionStrength = this.blurDispersionStrength;\r\n        serializationObject.blurDownsample = this.blurDownsample;\r\n        serializationObject.attenuateScreenBorders = this.attenuateScreenBorders;\r\n        serializationObject.attenuateIntersectionDistance = this.attenuateIntersectionDistance;\r\n        serializationObject.attenuateIntersectionIterations = this.attenuateIntersectionIterations;\r\n        serializationObject.attenuateFacingCamera = this.attenuateFacingCamera;\r\n        serializationObject.attenuateBackfaceReflection = this.attenuateBackfaceReflection;\r\n        serializationObject.inputTextureColorIsInGammaSpace = this.inputTextureColorIsInGammaSpace;\r\n        serializationObject.generateOutputInGammaSpace = this.generateOutputInGammaSpace;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.debug = serializationObject.debug;\r\n        this.strength = serializationObject.strength;\r\n        this.reflectionSpecularFalloffExponent = serializationObject.reflectionSpecularFalloffExponent;\r\n        this.reflectivityThreshold = serializationObject.reflectivityThreshold;\r\n        this.thickness = serializationObject.thickness;\r\n        this.step = serializationObject.step;\r\n        this.enableSmoothReflections = serializationObject.enableSmoothReflections;\r\n        this.maxSteps = serializationObject.maxSteps;\r\n        this.maxDistance = serializationObject.maxDistance;\r\n        this.roughnessFactor = serializationObject.roughnessFactor;\r\n        this.selfCollisionNumSkip = serializationObject.selfCollisionNumSkip;\r\n        this.ssrDownsample = serializationObject.ssrDownsample;\r\n        this.clipToFrustum = serializationObject.clipToFrustum;\r\n        this.useFresnel = serializationObject.useFresnel;\r\n        this.enableAutomaticThicknessComputation = serializationObject.enableAutomaticThicknessComputation;\r\n        this.blurDispersionStrength = serializationObject.blurDispersionStrength;\r\n        this.blurDownsample = serializationObject.blurDownsample;\r\n        this.attenuateScreenBorders = serializationObject.attenuateScreenBorders;\r\n        this.attenuateIntersectionDistance = serializationObject.attenuateIntersectionDistance;\r\n        this.attenuateIntersectionIterations = serializationObject.attenuateIntersectionIterations;\r\n        this.attenuateFacingCamera = serializationObject.attenuateFacingCamera;\r\n        this.attenuateBackfaceReflection = serializationObject.attenuateBackfaceReflection;\r\n        this.inputTextureColorIsInGammaSpace = serializationObject.inputTextureColorIsInGammaSpace;\r\n        this.generateOutputInGammaSpace = serializationObject.generateOutputInGammaSpace;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ssrPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSsrPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphSSRPostProcessBlock\", NodeRenderGraphSSRPostProcessBlock);\r\n}\r\n","/**\r\n * Class for generating 2D Halton sequences.\r\n * From https://observablehq.com/@jrus/halton\r\n */\r\nexport class Halton2DSequence {\r\n    private _curIndex = 0;\r\n    private _sequence: number[] = [];\r\n    private _numSamples = 0;\r\n    private _width: number;\r\n    private _height: number;\r\n    private _baseX;\r\n    private _baseY;\r\n\r\n    /**\r\n     * The x coordinate of the current sample.\r\n     */\r\n    public readonly x = 0;\r\n\r\n    /**\r\n     * The y coordinate of the current sample.\r\n     */\r\n    public readonly y = 0;\r\n\r\n    /**\r\n     * Creates a new Halton2DSequence.\r\n     * @param numSamples Number of samples in the sequence.\r\n     * @param baseX The base for the x coordinate (default: 2).\r\n     * @param baseY The base for the y coordinate (default: 3).\r\n     * @param width Factor to scale the x coordinate by (default: 1). The scaling factor is 1/width.\r\n     * @param height Factor to scale the y coordinate by (default: 1). The scaling factor is 1/height.\r\n     */\r\n    constructor(numSamples: number, baseX = 2, baseY = 3, width = 1, height = 1) {\r\n        this._width = width;\r\n        this._height = height;\r\n        this._baseX = baseX;\r\n        this._baseY = baseY;\r\n\r\n        this._generateSequence(numSamples);\r\n        this.next();\r\n    }\r\n\r\n    /**\r\n     * Regenerates the sequence with a new number of samples.\r\n     * @param numSamples Number of samples in the sequence.\r\n     */\r\n    public regenerate(numSamples: number) {\r\n        this._generateSequence(numSamples);\r\n        this.next();\r\n    }\r\n\r\n    /**\r\n     * Sets the dimensions of the sequence.\r\n     * @param width Factor to scale the x coordinate by. The scaling factor is 1/width.\r\n     * @param height Factor to scale the y coordinate by. The scaling factor is 1/height.\r\n     */\r\n    public setDimensions(width: number, height: number) {\r\n        this._width = width;\r\n        this._height = height;\r\n    }\r\n\r\n    /**\r\n     * Advances to the next sample in the sequence.\r\n     */\r\n    public next() {\r\n        (this.x as number) = this._sequence[this._curIndex] / this._width;\r\n        (this.y as number) = this._sequence[this._curIndex + 1] / this._height;\r\n\r\n        this._curIndex += 2;\r\n\r\n        if (this._curIndex >= this._numSamples * 2) {\r\n            this._curIndex = 0;\r\n        }\r\n    }\r\n\r\n    private _generateSequence(numSamples: number) {\r\n        this._sequence = [];\r\n        this._curIndex = 0;\r\n        this._numSamples = numSamples;\r\n\r\n        for (let i = 1; i <= numSamples; ++i) {\r\n            this._sequence.push(this._halton(i, this._baseX) - 0.5, this._halton(i, this._baseY) - 0.5);\r\n        }\r\n    }\r\n\r\n    private _halton(index: number, base: number) {\r\n        let fraction = 1;\r\n        let result = 0;\r\n        while (index > 0) {\r\n            fraction /= base;\r\n            result += fraction * (index % base);\r\n            index = ~~(index / base); // floor division\r\n        }\r\n        return result;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Material } from \"core/Materials/material.pure\";\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase.pure\";\nimport { RegisterMaterialPlugin, UnregisterMaterialPlugin } from \"core/Materials/materialPluginManager.pure\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\nimport { type Scene } from \"core/scene.pure\";\nimport { type Nullable } from \"core/types\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\n\nclass TAAJitterMaterialDefines extends MaterialDefines {\n    TAA_JITTER = false;\n}\n\nclass TAAJitterMaterialPlugin extends MaterialPluginBase {\n    public static readonly Name = \"TAAJitter\";\n\n    private _manager: Nullable<TAAMaterialManager>;\n    public get manager(): Nullable<TAAMaterialManager> {\n        return this._manager;\n    }\n\n    public set manager(manager: Nullable<TAAMaterialManager>) {\n        if (this._manager === manager) {\n            return;\n        }\n        this.dispose();\n        this._manager = manager;\n        manager?._materialPlugins.push(this);\n        this._updateMaterial();\n    }\n\n    public get isEnabled(): boolean {\n        return this._manager?.isEnabled ?? false;\n    }\n\n    constructor(material: Material) {\n        super(material, TAAJitterMaterialPlugin.Name, 300, new TAAJitterMaterialDefines());\n        this.registerForExtraEvents = true;\n        this.doNotSerialize = true;\n    }\n\n    /** @internal */\n    public _updateMaterial(): void {\n        this._enable(this.isEnabled);\n        this.markAllDefinesAsDirty();\n    }\n\n    public override isCompatible(): boolean {\n        return true;\n    }\n\n    public override getClassName(): string {\n        return \"TAAJitterMaterialPlugin\";\n    }\n\n    public override prepareDefines(defines: TAAJitterMaterialDefines): void {\n        defines.TAA_JITTER = this.isEnabled;\n    }\n\n    public override getUniforms(shaderLanguage = ShaderLanguage.GLSL) {\n        const ubo = [{ name: \"taa_jitter\", size: 2, type: \"vec2\" }];\n        if (shaderLanguage === ShaderLanguage.GLSL) {\n            return {\n                ubo,\n                vertex: `\n                    #ifdef TAA_JITTER\n                    uniform vec2 taa_jitter;\n                    #endif\n                `,\n            };\n        } else {\n            return { ubo };\n        }\n    }\n\n    public override hardBindForSubMesh(uniformBuffer: UniformBuffer): void {\n        if (this.isEnabled) {\n            const jitter = this._manager!.jitter;\n            uniformBuffer.updateFloat2(\"taa_jitter\", jitter.x, jitter.y);\n        }\n    }\n\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL) {\n        // We jitter instead of modifying the camera so the velocity buffer stays unaffected\n        // More info: https://sugulee.wordpress.com/2021/06/21/temporal-anti-aliasingtaa-tutorial/\n        if (shaderType !== \"vertex\") {\n            return null;\n        } else if (shaderLanguage === ShaderLanguage.WGSL) {\n            return {\n                CUSTOM_VERTEX_MAIN_END: `\n                    #ifdef TAA_JITTER\n                    vertexOutputs.position += vec4f(uniforms.taa_jitter * vertexOutputs.position.w, 0.0, 0.0);\n                    #endif\n                `,\n            };\n        } else {\n            return {\n                CUSTOM_VERTEX_MAIN_END: `\n                    #ifdef TAA_JITTER\n                    gl_Position.xy += taa_jitter * gl_Position.w;\n                    #endif\n                `,\n            };\n        }\n    }\n\n    public override dispose(): void {\n        if (this._manager) {\n            const index = this._manager._materialPlugins.indexOf(this);\n            if (index !== -1) {\n                this._manager._materialPlugins.splice(index, 1);\n            }\n        }\n    }\n}\n\n/**\n * Applies and manages the TAA jitter plugin on all materials.\n */\nexport class TAAMaterialManager {\n    private _isEnabled = true;\n    /**\n     * Set to enable or disable the jitter offset on all materials.\n     */\n    public get isEnabled(): boolean {\n        return this._isEnabled;\n    }\n\n    public set isEnabled(enabled: boolean) {\n        if (this._isEnabled === enabled) {\n            return;\n        }\n        this._isEnabled = enabled;\n        for (const plugin of this._materialPlugins) {\n            plugin._updateMaterial();\n        }\n    }\n\n    /**\n     * The current jitter offset to apply to all materials.\n     */\n    public readonly jitter = new Vector2();\n\n    /** @internal */\n    public readonly _materialPlugins: TAAJitterMaterialPlugin[] = [];\n\n    /**\n     * @param scene All materials in this scene will have a jitter offset applied to them.\n     */\n    constructor(scene: Scene) {\n        for (const material of scene.materials) {\n            this._getPlugin(material);\n        }\n        RegisterMaterialPlugin(TAAJitterMaterialPlugin.Name, (material) => this._getPlugin(material));\n    }\n\n    /**\n     * Disposes of the material manager.\n     */\n    public dispose(): void {\n        UnregisterMaterialPlugin(TAAJitterMaterialPlugin.Name);\n        const plugins = this._materialPlugins.splice(0, this._materialPlugins.length);\n        for (const plugin of plugins) {\n            plugin.manager = null;\n        }\n    }\n\n    private _getPlugin(material: Material): Nullable<TAAJitterMaterialPlugin> {\n        if (!material.pluginManager) {\n            return null;\n        }\n        let plugin = material.pluginManager.getPlugin<TAAJitterMaterialPlugin>(TAAJitterMaterialPlugin.Name);\n        if (!plugin) {\n            plugin = new TAAJitterMaterialPlugin(material);\n        }\n        plugin.manager = this;\n        return plugin;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for taaMaterialManager.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterTaaMaterialManager(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(`BABYLON.TAAJitterMaterialPlugin`, TAAJitterMaterialPlugin);\n}\n","import { type Nullable, type EffectWrapperCreationOptions, type Scene } from \"core/index\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { Halton2DSequence } from \"core/Maths/halton2DSequence\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { TAAMaterialManager } from \"./RenderPipeline/Pipelines/taaMaterialManager.pure\";\r\n\r\n/**\r\n * Simple implementation of Temporal Anti-Aliasing (TAA).\r\n * This can be used to improve image quality for still pictures (screenshots for e.g.).\r\n */\r\nexport class ThinTAAPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"taa\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"factor\"];\r\n\r\n    /**\r\n     * The list of samplers used by the effect\r\n     */\r\n    public static readonly Samplers = [\"historySampler\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/taa.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/taa.fragment\"));\r\n        }\r\n    }\r\n\r\n    private _samples = 8;\r\n    /**\r\n     * Number of accumulated samples (default: 8)\r\n     */\r\n    public set samples(samples: number) {\r\n        if (this._samples === samples) {\r\n            return;\r\n        }\r\n\r\n        this._samples = samples;\r\n        this._hs.regenerate(samples);\r\n    }\r\n\r\n    public get samples(): number {\r\n        return this._samples;\r\n    }\r\n\r\n    /**\r\n     * The factor used to blend the history frame with current frame (default: 0.05)\r\n     */\r\n    public factor = 0.05;\r\n\r\n    /**\r\n     * The camera to use for the post process\r\n     */\r\n    public camera: Nullable<Camera>;\r\n\r\n    private _disabled = false;\r\n    /**\r\n     * Whether the TAA is disabled\r\n     */\r\n    public get disabled() {\r\n        return this._disabled;\r\n    }\r\n\r\n    public set disabled(value: boolean) {\r\n        if (this._disabled === value) {\r\n            return;\r\n        }\r\n        this._disabled = value;\r\n        if (this._taaMaterialManager) {\r\n            this._taaMaterialManager.isEnabled = !value && this.reprojectHistory;\r\n        }\r\n        this._reset();\r\n    }\r\n\r\n    private _textureWidth = 0;\r\n    /**\r\n     * The width of the texture in which to render\r\n     */\r\n    public get textureWidth() {\r\n        return this._textureWidth;\r\n    }\r\n\r\n    public set textureWidth(width: number) {\r\n        if (this._textureWidth === width) {\r\n            return;\r\n        }\r\n        this._textureWidth = width;\r\n        this._reset();\r\n    }\r\n\r\n    private _textureHeight = 0;\r\n    /**\r\n     * The height of the texture in which to render\r\n     */\r\n    public get textureHeight() {\r\n        return this._textureHeight;\r\n    }\r\n\r\n    public set textureHeight(height: number) {\r\n        if (this._textureHeight === height) {\r\n            return;\r\n        }\r\n        this._textureHeight = height;\r\n        this._reset();\r\n    }\r\n\r\n    /**\r\n     * Disable TAA on camera move (default: true).\r\n     * You generally want to keep this enabled, otherwise you will get a ghost effect when the camera moves (but if it's what you want, go for it!)\r\n     */\r\n    public disableOnCameraMove = true;\r\n\r\n    private _reprojectHistory = false;\r\n    /**\r\n     * Enables reprojecting the history texture with a per-pixel velocity.\r\n     * If set the \"velocitySampler\" has to be provided.\r\n     */\r\n    public get reprojectHistory(): boolean {\r\n        return this._reprojectHistory;\r\n    }\r\n\r\n    public set reprojectHistory(reproject: boolean) {\r\n        if (this._reprojectHistory === reproject) {\r\n            return;\r\n        }\r\n        this._reprojectHistory = reproject;\r\n\r\n        if (reproject) {\r\n            if (!this._taaMaterialManager) {\r\n                this._taaMaterialManager = new TAAMaterialManager(this._scene);\r\n            }\r\n            // The velocity buffer may be old so reset for one frame\r\n            this._reset();\r\n        }\r\n\r\n        if (this._taaMaterialManager) {\r\n            this._taaMaterialManager.isEnabled = reproject && !this._disabled;\r\n        }\r\n\r\n        this._updateEffect();\r\n    }\r\n\r\n    private _clampHistory = false;\r\n    /**\r\n     * Clamps the history pixel to the min and max of the 3x3 pixels surrounding the target pixel.\r\n     * This can help further reduce ghosting and artifacts.\r\n     */\r\n    public get clampHistory(): boolean {\r\n        return this._clampHistory;\r\n    }\r\n\r\n    public set clampHistory(clamp: boolean) {\r\n        if (this._clampHistory === clamp) {\r\n            return;\r\n        }\r\n        this._clampHistory = clamp;\r\n        this._updateEffect();\r\n    }\r\n\r\n    private _scene: Scene;\r\n    private _hs: Halton2DSequence;\r\n    private _firstUpdate = true;\r\n    private _taaMaterialManager: Nullable<TAAMaterialManager>;\r\n\r\n    /**\r\n     * Constructs a new TAA post process\r\n     * @param name Name of the effect\r\n     * @param scene The scene the post process belongs to\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, scene: Scene, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: scene.getEngine(),\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinTAAPostProcess.FragmentUrl,\r\n            uniforms: ThinTAAPostProcess.Uniforms,\r\n            samplers: ThinTAAPostProcess.Samplers,\r\n        });\r\n\r\n        this._scene = scene;\r\n        this._hs = new Halton2DSequence(this.samples);\r\n    }\r\n\r\n    /** @internal */\r\n    public _reset(): void {\r\n        this._hs.setDimensions(this._textureWidth / 2, this._textureHeight / 2);\r\n        this._hs.next();\r\n        this._firstUpdate = true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateJitter() {\r\n        if (this.reprojectHistory && this._taaMaterialManager) {\r\n            // Applying jitter to the projection matrix messes with the velocity buffer,\r\n            // so we do it as a final vertex step in a material plugin instead\r\n            this._nextJitterOffset(this._taaMaterialManager.jitter);\r\n        } else {\r\n            // Use the projection matrix by default since it supports most materials\r\n            this._updateProjectionMatrix();\r\n        }\r\n    }\r\n\r\n    protected _nextJitterOffset(output = new Vector2()): Vector2 {\r\n        if (!this.camera || !this.camera.hasMoved || !this.disableOnCameraMove) {\r\n            this._hs.next();\r\n        }\r\n        output.set(this._hs.x, this._hs.y);\r\n        return output;\r\n    }\r\n\r\n    protected _updateProjectionMatrix(): void {\r\n        if (this.disabled) {\r\n            return;\r\n        }\r\n\r\n        if (this.camera && !this.camera.hasMoved) {\r\n            if (this.camera.mode === Camera.PERSPECTIVE_CAMERA) {\r\n                const projMat = this.camera.getProjectionMatrix();\r\n                projMat.setRowFromFloats(2, this._hs.x, this._hs.y, projMat.m[10], projMat.m[11]);\r\n            } else {\r\n                // We must force the update of the projection matrix so that m[12] and m[13] are recomputed, as we modified them the previous frame\r\n                const projMat = this.camera.getProjectionMatrix(true);\r\n                projMat.setRowFromFloats(3, this._hs.x + projMat.m[12], this._hs.y + projMat.m[13], projMat.m[14], projMat.m[15]);\r\n            }\r\n        }\r\n\r\n        this._hs.next();\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        if (this.disabled) {\r\n            return;\r\n        }\r\n\r\n        const effect = this._drawWrapper.effect!;\r\n\r\n        effect.setFloat(\"factor\", (this.camera?.hasMoved && this.disableOnCameraMove) || this._firstUpdate ? 1 : this.factor);\r\n\r\n        this._firstUpdate = false;\r\n    }\r\n\r\n    public override dispose() {\r\n        this._taaMaterialManager?.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    private _updateEffect(): void {\r\n        const defines: string[] = [];\r\n        // There seems to be an issue where `updateEffect` sometimes doesn't include the initial samplers\r\n        const samplers = [\"textureSampler\", \"historySampler\"];\r\n        if (this._reprojectHistory) {\r\n            defines.push(\"#define TAA_REPROJECT_HISTORY\");\r\n            samplers.push(\"velocitySampler\");\r\n        }\r\n        if (this._clampHistory) {\r\n            defines.push(\"#define TAA_CLAMP_HISTORY\");\r\n        }\r\n        this.updateEffect(defines.join(\"\\n\"), null, samplers);\r\n    }\r\n}\r\n","import {\r\n    type FrameGraph,\r\n    type FrameGraphRenderPass,\r\n    type FrameGraphObjectRendererTask,\r\n    type FrameGraphTextureCreationOptions,\r\n    type Observer,\r\n    type ObjectRenderer,\r\n    type FrameGraphTextureHandle,\r\n    type Scene,\r\n} from \"core/index\";\r\nimport { ThinTAAPostProcess } from \"core/PostProcesses/thinTAAPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\n/**\r\n * Task which applies a Temporal Anti-Aliasing post process.\r\n */\r\nexport class FrameGraphTAATask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinTAAPostProcess;\r\n\r\n    /**\r\n     * The object renderer task used to render the scene objects.\r\n     */\r\n    public objectRendererTask: FrameGraphObjectRendererTask;\r\n\r\n    /**\r\n     * The handle to the velocity texture. Only needed if postProcess.reprojectHistory is enabled.\r\n     * Note that you must use the linear velocity texture!\r\n     */\r\n    public velocityTexture?: FrameGraphTextureHandle;\r\n\r\n    protected _onBeforeRenderSceneObserver: Observer<Scene>;\r\n    protected _initRenderingObserver: Observer<ObjectRenderer>;\r\n\r\n    /**\r\n     * Constructs a new Temporal Anti-Aliasing task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the Temporal Anti-Aliasing effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinTAAPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinTAAPostProcess(name, frameGraph.scene));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphTAATask\";\r\n    }\r\n\r\n    public override record(): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.objectRendererTask === undefined) {\r\n            throw new Error(`FrameGraphPostProcessTask \"${this.name}\": sourceTexture and objectRendererTask are required`);\r\n        }\r\n\r\n        this._frameGraph.scene.onBeforeRenderObservable.remove(this._onBeforeRenderSceneObserver);\r\n        this._onBeforeRenderSceneObserver = this._frameGraph.scene.onBeforeRenderObservable.add(() => {\r\n            if (this.postProcess.reprojectHistory && !this.disabled) {\r\n                this.postProcess._updateJitter();\r\n            }\r\n        });\r\n\r\n        const objectRenderer = this.objectRendererTask.objectRenderer;\r\n\r\n        objectRenderer.onInitRenderingObservable.remove(this._initRenderingObserver);\r\n        this._initRenderingObserver = objectRenderer.onInitRenderingObservable.add(() => {\r\n            if (!this.postProcess.reprojectHistory && !this.disabled) {\r\n                this.postProcess._updateJitter();\r\n\r\n                // We pass false to this.camera.getProjectionMatrix() when TAA is enabled to avoid overwriting the projection matrix calculated by the call to this.postProcess.updateJitter()\r\n                const camera = objectRenderer.activeCamera!;\r\n                this._frameGraph.scene.setTransformMatrix(camera.getViewMatrix(), camera.getProjectionMatrix(this.postProcess.disabled));\r\n            }\r\n        });\r\n\r\n        const textureManager = this._frameGraph.textureManager;\r\n        const sourceSize = textureManager.getTextureAbsoluteDimensions(this.sourceTexture);\r\n\r\n        this._sourceWidth = this._outputWidth = sourceSize.width;\r\n        this._sourceHeight = this._outputHeight = sourceSize.height;\r\n\r\n        const renderTextureSize = textureManager.getTextureAbsoluteDimensions(this.objectRendererTask.outputTexture);\r\n\r\n        this.postProcess.textureWidth = renderTextureSize.width;\r\n        this.postProcess.textureHeight = renderTextureSize.height;\r\n\r\n        const pingPongTextureCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: sourceSize,\r\n            options: {\r\n                createMipMaps: false,\r\n                types: [Constants.TEXTURETYPE_HALF_FLOAT],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                samples: 1,\r\n                useSRGBBuffers: [false],\r\n                creationFlags: [0],\r\n                labels: [\"\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: true,\r\n        };\r\n\r\n        const pingPongHandle = textureManager.createRenderTargetTexture(`${this.name} history`, pingPongTextureCreationOptions);\r\n\r\n        textureManager.resolveDanglingHandle(this.outputTexture, pingPongHandle);\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.depthReadOnly = this.depthReadOnly;\r\n        pass.stencilReadOnly = this.stencilReadOnly;\r\n\r\n        pass.addDependencies(this.sourceTexture);\r\n\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setRenderTargetDepth(this.depthAttachmentTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            objectRenderer.dontSetTransformationMatrix = !this.postProcess.reprojectHistory;\r\n            this.postProcess.camera = objectRenderer.activeCamera;\r\n\r\n            if (this.sourceTexture !== undefined) {\r\n                context.setTextureSamplingMode(this.sourceTexture, this.sourceSamplingMode);\r\n            }\r\n            if (this.velocityTexture !== undefined) {\r\n                context.setTextureSamplingMode(this.velocityTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            }\r\n\r\n            context.setTextureSamplingMode(pingPongHandle, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n\r\n            context.applyFullScreenEffect(\r\n                this._postProcessDrawWrapper,\r\n                () => {\r\n                    context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"textureSampler\", this.sourceTexture!);\r\n                    context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"historySampler\", pingPongHandle);\r\n                    if (this.postProcess.reprojectHistory && this.velocityTexture !== undefined) {\r\n                        context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"velocitySampler\", this.velocityTexture);\r\n                    }\r\n                    this.postProcess.bind();\r\n                },\r\n                this.stencilState,\r\n                this.disableColorWrite,\r\n                this.drawBackFace,\r\n                this.depthTest\r\n            );\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.depthReadOnly = this.depthReadOnly;\r\n        passDisabled.stencilReadOnly = this.stencilReadOnly;\r\n\r\n        passDisabled.addDependencies(this.sourceTexture);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setRenderTargetDepth(this.depthAttachmentTexture);\r\n        passDisabled.setExecuteFunc((context) => {\r\n            context.copyTexture(this.sourceTexture!);\r\n        });\r\n\r\n        return pass;\r\n    }\r\n\r\n    public override dispose() {\r\n        this.objectRendererTask?.objectRenderer.onInitRenderingObservable.remove(this._initRenderingObserver);\r\n        this._frameGraph.scene.onBeforeRenderObservable.remove(this._onBeforeRenderSceneObserver);\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type NodeRenderGraphConnectionPoint,\r\n    type Scene,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraph,\r\n    type FrameGraphObjectRendererTask,\r\n    type FrameGraphTextureHandle,\r\n} from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes, NodeRenderGraphConnectionPointDirection } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphTAATask } from \"core/FrameGraph/Tasks/PostProcesses/taaTask\";\r\nimport { NodeRenderGraphConnectionPointCustomObject } from \"../../nodeRenderGraphConnectionPointCustomObject\";\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"../Rendering/baseObjectRendererBlock\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the TAA post process\r\n */\r\nexport class NodeRenderGraphTAAPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphTAATask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphTAAPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\r\n            \"objectRenderer\",\r\n            NodeRenderGraphBlockConnectionPointTypes.Object,\r\n            false,\r\n            new NodeRenderGraphConnectionPointCustomObject(\r\n                \"objectRenderer\",\r\n                this,\r\n                NodeRenderGraphConnectionPointDirection.Input,\r\n                NodeRenderGraphBaseObjectRendererBlock,\r\n                \"NodeRenderGraphBaseObjectRendererBlock\"\r\n            )\r\n        );\r\n        this.registerInput(\"geomVelocity\", NodeRenderGraphBlockConnectionPointTypes.TextureLinearVelocity, true);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphTAATask(this.name, frameGraph);\r\n    }\r\n\r\n    /** Number of accumulated samples */\r\n    @editableInPropertyPage(\"Samples\", PropertyTypeForEdition.Int, \"PROPERTIES\")\r\n    public get samples() {\r\n        return this._frameGraphTask.postProcess.samples;\r\n    }\r\n\r\n    public set samples(value: number) {\r\n        this._frameGraphTask.postProcess.samples = value;\r\n    }\r\n\r\n    /** The factor used to blend the history frame with current frame */\r\n    @editableInPropertyPage(\"Factor\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get factor() {\r\n        return this._frameGraphTask.postProcess.factor;\r\n    }\r\n\r\n    public set factor(value: number) {\r\n        this._frameGraphTask.postProcess.factor = value;\r\n    }\r\n\r\n    /** Enables reprojecting the history texture with a per-pixel velocity */\r\n    @editableInPropertyPage(\"Reproject history\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get reprojectHistory() {\r\n        return this._frameGraphTask.postProcess.reprojectHistory;\r\n    }\r\n\r\n    public set reprojectHistory(value: boolean) {\r\n        this._frameGraphTask.postProcess.reprojectHistory = value;\r\n    }\r\n\r\n    /** Clamps the history pixel to the min and max of the 3x3 pixels surrounding the target pixel */\r\n    @editableInPropertyPage(\"Clamp history\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get clampHistory() {\r\n        return this._frameGraphTask.postProcess.clampHistory;\r\n    }\r\n\r\n    public set clampHistory(value: boolean) {\r\n        this._frameGraphTask.postProcess.clampHistory = value;\r\n    }\r\n\r\n    /** Indicates if depth testing must be enabled or disabled */\r\n    @editableInPropertyPage(\"Disable on camera move\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get disableOnCameraMove() {\r\n        return this._frameGraphTask.postProcess.disableOnCameraMove;\r\n    }\r\n\r\n    public set disableOnCameraMove(value: boolean) {\r\n        this._frameGraphTask.postProcess.disableOnCameraMove = value;\r\n    }\r\n\r\n    /** Indicates if TAA must be enabled or disabled */\r\n    @editableInPropertyPage(\"Disable TAA\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get disableTAA() {\r\n        return this._frameGraphTask.postProcess.disabled;\r\n    }\r\n\r\n    public set disableTAA(value: boolean) {\r\n        this._frameGraphTask.postProcess.disabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphTAAPostProcessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the object renderer input component\r\n     */\r\n    public get objectRenderer(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry velocity input component\r\n     */\r\n    public get geomVelocity(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.objectRendererTask = this.objectRenderer.connectedPoint?.value as FrameGraphObjectRendererTask;\r\n        this._frameGraphTask.velocityTexture = this.geomVelocity.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.samples = ${this.samples};`);\r\n        codes.push(`${this._codeVariableName}.factor = ${this.factor};`);\r\n        codes.push(`${this._codeVariableName}.clampHistory = ${this.clampHistory};`);\r\n        codes.push(`${this._codeVariableName}.reprojectHistory = ${this.reprojectHistory};`);\r\n        codes.push(`${this._codeVariableName}.disableOnCameraMove = ${this.disableOnCameraMove};`);\r\n        codes.push(`${this._codeVariableName}.disableTAA = ${this.disableTAA};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.samples = this.samples;\r\n        serializationObject.factor = this.factor;\r\n        serializationObject.clampHistory = this.clampHistory;\r\n        serializationObject.reprojectHistory = this.reprojectHistory;\r\n        serializationObject.disableOnCameraMove = this.disableOnCameraMove;\r\n        serializationObject.disableTAA = this.disableTAA;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.samples = serializationObject.samples;\r\n        this.factor = serializationObject.factor;\r\n        this.clampHistory = serializationObject.clampHistory;\r\n        this.reprojectHistory = serializationObject.reprojectHistory;\r\n        this.disableOnCameraMove = serializationObject.disableOnCameraMove;\r\n        this.disableTAA = serializationObject.disableTAA;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for taaPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTaaPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphTAAPostProcessBlock\", NodeRenderGraphTAAPostProcessBlock);\r\n}\r\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\n/** Defines operator used for tonemapping */\r\nexport const enum TonemappingOperator {\r\n    /** Hable */\r\n    Hable = 0,\r\n    /** Reinhard */\r\n    Reinhard = 1,\r\n    /** HejiDawson */\r\n    HejiDawson = 2,\r\n    /** Photographic */\r\n    Photographic = 3,\r\n}\r\n\r\n/**\r\n * Options used to create a ThinTonemapPostProcess.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface ThinTonemapPostProcessOptions extends EffectWrapperCreationOptions {\r\n    /** Defines the operator to use (default: Reinhard) */\r\n    operator?: TonemappingOperator;\r\n\r\n    /** Defines the required exposure adjustment (default: 1.0) */\r\n    exposureAdjustment?: number;\r\n}\r\n\r\n/**\r\n * Post process used to apply a tone mapping operator\r\n */\r\nexport class ThinTonemapPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader url\r\n     */\r\n    public static readonly FragmentUrl = \"tonemap\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"_ExposureAdjustment\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/tonemap.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/tonemap.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructs a new tone mapping post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: ThinTonemapPostProcessOptions) {\r\n        const operator = options?.operator ?? TonemappingOperator.Reinhard;\r\n\r\n        let defines = \"#define \";\r\n\r\n        if (operator === TonemappingOperator.Hable) {\r\n            defines += \"HABLE_TONEMAPPING\";\r\n        } else if (operator === TonemappingOperator.Reinhard) {\r\n            defines += \"REINHARD_TONEMAPPING\";\r\n        } else if (operator === TonemappingOperator.HejiDawson) {\r\n            defines += \"OPTIMIZED_HEJIDAWSON_TONEMAPPING\";\r\n        } else if (operator === TonemappingOperator.Photographic) {\r\n            defines += \"PHOTOGRAPHIC_TONEMAPPING\";\r\n        }\r\n\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinTonemapPostProcess.FragmentUrl,\r\n            uniforms: ThinTonemapPostProcess.Uniforms,\r\n            defines,\r\n        });\r\n\r\n        this.operator = operator;\r\n        this.exposureAdjustment = options?.exposureAdjustment ?? 1;\r\n    }\r\n\r\n    /**\r\n     * Gets the operator to use (default: Reinhard)\r\n     */\r\n    public readonly operator: TonemappingOperator = TonemappingOperator.Reinhard;\r\n\r\n    /**\r\n     * Defines the required exposure adjustment (default: 1.0)\r\n     */\r\n    public exposureAdjustment = 1;\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n        this._drawWrapper.effect!.setFloat(\"_ExposureAdjustment\", this.exposureAdjustment);\r\n    }\r\n}\r\n","import { type FrameGraph } from \"core/FrameGraph/frameGraph\";\r\nimport { ThinTonemapPostProcess } from \"core/PostProcesses/thinTonemapPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * Task which applies a tonemap post process.\r\n */\r\nexport class FrameGraphTonemapTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinTonemapPostProcess;\r\n\r\n    /**\r\n     * Constructs a new tonemap task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param thinPostProcess The thin post process to use for the tonemap effect. If not provided, a new one will be created.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinTonemapPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinTonemapPostProcess(name, frameGraph.engine));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphTonemapTask\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphTonemapTask } from \"../../../Tasks/PostProcesses/tonemapTask\";\r\nimport { ThinTonemapPostProcess, TonemappingOperator } from \"../../../../PostProcesses/thinTonemapPostProcess\";\r\nimport { NodeRenderGraphBaseWithPropertiesPostProcessBlock } from \"./baseWithPropertiesPostProcessBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the tonemap post process\r\n */\r\nexport class NodeRenderGraphTonemapPostProcessBlock extends NodeRenderGraphBaseWithPropertiesPostProcessBlock {\r\n    protected override _frameGraphTask: FrameGraphTonemapTask;\r\n\r\n    public override _additionalConstructionParameters: [TonemappingOperator];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphTonemapPostProcessBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param operator defines the operator to use (default: Reinhard)\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, operator: TonemappingOperator = TonemappingOperator.Reinhard) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [operator];\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphTonemapTask(this.name, frameGraph, new ThinTonemapPostProcess(name, frameGraph.engine, { operator }));\r\n    }\r\n\r\n    private _createTask(operator: TonemappingOperator) {\r\n        const sourceSamplingMode = this._frameGraphTask.sourceSamplingMode;\r\n        const exposureAdjustment = this._frameGraphTask.postProcess.exposureAdjustment;\r\n\r\n        this._frameGraphTask.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphTonemapTask(this.name, this._frameGraph, new ThinTonemapPostProcess(this.name, this._frameGraph.engine, { operator }));\r\n        this._frameGraphTask.sourceSamplingMode = sourceSamplingMode;\r\n        this._frameGraphTask.postProcess.exposureAdjustment = exposureAdjustment;\r\n\r\n        this._additionalConstructionParameters = [operator];\r\n    }\r\n\r\n    @editableInPropertyPage(\"Operator\", PropertyTypeForEdition.List, \"PROPERTIES\", {\r\n        options: [\r\n            { label: \"Hable\", value: TonemappingOperator.Hable },\r\n            { label: \"Reinhard\", value: TonemappingOperator.Reinhard },\r\n            { label: \"HejiDawson\", value: TonemappingOperator.HejiDawson },\r\n            { label: \"Photographic\", value: TonemappingOperator.Photographic },\r\n        ],\r\n    })\r\n    public get operator(): TonemappingOperator {\r\n        return this._frameGraphTask.postProcess.operator;\r\n    }\r\n\r\n    public set operator(value: TonemappingOperator) {\r\n        this._createTask(value);\r\n    }\r\n\r\n    /** Defines the required exposure adjustment */\r\n    @editableInPropertyPage(\"Exposure adjustment\", PropertyTypeForEdition.Float, \"PROPERTIES\")\r\n    public get exposureAdjustment(): number {\r\n        return this._frameGraphTask.postProcess.exposureAdjustment;\r\n    }\r\n\r\n    public set exposureAdjustment(value: number) {\r\n        this._frameGraphTask.postProcess.exposureAdjustment = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphTonemapPostProcessBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.exposureAdjustment = ${this.exposureAdjustment};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.exposureAdjustment = this.exposureAdjustment;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.exposureAdjustment = serializationObject.exposureAdjustment;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for tonemapPostProcessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTonemapPostProcessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphTonemapPostProcessBlock\", NodeRenderGraphTonemapPostProcessBlock);\r\n}\r\n","import {\r\n    type AbstractEngine,\r\n    type Camera,\r\n    type EffectWrapperCreationOptions,\r\n    type FrameGraph,\r\n    type FrameGraphRenderPass,\r\n    type FrameGraphTextureHandle,\r\n    type Nullable,\r\n} from \"core/index\";\r\nimport { Vector3, Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { ThinPassPostProcess } from \"core/PostProcesses/thinPassPostProcess\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\n\r\n/**\r\n * @internal\r\n */\r\nclass VolumetricLightingBlendVolumeThinPostProcess extends ThinPassPostProcess {\r\n    public camera: Camera;\r\n\r\n    public outputTextureWidth = 0;\r\n\r\n    public outputTextureHeight = 0;\r\n\r\n    public extinction = new Vector3(0, 0, 0);\r\n\r\n    public enableExtinction = false;\r\n\r\n    private _invProjection: Matrix;\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../../../ShadersWGSL/pass.fragment\"), import(\"../../../ShadersWGSL/volumetricLightingBlendVolume.fragment\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../../../Shaders/pass.fragment\"), import(\"../../../Shaders/volumetricLightingBlendVolume.fragment\")]));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, enableExtinction = false, options?: EffectWrapperCreationOptions) {\r\n        super(name, engine, {\r\n            ...options,\r\n            fragmentShader: \"volumetricLightingBlendVolume\",\r\n            samplers: [\"depthSampler\"],\r\n            uniforms: [\"invProjection\", \"outputTextureSize\", \"extinction\"],\r\n            defines: enableExtinction ? [\"#define DUAL_SOURCE_BLENDING\", \"#define USE_EXTINCTION\"] : undefined,\r\n        });\r\n\r\n        this._invProjection = new Matrix();\r\n        this.alphaMode = enableExtinction ? Constants.ALPHA_DUAL_SRC0_ADD_SRC1xDST : Constants.ALPHA_ADD;\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this.drawWrapper.effect!;\r\n\r\n        this._invProjection.copyFrom(this.camera.getProjectionMatrix());\r\n        this._invProjection.invert();\r\n\r\n        effect.setMatrix(\"invProjection\", this._invProjection);\r\n        effect.setFloat2(\"outputTextureSize\", this.outputTextureWidth, this.outputTextureHeight);\r\n        effect.setVector3(\"extinction\", this.extinction);\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class FrameGraphVolumetricLightingBlendVolumeTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: VolumetricLightingBlendVolumeThinPostProcess;\r\n\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    public camera: Camera;\r\n\r\n    constructor(name: string, frameGraph: FrameGraph, enableExtinction = false) {\r\n        super(name, frameGraph, new VolumetricLightingBlendVolumeThinPostProcess(name, frameGraph.engine, enableExtinction));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphVolumetricLightingBlendVolumeTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphVolumetricLightingBlendVolumeTask \"${this.name}\": sourceTexture, depthTexture and camera are required`);\r\n        }\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {\r\n            this.postProcess.camera = this.camera;\r\n            context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n        });\r\n\r\n        pass.addDependencies(this.depthTexture);\r\n\r\n        this.postProcess.outputTextureWidth = this._outputWidth;\r\n        this.postProcess.outputTextureHeight = this._outputHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r\n","import { type AbstractEngine, type Camera, type DirectionalLight, type FrameGraph, type FrameGraphObjectList, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { FrameGraphVolumetricLightingBlendVolumeTask } from \"./volumetricLightingBlendVolumeTask\";\r\nimport { Matrix, TmpVectors, Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color.pure\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { FrameGraphClearTextureTask } from \"../Texture/clearTextureTask\";\r\nimport { FrameGraphObjectRendererTask } from \"../Rendering/objectRendererTask\";\r\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\nconst InvViewProjectionMatrix = new Matrix();\r\n\r\n/**\r\n * A frame graph task that performs volumetric lighting.\r\n */\r\nexport class FrameGraphVolumetricLightingTask extends FrameGraphTask {\r\n    /**\r\n     * Returns whether volumetric lighting is supported by the engine.\r\n     * @param engine The engine to check for volumetric lighting support.\r\n     * @param enableExtinction Whether the extinction/dual-source blending path will be used.\r\n     * @returns True if volumetric lighting is supported, false otherwise.\r\n     */\r\n    public static IsSupported(engine: AbstractEngine, enableExtinction: boolean = false) {\r\n        return !enableExtinction || engine.getCaps().dualSourceBlending;\r\n    }\r\n\r\n    /**\r\n     * The target texture to which the volumetric lighting will be applied.\r\n     */\r\n    public targetTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The sampling mode to use when blending the volumetric lighting texture with targetTexture.\r\n     */\r\n    public sourceSamplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n\r\n    /**\r\n     * The depth texture used for volumetric lighting calculations.\r\n     * It must be the depth texture used to generate targetTexture.\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    private _camera: Camera;\r\n    /**\r\n     * The camera used for volumetric lighting calculations.\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(value: Camera) {\r\n        if (this._camera === value) {\r\n            return;\r\n        }\r\n        this._camera = value;\r\n        this._renderLightingVolumeTask.camera = value;\r\n        this._blendLightingVolumeTask.camera = value;\r\n    }\r\n\r\n    /**\r\n     * The mesh representing the lighting volume.\r\n     * This is the mesh that will be rendered to create the volumetric lighting effect.\r\n     */\r\n    public lightingVolumeMesh: FrameGraphObjectList;\r\n\r\n    /**\r\n     * The directional light used for volumetric lighting.\r\n     */\r\n    public light: DirectionalLight;\r\n\r\n    /**\r\n     * The lighting volume texture (optional).\r\n     * If not provided, a new texture will be created, with the same size, format and type as targetTexture.\r\n     * This is the texture that will store the volumetric lighting information, before being blended to targetTexture.\r\n     */\r\n    public lightingVolumeTexture?: FrameGraphTextureHandle;\r\n\r\n    private _extinctionPhaseG = new Vector4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * The phase G parameter for the volumetric lighting effect (default: 0).\r\n     * This parameter controls the anisotropy of the scattering.\r\n     * A value of 0 means isotropic scattering, while a value of 1 means forward scattering and -1 means backward scattering.\r\n     */\r\n    public get phaseG() {\r\n        return this._extinctionPhaseG.w;\r\n    }\r\n\r\n    public set phaseG(value: number) {\r\n        this._extinctionPhaseG.w = value;\r\n        this._renderLightingVolumeMaterial.setVector4(\"extinctionPhaseG\", this._extinctionPhaseG);\r\n    }\r\n\r\n    /**\r\n     * Whether to enable extinction in the volumetric lighting effect (default: false).\r\n     * Read-only property set in the constructor.\r\n     */\r\n    public readonly enableExtinction: boolean;\r\n\r\n    /**\r\n     * The extinction coefficient for the volumetric lighting effect (default: (0, 0, 0) - no extinction).\r\n     * This parameter controls how much light is absorbed and scattered as it travels through the medium.\r\n     * Will only have an effect if enableExtinction is set to true in the constructor!\r\n     */\r\n    public get extinction() {\r\n        return this._blendLightingVolumeTask.postProcess.extinction;\r\n    }\r\n\r\n    public set extinction(value: Vector3) {\r\n        this._extinctionPhaseG.x = Math.max(value.x, 1e-6);\r\n        this._extinctionPhaseG.y = Math.max(value.y, 1e-6);\r\n        this._extinctionPhaseG.z = Math.max(value.z, 1e-6);\r\n        this._renderLightingVolumeMaterial.setVector4(\"extinctionPhaseG\", this._extinctionPhaseG);\r\n        this._blendLightingVolumeTask.postProcess.extinction.copyFromFloats(this._extinctionPhaseG.x, this._extinctionPhaseG.y, this._extinctionPhaseG.z);\r\n    }\r\n\r\n    private _lightPower = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * The light power/color for the volumetric lighting effect (default: (1, 1, 1)).\r\n     * This parameter controls the intensity and color of the light used for volumetric lighting.\r\n     */\r\n    public get lightPower() {\r\n        return this._lightPower;\r\n    }\r\n\r\n    public set lightPower(value: Color3) {\r\n        this._lightPower.copyFrom(value);\r\n        this._renderLightingVolumeMaterial.setColor3(\"lightPower\", this._lightPower);\r\n    }\r\n\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(name: string) {\r\n        this._name = name;\r\n        if (this._renderLightingVolumeMaterial) {\r\n            this._renderLightingVolumeMaterial.name = `${name} - render lighting volume`;\r\n        }\r\n        if (this._clearLightingVolumeTextureTask) {\r\n            this._clearLightingVolumeTextureTask.name = `${name} - clear lighting volume texture`;\r\n        }\r\n        if (this._renderLightingVolumeTask) {\r\n            this._renderLightingVolumeTask.name = `${name} - render lighting volume`;\r\n        }\r\n        if (this._blendLightingVolumeTask) {\r\n            this._blendLightingVolumeTask.name = `${name} - blend lighting volume`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The output texture of the task. It will be the same as targetTexture.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    private readonly _clearLightingVolumeTextureTask: FrameGraphClearTextureTask;\r\n    private readonly _renderLightingVolumeTask: FrameGraphObjectRendererTask;\r\n    private readonly _blendLightingVolumeTask: FrameGraphVolumetricLightingBlendVolumeTask;\r\n    private _renderLightingVolumeMaterial: ShaderMaterial;\r\n\r\n    /**\r\n     * Creates a new FrameGraphVolumetricLightingTask.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph to which the task belongs.\r\n     * @param enableExtinction Whether to enable extinction in the volumetric lighting effect (default: false). If you don't plan to set extinction to something different than (0, 0, 0), you can disable this to save some performance.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, enableExtinction = false) {\r\n        super(name, frameGraph);\r\n\r\n        if (!FrameGraphVolumetricLightingTask.IsSupported(frameGraph.engine, enableExtinction)) {\r\n            throw new Error(\r\n                `FrameGraphVolumetricLightingTask \"${name}\": the current configuration is not supported. Use FrameGraphVolumetricLightingTask.IsSupported(engine, enableExtinction) to check before creating this task.`\r\n            );\r\n        }\r\n\r\n        this.enableExtinction = enableExtinction;\r\n\r\n        const isWebGPU = this._frameGraph.engine.isWebGPU;\r\n\r\n        this._renderLightingVolumeMaterial = new ShaderMaterial(`${name} - render lighting volume`, this._frameGraph.scene, \"volumetricLightingRenderVolume\", {\r\n            attributes: [\"position\"],\r\n            uniformBuffers: [\"Scene\", \"Mesh\"],\r\n            uniforms: [\"world\", \"viewProjection\", \"vEyePosition\", \"lightDir\", \"invViewProjection\", \"outputTextureSize\", \"extinctionPhaseG\", \"lightPower\", \"textureRatio\"],\r\n            samplers: [\"depthTexture\"],\r\n            defines: enableExtinction ? [\"USE_EXTINCTION\"] : [],\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            needAlphaBlending: true,\r\n        });\r\n        this._renderLightingVolumeMaterial.backFaceCulling = false;\r\n        this._renderLightingVolumeMaterial.alphaMode = Constants.ALPHA_ADD;\r\n        this._renderLightingVolumeMaterial.onBindObservable.add(() => {\r\n            this._renderLightingVolumeMaterial.bindEyePosition(this._renderLightingVolumeMaterial.getEffect());\r\n        });\r\n\r\n        this._clearLightingVolumeTextureTask = new FrameGraphClearTextureTask(`clear lighting volume texture`, frameGraph);\r\n        this._renderLightingVolumeTask = new FrameGraphObjectRendererTask(`render lighting volume`, frameGraph, frameGraph.scene);\r\n        this._blendLightingVolumeTask = new FrameGraphVolumetricLightingBlendVolumeTask(`blend lighting volume texture`, frameGraph, enableExtinction);\r\n\r\n        this.onTexturesAllocatedObservable.add(() => {\r\n            this._renderLightingVolumeMaterial.setInternalTexture(\"depthTexture\", frameGraph.textureManager.getTextureFromHandle(this.depthTexture)!);\r\n        });\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n\r\n        // Triggers the setters to set the uniforms\r\n        this.phaseG = this._extinctionPhaseG.w;\r\n        this.extinction = new Vector3(this.extinction.x, this.extinction.y, this.extinction.z);\r\n        this.lightPower = this._lightPower;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public override initAsync(): Promise<unknown> {\r\n        if (this._frameGraph.engine.isWebGPU) {\r\n            return Promise.all([import(\"../../../ShadersWGSL/volumetricLightingRenderVolume.vertex\"), import(\"../../../ShadersWGSL/volumetricLightingRenderVolume.fragment\")]);\r\n        }\r\n\r\n        return Promise.all([import(\"../../../Shaders/volumetricLightingRenderVolume.vertex\"), import(\"../../../Shaders/volumetricLightingRenderVolume.fragment\")]);\r\n    }\r\n\r\n    public override isReady() {\r\n        return (\r\n            this._renderLightingVolumeMaterial.isReady() &&\r\n            this._clearLightingVolumeTextureTask.isReady() &&\r\n            this._renderLightingVolumeMaterial.isReady() &&\r\n            this._blendLightingVolumeTask.isReady()\r\n        );\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphVolumetricLightingTask\";\r\n    }\r\n\r\n    public record(skipCreationOfDisabledPasses = false) {\r\n        if (this.targetTexture === undefined || this.depthTexture === undefined || this.camera === undefined || this.lightingVolumeMesh === undefined || this.light === undefined) {\r\n            throw new Error(`FrameGraphVolumetricLightingTask \"${this.name}\": targetTexture, depthTexture, camera, lightingVolumeMesh and light are required`);\r\n        }\r\n        if (!this.lightingVolumeMesh.meshes || this.lightingVolumeMesh.meshes.length === 0) {\r\n            throw new Error(`FrameGraphVolumetricLightingTask \"${this.name}\": lightingVolumeMesh is empty`);\r\n        }\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);\r\n\r\n        const textureManager = this._frameGraph.textureManager;\r\n\r\n        let lightingVolumeTexture = this.lightingVolumeTexture;\r\n        if (!lightingVolumeTexture) {\r\n            const targetTextureCreationOptions = textureManager.getTextureCreationOptions(this.targetTexture);\r\n\r\n            targetTextureCreationOptions.options.labels = [\"InScattering\"];\r\n            targetTextureCreationOptions.options.samples = 1;\r\n\r\n            lightingVolumeTexture = textureManager.createRenderTargetTexture(`${this.name} - lighting volume texture`, targetTextureCreationOptions);\r\n        }\r\n\r\n        this.lightingVolumeMesh.meshes[0].material = this._renderLightingVolumeMaterial;\r\n\r\n        const targetTextureSize = textureManager.getTextureAbsoluteDimensions(this.targetTexture);\r\n        const volumeTextureSize = textureManager.getTextureAbsoluteDimensions(lightingVolumeTexture);\r\n\r\n        this._renderLightingVolumeMaterial.setVector2(\r\n            \"textureRatio\",\r\n            new Vector2(targetTextureSize.width / volumeTextureSize.width, targetTextureSize.height / volumeTextureSize.height)\r\n        );\r\n        this._renderLightingVolumeMaterial.setVector2(\"outputTextureSize\", new Vector2(volumeTextureSize.width, volumeTextureSize.height));\r\n\r\n        const passUpdateMaterial = this._frameGraph.addPass(this.name);\r\n\r\n        passUpdateMaterial.setExecuteFunc(() => {\r\n            this.camera.getTransformationMatrix().invertToRef(InvViewProjectionMatrix);\r\n\r\n            this._renderLightingVolumeMaterial.setMatrix(\"invViewProjection\", InvViewProjectionMatrix);\r\n            this._renderLightingVolumeMaterial.setVector3(\"lightDir\", this.light.direction.normalizeToRef(TmpVectors.Vector3[0]));\r\n        });\r\n\r\n        this._clearLightingVolumeTextureTask.clearColor = true;\r\n        this._clearLightingVolumeTextureTask.clearStencil = this.enableExtinction;\r\n        this._clearLightingVolumeTextureTask.color = new Color4(0, 0, 0, 1);\r\n        this._clearLightingVolumeTextureTask.stencilValue = 0;\r\n        this._clearLightingVolumeTextureTask.targetTexture = lightingVolumeTexture;\r\n        this._clearLightingVolumeTextureTask.record(true);\r\n\r\n        this._renderLightingVolumeTask.targetTexture = this._clearLightingVolumeTextureTask.outputTexture;\r\n        this._renderLightingVolumeTask.objectList = this.lightingVolumeMesh;\r\n        this._renderLightingVolumeTask.camera = this.camera;\r\n        this._renderLightingVolumeTask.disableImageProcessing = true;\r\n        this._renderLightingVolumeTask.depthTest = false;\r\n        this._renderLightingVolumeTask.record(true);\r\n\r\n        this._blendLightingVolumeTask.sourceTexture = this._renderLightingVolumeTask.outputTexture;\r\n        this._blendLightingVolumeTask.sourceSamplingMode = this.sourceSamplingMode;\r\n        this._blendLightingVolumeTask.targetTexture = this.targetTexture;\r\n        this._blendLightingVolumeTask.depthTexture = this.depthTexture;\r\n        this._blendLightingVolumeTask.camera = this.camera;\r\n        this._blendLightingVolumeTask.record(true);\r\n\r\n        if (!skipCreationOfDisabledPasses) {\r\n            const disabledPass = this._frameGraph.addPass(this.name + \"_disabled\", true);\r\n\r\n            disabledPass.setExecuteFunc(() => {});\r\n        }\r\n    }\r\n\r\n    public override dispose() {\r\n        this._renderLightingVolumeMaterial?.dispose();\r\n        this._clearLightingVolumeTextureTask.dispose();\r\n        this._renderLightingVolumeTask.dispose();\r\n        this._blendLightingVolumeTask.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type Camera,\r\n    type DirectionalLight,\r\n    type FrameGraph,\r\n    type FrameGraphObjectList,\r\n    type FrameGraphTextureHandle,\r\n    type NodeRenderGraphBuildState,\r\n    type NodeRenderGraphConnectionPoint,\r\n    type Scene,\r\n} from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { FrameGraphVolumetricLightingTask } from \"core/FrameGraph/Tasks/PostProcesses/volumetricLightingTask\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Color3 } from \"core/Maths/math.color.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements the volumetric lighting post process\r\n */\r\nexport class NodeRenderGraphVolumetricLightingBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphVolumetricLightingTask;\r\n\r\n    public override _additionalConstructionParameters: [boolean];\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphVolumetricLightingBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param enableExtinction defines whether to enable extinction coefficients\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, enableExtinction = false) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [enableExtinction];\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"depth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"lightingVolumeMesh\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n        this.registerInput(\"light\", NodeRenderGraphBlockConnectionPointTypes.ShadowLight);\r\n        this.registerInput(\"lightingVolumeTexture\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n        this.lightingVolumeTexture.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n\r\n        this.depth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureDepthStencilAttachment | NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth\r\n        );\r\n\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = () => {\r\n            return this.target;\r\n        };\r\n\r\n        this._frameGraphTask = new FrameGraphVolumetricLightingTask(name, frameGraph, enableExtinction);\r\n    }\r\n\r\n    private _createTask(enableExtinction: boolean) {\r\n        const sourceSamplingMode = this._frameGraphTask.sourceSamplingMode;\r\n        const phaseG = this._frameGraphTask.phaseG;\r\n        const extinction = this._frameGraphTask.extinction;\r\n        const lightPower = this._frameGraphTask.lightPower;\r\n\r\n        this._frameGraphTask.dispose();\r\n\r\n        this._frameGraphTask = new FrameGraphVolumetricLightingTask(this.name, this._frameGraph, enableExtinction);\r\n        this._frameGraphTask.sourceSamplingMode = sourceSamplingMode;\r\n        this._frameGraphTask.phaseG = phaseG;\r\n        this._frameGraphTask.extinction = extinction;\r\n        this._frameGraphTask.lightPower = lightPower;\r\n\r\n        this._additionalConstructionParameters = [enableExtinction];\r\n    }\r\n\r\n    /** Gets or sets the phaseG parameter */\r\n    @editableInPropertyPage(\"PhaseG\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: -0.9, max: 0.9 })\r\n    public get phaseG(): number {\r\n        return this._frameGraphTask.phaseG;\r\n    }\r\n\r\n    public set phaseG(value: number) {\r\n        this._frameGraphTask.phaseG = value;\r\n    }\r\n\r\n    /** If extinction coefficients should be used */\r\n    @editableInPropertyPage(\"Enable extinction\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get enableExtinction(): boolean {\r\n        return this._frameGraphTask.enableExtinction;\r\n    }\r\n\r\n    public set enableExtinction(value: boolean) {\r\n        this._createTask(value);\r\n    }\r\n\r\n    /** Gets or sets the extinction color */\r\n    @editableInPropertyPage(\"Extinction\", PropertyTypeForEdition.Vector3, \"PROPERTIES\")\r\n    public get extinction(): Vector3 {\r\n        return this._frameGraphTask.extinction;\r\n    }\r\n\r\n    public set extinction(value: Vector3) {\r\n        this._frameGraphTask.extinction = value;\r\n    }\r\n\r\n    /** Gets or sets the light power */\r\n    @editableInPropertyPage(\"Light power\", PropertyTypeForEdition.Color3, \"PROPERTIES\")\r\n    public get lightPower(): Color3 {\r\n        return this._frameGraphTask.lightPower;\r\n    }\r\n\r\n    public set lightPower(value: Color3) {\r\n        this._frameGraphTask.lightPower = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphVolumetricLightingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth texture input component\r\n     */\r\n    public get depth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the lighting volume mesh input component\r\n     */\r\n    public get lightingVolumeMesh(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the light input component\r\n     */\r\n    public get light(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the lighting volume texture input component\r\n     */\r\n    public get lightingVolumeTexture(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.depthTexture = this.depth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n        this._frameGraphTask.lightingVolumeMesh = this.lightingVolumeMesh.connectedPoint?.value as FrameGraphObjectList;\r\n        this._frameGraphTask.light = this.light.connectedPoint?.value as DirectionalLight;\r\n        this._frameGraphTask.lightingVolumeTexture = this.lightingVolumeTexture.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.phaseG = ${this.phaseG};`);\r\n        codes.push(`${this._codeVariableName}.extinction = new BABYLON.Vector3(${this.extinction.x}, ${this.extinction.y}, ${this.extinction.z});`);\r\n        codes.push(`${this._codeVariableName}.lightPower = new Color3(${this.lightPower.r}, ${this.lightPower.g}, ${this.lightPower.b});`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.phaseG = this.phaseG;\r\n        serializationObject.extinction = this.extinction.asArray();\r\n        serializationObject.lightPower = this.lightPower.asArray();\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.phaseG = serializationObject.phaseG;\r\n        this.extinction = Vector3.FromArray(serializationObject.extinction);\r\n        this.lightPower = Color3.FromArray(serializationObject.lightPower);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for volumetricLightingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVolumetricLightingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphVolumetricLightingBlock\", NodeRenderGraphVolumetricLightingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { serialize, serializeAsVector2 } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { ThinBlurPostProcess } from \"./thinBlurPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The Blur Post Process which blurs an image based on a kernel and direction.\r\n * Can be used twice in x and y directions to perform a gaussian blur in two passes.\r\n */\r\nexport class BlurPostProcess extends PostProcess {\r\n    /** The direction in which to blur the image. */\r\n    @serializeAsVector2()\r\n    public get direction() {\r\n        return this._effectWrapper.direction;\r\n    }\r\n\r\n    public set direction(value: Vector2) {\r\n        this._effectWrapper.direction = value;\r\n    }\r\n\r\n    /**\r\n     * Sets the length in pixels of the blur sample region\r\n     */\r\n    @serialize()\r\n    public set kernel(v: number) {\r\n        this._effectWrapper.kernel = v;\r\n    }\r\n\r\n    /**\r\n     * Gets the length in pixels of the blur sample region\r\n     */\r\n    public get kernel(): number {\r\n        return this._effectWrapper.kernel;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not the blur needs to unpack/repack floats\r\n     */\r\n    @serialize()\r\n    public set packedFloat(v: boolean) {\r\n        this._effectWrapper.packedFloat = v;\r\n    }\r\n\r\n    /**\r\n     * Gets whether or not the blur is unpacking/repacking floats\r\n     */\r\n    public get packedFloat(): boolean {\r\n        return this._effectWrapper.packedFloat;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"BlurPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"BlurPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinBlurPostProcess;\r\n\r\n    /**\r\n     * Creates a new instance BlurPostProcess\r\n     * @param name The name of the effect.\r\n     * @param direction The direction in which to blur the image.\r\n     * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param defines\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        direction: Vector2,\r\n        kernel: number,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode: number = Texture.BILINEAR_SAMPLINGMODE,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        defines = \"\",\r\n        blockCompilation = false,\r\n        textureFormat = Constants.TEXTUREFORMAT_RGBA\r\n    ) {\r\n        const blockCompilationFinal = typeof options === \"number\" ? blockCompilation : !!options.blockCompilation;\r\n        const localOptions = {\r\n            uniforms: ThinBlurPostProcess.Uniforms,\r\n            samplers: ThinBlurPostProcess.Samplers,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            vertexUrl: ThinBlurPostProcess.VertexUrl,\r\n            indexParameters: { varyingCount: 0, depCount: 0 },\r\n            textureFormat,\r\n            defines,\r\n            ...(options as PostProcessOptions),\r\n            blockCompilation: true,\r\n        };\r\n\r\n        super(name, ThinBlurPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinBlurPostProcess(name, engine, undefined, undefined, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this._effectWrapper.options.blockCompilation = blockCompilationFinal;\r\n\r\n        this.direction = direction;\r\n        this.onApplyObservable.add(() => {\r\n            this._effectWrapper.textureWidth = this._outputTexture ? this._outputTexture.width : this.width;\r\n            this._effectWrapper.textureHeight = this._outputTexture ? this._outputTexture.height : this.height;\r\n        });\r\n\r\n        this.kernel = kernel;\r\n    }\r\n\r\n    /**\r\n     * Updates the effect with the current post process compile time values and recompiles the shader\r\n     * @param _defines the post process defines\r\n     * @param _uniforms the post process uniforms\r\n     * @param _samplers the post process samplers\r\n     * @param _indexParameters the index parameters\r\n     * @param onCompiled callback called when the shader is compiled\r\n     * @param onError callback called if there is an error\r\n     */\r\n    public override updateEffect(\r\n        _defines: Nullable<string> = null,\r\n        _uniforms: Nullable<string[]> = null,\r\n        _samplers: Nullable<string[]> = null,\r\n        _indexParameters?: any,\r\n        onCompiled?: (effect: Effect) => void,\r\n        onError?: (effect: Effect, errors: string) => void\r\n    ) {\r\n        this._effectWrapper._updateParameters(onCompiled, onError);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<BlurPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new BlurPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.direction,\r\n                    parsedPostProcess.kernel,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.textureType,\r\n                    undefined,\r\n                    false\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for blurPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBlurPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BlurPostProcess\", BlurPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type SmartArrayNoDuplicate } from \"../../Misc/smartArray\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { SceneComponentConstants, type ISceneSerializableComponent } from \"../../sceneComponent\";\r\n\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type ShadowGenerator } from \"./shadowGenerator\";\r\nimport { AddParser } from \"core/Loading/Plugins/babylonFileParser.function\";\r\n\r\n/**\r\n * Defines the shadow generator component responsible to manage any shadow generators\r\n * in a given scene.\r\n */\r\nexport class ShadowGeneratorSceneComponent implements ISceneSerializableComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_SHADOWGENERATOR;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_SHADOWGENERATOR, this, this._gatherRenderTargets);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing To Do Here.\r\n    }\r\n\r\n    /**\r\n     * Serializes the component data to the specified json object\r\n     * @param serializationObject The object to serialize to\r\n     */\r\n    public serialize(serializationObject: any): void {\r\n        // Shadows\r\n        serializationObject.shadowGenerators = [];\r\n        const lights = this.scene.lights;\r\n        for (const light of lights) {\r\n            if (light.doNotSerialize) {\r\n                continue;\r\n            }\r\n            const shadowGenerators = light.getShadowGenerators();\r\n            if (shadowGenerators) {\r\n                const iterator = shadowGenerators.values();\r\n                for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                    const shadowGenerator = key.value;\r\n                    if (shadowGenerator.doNotSerialize) {\r\n                        continue;\r\n                    }\r\n                    serializationObject.shadowGenerators.push(shadowGenerator.serialize());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     * @param container the container holding the elements\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public addFromContainer(container: IAssetContainer): void {\r\n        // Nothing To Do Here. (directly attached to a light)\r\n    }\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     * @param container contains the elements to remove\r\n     * @param dispose if the removed element should be disposed (default: false)\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public removeFromContainer(container: IAssetContainer, dispose?: boolean): void {\r\n        // Nothing To Do Here. (directly attached to a light)\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public dispose(): void {\r\n        // Nothing To Do Here.\r\n    }\r\n\r\n    private _gatherRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {\r\n        // Shadows\r\n        const scene = this.scene;\r\n        if (this.scene.shadowsEnabled) {\r\n            for (let lightIndex = 0; lightIndex < scene.lights.length; lightIndex++) {\r\n                const light = scene.lights[lightIndex];\r\n                const shadowGenerators = light.getShadowGenerators();\r\n\r\n                if (light.isEnabled() && light.shadowEnabled && shadowGenerators) {\r\n                    const iterator = shadowGenerators.values();\r\n                    for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                        const shadowGenerator = key.value;\r\n                        const shadowMap = <RenderTargetTexture>shadowGenerator.getShadowMap();\r\n                        if (scene.textures.indexOf(shadowMap) !== -1) {\r\n                            renderTargets.push(shadowMap);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for shadowGeneratorSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param shadowGeneratorClass The class of the shadow generator to register the component for\r\n */\r\nexport function RegisterShadowGeneratorSceneComponent(shadowGeneratorClass: typeof ShadowGenerator): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Adds the parser to the scene parsers.\r\n    AddParser(SceneComponentConstants.NAME_SHADOWGENERATOR, (parsedData: any, scene: Scene) => {\r\n        // Shadows\r\n        if (parsedData.shadowGenerators !== undefined && parsedData.shadowGenerators !== null) {\r\n            for (let index = 0, cache = parsedData.shadowGenerators.length; index < cache; index++) {\r\n                const parsedShadowGenerator = parsedData.shadowGenerators[index];\r\n                if (shadowGeneratorClass._CascadedShadowGeneratorParser && parsedShadowGenerator.className === \"CascadedShadowGenerator\") {\r\n                    shadowGeneratorClass._CascadedShadowGeneratorParser(parsedShadowGenerator, scene);\r\n                } else {\r\n                    shadowGeneratorClass.Parse(parsedShadowGenerator, scene);\r\n                }\r\n                // SG would be available on their associated lights\r\n            }\r\n        }\r\n    });\r\n\r\n    shadowGeneratorClass._SceneComponentInitialization = (scene: Scene) => {\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_SHADOWGENERATOR);\r\n        if (!component) {\r\n            component = new ShadowGeneratorSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","import { type SmartArray } from \"../../Misc/smartArray\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Matrix, Vector3, Vector2, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\n\r\nimport { type IShadowLight } from \"../../Lights/shadowLight\";\r\nimport { Light } from \"../../Lights/light\";\r\nimport { type MaterialDefines } from \"../../Materials/materialDefines\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../../Materials/effect\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { RegisterRenderTargetTexture, RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\n\r\nimport { PostProcess } from \"../../PostProcesses/postProcess.pure\";\r\nimport { BlurPostProcess } from \"../../PostProcesses/blurPostProcess.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\nimport { RegisterShadowGeneratorSceneComponent } from \"./shadowGeneratorSceneComponent.pure\";\r\nimport { EffectFallbacks } from \"../../Materials/effectFallbacks\";\r\nimport { RenderingManager } from \"../../Rendering/renderingManager\";\r\nimport { DrawWrapper } from \"../../Materials/drawWrapper\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\n\r\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"../../Materials/clipPlaneMaterialHelper\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport {\r\n    BindBonesParameters,\r\n    BindMorphTargetParameters,\r\n    BindSceneUniformBuffer,\r\n    PrepareDefinesAndAttributesForMorphTargets,\r\n    PushAttributesForInstances,\r\n} from \"../../Materials/materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { FloatingOriginCurrentScene, GetFullOffsetViewProjectionToRef } from \"../../Materials/floatingOriginMatrixOverrides\";\r\n\r\n/**\r\n * Defines the options associated with the creation of a custom shader for a shadow generator.\r\n */\r\nexport interface ICustomShaderOptions {\r\n    /**\r\n     * Gets or sets the custom shader name to use\r\n     */\r\n    shaderName: string;\r\n\r\n    /**\r\n     * The list of attribute names used in the shader\r\n     */\r\n    attributes?: string[];\r\n\r\n    /**\r\n     * The list of uniform names used in the shader\r\n     */\r\n    uniforms?: string[];\r\n\r\n    /**\r\n     * The list of sampler names used in the shader\r\n     */\r\n    samplers?: string[];\r\n\r\n    /**\r\n     * The list of defines used in the shader\r\n     */\r\n    defines?: string[];\r\n}\r\n\r\n/**\r\n * Interface to implement to create a shadow generator compatible with BJS.\r\n */\r\nexport interface IShadowGenerator {\r\n    /** Gets or set the id of the shadow generator. It will be the one from the light if not defined */\r\n    id: string;\r\n\r\n    /**\r\n     * Specifies if the `ShadowGenerator` should be serialized, `true` to skip serialization.\r\n     * Note a `ShadowGenerator` will not be serialized if its light has `doNotSerialize=true`\r\n     */\r\n    doNotSerialize?: boolean;\r\n\r\n    /**\r\n     * Gets the main RTT containing the shadow map (usually storing depth from the light point of view).\r\n     * @returns The render target texture if present otherwise, null\r\n     */\r\n    getShadowMap(): Nullable<RenderTargetTexture>;\r\n\r\n    /**\r\n     * Determine whether the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).\r\n     * @param subMesh The submesh we want to render in the shadow map\r\n     * @param useInstances Defines whether will draw in the map using instances\r\n     * @param isTransparent Indicates that isReady is called for a transparent subMesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    isReady(subMesh: SubMesh, useInstances: boolean, isTransparent: boolean): boolean;\r\n\r\n    /**\r\n     * Prepare all the defines in a material relying on a shadow map at the specified light index.\r\n     * @param defines Defines of the material we want to update\r\n     * @param lightIndex Index of the light in the enabled light list of the material\r\n     */\r\n    prepareDefines(defines: MaterialDefines, lightIndex: number): void;\r\n    /**\r\n     * Binds the shadow related information inside of an effect (information like near, far, darkness...\r\n     * defined in the generator but impacting the effect).\r\n     * It implies the uniforms available on the materials are the standard BJS ones.\r\n     * @param lightIndex Index of the light in the enabled light list of the material owning the effect\r\n     * @param effect The effect we are binding the information for\r\n     */\r\n    bindShadowLight(lightIndex: string, effect: Effect): void;\r\n    /**\r\n     * Gets the transformation matrix used to project the meshes into the map from the light point of view.\r\n     * (eq to shadow projection matrix * light transform matrix)\r\n     * @returns The transform matrix used to create the shadow map\r\n     */\r\n    getTransformMatrix(): Matrix;\r\n\r\n    /**\r\n     * Recreates the shadow map dependencies like RTT and post processes. This can be used during the switch between\r\n     * Cube and 2D textures for instance.\r\n     */\r\n    recreateShadowMap(): void;\r\n\r\n    /**\r\n     * Forces all the attached effect to compile to enable rendering only once ready vs. lazily compiling effects.\r\n     * @param onCompiled Callback triggered at the and of the effects compilation\r\n     * @param options Sets of optional options forcing the compilation with different modes\r\n     */\r\n    forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{ useInstances: boolean }>): void;\r\n\r\n    /**\r\n     * Forces all the attached effect to compile to enable rendering only once ready vs. lazily compiling effects.\r\n     * @param options Sets of optional options forcing the compilation with different modes\r\n     * @returns A promise that resolves when the compilation completes\r\n     */\r\n    forceCompilationAsync(options?: Partial<{ useInstances: boolean }>): Promise<void>;\r\n\r\n    /**\r\n     * Serializes the shadow generator setup to a json object.\r\n     * @returns The serialized JSON object\r\n     */\r\n    serialize(): any;\r\n\r\n    /**\r\n     * Disposes the Shadow map and related Textures and effects.\r\n     */\r\n    dispose(): void;\r\n}\r\n\r\n/**\r\n * Default implementation IShadowGenerator.\r\n * This is the main object responsible of generating shadows in the framework.\r\n * Documentation: https://doc.babylonjs.com/features/featuresDeepDive/lights/shadows\r\n * @see [WebGL](https://playground.babylonjs.com/#IFYDRS#0)\r\n * @see [WebGPU](https://playground.babylonjs.com/#IFYDRS#835)\r\n */\r\nexport class ShadowGenerator implements IShadowGenerator {\r\n    /**\r\n     * Name of the shadow generator class\r\n     */\r\n    public static CLASSNAME = \"ShadowGenerator\";\r\n\r\n    /**\r\n     * Force all the shadow generators to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * Shadow generator mode None: no filtering applied.\r\n     */\r\n    public static readonly FILTER_NONE = 0;\r\n    /**\r\n     * Shadow generator mode ESM: Exponential Shadow Mapping.\r\n     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)\r\n     */\r\n    public static readonly FILTER_EXPONENTIALSHADOWMAP = 1;\r\n    /**\r\n     * Shadow generator mode Poisson Sampling: Percentage Closer Filtering.\r\n     * (Multiple Tap around evenly distributed around the pixel are used to evaluate the shadow strength)\r\n     */\r\n    public static readonly FILTER_POISSONSAMPLING = 2;\r\n    /**\r\n     * Shadow generator mode ESM: Blurred Exponential Shadow Mapping.\r\n     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)\r\n     */\r\n    public static readonly FILTER_BLUREXPONENTIALSHADOWMAP = 3;\r\n    /**\r\n     * Shadow generator mode ESM: Exponential Shadow Mapping using the inverse of the exponential preventing\r\n     * edge artifacts on steep falloff.\r\n     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)\r\n     */\r\n    public static readonly FILTER_CLOSEEXPONENTIALSHADOWMAP = 4;\r\n    /**\r\n     * Shadow generator mode ESM: Blurred Exponential Shadow Mapping using the inverse of the exponential preventing\r\n     * edge artifacts on steep falloff.\r\n     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)\r\n     */\r\n    public static readonly FILTER_BLURCLOSEEXPONENTIALSHADOWMAP = 5;\r\n    /**\r\n     * Shadow generator mode PCF: Percentage Closer Filtering\r\n     * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1\r\n     * (https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html)\r\n     */\r\n    public static readonly FILTER_PCF = 6;\r\n    /**\r\n     * Shadow generator mode PCSS: Percentage Closering Soft Shadow.\r\n     * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1\r\n     * Contact Hardening\r\n     */\r\n    public static readonly FILTER_PCSS = 7;\r\n\r\n    /**\r\n     * Reserved for PCF and PCSS\r\n     * Highest Quality.\r\n     *\r\n     * Execute PCF on a 5*5 kernel improving a lot the shadow aliasing artifacts.\r\n     *\r\n     * Execute PCSS with 32 taps blocker search and 64 taps PCF.\r\n     */\r\n    public static readonly QUALITY_HIGH = 0;\r\n    /**\r\n     * Reserved for PCF and PCSS\r\n     * Good tradeoff for quality/perf cross devices\r\n     *\r\n     * Execute PCF on a 3*3 kernel.\r\n     *\r\n     * Execute PCSS with 16 taps blocker search and 32 taps PCF.\r\n     */\r\n    public static readonly QUALITY_MEDIUM = 1;\r\n    /**\r\n     * Reserved for PCF and PCSS\r\n     * The lowest quality but the fastest.\r\n     *\r\n     * Execute PCF on a 1*1 kernel.\r\n     *\r\n     * Execute PCSS with 16 taps blocker search and 16 taps PCF.\r\n     */\r\n    public static readonly QUALITY_LOW = 2;\r\n\r\n    /**\r\n     * Defines the default alpha cutoff value used for transparent alpha tested materials.\r\n     */\r\n    public static DEFAULT_ALPHA_CUTOFF = 0.5;\r\n\r\n    /** Gets or set the id of the shadow generator. It will be the one from the light if not defined */\r\n    public id: string;\r\n\r\n    /** Gets or sets the custom shader name to use */\r\n    public customShaderOptions: ICustomShaderOptions;\r\n\r\n    /** Gets or sets a custom function to allow/disallow rendering a sub mesh in the shadow map */\r\n    public customAllowRendering: (subMesh: SubMesh) => boolean;\r\n\r\n    /**\r\n     * Observable triggered before the shadow is rendered. Can be used to update internal effect state\r\n     */\r\n    public onBeforeShadowMapRenderObservable = new Observable<Effect>();\r\n\r\n    /**\r\n     * Observable triggered after the shadow is rendered. Can be used to restore internal effect state\r\n     */\r\n    public onAfterShadowMapRenderObservable = new Observable<Effect>();\r\n\r\n    /**\r\n     * Observable triggered before a mesh is rendered in the shadow map.\r\n     * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)\r\n     */\r\n    public onBeforeShadowMapRenderMeshObservable = new Observable<Mesh>();\r\n\r\n    /**\r\n     * Observable triggered after a mesh is rendered in the shadow map.\r\n     * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)\r\n     */\r\n    public onAfterShadowMapRenderMeshObservable = new Observable<Mesh>();\r\n\r\n    /**\r\n     * Specifies if the `ShadowGenerator` should be serialized, `true` to skip serialization.\r\n     * Note a `ShadowGenerator` will not be serialized if its light has `doNotSerialize=true`\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    protected _bias = 0.00005;\r\n    /**\r\n     * Gets the bias: offset applied on the depth preventing acnea (in light direction).\r\n     */\r\n    public get bias(): number {\r\n        return this._bias;\r\n    }\r\n    /**\r\n     * Sets the bias: offset applied on the depth preventing acnea (in light direction).\r\n     */\r\n    public set bias(bias: number) {\r\n        this._bias = bias;\r\n    }\r\n\r\n    protected _normalBias = 0;\r\n    /**\r\n     * Gets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportional to the light/normal angle).\r\n     */\r\n    public get normalBias(): number {\r\n        return this._normalBias;\r\n    }\r\n    /**\r\n     * Sets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportional to the light/normal angle).\r\n     */\r\n    public set normalBias(normalBias: number) {\r\n        this._normalBias = normalBias;\r\n    }\r\n\r\n    protected _blurBoxOffset = 1;\r\n    /**\r\n     * Gets the blur box offset: offset applied during the blur pass.\r\n     * Only useful if useKernelBlur = false\r\n     */\r\n    public get blurBoxOffset(): number {\r\n        return this._blurBoxOffset;\r\n    }\r\n    /**\r\n     * Sets the blur box offset: offset applied during the blur pass.\r\n     * Only useful if useKernelBlur = false\r\n     */\r\n    public set blurBoxOffset(value: number) {\r\n        if (this._blurBoxOffset === value) {\r\n            return;\r\n        }\r\n\r\n        this._blurBoxOffset = value;\r\n        this._disposeBlurPostProcesses();\r\n    }\r\n\r\n    protected _blurScale = 2;\r\n    /**\r\n     * Gets the blur scale: scale of the blurred texture compared to the main shadow map.\r\n     * 2 means half of the size.\r\n     */\r\n    public get blurScale(): number {\r\n        return this._blurScale;\r\n    }\r\n    /**\r\n     * Sets the blur scale: scale of the blurred texture compared to the main shadow map.\r\n     * 2 means half of the size.\r\n     */\r\n    public set blurScale(value: number) {\r\n        if (this._blurScale === value) {\r\n            return;\r\n        }\r\n\r\n        this._blurScale = value;\r\n        this._disposeBlurPostProcesses();\r\n    }\r\n\r\n    protected _blurKernel = 1;\r\n    /**\r\n     * Gets the blur kernel: kernel size of the blur pass.\r\n     * Only useful if useKernelBlur = true\r\n     */\r\n    public get blurKernel(): number {\r\n        return this._blurKernel;\r\n    }\r\n    /**\r\n     * Sets the blur kernel: kernel size of the blur pass.\r\n     * Only useful if useKernelBlur = true\r\n     */\r\n    public set blurKernel(value: number) {\r\n        if (this._blurKernel === value) {\r\n            return;\r\n        }\r\n\r\n        this._blurKernel = value;\r\n        this._disposeBlurPostProcesses();\r\n    }\r\n\r\n    protected _useKernelBlur = false;\r\n    /**\r\n     * Gets whether the blur pass is a kernel blur (if true) or box blur.\r\n     * Only useful in filtered mode (useBlurExponentialShadowMap...)\r\n     */\r\n    public get useKernelBlur(): boolean {\r\n        return this._useKernelBlur;\r\n    }\r\n    /**\r\n     * Sets whether the blur pass is a kernel blur (if true) or box blur.\r\n     * Only useful in filtered mode (useBlurExponentialShadowMap...)\r\n     */\r\n    public set useKernelBlur(value: boolean) {\r\n        if (this._useKernelBlur === value) {\r\n            return;\r\n        }\r\n\r\n        this._useKernelBlur = value;\r\n        this._disposeBlurPostProcesses();\r\n    }\r\n\r\n    protected _depthScale: number;\r\n    /**\r\n     * Gets the depth scale used in ESM mode.\r\n     */\r\n    public get depthScale(): number {\r\n        return this._depthScale !== undefined ? this._depthScale : this._light.getDepthScale();\r\n    }\r\n    /**\r\n     * Sets the depth scale used in ESM mode.\r\n     * This can override the scale stored on the light.\r\n     */\r\n    public set depthScale(value: number) {\r\n        this._depthScale = value;\r\n    }\r\n\r\n    protected _validateFilter(filter: number): number {\r\n        return filter;\r\n    }\r\n\r\n    protected _filter = ShadowGenerator.FILTER_NONE;\r\n    /**\r\n     * Gets the current mode of the shadow generator (normal, PCF, ESM...).\r\n     * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE\r\n     */\r\n    public get filter(): number {\r\n        return this._filter;\r\n    }\r\n    /**\r\n     * Sets the current mode of the shadow generator (normal, PCF, ESM...).\r\n     * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE\r\n     */\r\n    public set filter(value: number) {\r\n        value = this._validateFilter(value);\r\n\r\n        // Blurring the cubemap is going to be too expensive. Reverting to unblurred version\r\n        if (this._light.needCube()) {\r\n            if (value === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {\r\n                this.useExponentialShadowMap = true;\r\n                return;\r\n            } else if (value === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) {\r\n                this.useCloseExponentialShadowMap = true;\r\n                return;\r\n            }\r\n            // PCF on cubemap would also be expensive\r\n            else if (value === ShadowGenerator.FILTER_PCF || value === ShadowGenerator.FILTER_PCSS) {\r\n                this.usePoissonSampling = true;\r\n                return;\r\n            }\r\n        }\r\n\r\n        // Weblg1 fallback for PCF.\r\n        if (value === ShadowGenerator.FILTER_PCF || value === ShadowGenerator.FILTER_PCSS) {\r\n            if (!this._scene.getEngine()._features.supportShadowSamplers) {\r\n                this.usePoissonSampling = true;\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (this._filter === value) {\r\n            return;\r\n        }\r\n\r\n        this._filter = value;\r\n        this._disposeBlurPostProcesses();\r\n        this._applyFilterValues();\r\n        this._light._markMeshesAsLightDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to Poisson Sampling.\r\n     */\r\n    public get usePoissonSampling(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_POISSONSAMPLING;\r\n    }\r\n    /**\r\n     * Sets the current filter to Poisson Sampling.\r\n     */\r\n    public set usePoissonSampling(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_POISSONSAMPLING);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_POISSONSAMPLING) {\r\n            return;\r\n        }\r\n\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to ESM.\r\n     */\r\n    public get useExponentialShadowMap(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP;\r\n    }\r\n    /**\r\n     * Sets the current filter is to ESM.\r\n     */\r\n    public set useExponentialShadowMap(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) {\r\n            return;\r\n        }\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to filtered ESM.\r\n     */\r\n    public get useBlurExponentialShadowMap(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP;\r\n    }\r\n    /**\r\n     * Gets if the current filter is set to filtered  ESM.\r\n     */\r\n    public set useBlurExponentialShadowMap(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {\r\n            return;\r\n        }\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to \"close ESM\" (using the inverse of the\r\n     * exponential to prevent steep falloff artifacts).\r\n     */\r\n    public get useCloseExponentialShadowMap(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP;\r\n    }\r\n    /**\r\n     * Sets the current filter to \"close ESM\" (using the inverse of the\r\n     * exponential to prevent steep falloff artifacts).\r\n     */\r\n    public set useCloseExponentialShadowMap(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP) {\r\n            return;\r\n        }\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to filtered \"close ESM\" (using the inverse of the\r\n     * exponential to prevent steep falloff artifacts).\r\n     */\r\n    public get useBlurCloseExponentialShadowMap(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP;\r\n    }\r\n    /**\r\n     * Sets the current filter to filtered \"close ESM\" (using the inverse of the\r\n     * exponential to prevent steep falloff artifacts).\r\n     */\r\n    public set useBlurCloseExponentialShadowMap(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) {\r\n            return;\r\n        }\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to \"PCF\" (percentage closer filtering).\r\n     */\r\n    public get usePercentageCloserFiltering(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_PCF;\r\n    }\r\n    /**\r\n     * Sets the current filter to \"PCF\" (percentage closer filtering).\r\n     */\r\n    public set usePercentageCloserFiltering(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_PCF);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_PCF) {\r\n            return;\r\n        }\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    protected _filteringQuality = ShadowGenerator.QUALITY_HIGH;\r\n    /**\r\n     * Gets the PCF or PCSS Quality.\r\n     * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.\r\n     */\r\n    public get filteringQuality(): number {\r\n        return this._filteringQuality;\r\n    }\r\n    /**\r\n     * Sets the PCF or PCSS Quality.\r\n     * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.\r\n     */\r\n    public set filteringQuality(filteringQuality: number) {\r\n        if (this._filteringQuality === filteringQuality) {\r\n            return;\r\n        }\r\n\r\n        this._filteringQuality = filteringQuality;\r\n\r\n        this._disposeBlurPostProcesses();\r\n        this._applyFilterValues();\r\n        this._light._markMeshesAsLightDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets if the current filter is set to \"PCSS\" (contact hardening).\r\n     */\r\n    public get useContactHardeningShadow(): boolean {\r\n        return this.filter === ShadowGenerator.FILTER_PCSS;\r\n    }\r\n    /**\r\n     * Sets the current filter to \"PCSS\" (contact hardening).\r\n     */\r\n    public set useContactHardeningShadow(value: boolean) {\r\n        const filter = this._validateFilter(ShadowGenerator.FILTER_PCSS);\r\n\r\n        if (!value && this.filter !== ShadowGenerator.FILTER_PCSS) {\r\n            return;\r\n        }\r\n        this.filter = value ? filter : ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    protected _contactHardeningLightSizeUVRatio = 0.1;\r\n    /**\r\n     * Gets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.\r\n     * Using a ratio helps keeping shape stability independently of the map size.\r\n     *\r\n     * It does not account for the light projection as it was having too much\r\n     * instability during the light setup or during light position changes.\r\n     *\r\n     * Only valid if useContactHardeningShadow is true.\r\n     */\r\n    public get contactHardeningLightSizeUVRatio(): number {\r\n        return this._contactHardeningLightSizeUVRatio;\r\n    }\r\n    /**\r\n     * Sets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.\r\n     * Using a ratio helps keeping shape stability independently of the map size.\r\n     *\r\n     * It does not account for the light projection as it was having too much\r\n     * instability during the light setup or during light position changes.\r\n     *\r\n     * Only valid if useContactHardeningShadow is true.\r\n     */\r\n    public set contactHardeningLightSizeUVRatio(contactHardeningLightSizeUVRatio: number) {\r\n        this._contactHardeningLightSizeUVRatio = contactHardeningLightSizeUVRatio;\r\n    }\r\n\r\n    protected _darkness = 0;\r\n\r\n    /** Gets or sets the actual darkness of a shadow */\r\n    public get darkness() {\r\n        return this._darkness;\r\n    }\r\n\r\n    public set darkness(value: number) {\r\n        this.setDarkness(value);\r\n    }\r\n\r\n    /**\r\n     * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.\r\n     * 0 means strongest and 1 would means no shadow.\r\n     * @returns the darkness.\r\n     */\r\n    public getDarkness(): number {\r\n        return this._darkness;\r\n    }\r\n    /**\r\n     * Sets the darkness value (float). This can only decrease the actual darkness of a shadow.\r\n     * @param darkness The darkness value 0 means strongest and 1 would means no shadow.\r\n     * @returns the shadow generator allowing fluent coding.\r\n     */\r\n    public setDarkness(darkness: number): ShadowGenerator {\r\n        if (darkness >= 1.0) {\r\n            this._darkness = 1.0;\r\n        } else if (darkness <= 0.0) {\r\n            this._darkness = 0.0;\r\n        } else {\r\n            this._darkness = darkness;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    protected _transparencyShadow = false;\r\n\r\n    /** Gets or sets the ability to have transparent shadow */\r\n    public get transparencyShadow() {\r\n        return this._transparencyShadow;\r\n    }\r\n\r\n    public set transparencyShadow(value: boolean) {\r\n        this.setTransparencyShadow(value);\r\n    }\r\n\r\n    /**\r\n     * Sets the ability to have transparent shadow (boolean).\r\n     * @param transparent True if transparent else False\r\n     * @returns the shadow generator allowing fluent coding\r\n     */\r\n    public setTransparencyShadow(transparent: boolean): ShadowGenerator {\r\n        this._transparencyShadow = transparent;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Enables or disables shadows with varying strength based on the transparency\r\n     * When it is enabled, the strength of the shadow is taken equal to mesh.visibility\r\n     * If you enabled an alpha texture on your material, the alpha value red from the texture is also combined to compute the strength:\r\n     *          mesh.visibility * alphaTexture.a\r\n     * The texture used is the diffuse by default, but it can be set to the opacity by setting useOpacityTextureForTransparentShadow\r\n     * Note that by definition transparencyShadow must be set to true for enableSoftTransparentShadow to work!\r\n     */\r\n    public enableSoftTransparentShadow: boolean = false;\r\n\r\n    /**\r\n     * If this is true, use the opacity texture's alpha channel for transparent shadows instead of the diffuse one\r\n     */\r\n    public useOpacityTextureForTransparentShadow: boolean = false;\r\n\r\n    protected _shadowMap: Nullable<RenderTargetTexture>;\r\n    protected _shadowMap2: Nullable<RenderTargetTexture>;\r\n\r\n    /**\r\n     * Gets the main RTT containing the shadow map (usually storing depth from the light point of view).\r\n     * @returns The render target texture if present otherwise, null\r\n     */\r\n    public getShadowMap(): Nullable<RenderTargetTexture> {\r\n        return this._shadowMap;\r\n    }\r\n\r\n    /**\r\n     * Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).\r\n     * @returns The render target texture if the shadow map is present otherwise, null\r\n     */\r\n    public getShadowMapForRendering(): Nullable<RenderTargetTexture> {\r\n        if (this._shadowMap2) {\r\n            return this._shadowMap2;\r\n        }\r\n\r\n        return this._shadowMap;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of that object\r\n     * @returns \"ShadowGenerator\"\r\n     */\r\n    public getClassName(): string {\r\n        return ShadowGenerator.CLASSNAME;\r\n    }\r\n\r\n    /**\r\n     * Helper function to add a mesh and its descendants to the list of shadow casters.\r\n     * @param mesh Mesh to add\r\n     * @param includeDescendants boolean indicating if the descendants should be added. Default to true\r\n     * @returns the Shadow Generator itself\r\n     */\r\n    public addShadowCaster(mesh: AbstractMesh, includeDescendants = true): ShadowGenerator {\r\n        if (!this._shadowMap) {\r\n            return this;\r\n        }\r\n\r\n        if (!this._shadowMap.renderList) {\r\n            this._shadowMap.renderList = [];\r\n        }\r\n\r\n        if (this._shadowMap.renderList.indexOf(mesh) === -1) {\r\n            this._shadowMap.renderList.push(mesh);\r\n        }\r\n\r\n        if (includeDescendants) {\r\n            for (const childMesh of mesh.getChildMeshes()) {\r\n                if (this._shadowMap.renderList.indexOf(childMesh) === -1) {\r\n                    this._shadowMap.renderList.push(childMesh);\r\n                }\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Helper function to remove a mesh and its descendants from the list of shadow casters\r\n     * @param mesh Mesh to remove\r\n     * @param includeDescendants boolean indicating if the descendants should be removed. Default to true\r\n     * @returns the Shadow Generator itself\r\n     */\r\n    public removeShadowCaster(mesh: AbstractMesh, includeDescendants = true): ShadowGenerator {\r\n        if (!this._shadowMap || !this._shadowMap.renderList) {\r\n            return this;\r\n        }\r\n\r\n        const index = this._shadowMap.renderList.indexOf(mesh);\r\n\r\n        if (index !== -1) {\r\n            this._shadowMap.renderList.splice(index, 1);\r\n        }\r\n\r\n        if (includeDescendants) {\r\n            for (const child of mesh.getChildren()) {\r\n                this.removeShadowCaster(<any>child);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Controls the extent to which the shadows fade out at the edge of the frustum\r\n     */\r\n    public frustumEdgeFalloff = 0;\r\n\r\n    protected _light: IShadowLight;\r\n    /**\r\n     * Returns the associated light object.\r\n     * @returns the light generating the shadow\r\n     */\r\n    public getLight(): IShadowLight {\r\n        return this._light;\r\n    }\r\n\r\n    /** Shader language used by the generator */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this generator.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * If true the shadow map is generated by rendering the back face of the mesh instead of the front face.\r\n     * This can help with self-shadowing as the geometry making up the back of objects is slightly offset.\r\n     * It might on the other hand introduce peter panning.\r\n     */\r\n    public forceBackFacesOnly = false;\r\n\r\n    protected _camera: Nullable<Camera>;\r\n\r\n    protected _getCamera() {\r\n        return this._camera ?? this._scene.activeCamera;\r\n    }\r\n\r\n    protected _scene: Scene;\r\n    protected _useRedTextureType: boolean;\r\n    protected _lightDirection = Vector3.Zero();\r\n    protected _usefullFloatFirst: boolean;\r\n    protected _forceGLSL: boolean;\r\n\r\n    protected _viewMatrix = Matrix.Zero();\r\n    protected _projectionMatrix = Matrix.Zero();\r\n    protected _transformMatrix = Matrix.Zero();\r\n    protected _cachedPosition: Vector3 = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n    protected _cachedDirection: Vector3 = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n    protected _cachedDefines: string;\r\n    protected _currentRenderId: number;\r\n    protected _boxBlurPostprocess: Nullable<PostProcess>;\r\n    protected _kernelBlurXPostprocess: Nullable<PostProcess>;\r\n    protected _kernelBlurYPostprocess: Nullable<PostProcess>;\r\n    protected _blurPostProcesses: PostProcess[];\r\n    protected _mapSize: number;\r\n    protected _currentFaceIndex = 0;\r\n    protected _currentFaceIndexCache = 0;\r\n    protected _textureType: number;\r\n    protected _defaultTextureMatrix = Matrix.Identity();\r\n    protected _storedUniqueId: Nullable<number>;\r\n    protected _useUBO: boolean;\r\n    protected _sceneUBOs: UniformBuffer[];\r\n    protected _currentSceneUBO: UniformBuffer;\r\n    protected _opacityTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"ShadowGeneratorSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     * Used by the scene component parser to parse cascaded shadow generators without a direct import\r\n     * (avoids circular dependency between shadowGeneratorSceneComponent and cascadedShadowGenerator).\r\n     */\r\n    public static _CascadedShadowGeneratorParser: ((parsedShadowGenerator: any, scene: Scene) => ShadowGenerator) | null = null;\r\n\r\n    /**\r\n     * Gets or sets the size of the texture what stores the shadows\r\n     */\r\n    public get mapSize(): number {\r\n        return this._mapSize;\r\n    }\r\n\r\n    public set mapSize(size: number) {\r\n        this._mapSize = size;\r\n        this._light._markMeshesAsLightDirty();\r\n        this.recreateShadowMap();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the light that is casting the shadows\r\n     */\r\n    public get light(): IShadowLight {\r\n        return this._light;\r\n    }\r\n\r\n    public set light(light: IShadowLight) {\r\n        if (this._light === light) {\r\n            return;\r\n        }\r\n        this.dispose(false);\r\n        this._light = light;\r\n        this._createInstance();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a value indicating whether the shadow map should use full float texture type (instead of half float, which is the default).\r\n     * Use this option when you need more precision (for self shadowing, for instance).\r\n     */\r\n    public get useFloat32TextureType(): boolean {\r\n        return this._usefullFloatFirst;\r\n    }\r\n\r\n    public set useFloat32TextureType(useFloat32TextureType: boolean) {\r\n        if (this._usefullFloatFirst === useFloat32TextureType) {\r\n            return;\r\n        }\r\n        this.dispose(false);\r\n        this._usefullFloatFirst = useFloat32TextureType;\r\n        this._createInstance();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the camera associated with this shadow generator.\r\n     * When null, the scene's active camera is used at render time.\r\n     */\r\n    public get camera(): Nullable<Camera> {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(camera: Nullable<Camera>) {\r\n        if (this._camera === camera) {\r\n            return;\r\n        }\r\n        this.dispose(false);\r\n        this._camera = camera;\r\n        this._createInstance();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a value indicating whether the shadow map should use a red-channel-only texture format.\r\n     * Using a single-channel format reduces memory usage when color data is not needed.\r\n     */\r\n    public get useRedTextureFormat(): boolean {\r\n        return this._useRedTextureType;\r\n    }\r\n\r\n    public set useRedTextureFormat(useRedTextureFormat: boolean) {\r\n        if (this._useRedTextureType === useRedTextureFormat) {\r\n            return;\r\n        }\r\n        this.dispose(false);\r\n        this._useRedTextureType = useRedTextureFormat;\r\n        this._createInstance();\r\n    }\r\n\r\n    /**\r\n     * Creates a ShadowGenerator object.\r\n     * A ShadowGenerator is the required tool to use the shadows.\r\n     * Each light casting shadows needs to use its own ShadowGenerator.\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/shadows\r\n     * @param mapSize The size of the texture what stores the shadows. Example : 1024.\r\n     * @param light The light object generating the shadows.\r\n     * @param usefullFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.\r\n     * @param camera Camera associated with this shadow generator (default: null). If null, takes the scene active camera at the time we need to access it\r\n     * @param useRedTextureType Forces the generator to use a Red instead of a RGBA type for the shadow map texture format (default: false)\r\n     * @param forceGLSL defines a boolean indicating if the shader must be compiled in GLSL even if we are using WebGPU\r\n     */\r\n    constructor(mapSize: number, light: IShadowLight, usefullFloatFirst?: boolean, camera?: Nullable<Camera>, useRedTextureType?: boolean, forceGLSL = false) {\r\n        this._mapSize = mapSize;\r\n        this._light = light;\r\n        this._usefullFloatFirst = !!usefullFloatFirst;\r\n        this._scene = light.getScene();\r\n        this._camera = camera ?? null;\r\n        this._useRedTextureType = !!useRedTextureType;\r\n        this._forceGLSL = forceGLSL;\r\n\r\n        this._createInstance();\r\n    }\r\n\r\n    private _createInstance() {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(this._forceGLSL);\r\n\r\n        let shadowGenerators = this._light._shadowGenerators;\r\n        if (!shadowGenerators) {\r\n            shadowGenerators = this._light._shadowGenerators = new Map();\r\n        }\r\n        shadowGenerators.set(this._camera, this);\r\n        this.id = this._light.id;\r\n        this._useUBO = this._scene.getEngine().supportsUniformBuffers;\r\n\r\n        if (this._useUBO) {\r\n            this._sceneUBOs = [this._scene.createSceneUniformBuffer(`Scene for Shadow Generator (light \"${this._light.name}\")`, { forceMono: true })];\r\n        }\r\n\r\n        RegisterShadowGeneratorSceneComponent(ShadowGenerator);\r\n        ShadowGenerator._SceneComponentInitialization(this._scene);\r\n\r\n        // PCF and PCSS filtering bind a comparison sampler through Effect.setDepthStencilTexture,\r\n        // which is only installed by the render target texture registration. This module imports\r\n        // renderTargetTexture.pure (side-effect free), so pull the registration in here to guarantee\r\n        // the sampler is available (otherwise WebGPU bind-group assembly fails for filtered shadows).\r\n        RegisterRenderTargetTexture();\r\n\r\n        // Texture type fallback from float to int if not supported.\r\n        const caps = this._scene.getEngine().getCaps();\r\n\r\n        if (!this._usefullFloatFirst) {\r\n            if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {\r\n                this._textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {\r\n                this._textureType = Constants.TEXTURETYPE_FLOAT;\r\n            } else {\r\n                this._textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            }\r\n        } else {\r\n            if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {\r\n                this._textureType = Constants.TEXTURETYPE_FLOAT;\r\n            } else if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {\r\n                this._textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else {\r\n                this._textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            }\r\n        }\r\n\r\n        this._initializeGenerator();\r\n        this._applyFilterValues();\r\n    }\r\n\r\n    protected _initializeGenerator(): void {\r\n        this._light._markMeshesAsLightDirty();\r\n        this._initializeShadowMap();\r\n    }\r\n\r\n    protected _createTargetRenderTexture(): void {\r\n        const engine = this._scene.getEngine();\r\n        this._shadowMap?.dispose();\r\n        if (engine._features.supportDepthStencilTexture) {\r\n            this._shadowMap = new RenderTargetTexture(\r\n                this._light.name + \"_shadowMap\",\r\n                this._mapSize,\r\n                this._scene,\r\n                false,\r\n                true,\r\n                this._textureType,\r\n                this._light.needCube(),\r\n                undefined,\r\n                false,\r\n                false,\r\n                undefined,\r\n                this._useRedTextureType ? Constants.TEXTUREFORMAT_RED : Constants.TEXTUREFORMAT_RGBA\r\n            );\r\n            this._shadowMap.createDepthStencilTexture(\r\n                engine.useReverseDepthBuffer ? Constants.GREATER : Constants.LESS,\r\n                true,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                `DepthStencilForShadowGenerator-${this._light.name}`\r\n            );\r\n        } else {\r\n            this._shadowMap = new RenderTargetTexture(this._light.name + \"_shadowMap\", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube());\r\n        }\r\n        this._shadowMap.noPrePassRenderer = true;\r\n    }\r\n\r\n    protected _initializeShadowMap(): void {\r\n        this._createTargetRenderTexture();\r\n\r\n        if (this._shadowMap === null) {\r\n            return;\r\n        }\r\n\r\n        this._shadowMap.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._shadowMap.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._shadowMap.anisotropicFilteringLevel = 1;\r\n        this._shadowMap.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);\r\n        this._shadowMap.renderParticles = false;\r\n        this._shadowMap.ignoreCameraViewport = true;\r\n        if (this._storedUniqueId) {\r\n            this._shadowMap.uniqueId = this._storedUniqueId;\r\n        }\r\n\r\n        // Custom render function.\r\n        this._shadowMap.customRenderFunction = (\r\n            opaqueSubMeshes: SmartArray<SubMesh>,\r\n            alphaTestSubMeshes: SmartArray<SubMesh>,\r\n            transparentSubMeshes: SmartArray<SubMesh>,\r\n            depthOnlySubMeshes: SmartArray<SubMesh>\r\n        ) => this._renderForShadowMap(opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes);\r\n\r\n        // When preWarm is false, forces the mesh is ready function to true as we are double checking it\r\n        // in the custom render function. Also it prevents side effects and useless\r\n        // shader variations in DEPTHPREPASS mode.\r\n        this._shadowMap.customIsReadyFunction = (mesh: AbstractMesh, _refreshRate: number, preWarm?: boolean): boolean => {\r\n            if (!preWarm || !mesh.subMeshes) {\r\n                return true;\r\n            }\r\n\r\n            let isReady = true;\r\n            for (const subMesh of mesh.subMeshes) {\r\n                const renderingMesh = subMesh.getRenderingMesh();\r\n                const scene = this._scene;\r\n                const engine = scene.getEngine();\r\n                const material = subMesh.getMaterial();\r\n\r\n                if (!material || subMesh.verticesCount === 0 || (this.customAllowRendering && !this.customAllowRendering(subMesh))) {\r\n                    continue;\r\n                }\r\n\r\n                const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n                if (batch.mustReturn) {\r\n                    continue;\r\n                }\r\n\r\n                const hardwareInstancedRendering =\r\n                    engine.getCaps().instancedArrays &&\r\n                    ((batch.visibleInstances[subMesh._id] !== null && batch.visibleInstances[subMesh._id] !== undefined) || renderingMesh.hasThinInstances);\r\n\r\n                const isTransparent = material.needAlphaBlendingForMesh(renderingMesh);\r\n\r\n                isReady = this.isReady(subMesh, hardwareInstancedRendering, isTransparent) && isReady;\r\n            }\r\n\r\n            return isReady;\r\n        };\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        this._shadowMap.onBeforeBindObservable.add(() => {\r\n            this._currentSceneUBO = this._scene.getSceneUniformBuffer();\r\n            if (engine._enableGPUDebugMarkers) {\r\n                engine._debugPushGroup?.(`Shadow map generation for pass id ${engine.currentRenderPassId}`);\r\n            }\r\n        });\r\n\r\n        // Record Face Index before render.\r\n        this._shadowMap.onBeforeRenderObservable.add((faceIndex: number) => {\r\n            if (this._sceneUBOs) {\r\n                this._scene.setSceneUniformBuffer(this._sceneUBOs[0]);\r\n            }\r\n            this._currentFaceIndex = faceIndex;\r\n            if (this._filter === ShadowGenerator.FILTER_PCF) {\r\n                engine.setColorWrite(false);\r\n            }\r\n            this.getTransformMatrix(); // generate the view/projection matrix\r\n            FloatingOriginCurrentScene.eyeAtCamera = false;\r\n            this._scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);\r\n            if (this._sceneUBOs) {\r\n                this._scene.getSceneUniformBuffer().unbindEffect();\r\n                this._scene.finalizeSceneUbo();\r\n            }\r\n        });\r\n\r\n        // Blur if required after render.\r\n        this._shadowMap.onAfterUnbindObservable.add(() => {\r\n            if (this._sceneUBOs) {\r\n                this._scene.setSceneUniformBuffer(this._currentSceneUBO);\r\n            }\r\n            FloatingOriginCurrentScene.eyeAtCamera = true;\r\n            this._scene.updateTransformMatrix(); // restore the view/projection matrices of the active camera\r\n\r\n            if (this._filter === ShadowGenerator.FILTER_PCF) {\r\n                engine.setColorWrite(true);\r\n            }\r\n            if (!this.useBlurExponentialShadowMap && !this.useBlurCloseExponentialShadowMap) {\r\n                engine._debugPopGroup?.();\r\n                return;\r\n            }\r\n            const shadowMap = this.getShadowMapForRendering();\r\n\r\n            if (shadowMap) {\r\n                this._scene.postProcessManager.directRender(this._blurPostProcesses, shadowMap.renderTarget, true);\r\n                engine.unBindFramebuffer(shadowMap.renderTarget!, true);\r\n            }\r\n\r\n            if (engine._enableGPUDebugMarkers) {\r\n                engine._debugPopGroup?.();\r\n            }\r\n        });\r\n\r\n        // Clear according to the chosen filter.\r\n        const clearZero = new Color4(0, 0, 0, 0);\r\n        const clearOne = new Color4(1.0, 1.0, 1.0, 1.0);\r\n        this._shadowMap.onClearObservable.add((engine) => {\r\n            if (this._filter === ShadowGenerator.FILTER_PCF) {\r\n                engine.clear(clearOne, false, true, false);\r\n            } else if (this.useExponentialShadowMap || this.useBlurExponentialShadowMap) {\r\n                engine.clear(clearZero, true, true, false);\r\n            } else {\r\n                engine.clear(clearOne, true, true, false);\r\n            }\r\n        });\r\n\r\n        // Recreate on resize.\r\n        this._shadowMap.onResizeObservable.add((rtt) => {\r\n            this._storedUniqueId = this._shadowMap!.uniqueId;\r\n            this._mapSize = rtt.getRenderSize();\r\n            this._light._markMeshesAsLightDirty();\r\n            this.recreateShadowMap();\r\n        });\r\n\r\n        // Ensures rendering groupids do not erase the depth buffer\r\n        // or we would lose the shadows information.\r\n        for (let i = RenderingManager.MIN_RENDERINGGROUPS; i < RenderingManager.MAX_RENDERINGGROUPS; i++) {\r\n            this._shadowMap.setRenderingAutoClearDepthStencil(i, false);\r\n        }\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n    private async _initShaderSourceAsync(forceGLSL = false) {\r\n        const engine = this._scene.getEngine();\r\n\r\n        if (engine.isWebGPU && !forceGLSL && !ShadowGenerator.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([\r\n                import(\"../../ShadersWGSL/shadowMap.fragment\"),\r\n                import(\"../../ShadersWGSL/shadowMap.vertex\"),\r\n                import(\"../../ShadersWGSL/depthBoxBlur.fragment\"),\r\n                import(\"../../ShadersWGSL/ShadersInclude/shadowMapFragmentSoftTransparentShadow\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../Shaders/shadowMap.fragment\"),\r\n                import(\"../../Shaders/shadowMap.vertex\"),\r\n                import(\"../../Shaders/depthBoxBlur.fragment\"),\r\n                import(\"../../Shaders/ShadersInclude/shadowMapFragmentSoftTransparentShadow\"),\r\n            ]);\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n    }\r\n\r\n    protected _initializeBlurRTTAndPostProcesses(): void {\r\n        const engine = this._scene.getEngine();\r\n        const targetSize = this._mapSize / this.blurScale;\r\n\r\n        if (!this.useKernelBlur || this.blurScale !== 1.0) {\r\n            this._shadowMap2 = new RenderTargetTexture(this._light.name + \"_shadowMap2\", targetSize, this._scene, false, true, this._textureType, undefined, undefined, false);\r\n            this._shadowMap2.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n            this._shadowMap2.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n            this._shadowMap2.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);\r\n        }\r\n\r\n        if (this.useKernelBlur) {\r\n            this._kernelBlurXPostprocess = new BlurPostProcess(\r\n                this._light.name + \"KernelBlurX\",\r\n                new Vector2(1, 0),\r\n                this.blurKernel,\r\n                1.0,\r\n                null,\r\n                Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                false,\r\n                this._textureType\r\n            );\r\n            this._kernelBlurXPostprocess.width = targetSize;\r\n            this._kernelBlurXPostprocess.height = targetSize;\r\n            this._kernelBlurXPostprocess.externalTextureSamplerBinding = true;\r\n            this._kernelBlurXPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setTexture(\"textureSampler\", this._shadowMap);\r\n            });\r\n\r\n            this._kernelBlurYPostprocess = new BlurPostProcess(\r\n                this._light.name + \"KernelBlurY\",\r\n                new Vector2(0, 1),\r\n                this.blurKernel,\r\n                1.0,\r\n                null,\r\n                Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                false,\r\n                this._textureType\r\n            );\r\n\r\n            this._kernelBlurXPostprocess.autoClear = false;\r\n            this._kernelBlurYPostprocess.autoClear = false;\r\n\r\n            if (this._textureType === Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n                (<BlurPostProcess>this._kernelBlurXPostprocess).packedFloat = true;\r\n                (<BlurPostProcess>this._kernelBlurYPostprocess).packedFloat = true;\r\n            }\r\n\r\n            this._blurPostProcesses = [this._kernelBlurXPostprocess, this._kernelBlurYPostprocess];\r\n        } else {\r\n            this._boxBlurPostprocess = new PostProcess(\r\n                this._light.name + \"DepthBoxBlur\",\r\n                \"depthBoxBlur\",\r\n                [\"screenSize\", \"boxOffset\"],\r\n                [],\r\n                1.0,\r\n                null,\r\n                Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                false,\r\n                \"#define OFFSET \" + this._blurBoxOffset,\r\n                this._textureType,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                this._shaderLanguage\r\n            );\r\n            this._boxBlurPostprocess.externalTextureSamplerBinding = true;\r\n            this._boxBlurPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setFloat2(\"screenSize\", targetSize, targetSize);\r\n                effect.setTexture(\"textureSampler\", this._shadowMap);\r\n            });\r\n\r\n            this._boxBlurPostprocess.autoClear = false;\r\n\r\n            this._blurPostProcesses = [this._boxBlurPostprocess];\r\n        }\r\n    }\r\n\r\n    protected _renderForShadowMap(\r\n        opaqueSubMeshes: SmartArray<SubMesh>,\r\n        alphaTestSubMeshes: SmartArray<SubMesh>,\r\n        transparentSubMeshes: SmartArray<SubMesh>,\r\n        depthOnlySubMeshes: SmartArray<SubMesh>\r\n    ): void {\r\n        let index: number;\r\n\r\n        if (depthOnlySubMeshes.length) {\r\n            for (index = 0; index < depthOnlySubMeshes.length; index++) {\r\n                this._renderSubMeshForShadowMap(depthOnlySubMeshes.data[index]);\r\n            }\r\n        }\r\n\r\n        for (index = 0; index < opaqueSubMeshes.length; index++) {\r\n            this._renderSubMeshForShadowMap(opaqueSubMeshes.data[index]);\r\n        }\r\n\r\n        for (index = 0; index < alphaTestSubMeshes.length; index++) {\r\n            this._renderSubMeshForShadowMap(alphaTestSubMeshes.data[index]);\r\n        }\r\n\r\n        if (this._transparencyShadow) {\r\n            for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                this._renderSubMeshForShadowMap(transparentSubMeshes.data[index], true);\r\n            }\r\n        } else {\r\n            for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                transparentSubMeshes.data[index].getEffectiveMesh()._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect, mesh: AbstractMesh): void {\r\n        effect.setMatrix(\"viewProjection\", this.getTransformMatrix());\r\n    }\r\n\r\n    protected _renderSubMeshForShadowMap(subMesh: SubMesh, isTransparent: boolean = false): void {\r\n        const renderingMesh = subMesh.getRenderingMesh();\r\n        const effectiveMesh = subMesh.getEffectiveMesh();\r\n        const scene = this._scene;\r\n        const engine = scene.getEngine();\r\n        const material = subMesh.getMaterial();\r\n\r\n        effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n\r\n        if (!material || subMesh.verticesCount === 0 || subMesh._renderId === scene.getRenderId()) {\r\n            return;\r\n        }\r\n\r\n        // Culling\r\n        // Note:\r\n        // In rhs mode, we assume that meshes will be rendered in right-handed space (i.e. with an RHS camera), so the default value of material.sideOrientation is updated accordingly (see material constructor).\r\n        // However, when generating a shadow map, we render from the point of view of the light, whose view/projection matrices are always in lhs mode.\r\n        // We therefore need to \"undo\" the sideOrientation inversion that was previously performed when constructing the material.\r\n        const useRHS = scene.useRightHandedSystem;\r\n        const detNeg = effectiveMesh._getWorldMatrixDeterminant() < 0;\r\n        let sideOrientation = material._getEffectiveOrientation(renderingMesh);\r\n\r\n        if ((detNeg && !useRHS) || (!detNeg && useRHS)) {\r\n            sideOrientation =\r\n                sideOrientation === Constants.MATERIAL_ClockWiseSideOrientation ? Constants.MATERIAL_CounterClockWiseSideOrientation : Constants.MATERIAL_ClockWiseSideOrientation;\r\n        }\r\n        const reverseSideOrientation = sideOrientation === Constants.MATERIAL_ClockWiseSideOrientation;\r\n\r\n        engine.setState(material.backFaceCulling, undefined, undefined, reverseSideOrientation, material.cullBackFaces);\r\n\r\n        // Managing instances\r\n        const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n        if (batch.mustReturn) {\r\n            return;\r\n        }\r\n\r\n        const hardwareInstancedRendering =\r\n            engine.getCaps().instancedArrays &&\r\n            ((batch.visibleInstances[subMesh._id] !== null && batch.visibleInstances[subMesh._id] !== undefined) || renderingMesh.hasThinInstances);\r\n\r\n        if (this.customAllowRendering && !this.customAllowRendering(subMesh)) {\r\n            return;\r\n        }\r\n\r\n        if (this.isReady(subMesh, hardwareInstancedRendering, isTransparent)) {\r\n            subMesh._renderId = scene.getRenderId();\r\n\r\n            const shadowDepthWrapper = material.shadowDepthWrapper;\r\n\r\n            const drawWrapper = shadowDepthWrapper?.getEffect(subMesh, this, engine.currentRenderPassId) ?? subMesh._getDrawWrapper()!;\r\n            const effect = DrawWrapper.GetEffect(drawWrapper)!;\r\n\r\n            engine.enableEffect(drawWrapper);\r\n\r\n            if (!hardwareInstancedRendering) {\r\n                renderingMesh._bind(subMesh, effect, material.fillMode);\r\n            }\r\n\r\n            this.getTransformMatrix(); // make sure _cachedDirection et _cachedPosition are up to date\r\n\r\n            effect.setFloat3(\"biasAndScaleSM\", this.bias, this.normalBias, this.depthScale);\r\n\r\n            if (this.getLight().getTypeID() === Light.LIGHTTYPEID_DIRECTIONALLIGHT) {\r\n                effect.setVector3(\"lightDataSM\", this._cachedDirection);\r\n            } else {\r\n                effect.setVector3(\"lightDataSM\", this._cachedPosition.subtractToRef(this._scene.floatingOriginOffset, TmpVectors.Vector3[0]));\r\n            }\r\n\r\n            const camera = this._getCamera();\r\n            effect.setFloat2(\"depthValuesSM\", this.getLight().getDepthMinZ(camera), this.getLight().getDepthMinZ(camera) + this.getLight().getDepthMaxZ(camera));\r\n\r\n            if (isTransparent && this.enableSoftTransparentShadow) {\r\n                effect.setFloat2(\"softTransparentShadowSM\", effectiveMesh.visibility * material.alpha, this._opacityTexture?.getAlphaFromRGB ? 1 : 0);\r\n            }\r\n\r\n            if (shadowDepthWrapper) {\r\n                subMesh._setMainDrawWrapperOverride(drawWrapper);\r\n                if (shadowDepthWrapper.standalone) {\r\n                    shadowDepthWrapper.baseMaterial.bindForSubMesh(effectiveMesh.getWorldMatrix(), renderingMesh, subMesh);\r\n                } else {\r\n                    material.bindForSubMesh(effectiveMesh.getWorldMatrix(), renderingMesh, subMesh);\r\n                }\r\n                subMesh._setMainDrawWrapperOverride(null);\r\n            } else {\r\n                // Alpha test\r\n                if (this._opacityTexture) {\r\n                    effect.setTexture(\"diffuseSampler\", this._opacityTexture);\r\n                    effect.setMatrix(\"diffuseMatrix\", this._opacityTexture.getTextureMatrix() || this._defaultTextureMatrix);\r\n                }\r\n\r\n                // Bones\r\n                BindBonesParameters(renderingMesh, effect);\r\n\r\n                // Morph targets\r\n                BindMorphTargetParameters(renderingMesh, effect);\r\n                if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\r\n                    renderingMesh.morphTargetManager._bind(effect);\r\n                }\r\n\r\n                // Baked vertex animations\r\n                const bvaManager = subMesh.getMesh().bakedVertexAnimationManager;\r\n                if (bvaManager && bvaManager.isEnabled) {\r\n                    bvaManager.bind(effect, hardwareInstancedRendering);\r\n                }\r\n\r\n                // Clip planes\r\n                BindClipPlane(effect, material, scene);\r\n            }\r\n\r\n            if (!this._useUBO && !shadowDepthWrapper) {\r\n                this._bindCustomEffectForRenderSubMeshForShadowMap(subMesh, effect, effectiveMesh);\r\n            }\r\n\r\n            BindSceneUniformBuffer(effect, this._scene.getSceneUniformBuffer());\r\n            this._scene.getSceneUniformBuffer().bindUniformBuffer();\r\n\r\n            const world = effectiveMesh.getWorldMatrix();\r\n\r\n            // In the non hardware instanced mode, the Mesh ubo update is done by the callback passed to renderingMesh._processRendering (see below)\r\n            if (hardwareInstancedRendering) {\r\n                effectiveMesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n                effectiveMesh.transferToEffect(world);\r\n            }\r\n\r\n            if (this.forceBackFacesOnly) {\r\n                engine.setState(true, 0, false, true, material.cullBackFaces);\r\n            }\r\n\r\n            // Observables\r\n            this.onBeforeShadowMapRenderMeshObservable.notifyObservers(renderingMesh);\r\n            this.onBeforeShadowMapRenderObservable.notifyObservers(effect);\r\n\r\n            // Draw\r\n            renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, worldOverride) => {\r\n                if (effectiveMesh !== renderingMesh && !isInstance) {\r\n                    renderingMesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n                    renderingMesh.transferToEffect(worldOverride);\r\n                } else {\r\n                    effectiveMesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n                    effectiveMesh.transferToEffect(isInstance ? worldOverride : world);\r\n                }\r\n            });\r\n\r\n            if (this.forceBackFacesOnly) {\r\n                engine.setState(true, 0, false, false, material.cullBackFaces);\r\n            }\r\n\r\n            // Observables\r\n            this.onAfterShadowMapRenderObservable.notifyObservers(effect);\r\n            this.onAfterShadowMapRenderMeshObservable.notifyObservers(renderingMesh);\r\n        } else {\r\n            // Need to reset refresh rate of the shadowMap\r\n            if (this._shadowMap) {\r\n                this._shadowMap.resetRefreshCounter();\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _applyFilterValues(): void {\r\n        if (!this._shadowMap) {\r\n            return;\r\n        }\r\n\r\n        if (this.filter === ShadowGenerator.FILTER_NONE || this.filter === ShadowGenerator.FILTER_PCSS) {\r\n            this._shadowMap.updateSamplingMode(Texture.NEAREST_SAMPLINGMODE);\r\n        } else {\r\n            this._shadowMap.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Forces all the attached effect to compile to enable rendering only once ready vs. lazily compiling effects.\r\n     * @param onCompiled Callback triggered at the and of the effects compilation\r\n     * @param options Sets of optional options forcing the compilation with different modes\r\n     */\r\n    public forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{ useInstances: boolean }>): void {\r\n        const localOptions = {\r\n            useInstances: false,\r\n            ...options,\r\n        };\r\n\r\n        const shadowMap = this.getShadowMap();\r\n        if (!shadowMap) {\r\n            if (onCompiled) {\r\n                onCompiled(this);\r\n            }\r\n            return;\r\n        }\r\n\r\n        const renderList = shadowMap.renderList;\r\n        if (!renderList) {\r\n            if (onCompiled) {\r\n                onCompiled(this);\r\n            }\r\n            return;\r\n        }\r\n\r\n        const subMeshes: SubMesh[] = [];\r\n        for (const mesh of renderList) {\r\n            subMeshes.push(...mesh.subMeshes);\r\n        }\r\n        if (subMeshes.length === 0) {\r\n            if (onCompiled) {\r\n                onCompiled(this);\r\n            }\r\n            return;\r\n        }\r\n\r\n        let currentIndex = 0;\r\n\r\n        const checkReady = () => {\r\n            if (!this._scene || !this._scene.getEngine()) {\r\n                return;\r\n            }\r\n\r\n            while (\r\n                this.isReady(\r\n                    subMeshes[currentIndex],\r\n                    localOptions.useInstances,\r\n                    subMeshes[currentIndex].getMaterial()?.needAlphaBlendingForMesh(subMeshes[currentIndex].getMesh()) ?? false\r\n                )\r\n            ) {\r\n                currentIndex++;\r\n                if (currentIndex >= subMeshes.length) {\r\n                    if (onCompiled) {\r\n                        onCompiled(this);\r\n                    }\r\n                    return;\r\n                }\r\n            }\r\n            setTimeout(checkReady, 16);\r\n        };\r\n\r\n        checkReady();\r\n    }\r\n\r\n    /**\r\n     * Forces all the attached effect to compile to enable rendering only once ready vs. lazily compiling effects.\r\n     * @param options Sets of optional options forcing the compilation with different modes\r\n     * @returns A promise that resolves when the compilation completes\r\n     */\r\n    public async forceCompilationAsync(options?: Partial<{ useInstances: boolean }>): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            this.forceCompilation(() => {\r\n                resolve();\r\n            }, options);\r\n        });\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _isReadyCustomDefines(defines: any, subMesh: SubMesh, useInstances: boolean): void {}\r\n\r\n    private _prepareShadowDefines(subMesh: SubMesh, useInstances: boolean, defines: string[], isTransparent: boolean): string[] {\r\n        defines.push(\"#define SM_LIGHTTYPE_\" + this._light.getClassName().toUpperCase());\r\n\r\n        defines.push(\"#define SM_FLOAT \" + (this._textureType !== Constants.TEXTURETYPE_UNSIGNED_BYTE ? \"1\" : \"0\"));\r\n\r\n        defines.push(\"#define SM_ESM \" + (this.useExponentialShadowMap || this.useBlurExponentialShadowMap ? \"1\" : \"0\"));\r\n\r\n        defines.push(\"#define SM_DEPTHTEXTURE \" + (this.usePercentageCloserFiltering || this.useContactHardeningShadow ? \"1\" : \"0\"));\r\n\r\n        const mesh = subMesh.getMesh();\r\n\r\n        // Normal bias.\r\n        defines.push(\"#define SM_NORMALBIAS \" + (this.normalBias && mesh.isVerticesDataPresent(VertexBuffer.NormalKind) ? \"1\" : \"0\"));\r\n        defines.push(\"#define SM_DIRECTIONINLIGHTDATA \" + (this.getLight().getTypeID() === Light.LIGHTTYPEID_DIRECTIONALLIGHT ? \"1\" : \"0\"));\r\n\r\n        // Point light\r\n        defines.push(\"#define SM_USEDISTANCE \" + (this._light.needCube() ? \"1\" : \"0\"));\r\n\r\n        // Soft transparent shadows\r\n        defines.push(\"#define SM_SOFTTRANSPARENTSHADOW \" + (this.enableSoftTransparentShadow && isTransparent ? \"1\" : \"0\"));\r\n\r\n        this._isReadyCustomDefines(defines, subMesh, useInstances);\r\n\r\n        return defines;\r\n    }\r\n\r\n    /**\r\n     * Determine whether the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).\r\n     * @param subMesh The submesh we want to render in the shadow map\r\n     * @param useInstances Defines whether will draw in the map using instances\r\n     * @param isTransparent Indicates that isReady is called for a transparent subMesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean, isTransparent: boolean): boolean {\r\n        if (!this._shadersLoaded) {\r\n            return false;\r\n        }\r\n\r\n        const material = subMesh.getMaterial(),\r\n            shadowDepthWrapper = material?.shadowDepthWrapper;\r\n\r\n        this._opacityTexture = null;\r\n\r\n        if (!material) {\r\n            return false;\r\n        }\r\n\r\n        const defines: string[] = [];\r\n\r\n        this._prepareShadowDefines(subMesh, useInstances, defines, isTransparent);\r\n\r\n        if (shadowDepthWrapper) {\r\n            if (!shadowDepthWrapper.isReadyForSubMesh(subMesh, defines, this, useInstances, this._scene.getEngine().currentRenderPassId)) {\r\n                return false;\r\n            }\r\n        } else {\r\n            const subMeshEffect = subMesh._getDrawWrapper(undefined, true)!;\r\n\r\n            let effect = subMeshEffect.effect!;\r\n            let cachedDefines = subMeshEffect.defines;\r\n\r\n            const attribs = [VertexBuffer.PositionKind];\r\n\r\n            const mesh = subMesh.getMesh();\r\n\r\n            let useNormal = false;\r\n            let uv1 = false;\r\n            let uv2 = false;\r\n            const color = false;\r\n\r\n            // Normal bias.\r\n            if (this.normalBias && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n                attribs.push(VertexBuffer.NormalKind);\r\n                defines.push(\"#define NORMAL\");\r\n                useNormal = true;\r\n                if (mesh.nonUniformScaling) {\r\n                    defines.push(\"#define NONUNIFORMSCALING\");\r\n                }\r\n            }\r\n\r\n            // Alpha test\r\n            const needAlphaTesting = material.needAlphaTestingForMesh(mesh);\r\n\r\n            if (needAlphaTesting || material.needAlphaBlendingForMesh(mesh)) {\r\n                if (this.useOpacityTextureForTransparentShadow) {\r\n                    this._opacityTexture = (material as any).opacityTexture;\r\n                } else {\r\n                    this._opacityTexture = material.getAlphaTestTexture();\r\n                }\r\n                if (this._opacityTexture) {\r\n                    if (!this._opacityTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n\r\n                    const alphaCutOff = (material as any).alphaCutOff ?? ShadowGenerator.DEFAULT_ALPHA_CUTOFF;\r\n\r\n                    defines.push(\"#define ALPHATEXTURE\");\r\n                    if (needAlphaTesting) {\r\n                        defines.push(`#define ALPHATESTVALUE ${alphaCutOff}${alphaCutOff % 1 === 0 ? \".\" : \"\"}`);\r\n                    }\r\n                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                        attribs.push(VertexBuffer.UVKind);\r\n                        defines.push(\"#define UV1\");\r\n                        uv1 = true;\r\n                    }\r\n                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n                        if (this._opacityTexture.coordinatesIndex === 1) {\r\n                            attribs.push(VertexBuffer.UV2Kind);\r\n                            defines.push(\"#define UV2\");\r\n                            uv2 = true;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Bones\r\n            const fallbacks = new EffectFallbacks();\r\n            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n                attribs.push(VertexBuffer.MatricesIndicesKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsKind);\r\n                if (mesh.numBoneInfluencers > 4) {\r\n                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n                }\r\n                const skeleton = mesh.skeleton;\r\n                defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n                if (mesh.numBoneInfluencers > 0) {\r\n                    fallbacks.addCPUSkinningFallback(0, mesh);\r\n                }\r\n\r\n                if (skeleton.isUsingTextureForMatrices) {\r\n                    defines.push(\"#define BONETEXTURE\");\r\n                } else {\r\n                    defines.push(\"#define BonesPerMesh \" + (skeleton.bones.length + 1));\r\n                }\r\n            } else {\r\n                defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n            }\r\n\r\n            // Morph targets\r\n            const numMorphInfluencers = mesh.morphTargetManager\r\n                ? PrepareDefinesAndAttributesForMorphTargets(\r\n                      mesh.morphTargetManager,\r\n                      defines,\r\n                      attribs,\r\n                      mesh,\r\n                      true, // usePositionMorph\r\n                      useNormal, // useNormalMorph\r\n                      false, // useTangentMorph\r\n                      uv1, // useUVMorph\r\n                      uv2, // useUV2Morph\r\n                      color // useColorMorph\r\n                  )\r\n                : 0;\r\n\r\n            // ClipPlanes\r\n            PrepareStringDefinesForClipPlanes(material, this._scene, defines);\r\n\r\n            // Instances\r\n            if (useInstances) {\r\n                defines.push(\"#define INSTANCES\");\r\n                PushAttributesForInstances(attribs);\r\n                if (subMesh.getRenderingMesh().hasThinInstances) {\r\n                    defines.push(\"#define THIN_INSTANCES\");\r\n                }\r\n            }\r\n\r\n            if (this.customShaderOptions) {\r\n                if (this.customShaderOptions.defines) {\r\n                    for (const define of this.customShaderOptions.defines) {\r\n                        if (defines.indexOf(define) === -1) {\r\n                            defines.push(define);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Baked vertex animations\r\n            const bvaManager = mesh.bakedVertexAnimationManager;\r\n            if (bvaManager && bvaManager.isEnabled) {\r\n                defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\r\n                if (useInstances) {\r\n                    attribs.push(\"bakedVertexAnimationSettingsInstanced\");\r\n                }\r\n            }\r\n\r\n            // Get correct effect\r\n            const join = defines.join(\"\\n\");\r\n            if (cachedDefines !== join) {\r\n                cachedDefines = join;\r\n\r\n                let shaderName = \"shadowMap\";\r\n                const uniforms = [\r\n                    \"world\",\r\n                    \"mBones\",\r\n                    \"viewProjection\",\r\n                    \"diffuseMatrix\",\r\n                    \"lightDataSM\",\r\n                    \"depthValuesSM\",\r\n                    \"biasAndScaleSM\",\r\n                    \"morphTargetInfluences\",\r\n                    \"morphTargetCount\",\r\n                    \"boneTextureInfo\",\r\n                    \"softTransparentShadowSM\",\r\n                    \"morphTargetTextureInfo\",\r\n                    \"morphTargetTextureIndices\",\r\n                    \"bakedVertexAnimationSettings\",\r\n                    \"bakedVertexAnimationTextureSizeInverted\",\r\n                    \"bakedVertexAnimationTime\",\r\n                    \"bakedVertexAnimationTexture\",\r\n                ];\r\n                const samplers = [\"diffuseSampler\", \"boneSampler\", \"morphTargets\", \"bakedVertexAnimationTexture\"];\r\n                const uniformBuffers = [\"Scene\", \"Mesh\"];\r\n\r\n                AddClipPlaneUniforms(uniforms);\r\n\r\n                // Custom shader?\r\n                if (this.customShaderOptions) {\r\n                    shaderName = this.customShaderOptions.shaderName;\r\n\r\n                    if (this.customShaderOptions.attributes) {\r\n                        for (const attrib of this.customShaderOptions.attributes) {\r\n                            if (attribs.indexOf(attrib) === -1) {\r\n                                attribs.push(attrib);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (this.customShaderOptions.uniforms) {\r\n                        for (const uniform of this.customShaderOptions.uniforms) {\r\n                            if (uniforms.indexOf(uniform) === -1) {\r\n                                uniforms.push(uniform);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (this.customShaderOptions.samplers) {\r\n                        for (const sampler of this.customShaderOptions.samplers) {\r\n                            if (samplers.indexOf(sampler) === -1) {\r\n                                samplers.push(sampler);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                const engine = this._scene.getEngine();\r\n\r\n                effect = engine.createEffect(\r\n                    shaderName,\r\n                    <IEffectCreationOptions>{\r\n                        attributes: attribs,\r\n                        uniformsNames: uniforms,\r\n                        uniformBuffersNames: uniformBuffers,\r\n                        samplers: samplers,\r\n                        defines: join,\r\n                        fallbacks: fallbacks,\r\n                        onCompiled: null,\r\n                        onError: null,\r\n                        indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                        shaderLanguage: this._shaderLanguage,\r\n                    },\r\n                    engine\r\n                );\r\n\r\n                subMeshEffect.setEffect(effect, cachedDefines);\r\n            }\r\n\r\n            if (!effect.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (this.useBlurExponentialShadowMap || this.useBlurCloseExponentialShadowMap) {\r\n            if (!this._blurPostProcesses || !this._blurPostProcesses.length) {\r\n                this._initializeBlurRTTAndPostProcesses();\r\n            }\r\n        }\r\n\r\n        if (this._kernelBlurXPostprocess && !this._kernelBlurXPostprocess.isReady()) {\r\n            return false;\r\n        }\r\n        if (this._kernelBlurYPostprocess && !this._kernelBlurYPostprocess.isReady()) {\r\n            return false;\r\n        }\r\n        if (this._boxBlurPostprocess && !this._boxBlurPostprocess.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Prepare all the defines in a material relying on a shadow map at the specified light index.\r\n     * @param defines Defines of the material we want to update\r\n     * @param lightIndex Index of the light in the enabled light list of the material\r\n     */\r\n    public prepareDefines(defines: any, lightIndex: number): void {\r\n        const scene = this._scene;\r\n        const light = this._light;\r\n\r\n        if (!scene.shadowsEnabled || !light.shadowEnabled) {\r\n            return;\r\n        }\r\n\r\n        defines[\"SHADOW\" + lightIndex] = true;\r\n\r\n        if (this.useContactHardeningShadow) {\r\n            defines[\"SHADOWPCSS\" + lightIndex] = true;\r\n            if (this._filteringQuality === ShadowGenerator.QUALITY_LOW) {\r\n                defines[\"SHADOWLOWQUALITY\" + lightIndex] = true;\r\n            } else if (this._filteringQuality === ShadowGenerator.QUALITY_MEDIUM) {\r\n                defines[\"SHADOWMEDIUMQUALITY\" + lightIndex] = true;\r\n            }\r\n            // else default to high.\r\n        } else if (this.usePercentageCloserFiltering) {\r\n            defines[\"SHADOWPCF\" + lightIndex] = true;\r\n            if (this._filteringQuality === ShadowGenerator.QUALITY_LOW) {\r\n                defines[\"SHADOWLOWQUALITY\" + lightIndex] = true;\r\n            } else if (this._filteringQuality === ShadowGenerator.QUALITY_MEDIUM) {\r\n                defines[\"SHADOWMEDIUMQUALITY\" + lightIndex] = true;\r\n            }\r\n            // else default to high.\r\n        } else if (this.usePoissonSampling) {\r\n            defines[\"SHADOWPOISSON\" + lightIndex] = true;\r\n        } else if (this.useExponentialShadowMap || this.useBlurExponentialShadowMap) {\r\n            defines[\"SHADOWESM\" + lightIndex] = true;\r\n        } else if (this.useCloseExponentialShadowMap || this.useBlurCloseExponentialShadowMap) {\r\n            defines[\"SHADOWCLOSEESM\" + lightIndex] = true;\r\n        }\r\n\r\n        if (light.needCube()) {\r\n            defines[\"SHADOWCUBE\" + lightIndex] = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the shadow related information inside of an effect (information like near, far, darkness...\r\n     * defined in the generator but impacting the effect).\r\n     * @param lightIndex Index of the light in the enabled light list of the material owning the effect\r\n     * @param effect The effect we are binding the information for\r\n     */\r\n    public bindShadowLight(lightIndex: string, effect: Effect): void {\r\n        const light = this._light;\r\n        const scene = this._scene;\r\n\r\n        if (!scene.shadowsEnabled || !light.shadowEnabled) {\r\n            return;\r\n        }\r\n\r\n        const camera = this._getCamera();\r\n        const shadowMap = this.getShadowMap();\r\n\r\n        if (!shadowMap) {\r\n            return;\r\n        }\r\n\r\n        if (!light.needCube()) {\r\n            const offset = scene.floatingOriginOffset;\r\n            const transform = this.getTransformMatrix(); // ensures updated view/projection\r\n            // Doing the check for floatingOrigin here to avoid unnecessary matrix operations when offset is 0\r\n            const lightMatrix = scene.floatingOriginMode ? GetFullOffsetViewProjectionToRef(offset, this._viewMatrix, this._projectionMatrix, TmpVectors.Matrix[0]) : transform;\r\n            effect.setMatrix(\"lightMatrix\" + lightIndex, lightMatrix);\r\n        }\r\n\r\n        // Only PCF uses depth stencil texture.\r\n        const shadowMapForRendering = this.getShadowMapForRendering();\r\n        if (this._filter === ShadowGenerator.FILTER_PCF) {\r\n            effect.setDepthStencilTexture(\"shadowTexture\" + lightIndex, shadowMapForRendering);\r\n            light._uniformBuffer.updateFloat4(\"shadowsInfo\", this.getDarkness(), shadowMap.getSize().width, 1 / shadowMap.getSize().width, this.frustumEdgeFalloff, lightIndex);\r\n        } else if (this._filter === ShadowGenerator.FILTER_PCSS) {\r\n            effect.setDepthStencilTexture(\"shadowTexture\" + lightIndex, shadowMapForRendering);\r\n            effect.setTexture(\"depthTexture\" + lightIndex, shadowMapForRendering);\r\n            light._uniformBuffer.updateFloat4(\r\n                \"shadowsInfo\",\r\n                this.getDarkness(),\r\n                1 / shadowMap.getSize().width,\r\n                this._contactHardeningLightSizeUVRatio * shadowMap.getSize().width,\r\n                this.frustumEdgeFalloff,\r\n                lightIndex\r\n            );\r\n        } else {\r\n            effect.setTexture(\"shadowTexture\" + lightIndex, shadowMapForRendering);\r\n            light._uniformBuffer.updateFloat4(\"shadowsInfo\", this.getDarkness(), this.blurScale / shadowMap.getSize().width, this.depthScale, this.frustumEdgeFalloff, lightIndex);\r\n        }\r\n\r\n        light._uniformBuffer.updateFloat2(\r\n            \"depthValues\",\r\n            this.getLight().getDepthMinZ(camera),\r\n            this.getLight().getDepthMinZ(camera) + this.getLight().getDepthMaxZ(camera),\r\n            lightIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the view matrix used to render the shadow map.\r\n     */\r\n    public get viewMatrix() {\r\n        return this._viewMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the projection matrix used to render the shadow map.\r\n     */\r\n    public get projectionMatrix() {\r\n        return this._projectionMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the transformation matrix used to project the meshes into the map from the light point of view.\r\n     * (eq to shadow projection matrix * light transform matrix)\r\n     * @returns The transform matrix used to create the shadow map\r\n     */\r\n    public getTransformMatrix(): Matrix {\r\n        const scene = this._scene;\r\n        if (this._currentRenderId === scene.getRenderId() && this._currentFaceIndexCache === this._currentFaceIndex) {\r\n            return this._transformMatrix;\r\n        }\r\n\r\n        this._currentRenderId = scene.getRenderId();\r\n        this._currentFaceIndexCache = this._currentFaceIndex;\r\n\r\n        let lightPosition = this._light.position;\r\n        if (this._light.computeTransformedInformation()) {\r\n            lightPosition = this._light.transformedPosition;\r\n        }\r\n\r\n        Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);\r\n        if (Math.abs(Vector3.Dot(this._lightDirection, Vector3.Up())) === 1.0) {\r\n            this._lightDirection.z = 0.0000000000001; // Required to avoid perfectly perpendicular light\r\n        }\r\n\r\n        if (\r\n            this._light.needProjectionMatrixCompute() ||\r\n            !this._cachedPosition ||\r\n            !this._cachedDirection ||\r\n            !lightPosition.equals(this._cachedPosition) ||\r\n            !this._lightDirection.equals(this._cachedDirection)\r\n        ) {\r\n            this._cachedPosition.copyFrom(lightPosition);\r\n            this._cachedDirection.copyFrom(this._lightDirection);\r\n\r\n            Matrix.LookAtLHToRef(lightPosition, lightPosition.add(this._lightDirection), Vector3.Up(), this._viewMatrix);\r\n\r\n            const shadowMap = this.getShadowMap();\r\n\r\n            if (shadowMap) {\r\n                const renderList = shadowMap.renderList;\r\n\r\n                if (renderList) {\r\n                    this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, renderList);\r\n                }\r\n            }\r\n\r\n            this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);\r\n        }\r\n\r\n        return this._transformMatrix;\r\n    }\r\n\r\n    /**\r\n     * Recreates the shadow map dependencies like RTT and post processes. This can be used during the switch between\r\n     * Cube and 2D textures for instance.\r\n     */\r\n    public recreateShadowMap(): void {\r\n        const shadowMap = this._shadowMap;\r\n        if (!shadowMap) {\r\n            return;\r\n        }\r\n\r\n        // Track render list.\r\n        const renderList = shadowMap.renderList;\r\n        // Clean up existing data.\r\n        this._disposeRTTandPostProcesses();\r\n        // Reinitializes.\r\n        this._initializeGenerator();\r\n        // Reaffect the filter to ensure a correct fallback if necessary.\r\n        this.filter = this._filter;\r\n        // Reaffect the filter.\r\n        this._applyFilterValues();\r\n        // Reaffect Render List.\r\n        if (renderList) {\r\n            // Note: don't do this._shadowMap!.renderList = renderList;\r\n            // The renderList hooked array is accessing the old RenderTargetTexture (see RenderTargetTexture._hookArray), which is disposed at this point (by the call to _disposeRTTandPostProcesses)\r\n            if (!this._shadowMap!.renderList) {\r\n                this._shadowMap!.renderList = [];\r\n            }\r\n            for (const mesh of renderList) {\r\n                this._shadowMap!.renderList.push(mesh);\r\n            }\r\n        } else {\r\n            this._shadowMap!.renderList = null;\r\n        }\r\n    }\r\n\r\n    protected _disposeBlurPostProcesses(): void {\r\n        if (this._shadowMap2) {\r\n            this._shadowMap2.dispose();\r\n            this._shadowMap2 = null;\r\n        }\r\n\r\n        if (this._boxBlurPostprocess) {\r\n            this._boxBlurPostprocess.dispose();\r\n            this._boxBlurPostprocess = null;\r\n        }\r\n\r\n        if (this._kernelBlurXPostprocess) {\r\n            this._kernelBlurXPostprocess.dispose();\r\n            this._kernelBlurXPostprocess = null;\r\n        }\r\n\r\n        if (this._kernelBlurYPostprocess) {\r\n            this._kernelBlurYPostprocess.dispose();\r\n            this._kernelBlurYPostprocess = null;\r\n        }\r\n\r\n        this._blurPostProcesses = [];\r\n    }\r\n\r\n    protected _disposeRTTandPostProcesses(): void {\r\n        if (this._shadowMap) {\r\n            this._shadowMap.dispose();\r\n            this._shadowMap = null;\r\n        }\r\n\r\n        this._disposeBlurPostProcesses();\r\n    }\r\n\r\n    protected _disposeSceneUBOs(): void {\r\n        if (this._sceneUBOs) {\r\n            for (const ubo of this._sceneUBOs) {\r\n                ubo.dispose();\r\n            }\r\n            this._sceneUBOs = [];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the ShadowGenerator.\r\n     * @param clearObservables Defines whether to clear the observables or not (true by default).\r\n     * Returns nothing.\r\n     */\r\n    public dispose(clearObservables: boolean = true): void {\r\n        this._disposeRTTandPostProcesses();\r\n\r\n        this._disposeSceneUBOs();\r\n\r\n        if (this._light) {\r\n            if (this._light._shadowGenerators) {\r\n                const iterator = this._light._shadowGenerators.entries();\r\n                for (let entry = iterator.next(); entry.done !== true; entry = iterator.next()) {\r\n                    const [camera, shadowGenerator] = entry.value;\r\n                    if (shadowGenerator === this) {\r\n                        this._light._shadowGenerators.delete(camera);\r\n                    }\r\n                }\r\n                if (this._light._shadowGenerators.size === 0) {\r\n                    this._light._shadowGenerators = null;\r\n                }\r\n            }\r\n            this._light._markMeshesAsLightDirty();\r\n        }\r\n\r\n        if (clearObservables) {\r\n            this.onBeforeShadowMapRenderMeshObservable.clear();\r\n            this.onBeforeShadowMapRenderObservable.clear();\r\n            this.onAfterShadowMapRenderMeshObservable.clear();\r\n            this.onAfterShadowMapRenderObservable.clear();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the shadow generator setup to a json object.\r\n     * @returns The serialized JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        const shadowMap = this.getShadowMap();\r\n\r\n        if (!shadowMap) {\r\n            return serializationObject;\r\n        }\r\n\r\n        serializationObject.className = this.getClassName();\r\n        serializationObject.lightId = this._light.id;\r\n        serializationObject.cameraId = this._camera?.id;\r\n        serializationObject.id = this.id;\r\n        serializationObject.mapSize = shadowMap.getRenderSize();\r\n        serializationObject.forceBackFacesOnly = this.forceBackFacesOnly;\r\n        serializationObject.darkness = this.getDarkness();\r\n        serializationObject.transparencyShadow = this._transparencyShadow;\r\n        serializationObject.frustumEdgeFalloff = this.frustumEdgeFalloff;\r\n        serializationObject.bias = this.bias;\r\n        serializationObject.normalBias = this.normalBias;\r\n        serializationObject.usePercentageCloserFiltering = this.usePercentageCloserFiltering;\r\n        serializationObject.useContactHardeningShadow = this.useContactHardeningShadow;\r\n        serializationObject.contactHardeningLightSizeUVRatio = this.contactHardeningLightSizeUVRatio;\r\n        serializationObject.filteringQuality = this.filteringQuality;\r\n        serializationObject.useExponentialShadowMap = this.useExponentialShadowMap;\r\n        serializationObject.useBlurExponentialShadowMap = this.useBlurExponentialShadowMap;\r\n        serializationObject.useCloseExponentialShadowMap = this.useCloseExponentialShadowMap;\r\n        serializationObject.useBlurCloseExponentialShadowMap = this.useBlurCloseExponentialShadowMap;\r\n        serializationObject.usePoissonSampling = this.usePoissonSampling;\r\n        serializationObject.depthScale = this.depthScale;\r\n        serializationObject.blurBoxOffset = this.blurBoxOffset;\r\n        serializationObject.blurKernel = this.blurKernel;\r\n        serializationObject.blurScale = this.blurScale;\r\n        serializationObject.useKernelBlur = this.useKernelBlur;\r\n\r\n        serializationObject.renderList = [];\r\n        if (shadowMap.renderList) {\r\n            for (let meshIndex = 0; meshIndex < shadowMap.renderList.length; meshIndex++) {\r\n                const mesh = shadowMap.renderList[meshIndex];\r\n\r\n                serializationObject.renderList.push(mesh.id);\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized ShadowGenerator and returns a new ShadowGenerator.\r\n     * @param parsedShadowGenerator The JSON object to parse\r\n     * @param scene The scene to create the shadow map for\r\n     * @param constr A function that builds a shadow generator or undefined to create an instance of the default shadow generator\r\n     * @returns The parsed shadow generator\r\n     */\r\n    public static Parse(parsedShadowGenerator: any, scene: Scene, constr?: (mapSize: number, light: IShadowLight, camera: Nullable<Camera>) => ShadowGenerator): ShadowGenerator {\r\n        const light = <IShadowLight>scene.getLightById(parsedShadowGenerator.lightId);\r\n        const camera: Nullable<Camera> = parsedShadowGenerator.cameraId !== undefined ? scene.getCameraById(parsedShadowGenerator.cameraId) : null;\r\n        const shadowGenerator = constr ? constr(parsedShadowGenerator.mapSize, light, camera) : new ShadowGenerator(parsedShadowGenerator.mapSize, light, undefined, camera);\r\n        const shadowMap = shadowGenerator.getShadowMap();\r\n\r\n        if (parsedShadowGenerator.renderList.length && shadowMap) {\r\n            const renderSet = new Set<string>(parsedShadowGenerator.renderList);\r\n            let renderList = shadowMap.renderList;\r\n            if (!renderList) {\r\n                renderList = shadowMap.renderList = [];\r\n            }\r\n            const meshes = scene.meshes;\r\n            for (const mesh of meshes) {\r\n                if (renderSet.has(mesh.id)) {\r\n                    renderList.push(mesh);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (parsedShadowGenerator.id !== undefined) {\r\n            shadowGenerator.id = parsedShadowGenerator.id;\r\n        }\r\n\r\n        shadowGenerator.forceBackFacesOnly = !!parsedShadowGenerator.forceBackFacesOnly;\r\n\r\n        if (parsedShadowGenerator.darkness !== undefined) {\r\n            shadowGenerator.setDarkness(parsedShadowGenerator.darkness);\r\n        }\r\n\r\n        if (parsedShadowGenerator.transparencyShadow) {\r\n            shadowGenerator.setTransparencyShadow(true);\r\n        }\r\n\r\n        if (parsedShadowGenerator.frustumEdgeFalloff !== undefined) {\r\n            shadowGenerator.frustumEdgeFalloff = parsedShadowGenerator.frustumEdgeFalloff;\r\n        }\r\n\r\n        if (parsedShadowGenerator.bias !== undefined) {\r\n            shadowGenerator.bias = parsedShadowGenerator.bias;\r\n        }\r\n\r\n        if (parsedShadowGenerator.normalBias !== undefined) {\r\n            shadowGenerator.normalBias = parsedShadowGenerator.normalBias;\r\n        }\r\n\r\n        if (parsedShadowGenerator.usePercentageCloserFiltering) {\r\n            shadowGenerator.usePercentageCloserFiltering = true;\r\n        } else if (parsedShadowGenerator.useContactHardeningShadow) {\r\n            shadowGenerator.useContactHardeningShadow = true;\r\n        } else if (parsedShadowGenerator.usePoissonSampling) {\r\n            shadowGenerator.usePoissonSampling = true;\r\n        } else if (parsedShadowGenerator.useExponentialShadowMap) {\r\n            shadowGenerator.useExponentialShadowMap = true;\r\n        } else if (parsedShadowGenerator.useBlurExponentialShadowMap) {\r\n            shadowGenerator.useBlurExponentialShadowMap = true;\r\n        } else if (parsedShadowGenerator.useCloseExponentialShadowMap) {\r\n            shadowGenerator.useCloseExponentialShadowMap = true;\r\n        } else if (parsedShadowGenerator.useBlurCloseExponentialShadowMap) {\r\n            shadowGenerator.useBlurCloseExponentialShadowMap = true;\r\n        }\r\n        // Backward compat\r\n        else if (parsedShadowGenerator.useVarianceShadowMap) {\r\n            shadowGenerator.useExponentialShadowMap = true;\r\n        } else if (parsedShadowGenerator.useBlurVarianceShadowMap) {\r\n            shadowGenerator.useBlurExponentialShadowMap = true;\r\n        }\r\n\r\n        if (parsedShadowGenerator.contactHardeningLightSizeUVRatio !== undefined) {\r\n            shadowGenerator.contactHardeningLightSizeUVRatio = parsedShadowGenerator.contactHardeningLightSizeUVRatio;\r\n        }\r\n\r\n        if (parsedShadowGenerator.filteringQuality !== undefined) {\r\n            shadowGenerator.filteringQuality = parsedShadowGenerator.filteringQuality;\r\n        }\r\n\r\n        if (parsedShadowGenerator.depthScale) {\r\n            shadowGenerator.depthScale = parsedShadowGenerator.depthScale;\r\n        }\r\n\r\n        if (parsedShadowGenerator.blurScale) {\r\n            shadowGenerator.blurScale = parsedShadowGenerator.blurScale;\r\n        }\r\n\r\n        if (parsedShadowGenerator.blurBoxOffset) {\r\n            shadowGenerator.blurBoxOffset = parsedShadowGenerator.blurBoxOffset;\r\n        }\r\n\r\n        if (parsedShadowGenerator.useKernelBlur) {\r\n            shadowGenerator.useKernelBlur = parsedShadowGenerator.useKernelBlur;\r\n        }\r\n\r\n        if (parsedShadowGenerator.blurKernel) {\r\n            shadowGenerator.blurKernel = parsedShadowGenerator.blurKernel;\r\n        }\r\n\r\n        return shadowGenerator;\r\n    }\r\n}\r\n","import {\r\n    type NodeRenderGraphConnectionPoint,\r\n    type Scene,\r\n    type NodeRenderGraphBuildState,\r\n    type FrameGraph,\r\n    type IShadowLight,\r\n    type FrameGraphObjectList,\r\n    type FrameGraphShadowGeneratorTask,\r\n    type Camera,\r\n} from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { ShadowGenerator } from \"../../../../Lights/Shadows/shadowGenerator\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class NodeRenderGraphBaseShadowGeneratorBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphShadowGeneratorTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphBaseShadowGeneratorBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"light\", NodeRenderGraphBlockConnectionPointTypes.ShadowLight);\r\n        this.registerInput(\"objects\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n    }\r\n\r\n    protected _finalizeInputOutputRegistering() {\r\n        this._addDependenciesInput();\r\n        this.registerOutput(\"generator\", NodeRenderGraphBlockConnectionPointTypes.ShadowGenerator);\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /** Sets the size of the shadow texture */\r\n    @editableInPropertyPage(\"Map size\", PropertyTypeForEdition.List, \"PROPERTIES\", {\r\n        options: [\r\n            { label: \"128\", value: 128 },\r\n            { label: \"256\", value: 256 },\r\n            { label: \"512\", value: 512 },\r\n            { label: \"1024\", value: 1024 },\r\n            { label: \"2048\", value: 2048 },\r\n            { label: \"4096\", value: 4096 },\r\n            { label: \"8192\", value: 8192 },\r\n        ],\r\n    })\r\n    public get mapSize() {\r\n        return this._frameGraphTask.mapSize;\r\n    }\r\n\r\n    public set mapSize(value: number) {\r\n        this._frameGraphTask.mapSize = value;\r\n    }\r\n\r\n    /** Sets the texture type to float (by default, half float is used if supported) */\r\n    @editableInPropertyPage(\"Use 32 bits float texture type\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get useFloat32TextureType() {\r\n        return this._frameGraphTask.useFloat32TextureType;\r\n    }\r\n\r\n    public set useFloat32TextureType(value: boolean) {\r\n        this._frameGraphTask.useFloat32TextureType = value;\r\n    }\r\n\r\n    /** Sets the texture type to Red */\r\n    @editableInPropertyPage(\"Use red texture format\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get useRedTextureFormat() {\r\n        return this._frameGraphTask.useRedTextureFormat;\r\n    }\r\n\r\n    public set useRedTextureFormat(value: boolean) {\r\n        this._frameGraphTask.useRedTextureFormat = value;\r\n    }\r\n\r\n    /** Sets the bias */\r\n    @editableInPropertyPage(\"Bias\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get bias() {\r\n        return this._frameGraphTask.bias;\r\n    }\r\n\r\n    public set bias(value: number) {\r\n        this._frameGraphTask.bias = value;\r\n    }\r\n\r\n    /** Sets the normal bias */\r\n    @editableInPropertyPage(\"Normal bias\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get normalBias() {\r\n        return this._frameGraphTask.normalBias;\r\n    }\r\n\r\n    public set normalBias(value: number) {\r\n        this._frameGraphTask.normalBias = value;\r\n    }\r\n\r\n    /** Sets the darkness of the shadows */\r\n    @editableInPropertyPage(\"Darkness\", PropertyTypeForEdition.Float, \"PROPERTIES\", { min: 0, max: 1 })\r\n    public get darkness() {\r\n        return this._frameGraphTask.darkness;\r\n    }\r\n\r\n    public set darkness(value: number) {\r\n        this._frameGraphTask.darkness = value;\r\n    }\r\n\r\n    /** Sets the filter method */\r\n    @editableInPropertyPage(\"Filter\", PropertyTypeForEdition.List, \"PROPERTIES\", {\r\n        options: [\r\n            { label: \"None\", value: ShadowGenerator.FILTER_NONE },\r\n            { label: \"Exponential\", value: ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP },\r\n            { label: \"Poisson Sampling\", value: ShadowGenerator.FILTER_POISSONSAMPLING },\r\n            { label: \"Blur exponential\", value: ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP },\r\n            { label: \"Close exponential\", value: ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP },\r\n            { label: \"Blur close exponential\", value: ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP },\r\n            { label: \"PCF\", value: ShadowGenerator.FILTER_PCF },\r\n            { label: \"PCSS\", value: ShadowGenerator.FILTER_PCSS },\r\n        ],\r\n    })\r\n    public get filter() {\r\n        return this._frameGraphTask.filter;\r\n    }\r\n\r\n    public set filter(value: number) {\r\n        this._frameGraphTask.filter = value;\r\n    }\r\n\r\n    /** Sets the filter quality (for PCF and PCSS) */\r\n    @editableInPropertyPage(\"Filter quality\", PropertyTypeForEdition.List, \"PROPERTIES\", {\r\n        options: [\r\n            { label: \"Low\", value: ShadowGenerator.QUALITY_LOW },\r\n            { label: \"Medium\", value: ShadowGenerator.QUALITY_MEDIUM },\r\n            { label: \"High\", value: ShadowGenerator.QUALITY_HIGH },\r\n        ],\r\n    })\r\n    public get filteringQuality() {\r\n        return this._frameGraphTask.filteringQuality;\r\n    }\r\n\r\n    public set filteringQuality(value: number) {\r\n        this._frameGraphTask.filteringQuality = value;\r\n    }\r\n\r\n    /** Gets or sets the ability to have transparent shadow */\r\n    @editableInPropertyPage(\"Transparency shadow\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get transparencyShadow() {\r\n        return this._frameGraphTask.transparencyShadow;\r\n    }\r\n\r\n    public set transparencyShadow(value: boolean) {\r\n        this._frameGraphTask.transparencyShadow = value;\r\n    }\r\n\r\n    /** Enables or disables shadows with varying strength based on the transparency */\r\n    @editableInPropertyPage(\"Enable soft transparent shadows\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get enableSoftTransparentShadow() {\r\n        return this._frameGraphTask.enableSoftTransparentShadow;\r\n    }\r\n\r\n    public set enableSoftTransparentShadow(value: boolean) {\r\n        this._frameGraphTask.enableSoftTransparentShadow = value;\r\n    }\r\n\r\n    /** If this is true, use the opacity texture's alpha channel for transparent shadows instead of the diffuse one */\r\n    @editableInPropertyPage(\"Use opacity texture for transparent shadows\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get useOpacityTextureForTransparentShadow() {\r\n        return this._frameGraphTask.useOpacityTextureForTransparentShadow;\r\n    }\r\n\r\n    public set useOpacityTextureForTransparentShadow(value: boolean) {\r\n        this._frameGraphTask.useOpacityTextureForTransparentShadow = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphBaseShadowGeneratorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the light input component\r\n     */\r\n    public get light(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the objects input component\r\n     */\r\n    public get objects(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow generator component\r\n     */\r\n    public get generator(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output texture component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.light = this.light.connectedPoint?.value as IShadowLight;\r\n        this._frameGraphTask.objectList = this.objects.connectedPoint?.value as FrameGraphObjectList;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n\r\n        // Important: the shadow generator object is created by the task when we set the light, that's why we must set generator.value after setting the light!\r\n        this.generator.value = this._frameGraphTask;\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.mapSize = ${this.mapSize};`);\r\n        codes.push(`${this._codeVariableName}.useFloat32TextureType = ${this.useFloat32TextureType};`);\r\n        codes.push(`${this._codeVariableName}.useRedTextureFormat = ${this.useRedTextureFormat};`);\r\n        codes.push(`${this._codeVariableName}.bias = ${this.bias};`);\r\n        codes.push(`${this._codeVariableName}.normalBias = ${this.normalBias};`);\r\n        codes.push(`${this._codeVariableName}.darkness = ${this.darkness};`);\r\n        codes.push(`${this._codeVariableName}.filter = ${this.filter};`);\r\n        codes.push(`${this._codeVariableName}.filteringQuality = ${this.filteringQuality};`);\r\n        codes.push(`${this._codeVariableName}.transparencyShadow = ${this.transparencyShadow};`);\r\n        codes.push(`${this._codeVariableName}.enableSoftTransparentShadow = ${this.enableSoftTransparentShadow};`);\r\n        codes.push(`${this._codeVariableName}.useOpacityTextureForTransparentShadow = ${this.useOpacityTextureForTransparentShadow};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.mapSize = this.mapSize;\r\n        serializationObject.useFloat32TextureType = this.useFloat32TextureType;\r\n        serializationObject.useRedTextureFormat = this.useRedTextureFormat;\r\n        serializationObject.bias = this.bias;\r\n        serializationObject.normalBias = this.normalBias;\r\n        serializationObject.darkness = this.darkness;\r\n        serializationObject.filter = this.filter;\r\n        serializationObject.filteringQuality = this.filteringQuality;\r\n        serializationObject.transparencyShadow = this.transparencyShadow;\r\n        serializationObject.enableSoftTransparentShadow = this.enableSoftTransparentShadow;\r\n        serializationObject.useOpacityTextureForTransparentShadow = this.useOpacityTextureForTransparentShadow;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.mapSize = serializationObject.mapSize;\r\n        this.useFloat32TextureType = serializationObject.useFloat32TextureType;\r\n        this.useRedTextureFormat = serializationObject.useRedTextureFormat;\r\n        this.bias = serializationObject.bias;\r\n        this.normalBias = serializationObject.normalBias;\r\n        this.darkness = serializationObject.darkness;\r\n        this.filter = serializationObject.filter;\r\n        this.filteringQuality = serializationObject.filteringQuality;\r\n        this.transparencyShadow = serializationObject.transparencyShadow;\r\n        this.enableSoftTransparentShadow = serializationObject.enableSoftTransparentShadow;\r\n        this.useOpacityTextureForTransparentShadow = serializationObject.useOpacityTextureForTransparentShadow;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type SmartArrayNoDuplicate } from \"../Misc/smartArray\";\r\n\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type DepthRenderer } from \"./depthRenderer.pure\";\r\n\r\n/**\r\n * Defines the Depth Renderer scene component responsible to manage a depth buffer useful\r\n * in several rendering techniques.\r\n */\r\nexport class DepthRendererSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_DEPTHRENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_DEPTHRENDERER, this, this._gatherRenderTargets);\r\n        this.scene._gatherActiveCameraRenderTargetsStage.registerStep(\r\n            SceneComponentConstants.STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER,\r\n            this,\r\n            this._gatherActiveCameraRenderTargets\r\n        );\r\n        this.scene._isReadyForMeshStage.registerStep(SceneComponentConstants.STEP_ISREADYFORMESH_DEPTHRENDERER, this, this._isReadyForMesh);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        for (const key in this.scene._depthRenderer) {\r\n            this.scene._depthRenderer[key].dispose();\r\n        }\r\n    }\r\n\r\n    private _gatherRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {\r\n        if (this.scene._depthRenderer) {\r\n            for (const key in this.scene._depthRenderer) {\r\n                const depthRenderer = this.scene._depthRenderer[key];\r\n                if (depthRenderer.enabled && !depthRenderer.useOnlyInActiveCamera) {\r\n                    renderTargets.push(depthRenderer.getDepthMap());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _isReadyForMesh(mesh: AbstractMesh, hardwareInstancedRendering: boolean): boolean {\r\n        if (!this.scene._depthRenderer) {\r\n            return true;\r\n        }\r\n\r\n        for (const key in this.scene._depthRenderer) {\r\n            const depthRenderer = this.scene._depthRenderer[key];\r\n            if (!depthRenderer.enabled) {\r\n                continue;\r\n            }\r\n            if (mesh.subMeshes) {\r\n                for (let i = 0; i < mesh.subMeshes.length; ++i) {\r\n                    const subMesh = mesh.subMeshes[i];\r\n                    const material = subMesh.getMaterial();\r\n                    // Skip submeshes that the depth renderer would never render\r\n                    if (!material || material.disableDepthWrite || subMesh.verticesCount === 0) {\r\n                        continue;\r\n                    }\r\n                    if (!depthRenderer.isReady(subMesh, hardwareInstancedRendering)) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _gatherActiveCameraRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {\r\n        if (this.scene._depthRenderer) {\r\n            for (const key in this.scene._depthRenderer) {\r\n                const depthRenderer = this.scene._depthRenderer[key];\r\n                if (depthRenderer.enabled && depthRenderer.useOnlyInActiveCamera && `${this.scene.activeCamera!.uniqueId}` === key) {\r\n                    renderTargets.push(depthRenderer.getDepthMap());\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for depthRendererSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param depthRendererClass The DepthRenderer class to register the component for\r\n */\r\nexport function RegisterDepthRendererSceneComponent(depthRendererClass: typeof DepthRenderer): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.enableDepthRenderer = function (\r\n        camera?: Nullable<Camera>,\r\n        storeNonLinearDepth = false,\r\n        force32bitsFloat: boolean = false,\r\n        samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        storeCameraSpaceZ: boolean = false,\r\n        existingRenderTargetTexture?: RenderTargetTexture\r\n    ): DepthRenderer {\r\n        camera = camera || this.activeCamera;\r\n        if (!camera) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"No camera available to enable depth renderer\";\r\n        }\r\n        if (!this._depthRenderer) {\r\n            this._depthRenderer = {};\r\n        }\r\n        if (!this._depthRenderer[camera.uniqueId]) {\r\n            const supportFullfloat = !!this.getEngine().getCaps().textureFloatRender;\r\n            let textureType: number;\r\n            if (this.getEngine().getCaps().textureHalfFloatRender && (!force32bitsFloat || !supportFullfloat)) {\r\n                textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n            } else if (supportFullfloat) {\r\n                textureType = Constants.TEXTURETYPE_FLOAT;\r\n            } else {\r\n                textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            }\r\n            this._depthRenderer[camera.uniqueId] = new depthRendererClass(\r\n                this,\r\n                textureType,\r\n                camera,\r\n                storeNonLinearDepth,\r\n                samplingMode,\r\n                storeCameraSpaceZ,\r\n                undefined,\r\n                existingRenderTargetTexture\r\n            );\r\n        }\r\n\r\n        return this._depthRenderer[camera.uniqueId];\r\n    };\r\n\r\n    Scene.prototype.disableDepthRenderer = function (camera?: Nullable<Camera>): void {\r\n        camera = camera || this.activeCamera;\r\n        if (!camera || !this._depthRenderer || !this._depthRenderer[camera.uniqueId]) {\r\n            return;\r\n        }\r\n\r\n        this._depthRenderer[camera.uniqueId].dispose();\r\n    };\r\n\r\n    depthRendererClass._SceneComponentInitialization = (scene: Scene) => {\r\n        // Register the G Buffer component to the scene.\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_DEPTHRENDERER) as DepthRendererSceneComponent;\r\n        if (!component) {\r\n            component = new DepthRendererSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"../Materials/clipPlaneMaterialHelper\";\r\n\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { BindBonesParameters, BindMorphTargetParameters, PrepareDefinesAndAttributesForMorphTargets, PushAttributesForInstances } from \"../Materials/materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { EffectFallbacks } from \"core/Materials/effectFallbacks\";\r\nimport { type IEffectCreationOptions } from \"core/Materials/effect.pure\";\r\nimport { type GaussianSplattingMaterial } from \"../Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { type GaussianSplattingMesh } from \"../Meshes/GaussianSplatting/gaussianSplattingMesh.pure\";\r\nimport { _IsGaussianSplattingMesh } from \"../Meshes/GaussianSplatting/gaussianSplatting.functions\";\r\nimport { RegisterDepthRendererSceneComponent } from \"./depthRendererSceneComponent.pure\";\r\n\r\n/**\r\n * This represents a depth renderer in Babylon.\r\n * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing\r\n */\r\nexport class DepthRenderer {\r\n    private _scene: Scene;\r\n    private _depthMap: RenderTargetTexture;\r\n    private readonly _storeNonLinearDepth: boolean;\r\n    private readonly _storeCameraSpaceZ: boolean;\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Force all the depth renderer to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /** Color used to clear the depth texture. Default: (1,0,0,1) */\r\n    public clearColor: Color4;\r\n\r\n    /** Get if the depth renderer is using packed depth or not */\r\n    public readonly isPacked: boolean;\r\n\r\n    private _camera: Nullable<Camera>;\r\n\r\n    /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */\r\n    public enabled = true;\r\n\r\n    /** Force writing the transparent objects into the depth map */\r\n    public forceDepthWriteTransparentMeshes = false;\r\n\r\n    private _alphaBlendedDepth = false;\r\n    private _alphaBlendedDepthMaterialCache: Map<number, boolean> = new Map();\r\n\r\n    /**\r\n     * Enable or disable the alpha blending for depth rendering. When enabled,\r\n     * the depth renderer will blend the depth values with the alpha values of\r\n     * the transparent objects.\r\n     */\r\n    public get alphaBlendedDepth(): boolean {\r\n        return this._alphaBlendedDepth;\r\n    }\r\n    public set alphaBlendedDepth(value: boolean) {\r\n        if (this._alphaBlendedDepth === value) {\r\n            return;\r\n        }\r\n        this._alphaBlendedDepth = value;\r\n        // Clear the cache so materials will be recreated with the new define\r\n        this._alphaBlendedDepthMaterialCache.clear();\r\n    }\r\n\r\n    /**\r\n     * Specifies that the depth renderer will only be used within\r\n     * the camera it is created for.\r\n     * This can help forcing its rendering during the camera processing.\r\n     */\r\n    public useOnlyInActiveCamera: boolean = false;\r\n\r\n    /** If true, reverse the culling of materials before writing to the depth texture.\r\n     * So, basically, when \"true\", back facing instead of front facing faces are rasterized into the texture\r\n     */\r\n    public reverseCulling = false;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"DepthRendererSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * Sets a specific material to be used to render a mesh/a list of meshes by the depth renderer\r\n     * @param mesh mesh or array of meshes\r\n     * @param material material to use by the depth render when rendering the mesh(es). If undefined is passed, the specific material created by the depth renderer will be used.\r\n     */\r\n    public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material): void {\r\n        this._depthMap.setMaterialForRendering(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Ensures the GaussianSplatting depth material exists and is up to date for the given mesh.\r\n     * Creates the material on first call, and recreates it when alphaBlendedDepth changes.\r\n     * @param mesh the GaussianSplatting mesh\r\n     * @param renderPassId the render pass ID to look up the per-pass material\r\n     * @returns the current depth rendering material, or null if the mesh has no GS material\r\n     */\r\n    private _ensureGaussianSplattingDepthMaterial(mesh: AbstractMesh, renderPassId: number): Nullable<Material> {\r\n        let renderingMaterial = mesh._internalAbstractMeshDataInfo._materialForRenderPass?.[renderPassId];\r\n        const cachedAlphaBlendedDepth = this._alphaBlendedDepthMaterialCache.get(mesh.uniqueId);\r\n\r\n        if (renderingMaterial === undefined || cachedAlphaBlendedDepth !== this.alphaBlendedDepth) {\r\n            const gsMaterial = mesh.material as GaussianSplattingMaterial;\r\n            if (!gsMaterial) {\r\n                return null;\r\n            }\r\n            const compoundMesh = (mesh as unknown as GaussianSplattingMesh).isCompound;\r\n            renderingMaterial = gsMaterial.makeDepthRenderingMaterial(this._scene, this._shaderLanguage, this.alphaBlendedDepth, compoundMesh);\r\n            this.setMaterialForRendering(mesh, renderingMaterial);\r\n            this._alphaBlendedDepthMaterialCache.set(mesh.uniqueId, this.alphaBlendedDepth);\r\n        }\r\n\r\n        return renderingMaterial;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a depth renderer\r\n     * @param scene The scene the renderer belongs to\r\n     * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)\r\n     * @param camera The camera to be used to render the depth map (default: scene's active camera)\r\n     * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z\r\n     * @param samplingMode The sampling mode to be used with the render target (Linear, Nearest...) (default: TRILINEAR_SAMPLINGMODE)\r\n     * @param storeCameraSpaceZ Defines whether the depth stored is the Z coordinate in camera space. If true, storeNonLinearDepth has no effect. (Default: false)\r\n     * @param name Name of the render target (default: DepthRenderer)\r\n     * @param existingRenderTargetTexture An existing render target texture to use (default: undefined). If not provided, a new render target texture will be created.\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        type: number = Constants.TEXTURETYPE_FLOAT,\r\n        camera: Nullable<Camera> = null,\r\n        storeNonLinearDepth = false,\r\n        samplingMode = Texture.TRILINEAR_SAMPLINGMODE,\r\n        storeCameraSpaceZ = false,\r\n        name?: string,\r\n        existingRenderTargetTexture?: RenderTargetTexture\r\n    ) {\r\n        this._scene = scene;\r\n        this._storeNonLinearDepth = storeNonLinearDepth;\r\n        this._storeCameraSpaceZ = storeCameraSpaceZ;\r\n        this.isPacked = type === Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (this.isPacked) {\r\n            this.clearColor = new Color4(1.0, 1.0, 1.0, 1.0);\r\n        } else {\r\n            this.clearColor = new Color4(storeCameraSpaceZ ? 0.0 : 1.0, 0.0, 0.0, 1.0);\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n\r\n        RegisterDepthRendererSceneComponent(DepthRenderer);\r\n        DepthRenderer._SceneComponentInitialization(this._scene);\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        this._camera = camera;\r\n\r\n        if (samplingMode !== Texture.NEAREST_SAMPLINGMODE) {\r\n            if (type === Constants.TEXTURETYPE_FLOAT && !engine._caps.textureFloatLinearFiltering) {\r\n                samplingMode = Texture.NEAREST_SAMPLINGMODE;\r\n            }\r\n            if (type === Constants.TEXTURETYPE_HALF_FLOAT && !engine._caps.textureHalfFloatLinearFiltering) {\r\n                samplingMode = Texture.NEAREST_SAMPLINGMODE;\r\n            }\r\n        }\r\n\r\n        // Render target\r\n        const format = this.isPacked || !engine._features.supportExtendedTextureFormats ? Constants.TEXTUREFORMAT_RGBA : Constants.TEXTUREFORMAT_R;\r\n        this._depthMap =\r\n            existingRenderTargetTexture ??\r\n            new RenderTargetTexture(\r\n                name ?? \"DepthRenderer\",\r\n                { width: engine.getRenderWidth(), height: engine.getRenderHeight() },\r\n                this._scene,\r\n                false,\r\n                true,\r\n                type,\r\n                false,\r\n                samplingMode,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                format\r\n            );\r\n        this._depthMap.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._depthMap.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._depthMap.refreshRate = 1;\r\n        this._depthMap.renderParticles = false;\r\n        this._depthMap.renderList = null;\r\n        this._depthMap.noPrePassRenderer = true;\r\n\r\n        // Camera to get depth map from to support multiple concurrent cameras\r\n        this._depthMap.activeCamera = this._camera;\r\n        this._depthMap.ignoreCameraViewport = true;\r\n        this._depthMap.useCameraPostProcesses = false;\r\n\r\n        // set default depth value to 1.0 (far away)\r\n        this._depthMap.onClearObservable.add((engine) => {\r\n            engine.clear(this.clearColor, true, true, true);\r\n        });\r\n\r\n        this._depthMap.customIsReadyFunction = (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => {\r\n            if ((preWarm || refreshRate === 0) && mesh.subMeshes) {\r\n                for (let i = 0; i < mesh.subMeshes.length; ++i) {\r\n                    const subMesh = mesh.subMeshes[i];\r\n                    const material = subMesh.getMaterial();\r\n                    const effectiveMesh = subMesh.getEffectiveMesh();\r\n\r\n                    // Skip submeshes that won't be rendered by the depth renderer (mirroring renderSubMesh logic)\r\n                    if (!material || effectiveMesh.infiniteDistance || material.disableDepthWrite || subMesh.verticesCount === 0) {\r\n                        continue;\r\n                    }\r\n\r\n                    const renderingMesh = subMesh.getRenderingMesh();\r\n\r\n                    const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n                    const hardwareInstancedRendering =\r\n                        engine.getCaps().instancedArrays &&\r\n                        ((batch.visibleInstances[subMesh._id] !== null && batch.visibleInstances[subMesh._id] !== undefined) || renderingMesh.hasThinInstances);\r\n\r\n                    if (!this.isReady(subMesh, hardwareInstancedRendering)) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return true;\r\n        };\r\n\r\n        // Custom render function\r\n        const renderSubMesh = (subMesh: SubMesh): void => {\r\n            const renderingMesh = subMesh.getRenderingMesh();\r\n            const effectiveMesh = subMesh.getEffectiveMesh();\r\n            const scene = this._scene;\r\n            const engine = scene.getEngine();\r\n            const material = subMesh.getMaterial();\r\n\r\n            effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n\r\n            if (!material || effectiveMesh.infiniteDistance || material.disableDepthWrite || subMesh.verticesCount === 0 || subMesh._renderId === scene.getRenderId()) {\r\n                return;\r\n            }\r\n\r\n            // Culling\r\n            const detNeg = effectiveMesh._getWorldMatrixDeterminant() < 0;\r\n            let sideOrientation = material._getEffectiveOrientation(renderingMesh);\r\n\r\n            if (detNeg) {\r\n                sideOrientation =\r\n                    sideOrientation === Constants.MATERIAL_ClockWiseSideOrientation\r\n                        ? Constants.MATERIAL_CounterClockWiseSideOrientation\r\n                        : Constants.MATERIAL_ClockWiseSideOrientation;\r\n            }\r\n            const reverseSideOrientation = sideOrientation === Constants.MATERIAL_ClockWiseSideOrientation;\r\n\r\n            engine.setState(material.backFaceCulling, 0, false, reverseSideOrientation, this.reverseCulling ? !material.cullBackFaces : material.cullBackFaces);\r\n\r\n            // Managing instances\r\n            const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n\r\n            if (batch.mustReturn) {\r\n                return;\r\n            }\r\n\r\n            const hardwareInstancedRendering =\r\n                engine.getCaps().instancedArrays &&\r\n                ((batch.visibleInstances[subMesh._id] !== null && batch.visibleInstances[subMesh._id] !== undefined) || renderingMesh.hasThinInstances);\r\n\r\n            const camera = this._camera || scene.activeCamera;\r\n            if (this.isReady(subMesh, hardwareInstancedRendering) && camera) {\r\n                subMesh._renderId = scene.getRenderId();\r\n\r\n                if (_IsGaussianSplattingMesh(effectiveMesh)) {\r\n                    const gsMaterial = this._ensureGaussianSplattingDepthMaterial(effectiveMesh, engine.currentRenderPassId);\r\n                    if (gsMaterial && !gsMaterial.isReadyForSubMesh(effectiveMesh, subMesh, hardwareInstancedRendering)) {\r\n                        return;\r\n                    }\r\n                    // Alpha blending for transparent materials\r\n                    if (this.alphaBlendedDepth && material.needAlphaBlendingForMesh(effectiveMesh)) {\r\n                        engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n                    } else {\r\n                        engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n                    }\r\n                    // Delegate to the GS mesh's render() which properly routes through camera meshes\r\n                    // with the correct thin instance data. The depth material is already set as the\r\n                    // render pass material and will be propagated to the camera mesh.\r\n                    (effectiveMesh as Mesh).render(subMesh, false);\r\n                    return;\r\n                }\r\n\r\n                const renderingMaterial = effectiveMesh._internalAbstractMeshDataInfo._materialForRenderPass?.[engine.currentRenderPassId];\r\n                let drawWrapper = subMesh._getDrawWrapper();\r\n                if (!drawWrapper && renderingMaterial) {\r\n                    drawWrapper = renderingMaterial._getDrawWrapper();\r\n                }\r\n                const cameraIsOrtho = camera.mode === Camera.ORTHOGRAPHIC_CAMERA;\r\n\r\n                if (!drawWrapper) {\r\n                    return;\r\n                }\r\n\r\n                const effect = drawWrapper.effect!;\r\n\r\n                engine.enableEffect(drawWrapper);\r\n\r\n                if (!hardwareInstancedRendering) {\r\n                    renderingMesh._bind(subMesh, effect, material.fillMode);\r\n                }\r\n\r\n                if (!renderingMaterial) {\r\n                    effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\r\n                    effect.setMatrix(\"world\", effectiveMesh.getWorldMatrix());\r\n                    if (this._storeCameraSpaceZ) {\r\n                        effect.setMatrix(\"view\", scene.getViewMatrix());\r\n                    }\r\n                } else {\r\n                    renderingMaterial.bindForSubMesh(effectiveMesh.getWorldMatrix(), effectiveMesh as Mesh, subMesh);\r\n                }\r\n\r\n                let minZ: number, maxZ: number;\r\n\r\n                if (cameraIsOrtho) {\r\n                    minZ = !engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\r\n                    maxZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;\r\n                } else {\r\n                    minZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? camera.minZ : engine.isNDCHalfZRange ? 0 : camera.minZ;\r\n                    maxZ = engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : camera.maxZ;\r\n                }\r\n\r\n                effect.setFloat2(\"depthValues\", minZ, minZ + maxZ);\r\n\r\n                if (!renderingMaterial) {\r\n                    // Alpha test\r\n                    if (material.needAlphaTestingForMesh(effectiveMesh)) {\r\n                        const alphaTexture = material.getAlphaTestTexture();\r\n\r\n                        if (alphaTexture) {\r\n                            effect.setTexture(\"diffuseSampler\", alphaTexture);\r\n                            effect.setMatrix(\"diffuseMatrix\", alphaTexture.getTextureMatrix());\r\n                        }\r\n                    }\r\n\r\n                    // Bones\r\n                    BindBonesParameters(renderingMesh, effect);\r\n\r\n                    // Clip planes\r\n                    BindClipPlane(effect, material, scene);\r\n\r\n                    // Morph targets\r\n                    BindMorphTargetParameters(renderingMesh, effect);\r\n                    if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\r\n                        renderingMesh.morphTargetManager._bind(effect);\r\n                    }\r\n\r\n                    // Baked vertex animations\r\n                    const bvaManager = subMesh.getMesh().bakedVertexAnimationManager;\r\n                    if (bvaManager && bvaManager.isEnabled) {\r\n                        bvaManager.bind(effect, hardwareInstancedRendering);\r\n                    }\r\n\r\n                    // Points cloud rendering\r\n                    if (material.pointsCloud) {\r\n                        effect.setFloat(\"pointSize\", material.pointSize);\r\n                    }\r\n                }\r\n\r\n                // Alpha blending for transparent materials\r\n                if (this.alphaBlendedDepth && material.needAlphaBlendingForMesh(effectiveMesh)) {\r\n                    engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n                } else {\r\n                    engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n                }\r\n\r\n                // Draw\r\n                renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, world) =>\r\n                    effect.setMatrix(\"world\", world)\r\n                );\r\n            }\r\n        };\r\n\r\n        this._depthMap.customRenderFunction = (\r\n            opaqueSubMeshes: SmartArray<SubMesh>,\r\n            alphaTestSubMeshes: SmartArray<SubMesh>,\r\n            transparentSubMeshes: SmartArray<SubMesh>,\r\n            depthOnlySubMeshes: SmartArray<SubMesh>\r\n        ): void => {\r\n            const engine = this._scene.getEngine();\r\n            // Save the current alpha mode to restore it after rendering\r\n            const previousAlphaMode = engine.getAlphaMode();\r\n\r\n            let index;\r\n\r\n            if (depthOnlySubMeshes.length) {\r\n                for (index = 0; index < depthOnlySubMeshes.length; index++) {\r\n                    renderSubMesh(depthOnlySubMeshes.data[index]);\r\n                }\r\n            }\r\n\r\n            for (index = 0; index < opaqueSubMeshes.length; index++) {\r\n                renderSubMesh(opaqueSubMeshes.data[index]);\r\n            }\r\n\r\n            for (index = 0; index < alphaTestSubMeshes.length; index++) {\r\n                renderSubMesh(alphaTestSubMeshes.data[index]);\r\n            }\r\n\r\n            if (this.forceDepthWriteTransparentMeshes) {\r\n                for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                    renderSubMesh(transparentSubMeshes.data[index]);\r\n                }\r\n            } else {\r\n                for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                    transparentSubMeshes.data[index].getEffectiveMesh()._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n                }\r\n            }\r\n\r\n            if (this.alphaBlendedDepth) {\r\n                engine.setAlphaMode(previousAlphaMode);\r\n            }\r\n        };\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n    private async _initShaderSourceAsync(forceGLSL = false) {\r\n        const engine = this._scene.getEngine();\r\n\r\n        if (engine.isWebGPU && !forceGLSL && !DepthRenderer.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([import(\"../ShadersWGSL/depth.vertex\"), import(\"../ShadersWGSL/depth.fragment\")]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/depth.vertex\"), import(\"../Shaders/depth.fragment\")]);\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n    }\r\n\r\n    /**\r\n     * Creates the depth rendering effect and checks if the effect is ready.\r\n     * @param subMesh The submesh to be used to render the depth map of\r\n     * @param useInstances If multiple world instances should be used\r\n     * @returns if the depth renderer is ready to render the depth map\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        if (!this._shadersLoaded) {\r\n            return false;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n        const mesh = subMesh.getMesh();\r\n        const scene = mesh.getScene();\r\n\r\n        // Use the depth map's render pass ID to look up per-pass materials,\r\n        // since isReady can be called outside of the depth renderer's render pass\r\n        // (e.g. from the scene's isReady check).\r\n        const renderPassId = this._depthMap.renderPassId;\r\n        let renderingMaterial: Nullable<Material> = mesh._internalAbstractMeshDataInfo._materialForRenderPass?.[renderPassId] ?? null;\r\n\r\n        // For GaussianSplatting meshes, eagerly create the depth material so that\r\n        // the scene's isReady check properly blocks until it is compiled.\r\n        if (_IsGaussianSplattingMesh(mesh)) {\r\n            renderingMaterial = this._ensureGaussianSplattingDepthMaterial(mesh, renderPassId);\r\n        }\r\n\r\n        if (renderingMaterial) {\r\n            return renderingMaterial.isReadyForSubMesh(mesh, subMesh, useInstances);\r\n        }\r\n\r\n        const material = subMesh.getMaterial();\r\n        if (!material || material.disableDepthWrite) {\r\n            return false;\r\n        }\r\n\r\n        const defines = [];\r\n\r\n        const attribs = [VertexBuffer.PositionKind];\r\n\r\n        let uv1 = false;\r\n        let uv2 = false;\r\n        const color = false;\r\n\r\n        // Alpha test\r\n        if (material.needAlphaTestingForMesh(mesh) && material.getAlphaTestTexture()) {\r\n            defines.push(\"#define ALPHATEST\");\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                attribs.push(VertexBuffer.UVKind);\r\n                defines.push(\"#define UV1\");\r\n                uv1 = true;\r\n            }\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n                attribs.push(VertexBuffer.UV2Kind);\r\n                defines.push(\"#define UV2\");\r\n                uv2 = true;\r\n            }\r\n        }\r\n\r\n        // Bones\r\n        const fallbacks = new EffectFallbacks();\r\n        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n            attribs.push(VertexBuffer.MatricesIndicesKind);\r\n            attribs.push(VertexBuffer.MatricesWeightsKind);\r\n            if (mesh.numBoneInfluencers > 4) {\r\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n            }\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n            if (mesh.numBoneInfluencers > 0) {\r\n                fallbacks.addCPUSkinningFallback(0, mesh);\r\n            }\r\n\r\n            const skeleton = mesh.skeleton;\r\n            if (skeleton.isUsingTextureForMatrices) {\r\n                defines.push(\"#define BONETEXTURE\");\r\n            } else {\r\n                defines.push(\"#define BonesPerMesh \" + (skeleton.bones.length + 1));\r\n            }\r\n        } else {\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n        }\r\n\r\n        // Morph targets\r\n        const numMorphInfluencers = mesh.morphTargetManager\r\n            ? PrepareDefinesAndAttributesForMorphTargets(\r\n                  mesh.morphTargetManager,\r\n                  defines,\r\n                  attribs,\r\n                  mesh,\r\n                  true, // usePositionMorph\r\n                  false, // useNormalMorph\r\n                  false, // useTangentMorph\r\n                  uv1, // useUVMorph\r\n                  uv2, // useUV2Morph\r\n                  color // useColorMorph\r\n              )\r\n            : 0;\r\n\r\n        // Points cloud rendering\r\n        if (material.pointsCloud) {\r\n            defines.push(\"#define POINTSIZE\");\r\n        }\r\n\r\n        // Instances\r\n        if (useInstances) {\r\n            defines.push(\"#define INSTANCES\");\r\n            PushAttributesForInstances(attribs);\r\n            if (subMesh.getRenderingMesh().hasThinInstances) {\r\n                defines.push(\"#define THIN_INSTANCES\");\r\n            }\r\n        }\r\n\r\n        // Baked vertex animations\r\n        const bvaManager = mesh.bakedVertexAnimationManager;\r\n        if (bvaManager && bvaManager.isEnabled) {\r\n            defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\r\n            if (useInstances) {\r\n                attribs.push(\"bakedVertexAnimationSettingsInstanced\");\r\n            }\r\n        }\r\n\r\n        // None linear depth\r\n        if (this._storeNonLinearDepth) {\r\n            defines.push(\"#define NONLINEARDEPTH\");\r\n        }\r\n\r\n        // Store camera space Z coordinate instead of NDC Z\r\n        if (this._storeCameraSpaceZ) {\r\n            defines.push(\"#define STORE_CAMERASPACE_Z\");\r\n        }\r\n\r\n        // Float Mode\r\n        if (this.isPacked) {\r\n            defines.push(\"#define PACKED\");\r\n        }\r\n\r\n        // Clip planes\r\n        PrepareStringDefinesForClipPlanes(material, scene, defines);\r\n\r\n        // Get correct effect\r\n        // Determine which render pass id to use for the draw wrapper. isReady can be called from\r\n        // contexts where engine.currentRenderPassId is *not* one of the depth map's render pass ids\r\n        // (e.g. from EffectLayer / scene readiness checks). In that case, using\r\n        // engine.currentRenderPassId would stamp the depth effect onto the main pass's draw wrapper,\r\n        // which is especially harmful for frozen materials that won't restore the correct effect on\r\n        // their next isReady call (forum bug 63230).\r\n        // When engine.currentRenderPassId already belongs to this depth map (the normal in-pass\r\n        // case, including multi-pass render targets like cube/array depth textures), keep using it\r\n        // so each pass keeps its own draw wrapper. Otherwise fall back to the depth map's primary\r\n        // render pass id.\r\n        const currentPassId = engine.currentRenderPassId;\r\n        const depthPassIds = this._depthMap.renderPassIds;\r\n        const passId = depthPassIds.includes(currentPassId) ? currentPassId : this._depthMap.renderPassId;\r\n        const drawWrapper = subMesh._getDrawWrapper(passId, true)!;\r\n        const cachedDefines = drawWrapper.defines;\r\n        const join = defines.join(\"\\n\");\r\n        if (cachedDefines !== join) {\r\n            const uniforms = [\r\n                \"world\",\r\n                \"mBones\",\r\n                \"boneTextureInfo\",\r\n                \"pointSize\",\r\n                \"viewProjection\",\r\n                \"view\",\r\n                \"diffuseMatrix\",\r\n                \"depthValues\",\r\n                \"morphTargetInfluences\",\r\n                \"morphTargetCount\",\r\n                \"morphTargetTextureInfo\",\r\n                \"morphTargetTextureIndices\",\r\n                \"bakedVertexAnimationSettings\",\r\n                \"bakedVertexAnimationTextureSizeInverted\",\r\n                \"bakedVertexAnimationTime\",\r\n                \"bakedVertexAnimationTexture\",\r\n            ];\r\n            const samplers = [\"diffuseSampler\", \"morphTargets\", \"boneSampler\", \"bakedVertexAnimationTexture\"];\r\n\r\n            AddClipPlaneUniforms(uniforms);\r\n\r\n            drawWrapper.setEffect(\r\n                engine.createEffect(\r\n                    \"depth\",\r\n                    <IEffectCreationOptions>{\r\n                        attributes: attribs,\r\n                        uniformsNames: uniforms,\r\n                        uniformBuffersNames: [],\r\n                        samplers: samplers,\r\n                        defines: join,\r\n                        fallbacks: fallbacks,\r\n                        onCompiled: null,\r\n                        onError: null,\r\n                        indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                        shaderLanguage: this._shaderLanguage,\r\n                    },\r\n                    engine\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        return drawWrapper.effect!.isReady();\r\n    }\r\n\r\n    /**\r\n     * Gets the texture which the depth map will be written to.\r\n     * @returns The depth map texture\r\n     */\r\n    public getDepthMap(): RenderTargetTexture {\r\n        return this._depthMap;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the depth renderer.\r\n     */\r\n    public dispose(): void {\r\n        const keysToDelete = [];\r\n        for (const key in this._scene._depthRenderer) {\r\n            const depthRenderer = this._scene._depthRenderer[key];\r\n            if (depthRenderer === this) {\r\n                keysToDelete.push(key);\r\n            }\r\n        }\r\n\r\n        if (keysToDelete.length > 0) {\r\n            this._depthMap.dispose();\r\n\r\n            for (const key of keysToDelete) {\r\n                delete this._scene._depthRenderer[key];\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type Nullable, type EffectWrapperCreationOptions, type AbstractEngine, type InternalTexture, type Scene } from \"core/index\";\r\nimport { Observable } from \"./observable\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport const enum DepthTextureType {\r\n    NormalizedViewDepth = 0,\r\n    ViewDepth = 1,\r\n    ScreenDepth = 2,\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinMinMaxReducerPostProcess extends EffectWrapper {\r\n    public static readonly FragmentUrl = \"minmaxRedux\";\r\n\r\n    public static readonly Uniforms = [\"texSize\"];\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/minmaxRedux.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/minmaxRedux.fragment\"));\r\n        }\r\n    }\r\n\r\n    public textureWidth = 0;\r\n\r\n    public textureHeight = 0;\r\n\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, defines = \"\", options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinMinMaxReducerPostProcess.FragmentUrl,\r\n            uniforms: ThinMinMaxReducerPostProcess.Uniforms,\r\n            defines,\r\n        });\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        const effect = this.drawWrapper.effect!;\r\n\r\n        if (this.textureWidth === 1 || this.textureHeight === 1) {\r\n            effect.setInt2(\"texSize\", this.textureWidth, this.textureHeight);\r\n        } else {\r\n            effect.setFloat2(\"texSize\", this.textureWidth, this.textureHeight);\r\n        }\r\n    }\r\n}\r\n\r\nconst BufferFloat = new Float32Array(4 * 1 * 1);\r\nconst BufferUint8 = new Uint8Array(4 * 1 * 1);\r\nconst MinMax = { min: 0, max: 0 };\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class ThinMinMaxReducer {\r\n    public readonly onAfterReductionPerformed = new Observable<{ min: number; max: number }>();\r\n\r\n    public readonly reductionSteps: Array<ThinMinMaxReducerPostProcess>;\r\n\r\n    private _depthRedux: boolean;\r\n    private _depthTextureType: DepthTextureType;\r\n\r\n    public get depthRedux() {\r\n        return this._depthRedux;\r\n    }\r\n\r\n    public set depthRedux(value: boolean) {\r\n        if (this._depthRedux === value) {\r\n            return;\r\n        }\r\n\r\n        this._depthRedux = value;\r\n\r\n        this._recreatePostProcesses();\r\n    }\r\n\r\n    protected readonly _scene: Scene;\r\n\r\n    private _textureWidth = 0;\r\n    private _textureHeight = 0;\r\n\r\n    public get textureWidth() {\r\n        return this._textureWidth;\r\n    }\r\n\r\n    public get textureHeight() {\r\n        return this._textureHeight;\r\n    }\r\n\r\n    constructor(scene: Scene, depthRedux = true) {\r\n        this._scene = scene;\r\n        this._depthRedux = depthRedux;\r\n        this.reductionSteps = [];\r\n    }\r\n\r\n    public setTextureDimensions(width: number, height: number, depthTextureType: DepthTextureType = DepthTextureType.NormalizedViewDepth) {\r\n        if (width === this._textureWidth && height === this._textureHeight && depthTextureType === this._depthTextureType) {\r\n            return false;\r\n        }\r\n\r\n        this._textureWidth = width;\r\n        this._textureHeight = height;\r\n        this._depthTextureType = depthTextureType;\r\n\r\n        this._recreatePostProcesses();\r\n\r\n        return true;\r\n    }\r\n\r\n    public readMinMax(texture: InternalTexture) {\r\n        // Note that we should normally await the call to _readTexturePixels!\r\n        // But because WebGL does the read synchronously, we know the values will be updated without waiting for the promise to be resolved, which will let us get the updated values\r\n        // in the current frame, whereas in WebGPU, the read is asynchronous and we should normally wait for the promise to be resolved to get the updated values.\r\n        // However, it's safe to avoid waiting for the promise to be resolved in WebGPU as well, because we will simply use the current values until \"buffer\" is updated later on.\r\n        // Note that it means we can suffer some rendering artifacts in WebGPU because we may use previous min/max values for the current frame.\r\n        const isFloat = texture.type === Constants.TEXTURETYPE_FLOAT || texture.type === Constants.TEXTURETYPE_HALF_FLOAT;\r\n        const buffer = isFloat ? BufferFloat : BufferUint8;\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._scene.getEngine()._readTexturePixels(texture, 1, 1, -1, 0, buffer, false);\r\n\r\n        MinMax.min = buffer[0];\r\n        MinMax.max = buffer[1];\r\n\r\n        if (!isFloat) {\r\n            MinMax.min = MinMax.min / 255.0;\r\n            MinMax.max = MinMax.max / 255.0;\r\n        }\r\n\r\n        if (MinMax.min >= MinMax.max) {\r\n            MinMax.min = 0;\r\n            MinMax.max = 1;\r\n        }\r\n\r\n        this.onAfterReductionPerformed.notifyObservers(MinMax);\r\n    }\r\n\r\n    public dispose(disposeAll = true): void {\r\n        if (disposeAll) {\r\n            this.onAfterReductionPerformed.clear();\r\n            this._textureWidth = 0;\r\n            this._textureHeight = 0;\r\n        }\r\n\r\n        for (let i = 0; i < this.reductionSteps.length; ++i) {\r\n            this.reductionSteps[i].dispose();\r\n        }\r\n        this.reductionSteps.length = 0;\r\n    }\r\n\r\n    private _recreatePostProcesses() {\r\n        this.dispose(false);\r\n\r\n        const scene = this._scene;\r\n\r\n        let w = this.textureWidth,\r\n            h = this.textureHeight;\r\n\r\n        const reductionInitial = new ThinMinMaxReducerPostProcess(\r\n            \"Initial reduction phase\",\r\n            scene.getEngine(),\r\n            \"#define INITIAL\" + (this._depthRedux ? \"\\n#define DEPTH_REDUX\" : \"\") + (this._depthTextureType === DepthTextureType.ViewDepth ? \"\\n#define VIEW_DEPTH\" : \"\")\r\n        );\r\n\r\n        reductionInitial.textureWidth = w;\r\n        reductionInitial.textureHeight = h;\r\n\r\n        this.reductionSteps.push(reductionInitial);\r\n\r\n        let index = 1;\r\n\r\n        // create the additional steps\r\n        while (w > 1 || h > 1) {\r\n            w = Math.max(Math.round(w / 2), 1);\r\n            h = Math.max(Math.round(h / 2), 1);\r\n\r\n            const reduction = new ThinMinMaxReducerPostProcess(\r\n                \"Reduction phase \" + index,\r\n                scene.getEngine(),\r\n                \"#define \" + (w == 1 && h == 1 ? \"LAST\" : w == 1 || h == 1 ? \"ONEBEFORELAST\" : \"MAIN\")\r\n            );\r\n\r\n            reduction.textureWidth = w;\r\n            reduction.textureHeight = h;\r\n\r\n            this.reductionSteps.push(reduction);\r\n\r\n            index++;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Observer } from \"./observable.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { PostProcessManager } from \"../PostProcesses/postProcessManager\";\r\n\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { ThinMinMaxReducer, ThinMinMaxReducerPostProcess } from \"./thinMinMaxReducer\";\r\n\r\n/**\r\n * This class computes a min/max reduction from a texture: it means it computes the minimum\r\n * and maximum values from all values of the texture.\r\n * It is performed on the GPU for better performances, thanks to a succession of post processes.\r\n * The source values are read from the red channel of the texture.\r\n */\r\nexport class MinMaxReducer {\r\n    /**\r\n     * Observable triggered when the computation has been performed\r\n     */\r\n    public get onAfterReductionPerformed() {\r\n        return this._thinMinMaxReducer.onAfterReductionPerformed;\r\n    }\r\n\r\n    protected readonly _camera: Camera;\r\n    protected readonly _thinMinMaxReducer: ThinMinMaxReducer;\r\n    protected _sourceTexture: Nullable<RenderTargetTexture>;\r\n    protected readonly _reductionSteps: Array<PostProcess>;\r\n    protected readonly _postProcessManager: PostProcessManager;\r\n    protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>> = null;\r\n    protected _forceFullscreenViewport = true;\r\n    protected readonly _onContextRestoredObserver: Observer<AbstractEngine>;\r\n\r\n    /**\r\n     * Creates a min/max reducer\r\n     * @param camera The camera to use for the post processes\r\n     */\r\n    constructor(camera: Camera) {\r\n        this._camera = camera;\r\n        this._postProcessManager = new PostProcessManager(camera.getScene());\r\n        this._thinMinMaxReducer = new ThinMinMaxReducer(camera.getScene());\r\n        this._reductionSteps = [];\r\n\r\n        this._onContextRestoredObserver = camera.getEngine().onContextRestoredObservable.add(() => {\r\n            this._postProcessManager._rebuild();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the texture used to read the values from.\r\n     */\r\n    public get sourceTexture(): Nullable<RenderTargetTexture> {\r\n        return this._sourceTexture;\r\n    }\r\n\r\n    /**\r\n     * Sets the source texture to read the values from.\r\n     * One must indicate if the texture is a depth texture or not through the depthRedux parameter\r\n     * because in such textures '1' value must not be taken into account to compute the maximum\r\n     * as this value is used to clear the texture.\r\n     * Note that the computation is not activated by calling this function, you must call activate() for that!\r\n     * @param sourceTexture The texture to read the values from. The values should be in the red channel.\r\n     * @param depthRedux Indicates if the texture is a depth texture or not\r\n     * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)\r\n     * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)\r\n     */\r\n    public setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type: number = Constants.TEXTURETYPE_HALF_FLOAT, forceFullscreenViewport = true): void {\r\n        if (sourceTexture === this._sourceTexture) {\r\n            return;\r\n        }\r\n\r\n        this._thinMinMaxReducer.depthRedux = depthRedux;\r\n\r\n        this.deactivate();\r\n\r\n        this._sourceTexture = sourceTexture;\r\n        this._forceFullscreenViewport = forceFullscreenViewport;\r\n\r\n        if (this._thinMinMaxReducer.setTextureDimensions(sourceTexture.getRenderWidth(), sourceTexture.getRenderHeight())) {\r\n            this._disposePostProcesses();\r\n\r\n            const reductionSteps = this._thinMinMaxReducer.reductionSteps;\r\n\r\n            for (let i = 0; i < reductionSteps.length; ++i) {\r\n                const reductionStep = reductionSteps[i];\r\n\r\n                const postProcess = new PostProcess(reductionStep.name, ThinMinMaxReducerPostProcess.FragmentUrl, {\r\n                    effectWrapper: reductionStep,\r\n                    samplingMode: Constants.TEXTURE_NEAREST_NEAREST,\r\n                    engine: this._camera.getScene().getEngine(),\r\n                    textureType: type,\r\n                    textureFormat: Constants.TEXTUREFORMAT_RG,\r\n                    size: { width: reductionStep.textureWidth, height: reductionStep.textureHeight },\r\n                });\r\n\r\n                this._reductionSteps.push(postProcess);\r\n\r\n                postProcess.autoClear = false;\r\n                postProcess.forceFullscreenViewport = forceFullscreenViewport;\r\n\r\n                if (i === 0) {\r\n                    postProcess.externalTextureSamplerBinding = true;\r\n                    postProcess.onApplyObservable.add((effect: Effect) => {\r\n                        effect.setTexture(\"textureSampler\", this._sourceTexture);\r\n                    });\r\n                }\r\n\r\n                if (i === reductionSteps.length - 1) {\r\n                    this._reductionSteps[i - 1].onAfterRenderObservable.add(() => {\r\n                        this._thinMinMaxReducer.readMinMax(postProcess.inputTexture.texture!);\r\n                    });\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the refresh rate of the computation.\r\n     * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...\r\n     */\r\n    public get refreshRate(): number {\r\n        return this._sourceTexture ? this._sourceTexture.refreshRate : -1;\r\n    }\r\n\r\n    public set refreshRate(value: number) {\r\n        if (this._sourceTexture) {\r\n            this._sourceTexture.refreshRate = value;\r\n        }\r\n    }\r\n\r\n    protected _activated = false;\r\n\r\n    /**\r\n     * Gets the activation status of the reducer\r\n     */\r\n    public get activated(): boolean {\r\n        return this._activated;\r\n    }\r\n\r\n    /**\r\n     * Activates the reduction computation.\r\n     * When activated, the observers registered in onAfterReductionPerformed are\r\n     * called after the computation is performed\r\n     */\r\n    public activate(): void {\r\n        if (this._onAfterUnbindObserver || !this._sourceTexture) {\r\n            return;\r\n        }\r\n\r\n        this._onAfterUnbindObserver = this._sourceTexture.onAfterUnbindObservable.add(() => {\r\n            const engine = this._camera.getScene().getEngine();\r\n            engine._debugPushGroup?.(`min max reduction`);\r\n            this._reductionSteps![0].activate(this._camera);\r\n            this._postProcessManager.directRender(\r\n                this._reductionSteps!,\r\n                this._reductionSteps![0].inputTexture,\r\n                this._forceFullscreenViewport,\r\n                0,\r\n                0,\r\n                true,\r\n                this._reductionSteps.length - 1\r\n            );\r\n            engine.unBindFramebuffer(this._reductionSteps![this._reductionSteps.length - 1].inputTexture, false);\r\n            engine._debugPopGroup?.();\r\n        });\r\n\r\n        this._activated = true;\r\n    }\r\n\r\n    /**\r\n     * Deactivates the reduction computation.\r\n     */\r\n    public deactivate(): void {\r\n        if (!this._onAfterUnbindObserver || !this._sourceTexture) {\r\n            return;\r\n        }\r\n\r\n        this._sourceTexture.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);\r\n        this._onAfterUnbindObserver = null;\r\n        this._activated = false;\r\n    }\r\n\r\n    /**\r\n     * Disposes the min/max reducer\r\n     * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.\r\n     */\r\n    public dispose(disposeAll = true): void {\r\n        if (!disposeAll) {\r\n            return;\r\n        }\r\n\r\n        this.onAfterReductionPerformed.clear();\r\n\r\n        this._camera.getEngine().onContextRestoredObservable.remove(this._onContextRestoredObserver);\r\n        (this._onContextRestoredObserver as any) = undefined;\r\n\r\n        this._disposePostProcesses();\r\n\r\n        this._postProcessManager.dispose();\r\n        (this._postProcessManager as any) = undefined as any;\r\n        this._thinMinMaxReducer.dispose();\r\n        (this._thinMinMaxReducer as any) = undefined;\r\n        this._sourceTexture = null;\r\n    }\r\n\r\n    private _disposePostProcesses() {\r\n        for (let i = 0; i < this._reductionSteps.length; ++i) {\r\n            this._reductionSteps[i].dispose();\r\n        }\r\n        this._reductionSteps.length = 0;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { DepthRenderer } from \"../Rendering/depthRenderer.pure\";\r\n\r\nimport { MinMaxReducer } from \"./minMaxReducer.pure\";\r\n\r\n/**\r\n * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture\r\n */\r\nexport class DepthReducer extends MinMaxReducer {\r\n    private _depthRenderer: Nullable<DepthRenderer>;\r\n    private _depthRendererId: string;\r\n\r\n    /**\r\n     * Gets the depth renderer used for the computation.\r\n     * Note that the result is null if you provide your own renderer when calling setDepthRenderer.\r\n     */\r\n    public get depthRenderer(): Nullable<DepthRenderer> {\r\n        return this._depthRenderer;\r\n    }\r\n\r\n    /**\r\n     * Creates a depth reducer\r\n     * @param camera The camera used to render the depth texture\r\n     */\r\n    constructor(camera: Camera) {\r\n        super(camera);\r\n    }\r\n\r\n    /**\r\n     * Sets the depth renderer to use to generate the depth map\r\n     * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically\r\n     * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)\r\n     * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)\r\n     */\r\n    public setDepthRenderer(depthRenderer: Nullable<DepthRenderer> = null, type: number = Constants.TEXTURETYPE_HALF_FLOAT, forceFullscreenViewport = true): void {\r\n        const scene = this._camera.getScene();\r\n\r\n        if (this._depthRenderer) {\r\n            delete scene._depthRenderer[this._depthRendererId];\r\n\r\n            this._depthRenderer.dispose();\r\n            this._depthRenderer = null;\r\n        }\r\n\r\n        if (depthRenderer === null) {\r\n            if (!scene._depthRenderer) {\r\n                scene._depthRenderer = {};\r\n            }\r\n\r\n            this._depthRendererId = \"minmax_\" + this._camera.uniqueId;\r\n\r\n            depthRenderer = this._depthRenderer = new DepthRenderer(\r\n                scene,\r\n                type,\r\n                this._camera,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                false,\r\n                `DepthRenderer ${this._depthRendererId}`\r\n            );\r\n            depthRenderer.enabled = false;\r\n\r\n            scene._depthRenderer[this._depthRendererId] = depthRenderer;\r\n        }\r\n\r\n        super.setSourceTexture(depthRenderer.getDepthMap(), true, type, forceFullscreenViewport);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override setSourceTexture(\r\n        sourceTexture: RenderTargetTexture,\r\n        depthRedux: boolean,\r\n        type: number = Constants.TEXTURETYPE_HALF_FLOAT,\r\n        forceFullscreenViewport = true\r\n    ): void {\r\n        super.setSourceTexture(sourceTexture, depthRedux, type, forceFullscreenViewport);\r\n    }\r\n\r\n    /**\r\n     * Activates the reduction computation.\r\n     * When activated, the observers registered in onAfterReductionPerformed are\r\n     * called after the computation is performed\r\n     */\r\n    public override activate(): void {\r\n        if (this._depthRenderer) {\r\n            this._depthRenderer.enabled = true;\r\n        }\r\n\r\n        super.activate();\r\n    }\r\n\r\n    /**\r\n     * Deactivates the reduction computation.\r\n     */\r\n    public override deactivate(): void {\r\n        super.deactivate();\r\n\r\n        if (this._depthRenderer) {\r\n            this._depthRenderer.enabled = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the depth reducer\r\n     * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.\r\n     */\r\n    public override dispose(disposeAll = true): void {\r\n        super.dispose(disposeAll);\r\n\r\n        if (this._depthRenderer && disposeAll) {\r\n            this._depthRenderer.dispose();\r\n            this._depthRenderer = null;\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\n\r\nimport { type IShadowLight } from \"../../Lights/shadowLight\";\r\nimport { type Effect } from \"../../Materials/effect\";\r\nimport { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\n\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\nimport { ShadowGenerator } from \"./shadowGenerator\";\r\nimport { type DirectionalLight } from \"../directionalLight\";\r\n\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type DepthRenderer } from \"../../Rendering/depthRenderer\";\r\nimport { DepthReducer } from \"../../Misc/depthReducer\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { FloatingOriginCurrentScene, GetOffsetTransformMatrices } from \"../../Materials/floatingOriginMatrixOverrides\";\r\n\r\ninterface ICascade {\r\n    prevBreakDistance: number;\r\n    breakDistance: number;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst UpDir = /*#__PURE__*/ Vector3.Up();\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst ZeroVec = /*#__PURE__*/ Vector3.Zero();\r\n\r\nconst Tmpv1 = /*#__PURE__*/ new Vector3();\r\nconst Tmpv2 = /*#__PURE__*/ new Vector3();\r\nconst TmpMatrix = /*#__PURE__*/ new Matrix();\r\n\r\n/**\r\n * A CSM implementation allowing casting shadows on large scenes.\r\n * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows\r\n * Based on: https://github.com/TheRealMJP/Shadows and https://johanmedestrom.wordpress.com/2016/03/18/opengl-cascaded-shadow-maps/\r\n */\r\nexport class CascadedShadowGenerator extends ShadowGenerator {\r\n    private static readonly _FrustumCornersNdcSpace = [\r\n        new Vector3(-1.0, +1.0, -1.0),\r\n        new Vector3(+1.0, +1.0, -1.0),\r\n        new Vector3(+1.0, -1.0, -1.0),\r\n        new Vector3(-1.0, -1.0, -1.0),\r\n        new Vector3(-1.0, +1.0, +1.0),\r\n        new Vector3(+1.0, +1.0, +1.0),\r\n        new Vector3(+1.0, -1.0, +1.0),\r\n        new Vector3(-1.0, -1.0, +1.0),\r\n    ];\r\n\r\n    /**\r\n     * Name of the CSM class\r\n     */\r\n    public static override CLASSNAME = \"CascadedShadowGenerator\";\r\n\r\n    /**\r\n     * Defines the default number of cascades used by the CSM.\r\n     */\r\n    public static readonly DEFAULT_CASCADES_COUNT = 4;\r\n    /**\r\n     * Defines the minimum number of cascades used by the CSM.\r\n     */\r\n    public static MIN_CASCADES_COUNT = 2;\r\n    /**\r\n     * Defines the maximum number of cascades used by the CSM.\r\n     */\r\n    public static MAX_CASCADES_COUNT = 4;\r\n\r\n    protected override _validateFilter(filter: number): number {\r\n        if (filter === ShadowGenerator.FILTER_NONE || filter === ShadowGenerator.FILTER_PCF || filter === ShadowGenerator.FILTER_PCSS) {\r\n            return filter;\r\n        }\r\n\r\n        Logger.Error('Unsupported filter \"' + filter + '\"!');\r\n\r\n        return ShadowGenerator.FILTER_NONE;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the actual darkness of the soft shadows while using PCSS filtering (value between 0. and 1.)\r\n     */\r\n    public penumbraDarkness: number;\r\n\r\n    private _numCascades: number;\r\n\r\n    /**\r\n     * Gets or set the number of cascades used by the CSM.\r\n     */\r\n    public get numCascades(): number {\r\n        return this._numCascades;\r\n    }\r\n\r\n    public set numCascades(value: number) {\r\n        value = Math.min(Math.max(value, CascadedShadowGenerator.MIN_CASCADES_COUNT), CascadedShadowGenerator.MAX_CASCADES_COUNT);\r\n        if (value === this._numCascades) {\r\n            return;\r\n        }\r\n\r\n        this._numCascades = value;\r\n        this.recreateShadowMap();\r\n        this._recreateSceneUBOs();\r\n    }\r\n\r\n    /**\r\n     * Sets this to true if you want that the edges of the shadows don't \"swimm\" / \"shimmer\" when rotating the camera.\r\n     * The trade off is that you lose some precision in the shadow rendering when enabling this setting.\r\n     */\r\n    public stabilizeCascades: boolean;\r\n\r\n    private _freezeShadowCastersBoundingInfo: boolean;\r\n    private _freezeShadowCastersBoundingInfoObservable: Nullable<Observer<Scene>>;\r\n\r\n    /**\r\n     * Enables or disables the shadow casters bounding info computation.\r\n     * If your shadow casters don't move, you can disable this feature.\r\n     * If it is enabled, the bounding box computation is done every frame.\r\n     */\r\n    public get freezeShadowCastersBoundingInfo(): boolean {\r\n        return this._freezeShadowCastersBoundingInfo;\r\n    }\r\n\r\n    public set freezeShadowCastersBoundingInfo(freeze: boolean) {\r\n        if (this._freezeShadowCastersBoundingInfoObservable && freeze) {\r\n            this._scene.onBeforeRenderObservable.remove(this._freezeShadowCastersBoundingInfoObservable);\r\n            this._freezeShadowCastersBoundingInfoObservable = null;\r\n        }\r\n\r\n        if (!this._freezeShadowCastersBoundingInfoObservable && !freeze) {\r\n            this._freezeShadowCastersBoundingInfoObservable = this._scene.onBeforeRenderObservable.add(() => this._computeShadowCastersBoundingInfo());\r\n        }\r\n\r\n        this._freezeShadowCastersBoundingInfo = freeze;\r\n\r\n        if (freeze) {\r\n            this._computeShadowCastersBoundingInfo();\r\n        }\r\n    }\r\n\r\n    private _scbiMin: Vector3;\r\n    private _scbiMax: Vector3;\r\n\r\n    protected _computeShadowCastersBoundingInfo(): void {\r\n        this._scbiMin.copyFromFloats(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        this._scbiMax.copyFromFloats(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n        if (this._shadowMap && this._shadowMap.renderList) {\r\n            const renderList = this._shadowMap.renderList;\r\n            for (let meshIndex = 0; meshIndex < renderList.length; meshIndex++) {\r\n                const mesh = renderList[meshIndex];\r\n\r\n                if (!mesh) {\r\n                    continue;\r\n                }\r\n\r\n                const boundingInfo = mesh.getBoundingInfo(),\r\n                    boundingBox = boundingInfo.boundingBox;\r\n\r\n                this._scbiMin.minimizeInPlace(boundingBox.minimumWorld);\r\n                this._scbiMax.maximizeInPlace(boundingBox.maximumWorld);\r\n            }\r\n        }\r\n\r\n        this._shadowCastersBoundingInfo.reConstruct(this._scbiMin, this._scbiMax);\r\n    }\r\n\r\n    protected _shadowCastersBoundingInfo: BoundingInfo;\r\n\r\n    /**\r\n     * Gets or sets the shadow casters bounding info.\r\n     * If you provide your own shadow casters bounding info, first enable freezeShadowCastersBoundingInfo\r\n     * so that the system won't overwrite the bounds you provide\r\n     */\r\n    public get shadowCastersBoundingInfo(): BoundingInfo {\r\n        return this._shadowCastersBoundingInfo;\r\n    }\r\n\r\n    public set shadowCastersBoundingInfo(boundingInfo: BoundingInfo) {\r\n        this._shadowCastersBoundingInfo = boundingInfo;\r\n    }\r\n\r\n    protected _breaksAreDirty: boolean;\r\n\r\n    protected _minDistance: number;\r\n    protected _maxDistance: number;\r\n\r\n    /**\r\n     * Sets the minimal and maximal distances to use when computing the cascade breaks.\r\n     *\r\n     * The values of min / max are typically the depth zmin and zmax values of your scene, for a given frame.\r\n     * If you don't know these values, simply leave them to their defaults and don't call this function.\r\n     * @param min minimal distance for the breaks (default to 0.)\r\n     * @param max maximal distance for the breaks (default to 1.)\r\n     */\r\n    public setMinMaxDistance(min: number, max: number): void {\r\n        if (this._minDistance === min && this._maxDistance === max) {\r\n            return;\r\n        }\r\n\r\n        // Clamp both bounds into [0, 1] before checking ordering: previously min was only clamped\r\n        // low and max only clamped high, so inputs like (1.5, 2) produced min > max.\r\n        min = Math.min(Math.max(min, 0), 1);\r\n        max = Math.min(Math.max(max, 0), 1);\r\n\r\n        if (min > max) {\r\n            min = 0;\r\n            max = 1;\r\n        }\r\n\r\n        this._minDistance = min;\r\n        this._maxDistance = max;\r\n        this._breaksAreDirty = true;\r\n    }\r\n\r\n    /** Gets the minimal distance used in the cascade break computation */\r\n    public get minDistance(): number {\r\n        return this._minDistance;\r\n    }\r\n\r\n    /** Gets the maximal distance used in the cascade break computation */\r\n    public get maxDistance(): number {\r\n        return this._maxDistance;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of that object\r\n     * @returns \"CascadedShadowGenerator\"\r\n     */\r\n    public override getClassName(): string {\r\n        return CascadedShadowGenerator.CLASSNAME;\r\n    }\r\n\r\n    private _cascadeMinExtents: Array<Vector3>;\r\n    private _cascadeMaxExtents: Array<Vector3>;\r\n\r\n    /**\r\n     * Gets a cascade minimum extents\r\n     * @param cascadeIndex index of the cascade\r\n     * @returns the minimum cascade extents\r\n     */\r\n    public getCascadeMinExtents(cascadeIndex: number): Nullable<Vector3> {\r\n        return cascadeIndex >= 0 && cascadeIndex < this._numCascades ? this._cascadeMinExtents[cascadeIndex] : null;\r\n    }\r\n\r\n    /**\r\n     * Gets a cascade maximum extents\r\n     * @param cascadeIndex index of the cascade\r\n     * @returns the maximum cascade extents\r\n     */\r\n    public getCascadeMaxExtents(cascadeIndex: number): Nullable<Vector3> {\r\n        return cascadeIndex >= 0 && cascadeIndex < this._numCascades ? this._cascadeMaxExtents[cascadeIndex] : null;\r\n    }\r\n\r\n    private _cascades: Array<ICascade>;\r\n    private _currentLayer: number;\r\n    private _viewSpaceFrustumsZ: Array<number>;\r\n    private _viewMatrices: Array<Matrix>;\r\n    private _projectionMatrices: Array<Matrix>;\r\n    private _transformMatrices: Array<Matrix>;\r\n    private _transformMatricesAsArray: Float32Array;\r\n    private _tempTransformMatricesAsArray: Float32Array;\r\n    private _frustumLengths: Array<number>;\r\n    private _lightSizeUVCorrection: Array<number>;\r\n    private _depthCorrection: Array<number>;\r\n    private _frustumCornersWorldSpace: Array<Array<Vector3>>;\r\n    private _frustumCenter: Array<Vector3>;\r\n    private _shadowCameraPos: Array<Vector3>;\r\n\r\n    private _shadowMaxZ: number;\r\n    /**\r\n     * Gets the shadow max z distance. It's the limit beyond which shadows are not displayed.\r\n     * It defaults to camera.maxZ\r\n     */\r\n    public get shadowMaxZ(): number {\r\n        if (!this._getCamera()) {\r\n            return 0;\r\n        }\r\n        return this._shadowMaxZ;\r\n    }\r\n    /**\r\n     * Sets the shadow max z distance.\r\n     */\r\n    public set shadowMaxZ(value: number) {\r\n        const camera = this._getCamera();\r\n        if (!camera) {\r\n            this._shadowMaxZ = value;\r\n            return;\r\n        }\r\n        if (this._shadowMaxZ === value || value < camera.minZ || (value > camera.maxZ && camera.maxZ !== 0)) {\r\n            return;\r\n        }\r\n        this._shadowMaxZ = value;\r\n        this._light._markMeshesAsLightDirty();\r\n        this._breaksAreDirty = true;\r\n    }\r\n\r\n    protected _debug: boolean;\r\n\r\n    /**\r\n     * Gets or sets the debug flag.\r\n     * When enabled, the cascades are materialized by different colors on the screen.\r\n     */\r\n    public get debug(): boolean {\r\n        return this._debug;\r\n    }\r\n\r\n    public set debug(dbg: boolean) {\r\n        this._debug = dbg;\r\n        this._light._markMeshesAsLightDirty();\r\n    }\r\n\r\n    private _depthClamp: boolean;\r\n\r\n    /**\r\n     * Gets or sets the depth clamping value.\r\n     *\r\n     * When enabled, it improves the shadow quality because the near z plane of the light frustum don't need to be adjusted\r\n     * to account for the shadow casters far away.\r\n     *\r\n     * Note that this property is incompatible with PCSS filtering, so it won't be used in that case.\r\n     */\r\n    public get depthClamp(): boolean {\r\n        return this._depthClamp;\r\n    }\r\n\r\n    public set depthClamp(value: boolean) {\r\n        this._depthClamp = value;\r\n    }\r\n\r\n    private _cascadeBlendPercentage: number;\r\n\r\n    /**\r\n     * Gets or sets the percentage of blending between two cascades (value between 0. and 1.).\r\n     * It defaults to 0.1 (10% blending).\r\n     */\r\n    public get cascadeBlendPercentage(): number {\r\n        return this._cascadeBlendPercentage;\r\n    }\r\n\r\n    public set cascadeBlendPercentage(value: number) {\r\n        this._cascadeBlendPercentage = value;\r\n        this._light._markMeshesAsLightDirty();\r\n    }\r\n\r\n    private _lambda: number;\r\n\r\n    /**\r\n     * Gets or set the lambda parameter.\r\n     * This parameter is used to split the camera frustum and create the cascades.\r\n     * It's a value between 0. and 1.: If 0, the split is a uniform split of the frustum, if 1 it is a logarithmic split.\r\n     * For all values in-between, it's a linear combination of the uniform and logarithm split algorithm.\r\n     */\r\n    public get lambda(): number {\r\n        return this._lambda;\r\n    }\r\n\r\n    public set lambda(value: number) {\r\n        const lambda = Math.min(Math.max(value, 0), 1);\r\n        if (this._lambda == lambda) {\r\n            return;\r\n        }\r\n        this._lambda = lambda;\r\n        this._breaksAreDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Gets the view matrix corresponding to a given cascade\r\n     * @param cascadeNum cascade to retrieve the view matrix from\r\n     * @returns the cascade view matrix\r\n     */\r\n    public getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix> {\r\n        return cascadeNum >= 0 && cascadeNum < this._numCascades ? this._viewMatrices[cascadeNum] : null;\r\n    }\r\n\r\n    /**\r\n     * Gets the projection matrix corresponding to a given cascade\r\n     * @param cascadeNum cascade to retrieve the projection matrix from\r\n     * @returns the cascade projection matrix\r\n     */\r\n    public getCascadeProjectionMatrix(cascadeNum: number): Nullable<Matrix> {\r\n        return cascadeNum >= 0 && cascadeNum < this._numCascades ? this._projectionMatrices[cascadeNum] : null;\r\n    }\r\n\r\n    /**\r\n     * Gets the transformation matrix corresponding to a given cascade\r\n     * @param cascadeNum cascade to retrieve the transformation matrix from\r\n     * @returns the cascade transformation matrix\r\n     */\r\n    public getCascadeTransformMatrix(cascadeNum: number): Nullable<Matrix> {\r\n        return cascadeNum >= 0 && cascadeNum < this._numCascades ? this._transformMatrices[cascadeNum] : null;\r\n    }\r\n\r\n    private _depthRenderer: Nullable<DepthRenderer>;\r\n    /**\r\n     * Sets the depth renderer to use when autoCalcDepthBounds is enabled.\r\n     *\r\n     * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.\r\n     *\r\n     * You should call this function if you already have a depth renderer enabled in your scene, to avoid\r\n     * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!\r\n     * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created\r\n     */\r\n    public setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void {\r\n        this._depthRenderer = depthRenderer;\r\n\r\n        if (this._depthReducer) {\r\n            this._depthReducer.setDepthRenderer(this._depthRenderer);\r\n        }\r\n    }\r\n\r\n    private _depthReducer: Nullable<DepthReducer>;\r\n    private _autoCalcDepthBounds: boolean;\r\n\r\n    /**\r\n     * Gets or sets the autoCalcDepthBounds property.\r\n     *\r\n     * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one\r\n     * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the\r\n     * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.\r\n     * It can greatly enhance the shadow quality, at the expense of more GPU works.\r\n     * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.\r\n     */\r\n    public get autoCalcDepthBounds(): boolean {\r\n        return this._autoCalcDepthBounds;\r\n    }\r\n\r\n    public set autoCalcDepthBounds(value: boolean) {\r\n        const camera = this._getCamera();\r\n\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        this._autoCalcDepthBounds = value;\r\n\r\n        if (!value) {\r\n            if (this._depthReducer) {\r\n                this._depthReducer.deactivate();\r\n            }\r\n            this.setMinMaxDistance(0, 1);\r\n            return;\r\n        }\r\n\r\n        if (!this._depthReducer) {\r\n            this._depthReducer = new DepthReducer(camera);\r\n            this._depthReducer.onAfterReductionPerformed.add((minmax: { min: number; max: number }) => {\r\n                let min = minmax.min,\r\n                    max = minmax.max;\r\n                if (min >= max) {\r\n                    min = 0;\r\n                    max = 1;\r\n                }\r\n                if (min != this._minDistance || max != this._maxDistance) {\r\n                    this.setMinMaxDistance(min, max);\r\n                }\r\n            });\r\n            this._depthReducer.setDepthRenderer(this._depthRenderer);\r\n        }\r\n\r\n        this._depthReducer.activate();\r\n    }\r\n\r\n    /**\r\n     * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true\r\n     * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...\r\n     * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible\r\n     * for setting the refresh rate on the renderer yourself!\r\n     */\r\n    public get autoCalcDepthBoundsRefreshRate(): number {\r\n        return this._depthReducer?.depthRenderer?.getDepthMap().refreshRate ?? -1;\r\n    }\r\n\r\n    public set autoCalcDepthBoundsRefreshRate(value: number) {\r\n        if (this._depthReducer?.depthRenderer) {\r\n            this._depthReducer.depthRenderer.getDepthMap().refreshRate = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.\r\n     * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if\r\n     * you change the camera near/far planes!\r\n     */\r\n    public splitFrustum(): void {\r\n        this._breaksAreDirty = true;\r\n    }\r\n\r\n    private _splitFrustum(): void {\r\n        const camera = this._getCamera();\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        const near = camera.minZ,\r\n            far = camera.maxZ || this._shadowMaxZ, // account for infinite far plane (ie. maxZ = 0)\r\n            cameraRange = far - near,\r\n            minDistance = this._minDistance,\r\n            maxDistance = this._shadowMaxZ < far && this._shadowMaxZ >= near ? Math.min((this._shadowMaxZ - near) / (far - near), this._maxDistance) : this._maxDistance;\r\n\r\n        const minZ = near + minDistance * cameraRange,\r\n            maxZ = near + maxDistance * cameraRange;\r\n\r\n        const range = maxZ - minZ,\r\n            ratio = maxZ / minZ;\r\n\r\n        for (let cascadeIndex = 0; cascadeIndex < this._cascades.length; ++cascadeIndex) {\r\n            const p = (cascadeIndex + 1) / this._numCascades,\r\n                log = minZ * ratio ** p,\r\n                uniform = minZ + range * p;\r\n\r\n            const d = this._lambda * (log - uniform) + uniform;\r\n\r\n            this._cascades[cascadeIndex].prevBreakDistance = cascadeIndex === 0 ? minDistance : this._cascades[cascadeIndex - 1].breakDistance;\r\n            this._cascades[cascadeIndex].breakDistance = (d - near) / cameraRange;\r\n\r\n            this._viewSpaceFrustumsZ[cascadeIndex] = d;\r\n            this._frustumLengths[cascadeIndex] = (this._cascades[cascadeIndex].breakDistance - this._cascades[cascadeIndex].prevBreakDistance) * cameraRange;\r\n        }\r\n\r\n        this._breaksAreDirty = false;\r\n    }\r\n\r\n    private _computeMatrices(): void {\r\n        const scene = this._scene;\r\n\r\n        const camera = this._getCamera();\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        Vector3.NormalizeToRef(this._light.getShadowDirection(0), this._lightDirection);\r\n        if (Math.abs(Vector3.Dot(this._lightDirection, Vector3.Up())) === 1.0) {\r\n            this._lightDirection.z = 0.0000000000001; // Required to avoid perfectly perpendicular light\r\n        }\r\n\r\n        this._cachedDirection.copyFrom(this._lightDirection);\r\n\r\n        const useReverseDepthBuffer = scene.getEngine().useReverseDepthBuffer;\r\n\r\n        for (let cascadeIndex = 0; cascadeIndex < this._numCascades; ++cascadeIndex) {\r\n            this._computeFrustumInWorldSpace(cascadeIndex);\r\n            this._computeCascadeFrustum(cascadeIndex);\r\n\r\n            this._cascadeMaxExtents[cascadeIndex].subtractToRef(this._cascadeMinExtents[cascadeIndex], Tmpv1); // tmpv1 = cascadeExtents\r\n\r\n            // Get position of the shadow camera\r\n            this._frustumCenter[cascadeIndex].addToRef(this._lightDirection.scale(this._cascadeMinExtents[cascadeIndex].z), this._shadowCameraPos[cascadeIndex]);\r\n\r\n            // Come up with a new orthographic camera for the shadow caster\r\n            Matrix.LookAtLHToRef(this._shadowCameraPos[cascadeIndex], this._frustumCenter[cascadeIndex], UpDir, this._viewMatrices[cascadeIndex]);\r\n\r\n            // Z extents of the current cascade, in cascade view coordinate system\r\n            let viewMinZ = 0,\r\n                viewMaxZ = Tmpv1.z;\r\n\r\n            // Try to tighten minZ and maxZ based on the bounding box of the shadow casters\r\n            const boundingInfo = this._shadowCastersBoundingInfo;\r\n\r\n            boundingInfo.update(this._viewMatrices[cascadeIndex]);\r\n            // Note that after the call to update, the boundingInfo properties that are identified as \"world\" coordinates are in fact view coordinates for the current cascade!\r\n            // This is because the boundingInfo properties that are identifed as \"local\" are in fact world coordinates (see _computeShadowCastersBoundingInfo()), and we multiply them by the current cascade view matrix when we call update.\r\n\r\n            const castersViewMinZ = boundingInfo.boundingBox.minimumWorld.z;\r\n            const castersViewMaxZ = boundingInfo.boundingBox.maximumWorld.z;\r\n\r\n            if (castersViewMinZ > viewMaxZ) {\r\n                // Do nothing, keep the current z extents.\r\n                // All the casters are too far from the light to have an impact on the current cascade.\r\n                // Possible optimization: skip the rendering of the shadow map for this cascade, as all the casters will be clipped by the GPU anyway.\r\n            } else {\r\n                if (!this._depthClamp || this.filter === ShadowGenerator.FILTER_PCSS) {\r\n                    // If we don't use depth clamping, we must define minZ so that all shadow casters are in the cascade frustum\r\n                    viewMinZ = Math.min(viewMinZ, castersViewMinZ);\r\n\r\n                    if (this.filter !== ShadowGenerator.FILTER_PCSS) {\r\n                        // We do not need the actual distance between the currently shaded pixel and the occluder when generating shadows, so we can lower the far plane to increase the accuracy of the shadow map.\r\n                        viewMaxZ = Math.min(viewMaxZ, castersViewMaxZ);\r\n                    }\r\n                } else {\r\n                    // If we use depth clamping (but not PCSS!), we can adjust minZ/maxZ to reduce the range [minZ, maxZ] (and obtain additional precision in the shadow map)\r\n                    viewMaxZ = Math.min(viewMaxZ, castersViewMaxZ);\r\n\r\n                    // Thanks to depth clamping, casters won't be Z clipped even if they fall outside the [-1,1] range, so we can move the near plane to 0 if castersViewMinZ < 0.\r\n                    // We will generate negative Z values in the shadow map, but that's okay (they will be clamped to the 0..1 range anyway), except in PCSS case\r\n                    // where we need the actual distance between the currently shader pixel and the occluder: that's why we don't use depth clamping in PCSS case.\r\n                    viewMinZ = Math.max(viewMinZ, castersViewMinZ);\r\n\r\n                    // If all the casters are behind the near plane of the cascade, minZ = 0 due to the previous line, and maxZ < 0 at this point.\r\n                    // We need to make sure that maxZ > minZ, so in this case we set maxZ a little higher than minZ. As we are using depth clamping, the casters won't be Z clipped, so we just need to make sure that we have a valid Z range for the cascade.\r\n                    // Having a 0 range is not ok, due to undefined behavior in the calculation in this case.\r\n                    viewMaxZ = Math.max(viewMinZ + 1.0, viewMaxZ);\r\n                }\r\n            }\r\n\r\n            Matrix.OrthoOffCenterLHToRef(\r\n                this._cascadeMinExtents[cascadeIndex].x,\r\n                this._cascadeMaxExtents[cascadeIndex].x,\r\n                this._cascadeMinExtents[cascadeIndex].y,\r\n                this._cascadeMaxExtents[cascadeIndex].y,\r\n                useReverseDepthBuffer ? viewMaxZ : viewMinZ,\r\n                useReverseDepthBuffer ? viewMinZ : viewMaxZ,\r\n                this._projectionMatrices[cascadeIndex],\r\n                scene.getEngine().isNDCHalfZRange\r\n            );\r\n\r\n            this._cascadeMinExtents[cascadeIndex].z = viewMinZ;\r\n            this._cascadeMaxExtents[cascadeIndex].z = viewMaxZ;\r\n\r\n            this._viewMatrices[cascadeIndex].multiplyToRef(this._projectionMatrices[cascadeIndex], this._transformMatrices[cascadeIndex]);\r\n\r\n            // Create the rounding matrix, by projecting the world-space origin and determining\r\n            // the fractional offset in texel space\r\n            Vector3.TransformCoordinatesToRef(ZeroVec, this._transformMatrices[cascadeIndex], Tmpv1); // tmpv1 = shadowOrigin\r\n            Tmpv1.scaleInPlace(this._mapSize / 2);\r\n\r\n            Tmpv2.copyFromFloats(Math.round(Tmpv1.x), Math.round(Tmpv1.y), Math.round(Tmpv1.z)); // tmpv2 = roundedOrigin\r\n            Tmpv2.subtractInPlace(Tmpv1).scaleInPlace(2 / this._mapSize); // tmpv2 = roundOffset\r\n\r\n            Matrix.TranslationToRef(Tmpv2.x, Tmpv2.y, 0.0, TmpMatrix);\r\n\r\n            this._projectionMatrices[cascadeIndex].multiplyToRef(TmpMatrix, this._projectionMatrices[cascadeIndex]);\r\n            this._viewMatrices[cascadeIndex].multiplyToRef(this._projectionMatrices[cascadeIndex], this._transformMatrices[cascadeIndex]);\r\n\r\n            this._transformMatrices[cascadeIndex].copyToArray(this._transformMatricesAsArray, cascadeIndex * 16);\r\n        }\r\n    }\r\n\r\n    // Get the 8 points of the view frustum in world space\r\n    private _computeFrustumInWorldSpace(cascadeIndex: number): void {\r\n        const camera = this._getCamera();\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        const prevSplitDist = this._cascades[cascadeIndex].prevBreakDistance,\r\n            splitDist = this._cascades[cascadeIndex].breakDistance;\r\n\r\n        const isNDCHalfZRange = this._scene.getEngine().isNDCHalfZRange;\r\n\r\n        camera.getViewMatrix(); // make sure the transformation matrix we get when calling 'getTransformationMatrix()' is calculated with an up to date view matrix\r\n\r\n        const cameraInfiniteFarPlane = camera.maxZ === 0;\r\n        const saveCameraMaxZ = camera.maxZ;\r\n\r\n        if (cameraInfiniteFarPlane) {\r\n            camera.maxZ = this._shadowMaxZ;\r\n            camera.getProjectionMatrix(true);\r\n        }\r\n\r\n        const invViewProj = Matrix.Invert(camera.getTransformationMatrix());\r\n\r\n        if (cameraInfiniteFarPlane) {\r\n            camera.maxZ = saveCameraMaxZ;\r\n            camera.getProjectionMatrix(true);\r\n        }\r\n\r\n        const cornerIndexOffset = this._scene.getEngine().useReverseDepthBuffer ? 4 : 0;\r\n        for (let cornerIndex = 0; cornerIndex < CascadedShadowGenerator._FrustumCornersNdcSpace.length; ++cornerIndex) {\r\n            Tmpv1.copyFrom(CascadedShadowGenerator._FrustumCornersNdcSpace[(cornerIndex + cornerIndexOffset) % CascadedShadowGenerator._FrustumCornersNdcSpace.length]);\r\n            if (isNDCHalfZRange && Tmpv1.z === -1) {\r\n                Tmpv1.z = 0;\r\n            }\r\n            Vector3.TransformCoordinatesToRef(Tmpv1, invViewProj, this._frustumCornersWorldSpace[cascadeIndex][cornerIndex]);\r\n        }\r\n\r\n        // Get the corners of the current cascade slice of the view frustum\r\n        for (let cornerIndex = 0; cornerIndex < CascadedShadowGenerator._FrustumCornersNdcSpace.length / 2; ++cornerIndex) {\r\n            Tmpv1.copyFrom(this._frustumCornersWorldSpace[cascadeIndex][cornerIndex + 4]).subtractInPlace(this._frustumCornersWorldSpace[cascadeIndex][cornerIndex]);\r\n            Tmpv2.copyFrom(Tmpv1).scaleInPlace(prevSplitDist); // near corner ray\r\n            Tmpv1.scaleInPlace(splitDist); // far corner ray\r\n\r\n            Tmpv1.addInPlace(this._frustumCornersWorldSpace[cascadeIndex][cornerIndex]);\r\n\r\n            this._frustumCornersWorldSpace[cascadeIndex][cornerIndex + 4].copyFrom(Tmpv1);\r\n            this._frustumCornersWorldSpace[cascadeIndex][cornerIndex].addInPlace(Tmpv2);\r\n        }\r\n    }\r\n\r\n    private _computeCascadeFrustum(cascadeIndex: number): void {\r\n        this._cascadeMinExtents[cascadeIndex].copyFromFloats(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        this._cascadeMaxExtents[cascadeIndex].copyFromFloats(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n        this._frustumCenter[cascadeIndex].copyFromFloats(0, 0, 0);\r\n\r\n        const camera = this._getCamera();\r\n\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        // Calculate the centroid of the view frustum slice\r\n        for (let cornerIndex = 0; cornerIndex < this._frustumCornersWorldSpace[cascadeIndex].length; ++cornerIndex) {\r\n            this._frustumCenter[cascadeIndex].addInPlace(this._frustumCornersWorldSpace[cascadeIndex][cornerIndex]);\r\n        }\r\n\r\n        this._frustumCenter[cascadeIndex].scaleInPlace(1 / this._frustumCornersWorldSpace[cascadeIndex].length);\r\n\r\n        if (this.stabilizeCascades) {\r\n            // Calculate the radius of a bounding sphere surrounding the frustum corners\r\n            let sphereRadius = 0;\r\n            for (let cornerIndex = 0; cornerIndex < this._frustumCornersWorldSpace[cascadeIndex].length; ++cornerIndex) {\r\n                const dist = this._frustumCornersWorldSpace[cascadeIndex][cornerIndex].subtractToRef(this._frustumCenter[cascadeIndex], Tmpv1).length();\r\n                sphereRadius = Math.max(sphereRadius, dist);\r\n            }\r\n\r\n            sphereRadius = Math.ceil(sphereRadius * 16) / 16;\r\n\r\n            this._cascadeMaxExtents[cascadeIndex].copyFromFloats(sphereRadius, sphereRadius, sphereRadius);\r\n            this._cascadeMinExtents[cascadeIndex].copyFromFloats(-sphereRadius, -sphereRadius, -sphereRadius);\r\n        } else {\r\n            // Create a temporary view matrix for the light\r\n            const lightCameraPos = this._frustumCenter[cascadeIndex];\r\n\r\n            this._frustumCenter[cascadeIndex].addToRef(this._lightDirection, Tmpv1); // tmpv1 = look at\r\n\r\n            Matrix.LookAtLHToRef(lightCameraPos, Tmpv1, UpDir, TmpMatrix); // matrix = lightView\r\n\r\n            // Calculate an AABB around the frustum corners\r\n            for (let cornerIndex = 0; cornerIndex < this._frustumCornersWorldSpace[cascadeIndex].length; ++cornerIndex) {\r\n                Vector3.TransformCoordinatesToRef(this._frustumCornersWorldSpace[cascadeIndex][cornerIndex], TmpMatrix, Tmpv1);\r\n\r\n                this._cascadeMinExtents[cascadeIndex].minimizeInPlace(Tmpv1);\r\n                this._cascadeMaxExtents[cascadeIndex].maximizeInPlace(Tmpv1);\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _recreateSceneUBOs(): void {\r\n        this._disposeSceneUBOs();\r\n        if (this._sceneUBOs) {\r\n            for (let i = 0; i < this._numCascades; ++i) {\r\n                this._sceneUBOs.push(this._scene.createSceneUniformBuffer(`Scene for CSM Shadow Generator (light \"${this._light.name}\" cascade #${i})`, { forceMono: true }));\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     *  Support test.\r\n     */\r\n    public static get IsSupported(): boolean {\r\n        const engine = EngineStore.LastCreatedEngine;\r\n        if (!engine) {\r\n            return false;\r\n        }\r\n        return engine._features.supportCSM;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"ShadowGeneratorSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * Creates a Cascaded Shadow Generator object.\r\n     * A ShadowGenerator is the required tool to use the shadows.\r\n     * Each directional light casting shadows needs to use its own ShadowGenerator.\r\n     * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows\r\n     * @param mapSize The size of the texture what stores the shadows. Example : 1024.\r\n     * @param light The directional light object generating the shadows.\r\n     * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.\r\n     * @param camera Camera associated with this shadow generator (default: null). If null, takes the scene active camera at the time we need to access it\r\n     * @param useRedTextureType Forces the generator to use a Red instead of a RGBA type for the shadow map texture format (default: true)\r\n     */\r\n    constructor(mapSize: number, light: DirectionalLight, usefulFloatFirst?: boolean, camera?: Nullable<Camera>, useRedTextureType = true) {\r\n        if (!CascadedShadowGenerator.IsSupported) {\r\n            Logger.Error(\"CascadedShadowMap is not supported by the current engine.\");\r\n            return;\r\n        }\r\n\r\n        super(mapSize, light, usefulFloatFirst, camera, useRedTextureType);\r\n\r\n        this.usePercentageCloserFiltering = true;\r\n    }\r\n\r\n    protected override _initializeGenerator(): void {\r\n        this.penumbraDarkness = this.penumbraDarkness ?? 1.0;\r\n        this._numCascades = this._numCascades ?? CascadedShadowGenerator.DEFAULT_CASCADES_COUNT;\r\n        this.stabilizeCascades = this.stabilizeCascades ?? false;\r\n        this._freezeShadowCastersBoundingInfoObservable = this._freezeShadowCastersBoundingInfoObservable ?? null;\r\n        this.freezeShadowCastersBoundingInfo = this.freezeShadowCastersBoundingInfo ?? false;\r\n        this._scbiMin = this._scbiMin ?? new Vector3(0, 0, 0);\r\n        this._scbiMax = this._scbiMax ?? new Vector3(0, 0, 0);\r\n        this._shadowCastersBoundingInfo = this._shadowCastersBoundingInfo ?? new BoundingInfo(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\r\n        this._breaksAreDirty = this._breaksAreDirty ?? true;\r\n        this._minDistance = this._minDistance ?? 0;\r\n        this._maxDistance = this._maxDistance ?? 1;\r\n        this._currentLayer = this._currentLayer ?? 0;\r\n        this._shadowMaxZ = this._shadowMaxZ ?? this._getCamera()?.maxZ ?? 10000;\r\n        this._debug = this._debug ?? false;\r\n        this._depthClamp = this._depthClamp ?? true;\r\n        this._cascadeBlendPercentage = this._cascadeBlendPercentage ?? 0.1;\r\n        this._lambda = this._lambda ?? 0.5;\r\n        this._autoCalcDepthBounds = this._autoCalcDepthBounds ?? false;\r\n\r\n        this._recreateSceneUBOs();\r\n\r\n        super._initializeGenerator();\r\n    }\r\n\r\n    protected override _createTargetRenderTexture(): void {\r\n        const engine = this._scene.getEngine();\r\n        this._shadowMap?.dispose();\r\n        const size = { width: this._mapSize, height: this._mapSize, layers: this.numCascades };\r\n        this._shadowMap = new RenderTargetTexture(\r\n            this._light.name + \"_CSMShadowMap\",\r\n            size,\r\n            this._scene,\r\n            false,\r\n            true,\r\n            this._textureType,\r\n            false,\r\n            undefined,\r\n            false,\r\n            false,\r\n            undefined,\r\n            this._useRedTextureType ? Constants.TEXTUREFORMAT_RED : Constants.TEXTUREFORMAT_RGBA\r\n        );\r\n        this._shadowMap.createDepthStencilTexture(\r\n            engine.useReverseDepthBuffer ? Constants.GREATER : Constants.LESS,\r\n            true,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            `DepthStencilForCSMShadowGenerator-${this._light.name}`\r\n        );\r\n        this._shadowMap.noPrePassRenderer = true;\r\n    }\r\n\r\n    protected override _initializeShadowMap(): void {\r\n        super._initializeShadowMap();\r\n\r\n        if (this._shadowMap === null) {\r\n            return;\r\n        }\r\n\r\n        this._transformMatricesAsArray = new Float32Array(this._numCascades * 16);\r\n        this._tempTransformMatricesAsArray = new Float32Array(this._numCascades * 16);\r\n        this._viewSpaceFrustumsZ = new Array(this._numCascades);\r\n        this._frustumLengths = new Array(this._numCascades);\r\n        this._lightSizeUVCorrection = new Array(this._numCascades * 2);\r\n        this._depthCorrection = new Array(this._numCascades);\r\n\r\n        this._cascades = [];\r\n        this._viewMatrices = [];\r\n        this._projectionMatrices = [];\r\n        this._transformMatrices = [];\r\n        this._cascadeMinExtents = [];\r\n        this._cascadeMaxExtents = [];\r\n        this._frustumCenter = [];\r\n        this._shadowCameraPos = [];\r\n        this._frustumCornersWorldSpace = [];\r\n\r\n        for (let cascadeIndex = 0; cascadeIndex < this._numCascades; ++cascadeIndex) {\r\n            this._cascades[cascadeIndex] = {\r\n                prevBreakDistance: 0,\r\n                breakDistance: 0,\r\n            };\r\n\r\n            this._viewMatrices[cascadeIndex] = Matrix.Zero();\r\n            this._projectionMatrices[cascadeIndex] = Matrix.Zero();\r\n            this._transformMatrices[cascadeIndex] = Matrix.Zero();\r\n            this._cascadeMinExtents[cascadeIndex] = new Vector3();\r\n            this._cascadeMaxExtents[cascadeIndex] = new Vector3();\r\n            this._frustumCenter[cascadeIndex] = new Vector3();\r\n            this._shadowCameraPos[cascadeIndex] = new Vector3();\r\n            this._frustumCornersWorldSpace[cascadeIndex] = new Array(CascadedShadowGenerator._FrustumCornersNdcSpace.length);\r\n\r\n            for (let i = 0; i < CascadedShadowGenerator._FrustumCornersNdcSpace.length; ++i) {\r\n                this._frustumCornersWorldSpace[cascadeIndex][i] = new Vector3();\r\n            }\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        this._shadowMap.onBeforeBindObservable.clear();\r\n        this._shadowMap.onBeforeRenderObservable.clear();\r\n\r\n        this._shadowMap.onBeforeRenderObservable.add((layer: number) => {\r\n            if (this._sceneUBOs) {\r\n                this._scene.setSceneUniformBuffer(this._sceneUBOs[layer]);\r\n            }\r\n            this._currentLayer = layer;\r\n            if (this._filter === ShadowGenerator.FILTER_PCF) {\r\n                engine.setColorWrite(false);\r\n            }\r\n            FloatingOriginCurrentScene.eyeAtCamera = false;\r\n            this._scene.setTransformMatrix(this.getCascadeViewMatrix(layer)!, this.getCascadeProjectionMatrix(layer)!);\r\n            if (this._useUBO) {\r\n                this._scene.getSceneUniformBuffer().unbindEffect();\r\n                this._scene.finalizeSceneUbo();\r\n            }\r\n        });\r\n\r\n        this._shadowMap.onBeforeBindObservable.add(() => {\r\n            this._currentSceneUBO = this._scene.getSceneUniformBuffer();\r\n            if (engine._enableGPUDebugMarkers) {\r\n                engine._debugPushGroup?.(`Cascaded shadow map generation for pass id ${engine.currentRenderPassId}`);\r\n            }\r\n            if (this._breaksAreDirty) {\r\n                this._splitFrustum();\r\n            }\r\n            this._computeMatrices();\r\n        });\r\n\r\n        this._splitFrustum();\r\n    }\r\n\r\n    protected override _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void {\r\n        effect.setMatrix(\"viewProjection\", this.getCascadeTransformMatrix(this._currentLayer)!);\r\n    }\r\n\r\n    protected override _isReadyCustomDefines(defines: any): void {\r\n        defines.push(\"#define SM_DEPTHCLAMP \" + (this._depthClamp && this._filter !== ShadowGenerator.FILTER_PCSS ? \"1\" : \"0\"));\r\n    }\r\n\r\n    /**\r\n     * Prepare all the defines in a material relying on a shadow map at the specified light index.\r\n     * @param defines Defines of the material we want to update\r\n     * @param lightIndex Index of the light in the enabled light list of the material\r\n     */\r\n    public override prepareDefines(defines: any, lightIndex: number): void {\r\n        super.prepareDefines(defines, lightIndex);\r\n\r\n        const scene = this._scene;\r\n        const light = this._light;\r\n\r\n        if (!scene.shadowsEnabled || !light.shadowEnabled) {\r\n            return;\r\n        }\r\n\r\n        defines[\"SHADOWCSM\" + lightIndex] = true;\r\n        defines[\"SHADOWCSMDEBUG\" + lightIndex] = this.debug;\r\n        defines[\"SHADOWCSMNUM_CASCADES\" + lightIndex] = this.numCascades;\r\n        defines[\"SHADOWCSM_RIGHTHANDED\" + lightIndex] = scene.useRightHandedSystem;\r\n\r\n        const camera = this._getCamera();\r\n\r\n        if (camera && this._shadowMaxZ <= (camera.maxZ || this._shadowMaxZ)) {\r\n            defines[\"SHADOWCSMUSESHADOWMAXZ\" + lightIndex] = true;\r\n        }\r\n\r\n        if (this.cascadeBlendPercentage === 0) {\r\n            defines[\"SHADOWCSMNOBLEND\" + lightIndex] = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the shadow related information inside of an effect (information like near, far, darkness...\r\n     * defined in the generator but impacting the effect).\r\n     * @param lightIndex Index of the light in the enabled light list of the material owning the effect\r\n     * @param effect The effect we are binfing the information for\r\n     */\r\n    public override bindShadowLight(lightIndex: string, effect: Effect): void {\r\n        const light = this._light;\r\n        const scene = this._scene;\r\n\r\n        if (!scene.shadowsEnabled || !light.shadowEnabled) {\r\n            return;\r\n        }\r\n\r\n        const camera = this._getCamera();\r\n        if (!camera) {\r\n            return;\r\n        }\r\n\r\n        const shadowMap = this.getShadowMap();\r\n        if (!shadowMap) {\r\n            return;\r\n        }\r\n\r\n        const width = shadowMap.getSize().width;\r\n\r\n        const transform = this._transformMatricesAsArray;\r\n        // Doing the check for floatingOrigin here to avoid unnecessary matrix operations when offset is 0\r\n        const lightMatrix = scene.floatingOriginMode\r\n            ? GetOffsetTransformMatrices(this._scene.floatingOriginOffset, this._viewMatrices, this._projectionMatrices, this._numCascades, this._tempTransformMatricesAsArray)\r\n            : transform;\r\n\r\n        effect.setMatrices(\"lightMatrix\" + lightIndex, lightMatrix);\r\n        effect.setArray(\"viewFrustumZ\" + lightIndex, this._viewSpaceFrustumsZ);\r\n        effect.setFloat(\"cascadeBlendFactor\" + lightIndex, this.cascadeBlendPercentage === 0 ? 10000 : 1 / this.cascadeBlendPercentage);\r\n        effect.setArray(\"frustumLengths\" + lightIndex, this._frustumLengths);\r\n\r\n        // Only PCF uses depth stencil texture.\r\n        if (this._filter === ShadowGenerator.FILTER_PCF) {\r\n            effect.setDepthStencilTexture(\"shadowTexture\" + lightIndex, shadowMap);\r\n            light._uniformBuffer.updateFloat4(\"shadowsInfo\", this.getDarkness(), width, 1 / width, this.frustumEdgeFalloff, lightIndex);\r\n        } else if (this._filter === ShadowGenerator.FILTER_PCSS) {\r\n            for (let cascadeIndex = 0; cascadeIndex < this._numCascades; ++cascadeIndex) {\r\n                this._lightSizeUVCorrection[cascadeIndex * 2 + 0] =\r\n                    cascadeIndex === 0\r\n                        ? 1\r\n                        : (this._cascadeMaxExtents[0].x - this._cascadeMinExtents[0].x) / (this._cascadeMaxExtents[cascadeIndex].x - this._cascadeMinExtents[cascadeIndex].x); // x correction\r\n                this._lightSizeUVCorrection[cascadeIndex * 2 + 1] =\r\n                    cascadeIndex === 0\r\n                        ? 1\r\n                        : (this._cascadeMaxExtents[0].y - this._cascadeMinExtents[0].y) / (this._cascadeMaxExtents[cascadeIndex].y - this._cascadeMinExtents[cascadeIndex].y); // y correction\r\n                this._depthCorrection[cascadeIndex] =\r\n                    cascadeIndex === 0\r\n                        ? 1\r\n                        : (this._cascadeMaxExtents[cascadeIndex].z - this._cascadeMinExtents[cascadeIndex].z) / (this._cascadeMaxExtents[0].z - this._cascadeMinExtents[0].z);\r\n            }\r\n            effect.setDepthStencilTexture(\"shadowTexture\" + lightIndex, shadowMap);\r\n            effect.setTexture(\"depthTexture\" + lightIndex, shadowMap);\r\n\r\n            effect.setArray2(\"lightSizeUVCorrection\" + lightIndex, this._lightSizeUVCorrection);\r\n            effect.setArray(\"depthCorrection\" + lightIndex, this._depthCorrection);\r\n            effect.setFloat(\"penumbraDarkness\" + lightIndex, this.penumbraDarkness);\r\n            light._uniformBuffer.updateFloat4(\"shadowsInfo\", this.getDarkness(), 1 / width, this._contactHardeningLightSizeUVRatio * width, this.frustumEdgeFalloff, lightIndex);\r\n        } else {\r\n            effect.setTexture(\"shadowTexture\" + lightIndex, shadowMap);\r\n            light._uniformBuffer.updateFloat4(\"shadowsInfo\", this.getDarkness(), width, 1 / width, this.frustumEdgeFalloff, lightIndex);\r\n        }\r\n\r\n        light._uniformBuffer.updateFloat2(\r\n            \"depthValues\",\r\n            this.getLight().getDepthMinZ(camera),\r\n            this.getLight().getDepthMinZ(camera) + this.getLight().getDepthMaxZ(camera),\r\n            lightIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the transformation matrix of the first cascade used to project the meshes into the map from the light point of view.\r\n     * (eq to view projection * shadow projection matrices)\r\n     * @returns The transform matrix used to create the shadow map\r\n     */\r\n    public override getTransformMatrix(): Matrix {\r\n        return this.getCascadeTransformMatrix(0)!;\r\n    }\r\n\r\n    /**\r\n     * Disposes the ShadowGenerator.\r\n     * Returns nothing.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        if (this._freezeShadowCastersBoundingInfoObservable) {\r\n            this._scene.onBeforeRenderObservable.remove(this._freezeShadowCastersBoundingInfoObservable);\r\n            this._freezeShadowCastersBoundingInfoObservable = null;\r\n        }\r\n\r\n        if (this._depthReducer) {\r\n            this._depthReducer.dispose();\r\n            this._depthReducer = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the shadow generator setup to a json object.\r\n     * @returns The serialized JSON object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject: any = super.serialize();\r\n        const shadowMap = this.getShadowMap();\r\n\r\n        if (!shadowMap) {\r\n            return serializationObject;\r\n        }\r\n\r\n        serializationObject.numCascades = this._numCascades;\r\n        serializationObject.debug = this._debug;\r\n        serializationObject.stabilizeCascades = this.stabilizeCascades;\r\n        serializationObject.lambda = this._lambda;\r\n        serializationObject.cascadeBlendPercentage = this.cascadeBlendPercentage;\r\n        serializationObject.depthClamp = this._depthClamp;\r\n        serializationObject.autoCalcDepthBounds = this.autoCalcDepthBounds;\r\n        serializationObject.shadowMaxZ = this._shadowMaxZ;\r\n        serializationObject.penumbraDarkness = this.penumbraDarkness;\r\n\r\n        serializationObject.freezeShadowCastersBoundingInfo = this._freezeShadowCastersBoundingInfo;\r\n        serializationObject.minDistance = this.minDistance;\r\n        serializationObject.maxDistance = this.maxDistance;\r\n\r\n        serializationObject.renderList = [];\r\n        if (shadowMap.renderList) {\r\n            for (let meshIndex = 0; meshIndex < shadowMap.renderList.length; meshIndex++) {\r\n                const mesh = shadowMap.renderList[meshIndex];\r\n\r\n                serializationObject.renderList.push(mesh.id);\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized ShadowGenerator and returns a new ShadowGenerator.\r\n     * @param parsedShadowGenerator The JSON object to parse\r\n     * @param scene The scene to create the shadow map for\r\n     * @returns The parsed shadow generator\r\n     */\r\n    public static override Parse(parsedShadowGenerator: any, scene: Scene): ShadowGenerator {\r\n        const shadowGenerator = ShadowGenerator.Parse(\r\n            parsedShadowGenerator,\r\n            scene,\r\n            (mapSize: number, light: IShadowLight, camera: Nullable<Camera>) => new CascadedShadowGenerator(mapSize, <DirectionalLight>light, undefined, camera)\r\n        ) as CascadedShadowGenerator;\r\n\r\n        if (parsedShadowGenerator.numCascades !== undefined) {\r\n            shadowGenerator.numCascades = parsedShadowGenerator.numCascades;\r\n        }\r\n\r\n        if (parsedShadowGenerator.debug !== undefined) {\r\n            shadowGenerator.debug = parsedShadowGenerator.debug;\r\n        }\r\n\r\n        if (parsedShadowGenerator.stabilizeCascades !== undefined) {\r\n            shadowGenerator.stabilizeCascades = parsedShadowGenerator.stabilizeCascades;\r\n        }\r\n\r\n        if (parsedShadowGenerator.lambda !== undefined) {\r\n            shadowGenerator.lambda = parsedShadowGenerator.lambda;\r\n        }\r\n\r\n        if (parsedShadowGenerator.cascadeBlendPercentage !== undefined) {\r\n            shadowGenerator.cascadeBlendPercentage = parsedShadowGenerator.cascadeBlendPercentage;\r\n        }\r\n\r\n        if (parsedShadowGenerator.depthClamp !== undefined) {\r\n            shadowGenerator.depthClamp = parsedShadowGenerator.depthClamp;\r\n        }\r\n\r\n        if (parsedShadowGenerator.autoCalcDepthBounds !== undefined) {\r\n            shadowGenerator.autoCalcDepthBounds = parsedShadowGenerator.autoCalcDepthBounds;\r\n        }\r\n\r\n        if (parsedShadowGenerator.shadowMaxZ !== undefined) {\r\n            shadowGenerator.shadowMaxZ = parsedShadowGenerator.shadowMaxZ;\r\n        }\r\n\r\n        if (parsedShadowGenerator.penumbraDarkness !== undefined) {\r\n            shadowGenerator.penumbraDarkness = parsedShadowGenerator.penumbraDarkness;\r\n        }\r\n\r\n        if (parsedShadowGenerator.freezeShadowCastersBoundingInfo !== undefined) {\r\n            shadowGenerator.freezeShadowCastersBoundingInfo = parsedShadowGenerator.freezeShadowCastersBoundingInfo;\r\n        }\r\n\r\n        if (parsedShadowGenerator.minDistance !== undefined && parsedShadowGenerator.maxDistance !== undefined) {\r\n            shadowGenerator.setMinMaxDistance(parsedShadowGenerator.minDistance, parsedShadowGenerator.maxDistance);\r\n        }\r\n\r\n        return shadowGenerator;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cascadedShadowGenerator.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCascadedShadowGenerator(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    ShadowGenerator._CascadedShadowGeneratorParser = (parsedShadowGenerator: any, scene: Scene) => CascadedShadowGenerator.Parse(parsedShadowGenerator, scene);\r\n}\r\n","import { type FrameGraph, type FrameGraphObjectList, type IShadowLight, type WritableObject, type FrameGraphTextureHandle, type Camera } from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { ShadowGenerator } from \"../../../Lights/Shadows/shadowGenerator\";\r\n\r\n/**\r\n * Task used to generate shadows from a list of objects.\r\n */\r\nexport class FrameGraphShadowGeneratorTask extends FrameGraphTask {\r\n    /**\r\n     * The object list that generates shadows.\r\n     */\r\n    public objectList: FrameGraphObjectList;\r\n\r\n    private _light: IShadowLight;\r\n    /**\r\n     * The light to generate shadows from.\r\n     */\r\n    public get light(): IShadowLight {\r\n        return this._light;\r\n    }\r\n\r\n    public set light(value: IShadowLight) {\r\n        if (value === this._light) {\r\n            return;\r\n        }\r\n\r\n        this._light = value;\r\n        this._createShadowGenerator(); // make sure the shadow generator is created\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.light = value;\r\n            this._updateShadowMap();\r\n        }\r\n    }\r\n\r\n    private _camera: Camera;\r\n    /**\r\n     * Gets or sets the camera used to generate the shadow generator.\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(camera: Camera) {\r\n        this._camera = camera;\r\n\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.camera = camera;\r\n            this._shadowGenerator.getShadowMap()!.cameraForLOD = camera;\r\n            this._updateShadowMap();\r\n        }\r\n    }\r\n\r\n    private _mapSize = 1024;\r\n    /**\r\n     * The size of the shadow map.\r\n     */\r\n    public get mapSize() {\r\n        return this._mapSize;\r\n    }\r\n\r\n    public set mapSize(value: number) {\r\n        if (value === this._mapSize) {\r\n            return;\r\n        }\r\n\r\n        this._mapSize = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.mapSize = value;\r\n            this._updateShadowMap();\r\n        }\r\n    }\r\n\r\n    private _useFloat32TextureType = false;\r\n    /**\r\n     * If true, the shadow map will use a 32 bits float texture type (else, 16 bits float is used if supported).\r\n     */\r\n    public get useFloat32TextureType() {\r\n        return this._useFloat32TextureType;\r\n    }\r\n\r\n    public set useFloat32TextureType(value: boolean) {\r\n        if (value === this._useFloat32TextureType) {\r\n            return;\r\n        }\r\n\r\n        this._useFloat32TextureType = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.useFloat32TextureType = value;\r\n            this._updateShadowMap();\r\n        }\r\n    }\r\n\r\n    private _useRedTextureFormat = true;\r\n    /**\r\n     * If true, the shadow map will use a red texture format (else, a RGBA format is used).\r\n     */\r\n    public get useRedTextureFormat() {\r\n        return this._useRedTextureFormat;\r\n    }\r\n\r\n    public set useRedTextureFormat(value: boolean) {\r\n        if (value === this._useRedTextureFormat) {\r\n            return;\r\n        }\r\n\r\n        this._useRedTextureFormat = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.useRedTextureFormat = value;\r\n            this._updateShadowMap();\r\n        }\r\n    }\r\n\r\n    private _bias = 0.01;\r\n    /**\r\n     * The bias to apply to the shadow map.\r\n     */\r\n    public get bias() {\r\n        return this._bias;\r\n    }\r\n\r\n    public set bias(value: number) {\r\n        if (value === this._bias) {\r\n            return;\r\n        }\r\n\r\n        this._bias = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.bias = value;\r\n        }\r\n    }\r\n\r\n    private _normalBias = 0;\r\n    /**\r\n     * The normal bias to apply to the shadow map.\r\n     */\r\n    public get normalBias() {\r\n        return this._normalBias;\r\n    }\r\n\r\n    public set normalBias(value: number) {\r\n        if (value === this._normalBias) {\r\n            return;\r\n        }\r\n\r\n        this._normalBias = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.normalBias = value;\r\n        }\r\n    }\r\n\r\n    private _darkness = 0;\r\n    /**\r\n     * The darkness of the shadows.\r\n     */\r\n    public get darkness() {\r\n        return this._darkness;\r\n    }\r\n\r\n    public set darkness(value: number) {\r\n        if (value === this._darkness) {\r\n            return;\r\n        }\r\n\r\n        this._darkness = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.darkness = value;\r\n        }\r\n    }\r\n\r\n    private _transparencyShadow = false;\r\n    /**\r\n     * Gets or sets the ability to have transparent shadow\r\n     */\r\n    public get transparencyShadow() {\r\n        return this._transparencyShadow;\r\n    }\r\n\r\n    public set transparencyShadow(value: boolean) {\r\n        if (value === this._transparencyShadow) {\r\n            return;\r\n        }\r\n\r\n        this._transparencyShadow = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.transparencyShadow = value;\r\n        }\r\n    }\r\n\r\n    private _enableSoftTransparentShadow = false;\r\n    /**\r\n     * Enables or disables shadows with varying strength based on the transparency\r\n     */\r\n    public get enableSoftTransparentShadow() {\r\n        return this._enableSoftTransparentShadow;\r\n    }\r\n\r\n    public set enableSoftTransparentShadow(value: boolean) {\r\n        if (value === this._enableSoftTransparentShadow) {\r\n            return;\r\n        }\r\n\r\n        this._enableSoftTransparentShadow = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.enableSoftTransparentShadow = value;\r\n        }\r\n    }\r\n\r\n    private _useOpacityTextureForTransparentShadow = false;\r\n    /**\r\n     * If this is true, use the opacity texture's alpha channel for transparent shadows instead of the diffuse one\r\n     */\r\n    public get useOpacityTextureForTransparentShadow() {\r\n        return this._useOpacityTextureForTransparentShadow;\r\n    }\r\n\r\n    public set useOpacityTextureForTransparentShadow(value: boolean) {\r\n        if (value === this._useOpacityTextureForTransparentShadow) {\r\n            return;\r\n        }\r\n\r\n        this._useOpacityTextureForTransparentShadow = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.useOpacityTextureForTransparentShadow = value;\r\n        }\r\n    }\r\n\r\n    private _filter = ShadowGenerator.FILTER_PCF;\r\n    /**\r\n     * The filter to apply to the shadow map.\r\n     */\r\n    public get filter() {\r\n        return this._filter;\r\n    }\r\n\r\n    public set filter(value: number) {\r\n        if (value === this._filter) {\r\n            return;\r\n        }\r\n\r\n        this._filter = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.filter = value;\r\n        }\r\n    }\r\n\r\n    private _filteringQuality = ShadowGenerator.QUALITY_HIGH;\r\n    /**\r\n     * The filtering quality to apply to the filter.\r\n     */\r\n    public get filteringQuality() {\r\n        return this._filteringQuality;\r\n    }\r\n\r\n    public set filteringQuality(value: number) {\r\n        if (value === this._filteringQuality) {\r\n            return;\r\n        }\r\n\r\n        this._filteringQuality = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.filteringQuality = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The shadow generator.\r\n     */\r\n    public readonly shadowGenerator: ShadowGenerator;\r\n\r\n    /**\r\n     * The shadow map texture.\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    protected _shadowGenerator: ShadowGenerator | undefined;\r\n\r\n    protected _updateShadowMap() {\r\n        const shadowGenerator = this._shadowGenerator as ShadowGenerator | undefined;\r\n        if (shadowGenerator === undefined) {\r\n            return;\r\n        }\r\n\r\n        const shadowMap = shadowGenerator.getShadowMap()!;\r\n\r\n        shadowMap._disableEngineStages = true;\r\n        shadowMap.cameraForLOD = this._camera;\r\n    }\r\n\r\n    protected _createShadowGeneratorInstance() {\r\n        this._shadowGenerator = new ShadowGenerator(this._mapSize, this._light, this._useFloat32TextureType, undefined, this._useRedTextureFormat);\r\n    }\r\n\r\n    protected _createShadowGenerator() {\r\n        if (!this._shadowGenerator && this._light) {\r\n            this._createShadowGeneratorInstance();\r\n            const shadowGenerator = this._shadowGenerator as ShadowGenerator | undefined;\r\n            if (shadowGenerator === undefined) {\r\n                return;\r\n            }\r\n            shadowGenerator.bias = this._bias;\r\n            shadowGenerator.normalBias = this._normalBias;\r\n            shadowGenerator.darkness = this._darkness;\r\n            shadowGenerator.transparencyShadow = this._transparencyShadow;\r\n            shadowGenerator.enableSoftTransparentShadow = this._enableSoftTransparentShadow;\r\n            shadowGenerator.useOpacityTextureForTransparentShadow = this._useOpacityTextureForTransparentShadow;\r\n            shadowGenerator.filter = this._filter;\r\n            shadowGenerator.filteringQuality = this._filteringQuality;\r\n\r\n            this._updateShadowMap();\r\n\r\n            (this.shadowGenerator as WritableObject<ShadowGenerator>) = shadowGenerator;\r\n\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return !!this._shadowGenerator && !!this._shadowGenerator.getShadowMap()?.isReadyForRendering();\r\n    }\r\n\r\n    /**\r\n     * Creates a new shadow generator task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphShadowGeneratorTask\";\r\n    }\r\n\r\n    public record() {\r\n        if (this.light === undefined || this.objectList === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphShadowGeneratorTask ${this.name}: light, objectList and camera are required`);\r\n        }\r\n\r\n        // Make sure the renderList / particleSystemList are set when FrameGraphShadowGeneratorTask.isReady() is called!\r\n        const shadowMap = this._shadowGenerator!.getShadowMap()!;\r\n\r\n        shadowMap.renderList = this.objectList.meshes;\r\n        shadowMap.particleSystemList = this.objectList.particleSystems;\r\n\r\n        const shadowTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} shadowmap`, this._shadowGenerator!.getShadowMap()!.getInternalTexture()!);\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, shadowTextureHandle);\r\n\r\n        const pass = this._frameGraph.addPass(this.name);\r\n\r\n        pass.setExecuteFunc((context) => {\r\n            if (!this.light.isEnabled() || !this.light.shadowEnabled) {\r\n                return;\r\n            }\r\n\r\n            const shadowMap = this._shadowGenerator!.getShadowMap()!;\r\n\r\n            shadowMap.renderList = this.objectList.meshes;\r\n            shadowMap.particleSystemList = this.objectList.particleSystems;\r\n\r\n            context.saveDepthStates();\r\n            context.setDepthStates(true, true);\r\n\r\n            context.renderUnmanaged(shadowMap);\r\n\r\n            context.restoreDepthStates();\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n\r\n    public override dispose() {\r\n        this._shadowGenerator?.dispose();\r\n        this._shadowGenerator = undefined;\r\n    }\r\n}\r\n","import { type FrameGraphTextureHandle, type FrameGraph } from \"core/index\";\r\nimport { CascadedShadowGenerator } from \"../../../Lights/Shadows/cascadedShadowGenerator.pure\";\r\nimport { FrameGraphShadowGeneratorTask } from \"./shadowGeneratorTask\";\r\nimport { DirectionalLight } from \"../../../Lights/directionalLight.pure\";\r\nimport { DepthTextureType, ThinMinMaxReducer } from \"../../../Misc/thinMinMaxReducer\";\r\nimport { FrameGraphPostProcessTask } from \"../PostProcesses/postProcessTask\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { textureSizeIsObject } from \"../../../Materials/Textures/textureCreationOptions\";\r\n\r\n/**\r\n * Task used to generate a cascaded shadow map from a list of objects.\r\n */\r\nexport class FrameGraphCascadedShadowGeneratorTask extends FrameGraphShadowGeneratorTask {\r\n    protected override _shadowGenerator: CascadedShadowGenerator | undefined;\r\n\r\n    /**\r\n     * Checks if a shadow generator task is a cascaded shadow generator task.\r\n     * @param task The task to check.\r\n     * @returns True if the task is a cascaded shadow generator task, else false.\r\n     */\r\n    public static IsCascadedShadowGenerator(task: FrameGraphShadowGeneratorTask): task is FrameGraphCascadedShadowGeneratorTask {\r\n        return (task as FrameGraphCascadedShadowGeneratorTask).numCascades !== undefined;\r\n    }\r\n\r\n    /**\r\n     * The depth texture used by the autoCalcDepthBounds feature (optional if autoCalcDepthBounds is set to false).\r\n     * This texture is used to compute the min/max depth bounds of the scene to setup the cascaded shadow generator.\r\n     * The texture should contain either “view,” “normalized view,” or “screen” depth values - if possible, connect “normalized view,” or “screen” for best performance.\r\n     * Warning: Do not set a texture if you are not using the autoCalcDepthBounds feature, to avoid generating a depth texture that will not be used.\r\n     */\r\n    public depthTexture?: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The type of the depth texture used by the autoCalcDepthBounds feature.\r\n     */\r\n    public depthTextureType: DepthTextureType = DepthTextureType.NormalizedViewDepth;\r\n\r\n    private _numCascades = CascadedShadowGenerator.DEFAULT_CASCADES_COUNT;\r\n    /**\r\n     * The number of cascades.\r\n     */\r\n    public get numCascades() {\r\n        return this._numCascades;\r\n    }\r\n\r\n    public set numCascades(value: number) {\r\n        if (value === this._numCascades) {\r\n            return;\r\n        }\r\n\r\n        this._numCascades = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.numCascades = value;\r\n            this._updateShadowMap();\r\n        }\r\n    }\r\n\r\n    private _debug = false;\r\n    /**\r\n     * Gets or sets a value indicating whether the shadow generator should display the cascades.\r\n     */\r\n    public get debug() {\r\n        return this._debug;\r\n    }\r\n\r\n    public set debug(value: boolean) {\r\n        if (value === this._debug) {\r\n            return;\r\n        }\r\n\r\n        this._debug = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.debug = value;\r\n        }\r\n    }\r\n\r\n    private _stabilizeCascades = false;\r\n    /**\r\n     * Gets or sets a value indicating whether the shadow generator should stabilize the cascades.\r\n     */\r\n    public get stabilizeCascades() {\r\n        return this._stabilizeCascades;\r\n    }\r\n\r\n    public set stabilizeCascades(value: boolean) {\r\n        if (value === this._stabilizeCascades) {\r\n            return;\r\n        }\r\n\r\n        this._stabilizeCascades = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.stabilizeCascades = value;\r\n        }\r\n    }\r\n\r\n    private _lambda = 0.5;\r\n    /**\r\n     * Gets or sets the lambda parameter of the shadow generator.\r\n     */\r\n    public get lambda() {\r\n        return this._lambda;\r\n    }\r\n\r\n    public set lambda(value: number) {\r\n        if (value === this._lambda) {\r\n            return;\r\n        }\r\n\r\n        this._lambda = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.lambda = value;\r\n        }\r\n    }\r\n\r\n    private _cascadeBlendPercentage = 0.1;\r\n    /**\r\n     * Gets or sets the cascade blend percentage.\r\n     */\r\n    public get cascadeBlendPercentage() {\r\n        return this._cascadeBlendPercentage;\r\n    }\r\n\r\n    public set cascadeBlendPercentage(value: number) {\r\n        if (value === this._cascadeBlendPercentage) {\r\n            return;\r\n        }\r\n\r\n        this._cascadeBlendPercentage = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.cascadeBlendPercentage = value;\r\n        }\r\n    }\r\n\r\n    private _depthClamp = true;\r\n    /**\r\n     * Gets or sets a value indicating whether the shadow generator should use depth clamping.\r\n     */\r\n    public get depthClamp() {\r\n        return this._depthClamp;\r\n    }\r\n\r\n    public set depthClamp(value: boolean) {\r\n        if (value === this._depthClamp) {\r\n            return;\r\n        }\r\n\r\n        this._depthClamp = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.depthClamp = value;\r\n        }\r\n    }\r\n\r\n    private _autoCalcDepthBounds = false;\r\n    /**\r\n     * Gets or sets a value indicating whether the shadow generator should automatically calculate the depth bounds.\r\n     */\r\n    public get autoCalcDepthBounds() {\r\n        return this._autoCalcDepthBounds;\r\n    }\r\n\r\n    public set autoCalcDepthBounds(value: boolean) {\r\n        if (value === this._autoCalcDepthBounds) {\r\n            return;\r\n        }\r\n\r\n        this._autoCalcDepthBounds = value;\r\n        this._currentAutoCalcDepthBoundsCounter = this._autoCalcDepthBoundsRefreshRate;\r\n\r\n        if (!value) {\r\n            this._shadowGenerator?.setMinMaxDistance(0, 1);\r\n        }\r\n\r\n        // All passes but the last one are related to min/max reduction and should be enabled/disabled depending on autoCalcDepthBounds value\r\n        const passes = this.passes;\r\n        for (let i = 0; i < passes.length - 1; ++i) {\r\n            passes[i].disabled = !value;\r\n        }\r\n    }\r\n\r\n    private _currentAutoCalcDepthBoundsCounter = 0;\r\n    private _autoCalcDepthBoundsRefreshRate = 1;\r\n    /**\r\n     * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true\r\n     * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...\r\n     */\r\n    public get autoCalcDepthBoundsRefreshRate() {\r\n        return this._autoCalcDepthBoundsRefreshRate;\r\n    }\r\n\r\n    public set autoCalcDepthBoundsRefreshRate(value: number) {\r\n        this._autoCalcDepthBoundsRefreshRate = value;\r\n        this._currentAutoCalcDepthBoundsCounter = this._autoCalcDepthBoundsRefreshRate;\r\n    }\r\n\r\n    private _shadowMaxZ = 10000;\r\n    /**\r\n     * Gets or sets the maximum shadow Z value.\r\n     */\r\n    public get shadowMaxZ() {\r\n        return this._shadowMaxZ;\r\n    }\r\n\r\n    public set shadowMaxZ(value: number) {\r\n        if (value === this._shadowMaxZ) {\r\n            return;\r\n        }\r\n\r\n        this._shadowMaxZ = value;\r\n        if (this._shadowGenerator) {\r\n            this._shadowGenerator.shadowMaxZ = value;\r\n        }\r\n    }\r\n\r\n    protected readonly _thinMinMaxReducer: ThinMinMaxReducer;\r\n\r\n    /**\r\n     * Creates a new shadow generator task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this._thinMinMaxReducer = new ThinMinMaxReducer(frameGraph.scene);\r\n\r\n        this._thinMinMaxReducer.onAfterReductionPerformed.add((minmax: { min: number; max: number }) => {\r\n            if (!this._shadowGenerator) {\r\n                return;\r\n            }\r\n\r\n            const camera = this.camera;\r\n\r\n            let min = minmax.min,\r\n                max = minmax.max;\r\n\r\n            if (min >= max) {\r\n                min = 0;\r\n                max = 1;\r\n            } else if (camera && this.depthTextureType !== DepthTextureType.NormalizedViewDepth) {\r\n                if (this.depthTextureType === DepthTextureType.ScreenDepth) {\r\n                    const engine = this._frameGraph.engine;\r\n                    const projectionMatrix = camera.getProjectionMatrix();\r\n                    const p2z = projectionMatrix.m[10];\r\n                    const p3z = projectionMatrix.m[14];\r\n\r\n                    if (!engine.isNDCHalfZRange) {\r\n                        // Convert to NDC depth\r\n                        min = min * 2 - 1;\r\n                        max = max * 2 - 1;\r\n                    }\r\n\r\n                    // Convert to view depth\r\n                    min = p3z / (min - p2z);\r\n                    max = p3z / (max - p2z);\r\n                }\r\n\r\n                // Convert to normalized view depth\r\n                const zNear = camera.minZ;\r\n                const zFar = camera.maxZ;\r\n\r\n                min = (min - zNear) / (zFar - zNear);\r\n                max = (max - zNear) / (zFar - zNear);\r\n            }\r\n\r\n            if (min !== this._shadowGenerator.minDistance || max !== this._shadowGenerator.maxDistance) {\r\n                this._shadowGenerator.setMinMaxDistance(min, max);\r\n            }\r\n        });\r\n    }\r\n\r\n    protected override _createShadowGeneratorInstance() {\r\n        if (!(this.light instanceof DirectionalLight)) {\r\n            throw new Error(`FrameGraphCascadedShadowGeneratorTask ${this.name}: the CSM shadow generator only supports directional lights.`);\r\n        }\r\n        this._shadowGenerator = new CascadedShadowGenerator(this.mapSize, this.light, this.useFloat32TextureType, this.camera, this.useRedTextureFormat);\r\n    }\r\n\r\n    protected override _createShadowGenerator() {\r\n        if (super._createShadowGenerator()) {\r\n            const shadowGenerator = this._shadowGenerator;\r\n            if (shadowGenerator === undefined) {\r\n                return;\r\n            }\r\n\r\n            shadowGenerator.numCascades = this._numCascades;\r\n            shadowGenerator.debug = this._debug;\r\n            shadowGenerator.stabilizeCascades = this._stabilizeCascades;\r\n            shadowGenerator.lambda = this._lambda;\r\n            shadowGenerator.cascadeBlendPercentage = this._cascadeBlendPercentage;\r\n            shadowGenerator.depthClamp = this._depthClamp;\r\n            shadowGenerator.shadowMaxZ = this._shadowMaxZ;\r\n\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphCascadedShadowGeneratorTask\";\r\n    }\r\n\r\n    public override record() {\r\n        if (this.light === undefined || this.objectList === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphCascadedShadowGeneratorTask ${this.name}: light, objectList and camera are required`);\r\n        }\r\n\r\n        if (this.depthTexture !== undefined) {\r\n            const depthTextureCreationOptions = this._frameGraph.textureManager.getTextureCreationOptions(this.depthTexture);\r\n\r\n            const size = !depthTextureCreationOptions.sizeIsPercentage\r\n                ? textureSizeIsObject(depthTextureCreationOptions.size)\r\n                    ? depthTextureCreationOptions.size\r\n                    : { width: depthTextureCreationOptions.size, height: depthTextureCreationOptions.size }\r\n                : this._frameGraph.textureManager.getAbsoluteDimensions(depthTextureCreationOptions.size);\r\n\r\n            const width = size.width;\r\n            const height = size.height;\r\n\r\n            depthTextureCreationOptions.sizeIsPercentage = false;\r\n            depthTextureCreationOptions.options.formats = [Constants.TEXTUREFORMAT_RG];\r\n            depthTextureCreationOptions.options.samples = 1;\r\n\r\n            this._thinMinMaxReducer.setTextureDimensions(width, height, this.depthTextureType);\r\n\r\n            const reductionSteps = this._thinMinMaxReducer.reductionSteps;\r\n\r\n            let targetTexture: FrameGraphTextureHandle;\r\n\r\n            this._frameGraph.addPass(`${this.name} Before Min Max Reduction`).setExecuteFunc((context) => {\r\n                context.pushDebugGroup(`Min Max Reduction`);\r\n            });\r\n\r\n            for (let i = 0; i < reductionSteps.length - 1; ++i) {\r\n                const reductionStep = reductionSteps[i];\r\n\r\n                depthTextureCreationOptions.size = { width: reductionSteps[i + 1].textureWidth, height: reductionSteps[i + 1].textureHeight };\r\n\r\n                const postProcess = new FrameGraphPostProcessTask(reductionStep.name, this._frameGraph, reductionStep);\r\n\r\n                postProcess.sourceTexture = i == 0 ? this.depthTexture : targetTexture!;\r\n                postProcess.sourceSamplingMode = Constants.TEXTURE_NEAREST_NEAREST;\r\n                postProcess.targetTexture = this._frameGraph.textureManager.createRenderTargetTexture(`${this.name} ${reductionStep.name}`, depthTextureCreationOptions);\r\n\r\n                postProcess.record(true);\r\n\r\n                targetTexture = postProcess.outputTexture;\r\n            }\r\n\r\n            this._frameGraph.addPass(`${this.name} After Min Max Reduction`).setExecuteFunc((context) => {\r\n                context.popDebugGroup();\r\n                if (this._autoCalcDepthBounds && this._currentAutoCalcDepthBoundsCounter >= 0) {\r\n                    if (++this._currentAutoCalcDepthBoundsCounter >= this._autoCalcDepthBoundsRefreshRate) {\r\n                        const minMaxTexture = context.getTextureFromHandle(targetTexture!);\r\n                        if (minMaxTexture) {\r\n                            this._thinMinMaxReducer.readMinMax(minMaxTexture);\r\n                        }\r\n                    }\r\n                    this._currentAutoCalcDepthBoundsCounter %= this._autoCalcDepthBoundsRefreshRate;\r\n                    if (this._autoCalcDepthBoundsRefreshRate === 0) {\r\n                        this._currentAutoCalcDepthBoundsCounter = -1;\r\n                    }\r\n                }\r\n            });\r\n        }\r\n\r\n        super.record();\r\n    }\r\n\r\n    public override dispose() {\r\n        super.dispose();\r\n        this._thinMinMaxReducer.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph, type NodeRenderGraphConnectionPoint, type FrameGraphTextureHandle, type NodeRenderGraphBuildState } from \"core/index\";\r\nimport { NodeRenderGraphBaseShadowGeneratorBlock } from \"./baseShadowGeneratorBlock\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphCascadedShadowGeneratorTask } from \"../../../Tasks/Rendering/csmShadowGeneratorTask\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { DepthTextureType } from \"core/Misc/thinMinMaxReducer\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that generates shadows through a shadow generator\r\n */\r\nexport class NodeRenderGraphCascadedShadowGeneratorBlock extends NodeRenderGraphBaseShadowGeneratorBlock {\r\n    protected override _frameGraphTask: FrameGraphCascadedShadowGeneratorTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphCascadedShadowGeneratorBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"geomDepth\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.geomDepth.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeRenderGraphBlockConnectionPointTypes.TextureNormalizedViewDepth |\r\n                NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth |\r\n                NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth\r\n        );\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphCascadedShadowGeneratorTask(this.name, frameGraph);\r\n    }\r\n\r\n    /** Sets the number of cascades */\r\n    @editableInPropertyPage(\"Number of cascades\", PropertyTypeForEdition.List, \"CSM PROPERTIES\", {\r\n        options: [\r\n            { label: \"2\", value: 2 },\r\n            { label: \"3\", value: 3 },\r\n            { label: \"4\", value: 4 },\r\n        ],\r\n    })\r\n    public get numCascades() {\r\n        return this._frameGraphTask.numCascades;\r\n    }\r\n\r\n    public set numCascades(value: number) {\r\n        this._frameGraphTask.numCascades = value;\r\n    }\r\n\r\n    /** Gets or sets a value indicating whether the shadow generator should display the cascades. */\r\n    @editableInPropertyPage(\"Debug mode\", PropertyTypeForEdition.Boolean, \"CSM PROPERTIES\")\r\n    public get debug() {\r\n        return this._frameGraphTask.debug;\r\n    }\r\n\r\n    public set debug(value: boolean) {\r\n        this._frameGraphTask.debug = value;\r\n    }\r\n\r\n    /** Gets or sets a value indicating whether the shadow generator should stabilize the cascades. */\r\n    @editableInPropertyPage(\"Stabilize cascades\", PropertyTypeForEdition.Boolean, \"CSM PROPERTIES\")\r\n    public get stabilizeCascades() {\r\n        return this._frameGraphTask.stabilizeCascades;\r\n    }\r\n\r\n    public set stabilizeCascades(value: boolean) {\r\n        this._frameGraphTask.stabilizeCascades = value;\r\n    }\r\n\r\n    /** Gets or sets the lambda parameter of the shadow generator. */\r\n    @editableInPropertyPage(\"Lambda\", PropertyTypeForEdition.Float, \"CSM PROPERTIES\", { min: 0, max: 1 })\r\n    public get lambda() {\r\n        return this._frameGraphTask.lambda;\r\n    }\r\n\r\n    public set lambda(value: number) {\r\n        this._frameGraphTask.lambda = value;\r\n    }\r\n\r\n    /** Gets or sets the cascade blend percentage. */\r\n    @editableInPropertyPage(\"Cascade blend\", PropertyTypeForEdition.Float, \"CSM PROPERTIES\", { min: 0, max: 1 })\r\n    public get cascadeBlendPercentage() {\r\n        return this._frameGraphTask.cascadeBlendPercentage;\r\n    }\r\n\r\n    public set cascadeBlendPercentage(value: number) {\r\n        this._frameGraphTask.cascadeBlendPercentage = value;\r\n    }\r\n\r\n    /** Gets or sets a value indicating whether the shadow generator should use depth clamping. */\r\n    @editableInPropertyPage(\"Depth clamp\", PropertyTypeForEdition.Boolean, \"CSM PROPERTIES\")\r\n    public get depthClamp() {\r\n        return this._frameGraphTask.depthClamp;\r\n    }\r\n\r\n    public set depthClamp(value: boolean) {\r\n        this._frameGraphTask.depthClamp = value;\r\n    }\r\n\r\n    /** Gets or sets a value indicating whether the shadow generator should automatically calculate the depth bounds. */\r\n    @editableInPropertyPage(\"Auto-Calc depth bounds\", PropertyTypeForEdition.Boolean, \"CSM PROPERTIES\")\r\n    public get autoCalcDepthBounds() {\r\n        return this._frameGraphTask.autoCalcDepthBounds;\r\n    }\r\n\r\n    public set autoCalcDepthBounds(value: boolean) {\r\n        this._frameGraphTask.autoCalcDepthBounds = value;\r\n    }\r\n\r\n    /** Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true. */\r\n    @editableInPropertyPage(\"Auto-Calc depth bounds refresh rate\", PropertyTypeForEdition.Int, \"CSM PROPERTIES\")\r\n    public get autoCalcDepthBoundsRefreshRate() {\r\n        return this._frameGraphTask.autoCalcDepthBoundsRefreshRate;\r\n    }\r\n\r\n    public set autoCalcDepthBoundsRefreshRate(value: number) {\r\n        this._frameGraphTask.autoCalcDepthBoundsRefreshRate = value;\r\n    }\r\n\r\n    /** Gets or sets the maximum shadow Z value. */\r\n    @editableInPropertyPage(\"Shadow maxZ\", PropertyTypeForEdition.Float, \"CSM PROPERTIES\")\r\n    public get shadowMaxZ() {\r\n        return this._frameGraphTask.shadowMaxZ;\r\n    }\r\n\r\n    public set shadowMaxZ(value: number) {\r\n        this._frameGraphTask.shadowMaxZ = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphCascadedShadowGeneratorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry (view / normalized view) depth component\r\n     */\r\n    public get geomDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._frameGraphTask.depthTexture = this.geomDepth.connectedPoint?.value as FrameGraphTextureHandle;\r\n\r\n        if (this.geomDepth.connectedPoint) {\r\n            switch (this.geomDepth.connectedPoint.type) {\r\n                case NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth:\r\n                    this._frameGraphTask.depthTextureType = DepthTextureType.ScreenDepth;\r\n                    break;\r\n                case NodeRenderGraphBlockConnectionPointTypes.TextureNormalizedViewDepth:\r\n                    this._frameGraphTask.depthTextureType = DepthTextureType.NormalizedViewDepth;\r\n                    break;\r\n                case NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth:\r\n                    this._frameGraphTask.depthTextureType = DepthTextureType.ViewDepth;\r\n                    break;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.numCascades = ${this.numCascades};`);\r\n        codes.push(`${this._codeVariableName}.debug = ${this.debug};`);\r\n        codes.push(`${this._codeVariableName}.stabilizeCascades = ${this.stabilizeCascades};`);\r\n        codes.push(`${this._codeVariableName}.lambda = ${this.lambda};`);\r\n        codes.push(`${this._codeVariableName}.cascadeBlendPercentage = ${this.cascadeBlendPercentage};`);\r\n        codes.push(`${this._codeVariableName}.depthClamp = ${this.depthClamp};`);\r\n        codes.push(`${this._codeVariableName}.autoCalcDepthBounds = ${this.autoCalcDepthBounds};`);\r\n        codes.push(`${this._codeVariableName}.autoCalcDepthBoundsRefreshRate = ${this.autoCalcDepthBoundsRefreshRate};`);\r\n        codes.push(`${this._codeVariableName}.shadowMaxZ = ${this.shadowMaxZ};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.numCascades = this.numCascades;\r\n        serializationObject.debug = this.debug;\r\n        serializationObject.stabilizeCascades = this.stabilizeCascades;\r\n        serializationObject.lambda = this.lambda;\r\n        serializationObject.cascadeBlendPercentage = this.cascadeBlendPercentage;\r\n        serializationObject.depthClamp = this.depthClamp;\r\n        serializationObject.autoCalcDepthBounds = this.autoCalcDepthBounds;\r\n        serializationObject.autoCalcDepthBoundsRefreshRate = this.autoCalcDepthBoundsRefreshRate;\r\n        serializationObject.shadowMaxZ = this.shadowMaxZ;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.numCascades = serializationObject.numCascades;\r\n        this.debug = serializationObject.debug;\r\n        this.stabilizeCascades = serializationObject.stabilizeCascades;\r\n        this.lambda = serializationObject.lambda;\r\n        this.cascadeBlendPercentage = serializationObject.cascadeBlendPercentage;\r\n        this.depthClamp = serializationObject.depthClamp;\r\n        this.autoCalcDepthBounds = serializationObject.autoCalcDepthBounds;\r\n        this.autoCalcDepthBoundsRefreshRate = serializationObject.autoCalcDepthBoundsRefreshRate ?? 1;\r\n        this.shadowMaxZ = serializationObject.shadowMaxZ;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for csmShadowGeneratorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCsmShadowGeneratorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphCascadedShadowGeneratorBlock\", NodeRenderGraphCascadedShadowGeneratorBlock);\r\n}\r\n","import {\r\n    type FrameGraphTextureHandle,\r\n    type Scene,\r\n    type FrameGraph,\r\n    type AbstractMesh,\r\n    type ObjectRendererOptions,\r\n    type FrameGraphRenderContext,\r\n    type FrameGraphRenderPass,\r\n    type ObjectRenderer,\r\n    type GeometryRenderingMeshBlendTagProvider,\r\n} from \"core/index\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { MaterialHelperGeometryRendering, GeometryRenderingTextureClearType, type GeometryRenderingObjectIdProvider } from \"core/Materials/materialHelper.geometryrendering\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { _IsMeshBlendingSupported } from \"../../../Meshes/meshBlendingTag\";\r\nimport { FrameGraphObjectRendererTask } from \"./objectRendererTask\";\r\n\r\n/**\r\n * Description of a texture used by the geometry renderer task.\r\n */\r\nexport interface IFrameGraphGeometryRendererTextureDescription {\r\n    /**\r\n     * The type of the texture.\r\n     * The value should be one of the Constants.PREPASS_XXX_TEXTURE_TYPE values.\r\n     */\r\n    type: number;\r\n\r\n    /**\r\n     * The type of the texture.\r\n     */\r\n    textureType: number;\r\n\r\n    /**\r\n     * The format of the texture.\r\n     */\r\n    textureFormat: number;\r\n}\r\n\r\nconst ClearColors: Color4[] = [new Color4(0, 0, 0, 0), new Color4(1, 1, 1, 1), new Color4(0, 0, 0, 0)];\r\n\r\n/**\r\n * Task used to render geometry to a set of textures.\r\n */\r\nexport class FrameGraphGeometryRendererTask extends FrameGraphObjectRendererTask {\r\n    /**\r\n     * The size of the output textures (default is 100% of the back buffer texture size).\r\n     */\r\n    public size: { width: number; height: number } = { width: 100, height: 100 };\r\n\r\n    /**\r\n     * Whether the size is a percentage of the back buffer size (default is true).\r\n     */\r\n    public sizeIsPercentage = true;\r\n\r\n    /**\r\n     * The number of samples to use for the output textures (default is 1).\r\n     */\r\n    public samples = 1;\r\n\r\n    private _reverseCulling = false;\r\n\r\n    /**\r\n     * Whether to reverse culling (default is false).\r\n     */\r\n    public get reverseCulling() {\r\n        return this._reverseCulling;\r\n    }\r\n\r\n    public set reverseCulling(value: boolean) {\r\n        this._reverseCulling = value;\r\n\r\n        const configuration = MaterialHelperGeometryRendering.GetConfiguration(this._renderer.renderPassId);\r\n        if (configuration) {\r\n            configuration.reverseCulling = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Indicates if a mesh shouldn't be rendered when its material has depth write disabled (default is true).\r\n     */\r\n    public dontRenderWhenMaterialDepthWriteIsDisabled = true;\r\n\r\n    private _disableDepthPrePass = true;\r\n    /**\r\n     * Indicates whether the depth pre-pass is disabled (default is true).\r\n     * Materials that require depth pre-pass (Material.needDepthPrePass == true) don't work with the geometry renderer, that's why this setting is true by default.\r\n     * However, if the geometry renderer doesn't generate any geometry textures but only renders to the main target texture, then depth pre-pass can be enabled.\r\n     */\r\n    public get disableDepthPrePass() {\r\n        return this._disableDepthPrePass;\r\n    }\r\n\r\n    public set disableDepthPrePass(value: boolean) {\r\n        this._disableDepthPrePass = value;\r\n        this._renderer.disableDepthPrePass = value;\r\n    }\r\n\r\n    /**\r\n     * The list of texture descriptions used by the geometry renderer task.\r\n     */\r\n    public textureDescriptions: IFrameGraphGeometryRendererTextureDescription[] = [];\r\n\r\n    private _objectIdProvider?: GeometryRenderingObjectIdProvider;\r\n    private _meshBlendTagProvider?: GeometryRenderingMeshBlendTagProvider;\r\n\r\n    /**\r\n     * Provides the object ID written for each rendered mesh.\r\n     *\r\n     * IDs must be integers between 0 and 0xFFFFFF for RGBA textures, or between 0 and 0xFF for RED textures.\r\n     * ID 0 is reserved for background or excluded meshes.\r\n     * By default, meshes use their unique ID.\r\n     * Instances use the ID of their source mesh. Default IDs are only stable for the lifetime of the current scene and should not be persisted.\r\n     * When using a RED texture, provide a custom ID if mesh unique IDs can exceed 0xFF.\r\n     * The provider runs in the render hot path and may be called multiple times for the same mesh in a frame.\r\n     * @see https://playground.babylonjs.com/?version=preview#00T6WJ#0\r\n     */\r\n    public get objectIdProvider(): GeometryRenderingObjectIdProvider | undefined {\r\n        return this._objectIdProvider;\r\n    }\r\n\r\n    public set objectIdProvider(value: GeometryRenderingObjectIdProvider | undefined) {\r\n        this._objectIdProvider = value;\r\n\r\n        const configuration = MaterialHelperGeometryRendering.GetConfiguration(this._renderer.renderPassId);\r\n        if (configuration) {\r\n            configuration.objectIdProvider = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Provides the packed mesh-blending tag written for each rendered mesh.\r\n     *\r\n     * Tags must be 0 or contain a group ID between 1 and 63 in their low six bits. Tag 0 disables mesh blending.\r\n     * By default, meshes use their `meshBlendingTag` property. Instances and thin instances use the source mesh tag.\r\n     * The provider runs in the render hot path and receives the source mesh for instanced draws.\r\n     * It should avoid allocations and return a consistent value for a mesh during a render.\r\n     */\r\n    public get meshBlendTagProvider(): GeometryRenderingMeshBlendTagProvider | undefined {\r\n        return this._meshBlendTagProvider;\r\n    }\r\n\r\n    public set meshBlendTagProvider(value: GeometryRenderingMeshBlendTagProvider | undefined) {\r\n        this._meshBlendTagProvider = value;\r\n\r\n        const configuration = MaterialHelperGeometryRendering.GetConfiguration(this._renderer.renderPassId);\r\n        if (configuration) {\r\n            configuration.meshBlendTagProvider = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The irradiance output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryIrradianceTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The depth (in view space) output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryViewDepthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The normalized depth (in view space) output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     * The normalization is (d - near) / (far - near), where d is the depth value in view space and near and far are the near and far planes of the camera.\r\n     */\r\n    public readonly geometryNormViewDepthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The depth (in screen space) output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryScreenDepthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The normal (in view space) output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryViewNormalTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The normal (in world space, encoded from [-1, 1] to [0, 1]) output texture.\r\n     * Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryWorldNormalTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The position (in local space) output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryLocalPositionTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The position (in world space) output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryWorldPositionTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The albedo output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryAlbedoTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The reflectivity output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     */\r\n    public readonly geometryReflectivityTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The velocity output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     * Built-in CPU/GPU particles write neutral velocity (0.5, 0.5); their motion is not represented.\r\n     */\r\n    public readonly geometryVelocityTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The linear velocity output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     * Built-in CPU/GPU particles write neutral velocity (0, 0); their motion is not represented.\r\n     */\r\n    public readonly geometryLinearVelocityTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The object ID output texture. Will point to a valid texture only if that texture has been requested in textureDescriptions!\r\n     * RGBA unsigned byte textures store 24-bit IDs, while RED unsigned byte textures store 8-bit IDs.\r\n     * Decode RED values with `round(value * 255.0)`.\r\n     */\r\n    public readonly geometryObjectIdTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The packed, single-sample R8UI mesh-blending tag output texture for WebGL2 and WebGPU.\r\n     *\r\n     * Opaque, alpha-tested, and caller-selected transparent meshes are supported.\r\n     */\r\n    public readonly geometryMeshBlendTagTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Gets or sets the name of the task.\r\n     */\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(value: string) {\r\n        this._name = value;\r\n        if (this._renderer) {\r\n            this._renderer.name = value;\r\n        }\r\n    }\r\n\r\n    private _clearAttachmentsLayout: Map<GeometryRenderingTextureClearType, number[]>;\r\n    private _allAttachmentsLayout: number[];\r\n    private _colorAttachmentsLayout: number[];\r\n\r\n    /**\r\n     * Constructs a new geometry renderer task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     * @param scene The scene the frame graph is associated with.\r\n     * @param options The options of the object renderer.\r\n     * @param existingObjectRenderer An existing object renderer to use (optional). If provided, the options parameter will be ignored.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene, options?: ObjectRendererOptions, existingObjectRenderer?: ObjectRenderer) {\r\n        super(name, frameGraph, scene, options, existingObjectRenderer);\r\n\r\n        this.renderSprites = false;\r\n        this.renderParticles = false;\r\n        this.enableBoundingBoxRendering = false;\r\n        this.enableOutlineRendering = false;\r\n        this._renderer.disableDepthPrePass = true;\r\n\r\n        this._renderer.customIsReadyFunction = (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => {\r\n            if (this.dontRenderWhenMaterialDepthWriteIsDisabled && mesh.material && mesh.material.disableDepthWrite) {\r\n                return !!preWarm;\r\n            }\r\n\r\n            return mesh.isReady(!!preWarm || refreshRate === 0);\r\n        };\r\n\r\n        this._renderer.onBeforeRenderingManagerRenderObservable.add(() => {\r\n            if (!this._renderer.options.doNotChangeAspectRatio) {\r\n                scene.updateTransformMatrix(true);\r\n            }\r\n        });\r\n\r\n        this._clearAttachmentsLayout = new Map();\r\n        this._allAttachmentsLayout = [];\r\n        this._colorAttachmentsLayout = [];\r\n\r\n        this.geometryIrradianceTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryViewDepthTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryNormViewDepthTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryScreenDepthTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryViewNormalTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryWorldNormalTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryLocalPositionTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryWorldPositionTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryAlbedoTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryReflectivityTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryVelocityTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryLinearVelocityTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryObjectIdTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n        this.geometryMeshBlendTagTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    /**\r\n     * Gets the list of excluded meshes from the velocity texture.\r\n     */\r\n    public get excludedSkinnedMeshFromVelocityTexture(): AbstractMesh[] {\r\n        return MaterialHelperGeometryRendering.GetConfiguration(this._renderer.renderPassId).excludedSkinnedMesh;\r\n    }\r\n\r\n    /**\r\n     * Excludes the given skinned mesh from computing bones velocities.\r\n     * Computing bones velocities can have a cost. The cost can be saved by calling this function and by passing the skinned mesh to ignore.\r\n     * @param skinnedMesh The mesh containing the skeleton to ignore when computing the velocity map.\r\n     */\r\n    public excludeSkinnedMeshFromVelocityTexture(skinnedMesh: AbstractMesh): void {\r\n        if (skinnedMesh.skeleton) {\r\n            const list = this.excludedSkinnedMeshFromVelocityTexture;\r\n            if (list.indexOf(skinnedMesh) === -1) {\r\n                list.push(skinnedMesh);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes the given skinned mesh from the excluded meshes to integrate bones velocities while rendering the velocity map.\r\n     * @param skinnedMesh The mesh containing the skeleton that has been ignored previously.\r\n     * @see excludeSkinnedMesh to exclude a skinned mesh from bones velocity computation.\r\n     */\r\n    public removeExcludedSkinnedMeshFromVelocityTexture(skinnedMesh: AbstractMesh): void {\r\n        const list = this.excludedSkinnedMeshFromVelocityTexture;\r\n        const index = list.indexOf(skinnedMesh);\r\n        if (index !== -1) {\r\n            list.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphGeometryRendererTask\";\r\n    }\r\n\r\n    /**\r\n     * Records the geometry renderer task into the frame graph.\r\n     * @param skipCreationOfDisabledPasses defines whether disabled passes should be skipped\r\n     * @param additionalExecute defines an optional callback executed by the pass\r\n     * @returns the recorded render pass\r\n     */\r\n    public override record(skipCreationOfDisabledPasses = false, additionalExecute?: (context: FrameGraphRenderContext) => void): FrameGraphRenderPass {\r\n        this._buildClearAttachmentsLayout();\r\n\r\n        this._registerForRenderPassId(this._renderer.renderPassId);\r\n\r\n        MaterialHelperGeometryRendering.MarkAsDirty(this._renderer.renderPassId, this.objectList.meshes || this._scene.meshes);\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, additionalExecute) as FrameGraphRenderPass;\r\n\r\n        const outputTextureHandles = pass.renderTarget as FrameGraphTextureHandle[];\r\n        const targetTextureCount = this._getTargetTextureCount();\r\n\r\n        let needPreviousWorldMatrices = false;\r\n\r\n        for (let i = 0; i < this.textureDescriptions.length; i++) {\r\n            const description = this.textureDescriptions[i];\r\n            const handle = outputTextureHandles[targetTextureCount + i];\r\n            const index = MaterialHelperGeometryRendering.GeometryTextureDescriptions.findIndex((f) => f.type === description.type);\r\n            const geometryDescription = MaterialHelperGeometryRendering.GeometryTextureDescriptions[index];\r\n\r\n            switch (geometryDescription.type) {\r\n                case Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryIrradianceTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_DEPTH_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryViewDepthTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_NORMALIZED_VIEW_DEPTH_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryNormViewDepthTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryScreenDepthTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_NORMAL_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryViewNormalTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryWorldNormalTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryLocalPositionTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_POSITION_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryWorldPositionTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_ALBEDO_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryAlbedoTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryReflectivityTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_VELOCITY_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryVelocityTexture, handle);\r\n                    needPreviousWorldMatrices = true;\r\n                    break;\r\n                case Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryLinearVelocityTexture, handle);\r\n                    needPreviousWorldMatrices = true;\r\n                    break;\r\n                case Constants.PREPASS_OBJECT_ID_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryObjectIdTexture, handle);\r\n                    break;\r\n                case Constants.PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE:\r\n                    this._frameGraph.textureManager.resolveDanglingHandle(this.geometryMeshBlendTagTexture, handle);\r\n                    break;\r\n            }\r\n        }\r\n\r\n        this._scene.needsPreviousWorldMatrices = needPreviousWorldMatrices;\r\n\r\n        return pass;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        MaterialHelperGeometryRendering.DeleteConfiguration(this._renderer.renderPassId);\r\n        this._renderer.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    protected override _resolveDanglingHandles(_targetTextures: FrameGraphTextureHandle[]) {\r\n        if (this.targetTexture !== undefined) {\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, Array.isArray(this.targetTexture) ? this.targetTexture[0] : this.targetTexture);\r\n        }\r\n\r\n        if (this.depthTexture !== undefined) {\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputDepthTexture, this.depthTexture);\r\n        }\r\n    }\r\n\r\n    protected override _checkParameters() {\r\n        if (this.objectList === undefined || this.camera === undefined) {\r\n            throw new Error(`FrameGraphGeometryRendererTask ${this.name}: object list and camera must be provided`);\r\n        }\r\n\r\n        const objectIdDescription = this.textureDescriptions.find((description) => description.type === Constants.PREPASS_OBJECT_ID_TEXTURE_TYPE);\r\n        if (objectIdDescription) {\r\n            if (this.samples !== 1) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: object ID textures currently require samples to be 1`);\r\n            }\r\n\r\n            const isSupportedFormat = objectIdDescription.textureFormat === Constants.TEXTUREFORMAT_RGBA || objectIdDescription.textureFormat === Constants.TEXTUREFORMAT_RED;\r\n            if (objectIdDescription.textureType !== Constants.TEXTURETYPE_UNSIGNED_BYTE || !isSupportedFormat) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: object ID textures must use TEXTURETYPE_UNSIGNED_BYTE with TEXTUREFORMAT_RGBA or TEXTUREFORMAT_RED`);\r\n            }\r\n        }\r\n\r\n        const meshBlendTagIndex = this.textureDescriptions.findIndex((description) => description.type === Constants.PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE);\r\n        if (meshBlendTagIndex !== -1) {\r\n            const description = this.textureDescriptions[meshBlendTagIndex];\r\n            const engine = this._engine;\r\n            if (!_IsMeshBlendingSupported(engine)) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: mesh-blending tag textures require WebGL2 or WebGPU`);\r\n            }\r\n            if ((this.renderTransparentMeshes || this.renderSprites || this.renderParticles) && !engine.isWebGPU && !engine.getCaps().blendParametersPerTarget) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: transparent mesh-blending tags require per-target blend parameters`);\r\n            }\r\n            if (this.samples !== 1) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: mesh-blending tag textures require samples to be 1`);\r\n            }\r\n            if (description.textureType !== Constants.TEXTURETYPE_UNSIGNED_BYTE || description.textureFormat !== Constants.TEXTUREFORMAT_RED_INTEGER) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: mesh-blending tag textures must use TEXTURETYPE_UNSIGNED_BYTE with TEXTUREFORMAT_RED_INTEGER`);\r\n            }\r\n        }\r\n\r\n        const targetTextureCount = this.targetTexture === undefined ? 0 : Array.isArray(this.targetTexture) ? this.targetTexture.length : 1;\r\n        const attachmentCount = this.textureDescriptions.length + targetTextureCount;\r\n        const maxDrawBuffers = Math.min(this._engine.getCaps().maxDrawBuffers ?? 1, 8);\r\n        if (attachmentCount > maxDrawBuffers) {\r\n            throw new Error(`FrameGraphGeometryRendererTask ${this.name}: ${attachmentCount} color attachments were requested, but this engine supports at most ${maxDrawBuffers}`);\r\n        }\r\n    }\r\n\r\n    protected override _checkTextureCompatibility(targetTextures: FrameGraphTextureHandle[]): boolean {\r\n        let depthEnabled = false;\r\n\r\n        let dimensions: { width: number; height: number } | null = null;\r\n\r\n        if (this.targetTexture !== undefined) {\r\n            const outputTextureDescription = this._frameGraph.textureManager.getTextureDescription(Array.isArray(this.targetTexture) ? this.targetTexture[0] : this.targetTexture);\r\n            if (this.samples !== outputTextureDescription.options.samples) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: the target texture and the output geometry textures  must have the same number of samples`);\r\n            }\r\n            dimensions = outputTextureDescription.size;\r\n        }\r\n\r\n        if (this.depthTexture !== undefined) {\r\n            const depthTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.depthTexture);\r\n            if (depthTextureDescription.options.samples !== this.samples && this.textureDescriptions.length > 0) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: the depth texture and the output geometry textures must have the same number of samples`);\r\n            }\r\n\r\n            this._frameGraph.textureManager.resolveDanglingHandle(this.outputDepthTexture, this.depthTexture);\r\n\r\n            depthEnabled = true;\r\n            dimensions = depthTextureDescription.size;\r\n        }\r\n\r\n        const geomTextureDimensions = this.sizeIsPercentage ? this._frameGraph.textureManager.getAbsoluteDimensions(this.size) : this.size;\r\n        if (dimensions !== null) {\r\n            if (geomTextureDimensions.width !== dimensions.width || geomTextureDimensions.height !== dimensions.height) {\r\n                throw new Error(\r\n                    `FrameGraphGeometryRendererTask ${this.name}: the geometry textures (size: ${geomTextureDimensions.width}x${geomTextureDimensions.height}) and the target/depth texture (size: ${dimensions.width}x${dimensions.height}) must have the same dimensions.`\r\n                );\r\n            }\r\n        }\r\n\r\n        depthEnabled = depthEnabled || super._checkTextureCompatibility(targetTextures);\r\n\r\n        return depthEnabled;\r\n    }\r\n\r\n    protected override _getTargetHandles(): FrameGraphTextureHandle[] {\r\n        const types: number[] = [];\r\n        const formats: number[] = [];\r\n        const labels: string[] = [];\r\n        const useSRGBBuffers: boolean[] = [];\r\n\r\n        for (let i = 0; i < this.textureDescriptions.length; i++) {\r\n            const description = this.textureDescriptions[i];\r\n            const index = MaterialHelperGeometryRendering.GeometryTextureDescriptions.findIndex((f) => f.type === description.type);\r\n\r\n            if (index === -1) {\r\n                throw new Error(`FrameGraphGeometryRendererTask ${this.name}: unknown texture type ${description.type}`);\r\n            }\r\n\r\n            types[i] = description.textureType;\r\n            formats[i] = description.textureFormat;\r\n            labels[i] = MaterialHelperGeometryRendering.GeometryTextureDescriptions[index].name;\r\n            useSRGBBuffers[i] = false;\r\n        }\r\n\r\n        const handles: FrameGraphTextureHandle[] = [];\r\n\r\n        if (this.targetTexture !== undefined) {\r\n            if (Array.isArray(this.targetTexture)) {\r\n                handles.push(...this.targetTexture);\r\n            } else {\r\n                handles.push(this.targetTexture);\r\n            }\r\n        }\r\n\r\n        if (this.textureDescriptions.length > 0) {\r\n            const baseHandle = this._frameGraph.textureManager.createRenderTargetTexture(this.name, {\r\n                size: this.size,\r\n                sizeIsPercentage: this.sizeIsPercentage,\r\n                options: {\r\n                    createMipMaps: false,\r\n                    samples: this.samples,\r\n                    types,\r\n                    formats,\r\n                    useSRGBBuffers,\r\n                    labels,\r\n                },\r\n            });\r\n\r\n            for (let i = 0; i < this.textureDescriptions.length; i++) {\r\n                handles.push(baseHandle + i);\r\n            }\r\n        }\r\n\r\n        return handles;\r\n    }\r\n\r\n    protected override _prepareRendering(context: FrameGraphRenderContext, depthEnabled: boolean) {\r\n        context.setDepthStates(this.depthTest && depthEnabled, this.depthWrite && depthEnabled);\r\n\r\n        context.pushDebugGroup(`Clear attachments`);\r\n\r\n        this._clearAttachmentsLayout.forEach((layout, clearType) => {\r\n            context.clearColorAttachments(ClearColors[clearType], layout);\r\n        });\r\n\r\n        context.restoreDefaultFramebuffer();\r\n        context.popDebugGroup();\r\n\r\n        return this._colorAttachmentsLayout;\r\n    }\r\n\r\n    private _getTargetTextureCount(): number {\r\n        return this.targetTexture === undefined ? 0 : Array.isArray(this.targetTexture) ? this.targetTexture.length : 1;\r\n    }\r\n\r\n    private _buildClearAttachmentsLayout() {\r\n        const clearAttachmentsLayout = new Map<GeometryRenderingTextureClearType, boolean[]>();\r\n        const targetTextureCount = this._getTargetTextureCount();\r\n        const allAttachmentsLayout: boolean[] = new Array(targetTextureCount).fill(true);\r\n\r\n        for (let i = 0; i < this.textureDescriptions.length; i++) {\r\n            const description = this.textureDescriptions[i];\r\n            const index = MaterialHelperGeometryRendering.GeometryTextureDescriptions.findIndex((f) => f.type === description.type);\r\n            const geometryDescription = MaterialHelperGeometryRendering.GeometryTextureDescriptions[index];\r\n\r\n            const clearType =\r\n                geometryDescription.type === Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE && this._engine.useReverseDepthBuffer\r\n                    ? GeometryRenderingTextureClearType.Zero\r\n                    : geometryDescription.clearType;\r\n            let layout = clearAttachmentsLayout.get(clearType);\r\n            if (layout === undefined) {\r\n                layout = [];\r\n                clearAttachmentsLayout.set(clearType, layout);\r\n                for (let j = 0; j < targetTextureCount + i; j++) {\r\n                    layout[j] = false;\r\n                }\r\n            }\r\n\r\n            clearAttachmentsLayout.forEach((layout, layoutClearType) => {\r\n                layout.push(layoutClearType === clearType);\r\n            });\r\n\r\n            allAttachmentsLayout.push(true);\r\n        }\r\n\r\n        this._clearAttachmentsLayout = new Map();\r\n\r\n        clearAttachmentsLayout.forEach((layout, clearType) => {\r\n            this._clearAttachmentsLayout.set(clearType, this._engine.buildTextureLayout(layout));\r\n        });\r\n\r\n        this._allAttachmentsLayout = this._engine.buildTextureLayout(allAttachmentsLayout);\r\n        this._colorAttachmentsLayout = this._engine.buildTextureLayout(allAttachmentsLayout.map((_, index) => targetTextureCount > 0 && index === 0));\r\n    }\r\n\r\n    private _registerForRenderPassId(renderPassId: number) {\r\n        const configuration = MaterialHelperGeometryRendering.CreateConfiguration(renderPassId);\r\n        const targetTextureCount = this._getTargetTextureCount();\r\n\r\n        for (let i = 0; i < this.textureDescriptions.length; i++) {\r\n            const description = this.textureDescriptions[i];\r\n            const index = MaterialHelperGeometryRendering.GeometryTextureDescriptions.findIndex((f) => f.type === description.type);\r\n            const geometryDescription = MaterialHelperGeometryRendering.GeometryTextureDescriptions[index];\r\n\r\n            configuration.defines[geometryDescription.defineIndex] = targetTextureCount + i;\r\n            if (description.type === Constants.PREPASS_OBJECT_ID_TEXTURE_TYPE) {\r\n                configuration.objectIdIsRedFormat = description.textureFormat === Constants.TEXTUREFORMAT_RED;\r\n            } else if (description.type === Constants.PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE) {\r\n                configuration.meshBlendTagProvider = this.meshBlendTagProvider;\r\n            }\r\n        }\r\n\r\n        if (targetTextureCount > 0) {\r\n            configuration.defines[\"PREPASS_COLOR_INDEX\"] = 0;\r\n        }\r\n\r\n        configuration.reverseCulling = this.reverseCulling;\r\n        configuration.objectIdProvider = this.objectIdProvider;\r\n        MaterialHelperGeometryRendering._PrepareConfiguration(renderPassId, this._allAttachmentsLayout, this._colorAttachmentsLayout);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type NodeRenderGraphBuildState, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBaseObjectRendererBlock } from \"./baseObjectRendererBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { FrameGraphGeometryRendererTask } from \"../../../Tasks/Rendering/geometryRendererTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that render geometry of objects to a multi render target\r\n */\r\nexport class NodeRenderGraphGeometryRendererBlock extends NodeRenderGraphBaseObjectRendererBlock {\r\n    protected override _frameGraphTask: FrameGraphGeometryRendererTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphGeometryRendererBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param doNotChangeAspectRatio True (default) to not change the aspect ratio of the scene in the RTT\r\n     * @param enableClusteredLights True (default) to enable clustered lights\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, doNotChangeAspectRatio = true, enableClusteredLights = true) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.getInputByName(\"target\")!.isOptional = true;\r\n\r\n        this.registerOutput(\"geomIrradiance\", NodeRenderGraphBlockConnectionPointTypes.TextureIrradiance);\r\n        this.registerOutput(\"geomViewDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureViewDepth);\r\n        this.registerOutput(\"geomNormViewDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureNormalizedViewDepth);\r\n        this.registerOutput(\"geomScreenDepth\", NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth);\r\n        this.registerOutput(\"geomViewNormal\", NodeRenderGraphBlockConnectionPointTypes.TextureViewNormal);\r\n        this.registerOutput(\"geomWorldNormal\", NodeRenderGraphBlockConnectionPointTypes.TextureWorldNormal);\r\n        this.registerOutput(\"geomLocalPosition\", NodeRenderGraphBlockConnectionPointTypes.TextureLocalPosition);\r\n        this.registerOutput(\"geomWorldPosition\", NodeRenderGraphBlockConnectionPointTypes.TextureWorldPosition);\r\n        this.registerOutput(\"geomAlbedo\", NodeRenderGraphBlockConnectionPointTypes.TextureAlbedo);\r\n        this.registerOutput(\"geomReflectivity\", NodeRenderGraphBlockConnectionPointTypes.TextureReflectivity);\r\n        this.registerOutput(\"geomVelocity\", NodeRenderGraphBlockConnectionPointTypes.TextureVelocity);\r\n        this.registerOutput(\"geomLinearVelocity\", NodeRenderGraphBlockConnectionPointTypes.TextureLinearVelocity);\r\n        this.registerOutput(\"geomObjectId\", NodeRenderGraphBlockConnectionPointTypes.TextureObjectId);\r\n        this.registerOutput(\"geomMeshBlendTag\", NodeRenderGraphBlockConnectionPointTypes.TextureMeshBlendTag);\r\n\r\n        this._frameGraphTask = new FrameGraphGeometryRendererTask(this.name, frameGraph, scene, { doNotChangeAspectRatio, enableClusteredLights });\r\n    }\r\n\r\n    protected override _createFrameGraphObject(): void {\r\n        this._frameGraphTask?.dispose();\r\n        this._frameGraphTask = new FrameGraphGeometryRendererTask(this.name, this._frameGraph, this._scene, {\r\n            doNotChangeAspectRatio: this._additionalConstructionParameters![0] as boolean,\r\n            enableClusteredLights: this._additionalConstructionParameters![1] as boolean,\r\n        });\r\n    }\r\n\r\n    protected override _saveState(state: { [key: string]: any }) {\r\n        super._saveState(state);\r\n        state.disabled = this._frameGraphTask.disabled;\r\n        state.isMainObjectRenderer = this.isMainObjectRenderer;\r\n        state.depthTest = this.depthTest;\r\n        state.depthWrite = this.depthWrite;\r\n        state.disableShadows = this.disableShadows;\r\n        state.renderInLinearSpace = this.renderInLinearSpace;\r\n        state.renderParticles = this.renderParticles;\r\n        state.renderSprites = this.renderSprites;\r\n        state.forceLayerMaskCheck = this.forceLayerMaskCheck;\r\n        state.enableBoundingBoxRendering = this.enableBoundingBoxRendering;\r\n        state.enableOutlineRendering = this.enableOutlineRendering;\r\n\r\n        state.width = this.width;\r\n        state.height = this.height;\r\n        state.sizeInPercentage = this.sizeInPercentage;\r\n        state.samples = this.samples;\r\n        state.reverseCulling = this.reverseCulling;\r\n        state.dontRenderWhenMaterialDepthWriteIsDisabled = this.dontRenderWhenMaterialDepthWriteIsDisabled;\r\n        state.disableDepthPrePass = this.disableDepthPrePass;\r\n    }\r\n\r\n    protected override _restoreState(state: { [key: string]: any }) {\r\n        super._restoreState(state);\r\n        this._frameGraphTask.disabled = state.disabled;\r\n        this.isMainObjectRenderer = state.isMainObjectRenderer;\r\n        this.depthTest = state.depthTest;\r\n        this.depthWrite = state.depthWrite;\r\n        this.disableShadows = state.disableShadows;\r\n        this.renderInLinearSpace = state.renderInLinearSpace;\r\n        this.renderParticles = state.renderParticles;\r\n        this.renderSprites = state.renderSprites;\r\n        this.forceLayerMaskCheck = state.forceLayerMaskCheck;\r\n        this.enableBoundingBoxRendering = state.enableBoundingBoxRendering;\r\n        this.enableOutlineRendering = state.enableOutlineRendering;\r\n\r\n        this.width = state.width;\r\n        this.height = state.height;\r\n        this.sizeInPercentage = state.sizeInPercentage;\r\n        this.samples = state.samples;\r\n        this.reverseCulling = state.reverseCulling;\r\n        this.dontRenderWhenMaterialDepthWriteIsDisabled = state.dontRenderWhenMaterialDepthWriteIsDisabled;\r\n        this.disableDepthPrePass = state.disableDepthPrePass;\r\n    }\r\n\r\n    /** Width of the geometry texture */\r\n    @editableInPropertyPage(\"Texture width\", PropertyTypeForEdition.Int, \"GEOMETRY\")\r\n    public get width() {\r\n        return this._frameGraphTask.size.width;\r\n    }\r\n\r\n    public set width(value: number) {\r\n        this._frameGraphTask.size.width = value;\r\n    }\r\n\r\n    /** Height of the geometry texture */\r\n    @editableInPropertyPage(\"Texture height\", PropertyTypeForEdition.Int, \"GEOMETRY\")\r\n    public get height() {\r\n        return this._frameGraphTask.size.height;\r\n    }\r\n\r\n    public set height(value: number) {\r\n        this._frameGraphTask.size.height = value;\r\n    }\r\n\r\n    /** Indicates if the geometry texture width and height are percentages or absolute values */\r\n    @editableInPropertyPage(\"Size is in percentage\", PropertyTypeForEdition.Boolean, \"GEOMETRY\")\r\n    public get sizeInPercentage() {\r\n        return this._frameGraphTask.sizeIsPercentage;\r\n    }\r\n\r\n    public set sizeInPercentage(value: boolean) {\r\n        this._frameGraphTask.sizeIsPercentage = value;\r\n    }\r\n\r\n    /** Number of samples of the geometry texture */\r\n    @editableInPropertyPage(\"Samples\", PropertyTypeForEdition.Int, \"GEOMETRY\", { min: 1, max: 8 })\r\n    public get samples() {\r\n        return this._frameGraphTask.samples;\r\n    }\r\n\r\n    public set samples(value: number) {\r\n        this._frameGraphTask.samples = value;\r\n    }\r\n\r\n    /** Indicates if culling must be reversed */\r\n    @editableInPropertyPage(\"Reverse culling\", PropertyTypeForEdition.Boolean, \"GEOMETRY\")\r\n    public get reverseCulling() {\r\n        return this._frameGraphTask.reverseCulling;\r\n    }\r\n\r\n    public set reverseCulling(value: boolean) {\r\n        this._frameGraphTask.reverseCulling = value;\r\n    }\r\n\r\n    /** Indicates if a mesh shouldn't be rendered when its material has depth write disabled */\r\n    @editableInPropertyPage(\"Don't render if material depth write is disabled\", PropertyTypeForEdition.Boolean, \"GEOMETRY\")\r\n    public get dontRenderWhenMaterialDepthWriteIsDisabled() {\r\n        return this._frameGraphTask.dontRenderWhenMaterialDepthWriteIsDisabled;\r\n    }\r\n\r\n    public set dontRenderWhenMaterialDepthWriteIsDisabled(value: boolean) {\r\n        this._frameGraphTask.dontRenderWhenMaterialDepthWriteIsDisabled = value;\r\n    }\r\n\r\n    /** Indicates if depth pre-pass must be disabled */\r\n    @editableInPropertyPage(\"Disable depth pre-pass\", PropertyTypeForEdition.Boolean, \"GEOMETRY\")\r\n    public get disableDepthPrePass() {\r\n        return this._frameGraphTask.disableDepthPrePass;\r\n    }\r\n\r\n    public set disableDepthPrePass(value: boolean) {\r\n        this._frameGraphTask.disableDepthPrePass = value;\r\n    }\r\n\r\n    // Irradiance\r\n    /** The format of the irradiance output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - IRRADIANCE\")\r\n    public irradianceFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the irradiance output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - IRRADIANCE\")\r\n    public irradianceType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n    // View depth\r\n    /** The format of the view depth output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - VIEW DEPTH\")\r\n    public viewDepthFormat = Constants.TEXTUREFORMAT_RED;\r\n\r\n    /** The type of the view depth output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - VIEW DEPTH\")\r\n    public viewDepthType = Constants.TEXTURETYPE_FLOAT;\r\n\r\n    // Normalized view depth\r\n    /** The format of the normalized view depth output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - NORMALIZED VIEW DEPTH\")\r\n    public normalizedViewDepthFormat = Constants.TEXTUREFORMAT_RED;\r\n\r\n    /** The type of the normalized view depth output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - NORMALIZED VIEW DEPTH\")\r\n    public normalizedViewDepthType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n    // Screen depth\r\n    /** The format of the screen depth output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - SCREEN DEPTH\")\r\n    public screenDepthFormat = Constants.TEXTUREFORMAT_RED;\r\n\r\n    /** The type of the screen depth output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - SCREEN DEPTH\")\r\n    public screenDepthType = Constants.TEXTURETYPE_FLOAT;\r\n\r\n    // View normal\r\n    /** The format of the view normal output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - VIEW NORMAL\")\r\n    public viewNormalFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the view normal output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - VIEW NORMAL\")\r\n    public viewNormalType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n    // World normal\r\n    /** The format of the world normal output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - WORLD NORMAL\")\r\n    public worldNormalFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the world normal output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - WORLD NORMAL\")\r\n    public worldNormalType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n    // Local position\r\n    /** The format of the local position output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - LOCAL POSITION\")\r\n    public localPositionFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the local position output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - LOCAL POSITION\")\r\n    public localPositionType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n    // World Position\r\n    /** The format of the world position output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - WORLD POSITION\")\r\n    public worldPositionFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the world position output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - WORLD POSITION\")\r\n    public worldPositionType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n    // Albedo\r\n    /** The format of the albedo output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - ALBEDO\")\r\n    public albedoFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the albedo output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - ALBEDO\")\r\n    public albedoType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n    // Reflectivity\r\n    /** The format of the reflectivity output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - REFLECTIVITY\")\r\n    public reflectivityFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the reflectivity output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - REFLECTIVITY\")\r\n    public reflectivityType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n    // Velocity\r\n    /** The format of the velocity output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - VELOCITY\")\r\n    public velocityFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the velocity output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - VELOCITY\")\r\n    public velocityType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n    // Linear velocity\r\n    /** The format of the linear velocity output texture */\r\n    @editableInPropertyPage(\"Format\", PropertyTypeForEdition.TextureFormat, \"OUTPUT - LINEAR VELOCITY\")\r\n    public linearVelocityFormat = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n    /** The type of the linear velocity output texture */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.TextureType, \"OUTPUT - LINEAR VELOCITY\")\r\n    public linearVelocityType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphGeometryRendererBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry irradiance component\r\n     */\r\n    public get geomIrradiance(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry view depth component\r\n     */\r\n    public get geomViewDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry normalized view depth component\r\n     */\r\n    public get geomNormViewDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry screen depth component\r\n     */\r\n    public get geomScreenDepth(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry view normal component\r\n     */\r\n    public get geomViewNormal(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the world geometry normal component, encoded from [-1, 1] to [0, 1]\r\n     */\r\n    public get geomWorldNormal(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[8];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry local position component\r\n     */\r\n    public get geomLocalPosition(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[9];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry world position component\r\n     */\r\n    public get geomWorldPosition(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[10];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry albedo component\r\n     */\r\n    public get geomAlbedo(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[11];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry reflectivity component\r\n     */\r\n    public get geomReflectivity(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[12];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry velocity component\r\n     */\r\n    public get geomVelocity(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[13];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry linear velocity component\r\n     */\r\n    public get geomLinearVelocity(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[14];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry object ID component\r\n     */\r\n    public get geomObjectId(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[15];\r\n    }\r\n\r\n    /**\r\n     * Gets the packed mesh-blending tag component.\r\n     */\r\n    public get geomMeshBlendTag(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[16];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const textureActivation = [\r\n            this.geomIrradiance.isConnected,\r\n            this.geomViewDepth.isConnected,\r\n            this.geomNormViewDepth.isConnected,\r\n            this.geomScreenDepth.isConnected,\r\n            this.geomViewNormal.isConnected,\r\n            this.geomWorldNormal.isConnected,\r\n            this.geomLocalPosition.isConnected,\r\n            this.geomWorldPosition.isConnected,\r\n            this.geomAlbedo.isConnected,\r\n            this.geomReflectivity.isConnected,\r\n            this.geomVelocity.isConnected,\r\n            this.geomLinearVelocity.isConnected,\r\n            this.geomObjectId.isConnected,\r\n            this.geomMeshBlendTag.isConnected,\r\n        ];\r\n\r\n        this.geomIrradiance.value = this._frameGraphTask.geometryIrradianceTexture;\r\n        this.geomViewDepth.value = this._frameGraphTask.geometryViewDepthTexture;\r\n        this.geomNormViewDepth.value = this._frameGraphTask.geometryNormViewDepthTexture;\r\n        this.geomScreenDepth.value = this._frameGraphTask.geometryScreenDepthTexture;\r\n        this.geomViewNormal.value = this._frameGraphTask.geometryViewNormalTexture;\r\n        this.geomWorldNormal.value = this._frameGraphTask.geometryWorldNormalTexture;\r\n        this.geomLocalPosition.value = this._frameGraphTask.geometryLocalPositionTexture;\r\n        this.geomWorldPosition.value = this._frameGraphTask.geometryWorldPositionTexture;\r\n        this.geomAlbedo.value = this._frameGraphTask.geometryAlbedoTexture;\r\n        this.geomReflectivity.value = this._frameGraphTask.geometryReflectivityTexture;\r\n        this.geomVelocity.value = this._frameGraphTask.geometryVelocityTexture;\r\n        this.geomLinearVelocity.value = this._frameGraphTask.geometryLinearVelocityTexture;\r\n        this.geomObjectId.value = this._frameGraphTask.geometryObjectIdTexture;\r\n        this.geomMeshBlendTag.value = this._frameGraphTask.geometryMeshBlendTagTexture;\r\n\r\n        this._frameGraphTask.textureDescriptions = [];\r\n\r\n        const textureFormats = [\r\n            this.irradianceFormat,\r\n            this.viewDepthFormat,\r\n            this.normalizedViewDepthFormat,\r\n            this.screenDepthFormat,\r\n            this.viewNormalFormat,\r\n            this.worldNormalFormat,\r\n            this.localPositionFormat,\r\n            this.worldPositionFormat,\r\n            this.albedoFormat,\r\n            this.reflectivityFormat,\r\n            this.velocityFormat,\r\n            this.linearVelocityFormat,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            Constants.TEXTUREFORMAT_RED_INTEGER,\r\n        ];\r\n        const textureTypes = [\r\n            this.irradianceType,\r\n            this.viewDepthType,\r\n            this.normalizedViewDepthType,\r\n            this.screenDepthType,\r\n            this.viewNormalType,\r\n            this.worldNormalType,\r\n            this.localPositionType,\r\n            this.worldPositionType,\r\n            this.albedoType,\r\n            this.reflectivityType,\r\n            this.velocityType,\r\n            this.linearVelocityType,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        ];\r\n        const bufferTypes = [\r\n            Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE,\r\n            Constants.PREPASS_DEPTH_TEXTURE_TYPE,\r\n            Constants.PREPASS_NORMALIZED_VIEW_DEPTH_TEXTURE_TYPE,\r\n            Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE,\r\n            Constants.PREPASS_NORMAL_TEXTURE_TYPE,\r\n            Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE,\r\n            Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE,\r\n            Constants.PREPASS_POSITION_TEXTURE_TYPE,\r\n            Constants.PREPASS_ALBEDO_TEXTURE_TYPE,\r\n            Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,\r\n            Constants.PREPASS_VELOCITY_TEXTURE_TYPE,\r\n            Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE,\r\n            Constants.PREPASS_OBJECT_ID_TEXTURE_TYPE,\r\n            Constants.PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE,\r\n        ];\r\n\r\n        for (let i = 0; i < textureActivation.length; i++) {\r\n            if (textureActivation[i]) {\r\n                this._frameGraphTask.textureDescriptions.push({\r\n                    textureFormat: textureFormats[i],\r\n                    textureType: textureTypes[i],\r\n                    type: bufferTypes[i],\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.size = { width: ${this.width}, height: ${this.height} };`);\r\n        codes.push(`${this._codeVariableName}.sizeInPercentage = ${this.sizeInPercentage};`);\r\n        codes.push(`${this._codeVariableName}.samples = ${this.samples};`);\r\n        codes.push(`${this._codeVariableName}.reverseCulling = ${this.reverseCulling};`);\r\n        codes.push(`${this._codeVariableName}.dontRenderWhenMaterialDepthWriteIsDisabled = ${this.dontRenderWhenMaterialDepthWriteIsDisabled};`);\r\n        codes.push(`${this._codeVariableName}.disableDepthPrePass = ${this.disableDepthPrePass};`);\r\n        codes.push(`${this._codeVariableName}.irradianceFormat = ${this.irradianceFormat};`);\r\n        codes.push(`${this._codeVariableName}.irradianceType = ${this.irradianceType};`);\r\n        codes.push(`${this._codeVariableName}.viewDepthFormat = ${this.viewDepthFormat};`);\r\n        codes.push(`${this._codeVariableName}.viewDepthType = ${this.viewDepthType};`);\r\n        codes.push(`${this._codeVariableName}.normalizedViewDepthFormat = ${this.normalizedViewDepthFormat};`);\r\n        codes.push(`${this._codeVariableName}.normalizedViewDepthType = ${this.normalizedViewDepthType};`);\r\n        codes.push(`${this._codeVariableName}.screenDepthFormat = ${this.screenDepthFormat};`);\r\n        codes.push(`${this._codeVariableName}.screenDepthType = ${this.screenDepthType};`);\r\n        codes.push(`${this._codeVariableName}.localPositionFormat = ${this.localPositionFormat};`);\r\n        codes.push(`${this._codeVariableName}.localPositionType = ${this.localPositionType};`);\r\n        codes.push(`${this._codeVariableName}.worldPositionFormat = ${this.worldPositionFormat};`);\r\n        codes.push(`${this._codeVariableName}.worldPositionType = ${this.worldPositionType};`);\r\n        codes.push(`${this._codeVariableName}.viewNormalFormat = ${this.viewNormalFormat};`);\r\n        codes.push(`${this._codeVariableName}.viewNormalType = ${this.viewNormalType};`);\r\n        codes.push(`${this._codeVariableName}.worldNormalFormat = ${this.worldNormalFormat};`);\r\n        codes.push(`${this._codeVariableName}.worldNormalType = ${this.worldNormalType};`);\r\n        codes.push(`${this._codeVariableName}.albedoFormat = ${this.albedoFormat};`);\r\n        codes.push(`${this._codeVariableName}.albedoType = ${this.albedoType};`);\r\n        codes.push(`${this._codeVariableName}.reflectivityFormat = ${this.reflectivityFormat};`);\r\n        codes.push(`${this._codeVariableName}.reflectivityType = ${this.reflectivityType};`);\r\n        codes.push(`${this._codeVariableName}.velocityFormat = ${this.velocityFormat};`);\r\n        codes.push(`${this._codeVariableName}.velocityType = ${this.velocityType};`);\r\n        codes.push(`${this._codeVariableName}.linearVelocityFormat = ${this.linearVelocityFormat};`);\r\n        codes.push(`${this._codeVariableName}.linearVelocityType = ${this.linearVelocityType};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.sizeInPercentage = this.sizeInPercentage;\r\n        serializationObject.width = this.width;\r\n        serializationObject.height = this.height;\r\n        serializationObject.samples = this.samples;\r\n        serializationObject.reverseCulling = this.reverseCulling;\r\n        serializationObject.dontRenderWhenMaterialDepthWriteIsDisabled = this.dontRenderWhenMaterialDepthWriteIsDisabled;\r\n        serializationObject.disableDepthPrePass = this.disableDepthPrePass;\r\n        serializationObject.irradianceFormat = this.irradianceFormat;\r\n        serializationObject.irradianceType = this.irradianceType;\r\n        serializationObject.viewDepthFormat = this.viewDepthFormat;\r\n        serializationObject.viewDepthType = this.viewDepthType;\r\n        serializationObject.normalizedViewDepthFormat = this.normalizedViewDepthFormat;\r\n        serializationObject.normalizedViewDepthType = this.normalizedViewDepthType;\r\n        serializationObject.screenDepthFormat = this.screenDepthFormat;\r\n        serializationObject.screenDepthType = this.screenDepthType;\r\n        serializationObject.localPositionFormat = this.localPositionFormat;\r\n        serializationObject.localPositionType = this.localPositionType;\r\n        serializationObject.worldPositionFormat = this.worldPositionFormat;\r\n        serializationObject.worldPositionType = this.worldPositionType;\r\n        serializationObject.viewNormalFormat = this.viewNormalFormat;\r\n        serializationObject.viewNormalType = this.viewNormalType;\r\n        serializationObject.worldNormalFormat = this.worldNormalFormat;\r\n        serializationObject.worldNormalType = this.worldNormalType;\r\n        serializationObject.albedoFormat = this.albedoFormat;\r\n        serializationObject.albedoType = this.albedoType;\r\n        serializationObject.reflectivityFormat = this.reflectivityFormat;\r\n        serializationObject.reflectivityType = this.reflectivityType;\r\n        serializationObject.velocityFormat = this.velocityFormat;\r\n        serializationObject.velocityType = this.velocityType;\r\n        serializationObject.linearVelocityFormat = this.linearVelocityFormat;\r\n        serializationObject.linearVelocityType = this.linearVelocityType;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.sizeInPercentage = !!serializationObject.sizeInPercentage;\r\n        this.width = serializationObject.width ?? 100;\r\n        this.height = serializationObject.height ?? 100;\r\n        this.samples = serializationObject.samples;\r\n        this.reverseCulling = serializationObject.reverseCulling;\r\n        this.dontRenderWhenMaterialDepthWriteIsDisabled = serializationObject.dontRenderWhenMaterialDepthWriteIsDisabled;\r\n        this.disableDepthPrePass = serializationObject.disableDepthPrePass ?? true;\r\n        this.irradianceFormat = serializationObject.irradianceFormat ?? Constants.TEXTUREFORMAT_RGBA;\r\n        this.irradianceType = serializationObject.irradianceType ?? Constants.TEXTURETYPE_HALF_FLOAT;\r\n        this.viewDepthFormat = serializationObject.viewDepthFormat;\r\n        this.viewDepthType = serializationObject.viewDepthType;\r\n        this.normalizedViewDepthFormat = serializationObject.normalizedViewDepthFormat ?? Constants.TEXTUREFORMAT_RED;\r\n        this.normalizedViewDepthType = serializationObject.normalizedViewDepthType ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        this.screenDepthFormat = serializationObject.screenDepthFormat;\r\n        this.screenDepthType = serializationObject.screenDepthType;\r\n        this.localPositionFormat = serializationObject.localPositionFormat;\r\n        this.localPositionType = serializationObject.localPositionType;\r\n        this.worldPositionFormat = serializationObject.worldPositionFormat;\r\n        this.worldPositionType = serializationObject.worldPositionType;\r\n        this.viewNormalFormat = serializationObject.viewNormalFormat;\r\n        this.viewNormalType = serializationObject.viewNormalType;\r\n        this.worldNormalFormat = serializationObject.worldNormalFormat;\r\n        this.worldNormalType = serializationObject.worldNormalType;\r\n        this.albedoFormat = serializationObject.albedoFormat;\r\n        this.albedoType = serializationObject.albedoType;\r\n        this.reflectivityFormat = serializationObject.reflectivityFormat;\r\n        this.reflectivityType = serializationObject.reflectivityType;\r\n        this.velocityFormat = serializationObject.velocityFormat;\r\n        this.velocityType = serializationObject.velocityType;\r\n        this.linearVelocityFormat = serializationObject.linearVelocityFormat;\r\n        this.linearVelocityType = serializationObject.linearVelocityType;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryRendererBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryRendererBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphGeometryRendererBlock\", NodeRenderGraphGeometryRendererBlock);\r\n}\r\n","import { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { RGBDTextureTools } from \"./rgbdTextureTools\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst _environmentBRDFBase64Texture =\r\n    \"data:image/png;base64,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\";\r\n\r\n// Multiple-Scattering Sheen BRDF LUT from https://github.com/tizian/ltc-sheen\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst _environmentFuzzBRDFBase64Texture =\r\n    \"data:image/png;base64,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\";\r\n\r\n// OpenPBR BRDF LUT — three-channel height-correlated GGX with Hammersley importance sampling.\r\n// R = Schlick F90 scale integral  [same as standard LUT channel 0]\r\n// G = GGX directional albedo      [same as standard LUT channel 1]\r\n// B = F82 correction term integral, stored * BRDF_Z_SCALE (=16) for 8-bit range\r\n// See pbrBRDFFunctions.fx: BRDF_Z_SCALE\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst _openPBREnvironmentBRDFBase64Texture =\r\n    \"data:image/png;base64,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\";\r\n\r\nlet InstanceNumber = 0;\r\n\r\n/**\r\n * Internal function to load and setup BRDF textures\r\n * @param scene defines the hosting scene\r\n * @param textureData defines the base64 texture data\r\n * @param textureProperty defines the scene property name to store the texture\r\n * @param textureName defines the name for the texture\r\n * @returns the environment BRDF texture\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst loadBRDFTexture = (scene: Scene, textureData: string, textureProperty: string, textureName: string): BaseTexture => {\r\n    if (!(scene as any)[textureProperty]) {\r\n        // Forces Delayed Texture Loading to prevent undefined error whilst setting RGBD values.\r\n        const useDelayedTextureLoading = scene.useDelayedTextureLoading;\r\n        scene.useDelayedTextureLoading = false;\r\n\r\n        const previousState = scene._blockEntityCollection;\r\n        scene._blockEntityCollection = false;\r\n        const texture = Texture.CreateFromBase64String(textureData, textureName + InstanceNumber++, scene, true, false, Texture.BILINEAR_SAMPLINGMODE);\r\n        scene._blockEntityCollection = previousState;\r\n        // BRDF Texture should not be cached here due to pre processing and redundant scene caches.\r\n        const texturesCache = scene.getEngine().getLoadedTexturesCache();\r\n        const index = texturesCache.indexOf(texture.getInternalTexture()!);\r\n        if (index !== -1) {\r\n            texturesCache.splice(index, 1);\r\n        }\r\n\r\n        texture.isRGBD = true;\r\n        texture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        (scene as any)[textureProperty] = texture;\r\n\r\n        scene.useDelayedTextureLoading = useDelayedTextureLoading;\r\n\r\n        RGBDTextureTools.ExpandRGBDTexture(texture);\r\n\r\n        const observer = scene.getEngine().onContextRestoredObservable.add(() => {\r\n            texture.isRGBD = true;\r\n            /**\r\n             * Using scene.onBeforeRenderObservable instead of Tools.SetImmediate to check the texture's state of readiness allows us to check before any rendering occurs.\r\n             * When a context restore occurs, it gives ExpandRGBDTexture the ability to reset the state to false, preventing the texture from being used in any rendering.\r\n             * In WebGPU, not doing so would generate an error because ExpandRGBDTexture performs a _swapAndDie on the texture, which causes WebGPU caches to fail if the texture has already been used for rendering.\r\n             * Only when ExpandRGBDTexture has finished its work, the texture is ready to be used again.\r\n             */\r\n            const oo = scene.onBeforeRenderObservable.add(() => {\r\n                if (texture.isReady()) {\r\n                    scene.onBeforeRenderObservable.remove(oo);\r\n                    RGBDTextureTools.ExpandRGBDTexture(texture);\r\n                }\r\n            });\r\n        });\r\n\r\n        scene.onDisposeObservable.add(() => {\r\n            scene.getEngine().onContextRestoredObservable.remove(observer);\r\n        });\r\n    }\r\n\r\n    return (scene as any)[textureProperty];\r\n};\r\n\r\n/**\r\n * Gets a default environment BRDF for MS-BRDF Height Correlated BRDF\r\n * @param scene defines the hosting scene\r\n * @returns the environment BRDF texture\r\n */\r\nexport const GetEnvironmentBRDFTexture = (scene: Scene): BaseTexture => {\r\n    return loadBRDFTexture(scene, _environmentBRDFBase64Texture, \"environmentBRDFTexture\", \"EnvironmentBRDFTexture\");\r\n};\r\n\r\n/**\r\n * Gets a default environment fuzz BRDF texture\r\n * @param scene defines the hosting scene\r\n * @returns the environment fuzz BRDF texture\r\n */\r\nexport const GetEnvironmentFuzzBRDFTexture = (scene: Scene): BaseTexture => {\r\n    return loadBRDFTexture(scene, _environmentFuzzBRDFBase64Texture, \"environmentFuzzBRDFTexture\", \"EnvironmentFuzzBRDFTexture\");\r\n};\r\n\r\n/**\r\n * Gets the OpenPBR environment BRDF texture (3-channel F82 LUT)\r\n * @param scene defines the hosting scene\r\n * @returns the OpenPBR environment BRDF texture\r\n */\r\nexport const GetOpenPBREnvironmentBRDFTexture = (scene: Scene): BaseTexture => {\r\n    return loadBRDFTexture(scene, _openPBREnvironmentBRDFBase64Texture, \"openPBREnvironmentBRDFTexture\", \"OpenPBREnvironmentBRDFTexture\");\r\n};\r\n\r\n/**\r\n * Class used to host texture specific utilities\r\n */\r\nexport const BRDFTextureTools = {\r\n    /**\r\n     * Gets a default environment BRDF for MS-BRDF Height Correlated BRDF\r\n     * @param scene defines the hosting scene\r\n     * @returns the environment BRDF texture\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    GetEnvironmentBRDFTexture,\r\n\r\n    /**\r\n     * Gets a default environment fuzz BRDF texture\r\n     * @param scene defines the hosting scene\r\n     * @returns the environment fuzz BRDF texture\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    GetEnvironmentFuzzBRDFTexture,\r\n\r\n    /**\r\n     * Gets the OpenPBR environment BRDF texture (3-channel F82 LUT)\r\n     * @param scene defines the hosting scene\r\n     * @returns the OpenPBR environment BRDF texture\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    GetOpenPBREnvironmentBRDFTexture,\r\n};\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { serialize, expandToProperty } from \"../../Misc/decorators\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { type PBRBaseMaterial } from \"./pbrBaseMaterial\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialBRDFDefines extends MaterialDefines {\r\n    BRDF_V_HEIGHT_CORRELATED = false;\r\n    MS_BRDF_ENERGY_CONSERVATION = false;\r\n    SPHERICAL_HARMONICS = false;\r\n    SPECULAR_GLOSSINESS_ENERGY_CONSERVATION = false;\r\n    MIX_IBL_RADIANCE_WITH_IRRADIANCE = true;\r\n    LEGACY_SPECULAR_ENERGY_CONSERVATION = false;\r\n    BASE_DIFFUSE_MODEL = 0;\r\n    DIELECTRIC_SPECULAR_MODEL = 0;\r\n    CONDUCTOR_SPECULAR_MODEL = 0;\r\n}\r\n\r\n/**\r\n * Plugin that implements the BRDF component of the PBR material\r\n */\r\nexport class PBRBRDFConfiguration extends MaterialPluginBase {\r\n    /**\r\n     * Default value used for the energy conservation.\r\n     * This should only be changed to adapt to the type of texture in scene.environmentBRDFTexture.\r\n     */\r\n    public static DEFAULT_USE_ENERGY_CONSERVATION = true;\r\n\r\n    /**\r\n     * Default value used for the Smith Visibility Height Correlated mode.\r\n     * This should only be changed to adapt to the type of texture in scene.environmentBRDFTexture.\r\n     */\r\n    public static DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED = true;\r\n\r\n    /**\r\n     * Default value used for the IBL diffuse part.\r\n     * This can help switching back to the polynomials mode globally which is a tiny bit\r\n     * less GPU intensive at the drawback of a lower quality.\r\n     */\r\n    public static DEFAULT_USE_SPHERICAL_HARMONICS = true;\r\n\r\n    /**\r\n     * Default value used for activating energy conservation for the specular workflow.\r\n     * If activated, the albedo color is multiplied with (1. - maxChannel(specular color)).\r\n     * If deactivated, a material is only physically plausible, when (albedo color + specular color) < 1.\r\n     */\r\n    public static DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION = true;\r\n\r\n    /**\r\n     * Default value for whether IBL irradiance is used to augment rough radiance.\r\n     * If activated, irradiance is blended into the radiance contribution when the material is rough.\r\n     * This better approximates raytracing results for rough surfaces.\r\n     */\r\n    public static DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE = true;\r\n\r\n    /**\r\n     * Default value for whether the legacy specular energy conservation is used.\r\n     */\r\n    public static DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION = true;\r\n\r\n    /**\r\n     * Defines the default diffuse model used by the material.\r\n     */\r\n    public static DEFAULT_DIFFUSE_MODEL = Constants.MATERIAL_DIFFUSE_MODEL_E_OREN_NAYAR;\r\n\r\n    /**\r\n     * Defines the default dielectric specular model used by the material.\r\n     */\r\n    public static DEFAULT_DIELECTRIC_SPECULAR_MODEL: number = Constants.MATERIAL_DIELECTRIC_SPECULAR_MODEL_GLTF;\r\n\r\n    /**\r\n     * Defines the default conductor specular model used by the material.\r\n     */\r\n    public static DEFAULT_CONDUCTOR_SPECULAR_MODEL: number = Constants.MATERIAL_CONDUCTOR_SPECULAR_MODEL_GLTF;\r\n\r\n    private _useEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION;\r\n    /**\r\n     * Defines if the material uses energy conservation.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor useEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION;\r\n\r\n    private _useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED;\r\n    /**\r\n     * LEGACY Mode set to false\r\n     * Defines if the material uses height smith correlated visibility term.\r\n     * If you intent to not use our default BRDF, you need to load a separate BRDF Texture for the PBR\r\n     * You can either load https://assets.babylonjs.com/environments/uncorrelatedBRDF.png\r\n     * or https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds to have more precision\r\n     * Not relying on height correlated will also disable energy conservation.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED;\r\n\r\n    private _useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS;\r\n    /**\r\n     * LEGACY Mode set to false\r\n     * Defines if the material uses spherical harmonics vs spherical polynomials for the\r\n     * diffuse part of the IBL.\r\n     * The harmonics despite a tiny bigger cost has been proven to provide closer results\r\n     * to the ground truth.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS;\r\n\r\n    private _useSpecularGlossinessInputEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION;\r\n    /**\r\n     * Defines if the material uses energy conservation, when the specular workflow is active.\r\n     * If activated, the albedo color is multiplied with (1. - maxChannel(specular color)).\r\n     * If deactivated, a material is only physically plausible, when (albedo color + specular color) < 1.\r\n     * In the deactivated case, the material author has to ensure energy conservation, for a physically plausible rendering.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor useSpecularGlossinessInputEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION;\r\n\r\n    private _mixIblRadianceWithIrradiance = PBRBRDFConfiguration.DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE;\r\n    /**\r\n     * Defines if IBL irradiance is used to augment rough radiance.\r\n     * If activated, irradiance is blended into the radiance contribution when the material is rough.\r\n     * This better approximates raytracing results for rough surfaces.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor mixIblRadianceWithIrradiance = PBRBRDFConfiguration.DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE;\r\n\r\n    private _useLegacySpecularEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION;\r\n    /**\r\n     * Defines if the legacy specular energy conservation is used.\r\n     * If activated, the specular color is multiplied with (1. - maxChannel(albedo color)).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor useLegacySpecularEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION;\r\n\r\n    private _baseDiffuseModel: number = PBRBRDFConfiguration.DEFAULT_DIFFUSE_MODEL;\r\n    /**\r\n     * Defines the base diffuse roughness model of the material.\r\n     */\r\n    @serialize(\"baseDiffuseModel\")\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor baseDiffuseModel: number = PBRBRDFConfiguration.DEFAULT_DIFFUSE_MODEL;\r\n\r\n    private _dielectricSpecularModel: number = PBRBRDFConfiguration.DEFAULT_DIELECTRIC_SPECULAR_MODEL;\r\n    /**\r\n     * The material model to use for specular lighting of dielectric materials.\r\n     */\r\n    @serialize(\"dielectricSpecularModel\")\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor dielectricSpecularModel: number = PBRBRDFConfiguration.DEFAULT_DIELECTRIC_SPECULAR_MODEL;\r\n\r\n    private _conductorSpecularModel: number = PBRBRDFConfiguration.DEFAULT_CONDUCTOR_SPECULAR_MODEL;\r\n    /**\r\n     * The material model to use for specular lighting.\r\n     */\r\n    @serialize(\"conductorSpecularModel\")\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor conductorSpecularModel: number = PBRBRDFConfiguration.DEFAULT_CONDUCTOR_SPECULAR_MODEL;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsMiscDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsMiscDirty(): void {\r\n        this._internalMarkAllSubMeshesAsMiscDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial, addToPluginList = true) {\r\n        super(material, \"PBRBRDF\", 90, new MaterialBRDFDefines(), addToPluginList);\r\n\r\n        this._internalMarkAllSubMeshesAsMiscDirty = material._dirtyCallbacks[Constants.MATERIAL_MiscDirtyFlag];\r\n        this._enable(true);\r\n    }\r\n\r\n    /**\r\n     * Updates the material defines for BRDF settings.\r\n     * @param defines defines the material defines to update\r\n     */\r\n    public override prepareDefines(defines: MaterialBRDFDefines): void {\r\n        defines.BRDF_V_HEIGHT_CORRELATED = this._useSmithVisibilityHeightCorrelated;\r\n        defines.MS_BRDF_ENERGY_CONSERVATION = this._useEnergyConservation && this._useSmithVisibilityHeightCorrelated;\r\n        defines.SPHERICAL_HARMONICS = this._useSphericalHarmonics;\r\n        defines.SPECULAR_GLOSSINESS_ENERGY_CONSERVATION = this._useSpecularGlossinessInputEnergyConservation;\r\n        defines.MIX_IBL_RADIANCE_WITH_IRRADIANCE = this._mixIblRadianceWithIrradiance && !(this._material as PBRBaseMaterial)._disableLighting;\r\n        defines.LEGACY_SPECULAR_ENERGY_CONSERVATION = this._useLegacySpecularEnergyConservation;\r\n        defines.BASE_DIFFUSE_MODEL = this._baseDiffuseModel;\r\n        defines.DIELECTRIC_SPECULAR_MODEL = this._dielectricSpecularModel;\r\n        defines.CONDUCTOR_SPECULAR_MODEL = this._conductorSpecularModel;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRBRDFConfiguration\";\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../../types\";\r\nimport { serialize, serializeAsTexture, expandToProperty, serializeAsColor3 } from \"../../Misc/decorators\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { MaterialFlags } from \"../materialFlags\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { type EffectFallbacks } from \"../effectFallbacks\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\n\r\nimport { type Engine } from \"../../Engines/engine\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type PBRBaseMaterial } from \"./pbrBaseMaterial\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"../materialHelper.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialClearCoatDefines extends MaterialDefines {\r\n    public CLEARCOAT = false;\r\n    public CLEARCOAT_DEFAULTIOR = false;\r\n    public CLEARCOAT_TEXTURE = false;\r\n    public CLEARCOAT_TEXTURE_ROUGHNESS = false;\r\n    public CLEARCOAT_TEXTUREDIRECTUV = 0;\r\n    public CLEARCOAT_TEXTURE_ROUGHNESSDIRECTUV = 0;\r\n    public CLEARCOAT_BUMP = false;\r\n    public CLEARCOAT_BUMPDIRECTUV = 0;\r\n    public CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE = false;\r\n    public CLEARCOAT_REMAP_F0 = false;\r\n\r\n    public CLEARCOAT_TINT = false;\r\n    public CLEARCOAT_TINT_TEXTURE = false;\r\n    public CLEARCOAT_TINT_TEXTUREDIRECTUV = 0;\r\n    public CLEARCOAT_TINT_GAMMATEXTURE = false;\r\n}\r\n\r\n/**\r\n * Plugin that implements the clear coat component of the PBR material\r\n */\r\nexport class PBRClearCoatConfiguration extends MaterialPluginBase {\r\n    declare protected _material: PBRBaseMaterial;\r\n\r\n    /**\r\n     * This defaults to 1.5 corresponding to a 0.04 f0 or a 4% reflectance at normal incidence\r\n     * The default fits with a polyurethane material.\r\n     * @internal\r\n     */\r\n    public static readonly _DefaultIndexOfRefraction = 1.5;\r\n\r\n    private _isEnabled = false;\r\n    /**\r\n     * Defines if the clear coat is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    /**\r\n     * Defines the clear coat layer strength (between 0 and 1) it defaults to 1.\r\n     */\r\n    @serialize()\r\n    public intensity: number = 1;\r\n\r\n    /**\r\n     * Defines the clear coat layer roughness.\r\n     */\r\n    @serialize()\r\n    public roughness: number = 0;\r\n\r\n    private _indexOfRefraction = PBRClearCoatConfiguration._DefaultIndexOfRefraction;\r\n    /**\r\n     * Defines the index of refraction of the clear coat.\r\n     * This defaults to 1.5 corresponding to a 0.04 f0 or a 4% reflectance at normal incidence\r\n     * The default fits with a polyurethane material.\r\n     * Changing the default value is more performance intensive.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor indexOfRefraction = PBRClearCoatConfiguration._DefaultIndexOfRefraction;\r\n\r\n    private _texture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the clear coat values in a texture (red channel is intensity and green channel is roughness)\r\n     * If useRoughnessFromMainTexture is false, the green channel of texture is not used and the green channel of textureRoughness is used instead\r\n     * if textureRoughness is not empty, else no texture roughness is used\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor texture: Nullable<BaseTexture> = null;\r\n\r\n    private _useRoughnessFromMainTexture = true;\r\n    /**\r\n     * Indicates that the green channel of the texture property will be used for roughness (default: true)\r\n     * If false, the green channel from textureRoughness is used for roughness\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRoughnessFromMainTexture = true;\r\n\r\n    private _textureRoughness: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the clear coat roughness in a texture (green channel)\r\n     * Not used if useRoughnessFromMainTexture is true\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor textureRoughness: Nullable<BaseTexture> = null;\r\n\r\n    private _remapF0OnInterfaceChange = true;\r\n    /**\r\n     * Defines if the F0 value should be remapped to account for the interface change in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor remapF0OnInterfaceChange = true;\r\n\r\n    private _bumpTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Define the clear coat specific bump texture.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor bumpTexture: Nullable<BaseTexture> = null;\r\n\r\n    private _isTintEnabled = false;\r\n    /**\r\n     * Defines if the clear coat tint is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isTintEnabled = false;\r\n\r\n    /**\r\n     * Defines the clear coat tint of the material.\r\n     * This is only use if tint is enabled\r\n     */\r\n    @serializeAsColor3()\r\n    public tintColor = Color3.White();\r\n\r\n    /**\r\n     * Defines the distance at which the tint color should be found in the\r\n     * clear coat media.\r\n     * This is only use if tint is enabled\r\n     */\r\n    @serialize()\r\n    public tintColorAtDistance = 1;\r\n\r\n    /**\r\n     * Defines the clear coat layer thickness.\r\n     * This is only use if tint is enabled\r\n     */\r\n    @serialize()\r\n    public tintThickness: number = 1;\r\n\r\n    private _tintTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the clear tint values in a texture.\r\n     * rgb is tint\r\n     * a is a thickness factor\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor tintTexture: Nullable<BaseTexture> = null;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial, addToPluginList = true) {\r\n        super(material, \"PBRClearCoat\", 100, new MaterialClearCoatDefines(), addToPluginList);\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks whether the clear coat textures are ready for the sub mesh.\r\n     * @param defines defines the material defines to inspect\r\n     * @param scene defines the scene to use for readiness checks\r\n     * @param engine defines the engine to use for readiness checks\r\n     * @returns true if clear coat is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: MaterialClearCoatDefines, scene: Scene, engine: Engine): boolean {\r\n        if (!this._isEnabled) {\r\n            return true;\r\n        }\r\n\r\n        const disableBumpMap = this._material._disableBumpMap;\r\n        if (defines._areTexturesDirty) {\r\n            if (scene.texturesEnabled) {\r\n                if (this._texture && MaterialFlags.ClearCoatTextureEnabled) {\r\n                    if (!this._texture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._textureRoughness && MaterialFlags.ClearCoatTextureEnabled) {\r\n                    if (!this._textureRoughness.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (engine.getCaps().standardDerivatives && this._bumpTexture && MaterialFlags.ClearCoatBumpTextureEnabled && !disableBumpMap) {\r\n                    // Bump texture cannot be not blocking.\r\n                    if (!this._bumpTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._isTintEnabled && this._tintTexture && MaterialFlags.ClearCoatTintTextureEnabled) {\r\n                    if (!this._tintTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates shader defines for clear coat before attributes are processed.\r\n     * @param defines defines the material defines to update\r\n     * @param scene defines the scene to use for texture checks\r\n     */\r\n    public override prepareDefinesBeforeAttributes(defines: MaterialClearCoatDefines, scene: Scene): void {\r\n        if (this._isEnabled) {\r\n            defines.CLEARCOAT = true;\r\n            defines.CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE = this._useRoughnessFromMainTexture;\r\n            defines.CLEARCOAT_REMAP_F0 = this._remapF0OnInterfaceChange;\r\n\r\n            if (defines._areTexturesDirty) {\r\n                if (scene.texturesEnabled) {\r\n                    if (this._texture && MaterialFlags.ClearCoatTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._texture, defines, \"CLEARCOAT_TEXTURE\");\r\n                    } else {\r\n                        defines.CLEARCOAT_TEXTURE = false;\r\n                    }\r\n\r\n                    if (this._textureRoughness && MaterialFlags.ClearCoatTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._textureRoughness, defines, \"CLEARCOAT_TEXTURE_ROUGHNESS\");\r\n                    } else {\r\n                        defines.CLEARCOAT_TEXTURE_ROUGHNESS = false;\r\n                    }\r\n\r\n                    if (this._bumpTexture && MaterialFlags.ClearCoatBumpTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._bumpTexture, defines, \"CLEARCOAT_BUMP\");\r\n                    } else {\r\n                        defines.CLEARCOAT_BUMP = false;\r\n                    }\r\n\r\n                    defines.CLEARCOAT_DEFAULTIOR = this._indexOfRefraction === PBRClearCoatConfiguration._DefaultIndexOfRefraction;\r\n\r\n                    if (this._isTintEnabled) {\r\n                        defines.CLEARCOAT_TINT = true;\r\n                        if (this._tintTexture && MaterialFlags.ClearCoatTintTextureEnabled) {\r\n                            PrepareDefinesForMergedUV(this._tintTexture, defines, \"CLEARCOAT_TINT_TEXTURE\");\r\n                            defines.CLEARCOAT_TINT_GAMMATEXTURE = this._tintTexture.gammaSpace;\r\n                        } else {\r\n                            defines.CLEARCOAT_TINT_TEXTURE = false;\r\n                        }\r\n                    } else {\r\n                        defines.CLEARCOAT_TINT = false;\r\n                        defines.CLEARCOAT_TINT_TEXTURE = false;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            defines.CLEARCOAT = false;\r\n            defines.CLEARCOAT_TEXTURE = false;\r\n            defines.CLEARCOAT_TEXTURE_ROUGHNESS = false;\r\n            defines.CLEARCOAT_BUMP = false;\r\n            defines.CLEARCOAT_TINT = false;\r\n            defines.CLEARCOAT_TINT_TEXTURE = false;\r\n            defines.CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE = false;\r\n            defines.CLEARCOAT_DEFAULTIOR = false;\r\n            defines.CLEARCOAT_TEXTUREDIRECTUV = 0;\r\n            defines.CLEARCOAT_TEXTURE_ROUGHNESSDIRECTUV = 0;\r\n            defines.CLEARCOAT_BUMPDIRECTUV = 0;\r\n            defines.CLEARCOAT_REMAP_F0 = false;\r\n            defines.CLEARCOAT_TINT_TEXTUREDIRECTUV = 0;\r\n            defines.CLEARCOAT_TINT_GAMMATEXTURE = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds clear coat data for a sub mesh.\r\n     * @param uniformBuffer defines the uniform buffer to update\r\n     * @param scene defines the scene to use for texture binding\r\n     * @param engine defines the engine to use for capability checks\r\n     * @param subMesh defines the sub mesh being rendered\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const defines = subMesh.materialDefines as unknown as MaterialClearCoatDefines;\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n\r\n        const disableBumpMap = this._material._disableBumpMap;\r\n        const invertNormalMapX = this._material._invertNormalMapX;\r\n        const invertNormalMapY = this._material._invertNormalMapY;\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            if ((this._texture || this._textureRoughness) && MaterialFlags.ClearCoatTextureEnabled) {\r\n                uniformBuffer.updateFloat4(\r\n                    \"vClearCoatInfos\",\r\n                    this._texture?.coordinatesIndex ?? 0,\r\n                    this._texture?.level ?? 0,\r\n                    this._textureRoughness?.coordinatesIndex ?? 0,\r\n                    this._textureRoughness?.level ?? 0\r\n                );\r\n                if (this._texture) {\r\n                    BindTextureMatrix(this._texture, uniformBuffer, \"clearCoat\");\r\n                }\r\n                if (this._textureRoughness && !defines.CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE) {\r\n                    BindTextureMatrix(this._textureRoughness, uniformBuffer, \"clearCoatRoughness\");\r\n                }\r\n            }\r\n\r\n            if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.ClearCoatTextureEnabled && !disableBumpMap) {\r\n                uniformBuffer.updateFloat2(\"vClearCoatBumpInfos\", this._bumpTexture.coordinatesIndex, this._bumpTexture.level);\r\n                BindTextureMatrix(this._bumpTexture, uniformBuffer, \"clearCoatBump\");\r\n\r\n                if (scene._mirroredCameraPosition) {\r\n                    uniformBuffer.updateFloat2(\"vClearCoatTangentSpaceParams\", invertNormalMapX ? 1.0 : -1.0, invertNormalMapY ? 1.0 : -1.0);\r\n                } else {\r\n                    uniformBuffer.updateFloat2(\"vClearCoatTangentSpaceParams\", invertNormalMapX ? -1.0 : 1.0, invertNormalMapY ? -1.0 : 1.0);\r\n                }\r\n            }\r\n\r\n            if (this._tintTexture && MaterialFlags.ClearCoatTintTextureEnabled) {\r\n                uniformBuffer.updateFloat2(\"vClearCoatTintInfos\", this._tintTexture.coordinatesIndex, this._tintTexture.level);\r\n                BindTextureMatrix(this._tintTexture, uniformBuffer, \"clearCoatTint\");\r\n            }\r\n\r\n            // Clear Coat General params\r\n            uniformBuffer.updateFloat2(\"vClearCoatParams\", this.intensity, this.roughness);\r\n\r\n            // Clear Coat Refraction params\r\n            const a = 1 - this._indexOfRefraction;\r\n            const b = 1 + this._indexOfRefraction;\r\n            const f0 = Math.pow(-a / b, 2); // Schlicks approx: (ior1 - ior2) / (ior1 + ior2) where ior2 for air is close to vacuum = 1.\r\n            const eta = 1 / this._indexOfRefraction;\r\n            uniformBuffer.updateFloat4(\"vClearCoatRefractionParams\", f0, eta, a, b);\r\n\r\n            if (this._isTintEnabled) {\r\n                uniformBuffer.updateFloat4(\"vClearCoatTintParams\", this.tintColor.r, this.tintColor.g, this.tintColor.b, Math.max(0.00001, this.tintThickness));\r\n                uniformBuffer.updateFloat(\"clearCoatColorAtDistance\", Math.max(0.00001, this.tintColorAtDistance));\r\n            }\r\n        }\r\n\r\n        // Textures\r\n        if (scene.texturesEnabled) {\r\n            if (this._texture && MaterialFlags.ClearCoatTextureEnabled) {\r\n                uniformBuffer.setTexture(\"clearCoatSampler\", this._texture);\r\n            }\r\n\r\n            if (this._textureRoughness && !defines.CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE && MaterialFlags.ClearCoatTextureEnabled) {\r\n                uniformBuffer.setTexture(\"clearCoatRoughnessSampler\", this._textureRoughness);\r\n            }\r\n\r\n            if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.ClearCoatBumpTextureEnabled && !disableBumpMap) {\r\n                uniformBuffer.setTexture(\"clearCoatBumpSampler\", this._bumpTexture);\r\n            }\r\n\r\n            if (this._isTintEnabled && this._tintTexture && MaterialFlags.ClearCoatTintTextureEnabled) {\r\n                uniformBuffer.setTexture(\"clearCoatTintSampler\", this._tintTexture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether clear coat uses a texture.\r\n     * @param texture defines the texture to check\r\n     * @returns true if the texture is used by clear coat\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (this._texture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._textureRoughness === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._bumpTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._tintTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds the active clear coat textures.\r\n     * @param activeTextures defines the list of active textures to update\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this._texture) {\r\n            activeTextures.push(this._texture);\r\n        }\r\n\r\n        if (this._textureRoughness) {\r\n            activeTextures.push(this._textureRoughness);\r\n        }\r\n\r\n        if (this._bumpTexture) {\r\n            activeTextures.push(this._bumpTexture);\r\n        }\r\n\r\n        if (this._tintTexture) {\r\n            activeTextures.push(this._tintTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the animatable clear coat textures.\r\n     * @param animatables defines the list of animatables to update\r\n     */\r\n    public override getAnimatables(animatables: IAnimatable[]): void {\r\n        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {\r\n            animatables.push(this._texture);\r\n        }\r\n\r\n        if (this._textureRoughness && this._textureRoughness.animations && this._textureRoughness.animations.length > 0) {\r\n            animatables.push(this._textureRoughness);\r\n        }\r\n\r\n        if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {\r\n            animatables.push(this._bumpTexture);\r\n        }\r\n\r\n        if (this._tintTexture && this._tintTexture.animations && this._tintTexture.animations.length > 0) {\r\n            animatables.push(this._tintTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the clear coat textures.\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     */\r\n    public override dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            this._texture?.dispose();\r\n            this._textureRoughness?.dispose();\r\n            this._bumpTexture?.dispose();\r\n            this._tintTexture?.dispose();\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRClearCoatConfiguration\";\r\n    }\r\n\r\n    public override addFallbacks(defines: MaterialClearCoatDefines, fallbacks: EffectFallbacks, currentRank: number): number {\r\n        if (defines.CLEARCOAT_BUMP) {\r\n            fallbacks.addFallback(currentRank++, \"CLEARCOAT_BUMP\");\r\n        }\r\n        if (defines.CLEARCOAT_TINT) {\r\n            fallbacks.addFallback(currentRank++, \"CLEARCOAT_TINT\");\r\n        }\r\n        if (defines.CLEARCOAT) {\r\n            fallbacks.addFallback(currentRank++, \"CLEARCOAT\");\r\n        }\r\n        return currentRank;\r\n    }\r\n\r\n    /**\r\n     * Adds the clear coat sampler names.\r\n     * @param samplers defines the list of sampler names to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"clearCoatSampler\", \"clearCoatRoughnessSampler\", \"clearCoatBumpSampler\", \"clearCoatTintSampler\");\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vClearCoatParams\", size: 2, type: \"vec2\" },\r\n                { name: \"vClearCoatRefractionParams\", size: 4, type: \"vec4\" },\r\n                { name: \"vClearCoatInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"clearCoatMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"clearCoatRoughnessMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"vClearCoatBumpInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"vClearCoatTangentSpaceParams\", size: 2, type: \"vec2\" },\r\n                { name: \"clearCoatBumpMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"vClearCoatTintParams\", size: 4, type: \"vec4\" },\r\n                { name: \"clearCoatColorAtDistance\", size: 1, type: \"float\" },\r\n                { name: \"vClearCoatTintInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"clearCoatTintMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../../types\";\r\nimport { serialize, serializeAsTexture, expandToProperty } from \"../../Misc/decorators\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { MaterialFlags } from \"../materialFlags\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { type EffectFallbacks } from \"../effectFallbacks\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\n\r\nimport { type Scene } from \"../../scene\";\r\nimport { type PBRBaseMaterial } from \"./pbrBaseMaterial\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"../materialHelper.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialIridescenceDefines extends MaterialDefines {\r\n    public IRIDESCENCE = false;\r\n    public IRIDESCENCE_TEXTURE = false;\r\n    public IRIDESCENCE_TEXTUREDIRECTUV = 0;\r\n    public IRIDESCENCE_THICKNESS_TEXTURE = false;\r\n    public IRIDESCENCE_THICKNESS_TEXTUREDIRECTUV = 0;\r\n}\r\n\r\n/**\r\n * Plugin that implements the iridescence (thin film) component of the PBR material\r\n */\r\nexport class PBRIridescenceConfiguration extends MaterialPluginBase {\r\n    declare protected _material: PBRBaseMaterial;\r\n\r\n    /**\r\n     * The default minimum thickness of the thin-film layer given in nanometers (nm).\r\n     * Defaults to 100 nm.\r\n     * @internal\r\n     */\r\n    public static readonly _DefaultMinimumThickness = 100;\r\n\r\n    /**\r\n     * The default maximum thickness of the thin-film layer given in nanometers (nm).\r\n     * Defaults to 400 nm.\r\n     * @internal\r\n     */\r\n    public static readonly _DefaultMaximumThickness = 400;\r\n\r\n    /**\r\n     * The default index of refraction of the thin-film layer.\r\n     * Defaults to 1.3\r\n     * @internal\r\n     */\r\n    public static readonly _DefaultIndexOfRefraction = 1.3;\r\n\r\n    private _isEnabled = false;\r\n    /**\r\n     * Defines if the iridescence is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    /**\r\n     * Defines the iridescence layer strength (between 0 and 1) it defaults to 1.\r\n     */\r\n    @serialize()\r\n    public intensity: number = 1;\r\n\r\n    /**\r\n     * Defines the minimum thickness of the thin-film layer given in nanometers (nm).\r\n     */\r\n    @serialize()\r\n    public minimumThickness: number = PBRIridescenceConfiguration._DefaultMinimumThickness;\r\n\r\n    /**\r\n     * Defines the maximum thickness of the thin-film layer given in nanometers (nm). This will be the thickness used if not thickness texture has been set.\r\n     */\r\n    @serialize()\r\n    public maximumThickness: number = PBRIridescenceConfiguration._DefaultMaximumThickness;\r\n\r\n    /**\r\n     * Defines the maximum thickness of the thin-film layer given in nanometers (nm).\r\n     */\r\n    @serialize()\r\n    public indexOfRefraction: number = PBRIridescenceConfiguration._DefaultIndexOfRefraction;\r\n\r\n    private _texture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the iridescence intensity in a texture (red channel)\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor texture: Nullable<BaseTexture> = null;\r\n\r\n    private _thicknessTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the iridescence thickness in a texture (green channel)\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor thicknessTexture: Nullable<BaseTexture> = null;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial, addToPluginList = true) {\r\n        super(material, \"PBRIridescence\", 110, new MaterialIridescenceDefines(), addToPluginList);\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks whether the iridescence textures are ready for the sub mesh.\r\n     * @param defines defines the material defines to inspect\r\n     * @param scene defines the scene to use for readiness checks\r\n     * @returns true if iridescence is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: MaterialIridescenceDefines, scene: Scene): boolean {\r\n        if (!this._isEnabled) {\r\n            return true;\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            if (scene.texturesEnabled) {\r\n                if (this._texture && MaterialFlags.IridescenceTextureEnabled) {\r\n                    if (!this._texture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._thicknessTexture && MaterialFlags.IridescenceTextureEnabled) {\r\n                    if (!this._thicknessTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates shader defines for iridescence before attributes are processed.\r\n     * @param defines defines the material defines to update\r\n     * @param scene defines the scene to use for texture checks\r\n     */\r\n    public override prepareDefinesBeforeAttributes(defines: MaterialIridescenceDefines, scene: Scene): void {\r\n        if (this._isEnabled) {\r\n            defines.IRIDESCENCE = true;\r\n\r\n            if (defines._areTexturesDirty) {\r\n                if (scene.texturesEnabled) {\r\n                    if (this._texture && MaterialFlags.IridescenceTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._texture, defines, \"IRIDESCENCE_TEXTURE\");\r\n                    } else {\r\n                        defines.IRIDESCENCE_TEXTURE = false;\r\n                    }\r\n\r\n                    if (this._thicknessTexture && MaterialFlags.IridescenceTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._thicknessTexture, defines, \"IRIDESCENCE_THICKNESS_TEXTURE\");\r\n                    } else {\r\n                        defines.IRIDESCENCE_THICKNESS_TEXTURE = false;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            defines.IRIDESCENCE = false;\r\n            defines.IRIDESCENCE_TEXTURE = false;\r\n            defines.IRIDESCENCE_THICKNESS_TEXTURE = false;\r\n            defines.IRIDESCENCE_TEXTUREDIRECTUV = 0;\r\n            defines.IRIDESCENCE_THICKNESS_TEXTUREDIRECTUV = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds iridescence data for a sub mesh.\r\n     * @param uniformBuffer defines the uniform buffer to update\r\n     * @param scene defines the scene to use for texture binding\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene): void {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            if ((this._texture || this._thicknessTexture) && MaterialFlags.IridescenceTextureEnabled) {\r\n                uniformBuffer.updateFloat4(\r\n                    \"vIridescenceInfos\",\r\n                    this._texture?.coordinatesIndex ?? 0,\r\n                    this._texture?.level ?? 0,\r\n                    this._thicknessTexture?.coordinatesIndex ?? 0,\r\n                    this._thicknessTexture?.level ?? 0\r\n                );\r\n                if (this._texture) {\r\n                    BindTextureMatrix(this._texture, uniformBuffer, \"iridescence\");\r\n                }\r\n                if (this._thicknessTexture) {\r\n                    BindTextureMatrix(this._thicknessTexture, uniformBuffer, \"iridescenceThickness\");\r\n                }\r\n            }\r\n\r\n            // Clear Coat General params\r\n            uniformBuffer.updateFloat4(\"vIridescenceParams\", this.intensity, this.indexOfRefraction, this.minimumThickness, this.maximumThickness);\r\n        }\r\n\r\n        // Textures\r\n        if (scene.texturesEnabled) {\r\n            if (this._texture && MaterialFlags.IridescenceTextureEnabled) {\r\n                uniformBuffer.setTexture(\"iridescenceSampler\", this._texture);\r\n            }\r\n\r\n            if (this._thicknessTexture && MaterialFlags.IridescenceTextureEnabled) {\r\n                uniformBuffer.setTexture(\"iridescenceThicknessSampler\", this._thicknessTexture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether iridescence uses a texture.\r\n     * @param texture defines the texture to check\r\n     * @returns true if the texture is used by iridescence\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (this._texture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._thicknessTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds the active iridescence textures.\r\n     * @param activeTextures defines the list of active textures to update\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this._texture) {\r\n            activeTextures.push(this._texture);\r\n        }\r\n\r\n        if (this._thicknessTexture) {\r\n            activeTextures.push(this._thicknessTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the animatable iridescence textures.\r\n     * @param animatables defines the list of animatables to update\r\n     */\r\n    public override getAnimatables(animatables: IAnimatable[]): void {\r\n        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {\r\n            animatables.push(this._texture);\r\n        }\r\n\r\n        if (this._thicknessTexture && this._thicknessTexture.animations && this._thicknessTexture.animations.length > 0) {\r\n            animatables.push(this._thicknessTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the iridescence textures.\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     */\r\n    public override dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            this._texture?.dispose();\r\n            this._thicknessTexture?.dispose();\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRIridescenceConfiguration\";\r\n    }\r\n\r\n    public override addFallbacks(defines: MaterialIridescenceDefines, fallbacks: EffectFallbacks, currentRank: number): number {\r\n        if (defines.IRIDESCENCE) {\r\n            fallbacks.addFallback(currentRank++, \"IRIDESCENCE\");\r\n        }\r\n        return currentRank;\r\n    }\r\n\r\n    /**\r\n     * Adds the iridescence sampler names.\r\n     * @param samplers defines the list of sampler names to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"iridescenceSampler\", \"iridescenceThicknessSampler\");\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vIridescenceParams\", size: 4, type: \"vec4\" },\r\n                { name: \"vIridescenceInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"iridescenceMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"iridescenceThicknessMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { serialize, expandToProperty, serializeAsVector2, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { MaterialFlags } from \"../../Materials/materialFlags\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { type EffectFallbacks } from \"../effectFallbacks\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\n\r\nimport { type Scene } from \"../../scene\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type PBRBaseMaterial } from \"./pbrBaseMaterial\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"../materialHelper.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialAnisotropicDefines extends MaterialDefines {\r\n    public ANISOTROPIC = false;\r\n    public ANISOTROPIC_TEXTURE = false;\r\n    public ANISOTROPIC_TEXTUREDIRECTUV = 0;\r\n    public ANISOTROPIC_LEGACY = false;\r\n    public MAINUV1 = false;\r\n}\r\n\r\n/**\r\n * Plugin that implements the anisotropic component of the PBR material\r\n */\r\nexport class PBRAnisotropicConfiguration extends MaterialPluginBase {\r\n    private _isEnabled = false;\r\n    /**\r\n     * Defines if the anisotropy is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    /**\r\n     * Defines the anisotropy strength (between 0 and 1) it defaults to 1.\r\n     */\r\n    @serialize()\r\n    public intensity: number = 1;\r\n\r\n    /**\r\n     * Defines if the effect is along the tangents, bitangents or in between.\r\n     * By default, the effect is \"stretching\" the highlights along the tangents.\r\n     */\r\n    @serializeAsVector2()\r\n    public direction = new Vector2(1, 0);\r\n\r\n    /**\r\n     * Sets the anisotropy direction as an angle.\r\n     */\r\n    public set angle(value: number) {\r\n        this.direction.x = Math.cos(value);\r\n        this.direction.y = Math.sin(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the anisotropy angle value in radians.\r\n     * @returns the anisotropy angle value in radians.\r\n     */\r\n    public get angle(): number {\r\n        return Math.atan2(this.direction.y, this.direction.x);\r\n    }\r\n\r\n    private _texture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the anisotropy values in a texture.\r\n     * rg is direction (like normal from -1 to 1)\r\n     * b is a intensity\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor texture: Nullable<BaseTexture> = null;\r\n\r\n    private _legacy = false;\r\n    /**\r\n     * Defines if the anisotropy is in legacy mode for backwards compatibility before 6.4.0.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor legacy: boolean = false;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsMiscDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsMiscDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsMiscDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial, addToPluginList = true) {\r\n        super(material, \"PBRAnisotropic\", 110, new MaterialAnisotropicDefines(), addToPluginList);\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n        this._internalMarkAllSubMeshesAsMiscDirty = material._dirtyCallbacks[Constants.MATERIAL_MiscDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks whether the anisotropy textures are ready for the sub mesh.\r\n     * @param defines defines the material defines to inspect\r\n     * @param scene defines the scene to use for readiness checks\r\n     * @returns true if anisotropy is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: MaterialAnisotropicDefines, scene: Scene): boolean {\r\n        if (!this._isEnabled) {\r\n            return true;\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            if (scene.texturesEnabled) {\r\n                if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {\r\n                    if (!this._texture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates shader defines for anisotropy before attributes are processed.\r\n     * @param defines defines the material defines to update\r\n     * @param scene defines the scene to use for texture checks\r\n     * @param mesh defines the mesh to inspect for tangent data\r\n     */\r\n    public override prepareDefinesBeforeAttributes(defines: MaterialAnisotropicDefines, scene: Scene, mesh: AbstractMesh): void {\r\n        if (this._isEnabled) {\r\n            defines.ANISOTROPIC = this._isEnabled;\r\n            if (this._isEnabled && !mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n                defines._needUVs = true;\r\n                defines.MAINUV1 = true;\r\n            }\r\n\r\n            if (defines._areTexturesDirty) {\r\n                if (scene.texturesEnabled) {\r\n                    if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._texture, defines, \"ANISOTROPIC_TEXTURE\");\r\n                    } else {\r\n                        defines.ANISOTROPIC_TEXTURE = false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (defines._areMiscDirty) {\r\n                defines.ANISOTROPIC_LEGACY = this._legacy;\r\n            }\r\n        } else {\r\n            defines.ANISOTROPIC = false;\r\n            defines.ANISOTROPIC_TEXTURE = false;\r\n            defines.ANISOTROPIC_TEXTUREDIRECTUV = 0;\r\n            defines.ANISOTROPIC_LEGACY = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds anisotropy data for a sub mesh.\r\n     * @param uniformBuffer defines the uniform buffer to update\r\n     * @param scene defines the scene to use for texture binding\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene): void {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {\r\n                uniformBuffer.updateFloat2(\"vAnisotropyInfos\", this._texture.coordinatesIndex, this._texture.level);\r\n                BindTextureMatrix(this._texture, uniformBuffer, \"anisotropy\");\r\n            }\r\n\r\n            // Anisotropy\r\n            uniformBuffer.updateFloat3(\"vAnisotropy\", this.direction.x, this.direction.y, this.intensity);\r\n        }\r\n\r\n        // Textures\r\n        if (scene.texturesEnabled) {\r\n            if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {\r\n                uniformBuffer.setTexture(\"anisotropySampler\", this._texture);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether anisotropy uses a texture.\r\n     * @param texture defines the texture to check\r\n     * @returns true if the texture is used by anisotropy\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (this._texture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds the active anisotropy textures.\r\n     * @param activeTextures defines the list of active textures to update\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this._texture) {\r\n            activeTextures.push(this._texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the animatable anisotropy textures.\r\n     * @param animatables defines the list of animatables to update\r\n     */\r\n    public override getAnimatables(animatables: IAnimatable[]): void {\r\n        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {\r\n            animatables.push(this._texture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the anisotropy textures.\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     */\r\n    public override dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            if (this._texture) {\r\n                this._texture.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRAnisotropicConfiguration\";\r\n    }\r\n\r\n    public override addFallbacks(defines: MaterialAnisotropicDefines, fallbacks: EffectFallbacks, currentRank: number): number {\r\n        if (defines.ANISOTROPIC) {\r\n            fallbacks.addFallback(currentRank++, \"ANISOTROPIC\");\r\n        }\r\n        return currentRank;\r\n    }\r\n\r\n    /**\r\n     * Adds the anisotropy sampler names.\r\n     * @param samplers defines the list of sampler names to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"anisotropySampler\");\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vAnisotropy\", size: 3, type: \"vec3\" },\r\n                { name: \"vAnisotropyInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"anisotropyMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Parses a anisotropy Configuration from a serialized object.\r\n     * @param source - Serialized object.\r\n     * @param scene Defines the scene we are parsing for\r\n     * @param rootUrl Defines the rootUrl to load from\r\n     */\r\n    public override parse(source: any, scene: Scene, rootUrl: string): void {\r\n        super.parse(source, scene, rootUrl);\r\n\r\n        // Backward compatibility\r\n        if (source.legacy === undefined) {\r\n            this.legacy = true;\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { serialize, expandToProperty, serializeAsColor3, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { MaterialFlags } from \"../../Materials/materialFlags\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { type EffectFallbacks } from \"../effectFallbacks\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\n\r\nimport { type Engine } from \"../../Engines/engine\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type PBRBaseMaterial } from \"./pbrBaseMaterial\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"../materialHelper.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialSheenDefines extends MaterialDefines {\r\n    public SHEEN = false;\r\n    public SHEEN_TEXTURE = false;\r\n    public SHEEN_GAMMATEXTURE = false;\r\n    public SHEEN_TEXTURE_ROUGHNESS = false;\r\n    public SHEEN_TEXTUREDIRECTUV = 0;\r\n    public SHEEN_TEXTURE_ROUGHNESSDIRECTUV = 0;\r\n    public SHEEN_LINKWITHALBEDO = false;\r\n    public SHEEN_ROUGHNESS = false;\r\n    public SHEEN_ALBEDOSCALING = false;\r\n    public SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE = false;\r\n}\r\n\r\n/**\r\n * Plugin that implements the sheen component of the PBR material.\r\n */\r\nexport class PBRSheenConfiguration extends MaterialPluginBase {\r\n    private _isEnabled = false;\r\n    /**\r\n     * Defines if the material uses sheen.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    private _linkSheenWithAlbedo = false;\r\n    /**\r\n     * Defines if the sheen is linked to the sheen color.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor linkSheenWithAlbedo = false;\r\n\r\n    /**\r\n     * Defines the sheen intensity.\r\n     */\r\n    @serialize()\r\n    public intensity = 1;\r\n\r\n    /**\r\n     * Defines the sheen color.\r\n     */\r\n    @serializeAsColor3()\r\n    public color = Color3.White();\r\n\r\n    private _texture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the sheen tint values in a texture.\r\n     * rgb is tint\r\n     * a is a intensity or roughness if the roughness property has been defined and useRoughnessFromTexture is true (in that case, textureRoughness won't be used)\r\n     * If the roughness property has been defined and useRoughnessFromTexture is false then the alpha channel is not used to modulate roughness\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor texture: Nullable<BaseTexture> = null;\r\n\r\n    private _useRoughnessFromMainTexture = true;\r\n    /**\r\n     * Indicates that the alpha channel of the texture property will be used for roughness.\r\n     * Has no effect if the roughness (and texture!) property is not defined\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRoughnessFromMainTexture = true;\r\n\r\n    private _roughness: Nullable<number> = null;\r\n    /**\r\n     * Defines the sheen roughness.\r\n     * It is not taken into account if linkSheenWithAlbedo is true.\r\n     * To stay backward compatible, material roughness is used instead if sheen roughness = null\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor roughness: Nullable<number> = null;\r\n\r\n    private _textureRoughness: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the sheen roughness in a texture.\r\n     * alpha channel is the roughness. This texture won't be used if the texture property is not empty and useRoughnessFromTexture is true\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor textureRoughness: Nullable<BaseTexture> = null;\r\n\r\n    private _albedoScaling = false;\r\n    /**\r\n     * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.\r\n     * It allows the strength of the sheen effect to not depend on the base color of the material,\r\n     * making it easier to setup and tweak the effect\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor albedoScaling = false;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial, addToPluginList = true) {\r\n        super(material, \"Sheen\", 120, new MaterialSheenDefines(), addToPluginList);\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks whether the sheen textures are ready for the sub mesh.\r\n     * @param defines defines the material defines to inspect\r\n     * @param scene defines the scene to use for readiness checks\r\n     * @returns true if sheen is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: MaterialSheenDefines, scene: Scene): boolean {\r\n        if (!this._isEnabled) {\r\n            return true;\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            if (scene.texturesEnabled) {\r\n                if (this._texture && MaterialFlags.SheenTextureEnabled) {\r\n                    if (!this._texture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {\r\n                    if (!this._textureRoughness.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates shader defines for sheen before attributes are processed.\r\n     * @param defines defines the material defines to update\r\n     * @param scene defines the scene to use for texture checks\r\n     */\r\n    public override prepareDefinesBeforeAttributes(defines: MaterialSheenDefines, scene: Scene): void {\r\n        if (this._isEnabled) {\r\n            defines.SHEEN = true;\r\n            defines.SHEEN_LINKWITHALBEDO = this._linkSheenWithAlbedo;\r\n            defines.SHEEN_ROUGHNESS = this._roughness !== null;\r\n            defines.SHEEN_ALBEDOSCALING = this._albedoScaling;\r\n            defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE = this._useRoughnessFromMainTexture;\r\n\r\n            if (defines._areTexturesDirty) {\r\n                if (scene.texturesEnabled) {\r\n                    if (this._texture && MaterialFlags.SheenTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._texture, defines, \"SHEEN_TEXTURE\");\r\n                        defines.SHEEN_GAMMATEXTURE = this._texture.gammaSpace;\r\n                    } else {\r\n                        defines.SHEEN_TEXTURE = false;\r\n                    }\r\n\r\n                    if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._textureRoughness, defines, \"SHEEN_TEXTURE_ROUGHNESS\");\r\n                    } else {\r\n                        defines.SHEEN_TEXTURE_ROUGHNESS = false;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            defines.SHEEN = false;\r\n            defines.SHEEN_TEXTURE = false;\r\n            defines.SHEEN_TEXTURE_ROUGHNESS = false;\r\n            defines.SHEEN_LINKWITHALBEDO = false;\r\n            defines.SHEEN_ROUGHNESS = false;\r\n            defines.SHEEN_ALBEDOSCALING = false;\r\n            defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE = false;\r\n            defines.SHEEN_GAMMATEXTURE = false;\r\n            defines.SHEEN_TEXTUREDIRECTUV = 0;\r\n            defines.SHEEN_TEXTURE_ROUGHNESSDIRECTUV = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds sheen data for a sub mesh.\r\n     * @param uniformBuffer defines the uniform buffer to update\r\n     * @param scene defines the scene to use for texture binding\r\n     * @param engine defines the engine to use for capability checks\r\n     * @param subMesh defines the sub mesh being rendered\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const defines = subMesh.materialDefines as unknown as MaterialSheenDefines;\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            if ((this._texture || this._textureRoughness) && MaterialFlags.SheenTextureEnabled) {\r\n                uniformBuffer.updateFloat4(\r\n                    \"vSheenInfos\",\r\n                    this._texture?.coordinatesIndex ?? 0,\r\n                    this._texture?.level ?? 0,\r\n                    this._textureRoughness?.coordinatesIndex ?? 0,\r\n                    this._textureRoughness?.level ?? 0\r\n                );\r\n                if (this._texture) {\r\n                    BindTextureMatrix(this._texture, uniformBuffer, \"sheen\");\r\n                }\r\n                if (this._textureRoughness && !defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE) {\r\n                    BindTextureMatrix(this._textureRoughness, uniformBuffer, \"sheenRoughness\");\r\n                }\r\n            }\r\n\r\n            // Sheen\r\n            uniformBuffer.updateFloat4(\"vSheenColor\", this.color.r, this.color.g, this.color.b, this.intensity);\r\n\r\n            if (this._roughness !== null) {\r\n                uniformBuffer.updateFloat(\"vSheenRoughness\", this._roughness);\r\n            }\r\n        }\r\n\r\n        // Textures\r\n        if (scene.texturesEnabled) {\r\n            if (this._texture && MaterialFlags.SheenTextureEnabled) {\r\n                uniformBuffer.setTexture(\"sheenSampler\", this._texture);\r\n            }\r\n\r\n            if (this._textureRoughness && !defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE && MaterialFlags.SheenTextureEnabled) {\r\n                uniformBuffer.setTexture(\"sheenRoughnessSampler\", this._textureRoughness);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether sheen uses a texture.\r\n     * @param texture defines the texture to check\r\n     * @returns true if the texture is used by sheen\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (this._texture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._textureRoughness === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds the active sheen textures.\r\n     * @param activeTextures defines the list of active textures to update\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this._texture) {\r\n            activeTextures.push(this._texture);\r\n        }\r\n\r\n        if (this._textureRoughness) {\r\n            activeTextures.push(this._textureRoughness);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the animatable sheen textures.\r\n     * @param animatables defines the list of animatables to update\r\n     */\r\n    public override getAnimatables(animatables: IAnimatable[]): void {\r\n        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {\r\n            animatables.push(this._texture);\r\n        }\r\n\r\n        if (this._textureRoughness && this._textureRoughness.animations && this._textureRoughness.animations.length > 0) {\r\n            animatables.push(this._textureRoughness);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the sheen textures.\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     */\r\n    public override dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            this._texture?.dispose();\r\n            this._textureRoughness?.dispose();\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRSheenConfiguration\";\r\n    }\r\n\r\n    public override addFallbacks(defines: MaterialSheenDefines, fallbacks: EffectFallbacks, currentRank: number): number {\r\n        if (defines.SHEEN) {\r\n            fallbacks.addFallback(currentRank++, \"SHEEN\");\r\n        }\r\n        return currentRank;\r\n    }\r\n\r\n    /**\r\n     * Adds the sheen sampler names.\r\n     * @param samplers defines the list of sampler names to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"sheenSampler\", \"sheenRoughnessSampler\");\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vSheenColor\", size: 4, type: \"vec4\" },\r\n                { name: \"vSheenRoughness\", size: 1, type: \"float\" },\r\n                { name: \"vSheenInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"sheenMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"sheenRoughnessMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { serialize, serializeAsTexture, expandToProperty, serializeAsColor3 } from \"../../Misc/decorators\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type SmartArray } from \"../../Misc/smartArray\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture\";\r\nimport { MaterialFlags } from \"../materialFlags\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { type EffectFallbacks } from \"../effectFallbacks\";\r\nimport { type CubeTexture } from \"../Textures/cubeTexture\";\r\nimport { TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\n\r\nimport { type Engine } from \"../../Engines/engine\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type PBRBaseMaterial } from \"./pbrBaseMaterial\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"../materialHelper.functions\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialSubSurfaceDefines extends MaterialDefines {\r\n    public SUBSURFACE = false;\r\n\r\n    public SS_REFRACTION = false;\r\n    public SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = false;\r\n    public SS_TRANSLUCENCY = false;\r\n    public SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = false;\r\n    public SS_SCATTERING = false;\r\n    public SS_DISPERSION = false;\r\n\r\n    public SS_THICKNESSANDMASK_TEXTURE = false;\r\n    public SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;\r\n    public SS_HAS_THICKNESS = false;\r\n    public SS_REFRACTIONINTENSITY_TEXTURE = false;\r\n    public SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV = 0;\r\n    public SS_TRANSLUCENCYINTENSITY_TEXTURE = false;\r\n    public SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV = 0;\r\n    public SS_TRANSLUCENCYCOLOR_TEXTURE = false;\r\n    public SS_TRANSLUCENCYCOLOR_TEXTUREDIRECTUV = 0;\r\n    public SS_TRANSLUCENCYCOLOR_TEXTURE_GAMMA = false;\r\n\r\n    public SS_REFRACTIONMAP_3D = false;\r\n    public SS_REFRACTIONMAP_OPPOSITEZ = false;\r\n    public SS_LODINREFRACTIONALPHA = false;\r\n    public SS_GAMMAREFRACTION = false;\r\n    public SS_RGBDREFRACTION = false;\r\n    public SS_LINEARSPECULARREFRACTION = false;\r\n    public SS_LINKREFRACTIONTOTRANSPARENCY = false;\r\n    public SS_ALBEDOFORREFRACTIONTINT = false;\r\n    public SS_ALBEDOFORTRANSLUCENCYTINT = false;\r\n    public SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false;\r\n    public SS_USE_THICKNESS_AS_DEPTH = false;\r\n\r\n    public SS_USE_GLTF_TEXTURES = false;\r\n    public SS_APPLY_ALBEDO_AFTER_SUBSURFACE = false;\r\n    public SS_TRANSLUCENCY_LEGACY = false;\r\n}\r\n\r\n/**\r\n * Plugin that implements the sub surface component of the PBR material\r\n */\r\nexport class PBRSubSurfaceConfiguration extends MaterialPluginBase {\r\n    /**\r\n     * Default value used for applyAlbedoAfterSubSurface.\r\n     *\r\n     * This property only exists for backward compatibility reasons.\r\n     * Set it to true if your rendering in 8.0+ is different from that in 7 when you use sub-surface properties (transmission, refraction, etc.). Default is false.\r\n     * Note however that the PBR calculation is wrong when this property is set to true, so only use it if you want to mimic the 7.0 behavior.\r\n     */\r\n    public static DEFAULT_APPLY_ALBEDO_AFTERSUBSURFACE = false;\r\n\r\n    /**\r\n     * Default value used for legacyTranslucency.\r\n     *\r\n     * This property only exists for backward compatibility reasons.\r\n     * Set it to true if your rendering in 8.0+ is different from that in 7 when you use sub-surface translucency. Default is false.\r\n     */\r\n    public static DEFAULT_LEGACY_TRANSLUCENCY = false;\r\n\r\n    declare protected _material: PBRBaseMaterial;\r\n\r\n    private _isRefractionEnabled = false;\r\n    /**\r\n     * Defines if the refraction is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isRefractionEnabled = false;\r\n\r\n    private _isTranslucencyEnabled = false;\r\n    /**\r\n     * Defines if the translucency is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isTranslucencyEnabled = false;\r\n\r\n    private _isDispersionEnabled = false;\r\n    /**\r\n     * Defines if dispersion is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isDispersionEnabled = false;\r\n\r\n    private _isScatteringEnabled = false;\r\n    /**\r\n     * Defines if the sub surface scattering is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markScenePrePassDirty\")\r\n    public accessor isScatteringEnabled = false;\r\n\r\n    @serialize()\r\n    private _scatteringDiffusionProfileIndex = 0;\r\n\r\n    /**\r\n     * Diffusion profile for subsurface scattering.\r\n     * Useful for better scattering in the skins or foliages.\r\n     */\r\n    public get scatteringDiffusionProfile(): Nullable<Color3> {\r\n        if (!this._scene.subSurfaceConfiguration) {\r\n            return null;\r\n        }\r\n\r\n        return this._scene.subSurfaceConfiguration.ssDiffusionProfileColors[this._scatteringDiffusionProfileIndex];\r\n    }\r\n\r\n    public set scatteringDiffusionProfile(c: Nullable<Color3>) {\r\n        if (!this._scene.enableSubSurfaceForPrePass()) {\r\n            // Not supported\r\n            return;\r\n        }\r\n\r\n        // addDiffusionProfile automatically checks for doubles\r\n        if (c) {\r\n            this._scatteringDiffusionProfileIndex = this._scene.subSurfaceConfiguration!.addDiffusionProfile(c);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Defines the refraction intensity of the material.\r\n     * The refraction when enabled replaces the Diffuse part of the material.\r\n     * The intensity helps transitioning between diffuse and refraction.\r\n     */\r\n    @serialize()\r\n    public refractionIntensity: number = 1;\r\n\r\n    /**\r\n     * Defines the translucency intensity of the material.\r\n     * When translucency has been enabled, this defines how much of the \"translucency\"\r\n     * is added to the diffuse part of the material.\r\n     */\r\n    @serialize()\r\n    public translucencyIntensity: number = 1;\r\n\r\n    private _useAlbedoToTintRefraction = false;\r\n    /**\r\n     * When enabled, transparent surfaces will be tinted with the albedo colour (independent of thickness)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAlbedoToTintRefraction: boolean = false;\r\n\r\n    private _useAlbedoToTintTranslucency = false;\r\n    /**\r\n     * When enabled, translucent surfaces will be tinted with the albedo colour (independent of thickness)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAlbedoToTintTranslucency: boolean = false;\r\n\r\n    private _thicknessTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the average thickness of a mesh in a texture (The texture is holding the values linearly).\r\n     * The red (or green if useGltfStyleTextures=true) channel of the texture should contain the thickness remapped between 0 and 1.\r\n     * 0 would mean minimumThickness\r\n     * 1 would mean maximumThickness\r\n     * The other channels might be use as a mask to vary the different effects intensity.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor thicknessTexture: Nullable<BaseTexture> = null;\r\n\r\n    private _refractionTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Defines the texture to use for refraction.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor refractionTexture: Nullable<BaseTexture> = null;\r\n\r\n    /** @internal */\r\n    public _indexOfRefraction = 1.5;\r\n    /**\r\n     * Index of refraction of the material base layer.\r\n     * https://en.wikipedia.org/wiki/List_of_refractive_indices\r\n     *\r\n     * This does not only impact refraction but also the Base F0 of Dielectric Materials.\r\n     *\r\n     * From dielectric fresnel rules: F0 = square((iorT - iorI) / (iorT + iorI))\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor indexOfRefraction = 1.5;\r\n\r\n    @serialize()\r\n    private _volumeIndexOfRefraction = -1.0;\r\n\r\n    /**\r\n     * Index of refraction of the material's volume.\r\n     * https://en.wikipedia.org/wiki/List_of_refractive_indices\r\n     *\r\n     * This ONLY impacts refraction. If not provided or given a non-valid value,\r\n     * the volume will use the same IOR as the surface.\r\n     */\r\n    public get volumeIndexOfRefraction(): number {\r\n        if (this._volumeIndexOfRefraction >= 1.0) {\r\n            return this._volumeIndexOfRefraction;\r\n        }\r\n        return this._indexOfRefraction;\r\n    }\r\n    public set volumeIndexOfRefraction(value: number) {\r\n        const volumeIndexOfRefraction = value >= 1.0 ? value : -1.0;\r\n        if (this._volumeIndexOfRefraction === volumeIndexOfRefraction) {\r\n            return;\r\n        }\r\n        this._volumeIndexOfRefraction = volumeIndexOfRefraction;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _invertRefractionY = false;\r\n    /**\r\n     * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertRefractionY = false;\r\n\r\n    /** @internal */\r\n    public _linkRefractionWithTransparency = false;\r\n    /**\r\n     * This parameters will make the material used its opacity to control how much it is refracting against not.\r\n     * Materials half opaque for instance using refraction could benefit from this control.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor linkRefractionWithTransparency = false;\r\n\r\n    /**\r\n     * Defines the minimum thickness stored in the thickness map.\r\n     * If no thickness map is defined, this value will be used to simulate thickness.\r\n     */\r\n    @serialize()\r\n    public minimumThickness: number = 0;\r\n\r\n    /**\r\n     * Defines the maximum thickness stored in the thickness map.\r\n     */\r\n    @serialize()\r\n    public maximumThickness: number = 1;\r\n\r\n    /**\r\n     * Defines that the thickness should be used as a measure of the depth volume.\r\n     */\r\n    @serialize()\r\n    public useThicknessAsDepth = false;\r\n\r\n    /**\r\n     * Defines the volume tint of the material.\r\n     * This is used for both translucency and scattering.\r\n     */\r\n    @serializeAsColor3()\r\n    public tintColor = Color3.White();\r\n\r\n    /**\r\n     * Defines the distance at which the tint color should be found in the media.\r\n     * This is used for refraction only.\r\n     */\r\n    @serialize()\r\n    public tintColorAtDistance = 1;\r\n\r\n    /**\r\n     * Defines the Abbe number for the volume.\r\n     */\r\n    @serialize()\r\n    public dispersion = 0;\r\n\r\n    /**\r\n     * Defines how far each channel transmit through the media.\r\n     * It is defined as a color to simplify it selection.\r\n     */\r\n    @serializeAsColor3()\r\n    public diffusionDistance = Color3.White();\r\n\r\n    private _useMaskFromThicknessTexture = false;\r\n    /**\r\n     * Stores the intensity of the different subsurface effects in the thickness texture.\r\n     * Note that if refractionIntensityTexture and/or translucencyIntensityTexture is provided it takes precedence over thicknessTexture + useMaskFromThicknessTexture\r\n     * * the green (red if useGltfStyleTextures = true) channel is the refraction intensity.\r\n     * * the blue (alpha if useGltfStyleTextures = true) channel is the translucency intensity.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useMaskFromThicknessTexture: boolean = false;\r\n\r\n    private _refractionIntensityTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the intensity of the refraction. If provided, it takes precedence over thicknessTexture + useMaskFromThicknessTexture\r\n     * * the green (red if useGltfStyleTextures = true) channel is the refraction intensity.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor refractionIntensityTexture: Nullable<BaseTexture> = null;\r\n\r\n    private _translucencyIntensityTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Stores the intensity of the translucency. If provided, it takes precedence over thicknessTexture + useMaskFromThicknessTexture\r\n     * * the blue (alpha if useGltfStyleTextures = true) channel is the translucency intensity.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor translucencyIntensityTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Defines the translucency tint of the material.\r\n     * If not set, the tint color will be used instead.\r\n     */\r\n    @serializeAsColor3()\r\n    public translucencyColor: Nullable<Color3> = null;\r\n\r\n    private _translucencyColorTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Defines the translucency tint color of the material as a texture.\r\n     * This is multiplied against the translucency color to add variety and realism to the material.\r\n     * If translucencyColor is not set, the tint color will be used instead.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor translucencyColorTexture: Nullable<BaseTexture> = null;\r\n\r\n    private _useGltfStyleTextures = true;\r\n    /**\r\n     * Use channels layout used by glTF:\r\n     * * thicknessTexture: the green (instead of red) channel is the thickness\r\n     * * thicknessTexture/refractionIntensityTexture: the red (instead of green) channel is the refraction intensity\r\n     * * thicknessTexture/translucencyIntensityTexture: the alpha (instead of blue) channel is the translucency intensity\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useGltfStyleTextures: boolean = true;\r\n\r\n    /**\r\n     * This property only exists for backward compatibility reasons.\r\n     * Set it to true if your rendering in 8.0+ is different from that in 7 when you use sub-surface properties (transmission, refraction, etc.). Default is false.\r\n     * Note however that the PBR calculation is wrong when this property is set to true, so only use it if you want to mimic the 7.0 behavior.\r\n     */\r\n    @serialize()\r\n    public applyAlbedoAfterSubSurface = PBRSubSurfaceConfiguration.DEFAULT_APPLY_ALBEDO_AFTERSUBSURFACE;\r\n\r\n    /**\r\n     * This property only exists for backward compatibility reasons.\r\n     * Set it to true if your rendering in 8.0+ is different from that in 7 when you use sub-surface translucency. Default is false.\r\n     */\r\n    @serialize()\r\n    public legacyTranslucency = PBRSubSurfaceConfiguration.DEFAULT_LEGACY_TRANSLUCENCY;\r\n\r\n    /**\r\n     * Keeping for backward compatibility... Should not be used anymore. It has been replaced by\r\n     * the property with the correct spelling.\r\n     * @see legacyTranslucency\r\n     */\r\n    public get legacyTransluceny(): boolean {\r\n        return this.legacyTranslucency;\r\n    }\r\n    public set legacyTransluceny(value: boolean) {\r\n        this.legacyTranslucency = value;\r\n    }\r\n\r\n    private _scene: Scene;\r\n\r\n    /** @internal */\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n    private _internalMarkScenePrePassDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isRefractionEnabled || this._isTranslucencyEnabled || this._isScatteringEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n    /** @internal */\r\n    public _markScenePrePassDirty(): void {\r\n        this._enable(this._isRefractionEnabled || this._isTranslucencyEnabled || this._isScatteringEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n        this._internalMarkScenePrePassDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: PBRBaseMaterial, addToPluginList = true) {\r\n        super(material, \"PBRSubSurface\", 130, new MaterialSubSurfaceDefines(), addToPluginList);\r\n\r\n        this._scene = material.getScene();\r\n        this.registerForExtraEvents = true;\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n        this._internalMarkScenePrePassDirty = material._dirtyCallbacks[Constants.MATERIAL_PrePassDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks whether the subsurface textures are ready for the sub mesh.\r\n     * @param defines defines the material defines to inspect\r\n     * @param scene defines the scene to use for readiness checks\r\n     * @returns true if subsurface is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: MaterialSubSurfaceDefines, scene: Scene): boolean {\r\n        if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {\r\n            return true;\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            if (scene.texturesEnabled) {\r\n                if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {\r\n                    if (!this._thicknessTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled) {\r\n                    if (!this._refractionIntensityTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled) {\r\n                    if (!this._translucencyColorTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled) {\r\n                    if (!this._translucencyIntensityTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                const refractionTexture = this._getRefractionTexture(scene);\r\n                if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {\r\n                    if (!refractionTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates shader defines for subsurface rendering before attributes are processed.\r\n     * @param defines defines the material defines to update\r\n     * @param scene defines the scene to use for texture checks\r\n     */\r\n    public override prepareDefinesBeforeAttributes(defines: MaterialSubSurfaceDefines, scene: Scene): void {\r\n        if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {\r\n            defines.SUBSURFACE = false;\r\n            defines.SS_DISPERSION = false;\r\n            defines.SS_TRANSLUCENCY = false;\r\n            defines.SS_SCATTERING = false;\r\n            defines.SS_REFRACTION = false;\r\n            defines.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = false;\r\n            defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = false;\r\n            defines.SS_THICKNESSANDMASK_TEXTURE = false;\r\n            defines.SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;\r\n            defines.SS_HAS_THICKNESS = false;\r\n            defines.SS_REFRACTIONINTENSITY_TEXTURE = false;\r\n            defines.SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV = 0;\r\n            defines.SS_TRANSLUCENCYINTENSITY_TEXTURE = false;\r\n            defines.SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV = 0;\r\n            defines.SS_REFRACTIONMAP_3D = false;\r\n            defines.SS_REFRACTIONMAP_OPPOSITEZ = false;\r\n            defines.SS_LODINREFRACTIONALPHA = false;\r\n            defines.SS_GAMMAREFRACTION = false;\r\n            defines.SS_RGBDREFRACTION = false;\r\n            defines.SS_LINEARSPECULARREFRACTION = false;\r\n            defines.SS_LINKREFRACTIONTOTRANSPARENCY = false;\r\n            defines.SS_ALBEDOFORREFRACTIONTINT = false;\r\n            defines.SS_ALBEDOFORTRANSLUCENCYTINT = false;\r\n            defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false;\r\n            defines.SS_USE_THICKNESS_AS_DEPTH = false;\r\n            defines.SS_USE_GLTF_TEXTURES = false;\r\n            defines.SS_TRANSLUCENCYCOLOR_TEXTURE = false;\r\n            defines.SS_TRANSLUCENCYCOLOR_TEXTUREDIRECTUV = 0;\r\n            defines.SS_TRANSLUCENCYCOLOR_TEXTURE_GAMMA = false;\r\n            defines.SS_APPLY_ALBEDO_AFTER_SUBSURFACE = false;\r\n            return;\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            defines.SUBSURFACE = true;\r\n\r\n            defines.SS_DISPERSION = this._isDispersionEnabled;\r\n            defines.SS_TRANSLUCENCY = this._isTranslucencyEnabled;\r\n            defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = false;\r\n            defines.SS_TRANSLUCENCY_LEGACY = this.legacyTranslucency;\r\n            defines.SS_SCATTERING = this._isScatteringEnabled;\r\n            defines.SS_THICKNESSANDMASK_TEXTURE = false;\r\n            defines.SS_REFRACTIONINTENSITY_TEXTURE = false;\r\n            defines.SS_TRANSLUCENCYINTENSITY_TEXTURE = false;\r\n            defines.SS_HAS_THICKNESS = false;\r\n            defines.SS_USE_GLTF_TEXTURES = false;\r\n            defines.SS_REFRACTION = false;\r\n            defines.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = false;\r\n            defines.SS_REFRACTIONMAP_3D = false;\r\n            defines.SS_GAMMAREFRACTION = false;\r\n            defines.SS_RGBDREFRACTION = false;\r\n            defines.SS_LINEARSPECULARREFRACTION = false;\r\n            defines.SS_REFRACTIONMAP_OPPOSITEZ = false;\r\n            defines.SS_LODINREFRACTIONALPHA = false;\r\n            defines.SS_LINKREFRACTIONTOTRANSPARENCY = false;\r\n            defines.SS_ALBEDOFORREFRACTIONTINT = false;\r\n            defines.SS_ALBEDOFORTRANSLUCENCYTINT = false;\r\n            defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false;\r\n            defines.SS_USE_THICKNESS_AS_DEPTH = false;\r\n            defines.SS_TRANSLUCENCYCOLOR_TEXTURE = false;\r\n            defines.SS_APPLY_ALBEDO_AFTER_SUBSURFACE = this.applyAlbedoAfterSubSurface;\r\n\r\n            if (defines._areTexturesDirty) {\r\n                if (scene.texturesEnabled) {\r\n                    if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._thicknessTexture, defines, \"SS_THICKNESSANDMASK_TEXTURE\");\r\n                    }\r\n\r\n                    if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._refractionIntensityTexture, defines, \"SS_REFRACTIONINTENSITY_TEXTURE\");\r\n                    }\r\n\r\n                    if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._translucencyIntensityTexture, defines, \"SS_TRANSLUCENCYINTENSITY_TEXTURE\");\r\n                    }\r\n\r\n                    if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled) {\r\n                        PrepareDefinesForMergedUV(this._translucencyColorTexture, defines, \"SS_TRANSLUCENCYCOLOR_TEXTURE\");\r\n                        defines.SS_TRANSLUCENCYCOLOR_TEXTURE_GAMMA = this._translucencyColorTexture.gammaSpace;\r\n                    }\r\n                }\r\n            }\r\n\r\n            defines.SS_HAS_THICKNESS = this.maximumThickness - this.minimumThickness !== 0.0;\r\n            defines.SS_USE_GLTF_TEXTURES = this._useGltfStyleTextures;\r\n            defines.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = this._useMaskFromThicknessTexture && !this._refractionIntensityTexture;\r\n            defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = this._useMaskFromThicknessTexture && !this._translucencyIntensityTexture;\r\n\r\n            if (this._isRefractionEnabled) {\r\n                if (scene.texturesEnabled) {\r\n                    const refractionTexture = this._getRefractionTexture(scene);\r\n                    if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {\r\n                        defines.SS_REFRACTION = true;\r\n                        defines.SS_REFRACTIONMAP_3D = refractionTexture.isCube;\r\n                        defines.SS_GAMMAREFRACTION = refractionTexture.gammaSpace;\r\n                        defines.SS_RGBDREFRACTION = refractionTexture.isRGBD;\r\n                        defines.SS_LINEARSPECULARREFRACTION = refractionTexture.linearSpecularLOD;\r\n                        defines.SS_REFRACTIONMAP_OPPOSITEZ = this._scene.useRightHandedSystem && refractionTexture.isCube ? !refractionTexture.invertZ : refractionTexture.invertZ;\r\n                        defines.SS_LODINREFRACTIONALPHA = refractionTexture.lodLevelInAlpha;\r\n                        defines.SS_LINKREFRACTIONTOTRANSPARENCY = this._linkRefractionWithTransparency;\r\n                        defines.SS_ALBEDOFORREFRACTIONTINT = this._useAlbedoToTintRefraction;\r\n                        defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = refractionTexture.isCube && (<any>refractionTexture).boundingBoxSize;\r\n                        defines.SS_USE_THICKNESS_AS_DEPTH = this.useThicknessAsDepth;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this._isTranslucencyEnabled) {\r\n                defines.SS_ALBEDOFORTRANSLUCENCYTINT = this._useAlbedoToTintTranslucency;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the material data (this function is called even if mustRebind() returns false)\r\n     * @param uniformBuffer defines the Uniform buffer to fill in.\r\n     * @param scene defines the scene the material belongs to.\r\n     * @param engine defines the engine the material belongs to.\r\n     * @param subMesh the submesh to bind data for\r\n     */\r\n    public override hardBindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void {\r\n        if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {\r\n            return;\r\n        }\r\n\r\n        // If min/max thickness is 0, avoid decompising to determine the scaled thickness (it's always zero).\r\n        if (this.maximumThickness === 0.0 && this.minimumThickness === 0.0) {\r\n            uniformBuffer.updateFloat2(\"vThicknessParam\", 0, 0);\r\n        } else {\r\n            subMesh.getRenderingMesh().getWorldMatrix().decompose(TmpVectors.Vector3[0]);\r\n            const thicknessScale = Math.max(Math.abs(TmpVectors.Vector3[0].x), Math.abs(TmpVectors.Vector3[0].y), Math.abs(TmpVectors.Vector3[0].z));\r\n            uniformBuffer.updateFloat2(\"vThicknessParam\", this.minimumThickness * thicknessScale, (this.maximumThickness - this.minimumThickness) * thicknessScale);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds subsurface data for a sub mesh.\r\n     * @param uniformBuffer defines the uniform buffer to update\r\n     * @param scene defines the scene to use for texture binding\r\n     * @param engine defines the engine used for binding\r\n     * @param subMesh defines the sub mesh being rendered\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void {\r\n        if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {\r\n            return;\r\n        }\r\n\r\n        const defines = subMesh.materialDefines as unknown as MaterialSubSurfaceDefines;\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n        const realTimeFiltering = this._material.realTimeFiltering;\r\n        const lodBasedMicrosurface = defines.LODBASEDMICROSFURACE;\r\n\r\n        const refractionTexture = this._getRefractionTexture(scene);\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {\r\n                uniformBuffer.updateFloat2(\"vThicknessInfos\", this._thicknessTexture.coordinatesIndex, this._thicknessTexture.level);\r\n                BindTextureMatrix(this._thicknessTexture, uniformBuffer, \"thickness\");\r\n            }\r\n\r\n            if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled && defines.SS_REFRACTIONINTENSITY_TEXTURE) {\r\n                uniformBuffer.updateFloat2(\"vRefractionIntensityInfos\", this._refractionIntensityTexture.coordinatesIndex, this._refractionIntensityTexture.level);\r\n                BindTextureMatrix(this._refractionIntensityTexture, uniformBuffer, \"refractionIntensity\");\r\n            }\r\n\r\n            if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled && defines.SS_TRANSLUCENCYCOLOR_TEXTURE) {\r\n                uniformBuffer.updateFloat2(\"vTranslucencyColorInfos\", this._translucencyColorTexture.coordinatesIndex, this._translucencyColorTexture.level);\r\n                BindTextureMatrix(this._translucencyColorTexture, uniformBuffer, \"translucencyColor\");\r\n            }\r\n\r\n            if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled && defines.SS_TRANSLUCENCYINTENSITY_TEXTURE) {\r\n                uniformBuffer.updateFloat2(\"vTranslucencyIntensityInfos\", this._translucencyIntensityTexture.coordinatesIndex, this._translucencyIntensityTexture.level);\r\n                BindTextureMatrix(this._translucencyIntensityTexture, uniformBuffer, \"translucencyIntensity\");\r\n            }\r\n\r\n            if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {\r\n                uniformBuffer.updateMatrix(\"refractionMatrix\", refractionTexture.getRefractionTextureMatrix());\r\n\r\n                let depth = 1.0;\r\n                if (!refractionTexture.isCube) {\r\n                    if ((<any>refractionTexture).depth) {\r\n                        depth = (<any>refractionTexture).depth;\r\n                    }\r\n                }\r\n\r\n                const width = refractionTexture.getSize().width;\r\n                const refractionIor = this.volumeIndexOfRefraction;\r\n                uniformBuffer.updateFloat4(\"vRefractionInfos\", refractionTexture.level, 1 / refractionIor, depth, this._invertRefractionY ? -1 : 1);\r\n                uniformBuffer.updateFloat4(\r\n                    \"vRefractionMicrosurfaceInfos\",\r\n                    width,\r\n                    refractionTexture.lodGenerationScale,\r\n                    refractionTexture.lodGenerationOffset,\r\n                    1.0 / this.indexOfRefraction\r\n                );\r\n\r\n                if (realTimeFiltering) {\r\n                    uniformBuffer.updateFloat2(\"vRefractionFilteringInfo\", width, Math.log2(width));\r\n                }\r\n\r\n                if ((<any>refractionTexture).boundingBoxSize) {\r\n                    const cubeTexture = <CubeTexture>refractionTexture;\r\n\r\n                    uniformBuffer.updateVector3(\"vRefractionPosition\", cubeTexture.boundingBoxPosition);\r\n                    uniformBuffer.updateVector3(\"vRefractionSize\", cubeTexture.boundingBoxSize);\r\n                }\r\n            }\r\n\r\n            if (this._isScatteringEnabled) {\r\n                uniformBuffer.updateFloat(\"scatteringDiffusionProfile\", this._scatteringDiffusionProfileIndex);\r\n            }\r\n            uniformBuffer.updateColor3(\"vDiffusionDistance\", this.diffusionDistance);\r\n\r\n            uniformBuffer.updateFloat4(\"vTintColor\", this.tintColor.r, this.tintColor.g, this.tintColor.b, Math.max(0.00001, this.tintColorAtDistance));\r\n            uniformBuffer.updateColor4(\"vTranslucencyColor\", this.translucencyColor ?? this.tintColor, 0);\r\n\r\n            uniformBuffer.updateFloat3(\"vSubSurfaceIntensity\", this.refractionIntensity, this.translucencyIntensity, 0);\r\n\r\n            uniformBuffer.updateFloat(\"dispersion\", this.dispersion);\r\n        }\r\n\r\n        // Textures\r\n        if (scene.texturesEnabled) {\r\n            if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {\r\n                uniformBuffer.setTexture(\"thicknessSampler\", this._thicknessTexture);\r\n            }\r\n\r\n            if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled && defines.SS_REFRACTIONINTENSITY_TEXTURE) {\r\n                uniformBuffer.setTexture(\"refractionIntensitySampler\", this._refractionIntensityTexture);\r\n            }\r\n\r\n            if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled && defines.SS_TRANSLUCENCYINTENSITY_TEXTURE) {\r\n                uniformBuffer.setTexture(\"translucencyIntensitySampler\", this._translucencyIntensityTexture);\r\n            }\r\n\r\n            if (this._translucencyColorTexture && MaterialFlags.TranslucencyColorTextureEnabled && defines.SS_TRANSLUCENCYCOLOR_TEXTURE) {\r\n                uniformBuffer.setTexture(\"translucencyColorSampler\", this._translucencyColorTexture);\r\n            }\r\n\r\n            if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {\r\n                if (lodBasedMicrosurface) {\r\n                    uniformBuffer.setTexture(\"refractionSampler\", refractionTexture);\r\n                } else {\r\n                    uniformBuffer.setTexture(\"refractionSampler\", refractionTexture._lodTextureMid || refractionTexture);\r\n                    uniformBuffer.setTexture(\"refractionSamplerLow\", refractionTexture._lodTextureLow || refractionTexture);\r\n                    uniformBuffer.setTexture(\"refractionSamplerHigh\", refractionTexture._lodTextureHigh || refractionTexture);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the texture used for refraction or null if none is used.\r\n     * @param scene defines the scene the material belongs to.\r\n     * @returns - Refraction texture if present.  If no refraction texture and refraction\r\n     * is linked with transparency, returns environment texture.  Otherwise, returns null.\r\n     */\r\n    private _getRefractionTexture(scene: Scene): Nullable<BaseTexture> {\r\n        if (this._refractionTexture) {\r\n            return this._refractionTexture;\r\n        }\r\n\r\n        if (this._isRefractionEnabled) {\r\n            return scene.environmentTexture;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Returns true if alpha blending should be disabled.\r\n     */\r\n    public get disableAlphaBlending(): boolean {\r\n        return this._isRefractionEnabled && this._linkRefractionWithTransparency;\r\n    }\r\n\r\n    /**\r\n     * Fills the list of render target textures.\r\n     * @param renderTargets the list of render targets to update\r\n     */\r\n    public override fillRenderTargetTextures(renderTargets: SmartArray<RenderTargetTexture>): void {\r\n        if (MaterialFlags.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {\r\n            renderTargets.push(<RenderTargetTexture>this._refractionTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether subsurface rendering uses a texture.\r\n     * @param texture defines the texture to check\r\n     * @returns true if the texture is used by subsurface rendering\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (this._thicknessTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._refractionTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._refractionIntensityTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._translucencyIntensityTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._translucencyColorTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public override hasRenderTargetTextures(): boolean {\r\n        if (MaterialFlags.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds the active subsurface textures.\r\n     * @param activeTextures defines the list of active textures to update\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this._thicknessTexture) {\r\n            activeTextures.push(this._thicknessTexture);\r\n        }\r\n\r\n        if (this._refractionTexture) {\r\n            activeTextures.push(this._refractionTexture);\r\n        }\r\n\r\n        if (this._refractionIntensityTexture) {\r\n            activeTextures.push(this._refractionIntensityTexture);\r\n        }\r\n\r\n        if (this._translucencyColorTexture) {\r\n            activeTextures.push(this._translucencyColorTexture);\r\n        }\r\n\r\n        if (this._translucencyIntensityTexture) {\r\n            activeTextures.push(this._translucencyIntensityTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the animatable subsurface textures.\r\n     * @param animatables defines the list of animatables to update\r\n     */\r\n    public override getAnimatables(animatables: IAnimatable[]): void {\r\n        if (this._thicknessTexture && this._thicknessTexture.animations && this._thicknessTexture.animations.length > 0) {\r\n            animatables.push(this._thicknessTexture);\r\n        }\r\n\r\n        if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) {\r\n            animatables.push(this._refractionTexture);\r\n        }\r\n\r\n        if (this._refractionIntensityTexture && this._refractionIntensityTexture.animations && this._refractionIntensityTexture.animations.length > 0) {\r\n            animatables.push(this._refractionIntensityTexture);\r\n        }\r\n\r\n        if (this._translucencyColorTexture && this._translucencyColorTexture.animations && this._translucencyColorTexture.animations.length > 0) {\r\n            animatables.push(this._translucencyColorTexture);\r\n        }\r\n\r\n        if (this._translucencyIntensityTexture && this._translucencyIntensityTexture.animations && this._translucencyIntensityTexture.animations.length > 0) {\r\n            animatables.push(this._translucencyIntensityTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the subsurface textures.\r\n     * @param forceDisposeTextures defines whether to dispose the textures\r\n     */\r\n    public override dispose(forceDisposeTextures?: boolean): void {\r\n        if (forceDisposeTextures) {\r\n            if (this._thicknessTexture) {\r\n                this._thicknessTexture.dispose();\r\n            }\r\n\r\n            if (this._refractionTexture) {\r\n                this._refractionTexture.dispose();\r\n            }\r\n\r\n            if (this._refractionIntensityTexture) {\r\n                this._refractionIntensityTexture.dispose();\r\n            }\r\n\r\n            if (this._translucencyColorTexture) {\r\n                this._translucencyColorTexture.dispose();\r\n            }\r\n\r\n            if (this._translucencyIntensityTexture) {\r\n                this._translucencyIntensityTexture.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRSubSurfaceConfiguration\";\r\n    }\r\n\r\n    public override addFallbacks(defines: MaterialSubSurfaceDefines, fallbacks: EffectFallbacks, currentRank: number): number {\r\n        if (defines.SS_SCATTERING) {\r\n            fallbacks.addFallback(currentRank++, \"SS_SCATTERING\");\r\n        }\r\n        if (defines.SS_TRANSLUCENCY) {\r\n            fallbacks.addFallback(currentRank++, \"SS_TRANSLUCENCY\");\r\n        }\r\n        return currentRank;\r\n    }\r\n\r\n    /**\r\n     * Adds the subsurface sampler names.\r\n     * @param samplers defines the list of sampler names to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\r\n            \"thicknessSampler\",\r\n            \"refractionIntensitySampler\",\r\n            \"translucencyIntensitySampler\",\r\n            \"refractionSampler\",\r\n            \"refractionSamplerLow\",\r\n            \"refractionSamplerHigh\",\r\n            \"translucencyColorSampler\"\r\n        );\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vRefractionMicrosurfaceInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"vRefractionFilteringInfo\", size: 2, type: \"vec2\" },\r\n                { name: \"vTranslucencyIntensityInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"vRefractionInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"refractionMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"vThicknessInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"vRefractionIntensityInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"thicknessMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"refractionIntensityMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"translucencyIntensityMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"vThicknessParam\", size: 2, type: \"vec2\" },\r\n                { name: \"vDiffusionDistance\", size: 3, type: \"vec3\" },\r\n                { name: \"vTintColor\", size: 4, type: \"vec4\" },\r\n                { name: \"vSubSurfaceIntensity\", size: 3, type: \"vec3\" },\r\n                { name: \"vRefractionPosition\", size: 3, type: \"vec3\" },\r\n                { name: \"vRefractionSize\", size: 3, type: \"vec3\" },\r\n                { name: \"scatteringDiffusionProfile\", size: 1, type: \"float\" },\r\n                { name: \"dispersion\", size: 1, type: \"float\" },\r\n\r\n                { name: \"vTranslucencyColor\", size: 4, type: \"vec4\" },\r\n                { name: \"vTranslucencyColorInfos\", size: 2, type: \"vec2\" },\r\n                { name: \"translucencyColorMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { expandToProperty } from \"../../Misc/decorators\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { SmartArray } from \"../../Misc/smartArray\";\r\nimport { GetEnvironmentBRDFTexture } from \"../../Misc/brdfTextureTools\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { type Matrix, Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { PBRBRDFConfiguration } from \"./pbrBRDFConfiguration\";\r\nimport { PrePassConfiguration } from \"../prePassConfiguration\";\r\nimport { Color3, TmpColors } from \"../../Maths/math.color.pure\";\r\n\r\nimport { ImageProcessingDefinesMixin } from \"../../Materials/imageProcessingConfiguration.defines\";\r\nimport { ImageProcessingConfiguration } from \"../../Materials/imageProcessingConfiguration.pure\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../../Materials/effect.pure\";\r\nimport { type IMaterialCompilationOptions, type ICustomShaderNameResolveOptions, Material } from \"../../Materials/material.pure\";\r\nimport { MaterialPluginEvent } from \"../materialPluginEvent\";\r\nimport { MaterialDefines } from \"../../Materials/materialDefines\";\r\nimport { PushMaterial } from \"../../Materials/pushMaterial\";\r\n\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\n\r\nimport { MaterialFlags } from \"../materialFlags\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\n\r\nimport { EffectFallbacks } from \"../effectFallbacks\";\r\nimport { PBRClearCoatConfiguration } from \"./pbrClearCoatConfiguration\";\r\nimport { PBRIridescenceConfiguration } from \"./pbrIridescenceConfiguration\";\r\nimport { PBRAnisotropicConfiguration } from \"./pbrAnisotropicConfiguration\";\r\nimport { PBRSheenConfiguration } from \"./pbrSheenConfiguration\";\r\nimport { PBRSubSurfaceConfiguration } from \"./pbrSubSurfaceConfiguration\";\r\nimport { DetailMapConfiguration } from \"../material.detailMapConfiguration\";\r\nimport { AddClipPlaneUniforms, BindClipPlane } from \"../clipPlaneMaterialHelper\";\r\nimport { PrepareVertexPullingUniforms, BindVertexPullingUniforms, type IVertexPullingMetadata } from \"../vertexPullingHelper.functions\";\r\nimport {\r\n    BindBonesParameters,\r\n    BindFogParameters,\r\n    BindLights,\r\n    BindLogDepth,\r\n    BindMorphTargetParameters,\r\n    BindTextureMatrix,\r\n    BindIBLParameters,\r\n    BindIBLSamplers,\r\n    HandleFallbacksForShadows,\r\n    PrepareAttributesForBakedVertexAnimation,\r\n    PrepareAttributesForBones,\r\n    PrepareAttributesForInstances,\r\n    PrepareAttributesForMorphTargets,\r\n    PrepareDefinesForAttributes,\r\n    PrepareDefinesForFrameBoundValues,\r\n    PrepareDefinesForLights,\r\n    PrepareDefinesForIBL,\r\n    PrepareDefinesForMergedUV,\r\n    PrepareDefinesForMisc,\r\n    PrepareDefinesForMultiview,\r\n    PrepareDefinesForOIT,\r\n    PrepareDefinesForPrePass,\r\n    PrepareUniformsAndSamplersList,\r\n    PrepareUniformsAndSamplersForIBL,\r\n    PrepareUniformLayoutForIBL,\r\n    AreLightsTexturesReady,\r\n} from \"../materialHelper.functions\";\r\nimport { _ShaderImportLoader } from \"../../Misc/shaderImportLoader\";\r\nimport { MaterialHelperGeometryRendering } from \"../materialHelper.geometryrendering\";\r\nimport { UVDefinesMixin } from \"../uv.defines\";\r\nimport { PrepassDefinesMixin } from \"../prepass.defines\";\r\nimport { ImageProcessingMixin } from \"../imageProcessing\";\r\n\r\nconst onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };\r\n\r\nclass PBRMaterialDefinesBase extends PrepassDefinesMixin(UVDefinesMixin(MaterialDefines)) {}\r\n\r\n/**\r\n * Manages the defines for the PBR Material.\r\n * @internal\r\n */\r\nexport class PBRMaterialDefines extends ImageProcessingDefinesMixin(PBRMaterialDefinesBase) {\r\n    public PBR = true;\r\n\r\n    public NUM_SAMPLES = \"0\";\r\n    public REALTIME_FILTERING = false;\r\n    public IBL_CDF_FILTERING = false;\r\n\r\n    public ALBEDO = false;\r\n    public GAMMAALBEDO = false;\r\n    public ALBEDODIRECTUV = 0;\r\n    public VERTEXCOLOR = false;\r\n\r\n    public BASE_WEIGHT = false;\r\n    public BASE_WEIGHTDIRECTUV = 0;\r\n    public BASE_DIFFUSE_ROUGHNESS = false;\r\n    public BASE_DIFFUSE_ROUGHNESSDIRECTUV = 0;\r\n\r\n    public BAKED_VERTEX_ANIMATION_TEXTURE = false;\r\n\r\n    public AMBIENT = false;\r\n    public AMBIENTDIRECTUV = 0;\r\n    public AMBIENTINGRAYSCALE = false;\r\n\r\n    public OPACITY = false;\r\n    public VERTEXALPHA = false;\r\n    public OPACITYDIRECTUV = 0;\r\n    public OPACITYRGB = false;\r\n    public ALPHATEST = false;\r\n    public DEPTHPREPASS = false;\r\n    public ALPHABLEND = false;\r\n    public ALPHAFROMALBEDO = false;\r\n    public ALPHATESTVALUE = \"0.5\";\r\n    public SPECULAROVERALPHA = false;\r\n    public RADIANCEOVERALPHA = false;\r\n    public ALPHAFRESNEL = false;\r\n    public LINEARALPHAFRESNEL = false;\r\n    public PREMULTIPLYALPHA = false;\r\n\r\n    public EMISSIVE = false;\r\n    public EMISSIVEDIRECTUV = 0;\r\n    public GAMMAEMISSIVE = false;\r\n\r\n    public REFLECTIVITY = false;\r\n    public REFLECTIVITY_GAMMA = false;\r\n    public REFLECTIVITYDIRECTUV = 0;\r\n    public SPECULARTERM = false;\r\n\r\n    public MICROSURFACEFROMREFLECTIVITYMAP = false;\r\n    public MICROSURFACEAUTOMATIC = false;\r\n    public LODBASEDMICROSFURACE = false;\r\n    public MICROSURFACEMAP = false;\r\n    public MICROSURFACEMAPDIRECTUV = 0;\r\n\r\n    public METALLICWORKFLOW = false;\r\n    public ROUGHNESSSTOREINMETALMAPALPHA = false;\r\n    public ROUGHNESSSTOREINMETALMAPGREEN = false;\r\n    public METALLNESSSTOREINMETALMAPBLUE = false;\r\n    public AOSTOREINMETALMAPRED = false;\r\n    public METALLIC_REFLECTANCE = false;\r\n    public METALLIC_REFLECTANCE_GAMMA = false;\r\n    public METALLIC_REFLECTANCEDIRECTUV = 0;\r\n    public METALLIC_REFLECTANCE_USE_ALPHA_ONLY = false;\r\n    public REFLECTANCE = false;\r\n    public REFLECTANCE_GAMMA = false;\r\n    public REFLECTANCEDIRECTUV = 0;\r\n\r\n    public ENVIRONMENTBRDF = false;\r\n    public ENVIRONMENTBRDF_RGBD = false;\r\n\r\n    public NORMAL = false;\r\n    public TANGENT = false;\r\n    public BUMP = false;\r\n    public BUMPDIRECTUV = 0;\r\n    public OBJECTSPACE_NORMALMAP = false;\r\n    public PARALLAX = false;\r\n    public PARALLAX_RHS = false;\r\n    public PARALLAXOCCLUSION = false;\r\n    public NORMALXYSCALE = true;\r\n\r\n    public LIGHTMAP = false;\r\n    public LIGHTMAPDIRECTUV = 0;\r\n    public USELIGHTMAPASSHADOWMAP = false;\r\n    public GAMMALIGHTMAP = false;\r\n    public RGBDLIGHTMAP = false;\r\n\r\n    public REFLECTION = false;\r\n    public REFLECTIONMAP_3D = false;\r\n    public REFLECTIONMAP_SPHERICAL = false;\r\n    public REFLECTIONMAP_PLANAR = false;\r\n    public REFLECTIONMAP_CUBIC = false;\r\n    public USE_LOCAL_REFLECTIONMAP_CUBIC = false;\r\n    public REFLECTIONMAP_PROJECTION = false;\r\n    public REFLECTIONMAP_SKYBOX = false;\r\n    public REFLECTIONMAP_EXPLICIT = false;\r\n    public REFLECTIONMAP_EQUIRECTANGULAR = false;\r\n    public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;\r\n    public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;\r\n    public INVERTCUBICMAP = false;\r\n    public USESPHERICALFROMREFLECTIONMAP = false;\r\n    public USEIRRADIANCEMAP = false;\r\n    public USE_IRRADIANCE_DOMINANT_DIRECTION = false;\r\n    public USESPHERICALINVERTEX = false;\r\n    public REFLECTIONMAP_OPPOSITEZ = false;\r\n    public LODINREFLECTIONALPHA = false;\r\n    public GAMMAREFLECTION = false;\r\n    public RGBDREFLECTION = false;\r\n    public LINEARSPECULARREFLECTION = false;\r\n    public RADIANCEOCCLUSION = false;\r\n    public HORIZONOCCLUSION = false;\r\n\r\n    public INSTANCES = false;\r\n    public THIN_INSTANCES = false;\r\n    public INSTANCESCOLOR = false;\r\n\r\n    public NUM_BONE_INFLUENCERS = 0;\r\n    public BonesPerMesh = 0;\r\n    public BONETEXTURE = false;\r\n    public BONES_VELOCITY_ENABLED = false;\r\n\r\n    public NONUNIFORMSCALING = false;\r\n\r\n    public MORPHTARGETS = false;\r\n    public MORPHTARGETS_POSITION = false;\r\n    public MORPHTARGETS_NORMAL = false;\r\n    public MORPHTARGETS_TANGENT = false;\r\n    public MORPHTARGETS_UV = false;\r\n    public MORPHTARGETS_UV2 = false;\r\n    public MORPHTARGETS_COLOR = false;\r\n    public MORPHTARGETTEXTURE_HASPOSITIONS = false;\r\n    public MORPHTARGETTEXTURE_HASNORMALS = false;\r\n    public MORPHTARGETTEXTURE_HASTANGENTS = false;\r\n    public MORPHTARGETTEXTURE_HASUVS = false;\r\n    public MORPHTARGETTEXTURE_HASUV2S = false;\r\n    public MORPHTARGETTEXTURE_HASCOLORS = false;\r\n    public NUM_MORPH_INFLUENCERS = 0;\r\n    public MORPHTARGETS_TEXTURE = false;\r\n\r\n    public MULTIVIEW = false;\r\n    public ORDER_INDEPENDENT_TRANSPARENCY = false;\r\n    public ORDER_INDEPENDENT_TRANSPARENCY_16BITS = false;\r\n\r\n    public USEPHYSICALLIGHTFALLOFF = false;\r\n    public USEGLTFLIGHTFALLOFF = false;\r\n    public TWOSIDEDLIGHTING = false;\r\n    public MIRRORED = false;\r\n    public SHADOWFLOAT = false;\r\n    public CLIPPLANE = false;\r\n    public CLIPPLANE2 = false;\r\n    public CLIPPLANE3 = false;\r\n    public CLIPPLANE4 = false;\r\n    public CLIPPLANE5 = false;\r\n    public CLIPPLANE6 = false;\r\n    public POINTSIZE = false;\r\n    public FOG = false;\r\n    public LOGARITHMICDEPTH = false;\r\n    public CAMERA_ORTHOGRAPHIC = false;\r\n    public CAMERA_PERSPECTIVE = false;\r\n    public AREALIGHTSUPPORTED = true;\r\n\r\n    public FORCENORMALFORWARD = false;\r\n\r\n    public SPECULARAA = false;\r\n\r\n    public UNLIT = false;\r\n\r\n    public DECAL_AFTER_DETAIL = false;\r\n\r\n    public TEXTURE_REPETITION_MODE = 0;\r\n\r\n    public DEBUGMODE = 0;\r\n    public USE_VERTEX_PULLING = false;\r\n    public VERTEX_PULLING_USE_INDEX_BUFFER = false;\r\n    public VERTEX_PULLING_INDEX_BUFFER_32BITS = false;\r\n    public RIGHT_HANDED = false;\r\n\r\n    public CLUSTLIGHT_SLICES = 0;\r\n    public CLUSTLIGHT_BATCH = 0;\r\n\r\n    /**\r\n     * Initializes the PBR Material defines.\r\n     * @param externalProperties The external properties\r\n     */\r\n    constructor(externalProperties?: { [name: string]: { type: string; default: any } }) {\r\n        super(externalProperties);\r\n        this.rebuild();\r\n    }\r\n\r\n    /**\r\n     * Resets the PBR Material defines.\r\n     */\r\n    public override reset(): void {\r\n        super.reset();\r\n        this.ALPHATESTVALUE = \"0.5\";\r\n        this.PBR = true;\r\n        this.NORMALXYSCALE = true;\r\n    }\r\n}\r\n\r\nclass PBRBaseMaterialBase extends ImageProcessingMixin(PushMaterial) {}\r\n/**\r\n * The Physically based material base class of BJS.\r\n *\r\n * This offers the main features of a standard PBR material.\r\n * For more information, please refer to the documentation :\r\n * https://doc.babylonjs.com/features/featuresDeepDive/materials/using/introToPBR\r\n * @see [WebGL](https://playground.babylonjs.com/#CGHTSM#1)\r\n * @see [WebGPU](https://playground.babylonjs.com/#CGHTSM#2)\r\n */\r\nexport abstract class PBRBaseMaterial extends PBRBaseMaterialBase {\r\n    /**\r\n     * PBRMaterialTransparencyMode: No transparency mode, Alpha channel is not use.\r\n     */\r\n    public static readonly PBRMATERIAL_OPAQUE = Material.MATERIAL_OPAQUE;\r\n\r\n    /**\r\n     * PBRMaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.\r\n     */\r\n    public static readonly PBRMATERIAL_ALPHATEST = Material.MATERIAL_ALPHATEST;\r\n\r\n    /**\r\n     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.\r\n     */\r\n    public static readonly PBRMATERIAL_ALPHABLEND = Material.MATERIAL_ALPHABLEND;\r\n\r\n    /**\r\n     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.\r\n     * They are also discarded below the alpha cutoff threshold to improve performances.\r\n     */\r\n    public static readonly PBRMATERIAL_ALPHATESTANDBLEND = Material.MATERIAL_ALPHATESTANDBLEND;\r\n\r\n    /**\r\n     * Defines the default value of how much AO map is occluding the analytical lights\r\n     * (point spot...).\r\n     */\r\n    public static DEFAULT_AO_ON_ANALYTICAL_LIGHTS = 0;\r\n\r\n    /**\r\n     * PBRMaterialLightFalloff Physical: light is falling off following the inverse squared distance law.\r\n     */\r\n    public static override readonly LIGHTFALLOFF_PHYSICAL = 0;\r\n\r\n    /**\r\n     * PBRMaterialLightFalloff gltf: light is falling off as described in the gltf moving to PBR document\r\n     * to enhance interoperability with other engines.\r\n     */\r\n    public static override readonly LIGHTFALLOFF_GLTF = 1;\r\n\r\n    /**\r\n     * PBRMaterialLightFalloff Standard: light is falling off like in the standard material\r\n     * to enhance interoperability with other materials.\r\n     */\r\n    public static override readonly LIGHTFALLOFF_STANDARD = 2;\r\n\r\n    /**\r\n     * Force all the PBR materials to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * Intensity of the direct lights e.g. the four lights available in your scene.\r\n     * This impacts both the direct diffuse and specular highlights.\r\n     * @internal\r\n     */\r\n    public _directIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Intensity of the emissive part of the material.\r\n     * This helps controlling the emissive effect without modifying the emissive color.\r\n     * @internal\r\n     */\r\n    public _emissiveIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Intensity of the environment e.g. how much the environment will light the object\r\n     * either through harmonics for rough material or through the reflection for shiny ones.\r\n     * @internal\r\n     */\r\n    public _environmentIntensity: number = 1.0;\r\n\r\n    /**\r\n     * This is a special control allowing the reduction of the specular highlights coming from the\r\n     * four lights of the scene. Those highlights may not be needed in full environment lighting.\r\n     * @internal\r\n     */\r\n    public _specularIntensity: number = 1.0;\r\n\r\n    /**\r\n     * This stores the direct, emissive, environment, and specular light intensities into a Vector4.\r\n     */\r\n    private _lightingInfos: Vector4 = new Vector4(this._directIntensity, this._emissiveIntensity, this._environmentIntensity, this._specularIntensity);\r\n\r\n    /**\r\n     * Debug Control allowing disabling the bump map on this material.\r\n     * @internal\r\n     */\r\n    public _disableBumpMap: boolean = false;\r\n\r\n    /**\r\n     * AKA Diffuse Texture in standard nomenclature.\r\n     * @internal\r\n     */\r\n    public _albedoTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Base Weight texture (multiplier to the diffuse and metal lobes).\r\n     * @internal\r\n     */\r\n    public _baseWeightTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Base Diffuse Roughness texture (roughness of the diffuse lobe).\r\n     * @internal\r\n     */\r\n    public _baseDiffuseRoughnessTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * AKA Occlusion Texture in other nomenclature.\r\n     * @internal\r\n     */\r\n    public _ambientTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * AKA Occlusion Texture Intensity in other nomenclature.\r\n     * @internal\r\n     */\r\n    public _ambientTextureStrength: number = 1.0;\r\n\r\n    /**\r\n     * Defines how much the AO map is occluding the analytical lights (point spot...).\r\n     * 1 means it completely occludes it\r\n     * 0 mean it has no impact\r\n     * @internal\r\n     */\r\n    public _ambientTextureImpactOnAnalyticalLights: number = PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS;\r\n\r\n    /**\r\n     * Stores the alpha values in a texture.\r\n     * @internal\r\n     */\r\n    public _opacityTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Stores the reflection values in a texture.\r\n     * @internal\r\n     */\r\n    public _reflectionTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Stores the emissive values in a texture.\r\n     * @internal\r\n     */\r\n    public _emissiveTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * AKA Specular texture in other nomenclature.\r\n     * @internal\r\n     */\r\n    public _reflectivityTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Used to switch from specular/glossiness to metallic/roughness workflow.\r\n     * @internal\r\n     */\r\n    public _metallicTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Specifies the metallic scalar of the metallic/roughness workflow.\r\n     * Can also be used to scale the metalness values of the metallic texture.\r\n     * @internal\r\n     */\r\n    public _metallic: Nullable<number> = null;\r\n\r\n    /**\r\n     * Specifies the roughness scalar of the metallic/roughness workflow.\r\n     * Can also be used to scale the roughness values of the metallic texture.\r\n     * @internal\r\n     */\r\n    public _roughness: Nullable<number> = null;\r\n\r\n    /**\r\n     * In metallic workflow, specifies an F0 factor to help configuring the material F0.\r\n     * By default the indexOfrefraction is used to compute F0;\r\n     *\r\n     * This is used as a factor against the default reflectance at normal incidence to tweak it.\r\n     *\r\n     * F0 = defaultF0 * metallicF0Factor * metallicReflectanceColor;\r\n     * F90 = metallicReflectanceColor;\r\n     * @internal\r\n     */\r\n    public _metallicF0Factor = 1;\r\n\r\n    /**\r\n     * In metallic workflow, specifies an F0 color.\r\n     * By default the F90 is always 1;\r\n     *\r\n     * Please note that this factor is also used as a factor against the default reflectance at normal incidence.\r\n     *\r\n     * F0 = defaultF0_from_IOR * metallicF0Factor * metallicReflectanceColor\r\n     * F90 = metallicF0Factor;\r\n     * @internal\r\n     */\r\n    public _metallicReflectanceColor = Color3.White();\r\n\r\n    /**\r\n     * Specifies that only the A channel from _metallicReflectanceTexture should be used.\r\n     * If false, both RGB and A channels will be used\r\n     * @internal\r\n     */\r\n    public _useOnlyMetallicFromMetallicReflectanceTexture = false;\r\n\r\n    /**\r\n     * Defines to store metallicReflectanceColor in RGB and metallicF0Factor in A\r\n     * This is multiply against the scalar values defined in the material.\r\n     * @internal\r\n     */\r\n    public _metallicReflectanceTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Defines to store reflectanceColor in RGB\r\n     * This is multiplied against the scalar values defined in the material.\r\n     * If both _reflectanceTexture and _metallicReflectanceTexture textures are provided and _useOnlyMetallicFromMetallicReflectanceTexture\r\n     * is false, _metallicReflectanceTexture takes precedence and _reflectanceTexture is not used\r\n     * @internal\r\n     */\r\n    public _reflectanceTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Used to enable roughness/glossiness fetch from a separate channel depending on the current mode.\r\n     * Gray Scale represents roughness in metallic mode and glossiness in specular mode.\r\n     * @internal\r\n     */\r\n    public _microSurfaceTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Stores surface normal data used to displace a mesh in a texture.\r\n     * @internal\r\n     */\r\n    public _bumpTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Stores the pre-calculated light information of a mesh in a texture.\r\n     * @internal\r\n     */\r\n    public _lightmapTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * The color of a material in ambient lighting.\r\n     * @internal\r\n     */\r\n    public _ambientColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * AKA Diffuse Color in other nomenclature.\r\n     * @internal\r\n     */\r\n    public _albedoColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * Base Weight (multiplier to the diffuse and metal lobes).\r\n     * @internal\r\n     */\r\n    public _baseWeight = 1;\r\n\r\n    /**\r\n     * Base Diffuse Roughness (roughness of the diffuse lobe).\r\n     * Can also be used to scale the corresponding texture.\r\n     * @internal\r\n     */\r\n    public _baseDiffuseRoughness: Nullable<number> = null;\r\n\r\n    /**\r\n     * AKA Specular Color in other nomenclature.\r\n     * @internal\r\n     */\r\n    public _reflectivityColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * The color applied when light is reflected from a material.\r\n     * @internal\r\n     */\r\n    public _reflectionColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * The color applied when light is emitted from a material.\r\n     * @internal\r\n     */\r\n    public _emissiveColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * AKA Glossiness in other nomenclature.\r\n     * @internal\r\n     */\r\n    public _microSurface = 0.9;\r\n\r\n    /**\r\n     * Specifies that the material will use the light map as a show map.\r\n     * @internal\r\n     */\r\n    public _useLightmapAsShadowmap = false;\r\n\r\n    /**\r\n     * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal\r\n     * makes the reflect vector face the model (under horizon).\r\n     * @internal\r\n     */\r\n    public _useHorizonOcclusion = true;\r\n\r\n    /**\r\n     * This parameters will enable/disable radiance occlusion by preventing the radiance to lit\r\n     * too much the area relying on ambient texture to define their ambient occlusion.\r\n     * @internal\r\n     */\r\n    public _useRadianceOcclusion = true;\r\n\r\n    /**\r\n     * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.\r\n     * @internal\r\n     */\r\n    public _useAlphaFromAlbedoTexture = false;\r\n\r\n    /**\r\n     * Specifies that the material will keeps the specular highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good example of that. When sun reflects on it you can not see what is behind.\r\n     * @internal\r\n     */\r\n    public _useSpecularOverAlpha = true;\r\n\r\n    /**\r\n     * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.\r\n     * @internal\r\n     */\r\n    public _useMicroSurfaceFromReflectivityMapAlpha = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the roughness information in its alpha channel.\r\n     * @internal\r\n     */\r\n    public _useRoughnessFromMetallicTextureAlpha = true;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the roughness information in its green channel.\r\n     * @internal\r\n     */\r\n    public _useRoughnessFromMetallicTextureGreen = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the metallness information in its blue channel.\r\n     * @internal\r\n     */\r\n    public _useMetallnessFromMetallicTextureBlue = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the ambient occlusion information in its red channel.\r\n     * @internal\r\n     */\r\n    public _useAmbientOcclusionFromMetallicTextureRed = false;\r\n\r\n    /**\r\n     * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.\r\n     * @internal\r\n     */\r\n    public _useAmbientInGrayScale = false;\r\n\r\n    /**\r\n     * In case the reflectivity map does not contain the microsurface information in its alpha channel,\r\n     * The material will try to infer what glossiness each pixel should be.\r\n     * @internal\r\n     */\r\n    public _useAutoMicroSurfaceFromReflectivityMap = false;\r\n\r\n    /**\r\n     * Defines the  falloff type used in this material.\r\n     * It by default is Physical.\r\n     * @internal\r\n     */\r\n    public _lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL;\r\n\r\n    /**\r\n     * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good example of that. When the street lights reflects on it you can not see what is behind.\r\n     * @internal\r\n     */\r\n    public _useRadianceOverAlpha = true;\r\n\r\n    /**\r\n     * Allows using an object space normal map (instead of tangent space).\r\n     * @internal\r\n     */\r\n    public _useObjectSpaceNormalMap = false;\r\n\r\n    /**\r\n     * Allows using the bump map in parallax mode.\r\n     * @internal\r\n     */\r\n    public _useParallax = false;\r\n\r\n    /**\r\n     * Allows using the bump map in parallax occlusion mode.\r\n     * @internal\r\n     */\r\n    public _useParallaxOcclusion = false;\r\n\r\n    /**\r\n     * Controls the scale bias of the parallax mode.\r\n     * @internal\r\n     */\r\n    public _parallaxScaleBias = 0.05;\r\n\r\n    /**\r\n     * If sets to true, disables all the lights affecting the material.\r\n     * @internal\r\n     */\r\n    public _disableLighting = false;\r\n\r\n    /**\r\n     * Number of Simultaneous lights allowed on the material.\r\n     * @internal\r\n     */\r\n    public _maxSimultaneousLights = 4;\r\n\r\n    /**\r\n     * If sets to true, x component of normal map value will be inverted (x = 1.0 - x).\r\n     * @internal\r\n     */\r\n    public _invertNormalMapX = false;\r\n\r\n    /**\r\n     * If sets to true, y component of normal map value will be inverted (y = 1.0 - y).\r\n     * @internal\r\n     */\r\n    public _invertNormalMapY = false;\r\n\r\n    /**\r\n     * If sets to true and backfaceCulling is false, normals will be flipped on the backside.\r\n     * @internal\r\n     */\r\n    public _twoSidedLighting = false;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     * @internal\r\n     */\r\n    public _alphaCutOff = 0.4;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)\r\n     * @internal\r\n     */\r\n    public _useAlphaFresnel = false;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)\r\n     * @internal\r\n     */\r\n    public _useLinearAlphaFresnel = false;\r\n\r\n    /**\r\n     * Specifies the environment BRDF texture used to compute the scale and offset roughness values\r\n     * from cos theta and roughness:\r\n     * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf\r\n     * @internal\r\n     */\r\n    public _environmentBRDFTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Force the shader to compute irradiance in the fragment shader in order to take bump in account.\r\n     * @internal\r\n     */\r\n    public _forceIrradianceInFragment = false;\r\n\r\n    private _realTimeFiltering: boolean = false;\r\n    /**\r\n     * Enables realtime filtering on the texture.\r\n     */\r\n    public get realTimeFiltering() {\r\n        return this._realTimeFiltering;\r\n    }\r\n    public set realTimeFiltering(b: boolean) {\r\n        this._realTimeFiltering = b;\r\n        this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private _realTimeFilteringQuality: number = Constants.TEXTURE_FILTERING_QUALITY_LOW;\r\n    /**\r\n     * Quality switch for realtime filtering\r\n     */\r\n    public get realTimeFilteringQuality(): number {\r\n        return this._realTimeFilteringQuality;\r\n    }\r\n    public set realTimeFilteringQuality(n: number) {\r\n        this._realTimeFilteringQuality = n;\r\n        this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Can this material render to several textures at once\r\n     */\r\n    public override get canRenderToMRT() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Force normal to face away from face.\r\n     * @internal\r\n     */\r\n    public _forceNormalForward = false;\r\n\r\n    /**\r\n     * Enables specular anti aliasing in the PBR shader.\r\n     * It will both interacts on the Geometry for analytical and IBL lighting.\r\n     * It also prefilter the roughness map based on the bump values.\r\n     * @internal\r\n     */\r\n    public _enableSpecularAntiAliasing = false;\r\n\r\n    /**\r\n     * Stores the available render targets.\r\n     */\r\n    private _renderTargets = new SmartArray<RenderTargetTexture>(16);\r\n\r\n    /**\r\n     * Sets the global ambient color for the material used in lighting calculations.\r\n     */\r\n    private _globalAmbientColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * If set to true, no lighting calculations will be applied.\r\n     * @internal\r\n     */\r\n    public _unlit = false;\r\n\r\n    /**\r\n     * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false)\r\n     */\r\n    private _applyDecalMapAfterDetailMap = false;\r\n\r\n    private _debugMode = 0;\r\n\r\n    private static readonly _ShaderLoader = /*#__PURE__*/ new _ShaderImportLoader(\r\n        () => [import(\"../../Shaders/pbr.vertex\"), import(\"../../Shaders/pbr.fragment\")],\r\n        () => [import(\"../../ShadersWGSL/pbr.vertex\"), import(\"../../ShadersWGSL/pbr.fragment\")]\r\n    );\r\n    private _breakShaderLoadedCheck = false;\r\n    private _vertexPullingMetadata: Map<string, IVertexPullingMetadata> | null = null;\r\n\r\n    /**\r\n     * @internal\r\n     * This is reserved for the inspector.\r\n     * Defines the material debug mode.\r\n     * It helps seeing only some components of the material while troubleshooting.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor debugMode = 0;\r\n\r\n    /**\r\n     * @internal\r\n     * This is reserved for the inspector.\r\n     * Specify from where on screen the debug mode should start.\r\n     * The value goes from -1 (full screen) to 1 (not visible)\r\n     * It helps with side by side comparison against the final render\r\n     * This defaults to -1\r\n     */\r\n    public debugLimit = -1;\r\n\r\n    /**\r\n     * @internal\r\n     * This is reserved for the inspector.\r\n     * As the default viewing range might not be enough (if the ambient is really small for instance)\r\n     * You can use the factor to better multiply the final value.\r\n     */\r\n    public debugFactor = 1;\r\n\r\n    /**\r\n     * Defines the clear coat layer parameters for the material.\r\n     */\r\n    public readonly clearCoat: PBRClearCoatConfiguration;\r\n\r\n    /**\r\n     * Defines the iridescence layer parameters for the material.\r\n     */\r\n    public readonly iridescence: PBRIridescenceConfiguration;\r\n\r\n    /**\r\n     * Defines the anisotropic parameters for the material.\r\n     */\r\n    public readonly anisotropy: PBRAnisotropicConfiguration;\r\n\r\n    /**\r\n     * Defines the BRDF parameters for the material.\r\n     */\r\n    public readonly brdf: PBRBRDFConfiguration;\r\n\r\n    /**\r\n     * Defines the Sheen parameters for the material.\r\n     */\r\n    public readonly sheen: PBRSheenConfiguration;\r\n\r\n    /**\r\n     * Defines the SubSurface parameters for the material.\r\n     */\r\n    public readonly subSurface: PBRSubSurfaceConfiguration;\r\n\r\n    /**\r\n     * Defines additional PrePass parameters for the material.\r\n     */\r\n    public readonly prePassConfiguration: PrePassConfiguration;\r\n\r\n    /**\r\n     * Defines the detail map parameters for the material.\r\n     */\r\n    public readonly detailMap: DetailMapConfiguration;\r\n\r\n    protected _cacheHasRenderTargetTextures = false;\r\n\r\n    /**\r\n     * Instantiates a new PBRMaterial instance.\r\n     *\r\n     * @param name The material name\r\n     * @param scene The scene the material will be use in.\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(name: string, scene?: Scene, forceGLSL = false) {\r\n        super(name, scene, undefined, forceGLSL || PBRBaseMaterial.ForceGLSL);\r\n\r\n        this.brdf = new PBRBRDFConfiguration(this);\r\n        this.clearCoat = new PBRClearCoatConfiguration(this);\r\n        this.iridescence = new PBRIridescenceConfiguration(this);\r\n        this.anisotropy = new PBRAnisotropicConfiguration(this);\r\n        this.sheen = new PBRSheenConfiguration(this);\r\n        this.subSurface = new PBRSubSurfaceConfiguration(this);\r\n        this.detailMap = new DetailMapConfiguration(this);\r\n\r\n        // Setup the default processing configuration to the scene.\r\n        this._attachImageProcessingConfiguration(null);\r\n\r\n        this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {\r\n            this._renderTargets.reset();\r\n\r\n            if (MaterialFlags.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n                this._renderTargets.push(<RenderTargetTexture>this._reflectionTexture);\r\n            }\r\n\r\n            this._eventInfo.renderTargets = this._renderTargets;\r\n            this._callbackPluginEventFillRenderTargetTextures(this._eventInfo);\r\n\r\n            return this._renderTargets;\r\n        };\r\n\r\n        this._environmentBRDFTexture = GetEnvironmentBRDFTexture(this.getScene());\r\n        this.prePassConfiguration = new PrePassConfiguration();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     */\r\n    public override get hasRenderTargetTextures(): boolean {\r\n        if (MaterialFlags.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        return this._cacheHasRenderTargetTextures;\r\n    }\r\n\r\n    /**\r\n     * Can this material render to prepass\r\n     */\r\n    public override get isPrePassCapable(): boolean {\r\n        return !this.disableDepthWrite;\r\n    }\r\n\r\n    /**\r\n     * @returns the name of the material class.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PBRBaseMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Returns true if alpha blending should be disabled.\r\n     */\r\n    protected override get _disableAlphaBlending(): boolean {\r\n        return (\r\n            this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_OPAQUE ||\r\n            this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST ||\r\n            this.subSurface?.disableAlphaBlending\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not this material should be rendered in alpha blend mode.\r\n     */\r\n    public override needAlphaBlending(): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsBlend;\r\n        }\r\n\r\n        if (this._disableAlphaBlending) {\r\n            return false;\r\n        }\r\n\r\n        return this.alpha < 1.0 || this._opacityTexture != null || this._shouldUseAlphaFromAlbedoTexture();\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not this material should be rendered in alpha test mode.\r\n     */\r\n    public override needAlphaTesting(): boolean {\r\n        if (this._hasTransparencyMode) {\r\n            return this._transparencyModeIsTest;\r\n        }\r\n\r\n        if (this.subSurface?.disableAlphaBlending) {\r\n            return false;\r\n        }\r\n\r\n        return this._hasAlphaChannel() && (this._transparencyMode == null || this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST);\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not the alpha value of the albedo texture should be used for alpha blending.\r\n     */\r\n    protected _shouldUseAlphaFromAlbedoTexture(): boolean {\r\n        return this._albedoTexture != null && this._albedoTexture.hasAlpha && this._useAlphaFromAlbedoTexture && this._transparencyMode !== PBRBaseMaterial.PBRMATERIAL_OPAQUE;\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not there is a usable alpha channel for transparency.\r\n     */\r\n    protected _hasAlphaChannel(): boolean {\r\n        return (this._albedoTexture != null && this._albedoTexture.hasAlpha) || this._opacityTexture != null;\r\n    }\r\n\r\n    /**\r\n     * @returns the texture used for the alpha test.\r\n     */\r\n    public override getAlphaTestTexture(): Nullable<BaseTexture> {\r\n        return this._albedoTexture;\r\n    }\r\n\r\n    /**\r\n     * Specifies that the submesh is ready to be used.\r\n     * @param mesh - BJS mesh.\r\n     * @param subMesh - A submesh of the BJS mesh.  Used to check if it is ready.\r\n     * @param useInstances - Specifies that instances should be used.\r\n     * @returns - boolean indicating that the submesh is ready or not.\r\n     */\r\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {\r\n        if (!this._uniformBufferLayoutBuilt) {\r\n            this.buildUniformLayout();\r\n        }\r\n\r\n        const drawWrapper = subMesh._drawWrapper;\r\n\r\n        if (drawWrapper.effect && this.isFrozen) {\r\n            if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (!subMesh.materialDefines) {\r\n            this._callbackPluginEventGeneric(MaterialPluginEvent.GetDefineNames, this._eventInfo);\r\n            subMesh.materialDefines = new PBRMaterialDefines(this._eventInfo.defineNames);\r\n        }\r\n\r\n        const defines = <PBRMaterialDefines>subMesh.materialDefines;\r\n        if (this._isReadyForSubMesh(subMesh)) {\r\n            return true;\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        if (defines._areTexturesDirty) {\r\n            this._eventInfo.hasRenderTargetTextures = false;\r\n            this._callbackPluginEventHasRenderTargetTextures(this._eventInfo);\r\n            this._cacheHasRenderTargetTextures = this._eventInfo.hasRenderTargetTextures;\r\n            if (scene.texturesEnabled) {\r\n                if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                    if (!this._albedoTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {\r\n                    if (!this._baseWeightTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._baseDiffuseRoughnessTexture && MaterialFlags.BaseDiffuseRoughnessTextureEnabled) {\r\n                    if (!this._baseDiffuseRoughnessTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {\r\n                    if (!this._ambientTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {\r\n                    if (!this._opacityTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                const reflectionTexture = this._getReflectionTexture();\r\n                if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    if (!reflectionTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                    if (reflectionTexture.irradianceTexture) {\r\n                        if (!reflectionTexture.irradianceTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    } else {\r\n                        // Not ready until spherical are ready too.\r\n                        if (!reflectionTexture.sphericalPolynomial && reflectionTexture.getInternalTexture()?._sphericalPolynomialPromise) {\r\n                            return false;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {\r\n                    if (!this._lightmapTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {\r\n                    if (!this._emissiveTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (MaterialFlags.SpecularTextureEnabled) {\r\n                    if (this._metallicTexture) {\r\n                        if (!this._metallicTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    } else if (this._reflectivityTexture) {\r\n                        if (!this._reflectivityTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    }\r\n\r\n                    if (this._metallicReflectanceTexture) {\r\n                        if (!this._metallicReflectanceTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    }\r\n\r\n                    if (this._reflectanceTexture) {\r\n                        if (!this._reflectanceTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    }\r\n\r\n                    if (this._microSurfaceTexture) {\r\n                        if (!this._microSurfaceTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (engine.getCaps().standardDerivatives && this._bumpTexture && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {\r\n                    // Bump texture cannot be not blocking.\r\n                    if (!this._bumpTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    // This is blocking.\r\n                    if (!this._environmentBRDFTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._eventInfo.isReadyForSubMesh = true;\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);\r\n\r\n        if (!this._eventInfo.isReadyForSubMesh) {\r\n            return false;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {\r\n            if (!this._imageProcessingConfiguration.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        // Check if Area Lights have LTC texture.\r\n        if (defines[\"AREALIGHTUSED\"] || defines[\"CLUSTLIGHT_BATCH\"]) {\r\n            for (let index = 0; index < mesh.lightSources.length; index++) {\r\n                if (!mesh.lightSources[index]._isReady()) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!engine.getCaps().standardDerivatives && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            mesh.createNormals(true);\r\n            Logger.Warn(\"PBRMaterial: Normals have been created for the mesh: \" + mesh.name);\r\n        }\r\n\r\n        if (!AreLightsTexturesReady(scene, mesh, this._maxSimultaneousLights, this._disableLighting)) {\r\n            return false;\r\n        }\r\n\r\n        const previousEffect = subMesh.effect;\r\n        const lightDisposed = defines._areLightsDisposed;\r\n        const effect = this._prepareEffect(mesh, subMesh.getRenderingMesh(), defines, this.onCompiled, this.onError, useInstances, null);\r\n\r\n        let forceWasNotReadyPreviously = false;\r\n\r\n        if (effect) {\r\n            if (this._onEffectCreatedObservable) {\r\n                onCreatedEffectParameters.effect = effect;\r\n                onCreatedEffectParameters.subMesh = subMesh;\r\n                this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);\r\n            }\r\n\r\n            // Use previous effect while new one is compiling\r\n            if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {\r\n                defines.markAsUnprocessed();\r\n\r\n                forceWasNotReadyPreviously = this.isFrozen;\r\n\r\n                if (lightDisposed) {\r\n                    // re register in case it takes more than one frame.\r\n                    defines._areLightsDisposed = true;\r\n                    return false;\r\n                }\r\n            } else {\r\n                scene.resetCachedMaterial();\r\n                subMesh.setEffect(effect, defines, this._materialContext);\r\n            }\r\n        }\r\n\r\n        if (!subMesh.effect || !subMesh.effect.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        defines._renderId = scene.getRenderId();\r\n        drawWrapper._wasPreviouslyReady = forceWasNotReadyPreviously ? false : true;\r\n        drawWrapper._wasPreviouslyUsingInstances = !!useInstances;\r\n\r\n        this._checkScenePerformancePriority();\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the material uses metallic roughness workflow.\r\n     * @returns boolean specifying if the material uses metallic roughness workflow.\r\n     */\r\n    public isMetallicWorkflow(): boolean {\r\n        if (this._metallic != null || this._roughness != null || this._metallicTexture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    private _prepareEffect(\r\n        mesh: AbstractMesh,\r\n        renderingMesh: AbstractMesh,\r\n        defines: PBRMaterialDefines,\r\n        onCompiled: Nullable<(effect: Effect) => void> = null,\r\n        onError: Nullable<(effect: Effect, errors: string) => void> = null,\r\n        useInstances: Nullable<boolean> = null,\r\n        useClipPlane: Nullable<boolean> = null\r\n    ): Nullable<Effect> {\r\n        this._prepareDefines(mesh, renderingMesh, defines, useInstances, useClipPlane);\r\n\r\n        if (!defines.isDirty) {\r\n            return null;\r\n        }\r\n\r\n        defines.markAsProcessed();\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        // Fallbacks\r\n        const fallbacks = new EffectFallbacks();\r\n        let fallbackRank = 0;\r\n        if (defines.USESPHERICALINVERTEX) {\r\n            fallbacks.addFallback(fallbackRank++, \"USESPHERICALINVERTEX\");\r\n        }\r\n\r\n        if (defines.FOG) {\r\n            fallbacks.addFallback(fallbackRank, \"FOG\");\r\n        }\r\n        if (defines.SPECULARAA) {\r\n            fallbacks.addFallback(fallbackRank, \"SPECULARAA\");\r\n        }\r\n        if (defines.POINTSIZE) {\r\n            fallbacks.addFallback(fallbackRank, \"POINTSIZE\");\r\n        }\r\n        if (defines.LOGARITHMICDEPTH) {\r\n            fallbacks.addFallback(fallbackRank, \"LOGARITHMICDEPTH\");\r\n        }\r\n        if (defines.PARALLAX) {\r\n            fallbacks.addFallback(fallbackRank, \"PARALLAX\");\r\n        }\r\n        if (defines.PARALLAX_RHS) {\r\n            fallbacks.addFallback(fallbackRank, \"PARALLAX_RHS\");\r\n        }\r\n        if (defines.PARALLAXOCCLUSION) {\r\n            fallbacks.addFallback(fallbackRank++, \"PARALLAXOCCLUSION\");\r\n        }\r\n\r\n        if (defines.ENVIRONMENTBRDF) {\r\n            fallbacks.addFallback(fallbackRank++, \"ENVIRONMENTBRDF\");\r\n        }\r\n\r\n        if (defines.TANGENT) {\r\n            fallbacks.addFallback(fallbackRank++, \"TANGENT\");\r\n        }\r\n\r\n        if (defines.BUMP) {\r\n            fallbacks.addFallback(fallbackRank++, \"BUMP\");\r\n        }\r\n\r\n        fallbackRank = HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank);\r\n\r\n        if (defines.SPECULARTERM) {\r\n            fallbacks.addFallback(fallbackRank++, \"SPECULARTERM\");\r\n        }\r\n\r\n        if (defines.USESPHERICALFROMREFLECTIONMAP) {\r\n            fallbacks.addFallback(fallbackRank++, \"USESPHERICALFROMREFLECTIONMAP\");\r\n        }\r\n\r\n        if (defines.USEIRRADIANCEMAP) {\r\n            fallbacks.addFallback(fallbackRank++, \"USEIRRADIANCEMAP\");\r\n        }\r\n\r\n        if (defines.LIGHTMAP) {\r\n            fallbacks.addFallback(fallbackRank++, \"LIGHTMAP\");\r\n        }\r\n\r\n        if (defines.NORMAL) {\r\n            fallbacks.addFallback(fallbackRank++, \"NORMAL\");\r\n        }\r\n\r\n        if (defines.AMBIENT) {\r\n            fallbacks.addFallback(fallbackRank++, \"AMBIENT\");\r\n        }\r\n\r\n        if (defines.EMISSIVE) {\r\n            fallbacks.addFallback(fallbackRank++, \"EMISSIVE\");\r\n        }\r\n\r\n        if (defines.VERTEXCOLOR) {\r\n            fallbacks.addFallback(fallbackRank++, \"VERTEXCOLOR\");\r\n        }\r\n\r\n        if (defines.MORPHTARGETS) {\r\n            fallbacks.addFallback(fallbackRank++, \"MORPHTARGETS\");\r\n        }\r\n\r\n        if (defines.MULTIVIEW) {\r\n            fallbacks.addFallback(0, \"MULTIVIEW\");\r\n        }\r\n\r\n        //Attributes\r\n        const attribs = [VertexBuffer.PositionKind];\r\n\r\n        if (defines.NORMAL) {\r\n            attribs.push(VertexBuffer.NormalKind);\r\n        }\r\n\r\n        if (defines.TANGENT) {\r\n            attribs.push(VertexBuffer.TangentKind);\r\n        }\r\n\r\n        for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n            if (defines[\"UV\" + i]) {\r\n                attribs.push(`uv${i === 1 ? \"\" : i}`);\r\n            }\r\n        }\r\n\r\n        if (defines.VERTEXCOLOR) {\r\n            attribs.push(VertexBuffer.ColorKind);\r\n        }\r\n\r\n        PrepareAttributesForBones(attribs, mesh, defines, fallbacks);\r\n        PrepareAttributesForInstances(attribs, defines);\r\n        PrepareAttributesForMorphTargets(attribs, mesh, defines);\r\n        PrepareAttributesForBakedVertexAnimation(attribs, mesh, defines);\r\n\r\n        let shaderName = \"pbr\";\r\n\r\n        const uniforms = [\r\n            \"world\",\r\n            \"view\",\r\n            \"viewProjection\",\r\n            \"vEyePosition\",\r\n            \"vLightsType\",\r\n            \"vAmbientColor\",\r\n            \"vAlbedoColor\",\r\n            \"baseWeight\",\r\n            \"baseDiffuseRoughness\",\r\n            \"vReflectivityColor\",\r\n            \"vMetallicReflectanceFactors\",\r\n            \"vEmissiveColor\",\r\n            \"visibility\",\r\n            \"vFogInfos\",\r\n            \"vFogColor\",\r\n            \"pointSize\",\r\n            \"vAlbedoInfos\",\r\n            \"vBaseWeightInfos\",\r\n            \"vBaseDiffuseRoughnessInfos\",\r\n            \"vAmbientInfos\",\r\n            \"vOpacityInfos\",\r\n            \"vEmissiveInfos\",\r\n            \"vReflectivityInfos\",\r\n            \"vMetallicReflectanceInfos\",\r\n            \"vReflectanceInfos\",\r\n            \"vMicroSurfaceSamplerInfos\",\r\n            \"vBumpInfos\",\r\n            \"vLightmapInfos\",\r\n            \"mBones\",\r\n            \"albedoMatrix\",\r\n            \"baseWeightMatrix\",\r\n            \"baseDiffuseRoughnessMatrix\",\r\n            \"ambientMatrix\",\r\n            \"opacityMatrix\",\r\n            \"emissiveMatrix\",\r\n            \"reflectivityMatrix\",\r\n            \"normalMatrix\",\r\n            \"microSurfaceSamplerMatrix\",\r\n            \"bumpMatrix\",\r\n            \"lightmapMatrix\",\r\n            \"metallicReflectanceMatrix\",\r\n            \"reflectanceMatrix\",\r\n            \"vLightingIntensity\",\r\n            \"logarithmicDepthConstant\",\r\n            \"vTangentSpaceParams\",\r\n            \"boneTextureInfo\",\r\n            \"vDebugMode\",\r\n            \"morphTargetTextureInfo\",\r\n            \"morphTargetTextureIndices\",\r\n            \"cameraInfo\",\r\n            \"vTextureRepetitionHexTilingParams\",\r\n        ];\r\n\r\n        const samplers = [\r\n            \"albedoSampler\",\r\n            \"baseWeightSampler\",\r\n            \"baseDiffuseRoughnessSampler\",\r\n            \"reflectivitySampler\",\r\n            \"ambientSampler\",\r\n            \"emissiveSampler\",\r\n            \"bumpSampler\",\r\n            \"lightmapSampler\",\r\n            \"opacitySampler\",\r\n            \"microSurfaceSampler\",\r\n            \"environmentBrdfSampler\",\r\n            \"boneSampler\",\r\n            \"metallicReflectanceSampler\",\r\n            \"reflectanceSampler\",\r\n            \"morphTargets\",\r\n            \"oitDepthSampler\",\r\n            \"oitFrontColorSampler\",\r\n            \"areaLightsLTC1Sampler\",\r\n            \"areaLightsLTC2Sampler\",\r\n        ];\r\n\r\n        PrepareUniformsAndSamplersForIBL(uniforms, samplers, true);\r\n\r\n        const uniformBuffers = [\"Material\", \"Scene\", \"Mesh\"];\r\n\r\n        const indexParameters = { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS };\r\n\r\n        this._eventInfo.fallbacks = fallbacks;\r\n        this._eventInfo.fallbackRank = fallbackRank;\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.uniforms = uniforms;\r\n        this._eventInfo.attributes = attribs;\r\n        this._eventInfo.samplers = samplers;\r\n        this._eventInfo.uniformBuffersNames = uniformBuffers;\r\n        this._eventInfo.customCode = undefined;\r\n        this._eventInfo.mesh = mesh;\r\n        this._eventInfo.indexParameters = indexParameters;\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.PrepareEffect, this._eventInfo);\r\n\r\n        MaterialHelperGeometryRendering.AddUniformsAndSamplers(uniforms, samplers);\r\n\r\n        PrePassConfiguration.AddUniforms(uniforms);\r\n        PrePassConfiguration.AddSamplers(samplers);\r\n        AddClipPlaneUniforms(uniforms);\r\n\r\n        // Vertex pulling metadata uniforms\r\n        if (this._useVertexPulling) {\r\n            const geometry = (renderingMesh as Mesh)?.geometry;\r\n            if (geometry) {\r\n                this._vertexPullingMetadata = PrepareVertexPullingUniforms(geometry);\r\n                if (this._vertexPullingMetadata) {\r\n                    this._vertexPullingMetadata.forEach((_, attribute) => {\r\n                        uniforms.push(`vp_${attribute}_info`);\r\n                    });\r\n                }\r\n            }\r\n        } else {\r\n            this._vertexPullingMetadata = null;\r\n        }\r\n\r\n        if (ImageProcessingConfiguration) {\r\n            ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);\r\n            ImageProcessingConfiguration.PrepareSamplers(samplers, defines);\r\n        }\r\n\r\n        PrepareUniformsAndSamplersList(<IEffectCreationOptions>{\r\n            uniformsNames: uniforms,\r\n            uniformBuffersNames: uniformBuffers,\r\n            samplers: samplers,\r\n            defines: defines,\r\n            maxSimultaneousLights: this._maxSimultaneousLights,\r\n            shaderLanguage: this._shaderLanguage,\r\n        });\r\n\r\n        const csnrOptions: ICustomShaderNameResolveOptions = {};\r\n\r\n        if (this.customShaderNameResolve) {\r\n            shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines, attribs, csnrOptions);\r\n        }\r\n\r\n        const join = defines.toString();\r\n        const effect = engine.createEffect(\r\n            shaderName,\r\n            <IEffectCreationOptions>{\r\n                attributes: attribs,\r\n                uniformsNames: uniforms,\r\n                uniformBuffersNames: uniformBuffers,\r\n                samplers: samplers,\r\n                defines: join,\r\n                fallbacks: fallbacks,\r\n                onCompiled: onCompiled,\r\n                onError: onError,\r\n                indexParameters,\r\n                processFinalCode: csnrOptions.processFinalCode,\r\n                processCodeAfterIncludes: this._eventInfo.customCode,\r\n                multiTarget: defines.PREPASS,\r\n                shaderLanguage: this._shaderLanguage,\r\n                extraInitializationsAsync: PBRBaseMaterial._ShaderLoader.getLoadCallback(this._shaderLanguage),\r\n            },\r\n            engine\r\n        );\r\n\r\n        this._eventInfo.customCode = undefined;\r\n\r\n        return effect;\r\n    }\r\n\r\n    private _prepareDefines(\r\n        mesh: AbstractMesh,\r\n        renderingMesh: AbstractMesh,\r\n        defines: PBRMaterialDefines,\r\n        useInstances: Nullable<boolean> = null,\r\n        useClipPlane: Nullable<boolean> = null\r\n    ): void {\r\n        const useThinInstances = renderingMesh.hasThinInstances;\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        // Lights\r\n        PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);\r\n        defines._needNormals = true;\r\n\r\n        // Multiview\r\n        PrepareDefinesForMultiview(scene, defines);\r\n\r\n        // PrePass\r\n        const oit = this.needAlphaBlendingForMesh(mesh) && this.getScene().useOrderIndependentTransparency;\r\n        PrepareDefinesForPrePass(scene, defines, this.canRenderToMRT && !oit);\r\n\r\n        // Order independant transparency\r\n        PrepareDefinesForOIT(scene, defines, oit);\r\n\r\n        MaterialHelperGeometryRendering.PrepareDefines(engine.currentRenderPassId, mesh, defines);\r\n\r\n        // Textures\r\n        defines.METALLICWORKFLOW = this.isMetallicWorkflow();\r\n        if (defines._areTexturesDirty) {\r\n            defines._needUVs = false;\r\n            for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n                defines[\"MAINUV\" + i] = false;\r\n            }\r\n            if (scene.texturesEnabled) {\r\n                defines.ALBEDODIRECTUV = 0;\r\n                defines.BASE_WEIGHTDIRECTUV = 0;\r\n                defines.BASE_DIFFUSE_ROUGHNESSDIRECTUV = 0;\r\n                defines.AMBIENTDIRECTUV = 0;\r\n                defines.OPACITYDIRECTUV = 0;\r\n                defines.EMISSIVEDIRECTUV = 0;\r\n                defines.REFLECTIVITYDIRECTUV = 0;\r\n                defines.MICROSURFACEMAPDIRECTUV = 0;\r\n                defines.METALLIC_REFLECTANCEDIRECTUV = 0;\r\n                defines.REFLECTANCEDIRECTUV = 0;\r\n                defines.BUMPDIRECTUV = 0;\r\n                defines.LIGHTMAPDIRECTUV = 0;\r\n\r\n                if (engine.getCaps().textureLOD) {\r\n                    defines.LODBASEDMICROSFURACE = true;\r\n                }\r\n\r\n                if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._albedoTexture, defines, \"ALBEDO\");\r\n                    defines.GAMMAALBEDO = this._albedoTexture.gammaSpace;\r\n                } else {\r\n                    defines.ALBEDO = false;\r\n                }\r\n\r\n                if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._baseWeightTexture, defines, \"BASE_WEIGHT\");\r\n                } else {\r\n                    defines.BASE_WEIGHT = false;\r\n                }\r\n\r\n                if (this._baseDiffuseRoughnessTexture && MaterialFlags.BaseDiffuseRoughnessTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._baseDiffuseRoughnessTexture, defines, \"BASE_DIFFUSE_ROUGHNESS\");\r\n                } else {\r\n                    defines.BASE_DIFFUSE_ROUGHNESS = false;\r\n                }\r\n\r\n                if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._ambientTexture, defines, \"AMBIENT\");\r\n                    defines.AMBIENTINGRAYSCALE = this._useAmbientInGrayScale;\r\n                } else {\r\n                    defines.AMBIENT = false;\r\n                }\r\n\r\n                if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._opacityTexture, defines, \"OPACITY\");\r\n                    defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;\r\n                } else {\r\n                    defines.OPACITY = false;\r\n                }\r\n\r\n                const reflectionTexture = this._getReflectionTexture();\r\n                const useSHInFragment: boolean =\r\n                    this._forceIrradianceInFragment ||\r\n                    this.realTimeFiltering ||\r\n                    this._twoSidedLighting ||\r\n                    engine.getCaps().maxVaryingVectors <= 8 ||\r\n                    this._baseDiffuseRoughnessTexture != null;\r\n                PrepareDefinesForIBL(scene, reflectionTexture, defines, this.realTimeFiltering, this.realTimeFilteringQuality, !useSHInFragment);\r\n\r\n                if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._lightmapTexture, defines, \"LIGHTMAP\");\r\n                    defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;\r\n                    defines.GAMMALIGHTMAP = this._lightmapTexture.gammaSpace;\r\n                    defines.RGBDLIGHTMAP = this._lightmapTexture.isRGBD;\r\n                } else {\r\n                    defines.LIGHTMAP = false;\r\n                }\r\n\r\n                if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {\r\n                    PrepareDefinesForMergedUV(this._emissiveTexture, defines, \"EMISSIVE\");\r\n                    defines.GAMMAEMISSIVE = this._emissiveTexture.gammaSpace;\r\n                } else {\r\n                    defines.EMISSIVE = false;\r\n                }\r\n\r\n                if (MaterialFlags.SpecularTextureEnabled) {\r\n                    if (this._metallicTexture) {\r\n                        PrepareDefinesForMergedUV(this._metallicTexture, defines, \"REFLECTIVITY\");\r\n                        defines.ROUGHNESSSTOREINMETALMAPALPHA = this._useRoughnessFromMetallicTextureAlpha;\r\n                        defines.ROUGHNESSSTOREINMETALMAPGREEN = !this._useRoughnessFromMetallicTextureAlpha && this._useRoughnessFromMetallicTextureGreen;\r\n                        defines.METALLNESSSTOREINMETALMAPBLUE = this._useMetallnessFromMetallicTextureBlue;\r\n                        defines.AOSTOREINMETALMAPRED = this._useAmbientOcclusionFromMetallicTextureRed;\r\n                        defines.REFLECTIVITY_GAMMA = false;\r\n                    } else if (this._reflectivityTexture) {\r\n                        PrepareDefinesForMergedUV(this._reflectivityTexture, defines, \"REFLECTIVITY\");\r\n                        defines.MICROSURFACEFROMREFLECTIVITYMAP = this._useMicroSurfaceFromReflectivityMapAlpha;\r\n                        defines.MICROSURFACEAUTOMATIC = this._useAutoMicroSurfaceFromReflectivityMap;\r\n                        defines.REFLECTIVITY_GAMMA = this._reflectivityTexture.gammaSpace;\r\n                    } else {\r\n                        defines.REFLECTIVITY = false;\r\n                    }\r\n\r\n                    if (this._metallicReflectanceTexture || this._reflectanceTexture) {\r\n                        defines.METALLIC_REFLECTANCE_USE_ALPHA_ONLY = this._useOnlyMetallicFromMetallicReflectanceTexture;\r\n                        if (this._metallicReflectanceTexture) {\r\n                            PrepareDefinesForMergedUV(this._metallicReflectanceTexture, defines, \"METALLIC_REFLECTANCE\");\r\n                            defines.METALLIC_REFLECTANCE_GAMMA = this._metallicReflectanceTexture.gammaSpace;\r\n                        } else {\r\n                            defines.METALLIC_REFLECTANCE = false;\r\n                        }\r\n                        if (\r\n                            this._reflectanceTexture &&\r\n                            (!this._metallicReflectanceTexture || (this._metallicReflectanceTexture && this._useOnlyMetallicFromMetallicReflectanceTexture))\r\n                        ) {\r\n                            PrepareDefinesForMergedUV(this._reflectanceTexture, defines, \"REFLECTANCE\");\r\n                            defines.REFLECTANCE_GAMMA = this._reflectanceTexture.gammaSpace;\r\n                        } else {\r\n                            defines.REFLECTANCE = false;\r\n                        }\r\n                    } else {\r\n                        defines.METALLIC_REFLECTANCE = false;\r\n                        defines.REFLECTANCE = false;\r\n                    }\r\n\r\n                    if (this._microSurfaceTexture) {\r\n                        PrepareDefinesForMergedUV(this._microSurfaceTexture, defines, \"MICROSURFACEMAP\");\r\n                    } else {\r\n                        defines.MICROSURFACEMAP = false;\r\n                    }\r\n                } else {\r\n                    defines.REFLECTIVITY = false;\r\n                    defines.MICROSURFACEMAP = false;\r\n                }\r\n\r\n                if (engine.getCaps().standardDerivatives && this._bumpTexture && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {\r\n                    PrepareDefinesForMergedUV(this._bumpTexture, defines, \"BUMP\");\r\n\r\n                    if (this._useParallax && this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                        defines.PARALLAX = true;\r\n                        defines.PARALLAX_RHS = scene.useRightHandedSystem;\r\n                        defines.PARALLAXOCCLUSION = !!this._useParallaxOcclusion;\r\n                    } else {\r\n                        defines.PARALLAX = false;\r\n                    }\r\n\r\n                    defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;\r\n                } else {\r\n                    defines.BUMP = false;\r\n                    defines.PARALLAX = false;\r\n                    defines.PARALLAX_RHS = false;\r\n                    defines.PARALLAXOCCLUSION = false;\r\n                    defines.OBJECTSPACE_NORMALMAP = false;\r\n                }\r\n\r\n                if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    defines.ENVIRONMENTBRDF = true;\r\n                    defines.ENVIRONMENTBRDF_RGBD = this._environmentBRDFTexture.isRGBD;\r\n                } else {\r\n                    defines.ENVIRONMENTBRDF = false;\r\n                    defines.ENVIRONMENTBRDF_RGBD = false;\r\n                }\r\n\r\n                if (this._shouldUseAlphaFromAlbedoTexture()) {\r\n                    defines.ALPHAFROMALBEDO = true;\r\n                } else {\r\n                    defines.ALPHAFROMALBEDO = false;\r\n                }\r\n            }\r\n\r\n            defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;\r\n\r\n            if (this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_STANDARD) {\r\n                defines.USEPHYSICALLIGHTFALLOFF = false;\r\n                defines.USEGLTFLIGHTFALLOFF = false;\r\n            } else if (this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_GLTF) {\r\n                defines.USEPHYSICALLIGHTFALLOFF = false;\r\n                defines.USEGLTFLIGHTFALLOFF = true;\r\n            } else {\r\n                defines.USEPHYSICALLIGHTFALLOFF = true;\r\n                defines.USEGLTFLIGHTFALLOFF = false;\r\n            }\r\n\r\n            defines.RADIANCEOVERALPHA = this._useRadianceOverAlpha;\r\n\r\n            if (!this.backFaceCulling && this._twoSidedLighting) {\r\n                defines.TWOSIDEDLIGHTING = true;\r\n            } else {\r\n                defines.TWOSIDEDLIGHTING = false;\r\n            }\r\n\r\n            // We need it to not invert normals in two sided lighting mode (based on the winding of the face)\r\n            defines.MIRRORED = !!scene._mirroredCameraPosition;\r\n\r\n            defines.SPECULARAA = engine.getCaps().standardDerivatives && this._enableSpecularAntiAliasing;\r\n        }\r\n\r\n        if (defines._areTexturesDirty || defines._areMiscDirty) {\r\n            defines.ALPHATESTVALUE = `${this._alphaCutOff}${this._alphaCutOff % 1 === 0 ? \".\" : \"\"}`;\r\n            defines.PREMULTIPLYALPHA = this.alphaMode === Constants.ALPHA_PREMULTIPLIED || this.alphaMode === Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n            defines.ALPHABLEND = this.needAlphaBlendingForMesh(mesh);\r\n            defines.ALPHAFRESNEL = this._useAlphaFresnel || this._useLinearAlphaFresnel;\r\n            defines.LINEARALPHAFRESNEL = this._useLinearAlphaFresnel;\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            defines.TEXTURE_REPETITION_MODE = engine.version > 1 || engine.isWebGPU ? this.textureRepetitionMode : 0;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {\r\n            this._imageProcessingConfiguration.prepareDefines(defines);\r\n        }\r\n\r\n        defines.FORCENORMALFORWARD = this._forceNormalForward;\r\n\r\n        defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;\r\n\r\n        defines.HORIZONOCCLUSION = this._useHorizonOcclusion;\r\n\r\n        // Misc.\r\n        if (defines._areMiscDirty) {\r\n            PrepareDefinesForMisc(\r\n                mesh,\r\n                scene,\r\n                this._useLogarithmicDepth,\r\n                this.pointsCloud,\r\n                this.fogEnabled,\r\n                this.needAlphaTestingForMesh(mesh),\r\n                defines,\r\n                this._applyDecalMapAfterDetailMap,\r\n                this._useVertexPulling,\r\n                renderingMesh,\r\n                this._isVertexOutputInvariant\r\n            );\r\n            defines.UNLIT = this._unlit || ((this.pointsCloud || this.wireframe) && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind));\r\n            defines.DEBUGMODE = this._debugMode;\r\n        }\r\n\r\n        // Values that need to be evaluated on every frame\r\n        PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances ? true : false, useClipPlane, useThinInstances);\r\n\r\n        // External config\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.mesh = mesh;\r\n        this._callbackPluginEventPrepareDefinesBeforeAttributes(this._eventInfo);\r\n\r\n        // Attribs\r\n        PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRBaseMaterial.PBRMATERIAL_OPAQUE);\r\n\r\n        // External config\r\n        this._callbackPluginEventPrepareDefines(this._eventInfo);\r\n    }\r\n\r\n    /**\r\n     * Force shader compilation\r\n     * @param mesh - Define the mesh we want to force the compilation for\r\n     * @param onCompiled - Define a callback triggered when the compilation completes\r\n     * @param options - Define the options used to create the compilation\r\n     */\r\n    public override forceCompilation(mesh: AbstractMesh, onCompiled?: (material: Material) => void, options?: Partial<IMaterialCompilationOptions>): void {\r\n        const localOptions = {\r\n            clipPlane: false,\r\n            useInstances: false,\r\n            ...options,\r\n        };\r\n\r\n        if (!this._uniformBufferLayoutBuilt) {\r\n            this.buildUniformLayout();\r\n        }\r\n\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.GetDefineNames, this._eventInfo);\r\n        const checkReady = () => {\r\n            if (this._breakShaderLoadedCheck) {\r\n                return;\r\n            }\r\n            const defines = new PBRMaterialDefines(this._eventInfo.defineNames);\r\n            const effect = this._prepareEffect(mesh, mesh, defines, undefined, undefined, localOptions.useInstances, localOptions.clipPlane)!;\r\n            if (this._onEffectCreatedObservable) {\r\n                onCreatedEffectParameters.effect = effect;\r\n                onCreatedEffectParameters.subMesh = null;\r\n                this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);\r\n            }\r\n            if (effect.isReady()) {\r\n                if (onCompiled) {\r\n                    onCompiled(this);\r\n                }\r\n            } else {\r\n                effect.onCompileObservable.add(() => {\r\n                    if (onCompiled) {\r\n                        onCompiled(this);\r\n                    }\r\n                });\r\n            }\r\n        };\r\n        checkReady();\r\n    }\r\n\r\n    /**\r\n     * Initializes the uniform buffer layout for the shader.\r\n     */\r\n    public override buildUniformLayout(): void {\r\n        // Order is important !\r\n        const ubo = this._uniformBuffer;\r\n        ubo.addUniform(\"vAlbedoInfos\", 2);\r\n        ubo.addUniform(\"vBaseWeightInfos\", 2);\r\n        ubo.addUniform(\"vBaseDiffuseRoughnessInfos\", 2);\r\n        ubo.addUniform(\"vAmbientInfos\", 4);\r\n        ubo.addUniform(\"vOpacityInfos\", 2);\r\n        ubo.addUniform(\"vEmissiveInfos\", 2);\r\n        ubo.addUniform(\"vLightmapInfos\", 2);\r\n        ubo.addUniform(\"vReflectivityInfos\", 3);\r\n        ubo.addUniform(\"vMicroSurfaceSamplerInfos\", 2);\r\n        ubo.addUniform(\"vBumpInfos\", 3);\r\n        ubo.addUniform(\"albedoMatrix\", 16);\r\n        ubo.addUniform(\"baseWeightMatrix\", 16);\r\n        ubo.addUniform(\"baseDiffuseRoughnessMatrix\", 16);\r\n        ubo.addUniform(\"ambientMatrix\", 16);\r\n        ubo.addUniform(\"opacityMatrix\", 16);\r\n        ubo.addUniform(\"emissiveMatrix\", 16);\r\n        ubo.addUniform(\"lightmapMatrix\", 16);\r\n        ubo.addUniform(\"reflectivityMatrix\", 16);\r\n        ubo.addUniform(\"microSurfaceSamplerMatrix\", 16);\r\n        ubo.addUniform(\"bumpMatrix\", 16);\r\n        ubo.addUniform(\"vTangentSpaceParams\", 2);\r\n        ubo.addUniform(\"vAlbedoColor\", 4);\r\n        ubo.addUniform(\"baseWeight\", 1);\r\n        ubo.addUniform(\"baseDiffuseRoughness\", 1);\r\n        ubo.addUniform(\"vLightingIntensity\", 4);\r\n\r\n        ubo.addUniform(\"pointSize\", 1);\r\n        ubo.addUniform(\"vReflectivityColor\", 4);\r\n        ubo.addUniform(\"vEmissiveColor\", 3);\r\n        ubo.addUniform(\"vAmbientColor\", 3);\r\n\r\n        ubo.addUniform(\"vDebugMode\", 2);\r\n\r\n        ubo.addUniform(\"vMetallicReflectanceFactors\", 4);\r\n        ubo.addUniform(\"vMetallicReflectanceInfos\", 2);\r\n        ubo.addUniform(\"metallicReflectanceMatrix\", 16);\r\n        ubo.addUniform(\"vReflectanceInfos\", 2);\r\n        ubo.addUniform(\"reflectanceMatrix\", 16);\r\n\r\n        ubo.addUniform(\"cameraInfo\", 4);\r\n        ubo.addUniform(\"vTextureRepetitionHexTilingParams\", 4);\r\n        PrepareUniformLayoutForIBL(ubo, true, true, true, true, true);\r\n        super.buildUniformLayout();\r\n    }\r\n\r\n    /**\r\n     * Binds the submesh data.\r\n     * @param world - The world matrix.\r\n     * @param mesh - The BJS mesh.\r\n     * @param subMesh - A submesh of the BJS mesh.\r\n     */\r\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\r\n        const scene = this.getScene();\r\n\r\n        const defines = <PBRMaterialDefines>subMesh.materialDefines;\r\n        if (!defines) {\r\n            return;\r\n        }\r\n\r\n        const effect = subMesh.effect;\r\n\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        this._activeEffect = effect;\r\n\r\n        // Matrices Mesh.\r\n        mesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n        mesh.transferToEffect(world);\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        // Binding unconditionally\r\n        this._uniformBuffer.bindToEffect(effect, \"Material\");\r\n\r\n        this.prePassConfiguration.bindForSubMesh(this._activeEffect, scene, mesh, world, this.isFrozen);\r\n\r\n        MaterialHelperGeometryRendering.Bind(engine.currentRenderPassId, this._activeEffect, mesh, world, this);\r\n\r\n        const camera = scene.activeCamera;\r\n        if (camera) {\r\n            this._uniformBuffer.updateFloat4(\"cameraInfo\", camera.minZ, camera.maxZ, 0, 0);\r\n        } else {\r\n            this._uniformBuffer.updateFloat4(\"cameraInfo\", 0, 0, 0, 0);\r\n        }\r\n\r\n        const hexParams = this.textureRepetitionHexTilingParams;\r\n        this._uniformBuffer.updateFloat4(\"vTextureRepetitionHexTilingParams\", hexParams[0], hexParams[1], hexParams[2], hexParams[3]);\r\n\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventHardBindForSubMesh(this._eventInfo);\r\n\r\n        // Normal Matrix\r\n        if (defines.OBJECTSPACE_NORMALMAP) {\r\n            world.toNormalMatrix(this._normalMatrix);\r\n            this.bindOnlyNormalMatrix(this._normalMatrix);\r\n        }\r\n\r\n        const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);\r\n        const needToAlwaysBindUniformBuffers = engine._features.needToAlwaysBindUniformBuffers;\r\n\r\n        // Bones\r\n        BindBonesParameters(mesh, this._activeEffect, this.prePassConfiguration);\r\n\r\n        // Vertex pulling\r\n        if (this._vertexPullingMetadata) {\r\n            BindVertexPullingUniforms(this._activeEffect, this._vertexPullingMetadata);\r\n        }\r\n\r\n        let reflectionTexture: Nullable<BaseTexture> = null;\r\n        const ubo = this._uniformBuffer;\r\n        if (mustRebind) {\r\n            this.bindViewProjection(effect);\r\n            reflectionTexture = this._getReflectionTexture();\r\n\r\n            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync || subMesh._drawWrapper._forceRebindOnNextCall) {\r\n                // Texture uniforms\r\n                if (scene.texturesEnabled) {\r\n                    if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                        ubo.updateFloat2(\"vAlbedoInfos\", this._albedoTexture.coordinatesIndex, this._albedoTexture.level);\r\n                        BindTextureMatrix(this._albedoTexture, ubo, \"albedo\");\r\n                    }\r\n\r\n                    if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {\r\n                        ubo.updateFloat2(\"vBaseWeightInfos\", this._baseWeightTexture.coordinatesIndex, this._baseWeightTexture.level);\r\n                        BindTextureMatrix(this._baseWeightTexture, ubo, \"baseWeight\");\r\n                    }\r\n\r\n                    if (this._baseDiffuseRoughnessTexture && MaterialFlags.BaseDiffuseRoughnessTextureEnabled) {\r\n                        ubo.updateFloat2(\"vBaseDiffuseRoughnessInfos\", this._baseDiffuseRoughnessTexture.coordinatesIndex, this._baseDiffuseRoughnessTexture.level);\r\n                        BindTextureMatrix(this._baseDiffuseRoughnessTexture, ubo, \"baseDiffuseRoughness\");\r\n                    }\r\n\r\n                    if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {\r\n                        ubo.updateFloat4(\r\n                            \"vAmbientInfos\",\r\n                            this._ambientTexture.coordinatesIndex,\r\n                            this._ambientTexture.level,\r\n                            this._ambientTextureStrength,\r\n                            this._ambientTextureImpactOnAnalyticalLights\r\n                        );\r\n                        BindTextureMatrix(this._ambientTexture, ubo, \"ambient\");\r\n                    }\r\n\r\n                    if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {\r\n                        ubo.updateFloat2(\"vOpacityInfos\", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);\r\n                        BindTextureMatrix(this._opacityTexture, ubo, \"opacity\");\r\n                    }\r\n\r\n                    if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {\r\n                        ubo.updateFloat2(\"vEmissiveInfos\", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);\r\n                        BindTextureMatrix(this._emissiveTexture, ubo, \"emissive\");\r\n                    }\r\n\r\n                    if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {\r\n                        ubo.updateFloat2(\"vLightmapInfos\", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);\r\n                        BindTextureMatrix(this._lightmapTexture, ubo, \"lightmap\");\r\n                    }\r\n\r\n                    if (MaterialFlags.SpecularTextureEnabled) {\r\n                        if (this._metallicTexture) {\r\n                            ubo.updateFloat3(\"vReflectivityInfos\", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength);\r\n                            BindTextureMatrix(this._metallicTexture, ubo, \"reflectivity\");\r\n                        } else if (this._reflectivityTexture) {\r\n                            ubo.updateFloat3(\"vReflectivityInfos\", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0);\r\n                            BindTextureMatrix(this._reflectivityTexture, ubo, \"reflectivity\");\r\n                        }\r\n\r\n                        if (this._metallicReflectanceTexture) {\r\n                            ubo.updateFloat2(\"vMetallicReflectanceInfos\", this._metallicReflectanceTexture.coordinatesIndex, this._metallicReflectanceTexture.level);\r\n                            BindTextureMatrix(this._metallicReflectanceTexture, ubo, \"metallicReflectance\");\r\n                        }\r\n\r\n                        if (this._reflectanceTexture && defines.REFLECTANCE) {\r\n                            ubo.updateFloat2(\"vReflectanceInfos\", this._reflectanceTexture.coordinatesIndex, this._reflectanceTexture.level);\r\n                            BindTextureMatrix(this._reflectanceTexture, ubo, \"reflectance\");\r\n                        }\r\n\r\n                        if (this._microSurfaceTexture) {\r\n                            ubo.updateFloat2(\"vMicroSurfaceSamplerInfos\", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level);\r\n                            BindTextureMatrix(this._microSurfaceTexture, ubo, \"microSurfaceSampler\");\r\n                        }\r\n                    }\r\n\r\n                    if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {\r\n                        ubo.updateFloat3(\"vBumpInfos\", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias);\r\n                        BindTextureMatrix(this._bumpTexture, ubo, \"bump\");\r\n\r\n                        if (scene._mirroredCameraPosition) {\r\n                            ubo.updateFloat2(\"vTangentSpaceParams\", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);\r\n                        } else {\r\n                            ubo.updateFloat2(\"vTangentSpaceParams\", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);\r\n                        }\r\n                    }\r\n\r\n                    BindIBLParameters(scene, defines, ubo, this._reflectionColor, reflectionTexture, this.realTimeFiltering, true, true, true, true, true);\r\n                }\r\n\r\n                // Point size\r\n                if (this.pointsCloud) {\r\n                    ubo.updateFloat(\"pointSize\", this.pointSize);\r\n                }\r\n\r\n                // Colors\r\n                if (defines.METALLICWORKFLOW) {\r\n                    TmpColors.Color4[0].r = this._metallic === undefined || this._metallic === null ? 1 : this._metallic;\r\n                    TmpColors.Color4[0].g = this._roughness === undefined || this._roughness === null ? 1 : this._roughness;\r\n                    const ior = this.subSurface?._indexOfRefraction ?? 1.5;\r\n                    const outsideIOR = 1; // consider air as clear coat and other layers would remap in the shader.\r\n                    TmpColors.Color4[0].b = ior;\r\n                    // We are here deriving our default reflectance from a common value for none metallic surface.\r\n                    // Based of the schlick fresnel approximation model\r\n                    // for dielectrics.\r\n                    const f0 = Math.pow((ior - outsideIOR) / (ior + outsideIOR), 2);\r\n                    TmpColors.Color4[0].a = f0;\r\n                    ubo.updateDirectColor4(\"vReflectivityColor\", TmpColors.Color4[0]);\r\n                    ubo.updateColor4(\"vMetallicReflectanceFactors\", this._metallicReflectanceColor, this._metallicF0Factor);\r\n                } else {\r\n                    ubo.updateColor4(\"vReflectivityColor\", this._reflectivityColor, this._microSurface);\r\n                }\r\n\r\n                ubo.updateColor3(\"vEmissiveColor\", MaterialFlags.EmissiveTextureEnabled ? this._emissiveColor : Color3.BlackReadOnly);\r\n\r\n                if (!defines.SS_REFRACTION && this.subSurface?._linkRefractionWithTransparency) {\r\n                    ubo.updateColor4(\"vAlbedoColor\", this._albedoColor, 1);\r\n                } else {\r\n                    ubo.updateColor4(\"vAlbedoColor\", this._albedoColor, this.alpha);\r\n                }\r\n\r\n                ubo.updateFloat(\"baseWeight\", this._baseWeight);\r\n                ubo.updateFloat(\"baseDiffuseRoughness\", this._baseDiffuseRoughness || 0.0);\r\n\r\n                // Misc\r\n                this._lightingInfos.x = this._directIntensity;\r\n                this._lightingInfos.y = this._emissiveIntensity;\r\n                this._lightingInfos.z = this._environmentIntensity * scene.environmentIntensity;\r\n                this._lightingInfos.w = this._specularIntensity;\r\n\r\n                ubo.updateVector4(\"vLightingIntensity\", this._lightingInfos);\r\n\r\n                // Colors\r\n                scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor);\r\n\r\n                ubo.updateColor3(\"vAmbientColor\", this._globalAmbientColor);\r\n\r\n                ubo.updateFloat2(\"vDebugMode\", this.debugLimit, this.debugFactor);\r\n            }\r\n\r\n            // Textures\r\n            if (scene.texturesEnabled) {\r\n                if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                    ubo.setTexture(\"albedoSampler\", this._albedoTexture);\r\n                }\r\n\r\n                if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {\r\n                    ubo.setTexture(\"baseWeightSampler\", this._baseWeightTexture);\r\n                }\r\n\r\n                if (this._baseDiffuseRoughnessTexture && MaterialFlags.BaseDiffuseRoughnessTextureEnabled) {\r\n                    ubo.setTexture(\"baseDiffuseRoughnessSampler\", this._baseDiffuseRoughnessTexture);\r\n                }\r\n\r\n                if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {\r\n                    ubo.setTexture(\"ambientSampler\", this._ambientTexture);\r\n                }\r\n\r\n                if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {\r\n                    ubo.setTexture(\"opacitySampler\", this._opacityTexture);\r\n                }\r\n\r\n                BindIBLSamplers(scene, defines, ubo, reflectionTexture, this.realTimeFiltering);\r\n\r\n                if (defines.ENVIRONMENTBRDF) {\r\n                    ubo.setTexture(\"environmentBrdfSampler\", this._environmentBRDFTexture);\r\n                }\r\n\r\n                if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {\r\n                    ubo.setTexture(\"emissiveSampler\", this._emissiveTexture);\r\n                }\r\n\r\n                if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {\r\n                    ubo.setTexture(\"lightmapSampler\", this._lightmapTexture);\r\n                }\r\n\r\n                if (MaterialFlags.SpecularTextureEnabled) {\r\n                    if (this._metallicTexture) {\r\n                        ubo.setTexture(\"reflectivitySampler\", this._metallicTexture);\r\n                    } else if (this._reflectivityTexture) {\r\n                        ubo.setTexture(\"reflectivitySampler\", this._reflectivityTexture);\r\n                    }\r\n\r\n                    if (this._metallicReflectanceTexture) {\r\n                        ubo.setTexture(\"metallicReflectanceSampler\", this._metallicReflectanceTexture);\r\n                    }\r\n\r\n                    if (this._reflectanceTexture && defines.REFLECTANCE) {\r\n                        ubo.setTexture(\"reflectanceSampler\", this._reflectanceTexture);\r\n                    }\r\n\r\n                    if (this._microSurfaceTexture) {\r\n                        ubo.setTexture(\"microSurfaceSampler\", this._microSurfaceTexture);\r\n                    }\r\n                }\r\n\r\n                if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {\r\n                    ubo.setTexture(\"bumpSampler\", this._bumpTexture);\r\n                }\r\n            }\r\n\r\n            // OIT with depth peeling\r\n            if (this.getScene().useOrderIndependentTransparency && this.needAlphaBlendingForMesh(mesh)) {\r\n                this.getScene().depthPeelingRenderer!.bind(effect);\r\n            }\r\n\r\n            this._eventInfo.subMesh = subMesh;\r\n            this._callbackPluginEventBindForSubMesh(this._eventInfo);\r\n\r\n            // Clip plane\r\n            BindClipPlane(this._activeEffect, this, scene);\r\n\r\n            this.bindEyePosition(effect);\r\n        } else if (needToAlwaysBindUniformBuffers) {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n\r\n        // Lights\r\n        if ((mustRebind || !this.isFrozen || needToAlwaysBindUniformBuffers) && scene.lightsEnabled && !this._disableLighting) {\r\n            BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);\r\n        }\r\n\r\n        if (mustRebind || !this.isFrozen) {\r\n            // View\r\n            if (\r\n                (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) ||\r\n                reflectionTexture ||\r\n                this.subSurface.refractionTexture ||\r\n                mesh.receiveShadows ||\r\n                defines.PREPASS ||\r\n                defines[\"CLUSTLIGHT_BATCH\"]\r\n            ) {\r\n                this.bindView(effect);\r\n            }\r\n\r\n            // Fog\r\n            BindFogParameters(scene, mesh, this._activeEffect, true);\r\n\r\n            // Morph targets\r\n            if (defines.NUM_MORPH_INFLUENCERS) {\r\n                BindMorphTargetParameters(mesh, this._activeEffect);\r\n            }\r\n\r\n            if (defines.BAKED_VERTEX_ANIMATION_TEXTURE) {\r\n                mesh.bakedVertexAnimationManager?.bind(effect, defines.INSTANCES);\r\n            }\r\n\r\n            // image processing\r\n            this._imageProcessingConfiguration.bind(this._activeEffect);\r\n\r\n            // Log. depth\r\n            BindLogDepth(defines, this._activeEffect, scene);\r\n        }\r\n\r\n        this._afterBind(mesh, this._activeEffect, subMesh);\r\n\r\n        ubo.update();\r\n    }\r\n\r\n    /**\r\n     * Returns the animatable textures.\r\n     * If material have animatable metallic texture, then reflectivity texture will not be returned, even if it has animations.\r\n     * @returns - Array of animatable textures.\r\n     */\r\n    public override getAnimatables(): IAnimatable[] {\r\n        const results = super.getAnimatables();\r\n\r\n        if (this._albedoTexture && this._albedoTexture.animations && this._albedoTexture.animations.length > 0) {\r\n            results.push(this._albedoTexture);\r\n        }\r\n\r\n        if (this._baseWeightTexture && this._baseWeightTexture.animations && this._baseWeightTexture.animations.length > 0) {\r\n            results.push(this._baseWeightTexture);\r\n        }\r\n\r\n        if (this._baseDiffuseRoughnessTexture && this._baseDiffuseRoughnessTexture.animations && this._baseDiffuseRoughnessTexture.animations.length > 0) {\r\n            results.push(this._baseDiffuseRoughnessTexture);\r\n        }\r\n\r\n        if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {\r\n            results.push(this._ambientTexture);\r\n        }\r\n\r\n        if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {\r\n            results.push(this._opacityTexture);\r\n        }\r\n\r\n        if (this._reflectionTexture && this._reflectionTexture.animations && this._reflectionTexture.animations.length > 0) {\r\n            results.push(this._reflectionTexture);\r\n        }\r\n\r\n        if (this._emissiveTexture && this._emissiveTexture.animations && this._emissiveTexture.animations.length > 0) {\r\n            results.push(this._emissiveTexture);\r\n        }\r\n\r\n        if (this._metallicTexture && this._metallicTexture.animations && this._metallicTexture.animations.length > 0) {\r\n            results.push(this._metallicTexture);\r\n        } else if (this._reflectivityTexture && this._reflectivityTexture.animations && this._reflectivityTexture.animations.length > 0) {\r\n            results.push(this._reflectivityTexture);\r\n        }\r\n\r\n        if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {\r\n            results.push(this._bumpTexture);\r\n        }\r\n\r\n        if (this._lightmapTexture && this._lightmapTexture.animations && this._lightmapTexture.animations.length > 0) {\r\n            results.push(this._lightmapTexture);\r\n        }\r\n\r\n        if (this._metallicReflectanceTexture && this._metallicReflectanceTexture.animations && this._metallicReflectanceTexture.animations.length > 0) {\r\n            results.push(this._metallicReflectanceTexture);\r\n        }\r\n\r\n        if (this._reflectanceTexture && this._reflectanceTexture.animations && this._reflectanceTexture.animations.length > 0) {\r\n            results.push(this._reflectanceTexture);\r\n        }\r\n\r\n        if (this._microSurfaceTexture && this._microSurfaceTexture.animations && this._microSurfaceTexture.animations.length > 0) {\r\n            results.push(this._microSurfaceTexture);\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Returns the texture used for reflections.\r\n     * @returns - Reflection texture if present.  Otherwise, returns the environment texture.\r\n     */\r\n    private _getReflectionTexture(): Nullable<BaseTexture> {\r\n        if (this._reflectionTexture) {\r\n            return this._reflectionTexture;\r\n        }\r\n\r\n        return this.getScene().environmentTexture;\r\n    }\r\n\r\n    /**\r\n     * Returns an array of the actively used textures.\r\n     * @returns - Array of BaseTextures\r\n     */\r\n    public override getActiveTextures(): BaseTexture[] {\r\n        const activeTextures = super.getActiveTextures();\r\n\r\n        if (this._albedoTexture) {\r\n            activeTextures.push(this._albedoTexture);\r\n        }\r\n\r\n        if (this._baseWeightTexture) {\r\n            activeTextures.push(this._baseWeightTexture);\r\n        }\r\n\r\n        if (this._baseDiffuseRoughnessTexture) {\r\n            activeTextures.push(this._baseDiffuseRoughnessTexture);\r\n        }\r\n\r\n        if (this._ambientTexture) {\r\n            activeTextures.push(this._ambientTexture);\r\n        }\r\n\r\n        if (this._opacityTexture) {\r\n            activeTextures.push(this._opacityTexture);\r\n        }\r\n\r\n        if (this._reflectionTexture) {\r\n            activeTextures.push(this._reflectionTexture);\r\n        }\r\n\r\n        if (this._emissiveTexture) {\r\n            activeTextures.push(this._emissiveTexture);\r\n        }\r\n\r\n        if (this._reflectivityTexture) {\r\n            activeTextures.push(this._reflectivityTexture);\r\n        }\r\n\r\n        if (this._metallicTexture) {\r\n            activeTextures.push(this._metallicTexture);\r\n        }\r\n\r\n        if (this._metallicReflectanceTexture) {\r\n            activeTextures.push(this._metallicReflectanceTexture);\r\n        }\r\n\r\n        if (this._reflectanceTexture) {\r\n            activeTextures.push(this._reflectanceTexture);\r\n        }\r\n\r\n        if (this._microSurfaceTexture) {\r\n            activeTextures.push(this._microSurfaceTexture);\r\n        }\r\n\r\n        if (this._bumpTexture) {\r\n            activeTextures.push(this._bumpTexture);\r\n        }\r\n\r\n        if (this._lightmapTexture) {\r\n            activeTextures.push(this._lightmapTexture);\r\n        }\r\n\r\n        return activeTextures;\r\n    }\r\n\r\n    /**\r\n     * Checks to see if a texture is used in the material.\r\n     * @param texture - Base texture to use.\r\n     * @returns - Boolean specifying if a texture is used in the material.\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (super.hasTexture(texture)) {\r\n            return true;\r\n        }\r\n\r\n        if (this._albedoTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._baseWeightTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._baseDiffuseRoughnessTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._ambientTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._opacityTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._reflectionTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._emissiveTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._reflectivityTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._metallicTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._metallicReflectanceTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._reflectanceTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._microSurfaceTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._bumpTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._lightmapTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Sets the required values to the prepass renderer.\r\n     * It can't be sets when subsurface scattering of this material is disabled.\r\n     * When scene have ability to enable subsurface prepass effect, it will enable.\r\n     * @returns - If prepass is enabled or not.\r\n     */\r\n    public override setPrePassRenderer(): boolean {\r\n        if (!this.subSurface?.isScatteringEnabled) {\r\n            return false;\r\n        }\r\n\r\n        const subSurfaceConfiguration = this.getScene().enableSubSurfaceForPrePass();\r\n        if (subSurfaceConfiguration) {\r\n            subSurfaceConfiguration.enabled = true;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources of the material.\r\n     * @param forceDisposeEffect - Forces the disposal of effects.\r\n     * @param forceDisposeTextures - Forces the disposal of all textures.\r\n     */\r\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {\r\n        this._breakShaderLoadedCheck = true;\r\n        if (forceDisposeTextures) {\r\n            if (this._environmentBRDFTexture && this.getScene().environmentBRDFTexture !== this._environmentBRDFTexture) {\r\n                this._environmentBRDFTexture.dispose();\r\n            }\r\n\r\n            this._albedoTexture?.dispose();\r\n            this._baseWeightTexture?.dispose();\r\n            this._baseDiffuseRoughnessTexture?.dispose();\r\n            this._ambientTexture?.dispose();\r\n            this._opacityTexture?.dispose();\r\n            this._reflectionTexture?.dispose();\r\n            this._emissiveTexture?.dispose();\r\n            this._metallicTexture?.dispose();\r\n            this._reflectivityTexture?.dispose();\r\n            this._bumpTexture?.dispose();\r\n            this._lightmapTexture?.dispose();\r\n            this._metallicReflectanceTexture?.dispose();\r\n            this._reflectanceTexture?.dispose();\r\n            this._microSurfaceTexture?.dispose();\r\n        }\r\n\r\n        this._renderTargets.dispose();\r\n\r\n        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n        }\r\n\r\n        super.dispose(forceDisposeEffect, forceDisposeTextures);\r\n    }\r\n}\r\n\r\n// #region GENERATED_SIDE_EFFECT_STUBS — do not edit, regenerate with `npm run generate:side-effect-stubs`\r\nimport { _MissingSideEffectProperty } from \"../../Misc/devTools\";\r\n\r\nif (!Object.getOwnPropertyDescriptor(PBRBaseMaterial.prototype, \"decalMap\")) {\r\n    Object.defineProperty(PBRBaseMaterial.prototype, \"decalMap\", _MissingSideEffectProperty(\"PBRBaseMaterial\", \"decalMap\"));\r\n}\r\n// #endregion GENERATED_SIDE_EFFECT_STUBS\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase.pure\";\r\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type StandardMaterial } from \"core/Materials/standardMaterial.pure\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial.pure\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { expandToProperty, serialize } from \"core/Misc/decorators\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial.pure\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * @internal\r\n */\r\nclass MaterialIBLShadowsRenderDefines extends MaterialDefines {\r\n    public RENDER_WITH_IBL_SHADOWS = false;\r\n    public COLORED_IBL_SHADOWS = false;\r\n}\r\n\r\n/**\r\n * Plugin used to render the contribution from IBL shadows.\r\n */\r\nexport class IBLShadowsPluginMaterial extends MaterialPluginBase {\r\n    /**\r\n     * Defines the name of the plugin.\r\n     */\r\n    public static readonly Name = \"IBLShadowsPluginMaterial\";\r\n\r\n    /**\r\n     * The texture containing the contribution from IBL shadows.\r\n     */\r\n    private _iblShadowsTexture!: InternalTexture;\r\n\r\n    public get iblShadowsTexture(): InternalTexture {\r\n        return this._iblShadowsTexture;\r\n    }\r\n\r\n    public set iblShadowsTexture(value: InternalTexture) {\r\n        if (this._iblShadowsTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._iblShadowsTexture = value;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * The opacity of the shadows.\r\n     */\r\n    @serialize()\r\n    public shadowOpacity: number = 1.0;\r\n\r\n    private _isEnabled = false;\r\n    private _isColored = false;\r\n    public get isColored(): boolean {\r\n        return this._isColored;\r\n    }\r\n    public set isColored(value: boolean) {\r\n        if (this._isColored === value) {\r\n            return;\r\n        }\r\n        this._isColored = value;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n    /**\r\n     * Defines if the plugin is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    protected _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a give shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: Material | StandardMaterial | PBRBaseMaterial | OpenPBRMaterial) {\r\n        super(material, IBLShadowsPluginMaterial.Name, 310, new MaterialIBLShadowsRenderDefines());\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n    }\r\n\r\n    private _isOpenPBRMaterial(): boolean {\r\n        return this._material.getClassName() === \"OpenPBRMaterial\";\r\n    }\r\n\r\n    private _isShadowOnlyMaterial(): boolean {\r\n        return this._material.getClassName() === \"ShadowOnlyMaterial\";\r\n    }\r\n\r\n    public override prepareDefines(defines: MaterialIBLShadowsRenderDefines) {\r\n        defines.RENDER_WITH_IBL_SHADOWS = this._isEnabled;\r\n        defines.COLORED_IBL_SHADOWS = this.isColored;\r\n    }\r\n\r\n    public override getClassName() {\r\n        return \"IBLShadowsPluginMaterial\";\r\n    }\r\n\r\n    public override getUniforms(_shaderLanguage: ShaderLanguage) {\r\n        const result: any = {};\r\n        result.ubo = [];\r\n        if (this._isOpenPBRMaterial()) {\r\n            if (_shaderLanguage === ShaderLanguage.WGSL) {\r\n                result.fragment = `#ifdef RENDER_WITH_IBL_SHADOWS\r\n                    var shadowOpacity: f32;\r\n                #endif`;\r\n            } else {\r\n                result.fragment = `#ifdef RENDER_WITH_IBL_SHADOWS\r\n                    uniform float shadowOpacity;\r\n                #endif`;\r\n            }\r\n        } else {\r\n            result.ubo.push({ name: \"renderTargetSize\", size: 2, type: \"vec2\" });\r\n            if (_shaderLanguage === ShaderLanguage.WGSL) {\r\n                result.fragment = `#ifdef RENDER_WITH_IBL_SHADOWS\r\n                    var renderTargetSize: vec2f;\r\n                    var shadowOpacity: f32;\r\n                #endif`;\r\n            } else {\r\n                result.fragment = `#ifdef RENDER_WITH_IBL_SHADOWS\r\n                    uniform vec2 renderTargetSize;\r\n                    uniform float shadowOpacity;\r\n                #endif`;\r\n            }\r\n        }\r\n        result.ubo.push({ name: \"shadowOpacity\", size: 1, type: \"float\" });\r\n        return result;\r\n    }\r\n\r\n    public override getSamplers(samplers: string[]) {\r\n        samplers.push(\"iblShadowsTexture\");\r\n    }\r\n\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer) {\r\n        if (this._isEnabled && this.iblShadowsTexture) {\r\n            uniformBuffer.bindTexture(\"iblShadowsTexture\", this.iblShadowsTexture);\r\n            uniformBuffer.updateFloat2(\"renderTargetSize\", this._material.getScene().getEngine().getRenderWidth(), this._material.getScene().getEngine().getRenderHeight());\r\n            uniformBuffer.updateFloat(\"shadowOpacity\", this.shadowOpacity);\r\n        }\r\n    }\r\n\r\n    public override getCustomCode(shaderType: string, shaderLanguage: ShaderLanguage) {\r\n        let frag: { [name: string]: string };\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            frag = {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    var iblShadowsTextureSampler: sampler;\r\n                    var iblShadowsTexture: texture_2d<f32>;\r\n\r\n                    #ifdef COLORED_IBL_SHADOWS\r\n                        fn computeIndirectShadow() -> vec3f {\r\n                            var uv = fragmentInputs.position.xy / uniforms.renderTargetSize;\r\n                            var shadowValue: vec3f = textureSample(iblShadowsTexture, iblShadowsTextureSampler, uv).rgb;\r\n                            return mix(shadowValue, vec3f(1.0), 1.0 - uniforms.shadowOpacity);\r\n                        }\r\n                    #else\r\n                        fn computeIndirectShadow() -> vec2f {\r\n                            var uv = fragmentInputs.position.xy / uniforms.renderTargetSize;\r\n                            var shadowValue: vec2f = textureSample(iblShadowsTexture, iblShadowsTextureSampler, uv).rg;\r\n                            return mix(shadowValue, vec2f(1.0), 1.0 - uniforms.shadowOpacity);\r\n                        }\r\n                    #endif\r\n                #endif\r\n            `,\r\n            };\r\n\r\n            if (this._material instanceof PBRBaseMaterial) {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifndef UNLIT\r\n                        #ifdef REFLECTION\r\n                            #ifdef COLORED_IBL_SHADOWS\r\n                                var shadowValue: vec3f = computeIndirectShadow();\r\n                                finalIrradiance *= shadowValue;\r\n                                finalRadianceScaled *= mix(vec3f(1.0), shadowValue, roughness);\r\n                            #else\r\n                                var shadowValue: vec2f = computeIndirectShadow();\r\n                                finalIrradiance *= vec3f(shadowValue.x);\r\n                                finalRadianceScaled *= vec3f(mix(pow(shadowValue.y, 4.0), shadowValue.x, roughness));\r\n                            #endif\r\n                        #endif\r\n                    #else\r\n                        finalDiffuse *= computeIndirectShadow().x;\r\n                    #endif\r\n                #endif\r\n            `;\r\n            } else if (this._isOpenPBRMaterial()) {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_IBLLAYERCOMPOSITION\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifndef UNLIT\r\n                        #ifdef REFLECTION\r\n                            #ifdef COLORED_IBL_SHADOWS\r\n                                var shadowValue: vec3f = computeIndirectShadow();\r\n                                ambient_occlusion = min(ambient_occlusion, shadowValue);\r\n                            #else\r\n                                var shadowValue: vec2f = computeIndirectShadow();\r\n                                ambient_occlusion = min(ambient_occlusion, vec3f(shadowValue.x));\r\n                                specular_ambient_occlusion = min(specular_ambient_occlusion, pow(shadowValue.y, 4.0));\r\n                            #endif\r\n                        #endif\r\n                    #else\r\n                        ambient_occlusion = min(ambient_occlusion, vec3f(computeIndirectShadow().x));\r\n                    #endif\r\n                #endif\r\n            `;\r\n            } else if (this._isShadowOnlyMaterial()) {\r\n                // ShadowOnlyMaterial encodes shadow strength in a single alpha channel via the `shadow`\r\n                // scalar, so modulate `shadow` directly rather than color.rgb (which is the -typically\r\n                // black- shadowColor). Because there is only one output channel, IBL shadows on this\r\n                // material are monochrome by contract: a colored shadow value is reduced to its Rec.709\r\n                // luminance rather than preserving per-channel hue (which an alpha-only catcher cannot do).\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_LIGHT_COMPOSITION\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifdef COLORED_IBL_SHADOWS\r\n                        var shadowValue: vec3f = computeIndirectShadow();\r\n                        shadow *= clamp(dot(shadowValue, vec3f(0.2126f, 0.7152f, 0.0722f)), 0.0f, 1.0f);\r\n                    #else\r\n                        var shadowValue: vec2f = computeIndirectShadow();\r\n                        shadow *= clamp(shadowValue.x, 0.0f, 1.0f);\r\n                    #endif\r\n                #endif\r\n            `;\r\n            } else {\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifdef COLORED_IBL_SHADOWS\r\n                        var shadowValue: vec3f = computeIndirectShadow();\r\n                        color *= toGammaSpace(vec4f(shadowValue, 1.0f));\r\n                    #else\r\n                        var shadowValue: vec2f = computeIndirectShadow();\r\n                        color *= toGammaSpace(vec4f(shadowValue.x, shadowValue.x, shadowValue.x, 1.0f));\r\n                    #endif\r\n                #endif\r\n            `;\r\n            }\r\n        } else {\r\n            frag = {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    uniform sampler2D iblShadowsTexture;\r\n                #ifdef COLORED_IBL_SHADOWS\r\n                    vec3 computeIndirectShadow() {\r\n                        vec2 uv = gl_FragCoord.xy / renderTargetSize;\r\n                        vec3 shadowValue = texture2D(iblShadowsTexture, uv).rgb;\r\n                        return mix(shadowValue.rgb, vec3(1.0), 1.0 - shadowOpacity);\r\n                    }\r\n                #else\r\n                    vec2 computeIndirectShadow() {\r\n                        vec2 uv = gl_FragCoord.xy / renderTargetSize;\r\n                        vec2 shadowValue = texture2D(iblShadowsTexture, uv).rg;\r\n                        return mix(shadowValue.rg, vec2(1.0), 1.0 - shadowOpacity);\r\n                    }\r\n                #endif\r\n                #endif\r\n            `,\r\n            };\r\n\r\n            if (this._material instanceof PBRBaseMaterial) {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifndef UNLIT\r\n                        #ifdef REFLECTION\r\n                            #ifdef COLORED_IBL_SHADOWS\r\n                                vec3 shadowValue = computeIndirectShadow();\r\n                                finalIrradiance.rgb *= shadowValue.rgb;\r\n                                finalRadianceScaled *= mix(vec3(1.0), shadowValue.rgb, roughness);\r\n                            #else\r\n                                vec2 shadowValue = computeIndirectShadow();\r\n                                finalIrradiance *= shadowValue.x;\r\n                                finalRadianceScaled *= mix(pow(shadowValue.y, 4.0), shadowValue.x, roughness);\r\n                            #endif\r\n                        #endif\r\n                    #else\r\n                        finalDiffuse *= computeIndirectShadow().x;\r\n                    #endif\r\n                #endif\r\n            `;\r\n            } else if (this._isOpenPBRMaterial()) {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_IBLLAYERCOMPOSITION\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifndef UNLIT\r\n                        #ifdef REFLECTION\r\n                            #ifdef COLORED_IBL_SHADOWS\r\n                                vec3 shadowValue = computeIndirectShadow();\r\n                                ambient_occlusion = min(ambient_occlusion, shadowValue);\r\n                            #else\r\n                                vec2 shadowValue = computeIndirectShadow();\r\n                                ambient_occlusion = min(ambient_occlusion, vec3(shadowValue.x));\r\n                                specular_ambient_occlusion = min(specular_ambient_occlusion, pow(shadowValue.y, 4.0));\r\n                            #endif\r\n                        #endif\r\n                    #else\r\n                        ambient_occlusion = min(ambient_occlusion, vec3(computeIndirectShadow().x));\r\n                    #endif\r\n                #endif\r\n            `;\r\n            } else if (this._isShadowOnlyMaterial()) {\r\n                // ShadowOnlyMaterial encodes shadow strength in a single alpha channel via the `shadow`\r\n                // scalar, so modulate `shadow` directly rather than color.rgb (which is the -typically\r\n                // black- shadowColor). Because there is only one output channel, IBL shadows on this\r\n                // material are monochrome by contract: a colored shadow value is reduced to its Rec.709\r\n                // luminance rather than preserving per-channel hue (which an alpha-only catcher cannot do).\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_LIGHT_COMPOSITION\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifdef COLORED_IBL_SHADOWS\r\n                        vec3 shadowValue = computeIndirectShadow();\r\n                        shadow *= clamp(dot(shadowValue, vec3(0.2126, 0.7152, 0.0722)), 0.0, 1.0);\r\n                    #else\r\n                        vec2 shadowValue = computeIndirectShadow();\r\n                        shadow *= clamp(shadowValue.x, 0.0, 1.0);\r\n                    #endif\r\n                #endif\r\n            `;\r\n            } else {\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\"] = `\r\n                #ifdef RENDER_WITH_IBL_SHADOWS\r\n                    #ifdef COLORED_IBL_SHADOWS\r\n                        vec3 shadowValue = computeIndirectShadow();\r\n                        color.rgb *= toGammaSpace(shadowValue.rgb);\r\n                    #else\r\n                        vec2 shadowValue = computeIndirectShadow();\r\n                        color.rgb *= toGammaSpace(shadowValue.x);\r\n                    #endif\r\n                #endif\r\n            `;\r\n            }\r\n        }\r\n\r\n        return shaderType === \"vertex\" ? null : frag;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for iblShadowsPluginMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterIblShadowsPluginMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(`BABYLON.IBLShadowsPluginMaterial`, IBLShadowsPluginMaterial);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { type SmartArrayNoDuplicate } from \"../Misc/smartArray\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type GeometryBufferRenderer, type IGeometryBufferTextureTypeAndFormat } from \"./geometryBufferRenderer.pure\";\r\n\r\n/**\r\n * Defines the Geometry Buffer scene component responsible to manage a G-Buffer useful\r\n * in several rendering techniques.\r\n */\r\nexport class GeometryBufferRendererSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_GEOMETRYBUFFERRENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER, this, this._gatherRenderTargets);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    private _gatherRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {\r\n        if (this.scene._geometryBufferRenderer) {\r\n            renderTargets.push(this.scene._geometryBufferRenderer.getGBuffer());\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryBufferRendererSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param geometryBufferRendererClass The GeometryBufferRenderer class to register the component for\r\n */\r\nexport function RegisterGeometryBufferRendererSceneComponent(geometryBufferRendererClass: typeof GeometryBufferRenderer): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"geometryBufferRenderer\", {\r\n        get: function (this: Scene) {\r\n            return this._geometryBufferRenderer;\r\n        },\r\n        set: function (this: Scene, value: Nullable<GeometryBufferRenderer>) {\r\n            if (value && value.isSupported) {\r\n                this._geometryBufferRenderer = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.enableGeometryBufferRenderer = function (\r\n        ratio: number | { width: number; height: number } = 1,\r\n        depthFormat = Constants.TEXTUREFORMAT_DEPTH16,\r\n        textureTypesAndFormats?: { [key: number]: IGeometryBufferTextureTypeAndFormat }\r\n    ): Nullable<GeometryBufferRenderer> {\r\n        if (this._geometryBufferRenderer) {\r\n            return this._geometryBufferRenderer;\r\n        }\r\n\r\n        this._geometryBufferRenderer = new geometryBufferRendererClass(this, ratio, depthFormat, textureTypesAndFormats);\r\n        if (!this._geometryBufferRenderer.isSupported) {\r\n            this._geometryBufferRenderer = null;\r\n        }\r\n\r\n        return this._geometryBufferRenderer;\r\n    };\r\n\r\n    Scene.prototype.disableGeometryBufferRenderer = function (): void {\r\n        if (!this._geometryBufferRenderer) {\r\n            return;\r\n        }\r\n\r\n        this._geometryBufferRenderer.dispose();\r\n        this._geometryBufferRenderer = null;\r\n    };\r\n\r\n    geometryBufferRendererClass._SceneComponentInitialization = (scene: Scene) => {\r\n        // Register the G Buffer component to the scene.\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_GEOMETRYBUFFERRENDERER) as GeometryBufferRendererSceneComponent;\r\n        if (!component) {\r\n            component = new GeometryBufferRendererSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { MultiRenderTarget } from \"../Materials/Textures/multiRenderTarget.pure\";\r\nimport { type PrePassRenderer } from \"../Rendering/prePassRenderer.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { MaterialFlags } from \"../Materials/materialFlags\";\r\nimport { BindClipPlane, PrepareStringDefinesForClipPlanes, AddClipPlaneUniforms } from \"../Materials/clipPlaneMaterialHelper\";\r\nimport {\r\n    BindMorphTargetParameters,\r\n    BindSceneUniformBuffer,\r\n    PrepareDefinesAndAttributesForMorphTargets,\r\n    PushAttributesForInstances,\r\n    PrepareDefinesForIBL,\r\n    PrepareUniformsAndSamplersForIBL,\r\n} from \"../Materials/materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type OpenPBRMaterial } from \"../Materials/PBR/openpbrMaterial.pure\";\r\nimport { type IblShadowsRenderPipeline } from \"./IBLShadows/iblShadowsRenderPipeline.pure\";\r\nimport { RegisterGeometryBufferRendererSceneComponent } from \"./geometryBufferRendererSceneComponent.pure\";\r\nimport { _IsGaussianSplattingMesh } from \"../Meshes/GaussianSplatting/gaussianSplatting.functions\";\r\nimport { _IsMeshBlendingSupported } from \"../Meshes/meshBlendingTag\";\r\nimport {\r\n    _GetGeometryRenderingMeshBlendTag,\r\n    _GetGeometryRenderingObjectId,\r\n    type GeometryRenderingMeshBlendTagProvider,\r\n    type GeometryRenderingObjectIdProvider,\r\n} from \"../Materials/materialHelper.geometryrendering\";\r\n\r\n/** @internal */\r\ninterface ISavedTransformationMatrix {\r\n    world: Matrix;\r\n    viewProjection: Matrix;\r\n}\r\n\r\n/**\r\n * Type, format and sampling settings for a geometry buffer render target.\r\n */\r\nexport interface IGeometryBufferTextureTypeAndFormat {\r\n    /** Texture type for the target. */\r\n    textureType: number;\r\n    /** Texture format for the target. */\r\n    textureFormat: number;\r\n    /** Optional sampling mode for the target texture. Defaults to bilinear when omitted. */\r\n    samplingMode?: number;\r\n}\r\n\r\nexport const Samplers = [\r\n    \"diffuseSampler\",\r\n    \"bumpSampler\",\r\n    \"reflectivitySampler\",\r\n    \"albedoSampler\",\r\n    \"morphTargets\",\r\n    \"boneSampler\",\r\n    \"transmissionWeightSampler\",\r\n    \"subsurfaceWeightSampler\",\r\n    \"iblShadowSampler\",\r\n];\r\n\r\n/** list the uniforms used by the geometry renderer */\r\nexport const Uniforms = [\r\n    \"world\",\r\n    \"mBones\",\r\n    \"viewProjection\",\r\n    \"diffuseMatrix\",\r\n    \"alphaCutOff\",\r\n    \"view\",\r\n    \"previousWorld\",\r\n    \"previousViewProjection\",\r\n    \"mPreviousBones\",\r\n    \"bumpMatrix\",\r\n    \"reflectivityMatrix\",\r\n    \"albedoMatrix\",\r\n    \"reflectivityColor\",\r\n    \"albedoColor\",\r\n    \"reflectionMatrix\",\r\n    \"vTransmissionWeight\",\r\n    \"vSubsurfaceWeight\",\r\n    \"vEyePosition\",\r\n    \"vTransmissionScatterAnisotropy\",\r\n    \"vSubsurfaceScatterAnisotropy\",\r\n    \"shadowTextureSize\",\r\n    \"metallic\",\r\n    \"glossiness\",\r\n    \"vTangentSpaceParams\",\r\n    \"vBumpInfos\",\r\n    \"morphTargetInfluences\",\r\n    \"morphTargetCount\",\r\n    \"morphTargetTextureInfo\",\r\n    \"morphTargetTextureIndices\",\r\n    \"boneTextureInfo\",\r\n    \"objectId\",\r\n    \"meshBlendTag\",\r\n];\r\n\r\n/**\r\n * This renderer is helpful to fill one of the render target with a geometry buffer.\r\n */\r\nexport class GeometryBufferRenderer {\r\n    /**\r\n     * Force all the standard materials to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n    /**\r\n     * Constant used to retrieve the depth texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.DEPTH_TEXTURE_INDEX)\r\n     */\r\n    public static readonly DEPTH_TEXTURE_TYPE = 0;\r\n    /**\r\n     * Constant used to retrieve the normal texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.NORMAL_TEXTURE_INDEX)\r\n     */\r\n    public static readonly NORMAL_TEXTURE_TYPE = 1;\r\n    /**\r\n     * Constant used to retrieve the position texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.POSITION_TEXTURE_INDEX)\r\n     */\r\n    public static readonly POSITION_TEXTURE_TYPE = 2;\r\n    /**\r\n     * Constant used to retrieve the velocity texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_INDEX)\r\n     */\r\n    public static readonly VELOCITY_TEXTURE_TYPE = 3;\r\n    /**\r\n     * Constant used to retrieve the reflectivity texture index in the G-Buffer textures array\r\n     * using the getIndex(GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE)\r\n     */\r\n    public static readonly REFLECTIVITY_TEXTURE_TYPE = 4;\r\n\r\n    /**\r\n     * Constant used to retrieve the screen-space depth texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE)\r\n     */\r\n    public static readonly SCREENSPACE_DEPTH_TEXTURE_TYPE = 5;\r\n\r\n    /**\r\n     * Constant used to retrieve the linear velocity texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE)\r\n     */\r\n    public static readonly VELOCITY_LINEAR_TEXTURE_TYPE = 6;\r\n\r\n    /**\r\n     * Constant used to retrieve the irradiance texture index in the G-Buffer textures array\r\n     * using getIndex(GeometryBufferRenderer.IRRADIANCE_TEXTURE_TYPE)\r\n     */\r\n    public static readonly IRRADIANCE_TEXTURE_TYPE = 7;\r\n\r\n    /**\r\n     * Constant used to retrieve the object ID texture index in the G-Buffer textures array.\r\n     * Object IDs are stored as 24-bit unsigned integers encoded in the RGB channels.\r\n     */\r\n    public static readonly OBJECT_ID_TEXTURE_TYPE = 8;\r\n\r\n    /**\r\n     * Constant used to retrieve the packed mesh-blending tag texture index in the G-Buffer textures array.\r\n     */\r\n    public static readonly MESH_BLEND_TAG_TEXTURE_TYPE = 9;\r\n\r\n    /**\r\n     * Dictionary used to store the previous transformation matrices of each rendered mesh\r\n     * in order to compute objects velocities when enableVelocity is set to \"true\"\r\n     * @internal\r\n     */\r\n    public _previousTransformationMatrices: { [index: number]: ISavedTransformationMatrix } = {};\r\n    /**\r\n     * Dictionary used to store the previous bones transformation matrices of each rendered mesh\r\n     * in order to compute objects velocities when enableVelocity is set to \"true\"\r\n     * @internal\r\n     */\r\n    public _previousBonesTransformationMatrices: { [index: number]: Float32Array } = {};\r\n    /**\r\n     * Array used to store the ignored skinned meshes while computing velocity map (typically used by the motion blur post-process).\r\n     * Avoids computing bones velocities and computes only mesh's velocity itself (position, rotation, scaling).\r\n     */\r\n    public excludedSkinnedMeshesFromVelocity: AbstractMesh[] = [];\r\n\r\n    private _renderTransparentMeshes = true;\r\n\r\n    /** Gets or sets a boolean indicating if transparent meshes should be rendered */\r\n    public get renderTransparentMeshes(): boolean {\r\n        return this._renderTransparentMeshes;\r\n    }\r\n\r\n    public set renderTransparentMeshes(value: boolean) {\r\n        if (value && this._enableMeshBlendTag && !this._scene.getEngine().getCaps().blendParametersPerTarget) {\r\n            throw new Error(\"GeometryBufferRenderer: transparent mesh-blending tags require per-target blend parameters\");\r\n        }\r\n        this._renderTransparentMeshes = value;\r\n    }\r\n\r\n    /**\r\n     * Provides the object ID written for each rendered mesh.\r\n     *\r\n     * IDs must be integers between 0 and 0xFFFFFF. ID 0 is reserved for background or excluded meshes.\r\n     * Instances use the ID of their source mesh. The default is the mesh unique ID.\r\n     * Default IDs are only stable for the lifetime of the current scene and should not be persisted.\r\n     * The provider runs in the render hot path and may be called multiple times for the same mesh in a frame.\r\n     * @see https://playground.babylonjs.com/?version=preview#SQXZ3X#1\r\n     */\r\n    public objectIdProvider?: GeometryRenderingObjectIdProvider;\r\n\r\n    /**\r\n     * Provides the packed mesh-blending tag written for each rendered mesh.\r\n     *\r\n     * Tags must be 0 or contain a group ID between 1 and 63 in their low six bits. Tag 0 disables mesh blending.\r\n     * By default, meshes use their `meshBlendingTag` property. Instances and thin instances use the source mesh tag.\r\n     * The provider runs in the render hot path and receives the source mesh for instanced draws.\r\n     * It should avoid allocations and return a consistent value for a mesh during a render.\r\n     */\r\n    public meshBlendTagProvider?: GeometryRenderingMeshBlendTagProvider;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if normals should be generated in world space (default: false, meaning normals are generated in view space)\r\n     */\r\n    public generateNormalsInWorldSpace = false;\r\n\r\n    private _normalsAreUnsigned = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating if normals are encoded in the [0,1] range in the render target. If true, you should do `normal = normal_rt * 2.0 - 1.0` to get the right normal\r\n     */\r\n    public get normalsAreUnsigned() {\r\n        return this._normalsAreUnsigned;\r\n    }\r\n\r\n    private _scene: Scene;\r\n    private _resizeObserver: Nullable<Observer<AbstractEngine>> = null;\r\n    private _multiRenderTarget: MultiRenderTarget;\r\n    private _textureTypesAndFormats: { [key: number]: IGeometryBufferTextureTypeAndFormat };\r\n    private _ratioOrDimensions: number | { width: number; height: number };\r\n    private _enableDepth: boolean = true;\r\n    private _enableNormal: boolean = true;\r\n    private _enablePosition: boolean = false;\r\n    private _enableVelocity: boolean = false;\r\n    private _enableVelocityLinear: boolean = false;\r\n    private _enableReflectivity: boolean = false;\r\n    private _enableScreenspaceDepth: boolean = false;\r\n    private _enableIrradiance: boolean = false;\r\n    private _enableObjectId: boolean = false;\r\n    private _enableMeshBlendTag: boolean = false;\r\n    private _depthFormat: number;\r\n    private _clearColor = new Color4(0, 0, 0, 0);\r\n    private _clearDepthColor = new Color4(0, 0, 0, 1); // sets an invalid value by default - depth in the depth texture is view.z, so 0 is not possible because view.z can't be less than camera.minZ\r\n\r\n    private _positionIndex: number = -1;\r\n    private _velocityIndex: number = -1;\r\n    private _velocityLinearIndex: number = -1;\r\n    private _reflectivityIndex: number = -1;\r\n    private _depthIndex: number = -1;\r\n    private _normalIndex: number = -1;\r\n    private _screenspaceDepthIndex: number = -1;\r\n    private _irradianceIndex: number = -1;\r\n    private _objectIdIndex: number = -1;\r\n    private _meshBlendTagIndex: number = -1;\r\n\r\n    private _linkedWithPrePass: boolean = false;\r\n    private _prePassRenderer: PrePassRenderer;\r\n    private _attachmentsFromPrePass: number[];\r\n    private _useUbo: boolean;\r\n\r\n    protected _cachedDefines: string;\r\n\r\n    /**\r\n     * @internal\r\n     * Sets up internal structures to share outputs with PrePassRenderer\r\n     * This method should only be called by the PrePassRenderer itself\r\n     */\r\n    public _linkPrePassRenderer(prePassRenderer: PrePassRenderer) {\r\n        if (this._enableObjectId || this._enableMeshBlendTag) {\r\n            throw new Error(\"GeometryBufferRenderer: object ID and mesh-blending tag textures are not supported when linked to the PrePassRenderer\");\r\n        }\r\n\r\n        this._linkedWithPrePass = true;\r\n        this._prePassRenderer = prePassRenderer;\r\n\r\n        if (this._multiRenderTarget) {\r\n            // prevents clearing of the RT since it's done by prepass\r\n            this._multiRenderTarget.onClearObservable.clear();\r\n            this._multiRenderTarget.onClearObservable.add(() => {\r\n                // pass\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Separates internal structures from PrePassRenderer so the geometry buffer can now operate by itself.\r\n     * This method should only be called by the PrePassRenderer itself\r\n     */\r\n    public _unlinkPrePassRenderer() {\r\n        this._linkedWithPrePass = false;\r\n        this._createRenderTargets();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Resets the geometry buffer layout\r\n     */\r\n    public _resetLayout() {\r\n        this._enableDepth = true;\r\n        this._enableNormal = true;\r\n        this._enablePosition = false;\r\n        this._enableReflectivity = false;\r\n        this._enableVelocity = false;\r\n        this._enableVelocityLinear = false;\r\n        this._enableScreenspaceDepth = false;\r\n        this._enableIrradiance = false;\r\n        this._enableObjectId = false;\r\n        this._enableMeshBlendTag = false;\r\n        this._attachmentsFromPrePass = [];\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Replaces a texture in the geometry buffer renderer\r\n     * Useful when linking textures of the prepass renderer\r\n     */\r\n    public _forceTextureType(geometryBufferType: number, index: number) {\r\n        if (geometryBufferType === GeometryBufferRenderer.POSITION_TEXTURE_TYPE) {\r\n            this._positionIndex = index;\r\n            this._enablePosition = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE) {\r\n            this._velocityIndex = index;\r\n            this._enableVelocity = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE) {\r\n            this._velocityLinearIndex = index;\r\n            this._enableVelocityLinear = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE) {\r\n            this._reflectivityIndex = index;\r\n            this._enableReflectivity = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.DEPTH_TEXTURE_TYPE) {\r\n            this._depthIndex = index;\r\n            this._enableDepth = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.NORMAL_TEXTURE_TYPE) {\r\n            this._normalIndex = index;\r\n            this._enableNormal = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE) {\r\n            this._screenspaceDepthIndex = index;\r\n            this._enableScreenspaceDepth = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.IRRADIANCE_TEXTURE_TYPE) {\r\n            this._irradianceIndex = index;\r\n            this._enableIrradiance = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.OBJECT_ID_TEXTURE_TYPE) {\r\n            this._objectIdIndex = index;\r\n            this._enableObjectId = true;\r\n        } else if (geometryBufferType === GeometryBufferRenderer.MESH_BLEND_TAG_TEXTURE_TYPE) {\r\n            this._meshBlendTagIndex = index;\r\n            this._enableMeshBlendTag = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Sets texture attachments\r\n     * Useful when linking textures of the prepass renderer\r\n     */\r\n    public _setAttachments(attachments: number[]) {\r\n        this._attachmentsFromPrePass = attachments;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Replaces the first texture which is hard coded as a depth texture in the geometry buffer\r\n     * Useful when linking textures of the prepass renderer\r\n     */\r\n    public _linkInternalTexture(internalTexture: InternalTexture) {\r\n        this._multiRenderTarget.setInternalTexture(internalTexture, 0, false);\r\n    }\r\n\r\n    /**\r\n     * Gets the render list (meshes to be rendered) used in the G buffer.\r\n     */\r\n    public get renderList() {\r\n        return this._multiRenderTarget.renderList;\r\n    }\r\n\r\n    /**\r\n     * Set the render list (meshes to be rendered) used in the G buffer.\r\n     */\r\n    public set renderList(meshes: Nullable<AbstractMesh[]>) {\r\n        this._multiRenderTarget.renderList = meshes;\r\n    }\r\n\r\n    /**\r\n     * Gets whether or not G buffer are supported by the running hardware.\r\n     * This requires draw buffer supports\r\n     */\r\n    public get isSupported(): boolean {\r\n        return this._multiRenderTarget.isSupported;\r\n    }\r\n\r\n    /**\r\n     * Returns the index of the given texture type in the G-Buffer textures array\r\n     * @param textureType The texture type constant. For example GeometryBufferRenderer.POSITION_TEXTURE_INDEX\r\n     * @returns the index of the given texture type in the G-Buffer textures array\r\n     */\r\n    public getTextureIndex(textureType: number): number {\r\n        switch (textureType) {\r\n            case GeometryBufferRenderer.POSITION_TEXTURE_TYPE:\r\n                return this._positionIndex;\r\n            case GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE:\r\n                return this._velocityIndex;\r\n            case GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE:\r\n                return this._velocityLinearIndex;\r\n            case GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE:\r\n                return this._reflectivityIndex;\r\n            case GeometryBufferRenderer.DEPTH_TEXTURE_TYPE:\r\n                return this._depthIndex;\r\n            case GeometryBufferRenderer.NORMAL_TEXTURE_TYPE:\r\n                return this._normalIndex;\r\n            case GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE:\r\n                return this._screenspaceDepthIndex;\r\n            case GeometryBufferRenderer.IRRADIANCE_TEXTURE_TYPE:\r\n                return this._irradianceIndex;\r\n            case GeometryBufferRenderer.OBJECT_ID_TEXTURE_TYPE:\r\n                return this._objectIdIndex;\r\n            case GeometryBufferRenderer.MESH_BLEND_TAG_TEXTURE_TYPE:\r\n                return this._meshBlendTagIndex;\r\n            default:\r\n                return -1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns a boolean indicating if object's depths are enabled for the G buffer.\r\n     */\r\n    public get enableDepth(): boolean {\r\n        return this._enableDepth;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not object's depths are enabled for the G buffer.\r\n     */\r\n    public set enableDepth(enable: boolean) {\r\n        this._enableDepth = enable;\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns a boolean indicating if object's normals are enabled for the G buffer.\r\n     */\r\n    public get enableNormal(): boolean {\r\n        return this._enableNormal;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not object's normals are enabled for the G buffer.\r\n     */\r\n    public set enableNormal(enable: boolean) {\r\n        this._enableNormal = enable;\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns a boolean indicating if objects positions are enabled for the G buffer.\r\n     */\r\n    public get enablePosition(): boolean {\r\n        return this._enablePosition;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not objects positions are enabled for the G buffer.\r\n     */\r\n    public set enablePosition(enable: boolean) {\r\n        this._enablePosition = enable;\r\n\r\n        // PrePass handles index and texture links\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns a boolean indicating if objects velocities are enabled for the G buffer.\r\n     */\r\n    public get enableVelocity(): boolean {\r\n        return this._enableVelocity;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not objects velocities are enabled for the G buffer.\r\n     */\r\n    public set enableVelocity(enable: boolean) {\r\n        this._enableVelocity = enable;\r\n\r\n        if (!enable) {\r\n            this._previousTransformationMatrices = {};\r\n        }\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n\r\n        this._scene.needsPreviousWorldMatrices = enable;\r\n    }\r\n\r\n    /**\r\n     * @returns a boolean indicating if object's linear velocities are enabled for the G buffer.\r\n     */\r\n    public get enableVelocityLinear(): boolean {\r\n        return this._enableVelocityLinear;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not object's linear velocities are enabled for the G buffer.\r\n     */\r\n    public set enableVelocityLinear(enable: boolean) {\r\n        this._enableVelocityLinear = enable;\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if objects reflectivity are enabled in the G buffer.\r\n     */\r\n    public get enableReflectivity(): boolean {\r\n        return this._enableReflectivity;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not objects reflectivity are enabled for the G buffer.\r\n     * For Metallic-Roughness workflow with ORM texture, we assume that ORM texture is defined according to the default layout:\r\n     * pbr.useRoughnessFromMetallicTextureAlpha = false;\r\n     * pbr.useRoughnessFromMetallicTextureGreen = true;\r\n     * pbr.useMetallnessFromMetallicTextureBlue = true;\r\n     */\r\n    public set enableReflectivity(enable: boolean) {\r\n        this._enableReflectivity = enable;\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not objects screenspace depth are enabled for the G buffer.\r\n     */\r\n    public get enableScreenspaceDepth(): boolean {\r\n        return this._enableScreenspaceDepth;\r\n    }\r\n\r\n    public set enableScreenspaceDepth(enable: boolean) {\r\n        this._enableScreenspaceDepth = enable;\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if objects irradiance are enabled in the G buffer.\r\n     */\r\n    public get enableIrradiance(): boolean {\r\n        return this._enableIrradiance;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not objects irradiance are enabled for the G buffer.\r\n     */\r\n    public set enableIrradiance(enable: boolean) {\r\n        this._enableIrradiance = enable;\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets whether object IDs are enabled for the G buffer.\r\n     */\r\n    public get enableObjectId(): boolean {\r\n        return this._enableObjectId;\r\n    }\r\n\r\n    /**\r\n     * Sets whether object IDs are enabled for the G buffer.\r\n     *\r\n     * Object ID rendering currently requires a single-sample G buffer.\r\n     * Object ID rendering is not supported when the G buffer is linked to the PrePassRenderer.\r\n     * @see https://playground.babylonjs.com/?version=preview#SQXZ3X#1\r\n     */\r\n    public set enableObjectId(enable: boolean) {\r\n        if (enable && this._linkedWithPrePass) {\r\n            throw new Error(\"GeometryBufferRenderer: object ID textures are not supported when linked to the PrePassRenderer\");\r\n        }\r\n\r\n        if (enable && this.samples !== 1) {\r\n            throw new Error(\"GeometryBufferRenderer: object ID textures currently require samples to be 1\");\r\n        }\r\n\r\n        if (enable && !this._enableObjectId && !this._linkedWithPrePass) {\r\n            const engine = this._scene.getEngine();\r\n            const maxDrawBuffers = Math.min(engine.getCaps().maxDrawBuffers ?? 1, 8);\r\n            const attachmentCount = this._assignRenderTargetIndices()[0] + 1;\r\n            if (engine.getCaps().drawBuffersExtension && attachmentCount > maxDrawBuffers) {\r\n                throw new Error(`GeometryBufferRenderer: ${attachmentCount} color attachments were requested, but this engine supports at most ${maxDrawBuffers}`);\r\n            }\r\n        }\r\n\r\n        this._enableObjectId = enable;\r\n        if (!enable) {\r\n            this._objectIdIndex = -1;\r\n        }\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets whether packed mesh-blending tags are enabled for the G buffer.\r\n     */\r\n    public get enableMeshBlendingTag(): boolean {\r\n        return this._enableMeshBlendTag;\r\n    }\r\n\r\n    /**\r\n     * Sets whether packed mesh-blending tags are enabled for the G buffer.\r\n     *\r\n     * Mesh-blending tags use a single-sample R8UI color attachment and are supported on WebGL2 and WebGPU.\r\n     * Transparent rendering remains controlled by renderTransparentMeshes. Applications are responsible for\r\n     * ensuring that transparent draws do not invalidate the SceneColor and geometry-input correspondence required\r\n     * by the mesh-blending pass. On WebGL2, transparent rendering with this output requires per-target blend parameters.\r\n     *\r\n     * Enabling or disabling this output rebuilds the renderer's targets. The application retains ownership\r\n     * of the GeometryBufferRenderer and of every post process that consumes the output.\r\n     */\r\n    public set enableMeshBlendingTag(enable: boolean) {\r\n        if (this._enableMeshBlendTag === enable) {\r\n            return;\r\n        }\r\n\r\n        if (enable) {\r\n            const engine = this._scene.getEngine() as ThinEngine;\r\n            if (!_IsMeshBlendingSupported(engine)) {\r\n                throw new Error(\"GeometryBufferRenderer: mesh-blending tag textures require WebGL2 or WebGPU\");\r\n            }\r\n            if (this.renderTransparentMeshes && !engine.isWebGPU && !engine.getCaps().blendParametersPerTarget) {\r\n                throw new Error(\"GeometryBufferRenderer: transparent mesh-blending tags require per-target blend parameters\");\r\n            }\r\n            if (this._linkedWithPrePass) {\r\n                throw new Error(\"GeometryBufferRenderer: mesh-blending tag textures are not supported when linked to the PrePassRenderer\");\r\n            }\r\n            if (this.samples !== 1) {\r\n                throw new Error(\"GeometryBufferRenderer: mesh-blending tag textures require samples to be 1\");\r\n            }\r\n            if (!this._enableMeshBlendTag) {\r\n                const maxDrawBuffers = Math.min(engine.getCaps().maxDrawBuffers ?? 1, 8);\r\n                const attachmentCount = this._assignRenderTargetIndices()[0] + 1;\r\n                if (engine.getCaps().drawBuffersExtension && attachmentCount > maxDrawBuffers) {\r\n                    throw new Error(`GeometryBufferRenderer: ${attachmentCount} color attachments were requested, but this engine supports at most ${maxDrawBuffers}`);\r\n                }\r\n            }\r\n        }\r\n\r\n        this._enableMeshBlendTag = enable;\r\n        if (!enable) {\r\n            this._meshBlendTagIndex = -1;\r\n        }\r\n\r\n        if (!this._linkedWithPrePass) {\r\n            this.dispose();\r\n            this._createRenderTargets();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This will store a mask in the alpha channel of the irradiance texture to indicate which pixels have\r\n     * scattering and should be taken into account when applying image-based lighting.\r\n     */\r\n    public generateIrradianceWithScatterMask = false;\r\n\r\n    /**\r\n     * If set to true (default: false), the depth texture will be cleared with the depth value corresponding to the far plane (1 in normal mode, 0 in reverse depth buffer mode)\r\n     * If set to false, the depth texture is always cleared with 0.\r\n     */\r\n    public useSpecificClearForDepthTexture = false;\r\n\r\n    /**\r\n     * Gets the scene associated with the buffer.\r\n     */\r\n    public get scene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets the ratio used by the buffer during its creation.\r\n     * How big is the buffer related to the main canvas.\r\n     */\r\n    public get ratio(): number {\r\n        return typeof this._ratioOrDimensions === \"object\" ? 1 : this._ratioOrDimensions;\r\n    }\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"GeometryBufferRendererSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * Creates a new G Buffer for the scene\r\n     * @param scene The scene the buffer belongs to\r\n     * @param ratioOrDimensions How big is the buffer related to the main canvas (default: 1). You can also directly pass a width and height for the generated textures\r\n     * @param depthFormat Format of the depth texture (default: Constants.TEXTUREFORMAT_DEPTH16)\r\n     * @param textureTypesAndFormats The types, formats and optional sampling modes of textures to create as render targets.\r\n     * If not provided, all textures will be RGBA and float or half float, depending on the engine capabilities.\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        ratioOrDimensions: number | { width: number; height: number } = 1,\r\n        depthFormat = Constants.TEXTUREFORMAT_DEPTH16,\r\n        textureTypesAndFormats?: { [key: number]: IGeometryBufferTextureTypeAndFormat }\r\n    ) {\r\n        this._scene = scene;\r\n        this._ratioOrDimensions = ratioOrDimensions;\r\n        this._useUbo = scene.getEngine().supportsUniformBuffers;\r\n        this._depthFormat = depthFormat;\r\n        this._textureTypesAndFormats = textureTypesAndFormats || {};\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n\r\n        RegisterGeometryBufferRendererSceneComponent(GeometryBufferRenderer);\r\n        GeometryBufferRenderer._SceneComponentInitialization(this._scene);\r\n\r\n        // Render target\r\n        this._createRenderTargets();\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n\r\n    private async _initShaderSourceAsync() {\r\n        const engine = this._scene.getEngine();\r\n\r\n        if (engine.isWebGPU && !GeometryBufferRenderer.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([import(\"../ShadersWGSL/geometry.vertex\"), import(\"../ShadersWGSL/geometry.fragment\")]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/geometry.vertex\"), import(\"../Shaders/geometry.fragment\")]);\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n    }\r\n\r\n    /**\r\n     * Checks whether everything is ready to render a submesh to the G buffer.\r\n     * @param subMesh the submesh to check readiness for\r\n     * @param useInstances is the mesh drawn using instance or not\r\n     * @returns true if ready otherwise false\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        if (!this._shadersLoaded) {\r\n            return false;\r\n        }\r\n\r\n        const material = <any>subMesh.getMaterial();\r\n\r\n        if (material && material.disableDepthWrite) {\r\n            return false;\r\n        }\r\n\r\n        // Gaussian Splatting meshes store splat indices in position.z (not world-space Z).\r\n        // The generic geometry.vertex shader misreads this as world coordinates, producing\r\n        // garbage positions and normals, and thus they should be excluded from the G-buffer\r\n        // rendering.\r\n        if (_IsGaussianSplattingMesh(subMesh.getMesh())) {\r\n            return false;\r\n        }\r\n\r\n        const defines = [];\r\n        const attribs = [VertexBuffer.PositionKind];\r\n        const mesh = subMesh.getMesh();\r\n        const hasNormals = mesh.isVerticesDataPresent(VertexBuffer.NormalKind);\r\n\r\n        if (hasNormals) {\r\n            defines.push(\"#define HAS_NORMAL_ATTRIBUTE\");\r\n            attribs.push(VertexBuffer.NormalKind);\r\n        }\r\n\r\n        let uv1 = false;\r\n        let uv2 = false;\r\n        const color = false;\r\n\r\n        if (material) {\r\n            let needUv = false;\r\n            // Alpha test\r\n            if (material.needAlphaTestingForMesh(mesh) && material.getAlphaTestTexture()) {\r\n                defines.push(\"#define ALPHATEST\");\r\n                defines.push(`#define ALPHATEST_UV${material.getAlphaTestTexture().coordinatesIndex + 1}`);\r\n                needUv = true;\r\n            }\r\n\r\n            // Normal map texture\r\n            if ((material.bumpTexture || material.normalTexture || material.geometryNormalTexture) && MaterialFlags.BumpTextureEnabled) {\r\n                const texture = material.bumpTexture || material.normalTexture || material.geometryNormalTexture;\r\n                defines.push(\"#define BUMP\");\r\n                defines.push(`#define BUMP_UV${texture.coordinatesIndex + 1}`);\r\n                needUv = true;\r\n            }\r\n\r\n            if (this._enableReflectivity) {\r\n                let metallicWorkflow = false;\r\n                // for PBR materials: cf. https://doc.babylonjs.com/features/featuresDeepDive/materials/using/masterPBR\r\n                if (material.getClassName() === \"PBRMetallicRoughnessMaterial\") {\r\n                    // if it is a PBR material in MetallicRoughness Mode:\r\n                    if (material.metallicRoughnessTexture) {\r\n                        defines.push(\"#define ORMTEXTURE\");\r\n                        defines.push(`#define REFLECTIVITY_UV${material.metallicRoughnessTexture.coordinatesIndex + 1}`);\r\n                        defines.push(\"#define METALLICWORKFLOW\");\r\n                        needUv = true;\r\n                        metallicWorkflow = true;\r\n                    }\r\n                    // null or undefined\r\n                    if (material.metallic != null) {\r\n                        defines.push(\"#define METALLIC\");\r\n                        defines.push(\"#define METALLICWORKFLOW\");\r\n                        metallicWorkflow = true;\r\n                    }\r\n                    // null or undefined\r\n                    if (material.roughness != null) {\r\n                        defines.push(\"#define ROUGHNESS\");\r\n                        defines.push(\"#define METALLICWORKFLOW\");\r\n                        metallicWorkflow = true;\r\n                    }\r\n                    if (metallicWorkflow) {\r\n                        if (material.baseTexture) {\r\n                            defines.push(\"#define ALBEDOTEXTURE\");\r\n                            defines.push(`#define ALBEDO_UV${material.baseTexture.coordinatesIndex + 1}`);\r\n                            if (material.baseTexture.gammaSpace) {\r\n                                defines.push(\"#define GAMMAALBEDO\");\r\n                            }\r\n                            needUv = true;\r\n                        }\r\n                        if (material.baseColor) {\r\n                            defines.push(\"#define ALBEDOCOLOR\");\r\n                        }\r\n                    }\r\n                } else if (material.getClassName() === \"PBRSpecularGlossinessMaterial\") {\r\n                    // if it is a PBR material in Specular/Glossiness Mode:\r\n                    if (material.specularGlossinessTexture) {\r\n                        defines.push(\"#define SPECULARGLOSSINESSTEXTURE\");\r\n                        defines.push(`#define REFLECTIVITY_UV${material.specularGlossinessTexture.coordinatesIndex + 1}`);\r\n                        needUv = true;\r\n                        if (material.specularGlossinessTexture.gammaSpace) {\r\n                            defines.push(\"#define GAMMAREFLECTIVITYTEXTURE\");\r\n                        }\r\n                    } else {\r\n                        if (material.specularColor) {\r\n                            defines.push(\"#define REFLECTIVITYCOLOR\");\r\n                        }\r\n                    }\r\n                    // null or undefined\r\n                    if (material.glossiness != null) {\r\n                        defines.push(\"#define GLOSSINESS\");\r\n                    }\r\n                } else if (material.getClassName() === \"PBRMaterial\") {\r\n                    // if it is the bigger PBRMaterial\r\n                    if (material.metallicTexture) {\r\n                        defines.push(\"#define ORMTEXTURE\");\r\n                        defines.push(`#define REFLECTIVITY_UV${material.metallicTexture.coordinatesIndex + 1}`);\r\n                        defines.push(\"#define METALLICWORKFLOW\");\r\n                        needUv = true;\r\n                        metallicWorkflow = true;\r\n                    }\r\n                    // null or undefined\r\n                    if (material.metallic != null) {\r\n                        defines.push(\"#define METALLIC\");\r\n                        defines.push(\"#define METALLICWORKFLOW\");\r\n                        metallicWorkflow = true;\r\n                    }\r\n\r\n                    // null or undefined\r\n                    if (material.roughness != null) {\r\n                        defines.push(\"#define ROUGHNESS\");\r\n                        defines.push(\"#define METALLICWORKFLOW\");\r\n                        metallicWorkflow = true;\r\n                    }\r\n\r\n                    if (metallicWorkflow) {\r\n                        if (material.albedoTexture) {\r\n                            defines.push(\"#define ALBEDOTEXTURE\");\r\n                            defines.push(`#define ALBEDO_UV${material.albedoTexture.coordinatesIndex + 1}`);\r\n                            if (material.albedoTexture.gammaSpace) {\r\n                                defines.push(\"#define GAMMAALBEDO\");\r\n                            }\r\n                            needUv = true;\r\n                        }\r\n                        if (material.albedoColor) {\r\n                            defines.push(\"#define ALBEDOCOLOR\");\r\n                        }\r\n                    } else {\r\n                        // SpecularGlossiness Model\r\n                        if (material.reflectivityTexture) {\r\n                            defines.push(\"#define SPECULARGLOSSINESSTEXTURE\");\r\n                            defines.push(`#define REFLECTIVITY_UV${material.reflectivityTexture.coordinatesIndex + 1}`);\r\n                            if (material.reflectivityTexture.gammaSpace) {\r\n                                defines.push(\"#define GAMMAREFLECTIVITYTEXTURE\");\r\n                            }\r\n                            needUv = true;\r\n                        } else if (material.reflectivityColor) {\r\n                            defines.push(\"#define REFLECTIVITYCOLOR\");\r\n                        }\r\n                        // null or undefined\r\n                        if (material.microSurface != null) {\r\n                            defines.push(\"#define GLOSSINESS\");\r\n                        }\r\n                    }\r\n                } else if (material.getClassName() === \"StandardMaterial\") {\r\n                    // if StandardMaterial:\r\n                    if (material.specularTexture) {\r\n                        defines.push(\"#define REFLECTIVITYTEXTURE\");\r\n                        defines.push(`#define REFLECTIVITY_UV${material.specularTexture.coordinatesIndex + 1}`);\r\n                        if (material.specularTexture.gammaSpace) {\r\n                            defines.push(\"#define GAMMAREFLECTIVITYTEXTURE\");\r\n                        }\r\n                        needUv = true;\r\n                    }\r\n                    if (material.specularColor) {\r\n                        defines.push(\"#define REFLECTIVITYCOLOR\");\r\n                    }\r\n                } else if (material.getClassName() === \"OpenPBRMaterial\") {\r\n                    const openpbrMaterial = material as OpenPBRMaterial;\r\n\r\n                    defines.push(\"#define METALLIC\");\r\n                    defines.push(\"#define ROUGHNESS\");\r\n                    if (openpbrMaterial._useRoughnessFromMetallicTextureGreen && openpbrMaterial.baseMetalnessTexture) {\r\n                        defines.push(\"#define ORMTEXTURE\");\r\n                        defines.push(`#define REFLECTIVITY_UV${openpbrMaterial.baseMetalnessTexture.coordinatesIndex + 1}`);\r\n                        needUv = true;\r\n                    } else if (openpbrMaterial.baseMetalnessTexture) {\r\n                        defines.push(\"#define METALLIC_TEXTURE\");\r\n                        defines.push(`#define METALLIC_UV${openpbrMaterial.baseMetalnessTexture.coordinatesIndex + 1}`);\r\n                        needUv = true;\r\n                    } else if (openpbrMaterial.specularRoughnessTexture) {\r\n                        defines.push(\"#define ROUGHNESS_TEXTURE\");\r\n                        defines.push(`#define ROUGHNESS_UV${openpbrMaterial.specularRoughnessTexture.coordinatesIndex + 1}`);\r\n                        needUv = true;\r\n                    }\r\n\r\n                    if (openpbrMaterial.baseColorTexture) {\r\n                        defines.push(\"#define ALBEDOTEXTURE\");\r\n                        defines.push(`#define ALBEDO_UV${openpbrMaterial.baseColorTexture.coordinatesIndex + 1}`);\r\n                        if (openpbrMaterial.baseColorTexture.gammaSpace) {\r\n                            defines.push(\"#define GAMMAALBEDO\");\r\n                        }\r\n                        needUv = true;\r\n                    }\r\n                    if (openpbrMaterial.baseColor) {\r\n                        defines.push(\"#define ALBEDOCOLOR\");\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this._enableIrradiance && this.generateIrradianceWithScatterMask) {\r\n                defines.push(\"#define IRRADIANCE_SCATTER_MASK\");\r\n                if (material.getClassName() === \"OpenPBRMaterial\") {\r\n                    const openpbrMaterial = material as OpenPBRMaterial;\r\n                    if (openpbrMaterial.subsurfaceWeight > 0) {\r\n                        if (openpbrMaterial.subsurfaceWeightTexture) {\r\n                            defines.push(\"#define SUBSURFACE_WEIGHT\");\r\n                            defines.push(`#define SUBSURFACEWEIGHT_UV${openpbrMaterial.subsurfaceWeightTexture.coordinatesIndex + 1}`);\r\n                            needUv = true;\r\n                        }\r\n                    }\r\n                    if (openpbrMaterial.transmissionWeight > 0) {\r\n                        if (openpbrMaterial.transmissionWeightTexture) {\r\n                            defines.push(\"#define TRANSMISSION_WEIGHT\");\r\n                            defines.push(`#define TRANSMISSIONWEIGHT_UV${openpbrMaterial.transmissionWeightTexture.coordinatesIndex + 1}`);\r\n                            needUv = true;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (needUv) {\r\n                defines.push(\"#define NEED_UV\");\r\n                if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                    attribs.push(VertexBuffer.UVKind);\r\n                    defines.push(\"#define UV1\");\r\n                    uv1 = true;\r\n                }\r\n                if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n                    attribs.push(VertexBuffer.UV2Kind);\r\n                    defines.push(\"#define UV2\");\r\n                    uv2 = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Buffers\r\n        if (this._enableDepth) {\r\n            defines.push(\"#define DEPTH\");\r\n            defines.push(\"#define DEPTH_INDEX \" + this._depthIndex);\r\n        }\r\n\r\n        if (this._enableNormal) {\r\n            defines.push(\"#define NORMAL\");\r\n            defines.push(\"#define NORMAL_INDEX \" + this._normalIndex);\r\n        }\r\n\r\n        if (this._enablePosition) {\r\n            defines.push(\"#define POSITION\");\r\n            defines.push(\"#define POSITION_INDEX \" + this._positionIndex);\r\n        }\r\n\r\n        if (this._enableVelocity) {\r\n            defines.push(\"#define VELOCITY\");\r\n            defines.push(\"#define VELOCITY_INDEX \" + this._velocityIndex);\r\n            if (this.excludedSkinnedMeshesFromVelocity.indexOf(mesh) === -1) {\r\n                defines.push(\"#define BONES_VELOCITY_ENABLED\");\r\n            }\r\n        }\r\n\r\n        if (this._enableVelocityLinear) {\r\n            defines.push(\"#define VELOCITY_LINEAR\");\r\n            defines.push(\"#define VELOCITY_LINEAR_INDEX \" + this._velocityLinearIndex);\r\n            if (this.excludedSkinnedMeshesFromVelocity.indexOf(mesh) === -1) {\r\n                defines.push(\"#define BONES_VELOCITY_ENABLED\");\r\n            }\r\n        }\r\n\r\n        if (this._enableReflectivity) {\r\n            defines.push(\"#define REFLECTIVITY\");\r\n            defines.push(\"#define REFLECTIVITY_INDEX \" + this._reflectivityIndex);\r\n        }\r\n\r\n        if (this._enableScreenspaceDepth) {\r\n            if (this._screenspaceDepthIndex !== -1) {\r\n                defines.push(\"#define SCREENSPACE_DEPTH_INDEX \" + this._screenspaceDepthIndex);\r\n                defines.push(\"#define SCREENSPACE_DEPTH\");\r\n            }\r\n        }\r\n\r\n        if (this._enableIrradiance) {\r\n            if (this._irradianceIndex !== -1) {\r\n                defines.push(\"#define IRRADIANCE_INDEX \" + this._irradianceIndex);\r\n                defines.push(\"#define IRRADIANCE\");\r\n\r\n                // Check if scene has IBL setup\r\n                const scene = this._scene;\r\n                if (scene.environmentTexture) {\r\n                    const iblDefines: any = {};\r\n                    let realtime = false;\r\n                    let realtimeQuality: number = 0;\r\n                    if (\r\n                        material.getClassName() === \"OpenPBRMaterial\" ||\r\n                        material.getClassName() === \"StandardMaterial\" ||\r\n                        material.getClassName() === \"PBRMetallicRoughnessMaterial\" ||\r\n                        material.getClassName() === \"PBRSpecularGlossinessMaterial\" ||\r\n                        material.getClassName() === \"PBRMaterial\"\r\n                    ) {\r\n                        realtime = material.realtimeFiltering ? true : false;\r\n                        realtimeQuality = material.realtimeFilteringQuality || 0;\r\n                    }\r\n                    PrepareDefinesForIBL(scene, scene.environmentTexture, iblDefines, realtime, realtimeQuality, true);\r\n                    for (const define in iblDefines) {\r\n                        if (iblDefines[define]) {\r\n                            defines.push(\"#define \" + define);\r\n                        }\r\n                    }\r\n                    if (!iblDefines.USEIRRADIANCEMAP) {\r\n                        defines.push(\"#define SPHERICAL_HARMONICS\");\r\n                    }\r\n\r\n                    const iblShadowsPipeline = scene.postProcessRenderPipelineManager.supportedPipelines.find((p) => p.getClassName() === \"IBLShadowsRenderPipeline\");\r\n                    if (iblShadowsPipeline) {\r\n                        const pipeline = iblShadowsPipeline as IblShadowsRenderPipeline;\r\n                        const shadowTexture = pipeline._getAccumulatedTexture();\r\n                        if (shadowTexture) {\r\n                            defines.push(\"#define IBL_SHADOW_TEXTURE\");\r\n                            if (pipeline.coloredShadows) {\r\n                                defines.push(\"#define COLORED_IBL_SHADOWS\");\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._enableObjectId) {\r\n            defines.push(\"#define OBJECT_ID\");\r\n            defines.push(\"#define OBJECT_ID_INDEX \" + this._objectIdIndex);\r\n        }\r\n\r\n        if (this._enableMeshBlendTag) {\r\n            defines.push(\"#define MESH_BLEND_TAG\");\r\n            defines.push(\"#define MESH_BLEND_TAG_INDEX \" + this._meshBlendTagIndex);\r\n        }\r\n\r\n        if (this.generateNormalsInWorldSpace) {\r\n            defines.push(\"#define NORMAL_WORLDSPACE\");\r\n        }\r\n\r\n        if (this._normalsAreUnsigned) {\r\n            defines.push(\"#define ENCODE_NORMAL\");\r\n        }\r\n\r\n        // Bones\r\n        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n            attribs.push(VertexBuffer.MatricesIndicesKind);\r\n            attribs.push(VertexBuffer.MatricesWeightsKind);\r\n            if (mesh.numBoneInfluencers > 4) {\r\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n            }\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n            defines.push(\"#define BONETEXTURE \" + mesh.skeleton.isUsingTextureForMatrices);\r\n            defines.push(\"#define BonesPerMesh \" + (mesh.skeleton.bones.length + 1));\r\n        } else {\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n            defines.push(\"#define BONETEXTURE false\");\r\n            defines.push(\"#define BonesPerMesh 0\");\r\n        }\r\n\r\n        // Morph targets\r\n        const numMorphInfluencers = mesh.morphTargetManager\r\n            ? PrepareDefinesAndAttributesForMorphTargets(\r\n                  mesh.morphTargetManager,\r\n                  defines,\r\n                  attribs,\r\n                  mesh,\r\n                  true, // usePositionMorph\r\n                  true, // useNormalMorph\r\n                  false, // useTangentMorph\r\n                  uv1, // useUVMorph\r\n                  uv2, // useUV2Morph\r\n                  color // useColorMorph\r\n              )\r\n            : 0;\r\n\r\n        // Instances\r\n        if (useInstances) {\r\n            defines.push(\"#define INSTANCES\");\r\n            PushAttributesForInstances(attribs, this._enableVelocity || this._enableVelocityLinear);\r\n            if (subMesh.getRenderingMesh().hasThinInstances) {\r\n                defines.push(\"#define THIN_INSTANCES\");\r\n            }\r\n        }\r\n\r\n        // Setup textures count\r\n        if (this._linkedWithPrePass) {\r\n            defines.push(\"#define SCENE_MRT_COUNT \" + this._attachmentsFromPrePass.length);\r\n        } else {\r\n            defines.push(\"#define SCENE_MRT_COUNT \" + this._multiRenderTarget.textures.length);\r\n        }\r\n\r\n        PrepareStringDefinesForClipPlanes(material, this._scene, defines);\r\n\r\n        // Get correct effect\r\n        const engine = this._scene.getEngine();\r\n        const drawWrapper = subMesh._getDrawWrapper(undefined, true)!;\r\n        const cachedDefines = drawWrapper.defines;\r\n        const join = defines.join(\"\\n\");\r\n        if (cachedDefines !== join) {\r\n            drawWrapper.setEffect(\r\n                engine.createEffect(\r\n                    \"geometry\",\r\n                    {\r\n                        attributes: attribs,\r\n                        uniformsNames: Uniforms,\r\n                        samplers: Samplers,\r\n                        defines: join,\r\n                        onCompiled: null,\r\n                        fallbacks: null,\r\n                        onError: null,\r\n                        uniformBuffersNames: [\"Scene\"],\r\n                        indexParameters: { buffersCount: this._multiRenderTarget.textures.length - 1, maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                        shaderLanguage: this.shaderLanguage,\r\n                    },\r\n                    engine\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        return drawWrapper.effect!.isReady();\r\n    }\r\n\r\n    /**\r\n     * Gets the current underlying G Buffer.\r\n     * @returns the buffer\r\n     */\r\n    public getGBuffer(): MultiRenderTarget {\r\n        return this._multiRenderTarget;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of samples used to render the buffer (anti aliasing).\r\n     */\r\n    public get samples(): number {\r\n        return this._multiRenderTarget.samples;\r\n    }\r\n\r\n    /**\r\n     * Sets the number of samples used to render the buffer (anti aliasing).\r\n     */\r\n    public set samples(value: number) {\r\n        if (this._enableObjectId && value !== 1) {\r\n            throw new Error(\"GeometryBufferRenderer: object ID textures currently require samples to be 1\");\r\n        }\r\n        if (this._enableMeshBlendTag && value !== 1) {\r\n            throw new Error(\"GeometryBufferRenderer: mesh-blending tag textures require samples to be 1\");\r\n        }\r\n\r\n        this._multiRenderTarget.samples = value;\r\n    }\r\n\r\n    /**\r\n     * Disposes the renderer and frees up associated resources.\r\n     */\r\n    public dispose(): void {\r\n        if (this._resizeObserver) {\r\n            const engine = this._scene.getEngine();\r\n            engine.onResizeObservable.remove(this._resizeObserver);\r\n            this._resizeObserver = null;\r\n        }\r\n        if (this._multiRenderTarget?.renderTarget && this.scene.getEngine()._currentRenderTarget === this._multiRenderTarget.renderTarget) {\r\n            this.scene.getEngine().unBindFramebuffer(this._multiRenderTarget?.renderTarget);\r\n        }\r\n        this.getGBuffer().dispose();\r\n    }\r\n\r\n    private _assignRenderTargetIndices(): [number, string[], Array<IGeometryBufferTextureTypeAndFormat | undefined>] {\r\n        const textureNames: string[] = [];\r\n        const textureTypesAndFormats: Array<IGeometryBufferTextureTypeAndFormat | undefined> = [];\r\n        let count = 0;\r\n\r\n        if (this._enableDepth) {\r\n            this._depthIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_Depth\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.DEPTH_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableNormal) {\r\n            this._normalIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_Normal\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.NORMAL_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enablePosition) {\r\n            this._positionIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_Position\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.POSITION_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableVelocity) {\r\n            this._velocityIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_Velocity\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableVelocityLinear) {\r\n            this._velocityLinearIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_VelocityLinear\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableReflectivity) {\r\n            this._reflectivityIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_Reflectivity\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableScreenspaceDepth) {\r\n            this._screenspaceDepthIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_ScreenspaceDepth\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableIrradiance) {\r\n            this._irradianceIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_Irradiance\");\r\n            textureTypesAndFormats.push(this._textureTypesAndFormats[GeometryBufferRenderer.IRRADIANCE_TEXTURE_TYPE]);\r\n        }\r\n\r\n        if (this._enableObjectId) {\r\n            this._objectIdIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_ObjectId\");\r\n            textureTypesAndFormats.push({\r\n                textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                textureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            });\r\n        }\r\n\r\n        if (this._enableMeshBlendTag) {\r\n            this._meshBlendTagIndex = count;\r\n            count++;\r\n            textureNames.push(\"gBuffer_MeshBlendTag\");\r\n            textureTypesAndFormats.push({\r\n                textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                textureFormat: Constants.TEXTUREFORMAT_RED_INTEGER,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            });\r\n        }\r\n\r\n        return [count, textureNames, textureTypesAndFormats];\r\n    }\r\n\r\n    protected _createRenderTargets(): void {\r\n        const engine = this._scene.getEngine();\r\n        const [count, textureNames, textureTypesAndFormat] = this._assignRenderTargetIndices();\r\n\r\n        const maxDrawBuffers = Math.min(engine.getCaps().maxDrawBuffers ?? 1, 8);\r\n        if (engine.getCaps().drawBuffersExtension && count > maxDrawBuffers) {\r\n            throw new Error(`GeometryBufferRenderer: ${count} color attachments were requested, but this engine supports at most ${maxDrawBuffers}`);\r\n        }\r\n\r\n        let type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (engine._caps.textureFloat && engine._caps.textureFloatLinearFiltering) {\r\n            type = Constants.TEXTURETYPE_FLOAT;\r\n        } else if (engine._caps.textureHalfFloat && engine._caps.textureHalfFloatLinearFiltering) {\r\n            type = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        }\r\n\r\n        const dimensions = this._getRenderTargetDimensions();\r\n\r\n        const textureTypes: number[] = [];\r\n        const textureFormats: number[] = [];\r\n        const samplingModes: number[] = [];\r\n\r\n        for (const typeAndFormat of textureTypesAndFormat) {\r\n            if (typeAndFormat) {\r\n                textureTypes.push(typeAndFormat.textureType);\r\n                textureFormats.push(typeAndFormat.textureFormat);\r\n                samplingModes.push(typeAndFormat.samplingMode ?? Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            } else {\r\n                textureTypes.push(type);\r\n                textureFormats.push(Constants.TEXTUREFORMAT_RGBA);\r\n                samplingModes.push(Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n            }\r\n        }\r\n\r\n        this._normalsAreUnsigned =\r\n            textureTypes[GeometryBufferRenderer.NORMAL_TEXTURE_TYPE] === Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV ||\r\n            textureTypes[GeometryBufferRenderer.NORMAL_TEXTURE_TYPE] === Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV;\r\n\r\n        this._multiRenderTarget = new MultiRenderTarget(\r\n            \"gBuffer\",\r\n            dimensions,\r\n            count,\r\n            this._scene,\r\n            { generateMipMaps: false, generateDepthTexture: true, types: textureTypes, formats: textureFormats, samplingModes, depthTextureFormat: this._depthFormat },\r\n            textureNames.concat(\"gBuffer_DepthBuffer\")\r\n        );\r\n        if (!this.isSupported) {\r\n            return;\r\n        }\r\n        this._multiRenderTarget.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._multiRenderTarget.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._multiRenderTarget.refreshRate = 1;\r\n        this._multiRenderTarget.renderParticles = false;\r\n        this._multiRenderTarget.renderList = null;\r\n\r\n        // Depth is always the first texture in the geometry buffer renderer!\r\n        const layoutAttachmentsAll = [true];\r\n        const layoutAttachmentsAllButDepth = [false];\r\n        const layoutAttachmentsDepthOnly = [true];\r\n\r\n        for (let i = 1; i < count; ++i) {\r\n            layoutAttachmentsAll.push(true);\r\n            layoutAttachmentsDepthOnly.push(false);\r\n            layoutAttachmentsAllButDepth.push(true);\r\n        }\r\n\r\n        const attachmentsAll = engine.buildTextureLayout(layoutAttachmentsAll);\r\n        const attachmentsAllButDepth = engine.buildTextureLayout(layoutAttachmentsAllButDepth);\r\n        const attachmentsDepthOnly = engine.buildTextureLayout(layoutAttachmentsDepthOnly);\r\n\r\n        this._multiRenderTarget.onClearObservable.add((engine) => {\r\n            const colorAttachments = this.useSpecificClearForDepthTexture ? attachmentsAllButDepth : attachmentsAll;\r\n            engine.clearAttachments(this._clearColor, colorAttachments, true, true, true);\r\n            if (this.useSpecificClearForDepthTexture) {\r\n                engine.clearAttachments(this._clearDepthColor, attachmentsDepthOnly, true, false, false);\r\n            }\r\n            engine.bindAttachments(attachmentsAll);\r\n        });\r\n\r\n        this._resizeObserver = engine.onResizeObservable.add(() => {\r\n            if (this._multiRenderTarget) {\r\n                this._multiRenderTarget.resize(this._getRenderTargetDimensions());\r\n            }\r\n        });\r\n\r\n        // Custom render function\r\n        const renderSubMesh = (subMesh: SubMesh): void => {\r\n            const renderingMesh = subMesh.getRenderingMesh();\r\n            const effectiveMesh = subMesh.getEffectiveMesh();\r\n            const scene = this._scene;\r\n            const engine = scene.getEngine();\r\n            const material = <any>subMesh.getMaterial();\r\n\r\n            if (!material) {\r\n                return;\r\n            }\r\n\r\n            effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n\r\n            // Velocity\r\n            if ((this._enableVelocity || this._enableVelocityLinear) && !this._previousTransformationMatrices[effectiveMesh.uniqueId]) {\r\n                this._previousTransformationMatrices[effectiveMesh.uniqueId] = {\r\n                    world: Matrix.Identity(),\r\n                    viewProjection: scene.getTransformMatrix(),\r\n                };\r\n\r\n                if (renderingMesh.skeleton) {\r\n                    const bonesTransformations = renderingMesh.skeleton.getTransformMatrices(renderingMesh);\r\n                    this._previousBonesTransformationMatrices[renderingMesh.uniqueId] = this._copyBonesTransformationMatrices(\r\n                        bonesTransformations,\r\n                        new Float32Array(bonesTransformations.length)\r\n                    );\r\n                }\r\n            }\r\n\r\n            // Managing instances\r\n            const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n\r\n            if (batch.mustReturn) {\r\n                return;\r\n            }\r\n\r\n            const hardwareInstancedRendering = engine.getCaps().instancedArrays && (batch.visibleInstances[subMesh._id] !== null || renderingMesh.hasThinInstances);\r\n            const world = effectiveMesh.getWorldMatrix();\r\n\r\n            if (this.isReady(subMesh, hardwareInstancedRendering)) {\r\n                const drawWrapper = subMesh._getDrawWrapper();\r\n\r\n                if (!drawWrapper) {\r\n                    return;\r\n                }\r\n\r\n                const effect = drawWrapper.effect!;\r\n\r\n                engine.enableEffect(drawWrapper);\r\n                if (!hardwareInstancedRendering) {\r\n                    renderingMesh._bind(subMesh, effect, material.fillMode);\r\n                }\r\n\r\n                if (!this._useUbo) {\r\n                    effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\r\n                    effect.setMatrix(\"view\", scene.getViewMatrix());\r\n                    this._scene.bindEyePosition(effect, \"vEyePosition\");\r\n                } else {\r\n                    BindSceneUniformBuffer(effect, this._scene.getSceneUniformBuffer());\r\n                    this._scene.finalizeSceneUbo();\r\n                }\r\n\r\n                let sideOrientation: Nullable<number>;\r\n                const instanceDataStorage = renderingMesh._instanceDataStorage;\r\n\r\n                if (!instanceDataStorage.isFrozen && (material.backFaceCulling || material.sideOrientation !== null)) {\r\n                    const mainDeterminant = effectiveMesh._getWorldMatrixDeterminant();\r\n                    sideOrientation = material._getEffectiveOrientation(renderingMesh);\r\n\r\n                    if (mainDeterminant < 0) {\r\n                        sideOrientation = sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;\r\n                    }\r\n                } else {\r\n                    sideOrientation = renderingMesh._effectiveSideOrientation;\r\n                }\r\n\r\n                material._preBind(drawWrapper, sideOrientation);\r\n\r\n                // Alpha test\r\n                if (material.needAlphaTestingForMesh(effectiveMesh)) {\r\n                    const alphaTexture = material.getAlphaTestTexture();\r\n                    if (alphaTexture) {\r\n                        effect.setTexture(\"diffuseSampler\", alphaTexture);\r\n                        effect.setMatrix(\"diffuseMatrix\", alphaTexture.getTextureMatrix());\r\n                        effect.setFloat(\"alphaCutOff\", material.alphaCutOff ?? 0.4);\r\n                    }\r\n                }\r\n\r\n                // Bump\r\n                if (\r\n                    (material.bumpTexture || material.normalTexture || material.geometryNormalTexture) &&\r\n                    scene.getEngine().getCaps().standardDerivatives &&\r\n                    MaterialFlags.BumpTextureEnabled\r\n                ) {\r\n                    const texture = material.bumpTexture || material.normalTexture || material.geometryNormalTexture;\r\n                    effect.setFloat3(\"vBumpInfos\", texture.coordinatesIndex, 1.0 / texture.level, material.parallaxScaleBias);\r\n                    effect.setMatrix(\"bumpMatrix\", texture.getTextureMatrix());\r\n                    effect.setTexture(\"bumpSampler\", texture);\r\n                    effect.setFloat2(\"vTangentSpaceParams\", material.invertNormalMapX ? -1.0 : 1.0, material.invertNormalMapY ? -1.0 : 1.0);\r\n                }\r\n\r\n                // Reflectivity\r\n                if (this._enableReflectivity) {\r\n                    // for PBR materials: cf. https://doc.babylonjs.com/features/featuresDeepDive/materials/using/masterPBR\r\n                    if (material.getClassName() === \"PBRMetallicRoughnessMaterial\") {\r\n                        // if it is a PBR material in MetallicRoughness Mode:\r\n                        if (material.metallicRoughnessTexture !== null) {\r\n                            effect.setTexture(\"reflectivitySampler\", material.metallicRoughnessTexture);\r\n                            effect.setMatrix(\"reflectivityMatrix\", material.metallicRoughnessTexture.getTextureMatrix());\r\n                        }\r\n                        if (material.metallic !== null) {\r\n                            effect.setFloat(\"metallic\", material.metallic);\r\n                        }\r\n                        if (material.roughness !== null) {\r\n                            effect.setFloat(\"glossiness\", 1.0 - material.roughness);\r\n                        }\r\n                        if (material.baseTexture !== null) {\r\n                            effect.setTexture(\"albedoSampler\", material.baseTexture);\r\n                            effect.setMatrix(\"albedoMatrix\", material.baseTexture.getTextureMatrix());\r\n                        }\r\n                        if (material.baseColor !== null) {\r\n                            effect.setColor3(\"albedoColor\", material.baseColor);\r\n                        }\r\n                    } else if (material.getClassName() === \"PBRSpecularGlossinessMaterial\") {\r\n                        // if it is a PBR material in Specular/Glossiness Mode:\r\n                        if (material.specularGlossinessTexture !== null) {\r\n                            effect.setTexture(\"reflectivitySampler\", material.specularGlossinessTexture);\r\n                            effect.setMatrix(\"reflectivityMatrix\", material.specularGlossinessTexture.getTextureMatrix());\r\n                        } else {\r\n                            if (material.specularColor !== null) {\r\n                                effect.setColor3(\"reflectivityColor\", material.specularColor);\r\n                            }\r\n                        }\r\n                        if (material.glossiness !== null) {\r\n                            effect.setFloat(\"glossiness\", material.glossiness);\r\n                        }\r\n                    } else if (material.getClassName() === \"PBRMaterial\") {\r\n                        // if it is the bigger PBRMaterial\r\n                        if (material.metallicTexture !== null) {\r\n                            effect.setTexture(\"reflectivitySampler\", material.metallicTexture);\r\n                            effect.setMatrix(\"reflectivityMatrix\", material.metallicTexture.getTextureMatrix());\r\n                        }\r\n                        if (material.metallic !== null) {\r\n                            effect.setFloat(\"metallic\", material.metallic);\r\n                        }\r\n\r\n                        if (material.roughness !== null) {\r\n                            effect.setFloat(\"glossiness\", 1.0 - material.roughness);\r\n                        }\r\n\r\n                        if (material.roughness !== null || material.metallic !== null || material.metallicTexture !== null) {\r\n                            // MetallicRoughness Model\r\n                            if (material.albedoTexture !== null) {\r\n                                effect.setTexture(\"albedoSampler\", material.albedoTexture);\r\n                                effect.setMatrix(\"albedoMatrix\", material.albedoTexture.getTextureMatrix());\r\n                            }\r\n                            if (material.albedoColor !== null) {\r\n                                effect.setColor3(\"albedoColor\", material.albedoColor);\r\n                            }\r\n                        } else {\r\n                            // SpecularGlossiness Model\r\n                            if (material.reflectivityTexture !== null) {\r\n                                effect.setTexture(\"reflectivitySampler\", material.reflectivityTexture);\r\n                                effect.setMatrix(\"reflectivityMatrix\", material.reflectivityTexture.getTextureMatrix());\r\n                            } else if (material.reflectivityColor !== null) {\r\n                                effect.setColor3(\"reflectivityColor\", material.reflectivityColor);\r\n                            }\r\n                            if (material.microSurface !== null) {\r\n                                effect.setFloat(\"glossiness\", material.microSurface);\r\n                            }\r\n                        }\r\n                    } else if (material.getClassName() === \"StandardMaterial\") {\r\n                        // if StandardMaterial:\r\n                        if (material.specularTexture !== null) {\r\n                            effect.setTexture(\"reflectivitySampler\", material.specularTexture);\r\n                            effect.setMatrix(\"reflectivityMatrix\", material.specularTexture.getTextureMatrix());\r\n                        }\r\n                        if (material.specularColor !== null) {\r\n                            effect.setColor3(\"reflectivityColor\", material.specularColor);\r\n                        }\r\n                    } else if (material.getClassName() === \"OpenPBRMaterial\") {\r\n                        // if it is a OpenPBR material:\r\n                        const openpbrMaterial = material as OpenPBRMaterial;\r\n                        if (openpbrMaterial._useRoughnessFromMetallicTextureGreen && openpbrMaterial.baseMetalnessTexture) {\r\n                            effect.setTexture(\"reflectivitySampler\", openpbrMaterial.baseMetalnessTexture);\r\n                            effect.setMatrix(\"reflectivityMatrix\", openpbrMaterial.baseMetalnessTexture.getTextureMatrix());\r\n                        } else if (openpbrMaterial.baseMetalnessTexture) {\r\n                            effect.setTexture(\"metallicSampler\", openpbrMaterial.baseMetalnessTexture);\r\n                            effect.setMatrix(\"metallicMatrix\", openpbrMaterial.baseMetalnessTexture.getTextureMatrix());\r\n                        } else if (openpbrMaterial.specularRoughnessTexture) {\r\n                            effect.setTexture(\"roughnessSampler\", openpbrMaterial.specularRoughnessTexture);\r\n                            effect.setMatrix(\"roughnessMatrix\", openpbrMaterial.specularRoughnessTexture.getTextureMatrix());\r\n                        }\r\n                        effect.setFloat(\"metallic\", openpbrMaterial.baseMetalness);\r\n                        effect.setFloat(\"glossiness\", 1.0 - openpbrMaterial.specularRoughness);\r\n                        if (openpbrMaterial.baseColorTexture !== null) {\r\n                            effect.setTexture(\"albedoSampler\", openpbrMaterial.baseColorTexture);\r\n                            effect.setMatrix(\"albedoMatrix\", openpbrMaterial.baseColorTexture.getTextureMatrix());\r\n                        }\r\n                        if (openpbrMaterial.baseColor !== null) {\r\n                            effect.setColor3(\"albedoColor\", openpbrMaterial.baseColor);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // IBL binding for irradiance\r\n                if (this._enableIrradiance && scene.environmentTexture) {\r\n                    const reflectionTexture = scene.environmentTexture;\r\n\r\n                    const iblShadowsPipeline = scene.postProcessRenderPipelineManager.supportedPipelines.find((p) => p.getClassName() === \"IBLShadowsRenderPipeline\");\r\n                    if (iblShadowsPipeline) {\r\n                        const pipeline = iblShadowsPipeline as IblShadowsRenderPipeline;\r\n                        const shadowTexture = pipeline._getAccumulatedTexture();\r\n                        if (shadowTexture) {\r\n                            effect.setTexture(\"iblShadowSampler\", shadowTexture);\r\n                            effect.setFloat2(\"shadowTextureSize\", shadowTexture.getSize().width, shadowTexture.getSize().height);\r\n                        }\r\n                    }\r\n\r\n                    // Bind reflection matrix\r\n                    effect.setMatrix(\"reflectionMatrix\", reflectionTexture.getReflectionTextureMatrix());\r\n\r\n                    // Bind reflection info (intensity and other parameters)\r\n                    effect.setFloat2(\"vReflectionInfos\", reflectionTexture.level * scene.iblIntensity, 0.0);\r\n\r\n                    // Bind reflection sampler\r\n                    effect.setTexture(\"reflectionSampler\", reflectionTexture);\r\n\r\n                    // Bind irradiance sampler if available\r\n                    if (reflectionTexture.irradianceTexture) {\r\n                        effect.setTexture(\"irradianceSampler\", reflectionTexture.irradianceTexture);\r\n                        if (reflectionTexture.irradianceTexture._dominantDirection) {\r\n                            effect.setVector3(\"vReflectionDominantDirection\", reflectionTexture.irradianceTexture._dominantDirection);\r\n                        }\r\n                    }\r\n\r\n                    // Bind spherical harmonics uniforms if available\r\n                    if (reflectionTexture.sphericalPolynomial) {\r\n                        const polynomials = reflectionTexture.sphericalPolynomial;\r\n                        if (polynomials.preScaledHarmonics) {\r\n                            const harmonics = polynomials.preScaledHarmonics;\r\n                            effect.setVector3(\"vSphericalL00\", harmonics.l00);\r\n                            effect.setVector3(\"vSphericalL1_1\", harmonics.l1_1);\r\n                            effect.setVector3(\"vSphericalL10\", harmonics.l10);\r\n                            effect.setVector3(\"vSphericalL11\", harmonics.l11);\r\n                            effect.setVector3(\"vSphericalL2_2\", harmonics.l2_2);\r\n                            effect.setVector3(\"vSphericalL2_1\", harmonics.l2_1);\r\n                            effect.setVector3(\"vSphericalL20\", harmonics.l20);\r\n                            effect.setVector3(\"vSphericalL21\", harmonics.l21);\r\n                            effect.setVector3(\"vSphericalL22\", harmonics.l22);\r\n                        } else {\r\n                            effect.setFloat3(\"vSphericalX\", polynomials.x.x, polynomials.x.y, polynomials.x.z);\r\n                            effect.setFloat3(\"vSphericalY\", polynomials.y.x, polynomials.y.y, polynomials.y.z);\r\n                            effect.setFloat3(\"vSphericalZ\", polynomials.z.x, polynomials.z.y, polynomials.z.z);\r\n                            effect.setFloat3(\"vSphericalXX_ZZ\", polynomials.xx.x - polynomials.zz.x, polynomials.xx.y - polynomials.zz.y, polynomials.xx.z - polynomials.zz.z);\r\n                            effect.setFloat3(\"vSphericalYY_ZZ\", polynomials.yy.x - polynomials.zz.x, polynomials.yy.y - polynomials.zz.y, polynomials.yy.z - polynomials.zz.z);\r\n                            effect.setFloat3(\"vSphericalZZ\", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z);\r\n                            effect.setFloat3(\"vSphericalXY\", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z);\r\n                            effect.setFloat3(\"vSphericalYZ\", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z);\r\n                            effect.setFloat3(\"vSphericalZX\", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);\r\n                        }\r\n                    }\r\n\r\n                    if (this.generateIrradianceWithScatterMask && material.getClassName() === \"OpenPBRMaterial\") {\r\n                        const openpbrMaterial = material as OpenPBRMaterial;\r\n                        effect.setFloat(\"vSubsurfaceWeight\", openpbrMaterial.subsurfaceWeight);\r\n                        if (openpbrMaterial.subsurfaceWeightTexture) {\r\n                            effect.setTexture(\"subsurfaceWeightSampler\", openpbrMaterial.subsurfaceWeightTexture);\r\n                            effect.setMatrix(\"subsurfaceWeightMatrix\", openpbrMaterial.subsurfaceWeightTexture.getTextureMatrix());\r\n                        }\r\n                        effect.setFloat(\"vTransmissionWeight\", openpbrMaterial.transmissionWeight);\r\n                        if (openpbrMaterial.transmissionWeightTexture) {\r\n                            effect.setTexture(\"transmissionWeightSampler\", openpbrMaterial.transmissionWeightTexture);\r\n                            effect.setMatrix(\"transmissionWeightMatrix\", openpbrMaterial.transmissionWeightTexture.getTextureMatrix());\r\n                        }\r\n                        effect.setFloat(\"vTransmissionScatterAnisotropy\", openpbrMaterial.transmissionScatterAnisotropy);\r\n                        effect.setFloat(\"vSubsurfaceScatterAnisotropy\", openpbrMaterial.subsurfaceScatterAnisotropy);\r\n                    }\r\n                }\r\n\r\n                // Clip plane\r\n                BindClipPlane(effect, material, this._scene);\r\n\r\n                // Bones\r\n                if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {\r\n                    const skeleton = renderingMesh.skeleton;\r\n\r\n                    if (skeleton.isUsingTextureForMatrices && effect.getUniformIndex(\"boneTextureInfo\") > -1) {\r\n                        const boneTexture = skeleton.getTransformMatrixTexture(renderingMesh);\r\n                        effect.setTexture(\"boneSampler\", boneTexture);\r\n                        effect.setFloat2(\"boneTextureInfo\", skeleton._textureWidth, skeleton._textureHeight);\r\n                    } else {\r\n                        effect.setMatrices(\"mBones\", renderingMesh.skeleton.getTransformMatrices(renderingMesh));\r\n                    }\r\n\r\n                    if (this._enableVelocity || this._enableVelocityLinear) {\r\n                        effect.setMatrices(\"mPreviousBones\", this._previousBonesTransformationMatrices[renderingMesh.uniqueId]);\r\n                    }\r\n                }\r\n\r\n                // Morph targets\r\n                BindMorphTargetParameters(renderingMesh, effect);\r\n                if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\r\n                    renderingMesh.morphTargetManager._bind(effect);\r\n                }\r\n\r\n                // Velocity\r\n                if (this._enableVelocity || this._enableVelocityLinear) {\r\n                    effect.setMatrix(\"previousWorld\", this._previousTransformationMatrices[effectiveMesh.uniqueId].world);\r\n                    effect.setMatrix(\"previousViewProjection\", this._previousTransformationMatrices[effectiveMesh.uniqueId].viewProjection);\r\n                }\r\n\r\n                if (this._enableObjectId) {\r\n                    let objectId = renderingMesh.uniqueId;\r\n                    if (this.objectIdProvider) {\r\n                        objectId = _GetGeometryRenderingObjectId(renderingMesh, this.objectIdProvider);\r\n                    } else if (objectId > 0xffffff) {\r\n                        throw new Error(`Invalid geometry object ID ${objectId} for mesh \"${renderingMesh.name}\". Object IDs must be integers between 0 and 0xFFFFFF.`);\r\n                    }\r\n                    effect.setFloat(\"objectId\", objectId);\r\n                }\r\n\r\n                if (this._enableMeshBlendTag) {\r\n                    const meshBlendTag = this.meshBlendTagProvider ? _GetGeometryRenderingMeshBlendTag(renderingMesh, this.meshBlendTagProvider) : renderingMesh.meshBlendingTag;\r\n                    effect.setInt(\"meshBlendTag\", meshBlendTag);\r\n                }\r\n\r\n                if (hardwareInstancedRendering && renderingMesh.hasThinInstances) {\r\n                    effect.setMatrix(\"world\", world);\r\n                }\r\n\r\n                // Draw\r\n                renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, w) => {\r\n                    if (!isInstance) {\r\n                        effect.setMatrix(\"world\", w);\r\n                    }\r\n                });\r\n            }\r\n\r\n            // Velocity\r\n            if (this._enableVelocity || this._enableVelocityLinear) {\r\n                this._previousTransformationMatrices[effectiveMesh.uniqueId].world = world.clone();\r\n                this._previousTransformationMatrices[effectiveMesh.uniqueId].viewProjection = this._scene.getTransformMatrix().clone();\r\n                if (renderingMesh.skeleton) {\r\n                    this._copyBonesTransformationMatrices(\r\n                        renderingMesh.skeleton.getTransformMatrices(renderingMesh),\r\n                        this._previousBonesTransformationMatrices[effectiveMesh.uniqueId]\r\n                    );\r\n                }\r\n            }\r\n        };\r\n\r\n        this._multiRenderTarget.customIsReadyFunction = (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => {\r\n            if ((preWarm || refreshRate === 0) && mesh.subMeshes) {\r\n                for (let i = 0; i < mesh.subMeshes.length; ++i) {\r\n                    const subMesh = mesh.subMeshes[i];\r\n                    const material = subMesh.getMaterial();\r\n                    const renderingMesh = subMesh.getRenderingMesh();\r\n\r\n                    if (!material) {\r\n                        continue;\r\n                    }\r\n\r\n                    const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n                    const hardwareInstancedRendering = engine.getCaps().instancedArrays && (batch.visibleInstances[subMesh._id] !== null || renderingMesh.hasThinInstances);\r\n\r\n                    if (!this.isReady(subMesh, hardwareInstancedRendering)) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return true;\r\n        };\r\n\r\n        this._multiRenderTarget.customRenderFunction = (\r\n            opaqueSubMeshes: SmartArray<SubMesh>,\r\n            alphaTestSubMeshes: SmartArray<SubMesh>,\r\n            transparentSubMeshes: SmartArray<SubMesh>,\r\n            depthOnlySubMeshes: SmartArray<SubMesh>\r\n        ): void => {\r\n            let index;\r\n\r\n            if (this._linkedWithPrePass) {\r\n                if (!this._prePassRenderer.enabled) {\r\n                    return;\r\n                }\r\n                this._scene.getEngine().bindAttachments(this._attachmentsFromPrePass);\r\n            }\r\n\r\n            if (depthOnlySubMeshes.length) {\r\n                engine.setColorWrite(false);\r\n                for (index = 0; index < depthOnlySubMeshes.length; index++) {\r\n                    renderSubMesh(depthOnlySubMeshes.data[index]);\r\n                }\r\n                engine.setColorWrite(true);\r\n            }\r\n\r\n            for (index = 0; index < opaqueSubMeshes.length; index++) {\r\n                renderSubMesh(opaqueSubMeshes.data[index]);\r\n            }\r\n\r\n            engine.setDepthWrite(false);\r\n            for (index = 0; index < alphaTestSubMeshes.length; index++) {\r\n                renderSubMesh(alphaTestSubMeshes.data[index]);\r\n            }\r\n\r\n            if (this.renderTransparentMeshes) {\r\n                for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                    renderSubMesh(transparentSubMeshes.data[index]);\r\n                }\r\n            }\r\n            engine.setDepthWrite(true);\r\n        };\r\n    }\r\n\r\n    private _getRenderTargetDimensions(): { width: number; height: number } {\r\n        if (typeof this._ratioOrDimensions === \"object\") {\r\n            return {\r\n                width: Math.max(1, Math.floor(this._ratioOrDimensions.width)),\r\n                height: Math.max(1, Math.floor(this._ratioOrDimensions.height)),\r\n            };\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n        return {\r\n            width: Math.max(1, Math.floor(engine.getRenderWidth() * this._ratioOrDimensions)),\r\n            height: Math.max(1, Math.floor(engine.getRenderHeight() * this._ratioOrDimensions)),\r\n        };\r\n    }\r\n\r\n    // Copies the bones transformation matrices into the target array and returns the target's reference\r\n    private _copyBonesTransformationMatrices(source: Float32Array, target: Float32Array): Float32Array {\r\n        for (let i = 0; i < source.length; i++) {\r\n            target[i] = source[i];\r\n        }\r\n\r\n        return target;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryBufferRenderer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryBufferRenderer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    PrepareUniformsAndSamplersForIBL(Uniforms, Samplers, true);\r\n\r\n    AddClipPlaneUniforms(Uniforms);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { serialize, expandToProperty, addAccessorsForMaterialProperty } from \"../../Misc/decorators\";\r\nimport { GetEnvironmentFuzzBRDFTexture, GetOpenPBREnvironmentBRDFTexture } from \"../../Misc/brdfTextureTools\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Color3, Color4 } from \"../../Maths/math.color.pure\";\r\nimport { ImageProcessingConfiguration, RegisterImageProcessingConfiguration } from \"../imageProcessingConfiguration.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type ThinTexture } from \"../../Materials/Textures/thinTexture\";\r\nimport { Texture } from \"../Textures/texture.pure\";\r\nimport { Material } from \"../material.pure\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { type Engine } from \"../../Engines/engine.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../../Materials/effect.pure\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\nimport { ImageProcessingDefinesMixin } from \"../imageProcessingConfiguration.defines\";\r\nimport { EffectFallbacks } from \"../effectFallbacks\";\r\nimport { AddClipPlaneUniforms, BindClipPlane } from \"../clipPlaneMaterialHelper\";\r\nimport { PrepareVertexPullingUniforms, BindVertexPullingUniforms, type IVertexPullingMetadata } from \"../vertexPullingHelper.functions\";\r\nimport {\r\n    BindBonesParameters,\r\n    BindFogParameters,\r\n    BindLights,\r\n    BindLogDepth,\r\n    BindMorphTargetParameters,\r\n    BindTextureMatrix,\r\n    BindIBLParameters,\r\n    BindIBLSamplers,\r\n    HandleFallbacksForShadows,\r\n    PrepareAttributesForBakedVertexAnimation,\r\n    PrepareAttributesForBones,\r\n    PrepareAttributesForInstances,\r\n    PrepareAttributesForMorphTargets,\r\n    PrepareDefinesForAttributes,\r\n    PrepareDefinesForFrameBoundValues,\r\n    PrepareDefinesForLights,\r\n    PrepareDefinesForIBL,\r\n    PrepareDefinesForMergedUV,\r\n    PrepareDefinesForMisc,\r\n    PrepareDefinesForMultiview,\r\n    PrepareDefinesForOIT,\r\n    PrepareDefinesForPrePass,\r\n    PrepareUniformsAndSamplersList,\r\n    PrepareUniformsAndSamplersForIBL,\r\n    PrepareUniformLayoutForIBL,\r\n    AreLightsTexturesReady,\r\n} from \"../materialHelper.functions\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { MaterialPluginEvent } from \"../materialPluginEvent\";\r\nimport { MaterialHelperGeometryRendering } from \"../materialHelper.geometryrendering\";\r\nimport { PrePassConfiguration } from \"../prePassConfiguration\";\r\nimport { type IMaterialCompilationOptions, type ICustomShaderNameResolveOptions } from \"../../Materials/material.pure\";\r\nimport { _ShaderImportLoader } from \"../../Misc/shaderImportLoader\";\r\nimport { MaterialFlags } from \"../materialFlags\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { UVDefinesMixin } from \"../uv.defines\";\r\nimport { PrepassDefinesMixin } from \"../prepass.defines\";\r\nimport { EnvironmentLightingDefinesMixin } from \"../environmentLighting.defines\";\r\nimport { Vector2, Vector3, Vector4, TmpVectors, type Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { ImageProcessingMixin } from \"../imageProcessing\";\r\nimport { PushMaterial } from \"../pushMaterial\";\r\nimport { SmartArray } from \"../../Misc/smartArray\";\r\nimport { type RenderTargetTexture } from \"../Textures/renderTargetTexture.pure\";\r\nimport { type IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { GeometryBufferRenderer } from \"core/Rendering/geometryBufferRenderer.pure\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\nconst onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };\r\n\r\nfunction _GetComponentCount(value: PropertyType): number {\r\n    if (typeof value === \"number\") {\r\n        return 1;\r\n    }\r\n    if (value instanceof Vector2) {\r\n        return 2;\r\n    }\r\n    if (value instanceof Vector3 || value instanceof Color3) {\r\n        return 3;\r\n    }\r\n    if (value instanceof Vector4 || value instanceof Color4) {\r\n        return 4;\r\n    }\r\n\r\n    throw new Error(\"Unsupported OpenPBR property type.\");\r\n}\r\n\r\nclass Uniform {\r\n    public name: string;\r\n    public numComponents: number;\r\n    public linkedProperties: { [name: string]: Property<PropertyType> } = {};\r\n    /**\r\n     * Cached key of the first entry of `linkedProperties`, set when the first\r\n     * property is linked. Used by the per-frame bind loop to avoid an\r\n     * `Object.keys(linkedProperties)[0]` allocation when reading scalar\r\n     * uniforms.\r\n     */\r\n    public firstLinkedKey: string = \"\";\r\n    /**\r\n     * Optional define name. If set, the per-frame bind loop will skip pushing\r\n     * this uniform to the UBO unless `defines[requiredDefine]` is true. The\r\n     * UBO slot still exists in the layout; only the per-frame update is\r\n     * skipped, which is safe because the shader only reads these uniforms\r\n     * inside the same #ifdef block.\r\n     */\r\n    public requiredDefine?: string;\r\n    public populateVectorFromLinkedProperties(vector: Vector4 | Vector3 | Vector2): void {\r\n        const destinationSize = _GetComponentCount(vector);\r\n        for (const propKey in this.linkedProperties) {\r\n            const prop = this.linkedProperties[propKey];\r\n            const sourceSize = prop.numComponents;\r\n            if (destinationSize < sourceSize || prop.targetUniformComponentOffset > destinationSize - sourceSize) {\r\n                if (sourceSize == 1) {\r\n                    Logger.Error(`Float property ${prop.name} has an offset that is too large.`);\r\n                } else {\r\n                    Logger.Error(`Vector${sourceSize} property ${prop.name} won't fit in Vector${destinationSize} or has an offset that is too large.`);\r\n                }\r\n                return;\r\n            }\r\n            if (typeof prop.value === \"number\") {\r\n                Uniform._tmpArray[prop.targetUniformComponentOffset] = prop.value;\r\n            } else {\r\n                prop.value.toArray(Uniform._tmpArray, prop.targetUniformComponentOffset);\r\n            }\r\n        }\r\n        vector.fromArray(Uniform._tmpArray);\r\n    }\r\n    public constructor(name: string, componentNum: number) {\r\n        this.name = name;\r\n        this.numComponents = componentNum;\r\n    }\r\n    private static _tmpArray: number[] = [0, 0, 0, 0];\r\n}\r\n\r\ntype PropertyType = Vector2 | Vector3 | Vector4 | number | Color3 | Color4;\r\n\r\n/**\r\n * Defines a property for the OpenPBRMaterial.\r\n */\r\nclass Property<T extends PropertyType> {\r\n    public name: string;\r\n    public targetUniformName: string;\r\n    public defaultValue: T;\r\n    public value: T;\r\n    // public includeAlphaFromProp: string = \"\";\r\n\r\n    /**\r\n     * If not given a type, there will be no uniform defined for this property and\r\n     * it will be assumed that the value will be packed into the already existing \"uniformName\" uniform.\r\n     */\r\n    public targetUniformComponentNum: number = 4; // Default to vec4\r\n    public targetUniformComponentOffset: number = 0;\r\n    /**\r\n     * Optional define name. If set, the per-frame bind loop will skip pushing\r\n     * the owning uniform to the UBO unless this define is active. All\r\n     * properties packed into the same uniform must share the same\r\n     * `requiredDefine` (or none of them must set it) for the gating to apply.\r\n     */\r\n    public requiredDefine?: string;\r\n\r\n    /**\r\n     * Creates a new Property instance.\r\n     * @param name The name of the property in the shader\r\n     * @param defaultValue The default value of the property\r\n     * @param targetUniformName The name of the property in the shader uniform block\r\n     * @param targetUniformComponentNum The number of components in the target uniform. All properties that are\r\n     * packed into the same uniform must agree on the size of the target uniform.\r\n     * @param targetUniformComponentOffset The offset in the uniform where this property will be packed.\r\n     * @param requiredDefine Optional define name. When provided, the per-frame\r\n     *  bind loop will skip pushing the owning uniform to the UBO unless\r\n     *  `defines[requiredDefine]` is true.\r\n     */\r\n    constructor(name: string, defaultValue: T, targetUniformName: string, targetUniformComponentNum: number, targetUniformComponentOffset: number = 0, requiredDefine?: string) {\r\n        this.name = name;\r\n        this.targetUniformName = targetUniformName;\r\n        this.defaultValue = defaultValue;\r\n        this.value = defaultValue;\r\n        this.targetUniformComponentNum = targetUniformComponentNum;\r\n        this.targetUniformComponentOffset = targetUniformComponentOffset;\r\n        this.requiredDefine = requiredDefine;\r\n    }\r\n\r\n    /**\r\n     * Returns the number of components of the property based on its default value type.\r\n     */\r\n    public get numComponents(): number {\r\n        if (typeof this.defaultValue === \"number\") {\r\n            return 1;\r\n        }\r\n        return _GetComponentCount(this.defaultValue);\r\n    }\r\n}\r\n\r\nclass Sampler {\r\n    public name: string;\r\n    public value: Nullable<BaseTexture> = null; // Texture value, default to null\r\n    public samplerPrefix: string = \"\"; // The name of the sampler in the shader\r\n    public textureDefine: string = \"\"; // The define used in the shader for this sampler\r\n\r\n    /**\r\n     * The name of the sampler used in the shader.\r\n     * If this naming changes, we'll also need to change:\r\n     * - samplerFragmentDeclaration.fx\r\n     * - openpbr.fragment.fx\r\n     */\r\n    public get samplerName(): string {\r\n        return this.samplerPrefix + \"Sampler\";\r\n    }\r\n    /**\r\n     * The name of the sampler info used in the shader.\r\n     * If this naming changes, we'll also need to change:\r\n     * - openpbr.vertex.fx\r\n     * - openpbr.fragment.fx\r\n     */\r\n    public get samplerInfoName(): string {\r\n        return \"v\" + this.samplerPrefix.charAt(0).toUpperCase() + this.samplerPrefix.slice(1) + \"Infos\";\r\n    }\r\n    /**\r\n     * The name of the matrix used for this sampler in the shader.\r\n     * If this naming changes, we'll also need to change:\r\n     * - materialHelper.functions.BindTextureMatrix\r\n     * - samplerVertexImplementation.fx\r\n     * - openpbr.fragment.fx\r\n     */\r\n    public get samplerMatrixName(): string {\r\n        return this.samplerPrefix + \"Matrix\";\r\n    }\r\n    /**\r\n     * Creates a new Sampler instance.\r\n     * @param name The name of the texture property\r\n     * @param samplerPrefix The prefix used for the name of the sampler in the shader\r\n     * @param textureDefine The define used in the shader for this sampler\r\n     */\r\n    constructor(name: string, samplerPrefix: string, textureDefine: string) {\r\n        this.name = name;\r\n        this.samplerPrefix = samplerPrefix;\r\n        this.textureDefine = textureDefine;\r\n    }\r\n}\r\n\r\nclass OpenPBRMaterialDefinesBase extends PrepassDefinesMixin(UVDefinesMixin(MaterialDefines)) {}\r\n\r\nclass OpenPBRMaterialDefinesWithEnvLighting extends EnvironmentLightingDefinesMixin(OpenPBRMaterialDefinesBase) {}\r\n\r\n/**\r\n * Manages the defines for the PBR Material.\r\n * @internal\r\n */\r\nexport class OpenPBRMaterialDefines extends ImageProcessingDefinesMixin(OpenPBRMaterialDefinesWithEnvLighting) {\r\n    public NUM_SAMPLES = \"0\";\r\n    public REALTIME_FILTERING = false;\r\n    public IBL_CDF_FILTERING = false;\r\n    public LIGHTCOUNT = 0;\r\n    public VERTEXCOLOR = false;\r\n\r\n    public BAKED_VERTEX_ANIMATION_TEXTURE = false;\r\n\r\n    public VERTEXALPHA = false;\r\n    public ALPHATEST = false;\r\n    public DEPTHPREPASS = false;\r\n    public ALPHABLEND = false;\r\n    public ALPHA_FROM_BASE_COLOR_TEXTURE = false;\r\n    public ALPHATESTVALUE = \"0.5\";\r\n    public PREMULTIPLYALPHA = false;\r\n\r\n    public REFLECTIVITY_GAMMA = false;\r\n    public REFLECTIVITYDIRECTUV = 0;\r\n    public SPECULARTERM = false;\r\n\r\n    public LODBASEDMICROSFURACE = true;\r\n\r\n    public SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN = false;\r\n    public BASE_METALNESS_FROM_METALNESS_TEXTURE_BLUE = false;\r\n    public AOSTOREINMETALMAPRED = false;\r\n    public SPECULAR_WEIGHT_IN_ALPHA = false;\r\n    public SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE = false;\r\n    public SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = false;\r\n    public COAT_ROUGHNESS_FROM_GREEN_CHANNEL = false;\r\n    public COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = false;\r\n    public USE_GLTF_STYLE_ANISOTROPY = false;\r\n    public THIN_FILM_THICKNESS_FROM_THIN_FILM_TEXTURE = false;\r\n    public FUZZ_ROUGHNESS_FROM_TEXTURE_ALPHA = false;\r\n    public SUBSURFACE_WEIGHT_FROM_TEXTURE_ALPHA = false;\r\n    public GEOMETRY_THICKNESS_FROM_GREEN_CHANNEL = false;\r\n\r\n    public ENVIRONMENTBRDF = false;\r\n    public ENVIRONMENTBRDF_RGBD = false;\r\n    public FUZZENVIRONMENTBRDF = false;\r\n\r\n    public NORMAL = false;\r\n    public TANGENT = false;\r\n    public OBJECTSPACE_NORMALMAP = false;\r\n    public PARALLAX = false;\r\n    public PARALLAX_RHS = false;\r\n    public PARALLAXOCCLUSION = false;\r\n    public NORMALXYSCALE = true;\r\n    /**\r\n     * Enables anisotropic logic. Still needed because it's used in pbrHelperFunctions\r\n     */\r\n    public ANISOTROPIC = false;\r\n    /**\r\n     * Tells the shader to use OpenPBR's anisotropic roughness remapping\r\n     */\r\n    public ANISOTROPIC_OPENPBR = true;\r\n    /**\r\n     * Tells the shader to apply anisotropy to the base layer\r\n     */\r\n    public ANISOTROPIC_BASE = false;\r\n    /**\r\n     * Tells the shader to apply anisotropy to the coat layer\r\n     */\r\n    public ANISOTROPIC_COAT = false;\r\n\r\n    /**\r\n     * Number of samples to use for the fuzz IBL lighting calculations\r\n     */\r\n    public FUZZ_IBL_SAMPLES = 6;\r\n\r\n    /**\r\n     * Enables the 4-tap rotated-grid kernel for refractive background blur.\r\n     * When false, a single dithered sample is used instead.\r\n     */\r\n    public REFRACTION_HIGH_QUALITY_BLUR = false;\r\n\r\n    /**\r\n     * Tells the shader to enable the fuzz layer\r\n     */\r\n    public FUZZ = false;\r\n\r\n    /**\r\n     * Tells the shader to enable the thin film layer\r\n     */\r\n    public THIN_FILM = false;\r\n\r\n    /**\r\n     * Tells the shader to enable the legacy iridescence code\r\n     * Iridescence is the name of thin film interference in the PBR material.\r\n     */\r\n    public IRIDESCENCE = false;\r\n\r\n    /**\r\n     * Tells the shader to enable dispersion in refraction\r\n     */\r\n    public DISPERSION = false;\r\n\r\n    /**\r\n     * Enables subsurface scattering\r\n     */\r\n    public SCATTERING = false;\r\n\r\n    /**\r\n     * Enables the use of screen-space irradiance texture for scattering\r\n     */\r\n    public USE_IRRADIANCE_TEXTURE_FOR_SCATTERING = false;\r\n\r\n    /**\r\n     * Number of samples used by the screen-space SSS convolution kernel.\r\n     */\r\n    public SSS_SAMPLE_COUNT = 16;\r\n\r\n    /**\r\n     * Indicates that the irradiance texture is from the legacy GeometryBufferRenderer.\r\n     * We use this to handle direct lights which don't render in the legacy GBuffer irradiance.\r\n     */\r\n    public USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER = false;\r\n\r\n    /**\r\n     * Enables transmission slab\r\n     */\r\n    public TRANSMISSION_SLAB = false;\r\n\r\n    /**\r\n     * Enables transmission slab with volume\r\n     */\r\n    public TRANSMISSION_SLAB_VOLUME = false;\r\n\r\n    /**\r\n     * Enables subsurface slab\r\n     */\r\n    public SUBSURFACE_SLAB = false;\r\n\r\n    /**\r\n     * Enables thin-walled geometry\r\n     */\r\n    public GEOMETRY_THIN_WALLED = false;\r\n\r\n    /**\r\n     * Refraction of the 2D background texture. Might include the rest of the scene or just the background.\r\n     */\r\n    public REFRACTED_BACKGROUND = false;\r\n\r\n    /**\r\n     * Refraction of direct lights.\r\n     */\r\n    public REFRACTED_LIGHTS = false;\r\n\r\n    /**\r\n     * Refraction of the environment texture (IBL).\r\n     */\r\n    public REFRACTED_ENVIRONMENT = false;\r\n    public REFRACTED_ENVIRONMENT_OPPOSITEZ = false;\r\n    public REFRACTED_ENVIRONMENT_LOCAL_CUBE = false;\r\n\r\n    public RADIANCEOCCLUSION = false;\r\n    public HORIZONOCCLUSION = false;\r\n\r\n    public INSTANCES = false;\r\n    public THIN_INSTANCES = false;\r\n    public INSTANCESCOLOR = false;\r\n\r\n    public NUM_BONE_INFLUENCERS = 0;\r\n    public BonesPerMesh = 0;\r\n    public BONETEXTURE = false;\r\n    public BONES_VELOCITY_ENABLED = false;\r\n\r\n    public NONUNIFORMSCALING = false;\r\n\r\n    public MORPHTARGETS = false;\r\n    public MORPHTARGETS_POSITION = false;\r\n    public MORPHTARGETS_NORMAL = false;\r\n    public MORPHTARGETS_TANGENT = false;\r\n    public MORPHTARGETS_UV = false;\r\n    public MORPHTARGETS_UV2 = false;\r\n    public MORPHTARGETS_COLOR = false;\r\n    public MORPHTARGETTEXTURE_HASPOSITIONS = false;\r\n    public MORPHTARGETTEXTURE_HASNORMALS = false;\r\n    public MORPHTARGETTEXTURE_HASTANGENTS = false;\r\n    public MORPHTARGETTEXTURE_HASUVS = false;\r\n    public MORPHTARGETTEXTURE_HASUV2S = false;\r\n    public MORPHTARGETTEXTURE_HASCOLORS = false;\r\n    public NUM_MORPH_INFLUENCERS = 0;\r\n    public MORPHTARGETS_TEXTURE = false;\r\n\r\n    public USEPHYSICALLIGHTFALLOFF = false;\r\n    public USEGLTFLIGHTFALLOFF = false;\r\n    public TWOSIDEDLIGHTING = false;\r\n    public MIRRORED = false;\r\n    public SHADOWFLOAT = false;\r\n    public CLIPPLANE = false;\r\n    public CLIPPLANE2 = false;\r\n    public CLIPPLANE3 = false;\r\n    public CLIPPLANE4 = false;\r\n    public CLIPPLANE5 = false;\r\n    public CLIPPLANE6 = false;\r\n    public POINTSIZE = false;\r\n    public FOG = false;\r\n    public LOGARITHMICDEPTH = false;\r\n    public CAMERA_ORTHOGRAPHIC = false;\r\n    public CAMERA_PERSPECTIVE = false;\r\n    public AREALIGHTSUPPORTED = true;\r\n\r\n    public FORCENORMALFORWARD = false;\r\n\r\n    public SPECULARAA = false;\r\n\r\n    public UNLIT = false;\r\n\r\n    public DECAL_AFTER_DETAIL = false;\r\n\r\n    public TEXTURE_REPETITION_MODE = 0;\r\n\r\n    public DEBUGMODE = 0;\r\n    public USE_VERTEX_PULLING = false;\r\n    public VERTEX_PULLING_USE_INDEX_BUFFER = false;\r\n    public VERTEX_PULLING_INDEX_BUFFER_32BITS = false;\r\n    public RIGHT_HANDED = false;\r\n\r\n    public CLUSTLIGHT_SLICES = 0;\r\n    public CLUSTLIGHT_BATCH = 0;\r\n\r\n    // BRDF defines\r\n    BRDF_V_HEIGHT_CORRELATED = true;\r\n    MS_BRDF_ENERGY_CONSERVATION = true;\r\n    SPHERICAL_HARMONICS = true;\r\n    SPECULAR_GLOSSINESS_ENERGY_CONSERVATION = true;\r\n    MIX_IBL_RADIANCE_WITH_IRRADIANCE = true;\r\n    LEGACY_SPECULAR_ENERGY_CONSERVATION = false;\r\n    BASE_DIFFUSE_MODEL = Constants.MATERIAL_DIFFUSE_MODEL_E_OREN_NAYAR;\r\n    DIELECTRIC_SPECULAR_MODEL = Constants.MATERIAL_DIELECTRIC_SPECULAR_MODEL_OPENPBR;\r\n    CONDUCTOR_SPECULAR_MODEL = Constants.MATERIAL_CONDUCTOR_SPECULAR_MODEL_OPENPBR;\r\n\r\n    /**\r\n     * Initializes the PBR Material defines.\r\n     * @param externalProperties The external properties\r\n     */\r\n    constructor(externalProperties?: { [name: string]: { type: string; default: any } }) {\r\n        super(externalProperties);\r\n        this.rebuild();\r\n    }\r\n\r\n    /**\r\n     * Resets the PBR Material defines.\r\n     */\r\n    public override reset(): void {\r\n        super.reset();\r\n        this.ALPHATESTVALUE = \"0.5\";\r\n        this.NORMALXYSCALE = true;\r\n    }\r\n}\r\n\r\nclass OpenPBRMaterialBase extends ImageProcessingMixin(PushMaterial) {}\r\n/**\r\n * A Physically based material that follows the specification of OpenPBR.\r\n *\r\n * For more information, please refer to the documentation :\r\n * https://academysoftwarefoundation.github.io/OpenPBR/index.html\r\n */\r\nexport class OpenPBRMaterial extends OpenPBRMaterialBase {\r\n    /**\r\n     * Base Weight is a multiplier on the diffuse and metal lobes.\r\n     * See OpenPBR's specs for base_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseWeight: Property<number> = new Property<number>(\"base_weight\", 1, \"vBaseWeight\", 1);\r\n\r\n    /**\r\n     * Base Weight is a multiplier on the diffuse and metal lobes.\r\n     * See OpenPBR's specs for base_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseWeightTexture: Sampler = new Sampler(\"base_weight\", \"baseWeight\", \"BASE_WEIGHT\");\r\n\r\n    /**\r\n     * Color of the base diffuse lobe.\r\n     * See OpenPBR's specs for base_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseColor: Property<Color3> = new Property<Color3>(\"base_color\", Color3.White(), \"vBaseColor\", 4);\r\n\r\n    /**\r\n     * Base Color Texture property.\r\n     * See OpenPBR's specs for base_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseColorTexture: Sampler = new Sampler(\"base_color\", \"baseColor\", \"BASE_COLOR\");\r\n\r\n    /**\r\n     * Roughness of the diffuse lobe.\r\n     * See OpenPBR's specs for base_diffuse_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseDiffuseRoughness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseDiffuseRoughness: Property<number> = new Property<number>(\"base_diffuse_roughness\", 0, \"vBaseDiffuseRoughness\", 1);\r\n\r\n    /**\r\n     * Roughness texture of the diffuse lobe.\r\n     * See OpenPBR's specs for base_diffuse_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseDiffuseRoughnessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseDiffuseRoughnessTexture: Sampler = new Sampler(\"base_diffuse_roughness\", \"baseDiffuseRoughness\", \"BASE_DIFFUSE_ROUGHNESS\");\r\n\r\n    /**\r\n     * Metalness of the base lobe.\r\n     * See OpenPBR's specs for base_metalness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseMetalness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseMetalness: Property<number> = new Property<number>(\"base_metalness\", 0, \"vReflectanceInfo\", 4, 0);\r\n\r\n    /**\r\n     * Metalness texture.\r\n     * See OpenPBR's specs for base_metalness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor baseMetalnessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _baseMetalnessTexture: Sampler = new Sampler(\"base_metalness\", \"baseMetalness\", \"BASE_METALNESS\");\r\n\r\n    /**\r\n     * Weight of the specular lobe.\r\n     * See OpenPBR's specs for specular_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularWeight: Property<number> = new Property<number>(\"specular_weight\", 1, \"vReflectanceInfo\", 4, 3);\r\n\r\n    /**\r\n     * Weight texture of the specular lobe.\r\n     * See OpenPBR's specs for specular_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularWeightTexture: Sampler = new Sampler(\"specular_weight\", \"specularWeight\", \"SPECULAR_WEIGHT\");\r\n\r\n    /**\r\n     * Color of the specular lobe.\r\n     * See OpenPBR's specs for specular_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularColor: Property<Color3> = new Property<Color3>(\"specular_color\", Color3.White(), \"vSpecularColor\", 4);\r\n\r\n    /**\r\n     * Specular Color Texture property.\r\n     * See OpenPBR's specs for specular_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularColorTexture: Sampler = new Sampler(\"specular_color\", \"specularColor\", \"SPECULAR_COLOR\");\r\n\r\n    /**\r\n     * Roughness of the specular lobe.\r\n     * See OpenPBR's specs for specular_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularRoughness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularRoughness: Property<number> = new Property<number>(\"specular_roughness\", 0.3, \"vReflectanceInfo\", 4, 1);\r\n\r\n    /**\r\n     * Roughness texture of the specular lobe.\r\n     * See OpenPBR's specs for specular_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularRoughnessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularRoughnessTexture: Sampler = new Sampler(\"specular_roughness\", \"specularRoughness\", \"SPECULAR_ROUGHNESS\");\r\n\r\n    /**\r\n     * Anisotropic roughness of the specular lobe.\r\n     * See OpenPBR's specs for specular_roughness_anisotropy\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularRoughnessAnisotropy: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularRoughnessAnisotropy: Property<number> = new Property<number>(\"specular_roughness_anisotropy\", 0, \"vSpecularAnisotropy\", 3, 2);\r\n\r\n    /**\r\n     * Anisotropic Roughness texture.\r\n     * See OpenPBR's specs for specular_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularRoughnessAnisotropyTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularRoughnessAnisotropyTexture: Sampler = new Sampler(\"specular_roughness_anisotropy\", \"specularRoughnessAnisotropy\", \"SPECULAR_ROUGHNESS_ANISOTROPY\");\r\n\r\n    /**\r\n     * IOR of the specular lobe.\r\n     * See OpenPBR's specs for specular_ior\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor specularIor: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _specularIor: Property<number> = new Property<number>(\"specular_ior\", 1.5, \"vReflectanceInfo\", 4, 2);\r\n\r\n    /**\r\n     * Transmission weight of the surface.\r\n     * See OpenPBR's specs for transmission_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionWeight: Property<number> = new Property<number>(\"transmission_weight\", 0.0, \"vTransmissionWeight\", 1);\r\n\r\n    /**\r\n     * Transmission weight texture.\r\n     * See OpenPBR's specs for transmission_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionWeightTexture: Sampler = new Sampler(\"transmission_weight\", \"transmissionWeight\", \"TRANSMISSION_WEIGHT\");\r\n\r\n    /**\r\n     * Transmission color of the surface.\r\n     * See OpenPBR's specs for transmission_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionColor: Property<Color3> = new Property<Color3>(\"transmission_color\", Color3.White(), \"vTransmissionColor\", 3, 0);\r\n\r\n    /**\r\n     * Transmission color texture.\r\n     * See OpenPBR's specs for transmission_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionColorTexture: Sampler = new Sampler(\"transmission_color\", \"transmissionColor\", \"TRANSMISSION_COLOR\");\r\n\r\n    /**\r\n     * Transmission depth of the volume\r\n     * See OpenPBR's specs for transmission_depth\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionDepth: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionDepth: Property<number> = new Property<number>(\"transmission_depth\", 0.0, \"vTransmissionDepth\", 1, 0);\r\n\r\n    /**\r\n     * Transmission depth texture.\r\n     * See OpenPBR's specs for transmission_depth\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionDepthTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionDepthTexture: Sampler = new Sampler(\"transmission_depth\", \"transmissionDepth\", \"TRANSMISSION_DEPTH\");\r\n\r\n    /**\r\n     * Transmission scatter of the surface.\r\n     * See OpenPBR's specs for transmission_scatter\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionScatter: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionScatter: Property<Color3> = new Property<Color3>(\"transmission_scatter\", Color3.Black(), \"vTransmissionScatter\", 3, 0);\r\n\r\n    /**\r\n     * Transmission scatter texture.\r\n     * See OpenPBR's specs for transmission_scatter\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionScatterTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionScatterTexture: Sampler = new Sampler(\"transmission_scatter\", \"transmissionScatter\", \"TRANSMISSION_SCATTER\");\r\n\r\n    /**\r\n     * Transmission scatter anisotropy\r\n     * See OpenPBR's specs for transmission_scatter_anisotropy\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionScatterAnisotropy: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionScatterAnisotropy: Property<number> = new Property<number>(\"transmission_scatter_anisotropy\", 0.0, \"vTransmissionScatterAnisotropy\", 1, 0);\r\n\r\n    /**\r\n     * Transmission Dispersion Scale factor.\r\n     * See OpenPBR's specs for transmission_dispersion_scale\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionDispersionScale: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionDispersionScale: Property<number> = new Property<number>(\"transmission_dispersion_scale\", 0.0, \"vTransmissionDispersionScale\", 1, 0);\r\n\r\n    /**\r\n     * Transmission Dispersion Scale texture.\r\n     * See OpenPBR's specs for transmission_dispersion_scale\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionDispersionScaleTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionDispersionScaleTexture: Sampler = new Sampler(\"transmission_dispersion_scale\", \"transmissionDispersionScale\", \"TRANSMISSION_DISPERSION_SCALE\");\r\n\r\n    /**\r\n     * Transmission Dispersion Abbe number.\r\n     * See OpenPBR's specs for transmission_dispersion_abbe_number\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor transmissionDispersionAbbeNumber: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _transmissionDispersionAbbeNumber: Property<number> = new Property<number>(\"transmission_dispersion_abbe_number\", 20.0, \"vTransmissionDispersionAbbeNumber\", 1, 0);\r\n\r\n    /**\r\n     * Defines the amount of subsurface scattering on the surface.\r\n     * See OpenPBR's specs for subsurface_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceWeight: Property<number> = new Property<number>(\"subsurface_weight\", 0.0, \"vSubsurfaceWeight\", 1, 0, \"SUBSURFACE_SLAB\");\r\n\r\n    /**\r\n     * Subsurface weight texture.\r\n     * See OpenPBR's specs for subsurface_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceWeightTexture: Sampler = new Sampler(\"subsurface_weight\", \"subsurfaceWeight\", \"SUBSURFACE_WEIGHT\");\r\n\r\n    /**\r\n     * Defines the color of the subsurface scattering in the volume.\r\n     * See OpenPBR's specs for subsurface_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceColor: Property<Color3> = new Property<Color3>(\"subsurface_color\", new Color3(0.8, 0.8, 0.8), \"vSubsurfaceColor\", 3, 0, \"SUBSURFACE_SLAB\");\r\n\r\n    /**\r\n     * Subsurface color texture.\r\n     * See OpenPBR's specs for subsurface_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceColorTexture: Sampler = new Sampler(\"subsurface_color\", \"subsurfaceColor\", \"SUBSURFACE_COLOR\");\r\n\r\n    /**\r\n     * Defines the radius of the subsurface scattering in the volume.\r\n     * See OpenPBR's specs for subsurface_radius\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceRadius: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceRadius: Property<number> = new Property<number>(\"subsurface_radius\", 0.1, \"vSubsurfaceRadius\", 1, 0, \"SUBSURFACE_SLAB\");\r\n\r\n    /**\r\n     * Defines the scale factor applied to the subsurface radius.\r\n     * See OpenPBR's specs for subsurface_radius_scale\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceRadiusScale: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceRadiusScale: Property<Color3> = new Property<Color3>(\"subsurface_radius_scale\", new Color3(1, 0.5, 0.25), \"vSubsurfaceRadiusScale\", 3, 0, \"SUBSURFACE_SLAB\");\r\n\r\n    /**\r\n     * Subsurface radius scale texture.\r\n     * See OpenPBR's specs for subsurface_radius_scale\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceRadiusScaleTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceRadiusScaleTexture: Sampler = new Sampler(\"subsurface_radius_scale\", \"subsurfaceRadiusScale\", \"SUBSURFACE_RADIUS_SCALE\");\r\n\r\n    /**\r\n     * Defines the anisotropy of the subsurface scattering in the volume.\r\n     * See OpenPBR's specs for subsurface_scatter_anisotropy\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor subsurfaceScatterAnisotropy: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _subsurfaceScatterAnisotropy: Property<number> = new Property<number>(\"subsurface_scatter_anisotropy\", 0.0, \"vSubsurfaceScatterAnisotropy\", 1, 0, \"SUBSURFACE_SLAB\");\r\n\r\n    /**\r\n     * Defines the amount of clear coat on the surface.\r\n     * See OpenPBR's specs for coat_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatWeight: Property<number> = new Property<number>(\"coat_weight\", 0.0, \"vCoatWeight\", 1, 0);\r\n\r\n    /**\r\n     * Coat weight texture.\r\n     * See OpenPBR's specs for coat_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatWeightTexture: Sampler = new Sampler(\"coat_weight\", \"coatWeight\", \"COAT_WEIGHT\");\r\n\r\n    /**\r\n     * Defines the color of the clear coat on the surface.\r\n     * See OpenPBR's specs for coat_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatColor: Property<Color3> = new Property<Color3>(\"coat_color\", Color3.White(), \"vCoatColor\", 3, 0);\r\n\r\n    /**\r\n     * Color texture of the clear coat.\r\n     * See OpenPBR's specs for coat_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatColorTexture: Sampler = new Sampler(\"coat_color\", \"coatColor\", \"COAT_COLOR\");\r\n\r\n    /**\r\n     * Defines the roughness of the clear coat on the surface.\r\n     * See OpenPBR's specs for coat_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatRoughness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatRoughness: Property<number> = new Property<number>(\"coat_roughness\", 0.0, \"vCoatRoughness\", 1, 0);\r\n\r\n    /**\r\n     * Roughness texture of the clear coat.\r\n     * See OpenPBR's specs for coat_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatRoughnessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatRoughnessTexture: Sampler = new Sampler(\"coat_roughness\", \"coatRoughness\", \"COAT_ROUGHNESS\");\r\n\r\n    /**\r\n     * Defines the anisotropy of the clear coat on the surface.\r\n     * See OpenPBR's specs for coat_roughness_anisotropy\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatRoughnessAnisotropy: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatRoughnessAnisotropy: Property<number> = new Property<number>(\"coat_roughness_anisotropy\", 0, \"vCoatRoughnessAnisotropy\", 1);\r\n\r\n    /**\r\n     * Anisotropic Roughness texture of the clear coat.\r\n     * See OpenPBR's specs for coat_roughness_anisotropy\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatRoughnessAnisotropyTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatRoughnessAnisotropyTexture: Sampler = new Sampler(\"coat_roughness_anisotropy\", \"coatRoughnessAnisotropy\", \"COAT_ROUGHNESS_ANISOTROPY\");\r\n\r\n    /**\r\n     * Defines the IOR of the clear coat on the surface.\r\n     * See OpenPBR's specs for coat_ior\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatIor: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatIor: Property<number> = new Property<number>(\"coat_ior\", 1.5, \"vCoatIor\", 1, 0);\r\n\r\n    /**\r\n     * Defines the amount that interreflections within the coat allow the underlying surface\r\n     * to be darkened. A value of 1.0 means that the physically correct amount of darkening\r\n     * is applied, while a value of 0.0 means that no darkening is applied.\r\n     * See OpenPBR's specs for coat_darkening\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatDarkening: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatDarkening: Property<number> = new Property<number>(\"coat_darkening\", 1.0, \"vCoatDarkening\", 1, 0);\r\n\r\n    /**\r\n     * Defines the amount that interreflections within the coat allow the underlying surface\r\n     * to be darkened. A value of 1.0 means that the physically correct amount of darkening\r\n     * is applied, while a value of 0.0 means that no darkening is applied.\r\n     * See OpenPBR's specs for coat_darkening\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor coatDarkeningTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _coatDarkeningTexture: Sampler = new Sampler(\"coat_darkening\", \"coatDarkening\", \"COAT_DARKENING\");\r\n\r\n    /**\r\n     * Specifies whether the coat roughness is taken from the\r\n     * same texture as the coat_weight.\r\n     */\r\n    public useCoatRoughnessFromWeightTexture: boolean = false;\r\n\r\n    /**\r\n     * Defines the weight of the fuzz layer on the surface.\r\n     * See OpenPBR's specs for fuzz_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor fuzzWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _fuzzWeight: Property<number> = new Property<number>(\"fuzz_weight\", 0.0, \"vFuzzWeight\", 1, 0);\r\n\r\n    /**\r\n     * Weight texture of the fuzz layer.\r\n     * See OpenPBR's specs for fuzz_weight\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor fuzzWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _fuzzWeightTexture: Sampler = new Sampler(\"fuzz_weight\", \"fuzzWeight\", \"FUZZ_WEIGHT\");\r\n\r\n    /**\r\n     * Defines the color of the fuzz layer on the surface.\r\n     * See OpenPBR's specs for fuzz_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor fuzzColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _fuzzColor: Property<Color3> = new Property<Color3>(\"fuzz_color\", Color3.White(), \"vFuzzColor\", 3, 0);\r\n\r\n    /**\r\n     * Color texture of the fuzz layer.\r\n     * See OpenPBR's specs for fuzz_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor fuzzColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _fuzzColorTexture: Sampler = new Sampler(\"fuzz_color\", \"fuzzColor\", \"FUZZ_COLOR\");\r\n\r\n    /**\r\n     * Defines the roughness of the fuzz layer on the surface.\r\n     * See OpenPBR's specs for fuzz_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor fuzzRoughness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _fuzzRoughness: Property<number> = new Property<number>(\"fuzz_roughness\", 0.5, \"vFuzzRoughness\", 1, 0);\r\n\r\n    /**\r\n     * Roughness texture of the fuzz layer.\r\n     * See OpenPBR's specs for fuzz_roughness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor fuzzRoughnessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _fuzzRoughnessTexture: Sampler = new Sampler(\"fuzz_roughness\", \"fuzzRoughness\", \"FUZZ_ROUGHNESS\");\r\n\r\n    /**\r\n     * Defines whether the geometry is thin-walled (like a sheet of paper) or not.\r\n     * See OpenPBR's specs for geometry_thin_walled\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryThinWalled: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryThinWalled: Property<number> = new Property<number>(\"geometry_thin_walled\", 0, \"vGeometryThinWalled\", 1, 0);\r\n\r\n    /**\r\n     * Defines the normal of the material's geometry.\r\n     * See OpenPBR's specs for geometry_normal\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryNormalTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryNormalTexture: Sampler = new Sampler(\"geometry_normal\", \"geometryNormal\", \"GEOMETRY_NORMAL\");\r\n\r\n    /**\r\n     * Defines the tangent of the material's geometry. Used only for anisotropic reflections.\r\n     * See OpenPBR's specs for geometry_tangent\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryTangent: Vector2;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryTangent: Property<Vector2> = new Property<Vector2>(\"geometry_tangent\", new Vector2(1, 0), \"vSpecularAnisotropy\", 3, 0);\r\n\r\n    /**\r\n     * Defines the angle of the tangent of the material's geometry. Used only for anisotropic reflections.\r\n     * See OpenPBR's specs for geometry_tangent\r\n     */\r\n    public get geometryTangentAngle(): number {\r\n        return Math.atan2(this.geometryTangent.y, this.geometryTangent.x);\r\n    }\r\n\r\n    public set geometryTangentAngle(value: number) {\r\n        this.geometryTangent = new Vector2(Math.cos(value), Math.sin(value));\r\n    }\r\n\r\n    /**\r\n     * Defines the tangent of the material's geometry. Used only for anisotropic reflections.\r\n     * See OpenPBR's specs for geometry_tangent\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryTangentTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryTangentTexture: Sampler = new Sampler(\"geometry_tangent\", \"geometryTangent\", \"GEOMETRY_TANGENT\");\r\n\r\n    /**\r\n     * Defines the normal of the material's coat layer.\r\n     * See OpenPBR's specs for geometry_coat_normal\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryCoatNormalTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryCoatNormalTexture: Sampler = new Sampler(\"geometry_coat_normal\", \"geometryCoatNormal\", \"GEOMETRY_COAT_NORMAL\");\r\n\r\n    /**\r\n     * Defines the tangent of the material's coat layer. Used only for anisotropic reflections.\r\n     * See OpenPBR's specs for geometry_coat_tangent\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryCoatTangent: Vector2;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryCoatTangent: Property<Vector2> = new Property<Vector2>(\"geometry_coat_tangent\", new Vector2(1, 0), \"vGeometryCoatTangent\", 2, 0);\r\n\r\n    /**\r\n     * Defines the angle of the tangent of the material's coat layer.\r\n     */\r\n    public get geometryCoatTangentAngle(): number {\r\n        return Math.atan2(this.geometryCoatTangent.y, this.geometryCoatTangent.x);\r\n    }\r\n\r\n    /**\r\n     * Defines the angle of the tangent of the material's coat layer.\r\n     */\r\n    public set geometryCoatTangentAngle(value: number) {\r\n        this.geometryCoatTangent = new Vector2(Math.cos(value), Math.sin(value));\r\n    }\r\n\r\n    /**\r\n     * Defines the tangent of the material's coat layer. Used only for anisotropic reflections.\r\n     * See OpenPBR's specs for geometry_coat_tangent\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryCoatTangentTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryCoatTangentTexture: Sampler = new Sampler(\"geometry_coat_tangent\", \"geometryCoatTangent\", \"GEOMETRY_COAT_TANGENT\");\r\n\r\n    /**\r\n     * Defines the opacity of the material's geometry.\r\n     * See OpenPBR's specs for geometry_opacity\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryOpacity: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryOpacity: Property<number> = new Property<number>(\"geometry_opacity\", 1.0, \"vBaseColor\", 4, 3);\r\n\r\n    /**\r\n     * Defines the opacity texture of the material's geometry.\r\n     * See OpenPBR's specs for geometry_opacity\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryOpacityTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryOpacityTexture: Sampler = new Sampler(\"geometry_opacity\", \"geometryOpacity\", \"GEOMETRY_OPACITY\");\r\n\r\n    /**\r\n     * Defines the thickness of the material's geometry.\r\n     * Not part of OpenPBR's specs but useful for rasterization approximations of volume.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryThickness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryThickness: Property<number> = new Property<number>(\"geometry_thickness\", 0.0, \"vGeometryThickness\", 1, 0);\r\n\r\n    /**\r\n     * Defines the thickness of the material's geometry.\r\n     * Not part of OpenPBR's specs but useful for rasterization approximations of volume.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor geometryThicknessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _geometryThicknessTexture: Sampler = new Sampler(\"geometry_thickness\", \"geometryThickness\", \"GEOMETRY_THICKNESS\");\r\n\r\n    /**\r\n     * Defines the luminance of the material's emission.\r\n     * See OpenPBR's specs for emission_luminance\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor emissionLuminance: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _emissionLuminance: Property<number> = new Property<number>(\"emission_luminance\", 1.0, \"vLightingIntensity\", 4, 1);\r\n\r\n    /**\r\n     * Defines the color of the material's emission.\r\n     * See OpenPBR's specs for emission_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor emissionColor: Color3;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _emissionColor: Property<Color3> = new Property<Color3>(\"emission_color\", Color3.Black(), \"vEmissionColor\", 3);\r\n\r\n    /**\r\n     * Defines the texture of the material's emission color.\r\n     * See OpenPBR's specs for emission_color\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor emissionColorTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _emissionColorTexture: Sampler = new Sampler(\"emission_color\", \"emissionColor\", \"EMISSION_COLOR\");\r\n\r\n    /**\r\n     * Defines the weight of the thin film layer on top of the base layer for iridescent effects.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor thinFilmWeight: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _thinFilmWeight: Property<number> = new Property<number>(\"thin_film_weight\", 0.0, \"vThinFilmWeight\", 1, 0);\r\n\r\n    /**\r\n     * Thin film weight texture.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor thinFilmWeightTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _thinFilmWeightTexture: Sampler = new Sampler(\"thin_film_weight\", \"thinFilmWeight\", \"THIN_FILM_WEIGHT\");\r\n\r\n    /**\r\n     * Defines the thickness of the thin film layer in μm. If a texture is provided for thinFilmWeightTexture,\r\n     * this value will act as a multiplier to the texture values.\r\n     * See OpenPBR's specs for thin_film_thickness\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor thinFilmThickness: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _thinFilmThickness: Property<number> = new Property<number>(\"thin_film_thickness\", 0.5, \"vThinFilmThickness\", 2, 0);\r\n\r\n    /**\r\n     * Defines the minimum thickness of the thin film layer in μm.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor thinFilmThicknessMin: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _thinFilmThicknessMin: Property<number> = new Property<number>(\"thin_film_thickness_min\", 0.0, \"vThinFilmThickness\", 2, 1);\r\n\r\n    /**\r\n     * Defines the maximum thickness of the thin film layer in μm.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor thinFilmThicknessTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _thinFilmThicknessTexture: Sampler = new Sampler(\"thin_film_thickness\", \"thinFilmThickness\", \"THIN_FILM_THICKNESS\");\r\n\r\n    /**\r\n     * Defines the index of refraction of the thin film layer.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor thinFilmIor: number;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _thinFilmIor: Property<number> = new Property<number>(\"thin_film_ior\", 1.4, \"vThinFilmIor\", 1, 0);\r\n\r\n    /**\r\n     * Defines the ambient occlusion texture.\r\n     */\r\n    @addAccessorsForMaterialProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    accessor ambientOcclusionTexture: Nullable<BaseTexture>;\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _ambientOcclusionTexture: Sampler = new Sampler(\"ambient_occlusion\", \"ambientOcclusion\", \"AMBIENT_OCCLUSION\");\r\n\r\n    /** SSS convolution uses 8 samples. */\r\n    public static readonly SSS_QUALITY_LOW = 0;\r\n    /** SSS convolution uses 16 samples (default). */\r\n    public static readonly SSS_QUALITY_MEDIUM = 1;\r\n    /** SSS convolution uses 32 samples. */\r\n    public static readonly SSS_QUALITY_HIGH = 2;\r\n\r\n    private _sssQuality: number = OpenPBRMaterial.SSS_QUALITY_MEDIUM;\r\n    /**\r\n     * Controls the sample count of the screen-space SSS convolution kernel.\r\n     * Use the SSS_QUALITY_LOW / MEDIUM / HIGH constants (8 / 16 / 32 samples).\r\n     * Higher quality reduces noise at the cost of GPU time. Default: MEDIUM.\r\n     */\r\n    public get sssQuality(): number {\r\n        return this._sssQuality;\r\n    }\r\n    public set sssQuality(value: number) {\r\n        if (this._sssQuality !== value) {\r\n            this._sssQuality = value;\r\n            this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n        }\r\n    }\r\n\r\n    private _sssIrradianceTexture: Nullable<ThinTexture> = null;\r\n    /**\r\n     * Defines the irradiance texture used for subsurface scattering.\r\n     * If it's not provided, the irradiance will be looked for in the scene.geometryBufferRenderer.\r\n     * Accepts a {@link ThinTexture} so that an {@link InternalTexture} obtained from a frame graph\r\n     * handle can be wrapped with `new ThinTexture(internalTexture)` and assigned directly.\r\n     * Setting this property marks all sub-meshes as textures-dirty so the shader recompiles.\r\n     */\r\n    public get sssIrradianceTexture(): Nullable<ThinTexture> {\r\n        return this._sssIrradianceTexture;\r\n    }\r\n    public set sssIrradianceTexture(value: Nullable<ThinTexture>) {\r\n        if (this._sssIrradianceTexture === value) {\r\n            return;\r\n        }\r\n        this._sssIrradianceTexture = value;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _sssDepthTexture: Nullable<ThinTexture> = null;\r\n    /**\r\n     * Defines the depth texture used for subsurface scattering. This is the depth defined\r\n     * in screen space. If it's not provided, the depth will be looked for in the scene.geometryBufferRenderer.\r\n     * Accepts a {@link ThinTexture} so that an {@link InternalTexture} obtained from a frame graph\r\n     * handle can be wrapped with `new ThinTexture(internalTexture)` and assigned directly.\r\n     * Setting this property marks all sub-meshes as textures-dirty so the shader recompiles.\r\n     */\r\n    public get sssDepthTexture(): Nullable<ThinTexture> {\r\n        return this._sssDepthTexture;\r\n    }\r\n    public set sssDepthTexture(value: Nullable<ThinTexture>) {\r\n        if (this._sssDepthTexture === value) {\r\n            return;\r\n        }\r\n        this._sssDepthTexture = value;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _propertyList: { [name: string]: Property<any> };\r\n    private _uniformsList: { [name: string]: Uniform } = {};\r\n    /**\r\n     * Flat array view of `_uniformsList`, populated once at construction. Used\r\n     * by the per-frame bind loop to avoid `Object.values()` allocation and\r\n     * closure creation on every submesh binding.\r\n     */\r\n    private _uniformsArray: Uniform[] = [];\r\n    private _samplersList: { [name: string]: Sampler } = {};\r\n    private _samplerDefines: { [name: string]: { type: string; default: any } } = {};\r\n\r\n    private static _noiseTextures: { [id: number]: BaseTexture } = {};\r\n\r\n    /**\r\n     * Intensity of the direct lights e.g. the four lights available in your scene.\r\n     * This impacts both the direct diffuse and specular highlights.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor directIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Intensity of the environment e.g. how much the environment will light the object\r\n     * either through harmonics for rough material or through the reflection for shiny ones.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor environmentIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Specifies that the specular weight is stored in the alpha channel of the specular weight texture.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useSpecularWeightFromTextureAlpha = false;\r\n\r\n    /**\r\n     * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor forceAlphaTest = false;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor alphaCutOff = 0.4;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the ambient occlusion information in its red channel.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAmbientOcclusionFromMetallicTextureRed = false;\r\n\r\n    /**\r\n     * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAmbientInGrayScale = false;\r\n\r\n    /**\r\n     * Specifies if we can see through the surface of the material due to subsurface scattering or transmission.\r\n     */\r\n    public get hasTransparency(): boolean {\r\n        return this.subsurfaceWeight > 0 || this.transmissionWeight > 0;\r\n    }\r\n\r\n    /** Specifies if the material has scattering properties such as subsurface scattering or transmission scattering. */\r\n    public get hasScattering(): boolean {\r\n        return (this.transmissionWeight > 0 && this.transmissionDepth > 0 && !this.transmissionScatter.equals(Color3.BlackReadOnly)) || this.subsurfaceWeight > 0;\r\n    }\r\n\r\n    /**\r\n     * BJS is using an hardcoded light falloff based on a manually sets up range.\r\n     * In PBR, one way to represents the falloff is to use the inverse squared root algorithm.\r\n     * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.\r\n     */\r\n    @serialize()\r\n    public get usePhysicalLightFalloff(): boolean {\r\n        return this._lightFalloff === Material.LIGHTFALLOFF_PHYSICAL;\r\n    }\r\n\r\n    /**\r\n     * BJS is using an hardcoded light falloff based on a manually sets up range.\r\n     * In PBR, one way to represents the falloff is to use the inverse squared root algorithm.\r\n     * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.\r\n     */\r\n    public set usePhysicalLightFalloff(value: boolean) {\r\n        if (value !== this.usePhysicalLightFalloff) {\r\n            // Ensure the effect will be rebuilt.\r\n            this._markAllSubMeshesAsTexturesDirty();\r\n\r\n            if (value) {\r\n                this._lightFalloff = Material.LIGHTFALLOFF_PHYSICAL;\r\n            } else {\r\n                this._lightFalloff = Material.LIGHTFALLOFF_STANDARD;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * In order to support the falloff compatibility with gltf, a special mode has been added\r\n     * to reproduce the gltf light falloff.\r\n     */\r\n    @serialize()\r\n    public get useGLTFLightFalloff(): boolean {\r\n        return this._lightFalloff === Material.LIGHTFALLOFF_GLTF;\r\n    }\r\n\r\n    /**\r\n     * In order to support the falloff compatibility with gltf, a special mode has been added\r\n     * to reproduce the gltf light falloff.\r\n     */\r\n    public set useGLTFLightFalloff(value: boolean) {\r\n        if (value !== this.useGLTFLightFalloff) {\r\n            // Ensure the effect will be rebuilt.\r\n            this._markAllSubMeshesAsTexturesDirty();\r\n\r\n            if (value) {\r\n                this._lightFalloff = Material.LIGHTFALLOFF_GLTF;\r\n            } else {\r\n                this._lightFalloff = Material.LIGHTFALLOFF_STANDARD;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Allows using an object space normal map (instead of tangent space).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useObjectSpaceNormalMap = false;\r\n\r\n    /**\r\n     * Allows using the normal map in parallax mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useParallax = false;\r\n\r\n    /**\r\n     * Allows using the normal map in parallax occlusion mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useParallaxOcclusion = false;\r\n\r\n    /**\r\n     * Controls the scale bias of the parallax mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor parallaxScaleBias = 0.05;\r\n\r\n    /**\r\n     * If sets to true, disables all the lights affecting the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor disableLighting = false;\r\n\r\n    /**\r\n     * Force the shader to compute irradiance in the fragment shader in order to take normal mapping into account.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor forceIrradianceInFragment = false;\r\n\r\n    /**\r\n     * Number of Simultaneous lights allowed on the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor maxSimultaneousLights = 4;\r\n\r\n    /**\r\n     * If sets to true, x component of normal map value will invert (x = 1.0 - x).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapX = false;\r\n\r\n    /**\r\n     * If sets to true, y component of normal map value will invert (y = 1.0 - y).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapY = false;\r\n\r\n    /**\r\n     * If sets to true and backfaceCulling is false, normals will be flipped on the backside.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor twoSidedLighting = false;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAlphaFresnel = false;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useLinearAlphaFresnel = false;\r\n\r\n    /**\r\n     * Let user defines the brdf lookup texture used for IBL.\r\n     * A default 8bit version is embedded but you could point at :\r\n     * * Default texture: https://assets.babylonjs.com/environments/correlatedMSBRDF_RGBD.png\r\n     * * Default 16bit pixel depth texture: https://assets.babylonjs.com/environments/correlatedMSBRDF.dds\r\n     * * LEGACY Default None correlated https://assets.babylonjs.com/environments/uncorrelatedBRDF_RGBD.png\r\n     * * LEGACY Default None correlated 16bit pixel depth https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor environmentBRDFTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Force normal to face away from face.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor forceNormalForward = false;\r\n\r\n    /**\r\n     * Enables specular anti aliasing in the PBR shader.\r\n     * It will both interacts on the Geometry for analytical and IBL lighting.\r\n     * It also prefilter the roughness map based on the normalmap values.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor enableSpecularAntiAliasing = false;\r\n\r\n    /**\r\n     * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal\r\n     * makes the reflect vector face the model (under horizon).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useHorizonOcclusion = true;\r\n\r\n    /**\r\n     * This parameters will enable/disable radiance occlusion by preventing the radiance to lit\r\n     * too much the area relying on ambient texture to define their ambient occlusion.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRadianceOcclusion = true;\r\n\r\n    /**\r\n     * If set to true, no lighting calculations will be applied.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor unlit = false;\r\n\r\n    /**\r\n     * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor applyDecalMapAfterDetailMap = false;\r\n\r\n    /**\r\n     * Force all the PBR materials to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * This stores the direct, emissive, environment, and specular light intensities into a Vector4.\r\n     */\r\n    private _lightingInfos: Vector4 = new Vector4(this.directIntensity, 1.0, this.environmentIntensity, 1.0);\r\n\r\n    /**\r\n     * Stores the radiance (and, possibly, irradiance) values in a texture.\r\n     * @internal\r\n     */\r\n    public _radianceTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Specifies that the specular weight will be read from the alpha channel.\r\n     * This is for compatibility with glTF's KHR_materials_specular extension.\r\n     * @internal\r\n     */\r\n    public _useSpecularWeightFromAlpha = false;\r\n\r\n    /**\r\n     * Specifies that the specular weight will be read from the alpha channel of the specular color texture.\r\n     * This is for compatibility with glTF's KHR_materials_specular extension.\r\n     * @internal\r\n     */\r\n    public _useSpecularWeightFromSpecularColorTexture = false;\r\n\r\n    /**\r\n     * Specifies if the material uses anisotropy weight read from the geometry tangent texture's blue channel.\r\n     * This is for compatibility with glTF's anisotropy extension.\r\n     * @internal\r\n     */\r\n    public _useSpecularRoughnessAnisotropyFromTangentTexture = false;\r\n\r\n    /**\r\n     * Specifies if the material uses coat anisotropy weight read from the coat's geometry tangent texture's blue channel.\r\n     * This is for compatibility with glTF's clearcoat_anisotropy extension.\r\n     * @internal\r\n     */\r\n    public _useCoatRoughnessAnisotropyFromTangentTexture = false;\r\n\r\n    /**\r\n     * Specifies whether the coat roughness is taken from the green channel of the coat texture.\r\n     * This is for compatibility with glTF's KHR_materials_clearcoat and KHR_materials_coat extensions.\r\n     * @internal\r\n     */\r\n    public _useCoatRoughnessFromGreenChannel = false;\r\n\r\n    /**\r\n     * Assume the anisotropy data is stored in the format specified by\r\n     * KHR_materials_anisotropy.\r\n     * @internal\r\n     */\r\n    public _useGltfStyleAnisotropy = false;\r\n\r\n    /**\r\n     * Specifies that the fuzz roughness is stored in the alpha channel of the texture.\r\n     * This is for compatibility with glTF where the fuzz roughness is often stored in\r\n     * the alpha channel of the fuzz color texture.\r\n     */\r\n    public _useFuzzRoughnessFromTextureAlpha = false;\r\n\r\n    /**\r\n     * Specifies that the subsurface weight is stored in the alpha channel of the texture.\r\n     * This is for compatibility with glTF where the subsurface weight is stored in\r\n     * the alpha channel of the diffuseTransmissionTexture.\r\n     */\r\n    public _useSubsurfaceWeightFromTextureAlpha = false;\r\n\r\n    /**\r\n     * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal\r\n     * makes the reflect vector face the model (under horizon).\r\n     * @internal\r\n     */\r\n    public _useHorizonOcclusion = true;\r\n\r\n    /**\r\n     * This parameters will enable/disable radiance occlusion by preventing the radiance to lit\r\n     * too much the area relying on ambient texture to define their ambient occlusion.\r\n     * @internal\r\n     */\r\n    public _useRadianceOcclusion = true;\r\n\r\n    /**\r\n     * Specifies that the alpha is coming from the base color texture's alpha channel.\r\n     * This is for compatibility with glTF.\r\n     * @internal\r\n     */\r\n    public _useAlphaFromBaseColorTexture = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the ambient occlusion information in its red channel.\r\n     * This is for compatibility with glTF.\r\n     * @internal\r\n     */\r\n    public _useAmbientOcclusionFromMetallicTextureRed = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the roughness information in its green channel.\r\n     * This is for compatibility with glTF.\r\n     * @internal\r\n     */\r\n    public _useRoughnessFromMetallicTextureGreen = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the metallic information in its blue channel.\r\n     * This is for compatibility with glTF.\r\n     * @internal\r\n     */\r\n    public _useMetallicFromMetallicTextureBlue = false;\r\n\r\n    /**\r\n     * Specifies if the thin film thickness is stored in the green channel of the thin film thickness texture.\r\n     * This is for compatibility with glTF.\r\n     * @internal\r\n     */\r\n    public _useThinFilmThicknessFromTextureGreen = false;\r\n\r\n    /**\r\n     * Specifies if the geometry thickness is stored in the green channel of the geometry thickness texture.\r\n     * This is for compatibility with glTF.\r\n     * @internal\r\n     */\r\n    public _useGeometryThicknessFromGreenChannel = false;\r\n\r\n    /**\r\n     * Defines the  falloff type used in this material.\r\n     * It by default is Physical.\r\n     * @internal\r\n     */\r\n    public _lightFalloff = Material.LIGHTFALLOFF_PHYSICAL;\r\n\r\n    /**\r\n     * Allows using an object space normal map (instead of tangent space).\r\n     * @internal\r\n     */\r\n    public _useObjectSpaceNormalMap = false;\r\n\r\n    /**\r\n     * Allows using the normal map in parallax mode.\r\n     * @internal\r\n     */\r\n    public _useParallax = false;\r\n\r\n    /**\r\n     * Allows using the normal map in parallax occlusion mode.\r\n     * @internal\r\n     */\r\n    public _useParallaxOcclusion = false;\r\n\r\n    /**\r\n     * Controls the scale bias of the parallax mode.\r\n     * @internal\r\n     */\r\n    public _parallaxScaleBias = 0.05;\r\n\r\n    /**\r\n     * If sets to true, disables all the lights affecting the material.\r\n     * @internal\r\n     */\r\n    public _disableLighting = false;\r\n\r\n    /**\r\n     * Number of Simultaneous lights allowed on the material.\r\n     * @internal\r\n     */\r\n    public _maxSimultaneousLights = 4;\r\n\r\n    /**\r\n     * If sets to true, x component of normal map value will be inverted (x = 1.0 - x).\r\n     * @internal\r\n     */\r\n    public _invertNormalMapX = false;\r\n\r\n    /**\r\n     * If sets to true, y component of normal map value will be inverted (y = 1.0 - y).\r\n     * @internal\r\n     */\r\n    public _invertNormalMapY = false;\r\n\r\n    /**\r\n     * If sets to true and backfaceCulling is false, normals will be flipped on the backside.\r\n     * @internal\r\n     */\r\n    public _twoSidedLighting = false;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     * @internal\r\n     */\r\n    public _alphaCutOff = 0.4;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)\r\n     * @internal\r\n     */\r\n    public _useAlphaFresnel = false;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)\r\n     * @internal\r\n     */\r\n    public _useLinearAlphaFresnel = false;\r\n\r\n    /**\r\n     * Specifies the environment BRDF texture used to compute the scale and offset roughness values\r\n     * from cos theta and roughness:\r\n     * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf\r\n     * @internal\r\n     */\r\n    public _environmentBRDFTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Specifies the environment BRDF texture used to compute the scale and offset roughness values\r\n     * from cos theta and roughness for the fuzz layer:\r\n     * https://github.com/tizian/ltc-sheen?tab=readme-ov-file\r\n     * @internal\r\n     */\r\n    public _environmentFuzzBRDFTexture: Nullable<BaseTexture> = null;\r\n\r\n    private _backgroundRefractionTexture: Nullable<BaseTexture> = null;\r\n    /**\r\n     * Set the texture used for refraction of the background of transparent materials\r\n     * @internal\r\n     */\r\n    public get backgroundRefractionTexture(): Nullable<BaseTexture> {\r\n        return this._backgroundRefractionTexture;\r\n    }\r\n    public set backgroundRefractionTexture(texture: Nullable<BaseTexture>) {\r\n        this._backgroundRefractionTexture = texture;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _refractionHighQualityBlur: boolean = true;\r\n    /**\r\n     * When true, uses a 4-tap rotated-grid kernel for refractive background blur,\r\n     * eliminating bilinear block artifacts at the cost of 3 extra texture samples.\r\n     * When false, a single dithered sample is used. Default: true.\r\n     */\r\n    public get refractionHighQualityBlur(): boolean {\r\n        return this._refractionHighQualityBlur;\r\n    }\r\n    public set refractionHighQualityBlur(value: boolean) {\r\n        if (this._refractionHighQualityBlur !== value) {\r\n            this._refractionHighQualityBlur = value;\r\n            this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Force the shader to compute irradiance in the fragment shader in order to take normal mapping into account.\r\n     * @internal\r\n     */\r\n    public _forceIrradianceInFragment = false;\r\n\r\n    private _realTimeFiltering: boolean = false;\r\n    /**\r\n     * Enables realtime filtering on the texture.\r\n     */\r\n    public get realTimeFiltering() {\r\n        return this._realTimeFiltering;\r\n    }\r\n    public set realTimeFiltering(b: boolean) {\r\n        this._realTimeFiltering = b;\r\n        this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private _realTimeFilteringQuality: number = Constants.TEXTURE_FILTERING_QUALITY_LOW;\r\n    /**\r\n     * Quality switch for realtime filtering\r\n     */\r\n    public get realTimeFilteringQuality(): number {\r\n        return this._realTimeFilteringQuality;\r\n    }\r\n    public set realTimeFilteringQuality(n: number) {\r\n        this._realTimeFilteringQuality = n;\r\n        this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    private _fuzzSampleNumber: number = 4;\r\n\r\n    /**\r\n     * The number of samples used to compute the fuzz IBL lighting.\r\n     */\r\n    public get fuzzSampleNumber(): number {\r\n        return this._fuzzSampleNumber;\r\n    }\r\n    public set fuzzSampleNumber(n: number) {\r\n        this._fuzzSampleNumber = n;\r\n        this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Can this material render to several textures at once\r\n     */\r\n    public override get canRenderToMRT() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Force normal to face away from face.\r\n     * @internal\r\n     */\r\n    public _forceNormalForward = false;\r\n\r\n    /**\r\n     * Enables specular anti aliasing in the PBR shader.\r\n     * It will both interacts on the Geometry for analytical and IBL lighting.\r\n     * It also prefilter the roughness map based on the normalmap values.\r\n     * @internal\r\n     */\r\n    public _enableSpecularAntiAliasing = false;\r\n\r\n    /**\r\n     * Stores the available render targets.\r\n     */\r\n    private _renderTargets = new SmartArray<RenderTargetTexture>(16);\r\n\r\n    /**\r\n     * If set to true, no lighting calculations will be applied.\r\n     */\r\n    private _unlit = false;\r\n\r\n    /**\r\n     * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false)\r\n     */\r\n    private _applyDecalMapAfterDetailMap = false;\r\n\r\n    private _debugMode = 0;\r\n\r\n    private static readonly _ShaderLoader = /*#__PURE__*/ new _ShaderImportLoader(\r\n        () => [import(\"../../Shaders/openpbr.vertex\"), import(\"../../Shaders/openpbr.fragment\")],\r\n        () => [import(\"../../ShadersWGSL/openpbr.vertex\"), import(\"../../ShadersWGSL/openpbr.fragment\")]\r\n    );\r\n    private _breakShaderLoadedCheck = false;\r\n    private _vertexPullingMetadata: Map<string, IVertexPullingMetadata> | null = null;\r\n\r\n    /**\r\n     * @internal\r\n     * This is reserved for the inspector.\r\n     * Defines the material debug mode.\r\n     * It helps seeing only some components of the material while troubleshooting.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor debugMode = 0;\r\n\r\n    /**\r\n     * @internal\r\n     * This is reserved for the inspector.\r\n     * Specify from where on screen the debug mode should start.\r\n     * The value goes from -1 (full screen) to 1 (not visible)\r\n     * It helps with side by side comparison against the final render\r\n     * This defaults to -1\r\n     */\r\n    public debugLimit = -1;\r\n\r\n    /**\r\n     * @internal\r\n     * This is reserved for the inspector.\r\n     * As the default viewing range might not be enough (if the ambient is really small for instance)\r\n     * You can use the factor to better multiply the final value.\r\n     */\r\n    public debugFactor = 1;\r\n\r\n    /**\r\n     * Defines additional PrePass parameters for the material.\r\n     */\r\n    public readonly prePassConfiguration: PrePassConfiguration;\r\n\r\n    protected _cacheHasRenderTargetTextures = false;\r\n\r\n    /**\r\n     * Instantiates a new OpenPBRMaterial instance.\r\n     *\r\n     * @param name The material name\r\n     * @param scene The scene the material will be use in.\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(name: string, scene?: Scene, forceGLSL = false) {\r\n        super(name, scene, undefined, forceGLSL || OpenPBRMaterial.ForceGLSL);\r\n        // TODO: Check if we're running WebGL 2.0 or above\r\n        if (this.getScene() && !this.getScene()?.getEngine().isWebGPU && (this.getScene().getEngine() as Engine).webGLVersion < 2) {\r\n            Logger.Error(\"OpenPBRMaterial: WebGL 2.0 or above is required for this material.\");\r\n        }\r\n\r\n        if (!OpenPBRMaterial._noiseTextures[this.getScene().uniqueId]) {\r\n            OpenPBRMaterial._noiseTextures[this.getScene().uniqueId] = new Texture(\r\n                Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/blue_noise/blue_noise_rgb.png\"),\r\n                this.getScene(),\r\n                false,\r\n                true,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE\r\n            );\r\n            this.getScene().onDisposeObservable.addOnce(() => {\r\n                OpenPBRMaterial._noiseTextures[this.getScene().uniqueId]?.dispose();\r\n                delete OpenPBRMaterial._noiseTextures[this.getScene().uniqueId];\r\n            });\r\n        }\r\n\r\n        // Setup the default processing configuration to the scene.\r\n        this._attachImageProcessingConfiguration(null);\r\n\r\n        this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {\r\n            this._renderTargets.reset();\r\n\r\n            if (MaterialFlags.ReflectionTextureEnabled && this._radianceTexture && this._radianceTexture.isRenderTarget) {\r\n                this._renderTargets.push(<RenderTargetTexture>this._radianceTexture);\r\n            }\r\n\r\n            if (MaterialFlags.RefractionTextureEnabled && this._backgroundRefractionTexture && this._backgroundRefractionTexture.isRenderTarget) {\r\n                this._renderTargets.push(<RenderTargetTexture>this._backgroundRefractionTexture);\r\n            }\r\n\r\n            this._eventInfo.renderTargets = this._renderTargets;\r\n            this._callbackPluginEventFillRenderTargetTextures(this._eventInfo);\r\n\r\n            return this._renderTargets;\r\n        };\r\n\r\n        this._environmentBRDFTexture = GetOpenPBREnvironmentBRDFTexture(this.getScene());\r\n        this._environmentFuzzBRDFTexture = GetEnvironmentFuzzBRDFTexture(this.getScene());\r\n        this.prePassConfiguration = new PrePassConfiguration();\r\n\r\n        // Build the internal property list that can be used to generate and update the uniform buffer\r\n        this._propertyList = {};\r\n        for (const key of Object.getOwnPropertyNames(this)) {\r\n            const value = (this as any)[key];\r\n            if (value instanceof Property) {\r\n                this._propertyList[key] = value;\r\n            }\r\n        }\r\n        // Build the internal uniforms list that is used for combining and updating\r\n        // property values in the uniform buffer\r\n        const propertyKeys = Object.keys(this._propertyList);\r\n        propertyKeys.forEach((key) => {\r\n            const prop = this._propertyList[key];\r\n            let uniform = this._uniformsList[prop.targetUniformName];\r\n            if (!uniform) {\r\n                uniform = new Uniform(prop.targetUniformName, prop.targetUniformComponentNum);\r\n                uniform.requiredDefine = prop.requiredDefine;\r\n                this._uniformsList[prop.targetUniformName] = uniform;\r\n            } else if (uniform.numComponents !== prop.targetUniformComponentNum) {\r\n                Logger.Error(`Uniform ${prop.targetUniformName} already exists of size ${uniform.numComponents}, but trying to set it to ${prop.targetUniformComponentNum}.`);\r\n            } else if (uniform.requiredDefine !== prop.requiredDefine) {\r\n                // Properties packed into the same uniform must share the same gating\r\n                // define, otherwise we cannot safely skip the per-frame UBO update.\r\n                uniform.requiredDefine = undefined;\r\n            }\r\n            if (uniform.firstLinkedKey === \"\") {\r\n                uniform.firstLinkedKey = prop.name;\r\n            }\r\n            uniform.linkedProperties[prop.name] = prop;\r\n        });\r\n        this._uniformsArray = Object.values(this._uniformsList);\r\n\r\n        // Build the internal list of samplers\r\n        this._samplersList = {};\r\n        for (const key of Object.getOwnPropertyNames(this)) {\r\n            const value = (this as any)[key];\r\n            if (value instanceof Sampler) {\r\n                this._samplersList[key] = value;\r\n            }\r\n        }\r\n\r\n        // For each sampler in _samplersList, add defines to be added to OpenPBRMaterialDefines\r\n        for (const samplerKey in this._samplersList) {\r\n            const sampler = this._samplersList[samplerKey];\r\n            const defineName = sampler.textureDefine;\r\n            this._samplerDefines[defineName] = { type: \"boolean\", default: false };\r\n            this._samplerDefines[defineName + \"DIRECTUV\"] = { type: \"number\", default: 0 };\r\n            this._samplerDefines[defineName + \"_GAMMA\"] = { type: \"boolean\", default: false };\r\n        }\r\n\r\n        // Arg. Why do I have to add these references to get rid of the linting errors?\r\n        this._baseWeight;\r\n        this._baseWeightTexture;\r\n        this._baseColor;\r\n        this._baseColorTexture;\r\n        this._baseDiffuseRoughness;\r\n        this._baseDiffuseRoughnessTexture;\r\n        this._baseMetalness;\r\n        this._baseMetalnessTexture;\r\n        this._specularWeight;\r\n        this._specularWeightTexture;\r\n        this._specularColor;\r\n        this._specularColorTexture;\r\n        this._specularRoughness;\r\n        this._specularIor;\r\n        this._specularRoughnessTexture;\r\n        this._specularRoughnessAnisotropy;\r\n        this._specularRoughnessAnisotropyTexture;\r\n        this._transmissionWeight;\r\n        this._transmissionWeightTexture;\r\n        this._transmissionColor;\r\n        this._transmissionColorTexture;\r\n        this._transmissionDepth;\r\n        this._transmissionDepthTexture;\r\n        this._transmissionScatter;\r\n        this._transmissionScatterTexture;\r\n        this._transmissionScatterAnisotropy;\r\n        this._transmissionDispersionScale;\r\n        this._transmissionDispersionScaleTexture;\r\n        this._transmissionDispersionAbbeNumber;\r\n        this._subsurfaceWeight;\r\n        this._subsurfaceWeightTexture;\r\n        this._subsurfaceColor;\r\n        this._subsurfaceColorTexture;\r\n        this._subsurfaceRadius;\r\n        this._subsurfaceRadiusScale;\r\n        this._subsurfaceRadiusScaleTexture;\r\n        this._subsurfaceScatterAnisotropy;\r\n        this._coatWeight;\r\n        this._coatWeightTexture;\r\n        this._coatColor;\r\n        this._coatColorTexture;\r\n        this._coatRoughness;\r\n        this._coatRoughnessTexture;\r\n        this._coatRoughnessAnisotropy;\r\n        this._coatRoughnessAnisotropyTexture;\r\n        this._coatIor;\r\n        this._coatDarkening;\r\n        this._coatDarkeningTexture;\r\n        this._fuzzWeight;\r\n        this._fuzzWeightTexture;\r\n        this._fuzzColor;\r\n        this._fuzzColorTexture;\r\n        this._fuzzRoughness;\r\n        this._fuzzRoughnessTexture;\r\n        this._geometryThinWalled;\r\n        this._geometryNormalTexture;\r\n        this._geometryTangent;\r\n        this._geometryTangentTexture;\r\n        this._geometryCoatNormalTexture;\r\n        this._geometryCoatTangent;\r\n        this._geometryCoatTangentTexture;\r\n        this._geometryOpacity;\r\n        this._geometryOpacityTexture;\r\n        this._geometryThickness;\r\n        this._geometryThicknessTexture;\r\n        this._thinFilmWeight;\r\n        this._thinFilmWeightTexture;\r\n        this._thinFilmThickness;\r\n        this._thinFilmThicknessMin;\r\n        this._thinFilmThicknessTexture;\r\n        this._thinFilmIor;\r\n        this._emissionLuminance;\r\n        this._emissionColor;\r\n        this._emissionColorTexture;\r\n        this._ambientOcclusionTexture;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     */\r\n    public override get hasRenderTargetTextures(): boolean {\r\n        if (MaterialFlags.ReflectionTextureEnabled && this._radianceTexture && this._radianceTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        if (MaterialFlags.RefractionTextureEnabled && this._backgroundRefractionTexture && this._backgroundRefractionTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        return this._cacheHasRenderTargetTextures;\r\n    }\r\n\r\n    /**\r\n     * Can this material render to prepass\r\n     */\r\n    public override get isPrePassCapable(): boolean {\r\n        return !this.disableDepthWrite;\r\n    }\r\n\r\n    /**\r\n     * @returns the name of the material class.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"OpenPBRMaterial\";\r\n    }\r\n\r\n    protected override _transparencyMode: number = Material.MATERIAL_OPAQUE;\r\n\r\n    @serialize()\r\n    public override get transparencyMode(): number {\r\n        return this._transparencyMode;\r\n    }\r\n\r\n    public override set transparencyMode(value: number) {\r\n        if (this._transparencyMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._transparencyMode = value;\r\n\r\n        this._markAllSubMeshesAsTexturesAndMiscDirty();\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not the alpha value of the albedo texture should be used for alpha blending.\r\n     */\r\n    protected _shouldUseAlphaFromBaseColorTexture(): boolean {\r\n        return this._hasAlphaChannel() && this._transparencyMode !== Material.MATERIAL_OPAQUE && !this.geometryOpacityTexture;\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not there is a usable alpha channel for transparency.\r\n     */\r\n    protected _hasAlphaChannel(): boolean {\r\n        return (this.baseColorTexture != null && this.baseColorTexture.hasAlpha && this._useAlphaFromBaseColorTexture) || this.geometryOpacityTexture != null;\r\n    }\r\n\r\n    /**\r\n     * @returns true when the material needs alpha blending — i.e. when geometry_opacity < 1\r\n     * or a geometry opacity texture is present.\r\n     */\r\n    public override needAlphaBlending(): boolean {\r\n        return this.geometryOpacity < 1.0 || this.geometryOpacityTexture != null;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the mesh will require alpha blending.\r\n     * Overridden to check geometry_opacity before the _hasTransparencyMode short-circuit in the\r\n     * base class, which would otherwise always return false when _transparencyMode is MATERIAL_OPAQUE.\r\n     * @param mesh The mesh to check\r\n     * @returns true if alpha blending is needed for the mesh\r\n     */\r\n    public override needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {\r\n        return this.geometryOpacity < 1.0 || this.geometryOpacityTexture != null || super.needAlphaBlendingForMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current material.\r\n     * @param name - name to use for the new material.\r\n     * @param cloneTexturesOnlyOnce - if a texture is used in more than one channel (e.g baseColor and opacity), only clone it once and reuse it on the other channels. Default false.\r\n     * @param rootUrl defines the root URL to use to load textures\r\n     * @returns cloned material instance\r\n     */\r\n    public override clone(name: string, cloneTexturesOnlyOnce: boolean = true, rootUrl = \"\"): OpenPBRMaterial {\r\n        const clone = SerializationHelper.Clone(() => new OpenPBRMaterial(name, this.getScene()), this, { cloneTexturesOnlyOnce });\r\n\r\n        clone.id = name;\r\n        clone.name = name;\r\n\r\n        this.stencil.copyTo(clone.stencil);\r\n\r\n        this._clonePlugins(clone, rootUrl);\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serializes this PBR Material.\r\n     * @returns - An object with the serialized material.\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.customType = \"BABYLON.OpenPBRMaterial\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Parses a PBR Material from a serialized object.\r\n     * @param source - Serialized object.\r\n     * @param scene - BJS scene instance.\r\n     * @param rootUrl - url for the scene object\r\n     * @returns - OpenPBRMaterial\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): OpenPBRMaterial {\r\n        const material = SerializationHelper.Parse(() => new OpenPBRMaterial(source.name, scene), source, scene, rootUrl);\r\n\r\n        if (source.stencil) {\r\n            material.stencil.parse(source.stencil, scene, rootUrl);\r\n        }\r\n\r\n        Material._ParsePlugins(source, material, scene, rootUrl);\r\n\r\n        return material;\r\n    }\r\n\r\n    /**\r\n     * Force shader compilation\r\n     * @param mesh - Define the mesh we want to force the compilation for\r\n     * @param onCompiled - Define a callback triggered when the compilation completes\r\n     * @param options - Define the options used to create the compilation\r\n     */\r\n    public override forceCompilation(mesh: AbstractMesh, onCompiled?: (material: Material) => void, options?: Partial<IMaterialCompilationOptions>): void {\r\n        const localOptions = {\r\n            clipPlane: false,\r\n            useInstances: false,\r\n            ...options,\r\n        };\r\n\r\n        if (!this._uniformBufferLayoutBuilt) {\r\n            this.buildUniformLayout();\r\n        }\r\n\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.GetDefineNames, this._eventInfo);\r\n        const checkReady = () => {\r\n            if (this._breakShaderLoadedCheck) {\r\n                return;\r\n            }\r\n\r\n            const defines = new OpenPBRMaterialDefines({\r\n                ...(this._eventInfo.defineNames || {}),\r\n                ...(this._samplerDefines || {}),\r\n            });\r\n            const effect = this._prepareEffect(mesh, mesh, defines, undefined, undefined, localOptions.useInstances, localOptions.clipPlane)!;\r\n            if (this._onEffectCreatedObservable) {\r\n                onCreatedEffectParameters.effect = effect;\r\n                onCreatedEffectParameters.subMesh = null;\r\n                this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);\r\n            }\r\n            if (effect.isReady()) {\r\n                if (onCompiled) {\r\n                    onCompiled(this);\r\n                }\r\n            } else {\r\n                effect.onCompileObservable.add(() => {\r\n                    if (onCompiled) {\r\n                        onCompiled(this);\r\n                    }\r\n                });\r\n            }\r\n        };\r\n        checkReady();\r\n    }\r\n\r\n    /**\r\n     * Specifies that the submesh is ready to be used.\r\n     * @param mesh - BJS mesh.\r\n     * @param subMesh - A submesh of the BJS mesh.  Used to check if it is ready.\r\n     * @param useInstances - Specifies that instances should be used.\r\n     * @returns - boolean indicating that the submesh is ready or not.\r\n     */\r\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {\r\n        if (!this._uniformBufferLayoutBuilt) {\r\n            this.buildUniformLayout();\r\n        }\r\n\r\n        const drawWrapper = subMesh._drawWrapper;\r\n\r\n        if (drawWrapper.effect && this.isFrozen) {\r\n            if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (!subMesh.materialDefines) {\r\n            this._callbackPluginEventGeneric(MaterialPluginEvent.GetDefineNames, this._eventInfo);\r\n            subMesh.materialDefines = new OpenPBRMaterialDefines({\r\n                ...(this._eventInfo.defineNames || {}),\r\n                ...(this._samplerDefines || {}),\r\n            });\r\n        }\r\n\r\n        const defines = <OpenPBRMaterialDefines>subMesh.materialDefines;\r\n        if (this._isReadyForSubMesh(subMesh)) {\r\n            return true;\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        if (defines._areTexturesDirty) {\r\n            this._eventInfo.hasRenderTargetTextures = false;\r\n            this._callbackPluginEventHasRenderTargetTextures(this._eventInfo);\r\n            this._cacheHasRenderTargetTextures = this._eventInfo.hasRenderTargetTextures;\r\n            if (scene.texturesEnabled) {\r\n                // Loop through samplers, check MaterialFlag and whether the texture is ready or not.\r\n                for (const key in this._samplersList) {\r\n                    const sampler = this._samplersList[key];\r\n                    if (sampler.value) {\r\n                        if (!sampler.value.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                const radianceTexture = this._getRadianceTexture();\r\n                if (radianceTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    if (!radianceTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                    if (radianceTexture.irradianceTexture) {\r\n                        if (!radianceTexture.irradianceTexture.isReadyOrNotBlocking()) {\r\n                            return false;\r\n                        }\r\n                    } else {\r\n                        // Not ready until spherical are ready too.\r\n                        if (!radianceTexture.sphericalPolynomial && radianceTexture.getInternalTexture()?._sphericalPolynomialPromise) {\r\n                            return false;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    // This is blocking.\r\n                    if (!this._environmentBRDFTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._environmentFuzzBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    // This is blocking.\r\n                    if (!this._environmentFuzzBRDFTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (this._backgroundRefractionTexture && MaterialFlags.RefractionTextureEnabled) {\r\n                    if (!this._backgroundRefractionTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                if (OpenPBRMaterial._noiseTextures[scene.uniqueId]) {\r\n                    if (!OpenPBRMaterial._noiseTextures[scene.uniqueId].isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                // When both SSS textures are assigned they will be used for screen-space subsurface\r\n                // scattering. Block readiness until both underlying textures are loaded so that\r\n                // scene.onReadyObservable never fires with missing SSS data.\r\n                if (this._sssIrradianceTexture && this._sssDepthTexture) {\r\n                    if (!this._sssIrradianceTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                    if (!this._sssDepthTexture.isReady()) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._eventInfo.isReadyForSubMesh = true;\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);\r\n\r\n        if (!this._eventInfo.isReadyForSubMesh) {\r\n            return false;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {\r\n            if (!this._imageProcessingConfiguration.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        // Check if Area Lights have LTC texture.\r\n        if (defines[\"AREALIGHTUSED\"]) {\r\n            for (let index = 0; index < mesh.lightSources.length; index++) {\r\n                if (!mesh.lightSources[index]._isReady()) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!engine.getCaps().standardDerivatives && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            mesh.createNormals(true);\r\n            Logger.Warn(\"OpenPBRMaterial: Normals have been created for the mesh: \" + mesh.name);\r\n        }\r\n\r\n        if (!AreLightsTexturesReady(scene, mesh, this._maxSimultaneousLights, this._disableLighting)) {\r\n            return false;\r\n        }\r\n\r\n        const previousEffect = subMesh.effect;\r\n        const lightDisposed = defines._areLightsDisposed;\r\n        const effect = this._prepareEffect(mesh, subMesh.getRenderingMesh(), defines, this.onCompiled, this.onError, useInstances, null);\r\n\r\n        let forceWasNotReadyPreviously = false;\r\n\r\n        if (effect) {\r\n            if (this._onEffectCreatedObservable) {\r\n                onCreatedEffectParameters.effect = effect;\r\n                onCreatedEffectParameters.subMesh = subMesh;\r\n                this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);\r\n            }\r\n\r\n            // Use previous effect while new one is compiling\r\n            if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {\r\n                defines.markAsUnprocessed();\r\n\r\n                forceWasNotReadyPreviously = this.isFrozen;\r\n\r\n                if (lightDisposed) {\r\n                    // re register in case it takes more than one frame.\r\n                    defines._areLightsDisposed = true;\r\n                    return false;\r\n                }\r\n            } else {\r\n                scene.resetCachedMaterial();\r\n                subMesh.setEffect(effect, defines, this._materialContext);\r\n            }\r\n        }\r\n\r\n        if (!subMesh.effect || !subMesh.effect.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        defines._renderId = scene.getRenderId();\r\n        drawWrapper._wasPreviouslyReady = forceWasNotReadyPreviously ? false : true;\r\n        drawWrapper._wasPreviouslyUsingInstances = !!useInstances;\r\n\r\n        this._checkScenePerformancePriority();\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Initializes the uniform buffer layout for the shader.\r\n     */\r\n    public override buildUniformLayout(): void {\r\n        // Order is important !\r\n        const ubo = this._uniformBuffer;\r\n        ubo.addUniform(\"vTangentSpaceParams\", 2);\r\n        ubo.addUniform(\"vLightingIntensity\", 4);\r\n\r\n        ubo.addUniform(\"pointSize\", 1);\r\n\r\n        ubo.addUniform(\"vDebugMode\", 2);\r\n        ubo.addUniform(\"renderTargetSize\", 2);\r\n        ubo.addUniform(\"cameraInfo\", 4);\r\n        ubo.addUniform(\"vTextureRepetitionHexTilingParams\", 4);\r\n        ubo.addUniform(\"backgroundRefractionMatrix\", 16);\r\n        ubo.addUniform(\"vBackgroundRefractionInfos\", 3);\r\n        PrepareUniformLayoutForIBL(ubo, true, true, true, true, true);\r\n\r\n        Object.values(this._uniformsList).forEach((uniform) => {\r\n            ubo.addUniform(uniform.name, uniform.numComponents);\r\n        });\r\n\r\n        Object.values(this._samplersList).forEach((sampler) => {\r\n            ubo.addUniform(sampler.samplerInfoName, 2);\r\n            ubo.addUniform(sampler.samplerMatrixName, 16);\r\n        });\r\n\r\n        super.buildUniformLayout();\r\n    }\r\n\r\n    /**\r\n     * Binds the material data (this function is called even if mustRebind() returns false)\r\n     * @param uniformBuffer defines the Uniform buffer to fill in.\r\n     * @param scene defines the scene the material belongs to.\r\n     * @param engine defines the engine the material belongs to.\r\n     * @param subMesh the submesh to bind data for\r\n     */\r\n    public bindPropertiesForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void {\r\n        // If min/max thickness is 0, avoid decomposing to determine the scaled thickness (it's always zero).\r\n        if (this.geometryThickness === 0.0) {\r\n            uniformBuffer.updateFloat(\"vGeometryThickness\", 0);\r\n        } else {\r\n            subMesh.getRenderingMesh().getWorldMatrix().decompose(TmpVectors.Vector3[0]);\r\n            const thicknessScale = Math.max(Math.abs(TmpVectors.Vector3[0].x), Math.abs(TmpVectors.Vector3[0].y), Math.abs(TmpVectors.Vector3[0].z));\r\n            uniformBuffer.updateFloat(\"vGeometryThickness\", this.geometryThickness * thicknessScale);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the submesh data.\r\n     * @param world - The world matrix.\r\n     * @param mesh - The BJS mesh.\r\n     * @param subMesh - A submesh of the BJS mesh.\r\n     */\r\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\r\n        const scene = this.getScene();\r\n\r\n        const defines = <OpenPBRMaterialDefines>subMesh.materialDefines;\r\n        if (!defines) {\r\n            return;\r\n        }\r\n\r\n        const effect = subMesh.effect;\r\n\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        this._activeEffect = effect;\r\n\r\n        // Matrices Mesh.\r\n        mesh.getMeshUniformBuffer().bindToEffect(effect, \"Mesh\");\r\n        mesh.transferToEffect(world);\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        // Binding unconditionally\r\n        this._uniformBuffer.bindToEffect(effect, \"Material\");\r\n\r\n        this.prePassConfiguration.bindForSubMesh(this._activeEffect, scene, mesh, world, this.isFrozen);\r\n\r\n        MaterialHelperGeometryRendering.Bind(engine.currentRenderPassId, this._activeEffect, mesh, world, this);\r\n\r\n        const camera = scene.activeCamera;\r\n        if (camera) {\r\n            this._uniformBuffer.updateFloat4(\"cameraInfo\", camera.minZ, camera.maxZ, 0, 0);\r\n        } else {\r\n            this._uniformBuffer.updateFloat4(\"cameraInfo\", 0, 0, 0, 0);\r\n        }\r\n\r\n        const hexParams = this.textureRepetitionHexTilingParams;\r\n        this._uniformBuffer.updateFloat4(\"vTextureRepetitionHexTilingParams\", hexParams[0], hexParams[1], hexParams[2], hexParams[3]);\r\n\r\n        this._eventInfo.subMesh = subMesh;\r\n        this._callbackPluginEventHardBindForSubMesh(this._eventInfo);\r\n\r\n        // Normal Matrix\r\n        if (defines.OBJECTSPACE_NORMALMAP) {\r\n            world.toNormalMatrix(this._normalMatrix);\r\n            this.bindOnlyNormalMatrix(this._normalMatrix);\r\n        }\r\n\r\n        const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);\r\n        const needToAlwaysBindUniformBuffers = engine._features.needToAlwaysBindUniformBuffers;\r\n\r\n        // Bones\r\n        BindBonesParameters(mesh, this._activeEffect, this.prePassConfiguration);\r\n\r\n        // Vertex pulling\r\n        if (this._vertexPullingMetadata) {\r\n            BindVertexPullingUniforms(this._activeEffect, this._vertexPullingMetadata);\r\n        }\r\n\r\n        const ubo = this._uniformBuffer;\r\n        if (mustRebind) {\r\n            this.bindViewProjection(effect);\r\n            const radianceTexture: Nullable<BaseTexture> = this._getRadianceTexture();\r\n\r\n            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync || subMesh._drawWrapper._forceRebindOnNextCall) {\r\n                // Texture uniforms\r\n                if (scene.texturesEnabled) {\r\n                    // Loop through samplers and bind info and matrix for each texture.\r\n                    for (const key in this._samplersList) {\r\n                        const sampler = this._samplersList[key];\r\n                        if (sampler.value) {\r\n                            ubo.updateFloat2(sampler.samplerInfoName, sampler.value.coordinatesIndex, sampler.value.level);\r\n                            BindTextureMatrix(sampler.value, ubo, sampler.samplerPrefix);\r\n                        }\r\n                    }\r\n\r\n                    if (this.geometryNormalTexture || this.geometryCoatNormalTexture) {\r\n                        if (scene._mirroredCameraPosition) {\r\n                            ubo.updateFloat2(\"vTangentSpaceParams\", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);\r\n                        } else {\r\n                            ubo.updateFloat2(\"vTangentSpaceParams\", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);\r\n                        }\r\n                    }\r\n\r\n                    BindIBLParameters(scene, defines, ubo, Color3.White(), radianceTexture, this.realTimeFiltering, true, true, true, true, true);\r\n                }\r\n\r\n                // Point size\r\n                if (this.pointsCloud) {\r\n                    ubo.updateFloat(\"pointSize\", this.pointSize);\r\n                }\r\n\r\n                const uniformsArray = this._uniformsArray;\r\n                for (let i = 0, len = uniformsArray.length; i < len; i++) {\r\n                    const uniform = uniformsArray[i];\r\n                    // Skip uniforms whose define is currently inactive. The shader only\r\n                    // reads them inside the same #ifdef block, so the UBO bytes can stay\r\n                    // stale. The full update will happen on the next bind once the\r\n                    // define becomes active again.\r\n                    if (uniform.requiredDefine !== undefined && !defines[uniform.requiredDefine]) {\r\n                        continue;\r\n                    }\r\n                    // If the property actually defines a uniform, update it.\r\n                    if (uniform.numComponents === 4) {\r\n                        uniform.populateVectorFromLinkedProperties(TmpVectors.Vector4[0]);\r\n                        ubo.updateVector4(uniform.name, TmpVectors.Vector4[0]);\r\n                    } else if (uniform.numComponents === 3) {\r\n                        uniform.populateVectorFromLinkedProperties(TmpVectors.Vector3[0]);\r\n                        ubo.updateVector3(uniform.name, TmpVectors.Vector3[0]);\r\n                    } else if (uniform.numComponents === 2) {\r\n                        uniform.populateVectorFromLinkedProperties(TmpVectors.Vector2[0]);\r\n                        ubo.updateFloat2(uniform.name, TmpVectors.Vector2[0].x, TmpVectors.Vector2[0].y);\r\n                    } else if (uniform.numComponents === 1) {\r\n                        ubo.updateFloat(uniform.name, uniform.linkedProperties[uniform.firstLinkedKey].value as number);\r\n                    }\r\n                }\r\n\r\n                // Misc\r\n                this._lightingInfos.x = this.directIntensity;\r\n                this._lightingInfos.y = this.emissionLuminance;\r\n                this._lightingInfos.z = this.environmentIntensity * scene.environmentIntensity;\r\n                this._lightingInfos.w = 1.0; // This is used to be _specularIntensity.\r\n\r\n                ubo.updateVector4(\"vLightingIntensity\", this._lightingInfos);\r\n\r\n                ubo.updateFloat2(\"vDebugMode\", this.debugLimit, this.debugFactor);\r\n            }\r\n\r\n            // Textures\r\n            if (scene.texturesEnabled) {\r\n                // Loop through samplers and set textures\r\n                for (const key in this._samplersList) {\r\n                    const sampler = this._samplersList[key];\r\n                    if (sampler.value) {\r\n                        ubo.setTexture(sampler.samplerName, sampler.value);\r\n                    }\r\n                }\r\n\r\n                BindIBLSamplers(scene, defines, ubo, radianceTexture, this.realTimeFiltering);\r\n\r\n                if (defines.ENVIRONMENTBRDF) {\r\n                    ubo.setTexture(\"environmentBrdfSampler\", this._environmentBRDFTexture);\r\n                }\r\n\r\n                if (defines.FUZZENVIRONMENTBRDF) {\r\n                    ubo.setTexture(\"environmentFuzzBrdfSampler\", this._environmentFuzzBRDFTexture);\r\n                }\r\n\r\n                if (defines.REFRACTED_BACKGROUND) {\r\n                    ubo.setTexture(\"backgroundRefractionSampler\", this._backgroundRefractionTexture);\r\n                    ubo.updateMatrix(\"backgroundRefractionMatrix\", this._backgroundRefractionTexture!.getReflectionTextureMatrix());\r\n                    TmpVectors.Vector3[1].set(Math.log2(this._backgroundRefractionTexture!.getSize().width), 0, 0);\r\n                    ubo.updateVector3(\"vBackgroundRefractionInfos\", TmpVectors.Vector3[1]);\r\n                }\r\n\r\n                if (defines.ANISOTROPIC || defines.FUZZ || defines.REFRACTED_BACKGROUND || defines.USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) {\r\n                    ubo.setTexture(\"blueNoiseSampler\", OpenPBRMaterial._noiseTextures[this.getScene().uniqueId]);\r\n                }\r\n\r\n                if (defines.USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) {\r\n                    if (this.sssIrradianceTexture && this.sssDepthTexture) {\r\n                        const renderTargetWidth = this.sssIrradianceTexture.getSize().width;\r\n                        const renderTargetHeight = this.sssIrradianceTexture.getSize().height;\r\n                        ubo.setTexture(\"sceneIrradianceSampler\", this.sssIrradianceTexture);\r\n                        ubo.setTexture(\"sceneDepthSampler\", this.sssDepthTexture);\r\n                        ubo.updateFloat2(\"renderTargetSize\", renderTargetWidth, renderTargetHeight);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // OIT with depth peeling\r\n            if (this.getScene().useOrderIndependentTransparency && this.needAlphaBlendingForMesh(mesh)) {\r\n                this.getScene().depthPeelingRenderer!.bind(effect);\r\n            }\r\n\r\n            this._eventInfo.subMesh = subMesh;\r\n            this._callbackPluginEventBindForSubMesh(this._eventInfo);\r\n\r\n            // Clip plane\r\n            BindClipPlane(this._activeEffect, this, scene);\r\n\r\n            this.bindEyePosition(effect);\r\n        } else if (needToAlwaysBindUniformBuffers) {\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n\r\n        this.bindPropertiesForSubMesh(this._uniformBuffer, scene, scene.getEngine() as Engine, subMesh);\r\n\r\n        // Lights\r\n        if ((mustRebind || !this.isFrozen || needToAlwaysBindUniformBuffers) && scene.lightsEnabled && !this._disableLighting) {\r\n            BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);\r\n        }\r\n\r\n        if (mustRebind || !this.isFrozen) {\r\n            // View\r\n            this.bindView(effect);\r\n\r\n            // Fog\r\n            BindFogParameters(scene, mesh, this._activeEffect, true);\r\n\r\n            // Morph targets\r\n            if (defines.NUM_MORPH_INFLUENCERS) {\r\n                BindMorphTargetParameters(mesh, this._activeEffect);\r\n            }\r\n\r\n            if (defines.BAKED_VERTEX_ANIMATION_TEXTURE) {\r\n                mesh.bakedVertexAnimationManager?.bind(effect, defines.INSTANCES);\r\n            }\r\n\r\n            // image processing\r\n            this._imageProcessingConfiguration.bind(this._activeEffect);\r\n\r\n            // Log. depth\r\n            BindLogDepth(defines, this._activeEffect, scene);\r\n        }\r\n\r\n        this._afterBind(mesh, this._activeEffect, subMesh);\r\n\r\n        ubo.update();\r\n    }\r\n\r\n    /**\r\n     * Returns the animatable textures.\r\n     * If material have animatable metallic texture, then reflectivity texture will not be returned, even if it has animations.\r\n     * @returns - Array of animatable textures.\r\n     */\r\n    public override getAnimatables(): IAnimatable[] {\r\n        const results = super.getAnimatables();\r\n\r\n        // Loop through samplers and push animated textures to list.\r\n        for (const key in this._samplersList) {\r\n            const sampler = this._samplersList[key];\r\n            if (sampler.value && sampler.value.animations && sampler.value.animations.length > 0) {\r\n                results.push(sampler.value);\r\n            }\r\n        }\r\n\r\n        if (this._radianceTexture && this._radianceTexture.animations && this._radianceTexture.animations.length > 0) {\r\n            results.push(this._radianceTexture);\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Returns an array of the actively used textures.\r\n     * @returns - Array of BaseTextures\r\n     */\r\n    public override getActiveTextures(): BaseTexture[] {\r\n        const activeTextures = super.getActiveTextures();\r\n\r\n        // Loop through samplers and push active textures\r\n        for (const key in this._samplersList) {\r\n            const sampler = this._samplersList[key];\r\n            if (sampler.value) {\r\n                activeTextures.push(sampler.value);\r\n            }\r\n        }\r\n\r\n        if (this._radianceTexture) {\r\n            activeTextures.push(this._radianceTexture);\r\n        }\r\n\r\n        return activeTextures;\r\n    }\r\n\r\n    /**\r\n     * Checks to see if a texture is used in the material.\r\n     * @param texture - Base texture to use.\r\n     * @returns - Boolean specifying if a texture is used in the material.\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (super.hasTexture(texture)) {\r\n            return true;\r\n        }\r\n\r\n        // Loop through samplers and check each texture for equality\r\n        for (const key in this._samplersList) {\r\n            const sampler = this._samplersList[key];\r\n            if (sampler.value === texture) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (this._radianceTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Sets the required values to the prepass renderer.\r\n     * It can't be sets when subsurface scattering of this material is disabled.\r\n     * When scene have ability to enable subsurface prepass effect, it will enable.\r\n     * @returns - If prepass is enabled or not.\r\n     */\r\n    public override setPrePassRenderer(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources of the material.\r\n     * @param forceDisposeEffect - Forces the disposal of effects.\r\n     * @param forceDisposeTextures - Forces the disposal of all textures.\r\n     */\r\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {\r\n        this._breakShaderLoadedCheck = true;\r\n        if (forceDisposeTextures) {\r\n            if (this._environmentBRDFTexture && (this.getScene() as any).openPBREnvironmentBRDFTexture !== this._environmentBRDFTexture) {\r\n                this._environmentBRDFTexture.dispose();\r\n            }\r\n            if (this._environmentFuzzBRDFTexture && this.getScene().environmentFuzzBRDFTexture !== this._environmentFuzzBRDFTexture) {\r\n                this._environmentFuzzBRDFTexture.dispose();\r\n            }\r\n            // The refraction texture will be cleaned up by the transmission helper.\r\n            this._backgroundRefractionTexture = null;\r\n\r\n            // Loop through samplers and dispose the textures\r\n            for (const key in this._samplersList) {\r\n                const sampler = this._samplersList[key];\r\n                sampler.value?.dispose();\r\n            }\r\n\r\n            this._radianceTexture?.dispose();\r\n        }\r\n\r\n        this._renderTargets.dispose();\r\n\r\n        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n        }\r\n\r\n        super.dispose(forceDisposeEffect, forceDisposeTextures);\r\n    }\r\n\r\n    /**\r\n     * Returns the texture used for reflections.\r\n     * @returns - Reflection texture if present.  Otherwise, returns the environment texture.\r\n     */\r\n    private _getRadianceTexture(): Nullable<BaseTexture> {\r\n        if (this._radianceTexture) {\r\n            return this._radianceTexture;\r\n        }\r\n\r\n        return this.getScene().environmentTexture;\r\n    }\r\n\r\n    private _prepareEffect(\r\n        mesh: AbstractMesh,\r\n        renderingMesh: AbstractMesh,\r\n        defines: OpenPBRMaterialDefines,\r\n        onCompiled: Nullable<(effect: Effect) => void> = null,\r\n        onError: Nullable<(effect: Effect, errors: string) => void> = null,\r\n        useInstances: Nullable<boolean> = null,\r\n        useClipPlane: Nullable<boolean> = null\r\n    ): Nullable<Effect> {\r\n        this._prepareDefines(mesh, renderingMesh, defines, useInstances, useClipPlane);\r\n\r\n        if (!defines.isDirty) {\r\n            return null;\r\n        }\r\n\r\n        defines.markAsProcessed();\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        // Fallbacks\r\n        const fallbacks = new EffectFallbacks();\r\n        let fallbackRank = 0;\r\n        if (defines.USESPHERICALINVERTEX) {\r\n            fallbacks.addFallback(fallbackRank++, \"USESPHERICALINVERTEX\");\r\n        }\r\n\r\n        if (defines.FOG) {\r\n            fallbacks.addFallback(fallbackRank, \"FOG\");\r\n        }\r\n        if (defines.SPECULARAA) {\r\n            fallbacks.addFallback(fallbackRank, \"SPECULARAA\");\r\n        }\r\n        if (defines.POINTSIZE) {\r\n            fallbacks.addFallback(fallbackRank, \"POINTSIZE\");\r\n        }\r\n        if (defines.LOGARITHMICDEPTH) {\r\n            fallbacks.addFallback(fallbackRank, \"LOGARITHMICDEPTH\");\r\n        }\r\n        if (defines.PARALLAX) {\r\n            fallbacks.addFallback(fallbackRank, \"PARALLAX\");\r\n        }\r\n        if (defines.PARALLAX_RHS) {\r\n            fallbacks.addFallback(fallbackRank, \"PARALLAX_RHS\");\r\n        }\r\n        if (defines.PARALLAXOCCLUSION) {\r\n            fallbacks.addFallback(fallbackRank++, \"PARALLAXOCCLUSION\");\r\n        }\r\n\r\n        if (defines.ENVIRONMENTBRDF) {\r\n            fallbacks.addFallback(fallbackRank++, \"ENVIRONMENTBRDF\");\r\n        }\r\n\r\n        if (defines.TANGENT) {\r\n            fallbacks.addFallback(fallbackRank++, \"TANGENT\");\r\n        }\r\n\r\n        fallbackRank = HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank);\r\n\r\n        if (defines.SPECULARTERM) {\r\n            fallbacks.addFallback(fallbackRank++, \"SPECULARTERM\");\r\n        }\r\n\r\n        if (defines.USESPHERICALFROMREFLECTIONMAP) {\r\n            fallbacks.addFallback(fallbackRank++, \"USESPHERICALFROMREFLECTIONMAP\");\r\n        }\r\n\r\n        if (defines.USEIRRADIANCEMAP) {\r\n            fallbacks.addFallback(fallbackRank++, \"USEIRRADIANCEMAP\");\r\n        }\r\n\r\n        if (defines.NORMAL) {\r\n            fallbacks.addFallback(fallbackRank++, \"NORMAL\");\r\n        }\r\n\r\n        if (defines.VERTEXCOLOR) {\r\n            fallbacks.addFallback(fallbackRank++, \"VERTEXCOLOR\");\r\n        }\r\n\r\n        if (defines.MORPHTARGETS) {\r\n            fallbacks.addFallback(fallbackRank++, \"MORPHTARGETS\");\r\n        }\r\n\r\n        if (defines.MULTIVIEW) {\r\n            fallbacks.addFallback(0, \"MULTIVIEW\");\r\n        }\r\n\r\n        //Attributes\r\n        const attribs = [VertexBuffer.PositionKind];\r\n\r\n        if (defines.NORMAL) {\r\n            attribs.push(VertexBuffer.NormalKind);\r\n        }\r\n\r\n        if (defines.TANGENT) {\r\n            attribs.push(VertexBuffer.TangentKind);\r\n        }\r\n\r\n        for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n            if (defines[\"UV\" + i]) {\r\n                attribs.push(`uv${i === 1 ? \"\" : i}`);\r\n            }\r\n        }\r\n\r\n        if (defines.VERTEXCOLOR) {\r\n            attribs.push(VertexBuffer.ColorKind);\r\n        }\r\n\r\n        PrepareAttributesForBones(attribs, mesh, defines, fallbacks);\r\n        PrepareAttributesForInstances(attribs, defines);\r\n        PrepareAttributesForMorphTargets(attribs, mesh, defines);\r\n        PrepareAttributesForBakedVertexAnimation(attribs, mesh, defines);\r\n\r\n        let shaderName = \"openpbr\";\r\n\r\n        const uniforms = [\r\n            \"world\",\r\n            \"view\",\r\n            \"viewProjection\",\r\n            \"projection\",\r\n            \"vEyePosition\",\r\n            \"inverseProjection\",\r\n            \"renderTargetSize\",\r\n            \"vLightsType\",\r\n            \"visibility\",\r\n            \"vFogInfos\",\r\n            \"vFogColor\",\r\n            \"pointSize\",\r\n            \"mBones\",\r\n            \"normalMatrix\",\r\n            \"vLightingIntensity\",\r\n            \"logarithmicDepthConstant\",\r\n            \"vTangentSpaceParams\",\r\n            \"boneTextureInfo\",\r\n            \"vDebugMode\",\r\n            \"morphTargetTextureInfo\",\r\n            \"morphTargetTextureIndices\",\r\n            \"cameraInfo\",\r\n            \"vTextureRepetitionHexTilingParams\",\r\n            \"backgroundRefractionMatrix\",\r\n            \"vBackgroundRefractionInfos\",\r\n        ];\r\n\r\n        for (const uniformName in this._uniformsList) {\r\n            uniforms.push(uniformName);\r\n        }\r\n\r\n        const samplers = [\"environmentBrdfSampler\", \"boneSampler\", \"morphTargets\", \"oitDepthSampler\", \"oitFrontColorSampler\", \"areaLightsLTC1Sampler\", \"areaLightsLTC2Sampler\"];\r\n\r\n        if (defines.FUZZENVIRONMENTBRDF) {\r\n            samplers.push(\"environmentFuzzBrdfSampler\");\r\n        }\r\n\r\n        if (defines.REFRACTED_BACKGROUND) {\r\n            samplers.push(\"backgroundRefractionSampler\");\r\n        }\r\n\r\n        if (defines.ANISOTROPIC || defines.FUZZ || defines.REFRACTED_BACKGROUND || defines.USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) {\r\n            samplers.push(\"blueNoiseSampler\");\r\n        }\r\n\r\n        if (defines.USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) {\r\n            samplers.push(\"sceneIrradianceSampler\");\r\n            samplers.push(\"sceneDepthSampler\");\r\n        }\r\n\r\n        for (const key in this._samplersList) {\r\n            const sampler = this._samplersList[key];\r\n            samplers.push(sampler.samplerName);\r\n\r\n            // Push uniforms for texture infos and matrix\r\n            uniforms.push(sampler.samplerInfoName);\r\n            uniforms.push(sampler.samplerMatrixName);\r\n        }\r\n\r\n        PrepareUniformsAndSamplersForIBL(uniforms, samplers, true);\r\n\r\n        const uniformBuffers = [\"Material\", \"Scene\", \"Mesh\"];\r\n\r\n        const indexParameters = { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS };\r\n\r\n        this._eventInfo.fallbacks = fallbacks;\r\n        this._eventInfo.fallbackRank = fallbackRank;\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.uniforms = uniforms;\r\n        this._eventInfo.attributes = attribs;\r\n        this._eventInfo.samplers = samplers;\r\n        this._eventInfo.uniformBuffersNames = uniformBuffers;\r\n        this._eventInfo.customCode = undefined;\r\n        this._eventInfo.mesh = mesh;\r\n        this._eventInfo.indexParameters = indexParameters;\r\n        this._callbackPluginEventGeneric(MaterialPluginEvent.PrepareEffect, this._eventInfo);\r\n\r\n        MaterialHelperGeometryRendering.AddUniformsAndSamplers(uniforms, samplers);\r\n\r\n        PrePassConfiguration.AddUniforms(uniforms);\r\n        PrePassConfiguration.AddSamplers(samplers);\r\n        AddClipPlaneUniforms(uniforms);\r\n\r\n        // Vertex pulling metadata uniforms\r\n        if (this._useVertexPulling) {\r\n            const geometry = (renderingMesh as Mesh)?.geometry;\r\n            if (geometry) {\r\n                this._vertexPullingMetadata = PrepareVertexPullingUniforms(geometry);\r\n                if (this._vertexPullingMetadata) {\r\n                    this._vertexPullingMetadata.forEach((_, attribute) => {\r\n                        uniforms.push(`vp_${attribute}_info`);\r\n                    });\r\n                }\r\n            }\r\n        } else {\r\n            this._vertexPullingMetadata = null;\r\n        }\r\n\r\n        if (ImageProcessingConfiguration) {\r\n            ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);\r\n            ImageProcessingConfiguration.PrepareSamplers(samplers, defines);\r\n        }\r\n\r\n        PrepareUniformsAndSamplersList(<IEffectCreationOptions>{\r\n            uniformsNames: uniforms,\r\n            uniformBuffersNames: uniformBuffers,\r\n            samplers: samplers,\r\n            defines: defines,\r\n            maxSimultaneousLights: this._maxSimultaneousLights,\r\n            shaderLanguage: this._shaderLanguage,\r\n        });\r\n\r\n        const csnrOptions: ICustomShaderNameResolveOptions = {};\r\n\r\n        if (this.customShaderNameResolve) {\r\n            shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines, attribs, csnrOptions);\r\n        }\r\n\r\n        const join = defines.toString();\r\n        const effect = engine.createEffect(\r\n            shaderName,\r\n            <IEffectCreationOptions>{\r\n                attributes: attribs,\r\n                uniformsNames: uniforms,\r\n                uniformBuffersNames: uniformBuffers,\r\n                samplers: samplers,\r\n                defines: join,\r\n                fallbacks: fallbacks,\r\n                onCompiled: onCompiled,\r\n                onError: onError,\r\n                indexParameters,\r\n                processFinalCode: csnrOptions.processFinalCode,\r\n                processCodeAfterIncludes: this._eventInfo.customCode,\r\n                multiTarget: defines.PREPASS,\r\n                shaderLanguage: this._shaderLanguage,\r\n                extraInitializationsAsync: OpenPBRMaterial._ShaderLoader.getLoadCallback(this._shaderLanguage),\r\n            },\r\n            engine\r\n        );\r\n\r\n        this._eventInfo.customCode = undefined;\r\n\r\n        return effect;\r\n    }\r\n\r\n    private _prepareDefines(\r\n        mesh: AbstractMesh,\r\n        renderingMesh: AbstractMesh,\r\n        defines: OpenPBRMaterialDefines,\r\n        useInstances: Nullable<boolean> = null,\r\n        useClipPlane: Nullable<boolean> = null\r\n    ): void {\r\n        const useThinInstances = renderingMesh.hasThinInstances;\r\n\r\n        const scene = this.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        // Lights\r\n        PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);\r\n        defines._needNormals = true;\r\n\r\n        // Multiview\r\n        PrepareDefinesForMultiview(scene, defines);\r\n\r\n        // PrePass\r\n        const oit = this.needAlphaBlendingForMesh(mesh) && this.getScene().useOrderIndependentTransparency;\r\n        PrepareDefinesForPrePass(scene, defines, this.canRenderToMRT && !oit);\r\n\r\n        // Order independant transparency\r\n        PrepareDefinesForOIT(scene, defines, oit);\r\n\r\n        MaterialHelperGeometryRendering.PrepareDefines(engine.currentRenderPassId, mesh, defines);\r\n\r\n        // Textures\r\n        if (defines._areTexturesDirty) {\r\n            defines._needUVs = false;\r\n            for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\r\n                defines[\"MAINUV\" + i] = false;\r\n            }\r\n            if (scene.texturesEnabled) {\r\n                // Loop through samplers and prepare defines for each texture\r\n                for (const key in this._samplersList) {\r\n                    const sampler = this._samplersList[key];\r\n                    if (sampler.value) {\r\n                        PrepareDefinesForMergedUV(sampler.value, defines, sampler.textureDefine);\r\n                        defines[sampler.textureDefine + \"_GAMMA\"] = sampler.value.gammaSpace;\r\n                    } else {\r\n                        defines[sampler.textureDefine] = false;\r\n                    }\r\n                }\r\n\r\n                const radianceTexture = this._getRadianceTexture();\r\n                const useSHInFragment: boolean =\r\n                    this._forceIrradianceInFragment ||\r\n                    this.realTimeFiltering ||\r\n                    this._twoSidedLighting ||\r\n                    engine.getCaps().maxVaryingVectors <= 8 ||\r\n                    this._baseDiffuseRoughnessTexture != null;\r\n                PrepareDefinesForIBL(scene, radianceTexture, defines, this.realTimeFiltering, this.realTimeFilteringQuality, !useSHInFragment);\r\n\r\n                if (this._baseMetalnessTexture) {\r\n                    defines.AOSTOREINMETALMAPRED = this._useAmbientOcclusionFromMetallicTextureRed;\r\n                }\r\n\r\n                defines.SPECULAR_WEIGHT_IN_ALPHA = this._useSpecularWeightFromAlpha;\r\n                defines.SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE = this._useSpecularWeightFromSpecularColorTexture;\r\n                defines.SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = this._useSpecularRoughnessAnisotropyFromTangentTexture;\r\n                defines.COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = this._useCoatRoughnessAnisotropyFromTangentTexture;\r\n                defines.COAT_ROUGHNESS_FROM_GREEN_CHANNEL = this._useCoatRoughnessFromGreenChannel;\r\n                defines.SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN = this._useRoughnessFromMetallicTextureGreen;\r\n                defines.FUZZ_ROUGHNESS_FROM_TEXTURE_ALPHA = this._useFuzzRoughnessFromTextureAlpha;\r\n                defines.SUBSURFACE_WEIGHT_FROM_TEXTURE_ALPHA = this._useSubsurfaceWeightFromTextureAlpha;\r\n                defines.BASE_METALNESS_FROM_METALNESS_TEXTURE_BLUE = this._useMetallicFromMetallicTextureBlue;\r\n                defines.THIN_FILM_THICKNESS_FROM_THIN_FILM_TEXTURE = this._useThinFilmThicknessFromTextureGreen;\r\n                defines.GEOMETRY_THICKNESS_FROM_GREEN_CHANNEL = this._useGeometryThicknessFromGreenChannel;\r\n\r\n                if (this.geometryNormalTexture) {\r\n                    if (this._useParallax && this.baseColorTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                        defines.PARALLAX = true;\r\n                        defines.PARALLAX_RHS = scene.useRightHandedSystem;\r\n                        defines.PARALLAXOCCLUSION = !!this._useParallaxOcclusion;\r\n                    } else {\r\n                        defines.PARALLAX = false;\r\n                    }\r\n                    defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;\r\n                } else {\r\n                    defines.PARALLAX = false;\r\n                    defines.PARALLAX_RHS = false;\r\n                    defines.PARALLAXOCCLUSION = false;\r\n                    defines.OBJECTSPACE_NORMALMAP = false;\r\n                }\r\n\r\n                if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    defines.ENVIRONMENTBRDF = true;\r\n                    defines.ENVIRONMENTBRDF_RGBD = this._environmentBRDFTexture.isRGBD;\r\n                } else {\r\n                    defines.ENVIRONMENTBRDF = false;\r\n                    defines.ENVIRONMENTBRDF_RGBD = false;\r\n                }\r\n\r\n                if (this._environmentFuzzBRDFTexture) {\r\n                    defines.FUZZENVIRONMENTBRDF = true;\r\n                } else {\r\n                    defines.FUZZENVIRONMENTBRDF = false;\r\n                }\r\n\r\n                if (this.hasTransparency) {\r\n                    defines.REFRACTED_BACKGROUND = !!this._backgroundRefractionTexture && MaterialFlags.RefractionTextureEnabled;\r\n                    defines.REFRACTION_HIGH_QUALITY_BLUR = this._refractionHighQualityBlur;\r\n                    defines.REFRACTED_LIGHTS = true;\r\n                    const radianceTexture = this._getRadianceTexture();\r\n                    if (radianceTexture) {\r\n                        defines.REFRACTED_ENVIRONMENT = MaterialFlags.RefractionTextureEnabled;\r\n                        defines.REFRACTED_ENVIRONMENT_OPPOSITEZ = this.getScene().useRightHandedSystem ? !radianceTexture.invertZ : radianceTexture.invertZ;\r\n                        defines.REFRACTED_ENVIRONMENT_LOCAL_CUBE = radianceTexture.isCube && (<any>radianceTexture).boundingBoxSize;\r\n                    } else {\r\n                        defines.REFRACTED_ENVIRONMENT = false;\r\n                    }\r\n                } else {\r\n                    defines.REFRACTED_BACKGROUND = false;\r\n                    defines.REFRACTED_LIGHTS = false;\r\n                    defines.REFRACTED_ENVIRONMENT = false;\r\n                }\r\n\r\n                if (this._shouldUseAlphaFromBaseColorTexture()) {\r\n                    defines.ALPHA_FROM_BASE_COLOR_TEXTURE = true;\r\n                } else {\r\n                    defines.ALPHA_FROM_BASE_COLOR_TEXTURE = false;\r\n                }\r\n            }\r\n\r\n            if (this._lightFalloff === Material.LIGHTFALLOFF_STANDARD) {\r\n                defines.USEPHYSICALLIGHTFALLOFF = false;\r\n                defines.USEGLTFLIGHTFALLOFF = false;\r\n            } else if (this._lightFalloff === Material.LIGHTFALLOFF_GLTF) {\r\n                defines.USEPHYSICALLIGHTFALLOFF = false;\r\n                defines.USEGLTFLIGHTFALLOFF = true;\r\n            } else {\r\n                defines.USEPHYSICALLIGHTFALLOFF = true;\r\n                defines.USEGLTFLIGHTFALLOFF = false;\r\n            }\r\n\r\n            if (!this.backFaceCulling && this._twoSidedLighting) {\r\n                defines.TWOSIDEDLIGHTING = true;\r\n            } else {\r\n                defines.TWOSIDEDLIGHTING = false;\r\n            }\r\n\r\n            // We need it to not invert normals in two sided lighting mode (based on the winding of the face)\r\n            defines.MIRRORED = !!scene._mirroredCameraPosition;\r\n\r\n            defines.SPECULARAA = engine.getCaps().standardDerivatives && this._enableSpecularAntiAliasing;\r\n        }\r\n\r\n        if (defines._areTexturesDirty || defines._areMiscDirty) {\r\n            defines.ALPHATESTVALUE = `${this._alphaCutOff}${this._alphaCutOff % 1 === 0 ? \".\" : \"\"}`;\r\n            defines.PREMULTIPLYALPHA = this.alphaMode === Constants.ALPHA_PREMULTIPLIED || this.alphaMode === Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n            defines.ALPHABLEND = this.needAlphaBlendingForMesh(mesh);\r\n        }\r\n\r\n        if (defines._areTexturesDirty) {\r\n            defines.TEXTURE_REPETITION_MODE = engine.version > 1 || engine.isWebGPU ? this.textureRepetitionMode : 0;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {\r\n            this._imageProcessingConfiguration.prepareDefines(defines);\r\n        }\r\n\r\n        defines.FORCENORMALFORWARD = this._forceNormalForward;\r\n\r\n        defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;\r\n\r\n        defines.HORIZONOCCLUSION = this._useHorizonOcclusion;\r\n\r\n        if (\r\n            (this.specularRoughnessAnisotropy > 0.0 || this.coatRoughnessAnisotropy > 0.0) &&\r\n            OpenPBRMaterial._noiseTextures[scene.uniqueId] &&\r\n            MaterialFlags.ReflectionTextureEnabled\r\n        ) {\r\n            // ANISOTROPIC is used to include common shader functions needed for anisotropy\r\n            // ANISOTROPIC_BASE is used to process anisotropy for the base layer\r\n            // ANISOTROPIC_COAT is used to process anisotropy for the coat layer\r\n            defines.ANISOTROPIC = true;\r\n            if (!mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n                defines._needUVs = true;\r\n                defines.MAINUV1 = true;\r\n            }\r\n            if (this._useGltfStyleAnisotropy) {\r\n                defines.USE_GLTF_STYLE_ANISOTROPY = true;\r\n            }\r\n            defines.ANISOTROPIC_BASE = this.specularRoughnessAnisotropy > 0.0;\r\n            defines.ANISOTROPIC_COAT = this.coatRoughnessAnisotropy > 0.0;\r\n        } else {\r\n            defines.ANISOTROPIC = false;\r\n            defines.USE_GLTF_STYLE_ANISOTROPY = false;\r\n            defines.ANISOTROPIC_BASE = false;\r\n            defines.ANISOTROPIC_COAT = false;\r\n        }\r\n\r\n        defines.THIN_FILM = this.thinFilmWeight > 0.0;\r\n        defines.IRIDESCENCE = this.thinFilmWeight > 0.0;\r\n        defines.DISPERSION = this.transmissionDispersionScale > 0.0;\r\n        defines.SCATTERING = this.hasScattering;\r\n        const _sssSampleCounts = [8, 16, 32];\r\n        defines.SSS_SAMPLE_COUNT = _sssSampleCounts[this._sssQuality] ?? 16;\r\n        defines.TRANSMISSION_SLAB = this.transmissionWeight > 0;\r\n        defines.TRANSMISSION_SLAB_VOLUME = this.transmissionWeight > 0 && this.transmissionDepth > 0;\r\n        defines.SUBSURFACE_SLAB = this.subsurfaceWeight > 0;\r\n        // Determine whether we should use the prepass irradiance texture for scattering.\r\n        // If this IS a prepass, we don't want to use the irradiance texture as it won't be available yet.\r\n        if (!defines.PREPASS && (defines.SUBSURFACE_SLAB || defines.TRANSMISSION_SLAB_VOLUME)) {\r\n            let usingGBuffer = false;\r\n            if (!this.sssIrradianceTexture && scene.geometryBufferRenderer) {\r\n                const irradianceTextureIndex = scene.geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.IRRADIANCE_TEXTURE_TYPE);\r\n                this.sssIrradianceTexture = scene.geometryBufferRenderer.getGBuffer().textures[irradianceTextureIndex];\r\n                usingGBuffer = true;\r\n            }\r\n\r\n            if (!this.sssDepthTexture && scene.geometryBufferRenderer) {\r\n                const depthIndex = scene.geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE);\r\n                this.sssDepthTexture = scene.geometryBufferRenderer.getGBuffer().textures[depthIndex];\r\n                usingGBuffer = true;\r\n            }\r\n            if (this.sssIrradianceTexture && this.sssDepthTexture) {\r\n                defines.USE_IRRADIANCE_TEXTURE_FOR_SCATTERING = true;\r\n                if (usingGBuffer) {\r\n                    defines.USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER = true;\r\n                }\r\n            }\r\n        }\r\n        defines.FUZZ = this.fuzzWeight > 0 && MaterialFlags.ReflectionTextureEnabled;\r\n        defines.GEOMETRY_THIN_WALLED = this.geometryThinWalled != 0;\r\n\r\n        if (defines.FUZZ) {\r\n            if (!mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n                defines._needUVs = true;\r\n                defines.MAINUV1 = true;\r\n            }\r\n            this._environmentFuzzBRDFTexture = GetEnvironmentFuzzBRDFTexture(this.getScene());\r\n            defines.FUZZ_IBL_SAMPLES = this.fuzzSampleNumber;\r\n        } else {\r\n            this._environmentFuzzBRDFTexture = null;\r\n            defines.FUZZENVIRONMENTBRDF = false;\r\n            defines.FUZZ_IBL_SAMPLES = 0;\r\n        }\r\n\r\n        // Misc.\r\n        if (defines._areMiscDirty) {\r\n            PrepareDefinesForMisc(\r\n                mesh,\r\n                scene,\r\n                this._useLogarithmicDepth,\r\n                this.pointsCloud,\r\n                this.fogEnabled,\r\n                this.needAlphaTestingForMesh(mesh),\r\n                defines,\r\n                this._applyDecalMapAfterDetailMap,\r\n                this._useVertexPulling,\r\n                renderingMesh,\r\n                this._isVertexOutputInvariant\r\n            );\r\n            defines.UNLIT = this._unlit || ((this.pointsCloud || this.wireframe) && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind));\r\n            defines.DEBUGMODE = this._debugMode;\r\n        }\r\n\r\n        // Values that need to be evaluated on every frame\r\n        PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances ? true : false, useClipPlane, useThinInstances);\r\n\r\n        // External config\r\n        this._eventInfo.defines = defines;\r\n        this._eventInfo.mesh = mesh;\r\n        this._callbackPluginEventPrepareDefinesBeforeAttributes(this._eventInfo);\r\n\r\n        // Attribs\r\n        PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== Material.MATERIAL_OPAQUE);\r\n\r\n        // External config\r\n        this._callbackPluginEventPrepareDefines(this._eventInfo);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for openpbrMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterOpenpbrMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // OpenPBRMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\r\n    RegisterImageProcessingConfiguration();\r\n\r\n    RegisterClass(\"BABYLON.OpenPBRMaterial\", OpenPBRMaterial);\r\n}\r\n","type EnvironmentLightingDefinesMixinConstructor<T = {}> = new (...args: any[]) => T;\r\n\r\n/**\r\n * Mixin to add UV defines to your material defines\r\n * @internal\r\n */\r\nexport function EnvironmentLightingDefinesMixin<Tbase extends EnvironmentLightingDefinesMixinConstructor>(base: Tbase) {\r\n    return class extends base {\r\n        public REFLECTION = false;\r\n        public REFLECTIONMAP_3D = false;\r\n        public REFLECTIONMAP_SPHERICAL = false;\r\n        public REFLECTIONMAP_PLANAR = false;\r\n        public REFLECTIONMAP_CUBIC = false;\r\n        public USE_LOCAL_REFLECTIONMAP_CUBIC = false;\r\n        public REFLECTIONMAP_PROJECTION = false;\r\n        public REFLECTIONMAP_SKYBOX = false;\r\n        public REFLECTIONMAP_EXPLICIT = false;\r\n        public REFLECTIONMAP_EQUIRECTANGULAR = false;\r\n        public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;\r\n        public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;\r\n        public INVERTCUBICMAP = false;\r\n        public USESPHERICALFROMREFLECTIONMAP = false;\r\n        public USEIRRADIANCEMAP = false;\r\n        public USE_IRRADIANCE_DOMINANT_DIRECTION = false;\r\n        public USESPHERICALINVERTEX = false;\r\n        public REFLECTIONMAP_OPPOSITEZ = false;\r\n        public LODINREFLECTIONALPHA = false;\r\n        public GAMMAREFLECTION = false;\r\n        public RGBDREFLECTION = false;\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Material } from \"core/Materials/material.pure\";\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial.pure\";\nimport { StandardMaterial } from \"core/Materials/standardMaterial.pure\";\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial.pure\";\n\n/**\n * Determines whether a material can receive IBL shadows by hosting an `IBLShadowsPluginMaterial`.\n *\n * Shared by both the legacy `IblShadowsRenderPipeline` and the Frame Graph\n * `FrameGraphIblShadowsRendererTask` so the two code paths cannot drift out of sync.\n * @param material The material to test.\n * @returns True if the material supports the IBL shadows plugin.\n * @internal\n */\nexport function IsIBLShadowsReceiverCompatible(material: Material): boolean {\n    return (\n        material instanceof PBRBaseMaterial ||\n        material instanceof StandardMaterial ||\n        material instanceof OpenPBRMaterial ||\n        // ShadowOnlyMaterial lives in the separate `materials` package (which `core` cannot import),\n        // so it is identified by class name rather than `instanceof`.\n        material.getClassName() === \"ShadowOnlyMaterial\"\n    );\n}\n","import { type Nullable, type AbstractEngine, type EffectWrapperCreationOptions, type Effect } from \"core/index\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Observable } from \"../Misc/observable\";\r\n\r\n/**\r\n * Class used to apply a custom post process\r\n */\r\nexport class ThinCustomPostProcess extends EffectWrapper {\r\n    /**\r\n     * Observable triggered when the post process is bound\r\n     */\r\n    public onBindObservable: Observable<Effect> = new Observable<Effect>();\r\n\r\n    /**\r\n     * Constructs a new custom post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine: Nullable<AbstractEngine> = null, options?: EffectWrapperCreationOptions) {\r\n        super({\r\n            name,\r\n            engine: engine || EngineStore.LastCreatedEngine!,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            ...options,\r\n        });\r\n    }\r\n\r\n    public override bind(noDefaultBindings = false) {\r\n        super.bind(noDefaultBindings);\r\n\r\n        this.onBindObservable.notifyObservers(this._drawWrapper.effect!);\r\n    }\r\n}\r\n","import { type DrawWrapper, type FrameGraph, type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type FrameGraphIblShadowsVoxelizationTask } from \"./iblShadowsVoxelizationTask\";\r\nimport { Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { ThinCustomPostProcess } from \"core/PostProcesses/thinCustomPostProcess\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { FrameGraphTask } from \"../../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to temporally accumulate IBL shadows.\r\n * @internal\r\n */\r\nexport class FrameGraphIblShadowsAccumulationTask extends FrameGraphTask {\r\n    public sourceTexture?: FrameGraphTextureHandle;\r\n    public velocityTexture?: FrameGraphTextureHandle;\r\n    public positionTexture?: FrameGraphTextureHandle;\r\n\r\n    private _remanence = 0.75;\r\n\r\n    public get remanence(): number {\r\n        return this._remanence;\r\n    }\r\n\r\n    public set remanence(value: number) {\r\n        this._remanence = Math.max(0, Math.min(value, 1));\r\n    }\r\n    public reset = true;\r\n    public isMoving = false;\r\n    public voxelGridSize = 1;\r\n    /** Voxelization task providing the runtime voxelGridSize used by the accumulation shader. */\r\n    public voxelizationTask?: FrameGraphIblShadowsVoxelizationTask;\r\n\r\n    protected _previousAccumulationTexture?: FrameGraphTextureHandle;\r\n    protected _previousPositionTexture?: FrameGraphTextureHandle;\r\n\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    public readonly postProcess: ThinCustomPostProcess;\r\n    protected readonly _postProcessDrawWrapper: DrawWrapper;\r\n    protected readonly _accumulationParams = new Vector4(0, 0, 0, 0);\r\n\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.postProcess = new ThinCustomPostProcess(name, frameGraph.engine, {\r\n            fragmentShader: \"iblShadowAccumulation\",\r\n            uniforms: [\"accumulationParameters\"],\r\n            samplers: [\"spatialBlurSampler\", \"oldAccumulationSampler\", \"prevPositionSampler\", \"motionSampler\", \"positionSampler\"],\r\n            shaderLanguage: frameGraph.engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n        this._postProcessDrawWrapper = this.postProcess.drawWrapper;\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphIblShadowsAccumulationTask\";\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public override initAsync(): Promise<unknown> {\r\n        if (this._frameGraph.engine.isWebGPU) {\r\n            return import(\"../../../../ShadersWGSL/iblShadowAccumulation.fragment\");\r\n        }\r\n\r\n        return import(\"../../../../Shaders/iblShadowAccumulation.fragment\");\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return this.postProcess.isReady();\r\n    }\r\n\r\n    public override record() {\r\n        if (this.sourceTexture === undefined || this.velocityTexture === undefined || this.positionTexture === undefined) {\r\n            throw new Error(`FrameGraphIblShadowsAccumulationTask ${this.name}: sourceTexture, velocityTexture and positionTexture are required`);\r\n        }\r\n\r\n        const textureManager = this._frameGraph.textureManager;\r\n        const outputSize = textureManager.getTextureAbsoluteDimensions(this.sourceTexture);\r\n        const positionSize = textureManager.getTextureAbsoluteDimensions(this.positionTexture);\r\n\r\n        const sharedTextureOptions = {\r\n            createMipMaps: false,\r\n            samples: 1,\r\n            formats: [Constants.TEXTUREFORMAT_RGBA],\r\n            useSRGBBuffers: [false],\r\n            creationFlags: [0],\r\n        };\r\n\r\n        const outputCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: outputSize,\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: false,\r\n            options: { ...sharedTextureOptions, types: [Constants.TEXTURETYPE_HALF_FLOAT], labels: [`${this.name} Output`] },\r\n        };\r\n\r\n        const previousAccumulationCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: outputSize,\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: false,\r\n            options: { ...sharedTextureOptions, types: [Constants.TEXTURETYPE_HALF_FLOAT], labels: [`${this.name} Previous Accumulation`] },\r\n        };\r\n\r\n        const previousPositionCreationOptions: FrameGraphTextureCreationOptions = {\r\n            size: positionSize,\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: false,\r\n            options: { ...sharedTextureOptions, types: [Constants.TEXTURETYPE_HALF_FLOAT], labels: [`${this.name} Previous Position`] },\r\n        };\r\n\r\n        textureManager.resolveDanglingHandle(this.outputTexture, undefined, `${this.name} Output`, outputCreationOptions);\r\n\r\n        this._previousAccumulationTexture = textureManager.createRenderTargetTexture(\r\n            `${this.name} Previous Accumulation`,\r\n            previousAccumulationCreationOptions,\r\n            this._previousAccumulationTexture\r\n        );\r\n        this._previousPositionTexture = textureManager.createRenderTargetTexture(`${this.name} Previous Position`, previousPositionCreationOptions, this._previousPositionTexture);\r\n\r\n        // Pass 1: Accumulate into outputTexture, sampling last frame's accumulation and position.\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.addDependencies(this.sourceTexture);\r\n        pass.addDependencies(this.velocityTexture);\r\n        pass.addDependencies(this.positionTexture);\r\n        pass.addDependencies(this._previousAccumulationTexture);\r\n        pass.addDependencies(this._previousPositionTexture);\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            context.setTextureSamplingMode(this.sourceTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.velocityTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.positionTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n\r\n            const remanence = this.isMoving ? this.remanence : 0.99;\r\n            this._accumulationParams.set(remanence, this.reset ? 1.0 : 0.0, this.voxelizationTask?.voxelGridSize ?? this.voxelGridSize, 0.0);\r\n\r\n            context.applyFullScreenEffect(\r\n                this._postProcessDrawWrapper,\r\n                () => {\r\n                    const effect = this._postProcessDrawWrapper.effect!;\r\n\r\n                    context.bindTextureHandle(effect, \"spatialBlurSampler\", this.sourceTexture!);\r\n                    context.bindTextureHandle(effect, \"oldAccumulationSampler\", this._previousAccumulationTexture!);\r\n                    context.bindTextureHandle(effect, \"prevPositionSampler\", this._previousPositionTexture!);\r\n                    context.bindTextureHandle(effect, \"motionSampler\", this.velocityTexture!);\r\n                    context.bindTextureHandle(effect, \"positionSampler\", this.positionTexture!);\r\n\r\n                    effect.setVector4(\"accumulationParameters\", this._accumulationParams);\r\n                    this.postProcess.bind();\r\n                },\r\n                undefined,\r\n                false,\r\n                false,\r\n                true\r\n            );\r\n\r\n            this.reset = false;\r\n            this.isMoving = false;\r\n        });\r\n\r\n        // Pass 2: Copy the current frame's world-position into previousPositionTexture so the\r\n        // next frame's accumulation pass can use it as \"previous frame positions\".\r\n        const copyPositionToPreviousPass = this._frameGraph.addRenderPass(`${this.name} CopyPositionToPrevious`);\r\n\r\n        copyPositionToPreviousPass.addDependencies(this.positionTexture);\r\n        copyPositionToPreviousPass.setRenderTarget(this._previousPositionTexture);\r\n        copyPositionToPreviousPass.setExecuteFunc((context) => {\r\n            context.copyTexture(this.positionTexture!);\r\n        });\r\n\r\n        // Pass 3: Copy the current frame's accumulation result into previousAccumulationTexture\r\n        // so the next frame's accumulation pass can use it as oldAccumulationSampler.\r\n        const copyAccumulationToPreviousPass = this._frameGraph.addRenderPass(`${this.name} CopyAccumulationToPrevious`);\r\n\r\n        copyAccumulationToPreviousPass.addDependencies(this.outputTexture);\r\n        copyAccumulationToPreviousPass.setRenderTarget(this._previousAccumulationTexture);\r\n        copyAccumulationToPreviousPass.setExecuteFunc((context) => {\r\n            context.copyTexture(this.outputTexture);\r\n        });\r\n\r\n        // Pass 4 (marker): empty execute, render target = outputTexture.\r\n        // Ensures _checkTask sees outputTexture as the task's last enabled-pass output,\r\n        // matching the disabled path. No render pass encoder is opened because the\r\n        // execute function never calls _applyRenderTarget.\r\n        const outputMarkerPass = this._frameGraph.addRenderPass(`${this.name} Output`);\r\n\r\n        outputMarkerPass.setRenderTarget(this.outputTexture);\r\n        outputMarkerPass.setExecuteFunc((_context) => {});\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.postProcess.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","import { type DrawWrapper, type FrameGraph, type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type FrameGraphIblShadowsVoxelizationTask } from \"./iblShadowsVoxelizationTask\";\r\nimport { Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ThinCustomPostProcess } from \"core/PostProcesses/thinCustomPostProcess\";\r\nimport { FrameGraphTask } from \"../../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to spatially blur IBL shadows.\r\n * @internal\r\n */\r\nexport class FrameGraphIblShadowsSpatialBlurTask extends FrameGraphTask {\r\n    public sourceTexture?: FrameGraphTextureHandle;\r\n    public depthTexture?: FrameGraphTextureHandle;\r\n    public normalTexture?: FrameGraphTextureHandle;\r\n\r\n    /** Voxelization task providing the dynamic voxelGridSize used as worldScale. */\r\n    public voxelizationTask?: FrameGraphIblShadowsVoxelizationTask;\r\n\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    public readonly postProcess: ThinCustomPostProcess;\r\n    protected readonly _postProcessDrawWrapper: DrawWrapper;\r\n    protected readonly _blurParameters = new Vector4(0, 0, 0, 0);\r\n\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.postProcess = new ThinCustomPostProcess(name, frameGraph.engine, {\r\n            fragmentShader: \"iblShadowSpatialBlur\",\r\n            uniforms: [\"blurParameters\"],\r\n            samplers: [\"voxelTracingSampler\", \"depthSampler\", \"worldNormalSampler\"],\r\n            shaderLanguage: frameGraph.engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n        this._postProcessDrawWrapper = this.postProcess.drawWrapper;\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphIblShadowsSpatialBlurTask\";\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public override initAsync(): Promise<unknown> {\r\n        if (this._frameGraph.engine.isWebGPU) {\r\n            return import(\"../../../../ShadersWGSL/iblShadowSpatialBlur.fragment\");\r\n        }\r\n\r\n        return import(\"../../../../Shaders/iblShadowSpatialBlur.fragment\");\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return this.postProcess.isReady();\r\n    }\r\n\r\n    public override record() {\r\n        if (this.sourceTexture === undefined || this.depthTexture === undefined || this.normalTexture === undefined) {\r\n            throw new Error(`FrameGraphIblShadowsSpatialBlurTask ${this.name}: sourceTexture, depthTexture and normalTexture are required`);\r\n        }\r\n\r\n        const textureManager = this._frameGraph.textureManager;\r\n        const size = textureManager.getTextureAbsoluteDimensions(this.sourceTexture);\r\n        const creationOptions: FrameGraphTextureCreationOptions = {\r\n            size,\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: false,\r\n            options: {\r\n                createMipMaps: false,\r\n                samples: 1,\r\n                types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                useSRGBBuffers: [false],\r\n                creationFlags: [0],\r\n                labels: [`${this.name} Output`],\r\n            },\r\n        };\r\n\r\n        textureManager.resolveDanglingHandle(this.outputTexture, undefined, `${this.name} Output`, creationOptions);\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.addDependencies(this.sourceTexture);\r\n        pass.addDependencies(this.depthTexture);\r\n        pass.addDependencies(this.normalTexture);\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            context.setTextureSamplingMode(this.sourceTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.depthTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.normalTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n\r\n            const iterationCount = 1;\r\n            this._blurParameters.set(iterationCount, this.voxelizationTask?.voxelGridSize ?? 1.0, 0.0, 0.0);\r\n\r\n            context.applyFullScreenEffect(\r\n                this._postProcessDrawWrapper,\r\n                () => {\r\n                    const effect = this._postProcessDrawWrapper.effect!;\r\n\r\n                    context.bindTextureHandle(effect, \"voxelTracingSampler\", this.sourceTexture!);\r\n                    context.bindTextureHandle(effect, \"depthSampler\", this.depthTexture!);\r\n                    context.bindTextureHandle(effect, \"worldNormalSampler\", this.normalTexture!);\r\n                    effect.setVector4(\"blurParameters\", this._blurParameters);\r\n\r\n                    this.postProcess.bind();\r\n                },\r\n                undefined,\r\n                false,\r\n                false,\r\n                true\r\n            );\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.postProcess.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","import { type Camera, type DrawWrapper, type FrameGraph, type FrameGraphTextureCreationOptions, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type FrameGraphIblShadowsVoxelizationTask } from \"./iblShadowsVoxelizationTask\";\r\nimport { Matrix, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ThinCustomPostProcess } from \"core/PostProcesses/thinCustomPostProcess\";\r\nimport { FrameGraphTask } from \"../../../frameGraphTask\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { type CubeTexture } from \"core/Materials/Textures/cubeTexture\";\r\n\r\n/**\r\n * Task used to trace IBL shadows from a voxel grid.\r\n * @internal\r\n */\r\nexport class FrameGraphIblShadowsTracingTask extends FrameGraphTask {\r\n    public camera?: Camera;\r\n    public voxelGridTexture?: FrameGraphTextureHandle;\r\n    public depthTexture?: FrameGraphTextureHandle;\r\n    public normalTexture?: FrameGraphTextureHandle;\r\n    public icdfTexture?: FrameGraphTextureHandle;\r\n    public environmentTexture?: FrameGraphTextureHandle;\r\n    public blueNoiseTexture?: FrameGraphTextureHandle;\r\n\r\n    private _sampleDirections = 2;\r\n\r\n    public get sampleDirections(): number {\r\n        return this._sampleDirections;\r\n    }\r\n\r\n    public set sampleDirections(value: number) {\r\n        this._sampleDirections = Math.max(1, Math.round(value));\r\n    }\r\n\r\n    public voxelShadowOpacity = 1;\r\n    public ssShadowOpacity = 1;\r\n\r\n    private _ssShadowSampleCount = 16;\r\n\r\n    public get ssShadowSampleCount(): number {\r\n        return this._ssShadowSampleCount;\r\n    }\r\n\r\n    public set ssShadowSampleCount(value: number) {\r\n        this._ssShadowSampleCount = Math.max(1, Math.round(value));\r\n    }\r\n\r\n    private _ssShadowStride = 8;\r\n\r\n    public get ssShadowStride(): number {\r\n        return this._ssShadowStride;\r\n    }\r\n\r\n    public set ssShadowStride(value: number) {\r\n        this._ssShadowStride = Math.max(1, Math.round(value));\r\n    }\r\n    /** Scale factor applied to voxelGridSize / 2^resolutionExp to get the max SSS ray distance. */\r\n    public ssShadowDistanceScale = 1.25;\r\n    /** Scale factor applied to voxelGridSize to get the SSS surface thickness. */\r\n    public ssShadowThicknessScale = 1.0;\r\n    /** Voxelization task providing dynamic voxelGridSize and resolutionExp for SSS parameter derivation. */\r\n    public voxelizationTask?: FrameGraphIblShadowsVoxelizationTask;\r\n    public envRotation = 0;\r\n    public voxelNormalBias = 1.4;\r\n    public voxelDirectionBias = 1.75;\r\n    public worldScaleMatrix = Matrix.Identity();\r\n\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    public readonly postProcess: ThinCustomPostProcess;\r\n    protected readonly _postProcessDrawWrapper: DrawWrapper;\r\n    protected readonly _shadowParameters = new Vector4(0, 0, 0, 0);\r\n    protected readonly _sssParameters = new Vector4(0, 0, 0, 0);\r\n    protected readonly _opacityParameters = new Vector4(0, 0, 0, 0);\r\n    protected readonly _voxelBiasParameters = new Vector4(0, 0, 0, 0);\r\n    protected readonly _cameraInvView = Matrix.Identity();\r\n    protected readonly _cameraInvProj = Matrix.Identity();\r\n    protected readonly _cameraInvViewProjection = Matrix.Identity();\r\n    protected _frameId = 0;\r\n    protected _coloredShadows = false;\r\n    protected _currentDefines = \"\";\r\n\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.postProcess = new ThinCustomPostProcess(name, frameGraph.engine, {\r\n            fragmentShader: \"iblShadowVoxelTracing\",\r\n            uniforms: [\r\n                \"viewMtx\",\r\n                \"projMtx\",\r\n                \"invProjMtx\",\r\n                \"invViewMtx\",\r\n                \"invVPMtx\",\r\n                \"wsNormalizationMtx\",\r\n                \"shadowParameters\",\r\n                \"voxelBiasParameters\",\r\n                \"sssParameters\",\r\n                \"shadowOpacity\",\r\n            ],\r\n            samplers: [\"depthSampler\", \"worldNormalSampler\", \"blueNoiseSampler\", \"icdfSampler\", \"voxelGridSampler\", \"iblSampler\"],\r\n            shaderLanguage: frameGraph.engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n        this._postProcessDrawWrapper = this.postProcess.drawWrapper;\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphIblShadowsTracingTask\";\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public override initAsync(): Promise<unknown> {\r\n        if (this._frameGraph.engine.isWebGPU) {\r\n            return import(\"../../../../ShadersWGSL/iblShadowVoxelTracing.fragment\");\r\n        }\r\n\r\n        return import(\"../../../../Shaders/iblShadowVoxelTracing.fragment\");\r\n    }\r\n\r\n    public get coloredShadows(): boolean {\r\n        return this._coloredShadows;\r\n    }\r\n\r\n    public set coloredShadows(value: boolean) {\r\n        if (this._coloredShadows === value) {\r\n            return;\r\n        }\r\n\r\n        this._coloredShadows = value;\r\n        this._updateDefines();\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return this.postProcess.isReady();\r\n    }\r\n\r\n    public override record() {\r\n        if (\r\n            this.camera === undefined ||\r\n            this.voxelGridTexture === undefined ||\r\n            this.depthTexture === undefined ||\r\n            this.normalTexture === undefined ||\r\n            this.icdfTexture === undefined\r\n        ) {\r\n            throw new Error(`FrameGraphIblShadowsTracingTask ${this.name}: camera, voxelGridTexture, depthTexture, normalTexture and icdfTexture are required`);\r\n        }\r\n\r\n        const textureManager = this._frameGraph.textureManager;\r\n        const size = textureManager.getTextureAbsoluteDimensions(this.depthTexture);\r\n        const creationOptions: FrameGraphTextureCreationOptions = {\r\n            size,\r\n            sizeIsPercentage: false,\r\n            isHistoryTexture: false,\r\n            options: {\r\n                createMipMaps: false,\r\n                samples: 1,\r\n                types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                useSRGBBuffers: [false],\r\n                creationFlags: [0],\r\n                labels: [`${this.name} Output`],\r\n            },\r\n        };\r\n\r\n        textureManager.resolveDanglingHandle(this.outputTexture, undefined, `${this.name} Output`, creationOptions);\r\n\r\n        this._updateDefines();\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        const dependencies: FrameGraphTextureHandle[] = [this.voxelGridTexture, this.depthTexture, this.normalTexture, this.icdfTexture];\r\n        if (this.environmentTexture !== undefined) {\r\n            dependencies.push(this.environmentTexture);\r\n        }\r\n        if (this.blueNoiseTexture !== undefined) {\r\n            dependencies.push(this.blueNoiseTexture);\r\n        }\r\n        pass.addDependencies(dependencies);\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            if (this.icdfTexture === undefined || this.blueNoiseTexture === undefined || (this.coloredShadows && this.environmentTexture === undefined)) {\r\n                context.clear(new Color4(1, 1, 1, 1), true, false, false);\r\n                return;\r\n            }\r\n\r\n            context.setTextureSamplingMode(this.depthTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.normalTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.icdfTexture!, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            context.setTextureSamplingMode(this.blueNoiseTexture, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n\r\n            const view = this.camera!.getViewMatrix();\r\n            const projection = this.camera!.getProjectionMatrix();\r\n            projection.invertToRef(this._cameraInvProj);\r\n            view.invertToRef(this._cameraInvView);\r\n            this.camera!.getTransformationMatrix().invertToRef(this._cameraInvViewProjection);\r\n\r\n            const voxelGridSize = textureManager.getTextureAbsoluteDimensions(this.voxelGridTexture!);\r\n            const highestMip = Math.floor(Math.log2(Math.max(1, voxelGridSize.width)));\r\n\r\n            this._frameId++;\r\n            let rotation = 0.0;\r\n            if (this.environmentTexture) {\r\n                rotation = (this._frameGraph.scene.environmentTexture as CubeTexture).rotationY ?? 0;\r\n            }\r\n            rotation = this._frameGraph.scene.useRightHandedSystem ? -(rotation + 0.5 * Math.PI) : rotation - 0.5 * Math.PI;\r\n            rotation = rotation % (2.0 * Math.PI);\r\n            this._shadowParameters.set(this.sampleDirections, this._frameId, 1.0, rotation);\r\n            this._voxelBiasParameters.set(this.voxelNormalBias, this.voxelDirectionBias, highestMip, 0.0);\r\n            const gridSize = this.voxelizationTask?.voxelGridSize ?? 1.0;\r\n            const resExp = this.voxelizationTask?.resolutionExp ?? 6;\r\n            const sssMaxDist = (this.ssShadowDistanceScale * gridSize) / (1 << resExp);\r\n            const sssThickness = this.ssShadowThicknessScale * 0.005 * gridSize;\r\n            this._sssParameters.set(this.ssShadowSampleCount, this.ssShadowStride, sssMaxDist, sssThickness);\r\n            this._opacityParameters.set(this.voxelShadowOpacity, this.ssShadowOpacity, 0.0, 0.0);\r\n\r\n            context.applyFullScreenEffect(\r\n                this._postProcessDrawWrapper,\r\n                () => {\r\n                    const effect = this._postProcessDrawWrapper.effect!;\r\n\r\n                    context.bindTextureHandle(effect, \"voxelGridSampler\", this.voxelGridTexture!);\r\n                    context.bindTextureHandle(effect, \"depthSampler\", this.depthTexture!);\r\n                    context.bindTextureHandle(effect, \"worldNormalSampler\", this.normalTexture!);\r\n                    context.bindTextureHandle(effect, \"icdfSampler\", this.icdfTexture!);\r\n                    context.bindTextureHandle(effect, \"blueNoiseSampler\", this.blueNoiseTexture!);\r\n                    if (this.coloredShadows && this.environmentTexture !== undefined) {\r\n                        context.bindTextureHandle(effect, \"iblSampler\", this.environmentTexture);\r\n                    }\r\n\r\n                    effect.setMatrix(\"viewMtx\", view);\r\n                    effect.setMatrix(\"projMtx\", projection);\r\n                    effect.setMatrix(\"invProjMtx\", this._cameraInvProj);\r\n                    effect.setMatrix(\"invViewMtx\", this._cameraInvView);\r\n                    effect.setMatrix(\"invVPMtx\", this._cameraInvViewProjection);\r\n                    effect.setMatrix(\"wsNormalizationMtx\", this.worldScaleMatrix);\r\n                    effect.setVector4(\"shadowParameters\", this._shadowParameters);\r\n                    effect.setVector4(\"voxelBiasParameters\", this._voxelBiasParameters);\r\n                    effect.setVector4(\"sssParameters\", this._sssParameters);\r\n                    effect.setVector4(\"shadowOpacity\", this._opacityParameters);\r\n\r\n                    this.postProcess.bind();\r\n                },\r\n                undefined,\r\n                false,\r\n                false,\r\n                true\r\n            );\r\n        });\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.postProcess.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    protected _updateDefines(): void {\r\n        const defines: string[] = [\"#define WORLD_NORMAL_UNSIGNED\"];\r\n\r\n        if (this._frameGraph.scene.useRightHandedSystem) {\r\n            defines.push(\"#define RIGHT_HANDED\");\r\n        }\r\n        if (this.coloredShadows) {\r\n            defines.push(\"#define COLOR_SHADOWS 1u\");\r\n        }\r\n\r\n        const defineString = defines.join(\"\\n\");\r\n        if (defineString !== this._currentDefines) {\r\n            this._currentDefines = defineString;\r\n            this.postProcess.updateEffect(this._currentDefines);\r\n        }\r\n    }\r\n}\r\n","import { Tools } from \"../../../Misc/tools.pure\";\r\nimport { type Scene } from \"../../../scene\";\r\nimport { type ISceneComponent, SceneComponentConstants } from \"../../../sceneComponent\";\r\n\r\n/**\r\n * Defines the Procedural Texture scene component responsible to manage any Procedural Texture\r\n * in a given scene.\r\n */\r\nexport class ProceduralTextureSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_PROCEDURALTEXTURE;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._beforeClearStage.registerStep(SceneComponentConstants.STEP_BEFORECLEAR_PROCEDURALTEXTURE, this, this._beforeClear);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do here.\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        // Nothing to do here.\r\n    }\r\n\r\n    private _beforeClear(): void {\r\n        if (this.scene.proceduralTexturesEnabled) {\r\n            Tools.StartPerformanceCounter(\"Procedural textures\", this.scene.proceduralTextures.length > 0);\r\n            for (let proceduralIndex = 0; proceduralIndex < this.scene.proceduralTextures.length; proceduralIndex++) {\r\n                const proceduralTexture = this.scene.proceduralTextures[proceduralIndex];\r\n                if (proceduralTexture._shouldRender()) {\r\n                    proceduralTexture.render();\r\n                }\r\n            }\r\n            Tools.EndPerformanceCounter(\"Procedural textures\", this.scene.proceduralTextures.length > 0);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../../../Misc/decorators\";\r\nimport { Observable } from \"../../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { type IColor3Like, type IColor4Like, type IMatrixLike, type IVector2Like, type IVector3Like, type IVector4Like } from \"../../../Maths/math.like\";\r\nimport { type AbstractEngine } from \"../../../Engines/abstractEngine.pure\";\r\nimport { VertexBuffer } from \"../../../Buffers/buffer.pure\";\r\nimport { SceneComponentConstants } from \"../../../sceneComponent\";\r\n\r\nimport { Material } from \"../../../Materials/material.pure\";\r\nimport { type Effect } from \"../../../Materials/effect.pure\";\r\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\r\nimport { type RenderTargetTextureOptions, RenderTargetTexture } from \"../../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { ProceduralTextureSceneComponent } from \"./proceduralTextureSceneComponent\";\r\n\r\nimport { type DataBuffer } from \"../../../Buffers/dataBuffer\";\r\nimport { type NodeMaterial } from \"../../Node/nodeMaterial.pure\";\r\nimport { type TextureSize } from \"../../../Materials/Textures/textureCreationOptions\";\r\nimport { EngineStore } from \"../../../Engines/engineStore\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { DrawWrapper } from \"../../drawWrapper\";\r\nimport { type RenderTargetWrapper } from \"../../../Engines/renderTargetWrapper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type ThinTexture } from \"core/Materials/Textures/thinTexture\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Options to create a procedural texture\r\n */\r\nexport interface IProceduralTextureCreationOptions extends RenderTargetTextureOptions {\r\n    /**\r\n     * Defines a fallback texture in case there were issues to create the custom texture\r\n     */\r\n    fallbackTexture?: Nullable<Texture>;\r\n    /**\r\n     * The shader language of the shader. (default: GLSL)\r\n     */\r\n    shaderLanguage?: ShaderLanguage;\r\n    /**\r\n     * Additional async code to run before preparing the effect\r\n     */\r\n    extraInitializationsAsync?: () => Promise<void>;\r\n    /**\r\n     * When true the texture will not be pushed onto scene.proceduralTextures and will\r\n     * therefore never be rendered automatically by the scene render loop. Use this for\r\n     * one-shot or manually-driven textures that manage their own render lifecycle.\r\n     */\r\n    skipSceneRegistration?: boolean;\r\n}\r\n\r\n/**\r\n * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes calmpler' images.\r\n * This is the base class of any Procedural texture and contains most of the shareable code.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/proceduralTextures\r\n */\r\nexport class ProceduralTexture extends Texture {\r\n    /**\r\n     * Define if the texture is enabled or not (disabled texture will not render)\r\n     */\r\n    @serialize()\r\n    public isEnabled = true;\r\n\r\n    /**\r\n     * Define if the texture must be cleared before rendering (default is true)\r\n     */\r\n    @serialize()\r\n    public autoClear = true;\r\n\r\n    /**\r\n     * Callback called when the texture is generated\r\n     */\r\n    public onGenerated: () => void;\r\n\r\n    /**\r\n     * Event raised when the texture is generated\r\n     */\r\n    public onGeneratedObservable = new Observable<ProceduralTexture>();\r\n\r\n    /**\r\n     * Event raised before the texture is generated\r\n     */\r\n    public onBeforeGenerationObservable = new Observable<ProceduralTexture>();\r\n\r\n    /**\r\n     * Gets or sets the node material used to create this texture (null if the texture was manually created)\r\n     */\r\n    public nodeMaterialSource: Nullable<NodeMaterial> = null;\r\n\r\n    /**\r\n     * Define the list of custom preprocessor defines used in the shader\r\n     */\r\n    public defines: string = \"\";\r\n\r\n    /** @internal */\r\n    @serialize()\r\n    public _generateMipMaps: boolean;\r\n\r\n    private _drawWrapper: DrawWrapper;\r\n\r\n    /** @internal */\r\n    public _textures: { [key: string]: ThinTexture } = {};\r\n\r\n    /** @internal */\r\n    protected _fallbackTexture: Nullable<Texture>;\r\n\r\n    /** @internal */\r\n    private _shaderLanguage: ShaderLanguage;\r\n\r\n    /**\r\n     * Gets the shader language type used to generate vertex and fragment source code.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    @serialize()\r\n    private _size: TextureSize;\r\n    private _textureType: number;\r\n    private _currentRefreshId = -1;\r\n    private _frameId = -1;\r\n    private _refreshRate = 1;\r\n    private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _uniforms = new Array<string>();\r\n    private _samplers = new Array<string>();\r\n    private _fragment: any;\r\n\r\n    private _floats: { [key: string]: number } = {};\r\n    private _ints: { [key: string]: number } = {};\r\n    private _floatsArrays: { [key: string]: number[] } = {};\r\n    private _colors3: { [key: string]: IColor3Like } = {};\r\n    private _colors4: { [key: string]: IColor4Like } = {};\r\n    private _vectors2: { [key: string]: IVector2Like } = {};\r\n    private _vectors3: { [key: string]: IVector3Like } = {};\r\n    private _vectors4: { [key: string]: IVector4Like } = {};\r\n    private _matrices: { [key: string]: IMatrixLike } = {};\r\n\r\n    private _fallbackTextureUsed = false;\r\n    private _fullEngine: AbstractEngine;\r\n\r\n    private _cachedDefines: Nullable<string> = null;\r\n\r\n    private _contentUpdateId = -1;\r\n    private _contentData: Nullable<Promise<ArrayBufferView>>;\r\n\r\n    private _rtWrapper: Nullable<RenderTargetWrapper> = null;\r\n    private _options: IProceduralTextureCreationOptions;\r\n\r\n    /**\r\n     * Instantiates a new procedural texture.\r\n     * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes called 'refMaps' or 'sampler' images.\r\n     * This is the base class of any Procedural texture and contains most of the shareable code.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/proceduralTextures\r\n     * @param name  Define the name of the texture\r\n     * @param size Define the size of the texture to create\r\n     * @param fragment Define the fragment shader to use to generate the texture or null if it is defined later:\r\n     *  * object: \\{ fragmentElement: \"fragmentShaderCode\" \\}, used with shader code in script tags\r\n     *  * object: \\{ fragmentSource: \"fragment shader code string\" \\}, the string contains the shader code\r\n     *  * string: the string contains a name \"XXX\" to lookup in Effect.ShadersStore[\"XXXFragmentShader\"]\r\n     * @param scene Define the scene the texture belongs to\r\n     * @param fallbackTexture Define a fallback texture in case there were issues to create the custom texture\r\n     * @param generateMipMaps Define if the texture should creates mip maps or not\r\n     * @param isCube Define if the texture is a cube texture or not (this will render each faces of the cube)\r\n     * @param textureType The FBO internal texture type\r\n     */\r\n    constructor(\r\n        name: string,\r\n        size: TextureSize,\r\n        fragment: any,\r\n        scene: Nullable<Scene>,\r\n        fallbackTexture: Nullable<Texture> | IProceduralTextureCreationOptions = null,\r\n        generateMipMaps = true,\r\n        isCube = false,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        super(null, scene, !generateMipMaps);\r\n\r\n        if (fallbackTexture !== null && !(fallbackTexture instanceof Texture)) {\r\n            this._options = fallbackTexture;\r\n            this._fallbackTexture = fallbackTexture.fallbackTexture ?? null;\r\n        } else {\r\n            this._options = {};\r\n            this._fallbackTexture = fallbackTexture;\r\n        }\r\n\r\n        this._shaderLanguage = this._options.shaderLanguage ?? ShaderLanguage.GLSL;\r\n\r\n        scene = this.getScene() || EngineStore.LastCreatedScene!;\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_PROCEDURALTEXTURE);\r\n        if (!component) {\r\n            component = new ProceduralTextureSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n        if (!this._options.skipSceneRegistration) {\r\n            scene.proceduralTextures.push(this);\r\n        }\r\n\r\n        this._fullEngine = scene.getEngine();\r\n\r\n        this.name = name;\r\n        this.isRenderTarget = true;\r\n        this._size = size;\r\n        this._textureType = textureType;\r\n        this._generateMipMaps = generateMipMaps;\r\n        this._drawWrapper = new DrawWrapper(this._fullEngine);\r\n\r\n        this.setFragment(fragment);\r\n\r\n        const rtWrapper = this._createRtWrapper(isCube, size, generateMipMaps, textureType);\r\n        this._texture = rtWrapper.texture;\r\n\r\n        // VBO\r\n        const vertices = [];\r\n        vertices.push(1, 1);\r\n        vertices.push(-1, 1);\r\n        vertices.push(-1, -1);\r\n        vertices.push(1, -1);\r\n\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._fullEngine, vertices, VertexBuffer.PositionKind, false, false, 2);\r\n\r\n        this._createIndexBuffer();\r\n    }\r\n\r\n    private _createRtWrapper(isCube: boolean, size: TextureSize, generateMipMaps: boolean, textureType: number) {\r\n        if (isCube) {\r\n            this._rtWrapper = this._fullEngine.createRenderTargetCubeTexture(size as number, {\r\n                generateMipMaps: generateMipMaps,\r\n                generateDepthBuffer: false,\r\n                generateStencilBuffer: false,\r\n                type: textureType,\r\n                ...this._options,\r\n            });\r\n            this.setFloat(\"face\", 0);\r\n        } else {\r\n            this._rtWrapper = this._fullEngine.createRenderTargetTexture(size, {\r\n                generateMipMaps: generateMipMaps,\r\n                generateDepthBuffer: false,\r\n                generateStencilBuffer: false,\r\n                type: textureType,\r\n                ...this._options,\r\n            });\r\n            if (this._rtWrapper.is3D) {\r\n                this.setFloat(\"layer\", 0);\r\n                this.setInt(\"layerNum\", 0);\r\n            }\r\n        }\r\n        return this._rtWrapper;\r\n    }\r\n\r\n    /**\r\n     * The effect that is created when initializing the post process.\r\n     * @returns The created effect corresponding the postprocess.\r\n     */\r\n    public getEffect(): Effect {\r\n        return this._drawWrapper.effect!;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setEffect(effect: Effect) {\r\n        this._drawWrapper.effect = effect;\r\n    }\r\n\r\n    /**\r\n     * Gets texture content (Use this function wisely as reading from a texture can be slow)\r\n     * @returns an ArrayBufferView promise (Uint8Array or Float32Array)\r\n     */\r\n    public getContent(): Nullable<Promise<ArrayBufferView>> {\r\n        if (this._contentData && this._frameId === this._contentUpdateId) {\r\n            return this._contentData;\r\n        }\r\n\r\n        if (this._contentData) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            this._contentData.then((buffer) => {\r\n                this._contentData = this.readPixels(0, 0, buffer);\r\n                this._contentUpdateId = this._frameId;\r\n            });\r\n        } else {\r\n            this._contentData = this.readPixels(0, 0);\r\n            this._contentUpdateId = this._frameId;\r\n        }\r\n\r\n        return this._contentData;\r\n    }\r\n\r\n    private _createIndexBuffer(): void {\r\n        const engine = this._fullEngine;\r\n\r\n        // Indices\r\n        const indices = [];\r\n        indices.push(0);\r\n        indices.push(1);\r\n        indices.push(2);\r\n\r\n        indices.push(0);\r\n        indices.push(2);\r\n        indices.push(3);\r\n\r\n        this._indexBuffer = engine.createIndexBuffer(indices);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _rebuild(): void {\r\n        const vb = this._vertexBuffers[VertexBuffer.PositionKind];\r\n\r\n        if (vb) {\r\n            vb._rebuild();\r\n        }\r\n\r\n        this._createIndexBuffer();\r\n\r\n        if (this.refreshRate === RenderTargetTexture.REFRESHRATE_RENDER_ONCE) {\r\n            this.refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the texture in order to recreate its associated resources.\r\n     * This can be called in case of context loss or if you change the shader code and need to regenerate the texture with the new code\r\n     */\r\n    public reset(): void {\r\n        this._drawWrapper.effect?.dispose();\r\n        this._drawWrapper.effect = null;\r\n        this._cachedDefines = null;\r\n    }\r\n\r\n    protected _getDefines(): string {\r\n        return this.defines;\r\n    }\r\n\r\n    /**\r\n     * Executes a function when the texture will be ready to be drawn.\r\n     * @param func The callback to be used.\r\n     */\r\n    public executeWhenReady(func: (texture: ProceduralTexture) => void): void {\r\n        if (this.isReady()) {\r\n            func(this);\r\n            return;\r\n        }\r\n\r\n        const effect = this.getEffect();\r\n        if (effect) {\r\n            effect.executeWhenCompiled(() => {\r\n                func(this);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Is the texture ready to be used ? (rendered at least once)\r\n     * @returns true if ready, otherwise, false.\r\n     */\r\n    public override isReady(): boolean {\r\n        const engine = this._fullEngine;\r\n\r\n        if (this.nodeMaterialSource) {\r\n            // When sourced from a node material, the effect is created asynchronously once the material\r\n            // build completes (some node material blocks load their shader code asynchronously). Until\r\n            // then there is no effect yet, so the texture is simply not ready.\r\n            return this._drawWrapper.effect?.isReady() ?? false;\r\n        }\r\n\r\n        if (!this._fragment) {\r\n            return false;\r\n        }\r\n\r\n        if (this._fallbackTextureUsed) {\r\n            return true;\r\n        }\r\n\r\n        if (!this._texture) {\r\n            return false;\r\n        }\r\n\r\n        const defines = this._getDefines();\r\n        if (this._drawWrapper.effect && defines === this._cachedDefines && this._drawWrapper.effect.isReady()) {\r\n            return true;\r\n        }\r\n\r\n        const shaders = {\r\n            vertex: \"procedural\",\r\n            fragmentElement: this._fragment.fragmentElement,\r\n            fragmentSource: this._fragment.fragmentSource,\r\n            fragment: typeof this._fragment === \"string\" ? this._fragment : undefined,\r\n        };\r\n\r\n        if (this._cachedDefines !== defines) {\r\n            this._cachedDefines = defines;\r\n\r\n            this._drawWrapper.effect = engine.createEffect(\r\n                shaders,\r\n                [VertexBuffer.PositionKind],\r\n                this._uniforms,\r\n                this._samplers,\r\n                defines,\r\n                undefined,\r\n                undefined,\r\n                () => {\r\n                    this._rtWrapper?.dispose();\r\n                    this._rtWrapper = this._texture = null;\r\n\r\n                    if (this._fallbackTexture) {\r\n                        this._texture = this._fallbackTexture._texture;\r\n\r\n                        if (this._texture) {\r\n                            this._texture.incrementReferences();\r\n                        }\r\n                    }\r\n\r\n                    this._fallbackTextureUsed = true;\r\n                },\r\n                undefined,\r\n                this._shaderLanguage,\r\n                async () => {\r\n                    if (this._options.extraInitializationsAsync) {\r\n                        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                            await Promise.all([import(\"../../../ShadersWGSL/procedural.vertex\"), this._options.extraInitializationsAsync()]);\r\n                        } else {\r\n                            await Promise.all([import(\"../../../Shaders/procedural.vertex\"), this._options.extraInitializationsAsync()]);\r\n                        }\r\n                    } else {\r\n                        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                            await import(\"../../../ShadersWGSL/procedural.vertex\");\r\n                        } else {\r\n                            await import(\"../../../Shaders/procedural.vertex\");\r\n                        }\r\n                    }\r\n                }\r\n            );\r\n        }\r\n\r\n        return this._drawWrapper.effect!.isReady();\r\n    }\r\n\r\n    /**\r\n     * Resets the refresh counter of the texture and start bak from scratch.\r\n     * Could be useful to regenerate the texture if it is setup to render only once.\r\n     */\r\n    public resetRefreshCounter(): void {\r\n        this._currentRefreshId = -1;\r\n    }\r\n\r\n    /**\r\n     * Set the fragment shader to use in order to render the texture.\r\n     * @param fragment This can be set to a path (into the shader store) or to a json object containing a fragmentElement property.\r\n     */\r\n    public setFragment(fragment: any) {\r\n        this._fragment = fragment;\r\n    }\r\n\r\n    /**\r\n     * Define the refresh rate of the texture or the rendering frequency.\r\n     * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...\r\n     */\r\n    @serialize()\r\n    public get refreshRate(): number {\r\n        return this._refreshRate;\r\n    }\r\n\r\n    public set refreshRate(value: number) {\r\n        this._refreshRate = value;\r\n        this.resetRefreshCounter();\r\n    }\r\n\r\n    /** @internal */\r\n    public _shouldRender(): boolean {\r\n        if (!this.isEnabled || !this.isReady() || !this._texture) {\r\n            if (this._texture) {\r\n                this._texture.isReady = false;\r\n            }\r\n            return false;\r\n        }\r\n\r\n        if (this._fallbackTextureUsed) {\r\n            return false;\r\n        }\r\n\r\n        if (this._currentRefreshId === -1) {\r\n            // At least render once\r\n            this._currentRefreshId = 1;\r\n            this._frameId++;\r\n            return true;\r\n        }\r\n\r\n        if (this.refreshRate === this._currentRefreshId) {\r\n            this._currentRefreshId = 1;\r\n            this._frameId++;\r\n            return true;\r\n        }\r\n\r\n        this._currentRefreshId++;\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Get the size the texture is rendering at.\r\n     * @returns the size (on cube texture it is always squared)\r\n     */\r\n    public getRenderSize(): TextureSize {\r\n        return this._size;\r\n    }\r\n\r\n    /**\r\n     * Resize the texture to new value.\r\n     * @param size Define the new size the texture should have\r\n     * @param generateMipMaps Define whether the new texture should create mip maps\r\n     */\r\n    public resize(size: TextureSize, generateMipMaps: boolean): void {\r\n        if (this._fallbackTextureUsed || !this._rtWrapper || !this._texture) {\r\n            return;\r\n        }\r\n\r\n        const isCube = this._texture.isCube;\r\n        this._rtWrapper.dispose();\r\n\r\n        const rtWrapper = this._createRtWrapper(isCube, size, generateMipMaps, this._textureType);\r\n        this._texture = rtWrapper.texture;\r\n\r\n        // Update properties\r\n        this._size = size;\r\n        this._generateMipMaps = generateMipMaps;\r\n    }\r\n\r\n    private _checkUniform(uniformName: string): void {\r\n        if (this._uniforms.indexOf(uniformName) === -1) {\r\n            this._uniforms.push(uniformName);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set a texture in the shader program used to render.\r\n     * @param name Define the name of the uniform samplers as defined in the shader\r\n     * @param texture Define the texture to bind to this sampler\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setTexture(name: string, texture: ThinTexture): ProceduralTexture {\r\n        if (this._samplers.indexOf(name) === -1) {\r\n            this._samplers.push(name);\r\n        }\r\n        this._textures[name] = texture;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a float in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setFloat(name: string, value: number): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._floats[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a int in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setInt(name: string, value: number): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._ints[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set an array of floats in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setFloats(name: string, value: number[]): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._floatsArrays[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a vec3 in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setColor3(name: string, value: IColor3Like): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._colors3[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a vec4 in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setColor4(name: string, value: IColor4Like): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._colors4[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a vec2 in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setVector2(name: string, value: IVector2Like): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._vectors2[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a vec3 in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setVector3(name: string, value: IVector3Like): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._vectors3[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a vec4 in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setVector4(name: string, value: IVector4Like): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._vectors4[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set a mat4 in the shader.\r\n     * @param name Define the name of the uniform as defined in the shader\r\n     * @param value Define the value to give to the uniform\r\n     * @returns the texture itself allowing \"fluent\" like uniform updates\r\n     */\r\n    public setMatrix(name: string, value: IMatrixLike): ProceduralTexture {\r\n        this._checkUniform(name);\r\n        this._matrices[name] = value;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Render the texture to its associated render target.\r\n     * @param useCameraPostProcess Define if camera post process should be applied to the texture\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public render(useCameraPostProcess?: boolean): void {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._fullEngine;\r\n\r\n        // Render\r\n        engine.enableEffect(this._drawWrapper);\r\n        this.onBeforeGenerationObservable.notifyObservers(this);\r\n        engine.setState(false);\r\n\r\n        if (!this.nodeMaterialSource) {\r\n            // Texture\r\n            for (const name in this._textures) {\r\n                this._drawWrapper.effect!.setTexture(name, this._textures[name]);\r\n            }\r\n\r\n            // Float\r\n            for (const name in this._ints) {\r\n                this._drawWrapper.effect!.setInt(name, this._ints[name]);\r\n            }\r\n\r\n            // Float\r\n            for (const name in this._floats) {\r\n                this._drawWrapper.effect!.setFloat(name, this._floats[name]);\r\n            }\r\n\r\n            // Floats\r\n            for (const name in this._floatsArrays) {\r\n                this._drawWrapper.effect!.setArray(name, this._floatsArrays[name]);\r\n            }\r\n\r\n            // Color3\r\n            for (const name in this._colors3) {\r\n                this._drawWrapper.effect!.setColor3(name, this._colors3[name]);\r\n            }\r\n\r\n            // Color4\r\n            for (const name in this._colors4) {\r\n                const color = this._colors4[name];\r\n                this._drawWrapper.effect!.setFloat4(name, color.r, color.g, color.b, color.a);\r\n            }\r\n\r\n            // Vector2\r\n            for (const name in this._vectors2) {\r\n                this._drawWrapper.effect!.setVector2(name, this._vectors2[name]);\r\n            }\r\n\r\n            // Vector3\r\n            for (const name in this._vectors3) {\r\n                this._drawWrapper.effect!.setVector3(name, this._vectors3[name]);\r\n            }\r\n\r\n            // Vector4\r\n            for (const name in this._vectors4) {\r\n                this._drawWrapper.effect!.setVector4(name, this._vectors4[name]);\r\n            }\r\n\r\n            // Matrix\r\n            for (const name in this._matrices) {\r\n                this._drawWrapper.effect!.setMatrix(name, this._matrices[name]);\r\n            }\r\n        }\r\n\r\n        if (!this._texture || !this._rtWrapper) {\r\n            return;\r\n        }\r\n\r\n        if (engine._enableGPUDebugMarkers) {\r\n            engine._debugPushGroup?.(`procedural texture generation for ${this.name}`);\r\n        }\r\n\r\n        const viewPort = engine.currentViewport;\r\n        if (this.isCube) {\r\n            for (let face = 0; face < 6; face++) {\r\n                engine.bindFramebuffer(this._rtWrapper, face, undefined, undefined, true);\r\n\r\n                // VBOs\r\n                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._drawWrapper.effect!);\r\n\r\n                this._drawWrapper.effect!.setFloat(\"face\", face);\r\n\r\n                // Clear\r\n                if (this.autoClear) {\r\n                    engine.clear(scene.clearColor, true, false, false);\r\n                }\r\n\r\n                // Draw order\r\n                engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n                // Unbind and restore viewport\r\n                engine.unBindFramebuffer(this._rtWrapper, true);\r\n            }\r\n        } else {\r\n            let numLayers = 1;\r\n            if (this._rtWrapper.is3D) {\r\n                numLayers = this._rtWrapper.depth;\r\n            } else if (this._rtWrapper.is2DArray) {\r\n                numLayers = this._rtWrapper.layers;\r\n            }\r\n            for (let layer = 0; layer < numLayers; layer++) {\r\n                engine.bindFramebuffer(this._rtWrapper, 0, undefined, undefined, true, 0, layer);\r\n\r\n                // VBOs\r\n                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._drawWrapper.effect!);\r\n\r\n                if (this._rtWrapper.is3D || this._rtWrapper.is2DArray) {\r\n                    this._drawWrapper.effect?.setFloat(\"layer\", numLayers !== 1 ? layer / (numLayers - 1) : 0);\r\n                    this._drawWrapper.effect?.setInt(\"layerNum\", layer);\r\n                    for (const name in this._textures) {\r\n                        this._drawWrapper.effect!.setTexture(name, this._textures[name]);\r\n                    }\r\n                }\r\n\r\n                // Clear\r\n                if (this.autoClear) {\r\n                    engine.clear(scene.clearColor, true, false, false);\r\n                }\r\n\r\n                // Draw order\r\n                engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n                // Unbind and restore viewport\r\n                engine.unBindFramebuffer(this._rtWrapper, !this._generateMipMaps);\r\n            }\r\n        }\r\n\r\n        if (viewPort) {\r\n            engine.setViewport(viewPort);\r\n        }\r\n\r\n        // Mipmaps\r\n        if (this.isCube) {\r\n            engine.generateMipMapsForCubemap(this._texture, true);\r\n        }\r\n\r\n        if (engine._enableGPUDebugMarkers) {\r\n            engine._debugPopGroup?.();\r\n        }\r\n\r\n        if (this.onGenerated) {\r\n            this.onGenerated();\r\n        }\r\n\r\n        this.onGeneratedObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Clone the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): ProceduralTexture {\r\n        const textureSize = this.getSize();\r\n        const newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, <Scene>this.getScene(), this._fallbackTexture, this._generateMipMaps);\r\n\r\n        // Base texture\r\n        newTexture.hasAlpha = this.hasAlpha;\r\n        newTexture.level = this.level;\r\n\r\n        // RenderTarget Texture\r\n        newTexture.coordinatesMode = this.coordinatesMode;\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        const index = scene.proceduralTextures.indexOf(this);\r\n\r\n        if (index >= 0) {\r\n            scene.proceduralTextures.splice(index, 1);\r\n        }\r\n\r\n        const vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (vertexBuffer) {\r\n            vertexBuffer.dispose();\r\n            this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n\r\n        if (this._indexBuffer && this._fullEngine._releaseBuffer(this._indexBuffer)) {\r\n            this._indexBuffer = null;\r\n        }\r\n\r\n        this.onGeneratedObservable.clear();\r\n        this.onBeforeGenerationObservable.clear();\r\n\r\n        super.dispose();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for proceduralTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterProceduralTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ProceduralTexture\", ProceduralTexture);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { Constants } from \"../../Engines/constants\";\nimport { type Engine } from \"../../Engines/engine.pure\";\nimport { ShaderMaterial } from \"../../Materials/shaderMaterial.pure\";\nimport { MultiRenderTarget } from \"../../Materials/Textures/multiRenderTarget.pure\";\nimport { RenderTargetTexture, type RenderTargetTextureOptions } from \"../../Materials/Textures/renderTargetTexture.pure\";\nimport { type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\nimport { Color4 } from \"../../Maths/math.color.pure\";\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\nimport { type Scene } from \"../../scene.pure\";\nimport { type SmartArray } from \"../../Misc/smartArray\";\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\nimport { Logger } from \"../../Misc/logger\";\nimport { Observable } from \"../../Misc/observable.pure\";\nimport { ProceduralTexture, type IProceduralTextureCreationOptions } from \"../../Materials/Textures/Procedurals/proceduralTexture.pure\";\nimport { EffectRenderer, EffectWrapper } from \"../../Materials/effectRenderer.pure\";\nimport { StorageBuffer } from \"../../Buffers/storageBuffer\";\nimport { ComputeShader } from \"../../Compute/computeShader.pure\";\nimport { type WebGPUEngine } from \"../../Engines/webgpuEngine.pure\";\nimport { type IblShadowsRenderPipeline } from \"./iblShadowsRenderPipeline.pure\";\nimport { type RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { type GaussianSplattingMesh } from \"../../Meshes/GaussianSplatting/gaussianSplattingMesh.pure\";\nimport { _IsGaussianSplattingMesh } from \"../../Meshes/GaussianSplatting/gaussianSplatting.functions\";\nimport { type GaussianSplattingMaterial } from \"../../Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\n\n// Max frames _renderVoxelGrid waits for splat depth sorts to settle before voxelizing anyway\n// (~3s at 60fps). Bounds the wait so a continuously re-sorting (orbiting) splat can't block it.\nconst _MaxSortSettleWaitFrames = 180;\n\n/**\n * Returns true if any of the given meshes (or their children) is a Gaussian splatting mesh.\n * Used to decide whether WebGPU voxelization needs the opacity accumulator buffer + copy pass.\n * @param meshes meshes included in the voxelization\n * @returns whether any included mesh (or child) is a Gaussian splatting mesh\n */\nfunction _HasGaussianSplatting(meshes: Mesh[]): boolean {\n    for (const mesh of meshes) {\n        if (!mesh) {\n            continue;\n        }\n        if (_IsGaussianSplattingMesh(mesh)) {\n            return true;\n        }\n        for (const child of mesh.getChildMeshes()) {\n            if (_IsGaussianSplattingMesh(child)) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n/**\n * Voxel-based shadow rendering for IBL's.\n * This should not be instanciated directly, as it is part of a scene component\n * @internal\n * @see https://playground.babylonjs.com/#8R5SSE#222\n */\nexport class _IblShadowsVoxelRenderer {\n    // View matrices for the three voxelization axes.\n    private static readonly _VOXEL_VIEW_MATRICES = [\n        Matrix.LookAtLH(Vector3.Zero(), new Vector3(1, 0, 0), Vector3.Up()),\n        Matrix.LookAtLH(Vector3.Zero(), new Vector3(0, 1, 0), new Vector3(1, 0, 0)),\n        Matrix.LookAtLH(Vector3.Zero(), new Vector3(0, 0, 1), Vector3.Up()),\n    ];\n\n    private _scene: Scene;\n    private _engine: Engine;\n\n    // WebGPU, single-pass voxelization.\n    // See https://playground.babylonjs.com/#XSNYAU#133\n    private _voxelGrid: RenderTargetTexture;\n    private _voxelGridRT: RenderTargetTexture;\n\n    // WebGL voxelization, including tri-planar voxelization.\n    private _combinedVoxelGridPT: ProceduralTexture;\n    private _voxelGridXaxis: RenderTargetTexture;\n    private _voxelGridYaxis: RenderTargetTexture;\n    private _voxelGridZaxis: RenderTargetTexture;\n    private _voxelMrtsXaxis: MultiRenderTarget[] = [];\n    private _voxelMrtsYaxis: MultiRenderTarget[] = [];\n    private _voxelMrtsZaxis: MultiRenderTarget[] = [];\n\n    private _voxelMaterial: ShaderMaterial;\n\n    // WebGPU only: per-voxel opacity accumulator (atomicMax during voxelization, copied to the r8 grid\n    // mip 0 by _copyBufferToGridCompute). Used only when Gaussian splats are present; regular-mesh-only\n    // voxelization writes the grid directly and skips it.\n    private _voxelOpacityBuffer?: StorageBuffer;\n    private _copyBufferToGridCompute?: ComputeShader;\n    private _useOpacityBuffer = false;\n    private _voxelClearColor: Color4 = new Color4(0, 0, 0, 1);\n\n    /**\n     * Return the voxel grid texture.\n     * @returns The voxel grid texture.\n     */\n    public getVoxelGrid(): ProceduralTexture | RenderTargetTexture {\n        if (this._engine.isWebGPU) {\n            return this._voxelGrid;\n        } else if (this._triPlanarVoxelization) {\n            return this._combinedVoxelGridPT;\n        } else {\n            return this._voxelGridZaxis;\n        }\n    }\n\n    /**\n     * Return the voxel render target used during voxelization.\n     * @returns The voxel render target.\n     */\n    public getRT(): ProceduralTexture | RenderTargetTexture {\n        if (this._engine.isWebGPU) {\n            return this._voxelGridRT;\n        } else if (this._triPlanarVoxelization) {\n            return this._combinedVoxelGridPT;\n        } else {\n            return this._voxelGridZaxis;\n        }\n    }\n\n    /**\n     * Observable that triggers when the voxelization is complete\n     */\n    public onVoxelizationCompleteObservable: Observable<void> = new Observable<void>();\n\n    private _maxDrawBuffers: number;\n    private _renderTargets: RenderTargetTexture[] = [];\n\n    /** Per-mesh voxel ShaderMaterials for GaussianSplattingMesh, keyed by mesh uniqueId. */\n    private _gsVoxelMaterialCache: Map<number, ShaderMaterial> = new Map();\n\n    private _triPlanarVoxelization: boolean = true;\n\n    /**\n     * Whether to use tri-planar voxelization. More expensive, but can help with artifacts.\n     */\n    public get triPlanarVoxelization(): boolean {\n        return this._triPlanarVoxelization;\n    }\n\n    /**\n     * Whether to use tri-planar voxelization. More expensive, but can help with artifacts.\n     */\n    public set triPlanarVoxelization(enabled: boolean) {\n        if (this._engine.isWebGPU) {\n            // WebGPU only supports tri-planar voxelization.\n            this._triPlanarVoxelization = true;\n            return;\n        }\n        if (this._triPlanarVoxelization === enabled) {\n            return;\n        }\n        this._disposeVoxelTextures();\n        this._triPlanarVoxelization = enabled;\n        this._createTextures();\n    }\n\n    private _voxelizationInProgress: boolean = false;\n    // Frames spent waiting for shadow-casting splats' depth sort to settle before voxelizing; see\n    // _renderVoxelGrid. Capped so a continuously re-sorting (e.g. orbiting) splat can't starve it.\n    private _sortSettleWaitFrames: number = 0;\n    private _invWorldScaleMatrix: Matrix = Matrix.Identity();\n\n    /**\n     * Set the matrix to use for scaling the world space to voxel space\n     * @param matrix The matrix to use for scaling the world space to voxel space\n     */\n    public setWorldScaleMatrix(matrix: Matrix) {\n        this._invWorldScaleMatrix = matrix;\n    }\n\n    /**\n     * @returns Whether voxelization is currently happening.\n     */\n    public isVoxelizationInProgress(): boolean {\n        return this._voxelizationInProgress;\n    }\n\n    private _voxelResolution: number = 64;\n    private _voxelResolutionExp: number = 6;\n\n    /**\n     * Resolution of the voxel grid. The final resolution will be 2^resolutionExp.\n     */\n    public get voxelResolutionExp(): number {\n        return this._voxelResolutionExp;\n    }\n\n    /**\n     * Resolution of the voxel grid. The final resolution will be 2^resolutionExp.\n     */\n    public set voxelResolutionExp(resolutionExp: number) {\n        if (this._voxelResolutionExp === resolutionExp && this._voxelGridZaxis) {\n            return;\n        }\n        this._voxelResolutionExp = Math.round(Math.min(Math.max(resolutionExp, 3), 9));\n        this._voxelResolution = Math.pow(2.0, this._voxelResolutionExp);\n        this._disposeVoxelTextures();\n        this._createTextures();\n    }\n\n    private _copyMipEffectRenderer: EffectRenderer;\n    private _copyMipEffectWrapper: EffectWrapper;\n    private _copyMipSourceTexture?: ProceduralTexture;\n    private _copyMipLayer = 0;\n    private _mipArray: ProceduralTexture[] = [];\n\n    /**\n     * Instanciates the voxel renderer\n     * @param scene Scene to attach to\n     * @param iblShadowsRenderPipeline The render pipeline this pass is associated with\n     * @param resolutionExp Resolution of the voxel grid. The final resolution will be 2^resolutionExp.\n     * @param triPlanarVoxelization Whether to use tri-planar voxelization. Only applies to WebGL. Voxelization will take longer but will reduce missing geometry.\n     * @returns The voxel renderer\n     */\n    constructor(scene: Scene, iblShadowsRenderPipeline: IblShadowsRenderPipeline, resolutionExp: number = 6, triPlanarVoxelization: boolean = true) {\n        this._scene = scene;\n        this._engine = scene.getEngine() as Engine;\n        this._triPlanarVoxelization = this._engine.isWebGPU || triPlanarVoxelization;\n        if (!this._engine.getCaps().drawBuffersExtension) {\n            Logger.Error(\"Can't do voxel rendering without the draw buffers extension.\");\n        }\n\n        const isWebGPU = this._engine.isWebGPU;\n        // Round down to a power of 2 so it evenly divides the power-of-2 voxel resolution,\n        // preventing out-of-bounds layer indices in the last MRT slab.\n        // This shader implementation writes up to 16 MRT outputs, so clamp to 16 to keep\n        // active draw buffers aligned with declared/written fragment outputs.\n        const rawMaxDrawBuffers = this._engine.getCaps().maxDrawBuffers || 0;\n        const cappedMaxDrawBuffers = Math.min(rawMaxDrawBuffers, 16);\n        this._maxDrawBuffers = cappedMaxDrawBuffers >= 1 ? 1 << Math.floor(Math.log2(cappedMaxDrawBuffers)) : 0;\n\n        this._copyMipEffectRenderer = new EffectRenderer(this._engine);\n        this._copyMipEffectWrapper = new EffectWrapper({\n            engine: this._engine,\n            fragmentShader: \"copyTexture3DLayerToTexture\",\n            useShaderStore: true,\n            uniformNames: [\"layerNum\"],\n            samplerNames: [\"textureSampler\"],\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n            extraInitializationsAsync: async () => {\n                if (isWebGPU) {\n                    await import(\"../../ShadersWGSL/copyTexture3DLayerToTexture.fragment\");\n                } else {\n                    await import(\"../../Shaders/copyTexture3DLayerToTexture.fragment\");\n                }\n            },\n        });\n        this._copyMipEffectWrapper.onApplyObservable.add(() => {\n            const effect = this._copyMipEffectWrapper.effect;\n            if (!effect || !this._copyMipSourceTexture) {\n                return;\n            }\n\n            effect.setTexture(\"textureSampler\", this._copyMipSourceTexture);\n            effect.setInt(\"layerNum\", this._copyMipLayer);\n        });\n\n        this.voxelResolutionExp = resolutionExp;\n    }\n\n    private _generateMipMaps() {\n        const iterations = Math.ceil(Math.log2(this._voxelResolution));\n        for (let i = 1; i < iterations + 1; i++) {\n            this._generateMipMap(i);\n        }\n    }\n\n    private _generateMipMap(lodLevel: number) {\n        // Generate a mip map for the given level by triggering the render of the procedural mip texture.\n        const mipTarget = this._mipArray[lodLevel - 1];\n        if (!mipTarget) {\n            return;\n        }\n\n        mipTarget.setTexture(\"srcMip\", lodLevel === 1 ? this.getVoxelGrid() : this._mipArray[lodLevel - 2]);\n        mipTarget.render();\n    }\n\n    private _copyMipMaps() {\n        const iterations = Math.ceil(Math.log2(this._voxelResolution));\n        for (let i = 1; i < iterations + 1; i++) {\n            this._copyMipMap(i);\n        }\n    }\n\n    private _copyMipMap(lodLevel: number) {\n        // Now, copy this mip into the mip chain of the voxel grid.\n        const mipTarget = this._mipArray[lodLevel - 1];\n        if (!mipTarget) {\n            return;\n        }\n        const voxelGrid = this.getVoxelGrid();\n        let rt: RenderTargetWrapper;\n        if (voxelGrid instanceof RenderTargetTexture && voxelGrid.renderTarget) {\n            rt = voxelGrid.renderTarget;\n        } else {\n            rt = (voxelGrid as any)._rtWrapper;\n        }\n        if (rt) {\n            this._copyMipEffectRenderer.saveStates();\n            const previousColorWrite = this._engine.getColorWrite();\n            const previousDepthBuffer = this._engine.getDepthBuffer();\n            const previousDepthWrite = this._engine.getDepthWrite();\n            const previousAlphaMode = this._engine.getAlphaMode();\n            this._engine.setColorWrite(true);\n            this._engine.setDepthBuffer(false);\n            this._engine.setDepthWrite(false);\n            this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\n            const bindSize = mipTarget.getSize().width;\n            let sourceDepth = mipTarget.getInternalTexture()?.depth;\n            sourceDepth = Math.max(1, sourceDepth || bindSize);\n            const destinationMipDepth = Math.max(1, this._voxelResolution >> lodLevel);\n            const layersToCopy = Math.min(sourceDepth, destinationMipDepth);\n            const destinationTexture = rt.texture;\n            const previousGenerateMipMaps = destinationTexture?.generateMipMaps;\n\n            if (destinationTexture) {\n                destinationTexture.generateMipMaps = false;\n            }\n\n            try {\n                // Render to each layer of the voxel grid.\n                for (let layer = 0; layer < layersToCopy; layer++) {\n                    this._engine.bindFramebuffer(rt, 0, bindSize, bindSize, true, lodLevel, layer);\n                    this._copyMipSourceTexture = mipTarget;\n                    this._copyMipLayer = layer;\n                    this._copyMipEffectRenderer.applyEffectWrapper(this._copyMipEffectWrapper);\n                    this._copyMipEffectRenderer.draw();\n                    this._engine.unBindFramebuffer(rt, true);\n                }\n\n                if (!this._engine.isWebGPU) {\n                    this._engine.unbindAllTextures();\n                }\n            } finally {\n                if (destinationTexture && previousGenerateMipMaps !== undefined) {\n                    destinationTexture.generateMipMaps = previousGenerateMipMaps;\n                }\n                this._engine.setAlphaMode(previousAlphaMode);\n                this._engine.setDepthWrite(previousDepthWrite);\n                this._engine.setDepthBuffer(previousDepthBuffer);\n                this._engine.setColorWrite(previousColorWrite);\n            }\n\n            this._copyMipSourceTexture = undefined;\n            this._copyMipEffectRenderer.restoreStates();\n        }\n    }\n\n    private _computeNumberOfSlabs(): number {\n        return Math.ceil(this._voxelResolution / this._maxDrawBuffers);\n    }\n\n    private _createTextures() {\n        const isWebGPU = this._engine.isWebGPU;\n        const size: TextureSize = {\n            width: this._voxelResolution,\n            height: this._voxelResolution,\n            depth: this._voxelResolution,\n        };\n        const voxelAxisOptions: RenderTargetTextureOptions = {\n            generateDepthBuffer: false,\n            generateMipMaps: false,\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\n            format: Constants.TEXTUREFORMAT_R,\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n        };\n\n        // We can render up to maxDrawBuffers voxel slices of the grid per render.\n        // We call this a slab.\n        const numSlabs = this._computeNumberOfSlabs();\n        const voxelCombinedOptions: IProceduralTextureCreationOptions = {\n            generateDepthBuffer: false,\n            generateMipMaps: true,\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\n            format: Constants.TEXTUREFORMAT_R,\n            samplingMode: Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST,\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n            extraInitializationsAsync: async () => {\n                if (isWebGPU) {\n                    await import(\"../../ShadersWGSL/iblCombineVoxelGrids.fragment\");\n                } else {\n                    await import(\"../../Shaders/iblCombineVoxelGrids.fragment\");\n                }\n            },\n        };\n        if (this._engine.isWebGPU) {\n            this._voxelGrid = new RenderTargetTexture(\"voxelGrid\", size, this._scene, {\n                ...voxelCombinedOptions,\n                format: Constants.TEXTUREFORMAT_R,\n                creationFlags: Constants.TEXTURE_CREATIONFLAG_STORAGE,\n            });\n            this._voxelGridRT = new RenderTargetTexture(\n                \"voxelGridRT\",\n                { width: Math.min(size.width * 2.0, 2048), height: Math.min(size.height * 2.0, 2048) },\n                this._scene,\n                voxelAxisOptions\n            );\n            // The opacity accumulator is created lazily, only when a voxelization includes Gaussian\n            // splats (see _ensureVoxelOpacityAccumulator).\n        } else if (this._triPlanarVoxelization) {\n            this._voxelGridXaxis = new RenderTargetTexture(\"voxelGridXaxis\", size, this._scene, voxelAxisOptions);\n            this._voxelGridYaxis = new RenderTargetTexture(\"voxelGridYaxis\", size, this._scene, voxelAxisOptions);\n            this._voxelGridZaxis = new RenderTargetTexture(\"voxelGridZaxis\", size, this._scene, voxelAxisOptions);\n            this._voxelMrtsXaxis = this._createVoxelMRTs(\"x_axis_\", this._voxelGridXaxis, numSlabs);\n            this._voxelMrtsYaxis = this._createVoxelMRTs(\"y_axis_\", this._voxelGridYaxis, numSlabs);\n            this._voxelMrtsZaxis = this._createVoxelMRTs(\"z_axis_\", this._voxelGridZaxis, numSlabs);\n\n            this._combinedVoxelGridPT = new ProceduralTexture(\"combinedVoxelGrid\", size, \"iblCombineVoxelGrids\", this._scene, voxelCombinedOptions, false);\n            this._scene.proceduralTextures.splice(this._scene.proceduralTextures.indexOf(this._combinedVoxelGridPT), 1);\n            this._combinedVoxelGridPT.setFloat(\"layer\", 0.0);\n            this._combinedVoxelGridPT.setTexture(\"voxelXaxisSampler\", this._voxelGridXaxis);\n            this._combinedVoxelGridPT.setTexture(\"voxelYaxisSampler\", this._voxelGridYaxis);\n            this._combinedVoxelGridPT.setTexture(\"voxelZaxisSampler\", this._voxelGridZaxis);\n            // We will render this only after voxelization is completed for the 3 axes.\n            this._combinedVoxelGridPT.autoClear = false;\n            this._combinedVoxelGridPT.wrapU = Texture.CLAMP_ADDRESSMODE;\n            this._combinedVoxelGridPT.wrapV = Texture.CLAMP_ADDRESSMODE;\n            this._combinedVoxelGridPT.wrapR = Texture.CLAMP_ADDRESSMODE;\n        } else {\n            this._voxelGridZaxis = new RenderTargetTexture(\"voxelGridZaxis\", size, this._scene, voxelCombinedOptions);\n            this._voxelMrtsZaxis = this._createVoxelMRTs(\"z_axis_\", this._voxelGridZaxis, numSlabs);\n        }\n\n        const generateVoxelMipOptions: IProceduralTextureCreationOptions = {\n            generateDepthBuffer: false,\n            generateMipMaps: false,\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\n            format: Constants.TEXTUREFORMAT_R,\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n            extraInitializationsAsync: async () => {\n                if (isWebGPU) {\n                    await import(\"../../ShadersWGSL/iblGenerateVoxelMip.fragment\");\n                } else {\n                    await import(\"../../Shaders/iblGenerateVoxelMip.fragment\");\n                }\n            },\n        };\n        this._mipArray = new Array(Math.ceil(Math.log2(this._voxelResolution)));\n        for (let mipIdx = 1; mipIdx <= this._mipArray.length; mipIdx++) {\n            const mipDim = this._voxelResolution >> mipIdx;\n            const mipSize: TextureSize = { width: mipDim, height: mipDim, depth: mipDim };\n            this._mipArray[mipIdx - 1] = new ProceduralTexture(\"voxelMip\" + mipIdx, mipSize, \"iblGenerateVoxelMip\", this._scene, generateVoxelMipOptions, false);\n            this._scene.proceduralTextures.splice(this._scene.proceduralTextures.indexOf(this._mipArray[mipIdx - 1]), 1);\n\n            const mipTarget = this._mipArray[mipIdx - 1];\n            mipTarget.autoClear = false;\n            mipTarget.wrapU = Texture.CLAMP_ADDRESSMODE;\n            mipTarget.wrapV = Texture.CLAMP_ADDRESSMODE;\n            mipTarget.wrapR = Texture.CLAMP_ADDRESSMODE;\n            mipTarget.setTexture(\"srcMip\", mipIdx > 1 ? this._mipArray[mipIdx - 2] : this.getVoxelGrid());\n            mipTarget.setInt(\"layerNum\", 0);\n        }\n\n        this._createVoxelMaterials();\n    }\n\n    /**\n     * WebGPU only. Allocates the opacity accumulator buffer and the compute shader that copies it into\n     * the r8 grid. Storage textures can't blend or do float atomics, so splats accumulate via atomicMax\n     * and this compute pass decodes the result into mip 0.\n     */\n    private _ensureVoxelOpacityAccumulator(): void {\n        if (this._voxelOpacityBuffer) {\n            return;\n        }\n        const res = this._voxelResolution;\n        // Packed 4 voxels/u32, so res^3 bytes. res is a power of two >= 8, so res^3 is a multiple of 4.\n        this._voxelOpacityBuffer = new StorageBuffer(this._engine as unknown as WebGPUEngine, res * res * res);\n        void (async () => {\n            await import(\"../../ShadersWGSL/iblCopyVoxelBufferToGrid.compute\");\n            this._copyBufferToGridCompute = new ComputeShader(\"iblCopyVoxelBufferToGrid\", this._engine, \"iblCopyVoxelBufferToGrid\", {\n                bindingsMapping: {\n                    voxelOpacityBuffer: { group: 0, binding: 0 },\n                    voxelGridTarget: { group: 0, binding: 1 },\n                },\n            });\n        })();\n    }\n\n    /**\n     * WebGPU only. Dispatches the compute pass that decodes the per-voxel opacity accumulator buffer\n     * into the r8 voxel grid (mip 0). Runs after all voxelization passes and before mip generation.\n     */\n    private _copyVoxelOpacityBufferToGrid(): void {\n        const compute = this._copyBufferToGridCompute;\n        if (!compute || !this._voxelOpacityBuffer) {\n            return;\n        }\n        compute.setStorageBuffer(\"voxelOpacityBuffer\", this._voxelOpacityBuffer);\n        compute.setStorageTexture(\"voxelGridTarget\", this._voxelGrid);\n        // Workgroup size is 4x4x4; cover the whole grid.\n        const groups = Math.ceil(this._voxelResolution / 4);\n        compute.dispatch(groups, groups, groups);\n    }\n\n    private _createVoxelMRTs(name: string, voxelRT: RenderTargetTexture, numSlabs: number): MultiRenderTarget[] {\n        voxelRT.wrapU = Texture.CLAMP_ADDRESSMODE;\n        voxelRT.wrapV = Texture.CLAMP_ADDRESSMODE;\n        // 3D texture: clamp the depth (R) axis too. The combine shader samples each grid with the depth\n        // coordinate spanning [0,1], so without this it wraps to the opposite face at the boundaries.\n        voxelRT.wrapR = Texture.CLAMP_ADDRESSMODE;\n        voxelRT.noPrePassRenderer = true;\n        const mrtArray: MultiRenderTarget[] = [];\n        const targetTypes = new Array(this._maxDrawBuffers).fill(Constants.TEXTURE_3D);\n\n        for (let mrtIndex = 0; mrtIndex < numSlabs; mrtIndex++) {\n            let layerIndices = new Array(this._maxDrawBuffers).fill(0);\n            layerIndices = layerIndices.map((value, index) => mrtIndex * this._maxDrawBuffers + index);\n\n            let textureNames = new Array(this._maxDrawBuffers).fill(\"\");\n            textureNames = textureNames.map((value, index) => \"voxel_grid_\" + name + (mrtIndex * this._maxDrawBuffers + index));\n\n            const mrt = new MultiRenderTarget(\n                \"mrt_\" + name + mrtIndex,\n                { width: this._voxelResolution, height: this._voxelResolution, depth: this._voxelResolution },\n                this._maxDrawBuffers, // number of draw buffers\n                this._scene,\n                {\n                    types: new Array(this._maxDrawBuffers).fill(Constants.TEXTURETYPE_UNSIGNED_BYTE),\n                    samplingModes: new Array(this._maxDrawBuffers).fill(Constants.TEXTURE_TRILINEAR_SAMPLINGMODE),\n                    generateMipMaps: false,\n                    targetTypes,\n                    formats: new Array(this._maxDrawBuffers).fill(Constants.TEXTUREFORMAT_R),\n                    faceIndex: new Array(this._maxDrawBuffers).fill(0),\n                    layerIndex: layerIndices,\n                    layerCounts: new Array(this._maxDrawBuffers).fill(this._voxelResolution),\n                    generateDepthBuffer: false,\n                    generateStencilBuffer: false,\n                },\n                textureNames\n            );\n\n            mrt.clearColor = new Color4(0, 0, 0, 1);\n            mrt.noPrePassRenderer = true;\n            for (let i = 0; i < this._maxDrawBuffers; i++) {\n                mrt.setInternalTexture(voxelRT.getInternalTexture()!, i);\n            }\n\n            mrtArray.push(mrt);\n        }\n        return mrtArray;\n    }\n\n    private _disposeVoxelTextures() {\n        this._stopVoxelization();\n        for (let i = 0; i < this._voxelMrtsZaxis.length; i++) {\n            if (this._triPlanarVoxelization) {\n                this._voxelMrtsXaxis[i].dispose(true);\n                this._voxelMrtsYaxis[i].dispose(true);\n            }\n            this._voxelMrtsZaxis[i].dispose(true);\n        }\n        if (this._triPlanarVoxelization) {\n            this._voxelGridXaxis?.dispose();\n            this._voxelGridYaxis?.dispose();\n            this._combinedVoxelGridPT?.dispose();\n        }\n        this._voxelGridZaxis?.dispose();\n        for (const mip of this._mipArray) {\n            mip.dispose();\n        }\n        this._voxelMaterial?.dispose();\n        this._voxelOpacityBuffer?.dispose();\n        this._voxelOpacityBuffer = undefined;\n        this._copyBufferToGridCompute = undefined;\n        // The recreated _voxelMaterial has no IBL_VOXEL_OPACITY_BUFFER define; reset the flag so\n        // updateVoxelGrid re-adds it (its change check would otherwise skip it after a resolution change).\n        this._useOpacityBuffer = false;\n        this._mipArray = [];\n        this._voxelMrtsXaxis = [];\n        this._voxelMrtsYaxis = [];\n        this._voxelMrtsZaxis = [];\n    }\n\n    private _createVoxelMaterials(): void {\n        const isWebGPU = this._engine.isWebGPU;\n        this._voxelMaterial = new ShaderMaterial(\"voxelization\", this._scene, \"iblVoxelGrid\", {\n            uniforms: [\"world\", \"viewMatrix\", \"invTransWorld\", \"invWorldScale\", \"nearPlane\", \"farPlane\", \"stepSize\"],\n            // WebGPU accumulates non-binary voxel opacity via atomicMax into this storage buffer.\n            storageBuffers: isWebGPU ? [\"voxelOpacityBuffer\"] : [],\n            defines: [\"MAX_DRAW_BUFFERS \" + this._maxDrawBuffers],\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n            extraInitializationsAsync: async () => {\n                if (isWebGPU) {\n                    await Promise.all([import(\"../../ShadersWGSL/iblVoxelGrid.fragment\"), import(\"../../ShadersWGSL/iblVoxelGrid.vertex\")]);\n                } else {\n                    await Promise.all([import(\"../../Shaders/iblVoxelGrid.fragment\"), import(\"../../Shaders/iblVoxelGrid.vertex\")]);\n                }\n            },\n        });\n\n        this._voxelMaterial.cullBackFaces = false;\n        this._voxelMaterial.backFaceCulling = false;\n        this._voxelMaterial.depthFunction = Constants.ALWAYS;\n    }\n\n    /**\n     * Checks if the voxel renderer is ready to voxelize scene\n     * @returns true if the voxel renderer is ready to voxelize scene\n     */\n    public isReady() {\n        let allReady = this.getVoxelGrid().isReady();\n        for (let i = 0; i < this._mipArray.length; i++) {\n            const mipReady = this._mipArray[i].isReady();\n            allReady &&= mipReady;\n        }\n\n        if (!allReady || this._voxelizationInProgress) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * If the MRT's are already in the list of render targets, this will\n     * remove them so that they don't get rendered again.\n     */\n    private _stopVoxelization() {\n        // If the MRT's are already in the list of render targets, remove them.\n        this._removeVoxelRTs(this._voxelMrtsXaxis);\n        this._removeVoxelRTs(this._voxelMrtsYaxis);\n        this._removeVoxelRTs(this._voxelMrtsZaxis);\n        this._removeVoxelRTs([this._voxelGridRT]);\n    }\n\n    private _removeVoxelRTs(rts: RenderTargetTexture[]) {\n        // const currentRTs = this._scene.customRenderTargets;\n        const rtIdx = this._renderTargets.findIndex((rt) => {\n            if (rt === rts[0]) {\n                return true;\n            }\n            return false;\n        });\n        if (rtIdx >= 0) {\n            this._renderTargets.splice(rtIdx, rts.length);\n        } else {\n            const rtIdx = this._scene.customRenderTargets.findIndex((rt) => {\n                if (rt === rts[0]) {\n                    return true;\n                }\n                return false;\n            });\n            if (rtIdx >= 0) {\n                this._scene.customRenderTargets.splice(rtIdx, rts.length);\n            }\n        }\n    }\n\n    /**\n     * Renders voxel grid of scene for IBL shadows\n     * @param includedMeshes\n     * @param registerAfterRenderObservable Whether to register scene onAfterRender callback (legacy path).\n     */\n    public updateVoxelGrid(includedMeshes: Mesh[], registerAfterRenderObservable: boolean = true) {\n        if (this._voxelizationInProgress) {\n            return;\n        }\n        this._stopVoxelization();\n        this._voxelizationInProgress = true;\n\n        if (this._engine.isWebGPU) {\n            // Route through the opacity accumulator only when Gaussian splats are present (they need\n            // non-binary accumulation). Regular-mesh-only voxelization writes the grid directly.\n            const useBuffer = _HasGaussianSplatting(includedMeshes);\n            if (useBuffer) {\n                this._ensureVoxelOpacityAccumulator();\n            }\n            if (useBuffer !== this._useOpacityBuffer) {\n                this._useOpacityBuffer = useBuffer;\n                this._voxelMaterial.setDefine(\"IBL_VOXEL_OPACITY_BUFFER\", useBuffer);\n            }\n        }\n\n        if (this._engine.isWebGPU) {\n            this._voxelGridRT.renderList = includedMeshes;\n            this._addRTsForRender([this._voxelGridRT], includedMeshes, 0);\n        } else if (this._triPlanarVoxelization) {\n            this._addRTsForRender(this._voxelMrtsXaxis, includedMeshes, 0);\n            this._addRTsForRender(this._voxelMrtsYaxis, includedMeshes, 1);\n            this._addRTsForRender(this._voxelMrtsZaxis, includedMeshes, 2);\n        } else {\n            this._addRTsForRender(this._voxelMrtsZaxis, includedMeshes, 2);\n        }\n        if (registerAfterRenderObservable) {\n            this._renderVoxelGridBound = this._renderVoxelGrid.bind(this);\n            this._scene.onAfterRenderObservable.add(this._renderVoxelGridBound);\n        }\n    }\n\n    /**\n     * Advances voxelization work when running in custom render loops (for example FrameGraph tasks)\n     * where scene onAfterRender timing may differ from classic pipeline flow.\n     */\n    public processVoxelization(): void {\n        this._renderVoxelGrid();\n    }\n\n    private _renderVoxelGridBound: () => void;\n\n    private _renderVoxelGrid() {\n        if (this._voxelizationInProgress) {\n            // Wait for shadow-casting GaussianSplatting meshes' depth sort to settle before\n            // rasterizing. Voxelization is order-independent — the order splats are drawn never\n            // affects the grid — but the GS voxel draw still *indexes* each splat through the\n            // `splatIndex` thin-instance buffer, and that buffer is (re)sized, filled and rebound by\n            // the sort worker's callback (the same callback that flips `_isDepthSortSettled`). After\n            // addPart() merges a splat, `forcedInstanceCount` jumps to the new total synchronously\n            // but the index buffer is only finalized when the sort lands; rasterizing in between\n            // indexes a stale/mismatched buffer and writes an empty grid (no IBL shadow until a\n            // later refresh). Frame-capped so a continuously re-sorting (orbiting) splat still\n            // voxelizes eventually rather than blocking forever.\n            let gsSortPending = false;\n            for (let i = 0; i < this._renderTargets.length && !gsSortPending; i++) {\n                const renderList = this._renderTargets[i].renderList;\n                if (!renderList) {\n                    continue;\n                }\n                for (const mesh of renderList) {\n                    if (_IsGaussianSplattingMesh(mesh) && !(mesh as GaussianSplattingMesh)._isDepthSortSettled) {\n                        gsSortPending = true;\n                        break;\n                    }\n                }\n            }\n            if (gsSortPending && this._sortSettleWaitFrames < _MaxSortSettleWaitFrames) {\n                this._sortSettleWaitFrames++;\n                return;\n            }\n            this._sortSettleWaitFrames = 0;\n\n            let allReady = this.getVoxelGrid().isReady();\n            for (let i = 0; i < this._mipArray.length; i++) {\n                const mipReady = this._mipArray[i].isReady();\n                allReady &&= mipReady;\n            }\n            for (let i = 0; i < this._renderTargets.length; i++) {\n                const rttReady = this._renderTargets[i].isReadyForRendering();\n                allReady &&= rttReady;\n            }\n            for (const gsVoxelMat of Array.from(this._gsVoxelMaterialCache.values())) {\n                allReady &&= gsVoxelMat.isReady();\n            }\n            if (!allReady) {\n                return;\n            }\n\n            const copyMipEffect = this._copyMipEffectWrapper.effect;\n            if (!copyMipEffect.isReady()) {\n                return;\n            }\n\n            if (this._engine.isWebGPU) {\n                if (this._useOpacityBuffer) {\n                    // The copy compute must be ready before we voxelize, else the grid stays unpopulated.\n                    if (!this._copyBufferToGridCompute || !this._copyBufferToGridCompute.isReady()) {\n                        return;\n                    }\n                    // Reset the accumulator. clear() is a command-encoder op, so it must run before any\n                    // render pass opens (here, not mid-render).\n                    this._voxelOpacityBuffer?.clear();\n                } else if (this._voxelGrid && this._voxelGrid.renderTarget) {\n                    // Direct mode (no splats): regular meshes textureStore into the grid, so clear each\n                    // layer first.\n                    for (let layer = 0; layer < this._voxelResolution; layer++) {\n                        this._engine.bindFramebuffer(this._voxelGrid.renderTarget, 0, undefined, undefined, true, 0, layer);\n                        this._engine.clear(this._voxelClearColor, true, false, false);\n                        this._engine.unBindFramebuffer(this._voxelGrid.renderTarget, true);\n                    }\n                }\n            }\n\n            for (const rt of this._renderTargets) {\n                rt.render();\n            }\n            this._stopVoxelization();\n\n            if (this._engine.isWebGPU) {\n                if (this._useOpacityBuffer) {\n                    // Decode the atomically-accumulated opacity buffer into the r8 voxel grid (mip 0).\n                    this._copyVoxelOpacityBufferToGrid();\n                }\n            } else if (this._triPlanarVoxelization) {\n                this._combinedVoxelGridPT.render();\n            }\n            this._generateMipMaps();\n            this._copyMipMaps();\n            this._scene.onAfterRenderObservable.removeCallback(this._renderVoxelGridBound);\n            this._voxelizationInProgress = false;\n            this.onVoxelizationCompleteObservable.notifyObservers();\n        }\n    }\n\n    /**\n     * Splits rendering for every voxel RT: non–Gaussian splatting meshes use subMesh.render\n     * (material override from setMaterialForRendering); GaussianSplattingMesh uses a custom draw path with its cached voxel ShaderMaterial.\n     * @param rtt - the render target texture to install the custom render function on\n     */\n    private _installVoxelMixedCustomRender(rtt: RenderTargetTexture): void {\n        const scene = this._scene;\n        const engine = scene.getEngine();\n\n        const renderGsSplat = (sm: SubMesh): void => {\n            const renderingMesh = sm.getRenderingMesh();\n            const effectiveMesh = sm.getEffectiveMesh();\n            const gsVoxelMaterial = this._gsVoxelMaterialCache.get(effectiveMesh.uniqueId);\n            if (!gsVoxelMaterial || !gsVoxelMaterial.isReady()) {\n                return;\n            }\n\n            const drawWrapper = gsVoxelMaterial._getDrawWrapper();\n            if (!drawWrapper?.effect) {\n                return;\n            }\n            const effect = drawWrapper.effect;\n\n            const batch = renderingMesh._getInstancesRenderList(sm._id, !!sm.getReplacementMesh());\n            if (batch.mustReturn) {\n                return;\n            }\n\n            const hardwareInstancedRendering =\n                engine.getCaps().instancedArrays && ((batch.visibleInstances[sm._id] !== null && batch.visibleInstances[sm._id] !== undefined) || renderingMesh.hasThinInstances);\n\n            const fillMode = sm.getMaterial()?.fillMode ?? Constants.MATERIAL_TriangleFillMode;\n            engine.enableEffect(drawWrapper);\n            renderingMesh._bind(sm, effect, fillMode);\n            gsVoxelMaterial._preBind(drawWrapper);\n            gsVoxelMaterial.bind(effectiveMesh.getWorldMatrix(), effectiveMesh, effect);\n            // If rotation/scale textures are missing, bind() logged the warning; skip the draw to avoid GPU errors.\n            if (!(effectiveMesh as GaussianSplattingMesh).rotationsATexture) {\n                gsVoxelMaterial.unbind();\n                return;\n            }\n            if (engine.isWebGPU) {\n                // A GSplat is a 3D Gaussian ellipsoid. To approximate its volume in the voxel grid\n                // we rasterize three planar cross-section quads — one per principal axis — each\n                // spanning the ellipsoid cross-section perpendicular to that axis. A quad rendered\n                // edge-on produces zero fragments, so we draw once per world axis: each draw lets\n                // computeVoxelSplatWorldPos pick the quad whose normal best aligns with that view,\n                // guaranteeing every splat is captured face-on from at least one direction.\n                const viewMatrices = _IblShadowsVoxelRenderer._VOXEL_VIEW_MATRICES;\n                for (let axisIdx = 0; axisIdx < 3; axisIdx++) {\n                    effect.setMatrix(\"viewMatrix\", viewMatrices[axisIdx]);\n                    renderingMesh._processRendering(effectiveMesh, sm, effect, fillMode, batch, hardwareInstancedRendering, (_isInstance, world) => {\n                        effect.setMatrix(\"world\", world);\n                    });\n                }\n            } else {\n                // Accumulate overlapping splats with a MAX blend equation (dst = max(src, dst)) so each\n                // cell keeps the strongest occluder; writing 0.0 into non-slab draw buffers is a no-op.\n                // Matches the WebGPU atomicMax path; see the opacity-compositing limitation in\n                // iblVoxelOpacityAtomicMax.\n                const previousAlphaMode = engine.getAlphaMode();\n                engine.setAlphaMode(Constants.ALPHA_MAX, true);\n                renderingMesh._processRendering(effectiveMesh, sm, effect, fillMode, batch, hardwareInstancedRendering, (_isInstance, world) => effect.setMatrix(\"world\", world));\n                engine.setAlphaMode(previousAlphaMode, true);\n            }\n            gsVoxelMaterial.unbind();\n        };\n\n        const processBucket = (subMeshes: SmartArray<SubMesh>, enableAlphaMode: boolean): void => {\n            for (let i = 0; i < subMeshes.length; i++) {\n                const sm = subMeshes.data[i];\n                const effective = sm.getEffectiveMesh();\n                if (_IsGaussianSplattingMesh(effective)) {\n                    renderGsSplat(sm);\n                } else {\n                    sm.render(enableAlphaMode);\n                }\n            }\n        };\n\n        rtt.customRenderFunction = (\n            opaqueSubMeshes: SmartArray<SubMesh>,\n            alphaTestSubMeshes: SmartArray<SubMesh>,\n            transparentSubMeshes: SmartArray<SubMesh>,\n            depthOnlySubMeshes: SmartArray<SubMesh>\n        ): void => {\n            if (depthOnlySubMeshes.length) {\n                engine.setColorWrite(false);\n                processBucket(depthOnlySubMeshes, false);\n                engine.setColorWrite(true);\n            }\n            processBucket(opaqueSubMeshes, false);\n            processBucket(alphaTestSubMeshes, false);\n            processBucket(transparentSubMeshes, true);\n        };\n    }\n\n    private _addGsMeshToVoxelRT(mrt: RenderTargetTexture, mesh: GaussianSplattingMesh): void {\n        let gsVoxelMaterial = this._gsVoxelMaterialCache.get(mesh.uniqueId);\n        if (!gsVoxelMaterial) {\n            const gsMaterial = mesh.material as GaussianSplattingMaterial;\n            if (!gsMaterial) {\n                return;\n            }\n            const shaderLanguage = this._engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\n            gsVoxelMaterial = gsMaterial.makeVoxelRenderingMaterial(this._scene, shaderLanguage, this._maxDrawBuffers, mesh.isCompound);\n            this._gsVoxelMaterialCache.set(mesh.uniqueId, gsVoxelMaterial);\n        }\n        mrt.renderList?.push(mesh as Mesh);\n        mrt.setMaterialForRendering(mesh as Mesh, gsVoxelMaterial);\n    }\n\n    private _addRTsForRender(mrts: RenderTargetTexture[], includedMeshes: Mesh[], axis: number) {\n        const slabSize = 1.0 / this._computeNumberOfSlabs();\n        const voxelMaterial = this._voxelMaterial;\n\n        // We need to update the world scale uniform for every mesh being rendered to the voxel grid.\n        for (let mrtIndex = 0; mrtIndex < mrts.length; mrtIndex++) {\n            const mrt = mrts[mrtIndex];\n            mrt._disableEngineStages = true;\n            mrt.useCameraPostProcesses = false;\n            mrt.renderParticles = false;\n            mrt.renderSprites = false;\n            mrt.enableOutlineRendering = false;\n\n            const renderBucket = (bucket: SmartArray<SubMesh>) => {\n                for (let index = 0; index < bucket.length; index++) {\n                    const subMesh = bucket.data[index];\n                    if (subMesh.getMaterial() !== voxelMaterial) {\n                        continue;\n                    }\n                    subMesh.render(false);\n                }\n            };\n\n            mrt.customRenderFunction = (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes) => {\n                renderBucket(depthOnlySubMeshes);\n                renderBucket(opaqueSubMeshes);\n                renderBucket(alphaTestSubMeshes);\n                renderBucket(transparentSubMeshes);\n            };\n\n            mrt.renderList = [];\n            const nearPlane = mrtIndex * slabSize;\n            const farPlane = (mrtIndex + 1) * slabSize;\n            const stepSize = slabSize / this._maxDrawBuffers;\n\n            const viewMatrix = _IblShadowsVoxelRenderer._VOXEL_VIEW_MATRICES[axis];\n            mrt.onBeforeRenderObservable.clear();\n            mrt.onBeforeRenderObservable.add(() => {\n                voxelMaterial.setMatrix(\"viewMatrix\", viewMatrix);\n                voxelMaterial.setMatrix(\"invWorldScale\", this._invWorldScaleMatrix);\n                voxelMaterial.setFloat(\"nearPlane\", nearPlane);\n                voxelMaterial.setFloat(\"farPlane\", farPlane);\n                voxelMaterial.setFloat(\"stepSize\", stepSize);\n                if (this._engine.isWebGPU) {\n                    this._voxelMaterial.useVertexPulling = true;\n                    this._voxelMaterial.setTexture(\"voxel_storage\", this.getVoxelGrid());\n                    if (this._voxelOpacityBuffer) {\n                        this._voxelMaterial.setStorageBuffer(\"voxelOpacityBuffer\", this._voxelOpacityBuffer);\n                    }\n                }\n                // Push per-slab uniforms to each GS voxel material in this MRT's render list.\n                for (const m of mrt.renderList ?? []) {\n                    if (_IsGaussianSplattingMesh(m)) {\n                        const gsVoxelMat = this._gsVoxelMaterialCache.get(m.uniqueId);\n                        if (gsVoxelMat) {\n                            gsVoxelMat.setMatrix(\"invWorldScale\", this._invWorldScaleMatrix);\n                            if (this._engine.isWebGPU) {\n                                // WGSL GS voxel shader uses the same viewMatrix approach as WebGL; the per-axis viewMatrix is set per-draw in renderGsSplat.\n                                gsVoxelMat.setTexture(\"voxel_storage\", this.getVoxelGrid());\n                                if (this._voxelOpacityBuffer) {\n                                    gsVoxelMat.setStorageBuffer(\"voxelOpacityBuffer\", this._voxelOpacityBuffer);\n                                }\n                            } else {\n                                gsVoxelMat.setMatrix(\"viewMatrix\", viewMatrix);\n                                gsVoxelMat.setFloat(\"nearPlane\", nearPlane);\n                                gsVoxelMat.setFloat(\"farPlane\", farPlane);\n                                gsVoxelMat.setFloat(\"stepSize\", stepSize);\n                            }\n                        }\n                    }\n                }\n            });\n\n            // Set this material on every mesh in the scene (for this RT)\n            if (includedMeshes.length === 0) {\n                return;\n            }\n            for (const mesh of includedMeshes) {\n                if (!mesh) {\n                    continue;\n                }\n                if (_IsGaussianSplattingMesh(mesh)) {\n                    this._addGsMeshToVoxelRT(mrt, mesh as GaussianSplattingMesh);\n                } else if (mesh.subMeshes && mesh.subMeshes.length > 0) {\n                    mrt.renderList?.push(mesh);\n                    mrt.setMaterialForRendering(mesh, voxelMaterial);\n                }\n                const meshes = mesh.getChildMeshes();\n                for (const childMesh of meshes) {\n                    if (_IsGaussianSplattingMesh(childMesh)) {\n                        this._addGsMeshToVoxelRT(mrt, childMesh as GaussianSplattingMesh);\n                    } else if (childMesh.subMeshes && childMesh.subMeshes.length > 0) {\n                        mrt.renderList?.push(childMesh);\n                        mrt.setMaterialForRendering(childMesh, voxelMaterial);\n                    }\n                }\n            }\n\n            this._installVoxelMixedCustomRender(mrt);\n        }\n\n        this._renderTargets = this._renderTargets.concat(mrts);\n    }\n\n    /**\n     * Called by the pipeline to resize resources.\n     */\n    public resize() {}\n\n    /**\n     * Disposes the voxel renderer and associated resources\n     */\n    public dispose() {\n        this._disposeVoxelTextures();\n        for (const mat of Array.from(this._gsVoxelMaterialCache.values())) {\n            mat.dispose();\n        }\n        this._gsVoxelMaterialCache.clear();\n    }\n}\n","import { type FrameGraph, type FrameGraphObjectList, type FrameGraphTextureHandle, type Mesh, type Observer } from \"core/index\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { _IblShadowsVoxelRenderer } from \"core/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure\";\r\nimport { FrameGraphTask } from \"../../../frameGraphTask\";\r\n\r\n/**\r\n * Task used to voxelize shadow casting objects for IBL shadows.\r\n * @internal\r\n */\r\nexport class FrameGraphIblShadowsVoxelizationTask extends FrameGraphTask {\r\n    /**\r\n     * Observable raised when voxelization completes.\r\n     */\r\n    public readonly onVoxelizationCompleteObservable = new Observable<void>();\r\n\r\n    /**\r\n     * Input object list containing the meshes to voxelize.\r\n     */\r\n    public objectList: FrameGraphObjectList;\r\n\r\n    /**\r\n     * World-space voxel grid size.\r\n     */\r\n    public voxelGridSize = 1;\r\n\r\n    /**\r\n     * Voxel grid resolution exponent. Actual resolution is 2^resolutionExp.\r\n     */\r\n    private _resolutionExp = 6;\r\n    /**\r\n     * Sets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.\r\n     */\r\n    public set resolutionExp(value: number) {\r\n        const newValue = Math.round(Math.max(1, Math.min(value, 8)));\r\n        if (newValue === this._resolutionExp) {\r\n            return;\r\n        }\r\n        this._resolutionExp = newValue;\r\n        if (this._voxelRenderer) {\r\n            this._voxelRenderer.voxelResolutionExp = this._resolutionExp;\r\n        }\r\n        this.dirty = true;\r\n    }\r\n    /**\r\n     * Gets voxel grid resolution exponent. Actual resolution is 2^resolutionExp.\r\n     */\r\n    public get resolutionExp(): number {\r\n        return this._resolutionExp;\r\n    }\r\n\r\n    /**\r\n     * Enables tri-planar voxelization mode.\r\n     */\r\n    public triPlanarVoxelization = true;\r\n\r\n    /**\r\n     * Indicates whether voxelization should be refreshed.\r\n     */\r\n    public dirty = true;\r\n\r\n    private _refreshRate = -1;\r\n\r\n    /**\r\n     * Controls how often voxelization is refreshed.\r\n     * - -1: manual only (requires setting `dirty = true`)\r\n     * - 0: every frame\r\n     * - 1: skip 1 frame between updates\r\n     * - N: skip N frames between updates\r\n     */\r\n    public get refreshRate(): number {\r\n        return this._refreshRate;\r\n    }\r\n\r\n    public set refreshRate(value: number) {\r\n        this._refreshRate = Math.max(-1, Math.round(value));\r\n    }\r\n\r\n    /**\r\n     * World-to-voxel normalization matrix used by tracing.\r\n     */\r\n    public readonly worldScaleMatrix = Matrix.Identity();\r\n\r\n    /**\r\n     * Output voxel grid texture handle.\r\n     */\r\n    public readonly outputVoxelGridTexture: FrameGraphTextureHandle;\r\n\r\n    private _voxelRenderer?: _IblShadowsVoxelRenderer;\r\n    private _voxelRendererResolutionExp?: number;\r\n    private _voxelRendererTriPlanar?: boolean;\r\n    private _voxelizationCompleteObserver: Observer<void> | null = null;\r\n    private _voxelRTTextureHandle?: FrameGraphTextureHandle;\r\n    private _voxelGridTextureHandle?: FrameGraphTextureHandle;\r\n    private _frameCounter = 0;\r\n\r\n    /**\r\n     * Creates a new voxelization task.\r\n     * @param name The task name.\r\n     * @param frameGraph The frame graph this task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.outputVoxelGridTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    /**\r\n     * Gets the class name.\r\n     * @returns The class name.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FrameGraphIblShadowsVoxelizationTask\";\r\n    }\r\n\r\n    /**\r\n     * Checks whether the task has all required inputs.\r\n     * @returns True when ready.\r\n     */\r\n    public override isReady(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Requests a voxelization update on the next eligible frame.\r\n     */\r\n    public requestVoxelizationUpdate(): void {\r\n        this.dirty = true;\r\n    }\r\n\r\n    /**\r\n     * Recomputes voxel world bounds from the current object list and updates worldScaleMatrix.\r\n     */\r\n    public updateSceneBounds(): void {\r\n        this._updateWorldScaleMatrix();\r\n    }\r\n\r\n    /**\r\n     * Records the voxelization passes.\r\n     */\r\n    public override record() {\r\n        if (this.objectList === undefined) {\r\n            throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: objectList is required`);\r\n        }\r\n\r\n        this._ensureVoxelRenderer();\r\n        this._updateWorldScaleMatrix();\r\n\r\n        this._updateOutputTextureHandlesFromRenderer();\r\n\r\n        const voxelRT = this._voxelRenderer!.getRT();\r\n        const voxelRTInternalTexture = voxelRT.getInternalTexture();\r\n        if (!voxelRTInternalTexture) {\r\n            throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: voxel renderer RT texture is unavailable`);\r\n        }\r\n        this._voxelRTTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} Voxel RT`, voxelRTInternalTexture, this._voxelRTTextureHandle);\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n        pass.setRenderTarget(this._voxelRTTextureHandle);\r\n        pass.addDependencies(this.outputVoxelGridTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            context.restoreDefaultFramebuffer();\r\n\r\n            this._frameCounter++;\r\n            const shouldRefreshFromRate = this.refreshRate >= 0 && (this._frameCounter - 1) % (this.refreshRate + 1) === 0;\r\n\r\n            if (this._voxelRenderer!.isVoxelizationInProgress()) {\r\n                this._voxelRenderer!.processVoxelization();\r\n                return;\r\n            }\r\n\r\n            if (this.dirty || shouldRefreshFromRate) {\r\n                const meshes = this.objectList!.meshes as Mesh[];\r\n                if (meshes.length === 0) {\r\n                    return;\r\n                }\r\n\r\n                this._ensureVoxelRenderer();\r\n                this._updateWorldScaleMatrix();\r\n                this._voxelRenderer!.setWorldScaleMatrix(this.worldScaleMatrix);\r\n                this._voxelRenderer!.updateVoxelGrid(meshes, false);\r\n                this.dirty = false;\r\n            }\r\n\r\n            if (this._voxelRenderer!.isVoxelizationInProgress()) {\r\n                this._voxelRenderer!.processVoxelization();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Disposes internal resources.\r\n     */\r\n    public override dispose(): void {\r\n        this._detachVoxelizationObserver();\r\n        this._voxelRenderer?.dispose();\r\n        this._voxelRenderer = undefined;\r\n        this.onVoxelizationCompleteObservable.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    private _ensureVoxelRenderer(): void {\r\n        const needsNewRenderer = !this._voxelRenderer || this._voxelRendererResolutionExp !== this.resolutionExp || this._voxelRendererTriPlanar !== this.triPlanarVoxelization;\r\n\r\n        if (!needsNewRenderer) {\r\n            return;\r\n        }\r\n\r\n        this._voxelRenderer?.dispose();\r\n        this._voxelRenderer = new _IblShadowsVoxelRenderer(this._frameGraph.scene, {} as never, this.resolutionExp, this.triPlanarVoxelization);\r\n        this._attachVoxelizationObserver();\r\n        this._voxelRendererResolutionExp = this.resolutionExp;\r\n        this._voxelRendererTriPlanar = this.triPlanarVoxelization;\r\n    }\r\n\r\n    private _attachVoxelizationObserver(): void {\r\n        this._detachVoxelizationObserver();\r\n\r\n        if (!this._voxelRenderer) {\r\n            return;\r\n        }\r\n\r\n        this._voxelizationCompleteObserver = this._voxelRenderer.onVoxelizationCompleteObservable.add(() => {\r\n            this._updateOutputTextureHandlesFromRenderer();\r\n            this.onVoxelizationCompleteObservable.notifyObservers();\r\n        });\r\n    }\r\n\r\n    private _detachVoxelizationObserver(): void {\r\n        if (this._voxelRenderer && this._voxelizationCompleteObserver) {\r\n            this._voxelRenderer.onVoxelizationCompleteObservable.remove(this._voxelizationCompleteObserver);\r\n        }\r\n\r\n        this._voxelizationCompleteObserver = null;\r\n    }\r\n\r\n    private _updateWorldScaleMatrix(): void {\r\n        const meshes = this.objectList?.meshes as Mesh[] | undefined;\r\n        if (!meshes || meshes.length === 0 || !isFinite(this.voxelGridSize) || this.voxelGridSize <= 0) {\r\n            this.worldScaleMatrix.copyFrom(Matrix.Identity());\r\n            return;\r\n        }\r\n\r\n        const bounds = {\r\n            min: new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE),\r\n            max: new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE),\r\n        };\r\n\r\n        for (const mesh of meshes) {\r\n            const localBounds = mesh.getHierarchyBoundingVectors(true);\r\n            bounds.min = Vector3.Minimize(bounds.min, localBounds.min);\r\n            bounds.max = Vector3.Maximize(bounds.max, localBounds.max);\r\n        }\r\n\r\n        const size = bounds.max.subtract(bounds.min);\r\n        this.voxelGridSize = Math.max(size.x, size.y, size.z);\r\n\r\n        const halfSize = this.voxelGridSize / 2.0;\r\n        const centerOffset = bounds.max.add(bounds.min).multiplyByFloats(-0.5, -0.5, -0.5);\r\n        const invWorldScaleMatrix = Matrix.Compose(new Vector3(1.0 / halfSize, 1.0 / halfSize, 1.0 / halfSize), new Quaternion(), Vector3.Zero());\r\n        const invTranslationMatrix = Matrix.Compose(new Vector3(1.0, 1.0, 1.0), new Quaternion(), centerOffset);\r\n        invTranslationMatrix.multiplyToRef(invWorldScaleMatrix, this.worldScaleMatrix);\r\n    }\r\n\r\n    private _updateOutputTextureHandlesFromRenderer(): void {\r\n        const voxelTexture = this._voxelRenderer!.getVoxelGrid();\r\n        const voxelInternalTexture = voxelTexture.getInternalTexture();\r\n        if (!voxelInternalTexture) {\r\n            throw new Error(`FrameGraphIblShadowsVoxelizationTask ${this.name}: voxel renderer texture is unavailable`);\r\n        }\r\n\r\n        this._voxelGridTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} Voxel Grid`, voxelInternalTexture, this._voxelGridTextureHandle);\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputVoxelGridTexture, this._voxelGridTextureHandle);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { serialize, serializeAsMatrix, serializeAsVector3 } from \"../../Misc/decorators\";\nimport { TimingTools } from \"../../Misc/timingTools\";\nimport { type Nullable } from \"../../types\";\nimport { type Scene } from \"../../scene.pure\";\nimport { Matrix, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\nimport { Constants } from \"../../Engines/constants\";\nimport { GetClass, RegisterClass } from \"../../Misc/typeStore\";\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\nimport { Observable } from \"../../Misc/observable.pure\";\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\nimport { RegisterAbstractEngineCubeTexture } from \"../../Engines/AbstractEngine/abstractEngine.cubeTexture.pure\";\n\n/**\n * Defines the available options when creating a cube texture\n */\nexport interface ICubeTextureCreationOptions {\n    /** Defines the suffixes add to the picture name in case six images are in use like _px.jpg */\n    extensions?: string[];\n\n    /** noMipmap defines if mipmaps should be created or not */\n    noMipmap?: boolean;\n\n    /** files defines the six files to load for the different faces in that order: px, py, pz, nx, ny, nz */\n    files?: string[];\n\n    /** buffer to load instead of loading the data from the url */\n    buffer?: ArrayBufferView;\n\n    /** onLoad defines a callback triggered at the end of the file load if no errors occurred */\n    onLoad?: () => void;\n\n    /** onError defines a callback triggered in case of error during load */\n    onError?: (message?: string, exception?: any) => void;\n\n    /** format defines the internal format to use for the texture once loaded */\n    format?: number;\n\n    /** prefiltered defines whether or not the texture is created from prefiltered data */\n    prefiltered?: boolean;\n\n    /** forcedExtension defines the extensions to use (force a special type of file to load) in case it is different from the file name */\n    forcedExtension?: any;\n\n    /** createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary */\n    createPolynomials?: boolean;\n\n    /** lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness */\n    lodScale?: number;\n\n    /** lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness */\n    lodOffset?: number;\n\n    /** loaderOptions options to be passed to the loader */\n    loaderOptions?: any;\n\n    /** useSRGBBuffer Defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU) (default: false) */\n    useSRGBBuffer?: boolean;\n\n    /** Target face size for spherical polynomial computation. 0 = full resolution (default). */\n    sphericalPolynomialTargetSize?: number;\n}\n\n// The default scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness\nconst DefaultLodScale = 0.8;\n\n/**\n * Class for creating a cube texture\n */\nexport class CubeTexture extends BaseTexture {\n    private _delayedOnLoad: Nullable<() => void>;\n    private _delayedOnError: Nullable<(message?: string, exception?: any) => void>;\n    private _lodScale: number;\n    private _lodOffset: number;\n\n    /**\n     * Observable triggered once the texture has been loaded.\n     */\n    public onLoadObservable: Observable<CubeTexture> = new Observable<CubeTexture>();\n\n    /**\n     * The url of the texture\n     */\n    @serialize()\n    public url: string;\n\n    /**\n     * Gets or sets the center of the bounding box associated with the cube texture.\n     * It must define where the camera used to render the texture was set\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#using-local-cubemap-mode\n     */\n    @serializeAsVector3()\n    public boundingBoxPosition = Vector3.Zero();\n\n    private _boundingBoxSize: Vector3;\n\n    /**\n     * Gets or sets the size of the bounding box associated with the cube texture\n     * When defined, the cubemap will switch to local mode\n     * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity\n     * @example https://www.babylonjs-playground.com/#RNASML\n     */\n    public set boundingBoxSize(value: Vector3) {\n        if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {\n            return;\n        }\n        this._boundingBoxSize = value;\n        const scene = this.getScene();\n        if (scene) {\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\n        }\n    }\n    /**\n     * Returns the bounding box size\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#using-local-cubemap-mode\n     */\n    @serializeAsVector3()\n    public get boundingBoxSize(): Vector3 {\n        return this._boundingBoxSize;\n    }\n\n    protected _rotationY: number = 0;\n\n    /**\n     * Sets texture matrix rotation angle around Y axis in radians.\n     */\n    @serialize(\"rotationY\")\n    public set rotationY(value: number) {\n        this._rotationY = value;\n        this.setReflectionTextureMatrix(Matrix.RotationY(this._rotationY));\n    }\n    /**\n     * Gets texture matrix rotation angle around Y axis radians.\n     */\n    public get rotationY(): number {\n        return this._rotationY;\n    }\n\n    /**\n     * Are mip maps generated for this texture or not.\n     */\n    public override get noMipmap(): boolean {\n        return this._noMipmap;\n    }\n\n    private _noMipmap: boolean;\n\n    /** @internal */\n    @serialize(\"files\")\n    public _files: Nullable<string[]> = null;\n\n    @serialize(\"forcedExtension\")\n    protected _forcedExtension: Nullable<string> = null;\n\n    /**\n     * Gets the forced extension (if any)\n     */\n    public get forcedExtension(): Nullable<string> {\n        return this._forcedExtension;\n    }\n\n    @serialize(\"extensions\")\n    private _extensions: Nullable<string[]> = null;\n\n    @serializeAsMatrix(\"textureMatrix\")\n    private _textureMatrix: Matrix;\n\n    @serializeAsMatrix(\"textureMatrixRefraction\")\n    private _textureMatrixRefraction: Matrix = new Matrix();\n\n    private _format: number;\n    private _createPolynomials: boolean;\n    private _loaderOptions: any;\n    private _useSRGBBuffer?: boolean;\n    private _buffer: Nullable<ArrayBufferView> = null;\n\n    /**\n     * Creates a cube texture to use with reflection for instance. It can be based upon dds or six images as well\n     * as prefiltered data.\n     * @param rootUrl defines the url of the texture or the root name of the six images\n     * @param sceneOrEngine defines the scene or engine the texture is attached to\n     * @param extensionsOrOptions defines the suffixes add to the picture name in case six images are in use like _px.jpg or set of all options to create the cube texture\n     * @param noMipmap defines if mipmaps should be created or not\n     * @param files defines the six files to load for the different faces in that order: px, py, pz, nx, ny, nz\n     * @param onLoad defines a callback triggered at the end of the file load if no errors occurred\n     * @param onError defines a callback triggered in case of error during load\n     * @param format defines the internal format to use for the texture once loaded\n     * @param prefiltered defines whether or not the texture is created from prefiltered data\n     * @param forcedExtension defines the extensions to use (force a special type of file to load) in case it is different from the file name\n     * @param createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary\n     * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness\n     * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness\n     * @param loaderOptions options to be passed to the loader\n     * @param useSRGBBuffer Defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU) (default: false)\n     * @returns the cube texture\n     */\n    constructor(\n        rootUrl: string,\n        sceneOrEngine: Scene | AbstractEngine,\n        extensionsOrOptions: Nullable<string[] | ICubeTextureCreationOptions> = null,\n        noMipmap: boolean = false,\n        files: Nullable<string[]> = null,\n        onLoad: Nullable<() => void> = null,\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\n        format: number = Constants.TEXTUREFORMAT_RGBA,\n        prefiltered = false,\n        forcedExtension: any = null,\n        createPolynomials: boolean = false,\n        lodScale: number = DefaultLodScale,\n        lodOffset: number = 0,\n        loaderOptions?: any,\n        useSRGBBuffer?: boolean\n    ) {\n        super(sceneOrEngine);\n\n        RegisterAbstractEngineCubeTexture();\n\n        this.name = rootUrl;\n        this.url = rootUrl;\n        this._noMipmap = noMipmap;\n        this.hasAlpha = false;\n        this.isCube = true;\n        this._textureMatrix = Matrix.Identity();\n        this.coordinatesMode = Texture.CUBIC_MODE;\n\n        let extensions: Nullable<string[]>;\n        let buffer: Nullable<ArrayBufferView> = null;\n\n        if (extensionsOrOptions !== null && !Array.isArray(extensionsOrOptions)) {\n            extensions = extensionsOrOptions.extensions ?? null;\n            this._noMipmap = extensionsOrOptions.noMipmap ?? false;\n            files = extensionsOrOptions.files ?? null;\n            buffer = extensionsOrOptions.buffer ?? null;\n            this._format = extensionsOrOptions.format ?? Constants.TEXTUREFORMAT_RGBA;\n            prefiltered = extensionsOrOptions.prefiltered ?? false;\n            forcedExtension = extensionsOrOptions.forcedExtension ?? null;\n            this._createPolynomials = extensionsOrOptions.createPolynomials ?? false;\n            this._lodScale = extensionsOrOptions.lodScale ?? DefaultLodScale;\n            this._lodOffset = extensionsOrOptions.lodOffset ?? 0;\n            this._loaderOptions = extensionsOrOptions.loaderOptions;\n            this._useSRGBBuffer = extensionsOrOptions.useSRGBBuffer;\n            this._sphericalPolynomialTargetSize = extensionsOrOptions.sphericalPolynomialTargetSize ?? 0;\n            onLoad = extensionsOrOptions.onLoad ?? null;\n            onError = extensionsOrOptions.onError ?? null;\n        } else {\n            this._noMipmap = noMipmap;\n            this._format = format;\n            this._createPolynomials = createPolynomials;\n            extensions = extensionsOrOptions;\n            this._loaderOptions = loaderOptions;\n            this._useSRGBBuffer = useSRGBBuffer;\n            this._lodScale = lodScale;\n            this._lodOffset = lodOffset;\n        }\n\n        if (!rootUrl && !files) {\n            return;\n        }\n\n        this.updateURL(rootUrl, forcedExtension, onLoad, prefiltered, onError, extensions, this.getScene()?.useDelayedTextureLoading, files, buffer);\n    }\n\n    /**\n     * Get the current class name of the texture useful for serialization or dynamic coding.\n     * @returns \"CubeTexture\"\n     */\n    public override getClassName(): string {\n        return \"CubeTexture\";\n    }\n\n    /**\n     * Update the url (and optional buffer) of this texture if url was null during construction.\n     * @param url the url of the texture\n     * @param forcedExtension defines the extension to use\n     * @param onLoad callback called when the texture is loaded  (defaults to null)\n     * @param prefiltered Defines whether the updated texture is prefiltered or not\n     * @param onError callback called if there was an error during the loading process (defaults to null)\n     * @param extensions defines the suffixes add to the picture name in case six images are in use like _px.jpg...\n     * @param delayLoad defines if the texture should be loaded now (false by default)\n     * @param files defines the six files to load for the different faces in that order: px, py, pz, nx, ny, nz\n     * @param buffer the buffer to use instead of loading from the url\n     */\n    public updateURL(\n        url: string,\n        forcedExtension: Nullable<string> = null,\n        onLoad: Nullable<() => void> = null,\n        prefiltered: boolean = false,\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\n        extensions: Nullable<string[]> = null,\n        delayLoad = false,\n        files: Nullable<string[]> = null,\n        buffer: Nullable<ArrayBufferView> = null\n    ): void {\n        if (!this.name || this.name.startsWith(\"data:\")) {\n            this.name = url;\n        }\n        this.url = url;\n\n        if (forcedExtension) {\n            this._forcedExtension = forcedExtension;\n        }\n\n        const lastDot = url.lastIndexOf(\".\");\n        const extension = forcedExtension ? forcedExtension : lastDot > -1 ? url.substring(lastDot).toLowerCase() : \"\";\n        const isDDS = extension.indexOf(\".dds\") === 0;\n        const isEnv = extension.indexOf(\".env\") === 0;\n        const isBasis = extension.indexOf(\".basis\") === 0;\n\n        if (isEnv) {\n            this.gammaSpace = false;\n            this._prefiltered = false;\n            this.anisotropicFilteringLevel = 1;\n        } else {\n            this._prefiltered = prefiltered;\n\n            if (prefiltered) {\n                this.gammaSpace = false;\n                this.anisotropicFilteringLevel = 1;\n            }\n        }\n\n        if (files) {\n            this._files = files;\n        } else {\n            if (!isBasis && !isEnv && !isDDS && !extensions) {\n                extensions = [\"_px.jpg\", \"_py.jpg\", \"_pz.jpg\", \"_nx.jpg\", \"_ny.jpg\", \"_nz.jpg\"];\n            }\n\n            this._files = this._files || [];\n            this._files.length = 0;\n\n            if (extensions) {\n                for (let index = 0; index < extensions.length; index++) {\n                    this._files.push(url + extensions[index]);\n                }\n                this._extensions = extensions;\n            }\n        }\n\n        this._buffer = buffer;\n\n        if (delayLoad) {\n            this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\n            this._delayedOnLoad = onLoad;\n            this._delayedOnError = onError;\n        } else {\n            this._loadTexture(onLoad, onError);\n        }\n    }\n\n    /**\n     * Delays loading of the cube texture\n     * @param forcedExtension defines the extension to use\n     */\n    public override delayLoad(forcedExtension?: string): void {\n        if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {\n            return;\n        }\n        if (forcedExtension) {\n            this._forcedExtension = forcedExtension;\n        }\n\n        this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\n        this._loadTexture(this._delayedOnLoad, this._delayedOnError);\n    }\n\n    /**\n     * Returns the reflection texture matrix\n     * @returns the reflection texture matrix\n     */\n    public override getReflectionTextureMatrix(): Matrix {\n        return this._textureMatrix;\n    }\n\n    /**\n     * Sets the reflection texture matrix\n     * @param value Reflection texture matrix\n     */\n    public setReflectionTextureMatrix(value: Matrix): void {\n        if (value.updateFlag === this._textureMatrix.updateFlag) {\n            return;\n        }\n\n        if (value.isIdentity() !== this._textureMatrix.isIdentity()) {\n            this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => mat.getActiveTextures().indexOf(this) !== -1);\n        }\n\n        this._textureMatrix = value;\n\n        if (!this.getScene()?.useRightHandedSystem) {\n            return;\n        }\n\n        const scale = TmpVectors.Vector3[0];\n        const quat = TmpVectors.Quaternion[0];\n        const trans = TmpVectors.Vector3[1];\n\n        this._textureMatrix.decompose(scale, quat, trans);\n\n        quat.z *= -1; // these two operations correspond to negating the x and y euler angles\n        quat.w *= -1;\n\n        Matrix.ComposeToRef(scale, quat, trans, this._textureMatrixRefraction);\n    }\n\n    /**\n     * Gets a suitable rotate/transform matrix when the texture is used for refraction.\n     * There's a separate function from getReflectionTextureMatrix because refraction requires a special configuration of the matrix in right-handed mode.\n     * @returns The refraction matrix\n     */\n    public override getRefractionTextureMatrix(): Matrix {\n        return this.getScene()?.useRightHandedSystem ? this._textureMatrixRefraction : this._textureMatrix;\n    }\n\n    private _loadTexture(onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {\n        const scene = this.getScene();\n        const oldTexture = this._texture;\n        this._texture = this._getFromCache(this.url, this._noMipmap, undefined, undefined, this._useSRGBBuffer, this.isCube);\n\n        const onLoadProcessing = () => {\n            this.onLoadObservable.notifyObservers(this);\n            if (oldTexture) {\n                oldTexture.dispose();\n                this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\n            }\n            if (onLoad) {\n                onLoad();\n            }\n        };\n\n        const errorHandler = (message?: string, exception?: any) => {\n            this._loadingError = true;\n            this._errorObject = { message, exception };\n            if (onError) {\n                onError(message, exception);\n            }\n            Texture.OnTextureLoadErrorObservable.notifyObservers(this);\n        };\n\n        if (!this._texture) {\n            if (this._prefiltered) {\n                this._texture = this._getEngine()!.createPrefilteredCubeTexture(\n                    this.url,\n                    scene,\n                    this._lodScale,\n                    this._lodOffset,\n                    onLoad,\n                    errorHandler,\n                    this._format,\n                    this._forcedExtension,\n                    this._createPolynomials,\n                    this._buffer\n                );\n            } else {\n                this._texture = this._getEngine()!.createCubeTexture(\n                    this.url,\n                    scene,\n                    this._files,\n                    this._noMipmap,\n                    onLoad,\n                    errorHandler,\n                    this._format,\n                    this._forcedExtension,\n                    false,\n                    this._lodScale,\n                    this._lodOffset,\n                    null,\n                    this._loaderOptions,\n                    !!this._useSRGBBuffer,\n                    this._buffer\n                );\n            }\n\n            this._texture?.onLoadedObservable.add(() => this.onLoadObservable.notifyObservers(this));\n        } else {\n            if (this._texture.isReady) {\n                TimingTools.SetImmediate(() => onLoadProcessing());\n            } else {\n                this._texture.onLoadedObservable.add(() => onLoadProcessing());\n            }\n        }\n    }\n\n    /**\n     * Makes a clone, or deep copy, of the cube texture\n     * @returns a new cube texture\n     */\n    public override clone(): CubeTexture {\n        let uniqueId = 0;\n\n        // Save the irradianceTexture before cloning. The irradianceTexture is\n        // stored on the InternalTexture (_texture._irradianceTexture), which may\n        // be shared between the source and clone when loaded from cache.\n        // BaseTexture.clone() returns null, so CopySource sets the shared\n        // irradianceTexture to null, losing it on both the original and the clone.\n        const savedIrradianceTexture = this.irradianceTexture;\n\n        const newCubeTexture = SerializationHelper.Clone(() => {\n            const cubeTexture = new CubeTexture(this.url, this.getScene() || this._getEngine()!, this._extensions, this._noMipmap, this._files);\n            uniqueId = cubeTexture.uniqueId;\n\n            return cubeTexture;\n        }, this);\n\n        newCubeTexture.uniqueId = uniqueId;\n\n        // Restore the irradianceTexture if it was cleared during cloning.\n        if (savedIrradianceTexture && !this.irradianceTexture) {\n            this.irradianceTexture = savedIrradianceTexture;\n        }\n\n        return newCubeTexture;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Creates a cube texture from an array of image urls\n * @param files defines an array of image urls\n * @param scene defines the hosting scene\n * @param noMipmap specifies if mip maps are not used\n * @returns a cube texture\n */\nexport function CubeTextureCreateFromImages(files: string[], scene: Scene, noMipmap?: boolean): CubeTexture {\n    let rootUrlKey = \"\";\n\n    for (const url of files) {\n        rootUrlKey += url;\n    }\n\n    return new CubeTexture(rootUrlKey, scene, null, noMipmap, files);\n}\n\n/**\n * Creates and return a texture created from prefilterd data by tools like IBL Baker or Lys.\n * @param url defines the url of the prefiltered texture\n * @param scene defines the scene the texture is attached to\n * @param forcedExtension defines the extension of the file if different from the url\n * @param createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary\n * @returns the prefiltered texture\n */\nexport function CubeTextureCreateFromPrefilteredData(url: string, scene: Scene, forcedExtension: any = null, createPolynomials: boolean = true): CubeTexture {\n    const oldValue = scene.useDelayedTextureLoading;\n    scene.useDelayedTextureLoading = false;\n\n    const result = new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);\n\n    scene.useDelayedTextureLoading = oldValue;\n\n    return result;\n}\n\n/**\n * Parses text to create a cube texture\n * @param parsedTexture define the serialized text to read from\n * @param scene defines the hosting scene\n * @param rootUrl defines the root url of the cube texture\n * @returns a cube texture\n */\nexport function CubeTextureParse(parsedTexture: any, scene: Scene, rootUrl: string): CubeTexture {\n    const texture = SerializationHelper.Parse(\n        () => {\n            let prefiltered: boolean = false;\n            if (parsedTexture.prefiltered) {\n                prefiltered = parsedTexture.prefiltered;\n            }\n            return new CubeTexture(\n                rootUrl + (parsedTexture.url ?? parsedTexture.name),\n                scene,\n                parsedTexture.extensions,\n                false,\n                parsedTexture.files || null,\n                null,\n                null,\n                undefined,\n                prefiltered,\n                parsedTexture.forcedExtension\n            );\n        },\n        parsedTexture,\n        scene\n    );\n\n    // Local Cubemaps\n    if (parsedTexture.boundingBoxPosition) {\n        texture.boundingBoxPosition = Vector3.FromArray(parsedTexture.boundingBoxPosition);\n    }\n    if (parsedTexture.boundingBoxSize) {\n        texture.boundingBoxSize = Vector3.FromArray(parsedTexture.boundingBoxSize);\n    }\n\n    // Animations\n    if (parsedTexture.animations) {\n        for (let animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {\n            const parsedAnimation = parsedTexture.animations[animationIndex];\n            const internalClass = GetClass(\"BABYLON.Animation\");\n            if (internalClass) {\n                texture.animations.push(internalClass.Parse(parsedAnimation));\n            }\n        }\n    }\n\n    return texture;\n}\n\n/**\n * Register side effects for cubeTexture.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterCubeTexture(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    CubeTexture.CreateFromImages = CubeTextureCreateFromImages;\n    CubeTexture.CreateFromPrefilteredData = CubeTextureCreateFromPrefilteredData;\n    CubeTexture.Parse = CubeTextureParse;\n\n    Texture._CubeTextureParser = CubeTextureParse;\n\n    // Some exporters relies on Tools.Instantiate\n    RegisterClass(\"BABYLON.CubeTexture\", CubeTexture);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type IblCdfGenerator } from \"./iblCdfGenerator\";\r\n\r\n/**\r\n * Defines the IBL CDF Generator scene component responsible for generating CDF maps for a given IBL.\r\n */\r\nexport class IblCdfGeneratorSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_IBLCDFGENERATOR;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this._updateIblSource();\r\n        this._newIblObserver = this.scene.onEnvironmentTextureChangedObservable.add(this._updateIblSource.bind(this));\r\n        this.scene.addIsReadyCheck(this);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        this.scene.onEnvironmentTextureChangedObservable.remove(this._newIblObserver);\r\n        this.scene.removeIsReadyCheck(this);\r\n    }\r\n\r\n    /**\r\n     * @returns true once the CDF generator's procedural textures and effects are ready.\r\n     * Used by `Scene.isReady` so that `executeWhenReady` waits for the CDF maps to be\r\n     * generated before declaring the scene ready to render.\r\n     */\r\n    public isReady(): boolean {\r\n        const generator = this.scene._iblCdfGenerator;\r\n        // If there's no generator, or no environment texture for it to consume,\r\n        // there's nothing to wait for - report ready so Scene.isReady() doesn't stall.\r\n        if (!generator || !this.scene.environmentTexture) {\r\n            return true;\r\n        }\r\n        return !!generator.isReady();\r\n    }\r\n\r\n    private _updateIblSource(): void {\r\n        if (this.scene.iblCdfGenerator && this.scene.environmentTexture) {\r\n            this.scene.iblCdfGenerator.iblSource = this.scene.environmentTexture;\r\n        }\r\n    }\r\n\r\n    private _newIblObserver: Nullable<Observer<Nullable<BaseTexture>>> = null;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for iblCdfGeneratorSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param iblCdfGeneratorClass The IblCdfGenerator class to register the component for\r\n */\r\nexport function RegisterIblCdfGeneratorSceneComponent(iblCdfGeneratorClass: typeof IblCdfGenerator): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"iblCdfGenerator\", {\r\n        get: function (this: Scene) {\r\n            return this._iblCdfGenerator;\r\n        },\r\n        set: function (this: Scene, value: Nullable<IblCdfGenerator>) {\r\n            if (value) {\r\n                this._iblCdfGenerator = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.enableIblCdfGenerator = function (): Nullable<IblCdfGenerator> {\r\n        if (this._iblCdfGenerator) {\r\n            return this._iblCdfGenerator;\r\n        }\r\n\r\n        this._iblCdfGenerator = new iblCdfGeneratorClass(this);\r\n        if (!this._iblCdfGenerator.isSupported) {\r\n            this._iblCdfGenerator = null;\r\n            return null;\r\n        }\r\n        if (this.environmentTexture) {\r\n            this._iblCdfGenerator.iblSource = this.environmentTexture;\r\n        }\r\n        return this._iblCdfGenerator;\r\n    };\r\n\r\n    Scene.prototype.disableIblCdfGenerator = function (): void {\r\n        if (!this._iblCdfGenerator) {\r\n            return;\r\n        }\r\n\r\n        this._iblCdfGenerator.dispose();\r\n        this._iblCdfGenerator = null;\r\n    };\r\n\r\n    iblCdfGeneratorClass._SceneComponentInitialization = (scene: Scene) => {\r\n        // Register the CDF generator component to the scene.\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_IBLCDFGENERATOR) as IblCdfGeneratorSceneComponent;\r\n        if (!component) {\r\n            component = new IblCdfGeneratorSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","import { Constants } from \"../Engines/constants\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\nimport { type Scene } from \"../scene\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type TextureSize } from \"../Materials/Textures/textureCreationOptions\";\r\nimport { ProceduralTexture, type IProceduralTextureCreationOptions } from \"../Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { PostProcess, type PostProcessOptions } from \"../PostProcesses/postProcess.pure\";\r\nimport { Vector3, Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { CubeTexture } from \"../Materials/Textures/cubeTexture.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { type Nullable } from \"../types\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { _RetryWithInterval } from \"../Misc/timingTools\";\r\nimport { RegisterIblCdfGeneratorSceneComponent } from \"./iblCdfGeneratorSceneComponent.pure\";\r\n\r\n/**\r\n * Build cdf maps to be used for IBL importance sampling.\r\n */\r\nexport class IblCdfGenerator {\r\n    private _scene: Nullable<Scene>;\r\n    private _engine: AbstractEngine;\r\n\r\n    private _cdfyPT: ProceduralTexture;\r\n    private _cdfxPT: ProceduralTexture;\r\n    private _icdfPT: Nullable<ProceduralTexture>;\r\n    private _scaledLuminancePT: ProceduralTexture;\r\n    private _dominantDirectionPT: ProceduralTexture;\r\n    private _iblSource: Nullable<BaseTexture>;\r\n    private _dummyTexture: RawTexture;\r\n    private _iblSourceLoadUnsubscribe: Nullable<() => void> = null;\r\n    private _iblSourceReadyRetryObserver: Nullable<() => void> = null;\r\n\r\n    private _cachedDominantDirection: Nullable<Vector3> = null;\r\n\r\n    /**\r\n     * Returns whether the CDF renderer is supported by the current engine\r\n     */\r\n    public get isSupported(): boolean {\r\n        const engine = EngineStore.LastCreatedEngine;\r\n        if (!engine) {\r\n            return false;\r\n        }\r\n        return engine.getCaps().texelFetch;\r\n    }\r\n\r\n    /**\r\n     * Gets the IBL source texture being used by the CDF renderer\r\n     */\r\n    public get iblSource(): Nullable<BaseTexture> {\r\n        return this._iblSource;\r\n    }\r\n\r\n    /**\r\n     * Sets the IBL source texture to be used by the CDF renderer.\r\n     * This will trigger recreation of the CDF assets.\r\n     */\r\n    public set iblSource(source: Nullable<BaseTexture>) {\r\n        if (this._iblSource === source) {\r\n            return;\r\n        }\r\n\r\n        this._clearIblSourceReadinessObservers();\r\n        this._disposeTextures();\r\n        this._iblSource = source;\r\n\r\n        if (!source) {\r\n            return;\r\n        }\r\n\r\n        const recreateFromObservedSourceIfReady = () => {\r\n            if (this._iblSource !== source || !this._isIblSourceReady(source)) {\r\n                return;\r\n            }\r\n\r\n            this._clearIblSourceReadinessObservers();\r\n            this._recreateAssetsFromNewIbl();\r\n        };\r\n\r\n        if (this._isIblSourceReady(source)) {\r\n            this._recreateAssetsFromNewIbl();\r\n            return;\r\n        }\r\n\r\n        if (source instanceof Texture) {\r\n            const observer = source.onLoadObservable.addOnce(recreateFromObservedSourceIfReady);\r\n            if (observer) {\r\n                this._iblSourceLoadUnsubscribe = () => source.onLoadObservable.remove(observer);\r\n            }\r\n        } else if (source instanceof CubeTexture) {\r\n            const observer = source.onLoadObservable.addOnce(recreateFromObservedSourceIfReady);\r\n            if (observer) {\r\n                this._iblSourceLoadUnsubscribe = () => source.onLoadObservable.remove(observer);\r\n            }\r\n        }\r\n\r\n        this._iblSourceReadyRetryObserver = _RetryWithInterval(\r\n            () => this._iblSource !== source || this._isIblSourceReady(source),\r\n            recreateFromObservedSourceIfReady,\r\n            undefined,\r\n            16,\r\n            30000,\r\n            false\r\n        );\r\n    }\r\n\r\n    private _isIblSourceReady(source: BaseTexture): boolean {\r\n        if (!source.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        if (!source.isCube) {\r\n            return true;\r\n        }\r\n\r\n        const internalTexture = source.getInternalTexture();\r\n        return !!internalTexture && internalTexture.isReady;\r\n    }\r\n\r\n    private _clearIblSourceReadinessObservers() {\r\n        this._iblSourceReadyRetryObserver?.();\r\n        this._iblSourceReadyRetryObserver = null;\r\n\r\n        this._iblSourceLoadUnsubscribe?.();\r\n        this._iblSourceLoadUnsubscribe = null;\r\n    }\r\n\r\n    private _recreateAssetsFromNewIbl() {\r\n        if (this._debugPass) {\r\n            this._debugPass.dispose();\r\n        }\r\n\r\n        this._createTextures();\r\n\r\n        if (this._debugPass) {\r\n            // Recreate the debug pass because of the new textures\r\n            this._createDebugPass();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Return the cumulative distribution function (CDF) texture\r\n     * @returns Return the cumulative distribution function (CDF) texture\r\n     */\r\n    public getIcdfTexture(): Texture {\r\n        return this._icdfPT ? this._icdfPT : this._dummyTexture;\r\n    }\r\n\r\n    /** Enable the debug view for this pass */\r\n    public debugEnabled: boolean = false;\r\n    private _debugPass: PostProcess;\r\n    private _debugSizeParams: Vector4 = new Vector4(0.0, 0.0, 1.0, 1.0);\r\n\r\n    /**\r\n     * Sets params that control the position and scaling of the debug display on the screen.\r\n     * @param x Screen X offset of the debug display (0-1)\r\n     * @param y Screen Y offset of the debug display (0-1)\r\n     * @param widthScale X scale of the debug display (0-1)\r\n     * @param heightScale Y scale of the debug display (0-1)\r\n     */\r\n    public setDebugDisplayParams(x: number, y: number, widthScale: number, heightScale: number) {\r\n        this._debugSizeParams.set(x, y, widthScale, heightScale);\r\n    }\r\n\r\n    /**\r\n     * The name of the debug pass post process\r\n     */\r\n    public get debugPassName(): string {\r\n        return this._debugPassName;\r\n    }\r\n    private _debugPassName: string = \"CDF Debug\";\r\n\r\n    /**\r\n     * Gets the debug pass post process\r\n     * @returns The post process\r\n     */\r\n    public getDebugPassPP(): PostProcess {\r\n        if (!this._debugPass) {\r\n            this._createDebugPass();\r\n        }\r\n        return this._debugPass;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"IblCdfGeneratorSceneComponentSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * Instanciates the CDF renderer\r\n     * @param sceneOrEngine Scene to attach to\r\n     * @returns The CDF renderer\r\n     */\r\n    constructor(sceneOrEngine: Nullable<Scene | AbstractEngine>) {\r\n        if (sceneOrEngine) {\r\n            if (IblCdfGenerator._IsScene(sceneOrEngine)) {\r\n                this._scene = sceneOrEngine;\r\n            } else {\r\n                this._engine = sceneOrEngine;\r\n            }\r\n        } else {\r\n            this._scene = EngineStore.LastCreatedScene;\r\n        }\r\n        if (this._scene) {\r\n            this._engine = this._scene.getEngine();\r\n        }\r\n        if (!this.isSupported) {\r\n            Logger.Warn(\"CDF renderer is not supported by the current engine.\");\r\n            return;\r\n        }\r\n        const blackPixels = new Uint16Array([0, 0, 0, 255]);\r\n        this._dummyTexture = new RawTexture(blackPixels, 1, 1, Constants.TEXTUREFORMAT_RGBA, sceneOrEngine, false, false, undefined, Constants.TEXTURETYPE_HALF_FLOAT);\r\n        if (this._scene) {\r\n            RegisterIblCdfGeneratorSceneComponent(IblCdfGenerator);\r\n            IblCdfGenerator._SceneComponentInitialization(this._scene);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Observable that triggers when the CDF renderer is ready\r\n     */\r\n    public onGeneratedObservable: Observable<void> = new Observable<void>();\r\n\r\n    /**\r\n     * Observable that triggers when CDF texture references change.\r\n     * It is raised after disposing textures (so fallback ICDF can be used)\r\n     * and after creating new textures (so consumers can rebind immediately).\r\n     */\r\n    public onTextureChangedObservable: Observable<void> = new Observable<void>();\r\n\r\n    private _createTextures() {\r\n        const size: TextureSize = this._iblSource ? { width: this._iblSource.getSize().width, height: this._iblSource.getSize().height } : { width: 1, height: 1 };\r\n        if (!this._iblSource) {\r\n            this._iblSource = RawTexture.CreateRTexture(\r\n                new Uint8Array([255]),\r\n                1,\r\n                1,\r\n                this._engine,\r\n                false,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n            );\r\n            this._iblSource.name = \"Placeholder IBL Source\";\r\n        }\r\n        if (this._iblSource.isCube) {\r\n            size.width *= 4;\r\n            size.height *= 2;\r\n            // Force the resolution to be a power of 2 because we rely on the\r\n            // auto-mipmap generation for the scaled luminance texture to produce\r\n            // a 1x1 mip that represents the true average pixel intensity of the IBL.\r\n            size.width = 1 << Math.floor(Math.log2(size.width));\r\n            size.height = 1 << Math.floor(Math.log2(size.height));\r\n        }\r\n\r\n        const isWebGPU = this._engine.isWebGPU;\r\n        // r32float mip generation requires filtered sampling. On WebGPU this hard-fails bind group\r\n        // validation (and drops the whole command buffer) when the optional `float32-filterable` adapter\r\n        // feature is absent, so fall back to r16float there. WebGL2/Native also depend on an extension\r\n        // (OES_texture_float_linear) for float32 filtering, but when it's missing they silently degrade\r\n        // to nearest sampling instead of hard-failing, so no fallback is needed there.\r\n        const scaledLuminanceType = isWebGPU && !this._engine.getCaps().textureFloatLinearFiltering ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_FLOAT;\r\n        // Create CDF maps (Cumulative Distribution Function) to assist in importance sampling\r\n        const cdfOptions: IProceduralTextureCreationOptions = {\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: false,\r\n            format: Constants.TEXTUREFORMAT_R,\r\n            type: Constants.TEXTURETYPE_FLOAT,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            gammaSpace: false,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../ShadersWGSL/iblCdfx.fragment\"), import(\"../ShadersWGSL/iblCdfy.fragment\"), import(\"../ShadersWGSL/iblScaledLuminance.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../Shaders/iblCdfx.fragment\"), import(\"../Shaders/iblCdfy.fragment\"), import(\"../Shaders/iblScaledLuminance.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n        const icdfOptions: IProceduralTextureCreationOptions = {\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: false,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            gammaSpace: false,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../ShadersWGSL/iblIcdf.fragment\"), import(\"../ShadersWGSL/iblDominantDirection.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../Shaders/iblIcdf.fragment\"), import(\"../Shaders/iblDominantDirection.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n        this._cdfyPT = new ProceduralTexture(\"cdfyTexture\", { width: size.width, height: size.height + 1 }, \"iblCdfy\", this._scene, cdfOptions, false, false);\r\n        this._cdfyPT.autoClear = false;\r\n        this._cdfyPT.setTexture(\"iblSource\", this._iblSource);\r\n        this._cdfyPT.setInt(\"iblHeight\", size.height);\r\n        this._cdfyPT.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        this._cdfyPT.refreshRate = 0;\r\n        if (this._iblSource.isCube) {\r\n            this._cdfyPT.defines = \"#define IBL_USE_CUBE_MAP\\n\";\r\n        }\r\n\r\n        this._cdfxPT = new ProceduralTexture(\"cdfxTexture\", { width: size.width + 1, height: 1 }, \"iblCdfx\", this._scene, cdfOptions, false, false);\r\n        this._cdfxPT.autoClear = false;\r\n        this._cdfxPT.setTexture(\"cdfy\", this._cdfyPT);\r\n        this._cdfxPT.refreshRate = 0;\r\n        this._cdfxPT.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n\r\n        this._scaledLuminancePT = new ProceduralTexture(\r\n            \"iblScaledLuminance\",\r\n            { width: size.width, height: size.height },\r\n            \"iblScaledLuminance\",\r\n            this._scene,\r\n            // This texture is trilinear-filtered and mip-mapped, so it must use a filterable format;\r\n            // see scaledLuminanceType above for why r16float is only used as a WebGPU fallback.\r\n            { ...cdfOptions, type: scaledLuminanceType, samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, generateMipMaps: true },\r\n            true,\r\n            false\r\n        );\r\n        this._scaledLuminancePT.autoClear = false;\r\n        this._scaledLuminancePT.setTexture(\"iblSource\", this._iblSource);\r\n        this._scaledLuminancePT.setInt(\"iblHeight\", size.height);\r\n        this._scaledLuminancePT.setInt(\"iblWidth\", size.width);\r\n        this._scaledLuminancePT.refreshRate = 0;\r\n        if (this._iblSource.isCube) {\r\n            this._scaledLuminancePT.defines = \"#define IBL_USE_CUBE_MAP\\n\";\r\n        }\r\n        this._icdfPT = new ProceduralTexture(\"icdfTexture\", { width: size.width, height: size.height }, \"iblIcdf\", this._scene, icdfOptions, false, false);\r\n        this._icdfPT.autoClear = false;\r\n        this._icdfPT.setTexture(\"cdfy\", this._cdfyPT);\r\n        this._icdfPT.setTexture(\"cdfx\", this._cdfxPT);\r\n        this._icdfPT.setTexture(\"iblSource\", this._iblSource);\r\n        this._icdfPT.setTexture(\"scaledLuminanceSampler\", this._scaledLuminancePT);\r\n        this._icdfPT.refreshRate = 0;\r\n        this._icdfPT.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        this._icdfPT.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        if (this._iblSource.isCube) {\r\n            this._icdfPT.defines = \"#define IBL_USE_CUBE_MAP\\n\";\r\n        }\r\n        // Once the textures are generated, notify that they are ready to use.\r\n        this._icdfPT.onGeneratedObservable.addOnce(() => {\r\n            this.onGeneratedObservable.notifyObservers();\r\n        });\r\n\r\n        this._dominantDirectionPT = new ProceduralTexture(\"iblDominantDirection\", { width: 1, height: 1 }, \"iblDominantDirection\", this._scene, icdfOptions, false, false);\r\n        this._dominantDirectionPT.autoClear = false;\r\n        this._dominantDirectionPT.setTexture(\"icdfSampler\", this._icdfPT);\r\n        this._dominantDirectionPT.refreshRate = 0;\r\n        this._dominantDirectionPT.defines = \"#define NUM_SAMPLES 32u\\n\";\r\n\r\n        this.onTextureChangedObservable.notifyObservers();\r\n    }\r\n\r\n    private _disposeTextures() {\r\n        this._cdfyPT?.dispose();\r\n        this._cdfxPT?.dispose();\r\n        this._icdfPT?.dispose();\r\n        this._scaledLuminancePT?.dispose();\r\n        this._dominantDirectionPT?.dispose();\r\n        this._icdfPT = null;\r\n\r\n        this.onTextureChangedObservable.notifyObservers();\r\n    }\r\n\r\n    private _createDebugPass() {\r\n        if (this._debugPass) {\r\n            this._debugPass.dispose();\r\n        }\r\n        const isWebGPU = this._engine.isWebGPU;\r\n        const debugOptions: PostProcessOptions = {\r\n            width: this._engine.getRenderWidth(),\r\n            height: this._engine.getRenderHeight(),\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine: this._engine,\r\n            textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            uniforms: [\"sizeParams\"],\r\n            samplers: [\"cdfy\", \"icdf\", \"cdfx\", \"iblSource\"],\r\n            defines: this._iblSource?.isCube ? \"#define IBL_USE_CUBE_MAP\\n\" : \"\",\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializations: (useWebGPU: boolean, list: Promise<any>[]) => {\r\n                if (useWebGPU) {\r\n                    list.push(import(\"../ShadersWGSL/iblCdfDebug.fragment\"));\r\n                } else {\r\n                    list.push(import(\"../Shaders/iblCdfDebug.fragment\"));\r\n                }\r\n            },\r\n        };\r\n        this._debugPass = new PostProcess(this._debugPassName, \"iblCdfDebug\", debugOptions);\r\n        const debugEffect = this._debugPass.getEffect();\r\n        if (debugEffect) {\r\n            debugEffect.defines = this._iblSource?.isCube ? \"#define IBL_USE_CUBE_MAP\\n\" : \"\";\r\n        }\r\n        if (this._iblSource?.isCube) {\r\n            this._debugPass.updateEffect(\"#define IBL_USE_CUBE_MAP\\n\");\r\n        }\r\n        this._debugPass.onApplyObservable.add((effect) => {\r\n            effect.setTexture(\"cdfy\", this._cdfyPT);\r\n            effect.setTexture(\"icdf\", this._icdfPT);\r\n            effect.setTexture(\"cdfx\", this._cdfxPT);\r\n            effect.setTexture(\"iblSource\", this._iblSource);\r\n            effect.setFloat4(\"sizeParams\", this._debugSizeParams.x, this._debugSizeParams.y, this._debugSizeParams.z, this._debugSizeParams.w);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Checks if the CDF renderer is ready\r\n     * @returns true if the CDF renderer is ready\r\n     */\r\n    public isReady() {\r\n        return (\r\n            this._iblSource &&\r\n            this._iblSource.name !== \"Placeholder IBL Source\" &&\r\n            this._iblSource.isReady() &&\r\n            this._cdfyPT &&\r\n            this._cdfyPT.isReady() &&\r\n            this._icdfPT &&\r\n            this._icdfPT.isReady() &&\r\n            this._cdfxPT &&\r\n            this._cdfxPT.isReady() &&\r\n            this._scaledLuminancePT &&\r\n            this._scaledLuminancePT.isReady()\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Explicitly trigger generation of CDF maps when they are ready to render.\r\n     * @returns Promise that resolves when the CDF maps are rendered.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public renderWhenReady(): Promise<void> {\r\n        this._cachedDominantDirection = null;\r\n        // Even if a IBL source must be set before calling this function, _icdfPT may not yet be created because the creation may be asynchronous (see @set iblSource).\r\n        const icdfPTPromise = new Promise((resolve, reject) => {\r\n            _RetryWithInterval(\r\n                () => !!this._icdfPT,\r\n                () => resolve(void 0),\r\n                () => reject(new Error(\"Waiting for _icdfPT creation failed\"))\r\n            );\r\n        });\r\n\r\n        // eslint-disable-next-line github/no-then, @typescript-eslint/promise-function-async\r\n        return icdfPTPromise.then(() => {\r\n            const icdfTexture = this._icdfPT;\r\n            const promises: Array<Promise<void>> = [];\r\n            const renderTargets: Array<ProceduralTexture> = [this._cdfyPT, this._cdfxPT, this._scaledLuminancePT, icdfTexture!];\r\n            for (const target of renderTargets) {\r\n                promises.push(\r\n                    new Promise((resolve) => {\r\n                        if (target.isReady()) {\r\n                            resolve();\r\n                        } else {\r\n                            target.getEffect().executeWhenCompiled(() => {\r\n                                resolve();\r\n                            });\r\n                        }\r\n                    })\r\n                );\r\n            }\r\n            // eslint-disable-next-line github/no-then\r\n            return Promise.all(promises).then(() => {\r\n                for (const target of renderTargets) {\r\n                    target.render();\r\n                }\r\n            });\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Finds the average direction of the highest intensity areas of the IBL source\r\n     * @returns Async promise that resolves to the dominant direction of the IBL source\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public findDominantDirection(): Promise<Vector3> {\r\n        if (this._cachedDominantDirection) {\r\n            return Promise.resolve(this._cachedDominantDirection);\r\n        }\r\n        return new Promise((resolve) => {\r\n            this._dominantDirectionPT.onGeneratedObservable.addOnce(() => {\r\n                const data = new Float32Array(4);\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                this._dominantDirectionPT.readPixels(0, 0, data, true)!.then(() => {\r\n                    const dominantDirection = new Vector3(data[0], data[1], data[2]);\r\n                    this._cachedDominantDirection = dominantDirection;\r\n                    resolve(dominantDirection);\r\n                });\r\n            });\r\n            if (this.isReady()) {\r\n                if (this._dominantDirectionPT.isReady()) {\r\n                    this._dominantDirectionPT.render();\r\n                } else {\r\n                    this._dominantDirectionPT.getEffect().executeWhenCompiled(() => {\r\n                        this._dominantDirectionPT.render();\r\n                    });\r\n                }\r\n            } else {\r\n                this.onGeneratedObservable.addOnce(() => {\r\n                    if (this._dominantDirectionPT.isReady()) {\r\n                        this._dominantDirectionPT.render();\r\n                    } else {\r\n                        this._dominantDirectionPT.getEffect().executeWhenCompiled(() => {\r\n                            this._dominantDirectionPT.render();\r\n                        });\r\n                    }\r\n                });\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Disposes the CDF renderer and associated resources\r\n     */\r\n    public dispose() {\r\n        this._clearIblSourceReadinessObservers();\r\n        this._disposeTextures();\r\n        this._dummyTexture.dispose();\r\n        if (this._debugPass) {\r\n            this._debugPass.dispose();\r\n        }\r\n        this.onGeneratedObservable.clear();\r\n    }\r\n\r\n    private static _IsScene(sceneOrEngine: Scene | AbstractEngine): sceneOrEngine is Scene {\r\n        return sceneOrEngine.getClassName() === \"Scene\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Camera, type FrameGraph, type FrameGraphObjectList, type FrameGraphTextureHandle, type InternalTexture, type Mesh, type Nullable, type Observer } from \"core/index\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { IBLShadowsPluginMaterial } from \"core/Rendering/IBLShadows/iblShadowsPluginMaterial.pure\";\r\nimport { IsIBLShadowsReceiverCompatible } from \"core/Rendering/IBLShadows/iblShadowsMaterialCompatibility.pure\";\r\nimport { FrameGraphIblShadowsAccumulationTask } from \"./iblShadows/iblShadowsAccumulationTask\";\r\nimport { FrameGraphIblShadowsSpatialBlurTask } from \"./iblShadows/iblShadowsSpatialBlurTask\";\r\nimport { FrameGraphIblShadowsTracingTask } from \"./iblShadows/iblShadowsTracingTask\";\r\nimport { FrameGraphIblShadowsVoxelizationTask } from \"./iblShadows/iblShadowsVoxelizationTask\";\r\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { CubeTexture } from \"core/Materials/Textures/cubeTexture.pure\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\nimport { Observable } from \"core/Misc/observable.pure\";\r\nimport { IblCdfGenerator } from \"core/Rendering/iblCdfGenerator\";\r\nimport { RegisterIblCdfGeneratorSceneComponent } from \"core/Rendering/iblCdfGeneratorSceneComponent.pure\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Composite task that owns the individual IBL shadows frame graph tasks.\r\n * The frame graph remains flat internally, but this task groups the pipeline\r\n * and owns the child task implementation details.\r\n */\r\nexport class FrameGraphIblShadowsRendererTask extends FrameGraphTask {\r\n    /** Final frame-graph texture handle produced by the task. */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    private readonly _voxelizationTask: FrameGraphIblShadowsVoxelizationTask;\r\n    private readonly _tracingTask: FrameGraphIblShadowsTracingTask;\r\n    private readonly _spatialBlurTask: FrameGraphIblShadowsSpatialBlurTask;\r\n    private readonly _accumulationTask: FrameGraphIblShadowsAccumulationTask;\r\n    private _dependenciesResolved = false;\r\n    private _shadowOpacity = 1.0;\r\n    private readonly _materialsWithRenderPlugin: Material[] = [];\r\n    private readonly _outputTextureReadyObservable = new Observable<InternalTexture>();\r\n    private _lastNotifiedOutputTexture: Nullable<InternalTexture> = null;\r\n    private _observedEnvironmentTexture: Nullable<Texture | CubeTexture> = null;\r\n    private _observedEnvironmentTextureUnsubscribe: Nullable<() => void> = null;\r\n    private _lastImportedIcdfTexture: Nullable<InternalTexture> = null;\r\n    private _lastImportedEnvironmentTexture: Nullable<InternalTexture> = null;\r\n    private _lastImportedBlueNoiseTexture: Nullable<InternalTexture> = null;\r\n    private readonly _blueNoiseTexture: Texture;\r\n    private _cameraViewChangedObserver: Nullable<Observer<any>> = null;\r\n    private _cdfTextureChangedObserver: Nullable<Observer<any>> = null;\r\n    private _cdfGeneratedObserver: Nullable<Observer<any>> = null;\r\n    private _environmentTextureChangedObserver: Nullable<Observer<any>> = null;\r\n    private _beforeRenderDependencyObserver: Nullable<Observer<any>> = null;\r\n    private _beforeRenderOutputReadyObserver: Nullable<Observer<any>> = null;\r\n    private _blueNoiseLoadObserver: Nullable<Observer<any>> = null;\r\n    private _texturesAllocatedObserver: Nullable<Observer<any>> = null;\r\n    private _voxelizationCompleteObserver: Nullable<Observer<any>> = null;\r\n\r\n    /**\r\n     * Gets the class name.\r\n     * @returns The class name.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FrameGraphIblShadowsRendererTask\";\r\n    }\r\n\r\n    public override get name() {\r\n        return this._name;\r\n    }\r\n\r\n    public override set name(value: string) {\r\n        this._name = value;\r\n        if (this._voxelizationTask) {\r\n            this._voxelizationTask.name = `${value} Voxelization`;\r\n        }\r\n        if (this._tracingTask) {\r\n            this._tracingTask.name = `${value} Tracing`;\r\n        }\r\n        if (this._spatialBlurTask) {\r\n            this._spatialBlurTask.name = `${value} Blur`;\r\n        }\r\n        if (this._accumulationTask) {\r\n            this._accumulationTask.name = `${value} Accumulation`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Whether the task is disabled.\r\n     */\r\n\r\n    public override get disabled(): boolean {\r\n        return this._disabled;\r\n    }\r\n\r\n    public override set disabled(value: boolean) {\r\n        this._disabled = value;\r\n        if (!this._disabled && this._dependenciesResolved) {\r\n            this._accumulationTask.reset = true;\r\n        }\r\n        this._applyMaterialPluginParameters();\r\n    }\r\n\r\n    // ------ Common properties ------\r\n\r\n    /** Camera used by the tracing stage. */\r\n    public get camera(): Camera {\r\n        return this._tracingTask.camera!;\r\n    }\r\n\r\n    /** Camera used by the tracing stage. */\r\n    public set camera(value: Camera) {\r\n        this._setCamera(value);\r\n    }\r\n\r\n    /** Object list used by voxelization. */\r\n    public get objectList(): FrameGraphObjectList {\r\n        return this._voxelizationTask.objectList;\r\n    }\r\n\r\n    /** Object list used by voxelization. */\r\n    public set objectList(value: FrameGraphObjectList) {\r\n        if (this._voxelizationTask.objectList === value) {\r\n            return;\r\n        }\r\n\r\n        this._voxelizationTask.objectList = value;\r\n        this._voxelizationTask.updateSceneBounds();\r\n        this._voxelizationTask.requestVoxelizationUpdate();\r\n        this._accumulationTask.reset = true;\r\n    }\r\n\r\n    /**\r\n     * Depth texture handle used by tracing and blur.\r\n     * This should be the screen-space depth of all objects in the scene\r\n     * that will receive shadows.\r\n     * It is important that this texture stores 32-bit depth values to avoid artifacts.\r\n     */\r\n    public depthTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * World-space normal texture handle used by tracing and blur.\r\n     * This should store the world-space normals of all objects in the scene\r\n     * that will receive shadows. Each component should be normalized to [0, 1] rather than [-1, 1].\r\n     * Recommended to be 16-bit floating point though 8-bit unsigned byte can be used with minimal\r\n     * loss in quality.\r\n     */\r\n    public normalTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Position texture handle used by accumulation.\r\n     * This should store the world-space position of all objects in the scene\r\n     * that will receive shadows.\r\n     * Should be stored as 16-bit floating point.\r\n     */\r\n    public positionTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Velocity texture handle used by accumulation.\r\n     * This should store the linear velocity per pixel of all objects in the scene\r\n     * that will receive shadows.\r\n     * Should be stored as 16-bit floating point.\r\n     */\r\n    public velocityTexture: FrameGraphTextureHandle;\r\n\r\n    // ------ Tracing properties ------\r\n\r\n    /** Number of tracing sample directions. */\r\n    public get sampleDirections(): number {\r\n        return this._tracingTask.sampleDirections;\r\n    }\r\n\r\n    /** Number of tracing sample directions. */\r\n    public set sampleDirections(value: number) {\r\n        this._tracingTask.sampleDirections = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Whether traced shadows preserve environment color. */\r\n    public get coloredShadows(): boolean {\r\n        return this._tracingTask.coloredShadows;\r\n    }\r\n\r\n    /** Whether traced shadows preserve environment color. */\r\n    public set coloredShadows(value: boolean) {\r\n        if (this._tracingTask.coloredShadows === value) {\r\n            return;\r\n        }\r\n        this._tracingTask.coloredShadows = value;\r\n        this._applyMaterialPluginParameters();\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Opacity of voxel-traced shadows. */\r\n    public get voxelShadowOpacity(): number {\r\n        return this._tracingTask.voxelShadowOpacity;\r\n    }\r\n\r\n    /** Opacity of voxel-traced shadows. */\r\n    public set voxelShadowOpacity(value: number) {\r\n        this._tracingTask.voxelShadowOpacity = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Opacity of screen-space shadows. */\r\n    public get ssShadowOpacity(): number {\r\n        return this._tracingTask.ssShadowOpacity;\r\n    }\r\n\r\n    /** Opacity of screen-space shadows. */\r\n    public set ssShadowOpacity(value: number) {\r\n        this._tracingTask.ssShadowOpacity = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Number of screen-space shadow samples. */\r\n    public get ssShadowSampleCount(): number {\r\n        return this._tracingTask.ssShadowSampleCount;\r\n    }\r\n\r\n    /** Number of screen-space shadow samples. */\r\n    public set ssShadowSampleCount(value: number) {\r\n        this._tracingTask.ssShadowSampleCount = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Stride used by screen-space shadow sampling. */\r\n    public get ssShadowStride(): number {\r\n        return this._tracingTask.ssShadowStride;\r\n    }\r\n\r\n    /** Stride used by screen-space shadow sampling. */\r\n    public set ssShadowStride(value: number) {\r\n        this._tracingTask.ssShadowStride = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Distance scale used by screen-space shadow tracing. */\r\n    public get ssShadowDistanceScale(): number {\r\n        return this._tracingTask.ssShadowDistanceScale;\r\n    }\r\n\r\n    /** Distance scale used by screen-space shadow tracing. */\r\n    public set ssShadowDistanceScale(value: number) {\r\n        this._tracingTask.ssShadowDistanceScale = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Thickness scale used by screen-space shadow tracing. */\r\n    public get ssShadowThicknessScale(): number {\r\n        return this._tracingTask.ssShadowThicknessScale;\r\n    }\r\n\r\n    /** Thickness scale used by screen-space shadow tracing. */\r\n    public set ssShadowThicknessScale(value: number) {\r\n        this._tracingTask.ssShadowThicknessScale = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Voxel tracing normal bias. */\r\n    public get voxelNormalBias(): number {\r\n        return this._tracingTask.voxelNormalBias;\r\n    }\r\n\r\n    /** Voxel tracing normal bias. */\r\n    public set voxelNormalBias(value: number) {\r\n        this._tracingTask.voxelNormalBias = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Voxel tracing direction bias. */\r\n    public get voxelDirectionBias(): number {\r\n        return this._tracingTask.voxelDirectionBias;\r\n    }\r\n\r\n    /** Voxel tracing direction bias. */\r\n    public set voxelDirectionBias(value: number) {\r\n        this._tracingTask.voxelDirectionBias = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Environment rotation in radians. */\r\n    public get envRotation(): number {\r\n        return this._tracingTask.envRotation;\r\n    }\r\n\r\n    /** Environment rotation in radians. */\r\n    public set envRotation(value: number) {\r\n        this._tracingTask.envRotation = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    // ------ Accumulation properties ------\r\n\r\n    /** Temporal shadow remanence while moving. */\r\n    public get shadowRemanence(): number {\r\n        return this._accumulationTask.remanence;\r\n    }\r\n\r\n    /** Temporal shadow remanence while moving. */\r\n    public set shadowRemanence(value: number) {\r\n        this._accumulationTask.remanence = value;\r\n    }\r\n\r\n    /** Final material shadow opacity. */\r\n    public get shadowOpacity(): number {\r\n        return this._shadowOpacity;\r\n    }\r\n\r\n    /** Final material shadow opacity. */\r\n    public set shadowOpacity(value: number) {\r\n        this._shadowOpacity = Math.max(0, Math.min(value, 1));\r\n        this._applyMaterialPluginParameters();\r\n    }\r\n\r\n    // ------ Voxelization properties ------\r\n\r\n    /** Voxelization resolution exponent. */\r\n    public get resolutionExp(): number {\r\n        return this._voxelizationTask.resolutionExp;\r\n    }\r\n\r\n    /** Voxelization resolution exponent. */\r\n    public set resolutionExp(value: number) {\r\n        this._voxelizationTask.resolutionExp = value;\r\n        this.resetAccumulation();\r\n    }\r\n\r\n    /** Voxelization refresh rate. */\r\n    public get refreshRate(): number {\r\n        return this._voxelizationTask.refreshRate;\r\n    }\r\n\r\n    /** Voxelization refresh rate. */\r\n    public set refreshRate(value: number) {\r\n        this._voxelizationTask.refreshRate = value;\r\n    }\r\n\r\n    /** Whether tri-planar voxelization is used. */\r\n    public get triPlanarVoxelization(): boolean {\r\n        return this._voxelizationTask.triPlanarVoxelization;\r\n    }\r\n\r\n    /** Whether tri-planar voxelization is used. */\r\n    public set triPlanarVoxelization(value: boolean) {\r\n        this._voxelizationTask.triPlanarVoxelization = value;\r\n    }\r\n\r\n    /** Current world-space voxel grid size. */\r\n    public get voxelGridSize(): number {\r\n        return this._voxelizationTask.voxelGridSize;\r\n    }\r\n\r\n    /** True when the accumulated output texture is ready. */\r\n    public get outputTextureReady(): boolean {\r\n        return !!this._getAccumulationOutputTexture()?.isReady;\r\n    }\r\n\r\n    /** Notifies when the accumulated output texture becomes ready. */\r\n    public get onOutputTextureReadyObservable(): Observable<InternalTexture> {\r\n        return this._outputTextureReadyObservable;\r\n    }\r\n\r\n    // ------ Public methods ------\r\n\r\n    /** Triggers a voxelization refresh on the next eligible frame. */\r\n    public updateVoxelization(): void {\r\n        this._voxelizationTask.requestVoxelizationUpdate();\r\n    }\r\n\r\n    /** Recomputes the voxelization scene bounds from the current object list. */\r\n    public updateSceneBounds(): void {\r\n        this._voxelizationTask.updateSceneBounds();\r\n    }\r\n\r\n    /** Resets temporal accumulation. */\r\n    public resetAccumulation(): void {\r\n        this._accumulationTask.reset = true;\r\n    }\r\n\r\n    /**\r\n     * Adds one or more materials that should receive IBL shadows.\r\n     * @param material The material or materials to register. If omitted, all scene materials are added.\r\n     */\r\n    public addShadowReceivingMaterial(material?: Material | Material[]): void {\r\n        if (!material) {\r\n            for (const sceneMaterial of this._frameGraph.scene.materials) {\r\n                this._addShadowReceivingMaterialInternal(sceneMaterial);\r\n            }\r\n        } else if (Array.isArray(material)) {\r\n            for (const sceneMaterial of material) {\r\n                this._addShadowReceivingMaterialInternal(sceneMaterial);\r\n            }\r\n        } else {\r\n            this._addShadowReceivingMaterialInternal(material);\r\n        }\r\n\r\n        this._applyMaterialPluginParameters();\r\n    }\r\n\r\n    /**\r\n     * Removes one or more materials from IBL shadow reception.\r\n     * @param material The material or materials to unregister.\r\n     */\r\n    public removeShadowReceivingMaterial(material: Material | Material[]): void {\r\n        const materials = Array.isArray(material) ? material : [material];\r\n        for (const mat of materials) {\r\n            const index = this._materialsWithRenderPlugin.indexOf(mat);\r\n            if (index !== -1) {\r\n                this._materialsWithRenderPlugin.splice(index, 1);\r\n            }\r\n\r\n            const plugin = mat.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name);\r\n            if (plugin) {\r\n                plugin.isEnabled = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    /** Clears all registered shadow-receiving materials. */\r\n    public clearShadowReceivingMaterials(): void {\r\n        for (const mat of this._materialsWithRenderPlugin) {\r\n            const plugin = mat.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name);\r\n            if (plugin) {\r\n                plugin.isEnabled = false;\r\n            }\r\n        }\r\n\r\n        this._materialsWithRenderPlugin.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Adds one or more meshes to the voxelization object list.\r\n     * @param mesh The mesh or meshes to add.\r\n     */\r\n    public addShadowCastingMesh(mesh: Mesh | Mesh[]): void {\r\n        const meshes = Array.isArray(mesh) ? mesh : [mesh];\r\n        const objectMeshes = this._voxelizationTask.objectList.meshes as Mesh[];\r\n        for (const currentMesh of meshes) {\r\n            if (currentMesh && objectMeshes.indexOf(currentMesh) === -1) {\r\n                objectMeshes.push(currentMesh);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes one or more meshes from the voxelization object list.\r\n     * @param mesh The mesh or meshes to remove.\r\n     */\r\n    public removeShadowCastingMesh(mesh: Mesh | Mesh[]): void {\r\n        const meshes = Array.isArray(mesh) ? mesh : [mesh];\r\n        const objectMeshes = this._voxelizationTask.objectList.meshes as Mesh[];\r\n        for (const currentMesh of meshes) {\r\n            const index = objectMeshes.indexOf(currentMesh);\r\n            if (index !== -1) {\r\n                objectMeshes.splice(index, 1);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** Clears all shadow-casting meshes from the voxelization object list. */\r\n    public clearShadowCastingMeshes(): void {\r\n        const objectMeshes = this._voxelizationTask.objectList.meshes as Mesh[];\r\n        objectMeshes.length = 0;\r\n    }\r\n\r\n    // ------ Framework overrides ------\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public override initAsync(): Promise<unknown> {\r\n        this._frameGraph.scene.enableIblCdfGenerator();\r\n\r\n        // Don't poll for shadow dependencies here.  _tryEnableShadowsTasks() is called\r\n        // in record() (where it imports a placeholder ICDF if the real one isn't ready yet,\r\n        // preventing any \"handle not found\" errors) and by _beforeRenderDependencyObserver\r\n        // on every frame.  Shadows enable automatically once the CDF, environment texture,\r\n        // and blue-noise texture are all ready — no timeout involved.git pu\r\n        return Promise.resolve();\r\n    }\r\n\r\n    public override isReady(): boolean {\r\n        return this._voxelizationTask.isReady() && this._tracingTask.isReady() && this._spatialBlurTask.isReady() && this._accumulationTask.isReady();\r\n    }\r\n\r\n    /**\r\n     * Records the parent task.\r\n     * Child tasks record the actual passes.\r\n     */\r\n    public override record(): void {\r\n        if (this.depthTexture === undefined || this.normalTexture === undefined || this.positionTexture === undefined || this.velocityTexture === undefined) {\r\n            throw new Error(`FrameGraphIblShadowsRendererTask \"${this.name}\": depthTexture, normalTexture, positionTexture and velocityTexture are required`);\r\n        }\r\n\r\n        this._lastImportedIcdfTexture = null;\r\n        this._lastImportedEnvironmentTexture = null;\r\n        this._lastImportedBlueNoiseTexture = null;\r\n\r\n        this._tryEnableShadowsTasks();\r\n\r\n        // Set sub-task texture inputs (these are set here because handles may not be available at construction time)\r\n        this._tracingTask.depthTexture = this.depthTexture;\r\n        this._tracingTask.normalTexture = this.normalTexture;\r\n        this._spatialBlurTask.depthTexture = this.depthTexture;\r\n        this._spatialBlurTask.normalTexture = this.normalTexture;\r\n        this._accumulationTask.positionTexture = this.positionTexture;\r\n        this._accumulationTask.velocityTexture = this.velocityTexture;\r\n\r\n        this._voxelizationTask.record();\r\n        this._tracingTask.record();\r\n        this._spatialBlurTask.record();\r\n        this._accumulationTask.record();\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n\r\n    /**\r\n     * Disposes the task and owned resources.\r\n     */\r\n    public override dispose(): void {\r\n        this._disposeObservers();\r\n        this._voxelizationTask.dispose();\r\n        this._tracingTask.dispose();\r\n        this._spatialBlurTask.dispose();\r\n        this._accumulationTask.dispose();\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Creates a new IBL shadows composite task.\r\n     * @param name The task name.\r\n     * @param frameGraph The owning frame graph.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        RegisterIblCdfGeneratorSceneComponent(IblCdfGenerator);\r\n\r\n        this._voxelizationTask = new FrameGraphIblShadowsVoxelizationTask(`${name} Voxelization`, frameGraph);\r\n\r\n        this._tracingTask = new FrameGraphIblShadowsTracingTask(`${name} Tracing`, frameGraph);\r\n        this._tracingTask.voxelGridTexture = this._voxelizationTask.outputVoxelGridTexture;\r\n        this._tracingTask.worldScaleMatrix = this._voxelizationTask.worldScaleMatrix;\r\n        this._tracingTask.voxelizationTask = this._voxelizationTask;\r\n\r\n        this._spatialBlurTask = new FrameGraphIblShadowsSpatialBlurTask(`${name} Blur`, frameGraph);\r\n        this._spatialBlurTask.sourceTexture = this._tracingTask.outputTexture;\r\n        this._spatialBlurTask.voxelizationTask = this._voxelizationTask;\r\n\r\n        this._accumulationTask = new FrameGraphIblShadowsAccumulationTask(`${name} Accumulation`, frameGraph);\r\n        this._accumulationTask.sourceTexture = this._spatialBlurTask.outputTexture;\r\n        this._accumulationTask.voxelizationTask = this._voxelizationTask;\r\n\r\n        this.outputTexture = this._accumulationTask.outputTexture;\r\n        this._blueNoiseTexture = new Texture(\r\n            Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/blue_noise/blue_noise_rgb.png\"),\r\n            frameGraph.scene,\r\n            false,\r\n            true,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE\r\n        );\r\n\r\n        this._initialize();\r\n    }\r\n\r\n    private _disposeDependencyObservers(): void {\r\n        this._observedEnvironmentTextureUnsubscribe?.();\r\n        this._observedEnvironmentTextureUnsubscribe = null;\r\n        this._observedEnvironmentTexture = null;\r\n    }\r\n\r\n    private _disposeObservers(): void {\r\n        this._disposeDependencyObservers();\r\n        this._tracingTask.camera?.onViewMatrixChangedObservable.remove(this._cameraViewChangedObserver);\r\n        this._frameGraph.scene.iblCdfGenerator?.onTextureChangedObservable.remove(this._cdfTextureChangedObserver);\r\n        this._frameGraph.scene.iblCdfGenerator?.onGeneratedObservable.remove(this._cdfGeneratedObserver);\r\n        this._frameGraph.scene.onEnvironmentTextureChangedObservable.remove(this._environmentTextureChangedObserver);\r\n        this._frameGraph.scene.onBeforeRenderObservable.remove(this._beforeRenderDependencyObserver);\r\n        this._frameGraph.scene.onBeforeRenderObservable.remove(this._beforeRenderOutputReadyObserver);\r\n        this._blueNoiseTexture.onLoadObservable.remove(this._blueNoiseLoadObserver);\r\n        this.onTexturesAllocatedObservable.remove(this._texturesAllocatedObserver);\r\n        this._voxelizationTask.onVoxelizationCompleteObservable.remove(this._voxelizationCompleteObserver);\r\n\r\n        this._cameraViewChangedObserver = null;\r\n        this._cdfTextureChangedObserver = null;\r\n        this._cdfGeneratedObserver = null;\r\n        this._environmentTextureChangedObserver = null;\r\n        this._beforeRenderDependencyObserver = null;\r\n        this._beforeRenderOutputReadyObserver = null;\r\n        this._blueNoiseLoadObserver = null;\r\n        this._texturesAllocatedObserver = null;\r\n        this._voxelizationCompleteObserver = null;\r\n        this._blueNoiseTexture.dispose();\r\n    }\r\n\r\n    private _setCamera(camera: Camera): void {\r\n        const currentCamera = this._tracingTask.camera;\r\n        if (currentCamera === camera && this._cameraViewChangedObserver !== null) {\r\n            return;\r\n        }\r\n\r\n        if (currentCamera && this._cameraViewChangedObserver) {\r\n            currentCamera.onViewMatrixChangedObservable.remove(this._cameraViewChangedObserver);\r\n            this._cameraViewChangedObserver = null;\r\n        }\r\n\r\n        this._tracingTask.camera = camera;\r\n        this._cameraViewChangedObserver = camera.onViewMatrixChangedObservable.add(() => {\r\n            this._accumulationTask.isMoving = true;\r\n        });\r\n        this._accumulationTask.reset = true;\r\n    }\r\n\r\n    private _observeEnvironmentTexture(): void {\r\n        const env = this._frameGraph.scene.environmentTexture;\r\n        const currentEnvironmentTexture = env instanceof Texture || env instanceof CubeTexture ? env : null;\r\n\r\n        if (currentEnvironmentTexture === this._observedEnvironmentTexture) {\r\n            return;\r\n        }\r\n\r\n        this._observedEnvironmentTextureUnsubscribe?.();\r\n        this._observedEnvironmentTextureUnsubscribe = null;\r\n        this._observedEnvironmentTexture = currentEnvironmentTexture;\r\n\r\n        if (currentEnvironmentTexture instanceof Texture) {\r\n            const observer = currentEnvironmentTexture.onLoadObservable.add(this._onEnvironmentTextureLoaded);\r\n            if (observer) {\r\n                this._observedEnvironmentTextureUnsubscribe = () => currentEnvironmentTexture.onLoadObservable.remove(observer);\r\n            }\r\n        } else if (currentEnvironmentTexture instanceof CubeTexture) {\r\n            const observer = currentEnvironmentTexture.onLoadObservable.add(this._onEnvironmentTextureLoaded);\r\n            if (observer) {\r\n                this._observedEnvironmentTextureUnsubscribe = () => currentEnvironmentTexture.onLoadObservable.remove(observer);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getEnvironmentTextureInternal(): Nullable<InternalTexture> {\r\n        const currentEnvironmentTexture = this._frameGraph.scene.environmentTexture;\r\n\r\n        if (!currentEnvironmentTexture || !currentEnvironmentTexture.isReadyOrNotBlocking()) {\r\n            return null;\r\n        }\r\n\r\n        const internalTexture = currentEnvironmentTexture.getInternalTexture();\r\n        return internalTexture?.isReady ? internalTexture : null;\r\n    }\r\n\r\n    private _getAccumulationOutputTexture(): Nullable<InternalTexture> {\r\n        try {\r\n            return this._frameGraph.textureManager.getTextureFromHandle(this._accumulationTask.outputTexture);\r\n        } catch {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    private _notifyIfOutputTextureReady(): void {\r\n        const outputTexture = this._getAccumulationOutputTexture();\r\n        if (!outputTexture?.isReady || this._lastNotifiedOutputTexture === outputTexture) {\r\n            return;\r\n        }\r\n\r\n        this._lastNotifiedOutputTexture = outputTexture;\r\n        this._outputTextureReadyObservable.notifyObservers(outputTexture);\r\n    }\r\n\r\n    private _applyMaterialPluginParameters(): void {\r\n        const accumulationTexture = this._getAccumulationOutputTexture();\r\n        for (const material of this._materialsWithRenderPlugin) {\r\n            const plugin = material.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name);\r\n            if (!plugin) {\r\n                continue;\r\n            }\r\n\r\n            if (accumulationTexture && accumulationTexture.isReady) {\r\n                plugin.iblShadowsTexture = accumulationTexture;\r\n            }\r\n\r\n            plugin.shadowOpacity = this._shadowOpacity;\r\n            plugin.isColored = this._tracingTask.coloredShadows;\r\n            plugin.isEnabled = !this._disabled && this._dependenciesResolved && !!accumulationTexture;\r\n        }\r\n    }\r\n\r\n    private _addShadowReceivingMaterialInternal(material: Material): void {\r\n        if (!IsIBLShadowsReceiverCompatible(material) || this._materialsWithRenderPlugin.indexOf(material) !== -1) {\r\n            return;\r\n        }\r\n\r\n        const plugin = material.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name);\r\n        if (!plugin) {\r\n            new IBLShadowsPluginMaterial(material);\r\n        }\r\n\r\n        this._materialsWithRenderPlugin.push(material);\r\n    }\r\n\r\n    private readonly _onEnvironmentTextureLoaded = () => {\r\n        this._tryEnableShadowsTasks();\r\n    };\r\n\r\n    private _tryEnableShadowsTasks(): boolean {\r\n        const scene = this._frameGraph.scene;\r\n        const icdfTexture = scene.iblCdfGenerator?.getIcdfTexture().getInternalTexture();\r\n        const environmentTexture = this._getEnvironmentTextureInternal();\r\n        const blueNoiseInternalTexture = this._blueNoiseTexture.getInternalTexture();\r\n\r\n        // Always import whatever textures are currently available so that their handles\r\n        // remain valid in the texture manager across rebuilds.  After a frameGraph.clear()\r\n        // all texture entries are wiped — without this, stale handles left in the tracing\r\n        // task would cause _computeTextureLifespan to throw \"texture handle not found\"\r\n        // even when CDF generation is still in progress.  Importing the 1×1 placeholder\r\n        // ICDF (returned by getIcdfTexture() when real generation hasn't completed) is\r\n        // harmless: _dependenciesResolved stays false, the tracing execute function clears\r\n        // to white, and the real texture is swapped in the moment CDF is ready.\r\n        const icdfChanged = this._lastImportedIcdfTexture !== icdfTexture;\r\n        if (icdfChanged && icdfTexture) {\r\n            this._tracingTask.icdfTexture = this._frameGraph.textureManager.importTexture(`ICDF Texture`, icdfTexture, this._tracingTask.icdfTexture);\r\n            this._lastImportedIcdfTexture = icdfTexture;\r\n        }\r\n\r\n        const environmentChanged = this._lastImportedEnvironmentTexture !== environmentTexture;\r\n        if (environmentChanged || !environmentTexture) {\r\n            if (environmentTexture) {\r\n                this._tracingTask.environmentTexture = this._frameGraph.textureManager.importTexture(\r\n                    `Environment Texture`,\r\n                    environmentTexture,\r\n                    this._tracingTask.environmentTexture\r\n                );\r\n                this._lastImportedEnvironmentTexture = environmentTexture;\r\n            } else {\r\n                // No environment texture (null or not yet ready) — clear any stale handle so\r\n                // it is not added to pass dependencies where _computeTextureLifespan would\r\n                // fail to find it.  This happens when a new IBL is dragged in: the environment\r\n                // texture temporarily returns null from _getEnvironmentTextureInternal() while\r\n                // it is still loading, but _lastImportedEnvironmentTexture was reset to null in\r\n                // record(), so environmentChanged is false and the old stale handle is never\r\n                // cleared — unless we add the || !environmentTexture guard here.\r\n                this._tracingTask.environmentTexture = undefined;\r\n                this._lastImportedEnvironmentTexture = null;\r\n            }\r\n        }\r\n\r\n        const blueNoiseChanged = this._lastImportedBlueNoiseTexture !== blueNoiseInternalTexture;\r\n        if (blueNoiseChanged || !blueNoiseInternalTexture) {\r\n            if (blueNoiseInternalTexture) {\r\n                this._tracingTask.blueNoiseTexture = this._frameGraph.textureManager.importTexture(\r\n                    `Blue Noise Texture`,\r\n                    blueNoiseInternalTexture,\r\n                    this._tracingTask.blueNoiseTexture\r\n                );\r\n                this._lastImportedBlueNoiseTexture = blueNoiseInternalTexture;\r\n            } else {\r\n                // Same null-guard as environment above.\r\n                this._tracingTask.blueNoiseTexture = undefined;\r\n                this._lastImportedBlueNoiseTexture = null;\r\n            }\r\n        }\r\n\r\n        // Only mark dependencies as resolved when all textures are genuinely ready.\r\n        //\r\n        // Use IblCdfGenerator.isReady() rather than icdfTexture?.isReady (the raw\r\n        // InternalTexture property).  For a ProceduralTexture render target, InternalTexture\r\n        // .isReady can remain false after onGeneratedObservable fires — it reflects GPU\r\n        // texture object creation state, not whether the ICDF effect has been compiled and\r\n        // the texture has been rendered.  IblCdfGenerator.isReady() checks _icdfPT.isReady()\r\n        // (ProceduralTexture readiness = effect compiled AND rendered at least once) plus all\r\n        // intermediate CDF textures.  Without this, _dependenciesResolved never flips to true\r\n        // when a new model is loaded (the CDF regenerates but isReady stays false), so the\r\n        // IBLShadowsPluginMaterial plugin is never enabled on any material.\r\n        const cdfReady = scene.iblCdfGenerator?.isReady() ?? false;\r\n        const ready = cdfReady && !!environmentTexture?.isReady && !!blueNoiseInternalTexture?.isReady;\r\n        if (!ready) {\r\n            if (this._dependenciesResolved) {\r\n                this._dependenciesResolved = false;\r\n            }\r\n            return false;\r\n        }\r\n\r\n        if (!this._dependenciesResolved) {\r\n            this._dependenciesResolved = true;\r\n            if (!this._disabled) {\r\n                this._accumulationTask.reset = true;\r\n            }\r\n            this._disposeDependencyObservers();\r\n        } else if (icdfChanged || environmentChanged || blueNoiseChanged) {\r\n            this._accumulationTask.reset = true;\r\n        }\r\n\r\n        this._applyMaterialPluginParameters();\r\n\r\n        return true;\r\n    }\r\n\r\n    private _initialize(): void {\r\n        const scene = this._frameGraph.scene;\r\n\r\n        this._voxelizationCompleteObserver = this._voxelizationTask.onVoxelizationCompleteObservable.add(() => {\r\n            this._tracingTask.voxelGridTexture = this._voxelizationTask.outputVoxelGridTexture;\r\n            this._accumulationTask.reset = true;\r\n        });\r\n\r\n        this._cdfTextureChangedObserver =\r\n            scene.iblCdfGenerator?.onTextureChangedObservable.add(() => {\r\n                this._lastImportedIcdfTexture = null;\r\n                this._accumulationTask.reset = true;\r\n            }) ?? null;\r\n\r\n        this._cdfGeneratedObserver =\r\n            scene.iblCdfGenerator?.onGeneratedObservable.add(() => {\r\n                this._lastImportedIcdfTexture = null;\r\n                this._tryEnableShadowsTasks();\r\n            }) ?? null;\r\n\r\n        this._environmentTextureChangedObserver = scene.onEnvironmentTextureChangedObservable.add(() => {\r\n            this._lastImportedEnvironmentTexture = null;\r\n            this._dependenciesResolved = false;\r\n            this._observeEnvironmentTexture();\r\n            this._applyMaterialPluginParameters();\r\n            this._tryEnableShadowsTasks();\r\n        });\r\n\r\n        this._observeEnvironmentTexture();\r\n\r\n        if (scene.environmentTexture?.isReadyOrNotBlocking()) {\r\n            this._tryEnableShadowsTasks();\r\n        }\r\n\r\n        this._blueNoiseLoadObserver = this._blueNoiseTexture.onLoadObservable.add(() => {\r\n            this._tryEnableShadowsTasks();\r\n        });\r\n\r\n        this._beforeRenderDependencyObserver = scene.onBeforeRenderObservable.add(() => {\r\n            this._tryEnableShadowsTasks();\r\n        });\r\n\r\n        this._beforeRenderOutputReadyObserver = scene.onBeforeRenderObservable.add(() => {\r\n            this._notifyIfOutputTextureReady();\r\n        });\r\n\r\n        this._tryEnableShadowsTasks();\r\n\r\n        this._texturesAllocatedObserver = this.onTexturesAllocatedObservable.add(() => {\r\n            this._applyMaterialPluginParameters();\r\n            this._notifyIfOutputTextureReady();\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    type Camera,\r\n    type FrameGraph,\r\n    type FrameGraphObjectList,\r\n    type FrameGraphTextureHandle,\r\n    type NodeRenderGraphBuildState,\r\n    type NodeRenderGraphConnectionPoint,\r\n    type Scene,\r\n} from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { FrameGraphIblShadowsRendererTask } from \"core/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that implements IBL (image-based lighting) shadows using voxel tracing.\r\n */\r\nexport class NodeRenderGraphIblShadowsRendererBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphIblShadowsRendererTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphIblShadowsRendererBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"depth\", NodeRenderGraphBlockConnectionPointTypes.TextureScreenDepth);\r\n        this.registerInput(\"normal\", NodeRenderGraphBlockConnectionPointTypes.TextureWorldNormal);\r\n        this.registerInput(\"position\", NodeRenderGraphBlockConnectionPointTypes.TextureWorldPosition);\r\n        this.registerInput(\"velocity\", NodeRenderGraphBlockConnectionPointTypes.TextureLinearVelocity);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this.registerInput(\"objects\", NodeRenderGraphBlockConnectionPointTypes.ObjectList);\r\n\r\n        this._addDependenciesInput();\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.Texture);\r\n\r\n        this._frameGraphTask = new FrameGraphIblShadowsRendererTask(name, frameGraph);\r\n    }\r\n\r\n    // ------ Tracing properties ------\r\n\r\n    /** Number of tracing sample directions */\r\n    @editableInPropertyPage(\"Sample directions\", PropertyTypeForEdition.Int, \"TRACING\", { min: 1, max: 16 })\r\n    public get sampleDirections(): number {\r\n        return this._frameGraphTask.sampleDirections;\r\n    }\r\n\r\n    public set sampleDirections(value: number) {\r\n        this._frameGraphTask.sampleDirections = value;\r\n    }\r\n\r\n    /** Whether traced shadows preserve environment color */\r\n    @editableInPropertyPage(\"Colored shadows\", PropertyTypeForEdition.Boolean, \"TRACING\")\r\n    public get coloredShadows(): boolean {\r\n        return this._frameGraphTask.coloredShadows;\r\n    }\r\n\r\n    public set coloredShadows(value: boolean) {\r\n        this._frameGraphTask.coloredShadows = value;\r\n    }\r\n\r\n    /** Opacity of voxel-traced shadows */\r\n    @editableInPropertyPage(\"Voxel shadow opacity\", PropertyTypeForEdition.Float, \"TRACING\", { min: 0, max: 1 })\r\n    public get voxelShadowOpacity(): number {\r\n        return this._frameGraphTask.voxelShadowOpacity;\r\n    }\r\n\r\n    public set voxelShadowOpacity(value: number) {\r\n        this._frameGraphTask.voxelShadowOpacity = value;\r\n    }\r\n\r\n    /** Opacity of screen-space shadows */\r\n    @editableInPropertyPage(\"SS shadow opacity\", PropertyTypeForEdition.Float, \"TRACING\", { min: 0, max: 1 })\r\n    public get ssShadowOpacity(): number {\r\n        return this._frameGraphTask.ssShadowOpacity;\r\n    }\r\n\r\n    public set ssShadowOpacity(value: number) {\r\n        this._frameGraphTask.ssShadowOpacity = value;\r\n    }\r\n\r\n    /** Number of screen-space shadow samples */\r\n    @editableInPropertyPage(\"SS sample count\", PropertyTypeForEdition.Int, \"TRACING\", { min: 1, max: 64 })\r\n    public get ssShadowSampleCount(): number {\r\n        return this._frameGraphTask.ssShadowSampleCount;\r\n    }\r\n\r\n    public set ssShadowSampleCount(value: number) {\r\n        this._frameGraphTask.ssShadowSampleCount = value;\r\n    }\r\n\r\n    /** Stride used by screen-space shadow sampling */\r\n    @editableInPropertyPage(\"SS stride\", PropertyTypeForEdition.Int, \"TRACING\", { min: 1, max: 32 })\r\n    public get ssShadowStride(): number {\r\n        return this._frameGraphTask.ssShadowStride;\r\n    }\r\n\r\n    public set ssShadowStride(value: number) {\r\n        this._frameGraphTask.ssShadowStride = value;\r\n    }\r\n\r\n    /** Distance scale used by screen-space shadow tracing */\r\n    @editableInPropertyPage(\"SS distance scale\", PropertyTypeForEdition.Float, \"TRACING\", { min: 0 })\r\n    public get ssShadowDistanceScale(): number {\r\n        return this._frameGraphTask.ssShadowDistanceScale;\r\n    }\r\n\r\n    public set ssShadowDistanceScale(value: number) {\r\n        this._frameGraphTask.ssShadowDistanceScale = value;\r\n    }\r\n\r\n    /** Thickness scale used by screen-space shadow tracing */\r\n    @editableInPropertyPage(\"SS thickness scale\", PropertyTypeForEdition.Float, \"TRACING\", { min: 0 })\r\n    public get ssShadowThicknessScale(): number {\r\n        return this._frameGraphTask.ssShadowThicknessScale;\r\n    }\r\n\r\n    public set ssShadowThicknessScale(value: number) {\r\n        this._frameGraphTask.ssShadowThicknessScale = value;\r\n    }\r\n\r\n    /** Voxel tracing normal bias */\r\n    @editableInPropertyPage(\"Normal bias\", PropertyTypeForEdition.Float, \"TRACING\", { min: 0 })\r\n    public get voxelNormalBias(): number {\r\n        return this._frameGraphTask.voxelNormalBias;\r\n    }\r\n\r\n    public set voxelNormalBias(value: number) {\r\n        this._frameGraphTask.voxelNormalBias = value;\r\n    }\r\n\r\n    /** Voxel tracing direction bias */\r\n    @editableInPropertyPage(\"Direction bias\", PropertyTypeForEdition.Float, \"TRACING\", { min: 0 })\r\n    public get voxelDirectionBias(): number {\r\n        return this._frameGraphTask.voxelDirectionBias;\r\n    }\r\n\r\n    public set voxelDirectionBias(value: number) {\r\n        this._frameGraphTask.voxelDirectionBias = value;\r\n    }\r\n\r\n    /** Environment rotation in radians */\r\n    @editableInPropertyPage(\"Env rotation\", PropertyTypeForEdition.Float, \"TRACING\")\r\n    public get envRotation(): number {\r\n        return this._frameGraphTask.envRotation;\r\n    }\r\n\r\n    public set envRotation(value: number) {\r\n        this._frameGraphTask.envRotation = value;\r\n    }\r\n\r\n    // ------ Accumulation properties ------\r\n\r\n    /** Temporal shadow remanence while moving */\r\n    @editableInPropertyPage(\"Shadow remanence\", PropertyTypeForEdition.Float, \"ACCUMULATION\", { min: 0, max: 1 })\r\n    public get shadowRemanence(): number {\r\n        return this._frameGraphTask.shadowRemanence;\r\n    }\r\n\r\n    public set shadowRemanence(value: number) {\r\n        this._frameGraphTask.shadowRemanence = value;\r\n    }\r\n\r\n    /** Final material shadow opacity */\r\n    @editableInPropertyPage(\"Shadow opacity\", PropertyTypeForEdition.Float, \"ACCUMULATION\", { min: 0, max: 1 })\r\n    public get shadowOpacity(): number {\r\n        return this._frameGraphTask.shadowOpacity;\r\n    }\r\n\r\n    public set shadowOpacity(value: number) {\r\n        this._frameGraphTask.shadowOpacity = value;\r\n    }\r\n\r\n    // ------ Voxelization properties ------\r\n\r\n    /** Voxelization resolution exponent (actual resolution is 2^value) */\r\n    @editableInPropertyPage(\"Resolution exp\", PropertyTypeForEdition.Int, \"VOXELIZATION\", { min: 1, max: 8 })\r\n    public get resolutionExp(): number {\r\n        return this._frameGraphTask.resolutionExp;\r\n    }\r\n\r\n    public set resolutionExp(value: number) {\r\n        this._frameGraphTask.resolutionExp = value;\r\n    }\r\n\r\n    /** Voxelization refresh rate (-1: manual, 0: every frame, N: skip N frames) */\r\n    @editableInPropertyPage(\"Refresh rate\", PropertyTypeForEdition.Int, \"VOXELIZATION\", { min: -1 })\r\n    public get refreshRate(): number {\r\n        return this._frameGraphTask.refreshRate;\r\n    }\r\n\r\n    public set refreshRate(value: number) {\r\n        this._frameGraphTask.refreshRate = value;\r\n    }\r\n\r\n    /** Whether tri-planar voxelization is used */\r\n    @editableInPropertyPage(\"Tri-planar\", PropertyTypeForEdition.Boolean, \"VOXELIZATION\")\r\n    public get triPlanarVoxelization(): boolean {\r\n        return this._frameGraphTask.triPlanarVoxelization;\r\n    }\r\n\r\n    public set triPlanarVoxelization(value: boolean) {\r\n        this._frameGraphTask.triPlanarVoxelization = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphIblShadowsRendererBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the depth texture input component\r\n     */\r\n    public get depth(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal texture input component\r\n     */\r\n    public get normal(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the position texture input component\r\n     */\r\n    public get position(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the velocity texture input component\r\n     */\r\n    public get velocity(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the objects input component\r\n     */\r\n    public get objects(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.depthTexture = this.depth.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.normalTexture = this.normal.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.positionTexture = this.position.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.velocityTexture = this.velocity.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n        this._frameGraphTask.objectList = this.objects.connectedPoint?.value as FrameGraphObjectList;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.sampleDirections = ${this.sampleDirections};`);\r\n        codes.push(`${this._codeVariableName}.coloredShadows = ${this.coloredShadows};`);\r\n        codes.push(`${this._codeVariableName}.voxelShadowOpacity = ${this.voxelShadowOpacity};`);\r\n        codes.push(`${this._codeVariableName}.ssShadowOpacity = ${this.ssShadowOpacity};`);\r\n        codes.push(`${this._codeVariableName}.ssShadowSampleCount = ${this.ssShadowSampleCount};`);\r\n        codes.push(`${this._codeVariableName}.ssShadowStride = ${this.ssShadowStride};`);\r\n        codes.push(`${this._codeVariableName}.ssShadowDistanceScale = ${this.ssShadowDistanceScale};`);\r\n        codes.push(`${this._codeVariableName}.ssShadowThicknessScale = ${this.ssShadowThicknessScale};`);\r\n        codes.push(`${this._codeVariableName}.voxelNormalBias = ${this.voxelNormalBias};`);\r\n        codes.push(`${this._codeVariableName}.voxelDirectionBias = ${this.voxelDirectionBias};`);\r\n        codes.push(`${this._codeVariableName}.envRotation = ${this.envRotation};`);\r\n        codes.push(`${this._codeVariableName}.shadowRemanence = ${this.shadowRemanence};`);\r\n        codes.push(`${this._codeVariableName}.shadowOpacity = ${this.shadowOpacity};`);\r\n        codes.push(`${this._codeVariableName}.resolutionExp = ${this.resolutionExp};`);\r\n        codes.push(`${this._codeVariableName}.refreshRate = ${this.refreshRate};`);\r\n        codes.push(`${this._codeVariableName}.triPlanarVoxelization = ${this.triPlanarVoxelization};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.sampleDirections = this.sampleDirections;\r\n        serializationObject.coloredShadows = this.coloredShadows;\r\n        serializationObject.voxelShadowOpacity = this.voxelShadowOpacity;\r\n        serializationObject.ssShadowOpacity = this.ssShadowOpacity;\r\n        serializationObject.ssShadowSampleCount = this.ssShadowSampleCount;\r\n        serializationObject.ssShadowStride = this.ssShadowStride;\r\n        serializationObject.ssShadowDistanceScale = this.ssShadowDistanceScale;\r\n        serializationObject.ssShadowThicknessScale = this.ssShadowThicknessScale;\r\n        serializationObject.voxelNormalBias = this.voxelNormalBias;\r\n        serializationObject.voxelDirectionBias = this.voxelDirectionBias;\r\n        serializationObject.envRotation = this.envRotation;\r\n        serializationObject.shadowRemanence = this.shadowRemanence;\r\n        serializationObject.shadowOpacity = this.shadowOpacity;\r\n        serializationObject.resolutionExp = this.resolutionExp;\r\n        serializationObject.refreshRate = this.refreshRate;\r\n        serializationObject.triPlanarVoxelization = this.triPlanarVoxelization;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        this.sampleDirections = serializationObject.sampleDirections;\r\n        this.coloredShadows = serializationObject.coloredShadows;\r\n        this.voxelShadowOpacity = serializationObject.voxelShadowOpacity;\r\n        this.ssShadowOpacity = serializationObject.ssShadowOpacity;\r\n        this.ssShadowSampleCount = serializationObject.ssShadowSampleCount;\r\n        this.ssShadowStride = serializationObject.ssShadowStride;\r\n        this.ssShadowDistanceScale = serializationObject.ssShadowDistanceScale;\r\n        this.ssShadowThicknessScale = serializationObject.ssShadowThicknessScale;\r\n        this.voxelNormalBias = serializationObject.voxelNormalBias;\r\n        this.voxelDirectionBias = serializationObject.voxelDirectionBias;\r\n        this.envRotation = serializationObject.envRotation;\r\n        this.shadowRemanence = serializationObject.shadowRemanence;\r\n        this.shadowOpacity = serializationObject.shadowOpacity;\r\n        this.resolutionExp = serializationObject.resolutionExp;\r\n        this.refreshRate = serializationObject.refreshRate;\r\n        this.triPlanarVoxelization = serializationObject.triPlanarVoxelization;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for iblShadowsRendererBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterIblShadowsRendererBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphIblShadowsRendererBlock\", NodeRenderGraphIblShadowsRendererBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene, type FrameGraph } from \"core/index\";\r\nimport { NodeRenderGraphBaseShadowGeneratorBlock } from \"./baseShadowGeneratorBlock\";\r\nimport { FrameGraphShadowGeneratorTask } from \"../../../Tasks/Rendering/shadowGeneratorTask\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block that generate shadows through a shadow generator\r\n */\r\nexport class NodeRenderGraphShadowGeneratorBlock extends NodeRenderGraphBaseShadowGeneratorBlock {\r\n    /**\r\n     * Create a new NodeRenderGraphShadowGeneratorBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._finalizeInputOutputRegistering();\r\n\r\n        this._frameGraphTask = new FrameGraphShadowGeneratorTask(this.name, frameGraph);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphShadowGeneratorBlock\";\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for shadowGeneratorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterShadowGeneratorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphShadowGeneratorBlock\", NodeRenderGraphShadowGeneratorBlock);\r\n}\r\n","import { type Camera, type FrameGraph, type FrameGraphTextureHandle, type Scene } from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { UtilityLayerRenderer } from \"core/Rendering/utilityLayerRenderer\";\r\n\r\n/**\r\n * Task used to render an utility layer.\r\n */\r\nexport class FrameGraphUtilityLayerRendererTask extends FrameGraphTask {\r\n    /**\r\n     * The target texture of the task.\r\n     */\r\n    public targetTexture: FrameGraphTextureHandle;\r\n\r\n    private _camera: Camera;\r\n    /**\r\n     * The camera used to render the utility layer.\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    public set camera(value: Camera) {\r\n        this._camera = value;\r\n\r\n        this.layer.setRenderCamera(value);\r\n        this.layer.utilityLayerScene.activeCamera = value;\r\n    }\r\n\r\n    /**\r\n     * The output texture of the task.\r\n     * This is the same texture as the target texture, but the handles are different!\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The utility layer renderer.\r\n     */\r\n    public readonly layer: UtilityLayerRenderer;\r\n\r\n    /**\r\n     * Creates a new utility layer renderer task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     * @param scene The scene the task belongs to.\r\n     * @param handleEvents If the utility layer should handle events.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, scene: Scene, handleEvents = true) {\r\n        super(name, frameGraph);\r\n\r\n        this.layer = new UtilityLayerRenderer(scene, handleEvents, true);\r\n        this.layer.utilityLayerScene._useCurrentFrameBuffer = true;\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphUtilityLayerRendererTask\";\r\n    }\r\n\r\n    public record(): void {\r\n        if (!this.targetTexture || !this.camera) {\r\n            throw new Error(`FrameGraphUtilityLayerRendererTask \"${this.name}\": targetTexture and camera are required`);\r\n        }\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            context.render(this.layer);\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.layer.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraph, type NodeRenderGraphBuildState, type FrameGraphTextureHandle, type Camera } from \"core/index\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { FrameGraphUtilityLayerRendererTask } from \"../../../Tasks/Rendering/utilityLayerRendererTask\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to render an utility layer in the frame graph\r\n */\r\nexport class NodeRenderGraphUtilityLayerRendererBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphUtilityLayerRendererTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeRenderGraphUtilityLayerRendererBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     * @param handleEvents If the utility layer should handle events.\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene, handleEvents = true) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._additionalConstructionParameters = [handleEvents];\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"camera\", NodeRenderGraphBlockConnectionPointTypes.Camera);\r\n        this._addDependenciesInput();\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAll);\r\n        this.output._typeConnectionSource = this.target;\r\n\r\n        this._frameGraphTask = new FrameGraphUtilityLayerRendererTask(name, frameGraph, scene, handleEvents);\r\n    }\r\n\r\n    private _createTask(handleEvents: boolean) {\r\n        const disabled = this._frameGraphTask.disabled;\r\n\r\n        this._frameGraphTask.dispose();\r\n        this._frameGraphTask = new FrameGraphUtilityLayerRendererTask(this.name, this._frameGraph, this._scene, handleEvents);\r\n        this._additionalConstructionParameters = [handleEvents];\r\n\r\n        this._frameGraphTask.disabled = disabled;\r\n    }\r\n\r\n    /** If the utility layer should handle events */\r\n    @editableInPropertyPage(\"Handle events\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get handleEvents() {\r\n        return this._frameGraphTask.layer.handleEvents;\r\n    }\r\n\r\n    public set handleEvents(value: boolean) {\r\n        this._createTask(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphUtilityLayerRendererBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera input component\r\n     */\r\n    public get camera(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.camera = this.camera.connectedPoint?.value as Camera;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for utilityLayerRendererBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUtilityLayerRendererBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphUtilityLayerRendererBlock\", NodeRenderGraphUtilityLayerRendererBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type Nullable, type FrameGraph, type NodeRenderGraphTeleportOutBlock } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to teleport a value to an endpoint\r\n */\r\nexport class NodeRenderGraphTeleportInBlock extends NodeRenderGraphBlock {\r\n    private _endpoints: NodeRenderGraphTeleportOutBlock[] = [];\r\n\r\n    /** Gets the list of attached endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphTeleportInBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._isTeleportIn = true;\r\n\r\n        this.registerInput(\"input\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphTeleportInBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    public override _dumpCode(uniqueNames: string[], alreadyDumped: NodeRenderGraphBlock[]) {\r\n        let codeString = super._dumpCode(uniqueNames, alreadyDumped);\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            if (alreadyDumped.indexOf(endpoint) === -1) {\r\n                codeString += endpoint._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given type\r\n     * @param type defines the potential type to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOfType(type: string): boolean {\r\n        if (this.getClassName() === type) {\r\n            return true;\r\n        }\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint.isAnAncestorOfType(type)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOf(block: NodeRenderGraphBlock): boolean {\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint === block) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.isAnAncestorOf(block)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Get the first descendant using a predicate\r\n     * @param predicate defines the predicate to check\r\n     * @returns descendant or null if none found\r\n     */\r\n    public override getDescendantOfPredicate(predicate: (block: NodeRenderGraphBlock) => boolean): Nullable<NodeRenderGraphBlock> {\r\n        if (predicate(this)) {\r\n            return this;\r\n        }\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            const descendant = endpoint.getDescendantOfPredicate(predicate);\r\n\r\n            if (descendant) {\r\n                return descendant;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Add an enpoint to this block\r\n     * @param endpoint define the endpoint to attach to\r\n     */\r\n    public attachToEndpoint(endpoint: NodeRenderGraphTeleportOutBlock) {\r\n        endpoint.detach();\r\n\r\n        this._endpoints.push(endpoint);\r\n        endpoint._entryPoint = this;\r\n        endpoint._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        endpoint._tempEntryPointUniqueId = null;\r\n        endpoint.name = \"> \" + this.name;\r\n    }\r\n\r\n    /**\r\n     * Remove enpoint from this block\r\n     * @param endpoint define the endpoint to remove\r\n     */\r\n    public detachFromEndpoint(endpoint: NodeRenderGraphTeleportOutBlock) {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index !== -1) {\r\n            this._endpoints.splice(index, 1);\r\n            endpoint._outputs[0]._typeConnectionSource = null;\r\n            endpoint._entryPoint = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n\r\n        for (const endpoint of this._endpoints) {\r\n            this.detachFromEndpoint(endpoint);\r\n        }\r\n\r\n        this._endpoints = [];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for frameGraphNodeBlocksTeleportTeleportInBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFrameGraphNodeBlocksTeleportTeleportInBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphTeleportInBlock\", NodeRenderGraphTeleportInBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type Nullable, type FrameGraph, type NodeRenderGraphTeleportInBlock, type NodeRenderGraphBuildState } from \"core/index\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to receive a value from a teleport entry point\r\n */\r\nexport class NodeRenderGraphTeleportOutBlock extends NodeRenderGraphBlock {\r\n    /** @internal */\r\n    public _entryPoint: Nullable<NodeRenderGraphTeleportInBlock> = null;\r\n    /** @internal */\r\n    public _tempEntryPointUniqueId: Nullable<number> = null;\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphTeleportOutBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this._isTeleportOut = true;\r\n\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n    }\r\n\r\n    /**\r\n     * Gets the entry point\r\n     */\r\n    public get entryPoint() {\r\n        return this._entryPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphTeleportOutBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** Detach from entry point */\r\n    public detach() {\r\n        if (!this._entryPoint) {\r\n            return;\r\n        }\r\n        this._entryPoint.detachFromEndpoint(this);\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        // Do nothing\r\n        // All work done by the emitter\r\n    }\r\n\r\n    protected override _customBuildStep(state: NodeRenderGraphBuildState): void {\r\n        if (this.entryPoint) {\r\n            this.entryPoint.build(state);\r\n        }\r\n    }\r\n\r\n    public override _dumpCode(uniqueNames: string[], alreadyDumped: NodeRenderGraphBlock[]) {\r\n        let codeString: string = \"\";\r\n        if (this.entryPoint) {\r\n            if (alreadyDumped.indexOf(this.entryPoint) === -1) {\r\n                codeString += this.entryPoint._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        return codeString + super._dumpCode(uniqueNames, alreadyDumped);\r\n    }\r\n\r\n    public override _dumpCodeForOutputConnections(alreadyDumped: NodeRenderGraphBlock[]) {\r\n        let codeString = super._dumpCodeForOutputConnections(alreadyDumped);\r\n\r\n        if (this.entryPoint) {\r\n            codeString += this.entryPoint._dumpCodeForOutputConnections(alreadyDumped);\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @returns a copy of the current block\r\n     */\r\n    public override clone() {\r\n        const clone = super.clone();\r\n\r\n        if (this.entryPoint) {\r\n            this.entryPoint.attachToEndpoint(clone as NodeRenderGraphTeleportOutBlock);\r\n        }\r\n\r\n        return clone;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n        if (this.entryPoint) {\r\n            codeString += `${this.entryPoint._codeVariableName}.attachToEndpoint(${this._codeVariableName});\\n`;\r\n        }\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.entryPoint = this.entryPoint?.uniqueId ?? \"\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this._tempEntryPointUniqueId = serializationObject.entryPoint;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for frameGraphNodeBlocksTeleportTeleportOutBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFrameGraphNodeBlocksTeleportTeleportOutBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphTeleportOutBlock\", NodeRenderGraphTeleportOutBlock);\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle, type IViewportLike, type Nullable } from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { IsDepthTexture } from \"../../../Materials/Textures/textureHelper.functions\";\r\n\r\n/**\r\n * Task used to copy a texture to another texture.\r\n */\r\nexport class FrameGraphCopyToTextureTask extends FrameGraphTask {\r\n    /**\r\n     * The source texture to copy from.\r\n     */\r\n    public sourceTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The target texture to copy to.\r\n     */\r\n    public targetTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The viewport to use when doing the copy.\r\n     * If set to null, the currently active viewport is used.\r\n     * If undefined (default), the viewport is reset to a full screen viewport before performing the copy.\r\n     */\r\n    public viewport?: Nullable<IViewportLike>;\r\n\r\n    /**\r\n     * The LOD level to copy from the source texture (default: 0).\r\n     */\r\n    public lodLevel: number = 0;\r\n\r\n    /**\r\n     * The output texture (same as targetTexture, but the handle may be different).\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Constructs a new FrameGraphCopyToTextureTask.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphCopyToTextureTask\";\r\n    }\r\n\r\n    public record() {\r\n        if (this.sourceTexture === undefined || this.targetTexture === undefined) {\r\n            throw new Error(`FrameGraphCopyToTextureTask \"${this.name}\": sourceTexture and targetTexture are required`);\r\n        }\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        pass.addDependencies(this.sourceTexture);\r\n        passDisabled.addDependencies(this.sourceTexture);\r\n\r\n        const textureDescription = this._frameGraph.textureManager.getTextureDescription(this.targetTexture);\r\n        const targetIsDepthTexture = IsDepthTexture(textureDescription.options.formats![0]);\r\n\r\n        if (targetIsDepthTexture) {\r\n            pass.setRenderTargetDepth(this.outputTexture);\r\n            passDisabled.setRenderTargetDepth(this.outputTexture);\r\n        } else {\r\n            pass.setRenderTarget(this.outputTexture);\r\n            passDisabled.setRenderTarget(this.outputTexture);\r\n        }\r\n        pass.setExecuteFunc((context) => {\r\n            if (this.viewport) {\r\n                context.setViewport(this.viewport);\r\n            }\r\n            context.setTextureSamplingMode(\r\n                this.sourceTexture,\r\n                targetIsDepthTexture\r\n                    ? Constants.TEXTURE_NEAREST_SAMPLINGMODE\r\n                    : this.lodLevel > 0\r\n                      ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE\r\n                      : Constants.TEXTURE_BILINEAR_SAMPLINGMODE\r\n            );\r\n            context.copyTexture(this.sourceTexture, undefined, this.viewport !== undefined, this.lodLevel);\r\n        });\r\n\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraphTextureHandle, type FrameGraph, type NodeRenderGraphBuildState, type IViewportLike } from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { FrameGraphCopyToTextureTask } from \"../../../Tasks/Texture/copyToTextureTask\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to copy a texture\r\n */\r\nexport class NodeRenderGraphCopyTextureBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphCopyToTextureTask;\r\n\r\n    protected _useCurrentViewport = false;\r\n    protected _useFullScreenViewport = true;\r\n    protected _viewport: IViewportLike = { x: 0, y: 0, width: 1, height: 1 };\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphCopyTextureBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"source\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this._addDependenciesInput();\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.source.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAll);\r\n        this.output._typeConnectionSource = this.source;\r\n\r\n        this._frameGraphTask = new FrameGraphCopyToTextureTask(name, frameGraph);\r\n    }\r\n\r\n    private _setViewport() {\r\n        if (this._useCurrentViewport) {\r\n            this._frameGraphTask.viewport = null;\r\n        } else if (this._useFullScreenViewport) {\r\n            this._frameGraphTask.viewport = undefined;\r\n        } else {\r\n            this._frameGraphTask.viewport = this._viewport;\r\n        }\r\n    }\r\n\r\n    /** If true, the current viewport will be left unchanged. */\r\n    @editableInPropertyPage(\"Use currently active viewport\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get useCurrentViewport(): boolean {\r\n        return this._useCurrentViewport;\r\n    }\r\n\r\n    public set useCurrentViewport(value: boolean) {\r\n        this._useCurrentViewport = value;\r\n        this._setViewport();\r\n    }\r\n\r\n    /** If true, a full screen viewport will be used. */\r\n    @editableInPropertyPage(\"Use full screen viewport\", PropertyTypeForEdition.Boolean, \"PROPERTIES\")\r\n    public get useFullScreenViewport(): boolean {\r\n        return this._useFullScreenViewport;\r\n    }\r\n\r\n    public set useFullScreenViewport(value: boolean) {\r\n        this._useFullScreenViewport = value;\r\n        this._setViewport();\r\n    }\r\n\r\n    /** The viewport to use. */\r\n    @editableInPropertyPage(\"    Viewport\", PropertyTypeForEdition.Viewport, \"PROPERTIES\")\r\n    public get viewport(): IViewportLike {\r\n        return this._viewport;\r\n    }\r\n\r\n    public set viewport(value: IViewportLike) {\r\n        this._viewport = value;\r\n        this._setViewport();\r\n    }\r\n\r\n    /** The LOD level to copy from the source texture (default: 0). */\r\n    @editableInPropertyPage(\"LOD Level\", PropertyTypeForEdition.Int, \"PROPERTIES\", { min: 0, max: 16 })\r\n    public get lodLevel(): number {\r\n        return this._frameGraphTask.lodLevel;\r\n    }\r\n\r\n    public set lodLevel(value: number) {\r\n        this._frameGraphTask.lodLevel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphCopyTextureBlock\";\r\n    }\r\n    /**\r\n     * Gets the source input component\r\n     */\r\n    public get source(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture; // the value of the output connection point is the \"output\" texture of the task\r\n\r\n        this._frameGraphTask.sourceTexture = this.source.connectedPoint?.value as FrameGraphTextureHandle;\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codes: string[] = [];\r\n        codes.push(`${this._codeVariableName}.viewport = ${this._useCurrentViewport ? \"null\" : this._useFullScreenViewport ? \"undefined\" : JSON.stringify(this._viewport)};`);\r\n        codes.push(`${this._codeVariableName}.lodLevel = ${this.lodLevel};`);\r\n        return super._dumpPropertiesCode() + codes.join(\"\\n\");\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.useCurrentViewport = this._useCurrentViewport;\r\n        serializationObject.useFullScreenViewport = this._useFullScreenViewport;\r\n        serializationObject.viewport = this._viewport;\r\n        serializationObject.lodLevel = this.lodLevel;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n        if (serializationObject.useCurrentViewport !== undefined) {\r\n            this._useCurrentViewport = serializationObject.useCurrentViewport;\r\n            this._useFullScreenViewport = serializationObject.useFullScreenViewport;\r\n            this._viewport = serializationObject.viewport;\r\n        }\r\n        this.lodLevel = serializationObject.lodLevel ?? 0;\r\n        this._setViewport();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for copyTextureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCopyTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphCopyTextureBlock\", NodeRenderGraphCopyTextureBlock);\r\n}\r\n","import { type FrameGraph, type FrameGraphTextureHandle } from \"core/index\";\r\nimport { FrameGraphTask } from \"../../frameGraphTask\";\r\n\r\n/**\r\n * Task which generates mipmaps for a texture.\r\n */\r\nexport class FrameGraphGenerateMipMapsTask extends FrameGraphTask {\r\n    /**\r\n     * The texture to generate mipmaps for.\r\n     */\r\n    public targetTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * The output texture (same as targetTexture, but the handle may be different).\r\n     */\r\n    public readonly outputTexture: FrameGraphTextureHandle;\r\n\r\n    /**\r\n     * Constructs a new FrameGraphGenerateMipMapsTask.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph the task belongs to.\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph) {\r\n        super(name, frameGraph);\r\n\r\n        this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphGenerateMipMapsTask\";\r\n    }\r\n\r\n    public record() {\r\n        if (this.targetTexture === undefined) {\r\n            throw new Error(`FrameGraphGenerateMipMapsTask ${this.name}: targetTexture is required`);\r\n        }\r\n\r\n        this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);\r\n\r\n        const outputTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.targetTexture);\r\n\r\n        if (!outputTextureDescription.options.createMipMaps) {\r\n            throw new Error(`FrameGraphGenerateMipMapsTask ${this.name}: targetTexture must have createMipMaps set to true`);\r\n        }\r\n\r\n        const pass = this._frameGraph.addRenderPass(this.name);\r\n\r\n        pass.setRenderTarget(this.outputTexture);\r\n        pass.setExecuteFunc((context) => {\r\n            context.generateMipMaps();\r\n        });\r\n\r\n        const passDisabled = this._frameGraph.addRenderPass(this.name + \"_disabled\", true);\r\n\r\n        passDisabled.setRenderTarget(this.outputTexture);\r\n        passDisabled.setExecuteFunc((_context) => {});\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeRenderGraphConnectionPoint, type Scene, type FrameGraphTextureHandle, type FrameGraph, type NodeRenderGraphBuildState } from \"core/index\";\r\nimport { NodeRenderGraphBlock } from \"../../nodeRenderGraphBlock\";\r\nimport { NodeRenderGraphBlockConnectionPointTypes } from \"../../Types/nodeRenderGraphTypes\";\r\nimport { FrameGraphGenerateMipMapsTask } from \"../../../Tasks/Texture/generateMipMapsTask\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to generate mipmaps for a texture\r\n */\r\nexport class NodeRenderGraphGenerateMipmapsBlock extends NodeRenderGraphBlock {\r\n    protected override _frameGraphTask: FrameGraphGenerateMipMapsTask;\r\n\r\n    /**\r\n     * Gets the frame graph task associated with this block\r\n     */\r\n    public override get task() {\r\n        return this._frameGraphTask;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeRenderGraphGenerateMipmapsBlock\r\n     * @param name defines the block name\r\n     * @param frameGraph defines the hosting frame graph\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public constructor(name: string, frameGraph: FrameGraph, scene: Scene) {\r\n        super(name, frameGraph, scene);\r\n\r\n        this.registerInput(\"target\", NodeRenderGraphBlockConnectionPointTypes.AutoDetect);\r\n        this._addDependenciesInput();\r\n        this.registerOutput(\"output\", NodeRenderGraphBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.target.addExcludedConnectionPointFromAllowedTypes(NodeRenderGraphBlockConnectionPointTypes.TextureAllButBackBuffer);\r\n        this.output._typeConnectionSource = this.target;\r\n\r\n        this._frameGraphTask = new FrameGraphGenerateMipMapsTask(name, frameGraph);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeRenderGraphGenerateMipmapsBlock\";\r\n    }\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeRenderGraphConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeRenderGraphConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeRenderGraphBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.output.value = this._frameGraphTask.outputTexture;\r\n\r\n        this._frameGraphTask.targetTexture = this.target.connectedPoint?.value as FrameGraphTextureHandle;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for generateMipmapsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGenerateMipmapsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeRenderGraphGenerateMipmapsBlock\", NodeRenderGraphGenerateMipmapsBlock);\r\n}\r\n","import { type FrameGraph, type EffectWrapperCreationOptions, type Observable, type Effect } from \"core/index\";\r\nimport { FrameGraphPostProcessTask } from \"./postProcessTask\";\r\nimport { ThinCustomPostProcess } from \"../../../PostProcesses/thinCustomPostProcess\";\r\n\r\n/**\r\n * Task which applies a custom post process.\r\n */\r\nexport class FrameGraphCustomPostProcessTask extends FrameGraphPostProcessTask {\r\n    public override readonly postProcess: ThinCustomPostProcess;\r\n\r\n    /**\r\n     * Observable triggered when bind is called for the post process.\r\n     * Use this to set custom uniforms.\r\n     */\r\n    public onApplyObservable: Observable<Effect>;\r\n\r\n    /**\r\n     * Constructs a new custom post process task.\r\n     * @param name The name of the task.\r\n     * @param frameGraph The frame graph this task is associated with.\r\n     * @param options Options to configure the post process\r\n     */\r\n    constructor(name: string, frameGraph: FrameGraph, options: EffectWrapperCreationOptions) {\r\n        super(name, frameGraph, new ThinCustomPostProcess(name, frameGraph.engine, options));\r\n\r\n        this.onApplyObservable = this.postProcess.onBindObservable;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphCustomPostProcessTask\";\r\n    }\r\n}\r\n","import { type Nullable, type AbstractMesh, type IParticleSystem, type ISpriteManager } from \"core/index\";\r\n\r\n/**\r\n * Structure used by the frame graph to reference objects.\r\n */\r\nexport class FrameGraphObjectList {\r\n    /**\r\n     * The meshes in the object list.\r\n     */\r\n    public meshes: Nullable<AbstractMesh[]>;\r\n    /**\r\n     * The particle systems in the object list.\r\n     */\r\n    public particleSystems: Nullable<IParticleSystem[]>;\r\n    /**\r\n     * The sprite managers in the object list. If omitted or null, all sprite managers in the scene are used. An empty array renders none.\r\n     * @see https://playground.babylonjs.com/#PVK3RV#2\r\n     */\r\n    public spriteManagers?: Nullable<ISpriteManager[]>;\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Node } from \"../node\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type LinesMesh } from \"../Meshes/linesMesh\";\r\nimport { CreateBox } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { PointerDragBehavior } from \"../Behaviors/Meshes/pointerDragBehavior\";\r\nimport { type GizmoAxisCache, type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { type ScaleGizmo } from \"./scaleGizmo\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\n\r\n/**\r\n * Interface for axis scale gizmo\r\n */\r\nexport interface IAxisScaleGizmo extends IGizmo {\r\n    /** Drag behavior responsible for the gizmos dragging interactions */\r\n    dragBehavior: PointerDragBehavior;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /** Incremental snap scaling. When true, with a snapDistance of 0.1, scaling will be 1.1,1.2,1.3 instead of, when false: 1.1,1.21,1.33,... */\r\n    incrementalSnap: boolean;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in distance\r\n     */\r\n    onSnapObservable: Observable<{ snapDistance: number }>;\r\n    /** If the scaling operation should be done on all axis */\r\n    uniformScaling: boolean;\r\n    /** Custom sensitivity value for the drag strength */\r\n    sensitivity: number;\r\n    /** The magnitude of the drag strength (scaling factor) */\r\n    dragScale: number;\r\n    /** If the gizmo is enabled */\r\n    isEnabled: boolean;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    coloredMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    hoverMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    disableMaterial: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Single axis scale gizmo\r\n */\r\nexport class AxisScaleGizmo extends Gizmo implements IAxisScaleGizmo {\r\n    /**\r\n     * Drag behavior responsible for the gizmos dragging interactions\r\n     */\r\n    public dragBehavior: PointerDragBehavior;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n    /**\r\n     * Scale distance in babylon units that the gizmo will snap to when dragged (Default: 0)\r\n     */\r\n    public snapDistance = 0;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in distance\r\n     */\r\n    public onSnapObservable = new Observable<{ snapDistance: number }>();\r\n    /**\r\n     * If the scaling operation should be done on all axis (default: false)\r\n     */\r\n    public uniformScaling = false;\r\n    /**\r\n     * Custom sensitivity value for the drag strength\r\n     */\r\n    public sensitivity = 1;\r\n    /**\r\n     * The magnitude of the drag strength (scaling factor)\r\n     */\r\n    public dragScale = 1;\r\n\r\n    /**\r\n     * The minimal absolute scale per component. can be positive or negative but never smaller.\r\n     */\r\n    public static MinimumAbsoluteScale = Epsilon;\r\n\r\n    /**\r\n     * Incremental snap scaling (default is false). When true, with a snapDistance of 0.1, scaling will be 1.1,1.2,1.3 instead of, when false: 1.1,1.21,1.33,...\r\n     */\r\n    public incrementalSnap = false;\r\n\r\n    protected _isEnabled: boolean = true;\r\n    protected _parent: Nullable<ScaleGizmo> = null;\r\n\r\n    protected _gizmoMesh: Mesh;\r\n    protected _coloredMaterial: StandardMaterial;\r\n    protected _hoverMaterial: StandardMaterial;\r\n    protected _disableMaterial: StandardMaterial;\r\n    protected _dragging: boolean = false;\r\n    private _tmpVector = new Vector3(0, 0, 0);\r\n    private _incrementalStartupValue = Vector3.Zero();\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    public get coloredMaterial() {\r\n        return this._coloredMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    public get hoverMaterial() {\r\n        return this._hoverMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    public get disableMaterial() {\r\n        return this._disableMaterial;\r\n    }\r\n\r\n    /**\r\n     * Creates an AxisScaleGizmo\r\n     * @param dragAxis The axis which the gizmo will be able to scale on\r\n     * @param color The color of the gizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param parent\r\n     * @param thickness display gizmo axis thickness\r\n     * @param hoverColor The color of the gizmo when hovering over and dragging\r\n     * @param disableColor The Color of the gizmo when its disabled\r\n     */\r\n    constructor(\r\n        dragAxis: Vector3,\r\n        color: Color3 = Color3.Gray(),\r\n        gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer,\r\n        parent: Nullable<ScaleGizmo> = null,\r\n        thickness: number = 1,\r\n        hoverColor: Color3 = Color3.Yellow(),\r\n        disableColor: Color3 = Color3.Gray()\r\n    ) {\r\n        super(gizmoLayer);\r\n        this._parent = parent;\r\n        // Create Material\r\n        this._coloredMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._coloredMaterial.diffuseColor = color;\r\n        this._coloredMaterial.specularColor = color.subtract(new Color3(0.1, 0.1, 0.1));\r\n\r\n        this._hoverMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._hoverMaterial.diffuseColor = hoverColor;\r\n\r\n        this._disableMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._disableMaterial.diffuseColor = disableColor;\r\n        this._disableMaterial.alpha = 0.4;\r\n\r\n        // Build mesh + Collider\r\n        this._gizmoMesh = new Mesh(\"axis\", gizmoLayer.utilityLayerScene);\r\n        const { arrowMesh, arrowTail } = this._createGizmoMesh(this._gizmoMesh, thickness);\r\n        const collider = this._createGizmoMesh(this._gizmoMesh, thickness + 4, true);\r\n\r\n        this._gizmoMesh.lookAt(this._rootMesh.position.add(dragAxis));\r\n        this._rootMesh.addChild(this._gizmoMesh, Gizmo.PreserveScaling);\r\n        this._gizmoMesh.scaling.scaleInPlace(1 / 3);\r\n\r\n        // Closure of initial prop values for resetting\r\n        const nodePosition = arrowMesh.position.clone();\r\n        const linePosition = arrowTail.position.clone();\r\n        const lineScale = arrowTail.scaling.clone();\r\n\r\n        const increaseGizmoMesh = (dragDistance: number) => {\r\n            const dragStrength = dragDistance * (3 / this._rootMesh.scaling.length()) * 6;\r\n\r\n            arrowMesh.position.z += dragStrength / 3.5;\r\n            arrowTail.scaling.y += dragStrength;\r\n            this.dragScale = arrowTail.scaling.y;\r\n            arrowTail.position.z = arrowMesh.position.z / 2;\r\n        };\r\n\r\n        const resetGizmoMesh = () => {\r\n            arrowMesh.position.set(nodePosition.x, nodePosition.y, nodePosition.z);\r\n            arrowTail.position.set(linePosition.x, linePosition.y, linePosition.z);\r\n            arrowTail.scaling.set(lineScale.x, lineScale.y, lineScale.z);\r\n            this.dragScale = arrowTail.scaling.y;\r\n            this._dragging = false;\r\n        };\r\n\r\n        // Add drag behavior to handle events when the gizmo is dragged\r\n        this.dragBehavior = new PointerDragBehavior({ dragAxis: dragAxis });\r\n        this.dragBehavior.moveAttached = false;\r\n        this.dragBehavior.updateDragPlane = false;\r\n        this._rootMesh.addBehavior(this.dragBehavior);\r\n\r\n        let currentSnapDragDistance = 0;\r\n        let currentSnapDragDistanceIncremental = 0;\r\n\r\n        const tmpSnapEvent = { snapDistance: 0 };\r\n        this.dragBehavior.onDragObservable.add((event) => {\r\n            if (this.attachedNode) {\r\n                // Drag strength is modified by the scale of the gizmo (eg. for small objects like boombox the strength will be increased to match the behavior of larger objects)\r\n                const dragStrength = this.sensitivity * event.dragDistance * ((this.scaleRatio * 3) / this._rootMesh.scaling.length());\r\n                const tmpVector = this._tmpVector;\r\n                // Snapping logic\r\n                let snapped = false;\r\n                let dragSteps = 0;\r\n                if (this.uniformScaling) {\r\n                    tmpVector.setAll(0.57735); // 1 / sqrt(3)\r\n                } else {\r\n                    tmpVector.copyFrom(dragAxis);\r\n                }\r\n                if (this.snapDistance == 0) {\r\n                    tmpVector.scaleToRef(dragStrength, tmpVector);\r\n                } else {\r\n                    currentSnapDragDistance += dragStrength;\r\n                    currentSnapDragDistanceIncremental += dragStrength;\r\n                    const currentSnap = this.incrementalSnap ? currentSnapDragDistanceIncremental : currentSnapDragDistance;\r\n                    if (Math.abs(currentSnap) > this.snapDistance) {\r\n                        dragSteps = Math.floor(Math.abs(currentSnap) / this.snapDistance);\r\n\r\n                        if (currentSnap < 0) {\r\n                            dragSteps *= -1;\r\n                        }\r\n                        currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;\r\n                        tmpVector.scaleToRef(this.snapDistance * dragSteps, tmpVector);\r\n                        snapped = true;\r\n                    } else {\r\n                        tmpVector.scaleInPlace(0);\r\n                    }\r\n                }\r\n\r\n                tmpVector.addInPlaceFromFloats(1, 1, 1);\r\n                // can't use Math.sign here because Math.sign(0) is 0 and it needs to be positive\r\n                tmpVector.x = Math.abs(tmpVector.x) < AxisScaleGizmo.MinimumAbsoluteScale ? AxisScaleGizmo.MinimumAbsoluteScale * (tmpVector.x < 0 ? -1 : 1) : tmpVector.x;\r\n                tmpVector.y = Math.abs(tmpVector.y) < AxisScaleGizmo.MinimumAbsoluteScale ? AxisScaleGizmo.MinimumAbsoluteScale * (tmpVector.y < 0 ? -1 : 1) : tmpVector.y;\r\n                tmpVector.z = Math.abs(tmpVector.z) < AxisScaleGizmo.MinimumAbsoluteScale ? AxisScaleGizmo.MinimumAbsoluteScale * (tmpVector.z < 0 ? -1 : 1) : tmpVector.z;\r\n\r\n                const transformNode = (<Mesh>this.attachedNode)._isMesh ? (this.attachedNode as TransformNode) : undefined;\r\n                if (Math.abs(this.snapDistance) > 0 && this.incrementalSnap) {\r\n                    // get current scaling\r\n                    this.attachedNode.getWorldMatrix().decompose(undefined, TmpVectors.Quaternion[0], TmpVectors.Vector3[2], Gizmo.PreserveScaling ? transformNode : undefined);\r\n                    // apply incrementally, without taking care of current scaling value\r\n                    tmpVector.addInPlace(this._incrementalStartupValue);\r\n                    tmpVector.addInPlaceFromFloats(-1, -1, -1);\r\n                    // keep same sign or stretching close to 0 will change orientation at each drag and scaling will oscillate around 0\r\n                    tmpVector.x = Math.abs(tmpVector.x) * (this._incrementalStartupValue.x > 0 ? 1 : -1);\r\n                    tmpVector.y = Math.abs(tmpVector.y) * (this._incrementalStartupValue.y > 0 ? 1 : -1);\r\n                    tmpVector.z = Math.abs(tmpVector.z) * (this._incrementalStartupValue.z > 0 ? 1 : -1);\r\n                    Matrix.ComposeToRef(tmpVector, TmpVectors.Quaternion[0], TmpVectors.Vector3[2], TmpVectors.Matrix[1]);\r\n                } else {\r\n                    Matrix.ScalingToRef(tmpVector.x, tmpVector.y, tmpVector.z, TmpVectors.Matrix[2]);\r\n                    TmpVectors.Matrix[2].multiplyToRef(this.attachedNode.getWorldMatrix(), TmpVectors.Matrix[1]);\r\n                }\r\n\r\n                // check scaling are not out of bounds. If not, copy resulting temp matrix to node world matrix\r\n                TmpVectors.Matrix[1].decompose(TmpVectors.Vector3[1], undefined, undefined, Gizmo.PreserveScaling ? transformNode : undefined);\r\n\r\n                const maxScale = 100000;\r\n                if (Math.abs(TmpVectors.Vector3[1].x) < maxScale && Math.abs(TmpVectors.Vector3[1].y) < maxScale && Math.abs(TmpVectors.Vector3[1].z) < maxScale) {\r\n                    this.attachedNode.getWorldMatrix().copyFrom(TmpVectors.Matrix[1]);\r\n                }\r\n\r\n                // notify observers\r\n                if (snapped) {\r\n                    tmpSnapEvent.snapDistance = this.snapDistance * dragSteps;\r\n                    this.onSnapObservable.notifyObservers(tmpSnapEvent);\r\n                }\r\n                this._matrixChanged();\r\n            }\r\n        });\r\n        // On Drag Listener: to move gizmo mesh with user action\r\n        this.dragBehavior.onDragStartObservable.add(() => {\r\n            this._dragging = true;\r\n            const transformNode = (<Mesh>this.attachedNode)._isMesh ? (this.attachedNode as TransformNode) : undefined;\r\n            this.attachedNode?.getWorldMatrix().decompose(this._incrementalStartupValue, undefined, undefined, Gizmo.PreserveScaling ? transformNode : undefined);\r\n            currentSnapDragDistance = 0;\r\n            currentSnapDragDistanceIncremental = 0;\r\n        });\r\n        this.dragBehavior.onDragObservable.add((e) => increaseGizmoMesh(e.dragDistance));\r\n        this.dragBehavior.onDragEndObservable.add(resetGizmoMesh);\r\n\r\n        // Listeners for Universal Scalar\r\n        parent?.uniformScaleGizmo?.dragBehavior?.onDragObservable?.add((e) => increaseGizmoMesh(e.delta.y));\r\n        parent?.uniformScaleGizmo?.dragBehavior?.onDragEndObservable?.add(resetGizmoMesh);\r\n\r\n        const cache: GizmoAxisCache = {\r\n            gizmoMeshes: [arrowMesh, arrowTail],\r\n            colliderMeshes: [collider.arrowMesh, collider.arrowTail],\r\n            material: this._coloredMaterial,\r\n            hoverMaterial: this._hoverMaterial,\r\n            disableMaterial: this._disableMaterial,\r\n            active: false,\r\n            dragBehavior: this.dragBehavior,\r\n        };\r\n        this._parent?.addToAxisCache(this._gizmoMesh, cache);\r\n\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (this._customMeshSet) {\r\n                return;\r\n            }\r\n            // axis mesh cache\r\n            let meshCache = this._parent?.getAxisCache(this._gizmoMesh);\r\n            this._isHovered = !!meshCache && !!(meshCache.colliderMeshes.indexOf(<Mesh>pointerInfo?.pickInfo?.pickedMesh) != -1);\r\n            // uniform mesh cache\r\n            meshCache = this._parent?.getAxisCache(this._rootMesh);\r\n            this._isHovered ||= !!meshCache && !!(meshCache.colliderMeshes.indexOf(<Mesh>pointerInfo?.pickInfo?.pickedMesh) != -1);\r\n            if (!this._parent) {\r\n                const material = this.dragBehavior.enabled ? (this._isHovered || this._dragging ? this._hoverMaterial : this._coloredMaterial) : this._disableMaterial;\r\n                this._setGizmoMeshMaterial(cache.gizmoMeshes, material);\r\n            }\r\n        });\r\n\r\n        this.dragBehavior.onEnabledObservable.add((newState) => {\r\n            this._setGizmoMeshMaterial(cache.gizmoMeshes, newState ? this._coloredMaterial : this._disableMaterial);\r\n        });\r\n\r\n        const light = gizmoLayer._getSharedGizmoLight();\r\n        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(this._rootMesh.getChildMeshes());\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Create Geometry for Gizmo\r\n     * @param parentMesh\r\n     * @param thickness\r\n     * @param isCollider\r\n     * @returns the gizmo mesh\r\n     */\r\n    protected _createGizmoMesh(parentMesh: AbstractMesh, thickness: number, isCollider = false) {\r\n        const arrowMesh = CreateBox(\"yPosMesh\", { size: 0.4 * (1 + (thickness - 1) / 4) }, this.gizmoLayer.utilityLayerScene);\r\n        const arrowTail = CreateCylinder(\r\n            \"cylinder\",\r\n            { diameterTop: 0.005 * thickness, height: 0.275, diameterBottom: 0.005 * thickness, tessellation: 96 },\r\n            this.gizmoLayer.utilityLayerScene\r\n        );\r\n\r\n        // Position arrow pointing in its drag axis\r\n        arrowMesh.scaling.scaleInPlace(0.1);\r\n        arrowMesh.material = this._coloredMaterial;\r\n        arrowMesh.rotation.x = Math.PI / 2;\r\n        arrowMesh.position.z += 0.3;\r\n\r\n        arrowTail.material = this._coloredMaterial;\r\n        arrowTail.position.z += 0.275 / 2;\r\n        arrowTail.rotation.x = Math.PI / 2;\r\n\r\n        if (isCollider) {\r\n            arrowMesh.visibility = 0;\r\n            arrowTail.visibility = 0;\r\n        }\r\n\r\n        parentMesh.addChild(arrowMesh);\r\n        parentMesh.addChild(arrowTail);\r\n\r\n        return { arrowMesh, arrowTail };\r\n    }\r\n\r\n    protected override _attachedNodeChanged(value: Nullable<Node>) {\r\n        if (this.dragBehavior) {\r\n            this.dragBehavior.enabled = value ? true : false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the gizmo is enabled\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        this._isEnabled = value;\r\n        if (!value) {\r\n            this.attachedMesh = null;\r\n            this.attachedNode = null;\r\n        } else {\r\n            if (this._parent) {\r\n                this.attachedMesh = this._parent.attachedMesh;\r\n                this.attachedNode = this._parent.attachedNode;\r\n            }\r\n        }\r\n    }\r\n\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        this.onSnapObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this.dragBehavior.detach();\r\n        if (this._gizmoMesh) {\r\n            this._gizmoMesh.dispose();\r\n        }\r\n        const mats = [this._coloredMaterial, this._hoverMaterial, this._disableMaterial];\r\n        for (const matl of mats) {\r\n            if (matl) {\r\n                matl.dispose();\r\n            }\r\n        }\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Disposes and replaces the current meshes in the gizmo with the specified mesh\r\n     * @param mesh The mesh to replace the default mesh of the gizmo\r\n     * @param useGizmoMaterial If the gizmo's default material should be used (default: false)\r\n     */\r\n    public override setCustomMesh(mesh: Mesh, useGizmoMaterial: boolean = false) {\r\n        super.setCustomMesh(mesh);\r\n        if (useGizmoMaterial) {\r\n            const childMeshes = this._gizmoMesh.getChildMeshes();\r\n            for (const m of childMeshes) {\r\n                m.material = this._coloredMaterial;\r\n                if ((<LinesMesh>m).color) {\r\n                    (<LinesMesh>m).color = this._coloredMaterial.diffuseColor;\r\n                }\r\n            }\r\n            this._customMeshSet = false;\r\n        }\r\n    }\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Quaternion, Matrix, Vector3, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { CreateBox } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { CreateLineSystem } from \"../Meshes/Builders/linesBuilder.pure\";\r\nimport { PointerDragBehavior } from \"../Behaviors/Meshes/pointerDragBehavior\";\r\nimport { type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { PivotTools } from \"../Misc/pivotTools\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type LinesMesh } from \"../Meshes/linesMesh\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { type IPointerEvent } from \"../Events/deviceInputEvents\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { KeyboardEventTypes, type KeyboardInfo } from \"../Events/keyboardEvents\";\r\n\r\n/**\r\n * Interface for bounding box gizmo\r\n */\r\nexport interface IBoundingBoxGizmo extends IGizmo {\r\n    /**\r\n     * If child meshes should be ignored when calculating the bounding box. This should be set to true to avoid perf hits with heavily nested meshes.\r\n     */\r\n    ignoreChildren: boolean;\r\n    /**\r\n     * Returns true if a descendant should be included when computing the bounding box. When null, all descendants are included. If ignoreChildren is set this will be ignored.\r\n     */\r\n    includeChildPredicate: Nullable<(abstractMesh: AbstractMesh) => boolean>;\r\n    /** The size of the rotation anchors attached to the bounding box */\r\n    rotationSphereSize: number;\r\n    /** The size of the scale boxes attached to the bounding box */\r\n    scaleBoxSize: number;\r\n    /**\r\n     * If set, the rotation anchors and scale boxes will increase in size based on the distance away from the camera to have a consistent screen size\r\n     * Note : fixedDragMeshScreenSize takes precedence over fixedDragMeshBoundsSize if both are true\r\n     */\r\n    fixedDragMeshScreenSize: boolean;\r\n    /**\r\n     * If set, the rotation anchors and scale boxes will increase in size based on the size of the bounding box\r\n     * Note : fixedDragMeshScreenSize takes precedence over fixedDragMeshBoundsSize if both are true\r\n     */\r\n    fixedDragMeshBoundsSize: boolean;\r\n    /**\r\n     * The distance away from the object which the draggable meshes should appear world sized when fixedDragMeshScreenSize is set to true\r\n     */\r\n    fixedDragMeshScreenSizeDistanceFactor: number;\r\n    /** True when a rotation anchor or scale box or a attached mesh is dragged */\r\n    readonly isDragging: boolean;\r\n    /** Fired when a rotation anchor or scale box is dragged */\r\n    onDragStartObservable: Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>;\r\n    /** Fired when the gizmo mesh hovering starts*/\r\n    onHoverStartObservable: Observable<void>;\r\n    /** Fired when the gizmo mesh hovering ends*/\r\n    onHoverEndObservable: Observable<void>;\r\n    /** Fired when a scale box is dragged */\r\n    onScaleBoxDragObservable: Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>;\r\n    /** Fired when a scale box drag is ended */\r\n    onScaleBoxDragEndObservable: Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>;\r\n    /** Fired when a rotation anchor is dragged */\r\n    onRotationSphereDragObservable: Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>;\r\n    /** Fired when a rotation anchor drag is ended */\r\n    onRotationSphereDragEndObservable: Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>;\r\n    /** Relative bounding box pivot used when scaling the attached node. */\r\n    scalePivot: Nullable<Vector3>;\r\n    /** Scale factor vector used for masking some axis */\r\n    axisFactor: Vector3;\r\n    /** Scale factor scalar affecting all axes' drag speed */\r\n    scaleDragSpeed: number;\r\n    /**\r\n     * Sets the color of the bounding box gizmo\r\n     * @param color the color to set\r\n     */\r\n    setColor(color: Color3): void;\r\n    /** Returns an array containing all boxes used for scaling (in increasing x, y and z orders) */\r\n    getScaleBoxes(): AbstractMesh[];\r\n    /** Updates the bounding box information for the Gizmo */\r\n    updateBoundingBox(): void;\r\n    /**\r\n     * Enables rotation on the specified axis and disables rotation on the others\r\n     * @param axis The list of axis that should be enabled (eg. \"xy\" or \"xyz\")\r\n     */\r\n    setEnabledRotationAxis(axis: string): void;\r\n    /**\r\n     * Enables/disables scaling\r\n     * @param enable if scaling should be enabled\r\n     * @param homogeneousScaling defines if scaling should only be homogeneous\r\n     */\r\n    setEnabledScaling(enable: boolean, homogeneousScaling?: boolean): void;\r\n    /** Enables a pointer drag behavior on the bounding box of the gizmo */\r\n    enableDragBehavior(): void;\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    releaseDrag(): void;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    coloredMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    hoverMaterial: StandardMaterial;\r\n\r\n    /** Drag distance in babylon units that the gizmo will snap scaling to when dragged */\r\n    scalingSnapDistance: number;\r\n    /** Drag distance in babylon units that the gizmo will snap rotation to when dragged */\r\n    rotationSnapDistance: number;\r\n}\r\n\r\n/**\r\n * Dragging operation in observable\r\n */\r\nexport const enum DragOperation {\r\n    Rotation,\r\n    Scaling,\r\n}\r\n\r\n/**\r\n * Bounding box gizmo\r\n */\r\nexport class BoundingBoxGizmo extends Gizmo implements IBoundingBoxGizmo {\r\n    protected _lineBoundingBox: TransformNode;\r\n    protected _rotateAnchorsParent: TransformNode;\r\n    protected _scaleBoxesParent: TransformNode;\r\n    protected _boundingDimensions = new Vector3(1, 1, 1);\r\n    protected _renderObserver: Nullable<Observer<Scene>> = null;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n    protected _scaleDragSpeed = 0.2;\r\n    protected _rotateAnchorsDragBehaviors: Array<PointerDragBehavior> = [];\r\n    protected _scaleBoxesDragBehaviors: Array<PointerDragBehavior> = [];\r\n    /**\r\n     * boolean updated when a rotation anchor or scale box is dragged\r\n     */\r\n    protected _dragging = false;\r\n\r\n    private _tmpQuaternion = new Quaternion();\r\n    private _tmpVector = new Vector3(0, 0, 0);\r\n    private _tmpRotationMatrix = new Matrix();\r\n    private _incrementalStartupValue = Vector3.Zero();\r\n    private _incrementalAnchorStartupValue = Vector3.Zero();\r\n    private _isCenterScaleModeActive = false;\r\n    private _centerScaleKeyObserver: Nullable<Observer<KeyboardInfo>> = null;\r\n\r\n    /**\r\n     * If child meshes should be ignored when calculating the bounding box. This should be set to true to avoid perf hits with heavily nested meshes (Default: false)\r\n     */\r\n    public ignoreChildren = false;\r\n    /**\r\n     * Returns true if a descendant should be included when computing the bounding box. When null, all descendants are included. If ignoreChildren is set this will be ignored. (Default: null)\r\n     */\r\n    public includeChildPredicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null;\r\n\r\n    /**\r\n     * The size of the rotation anchors attached to the bounding box (Default: 0.1)\r\n     */\r\n    public rotationSphereSize = 0.1;\r\n    /**\r\n     * The size of the scale boxes attached to the bounding box (Default: 0.1)\r\n     */\r\n    public scaleBoxSize = 0.1;\r\n    /**\r\n     * If set, the rotation anchors and scale boxes will increase in size based on the distance away from the camera to have a consistent screen size (Default: false)\r\n     * Note : fixedDragMeshScreenSize takes precedence over fixedDragMeshBoundsSize if both are true\r\n     */\r\n    public fixedDragMeshScreenSize = false;\r\n    /**\r\n     * If set, the rotation anchors and scale boxes will increase in size based on the size of the bounding box\r\n     * Note : fixedDragMeshScreenSize takes precedence over fixedDragMeshBoundsSize if both are true\r\n     */\r\n    public fixedDragMeshBoundsSize = false;\r\n    /**\r\n     * The distance away from the object which the draggable meshes should appear world sized when fixedDragMeshScreenSize is set to true (default: 10)\r\n     */\r\n    public fixedDragMeshScreenSizeDistanceFactor = 10;\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap scaling to when dragged\r\n     */\r\n    public scalingSnapDistance = 0;\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap rotation to when dragged\r\n     */\r\n    public rotationSnapDistance = 0;\r\n    /**\r\n     * Fired when a rotation anchor or scale box is dragged\r\n     */\r\n    public onDragStartObservable = new Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>();\r\n    /**\r\n     * Fired when the gizmo mesh hovering starts\r\n     */\r\n    public onHoverStartObservable = new Observable<void>();\r\n    /**\r\n     * Fired when the gizmo mesh hovering ends\r\n     */\r\n    public onHoverEndObservable = new Observable<void>();\r\n    /**\r\n     * Fired when a scale box is dragged\r\n     */\r\n    public onScaleBoxDragObservable = new Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>();\r\n    /**\r\n     * Fired when a scale box drag is ended\r\n     */\r\n    public onScaleBoxDragEndObservable = new Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>();\r\n    /**\r\n     * Fired when a rotation anchor is dragged\r\n     */\r\n    public onRotationSphereDragObservable = new Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>();\r\n    /**\r\n     * Fired when a rotation anchor drag is ended\r\n     */\r\n    public onRotationSphereDragEndObservable = new Observable<{ dragOperation: DragOperation; dragAxis: Vector3 }>();\r\n    /**\r\n     * Relative bounding box pivot used when scaling the attached node. When null object with scale from the opposite corner. 0.5,0.5,0.5 for center and 0.5,0,0.5 for bottom (Default: null)\r\n     */\r\n    public scalePivot: Nullable<Vector3> = null;\r\n    /**\r\n     * Scale factor used for masking some axis\r\n     */\r\n    protected _axisFactor = new Vector3(1, 1, 1);\r\n\r\n    /**\r\n     * Incremental snap scaling (default is false). When true, with a snapDistance of 0.1, scaling will be 1.1,1.2,1.3 instead of, when false: 1.1,1.21,1.33,...\r\n     */\r\n    public incrementalSnap = false;\r\n\r\n    /**\r\n     * Sets the axis factor\r\n     * @param factor the Vector3 value\r\n     */\r\n    public set axisFactor(factor: Vector3) {\r\n        this._axisFactor = factor;\r\n        // update scale cube visibility\r\n        const scaleBoxes = this._scaleBoxesParent.getChildMeshes();\r\n        let index = 0;\r\n        for (let i = 0; i < 3; i++) {\r\n            for (let j = 0; j < 3; j++) {\r\n                for (let k = 0; k < 3; k++) {\r\n                    const zeroAxisCount = (i === 1 ? 1 : 0) + (j === 1 ? 1 : 0) + (k === 1 ? 1 : 0);\r\n                    if (zeroAxisCount === 1 || zeroAxisCount === 3) {\r\n                        continue;\r\n                    }\r\n                    if (scaleBoxes[index]) {\r\n                        const dragAxis = new Vector3(i - 1, j - 1, k - 1);\r\n                        dragAxis.multiplyInPlace(this._axisFactor);\r\n                        scaleBoxes[index].setEnabled(dragAxis.lengthSquared() > Epsilon);\r\n                    }\r\n                    index++;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the axis factor\r\n     * @returns the Vector3 factor value\r\n     */\r\n    public get axisFactor(): Vector3 {\r\n        return this._axisFactor;\r\n    }\r\n\r\n    /**\r\n     * Sets scale drag speed value\r\n     * @param value the new speed value\r\n     */\r\n    public set scaleDragSpeed(value: number) {\r\n        this._scaleDragSpeed = value;\r\n    }\r\n\r\n    /**\r\n     * Gets scale drag speed\r\n     * @returns the scale speed number\r\n     */\r\n    public get scaleDragSpeed(): number {\r\n        return this._scaleDragSpeed;\r\n    }\r\n\r\n    /**\r\n     * Mesh used as a pivot to rotate the attached node\r\n     */\r\n    protected _anchorMesh: TransformNode;\r\n\r\n    protected _existingMeshScale = new Vector3();\r\n\r\n    // Dragging\r\n    protected _dragMesh: Nullable<Mesh> = null;\r\n    protected _pointerDragBehavior = new PointerDragBehavior();\r\n\r\n    protected _coloredMaterial: StandardMaterial;\r\n    protected _hoverColoredMaterial: StandardMaterial;\r\n\r\n    // HL2 style corner mesh\r\n    protected _cornerMesh: Nullable<Mesh> = null;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    public get coloredMaterial() {\r\n        return this._coloredMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    public get hoverMaterial() {\r\n        return this._hoverColoredMaterial;\r\n    }\r\n    /**\r\n     * Get the pointerDragBehavior\r\n     */\r\n    public get pointerDragBehavior(): PointerDragBehavior {\r\n        return this._pointerDragBehavior;\r\n    }\r\n\r\n    /** True when a rotation anchor or scale box or a attached mesh is dragged */\r\n    public get isDragging() {\r\n        return this._dragging || this._pointerDragBehavior.dragging;\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the bounding box gizmo\r\n     * @param color the color to set\r\n     */\r\n    public setColor(color: Color3) {\r\n        this._coloredMaterial.emissiveColor = color;\r\n        this._hoverColoredMaterial.emissiveColor = color.clone().add(new Color3(0.3, 0.3, 0.3));\r\n        const children = this._lineBoundingBox.getChildren();\r\n        for (const l of children) {\r\n            if ((l as LinesMesh).color) {\r\n                (l as LinesMesh).color = color;\r\n            }\r\n        }\r\n    }\r\n    /**\r\n     * Creates an BoundingBoxGizmo\r\n     * @param color The color of the gizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     */\r\n    constructor(color: Color3 = Color3.Gray(), gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultKeepDepthUtilityLayer) {\r\n        super(gizmoLayer);\r\n\r\n        // Do not update the gizmo's scale so it has a fixed size to the object its attached to\r\n        this.updateScale = false;\r\n\r\n        this._anchorMesh = new TransformNode(\"anchor\", gizmoLayer.utilityLayerScene);\r\n        // Create Materials\r\n        this._coloredMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._coloredMaterial.disableLighting = true;\r\n        this._hoverColoredMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._hoverColoredMaterial.disableLighting = true;\r\n\r\n        // Build bounding box out of lines\r\n        this._lineBoundingBox = new TransformNode(\"\", gizmoLayer.utilityLayerScene);\r\n        this._lineBoundingBox.rotationQuaternion = new Quaternion();\r\n        const lines: Vector3[][] = [\r\n            [new Vector3(0, 0, 0), new Vector3(this._boundingDimensions.x, 0, 0)],\r\n            [new Vector3(0, 0, 0), new Vector3(0, this._boundingDimensions.y, 0)],\r\n            [new Vector3(0, 0, 0), new Vector3(0, 0, this._boundingDimensions.z)],\r\n            [new Vector3(this._boundingDimensions.x, 0, 0), new Vector3(this._boundingDimensions.x, this._boundingDimensions.y, 0)],\r\n            [new Vector3(this._boundingDimensions.x, 0, 0), new Vector3(this._boundingDimensions.x, 0, this._boundingDimensions.z)],\r\n            [new Vector3(0, this._boundingDimensions.y, 0), new Vector3(this._boundingDimensions.x, this._boundingDimensions.y, 0)],\r\n            [new Vector3(0, this._boundingDimensions.y, 0), new Vector3(0, this._boundingDimensions.y, this._boundingDimensions.z)],\r\n            [new Vector3(0, 0, this._boundingDimensions.z), new Vector3(this._boundingDimensions.x, 0, this._boundingDimensions.z)],\r\n            [new Vector3(0, 0, this._boundingDimensions.z), new Vector3(0, this._boundingDimensions.y, this._boundingDimensions.z)],\r\n            [\r\n                new Vector3(this._boundingDimensions.x, this._boundingDimensions.y, this._boundingDimensions.z),\r\n                new Vector3(0, this._boundingDimensions.y, this._boundingDimensions.z),\r\n            ],\r\n            [\r\n                new Vector3(this._boundingDimensions.x, this._boundingDimensions.y, this._boundingDimensions.z),\r\n                new Vector3(this._boundingDimensions.x, 0, this._boundingDimensions.z),\r\n            ],\r\n            [\r\n                new Vector3(this._boundingDimensions.x, this._boundingDimensions.y, this._boundingDimensions.z),\r\n                new Vector3(this._boundingDimensions.x, this._boundingDimensions.y, 0),\r\n            ],\r\n        ];\r\n        const line = CreateLineSystem(\"lines\", { lines }, gizmoLayer.utilityLayerScene);\r\n        line.color = color;\r\n        line.position.addInPlace(new Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));\r\n        line.isPickable = false;\r\n        this._lineBoundingBox.addChild(line);\r\n        this._rootMesh.addChild(this._lineBoundingBox);\r\n\r\n        this.setColor(color);\r\n\r\n        // Create rotation anchors\r\n        this._rotateAnchorsParent = new TransformNode(\"\", gizmoLayer.utilityLayerScene);\r\n        this._rotateAnchorsParent.rotationQuaternion = new Quaternion();\r\n        for (let i = 0; i < 12; i++) {\r\n            const anchor = CreateBox(\"\", { width: i < 4 || i >= 8 ? 1.6 : 0.4, height: i >= 4 && i < 8 ? 1.6 : 0.4, depth: 0.4 }, gizmoLayer.utilityLayerScene);\r\n            anchor.rotation.x = i < 4 || i >= 8 ? Math.PI * 0.25 : 0;\r\n            anchor.rotation.y = i >= 4 && i < 8 ? Math.PI * 0.25 : 0;\r\n            anchor.bakeTransformIntoVertices(anchor.computeWorldMatrix(true));\r\n            anchor.rotationQuaternion = new Quaternion();\r\n            anchor.material = this._coloredMaterial;\r\n            anchor.isNearGrabbable = true;\r\n\r\n            // Drag behavior\r\n            const rotateAnchorsDragBehavior = new PointerDragBehavior({});\r\n            rotateAnchorsDragBehavior.moveAttached = false;\r\n            rotateAnchorsDragBehavior.updateDragPlane = false;\r\n            anchor.addBehavior(rotateAnchorsDragBehavior);\r\n            const startingTurnDirection = new Vector3(1, 0, 0);\r\n            let totalTurnAmountOfDrag = 0;\r\n            let previousProjectDist = 0;\r\n            rotateAnchorsDragBehavior.onDragStartObservable.add(() => {\r\n                startingTurnDirection.copyFrom(anchor.forward);\r\n                totalTurnAmountOfDrag = 0;\r\n                previousProjectDist = 0;\r\n            });\r\n            const computeAxis = function () {\r\n                const dragAxisIndex = Math.floor(i / 4);\r\n                TmpVectors.Vector3[0].set(dragAxisIndex == 0 ? 1 : 0, dragAxisIndex == 1 ? 1 : 0, dragAxisIndex == 2 ? 1 : 0);\r\n                return TmpVectors.Vector3[0];\r\n            };\r\n            rotateAnchorsDragBehavior.onDragObservable.add((event) => {\r\n                this.onRotationSphereDragObservable.notifyObservers({ dragOperation: DragOperation.Rotation, dragAxis: computeAxis().clone() });\r\n                if (this.attachedMesh) {\r\n                    const originalParent = this.attachedMesh.parent;\r\n                    if (originalParent && (originalParent as Mesh).scaling && (originalParent as Mesh).scaling.isNonUniformWithinEpsilon(0.001)) {\r\n                        Logger.Warn(\"BoundingBoxGizmo controls are not supported on child meshes with non-uniform parent scaling\");\r\n                        return;\r\n                    }\r\n                    PivotTools._RemoveAndStorePivotPoint(this.attachedMesh);\r\n\r\n                    const worldDragDirection = startingTurnDirection;\r\n\r\n                    // Project the world right on to the drag plane\r\n                    const toSub = event.dragPlaneNormal.scale(Vector3.Dot(event.dragPlaneNormal, worldDragDirection));\r\n                    const dragAxis = worldDragDirection.subtract(toSub).normalizeToNew();\r\n\r\n                    // project drag delta on to the resulting drag axis and rotate based on that\r\n                    let projectDist = Vector3.Dot(dragAxis, event.delta) < 0 ? Math.abs(event.delta.length()) : -Math.abs(event.delta.length());\r\n\r\n                    // Make rotation relative to size of mesh.\r\n                    projectDist = (projectDist / this._boundingDimensions.length()) * this._anchorMesh.scaling.length();\r\n\r\n                    // Rotate based on axis\r\n                    if (!this.attachedMesh.rotationQuaternion) {\r\n                        this.attachedMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(\r\n                            this.attachedMesh.rotation.y,\r\n                            this.attachedMesh.rotation.x,\r\n                            this.attachedMesh.rotation.z\r\n                        );\r\n                    }\r\n                    if (!this._anchorMesh.rotationQuaternion) {\r\n                        this._anchorMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(\r\n                            this._anchorMesh.rotation.y,\r\n                            this._anchorMesh.rotation.x,\r\n                            this._anchorMesh.rotation.z\r\n                        );\r\n                    }\r\n\r\n                    // Do not allow the object to turn more than a full circle\r\n                    totalTurnAmountOfDrag += projectDist;\r\n                    if (Math.abs(totalTurnAmountOfDrag) <= 2 * Math.PI) {\r\n                        if (this.rotationSnapDistance > 0) {\r\n                            const dragSteps = Math.floor(Math.abs(totalTurnAmountOfDrag) / this.rotationSnapDistance) * (totalTurnAmountOfDrag < 0 ? -1 : 1);\r\n                            const angle = this.rotationSnapDistance * dragSteps;\r\n                            projectDist = angle - previousProjectDist;\r\n                            previousProjectDist = angle;\r\n                        }\r\n                        if (i >= 8) {\r\n                            Quaternion.RotationYawPitchRollToRef(0, 0, projectDist, this._tmpQuaternion);\r\n                        } else if (i >= 4) {\r\n                            Quaternion.RotationYawPitchRollToRef(projectDist, 0, 0, this._tmpQuaternion);\r\n                        } else {\r\n                            Quaternion.RotationYawPitchRollToRef(0, projectDist, 0, this._tmpQuaternion);\r\n                        }\r\n\r\n                        // if using pivot, move anchor so mesh will be at relative (0,0,0) when parented\r\n                        if (this.attachedMesh.isUsingPivotMatrix()) {\r\n                            this._anchorMesh.position.copyFrom(this.attachedMesh.position);\r\n                        }\r\n                        // Rotate around center of bounding box\r\n                        this._anchorMesh.addChild(this.attachedMesh);\r\n                        if (this._anchorMesh.getScene().useRightHandedSystem) {\r\n                            this._tmpQuaternion.conjugateInPlace();\r\n                        }\r\n                        this._tmpQuaternion.normalize();\r\n                        this._anchorMesh.rotationQuaternion.multiplyToRef(this._tmpQuaternion, this._anchorMesh.rotationQuaternion);\r\n                        this._anchorMesh.rotationQuaternion.normalize();\r\n                        this._anchorMesh.removeChild(this.attachedMesh);\r\n                        this.attachedMesh.setParent(originalParent);\r\n                    }\r\n                    this.updateBoundingBox();\r\n\r\n                    PivotTools._RestorePivotPoint(this.attachedMesh);\r\n                }\r\n                this._updateDummy();\r\n            });\r\n\r\n            // Selection/deselection\r\n            rotateAnchorsDragBehavior.onDragStartObservable.add(() => {\r\n                this.onDragStartObservable.notifyObservers({ dragOperation: DragOperation.Rotation, dragAxis: computeAxis().clone() });\r\n                this._dragging = true;\r\n                this._selectNode(anchor);\r\n            });\r\n            rotateAnchorsDragBehavior.onDragEndObservable.add((event) => {\r\n                this.onRotationSphereDragEndObservable.notifyObservers({ dragOperation: DragOperation.Rotation, dragAxis: computeAxis().clone() });\r\n                this._dragging = false;\r\n                this._selectNode(null);\r\n                this._updateDummy();\r\n                this._unhoverMeshOnTouchUp(event.pointerInfo, anchor);\r\n            });\r\n\r\n            this._rotateAnchorsDragBehaviors.push(rotateAnchorsDragBehavior);\r\n\r\n            this._rotateAnchorsParent.addChild(anchor);\r\n        }\r\n        this._rootMesh.addChild(this._rotateAnchorsParent);\r\n\r\n        // Create scale cubes\r\n        this._scaleBoxesParent = new TransformNode(\"\", gizmoLayer.utilityLayerScene);\r\n        this._scaleBoxesParent.rotationQuaternion = new Quaternion();\r\n        for (let i = 0; i < 3; i++) {\r\n            for (let j = 0; j < 3; j++) {\r\n                for (let k = 0; k < 3; k++) {\r\n                    // create box for relevant axis\r\n                    const zeroAxisCount = (i === 1 ? 1 : 0) + (j === 1 ? 1 : 0) + (k === 1 ? 1 : 0);\r\n                    if (zeroAxisCount === 1 || zeroAxisCount === 3) {\r\n                        continue;\r\n                    }\r\n\r\n                    const box = zeroAxisCount === 2 ? CreateBox(\"\", { size: 1 }, gizmoLayer.utilityLayerScene) : this._getCornerMesh(gizmoLayer);\r\n                    if (zeroAxisCount === 0) {\r\n                        box.rotationQuaternion = Quaternion.FromEulerAngles(j * 0.25 * Math.PI, (k + 3 * i - i * k) * 0.25 * Math.PI, 0);\r\n                    }\r\n\r\n                    box.material = this._coloredMaterial;\r\n                    box._internalMetadata = zeroAxisCount === 2; // None homogenous scale handle\r\n                    box.isNearGrabbable = true;\r\n\r\n                    // box is oriented so, transform world desired axis to local one\r\n                    TmpVectors.Vector3[0].set(i - 1, j - 1, k - 1);\r\n                    TmpVectors.Vector3[0].normalize();\r\n                    box.computeWorldMatrix(true).invertToRef(TmpVectors.Matrix[0]);\r\n                    const dragAxis = Vector3.TransformCoordinates(TmpVectors.Vector3[0], TmpVectors.Matrix[0]);\r\n                    dragAxis.normalize();\r\n\r\n                    // Dragging logic\r\n                    const scaleBoxesDragBehavior = new PointerDragBehavior({ dragAxis: dragAxis });\r\n                    scaleBoxesDragBehavior.updateDragPlane = false;\r\n                    scaleBoxesDragBehavior.moveAttached = false;\r\n                    let totalRelativeDragDistance = 0;\r\n                    let previousScale = 0;\r\n                    const initialAnchorCenter = new Vector3();\r\n                    const initialBoxPosition = new Vector3();\r\n                    const initialMeshAbsolutePosition = new Vector3();\r\n                    box.addBehavior(scaleBoxesDragBehavior);\r\n                    scaleBoxesDragBehavior.onDragObservable.add((event) => {\r\n                        this.onScaleBoxDragObservable.notifyObservers({ dragOperation: DragOperation.Scaling, dragAxis: new Vector3(i - 1, j - 1, k - 1) });\r\n                        if (this.attachedMesh) {\r\n                            const originalParent = this.attachedMesh.parent;\r\n                            if (originalParent && (originalParent as Mesh).scaling && (originalParent as Mesh).scaling.isNonUniformWithinEpsilon(0.001)) {\r\n                                Logger.Warn(\"BoundingBoxGizmo controls are not supported on child meshes with non-uniform parent scaling\");\r\n                                return;\r\n                            }\r\n                            PivotTools._RemoveAndStorePivotPoint(this.attachedMesh);\r\n                            let relativeDragDistance = (event.dragDistance / this._boundingDimensions.length()) * this._anchorMesh.scaling.length();\r\n                            totalRelativeDragDistance += relativeDragDistance;\r\n                            if (this.scalingSnapDistance > 0) {\r\n                                const dragSteps = Math.floor(Math.abs(totalRelativeDragDistance) / this.scalingSnapDistance) * (totalRelativeDragDistance < 0 ? -1 : 1);\r\n                                const scale = this.scalingSnapDistance * dragSteps;\r\n                                relativeDragDistance = scale - previousScale;\r\n                                previousScale = scale;\r\n                            }\r\n\r\n                            const deltaScale = new Vector3(relativeDragDistance, relativeDragDistance, relativeDragDistance);\r\n                            const fullScale = new Vector3(previousScale, previousScale, previousScale);\r\n\r\n                            if (zeroAxisCount === 2) {\r\n                                // scale on 1 axis when using the anchor box in the face middle\r\n                                deltaScale.x *= Math.abs(dragAxis.x);\r\n                                deltaScale.y *= Math.abs(dragAxis.y);\r\n                                deltaScale.z *= Math.abs(dragAxis.z);\r\n                            }\r\n\r\n                            deltaScale.scaleInPlace(this._scaleDragSpeed);\r\n                            deltaScale.multiplyInPlace(this._axisFactor);\r\n\r\n                            fullScale.scaleInPlace(this._scaleDragSpeed);\r\n                            fullScale.multiplyInPlace(this._axisFactor);\r\n                            fullScale.addInPlace(this._incrementalStartupValue);\r\n\r\n                            this.updateBoundingBox();\r\n                            if (this._isCenterScaleModeActive) {\r\n                                // Use the original bounding box center captured at drag start so the pivot\r\n                                // stays fixed when the modifier is toggled mid-drag\r\n                                this._anchorMesh.position.copyFrom(initialAnchorCenter);\r\n                            } else if (this.scalePivot) {\r\n                                this.attachedMesh.getWorldMatrix().getRotationMatrixToRef(this._tmpRotationMatrix);\r\n                                // Move anchor to desired pivot point (Bottom left corner + dimension/2)\r\n                                this._boundingDimensions.scaleToRef(0.5, this._tmpVector);\r\n                                Vector3.TransformCoordinatesToRef(this._tmpVector, this._tmpRotationMatrix, this._tmpVector);\r\n                                this._anchorMesh.position.subtractInPlace(this._tmpVector);\r\n                                this._boundingDimensions.multiplyToRef(this.scalePivot, this._tmpVector);\r\n                                Vector3.TransformCoordinatesToRef(this._tmpVector, this._tmpRotationMatrix, this._tmpVector);\r\n                                this._anchorMesh.position.addInPlace(this._tmpVector);\r\n                            } else {\r\n                                // Scale from the original opposite corner (2*initialCenter - initialBoxPos)\r\n                                // so toggling modes mid-drag always references the same fixed point\r\n                                initialAnchorCenter.scaleToRef(2, this._tmpVector);\r\n                                this._tmpVector.subtractInPlace(initialBoxPosition);\r\n                                this._anchorMesh.position.copyFrom(this._tmpVector);\r\n                                if (this.attachedMesh.isUsingPivotMatrix()) {\r\n                                    this._anchorMesh.position.subtractInPlace(this.attachedMesh.getPivotPoint());\r\n                                }\r\n                            }\r\n\r\n                            // Reset mesh and anchor to drag-start state each frame so the pivot-scale\r\n                            // computation is non-iterative; mid-drag mode toggles won't cause jumps\r\n                            this.attachedMesh.setAbsolutePosition(initialMeshAbsolutePosition);\r\n                            this.attachedMesh.scaling.copyFrom(this._incrementalStartupValue);\r\n                            this._anchorMesh.scaling.copyFrom(this._incrementalAnchorStartupValue);\r\n                            this._anchorMesh.addChild(this.attachedMesh);\r\n                            if (this.incrementalSnap) {\r\n                                fullScale.x /= Math.abs(this._incrementalStartupValue.x) < Epsilon ? 1 : this._incrementalStartupValue.x;\r\n                                fullScale.y /= Math.abs(this._incrementalStartupValue.y) < Epsilon ? 1 : this._incrementalStartupValue.y;\r\n                                fullScale.z /= Math.abs(this._incrementalStartupValue.z) < Epsilon ? 1 : this._incrementalStartupValue.z;\r\n\r\n                                fullScale.x = Math.max(this._incrementalAnchorStartupValue.x * fullScale.x, this.scalingSnapDistance);\r\n                                fullScale.y = Math.max(this._incrementalAnchorStartupValue.y * fullScale.y, this.scalingSnapDistance);\r\n                                fullScale.z = Math.max(this._incrementalAnchorStartupValue.z * fullScale.z, this.scalingSnapDistance);\r\n\r\n                                if (this._isCenterScaleModeActive) {\r\n                                    fullScale.x = this._incrementalAnchorStartupValue.x + (fullScale.x - this._incrementalAnchorStartupValue.x) * 2;\r\n                                    fullScale.y = this._incrementalAnchorStartupValue.y + (fullScale.y - this._incrementalAnchorStartupValue.y) * 2;\r\n                                    fullScale.z = this._incrementalAnchorStartupValue.z + (fullScale.z - this._incrementalAnchorStartupValue.z) * 2;\r\n                                }\r\n\r\n                                this._anchorMesh.scaling.x += (fullScale.x - this._anchorMesh.scaling.x) * Math.abs(dragAxis.x);\r\n                                this._anchorMesh.scaling.y += (fullScale.y - this._anchorMesh.scaling.y) * Math.abs(dragAxis.y);\r\n                                this._anchorMesh.scaling.z += (fullScale.z - this._anchorMesh.scaling.z) * Math.abs(dragAxis.z);\r\n                            } else {\r\n                                // Compute absolute scale from total drag distance so modifier toggles mid-drag work retroactively\r\n                                const scaleMultiplier = this._isCenterScaleModeActive ? 2 : 1;\r\n                                const totalScale = totalRelativeDragDistance * this._scaleDragSpeed * scaleMultiplier;\r\n                                const newAnchorScale = this._incrementalAnchorStartupValue.clone();\r\n                                if (zeroAxisCount === 2) {\r\n                                    newAnchorScale.x += totalScale * Math.abs(dragAxis.x) * this._axisFactor.x;\r\n                                    newAnchorScale.y += totalScale * Math.abs(dragAxis.y) * this._axisFactor.y;\r\n                                    newAnchorScale.z += totalScale * Math.abs(dragAxis.z) * this._axisFactor.z;\r\n                                } else {\r\n                                    newAnchorScale.x += totalScale * this._axisFactor.x;\r\n                                    newAnchorScale.y += totalScale * this._axisFactor.y;\r\n                                    newAnchorScale.z += totalScale * this._axisFactor.z;\r\n                                }\r\n                                if (newAnchorScale.x > 0 && newAnchorScale.y > 0 && newAnchorScale.z > 0) {\r\n                                    this._anchorMesh.scaling.copyFrom(newAnchorScale);\r\n                                }\r\n                            }\r\n                            this._anchorMesh.removeChild(this.attachedMesh);\r\n                            this.attachedMesh.setParent(originalParent);\r\n                            PivotTools._RestorePivotPoint(this.attachedMesh);\r\n                        }\r\n                        this._updateDummy();\r\n                    });\r\n\r\n                    // Selection/deselection\r\n                    scaleBoxesDragBehavior.onDragStartObservable.add(() => {\r\n                        this.onDragStartObservable.notifyObservers({ dragOperation: DragOperation.Scaling, dragAxis: new Vector3(i - 1, j - 1, k - 1) });\r\n                        this._dragging = true;\r\n                        this._selectNode(box);\r\n                        totalRelativeDragDistance = 0;\r\n                        previousScale = 0;\r\n                        this.attachedMesh!.computeWorldMatrix(true);\r\n                        this._update();\r\n                        this._lineBoundingBox.computeWorldMatrix(true);\r\n                        this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);\r\n                        this._incrementalStartupValue.copyFrom(this.attachedMesh!.scaling);\r\n                        this._incrementalAnchorStartupValue.copyFrom(this._anchorMesh.scaling);\r\n                        initialAnchorCenter.copyFrom(this._anchorMesh.position);\r\n                        initialBoxPosition.copyFrom(box.absolutePosition);\r\n                        initialMeshAbsolutePosition.copyFrom(this.attachedMesh!.getAbsolutePosition());\r\n                    });\r\n                    scaleBoxesDragBehavior.onDragEndObservable.add((event) => {\r\n                        this.onScaleBoxDragEndObservable.notifyObservers({ dragOperation: DragOperation.Scaling, dragAxis: new Vector3(i - 1, j - 1, k - 1) });\r\n                        this._dragging = false;\r\n                        this._selectNode(null);\r\n                        this._updateDummy();\r\n                        this._unhoverMeshOnTouchUp(event.pointerInfo, box);\r\n                    });\r\n\r\n                    this._scaleBoxesParent.addChild(box);\r\n                    this._scaleBoxesDragBehaviors.push(scaleBoxesDragBehavior);\r\n                }\r\n            }\r\n        }\r\n        this._rootMesh.addChild(this._scaleBoxesParent);\r\n\r\n        // Keyboard observer for center-scale mode (Ctrl on Windows, Opt/Alt on Mac)\r\n        this._centerScaleKeyObserver = gizmoLayer.originalScene.onKeyboardObservable.add(({ type, event }) => {\r\n            if (type === KeyboardEventTypes.KEYDOWN && (event.ctrlKey || event.altKey)) {\r\n                this._isCenterScaleModeActive = true;\r\n            } else if (type === KeyboardEventTypes.KEYUP && !event.ctrlKey && !event.altKey) {\r\n                this._isCenterScaleModeActive = false;\r\n            }\r\n        });\r\n\r\n        // Hover color change\r\n        const pointerIds: AbstractMesh[] = [];\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (!pointerIds[(<IPointerEvent>pointerInfo.event).pointerId]) {\r\n                const meshes = this._rotateAnchorsParent.getChildMeshes().concat(this._scaleBoxesParent.getChildMeshes());\r\n\r\n                for (const mesh of meshes) {\r\n                    if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh == mesh) {\r\n                        pointerIds[(<IPointerEvent>pointerInfo.event).pointerId] = mesh;\r\n                        mesh.material = this._hoverColoredMaterial;\r\n                        this.onHoverStartObservable.notifyObservers();\r\n                        this._isHovered = true;\r\n                    }\r\n                }\r\n            } else {\r\n                if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh != pointerIds[(<IPointerEvent>pointerInfo.event).pointerId]) {\r\n                    pointerIds[(<IPointerEvent>pointerInfo.event).pointerId].material = this._coloredMaterial;\r\n                    pointerIds.splice((<IPointerEvent>pointerInfo.event).pointerId, 1);\r\n                    this.onHoverEndObservable.notifyObservers();\r\n                    this._isHovered = false;\r\n                }\r\n            }\r\n        });\r\n\r\n        // Update bounding box positions\r\n        this._renderObserver = this.gizmoLayer.originalScene.onBeforeRenderObservable.add(() => {\r\n            // Only update the bounding box if scaling has changed\r\n            if (this.attachedMesh && !this._existingMeshScale.equals(this.attachedMesh.scaling)) {\r\n                this.updateBoundingBox();\r\n            } else if (this.fixedDragMeshScreenSize || this.fixedDragMeshBoundsSize) {\r\n                this._updateRotationAnchors();\r\n                this._updateScaleBoxes();\r\n            }\r\n\r\n            // If drag mesh is enabled and dragging, update the attached mesh pose to match the drag mesh\r\n            if (this._dragMesh && this.attachedMesh && this._pointerDragBehavior.dragging) {\r\n                this._lineBoundingBox.position.rotateByQuaternionToRef(this._rootMesh.rotationQuaternion!, this._tmpVector);\r\n                this.attachedMesh.setAbsolutePosition(this._dragMesh.position.add(this._tmpVector.scale(-1)));\r\n            }\r\n        });\r\n        this.updateBoundingBox();\r\n    }\r\n\r\n    protected _getCornerMesh(gizmoLayer: UtilityLayerRenderer): Mesh {\r\n        if (!this._cornerMesh) {\r\n            const boxZ = CreateBox(\"\", { width: 0.4, height: 0.4, depth: 1.6 }, gizmoLayer.utilityLayerScene);\r\n            boxZ.position.z = 0.6;\r\n            const boxY = CreateBox(\"\", { width: 0.4, height: 1.6, depth: 0.4 }, gizmoLayer.utilityLayerScene);\r\n            boxY.position.y = 0.6;\r\n            const boxX = CreateBox(\"\", { width: 1.6, height: 0.4, depth: 0.4 }, gizmoLayer.utilityLayerScene);\r\n            boxX.position.x = 0.6;\r\n            this._cornerMesh = Mesh.MergeMeshes([boxX, boxY, boxZ], true);\r\n            return this._cornerMesh!;\r\n        }\r\n\r\n        return this._cornerMesh.clone();\r\n    }\r\n\r\n    /**\r\n     * returns true if the combination of non uniform scaling and rotation of the attached mesh is not supported\r\n     * In that case, the matrix is skewed and the bounding box gizmo will not work correctly\r\n     * @returns True if the combination is not supported, otherwise false.\r\n     */\r\n    protected _hasInvalidNonUniformScaling() {\r\n        return (\r\n            this._attachedMesh?.parent instanceof TransformNode &&\r\n            this._attachedMesh?.parent.absoluteScaling.isNonUniformWithinEpsilon(0.001) &&\r\n            ((this._attachedMesh?.rotationQuaternion && !this._attachedMesh?.rotationQuaternion.equalsWithEpsilon(Quaternion.Identity(), Epsilon)) ||\r\n                this._attachedMesh?.rotation.equalsWithEpsilon(Vector3.Zero(), Epsilon) === false)\r\n        );\r\n    }\r\n    protected override _attachedNodeChanged(value: Nullable<AbstractMesh>) {\r\n        if (value) {\r\n            if (this._hasInvalidNonUniformScaling()) {\r\n                Logger.Warn(\"BoundingBoxGizmo controls are not supported on meshes with non-uniform scaling and rotation\");\r\n                return;\r\n            }\r\n            // Reset anchor mesh to match attached mesh's scale\r\n            // This is needed to avoid invalid box/anchor position on first drag\r\n            this._anchorMesh.scaling.setAll(1);\r\n            PivotTools._RemoveAndStorePivotPoint(value);\r\n            const originalParent = value.parent;\r\n            this._anchorMesh.addChild(value);\r\n            this._anchorMesh.removeChild(value);\r\n            value.setParent(originalParent);\r\n            PivotTools._RestorePivotPoint(value);\r\n            this.updateBoundingBox();\r\n            const children = value.getChildMeshes(false);\r\n            for (const m of children) {\r\n                m.markAsDirty(\"scaling\");\r\n            }\r\n\r\n            this.gizmoLayer.utilityLayerScene.onAfterRenderObservable.addOnce(() => {\r\n                this._updateDummy();\r\n            });\r\n        }\r\n    }\r\n\r\n    protected _selectNode(selectedMesh: Nullable<Mesh>) {\r\n        const meshes = this._rotateAnchorsParent.getChildMeshes().concat(this._scaleBoxesParent.getChildMeshes());\r\n\r\n        for (const m of meshes) {\r\n            m.isVisible = !selectedMesh || m == selectedMesh;\r\n        }\r\n    }\r\n\r\n    protected _unhoverMeshOnTouchUp(pointerInfo: Nullable<PointerInfo>, selectedMesh: AbstractMesh) {\r\n        // force unhover mesh if not a mouse event\r\n        if (pointerInfo?.event instanceof PointerEvent && pointerInfo?.event.pointerType === \"touch\") {\r\n            selectedMesh.material = this._coloredMaterial;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * returns an array containing all boxes used for scaling (in increasing x, y and z orders)\r\n     * @returns array of scaling boxes\r\n     */\r\n    public getScaleBoxes() {\r\n        return this._scaleBoxesParent.getChildMeshes();\r\n    }\r\n\r\n    /**\r\n     * Updates the bounding box information for the Gizmo\r\n     */\r\n    public updateBoundingBox() {\r\n        if (this.attachedMesh && !this._hasInvalidNonUniformScaling()) {\r\n            PivotTools._RemoveAndStorePivotPoint(this.attachedMesh);\r\n\r\n            // Store original parent\r\n            const originalParent = this.attachedMesh.parent;\r\n            this.attachedMesh.setParent(null);\r\n\r\n            this._update();\r\n\r\n            // Rotate based on axis\r\n            if (!this.attachedMesh.rotationQuaternion) {\r\n                this.attachedMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);\r\n            }\r\n            if (!this._anchorMesh.rotationQuaternion) {\r\n                this._anchorMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._anchorMesh.rotation.y, this._anchorMesh.rotation.x, this._anchorMesh.rotation.z);\r\n            }\r\n            this._anchorMesh.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);\r\n\r\n            // Store original position and reset mesh to origin before computing the bounding box\r\n            this._tmpQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);\r\n            this._tmpVector.copyFrom(this.attachedMesh.position);\r\n            this.attachedMesh.rotationQuaternion.set(0, 0, 0, 1);\r\n            this.attachedMesh.position.set(0, 0, 0);\r\n\r\n            // Update bounding dimensions/positions\r\n            const boundingMinMax = this.attachedMesh.getHierarchyBoundingVectors(!this.ignoreChildren, this.includeChildPredicate);\r\n            boundingMinMax.max.subtractToRef(boundingMinMax.min, this._boundingDimensions);\r\n\r\n            // Update gizmo to match bounding box scaling and rotation\r\n            // The position set here is the offset from the origin for the boundingbox when the attached mesh is at the origin\r\n            // The position of the gizmo is then set to the attachedMesh in gizmo._update\r\n            this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);\r\n            this._lineBoundingBox.position.set(\r\n                (boundingMinMax.max.x + boundingMinMax.min.x) / 2,\r\n                (boundingMinMax.max.y + boundingMinMax.min.y) / 2,\r\n                (boundingMinMax.max.z + boundingMinMax.min.z) / 2\r\n            );\r\n            this._rotateAnchorsParent.position.copyFrom(this._lineBoundingBox.position);\r\n            this._scaleBoxesParent.position.copyFrom(this._lineBoundingBox.position);\r\n            this._lineBoundingBox.computeWorldMatrix();\r\n            this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);\r\n\r\n            // Restore position/rotation values\r\n            this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);\r\n            this.attachedMesh.position.copyFrom(this._tmpVector);\r\n\r\n            // Restore original parent\r\n            this.attachedMesh.setParent(originalParent);\r\n        }\r\n\r\n        this._updateRotationAnchors();\r\n        this._updateScaleBoxes();\r\n\r\n        if (this.attachedMesh) {\r\n            this._existingMeshScale.copyFrom(this.attachedMesh.scaling);\r\n            PivotTools._RestorePivotPoint(this.attachedMesh);\r\n        }\r\n    }\r\n\r\n    protected _updateRotationAnchors() {\r\n        const rotateAnchors = this._rotateAnchorsParent.getChildMeshes();\r\n        for (let i = 0; i < 3; i++) {\r\n            for (let j = 0; j < 2; j++) {\r\n                for (let k = 0; k < 2; k++) {\r\n                    const index = i * 4 + j * 2 + k;\r\n                    rotateAnchors[index].position.normalizeToRef(TmpVectors.Vector3[0]);\r\n                    if (i == 0) {\r\n                        rotateAnchors[index].position.set(0, this._boundingDimensions.y * (j - 0.5), this._boundingDimensions.z * (k - 0.5));\r\n                        TmpVectors.Vector3[1].set(1, 0, 0);\r\n                    }\r\n                    if (i == 1) {\r\n                        rotateAnchors[index].position.set(this._boundingDimensions.x * (j - 0.5), 0, this._boundingDimensions.z * (k - 0.5));\r\n                        TmpVectors.Vector3[1].set(0, 1, 0);\r\n                    }\r\n                    if (i == 2) {\r\n                        rotateAnchors[index].position.set(this._boundingDimensions.x * (j - 0.5), this._boundingDimensions.y * (k - 0.5), 0);\r\n                        TmpVectors.Vector3[1].set(0, 0, 1);\r\n                    }\r\n                    const target = TmpVectors.Vector3[2];\r\n                    Vector3.CrossToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[1], target);\r\n                    target.normalize();\r\n                    target.addInPlace(rotateAnchors[index].position);\r\n                    rotateAnchors[index].lookAt(target);\r\n\r\n                    if (this.fixedDragMeshScreenSize && this.gizmoLayer.utilityLayerScene.activeCamera) {\r\n                        rotateAnchors[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera.position, this._tmpVector);\r\n                        const distanceFromCamera = (this.rotationSphereSize * this._tmpVector.length()) / this.fixedDragMeshScreenSizeDistanceFactor;\r\n                        rotateAnchors[index].scaling.set(distanceFromCamera, distanceFromCamera, distanceFromCamera);\r\n                    } else if (this.fixedDragMeshBoundsSize) {\r\n                        rotateAnchors[index].scaling.set(\r\n                            this.rotationSphereSize * this._boundingDimensions.x,\r\n                            this.rotationSphereSize * this._boundingDimensions.y,\r\n                            this.rotationSphereSize * this._boundingDimensions.z\r\n                        );\r\n                    } else {\r\n                        rotateAnchors[index].scaling.set(this.rotationSphereSize, this.rotationSphereSize, this.rotationSphereSize);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _updateScaleBoxes() {\r\n        const scaleBoxes = this._scaleBoxesParent.getChildMeshes();\r\n        let index = 0;\r\n        for (let i = 0; i < 3; i++) {\r\n            for (let j = 0; j < 3; j++) {\r\n                for (let k = 0; k < 3; k++) {\r\n                    const zeroAxisCount = (i === 1 ? 1 : 0) + (j === 1 ? 1 : 0) + (k === 1 ? 1 : 0);\r\n                    if (zeroAxisCount === 1 || zeroAxisCount === 3) {\r\n                        continue;\r\n                    }\r\n                    if (scaleBoxes[index]) {\r\n                        scaleBoxes[index].position.set(this._boundingDimensions.x * (i / 2), this._boundingDimensions.y * (j / 2), this._boundingDimensions.z * (k / 2));\r\n                        scaleBoxes[index].position.addInPlace(new Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));\r\n                        if (this.fixedDragMeshScreenSize && this.gizmoLayer.utilityLayerScene.activeCamera) {\r\n                            scaleBoxes[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera.globalPosition, this._tmpVector);\r\n                            const distanceFromCamera = (this.scaleBoxSize * this._tmpVector.length()) / this.fixedDragMeshScreenSizeDistanceFactor;\r\n                            scaleBoxes[index].scaling.set(distanceFromCamera, distanceFromCamera, distanceFromCamera);\r\n                        } else if (this.fixedDragMeshBoundsSize) {\r\n                            scaleBoxes[index].scaling.set(\r\n                                this.scaleBoxSize * this._boundingDimensions.x,\r\n                                this.scaleBoxSize * this._boundingDimensions.y,\r\n                                this.scaleBoxSize * this._boundingDimensions.z\r\n                            );\r\n                        } else {\r\n                            scaleBoxes[index].scaling.set(this.scaleBoxSize, this.scaleBoxSize, this.scaleBoxSize);\r\n                        }\r\n                    }\r\n                    index++;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables rotation on the specified axis and disables rotation on the others\r\n     * @param axis The list of axis that should be enabled (eg. \"xy\" or \"xyz\")\r\n     */\r\n    public setEnabledRotationAxis(axis: string) {\r\n        const meshes = this._rotateAnchorsParent.getChildMeshes();\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const m = meshes[i] as Mesh;\r\n            if (i < 4) {\r\n                m.setEnabled(axis.indexOf(\"x\") != -1);\r\n            } else if (i < 8) {\r\n                m.setEnabled(axis.indexOf(\"y\") != -1);\r\n            } else {\r\n                m.setEnabled(axis.indexOf(\"z\") != -1);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables/disables scaling\r\n     * @param enable if scaling should be enabled\r\n     * @param homogeneousScaling defines if scaling should only be homogeneous\r\n     */\r\n    public setEnabledScaling(enable: boolean, homogeneousScaling = false) {\r\n        const meshes = this._scaleBoxesParent.getChildMeshes();\r\n        for (const m of meshes) {\r\n            let enableMesh = enable;\r\n            // Disable heterogeneous scale handles if requested.\r\n            if (homogeneousScaling && m._internalMetadata === true) {\r\n                enableMesh = false;\r\n            }\r\n            m.setEnabled(enableMesh);\r\n        }\r\n    }\r\n\r\n    protected _updateDummy() {\r\n        if (this._dragMesh) {\r\n            this._dragMesh.position.copyFrom(this._lineBoundingBox.getAbsolutePosition());\r\n            this._dragMesh.scaling.copyFrom(this._lineBoundingBox.scaling);\r\n            this._dragMesh.rotationQuaternion!.copyFrom(this._rootMesh.rotationQuaternion!);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables a pointer drag behavior on the bounding box of the gizmo\r\n     */\r\n    public enableDragBehavior() {\r\n        this._dragMesh = CreateBox(\"dummy\", { size: 1 }, this.gizmoLayer.utilityLayerScene);\r\n        this._dragMesh.visibility = 0;\r\n        this._dragMesh.rotationQuaternion = new Quaternion();\r\n        this._pointerDragBehavior.useObjectOrientationForDragging = false;\r\n        this._dragMesh.addBehavior(this._pointerDragBehavior);\r\n    }\r\n\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    public releaseDrag() {\r\n        for (const dragBehavior of this._scaleBoxesDragBehaviors) {\r\n            dragBehavior.releaseDrag();\r\n        }\r\n        for (const dragBehavior of this._rotateAnchorsDragBehaviors) {\r\n            dragBehavior.releaseDrag();\r\n        }\r\n        this._pointerDragBehavior.releaseDrag();\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this.gizmoLayer.originalScene.onBeforeRenderObservable.remove(this._renderObserver);\r\n        this.gizmoLayer.originalScene.onKeyboardObservable.remove(this._centerScaleKeyObserver);\r\n        this._lineBoundingBox.dispose();\r\n        this._rotateAnchorsParent.dispose();\r\n        this._scaleBoxesParent.dispose();\r\n        if (this._dragMesh) {\r\n            this._dragMesh.dispose();\r\n        }\r\n        this._scaleBoxesDragBehaviors.length = 0;\r\n        this._rotateAnchorsDragBehaviors.length = 0;\r\n        this.onDragStartObservable.clear();\r\n        this.onHoverStartObservable.clear();\r\n        this.onHoverEndObservable.clear();\r\n        this.onScaleBoxDragObservable.clear();\r\n        this.onScaleBoxDragEndObservable.clear();\r\n        this.onRotationSphereDragObservable.clear();\r\n        this.onRotationSphereDragEndObservable.clear();\r\n\r\n        this._coloredMaterial.dispose();\r\n        this._hoverColoredMaterial.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Makes a mesh not pickable and wraps the mesh inside of a bounding box mesh that is pickable. (This is useful to avoid picking within complex geometry)\r\n     * @param mesh the mesh to wrap in the bounding box mesh and make not pickable\r\n     * @returns the bounding box mesh with the passed in mesh as a child\r\n     */\r\n    public static MakeNotPickableAndWrapInBoundingBox(mesh: Mesh): Mesh {\r\n        const makeNotPickable = (root: AbstractMesh) => {\r\n            root.isPickable = false;\r\n            const children = root.getChildMeshes();\r\n            for (const c of children) {\r\n                makeNotPickable(c);\r\n            }\r\n        };\r\n        makeNotPickable(mesh);\r\n\r\n        // Reset position to get bounding box from origin with no rotation\r\n        if (!mesh.rotationQuaternion) {\r\n            mesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);\r\n        }\r\n        const oldPos = mesh.position.clone();\r\n        const oldRot = mesh.rotationQuaternion.clone();\r\n        mesh.rotationQuaternion.set(0, 0, 0, 1);\r\n        mesh.position.set(0, 0, 0);\r\n\r\n        // Update bounding dimensions/positions\r\n        const box = CreateBox(\"box\", { size: 1 }, mesh.getScene());\r\n        const boundingMinMax = mesh.getHierarchyBoundingVectors();\r\n        boundingMinMax.max.subtractToRef(boundingMinMax.min, box.scaling);\r\n\r\n        // Adjust scale to avoid undefined behavior when adding child\r\n        if (box.scaling.y === 0) {\r\n            box.scaling.y = Epsilon;\r\n        }\r\n        if (box.scaling.x === 0) {\r\n            box.scaling.x = Epsilon;\r\n        }\r\n        if (box.scaling.z === 0) {\r\n            box.scaling.z = Epsilon;\r\n        }\r\n\r\n        box.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);\r\n\r\n        // Restore original positions\r\n        mesh.addChild(box);\r\n        mesh.rotationQuaternion.copyFrom(oldRot);\r\n        mesh.position.copyFrom(oldPos);\r\n\r\n        // Reverse parenting\r\n        mesh.removeChild(box);\r\n\r\n        box.addChild(mesh);\r\n        box.visibility = 0;\r\n        return box;\r\n    }\r\n    /**\r\n     * CustomMeshes are not supported by this gizmo\r\n     */\r\n    public override setCustomMesh() {\r\n        Logger.Error(\"Custom meshes are not supported on this gizmo\");\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { Quaternion, Matrix, Vector3, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { PointerDragBehavior } from \"../Behaviors/Meshes/pointerDragBehavior\";\r\nimport { type GizmoAxisCache, type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type RotationGizmo } from \"./rotationGizmo\";\r\nimport { ShaderMaterial } from \"../Materials/shaderMaterial.pure\";\r\nimport { Effect } from \"../Materials/effect.pure\";\r\nimport { CreatePlane } from \"../Meshes/Builders/planeBuilder.pure\";\r\nimport { CreateTorus } from \"../Meshes/Builders/torusBuilder.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type TransformNode } from \"../Meshes/transformNode.pure\";\r\n\r\n/**\r\n * Interface for plane rotation gizmo\r\n */\r\nexport interface IPlaneRotationGizmo extends IGizmo {\r\n    /** Drag behavior responsible for the gizmos dragging interactions */\r\n    dragBehavior: PointerDragBehavior;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /** Sensitivity factor for dragging */\r\n    sensitivity: number;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in angle\r\n     */\r\n    onSnapObservable: Observable<{ snapDistance: number }>;\r\n    /** Accumulated relative angle value for rotation on the axis. */\r\n    angle: number;\r\n    /** If the gizmo is enabled */\r\n    isEnabled: boolean;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    coloredMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is hovered with mouse */\r\n    hoverMaterial: StandardMaterial;\r\n    /** Color used to render the drag angle sector when gizmo is rotated with mouse */\r\n    rotationColor: Color3;\r\n    /** Material used to render when gizmo is disabled. typically grey. */\r\n    disableMaterial: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Single plane rotation gizmo\r\n */\r\nexport class PlaneRotationGizmo extends Gizmo implements IPlaneRotationGizmo {\r\n    /**\r\n     * Drag behavior responsible for the gizmos dragging interactions\r\n     */\r\n    public dragBehavior: PointerDragBehavior;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n\r\n    /**\r\n     * Rotation distance in radians that the gizmo will snap to (Default: 0)\r\n     */\r\n    public snapDistance = 0;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in angle\r\n     */\r\n    public onSnapObservable = new Observable<{ snapDistance: number }>();\r\n\r\n    /**\r\n     * The maximum angle between the camera and the rotation allowed for interaction\r\n     * If a rotation plane appears 'flat', a lower value allows interaction.\r\n     */\r\n    public static MaxDragAngle: number = (Math.PI * 9) / 20;\r\n\r\n    /**\r\n     * Accumulated relative angle value for rotation on the axis. Reset to 0 when a dragStart occurs\r\n     */\r\n    public angle: number = 0;\r\n\r\n    /**\r\n     * Custom sensitivity value for the drag strength\r\n     */\r\n    public sensitivity = 1;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    public get coloredMaterial() {\r\n        return this._coloredMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is hovered with mouse */\r\n    public get hoverMaterial() {\r\n        return this._hoverMaterial;\r\n    }\r\n\r\n    /** Color used to render the drag angle sector when gizmo is rotated with mouse */\r\n    public set rotationColor(color: Color3) {\r\n        this._rotationShaderMaterial.setColor3(\"rotationColor\", color);\r\n    }\r\n\r\n    /** Material used to render when gizmo is disabled. typically grey. */\r\n    public get disableMaterial() {\r\n        return this._disableMaterial;\r\n    }\r\n\r\n    protected _isEnabled: boolean = true;\r\n    protected _parent: Nullable<RotationGizmo> = null;\r\n    protected _coloredMaterial: StandardMaterial;\r\n    protected _hoverMaterial: StandardMaterial;\r\n    protected _disableMaterial: StandardMaterial;\r\n    protected _gizmoMesh: Mesh;\r\n    protected _rotationDisplayPlane: Mesh;\r\n    protected _dragging: boolean = false;\r\n    protected _angles = new Vector3();\r\n\r\n    protected static _RotationGizmoVertexShader = `\r\n        precision highp float;\r\n        attribute vec3 position;\r\n        attribute vec2 uv;\r\n        uniform mat4 worldViewProjection;\r\n        varying vec3 vPosition;\r\n        varying vec2 vUV;\r\n\r\n        void main(void) {\r\n            gl_Position = worldViewProjection * vec4(position, 1.0);\r\n            vUV = uv;\r\n        }`;\r\n\r\n    protected static _RotationGizmoFragmentShader = `\r\n        precision highp float;\r\n        varying vec2 vUV;\r\n        varying vec3 vPosition;\r\n        uniform vec3 angles;\r\n        uniform vec3 rotationColor;\r\n\r\n        #define twopi 6.283185307\r\n\r\n        void main(void) {\r\n            vec2 uv = vUV - vec2(0.5);\r\n            float angle = atan(uv.y, uv.x) + 3.141592;\r\n            float delta = gl_FrontFacing ? angles.y : -angles.y;\r\n            float begin = angles.x - delta * angles.z;\r\n            float start = (begin < (begin + delta)) ? begin : (begin + delta);\r\n            float end = (begin > (begin + delta)) ? begin : (begin + delta);\r\n            float len = sqrt(dot(uv,uv));\r\n            float opacity = 1. - step(0.5, len);\r\n\r\n            float base = abs(floor(start / twopi)) * twopi;\r\n            start += base;\r\n            end += base;\r\n\r\n            float intensity = 0.;\r\n            for (int i = 0; i < 5; i++)\r\n            {\r\n                intensity += max(step(start, angle) - step(end, angle), 0.);\r\n                angle += twopi;\r\n            }\r\n            gl_FragColor = vec4(rotationColor, min(intensity * 0.25, 0.8)) * opacity;\r\n        }\r\n    `;\r\n\r\n    protected _rotationShaderMaterial: ShaderMaterial;\r\n\r\n    /**\r\n     * Creates a PlaneRotationGizmo\r\n     * @param planeNormal The normal of the plane which the gizmo will be able to rotate on\r\n     * @param color The color of the gizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param tessellation Amount of tessellation to be used when creating rotation circles\r\n     * @param parent\r\n     * @param useEulerRotation Use and update Euler angle instead of quaternion\r\n     * @param thickness display gizmo axis thickness\r\n     * @param hoverColor The color of the gizmo when hovering over and dragging\r\n     * @param disableColor The Color of the gizmo when its disabled\r\n     */\r\n    constructor(\r\n        planeNormal: Vector3,\r\n        color: Color3 = Color3.Gray(),\r\n        gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer,\r\n        tessellation = 32,\r\n        parent: Nullable<RotationGizmo> = null,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        useEulerRotation = false,\r\n        thickness: number = 1,\r\n        hoverColor: Color3 = Color3.Yellow(),\r\n        disableColor: Color3 = Color3.Gray()\r\n    ) {\r\n        super(gizmoLayer);\r\n        this._parent = parent;\r\n        // Create Material\r\n        this._coloredMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._coloredMaterial.diffuseColor = color;\r\n        this._coloredMaterial.specularColor = color.subtract(new Color3(0.1, 0.1, 0.1));\r\n\r\n        this._hoverMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._hoverMaterial.diffuseColor = hoverColor;\r\n        this._hoverMaterial.specularColor = hoverColor;\r\n\r\n        this._disableMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._disableMaterial.diffuseColor = disableColor;\r\n        this._disableMaterial.alpha = 0.4;\r\n\r\n        // Build mesh on root node\r\n        this._gizmoMesh = new Mesh(\"\", gizmoLayer.utilityLayerScene);\r\n        const { rotationMesh, collider } = this._createGizmoMesh(this._gizmoMesh, thickness, tessellation);\r\n\r\n        // Setup Rotation Circle\r\n        this._rotationDisplayPlane = CreatePlane(\r\n            \"rotationDisplay\",\r\n            {\r\n                size: 0.6,\r\n                updatable: false,\r\n            },\r\n            this.gizmoLayer.utilityLayerScene\r\n        );\r\n        this._rotationDisplayPlane.rotation.z = Math.PI * 0.5;\r\n        this._rotationDisplayPlane.parent = this._gizmoMesh;\r\n        this._rotationDisplayPlane.setEnabled(false);\r\n\r\n        Effect.ShadersStore[\"rotationGizmoVertexShader\"] = PlaneRotationGizmo._RotationGizmoVertexShader;\r\n        Effect.ShadersStore[\"rotationGizmoFragmentShader\"] = PlaneRotationGizmo._RotationGizmoFragmentShader;\r\n        this._rotationShaderMaterial = new ShaderMaterial(\r\n            \"shader\",\r\n            this.gizmoLayer.utilityLayerScene,\r\n            {\r\n                vertex: \"rotationGizmo\",\r\n                fragment: \"rotationGizmo\",\r\n            },\r\n            {\r\n                attributes: [\"position\", \"uv\"],\r\n                uniforms: [\"worldViewProjection\", \"angles\", \"rotationColor\"],\r\n            }\r\n        );\r\n        this._rotationShaderMaterial.backFaceCulling = false;\r\n        this.rotationColor = hoverColor;\r\n\r\n        this._rotationDisplayPlane.material = this._rotationShaderMaterial;\r\n        this._rotationDisplayPlane.visibility = 0.999;\r\n\r\n        this._gizmoMesh.lookAt(this._rootMesh.position.add(planeNormal));\r\n        this._rootMesh.addChild(this._gizmoMesh, Gizmo.PreserveScaling);\r\n        this._gizmoMesh.scaling.scaleInPlace(1 / 3);\r\n        // Add drag behavior to handle events when the gizmo is dragged\r\n        this.dragBehavior = new PointerDragBehavior({ dragPlaneNormal: planeNormal });\r\n        this.dragBehavior.moveAttached = false;\r\n        this.dragBehavior.maxDragAngle = PlaneRotationGizmo.MaxDragAngle;\r\n        this.dragBehavior._useAlternatePickedPointAboveMaxDragAngle = true;\r\n        this._rootMesh.addBehavior(this.dragBehavior);\r\n\r\n        // Closures for drag logic\r\n        const lastDragPosition = new Vector3();\r\n\r\n        const rotationMatrix = new Matrix();\r\n        const planeNormalTowardsCamera = new Vector3();\r\n        let localPlaneNormalTowardsCamera = new Vector3();\r\n\r\n        this.dragBehavior.onDragStartObservable.add((e) => {\r\n            if (this.attachedNode) {\r\n                if (this._additionalTransformNode) {\r\n                    this._additionalTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n                    Vector3.TransformCoordinatesToRef(e.dragPlanePoint, TmpVectors.Matrix[0], e.dragPlanePoint);\r\n                }\r\n                lastDragPosition.copyFrom(e.dragPlanePoint);\r\n                this._rotationDisplayPlane.setEnabled(true);\r\n\r\n                this._rotationDisplayPlane.getWorldMatrix().invertToRef(rotationMatrix);\r\n                Vector3.TransformCoordinatesToRef(e.dragPlanePoint, rotationMatrix, lastDragPosition);\r\n\r\n                this._angles.x = Math.atan2(lastDragPosition.y, lastDragPosition.x) + Math.PI;\r\n                this._angles.y = 0;\r\n                this._angles.z = this.updateGizmoRotationToMatchAttachedMesh ? 1 : 0;\r\n                this._dragging = true;\r\n                lastDragPosition.copyFrom(e.dragPlanePoint);\r\n                this._rotationShaderMaterial.setVector3(\"angles\", this._angles);\r\n                this.angle = 0;\r\n                // there is an issue with the rotation plane with additionalTransformNode, so we hide it in that case to avoid confusion\r\n                this._rotationDisplayPlane.visibility = this._additionalTransformNode ? 0 : 0.999;\r\n            }\r\n        });\r\n\r\n        this.dragBehavior.onDragEndObservable.add(() => {\r\n            this._dragging = false;\r\n            this._rotationDisplayPlane.setEnabled(false);\r\n        });\r\n\r\n        const tmpSnapEvent = { snapDistance: 0 };\r\n        let currentSnapDragDistance = 0;\r\n        const amountToRotate = new Quaternion();\r\n        this.dragBehavior.onDragObservable.add((event) => {\r\n            if (this.attachedNode) {\r\n                // Calc angle over full 360 degree (https://stackoverflow.com/questions/43493711/the-angle-between-two-3d-vectors-with-a-result-range-0-360)\r\n                const nodeScale = new Vector3(1, 1, 1);\r\n                const nodeQuaternion = new Quaternion(0, 0, 0, 1);\r\n                const nodeTranslation = new Vector3(0, 0, 0);\r\n                const attachedNodeTransform = this._attachedNode as TransformNode;\r\n                // check there is an active pivot for the TransformNode attached\r\n                if (attachedNodeTransform && attachedNodeTransform.isUsingPivotMatrix && attachedNodeTransform.isUsingPivotMatrix() && attachedNodeTransform.position) {\r\n                    // When a TransformNode has an active pivot, even without parenting,\r\n                    // translation from the world matrix is different from TransformNode.position.\r\n                    // Pivot works like a virtual parent that's using the node orientation.\r\n                    // As the world matrix is transformed by the gizmo and then decomposed to TRS\r\n                    // its translation part must be set to the Node's position.\r\n                    attachedNodeTransform.getWorldMatrix().setTranslation(attachedNodeTransform.position);\r\n                }\r\n\r\n                this.attachedNode.getWorldMatrix().decompose(nodeScale, nodeQuaternion, nodeTranslation);\r\n                // uniform scaling of absolute value of components\r\n                // (-1,1,1) is uniform but (1,1.001,1) is not\r\n                const uniformScaling = Math.abs(Math.abs(nodeScale.x) - Math.abs(nodeScale.y)) <= Epsilon && Math.abs(Math.abs(nodeScale.x) - Math.abs(nodeScale.z)) <= Epsilon;\r\n                if (!uniformScaling && this.updateGizmoRotationToMatchAttachedMesh) {\r\n                    Logger.Warn(\r\n                        \"Unable to use a rotation gizmo matching mesh rotation with non uniform scaling. Use uniform scaling or set updateGizmoRotationToMatchAttachedMesh to false.\"\r\n                    );\r\n                    return;\r\n                }\r\n                nodeQuaternion.normalize();\r\n\r\n                const nodeTranslationForOperation = this.updateGizmoPositionToMatchAttachedMesh ? nodeTranslation : this._rootMesh.absolutePosition;\r\n                if (this._additionalTransformNode) {\r\n                    this._additionalTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n                    Vector3.TransformCoordinatesToRef(event.dragPlanePoint, TmpVectors.Matrix[0], event.dragPlanePoint);\r\n                }\r\n                const newVector = event.dragPlanePoint.subtract(nodeTranslationForOperation).normalize();\r\n                const originalVector = lastDragPosition.subtract(nodeTranslationForOperation).normalize();\r\n                const cross = Vector3.Cross(newVector, originalVector);\r\n                const dot = Vector3.Dot(newVector, originalVector);\r\n                let angle = Math.atan2(cross.length(), dot) * this.sensitivity;\r\n                planeNormalTowardsCamera.copyFrom(planeNormal);\r\n                localPlaneNormalTowardsCamera.copyFrom(planeNormal);\r\n                if (this.updateGizmoRotationToMatchAttachedMesh) {\r\n                    nodeQuaternion.toRotationMatrix(rotationMatrix);\r\n                    localPlaneNormalTowardsCamera = Vector3.TransformCoordinates(planeNormalTowardsCamera, rotationMatrix);\r\n                }\r\n                // Flip up vector depending on which side the camera is on\r\n                let cameraFlipped = false;\r\n                if (gizmoLayer.utilityLayerScene.activeCamera) {\r\n                    const camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(nodeTranslationForOperation).normalize();\r\n                    if (Vector3.Dot(camVec, localPlaneNormalTowardsCamera) > 0) {\r\n                        planeNormalTowardsCamera.scaleInPlace(-1);\r\n                        localPlaneNormalTowardsCamera.scaleInPlace(-1);\r\n                        cameraFlipped = true;\r\n                    }\r\n                }\r\n                const halfCircleSide = Vector3.Dot(localPlaneNormalTowardsCamera, cross) > 0.0;\r\n                if (halfCircleSide) {\r\n                    angle = -angle;\r\n                }\r\n\r\n                TmpVectors.Vector3[0].set(angle, 0, 0);\r\n                if (!this.dragBehavior.validateDrag(TmpVectors.Vector3[0])) {\r\n                    angle = 0;\r\n                }\r\n\r\n                // Snapping logic\r\n                let snapped = false;\r\n                if (this.snapDistance != 0) {\r\n                    currentSnapDragDistance += angle;\r\n                    if (Math.abs(currentSnapDragDistance) > this.snapDistance) {\r\n                        let dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / this.snapDistance);\r\n                        if (currentSnapDragDistance < 0) {\r\n                            dragSteps *= -1;\r\n                        }\r\n                        currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;\r\n                        angle = this.snapDistance * dragSteps;\r\n                        snapped = true;\r\n                    } else {\r\n                        angle = 0;\r\n                    }\r\n                }\r\n\r\n                // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)\r\n                const quaternionCoefficient = Math.sin(angle / 2);\r\n                amountToRotate.set(\r\n                    planeNormalTowardsCamera.x * quaternionCoefficient,\r\n                    planeNormalTowardsCamera.y * quaternionCoefficient,\r\n                    planeNormalTowardsCamera.z * quaternionCoefficient,\r\n                    Math.cos(angle / 2)\r\n                );\r\n\r\n                if (this.updateGizmoRotationToMatchAttachedMesh) {\r\n                    // Rotate selected mesh quaternion over fixed axis\r\n                    nodeQuaternion.multiplyToRef(amountToRotate, nodeQuaternion);\r\n                    nodeQuaternion.normalize();\r\n                    // recompose matrix\r\n                    Matrix.ComposeToRef(nodeScale, nodeQuaternion, nodeTranslation, this.attachedNode.getWorldMatrix());\r\n                } else {\r\n                    // Rotate selected mesh quaternion over rotated axis\r\n                    amountToRotate.toRotationMatrix(TmpVectors.Matrix[0]);\r\n                    const translation = this.attachedNode.getWorldMatrix().getTranslation();\r\n                    this.attachedNode.getWorldMatrix().multiplyToRef(TmpVectors.Matrix[0], this.attachedNode.getWorldMatrix());\r\n                    this.attachedNode.getWorldMatrix().setTranslation(translation);\r\n                }\r\n\r\n                lastDragPosition.copyFrom(event.dragPlanePoint);\r\n                if (snapped) {\r\n                    tmpSnapEvent.snapDistance = angle;\r\n                    this.onSnapObservable.notifyObservers(tmpSnapEvent);\r\n                }\r\n                this._angles.y += gizmoLayer.utilityLayerScene.useRightHandedSystem ? -angle : angle;\r\n                this.angle += cameraFlipped ? -angle : angle;\r\n                this._rotationShaderMaterial.setVector3(\"angles\", this._angles);\r\n                this._matrixChanged();\r\n            }\r\n        });\r\n\r\n        const light = gizmoLayer._getSharedGizmoLight();\r\n        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(this._rootMesh.getChildMeshes(false));\r\n\r\n        const cache: GizmoAxisCache = {\r\n            colliderMeshes: [collider],\r\n            gizmoMeshes: [rotationMesh],\r\n            material: this._coloredMaterial,\r\n            hoverMaterial: this._hoverMaterial,\r\n            disableMaterial: this._disableMaterial,\r\n            active: false,\r\n            dragBehavior: this.dragBehavior,\r\n        };\r\n        this._parent?.addToAxisCache(this._gizmoMesh, cache);\r\n\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (this._customMeshSet) {\r\n                return;\r\n            }\r\n            // updating here the maxangle because ondragstart is too late (value already used) and the updated value is not taken into account\r\n            this.dragBehavior.maxDragAngle = PlaneRotationGizmo.MaxDragAngle;\r\n            this._isHovered = !!(cache.colliderMeshes.indexOf(<Mesh>pointerInfo?.pickInfo?.pickedMesh) != -1);\r\n            if (!this._parent) {\r\n                const material = cache.dragBehavior.enabled ? (this._isHovered || this._dragging ? this._hoverMaterial : this._coloredMaterial) : this._disableMaterial;\r\n                this._setGizmoMeshMaterial(cache.gizmoMeshes, material);\r\n            }\r\n        });\r\n\r\n        this.dragBehavior.onEnabledObservable.add((newState) => {\r\n            this._setGizmoMeshMaterial(cache.gizmoMeshes, newState ? this._coloredMaterial : this._disableMaterial);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Create Geometry for Gizmo\r\n     * @param parentMesh\r\n     * @param thickness\r\n     * @param tessellation\r\n     * @returns\r\n     */\r\n    protected _createGizmoMesh(parentMesh: AbstractMesh, thickness: number, tessellation: number) {\r\n        const collider = CreateTorus(\r\n            \"ignore\",\r\n            {\r\n                diameter: 0.6,\r\n                thickness: 0.03 * thickness,\r\n                tessellation,\r\n            },\r\n            this.gizmoLayer.utilityLayerScene\r\n        );\r\n        collider.visibility = 0;\r\n        const rotationMesh = CreateTorus(\r\n            \"\",\r\n            {\r\n                diameter: 0.6,\r\n                thickness: 0.005 * thickness,\r\n                tessellation,\r\n            },\r\n            this.gizmoLayer.utilityLayerScene\r\n        );\r\n        rotationMesh.material = this._coloredMaterial;\r\n\r\n        // Position arrow pointing in its drag axis\r\n        rotationMesh.rotation.x = Math.PI / 2;\r\n        collider.rotation.x = Math.PI / 2;\r\n\r\n        parentMesh.addChild(rotationMesh, Gizmo.PreserveScaling);\r\n        parentMesh.addChild(collider, Gizmo.PreserveScaling);\r\n        return { rotationMesh, collider };\r\n    }\r\n\r\n    protected override _attachedNodeChanged(value: Nullable<Node>) {\r\n        if (this.dragBehavior) {\r\n            this.dragBehavior.enabled = value ? true : false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the gizmo is enabled\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        this._isEnabled = value;\r\n        if (!value) {\r\n            this.attachedMesh = null;\r\n        } else {\r\n            if (this._parent) {\r\n                this.attachedMesh = this._parent.attachedMesh;\r\n            }\r\n        }\r\n    }\r\n\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        this.onSnapObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this.dragBehavior.detach();\r\n        if (this._gizmoMesh) {\r\n            this._gizmoMesh.dispose();\r\n        }\r\n        if (this._rotationDisplayPlane) {\r\n            this._rotationDisplayPlane.dispose();\r\n        }\r\n        if (this._rotationShaderMaterial) {\r\n            this._rotationShaderMaterial.dispose();\r\n        }\r\n        const materials = [this._coloredMaterial, this._hoverMaterial, this._disableMaterial];\r\n        for (const matl of materials) {\r\n            if (matl) {\r\n                matl.dispose();\r\n            }\r\n        }\r\n        super.dispose();\r\n    }\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type EventState, type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector3, type Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type GizmoAnchorPoint, type GizmoCoordinatesMode, type GizmoAxisCache, type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { type IPlaneRotationGizmo, PlaneRotationGizmo } from \"./planeRotationGizmo.pure\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { type Node } from \"../node\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type GizmoManager } from \"./gizmoManager\";\r\nimport { type DragEvent, type DragStartEndEvent } from \"core/Behaviors/Meshes/pointerDragEvents\";\r\n\r\n/**\r\n * Interface for rotation gizmo\r\n */\r\nexport interface IRotationGizmo extends IGizmo {\r\n    /** True when the mouse pointer is dragging a gizmo mesh */\r\n    readonly isDragging: boolean;\r\n    /** Internal gizmo used for interactions on the x axis */\r\n    xGizmo: IPlaneRotationGizmo;\r\n    /** Internal gizmo used for interactions on the y axis */\r\n    yGizmo: IPlaneRotationGizmo;\r\n    /** Internal gizmo used for interactions on the z axis */\r\n    zGizmo: IPlaneRotationGizmo;\r\n    /** Fires an event when any of it's sub gizmos are dragged */\r\n    onDragStartObservable: Observable<DragStartEndEvent>;\r\n    /** Fires an event when any of it's sub gizmos are being dragged */\r\n    onDragObservable: Observable<DragEvent>;\r\n    /** Fires an event when any of it's sub gizmos are released from dragging */\r\n    onDragEndObservable: Observable<DragStartEndEvent>;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /** Custom sensitivity value for the drag strength */\r\n    sensitivity: number;\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param mesh Axis gizmo mesh\r\n     * @param cache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    addToAxisCache(mesh: Mesh, cache: GizmoAxisCache): void;\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    releaseDrag(): void;\r\n}\r\n\r\n/**\r\n * Options for each individual plane rotation gizmo contained within RotationGizmo\r\n * @since 5.0.0\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PlaneRotationGizmoOptions {\r\n    /**\r\n     * Color to use for the plane rotation gizmo\r\n     */\r\n    color?: Color3;\r\n}\r\n\r\n/**\r\n * Additional options for each rotation gizmo\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface RotationGizmoOptions {\r\n    /**\r\n     * When set, the gizmo will always appear the same size no matter where the camera is (default: true)\r\n     */\r\n    updateScale?: boolean;\r\n\r\n    /**\r\n     * Specific options for xGizmo\r\n     */\r\n    xOptions?: PlaneRotationGizmoOptions;\r\n\r\n    /**\r\n     * Specific options for yGizmo\r\n     */\r\n    yOptions?: PlaneRotationGizmoOptions;\r\n\r\n    /**\r\n     * Specific options for zGizmo\r\n     */\r\n    zOptions?: PlaneRotationGizmoOptions;\r\n\r\n    /**\r\n     * Additional transform applied to the gizmo.\r\n     * @See Gizmo.additionalTransformNode for more detail\r\n     */\r\n    additionalTransformNode?: TransformNode;\r\n}\r\n\r\n/**\r\n * Gizmo that enables rotating a mesh along 3 axis\r\n */\r\nexport class RotationGizmo extends Gizmo implements IRotationGizmo {\r\n    /**\r\n     * Internal gizmo used for interactions on the x axis\r\n     */\r\n    public xGizmo: IPlaneRotationGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the y axis\r\n     */\r\n    public yGizmo: IPlaneRotationGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the z axis\r\n     */\r\n    public zGizmo: IPlaneRotationGizmo;\r\n\r\n    /** Fires an event when any of it's sub gizmos are dragged */\r\n    public onDragStartObservable = new Observable<DragStartEndEvent>();\r\n    /** Fires an event when any of it's sub gizmos are being dragged */\r\n    public onDragObservable = new Observable<DragEvent>();\r\n    /** Fires an event when any of it's sub gizmos are released from dragging */\r\n    public onDragEndObservable = new Observable<DragStartEndEvent>();\r\n\r\n    protected _meshAttached: Nullable<AbstractMesh>;\r\n    protected _nodeAttached: Nullable<Node>;\r\n    protected _observables: Observer<PointerInfo>[] = [];\r\n    protected _sensitivity: number = 1;\r\n\r\n    /** Node Caching for quick lookup */\r\n    protected _gizmoAxisCache: Map<Mesh, GizmoAxisCache> = new Map();\r\n\r\n    public override get attachedMesh() {\r\n        return this._meshAttached;\r\n    }\r\n    public override set attachedMesh(mesh: Nullable<AbstractMesh>) {\r\n        this._meshAttached = mesh;\r\n        this._nodeAttached = mesh;\r\n        this._checkBillboardTransform();\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo.isEnabled) {\r\n                gizmo.attachedMesh = mesh;\r\n            } else {\r\n                gizmo.attachedMesh = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    public override get attachedNode() {\r\n        return this._nodeAttached;\r\n    }\r\n    public override set attachedNode(node: Nullable<Node>) {\r\n        this._meshAttached = null;\r\n        this._nodeAttached = node;\r\n        this._checkBillboardTransform();\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo.isEnabled) {\r\n                gizmo.attachedNode = node;\r\n            } else {\r\n                gizmo.attachedNode = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _checkBillboardTransform() {\r\n        if (this._nodeAttached && (<TransformNode>this._nodeAttached).billboardMode) {\r\n            Logger.Log(\"Rotation Gizmo will not work with transforms in billboard mode.\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sensitivity factor for dragging (Default: 1)\r\n     */\r\n    public set sensitivity(value: number) {\r\n        this._sensitivity = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.sensitivity = value;\r\n            }\r\n        }\r\n    }\r\n    public get sensitivity() {\r\n        return this._sensitivity;\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is hovering a gizmo mesh\r\n     */\r\n    public override get isHovered() {\r\n        return this.xGizmo.isHovered || this.yGizmo.isHovered || this.zGizmo.isHovered;\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is dragging a gizmo mesh\r\n     */\r\n    public get isDragging() {\r\n        return this.xGizmo.dragBehavior.dragging || this.yGizmo.dragBehavior.dragging || this.zGizmo.dragBehavior.dragging;\r\n    }\r\n\r\n    public override get additionalTransformNode() {\r\n        return this._additionalTransformNode;\r\n    }\r\n\r\n    public override set additionalTransformNode(transformNode: TransformNode | undefined) {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.additionalTransformNode = transformNode;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a RotationGizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param tessellation Amount of tessellation to be used when creating rotation circles\r\n     * @param useEulerRotation Use and update Euler angle instead of quaternion\r\n     * @param thickness display gizmo axis thickness\r\n     * @param gizmoManager Gizmo manager\r\n     * @param options More options\r\n     */\r\n    constructor(\r\n        gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer,\r\n        tessellation = 32,\r\n        useEulerRotation = false,\r\n        thickness: number = 1,\r\n        gizmoManager?: GizmoManager,\r\n        options?: RotationGizmoOptions\r\n    ) {\r\n        super(gizmoLayer);\r\n        const xColor = options && options.xOptions && options.xOptions.color ? options.xOptions.color : Color3.Red().scale(0.5);\r\n        const yColor = options && options.yOptions && options.yOptions.color ? options.yOptions.color : Color3.Green().scale(0.5);\r\n        const zColor = options && options.zOptions && options.zOptions.color ? options.zOptions.color : Color3.Blue().scale(0.5);\r\n        this.xGizmo = new PlaneRotationGizmo(new Vector3(1, 0, 0), xColor, gizmoLayer, tessellation, this, useEulerRotation, thickness);\r\n        this.yGizmo = new PlaneRotationGizmo(new Vector3(0, 1, 0), yColor, gizmoLayer, tessellation, this, useEulerRotation, thickness);\r\n        this.zGizmo = new PlaneRotationGizmo(new Vector3(0, 0, 1), zColor, gizmoLayer, tessellation, this, useEulerRotation, thickness);\r\n\r\n        this.additionalTransformNode = options?.additionalTransformNode;\r\n\r\n        // Relay drag events and set update scale\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            //must set updateScale on each gizmo, as setting it on root RotationGizmo doesn't prevent individual gizmos from updating\r\n            //set it on startup since options are only applied once at construction time\r\n            if (options && options.updateScale != undefined) {\r\n                gizmo.updateScale = options.updateScale;\r\n            }\r\n            gizmo.dragBehavior.onDragStartObservable.add((eventData: DragStartEndEvent, eventState: EventState) =>\r\n                this.onDragStartObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n            gizmo.dragBehavior.onDragObservable.add((eventData: DragEvent, eventState: EventState) =>\r\n                this.onDragObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n            gizmo.dragBehavior.onDragEndObservable.add((eventData: DragStartEndEvent, eventState: EventState) =>\r\n                this.onDragEndObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n        }\r\n\r\n        this.attachedMesh = null;\r\n        this.attachedNode = null;\r\n\r\n        if (gizmoManager) {\r\n            gizmoManager.addToAxisCache(this._gizmoAxisCache);\r\n        } else {\r\n            // Only subscribe to pointer event if gizmoManager isnt\r\n            Gizmo.GizmoAxisPointerObserver(gizmoLayer, this._gizmoAxisCache);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)\r\n     * NOTE: This is only possible for meshes with uniform scaling, as otherwise it's not possible to decompose the rotation\r\n     */\r\n    public override set updateGizmoRotationToMatchAttachedMesh(value: boolean) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.updateGizmoRotationToMatchAttachedMesh = value;\r\n            this.yGizmo.updateGizmoRotationToMatchAttachedMesh = value;\r\n            this.zGizmo.updateGizmoRotationToMatchAttachedMesh = value;\r\n        }\r\n    }\r\n    public override get updateGizmoRotationToMatchAttachedMesh() {\r\n        return this.xGizmo.updateGizmoRotationToMatchAttachedMesh;\r\n    }\r\n\r\n    public override set updateGizmoPositionToMatchAttachedMesh(value: boolean) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.updateGizmoPositionToMatchAttachedMesh = value;\r\n            this.yGizmo.updateGizmoPositionToMatchAttachedMesh = value;\r\n            this.zGizmo.updateGizmoPositionToMatchAttachedMesh = value;\r\n        }\r\n    }\r\n    public override get updateGizmoPositionToMatchAttachedMesh() {\r\n        return this.xGizmo.updateGizmoPositionToMatchAttachedMesh;\r\n    }\r\n\r\n    public override set anchorPoint(value: GizmoAnchorPoint) {\r\n        this._anchorPoint = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.anchorPoint = value;\r\n        }\r\n    }\r\n    public override get anchorPoint() {\r\n        return this._anchorPoint;\r\n    }\r\n\r\n    /**\r\n     * Set the coordinate system to use. By default it's local.\r\n     * But it's possible for a user to tweak so its local for translation and world for rotation.\r\n     * In that case, setting the coordinate system will change `updateGizmoRotationToMatchAttachedMesh` and `updateGizmoPositionToMatchAttachedMesh`\r\n     */\r\n    public override set coordinatesMode(coordinatesMode: GizmoCoordinatesMode) {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.coordinatesMode = coordinatesMode;\r\n        }\r\n    }\r\n\r\n    public override set updateScale(value: boolean) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.updateScale = value;\r\n            this.yGizmo.updateScale = value;\r\n            this.zGizmo.updateScale = value;\r\n        }\r\n    }\r\n    public override get updateScale() {\r\n        return this.xGizmo.updateScale;\r\n    }\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)\r\n     */\r\n    public set snapDistance(value: number) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.snapDistance = value;\r\n            this.yGizmo.snapDistance = value;\r\n            this.zGizmo.snapDistance = value;\r\n        }\r\n    }\r\n    public get snapDistance() {\r\n        return this.xGizmo.snapDistance;\r\n    }\r\n\r\n    /**\r\n     * Ratio for the scale of the gizmo (Default: 1)\r\n     */\r\n    public override set scaleRatio(value: number) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.scaleRatio = value;\r\n            this.yGizmo.scaleRatio = value;\r\n            this.zGizmo.scaleRatio = value;\r\n        }\r\n    }\r\n    public override get scaleRatio() {\r\n        return this.xGizmo.scaleRatio;\r\n    }\r\n\r\n    /**\r\n     * Orientation that the gizmo will be displayed with.\r\n     * When set null, default value will be used (Quaternion(0, 0, 0, 1))\r\n     */\r\n    public override get customRotationQuaternion(): Nullable<Quaternion> {\r\n        return this._customRotationQuaternion;\r\n    }\r\n\r\n    public override set customRotationQuaternion(customRotationQuaternion: Nullable<Quaternion>) {\r\n        this._customRotationQuaternion = customRotationQuaternion;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.customRotationQuaternion = customRotationQuaternion;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param mesh Axis gizmo mesh\r\n     * @param cache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    public addToAxisCache(mesh: Mesh, cache: GizmoAxisCache) {\r\n        this._gizmoAxisCache.set(mesh, cache);\r\n    }\r\n\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    public releaseDrag() {\r\n        this.xGizmo.dragBehavior.releaseDrag();\r\n        this.yGizmo.dragBehavior.releaseDrag();\r\n        this.zGizmo.dragBehavior.releaseDrag();\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        this.xGizmo.dispose();\r\n        this.yGizmo.dispose();\r\n        this.zGizmo.dispose();\r\n        this.onDragStartObservable.clear();\r\n        this.onDragObservable.clear();\r\n        this.onDragEndObservable.clear();\r\n        for (const obs of this._observables) {\r\n            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(obs);\r\n        }\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * CustomMeshes are not supported by this gizmo\r\n     */\r\n    public override setCustomMesh() {\r\n        Logger.Error(\r\n            \"Custom meshes are not supported on this gizmo, please set the custom meshes on the gizmos contained within this one (gizmo.xGizmo, gizmo.yGizmo, gizmo.zGizmo)\"\r\n        );\r\n    }\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type Node } from \"../node\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { CreatePlane } from \"../Meshes/Builders/planeBuilder.pure\";\r\nimport { PointerDragBehavior } from \"../Behaviors/Meshes/pointerDragBehavior\";\r\nimport { type GizmoAxisCache, type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type PositionGizmo } from \"./positionGizmo\";\r\n\r\n/**\r\n * Interface for plane drag gizmo\r\n */\r\nexport interface IPlaneDragGizmo extends IGizmo {\r\n    /** Drag behavior responsible for the gizmos dragging interactions */\r\n    dragBehavior: PointerDragBehavior;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in distance\r\n     */\r\n    onSnapObservable: Observable<{ snapDistance: number }>;\r\n    /** If the gizmo is enabled */\r\n    isEnabled: boolean;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    coloredMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is hovered with mouse */\r\n    hoverMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is disabled. typically grey. */\r\n    disableMaterial: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Single plane drag gizmo\r\n */\r\nexport class PlaneDragGizmo extends Gizmo implements IPlaneDragGizmo {\r\n    /**\r\n     * Drag behavior responsible for the gizmos dragging interactions\r\n     */\r\n    public dragBehavior: PointerDragBehavior;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)\r\n     */\r\n    public snapDistance = 0;\r\n    /**\r\n     * Event that fires each time the gizmo snaps to a new location.\r\n     * * snapDistance is the change in distance\r\n     */\r\n    public onSnapObservable = new Observable<{ snapDistance: number }>();\r\n\r\n    protected _gizmoMesh: TransformNode;\r\n    protected _coloredMaterial: StandardMaterial;\r\n    protected _hoverMaterial: StandardMaterial;\r\n    protected _disableMaterial: StandardMaterial;\r\n\r\n    protected _isEnabled: boolean = false;\r\n    protected _parent: Nullable<PositionGizmo> = null;\r\n    protected _dragging: boolean = false;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    public get coloredMaterial() {\r\n        return this._coloredMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    public get hoverMaterial() {\r\n        return this._hoverMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    public get disableMaterial() {\r\n        return this._disableMaterial;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _CreatePlane(scene: Scene, material: StandardMaterial): TransformNode {\r\n        const plane = new TransformNode(\"plane\", scene);\r\n\r\n        //make sure plane is double sided\r\n        const dragPlane = CreatePlane(\"dragPlane\", { width: 0.1375, height: 0.1375, sideOrientation: 2 }, scene);\r\n        dragPlane.material = material;\r\n        dragPlane.parent = plane;\r\n        return plane;\r\n    }\r\n\r\n    /**\r\n     * Creates a PlaneDragGizmo\r\n     * @param dragPlaneNormal The axis normal to which the gizmo will be able to drag on\r\n     * @param color The color of the gizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param parent\r\n     * @param hoverColor The color of the gizmo when hovering over and dragging\r\n     * @param disableColor The Color of the gizmo when its disabled\r\n     */\r\n    constructor(\r\n        dragPlaneNormal: Vector3,\r\n        color: Color3 = Color3.Gray(),\r\n        gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer,\r\n        parent: Nullable<PositionGizmo> = null,\r\n        hoverColor: Color3 = Color3.Yellow(),\r\n        disableColor: Color3 = Color3.Gray()\r\n    ) {\r\n        super(gizmoLayer);\r\n        this._parent = parent;\r\n        // Create Material\r\n        this._coloredMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._coloredMaterial.diffuseColor = color;\r\n        this._coloredMaterial.specularColor = color.subtract(new Color3(0.1, 0.1, 0.1));\r\n\r\n        this._hoverMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._hoverMaterial.diffuseColor = hoverColor;\r\n\r\n        this._disableMaterial = new StandardMaterial(\"\", gizmoLayer.utilityLayerScene);\r\n        this._disableMaterial.diffuseColor = disableColor;\r\n        this._disableMaterial.alpha = 0.4;\r\n\r\n        // Build plane mesh on root node\r\n        this._gizmoMesh = PlaneDragGizmo._CreatePlane(gizmoLayer.utilityLayerScene, this._coloredMaterial);\r\n\r\n        this._gizmoMesh.lookAt(this._rootMesh.position.add(dragPlaneNormal));\r\n        this._gizmoMesh.scaling.scaleInPlace(1 / 3);\r\n        this._gizmoMesh.parent = this._rootMesh;\r\n\r\n        const currentSnapDragDistance = new Vector3();\r\n        const tmpVector = new Vector3();\r\n        const tmpVector2 = new Vector3();\r\n        const tmpSnapEvent = { snapDistance: 0 };\r\n        // Add dragPlaneNormal drag behavior to handle events when the gizmo is dragged\r\n        this.dragBehavior = new PointerDragBehavior({ dragPlaneNormal: dragPlaneNormal });\r\n        this.dragBehavior.moveAttached = false;\r\n        this._rootMesh.addBehavior(this.dragBehavior);\r\n\r\n        this.dragBehavior.onDragObservable.add((event) => {\r\n            if (this.attachedNode) {\r\n                // Keep world translation and use it to update world transform\r\n                // if the node has parent, the local transform properties (position, rotation, scale)\r\n                // will be recomputed in _matrixChanged function\r\n\r\n                // Transform delta by additionalTransformNode inverse world matrix if present\r\n                let delta = event.delta;\r\n                if (this._additionalTransformNode) {\r\n                    this._additionalTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n                    Vector3.TransformNormalToRef(event.delta, TmpVectors.Matrix[0], TmpVectors.Vector3[1]);\r\n                    delta = TmpVectors.Vector3[1];\r\n                }\r\n                // Snapping logic\r\n                if (this.snapDistance == 0) {\r\n                    this.attachedNode.getWorldMatrix().getTranslationToRef(TmpVectors.Vector3[0]);\r\n                    TmpVectors.Vector3[0].addToRef(delta, TmpVectors.Vector3[0]);\r\n                    if (this.dragBehavior.validateDrag(TmpVectors.Vector3[0])) {\r\n                        this.attachedNode.getWorldMatrix().addTranslationFromFloats(delta.x, delta.y, delta.z);\r\n                    }\r\n                } else {\r\n                    currentSnapDragDistance.addInPlace(delta);\r\n                    tmpVector2.set(0, 0, 0);\r\n                    const currentSnapDragDistanceArray = currentSnapDragDistance.asArray();\r\n                    for (let axis = 0; axis < 3; axis++) {\r\n                        const axisDistance = currentSnapDragDistanceArray[axis];\r\n                        if (Math.abs(axisDistance) > this.snapDistance) {\r\n                            const dragSteps = (axisDistance < 0 ? Math.ceil : Math.floor)(axisDistance / this.snapDistance);\r\n                            currentSnapDragDistanceArray[axis] = currentSnapDragDistanceArray[axis] % this.snapDistance;\r\n                            tmpVector.set(axis == 0 ? 1 : 0, axis == 1 ? 1 : 0, axis == 2 ? 1 : 0);\r\n                            tmpVector.scaleInPlace(this.snapDistance * dragSteps);\r\n                            tmpVector2.addInPlace(tmpVector);\r\n                        }\r\n                    }\r\n                    currentSnapDragDistance.fromArray(currentSnapDragDistanceArray);\r\n                    this.attachedNode.getWorldMatrix().getTranslationToRef(TmpVectors.Vector3[0]);\r\n                    TmpVectors.Vector3[0].addToRef(tmpVector2, TmpVectors.Vector3[0]);\r\n                    if (this.dragBehavior.validateDrag(TmpVectors.Vector3[0])) {\r\n                        this.attachedNode.getWorldMatrix().addTranslationFromFloats(tmpVector2.x, tmpVector2.y, tmpVector2.z);\r\n                        tmpSnapEvent.snapDistance = tmpVector2.length();\r\n                        this.onSnapObservable.notifyObservers(tmpSnapEvent);\r\n                    }\r\n                }\r\n                this._matrixChanged();\r\n            }\r\n        });\r\n        this.dragBehavior.onDragStartObservable.add(() => {\r\n            this._dragging = true;\r\n        });\r\n        this.dragBehavior.onDragEndObservable.add(() => {\r\n            this._dragging = false;\r\n        });\r\n\r\n        const light = gizmoLayer._getSharedGizmoLight();\r\n        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(this._rootMesh.getChildMeshes(false));\r\n\r\n        const cache: GizmoAxisCache = {\r\n            gizmoMeshes: this._gizmoMesh.getChildMeshes(),\r\n            colliderMeshes: this._gizmoMesh.getChildMeshes(),\r\n            material: this._coloredMaterial,\r\n            hoverMaterial: this._hoverMaterial,\r\n            disableMaterial: this._disableMaterial,\r\n            active: false,\r\n            dragBehavior: this.dragBehavior,\r\n        };\r\n        this._parent?.addToAxisCache(this._gizmoMesh as Mesh, cache);\r\n\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (this._customMeshSet) {\r\n                return;\r\n            }\r\n            this._isHovered = !!(cache.colliderMeshes.indexOf(<Mesh>pointerInfo?.pickInfo?.pickedMesh) != -1);\r\n            if (!this._parent) {\r\n                const material = cache.dragBehavior.enabled ? (this._isHovered || this._dragging ? this._hoverMaterial : this._coloredMaterial) : this._disableMaterial;\r\n                this._setGizmoMeshMaterial(cache.gizmoMeshes, material);\r\n            }\r\n        });\r\n\r\n        this.dragBehavior.onEnabledObservable.add((newState) => {\r\n            this._setGizmoMeshMaterial(cache.gizmoMeshes, newState ? this._coloredMaterial : this._disableMaterial);\r\n        });\r\n    }\r\n\r\n    protected override _attachedNodeChanged(value: Nullable<Node>) {\r\n        if (this.dragBehavior) {\r\n            this.dragBehavior.enabled = value ? true : false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the gizmo is enabled\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        this._isEnabled = value;\r\n        if (!value) {\r\n            this.attachedNode = null;\r\n        } else {\r\n            if (this._parent) {\r\n                this.attachedNode = this._parent.attachedNode;\r\n            }\r\n        }\r\n    }\r\n\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        this.onSnapObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this.dragBehavior.detach();\r\n        super.dispose();\r\n        if (this._gizmoMesh) {\r\n            this._gizmoMesh.dispose();\r\n        }\r\n        const materials = [this._coloredMaterial, this._hoverMaterial, this._disableMaterial];\r\n        for (const matl of materials) {\r\n            if (matl) {\r\n                matl.dispose();\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type EventState, type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector3, type Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Node } from \"../node\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type GizmoAnchorPoint, type GizmoCoordinatesMode, type GizmoAxisCache, type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { type IAxisDragGizmo, AxisDragGizmo } from \"./axisDragGizmo\";\r\nimport { type IPlaneDragGizmo, PlaneDragGizmo } from \"./planeDragGizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { type GizmoManager } from \"./gizmoManager\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type DragEvent, type DragStartEndEvent } from \"core/Behaviors/Meshes/pointerDragEvents\";\r\n\r\n/**\r\n * Interface for position gizmo\r\n */\r\nexport interface IPositionGizmo extends IGizmo {\r\n    /** Internal gizmo used for interactions on the x axis */\r\n    xGizmo: IAxisDragGizmo;\r\n    /** Internal gizmo used for interactions on the y axis */\r\n    yGizmo: IAxisDragGizmo;\r\n    /** Internal gizmo used for interactions on the z axis */\r\n    zGizmo: IAxisDragGizmo;\r\n    /** Internal gizmo used for interactions on the yz plane */\r\n    xPlaneGizmo: IPlaneDragGizmo;\r\n    /** Internal gizmo used for interactions on the xz plane */\r\n    yPlaneGizmo: IPlaneDragGizmo;\r\n    /** Internal gizmo used for interactions on the xy plane */\r\n    zPlaneGizmo: IPlaneDragGizmo;\r\n    /** True when the mouse pointer is dragging a gizmo mesh */\r\n    readonly isDragging: boolean;\r\n    /** Fires an event when any of it's sub gizmos are dragged */\r\n    onDragStartObservable: Observable<DragStartEndEvent>;\r\n    /** Fires an event when any of it's sub gizmos are being dragged */\r\n    onDragObservable: Observable<DragEvent>;\r\n    /** Fires an event when any of it's sub gizmos are released from dragging */\r\n    onDragEndObservable: Observable<DragStartEndEvent>;\r\n    /**\r\n     * If the planar drag gizmo is enabled\r\n     * setting this will enable/disable XY, XZ and YZ planes regardless of individual gizmo settings.\r\n     */\r\n    planarGizmoEnabled: boolean;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param mesh Axis gizmo mesh\r\n     * @param cache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    addToAxisCache(mesh: Mesh, cache: GizmoAxisCache): void;\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    releaseDrag(): void;\r\n}\r\n\r\n/**\r\n * Additional options for the position gizmo\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PositionGizmoOptions {\r\n    /**\r\n     * Additional transform applied to the gizmo.\r\n     * @See Gizmo.additionalTransformNode for more detail\r\n     */\r\n    additionalTransformNode?: TransformNode;\r\n}\r\n\r\n/**\r\n * Gizmo that enables dragging a mesh along 3 axis\r\n */\r\nexport class PositionGizmo extends Gizmo implements IPositionGizmo {\r\n    /**\r\n     * Internal gizmo used for interactions on the x axis\r\n     */\r\n    public xGizmo: IAxisDragGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the y axis\r\n     */\r\n    public yGizmo: IAxisDragGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the z axis\r\n     */\r\n    public zGizmo: IAxisDragGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the yz plane\r\n     */\r\n    public xPlaneGizmo: IPlaneDragGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the xz plane\r\n     */\r\n    public yPlaneGizmo: IPlaneDragGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the xy plane\r\n     */\r\n    public zPlaneGizmo: IPlaneDragGizmo;\r\n\r\n    /**\r\n     * protected variables\r\n     */\r\n    protected _meshAttached: Nullable<AbstractMesh> = null;\r\n    protected _nodeAttached: Nullable<Node> = null;\r\n    protected _snapDistance: number;\r\n    protected _observables: Observer<PointerInfo>[] = [];\r\n\r\n    /** Node Caching for quick lookup */\r\n    protected _gizmoAxisCache: Map<Mesh, GizmoAxisCache> = new Map();\r\n\r\n    /** Fires an event when any of it's sub gizmos are dragged */\r\n    public onDragStartObservable = new Observable<DragStartEndEvent>();\r\n    /** Fires an event when any of it's sub gizmos are being dragged */\r\n    public onDragObservable = new Observable<DragEvent>();\r\n    /** Fires an event when any of it's sub gizmos are released from dragging */\r\n    public onDragEndObservable = new Observable<DragStartEndEvent>();\r\n\r\n    /**\r\n     * If set to true, planar drag is enabled\r\n     */\r\n    protected _planarGizmoEnabled = false;\r\n\r\n    public override get attachedMesh() {\r\n        return this._meshAttached;\r\n    }\r\n    public override set attachedMesh(mesh: Nullable<AbstractMesh>) {\r\n        this._meshAttached = mesh;\r\n        this._nodeAttached = mesh;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo.isEnabled) {\r\n                gizmo.attachedMesh = mesh;\r\n            } else {\r\n                gizmo.attachedMesh = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    public override get attachedNode() {\r\n        return this._nodeAttached;\r\n    }\r\n    public override set attachedNode(node: Nullable<Node>) {\r\n        this._meshAttached = null;\r\n        this._nodeAttached = node;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo.isEnabled) {\r\n                gizmo.attachedNode = node;\r\n            } else {\r\n                gizmo.attachedNode = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is hovering a gizmo mesh\r\n     */\r\n    public override get isHovered() {\r\n        return this.xGizmo.isHovered || this.yGizmo.isHovered || this.zGizmo.isHovered || this.xPlaneGizmo.isHovered || this.yPlaneGizmo.isHovered || this.zPlaneGizmo.isHovered;\r\n    }\r\n\r\n    public get isDragging() {\r\n        return (\r\n            this.xGizmo.dragBehavior.dragging ||\r\n            this.yGizmo.dragBehavior.dragging ||\r\n            this.zGizmo.dragBehavior.dragging ||\r\n            this.xPlaneGizmo.dragBehavior.dragging ||\r\n            this.yPlaneGizmo.dragBehavior.dragging ||\r\n            this.zPlaneGizmo.dragBehavior.dragging\r\n        );\r\n    }\r\n\r\n    public override get additionalTransformNode() {\r\n        return this._additionalTransformNode;\r\n    }\r\n\r\n    public override set additionalTransformNode(transformNode: TransformNode | undefined) {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.additionalTransformNode = transformNode;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a PositionGizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param thickness display gizmo axis thickness\r\n     * @param gizmoManager\r\n     * @param options More options\r\n     */\r\n    constructor(gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer, thickness: number = 1, gizmoManager?: GizmoManager, options?: PositionGizmoOptions) {\r\n        super(gizmoLayer);\r\n        this.xGizmo = new AxisDragGizmo(new Vector3(1, 0, 0), Color3.Red().scale(0.5), gizmoLayer, this, thickness);\r\n        this.yGizmo = new AxisDragGizmo(new Vector3(0, 1, 0), Color3.Green().scale(0.5), gizmoLayer, this, thickness);\r\n        this.zGizmo = new AxisDragGizmo(new Vector3(0, 0, 1), Color3.Blue().scale(0.5), gizmoLayer, this, thickness);\r\n\r\n        this.xPlaneGizmo = new PlaneDragGizmo(new Vector3(1, 0, 0), Color3.Red().scale(0.5), this.gizmoLayer, this);\r\n        this.yPlaneGizmo = new PlaneDragGizmo(new Vector3(0, 1, 0), Color3.Green().scale(0.5), this.gizmoLayer, this);\r\n        this.zPlaneGizmo = new PlaneDragGizmo(new Vector3(0, 0, 1), Color3.Blue().scale(0.5), this.gizmoLayer, this);\r\n\r\n        this.additionalTransformNode = options?.additionalTransformNode;\r\n\r\n        // Relay drag events\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.dragBehavior.onDragStartObservable.add((eventData: DragStartEndEvent, eventState: EventState) =>\r\n                this.onDragStartObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n            gizmo.dragBehavior.onDragObservable.add((eventData: DragEvent, eventState: EventState) =>\r\n                this.onDragObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n            gizmo.dragBehavior.onDragEndObservable.add((eventData: DragStartEndEvent, eventState: EventState) =>\r\n                this.onDragEndObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n        }\r\n\r\n        this.attachedMesh = null;\r\n\r\n        if (gizmoManager) {\r\n            gizmoManager.addToAxisCache(this._gizmoAxisCache);\r\n        } else {\r\n            // Only subscribe to pointer event if gizmoManager isnt\r\n            Gizmo.GizmoAxisPointerObserver(gizmoLayer, this._gizmoAxisCache);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If the planar drag gizmo is enabled\r\n     * setting this will enable/disable XY, XZ and YZ planes regardless of individual gizmo settings.\r\n     */\r\n    public set planarGizmoEnabled(value: boolean) {\r\n        this._planarGizmoEnabled = value;\r\n        const gizmos = [this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.isEnabled = value;\r\n                if (value) {\r\n                    if (gizmo.attachedMesh) {\r\n                        gizmo.attachedMesh = this.attachedMesh;\r\n                    } else {\r\n                        gizmo.attachedNode = this.attachedNode;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n    public get planarGizmoEnabled(): boolean {\r\n        return this._planarGizmoEnabled;\r\n    }\r\n\r\n    /**\r\n     * Orientation that the gizmo will be displayed with.\r\n     * When set null, default value will be used (Quaternion(0, 0, 0, 1))\r\n     */\r\n    public override get customRotationQuaternion(): Nullable<Quaternion> {\r\n        return this._customRotationQuaternion;\r\n    }\r\n\r\n    public override set customRotationQuaternion(customRotationQuaternion: Nullable<Quaternion>) {\r\n        this._customRotationQuaternion = customRotationQuaternion;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.customRotationQuaternion = customRotationQuaternion;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)\r\n     * NOTE: This is only possible for meshes with uniform scaling, as otherwise it's not possible to decompose the rotation\r\n     */\r\n    public override set updateGizmoRotationToMatchAttachedMesh(value: boolean) {\r\n        this._updateGizmoRotationToMatchAttachedMesh = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.updateGizmoRotationToMatchAttachedMesh = value;\r\n            }\r\n        }\r\n    }\r\n    public override get updateGizmoRotationToMatchAttachedMesh() {\r\n        return this._updateGizmoRotationToMatchAttachedMesh;\r\n    }\r\n\r\n    public override set updateGizmoPositionToMatchAttachedMesh(value: boolean) {\r\n        this._updateGizmoPositionToMatchAttachedMesh = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.updateGizmoPositionToMatchAttachedMesh = value;\r\n            }\r\n        }\r\n    }\r\n    public override get updateGizmoPositionToMatchAttachedMesh() {\r\n        return this._updateGizmoPositionToMatchAttachedMesh;\r\n    }\r\n\r\n    public override set anchorPoint(value: GizmoAnchorPoint) {\r\n        this._anchorPoint = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.anchorPoint = value;\r\n        }\r\n    }\r\n    public override get anchorPoint() {\r\n        return this._anchorPoint;\r\n    }\r\n\r\n    /**\r\n     * Set the coordinate system to use. By default it's local.\r\n     * But it's possible for a user to tweak so its local for translation and world for rotation.\r\n     * In that case, setting the coordinate system will change `updateGizmoRotationToMatchAttachedMesh` and `updateGizmoPositionToMatchAttachedMesh`\r\n     */\r\n    public override set coordinatesMode(coordinatesMode: GizmoCoordinatesMode) {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.coordinatesMode = coordinatesMode;\r\n        }\r\n    }\r\n\r\n    public override set updateScale(value: boolean) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.updateScale = value;\r\n            this.yGizmo.updateScale = value;\r\n            this.zGizmo.updateScale = value;\r\n        }\r\n    }\r\n    public override get updateScale() {\r\n        return this.xGizmo.updateScale;\r\n    }\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)\r\n     */\r\n    public set snapDistance(value: number) {\r\n        this._snapDistance = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.snapDistance = value;\r\n            }\r\n        }\r\n    }\r\n    public get snapDistance() {\r\n        return this._snapDistance;\r\n    }\r\n\r\n    /**\r\n     * Ratio for the scale of the gizmo (Default: 1)\r\n     */\r\n    public override set scaleRatio(value: number) {\r\n        this._scaleRatio = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.scaleRatio = value;\r\n            }\r\n        }\r\n    }\r\n    public override get scaleRatio() {\r\n        return this._scaleRatio;\r\n    }\r\n\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param mesh Axis gizmo mesh\r\n     * @param cache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    public addToAxisCache(mesh: Mesh, cache: GizmoAxisCache) {\r\n        this._gizmoAxisCache.set(mesh, cache);\r\n    }\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    public releaseDrag() {\r\n        this.xGizmo.dragBehavior.releaseDrag();\r\n        this.yGizmo.dragBehavior.releaseDrag();\r\n        this.zGizmo.dragBehavior.releaseDrag();\r\n        this.xPlaneGizmo.dragBehavior.releaseDrag();\r\n        this.yPlaneGizmo.dragBehavior.releaseDrag();\r\n        this.zPlaneGizmo.dragBehavior.releaseDrag();\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.dispose();\r\n            }\r\n        }\r\n        for (const obs of this._observables) {\r\n            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(obs);\r\n        }\r\n        this.onDragStartObservable.clear();\r\n        this.onDragObservable.clear();\r\n        this.onDragEndObservable.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * CustomMeshes are not supported by this gizmo\r\n     */\r\n    public override setCustomMesh() {\r\n        Logger.Error(\r\n            \"Custom meshes are not supported on this gizmo, please set the custom meshes on the gizmos contained within this one (gizmo.xGizmo, gizmo.yGizmo, gizmo.zGizmo, gizmo.xPlaneGizmo, gizmo.yPlaneGizmo, gizmo.zPlaneGizmo)\"\r\n        );\r\n    }\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type EventState, type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector3, type Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { CreatePolyhedron } from \"../Meshes/Builders/polyhedronBuilder.pure\";\r\nimport { type GizmoAnchorPoint, type GizmoAxisCache, type IGizmo, GizmoCoordinatesMode, Gizmo } from \"./gizmo\";\r\nimport { type IAxisScaleGizmo, AxisScaleGizmo } from \"./axisScaleGizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type Node } from \"../node\";\r\nimport { type PointerInfo } from \"../Events/pointerEvents\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type GizmoManager } from \"./gizmoManager\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type DragEvent, type DragStartEndEvent } from \"core/Behaviors/Meshes/pointerDragEvents\";\r\n\r\n/**\r\n * Interface for scale gizmo\r\n */\r\nexport interface IScaleGizmo extends IGizmo {\r\n    /** True when the mouse pointer is dragging a gizmo mesh */\r\n    readonly isDragging: boolean;\r\n    /** Internal gizmo used for interactions on the x axis */\r\n    xGizmo: IAxisScaleGizmo;\r\n    /** Internal gizmo used for interactions on the y axis */\r\n    yGizmo: IAxisScaleGizmo;\r\n    /** Internal gizmo used for interactions on the z axis */\r\n    zGizmo: IAxisScaleGizmo;\r\n    /** Internal gizmo used to scale all axis equally*/\r\n    uniformScaleGizmo: IAxisScaleGizmo;\r\n    /** Fires an event when any of it's sub gizmos are dragged */\r\n    onDragStartObservable: Observable<DragStartEndEvent>;\r\n    /** Fires an event when any of it's sub gizmos are being dragged */\r\n    onDragObservable: Observable<DragEvent>;\r\n    /** Fires an event when any of it's sub gizmos are released from dragging */\r\n    onDragEndObservable: Observable<DragStartEndEvent>;\r\n    /** Drag distance in babylon units that the gizmo will snap to when dragged */\r\n    snapDistance: number;\r\n    /** Incremental snap scaling. When true, with a snapDistance of 0.1, scaling will be 1.1,1.2,1.3 instead of, when false: 1.1,1.21,1.33,... */\r\n    incrementalSnap: boolean;\r\n    /** Sensitivity factor for dragging */\r\n    sensitivity: number;\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param mesh Axis gizmo mesh\r\n     * @param cache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    addToAxisCache(mesh: Mesh, cache: GizmoAxisCache): void;\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    releaseDrag(): void;\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    coloredMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    hoverMaterial: StandardMaterial;\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    disableMaterial: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Additional options for the scale gizmo\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface ScaleGizmoOptions {\r\n    /**\r\n     * Additional transform applied to the gizmo.\r\n     * @See Gizmo.additionalTransformNode for more detail\r\n     */\r\n    additionalTransformNode?: TransformNode;\r\n}\r\n\r\n/**\r\n * Gizmo that enables scaling a mesh along 3 axis\r\n */\r\nexport class ScaleGizmo extends Gizmo implements IScaleGizmo {\r\n    /**\r\n     * Internal gizmo used for interactions on the x axis\r\n     */\r\n    public xGizmo: IAxisScaleGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the y axis\r\n     */\r\n    public yGizmo: IAxisScaleGizmo;\r\n    /**\r\n     * Internal gizmo used for interactions on the z axis\r\n     */\r\n    public zGizmo: IAxisScaleGizmo;\r\n\r\n    /**\r\n     * Internal gizmo used to scale all axis equally\r\n     */\r\n    public uniformScaleGizmo: IAxisScaleGizmo;\r\n\r\n    protected _meshAttached: Nullable<AbstractMesh> = null;\r\n    protected _nodeAttached: Nullable<Node> = null;\r\n    protected _snapDistance: number;\r\n    protected _incrementalSnap: boolean = false;\r\n    protected _uniformScalingMesh: Mesh;\r\n    protected _octahedron: Mesh;\r\n    protected _sensitivity: number = 1;\r\n    protected _coloredMaterial: StandardMaterial;\r\n    protected _hoverMaterial: StandardMaterial;\r\n    protected _disableMaterial: StandardMaterial;\r\n    protected _observables: Observer<PointerInfo>[] = [];\r\n\r\n    /** Node Caching for quick lookup */\r\n    protected _gizmoAxisCache: Map<Mesh, GizmoAxisCache> = new Map();\r\n\r\n    /** Default material used to render when gizmo is not disabled or hovered */\r\n    public get coloredMaterial() {\r\n        return this._coloredMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is hovered with mouse*/\r\n    public get hoverMaterial() {\r\n        return this._hoverMaterial;\r\n    }\r\n\r\n    /** Material used to render when gizmo is disabled. typically grey.*/\r\n    public get disableMaterial() {\r\n        return this._disableMaterial;\r\n    }\r\n    /** Fires an event when any of it's sub gizmos are dragged */\r\n    public onDragStartObservable = new Observable<DragStartEndEvent>();\r\n    /** Fires an event when any of it's sub gizmos are being dragged */\r\n    public onDragObservable = new Observable<DragEvent>();\r\n    /** Fires an event when any of it's sub gizmos are released from dragging */\r\n    public onDragEndObservable = new Observable<DragStartEndEvent>();\r\n\r\n    public override get attachedMesh() {\r\n        return this._meshAttached;\r\n    }\r\n    public override set attachedMesh(mesh: Nullable<AbstractMesh>) {\r\n        this._meshAttached = mesh;\r\n        this._nodeAttached = mesh;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo.isEnabled) {\r\n                gizmo.attachedMesh = mesh;\r\n            } else {\r\n                gizmo.attachedMesh = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    public override get attachedNode() {\r\n        return this._nodeAttached;\r\n    }\r\n    public override set attachedNode(node: Nullable<Node>) {\r\n        this._meshAttached = null;\r\n        this._nodeAttached = node;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo.isEnabled) {\r\n                gizmo.attachedNode = node;\r\n            } else {\r\n                gizmo.attachedNode = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    public override set updateScale(value: boolean) {\r\n        if (this.xGizmo) {\r\n            this.xGizmo.updateScale = value;\r\n            this.yGizmo.updateScale = value;\r\n            this.zGizmo.updateScale = value;\r\n        }\r\n    }\r\n    public override get updateScale() {\r\n        return this.xGizmo.updateScale;\r\n    }\r\n    /**\r\n     * True when the mouse pointer is hovering a gizmo mesh\r\n     */\r\n    public override get isHovered() {\r\n        return this.xGizmo.isHovered || this.yGizmo.isHovered || this.zGizmo.isHovered || this.uniformScaleGizmo.isHovered;\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is dragging a gizmo mesh\r\n     */\r\n    public get isDragging() {\r\n        return this.xGizmo.dragBehavior.dragging || this.yGizmo.dragBehavior.dragging || this.zGizmo.dragBehavior.dragging || this.uniformScaleGizmo.dragBehavior.dragging;\r\n    }\r\n\r\n    public override get additionalTransformNode() {\r\n        return this._additionalTransformNode;\r\n    }\r\n\r\n    public override set additionalTransformNode(transformNode: TransformNode | undefined) {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.additionalTransformNode = transformNode;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a ScaleGizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param thickness display gizmo axis thickness\r\n     * @param gizmoManager\r\n     * @param options More options\r\n     */\r\n    constructor(gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer, thickness: number = 1, gizmoManager?: GizmoManager, options?: ScaleGizmoOptions) {\r\n        super(gizmoLayer);\r\n        this.uniformScaleGizmo = this._createUniformScaleMesh();\r\n        this.xGizmo = new AxisScaleGizmo(new Vector3(1, 0, 0), Color3.Red().scale(0.5), gizmoLayer, this, thickness);\r\n        this.yGizmo = new AxisScaleGizmo(new Vector3(0, 1, 0), Color3.Green().scale(0.5), gizmoLayer, this, thickness);\r\n        this.zGizmo = new AxisScaleGizmo(new Vector3(0, 0, 1), Color3.Blue().scale(0.5), gizmoLayer, this, thickness);\r\n\r\n        this.additionalTransformNode = options?.additionalTransformNode;\r\n\r\n        // Relay drag events\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.dragBehavior.onDragStartObservable.add((eventData: DragStartEndEvent, eventState: EventState) =>\r\n                this.onDragStartObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n            gizmo.dragBehavior.onDragObservable.add((eventData: DragEvent, eventState: EventState) =>\r\n                this.onDragObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n            gizmo.dragBehavior.onDragEndObservable.add((eventData: DragStartEndEvent, eventState: EventState) =>\r\n                this.onDragEndObservable.notifyObservers(eventData, eventState.mask, eventState.target, eventState.currentTarget, eventState.userInfo)\r\n            );\r\n        }\r\n\r\n        this.attachedMesh = null;\r\n        this.attachedNode = null;\r\n\r\n        if (gizmoManager) {\r\n            gizmoManager.addToAxisCache(this._gizmoAxisCache);\r\n        } else {\r\n            // Only subscribe to pointer event if gizmoManager isnt\r\n            Gizmo.GizmoAxisPointerObserver(gizmoLayer, this._gizmoAxisCache);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Create Geometry for Gizmo\r\n     */\r\n    protected _createUniformScaleMesh(): AxisScaleGizmo {\r\n        this._coloredMaterial = new StandardMaterial(\"\", this.gizmoLayer.utilityLayerScene);\r\n        this._coloredMaterial.diffuseColor = Color3.Gray();\r\n\r\n        this._hoverMaterial = new StandardMaterial(\"\", this.gizmoLayer.utilityLayerScene);\r\n        this._hoverMaterial.diffuseColor = Color3.Yellow();\r\n\r\n        this._disableMaterial = new StandardMaterial(\"\", this.gizmoLayer.utilityLayerScene);\r\n        this._disableMaterial.diffuseColor = Color3.Gray();\r\n        this._disableMaterial.alpha = 0.4;\r\n\r\n        const uniformScaleGizmo = new AxisScaleGizmo(new Vector3(0, 1, 0), Color3.Gray().scale(0.5), this.gizmoLayer, this);\r\n        uniformScaleGizmo.updateGizmoRotationToMatchAttachedMesh = false;\r\n        uniformScaleGizmo.uniformScaling = true;\r\n        this._uniformScalingMesh = CreatePolyhedron(\"uniform\", { type: 1 }, uniformScaleGizmo.gizmoLayer.utilityLayerScene);\r\n        this._uniformScalingMesh.scaling.scaleInPlace(0.01);\r\n        this._uniformScalingMesh.visibility = 0;\r\n        this._octahedron = CreatePolyhedron(\"\", { type: 1 }, uniformScaleGizmo.gizmoLayer.utilityLayerScene);\r\n        this._octahedron.scaling.scaleInPlace(0.007);\r\n        this._uniformScalingMesh.addChild(this._octahedron);\r\n        uniformScaleGizmo.setCustomMesh(this._uniformScalingMesh, true);\r\n        const light = this.gizmoLayer._getSharedGizmoLight();\r\n        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(this._octahedron);\r\n\r\n        const cache: GizmoAxisCache = {\r\n            gizmoMeshes: [this._octahedron, this._uniformScalingMesh],\r\n            colliderMeshes: [this._octahedron, this._uniformScalingMesh],\r\n            material: this._coloredMaterial,\r\n            hoverMaterial: this._hoverMaterial,\r\n            disableMaterial: this._disableMaterial,\r\n            active: false,\r\n            dragBehavior: uniformScaleGizmo.dragBehavior,\r\n        };\r\n\r\n        this.addToAxisCache(uniformScaleGizmo._rootMesh, cache);\r\n\r\n        return uniformScaleGizmo;\r\n    }\r\n\r\n    public override set updateGizmoRotationToMatchAttachedMesh(value: boolean) {\r\n        if (!value) {\r\n            Logger.Warn(\"Setting updateGizmoRotationToMatchAttachedMesh = false on scaling gizmo is not supported.\");\r\n        } else {\r\n            this._updateGizmoRotationToMatchAttachedMesh = value;\r\n            const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n            for (const gizmo of gizmos) {\r\n                if (gizmo) {\r\n                    gizmo.updateGizmoRotationToMatchAttachedMesh = value;\r\n                }\r\n            }\r\n        }\r\n    }\r\n    public override get updateGizmoRotationToMatchAttachedMesh() {\r\n        return this._updateGizmoRotationToMatchAttachedMesh;\r\n    }\r\n\r\n    public override set anchorPoint(value: GizmoAnchorPoint) {\r\n        this._anchorPoint = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.anchorPoint = value;\r\n            }\r\n        }\r\n    }\r\n    public override get anchorPoint() {\r\n        return this._anchorPoint;\r\n    }\r\n\r\n    /**\r\n     * Orientation that the gizmo will be displayed with.\r\n     * When set null, default value will be used (Quaternion(0, 0, 0, 1))\r\n     */\r\n    public override get customRotationQuaternion(): Nullable<Quaternion> {\r\n        return this._customRotationQuaternion;\r\n    }\r\n\r\n    public override set customRotationQuaternion(customRotationQuaternion: Nullable<Quaternion>) {\r\n        this._customRotationQuaternion = customRotationQuaternion;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.customRotationQuaternion = customRotationQuaternion;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the coordinate system to use. By default it's local.\r\n     * But it's possible for a user to tweak so its local for translation and world for rotation.\r\n     * In that case, setting the coordinate system will change `updateGizmoRotationToMatchAttachedMesh` and `updateGizmoPositionToMatchAttachedMesh`\r\n     */\r\n    public override set coordinatesMode(coordinatesMode: GizmoCoordinatesMode) {\r\n        if (coordinatesMode == GizmoCoordinatesMode.World) {\r\n            Logger.Warn(\"Setting coordinates Mode to world on scaling gizmo is not supported.\");\r\n        }\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo.coordinatesMode = GizmoCoordinatesMode.Local;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)\r\n     */\r\n    public set snapDistance(value: number) {\r\n        this._snapDistance = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.snapDistance = value;\r\n            }\r\n        }\r\n    }\r\n    public get snapDistance() {\r\n        return this._snapDistance;\r\n    }\r\n\r\n    /**\r\n     * Incremental snap scaling (default is false). When true, with a snapDistance of 0.1, scaling will be 1.1,1.2,1.3 instead of, when false: 1.1,1.21,1.33,...\r\n     */\r\n    public set incrementalSnap(value: boolean) {\r\n        this._incrementalSnap = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.incrementalSnap = value;\r\n            }\r\n        }\r\n    }\r\n    public get incrementalSnap() {\r\n        return this._incrementalSnap;\r\n    }\r\n    /**\r\n     * Ratio for the scale of the gizmo (Default: 1)\r\n     */\r\n    public override set scaleRatio(value: number) {\r\n        this._scaleRatio = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.scaleRatio = value;\r\n            }\r\n        }\r\n    }\r\n    public override get scaleRatio() {\r\n        return this._scaleRatio;\r\n    }\r\n\r\n    /**\r\n     * Sensitivity factor for dragging (Default: 1)\r\n     */\r\n    public set sensitivity(value: number) {\r\n        this._sensitivity = value;\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.sensitivity = value;\r\n            }\r\n        }\r\n    }\r\n    public get sensitivity() {\r\n        return this._sensitivity;\r\n    }\r\n\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param mesh Axis gizmo mesh\r\n     * @param cache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    public addToAxisCache(mesh: Mesh, cache: GizmoAxisCache) {\r\n        this._gizmoAxisCache.set(mesh, cache);\r\n    }\r\n\r\n    /**\r\n     * Get the cache set with addToAxisCache for a specific mesh\r\n     * @param mesh Axis gizmo mesh\r\n     * @returns Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    public getAxisCache(mesh: Mesh): GizmoAxisCache | undefined {\r\n        return this._gizmoAxisCache.get(mesh);\r\n    }\r\n\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    public releaseDrag() {\r\n        this.xGizmo.dragBehavior.releaseDrag();\r\n        this.yGizmo.dragBehavior.releaseDrag();\r\n        this.zGizmo.dragBehavior.releaseDrag();\r\n        this.uniformScaleGizmo.dragBehavior.releaseDrag();\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo\r\n     */\r\n    public override dispose() {\r\n        const gizmos = [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.dispose();\r\n            }\r\n        }\r\n        for (const obs of this._observables) {\r\n            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(obs);\r\n        }\r\n        this.onDragStartObservable.clear();\r\n        this.onDragObservable.clear();\r\n        this.onDragEndObservable.clear();\r\n        const meshes = [this._uniformScalingMesh, this._octahedron];\r\n        for (const msh of meshes) {\r\n            if (msh) {\r\n                msh.dispose();\r\n            }\r\n        }\r\n        const materials = [this._coloredMaterial, this._hoverMaterial, this._disableMaterial];\r\n        for (const matl of materials) {\r\n            if (matl) {\r\n                matl.dispose();\r\n            }\r\n        }\r\n        super.dispose();\r\n    }\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { type Node } from \"../node\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { SixDofDragBehavior } from \"../Behaviors/Meshes/sixDofDragBehavior\";\r\nimport { type GizmoAxisCache, type IGizmo, Gizmo, GizmoCoordinatesMode } from \"./gizmo\";\r\nimport { type IRotationGizmo, RotationGizmo } from \"./rotationGizmo\";\r\nimport { type IPositionGizmo, PositionGizmo } from \"./positionGizmo\";\r\nimport { type IScaleGizmo, ScaleGizmo } from \"./scaleGizmo\";\r\nimport { type IBoundingBoxGizmo, BoundingBoxGizmo } from \"./boundingBoxGizmo\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\n\r\n/**\r\n * Helps set up gizmos in the scene to rotate/scale/position nodes\r\n */\r\nexport class GizmoManager implements IDisposable {\r\n    /**\r\n     * Gizmos created by the gizmo manager, gizmo will be null until gizmo has been enabled for the first time\r\n     */\r\n    public gizmos: {\r\n        positionGizmo: Nullable<IPositionGizmo>;\r\n        rotationGizmo: Nullable<IRotationGizmo>;\r\n        scaleGizmo: Nullable<IScaleGizmo>;\r\n        boundingBoxGizmo: Nullable<IBoundingBoxGizmo>;\r\n    };\r\n\r\n    /** When true, the gizmo will be detached from the current object when a pointer down occurs with an empty picked mesh */\r\n    public clearGizmoOnEmptyPointerEvent = false;\r\n\r\n    /** When true (default), picking to attach a new mesh is enabled. This works in sync with inspector autopicking. */\r\n    public enableAutoPicking = true;\r\n\r\n    /** Fires an event when the manager is attached to a mesh */\r\n    public onAttachedToMeshObservable = new Observable<Nullable<AbstractMesh>>();\r\n\r\n    /** Fires an event when the manager is attached to a node */\r\n    public onAttachedToNodeObservable = new Observable<Nullable<Node>>();\r\n\r\n    protected _gizmosEnabled = { positionGizmo: false, rotationGizmo: false, scaleGizmo: false, boundingBoxGizmo: false };\r\n    protected _pointerObservers: Observer<PointerInfo>[] = [];\r\n    protected _attachedMesh: Nullable<AbstractMesh> = null;\r\n    protected _attachedNode: Nullable<Node> = null;\r\n    protected _boundingBoxColor = Color3.FromHexString(\"#0984e3\");\r\n    protected _defaultUtilityLayer: UtilityLayerRenderer;\r\n    protected _defaultKeepDepthUtilityLayer: UtilityLayerRenderer;\r\n    protected _thickness: number = 1;\r\n    protected _scaleRatio: number = 1;\r\n    protected _coordinatesMode = GizmoCoordinatesMode.Local;\r\n    protected _additionalTransformNode?: TransformNode;\r\n\r\n    /** Node Caching for quick lookup */\r\n    private _gizmoAxisCache: Map<Mesh, GizmoAxisCache> = new Map();\r\n    /**\r\n     * When bounding box gizmo is enabled, this can be used to track drag/end events\r\n     */\r\n    public boundingBoxDragBehavior = new SixDofDragBehavior();\r\n    /**\r\n     * Array of meshes which will have the gizmo attached when a pointer selected them. If null, all meshes are attachable. (Default: null)\r\n     */\r\n    public attachableMeshes: Nullable<Array<AbstractMesh>> = null;\r\n    /**\r\n     * Array of nodes which will have the gizmo attached when a pointer selected them. If null, all nodes are attachable. (Default: null)\r\n     */\r\n    public attachableNodes: Nullable<Array<Node>> = null;\r\n    /**\r\n     * If pointer events should perform attaching/detaching a gizmo, if false this can be done manually via attachToMesh/attachToNode. (Default: true)\r\n     */\r\n    public usePointerToAttachGizmos = true;\r\n\r\n    /**\r\n     * Utility layer that the bounding box gizmo belongs to\r\n     */\r\n    public get keepDepthUtilityLayer() {\r\n        return this._defaultKeepDepthUtilityLayer;\r\n    }\r\n\r\n    /**\r\n     * Utility layer that all gizmos besides bounding box belong to\r\n     */\r\n    public get utilityLayer() {\r\n        return this._defaultUtilityLayer;\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is hovering a gizmo mesh\r\n     */\r\n    public get isHovered() {\r\n        let hovered = false;\r\n        for (const key in this.gizmos) {\r\n            const gizmo = <Nullable<IGizmo>>(<any>this.gizmos)[key];\r\n            if (gizmo && gizmo.isHovered) {\r\n                hovered = true;\r\n                break;\r\n            }\r\n        }\r\n        return hovered;\r\n    }\r\n\r\n    /**\r\n     * True when the mouse pointer is dragging a gizmo mesh\r\n     */\r\n    public get isDragging() {\r\n        let dragging = false;\r\n\r\n        const gizmos = [this.gizmos.positionGizmo, this.gizmos.rotationGizmo, this.gizmos.scaleGizmo, this.gizmos.boundingBoxGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo && gizmo.isDragging) {\r\n                dragging = true;\r\n            }\r\n        }\r\n\r\n        return dragging;\r\n    }\r\n\r\n    /**\r\n     * Ratio for the scale of the gizmo (Default: 1)\r\n     */\r\n    public set scaleRatio(value: number) {\r\n        this._scaleRatio = value;\r\n        const gizmos = [this.gizmos.positionGizmo, this.gizmos.rotationGizmo, this.gizmos.scaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.scaleRatio = value;\r\n            }\r\n        }\r\n    }\r\n    public get scaleRatio() {\r\n        return this._scaleRatio;\r\n    }\r\n\r\n    /**\r\n     * Set the coordinate system to use. By default it's local.\r\n     * But it's possible for a user to tweak so its local for translation and world for rotation.\r\n     * In that case, setting the coordinate system will change `updateGizmoRotationToMatchAttachedMesh` and `updateGizmoPositionToMatchAttachedMesh`\r\n     */\r\n    public set coordinatesMode(coordinatesMode: GizmoCoordinatesMode) {\r\n        this._coordinatesMode = coordinatesMode;\r\n        const gizmos = [this.gizmos.positionGizmo, this.gizmos.rotationGizmo, this.gizmos.scaleGizmo];\r\n        for (const gizmo of gizmos) {\r\n            if (gizmo) {\r\n                gizmo.coordinatesMode = coordinatesMode;\r\n            }\r\n        }\r\n    }\r\n\r\n    public get coordinatesMode(): GizmoCoordinatesMode {\r\n        return this._coordinatesMode;\r\n    }\r\n\r\n    /**\r\n     * The mesh the gizmo's is attached to\r\n     */\r\n    public get attachedMesh() {\r\n        return this._attachedMesh;\r\n    }\r\n\r\n    /**\r\n     * The node the gizmo's is attached to\r\n     */\r\n    public get attachedNode() {\r\n        return this._attachedNode;\r\n    }\r\n\r\n    /**\r\n     * Additional transform node that will be used to transform all the gizmos\r\n     */\r\n    public get additionalTransformNode() {\r\n        return this._additionalTransformNode;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a gizmo manager\r\n     * @param _scene the scene to overlay the gizmos on top of\r\n     * @param thickness display gizmo axis thickness\r\n     * @param utilityLayer the layer where gizmos are rendered\r\n     * @param keepDepthUtilityLayer the layer where occluded gizmos are rendered\r\n     */\r\n    constructor(\r\n        private _scene: Scene,\r\n        thickness: number = 1,\r\n        utilityLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer,\r\n        keepDepthUtilityLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultKeepDepthUtilityLayer\r\n    ) {\r\n        this._defaultUtilityLayer = utilityLayer;\r\n        this._defaultKeepDepthUtilityLayer = keepDepthUtilityLayer;\r\n        this._defaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;\r\n        this._thickness = thickness;\r\n        this.gizmos = { positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null };\r\n\r\n        const attachToMeshPointerObserver = this._attachToMeshPointerObserver(_scene);\r\n        const gizmoAxisPointerObserver = Gizmo.GizmoAxisPointerObserver(this._defaultUtilityLayer, this._gizmoAxisCache);\r\n        this._pointerObservers = [attachToMeshPointerObserver, gizmoAxisPointerObserver];\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Subscribes to pointer down events, for attaching and detaching mesh\r\n     * @param scene The scene layer the observer will be added to\r\n     * @returns the pointer observer\r\n     */\r\n    private _attachToMeshPointerObserver(scene: Scene): Observer<PointerInfo> {\r\n        // Instantiate/dispose gizmos based on pointer actions\r\n        const pointerObserver = scene.onPointerObservable.add((pointerInfo) => {\r\n            if (!this.usePointerToAttachGizmos) {\r\n                return;\r\n            }\r\n            if (pointerInfo.type == PointerEventTypes.POINTERDOWN) {\r\n                if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh) {\r\n                    if (this.enableAutoPicking) {\r\n                        let node: Nullable<Node> = pointerInfo.pickInfo.pickedMesh;\r\n                        if (this.attachableMeshes == null) {\r\n                            // Attach to the most parent node\r\n                            while (node && node.parent != null) {\r\n                                node = node.parent;\r\n                            }\r\n                        } else {\r\n                            // Attach to the parent node that is an attachableMesh\r\n                            let found = false;\r\n                            for (const mesh of this.attachableMeshes) {\r\n                                if (node && (node == mesh || node.isDescendantOf(mesh))) {\r\n                                    node = mesh;\r\n                                    found = true;\r\n                                }\r\n                            }\r\n                            if (!found) {\r\n                                node = null;\r\n                            }\r\n                        }\r\n                        if (node instanceof AbstractMesh) {\r\n                            if (this._attachedMesh != node) {\r\n                                this.attachToMesh(node);\r\n                            }\r\n                        } else {\r\n                            if (this.clearGizmoOnEmptyPointerEvent) {\r\n                                this.attachToMesh(null);\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (this.clearGizmoOnEmptyPointerEvent) {\r\n                        this.attachToMesh(null);\r\n                    }\r\n                }\r\n            }\r\n        });\r\n        return pointerObserver;\r\n    }\r\n\r\n    /**\r\n     * Attaches a set of gizmos to the specified mesh\r\n     * @param mesh The mesh the gizmo's should be attached to\r\n     */\r\n    public attachToMesh(mesh: Nullable<AbstractMesh>) {\r\n        if (this._attachedMesh) {\r\n            this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);\r\n        }\r\n        if (this._attachedNode) {\r\n            this._attachedNode.removeBehavior(this.boundingBoxDragBehavior);\r\n        }\r\n        this._attachedMesh = mesh;\r\n        this._attachedNode = null;\r\n        for (const key in this.gizmos) {\r\n            const gizmo = <Nullable<IGizmo>>(<any>this.gizmos)[key];\r\n            if (gizmo && (<any>this._gizmosEnabled)[key]) {\r\n                gizmo.attachedMesh = mesh;\r\n            }\r\n        }\r\n        if (this.boundingBoxGizmoEnabled && this._attachedMesh) {\r\n            this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);\r\n        }\r\n        this.onAttachedToMeshObservable.notifyObservers(mesh);\r\n    }\r\n\r\n    /**\r\n     * Attaches a set of gizmos to the specified node\r\n     * @param node The node the gizmo's should be attached to\r\n     */\r\n    public attachToNode(node: Nullable<Node>) {\r\n        if (this._attachedMesh) {\r\n            this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);\r\n        }\r\n        if (this._attachedNode) {\r\n            this._attachedNode.removeBehavior(this.boundingBoxDragBehavior);\r\n        }\r\n        this._attachedMesh = null;\r\n        this._attachedNode = node;\r\n        for (const key in this.gizmos) {\r\n            const gizmo = <Nullable<IGizmo>>(<any>this.gizmos)[key];\r\n            if (gizmo && (<any>this._gizmosEnabled)[key]) {\r\n                gizmo.attachedNode = node;\r\n            }\r\n        }\r\n        if (this.boundingBoxGizmoEnabled && this._attachedNode) {\r\n            this._attachedNode.addBehavior(this.boundingBoxDragBehavior);\r\n        }\r\n        this.onAttachedToNodeObservable.notifyObservers(node);\r\n    }\r\n\r\n    /**\r\n     * If the position gizmo is enabled\r\n     */\r\n    public set positionGizmoEnabled(value: boolean) {\r\n        if (value) {\r\n            if (!this.gizmos.positionGizmo) {\r\n                this.gizmos.positionGizmo = new PositionGizmo(this._defaultUtilityLayer, this._thickness, this);\r\n            }\r\n            if (this._attachedNode) {\r\n                this.gizmos.positionGizmo.attachedNode = this._attachedNode;\r\n            } else {\r\n                this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;\r\n            }\r\n        } else if (this.gizmos.positionGizmo) {\r\n            this.gizmos.positionGizmo.attachedNode = null;\r\n        }\r\n        this._gizmosEnabled.positionGizmo = value;\r\n        this._setAdditionalTransformNode();\r\n    }\r\n    public get positionGizmoEnabled(): boolean {\r\n        return this._gizmosEnabled.positionGizmo;\r\n    }\r\n    /**\r\n     * If the rotation gizmo is enabled\r\n     */\r\n    public set rotationGizmoEnabled(value: boolean) {\r\n        if (value) {\r\n            if (!this.gizmos.rotationGizmo) {\r\n                this.gizmos.rotationGizmo = new RotationGizmo(this._defaultUtilityLayer, 32, false, this._thickness, this);\r\n            }\r\n            if (this._attachedNode) {\r\n                this.gizmos.rotationGizmo.attachedNode = this._attachedNode;\r\n            } else {\r\n                this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;\r\n            }\r\n        } else if (this.gizmos.rotationGizmo) {\r\n            this.gizmos.rotationGizmo.attachedNode = null;\r\n        }\r\n        this._gizmosEnabled.rotationGizmo = value;\r\n        this._setAdditionalTransformNode();\r\n    }\r\n    public get rotationGizmoEnabled(): boolean {\r\n        return this._gizmosEnabled.rotationGizmo;\r\n    }\r\n    /**\r\n     * If the scale gizmo is enabled\r\n     */\r\n    public set scaleGizmoEnabled(value: boolean) {\r\n        if (value) {\r\n            this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new ScaleGizmo(this._defaultUtilityLayer, this._thickness, this);\r\n            if (this._attachedNode) {\r\n                this.gizmos.scaleGizmo.attachedNode = this._attachedNode;\r\n            } else {\r\n                this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;\r\n            }\r\n        } else if (this.gizmos.scaleGizmo) {\r\n            this.gizmos.scaleGizmo.attachedNode = null;\r\n        }\r\n        this._gizmosEnabled.scaleGizmo = value;\r\n        this._setAdditionalTransformNode();\r\n    }\r\n    public get scaleGizmoEnabled(): boolean {\r\n        return this._gizmosEnabled.scaleGizmo;\r\n    }\r\n    /**\r\n     * If the boundingBox gizmo is enabled\r\n     */\r\n    public set boundingBoxGizmoEnabled(value: boolean) {\r\n        if (value) {\r\n            this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BoundingBoxGizmo(this._boundingBoxColor, this._defaultKeepDepthUtilityLayer);\r\n            if (this._attachedMesh) {\r\n                this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;\r\n            } else {\r\n                this.gizmos.boundingBoxGizmo.attachedNode = this._attachedNode;\r\n            }\r\n\r\n            if (this._attachedMesh) {\r\n                this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);\r\n                this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);\r\n            } else if (this._attachedNode) {\r\n                this._attachedNode.removeBehavior(this.boundingBoxDragBehavior);\r\n                this._attachedNode.addBehavior(this.boundingBoxDragBehavior);\r\n            }\r\n        } else if (this.gizmos.boundingBoxGizmo) {\r\n            if (this._attachedMesh) {\r\n                this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);\r\n            } else if (this._attachedNode) {\r\n                this._attachedNode.removeBehavior(this.boundingBoxDragBehavior);\r\n            }\r\n            this.gizmos.boundingBoxGizmo.attachedNode = null;\r\n        }\r\n        this._gizmosEnabled.boundingBoxGizmo = value;\r\n        this._setAdditionalTransformNode();\r\n    }\r\n    public get boundingBoxGizmoEnabled(): boolean {\r\n        return this._gizmosEnabled.boundingBoxGizmo;\r\n    }\r\n\r\n    /**\r\n     * Sets the additional transform applied to all the gizmos.\r\n     * @See Gizmo.additionalTransformNode for more detail\r\n     */\r\n    public set additionalTransformNode(node: TransformNode | undefined) {\r\n        this._additionalTransformNode = node;\r\n        this._setAdditionalTransformNode();\r\n    }\r\n\r\n    private _setAdditionalTransformNode() {\r\n        for (const key in this.gizmos) {\r\n            const gizmo = <Nullable<IGizmo>>(<any>this.gizmos)[key];\r\n            if (gizmo && (<any>this._gizmosEnabled)[key]) {\r\n                gizmo.additionalTransformNode = this._additionalTransformNode;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Builds Gizmo Axis Cache to enable features such as hover state preservation and graying out other axis during manipulation\r\n     * @param gizmoAxisCache Gizmo axis definition used for reactive gizmo UI\r\n     */\r\n    public addToAxisCache(gizmoAxisCache: Map<Mesh, GizmoAxisCache>) {\r\n        if (gizmoAxisCache.size > 0) {\r\n            gizmoAxisCache.forEach((v, k) => {\r\n                this._gizmoAxisCache.set(k, v);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Force release the drag action by code\r\n     */\r\n    public releaseDrag() {\r\n        const gizmos = [this.gizmos.positionGizmo, this.gizmos.rotationGizmo, this.gizmos.scaleGizmo, this.gizmos.boundingBoxGizmo];\r\n        for (const gizmo of gizmos) {\r\n            gizmo?.releaseDrag();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo manager\r\n     */\r\n    public dispose() {\r\n        for (const observer of this._pointerObservers) {\r\n            this._scene.onPointerObservable.remove(observer);\r\n        }\r\n        for (const key in this.gizmos) {\r\n            const gizmo = <Nullable<IGizmo>>(<any>this.gizmos)[key];\r\n            if (gizmo) {\r\n                gizmo.dispose();\r\n            }\r\n        }\r\n        if (this._defaultKeepDepthUtilityLayer !== UtilityLayerRenderer._DefaultKeepDepthUtilityLayer) {\r\n            this._defaultKeepDepthUtilityLayer?.dispose();\r\n        }\r\n        if (this._defaultUtilityLayer !== UtilityLayerRenderer._DefaultUtilityLayer) {\r\n            this._defaultUtilityLayer?.dispose();\r\n        }\r\n        this.boundingBoxDragBehavior.detach();\r\n        this.onAttachedToMeshObservable.clear();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { CreateSphere } from \"../Builders/sphereBuilder.pure\";\r\nimport { CreateDisc } from \"./discBuilder.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Creates a hemisphere mesh\r\n * @param name defines the name of the mesh\r\n * @param options defines the options used to create the mesh\r\n * @param scene defines the hosting scene\r\n * @returns the hemisphere mesh\r\n */\r\nexport function CreateHemisphere(name: string, options: { segments?: number; diameter?: number; sideOrientation?: number } = {}, scene?: Scene): Mesh {\r\n    if (!options.diameter) {\r\n        options.diameter = 1;\r\n    }\r\n    if (!options.segments) {\r\n        options.segments = 16;\r\n    }\r\n\r\n    const halfSphere = CreateSphere(\"\", { slice: 0.5, diameter: options.diameter, segments: options.segments }, scene);\r\n    const disc = CreateDisc(\"\", { radius: options.diameter / 2, tessellation: options.segments * 3 + (4 - options.segments) }, scene);\r\n    disc.rotation.x = -Math.PI / 2;\r\n    disc.parent = halfSphere;\r\n\r\n    const merged = <Mesh>Mesh.MergeMeshes([disc, halfSphere], true);\r\n    merged.name = name;\r\n\r\n    return merged;\r\n}\r\n/**\r\n * Class containing static functions to help procedurally build meshes\r\n * @deprecated use the function directly from the module\r\n */\r\nexport const HemisphereBuilder = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    CreateHemisphere,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for hemisphereBuilder.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterHemisphereBuilder(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Creates a hemispheric light\r\n     * @param name\r\n     * @param segments\r\n     * @param diameter\r\n     * @param scene\r\n     * @returns the mesh\r\n     */\r\n    Mesh.CreateHemisphere = (name: string, segments: number, diameter: number, scene?: Scene): Mesh => {\r\n        const options = {\r\n            segments: segments,\r\n            diameter: diameter,\r\n        };\r\n\r\n        return CreateHemisphere(name, options, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsTexture } from \"../Misc/decorators\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { Light } from \"./light\";\r\nimport { ShadowLight } from \"./shadowLight\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type ProceduralTexture } from \"../Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Node } from \"../node\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * A spot light is defined by a position, a direction, an angle, and an exponent.\r\n * These values define a cone of light starting from the position, emitting toward the direction.\r\n * The angle, in radians, defines the size (field of illumination) of the spotlight's conical beam,\r\n * and the exponent defines the speed of the decay of the light with distance (reach).\r\n * Documentation: https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n */\r\nexport class SpotLight extends ShadowLight {\r\n    /*\r\n        upVector , rightVector and direction will form the coordinate system for this spot light.\r\n        These three vectors will be used as projection matrix when doing texture projection.\r\n\r\n        Also we have the following rules always holds:\r\n        direction cross up   = right\r\n        right cross direction = up\r\n        up cross right       = forward\r\n\r\n        light_near and light_far will control the range of the texture projection. If a plane is\r\n        out of the range in spot light space, there is no texture projection.\r\n    */\r\n\r\n    private _angle: number;\r\n    private _innerAngle: number = 0;\r\n    /** @internal */\r\n    public _cosHalfAngle: number;\r\n\r\n    /** @internal */\r\n    public _lightAngleScale: number;\r\n    /** @internal */\r\n    public _lightAngleOffset: number;\r\n\r\n    private _iesProfileTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Gets or sets the IES profile texture used to create the spotlight\r\n     * @see https://playground.babylonjs.com/#UIAXAU#1\r\n     */\r\n    public get iesProfileTexture(): Nullable<BaseTexture> {\r\n        return this._iesProfileTexture;\r\n    }\r\n\r\n    public set iesProfileTexture(value: Nullable<BaseTexture>) {\r\n        if (this._iesProfileTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._iesProfileTexture = value;\r\n\r\n        if (this._iesProfileTexture && SpotLight._IsTexture(this._iesProfileTexture)) {\r\n            this._iesProfileTexture.onLoadObservable.addOnce(() => {\r\n                this._markMeshesAsLightDirty();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the cone angle of the spot light in Radians.\r\n     */\r\n    @serialize()\r\n    public get angle(): number {\r\n        return this._angle;\r\n    }\r\n    /**\r\n     * Sets the cone angle of the spot light in Radians.\r\n     */\r\n    public set angle(value: number) {\r\n        this._angle = value;\r\n        this._cosHalfAngle = Math.cos(value * 0.5);\r\n        this._projectionTextureProjectionLightDirty = true;\r\n        this.forceProjectionMatrixCompute();\r\n        this._computeAngleValues();\r\n    }\r\n\r\n    /**\r\n     * Only used in gltf falloff mode, this defines the angle where\r\n     * the directional falloff will start before cutting at angle which could be seen\r\n     * as outer angle.\r\n     */\r\n    @serialize()\r\n    public get innerAngle(): number {\r\n        return this._innerAngle;\r\n    }\r\n    /**\r\n     * Only used in gltf falloff mode, this defines the angle where\r\n     * the directional falloff will start before cutting at angle which could be seen\r\n     * as outer angle.\r\n     */\r\n    public set innerAngle(value: number) {\r\n        this._innerAngle = value;\r\n        this._computeAngleValues();\r\n    }\r\n\r\n    private _shadowAngleScale: number;\r\n    /**\r\n     * Allows scaling the angle of the light for shadow generation only.\r\n     */\r\n    @serialize()\r\n    public get shadowAngleScale(): number {\r\n        return this._shadowAngleScale;\r\n    }\r\n    /**\r\n     * Allows scaling the angle of the light for shadow generation only.\r\n     */\r\n    public set shadowAngleScale(value: number) {\r\n        this._shadowAngleScale = value;\r\n        this.forceProjectionMatrixCompute();\r\n    }\r\n\r\n    /**\r\n     * The light decay speed with the distance from the emission spot.\r\n     */\r\n    @serialize()\r\n    public exponent: number;\r\n\r\n    private _projectionTextureMatrix = Matrix.Zero();\r\n    /**\r\n     * Allows reading the projection texture\r\n     */\r\n    public get projectionTextureMatrix(): Matrix {\r\n        return this._projectionTextureMatrix;\r\n    }\r\n\r\n    protected _projectionTextureLightNear: number = 1e-6;\r\n    /**\r\n     * Gets the near clip of the Spotlight for texture projection.\r\n     */\r\n    @serialize()\r\n    public get projectionTextureLightNear(): number {\r\n        return this._projectionTextureLightNear;\r\n    }\r\n    /**\r\n     * Sets the near clip of the Spotlight for texture projection.\r\n     */\r\n    public set projectionTextureLightNear(value: number) {\r\n        this._projectionTextureLightNear = value;\r\n        this._projectionTextureProjectionLightDirty = true;\r\n    }\r\n\r\n    protected _projectionTextureLightFar: number = 1000.0;\r\n    /**\r\n     * Gets the far clip of the Spotlight for texture projection.\r\n     */\r\n    @serialize()\r\n    public get projectionTextureLightFar(): number {\r\n        return this._projectionTextureLightFar;\r\n    }\r\n    /**\r\n     * Sets the far clip of the Spotlight for texture projection.\r\n     */\r\n    public set projectionTextureLightFar(value: number) {\r\n        this._projectionTextureLightFar = value;\r\n        this._projectionTextureProjectionLightDirty = true;\r\n    }\r\n\r\n    protected _projectionTextureUpDirection: Vector3 = Vector3.Up();\r\n    /**\r\n     * Gets the Up vector of the Spotlight for texture projection.\r\n     */\r\n    @serialize()\r\n    public get projectionTextureUpDirection(): Vector3 {\r\n        return this._projectionTextureUpDirection;\r\n    }\r\n    /**\r\n     * Sets the Up vector of the Spotlight for texture projection.\r\n     */\r\n    public set projectionTextureUpDirection(value: Vector3) {\r\n        this._projectionTextureUpDirection = value;\r\n        this._projectionTextureViewLightDirty = true;\r\n    }\r\n\r\n    @serializeAsTexture(\"projectedLightTexture\")\r\n    private _projectionTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Gets the projection texture of the light.\r\n     */\r\n    public get projectionTexture(): Nullable<BaseTexture> {\r\n        return this._projectionTexture;\r\n    }\r\n    /**\r\n     * Sets the projection texture of the light.\r\n     */\r\n    public set projectionTexture(value: Nullable<BaseTexture>) {\r\n        if (this._projectionTexture === value) {\r\n            return;\r\n        }\r\n        this._projectionTexture = value;\r\n        this._projectionTextureDirty = true;\r\n        if (this._projectionTexture && !this._projectionTexture.isReady()) {\r\n            if (SpotLight._IsProceduralTexture(this._projectionTexture)) {\r\n                this._projectionTexture.getEffect().executeWhenCompiled(() => {\r\n                    this._markMeshesAsLightDirty();\r\n                });\r\n            } else if (SpotLight._IsTexture(this._projectionTexture)) {\r\n                this._projectionTexture.onLoadObservable.addOnce(() => {\r\n                    this._markMeshesAsLightDirty();\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    private static _IsProceduralTexture(texture: BaseTexture): texture is ProceduralTexture {\r\n        return (texture as ProceduralTexture).onGeneratedObservable !== undefined;\r\n    }\r\n\r\n    private static _IsTexture(texture: BaseTexture): texture is Texture {\r\n        return (texture as Texture).onLoadObservable !== undefined;\r\n    }\r\n\r\n    private _projectionTextureViewLightDirty = true;\r\n    private _projectionTextureProjectionLightDirty = true;\r\n    private _projectionTextureDirty = true;\r\n    private _projectionTextureViewTargetVector = Vector3.Zero();\r\n    private _projectionTextureViewLightMatrix = Matrix.Zero();\r\n\r\n    private _projectionTextureProjectionLightMatrix = Matrix.Zero();\r\n    /**\r\n     * Gets or sets the light projection matrix as used by the projection texture\r\n     */\r\n    public get projectionTextureProjectionLightMatrix(): Matrix {\r\n        return this._projectionTextureProjectionLightMatrix;\r\n    }\r\n\r\n    public set projectionTextureProjectionLightMatrix(projection: Matrix) {\r\n        this._projectionTextureProjectionLightMatrix = projection;\r\n        this._projectionTextureProjectionLightDirty = false;\r\n        this._projectionTextureDirty = true;\r\n    }\r\n\r\n    private _projectionTextureScalingMatrix = Matrix.FromValues(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0);\r\n\r\n    /**\r\n     * Creates a SpotLight object in the scene. A spot light is a simply light oriented cone.\r\n     * It can cast shadows.\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     * @param name The light friendly name\r\n     * @param position The position of the spot light in the scene\r\n     * @param direction The direction of the light in the scene\r\n     * @param angle The cone angle of the light in Radians\r\n     * @param exponent The light decay speed with the distance from the emission spot\r\n     * @param scene The scene the lights belongs to\r\n     * @param dontAddToScene True to not add the light to the scene\r\n     */\r\n    constructor(name: string, position: Vector3, direction: Vector3, angle: number, exponent: number, scene?: Scene, dontAddToScene?: boolean) {\r\n        super(name, scene, dontAddToScene);\r\n\r\n        this.position = position;\r\n        this.direction = direction;\r\n        this.angle = angle;\r\n        this.exponent = exponent;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"SpotLight\".\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"SpotLight\";\r\n    }\r\n\r\n    /**\r\n     * Returns the integer 2.\r\n     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public override getTypeID(): number {\r\n        return Light.LIGHTTYPEID_SPOTLIGHT;\r\n    }\r\n\r\n    /**\r\n     * Overrides the direction setter to recompute the projection texture view light Matrix.\r\n     * @param value\r\n     */\r\n    protected override _setDirection(value: Vector3) {\r\n        super._setDirection(value);\r\n        this._projectionTextureViewLightDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Overrides the position setter to recompute the projection texture view light Matrix.\r\n     * @param value\r\n     */\r\n    protected override _setPosition(value: Vector3) {\r\n        super._setPosition(value);\r\n        this._projectionTextureViewLightDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Sets the passed matrix \"matrix\" as perspective projection matrix for the shadows and the passed view matrix with the fov equal to the SpotLight angle and and aspect ratio of 1.0.\r\n     * Returns the SpotLight.\r\n     * @param matrix\r\n     * @param viewMatrix\r\n     * @param renderList\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _setDefaultShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void {\r\n        const activeCamera = this.getScene().activeCamera;\r\n\r\n        if (!activeCamera) {\r\n            return;\r\n        }\r\n\r\n        this._shadowAngleScale = this._shadowAngleScale || 1;\r\n        const angle = this._shadowAngleScale * this._angle;\r\n\r\n        const minZ = this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera.minZ;\r\n        const maxZ = this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera.maxZ;\r\n\r\n        const useReverseDepthBuffer = this.getScene().getEngine().useReverseDepthBuffer;\r\n\r\n        Matrix.PerspectiveFovLHToRef(\r\n            angle,\r\n            1.0,\r\n            useReverseDepthBuffer ? maxZ : minZ,\r\n            useReverseDepthBuffer ? minZ : maxZ,\r\n            matrix,\r\n            true,\r\n            this._scene.getEngine().isNDCHalfZRange,\r\n            undefined,\r\n            useReverseDepthBuffer\r\n        );\r\n    }\r\n\r\n    protected _computeProjectionTextureViewLightMatrix(): void {\r\n        this._projectionTextureViewLightDirty = false;\r\n        this._projectionTextureDirty = true;\r\n\r\n        this.getAbsolutePosition().addToRef(this.getShadowDirection(), this._projectionTextureViewTargetVector);\r\n        Matrix.LookAtLHToRef(this.getAbsolutePosition(), this._projectionTextureViewTargetVector, this._projectionTextureUpDirection, this._projectionTextureViewLightMatrix);\r\n    }\r\n\r\n    protected _computeProjectionTextureProjectionLightMatrix(): void {\r\n        this._projectionTextureProjectionLightDirty = false;\r\n        this._projectionTextureDirty = true;\r\n\r\n        const lightFar = this.projectionTextureLightFar;\r\n        const lightNear = this.projectionTextureLightNear;\r\n\r\n        const p = lightFar / (lightFar - lightNear);\r\n        const q = -p * lightNear;\r\n        const s = 1.0 / Math.tan(this._angle / 2.0);\r\n        const a = 1.0;\r\n\r\n        Matrix.FromValuesToRef(s / a, 0.0, 0.0, 0.0, 0.0, s, 0.0, 0.0, 0.0, 0.0, p, 1.0, 0.0, 0.0, q, 0.0, this._projectionTextureProjectionLightMatrix);\r\n    }\r\n\r\n    /**\r\n     * Main function for light texture projection matrix computing.\r\n     */\r\n    protected _computeProjectionTextureMatrix(): void {\r\n        this._projectionTextureDirty = false;\r\n\r\n        this._projectionTextureViewLightMatrix.multiplyToRef(this._projectionTextureProjectionLightMatrix, this._projectionTextureMatrix);\r\n        if (this._projectionTexture instanceof Texture) {\r\n            const u = this._projectionTexture.uScale / 2.0;\r\n            const v = this._projectionTexture.vScale / 2.0;\r\n            Matrix.FromValuesToRef(u, 0.0, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0, this._projectionTextureScalingMatrix);\r\n        }\r\n        this._projectionTextureMatrix.multiplyToRef(this._projectionTextureScalingMatrix, this._projectionTextureMatrix);\r\n    }\r\n\r\n    protected _buildUniformLayout(): void {\r\n        this._uniformBuffer.addUniform(\"vLightData\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightDirection\", 3);\r\n        this._uniformBuffer.addUniform(\"vLightFalloff\", 4);\r\n        this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\r\n        this._uniformBuffer.addUniform(\"depthValues\", 2);\r\n        this._uniformBuffer.create();\r\n    }\r\n\r\n    private _computeAngleValues(): void {\r\n        this._lightAngleScale = 1.0 / Math.max(0.001, Math.cos(this._innerAngle * 0.5) - this._cosHalfAngle);\r\n        this._lightAngleOffset = -this._cosHalfAngle * this._lightAngleScale;\r\n    }\r\n\r\n    /**\r\n     * Sets the passed Effect \"effect\" with the Light textures.\r\n     * @param effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The light\r\n     */\r\n    public override transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\r\n        if (this.projectionTexture && this.projectionTexture.isReady()) {\r\n            if (this._projectionTextureViewLightDirty) {\r\n                this._computeProjectionTextureViewLightMatrix();\r\n            }\r\n            if (this._projectionTextureProjectionLightDirty) {\r\n                this._computeProjectionTextureProjectionLightMatrix();\r\n            }\r\n            if (this._projectionTextureDirty) {\r\n                this._computeProjectionTextureMatrix();\r\n            }\r\n            effect.setMatrix(\"textureProjectionMatrix\" + lightIndex, this._projectionTextureMatrix);\r\n            effect.setTexture(\"projectionLightTexture\" + lightIndex, this.projectionTexture);\r\n        }\r\n\r\n        if (this._iesProfileTexture && this._iesProfileTexture.isReady()) {\r\n            effect.setTexture(\"iesLightTexture\" + lightIndex, this._iesProfileTexture);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the passed Effect object with the SpotLight transformed position (or position if not parented) and normalized direction.\r\n     * @param effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The spot light\r\n     */\r\n    public transferToEffect(effect: Effect, lightIndex: string): SpotLight {\r\n        let normalizeDirection;\r\n        const offset = this._scene.floatingOriginOffset;\r\n\r\n        if (this.computeTransformedInformation()) {\r\n            this._uniformBuffer.updateFloat4(\r\n                \"vLightData\",\r\n                this.transformedPosition.x - offset.x,\r\n                this.transformedPosition.y - offset.y,\r\n                this.transformedPosition.z - offset.z,\r\n                this.exponent,\r\n                lightIndex\r\n            );\r\n\r\n            normalizeDirection = Vector3.Normalize(this.transformedDirection);\r\n        } else {\r\n            this._uniformBuffer.updateFloat4(\"vLightData\", this.position.x - offset.x, this.position.y - offset.y, this.position.z - offset.z, this.exponent, lightIndex);\r\n\r\n            normalizeDirection = Vector3.Normalize(this.direction);\r\n        }\r\n\r\n        this._uniformBuffer.updateFloat4(\"vLightDirection\", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, this._cosHalfAngle, lightIndex);\r\n\r\n        this._uniformBuffer.updateFloat4(\"vLightFalloff\", this.range, this._inverseSquaredRange, this._lightAngleScale, this._lightAngleOffset, lightIndex);\r\n        return this;\r\n    }\r\n\r\n    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {\r\n        let normalizeDirection;\r\n\r\n        if (this.computeTransformedInformation()) {\r\n            normalizeDirection = Vector3.Normalize(this.transformedDirection);\r\n        } else {\r\n            normalizeDirection = Vector3.Normalize(this.direction);\r\n        }\r\n\r\n        if (this.getScene().useRightHandedSystem) {\r\n            effect.setFloat3(lightDataUniformName, -normalizeDirection.x, -normalizeDirection.y, -normalizeDirection.z);\r\n        } else {\r\n            effect.setFloat3(lightDataUniformName, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disposes the light and the associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        if (this._projectionTexture) {\r\n            this._projectionTexture.dispose();\r\n        }\r\n        if (this._iesProfileTexture) {\r\n            this._iesProfileTexture.dispose();\r\n            this._iesProfileTexture = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the minZ used for shadow according to both the scene and the light.\r\n     * @param activeCamera The camera we are returning the min for\r\n     * @returns the depth min z\r\n     */\r\n    public override getDepthMinZ(activeCamera: Nullable<Camera>): number {\r\n        const engine = this._scene.getEngine();\r\n        const minZ = this.shadowMinZ !== undefined ? this.shadowMinZ : (activeCamera?.minZ ?? Constants.ShadowMinZ);\r\n\r\n        return engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? minZ : this._scene.getEngine().isNDCHalfZRange ? 0 : minZ;\r\n    }\r\n\r\n    /**\r\n     * Gets the maxZ used for shadow according to both the scene and the light.\r\n     * @param activeCamera The camera we are returning the max for\r\n     * @returns the depth max z\r\n     */\r\n    public override getDepthMaxZ(activeCamera: Nullable<Camera>): number {\r\n        const engine = this._scene.getEngine();\r\n        const maxZ = this.shadowMaxZ !== undefined ? this.shadowMaxZ : (activeCamera?.maxZ ?? Constants.ShadowMaxZ);\r\n\r\n        return engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : maxZ;\r\n    }\r\n\r\n    /**\r\n     * Returns whether light related textures are ready to be used in the rendering\r\n     * @override\r\n     * @returns true if the light textures are ready\r\n     */\r\n    public override areLightTexturesReady(): boolean {\r\n        if (this._projectionTexture && !this._projectionTexture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n        if (this._iesProfileTexture && !this._iesProfileTexture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Prepares the list of defines specific to the light type.\r\n     * @param defines the list of defines\r\n     * @param lightIndex defines the index of the light for the effect\r\n     */\r\n    public prepareLightSpecificDefines(defines: any, lightIndex: number): void {\r\n        defines[\"SPOTLIGHT\" + lightIndex] = true;\r\n        defines[\"PROJECTEDLIGHTTEXTURE\" + lightIndex] = this.projectionTexture && this.projectionTexture.isReady() ? true : false;\r\n        defines[\"IESLIGHTTEXTURE\" + lightIndex] = this._iesProfileTexture && this._iesProfileTexture.isReady() ? true : false;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for spotLight.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSpotLight(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"Light_Type_2\", (name, scene) => {\r\n        return () => new SpotLight(name, Vector3.Zero(), Vector3.Zero(), 0, 0, scene);\r\n    });\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.SpotLight\", SpotLight);\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { type Node } from \"../node\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { type Scene } from \"../scene\";\r\nimport { HemisphericLight } from \"../Lights/hemisphericLight.pure\";\r\nimport { DirectionalLight } from \"../Lights/directionalLight.pure\";\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { CreateHemisphere } from \"../Meshes/Builders/hemisphereBuilder.pure\";\r\nimport { SpotLight } from \"../Lights/spotLight.pure\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Interface for light gizmo\r\n */\r\nexport interface ILightGizmo extends IGizmo {\r\n    /** Event that fires each time the gizmo is clicked */\r\n    onClickedObservable: Observable<Light>;\r\n    /** The light that the gizmo is attached to */\r\n    light: Nullable<Light>;\r\n    /** The material used to render the light gizmo */\r\n    readonly material: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Gizmo that enables viewing a light\r\n */\r\nexport class LightGizmo extends Gizmo implements ILightGizmo {\r\n    protected _lightMesh: Mesh;\r\n    protected _material: StandardMaterial;\r\n    protected _cachedPosition = new Vector3();\r\n    protected _cachedForward = new Vector3(0, 0, 1);\r\n    protected _attachedMeshParent: TransformNode;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n\r\n    /**\r\n     * Event that fires each time the gizmo is clicked\r\n     */\r\n    public onClickedObservable = new Observable<Light>();\r\n\r\n    /**\r\n     * Creates a LightGizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     */\r\n    constructor(gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer) {\r\n        super(gizmoLayer);\r\n        this.attachedMesh = new Mesh(\"\", this.gizmoLayer.utilityLayerScene);\r\n        this._attachedMeshParent = new TransformNode(\"parent\", this.gizmoLayer.utilityLayerScene);\r\n\r\n        this.attachedMesh.parent = this._attachedMeshParent;\r\n        this._material = new StandardMaterial(\"light\", this.gizmoLayer.utilityLayerScene);\r\n        this._material.diffuseColor = new Color3(0.5, 0.5, 0.5);\r\n        this._material.specularColor = new Color3(0.1, 0.1, 0.1);\r\n\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (!this._light) {\r\n                return;\r\n            }\r\n\r\n            this._isHovered = !!(pointerInfo.pickInfo && this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1);\r\n            if (this._isHovered && pointerInfo.type === PointerEventTypes.POINTERDOWN && pointerInfo.event.button === 0) {\r\n                this.onClickedObservable.notifyObservers(this._light);\r\n            }\r\n        });\r\n    }\r\n    protected _light: Nullable<Light> = null;\r\n\r\n    /**\r\n     * Override attachedNode because lightgizmo only support attached mesh\r\n     * It will return the attached mesh (if any) and setting an attached node will log\r\n     * a warning\r\n     */\r\n    public override get attachedNode() {\r\n        return this.attachedMesh;\r\n    }\r\n    public override set attachedNode(value: Nullable<Node>) {\r\n        Logger.Warn(\"Nodes cannot be attached to LightGizmo. Attach to a mesh instead.\");\r\n    }\r\n\r\n    /**\r\n     * The light that the gizmo is attached to\r\n     */\r\n    public set light(light: Nullable<Light>) {\r\n        this._light = light;\r\n        if (light) {\r\n            // Create the mesh for the given light type\r\n            if (this._lightMesh) {\r\n                this._lightMesh.dispose();\r\n            }\r\n\r\n            if (light instanceof HemisphericLight) {\r\n                this._lightMesh = LightGizmo._CreateHemisphericLightMesh(this.gizmoLayer.utilityLayerScene);\r\n            } else if (light instanceof DirectionalLight) {\r\n                this._lightMesh = LightGizmo._CreateDirectionalLightMesh(this.gizmoLayer.utilityLayerScene);\r\n            } else if (light instanceof SpotLight) {\r\n                this._lightMesh = LightGizmo._CreateSpotLightMesh(this.gizmoLayer.utilityLayerScene);\r\n            } else {\r\n                this._lightMesh = LightGizmo._CreatePointLightMesh(this.gizmoLayer.utilityLayerScene);\r\n            }\r\n            const children = this._lightMesh.getChildMeshes(false);\r\n            for (const m of children) {\r\n                m.material = this._material;\r\n            }\r\n            this._lightMesh.parent = this._rootMesh;\r\n\r\n            // Add lighting to the light gizmo\r\n            const gizmoLight = this.gizmoLayer._getSharedGizmoLight();\r\n            gizmoLight.includedOnlyMeshes = gizmoLight.includedOnlyMeshes.concat(this._lightMesh.getChildMeshes(false));\r\n\r\n            this._lightMesh.rotationQuaternion = new Quaternion();\r\n\r\n            if (!this.attachedMesh!.reservedDataStore) {\r\n                this.attachedMesh!.reservedDataStore = {};\r\n            }\r\n            this.attachedMesh!.reservedDataStore.lightGizmo = this;\r\n\r\n            if (light.parent) {\r\n                this._attachedMeshParent.freezeWorldMatrix(light.parent.getWorldMatrix());\r\n            }\r\n\r\n            // Get update position and direction if the light has it\r\n            if ((light as any).position) {\r\n                this.attachedMesh!.position.copyFrom((light as any).position);\r\n                this.attachedMesh!.computeWorldMatrix(true);\r\n                this._cachedPosition.copyFrom(this.attachedMesh!.position);\r\n            }\r\n            if ((light as any).direction) {\r\n                this.attachedMesh!.setDirection((light as any).direction);\r\n                this.attachedMesh!.computeWorldMatrix(true);\r\n                const forward = this._getMeshForward();\r\n                this._cachedForward.copyFrom(forward);\r\n            }\r\n\r\n            this._update();\r\n        }\r\n    }\r\n    public get light() {\r\n        return this._light;\r\n    }\r\n\r\n    /**\r\n     * Gets the material used to render the light gizmo\r\n     */\r\n    public get material() {\r\n        return this._material;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * returns mesh forward\r\n     */\r\n    protected _getMeshForward(): Vector3 {\r\n        let forward = this.attachedMesh!.forward;\r\n        if (this.attachedMesh!.getScene().useRightHandedSystem) {\r\n            forward.negateToRef(TmpVectors.Vector3[0]);\r\n            forward = TmpVectors.Vector3[0];\r\n        }\r\n        return forward;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Updates the gizmo to match the attached mesh's position/rotation\r\n     */\r\n    protected override _update() {\r\n        super._update();\r\n        if (!this._light) {\r\n            return;\r\n        }\r\n\r\n        if (this._light.parent) {\r\n            this._attachedMeshParent.freezeWorldMatrix(this._light.parent.getWorldMatrix());\r\n        }\r\n\r\n        // For light position and direction, a dirty flag is set to true in the setter\r\n        // It means setting values individually or copying values will not call setter and\r\n        // dirty flag will not be set to true. Hence creating a new Vector3.\r\n        if ((this._light as any).position) {\r\n            // If the gizmo is moved update the light otherwise update the gizmo to match the light\r\n            if (!this.attachedMesh!.position.equals(this._cachedPosition)) {\r\n                // update light to match gizmo\r\n                const position = this.attachedMesh!.position;\r\n                (this._light as any).position = new Vector3(position.x, position.y, position.z);\r\n                this._cachedPosition.copyFrom(this.attachedMesh!.position);\r\n            } else {\r\n                // update gizmo to match light\r\n                this.attachedMesh!.position.copyFrom((this._light as any).position);\r\n                this.attachedMesh!.computeWorldMatrix(true);\r\n                this._cachedPosition.copyFrom(this.attachedMesh!.position);\r\n            }\r\n        }\r\n        if ((this._light as any).direction) {\r\n            // If the gizmo is moved update the light otherwise update the gizmo to match the light\r\n            const forward = this._getMeshForward();\r\n            if (Vector3.DistanceSquared(forward, this._cachedForward) > 0.0001) {\r\n                // update light to match gizmo\r\n                const direction = forward;\r\n                (this._light as any).direction = new Vector3(direction.x, direction.y, direction.z);\r\n                this._cachedForward.copyFrom(forward);\r\n            } else if (Vector3.DistanceSquared(forward, (this._light as any).direction) > 0.0001) {\r\n                // update gizmo to match light\r\n                this.attachedMesh!.setDirection((this._light as any).direction);\r\n                this.attachedMesh!.computeWorldMatrix(true);\r\n                this._cachedForward.copyFrom(forward);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Static helper methods\r\n    private static _Scale = 0.007;\r\n\r\n    /**\r\n     * Creates the lines for a light mesh\r\n     * @param levels\r\n     * @param scene\r\n     * @returns the light lines mesh\r\n     */\r\n    private static _CreateLightLines = (levels: number, scene: Scene) => {\r\n        const distFromSphere = 1.2;\r\n\r\n        const root = new Mesh(\"root\", scene);\r\n        root.rotation.x = Math.PI / 2;\r\n\r\n        // Create the top line, this will be cloned for all other lines\r\n        const linePivot = new Mesh(\"linePivot\", scene);\r\n        linePivot.parent = root;\r\n        const line = CreateCylinder(\r\n            \"line\",\r\n            {\r\n                updatable: false,\r\n                height: 2,\r\n                diameterTop: 0.2,\r\n                diameterBottom: 0.3,\r\n                tessellation: 6,\r\n                subdivisions: 1,\r\n            },\r\n            scene\r\n        );\r\n        line.position.y = line.scaling.y / 2 + distFromSphere;\r\n        line.parent = linePivot;\r\n\r\n        if (levels < 2) {\r\n            return linePivot;\r\n        }\r\n        for (let i = 0; i < 4; i++) {\r\n            const l = linePivot.clone(\"lineParentClone\");\r\n            l.rotation.z = Math.PI / 4;\r\n            l.rotation.y = Math.PI / 2 + (Math.PI / 2) * i;\r\n\r\n            l.getChildMeshes()[0].scaling.y = 0.5;\r\n            l.getChildMeshes()[0].scaling.x = l.getChildMeshes()[0].scaling.z = 0.8;\r\n            l.getChildMeshes()[0].position.y = l.getChildMeshes()[0].scaling.y / 2 + distFromSphere;\r\n        }\r\n\r\n        if (levels < 3) {\r\n            return root;\r\n        }\r\n        for (let i = 0; i < 4; i++) {\r\n            const l = linePivot.clone(\"linePivotClone\");\r\n            l.rotation.z = Math.PI / 2;\r\n            l.rotation.y = (Math.PI / 2) * i;\r\n        }\r\n\r\n        if (levels < 4) {\r\n            return root;\r\n        }\r\n        for (let i = 0; i < 4; i++) {\r\n            const l = linePivot.clone(\"linePivotClone\");\r\n            l.rotation.z = Math.PI + Math.PI / 4;\r\n            l.rotation.y = Math.PI / 2 + (Math.PI / 2) * i;\r\n\r\n            l.getChildMeshes()[0].scaling.y = 0.5;\r\n            l.getChildMeshes()[0].scaling.x = l.getChildMeshes()[0].scaling.z = 0.8;\r\n            l.getChildMeshes()[0].position.y = l.getChildMeshes()[0].scaling.y / 2 + distFromSphere;\r\n        }\r\n\r\n        if (levels < 5) {\r\n            return root;\r\n        }\r\n        const l = linePivot.clone(\"linePivotClone\");\r\n        l.rotation.z = Math.PI;\r\n\r\n        return root;\r\n    };\r\n\r\n    /**\r\n     * Disposes of the light gizmo\r\n     */\r\n    public override dispose() {\r\n        this.onClickedObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this._material.dispose();\r\n        super.dispose();\r\n        this._attachedMeshParent.dispose();\r\n    }\r\n\r\n    private static _CreateHemisphericLightMesh(scene: Scene) {\r\n        const root = new Mesh(\"hemisphereLight\", scene);\r\n        const hemisphere = CreateHemisphere(root.name, { segments: 10, diameter: 1 }, scene);\r\n        hemisphere.position.z = -0.15;\r\n        hemisphere.rotation.x = Math.PI / 2;\r\n        hemisphere.parent = root;\r\n\r\n        const lines = this._CreateLightLines(3, scene);\r\n        lines.parent = root;\r\n\r\n        root.scaling.scaleInPlace(LightGizmo._Scale);\r\n        root.rotation.x = Math.PI / 2;\r\n\r\n        return root;\r\n    }\r\n\r\n    private static _CreatePointLightMesh(scene: Scene) {\r\n        const root = new Mesh(\"pointLight\", scene);\r\n        const sphere = CreateSphere(root.name, { segments: 10, diameter: 1 }, scene);\r\n        sphere.rotation.x = Math.PI / 2;\r\n        sphere.parent = root;\r\n\r\n        const lines = this._CreateLightLines(5, scene);\r\n        lines.parent = root;\r\n        root.scaling.scaleInPlace(LightGizmo._Scale);\r\n        root.rotation.x = Math.PI / 2;\r\n\r\n        return root;\r\n    }\r\n\r\n    private static _CreateSpotLightMesh(scene: Scene) {\r\n        const root = new Mesh(\"spotLight\", scene);\r\n        const sphere = CreateSphere(root.name, { segments: 10, diameter: 1 }, scene);\r\n        sphere.parent = root;\r\n\r\n        const hemisphere = CreateHemisphere(root.name, { segments: 10, diameter: 2 }, scene);\r\n        hemisphere.parent = root;\r\n        hemisphere.rotation.x = -Math.PI / 2;\r\n\r\n        const lines = this._CreateLightLines(2, scene);\r\n        lines.parent = root;\r\n        root.scaling.scaleInPlace(LightGizmo._Scale);\r\n        root.rotation.x = Math.PI / 2;\r\n\r\n        return root;\r\n    }\r\n\r\n    private static _CreateDirectionalLightMesh(scene: Scene) {\r\n        const root = new Mesh(\"directionalLight\", scene);\r\n\r\n        const mesh = new Mesh(root.name, scene);\r\n        mesh.parent = root;\r\n        const sphere = CreateSphere(root.name, { diameter: 1.2, segments: 10 }, scene);\r\n        sphere.parent = mesh;\r\n\r\n        const line = CreateCylinder(\r\n            root.name,\r\n            {\r\n                updatable: false,\r\n                height: 6,\r\n                diameterTop: 0.3,\r\n                diameterBottom: 0.3,\r\n                tessellation: 6,\r\n                subdivisions: 1,\r\n            },\r\n            scene\r\n        );\r\n        line.parent = mesh;\r\n\r\n        let left = line.clone(root.name);\r\n        left.scaling.y = 0.5;\r\n        left.position.x += 1.25;\r\n\r\n        let right = line.clone(root.name);\r\n        right.scaling.y = 0.5;\r\n        right.position.x += -1.25;\r\n\r\n        const arrowHead = CreateCylinder(\r\n            root.name,\r\n            {\r\n                updatable: false,\r\n                height: 1,\r\n                diameterTop: 0,\r\n                diameterBottom: 0.6,\r\n                tessellation: 6,\r\n                subdivisions: 1,\r\n            },\r\n            scene\r\n        );\r\n        arrowHead.position.y += 3;\r\n        arrowHead.parent = mesh;\r\n\r\n        left = arrowHead.clone(root.name);\r\n        left.position.y = 1.5;\r\n        left.position.x += 1.25;\r\n\r\n        right = arrowHead.clone(root.name);\r\n        right.position.y = 1.5;\r\n        right.position.x += -1.25;\r\n\r\n        mesh.scaling.scaleInPlace(LightGizmo._Scale);\r\n        mesh.rotation.z = Math.PI / 2;\r\n        mesh.rotation.y = Math.PI / 2;\r\n        return root;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { CreateBox } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { Matrix } from \"../Maths/math\";\r\nimport { CreateLineSystem } from \"../Meshes/Builders/linesBuilder.pure\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\n\r\n/**\r\n * Interface for camera gizmo\r\n */\r\nexport interface ICameraGizmo extends IGizmo {\r\n    /** Event that fires each time the gizmo is clicked */\r\n    onClickedObservable: Observable<Camera>;\r\n    /** A boolean indicating if frustum lines must be rendered */\r\n    displayFrustum: boolean;\r\n    /** The camera that the gizmo is attached to */\r\n    camera: Nullable<Camera>;\r\n    /** The material used to render the camera gizmo */\r\n    readonly material: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Gizmo that enables viewing a camera\r\n */\r\nexport class CameraGizmo extends Gizmo implements ICameraGizmo {\r\n    protected _cameraMesh: Mesh;\r\n    protected _cameraLinesMesh: Mesh;\r\n    protected _material: StandardMaterial;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n    private _frustumLinesColor?: Color3;\r\n\r\n    /**\r\n     * Event that fires each time the gizmo is clicked\r\n     */\r\n    public onClickedObservable = new Observable<Camera>();\r\n\r\n    /**\r\n     * Creates a CameraGizmo\r\n     * @param gizmoLayer The utility layer the gizmo will be added to\r\n     * @param gizmoColor Camera mesh color. Default is Gray\r\n     * @param frustumLinesColor Frustum lines color. Default is White\r\n     */\r\n    constructor(gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer, gizmoColor?: Color3, frustumLinesColor?: Color3) {\r\n        super(gizmoLayer);\r\n\r\n        this._material = new StandardMaterial(\"cameraGizmoMaterial\", this.gizmoLayer.utilityLayerScene);\r\n        this._frustumLinesColor = frustumLinesColor;\r\n\r\n        this._material.diffuseColor = gizmoColor ?? new Color3(0.5, 0.5, 0.5);\r\n        this._material.specularColor = new Color3(0.1, 0.1, 0.1);\r\n\r\n        this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {\r\n            if (!this._camera) {\r\n                return;\r\n            }\r\n\r\n            this._isHovered = !!(pointerInfo.pickInfo && this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1);\r\n            if (this._isHovered && pointerInfo.type === PointerEventTypes.POINTERDOWN && pointerInfo.event.button === 0) {\r\n                this.onClickedObservable.notifyObservers(this._camera);\r\n            }\r\n        });\r\n    }\r\n    protected _camera: Nullable<Camera> = null;\r\n\r\n    /** Gets or sets a boolean indicating if frustum lines must be rendered (true by default) */\r\n    public get displayFrustum() {\r\n        return this._cameraLinesMesh.isEnabled();\r\n    }\r\n    public set displayFrustum(value) {\r\n        this._cameraLinesMesh.setEnabled(value);\r\n    }\r\n\r\n    /**\r\n     * The camera that the gizmo is attached to\r\n     */\r\n    public set camera(camera: Nullable<Camera>) {\r\n        this._camera = camera;\r\n        this.attachedNode = camera;\r\n        if (camera) {\r\n            // Create the mesh for the given camera\r\n            if (!this._customMeshSet) {\r\n                if (this._cameraMesh) {\r\n                    this._cameraMesh.dispose();\r\n                }\r\n                this._cameraMesh = CameraGizmo._CreateCameraMesh(this.gizmoLayer.utilityLayerScene);\r\n\r\n                const childMeshes = this._cameraMesh.getChildMeshes(false);\r\n                for (const m of childMeshes) {\r\n                    m.material = this._material;\r\n                }\r\n                this._cameraMesh.parent = this._rootMesh;\r\n            }\r\n\r\n            if (this._cameraLinesMesh) {\r\n                this._cameraLinesMesh.dispose();\r\n            }\r\n            const linesColor = this._frustumLinesColor?.toColor4(1) ?? new Color4(1, 1, 1, 1);\r\n            this._cameraLinesMesh = CameraGizmo._CreateCameraFrustum(this.gizmoLayer.utilityLayerScene, linesColor);\r\n            this._cameraLinesMesh.parent = this._rootMesh;\r\n\r\n            if (\r\n                this.gizmoLayer.utilityLayerScene.activeCamera &&\r\n                this.gizmoLayer.utilityLayerScene.activeCamera != camera &&\r\n                this.gizmoLayer.utilityLayerScene.activeCamera.maxZ < camera.maxZ\r\n            ) {\r\n                this.gizmoLayer.utilityLayerScene.activeCamera.maxZ = camera.maxZ;\r\n            }\r\n\r\n            if (!this.attachedNode!.reservedDataStore) {\r\n                this.attachedNode!.reservedDataStore = {};\r\n            }\r\n            this.attachedNode!.reservedDataStore.cameraGizmo = this;\r\n\r\n            // Add lighting to the camera gizmo\r\n            const gizmoLight = this.gizmoLayer._getSharedGizmoLight();\r\n            gizmoLight.includedOnlyMeshes = gizmoLight.includedOnlyMeshes.concat(this._cameraMesh.getChildMeshes(false));\r\n\r\n            this._update();\r\n        }\r\n    }\r\n\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    /**\r\n     * Gets the material used to render the camera gizmo\r\n     */\r\n    public get material() {\r\n        return this._material;\r\n    }\r\n    /**\r\n     * @internal\r\n     * Updates the gizmo to match the attached mesh's position/rotation\r\n     */\r\n\r\n    protected override _update() {\r\n        super._update();\r\n        if (!this._camera) {\r\n            return;\r\n        }\r\n\r\n        // frustum matrix\r\n        this._camera.getProjectionMatrix().invertToRef(this._invProjection);\r\n        this._cameraLinesMesh.setPivotMatrix(this._invProjection, false);\r\n\r\n        this._cameraLinesMesh.scaling.x = 1 / this._rootMesh.scaling.x;\r\n        this._cameraLinesMesh.scaling.y = 1 / this._rootMesh.scaling.y;\r\n        this._cameraLinesMesh.scaling.z = 1 / this._rootMesh.scaling.z;\r\n\r\n        // take care of coordinate system in camera scene to properly display the mesh with the good Y axis orientation in this scene\r\n        this._cameraMesh.parent = null;\r\n        this._cameraMesh.rotation.y = Math.PI * 0.5 * (this._camera.getScene().useRightHandedSystem ? 1 : -1);\r\n        this._cameraMesh.parent = this._rootMesh;\r\n    }\r\n\r\n    // Static helper methods\r\n    private static _Scale = 0.05;\r\n    private _invProjection = new Matrix();\r\n\r\n    /**\r\n     * Disposes and replaces the current camera mesh in the gizmo with the specified mesh\r\n     * @param mesh The mesh to replace the default mesh of the camera gizmo\r\n     */\r\n    public override setCustomMesh(mesh: Mesh) {\r\n        if (mesh.getScene() != this.gizmoLayer.utilityLayerScene) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"When setting a custom mesh on a gizmo, the custom meshes scene must be the same as the gizmos (eg. gizmo.gizmoLayer.utilityLayerScene)\";\r\n        }\r\n        if (this._cameraMesh) {\r\n            this._cameraMesh.dispose();\r\n        }\r\n        this._cameraMesh = mesh;\r\n        this._cameraMesh.parent = this._rootMesh;\r\n        this._customMeshSet = true;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the camera gizmo\r\n     */\r\n    public override dispose() {\r\n        this.onClickedObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        if (this._cameraMesh) {\r\n            this._cameraMesh.dispose();\r\n        }\r\n        if (this._cameraLinesMesh) {\r\n            this._cameraLinesMesh.dispose();\r\n        }\r\n        this._material.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    private static _CreateCameraMesh(scene: Scene) {\r\n        const root = new Mesh(\"rootCameraGizmo\", scene);\r\n\r\n        const mesh = new Mesh(root.name, scene);\r\n        mesh.parent = root;\r\n\r\n        const box = CreateBox(root.name, { width: 1.0, height: 0.8, depth: 0.5 }, scene);\r\n        box.parent = mesh;\r\n\r\n        const cyl1 = CreateCylinder(root.name, { height: 0.5, diameterTop: 0.8, diameterBottom: 0.8 }, scene);\r\n        cyl1.parent = mesh;\r\n        cyl1.position.y = 0.3;\r\n        cyl1.position.x = -0.6;\r\n        cyl1.rotation.x = Math.PI * 0.5;\r\n\r\n        const cyl2 = CreateCylinder(root.name, { height: 0.5, diameterTop: 0.6, diameterBottom: 0.6 }, scene);\r\n        cyl2.parent = mesh;\r\n        cyl2.position.y = 0.5;\r\n        cyl2.position.x = 0.4;\r\n        cyl2.rotation.x = Math.PI * 0.5;\r\n\r\n        const cyl3 = CreateCylinder(root.name, { height: 0.5, diameterTop: 0.5, diameterBottom: 0.5 }, scene);\r\n        cyl3.parent = mesh;\r\n        cyl3.position.y = 0.0;\r\n        cyl3.position.x = 0.6;\r\n        cyl3.rotation.z = Math.PI * 0.5;\r\n\r\n        root.scaling.scaleInPlace(CameraGizmo._Scale);\r\n        mesh.position.x = -0.9;\r\n\r\n        return root;\r\n    }\r\n\r\n    private static _CreateCameraFrustum(scene: Scene, linesColor: Color4) {\r\n        const root = new Mesh(\"rootCameraGizmo\", scene);\r\n        const mesh = new Mesh(root.name, scene);\r\n        mesh.parent = root;\r\n\r\n        const lines: Vector3[][] = [];\r\n        const colors: Color4[][] = [];\r\n\r\n        for (let y = 0; y < 4; y += 2) {\r\n            for (let x = 0; x < 4; x += 2) {\r\n                lines.push([new Vector3(-1 + x, -1 + y, -1), new Vector3(-1 + x, -1 + y, 1)]);\r\n\r\n                lines.push([new Vector3(-1, -1 + x, -1 + y), new Vector3(1, -1 + x, -1 + y)]);\r\n\r\n                lines.push([new Vector3(-1 + x, -1, -1 + y), new Vector3(-1 + x, 1, -1 + y)]);\r\n                colors.push([linesColor, linesColor], [linesColor, linesColor], [linesColor, linesColor]);\r\n            }\r\n        }\r\n\r\n        const line = CreateLineSystem(\"lines\", { lines, colors }, scene);\r\n\r\n        line.parent = mesh;\r\n        line.alwaysSelectAsActiveMesh = true;\r\n        line.isPickable = false;\r\n\r\n        return root;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Quaternion, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type IGizmo, Gizmo } from \"./gizmo\";\r\nimport { UtilityLayerRenderer } from \"../Rendering/utilityLayerRenderer\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type AbstractSoundSource } from \"../AudioV2/abstractAudio/abstractSoundSource\";\r\nimport { SpatialAudioAttachmentType } from \"../AudioV2/spatialAudioAttachmentType\";\r\n\r\n/**\r\n * Interface for a spatial audio gizmo.\r\n */\r\nexport interface ISpatialAudioGizmo extends IGizmo {\r\n    /** Event that fires each time the gizmo is clicked. */\r\n    onClickedObservable: Observable<AbstractSoundSource>;\r\n    /** The sound source the gizmo is attached to. */\r\n    soundSource: Nullable<AbstractSoundSource>;\r\n    /** The material used to render the gizmo. */\r\n    readonly material: StandardMaterial;\r\n}\r\n\r\n/**\r\n * Gizmo that visualizes the position and orientation of a v2 spatial sound source.\r\n */\r\nexport class SpatialAudioGizmo extends Gizmo implements ISpatialAudioGizmo {\r\n    private static readonly _Scale = 0.035;\r\n\r\n    protected _soundSource: Nullable<AbstractSoundSource> = null;\r\n    protected _audioMesh: Mesh;\r\n    protected _material: StandardMaterial;\r\n    protected _pointerObserver: Nullable<Observer<PointerInfo>> = null;\r\n\r\n    /** Event that fires each time the gizmo is clicked. */\r\n    public readonly onClickedObservable = new Observable<AbstractSoundSource>();\r\n\r\n    /**\r\n     * Creates a SpatialAudioGizmo.\r\n     * @param gizmoLayer The utility layer the gizmo will be added to.\r\n     */\r\n    constructor(gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer) {\r\n        super(gizmoLayer);\r\n\r\n        const utilityScene = this.gizmoLayer.utilityLayerScene;\r\n\r\n        // Parent under _rootMesh so super.dispose() — which only disposes _rootMesh —\r\n        // also tears down our attachedMesh and avoids leaking it in the utility layer scene.\r\n        this.attachedMesh = new Mesh(\"spatialAudioGizmo\", utilityScene);\r\n        this.attachedMesh.parent = this._rootMesh;\r\n\r\n        this._material = new StandardMaterial(\"spatialAudio\", utilityScene);\r\n        this._material.diffuseColor = new Color3(0.5, 0.5, 0.5);\r\n        this._material.specularColor = new Color3(0.1, 0.1, 0.1);\r\n\r\n        this._audioMesh = SpatialAudioGizmo._CreateSpeakerMesh(utilityScene);\r\n        this._audioMesh.parent = this._rootMesh;\r\n        for (const child of this._audioMesh.getChildMeshes(false)) {\r\n            child.material = this._material;\r\n        }\r\n\r\n        const gizmoLight = this.gizmoLayer._getSharedGizmoLight();\r\n        gizmoLight.includedOnlyMeshes = gizmoLight.includedOnlyMeshes.concat(this._audioMesh.getChildMeshes(false));\r\n\r\n        this._pointerObserver = utilityScene.onPointerObservable.add((pointerInfo) => {\r\n            if (!this._soundSource) {\r\n                return;\r\n            }\r\n            const picked = pointerInfo.pickInfo?.pickedMesh;\r\n            this._isHovered = !!picked && this._rootMesh.getChildMeshes().indexOf(picked as Mesh) !== -1;\r\n            if (this._isHovered && pointerInfo.type === PointerEventTypes.POINTERDOWN && pointerInfo.event.button === 0) {\r\n                this.onClickedObservable.notifyObservers(this._soundSource);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * The sound source the gizmo is attached to.\r\n     */\r\n    public get soundSource(): Nullable<AbstractSoundSource> {\r\n        return this._soundSource;\r\n    }\r\n\r\n    public set soundSource(soundSource: Nullable<AbstractSoundSource>) {\r\n        this._soundSource = soundSource;\r\n        if (soundSource && this.attachedMesh) {\r\n            if (!this.attachedMesh.reservedDataStore) {\r\n                this.attachedMesh.reservedDataStore = {};\r\n            }\r\n            this.attachedMesh.reservedDataStore.spatialAudioGizmo = this;\r\n            this.attachedMesh.rotationQuaternion ??= new Quaternion();\r\n            this._update();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the material used to render the gizmo.\r\n     */\r\n    public get material(): StandardMaterial {\r\n        return this._material;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Mirrors the attached mesh to the sound source's spatial position and rotation.\r\n     */\r\n    protected override _update(): void {\r\n        super._update();\r\n\r\n        const source = this._soundSource;\r\n        const attachedMesh = this.attachedMesh;\r\n        if (!source || !attachedMesh || !source._isSpatial) {\r\n            return;\r\n        }\r\n\r\n        attachedMesh.rotationQuaternion ??= new Quaternion();\r\n\r\n        // When the sound is attached to a scene node, the actual world transform is on the node;\r\n        // the spatial facade only caches the most recent user-set position/rotation. Decompose\r\n        // the node's world matrix directly so the gizmo tracks movement of the attached entity,\r\n        // and honor the spatial sub-property's attachment options (useBoundingBox, attachmentType).\r\n        const spatial = source.spatial;\r\n        const attachedNode = spatial.attachedNode;\r\n        if (attachedNode) {\r\n            const worldRotation = TmpVectors.Quaternion[0];\r\n            const worldPosition = TmpVectors.Vector3[0];\r\n            attachedNode.getWorldMatrix().decompose(undefined, worldRotation, worldPosition);\r\n\r\n            if (spatial.attachmentType & SpatialAudioAttachmentType.Position) {\r\n                if (spatial.useBoundingBox && (attachedNode as AbstractMesh).getBoundingInfo) {\r\n                    attachedMesh.position.copyFrom((attachedNode as AbstractMesh).getBoundingInfo().boundingBox.centerWorld);\r\n                } else {\r\n                    attachedMesh.position.copyFrom(worldPosition);\r\n                }\r\n            } else {\r\n                attachedMesh.position.copyFrom(spatial.position);\r\n            }\r\n\r\n            if (spatial.attachmentType & SpatialAudioAttachmentType.Rotation) {\r\n                attachedMesh.rotationQuaternion.copyFrom(worldRotation);\r\n            } else {\r\n                attachedMesh.rotationQuaternion.copyFrom(spatial.rotationQuaternion);\r\n            }\r\n        } else {\r\n            attachedMesh.position.copyFrom(spatial.position);\r\n            attachedMesh.rotationQuaternion.copyFrom(spatial.rotationQuaternion);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the gizmo.\r\n     */\r\n    public override dispose(): void {\r\n        this.onClickedObservable.clear();\r\n        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);\r\n        this._material.dispose();\r\n        // _audioMesh and attachedMesh are children of _rootMesh, so super.dispose() handles them.\r\n        super.dispose();\r\n    }\r\n\r\n    private static _CreateSpeakerMesh(scene: Scene): Mesh {\r\n        const root = new Mesh(\"spatialAudioRoot\", scene);\r\n\r\n        // Spherical body for the source point.\r\n        const body = CreateSphere(\"spatialAudioBody\", { diameter: 1, segments: 8 }, scene);\r\n        body.parent = root;\r\n\r\n        // A flared cone pointing along +Z to indicate the sound's facing direction.\r\n        const cone = CreateCylinder(\r\n            \"spatialAudioCone\",\r\n            {\r\n                height: 1.4,\r\n                diameterTop: 1.6,\r\n                diameterBottom: 0.2,\r\n                tessellation: 12,\r\n                subdivisions: 1,\r\n            },\r\n            scene\r\n        );\r\n        cone.parent = root;\r\n        cone.rotation.x = Math.PI / 2;\r\n        cone.position.z = 0.9;\r\n\r\n        root.scaling.scaleInPlace(SpatialAudioGizmo._Scale);\r\n        return root;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Observer } from \"../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { Matrix, Vector3, Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type ImageProcessingConfiguration } from \"../../Materials/imageProcessingConfiguration.pure\";\r\nimport { BlurPostProcess } from \"../../PostProcesses/blurPostProcess.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { Plane } from \"../../Maths/math.plane\";\r\nimport { type UniformBuffer } from \"../uniformBuffer\";\r\nimport { type TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * Mirror texture can be used to simulate the view from a mirror in a scene.\r\n * It will dynamically be rendered every frame to adapt to the camera point of view.\r\n * You can then easily use it as a reflectionTexture on a flat surface.\r\n * In case the surface is not a plane, please consider relying on reflection probes.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#mirrortexture\r\n */\r\nexport class MirrorTexture extends RenderTargetTexture {\r\n    /**\r\n     * Define the reflection plane we want to use. The mirrorPlane is usually set to the constructed reflector.\r\n     * It is possible to directly set the mirrorPlane by directly using a Plane(a, b, c, d) where a, b and c give the plane normal vector (a, b, c) and d is a scalar displacement from the mirrorPlane to the origin. However in all but the very simplest of situations it is more straight forward to set it to the reflector as stated in the doc.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#mirrors\r\n     */\r\n    public mirrorPlane = new Plane(0, 1, 0, 1);\r\n\r\n    /**\r\n     * Define the blur ratio used to blur the reflection if needed.\r\n     */\r\n    public set blurRatio(value: number) {\r\n        if (this._blurRatio === value) {\r\n            return;\r\n        }\r\n\r\n        this._blurRatio = value;\r\n        this._preparePostProcesses();\r\n    }\r\n\r\n    public get blurRatio(): number {\r\n        return this._blurRatio;\r\n    }\r\n\r\n    /**\r\n     * Define the adaptive blur kernel used to blur the reflection if needed.\r\n     * This will autocompute the closest best match for the `blurKernel`\r\n     */\r\n    public set adaptiveBlurKernel(value: number) {\r\n        this._adaptiveBlurKernel = value;\r\n        this._autoComputeBlurKernel();\r\n    }\r\n\r\n    /**\r\n     * Define the blur kernel used to blur the reflection if needed.\r\n     * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.\r\n     */\r\n    public set blurKernel(value: number) {\r\n        this.blurKernelX = value;\r\n        this.blurKernelY = value;\r\n    }\r\n\r\n    /**\r\n     * Define the blur kernel on the X Axis used to blur the reflection if needed.\r\n     * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.\r\n     */\r\n    public set blurKernelX(value: number) {\r\n        if (this._blurKernelX === value) {\r\n            return;\r\n        }\r\n\r\n        this._blurKernelX = value;\r\n        this._preparePostProcesses();\r\n    }\r\n\r\n    public get blurKernelX(): number {\r\n        return this._blurKernelX;\r\n    }\r\n\r\n    /**\r\n     * Define the blur kernel on the Y Axis used to blur the reflection if needed.\r\n     * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.\r\n     */\r\n    public set blurKernelY(value: number) {\r\n        if (this._blurKernelY === value) {\r\n            return;\r\n        }\r\n\r\n        this._blurKernelY = value;\r\n        this._preparePostProcesses();\r\n    }\r\n\r\n    public get blurKernelY(): number {\r\n        return this._blurKernelY;\r\n    }\r\n\r\n    private _autoComputeBlurKernel(): void {\r\n        const engine = this.getScene()!.getEngine();\r\n\r\n        const dw = this.getRenderWidth() / engine.getRenderWidth();\r\n        const dh = this.getRenderHeight() / engine.getRenderHeight();\r\n        this.blurKernelX = this._adaptiveBlurKernel * dw;\r\n        this.blurKernelY = this._adaptiveBlurKernel * dh;\r\n    }\r\n\r\n    public override resize(size: TextureSize | { ratio: number }): void {\r\n        super.resize(size);\r\n        if (!this._adaptiveBlurKernel) {\r\n            this._preparePostProcesses();\r\n        } else {\r\n            this._autoComputeBlurKernel();\r\n        }\r\n    }\r\n\r\n    protected override _onRatioRescale(): void {\r\n        if (this._sizeRatio) {\r\n            this.resize(this._initialSizeParameter);\r\n            if (!this._adaptiveBlurKernel) {\r\n                this._preparePostProcesses();\r\n            }\r\n        }\r\n\r\n        if (this._adaptiveBlurKernel) {\r\n            this._autoComputeBlurKernel();\r\n        }\r\n    }\r\n\r\n    private _updateGammaSpace() {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        this.gammaSpace = !scene.imageProcessingConfiguration.isEnabled || !scene.imageProcessingConfiguration.applyByPostProcess;\r\n    }\r\n\r\n    private _imageProcessingConfigChangeObserver: Nullable<Observer<ImageProcessingConfiguration>>;\r\n\r\n    private _transformMatrix = Matrix.Zero();\r\n    private _mirrorMatrix = Matrix.Zero();\r\n\r\n    private _blurX: Nullable<BlurPostProcess>;\r\n    private _blurY: Nullable<BlurPostProcess>;\r\n    private _adaptiveBlurKernel = 0;\r\n    private _blurKernelX = 0;\r\n    private _blurKernelY = 0;\r\n    private _blurRatio = 1.0;\r\n    private _sceneUBO: UniformBuffer;\r\n    private _currentSceneUBO: UniformBuffer;\r\n\r\n    /**\r\n     * Instantiates a Mirror Texture.\r\n     * Mirror texture can be used to simulate the view from a mirror in a scene.\r\n     * It will dynamically be rendered every frame to adapt to the camera point of view.\r\n     * You can then easily use it as a reflectionTexture on a flat surface.\r\n     * In case the surface is not a plane, please consider relying on reflection probes.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#mirrors\r\n     * @param name\r\n     * @param size\r\n     * @param scene\r\n     * @param generateMipMaps\r\n     * @param type\r\n     * @param samplingMode\r\n     * @param generateDepthBuffer\r\n     */\r\n    constructor(\r\n        name: string,\r\n        size: number | { width: number; height: number } | { ratio: number },\r\n        scene?: Scene,\r\n        generateMipMaps?: boolean,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        samplingMode = Texture.BILINEAR_SAMPLINGMODE,\r\n        generateDepthBuffer = true\r\n    ) {\r\n        super(name, size, scene, generateMipMaps, true, type, false, samplingMode, generateDepthBuffer);\r\n\r\n        scene = <Scene>this.getScene();\r\n\r\n        if (!scene) {\r\n            return this;\r\n        }\r\n        this.ignoreCameraViewport = true;\r\n\r\n        this._updateGammaSpace();\r\n        this._imageProcessingConfigChangeObserver = scene.imageProcessingConfiguration.onUpdateParameters.add(() => {\r\n            this._updateGammaSpace();\r\n        });\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        if (engine.supportsUniformBuffers) {\r\n            this._sceneUBO = scene.createSceneUniformBuffer(`Scene for Mirror Texture (name \"${name}\")`, { forceMono: true });\r\n        }\r\n\r\n        let saveClipPlane: Nullable<Plane>;\r\n\r\n        this.onBeforeRenderObservable.add(() => {\r\n            if (this._sceneUBO) {\r\n                this._currentSceneUBO = scene.getSceneUniformBuffer();\r\n                scene.setSceneUniformBuffer(this._sceneUBO);\r\n                scene.getSceneUniformBuffer().unbindEffect();\r\n            }\r\n\r\n            Matrix.ReflectionToRef(this.mirrorPlane, this._mirrorMatrix);\r\n            this._mirrorMatrix.multiplyToRef(scene.getViewMatrix(), this._transformMatrix);\r\n\r\n            scene.setTransformMatrix(this._transformMatrix, scene.getProjectionMatrix());\r\n\r\n            saveClipPlane = scene.clipPlane;\r\n            scene.clipPlane = this.mirrorPlane;\r\n\r\n            const eyePos = Vector3.TransformCoordinates((<Camera>scene.activeCamera).globalPosition, this._mirrorMatrix);\r\n            scene._mirroredCameraPosition = eyePos;\r\n            scene._forcedViewPosition = eyePos; // More performant to set 2 properties here than to check both mirroredCameraPos and forcedViewPos within eye binding (which happens on critical rendering path)\r\n        });\r\n\r\n        this.onAfterRenderObservable.add(() => {\r\n            if (this._sceneUBO) {\r\n                scene.setSceneUniformBuffer(this._currentSceneUBO);\r\n            }\r\n            scene.updateTransformMatrix();\r\n            scene._mirroredCameraPosition = null;\r\n            scene._forcedViewPosition = null;\r\n\r\n            scene.clipPlane = saveClipPlane;\r\n        });\r\n    }\r\n\r\n    private _preparePostProcesses(): void {\r\n        this.clearPostProcesses(true);\r\n\r\n        if (this._blurKernelX && this._blurKernelY) {\r\n            const engine = (<Scene>this.getScene()).getEngine();\r\n\r\n            const textureType =\r\n                engine.getCaps().textureFloatRender && engine.getCaps().textureFloatLinearFiltering ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n            this._blurX = new BlurPostProcess(\r\n                \"horizontal blur\",\r\n                new Vector2(1.0, 0),\r\n                this._blurKernelX,\r\n                this._blurRatio,\r\n                null,\r\n                Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                false,\r\n                textureType\r\n            );\r\n            this._blurX.autoClear = false;\r\n\r\n            if (this._blurRatio === 1 && this.samples < 2 && this._texture) {\r\n                this._blurX.inputTexture = this._renderTarget!;\r\n            } else {\r\n                this._blurX.alwaysForcePOT = true;\r\n            }\r\n\r\n            this._blurY = new BlurPostProcess(\r\n                \"vertical blur\",\r\n                new Vector2(0, 1.0),\r\n                this._blurKernelY,\r\n                this._blurRatio,\r\n                null,\r\n                Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                false,\r\n                textureType\r\n            );\r\n            this._blurY.autoClear = false;\r\n            this._blurY.alwaysForcePOT = this._blurRatio !== 1;\r\n\r\n            this.addPostProcess(this._blurX);\r\n            this.addPostProcess(this._blurY);\r\n        } else {\r\n            if (this._blurY) {\r\n                this.removePostProcess(this._blurY);\r\n                this._blurY.dispose();\r\n                this._blurY = null;\r\n            }\r\n            if (this._blurX) {\r\n                this.removePostProcess(this._blurX);\r\n                this._blurX.dispose();\r\n                this._blurX = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the mirror texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): MirrorTexture {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return this;\r\n        }\r\n\r\n        const textureSize = this.getSize();\r\n        const newTexture = new MirrorTexture(\r\n            this.name,\r\n            textureSize.width,\r\n            scene,\r\n            this._renderTargetOptions.generateMipMaps,\r\n            this._renderTargetOptions.type,\r\n            this._renderTargetOptions.samplingMode,\r\n            this._renderTargetOptions.generateDepthBuffer\r\n        );\r\n\r\n        // Base texture\r\n        newTexture.hasAlpha = this.hasAlpha;\r\n        newTexture.level = this.level;\r\n\r\n        // Mirror Texture\r\n        newTexture.mirrorPlane = this.mirrorPlane.clone();\r\n        if (this.renderList) {\r\n            newTexture.renderList = this.renderList.slice(0);\r\n        }\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture to a JSON representation you could use in Parse later on\r\n     * @returns the serialized JSON representation\r\n     */\r\n    public override serialize(): any {\r\n        if (!this.name) {\r\n            return null;\r\n        }\r\n\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.mirrorPlane = this.mirrorPlane.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        const scene = this.getScene();\r\n\r\n        if (scene) {\r\n            scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigChangeObserver);\r\n        }\r\n        this._sceneUBO?.dispose();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mirrorTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMirrorTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Texture._CreateMirror = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean): MirrorTexture => {\r\n        return new MirrorTexture(name, renderTargetSize, scene, generateMipMaps);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { serialize, serializeAsColor3, expandToProperty, serializeAsTexture, serializeAsVector3 } from \"../../Misc/decorators\";\r\nimport { SmartArray } from \"../../Misc/smartArray\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable, type int, type float } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type Matrix, TmpVectors, Vector3, Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type IEffectCreationOptions } from \"../../Materials/effect.pure\";\r\nimport { MaterialDefines } from \"../../Materials/materialDefines\";\r\nimport { PushMaterial } from \"../../Materials/pushMaterial\";\r\nimport { ImageProcessingDefinesMixin } from \"../../Materials/imageProcessingConfiguration.defines\";\r\nimport { ImageProcessingConfiguration, RegisterImageProcessingConfiguration } from \"../../Materials/imageProcessingConfiguration.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type IShadowLight } from \"../../Lights/shadowLight\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { MaterialFlags } from \"../materialFlags\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\n\r\nimport { EffectFallbacks } from \"../effectFallbacks\";\r\nimport { AddClipPlaneUniforms, BindClipPlane } from \"../clipPlaneMaterialHelper\";\r\nimport {\r\n    BindBonesParameters,\r\n    BindFogParameters,\r\n    BindLights,\r\n    BindLogDepth,\r\n    BindTextureMatrix,\r\n    BindIBLParameters,\r\n    BindIBLSamplers,\r\n    HandleFallbacksForShadows,\r\n    PrepareAttributesForBones,\r\n    PrepareAttributesForInstances,\r\n    PrepareDefinesForAttributes,\r\n    PrepareDefinesForFrameBoundValues,\r\n    PrepareDefinesForLights,\r\n    PrepareDefinesForIBL,\r\n    PrepareDefinesForMergedUV,\r\n    PrepareDefinesForMisc,\r\n    PrepareDefinesForMultiview,\r\n    PrepareUniformsAndSamplersList,\r\n    PrepareUniformsAndSamplersForIBL,\r\n    PrepareUniformLayoutForIBL,\r\n    AreLightsTexturesReady,\r\n} from \"../materialHelper.functions\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { _ShaderImportLoader } from \"../../Misc/shaderImportLoader\";\r\nimport { ImageProcessingMixin } from \"../imageProcessing\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\nclass BackgroundMaterialDefinesBase extends MaterialDefines {}\r\n\r\n/**\r\n * Background material defines definition.\r\n * @internal Mainly internal Use\r\n */\r\nclass BackgroundMaterialDefines extends ImageProcessingDefinesMixin(BackgroundMaterialDefinesBase) {\r\n    /**\r\n     * True if the diffuse texture is in use.\r\n     */\r\n    public DIFFUSE = false;\r\n\r\n    /**\r\n     * The direct UV channel to use.\r\n     */\r\n    public DIFFUSEDIRECTUV = 0;\r\n\r\n    /**\r\n     * True if the diffuse texture is in gamma space.\r\n     */\r\n    public GAMMADIFFUSE = false;\r\n\r\n    /**\r\n     * True if the diffuse texture has opacity in the alpha channel.\r\n     */\r\n    public DIFFUSEHASALPHA = false;\r\n\r\n    /**\r\n     * True if you want the material to fade to transparent at grazing angle.\r\n     */\r\n    public OPACITYFRESNEL = false;\r\n\r\n    /**\r\n     * True if an extra blur needs to be added in the reflection.\r\n     */\r\n    public REFLECTIONBLUR = false;\r\n\r\n    /**\r\n     * True if you want the material to fade to reflection at grazing angle.\r\n     */\r\n    public REFLECTIONFRESNEL = false;\r\n\r\n    /**\r\n     * True if you want the material to falloff as far as you move away from the scene center.\r\n     */\r\n    public REFLECTIONFALLOFF = false;\r\n\r\n    /**\r\n     * False if the current Webgl implementation does not support the texture lod extension.\r\n     */\r\n    public TEXTURELODSUPPORT = false;\r\n\r\n    /**\r\n     * True to ensure the data are premultiplied.\r\n     */\r\n    public PREMULTIPLYALPHA = false;\r\n\r\n    /**\r\n     * True if the texture contains cooked RGB values and not gray scaled multipliers.\r\n     */\r\n    public USERGBCOLOR = false;\r\n\r\n    /**\r\n     * True if highlight and shadow levels have been specified. It can help ensuring the main perceived color\r\n     * stays aligned with the desired configuration.\r\n     */\r\n    public USEHIGHLIGHTANDSHADOWCOLORS = false;\r\n\r\n    /**\r\n     * True if only shadows must be rendered\r\n     */\r\n    public BACKMAT_SHADOWONLY = false;\r\n\r\n    /**\r\n     * True to add noise in order to reduce the banding effect.\r\n     */\r\n    public NOISE = false;\r\n\r\n    /**\r\n     * is the reflection texture in BGR color scheme?\r\n     * Mainly used to solve a bug in ios10 video tag\r\n     */\r\n    public REFLECTIONBGR = false;\r\n\r\n    /**\r\n     * True if ground projection has been enabled.\r\n     */\r\n    public PROJECTED_GROUND = false;\r\n\r\n    /** Defines whether reflection is enabled */\r\n    public REFLECTION = false;\r\n    /** Defines whether the reflection map is 3D */\r\n    public REFLECTIONMAP_3D = false;\r\n    /** Defines whether the reflection map is spherical */\r\n    public REFLECTIONMAP_SPHERICAL = false;\r\n    /** Defines whether the reflection map is planar */\r\n    public REFLECTIONMAP_PLANAR = false;\r\n    /** Defines whether the reflection map is cubic */\r\n    public REFLECTIONMAP_CUBIC = false;\r\n    /** Defines whether the reflection map is in projection mode */\r\n    public REFLECTIONMAP_PROJECTION = false;\r\n    /** Defines whether the reflection map is a skybox */\r\n    public REFLECTIONMAP_SKYBOX = false;\r\n    /** Defines whether the reflection map is explicit */\r\n    public REFLECTIONMAP_EXPLICIT = false;\r\n    /** Defines whether the reflection map is equirectangular */\r\n    public REFLECTIONMAP_EQUIRECTANGULAR = false;\r\n    /** Defines whether the reflection map is fixed equirectangular */\r\n    public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;\r\n    /** Defines whether the reflection map is mirrored fixed equirectangular */\r\n    public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;\r\n    /** Defines whether the cubic map should be inverted */\r\n    public INVERTCUBICMAP = false;\r\n    /** Defines whether the reflection map uses opposite Z */\r\n    public REFLECTIONMAP_OPPOSITEZ = false;\r\n    /** Defines whether LOD is stored in the reflection alpha channel */\r\n    public LODINREFLECTIONALPHA = false;\r\n    /** Defines whether the reflection uses gamma space */\r\n    public GAMMAREFLECTION = false;\r\n    /** Defines whether the reflection is in RGBD format */\r\n    public RGBDREFLECTION = false;\r\n    /** Defines whether the equirectangular reflection uses a custom field of view */\r\n    public EQUIRECTANGULAR_RELFECTION_FOV = false;\r\n\r\n    /** Defines whether main UV1 channel is used */\r\n    public MAINUV1 = false;\r\n    /** Defines whether main UV2 channel is used */\r\n    public MAINUV2 = false;\r\n    /** Defines whether UV1 is used */\r\n    public UV1 = false;\r\n    /** Defines whether UV2 is used */\r\n    public UV2 = false;\r\n    /** Defines whether clip plane 1 is enabled */\r\n    public CLIPPLANE = false;\r\n    /** Defines whether clip plane 2 is enabled */\r\n    public CLIPPLANE2 = false;\r\n    /** Defines whether clip plane 3 is enabled */\r\n    public CLIPPLANE3 = false;\r\n    /** Defines whether clip plane 4 is enabled */\r\n    public CLIPPLANE4 = false;\r\n    /** Defines whether clip plane 5 is enabled */\r\n    public CLIPPLANE5 = false;\r\n    /** Defines whether clip plane 6 is enabled */\r\n    public CLIPPLANE6 = false;\r\n    /** Defines whether point size is used */\r\n    public POINTSIZE = false;\r\n    /** Defines whether fog is enabled */\r\n    public FOG = false;\r\n    /** Defines whether normals are available */\r\n    public NORMAL = false;\r\n    /** Defines the number of bone influencers */\r\n    public NUM_BONE_INFLUENCERS = 0;\r\n    /** Defines the number of bones per mesh */\r\n    public BonesPerMesh = 0;\r\n    /** Defines whether instances are used */\r\n    public INSTANCES = false;\r\n    /** Defines whether shadow uses float textures */\r\n    public SHADOWFLOAT = false;\r\n    /** Defines whether logarithmic depth is enabled */\r\n    public LOGARITHMICDEPTH = false;\r\n    /** Defines whether non-uniform scaling is applied */\r\n    public NONUNIFORMSCALING = false;\r\n    /** Defines whether alpha testing is enabled */\r\n    public ALPHATEST = false;\r\n\r\n    /**\r\n     * Constructor of the defines.\r\n     */\r\n    constructor() {\r\n        super();\r\n        this.rebuild();\r\n    }\r\n}\r\n\r\nclass BackgroundMaterialBase extends ImageProcessingMixin(PushMaterial) {}\r\n/**\r\n * Background material used to create an efficient environment around your scene.\r\n * #157MGZ: simple test\r\n */\r\nexport class BackgroundMaterial extends BackgroundMaterialBase {\r\n    /**\r\n     * Standard reflectance value at parallel view angle.\r\n     */\r\n    public static StandardReflectance0 = 0.05;\r\n\r\n    /**\r\n     * Standard reflectance value at grazing angle.\r\n     */\r\n    public static StandardReflectance90 = 0.5;\r\n\r\n    @serializeAsColor3()\r\n    protected _primaryColor: Color3;\r\n    /**\r\n     * Key light Color (multiply against the environment texture)\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor primaryColor = Color3.White();\r\n\r\n    @serializeAsColor3()\r\n    protected __perceptualColor: Nullable<Color3>;\r\n    /**\r\n     * Experimental Internal Use Only.\r\n     *\r\n     * Key light Color in \"perceptual value\" meaning the color you would like to see on screen.\r\n     * This acts as a helper to set the primary color to a more \"human friendly\" value.\r\n     * Conversion to linear space as well as exposure and tone mapping correction will be applied to keep the\r\n     * output color as close as possible from the chosen value.\r\n     * (This does not account for contrast color grading and color curves as they are considered post effect and not directly\r\n     * part of lighting setup.)\r\n     */\r\n    public get _perceptualColor(): Nullable<Color3> {\r\n        return this.__perceptualColor;\r\n    }\r\n    public set _perceptualColor(value: Nullable<Color3>) {\r\n        this.__perceptualColor = value;\r\n        this._computePrimaryColorFromPerceptualColor();\r\n        this._markAllSubMeshesAsLightsDirty();\r\n    }\r\n\r\n    @serialize()\r\n    protected _primaryColorShadowLevel: float = 0;\r\n    /**\r\n     * Defines the level of the shadows (dark area of the reflection map) in order to help scaling the colors.\r\n     * The color opposite to the primary color is used at the level chosen to define what the black area would look.\r\n     */\r\n    public get primaryColorShadowLevel(): float {\r\n        return this._primaryColorShadowLevel;\r\n    }\r\n    public set primaryColorShadowLevel(value: float) {\r\n        this._primaryColorShadowLevel = value;\r\n        this._computePrimaryColors();\r\n        this._markAllSubMeshesAsLightsDirty();\r\n    }\r\n\r\n    @serialize()\r\n    protected _primaryColorHighlightLevel: float = 0;\r\n    /**\r\n     * Defines the level of the highlights (highlight area of the reflection map) in order to help scaling the colors.\r\n     * The primary color is used at the level chosen to define what the white area would look.\r\n     */\r\n    public get primaryColorHighlightLevel(): float {\r\n        return this._primaryColorHighlightLevel;\r\n    }\r\n    public set primaryColorHighlightLevel(value: float) {\r\n        this._primaryColorHighlightLevel = value;\r\n        this._computePrimaryColors();\r\n        this._markAllSubMeshesAsLightsDirty();\r\n    }\r\n\r\n    @serializeAsTexture()\r\n    protected _reflectionTexture: Nullable<BaseTexture>;\r\n    /**\r\n     * Reflection Texture used in the material.\r\n     * Should be author in a specific way for the best result (refer to the documentation).\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionTexture: Nullable<BaseTexture> = null;\r\n\r\n    @serialize()\r\n    protected _reflectionBlur: float;\r\n    /**\r\n     * Reflection Texture level of blur.\r\n     *\r\n     * Can be use to reuse an existing HDR Texture and target a specific LOD to prevent authoring the\r\n     * texture twice.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionBlur: float = 0;\r\n\r\n    @serializeAsTexture()\r\n    protected _diffuseTexture: Nullable<BaseTexture>;\r\n    /**\r\n     * Diffuse Texture used in the material.\r\n     * Should be author in a specific way for the best result (refer to the documentation).\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor diffuseTexture: Nullable<BaseTexture> = null;\r\n\r\n    protected _shadowLights: Nullable<IShadowLight[]> = null;\r\n    /**\r\n     * Specify the list of lights casting shadow on the material.\r\n     * All scene shadow lights will be included if null.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor shadowLights: Nullable<IShadowLight[]> = null;\r\n\r\n    @serialize()\r\n    protected _shadowLevel: float;\r\n    /**\r\n     * Helps adjusting the shadow to a softer level if required.\r\n     * 0 means black shadows and 1 means no shadows.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor shadowLevel: float = 0;\r\n\r\n    @serializeAsVector3()\r\n    protected _sceneCenter: Vector3;\r\n    /**\r\n     * In case of opacity Fresnel or reflection falloff, this is use as a scene center.\r\n     * It is usually zero but might be interesting to modify according to your setup.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor sceneCenter: Vector3 = Vector3.Zero();\r\n\r\n    @serialize()\r\n    protected _opacityFresnel: boolean;\r\n    /**\r\n     * This helps specifying that the material is falling off to the sky box at grazing angle.\r\n     * This helps ensuring a nice transition when the camera goes under the ground.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor opacityFresnel: boolean = true;\r\n\r\n    @serialize()\r\n    protected _reflectionFresnel: boolean;\r\n    /**\r\n     * This helps specifying that the material is falling off from diffuse to the reflection texture at grazing angle.\r\n     * This helps adding a mirror texture on the ground.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionFresnel: boolean = false;\r\n\r\n    @serialize()\r\n    protected _reflectionFalloffDistance: number;\r\n    /**\r\n     * This helps specifying the falloff radius off the reflection texture from the sceneCenter.\r\n     * This helps adding a nice falloff effect to the reflection if used as a mirror for instance.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionFalloffDistance: number = 0.0;\r\n\r\n    @serialize()\r\n    protected _reflectionAmount: number;\r\n    /**\r\n     * This specifies the weight of the reflection against the background in case of reflection Fresnel.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionAmount: number = 1.0;\r\n\r\n    @serialize()\r\n    protected _reflectionReflectance0: number;\r\n    /**\r\n     * This specifies the weight of the reflection at grazing angle.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionReflectance0: number = 0.05;\r\n\r\n    @serialize()\r\n    protected _reflectionReflectance90: number;\r\n    /**\r\n     * This specifies the weight of the reflection at a perpendicular point of view.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionReflectance90: number = 0.5;\r\n\r\n    /**\r\n     * Sets the reflection reflectance fresnel values according to the default standard\r\n     * empirically know to work well :-)\r\n     */\r\n    public set reflectionStandardFresnelWeight(value: number) {\r\n        let reflectionWeight = value;\r\n\r\n        if (reflectionWeight < 0.5) {\r\n            reflectionWeight = reflectionWeight * 2.0;\r\n            this.reflectionReflectance0 = BackgroundMaterial.StandardReflectance0 * reflectionWeight;\r\n            this.reflectionReflectance90 = BackgroundMaterial.StandardReflectance90 * reflectionWeight;\r\n        } else {\r\n            reflectionWeight = reflectionWeight * 2.0 - 1.0;\r\n            this.reflectionReflectance0 = BackgroundMaterial.StandardReflectance0 + (1.0 - BackgroundMaterial.StandardReflectance0) * reflectionWeight;\r\n            this.reflectionReflectance90 = BackgroundMaterial.StandardReflectance90 + (1.0 - BackgroundMaterial.StandardReflectance90) * reflectionWeight;\r\n        }\r\n    }\r\n\r\n    @serialize()\r\n    protected _useRGBColor: boolean;\r\n    /**\r\n     * Helps to directly use the maps channels instead of their level.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRGBColor: boolean = true;\r\n\r\n    @serialize()\r\n    protected _enableNoise: boolean;\r\n    /**\r\n     * This helps reducing the banding effect that could occur on the background.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor enableNoise: boolean = false;\r\n\r\n    /**\r\n     * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values \"zoom in\" and higher values \"zoom out\".\r\n     * Best used when trying to implement visual zoom effects like fish-eye or binoculars while not adjusting camera fov.\r\n     * Recommended to be keep at 1.0 except for special cases.\r\n     */\r\n    public get fovMultiplier(): number {\r\n        return this._fovMultiplier;\r\n    }\r\n    public set fovMultiplier(value: number) {\r\n        if (isNaN(value)) {\r\n            value = 1.0;\r\n        }\r\n        this._fovMultiplier = Math.max(0.0, Math.min(2.0, value));\r\n    }\r\n    private _fovMultiplier: float = 1.0;\r\n\r\n    /**\r\n     * Enable the FOV adjustment feature controlled by fovMultiplier.\r\n     */\r\n    public useEquirectangularFOV: boolean = false;\r\n\r\n    @serialize()\r\n    private _maxSimultaneousLights: int = 4;\r\n    /**\r\n     * Number of Simultaneous lights allowed on the material.\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor maxSimultaneousLights: int = 4;\r\n\r\n    @serialize()\r\n    private _shadowOnly: boolean = false;\r\n    /**\r\n     * Make the material only render shadows\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor shadowOnly: boolean = false;\r\n\r\n    /**\r\n     * Due to a bug in iOS10, video tags (which are using the background material) are in BGR and not RGB.\r\n     * Setting this flag to true (not done automatically!) will convert it back to RGB.\r\n     */\r\n    public switchToBGR: boolean = false;\r\n\r\n    private _enableGroundProjection: boolean = false;\r\n    /**\r\n     * Enables the ground projection mode on the material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/skybox#ground-projection\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor enableGroundProjection: boolean = false;\r\n\r\n    /**\r\n     * Defines the radius of the projected ground if enableGroundProjection is true.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/skybox#ground-projection\r\n     */\r\n    @serialize()\r\n    public projectedGroundRadius = 1000;\r\n\r\n    /**\r\n     * Defines the height of the projected ground if enableGroundProjection is true.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/skybox#ground-projection\r\n     */\r\n    @serialize()\r\n    public projectedGroundHeight = 10;\r\n\r\n    // Temp values kept as cache in the material.\r\n    private _renderTargets = new SmartArray<RenderTargetTexture>(16);\r\n    private _reflectionControls = Vector4.Zero();\r\n    private _white = Color3.White();\r\n    private _primaryShadowColor = Color3.Black();\r\n    private _primaryHighlightColor = Color3.Black();\r\n\r\n    private static readonly _ShaderLoader = /*#__PURE__*/ new _ShaderImportLoader(\r\n        () => [import(\"../../Shaders/background.vertex\"), import(\"../../Shaders/background.fragment\")],\r\n        () => [import(\"../../ShadersWGSL/background.vertex\"), import(\"../../ShadersWGSL/background.fragment\")]\r\n    );\r\n\r\n    /**\r\n     * Instantiates a Background Material in the given scene\r\n     * @param name The friendly name of the material\r\n     * @param scene The scene to add the material to\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(name: string, scene?: Scene, forceGLSL = false) {\r\n        super(name, scene, undefined, forceGLSL);\r\n\r\n        // Setup the default processing configuration to the scene.\r\n        this._attachImageProcessingConfiguration(null);\r\n\r\n        this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {\r\n            this._renderTargets.reset();\r\n\r\n            if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {\r\n                this._renderTargets.push(this._diffuseTexture as RenderTargetTexture);\r\n            }\r\n\r\n            if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n                this._renderTargets.push(this._reflectionTexture as RenderTargetTexture);\r\n            }\r\n\r\n            return this._renderTargets;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that current material needs to register RTT\r\n     */\r\n    public override get hasRenderTargetTextures(): boolean {\r\n        if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * The entire material has been created in order to prevent overdraw.\r\n     * @returns false\r\n     */\r\n    public override needAlphaTesting(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * The entire material has been created in order to prevent overdraw.\r\n     * @returns true if blending is enable\r\n     */\r\n    public override needAlphaBlending(): boolean {\r\n        return this.alpha < 1 || (this._diffuseTexture != null && this._diffuseTexture.hasAlpha) || this._shadowOnly;\r\n    }\r\n\r\n    /**\r\n     * Checks whether the material is ready to be rendered for a given mesh.\r\n     * @param mesh The mesh to render\r\n     * @param subMesh The submesh to check against\r\n     * @param useInstances Specify wether or not the material is used with instances\r\n     * @returns true if all the dependencies are ready (Textures, Effects...)\r\n     */\r\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances: boolean = false): boolean {\r\n        const drawWrapper = subMesh._drawWrapper;\r\n\r\n        if (drawWrapper.effect && this.isFrozen) {\r\n            if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        if (!subMesh.materialDefines) {\r\n            subMesh.materialDefines = new BackgroundMaterialDefines();\r\n        }\r\n\r\n        const scene = this.getScene();\r\n        const defines = <BackgroundMaterialDefines>subMesh.materialDefines;\r\n\r\n        if (this._isReadyForSubMesh(subMesh)) {\r\n            return true;\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        // Lights\r\n        PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);\r\n        defines._needNormals = true;\r\n\r\n        if (!AreLightsTexturesReady(scene, mesh, this._maxSimultaneousLights)) {\r\n            return false;\r\n        }\r\n\r\n        // Multiview\r\n        PrepareDefinesForMultiview(scene, defines);\r\n\r\n        // Textures\r\n        if (defines._areTexturesDirty) {\r\n            defines._needUVs = false;\r\n            if (scene.texturesEnabled) {\r\n                if (scene.getEngine().getCaps().textureLOD) {\r\n                    defines.TEXTURELODSUPPORT = true;\r\n                }\r\n\r\n                if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                    if (!this._diffuseTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n\r\n                    PrepareDefinesForMergedUV(this._diffuseTexture, defines, \"DIFFUSE\");\r\n                    defines.DIFFUSEHASALPHA = this._diffuseTexture.hasAlpha;\r\n                    defines.GAMMADIFFUSE = this._diffuseTexture.gammaSpace;\r\n                    defines.OPACITYFRESNEL = this._opacityFresnel;\r\n                } else {\r\n                    defines.DIFFUSE = false;\r\n                    defines.DIFFUSEDIRECTUV = 0;\r\n                    defines.DIFFUSEHASALPHA = false;\r\n                    defines.GAMMADIFFUSE = false;\r\n                    defines.OPACITYFRESNEL = false;\r\n                }\r\n\r\n                const reflectionTexture = this._reflectionTexture;\r\n                PrepareDefinesForIBL(scene, reflectionTexture, defines);\r\n                if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    if (!reflectionTexture.isReadyOrNotBlocking()) {\r\n                        return false;\r\n                    }\r\n                    defines.EQUIRECTANGULAR_RELFECTION_FOV = this.useEquirectangularFOV;\r\n                    defines.REFLECTIONBGR = this.switchToBGR;\r\n                    defines.REFLECTIONBLUR = this._reflectionBlur > 0;\r\n\r\n                    if (this.reflectionFresnel) {\r\n                        defines.REFLECTIONFRESNEL = true;\r\n                        defines.REFLECTIONFALLOFF = this.reflectionFalloffDistance > 0;\r\n\r\n                        this._reflectionControls.x = this.reflectionAmount;\r\n                        this._reflectionControls.y = this.reflectionReflectance0;\r\n                        this._reflectionControls.z = this.reflectionReflectance90;\r\n                        this._reflectionControls.w = 1 / this.reflectionFalloffDistance;\r\n                    } else {\r\n                        defines.REFLECTIONFRESNEL = false;\r\n                        defines.REFLECTIONFALLOFF = false;\r\n                    }\r\n                } else {\r\n                    defines.REFLECTIONFRESNEL = false;\r\n                    defines.REFLECTIONFALLOFF = false;\r\n                    defines.REFLECTIONBLUR = false;\r\n                }\r\n            }\r\n\r\n            defines.PREMULTIPLYALPHA = this.alphaMode === Constants.ALPHA_PREMULTIPLIED || this.alphaMode === Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n            defines.USERGBCOLOR = this._useRGBColor;\r\n            defines.NOISE = this._enableNoise;\r\n        }\r\n\r\n        if (defines._areLightsDirty) {\r\n            defines.USEHIGHLIGHTANDSHADOWCOLORS = !this._useRGBColor && (this._primaryColorShadowLevel !== 0 || this._primaryColorHighlightLevel !== 0);\r\n            defines.BACKMAT_SHADOWONLY = this._shadowOnly;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {\r\n            if (!this._imageProcessingConfiguration.isReady()) {\r\n                return false;\r\n            }\r\n\r\n            this._imageProcessingConfiguration.prepareDefines(defines);\r\n        }\r\n\r\n        if (defines._areMiscDirty) {\r\n            if (defines.REFLECTIONMAP_3D && this._enableGroundProjection) {\r\n                defines.PROJECTED_GROUND = true;\r\n                defines.REFLECTIONMAP_SKYBOX = true;\r\n            } else {\r\n                defines.PROJECTED_GROUND = false;\r\n            }\r\n        }\r\n\r\n        // Misc.\r\n        PrepareDefinesForMisc(\r\n            mesh,\r\n            scene,\r\n            this._useLogarithmicDepth,\r\n            this.pointsCloud,\r\n            this.fogEnabled,\r\n            this.needAlphaTestingForMesh(mesh),\r\n            defines,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            this._isVertexOutputInvariant\r\n        );\r\n\r\n        // Values that need to be evaluated on every frame\r\n        PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, subMesh.getRenderingMesh().hasThinInstances);\r\n\r\n        // Attribs\r\n        if (PrepareDefinesForAttributes(mesh, defines, false, true, false)) {\r\n            if (mesh) {\r\n                if (!scene.getEngine().getCaps().standardDerivatives && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n                    mesh.createNormals(true);\r\n                    Logger.Warn(\"BackgroundMaterial: Normals have been created for the mesh: \" + mesh.name);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Get correct effect\r\n        if (defines.isDirty) {\r\n            defines.markAsProcessed();\r\n            scene.resetCachedMaterial();\r\n\r\n            // Fallbacks\r\n            const fallbacks = new EffectFallbacks();\r\n            if (defines.FOG) {\r\n                fallbacks.addFallback(0, \"FOG\");\r\n            }\r\n\r\n            if (defines.POINTSIZE) {\r\n                fallbacks.addFallback(1, \"POINTSIZE\");\r\n            }\r\n\r\n            if (defines.MULTIVIEW) {\r\n                fallbacks.addFallback(0, \"MULTIVIEW\");\r\n            }\r\n\r\n            HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights);\r\n\r\n            //Attributes\r\n            const attribs = [VertexBuffer.PositionKind];\r\n\r\n            if (defines.NORMAL) {\r\n                attribs.push(VertexBuffer.NormalKind);\r\n            }\r\n\r\n            if (defines.UV1) {\r\n                attribs.push(VertexBuffer.UVKind);\r\n            }\r\n\r\n            if (defines.UV2) {\r\n                attribs.push(VertexBuffer.UV2Kind);\r\n            }\r\n\r\n            PrepareAttributesForBones(attribs, mesh, defines, fallbacks);\r\n            PrepareAttributesForInstances(attribs, defines);\r\n\r\n            const uniforms = [\r\n                \"world\",\r\n                \"view\",\r\n                \"viewProjection\",\r\n                \"vEyePosition\",\r\n                \"vLightsType\",\r\n                \"vFogInfos\",\r\n                \"vFogColor\",\r\n                \"pointSize\",\r\n                \"mBones\",\r\n\r\n                \"vPrimaryColor\",\r\n                \"vPrimaryColorShadow\",\r\n                \"fFovMultiplier\",\r\n\r\n                \"shadowLevel\",\r\n                \"alpha\",\r\n\r\n                \"vBackgroundCenter\",\r\n                \"vReflectionControl\",\r\n\r\n                \"vDiffuseInfos\",\r\n                \"diffuseMatrix\",\r\n\r\n                \"projectedGroundInfos\",\r\n                \"logarithmicDepthConstant\",\r\n            ];\r\n\r\n            AddClipPlaneUniforms(uniforms);\r\n            const samplers = [\"diffuseSampler\"];\r\n            PrepareUniformsAndSamplersForIBL(uniforms, samplers, false);\r\n            const uniformBuffers = [\"Material\", \"Scene\"];\r\n\r\n            if (ImageProcessingConfiguration) {\r\n                ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);\r\n                ImageProcessingConfiguration.PrepareSamplers(samplers, defines);\r\n            }\r\n\r\n            PrepareUniformsAndSamplersList(<IEffectCreationOptions>{\r\n                uniformsNames: uniforms,\r\n                uniformBuffersNames: uniformBuffers,\r\n                samplers: samplers,\r\n                defines: defines,\r\n                maxSimultaneousLights: this._maxSimultaneousLights,\r\n                shaderLanguage: this._shaderLanguage,\r\n            });\r\n\r\n            const join = defines.toString();\r\n            const effect = scene.getEngine().createEffect(\r\n                \"background\",\r\n                <IEffectCreationOptions>{\r\n                    attributes: attribs,\r\n                    uniformsNames: uniforms,\r\n                    uniformBuffersNames: uniformBuffers,\r\n                    samplers: samplers,\r\n                    defines: join,\r\n                    fallbacks: fallbacks,\r\n                    onCompiled: this.onCompiled,\r\n                    onError: this.onError,\r\n                    indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights },\r\n                    shaderLanguage: this._shaderLanguage,\r\n                    extraInitializationsAsync: BackgroundMaterial._ShaderLoader.getLoadCallback(this._shaderLanguage),\r\n                },\r\n                engine\r\n            );\r\n            subMesh.setEffect(effect, defines, this._materialContext);\r\n\r\n            this.buildUniformLayout();\r\n        }\r\n\r\n        if (!subMesh.effect || !subMesh.effect.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        defines._renderId = scene.getRenderId();\r\n        drawWrapper._wasPreviouslyReady = true;\r\n        drawWrapper._wasPreviouslyUsingInstances = useInstances;\r\n\r\n        this._checkScenePerformancePriority();\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Compute the primary color according to the chosen perceptual color.\r\n     */\r\n    private _computePrimaryColorFromPerceptualColor(): void {\r\n        if (!this.__perceptualColor) {\r\n            return;\r\n        }\r\n\r\n        this._primaryColor.copyFrom(this.__perceptualColor);\r\n\r\n        // Revert gamma space.\r\n        this._primaryColor.toLinearSpaceToRef(this._primaryColor, this.getScene().getEngine().useExactSrgbConversions);\r\n\r\n        // Revert image processing configuration.\r\n        if (this._imageProcessingConfiguration) {\r\n            // Revert Exposure.\r\n            this._primaryColor.scaleToRef(1 / this._imageProcessingConfiguration.exposure, this._primaryColor);\r\n        }\r\n\r\n        this._computePrimaryColors();\r\n    }\r\n\r\n    /**\r\n     * Compute the highlights and shadow colors according to their chosen levels.\r\n     */\r\n    private _computePrimaryColors(): void {\r\n        if (this._primaryColorShadowLevel === 0 && this._primaryColorHighlightLevel === 0) {\r\n            return;\r\n        }\r\n\r\n        // Find the highlight color based on the configuration.\r\n        this._primaryColor.scaleToRef(this._primaryColorShadowLevel, this._primaryShadowColor);\r\n        this._primaryColor.subtractToRef(this._primaryShadowColor, this._primaryShadowColor);\r\n\r\n        // Find the shadow color based on the configuration.\r\n        this._white.subtractToRef(this._primaryColor, this._primaryHighlightColor);\r\n        this._primaryHighlightColor.scaleToRef(this._primaryColorHighlightLevel, this._primaryHighlightColor);\r\n        this._primaryColor.addToRef(this._primaryHighlightColor, this._primaryHighlightColor);\r\n    }\r\n\r\n    /**\r\n     * Build the uniform buffer used in the material.\r\n     */\r\n    public override buildUniformLayout(): void {\r\n        // Order is important !\r\n        this._uniformBuffer.addUniform(\"vPrimaryColor\", 4);\r\n        this._uniformBuffer.addUniform(\"vPrimaryColorShadow\", 4);\r\n        this._uniformBuffer.addUniform(\"vDiffuseInfos\", 2);\r\n        this._uniformBuffer.addUniform(\"diffuseMatrix\", 16);\r\n        this._uniformBuffer.addUniform(\"fFovMultiplier\", 1);\r\n        this._uniformBuffer.addUniform(\"pointSize\", 1);\r\n        this._uniformBuffer.addUniform(\"shadowLevel\", 1);\r\n        this._uniformBuffer.addUniform(\"alpha\", 1);\r\n        this._uniformBuffer.addUniform(\"vBackgroundCenter\", 3);\r\n        this._uniformBuffer.addUniform(\"vReflectionControl\", 4);\r\n        this._uniformBuffer.addUniform(\"projectedGroundInfos\", 2);\r\n\r\n        PrepareUniformLayoutForIBL(this._uniformBuffer, true, false, false);\r\n\r\n        this._uniformBuffer.create();\r\n    }\r\n\r\n    /**\r\n     * Unbind the material.\r\n     */\r\n    public override unbind(): void {\r\n        if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {\r\n            this._uniformBuffer.setTexture(\"diffuseSampler\", null);\r\n        }\r\n\r\n        if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {\r\n            this._uniformBuffer.setTexture(\"reflectionSampler\", null);\r\n        }\r\n\r\n        super.unbind();\r\n    }\r\n\r\n    /**\r\n     * Bind only the world matrix to the material.\r\n     * @param world The world matrix to bind.\r\n     */\r\n    public override bindOnlyWorldMatrix(world: Matrix): void {\r\n        this._activeEffect!.setMatrix(\"world\", world);\r\n    }\r\n\r\n    /**\r\n     * Bind the material for a dedicated submesh (every used meshes will be considered opaque).\r\n     * @param world The world matrix to bind.\r\n     * @param mesh the mesh to bind for.\r\n     * @param subMesh The submesh to bind for.\r\n     */\r\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\r\n        const scene = this.getScene();\r\n\r\n        const defines = <BackgroundMaterialDefines>subMesh.materialDefines;\r\n        if (!defines) {\r\n            return;\r\n        }\r\n\r\n        const effect = subMesh.effect;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n        this._activeEffect = effect;\r\n\r\n        // Matrices\r\n        this.bindOnlyWorldMatrix(world);\r\n\r\n        // Bones\r\n        BindBonesParameters(mesh, this._activeEffect);\r\n\r\n        const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);\r\n        const needToAlwaysBindUniformBuffers = scene.getEngine()._features.needToAlwaysBindUniformBuffers;\r\n        if (mustRebind) {\r\n            this._uniformBuffer.bindToEffect(effect, \"Material\");\r\n\r\n            this.bindViewProjection(effect);\r\n\r\n            const reflectionTexture = this._reflectionTexture;\r\n            if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync || subMesh._drawWrapper._forceRebindOnNextCall) {\r\n                // Texture uniforms\r\n                if (scene.texturesEnabled) {\r\n                    if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                        this._uniformBuffer.updateFloat2(\"vDiffuseInfos\", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);\r\n                        BindTextureMatrix(this._diffuseTexture, this._uniformBuffer, \"diffuse\");\r\n                    }\r\n\r\n                    BindIBLParameters(scene, defines, this._uniformBuffer, Color3.White(), reflectionTexture, false, true, false, false, false, false, this._reflectionBlur);\r\n                }\r\n\r\n                if (this.shadowLevel > 0) {\r\n                    this._uniformBuffer.updateFloat(\"shadowLevel\", this.shadowLevel);\r\n                }\r\n                this._uniformBuffer.updateFloat(\"alpha\", this.alpha);\r\n\r\n                // Point size\r\n                if (this.pointsCloud) {\r\n                    this._uniformBuffer.updateFloat(\"pointSize\", this.pointSize);\r\n                }\r\n\r\n                if (defines.USEHIGHLIGHTANDSHADOWCOLORS) {\r\n                    this._uniformBuffer.updateColor4(\"vPrimaryColor\", this._primaryHighlightColor, 1.0);\r\n                    this._uniformBuffer.updateColor4(\"vPrimaryColorShadow\", this._primaryShadowColor, 1.0);\r\n                } else {\r\n                    this._uniformBuffer.updateColor4(\"vPrimaryColor\", this._primaryColor, 1.0);\r\n                }\r\n            }\r\n\r\n            this._uniformBuffer.updateFloat(\"fFovMultiplier\", this._fovMultiplier);\r\n\r\n            // Fresnel\r\n            if (defines.REFLECTIONFRESNEL) {\r\n                this._uniformBuffer.updateFloat4(\r\n                    \"vReflectionControl\",\r\n                    this._reflectionControls.x,\r\n                    this._reflectionControls.y,\r\n                    this._reflectionControls.z,\r\n                    this._reflectionControls.w\r\n                );\r\n            }\r\n            if ((defines.REFLECTIONFRESNEL && defines.REFLECTIONFALLOFF) || defines.OPACITYFRESNEL) {\r\n                const center = TmpVectors.Vector3[0].copyFrom(this.sceneCenter).subtractInPlace(scene.floatingOriginOffset);\r\n                this._uniformBuffer.updateFloat3(\"vBackgroundCenter\", center.x, center.y, center.z);\r\n            }\r\n\r\n            // Textures\r\n            if (scene.texturesEnabled) {\r\n                if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) {\r\n                    this._uniformBuffer.setTexture(\"diffuseSampler\", this._diffuseTexture);\r\n                }\r\n\r\n                if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n                    BindIBLSamplers(scene, defines, this._uniformBuffer, reflectionTexture);\r\n                }\r\n\r\n                if (defines.PROJECTED_GROUND) {\r\n                    this._uniformBuffer.updateFloat2(\"projectedGroundInfos\", this.projectedGroundRadius, this.projectedGroundHeight);\r\n                }\r\n            }\r\n\r\n            // Clip plane\r\n            BindClipPlane(this._activeEffect, this, scene);\r\n\r\n            scene.bindEyePosition(effect);\r\n        } else if (needToAlwaysBindUniformBuffers) {\r\n            this._uniformBuffer.bindToEffect(effect, \"Material\");\r\n            this._needToBindSceneUbo = true;\r\n        }\r\n\r\n        if ((mustRebind || !this.isFrozen || needToAlwaysBindUniformBuffers) && scene.lightsEnabled) {\r\n            BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);\r\n        }\r\n\r\n        if (mustRebind || !this.isFrozen) {\r\n            // View\r\n            this.bindView(effect);\r\n\r\n            // Fog\r\n            BindFogParameters(scene, mesh, this._activeEffect, true);\r\n\r\n            // Log. depth\r\n            if (this._useLogarithmicDepth) {\r\n                BindLogDepth(defines, effect, scene);\r\n            }\r\n\r\n            // image processing\r\n            if (this._imageProcessingConfiguration) {\r\n                this._imageProcessingConfiguration.bind(this._activeEffect);\r\n            }\r\n        }\r\n\r\n        this._afterBind(mesh, this._activeEffect, subMesh);\r\n\r\n        this._uniformBuffer.update();\r\n    }\r\n\r\n    /**\r\n     * Checks to see if a texture is used in the material.\r\n     * @param texture - Base texture to use.\r\n     * @returns - Boolean specifying if a texture is used in the material.\r\n     */\r\n    public override hasTexture(texture: BaseTexture): boolean {\r\n        if (super.hasTexture(texture)) {\r\n            return true;\r\n        }\r\n\r\n        if (this._reflectionTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        if (this._diffuseTexture === texture) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Dispose the material.\r\n     * @param forceDisposeEffect Force disposal of the associated effect.\r\n     * @param forceDisposeTextures Force disposal of the associated textures.\r\n     */\r\n    public override dispose(forceDisposeEffect: boolean = false, forceDisposeTextures: boolean = false): void {\r\n        if (forceDisposeTextures) {\r\n            if (this.diffuseTexture) {\r\n                this.diffuseTexture.dispose();\r\n            }\r\n            if (this.reflectionTexture) {\r\n                this.reflectionTexture.dispose();\r\n            }\r\n        }\r\n\r\n        this._renderTargets.dispose();\r\n\r\n        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {\r\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\r\n        }\r\n\r\n        super.dispose(forceDisposeEffect);\r\n    }\r\n\r\n    /**\r\n     * Clones the material.\r\n     * @param name The cloned name.\r\n     * @returns The cloned material.\r\n     */\r\n    public override clone(name: string): BackgroundMaterial {\r\n        return SerializationHelper.Clone(() => new BackgroundMaterial(name, this.getScene()), this);\r\n    }\r\n\r\n    /**\r\n     * Serializes the current material to its JSON representation.\r\n     * @returns The JSON representation.\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.customType = \"BABYLON.BackgroundMaterial\";\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the material\r\n     * @returns \"BackgroundMaterial\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"BackgroundMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Parse a JSON input to create back a background material.\r\n     * @param source The JSON data to parse\r\n     * @param scene The scene to create the parsed material in\r\n     * @param rootUrl The root url of the assets the material depends upon\r\n     * @returns the instantiated BackgroundMaterial.\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): BackgroundMaterial {\r\n        return SerializationHelper.Parse(() => new BackgroundMaterial(source.name, scene), source, scene, rootUrl);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for backgroundMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBackgroundMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // BackgroundMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\r\n    RegisterImageProcessingConfiguration();\r\n\r\n    RegisterClass(\"BABYLON.BackgroundMaterial\", BackgroundMaterial);\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { ArcRotateCamera } from \"../Cameras/arcRotateCamera.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { MirrorTexture } from \"../Materials/Textures/mirrorTexture.pure\";\r\nimport { CubeTexture, CubeTextureCreateFromPrefilteredData } from \"../Materials/Textures/cubeTexture.pure\";\r\nimport { BackgroundMaterial } from \"../Materials/Background/backgroundMaterial.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { CreatePlane } from \"../Meshes/Builders/planeBuilder.pure\";\r\nimport { CreateBox } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { Plane } from \"../Maths/math.plane\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\n\r\n/**\r\n * Represents the different options available during the creation of\r\n * a Environment helper.\r\n *\r\n * This can control the default ground, skybox and image processing setup of your scene.\r\n */\r\nexport interface IEnvironmentHelperOptions {\r\n    /**\r\n     * Specifies whether or not to create a ground.\r\n     * True by default.\r\n     */\r\n    createGround: boolean;\r\n    /**\r\n     * Specifies the ground size.\r\n     * 15 by default.\r\n     */\r\n    groundSize: number;\r\n    /**\r\n     * The texture used on the ground for the main color.\r\n     * Comes from the BabylonJS CDN by default.\r\n     *\r\n     * Remarks: Can be either a texture or a url.\r\n     */\r\n    groundTexture: string | BaseTexture;\r\n    /**\r\n     * The color mixed in the ground texture by default.\r\n     * BabylonJS clearColor by default.\r\n     */\r\n    groundColor: Color3;\r\n    /**\r\n     * Specifies the ground opacity.\r\n     * 1 by default.\r\n     */\r\n    groundOpacity: number;\r\n    /**\r\n     * Enables the ground to receive shadows.\r\n     * True by default.\r\n     */\r\n    enableGroundShadow: boolean;\r\n    /**\r\n     * Helps preventing the shadow to be fully black on the ground.\r\n     * 0.5 by default.\r\n     */\r\n    groundShadowLevel: number;\r\n    /**\r\n     * Creates a mirror texture attach to the ground.\r\n     * false by default.\r\n     */\r\n    enableGroundMirror: boolean;\r\n    /**\r\n     * Specifies the ground mirror size ratio.\r\n     * 0.3 by default as the default kernel is 64.\r\n     */\r\n    groundMirrorSizeRatio: number;\r\n    /**\r\n     * Specifies the ground mirror blur kernel size.\r\n     * 64 by default.\r\n     */\r\n    groundMirrorBlurKernel: number;\r\n    /**\r\n     * Specifies the ground mirror visibility amount.\r\n     * 1 by default\r\n     */\r\n    groundMirrorAmount: number;\r\n    /**\r\n     * Specifies the ground mirror reflectance weight.\r\n     * This uses the standard weight of the background material to setup the fresnel effect\r\n     * of the mirror.\r\n     * 1 by default.\r\n     */\r\n    groundMirrorFresnelWeight: number;\r\n    /**\r\n     * Specifies the ground mirror Falloff distance.\r\n     * This can helps reducing the size of the reflection.\r\n     * 0 by Default.\r\n     */\r\n    groundMirrorFallOffDistance: number;\r\n    /**\r\n     * Specifies the ground mirror texture type.\r\n     * Unsigned Int by Default.\r\n     */\r\n    groundMirrorTextureType: number;\r\n    /**\r\n     * Specifies a bias applied to the ground vertical position to prevent z-fighting with\r\n     * the shown objects.\r\n     */\r\n    groundYBias: number;\r\n\r\n    /**\r\n     * Specifies whether or not to create a skybox.\r\n     * True by default.\r\n     */\r\n    createSkybox: boolean;\r\n    /**\r\n     * Specifies the skybox size.\r\n     * 20 by default.\r\n     */\r\n    skyboxSize: number;\r\n    /**\r\n     * The texture used on the skybox for the main color.\r\n     * Comes from the BabylonJS CDN by default.\r\n     *\r\n     * Remarks: Can be either a texture or a url.\r\n     */\r\n    skyboxTexture: string | BaseTexture;\r\n    /**\r\n     * The color mixed in the skybox texture by default.\r\n     * BabylonJS clearColor by default.\r\n     */\r\n    skyboxColor: Color3;\r\n\r\n    /**\r\n     * The background rotation around the Y axis of the scene.\r\n     * This helps aligning the key lights of your scene with the background.\r\n     * 0 by default.\r\n     */\r\n    backgroundYRotation: number;\r\n\r\n    /**\r\n     * Compute automatically the size of the elements to best fit with the scene.\r\n     */\r\n    sizeAuto: boolean;\r\n\r\n    /**\r\n     * Default position of the rootMesh if autoSize is not true.\r\n     */\r\n    rootPosition: Vector3;\r\n\r\n    /**\r\n     * Sets up the image processing in the scene.\r\n     * true by default.\r\n     */\r\n    setupImageProcessing: boolean;\r\n\r\n    /**\r\n     * The texture used as your environment texture in the scene.\r\n     * Comes from the BabylonJS CDN by default and in use if setupImageProcessing is true.\r\n     *\r\n     * Remarks: Can be either a texture or a url.\r\n     */\r\n    environmentTexture: string | BaseTexture;\r\n\r\n    /**\r\n     * The value of the exposure to apply to the scene.\r\n     * 0.6 by default if setupImageProcessing is true.\r\n     */\r\n    cameraExposure: number;\r\n\r\n    /**\r\n     * The value of the contrast to apply to the scene.\r\n     * 1.6 by default if setupImageProcessing is true.\r\n     */\r\n    cameraContrast: number;\r\n\r\n    /**\r\n     * Specifies whether or not tonemapping should be enabled in the scene.\r\n     * true by default if setupImageProcessing is true.\r\n     */\r\n    toneMappingEnabled: boolean;\r\n}\r\n\r\ninterface ISceneSize {\r\n    groundSize: number;\r\n    skyboxSize: number;\r\n    rootPosition: Vector3;\r\n}\r\n\r\n/**\r\n * The EnvironmentHelper class can be used to add a fully featured non-expensive background to your scene.\r\n * It includes by default a skybox and a ground relying on the BackgroundMaterial.\r\n * It also helps with the default setup of your ImageProcessingConfiguration.\r\n */\r\nexport class EnvironmentHelper {\r\n    /**\r\n     * Default ground texture URL.\r\n     */\r\n    private static _GroundTextureCDNUrl = \"https://assets.babylonjs.com/core/environments/backgroundGround.png\";\r\n\r\n    /**\r\n     * Default skybox texture URL.\r\n     */\r\n    private static _SkyboxTextureCDNUrl = \"https://assets.babylonjs.com/core/environments/backgroundSkybox.dds\";\r\n\r\n    /**\r\n     * Default environment texture URL.\r\n     */\r\n    private static _EnvironmentTextureCDNUrl = \"https://assets.babylonjs.com/core/environments/environmentSpecular.env\";\r\n\r\n    /**\r\n     * Creates the default options for the helper.\r\n     * @param scene The scene the environment helper belongs to.\r\n     * @returns default options for the helper.\r\n     */\r\n    private static _GetDefaultOptions(scene: Scene): IEnvironmentHelperOptions {\r\n        return {\r\n            createGround: true,\r\n            groundSize: 15,\r\n            groundTexture: Tools.GetAssetUrl(this._GroundTextureCDNUrl),\r\n            groundColor: new Color3(0.2, 0.2, 0.3).toLinearSpace(scene.getEngine().useExactSrgbConversions).scale(3),\r\n            groundOpacity: 0.9,\r\n            enableGroundShadow: true,\r\n            groundShadowLevel: 0.5,\r\n\r\n            enableGroundMirror: false,\r\n            groundMirrorSizeRatio: 0.3,\r\n            groundMirrorBlurKernel: 64,\r\n            groundMirrorAmount: 1,\r\n            groundMirrorFresnelWeight: 1,\r\n            groundMirrorFallOffDistance: 0,\r\n            groundMirrorTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n\r\n            groundYBias: 0.00001,\r\n\r\n            createSkybox: true,\r\n            skyboxSize: 20,\r\n            skyboxTexture: Tools.GetAssetUrl(this._SkyboxTextureCDNUrl),\r\n            skyboxColor: new Color3(0.2, 0.2, 0.3).toLinearSpace(scene.getEngine().useExactSrgbConversions).scale(3),\r\n\r\n            backgroundYRotation: 0,\r\n            sizeAuto: true,\r\n            rootPosition: Vector3.Zero(),\r\n\r\n            setupImageProcessing: true,\r\n            environmentTexture: Tools.GetAssetUrl(this._EnvironmentTextureCDNUrl),\r\n            cameraExposure: 0.8,\r\n            cameraContrast: 1.2,\r\n            toneMappingEnabled: true,\r\n        };\r\n    }\r\n\r\n    private _rootMesh: Mesh;\r\n    /**\r\n     * Gets the root mesh created by the helper.\r\n     */\r\n    public get rootMesh(): Mesh {\r\n        return this._rootMesh;\r\n    }\r\n\r\n    private _skybox: Nullable<Mesh>;\r\n    /**\r\n     * Gets the skybox created by the helper.\r\n     */\r\n    public get skybox(): Nullable<Mesh> {\r\n        return this._skybox;\r\n    }\r\n\r\n    private _skyboxTexture: Nullable<BaseTexture>;\r\n    /**\r\n     * Gets the skybox texture created by the helper.\r\n     */\r\n    public get skyboxTexture(): Nullable<BaseTexture> {\r\n        return this._skyboxTexture;\r\n    }\r\n\r\n    private _skyboxMaterial: Nullable<BackgroundMaterial>;\r\n    /**\r\n     * Gets the skybox material created by the helper.\r\n     */\r\n    public get skyboxMaterial(): Nullable<BackgroundMaterial> {\r\n        return this._skyboxMaterial;\r\n    }\r\n\r\n    private _ground: Nullable<Mesh>;\r\n    /**\r\n     * Gets the ground mesh created by the helper.\r\n     */\r\n    public get ground(): Nullable<Mesh> {\r\n        return this._ground;\r\n    }\r\n\r\n    private _groundTexture: Nullable<BaseTexture>;\r\n    /**\r\n     * Gets the ground texture created by the helper.\r\n     */\r\n    public get groundTexture(): Nullable<BaseTexture> {\r\n        return this._groundTexture;\r\n    }\r\n\r\n    private _groundMirror: Nullable<MirrorTexture>;\r\n    /**\r\n     * Gets the ground mirror created by the helper.\r\n     */\r\n    public get groundMirror(): Nullable<MirrorTexture> {\r\n        return this._groundMirror;\r\n    }\r\n\r\n    /**\r\n     * Gets the ground mirror render list to helps pushing the meshes\r\n     * you wish in the ground reflection.\r\n     */\r\n    public get groundMirrorRenderList(): Nullable<AbstractMesh[]> {\r\n        if (this._groundMirror) {\r\n            return this._groundMirror.renderList;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private _groundMaterial: Nullable<BackgroundMaterial>;\r\n    /**\r\n     * Gets the ground material created by the helper.\r\n     */\r\n    public get groundMaterial(): Nullable<BackgroundMaterial> {\r\n        return this._groundMaterial;\r\n    }\r\n\r\n    /**\r\n     * Stores the creation options.\r\n     */\r\n    private readonly _scene: Scene;\r\n    private _options: IEnvironmentHelperOptions;\r\n\r\n    /**\r\n     * This observable will be notified with any error during the creation of the environment,\r\n     * mainly texture creation errors.\r\n     */\r\n    public onErrorObservable: Observable<{ message?: string; exception?: any }>;\r\n\r\n    /**\r\n     * constructor\r\n     * @param options Defines the options we want to customize the helper\r\n     * @param scene The scene to add the material to\r\n     */\r\n    constructor(options: Partial<IEnvironmentHelperOptions>, scene: Scene) {\r\n        this._options = {\r\n            ...EnvironmentHelper._GetDefaultOptions(scene),\r\n            ...options,\r\n        };\r\n        this._scene = scene;\r\n        this.onErrorObservable = new Observable();\r\n\r\n        this._setupBackground();\r\n        this._setupImageProcessing();\r\n    }\r\n\r\n    /**\r\n     * Updates the environment according to the new options\r\n     * @param options options to configure the helper (IEnvironmentHelperOptions)\r\n     */\r\n    public updateOptions(options: Partial<IEnvironmentHelperOptions>) {\r\n        const newOptions = {\r\n            ...this._options,\r\n            ...options,\r\n        };\r\n\r\n        if (this._ground && !newOptions.createGround) {\r\n            this._ground.dispose();\r\n            this._ground = null;\r\n        }\r\n\r\n        if (this._groundMaterial && !newOptions.createGround) {\r\n            this._groundMaterial.dispose();\r\n            this._groundMaterial = null;\r\n        }\r\n\r\n        if (this._groundTexture) {\r\n            if (this._options.groundTexture != newOptions.groundTexture) {\r\n                this._groundTexture.dispose();\r\n                this._groundTexture = null;\r\n            }\r\n        }\r\n\r\n        if (this._skybox && !newOptions.createSkybox) {\r\n            this._skybox.dispose();\r\n            this._skybox = null;\r\n        }\r\n\r\n        if (this._skyboxMaterial && !newOptions.createSkybox) {\r\n            this._skyboxMaterial.dispose();\r\n            this._skyboxMaterial = null;\r\n        }\r\n\r\n        if (this._skyboxTexture) {\r\n            if (this._options.skyboxTexture != newOptions.skyboxTexture) {\r\n                this._skyboxTexture.dispose();\r\n                this._skyboxTexture = null;\r\n            }\r\n        }\r\n\r\n        if (this._groundMirror && !newOptions.enableGroundMirror) {\r\n            const index = this._scene.customRenderTargets.indexOf(this._groundMirror);\r\n            if (index !== -1) {\r\n                this._scene.customRenderTargets.splice(index, 1);\r\n            }\r\n            this._groundMirror.dispose();\r\n            this._groundMirror = null;\r\n        }\r\n\r\n        if (this._scene.environmentTexture) {\r\n            if (this._options.environmentTexture != newOptions.environmentTexture) {\r\n                this._scene.environmentTexture.dispose();\r\n            }\r\n        }\r\n\r\n        this._options = newOptions;\r\n\r\n        this._setupBackground();\r\n        this._setupImageProcessing();\r\n    }\r\n\r\n    /**\r\n     * Sets the primary color of all the available elements.\r\n     * @param color the main color to affect to the ground and the background\r\n     */\r\n    public setMainColor(color: Color3): void {\r\n        if (this.groundMaterial) {\r\n            this.groundMaterial.primaryColor = color;\r\n        }\r\n\r\n        if (this.skyboxMaterial) {\r\n            this.skyboxMaterial.primaryColor = color;\r\n        }\r\n\r\n        if (this.groundMirror) {\r\n            this.groundMirror.clearColor = new Color4(color.r, color.g, color.b, 1.0);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Setup the image processing according to the specified options.\r\n     */\r\n    private _setupImageProcessing(): void {\r\n        if (this._options.setupImageProcessing) {\r\n            this._scene.imageProcessingConfiguration.contrast = this._options.cameraContrast;\r\n            this._scene.imageProcessingConfiguration.exposure = this._options.cameraExposure;\r\n            this._scene.imageProcessingConfiguration.toneMappingEnabled = this._options.toneMappingEnabled;\r\n            this._setupEnvironmentTexture();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Setup the environment texture according to the specified options.\r\n     */\r\n    private _setupEnvironmentTexture(): void {\r\n        if (this._scene.environmentTexture) {\r\n            return;\r\n        }\r\n\r\n        if (this._options.environmentTexture instanceof BaseTexture) {\r\n            this._scene.environmentTexture = this._options.environmentTexture;\r\n            return;\r\n        }\r\n\r\n        const environmentTexture = CubeTextureCreateFromPrefilteredData(this._options.environmentTexture, this._scene);\r\n        this._scene.environmentTexture = environmentTexture;\r\n    }\r\n\r\n    /**\r\n     * Setup the background according to the specified options.\r\n     */\r\n    private _setupBackground(): void {\r\n        if (!this._rootMesh) {\r\n            this._rootMesh = new Mesh(\"BackgroundHelper\", this._scene);\r\n        }\r\n        this._rootMesh.rotation.y = this._options.backgroundYRotation;\r\n\r\n        const sceneSize = this._getSceneSize();\r\n        if (this._options.createGround) {\r\n            this._setupGround(sceneSize);\r\n            this._setupGroundMaterial();\r\n            this._setupGroundDiffuseTexture();\r\n\r\n            if (this._options.enableGroundMirror) {\r\n                this._setupGroundMirrorTexture(sceneSize);\r\n            }\r\n            this._setupMirrorInGroundMaterial();\r\n        }\r\n\r\n        if (this._options.createSkybox) {\r\n            this._setupSkybox(sceneSize);\r\n            this._setupSkyboxMaterial();\r\n            this._setupSkyboxReflectionTexture();\r\n        }\r\n\r\n        this._rootMesh.position.x = sceneSize.rootPosition.x;\r\n        this._rootMesh.position.z = sceneSize.rootPosition.z;\r\n        this._rootMesh.position.y = sceneSize.rootPosition.y;\r\n    }\r\n\r\n    /**\r\n     * Get the scene sizes according to the setup.\r\n     * @returns the different ground and skybox sizes.\r\n     */\r\n    private _getSceneSize(): ISceneSize {\r\n        let groundSize = this._options.groundSize;\r\n        let skyboxSize = this._options.skyboxSize;\r\n        let rootPosition = this._options.rootPosition;\r\n        if (!this._scene.meshes || this._scene.meshes.length === 1) {\r\n            // 1 only means the root of the helper.\r\n            return { groundSize, skyboxSize, rootPosition };\r\n        }\r\n\r\n        const sceneExtends = this._scene.getWorldExtends((mesh) => {\r\n            return mesh !== this._ground && mesh !== this._rootMesh && mesh !== this._skybox;\r\n        });\r\n        const sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);\r\n\r\n        if (this._options.sizeAuto) {\r\n            if (this._scene.activeCamera instanceof ArcRotateCamera && this._scene.activeCamera.upperRadiusLimit) {\r\n                groundSize = this._scene.activeCamera.upperRadiusLimit * 2;\r\n                skyboxSize = groundSize;\r\n            }\r\n\r\n            const sceneDiagonalLength = sceneDiagonal.length();\r\n            if (sceneDiagonalLength > groundSize) {\r\n                groundSize = sceneDiagonalLength * 2;\r\n                skyboxSize = groundSize;\r\n            }\r\n\r\n            // 10 % bigger.\r\n            groundSize *= 1.1;\r\n            skyboxSize *= 1.5;\r\n            rootPosition = sceneExtends.min.add(sceneDiagonal.scale(0.5));\r\n            rootPosition.y = sceneExtends.min.y - this._options.groundYBias;\r\n        }\r\n\r\n        return { groundSize, skyboxSize, rootPosition };\r\n    }\r\n\r\n    /**\r\n     * Setup the ground according to the specified options.\r\n     * @param sceneSize\r\n     */\r\n    private _setupGround(sceneSize: ISceneSize): void {\r\n        if (!this._ground || this._ground.isDisposed()) {\r\n            this._ground = CreatePlane(\"BackgroundPlane\", { size: sceneSize.groundSize }, this._scene);\r\n            this._ground.rotation.x = Math.PI / 2; // Face up by default.\r\n            this._ground.isPickable = false;\r\n            this._ground.parent = this._rootMesh;\r\n            this._ground.onDisposeObservable.add(() => {\r\n                this._ground = null;\r\n            });\r\n        }\r\n\r\n        this._ground.receiveShadows = this._options.enableGroundShadow;\r\n    }\r\n\r\n    /**\r\n     * Setup the ground material according to the specified options.\r\n     */\r\n    private _setupGroundMaterial(): void {\r\n        if (!this._groundMaterial) {\r\n            this._groundMaterial = new BackgroundMaterial(\"BackgroundPlaneMaterial\", this._scene);\r\n        }\r\n        this._groundMaterial.alpha = this._options.groundOpacity;\r\n        this._groundMaterial.alphaMode = Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n        this._groundMaterial.shadowLevel = this._options.groundShadowLevel;\r\n        this._groundMaterial.primaryColor = this._options.groundColor;\r\n        this._groundMaterial.useRGBColor = false;\r\n        this._groundMaterial.enableNoise = true;\r\n\r\n        if (this._ground) {\r\n            this._ground.material = this._groundMaterial;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Setup the ground diffuse texture according to the specified options.\r\n     */\r\n    private _setupGroundDiffuseTexture(): void {\r\n        if (!this._groundMaterial) {\r\n            return;\r\n        }\r\n\r\n        if (this._groundTexture) {\r\n            return;\r\n        }\r\n\r\n        if (this._options.groundTexture instanceof BaseTexture) {\r\n            this._groundMaterial.diffuseTexture = this._options.groundTexture;\r\n            return;\r\n        }\r\n\r\n        this._groundTexture = new Texture(this._options.groundTexture, this._scene, undefined, undefined, undefined, undefined, this._errorHandler);\r\n        this._groundTexture.gammaSpace = false;\r\n        this._groundTexture.hasAlpha = true;\r\n        this._groundMaterial.diffuseTexture = this._groundTexture;\r\n    }\r\n\r\n    /**\r\n     * Setup the ground mirror texture according to the specified options.\r\n     * @param sceneSize\r\n     */\r\n    private _setupGroundMirrorTexture(sceneSize: ISceneSize): void {\r\n        const wrapping = Texture.CLAMP_ADDRESSMODE;\r\n        if (!this._groundMirror) {\r\n            this._groundMirror = new MirrorTexture(\r\n                \"BackgroundPlaneMirrorTexture\",\r\n                { ratio: this._options.groundMirrorSizeRatio },\r\n                this._scene,\r\n                false,\r\n                this._options.groundMirrorTextureType,\r\n                Texture.BILINEAR_SAMPLINGMODE,\r\n                true\r\n            );\r\n            this._groundMirror.mirrorPlane = new Plane(0, -1, 0, sceneSize.rootPosition.y);\r\n            this._groundMirror.anisotropicFilteringLevel = 1;\r\n            this._groundMirror.wrapU = wrapping;\r\n            this._groundMirror.wrapV = wrapping;\r\n\r\n            if (this._groundMirror.renderList) {\r\n                for (let i = 0; i < this._scene.meshes.length; i++) {\r\n                    const mesh = this._scene.meshes[i];\r\n                    if (mesh !== this._ground && mesh !== this._skybox && mesh !== this._rootMesh) {\r\n                        this._groundMirror.renderList.push(mesh);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this._scene.frameGraph) {\r\n                this._scene.customRenderTargets.push(this._groundMirror);\r\n            }\r\n        }\r\n\r\n        const gammaGround = this._options.groundColor.toGammaSpace(this._scene.getEngine().useExactSrgbConversions);\r\n        this._groundMirror.clearColor = new Color4(gammaGround.r, gammaGround.g, gammaGround.b, 1);\r\n        this._groundMirror.adaptiveBlurKernel = this._options.groundMirrorBlurKernel;\r\n    }\r\n\r\n    /**\r\n     * Setup the ground to receive the mirror texture.\r\n     */\r\n    private _setupMirrorInGroundMaterial(): void {\r\n        if (this._groundMaterial) {\r\n            this._groundMaterial.reflectionTexture = this._groundMirror;\r\n            this._groundMaterial.reflectionFresnel = true;\r\n            this._groundMaterial.reflectionAmount = this._options.groundMirrorAmount;\r\n            this._groundMaterial.reflectionStandardFresnelWeight = this._options.groundMirrorFresnelWeight;\r\n            this._groundMaterial.reflectionFalloffDistance = this._options.groundMirrorFallOffDistance;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Setup the skybox according to the specified options.\r\n     * @param sceneSize\r\n     */\r\n    private _setupSkybox(sceneSize: ISceneSize): void {\r\n        if (!this._skybox || this._skybox.isDisposed()) {\r\n            this._skybox = CreateBox(\"BackgroundSkybox\", { size: sceneSize.skyboxSize, sideOrientation: Mesh.BACKSIDE }, this._scene);\r\n            this._skybox.isPickable = false;\r\n            this._skybox.onDisposeObservable.add(() => {\r\n                this._skybox = null;\r\n            });\r\n        }\r\n        this._skybox.parent = this._rootMesh;\r\n    }\r\n\r\n    /**\r\n     * Setup the skybox material according to the specified options.\r\n     */\r\n    private _setupSkyboxMaterial(): void {\r\n        if (!this._skybox) {\r\n            return;\r\n        }\r\n\r\n        if (!this._skyboxMaterial) {\r\n            this._skyboxMaterial = new BackgroundMaterial(\"BackgroundSkyboxMaterial\", this._scene);\r\n        }\r\n        this._skyboxMaterial.useRGBColor = false;\r\n        this._skyboxMaterial.primaryColor = this._options.skyboxColor;\r\n        this._skyboxMaterial.enableNoise = true;\r\n\r\n        this._skybox.material = this._skyboxMaterial;\r\n    }\r\n\r\n    /**\r\n     * Setup the skybox reflection texture according to the specified options.\r\n     */\r\n    private _setupSkyboxReflectionTexture(): void {\r\n        if (!this._skyboxMaterial) {\r\n            return;\r\n        }\r\n\r\n        if (this._skyboxTexture) {\r\n            return;\r\n        }\r\n\r\n        if (this._options.skyboxTexture instanceof BaseTexture) {\r\n            this._skyboxMaterial.reflectionTexture = this._options.skyboxTexture;\r\n            return;\r\n        }\r\n\r\n        this._skyboxTexture = new CubeTexture(this._options.skyboxTexture, this._scene, undefined, undefined, undefined, undefined, this._errorHandler);\r\n        this._skyboxTexture.coordinatesMode = Texture.SKYBOX_MODE;\r\n        this._skyboxTexture.gammaSpace = false;\r\n        this._skyboxMaterial.reflectionTexture = this._skyboxTexture;\r\n    }\r\n\r\n    private _errorHandler = (message?: string, exception?: any) => {\r\n        this.onErrorObservable.notifyObservers({ message: message, exception: exception });\r\n    };\r\n\r\n    /**\r\n     * Dispose all the elements created by the Helper.\r\n     */\r\n    public dispose(): void {\r\n        if (this._groundMaterial) {\r\n            this._groundMaterial.dispose(true, true);\r\n        }\r\n        if (this._skyboxMaterial) {\r\n            this._skyboxMaterial.dispose(true, true);\r\n        }\r\n        this._rootMesh.dispose(false);\r\n    }\r\n}\r\n","import { type Scene } from \"../scene\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { BackgroundMaterial } from \"../Materials/Background/backgroundMaterial.pure\";\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Axis } from \"../Maths/math\";\r\n\r\nimport { type Camera } from \"../Cameras/camera\";\r\n\r\n/**\r\n * Display a 360/180 degree texture on an approximately spherical surface, useful for VR applications or skyboxes.\r\n * As a subclass of TransformNode, this allow parenting to the camera or multiple textures with different locations in the scene.\r\n * This class achieves its effect with a Texture and a correctly configured BackgroundMaterial on an inverted sphere.\r\n * Potential additions to this helper include zoom and and non-infinite distance rendering effects.\r\n */\r\nexport abstract class TextureDome<T extends Texture> extends TransformNode {\r\n    /**\r\n     * Define the source as a Monoscopic panoramic 360/180.\r\n     */\r\n    public static readonly MODE_MONOSCOPIC = 0;\r\n    /**\r\n     * Define the source as a Stereoscopic TopBottom/OverUnder panoramic 360/180.\r\n     */\r\n    public static readonly MODE_TOPBOTTOM = 1;\r\n    /**\r\n     * Define the source as a Stereoscopic Side by Side panoramic 360/180.\r\n     */\r\n    public static readonly MODE_SIDEBYSIDE = 2;\r\n\r\n    private _halfDome: boolean = false;\r\n    private _crossEye: boolean = false;\r\n\r\n    protected _useDirectMapping = false;\r\n\r\n    /**\r\n     * The texture being displayed on the sphere\r\n     */\r\n    protected _texture: T;\r\n\r\n    /**\r\n     * Gets the texture being displayed on the sphere\r\n     */\r\n    public get texture(): T {\r\n        return this._texture;\r\n    }\r\n\r\n    /**\r\n     * Sets the texture being displayed on the sphere\r\n     */\r\n    public set texture(newTexture: T) {\r\n        if (this._texture === newTexture) {\r\n            return;\r\n        }\r\n        this._texture = newTexture;\r\n        if (this._useDirectMapping) {\r\n            this._texture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n            this._texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n            this._material.diffuseTexture = this._texture;\r\n        } else {\r\n            this._texture.coordinatesMode = Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE; // matches orientation\r\n            this._texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n            this._material.reflectionTexture = this._texture;\r\n        }\r\n        this._changeTextureMode(this._textureMode);\r\n    }\r\n\r\n    /**\r\n     * The skybox material\r\n     */\r\n    protected _material: BackgroundMaterial;\r\n\r\n    /**\r\n     * The surface used for the dome\r\n     */\r\n    protected _mesh: Mesh;\r\n    /**\r\n     * Gets the mesh used for the dome.\r\n     */\r\n    public get mesh(): Mesh {\r\n        return this._mesh;\r\n    }\r\n\r\n    /**\r\n     * A mesh that will be used to mask the back of the dome in case it is a 180 degree movie.\r\n     */\r\n    private _halfDomeMask: Mesh;\r\n\r\n    /**\r\n     * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values \"zoom in\" and higher values \"zoom out\".\r\n     * Also see the options.resolution property.\r\n     */\r\n    public get fovMultiplier(): number {\r\n        return this._material.fovMultiplier;\r\n    }\r\n    public set fovMultiplier(value: number) {\r\n        this._material.fovMultiplier = value;\r\n    }\r\n\r\n    protected _textureMode = TextureDome.MODE_MONOSCOPIC;\r\n    /**\r\n     * Gets or set the current texture mode for the texture. It can be:\r\n     * * TextureDome.MODE_MONOSCOPIC : Define the texture source as a Monoscopic panoramic 360.\r\n     * * TextureDome.MODE_TOPBOTTOM  : Define the texture source as a Stereoscopic TopBottom/OverUnder panoramic 360.\r\n     * * TextureDome.MODE_SIDEBYSIDE : Define the texture source as a Stereoscopic Side by Side panoramic 360.\r\n     */\r\n    public get textureMode(): number {\r\n        return this._textureMode;\r\n    }\r\n    /**\r\n     * Sets the current texture mode for the texture. It can be:\r\n     * * TextureDome.MODE_MONOSCOPIC : Define the texture source as a Monoscopic panoramic 360.\r\n     * * TextureDome.MODE_TOPBOTTOM  : Define the texture source as a Stereoscopic TopBottom/OverUnder panoramic 360.\r\n     * * TextureDome.MODE_SIDEBYSIDE : Define the texture source as a Stereoscopic Side by Side panoramic 360.\r\n     */\r\n    public set textureMode(value: number) {\r\n        if (this._textureMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._changeTextureMode(value);\r\n    }\r\n\r\n    /**\r\n     * Is it a 180 degrees dome (half dome) or 360 texture (full dome)\r\n     */\r\n    public get halfDome(): boolean {\r\n        return this._halfDome;\r\n    }\r\n\r\n    /**\r\n     * Set the halfDome mode. If set, only the front (180 degrees) will be displayed and the back will be blacked out.\r\n     */\r\n    public set halfDome(enabled: boolean) {\r\n        this._halfDome = enabled;\r\n        this._halfDomeMask.setEnabled(enabled);\r\n        this._changeTextureMode(this._textureMode);\r\n    }\r\n\r\n    /**\r\n     * Set the cross-eye mode. If set, images that can be seen when crossing eyes will render correctly\r\n     */\r\n    public set crossEye(enabled: boolean) {\r\n        this._crossEye = enabled;\r\n        this._changeTextureMode(this._textureMode);\r\n    }\r\n\r\n    /**\r\n     * Is it a cross-eye texture?\r\n     */\r\n    public get crossEye(): boolean {\r\n        return this._crossEye;\r\n    }\r\n\r\n    /**\r\n     * The background material of this dome.\r\n     */\r\n    public get material(): BackgroundMaterial {\r\n        return this._material;\r\n    }\r\n\r\n    /**\r\n     * Oberserver used in Stereoscopic VR Mode.\r\n     */\r\n    private _onBeforeCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n    /**\r\n     * Observable raised when an error occurred while loading the texture\r\n     */\r\n    public onLoadErrorObservable = new Observable<string>();\r\n    /**\r\n     * Observable raised when the texture finished loading\r\n     */\r\n    public onLoadObservable = new Observable<void>();\r\n\r\n    /**\r\n     * Create an instance of this class and pass through the parameters to the relevant classes- Texture, StandardMaterial, and Mesh.\r\n     * @param name Element's name, child elements will append suffixes for their own names.\r\n     * @param textureUrlOrElement defines the url(s) or the (video) HTML element to use\r\n     * @param options An object containing optional or exposed sub element properties\r\n     * @param options.resolution\r\n     * @param options.clickToPlay\r\n     * @param options.autoPlay\r\n     * @param options.loop\r\n     * @param options.size\r\n     * @param options.poster\r\n     * @param options.faceForward\r\n     * @param options.useDirectMapping\r\n     * @param options.halfDomeMode\r\n     * @param options.crossEyeMode\r\n     * @param options.generateMipMaps\r\n     * @param options.mesh\r\n     * @param scene\r\n     * @param onError\r\n     */\r\n    constructor(\r\n        name: string,\r\n        textureUrlOrElement: string | string[] | HTMLVideoElement,\r\n        options: {\r\n            resolution?: number;\r\n            clickToPlay?: boolean;\r\n            autoPlay?: boolean;\r\n            loop?: boolean;\r\n            size?: number;\r\n            poster?: string;\r\n            faceForward?: boolean;\r\n            useDirectMapping?: boolean;\r\n            halfDomeMode?: boolean;\r\n            crossEyeMode?: boolean;\r\n            generateMipMaps?: boolean;\r\n            mesh?: Mesh;\r\n        },\r\n        scene: Scene,\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        protected onError: Nullable<(message?: string, exception?: any) => void> = null\r\n    ) {\r\n        super(name, scene);\r\n\r\n        scene = this.getScene();\r\n\r\n        // set defaults and manage values\r\n        name = name || \"textureDome\";\r\n        options.resolution = Math.abs(options.resolution as any) | 0 || 32;\r\n        options.clickToPlay = Boolean(options.clickToPlay);\r\n        options.autoPlay = options.autoPlay === undefined ? true : Boolean(options.autoPlay);\r\n        options.loop = options.loop === undefined ? true : Boolean(options.loop);\r\n        options.size = Math.abs(options.size as any) || (scene.activeCamera ? scene.activeCamera.maxZ * 0.48 : 1000);\r\n\r\n        if (options.useDirectMapping === undefined) {\r\n            this._useDirectMapping = true;\r\n        } else {\r\n            this._useDirectMapping = options.useDirectMapping;\r\n        }\r\n\r\n        if (options.faceForward === undefined) {\r\n            options.faceForward = true;\r\n        }\r\n\r\n        this._setReady(false);\r\n        if (!options.mesh) {\r\n            this._mesh = CreateSphere(name + \"_mesh\", { segments: options.resolution, diameter: options.size, updatable: false, sideOrientation: Mesh.BACKSIDE }, scene);\r\n        } else {\r\n            this._mesh = options.mesh;\r\n        }\r\n        // configure material\r\n        const material = (this._material = new BackgroundMaterial(name + \"_material\", scene));\r\n        material.useEquirectangularFOV = true;\r\n        material.fovMultiplier = 1.0;\r\n        material.opacityFresnel = false;\r\n\r\n        const texture = this._initTexture(textureUrlOrElement, scene, options);\r\n        this.texture = texture;\r\n\r\n        // configure mesh\r\n        this._mesh.material = material;\r\n        this._mesh.parent = this;\r\n\r\n        // create a (disabled until needed) mask to cover unneeded segments of 180 texture.\r\n        this._halfDomeMask = CreateSphere(\"\", { slice: 0.5, diameter: options.size * 0.98, segments: options.resolution * 2, sideOrientation: Mesh.BACKSIDE }, scene);\r\n        this._halfDomeMask.rotate(Axis.X, -Math.PI / 2);\r\n        // set the parent, so it will always be positioned correctly AND will be disposed when the main sphere is disposed\r\n        this._halfDomeMask.parent = this._mesh;\r\n        this._halfDome = !!options.halfDomeMode;\r\n        // enable or disable according to the settings\r\n        this._halfDomeMask.setEnabled(this._halfDome);\r\n        this._crossEye = !!options.crossEyeMode;\r\n\r\n        // create\r\n        this._texture.anisotropicFilteringLevel = 1;\r\n        this._texture.onLoadObservable.addOnce(() => {\r\n            this._setReady(true);\r\n        });\r\n\r\n        // Initial rotation\r\n        if (options.faceForward && scene.activeCamera) {\r\n            const camera = scene.activeCamera;\r\n\r\n            const forward = Vector3.Forward();\r\n            const direction = Vector3.TransformNormal(forward, camera.getViewMatrix());\r\n            direction.normalize();\r\n\r\n            this.rotation.y = Math.acos(Vector3.Dot(forward, direction));\r\n        }\r\n\r\n        this._changeTextureMode(this._textureMode);\r\n    }\r\n\r\n    protected abstract _initTexture(urlsOrElement: string | string[] | HTMLElement, scene: Scene, options: any): T;\r\n\r\n    protected _changeTextureMode(value: number): void {\r\n        this._scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);\r\n        this._textureMode = value;\r\n\r\n        // Default Setup and Reset.\r\n        this._texture.uScale = 1;\r\n        this._texture.vScale = 1;\r\n        this._texture.uOffset = 0;\r\n        this._texture.vOffset = 0;\r\n        this._texture.vAng = 0;\r\n\r\n        switch (value) {\r\n            case TextureDome.MODE_MONOSCOPIC:\r\n                if (this._halfDome) {\r\n                    this._texture.uScale = 2;\r\n                    this._texture.uOffset = -1;\r\n                }\r\n                break;\r\n            case TextureDome.MODE_SIDEBYSIDE: {\r\n                // in half-dome mode the uScale should be double of 360 texture\r\n                // Use 0.99999 to boost perf by not switching program\r\n                this._texture.uScale = this._halfDome ? 0.99999 : 0.5;\r\n                const rightOffset = this._halfDome ? 0.0 : 0.5;\r\n                const leftOffset = this._halfDome ? -0.5 : 0.0;\r\n                this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add((camera) => {\r\n                    let isRightCamera = camera.isRightCamera;\r\n                    if (this._crossEye) {\r\n                        isRightCamera = !isRightCamera;\r\n                    }\r\n                    if (isRightCamera) {\r\n                        this._texture.uOffset = rightOffset;\r\n                    } else {\r\n                        this._texture.uOffset = leftOffset;\r\n                    }\r\n                });\r\n                break;\r\n            }\r\n            case TextureDome.MODE_TOPBOTTOM:\r\n                // in half-dome mode the vScale should be double of 360 texture\r\n                // Use 0.99999 to boost perf by not switching program\r\n                this._texture.vScale = this._halfDome ? 0.99999 : 0.5;\r\n                this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add((camera) => {\r\n                    let isRightCamera = camera.isRightCamera;\r\n                    // allow \"cross-eye\" if left and right were switched in this mode\r\n                    if (this._crossEye) {\r\n                        isRightCamera = !isRightCamera;\r\n                    }\r\n                    this._texture.vOffset = isRightCamera ? 0.5 : 0.0;\r\n                });\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases resources associated with this node.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        this._texture.dispose();\r\n        this._mesh.dispose();\r\n        this._material.dispose();\r\n\r\n        this._scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);\r\n        this.onLoadErrorObservable.clear();\r\n        this.onLoadObservable.clear();\r\n\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n}\r\n","import { type Scene } from \"../scene\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { TextureDome } from \"./textureDome\";\r\n\r\n/**\r\n * Display a 360 degree photo on an approximately spherical surface, useful for VR applications or skyboxes.\r\n * As a subclass of TransformNode, this allow parenting to the camera with different locations in the scene.\r\n * This class achieves its effect with a Texture and a correctly configured BackgroundMaterial on an inverted sphere.\r\n * Potential additions to this helper include zoom and and non-infinite distance rendering effects.\r\n */\r\nexport class PhotoDome extends TextureDome<Texture> {\r\n    /**\r\n     * Define the image as a Monoscopic panoramic 360 image.\r\n     */\r\n    public static override readonly MODE_MONOSCOPIC = TextureDome.MODE_MONOSCOPIC;\r\n    /**\r\n     * Define the image as a Stereoscopic TopBottom/OverUnder panoramic 360 image.\r\n     */\r\n    public static override readonly MODE_TOPBOTTOM = TextureDome.MODE_TOPBOTTOM;\r\n    /**\r\n     * Define the image as a Stereoscopic Side by Side panoramic 360 image.\r\n     */\r\n    public static override readonly MODE_SIDEBYSIDE = TextureDome.MODE_SIDEBYSIDE;\r\n    /**\r\n     * Gets or sets the texture being displayed on the sphere\r\n     */\r\n    public get photoTexture(): Texture {\r\n        return this.texture;\r\n    }\r\n\r\n    /**\r\n     * sets the texture being displayed on the sphere\r\n     */\r\n    public set photoTexture(value: Texture) {\r\n        this.texture = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current video mode for the video. It can be:\r\n     * * TextureDome.MODE_MONOSCOPIC : Define the texture source as a Monoscopic panoramic 360.\r\n     * * TextureDome.MODE_TOPBOTTOM  : Define the texture source as a Stereoscopic TopBottom/OverUnder panoramic 360.\r\n     * * TextureDome.MODE_SIDEBYSIDE : Define the texture source as a Stereoscopic Side by Side panoramic 360.\r\n     */\r\n    public get imageMode(): number {\r\n        return this.textureMode;\r\n    }\r\n    /**\r\n     * Sets the current video mode for the video. It can be:\r\n     * * TextureDome.MODE_MONOSCOPIC : Define the texture source as a Monoscopic panoramic 360.\r\n     * * TextureDome.MODE_TOPBOTTOM  : Define the texture source as a Stereoscopic TopBottom/OverUnder panoramic 360.\r\n     * * TextureDome.MODE_SIDEBYSIDE : Define the texture source as a Stereoscopic Side by Side panoramic 360.\r\n     */\r\n    public set imageMode(value: number) {\r\n        this.textureMode = value;\r\n    }\r\n\r\n    protected _initTexture(urlsOrElement: string, scene: Scene, options: any): Texture {\r\n        return new Texture(\r\n            urlsOrElement,\r\n            scene,\r\n            !options.generateMipMaps,\r\n            !this._useDirectMapping,\r\n            undefined,\r\n            () => {\r\n                this.onLoadObservable.notifyObservers();\r\n            },\r\n            (message, exception) => {\r\n                this.onLoadErrorObservable.notifyObservers(message || \"Unknown error occured\");\r\n\r\n                if (this.onError) {\r\n                    this.onError(message, exception);\r\n                }\r\n            }\r\n        );\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsColor3, expandToProperty, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { GetEnvironmentBRDFTexture } from \"../../Misc/brdfTextureTools\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { PBRBaseMaterial } from \"./pbrBaseMaterial.pure\";\r\nimport { RegisterImageProcessingConfiguration } from \"../imageProcessingConfiguration.pure\";\r\nimport { Material } from \"../material.pure\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * The Physically based material of BJS.\r\n *\r\n * This offers the main features of a standard PBR material.\r\n * For more information, please refer to the documentation :\r\n * https://doc.babylonjs.com/features/featuresDeepDive/materials/using/introToPBR\r\n */\r\nexport class PBRMaterial extends PBRBaseMaterial {\r\n    /**\r\n     * PBRMaterialTransparencyMode: No transparency mode, Alpha channel is not use.\r\n     */\r\n    public static override readonly PBRMATERIAL_OPAQUE = PBRBaseMaterial.PBRMATERIAL_OPAQUE;\r\n\r\n    /**\r\n     * PBRMaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.\r\n     */\r\n    public static override readonly PBRMATERIAL_ALPHATEST = PBRBaseMaterial.PBRMATERIAL_ALPHATEST;\r\n\r\n    /**\r\n     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.\r\n     */\r\n    public static override readonly PBRMATERIAL_ALPHABLEND = PBRBaseMaterial.PBRMATERIAL_ALPHABLEND;\r\n\r\n    /**\r\n     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.\r\n     * They are also discarded below the alpha cutoff threshold to improve performances.\r\n     */\r\n    public static override readonly PBRMATERIAL_ALPHATESTANDBLEND = PBRBaseMaterial.PBRMATERIAL_ALPHATESTANDBLEND;\r\n\r\n    /**\r\n     * Defines the default value of how much AO map is occluding the analytical lights\r\n     * (point spot...).\r\n     */\r\n    public static override DEFAULT_AO_ON_ANALYTICAL_LIGHTS = PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS;\r\n\r\n    /**\r\n     * Intensity of the direct lights e.g. the four lights available in your scene.\r\n     * This impacts both the direct diffuse and specular highlights.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor directIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Intensity of the emissive part of the material.\r\n     * This helps controlling the emissive effect without modifying the emissive color.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor emissiveIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Intensity of the environment e.g. how much the environment will light the object\r\n     * either through harmonics for rough material or through the reflection for shiny ones.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor environmentIntensity: number = 1.0;\r\n\r\n    /**\r\n     * This is a special control allowing the reduction of the specular highlights coming from the\r\n     * four lights of the scene. Those highlights may not be needed in full environment lighting.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor specularIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Debug Control allowing disabling the bump map on this material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor disableBumpMap: boolean = false;\r\n\r\n    /**\r\n     * AKA Diffuse Texture in standard nomenclature.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor albedoTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * OpenPBR Base Weight texture (multiplier to the diffuse and metal lobes).\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor baseWeightTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * OpenPBR Base Diffuse Roughness texture (roughness of the diffuse lobe).\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor baseDiffuseRoughnessTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * AKA Occlusion Texture in other nomenclature.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor ambientTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * AKA Occlusion Texture Intensity in other nomenclature.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor ambientTextureStrength: number = 1.0;\r\n\r\n    /**\r\n     * Defines how much the AO map is occluding the analytical lights (point spot...).\r\n     * 1 means it completely occludes it\r\n     * 0 mean it has no impact\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor ambientTextureImpactOnAnalyticalLights: number = PBRMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS;\r\n\r\n    /**\r\n     * Stores the alpha values in a texture. Use luminance if texture.getAlphaFromRGB is true.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor opacityTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Stores the reflection values in a texture.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Stores the emissive values in a texture.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor emissiveTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * AKA Specular texture in other nomenclature.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectivityTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Used to switch from specular/glossiness to metallic/roughness workflow.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor metallicTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Specifies the metallic scalar of the metallic/roughness workflow.\r\n     * Can also be used to scale the metalness values of the metallic texture.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor metallic: Nullable<number>;\r\n\r\n    /**\r\n     * Specifies the roughness scalar of the metallic/roughness workflow.\r\n     * Can also be used to scale the roughness values of the metallic texture.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor roughness: Nullable<number>;\r\n\r\n    /**\r\n     * In metallic workflow, specifies an F0 factor to help configuring the material F0.\r\n     * By default the indexOfrefraction is used to compute F0;\r\n     *\r\n     * This is used as a factor against the default reflectance at normal incidence to tweak it.\r\n     *\r\n     * F0 = defaultF0 * metallicF0Factor * metallicReflectanceColor;\r\n     * F90 = metallicReflectanceColor;\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor metallicF0Factor = 1;\r\n\r\n    /**\r\n     * In metallic workflow, specifies an F0 color.\r\n     * By default the F90 is always 1;\r\n     *\r\n     * Please note that this factor is also used as a factor against the default reflectance at normal incidence.\r\n     *\r\n     * F0 = defaultF0_from_IOR * metallicF0Factor * metallicReflectanceColor\r\n     * F90 = metallicF0Factor;\r\n     */\r\n    @serializeAsColor3()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor metallicReflectanceColor = Color3.White();\r\n\r\n    /**\r\n     * Specifies that only the A channel from metallicReflectanceTexture should be used.\r\n     * If false, both RGB and A channels will be used\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useOnlyMetallicFromMetallicReflectanceTexture = false;\r\n\r\n    /**\r\n     * Defines to store metallicReflectanceColor in RGB and metallicF0Factor in A\r\n     * This is multiplied against the scalar values defined in the material.\r\n     * If useOnlyMetallicFromMetallicReflectanceTexture is true, don't use the RGB channels, only A\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor metallicReflectanceTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Defines to store reflectanceColor in RGB\r\n     * This is multiplied against the scalar values defined in the material.\r\n     * If both reflectanceTexture and metallicReflectanceTexture textures are provided and useOnlyMetallicFromMetallicReflectanceTexture\r\n     * is false, metallicReflectanceTexture takes priority and reflectanceTexture is not used\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectanceTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Used to enable roughness/glossiness fetch from a separate channel depending on the current mode.\r\n     * Gray Scale represents roughness in metallic mode and glossiness in specular mode.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor microSurfaceTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Stores surface normal data used to displace a mesh in a texture.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor bumpTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Stores the pre-calculated light information of a mesh in a texture.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", null)\r\n    public accessor lightmapTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Stores the refracted light information in a texture.\r\n     */\r\n    public get refractionTexture(): Nullable<BaseTexture> {\r\n        return this.subSurface.refractionTexture;\r\n    }\r\n    public set refractionTexture(value: Nullable<BaseTexture>) {\r\n        this.subSurface.refractionTexture = value;\r\n        if (value) {\r\n            this.subSurface.isRefractionEnabled = true;\r\n        } else if (!this.subSurface.linkRefractionWithTransparency) {\r\n            this.subSurface.isRefractionEnabled = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The color of a material in ambient lighting.\r\n     */\r\n    @serializeAsColor3(\"ambient\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor ambientColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * AKA Diffuse Color in other nomenclature.\r\n     */\r\n    @serializeAsColor3(\"albedo\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor albedoColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * OpenPBR Base Weight (multiplier to the diffuse and metal lobes).\r\n     */\r\n    @serialize(\"baseWeight\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor baseWeight = 1;\r\n\r\n    /**\r\n     * OpenPBR Base Diffuse Roughness (roughness of the diffuse lobe).\r\n     */\r\n    @serialize(\"baseDiffuseRoughness\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor baseDiffuseRoughness: Nullable<number>;\r\n\r\n    /**\r\n     * AKA Specular Color in other nomenclature.\r\n     */\r\n    @serializeAsColor3(\"reflectivity\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectivityColor = new Color3(1, 1, 1);\r\n\r\n    /**\r\n     * The color reflected from the material.\r\n     */\r\n    @serializeAsColor3(\"reflection\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor reflectionColor = new Color3(1.0, 1.0, 1.0);\r\n\r\n    /**\r\n     * The color emitted from the material.\r\n     */\r\n    @serializeAsColor3(\"emissive\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor emissiveColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * AKA Glossiness in other nomenclature.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor microSurface = 1.0;\r\n\r\n    /**\r\n     * Index of refraction of the material base layer.\r\n     * https://en.wikipedia.org/wiki/List_of_refractive_indices\r\n     *\r\n     * This does not only impact refraction but also the Base F0 of Dielectric Materials.\r\n     *\r\n     * From dielectric fresnel rules: F0 = square((iorT - iorI) / (iorT + iorI))\r\n     */\r\n    public get indexOfRefraction(): number {\r\n        return this.subSurface.indexOfRefraction;\r\n    }\r\n    public set indexOfRefraction(value: number) {\r\n        this.subSurface.indexOfRefraction = value;\r\n    }\r\n\r\n    /**\r\n     * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.\r\n     */\r\n    public get invertRefractionY(): boolean {\r\n        return this.subSurface.invertRefractionY;\r\n    }\r\n    public set invertRefractionY(value: boolean) {\r\n        this.subSurface.invertRefractionY = value;\r\n    }\r\n\r\n    /**\r\n     * This parameters will make the material used its opacity to control how much it is refracting against not.\r\n     * Materials half opaque for instance using refraction could benefit from this control.\r\n     */\r\n    public get linkRefractionWithTransparency(): boolean {\r\n        return this.subSurface.linkRefractionWithTransparency;\r\n    }\r\n    public set linkRefractionWithTransparency(value: boolean) {\r\n        this.subSurface.linkRefractionWithTransparency = value;\r\n        if (value) {\r\n            this.subSurface.isRefractionEnabled = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If true, the light map contains occlusion information instead of lighting info.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useLightmapAsShadowmap = false;\r\n\r\n    /**\r\n     * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor useAlphaFromAlbedoTexture = false;\r\n\r\n    /**\r\n     * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor forceAlphaTest = false;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesAndMiscDirty\")\r\n    public accessor alphaCutOff = 0.4;\r\n\r\n    /**\r\n     * Specifies that the material will keep the specular highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good example of that. When sun reflects on it you can not see what is behind.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useSpecularOverAlpha = true;\r\n\r\n    /**\r\n     * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useMicroSurfaceFromReflectivityMapAlpha = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the roughness information in its alpha channel.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRoughnessFromMetallicTextureAlpha = true;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the roughness information in its green channel.\r\n     * Needs useRoughnessFromMetallicTextureAlpha to be false.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRoughnessFromMetallicTextureGreen = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the metallness information in its blue channel.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useMetallnessFromMetallicTextureBlue = false;\r\n\r\n    /**\r\n     * Specifies if the metallic texture contains the ambient occlusion information in its red channel.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAmbientOcclusionFromMetallicTextureRed = false;\r\n\r\n    /**\r\n     * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAmbientInGrayScale = false;\r\n\r\n    /**\r\n     * In case the reflectivity map does not contain the microsurface information in its alpha channel,\r\n     * The material will try to infer what glossiness each pixel should be.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAutoMicroSurfaceFromReflectivityMap = false;\r\n\r\n    /**\r\n     * BJS is using an hardcoded light falloff based on a manually sets up range.\r\n     * In PBR, one way to represents the falloff is to use the inverse squared root algorithm.\r\n     * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.\r\n     */\r\n    @serialize()\r\n    public get usePhysicalLightFalloff(): boolean {\r\n        return this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL;\r\n    }\r\n\r\n    /**\r\n     * BJS is using an hardcoded light falloff based on a manually sets up range.\r\n     * In PBR, one way to represents the falloff is to use the inverse squared root algorithm.\r\n     * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.\r\n     */\r\n    public set usePhysicalLightFalloff(value: boolean) {\r\n        if (value !== this.usePhysicalLightFalloff) {\r\n            // Ensure the effect will be rebuilt.\r\n            this._markAllSubMeshesAsTexturesDirty();\r\n\r\n            if (value) {\r\n                this._lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL;\r\n            } else {\r\n                this._lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_STANDARD;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * In order to support the falloff compatibility with gltf, a special mode has been added\r\n     * to reproduce the gltf light falloff.\r\n     */\r\n    @serialize()\r\n    public get useGLTFLightFalloff(): boolean {\r\n        return this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_GLTF;\r\n    }\r\n\r\n    /**\r\n     * In order to support the falloff compatibility with gltf, a special mode has been added\r\n     * to reproduce the gltf light falloff.\r\n     */\r\n    public set useGLTFLightFalloff(value: boolean) {\r\n        if (value !== this.useGLTFLightFalloff) {\r\n            // Ensure the effect will be rebuilt.\r\n            this._markAllSubMeshesAsTexturesDirty();\r\n\r\n            if (value) {\r\n                this._lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_GLTF;\r\n            } else {\r\n                this._lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_STANDARD;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good example of that. When the street lights reflects on it you can not see what is behind.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRadianceOverAlpha = true;\r\n\r\n    /**\r\n     * Allows using an object space normal map (instead of tangent space).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useObjectSpaceNormalMap = false;\r\n\r\n    /**\r\n     * Allows using the bump map in parallax mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useParallax = false;\r\n\r\n    /**\r\n     * Allows using the bump map in parallax occlusion mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useParallaxOcclusion = false;\r\n\r\n    /**\r\n     * Controls the scale bias of the parallax mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor parallaxScaleBias = 0.05;\r\n\r\n    /**\r\n     * If sets to true, disables all the lights affecting the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor disableLighting = false;\r\n\r\n    /**\r\n     * Force the shader to compute irradiance in the fragment shader in order to take bump in account.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor forceIrradianceInFragment = false;\r\n\r\n    /**\r\n     * Number of Simultaneous lights allowed on the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor maxSimultaneousLights = 4;\r\n\r\n    /**\r\n     * If sets to true, x component of normal map value will invert (x = 1.0 - x).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapX = false;\r\n\r\n    /**\r\n     * If sets to true, y component of normal map value will invert (y = 1.0 - y).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapY = false;\r\n\r\n    /**\r\n     * If sets to true and backfaceCulling is false, normals will be flipped on the backside.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor twoSidedLighting = false;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useAlphaFresnel = false;\r\n\r\n    /**\r\n     * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.\r\n     * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useLinearAlphaFresnel = false;\r\n\r\n    /**\r\n     * Let user defines the brdf lookup texture used for IBL.\r\n     * A default 8bit version is embedded but you could point at :\r\n     * * Default texture: https://assets.babylonjs.com/environments/correlatedMSBRDF_RGBD.png\r\n     * * Default 16bit pixel depth texture: https://assets.babylonjs.com/environments/correlatedMSBRDF.dds\r\n     * * LEGACY Default None correlated https://assets.babylonjs.com/environments/uncorrelatedBRDF_RGBD.png\r\n     * * LEGACY Default None correlated 16bit pixel depth https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds\r\n     */\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor environmentBRDFTexture: Nullable<BaseTexture> = null;\r\n\r\n    /**\r\n     * Force normal to face away from face.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor forceNormalForward = false;\r\n\r\n    /**\r\n     * Enables specular anti aliasing in the PBR shader.\r\n     * It will both interacts on the Geometry for analytical and IBL lighting.\r\n     * It also prefilter the roughness map based on the bump values.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor enableSpecularAntiAliasing = false;\r\n\r\n    /**\r\n     * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal\r\n     * makes the reflect vector face the model (under horizon).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useHorizonOcclusion = true;\r\n\r\n    /**\r\n     * This parameters will enable/disable radiance occlusion by preventing the radiance to lit\r\n     * too much the area relying on ambient texture to define their ambient occlusion.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useRadianceOcclusion = true;\r\n\r\n    /**\r\n     * If set to true, no lighting calculations will be applied.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor unlit = false;\r\n\r\n    /**\r\n     * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false)\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsMiscDirty\")\r\n    public accessor applyDecalMapAfterDetailMap = false;\r\n\r\n    /**\r\n     * Instantiates a new PBRMaterial instance.\r\n     *\r\n     * @param name The material name\r\n     * @param scene The scene the material will be use in.\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(name: string, scene?: Scene, forceGLSL = false) {\r\n        super(name, scene, forceGLSL);\r\n\r\n        this._environmentBRDFTexture = GetEnvironmentBRDFTexture(this.getScene());\r\n    }\r\n\r\n    /**\r\n     * @returns the name of this material class.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PBRMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current material.\r\n     * @param name - name to use for the new material.\r\n     * @param cloneTexturesOnlyOnce - if a texture is used in more than one channel (e.g diffuse and opacity), only clone it once and reuse it on the other channels. Default false.\r\n     * @param rootUrl defines the root URL to use to load textures\r\n     * @returns cloned material instance\r\n     */\r\n    public override clone(name: string, cloneTexturesOnlyOnce: boolean = true, rootUrl = \"\"): PBRMaterial {\r\n        const clone = SerializationHelper.Clone(() => new PBRMaterial(name, this.getScene()), this, { cloneTexturesOnlyOnce });\r\n\r\n        clone.id = name;\r\n        clone.name = name;\r\n\r\n        this.stencil.copyTo(clone.stencil);\r\n\r\n        this._clonePlugins(clone, rootUrl);\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serializes this PBR Material.\r\n     * @returns - An object with the serialized material.\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.customType = \"BABYLON.PBRMaterial\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Parses a PBR Material from a serialized object.\r\n     * @param source - Serialized object.\r\n     * @param scene - BJS scene instance.\r\n     * @param rootUrl - url for the scene object\r\n     * @returns - PBRMaterial\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): PBRMaterial {\r\n        const material = SerializationHelper.Parse(() => new PBRMaterial(source.name, scene), source, scene, rootUrl);\r\n\r\n        if (source.stencil) {\r\n            material.stencil.parse(source.stencil, scene, rootUrl);\r\n        }\r\n\r\n        Material._ParsePlugins(source, material, scene, rootUrl);\r\n\r\n        // The code block below ensures backward compatibility with serialized materials before plugins are automatically serialized.\r\n        if (source.clearCoat) {\r\n            material.clearCoat.parse(source.clearCoat, scene, rootUrl);\r\n        }\r\n        if (source.anisotropy) {\r\n            material.anisotropy.parse(source.anisotropy, scene, rootUrl);\r\n        }\r\n        if (source.brdf) {\r\n            material.brdf.parse(source.brdf, scene, rootUrl);\r\n        }\r\n        if (source.sheen) {\r\n            material.sheen.parse(source.sheen, scene, rootUrl);\r\n        }\r\n        if (source.subSurface) {\r\n            material.subSurface.parse(source.subSurface, scene, rootUrl);\r\n        }\r\n        if (source.iridescence) {\r\n            material.iridescence.parse(source.iridescence, scene, rootUrl);\r\n        }\r\n\r\n        return material;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pbrMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPbrMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // PBRMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\r\n    RegisterImageProcessingConfiguration();\r\n\r\n    RegisterClass(\"BABYLON.PBRMaterial\", PBRMaterial);\r\n}\r\n\r\n/**\r\n * Register side effects for PBRMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * Alias for {@link RegisterPbrMaterial}.\r\n */\r\nexport function RegisterPBRMaterial(): void {\r\n    RegisterPbrMaterial();\r\n}\r\n","import { Vector3, Matrix, Quaternion, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { FreeCamera } from \"../Cameras/freeCamera.pure\";\r\nimport { TargetCamera } from \"../Cameras/targetCamera.pure\";\r\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { Viewport } from \"../Maths/math.viewport\";\r\nimport { Observable, type Observer } from \"../Misc/observable\";\r\nimport { WebXRTrackingState } from \"./webXRTypes\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * WebXR Camera which holds the views for the xrSession\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRCamera\r\n */\r\nexport class WebXRCamera extends FreeCamera {\r\n    private static _ScaleReadOnly = Vector3.One();\r\n\r\n    private _firstFrame = false;\r\n    private _xrSessionInitObserver: Nullable<Observer<XRSession>> = null;\r\n    private _xrFrameObserver: Nullable<Observer<XRFrame>> = null;\r\n    private _referenceQuaternion: Quaternion = Quaternion.Identity();\r\n    private _referencedPosition: Vector3 = new Vector3();\r\n    private _trackingState: WebXRTrackingState = WebXRTrackingState.NOT_TRACKING;\r\n\r\n    private _onWorldScaleFactorChanged = () => {\r\n        // only run if in session\r\n        if (!this._xrSessionManager.currentFrame) {\r\n            return;\r\n        }\r\n        this._updateDepthNearFar();\r\n    };\r\n\r\n    /**\r\n     * This will be triggered after the first XR Frame initialized the camera,\r\n     * including the right number of views and their rendering parameters\r\n     */\r\n    public onXRCameraInitializedObservable = new Observable<WebXRCamera>();\r\n\r\n    /**\r\n     * Observable raised before camera teleportation\r\n     * @deprecated use onBeforeCameraTeleport of the teleportation feature instead\r\n     */\r\n    public onBeforeCameraTeleport = new Observable<Vector3>();\r\n\r\n    /**\r\n     *  Observable raised after camera teleportation\r\n     * @deprecated use onAfterCameraTeleport of the teleportation feature instead\r\n     */\r\n    public onAfterCameraTeleport = new Observable<Vector3>();\r\n\r\n    /**\r\n     * Notifies when the camera's tracking state has changed.\r\n     * Notice - will also be triggered when tracking has started (at the beginning of the session)\r\n     */\r\n    public onTrackingStateChanged = new Observable<WebXRTrackingState>();\r\n\r\n    /**\r\n     * Should position compensation execute on first frame.\r\n     * This is used when copying the position from a native (non XR) camera\r\n     */\r\n    public compensateOnFirstFrame: boolean = true;\r\n\r\n    /**\r\n     * The last XRViewerPose from the current XRFrame\r\n     * @internal\r\n     */\r\n    public _lastXRViewerPose?: XRViewerPose;\r\n\r\n    /**\r\n     * webXRCamera relies on rotationQuaternion and doesn't use camera rotation property\r\n     */\r\n    public override rotationQuaternion: Quaternion;\r\n\r\n    /**\r\n     * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager\r\n     * @param name the name of the camera\r\n     * @param scene the scene to add the camera to\r\n     * @param _xrSessionManager a constructed xr session manager\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        private _xrSessionManager: WebXRSessionManager\r\n    ) {\r\n        super(name, Vector3.Zero(), scene);\r\n\r\n        // Initial camera configuration\r\n        this.minZ = 0.1;\r\n        this.rotationQuaternion = new Quaternion();\r\n        this.cameraRigMode = Camera.RIG_MODE_CUSTOM;\r\n        this.updateUpVectorFromRotation = true;\r\n        this._updateNumberOfRigCameras(1);\r\n        // freeze projection matrix, which will be copied later\r\n        this.freezeProjectionMatrix();\r\n        this._deferOnly = true;\r\n\r\n        this._xrSessionInitObserver = this._xrSessionManager.onXRSessionInit.add(() => {\r\n            this._referencedPosition.copyFromFloats(0, 0, 0);\r\n            this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);\r\n            // first frame - camera's y position should be 0 for the correct offset\r\n            this._firstFrame = this.compensateOnFirstFrame;\r\n        });\r\n\r\n        this._xrSessionManager.onWorldScaleFactorChangedObservable.add(this._onWorldScaleFactorChanged);\r\n\r\n        // Check transformation changes on each frame. Callback is added to be first so that the transformation will be\r\n        // applied to the rest of the elements using the referenceSpace object\r\n        this._xrFrameObserver = this._xrSessionManager.onXRFrameObservable.add(\r\n            () => {\r\n                if (this._firstFrame) {\r\n                    this._updateFromXRSession();\r\n                }\r\n                if (this.onXRCameraInitializedObservable.hasObservers()) {\r\n                    this.onXRCameraInitializedObservable.notifyObservers(this);\r\n                    this.onXRCameraInitializedObservable.clear();\r\n                }\r\n\r\n                if (this._deferredUpdated) {\r\n                    this.position.copyFrom(this._deferredPositionUpdate);\r\n                    this.rotationQuaternion.copyFrom(this._deferredRotationQuaternionUpdate);\r\n                }\r\n\r\n                this._updateReferenceSpace();\r\n                this._updateFromXRSession();\r\n            },\r\n            undefined,\r\n            true\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Get the current XR tracking state of the camera\r\n     */\r\n    public get trackingState(): WebXRTrackingState {\r\n        return this._trackingState;\r\n    }\r\n\r\n    private _setTrackingState(newState: WebXRTrackingState) {\r\n        if (this._trackingState !== newState) {\r\n            this._trackingState = newState;\r\n            this.onTrackingStateChanged.notifyObservers(newState);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Return the user's height, unrelated to the current ground.\r\n     * This will be the y position of this camera, when ground level is 0.\r\n     *\r\n     * Note - this value is multiplied by the worldScalingFactor (if set), so it will be in the same units as the scene.\r\n     */\r\n    public get realWorldHeight(): number {\r\n        const basePose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(this._xrSessionManager.baseReferenceSpace);\r\n        if (basePose && basePose.transform) {\r\n            return basePose.transform.position.y * this._xrSessionManager.worldScalingFactor;\r\n        } else {\r\n            return 0;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _updateForDualEyeDebugging(/*pupilDistance = 0.01*/) {\r\n        // Create initial camera rigs\r\n        this._updateNumberOfRigCameras(2);\r\n        this.rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);\r\n        // this.rigCameras[0].position.x = -pupilDistance / 2;\r\n        this.rigCameras[0].outputRenderTarget = null;\r\n        this.rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);\r\n        // this.rigCameras[1].position.x = pupilDistance / 2;\r\n        this.rigCameras[1].outputRenderTarget = null;\r\n    }\r\n\r\n    /**\r\n     * Sets this camera's transformation based on a non-vr camera\r\n     * @param otherCamera the non-vr camera to copy the transformation from\r\n     * @param resetToBaseReferenceSpace should XR reset to the base reference space\r\n     */\r\n    public setTransformationFromNonVRCamera(otherCamera: Camera = this.getScene().activeCamera!, resetToBaseReferenceSpace: boolean = true) {\r\n        if (!otherCamera || otherCamera === this) {\r\n            return;\r\n        }\r\n        const mat = otherCamera.computeWorldMatrix();\r\n        mat.decompose(undefined, this.rotationQuaternion, this.position);\r\n        // set the ground level\r\n        this.position.y = 0;\r\n        Quaternion.FromEulerAnglesToRef(0, this.rotationQuaternion.toEulerAngles().y, 0, this.rotationQuaternion);\r\n        this._firstFrame = true;\r\n        if (resetToBaseReferenceSpace) {\r\n            this._xrSessionManager.resetReferenceSpace();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance class name (\"WebXRCamera\").\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"WebXRCamera\";\r\n    }\r\n\r\n    /**\r\n     * Set the target for the camera to look at.\r\n     * Note that this only rotates around the Y axis, as opposed to the default behavior of other cameras\r\n     * @param target the target to set the camera to look at\r\n     */\r\n    public override setTarget(target: Vector3): void {\r\n        // only rotate around the y axis!\r\n        const tmpVector = TmpVectors.Vector3[1];\r\n        target.subtractToRef(this.position, tmpVector);\r\n        tmpVector.y = 0;\r\n        tmpVector.normalize();\r\n        const yRotation = Math.atan2(tmpVector.x, tmpVector.z) + (this._scene.useRightHandedSystem ? Math.PI : 0);\r\n        this.rotationQuaternion.toEulerAnglesToRef(tmpVector);\r\n        Quaternion.FromEulerAnglesToRef(tmpVector.x, yRotation, tmpVector.z, this.rotationQuaternion);\r\n    }\r\n\r\n    public override dispose() {\r\n        this._xrSessionManager.onWorldScaleFactorChangedObservable.removeCallback(this._onWorldScaleFactorChanged);\r\n        this._xrSessionManager.onXRSessionInit.remove(this._xrSessionInitObserver);\r\n        this._xrSessionInitObserver = null;\r\n        this._xrSessionManager.onXRFrameObservable.remove(this._xrFrameObserver);\r\n        this._xrFrameObserver = null;\r\n        super.dispose();\r\n        this._lastXRViewerPose = undefined;\r\n        this.onTrackingStateChanged.clear();\r\n    }\r\n\r\n    private _updateDepthNearFar() {\r\n        const far = (this.maxZ || 10000) * this._xrSessionManager.worldScalingFactor;\r\n        const xrRenderState: XRRenderStateInit = {\r\n            // if maxZ is 0 it should be \"Infinity\", but it doesn't work with the WebXR API. Setting to a large number.\r\n            depthFar: far,\r\n            depthNear: this.minZ,\r\n        };\r\n\r\n        this._xrSessionManager.updateRenderState(xrRenderState);\r\n        this._cache.minZ = this.minZ;\r\n        this._cache.maxZ = far;\r\n    }\r\n\r\n    private _updateFromXRSession() {\r\n        const pose = this._xrSessionManager.currentFrame && this._xrSessionManager.currentFrame.getViewerPose(this._xrSessionManager.referenceSpace);\r\n        this._lastXRViewerPose = pose || undefined;\r\n        if (!pose) {\r\n            this._setTrackingState(WebXRTrackingState.NOT_TRACKING);\r\n            return;\r\n        }\r\n\r\n        // Set the tracking state. if it didn't change it is a no-op\r\n        const trackingState = pose.emulatedPosition ? WebXRTrackingState.TRACKING_LOST : WebXRTrackingState.TRACKING;\r\n        this._setTrackingState(trackingState);\r\n\r\n        // check min/max Z and update if not the same as in cache\r\n        if (this.minZ !== this._cache.minZ || this.maxZ !== this._cache.maxZ) {\r\n            this._updateDepthNearFar();\r\n        }\r\n\r\n        if (pose.transform) {\r\n            const orientation = pose.transform.orientation;\r\n            if (pose.transform.orientation.x === undefined) {\r\n                // Babylon native polyfill can return an undefined orientation value\r\n                // When not initialized\r\n                return;\r\n            }\r\n            const pos = pose.transform.position;\r\n            this._referencedPosition.set(pos.x, pos.y, pos.z).scaleInPlace(this._xrSessionManager.worldScalingFactor);\r\n\r\n            this._referenceQuaternion.set(orientation.x, orientation.y, orientation.z, orientation.w);\r\n            if (!this._scene.useRightHandedSystem) {\r\n                this._referencedPosition.z *= -1;\r\n                this._referenceQuaternion.z *= -1;\r\n                this._referenceQuaternion.w *= -1;\r\n            }\r\n\r\n            if (this._firstFrame) {\r\n                this._firstFrame = false;\r\n                // we have the XR reference, now use this to find the offset to get the camera to be\r\n                // in the right position\r\n\r\n                // set the height to correlate to the current height\r\n                this.position.y += this._referencedPosition.y;\r\n                // avoid using the head rotation on the first frame.\r\n                this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);\r\n            } else {\r\n                // update position and rotation as reference\r\n                this.rotationQuaternion.copyFrom(this._referenceQuaternion);\r\n                this.position.copyFrom(this._referencedPosition);\r\n            }\r\n        }\r\n\r\n        // Update camera rigs\r\n        if (this.rigCameras.length !== pose.views.length) {\r\n            this._updateNumberOfRigCameras(pose.views.length);\r\n        }\r\n\r\n        for (let i = 0; i < pose.views.length; i++) {\r\n            const view = pose.views[i];\r\n            const currentRig = <TargetCamera>this.rigCameras[i];\r\n            // update right and left, where applicable\r\n            if (!currentRig.isLeftCamera && !currentRig.isRightCamera) {\r\n                if (view.eye === \"right\") {\r\n                    currentRig._isRightCamera = true;\r\n                } else if (view.eye === \"left\") {\r\n                    currentRig._isLeftCamera = true;\r\n                }\r\n            }\r\n            // add any custom render targets to this camera, if available in the scene\r\n            const customRenderTargets = this.getScene().customRenderTargets;\r\n            // use a for loop\r\n            for (let i = 0; i < customRenderTargets.length; i++) {\r\n                const rt = customRenderTargets[i];\r\n                // make sure we don't add the same render target twice\r\n                if (currentRig.customRenderTargets.indexOf(rt) === -1) {\r\n                    currentRig.customRenderTargets.push(rt);\r\n                }\r\n            }\r\n            // Update view/projection matrix\r\n            const pos = view.transform.position;\r\n            const orientation = view.transform.orientation;\r\n\r\n            currentRig.parent = this.parent;\r\n\r\n            currentRig.position.set(pos.x, pos.y, pos.z).scaleInPlace(this._xrSessionManager.worldScalingFactor);\r\n            currentRig.rotationQuaternion?.set(orientation.x, orientation.y, orientation.z, orientation.w);\r\n            if (!this._scene.useRightHandedSystem && currentRig.rotationQuaternion) {\r\n                currentRig.position.z *= -1;\r\n                currentRig.rotationQuaternion.z *= -1;\r\n                currentRig.rotationQuaternion.w *= -1;\r\n            }\r\n            Matrix.FromFloat32ArrayToRefScaled(view.projectionMatrix, 0, 1, currentRig._projectionMatrix);\r\n\r\n            // WebGPU uses a [0, 1] clip-space depth range (engine.isNDCHalfZRange === true) whereas WebGL/OpenGL uses\r\n            // [-1, 1]. The rig cameras freeze their projection (see _updateNumberOfRigCameras) and take the XR binding's\r\n            // projection matrix verbatim, bypassing the engine's range-aware projection builders. If the binding hands\r\n            // back a [-1, 1]-convention matrix while the engine clips at [0, 1], every fragment with NDC z in [-1, 0)\r\n            // is clipped and all geometry disappears. On a half-Z engine we therefore detect the convention the binding\r\n            // actually used and convert a [-1, 1] matrix to [0, 1]. Detection is empirical (coefficient inspection is\r\n            // provably ambiguous): project the view-space near-plane point through the raw matrix, before the hand\r\n            // toggle. WebXR view space is right-handed (-Z forward), so the near point is (0, 0, -near); a [-1, 1] matrix\r\n            // maps it to NDC z ~= -1, a [0, 1] matrix to ~= 0. Assumes a non-reverse-Z projection (near -> 0 or -1),\r\n            // which UA-provided XR matrices are. WebGL2 (isNDCHalfZRange === false) never enters this block, so its path\r\n            // is byte-identical.\r\n            if (this._scene.getEngine().isNDCHalfZRange) {\r\n                const near = this.minZ;\r\n                let needsHalfZConversion: boolean;\r\n                if (near > 0) {\r\n                    const ndc = Vector3.TransformCoordinatesFromFloatsToRef(0, 0, -near, currentRig._projectionMatrix, TmpVectors.Vector3[0]);\r\n                    needsHalfZConversion = ndc.z < -0.5;\r\n                } else {\r\n                    // depthNear must be > 0 per the WebXR spec; if it is not, the near-plane probe would divide by zero,\r\n                    // so default to converting (matches the [-1, 1] range current XRGPUBinding implementations return).\r\n                    needsHalfZConversion = true;\r\n                }\r\n                if (needsHalfZConversion) {\r\n                    currentRig._projectionMatrix._convertProjectionToHalfZRangeInPlace();\r\n                }\r\n            }\r\n\r\n            if (!this._scene.useRightHandedSystem) {\r\n                currentRig._projectionMatrix.toggleProjectionMatrixHandInPlace();\r\n            }\r\n\r\n            // fov\r\n            const fov = Math.atan2(1, view.projectionMatrix[5]) * 2;\r\n            currentRig.fov = fov;\r\n            // first camera?\r\n            if (i === 0) {\r\n                this.fov = fov;\r\n                this._projectionMatrix.copyFrom(currentRig._projectionMatrix);\r\n            }\r\n\r\n            const renderTargetTexture = this._xrSessionManager.getRenderTargetTextureForView(view);\r\n            this._renderingMultiview = renderTargetTexture?._texture?.isMultiview || false;\r\n            if (this._renderingMultiview) {\r\n                // For multiview, the render target texture is the same per-view (just the slice index is different),\r\n                // so we only need to set the output render target once for the rig parent.\r\n                if (i == 0) {\r\n                    this._xrSessionManager.trySetViewportForView(this.viewport, view);\r\n                    this.outputRenderTarget = renderTargetTexture;\r\n                }\r\n            } else {\r\n                // Update viewport\r\n                this._xrSessionManager.trySetViewportForView(currentRig.viewport, view);\r\n\r\n                // Set cameras to render to the session's render target\r\n                currentRig.outputRenderTarget = renderTargetTexture || this._xrSessionManager.getRenderTargetTextureForView(view);\r\n            }\r\n\r\n            // Replicate parent rig camera behavior\r\n            currentRig.layerMask = this.layerMask;\r\n        }\r\n    }\r\n\r\n    private _updateNumberOfRigCameras(viewCount = 1) {\r\n        while (this.rigCameras.length < viewCount) {\r\n            const newCamera = new TargetCamera(\"XR-RigCamera: \" + this.rigCameras.length, Vector3.Zero(), this.getScene());\r\n            newCamera.minZ = 0.1;\r\n            newCamera.rotationQuaternion = new Quaternion();\r\n            newCamera.updateUpVectorFromRotation = true;\r\n            newCamera.isRigCamera = true;\r\n            newCamera.rigParent = this;\r\n            // do not compute projection matrix, provided by XR\r\n            newCamera.freezeProjectionMatrix();\r\n            this.rigCameras.push(newCamera);\r\n        }\r\n        while (this.rigCameras.length > viewCount) {\r\n            const removedCamera = this.rigCameras.pop();\r\n            if (removedCamera) {\r\n                removedCamera.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateReferenceSpace() {\r\n        // were position & rotation updated OUTSIDE of the xr update loop\r\n        if (!this.position.equals(this._referencedPosition) || !this.rotationQuaternion.equals(this._referenceQuaternion)) {\r\n            const referencedMat = TmpVectors.Matrix[0];\r\n            const poseMat = TmpVectors.Matrix[1];\r\n            const transformMat = TmpVectors.Matrix[2];\r\n\r\n            Matrix.ComposeToRef(WebXRCamera._ScaleReadOnly, this._referenceQuaternion, this._referencedPosition, referencedMat);\r\n            Matrix.ComposeToRef(WebXRCamera._ScaleReadOnly, this.rotationQuaternion, this.position, poseMat);\r\n            referencedMat.invert().multiplyToRef(poseMat, transformMat);\r\n            transformMat.invert();\r\n\r\n            if (!this._scene.useRightHandedSystem) {\r\n                transformMat.toggleModelMatrixHandInPlace();\r\n            }\r\n\r\n            transformMat.decompose(undefined, this._referenceQuaternion, this._referencedPosition);\r\n            const transform = new XRRigidTransform(\r\n                {\r\n                    x: this._referencedPosition.x / this._xrSessionManager.worldScalingFactor,\r\n                    y: this._referencedPosition.y / this._xrSessionManager.worldScalingFactor,\r\n                    z: this._referencedPosition.z / this._xrSessionManager.worldScalingFactor,\r\n                    w: 1,\r\n                },\r\n                {\r\n                    x: this._referenceQuaternion.x,\r\n                    y: this._referenceQuaternion.y,\r\n                    z: this._referenceQuaternion.z,\r\n                    w: this._referenceQuaternion.w,\r\n                }\r\n            );\r\n            this._xrSessionManager.referenceSpace = this._xrSessionManager.referenceSpace.getOffsetReferenceSpace(transform);\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Observable, type Observer } from \"../Misc/observable\";\r\nimport { type IDisposable, type Scene } from \"../scene\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { WebXRCamera } from \"./webXRCamera\";\r\nimport { type WebXRRenderTarget, WebXRState } from \"./webXRTypes\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"./webXRFeaturesManager\";\r\nimport { IsWebGPUXREngineCompatible, WebGPUXREngineNotCompatibleErrorMessage, WebGPUXRNotSupportedErrorMessage } from \"./webXRGraphicsBinding\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { UniversalCamera } from \"../Cameras/universalCamera.pure\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * Options for setting up XR spectator camera.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface WebXRSpectatorModeOption {\r\n    /**\r\n     * Expected refresh rate (frames per sec) for a spectator camera.\r\n     */\r\n    fps?: number;\r\n    /**\r\n     * The index of rigCameras array in a WebXR camera.\r\n     */\r\n    preferredCameraIndex?: number;\r\n}\r\n\r\n/**\r\n * Base set of functionality needed to create an XR experience (WebXRSessionManager, Camera, StateManagement, etc.)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRExperienceHelpers\r\n */\r\nexport class WebXRExperienceHelper implements IDisposable {\r\n    private _nonVRCamera: Nullable<Camera> = null;\r\n    private _attachedToElement: boolean = false;\r\n    private _spectatorCamera: Nullable<UniversalCamera> = null;\r\n    private _originalSceneAutoClear = true;\r\n    private _supported = false;\r\n    private _spectatorMode = false;\r\n    private _lastTimestamp = 0;\r\n    private _spectatorStateChangedObserver: Nullable<Observer<WebXRState>> = null;\r\n    private _spectatorXRFrameObserver: Nullable<Observer<XRFrame>> = null;\r\n    private _spectatorAfterRenderObserver: Nullable<Observer<Camera>> = null;\r\n\r\n    /**\r\n     * Camera used to render xr content\r\n     */\r\n    public camera: WebXRCamera;\r\n    /** A features manager for this xr session */\r\n    public featuresManager: WebXRFeaturesManager;\r\n    /**\r\n     * Observers registered here will be triggered after the camera's initial transformation is set\r\n     * This can be used to set a different ground level or an extra rotation.\r\n     *\r\n     * Note that ground level is considered to be at 0. The height defined by the XR camera will be added\r\n     * to the position set after this observable is done executing.\r\n     */\r\n    public onInitialXRPoseSetObservable = new Observable<WebXRCamera>();\r\n    /**\r\n     * Fires when the state of the experience helper has changed\r\n     */\r\n    public onStateChangedObservable = new Observable<WebXRState>();\r\n    /** Session manager used to keep track of xr session */\r\n    public sessionManager: WebXRSessionManager;\r\n    /**\r\n     * The current state of the XR experience (eg. transitioning, in XR or not in XR)\r\n     */\r\n    public state: WebXRState = WebXRState.NOT_IN_XR;\r\n\r\n    /**\r\n     * Creates a WebXRExperienceHelper\r\n     * @param _scene The scene the helper should be created in\r\n     */\r\n    private constructor(private _scene: Scene) {\r\n        this.sessionManager = new WebXRSessionManager(_scene);\r\n        this.camera = new WebXRCamera(\"webxr\", _scene, this.sessionManager);\r\n        this.featuresManager = new WebXRFeaturesManager(this.sessionManager);\r\n        this.sessionManager.onXRSessionInit.add(() => {\r\n            if (this._scene.getEngine().isWebGPU && !this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)?.attached) {\r\n                throw new Error(\"WebGPU XR could not attach the required WebXR Layers feature.\");\r\n            }\r\n        });\r\n\r\n        _scene.onDisposeObservable.addOnce(() => {\r\n            this.dispose();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates the experience helper\r\n     * @param scene the scene to attach the experience helper to\r\n     * @returns a promise for the experience helper\r\n     */\r\n    public static async CreateAsync(scene: Scene): Promise<WebXRExperienceHelper> {\r\n        const helper = new WebXRExperienceHelper(scene);\r\n        return await helper.sessionManager\r\n            .initializeAsync()\r\n            // eslint-disable-next-line github/no-then\r\n            .then(() => {\r\n                helper._supported = true;\r\n                return helper;\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .catch((e) => {\r\n                helper._setState(WebXRState.NOT_IN_XR);\r\n                helper.dispose();\r\n                throw e;\r\n            });\r\n    }\r\n\r\n    /**\r\n     * Disposes of the experience helper\r\n     */\r\n    public dispose() {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this.exitXRAsync();\r\n        this._clearSpectatorObservers();\r\n        this.camera.dispose();\r\n        this.onStateChangedObservable.clear();\r\n        this.onInitialXRPoseSetObservable.clear();\r\n        this.sessionManager.dispose();\r\n        this._spectatorCamera?.dispose();\r\n        if (this._nonVRCamera) {\r\n            this._scene.activeCamera = this._nonVRCamera;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enters XR mode (This must be done within a user interaction in most browsers eg. button click)\r\n     * @param sessionMode options for the XR session\r\n     * @param referenceSpaceType frame of reference of the XR session\r\n     * @param renderTarget the output canvas that will be used to enter XR mode\r\n     * @param sessionCreationOptions optional XRSessionInit object to init the session with\r\n     * @returns promise that resolves after xr mode has entered\r\n     */\r\n    public async enterXRAsync(\r\n        sessionMode: XRSessionMode,\r\n        referenceSpaceType: XRReferenceSpaceType,\r\n        renderTarget?: WebXRRenderTarget,\r\n        sessionCreationOptions: XRSessionInit = {}\r\n    ): Promise<WebXRSessionManager> {\r\n        if (!this._supported) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"WebXR not supported in this browser or environment\";\r\n        }\r\n        if (this._scene.getEngine().isWebGPU) {\r\n            if (!IsWebGPUXREngineCompatible(this._scene.getEngine())) {\r\n                throw new Error(WebGPUXREngineNotCompatibleErrorMessage);\r\n            }\r\n            if (!WebXRSessionManager.IsWebGPUXRSupported) {\r\n                throw new Error(WebGPUXRNotSupportedErrorMessage);\r\n            }\r\n            if (!this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)) {\r\n                throw new Error(\"WebGPU XR requires the WebXR Layers feature. Import and enable WebXRLayers before calling enterXRAsync.\");\r\n            }\r\n            sessionCreationOptions = {\r\n                ...sessionCreationOptions,\r\n                requiredFeatures: sessionCreationOptions.requiredFeatures ? [...sessionCreationOptions.requiredFeatures] : undefined,\r\n                optionalFeatures: sessionCreationOptions.optionalFeatures ? [...sessionCreationOptions.optionalFeatures] : undefined,\r\n            };\r\n        }\r\n        renderTarget ??= this.sessionManager.getWebXRRenderTarget();\r\n        this._setState(WebXRState.ENTERING_XR);\r\n        if (referenceSpaceType !== \"viewer\" && referenceSpaceType !== \"local\") {\r\n            sessionCreationOptions.optionalFeatures = sessionCreationOptions.optionalFeatures || [];\r\n            sessionCreationOptions.optionalFeatures.push(referenceSpaceType);\r\n        }\r\n        sessionCreationOptions = await this.featuresManager._extendXRSessionInitObject(sessionCreationOptions);\r\n        if (this._scene.getEngine().isWebGPU) {\r\n            const requiredFeatures = sessionCreationOptions.requiredFeatures ? [...sessionCreationOptions.requiredFeatures] : [];\r\n            if (!requiredFeatures.includes(\"layers\")) {\r\n                requiredFeatures.push(\"layers\");\r\n            }\r\n            sessionCreationOptions = {\r\n                ...sessionCreationOptions,\r\n                requiredFeatures,\r\n                optionalFeatures: sessionCreationOptions.optionalFeatures?.filter((feature) => feature !== \"layers\"),\r\n            };\r\n        }\r\n        // we currently recommend \"unbounded\" space in AR (#7959)\r\n        if (sessionMode === \"immersive-ar\" && referenceSpaceType !== \"unbounded\") {\r\n            Logger.Warn(\"We recommend using 'unbounded' reference space type when using 'immersive-ar' session mode\");\r\n        }\r\n        this._originalSceneAutoClear = this._scene.autoClear;\r\n        this._nonVRCamera = this._scene.activeCamera;\r\n        this._attachedToElement = !!this._nonVRCamera?.inputs?.attachedToElement;\r\n        let sceneStateChanged = false;\r\n        const sessionEndedObserver = this.sessionManager.onXRSessionEnded.add(\r\n            () => {\r\n                // when using the back button and not the exit button (default on mobile), the session is ending but the EXITING state was not set\r\n                if (this.state !== WebXRState.EXITING_XR) {\r\n                    this._setState(WebXRState.EXITING_XR);\r\n                }\r\n                if (sceneStateChanged) {\r\n                    // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends\r\n                    for (const c of this.camera.rigCameras) {\r\n                        c.outputRenderTarget = null;\r\n                    }\r\n\r\n                    // Restore scene settings\r\n                    this._scene.autoClear = this._originalSceneAutoClear;\r\n                    this._scene.activeCamera = this._nonVRCamera;\r\n                    if (this._attachedToElement && this._nonVRCamera) {\r\n                        this._nonVRCamera.attachControl(!!this._nonVRCamera.inputs.noPreventDefault);\r\n                    }\r\n                    if (sessionMode !== \"immersive-ar\" && this.camera.compensateOnFirstFrame) {\r\n                        if ((<any>this._nonVRCamera).setPosition) {\r\n                            (<any>this._nonVRCamera).setPosition(this.camera.position);\r\n                        } else {\r\n                            this._nonVRCamera!.position.copyFrom(this.camera.position);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                this._setState(WebXRState.NOT_IN_XR);\r\n            },\r\n            undefined,\r\n            // Restore the scene before feature observers in case one of them throws during teardown.\r\n            true,\r\n            undefined,\r\n            true\r\n        );\r\n        // make sure that the session mode is supported\r\n        try {\r\n            await this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);\r\n            await this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);\r\n\r\n            const xrRenderState: XRRenderStateInit = {\r\n                // if maxZ is 0 it should be \"Infinity\", but it doesn't work with the WebXR API. Setting to a large number.\r\n                depthFar: this.camera.maxZ || 10000,\r\n                depthNear: this.camera.minZ,\r\n            };\r\n\r\n            // The layers feature will have already initialized the XR session's layers on session init.\r\n            // WebGPU-XR is layers-only, while WebGL can continue to use the legacy base-layer path.\r\n            if (!this._scene.getEngine().isWebGPU && !this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)) {\r\n                const baseLayer = await renderTarget.initializeXRLayerAsync(this.sessionManager.session);\r\n                xrRenderState.baseLayer = baseLayer;\r\n            }\r\n\r\n            this.sessionManager.updateRenderState(xrRenderState);\r\n            // run the render loop\r\n            this.sessionManager.runXRRenderLoop();\r\n            // Switch the scene to the XR camera.\r\n            sceneStateChanged = true;\r\n            this._nonVRCamera?.detachControl();\r\n\r\n            this._scene.activeCamera = this.camera;\r\n            // do not compensate when AR session is used\r\n            if (sessionMode !== \"immersive-ar\") {\r\n                this._nonXRToXRCamera();\r\n            } else {\r\n                // Kept here, TODO - check if needed\r\n                this._scene.autoClear = false;\r\n                this.camera.compensateOnFirstFrame = false;\r\n                // reset the camera's position to the origin\r\n                this.camera.position.set(0, 0, 0);\r\n                this.camera.rotationQuaternion.set(0, 0, 0, 1);\r\n                this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n            }\r\n\r\n            // Vision Pro suspends the audio context when entering XR, so we resume it here if needed.\r\n            AbstractEngine.audioEngine?._resumeAudioContextOnStateChange();\r\n\r\n            // Wait until the first frame arrives before setting state to in xr\r\n            this.sessionManager.onXRFrameObservable.addOnce(() => {\r\n                this._setState(WebXRState.IN_XR);\r\n            });\r\n            return this.sessionManager;\r\n        } catch (e) {\r\n            if (this.sessionManager.inXRSession) {\r\n                await this.sessionManager.exitXRAsync();\r\n            }\r\n            if (!this.sessionManager.inXRSession) {\r\n                this.sessionManager.onXRSessionEnded.remove(sessionEndedObserver);\r\n            }\r\n            Logger.Log(e);\r\n            Logger.Log(e.message);\r\n            this._setState(this.sessionManager.inXRSession ? WebXRState.ENTERING_XR : WebXRState.NOT_IN_XR);\r\n            throw e;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Exits XR mode and returns the scene to its original state\r\n     * @returns promise that resolves after xr mode has exited\r\n     */\r\n    public async exitXRAsync() {\r\n        const isSessionStarting = this.state === WebXRState.ENTERING_XR && this.sessionManager.inXRSession;\r\n        if (this.state !== WebXRState.IN_XR && !isSessionStarting) {\r\n            return;\r\n        }\r\n        const previousState = this.state;\r\n        this._setState(WebXRState.EXITING_XR);\r\n        await this.sessionManager.exitXRAsync();\r\n        if (this.sessionManager.inXRSession) {\r\n            this._setState(previousState);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enable spectator mode for desktop VR experiences.\r\n     * When spectator mode is enabled a camera will be attached to the desktop canvas and will\r\n     * display the first rig camera's view on the desktop canvas.\r\n     * Please note that this will degrade performance, as it requires another camera render.\r\n     * It is also not recommended to enable this in devices like the quest, as it brings no benefit there.\r\n     * @param options giving WebXRSpectatorModeOption for specutator camera to setup when the spectator mode is enabled.\r\n     */\r\n    public enableSpectatorMode(options?: WebXRSpectatorModeOption): void {\r\n        if (!this._spectatorMode) {\r\n            this._spectatorMode = true;\r\n            this._switchSpectatorMode(options);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disable spectator mode for desktop VR experiences.\r\n     */\r\n    public disableSpecatatorMode(): void {\r\n        if (this._spectatorMode) {\r\n            this._spectatorMode = false;\r\n            this._switchSpectatorMode();\r\n        }\r\n    }\r\n\r\n    private _clearSpectatorObservers() {\r\n        this.sessionManager.onXRFrameObservable.remove(this._spectatorXRFrameObserver);\r\n        this._spectatorXRFrameObserver = null;\r\n        this._scene.onAfterRenderCameraObservable.remove(this._spectatorAfterRenderObserver);\r\n        this._spectatorAfterRenderObserver = null;\r\n        this.onStateChangedObservable.remove(this._spectatorStateChangedObserver);\r\n        this._spectatorStateChangedObserver = null;\r\n    }\r\n\r\n    private _switchSpectatorMode(options?: WebXRSpectatorModeOption): void {\r\n        this._clearSpectatorObservers();\r\n\r\n        const fps = options?.fps ? options.fps : 1000.0;\r\n        const refreshRate = (1.0 / fps) * 1000.0;\r\n        const cameraIndex = options?.preferredCameraIndex ? options?.preferredCameraIndex : 0;\r\n\r\n        const updateSpectatorCamera = () => {\r\n            if (this._spectatorCamera) {\r\n                const delta = this.sessionManager.currentTimestamp - this._lastTimestamp;\r\n                if (delta >= refreshRate) {\r\n                    this._lastTimestamp = this.sessionManager.currentTimestamp;\r\n                    this._spectatorCamera.position.copyFrom(this.camera.rigCameras[cameraIndex].globalPosition);\r\n                    this._spectatorCamera.rotationQuaternion?.copyFrom(this.camera.rigCameras[cameraIndex].absoluteRotation);\r\n                }\r\n            }\r\n        };\r\n        if (this._spectatorMode) {\r\n            if (cameraIndex >= this.camera.rigCameras.length) {\r\n                throw new Error(\"the preferred camera index is beyond the length of rig camera array.\");\r\n            }\r\n            const onStateChanged = () => {\r\n                if (this.state === WebXRState.IN_XR) {\r\n                    this._spectatorCamera?.dispose();\r\n                    this._spectatorCamera = new UniversalCamera(\"webxr-spectator\", Vector3.Zero(), this._scene);\r\n                    this._spectatorCamera.rotationQuaternion = new Quaternion();\r\n                    this._scene.activeCameras = [this.camera, this._spectatorCamera];\r\n                    this._spectatorXRFrameObserver = this.sessionManager.onXRFrameObservable.add(updateSpectatorCamera);\r\n                    this._spectatorAfterRenderObserver = this._scene.onAfterRenderCameraObservable.add((camera) => {\r\n                        if (camera === this.camera) {\r\n                            // reset the dimensions object for correct resizing\r\n                            this._scene.getEngine().framebufferDimensionsObject = null;\r\n                        }\r\n                    });\r\n                } else if (this.state === WebXRState.EXITING_XR) {\r\n                    this.sessionManager.onXRFrameObservable.remove(this._spectatorXRFrameObserver);\r\n                    this._spectatorXRFrameObserver = null;\r\n\r\n                    this._scene.onAfterRenderCameraObservable.remove(this._spectatorAfterRenderObserver);\r\n                    this._spectatorAfterRenderObserver = null;\r\n                    this._spectatorCamera?.dispose();\r\n                    this._spectatorCamera = null;\r\n                    this._scene.activeCameras = null;\r\n                }\r\n            };\r\n            this._spectatorStateChangedObserver = this.onStateChangedObservable.add(onStateChanged);\r\n            onStateChanged();\r\n        } else {\r\n            this._spectatorCamera?.dispose();\r\n            this._spectatorCamera = null;\r\n            this._scene.activeCameras = [this.camera];\r\n        }\r\n    }\r\n\r\n    private _nonXRToXRCamera() {\r\n        this.camera.setTransformationFromNonVRCamera(this._nonVRCamera!);\r\n        this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n    }\r\n\r\n    private _setState(val: WebXRState) {\r\n        if (this.state === val) {\r\n            return;\r\n        }\r\n        this.state = val;\r\n        this.onStateChangedObservable.notifyObservers(this.state);\r\n    }\r\n}\r\n","import { type IMinimalMotionControllerObject, type MotionControllerComponentType } from \"./webXRAbstractMotionController\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { type IDisposable } from \"../../scene\";\r\n\r\n/**\r\n * X-Y values for axes in WebXR\r\n */\r\nexport interface IWebXRMotionControllerAxesValue {\r\n    /**\r\n     * The value of the x axis\r\n     */\r\n    x: number;\r\n    /**\r\n     * The value of the y-axis\r\n     */\r\n    y: number;\r\n}\r\n\r\n/**\r\n * changed / previous values for the values of this component\r\n */\r\nexport interface IWebXRMotionControllerComponentChangesValues<T> {\r\n    /**\r\n     * current (this frame) value\r\n     */\r\n    current: T;\r\n    /**\r\n     * previous (last change) value\r\n     */\r\n    previous: T;\r\n}\r\n\r\n/**\r\n * Represents changes in the component between current frame and last values recorded\r\n */\r\nexport interface IWebXRMotionControllerComponentChanges {\r\n    /**\r\n     * will be populated with previous and current values if axes changed\r\n     */\r\n    axes?: IWebXRMotionControllerComponentChangesValues<IWebXRMotionControllerAxesValue>;\r\n    /**\r\n     * will be populated with previous and current values if pressed changed\r\n     */\r\n    pressed?: IWebXRMotionControllerComponentChangesValues<boolean>;\r\n    /**\r\n     * will be populated with previous and current values if touched changed\r\n     */\r\n    touched?: IWebXRMotionControllerComponentChangesValues<boolean>;\r\n    /**\r\n     * will be populated with previous and current values if value changed\r\n     */\r\n    value?: IWebXRMotionControllerComponentChangesValues<number>;\r\n}\r\n/**\r\n * This class represents a single component (for example button or thumbstick) of a motion controller\r\n */\r\nexport class WebXRControllerComponent implements IDisposable {\r\n    private _axes: IWebXRMotionControllerAxesValue = {\r\n        x: 0,\r\n        y: 0,\r\n    };\r\n    private _changes: IWebXRMotionControllerComponentChanges = {};\r\n    private _currentValue: number = 0;\r\n    private _hasChanges: boolean = false;\r\n    private _pressed: boolean = false;\r\n    private _touched: boolean = false;\r\n\r\n    /**\r\n     * button component type\r\n     */\r\n    public static BUTTON_TYPE: MotionControllerComponentType = \"button\";\r\n    /**\r\n     * squeeze component type\r\n     */\r\n    public static SQUEEZE_TYPE: MotionControllerComponentType = \"squeeze\";\r\n    /**\r\n     * Thumbstick component type\r\n     */\r\n    public static THUMBSTICK_TYPE: MotionControllerComponentType = \"thumbstick\";\r\n    /**\r\n     * Touchpad component type\r\n     */\r\n    public static TOUCHPAD_TYPE: MotionControllerComponentType = \"touchpad\";\r\n    /**\r\n     * trigger component type\r\n     */\r\n    public static TRIGGER_TYPE: MotionControllerComponentType = \"trigger\";\r\n\r\n    /**\r\n     * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when\r\n     * the axes data changes\r\n     */\r\n    public onAxisValueChangedObservable: Observable<{ x: number; y: number }> = new Observable();\r\n    /**\r\n     * Observers registered here will be triggered when the state of a button changes\r\n     * State change is either pressed / touched / value\r\n     */\r\n    public onButtonStateChangedObservable: Observable<WebXRControllerComponent> = new Observable();\r\n\r\n    /**\r\n     * Creates a new component for a motion controller.\r\n     * It is created by the motion controller itself\r\n     *\r\n     * @param id the id of this component\r\n     * @param type the type of the component\r\n     * @param _buttonIndex index in the buttons array of the gamepad\r\n     * @param _axesIndices indices of the values in the axes array of the gamepad\r\n     */\r\n    constructor(\r\n        /**\r\n         * the id of this component\r\n         */\r\n        public id: string,\r\n        /**\r\n         * the type of the component\r\n         */\r\n        public type: MotionControllerComponentType,\r\n        private _buttonIndex: number = -1,\r\n        private _axesIndices: number[] = []\r\n    ) {}\r\n\r\n    /**\r\n     * The current axes data. If this component has no axes it will still return an object { x: 0, y: 0 }\r\n     */\r\n    public get axes(): IWebXRMotionControllerAxesValue {\r\n        return this._axes;\r\n    }\r\n\r\n    /**\r\n     * Get the changes. Elements will be populated only if they changed with their previous and current value\r\n     */\r\n    public get changes(): IWebXRMotionControllerComponentChanges {\r\n        return this._changes;\r\n    }\r\n\r\n    /**\r\n     * Return whether or not the component changed the last frame\r\n     */\r\n    public get hasChanges(): boolean {\r\n        return this._hasChanges;\r\n    }\r\n\r\n    /**\r\n     * is the button currently pressed\r\n     */\r\n    public get pressed(): boolean {\r\n        return this._pressed;\r\n    }\r\n\r\n    /**\r\n     * is the button currently touched\r\n     */\r\n    public get touched(): boolean {\r\n        return this._touched;\r\n    }\r\n\r\n    /**\r\n     * Get the current value of this component\r\n     */\r\n    public get value(): number {\r\n        return this._currentValue;\r\n    }\r\n\r\n    /**\r\n     * Dispose this component\r\n     */\r\n    public dispose(): void {\r\n        this.onAxisValueChangedObservable.clear();\r\n        this.onButtonStateChangedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Are there axes correlating to this component\r\n     * @returns true is axes data is available\r\n     */\r\n    public isAxes(): boolean {\r\n        return this._axesIndices.length !== 0;\r\n    }\r\n\r\n    /**\r\n     * Is this component a button (hence - pressable)\r\n     * @returns true if can be pressed\r\n     */\r\n    public isButton(): boolean {\r\n        return this._buttonIndex !== -1;\r\n    }\r\n\r\n    /**\r\n     * update this component using the gamepad object it is in. Called on every frame\r\n     * @param nativeController the native gamepad controller object\r\n     */\r\n    public update(nativeController: IMinimalMotionControllerObject) {\r\n        let buttonUpdated = false;\r\n        let axesUpdate = false;\r\n        this._hasChanges = false;\r\n        this._changes = {};\r\n\r\n        if (this.isButton()) {\r\n            const button = nativeController.buttons[this._buttonIndex];\r\n            // defensive, in case a profile was forced\r\n            if (!button) {\r\n                return;\r\n            }\r\n            if (this._currentValue !== button.value) {\r\n                this.changes.value = {\r\n                    current: button.value,\r\n                    previous: this._currentValue,\r\n                };\r\n                buttonUpdated = true;\r\n                this._currentValue = button.value;\r\n            }\r\n            if (this._touched !== button.touched) {\r\n                this.changes.touched = {\r\n                    current: button.touched,\r\n                    previous: this._touched,\r\n                };\r\n                buttonUpdated = true;\r\n                this._touched = button.touched;\r\n            }\r\n            if (this._pressed !== button.pressed) {\r\n                this.changes.pressed = {\r\n                    current: button.pressed,\r\n                    previous: this._pressed,\r\n                };\r\n                buttonUpdated = true;\r\n                this._pressed = button.pressed;\r\n            }\r\n        }\r\n\r\n        if (this.isAxes()) {\r\n            if (this._axes.x !== nativeController.axes[this._axesIndices[0]]) {\r\n                this.changes.axes = {\r\n                    current: {\r\n                        x: nativeController.axes[this._axesIndices[0]],\r\n                        y: this._axes.y,\r\n                    },\r\n                    previous: {\r\n                        x: this._axes.x,\r\n                        y: this._axes.y,\r\n                    },\r\n                };\r\n                this._axes.x = nativeController.axes[this._axesIndices[0]];\r\n                axesUpdate = true;\r\n            }\r\n\r\n            if (this._axes.y !== nativeController.axes[this._axesIndices[1]]) {\r\n                if (this.changes.axes) {\r\n                    this.changes.axes.current.y = nativeController.axes[this._axesIndices[1]];\r\n                } else {\r\n                    this.changes.axes = {\r\n                        current: {\r\n                            x: this._axes.x,\r\n                            y: nativeController.axes[this._axesIndices[1]],\r\n                        },\r\n                        previous: {\r\n                            x: this._axes.x,\r\n                            y: this._axes.y,\r\n                        },\r\n                    };\r\n                }\r\n                this._axes.y = nativeController.axes[this._axesIndices[1]];\r\n                axesUpdate = true;\r\n            }\r\n        }\r\n\r\n        if (buttonUpdated) {\r\n            this._hasChanges = true;\r\n            this.onButtonStateChangedObservable.notifyObservers(this);\r\n        }\r\n        if (axesUpdate) {\r\n            this._hasChanges = true;\r\n            this.onAxisValueChangedObservable.notifyObservers(this._axes);\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type DeepImmutable, type Nullable } from \"../types\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type AnimationGroup } from \"../Animations/animationGroup\";\r\nimport { type AssetContainer } from \"../assetContainer\";\r\nimport { type IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport { type Skeleton } from \"../Bones/skeleton\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { SceneLoaderFlags } from \"./sceneLoaderFlags\";\r\nimport { type IFileRequest } from \"../Misc/fileRequest\";\r\nimport { type WebRequest } from \"../Misc/webRequest\";\r\nimport { type LoadFileError, IsBase64DataUrl } from \"../Misc/fileTools.pure\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type Geometry } from \"../Meshes/geometry\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { RuntimeError, ErrorCodes } from \"../Misc/error\";\r\nimport { type ISpriteManager } from \"../Sprites/spriteManager\";\r\nimport { RandomGUID } from \"../Misc/guid\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { _FetchAsync } from \"core/Misc/webRequest.fetch\";\r\n\r\n/**\r\n * Type used for the success callback of ImportMesh\r\n */\r\nexport type SceneLoaderSuccessCallback = (\r\n    meshes: AbstractMesh[],\r\n    particleSystems: IParticleSystem[],\r\n    skeletons: Skeleton[],\r\n    animationGroups: AnimationGroup[],\r\n    transformNodes: TransformNode[],\r\n    geometries: Geometry[],\r\n    lights: Light[],\r\n    spriteManagers: ISpriteManager[]\r\n) => void;\r\n\r\n/**\r\n * Interface used for the result of ImportMeshAsync\r\n */\r\nexport interface ISceneLoaderAsyncResult {\r\n    /**\r\n     * The array of loaded meshes\r\n     */\r\n    readonly meshes: AbstractMesh[];\r\n\r\n    /**\r\n     * The array of loaded particle systems\r\n     */\r\n    readonly particleSystems: IParticleSystem[];\r\n\r\n    /**\r\n     * The array of loaded skeletons\r\n     */\r\n    readonly skeletons: Skeleton[];\r\n\r\n    /**\r\n     * The array of loaded animation groups\r\n     */\r\n    readonly animationGroups: AnimationGroup[];\r\n\r\n    /**\r\n     * The array of loaded transform nodes\r\n     */\r\n    readonly transformNodes: TransformNode[];\r\n\r\n    /**\r\n     * The array of loaded geometries\r\n     */\r\n    readonly geometries: Geometry[];\r\n\r\n    /**\r\n     * The array of loaded lights\r\n     */\r\n    readonly lights: Light[];\r\n\r\n    /**\r\n     * The array of loaded sprite managers\r\n     */\r\n    readonly spriteManagers: ISpriteManager[];\r\n}\r\n\r\n/**\r\n * Interface used to represent data loading progression\r\n */\r\nexport interface ISceneLoaderProgressEvent {\r\n    /**\r\n     * Defines if data length to load can be evaluated\r\n     */\r\n    readonly lengthComputable: boolean;\r\n\r\n    /**\r\n     * Defines the loaded data length\r\n     */\r\n    readonly loaded: number;\r\n\r\n    /**\r\n     * Defines the data length to load\r\n     */\r\n    readonly total: number;\r\n}\r\n\r\n/**\r\n * Interface used by SceneLoader plugins to define supported file extensions\r\n */\r\nexport interface ISceneLoaderPluginExtensions {\r\n    /**\r\n     * Defines the list of supported extensions\r\n     */\r\n    readonly [extension: string]: {\r\n        readonly isBinary: boolean;\r\n        readonly mimeType?: string;\r\n    };\r\n}\r\n\r\n/**\r\n * Metadata for a SceneLoader plugin that must also be provided by a plugin factory\r\n */\r\nexport interface ISceneLoaderPluginMetadata {\r\n    /**\r\n     * The friendly name of the plugin.\r\n     */\r\n    readonly name: string;\r\n\r\n    /**\r\n     * The file extensions supported by the plugin.\r\n     */\r\n    readonly extensions: string | ISceneLoaderPluginExtensions;\r\n\r\n    /**\r\n     * The callback that returns true if the data can be directly loaded.\r\n     * @param data string containing the file data\r\n     * @returns if the data can be loaded directly\r\n     */\r\n    canDirectLoad?(data: string): boolean;\r\n}\r\n\r\n/**\r\n * Interface used by SceneLoader plugin factory\r\n */\r\nexport interface ISceneLoaderPluginFactory extends ISceneLoaderPluginMetadata {\r\n    /**\r\n     * Function called to create a new plugin\r\n     * @param options plugin options that were passed to the SceneLoader operation\r\n     * @returns the new plugin\r\n     */\r\n    createPlugin(options: SceneLoaderPluginOptions): ISceneLoaderPlugin | ISceneLoaderPluginAsync | Promise<ISceneLoaderPlugin | ISceneLoaderPluginAsync>;\r\n}\r\n\r\n/**\r\n * Interface used to define the base of ISceneLoaderPlugin and ISceneLoaderPluginAsync\r\n */\r\nexport interface ISceneLoaderPluginBase extends ISceneLoaderPluginMetadata {\r\n    /**\r\n     * The callback called when loading from a url.\r\n     * @param scene scene loading this url\r\n     * @param fileOrUrl file or url to load\r\n     * @param rootUrl root url to use to load assets\r\n     * @param onSuccess callback called when the file successfully loads\r\n     * @param onProgress callback called while file is loading (if the server supports this mode)\r\n     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer\r\n     * @param onError callback called when the file fails to load\r\n     * @param name defines the name of the file when loading a binary file\r\n     * @returns a file request object\r\n     */\r\n    loadFile?(\r\n        scene: Scene,\r\n        fileOrUrl: File | string | ArrayBufferView,\r\n        rootUrl: string,\r\n        onSuccess: (data: unknown, responseURL?: string) => void,\r\n        onProgress?: (ev: ISceneLoaderProgressEvent) => void,\r\n        useArrayBuffer?: boolean,\r\n        onError?: (request?: WebRequest, exception?: LoadFileError) => void,\r\n        name?: string\r\n    ): Nullable<IFileRequest>;\r\n\r\n    /**\r\n     * The callback that returns the data to pass to the plugin if the data can be directly loaded.\r\n     * @param scene scene loading this data\r\n     * @param data string containing the data\r\n     * @returns data to pass to the plugin\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\r\n    directLoad?(scene: Scene, data: string): unknown | Promise<unknown>;\r\n\r\n    /**\r\n     * The callback that allows custom handling of the root url based on the response url.\r\n     * @param rootUrl the original root url\r\n     * @param responseURL the response url if available\r\n     * @returns the new root url\r\n     */\r\n    rewriteRootURL?(rootUrl: string, responseURL?: string): string;\r\n}\r\n\r\n/**\r\n * Interface used to define a SceneLoader plugin\r\n */\r\nexport interface ISceneLoaderPlugin extends ISceneLoaderPluginBase {\r\n    /**\r\n     * Import meshes into a scene.\r\n     * @param meshesNames An array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported\r\n     * @param scene The scene to import into\r\n     * @param data The data to import\r\n     * @param rootUrl The root url for scene and resources\r\n     * @param meshes The meshes array to import into\r\n     * @param particleSystems The particle systems array to import into\r\n     * @param skeletons The skeletons array to import into\r\n     * @param onError The callback when import fails\r\n     * @returns True if successful or false otherwise\r\n     */\r\n    importMesh(\r\n        meshesNames: string | readonly string[] | null | undefined,\r\n        scene: Scene,\r\n        data: unknown,\r\n        rootUrl: string,\r\n        meshes: AbstractMesh[],\r\n        particleSystems: IParticleSystem[],\r\n        skeletons: Skeleton[],\r\n        onError?: (message: string, exception?: any) => void\r\n    ): boolean;\r\n\r\n    /**\r\n     * Load into a scene.\r\n     * @param scene The scene to load into\r\n     * @param data The data to import\r\n     * @param rootUrl The root url for scene and resources\r\n     * @param onError The callback when import fails\r\n     * @returns True if successful or false otherwise\r\n     */\r\n    load(scene: Scene, data: unknown, rootUrl: string, onError?: (message: string, exception?: any) => void): boolean;\r\n\r\n    /**\r\n     * Load into an asset container.\r\n     * @param scene The scene to load into\r\n     * @param data The data to import\r\n     * @param rootUrl The root url for scene and resources\r\n     * @param onError The callback when import fails\r\n     * @returns The loaded asset container\r\n     */\r\n    loadAssetContainer(scene: Scene, data: unknown, rootUrl: string, onError?: (message: string, exception?: any) => void): AssetContainer;\r\n}\r\n\r\n/**\r\n * Interface used to define an async SceneLoader plugin\r\n */\r\nexport interface ISceneLoaderPluginAsync extends ISceneLoaderPluginBase {\r\n    /**\r\n     * Import meshes into a scene.\r\n     * @param meshesNames An array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported\r\n     * @param scene The scene to import into\r\n     * @param data The data to import\r\n     * @param rootUrl The root url for scene and resources\r\n     * @param onProgress The callback when the load progresses\r\n     * @param fileName Defines the name of the file to load\r\n     * @returns The loaded objects (e.g. meshes, particle systems, skeletons, animation groups, etc.)\r\n     */\r\n    importMeshAsync(\r\n        meshesNames: string | readonly string[] | null | undefined,\r\n        scene: Scene,\r\n        data: unknown,\r\n        rootUrl: string,\r\n        onProgress?: (event: ISceneLoaderProgressEvent) => void,\r\n        fileName?: string\r\n    ): Promise<ISceneLoaderAsyncResult>;\r\n\r\n    /**\r\n     * Load into a scene.\r\n     * @param scene The scene to load into\r\n     * @param data The data to import\r\n     * @param rootUrl The root url for scene and resources\r\n     * @param onProgress The callback when the load progresses\r\n     * @param fileName Defines the name of the file to load\r\n     * @returns Nothing\r\n     */\r\n    loadAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<void>;\r\n\r\n    /**\r\n     * Load into an asset container.\r\n     * @param scene The scene to load into\r\n     * @param data The data to import\r\n     * @param rootUrl The root url for scene and resources\r\n     * @param onProgress The callback when the load progresses\r\n     * @param fileName Defines the name of the file to load\r\n     * @returns The loaded asset container\r\n     */\r\n    loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer>;\r\n}\r\n\r\n/**\r\n * Mode that determines how to handle old animation groups before loading new ones.\r\n */\r\nexport const enum SceneLoaderAnimationGroupLoadingMode {\r\n    /**\r\n     * Reset all old animations to initial state then dispose them.\r\n     */\r\n    Clean = 0,\r\n\r\n    /**\r\n     * Stop all old animations.\r\n     */\r\n    Stop = 1,\r\n\r\n    /**\r\n     * Restart old animations from first frame.\r\n     */\r\n    Sync = 2,\r\n\r\n    /**\r\n     * Old animations remains untouched.\r\n     */\r\n    NoSync = 3,\r\n}\r\n\r\n/**\r\n * Defines internal only plugin members.\r\n */\r\ninterface ISceneLoaderPluginInternal {\r\n    /**\r\n     * An optional observable to notify when the plugin is disposed\r\n     */\r\n    readonly onDisposeObservable: Observable<void>;\r\n}\r\n\r\n/**\r\n * A concrete (non-factory) SceneLoader plugin, which may be synchronous or asynchronous and may expose internal members.\r\n */\r\ntype SceneLoaderPlugin = (ISceneLoaderPlugin | ISceneLoaderPluginAsync) & Partial<ISceneLoaderPluginInternal>;\r\n\r\n/**\r\n * Defines a plugin registered by the SceneLoader\r\n */\r\ninterface IRegisteredPlugin {\r\n    /**\r\n     * Defines the plugin to use\r\n     */\r\n    plugin: SceneLoaderPlugin | ISceneLoaderPluginFactory;\r\n    /**\r\n     * Defines if the plugin supports binary data\r\n     */\r\n    isBinary: boolean;\r\n    mimeType?: string;\r\n}\r\n\r\nfunction IsFactory(pluginOrFactory: IRegisteredPlugin[\"plugin\"]): pluginOrFactory is ISceneLoaderPluginFactory {\r\n    return !!(pluginOrFactory as ISceneLoaderPluginFactory).createPlugin;\r\n}\r\n\r\n/**\r\n * Defines file information\r\n */\r\ninterface IFileInfo {\r\n    /**\r\n     * Gets the file url\r\n     */\r\n    url: string;\r\n    /**\r\n     * Gets the root url\r\n     */\r\n    rootUrl: string;\r\n    /**\r\n     * Gets filename\r\n     */\r\n    name: string;\r\n    /**\r\n     * Gets the file\r\n     */\r\n    file: Nullable<File>;\r\n\r\n    /**\r\n     * Gets raw binary data.\r\n     */\r\n    rawData: Nullable<ArrayBufferView>;\r\n}\r\n\r\n/**\r\n * Defines options for SceneLoader plugins. This interface is extended by specific plugins.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/naming-convention\r\nexport interface SceneLoaderPluginOptions extends Record<string, Record<string, unknown> | undefined> {}\r\n\r\n/**\r\n * Adds default/implicit options to plugin specific options.\r\n */\r\ntype DefaultPluginOptions<BasePluginOptions> = {\r\n    /**\r\n     * Defines if the plugin is enabled\r\n     */\r\n    enabled?: boolean;\r\n} & BasePluginOptions;\r\n\r\n// This captures the type defined inline for the pluginOptions property, which is just SceneLoaderPluginOptions wrapped with DefaultPluginOptions.\r\n// We do it this way rather than explicitly defining the type here and then using it in SceneLoaderOptions because we want the full expanded type\r\n// to show up in the user's intellisense to make it easier to understand what options are available.\r\nexport type PluginOptions = ISceneLoaderOptions[\"pluginOptions\"];\r\n\r\ntype SceneSource = string | File | ArrayBufferView;\r\n\r\n/**\r\n * Defines common options for loading operations performed by SceneLoader.\r\n */\r\ninterface ISceneLoaderOptions {\r\n    /**\r\n     * A string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     */\r\n    rootUrl?: string;\r\n\r\n    /**\r\n     * A callback with a progress event for each file being loaded\r\n     */\r\n    onProgress?: (event: ISceneLoaderProgressEvent) => void;\r\n\r\n    /**\r\n     * The extension used to determine the plugin\r\n     */\r\n    pluginExtension?: string;\r\n\r\n    /**\r\n     * Defines the filename, if the data is binary\r\n     */\r\n    name?: string;\r\n\r\n    /**\r\n     * Defines options for the registered plugins\r\n     */\r\n    pluginOptions?: {\r\n        // NOTE: This type is doing two things:\r\n        // 1. Adding an implicit 'enabled' property to the options for each plugin.\r\n        // 2. Creating a mapped type of all the options of all the plugins to make it just look like a consolidated plain object in intellisense for the user.\r\n        [Plugin in keyof SceneLoaderPluginOptions]?: {\r\n            [Option in keyof DefaultPluginOptions<SceneLoaderPluginOptions[Plugin]>]: DefaultPluginOptions<SceneLoaderPluginOptions[Plugin]>[Option];\r\n        };\r\n    };\r\n}\r\n\r\n/**\r\n * Defines options for ImportMeshAsync.\r\n */\r\nexport interface ImportMeshOptions extends ISceneLoaderOptions {\r\n    /**\r\n     * An array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported\r\n     */\r\n    meshNames?: string | readonly string[] | null | undefined;\r\n}\r\n\r\n/**\r\n * Defines options for LoadAsync.\r\n */\r\nexport interface LoadOptions extends ISceneLoaderOptions {}\r\n\r\n/**\r\n * Defines options for AppendAsync.\r\n */\r\nexport interface AppendOptions extends ISceneLoaderOptions {}\r\n\r\n/**\r\n * Defines options for LoadAssetContainerAsync.\r\n */\r\nexport interface LoadAssetContainerOptions extends ISceneLoaderOptions {}\r\n\r\n/**\r\n * Defines options for ImportAnimationsAsync.\r\n */\r\nexport interface ImportAnimationsOptions extends ISceneLoaderOptions {\r\n    /**\r\n     * When true, animations are cleaned before importing new ones. Animations are appended otherwise\r\n     */\r\n    overwriteAnimations?: boolean;\r\n\r\n    /**\r\n     * Defines how to handle old animations groups before importing new ones\r\n     */\r\n    animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode;\r\n\r\n    /**\r\n     * defines a function used to convert animation targets from loaded scene to current scene (default: search node by name)\r\n     */\r\n    targetConverter?: Nullable<(target: unknown) => unknown>;\r\n}\r\n\r\nfunction isFile(value: unknown): value is File {\r\n    return !!(value as File).name;\r\n}\r\n\r\nconst onPluginActivatedObservable = new Observable<ISceneLoaderPlugin | ISceneLoaderPluginAsync>();\r\nconst registeredPlugins: { [extension: string]: IRegisteredPlugin } = {};\r\nlet showingLoadingScreen = false;\r\n\r\nfunction getDefaultPlugin(): IRegisteredPlugin | undefined {\r\n    return registeredPlugins[\".babylon\"];\r\n}\r\n\r\nfunction getPluginForMimeType(mimeType: string): IRegisteredPlugin | undefined {\r\n    for (const registeredPluginKey in registeredPlugins) {\r\n        const registeredPlugin = registeredPlugins[registeredPluginKey];\r\n        if (registeredPlugin.mimeType === mimeType) {\r\n            return registeredPlugin;\r\n        }\r\n    }\r\n    return undefined;\r\n}\r\n\r\nfunction getPluginForExtension(extension: string, returnDefault: boolean): IRegisteredPlugin | undefined {\r\n    const registeredPlugin = registeredPlugins[extension];\r\n    if (registeredPlugin) {\r\n        return registeredPlugin;\r\n    }\r\n    Logger.Warn(\r\n        \"Unable to find a plugin to load \" +\r\n            extension +\r\n            \" files. Trying to use .babylon default plugin. To load from a specific filetype (eg. gltf) see: https://doc.babylonjs.com/features/featuresDeepDive/importers/loadingFileTypes\"\r\n    );\r\n    return returnDefault ? getDefaultPlugin() : undefined;\r\n}\r\n\r\nfunction isPluginForExtensionAvailable(extension: string): boolean {\r\n    return !!registeredPlugins[extension];\r\n}\r\n\r\nfunction getPluginForDirectLoad(data: string): IRegisteredPlugin | undefined {\r\n    for (const extension in registeredPlugins) {\r\n        const plugin = registeredPlugins[extension].plugin;\r\n\r\n        if (plugin.canDirectLoad && plugin.canDirectLoad(data)) {\r\n            return registeredPlugins[extension];\r\n        }\r\n    }\r\n\r\n    return getDefaultPlugin();\r\n}\r\n\r\nfunction getFilenameExtension(sceneFilename: string): string {\r\n    const queryStringPosition = sceneFilename.indexOf(\"?\");\r\n\r\n    if (queryStringPosition !== -1) {\r\n        sceneFilename = sceneFilename.substring(0, queryStringPosition);\r\n    }\r\n\r\n    const dotPosition = sceneFilename.lastIndexOf(\".\");\r\n\r\n    return sceneFilename.substring(dotPosition, sceneFilename.length).toLowerCase();\r\n}\r\n\r\nfunction getDirectLoad(sceneFilename: string): Nullable<string> {\r\n    if (sceneFilename.substring(0, 5) === \"data:\") {\r\n        return sceneFilename.substring(5);\r\n    }\r\n\r\n    return null;\r\n}\r\n\r\nfunction formatErrorMessage(fileInfo: IFileInfo, message?: string, exception?: any): string {\r\n    const fromLoad = fileInfo.rawData ? \"binary data\" : fileInfo.url;\r\n    let errorMessage = \"Unable to load from \" + fromLoad;\r\n\r\n    if (message) {\r\n        errorMessage += `: ${message}`;\r\n    } else if (exception) {\r\n        errorMessage += `: ${exception}`;\r\n    }\r\n\r\n    return errorMessage;\r\n}\r\n\r\n/**\r\n * The plugin instance and the loaded data produced by loadDataAsync.\r\n */\r\ntype LoadedPluginData = {\r\n    plugin: SceneLoaderPlugin;\r\n    data: unknown;\r\n    responseURL?: string;\r\n};\r\n\r\nfunction createLoadError(fileInfo: IFileInfo, message?: string, exception?: any): RuntimeError {\r\n    const errorMessage = formatErrorMessage(fileInfo, message, exception);\r\n    return new RuntimeError(errorMessage, ErrorCodes.SceneLoaderError, exception);\r\n}\r\n\r\nfunction getErrorMessage(error: unknown): string {\r\n    return error instanceof Error ? error.message : String(error);\r\n}\r\n\r\n// Converts an error into a SceneLoader RuntimeError, leaving an already-wrapped SceneLoader error untouched\r\n// so that it is not double-wrapped (which would duplicate the \"Unable to load from ...\" prefix).\r\nfunction toLoadError(fileInfo: IFileInfo, error: unknown): RuntimeError {\r\n    return error instanceof RuntimeError && error.errorCode === ErrorCodes.SceneLoaderError ? error : createLoadError(fileInfo, getErrorMessage(error), error);\r\n}\r\n\r\nconst loadAssetContainerNotSupportedMessage = \"LoadAssetContainer is not supported by this plugin. Plugin did not provide a loadAssetContainer or loadAssetContainerAsync method.\";\r\n\r\n// A synchronous plugin exposes the synchronous import/load methods; an asynchronous plugin exposes the *Async methods.\r\nfunction isSyncPlugin(plugin: SceneLoaderPlugin): plugin is ISceneLoaderPlugin & Partial<ISceneLoaderPluginInternal> {\r\n    const candidate = plugin as Partial<ISceneLoaderPlugin>;\r\n    return !!candidate.importMesh || !!candidate.load || !!candidate.loadAssetContainer;\r\n}\r\n\r\n// Adapts a synchronous ISceneLoaderPlugin into an ISceneLoaderPluginAsync so that callers can use a single\r\n// promise-based code path regardless of whether the underlying plugin is synchronous or asynchronous.\r\n// Asynchronous plugins are returned unchanged. The synchronous plugin reports failure via an onError callback\r\n// and/or a falsy return value; both are translated into a rejected promise.\r\nfunction toAsyncPlugin(plugin: SceneLoaderPlugin, fileInfo: IFileInfo): ISceneLoaderPluginAsync {\r\n    if (!isSyncPlugin(plugin)) {\r\n        return plugin;\r\n    }\r\n\r\n    const runSync = <T>(invoke: (onError: (message?: string, exception?: any) => void) => T): NonNullable<T> => {\r\n        let pluginError: { message?: string; exception?: any } | undefined;\r\n        const result = invoke((message, exception) => {\r\n            pluginError = { message, exception };\r\n        });\r\n        if (!result) {\r\n            throw createLoadError(fileInfo, pluginError?.message, pluginError?.exception);\r\n        }\r\n        return result;\r\n    };\r\n\r\n    return {\r\n        name: plugin.name,\r\n        extensions: plugin.extensions,\r\n        importMeshAsync: async (meshesNames, scene, data, rootUrl) => {\r\n            const meshes: AbstractMesh[] = [];\r\n            const particleSystems: IParticleSystem[] = [];\r\n            const skeletons: Skeleton[] = [];\r\n            runSync((onError) => plugin.importMesh(meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons, onError));\r\n            return { meshes, particleSystems, skeletons, animationGroups: [], transformNodes: [], geometries: [], lights: [], spriteManagers: [] };\r\n        },\r\n        loadAsync: async (scene, data, rootUrl) => {\r\n            runSync((onError) => plugin.load(scene, data, rootUrl, onError));\r\n        },\r\n        loadAssetContainerAsync: async (scene, data, rootUrl) => {\r\n            return runSync((onError) => plugin.loadAssetContainer(scene, data, rootUrl, onError));\r\n        },\r\n    };\r\n}\r\n\r\n// Reports a load failure to the legacy onError callback. The onError signature requires a Scene, but a scene\r\n// may not be available (e.g. the error occurred before any scene was created). In that case, fall back to\r\n// logging so the error handler does not throw a secondary error and mask the original failure.\r\nfunction reportLegacyLoadError(onError: Nullable<(scene: Scene, message: string, exception?: any) => void> | undefined, reportScene: Nullable<Scene>, error: unknown): void {\r\n    const message = getErrorMessage(error);\r\n    if (onError && reportScene) {\r\n        onError(reportScene, message, error);\r\n    } else {\r\n        Logger.Error(message);\r\n    }\r\n}\r\n\r\n// Wraps a user supplied progress callback so that an exception thrown by it is logged rather than\r\n// aborting the entire loading operation.\r\nfunction wrapProgress(onProgress: Nullable<(event: ISceneLoaderProgressEvent) => void> | undefined): ((event: ISceneLoaderProgressEvent) => void) | undefined {\r\n    if (!onProgress) {\r\n        return undefined;\r\n    }\r\n\r\n    return (event: ISceneLoaderProgressEvent) => {\r\n        try {\r\n            onProgress(event);\r\n        } catch (error) {\r\n            Logger.Warn(\"Error in onProgress callback: \" + getErrorMessage(error));\r\n        }\r\n    };\r\n}\r\n\r\nasync function loadDataAsync(\r\n    fileInfo: IFileInfo,\r\n    scene: Scene,\r\n    onProgress: ((event: ISceneLoaderProgressEvent) => void) | undefined,\r\n    pluginExtension: Nullable<string>,\r\n    name: string,\r\n    pluginOptions: PluginOptions\r\n): Promise<LoadedPluginData> {\r\n    const directLoad = getDirectLoad(fileInfo.url);\r\n\r\n    if (fileInfo.rawData && !pluginExtension) {\r\n        throw new Error(\"When using ArrayBufferView to load data the file extension must be provided.\");\r\n    }\r\n\r\n    const fileExtension = !directLoad && !pluginExtension ? getFilenameExtension(fileInfo.url) : \"\";\r\n\r\n    let registeredPlugin = pluginExtension\r\n        ? getPluginForExtension(pluginExtension, true)\r\n        : directLoad\r\n          ? getPluginForDirectLoad(fileInfo.url)\r\n          : getPluginForExtension(fileExtension, false);\r\n\r\n    if (!registeredPlugin && fileExtension) {\r\n        if (fileInfo.url && !fileInfo.url.startsWith(\"blob:\")) {\r\n            // Fetching head content to get the mime type\r\n            const response = await _FetchAsync(fileInfo.url, { method: \"HEAD\", responseHeaders: [\"Content-Type\"] });\r\n            const mimeType = response.headerValues ? response.headerValues[\"Content-Type\"] : \"\";\r\n            if (mimeType) {\r\n                registeredPlugin = getPluginForMimeType(mimeType);\r\n            }\r\n        }\r\n\r\n        if (!registeredPlugin) {\r\n            registeredPlugin = getDefaultPlugin();\r\n        }\r\n    }\r\n\r\n    if (!registeredPlugin) {\r\n        throw new Error(`No plugin or fallback for ${pluginExtension ?? fileInfo.url}`);\r\n    }\r\n\r\n    if (pluginOptions?.[registeredPlugin.plugin.name]?.enabled === false) {\r\n        throw new Error(`The '${registeredPlugin.plugin.name}' plugin is disabled via the loader options passed to the loading operation.`);\r\n    }\r\n\r\n    if (fileInfo.rawData && !registeredPlugin.isBinary) {\r\n        throw new Error(\"Loading from ArrayBufferView can not be used with plugins that don't support binary loading.\");\r\n    }\r\n\r\n    // For plugin factories, the plugin is instantiated on each SceneLoader operation. This makes options handling\r\n    // much simpler as we can just pass the options to the factory, rather than passing options through to every possible\r\n    // plugin call. Given this, options are only supported for plugins that provide a factory function.\r\n    let plugin: SceneLoaderPlugin;\r\n    if (IsFactory(registeredPlugin.plugin)) {\r\n        const pluginFactory = registeredPlugin.plugin;\r\n        try {\r\n            // Only await when the factory is actually asynchronous, so that for synchronous factories the plugin is\r\n            // instantiated (and onPluginActivatedObservable is notified) synchronously within the calling load operation.\r\n            const createdPlugin = pluginFactory.createPlugin((pluginOptions ?? {}) as SceneLoaderPluginOptions);\r\n            plugin = createdPlugin instanceof Promise ? await createdPlugin : createdPlugin;\r\n        } catch (error) {\r\n            throw createLoadError(fileInfo, \"Error instantiating plugin.\", error);\r\n        }\r\n    } else {\r\n        plugin = registeredPlugin.plugin;\r\n    }\r\n\r\n    if (!plugin) {\r\n        throw new Error(`The loader plugin corresponding to the '${pluginExtension}' file type has not been found. If using es6, please import the plugin you wish to use before.`);\r\n    }\r\n\r\n    onPluginActivatedObservable.notifyObservers(plugin);\r\n\r\n    // Check if we have a direct load url. If the plugin is registered to handle\r\n    // it or it's not a base64 data url, then pass it through the direct load path.\r\n    if (directLoad && ((plugin.canDirectLoad && plugin.canDirectLoad(fileInfo.url)) || !IsBase64DataUrl(fileInfo.url))) {\r\n        if (plugin.directLoad) {\r\n            let data: unknown;\r\n            try {\r\n                data = await plugin.directLoad(scene, directLoad);\r\n            } catch (error) {\r\n                throw createLoadError(fileInfo, \"Error in directLoad of _loadData: \" + error, error);\r\n            }\r\n            return { plugin, data };\r\n        }\r\n        return { plugin, data: directLoad };\r\n    }\r\n\r\n    const useArrayBuffer = registeredPlugin.isBinary;\r\n\r\n    return await new Promise<LoadedPluginData>((resolve, reject) => {\r\n        let request: Nullable<IFileRequest> = null;\r\n        let pluginDisposed = false;\r\n\r\n        const onDisposeObserver = plugin.onDisposeObservable?.add(() => {\r\n            pluginDisposed = true;\r\n\r\n            if (request) {\r\n                request.abort();\r\n                request = null;\r\n            }\r\n\r\n            rejectAndCleanup(createLoadError(fileInfo, \"Loading was aborted because the plugin was disposed.\"));\r\n        });\r\n\r\n        // Ensure the onDispose observer is removed once the promise settles, so observers do not accumulate across loads.\r\n        const cleanup = () => {\r\n            if (onDisposeObserver) {\r\n                plugin.onDisposeObservable?.remove(onDisposeObserver);\r\n            }\r\n        };\r\n        const resolveAndCleanup = (value: LoadedPluginData) => {\r\n            cleanup();\r\n            resolve(value);\r\n        };\r\n        const rejectAndCleanup = (error: Error) => {\r\n            cleanup();\r\n            reject(error);\r\n        };\r\n\r\n        const dataCallback = (data: unknown, responseURL?: string) => {\r\n            if (scene.isDisposed) {\r\n                rejectAndCleanup(createLoadError(fileInfo, \"Scene has been disposed\"));\r\n                return;\r\n            }\r\n\r\n            resolveAndCleanup({ plugin, data, responseURL });\r\n        };\r\n\r\n        const manifestChecked = () => {\r\n            if (pluginDisposed) {\r\n                return;\r\n            }\r\n\r\n            const errorCallback = (request?: WebRequest, exception?: LoadFileError) => {\r\n                rejectAndCleanup(createLoadError(fileInfo, request?.statusText, exception));\r\n            };\r\n\r\n            if (!plugin.loadFile && fileInfo.rawData) {\r\n                rejectAndCleanup(createLoadError(fileInfo, \"Plugin does not support loading ArrayBufferView.\"));\r\n                return;\r\n            }\r\n\r\n            try {\r\n                request = plugin.loadFile\r\n                    ? plugin.loadFile(scene, fileInfo.rawData || fileInfo.file || fileInfo.url, fileInfo.rootUrl, dataCallback, onProgress, useArrayBuffer, errorCallback, name)\r\n                    : scene._loadFile(fileInfo.file || fileInfo.url, dataCallback, onProgress, true, useArrayBuffer, errorCallback);\r\n            } catch (error) {\r\n                rejectAndCleanup(createLoadError(fileInfo, undefined, error));\r\n            }\r\n        };\r\n\r\n        const engine = scene.getEngine();\r\n        // File objects and raw data buffers are already in-memory and are not URL-backed requests, so they must\r\n        // not be routed through the offline (manifest/cache) provider.\r\n        let canUseOfflineSupport = !fileInfo.file && !fileInfo.rawData && engine.enableOfflineSupport;\r\n        if (canUseOfflineSupport) {\r\n            // Also check for exceptions\r\n            let exceptionFound = false;\r\n            for (const regex of scene.disableOfflineSupportExceptionRules) {\r\n                if (regex.test(fileInfo.url)) {\r\n                    exceptionFound = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            canUseOfflineSupport = !exceptionFound;\r\n        }\r\n\r\n        if (canUseOfflineSupport && AbstractEngine.OfflineProviderFactory) {\r\n            // Checking if a manifest file has been set for this scene and if offline mode has been requested\r\n            try {\r\n                scene.offlineProvider = AbstractEngine.OfflineProviderFactory(fileInfo.url, manifestChecked, engine.disableManifestCheck);\r\n            } catch (error) {\r\n                rejectAndCleanup(createLoadError(fileInfo, undefined, error));\r\n            }\r\n        } else {\r\n            manifestChecked();\r\n        }\r\n    });\r\n}\r\n\r\nfunction GetFileInfo(rootUrl: string, sceneSource: SceneSource): Nullable<IFileInfo> {\r\n    let url: string;\r\n    let name: string;\r\n    let file: Nullable<File> = null;\r\n    let rawData: Nullable<ArrayBufferView> = null;\r\n\r\n    if (!sceneSource) {\r\n        url = rootUrl;\r\n        name = Tools.GetFilename(rootUrl);\r\n        rootUrl = Tools.GetFolderPath(rootUrl);\r\n    } else if (isFile(sceneSource)) {\r\n        url = `file:${sceneSource.name}`;\r\n        name = sceneSource.name;\r\n        file = sceneSource;\r\n    } else if (ArrayBuffer.isView(sceneSource)) {\r\n        url = \"\";\r\n        name = RandomGUID();\r\n        rawData = sceneSource;\r\n    } else if (sceneSource.startsWith(\"data:\")) {\r\n        url = sceneSource;\r\n        name = \"\";\r\n    } else if (rootUrl) {\r\n        const filename = sceneSource;\r\n        if (filename.substring(0, 1) === \"/\") {\r\n            Tools.Error(\"Wrong sceneFilename parameter\");\r\n            return null;\r\n        }\r\n\r\n        url = rootUrl + filename;\r\n        name = filename;\r\n    } else {\r\n        url = sceneSource;\r\n        name = Tools.GetFilename(sceneSource);\r\n        rootUrl = Tools.GetFolderPath(sceneSource);\r\n    }\r\n\r\n    return {\r\n        url: url,\r\n        rootUrl: rootUrl,\r\n        name: name,\r\n        file: file,\r\n        rawData,\r\n    };\r\n}\r\n\r\n/**\r\n * Adds a new plugin to the list of registered plugins\r\n * @param plugin defines the plugin to add\r\n */\r\nexport function RegisterSceneLoaderPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync | ISceneLoaderPluginFactory): void {\r\n    if (typeof plugin.extensions === \"string\") {\r\n        const extension = plugin.extensions;\r\n        registeredPlugins[extension.toLowerCase()] = {\r\n            plugin: plugin,\r\n            isBinary: false,\r\n        };\r\n    } else {\r\n        const extensions = plugin.extensions;\r\n        const keys = Object.keys(extensions);\r\n        for (const extension of keys) {\r\n            registeredPlugins[extension.toLowerCase()] = {\r\n                plugin: plugin,\r\n                isBinary: extensions[extension].isBinary,\r\n                mimeType: extensions[extension].mimeType,\r\n            };\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Adds a new plugin to the list of registered plugins\r\n * @deprecated Please use {@link RegisterSceneLoaderPlugin} instead.\r\n * @param plugin defines the plugin to add\r\n */\r\nexport function registerSceneLoaderPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync | ISceneLoaderPluginFactory): void {\r\n    RegisterSceneLoaderPlugin(plugin);\r\n}\r\n\r\n/**\r\n * Gets metadata for all currently registered scene loader plugins.\r\n * @returns An array where each entry has metadata for a single scene loader plugin.\r\n */\r\nexport function GetRegisteredSceneLoaderPluginMetadata(): DeepImmutable<\r\n    Array<\r\n        Pick<ISceneLoaderPluginMetadata, \"name\"> & {\r\n            /**\r\n             * The extensions supported by the plugin.\r\n             */\r\n            extensions: ({\r\n                /**\r\n                 * The file extension.\r\n                 */\r\n                extension: string;\r\n            } & ISceneLoaderPluginExtensions[string])[];\r\n        }\r\n    >\r\n> {\r\n    return Array.from(\r\n        Object.entries(registeredPlugins).reduce((pluginMap, [extension, extensionRegistration]) => {\r\n            let pluginMetadata = pluginMap.get(extensionRegistration.plugin.name);\r\n            if (!pluginMetadata) {\r\n                pluginMap.set(extensionRegistration.plugin.name, (pluginMetadata = []));\r\n            }\r\n            pluginMetadata.push({ extension, isBinary: extensionRegistration.isBinary, mimeType: extensionRegistration.mimeType });\r\n            return pluginMap;\r\n        }, new Map<string, ({ extension: string } & ISceneLoaderPluginExtensions[string])[]>())\r\n    ).map(([name, extensions]) => ({ name, extensions }));\r\n}\r\n\r\n/**\r\n * Import meshes into a scene\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene the instance of BABYLON.Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns The loaded list of imported meshes, particle systems, skeletons, and animation groups\r\n */\r\nexport async function ImportMeshAsync(source: SceneSource, scene: Scene, options?: ImportMeshOptions): Promise<ISceneLoaderAsyncResult> {\r\n    const { meshNames, rootUrl = \"\", onProgress, pluginExtension, name, pluginOptions } = options ?? {};\r\n    return await importMeshCoreAsync(meshNames, rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);\r\n}\r\n\r\nasync function importMeshCoreAsync(\r\n    meshNames: string | readonly string[] | null | undefined,\r\n    rootUrl: string,\r\n    sceneFilename: SceneSource = \"\",\r\n    scene: Nullable<Scene> = EngineStore.LastCreatedScene,\r\n    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n    pluginExtension?: Nullable<string>,\r\n    name = \"\",\r\n    pluginOptions: PluginOptions = {}\r\n): Promise<ISceneLoaderAsyncResult> {\r\n    if (!scene) {\r\n        throw new Error(\"No scene available to import mesh to\");\r\n    }\r\n\r\n    const fileInfo = GetFileInfo(rootUrl, sceneFilename);\r\n    if (!fileInfo) {\r\n        throw new Error(\"Cannot load file: a valid scene filename or root url was not provided.\");\r\n    }\r\n\r\n    const loadingToken = {};\r\n    scene.addPendingData(loadingToken);\r\n\r\n    const progressHandler = wrapProgress(onProgress);\r\n\r\n    try {\r\n        const { plugin, data, responseURL } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);\r\n\r\n        if (plugin.rewriteRootURL) {\r\n            fileInfo.rootUrl = plugin.rewriteRootURL(fileInfo.rootUrl, responseURL);\r\n        }\r\n\r\n        let result: ISceneLoaderAsyncResult;\r\n        try {\r\n            result = await toAsyncPlugin(plugin, fileInfo).importMeshAsync(meshNames, scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);\r\n        } catch (error) {\r\n            throw toLoadError(fileInfo, error);\r\n        }\r\n\r\n        // eslint-disable-next-line require-atomic-updates\r\n        scene.loadingPluginName = plugin.name;\r\n        scene.importedMeshesFiles.push(fileInfo.url);\r\n\r\n        return result;\r\n    } finally {\r\n        scene.removePendingData(loadingToken);\r\n    }\r\n}\r\n\r\n// This is the core implementation of load scene\r\nasync function loadSceneCoreAsync(\r\n    rootUrl: string,\r\n    sceneFilename: SceneSource = \"\",\r\n    engine: Nullable<AbstractEngine> = EngineStore.LastCreatedEngine,\r\n    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n    pluginExtension?: Nullable<string>,\r\n    name = \"\",\r\n    pluginOptions: PluginOptions = {}\r\n): Promise<Scene> {\r\n    if (!engine) {\r\n        throw new Error(\"No engine available\");\r\n    }\r\n\r\n    const scene = new Scene(engine);\r\n    try {\r\n        await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);\r\n    } catch (error) {\r\n        // The scene was created here, so dispose it on failure to avoid leaking the partially loaded scene.\r\n        scene.dispose();\r\n        throw error;\r\n    }\r\n    return scene;\r\n}\r\n\r\n/**\r\n * Load a scene\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param engine is the instance of BABYLON.Engine to use to create the scene\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns The loaded scene\r\n */\r\nexport async function LoadSceneAsync(source: SceneSource, engine: AbstractEngine, options?: LoadOptions): Promise<Scene> {\r\n    const { rootUrl = \"\", onProgress, pluginExtension, name, pluginOptions } = options ?? {};\r\n    return await loadSceneCoreAsync(rootUrl, source, engine, onProgress, pluginExtension, name, pluginOptions);\r\n}\r\n\r\n/**\r\n * Load a scene\r\n * @deprecated Please use {@link LoadSceneAsync} instead.\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param engine is the instance of BABYLON.Engine to use to create the scene\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns The loaded scene\r\n */\r\nexport async function loadSceneAsync(source: SceneSource, engine: AbstractEngine, options?: LoadOptions): Promise<Scene> {\r\n    return await LoadSceneAsync(source, engine, options);\r\n}\r\n\r\n// This is the core implementation of append scene\r\nasync function appendSceneCoreAsync(\r\n    rootUrl: string,\r\n    sceneFilename: SceneSource = \"\",\r\n    scene: Nullable<Scene> = EngineStore.LastCreatedScene,\r\n    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n    pluginExtension?: Nullable<string>,\r\n    name = \"\",\r\n    pluginOptions: PluginOptions = {}\r\n): Promise<Scene> {\r\n    if (!scene) {\r\n        throw new Error(\"No scene available to append to\");\r\n    }\r\n\r\n    const fileInfo = GetFileInfo(rootUrl, sceneFilename);\r\n    if (!fileInfo) {\r\n        throw new Error(\"Cannot load file: a valid scene filename or root url was not provided.\");\r\n    }\r\n\r\n    const loadingToken = {};\r\n    scene.addPendingData(loadingToken);\r\n\r\n    if (SceneLoaderFlags.ShowLoadingScreen && !showingLoadingScreen) {\r\n        showingLoadingScreen = true;\r\n        scene.getEngine().displayLoadingUI();\r\n        scene.executeWhenReady(() => {\r\n            scene.getEngine().hideLoadingUI();\r\n            showingLoadingScreen = false;\r\n        });\r\n    }\r\n\r\n    const progressHandler = wrapProgress(onProgress);\r\n\r\n    try {\r\n        const { plugin, data } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);\r\n\r\n        try {\r\n            await toAsyncPlugin(plugin, fileInfo).loadAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);\r\n        } catch (error) {\r\n            throw toLoadError(fileInfo, error);\r\n        }\r\n\r\n        // eslint-disable-next-line require-atomic-updates\r\n        scene.loadingPluginName = plugin.name;\r\n        return scene;\r\n    } finally {\r\n        scene.removePendingData(loadingToken);\r\n    }\r\n}\r\n\r\n/**\r\n * Append a scene\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene is the instance of BABYLON.Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns A promise that resolves when the scene is appended\r\n */\r\nexport async function AppendSceneAsync(source: SceneSource, scene: Scene, options?: AppendOptions): Promise<void> {\r\n    const { rootUrl = \"\", onProgress, pluginExtension, name, pluginOptions } = options ?? {};\r\n    await appendSceneCoreAsync(rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);\r\n}\r\n\r\n/**\r\n * Append a scene\r\n * @deprecated Please use {@link AppendSceneAsync} instead.\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene is the instance of BABYLON.Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns A promise that resolves when the scene is appended\r\n */\r\nexport async function appendSceneAsync(source: SceneSource, scene: Scene, options?: AppendOptions): Promise<void> {\r\n    return await AppendSceneAsync(source, scene, options);\r\n}\r\n\r\n// This is the core implementation of load asset container\r\nasync function loadAssetContainerCoreAsync(\r\n    rootUrl: string,\r\n    sceneFilename: SceneSource = \"\",\r\n    scene: Nullable<Scene> = EngineStore.LastCreatedScene,\r\n    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n    pluginExtension?: Nullable<string>,\r\n    name = \"\",\r\n    pluginOptions: PluginOptions = {}\r\n): Promise<AssetContainer> {\r\n    if (!scene) {\r\n        throw new Error(\"No scene available to load asset container to\");\r\n    }\r\n\r\n    const fileInfo = GetFileInfo(rootUrl, sceneFilename);\r\n    if (!fileInfo) {\r\n        throw new Error(\"Cannot load file: a valid scene filename or root url was not provided.\");\r\n    }\r\n\r\n    const loadingToken = {};\r\n    scene.addPendingData(loadingToken);\r\n\r\n    const progressHandler = wrapProgress(onProgress);\r\n\r\n    try {\r\n        const { plugin, data } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);\r\n\r\n        const asyncPlugin = toAsyncPlugin(plugin, fileInfo);\r\n        if (!asyncPlugin.loadAssetContainerAsync) {\r\n            throw createLoadError(fileInfo, loadAssetContainerNotSupportedMessage);\r\n        }\r\n\r\n        let assetContainer: AssetContainer;\r\n        try {\r\n            assetContainer = await asyncPlugin.loadAssetContainerAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);\r\n        } catch (error) {\r\n            throw toLoadError(fileInfo, error);\r\n        }\r\n\r\n        assetContainer.populateRootNodes();\r\n        // eslint-disable-next-line require-atomic-updates\r\n        scene.loadingPluginName = plugin.name;\r\n\r\n        return assetContainer;\r\n    } finally {\r\n        scene.removePendingData(loadingToken);\r\n    }\r\n}\r\n\r\n/**\r\n * Load a scene into an asset container\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene is the instance of Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns The loaded asset container\r\n */\r\nexport async function LoadAssetContainerAsync(source: SceneSource, scene: Scene, options?: LoadAssetContainerOptions): Promise<AssetContainer> {\r\n    const { rootUrl = \"\", onProgress, pluginExtension, name, pluginOptions } = options ?? {};\r\n    return await loadAssetContainerCoreAsync(rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);\r\n}\r\n\r\n/**\r\n * Load a scene into an asset container\r\n * @deprecated Please use {@link LoadAssetContainerAsync} instead.\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene is the instance of Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns The loaded asset container\r\n */\r\nexport async function loadAssetContainerAsync(source: SceneSource, scene: Scene, options?: LoadAssetContainerOptions): Promise<AssetContainer> {\r\n    return await LoadAssetContainerAsync(source, scene, options);\r\n}\r\n\r\n// This is the core implementation of import animations\r\nasync function importAnimationsCoreAsync(\r\n    rootUrl: string,\r\n    sceneFilename: SceneSource = \"\",\r\n    scene: Nullable<Scene> = EngineStore.LastCreatedScene,\r\n    overwriteAnimations = true,\r\n    animationGroupLoadingMode = SceneLoaderAnimationGroupLoadingMode.Clean,\r\n    targetConverter: Nullable<(target: any) => any> = null,\r\n    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n    pluginExtension?: Nullable<string>,\r\n    name = \"\",\r\n    pluginOptions: PluginOptions = {}\r\n): Promise<void> {\r\n    if (!scene) {\r\n        throw new Error(\"No scene available to load animations to\");\r\n    }\r\n\r\n    if (overwriteAnimations) {\r\n        // Reset, stop and dispose all animations before loading new ones\r\n        for (const animatable of scene.animatables) {\r\n            animatable.reset();\r\n        }\r\n        scene.stopAllAnimations();\r\n        const animationGroups = scene.animationGroups.slice();\r\n        for (const animationGroup of animationGroups) {\r\n            animationGroup.dispose();\r\n        }\r\n        const nodes = scene.getNodes();\r\n        for (const node of nodes) {\r\n            if (node.animations) {\r\n                node.animations = [];\r\n            }\r\n        }\r\n    } else {\r\n        switch (animationGroupLoadingMode as number) {\r\n            case SceneLoaderAnimationGroupLoadingMode.Clean:\r\n                const animationGroups = scene.animationGroups.slice();\r\n                for (const animationGroup of animationGroups) {\r\n                    animationGroup.dispose();\r\n                }\r\n                break;\r\n            case SceneLoaderAnimationGroupLoadingMode.Stop:\r\n                for (const animationGroup of scene.animationGroups) {\r\n                    animationGroup.stop();\r\n                }\r\n                break;\r\n            case SceneLoaderAnimationGroupLoadingMode.Sync:\r\n                for (const animationGroup of scene.animationGroups) {\r\n                    animationGroup.reset();\r\n                    animationGroup.restart();\r\n                }\r\n                break;\r\n            case SceneLoaderAnimationGroupLoadingMode.NoSync:\r\n                // nothing to do\r\n                break;\r\n            default:\r\n                throw new Error(\"Unknown animation group loading mode value '\" + animationGroupLoadingMode + \"'\");\r\n        }\r\n    }\r\n\r\n    const startingIndexForNewAnimatables = scene.animatables.length;\r\n\r\n    const container = await loadAssetContainerCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);\r\n\r\n    container.mergeAnimationsTo(scene, scene.animatables.slice(startingIndexForNewAnimatables), targetConverter);\r\n    container.dispose();\r\n    scene.onAnimationFileImportedObservable.notifyObservers(scene);\r\n}\r\n\r\n/**\r\n * Import animations from a file into a scene\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene is the instance of BABYLON.Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns A promise that resolves when the animations are imported\r\n */\r\nexport async function ImportAnimationsAsync(source: SceneSource, scene: Scene, options?: ImportAnimationsOptions): Promise<void> {\r\n    const { rootUrl = \"\", overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name, pluginOptions } = options ?? {};\r\n    await importAnimationsCoreAsync(rootUrl, source, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name, pluginOptions);\r\n}\r\n\r\n/**\r\n * Import animations from a file into a scene\r\n * @deprecated Please use {@link ImportAnimationsAsync} instead.\r\n * @param source a string that defines the name of the scene file, or starts with \"data:\" following by the stringified version of the scene, or a File object, or an ArrayBufferView\r\n * @param scene is the instance of BABYLON.Scene to append to\r\n * @param options an object that configures aspects of how the scene is loaded\r\n * @returns A promise that resolves when the animations are imported\r\n */\r\nexport async function importAnimationsAsync(source: SceneSource, scene: Scene, options?: ImportAnimationsOptions): Promise<void> {\r\n    return await ImportAnimationsAsync(source, scene, options);\r\n}\r\n\r\n/**\r\n * Class used to load scene from various file formats using registered plugins\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/loadingFileTypes\r\n * @deprecated The module level functions are more efficient for bundler tree shaking and allow plugin options to be passed through. Future improvements to scene loading will primarily be in the module level functions. The SceneLoader class will remain available, but it will be beneficial to prefer the module level functions.\r\n * @see {@link ImportMeshAsync}, {@link LoadSceneAsync}, {@link AppendSceneAsync}, {@link ImportAnimationsAsync}, {@link LoadAssetContainerAsync}\r\n */\r\nexport class SceneLoader {\r\n    /**\r\n     * No logging while loading\r\n     */\r\n    public static readonly NO_LOGGING = Constants.SCENELOADER_NO_LOGGING;\r\n\r\n    /**\r\n     * Minimal logging while loading\r\n     */\r\n    public static readonly MINIMAL_LOGGING = Constants.SCENELOADER_MINIMAL_LOGGING;\r\n\r\n    /**\r\n     * Summary logging while loading\r\n     */\r\n    public static readonly SUMMARY_LOGGING = Constants.SCENELOADER_SUMMARY_LOGGING;\r\n\r\n    /**\r\n     * Detailed logging while loading\r\n     */\r\n    public static readonly DETAILED_LOGGING = Constants.SCENELOADER_DETAILED_LOGGING;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if entire scene must be loaded even if scene contains incremental data\r\n     */\r\n    public static get ForceFullSceneLoadingForIncremental() {\r\n        return SceneLoaderFlags.ForceFullSceneLoadingForIncremental;\r\n    }\r\n\r\n    public static set ForceFullSceneLoadingForIncremental(value: boolean) {\r\n        SceneLoaderFlags.ForceFullSceneLoadingForIncremental = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if loading screen must be displayed while loading a scene\r\n     */\r\n    public static get ShowLoadingScreen(): boolean {\r\n        return SceneLoaderFlags.ShowLoadingScreen;\r\n    }\r\n\r\n    public static set ShowLoadingScreen(value: boolean) {\r\n        SceneLoaderFlags.ShowLoadingScreen = value;\r\n    }\r\n\r\n    /**\r\n     * Defines the current logging level (while loading the scene)\r\n     * @ignorenaming\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static get loggingLevel(): number {\r\n        return SceneLoaderFlags.loggingLevel;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static set loggingLevel(value: number) {\r\n        SceneLoaderFlags.loggingLevel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or set a boolean indicating if matrix weights must be cleaned upon loading\r\n     */\r\n    public static get CleanBoneMatrixWeights(): boolean {\r\n        return SceneLoaderFlags.CleanBoneMatrixWeights;\r\n    }\r\n\r\n    public static set CleanBoneMatrixWeights(value: boolean) {\r\n        SceneLoaderFlags.CleanBoneMatrixWeights = value;\r\n    }\r\n\r\n    // Members\r\n\r\n    /**\r\n     * Event raised when a plugin is used to load a scene\r\n     */\r\n    public static readonly OnPluginActivatedObservable = onPluginActivatedObservable;\r\n\r\n    /**\r\n     * Gets the default plugin (used to load Babylon files)\r\n     * @returns the .babylon plugin\r\n     */\r\n    public static GetDefaultPlugin(): IRegisteredPlugin | undefined {\r\n        return getDefaultPlugin();\r\n    }\r\n\r\n    // Public functions\r\n\r\n    /**\r\n     * Gets a plugin that can load the given extension\r\n     * @param extension defines the extension to load\r\n     * @returns a plugin or null if none works\r\n     */\r\n    public static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync | ISceneLoaderPluginFactory | undefined {\r\n        return getPluginForExtension(extension, true)?.plugin;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the given extension can be loaded\r\n     * @param extension defines the extension to load\r\n     * @returns true if the extension is supported\r\n     */\r\n    public static IsPluginForExtensionAvailable(extension: string): boolean {\r\n        return isPluginForExtensionAvailable(extension);\r\n    }\r\n\r\n    /**\r\n     * Adds a new plugin to the list of registered plugins\r\n     * @param plugin defines the plugin to add\r\n     */\r\n    public static RegisterPlugin(plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync | ISceneLoaderPluginFactory): void {\r\n        RegisterSceneLoaderPlugin(plugin);\r\n    }\r\n\r\n    /**\r\n     * Import meshes into a scene\r\n     * @param meshNames an array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene the instance of BABYLON.Scene to append to\r\n     * @param onSuccess a callback with a list of imported meshes, particleSystems, skeletons, and animationGroups when import succeeds\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param onError a callback with the scene, a message, and possibly an exception when import fails\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the name of the file, if the data is binary\r\n     * @param pluginOptions defines the options to use with the plugin\r\n     * @deprecated Please use the module level {@link ImportMeshAsync} instead\r\n     */\r\n    public static ImportMesh(\r\n        meshNames: string | readonly string[] | null | undefined,\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        onSuccess?: Nullable<SceneLoaderSuccessCallback>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string,\r\n        pluginOptions?: PluginOptions\r\n    ): void {\r\n        const reportScene = scene ?? EngineStore.LastCreatedScene;\r\n        void (async () => {\r\n            try {\r\n                const result = await importMeshCoreAsync(meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);\r\n                onSuccess?.(\r\n                    result.meshes,\r\n                    result.particleSystems,\r\n                    result.skeletons,\r\n                    result.animationGroups,\r\n                    result.transformNodes,\r\n                    result.geometries,\r\n                    result.lights,\r\n                    result.spriteManagers\r\n                );\r\n            } catch (error) {\r\n                reportLegacyLoadError(onError, reportScene, error);\r\n            }\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * Import meshes into a scene\r\n     * @param meshNames an array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene the instance of BABYLON.Scene to append to\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the name of the file\r\n     * @returns The loaded list of imported meshes, particle systems, skeletons, and animation groups\r\n     * @deprecated Please use the module level {@link ImportMeshAsync} instead\r\n     */\r\n    public static async ImportMeshAsync(\r\n        meshNames: string | readonly string[] | null | undefined,\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ): Promise<ISceneLoaderAsyncResult> {\r\n        return await importMeshCoreAsync(meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);\r\n    }\r\n\r\n    /**\r\n     * Load a scene\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param engine is the instance of BABYLON.Engine to use to create the scene\r\n     * @param onSuccess a callback with the scene when import succeeds\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param onError a callback with the scene, a message, and possibly an exception when import fails\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the filename, if the data is binary\r\n     * @deprecated Please use the module level {@link LoadSceneAsync} instead\r\n     */\r\n    public static Load(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        engine?: Nullable<AbstractEngine>,\r\n        onSuccess?: Nullable<(scene: Scene) => void>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ) {\r\n        void (async () => {\r\n            try {\r\n                const scene = await loadSceneCoreAsync(rootUrl, sceneFilename, engine, onProgress, pluginExtension, name);\r\n                onSuccess?.(scene);\r\n            } catch (error) {\r\n                reportLegacyLoadError(onError, EngineStore.LastCreatedScene, error);\r\n            }\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * Load a scene\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param engine is the instance of BABYLON.Engine to use to create the scene\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the filename, if the data is binary\r\n     * @returns The loaded scene\r\n     * @deprecated Please use the module level {@link LoadSceneAsync} instead\r\n     */\r\n    public static async LoadAsync(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        engine?: Nullable<AbstractEngine>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ): Promise<Scene> {\r\n        return await loadSceneCoreAsync(rootUrl, sceneFilename, engine, onProgress, pluginExtension, name);\r\n    }\r\n\r\n    /**\r\n     * Append a scene\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene is the instance of BABYLON.Scene to append to\r\n     * @param onSuccess a callback with the scene when import succeeds\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param onError a callback with the scene, a message, and possibly an exception when import fails\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the name of the file, if the data is binary\r\n     * @deprecated Please use the module level {@link AppendSceneAsync} instead\r\n     */\r\n    public static Append(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        onSuccess?: Nullable<(scene: Scene) => void>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ) {\r\n        const reportScene = scene ?? EngineStore.LastCreatedScene;\r\n        void (async () => {\r\n            try {\r\n                const appendedScene = await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);\r\n                onSuccess?.(appendedScene);\r\n            } catch (error) {\r\n                reportLegacyLoadError(onError, reportScene, error);\r\n            }\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * Append a scene\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene is the instance of BABYLON.Scene to append to\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the name of the file, if the data is binary\r\n     * @returns The given scene\r\n     * @deprecated Please use the module level {@link AppendSceneAsync} instead\r\n     */\r\n    public static async AppendAsync(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ): Promise<Scene> {\r\n        return await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);\r\n    }\r\n\r\n    /**\r\n     * Load a scene into an asset container\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene is the instance of BABYLON.Scene to append to (default: last created scene)\r\n     * @param onSuccess a callback with the scene when import succeeds\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param onError a callback with the scene, a message, and possibly an exception when import fails\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the filename, if the data is binary\r\n     * @deprecated Please use the module level {@link LoadAssetContainerAsync} instead\r\n     */\r\n    public static LoadAssetContainer(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        onSuccess?: Nullable<(assets: AssetContainer) => void>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ) {\r\n        const reportScene = scene ?? EngineStore.LastCreatedScene;\r\n        void (async () => {\r\n            try {\r\n                const assets = await loadAssetContainerCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);\r\n                onSuccess?.(assets);\r\n            } catch (error) {\r\n                reportLegacyLoadError(onError, reportScene, error);\r\n            }\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * Load a scene into an asset container\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene (default: empty string)\r\n     * @param scene is the instance of Scene to append to\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the filename, if the data is binary\r\n     * @returns The loaded asset container\r\n     * @deprecated Please use the module level {@link LoadAssetContainerAsync} instead\r\n     */\r\n    public static async LoadAssetContainerAsync(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ): Promise<AssetContainer> {\r\n        return await loadAssetContainerCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);\r\n    }\r\n\r\n    /**\r\n     * Import animations from a file into a scene\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene is the instance of BABYLON.Scene to append to (default: last created scene)\r\n     * @param overwriteAnimations when true, animations are cleaned before importing new ones. Animations are appended otherwise\r\n     * @param animationGroupLoadingMode defines how to handle old animations groups before importing new ones\r\n     * @param targetConverter defines a function used to convert animation targets from loaded scene to current scene (default: search node by name)\r\n     * @param onSuccess a callback with the scene when import succeeds\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param onError a callback with the scene, a message, and possibly an exception when import fails\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the filename, if the data is binary\r\n     * @deprecated Please use the module level {@link ImportAnimationsAsync} instead\r\n     */\r\n    public static ImportAnimations(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        overwriteAnimations?: boolean,\r\n        animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode,\r\n        targetConverter?: Nullable<(target: any) => any>,\r\n        onSuccess?: Nullable<(scene: Scene) => void>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ): void {\r\n        const reportScene = scene ?? EngineStore.LastCreatedScene;\r\n        void (async () => {\r\n            try {\r\n                await importAnimationsCoreAsync(rootUrl, sceneFilename, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name);\r\n                onSuccess?.(reportScene!);\r\n            } catch (error) {\r\n                reportLegacyLoadError(onError, reportScene, error);\r\n            }\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * Import animations from a file into a scene\r\n     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)\r\n     * @param sceneFilename a string that defines the name of the scene file or starts with \"data:\" following by the stringified version of the scene or a File object (default: empty string)\r\n     * @param scene is the instance of BABYLON.Scene to append to (default: last created scene)\r\n     * @param overwriteAnimations when true, animations are cleaned before importing new ones. Animations are appended otherwise\r\n     * @param animationGroupLoadingMode defines how to handle old animations groups before importing new ones\r\n     * @param targetConverter defines a function used to convert animation targets from loaded scene to current scene (default: search node by name)\r\n     * @param onSuccess a callback with the scene when import succeeds\r\n     * @param onProgress a callback with a progress event for each file being loaded\r\n     * @param onError a callback with the scene, a message, and possibly an exception when import fails\r\n     * @param pluginExtension the extension used to determine the plugin\r\n     * @param name defines the filename, if the data is binary\r\n     * @returns the updated scene with imported animations\r\n     * @deprecated Please use the module level {@link ImportAnimationsAsync} instead\r\n     */\r\n    public static async ImportAnimationsAsync(\r\n        rootUrl: string,\r\n        sceneFilename?: SceneSource,\r\n        scene?: Nullable<Scene>,\r\n        overwriteAnimations?: boolean,\r\n        animationGroupLoadingMode?: SceneLoaderAnimationGroupLoadingMode,\r\n        targetConverter?: Nullable<(target: any) => any>,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        onSuccess?: Nullable<(scene: Scene) => void>,\r\n        onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,\r\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n        onError?: Nullable<(scene: Scene, message: string, exception?: any) => void>,\r\n        pluginExtension?: Nullable<string>,\r\n        name?: string\r\n    ): Promise<Scene> {\r\n        const targetScene = scene ?? EngineStore.LastCreatedScene;\r\n        await importAnimationsCoreAsync(rootUrl, sceneFilename, targetScene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name);\r\n        return targetScene!;\r\n    }\r\n}\r\n","import { WebRequest } from \"./webRequest\";\r\n\r\n/**\r\n * Fetches a resource from the network\r\n * @param url defines the url to fetch the resource from\r\n * @param options defines the options to use when fetching the resource\r\n * @returns a promise that resolves when the resource is fetched\r\n * @internal\r\n */\r\nexport async function _FetchAsync(\r\n    url: string,\r\n    options: Partial<{ method: string; responseHeaders?: string[] }>\r\n): Promise<{ response: Response; headerValues: { [key: string]: string } }> {\r\n    const method = options.method || \"GET\";\r\n    return await new Promise((resolve, reject) => {\r\n        const request = new WebRequest();\r\n        request.addEventListener(\"readystatechange\", () => {\r\n            if (request.readyState == 4) {\r\n                if (request.status == 200) {\r\n                    const headerValues: { [key: string]: string } = {};\r\n                    if (options.responseHeaders) {\r\n                        for (const header of options.responseHeaders) {\r\n                            headerValues[header] = request.getResponseHeader(header) || \"\";\r\n                        }\r\n                    }\r\n\r\n                    resolve({ response: request.response, headerValues: headerValues });\r\n                } else {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(`Unable to fetch data from ${url}. Error code: ${request.status}`);\r\n                }\r\n            }\r\n        });\r\n\r\n        request.open(method, url);\r\n        request.send();\r\n    });\r\n}\r\n","import { type IDisposable, type Scene } from \"../../scene\";\r\nimport { WebXRControllerComponent } from \"./webXRControllerComponent\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { SceneLoader } from \"../../Loading/sceneLoader\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Quaternion, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\n\r\n/**\r\n * Handedness type in xrInput profiles. These can be used to define layouts in the Layout Map.\r\n */\r\nexport type MotionControllerHandedness = \"none\" | \"left\" | \"right\";\r\n/**\r\n * The type of components available in motion controllers.\r\n * This is not the name of the component.\r\n */\r\nexport type MotionControllerComponentType = \"trigger\" | \"squeeze\" | \"touchpad\" | \"thumbstick\" | \"button\";\r\n\r\n/**\r\n * The state of a controller component\r\n */\r\nexport type MotionControllerComponentStateType = \"default\" | \"touched\" | \"pressed\";\r\n\r\n/**\r\n * The haptic capabilities exposed by a WebXR motion controller actuator.\r\n */\r\nexport interface IWebXRControllerHapticActuator {\r\n    /**\r\n     * The haptic effects reported as supported by this actuator.\r\n     */\r\n    readonly effects?: ReadonlyArray<GamepadHapticEffectType>;\r\n    /**\r\n     * Plays a haptic effect, when advanced haptic playback is supported.\r\n     */\r\n    playEffect?: GamepadHapticActuator[\"playEffect\"];\r\n    /**\r\n     * Stops the active haptic effect, when reset is supported.\r\n     */\r\n    reset?: GamepadHapticActuator[\"reset\"];\r\n}\r\n\r\n/**\r\n * The schema of motion controller layout.\r\n * No object will be initialized using this interface\r\n * This is used just to define the profile.\r\n */\r\nexport interface IMotionControllerLayout {\r\n    /**\r\n     * Path to load the assets. Usually relative to the base path\r\n     */\r\n    assetPath: string;\r\n    /**\r\n     * Available components (unsorted)\r\n     */\r\n    components: {\r\n        /**\r\n         * A map of component Ids\r\n         */\r\n        [componentId: string]: {\r\n            /**\r\n             * The type of input the component outputs\r\n             */\r\n            type: MotionControllerComponentType;\r\n            /**\r\n             * The indices of this component in the gamepad object\r\n             */\r\n            gamepadIndices: {\r\n                /**\r\n                 * Index of button\r\n                 */\r\n                button?: number;\r\n                /**\r\n                 * If available, index of x-axis\r\n                 */\r\n                xAxis?: number;\r\n                /**\r\n                 * If available, index of y-axis\r\n                 */\r\n                yAxis?: number;\r\n            };\r\n            /**\r\n             * The mesh's root node name\r\n             */\r\n            rootNodeName: string;\r\n            /**\r\n             * Animation definitions for this model\r\n             */\r\n            visualResponses: {\r\n                [stateKey: string]: {\r\n                    /**\r\n                     * What property will be animated\r\n                     */\r\n                    componentProperty: \"xAxis\" | \"yAxis\" | \"button\" | \"state\";\r\n                    /**\r\n                     * What states influence this visual response\r\n                     */\r\n                    states: MotionControllerComponentStateType[];\r\n                    /**\r\n                     * Type of animation - movement or visibility\r\n                     */\r\n                    valueNodeProperty: \"transform\" | \"visibility\";\r\n                    /**\r\n                     * Base node name to move. Its position will be calculated according to the min and max nodes\r\n                     */\r\n                    valueNodeName?: string;\r\n                    /**\r\n                     * Minimum movement node\r\n                     */\r\n                    minNodeName?: string;\r\n                    /**\r\n                     * Max movement node\r\n                     */\r\n                    maxNodeName?: string;\r\n                };\r\n            };\r\n            /**\r\n             * If touch enabled, what is the name of node to display user feedback\r\n             */\r\n            touchPointNodeName?: string;\r\n        };\r\n    };\r\n    /**\r\n     * Is it xr standard mapping or not\r\n     */\r\n    gamepadMapping: \"\" | \"xr-standard\";\r\n    /**\r\n     * Base root node of this entire model\r\n     */\r\n    rootNodeName: string;\r\n    /**\r\n     * Defines the main button component id\r\n     */\r\n    selectComponentId: string;\r\n}\r\n\r\n/**\r\n * A definition for the layout map in the input profile\r\n */\r\nexport interface IMotionControllerLayoutMap {\r\n    /**\r\n     * Layouts with handedness type as a key\r\n     */\r\n    [handedness: string /* handedness */]: IMotionControllerLayout;\r\n}\r\n\r\n/**\r\n * The XR Input profile schema\r\n * Profiles can be found here:\r\n * https://github.com/immersive-web/webxr-input-profiles/tree/master/packages/registry/profiles\r\n */\r\nexport interface IMotionControllerProfile {\r\n    /**\r\n     * fallback profiles for this profileId\r\n     */\r\n    fallbackProfileIds: string[];\r\n    /**\r\n     * The layout map, with handedness as key\r\n     */\r\n    layouts: IMotionControllerLayoutMap;\r\n    /**\r\n     * The id of this profile\r\n     * correlates to the profile(s) in the xrInput.profiles array\r\n     */\r\n    profileId: string;\r\n}\r\n\r\n/**\r\n * A helper-interface for the 3 meshes needed for controller button animation\r\n * The meshes are provided to the _lerpButtonTransform function to calculate the current position of the value mesh\r\n */\r\nexport interface IMotionControllerButtonMeshMap {\r\n    /**\r\n     * the mesh that defines the pressed value mesh position.\r\n     * This is used to find the max-position of this button\r\n     */\r\n    pressedMesh: AbstractMesh;\r\n    /**\r\n     * the mesh that defines the unpressed value mesh position.\r\n     * This is used to find the min (or initial) position of this button\r\n     */\r\n    unpressedMesh: AbstractMesh;\r\n    /**\r\n     * The mesh that will be changed when value changes\r\n     */\r\n    valueMesh: AbstractMesh;\r\n}\r\n\r\n/**\r\n * A helper-interface for the 3 meshes needed for controller axis animation.\r\n * This will be expanded when touchpad animations are fully supported\r\n * The meshes are provided to the _lerpAxisTransform function to calculate the current position of the value mesh\r\n */\r\nexport interface IMotionControllerMeshMap {\r\n    /**\r\n     * the mesh that defines the maximum value mesh position.\r\n     */\r\n    maxMesh?: AbstractMesh;\r\n    /**\r\n     * the mesh that defines the minimum value mesh position.\r\n     */\r\n    minMesh?: AbstractMesh;\r\n    /**\r\n     * The mesh that will be changed when axis value changes\r\n     */\r\n    valueMesh?: AbstractMesh;\r\n}\r\n\r\n/**\r\n * The elements needed for change-detection of the gamepad objects in motion controllers\r\n */\r\nexport interface IMinimalMotionControllerObject {\r\n    /**\r\n     * Available axes of this controller\r\n     */\r\n    axes: number[];\r\n    /**\r\n     * An array of available buttons\r\n     */\r\n    buttons: Array<{\r\n        /**\r\n         * Value of the button/trigger\r\n         */\r\n        value: number;\r\n        /**\r\n         * If the button/trigger is currently touched\r\n         */\r\n        touched: boolean;\r\n        /**\r\n         * If the button/trigger is currently pressed\r\n         */\r\n        pressed: boolean;\r\n    }>;\r\n\r\n    /**\r\n     * EXPERIMENTAL haptic support.\r\n     */\r\n    hapticActuators?: Array<\r\n        IWebXRControllerHapticActuator & {\r\n            /**\r\n             * Plays a legacy haptic pulse.\r\n             */\r\n            pulse: (value: number, duration: number) => Promise<boolean>;\r\n        }\r\n    >;\r\n\r\n    /**\r\n     * The primary Gamepad vibration actuator used for advanced haptic effects.\r\n     */\r\n    vibrationActuator?: IWebXRControllerHapticActuator;\r\n}\r\n\r\n/**\r\n * An Abstract Motion controller\r\n * This class receives an xrInput and a profile layout and uses those to initialize the components\r\n * Each component has an observable to check for changes in value and state\r\n */\r\nexport abstract class WebXRAbstractMotionController implements IDisposable {\r\n    private _initComponent = (id: string) => {\r\n        if (!id) {\r\n            return;\r\n        }\r\n        const componentDef = this.layout.components[id];\r\n        const type = componentDef.type;\r\n        const buttonIndex = componentDef.gamepadIndices.button;\r\n        // search for axes\r\n        const axes: number[] = [];\r\n        if (componentDef.gamepadIndices.xAxis !== undefined && componentDef.gamepadIndices.yAxis !== undefined) {\r\n            axes.push(componentDef.gamepadIndices.xAxis, componentDef.gamepadIndices.yAxis);\r\n        }\r\n\r\n        this.components[id] = new WebXRControllerComponent(id, type, buttonIndex, axes);\r\n    };\r\n\r\n    private _modelReady: boolean = false;\r\n\r\n    /**\r\n     * A map of components (WebXRControllerComponent) in this motion controller\r\n     * Components have a ComponentType and can also have both button and axis definitions\r\n     */\r\n    public readonly components: {\r\n        [id: string]: WebXRControllerComponent;\r\n    } = {};\r\n\r\n    /**\r\n     * Disable the model's animation. Can be set at any time.\r\n     */\r\n    public disableAnimation: boolean = false;\r\n    /**\r\n     * Observers registered here will be triggered when the model of this controller is done loading\r\n     */\r\n    public onModelLoadedObservable: Observable<WebXRAbstractMotionController> = new Observable();\r\n    /**\r\n     * The profile id of this motion controller\r\n     */\r\n    public abstract profileId: string;\r\n    /**\r\n     * The root mesh of the model. It is null if the model was not yet initialized\r\n     */\r\n    public rootMesh: Nullable<AbstractMesh>;\r\n\r\n    /**\r\n     * constructs a new abstract motion controller\r\n     * @param scene the scene to which the model of the controller will be added\r\n     * @param layout The profile layout to load\r\n     * @param gamepadObject The gamepad object correlating to this controller\r\n     * @param handedness handedness (left/right/none) of this controller\r\n     * @param _doNotLoadControllerMesh set this flag to ignore the mesh loading\r\n     * @param _controllerCache a cache holding controller models already loaded in this session\r\n     */\r\n    constructor(\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        protected scene: Scene,\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        protected layout: IMotionControllerLayout,\r\n        /**\r\n         * The gamepad object correlating to this controller\r\n         */\r\n        public gamepadObject: IMinimalMotionControllerObject,\r\n        /**\r\n         * handedness (left/right/none) of this controller\r\n         */\r\n        public handedness: MotionControllerHandedness,\r\n        /**\r\n         * @internal\r\n         * [false]\r\n         */\r\n        public _doNotLoadControllerMesh: boolean = false,\r\n        private _controllerCache?: Array<{\r\n            filename: string;\r\n            path: string;\r\n            meshes: AbstractMesh[];\r\n        }>\r\n    ) {\r\n        // initialize the components\r\n        if (layout.components) {\r\n            const keys = Object.keys(layout.components);\r\n            for (const key of keys) {\r\n                this._initComponent(key);\r\n            }\r\n        }\r\n        // Model is loaded in WebXRInput\r\n    }\r\n\r\n    /**\r\n     * Dispose this controller, the model mesh and all its components\r\n     */\r\n    public dispose(): void {\r\n        const ids = this.getComponentIds();\r\n        for (const id of ids) {\r\n            this.getComponent(id).dispose();\r\n        }\r\n        if (this.rootMesh) {\r\n            const nodes = this.rootMesh.getChildren(undefined, true);\r\n            for (const node of nodes) {\r\n                node.setEnabled(false);\r\n            }\r\n            this.rootMesh.dispose(!!this._controllerCache, !this._controllerCache);\r\n        }\r\n        this.onModelLoadedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Returns all components of specific type\r\n     * @param type the type to search for\r\n     * @returns an array of components with this type\r\n     */\r\n    public getAllComponentsOfType(type: MotionControllerComponentType): WebXRControllerComponent[] {\r\n        return this.getComponentIds()\r\n            .map((id) => this.components[id])\r\n            .filter((component) => component.type === type);\r\n    }\r\n\r\n    /**\r\n     * get a component based an its component id as defined in layout.components\r\n     * @param id the id of the component\r\n     * @returns the component correlates to the id or undefined if not found\r\n     */\r\n    public getComponent(id: string): WebXRControllerComponent {\r\n        return this.components[id];\r\n    }\r\n\r\n    /**\r\n     * Get the list of components available in this motion controller\r\n     * @returns an array of strings correlating to available components\r\n     */\r\n    public getComponentIds(): string[] {\r\n        return Object.keys(this.components);\r\n    }\r\n\r\n    /**\r\n     * Get the first component of specific type\r\n     * @param type type of component to find\r\n     * @returns a controller component or null if not found\r\n     */\r\n    public getComponentOfType(type: MotionControllerComponentType): Nullable<WebXRControllerComponent> {\r\n        return this.getAllComponentsOfType(type)[0] || null;\r\n    }\r\n\r\n    /**\r\n     * Get the main (Select) component of this controller as defined in the layout\r\n     * @returns the main component of this controller\r\n     */\r\n    public getMainComponent(): WebXRControllerComponent {\r\n        return this.getComponent(this.layout.selectComponentId);\r\n    }\r\n\r\n    /**\r\n     * Loads the model correlating to this controller\r\n     * When the mesh is loaded, the onModelLoadedObservable will be triggered\r\n     * @returns A promise fulfilled with the result of the model loading\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async loadModel(): Promise<boolean> {\r\n        const useGeneric = !this._getModelLoadingConstraints();\r\n        let loadingParams = this._getGenericFilenameAndPath();\r\n        // Checking if GLB loader is present\r\n        if (useGeneric) {\r\n            Logger.Warn(\"Falling back to generic models\");\r\n        } else {\r\n            loadingParams = this._getFilenameAndPath();\r\n        }\r\n        return await new Promise((resolve, reject) => {\r\n            const meshesLoaded = (meshes: AbstractMesh[]) => {\r\n                if (useGeneric) {\r\n                    this._getGenericParentMesh(meshes);\r\n                } else {\r\n                    this._setRootMesh(meshes);\r\n                }\r\n                this._processLoadedModel(meshes);\r\n                this._modelReady = true;\r\n                this.onModelLoadedObservable.notifyObservers(this);\r\n                resolve(true);\r\n            };\r\n            if (this._controllerCache) {\r\n                // look for it in the cache\r\n                const found = this._controllerCache.filter((c) => {\r\n                    return c.filename === loadingParams.filename && c.path === loadingParams.path;\r\n                });\r\n                if (found[0]) {\r\n                    for (const mesh of found[0].meshes) {\r\n                        mesh.setEnabled(true);\r\n                    }\r\n                    meshesLoaded(found[0].meshes);\r\n                    return;\r\n                    // found, don't continue to load\r\n                }\r\n            }\r\n            SceneLoader.ImportMesh(\r\n                \"\",\r\n                loadingParams.path,\r\n                loadingParams.filename,\r\n                this.scene,\r\n                (meshes) => {\r\n                    if (this._controllerCache) {\r\n                        this._controllerCache.push({\r\n                            ...loadingParams,\r\n                            meshes,\r\n                        });\r\n                    }\r\n                    meshesLoaded(meshes);\r\n                },\r\n                null,\r\n                (_scene: Scene, message: string) => {\r\n                    Logger.Log(message);\r\n                    Logger.Warn(`Failed to retrieve controller model of type ${this.profileId} from the remote server: ${loadingParams.path}${loadingParams.filename}`);\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(message);\r\n                }\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Update this model using the current XRFrame\r\n     * @param xrFrame the current xr frame to use and update the model\r\n     */\r\n    public updateFromXRFrame(xrFrame: XRFrame): void {\r\n        for (const id of this.getComponentIds()) {\r\n            this.getComponent(id).update(this.gamepadObject);\r\n        }\r\n        this.updateModel(xrFrame);\r\n    }\r\n\r\n    /**\r\n     * Backwards compatibility due to a deeply-integrated typo\r\n     */\r\n    public get handness() {\r\n        return this.handedness;\r\n    }\r\n\r\n    /**\r\n     * Gets the haptic effects reported as supported by an actuator.\r\n     * See https://playground.babylonjs.com/#ULVR1X#0 for an interactive example.\r\n     *\r\n     * @param hapticActuatorIndex index of the actuator (usually 0)\r\n     * @returns the effects reported by the actuator, or an empty array when effect discovery is unavailable\r\n     * @throws a RangeError when the actuator index is invalid\r\n     */\r\n    public getHapticEffects(hapticActuatorIndex: number = 0): ReadonlyArray<GamepadHapticEffectType> {\r\n        return this._getHapticActuator(hapticActuatorIndex).effects ?? [];\r\n    }\r\n\r\n    /**\r\n     * Plays an advanced haptic effect on this controller.\r\n     *\r\n     * @param effectType the standard Gamepad haptic effect to play\r\n     * @param parameters effect duration, delay, and motor magnitudes\r\n     * @param hapticActuatorIndex index of the actuator (usually 0)\r\n     * @returns the native completion result from the actuator\r\n     * @throws an Error when the actuator or requested effect is unsupported, or a RangeError when the actuator index is invalid\r\n     */\r\n    public async playHapticEffectAsync(effectType: GamepadHapticEffectType, parameters?: GamepadEffectParameters, hapticActuatorIndex: number = 0): Promise<GamepadHapticsResult> {\r\n        const actuator = this._getHapticActuator(hapticActuatorIndex);\r\n        if (!actuator.effects) {\r\n            throw new Error(`Haptic actuator ${hapticActuatorIndex} does not support effect discovery.`);\r\n        }\r\n        if (actuator.effects.indexOf(effectType) === -1) {\r\n            throw new Error(`Haptic effect \"${effectType}\" is not supported by actuator ${hapticActuatorIndex}.`);\r\n        }\r\n        if (!actuator.playEffect) {\r\n            throw new Error(`Haptic actuator ${hapticActuatorIndex} does not support advanced effect playback.`);\r\n        }\r\n\r\n        return await actuator.playEffect(effectType, parameters);\r\n    }\r\n\r\n    /**\r\n     * Stops the active haptic effect on an actuator.\r\n     *\r\n     * @param hapticActuatorIndex index of the actuator (usually 0)\r\n     * @returns the native completion result from the actuator\r\n     * @throws an Error when reset is unsupported, or a RangeError when the actuator index is invalid\r\n     */\r\n    public async resetHapticActuatorAsync(hapticActuatorIndex: number = 0): Promise<GamepadHapticsResult> {\r\n        const actuator = this._getHapticActuator(hapticActuatorIndex);\r\n        if (!actuator.reset) {\r\n            throw new Error(`Haptic actuator ${hapticActuatorIndex} does not support reset.`);\r\n        }\r\n\r\n        return await actuator.reset();\r\n    }\r\n\r\n    /**\r\n     * Pulse (vibrate) this controller\r\n     * If the controller does not support pulses, this function will fail silently and return Promise<false> directly after called\r\n     * Consecutive calls to this function will cancel the last pulse call\r\n     *\r\n     * @param value the strength of the pulse in 0.0...1.0 range\r\n     * @param duration Duration of the pulse in milliseconds\r\n     * @param hapticActuatorIndex optional index of actuator (will usually be 0)\r\n     * @returns a promise that will send true when the pulse has ended and false if the device doesn't support pulse or an error accrued\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async pulse(value: number, duration: number, hapticActuatorIndex: number = 0): Promise<boolean> {\r\n        if (this.gamepadObject.hapticActuators && this.gamepadObject.hapticActuators[hapticActuatorIndex]) {\r\n            return await this.gamepadObject.hapticActuators[hapticActuatorIndex].pulse(value, duration);\r\n        } else {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    private _getHapticActuator(hapticActuatorIndex: number): IWebXRControllerHapticActuator {\r\n        if (!Number.isInteger(hapticActuatorIndex) || hapticActuatorIndex < 0) {\r\n            throw new RangeError(`Haptic actuator index ${hapticActuatorIndex} is out of range.`);\r\n        }\r\n\r\n        if (hapticActuatorIndex === 0 && this.gamepadObject.vibrationActuator) {\r\n            return this.gamepadObject.vibrationActuator;\r\n        }\r\n\r\n        const actuators = this.gamepadObject.hapticActuators;\r\n        const actuator = actuators?.[hapticActuatorIndex];\r\n        if (!actuator) {\r\n            throw new RangeError(`Haptic actuator index ${hapticActuatorIndex} is out of range.`);\r\n        }\r\n\r\n        return actuator;\r\n    }\r\n\r\n    // Look through all children recursively. This will return null if no mesh exists with the given name.\r\n    protected _getChildByName(node: AbstractMesh, name: string): AbstractMesh | undefined {\r\n        return <AbstractMesh | undefined>node.getChildren((n) => n.name === name, false)[0];\r\n    }\r\n\r\n    // Look through only immediate children. This will return null if no mesh exists with the given name.\r\n    protected _getImmediateChildByName(node: AbstractMesh, name: string): AbstractMesh | undefined {\r\n        return <AbstractMesh | undefined>node.getChildren((n) => n.name == name, true)[0];\r\n    }\r\n\r\n    /**\r\n     * Moves the axis on the controller mesh based on its current state\r\n     * @param axisMap\r\n     * @param axisValue the value of the axis which determines the meshes new position\r\n     * @internal\r\n     */\r\n    protected _lerpTransform(axisMap: IMotionControllerMeshMap, axisValue: number, fixValueCoordinates?: boolean): void {\r\n        if (!axisMap.minMesh || !axisMap.maxMesh || !axisMap.valueMesh) {\r\n            return;\r\n        }\r\n\r\n        if (!axisMap.minMesh.rotationQuaternion || !axisMap.maxMesh.rotationQuaternion || !axisMap.valueMesh.rotationQuaternion) {\r\n            return;\r\n        }\r\n\r\n        // Convert from gamepad value range (-1 to +1) to lerp range (0 to 1)\r\n        const lerpValue = fixValueCoordinates ? axisValue * 0.5 + 0.5 : axisValue;\r\n        Quaternion.SlerpToRef(axisMap.minMesh.rotationQuaternion, axisMap.maxMesh.rotationQuaternion, lerpValue, axisMap.valueMesh.rotationQuaternion);\r\n        Vector3.LerpToRef(axisMap.minMesh.position, axisMap.maxMesh.position, lerpValue, axisMap.valueMesh.position);\r\n    }\r\n\r\n    /**\r\n     * Update the model itself with the current frame data\r\n     * @param xrFrame the frame to use for updating the model mesh\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected updateModel(xrFrame: XRFrame): void {\r\n        if (!this._modelReady) {\r\n            return;\r\n        }\r\n        this._updateModel(xrFrame);\r\n    }\r\n\r\n    /**\r\n     * Get the filename and path for this controller's model\r\n     * @returns a map of filename and path\r\n     */\r\n    protected abstract _getFilenameAndPath(): { filename: string; path: string };\r\n    /**\r\n     * This function is called before the mesh is loaded. It checks for loading constraints.\r\n     * For example, this function can check if the GLB loader is available\r\n     * If this function returns false, the generic controller will be loaded instead\r\n     * @returns Is the client ready to load the mesh\r\n     */\r\n    protected abstract _getModelLoadingConstraints(): boolean;\r\n    /**\r\n     * This function will be called after the model was successfully loaded and can be used\r\n     * for mesh transformations before it is available for the user\r\n     * @param meshes the loaded meshes\r\n     */\r\n    protected abstract _processLoadedModel(meshes: AbstractMesh[]): void;\r\n    /**\r\n     * Set the root mesh for this controller. Important for the WebXR controller class\r\n     * @param meshes the loaded meshes\r\n     */\r\n    protected abstract _setRootMesh(meshes: AbstractMesh[]): void;\r\n    /**\r\n     * A function executed each frame that updates the mesh (if needed)\r\n     * @param xrFrame the current xrFrame\r\n     */\r\n    protected abstract _updateModel(xrFrame: XRFrame): void;\r\n\r\n    private _getGenericFilenameAndPath(): { filename: string; path: string } {\r\n        return {\r\n            filename: \"generic.babylon\",\r\n            path: \"https://controllers.babylonjs.com/generic/\",\r\n        };\r\n    }\r\n\r\n    private _getGenericParentMesh(meshes: AbstractMesh[]): void {\r\n        this.rootMesh = new Mesh(this.profileId + \" \" + this.handedness, this.scene);\r\n\r\n        for (const mesh of meshes) {\r\n            if (!mesh.parent) {\r\n                mesh.isPickable = false;\r\n                mesh.setParent(this.rootMesh);\r\n            }\r\n        }\r\n\r\n        this.rootMesh.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);\r\n    }\r\n}\r\n","import { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type IMotionControllerProfile, type IMotionControllerMeshMap, WebXRAbstractMotionController } from \"./webXRAbstractMotionController\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { SceneLoader } from \"../../Loading/sceneLoader\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Axis, Space } from \"../../Maths/math.axis\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { WebXRControllerComponent } from \"./webXRControllerComponent\";\r\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder.pure\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\n\r\n/**\r\n * A profiled motion controller has its profile loaded from an online repository.\r\n * The class is responsible of loading the model, mapping the keys and enabling model-animations\r\n */\r\nexport class WebXRProfiledMotionController extends WebXRAbstractMotionController {\r\n    private _buttonMeshMapping: {\r\n        [buttonName: string]: {\r\n            mainMesh?: AbstractMesh;\r\n            states: {\r\n                [state: string]: IMotionControllerMeshMap;\r\n            };\r\n        };\r\n    } = {};\r\n    private _touchDots: { [visKey: string]: AbstractMesh } = {};\r\n\r\n    /**\r\n     * The profile ID of this controller. Will be populated when the controller initializes.\r\n     */\r\n    public profileId: string;\r\n\r\n    constructor(\r\n        scene: Scene,\r\n        xrInput: XRInputSource,\r\n        _profile: IMotionControllerProfile,\r\n        private _repositoryUrl: string,\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        private controllerCache?: Array<{\r\n            filename: string;\r\n            path: string;\r\n            meshes: AbstractMesh[];\r\n        }>\r\n    ) {\r\n        super(scene, _profile.layouts[xrInput.handedness || \"none\"], xrInput.gamepad as any, xrInput.handedness, undefined, controllerCache);\r\n        this.profileId = _profile.profileId;\r\n    }\r\n\r\n    public override dispose() {\r\n        super.dispose();\r\n        if (!this.controllerCache) {\r\n            const keys = Object.keys(this._touchDots);\r\n            for (const visResKey of keys) {\r\n                this._touchDots[visResKey].dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        return {\r\n            filename: this.layout.assetPath,\r\n            path: `${this._repositoryUrl}/profiles/${this.profileId}/`,\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        const glbLoaded = SceneLoader.IsPluginForExtensionAvailable(\".glb\");\r\n        if (!glbLoaded) {\r\n            Logger.Warn(\"glTF / glb loader was not registered, using generic controller instead\");\r\n        }\r\n        return glbLoaded;\r\n    }\r\n\r\n    protected _processLoadedModel(_meshes: AbstractMesh[]): void {\r\n        const ids = this.getComponentIds();\r\n\r\n        for (const type of ids) {\r\n            const componentInLayout = this.layout.components[type];\r\n            this._buttonMeshMapping[type] = {\r\n                mainMesh: this._getChildByName(this.rootMesh!, componentInLayout.rootNodeName),\r\n                states: {},\r\n            };\r\n            const keys = Object.keys(componentInLayout.visualResponses);\r\n            for (const visualResponseKey of keys) {\r\n                const visResponse = componentInLayout.visualResponses[visualResponseKey];\r\n                if (visResponse.valueNodeProperty === \"transform\") {\r\n                    this._buttonMeshMapping[type].states[visualResponseKey] = {\r\n                        valueMesh: this._getChildByName(this.rootMesh!, visResponse.valueNodeName!),\r\n                        minMesh: this._getChildByName(this.rootMesh!, visResponse.minNodeName!),\r\n                        maxMesh: this._getChildByName(this.rootMesh!, visResponse.maxNodeName!),\r\n                    };\r\n                } else {\r\n                    // visibility, usually for touchpads\r\n                    const nameOfMesh =\r\n                        componentInLayout.type === WebXRControllerComponent.TOUCHPAD_TYPE && componentInLayout.touchPointNodeName\r\n                            ? componentInLayout.touchPointNodeName\r\n                            : visResponse.valueNodeName!;\r\n                    this._buttonMeshMapping[type].states[visualResponseKey] = {\r\n                        valueMesh: this._getChildByName(this.rootMesh!, nameOfMesh),\r\n                    };\r\n                    if (componentInLayout.type === WebXRControllerComponent.TOUCHPAD_TYPE && !this._touchDots[visualResponseKey]) {\r\n                        const dot = CreateSphere(\r\n                            visualResponseKey + \"dot\",\r\n                            {\r\n                                diameter: 0.0015,\r\n                                segments: 8,\r\n                            },\r\n                            this.scene\r\n                        );\r\n                        dot.material = new StandardMaterial(visualResponseKey + \"mat\", this.scene);\r\n                        (<StandardMaterial>dot.material).diffuseColor = Color3.Red();\r\n                        dot.parent = this._buttonMeshMapping[type].states[visualResponseKey].valueMesh || null;\r\n                        dot.isVisible = false;\r\n                        this._touchDots[visualResponseKey] = dot;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        this.rootMesh = new Mesh(this.profileId + \"-\" + this.handedness, this.scene);\r\n        this.rootMesh.isPickable = false;\r\n        let rootMesh;\r\n        // Find the root node in the loaded glTF scene, and attach it as a child of 'parentMesh'\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const mesh = meshes[i];\r\n\r\n            mesh.isPickable = false;\r\n\r\n            if (!mesh.parent) {\r\n                // Handle root node, attach to the new parentMesh\r\n                rootMesh = mesh;\r\n            }\r\n        }\r\n\r\n        if (rootMesh) {\r\n            rootMesh.setParent(this.rootMesh);\r\n        }\r\n        if (!this.scene.useRightHandedSystem) {\r\n            this.rootMesh.rotate(Axis.Y, Math.PI, Space.WORLD);\r\n        }\r\n    }\r\n\r\n    protected _updateModel(_xrFrame: XRFrame): void {\r\n        if (this.disableAnimation) {\r\n            return;\r\n        }\r\n        const ids = this.getComponentIds();\r\n\r\n        for (const id of ids) {\r\n            const component = this.getComponent(id);\r\n            if (!component.hasChanges) {\r\n                continue;\r\n            }\r\n            const meshes = this._buttonMeshMapping[id];\r\n            const componentInLayout = this.layout.components[id];\r\n            const keys = Object.keys(componentInLayout.visualResponses);\r\n            for (const visualResponseKey of keys) {\r\n                const visResponse = componentInLayout.visualResponses[visualResponseKey];\r\n                let value = component.value;\r\n                if (visResponse.componentProperty === \"xAxis\") {\r\n                    value = component.axes.x;\r\n                } else if (visResponse.componentProperty === \"yAxis\") {\r\n                    value = component.axes.y;\r\n                }\r\n                if (visResponse.valueNodeProperty === \"transform\") {\r\n                    this._lerpTransform(meshes.states[visualResponseKey], value, visResponse.componentProperty !== \"button\");\r\n                } else {\r\n                    // visibility\r\n                    const valueMesh = meshes.states[visualResponseKey].valueMesh;\r\n                    if (valueMesh) {\r\n                        valueMesh.isVisible = component.touched || component.pressed;\r\n                    }\r\n                    if (this._touchDots[visualResponseKey]) {\r\n                        this._touchDots[visualResponseKey].isVisible = component.touched || component.pressed;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import {\r\n    type IMinimalMotionControllerObject,\r\n    type MotionControllerHandedness,\r\n    type IMotionControllerLayoutMap,\r\n    WebXRAbstractMotionController,\r\n} from \"./webXRAbstractMotionController\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * A generic trigger-only motion controller for WebXR\r\n */\r\nexport class WebXRGenericTriggerMotionController extends WebXRAbstractMotionController {\r\n    /**\r\n     * Static version of the profile id of this controller\r\n     */\r\n    public static ProfileId = \"generic-trigger\";\r\n\r\n    public profileId = WebXRGenericTriggerMotionController.ProfileId;\r\n\r\n    constructor(scene: Scene, gamepadObject: IMinimalMotionControllerObject, handedness: MotionControllerHandedness) {\r\n        super(scene, GenericTriggerLayout[handedness], gamepadObject, handedness);\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        return {\r\n            filename: \"generic.babylon\",\r\n            path: \"https://controllers.babylonjs.com/generic/\",\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        return true;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _processLoadedModel(meshes: AbstractMesh[]): void {\r\n        // nothing to do\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        this.rootMesh = new Mesh(this.profileId + \" \" + this.handedness, this.scene);\r\n\r\n        for (const mesh of meshes) {\r\n            mesh.isPickable = false;\r\n            if (!mesh.parent) {\r\n                mesh.setParent(this.rootMesh);\r\n            }\r\n        }\r\n\r\n        this.rootMesh.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);\r\n    }\r\n\r\n    protected _updateModel(): void {\r\n        // no-op\r\n    }\r\n}\r\n\r\n// https://github.com/immersive-web/webxr-input-profiles/blob/master/packages/registry/profiles/generic/generic-trigger-touchpad-thumbstick.json\r\nconst GenericTriggerLayout: IMotionControllerLayoutMap = {\r\n    left: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"generic-trigger-left\",\r\n        assetPath: \"left.glb\",\r\n    },\r\n    right: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"generic-trigger-right\",\r\n        assetPath: \"right.glb\",\r\n    },\r\n    none: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"generic-trigger-none\",\r\n        assetPath: \"none.glb\",\r\n    },\r\n};\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type WebXRAbstractMotionController, type IMotionControllerProfile } from \"./webXRAbstractMotionController\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { WebXRProfiledMotionController } from \"./webXRProfiledMotionController\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { WebXRGenericTriggerMotionController } from \"./webXRGenericMotionController\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * A construction function type to create a new controller based on an xrInput object\r\n */\r\nexport type MotionControllerConstructor = (xrInput: XRInputSource, scene: Scene) => WebXRAbstractMotionController;\r\n\r\n/**\r\n * The MotionController Manager manages all registered motion controllers and loads the right one when needed.\r\n *\r\n * When this repository is complete: https://github.com/immersive-web/webxr-input-profiles/tree/master/packages/assets\r\n * it should be replaced with auto-loaded controllers.\r\n *\r\n * When using a model try to stay as generic as possible. Eventually there will be no need in any of the controller classes\r\n */\r\n\r\nconst ControllerCache: Array<{\r\n    filename: string;\r\n    path: string;\r\n    meshes: AbstractMesh[];\r\n}> = [];\r\n\r\n/**\r\n * Motion controller manager is managing the different webxr profiles and makes sure the right\r\n * controller is being loaded.\r\n */\r\nexport class WebXRMotionControllerManager {\r\n    private static _AvailableControllers: { [type: string]: MotionControllerConstructor } = {};\r\n    private static _Fallbacks: { [profileId: string]: string[] } = {};\r\n    // cache for loading\r\n    private static _ProfileLoadingPromises: { [profileName: string]: Promise<IMotionControllerProfile> } = {};\r\n    private static _ProfilesList: Nullable<Promise<{ [profile: string]: string }>>;\r\n\r\n    /**\r\n     * The base URL of the online controller repository. Can be changed at any time.\r\n     */\r\n    public static BaseRepositoryUrl = \"https://immersive-web.github.io/webxr-input-profiles/packages/viewer/dist\";\r\n    /**\r\n     * Which repository gets priority - local or online\r\n     */\r\n    public static PrioritizeOnlineRepository: boolean = true;\r\n    /**\r\n     * Use the online repository, or use only locally-defined controllers\r\n     */\r\n    public static UseOnlineRepository: boolean = true;\r\n\r\n    /**\r\n     * Disable the controller cache and load the models each time a new WebXRProfileMotionController is loaded.\r\n     * Defaults to true.\r\n     */\r\n    public static DisableControllerCache: boolean = true;\r\n\r\n    /**\r\n     * Clear the cache used for profile loading and reload when requested again\r\n     */\r\n    public static ClearProfilesCache() {\r\n        this._ProfilesList = null;\r\n        this._ProfileLoadingPromises = {};\r\n    }\r\n\r\n    /**\r\n     * Register the default fallbacks.\r\n     * This function is called automatically when this file is imported.\r\n     */\r\n    public static DefaultFallbacks() {\r\n        this.RegisterFallbacksForProfileId(\"google-daydream\", [\"generic-touchpad\"]);\r\n        this.RegisterFallbacksForProfileId(\"htc-vive-focus\", [\"generic-trigger-touchpad\"]);\r\n        this.RegisterFallbacksForProfileId(\"htc-vive\", [\"generic-trigger-squeeze-touchpad\"]);\r\n        this.RegisterFallbacksForProfileId(\"magicleap-one\", [\"generic-trigger-squeeze-touchpad\"]);\r\n        this.RegisterFallbacksForProfileId(\"windows-mixed-reality\", [\"generic-trigger-squeeze-touchpad-thumbstick\"]);\r\n        this.RegisterFallbacksForProfileId(\"microsoft-mixed-reality\", [\"windows-mixed-reality\", \"generic-trigger-squeeze-touchpad-thumbstick\"]);\r\n        this.RegisterFallbacksForProfileId(\"oculus-go\", [\"generic-trigger-touchpad\"]);\r\n        this.RegisterFallbacksForProfileId(\"oculus-touch-v2\", [\"oculus-touch\", \"generic-trigger-squeeze-thumbstick\"]);\r\n        this.RegisterFallbacksForProfileId(\"oculus-touch\", [\"generic-trigger-squeeze-thumbstick\"]);\r\n        this.RegisterFallbacksForProfileId(\"samsung-gearvr\", [\"windows-mixed-reality\", \"generic-trigger-squeeze-touchpad-thumbstick\"]);\r\n        this.RegisterFallbacksForProfileId(\"samsung-odyssey\", [\"generic-touchpad\"]);\r\n        this.RegisterFallbacksForProfileId(\"valve-index\", [\"generic-trigger-squeeze-touchpad-thumbstick\"]);\r\n        this.RegisterFallbacksForProfileId(\"generic-hand-select\", [\"generic-trigger\"]);\r\n        this.RegisterFallbacksForProfileId(\"oculus-hand\", [\"generic-trigger\"]);\r\n    }\r\n\r\n    /**\r\n     * Find a fallback profile if the profile was not found. There are a few predefined generic profiles.\r\n     * @param profileId the profile to which a fallback needs to be found\r\n     * @returns an array with corresponding fallback profiles\r\n     */\r\n    public static FindFallbackWithProfileId(profileId: string): string[] {\r\n        const returnArray = [...(this._Fallbacks[profileId] || [])];\r\n\r\n        returnArray.unshift(profileId);\r\n        return returnArray;\r\n    }\r\n\r\n    /**\r\n     * When acquiring a new xrInput object (usually by the WebXRInput class), match it with the correct profile.\r\n     * The order of search:\r\n     *\r\n     * 1) Iterate the profiles array of the xr input and try finding a corresponding motion controller\r\n     * 2) (If not found) search in the gamepad id and try using it (legacy versions only)\r\n     * 3) search for registered fallbacks (should be redundant, nonetheless it makes sense to check)\r\n     * 4) return the generic trigger controller if none were found\r\n     *\r\n     * @param xrInput the xrInput to which a new controller is initialized\r\n     * @param scene the scene to which the model will be added\r\n     * @param forceProfile force a certain profile for this controller\r\n     * @returns A promise that fulfils with the motion controller class for this profile id or the generic standard class if none was found\r\n     */\r\n    public static async GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene, forceProfile?: string): Promise<WebXRAbstractMotionController> {\r\n        const profileArray: string[] = [];\r\n        if (forceProfile) {\r\n            profileArray.push(forceProfile);\r\n        }\r\n        profileArray.push(...(xrInput.profiles || []));\r\n\r\n        // emulator support\r\n        if (profileArray.length && !profileArray[0]) {\r\n            // remove the first \"undefined\" that the emulator is adding\r\n            profileArray.shift();\r\n        }\r\n\r\n        // legacy support - try using the gamepad id\r\n        if (xrInput.gamepad && xrInput.gamepad.id) {\r\n            switch (xrInput.gamepad.id) {\r\n                case xrInput.gamepad.id.match(/oculus touch/gi) ? xrInput.gamepad.id : undefined:\r\n                    // oculus in gamepad id\r\n                    profileArray.push(\"oculus-touch-v2\");\r\n                    break;\r\n            }\r\n        }\r\n\r\n        // make sure microsoft/windows mixed reality works correctly\r\n        const windowsMRIdx = profileArray.indexOf(\"windows-mixed-reality\");\r\n        if (windowsMRIdx !== -1) {\r\n            profileArray.splice(windowsMRIdx, 0, \"microsoft-mixed-reality\");\r\n        }\r\n\r\n        if (!profileArray.length) {\r\n            profileArray.push(\"generic-trigger\");\r\n        }\r\n\r\n        if (this.UseOnlineRepository) {\r\n            const firstFunction = this.PrioritizeOnlineRepository ? this._LoadProfileFromRepositoryAsync : this._LoadProfilesFromAvailableControllersAsync;\r\n            const secondFunction = this.PrioritizeOnlineRepository ? this._LoadProfilesFromAvailableControllersAsync : this._LoadProfileFromRepositoryAsync;\r\n\r\n            // eslint-disable-next-line github/no-then\r\n            return await firstFunction.call(this, profileArray, xrInput, scene).catch(async () => {\r\n                return await secondFunction.call(this, profileArray, xrInput, scene);\r\n            });\r\n        } else {\r\n            // use only available functions\r\n            return await this._LoadProfilesFromAvailableControllersAsync(profileArray, xrInput, scene);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Register a new controller based on its profile. This function will be called by the controller classes themselves.\r\n     *\r\n     * If you are missing a profile, make sure it is imported in your source, otherwise it will not register.\r\n     *\r\n     * @param type the profile type to register\r\n     * @param constructFunction the function to be called when loading this profile\r\n     */\r\n    public static RegisterController(type: string, constructFunction: MotionControllerConstructor) {\r\n        this._AvailableControllers[type] = constructFunction;\r\n    }\r\n\r\n    /**\r\n     * Register a fallback to a specific profile.\r\n     * @param profileId the profileId that will receive the fallbacks\r\n     * @param fallbacks A list of fallback profiles\r\n     */\r\n    public static RegisterFallbacksForProfileId(profileId: string, fallbacks: string[]): void {\r\n        if (this._Fallbacks[profileId]) {\r\n            this._Fallbacks[profileId].push(...fallbacks);\r\n        } else {\r\n            this._Fallbacks[profileId] = fallbacks;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Will update the list of profiles available in the repository\r\n     * @returns a promise that resolves to a map of profiles available online\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static async UpdateProfilesList(): Promise<{\r\n        [profile: string]: string;\r\n    }> {\r\n        const data = await Tools.LoadFileAsync(this.BaseRepositoryUrl + \"/profiles/profilesList.json\", false);\r\n        this._ProfilesList = JSON.parse(data);\r\n        return await this._ProfilesList!;\r\n    }\r\n\r\n    /**\r\n     * Clear the controller's cache (usually happens at the end of a session)\r\n     */\r\n    public static ClearControllerCache() {\r\n        for (const cacheItem of ControllerCache) {\r\n            for (const mesh of cacheItem.meshes) {\r\n                mesh.dispose(false, true);\r\n            }\r\n        }\r\n        ControllerCache.length = 0;\r\n    }\r\n\r\n    private static async _LoadProfileFromRepositoryAsync(profileArray: string[], xrInput: XRInputSource, scene: Scene): Promise<WebXRAbstractMotionController> {\r\n        return await Promise.resolve()\r\n            // eslint-disable-next-line github/no-then\r\n            .then(async () => {\r\n                if (!this._ProfilesList) {\r\n                    return await this.UpdateProfilesList();\r\n                } else {\r\n                    return await this._ProfilesList;\r\n                }\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .then((profilesList: { [profile: string]: string }) => {\r\n                // load the right profile\r\n                for (let i = 0; i < profileArray.length; ++i) {\r\n                    // defensive\r\n                    if (!profileArray[i]) {\r\n                        continue;\r\n                    }\r\n                    if (profilesList[profileArray[i]]) {\r\n                        return profileArray[i];\r\n                    }\r\n                }\r\n\r\n                throw new Error(`neither controller ${profileArray[0]} nor all fallbacks were found in the repository,`);\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .then(async (profileToLoad: string) => {\r\n                // load the profile\r\n                // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n                if (!this._ProfileLoadingPromises[profileToLoad]) {\r\n                    // eslint-disable-next-line github/no-then\r\n                    this._ProfileLoadingPromises[profileToLoad] = Tools.LoadFileAsync(`${this.BaseRepositoryUrl}/profiles/${profileToLoad}/profile.json`, false).then(\r\n                        (data) => <IMotionControllerProfile>JSON.parse(data)\r\n                    );\r\n                }\r\n                return await this._ProfileLoadingPromises[profileToLoad];\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .then((profile: IMotionControllerProfile) => {\r\n                return new WebXRProfiledMotionController(scene, xrInput, profile, this.BaseRepositoryUrl, this.DisableControllerCache ? undefined : ControllerCache);\r\n            });\r\n    }\r\n\r\n    private static async _LoadProfilesFromAvailableControllersAsync(profileArray: string[], xrInput: XRInputSource, scene: Scene) {\r\n        // check fallbacks\r\n        for (let i = 0; i < profileArray.length; ++i) {\r\n            // defensive\r\n            if (!profileArray[i]) {\r\n                continue;\r\n            }\r\n            const fallbacks = this.FindFallbackWithProfileId(profileArray[i]);\r\n            for (let j = 0; j < fallbacks.length; ++j) {\r\n                const constructionFunction = this._AvailableControllers[fallbacks[j]];\r\n                if (constructionFunction) {\r\n                    return constructionFunction(xrInput, scene);\r\n                }\r\n            }\r\n        }\r\n\r\n        throw new Error(`no controller requested was found in the available controllers list`);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRMotionControllerManager.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRMotionControllerManager(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the generic profile(s) here so we will at least have them\r\n    WebXRMotionControllerManager.RegisterController(WebXRGenericTriggerMotionController.ProfileId, (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXRGenericTriggerMotionController(scene, <any>xrInput.gamepad, xrInput.handedness);\r\n    });\r\n\r\n    // register fallbacks\r\n    WebXRMotionControllerManager.DefaultFallbacks();\r\n}\r\n","import { Observable } from \"../Misc/observable\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Ray } from \"../Culling/ray\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type WebXRAbstractMotionController } from \"./motionController/webXRAbstractMotionController\";\r\nimport { WebXRMotionControllerManager } from \"./motionController/webXRMotionControllerManager.pure\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type WebXRCamera } from \"./webXRCamera\";\r\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\n\r\nlet IdCount = 0;\r\n\r\n/**\r\n * Configuration options for the WebXR controller creation\r\n */\r\nexport interface IWebXRControllerOptions {\r\n    /**\r\n     * Should the controller mesh be animated when a user interacts with it\r\n     * The pressed buttons / thumbstick and touchpad animations will be disabled\r\n     */\r\n    disableMotionControllerAnimation?: boolean;\r\n    /**\r\n     * Do not load the controller mesh, in case a different mesh needs to be loaded.\r\n     */\r\n    doNotLoadControllerMesh?: boolean;\r\n    /**\r\n     * Force a specific controller type for this controller.\r\n     * This can be used when creating your own profile or when testing different controllers\r\n     */\r\n    forceControllerProfile?: string;\r\n    /**\r\n     * Defines a rendering group ID for meshes that will be loaded.\r\n     * This is for the default controllers only.\r\n     */\r\n    renderingGroupId?: number;\r\n}\r\n\r\n/**\r\n * Represents an XR controller\r\n */\r\nexport class WebXRInputSource {\r\n    private _tmpVector = new Vector3();\r\n    private _uniqueId: string;\r\n    private _disposed = false;\r\n\r\n    /**\r\n     * Represents the part of the controller that is held. This may not exist if the controller is the head mounted display itself, if that's the case only the pointer from the head will be available\r\n     */\r\n    public grip?: AbstractMesh;\r\n    /**\r\n     * If available, this is the gamepad object related to this controller.\r\n     * Using this object it is possible to get click events and trackpad changes of the\r\n     * webxr controller that is currently being used.\r\n     */\r\n    public motionController?: WebXRAbstractMotionController;\r\n    /**\r\n     * Event that fires when the controller is removed/disposed.\r\n     * The object provided as event data is this controller, after associated assets were disposed.\r\n     * uniqueId is still available.\r\n     */\r\n    public onDisposeObservable = new Observable<WebXRInputSource>();\r\n    /**\r\n     * Will be triggered when the mesh associated with the motion controller is done loading.\r\n     * It is also possible that this will never trigger (!) if no mesh was loaded, or if the developer decides to load a different mesh\r\n     * A shortened version of controller -> motion controller -> on mesh loaded.\r\n     */\r\n    public onMeshLoadedObservable = new Observable<AbstractMesh>();\r\n    /**\r\n     * Observers registered here will trigger when a motion controller profile was assigned to this xr controller\r\n     */\r\n    public onMotionControllerInitObservable = new Observable<WebXRAbstractMotionController>();\r\n    /**\r\n     * Pointer which can be used to select objects or attach a visible laser to\r\n     */\r\n    public pointer: AbstractMesh;\r\n\r\n    /**\r\n     * The last XRPose the was calculated on the current XRFrame\r\n     * @internal\r\n     */\r\n    public _lastXRPose?: XRPose;\r\n\r\n    /**\r\n     * Creates the input source object\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRInputControllerSupport\r\n     * @param _scene the scene which the controller should be associated to\r\n     * @param inputSource the underlying input source for the controller\r\n     * @param _options options for this controller creation\r\n     */\r\n    constructor(\r\n        private _scene: Scene,\r\n        /** The underlying input source for the controller  */\r\n        public inputSource: XRInputSource,\r\n        private _options: IWebXRControllerOptions = {}\r\n    ) {\r\n        this._uniqueId = `controller-${IdCount++}-${inputSource.targetRayMode}-${inputSource.handedness}`;\r\n\r\n        this.pointer = new Mesh(`${this._uniqueId}-pointer`, _scene);\r\n        this.pointer.rotationQuaternion = new Quaternion();\r\n\r\n        if (this.inputSource.gripSpace) {\r\n            this.grip = new Mesh(`${this._uniqueId}-grip`, this._scene);\r\n            this.grip.rotationQuaternion = new Quaternion();\r\n        }\r\n\r\n        this._tmpVector.set(0, 0, this._scene.useRightHandedSystem ? -1.0 : 1.0);\r\n\r\n        // for now only load motion controllers if gamepad object available\r\n        if (this.inputSource.gamepad && this.inputSource.targetRayMode === \"tracked-pointer\") {\r\n            // eslint-disable-next-line github/no-then\r\n            WebXRMotionControllerManager.GetMotionControllerWithXRInput(inputSource, _scene, this._options.forceControllerProfile).then(\r\n                (motionController) => {\r\n                    this.motionController = motionController;\r\n                    this.onMotionControllerInitObservable.notifyObservers(motionController);\r\n                    // should the model be loaded?\r\n                    if (!this._options.doNotLoadControllerMesh && !this.inputSource.skipRendering && !this.motionController._doNotLoadControllerMesh) {\r\n                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                        this.motionController.loadModel().then((success) => {\r\n                            if (success && this.motionController && this.motionController.rootMesh) {\r\n                                if (this._options.renderingGroupId) {\r\n                                    // anything other than 0?\r\n                                    this.motionController.rootMesh.renderingGroupId = this._options.renderingGroupId;\r\n                                    const childMeshes = this.motionController.rootMesh.getChildMeshes(false);\r\n                                    for (const mesh of childMeshes) {\r\n                                        mesh.renderingGroupId = this._options.renderingGroupId!;\r\n                                    }\r\n                                }\r\n                                this.onMeshLoadedObservable.notifyObservers(this.motionController.rootMesh);\r\n                                this.motionController.rootMesh.parent = this.grip || this.pointer;\r\n                                this.motionController.disableAnimation = !!this._options.disableMotionControllerAnimation;\r\n                            }\r\n                            // make sure to dispose is the controller is already disposed\r\n                            if (this._disposed) {\r\n                                this.motionController?.dispose();\r\n                            }\r\n                        });\r\n                    }\r\n                },\r\n                () => {\r\n                    Tools.Warn(`Could not find a matching motion controller for the registered input source`);\r\n                }\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get this controllers unique id\r\n     */\r\n    public get uniqueId() {\r\n        return this._uniqueId;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the object\r\n     */\r\n    public dispose() {\r\n        if (this.grip) {\r\n            this.grip.dispose(true);\r\n        }\r\n        if (this.motionController) {\r\n            this.motionController.dispose();\r\n        }\r\n        this.pointer.dispose(true);\r\n        this.onMotionControllerInitObservable.clear();\r\n        this.onMeshLoadedObservable.clear();\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n        this._disposed = true;\r\n    }\r\n\r\n    /**\r\n     * Gets a world space ray coming from the pointer or grip\r\n     * @param result the resulting ray\r\n     * @param gripIfAvailable use the grip mesh instead of the pointer, if available\r\n     */\r\n    public getWorldPointerRayToRef(result: Ray, gripIfAvailable: boolean = false) {\r\n        const object = gripIfAvailable && this.grip ? this.grip : this.pointer;\r\n        Vector3.TransformNormalToRef(this._tmpVector, object.getWorldMatrix(), result.direction);\r\n        result.direction.normalize();\r\n        result.origin.copyFrom(object.absolutePosition);\r\n        result.length = 1000;\r\n    }\r\n\r\n    /**\r\n     * Updates the controller pose based on the given XRFrame\r\n     * @param xrFrame xr frame to update the pose with\r\n     * @param referenceSpace reference space to use\r\n     * @param xrCamera the xr camera, used for parenting\r\n     * @param xrSessionManager the session manager used to get the world reference system\r\n     */\r\n    public updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace, xrCamera: WebXRCamera, xrSessionManager: WebXRSessionManager) {\r\n        const pose = xrFrame.getPose(this.inputSource.targetRaySpace, referenceSpace);\r\n        this._lastXRPose = pose;\r\n\r\n        // Update the pointer mesh\r\n        if (pose) {\r\n            const pos = pose.transform.position;\r\n            this.pointer.position.set(pos.x, pos.y, pos.z).scaleInPlace(xrSessionManager.worldScalingFactor);\r\n            const orientation = pose.transform.orientation;\r\n            this.pointer.rotationQuaternion!.set(orientation.x, orientation.y, orientation.z, orientation.w);\r\n            if (!this._scene.useRightHandedSystem) {\r\n                this.pointer.position.z *= -1;\r\n                this.pointer.rotationQuaternion!.z *= -1;\r\n                this.pointer.rotationQuaternion!.w *= -1;\r\n            }\r\n            this.pointer.parent = xrCamera.parent;\r\n            this.pointer.scaling.setAll(xrSessionManager.worldScalingFactor);\r\n        }\r\n\r\n        // Update the grip mesh if it exists\r\n        if (this.inputSource.gripSpace && this.grip) {\r\n            const pose = xrFrame.getPose(this.inputSource.gripSpace, referenceSpace);\r\n            if (pose) {\r\n                const pos = pose.transform.position;\r\n                const orientation = pose.transform.orientation;\r\n                this.grip.position.set(pos.x, pos.y, pos.z).scaleInPlace(xrSessionManager.worldScalingFactor);\r\n                this.grip.rotationQuaternion!.set(orientation.x, orientation.y, orientation.z, orientation.w);\r\n                if (!this._scene.useRightHandedSystem) {\r\n                    this.grip.position.z *= -1;\r\n                    this.grip.rotationQuaternion!.z *= -1;\r\n                    this.grip.rotationQuaternion!.w *= -1;\r\n                }\r\n            }\r\n            this.grip.parent = xrCamera.parent;\r\n            this.grip.scaling.setAll(xrSessionManager.worldScalingFactor);\r\n        }\r\n        if (this.motionController) {\r\n            // either update buttons only or also position, if in gamepad mode\r\n            this.motionController.updateFromXRFrame(xrFrame);\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type IDisposable } from \"../scene\";\r\nimport { type IWebXRControllerOptions, WebXRInputSource } from \"./webXRInputSource\";\r\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { type WebXRCamera } from \"./webXRCamera\";\r\nimport { WebXRMotionControllerManager } from \"./motionController/webXRMotionControllerManager.pure\";\r\n\r\n/**\r\n * The schema for initialization options of the XR Input class\r\n */\r\nexport interface IWebXRInputOptions {\r\n    /**\r\n     * If set to true no model will be automatically loaded\r\n     */\r\n    doNotLoadControllerMeshes?: boolean;\r\n\r\n    /**\r\n     * If set, this profile will be used for all controllers loaded (for example \"microsoft-mixed-reality\")\r\n     * If not found, the xr input profile data will be used.\r\n     * Profiles are defined here - https://github.com/immersive-web/webxr-input-profiles/\r\n     */\r\n    forceInputProfile?: string;\r\n\r\n    /**\r\n     * Do not send a request to the controller repository to load the profile.\r\n     *\r\n     * Instead, use the controllers available in babylon itself.\r\n     */\r\n    disableOnlineControllerRepository?: boolean;\r\n\r\n    /**\r\n     * A custom URL for the controllers repository\r\n     */\r\n    customControllersRepositoryURL?: string;\r\n\r\n    /**\r\n     * Should the controller model's components not move according to the user input\r\n     */\r\n    disableControllerAnimation?: boolean;\r\n\r\n    /**\r\n     * Optional options to pass to the controller. Will be overridden by the Input options where applicable\r\n     */\r\n    controllerOptions?: IWebXRControllerOptions;\r\n}\r\n/**\r\n * XR input used to track XR inputs such as controllers/rays\r\n */\r\nexport class WebXRInput implements IDisposable {\r\n    /**\r\n     * XR controllers being tracked\r\n     */\r\n    public controllers: Array<WebXRInputSource> = [];\r\n    private _frameObserver: Nullable<Observer<any>>;\r\n    private _sessionEndedObserver: Nullable<Observer<any>>;\r\n    private _sessionInitObserver: Nullable<Observer<any>>;\r\n    private _currentXRSession: Nullable<XRSession> = null;\r\n    /**\r\n     * Event when a controller has been connected/added\r\n     */\r\n    public onControllerAddedObservable = new Observable<WebXRInputSource>();\r\n    /**\r\n     * Event when a controller has been removed/disconnected\r\n     */\r\n    public onControllerRemovedObservable = new Observable<WebXRInputSource>();\r\n\r\n    /**\r\n     * Initializes the WebXRInput\r\n     * @param xrSessionManager the xr session manager for this session\r\n     * @param xrCamera the WebXR camera for this session. Mainly used for teleportation\r\n     * @param _options = initialization options for this xr input\r\n     */\r\n    public constructor(\r\n        /**\r\n         * the xr session manager for this session\r\n         */\r\n        public xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * the WebXR camera for this session. Mainly used for teleportation\r\n         */\r\n        public xrCamera: WebXRCamera,\r\n        private readonly _options: IWebXRInputOptions = {}\r\n    ) {\r\n        // Remove controllers when exiting XR\r\n        this._sessionEndedObserver = this.xrSessionManager.onXRSessionEnded.add(() => {\r\n            this._currentXRSession?.removeEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n            this._currentXRSession = null;\r\n            this._addAndRemoveControllers(\r\n                [],\r\n                this.controllers.map((c) => {\r\n                    return c.inputSource;\r\n                })\r\n            );\r\n        });\r\n\r\n        this._sessionInitObserver = this.xrSessionManager.onXRSessionInit.add((session) => {\r\n            this._currentXRSession = session;\r\n            session.addEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n        });\r\n\r\n        this._frameObserver = this.xrSessionManager.onXRFrameObservable.add((frame) => {\r\n            // Update controller pose info\r\n            for (const controller of this.controllers) {\r\n                controller.updateFromXRFrame(frame, this.xrSessionManager.referenceSpace, this.xrCamera, this.xrSessionManager);\r\n            }\r\n        });\r\n\r\n        if (this._options.customControllersRepositoryURL) {\r\n            WebXRMotionControllerManager.BaseRepositoryUrl = this._options.customControllersRepositoryURL;\r\n        }\r\n\r\n        WebXRMotionControllerManager.UseOnlineRepository = !this._options.disableOnlineControllerRepository;\r\n        if (WebXRMotionControllerManager.UseOnlineRepository) {\r\n            // pre-load the profiles list to load the controllers quicker afterwards\r\n            try {\r\n                // eslint-disable-next-line github/no-then\r\n                WebXRMotionControllerManager.UpdateProfilesList().catch(() => {\r\n                    WebXRMotionControllerManager.UseOnlineRepository = false;\r\n                });\r\n            } catch (e) {\r\n                WebXRMotionControllerManager.UseOnlineRepository = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onInputSourcesChange = (event: XRInputSourceChangeEvent) => {\r\n        this._addAndRemoveControllers(event.added, event.removed);\r\n    };\r\n\r\n    private _addAndRemoveControllers(addInputs: readonly XRInputSource[], removeInputs: readonly XRInputSource[]) {\r\n        // Add controllers if they don't already exist\r\n        const sources = this.controllers.map((c) => {\r\n            return c.inputSource;\r\n        });\r\n        for (const input of addInputs) {\r\n            if (sources.indexOf(input) === -1) {\r\n                const controller = new WebXRInputSource(this.xrSessionManager.scene, input, {\r\n                    ...(this._options.controllerOptions || {}),\r\n                    forceControllerProfile: this._options.forceInputProfile,\r\n                    doNotLoadControllerMesh: this._options.doNotLoadControllerMeshes,\r\n                    disableMotionControllerAnimation: this._options.disableControllerAnimation,\r\n                });\r\n                this.controllers.push(controller);\r\n                this.onControllerAddedObservable.notifyObservers(controller);\r\n            }\r\n        }\r\n\r\n        // Remove and dispose of controllers to be disposed\r\n        const keepControllers: Array<WebXRInputSource> = [];\r\n        const removedControllers: Array<WebXRInputSource> = [];\r\n        for (const c of this.controllers) {\r\n            if (removeInputs.indexOf(c.inputSource) === -1) {\r\n                keepControllers.push(c);\r\n            } else {\r\n                removedControllers.push(c);\r\n            }\r\n        }\r\n        this.controllers = keepControllers;\r\n        for (const c of removedControllers) {\r\n            this.onControllerRemovedObservable.notifyObservers(c);\r\n            c.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the object\r\n     */\r\n    public dispose() {\r\n        this._currentXRSession?.removeEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n        this._currentXRSession = null;\r\n        for (const c of this.controllers) {\r\n            c.dispose();\r\n        }\r\n        this.xrSessionManager.onXRFrameObservable.remove(this._frameObserver);\r\n        this.xrSessionManager.onXRSessionInit.remove(this._sessionInitObserver);\r\n        this.xrSessionManager.onXRSessionEnded.remove(this._sessionEndedObserver);\r\n        this.onControllerAddedObservable.clear();\r\n        this.onControllerRemovedObservable.clear();\r\n\r\n        // clear the controller cache\r\n        WebXRMotionControllerManager.ClearControllerCache();\r\n    }\r\n}\r\n","import { type IWebXRFeature } from \"../webXRFeaturesManager\";\r\nimport { _MarkWebXRFeatureWithSpecificDisableWarning } from \"../webXRFeatureWarningRegistry\";\r\nimport { type Observer, type EventState, Observable } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * This is the base class for all WebXR features.\r\n * Since most features require almost the same resources and callbacks, this class can be used to simplify the development\r\n * Note that since the features manager is using the `IWebXRFeature` you are in no way obligated to use this class\r\n */\r\nexport abstract class WebXRAbstractFeature implements IWebXRFeature {\r\n    private _attached: boolean = false;\r\n    private _disableAutoAttachWarningEmitted: boolean = false;\r\n    private _removeOnDetach: {\r\n        observer: Nullable<Observer<any>>;\r\n        observable: Observable<any>;\r\n    }[] = [];\r\n\r\n    /**\r\n     * Is this feature disposed?\r\n     */\r\n    public isDisposed: boolean = false;\r\n\r\n    /**\r\n     * Should auto-attach be disabled?\r\n     */\r\n    public disableAutoAttach: boolean = false;\r\n\r\n    /** @internal */\r\n    public _autoAttachPolicyBeforeAttach?: boolean;\r\n\r\n    protected _xrNativeFeatureName: string = \"\";\r\n\r\n    /**\r\n     * The name of the native xr feature name (like anchor, hit-test, or hand-tracking)\r\n     */\r\n    public get xrNativeFeatureName() {\r\n        return this._xrNativeFeatureName;\r\n    }\r\n\r\n    public set xrNativeFeatureName(name: string) {\r\n        // check if feature was initialized while in session but needs to be initialized before the session starts\r\n        if (!this._xrSessionManager.isNative && name && this._xrSessionManager.inXRSession && this._xrSessionManager.enabledFeatures?.indexOf(name) === -1) {\r\n            Logger.Warn(`The feature ${name} needs to be enabled before starting the XR session. Note - It is still possible it is not supported.`);\r\n        }\r\n        this._xrNativeFeatureName = name;\r\n    }\r\n\r\n    /**\r\n     * Observers registered here will be executed when the feature is attached\r\n     */\r\n    public onFeatureAttachObservable: Observable<IWebXRFeature> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when the feature is detached\r\n     */\r\n    public onFeatureDetachObservable: Observable<IWebXRFeature> = new Observable();\r\n\r\n    /**\r\n     * The dependencies of this feature, if any\r\n     */\r\n    public dependsOn?: string[];\r\n\r\n    /**\r\n     * Construct a new (abstract) WebXR feature\r\n     * @param _xrSessionManager the xr session manager for this feature\r\n     */\r\n    constructor(protected _xrSessionManager: WebXRSessionManager) {}\r\n\r\n    /**\r\n     * Is this feature attached\r\n     */\r\n    public get attached() {\r\n        return this._attached;\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     *\r\n     * @param force should attachment be forced (even when already attached)\r\n     * @returns true if successful, false is failed or already attached\r\n     */\r\n    public attach(force?: boolean): boolean {\r\n        // do not attach a disposed feature\r\n        if (this.isDisposed) {\r\n            return false;\r\n        }\r\n        if (!force) {\r\n            if (this.attached) {\r\n                return false;\r\n            }\r\n        } else {\r\n            if (this.attached) {\r\n                // detach first, to be sure\r\n                this.detach();\r\n            }\r\n        }\r\n\r\n        // if this is a native WebXR feature, check if it is enabled on the session\r\n        // For now only check if not using babylon native\r\n        // vision OS doesn't support the enabledFeatures array, so just warn instead of failing\r\n        if (!this._xrSessionManager.enabledFeatures) {\r\n            Logger.Warn(\"session.enabledFeatures is not available on this device. It is possible that this feature is not supported.\");\r\n        } else if (!this._xrSessionManager.isNative && this.xrNativeFeatureName && this._xrSessionManager.enabledFeatures.indexOf(this.xrNativeFeatureName) === -1) {\r\n            return false;\r\n        }\r\n\r\n        this._attached = true;\r\n        this._addNewAttachObserver(this._xrSessionManager.onXRFrameObservable, (frame) => this._onXRFrame(frame));\r\n        this.onFeatureAttachObservable.notifyObservers(this);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     *\r\n     * @returns true if successful, false if failed or already detached\r\n     */\r\n    public detach(): boolean {\r\n        if (!this._attached) {\r\n            this.disableAutoAttach = true;\r\n            return false;\r\n        }\r\n        this._attached = false;\r\n        for (const toRemove of this._removeOnDetach) {\r\n            toRemove.observable.remove(toRemove.observer);\r\n        }\r\n        this.onFeatureDetachObservable.notifyObservers(this);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public dispose(): void {\r\n        this.detach();\r\n        this.isDisposed = true;\r\n        this.onFeatureAttachObservable.clear();\r\n        this.onFeatureDetachObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * This function will be executed during before enabling the feature and can be used to not-allow enabling it.\r\n     * Note that at this point the session has NOT started, so this is purely checking if the browser supports it\r\n     *\r\n     * @returns whether or not the feature is compatible in this environment\r\n     */\r\n    public isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Disables future automatic attachment when a runtime capability required by the feature is unavailable.\r\n     * @param warning the specific warning explaining why the feature was disabled\r\n     * @returns false so feature attach implementations can return the result directly\r\n     */\r\n    protected _disableAutoAttach(warning: string): false {\r\n        if (!this._disableAutoAttachWarningEmitted) {\r\n            Logger.Warn(warning);\r\n            this._disableAutoAttachWarningEmitted = true;\r\n        }\r\n        _MarkWebXRFeatureWithSpecificDisableWarning(this);\r\n        this.disableAutoAttach = true;\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * This is used to register callbacks that will automatically be removed when detach is called.\r\n     * @param observable the observable to which the observer will be attached\r\n     * @param callback the callback to register\r\n     * @param insertFirst should the callback be executed as soon as it is registered\r\n     */\r\n    protected _addNewAttachObserver<T>(observable: Observable<T>, callback: (eventData: T, eventState: EventState) => void, insertFirst?: boolean) {\r\n        this._removeOnDetach.push({\r\n            observable,\r\n            observer: observable.add(callback, undefined, insertFirst),\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Code in this function will be executed on each xrFrame received from the browser.\r\n     * This function will not execute after the feature is detached.\r\n     * @param _xrFrame the current frame\r\n     */\r\n    protected abstract _onXRFrame(_xrFrame: XRFrame): void;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Observer } from \"../../Misc/observable.pure\";\r\nimport { type WebXRInput } from \"../webXRInput\";\r\nimport { type WebXRInputSource } from \"../webXRInputSource\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type WebXRControllerComponent } from \"../motionController/webXRControllerComponent\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial.pure\";\r\nimport { CreateCylinder } from \"../../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { CreateTorus } from \"../../Meshes/Builders/torusBuilder.pure\";\r\nimport { Ray, RegisterRay } from \"../../Culling/ray.pure\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer\";\r\nimport { type WebXRAbstractMotionController } from \"../motionController/webXRAbstractMotionController\";\r\nimport { type WebXRCamera } from \"../webXRCamera\";\r\nimport { type Node } from \"../../node\";\r\nimport { Viewport } from \"../../Maths/math.viewport\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\n\r\n/**\r\n * Options interface for the pointer selection module\r\n */\r\nexport interface IWebXRControllerPointerSelectionOptions {\r\n    /**\r\n     * if provided, this scene will be used to render meshes.\r\n     */\r\n    customUtilityLayerScene?: Scene;\r\n    /**\r\n     * Disable the pointer up event when the xr controller in screen and gaze mode is disposed (meaning - when the user removed the finger from the screen)\r\n     * If not disabled, the last picked point will be used to execute a pointer up event\r\n     * If disabled, pointer up event will be triggered right after the pointer down event.\r\n     * Used in screen and gaze target ray mode only\r\n     */\r\n    disablePointerUpOnTouchOut: boolean;\r\n    /**\r\n     * For gaze mode for tracked-pointer / controllers (time to select instead of button press)\r\n     */\r\n    forceGazeMode: boolean;\r\n    /**\r\n     * Factor to be applied to the pointer-moved function in the gaze mode. How sensitive should the gaze mode be when checking if the pointer moved\r\n     * to start a new countdown to the pointer down event.\r\n     * Defaults to 1.\r\n     */\r\n    gazeModePointerMovedFactor?: number;\r\n    /**\r\n     * Different button type to use instead of the main component\r\n     */\r\n    overrideButtonId?: string;\r\n    /**\r\n     *  use this rendering group id for the meshes (optional)\r\n     */\r\n    renderingGroupId?: number;\r\n    /**\r\n     * The amount of time in milliseconds it takes between pick found something to a pointer down event.\r\n     * Used in gaze modes. Tracked pointer uses the trigger, screen uses touch events\r\n     * 3000 means 3 seconds between pointing at something and selecting it\r\n     */\r\n    timeToSelect?: number;\r\n    /**\r\n     * Should meshes created here be added to a utility layer or the main scene\r\n     */\r\n    useUtilityLayer?: boolean;\r\n    /**\r\n     * Optional WebXR camera to be used for gaze selection\r\n     */\r\n    gazeCamera?: WebXRCamera;\r\n    /**\r\n     * the xr input to use with this pointer selection\r\n     */\r\n    xrInput: WebXRInput;\r\n\r\n    /**\r\n     * Should the scene pointerX and pointerY update be disabled\r\n     * This is required for fullscreen AR GUI, but might slow down other experiences.\r\n     * Disable in VR, if not needed.\r\n     * The first rig camera (left eye) will be used to calculate the projection\r\n     */\r\n    disableScenePointerVectorUpdate: boolean;\r\n\r\n    /**\r\n     * Enable pointer selection on all controllers instead of switching between them\r\n     */\r\n    enablePointerSelectionOnAllControllers?: boolean;\r\n\r\n    /**\r\n     * The preferred hand to give the pointer selection to. This will be prioritized when the controller initialize.\r\n     * If switch is enabled, it will still allow the user to switch between the different controllers\r\n     */\r\n    preferredHandedness?: XRHandedness;\r\n\r\n    /**\r\n     * Disable switching the pointer selection from one controller to the other.\r\n     * If the preferred hand is set it will be fixed on this hand, and if not it will be fixed on the first controller added to the scene\r\n     */\r\n    disableSwitchOnClick?: boolean;\r\n\r\n    /**\r\n     * The maximum distance of the pointer selection feature. Defaults to 100.\r\n     */\r\n    maxPointerDistance?: number;\r\n\r\n    /**\r\n     * A function that will be called when a new selection mesh is generated.\r\n     * This function should return a mesh that will be used as the selection mesh.\r\n     * The default is a torus with a 0.01 diameter and 0.0075 thickness .\r\n     */\r\n    customSelectionMeshGenerator?: () => Mesh;\r\n\r\n    /**\r\n     * A function that will be called when a new laser pointer mesh is generated.\r\n     * This function should return a mesh that will be used as the laser pointer mesh.\r\n     * The height (y) of the mesh must be 1.\r\n     */\r\n    customLasterPointerMeshGenerator?: () => AbstractMesh;\r\n\r\n    /**\r\n     * Use the grip space instead of the pointer space for selection, if available.\r\n     */\r\n    forceGripIfAvailable?: boolean;\r\n\r\n    /**\r\n     * If set to true, the hand rays will be disabled and the user will be able to look and pick objects.\r\n     * This requires system support (like in the vision OS) and will not work in all systems.\r\n     * @experimental - this is an experimental feature and might change int he future\r\n     */\r\n    lookAndPickMode?: boolean;\r\n}\r\n\r\n/**\r\n * A module that will enable pointer selection for motion controllers of XR Input Sources\r\n */\r\nexport class WebXRControllerPointerSelection extends WebXRAbstractFeature {\r\n    private static _IdCounter = 200;\r\n\r\n    private _attachController = (xrController: WebXRInputSource) => {\r\n        if (this._controllers[xrController.uniqueId]) {\r\n            // already attached\r\n            return;\r\n        }\r\n\r\n        const { laserPointer, selectionMesh } = this._generateNewMeshPair(this._options.forceGripIfAvailable && xrController.grip ? xrController.grip : xrController.pointer);\r\n\r\n        // get two new meshes\r\n        this._controllers[xrController.uniqueId] = {\r\n            xrController,\r\n            laserPointer,\r\n            selectionMesh,\r\n            meshUnderPointer: null,\r\n            pick: null,\r\n            tmpRay: new Ray(new Vector3(), new Vector3()),\r\n            disabledByNearInteraction: false,\r\n            id: WebXRControllerPointerSelection._IdCounter++,\r\n        };\r\n\r\n        if (this._attachedController) {\r\n            if (\r\n                !this._options.enablePointerSelectionOnAllControllers &&\r\n                this._options.preferredHandedness &&\r\n                xrController.inputSource.handedness === this._options.preferredHandedness\r\n            ) {\r\n                this._attachedController = xrController.uniqueId;\r\n            }\r\n        } else {\r\n            if (!this._options.enablePointerSelectionOnAllControllers) {\r\n                this._attachedController = xrController.uniqueId;\r\n            }\r\n        }\r\n\r\n        switch (xrController.inputSource.targetRayMode) {\r\n            case \"tracked-pointer\":\r\n                return this._attachTrackedPointerRayMode(xrController);\r\n            case \"gaze\":\r\n                return this._attachGazeMode(xrController);\r\n            case \"screen\":\r\n            case \"transient-pointer\":\r\n                return this._attachScreenRayMode(xrController);\r\n        }\r\n    };\r\n\r\n    private _controllers: {\r\n        [controllerUniqueId: string]: {\r\n            xrController?: WebXRInputSource;\r\n            webXRCamera?: WebXRCamera;\r\n            selectionComponent?: WebXRControllerComponent;\r\n            onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n            onFrameObserver?: Nullable<Observer<XRFrame>>;\r\n            laserPointer: AbstractMesh;\r\n            selectionMesh: AbstractMesh;\r\n            meshUnderPointer: Nullable<AbstractMesh>;\r\n            pick: Nullable<PickingInfo>;\r\n            id: number;\r\n            tmpRay: Ray;\r\n            disabledByNearInteraction: boolean;\r\n            // event support\r\n            eventListeners?: { [event in XREventType]?: (event: XRInputSourceEvent) => void };\r\n            screenCoordinates?: { x: number; y: number };\r\n            pointerDownTriggered?: boolean;\r\n            finalPointerUpTriggered?: boolean;\r\n        };\r\n    } = {};\r\n    private _scene: Scene;\r\n    private _tmpVectorForPickCompare = new Vector3();\r\n\r\n    private _attachedController: string;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.POINTER_SELECTION;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Disable lighting on the laser pointer (so it will always be visible)\r\n     */\r\n    public disablePointerLighting: boolean = true;\r\n    /**\r\n     * Disable lighting on the selection mesh (so it will always be visible)\r\n     */\r\n    public disableSelectionMeshLighting: boolean = true;\r\n    /**\r\n     * Should the laser pointer be displayed\r\n     */\r\n    public displayLaserPointer: boolean = true;\r\n    /**\r\n     * Should the selection mesh be displayed (The ring at the end of the laser pointer)\r\n     */\r\n    public displaySelectionMesh: boolean = true;\r\n    /**\r\n     * This color will be set to the laser pointer when selection is triggered\r\n     */\r\n    public laserPointerPickedColor: Color3 = new Color3(0.9, 0.9, 0.9);\r\n    /**\r\n     * Default color of the laser pointer\r\n     */\r\n    public laserPointerDefaultColor: Color3 = new Color3(0.7, 0.7, 0.7);\r\n    /**\r\n     * default color of the selection ring\r\n     */\r\n    public selectionMeshDefaultColor: Color3 = new Color3(0.8, 0.8, 0.8);\r\n    /**\r\n     * This color will be applied to the selection ring when selection is triggered\r\n     */\r\n    public selectionMeshPickedColor: Color3 = new Color3(0.3, 0.3, 1.0);\r\n\r\n    /**\r\n     * Optional filter to be used for ray selection.  This predicate shares behavior with\r\n     * scene.pointerMovePredicate which takes priority if it is also assigned.\r\n     */\r\n    public raySelectionPredicate: (mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * constructs a new background remover module\r\n     * @param _xrSessionManager the session manager for this module\r\n     * @param _options read-only options to be used in this module\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private readonly _options: IWebXRControllerPointerSelectionOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this._scene = this._xrSessionManager.scene;\r\n\r\n        // force look and pick mode if using WebXR on safari, assuming it is vision OS\r\n        // Only if not explicitly set. If set to false, it will not be forced\r\n        if (this._options.lookAndPickMode === undefined && (this._scene.getEngine()._badDesktopOS || this._scene.getEngine()._badOS)) {\r\n            this._options.lookAndPickMode = true;\r\n        }\r\n\r\n        // look and pick mode extra state changes\r\n        if (this._options.lookAndPickMode) {\r\n            this._options.enablePointerSelectionOnAllControllers = true;\r\n            this.displayLaserPointer = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        for (const controller of this._options.xrInput.controllers) {\r\n            this._attachController(controller);\r\n        }\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController, true);\r\n        this._addNewAttachObserver(\r\n            this._options.xrInput.onControllerRemovedObservable,\r\n            (controller) => {\r\n                // REMOVE the controller\r\n                this._detachController(controller.uniqueId);\r\n            },\r\n            true\r\n        );\r\n\r\n        this._scene.constantlyUpdateMeshUnderPointer = true;\r\n\r\n        if (this._options.gazeCamera) {\r\n            const webXRCamera = this._options.gazeCamera;\r\n\r\n            const { laserPointer, selectionMesh } = this._generateNewMeshPair(webXRCamera);\r\n\r\n            this._controllers[\"camera\"] = {\r\n                webXRCamera,\r\n                laserPointer,\r\n                selectionMesh,\r\n                meshUnderPointer: null,\r\n                pick: null,\r\n                tmpRay: new Ray(new Vector3(), new Vector3()),\r\n                disabledByNearInteraction: false,\r\n                id: WebXRControllerPointerSelection._IdCounter++,\r\n            };\r\n            this._attachGazeMode();\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n        const keys = Object.keys(this._controllers);\r\n        for (const controllerId of keys) {\r\n            this._detachController(controllerId);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Will get the mesh under a specific pointer.\r\n     * `scene.meshUnderPointer` will only return one mesh - either left or right.\r\n     * @param controllerId the controllerId to check\r\n     * @returns The mesh under pointer or null if no mesh is under the pointer\r\n     */\r\n    public getMeshUnderPointer(controllerId: string): Nullable<AbstractMesh> {\r\n        if (this._controllers[controllerId]) {\r\n            return this._controllers[controllerId].meshUnderPointer;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the unique id of the currently attached (active) controller for pointer selection.\r\n     * When `enablePointerSelectionOnAllControllers` is true, this value is not meaningful\r\n     * because all controllers are active simultaneously.\r\n     * @returns the unique id of the attached controller, or an empty string if none is attached\r\n     */\r\n    public get attachedControllerId(): string {\r\n        return this._attachedController || \"\";\r\n    }\r\n\r\n    /**\r\n     * Set the active controller for pointer selection during an XR session.\r\n     * Accepts either an `XRHandedness` value (`\"left\"`, `\"right\"`, `\"none\"`) to select\r\n     * the first matching controller, or a controller unique id string for precise control.\r\n     *\r\n     * When a matching controller is found, any in-progress pointer-down state on the\r\n     * previously active controller is properly resolved (pointer-up is simulated).\r\n     *\r\n     * This also updates the `preferredHandedness` option so that if controllers are\r\n     * re-initialized (e.g. on disconnect/reconnect), the new preference persists.\r\n     *\r\n     * This method is a no-op when `enablePointerSelectionOnAllControllers` is true,\r\n     * since all controllers are active simultaneously in that mode.\r\n     *\r\n     * @param controllerId the XRHandedness (`\"left\"`, `\"right\"`, `\"none\"`) or the unique id of the controller to attach\r\n     * @returns true if the active controller was changed, false otherwise\r\n     */\r\n    public setAttachedController(controllerId: XRHandedness | string): boolean {\r\n        if (this._options.enablePointerSelectionOnAllControllers) {\r\n            return false;\r\n        }\r\n\r\n        let targetUniqueId: string | undefined;\r\n\r\n        // Check if controllerId matches a known handedness value\r\n        if (controllerId === \"left\" || controllerId === \"right\" || controllerId === \"none\") {\r\n            // Find the first controller that matches the given handedness\r\n            for (const id in this._controllers) {\r\n                const data = this._controllers[id];\r\n                if (data.xrController && data.xrController.inputSource.handedness === controllerId) {\r\n                    targetUniqueId = id;\r\n                    break;\r\n                }\r\n            }\r\n        } else {\r\n            // Treat as a controller unique id\r\n            if (this._controllers[controllerId]) {\r\n                targetUniqueId = controllerId;\r\n            }\r\n        }\r\n\r\n        if (!targetUniqueId || targetUniqueId === this._attachedController) {\r\n            return false;\r\n        }\r\n\r\n        // Update preferredHandedness only after confirming the switch will happen\r\n        if (controllerId === \"left\" || controllerId === \"right\" || controllerId === \"none\") {\r\n            (this._options as IWebXRControllerPointerSelectionOptions).preferredHandedness = controllerId;\r\n        } else {\r\n            const targetData = this._controllers[targetUniqueId];\r\n            if (targetData.xrController) {\r\n                (this._options as IWebXRControllerPointerSelectionOptions).preferredHandedness = targetData.xrController.inputSource.handedness;\r\n            }\r\n        }\r\n\r\n        // Properly finalize pointer state on the previous controller\r\n        const prevControllerData = this._controllers[this._attachedController];\r\n        if (prevControllerData && prevControllerData.pointerDownTriggered && !prevControllerData.finalPointerUpTriggered && this._scene.isPointerCaptured(prevControllerData.id)) {\r\n            const pointerEventInit: PointerEventInit = {\r\n                pointerId: prevControllerData.id,\r\n                pointerType: \"xr\",\r\n            };\r\n            this._augmentPointerInit(pointerEventInit, prevControllerData.id, prevControllerData.screenCoordinates);\r\n            this._scene.simulatePointerUp(prevControllerData.pick || new PickingInfo(), pointerEventInit);\r\n            prevControllerData.pointerDownTriggered = false;\r\n            prevControllerData.finalPointerUpTriggered = true;\r\n        }\r\n\r\n        this._attachedController = targetUniqueId;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Get the xr controller that correlates to the pointer id in the pointer event\r\n     *\r\n     * @param id the pointer id to search for\r\n     * @returns the controller that correlates to this id or null if not found\r\n     */\r\n    public getXRControllerByPointerId(id: number): Nullable<WebXRInputSource> {\r\n        const keys = Object.keys(this._controllers);\r\n\r\n        for (let i = 0; i < keys.length; ++i) {\r\n            if (this._controllers[keys[i]].id === id) {\r\n                return this._controllers[keys[i]].xrController || null;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getPointerSelectionDisabledByPointerId(id: number): boolean {\r\n        const keys = Object.keys(this._controllers);\r\n\r\n        for (let i = 0; i < keys.length; ++i) {\r\n            if (this._controllers[keys[i]].id === id) {\r\n                return this._controllers[keys[i]].disabledByNearInteraction;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _setPointerSelectionDisabledByPointerId(id: number, state: boolean) {\r\n        const keys = Object.keys(this._controllers);\r\n\r\n        for (let i = 0; i < keys.length; ++i) {\r\n            if (this._controllers[keys[i]].id === id) {\r\n                this._controllers[keys[i]].disabledByNearInteraction = state;\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _identityMatrix = Matrix.Identity();\r\n    private _screenCoordinatesRef = Vector3.Zero();\r\n    private _viewportRef = new Viewport(0, 0, 0, 0);\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame) {\r\n        const keys = Object.keys(this._controllers);\r\n        for (const id of keys) {\r\n            // look and pick mode\r\n            // only do this for the selected pointer\r\n            const controllerData = this._controllers[id];\r\n            if (this._options.lookAndPickMode && controllerData.xrController?.inputSource.targetRayMode !== \"transient-pointer\") {\r\n                continue;\r\n            }\r\n            if ((!this._options.enablePointerSelectionOnAllControllers && id !== this._attachedController) || controllerData.disabledByNearInteraction) {\r\n                controllerData.selectionMesh.isVisible = false;\r\n                controllerData.laserPointer.isVisible = false;\r\n                controllerData.pick = null;\r\n                continue;\r\n            }\r\n\r\n            controllerData.laserPointer.isVisible = this.displayLaserPointer;\r\n\r\n            let controllerGlobalPosition: Vector3;\r\n\r\n            // Every frame check collisions/input\r\n            if (controllerData.xrController) {\r\n                controllerGlobalPosition =\r\n                    this._options.forceGripIfAvailable && controllerData.xrController.grip\r\n                        ? controllerData.xrController.grip.position\r\n                        : controllerData.xrController.pointer.position;\r\n                controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay, this._options.forceGripIfAvailable);\r\n            } else if (controllerData.webXRCamera) {\r\n                controllerGlobalPosition = controllerData.webXRCamera.position;\r\n                controllerData.webXRCamera.getForwardRayToRef(controllerData.tmpRay);\r\n            } else {\r\n                continue;\r\n            }\r\n\r\n            if (this._options.maxPointerDistance) {\r\n                controllerData.tmpRay.length = this._options.maxPointerDistance;\r\n            }\r\n            // update pointerX and pointerY of the scene. Only if the flag is set to true!\r\n            if (!this._options.disableScenePointerVectorUpdate && controllerGlobalPosition) {\r\n                const scene = this._xrSessionManager.scene;\r\n                const camera = this._options.xrInput.xrCamera;\r\n                if (camera) {\r\n                    camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth() / camera.rigCameras.length, scene.getEngine().getRenderHeight(), this._viewportRef);\r\n                    Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, camera.getTransformationMatrix(), this._viewportRef, this._screenCoordinatesRef);\r\n                    // stay safe\r\n                    if (\r\n                        typeof this._screenCoordinatesRef.x === \"number\" &&\r\n                        typeof this._screenCoordinatesRef.y === \"number\" &&\r\n                        !isNaN(this._screenCoordinatesRef.x) &&\r\n                        !isNaN(this._screenCoordinatesRef.y) &&\r\n                        this._screenCoordinatesRef.x !== Infinity &&\r\n                        this._screenCoordinatesRef.y !== Infinity\r\n                    ) {\r\n                        scene.pointerX = this._screenCoordinatesRef.x;\r\n                        scene.pointerY = this._screenCoordinatesRef.y;\r\n\r\n                        controllerData.screenCoordinates = {\r\n                            x: this._screenCoordinatesRef.x,\r\n                            y: this._screenCoordinatesRef.y,\r\n                        };\r\n                    }\r\n                }\r\n            }\r\n\r\n            let utilityScenePick = null;\r\n            if (this._utilityLayerScene) {\r\n                utilityScenePick = this._utilityLayerScene.pickWithRay(controllerData.tmpRay, this._utilityLayerScene.pointerMovePredicate || this.raySelectionPredicate);\r\n            }\r\n\r\n            const originalScenePick = this._scene.pickWithRay(controllerData.tmpRay, this._scene.pointerMovePredicate || this.raySelectionPredicate);\r\n            if (!utilityScenePick || !utilityScenePick.hit) {\r\n                // No hit in utility scene\r\n                controllerData.pick = originalScenePick;\r\n            } else if (!originalScenePick || !originalScenePick.hit) {\r\n                // No hit in original scene\r\n                controllerData.pick = utilityScenePick;\r\n            } else if (utilityScenePick.distance < originalScenePick.distance) {\r\n                // Hit is closer in utility scene\r\n                controllerData.pick = utilityScenePick;\r\n            } else {\r\n                // Hit is closer in original scene\r\n                controllerData.pick = originalScenePick;\r\n            }\r\n\r\n            if (controllerData.pick && controllerData.xrController) {\r\n                controllerData.pick.aimTransform = controllerData.xrController.pointer;\r\n                controllerData.pick.gripTransform = controllerData.xrController.grip || null;\r\n                controllerData.pick.originMesh = controllerData.xrController.pointer;\r\n                controllerData.tmpRay.length = controllerData.pick.distance;\r\n            }\r\n\r\n            const pick = controllerData.pick;\r\n\r\n            if (pick && pick.pickedPoint && pick.hit) {\r\n                // Update laser state\r\n                this._updatePointerDistance(controllerData.laserPointer, pick.distance);\r\n\r\n                // Update cursor state\r\n                controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\r\n                controllerData.selectionMesh.scaling.x = Math.sqrt(pick.distance);\r\n                controllerData.selectionMesh.scaling.y = Math.sqrt(pick.distance);\r\n                controllerData.selectionMesh.scaling.z = Math.sqrt(pick.distance);\r\n\r\n                // To avoid z-fighting\r\n                const pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(true), controllerData.tmpRay);\r\n                const deltaFighting = 0.001;\r\n                controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\r\n                if (pickNormal) {\r\n                    const axis1 = Vector3.Cross(Axis.Y, pickNormal);\r\n                    const axis2 = Vector3.Cross(pickNormal, axis1);\r\n                    Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, controllerData.selectionMesh.rotation);\r\n                    controllerData.selectionMesh.position.addInPlace(pickNormal.scale(deltaFighting));\r\n                }\r\n                controllerData.selectionMesh.isVisible = this.displaySelectionMesh;\r\n                controllerData.meshUnderPointer = pick.pickedMesh;\r\n            } else {\r\n                controllerData.selectionMesh.isVisible = false;\r\n                this._updatePointerDistance(controllerData.laserPointer, 1);\r\n                controllerData.meshUnderPointer = null;\r\n            }\r\n        }\r\n    }\r\n\r\n    private get _utilityLayerScene() {\r\n        return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\r\n    }\r\n\r\n    private _attachGazeMode(xrController?: WebXRInputSource) {\r\n        const controllerData = this._controllers[(xrController && xrController.uniqueId) || \"camera\"];\r\n        // attached when touched, detaches when raised\r\n        const timeToSelect = this._options.timeToSelect || 3000;\r\n        const sceneToRenderTo = this._options.useUtilityLayer ? this._utilityLayerScene : this._scene;\r\n        let oldPick = new PickingInfo();\r\n        const discMesh = CreateTorus(\r\n            \"selection\",\r\n            {\r\n                diameter: 0.0035 * 15,\r\n                thickness: 0.0025 * 6,\r\n                tessellation: 20,\r\n            },\r\n            sceneToRenderTo\r\n        );\r\n        discMesh.isVisible = false;\r\n        discMesh.isPickable = false;\r\n        discMesh.parent = controllerData.selectionMesh;\r\n        let timer = 0;\r\n        let downTriggered = false;\r\n        const pointerEventInit: PointerEventInit = {\r\n            pointerId: controllerData.id,\r\n            pointerType: \"xr\",\r\n        };\r\n        controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\r\n            if (!controllerData.pick) {\r\n                return;\r\n            }\r\n            this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n            controllerData.laserPointer.material!.alpha = 0;\r\n            discMesh.isVisible = false;\r\n            if (controllerData.pick.hit) {\r\n                if (!this._pickingMoved(oldPick, controllerData.pick)) {\r\n                    if (timer > timeToSelect / 10) {\r\n                        discMesh.isVisible = true;\r\n                    }\r\n\r\n                    timer += this._scene.getEngine().getDeltaTime();\r\n                    if (timer >= timeToSelect) {\r\n                        this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                        // this pointerdown event is not setting the controllerData.pointerDownTriggered to avoid a pointerUp event when this feature is detached\r\n                        downTriggered = true;\r\n                        // pointer up right after down, if disable on touch out\r\n                        if (this._options.disablePointerUpOnTouchOut) {\r\n                            this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                        }\r\n                        discMesh.isVisible = false;\r\n                    } else {\r\n                        const scaleFactor = 1 - timer / timeToSelect;\r\n                        discMesh.scaling.set(scaleFactor, scaleFactor, scaleFactor);\r\n                    }\r\n                } else {\r\n                    if (downTriggered) {\r\n                        if (!this._options.disablePointerUpOnTouchOut) {\r\n                            this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                        }\r\n                    }\r\n                    downTriggered = false;\r\n                    timer = 0;\r\n                }\r\n            } else {\r\n                downTriggered = false;\r\n                timer = 0;\r\n            }\r\n\r\n            this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n\r\n            oldPick = controllerData.pick;\r\n        });\r\n\r\n        if (this._options.renderingGroupId !== undefined) {\r\n            discMesh.renderingGroupId = this._options.renderingGroupId;\r\n        }\r\n        if (xrController) {\r\n            xrController.onDisposeObservable.addOnce(() => {\r\n                if (controllerData.pick && !this._options.disablePointerUpOnTouchOut && downTriggered) {\r\n                    this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                    controllerData.finalPointerUpTriggered = true;\r\n                }\r\n                discMesh.dispose();\r\n            });\r\n        }\r\n    }\r\n\r\n    private _attachScreenRayMode(xrController: WebXRInputSource) {\r\n        const controllerData = this._controllers[xrController.uniqueId];\r\n        let downTriggered = false;\r\n        const pointerEventInit: PointerEventInit = {\r\n            pointerId: controllerData.id,\r\n            pointerType: \"xr\",\r\n        };\r\n        controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\r\n            this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n            if (!controllerData.pick || (this._options.disablePointerUpOnTouchOut && downTriggered)) {\r\n                return;\r\n            }\r\n            if (!downTriggered) {\r\n                this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                controllerData.pointerDownTriggered = true;\r\n                downTriggered = true;\r\n                if (this._options.disablePointerUpOnTouchOut) {\r\n                    this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                }\r\n            } else {\r\n                this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n            }\r\n        });\r\n        xrController.onDisposeObservable.addOnce(() => {\r\n            this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n            this._xrSessionManager.runInXRFrame(() => {\r\n                if (controllerData.pick && !controllerData.finalPointerUpTriggered && downTriggered && !this._options.disablePointerUpOnTouchOut) {\r\n                    this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                    controllerData.finalPointerUpTriggered = true;\r\n                }\r\n            });\r\n        });\r\n    }\r\n\r\n    private _attachTrackedPointerRayMode(xrController: WebXRInputSource) {\r\n        const controllerData = this._controllers[xrController.uniqueId];\r\n        if (this._options.forceGazeMode) {\r\n            return this._attachGazeMode(xrController);\r\n        }\r\n        const pointerEventInit: PointerEventInit = {\r\n            pointerId: controllerData.id,\r\n            pointerType: \"xr\",\r\n        };\r\n        controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\r\n            (<StandardMaterial>controllerData.laserPointer.material).disableLighting = this.disablePointerLighting;\r\n            (<StandardMaterial>controllerData.selectionMesh.material).disableLighting = this.disableSelectionMeshLighting;\r\n\r\n            if (controllerData.pick) {\r\n                this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n                this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n            }\r\n        });\r\n        if (xrController.inputSource.gamepad) {\r\n            const init = (motionController: WebXRAbstractMotionController) => {\r\n                if (this._options.overrideButtonId) {\r\n                    controllerData.selectionComponent = motionController.getComponent(this._options.overrideButtonId);\r\n                }\r\n                if (!controllerData.selectionComponent) {\r\n                    controllerData.selectionComponent = motionController.getMainComponent();\r\n                }\r\n\r\n                controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {\r\n                    if (component.changes.pressed) {\r\n                        const pressed = component.changes.pressed.current;\r\n                        if (controllerData.pick) {\r\n                            if (this._options.enablePointerSelectionOnAllControllers || xrController.uniqueId === this._attachedController) {\r\n                                this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n                                if (pressed) {\r\n                                    this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                                    controllerData.pointerDownTriggered = true;\r\n                                    (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshPickedColor;\r\n                                    (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerPickedColor;\r\n                                } else {\r\n                                    this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                                    (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshDefaultColor;\r\n                                    (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerDefaultColor;\r\n                                }\r\n                            }\r\n                        } else {\r\n                            if (pressed && !this._options.enablePointerSelectionOnAllControllers && !this._options.disableSwitchOnClick) {\r\n                                // force a pointer up if switching controllers\r\n                                // get the controller that was attached before\r\n                                const prevController = this._controllers[this._attachedController];\r\n                                if (prevController && prevController.pointerDownTriggered && !prevController.finalPointerUpTriggered) {\r\n                                    this._augmentPointerInit(pointerEventInit, prevController.id, prevController.screenCoordinates);\r\n                                    this._scene.simulatePointerUp(new PickingInfo(), {\r\n                                        pointerId: prevController.id,\r\n                                        pointerType: \"xr\",\r\n                                    });\r\n                                    prevController.finalPointerUpTriggered = true;\r\n                                }\r\n                                this._attachedController = xrController.uniqueId;\r\n                            }\r\n                        }\r\n                    }\r\n                });\r\n            };\r\n            if (xrController.motionController) {\r\n                init(xrController.motionController);\r\n            } else {\r\n                xrController.onMotionControllerInitObservable.add(init);\r\n            }\r\n        } else {\r\n            // use the select and squeeze events\r\n            const selectStartListener = (event: XRInputSourceEvent) => {\r\n                this._xrSessionManager.onXRFrameObservable.addOnce(() => {\r\n                    this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n                    if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\r\n                        this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                        controllerData.pointerDownTriggered = true;\r\n                        (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshPickedColor;\r\n                        (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerPickedColor;\r\n                    }\r\n                });\r\n            };\r\n\r\n            const selectEndListener = (event: XRInputSourceEvent) => {\r\n                this._xrSessionManager.onXRFrameObservable.addOnce(() => {\r\n                    this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n                    if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\r\n                        this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                        (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshDefaultColor;\r\n                        (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerDefaultColor;\r\n                    }\r\n                });\r\n            };\r\n\r\n            controllerData.eventListeners = {\r\n                selectend: selectEndListener,\r\n                selectstart: selectStartListener,\r\n            };\r\n\r\n            this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\r\n            this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\r\n        }\r\n    }\r\n\r\n    private _convertNormalToDirectionOfRay(normal: Nullable<Vector3>, ray: Ray) {\r\n        if (normal) {\r\n            const angle = Math.acos(Vector3.Dot(normal, ray.direction));\r\n            if (angle < Math.PI / 2) {\r\n                normal.scaleInPlace(-1);\r\n            }\r\n        }\r\n        return normal;\r\n    }\r\n\r\n    private _detachController(xrControllerUniqueId: string) {\r\n        const controllerData = this._controllers[xrControllerUniqueId];\r\n        if (!controllerData) {\r\n            return;\r\n        }\r\n        if (controllerData.selectionComponent) {\r\n            if (controllerData.onButtonChangedObserver) {\r\n                controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\r\n            }\r\n        }\r\n        if (controllerData.onFrameObserver) {\r\n            this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\r\n        }\r\n        if (controllerData.eventListeners) {\r\n            const keys = Object.keys(controllerData.eventListeners);\r\n            for (const eventName of keys) {\r\n                const func = controllerData.eventListeners && controllerData.eventListeners[eventName as XREventType];\r\n                if (func) {\r\n                    // For future reference - this is an issue in the WebXR typings.\r\n                    this._xrSessionManager.session.removeEventListener(eventName as XREventType, func as any);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!controllerData.finalPointerUpTriggered && controllerData.pointerDownTriggered) {\r\n            // Stay safe and fire a pointerup, in case it wasn't already triggered\r\n            const pointerEventInit: PointerEventInit = {\r\n                pointerId: controllerData.id,\r\n                pointerType: \"xr\",\r\n            };\r\n            this._xrSessionManager.runInXRFrame(() => {\r\n                this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n                this._scene.simulatePointerUp(controllerData.pick || new PickingInfo(), pointerEventInit);\r\n                controllerData.finalPointerUpTriggered = true;\r\n            });\r\n        }\r\n        this._xrSessionManager.scene.onBeforeRenderObservable.addOnce(() => {\r\n            try {\r\n                controllerData.selectionMesh.dispose();\r\n                controllerData.laserPointer.dispose();\r\n                // remove from the map\r\n                delete this._controllers[xrControllerUniqueId];\r\n                if (this._attachedController === xrControllerUniqueId) {\r\n                    // check for other controllers\r\n                    const keys = Object.keys(this._controllers);\r\n                    if (keys.length) {\r\n                        this._attachedController = keys[0];\r\n                    } else {\r\n                        this._attachedController = \"\";\r\n                    }\r\n                }\r\n            } catch (e) {\r\n                Logger.Warn(\"controller already detached.\");\r\n            }\r\n        });\r\n    }\r\n\r\n    private _generateNewMeshPair(meshParent: Node) {\r\n        const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n        const laserPointer = this._options.customLasterPointerMeshGenerator\r\n            ? this._options.customLasterPointerMeshGenerator()\r\n            : CreateCylinder(\r\n                  \"laserPointer\",\r\n                  {\r\n                      height: 1,\r\n                      diameterTop: 0.0002,\r\n                      diameterBottom: 0.004,\r\n                      tessellation: 20,\r\n                      subdivisions: 1,\r\n                  },\r\n                  sceneToRenderTo\r\n              );\r\n        laserPointer.parent = meshParent;\r\n        const laserPointerMaterial = new StandardMaterial(\"laserPointerMat\", sceneToRenderTo);\r\n        laserPointerMaterial.emissiveColor = this.laserPointerDefaultColor;\r\n        laserPointerMaterial.alpha = 0.7;\r\n        laserPointer.material = laserPointerMaterial;\r\n        laserPointer.rotation.x = Math.PI / 2;\r\n        this._updatePointerDistance(laserPointer, 1);\r\n        laserPointer.isPickable = false;\r\n        laserPointer.isVisible = false;\r\n\r\n        // Create a gaze tracker for the  XR controller\r\n        const selectionMesh = this._options.customSelectionMeshGenerator\r\n            ? this._options.customSelectionMeshGenerator()\r\n            : CreateTorus(\r\n                  \"gazeTracker\",\r\n                  {\r\n                      diameter: 0.0035 * 3,\r\n                      thickness: 0.0025 * 3,\r\n                      tessellation: 20,\r\n                  },\r\n                  sceneToRenderTo\r\n              );\r\n        selectionMesh.bakeCurrentTransformIntoVertices();\r\n        selectionMesh.isPickable = false;\r\n        selectionMesh.isVisible = false;\r\n        const targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\r\n        targetMat.specularColor = Color3.Black();\r\n        targetMat.emissiveColor = this.selectionMeshDefaultColor;\r\n        targetMat.backFaceCulling = false;\r\n        selectionMesh.material = targetMat;\r\n\r\n        if (this._options.renderingGroupId !== undefined) {\r\n            laserPointer.renderingGroupId = this._options.renderingGroupId;\r\n            selectionMesh.renderingGroupId = this._options.renderingGroupId;\r\n        }\r\n\r\n        return {\r\n            laserPointer,\r\n            selectionMesh,\r\n        };\r\n    }\r\n\r\n    private _pickingMoved(oldPick: PickingInfo, newPick: PickingInfo) {\r\n        if (!oldPick.hit || !newPick.hit) {\r\n            return true;\r\n        }\r\n        if (!oldPick.pickedMesh || !oldPick.pickedPoint || !newPick.pickedMesh || !newPick.pickedPoint) {\r\n            return true;\r\n        }\r\n        if (oldPick.pickedMesh !== newPick.pickedMesh) {\r\n            return true;\r\n        }\r\n        oldPick.pickedPoint?.subtractToRef(newPick.pickedPoint, this._tmpVectorForPickCompare);\r\n        this._tmpVectorForPickCompare.set(Math.abs(this._tmpVectorForPickCompare.x), Math.abs(this._tmpVectorForPickCompare.y), Math.abs(this._tmpVectorForPickCompare.z));\r\n        const delta = (this._options.gazeModePointerMovedFactor || 1) * 0.01 * newPick.distance;\r\n        const length = this._tmpVectorForPickCompare.length();\r\n        if (length > delta) {\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    private _updatePointerDistance(_laserPointer: AbstractMesh, distance: number = 100) {\r\n        _laserPointer.scaling.y = distance;\r\n        // a bit of distance from the controller\r\n        if (this._scene.useRightHandedSystem) {\r\n            distance *= -1;\r\n        }\r\n        _laserPointer.position.z = distance / 2 + 0.05;\r\n    }\r\n\r\n    private _augmentPointerInit(pointerEventInit: PointerEventInit, id: number, screenCoordinates?: { x: number; y: number }): void {\r\n        pointerEventInit.pointerId = id;\r\n        pointerEventInit.pointerType = \"xr\";\r\n        if (screenCoordinates) {\r\n            pointerEventInit.screenX = screenCoordinates.x;\r\n            pointerEventInit.screenY = screenCoordinates.y;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public get lasterPointerDefaultColor(): Color3 {\r\n        // here due to a typo\r\n        return this.laserPointerDefaultColor;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRControllerPointerSelection.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRControllerPointerSelection(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterRay();\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRControllerPointerSelection.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRControllerPointerSelection(xrSessionManager, options);\r\n        },\r\n        WebXRControllerPointerSelection.Version,\r\n        true\r\n    );\r\n}\r\n","/**\r\n * Defines the kind of connection point for node based material\r\n */\r\nexport enum NodeMaterialBlockConnectionPointTypes {\r\n    /** Float */\r\n    Float = 0x0001,\r\n    /** Int */\r\n    Int = 0x0002,\r\n    /** Vector2 */\r\n    Vector2 = 0x0004,\r\n    /** Vector3 */\r\n    Vector3 = 0x0008,\r\n    /** Vector4 */\r\n    Vector4 = 0x0010,\r\n    /** Color3 */\r\n    Color3 = 0x0020,\r\n    /** Color4 */\r\n    Color4 = 0x0040,\r\n    /** Matrix */\r\n    Matrix = 0x0080,\r\n    /** Custom object */\r\n    Object = 0x0100,\r\n    /** Detect type based on connection */\r\n    AutoDetect = 0x0400,\r\n    /** Output type that will be defined by input type */\r\n    BasedOnInput = 0x0800,\r\n    /** Bitmask of all types */\r\n    All = 0x0fff,\r\n}\r\n","/**\r\n * Enum used to define the target of a block\r\n */\r\nexport enum NodeMaterialBlockTargets {\r\n    /** Vertex shader */\r\n    Vertex = 1,\r\n    /** Fragment shader */\r\n    Fragment = 2,\r\n    /** Neutral */\r\n    Neutral = 4,\r\n    /** Vertex and Fragment */\r\n    VertexAndFragment = Vertex | Fragment,\r\n}\r\n","import { NodeMaterialBlockConnectionPointTypes } from \"./Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { NodeMaterialBlockTargets } from \"./Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialBuildStateSharedData } from \"./nodeMaterialBuildStateSharedData\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { type NodeMaterialConnectionPoint } from \"./nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderStore as EngineShaderStore } from \"../../Engines/shaderStore\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type NodeMaterialBlock } from \"./nodeMaterialBlock\";\r\nimport { Process } from \"core/Engines/Processors/shaderProcessor\";\r\nimport { type _IProcessingOptions } from \"core/Engines/Processors/shaderProcessingOptions\";\r\nimport { WebGLShaderProcessor } from \"core/Engines/WebGL/webGLShaderProcessors\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Class used to store node based material build state\r\n */\r\nexport class NodeMaterialBuildState {\r\n    /** Gets or sets a boolean indicating if the current state can emit uniform buffers */\r\n    public supportUniformBuffers = false;\r\n    /**\r\n     * Gets the list of emitted attributes\r\n     */\r\n    public attributes: string[] = [];\r\n    /**\r\n     * Gets the list of emitted uniforms\r\n     */\r\n    public uniforms: string[] = [];\r\n    /**\r\n     * Gets the list of emitted constants\r\n     */\r\n    public constants: string[] = [];\r\n    /**\r\n     * Gets the list of emitted samplers\r\n     */\r\n    public samplers: string[] = [];\r\n    /**\r\n     * Gets the list of emitted functions\r\n     */\r\n    public functions: { [key: string]: string } = {};\r\n    /**\r\n     * Gets the list of emitted extensions\r\n     */\r\n    public extensions: { [key: string]: string } = {};\r\n    /**\r\n     * Gets the list of emitted prePass outputs - if using the prepass\r\n     */\r\n    public prePassOutput: { [key: string]: string } = {};\r\n\r\n    /**\r\n     * Gets the target of the compilation state\r\n     */\r\n    public target: NodeMaterialBlockTargets;\r\n    /**\r\n     * Gets the list of emitted counters\r\n     */\r\n    public counters: { [key: string]: number } = {};\r\n\r\n    /**\r\n     * Shared data between multiple NodeMaterialBuildState instances\r\n     */\r\n    public sharedData: NodeMaterialBuildStateSharedData;\r\n\r\n    /** @internal */\r\n    public _terminalBlocks: Set<NodeMaterialBlock> = new Set();\r\n\r\n    /** @internal */\r\n    public _vertexState: NodeMaterialBuildState;\r\n\r\n    /** @internal */\r\n    public _attributeDeclaration = \"\";\r\n    /** @internal */\r\n    public _uniformDeclaration = \"\";\r\n    /** @internal */\r\n    public _constantDeclaration = \"\";\r\n    /** @internal */\r\n    public _samplerDeclaration = \"\";\r\n    /** @internal */\r\n    public _varyingTransfer = \"\";\r\n    /** @internal */\r\n    public _injectAtEnd = \"\";\r\n    /** @internal */\r\n    public _injectAtTop = \"\";\r\n    /** @internal */\r\n    public _customEntryHeader = \"\";\r\n    /** @internal */\r\n    private _repeatableContentAnchorIndex = 0;\r\n    /** @internal */\r\n    public _builtCompilationString = \"\";\r\n\r\n    /**\r\n     * Gets the emitted compilation strings\r\n     */\r\n    public compilationString = \"\";\r\n\r\n    /**\r\n     * Gets the current shader language to use\r\n     */\r\n    public get shaderLanguage() {\r\n        return this.sharedData.nodeMaterial.shaderLanguage;\r\n    }\r\n\r\n    /** Gets suffix to add behind type casting */\r\n    public get fSuffix() {\r\n        return this.shaderLanguage === ShaderLanguage.WGSL ? \"f\" : \"\";\r\n    }\r\n\r\n    /**\r\n     * Returns the processed, compiled shader code\r\n     * @param defines defines to use for the shader processing\r\n     * @returns the raw shader code used by the engine\r\n     */\r\n    public async getProcessedShaderAsync(defines: string): Promise<string> {\r\n        if (!this._builtCompilationString) {\r\n            Logger.Error(\"getProcessedShaderAsync: Shader not built yet.\");\r\n            return \"\";\r\n        }\r\n\r\n        const engine = this.sharedData.nodeMaterial.getScene().getEngine();\r\n        const options: _IProcessingOptions = {\r\n            defines: defines.split(\"\\n\"),\r\n            indexParameters: undefined,\r\n            isFragment: this.target === NodeMaterialBlockTargets.Fragment,\r\n            shouldUseHighPrecisionShader: engine._shouldUseHighPrecisionShader,\r\n            processor: engine._getShaderProcessor(this.shaderLanguage),\r\n            supportsUniformBuffers: engine.supportsUniformBuffers,\r\n            shadersRepository: EngineShaderStore.GetShadersRepository(this.shaderLanguage),\r\n            includesShadersStore: EngineShaderStore.GetIncludesShadersStore(this.shaderLanguage),\r\n            version: (engine.version * 100).toString(),\r\n            platformName: engine.shaderPlatformName,\r\n            processingContext: null,\r\n            isNDCHalfZRange: engine.isNDCHalfZRange,\r\n            useReverseDepthBuffer: engine.useReverseDepthBuffer,\r\n        };\r\n\r\n        // Export WebGL2 shaders with WebGL1 syntax for max compatibility\r\n        if (!engine.isWebGPU && engine.version > 1.0) {\r\n            options.processor = new WebGLShaderProcessor();\r\n        }\r\n\r\n        return await new Promise((resolve) => {\r\n            Process(\r\n                this._builtCompilationString,\r\n                options,\r\n                (migratedCode, _) => {\r\n                    resolve(migratedCode);\r\n                },\r\n                engine\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Finalize the compilation strings\r\n     * @param state defines the current compilation state\r\n     */\r\n    public finalize(state: NodeMaterialBuildState) {\r\n        const emitComments = state.sharedData.emitComments;\r\n        const isFragmentMode = this.target === NodeMaterialBlockTargets.Fragment;\r\n\r\n        let entryPointString = `\\n${emitComments ? \"//Entry point\\n\" : \"\"}`;\r\n        if (this._customEntryHeader) {\r\n            entryPointString += this._customEntryHeader;\r\n        } else if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            if (isFragmentMode) {\r\n                entryPointString += `@fragment\\nfn main(input: FragmentInputs) -> FragmentOutputs {\\n${this.sharedData.varyingInitializationsFragment}`;\r\n            } else {\r\n                entryPointString += `@vertex\\nfn main(input: VertexInputs) -> FragmentInputs{\\n`;\r\n            }\r\n        } else {\r\n            entryPointString += `void main(void) {\\n`;\r\n        }\r\n\r\n        this.compilationString = entryPointString + this.compilationString;\r\n\r\n        if (this._constantDeclaration) {\r\n            this.compilationString = `\\n${emitComments ? \"//Constants\\n\" : \"\"}${this._constantDeclaration}\\n${this.compilationString}`;\r\n        }\r\n\r\n        let functionCode = \"\";\r\n        for (const functionName in this.functions) {\r\n            functionCode += this.functions[functionName] + `\\n`;\r\n        }\r\n        this.compilationString = `\\n${functionCode}\\n${this.compilationString}`;\r\n\r\n        if (!isFragmentMode && this._varyingTransfer) {\r\n            this.compilationString = `${this.compilationString}\\n${this._varyingTransfer}`;\r\n        }\r\n\r\n        if (this._injectAtEnd) {\r\n            this.compilationString = `${this.compilationString}\\n${this._injectAtEnd}`;\r\n        }\r\n\r\n        this.compilationString = `${this.compilationString}\\n}`;\r\n\r\n        if (this.sharedData.varyingDeclaration) {\r\n            this.compilationString = `\\n${emitComments ? \"//Varyings\\n\" : \"\"}${isFragmentMode ? this.sharedData.varyingDeclarationFragment : this.sharedData.varyingDeclaration}\\n${this.compilationString}`;\r\n        }\r\n\r\n        if (this._samplerDeclaration) {\r\n            this.compilationString = `\\n${emitComments ? \"//Samplers\\n\" : \"\"}${this._samplerDeclaration}\\n${this.compilationString}`;\r\n        }\r\n\r\n        if (this._uniformDeclaration) {\r\n            this.compilationString = `\\n${emitComments ? \"//Uniforms\\n\" : \"\"}${this._uniformDeclaration}\\n${this.compilationString}`;\r\n        }\r\n\r\n        if (this._attributeDeclaration && !isFragmentMode) {\r\n            this.compilationString = `\\n${emitComments ? \"//Attributes\\n\" : \"\"}${this._attributeDeclaration}\\n${this.compilationString}`;\r\n        }\r\n\r\n        if (this.shaderLanguage !== ShaderLanguage.WGSL) {\r\n            this.compilationString = \"precision highp float;\\n\" + this.compilationString;\r\n            this.compilationString = \"#if defined(WEBGL2) || defined(WEBGPU)\\nprecision highp sampler2DArray;\\n#endif\\n\" + this.compilationString;\r\n\r\n            if (isFragmentMode) {\r\n                let prePassDeclaration = \"#if defined(PREPASS)\\r\\n\" + \"#extension GL_EXT_draw_buffers : require\\r\\n\" + \"#ifdef PREPASS_MESH_BLEND_TAG\\r\\n\";\r\n\r\n                for (let index = 0; index < 8; index++) {\r\n                    prePassDeclaration += `#if SCENE_MRT_COUNT > ${index}\\r\\n`;\r\n                    prePassDeclaration += `#if PREPASS_MESH_BLEND_TAG_INDEX == ${index}\\r\\n`;\r\n                    prePassDeclaration += `layout(location = ${index}) out highp uvec4 meshBlendTagOutput;\\r\\n`;\r\n                    prePassDeclaration += \"#else\\r\\n\";\r\n                    prePassDeclaration += `layout(location = ${index}) out highp vec4 glFragData${index};\\r\\n`;\r\n                    prePassDeclaration += \"#endif\\r\\n\";\r\n                    prePassDeclaration += \"#endif\\r\\n\";\r\n                }\r\n\r\n                prePassDeclaration += \"void writeGeometryFragmentOutput(highp int index, highp vec4 value) {\\r\\n\";\r\n                for (let index = 0; index < 8; index++) {\r\n                    prePassDeclaration += `#if SCENE_MRT_COUNT > ${index} && PREPASS_MESH_BLEND_TAG_INDEX != ${index}\\r\\n`;\r\n                    prePassDeclaration += `if (index == ${index}) { glFragData${index} = value; }\\r\\n`;\r\n                    prePassDeclaration += \"#endif\\r\\n\";\r\n                }\r\n                prePassDeclaration += \"}\\r\\n\";\r\n                prePassDeclaration += \"#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX, VALUE) writeGeometryFragmentOutput(INDEX, VALUE)\\r\\n\";\r\n                prePassDeclaration += \"#else\\r\\n\";\r\n                prePassDeclaration += \"layout(location = 0) out highp vec4 glFragData[SCENE_MRT_COUNT];\\r\\n\";\r\n                prePassDeclaration += \"#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX, VALUE) gl_FragData[INDEX] = VALUE\\r\\n\";\r\n                prePassDeclaration += \"#endif\\r\\n\";\r\n                prePassDeclaration += \"highp vec4 gl_FragColor;\\r\\n\";\r\n                prePassDeclaration += \"#endif\\r\\n\";\r\n\r\n                this.compilationString = prePassDeclaration + this.compilationString;\r\n            }\r\n\r\n            for (const extensionName in this.extensions) {\r\n                const extension = this.extensions[extensionName];\r\n                this.compilationString = `\\n${extension}\\n${this.compilationString}`;\r\n            }\r\n        }\r\n\r\n        if (this._injectAtTop) {\r\n            this.compilationString = `${this._injectAtTop}\\n${this.compilationString}`;\r\n        }\r\n\r\n        this._builtCompilationString = this.compilationString;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _repeatableContentAnchor(): string {\r\n        return `###___ANCHOR${this._repeatableContentAnchorIndex++}___###`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getFreeVariableName(prefix: string): string {\r\n        prefix = this.sharedData.formatConfig.formatVariablename(prefix);\r\n\r\n        if (this.sharedData.variableNames[prefix] === undefined) {\r\n            this.sharedData.variableNames[prefix] = 0;\r\n\r\n            // Check reserved words\r\n            if (prefix === \"output\" || prefix === \"texture\") {\r\n                return prefix + this.sharedData.variableNames[prefix];\r\n            }\r\n\r\n            return prefix;\r\n        } else {\r\n            this.sharedData.variableNames[prefix]++;\r\n        }\r\n\r\n        return prefix + this.sharedData.variableNames[prefix];\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getFreeDefineName(prefix: string): string {\r\n        if (this.sharedData.defineNames[prefix] === undefined) {\r\n            this.sharedData.defineNames[prefix] = 0;\r\n        } else {\r\n            this.sharedData.defineNames[prefix]++;\r\n        }\r\n\r\n        return prefix + this.sharedData.defineNames[prefix];\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _excludeVariableName(name: string) {\r\n        this.sharedData.variableNames[name] = 0;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emit2DSampler(name: string, define = \"\", force = false, annotation?: string, unsignedSampler?: boolean, precision?: string) {\r\n        if (this.samplers.indexOf(name) < 0 || force) {\r\n            if (define) {\r\n                this._samplerDeclaration += `#if ${define}\\n`;\r\n            }\r\n\r\n            if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                const unsignedSamplerPrefix = unsignedSampler ? \"u\" : \"f\";\r\n                this._samplerDeclaration += `var ${name + Constants.AUTOSAMPLERSUFFIX}: sampler;\\n`;\r\n                this._samplerDeclaration += `var ${name}: texture_2d<${unsignedSamplerPrefix}32>;\\n`;\r\n            } else {\r\n                const unsignedSamplerPrefix = unsignedSampler ? \"u\" : \"\";\r\n                const precisionDecl = precision ?? \"\";\r\n                this._samplerDeclaration += `uniform ${precisionDecl} ${unsignedSamplerPrefix}sampler2D ${name}; ${annotation ? annotation : \"\"}\\n`;\r\n            }\r\n\r\n            if (define) {\r\n                this._samplerDeclaration += `#endif\\n`;\r\n            }\r\n\r\n            if (!force) {\r\n                this.samplers.push(name);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitCubeSampler(name: string, define = \"\", force = false) {\r\n        if (this.samplers.indexOf(name) < 0 || force) {\r\n            if (define) {\r\n                this._samplerDeclaration += `#if ${define}\\n`;\r\n            }\r\n\r\n            if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                this._samplerDeclaration += `var ${name + Constants.AUTOSAMPLERSUFFIX}: sampler;\\n`;\r\n                this._samplerDeclaration += `var ${name}: texture_cube<f32>;\\n`;\r\n            } else {\r\n                this._samplerDeclaration += `uniform samplerCube ${name};\\n`;\r\n            }\r\n\r\n            if (define) {\r\n                this._samplerDeclaration += `#endif\\n`;\r\n            }\r\n\r\n            if (!force) {\r\n                this.samplers.push(name);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emit2DArraySampler(name: string) {\r\n        if (this.samplers.indexOf(name) < 0) {\r\n            if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                this._samplerDeclaration += `var ${name + Constants.AUTOSAMPLERSUFFIX}: sampler;\\n`;\r\n                this._samplerDeclaration += `var ${name}: texture_2d_array<f32>;\\n`;\r\n            } else {\r\n                this._samplerDeclaration += `uniform sampler2DArray ${name};\\n`;\r\n            }\r\n            this.samplers.push(name);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getGLType(type: NodeMaterialBlockConnectionPointTypes): string {\r\n        switch (type) {\r\n            case NodeMaterialBlockConnectionPointTypes.Float:\r\n                return \"float\";\r\n            case NodeMaterialBlockConnectionPointTypes.Int:\r\n                return \"int\";\r\n            case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                return \"vec2\";\r\n            case NodeMaterialBlockConnectionPointTypes.Color3:\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                return \"vec3\";\r\n            case NodeMaterialBlockConnectionPointTypes.Color4:\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                return \"vec4\";\r\n            case NodeMaterialBlockConnectionPointTypes.Matrix:\r\n                return \"mat4\";\r\n        }\r\n\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getShaderType(type: NodeMaterialBlockConnectionPointTypes) {\r\n        const isWGSL = this.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        switch (type) {\r\n            case NodeMaterialBlockConnectionPointTypes.Float:\r\n                return isWGSL ? \"f32\" : \"float\";\r\n            case NodeMaterialBlockConnectionPointTypes.Int:\r\n                return isWGSL ? \"i32\" : \"int\";\r\n            case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                return isWGSL ? \"vec2f\" : \"vec2\";\r\n            case NodeMaterialBlockConnectionPointTypes.Color3:\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                return isWGSL ? \"vec3f\" : \"vec3\";\r\n            case NodeMaterialBlockConnectionPointTypes.Color4:\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                return isWGSL ? \"vec4f\" : \"vec4\";\r\n            case NodeMaterialBlockConnectionPointTypes.Matrix:\r\n                return isWGSL ? \"mat4x4f\" : \"mat4\";\r\n        }\r\n\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitExtension(name: string, extension: string, define: string = \"\") {\r\n        if (this.extensions[name]) {\r\n            return;\r\n        }\r\n\r\n        if (define) {\r\n            extension = `#if ${define}\\n${extension}\\n#endif`;\r\n        }\r\n        this.extensions[name] = extension;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitFunction(name: string, code: string, comments: string) {\r\n        if (this.functions[name]) {\r\n            return;\r\n        }\r\n\r\n        if (this.sharedData.emitComments) {\r\n            code = comments + `\\n` + code;\r\n        }\r\n\r\n        this.functions[name] = code;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitCodeFromInclude(\r\n        includeName: string,\r\n        comments: string,\r\n        options?: {\r\n            replaceStrings?: { search: RegExp; replace: string }[];\r\n            repeatKey?: string;\r\n            substitutionVars?: string;\r\n        }\r\n    ) {\r\n        const store = EngineShaderStore.GetIncludesShadersStore(this.shaderLanguage);\r\n\r\n        if (options && options.repeatKey) {\r\n            return `#include<${includeName}>${options.substitutionVars ? \"(\" + options.substitutionVars + \")\" : \"\"}[0..${options.repeatKey}]\\n`;\r\n        }\r\n\r\n        let code = store[includeName] + \"\\n\";\r\n\r\n        if (this.sharedData.emitComments) {\r\n            code = comments + `\\n` + code;\r\n        }\r\n\r\n        if (!options) {\r\n            return code;\r\n        }\r\n\r\n        if (options.replaceStrings) {\r\n            for (let index = 0; index < options.replaceStrings.length; index++) {\r\n                const replaceString = options.replaceStrings[index];\r\n                code = code.replace(replaceString.search, replaceString.replace);\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitFunctionFromInclude(\r\n        includeName: string,\r\n        comments: string,\r\n        options?: {\r\n            repeatKey?: string;\r\n            substitutionVars?: string;\r\n            removeAttributes?: boolean;\r\n            removeUniforms?: boolean;\r\n            removeVaryings?: boolean;\r\n            removeIfDef?: boolean;\r\n            define?: string;\r\n            replaceStrings?: { search: RegExp; replace: string }[];\r\n        },\r\n        storeKey: string = \"\"\r\n    ) {\r\n        const key = includeName + storeKey + (options?.define ? `_${options.define}` : \"\");\r\n        if (this.functions[key]) {\r\n            return;\r\n        }\r\n        const store = EngineShaderStore.GetIncludesShadersStore(this.shaderLanguage);\r\n\r\n        if (!options || (!options.removeAttributes && !options.removeUniforms && !options.removeVaryings && !options.removeIfDef && !options.replaceStrings)) {\r\n            if (options && options.repeatKey) {\r\n                this.functions[key] = `#include<${includeName}>${options.substitutionVars ? \"(\" + options.substitutionVars + \")\" : \"\"}[0..${options.repeatKey}]\\n`;\r\n            } else {\r\n                this.functions[key] = `#include<${includeName}>${options?.substitutionVars ? \"(\" + options?.substitutionVars + \")\" : \"\"}\\n`;\r\n            }\r\n\r\n            if (this.sharedData.emitComments) {\r\n                this.functions[key] = comments + `\\n` + this.functions[key];\r\n            }\r\n\r\n            if (options?.define) {\r\n                this.functions[key] = `#ifdef ${options.define}\\n${this.functions[key]}#endif\\n`;\r\n            }\r\n\r\n            return;\r\n        }\r\n\r\n        this.functions[key] = store[includeName];\r\n\r\n        if (this.sharedData.emitComments) {\r\n            this.functions[key] = comments + `\\n` + this.functions[key];\r\n        }\r\n\r\n        if (options.removeIfDef) {\r\n            this.functions[key] = this.functions[key].replace(/^\\s*?#ifdef.+$/gm, \"\");\r\n            this.functions[key] = this.functions[key].replace(/^\\s*?#endif.*$/gm, \"\");\r\n            this.functions[key] = this.functions[key].replace(/^\\s*?#else.*$/gm, \"\");\r\n            this.functions[key] = this.functions[key].replace(/^\\s*?#elif.*$/gm, \"\");\r\n        }\r\n\r\n        if (options.removeAttributes) {\r\n            this.functions[key] = this.functions[key].replace(/\\s*?attribute .+?;/g, \"\\n\");\r\n        }\r\n\r\n        if (options.removeUniforms) {\r\n            this.functions[key] = this.functions[key].replace(/\\s*?uniform .*?;/g, \"\\n\");\r\n        }\r\n\r\n        if (options.removeVaryings) {\r\n            this.functions[key] = this.functions[key].replace(/\\s*?(varying|in) .+?;/g, \"\\n\");\r\n        }\r\n\r\n        if (options.replaceStrings) {\r\n            for (let index = 0; index < options.replaceStrings.length; index++) {\r\n                const replaceString = options.replaceStrings[index];\r\n                this.functions[key] = this.functions[key].replace(replaceString.search, replaceString.replace);\r\n            }\r\n        }\r\n\r\n        if (options.define) {\r\n            this.functions[key] = `#ifdef ${options.define}\\n${this.functions[key]}#endif\\n`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _registerTempVariable(name: string) {\r\n        if (this.sharedData.temps.indexOf(name) !== -1) {\r\n            return false;\r\n        }\r\n\r\n        this.sharedData.temps.push(name);\r\n        return true;\r\n    }\r\n\r\n    private _emitDefineStart(define?: string, notDefine = false) {\r\n        let code = \"\";\r\n        if (define) {\r\n            if (define.startsWith(\"defined(\")) {\r\n                code = `#if ${define}\\n`;\r\n            } else {\r\n                code = `${notDefine ? \"#ifndef\" : \"#ifdef\"} ${define}\\n`;\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    private _emitDefineEnd(define?: string) {\r\n        return define ? `#endif\\n` : \"\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitVaryingFromString(name: string, type: NodeMaterialBlockConnectionPointTypes, define: string = \"\", notDefine = false) {\r\n        if (this.sharedData.varyings.indexOf(name) !== -1) {\r\n            return false;\r\n        }\r\n\r\n        this.sharedData.varyings.push(name);\r\n\r\n        const shaderType = this._getShaderType(type);\r\n\r\n        const emitCode = (forFragment = false) => {\r\n            let code = this._emitDefineStart(define, notDefine);\r\n            if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                switch (shaderType) {\r\n                    case \"i32\":\r\n                    case \"f32\":\r\n                    case \"vec2f\":\r\n                    case \"vec3f\":\r\n                    case \"vec4f\":\r\n                        code += `varying ${name}: ${shaderType};\\n`;\r\n\r\n                        if (forFragment) {\r\n                            code += `var<private> ${name}: ${shaderType};\\n`;\r\n                            this.sharedData.varyingInitializationsFragment +=\r\n                                this._emitDefineStart(define, notDefine) + `${name} = fragmentInputs.${name};\\n` + this._emitDefineEnd(define);\r\n                        }\r\n                        break;\r\n                    case \"mat4x4f\":\r\n                        // We can't pass a matrix as a varying in WGSL, so we need to split it into 4 vectors\r\n                        code += `varying ${name}_r0: vec4f;\\n`;\r\n                        code += `varying ${name}_r1: vec4f;\\n`;\r\n                        code += `varying ${name}_r2: vec4f;\\n`;\r\n                        code += `varying ${name}_r3: vec4f;\\n`;\r\n\r\n                        if (forFragment) {\r\n                            code += `var<private> ${name}: mat4x4f;\\n`;\r\n                            this.sharedData.varyingInitializationsFragment +=\r\n                                this._emitDefineStart(define, notDefine) +\r\n                                `${name} = mat4x4f(fragmentInputs.${name}_r0, fragmentInputs.${name}_r1, fragmentInputs.${name}_r2, fragmentInputs.${name}_r3);\\n` +\r\n                                this._emitDefineEnd(define);\r\n                        }\r\n                        break;\r\n                    default:\r\n                        code += `varying ${name}: ${shaderType};\\n`;\r\n                        break;\r\n                }\r\n            } else {\r\n                code += `varying ${shaderType} ${name};\\n`;\r\n            }\r\n            code += this._emitDefineEnd(define);\r\n            return code;\r\n        };\r\n\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            this.sharedData.varyingDeclaration += emitCode(false);\r\n            this.sharedData.varyingDeclarationFragment += emitCode(true);\r\n        } else {\r\n            const code = emitCode();\r\n            this.sharedData.varyingDeclaration += code;\r\n            this.sharedData.varyingDeclarationFragment += code;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getVaryingName(name: string): string {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return (this.target !== NodeMaterialBlockTargets.Fragment ? \"vertexOutputs.\" : \"fragmentInputs.\") + name;\r\n        }\r\n\r\n        return name;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitUniformFromString(name: string, type: NodeMaterialBlockConnectionPointTypes, define: string = \"\", notDefine = false) {\r\n        if (this.uniforms.indexOf(name) !== -1) {\r\n            return;\r\n        }\r\n\r\n        this.uniforms.push(name);\r\n\r\n        if (define) {\r\n            if (define.startsWith(\"defined(\")) {\r\n                this._uniformDeclaration += `#if ${define}\\n`;\r\n            } else {\r\n                this._uniformDeclaration += `${notDefine ? \"#ifndef\" : \"#ifdef\"} ${define}\\n`;\r\n            }\r\n        }\r\n        if (this.sharedData.formatConfig.getUniformAnnotation) {\r\n            this._uniformDeclaration += this.sharedData.formatConfig.getUniformAnnotation(name);\r\n        }\r\n        const shaderType = this._getShaderType(type);\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            this._uniformDeclaration += `uniform ${name}: ${shaderType};\\n`;\r\n        } else {\r\n            this._uniformDeclaration += `uniform ${shaderType} ${name};\\n`;\r\n        }\r\n        if (define) {\r\n            this._uniformDeclaration += `#endif\\n`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _generateTernary(trueStatement: string, falseStatement: string, condition: string) {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `select(${falseStatement}, ${trueStatement}, ${condition})`;\r\n        }\r\n\r\n        return `(${condition}) ? ${trueStatement} : ${falseStatement}`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _emitFloat(value: number) {\r\n        if (value.toString() === value.toFixed(0)) {\r\n            return `${value}.0`;\r\n        }\r\n\r\n        return value.toString();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _declareOutput(output: NodeMaterialConnectionPoint, isConst?: boolean): string {\r\n        return this._declareLocalVar(output.associatedVariableName, output.type, isConst);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _declareLocalVar(name: string, type: NodeMaterialBlockConnectionPointTypes, isConst?: boolean, isVarPrivate?: boolean): string {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `${isConst ? \"const\" : \"var\" + (isVarPrivate ? \"<private>\" : \"\")} ${name}: ${this._getShaderType(type)}`;\r\n        } else {\r\n            return `${isConst ? \"const \" : \"\"}${this._getShaderType(type)} ${name}`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _samplerCubeFunc() {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return \"textureSample\";\r\n        }\r\n        return \"textureCube\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _samplerFunc() {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return \"textureSample\";\r\n        }\r\n        return \"texture2D\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _samplerLODFunc() {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return \"textureSampleLevel\";\r\n        }\r\n        return \"texture2DLodEXT\";\r\n    }\r\n\r\n    public _toLinearSpace(output: NodeMaterialConnectionPoint) {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            if (output.type === NodeMaterialBlockConnectionPointTypes.Color3 || output.type === NodeMaterialBlockConnectionPointTypes.Vector3) {\r\n                return `toLinearSpaceVec3(${output.associatedVariableName})`;\r\n            }\r\n\r\n            return `toLinearSpace(${output.associatedVariableName})`;\r\n        }\r\n        return `toLinearSpace(${output.associatedVariableName})`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _generateTextureSample(uv: string, samplerName: string) {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `${this._samplerFunc()}(${samplerName},${samplerName + Constants.AUTOSAMPLERSUFFIX}, ${uv})`;\r\n        }\r\n        return `${this._samplerFunc()}(${samplerName}, ${uv})`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _generateTextureSampleLOD(uv: string, samplerName: string, lod: string) {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `${this._samplerLODFunc()}(${samplerName},${samplerName + Constants.AUTOSAMPLERSUFFIX}, ${uv}, ${lod})`;\r\n        }\r\n        return `${this._samplerLODFunc()}(${samplerName}, ${uv}, ${lod})`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _generateTextureSampleCube(uv: string, samplerName: string) {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `${this._samplerCubeFunc()}(${samplerName},${samplerName + Constants.AUTOSAMPLERSUFFIX}, ${uv})`;\r\n        }\r\n        return `${this._samplerCubeFunc()}(${samplerName}, ${uv})`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _generateTextureSampleCubeLOD(uv: string, samplerName: string, lod: string) {\r\n        if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `${this._samplerCubeFunc()}(${samplerName},${samplerName + Constants.AUTOSAMPLERSUFFIX}, ${uv}, ${lod})`;\r\n        }\r\n        return `${this._samplerCubeFunc()}(${samplerName}, ${uv}, ${lod})`;\r\n    }\r\n\r\n    private _convertVariableDeclarationToWGSL(type: string, dest: string, source: string): string {\r\n        return source.replace(new RegExp(`(${type})\\\\s+(\\\\w+)`, \"g\"), `var $2: ${dest}`);\r\n    }\r\n\r\n    private _convertVariableConstructorsToWGSL(type: string, dest: string, source: string): string {\r\n        return source.replace(new RegExp(`(${type})\\\\(`, \"g\"), ` ${dest}(`);\r\n    }\r\n\r\n    private _convertOutParametersToWGSL(source: string): string {\r\n        return source.replace(new RegExp(`out\\\\s+var\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)`, \"g\"), `$1: ptr<function, $2>`);\r\n    }\r\n\r\n    private _convertTernaryOperandsToWGSL(source: string): string {\r\n        return source.replace(new RegExp(`\\\\[(.*?)\\\\?(.*?):(.*)\\\\]`, \"g\"), (match, condition, trueCase, falseCase) => `select(${falseCase}, ${trueCase}, ${condition})`);\r\n    }\r\n\r\n    private _convertModOperatorsToWGSL(source: string): string {\r\n        return source.replace(new RegExp(`mod\\\\((.+?),\\\\s*(.+?)\\\\)`, \"g\"), (match, left, right) => `((${left})%(${right}))`);\r\n    }\r\n\r\n    private _convertConstToWGSL(source: string): string {\r\n        return source.replace(new RegExp(`const var`, \"g\"), `const`);\r\n    }\r\n\r\n    private _convertInnerFunctionsToWGSL(source: string): string {\r\n        return source.replace(new RegExp(`inversesqrt`, \"g\"), `inverseSqrt`);\r\n    }\r\n\r\n    private _convertFunctionsToWGSL(source: string): string {\r\n        const regex = /var\\s+(\\w+)\\s*:\\s*(\\w+)\\((.*)\\)/g;\r\n\r\n        let match: RegExpMatchArray | null;\r\n        while ((match = regex.exec(source)) !== null) {\r\n            const funcName = match[1];\r\n            const funcType = match[2];\r\n            const params = match[3]; // All parameters as a single string\r\n\r\n            // Processing the parameters to match 'name: type' format\r\n            const formattedParams = params.replace(/var\\s/g, \"\");\r\n\r\n            // Constructing the final output string\r\n            source = source.replace(match[0], `fn ${funcName}(${formattedParams}) -> ${funcType}`);\r\n        }\r\n        return source;\r\n    }\r\n\r\n    public _babylonSLtoWGSL(code: string) {\r\n        // variable declarations\r\n        code = this._convertVariableDeclarationToWGSL(\"void\", \"voidnull\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"bool\", \"bool\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"int\", \"i32\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"uint\", \"u32\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"float\", \"f32\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"vec2\", \"vec2f\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"vec3\", \"vec3f\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"vec4\", \"vec4f\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"mat2\", \"mat2x2f\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"mat3\", \"mat3x3f\", code);\r\n        code = this._convertVariableDeclarationToWGSL(\"mat4\", \"mat4x4f\", code);\r\n\r\n        // Type constructors\r\n        code = this._convertVariableConstructorsToWGSL(\"float\", \"f32\", code);\r\n        code = this._convertVariableConstructorsToWGSL(\"vec2\", \"vec2f\", code);\r\n        code = this._convertVariableConstructorsToWGSL(\"vec3\", \"vec3f\", code);\r\n        code = this._convertVariableConstructorsToWGSL(\"vec4\", \"vec4f\", code);\r\n        code = this._convertVariableConstructorsToWGSL(\"mat2\", \"mat2x2f\", code);\r\n        code = this._convertVariableConstructorsToWGSL(\"mat3\", \"mat3x3f\", code);\r\n        code = this._convertVariableConstructorsToWGSL(\"mat4\", \"mat4x4f\", code);\r\n\r\n        // Ternary operands\r\n        code = this._convertTernaryOperandsToWGSL(code);\r\n\r\n        // Mod operators\r\n        code = this._convertModOperatorsToWGSL(code);\r\n\r\n        // Const\r\n        code = this._convertConstToWGSL(code);\r\n\r\n        // Inner functions\r\n        code = this._convertInnerFunctionsToWGSL(code);\r\n\r\n        // Out paramters\r\n        code = this._convertOutParametersToWGSL(code);\r\n        code = code.replace(/\\[\\*\\]/g, \"*\");\r\n\r\n        // Functions\r\n        code = this._convertFunctionsToWGSL(code);\r\n\r\n        // Remove voidnull\r\n        code = code.replace(/\\s->\\svoidnull/g, \"\");\r\n\r\n        // Derivatives\r\n        code = code.replace(/dFdx/g, \"dpdx\");\r\n        code = code.replace(/dFdy/g, \"dpdy\");\r\n\r\n        return code;\r\n    }\r\n\r\n    private _convertTernaryOperandsToGLSL(source: string): string {\r\n        return source.replace(new RegExp(`\\\\[(.+?)\\\\?(.+?):(.+)\\\\]`, \"g\"), (match, condition, trueCase, falseCase) => `${condition} ? ${trueCase} : ${falseCase}`);\r\n    }\r\n\r\n    public _babylonSLtoGLSL(code: string) {\r\n        /** Remove BSL specifics */\r\n        code = code.replace(/\\[\\*\\]/g, \"\");\r\n        code = this._convertTernaryOperandsToGLSL(code);\r\n\r\n        return code;\r\n    }\r\n}\r\n","import { type NodeMaterialConnectionPoint } from \"./nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterialBlock } from \"./nodeMaterialBlock\";\r\nimport { type InputBlock } from \"./Blocks/Input/inputBlock\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Immutable, type Nullable } from \"../../types\";\r\nimport { type NodeMaterial, type NodeMaterialTextureBlocks } from \"./nodeMaterial\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Class used to store shared data between 2 NodeMaterialBuildState\r\n */\r\nexport class NodeMaterialBuildStateSharedData {\r\n    /**\r\n     * The node material we are currently building\r\n     */\r\n    public nodeMaterial: NodeMaterial;\r\n\r\n    /**\r\n     * Gets the list of emitted varyings\r\n     */\r\n    public temps: string[] = [];\r\n\r\n    /**\r\n     * Gets the list of emitted varyings\r\n     */\r\n    public varyings: string[] = [];\r\n\r\n    /**\r\n     * Gets the varying declaration string (for vertex shader)\r\n     */\r\n    public varyingDeclaration = \"\";\r\n\r\n    /**\r\n     * Gets the varying declaration string (for fragment shader)\r\n     * This is potentially different from varyingDeclaration only in WebGPU\r\n     */\r\n    public varyingDeclarationFragment = \"\";\r\n\r\n    /**\r\n     * Gets the varying initialization string (for fragment shader)\r\n     * Only used in WebGPU, to reconstruct the varying values from the vertex shader if their types is mat4x4f\r\n     */\r\n    public varyingInitializationsFragment = \"\";\r\n\r\n    /**\r\n     * List of the fragment output nodes\r\n     */\r\n    public fragmentOutputNodes: Immutable<Array<NodeMaterialBlock>>;\r\n\r\n    /**\r\n     * Input blocks\r\n     */\r\n    public inputBlocks: InputBlock[] = [];\r\n\r\n    /**\r\n     * Input blocks\r\n     */\r\n    public textureBlocks: NodeMaterialTextureBlocks[] = [];\r\n\r\n    /**\r\n     * Bindable blocks (Blocks that need to set data to the effect)\r\n     */\r\n    public bindableBlocks: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * Bindable blocks (Blocks that need to set data to the effect) that will always be called (by bindForSubMesh), contrary to bindableBlocks that won't be called if _mustRebind() returns false\r\n     */\r\n    public forcedBindableBlocks: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * List of blocks that can provide a compilation fallback\r\n     */\r\n    public blocksWithFallbacks: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * List of blocks that can provide a define update\r\n     */\r\n    public blocksWithDefines: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * List of blocks that can provide a repeatable content\r\n     */\r\n    public repeatableContentBlocks: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * List of blocks that can provide a dynamic list of uniforms\r\n     */\r\n    public dynamicUniformBlocks: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * List of blocks that can block the isReady function for the material\r\n     */\r\n    public blockingBlocks: NodeMaterialBlock[] = [];\r\n\r\n    /**\r\n     * Gets the list of animated inputs\r\n     */\r\n    public animatedInputs: InputBlock[] = [];\r\n\r\n    /**\r\n     * Defines to inject in the vertex and fragment shaders\r\n     */\r\n    public defines: { [key: string]: string } = {};\r\n\r\n    /**\r\n     * Configurations used to format the generated code\r\n     */\r\n    public formatConfig = {\r\n        getUniformAnnotation: null as Nullable<(name: string) => string>,\r\n        formatVariablename: (name: string) => name.replace(/[^a-zA-Z_]+/g, \"\"),\r\n    };\r\n\r\n    /**\r\n     * Build Id used to avoid multiple recompilations\r\n     */\r\n    public buildId: number;\r\n\r\n    /** List of emitted variables */\r\n    public variableNames: { [key: string]: number } = {};\r\n\r\n    /** List of emitted defines */\r\n    public defineNames: { [key: string]: number } = {};\r\n\r\n    /** Should emit comments? */\r\n    public emitComments: boolean;\r\n\r\n    /** Emit build activity */\r\n    public verbose: boolean;\r\n\r\n    /** Gets or sets the hosting scene */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Gets the compilation hints emitted at compilation time\r\n     */\r\n    public hints = {\r\n        needWorldViewMatrix: false,\r\n        needWorldViewProjectionMatrix: false,\r\n        needAlphaBlending: false,\r\n        needAlphaTesting: false,\r\n    };\r\n\r\n    /**\r\n     * List of compilation checks\r\n     */\r\n    public checks = {\r\n        emitVertex: false,\r\n        emitFragment: false,\r\n        notConnectedNonOptionalInputs: new Array<NodeMaterialConnectionPoint>(),\r\n        customErrors: new Array<string>(),\r\n    };\r\n\r\n    /**\r\n     * Is vertex program allowed to be empty?\r\n     */\r\n    public allowEmptyVertexProgram: boolean = false;\r\n\r\n    /** Creates a new shared data */\r\n    public constructor() {\r\n        // Exclude usual attributes from free variable names\r\n        this.variableNames[\"position\"] = 0;\r\n        this.variableNames[\"normal\"] = 0;\r\n        this.variableNames[\"tangent\"] = 0;\r\n        this.variableNames[\"uv\"] = 0;\r\n        this.variableNames[\"uv2\"] = 0;\r\n        this.variableNames[\"uv3\"] = 0;\r\n        this.variableNames[\"uv4\"] = 0;\r\n        this.variableNames[\"uv5\"] = 0;\r\n        this.variableNames[\"uv6\"] = 0;\r\n        this.variableNames[\"color\"] = 0;\r\n        this.variableNames[\"matricesIndices\"] = 0;\r\n        this.variableNames[\"matricesWeights\"] = 0;\r\n        this.variableNames[\"matricesIndicesExtra\"] = 0;\r\n        this.variableNames[\"matricesWeightsExtra\"] = 0;\r\n        this.variableNames[\"diffuseBase\"] = 0;\r\n        this.variableNames[\"specularBase\"] = 0;\r\n        this.variableNames[\"worldPos\"] = 0;\r\n        this.variableNames[\"shadow\"] = 0;\r\n        this.variableNames[\"view\"] = 0;\r\n\r\n        // Exclude known varyings\r\n        this.variableNames[\"vTBN\"] = 0;\r\n\r\n        // Exclude defines\r\n        this.defineNames[\"MAINUV0\"] = 0;\r\n        this.defineNames[\"MAINUV1\"] = 0;\r\n        this.defineNames[\"MAINUV2\"] = 0;\r\n        this.defineNames[\"MAINUV3\"] = 0;\r\n        this.defineNames[\"MAINUV4\"] = 0;\r\n        this.defineNames[\"MAINUV5\"] = 0;\r\n        this.defineNames[\"MAINUV6\"] = 0;\r\n        this.defineNames[\"MAINUV7\"] = 0;\r\n    }\r\n\r\n    /**\r\n     * Push a new error to the build state, avoiding exceptions that can break the build process\r\n     * @param message defines the error message to push\r\n     */\r\n    public raiseBuildError(message: string) {\r\n        if (this.checks.customErrors.indexOf(message) === -1) {\r\n            this.checks.customErrors.push(message);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Emits console errors and exceptions if there is a failing check\r\n     * @returns true if all checks pass\r\n     */\r\n    public emitErrors() {\r\n        let errorMessage = \"\";\r\n\r\n        if (!this.checks.emitVertex && !this.allowEmptyVertexProgram) {\r\n            errorMessage += \"NodeMaterial does not have a vertex output. You need to at least add a block that generates a position value.\\n\";\r\n        }\r\n        if (!this.checks.emitFragment) {\r\n            errorMessage += \"NodeMaterial does not have a fragment output. You need to at least add a block that generates a color value.\\n\";\r\n        }\r\n        for (const notConnectedInput of this.checks.notConnectedNonOptionalInputs) {\r\n            errorMessage += `input ${notConnectedInput.name} from block ${\r\n                notConnectedInput.ownerBlock.name\r\n            }[${notConnectedInput.ownerBlock.getClassName()}] is not connected and is not optional.\\n`;\r\n        }\r\n        for (const customError of this.checks.customErrors) {\r\n            errorMessage += customError + \"\\n\";\r\n        }\r\n\r\n        if (errorMessage) {\r\n            errorMessage = \"Node material build failed: \\n\" + errorMessage;\r\n            Logger.Error(errorMessage);\r\n            this.nodeMaterial.onBuildErrorObservable.notifyObservers(errorMessage);\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n}\r\n","import { NodeMaterialBlockConnectionPointTypes } from \"./Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { NodeMaterialBlockTargets } from \"./Enums/nodeMaterialBlockTargets\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type InputBlock } from \"./Blocks/Input/inputBlock\";\r\nimport { Observable, type Observer } from \"../../Misc/observable\";\r\nimport { type NodeMaterialBlock } from \"./nodeMaterialBlock\";\r\n\r\n/**\r\n * Enum used to define the compatibility state between two connection points\r\n */\r\nexport const enum NodeMaterialConnectionPointCompatibilityStates {\r\n    /** Points are compatibles */\r\n    Compatible,\r\n    /** Points are incompatible because of their types */\r\n    TypeIncompatible,\r\n    /** Points are incompatible because of their targets (vertex vs fragment) */\r\n    TargetIncompatible,\r\n    /** Points are incompatible because they are in the same hierarchy **/\r\n    HierarchyIssue,\r\n}\r\n\r\n/**\r\n * Defines the direction of a connection point\r\n */\r\nexport const enum NodeMaterialConnectionPointDirection {\r\n    /** Input */\r\n    Input,\r\n    /** Output */\r\n    Output,\r\n}\r\n\r\n/**\r\n * Defines a connection point for a block\r\n */\r\nexport class NodeMaterialConnectionPoint {\r\n    /**\r\n     * Checks if two types are equivalent\r\n     * @param type1 type 1 to check\r\n     * @param type2 type 2 to check\r\n     * @returns true if both types are equivalent, else false\r\n     */\r\n    public static AreEquivalentTypes(type1: number, type2: number): boolean {\r\n        switch (type1) {\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3: {\r\n                if (type2 === NodeMaterialBlockConnectionPointTypes.Color3) {\r\n                    return true;\r\n                }\r\n                break;\r\n            }\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4: {\r\n                if (type2 === NodeMaterialBlockConnectionPointTypes.Color4) {\r\n                    return true;\r\n                }\r\n                break;\r\n            }\r\n            case NodeMaterialBlockConnectionPointTypes.Color3: {\r\n                if (type2 === NodeMaterialBlockConnectionPointTypes.Vector3) {\r\n                    return true;\r\n                }\r\n                break;\r\n            }\r\n            case NodeMaterialBlockConnectionPointTypes.Color4: {\r\n                if (type2 === NodeMaterialBlockConnectionPointTypes.Vector4) {\r\n                    return true;\r\n                }\r\n                break;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _isInactive: boolean = false;\r\n\r\n    /**\r\n     * Boolean used to provide visual clue to users when some ports are not active in the current block configuration\r\n     */\r\n    public get isInactive(): boolean {\r\n        return this._isInactive;\r\n    }\r\n\r\n    /** @internal */\r\n    public _preventBubbleUp = false;\r\n\r\n    /** @internal */\r\n    public readonly _ownerBlock: NodeMaterialBlock;\r\n\r\n    private _connectedPointBackingField: Nullable<NodeMaterialConnectionPoint> = null;\r\n    private _connectedPointTypeChangedObserver: Nullable<Observer<NodeMaterialBlockConnectionPointTypes>>;\r\n\r\n    private get _connectedPoint(): Nullable<NodeMaterialConnectionPoint> {\r\n        return this._connectedPointBackingField;\r\n    }\r\n\r\n    private set _connectedPoint(value: Nullable<NodeMaterialConnectionPoint>) {\r\n        if (this._connectedPointBackingField === value) {\r\n            return;\r\n        }\r\n\r\n        this._connectedPointTypeChangedObserver?.remove();\r\n        this._updateTypeDependentState(() => (this._connectedPointBackingField = value));\r\n        if (this._connectedPointBackingField) {\r\n            this._connectedPointTypeChangedObserver = this._connectedPointBackingField.onTypeChangedObservable.add(() => {\r\n                this._notifyTypeChanged();\r\n            });\r\n        }\r\n    }\r\n\r\n    private readonly _endpoints = new Array<NodeMaterialConnectionPoint>();\r\n    private _associatedVariableName: string;\r\n    private readonly _direction: NodeMaterialConnectionPointDirection;\r\n\r\n    /** @internal */\r\n    public _redirectedSource: Nullable<NodeMaterialConnectionPoint> = null;\r\n\r\n    private _typeConnectionSourceBackingField: Nullable<NodeMaterialConnectionPoint> = null;\r\n    private _typeConnectionSourceTypeChangedObserver: Nullable<Observer<NodeMaterialBlockConnectionPointTypes>>;\r\n\r\n    /** @internal */\r\n    public get _typeConnectionSource(): Nullable<NodeMaterialConnectionPoint> {\r\n        return this._typeConnectionSourceBackingField;\r\n    }\r\n\r\n    /** @internal */\r\n    public set _typeConnectionSource(value: Nullable<NodeMaterialConnectionPoint>) {\r\n        if (this._typeConnectionSourceBackingField === value) {\r\n            return;\r\n        }\r\n\r\n        this._typeConnectionSourceTypeChangedObserver?.remove();\r\n        this._updateTypeDependentState(() => (this._typeConnectionSourceBackingField = value));\r\n        if (this._typeConnectionSourceBackingField) {\r\n            this._typeConnectionSourceTypeChangedObserver = this._typeConnectionSourceBackingField.onTypeChangedObservable.add(() => {\r\n                this._notifyTypeChanged();\r\n            });\r\n        }\r\n    }\r\n\r\n    private _defaultConnectionPointTypeBackingField: Nullable<NodeMaterialBlockConnectionPointTypes> = null;\r\n\r\n    /** @internal */\r\n    public get _defaultConnectionPointType(): Nullable<NodeMaterialBlockConnectionPointTypes> {\r\n        return this._defaultConnectionPointTypeBackingField;\r\n    }\r\n\r\n    /** @internal */\r\n    public set _defaultConnectionPointType(value: Nullable<NodeMaterialBlockConnectionPointTypes>) {\r\n        this._updateTypeDependentState(() => (this._defaultConnectionPointTypeBackingField = value));\r\n    }\r\n\r\n    /** @internal */\r\n    public _isMainLinkSource = false;\r\n\r\n    private _linkedConnectionSourceBackingField: Nullable<NodeMaterialConnectionPoint> = null;\r\n    private _linkedConnectionSourceTypeChangedObserver: Nullable<Observer<NodeMaterialBlockConnectionPointTypes>>;\r\n\r\n    /** @internal */\r\n    public get _linkedConnectionSource(): Nullable<NodeMaterialConnectionPoint> {\r\n        return this._linkedConnectionSourceBackingField;\r\n    }\r\n\r\n    /** @internal */\r\n    public set _linkedConnectionSource(value: Nullable<NodeMaterialConnectionPoint>) {\r\n        if (this._linkedConnectionSourceBackingField === value) {\r\n            return;\r\n        }\r\n\r\n        this._linkedConnectionSourceTypeChangedObserver?.remove();\r\n        this._updateTypeDependentState(() => (this._linkedConnectionSourceBackingField = value));\r\n        this._isMainLinkSource = false;\r\n        if (this._linkedConnectionSourceBackingField) {\r\n            this._linkedConnectionSourceTypeChangedObserver = this._linkedConnectionSourceBackingField.onTypeChangedObservable.add(() => {\r\n                this._notifyTypeChanged();\r\n            });\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _acceptedConnectionPointType: Nullable<NodeMaterialConnectionPoint> = null;\r\n\r\n    private _type = NodeMaterialBlockConnectionPointTypes.Float;\r\n\r\n    /** @internal */\r\n    public _enforceAssociatedVariableName = false;\r\n\r\n    /** @internal */\r\n    public _forPostBuild = false;\r\n\r\n    /** Gets the direction of the point */\r\n    public get direction() {\r\n        return this._direction;\r\n    }\r\n\r\n    /** Indicates that this connection point needs dual validation before being connected to another point */\r\n    public needDualDirectionValidation: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets the additional types supported by this connection point\r\n     */\r\n    public acceptedConnectionPointTypes: NodeMaterialBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Gets or sets the additional types excluded by this connection point\r\n     */\r\n    public excludedConnectionPointTypes: NodeMaterialBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Observable triggered when this point is connected\r\n     */\r\n    public readonly onConnectionObservable = new Observable<NodeMaterialConnectionPoint>();\r\n\r\n    /**\r\n     * Observable triggered when this point is disconnected\r\n     */\r\n    public readonly onDisconnectionObservable = new Observable<NodeMaterialConnectionPoint>();\r\n\r\n    /**\r\n     * Observable triggered when the type of the connection point is changed\r\n     */\r\n    public readonly onTypeChangedObservable = new Observable<NodeMaterialBlockConnectionPointTypes>();\r\n    private _isTypeChangeObservableNotifying = false;\r\n\r\n    /**\r\n     * Gets the declaration variable name in the shader\r\n     */\r\n    public get declarationVariableName(): string {\r\n        if (this._ownerBlock.isInput) {\r\n            return (this._ownerBlock as InputBlock).declarationVariableName;\r\n        }\r\n\r\n        if ((!this._enforceAssociatedVariableName || !this._associatedVariableName) && this._connectedPoint) {\r\n            return this._connectedPoint.declarationVariableName;\r\n        }\r\n\r\n        return this._associatedVariableName;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the associated variable name in the shader\r\n     */\r\n    public get associatedVariableName(): string {\r\n        if (this._ownerBlock.isInput) {\r\n            return (this._ownerBlock as InputBlock).associatedVariableName;\r\n        }\r\n\r\n        if ((!this._enforceAssociatedVariableName || !this._associatedVariableName) && this._connectedPoint) {\r\n            return this._connectedPoint.associatedVariableName;\r\n        }\r\n\r\n        return this._associatedVariableName;\r\n    }\r\n\r\n    public set associatedVariableName(value: string) {\r\n        this._associatedVariableName = value;\r\n    }\r\n\r\n    /** Get the inner type (ie AutoDetect for instance instead of the inferred one) */\r\n    public get innerType() {\r\n        if (this._linkedConnectionSource && !this._isMainLinkSource && this._linkedConnectionSource.isConnected) {\r\n            return this.type;\r\n        }\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is float)\r\n     */\r\n    public get type(): NodeMaterialBlockConnectionPointTypes {\r\n        if (this._type === NodeMaterialBlockConnectionPointTypes.AutoDetect) {\r\n            if (this._ownerBlock.isInput) {\r\n                return (this._ownerBlock as InputBlock).type;\r\n            }\r\n\r\n            if (this._connectedPoint) {\r\n                return this._connectedPoint.type;\r\n            }\r\n\r\n            if (this._linkedConnectionSource) {\r\n                if (this._linkedConnectionSource.isConnected) {\r\n                    if (this._linkedConnectionSource.connectedPoint!._redirectedSource && this._linkedConnectionSource.connectedPoint!._redirectedSource.isConnected) {\r\n                        return this._linkedConnectionSource.connectedPoint!._redirectedSource.type;\r\n                    }\r\n                    return this._linkedConnectionSource.type;\r\n                }\r\n                if (this._linkedConnectionSource._defaultConnectionPointType) {\r\n                    return this._linkedConnectionSource._defaultConnectionPointType;\r\n                }\r\n            }\r\n\r\n            if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        if (this._type === NodeMaterialBlockConnectionPointTypes.BasedOnInput) {\r\n            if (this._typeConnectionSource) {\r\n                if (!this._typeConnectionSource.isConnected && this._defaultConnectionPointType) {\r\n                    return this._defaultConnectionPointType;\r\n                }\r\n                return this._typeConnectionSource.type;\r\n            } else if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    public set type(value: NodeMaterialBlockConnectionPointTypes) {\r\n        this._updateTypeDependentState(() => (this._type = value));\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the connection point name\r\n     */\r\n    public readonly name: string;\r\n\r\n    /**\r\n     * Gets or sets the connection point name\r\n     */\r\n    public displayName: string;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point can be omitted\r\n     */\r\n    public isOptional: boolean;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is exposed on a frame\r\n     */\r\n    public isExposedOnFrame: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets number indicating the position that the port is exposed to on a frame\r\n     */\r\n    public exposedPortPosition: number = -1;\r\n\r\n    /**\r\n     * Gets or sets a string indicating that this uniform must be defined under a #ifdef\r\n     */\r\n    public define: string;\r\n\r\n    /** @internal */\r\n    public _prioritizeVertex = false;\r\n\r\n    private _target: NodeMaterialBlockTargets = NodeMaterialBlockTargets.VertexAndFragment;\r\n\r\n    /** Gets or sets the target of that connection point */\r\n    public get target(): NodeMaterialBlockTargets {\r\n        if (!this._prioritizeVertex || !this._ownerBlock) {\r\n            return this._target;\r\n        }\r\n\r\n        if (this._target !== NodeMaterialBlockTargets.VertexAndFragment) {\r\n            return this._target;\r\n        }\r\n\r\n        if (this._ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            return NodeMaterialBlockTargets.Fragment;\r\n        }\r\n\r\n        return NodeMaterialBlockTargets.Vertex;\r\n    }\r\n\r\n    public set target(value: NodeMaterialBlockTargets) {\r\n        this._target = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current point is connected to another NodeMaterialBlock\r\n     */\r\n    public get isConnected(): boolean {\r\n        return this.connectedPoint !== null || this.hasEndpoints;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current point is connected to an input block\r\n     */\r\n    public get isConnectedToInputBlock(): boolean {\r\n        return this.connectedPoint !== null && this.connectedPoint.ownerBlock.isInput;\r\n    }\r\n\r\n    /**\r\n     * Gets a the connected input block (if any)\r\n     */\r\n    public get connectInputBlock(): Nullable<InputBlock> {\r\n        if (!this.isConnectedToInputBlock) {\r\n            return null;\r\n        }\r\n\r\n        return this.connectedPoint!.ownerBlock as InputBlock;\r\n    }\r\n\r\n    /** Get the other side of the connection (if any) */\r\n    public get connectedPoint(): Nullable<NodeMaterialConnectionPoint> {\r\n        return this._connectedPoint;\r\n    }\r\n\r\n    /** Get the block that owns this connection point */\r\n    public get ownerBlock(): NodeMaterialBlock {\r\n        return this._ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the other side of this connection (if any) */\r\n    public get sourceBlock(): Nullable<NodeMaterialBlock> {\r\n        if (!this._connectedPoint) {\r\n            return null;\r\n        }\r\n\r\n        return this._connectedPoint.ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the endpoints of this connection (if any) */\r\n    public get connectedBlocks(): Array<NodeMaterialBlock> {\r\n        if (this._endpoints.length === 0) {\r\n            return [];\r\n        }\r\n\r\n        return this._endpoints.map((e) => e.ownerBlock);\r\n    }\r\n\r\n    /** Gets the list of connected endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /** Gets a boolean indicating if that output point is connected to at least one input */\r\n    public get hasEndpoints(): boolean {\r\n        return this._endpoints && this._endpoints.length > 0;\r\n    }\r\n\r\n    /** Gets a boolean indicating that this connection has a path to the vertex output*/\r\n    public get isDirectlyConnectedToVertexOutput(): boolean {\r\n        if (!this.hasEndpoints) {\r\n            return false;\r\n        }\r\n\r\n        for (const endpoint of this._endpoints) {\r\n            if (endpoint.ownerBlock.target === NodeMaterialBlockTargets.Vertex) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.ownerBlock.target === NodeMaterialBlockTargets.Neutral || endpoint.ownerBlock.target === NodeMaterialBlockTargets.VertexAndFragment) {\r\n                if (endpoint.ownerBlock.outputs.some((o) => o.isDirectlyConnectedToVertexOutput)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /** Gets a boolean indicating that this connection will be used in the vertex shader */\r\n    public get isConnectedInVertexShader(): boolean {\r\n        if (this.target === NodeMaterialBlockTargets.Vertex) {\r\n            return true;\r\n        }\r\n\r\n        if (!this.hasEndpoints) {\r\n            return false;\r\n        }\r\n\r\n        for (const endpoint of this._endpoints) {\r\n            if (endpoint.ownerBlock.target === NodeMaterialBlockTargets.Vertex) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.target === NodeMaterialBlockTargets.Vertex) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.ownerBlock.target === NodeMaterialBlockTargets.Neutral || endpoint.ownerBlock.target === NodeMaterialBlockTargets.VertexAndFragment) {\r\n                if (endpoint.ownerBlock.outputs.some((o) => o.isConnectedInVertexShader)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /** Gets a boolean indicating that this connection will be used in the fragment shader */\r\n    public get isConnectedInFragmentShader(): boolean {\r\n        if (this.target === NodeMaterialBlockTargets.Fragment) {\r\n            return true;\r\n        }\r\n\r\n        if (!this.hasEndpoints) {\r\n            return false;\r\n        }\r\n\r\n        for (const endpoint of this._endpoints) {\r\n            if (endpoint.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.ownerBlock.target === NodeMaterialBlockTargets.Neutral || endpoint.ownerBlock.target === NodeMaterialBlockTargets.VertexAndFragment) {\r\n                if (endpoint.ownerBlock.isConnectedInFragmentShader()) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Creates a block suitable to be used as an input for this input point.\r\n     * If null is returned, a block based on the point type will be created.\r\n     * @returns The returned string parameter is the name of the output point of NodeMaterialBlock (first parameter of the returned array) that can be connected to the input\r\n     */\r\n    public createCustomInputBlock(): Nullable<[NodeMaterialBlock, string]> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Creates a new connection point\r\n     * @param name defines the connection point name\r\n     * @param ownerBlock defines the block hosting this connection point\r\n     * @param direction defines the direction of the connection point\r\n     */\r\n    public constructor(name: string, ownerBlock: NodeMaterialBlock, direction: NodeMaterialConnectionPointDirection) {\r\n        this._ownerBlock = ownerBlock;\r\n        this.name = name;\r\n        this._direction = direction;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeMaterialConnectionPoint\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeMaterialConnectionPoint\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a boolean\r\n     */\r\n    public canConnectTo(connectionPoint: NodeMaterialConnectionPoint) {\r\n        return this.checkCompatibilityState(connectionPoint) === NodeMaterialConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Gets a number indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a number defining the compatibility state\r\n     */\r\n    public checkCompatibilityState(connectionPoint: NodeMaterialConnectionPoint): NodeMaterialConnectionPointCompatibilityStates {\r\n        const ownerBlock = this._ownerBlock;\r\n        const otherBlock = connectionPoint.ownerBlock;\r\n\r\n        if (ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            // Let's check we are not going reverse\r\n\r\n            if (otherBlock.target === NodeMaterialBlockTargets.Vertex) {\r\n                return NodeMaterialConnectionPointCompatibilityStates.TargetIncompatible;\r\n            }\r\n\r\n            for (const output of otherBlock.outputs) {\r\n                if (output.ownerBlock.target != NodeMaterialBlockTargets.Neutral && output.isConnectedInVertexShader) {\r\n                    return NodeMaterialConnectionPointCompatibilityStates.TargetIncompatible;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this.type !== connectionPoint.type && connectionPoint.innerType !== NodeMaterialBlockConnectionPointTypes.AutoDetect) {\r\n            // Equivalents\r\n            if (NodeMaterialConnectionPoint.AreEquivalentTypes(this.type, connectionPoint.type)) {\r\n                return NodeMaterialConnectionPointCompatibilityStates.Compatible;\r\n            }\r\n\r\n            // Accepted types\r\n            if (\r\n                (connectionPoint.acceptedConnectionPointTypes && connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1) ||\r\n                (connectionPoint._acceptedConnectionPointType && NodeMaterialConnectionPoint.AreEquivalentTypes(connectionPoint._acceptedConnectionPointType.type, this.type))\r\n            ) {\r\n                return NodeMaterialConnectionPointCompatibilityStates.Compatible;\r\n            } else {\r\n                return NodeMaterialConnectionPointCompatibilityStates.TypeIncompatible;\r\n            }\r\n        }\r\n\r\n        // Excluded\r\n        if (connectionPoint.excludedConnectionPointTypes && connectionPoint.excludedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n            return NodeMaterialConnectionPointCompatibilityStates.TypeIncompatible;\r\n        }\r\n\r\n        // Check hierarchy\r\n        let targetBlock = otherBlock;\r\n        let sourceBlock = ownerBlock;\r\n        if (this.direction === NodeMaterialConnectionPointDirection.Input) {\r\n            targetBlock = ownerBlock;\r\n            sourceBlock = otherBlock;\r\n        }\r\n\r\n        if (targetBlock.isAnAncestorOf(sourceBlock)) {\r\n            return NodeMaterialConnectionPointCompatibilityStates.HierarchyIssue;\r\n        }\r\n\r\n        return NodeMaterialConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Connect this point to another connection point\r\n     * @param connectionPoint defines the other connection point\r\n     * @param ignoreConstraints defines if the system will ignore connection type constraints (default is false)\r\n     * @returns the current connection point\r\n     */\r\n    public connectTo(connectionPoint: NodeMaterialConnectionPoint, ignoreConstraints = false): NodeMaterialConnectionPoint {\r\n        if (!ignoreConstraints && !this.canConnectTo(connectionPoint)) {\r\n            throw new Error(\r\n                `Cannot connect these two connectors. source: \"${this.ownerBlock.name}\".${this.name}, target: \"${connectionPoint.ownerBlock.name}\".${connectionPoint.name}`\r\n            );\r\n        }\r\n\r\n        this._endpoints.push(connectionPoint);\r\n        connectionPoint._connectedPoint = this;\r\n\r\n        this._enforceAssociatedVariableName = false;\r\n\r\n        this.onConnectionObservable.notifyObservers(connectionPoint);\r\n        connectionPoint.onConnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disconnect this point from one of his endpoint\r\n     * @param endpoint defines the other connection point\r\n     * @returns the current connection point\r\n     */\r\n    public disconnectFrom(endpoint: NodeMaterialConnectionPoint): NodeMaterialConnectionPoint {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index === -1) {\r\n            return this;\r\n        }\r\n\r\n        this._endpoints.splice(index, 1);\r\n        endpoint._connectedPoint = null;\r\n        this._enforceAssociatedVariableName = false;\r\n        endpoint._enforceAssociatedVariableName = false;\r\n\r\n        this.onDisconnectionObservable.notifyObservers(endpoint);\r\n        endpoint.onDisconnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Fill the list of excluded connection point types with all types other than those passed in the parameter\r\n     * @param mask Types (ORed values of NodeMaterialBlockConnectionPointTypes) that are allowed, and thus will not be pushed to the excluded list\r\n     */\r\n    public addExcludedConnectionPointFromAllowedTypes(mask: number): void {\r\n        let bitmask = 1;\r\n        while (bitmask < NodeMaterialBlockConnectionPointTypes.All) {\r\n            if (!(mask & bitmask)) {\r\n                this.excludedConnectionPointTypes.push(bitmask);\r\n            }\r\n            bitmask = bitmask << 1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this point in a JSON representation\r\n     * @param isInput defines if the connection point is an input (default is true)\r\n     * @returns the serialized point object\r\n     */\r\n    public serialize(isInput = true): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        if (this.displayName) {\r\n            serializationObject.displayName = this.displayName;\r\n        }\r\n\r\n        if (isInput && this.connectedPoint) {\r\n            serializationObject.inputName = this.name;\r\n            serializationObject.targetBlockId = this.connectedPoint.ownerBlock.uniqueId;\r\n            serializationObject.targetConnectionName = this.connectedPoint.name;\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        if (this.isExposedOnFrame || this.exposedPortPosition >= 0) {\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        this.onConnectionObservable.clear();\r\n        this.onDisconnectionObservable.clear();\r\n        this.onTypeChangedObservable.clear();\r\n\r\n        this._connectedPoint = null;\r\n        this._typeConnectionSource = null;\r\n        this._linkedConnectionSource = null;\r\n    }\r\n\r\n    private _updateTypeDependentState(update: () => void) {\r\n        const previousType = this.type;\r\n        update();\r\n        if (this.type !== previousType) {\r\n            this._notifyTypeChanged();\r\n        }\r\n    }\r\n\r\n    private _notifyTypeChanged() {\r\n        // Disallow re-entrancy\r\n        if (this._isTypeChangeObservableNotifying) {\r\n            return;\r\n        }\r\n\r\n        this._isTypeChangeObservableNotifying = true;\r\n        this.onTypeChangedObservable.notifyObservers(this.type);\r\n        this._isTypeChangeObservableNotifying = false;\r\n    }\r\n}\r\n","import { NodeMaterialBlockConnectionPointTypes } from \"./Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"./nodeMaterialBuildState\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"./nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"./Enums/nodeMaterialBlockTargets\";\r\nimport { type Effect } from \"../effect\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"./nodeMaterial\";\r\nimport { type InputBlock } from \"./Blocks/Input/inputBlock\";\r\nimport { UniqueIdGenerator } from \"../../Misc/uniqueIdGenerator\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { GetClass } from \"../../Misc/typeStore\";\r\nimport { type EffectFallbacks } from \"../effectFallbacks\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { type NodeMaterialTeleportOutBlock } from \"./Blocks/Teleport/teleportOutBlock\";\r\n\r\n/**\r\n * Defines a block that can be used inside a node based material\r\n */\r\nexport class NodeMaterialBlock {\r\n    private _buildId: number;\r\n    private _buildTarget: NodeMaterialBlockTargets;\r\n    protected _target: NodeMaterialBlockTargets;\r\n    private _isFinalMerger = false;\r\n    private _isInput = false;\r\n    private _isLoop = false;\r\n    private _isTeleportOut = false;\r\n    private _isTeleportIn = false;\r\n    private _name = \"\";\r\n    protected _isUnique = false;\r\n    protected _codeIsReady = true;\r\n    /** @internal */\r\n    public _isFinalOutput = false;\r\n\r\n    /** @internal */\r\n    public get _isFinalOutputAndActive() {\r\n        return this._isFinalOutput;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _hasPrecedence() {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Observable raised when the block code is ready (if the code loading is async)\r\n     */\r\n    public onCodeIsReadyObservable = new Observable<NodeMaterialBlock>();\r\n\r\n    /** Gets or sets a boolean indicating that only one input can be connected at a time */\r\n    public inputsAreExclusive = false;\r\n\r\n    /** @internal */\r\n    public _codeVariableName = \"\";\r\n\r\n    /** @internal */\r\n    public _inputs = new Array<NodeMaterialConnectionPoint>();\r\n    /** @internal */\r\n    public _outputs = new Array<NodeMaterialConnectionPoint>();\r\n\r\n    /** @internal */\r\n    public _preparationId: number;\r\n\r\n    /** @internal */\r\n    public readonly _originalTargetIsNeutral: boolean;\r\n\r\n    /**\r\n     * Gets the name of the block\r\n     */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block has is code ready to be used\r\n     */\r\n    public get codeIsReady() {\r\n        return this._codeIsReady;\r\n    }\r\n\r\n    /**\r\n     * Sets the name of the block. Will check if the name is valid.\r\n     */\r\n    public set name(newName: string) {\r\n        if (!this.validateBlockName(newName)) {\r\n            return;\r\n        }\r\n\r\n        this._name = newName;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the unique id of the node\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Gets or sets the comments associated with this block\r\n     */\r\n    public comments: string = \"\";\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block can only be used once per NodeMaterial\r\n     */\r\n    public get isUnique() {\r\n        return this._isUnique;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block is an end block (e.g. it is generating a system value)\r\n     */\r\n    public get isFinalMerger(): boolean {\r\n        return this._isFinalMerger;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block is an input (e.g. it sends data to the shader)\r\n     */\r\n    public get isInput(): boolean {\r\n        return this._isInput;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport out\r\n     */\r\n    public get isTeleportOut(): boolean {\r\n        return this._isTeleportOut;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport in\r\n     */\r\n    public get isTeleportIn(): boolean {\r\n        return this._isTeleportIn;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a loop\r\n     */\r\n    public get isLoop(): boolean {\r\n        return this._isLoop;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the build Id\r\n     */\r\n    public get buildId(): number {\r\n        return this._buildId;\r\n    }\r\n\r\n    public set buildId(value: number) {\r\n        this._buildId = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the target of the block\r\n     */\r\n    public get target() {\r\n        return this._target;\r\n    }\r\n\r\n    public set target(value: NodeMaterialBlockTargets) {\r\n        if ((this._target & value) !== 0) {\r\n            return;\r\n        }\r\n        this._target = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of input points\r\n     */\r\n    public get inputs(): NodeMaterialConnectionPoint[] {\r\n        return this._inputs;\r\n    }\r\n\r\n    /** Gets the list of output points */\r\n    public get outputs(): NodeMaterialConnectionPoint[] {\r\n        return this._outputs;\r\n    }\r\n\r\n    /**\r\n     * Find an input by its name\r\n     * @param name defines the name of the input to look for\r\n     * @returns the input or null if not found\r\n     */\r\n    public getInputByName(name: string) {\r\n        const filter = this._inputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Find an output by its name\r\n     * @param name defines the name of the output to look for\r\n     * @returns the output or null if not found\r\n     */\r\n    public getOutputByName(name: string) {\r\n        const filter = this._outputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */\r\n    public visibleInInspector = false;\r\n\r\n    /** Gets or sets a boolean indicating that this input can be edited from a collapsed frame */\r\n    public visibleOnFrame = false;\r\n\r\n    /**\r\n     * Creates a new NodeMaterialBlock\r\n     * @param name defines the block name\r\n     * @param target defines the target of that block (Vertex by default)\r\n     * @param isFinalMerger defines a boolean indicating that this block is an end block (e.g. it is generating a system value). Default is false\r\n     * @param isFinalOutput defines a boolean indicating that this block is generating a final output and no other block should be generated after\r\n     */\r\n    public constructor(name: string, target = NodeMaterialBlockTargets.Vertex, isFinalMerger = false, isFinalOutput = false) {\r\n        this._target = target;\r\n        this._originalTargetIsNeutral = target === NodeMaterialBlockTargets.Neutral;\r\n        this._isFinalMerger = isFinalMerger;\r\n        this._isFinalOutput = isFinalOutput;\r\n        switch (this.getClassName()) {\r\n            case \"InputBlock\":\r\n                this._isInput = true;\r\n                break;\r\n            case \"NodeMaterialTeleportOutBlock\":\r\n                this._isTeleportOut = true;\r\n                break;\r\n            case \"NodeMaterialTeleportInBlock\":\r\n                this._isTeleportIn = true;\r\n                break;\r\n            case \"LoopBlock\":\r\n                this._isLoop = true;\r\n                break;\r\n        }\r\n\r\n        this._name = name;\r\n        this.uniqueId = UniqueIdGenerator.UniqueId;\r\n    }\r\n\r\n    /** @internal */\r\n    public _setInitialTarget(target: NodeMaterialBlockTargets): void {\r\n        this._target = target;\r\n        // marked as read only\r\n        (this._originalTargetIsNeutral as boolean) = target === NodeMaterialBlockTargets.Neutral;\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public initialize(state: NodeMaterialBuildState) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect. Will only be called for blocks with isBindable === true\r\n     * @param effect defines the effect to bind data to\r\n     * @param nodeMaterial defines the hosting NodeMaterial\r\n     * @param mesh defines the mesh that will be rendered\r\n     * @param subMesh defines the submesh that will be rendered\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh, subMesh?: SubMesh) {\r\n        // Do nothing\r\n    }\r\n\r\n    protected _writeVariable(currentPoint: NodeMaterialConnectionPoint): string {\r\n        const connectionPoint = currentPoint.connectedPoint;\r\n\r\n        if (connectionPoint) {\r\n            return `${currentPoint.associatedVariableName}`;\r\n        }\r\n\r\n        return `0.`;\r\n    }\r\n\r\n    protected _writeFloat(value: number) {\r\n        let stringVersion = value.toString();\r\n\r\n        if (stringVersion.indexOf(\".\") === -1) {\r\n            stringVersion += \".0\";\r\n        }\r\n        return `${stringVersion}`;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeMaterialBlock\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName() {\r\n        return \"NodeMaterialBlock\";\r\n    }\r\n\r\n    /** Gets a boolean indicating that this connection will be used in the fragment shader\r\n     * @returns true if connected in fragment shader\r\n     */\r\n    public isConnectedInFragmentShader() {\r\n        return this.outputs.some((o) => o.isConnectedInFragmentShader);\r\n    }\r\n\r\n    /**\r\n     * Register a new input. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param isOptional defines a boolean indicating that this input can be omitted\r\n     * @param target defines the target to use to limit the connection point (will be VertexAndFragment by default)\r\n     * @param point an already created connection point. If not provided, create a new one\r\n     * @returns the current block\r\n     */\r\n    public registerInput(\r\n        name: string,\r\n        type: NodeMaterialBlockConnectionPointTypes,\r\n        isOptional: boolean = false,\r\n        target?: NodeMaterialBlockTargets,\r\n        point?: NodeMaterialConnectionPoint\r\n    ) {\r\n        point = point ?? new NodeMaterialConnectionPoint(name, this, NodeMaterialConnectionPointDirection.Input);\r\n        point.type = type;\r\n        point.isOptional = isOptional;\r\n        if (target) {\r\n            point.target = target;\r\n        }\r\n\r\n        this._inputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Register a new output. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param target defines the target to use to limit the connection point (will be VertexAndFragment by default)\r\n     * @param point an already created connection point. If not provided, create a new one\r\n     * @returns the current block\r\n     */\r\n    public registerOutput(name: string, type: NodeMaterialBlockConnectionPointTypes, target?: NodeMaterialBlockTargets, point?: NodeMaterialConnectionPoint) {\r\n        point = point ?? new NodeMaterialConnectionPoint(name, this, NodeMaterialConnectionPointDirection.Output);\r\n        point.type = type;\r\n        if (target) {\r\n            point.target = target;\r\n        }\r\n\r\n        this._outputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Will return the first available input e.g. the first one which is not an uniform or an attribute\r\n     * @param forOutput defines an optional connection point to check compatibility with\r\n     * @returns the first available input or null\r\n     */\r\n    public getFirstAvailableInput(forOutput: Nullable<NodeMaterialConnectionPoint> = null) {\r\n        for (const input of this._inputs) {\r\n            if (!input.connectedPoint) {\r\n                if (\r\n                    !forOutput ||\r\n                    forOutput.type === input.type ||\r\n                    input.type === NodeMaterialBlockConnectionPointTypes.AutoDetect ||\r\n                    input.acceptedConnectionPointTypes.indexOf(forOutput.type) !== -1\r\n                ) {\r\n                    return input;\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Will return the first available output e.g. the first one which is not yet connected and not a varying\r\n     * @param forBlock defines an optional block to check compatibility with\r\n     * @returns the first available input or null\r\n     */\r\n    public getFirstAvailableOutput(forBlock: Nullable<NodeMaterialBlock> = null) {\r\n        for (const output of this._outputs) {\r\n            if (!forBlock || !forBlock.target || forBlock.target === NodeMaterialBlockTargets.Neutral || (forBlock.target & output.target) !== 0) {\r\n                return output;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the sibling of the given output\r\n     * @param current defines the current output\r\n     * @returns the next output in the list or null\r\n     */\r\n    public getSiblingOutput(current: NodeMaterialConnectionPoint) {\r\n        const index = this._outputs.indexOf(current);\r\n\r\n        if (index === -1 || index >= this._outputs.length) {\r\n            return null;\r\n        }\r\n\r\n        return this._outputs[index + 1];\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOf(block: NodeMaterialBlock): boolean {\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock === block) {\r\n                    return true;\r\n                }\r\n                if (endpoint.ownerBlock.isAnAncestorOf(block)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Connect current block with another block\r\n     * @param other defines the block to connect with\r\n     * @param options define the various options to help pick the right connections\r\n     * @returns the current block\r\n     */\r\n    public connectTo(\r\n        other: NodeMaterialBlock,\r\n        options?: {\r\n            input?: string;\r\n            output?: string;\r\n            outputSwizzle?: string;\r\n        }\r\n    ) {\r\n        if (this._outputs.length === 0) {\r\n            return;\r\n        }\r\n\r\n        let output = options && options.output ? this.getOutputByName(options.output) : this.getFirstAvailableOutput(other);\r\n\r\n        let notFound = true;\r\n        while (notFound) {\r\n            const input = options && options.input ? other.getInputByName(options.input) : other.getFirstAvailableInput(output);\r\n\r\n            if (output && input && output.canConnectTo(input)) {\r\n                output.connectTo(input);\r\n                notFound = false;\r\n            } else if (!output) {\r\n                throw new Error(\"Unable to find a compatible match\");\r\n            } else {\r\n                output = this.getSiblingOutput(output);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _buildBlock(state: NodeMaterialBuildState) {\r\n        // Empty. Must be defined by child nodes\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _postBuildBlock(state: NodeMaterialBuildState) {\r\n        // Empty. Must be defined by child nodes\r\n    }\r\n\r\n    /**\r\n     * Add uniforms, samplers and uniform buffers at compilation time\r\n     * @param state defines the state to update\r\n     * @param nodeMaterial defines the node material requesting the update\r\n     * @param defines defines the material defines to update\r\n     * @param uniformBuffers defines the list of uniform buffer names\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public updateUniformsAndSamples(state: NodeMaterialBuildState, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, uniformBuffers: string[]) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Add potential fallbacks if shader compilation fails\r\n     * @param fallbacks defines the current prioritized list of fallbacks\r\n     * @param mesh defines the mesh to be rendered\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public provideFallbacks(fallbacks: EffectFallbacks, mesh?: AbstractMesh) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Initialize defines for shader compilation\r\n     * @param defines defines the material defines to update\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public initializeDefines(defines: NodeMaterialDefines) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Update defines for shader compilation\r\n     * @param defines defines the material defines to update\r\n     * @param nodeMaterial defines the node material requesting the update\r\n     * @param mesh defines the mesh to be rendered\r\n     * @param useInstances specifies that instances should be used\r\n     * @param subMesh defines which submesh to render\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh, useInstances: boolean = false, subMesh?: SubMesh) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Lets the block try to connect some inputs automatically\r\n     * @param material defines the hosting NodeMaterial\r\n     * @param additionalFilteringInfo optional additional filtering condition when looking for compatible blocks\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Function called when a block is declared as repeatable content generator\r\n     * @param vertexShaderState defines the current compilation state for the vertex shader\r\n     * @param defines defines the material defines to update\r\n     * @param mesh defines the mesh to be rendered\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public replaceRepeatableContent(vertexShaderState: NodeMaterialBuildState, defines: NodeMaterialDefines, mesh?: AbstractMesh) {\r\n        // Do nothing\r\n    }\r\n\r\n    /** Gets a boolean indicating that the code of this block will be promoted to vertex shader even if connected to fragment output */\r\n    public get willBeGeneratedIntoVertexShaderFromFragmentShader(): boolean {\r\n        if (this.isInput || this.isFinalMerger) {\r\n            return false;\r\n        }\r\n\r\n        if (this._outputs.some((o) => o.isDirectlyConnectedToVertexOutput)) {\r\n            return false;\r\n        }\r\n\r\n        if (this.target === NodeMaterialBlockTargets.Vertex) {\r\n            return false;\r\n        }\r\n\r\n        if (this.target === NodeMaterialBlockTargets.VertexAndFragment || this.target === NodeMaterialBlockTargets.Neutral) {\r\n            if (this._outputs.some((o) => o.isConnectedInVertexShader)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @param mesh defines the mesh to be rendered\r\n     * @param nodeMaterial defines the node material requesting the update\r\n     * @param defines defines the material defines to update\r\n     * @param useInstances specifies that instances should be used\r\n     * @returns true if the block is ready\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public isReady(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances: boolean = false) {\r\n        return true;\r\n    }\r\n\r\n    protected _linkConnectionTypes(inputIndex0: number, inputIndex1: number, looseCoupling = false) {\r\n        if (looseCoupling) {\r\n            this._inputs[inputIndex1]._acceptedConnectionPointType = this._inputs[inputIndex0];\r\n        } else {\r\n            this._inputs[inputIndex0]._linkedConnectionSource = this._inputs[inputIndex1];\r\n            this._inputs[inputIndex0]._isMainLinkSource = true;\r\n        }\r\n        this._inputs[inputIndex1]._linkedConnectionSource = this._inputs[inputIndex0];\r\n    }\r\n\r\n    private _processBuild(block: NodeMaterialBlock, state: NodeMaterialBuildState, input: NodeMaterialConnectionPoint, activeBlocks: NodeMaterialBlock[]) {\r\n        block.build(state, activeBlocks);\r\n\r\n        const localBlockIsFragment = state._vertexState != null;\r\n        const otherBlockWasGeneratedInVertexShader = block._buildTarget === NodeMaterialBlockTargets.Vertex && block.target !== NodeMaterialBlockTargets.VertexAndFragment;\r\n\r\n        if (block.isTeleportOut && (block as NodeMaterialTeleportOutBlock).entryPoint?.isConnectedToUniform) {\r\n            // In that case, we skip the context switch as the teleport out block is connected to a uniform\r\n            return;\r\n        }\r\n\r\n        if (\r\n            localBlockIsFragment &&\r\n            ((block.target & block._buildTarget) === 0 ||\r\n                (block.target & input.target) === 0 ||\r\n                (this.target !== NodeMaterialBlockTargets.VertexAndFragment && otherBlockWasGeneratedInVertexShader))\r\n        ) {\r\n            // context switch! We need a varying\r\n            if (\r\n                (!block.isInput && state.target !== block._buildTarget) || // block was already emitted by vertex shader\r\n                (block.isInput && (block as InputBlock).isAttribute && !(block as InputBlock)._noContextSwitch) // block is an attribute\r\n            ) {\r\n                const connectedPoint = input.connectedPoint!;\r\n                if (state._vertexState._emitVaryingFromString(\"v_\" + connectedPoint.declarationVariableName, connectedPoint.type)) {\r\n                    const prefix = state.shaderLanguage === ShaderLanguage.WGSL ? \"vertexOutputs.\" : \"\";\r\n                    if (state.shaderLanguage === ShaderLanguage.WGSL && connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Matrix) {\r\n                        // We can't pass a matrix as a varying in WGSL, so we need to split it into 4 vectors\r\n                        state._vertexState.compilationString += `${prefix}${\"v_\" + connectedPoint.declarationVariableName}_r0 = ${connectedPoint.associatedVariableName}[0];\\n`;\r\n                        state._vertexState.compilationString += `${prefix}${\"v_\" + connectedPoint.declarationVariableName}_r1 = ${connectedPoint.associatedVariableName}[1];\\n`;\r\n                        state._vertexState.compilationString += `${prefix}${\"v_\" + connectedPoint.declarationVariableName}_r2 = ${connectedPoint.associatedVariableName}[2];\\n`;\r\n                        state._vertexState.compilationString += `${prefix}${\"v_\" + connectedPoint.declarationVariableName}_r3 = ${connectedPoint.associatedVariableName}[3];\\n`;\r\n                    } else {\r\n                        state._vertexState.compilationString += `${prefix}${\"v_\" + connectedPoint.declarationVariableName} = ${connectedPoint.associatedVariableName};\\n`;\r\n                    }\r\n                }\r\n                const prefix = state.shaderLanguage === ShaderLanguage.WGSL && connectedPoint.type !== NodeMaterialBlockConnectionPointTypes.Matrix ? \"fragmentInputs.\" : \"\";\r\n                input.associatedVariableName = prefix + \"v_\" + connectedPoint.declarationVariableName;\r\n                input._enforceAssociatedVariableName = true;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Validates the new name for the block node.\r\n     * @param newName the new name to be given to the node.\r\n     * @returns false if the name is a reserve word, else true.\r\n     */\r\n    public validateBlockName(newName: string) {\r\n        const reservedNames: Array<string> = [\r\n            \"position\",\r\n            \"normal\",\r\n            \"tangent\",\r\n            \"particle_positionw\",\r\n            \"uv\",\r\n            \"uv2\",\r\n            \"uv3\",\r\n            \"uv4\",\r\n            \"uv5\",\r\n            \"uv6\",\r\n            \"position2d\",\r\n            \"particle_uv\",\r\n            \"postprocess_uv\",\r\n            \"matricesIndices\",\r\n            \"matricesWeights\",\r\n            \"world0\",\r\n            \"world1\",\r\n            \"world2\",\r\n            \"world3\",\r\n            \"particle_color\",\r\n            \"particle_texturemask\",\r\n        ];\r\n        for (const reservedName of reservedNames) {\r\n            if (newName === reservedName) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _customBuildStep(state: NodeMaterialBuildState, activeBlocks: NodeMaterialBlock[]): void {\r\n        // Must be implemented by children\r\n    }\r\n\r\n    /**\r\n     * Compile the current node and generate the shader code\r\n     * @param state defines the current compilation state (uniforms, samplers, current string)\r\n     * @param activeBlocks defines the list of active blocks (i.e. blocks to compile)\r\n     * @returns true if already built\r\n     */\r\n    public build(state: NodeMaterialBuildState, activeBlocks: NodeMaterialBlock[]): boolean {\r\n        if (this._buildId === state.sharedData.buildId) {\r\n            return true;\r\n        }\r\n\r\n        if (!this.isInput) {\r\n            /** Prepare outputs */\r\n            for (const output of this._outputs) {\r\n                if (!output.associatedVariableName) {\r\n                    output.associatedVariableName = state._getFreeVariableName(output.name);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Check if \"parent\" blocks are compiled\r\n        for (const input of this._inputs) {\r\n            if (!input.connectedPoint) {\r\n                if (!input.isOptional) {\r\n                    // Emit a warning\r\n                    state.sharedData.checks.notConnectedNonOptionalInputs.push(input);\r\n                }\r\n                continue;\r\n            }\r\n\r\n            if (this.target !== NodeMaterialBlockTargets.Neutral) {\r\n                if ((input.target & this.target) === 0) {\r\n                    continue;\r\n                }\r\n\r\n                if ((input.target & state.target) === 0) {\r\n                    continue;\r\n                }\r\n            }\r\n\r\n            const block = input.connectedPoint.ownerBlock;\r\n            if (block && block !== this) {\r\n                this._processBuild(block, state, input, activeBlocks);\r\n            }\r\n        }\r\n\r\n        this._customBuildStep(state, activeBlocks);\r\n\r\n        if (this._buildId === state.sharedData.buildId) {\r\n            return true; // Need to check again as inputs can be connected multiple time to this endpoint\r\n        }\r\n\r\n        // Logs\r\n        if (state.sharedData.verbose) {\r\n            Logger.Log(`${state.target === NodeMaterialBlockTargets.Vertex ? \"Vertex shader\" : \"Fragment shader\"}: Building ${this.name} [${this.getClassName()}]`);\r\n        }\r\n\r\n        // Checks final outputs\r\n        if (this.isFinalMerger) {\r\n            switch (state.target) {\r\n                case NodeMaterialBlockTargets.Vertex:\r\n                    state.sharedData.checks.emitVertex = true;\r\n                    break;\r\n                case NodeMaterialBlockTargets.Fragment:\r\n                    state.sharedData.checks.emitFragment = true;\r\n                    break;\r\n            }\r\n        }\r\n\r\n        if (!this.isInput && state.sharedData.emitComments) {\r\n            state.compilationString += `\\n//${this.name}\\n`;\r\n        }\r\n\r\n        this._buildBlock(state);\r\n\r\n        this._buildId = state.sharedData.buildId;\r\n        this._buildTarget = state.target;\r\n\r\n        // Compile connected blocks\r\n        for (const output of this._outputs) {\r\n            if (output._forPostBuild) {\r\n                continue;\r\n            }\r\n            if ((output.target & state.target) === 0) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const block = endpoint.ownerBlock;\r\n\r\n                if (block) {\r\n                    if (((block.target & state.target) !== 0 && activeBlocks.indexOf(block) !== -1) || state._terminalBlocks.has(block)) {\r\n                        this._processBuild(block, state, endpoint, activeBlocks);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._postBuildBlock(state);\r\n\r\n        // Compile post build connected blocks\r\n        for (const output of this._outputs) {\r\n            if (!output._forPostBuild) {\r\n                continue;\r\n            }\r\n            if ((output.target & state.target) === 0) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const block = endpoint.ownerBlock;\r\n\r\n                if (block && (block.target & state.target) !== 0 && activeBlocks.indexOf(block) !== -1) {\r\n                    this._processBuild(block, state, endpoint, activeBlocks);\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    protected _inputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    protected _outputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    protected _dumpPropertiesCode() {\r\n        const variableName = this._codeVariableName;\r\n        return `${variableName}.visibleInInspector = ${this.visibleInInspector};\\n${variableName}.visibleOnFrame = ${this.visibleOnFrame};\\n${variableName}.target = ${this.target};\\n`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _dumpCode(uniqueNames: string[], alreadyDumped: NodeMaterialBlock[]) {\r\n        alreadyDumped.push(this);\r\n\r\n        // Get unique name\r\n        const nameAsVariableName = this.name.replace(/[^A-Za-z_]+/g, \"\");\r\n        this._codeVariableName = nameAsVariableName || `${this.getClassName()}_${this.uniqueId}`;\r\n\r\n        if (uniqueNames.indexOf(this._codeVariableName) !== -1) {\r\n            let index = 0;\r\n            do {\r\n                index++;\r\n                this._codeVariableName = nameAsVariableName + index;\r\n            } while (uniqueNames.indexOf(this._codeVariableName) !== -1);\r\n        }\r\n\r\n        uniqueNames.push(this._codeVariableName);\r\n\r\n        // Declaration\r\n        let codeString = `\\n// ${this.getClassName()}\\n`;\r\n        if (this.comments) {\r\n            codeString += `// ${this.comments}\\n`;\r\n        }\r\n        codeString += `var ${this._codeVariableName} = new BABYLON.${this.getClassName()}(\"${this.name}\");\\n`;\r\n\r\n        // Properties\r\n        codeString += this._dumpPropertiesCode();\r\n\r\n        // Inputs\r\n        for (const input of this.inputs) {\r\n            if (!input.isConnected) {\r\n                continue;\r\n            }\r\n\r\n            const connectedOutput = input.connectedPoint!;\r\n            const connectedBlock = connectedOutput.ownerBlock;\r\n\r\n            if (alreadyDumped.indexOf(connectedBlock) === -1) {\r\n                codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        // Outputs\r\n        for (const output of this.outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const connectedBlock = endpoint.ownerBlock;\r\n                if (connectedBlock && alreadyDumped.indexOf(connectedBlock) === -1) {\r\n                    codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);\r\n                }\r\n            }\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _dumpCodeForOutputConnections(alreadyDumped: NodeMaterialBlock[]) {\r\n        let codeString = \"\";\r\n\r\n        if (alreadyDumped.indexOf(this) !== -1) {\r\n            return codeString;\r\n        }\r\n\r\n        alreadyDumped.push(this);\r\n\r\n        for (const input of this.inputs) {\r\n            if (!input.isConnected) {\r\n                continue;\r\n            }\r\n\r\n            const connectedOutput = input.connectedPoint!;\r\n            const connectedBlock = connectedOutput.ownerBlock;\r\n\r\n            codeString += connectedBlock._dumpCodeForOutputConnections(alreadyDumped);\r\n            codeString += `${connectedBlock._codeVariableName}.${connectedBlock._outputRename(connectedOutput.name)}.connectTo(${this._codeVariableName}.${this._inputRename(\r\n                input.name\r\n            )});\\n`;\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @returns a copy of the current block\r\n     */\r\n    public clone(scene: Scene, rootUrl: string = \"\") {\r\n        const serializationObject = this.serialize();\r\n\r\n        const blockType = GetClass(serializationObject.customType);\r\n        if (blockType) {\r\n            const block: NodeMaterialBlock = new blockType();\r\n            block._deserialize(serializationObject, scene, rootUrl);\r\n\r\n            return block;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.customType = \"BABYLON.\" + this.getClassName();\r\n        serializationObject.id = this.uniqueId;\r\n        serializationObject.name = this.name;\r\n        serializationObject.comments = this.comments;\r\n        serializationObject.visibleInInspector = this.visibleInInspector;\r\n        serializationObject.visibleOnFrame = this.visibleOnFrame;\r\n        serializationObject.target = this.target;\r\n\r\n        serializationObject.inputs = [];\r\n        serializationObject.outputs = [];\r\n\r\n        for (const input of this.inputs) {\r\n            serializationObject.inputs.push(input.serialize());\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            serializationObject.outputs.push(output.serialize(false));\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string, urlRewriter?: (url: string) => string) {\r\n        this.name = serializationObject.name;\r\n        this.comments = serializationObject.comments;\r\n        this.visibleInInspector = !!serializationObject.visibleInInspector;\r\n        this.visibleOnFrame = !!serializationObject.visibleOnFrame;\r\n        this._target = serializationObject.target ?? this.target;\r\n        this._deserializePortDisplayNamesAndExposedOnFrame(serializationObject);\r\n    }\r\n\r\n    private _deserializePortDisplayNamesAndExposedOnFrame(serializationObject: any) {\r\n        const serializedInputs = serializationObject.inputs;\r\n        const serializedOutputs = serializationObject.outputs;\r\n        if (serializedInputs) {\r\n            for (let i = 0; i < Math.min(serializedInputs.length, this.inputs.length); i++) {\r\n                const port = serializedInputs[i];\r\n\r\n                if (port.displayName) {\r\n                    this.inputs[i].displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    this.inputs[i].isExposedOnFrame = port.isExposedOnFrame;\r\n                    this.inputs[i].exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n            }\r\n        }\r\n        if (serializedOutputs) {\r\n            for (let i = 0; i < Math.min(serializedOutputs.length, this.outputs.length); i++) {\r\n                const port = serializedOutputs[i];\r\n                if (port.displayName) {\r\n                    this.outputs[i].displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    this.outputs[i].isExposedOnFrame = port.isExposedOnFrame;\r\n                    this.outputs[i].exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        this.onCodeIsReadyObservable.clear();\r\n\r\n        for (const input of this.inputs) {\r\n            input.dispose();\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            output.dispose();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type NodeMaterialDefines, type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { BindLogDepth } from \"../../../materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Color spaces supported by the fragment output block\r\n */\r\nexport enum FragmentOutputBlockColorSpace {\r\n    /** Unspecified */\r\n    NoColorSpace,\r\n    /** Gamma */\r\n    Gamma,\r\n    /** Linear */\r\n    Linear,\r\n}\r\n\r\n/**\r\n * Block used to output the final color\r\n */\r\nexport class FragmentOutputBlock extends NodeMaterialBlock {\r\n    private _linearDefineName: string;\r\n    private _gammaDefineName: string;\r\n    private _additionalColorDefineName: string | undefined;\r\n    protected _outputString: string;\r\n\r\n    /**\r\n     * Create a new FragmentOutputBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment, true, true);\r\n\r\n        this.registerInput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, true);\r\n        this.registerInput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, true);\r\n        this.registerInput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"glow\", NodeMaterialBlockConnectionPointTypes.Color3, true);\r\n\r\n        this.rgb.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.rgb.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.additionalColor.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.additionalColor.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if content needs to be converted to gamma space */\r\n    public convertToGammaSpace = false;\r\n\r\n    /** Gets or sets a boolean indicating if content needs to be converted to linear space */\r\n    public convertToLinearSpace = false;\r\n\r\n    /** Gets or sets a boolean indicating if logarithmic depth should be used */\r\n    @editableInPropertyPage(\"Use logarithmic depth\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true })\r\n    public useLogarithmicDepth = false;\r\n\r\n    /**\r\n     * Gets or sets the color space used for the block\r\n     */\r\n    @editableInPropertyPage(\"Color space\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"No color space\", value: FragmentOutputBlockColorSpace.NoColorSpace },\r\n            { label: \"To Gamma\", value: FragmentOutputBlockColorSpace.Gamma },\r\n            { label: \"To Linear\", value: FragmentOutputBlockColorSpace.Linear },\r\n        ],\r\n    })\r\n    public get colorSpace() {\r\n        if (this.convertToGammaSpace) {\r\n            return FragmentOutputBlockColorSpace.Gamma;\r\n        }\r\n        if (this.convertToLinearSpace) {\r\n            return FragmentOutputBlockColorSpace.Linear;\r\n        }\r\n        return FragmentOutputBlockColorSpace.NoColorSpace;\r\n    }\r\n\r\n    public set colorSpace(value: FragmentOutputBlockColorSpace) {\r\n        this.convertToGammaSpace = value === FragmentOutputBlockColorSpace.Gamma;\r\n        this.convertToLinearSpace = value === FragmentOutputBlockColorSpace.Linear;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"FragmentOutputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"logarithmicDepthConstant\");\r\n        state._excludeVariableName(\"vFragmentDepth\");\r\n        state._excludeVariableName(\"objectId\");\r\n        state._excludeVariableName(\"meshBlendTag\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\"), import(\"../../../../ShadersWGSL/ShadersInclude/objectIdFunctions\")]);\r\n        } else {\r\n            await Promise.all([import(\"../../../../Shaders/ShadersInclude/helperFunctions\"), import(\"../../../../Shaders/ShadersInclude/objectIdFunctions\")]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba input component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb input component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the a input component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the additionalColor input component (named glow in the UI for now)\r\n     */\r\n    public get additionalColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the glow input component\r\n     */\r\n    public get glow(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    protected _getOutputString(state: NodeMaterialBuildState): string {\r\n        return state.shaderLanguage === ShaderLanguage.WGSL ? \"fragmentOutputsColor\" : \"gl_FragColor\";\r\n    }\r\n\r\n    private _writePrePassOutput(state: NodeMaterialBuildState, define: string, indexDefine: string, value: string): string {\r\n        if (state.shaderLanguage !== ShaderLanguage.WGSL) {\r\n            return `#ifdef ${define}\\r\\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(${indexDefine}, ${value});\\r\\n#endif\\r\\n`;\r\n        }\r\n\r\n        let code = \"\";\r\n        for (let index = 0; index < 8; index++) {\r\n            code += `#if defined(${define}) && ${indexDefine} == ${index}\\r\\nfragmentOutputs.fragData${index} = ${value};\\r\\n#endif\\r\\n`;\r\n        }\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     * @param nodeMaterial - the node material\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial) {\r\n        defines.setValue(this._linearDefineName, this.convertToLinearSpace, true);\r\n        defines.setValue(this._gammaDefineName, this.convertToGammaSpace, true);\r\n        if (this._additionalColorDefineName !== undefined) {\r\n            defines.setValue(this._additionalColorDefineName, !!this.additionalColor.connectedPoint && nodeMaterial._useAdditionalColor, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if ((this.useLogarithmicDepth || nodeMaterial.useLogarithmicDepth) && mesh) {\r\n            BindLogDepth(undefined, effect, mesh.getScene());\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const rgba = this.rgba;\r\n        const rgb = this.rgb;\r\n        const a = this.a;\r\n        const additionalColor = this.additionalColor;\r\n\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        state.sharedData.hints.needAlphaBlending = rgba.isConnected || a.isConnected;\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        if (this.useLogarithmicDepth || state.sharedData.nodeMaterial.useLogarithmicDepth) {\r\n            state._emitUniformFromString(\"logarithmicDepthConstant\", NodeMaterialBlockConnectionPointTypes.Float);\r\n            state._emitVaryingFromString(\"vFragmentDepth\", NodeMaterialBlockConnectionPointTypes.Float);\r\n            state.sharedData.bindableBlocks.push(this);\r\n        }\r\n\r\n        if (additionalColor.connectedPoint) {\r\n            state._excludeVariableName(\"useAdditionalColor\");\r\n            state._emitUniformFromString(\"useAdditionalColor\", NodeMaterialBlockConnectionPointTypes.Float);\r\n            this._additionalColorDefineName = state._getFreeDefineName(\"USEADDITIONALCOLOR\");\r\n        }\r\n\r\n        this._linearDefineName = state._getFreeDefineName(\"CONVERTTOLINEAR\");\r\n        this._gammaDefineName = state._getFreeDefineName(\"CONVERTTOGAMMA\");\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n        state._emitFunctionFromInclude(\"objectIdFunctions\", comments, { define: \"PREPASS_OBJECT_ID\" });\r\n        state._emitUniformFromString(\"objectId\", NodeMaterialBlockConnectionPointTypes.Float, \"PREPASS_OBJECT_ID\");\r\n        state._emitUniformFromString(\"meshBlendTag\", NodeMaterialBlockConnectionPointTypes.Int, \"PREPASS_MESH_BLEND_TAG\");\r\n\r\n        const outputString = this._getOutputString(state);\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            state.compilationString += `var ${outputString} : vec4<f32>;\\r\\n`;\r\n        }\r\n\r\n        const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        if (additionalColor.connectedPoint) {\r\n            let aValue = \"1.0\";\r\n\r\n            if (a.connectedPoint) {\r\n                aValue = a.associatedVariableName;\r\n            }\r\n            state.compilationString += `#ifdef ${this._additionalColorDefineName}\\n`;\r\n            if (additionalColor.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n                state.compilationString += `${outputString}  = ${vec4}(${additionalColor.associatedVariableName}, ${additionalColor.associatedVariableName}, ${additionalColor.associatedVariableName}, ${aValue});\\n`;\r\n            } else {\r\n                state.compilationString += `${outputString}  = ${vec4}(${additionalColor.associatedVariableName}, ${aValue});\\n`;\r\n            }\r\n            state.compilationString += `#else\\n`;\r\n        }\r\n\r\n        if (rgba.connectedPoint) {\r\n            if (a.isConnected) {\r\n                state.compilationString += `${outputString} = ${vec4}(${rgba.associatedVariableName}.rgb, ${a.associatedVariableName});\\n`;\r\n            } else {\r\n                state.compilationString += `${outputString}  = ${rgba.associatedVariableName};\\n`;\r\n            }\r\n        } else if (rgb.connectedPoint) {\r\n            let aValue = \"1.0\";\r\n\r\n            if (a.connectedPoint) {\r\n                aValue = a.associatedVariableName;\r\n            }\r\n\r\n            if (rgb.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n                state.compilationString += `${outputString}  = ${vec4}(${rgb.associatedVariableName}, ${rgb.associatedVariableName}, ${rgb.associatedVariableName}, ${aValue});\\n`;\r\n            } else {\r\n                state.compilationString += `${outputString}  = ${vec4}(${rgb.associatedVariableName}, ${aValue});\\n`;\r\n            }\r\n        } else {\r\n            state.sharedData.checks.notConnectedNonOptionalInputs.push(rgba);\r\n        }\r\n\r\n        if (additionalColor.connectedPoint) {\r\n            state.compilationString += `#endif\\n`;\r\n        }\r\n\r\n        state.compilationString += `#ifdef ${this._linearDefineName}\\n`;\r\n        state.compilationString += `${outputString}  = toLinearSpace${state.shaderLanguage === ShaderLanguage.WGSL ? \"Vec4\" : \"\"}(${outputString});\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        state.compilationString += `#ifdef ${this._gammaDefineName}\\n`;\r\n        state.compilationString += `${outputString}  = toGammaSpace(${outputString});\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            state.compilationString += `#if !defined(PREPASS)\\r\\n`;\r\n            state.compilationString += `fragmentOutputs.color = ${outputString};\\r\\n`;\r\n            state.compilationString += `#endif\\r\\n`;\r\n        }\r\n\r\n        if (this.useLogarithmicDepth || state.sharedData.nodeMaterial.useLogarithmicDepth) {\r\n            const fragDepth = isWebGPU ? \"input.vFragmentDepth\" : \"vFragmentDepth\";\r\n            const uniformP = isWebGPU ? \"uniforms.\" : \"\";\r\n            const output = isWebGPU ? \"fragmentOutputs.fragDepth\" : \"gl_FragDepthEXT\";\r\n\r\n            state.compilationString += `${output} = log2(${fragDepth}) * ${uniformP}logarithmicDepthConstant * 0.5;\\n`;\r\n        }\r\n\r\n        const uniformPrefix = isWebGPU ? \"uniforms.\" : \"\";\r\n        state.compilationString += `#if defined(PREPASS)\\r\\n`;\r\n        state.compilationString += this._writePrePassOutput(state, \"PREPASS_COLOR\", \"PREPASS_COLOR_INDEX\", outputString);\r\n        state.compilationString += this._writePrePassOutput(state, \"PREPASS_OBJECT_ID\", \"PREPASS_OBJECT_ID_INDEX\", `encodeObjectId(${uniformPrefix}objectId)`);\r\n        if (isWebGPU) {\r\n            state.compilationString += this._writePrePassOutput(\r\n                state,\r\n                \"PREPASS_MESH_BLEND_TAG\",\r\n                \"PREPASS_MESH_BLEND_TAG_INDEX\",\r\n                `vec4u(u32(${uniformPrefix}meshBlendTag), 0u, 0u, 0u)`\r\n            );\r\n        } else {\r\n            state.compilationString += `#ifdef PREPASS_MESH_BLEND_TAG\\r\\n`;\r\n            state.compilationString += `meshBlendTagOutput = uvec4(uint(${uniformPrefix}meshBlendTag), 0u, 0u, 0u);\\r\\n`;\r\n            state.compilationString += `#endif\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n        codeString += `${this._codeVariableName}.convertToGammaSpace = ${this.convertToGammaSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.convertToLinearSpace = ${this.convertToLinearSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.useLogarithmicDepth = ${this.useLogarithmicDepth};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.convertToGammaSpace = this.convertToGammaSpace;\r\n        serializationObject.convertToLinearSpace = this.convertToLinearSpace;\r\n        serializationObject.useLogarithmicDepth = this.useLogarithmicDepth;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.convertToGammaSpace = !!serializationObject.convertToGammaSpace;\r\n        this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;\r\n        this.useLogarithmicDepth = serializationObject.useLogarithmicDepth ?? false;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fragmentOutputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFragmentOutputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FragmentOutputBlock\", FragmentOutputBlock);\r\n}\r\n","/**\r\n * Enum used to define the material modes\r\n */\r\nexport enum NodeMaterialModes {\r\n    /** Regular material */\r\n    Material = 0,\r\n    /** For post process */\r\n    PostProcess = 1,\r\n    /** For particle system */\r\n    Particle = 2,\r\n    /** For procedural texture */\r\n    ProceduralTexture = 3,\r\n    /** For gaussian splatting */\r\n    GaussianSplatting = 4,\r\n    /** For SFE */\r\n    SFE = 5,\r\n}\r\n","/**\r\n * Enum used to define system values e.g. values automatically provided by the system\r\n */\r\nexport enum NodeMaterialSystemValues {\r\n    /** World */\r\n    World = 1,\r\n    /** View */\r\n    View = 2,\r\n    /** Projection */\r\n    Projection = 3,\r\n    /** ViewProjection */\r\n    ViewProjection = 4,\r\n    /** WorldView */\r\n    WorldView = 5,\r\n    /** WorldViewProjection */\r\n    WorldViewProjection = 6,\r\n    /** CameraPosition */\r\n    CameraPosition = 7,\r\n    /** Fog Color */\r\n    FogColor = 8,\r\n    /** Delta time */\r\n    DeltaTime = 9,\r\n    /** Camera parameters */\r\n    CameraParameters = 10,\r\n    /** Material alpha */\r\n    MaterialAlpha = 11,\r\n    /** Projection */\r\n    ProjectionInverse = 12,\r\n    /** CameraForward */\r\n    CameraForward = 13,\r\n}\r\n","/**\r\n * Enum defining the type of animations supported by InputBlock\r\n */\r\nexport enum AnimatedInputBlockTypes {\r\n    /** No animation */\r\n    None,\r\n    /** Time based animation (is incremented by 0.6 each second). Will only work for floats */\r\n    Time,\r\n    /** Time elapsed (in seconds) since the engine was initialized. Will only work for floats */\r\n    RealTime,\r\n    MouseInfo,\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { NodeMaterialBlockConnectionPointMode } from \"../../Enums/nodeMaterialBlockConnectionPointMode\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type Effect } from \"../../../../Materials/effect.pure\";\r\nimport { Matrix, Vector2, Vector3, Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { GetClass, RegisterClass } from \"../../../../Misc/typeStore\";\r\nimport { Color3, Color4, TmpColors, TmpVectors } from \"../../../../Maths/math\";\r\nimport { AnimatedInputBlockTypes } from \"./animatedInputBlockTypes\";\r\nimport { Observable } from \"../../../../Misc/observable.pure\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { PrecisionDate } from \"../../../../Misc/precisionDate\";\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\n\r\nconst remapAttributeName: { [name: string]: string } = {\r\n    position2d: \"position\",\r\n    // From particle.vertex:\r\n    particle_uv: \"vUV\",\r\n    particle_color: \"vColor\",\r\n    particle_texturemask: \"textureMask\",\r\n    particle_positionw: \"vPositionW\",\r\n    // From postprocess.vertex:\r\n    postprocess_uv: \"vUV\",\r\n};\r\n\r\nconst attributeInFragmentOnly: { [name: string]: boolean } = {\r\n    particle_uv: true,\r\n    particle_color: true,\r\n    particle_texturemask: true,\r\n    particle_positionw: true,\r\n    postprocess_uv: true,\r\n};\r\n\r\nconst attributeAsUniform: { [name: string]: boolean } = {\r\n    particle_texturemask: true,\r\n};\r\n\r\nconst attributeDefine: { [name: string]: string } = {\r\n    normal: \"NORMAL\",\r\n    tangent: \"TANGENT\",\r\n    uv: \"UV1\",\r\n    uv2: \"UV2\",\r\n    uv3: \"UV3\",\r\n    uv4: \"UV4\",\r\n    uv5: \"UV5\",\r\n    uv6: \"UV6\",\r\n    uv7: \"UV7\",\r\n    uv8: \"UV8\",\r\n};\r\n\r\n/**\r\n * Block used to expose an input value\r\n */\r\nexport class InputBlock extends NodeMaterialBlock {\r\n    private _mode = NodeMaterialBlockConnectionPointMode.Undefined;\r\n    private _associatedVariableName: string;\r\n    private _storedValue: any;\r\n    private _valueCallback: () => any;\r\n    private _type: NodeMaterialBlockConnectionPointTypes;\r\n    private _animationType = AnimatedInputBlockTypes.None;\r\n    private _prefix = \"\";\r\n\r\n    /** Gets or set a value used to limit the range of float values */\r\n    public min: number = 0;\r\n\r\n    /** Gets or set a value used to limit the range of float values */\r\n    public max: number = 0;\r\n\r\n    /** Gets or set a value indicating that this input can only get 0 and 1 values */\r\n    public isBoolean: boolean = false;\r\n\r\n    /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */\r\n    public matrixMode: number = 0;\r\n\r\n    /** @internal */\r\n    public _systemValue: Nullable<NodeMaterialSystemValues> = null;\r\n\r\n    /** Gets or sets a boolean indicating that the value of this input will not change after a build */\r\n    public isConstant = false;\r\n\r\n    /** Gets or sets the group to use to display this block in the Inspector */\r\n    public groupInInspector = \"\";\r\n\r\n    /** Gets an observable raised when the value is changed */\r\n    public onValueChangedObservable = new Observable<InputBlock>();\r\n\r\n    /** Gets or sets a boolean indicating if content needs to be converted to gamma space (for color3/4 only) */\r\n    public convertToGammaSpace = false;\r\n\r\n    /** Gets or sets a boolean indicating if content needs to be converted to linear space (for color3/4 only) */\r\n    public convertToLinearSpace = false;\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is float)\r\n     */\r\n    public get type(): NodeMaterialBlockConnectionPointTypes {\r\n        if (this._type === NodeMaterialBlockConnectionPointTypes.AutoDetect) {\r\n            if (this.isUniform && this.value != null) {\r\n                if (!isNaN(this.value)) {\r\n                    this._type = NodeMaterialBlockConnectionPointTypes.Float;\r\n                    return this._type;\r\n                }\r\n\r\n                switch (this.value.getClassName()) {\r\n                    case \"Vector2\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector2;\r\n                        return this._type;\r\n                    case \"Vector3\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector3;\r\n                        return this._type;\r\n                    case \"Vector4\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector4;\r\n                        return this._type;\r\n                    case \"Color3\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Color3;\r\n                        return this._type;\r\n                    case \"Color4\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Color4;\r\n                        return this._type;\r\n                    case \"Matrix\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Matrix;\r\n                        return this._type;\r\n                }\r\n            }\r\n\r\n            if (this.isAttribute) {\r\n                switch (this.name) {\r\n                    case \"splatIndex\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Float;\r\n                        return this._type;\r\n                    case \"position\":\r\n                    case \"normal\":\r\n                    case \"particle_positionw\":\r\n                    case \"splatPosition\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector3;\r\n                        return this._type;\r\n                    case \"uv\":\r\n                    case \"uv2\":\r\n                    case \"uv3\":\r\n                    case \"uv4\":\r\n                    case \"uv5\":\r\n                    case \"uv6\":\r\n                    case \"position2d\":\r\n                    case \"particle_uv\":\r\n                    case \"splatScale\":\r\n                    case \"postprocess_uv\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector2;\r\n                        return this._type;\r\n                    case \"matricesIndices\":\r\n                    case \"matricesWeights\":\r\n                    case \"matricesIndicesExtra\":\r\n                    case \"matricesWeightsExtra\":\r\n                    case \"world0\":\r\n                    case \"world1\":\r\n                    case \"world2\":\r\n                    case \"world3\":\r\n                    case \"tangent\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector4;\r\n                        return this._type;\r\n                    case \"color\":\r\n                    case \"instanceColor\":\r\n                    case \"particle_color\":\r\n                    case \"particle_texturemask\":\r\n                    case \"splatColor\":\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Color4;\r\n                        return this._type;\r\n                }\r\n            }\r\n\r\n            if (this.isSystemValue) {\r\n                switch (this._systemValue) {\r\n                    case NodeMaterialSystemValues.World:\r\n                    case NodeMaterialSystemValues.WorldView:\r\n                    case NodeMaterialSystemValues.WorldViewProjection:\r\n                    case NodeMaterialSystemValues.View:\r\n                    case NodeMaterialSystemValues.ViewProjection:\r\n                    case NodeMaterialSystemValues.Projection:\r\n                    case NodeMaterialSystemValues.ProjectionInverse:\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Matrix;\r\n                        return this._type;\r\n                    case NodeMaterialSystemValues.CameraPosition:\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector3;\r\n                        return this._type;\r\n                    case NodeMaterialSystemValues.CameraForward:\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector3;\r\n                        return this._type;\r\n                    case NodeMaterialSystemValues.FogColor:\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Color3;\r\n                        return this._type;\r\n                    case NodeMaterialSystemValues.DeltaTime:\r\n                    case NodeMaterialSystemValues.MaterialAlpha:\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Float;\r\n                        return this._type;\r\n                    case NodeMaterialSystemValues.CameraParameters:\r\n                        this._type = NodeMaterialBlockConnectionPointTypes.Vector4;\r\n                        return this._type;\r\n                }\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Creates a new InputBlock\r\n     * @param name defines the block name\r\n     * @param target defines the target of that block (Vertex by default)\r\n     * @param type defines the type of the input (can be set to NodeMaterialBlockConnectionPointTypes.AutoDetect)\r\n     */\r\n    public constructor(name: string, target = NodeMaterialBlockTargets.Vertex, type: NodeMaterialBlockConnectionPointTypes = NodeMaterialBlockConnectionPointTypes.AutoDetect) {\r\n        super(name, target, false);\r\n\r\n        this._type = type;\r\n\r\n        this.setDefaultValue();\r\n\r\n        this.registerOutput(\"output\", type);\r\n    }\r\n\r\n    /**\r\n     * Validates if a name is a reserve word.\r\n     * @param newName the new name to be given to the node.\r\n     * @returns false if the name is a reserve word, else true.\r\n     */\r\n    public override validateBlockName(newName: string) {\r\n        if (!this.isAttribute) {\r\n            return super.validateBlockName(newName);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Set the source of this connection point to a vertex attribute\r\n     * @param attributeName defines the attribute name (position, uv, normal, etc...). If not specified it will take the connection point name\r\n     * @returns the current connection point\r\n     */\r\n    public setAsAttribute(attributeName?: string): InputBlock {\r\n        this._mode = NodeMaterialBlockConnectionPointMode.Attribute;\r\n        if (attributeName) {\r\n            this.name = attributeName;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set the source of this connection point to a system value\r\n     * @param value define the system value to use (world, view, etc...) or null to switch to manual value\r\n     * @returns the current connection point\r\n     */\r\n    public setAsSystemValue(value: Nullable<NodeMaterialSystemValues>): InputBlock {\r\n        this.systemValue = value;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the value of that point.\r\n     * Please note that this value will be ignored if valueCallback is defined\r\n     */\r\n    public get value(): any {\r\n        return this._storedValue;\r\n    }\r\n\r\n    public set value(value: any) {\r\n        if (this.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n            if (this.isBoolean) {\r\n                value = value ? 1 : 0;\r\n            } else if (this.min !== this.max) {\r\n                value = Math.max(this.min, value);\r\n                value = Math.min(this.max, value);\r\n            }\r\n        }\r\n\r\n        this._storedValue = value;\r\n        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;\r\n\r\n        this.onValueChangedObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a callback used to get the value of that point.\r\n     * Please note that setting this value will force the connection point to ignore the value property\r\n     */\r\n    public get valueCallback(): () => any {\r\n        return this._valueCallback;\r\n    }\r\n\r\n    public set valueCallback(value: () => any) {\r\n        this._valueCallback = value;\r\n        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;\r\n    }\r\n\r\n    /**\r\n     * Gets the declaration variable name in the shader\r\n     */\r\n    public get declarationVariableName(): string {\r\n        return this._associatedVariableName;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the associated variable name in the shader\r\n     */\r\n    public get associatedVariableName(): string {\r\n        return this._prefix + this._associatedVariableName;\r\n    }\r\n\r\n    public set associatedVariableName(value: string) {\r\n        this._associatedVariableName = value;\r\n    }\r\n\r\n    /** Gets or sets the type of animation applied to the input */\r\n    public get animationType() {\r\n        return this._animationType;\r\n    }\r\n\r\n    public set animationType(value: AnimatedInputBlockTypes) {\r\n        this._animationType = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this connection point not defined yet\r\n     */\r\n    public get isUndefined(): boolean {\r\n        return this._mode === NodeMaterialBlockConnectionPointMode.Undefined;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is coming from an uniform.\r\n     * In this case the connection point name must be the name of the uniform to use.\r\n     * Can only be set on inputs\r\n     */\r\n    public get isUniform(): boolean {\r\n        return this._mode === NodeMaterialBlockConnectionPointMode.Uniform;\r\n    }\r\n\r\n    public set isUniform(value: boolean) {\r\n        this._mode = value ? NodeMaterialBlockConnectionPointMode.Uniform : NodeMaterialBlockConnectionPointMode.Undefined;\r\n        this.associatedVariableName = \"\";\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is coming from an attribute.\r\n     * In this case the connection point name must be the name of the attribute to use\r\n     * Can only be set on inputs\r\n     */\r\n    public get isAttribute(): boolean {\r\n        return this._mode === NodeMaterialBlockConnectionPointMode.Attribute;\r\n    }\r\n\r\n    public set isAttribute(value: boolean) {\r\n        this._mode = value ? NodeMaterialBlockConnectionPointMode.Attribute : NodeMaterialBlockConnectionPointMode.Undefined;\r\n        this.associatedVariableName = \"\";\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is generating a varying variable.\r\n     * Can only be set on exit points\r\n     */\r\n    public get isVarying(): boolean {\r\n        return this._mode === NodeMaterialBlockConnectionPointMode.Varying;\r\n    }\r\n\r\n    public set isVarying(value: boolean) {\r\n        this._mode = value ? NodeMaterialBlockConnectionPointMode.Varying : NodeMaterialBlockConnectionPointMode.Undefined;\r\n        this.associatedVariableName = \"\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current connection point is a system value\r\n     */\r\n    public get isSystemValue(): boolean {\r\n        return this._systemValue != null;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current well known value or null if not defined as a system value\r\n     */\r\n    public get systemValue(): Nullable<NodeMaterialSystemValues> {\r\n        return this._systemValue;\r\n    }\r\n\r\n    public set systemValue(value: Nullable<NodeMaterialSystemValues>) {\r\n        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;\r\n        this.associatedVariableName = \"\";\r\n        this._systemValue = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Animate the input if animationType !== None\r\n     * @param scene defines the rendering scene\r\n     */\r\n    public animate(scene: Scene) {\r\n        switch (this._animationType) {\r\n            case AnimatedInputBlockTypes.Time: {\r\n                if (this.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n                    this.value += scene.getAnimationRatio() * 0.01;\r\n                }\r\n                break;\r\n            }\r\n            case AnimatedInputBlockTypes.RealTime: {\r\n                if (this.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n                    this.value = (PrecisionDate.Now - scene.getEngine().startTime) / 1000;\r\n                }\r\n                break;\r\n            }\r\n            case AnimatedInputBlockTypes.MouseInfo: {\r\n                if (this.type === NodeMaterialBlockConnectionPointTypes.Vector4) {\r\n                    const event = scene._inputManager._originMouseEvent;\r\n                    if (event) {\r\n                        const x = event.offsetX;\r\n                        const y = event.offsetY;\r\n                        const z = (event.buttons & 1) != 0 ? 1 : 0;\r\n                        const w = (event.buttons & 2) != 0 ? 1 : 0;\r\n                        this.value = new Vector4(x, y, z, w);\r\n                    } else {\r\n                        this.value = new Vector4(0, 0, 0, 0);\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _emitDefine(define: string, notDefine = false): string {\r\n        return `${notDefine ? \"#ifndef\" : \"#ifdef\"} ${define}\\n`;\r\n    }\r\n\r\n    /**\r\n     * Initialize the block\r\n     */\r\n    public override initialize() {\r\n        this.associatedVariableName = \"\";\r\n    }\r\n\r\n    /**\r\n     * Set the input block to its default value (based on its type)\r\n     */\r\n    public setDefaultValue() {\r\n        switch (this.type) {\r\n            case NodeMaterialBlockConnectionPointTypes.Float:\r\n                this.value = 0;\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                this.value = Vector2.Zero();\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                this.value = Vector3.Zero();\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                this.value = Vector4.Zero();\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Color3:\r\n                this.value = Color3.White();\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Color4:\r\n                this.value = new Color4(1, 1, 1, 1);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Matrix:\r\n                this.value = Matrix.Identity();\r\n                break;\r\n        }\r\n    }\r\n\r\n    private _emitConstant(state: NodeMaterialBuildState) {\r\n        switch (this.type) {\r\n            case NodeMaterialBlockConnectionPointTypes.Float:\r\n                return `${state._emitFloat(this.value)}`;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                return `vec2(${this.value.x}, ${this.value.y})`;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                return `vec3(${this.value.x}, ${this.value.y}, ${this.value.z})`;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                return `vec4(${this.value.x}, ${this.value.y}, ${this.value.z}, ${this.value.w})`;\r\n            case NodeMaterialBlockConnectionPointTypes.Color3:\r\n                TmpColors.Color3[0].set(this.value.r, this.value.g, this.value.b);\r\n                if (this.convertToGammaSpace) {\r\n                    TmpColors.Color3[0].toGammaSpaceToRef(TmpColors.Color3[0], state.sharedData.scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                if (this.convertToLinearSpace) {\r\n                    TmpColors.Color3[0].toLinearSpaceToRef(TmpColors.Color3[0], state.sharedData.scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                return `vec3(${TmpColors.Color3[0].r}, ${TmpColors.Color3[0].g}, ${TmpColors.Color3[0].b})`;\r\n            case NodeMaterialBlockConnectionPointTypes.Color4:\r\n                TmpColors.Color4[0].set(this.value.r, this.value.g, this.value.b, this.value.a);\r\n                if (this.convertToGammaSpace) {\r\n                    TmpColors.Color4[0].toGammaSpaceToRef(TmpColors.Color4[0], state.sharedData.scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                if (this.convertToLinearSpace) {\r\n                    TmpColors.Color4[0].toLinearSpaceToRef(TmpColors.Color4[0], state.sharedData.scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                return `vec4(${TmpColors.Color4[0].r}, ${TmpColors.Color4[0].g}, ${TmpColors.Color4[0].b}, ${TmpColors.Color4[0].a})`;\r\n        }\r\n\r\n        return \"\";\r\n    }\r\n\r\n    /** @internal */\r\n    public get _noContextSwitch(): boolean {\r\n        return attributeInFragmentOnly[this.name];\r\n    }\r\n\r\n    private _emit(state: NodeMaterialBuildState) {\r\n        // Uniforms\r\n        if (this.isUniform) {\r\n            if (!this._associatedVariableName) {\r\n                this._associatedVariableName = state._getFreeVariableName(\"u_\" + this.name);\r\n            }\r\n\r\n            if (this.isConstant) {\r\n                if (state.constants.indexOf(this.associatedVariableName) !== -1) {\r\n                    return;\r\n                }\r\n                state.constants.push(this.associatedVariableName);\r\n                state._constantDeclaration += state._declareOutput(this.output, true) + ` = ${this._emitConstant(state)};\\n`;\r\n                return;\r\n            }\r\n\r\n            if (state.uniforms.indexOf(this.associatedVariableName) !== -1) {\r\n                return;\r\n            }\r\n\r\n            state._emitUniformFromString(this._associatedVariableName, this.type);\r\n\r\n            if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                this._prefix = \"uniforms.\";\r\n            }\r\n\r\n            // well known\r\n            const hints = state.sharedData.hints;\r\n            if (this._systemValue !== null && this._systemValue !== undefined) {\r\n                switch (this._systemValue) {\r\n                    case NodeMaterialSystemValues.WorldView:\r\n                        hints.needWorldViewMatrix = true;\r\n                        break;\r\n                    case NodeMaterialSystemValues.WorldViewProjection:\r\n                        hints.needWorldViewProjectionMatrix = true;\r\n                        break;\r\n                }\r\n            } else {\r\n                if (this._animationType !== AnimatedInputBlockTypes.None) {\r\n                    state.sharedData.animatedInputs.push(this);\r\n                }\r\n            }\r\n\r\n            return;\r\n        }\r\n\r\n        // Attribute\r\n        if (this.isAttribute) {\r\n            this.associatedVariableName = remapAttributeName[this.name] ?? this.name;\r\n\r\n            if (this.name === \"particle_positionw\") {\r\n                state.sharedData.defines[\"POSITIONW_AS_VARYING\"] = \"true\";\r\n            }\r\n            if (this.target === NodeMaterialBlockTargets.Vertex && state._vertexState) {\r\n                // Attribute for fragment need to be carried over by varyings\r\n                if (attributeInFragmentOnly[this.name]) {\r\n                    if (attributeAsUniform[this.name]) {\r\n                        state._emitUniformFromString(this.declarationVariableName, this.type);\r\n                        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                            this._prefix = `vertexInputs.`;\r\n                        }\r\n                    } else {\r\n                        state._emitVaryingFromString(this.declarationVariableName, this.type);\r\n                    }\r\n                } else {\r\n                    this._emit(state._vertexState);\r\n                }\r\n                return;\r\n            }\r\n\r\n            const alreadyDeclared = state.attributes.indexOf(this.declarationVariableName) !== -1;\r\n\r\n            if (!alreadyDeclared) {\r\n                state.attributes.push(this.declarationVariableName);\r\n            }\r\n\r\n            if (attributeInFragmentOnly[this.name]) {\r\n                if (attributeAsUniform[this.name]) {\r\n                    if (!alreadyDeclared) {\r\n                        state._emitUniformFromString(this.declarationVariableName, this.type);\r\n                    }\r\n                    if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                        this._prefix = `uniforms.`;\r\n                    }\r\n                } else {\r\n                    if (!alreadyDeclared) {\r\n                        state._emitVaryingFromString(this.declarationVariableName, this.type);\r\n                    }\r\n                    if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                        this._prefix = `fragmentInputs.`;\r\n                    }\r\n                }\r\n            } else {\r\n                if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                    if (!alreadyDeclared) {\r\n                        const defineName = attributeDefine[this.name];\r\n                        if (defineName) {\r\n                            state._attributeDeclaration += this._emitDefine(defineName);\r\n                            state._attributeDeclaration += `attribute ${this.declarationVariableName}: ${state._getShaderType(this.type)};\\n`;\r\n                            state._attributeDeclaration += `#else\\n`;\r\n                            state._attributeDeclaration += `var<private> ${this.declarationVariableName}: ${state._getShaderType(this.type)} = ${state._getShaderType(this.type)}(0.);\\n`;\r\n                            state._attributeDeclaration += `#endif\\n`;\r\n                        } else {\r\n                            state._attributeDeclaration += `attribute ${this.declarationVariableName}: ${state._getShaderType(this.type)};\\n`;\r\n                        }\r\n                    }\r\n                    this._prefix = `vertexInputs.`;\r\n                } else {\r\n                    if (!alreadyDeclared) {\r\n                        const defineName = attributeDefine[this.name];\r\n                        if (defineName) {\r\n                            state._attributeDeclaration += this._emitDefine(defineName);\r\n                            state._attributeDeclaration += `attribute ${state._getShaderType(this.type)} ${this.declarationVariableName};\\n`;\r\n                            state._attributeDeclaration += `#else\\n`;\r\n                            state._attributeDeclaration += `${state._getShaderType(this.type)} ${this.declarationVariableName} = ${state._getShaderType(this.type)}(0.);\\n`;\r\n                            state._attributeDeclaration += `#endif\\n`;\r\n                        } else {\r\n                            state._attributeDeclaration += `attribute ${state._getShaderType(this.type)} ${this.declarationVariableName};\\n`;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _transmitWorld(effect: Effect, world: Matrix, worldView: Matrix, worldViewProjection: Matrix) {\r\n        if (!this._systemValue) {\r\n            return;\r\n        }\r\n\r\n        const variableName = this._associatedVariableName;\r\n        switch (this._systemValue) {\r\n            case NodeMaterialSystemValues.World:\r\n                effect.setMatrix(variableName, world);\r\n                break;\r\n            case NodeMaterialSystemValues.WorldView:\r\n                effect.setMatrix(variableName, worldView);\r\n                break;\r\n            case NodeMaterialSystemValues.WorldViewProjection:\r\n                effect.setMatrix(variableName, worldViewProjection);\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _transmit(effect: Effect, scene: Scene, material: NodeMaterial) {\r\n        if (this.isAttribute) {\r\n            return;\r\n        }\r\n\r\n        const variableName = this._associatedVariableName;\r\n        if (this._systemValue) {\r\n            switch (this._systemValue) {\r\n                case NodeMaterialSystemValues.World:\r\n                case NodeMaterialSystemValues.WorldView:\r\n                case NodeMaterialSystemValues.WorldViewProjection:\r\n                    return;\r\n                case NodeMaterialSystemValues.View:\r\n                    effect.setMatrix(variableName, scene.getViewMatrix());\r\n                    break;\r\n                case NodeMaterialSystemValues.Projection:\r\n                    effect.setMatrix(variableName, scene.getProjectionMatrix());\r\n                    break;\r\n                case NodeMaterialSystemValues.ProjectionInverse: {\r\n                    const projectionMatrix = scene.getProjectionMatrix();\r\n                    projectionMatrix.invertToRef(TmpVectors.Matrix[0]);\r\n                    effect.setMatrix(variableName, TmpVectors.Matrix[0]);\r\n                    break;\r\n                }\r\n                case NodeMaterialSystemValues.ViewProjection:\r\n                    effect.setMatrix(variableName, scene.getTransformMatrix());\r\n                    break;\r\n                case NodeMaterialSystemValues.CameraPosition:\r\n                    scene.bindEyePosition(effect, variableName, true);\r\n                    break;\r\n                case NodeMaterialSystemValues.CameraForward:\r\n                    if (scene.activeCamera) {\r\n                        const transform = scene.activeCamera.getWorldMatrix();\r\n                        const forward = TmpVectors.Vector3[2];\r\n                        forward.set(0, 0, scene.useRightHandedSystem ? -1 : 1);\r\n                        const worldForward = new Vector3();\r\n                        Vector3.TransformNormalToRef(forward, transform, worldForward);\r\n                        worldForward.normalize();\r\n\r\n                        effect.setVector3(variableName, worldForward);\r\n                    }\r\n                    break;\r\n                case NodeMaterialSystemValues.FogColor:\r\n                    effect.setColor3(variableName, scene.fogColor);\r\n                    break;\r\n                case NodeMaterialSystemValues.DeltaTime:\r\n                    effect.setFloat(variableName, scene.deltaTime / 1000.0);\r\n                    break;\r\n                case NodeMaterialSystemValues.CameraParameters:\r\n                    if (scene.activeCamera) {\r\n                        effect.setFloat4(\r\n                            variableName,\r\n                            scene.getEngine().hasOriginBottomLeft ? -1 : 1,\r\n                            scene.activeCamera.minZ,\r\n                            scene.activeCamera.maxZ,\r\n                            1 / scene.activeCamera.maxZ\r\n                        );\r\n                    }\r\n                    break;\r\n                case NodeMaterialSystemValues.MaterialAlpha:\r\n                    effect.setFloat(variableName, material.alpha);\r\n                    break;\r\n            }\r\n            return;\r\n        }\r\n\r\n        const value = this._valueCallback ? this._valueCallback() : this._storedValue;\r\n\r\n        if (value === null) {\r\n            return;\r\n        }\r\n\r\n        switch (this.type) {\r\n            case NodeMaterialBlockConnectionPointTypes.Float:\r\n                effect.setFloat(variableName, value);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Int:\r\n                effect.setInt(variableName, value);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Color3:\r\n                TmpColors.Color3[0].set(this.value.r, this.value.g, this.value.b);\r\n                if (this.convertToGammaSpace) {\r\n                    TmpColors.Color3[0].toGammaSpaceToRef(TmpColors.Color3[0], scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                if (this.convertToLinearSpace) {\r\n                    TmpColors.Color3[0].toLinearSpaceToRef(TmpColors.Color3[0], scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                effect.setColor3(variableName, TmpColors.Color3[0]);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Color4:\r\n                TmpColors.Color4[0].set(this.value.r, this.value.g, this.value.b, this.value.a);\r\n                if (this.convertToGammaSpace) {\r\n                    TmpColors.Color4[0].toGammaSpaceToRef(TmpColors.Color4[0], scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                if (this.convertToLinearSpace) {\r\n                    TmpColors.Color4[0].toLinearSpaceToRef(TmpColors.Color4[0], scene.getEngine().useExactSrgbConversions);\r\n                }\r\n                effect.setDirectColor4(variableName, TmpColors.Color4[0]);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                effect.setVector2(variableName, value);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                effect.setVector3(variableName, value);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                effect.setVector4(variableName, value);\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Matrix:\r\n                effect.setMatrix(variableName, value);\r\n                break;\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (this.isUniform || this.isSystemValue) {\r\n            state.sharedData.inputBlocks.push(this);\r\n        }\r\n\r\n        this._emit(state);\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const variableName = this._codeVariableName;\r\n\r\n        if (this.isAttribute) {\r\n            return super._dumpPropertiesCode() + `${variableName}.setAsAttribute(\"${this.name}\");\\n`;\r\n        }\r\n        if (this.isSystemValue) {\r\n            return super._dumpPropertiesCode() + `${variableName}.setAsSystemValue(BABYLON.NodeMaterialSystemValues.${NodeMaterialSystemValues[this._systemValue!]});\\n`;\r\n        }\r\n        if (this.isUniform) {\r\n            const codes: string[] = [];\r\n\r\n            let valueString = \"\";\r\n\r\n            switch (this.type) {\r\n                case NodeMaterialBlockConnectionPointTypes.Float:\r\n                    valueString = `${this.value}`;\r\n                    break;\r\n                case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                    valueString = `new BABYLON.Vector2(${this.value.x}, ${this.value.y})`;\r\n                    break;\r\n                case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                    valueString = `new BABYLON.Vector3(${this.value.x}, ${this.value.y}, ${this.value.z})`;\r\n                    break;\r\n                case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                    valueString = `new BABYLON.Vector4(${this.value.x}, ${this.value.y}, ${this.value.z}, ${this.value.w})`;\r\n                    break;\r\n                case NodeMaterialBlockConnectionPointTypes.Color3:\r\n                    valueString = `new BABYLON.Color3(${this.value.r}, ${this.value.g}, ${this.value.b})`;\r\n                    if (this.convertToGammaSpace) {\r\n                        valueString += \".toGammaSpace()\";\r\n                    }\r\n                    if (this.convertToLinearSpace) {\r\n                        valueString += \".toLinearSpace()\";\r\n                    }\r\n                    break;\r\n                case NodeMaterialBlockConnectionPointTypes.Color4:\r\n                    valueString = `new BABYLON.Color4(${this.value.r}, ${this.value.g}, ${this.value.b}, ${this.value.a})`;\r\n                    if (this.convertToGammaSpace) {\r\n                        valueString += \".toGammaSpace()\";\r\n                    }\r\n                    if (this.convertToLinearSpace) {\r\n                        valueString += \".toLinearSpace()\";\r\n                    }\r\n                    break;\r\n                case NodeMaterialBlockConnectionPointTypes.Matrix:\r\n                    valueString = `BABYLON.Matrix.FromArray([${(this.value as Matrix).m.join(\", \")}])`;\r\n                    break;\r\n            }\r\n\r\n            // Common Property \"Value\"\r\n            codes.push(`${variableName}.value = ${valueString}`);\r\n\r\n            // Float-Value-Specific Properties\r\n            if (this.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n                codes.push(\r\n                    `${variableName}.min = ${this.min}`,\r\n                    `${variableName}.max = ${this.max}`,\r\n                    `${variableName}.isBoolean = ${this.isBoolean}`,\r\n                    `${variableName}.matrixMode = ${this.matrixMode}`,\r\n                    `${variableName}.animationType = BABYLON.AnimatedInputBlockTypes.${AnimatedInputBlockTypes[this.animationType]}`\r\n                );\r\n            }\r\n\r\n            // Common Property \"Type\"\r\n            codes.push(`${variableName}.isConstant = ${this.isConstant}`);\r\n\r\n            codes.push(\"\");\r\n\r\n            return super._dumpPropertiesCode() + codes.join(\";\\n\");\r\n        }\r\n        return super._dumpPropertiesCode();\r\n    }\r\n\r\n    /**\r\n     * Releases the resources held by the block\r\n     */\r\n    public override dispose() {\r\n        this.onValueChangedObservable.clear();\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.type = this.type;\r\n        serializationObject.mode = this._mode;\r\n        serializationObject.systemValue = this._systemValue;\r\n        serializationObject.animationType = this._animationType;\r\n        serializationObject.min = this.min;\r\n        serializationObject.max = this.max;\r\n        serializationObject.isBoolean = this.isBoolean;\r\n        serializationObject.matrixMode = this.matrixMode;\r\n        serializationObject.isConstant = this.isConstant;\r\n        serializationObject.groupInInspector = this.groupInInspector;\r\n        serializationObject.convertToGammaSpace = this.convertToGammaSpace;\r\n        serializationObject.convertToLinearSpace = this.convertToLinearSpace;\r\n\r\n        if (this._storedValue != null && this._mode === NodeMaterialBlockConnectionPointMode.Uniform) {\r\n            if (this._storedValue.asArray) {\r\n                serializationObject.valueType = \"BABYLON.\" + this._storedValue.getClassName();\r\n                serializationObject.value = this._storedValue.asArray();\r\n            } else {\r\n                serializationObject.valueType = \"number\";\r\n                serializationObject.value = this._storedValue;\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - defines the serialized object\r\n     * @param scene - defines the scene\r\n     * @param rootUrl - defines the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        this._mode = serializationObject.mode;\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this._type = serializationObject.type;\r\n\r\n        this._systemValue = serializationObject.systemValue || serializationObject.wellKnownValue;\r\n        this._animationType = serializationObject.animationType;\r\n        this.min = serializationObject.min || 0;\r\n        this.max = serializationObject.max || 0;\r\n        this.isBoolean = !!serializationObject.isBoolean;\r\n        this.matrixMode = serializationObject.matrixMode || 0;\r\n        this.isConstant = !!serializationObject.isConstant;\r\n        this.groupInInspector = serializationObject.groupInInspector || \"\";\r\n        this.convertToGammaSpace = !!serializationObject.convertToGammaSpace;\r\n        this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;\r\n\r\n        // Tangents back compat\r\n        if (\r\n            serializationObject.name === \"tangent\" &&\r\n            serializationObject.mode === NodeMaterialBlockConnectionPointMode.Attribute &&\r\n            serializationObject.type === NodeMaterialBlockConnectionPointTypes.Vector3\r\n        ) {\r\n            this._type = NodeMaterialBlockConnectionPointTypes.Vector4;\r\n        }\r\n\r\n        if (!serializationObject.valueType) {\r\n            return;\r\n        }\r\n\r\n        if (serializationObject.valueType === \"number\") {\r\n            this._storedValue = serializationObject.value;\r\n        } else {\r\n            const valueType = GetClass(serializationObject.valueType);\r\n\r\n            if (valueType) {\r\n                this._storedValue = valueType.FromArray(serializationObject.value);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialsNodeBlocksInputInputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialsNodeBlocksInputInputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InputBlock\", InputBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get the screen sizes\r\n */\r\nexport class ScreenSizeBlock extends NodeMaterialBlock {\r\n    private _varName: string;\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Name of the variable in the shader that holds the screen size\r\n     */\r\n    public get associatedVariableName(): string {\r\n        return this._varName;\r\n    }\r\n\r\n    /**\r\n     * Creates a new ScreenSizeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"xy\", NodeMaterialBlockConnectionPointTypes.Vector2, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"x\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"y\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ScreenSizeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component\r\n     */\r\n    public get xy(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - defines the effect to bind data to\r\n     */\r\n    public override bind(effect: Effect) {\r\n        const engine = this._scene.getEngine();\r\n\r\n        effect.setFloat2(this._varName, engine.getRenderWidth(), engine.getRenderHeight());\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected writeOutputs(state: NodeMaterialBuildState, varName: string): string {\r\n        let code = \"\";\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                code += `${state._declareOutput(output)} = ${varName}.${output.name};\\n`;\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._scene = state.sharedData.scene;\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            state.sharedData.raiseBuildError(\"ScreenSizeBlock must only be used in a fragment shader\");\r\n            return this;\r\n        }\r\n\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        this._varName = state._getFreeVariableName(\"screenSize\");\r\n        state._emitUniformFromString(this._varName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        const prefix = state.shaderLanguage === ShaderLanguage.WGSL ? \"uniforms.\" : \"\";\r\n        state.compilationString += this.writeOutputs(state, prefix + this._varName);\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for screenSizeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScreenSizeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ScreenSizeBlock\", ScreenSizeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { FragmentOutputBlock } from \"./fragmentOutputBlock.pure\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialModes } from \"../../Enums/nodeMaterialModes\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { ScreenSizeBlock } from \"../Fragment/screenSizeBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/** @internal */\r\nexport const SfeModeDefine = \"USE_SFE_FRAMEWORK\";\r\n\r\n/**\r\n * Block used to output the final color with Smart Filters structural support.\r\n */\r\nexport class SmartFilterFragmentOutputBlock extends FragmentOutputBlock {\r\n    /**\r\n     * Create a new SmartFilterFragmentOutputBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SmartFilterFragmentOutputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        super.initialize(state);\r\n\r\n        if (state.sharedData.nodeMaterial.mode !== NodeMaterialModes.SFE) {\r\n            state.sharedData.raiseBuildError(\"SmartFilterFragmentOutputBlock should not be used outside of SFE mode.\");\r\n        }\r\n\r\n        if (state.sharedData.nodeMaterial.shaderLanguage !== ShaderLanguage.GLSL) {\r\n            state.sharedData.raiseBuildError(\"WebGPU is not supported in SmartFilters mode.\");\r\n        }\r\n\r\n        // Annotate uniforms of InputBlocks and bindable blocks with their current values\r\n        if (!state.sharedData.formatConfig.getUniformAnnotation) {\r\n            state.sharedData.formatConfig.getUniformAnnotation = (name: string) => {\r\n                for (const block of state.sharedData.nodeMaterial.attachedBlocks) {\r\n                    if (block instanceof InputBlock && block.isUniform && block.associatedVariableName === name) {\r\n                        return this._generateInputBlockAnnotation(block);\r\n                    }\r\n                    if (block instanceof ScreenSizeBlock && block.associatedVariableName === name) {\r\n                        return this._generateScreenSizeBlockAnnotation();\r\n                    }\r\n                }\r\n                return \"\";\r\n            };\r\n        }\r\n\r\n        // Do our best to clean up variable names, as they will be used as display names.\r\n        state.sharedData.formatConfig.formatVariablename = (n: string) => {\r\n            let name = n;\r\n\r\n            const hasUnderscoredPrefix = name.length > 1 && name[1] === \"_\";\r\n            if (hasUnderscoredPrefix) {\r\n                name = name.substring(2);\r\n            }\r\n\r\n            return name.replace(/[^a-zA-Z]+/g, \"\");\r\n        };\r\n    }\r\n\r\n    private _generateInputBlockAnnotation(inputBlock: InputBlock): string {\r\n        const value = inputBlock.valueCallback ? inputBlock.valueCallback() : inputBlock.value;\r\n        return `// { \"default\": ${JSON.stringify(value)} }\\n`;\r\n    }\r\n\r\n    private _generateScreenSizeBlockAnnotation(): string {\r\n        return `// { \"autoBind\": \"outputResolution\" }\\n`;\r\n    }\r\n\r\n    private _getMainUvName(state: NodeMaterialBuildState): string {\r\n        // Get the ScreenUVBlock's name, which is required for SFE and should be vUV.\r\n        // NOTE: In the future, when we move to vertex shaders, update this to check for the nearest vec2 varying output.\r\n        const screenUv = state.sharedData.nodeMaterial.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"postprocess_uv\");\r\n        if (!screenUv || !screenUv.isAnAncestorOf(this)) {\r\n            return \"\";\r\n        }\r\n        return screenUv.associatedVariableName;\r\n    }\r\n\r\n    protected override _getOutputString(): string {\r\n        return \"outColor\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const outputString = this._getOutputString();\r\n\r\n        state._customEntryHeader += `#ifdef ${SfeModeDefine}\\n`;\r\n        state._customEntryHeader += `vec4 nmeMain(vec2 ${this._getMainUvName(state)}) { // main\\n`;\r\n        state._customEntryHeader += `#else\\n`;\r\n        state._customEntryHeader += `void main(void) {\\n`;\r\n        state._customEntryHeader += `#endif\\n`;\r\n        state._customEntryHeader += `vec4 ${outputString} = vec4(0.0);\\n`;\r\n\r\n        state.compilationString += `\\n#ifndef ${SfeModeDefine}\\n`;\r\n        state.compilationString += `gl_FragColor = ${outputString};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += `return ${outputString};\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for smartFilterFragmentOutputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSmartFilterFragmentOutputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SmartFilterFragmentOutputBlock\", SmartFilterFragmentOutputBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { type InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../nodeMaterial.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to transform a vector (2, 3 or 4) with a matrix. It will generate a Vector4\r\n */\r\nexport class TransformBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Defines the value to use to complement W value to transform it to a Vector4\r\n     */\r\n    public complementW = 1;\r\n\r\n    /**\r\n     * Defines the value to use to complement z value to transform it to a Vector4\r\n     */\r\n    public complementZ = 0;\r\n\r\n    /**\r\n     * Boolean indicating if the transformation is made for a direction vector and not a position vector\r\n     * If set to true the complementW value will be set to 0 else it will be set to 1\r\n     */\r\n    @editableInPropertyPage(\"Transform as direction\", PropertyTypeForEdition.Boolean, undefined, { embedded: true })\r\n    public get transformAsDirection() {\r\n        return this.complementW === 0;\r\n    }\r\n\r\n    public set transformAsDirection(value: boolean) {\r\n        this.complementW = value ? 0 : 1;\r\n    }\r\n\r\n    /**\r\n     * Creates a new TransformBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.target = NodeMaterialBlockTargets.Vertex;\r\n\r\n        this.registerInput(\"vector\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"transform\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"xyz\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._inputs[0].onConnectionObservable.add((other) => {\r\n            if (other.ownerBlock.isInput) {\r\n                const otherAsInput = other.ownerBlock as InputBlock;\r\n\r\n                if (otherAsInput.name === \"normal\" || otherAsInput.name === \"tangent\") {\r\n                    this.complementW = 0;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TransformBlock\";\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the vector input\r\n     */\r\n    public get vector(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz output component\r\n     */\r\n    public get xyz(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix transform input\r\n     */\r\n    public get transform(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const vector = this.vector;\r\n        const transform = this.transform;\r\n\r\n        const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        const vec3 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        if (vector.connectedPoint) {\r\n            // None uniform scaling case.\r\n            if (this.complementW === 0 || this.transformAsDirection) {\r\n                const comments = `//${this.name}`;\r\n                state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n                state.sharedData.blocksWithDefines.push(this);\r\n\r\n                const transformName = state._getFreeVariableName(`${transform.associatedVariableName}_NUS`);\r\n                if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                    state.compilationString += `var ${transformName}: mat3x3f = mat3x3f(${transform.associatedVariableName}[0].xyz, ${transform.associatedVariableName}[1].xyz, ${transform.associatedVariableName}[2].xyz);\\n`;\r\n                } else {\r\n                    state.compilationString += `mat3 ${transformName} = mat3(${transform.associatedVariableName});\\n`;\r\n                }\r\n                state.compilationString += `#ifdef NONUNIFORMSCALING\\n`;\r\n                state.compilationString += `${transformName} = transposeMat3(inverseMat3(${transformName}));\\n`;\r\n                state.compilationString += `#endif\\n`;\r\n                switch (vector.connectedPoint.type) {\r\n                    case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                        state.compilationString +=\r\n                            state._declareOutput(this.output) +\r\n                            ` = ${vec4}(${transformName} * ${vec3}(${vector.associatedVariableName}, ${this._writeFloat(this.complementZ)}), ${this._writeFloat(this.complementW)});\\n`;\r\n                        break;\r\n                    case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                    case NodeMaterialBlockConnectionPointTypes.Color3:\r\n                        state.compilationString +=\r\n                            state._declareOutput(this.output) + ` = ${vec4}(${transformName} * ${vector.associatedVariableName}, ${this._writeFloat(this.complementW)});\\n`;\r\n                        break;\r\n                    default:\r\n                        state.compilationString +=\r\n                            state._declareOutput(this.output) + ` = ${vec4}(${transformName} * ${vector.associatedVariableName}.xyz, ${this._writeFloat(this.complementW)});\\n`;\r\n                        break;\r\n                }\r\n            } else {\r\n                const transformName = transform.associatedVariableName;\r\n                switch (vector.connectedPoint.type) {\r\n                    case NodeMaterialBlockConnectionPointTypes.Vector2:\r\n                        state.compilationString +=\r\n                            state._declareOutput(this.output) +\r\n                            ` = ${transformName} * ${vec4}(${vector.associatedVariableName}, ${this._writeFloat(this.complementZ)}, ${this._writeFloat(this.complementW)});\\n`;\r\n                        break;\r\n                    case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                    case NodeMaterialBlockConnectionPointTypes.Color3:\r\n                        state.compilationString +=\r\n                            state._declareOutput(this.output) + ` = ${transformName} * ${vec4}(${vector.associatedVariableName}, ${this._writeFloat(this.complementW)});\\n`;\r\n                        break;\r\n                    default:\r\n                        state.compilationString += state._declareOutput(this.output) + ` = ${transformName} * ${vector.associatedVariableName};\\n`;\r\n                        break;\r\n                }\r\n            }\r\n\r\n            if (this.xyz.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(this.xyz) + ` = ${this.output.associatedVariableName}.xyz;\\n`;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Update defines for shader compilation\r\n     * @param defines defines the material defines to update\r\n     * @param nodeMaterial defines the node material requesting the update\r\n     * @param mesh defines the mesh to be rendered\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (mesh && mesh.nonUniformScaling) {\r\n            defines.setValue(\"NONUNIFORMSCALING\", true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.complementZ = this.complementZ;\r\n        serializationObject.complementW = this.complementW;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.complementZ = serializationObject.complementZ !== undefined ? serializationObject.complementZ : 0.0;\r\n        this.complementW = serializationObject.complementW !== undefined ? serializationObject.complementW : 1.0;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.complementZ = ${this.complementZ};\\n`;\r\n\r\n        codeString += `${this._codeVariableName}.complementW = ${this.complementW};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for transformBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTransformBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TransformBlock\", TransformBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type Immutable } from \"../../../../types\";\r\n\r\nimport { type FragmentOutputBlock } from \"../Fragment/fragmentOutputBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to output the vertex position\r\n */\r\nexport class VertexOutputBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new VertexOutputBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex, true);\r\n\r\n        this.registerInput(\"vector\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"VertexOutputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the vector input component\r\n     */\r\n    public get vector(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    private _isLogarithmicDepthEnabled(nodeList: Immutable<NodeMaterialBlock[]>, useLogarithmicDepth: boolean): boolean {\r\n        if (useLogarithmicDepth) {\r\n            return true;\r\n        }\r\n\r\n        for (const node of nodeList) {\r\n            if ((node as FragmentOutputBlock).useLogarithmicDepth) {\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const input = this.vector;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            state.compilationString += `vertexOutputs.position = ${input.associatedVariableName};\\n`;\r\n        } else {\r\n            state.compilationString += `gl_Position = ${input.associatedVariableName};\\n`;\r\n        }\r\n\r\n        // TODOWGSL\r\n        if (this._isLogarithmicDepthEnabled(state.sharedData.fragmentOutputNodes, state.sharedData.nodeMaterial.useLogarithmicDepth)) {\r\n            state._emitUniformFromString(\"logarithmicDepthConstant\", NodeMaterialBlockConnectionPointTypes.Float);\r\n            state._emitVaryingFromString(\"vFragmentDepth\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n            const fragDepth = isWebGPU ? \"vertexOutputs.vFragmentDepth\" : \"vFragmentDepth\";\r\n            const uniformP = isWebGPU ? \"uniforms.\" : \"\";\r\n            const position = isWebGPU ? \"vertexOutputs.position\" : \"gl_Position\";\r\n\r\n            state.compilationString += `${fragDepth} = 1.0 + ${position}.w;\\n`;\r\n            state.compilationString += `${position}.z = log2(max(0.000001, ${fragDepth})) * ${uniformP}logarithmicDepthConstant;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vertexOutputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVertexOutputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.VertexOutputBlock\", VertexOutputBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Base block used as input for post process\r\n */\r\nexport class CurrentScreenBlock extends NodeMaterialBlock {\r\n    protected _samplerName = \"textureSampler\";\r\n    protected _linearDefineName: string;\r\n    protected _gammaDefineName: string;\r\n    protected _mainUVName: string;\r\n    protected _tempTextureRead: string;\r\n    protected _texture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * The name of the sampler to read the screen texture from.\r\n     */\r\n    public get samplerName(): string {\r\n        return this._samplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public get texture(): Nullable<BaseTexture> {\r\n        return this._texture;\r\n    }\r\n    public set texture(value: Nullable<BaseTexture>) {\r\n        this._texture = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to gamma space\r\n     */\r\n    public convertToGammaSpace = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to linear space\r\n     */\r\n    public convertToLinearSpace = false;\r\n\r\n    /**\r\n     * Create a new CurrentScreenBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this._isUnique = false;\r\n\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"r\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"g\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"b\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector2 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n\r\n        this._inputs[0]._prioritizeVertex = false;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CurrentScreenBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba output component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb output component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the r output component\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the g output component\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the b output component\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the a output component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(this.samplerName);\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get target() {\r\n        if (!this.uv.isConnected) {\r\n            return NodeMaterialBlockTargets.VertexAndFragment;\r\n        }\r\n\r\n        if (this.uv.sourceBlock!.isInput) {\r\n            return NodeMaterialBlockTargets.VertexAndFragment;\r\n        }\r\n\r\n        return NodeMaterialBlockTargets.Fragment;\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        defines.setValue(this._linearDefineName, this.convertToGammaSpace, true);\r\n        defines.setValue(this._gammaDefineName, this.convertToLinearSpace, true);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        if (this.texture && !this.texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    protected _getMainUvName(_state: NodeMaterialBuildState): string {\r\n        return \"vMain\" + this.uv.associatedVariableName;\r\n    }\r\n\r\n    protected _injectVertexCode(state: NodeMaterialBuildState) {\r\n        const uvInput = this.uv;\r\n\r\n        if (uvInput.connectedPoint!.ownerBlock.isInput) {\r\n            const uvInputOwnerBlock = uvInput.connectedPoint!.ownerBlock as InputBlock;\r\n\r\n            if (!uvInputOwnerBlock.isAttribute) {\r\n                state._emitUniformFromString(uvInput.associatedVariableName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n            }\r\n        }\r\n\r\n        state.compilationString += `${this._mainUVName} = ${uvInput.associatedVariableName}.xy;\\n`;\r\n\r\n        if (!this._outputs.some((o) => o.isConnectedInVertexShader)) {\r\n            return;\r\n        }\r\n\r\n        this._writeTextureRead(state, true);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                this._writeOutput(state, output, output.name, true);\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _writeTextureRead(state: NodeMaterialBuildState, vertexMode = false) {\r\n        const uvInput = this.uv;\r\n\r\n        if (vertexMode) {\r\n            if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n                return;\r\n            }\r\n            const textureReadFunc =\r\n                state.shaderLanguage === ShaderLanguage.GLSL\r\n                    ? `texture2D(${this.samplerName},`\r\n                    : `textureSampleLevel(${this.samplerName}, ${this.samplerName + Constants.AUTOSAMPLERSUFFIX},`;\r\n\r\n            const complement = state.shaderLanguage === ShaderLanguage.GLSL ? \"\" : \", 0\";\r\n\r\n            state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${textureReadFunc} ${uvInput.associatedVariableName}${complement});\\n`;\r\n            return;\r\n        }\r\n\r\n        const textureReadFunc =\r\n            state.shaderLanguage === ShaderLanguage.GLSL\r\n                ? `texture2D(${this.samplerName},`\r\n                : `textureSample(${this.samplerName}, ${this.samplerName + Constants.AUTOSAMPLERSUFFIX},`;\r\n\r\n        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${textureReadFunc} ${uvInput.associatedVariableName});\\n`;\r\n            return;\r\n        }\r\n\r\n        state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${textureReadFunc} ${this._mainUVName});\\n`;\r\n    }\r\n\r\n    protected _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string, vertexMode = false) {\r\n        if (vertexMode) {\r\n            if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n                return;\r\n            }\r\n\r\n            state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n\r\n            return;\r\n        }\r\n\r\n        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n            return;\r\n        }\r\n\r\n        state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n\r\n        state.compilationString += `#ifdef ${this._linearDefineName}\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = toGammaSpace(${output.associatedVariableName});\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        state.compilationString += `#ifdef ${this._gammaDefineName}\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = toLinearSpace(${output.associatedVariableName});\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n    }\r\n\r\n    protected _emitUvAndSampler(state: NodeMaterialBuildState) {\r\n        state._emitVaryingFromString(this._mainUVName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        state._emit2DSampler(this.samplerName);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._tempTextureRead = state._getFreeVariableName(\"tempTextureRead\");\r\n\r\n        if (state.sharedData.blockingBlocks.indexOf(this) < 0) {\r\n            state.sharedData.blockingBlocks.push(this);\r\n        }\r\n        if (state.sharedData.textureBlocks.indexOf(this) < 0) {\r\n            state.sharedData.textureBlocks.push(this);\r\n        }\r\n        if (state.sharedData.blocksWithDefines.indexOf(this) < 0) {\r\n            state.sharedData.blocksWithDefines.push(this);\r\n        }\r\n        this._mainUVName = this._getMainUvName(state);\r\n\r\n        this._emitUvAndSampler(state);\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            // Vertex\r\n            this._injectVertexCode(state);\r\n            return;\r\n        }\r\n\r\n        // Fragment\r\n        if (!this._outputs.some((o) => o.isConnectedInFragmentShader)) {\r\n            return;\r\n        }\r\n\r\n        this._linearDefineName = state._getFreeDefineName(\"ISLINEAR\");\r\n        this._gammaDefineName = state._getFreeDefineName(\"ISGAMMA\");\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n\r\n        this._writeTextureRead(state);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                this._writeOutput(state, output, output.name);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.convertToGammaSpace = this.convertToGammaSpace;\r\n        serializationObject.convertToLinearSpace = this.convertToLinearSpace;\r\n        if (this.texture && !this.texture.isRenderTarget) {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.convertToGammaSpace = serializationObject.convertToGammaSpace;\r\n        this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;\r\n\r\n        if (serializationObject.texture) {\r\n            rootUrl = serializationObject.texture.url.indexOf(\"data:\") === 0 ? \"\" : rootUrl;\r\n            this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl) as Texture;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for currentScreenBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCurrentScreenBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CurrentScreenBlock\", CurrentScreenBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterialDefines, type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Base block used for the particle texture\r\n */\r\nexport class ParticleTextureBlock extends NodeMaterialBlock {\r\n    private _samplerName = \"diffuseSampler\";\r\n    private _linearDefineName: string;\r\n    private _gammaDefineName: string;\r\n    private _tempTextureRead: string;\r\n\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public texture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to gamma space\r\n     */\r\n    public convertToGammaSpace = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to linear space\r\n     */\r\n    public convertToLinearSpace = false;\r\n\r\n    /**\r\n     * Create a new ParticleTextureBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = false;\r\n\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"r\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"g\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"b\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector2 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleTextureBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba output component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb output component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the r output component\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the g output component\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the b output component\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the a output component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"diffuseSampler\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - defines the node material\r\n     * @param additionalFilteringInfo - defines additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.uv.isConnected) {\r\n            let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"particle_uv\" && additionalFilteringInfo(b));\r\n\r\n            if (!uvInput) {\r\n                uvInput = new InputBlock(\"uv\");\r\n                uvInput.setAsAttribute(\"particle_uv\");\r\n            }\r\n            uvInput.output.connectTo(this.uv);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - defines the list of defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        defines.setValue(this._linearDefineName, this.convertToGammaSpace, true);\r\n        defines.setValue(this._gammaDefineName, this.convertToLinearSpace, true);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        if (this.texture && !this.texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string) {\r\n        state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n\r\n        state.compilationString += `#ifdef ${this._linearDefineName}\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = toGammaSpace(${output.associatedVariableName});\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        state.compilationString += `#ifdef ${this._gammaDefineName}\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = toLinearSpace(${output.associatedVariableName});\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            return;\r\n        }\r\n\r\n        this._tempTextureRead = state._getFreeVariableName(\"tempTextureRead\");\r\n\r\n        state._emit2DSampler(this._samplerName);\r\n\r\n        state.sharedData.blockingBlocks.push(this);\r\n        state.sharedData.textureBlocks.push(this);\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        this._linearDefineName = state._getFreeDefineName(\"ISLINEAR\");\r\n        this._gammaDefineName = state._getFreeDefineName(\"ISGAMMA\");\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n\r\n        state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${state._generateTextureSample(this.uv.associatedVariableName, this._samplerName)};\\n`;\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                this._writeOutput(state, output, output.name);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.convertToGammaSpace = this.convertToGammaSpace;\r\n        serializationObject.convertToLinearSpace = this.convertToLinearSpace;\r\n        if (this.texture && !this.texture.isRenderTarget) {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - defines the serialized object\r\n     * @param scene - defines the scene\r\n     * @param rootUrl - defines the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.convertToGammaSpace = serializationObject.convertToGammaSpace;\r\n        this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;\r\n\r\n        if (serializationObject.texture) {\r\n            rootUrl = serializationObject.texture.url.indexOf(\"data:\") === 0 ? \"\" : rootUrl;\r\n            this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl) as Texture;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleTextureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleTextureBlock\", ParticleTextureBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used for the particle ramp gradient section\r\n */\r\nexport class ParticleRampGradientBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ParticleRampGradientBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.Color4, false, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"rampColor\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleRampGradientBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rampColor output component\r\n     */\r\n    public get rampColor(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"remapRanges\");\r\n        state._excludeVariableName(\"rampSampler\");\r\n        state._excludeVariableName(\"baseColor\");\r\n        state._excludeVariableName(\"alpha\");\r\n        state._excludeVariableName(\"remappedColorIndex\");\r\n        state._excludeVariableName(\"rampColor\");\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            return;\r\n        }\r\n\r\n        state._emit2DSampler(\"rampSampler\", \"RAMPGRADIENT\");\r\n        state._emitVaryingFromString(\"remapRanges\", NodeMaterialBlockConnectionPointTypes.Vector4, \"RAMPGRADIENT\");\r\n\r\n        const varyingString = state.shaderLanguage === ShaderLanguage.GLSL ? \"\" : \"fragmentInputs.\";\r\n\r\n        state.compilationString += `\r\n            #ifdef RAMPGRADIENT\r\n                ${state._declareLocalVar(\"baseColor\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this.color.associatedVariableName};\r\n                ${state._declareLocalVar(\"alpha\", NodeMaterialBlockConnectionPointTypes.Float)} = ${this.color.associatedVariableName}.a;\r\n\r\n                ${state._declareLocalVar(\"remappedColorIndex\", NodeMaterialBlockConnectionPointTypes.Float)} = clamp((alpha - ${varyingString}remapRanges.x) / ${varyingString}remapRanges.y, 0.0, 1.0);\r\n\r\n                ${state._declareLocalVar(\"rampColor\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${state._generateTextureSample(\"vec2(1.0 - remappedColorIndex, 0.)\", \"rampSampler\")};\r\n\r\n                // Remapped alpha\r\n                ${state._declareOutput(this.rampColor)} = vec4${state.fSuffix}(baseColor.rgb * rampColor.rgb, clamp((alpha * rampColor.a - ${varyingString}remapRanges.z) / ${varyingString}remapRanges.w, 0.0, 1.0));\r\n            #else\r\n                ${state._declareOutput(this.rampColor)} = ${this.color.associatedVariableName};\r\n            #endif\r\n        `;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleRampGradientBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleRampGradientBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleRampGradientBlock\", ParticleRampGradientBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used for the particle blend multiply section\r\n */\r\nexport class ParticleBlendMultiplyBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ParticleBlendMultiplyBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.Color4, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"alphaTexture\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"alphaColor\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"blendColor\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleBlendMultiplyBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the alphaTexture input component\r\n     */\r\n    public get alphaTexture(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the alphaColor input component\r\n     */\r\n    public get alphaColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the blendColor output component\r\n     */\r\n    public get blendColor(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"sourceAlpha\");\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            return;\r\n        }\r\n\r\n        state.compilationString += `\r\n            #ifdef BLENDMULTIPLYMODE\r\n                ${state._declareOutput(this.blendColor)};\r\n                ${state._declareLocalVar(\"sourceAlpha\", NodeMaterialBlockConnectionPointTypes.Float)}  = ${this.alphaColor.associatedVariableName} * ${this.alphaTexture.associatedVariableName};\r\n                ${this.blendColor.associatedVariableName} = vec4${state.fSuffix}(${this.color.associatedVariableName}.rgb * sourceAlpha + vec3(1.0) * (1.0 - sourceAlpha), ${this.color.associatedVariableName}.a);\r\n            #else\r\n                ${state._declareOutput(this.blendColor)} = ${this.color.associatedVariableName};\r\n            #endif\r\n        `;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleBlendMultiplyBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleBlendMultiplyBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleBlendMultiplyBlock\", ParticleBlendMultiplyBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to create a Vector2/3/4 out of individual inputs (one for each component)\r\n */\r\nexport class VectorMergerBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the swizzle for x (meaning which component to affect to the output.x)\r\n     */\r\n    public xSwizzle: \"x\" | \"y\" | \"z\" | \"w\" = \"x\";\r\n    /**\r\n     * Gets or sets the swizzle for y (meaning which component to affect to the output.y)\r\n     */\r\n    public ySwizzle: \"x\" | \"y\" | \"z\" | \"w\" = \"y\";\r\n    /**\r\n     * Gets or sets the swizzle for z (meaning which component to affect to the output.z)\r\n     */\r\n    public zSwizzle: \"x\" | \"y\" | \"z\" | \"w\" = \"z\";\r\n    /**\r\n     * Gets or sets the swizzle for w (meaning which component to affect to the output.w)\r\n     */\r\n    public wSwizzle: \"x\" | \"y\" | \"z\" | \"w\" = \"w\";\r\n\r\n    /**\r\n     * Create a new VectorMergerBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"xyzw \", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"xyz \", NodeMaterialBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"xy \", NodeMaterialBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"zw \", NodeMaterialBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"x\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"y\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"z\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"w\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n\r\n        this.registerOutput(\"xyzw\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"xyz\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"xy\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"zw\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"VectorMergerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component (input)\r\n     */\r\n    public get xyzwIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (input)\r\n     */\r\n    public get xyzIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (input)\r\n     */\r\n    public get xyIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (input)\r\n     */\r\n    public get zwIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component (input)\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component (input)\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component (input)\r\n     */\r\n    public get z(): NodeMaterialConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component (input)\r\n     */\r\n    public get w(): NodeMaterialConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component (output)\r\n     */\r\n    public get xyzw(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (output)\r\n     */\r\n    public get xyzOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (output)\r\n     */\r\n    public get xyOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (output)\r\n     */\r\n    public get zwOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (output)\r\n     * @deprecated Please use xyOut instead.\r\n     */\r\n    public get xy(): NodeMaterialConnectionPoint {\r\n        return this.xyOut;\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (output)\r\n     * @deprecated Please use xyzOut instead.\r\n     */\r\n    public get xyz(): NodeMaterialConnectionPoint {\r\n        return this.xyzOut;\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"xyzw \") {\r\n            return \"xyzwIn\";\r\n        }\r\n        if (name === \"xyz \") {\r\n            return \"xyzIn\";\r\n        }\r\n        if (name === \"xy \") {\r\n            return \"xyIn\";\r\n        }\r\n        if (name === \"zw \") {\r\n            return \"zwIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    private _buildSwizzle(len: number) {\r\n        const swizzle = this.xSwizzle + this.ySwizzle + this.zSwizzle + this.wSwizzle;\r\n\r\n        return \".\" + swizzle.substring(0, len);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const xInput = this.x;\r\n        const yInput = this.y;\r\n        const zInput = this.z;\r\n        const wInput = this.w;\r\n        const xyInput = this.xyIn;\r\n        const zwInput = this.zwIn;\r\n        const xyzInput = this.xyzIn;\r\n        const xyzwInput = this.xyzwIn;\r\n\r\n        const v4Output = this._outputs[0];\r\n        const v3Output = this._outputs[1];\r\n        const v2Output = this._outputs[2];\r\n        const v2CompOutput = this._outputs[3];\r\n\r\n        const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        const vec3 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        const vec2 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        if (xyzwInput.isConnected) {\r\n            if (v4Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(v4Output) + ` = ${xyzwInput.associatedVariableName}${this._buildSwizzle(4)};\\n`;\r\n            }\r\n\r\n            if (v3Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(v3Output) + ` = ${xyzwInput.associatedVariableName}${this._buildSwizzle(3)};\\n`;\r\n            }\r\n\r\n            if (v2Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(v2Output) + ` = ${xyzwInput.associatedVariableName}${this._buildSwizzle(2)};\\n`;\r\n            }\r\n        } else if (xyzInput.isConnected) {\r\n            if (v4Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(v4Output) +\r\n                    ` = ${vec4}(${xyzInput.associatedVariableName}, ${wInput.isConnected ? this._writeVariable(wInput) : \"0.0\"})${this._buildSwizzle(4)};\\n`;\r\n            }\r\n\r\n            if (v3Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(v3Output) + ` = ${xyzInput.associatedVariableName}${this._buildSwizzle(3)};\\n`;\r\n            }\r\n\r\n            if (v2Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(v2Output) + ` = ${xyzInput.associatedVariableName}${this._buildSwizzle(2)};\\n`;\r\n            }\r\n        } else if (xyInput.isConnected) {\r\n            if (v4Output.hasEndpoints) {\r\n                if (zwInput.isConnected) {\r\n                    state.compilationString +=\r\n                        state._declareOutput(v4Output) + ` = ${vec4}(${xyInput.associatedVariableName}, ${zwInput.associatedVariableName})${this._buildSwizzle(4)};\\n`;\r\n                } else {\r\n                    state.compilationString +=\r\n                        state._declareOutput(v4Output) +\r\n                        ` = ${vec4}(${xyInput.associatedVariableName}, ${zInput.isConnected ? this._writeVariable(zInput) : \"0.0\"}, ${\r\n                            wInput.isConnected ? this._writeVariable(wInput) : \"0.0\"\r\n                        })${this._buildSwizzle(4)};\\n`;\r\n                }\r\n            }\r\n\r\n            if (v3Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(v3Output) +\r\n                    ` = ${vec3}(${xyInput.associatedVariableName}, ${zInput.isConnected ? this._writeVariable(zInput) : \"0.0\"})${this._buildSwizzle(3)};\\n`;\r\n            }\r\n\r\n            if (v2Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(v2Output) + ` = ${xyInput.associatedVariableName}${this._buildSwizzle(2)};\\n`;\r\n            }\r\n\r\n            if (v2CompOutput.hasEndpoints) {\r\n                if (zwInput.isConnected) {\r\n                    state.compilationString += state._declareOutput(v2CompOutput) + ` = ${zwInput.associatedVariableName}${this._buildSwizzle(2)};\\n`;\r\n                } else {\r\n                    state.compilationString +=\r\n                        state._declareOutput(v2CompOutput) +\r\n                        ` = ${vec2}(${zInput.isConnected ? this._writeVariable(zInput) : \"0.0\"}, ${wInput.isConnected ? this._writeVariable(wInput) : \"0.0\"})${this._buildSwizzle(\r\n                            2\r\n                        )};\\n`;\r\n                }\r\n            }\r\n        } else {\r\n            if (v4Output.hasEndpoints) {\r\n                if (zwInput.isConnected) {\r\n                    state.compilationString +=\r\n                        state._declareOutput(v4Output) +\r\n                        ` = ${vec4}(${xInput.isConnected ? this._writeVariable(xInput) : \"0.0\"}, ${yInput.isConnected ? this._writeVariable(yInput) : \"0.0\"}, ${\r\n                            zwInput.associatedVariableName\r\n                        })${this._buildSwizzle(4)};\\n`;\r\n                } else {\r\n                    state.compilationString +=\r\n                        state._declareOutput(v4Output) +\r\n                        ` = ${vec4}(${xInput.isConnected ? this._writeVariable(xInput) : \"0.0\"}, ${yInput.isConnected ? this._writeVariable(yInput) : \"0.0\"}, ${\r\n                            zInput.isConnected ? this._writeVariable(zInput) : \"0.0\"\r\n                        }, ${wInput.isConnected ? this._writeVariable(wInput) : \"0.0\"})${this._buildSwizzle(4)};\\n`;\r\n                }\r\n            }\r\n\r\n            if (v3Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(v3Output) +\r\n                    ` = ${vec3}(${xInput.isConnected ? this._writeVariable(xInput) : \"0.0\"}, ${yInput.isConnected ? this._writeVariable(yInput) : \"0.0\"}, ${\r\n                        zInput.isConnected ? this._writeVariable(zInput) : \"0.0\"\r\n                    })${this._buildSwizzle(3)};\\n`;\r\n            }\r\n\r\n            if (v2Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(v2Output) +\r\n                    ` = ${vec2}(${xInput.isConnected ? this._writeVariable(xInput) : \"0.0\"}, ${yInput.isConnected ? this._writeVariable(yInput) : \"0.0\"})${this._buildSwizzle(2)};\\n`;\r\n            }\r\n\r\n            if (v2CompOutput.hasEndpoints) {\r\n                if (zwInput.isConnected) {\r\n                    state.compilationString += state._declareOutput(v2CompOutput) + ` = ${zwInput.associatedVariableName}${this._buildSwizzle(2)};\\n`;\r\n                } else {\r\n                    state.compilationString +=\r\n                        state._declareOutput(v2CompOutput) +\r\n                        ` = ${vec2}(${zInput.isConnected ? this._writeVariable(zInput) : \"0.0\"}, ${wInput.isConnected ? this._writeVariable(wInput) : \"0.0\"})${this._buildSwizzle(\r\n                            2\r\n                        )};\\n`;\r\n                }\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.xSwizzle = this.xSwizzle;\r\n        serializationObject.ySwizzle = this.ySwizzle;\r\n        serializationObject.zSwizzle = this.zSwizzle;\r\n        serializationObject.wSwizzle = this.wSwizzle;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.xSwizzle = serializationObject.xSwizzle ?? \"x\";\r\n        this.ySwizzle = serializationObject.ySwizzle ?? \"y\";\r\n        this.zSwizzle = serializationObject.zSwizzle ?? \"z\";\r\n        this.wSwizzle = serializationObject.wSwizzle ?? \"w\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n        codeString += `${this._codeVariableName}.xSwizzle = \"${this.xSwizzle}\";\\n`;\r\n        codeString += `${this._codeVariableName}.ySwizzle = \"${this.ySwizzle}\";\\n`;\r\n        codeString += `${this._codeVariableName}.zSwizzle = \"${this.zSwizzle}\";\\n`;\r\n        codeString += `${this._codeVariableName}.wSwizzle = \"${this.wSwizzle}\";\\n`;\r\n\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vectorMergerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVectorMergerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.VectorMergerBlock\", VectorMergerBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { Vector2 } from \"../../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to remap a float from a range to a new one\r\n */\r\nexport class RemapBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the source range\r\n     */\r\n    @editableInPropertyPage(\"From\", PropertyTypeForEdition.Vector2)\r\n    public sourceRange = new Vector2(-1, 1);\r\n\r\n    /**\r\n     * Gets or sets the target range\r\n     */\r\n    @editableInPropertyPage(\"To\", PropertyTypeForEdition.Vector2)\r\n    public targetRange = new Vector2(0, 1);\r\n\r\n    /**\r\n     * Creates a new RemapBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"sourceMin\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"sourceMax\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"targetMin\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"targetMax\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RemapBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the source min input component\r\n     */\r\n    public get sourceMin(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the source max input component\r\n     */\r\n    public get sourceMax(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the target min input component\r\n     */\r\n    public get targetMin(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the target max input component\r\n     */\r\n    public get targetMax(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        const sourceMin = this.sourceMin.isConnected ? this.sourceMin.associatedVariableName : this._writeFloat(this.sourceRange.x);\r\n        const sourceMax = this.sourceMax.isConnected ? this.sourceMax.associatedVariableName : this._writeFloat(this.sourceRange.y);\r\n\r\n        const targetMin = this.targetMin.isConnected ? this.targetMin.associatedVariableName : this._writeFloat(this.targetRange.x);\r\n        const targetMax = this.targetMax.isConnected ? this.targetMax.associatedVariableName : this._writeFloat(this.targetRange.y);\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = ${targetMin} + (${this._inputs[0].associatedVariableName} - ${sourceMin}) * (${targetMax} - ${targetMin}) / (${sourceMax} - ${sourceMin});\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.sourceRange = new BABYLON.Vector2(${this.sourceRange.x}, ${this.sourceRange.y});\\n`;\r\n\r\n        codeString += `${this._codeVariableName}.targetRange = new BABYLON.Vector2(${this.targetRange.x}, ${this.targetRange.y});\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.sourceRange = this.sourceRange.asArray();\r\n        serializationObject.targetRange = this.targetRange.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.sourceRange = Vector2.FromArray(serializationObject.sourceRange);\r\n        this.targetRange = Vector2.FromArray(serializationObject.targetRange);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for remapBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRemapBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RemapBlock\", RemapBlock);\r\n}\r\n","import { type Observer } from \"core/Misc/observable\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\n\r\n/**\r\n * Block used to perform a mathematical operation on 2 values\r\n */\r\nexport class BaseMathBlock extends NodeMaterialBlock {\r\n    private readonly _connectionObservers: Observer<NodeMaterialBlockConnectionPointTypes>[];\r\n\r\n    protected constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = this.left;\r\n        this._linkConnectionTypes(0, 1, true);\r\n\r\n        this.left.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.right.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._connectionObservers = [\r\n            this.left.onTypeChangedObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onTypeChangedObservable.add(() => this._updateInputOutputTypes()),\r\n        ];\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _updateInputOutputTypes() {\r\n        // First update the output type with the initial assumption that we'll base it on the left input.\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        if (this.left.isConnected && this.right.isConnected) {\r\n            // Both inputs are connected, so we need to determine the output type based on the input types.\r\n            if (\r\n                this.left.type === NodeMaterialBlockConnectionPointTypes.Int ||\r\n                (this.left.type === NodeMaterialBlockConnectionPointTypes.Float && this.right.type !== NodeMaterialBlockConnectionPointTypes.Int)\r\n            ) {\r\n                this.output._typeConnectionSource = this.right;\r\n            }\r\n        } else if (this.left.isConnected !== this.right.isConnected) {\r\n            // Only one input is connected, so we need to determine the output type based on the connected input.\r\n            this.output._typeConnectionSource = this.left.isConnected ? this.left : this.right;\r\n        }\r\n\r\n        // Next update the accepted connection point types for the inputs based on the current input connection state.\r\n        if (this.left.isConnected || this.right.isConnected) {\r\n            for (const [first, second] of [\r\n                [this.left, this.right],\r\n                [this.right, this.left],\r\n            ]) {\r\n                // Always allow Ints and Floats.\r\n                first.acceptedConnectionPointTypes = [NodeMaterialBlockConnectionPointTypes.Int, NodeMaterialBlockConnectionPointTypes.Float];\r\n\r\n                if (second.isConnected) {\r\n                    // The same types as the connected input are always allowed.\r\n                    first.acceptedConnectionPointTypes.push(second.type);\r\n\r\n                    // If the other input is a scalar, then we also allow Vector/Color/Matrix types.\r\n                    if (second.type === NodeMaterialBlockConnectionPointTypes.Int || second.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n                        first.acceptedConnectionPointTypes.push(\r\n                            NodeMaterialBlockConnectionPointTypes.Vector2,\r\n                            NodeMaterialBlockConnectionPointTypes.Vector3,\r\n                            NodeMaterialBlockConnectionPointTypes.Vector4,\r\n                            NodeMaterialBlockConnectionPointTypes.Color3,\r\n                            NodeMaterialBlockConnectionPointTypes.Color4,\r\n                            NodeMaterialBlockConnectionPointTypes.Matrix\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        for (const observer of this._connectionObservers) {\r\n            observer.remove();\r\n        }\r\n        this._connectionObservers.length = 0;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { BaseMathBlock } from \"./baseMathBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to multiply 2 values\r\n */\r\nexport class MultiplyBlock extends BaseMathBlock {\r\n    /**\r\n     * Creates a new MultiplyBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MultiplyBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.left.associatedVariableName} * ${this.right.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for multiplyBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMultiplyBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MultiplyBlock\", MultiplyBlock);\r\n}\r\n","import { type Color3, Color4 } from \"../Maths/math.color.pure\";\r\n\r\n/** Interface used by value gradients (color, factor, ...) */\r\nexport interface IValueGradient {\r\n    /**\r\n     * Gets or sets the gradient value (between 0 and 1)\r\n     */\r\n    gradient: number;\r\n}\r\n\r\n/** Class used to store color4 gradient */\r\nexport class ColorGradient implements IValueGradient {\r\n    /**\r\n     * Creates a new color4 gradient\r\n     * @param gradient gets or sets the gradient value (between 0 and 1)\r\n     * @param color1 gets or sets first associated color\r\n     * @param color2 gets or sets first second color\r\n     */\r\n    public constructor(\r\n        /**\r\n         * Gets or sets the gradient value (between 0 and 1)\r\n         */\r\n        public gradient: number,\r\n        /**\r\n         * Gets or sets first associated color\r\n         */\r\n        public color1: Color4,\r\n        /**\r\n         * Gets or sets second associated color\r\n         */\r\n        public color2?: Color4\r\n    ) {}\r\n\r\n    /**\r\n     * Will get a color picked randomly between color1 and color2.\r\n     * If color2 is undefined then color1 will be used\r\n     * @param result defines the target Color4 to store the result in\r\n     */\r\n    public getColorToRef(result: Color4) {\r\n        if (!this.color2) {\r\n            result.copyFrom(this.color1);\r\n            return;\r\n        }\r\n\r\n        Color4.LerpToRef(this.color1, this.color2, Math.random(), result);\r\n    }\r\n}\r\n\r\n/** Class used to store color 3 gradient */\r\nexport class Color3Gradient implements IValueGradient {\r\n    /**\r\n     * Creates a new color3 gradient\r\n     * @param gradient gets or sets the gradient value (between 0 and 1)\r\n     * @param color gets or sets associated color\r\n     */\r\n    public constructor(\r\n        /**\r\n         * Gets or sets the gradient value (between 0 and 1)\r\n         */\r\n        public gradient: number,\r\n        /**\r\n         * Gets or sets the associated color\r\n         */\r\n        public color: Color3\r\n    ) {}\r\n}\r\n\r\n/** Class used to store factor gradient */\r\nexport class FactorGradient implements IValueGradient {\r\n    /**\r\n     * Creates a new factor gradient\r\n     * @param gradient gets or sets the gradient value (between 0 and 1)\r\n     * @param factor1 gets or sets first associated factor\r\n     * @param factor2 gets or sets second associated factor\r\n     */\r\n    public constructor(\r\n        /**\r\n         * Gets or sets the gradient value (between 0 and 1)\r\n         */\r\n        public gradient: number,\r\n        /**\r\n         * Gets or sets first associated factor\r\n         */\r\n        public factor1: number,\r\n        /**\r\n         * Gets or sets second associated factor\r\n         */\r\n        public factor2?: number\r\n    ) {}\r\n\r\n    /**\r\n     * Will get a number picked randomly between factor1 and factor2.\r\n     * If factor2 is undefined then factor1 will be used\r\n     * @returns the picked number\r\n     */\r\n    public getFactor(): number {\r\n        if (this.factor2 === undefined || this.factor2 === this.factor1) {\r\n            return this.factor1;\r\n        }\r\n\r\n        return this.factor1 + (this.factor2 - this.factor1) * Math.random();\r\n    }\r\n}\r\n\r\n/**\r\n * Helper used to simplify some generic gradient tasks\r\n */\r\nexport class GradientHelper {\r\n    /**\r\n     * Gets the current gradient from an array of IValueGradient\r\n     * @param ratio defines the current ratio to get\r\n     * @param gradients defines the array of IValueGradient\r\n     * @param updateFunc defines the callback function used to get the final value from the selected gradients\r\n     */\r\n    public static GetCurrentGradient(ratio: number, gradients: IValueGradient[], updateFunc: (current: IValueGradient, next: IValueGradient, scale: number) => void) {\r\n        // Use last index if over\r\n        if (gradients[0].gradient > ratio) {\r\n            updateFunc(gradients[0], gradients[0], 1.0);\r\n            return;\r\n        }\r\n\r\n        for (let gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {\r\n            const currentGradient = gradients[gradientIndex];\r\n            const nextGradient = gradients[gradientIndex + 1];\r\n\r\n            if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {\r\n                const scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);\r\n                updateFunc(currentGradient, nextGradient, scale);\r\n                return;\r\n            }\r\n        }\r\n\r\n        // Use last index if over\r\n        const lastIndex = gradients.length - 1;\r\n        updateFunc(gradients[lastIndex], gradients[lastIndex], 1.0);\r\n    }\r\n}\r\n","import { type Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Particle } from \"../../Particles/particle\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\nimport { RandomRange } from \"../../Maths/math.scalar.functions\";\r\nimport { DeepCopier } from \"../../Misc/deepCopier\";\r\n/**\r\n * Particle emitter emitting particles from the inside of a box.\r\n * It emits the particles randomly between 2 given directions.\r\n */\r\nexport class BoxParticleEmitter implements IParticleEmitterType {\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     */\r\n    public direction1 = new Vector3(0, 1.0, 0);\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     */\r\n    public direction2 = new Vector3(0, 1.0, 0);\r\n\r\n    /**\r\n     * Minimum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.\r\n     */\r\n    public minEmitBox = new Vector3(-0.5, -0.5, -0.5);\r\n    /**\r\n     * Maximum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.\r\n     */\r\n    public maxEmitBox = new Vector3(0.5, 0.5, 0.5);\r\n\r\n    /**\r\n     * Creates a new instance BoxParticleEmitter\r\n     */\r\n    constructor() {}\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randX = RandomRange(this.direction1.x, this.direction2.x);\r\n        const randY = RandomRange(this.direction1.y, this.direction2.y);\r\n        const randZ = RandomRange(this.direction1.z, this.direction2.z);\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.x = randX;\r\n            directionToUpdate.y = randY;\r\n            directionToUpdate.z = randZ;\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randX = RandomRange(this.minEmitBox.x, this.maxEmitBox.x);\r\n        const randY = RandomRange(this.minEmitBox.y, this.maxEmitBox.y);\r\n        const randZ = RandomRange(this.minEmitBox.z, this.maxEmitBox.z);\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.x = randX;\r\n            positionToUpdate.y = randY;\r\n            positionToUpdate.z = randZ;\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): BoxParticleEmitter {\r\n        const newOne = new BoxParticleEmitter();\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setVector3(\"direction1\", this.direction1);\r\n        uboOrEffect.setVector3(\"direction2\", this.direction2);\r\n        uboOrEffect.setVector3(\"minEmitBox\", this.minEmitBox);\r\n        uboOrEffect.setVector3(\"maxEmitBox\", this.maxEmitBox);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"direction1\", 3);\r\n        ubo.addUniform(\"direction2\", 3);\r\n        ubo.addUniform(\"minEmitBox\", 3);\r\n        ubo.addUniform(\"maxEmitBox\", 3);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"#define BOXEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"BoxParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"BoxParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.direction1 = this.direction1.asArray();\r\n        serializationObject.direction2 = this.direction2.asArray();\r\n        serializationObject.minEmitBox = this.minEmitBox.asArray();\r\n        serializationObject.maxEmitBox = this.maxEmitBox.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        Vector3.FromArrayToRef(serializationObject.direction1, 0, this.direction1);\r\n        Vector3.FromArrayToRef(serializationObject.direction2, 0, this.direction2);\r\n        Vector3.FromArrayToRef(serializationObject.minEmitBox, 0, this.minEmitBox);\r\n        Vector3.FromArrayToRef(serializationObject.maxEmitBox, 0, this.maxEmitBox);\r\n    }\r\n}\r\n","import { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { type Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { RandomRange } from \"../../Maths/math.scalar.functions\";\r\nimport { type Particle } from \"../../Particles/particle\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\n/**\r\n * Particle emitter emitting particles from a point.\r\n * It emits the particles randomly between 2 given directions.\r\n */\r\nexport class PointParticleEmitter implements IParticleEmitterType {\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     */\r\n    public direction1 = new Vector3(0, 1.0, 0);\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     */\r\n    public direction2 = new Vector3(0, 1.0, 0);\r\n\r\n    /**\r\n     * Creates a new instance PointParticleEmitter\r\n     */\r\n    constructor() {}\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randX = RandomRange(this.direction1.x, this.direction2.x);\r\n        const randY = RandomRange(this.direction1.y, this.direction2.y);\r\n        const randZ = RandomRange(this.direction1.z, this.direction2.z);\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFromFloats(randX, randY, randZ);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        if (isLocal) {\r\n            positionToUpdate.copyFromFloats(0, 0, 0);\r\n            return;\r\n        }\r\n        Vector3.TransformCoordinatesFromFloatsToRef(0, 0, 0, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): PointParticleEmitter {\r\n        const newOne = new PointParticleEmitter();\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setVector3(\"direction1\", this.direction1);\r\n        uboOrEffect.setVector3(\"direction2\", this.direction2);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"direction1\", 3);\r\n        ubo.addUniform(\"direction2\", 3);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"#define POINTEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"PointParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"PointParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.direction1 = this.direction1.asArray();\r\n        serializationObject.direction2 = this.direction2.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        Vector3.FromArrayToRef(serializationObject.direction1, 0, this.direction1);\r\n        Vector3.FromArrayToRef(serializationObject.direction2, 0, this.direction2);\r\n    }\r\n}\r\n","import { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { type Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { RandomRange } from \"../../Maths/math.scalar.functions\";\r\nimport { type Particle } from \"../../Particles/particle\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\n/**\r\n * Particle emitter emitting particles from the inside of a hemisphere.\r\n * It emits the particles alongside the hemisphere radius. The emission direction might be randomized.\r\n */\r\nexport class HemisphericParticleEmitter implements IParticleEmitterType {\r\n    /**\r\n     * Creates a new instance HemisphericParticleEmitter\r\n     * @param radius the radius of the emission hemisphere (1 by default)\r\n     * @param radiusRange the range of the emission hemisphere [0-1] 0 Surface only, 1 Entire Radius (1 by default)\r\n     * @param directionRandomizer defines how much to randomize the particle direction [0-1]\r\n     */\r\n    constructor(\r\n        /**\r\n         * [1] The radius of the emission hemisphere.\r\n         */\r\n        public radius = 1,\r\n        /**\r\n         * [1] The range of emission [0-1] 0 Surface only, 1 Entire Radius.\r\n         */\r\n        public radiusRange = 1,\r\n        /**\r\n         * [0] How much to randomize the particle direction [0-1].\r\n         */\r\n        public directionRandomizer = 0\r\n    ) {}\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();\r\n        const randX = RandomRange(0, this.directionRandomizer);\r\n        const randY = RandomRange(0, this.directionRandomizer);\r\n        const randZ = RandomRange(0, this.directionRandomizer);\r\n        direction.x += randX;\r\n        direction.y += randY;\r\n        direction.z += randZ;\r\n        direction.normalize();\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFrom(direction);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randRadius = this.radius - RandomRange(0, this.radius * this.radiusRange);\r\n        const v = RandomRange(0, 1.0);\r\n        const phi = RandomRange(0, 2 * Math.PI);\r\n        const theta = Math.acos(2 * v - 1);\r\n        const randX = randRadius * Math.cos(phi) * Math.sin(theta);\r\n        const randY = randRadius * Math.cos(theta);\r\n        const randZ = randRadius * Math.sin(phi) * Math.sin(theta);\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.copyFromFloats(randX, Math.abs(randY), randZ);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesFromFloatsToRef(randX, Math.abs(randY), randZ, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): HemisphericParticleEmitter {\r\n        const newOne = new HemisphericParticleEmitter(this.radius, this.directionRandomizer);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setFloat(\"radius\", this.radius);\r\n        uboOrEffect.setFloat(\"radiusRange\", this.radiusRange);\r\n        uboOrEffect.setFloat(\"directionRandomizer\", this.directionRandomizer);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"radius\", 1);\r\n        ubo.addUniform(\"radiusRange\", 1);\r\n        ubo.addUniform(\"directionRandomizer\", 1);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"#define HEMISPHERICEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"HemisphericParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"HemisphericParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.radius = this.radius;\r\n        serializationObject.radiusRange = this.radiusRange;\r\n        serializationObject.directionRandomizer = this.directionRandomizer;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        this.radius = serializationObject.radius;\r\n        this.radiusRange = serializationObject.radiusRange;\r\n        this.directionRandomizer = serializationObject.directionRandomizer;\r\n    }\r\n}\r\n","import { type Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { RandomRange } from \"../../Maths/math.scalar.functions\";\r\nimport { type Particle } from \"../../Particles/particle\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\nimport { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\n/**\r\n * Particle emitter emitting particles from the inside of a sphere.\r\n * It emits the particles alongside the sphere radius. The emission direction might be randomized.\r\n */\r\nexport class SphereParticleEmitter implements IParticleEmitterType {\r\n    /**\r\n     * Creates a new instance SphereParticleEmitter\r\n     * @param radius the radius of the emission sphere (1 by default)\r\n     * @param radiusRange the range of the emission sphere [0-1] 0 Surface only, 1 Entire Radius (1 by default)\r\n     * @param directionRandomizer defines how much to randomize the particle direction [0-1]\r\n     */\r\n    constructor(\r\n        /**\r\n         * [1] The radius of the emission sphere.\r\n         */\r\n        public radius = 1,\r\n        /**\r\n         * [1] The range of emission [0-1] 0 Surface only, 1 Entire Radius.\r\n         */\r\n        public radiusRange = 1,\r\n        /**\r\n         * [0] How much to randomize the particle direction [0-1].\r\n         */\r\n        public directionRandomizer = 0\r\n    ) {}\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();\r\n        const randX = RandomRange(0, this.directionRandomizer);\r\n        const randY = RandomRange(0, this.directionRandomizer);\r\n        const randZ = RandomRange(0, this.directionRandomizer);\r\n        direction.x += randX;\r\n        direction.y += randY;\r\n        direction.z += randZ;\r\n        direction.normalize();\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFrom(direction);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randRadius = this.radius - RandomRange(0, this.radius * this.radiusRange);\r\n        const v = RandomRange(0, 1.0);\r\n        const phi = RandomRange(0, 2 * Math.PI);\r\n        const theta = Math.acos(2 * v - 1);\r\n        const randX = randRadius * Math.cos(phi) * Math.sin(theta);\r\n        const randY = randRadius * Math.cos(theta);\r\n        const randZ = randRadius * Math.sin(phi) * Math.sin(theta);\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.copyFromFloats(randX, randY, randZ);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): SphereParticleEmitter {\r\n        const newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setFloat(\"radius\", this.radius);\r\n        uboOrEffect.setFloat(\"radiusRange\", this.radiusRange);\r\n        uboOrEffect.setFloat(\"directionRandomizer\", this.directionRandomizer);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"radius\", 1);\r\n        ubo.addUniform(\"radiusRange\", 1);\r\n        ubo.addUniform(\"directionRandomizer\", 1);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"#define SPHEREEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"SphereParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"SphereParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.radius = this.radius;\r\n        serializationObject.radiusRange = this.radiusRange;\r\n        serializationObject.directionRandomizer = this.directionRandomizer;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        this.radius = serializationObject.radius;\r\n        this.radiusRange = serializationObject.radiusRange;\r\n        this.directionRandomizer = serializationObject.directionRandomizer;\r\n    }\r\n}\r\n\r\n/**\r\n * Particle emitter emitting particles from the inside of a sphere.\r\n * It emits the particles randomly between two vectors.\r\n */\r\nexport class SphereDirectedParticleEmitter extends SphereParticleEmitter {\r\n    /**\r\n     * Creates a new instance SphereDirectedParticleEmitter\r\n     * @param radius the radius of the emission sphere (1 by default)\r\n     * @param direction1 the min limit of the emission direction (up vector by default)\r\n     * @param direction2 the max limit of the emission direction (up vector by default)\r\n     */\r\n    constructor(\r\n        radius = 1,\r\n        /**\r\n         * [Up vector] The min limit of the emission direction.\r\n         */\r\n        public direction1 = new Vector3(0, 1, 0),\r\n        /**\r\n         * [Up vector] The max limit of the emission direction.\r\n         */\r\n        public direction2 = new Vector3(0, 1, 0)\r\n    ) {\r\n        super(radius);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public override startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randX = RandomRange(this.direction1.x, this.direction2.x);\r\n        const randY = RandomRange(this.direction1.y, this.direction2.y);\r\n        const randZ = RandomRange(this.direction1.z, this.direction2.z);\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFromFloats(randX, randY, randZ);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public override clone(): SphereDirectedParticleEmitter {\r\n        const newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public override applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setFloat(\"radius\", this.radius);\r\n        uboOrEffect.setFloat(\"radiusRange\", this.radiusRange);\r\n        uboOrEffect.setVector3(\"direction1\", this.direction1);\r\n        uboOrEffect.setVector3(\"direction2\", this.direction2);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public override buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"radius\", 1);\r\n        ubo.addUniform(\"radiusRange\", 1);\r\n        ubo.addUniform(\"direction1\", 3);\r\n        ubo.addUniform(\"direction2\", 3);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public override getEffectDefines(): string {\r\n        return \"#define SPHEREEMITTER\\n#define DIRECTEDSPHEREEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"SphereDirectedParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"SphereDirectedParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.direction1 = this.direction1.asArray();\r\n        serializationObject.direction2 = this.direction2.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public override parse(serializationObject: any): void {\r\n        super.parse(serializationObject);\r\n        Vector3.FromArrayToRef(serializationObject.direction1, 0, this.direction1);\r\n        Vector3.FromArrayToRef(serializationObject.direction2, 0, this.direction2);\r\n    }\r\n}\r\n","import { type Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { RandomRange } from \"../../Maths/math.scalar.functions\";\r\nimport { type Particle } from \"../../Particles/particle\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\nimport { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\n/**\r\n * Particle emitter emitting particles from the inside of a cylinder.\r\n * It emits the particles alongside the cylinder radius. The emission direction might be randomized.\r\n */\r\nexport class CylinderParticleEmitter implements IParticleEmitterType {\r\n    private _tempVector = Vector3.Zero();\r\n\r\n    /**\r\n     * Creates a new instance CylinderParticleEmitter\r\n     * @param radius the radius of the emission cylinder (1 by default)\r\n     * @param height the height of the emission cylinder (1 by default)\r\n     * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)\r\n     * @param directionRandomizer defines how much to randomize the particle direction [0-1]\r\n     */\r\n    constructor(\r\n        /**\r\n         * [1] The radius of the emission cylinder.\r\n         */\r\n        public radius = 1,\r\n        /**\r\n         * [1] The height of the emission cylinder.\r\n         */\r\n        public height = 1,\r\n        /**\r\n         * [1] The range of emission [0-1] 0 Surface only, 1 Entire Radius.\r\n         */\r\n        public radiusRange = 1,\r\n        /**\r\n         * [0] How much to randomize the particle direction [0-1].\r\n         */\r\n        public directionRandomizer = 0\r\n    ) {}\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     * @param inverseWorldMatrix defines the inverted world matrix to use if isLocal is false\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean, inverseWorldMatrix: Matrix): void {\r\n        particle.position.subtractToRef(worldMatrix.getTranslation(), this._tempVector);\r\n\r\n        this._tempVector.normalize();\r\n\r\n        Vector3.TransformNormalToRef(this._tempVector, inverseWorldMatrix, this._tempVector);\r\n\r\n        const randY = RandomRange(-this.directionRandomizer / 2, this.directionRandomizer / 2);\r\n\r\n        let angle = Math.atan2(this._tempVector.x, this._tempVector.z);\r\n        angle += RandomRange(-Math.PI / 2, Math.PI / 2) * this.directionRandomizer;\r\n\r\n        this._tempVector.y = randY; // set direction y to rand y to mirror normal of cylinder surface\r\n        this._tempVector.x = Math.sin(angle);\r\n        this._tempVector.z = Math.cos(angle);\r\n        this._tempVector.normalize();\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFrom(this._tempVector);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(this._tempVector.x, this._tempVector.y, this._tempVector.z, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const yPos = RandomRange(-this.height / 2, this.height / 2);\r\n        const angle = RandomRange(0, 2 * Math.PI);\r\n\r\n        // Pick a properly distributed point within the circle https://programming.guide/random-point-within-circle.html\r\n        const radiusDistribution = RandomRange((1 - this.radiusRange) * (1 - this.radiusRange), 1);\r\n        const positionRadius = Math.sqrt(radiusDistribution) * this.radius;\r\n        const xPos = positionRadius * Math.cos(angle);\r\n        const zPos = positionRadius * Math.sin(angle);\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.copyFromFloats(xPos, yPos, zPos);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesFromFloatsToRef(xPos, yPos, zPos, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): CylinderParticleEmitter {\r\n        const newOne = new CylinderParticleEmitter(this.radius, this.directionRandomizer);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setFloat(\"radius\", this.radius);\r\n        uboOrEffect.setFloat(\"height\", this.height);\r\n        uboOrEffect.setFloat(\"radiusRange\", this.radiusRange);\r\n        uboOrEffect.setFloat(\"directionRandomizer\", this.directionRandomizer);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"radius\", 1);\r\n        ubo.addUniform(\"height\", 1);\r\n        ubo.addUniform(\"radiusRange\", 1);\r\n        ubo.addUniform(\"directionRandomizer\", 1);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"#define CYLINDEREMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"CylinderParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"CylinderParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.radius = this.radius;\r\n        serializationObject.height = this.height;\r\n        serializationObject.radiusRange = this.radiusRange;\r\n        serializationObject.directionRandomizer = this.directionRandomizer;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        this.radius = serializationObject.radius;\r\n        this.height = serializationObject.height;\r\n        this.radiusRange = serializationObject.radiusRange;\r\n        this.directionRandomizer = serializationObject.directionRandomizer;\r\n    }\r\n}\r\n\r\n/**\r\n * Particle emitter emitting particles from the inside of a cylinder.\r\n * It emits the particles randomly between two vectors.\r\n */\r\nexport class CylinderDirectedParticleEmitter extends CylinderParticleEmitter {\r\n    /**\r\n     * Creates a new instance CylinderDirectedParticleEmitter\r\n     * @param radius the radius of the emission cylinder (1 by default)\r\n     * @param height the height of the emission cylinder (1 by default)\r\n     * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)\r\n     * @param direction1 the min limit of the emission direction (up vector by default)\r\n     * @param direction2 the max limit of the emission direction (up vector by default)\r\n     */\r\n    constructor(\r\n        radius = 1,\r\n        height = 1,\r\n        radiusRange = 1,\r\n        /**\r\n         * [Up vector] The min limit of the emission direction.\r\n         */\r\n        public direction1 = new Vector3(0, 1, 0),\r\n        /**\r\n         * [Up vector] The max limit of the emission direction.\r\n         */\r\n        public direction2 = new Vector3(0, 1, 0)\r\n    ) {\r\n        super(radius, height, radiusRange);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param _particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public override startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, _particle: Particle, isLocal: boolean): void {\r\n        const randX = RandomRange(this.direction1.x, this.direction2.x);\r\n        const randY = RandomRange(this.direction1.y, this.direction2.y);\r\n        const randZ = RandomRange(this.direction1.z, this.direction2.z);\r\n        if (isLocal) {\r\n            directionToUpdate.copyFromFloats(randX, randY, randZ);\r\n            return;\r\n        }\r\n        Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public override clone(): CylinderDirectedParticleEmitter {\r\n        const newOne = new CylinderDirectedParticleEmitter(this.radius, this.height, this.radiusRange, this.direction1, this.direction2);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public override applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setFloat(\"radius\", this.radius);\r\n        uboOrEffect.setFloat(\"height\", this.height);\r\n        uboOrEffect.setFloat(\"radiusRange\", this.radiusRange);\r\n        uboOrEffect.setVector3(\"direction1\", this.direction1);\r\n        uboOrEffect.setVector3(\"direction2\", this.direction2);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public override buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"radius\", 1);\r\n        ubo.addUniform(\"height\", 1);\r\n        ubo.addUniform(\"radiusRange\", 1);\r\n        ubo.addUniform(\"direction1\", 3);\r\n        ubo.addUniform(\"direction2\", 3);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public override getEffectDefines(): string {\r\n        return \"#define CYLINDEREMITTER\\n#define DIRECTEDCYLINDEREMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"CylinderDirectedParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"CylinderDirectedParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.direction1 = this.direction1.asArray();\r\n        serializationObject.direction2 = this.direction2.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public override parse(serializationObject: any): void {\r\n        super.parse(serializationObject);\r\n        Vector3.FromArrayToRef(serializationObject.direction1, 0, this.direction1);\r\n        Vector3.FromArrayToRef(serializationObject.direction2, 0, this.direction2);\r\n    }\r\n}\r\n","import { type Matrix, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"core/Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\n\r\nimport { DeepCopier } from \"core/Misc/deepCopier\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\n\r\n/**\r\n * Particle emitter emitting particles from the inside of a cone.\r\n * It emits the particles alongside the cone volume from the base to the particle.\r\n * The emission direction might be randomized.\r\n */\r\nexport class ConeParticleEmitter implements IParticleEmitterType {\r\n    private _radius: number;\r\n    private _angle: number;\r\n    private _height: number;\r\n\r\n    /**\r\n     * Gets or sets a value indicating where on the radius the start position should be picked (1 = everywhere, 0 = only surface)\r\n     */\r\n    public radiusRange = 1;\r\n\r\n    /**\r\n     * Gets or sets a value indicating where on the height the start position should be picked (1 = everywhere, 0 = only surface)\r\n     */\r\n    public heightRange = 1;\r\n\r\n    /**\r\n     * Gets or sets a value indicating if all the particles should be emitted from the spawn point only (the base of the cone)\r\n     */\r\n    public emitFromSpawnPointOnly = false;\r\n\r\n    /**\r\n     * Gets or sets the radius of the emission cone\r\n     */\r\n    public get radius(): number {\r\n        return this._radius;\r\n    }\r\n\r\n    public set radius(value: number) {\r\n        this._radius = value;\r\n        this._buildHeight();\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the angle of the emission cone\r\n     */\r\n    public get angle(): number {\r\n        return this._angle;\r\n    }\r\n\r\n    public set angle(value: number) {\r\n        this._angle = value;\r\n        this._buildHeight();\r\n    }\r\n\r\n    private _buildHeight() {\r\n        if (this._angle !== 0) {\r\n            this._height = this._radius / Math.tan(this._angle / 2);\r\n        } else {\r\n            this._height = 1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance ConeParticleEmitter\r\n     * @param radius the radius of the emission cone (1 by default)\r\n     * @param angle the cone base angle (PI by default)\r\n     * @param directionRandomizer defines how much to randomize the particle direction [0-1] (default is 0)\r\n     */\r\n    constructor(\r\n        radius = 1,\r\n        angle = Math.PI,\r\n        /** [0] defines how much to randomize the particle direction [0-1] (default is 0) */\r\n        public directionRandomizer = 0\r\n    ) {\r\n        this.angle = angle;\r\n        this.radius = radius;\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();\r\n        const randX = RandomRange(0, this.directionRandomizer);\r\n        const randY = RandomRange(0, this.directionRandomizer);\r\n        const randZ = RandomRange(0, this.directionRandomizer);\r\n        direction.x += randX;\r\n        direction.y += randY;\r\n        direction.z += randZ;\r\n        direction.normalize();\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFrom(direction);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const s = RandomRange(0, Math.PI * 2);\r\n        let h: number;\r\n\r\n        if (!this.emitFromSpawnPointOnly) {\r\n            h = RandomRange(0, this.heightRange);\r\n            // Better distribution in a cone at normal angles.\r\n            h = 1 - h * h;\r\n        } else {\r\n            h = 0.0001;\r\n        }\r\n        let radius = this._radius - RandomRange(0, this._radius * this.radiusRange);\r\n        radius = radius * h;\r\n\r\n        const randX = radius * Math.sin(s);\r\n        const randZ = radius * Math.cos(s);\r\n        const randY = h * this._height;\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.x = randX;\r\n            positionToUpdate.y = randY;\r\n            positionToUpdate.z = randZ;\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): ConeParticleEmitter {\r\n        const newOne = new ConeParticleEmitter(this._radius, this._angle, this.directionRandomizer);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setFloat2(\"radius\", this._radius, this.radiusRange);\r\n        uboOrEffect.setFloat(\"coneAngle\", this._angle);\r\n        uboOrEffect.setFloat2(\"height\", this._height, this.heightRange);\r\n        uboOrEffect.setFloat(\"directionRandomizer\", this.directionRandomizer);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"radius\", 2);\r\n        ubo.addUniform(\"coneAngle\", 1);\r\n        ubo.addUniform(\"height\", 2);\r\n        ubo.addUniform(\"directionRandomizer\", 1);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        let defines = \"#define CONEEMITTER\";\r\n\r\n        if (this.emitFromSpawnPointOnly) {\r\n            defines += \"\\n#define CONEEMITTERSPAWNPOINT\";\r\n        }\r\n\r\n        return defines;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"ConeParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ConeParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.radius = this._radius;\r\n        serializationObject.angle = this._angle;\r\n        serializationObject.directionRandomizer = this.directionRandomizer;\r\n        serializationObject.radiusRange = this.radiusRange;\r\n        serializationObject.heightRange = this.heightRange;\r\n        serializationObject.emitFromSpawnPointOnly = this.emitFromSpawnPointOnly;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        this.radius = serializationObject.radius;\r\n        this.angle = serializationObject.angle;\r\n        this.directionRandomizer = serializationObject.directionRandomizer;\r\n\r\n        this.radiusRange = serializationObject.radiusRange !== undefined ? serializationObject.radiusRange : 1;\r\n        this.heightRange = serializationObject.heightRange !== undefined ? serializationObject.heightRange : 1;\r\n        this.emitFromSpawnPointOnly = serializationObject.emitFromSpawnPointOnly !== undefined ? serializationObject.emitFromSpawnPointOnly : false;\r\n    }\r\n}\r\nexport class ConeDirectedParticleEmitter extends ConeParticleEmitter {\r\n    constructor(\r\n        radius = 1,\r\n        angle = Math.PI,\r\n        /**\r\n         * [Up vector] The min limit of the emission direction.\r\n         */\r\n        public direction1 = new Vector3(0, 1, 0),\r\n        /**\r\n         * [Up vector] The max limit of the emission direction.\r\n         */\r\n        public direction2 = new Vector3(0, 1, 0)\r\n    ) {\r\n        super(radius, angle);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public override startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const randX = RandomRange(this.direction1.x, this.direction2.x);\r\n        const randY = RandomRange(this.direction1.y, this.direction2.y);\r\n        const randZ = RandomRange(this.direction1.z, this.direction2.z);\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFromFloats(randX, randY, randZ);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public override clone(): ConeDirectedParticleEmitter {\r\n        const newOne = new ConeDirectedParticleEmitter(this.radius, this.angle, this.direction1, this.direction2);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public override applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        super.applyToShader(uboOrEffect);\r\n        uboOrEffect.setVector3(\"direction1\", this.direction1);\r\n        uboOrEffect.setVector3(\"direction2\", this.direction2);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public override buildUniformLayout(ubo: UniformBuffer): void {\r\n        super.buildUniformLayout(ubo);\r\n        ubo.addUniform(\"direction1\", 3);\r\n        ubo.addUniform(\"direction2\", 3);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public override getEffectDefines(): string {\r\n        return \"#define CONEEMITTER\\n#define DIRECTEDCONEEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"ConeDirectedParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ConeDirectedParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.direction1 = this.direction1.asArray();\r\n        serializationObject.direction2 = this.direction2.asArray();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public override parse(serializationObject: any): void {\r\n        super.parse(serializationObject);\r\n        Vector3.FromArrayToRef(serializationObject.direction1, 0, this.direction1);\r\n        Vector3.FromArrayToRef(serializationObject.direction2, 0, this.direction2);\r\n    }\r\n}\r\n","import { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { type Matrix, Vector3, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { RandomRange } from \"../../Maths/math.scalar.functions\";\r\nimport { type Particle } from \"../../Particles/particle\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\nimport { type IndicesArray, type Nullable, type FloatArray } from \"../../types\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"../../Materials/uniformBuffer\";\r\n/**\r\n * Particle emitter emitting particles from the inside of a box.\r\n * It emits the particles randomly between 2 given directions.\r\n */\r\nexport class MeshParticleEmitter implements IParticleEmitterType {\r\n    private _indices: Nullable<IndicesArray> = null;\r\n    private _positions: Nullable<FloatArray> = null;\r\n    private _normals: Nullable<FloatArray> = null;\r\n    private _storedNormal = Vector3.Zero();\r\n    private _mesh: Nullable<AbstractMesh> = null;\r\n\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     */\r\n    public direction1 = new Vector3(0, 1.0, 0);\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     */\r\n    public direction2 = new Vector3(0, 1.0, 0);\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that particle directions must be built from mesh face normals\r\n     */\r\n    public useMeshNormalsForDirection = true;\r\n\r\n    /** Defines the mesh to use as source */\r\n    public get mesh(): Nullable<AbstractMesh> {\r\n        return this._mesh;\r\n    }\r\n\r\n    public set mesh(value: Nullable<AbstractMesh>) {\r\n        if (this._mesh === value) {\r\n            return;\r\n        }\r\n\r\n        this._mesh = value;\r\n\r\n        if (value) {\r\n            this._indices = value.getIndices();\r\n            this._positions = value.getVerticesData(VertexBuffer.PositionKind);\r\n            this._normals = value.getVerticesData(VertexBuffer.NormalKind);\r\n        } else {\r\n            this._indices = null;\r\n            this._positions = null;\r\n            this._normals = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance MeshParticleEmitter\r\n     * @param mesh defines the mesh to use as source\r\n     */\r\n    constructor(mesh: Nullable<AbstractMesh> = null) {\r\n        this.mesh = mesh;\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        if (this.useMeshNormalsForDirection && this._normals) {\r\n            Vector3.TransformNormalToRef(this._storedNormal, worldMatrix, directionToUpdate);\r\n            return;\r\n        }\r\n\r\n        const randX = RandomRange(this.direction1.x, this.direction2.x);\r\n        const randY = RandomRange(this.direction1.y, this.direction2.y);\r\n        const randZ = RandomRange(this.direction1.z, this.direction2.z);\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFromFloats(randX, randY, randZ);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        if (!this._indices || !this._positions) {\r\n            return;\r\n        }\r\n\r\n        const randomFaceIndex = 3 * ((Math.random() * (this._indices.length / 3)) | 0);\r\n        const bu = Math.random();\r\n        const bv = Math.random() * (1.0 - bu);\r\n        const bw = 1.0 - bu - bv;\r\n\r\n        const faceIndexA = this._indices[randomFaceIndex];\r\n        const faceIndexB = this._indices[randomFaceIndex + 1];\r\n        const faceIndexC = this._indices[randomFaceIndex + 2];\r\n        const vertexA = TmpVectors.Vector3[0];\r\n        const vertexB = TmpVectors.Vector3[1];\r\n        const vertexC = TmpVectors.Vector3[2];\r\n        const randomVertex = TmpVectors.Vector3[3];\r\n\r\n        Vector3.FromArrayToRef(this._positions, faceIndexA * 3, vertexA);\r\n        Vector3.FromArrayToRef(this._positions, faceIndexB * 3, vertexB);\r\n        Vector3.FromArrayToRef(this._positions, faceIndexC * 3, vertexC);\r\n\r\n        randomVertex.x = bu * vertexA.x + bv * vertexB.x + bw * vertexC.x;\r\n        randomVertex.y = bu * vertexA.y + bv * vertexB.y + bw * vertexC.y;\r\n        randomVertex.z = bu * vertexA.z + bv * vertexB.z + bw * vertexC.z;\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.copyFromFloats(randomVertex.x, randomVertex.y, randomVertex.z);\r\n        } else {\r\n            Vector3.TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, worldMatrix, positionToUpdate);\r\n        }\r\n\r\n        if (this.useMeshNormalsForDirection && this._normals) {\r\n            Vector3.FromArrayToRef(this._normals, faceIndexA * 3, vertexA);\r\n            Vector3.FromArrayToRef(this._normals, faceIndexB * 3, vertexB);\r\n            Vector3.FromArrayToRef(this._normals, faceIndexC * 3, vertexC);\r\n\r\n            this._storedNormal.x = bu * vertexA.x + bv * vertexB.x + bw * vertexC.x;\r\n            this._storedNormal.y = bu * vertexA.y + bv * vertexB.y + bw * vertexC.y;\r\n            this._storedNormal.z = bu * vertexA.z + bv * vertexB.z + bw * vertexC.z;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): MeshParticleEmitter {\r\n        const newOne = new MeshParticleEmitter(this.mesh);\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {\r\n        uboOrEffect.setVector3(\"direction1\", this.direction1);\r\n        uboOrEffect.setVector3(\"direction2\", this.direction2);\r\n    }\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    public buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"direction1\", 3);\r\n        ubo.addUniform(\"direction2\", 3);\r\n    }\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"BoxParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"MeshParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.direction1 = this.direction1.asArray();\r\n        serializationObject.direction2 = this.direction2.asArray();\r\n        serializationObject.meshId = this.mesh?.id;\r\n        serializationObject.useMeshNormalsForDirection = this.useMeshNormalsForDirection;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public parse(serializationObject: any, scene: Nullable<Scene>): void {\r\n        Vector3.FromArrayToRef(serializationObject.direction1, 0, this.direction1);\r\n        Vector3.FromArrayToRef(serializationObject.direction2, 0, this.direction2);\r\n\r\n        if (serializationObject.meshId && scene) {\r\n            this.mesh = scene.getLastMeshById(serializationObject.meshId);\r\n        }\r\n\r\n        this.useMeshNormalsForDirection = serializationObject.useMeshNormalsForDirection;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector2, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type ImageProcessingConfiguration } from \"../Materials/imageProcessingConfiguration.pure\";\r\nimport { ImageProcessingConfigurationDefines } from \"../Materials/imageProcessingConfiguration.defines\";\r\nimport { FactorGradient, type ColorGradient, type Color3Gradient, type IValueGradient } from \"../Misc/gradients\";\r\n\r\nimport { type BoxParticleEmitter } from \"../Particles/EmitterTypes/boxParticleEmitter\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type IClipPlanesHolder } from \"../Misc/interfaces/iClipPlanesHolder\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\nimport { type Animation } from \"../Animations/animation.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type ProceduralTexture } from \"../Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { type IParticleEmitterType } from \"./EmitterTypes/IParticleEmitterType\";\r\nimport { type PointParticleEmitter } from \"./EmitterTypes/pointParticleEmitter\";\r\nimport { type HemisphericParticleEmitter } from \"./EmitterTypes/hemisphericParticleEmitter\";\r\nimport { type SphereDirectedParticleEmitter, type SphereParticleEmitter } from \"./EmitterTypes/sphereParticleEmitter\";\r\nimport { type CylinderDirectedParticleEmitter, type CylinderParticleEmitter } from \"./EmitterTypes/cylinderParticleEmitter\";\r\nimport { type ConeDirectedParticleEmitter, type ConeParticleEmitter } from \"./EmitterTypes/coneParticleEmitter\";\r\nimport { type MeshParticleEmitter } from \"./EmitterTypes/meshParticleEmitter\";\r\nimport { type Attractor } from \"./attractor\";\r\nimport {\r\n    CreateBoxEmitter,\r\n    CreateConeEmitter,\r\n    CreateCylinderEmitter,\r\n    CreateDirectedConeEmitter,\r\n    CreateDirectedCylinderEmitter,\r\n    CreateDirectedSphereEmitter,\r\n    CreateHemisphericEmitter,\r\n    CreateMeshEmitter,\r\n    CreatePointEmitter,\r\n    CreateSphereEmitter,\r\n} from \"./particleSystem.functions\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * This represents the base class for particle system in Babylon.\r\n * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.\r\n * Particles can take different shapes while emitted like box, sphere, cone or you can write your custom function.\r\n * @example https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro\r\n */\r\nexport class BaseParticleSystem implements IClipPlanesHolder {\r\n    /**\r\n     * Source color is added to the destination color without alpha affecting the result. Great for additive glow effects (fire, magic, lasers)\r\n     */\r\n    public static BLENDMODE_ONEONE = 0;\r\n    /**\r\n     * Blend current color and particle color using particle’s alpha. Same as Constants.ALPHA_COMBINE, the go-to for transparency. 100% alpha means source, 0% alpha means background. Glass, UI fade, smoke\r\n     */\r\n    public static BLENDMODE_STANDARD = 1;\r\n    /**\r\n     * Add current color and particle color multiplied by particle’s alpha\r\n     */\r\n    public static BLENDMODE_ADD = 2;\r\n    /**\r\n     * Multiply current color with particle color\r\n     */\r\n    public static BLENDMODE_MULTIPLY = 3;\r\n    /**\r\n     * Multiply current color with particle color then add current color and particle color multiplied by particle’s alpha\r\n     */\r\n    public static BLENDMODE_MULTIPLYADD = 4;\r\n    /**\r\n     * Subtracts source (particle) from destination (current color), leading to darker results\r\n     * - NOTE: Init as -1 so we can properly map all modes to Engine Const's (otherwise ALPHA_SUBTRACT will conflict with BLENDMODE_MULTIPLY since both use 3)\r\n     */\r\n    public static BLENDMODE_SUBTRACT = -1;\r\n\r\n    /**\r\n     * List of animations used by the particle system.\r\n     */\r\n    public animations: Animation[] = [];\r\n\r\n    /**\r\n     * Gets or sets the unique id of the particle system\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * The id of the Particle system.\r\n     */\r\n    public id: string;\r\n\r\n    /**\r\n     * The friendly name of the Particle system.\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * Snippet ID if the particle system was created from the snippet server\r\n     */\r\n    public snippetId: string;\r\n\r\n    /**\r\n     * The rendering group used by the Particle system to chose when to render.\r\n     */\r\n    public renderingGroupId = 0;\r\n\r\n    /**\r\n     * The emitter represents the Mesh or position we are attaching the particle system to.\r\n     */\r\n    public emitter: Nullable<AbstractMesh | Vector3> = Vector3.Zero();\r\n\r\n    /**\r\n     * The maximum number of particles to emit per frame\r\n     */\r\n    public emitRate = 10;\r\n\r\n    /**\r\n     * If you want to launch only a few particles at once, that can be done, as well.\r\n     */\r\n    public manualEmitCount = -1;\r\n\r\n    /**\r\n     * The overall motion speed (0.01 is default update speed, faster updates = faster animation)\r\n     */\r\n    public updateSpeed = 0.01;\r\n\r\n    /** @internal */\r\n    public _targetStopDuration = 0;\r\n    /**\r\n     * The amount of time the particle system is running (depends of the overall update speed).\r\n     */\r\n    public get targetStopDuration() {\r\n        return this._targetStopDuration;\r\n    }\r\n\r\n    public set targetStopDuration(value: number) {\r\n        if (this._targetStopDuration === value) {\r\n            return;\r\n        }\r\n\r\n        this._targetStopDuration = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether the particle system will be disposed once it reaches the end of the animation.\r\n     */\r\n    public disposeOnStop = false;\r\n\r\n    /**\r\n     * Minimum power of emitting particles.\r\n     */\r\n    public minEmitPower = 1;\r\n    /**\r\n     * Maximum power of emitting particles.\r\n     */\r\n    public maxEmitPower = 1;\r\n\r\n    /**\r\n     * Minimum life time of emitting particles.\r\n     */\r\n    public minLifeTime = 1;\r\n    /**\r\n     * Maximum life time of emitting particles.\r\n     */\r\n    public maxLifeTime = 1;\r\n\r\n    /**\r\n     * Minimum Size of emitting particles.\r\n     */\r\n    public minSize = 1;\r\n    /**\r\n     * Maximum Size of emitting particles.\r\n     */\r\n    public maxSize = 1;\r\n\r\n    /**\r\n     * Minimum scale of emitting particles on X axis.\r\n     */\r\n    public minScaleX = 1;\r\n    /**\r\n     * Maximum scale of emitting particles on X axis.\r\n     */\r\n    public maxScaleX = 1;\r\n\r\n    /**\r\n     * Minimum scale of emitting particles on Y axis.\r\n     */\r\n    public minScaleY = 1;\r\n    /**\r\n     * Maximum scale of emitting particles on Y axis.\r\n     */\r\n    public maxScaleY = 1;\r\n\r\n    /**\r\n     * Gets or sets the minimal initial rotation in radians.\r\n     */\r\n    public minInitialRotation = 0;\r\n    /**\r\n     * Gets or sets the maximal initial rotation in radians.\r\n     */\r\n    public maxInitialRotation = 0;\r\n\r\n    /**\r\n     * Minimum angular speed of emitting particles (Z-axis rotation for each particle).\r\n     */\r\n    public minAngularSpeed = 0;\r\n    /**\r\n     * Maximum angular speed of emitting particles (Z-axis rotation for each particle).\r\n     */\r\n    public maxAngularSpeed = 0;\r\n\r\n    /**\r\n     * The texture used to render each particle. (this can be a spritesheet)\r\n     */\r\n    public particleTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * The layer mask we are rendering the particles through.\r\n     */\r\n    public layerMask: number = 0x0fffffff;\r\n\r\n    /**\r\n     * This can help using your own shader to render the particle system.\r\n     * The according effect will be created\r\n     */\r\n    public customShader: any = null;\r\n\r\n    /**\r\n     * By default particle system starts as soon as they are created. This prevents the\r\n     * automatic start to happen and let you decide when to start emitting particles.\r\n     */\r\n    public preventAutoStart: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this particle system will allow fog to be rendered on it (false by default)\r\n     */\r\n    public applyFog = false;\r\n\r\n    /** @internal */\r\n    _wasDispatched = false;\r\n\r\n    protected _rootUrl = \"\";\r\n    protected _noiseTexture: Nullable<ProceduralTexture>;\r\n\r\n    /**\r\n     * Returns true if the particle system was generated by a node particle system set\r\n     */\r\n    public get isNodeGenerated(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a texture used to add random noise to particle positions\r\n     */\r\n    public get noiseTexture(): Nullable<ProceduralTexture> {\r\n        return this._noiseTexture;\r\n    }\r\n\r\n    public set noiseTexture(value: Nullable<ProceduralTexture>) {\r\n        if (this._noiseTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._noiseTexture = value;\r\n        this._reset();\r\n    }\r\n\r\n    /** Gets or sets the strength to apply to the noise value (default is (10, 10, 10)) */\r\n    public noiseStrength = new Vector3(10, 10, 10);\r\n\r\n    /** @internal */\r\n    protected _attractors: Attractor[] = [];\r\n\r\n    /**\r\n     * The list of attractors used to change the direction of the particles in the system.\r\n     * Please note that this is a copy of the internal array. If you want to modify it, please use the addAttractor and removeAttractor methods.\r\n     */\r\n    public get attractors(): Attractor[] {\r\n        return this._attractors.slice(0);\r\n    }\r\n\r\n    /**\r\n     * Add an attractor to the particle system. Attractors are used to change the direction of the particles in the system.\r\n     * @param attractor - The attractor to add to the particle system\r\n     */\r\n    public addAttractor(attractor: Attractor): void {\r\n        this._attractors.push(attractor);\r\n    }\r\n\r\n    /**\r\n     * Removes an attractor from the particle system. Attractors are used to change the direction of the particles in the system.\r\n     * @param attractor - The attractor to remove from the particle system\r\n     */\r\n    public removeAttractor(attractor: Attractor): void {\r\n        const index = this._attractors.indexOf(attractor);\r\n        if (index !== -1) {\r\n            this._attractors.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Callback triggered when the particle animation is ending.\r\n     */\r\n    public onAnimationEnd: Nullable<() => void> = null;\r\n\r\n    /**\r\n     * Blend mode use to render the particle\r\n     * For original blend modes which are exposed from ParticleSystem (OneOne, Standard, Add, Multiply, MultiplyAdd, and Subtract), use ParticleSystem.BLENDMODE_FOO\r\n     * For all other blend modes, use Engine Constants.ALPHA_FOO blend modes\r\n     */\r\n    public blendMode = BaseParticleSystem.BLENDMODE_ONEONE;\r\n\r\n    /**\r\n     * Forces the particle to write their depth information to the depth buffer. This can help preventing other draw calls\r\n     * to override the particles.\r\n     */\r\n    public forceDepthWrite = false;\r\n\r\n    /** Gets or sets a value indicating how many cycles (or frames) must be executed before first rendering (this value has to be set before starting the system). Default is 0 */\r\n    public preWarmCycles = 0;\r\n\r\n    /** Gets or sets a value indicating the time step multiplier to use in pre-warm mode (default is 1) */\r\n    public preWarmStepOffset = 1;\r\n\r\n    /**\r\n     * If using a spritesheet (isAnimationSheetEnabled) defines the speed of the sprite loop (default is 1 meaning the animation will play once during the entire particle lifetime)\r\n     */\r\n    public spriteCellChangeSpeed = 1;\r\n    /**\r\n     * If using a spritesheet (isAnimationSheetEnabled) defines the first sprite cell to display\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public startSpriteCellID = 0;\r\n    /**\r\n     * If using a spritesheet (isAnimationSheetEnabled) defines the last sprite cell to display\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public endSpriteCellID = 0;\r\n    /**\r\n     * If using a spritesheet (isAnimationSheetEnabled), defines the sprite cell width to use\r\n     */\r\n    public spriteCellWidth = 0;\r\n    /**\r\n     * If using a spritesheet (isAnimationSheetEnabled), defines the sprite cell height to use\r\n     */\r\n    public spriteCellHeight = 0;\r\n    /**\r\n     * If using a spritesheet (isAnimationSheetEnabled), defines wether the sprite animation is looping\r\n     */\r\n    public spriteCellLoop = true;\r\n    /**\r\n     * This allows the system to random pick the start cell ID between startSpriteCellID and endSpriteCellID\r\n     */\r\n    public spriteRandomStartCell = false;\r\n\r\n    /** Gets or sets a Vector2 used to move the pivot (by default (0,0)) */\r\n    public translationPivot = new Vector2(0, 0);\r\n\r\n    protected _animationSheetEnabled = false;\r\n    /** @internal */\r\n    public get _isAnimationSheetEnabled() {\r\n        return this._animationSheetEnabled;\r\n    }\r\n\r\n    public set _isAnimationSheetEnabled(value: boolean) {\r\n        if (this._animationSheetEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._animationSheetEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that hosted animations (in the system.animations array) must be started when system.start() is called\r\n     */\r\n    public beginAnimationOnStart = false;\r\n\r\n    /**\r\n     * Gets or sets the frame to start the animation from when beginAnimationOnStart is true\r\n     */\r\n    public beginAnimationFrom = 0;\r\n\r\n    /**\r\n     * Gets or sets the frame to end the animation on when beginAnimationOnStart is true\r\n     */\r\n    public beginAnimationTo = 60;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if animations must loop when beginAnimationOnStart is true\r\n     */\r\n    public beginAnimationLoop = false;\r\n\r\n    /**\r\n     * Gets or sets a world offset applied to all particles\r\n     */\r\n    public worldOffset = new Vector3(0, 0, 0);\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 1\r\n     */\r\n    public clipPlane: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 2\r\n     */\r\n    public clipPlane2: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 3\r\n     */\r\n    public clipPlane3: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 4\r\n     */\r\n    public clipPlane4: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 5\r\n     */\r\n    public clipPlane5: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets the active clipplane 6\r\n     */\r\n    public clipPlane6: Nullable<Plane>;\r\n\r\n    /**\r\n     * Gets or sets whether an animation sprite sheet is enabled or not on the particle system\r\n     */\r\n    public get isAnimationSheetEnabled(): boolean {\r\n        return this._isAnimationSheetEnabled;\r\n    }\r\n\r\n    public set isAnimationSheetEnabled(value: boolean) {\r\n        if (this._isAnimationSheetEnabled == value) {\r\n            return;\r\n        }\r\n\r\n        this._isAnimationSheetEnabled = value;\r\n\r\n        this._reset();\r\n    }\r\n\r\n    private _useLogarithmicDepth: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean enabling the use of logarithmic depth buffers, which is good for wide depth buffers.\r\n     */\r\n    public get useLogarithmicDepth(): boolean {\r\n        return this._useLogarithmicDepth;\r\n    }\r\n\r\n    public set useLogarithmicDepth(value: boolean) {\r\n        this._useLogarithmicDepth = value && this.getScene()!.getEngine().getCaps().fragmentDepthSupported;\r\n    }\r\n\r\n    /**\r\n     * Get hosting scene\r\n     * @returns the scene\r\n     */\r\n    public getScene(): Nullable<Scene> {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * You can use gravity if you want to give an orientation to your particles.\r\n     */\r\n    public gravity = Vector3.Zero();\r\n\r\n    /** @internal */\r\n    public _colorGradients: Nullable<Array<ColorGradient>> = null;\r\n    /** @internal */\r\n    public _sizeGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _lifeTimeGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _angularSpeedGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _velocityGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _limitVelocityGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _dragGradients: Nullable<Array<FactorGradient>> = null;\r\n    protected _emitRateGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _startSizeGradients: Nullable<Array<FactorGradient>> = null;\r\n    protected _rampGradients: Nullable<Array<Color3Gradient>> = null;\r\n    /** @internal */\r\n    public _colorRemapGradients: Nullable<Array<FactorGradient>> = null;\r\n    /** @internal */\r\n    public _alphaRemapGradients: Nullable<Array<FactorGradient>> = null;\r\n\r\n    protected _hasTargetStopDurationDependantGradient() {\r\n        return (\r\n            (this._startSizeGradients && this._startSizeGradients.length > 0) ||\r\n            (this._emitRateGradients && this._emitRateGradients.length > 0) ||\r\n            (this._lifeTimeGradients && this._lifeTimeGradients.length > 0)\r\n        );\r\n    }\r\n\r\n    protected _setEngineBasedOnBlendMode(blendMode: number): void {\r\n        switch (blendMode) {\r\n            case BaseParticleSystem.BLENDMODE_MULTIPLYADD:\r\n                // Don't want to update engine since there is no equivalent engine alpha mode, instead it gets handled within particleSystem\r\n                return;\r\n            case BaseParticleSystem.BLENDMODE_ADD:\r\n                blendMode = Constants.ALPHA_ADD;\r\n                break;\r\n            case BaseParticleSystem.BLENDMODE_ONEONE:\r\n                blendMode = Constants.ALPHA_ONEONE;\r\n                break;\r\n            case BaseParticleSystem.BLENDMODE_STANDARD:\r\n                blendMode = Constants.ALPHA_COMBINE;\r\n                break;\r\n            case BaseParticleSystem.BLENDMODE_MULTIPLY:\r\n                blendMode = Constants.ALPHA_MULTIPLY;\r\n                break;\r\n            case BaseParticleSystem.BLENDMODE_SUBTRACT:\r\n                blendMode = Constants.ALPHA_SUBTRACT;\r\n                break;\r\n            default:\r\n                // For all other blend modes that were added after the initial particleSystem implementation,\r\n                // the ParticleSystem.BLENDMODE_FOO are already mapped to the underlying Constants.ALPHA_FOO\r\n                break;\r\n        }\r\n        this._engine.setAlphaMode(blendMode);\r\n    }\r\n\r\n    /**\r\n     * Defines the delay in milliseconds before starting the system (0 by default)\r\n     */\r\n    public startDelay = 0;\r\n\r\n    /**\r\n     * Gets the current list of drag gradients.\r\n     * You must use addDragGradient and removeDragGradient to update this list\r\n     * @returns the list of drag gradients\r\n     */\r\n    public getDragGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._dragGradients;\r\n    }\r\n\r\n    /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */\r\n    public limitVelocityDamping = 0.4;\r\n\r\n    /**\r\n     * Gets the current list of limit velocity gradients.\r\n     * You must use addLimitVelocityGradient and removeLimitVelocityGradient to update this list\r\n     * @returns the list of limit velocity gradients\r\n     */\r\n    public getLimitVelocityGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._limitVelocityGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of color gradients.\r\n     * You must use addColorGradient and removeColorGradient to update this list\r\n     * @returns the list of color gradients\r\n     */\r\n    public getColorGradients(): Nullable<Array<ColorGradient>> {\r\n        return this._colorGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of size gradients.\r\n     * You must use addSizeGradient and removeSizeGradient to update this list\r\n     * @returns the list of size gradients\r\n     */\r\n    public getSizeGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._sizeGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of color remap gradients.\r\n     * You must use addColorRemapGradient and removeColorRemapGradient to update this list\r\n     * @returns the list of color remap gradients\r\n     */\r\n    public getColorRemapGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._colorRemapGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of alpha remap gradients.\r\n     * You must use addAlphaRemapGradient and removeAlphaRemapGradient to update this list\r\n     * @returns the list of alpha remap gradients\r\n     */\r\n    public getAlphaRemapGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._alphaRemapGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of life time gradients.\r\n     * You must use addLifeTimeGradient and removeLifeTimeGradient to update this list\r\n     * @returns the list of life time gradients\r\n     */\r\n    public getLifeTimeGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._lifeTimeGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of angular speed gradients.\r\n     * You must use addAngularSpeedGradient and removeAngularSpeedGradient to update this list\r\n     * @returns the list of angular speed gradients\r\n     */\r\n    public getAngularSpeedGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._angularSpeedGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of velocity gradients.\r\n     * You must use addVelocityGradient and removeVelocityGradient to update this list\r\n     * @returns the list of velocity gradients\r\n     */\r\n    public getVelocityGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._velocityGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of start size gradients.\r\n     * You must use addStartSizeGradient and removeStartSizeGradient to update this list\r\n     * @returns the list of start size gradients\r\n     */\r\n    public getStartSizeGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._startSizeGradients;\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of emit rate gradients.\r\n     * You must use addEmitRateGradient and removeEmitRateGradient to update this list\r\n     * @returns the list of emit rate gradients\r\n     */\r\n    public getEmitRateGradients(): Nullable<Array<FactorGradient>> {\r\n        return this._emitRateGradients;\r\n    }\r\n\r\n    /**\r\n     * Adds a new emit rate gradient (please note that this will only work if you set the targetStopDuration property)\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the emit rate value to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addEmitRateGradient(gradient: number, factor: number, factor2?: number): this {\r\n        if (!this._emitRateGradients) {\r\n            this._emitRateGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._emitRateGradients, gradient, factor, factor2);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific emit rate gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeEmitRateGradient(gradient: number): this {\r\n        this._removeFactorGradient(this._emitRateGradients, gradient);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     * This only works when particleEmitterTyps is a BoxParticleEmitter\r\n     */\r\n    public get direction1(): Vector3 {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).direction1) {\r\n            return (<BoxParticleEmitter>this.particleEmitterType).direction1;\r\n        }\r\n\r\n        return Vector3.Zero();\r\n    }\r\n\r\n    public set direction1(value: Vector3) {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).direction1) {\r\n            (<BoxParticleEmitter>this.particleEmitterType).direction1 = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.\r\n     * This only works when particleEmitterTyps is a BoxParticleEmitter\r\n     */\r\n    public get direction2(): Vector3 {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).direction2) {\r\n            return (<BoxParticleEmitter>this.particleEmitterType).direction2;\r\n        }\r\n\r\n        return Vector3.Zero();\r\n    }\r\n\r\n    public set direction2(value: Vector3) {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).direction2) {\r\n            (<BoxParticleEmitter>this.particleEmitterType).direction2 = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Minimum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.\r\n     * This only works when particleEmitterTyps is a BoxParticleEmitter\r\n     */\r\n    public get minEmitBox(): Vector3 {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).minEmitBox) {\r\n            return (<BoxParticleEmitter>this.particleEmitterType).minEmitBox;\r\n        }\r\n\r\n        return Vector3.Zero();\r\n    }\r\n\r\n    public set minEmitBox(value: Vector3) {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).minEmitBox) {\r\n            (<BoxParticleEmitter>this.particleEmitterType).minEmitBox = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Maximum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.\r\n     * This only works when particleEmitterTyps is a BoxParticleEmitter\r\n     */\r\n    public get maxEmitBox(): Vector3 {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).maxEmitBox) {\r\n            return (<BoxParticleEmitter>this.particleEmitterType).maxEmitBox;\r\n        }\r\n\r\n        return Vector3.Zero();\r\n    }\r\n\r\n    public set maxEmitBox(value: Vector3) {\r\n        if ((<BoxParticleEmitter>this.particleEmitterType).maxEmitBox) {\r\n            (<BoxParticleEmitter>this.particleEmitterType).maxEmitBox = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Random color of each particle after it has been emitted, between color1 and color2 vectors\r\n     */\r\n    public color1 = new Color4(1.0, 1.0, 1.0, 1.0);\r\n    /**\r\n     * Random color of each particle after it has been emitted, between color1 and color2 vectors\r\n     */\r\n    public color2 = new Color4(1.0, 1.0, 1.0, 1.0);\r\n    /**\r\n     * Color the particle will have at the end of its lifetime\r\n     */\r\n    public colorDead = new Color4(0, 0, 0, 1.0);\r\n\r\n    /**\r\n     * An optional mask to filter some colors out of the texture, or filter a part of the alpha channel\r\n     */\r\n    public textureMask = new Color4(1.0, 1.0, 1.0, 1.0);\r\n\r\n    /**\r\n     * The particle emitter type defines the emitter used by the particle system.\r\n     * It can be for example box, sphere, or cone...\r\n     */\r\n    public particleEmitterType: IParticleEmitterType;\r\n\r\n    /** @internal */\r\n    public _isSubEmitter = false;\r\n\r\n    /** @internal */\r\n    public _billboardMode = Constants.PARTICLES_BILLBOARDMODE_ALL;\r\n    /**\r\n     * Gets or sets the billboard mode to use when isBillboardBased = true.\r\n     * Value can be: ParticleSystem.BILLBOARDMODE_ALL, ParticleSystem.BILLBOARDMODE_Y, ParticleSystem.BILLBOARDMODE_STRETCHED, ParticleSystem.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL\r\n     */\r\n    public get billboardMode(): number {\r\n        return this._billboardMode;\r\n    }\r\n\r\n    public set billboardMode(value: number) {\r\n        if (this._billboardMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._billboardMode = value;\r\n        this._reset();\r\n    }\r\n\r\n    /** @internal */\r\n    public _isBillboardBased = true;\r\n    /**\r\n     * Gets or sets a boolean indicating if the particles must be rendered as billboard or aligned with the direction\r\n     */\r\n    public get isBillboardBased(): boolean {\r\n        return this._isBillboardBased;\r\n    }\r\n\r\n    public set isBillboardBased(value: boolean) {\r\n        if (this._isBillboardBased === value) {\r\n            return;\r\n        }\r\n\r\n        this._isBillboardBased = value;\r\n        this._reset();\r\n    }\r\n\r\n    /**\r\n     * The scene the particle system belongs to.\r\n     */\r\n    protected _scene: Nullable<Scene>;\r\n\r\n    /**\r\n     * The engine the particle system belongs to.\r\n     */\r\n    protected _engine: AbstractEngine;\r\n\r\n    /**\r\n     * Local cache of defines for image processing.\r\n     */\r\n    protected _imageProcessingConfigurationDefines = new ImageProcessingConfigurationDefines();\r\n\r\n    /**\r\n     * Default configuration related to image processing available in the standard Material.\r\n     */\r\n    protected _imageProcessingConfiguration: Nullable<ImageProcessingConfiguration>;\r\n\r\n    /**\r\n     * Gets the image processing configuration used either in this material.\r\n     */\r\n    public get imageProcessingConfiguration(): Nullable<ImageProcessingConfiguration> {\r\n        return this._imageProcessingConfiguration;\r\n    }\r\n\r\n    /**\r\n     * Sets the Default image processing configuration used either in the this material.\r\n     *\r\n     * If sets to null, the scene one is in use.\r\n     */\r\n    public set imageProcessingConfiguration(value: Nullable<ImageProcessingConfiguration>) {\r\n        this._attachImageProcessingConfiguration(value);\r\n    }\r\n\r\n    /**\r\n     * Attaches a new image processing configuration to the Standard Material.\r\n     * @param configuration\r\n     */\r\n    protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void {\r\n        if (configuration === this._imageProcessingConfiguration) {\r\n            return;\r\n        }\r\n\r\n        // Pick the scene configuration if needed.\r\n        if (!configuration && this._scene) {\r\n            this._imageProcessingConfiguration = this._scene.imageProcessingConfiguration;\r\n        } else {\r\n            this._imageProcessingConfiguration = configuration;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    protected _reset() {}\r\n\r\n    /**\r\n     * Adds a new factor gradient to the given array, sorted by gradient value.\r\n     * @param factorGradients - The array of factor gradients to add to\r\n     * @param gradient - The gradient value (between 0 and 1)\r\n     * @param factor - The first factor value\r\n     * @param factor2 - Optional second factor value for per-particle randomization\r\n     */\r\n    protected _addFactorGradient(factorGradients: FactorGradient[], gradient: number, factor: number, factor2?: number) {\r\n        const newGradient = new FactorGradient(gradient, factor, factor2);\r\n        factorGradients.push(newGradient);\r\n\r\n        factorGradients.sort((a, b) => {\r\n            if (a.gradient < b.gradient) {\r\n                return -1;\r\n            } else if (a.gradient > b.gradient) {\r\n                return 1;\r\n            }\r\n\r\n            return 0;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Removes a factor gradient from the given array by its gradient value.\r\n     * @param factorGradients - The array of factor gradients to remove from\r\n     * @param gradient - The gradient value to match for removal\r\n     */\r\n    protected _removeFactorGradient(factorGradients: Nullable<FactorGradient[]>, gradient: number) {\r\n        if (!factorGradients) {\r\n            return;\r\n        }\r\n\r\n        let index = 0;\r\n        for (const factorGradient of factorGradients) {\r\n            if (factorGradient.gradient === gradient) {\r\n                factorGradients.splice(index, 1);\r\n                break;\r\n            }\r\n            index++;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    protected _removeGradientAndTexture(gradient: number, gradients: Nullable<IValueGradient[]>, texture: Nullable<RawTexture>): BaseParticleSystem {\r\n        if (!gradients) {\r\n            return this;\r\n        }\r\n\r\n        let index = 0;\r\n        for (const valueGradient of gradients) {\r\n            if (valueGradient.gradient === gradient) {\r\n                gradients.splice(index, 1);\r\n                break;\r\n            }\r\n            index++;\r\n        }\r\n\r\n        if (texture) {\r\n            texture.dispose();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a particle system.\r\n     * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.\r\n     * @param name The name of the particle system\r\n     */\r\n    public constructor(name: string) {\r\n        this.id = name;\r\n        this.name = name;\r\n    }\r\n\r\n    /**\r\n     * Creates a Point Emitter for the particle system (emits directly from the emitter position)\r\n     * @param direction1 Particles are emitted between the direction1 and direction2 from within the box\r\n     * @param direction2 Particles are emitted between the direction1 and direction2 from within the box\r\n     * @returns the emitter\r\n     */\r\n    public createPointEmitter(direction1: Vector3, direction2: Vector3): PointParticleEmitter {\r\n        const particleEmitter = CreatePointEmitter(direction1, direction2);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Hemisphere Emitter for the particle system (emits along the hemisphere radius)\r\n     * @param radius The radius of the hemisphere to emit from\r\n     * @param radiusRange The range of the hemisphere to emit from [0-1] 0 Surface Only, 1 Entire Radius\r\n     * @returns the emitter\r\n     */\r\n    public createHemisphericEmitter(radius = 1, radiusRange = 1): HemisphericParticleEmitter {\r\n        const particleEmitter = CreateHemisphericEmitter(radius, radiusRange);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Sphere Emitter for the particle system (emits along the sphere radius)\r\n     * @param radius The radius of the sphere to emit from\r\n     * @param radiusRange The range of the sphere to emit from [0-1] 0 Surface Only, 1 Entire Radius\r\n     * @returns the emitter\r\n     */\r\n    public createSphereEmitter(radius = 1, radiusRange = 1): SphereParticleEmitter {\r\n        const particleEmitter = CreateSphereEmitter(radius, radiusRange);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Directed Sphere Emitter for the particle system (emits between direction1 and direction2)\r\n     * @param radius The radius of the sphere to emit from\r\n     * @param direction1 Particles are emitted between the direction1 and direction2 from within the sphere\r\n     * @param direction2 Particles are emitted between the direction1 and direction2 from within the sphere\r\n     * @returns the emitter\r\n     */\r\n    public createDirectedSphereEmitter(radius = 1, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)): SphereDirectedParticleEmitter {\r\n        const particleEmitter = CreateDirectedSphereEmitter(radius, direction1, direction2);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Cylinder Emitter for the particle system (emits from the cylinder to the particle position)\r\n     * @param radius The radius of the emission cylinder\r\n     * @param height The height of the emission cylinder\r\n     * @param radiusRange The range of emission [0-1] 0 Surface only, 1 Entire Radius\r\n     * @param directionRandomizer How much to randomize the particle direction [0-1]\r\n     * @returns the emitter\r\n     */\r\n    public createCylinderEmitter(radius = 1, height = 1, radiusRange = 1, directionRandomizer = 0): CylinderParticleEmitter {\r\n        const particleEmitter = CreateCylinderEmitter(radius, height, radiusRange, directionRandomizer);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Directed Cylinder Emitter for the particle system (emits between direction1 and direction2)\r\n     * @param radius The radius of the cylinder to emit from\r\n     * @param height The height of the emission cylinder\r\n     * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)\r\n     * @param direction1 Particles are emitted between the direction1 and direction2 from within the cylinder\r\n     * @param direction2 Particles are emitted between the direction1 and direction2 from within the cylinder\r\n     * @returns the emitter\r\n     */\r\n    public createDirectedCylinderEmitter(\r\n        radius = 1,\r\n        height = 1,\r\n        radiusRange = 1,\r\n        direction1 = new Vector3(0, 1.0, 0),\r\n        direction2 = new Vector3(0, 1.0, 0)\r\n    ): CylinderDirectedParticleEmitter {\r\n        const particleEmitter = CreateDirectedCylinderEmitter(radius, height, radiusRange, direction1, direction2);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Cone Emitter for the particle system (emits from the cone to the particle position)\r\n     * @param radius The radius of the cone to emit from\r\n     * @param angle The base angle of the cone\r\n     * @returns the emitter\r\n     */\r\n    public createConeEmitter(radius = 1, angle = Math.PI / 4): ConeParticleEmitter {\r\n        const particleEmitter = CreateConeEmitter(radius, angle);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Directed Cone Emitter for the particle system (emits between direction1 and direction2)\r\n     * @param radius The radius of the cone to emit from\r\n     * @param angle The base angle of the cone\r\n     * @param direction1 Particles are emitted between the direction1 and direction2 from within the cone\r\n     * @param direction2 Particles are emitted between the direction1 and direction2 from within the cone\r\n     * @returns the emitter\r\n     */\r\n    public createDirectedConeEmitter(radius = 1, angle = Math.PI / 4, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)): ConeDirectedParticleEmitter {\r\n        const particleEmitter = CreateDirectedConeEmitter(radius, angle, direction1, direction2);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Box Emitter for the particle system. (emits between direction1 and direction2 from within the box defined by minEmitBox and maxEmitBox)\r\n     * @param direction1 Particles are emitted between the direction1 and direction2 from within the box\r\n     * @param direction2 Particles are emitted between the direction1 and direction2 from within the box\r\n     * @param minEmitBox Particles are emitted from the box between minEmitBox and maxEmitBox\r\n     * @param maxEmitBox  Particles are emitted from the box between minEmitBox and maxEmitBox\r\n     * @returns the emitter\r\n     */\r\n    public createBoxEmitter(direction1: Vector3, direction2: Vector3, minEmitBox: Vector3, maxEmitBox: Vector3): BoxParticleEmitter {\r\n        const particleEmitter = CreateBoxEmitter();\r\n        this.particleEmitterType = particleEmitter;\r\n        this.direction1 = direction1;\r\n        this.direction2 = direction2;\r\n        this.minEmitBox = minEmitBox;\r\n        this.maxEmitBox = maxEmitBox;\r\n        return particleEmitter;\r\n    }\r\n\r\n    /**\r\n     * Creates a Mesh Emitter for the particle system (emits from the surface of a mesh)\r\n     * @param mesh The mesh to use as the emitter source\r\n     * @returns the emitter\r\n     */\r\n    public createMeshEmitter(mesh: Nullable<AbstractMesh> = null): MeshParticleEmitter {\r\n        const particleEmitter = CreateMeshEmitter(mesh);\r\n        this.particleEmitterType = particleEmitter;\r\n        return particleEmitter;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for baseParticleSystem.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBaseParticleSystem(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.BaseParticleSystem\", BaseParticleSystem);\r\n}\r\n","import { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { BoxParticleEmitter } from \"./EmitterTypes/boxParticleEmitter\";\r\nimport { PointParticleEmitter } from \"./EmitterTypes/pointParticleEmitter\";\r\nimport { HemisphericParticleEmitter } from \"./EmitterTypes/hemisphericParticleEmitter\";\r\nimport { SphereDirectedParticleEmitter, SphereParticleEmitter } from \"./EmitterTypes/sphereParticleEmitter\";\r\nimport { CylinderDirectedParticleEmitter, CylinderParticleEmitter } from \"./EmitterTypes/cylinderParticleEmitter\";\r\nimport { ConeDirectedParticleEmitter, ConeParticleEmitter } from \"./EmitterTypes/coneParticleEmitter\";\r\nimport { MeshParticleEmitter } from \"./EmitterTypes/meshParticleEmitter\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * Creates a Point Emitter for the particle system (emits directly from the emitter position)\r\n * @param direction1 Particles are emitted between the direction1 and direction2 from within the box\r\n * @param direction2 Particles are emitted between the direction1 and direction2 from within the box\r\n * @returns the emitter\r\n */\r\nexport function CreatePointEmitter(direction1: Vector3, direction2: Vector3): PointParticleEmitter {\r\n    const particleEmitter = new PointParticleEmitter();\r\n    particleEmitter.direction1 = direction1;\r\n    particleEmitter.direction2 = direction2;\r\n    return particleEmitter;\r\n}\r\n\r\n/**\r\n * Creates a Hemisphere Emitter for the particle system (emits along the hemisphere radius)\r\n * @param radius The radius of the hemisphere to emit from\r\n * @param radiusRange The range of the hemisphere to emit from [0-1] 0 Surface Only, 1 Entire Radius\r\n * @returns the emitter\r\n */\r\nexport function CreateHemisphericEmitter(radius = 1, radiusRange = 1): HemisphericParticleEmitter {\r\n    return new HemisphericParticleEmitter(radius, radiusRange);\r\n}\r\n\r\n/**\r\n * Creates a Sphere Emitter for the particle system (emits along the sphere radius)\r\n * @param radius The radius of the sphere to emit from\r\n * @param radiusRange The range of the sphere to emit from [0-1] 0 Surface Only, 1 Entire Radius\r\n * @returns the emitter\r\n */\r\nexport function CreateSphereEmitter(radius = 1, radiusRange = 1): SphereParticleEmitter {\r\n    return new SphereParticleEmitter(radius, radiusRange);\r\n}\r\n\r\n/**\r\n * Creates a Directed Sphere Emitter for the particle system (emits between direction1 and direction2)\r\n * @param radius The radius of the sphere to emit from\r\n * @param direction1 Particles are emitted between the direction1 and direction2 from within the sphere\r\n * @param direction2 Particles are emitted between the direction1 and direction2 from within the sphere\r\n * @returns the emitter\r\n */\r\nexport function CreateDirectedSphereEmitter(radius = 1, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)): SphereDirectedParticleEmitter {\r\n    return new SphereDirectedParticleEmitter(radius, direction1, direction2);\r\n}\r\n\r\n/**\r\n * Creates a Cylinder Emitter for the particle system (emits from the cylinder to the particle position)\r\n * @param radius The radius of the emission cylinder\r\n * @param height The height of the emission cylinder\r\n * @param radiusRange The range of emission [0-1] 0 Surface only, 1 Entire Radius\r\n * @param directionRandomizer How much to randomize the particle direction [0-1]\r\n * @returns the emitter\r\n */\r\nexport function CreateCylinderEmitter(radius = 1, height = 1, radiusRange = 1, directionRandomizer = 0): CylinderParticleEmitter {\r\n    return new CylinderParticleEmitter(radius, height, radiusRange, directionRandomizer);\r\n}\r\n\r\n/**\r\n * Creates a Directed Cylinder Emitter for the particle system (emits between direction1 and direction2)\r\n * @param radius The radius of the cylinder to emit from\r\n * @param height The height of the emission cylinder\r\n * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)\r\n * @param direction1 Particles are emitted between the direction1 and direction2 from within the cylinder\r\n * @param direction2 Particles are emitted between the direction1 and direction2 from within the cylinder\r\n * @returns the emitter\r\n */\r\nexport function CreateDirectedCylinderEmitter(\r\n    radius = 1,\r\n    height = 1,\r\n    radiusRange = 1,\r\n    direction1 = new Vector3(0, 1.0, 0),\r\n    direction2 = new Vector3(0, 1.0, 0)\r\n): CylinderDirectedParticleEmitter {\r\n    return new CylinderDirectedParticleEmitter(radius, height, radiusRange, direction1, direction2);\r\n}\r\n\r\n/**\r\n * Creates a Cone Emitter for the particle system (emits from the cone to the particle position)\r\n * @param radius The radius of the cone to emit from\r\n * @param angle The base angle of the cone\r\n * @returns the emitter\r\n */\r\nexport function CreateConeEmitter(radius = 1, angle = Math.PI / 4): ConeParticleEmitter {\r\n    return new ConeParticleEmitter(radius, angle);\r\n}\r\n\r\nexport function CreateDirectedConeEmitter(radius = 1, angle = Math.PI / 4, direction1 = new Vector3(0, 1.0, 0), direction2 = new Vector3(0, 1.0, 0)): ConeDirectedParticleEmitter {\r\n    return new ConeDirectedParticleEmitter(radius, angle, direction1, direction2);\r\n}\r\n\r\n/**\r\n * Creates a Box Emitter for the particle system.\r\n * Direction and box bounds are configured on the returned emitter instance.\r\n * @returns the emitter\r\n */\r\nexport function CreateBoxEmitter(): BoxParticleEmitter {\r\n    return new BoxParticleEmitter();\r\n}\r\n\r\n/**\r\n * Creates a Mesh Emitter for the particle system (emits from the surface of a mesh)\r\n * @param mesh The mesh to use as the emitter source\r\n * @returns the emitter\r\n */\r\nexport function CreateMeshEmitter(mesh: Nullable<AbstractMesh> = null): MeshParticleEmitter {\r\n    return new MeshParticleEmitter(mesh);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to expand a Color3/4 into 4 outputs (one for each component)\r\n */\r\nexport class ColorSplitterBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ColorSplitterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, true);\r\n        this.registerInput(\"rgb \", NodeMaterialBlockConnectionPointTypes.Color3, true);\r\n\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n        this.registerOutput(\"r\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"g\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"b\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"a\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.inputsAreExclusive = true;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ColorSplitterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba component (input)\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component (input)\r\n     */\r\n    public get rgbIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component (output)\r\n     */\r\n    public get rgbOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the r component (output)\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the g component (output)\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n    /**\r\n     * Gets the b component (output)\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n    /**\r\n     * Gets the a component (output)\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"rgb \") {\r\n            return \"rgbIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _outputRename(name: string) {\r\n        if (name === \"rgb\") {\r\n            return \"rgbOut\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const input = this.rgba.isConnected ? this.rgba : this.rgbIn;\r\n\r\n        if (!input.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const rgbOutput = this._outputs[0];\r\n        const rOutput = this._outputs[1];\r\n        const gOutput = this._outputs[2];\r\n        const bOutput = this._outputs[3];\r\n        const aOutput = this._outputs[4];\r\n\r\n        if (rgbOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(rgbOutput) + ` = ${input.associatedVariableName}.rgb;\\n`;\r\n        }\r\n        if (rOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(rOutput) + ` = ${input.associatedVariableName}.r;\\n`;\r\n        }\r\n        if (gOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(gOutput) + ` = ${input.associatedVariableName}.g;\\n`;\r\n        }\r\n        if (bOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(bOutput) + ` = ${input.associatedVariableName}.b;\\n`;\r\n        }\r\n        if (aOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(aOutput) + ` = ${input.associatedVariableName}.a;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for colorSplitterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterColorSplitterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ColorSplitterBlock\", ColorSplitterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Trigonometry block\r\n */\r\nexport enum TrigonometryBlockOperations {\r\n    /** Cos */\r\n    Cos,\r\n    /** Sin */\r\n    Sin,\r\n    /** Abs */\r\n    Abs,\r\n    /** Exp */\r\n    Exp,\r\n    /** Exp2 */\r\n    Exp2,\r\n    /** Round */\r\n    Round,\r\n    /** Floor */\r\n    Floor,\r\n    /** Ceiling */\r\n    Ceiling,\r\n    /** Square root */\r\n    Sqrt,\r\n    /** Log */\r\n    Log,\r\n    /** Tangent */\r\n    Tan,\r\n    /** Arc tangent */\r\n    ArcTan,\r\n    /** Arc cosinus */\r\n    ArcCos,\r\n    /** Arc sinus */\r\n    ArcSin,\r\n    /** Fraction */\r\n    Fract,\r\n    /** Sign */\r\n    Sign,\r\n    /** To radians (from degrees) */\r\n    Radians,\r\n    /** To degrees (from radians) */\r\n    Degrees,\r\n    /** To Set a = b */\r\n    Set,\r\n}\r\n\r\n/**\r\n * Block used to apply trigonometry operation to floats\r\n */\r\nexport class TrigonometryBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Cos\", value: TrigonometryBlockOperations.Cos },\r\n            { label: \"Sin\", value: TrigonometryBlockOperations.Sin },\r\n            { label: \"Abs\", value: TrigonometryBlockOperations.Abs },\r\n            { label: \"Exp\", value: TrigonometryBlockOperations.Exp },\r\n            { label: \"Exp2\", value: TrigonometryBlockOperations.Exp2 },\r\n            { label: \"Round\", value: TrigonometryBlockOperations.Round },\r\n            { label: \"Floor\", value: TrigonometryBlockOperations.Floor },\r\n            { label: \"Ceiling\", value: TrigonometryBlockOperations.Ceiling },\r\n            { label: \"Sqrt\", value: TrigonometryBlockOperations.Sqrt },\r\n            { label: \"Log\", value: TrigonometryBlockOperations.Log },\r\n            { label: \"Tan\", value: TrigonometryBlockOperations.Tan },\r\n            { label: \"ArcTan\", value: TrigonometryBlockOperations.ArcTan },\r\n            { label: \"ArcCos\", value: TrigonometryBlockOperations.ArcCos },\r\n            { label: \"ArcSin\", value: TrigonometryBlockOperations.ArcSin },\r\n            { label: \"Fract\", value: TrigonometryBlockOperations.Fract },\r\n            { label: \"Sign\", value: TrigonometryBlockOperations.Sign },\r\n            { label: \"Radians\", value: TrigonometryBlockOperations.Radians },\r\n            { label: \"Degrees\", value: TrigonometryBlockOperations.Degrees },\r\n            { label: \"Set\", value: TrigonometryBlockOperations.Set },\r\n        ],\r\n    })\r\n    public operation = TrigonometryBlockOperations.Cos;\r\n\r\n    /**\r\n     * Creates a new TrigonometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TrigonometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        let operation = \"\";\r\n\r\n        switch (this.operation) {\r\n            case TrigonometryBlockOperations.Cos: {\r\n                operation = \"cos\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Sin: {\r\n                operation = \"sin\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Abs: {\r\n                operation = \"abs\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Exp: {\r\n                operation = \"exp\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Exp2: {\r\n                operation = \"exp2\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Round: {\r\n                operation = \"round\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Floor: {\r\n                operation = \"floor\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Ceiling: {\r\n                operation = \"ceil\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Sqrt: {\r\n                operation = \"sqrt\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Log: {\r\n                operation = \"log\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Tan: {\r\n                operation = \"tan\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.ArcTan: {\r\n                operation = \"atan\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.ArcCos: {\r\n                operation = \"acos\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.ArcSin: {\r\n                operation = \"asin\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Fract: {\r\n                operation = \"fract\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Sign: {\r\n                operation = \"sign\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Radians: {\r\n                operation = \"radians\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Degrees: {\r\n                operation = \"degrees\";\r\n                break;\r\n            }\r\n            case TrigonometryBlockOperations.Set: {\r\n                operation = \"\";\r\n                break;\r\n            }\r\n        }\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${operation}(${this.input.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString =\r\n            super._dumpPropertiesCode() + `${this._codeVariableName}.operation = BABYLON.TrigonometryBlockOperations.${TrigonometryBlockOperations[this.operation]};\\n`;\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for trigonometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTrigonometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TrigonometryBlock\", TrigonometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { type NodeMaterialBlock } from \"./nodeMaterialBlock\";\nimport { PushMaterial } from \"../pushMaterial\";\nimport { type Scene } from \"../../scene.pure\";\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\nimport { Matrix, Vector2 } from \"../../Maths/math.vector.pure\";\nimport { Color3, Color4 } from \"../../Maths/math.color.pure\";\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\nimport { NodeMaterialBuildState } from \"./nodeMaterialBuildState\";\nimport { type IEffectCreationOptions, Effect } from \"../effect.pure\";\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\nimport { Observable } from \"../../Misc/observable.pure\";\nimport { NodeMaterialBlockTargets } from \"./Enums/nodeMaterialBlockTargets\";\nimport { NodeMaterialBuildStateSharedData } from \"./nodeMaterialBuildStateSharedData\";\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\nimport { MaterialDefines } from \"../../Materials/materialDefines\";\nimport { type NodeMaterialOptimizer } from \"./Optimizers/nodeMaterialOptimizer\";\nimport { type Nullable } from \"../../types\";\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\nimport { Tools } from \"../../Misc/tools.pure\";\nimport { SfeModeDefine } from \"./Blocks/Fragment/smartFilterFragmentOutputBlock.pure\";\nimport { TransformBlock } from \"./Blocks/transformBlock.pure\";\nimport { VertexOutputBlock } from \"./Blocks/Vertex/vertexOutputBlock.pure\";\nimport { FragmentOutputBlock } from \"./Blocks/Fragment/fragmentOutputBlock.pure\";\nimport { InputBlock } from \"./Blocks/Input/inputBlock.pure\";\nimport { GetClass, RegisterClass } from \"../../Misc/typeStore\";\nimport { serialize } from \"../../Misc/decorators\";\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\nimport { type TextureBlock } from \"./Blocks/Dual/textureBlock.pure\";\nimport { type ReflectionTextureBaseBlock } from \"./Blocks/Dual/reflectionTextureBaseBlock.pure\";\nimport { type RefractionBlock } from \"./Blocks/PBR/refractionBlock.pure\";\nimport { CurrentScreenBlock } from \"./Blocks/Dual/currentScreenBlock.pure\";\nimport { ParticleTextureBlock } from \"./Blocks/Particle/particleTextureBlock.pure\";\nimport { ParticleRampGradientBlock } from \"./Blocks/Particle/particleRampGradientBlock.pure\";\nimport { ParticleBlendMultiplyBlock } from \"./Blocks/Particle/particleBlendMultiplyBlock.pure\";\nimport { EffectFallbacks } from \"../effectFallbacks\";\nimport { WebRequest } from \"../../Misc/webRequest\";\nimport { type PostProcessOptions, PostProcess } from \"../../PostProcesses/postProcess.pure\";\nimport { Constants } from \"../../Engines/constants\";\nimport { type Camera } from \"../../Cameras/camera.pure\";\nimport { VectorMergerBlock } from \"./Blocks/vectorMergerBlock.pure\";\nimport { RemapBlock } from \"./Blocks/remapBlock.pure\";\nimport { MultiplyBlock } from \"./Blocks/multiplyBlock.pure\";\nimport { NodeMaterialModes } from \"./Enums/nodeMaterialModes\";\nimport { Texture } from \"../Textures/texture.pure\";\nimport { type IParticleSystem } from \"../../Particles/IParticleSystem\";\nimport { BaseParticleSystem } from \"../../Particles/baseParticleSystem.pure\";\nimport { ColorSplitterBlock } from \"./Blocks/colorSplitterBlock.pure\";\nimport { TimingTools } from \"../../Misc/timingTools\";\nimport { ProceduralTexture } from \"../Textures/Procedurals/proceduralTexture.pure\";\nimport { AnimatedInputBlockTypes } from \"./Blocks/Input/animatedInputBlockTypes\";\nimport { TrigonometryBlock, TrigonometryBlockOperations } from \"./Blocks/trigonometryBlock.pure\";\nimport { NodeMaterialSystemValues } from \"./Enums/nodeMaterialSystemValues\";\nimport { type ImageSourceBlock } from \"./Blocks/Dual/imageSourceBlock.pure\";\nimport { EngineStore } from \"../../Engines/engineStore\";\nimport { Material } from \"../material.pure\";\nimport { type TriPlanarBlock } from \"./Blocks/triPlanarBlock.pure\";\nimport { type BiPlanarBlock } from \"./Blocks/biPlanarBlock.pure\";\nimport { type PrePassRenderer } from \"../../Rendering/prePassRenderer.pure\";\nimport { type PrePassTextureBlock } from \"./Blocks/Input/prePassTextureBlock.pure\";\nimport { type PrePassOutputBlock } from \"./Blocks/Fragment/prePassOutputBlock.pure\";\nimport { type NodeMaterialTeleportOutBlock } from \"./Blocks/Teleport/teleportOutBlock.pure\";\nimport { type NodeMaterialTeleportInBlock } from \"./Blocks/Teleport/teleportInBlock.pure\";\nimport { Logger } from \"core/Misc/logger\";\nimport { PrepareDefinesForCamera, PrepareDefinesForPrePass, AreLightsTexturesReady } from \"../materialHelper.functions\";\nimport { ImageProcessingDefinesMixin } from \"../imageProcessingConfiguration.defines\";\nimport { ImageProcessingConfiguration, RegisterImageProcessingConfiguration } from \"../imageProcessingConfiguration.pure\";\nimport { ShaderLanguage } from \"../shaderLanguage\";\nimport { AbstractEngine } from \"../../Engines/abstractEngine.pure\";\nimport { type LoopBlock } from \"./Blocks/loopBlock.pure\";\nimport { MaterialHelperGeometryRendering } from \"../materialHelper.geometryrendering\";\nimport { UVDefinesMixin } from \"../uv.defines\";\nimport { ImageProcessingMixin } from \"../imageProcessing\";\n\nconst onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };\n\n// declare NODEEDITOR namespace for compilation issue\ndeclare let NODEEDITOR: any;\ndeclare let BABYLON: any;\n\n/**\n * Interface used to configure the node material editor\n */\nexport interface INodeMaterialEditorOptions {\n    /** Define the URL to load node editor script from */\n    editorURL?: string;\n    /** Additional configuration for the NME */\n    nodeEditorConfig?: {\n        backgroundColor?: Color4;\n    };\n}\n\nclass NodeMaterialDefinesBase extends UVDefinesMixin(MaterialDefines) {}\n\n/** @internal */\nexport class NodeMaterialDefines extends ImageProcessingDefinesMixin(NodeMaterialDefinesBase) {\n    /** Normal */\n    public NORMAL = false;\n    /** Tangent */\n    public TANGENT = false;\n    /** Vertex color */\n    public VERTEXCOLOR_NME = false;\n\n    /** Prepass **/\n    public PREPASS = false;\n    /** Prepass color */\n    public PREPASS_COLOR = false;\n    /** Prepass color index */\n    public PREPASS_COLOR_INDEX = -1;\n    /** Prepass normal */\n    public PREPASS_NORMAL = false;\n    /** Prepass normal index */\n    public PREPASS_NORMAL_INDEX = -1;\n    /** Prepass world normal */\n    public PREPASS_WORLD_NORMAL = false;\n    /** Prepass world normal index */\n    public PREPASS_WORLD_NORMAL_INDEX = -1;\n    /** Prepass position */\n    public PREPASS_POSITION = false;\n    /** Prepass position index */\n    public PREPASS_POSITION_INDEX = -1;\n    /** Prepass local position */\n    public PREPASS_LOCAL_POSITION = false;\n    /** Prepass local position index */\n    public PREPASS_LOCAL_POSITION_INDEX = -1;\n    /** Prepass depth */\n    public PREPASS_DEPTH = false;\n    /** Prepass depth index */\n    public PREPASS_DEPTH_INDEX = -1;\n    /** Clip-space depth */\n    public PREPASS_SCREENSPACE_DEPTH = false;\n    /** Clip-space depth index */\n    public PREPASS_SCREENSPACE_DEPTH_INDEX = -1;\n    /** Reflectivity */\n    public PREPASS_REFLECTIVITY = false;\n    /** Reflectivity index */\n    public PREPASS_REFLECTIVITY_INDEX = -1;\n    /** Velocity */\n    public PREPASS_VELOCITY = false;\n    /** Velocity index */\n    public PREPASS_VELOCITY_INDEX = -1;\n    /** Velocity linear */\n    public PREPASS_VELOCITY_LINEAR = false;\n    /** Velocity linear index */\n    public PREPASS_VELOCITY_LINEAR_INDEX = -1;\n    /** Object ID */\n    public PREPASS_OBJECT_ID = false;\n    /** Object ID index */\n    public PREPASS_OBJECT_ID_INDEX = -1;\n    /** Whether object IDs use the RED texture format */\n    public PREPASS_OBJECT_ID_R8 = false;\n    /** Packed mesh-blending tag */\n    public PREPASS_MESH_BLEND_TAG = false;\n    /** Packed mesh-blending tag index */\n    public PREPASS_MESH_BLEND_TAG_INDEX = -1;\n    /** Scene MRT count */\n    public SCENE_MRT_COUNT = 0;\n\n    /** BONES */\n    public NUM_BONE_INFLUENCERS = 0;\n    /** Bones per mesh */\n    public BonesPerMesh = 0;\n    /** Using texture for bone storage */\n    public BONETEXTURE = false;\n\n    /** MORPH TARGETS */\n    public MORPHTARGETS = false;\n    /** Morph target position */\n    public MORPHTARGETS_POSITION = false;\n    /** Morph target normal */\n    public MORPHTARGETS_NORMAL = false;\n    /** Morph target tangent */\n    public MORPHTARGETS_TANGENT = false;\n    /** Morph target uv */\n    public MORPHTARGETS_UV = false;\n    /** Morph target uv2 */\n    public MORPHTARGETS_UV2 = false;\n    /** Morph target color support */\n    public MORPHTARGETS_COLOR = false;\n    /** Morph target support positions */\n    public MORPHTARGETTEXTURE_HASPOSITIONS = false;\n    /** Morph target support normals */\n    public MORPHTARGETTEXTURE_HASNORMALS = false;\n    /** Morph target support tangents */\n    public MORPHTARGETTEXTURE_HASTANGENTS = false;\n    /** Morph target support uvs */\n    public MORPHTARGETTEXTURE_HASUVS = false;\n    /** Morph target support uv2s */\n    public MORPHTARGETTEXTURE_HASUV2S = false;\n    /** Morph target texture has colors */\n    public MORPHTARGETTEXTURE_HASCOLORS = false;\n    /** Number of morph influencers */\n    public NUM_MORPH_INFLUENCERS = 0;\n    /** Using a texture to store morph target data */\n    public MORPHTARGETS_TEXTURE = false;\n\n    /** MISC. */\n    public BUMPDIRECTUV = 0;\n    /** Camera is orthographic */\n    public CAMERA_ORTHOGRAPHIC = false;\n    /** Camera is perspective */\n    public CAMERA_PERSPECTIVE = false;\n\n    /** Area light support */\n    public AREALIGHTSUPPORTED = true;\n\n    /** Area light no roughness */\n    public AREALIGHTNOROUGHTNESS = true;\n\n    /** Position W as varying */\n    public POSITIONW_AS_VARYING = false;\n\n    /**\n     * Creates a new NodeMaterialDefines\n     */\n    constructor() {\n        super();\n        this.rebuild();\n    }\n\n    /**\n     * Set the value of a specific key\n     * @param name defines the name of the key to set\n     * @param value defines the value to set\n     * @param markAsUnprocessedIfDirty Flag to indicate to the cache that this value needs processing\n     */\n    public setValue(name: string, value: any, markAsUnprocessedIfDirty = false) {\n        if (this[name] === undefined) {\n            this._keys.push(name);\n        }\n\n        if (markAsUnprocessedIfDirty && this[name] !== value) {\n            this.markAsUnprocessed();\n        }\n\n        this[name] = value;\n    }\n}\n\n/**\n * Class used to configure NodeMaterial\n */\nexport interface INodeMaterialOptions {\n    /**\n     * Defines if blocks should emit comments\n     */\n    emitComments: boolean;\n    /** Defines shader language to use (default to GLSL) */\n    shaderLanguage: ShaderLanguage;\n}\n\n/**\n * Blocks that manage a texture\n */\nexport type NodeMaterialTextureBlocks =\n    | TextureBlock\n    | ReflectionTextureBaseBlock\n    | RefractionBlock\n    | CurrentScreenBlock\n    | ParticleTextureBlock\n    | ImageSourceBlock\n    | TriPlanarBlock\n    | BiPlanarBlock\n    | PrePassTextureBlock;\n\nclass NodeMaterialBase extends ImageProcessingMixin(PushMaterial) {}\n/**\n * Class used to create a node based material built by assembling shader blocks\n */\nexport class NodeMaterial extends NodeMaterialBase {\n    private static _BuildIdGenerator: number = 0;\n    private _options: INodeMaterialOptions;\n    private _vertexCompilationState: NodeMaterialBuildState;\n    private _fragmentCompilationState: NodeMaterialBuildState;\n    private _sharedData: NodeMaterialBuildStateSharedData;\n    private _buildId: number = NodeMaterial._BuildIdGenerator++;\n    private _buildWasSuccessful = false;\n    private _cachedWorldViewMatrix = new Matrix();\n    private _cachedWorldViewProjectionMatrix = new Matrix();\n    private _optimizers = new Array<NodeMaterialOptimizer>();\n    private _animationFrame = -1;\n    private _buildIsInProgress = false;\n\n    /** Define the Url to load node editor script */\n    public static EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/nodeEditor/babylon.nodeEditor.js`;\n\n    /** Define the Url to load snippets */\n    public static SnippetUrl = Constants.SnippetUrl;\n\n    /** Gets or sets a boolean indicating that node materials should not deserialize textures from json / snippet content */\n    public static IgnoreTexturesAtLoadTime = false;\n\n    /** Gets or sets a boolean indicating that render target textures can be serialized */\n    public static AllowSerializationOfRenderTargetTextures = false;\n\n    /** Defines default shader language when no option is defined */\n    public static DefaultShaderLanguage = ShaderLanguage.GLSL;\n\n    /** If true, the node material will use GLSL if the engine is WebGL and WGSL if it's WebGPU. It takes priority over DefaultShaderLanguage if it's true */\n    public static UseNativeShaderLanguageOfEngine = false;\n\n    private BJSNODEMATERIALEDITOR = this._getGlobalNodeMaterialEditor();\n\n    /** Gets whether the node material is currently building */\n    public get buildIsInProgress(): boolean {\n        return this._buildIsInProgress;\n    }\n\n    /** @internal */\n    public _useAdditionalColor = false;\n\n    /**\n     * Sets whether glow mode is enabled\n     * @param value - the value to set\n     */\n    public override set _glowModeEnabled(value: boolean) {\n        this._useAdditionalColor = value;\n    }\n\n    /** Get the inspector from bundle or global\n     * @returns the global NME\n     */\n    private _getGlobalNodeMaterialEditor(): any {\n        // UMD global name detection from bundle metadata.\n        // Note: rollup-built UMD bundles do not expose the editor class\n        // directly on the namespace - it lives on `.default.NodeEditor` -\n        // so we unwrap that case before falling back to the BABYLON global.\n        if (typeof NODEEDITOR !== \"undefined\") {\n            if ((NODEEDITOR as any).NodeEditor) {\n                return NODEEDITOR;\n            }\n            if ((NODEEDITOR as any).default?.NodeEditor) {\n                return (NODEEDITOR as any).default;\n            }\n        }\n\n        // In case of module let's check the global emitted from the editor entry point.\n        if (typeof BABYLON !== \"undefined\" && typeof BABYLON.NodeEditor !== \"undefined\") {\n            return BABYLON;\n        }\n\n        return undefined;\n    }\n\n    /** Gets or sets the active shader language */\n    public override get shaderLanguage(): ShaderLanguage {\n        return this._options?.shaderLanguage || NodeMaterial.DefaultShaderLanguage;\n    }\n\n    public override set shaderLanguage(value: ShaderLanguage) {\n        this._options.shaderLanguage = value;\n    }\n\n    /**\n     * Snippet ID if the material was created from the snippet server\n     */\n    public snippetId: string;\n\n    /**\n     * Gets or sets data used by visual editor\n     * @see https://nme.babylonjs.com\n     */\n    public editorData: any = null;\n\n    /**\n     * Gets or sets a boolean indicating that alpha value must be ignored (This will turn alpha blending off even if an alpha value is produced by the material)\n     */\n    @serialize()\n    public ignoreAlpha = false;\n\n    /**\n     * Defines the maximum number of lights that can be used in the material\n     */\n    @serialize()\n    public maxSimultaneousLights = 4;\n\n    /**\n     * Observable raised when the material is built\n     */\n    public onBuildObservable = new Observable<NodeMaterial>();\n\n    /**\n     * Observable raised when an error is detected\n     */\n    public onBuildErrorObservable = new Observable<string>();\n\n    /**\n     * Gets or sets the root nodes of the material vertex shader\n     */\n    public _vertexOutputNodes = new Array<NodeMaterialBlock>();\n\n    /**\n     * Gets or sets the root nodes of the material fragment (pixel) shader\n     */\n    public _fragmentOutputNodes = new Array<NodeMaterialBlock>();\n\n    /** Gets or sets options to control the node material overall behavior */\n    public get options() {\n        return this._options;\n    }\n\n    public set options(options: INodeMaterialOptions) {\n        this._options = options;\n    }\n\n    /**\n     * Gets an array of blocks that needs to be serialized even if they are not yet connected\n     */\n    public attachedBlocks: NodeMaterialBlock[] = [];\n\n    /**\n     * Specifies the mode of the node material\n     * @internal\n     */\n    @serialize(\"mode\")\n    public _mode: NodeMaterialModes = NodeMaterialModes.Material;\n\n    /**\n     * Gets or sets the mode property\n     */\n    public get mode(): NodeMaterialModes {\n        return this._mode;\n    }\n\n    public set mode(value: NodeMaterialModes) {\n        this._mode = value;\n    }\n\n    /** Gets or sets the unique identifier used to identified the effect associated with the material */\n    public get buildId() {\n        return this._buildId;\n    }\n\n    public set buildId(value: number) {\n        this._buildId = value;\n    }\n\n    /**\n     * A free comment about the material\n     */\n    @serialize(\"comment\")\n    public comment: string;\n\n    /**\n     * Create a new node based material\n     * @param name defines the material name\n     * @param scene defines the hosting scene\n     * @param options defines creation option\n     */\n    constructor(name: string, scene?: Scene, options: Partial<INodeMaterialOptions> = {}) {\n        super(name, scene || EngineStore.LastCreatedScene!);\n\n        if (!NodeMaterial.UseNativeShaderLanguageOfEngine && options && options.shaderLanguage === ShaderLanguage.WGSL && !this.getScene().getEngine().isWebGPU) {\n            throw new Error(\"WebGPU shader language is only supported with WebGPU engine\");\n        }\n\n        this._options = {\n            emitComments: false,\n            shaderLanguage: NodeMaterial.DefaultShaderLanguage,\n            ...options,\n        };\n\n        if (NodeMaterial.UseNativeShaderLanguageOfEngine) {\n            this._options.shaderLanguage = this.getScene().getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\n        }\n\n        // Setup the default processing configuration to the scene.\n        this._attachImageProcessingConfiguration(null);\n    }\n\n    /**\n     * Gets the current class name of the material e.g. \"NodeMaterial\"\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return \"NodeMaterial\";\n    }\n\n    /**\n     * Get a block by its name\n     * @param name defines the name of the block to retrieve\n     * @returns the required block or null if not found\n     */\n    public getBlockByName(name: string) {\n        let result = null;\n        for (const block of this.attachedBlocks) {\n            if (block.name === name) {\n                if (!result) {\n                    result = block;\n                } else {\n                    Logger.Warn(\"More than one block was found with the name `\" + name + \"`\");\n                    return result;\n                }\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Get a block using a predicate\n     * @param predicate defines the predicate used to find the good candidate\n     * @returns the required block or null if not found\n     */\n    public getBlockByPredicate(predicate: (block: NodeMaterialBlock) => boolean) {\n        for (const block of this.attachedBlocks) {\n            if (predicate(block)) {\n                return block;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Get an input block using a predicate\n     * @param predicate defines the predicate used to find the good candidate\n     * @returns the required input block or null if not found\n     */\n    public getInputBlockByPredicate(predicate: (block: InputBlock) => boolean): Nullable<InputBlock> {\n        for (const block of this.attachedBlocks) {\n            if (block.isInput && predicate(block as InputBlock)) {\n                return block as InputBlock;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Gets the list of input blocks attached to this material\n     * @returns an array of InputBlocks\n     */\n    public getInputBlocks() {\n        const blocks: InputBlock[] = [];\n        for (const block of this.attachedBlocks) {\n            if (block.isInput) {\n                blocks.push(block as InputBlock);\n            }\n        }\n\n        return blocks;\n    }\n\n    /**\n     * Adds a new optimizer to the list of optimizers\n     * @param optimizer defines the optimizers to add\n     * @returns the current material\n     */\n    public registerOptimizer(optimizer: NodeMaterialOptimizer) {\n        const index = this._optimizers.indexOf(optimizer);\n\n        if (index > -1) {\n            return;\n        }\n\n        this._optimizers.push(optimizer);\n\n        return this;\n    }\n\n    /**\n     * Remove an optimizer from the list of optimizers\n     * @param optimizer defines the optimizers to remove\n     * @returns the current material\n     */\n    public unregisterOptimizer(optimizer: NodeMaterialOptimizer) {\n        const index = this._optimizers.indexOf(optimizer);\n\n        if (index === -1) {\n            return;\n        }\n\n        this._optimizers.splice(index, 1);\n\n        return this;\n    }\n\n    /**\n     * Add a new block to the list of output nodes\n     * @param node defines the node to add\n     * @returns the current material\n     */\n    public addOutputNode(node: NodeMaterialBlock) {\n        if (node.target === null) {\n            throw new Error(\"This node is not meant to be an output node. You may want to explicitly set its target value.\");\n        }\n\n        if ((node.target & NodeMaterialBlockTargets.Vertex) !== 0) {\n            this._addVertexOutputNode(node);\n        }\n\n        if ((node.target & NodeMaterialBlockTargets.Fragment) !== 0) {\n            this._addFragmentOutputNode(node);\n        }\n\n        return this;\n    }\n\n    /**\n     * Remove a block from the list of root nodes\n     * @param node defines the node to remove\n     * @returns the current material\n     */\n    public removeOutputNode(node: NodeMaterialBlock) {\n        if (node.target === null) {\n            return this;\n        }\n\n        if ((node.target & NodeMaterialBlockTargets.Vertex) !== 0) {\n            this._removeVertexOutputNode(node);\n        }\n\n        if ((node.target & NodeMaterialBlockTargets.Fragment) !== 0) {\n            this._removeFragmentOutputNode(node);\n        }\n\n        return this;\n    }\n\n    private _addVertexOutputNode(node: NodeMaterialBlock) {\n        if (this._vertexOutputNodes.indexOf(node) !== -1) {\n            return;\n        }\n\n        node.target = NodeMaterialBlockTargets.Vertex;\n        this._vertexOutputNodes.push(node);\n\n        return this;\n    }\n\n    private _removeVertexOutputNode(node: NodeMaterialBlock) {\n        const index = this._vertexOutputNodes.indexOf(node);\n        if (index === -1) {\n            return;\n        }\n\n        this._vertexOutputNodes.splice(index, 1);\n\n        return this;\n    }\n\n    private _addFragmentOutputNode(node: NodeMaterialBlock) {\n        if (this._fragmentOutputNodes.indexOf(node) !== -1) {\n            return;\n        }\n\n        node.target = NodeMaterialBlockTargets.Fragment;\n        this._fragmentOutputNodes.push(node);\n\n        return this;\n    }\n\n    private _removeFragmentOutputNode(node: NodeMaterialBlock) {\n        const index = this._fragmentOutputNodes.indexOf(node);\n        if (index === -1) {\n            return;\n        }\n\n        this._fragmentOutputNodes.splice(index, 1);\n\n        return this;\n    }\n\n    /**\n     * Gets or sets a boolean indicating that alpha blending must be enabled no matter what alpha value or alpha channel of the FragmentBlock are\n     */\n    @serialize()\n    public forceAlphaBlending = false;\n\n    /**\n     * Gets whether the glow layer is supported\n     * @returns true if the glow layer is supported\n     */\n    public override get _supportGlowLayer() {\n        if (this._fragmentOutputNodes.length === 0) {\n            return false;\n        }\n\n        if (this._fragmentOutputNodes.some((f) => (f as FragmentOutputBlock).additionalColor && (f as FragmentOutputBlock).additionalColor.isConnected)) {\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Specifies if the material will require alpha blending\n     * @returns a boolean specifying if alpha blending is needed\n     */\n    public override needAlphaBlending(): boolean {\n        if (this.ignoreAlpha) {\n            return false;\n        }\n        return this.forceAlphaBlending || this.alpha < 1.0 || (this._sharedData && this._sharedData.hints.needAlphaBlending);\n    }\n\n    /**\n     * Specifies if this material should be rendered in alpha test mode\n     * @returns a boolean specifying if an alpha test is needed.\n     */\n    public override needAlphaTesting(): boolean {\n        return this._sharedData && this._sharedData.hints.needAlphaTesting;\n    }\n\n    private _processInitializeOnLink(block: NodeMaterialBlock, state: NodeMaterialBuildState, nodesToProcessForOtherBuildState: NodeMaterialBlock[], autoConfigure = true) {\n        if (block.target === NodeMaterialBlockTargets.VertexAndFragment) {\n            nodesToProcessForOtherBuildState.push(block);\n        } else if (state.target === NodeMaterialBlockTargets.Fragment && block.target === NodeMaterialBlockTargets.Vertex && block._preparationId !== this._buildId) {\n            nodesToProcessForOtherBuildState.push(block);\n        }\n        this._initializeBlock(block, state, nodesToProcessForOtherBuildState, autoConfigure);\n    }\n\n    private _attachBlock(node: NodeMaterialBlock) {\n        if (this.attachedBlocks.indexOf(node) === -1) {\n            if (node.isUnique) {\n                const className = node.getClassName();\n\n                for (const other of this.attachedBlocks) {\n                    if (other.getClassName() === className) {\n                        this._sharedData.raiseBuildError(`Cannot have multiple blocks of type ${className} in the same NodeMaterial`);\n                        return;\n                    }\n                }\n            }\n            this.attachedBlocks.push(node);\n        }\n    }\n\n    private _initializeBlock(node: NodeMaterialBlock, state: NodeMaterialBuildState, nodesToProcessForOtherBuildState: NodeMaterialBlock[], autoConfigure = true) {\n        node.initialize(state);\n        if (autoConfigure) {\n            node.autoConfigure(this);\n        }\n        node._preparationId = this._buildId;\n\n        this._attachBlock(node);\n\n        for (const input of node.inputs) {\n            input.associatedVariableName = \"\";\n\n            const connectedPoint = input.connectedPoint;\n            if (connectedPoint && !connectedPoint._preventBubbleUp) {\n                const block = connectedPoint.ownerBlock;\n                if (block !== node) {\n                    this._processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure);\n                }\n            }\n        }\n\n        // Loop\n        if (node.isLoop) {\n            // We need to keep the storage write block in the active blocks\n            const loopBlock = node as LoopBlock;\n            if (loopBlock.loopID.hasEndpoints) {\n                for (const endpoint of loopBlock.loopID.endpoints) {\n                    const block = endpoint.ownerBlock;\n                    if (block.outputs.length !== 0) {\n                        continue;\n                    }\n                    state._terminalBlocks.add(block); // Attach the storage write only\n                    this._processInitializeOnLink(block, state, nodesToProcessForOtherBuildState, autoConfigure);\n                }\n            }\n        } else if (node.isTeleportOut) {\n            // Teleportation\n            const teleport = node as NodeMaterialTeleportOutBlock;\n            if (teleport.entryPoint) {\n                this._processInitializeOnLink(teleport.entryPoint, state, nodesToProcessForOtherBuildState, autoConfigure);\n            }\n        }\n\n        for (const output of node.outputs) {\n            output.associatedVariableName = \"\";\n        }\n    }\n\n    private _resetDualBlocks(node: NodeMaterialBlock, id: number) {\n        if (node.target === NodeMaterialBlockTargets.VertexAndFragment) {\n            node.buildId = id;\n        }\n\n        for (const input of node.inputs) {\n            const connectedPoint = input.connectedPoint;\n            if (connectedPoint && !connectedPoint._preventBubbleUp) {\n                const block = connectedPoint.ownerBlock;\n                if (block !== node) {\n                    this._resetDualBlocks(block, id);\n                }\n            }\n        }\n\n        // If this is a teleport out, we need to reset the connected block\n        if (node.isTeleportOut) {\n            const teleportOut = node as NodeMaterialTeleportOutBlock;\n            if (teleportOut.entryPoint) {\n                this._resetDualBlocks(teleportOut.entryPoint, id);\n            }\n        } else if (node.isLoop) {\n            // Loop\n            const loopBlock = node as LoopBlock;\n            if (loopBlock.loopID.hasEndpoints) {\n                for (const endpoint of loopBlock.loopID.endpoints) {\n                    const block = endpoint.ownerBlock;\n                    if (block.outputs.length !== 0) {\n                        continue;\n                    }\n                    this._resetDualBlocks(block, id);\n                }\n            }\n        }\n    }\n\n    /**\n     * Remove a block from the current node material\n     * @param block defines the block to remove\n     */\n    public removeBlock(block: NodeMaterialBlock) {\n        const attachedBlockIndex = this.attachedBlocks.indexOf(block);\n        if (attachedBlockIndex > -1) {\n            this.attachedBlocks.splice(attachedBlockIndex, 1);\n        }\n\n        if (block.isFinalMerger) {\n            this.removeOutputNode(block);\n        }\n    }\n\n    /**\n     * Build the material and generates the inner effect\n     * @param verbose defines if the build should log activity\n     * @param updateBuildId defines if the internal build Id should be updated (default is true)\n     * @param autoConfigure defines if the autoConfigure method should be called when initializing blocks (default is false)\n     */\n    public build(verbose: boolean = false, updateBuildId = true, autoConfigure = false) {\n        if (this._buildIsInProgress) {\n            Logger.Warn(\"Build is already in progress, You can use NodeMaterial.onBuildObservable to determine when the build is completed.\");\n            return;\n        }\n        this._buildIsInProgress = true;\n        // First time?\n        if (!this._vertexCompilationState && !autoConfigure) {\n            autoConfigure = true;\n        }\n\n        this._buildWasSuccessful = false;\n        const engine = this.getScene().getEngine();\n\n        const allowEmptyVertexProgram = this._mode === NodeMaterialModes.Particle || this._mode === NodeMaterialModes.SFE;\n\n        if (this._vertexOutputNodes.length === 0 && !allowEmptyVertexProgram) {\n            this.onBuildErrorObservable.notifyObservers(\"You must define at least one vertexOutputNode\");\n            this._buildIsInProgress = false;\n            return;\n        }\n\n        if (this._fragmentOutputNodes.length === 0) {\n            this.onBuildErrorObservable.notifyObservers(\"You must define at least one fragmentOutputNode\");\n            this._buildIsInProgress = false;\n            return;\n        }\n\n        // Compilation state\n        this._vertexCompilationState = new NodeMaterialBuildState();\n        this._vertexCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;\n        this._vertexCompilationState.target = NodeMaterialBlockTargets.Vertex;\n        this._fragmentCompilationState = new NodeMaterialBuildState();\n        this._fragmentCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;\n        this._fragmentCompilationState.target = NodeMaterialBlockTargets.Fragment;\n\n        // Shared data\n        const needToPurgeList = this._fragmentOutputNodes.filter((n) => n._isFinalOutputAndActive).length > 1;\n        let fragmentOutputNodes = this._fragmentOutputNodes;\n\n        if (needToPurgeList) {\n            // Get all but the final output nodes\n            fragmentOutputNodes = this._fragmentOutputNodes.filter((n) => !n._isFinalOutputAndActive);\n\n            // Get the first with precedence on\n            fragmentOutputNodes.push(this._fragmentOutputNodes.filter((n) => n._isFinalOutputAndActive && n._hasPrecedence)[0]);\n        }\n\n        this._sharedData = new NodeMaterialBuildStateSharedData();\n        this._sharedData.nodeMaterial = this;\n        this._sharedData.fragmentOutputNodes = fragmentOutputNodes;\n        this._vertexCompilationState.sharedData = this._sharedData;\n        this._fragmentCompilationState.sharedData = this._sharedData;\n        this._sharedData.buildId = this._buildId;\n        this._sharedData.emitComments = this._options.emitComments;\n        this._sharedData.verbose = verbose;\n        this._sharedData.scene = this.getScene();\n        this._sharedData.allowEmptyVertexProgram = allowEmptyVertexProgram;\n\n        // Initialize blocks\n        const vertexNodes: NodeMaterialBlock[] = [];\n        const fragmentNodes: NodeMaterialBlock[] = [];\n\n        for (const vertexOutputNode of this._vertexOutputNodes) {\n            vertexNodes.push(vertexOutputNode);\n            this._initializeBlock(vertexOutputNode, this._vertexCompilationState, fragmentNodes, autoConfigure);\n        }\n\n        for (const fragmentOutputNode of fragmentOutputNodes) {\n            fragmentNodes.push(fragmentOutputNode);\n            this._initializeBlock(fragmentOutputNode, this._fragmentCompilationState, vertexNodes, autoConfigure);\n        }\n\n        // Are blocks code ready?\n        let waitingNodeCount = 0;\n        for (const node of this.attachedBlocks) {\n            if (!node.codeIsReady) {\n                waitingNodeCount++;\n                node.onCodeIsReadyObservable.addOnce(() => {\n                    waitingNodeCount--;\n                    if (waitingNodeCount === 0) {\n                        this._finishBuildProcess(verbose, updateBuildId, vertexNodes, fragmentNodes);\n                    }\n                });\n            }\n        }\n\n        if (waitingNodeCount !== 0) {\n            return;\n        }\n\n        this._finishBuildProcess(verbose, updateBuildId, vertexNodes, fragmentNodes);\n    }\n\n    private _finishBuildProcess(verbose: boolean = false, updateBuildId = true, vertexNodes: NodeMaterialBlock[], fragmentNodes: NodeMaterialBlock[]) {\n        // Optimize\n        this.optimize();\n\n        // Vertex\n        for (const vertexOutputNode of vertexNodes) {\n            vertexOutputNode.build(this._vertexCompilationState, vertexNodes);\n        }\n\n        // Fragment\n        this._fragmentCompilationState.uniforms = this._vertexCompilationState.uniforms.slice(0);\n        this._fragmentCompilationState._uniformDeclaration = this._vertexCompilationState._uniformDeclaration;\n        this._fragmentCompilationState._constantDeclaration = this._vertexCompilationState._constantDeclaration;\n        this._fragmentCompilationState._vertexState = this._vertexCompilationState;\n\n        for (const fragmentOutputNode of fragmentNodes) {\n            this._resetDualBlocks(fragmentOutputNode, this._buildId - 1);\n        }\n\n        for (const fragmentOutputNode of fragmentNodes) {\n            fragmentOutputNode.build(this._fragmentCompilationState, fragmentNodes);\n        }\n\n        // Finalize\n        this._vertexCompilationState.finalize(this._vertexCompilationState);\n        this._fragmentCompilationState.finalize(this._fragmentCompilationState);\n\n        if (updateBuildId) {\n            this._buildId = NodeMaterial._BuildIdGenerator++;\n        }\n\n        if (verbose) {\n            Logger.Log(\"Vertex shader:\");\n            Logger.Log(this._vertexCompilationState.compilationString);\n            Logger.Log(\"Fragment shader:\");\n            Logger.Log(this._fragmentCompilationState.compilationString);\n        }\n\n        // Errors\n        const noError = this._sharedData.emitErrors();\n\n        this._buildIsInProgress = false;\n        if (noError) {\n            this._buildWasSuccessful = true;\n            this.onBuildObservable.notifyObservers(this);\n        }\n\n        // Wipe defines\n        const meshes = this.getScene().meshes;\n        for (const mesh of meshes) {\n            if (!mesh.subMeshes) {\n                continue;\n            }\n            for (const subMesh of mesh.subMeshes) {\n                if (subMesh.getMaterial() !== this) {\n                    continue;\n                }\n\n                if (!subMesh.materialDefines) {\n                    continue;\n                }\n\n                const defines = subMesh.materialDefines;\n                defines.markAllAsDirty();\n                defines.reset();\n            }\n        }\n\n        if (this.prePassTextureInputs.length) {\n            this.getScene().enablePrePassRenderer();\n        }\n        const prePassRenderer = this.getScene().prePassRenderer;\n        if (prePassRenderer) {\n            prePassRenderer.markAsDirty();\n        }\n    }\n\n    /**\n     * Runs an optimization phase to try to improve the shader code\n     */\n    public optimize() {\n        for (const optimizer of this._optimizers) {\n            optimizer.optimize(this._vertexOutputNodes, this._fragmentOutputNodes);\n        }\n    }\n\n    private _prepareDefinesForAttributes(mesh: AbstractMesh, defines: NodeMaterialDefines) {\n        const oldNormal = defines[\"NORMAL\"];\n        const oldTangent = defines[\"TANGENT\"];\n        const oldColor = defines[\"VERTEXCOLOR_NME\"];\n\n        defines[\"NORMAL\"] = mesh.isVerticesDataPresent(VertexBuffer.NormalKind);\n        defines[\"TANGENT\"] = mesh.isVerticesDataPresent(VertexBuffer.TangentKind);\n\n        const hasVertexColors = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);\n        defines[\"VERTEXCOLOR_NME\"] = hasVertexColors;\n\n        let uvChanged = false;\n        for (let i = 1; i <= Constants.MAX_SUPPORTED_UV_SETS; ++i) {\n            const oldUV = defines[\"UV\" + i];\n            defines[\"UV\" + i] = mesh.isVerticesDataPresent(`uv${i === 1 ? \"\" : i}`);\n            uvChanged = uvChanged || defines[\"UV\" + i] !== oldUV;\n        }\n\n        // PrePass\n        const oit = this.needAlphaBlendingForMesh(mesh) && this.getScene().useOrderIndependentTransparency;\n        PrepareDefinesForPrePass(this.getScene(), defines, !oit);\n\n        MaterialHelperGeometryRendering.PrepareDefines(this.getScene().getEngine().currentRenderPassId, mesh, defines);\n\n        if (oldNormal !== defines[\"NORMAL\"] || oldTangent !== defines[\"TANGENT\"] || oldColor !== defines[\"VERTEXCOLOR_NME\"] || uvChanged) {\n            defines.markAsAttributesDirty();\n        }\n    }\n\n    /**\n     * Can this material render to prepass\n     */\n    public override get isPrePassCapable(): boolean {\n        return true;\n    }\n\n    /**\n     * Outputs written to the prepass\n     */\n    public get prePassTextureOutputs(): number[] {\n        const prePassOutputBlock = this.getBlockByPredicate((block) => block.getClassName() === \"PrePassOutputBlock\") as PrePassOutputBlock;\n        const result = [Constants.PREPASS_COLOR_TEXTURE_TYPE];\n        if (!prePassOutputBlock) {\n            return result;\n        }\n        // Cannot write to prepass if we alread read from prepass\n        if (this.prePassTextureInputs.length) {\n            return result;\n        }\n\n        if (prePassOutputBlock.viewDepth.isConnected) {\n            result.push(Constants.PREPASS_DEPTH_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.screenDepth.isConnected) {\n            result.push(Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.viewNormal.isConnected) {\n            result.push(Constants.PREPASS_NORMAL_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.worldNormal.isConnected) {\n            result.push(Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.worldPosition.isConnected) {\n            result.push(Constants.PREPASS_POSITION_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.localPosition.isConnected) {\n            result.push(Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.reflectivity.isConnected) {\n            result.push(Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.velocity.isConnected) {\n            result.push(Constants.PREPASS_VELOCITY_TEXTURE_TYPE);\n        }\n\n        if (prePassOutputBlock.velocityLinear.isConnected) {\n            result.push(Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE);\n        }\n\n        return result;\n    }\n\n    /**\n     * Gets the list of prepass texture required\n     */\n    public get prePassTextureInputs(): number[] {\n        const prePassTextureBlocks = this.getAllTextureBlocks().filter((block) => block.getClassName() === \"PrePassTextureBlock\") as PrePassTextureBlock[];\n        const result = [] as number[];\n\n        for (const block of prePassTextureBlocks) {\n            if (block.position.isConnected && !result.includes(Constants.PREPASS_POSITION_TEXTURE_TYPE)) {\n                result.push(Constants.PREPASS_POSITION_TEXTURE_TYPE);\n            }\n            if (block.localPosition.isConnected && !result.includes(Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE)) {\n                result.push(Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE);\n            }\n            if (block.depth.isConnected && !result.includes(Constants.PREPASS_DEPTH_TEXTURE_TYPE)) {\n                result.push(Constants.PREPASS_DEPTH_TEXTURE_TYPE);\n            }\n            if (block.screenDepth.isConnected && !result.includes(Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE)) {\n                result.push(Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE);\n            }\n            if (block.normal.isConnected && !result.includes(Constants.PREPASS_NORMAL_TEXTURE_TYPE)) {\n                result.push(Constants.PREPASS_NORMAL_TEXTURE_TYPE);\n            }\n            if (block.worldNormal.isConnected && !result.includes(Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE)) {\n                result.push(Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE);\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Sets the required values to the prepass renderer.\n     * @param prePassRenderer defines the prepass renderer to set\n     * @returns true if the pre pass is needed\n     */\n    public override setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {\n        const prePassTexturesRequired = this.prePassTextureInputs.concat(this.prePassTextureOutputs);\n\n        if (prePassRenderer && prePassTexturesRequired.length > 1) {\n            let cfg = prePassRenderer.getEffectConfiguration(\"nodeMaterial\");\n            if (!cfg) {\n                cfg = prePassRenderer.addEffectConfiguration({\n                    enabled: true,\n                    needsImageProcessing: false,\n                    name: \"nodeMaterial\",\n                    texturesRequired: [],\n                });\n            }\n            for (const prePassTexture of prePassTexturesRequired) {\n                if (!cfg.texturesRequired.includes(prePassTexture)) {\n                    cfg.texturesRequired.push(prePassTexture);\n                }\n            }\n            cfg.enabled = true;\n        }\n\n        // COLOR_TEXTURE is always required for prepass, length > 1 means\n        // we actually need to write to special prepass textures\n        return prePassTexturesRequired.length > 1;\n    }\n\n    /**\n     * Create a post process from the material\n     * @param camera The camera to apply the render pass to.\n     * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\n     * @param engine The engine which the post process will be applied. (default: current engine)\n     * @param reusable If the post process can be reused on the same frame. (default: false)\n     * @param textureType Type of textures used when performing the post process. (default: 0)\n     * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)\n     * @returns the post process created\n     */\n    public createPostProcess(\n        camera: Nullable<Camera>,\n        options: number | PostProcessOptions = 1,\n        samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n        engine?: AbstractEngine,\n        reusable?: boolean,\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\n        textureFormat = Constants.TEXTUREFORMAT_RGBA\n    ): Nullable<PostProcess> {\n        if (this.mode !== NodeMaterialModes.PostProcess && this.mode !== NodeMaterialModes.SFE) {\n            Logger.Log(\"Incompatible material mode\");\n            return null;\n        }\n        return this._createEffectForPostProcess(null, camera, options, samplingMode, engine, reusable, textureType, textureFormat);\n    }\n\n    /**\n     * Create the post process effect from the material\n     * @param postProcess The post process to create the effect for\n     */\n    public createEffectForPostProcess(postProcess: PostProcess) {\n        this._createEffectForPostProcess(postProcess);\n    }\n\n    private _createEffectForPostProcess(\n        postProcess: Nullable<PostProcess>,\n        camera?: Nullable<Camera>,\n        options: number | PostProcessOptions = 1,\n        samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n        engine?: AbstractEngine,\n        reusable?: boolean,\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\n        textureFormat = Constants.TEXTUREFORMAT_RGBA\n    ): PostProcess {\n        // The post process effect is built from the shader code produced by the node graph. That code\n        // is only available once the build has completed. Some blocks (e.g. CurrentScreenBlock) load\n        // their shader sources asynchronously, so the build may still be running when this is called\n        // (for instance right after a synchronous NodeMaterial.Parse). Registering the still empty\n        // shaders would make the engine try to fetch them from a URL and fail with a 404, leaving the\n        // post process blank. Defer the effect creation until the build has completed.\n        if (!this._buildWasSuccessful) {\n            if (!postProcess) {\n                // Create the handle now with compilation blocked so callers can attach their observers;\n                // the actual effect is created once the build completes.\n                postProcess = new PostProcess(\n                    this.name + \"PostProcess\",\n                    \"postprocess\",\n                    null,\n                    null,\n                    options,\n                    camera!,\n                    samplingMode,\n                    engine,\n                    reusable,\n                    null,\n                    textureType,\n                    \"postprocess\",\n                    undefined,\n                    true,\n                    textureFormat,\n                    this.shaderLanguage\n                );\n                postProcess.nodeMaterialSource = this;\n            }\n\n            const deferredPostProcess = postProcess;\n            this.onBuildObservable.addOnce(() => {\n                this._createEffectForPostProcess(deferredPostProcess, camera, options, samplingMode, engine, reusable, textureType, textureFormat);\n            });\n\n            if (!this._buildIsInProgress) {\n                this.build();\n            }\n\n            return postProcess;\n        }\n\n        let tempName = this.name + this._buildId;\n\n        const defines = new NodeMaterialDefines();\n\n        let buildId = this._buildId;\n\n        this._processDefines(defines);\n\n        // If no vertex shader emitted, fallback to default postprocess vertex shader\n        const vertexCode = this._sharedData.checks.emitVertex ? this._vertexCompilationState._builtCompilationString : undefined;\n\n        Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, vertexCode, this.shaderLanguage);\n\n        if (!postProcess) {\n            postProcess = new PostProcess(\n                this.name + \"PostProcess\",\n                tempName,\n                this._fragmentCompilationState.uniforms,\n                this._fragmentCompilationState.samplers,\n                options,\n                camera!,\n                samplingMode,\n                engine,\n                reusable,\n                defines.toString(),\n                textureType,\n                vertexCode ? tempName : \"postprocess\",\n                { maxSimultaneousLights: this.maxSimultaneousLights },\n                false,\n                textureFormat,\n                this.shaderLanguage\n            );\n        } else {\n            postProcess.updateEffect(\n                defines.toString(),\n                this._fragmentCompilationState.uniforms,\n                this._fragmentCompilationState.samplers,\n                { maxSimultaneousLights: this.maxSimultaneousLights },\n                undefined,\n                undefined,\n                vertexCode ? tempName : \"postprocess\",\n                tempName\n            );\n        }\n\n        postProcess.nodeMaterialSource = this;\n\n        postProcess.onApplyObservable.add((effect) => {\n            if (buildId !== this._buildId) {\n                delete Effect.ShadersStore[tempName + \"VertexShader\"];\n                delete Effect.ShadersStore[tempName + \"PixelShader\"];\n\n                tempName = this.name + this._buildId;\n\n                defines.markAllAsDirty();\n\n                buildId = this._buildId;\n            }\n\n            const result = this._processDefines(defines);\n\n            if (result) {\n                // Recompute the vertex emission for the current build (the graph may have been rebuilt),\n                // and register with the material's shader language so WGSL post processes use the WGSL store.\n                const currentVertexCode = this._sharedData.checks.emitVertex ? this._vertexCompilationState._builtCompilationString : undefined;\n\n                Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, currentVertexCode, this.shaderLanguage);\n\n                TimingTools.SetImmediate(() =>\n                    postProcess.updateEffect(\n                        defines.toString(),\n                        this._fragmentCompilationState.uniforms,\n                        this._fragmentCompilationState.samplers,\n                        { maxSimultaneousLights: this.maxSimultaneousLights },\n                        undefined,\n                        undefined,\n                        currentVertexCode ? tempName : \"postprocess\",\n                        tempName\n                    )\n                );\n            }\n\n            this._checkInternals(effect);\n        });\n\n        return postProcess;\n    }\n\n    /**\n     * Create a new procedural texture based on this node material\n     * @param size defines the size of the texture\n     * @param scene defines the hosting scene\n     * @returns the new procedural texture attached to this node material\n     */\n    public createProceduralTexture(size: number | { width: number; height: number; layers?: number }, scene: Scene): Nullable<ProceduralTexture> {\n        if (this.mode !== NodeMaterialModes.ProceduralTexture) {\n            Logger.Log(\"Incompatible material mode\");\n            return null;\n        }\n\n        let tempName = this.name + this._buildId;\n\n        const proceduralTexture = new ProceduralTexture(tempName, size, null, scene);\n        proceduralTexture.nodeMaterialSource = this;\n\n        const defines = new NodeMaterialDefines();\n\n        let buildId = this._buildId;\n        let effect: Effect | undefined;\n\n        const refreshEffect = () => {\n            if (buildId !== this._buildId) {\n                delete Effect.ShadersStore[tempName + \"VertexShader\"];\n                delete Effect.ShadersStore[tempName + \"PixelShader\"];\n\n                tempName = this.name + this._buildId;\n\n                defines.markAllAsDirty();\n\n                buildId = this._buildId;\n            }\n\n            const result = this._processDefines(defines);\n\n            if (result) {\n                Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, this._vertexCompilationState._builtCompilationString, this.shaderLanguage);\n\n                TimingTools.SetImmediate(() => {\n                    // The material may have been disposed before this deferred effect creation runs.\n                    if (!this._fragmentCompilationState) {\n                        return;\n                    }\n\n                    effect = this.getScene().getEngine().createEffect(\n                        {\n                            vertexElement: tempName,\n                            fragmentElement: tempName,\n                        },\n                        [VertexBuffer.PositionKind],\n                        this._fragmentCompilationState.uniforms,\n                        this._fragmentCompilationState.samplers,\n                        defines.toString(),\n                        result?.fallbacks,\n                        undefined,\n                        undefined,\n                        undefined,\n                        this.shaderLanguage\n                    );\n\n                    proceduralTexture._setEffect(effect);\n                });\n            }\n\n            if (effect) {\n                this._checkInternals(effect);\n            }\n        };\n\n        proceduralTexture.onBeforeGenerationObservable.add(() => {\n            refreshEffect();\n        });\n\n        // This is needed if the procedural texture is not set to refresh automatically\n        this.onBuildObservable.add(() => {\n            refreshEffect();\n        });\n\n        // The effect is built from the shader code produced by the node graph, which is only available\n        // once the build has completed. Some blocks (e.g. CurrentScreenBlock) load their shader sources\n        // asynchronously, so the build may still be running here (for instance right after a synchronous\n        // NodeMaterial.Parse). Creating the effect now would register empty shaders and make the engine\n        // fetch them from a URL, failing with a 404. Only create the effect once the build has\n        // succeeded; otherwise the onBuildObservable hook above creates it when the build completes.\n        if (this._buildWasSuccessful) {\n            const result = this._processDefines(defines);\n            Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, this._vertexCompilationState._builtCompilationString, this.shaderLanguage);\n\n            effect = this.getScene().getEngine().createEffect(\n                {\n                    vertexElement: tempName,\n                    fragmentElement: tempName,\n                },\n                [VertexBuffer.PositionKind],\n                this._fragmentCompilationState.uniforms,\n                this._fragmentCompilationState.samplers,\n                defines.toString(),\n                result?.fallbacks,\n                undefined,\n                undefined,\n                undefined,\n                this.shaderLanguage\n            );\n\n            proceduralTexture._setEffect(effect);\n        } else if (!this._buildIsInProgress) {\n            this.build();\n        }\n\n        return proceduralTexture;\n    }\n\n    private _createEffectForParticles(\n        particleSystem: IParticleSystem,\n        blendMode: number,\n        onCompiled?: (effect: Effect) => void,\n        onError?: (effect: Effect, errors: string) => void,\n        effect?: Effect,\n        defines?: NodeMaterialDefines,\n        particleSystemDefinesJoined = \"\"\n    ) {\n        let tempName = this.name + this._buildId + \"_\" + blendMode;\n\n        if (!defines) {\n            defines = new NodeMaterialDefines();\n        }\n\n        let buildId = this._buildId;\n\n        const particleSystemDefines: Array<string> = [];\n        let join = particleSystemDefinesJoined;\n\n        if (!effect) {\n            const result = this._processDefines(defines);\n\n            Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, undefined, this.shaderLanguage);\n\n            particleSystem.fillDefines(particleSystemDefines, blendMode, false);\n\n            join = particleSystemDefines.join(\"\\n\");\n\n            effect = this.getScene()\n                .getEngine()\n                .createEffectForParticles(\n                    tempName,\n                    this._fragmentCompilationState.uniforms,\n                    this._fragmentCompilationState.samplers,\n                    defines.toString() + \"\\n\" + join,\n                    result?.fallbacks,\n                    onCompiled,\n                    onError,\n                    particleSystem,\n                    this.shaderLanguage\n                );\n\n            particleSystem.setCustomEffect(effect, blendMode);\n        }\n\n        effect.onBindObservable.add((effect) => {\n            if (buildId !== this._buildId) {\n                delete Effect.ShadersStore[tempName + \"PixelShader\"];\n\n                tempName = this.name + this._buildId + \"_\" + blendMode;\n\n                defines.markAllAsDirty();\n\n                buildId = this._buildId;\n            }\n\n            particleSystemDefines.length = 0;\n\n            particleSystem.fillDefines(particleSystemDefines, blendMode, false);\n\n            const particleSystemDefinesJoinedCurrent = particleSystemDefines.join(\"\\n\");\n\n            if (particleSystemDefinesJoinedCurrent !== join) {\n                defines.markAllAsDirty();\n                join = particleSystemDefinesJoinedCurrent;\n            }\n\n            const result = this._processDefines(defines);\n\n            if (result) {\n                Effect.RegisterShader(tempName, this._fragmentCompilationState._builtCompilationString, undefined, this.shaderLanguage);\n\n                effect = this.getScene()\n                    .getEngine()\n                    .createEffectForParticles(\n                        tempName,\n                        this._fragmentCompilationState.uniforms,\n                        this._fragmentCompilationState.samplers,\n                        defines.toString() + \"\\n\" + join,\n                        result?.fallbacks,\n                        onCompiled,\n                        onError,\n                        particleSystem\n                    );\n                particleSystem.setCustomEffect(effect, blendMode);\n                this._createEffectForParticles(particleSystem, blendMode, onCompiled, onError, effect, defines, particleSystemDefinesJoined); // add the effect.onBindObservable observer\n                return;\n            }\n\n            this._checkInternals(effect);\n        });\n    }\n\n    private _checkInternals(effect: Effect) {\n        // Animated blocks\n        if (this._sharedData.animatedInputs) {\n            const scene = this.getScene();\n\n            const frameId = scene.getFrameId();\n\n            if (this._animationFrame !== frameId) {\n                for (const input of this._sharedData.animatedInputs) {\n                    input.animate(scene);\n                }\n\n                this._animationFrame = frameId;\n            }\n        }\n\n        // Bindable blocks\n        for (const block of this._sharedData.bindableBlocks) {\n            block.bind(effect, this);\n        }\n\n        // Connection points\n        for (const inputBlock of this._sharedData.inputBlocks) {\n            inputBlock._transmit(effect, this.getScene(), this);\n        }\n    }\n\n    /**\n     * Create the effect to be used as the custom effect for a particle system.\n     * If the material has not been built successfully yet, the build is started when needed and the effect is only\n     * created once it completes, so the effect may not be set on the particle system when this method returns.\n     * @param particleSystem Particle system to create the effect for\n     * @param onCompiled defines a function to call when the effect creation is successful\n     * @param onError defines a function to call when the effect creation has failed\n     */\n    public createEffectForParticles(particleSystem: IParticleSystem, onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void) {\n        if (this.mode !== NodeMaterialModes.Particle) {\n            Logger.Log(\"Incompatible material mode\");\n            return;\n        }\n\n        // ParticleTextureBlock loads shader includes asynchronously. Wait for the build to produce\n        // shader code instead of registering an empty fragment shader that falls back to a URL.\n        if (!this._buildWasSuccessful) {\n            const buildObserver = this.onBuildObservable.addOnce(() => {\n                this.onBuildErrorObservable.remove(errorObserver);\n                this.createEffectForParticles(particleSystem, onCompiled, onError);\n            });\n            const errorObserver = this.onBuildErrorObservable.addOnce(() => {\n                this.onBuildObservable.remove(buildObserver);\n            });\n\n            if (!this._buildIsInProgress) {\n                this.build();\n            }\n\n            return;\n        }\n\n        this._createEffectForParticles(particleSystem, BaseParticleSystem.BLENDMODE_ONEONE, onCompiled, onError);\n        this._createEffectForParticles(particleSystem, BaseParticleSystem.BLENDMODE_MULTIPLY, onCompiled, onError);\n    }\n\n    /**\n     * Use this material as the shadow depth wrapper of a target material\n     * @param targetMaterial defines the target material\n     */\n    public createAsShadowDepthWrapper(targetMaterial: Material) {\n        if (this.mode !== NodeMaterialModes.Material) {\n            Logger.Log(\"Incompatible material mode\");\n            return;\n        }\n\n        targetMaterial.shadowDepthWrapper = new BABYLON.ShadowDepthWrapper(this, this.getScene());\n    }\n\n    private _processDefines(\n        defines: NodeMaterialDefines,\n        mesh?: AbstractMesh,\n        useInstances = false,\n        subMesh?: SubMesh\n    ): Nullable<{\n        lightDisposed: boolean;\n        uniformBuffers: string[];\n        mergedUniforms: string[];\n        mergedSamplers: string[];\n        fallbacks: EffectFallbacks;\n    }> {\n        let result = null;\n\n        // Global defines\n        const scene = this.getScene();\n        if (PrepareDefinesForCamera(scene, defines)) {\n            defines.markAsMiscDirty();\n        }\n\n        // Shared defines\n        for (const b of this._sharedData.blocksWithDefines) {\n            b.initializeDefines(defines);\n        }\n\n        for (const b of this._sharedData.blocksWithDefines) {\n            b.prepareDefines(defines, this, mesh, useInstances, subMesh);\n        }\n\n        for (const d in this._sharedData.defines) {\n            defines[d] = this._sharedData.defines[d];\n        }\n\n        // Need to recompile?\n        if (defines.isDirty) {\n            const lightDisposed = defines._areLightsDisposed;\n            defines.markAsProcessed();\n\n            // Repeatable content generators\n            this._vertexCompilationState.compilationString = this._vertexCompilationState._builtCompilationString;\n            this._fragmentCompilationState.compilationString = this._fragmentCompilationState._builtCompilationString;\n\n            for (const b of this._sharedData.repeatableContentBlocks) {\n                b.replaceRepeatableContent(this._vertexCompilationState, defines, mesh);\n            }\n\n            // Uniforms\n            const uniformBuffers: string[] = [];\n            for (const b of this._sharedData.dynamicUniformBlocks) {\n                b.updateUniformsAndSamples(this._vertexCompilationState, this, defines, uniformBuffers);\n            }\n\n            const mergedUniforms = this._vertexCompilationState.uniforms;\n\n            for (const u of this._fragmentCompilationState.uniforms) {\n                const index = mergedUniforms.indexOf(u);\n\n                if (index === -1) {\n                    mergedUniforms.push(u);\n                }\n            }\n\n            // Samplers\n            const mergedSamplers = this._vertexCompilationState.samplers;\n\n            for (const s of this._fragmentCompilationState.samplers) {\n                const index = mergedSamplers.indexOf(s);\n\n                if (index === -1) {\n                    mergedSamplers.push(s);\n                }\n            }\n\n            const fallbacks = new EffectFallbacks();\n\n            for (const b of this._sharedData.blocksWithFallbacks) {\n                b.provideFallbacks(fallbacks, mesh);\n            }\n\n            result = {\n                lightDisposed,\n                uniformBuffers,\n                mergedUniforms,\n                mergedSamplers,\n                fallbacks,\n            };\n        }\n\n        return result;\n    }\n\n    /**\n     * Get if the submesh is ready to be used and all its information available.\n     * Child classes can use it to update shaders\n     * @param mesh defines the mesh to check\n     * @param subMesh defines which submesh to check\n     * @param useInstances specifies that instances should be used\n     * @returns a boolean indicating that the submesh is ready or not\n     */\n    public override isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances: boolean = false): boolean {\n        if (!this._buildWasSuccessful) {\n            return false;\n        }\n\n        const scene = this.getScene();\n        if (this._sharedData.animatedInputs) {\n            const frameId = scene.getFrameId();\n\n            if (this._animationFrame !== frameId) {\n                for (const input of this._sharedData.animatedInputs) {\n                    input.animate(scene);\n                }\n\n                this._animationFrame = frameId;\n            }\n        }\n\n        const drawWrapper = subMesh._drawWrapper;\n\n        if (drawWrapper.effect && this.isFrozen) {\n            if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {\n                return true;\n            }\n        }\n\n        if (!subMesh.materialDefines) {\n            subMesh.materialDefines = new NodeMaterialDefines();\n        }\n\n        const defines = <NodeMaterialDefines>subMesh.materialDefines;\n        if (this._isReadyForSubMesh(subMesh)) {\n            return true;\n        }\n\n        const engine = scene.getEngine();\n\n        this._prepareDefinesForAttributes(mesh, defines);\n\n        // Check if blocks are ready\n        if (this._sharedData.blockingBlocks.some((b) => !b.isReady(mesh, this, defines, useInstances))) {\n            return false;\n        }\n\n        if (!AreLightsTexturesReady(scene, mesh, this.maxSimultaneousLights)) {\n            return false;\n        }\n\n        const result = this._processDefines(defines, mesh, useInstances, subMesh);\n\n        if (result) {\n            const previousEffect = subMesh.effect;\n            // Compilation\n            const join = defines.toString();\n            const effect = engine.createEffect(\n                {\n                    vertex: \"nodeMaterial\" + this._buildId,\n                    fragment: \"nodeMaterial\" + this._buildId,\n                    vertexSource: this._vertexCompilationState.compilationString,\n                    fragmentSource: this._fragmentCompilationState.compilationString,\n                },\n                <IEffectCreationOptions>{\n                    attributes: this._vertexCompilationState.attributes,\n                    uniformsNames: result.mergedUniforms,\n                    uniformBuffersNames: result.uniformBuffers,\n                    samplers: result.mergedSamplers,\n                    defines: join,\n                    fallbacks: result.fallbacks,\n                    onCompiled: this.onCompiled,\n                    onError: this.onError,\n                    multiTarget: defines.PREPASS,\n                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS },\n                    shaderLanguage: this.shaderLanguage,\n                },\n                engine\n            );\n\n            if (effect) {\n                if (this._onEffectCreatedObservable) {\n                    onCreatedEffectParameters.effect = effect;\n                    onCreatedEffectParameters.subMesh = subMesh;\n                    this._onEffectCreatedObservable.notifyObservers(onCreatedEffectParameters);\n                }\n\n                // Use previous effect while new one is compiling\n                if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {\n                    defines.markAsUnprocessed();\n\n                    if (result.lightDisposed) {\n                        // re register in case it takes more than one frame.\n                        defines._areLightsDisposed = true;\n                        return false;\n                    }\n                } else {\n                    scene.resetCachedMaterial();\n                    subMesh.setEffect(effect, defines, this._materialContext);\n                }\n            }\n        }\n\n        // Check if lights are ready\n        if (defines[\"AREALIGHTUSED\"] || defines[\"CLUSTLIGHT_BATCH\"]) {\n            for (let index = 0; index < mesh.lightSources.length; index++) {\n                if (!mesh.lightSources[index]._isReady()) {\n                    return false;\n                }\n            }\n        }\n\n        if (!subMesh.effect || !subMesh.effect.isReady()) {\n            return false;\n        }\n\n        defines._renderId = scene.getRenderId();\n        drawWrapper._wasPreviouslyReady = true;\n        drawWrapper._wasPreviouslyUsingInstances = useInstances;\n\n        this._checkScenePerformancePriority();\n\n        return true;\n    }\n\n    /**\n     * Get a string representing the shaders built by the current node graph\n     */\n    public get compiledShaders() {\n        if (!this._buildWasSuccessful) {\n            this.build();\n        }\n        return `// Vertex shader\\n${this._vertexCompilationState.compilationString}\\n\\n// Fragment shader\\n${this._fragmentCompilationState.compilationString}`;\n    }\n\n    /**\n     * Get a string representing the fragment shader used by the engine for the current node graph\n     * @internal\n     */\n    public async _getProcessedFragmentAsync(): Promise<string> {\n        if (!this._buildWasSuccessful) {\n            this.build();\n        }\n\n        const defines = new NodeMaterialDefines();\n        this._processDefines(defines);\n\n        let processingDefines = defines.toString();\n        if (this.mode === NodeMaterialModes.SFE) {\n            processingDefines += `#define ${SfeModeDefine}\\n`;\n        }\n\n        return await this._fragmentCompilationState.getProcessedShaderAsync(processingDefines);\n    }\n\n    /**\n     * Binds the world matrix to the material\n     * @param world defines the world transformation matrix\n     */\n    public override bindOnlyWorldMatrix(world: Matrix): void {\n        const scene = this.getScene();\n\n        if (!this._activeEffect) {\n            return;\n        }\n\n        const hints = this._sharedData.hints;\n\n        if (hints.needWorldViewMatrix) {\n            world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);\n        }\n\n        if (hints.needWorldViewProjectionMatrix) {\n            world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);\n        }\n\n        // Connection points\n        for (const inputBlock of this._sharedData.inputBlocks) {\n            inputBlock._transmitWorld(this._activeEffect, world, this._cachedWorldViewMatrix, this._cachedWorldViewProjectionMatrix);\n        }\n    }\n\n    /**\n     * Binds the submesh to this material by preparing the effect and shader to draw\n     * @param world defines the world transformation matrix\n     * @param mesh defines the mesh containing the submesh\n     * @param subMesh defines the submesh to bind the material to\n     */\n    public override bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {\n        const scene = this.getScene();\n        const effect = subMesh.effect;\n        if (!effect) {\n            return;\n        }\n        this._activeEffect = effect;\n\n        // Matrices\n        this.bindOnlyWorldMatrix(world);\n\n        MaterialHelperGeometryRendering.Bind(scene.getEngine().currentRenderPassId, effect, mesh, world, this);\n\n        const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);\n        const sharedData = this._sharedData;\n\n        if (mustRebind) {\n            // Bindable blocks\n            for (const block of sharedData.bindableBlocks) {\n                block.bind(effect, this, mesh, subMesh);\n            }\n\n            for (const block of sharedData.forcedBindableBlocks) {\n                block.bind(effect, this, mesh, subMesh);\n            }\n\n            // Connection points\n            for (const inputBlock of sharedData.inputBlocks) {\n                inputBlock._transmit(effect, scene, this);\n            }\n        } else if (!this.isFrozen) {\n            for (const block of sharedData.forcedBindableBlocks) {\n                block.bind(effect, this, mesh, subMesh);\n            }\n        }\n\n        this._afterBind(mesh, this._activeEffect, subMesh);\n    }\n\n    /**\n     * Gets the active textures from the material\n     * @returns an array of textures\n     */\n    public override getActiveTextures(): BaseTexture[] {\n        const activeTextures = super.getActiveTextures();\n\n        if (this._sharedData) {\n            activeTextures.push(...this._sharedData.textureBlocks.filter((tb) => tb.texture).map((tb) => tb.texture!));\n        }\n\n        return activeTextures;\n    }\n\n    /**\n     * Gets the list of texture blocks\n     * Note that this method will only return blocks that are reachable from the final block(s) and only after the material has been built!\n     * @returns an array of texture blocks\n     */\n    public getTextureBlocks(): NodeMaterialTextureBlocks[] {\n        if (!this._sharedData) {\n            return [];\n        }\n\n        return this._sharedData.textureBlocks;\n    }\n\n    /**\n     * Gets the list of all texture blocks\n     * Note that this method will scan all attachedBlocks and return blocks that are texture blocks\n     * @returns\n     */\n    public getAllTextureBlocks(): NodeMaterialTextureBlocks[] {\n        const textureBlocks: NodeMaterialTextureBlocks[] = [];\n\n        for (const block of this.attachedBlocks) {\n            if (NodeMaterialBlockIsTextureBlock(block)) {\n                textureBlocks.push(block);\n            }\n        }\n\n        return textureBlocks;\n    }\n\n    /**\n     * Specifies if the material uses a texture\n     * @param texture defines the texture to check against the material\n     * @returns a boolean specifying if the material uses the texture\n     */\n    public override hasTexture(texture: BaseTexture): boolean {\n        if (super.hasTexture(texture)) {\n            return true;\n        }\n\n        if (!this._sharedData) {\n            return false;\n        }\n\n        for (const t of this._sharedData.textureBlocks) {\n            if (t.texture === texture) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Disposes the material\n     * @param forceDisposeEffect specifies if effects should be forcefully disposed\n     * @param forceDisposeTextures specifies if textures should be forcefully disposed\n     * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh\n     */\n    public override dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, notBoundToMesh?: boolean): void {\n        if (forceDisposeTextures) {\n            for (const texture of this.getTextureBlocks()\n                .filter((tb) => tb.texture)\n                .map((tb) => tb.texture!)) {\n                texture.dispose();\n            }\n        }\n\n        for (const block of this.attachedBlocks) {\n            block.dispose();\n        }\n\n        this.attachedBlocks.length = 0;\n        (this._sharedData as any) = null;\n        (this._vertexCompilationState as any) = null;\n        (this._fragmentCompilationState as any) = null;\n\n        this.onBuildObservable.clear();\n        this.onBuildErrorObservable.clear();\n\n        if (this._imageProcessingObserver) {\n            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);\n            this._imageProcessingObserver = null;\n        }\n\n        super.dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh);\n    }\n\n    /** Creates the node editor window.\n     * @param additionalConfig Define the configuration of the editor\n     */\n    private _createNodeEditor(additionalConfig?: any) {\n        const nodeEditorConfig: any = {\n            nodeMaterial: this,\n            ...additionalConfig,\n        };\n        this.BJSNODEMATERIALEDITOR.NodeEditor.Show(nodeEditorConfig);\n    }\n\n    /**\n     * Launch the node material editor\n     * @param config Define the configuration of the editor\n     * @returns a promise fulfilled when the node editor is visible\n     */\n    public async edit(config?: INodeMaterialEditorOptions): Promise<void> {\n        return await new Promise((resolve) => {\n            this.BJSNODEMATERIALEDITOR = this.BJSNODEMATERIALEDITOR || this._getGlobalNodeMaterialEditor();\n            if (typeof this.BJSNODEMATERIALEDITOR == \"undefined\") {\n                const editorUrl = config && config.editorURL ? config.editorURL : NodeMaterial.EditorURL;\n\n                // Load editor and add it to the DOM\n                Tools.LoadBabylonScript(editorUrl, () => {\n                    this.BJSNODEMATERIALEDITOR = this.BJSNODEMATERIALEDITOR || this._getGlobalNodeMaterialEditor();\n                    this._createNodeEditor(config?.nodeEditorConfig);\n                    resolve();\n                });\n            } else {\n                // Otherwise creates the editor\n                this._createNodeEditor(config?.nodeEditorConfig);\n                resolve();\n            }\n        });\n    }\n\n    /**\n     * Clear the current material\n     */\n    public clear() {\n        this._vertexOutputNodes.length = 0;\n        this._fragmentOutputNodes.length = 0;\n        this.attachedBlocks.length = 0;\n        this._buildIsInProgress = false;\n    }\n\n    /**\n     * Clear the current material and set it to a default state\n     */\n    public setToDefault() {\n        this.clear();\n\n        this.editorData = null;\n\n        const positionInput = new InputBlock(\"Position\");\n        positionInput.setAsAttribute(\"position\");\n\n        const worldInput = new InputBlock(\"World\");\n        worldInput.setAsSystemValue(NodeMaterialSystemValues.World);\n\n        const worldPos = new TransformBlock(\"WorldPos\");\n        positionInput.connectTo(worldPos);\n        worldInput.connectTo(worldPos);\n\n        const viewProjectionInput = new InputBlock(\"ViewProjection\");\n        viewProjectionInput.setAsSystemValue(NodeMaterialSystemValues.ViewProjection);\n\n        const worldPosdMultipliedByViewProjection = new TransformBlock(\"WorldPos * ViewProjectionTransform\");\n        worldPos.connectTo(worldPosdMultipliedByViewProjection);\n        viewProjectionInput.connectTo(worldPosdMultipliedByViewProjection);\n\n        const vertexOutput = new VertexOutputBlock(\"VertexOutput\");\n        worldPosdMultipliedByViewProjection.connectTo(vertexOutput);\n\n        // Pixel\n        const pixelColor = new InputBlock(\"color\");\n        pixelColor.value = new Color4(0.8, 0.8, 0.8, 1);\n\n        const fragmentOutput = new FragmentOutputBlock(\"FragmentOutput\");\n        pixelColor.connectTo(fragmentOutput);\n\n        // Add to nodes\n        this.addOutputNode(vertexOutput);\n        this.addOutputNode(fragmentOutput);\n\n        this._mode = NodeMaterialModes.Material;\n    }\n\n    /**\n     * Clear the current material and set it to a default state for post process\n     */\n    public setToDefaultPostProcess() {\n        this.clear();\n\n        this.editorData = null;\n\n        const position = new InputBlock(\"Position\");\n        position.setAsAttribute(\"position2d\");\n\n        const const1 = new InputBlock(\"Constant1\");\n        const1.isConstant = true;\n        const1.value = 1;\n\n        const vmerger = new VectorMergerBlock(\"Position3D\");\n\n        position.connectTo(vmerger);\n        const1.connectTo(vmerger, { input: \"w\" });\n\n        const vertexOutput = new VertexOutputBlock(\"VertexOutput\");\n        vmerger.connectTo(vertexOutput);\n\n        // Pixel\n        const scale = new InputBlock(\"Scale\");\n        scale.visibleInInspector = true;\n        scale.value = new Vector2(1, 1);\n\n        const uv0 = new RemapBlock(\"uv0\");\n        position.connectTo(uv0);\n\n        const uv = new MultiplyBlock(\"UV scale\");\n        uv0.connectTo(uv);\n        scale.connectTo(uv);\n\n        const currentScreen = new CurrentScreenBlock(\"CurrentScreen\");\n        uv.connectTo(currentScreen);\n        const textureUrl = Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/nme/currentScreenPostProcess.png\");\n        currentScreen.texture = new Texture(textureUrl, this.getScene());\n\n        const fragmentOutput = new FragmentOutputBlock(\"FragmentOutput\");\n        currentScreen.connectTo(fragmentOutput, { output: \"rgba\" });\n\n        // Add to nodes\n        this.addOutputNode(vertexOutput);\n        this.addOutputNode(fragmentOutput);\n\n        this._mode = NodeMaterialModes.PostProcess;\n    }\n\n    /**\n     * Clear the current material and set it to a default state for procedural texture\n     */\n    public setToDefaultProceduralTexture() {\n        this.clear();\n\n        this.editorData = null;\n\n        const position = new InputBlock(\"Position\");\n        position.setAsAttribute(\"position2d\");\n\n        const const1 = new InputBlock(\"Constant1\");\n        const1.isConstant = true;\n        const1.value = 1;\n\n        const vmerger = new VectorMergerBlock(\"Position3D\");\n\n        position.connectTo(vmerger);\n        const1.connectTo(vmerger, { input: \"w\" });\n\n        const vertexOutput = new VertexOutputBlock(\"VertexOutput\");\n        vmerger.connectTo(vertexOutput);\n\n        // Pixel\n        const time = new InputBlock(\"Time\");\n        time.value = 0;\n        time.min = 0;\n        time.max = 0;\n        time.isBoolean = false;\n        time.matrixMode = 0;\n        time.animationType = AnimatedInputBlockTypes.Time;\n        time.isConstant = false;\n\n        const color = new InputBlock(\"Color3\");\n        color.value = new Color3(1, 1, 1);\n        color.isConstant = false;\n        const fragmentOutput = new FragmentOutputBlock(\"FragmentOutput\");\n\n        const vectorMerger = new VectorMergerBlock(\"VectorMerger\");\n        vectorMerger.visibleInInspector = false;\n\n        const cos = new TrigonometryBlock(\"Cos\");\n        cos.operation = TrigonometryBlockOperations.Cos;\n\n        position.connectTo(vectorMerger);\n        time.output.connectTo(cos.input);\n        cos.output.connectTo(vectorMerger.z);\n        vectorMerger.xyzOut.connectTo(fragmentOutput.rgb);\n\n        // Add to nodes\n        this.addOutputNode(vertexOutput);\n        this.addOutputNode(fragmentOutput);\n\n        this._mode = NodeMaterialModes.ProceduralTexture;\n    }\n\n    /**\n     * Clear the current material and set it to a default state for particle\n     */\n    public setToDefaultParticle() {\n        this.clear();\n\n        this.editorData = null;\n\n        // Pixel\n        const uv = new InputBlock(\"uv\");\n        uv.setAsAttribute(\"particle_uv\");\n\n        const texture = new ParticleTextureBlock(\"ParticleTexture\");\n        uv.connectTo(texture);\n\n        const color = new InputBlock(\"Color\");\n        color.setAsAttribute(\"particle_color\");\n\n        const multiply = new MultiplyBlock(\"Texture * Color\");\n        texture.connectTo(multiply);\n        color.connectTo(multiply);\n\n        const rampGradient = new ParticleRampGradientBlock(\"ParticleRampGradient\");\n        multiply.connectTo(rampGradient);\n\n        const cSplitter = new ColorSplitterBlock(\"ColorSplitter\");\n        color.connectTo(cSplitter);\n\n        const blendMultiply = new ParticleBlendMultiplyBlock(\"ParticleBlendMultiply\");\n        rampGradient.connectTo(blendMultiply);\n        texture.connectTo(blendMultiply, { output: \"a\" });\n        cSplitter.connectTo(blendMultiply, { output: \"a\" });\n\n        const fragmentOutput = new FragmentOutputBlock(\"FragmentOutput\");\n        blendMultiply.connectTo(fragmentOutput);\n\n        // Add to nodes\n        this.addOutputNode(fragmentOutput);\n\n        this._mode = NodeMaterialModes.Particle;\n    }\n\n    /**\n     * Loads the current Node Material from a url pointing to a file save by the Node Material Editor\n     * @deprecated Please use NodeMaterial.ParseFromFileAsync instead\n     * @param url defines the url to load from\n     * @param rootUrl defines the root URL for nested url in the node material\n     * @returns a promise that will fulfil when the material is fully loaded\n     */\n    public async loadAsync(url: string, rootUrl: string = \"\") {\n        return await NodeMaterialParseFromFileAsync(\"\", url, this.getScene(), rootUrl, true, this);\n    }\n\n    private _gatherBlocks(rootNode: NodeMaterialBlock, list: NodeMaterialBlock[]) {\n        if (list.indexOf(rootNode) !== -1) {\n            return;\n        }\n        list.push(rootNode);\n\n        for (const input of rootNode.inputs) {\n            const connectedPoint = input.connectedPoint;\n            if (connectedPoint) {\n                const block = connectedPoint.ownerBlock;\n                if (block !== rootNode) {\n                    this._gatherBlocks(block, list);\n                }\n            }\n        }\n\n        // Teleportation\n        if (rootNode.isTeleportOut) {\n            const block = rootNode as NodeMaterialTeleportOutBlock;\n            if (block.entryPoint) {\n                this._gatherBlocks(block.entryPoint, list);\n            }\n        }\n    }\n\n    /**\n     * Generate a string containing the code declaration required to create an equivalent of this material\n     * @returns a string\n     */\n    public generateCode() {\n        let alreadyDumped: NodeMaterialBlock[] = [];\n        const vertexBlocks: NodeMaterialBlock[] = [];\n        const uniqueNames: string[] = [\"const\", \"var\", \"let\"];\n        // Gets active blocks\n        for (const outputNode of this._vertexOutputNodes) {\n            this._gatherBlocks(outputNode, vertexBlocks);\n        }\n\n        const fragmentBlocks: NodeMaterialBlock[] = [];\n        for (const outputNode of this._fragmentOutputNodes) {\n            this._gatherBlocks(outputNode, fragmentBlocks);\n        }\n\n        // Generate vertex shader\n        let codeString = `var nodeMaterial = new BABYLON.NodeMaterial(\"${this.name || \"node material\"}\");\\n`;\n        codeString += `nodeMaterial.mode = BABYLON.NodeMaterialModes.${NodeMaterialModes[this.mode]};\\n`;\n        for (const node of vertexBlocks) {\n            if (node.isInput && alreadyDumped.indexOf(node) === -1) {\n                codeString += node._dumpCode(uniqueNames, alreadyDumped);\n            }\n        }\n\n        // Generate fragment shader\n        for (const node of fragmentBlocks) {\n            if (node.isInput && alreadyDumped.indexOf(node) === -1) {\n                codeString += node._dumpCode(uniqueNames, alreadyDumped);\n            }\n        }\n\n        // Connections\n        alreadyDumped = [];\n        codeString += \"\\n// Connections\\n\";\n        for (const node of this._vertexOutputNodes) {\n            codeString += node._dumpCodeForOutputConnections(alreadyDumped);\n        }\n        for (const node of this._fragmentOutputNodes) {\n            codeString += node._dumpCodeForOutputConnections(alreadyDumped);\n        }\n\n        // Output nodes\n        codeString += \"\\n// Output nodes\\n\";\n        for (const node of this._vertexOutputNodes) {\n            codeString += `nodeMaterial.addOutputNode(${node._codeVariableName});\\n`;\n        }\n\n        for (const node of this._fragmentOutputNodes) {\n            codeString += `nodeMaterial.addOutputNode(${node._codeVariableName});\\n`;\n        }\n\n        codeString += `nodeMaterial.build();\\n`;\n\n        return codeString;\n    }\n\n    /**\n     * Serializes this material in a JSON representation\n     * @param selectedBlocks defines an optional list of blocks to serialize\n     * @returns the serialized material object\n     */\n    public override serialize(selectedBlocks?: NodeMaterialBlock[]): any {\n        const serializationObject = selectedBlocks ? {} : SerializationHelper.Serialize(this);\n        serializationObject.editorData = JSON.parse(JSON.stringify(this.editorData)); // Copy\n\n        let blocks: NodeMaterialBlock[] = [];\n\n        if (selectedBlocks) {\n            blocks = selectedBlocks;\n        } else {\n            serializationObject.customType = \"BABYLON.NodeMaterial\";\n            serializationObject.outputNodes = [];\n\n            // Outputs\n            for (const outputNode of this._vertexOutputNodes) {\n                this._gatherBlocks(outputNode, blocks);\n                serializationObject.outputNodes.push(outputNode.uniqueId);\n            }\n\n            for (const outputNode of this._fragmentOutputNodes) {\n                this._gatherBlocks(outputNode, blocks);\n\n                if (serializationObject.outputNodes.indexOf(outputNode.uniqueId) === -1) {\n                    serializationObject.outputNodes.push(outputNode.uniqueId);\n                }\n            }\n        }\n\n        // Blocks\n        serializationObject.blocks = [];\n\n        for (const block of blocks) {\n            serializationObject.blocks.push(block.serialize());\n        }\n\n        if (!selectedBlocks) {\n            for (const block of this.attachedBlocks) {\n                if (blocks.indexOf(block) !== -1) {\n                    continue;\n                }\n                serializationObject.blocks.push(block.serialize());\n            }\n        }\n\n        serializationObject.uniqueId = this.uniqueId;\n\n        return serializationObject;\n    }\n\n    private _restoreConnections(block: NodeMaterialBlock, source: any, map: { [key: number]: NodeMaterialBlock }) {\n        for (const outputPoint of block.outputs) {\n            for (const candidate of source.blocks) {\n                const target = map[candidate.id];\n\n                if (!target) {\n                    continue;\n                }\n\n                for (const input of candidate.inputs) {\n                    if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {\n                        const inputPoint = target.getInputByName(input.inputName);\n                        if (!inputPoint || inputPoint.isConnected) {\n                            continue;\n                        }\n\n                        outputPoint.connectTo(inputPoint, true);\n                        this._restoreConnections(target, source, map);\n                        continue;\n                    }\n                }\n            }\n        }\n    }\n\n    private static _DefaultImageProcessingConfigurationSerialized?: string;\n\n    /**\n     * Determines whether a parsed image processing configuration only holds default values.\n     * @param configuration the configuration to test\n     * @returns true if the configuration matches a freshly created default configuration\n     */\n    private static _IsDefaultImageProcessingConfiguration(configuration: ImageProcessingConfiguration): boolean {\n        if (!NodeMaterial._DefaultImageProcessingConfigurationSerialized) {\n            NodeMaterial._DefaultImageProcessingConfigurationSerialized = JSON.stringify(new ImageProcessingConfiguration().serialize());\n        }\n        return JSON.stringify(configuration.serialize()) === NodeMaterial._DefaultImageProcessingConfigurationSerialized;\n    }\n\n    /**\n     * Clear the current graph and load a new one from a serialization object\n     * @param source defines the JSON representation of the material\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\n     * @param merge defines whether or not the source must be merged or replace the current content\n     * @param urlRewriter defines a function used to rewrite urls\n     */\n    public parseSerializedObject(source: any, rootUrl: string = \"\", merge = false, urlRewriter?: (url: string) => string) {\n        if (!merge) {\n            this.clear();\n        }\n\n        const id = this.id;\n        const uniqueId = this.uniqueId;\n\n        const previousImageProcessingConfiguration = this._imageProcessingConfiguration;\n        const previousImageProcessingObserver = this._imageProcessingObserver;\n        const hasSerializedImageProcessingConfiguration = Object.prototype.hasOwnProperty.call(source, \"_imageProcessingConfiguration\");\n\n        SerializationHelper.ParseProperties(source, this, this.getScene(), rootUrl);\n        const parsedImageProcessingConfiguration = this._imageProcessingConfiguration;\n        if (hasSerializedImageProcessingConfiguration) {\n            this._imageProcessingConfiguration = previousImageProcessingConfiguration;\n            this._imageProcessingObserver = previousImageProcessingObserver;\n            // A serialized configuration that only holds default values (the common case for Node Material\n            // snippets that never customized image processing) must not detach the material from the scene\n            // configuration. A detached private configuration is never updated by full-screen post-processes\n            // (e.g. the HDR DefaultRenderingPipeline sets applyByPostProcess on the scene configuration only),\n            // so image processing would end up applied both in the material shader and in the post-process.\n            // Only honor a genuinely customized configuration; otherwise fall back to the scene configuration.\n            const useParsedConfiguration = parsedImageProcessingConfiguration && !NodeMaterial._IsDefaultImageProcessingConfiguration(parsedImageProcessingConfiguration);\n            this._attachImageProcessingConfiguration(useParsedConfiguration ? parsedImageProcessingConfiguration : null);\n        }\n\n        this.id = id;\n        this.uniqueId = uniqueId;\n\n        const map: { [key: number]: NodeMaterialBlock } = {};\n\n        // Create blocks\n        for (const parsedBlock of source.blocks) {\n            const blockType = GetClass(parsedBlock.customType);\n            if (blockType) {\n                const block: NodeMaterialBlock = new blockType();\n                block._deserialize(parsedBlock, this.getScene(), rootUrl, urlRewriter);\n                map[parsedBlock.id] = block;\n\n                this.attachedBlocks.push(block);\n            }\n        }\n\n        // Reconnect teleportation\n        for (const block of this.attachedBlocks) {\n            if (block.isTeleportOut) {\n                const teleportOut = block as NodeMaterialTeleportOutBlock;\n                const id = teleportOut._tempEntryPointUniqueId;\n                if (id) {\n                    const source = map[id] as NodeMaterialTeleportInBlock;\n                    source.attachToEndpoint(teleportOut);\n                }\n            }\n        }\n\n        // Connections - Starts with input blocks only (except if in \"merge\" mode where we scan all blocks)\n        for (let blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {\n            const parsedBlock = source.blocks[blockIndex];\n            const block = map[parsedBlock.id];\n\n            if (!block) {\n                continue;\n            }\n\n            if (block.inputs.length && !merge) {\n                continue;\n            }\n            this._restoreConnections(block, source, map);\n        }\n\n        // Outputs\n        if (source.outputNodes) {\n            for (const outputNodeId of source.outputNodes) {\n                this.addOutputNode(map[outputNodeId]);\n            }\n        }\n\n        // UI related info\n        if (source.locations || (source.editorData && source.editorData.locations)) {\n            const locations: {\n                blockId: number;\n                x: number;\n                y: number;\n                isCollapsed: boolean;\n            }[] = source.locations || source.editorData.locations;\n\n            for (const location of locations) {\n                if (map[location.blockId]) {\n                    location.blockId = map[location.blockId].uniqueId;\n                }\n            }\n\n            if (merge && this.editorData && this.editorData.locations) {\n                locations.concat(this.editorData.locations);\n            }\n\n            if (source.locations) {\n                this.editorData = {\n                    locations: locations,\n                };\n            } else {\n                this.editorData = source.editorData;\n                this.editorData.locations = locations;\n            }\n\n            const blockMap: { [key: number]: number } = {};\n\n            for (const key in map) {\n                blockMap[key] = map[key].uniqueId;\n            }\n\n            this.editorData.map = blockMap;\n        }\n\n        Material.ParseAlphaMode(source, this);\n\n        if (!merge) {\n            this._mode = source.mode ?? NodeMaterialModes.Material;\n        }\n    }\n\n    /**\n     * Clear the current graph and load a new one from a serialization object\n     * @param source defines the JSON representation of the material\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\n     * @param merge defines whether or not the source must be merged or replace the current content\n     * @deprecated Please use the parseSerializedObject method instead\n     */\n    public loadFromSerialization(source: any, rootUrl: string = \"\", merge = false) {\n        this.parseSerializedObject(source, rootUrl, merge);\n    }\n\n    /**\n     * Makes a duplicate of the current material.\n     * @param name defines the name to use for the new material\n     * @param shareEffect defines if the clone material should share the same effect (default is false)\n     * @returns the cloned material\n     */\n    public override clone(name: string, shareEffect: boolean = false): NodeMaterial {\n        const serializationObject = this.serialize();\n\n        const clone = SerializationHelper.Clone(() => new NodeMaterial(name, this.getScene(), this.options), this);\n\n        clone.parseSerializedObject(serializationObject);\n\n        clone.id = name;\n        clone.name = name;\n        clone._buildId = this._buildId;\n\n        clone.build(false, !shareEffect);\n\n        return clone;\n    }\n\n    /**\n     * Awaits for all the material textures to be ready before resolving the returned promise.\n     * @returns A promise that resolves when the textures are ready.\n     */\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n    public whenTexturesReadyAsync(): Promise<void[]> {\n        // Ensures all textures are ready to render.\n        const textureReadyPromises: Promise<void>[] = [];\n        const activeTextures = this.getActiveTextures();\n        for (const texture of activeTextures) {\n            const internalTexture = texture.getInternalTexture();\n            if (internalTexture && !internalTexture.isReady) {\n                textureReadyPromises.push(\n                    new Promise((textureResolve, textureReject) => {\n                        internalTexture.onLoadedObservable.addOnce(() => {\n                            textureResolve();\n                        });\n                        internalTexture.onErrorObservable.addOnce((e) => {\n                            textureReject(_ErrorFromReason(e));\n                        });\n                    })\n                );\n            }\n        }\n\n        return Promise.all(textureReadyPromises);\n    }\n}\n\n/**\n * Checks if a block is a texture block\n * @param block The block to check\n * @returns True if the block is a texture block\n */\nexport function NodeMaterialBlockIsTextureBlock(block: NodeMaterialBlock): block is NodeMaterialTextureBlocks {\n    return (\n        block.getClassName() === \"TextureBlock\" ||\n        block.getClassName() === \"ReflectionTextureBaseBlock\" ||\n        block.getClassName() === \"ReflectionTextureBlock\" ||\n        block.getClassName() === \"ReflectionBlock\" ||\n        block.getClassName() === \"RefractionBlock\" ||\n        block.getClassName() === \"CurrentScreenBlock\" ||\n        block.getClassName() === \"SmartFilterTextureBlock\" ||\n        block.getClassName() === \"ParticleTextureBlock\" ||\n        block.getClassName() === \"ImageSourceBlock\" ||\n        block.getClassName() === \"TriPlanarBlock\" ||\n        block.getClassName() === \"BiPlanarBlock\" ||\n        block.getClassName() === \"PrePassTextureBlock\"\n    );\n}\n\n/**\n * Creates a node material from parsed material data\n * @param source defines the JSON representation of the material\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @param shaderLanguage defines the language to use (GLSL by default)\n * @returns a new node material\n */\nexport function NodeMaterialParse(source: any, scene: Scene, rootUrl: string = \"\", shaderLanguage = ShaderLanguage.GLSL): NodeMaterial {\n    const nodeMaterial = SerializationHelper.Parse(() => new NodeMaterial(source.name, scene, { shaderLanguage: shaderLanguage }), source, scene, rootUrl);\n\n    nodeMaterial.parseSerializedObject(source, rootUrl);\n    nodeMaterial.build();\n\n    return nodeMaterial;\n}\n\nasync function _WaitForBuildAsync(nodeMaterial: NodeMaterial): Promise<NodeMaterial> {\n    if (!nodeMaterial.buildIsInProgress) {\n        return nodeMaterial;\n    }\n\n    return await new Promise<NodeMaterial>((resolve, reject) => {\n        const buildObserver = nodeMaterial.onBuildObservable.addOnce(() => {\n            nodeMaterial.onBuildErrorObservable.remove(errorObserver);\n            resolve(nodeMaterial);\n        });\n        const errorObserver = nodeMaterial.onBuildErrorObservable.addOnce((error) => {\n            nodeMaterial.onBuildObservable.remove(buildObserver);\n            reject(new Error(error));\n        });\n    });\n}\n\nfunction _ErrorFromReason(reason: unknown): Error {\n    return reason instanceof Error ? reason : new Error(String(reason));\n}\n\nasync function _WaitForBuildAndTexturesAsync(nodeMaterial: NodeMaterial, waitForTextureReadyness: boolean): Promise<NodeMaterial> {\n    await _WaitForBuildAsync(nodeMaterial);\n    if (waitForTextureReadyness) {\n        await nodeMaterial.whenTexturesReadyAsync();\n    }\n    return nodeMaterial;\n}\n\n/**\n * Creates a node material from a snippet saved in a remote file\n * @param name defines the name of the material to create\n * @param url defines the url to load from\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL for nested url in the node material\n * @param skipBuild defines whether to build the node material\n * @param targetMaterial defines a material to use instead of creating a new one\n * @param urlRewriter defines a function used to rewrite urls\n * @param options defines options to be used with the node material\n * @returns a promise that will resolve to the new node material\n */\nexport async function NodeMaterialParseFromFileAsync(\n    name: string,\n    url: string,\n    scene: Scene,\n    rootUrl: string = \"\",\n    skipBuild: boolean = false,\n    targetMaterial?: NodeMaterial,\n    urlRewriter?: (url: string) => string,\n    options?: Partial<INodeMaterialOptions>\n): Promise<NodeMaterial> {\n    const material = targetMaterial ?? new NodeMaterial(name, scene, options);\n    const finalName = material.name;\n\n    const data = await scene._loadFileAsync(url);\n    const serializationObject = JSON.parse(data);\n    material.parseSerializedObject(serializationObject, rootUrl, undefined, urlRewriter);\n    material.name = finalName; // in case it was changed during parse\n    if (!skipBuild) {\n        material.build();\n        await _WaitForBuildAsync(material);\n    }\n    return material;\n}\n\n/**\n * Creates a node material from a snippet saved by the node material editor\n * @param snippetId defines the snippet to load\n * @param scene defines the hosting scene\n * @param rootUrl defines the root URL to use to load textures and relative dependencies\n * @param nodeMaterial defines a node material to update (instead of creating a new one)\n * @param skipBuild defines whether to build the node material\n * @param waitForTextureReadyness defines whether to wait for texture readiness resolving the promise (default: false)\n * @param urlRewriter defines a function used to rewrite urls\n * @param options defines options to be used with the node material\n * @returns a promise that will resolve to the new node material\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\nexport function NodeMaterialParseFromSnippetAsync(\n    this: typeof NodeMaterial | void,\n    snippetId: string,\n    scene: Scene = EngineStore.LastCreatedScene!,\n    rootUrl: string = \"\",\n    nodeMaterial?: NodeMaterial,\n    skipBuild: boolean = false,\n    waitForTextureReadyness: boolean = false,\n    urlRewriter?: (url: string) => string,\n    options?: Partial<INodeMaterialOptions>\n): Promise<NodeMaterial> {\n    if (snippetId === \"_BLANK\") {\n        return Promise.resolve(NodeMaterialCreateDefault(\"blank\", scene));\n    }\n\n    const snippetUrl = this?.SnippetUrl ?? NodeMaterial.SnippetUrl;\n\n    return new Promise((resolve, reject) => {\n        const request = new WebRequest();\n        request.addEventListener(\"readystatechange\", () => {\n            if (request.readyState == 4) {\n                if (request.status == 200) {\n                    const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\n                    const serializationObject = JSON.parse(snippet.nodeMaterial);\n\n                    if (!nodeMaterial) {\n                        nodeMaterial = SerializationHelper.Parse(() => new NodeMaterial(snippetId, scene, options), serializationObject, scene, rootUrl);\n                        nodeMaterial.uniqueId = scene.getUniqueId();\n                    }\n\n                    nodeMaterial.parseSerializedObject(serializationObject, undefined, undefined, urlRewriter);\n                    nodeMaterial.snippetId = snippetId;\n\n                    // We reset sideOrientation to default value\n                    nodeMaterial.sideOrientation = null;\n\n                    try {\n                        if (!skipBuild) {\n                            nodeMaterial.build();\n                        }\n                    } catch (err) {\n                        reject(_ErrorFromReason(err));\n                        return;\n                    }\n\n                    void (async () => {\n                        try {\n                            resolve(await _WaitForBuildAndTexturesAsync(nodeMaterial!, waitForTextureReadyness));\n                        } catch (err) {\n                            reject(_ErrorFromReason(err));\n                        }\n                    })();\n                } else {\n                    reject(new Error(\"Unable to load the snippet \" + snippetId));\n                }\n            }\n        });\n\n        request.open(\"GET\", snippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\n        request.send();\n    });\n}\n\n/**\n * Creates a new node material set to default basic configuration\n * @param name defines the name of the material\n * @param scene defines the hosting scene\n * @returns a new NodeMaterial\n */\nexport function NodeMaterialCreateDefault(name: string, scene?: Scene) {\n    const newMaterial = new NodeMaterial(name, scene);\n\n    newMaterial.setToDefault();\n    newMaterial.build();\n\n    return newMaterial;\n}\n\nlet _Registered = false;\n/**\n * Register side effects for nodeMaterial.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterNodeMaterial(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    // NodeMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\n    RegisterImageProcessingConfiguration();\n\n    NodeMaterial._BlockIsTextureBlock = NodeMaterialBlockIsTextureBlock;\n    NodeMaterial.Parse = NodeMaterialParse;\n    NodeMaterial.ParseFromFileAsync = NodeMaterialParseFromFileAsync;\n    NodeMaterial.ParseFromSnippetAsync = NodeMaterialParseFromSnippetAsync;\n    NodeMaterial.CreateDefault = NodeMaterialCreateDefault;\n\n    RegisterClass(\"BABYLON.NodeMaterial\", NodeMaterial);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRControllerPointerSelection } from \"./WebXRControllerPointerSelection.pure\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder.pure\";\r\nimport { type Observer } from \"../../Misc/observable.pure\";\r\nimport { type WebXRInput } from \"../webXRInput\";\r\nimport { type WebXRInputSource } from \"../webXRInputSource\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type WebXRControllerComponent } from \"../motionController/webXRControllerComponent\";\r\nimport { type IndicesArray, type Nullable } from \"../../types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { Ray } from \"../../Culling/ray.pure\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer\";\r\nimport { type WebXRAbstractMotionController } from \"../motionController/webXRAbstractMotionController\";\r\nimport { BoundingSphere } from \"../../Culling/boundingSphere\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial.pure\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type NodeMaterial, NodeMaterialParseFromFileAsync, NodeMaterialParseFromSnippetAsync } from \"../../Materials/Node/nodeMaterial.pure\";\r\nimport { type Material } from \"../../Materials/material.pure\";\r\nimport { Animation } from \"../../Animations/animation.pure\";\r\nimport { QuadraticEase, EasingFunction } from \"../../Animations/easing\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n// side effects\r\n\r\ntype ControllerData = {\r\n    xrController?: WebXRInputSource;\r\n    squeezeComponent?: WebXRControllerComponent;\r\n    selectionComponent?: WebXRControllerComponent;\r\n    onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n    onSqueezeButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n    onFrameObserver?: Nullable<Observer<XRFrame>>;\r\n    meshUnderPointer: Nullable<AbstractMesh>;\r\n    nearInteractionTargetMesh: Nullable<AbstractMesh>;\r\n    pick: Nullable<PickingInfo>;\r\n    stalePick: Nullable<PickingInfo>;\r\n    id: number;\r\n    touchCollisionMesh: AbstractMesh;\r\n    touchCollisionMeshFunction: (isTouch: boolean) => void;\r\n    hydrateCollisionMeshFunction: (isHydration: boolean) => void;\r\n    currentAnimationState: ControllerOrbAnimationState;\r\n    grabRay: Ray;\r\n    nearInteraction: boolean;\r\n    hoverInteraction: boolean;\r\n    grabInteraction: boolean;\r\n    downTriggered: boolean;\r\n    // event support\r\n    eventListeners?: { [event in XREventType]?: (event: XRInputSourceEvent) => void };\r\n    pickedPointVisualCue: AbstractMesh;\r\n    _worldScaleObserver?: Nullable<Observer<{ previousScaleFactor: number; newScaleFactor: number }>>;\r\n};\r\n\r\n// Tracks the interaction animation state when using a motion controller with a near interaction orb\r\nenum ControllerOrbAnimationState {\r\n    /**\r\n     * Orb is invisible\r\n     */\r\n    DEHYDRATED,\r\n    /**\r\n     * Orb is visible and inside the hover range\r\n     */\r\n    HOVER,\r\n    /**\r\n     * Orb is visible and touching a near interaction target\r\n     */\r\n    TOUCH,\r\n}\r\n\r\n/**\r\n * Where should the near interaction mesh be attached to when using a motion controller for near interaction\r\n */\r\nexport const enum WebXRNearControllerMode {\r\n    /**\r\n     * Motion controllers will not support near interaction\r\n     */\r\n    DISABLED = 0,\r\n    /**\r\n     * The interaction point for motion controllers will be inside of them\r\n     */\r\n    CENTERED_ON_CONTROLLER = 1,\r\n    /**\r\n     * The interaction point for motion controllers will be in front of the controller\r\n     */\r\n    CENTERED_IN_FRONT = 2,\r\n}\r\n\r\n/**\r\n * Options interface for the near interaction module\r\n */\r\nexport interface IWebXRNearInteractionOptions {\r\n    /**\r\n     * If provided, this scene will be used to render meshes.\r\n     */\r\n    customUtilityLayerScene?: Scene;\r\n    /**\r\n     * Should meshes created here be added to a utility layer or the main scene\r\n     */\r\n    useUtilityLayer?: boolean;\r\n    /**\r\n     * The xr input to use with this near interaction\r\n     */\r\n    xrInput: WebXRInput;\r\n    /**\r\n     * Enable near interaction on all controllers instead of switching between them\r\n     */\r\n    enableNearInteractionOnAllControllers?: boolean;\r\n    /**\r\n     * The preferred hand to give the near interaction to. This will be prioritized when the controller initialize.\r\n     * If switch is enabled, it will still allow the user to switch between the different controllers\r\n     */\r\n    preferredHandedness?: XRHandedness;\r\n    /**\r\n     * Disable switching the near interaction from one controller to the other.\r\n     * If the preferred hand is set it will be fixed on this hand, and if not it will be fixed on the first controller added to the scene\r\n     */\r\n    disableSwitchOnClick?: boolean;\r\n\r\n    /**\r\n     * Far interaction feature to toggle when near interaction takes precedence\r\n     */\r\n    farInteractionFeature?: WebXRControllerPointerSelection;\r\n\r\n    /**\r\n     * Near interaction mode for motion controllers\r\n     */\r\n    nearInteractionControllerMode?: WebXRNearControllerMode;\r\n\r\n    /**\r\n     * Optional material for the motion controller orb, if enabled\r\n     */\r\n    motionControllerOrbMaterial?: Material;\r\n\r\n    /**\r\n     * If provided, this URL will be used by Node Material to generate the material for the motion controller orb\r\n     * If not provided, a snippet will be downloaded from the Babylon.js snippet server CDN.\r\n     * The NME JSON file can be found here - https://github.com/BabylonJS/Assets/blob/master/nme/nearInteractionTouchMaterial.json\r\n     */\r\n    motionControllerTouchMaterialSnippetUrl?: string;\r\n}\r\n\r\nconst LocalTempVectors = [new Vector3(), new Vector3(), new Vector3(), new Vector3()];\r\n\r\n/**\r\n * A module that will enable near interaction near interaction for hands and motion controllers of XR Input Sources\r\n */\r\nexport class WebXRNearInteraction extends WebXRAbstractFeature {\r\n    private static _IdCounter = 200;\r\n\r\n    private _tmpRay: Ray = new Ray(new Vector3(), new Vector3());\r\n\r\n    private _attachController = (xrController: WebXRInputSource) => {\r\n        if (this._controllers[xrController.uniqueId]) {\r\n            // already attached\r\n            return;\r\n        }\r\n        // get two new meshes\r\n        const { touchCollisionMesh, touchCollisionMeshFunction, hydrateCollisionMeshFunction } = this._generateNewTouchPointMesh();\r\n        const selectionMesh = this._generateVisualCue();\r\n\r\n        this._controllers[xrController.uniqueId] = {\r\n            xrController,\r\n            meshUnderPointer: null,\r\n            nearInteractionTargetMesh: null,\r\n            pick: null,\r\n            stalePick: null,\r\n            touchCollisionMesh,\r\n            touchCollisionMeshFunction: touchCollisionMeshFunction,\r\n            hydrateCollisionMeshFunction: hydrateCollisionMeshFunction,\r\n            currentAnimationState: ControllerOrbAnimationState.DEHYDRATED,\r\n            grabRay: new Ray(new Vector3(), new Vector3()),\r\n            hoverInteraction: false,\r\n            nearInteraction: false,\r\n            grabInteraction: false,\r\n            downTriggered: false,\r\n            id: WebXRNearInteraction._IdCounter++,\r\n            pickedPointVisualCue: selectionMesh,\r\n        };\r\n\r\n        this._controllers[xrController.uniqueId]._worldScaleObserver =\r\n            this._controllers[xrController.uniqueId]._worldScaleObserver ||\r\n            this._xrSessionManager.onWorldScaleFactorChangedObservable.add((values) => {\r\n                if (values.newScaleFactor !== values.previousScaleFactor) {\r\n                    this._controllers[xrController.uniqueId].touchCollisionMesh.dispose();\r\n                    this._controllers[xrController.uniqueId].pickedPointVisualCue.dispose();\r\n\r\n                    const { touchCollisionMesh, touchCollisionMeshFunction, hydrateCollisionMeshFunction } = this._generateNewTouchPointMesh();\r\n                    this._controllers[xrController.uniqueId].touchCollisionMesh = touchCollisionMesh;\r\n                    this._controllers[xrController.uniqueId].touchCollisionMeshFunction = touchCollisionMeshFunction;\r\n                    this._controllers[xrController.uniqueId].hydrateCollisionMeshFunction = hydrateCollisionMeshFunction;\r\n                    this._controllers[xrController.uniqueId].pickedPointVisualCue = this._generateVisualCue();\r\n                }\r\n            });\r\n\r\n        if (this._attachedController) {\r\n            if (\r\n                !this._options.enableNearInteractionOnAllControllers &&\r\n                this._options.preferredHandedness &&\r\n                xrController.inputSource.handedness === this._options.preferredHandedness\r\n            ) {\r\n                this._attachedController = xrController.uniqueId;\r\n            }\r\n        } else {\r\n            if (!this._options.enableNearInteractionOnAllControllers) {\r\n                this._attachedController = xrController.uniqueId;\r\n            }\r\n        }\r\n        switch (xrController.inputSource.targetRayMode) {\r\n            case \"tracked-pointer\":\r\n                return this._attachNearInteractionMode(xrController);\r\n            case \"gaze\":\r\n                return null;\r\n            case \"screen\":\r\n                return null;\r\n        }\r\n    };\r\n\r\n    private _controllers: {\r\n        [controllerUniqueId: string]: ControllerData;\r\n    } = {};\r\n    private _scene: Scene;\r\n\r\n    private _attachedController: string;\r\n\r\n    private _farInteractionFeature: Nullable<WebXRControllerPointerSelection> = null;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.NEAR_INTERACTION;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * default color of the selection ring\r\n     */\r\n    public selectionMeshDefaultColor: Color3 = new Color3(0.8, 0.8, 0.8);\r\n    /**\r\n     * This color will be applied to the selection ring when selection is triggered\r\n     */\r\n    public selectionMeshPickedColor: Color3 = new Color3(0.3, 0.3, 1.0);\r\n\r\n    /**\r\n     * If set to true, the selection mesh will always be hidden. Otherwise it will be shown only when needed\r\n     */\r\n    public alwaysHideSelectionMesh: boolean = false;\r\n\r\n    /**\r\n     * constructs a new background remover module\r\n     * @param _xrSessionManager the session manager for this module\r\n     * @param _options read-only options to be used in this module\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private readonly _options: IWebXRNearInteractionOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this._scene = this._xrSessionManager.scene;\r\n        if (this._options.nearInteractionControllerMode === undefined) {\r\n            this._options.nearInteractionControllerMode = WebXRNearControllerMode.CENTERED_IN_FRONT;\r\n        }\r\n\r\n        if (this._options.farInteractionFeature) {\r\n            this._farInteractionFeature = this._options.farInteractionFeature;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        for (const controller of this._options.xrInput.controllers) {\r\n            this._attachController(controller);\r\n        }\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\r\n            // REMOVE the controller\r\n            this._detachController(controller.uniqueId);\r\n        });\r\n\r\n        this._scene.constantlyUpdateMeshUnderPointer = true;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        const keys = Object.keys(this._controllers);\r\n        for (const controllerId of keys) {\r\n            this._detachController(controllerId);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Will get the mesh under a specific pointer.\r\n     * `scene.meshUnderPointer` will only return one mesh - either left or right.\r\n     * @param controllerId the controllerId to check\r\n     * @returns The mesh under pointer or null if no mesh is under the pointer\r\n     */\r\n    public getMeshUnderPointer(controllerId: string): Nullable<AbstractMesh> {\r\n        if (this._controllers[controllerId]) {\r\n            return this._controllers[controllerId].meshUnderPointer;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the xr controller that correlates to the pointer id in the pointer event\r\n     *\r\n     * @param id the pointer id to search for\r\n     * @returns the controller that correlates to this id or null if not found\r\n     */\r\n    public getXRControllerByPointerId(id: number): Nullable<WebXRInputSource> {\r\n        const keys = Object.keys(this._controllers);\r\n\r\n        for (let i = 0; i < keys.length; ++i) {\r\n            if (this._controllers[keys[i]].id === id) {\r\n                return this._controllers[keys[i]].xrController || null;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * This function sets webXRControllerPointerSelection feature that will be disabled when\r\n     * the hover range is reached for a mesh and will be reattached when not in hover range.\r\n     * This is used to remove the selection rays when moving.\r\n     * @param farInteractionFeature the feature to disable when finger is in hover range for a mesh\r\n     */\r\n    public setFarInteractionFeature(farInteractionFeature: Nullable<WebXRControllerPointerSelection>) {\r\n        this._farInteractionFeature = farInteractionFeature;\r\n    }\r\n\r\n    /**\r\n     * Filter used for near interaction pick and hover\r\n     * @param mesh the mesh candidate to be pick-filtered\r\n     * @returns if the mesh should be included in the list of candidate meshes for near interaction\r\n     */\r\n    private _nearPickPredicate(mesh: AbstractMesh): boolean {\r\n        return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearPickable;\r\n    }\r\n\r\n    /**\r\n     * Filter used for near interaction grab\r\n     * @param mesh the mesh candidate to be pick-filtered\r\n     * @returns if the mesh should be included in the list of candidate meshes for near interaction\r\n     */\r\n    private _nearGrabPredicate(mesh: AbstractMesh): boolean {\r\n        return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearGrabbable;\r\n    }\r\n\r\n    /**\r\n     * Filter used for any near interaction\r\n     * @param mesh the mesh candidate to be pick-filtered\r\n     * @returns if the mesh should be included in the list of candidate meshes for near interaction\r\n     */\r\n    private _nearInteractionPredicate(mesh: AbstractMesh): boolean {\r\n        return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && (mesh.isNearPickable || mesh.isNearGrabbable);\r\n    }\r\n\r\n    private _controllerAvailablePredicate(mesh: AbstractMesh, controllerId: string): boolean {\r\n        let parent: TransformNode = mesh;\r\n\r\n        while (parent) {\r\n            if (parent.reservedDataStore && parent.reservedDataStore.nearInteraction && parent.reservedDataStore.nearInteraction.excludedControllerId === controllerId) {\r\n                return false;\r\n            }\r\n            parent = parent.parent as TransformNode;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _handleTransitionAnimation(controllerData: ControllerData, newState: ControllerOrbAnimationState) {\r\n        if (\r\n            controllerData.currentAnimationState === newState ||\r\n            this._options.nearInteractionControllerMode !== WebXRNearControllerMode.CENTERED_IN_FRONT ||\r\n            !!controllerData.xrController?.inputSource.hand\r\n        ) {\r\n            return;\r\n        }\r\n\r\n        // Don't always break to allow for animation fallthrough on rare cases of multi-transitions\r\n        if (newState > controllerData.currentAnimationState) {\r\n            switch (controllerData.currentAnimationState) {\r\n                case ControllerOrbAnimationState.DEHYDRATED: {\r\n                    controllerData.hydrateCollisionMeshFunction(true);\r\n                    if (newState === ControllerOrbAnimationState.HOVER) {\r\n                        break;\r\n                    }\r\n                }\r\n                // eslint-disable-next-line no-fallthrough\r\n                case ControllerOrbAnimationState.HOVER: {\r\n                    controllerData.touchCollisionMeshFunction(true);\r\n                    if (newState === ControllerOrbAnimationState.TOUCH) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            switch (controllerData.currentAnimationState) {\r\n                case ControllerOrbAnimationState.TOUCH: {\r\n                    controllerData.touchCollisionMeshFunction(false);\r\n                    if (newState === ControllerOrbAnimationState.HOVER) {\r\n                        break;\r\n                    }\r\n                }\r\n                // eslint-disable-next-line no-fallthrough\r\n                case ControllerOrbAnimationState.HOVER: {\r\n                    controllerData.hydrateCollisionMeshFunction(false);\r\n                    if (newState === ControllerOrbAnimationState.DEHYDRATED) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        controllerData.currentAnimationState = newState;\r\n    }\r\n\r\n    private readonly _hoverRadius = 0.1;\r\n    private readonly _pickRadius = 0.02;\r\n    private readonly _controllerPickRadius = 0.03; // The radius is slightly larger here to make it easier to manipulate since it's not tied to the hand position\r\n    private readonly _nearGrabLengthScale = 5;\r\n\r\n    private _processTouchPoint(id: string, position: Vector3, orientation: Quaternion) {\r\n        const controllerData = this._controllers[id];\r\n\r\n        // Position and orientation could be temporary values, se we take care of them before calling any functions that use temporary vectors/quaternions\r\n        controllerData.grabRay.origin.copyFrom(position);\r\n        orientation.toEulerAnglesToRef(TmpVectors.Vector3[0]);\r\n        controllerData.grabRay.direction.copyFrom(TmpVectors.Vector3[0]);\r\n\r\n        if (this._options.nearInteractionControllerMode === WebXRNearControllerMode.CENTERED_IN_FRONT && !controllerData.xrController?.inputSource.hand) {\r\n            // offset the touch point in the direction the transform is facing\r\n            controllerData.xrController!.getWorldPointerRayToRef(this._tmpRay);\r\n            controllerData.grabRay.origin.addInPlace(this._tmpRay.direction.scale(0.05));\r\n        }\r\n\r\n        controllerData.grabRay.length = this._nearGrabLengthScale * this._hoverRadius * this._xrSessionManager.worldScalingFactor;\r\n        controllerData.touchCollisionMesh.position.copyFrom(controllerData.grabRay.origin).scaleInPlace(this._xrSessionManager.worldScalingFactor);\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame) {\r\n        const keys = Object.keys(this._controllers);\r\n        for (const id of keys) {\r\n            // only do this for the selected pointer\r\n            const controllerData = this._controllers[id];\r\n            const handData = controllerData.xrController?.inputSource.hand;\r\n            // If near interaction is not enabled/available for this controller, skip it\r\n            if (\r\n                (!this._options.enableNearInteractionOnAllControllers && id !== this._attachedController) ||\r\n                !controllerData.xrController ||\r\n                (!handData && (!this._options.nearInteractionControllerMode || !controllerData.xrController.inputSource.gamepad))\r\n            ) {\r\n                controllerData.pick = null;\r\n                continue;\r\n            }\r\n            controllerData.hoverInteraction = false;\r\n            controllerData.nearInteraction = false;\r\n\r\n            // Every frame check collisions/input\r\n            if (controllerData.xrController) {\r\n                if (handData) {\r\n                    const xrIndexTip = handData.get(\"index-finger-tip\");\r\n                    if (xrIndexTip) {\r\n                        const indexTipPose = _xrFrame.getJointPose!(xrIndexTip, this._xrSessionManager.referenceSpace);\r\n                        if (indexTipPose && indexTipPose.transform) {\r\n                            const axisRHSMultiplier = this._scene.useRightHandedSystem ? 1 : -1;\r\n                            TmpVectors.Vector3[0].set(indexTipPose.transform.position.x, indexTipPose.transform.position.y, indexTipPose.transform.position.z * axisRHSMultiplier);\r\n                            TmpVectors.Quaternion[0].set(\r\n                                indexTipPose.transform.orientation.x,\r\n                                indexTipPose.transform.orientation.y,\r\n                                indexTipPose.transform.orientation.z * axisRHSMultiplier,\r\n                                indexTipPose.transform.orientation.w * axisRHSMultiplier\r\n                            );\r\n\r\n                            this._processTouchPoint(id, TmpVectors.Vector3[0], TmpVectors.Quaternion[0]);\r\n                        }\r\n                    }\r\n                } else if (controllerData.xrController.inputSource.gamepad && this._options.nearInteractionControllerMode !== WebXRNearControllerMode.DISABLED) {\r\n                    let controllerPose = controllerData.xrController.pointer;\r\n                    if (controllerData.xrController.grip && this._options.nearInteractionControllerMode === WebXRNearControllerMode.CENTERED_ON_CONTROLLER) {\r\n                        controllerPose = controllerData.xrController.grip;\r\n                    }\r\n\r\n                    this._processTouchPoint(id, controllerPose.position, controllerPose.rotationQuaternion!);\r\n                }\r\n            } else {\r\n                continue;\r\n            }\r\n\r\n            const accuratePickInfo = (originalScenePick: Nullable<PickingInfo>, utilityScenePick: Nullable<PickingInfo>): Nullable<PickingInfo> => {\r\n                let pick: Nullable<PickingInfo>;\r\n                if (!utilityScenePick || !utilityScenePick.hit) {\r\n                    // No hit in utility scene\r\n                    pick = originalScenePick;\r\n                } else if (!originalScenePick || !originalScenePick.hit) {\r\n                    // No hit in original scene\r\n                    pick = utilityScenePick;\r\n                } else if (utilityScenePick.distance < originalScenePick.distance) {\r\n                    // Hit is closer in utility scene\r\n                    pick = utilityScenePick;\r\n                } else {\r\n                    // Hit is closer in original scene\r\n                    pick = originalScenePick;\r\n                }\r\n                return pick;\r\n            };\r\n            const populateNearInteractionInfo = (nearInteractionInfo: Nullable<PickingInfo>): PickingInfo => {\r\n                let result = new PickingInfo();\r\n\r\n                let nearInteractionAtOrigin = false;\r\n                const nearInteraction = nearInteractionInfo && nearInteractionInfo.pickedPoint && nearInteractionInfo.hit;\r\n                if (nearInteractionInfo?.pickedPoint) {\r\n                    nearInteractionAtOrigin = nearInteractionInfo.pickedPoint.x === 0 && nearInteractionInfo.pickedPoint.y === 0 && nearInteractionInfo.pickedPoint.z === 0;\r\n                }\r\n                if (nearInteraction && !nearInteractionAtOrigin) {\r\n                    result = nearInteractionInfo!;\r\n                }\r\n                return result;\r\n            };\r\n\r\n            // Don't perform touch logic while grabbing, to prevent triggering touch interactions while in the middle of a grab interaction\r\n            // Dont update cursor logic either - the cursor should already be visible for the grab to be in range,\r\n            // and in order to maintain its position on the target mesh it is parented for the duration of the grab.\r\n            if (!controllerData.grabInteraction) {\r\n                let pick = null;\r\n\r\n                // near interaction hover\r\n                let utilitySceneHoverPick = null;\r\n                if (this._options.useUtilityLayer && this._utilityLayerScene) {\r\n                    utilitySceneHoverPick = this._pickWithSphere(\r\n                        controllerData,\r\n                        this._hoverRadius * this._xrSessionManager.worldScalingFactor,\r\n                        this._utilityLayerScene,\r\n                        (mesh: AbstractMesh) => this._nearInteractionPredicate(mesh)\r\n                    );\r\n                }\r\n                const originalSceneHoverPick = this._pickWithSphere(\r\n                    controllerData,\r\n                    this._hoverRadius * this._xrSessionManager.worldScalingFactor,\r\n                    this._scene,\r\n                    (mesh: AbstractMesh) => this._nearInteractionPredicate(mesh)\r\n                );\r\n\r\n                const hoverPickInfo = accuratePickInfo(originalSceneHoverPick, utilitySceneHoverPick);\r\n                if (hoverPickInfo && hoverPickInfo.hit) {\r\n                    pick = populateNearInteractionInfo(hoverPickInfo);\r\n                    if (pick.hit) {\r\n                        controllerData.hoverInteraction = true;\r\n                    }\r\n                }\r\n\r\n                // near interaction pick\r\n                if (controllerData.hoverInteraction) {\r\n                    let utilitySceneNearPick = null;\r\n                    const radius = (handData ? this._pickRadius : this._controllerPickRadius) * this._xrSessionManager.worldScalingFactor;\r\n                    if (this._options.useUtilityLayer && this._utilityLayerScene) {\r\n                        utilitySceneNearPick = this._pickWithSphere(controllerData, radius, this._utilityLayerScene, (mesh: AbstractMesh) => this._nearPickPredicate(mesh));\r\n                    }\r\n                    const originalSceneNearPick = this._pickWithSphere(controllerData, radius, this._scene, (mesh: AbstractMesh) => this._nearPickPredicate(mesh));\r\n                    const pickInfo = accuratePickInfo(originalSceneNearPick, utilitySceneNearPick);\r\n                    const nearPick = populateNearInteractionInfo(pickInfo);\r\n                    if (nearPick.hit) {\r\n                        // Near pick takes precedence over hover interaction\r\n                        pick = nearPick;\r\n                        controllerData.nearInteraction = true;\r\n                    }\r\n                }\r\n\r\n                controllerData.stalePick = controllerData.pick;\r\n                controllerData.pick = pick;\r\n\r\n                // Update mesh under pointer\r\n                if (controllerData.pick && controllerData.pick.pickedPoint && controllerData.pick.hit) {\r\n                    controllerData.meshUnderPointer = controllerData.pick.pickedMesh;\r\n                    controllerData.pickedPointVisualCue.position.copyFrom(controllerData.pick.pickedPoint);\r\n                    controllerData.pickedPointVisualCue.isVisible = !this.alwaysHideSelectionMesh;\r\n\r\n                    if (this._farInteractionFeature && this._farInteractionFeature.attached) {\r\n                        this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, true);\r\n                    }\r\n                } else {\r\n                    controllerData.meshUnderPointer = null;\r\n                    controllerData.pickedPointVisualCue.isVisible = false;\r\n\r\n                    if (this._farInteractionFeature && this._farInteractionFeature.attached) {\r\n                        this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, false);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Update the interaction animation. Only updates if the visible touch mesh is active\r\n            let state = ControllerOrbAnimationState.DEHYDRATED;\r\n            if (controllerData.grabInteraction || controllerData.nearInteraction) {\r\n                state = ControllerOrbAnimationState.TOUCH;\r\n            } else if (controllerData.hoverInteraction) {\r\n                state = ControllerOrbAnimationState.HOVER;\r\n            }\r\n            this._handleTransitionAnimation(controllerData, state);\r\n        }\r\n    }\r\n\r\n    private get _utilityLayerScene() {\r\n        return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\r\n    }\r\n\r\n    private _generateVisualCue() {\r\n        const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n        const selectionMesh = CreateSphere(\r\n            \"nearInteraction\",\r\n            {\r\n                diameter: 0.0035 * 3 * this._xrSessionManager.worldScalingFactor,\r\n            },\r\n            sceneToRenderTo\r\n        );\r\n        selectionMesh.bakeCurrentTransformIntoVertices();\r\n        selectionMesh.isPickable = false;\r\n        selectionMesh.isVisible = false;\r\n        selectionMesh.rotationQuaternion = Quaternion.Identity();\r\n        const targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\r\n        targetMat.specularColor = Color3.Black();\r\n        targetMat.emissiveColor = this.selectionMeshDefaultColor;\r\n        targetMat.backFaceCulling = false;\r\n        selectionMesh.material = targetMat;\r\n\r\n        return selectionMesh;\r\n    }\r\n\r\n    private _isControllerReadyForNearInteraction(id: number) {\r\n        if (this._farInteractionFeature) {\r\n            return this._farInteractionFeature._getPointerSelectionDisabledByPointerId(id);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _attachNearInteractionMode(xrController: WebXRInputSource) {\r\n        const controllerData = this._controllers[xrController.uniqueId];\r\n        const pointerEventInit: PointerEventInit = {\r\n            pointerId: controllerData.id,\r\n            pointerType: \"xr-near\",\r\n        };\r\n        controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\r\n            if (\r\n                (!this._options.enableNearInteractionOnAllControllers && xrController.uniqueId !== this._attachedController) ||\r\n                !controllerData.xrController ||\r\n                (!controllerData.xrController.inputSource.hand && (!this._options.nearInteractionControllerMode || !controllerData.xrController.inputSource.gamepad))\r\n            ) {\r\n                return;\r\n            }\r\n            if (controllerData.pick) {\r\n                controllerData.pick.ray = controllerData.grabRay;\r\n            }\r\n\r\n            if (controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\r\n                this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n            }\r\n\r\n            // Near pick pointer event\r\n            if (controllerData.nearInteraction && controllerData.pick && controllerData.pick.hit) {\r\n                if (!controllerData.nearInteractionTargetMesh) {\r\n                    this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                    controllerData.nearInteractionTargetMesh = controllerData.meshUnderPointer;\r\n                    controllerData.downTriggered = true;\r\n                }\r\n            } else if (controllerData.nearInteractionTargetMesh && controllerData.stalePick) {\r\n                this._scene.simulatePointerUp(controllerData.stalePick, pointerEventInit);\r\n                controllerData.downTriggered = false;\r\n                controllerData.nearInteractionTargetMesh = null;\r\n            }\r\n        });\r\n\r\n        const grabCheck = (pressed: boolean) => {\r\n            if (\r\n                this._options.enableNearInteractionOnAllControllers ||\r\n                (xrController.uniqueId === this._attachedController && this._isControllerReadyForNearInteraction(controllerData.id))\r\n            ) {\r\n                if (controllerData.pick) {\r\n                    controllerData.pick.ray = controllerData.grabRay;\r\n                }\r\n                if (pressed && controllerData.pick && controllerData.meshUnderPointer && this._nearGrabPredicate(controllerData.meshUnderPointer)) {\r\n                    controllerData.grabInteraction = true;\r\n                    controllerData.pickedPointVisualCue.isVisible = false;\r\n                    this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                    controllerData.downTriggered = true;\r\n                } else if (!pressed && controllerData.pick && controllerData.grabInteraction) {\r\n                    this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                    controllerData.downTriggered = false;\r\n                    controllerData.grabInteraction = false;\r\n                    controllerData.pickedPointVisualCue.isVisible = !this.alwaysHideSelectionMesh;\r\n                }\r\n            } else {\r\n                if (pressed && !this._options.enableNearInteractionOnAllControllers && !this._options.disableSwitchOnClick) {\r\n                    this._attachedController = xrController.uniqueId;\r\n                }\r\n            }\r\n        };\r\n\r\n        if (xrController.inputSource.gamepad) {\r\n            const init = (motionController: WebXRAbstractMotionController) => {\r\n                controllerData.squeezeComponent = motionController.getComponent(\"grasp\");\r\n                if (controllerData.squeezeComponent) {\r\n                    controllerData.onSqueezeButtonChangedObserver = controllerData.squeezeComponent.onButtonStateChangedObservable.add((component) => {\r\n                        if (component.changes.pressed) {\r\n                            const pressed = component.changes.pressed.current;\r\n                            grabCheck(pressed);\r\n                        }\r\n                    });\r\n                } else {\r\n                    controllerData.selectionComponent = motionController.getMainComponent();\r\n                    controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {\r\n                        if (component.changes.pressed) {\r\n                            const pressed = component.changes.pressed.current;\r\n                            grabCheck(pressed);\r\n                        }\r\n                    });\r\n                }\r\n            };\r\n            if (xrController.motionController) {\r\n                init(xrController.motionController);\r\n            } else {\r\n                xrController.onMotionControllerInitObservable.add(init);\r\n            }\r\n        } else {\r\n            // use the select and squeeze events\r\n            const selectStartListener = (event: XRInputSourceEvent) => {\r\n                if (\r\n                    controllerData.xrController &&\r\n                    event.inputSource === controllerData.xrController.inputSource &&\r\n                    controllerData.pick &&\r\n                    this._isControllerReadyForNearInteraction(controllerData.id) &&\r\n                    controllerData.meshUnderPointer &&\r\n                    this._nearGrabPredicate(controllerData.meshUnderPointer)\r\n                ) {\r\n                    controllerData.grabInteraction = true;\r\n                    controllerData.pickedPointVisualCue.isVisible = false;\r\n                    this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n                    controllerData.downTriggered = true;\r\n                }\r\n            };\r\n\r\n            const selectEndListener = (event: XRInputSourceEvent) => {\r\n                if (\r\n                    controllerData.xrController &&\r\n                    event.inputSource === controllerData.xrController.inputSource &&\r\n                    controllerData.pick &&\r\n                    this._isControllerReadyForNearInteraction(controllerData.id)\r\n                ) {\r\n                    this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n                    controllerData.grabInteraction = false;\r\n                    controllerData.pickedPointVisualCue.isVisible = !this.alwaysHideSelectionMesh;\r\n                    controllerData.downTriggered = false;\r\n                }\r\n            };\r\n\r\n            controllerData.eventListeners = {\r\n                selectend: selectEndListener,\r\n                selectstart: selectStartListener,\r\n            };\r\n\r\n            this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\r\n            this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\r\n        }\r\n    }\r\n\r\n    private _detachController(xrControllerUniqueId: string) {\r\n        const controllerData = this._controllers[xrControllerUniqueId];\r\n        if (!controllerData) {\r\n            return;\r\n        }\r\n        if (controllerData.squeezeComponent) {\r\n            if (controllerData.onSqueezeButtonChangedObserver) {\r\n                controllerData.squeezeComponent.onButtonStateChangedObservable.remove(controllerData.onSqueezeButtonChangedObserver);\r\n            }\r\n        }\r\n        if (controllerData.selectionComponent) {\r\n            if (controllerData.onButtonChangedObserver) {\r\n                controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\r\n            }\r\n        }\r\n        if (controllerData.onFrameObserver) {\r\n            this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\r\n        }\r\n        if (controllerData.eventListeners) {\r\n            const keys = Object.keys(controllerData.eventListeners);\r\n            for (const eventName of keys) {\r\n                const func = controllerData.eventListeners && controllerData.eventListeners[eventName as XREventType];\r\n                if (func) {\r\n                    this._xrSessionManager.session.removeEventListener(eventName as XREventType, func as any);\r\n                }\r\n            }\r\n        }\r\n        controllerData.touchCollisionMesh.dispose();\r\n        controllerData.pickedPointVisualCue.dispose();\r\n\r\n        this._xrSessionManager.runInXRFrame(() => {\r\n            if (!controllerData.downTriggered) {\r\n                return;\r\n            }\r\n            // Fire a pointerup in case controller was detached before a pointerup event was fired\r\n            const pointerEventInit: PointerEventInit = {\r\n                pointerId: controllerData.id,\r\n                pointerType: \"xr-near\",\r\n            };\r\n            this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);\r\n        });\r\n\r\n        // remove world scale observer\r\n        if (controllerData._worldScaleObserver) {\r\n            this._xrSessionManager.onWorldScaleFactorChangedObservable.remove(controllerData._worldScaleObserver);\r\n        }\r\n\r\n        // remove from the map\r\n        delete this._controllers[xrControllerUniqueId];\r\n        if (this._attachedController === xrControllerUniqueId) {\r\n            // check for other controllers\r\n            const keys = Object.keys(this._controllers);\r\n            if (keys.length) {\r\n                this._attachedController = keys[0];\r\n            } else {\r\n                this._attachedController = \"\";\r\n            }\r\n        }\r\n    }\r\n\r\n    private _generateNewTouchPointMesh() {\r\n        const worldScale = this._xrSessionManager.worldScalingFactor;\r\n        // populate information for near hover, pick and pinch\r\n        const meshCreationScene = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n\r\n        const touchCollisionMesh = CreateSphere(\"PickSphere\", { diameter: 1 * worldScale }, meshCreationScene);\r\n        touchCollisionMesh.isVisible = false;\r\n\r\n        // Generate the material for the touch mesh visuals\r\n        if (this._options.motionControllerOrbMaterial) {\r\n            touchCollisionMesh.material = this._options.motionControllerOrbMaterial;\r\n        } else {\r\n            let parsePromise: Promise<NodeMaterial>;\r\n            if (this._options.motionControllerTouchMaterialSnippetUrl) {\r\n                parsePromise = NodeMaterialParseFromFileAsync(\"motionControllerTouchMaterial\", this._options.motionControllerTouchMaterialSnippetUrl, meshCreationScene);\r\n            } else {\r\n                parsePromise = NodeMaterialParseFromSnippetAsync(\"8RUNKL#3\", meshCreationScene);\r\n            }\r\n            parsePromise\r\n                // eslint-disable-next-line github/no-then\r\n                .then((mat) => {\r\n                    touchCollisionMesh.material = mat;\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .catch((err) => {\r\n                    Logger.Warn(`Error creating touch material in WebXRNearInteraction: ${err}`);\r\n                });\r\n        }\r\n\r\n        const easingFunction = new QuadraticEase();\r\n        easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);\r\n\r\n        // Adjust the visual size based off of the size of the touch collision orb.\r\n        // Having the size perfectly match for hover gives a more accurate tell for when the user will start interacting with the target\r\n        // Sizes for other states are somewhat arbitrary, as they are based on what feels nice during an interaction\r\n        const hoverSizeVec = new Vector3(this._controllerPickRadius, this._controllerPickRadius, this._controllerPickRadius).scaleInPlace(worldScale);\r\n        const touchSize = this._controllerPickRadius * (4 / 3);\r\n        const touchSizeVec = new Vector3(touchSize, touchSize, touchSize).scaleInPlace(worldScale);\r\n        const hydrateTransitionSize = this._controllerPickRadius * (7 / 6);\r\n        const hydrateTransitionSizeVec = new Vector3(hydrateTransitionSize, hydrateTransitionSize, hydrateTransitionSize).scaleInPlace(worldScale);\r\n        const touchHoverTransitionSize = this._controllerPickRadius * (4 / 5);\r\n        const touchHoverTransitionSizeVec = new Vector3(touchHoverTransitionSize, touchHoverTransitionSize, touchHoverTransitionSize).scaleInPlace(worldScale);\r\n        const hoverTouchTransitionSize = this._controllerPickRadius * (3 / 2);\r\n        const hoverTouchTransitionSizeVec = new Vector3(hoverTouchTransitionSize, hoverTouchTransitionSize, hoverTouchTransitionSize).scaleInPlace(worldScale);\r\n\r\n        const touchKeys = [\r\n            { frame: 0, value: hoverSizeVec },\r\n            { frame: 10, value: hoverTouchTransitionSizeVec },\r\n            { frame: 18, value: touchSizeVec },\r\n        ];\r\n        const releaseKeys = [\r\n            { frame: 0, value: touchSizeVec },\r\n            { frame: 10, value: touchHoverTransitionSizeVec },\r\n            { frame: 18, value: hoverSizeVec },\r\n        ];\r\n        const hydrateKeys = [\r\n            { frame: 0, value: Vector3.ZeroReadOnly },\r\n            { frame: 12, value: hydrateTransitionSizeVec },\r\n            { frame: 15, value: hoverSizeVec },\r\n        ];\r\n        const dehydrateKeys = [\r\n            { frame: 0, value: hoverSizeVec },\r\n            { frame: 10, value: Vector3.ZeroReadOnly },\r\n            { frame: 15, value: Vector3.ZeroReadOnly },\r\n        ];\r\n\r\n        const touchAction = new Animation(\"touch\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n        const releaseAction = new Animation(\"release\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n        const hydrateAction = new Animation(\"hydrate\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n        const dehydrateAction = new Animation(\"dehydrate\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\r\n\r\n        touchAction.setEasingFunction(easingFunction);\r\n        releaseAction.setEasingFunction(easingFunction);\r\n        hydrateAction.setEasingFunction(easingFunction);\r\n        dehydrateAction.setEasingFunction(easingFunction);\r\n\r\n        touchAction.setKeys(touchKeys);\r\n        releaseAction.setKeys(releaseKeys);\r\n        hydrateAction.setKeys(hydrateKeys);\r\n        dehydrateAction.setKeys(dehydrateKeys);\r\n\r\n        const touchCollisionMeshFunction = (isTouch: boolean) => {\r\n            const action = isTouch ? touchAction : releaseAction;\r\n            meshCreationScene.beginDirectAnimation(touchCollisionMesh, [action], 0, 18, false, 1);\r\n        };\r\n\r\n        const hydrateCollisionMeshFunction = (isHydration: boolean) => {\r\n            const action = isHydration ? hydrateAction : dehydrateAction;\r\n            if (isHydration) {\r\n                touchCollisionMesh.isVisible = true;\r\n            }\r\n            meshCreationScene.beginDirectAnimation(touchCollisionMesh, [action], 0, 15, false, 1, () => {\r\n                if (!isHydration) {\r\n                    touchCollisionMesh.isVisible = false;\r\n                }\r\n            });\r\n        };\r\n\r\n        return { touchCollisionMesh, touchCollisionMeshFunction, hydrateCollisionMeshFunction };\r\n    }\r\n\r\n    private _pickWithSphere(controllerData: ControllerData, radius: number, sceneToUse: Scene, predicate: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo> {\r\n        const pickingInfo = new PickingInfo();\r\n        pickingInfo.distance = +Infinity;\r\n\r\n        if (controllerData.touchCollisionMesh && controllerData.xrController) {\r\n            const position = controllerData.touchCollisionMesh.position;\r\n            const sphere = BoundingSphere.CreateFromCenterAndRadius(position, radius);\r\n\r\n            for (let meshIndex = 0; meshIndex < sceneToUse.meshes.length; meshIndex++) {\r\n                const mesh = sceneToUse.meshes[meshIndex];\r\n                if (!predicate(mesh) || !this._controllerAvailablePredicate(mesh, controllerData.xrController.uniqueId)) {\r\n                    continue;\r\n                }\r\n                const result = WebXRNearInteractionPickMeshWithSphere(mesh, sphere);\r\n\r\n                if (result && result.hit && result.distance < pickingInfo.distance) {\r\n                    pickingInfo.hit = result.hit;\r\n                    pickingInfo.pickedMesh = mesh;\r\n                    pickingInfo.pickedPoint = result.pickedPoint;\r\n                    pickingInfo.aimTransform = controllerData.xrController.pointer;\r\n                    pickingInfo.gripTransform = controllerData.xrController.grip || null;\r\n                    pickingInfo.originMesh = controllerData.touchCollisionMesh;\r\n                    pickingInfo.distance = result.distance;\r\n                    pickingInfo.bu = result.bu;\r\n                    pickingInfo.bv = result.bv;\r\n                    pickingInfo.faceId = result.faceId;\r\n                    pickingInfo.subMeshId = result.subMeshId;\r\n                }\r\n            }\r\n        }\r\n        return pickingInfo;\r\n    }\r\n}\r\n\r\n/**\r\n * Picks a mesh with a sphere\r\n * @param mesh the mesh to pick\r\n * @param sphere picking sphere in world coordinates\r\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n * @returns the picking info\r\n */\r\nexport function WebXRNearInteractionPickMeshWithSphere(mesh: AbstractMesh, sphere: BoundingSphere, skipBoundingInfo = false): PickingInfo {\r\n    const subMeshes = mesh.subMeshes;\r\n    const pi = new PickingInfo();\r\n    const boundingInfo = mesh.getBoundingInfo();\r\n\r\n    if (!mesh._generatePointsArray()) {\r\n        return pi;\r\n    }\r\n\r\n    if (!mesh.subMeshes || !boundingInfo) {\r\n        return pi;\r\n    }\r\n\r\n    if (!skipBoundingInfo && !BoundingSphere.Intersects(boundingInfo.boundingSphere, sphere)) {\r\n        return pi;\r\n    }\r\n\r\n    const result = LocalTempVectors[0];\r\n    const tmpVec = LocalTempVectors[1];\r\n    LocalTempVectors[2].setAll(0);\r\n    LocalTempVectors[3].setAll(0);\r\n\r\n    const tmpRay = new Ray(LocalTempVectors[2], LocalTempVectors[3], 1);\r\n\r\n    let distance = +Infinity;\r\n    let tmp, tmpDistanceSphereToCenter, tmpDistanceSurfaceToCenter, intersectionInfo;\r\n    const center = TmpVectors.Vector3[2];\r\n    const worldToMesh = TmpVectors.Matrix[0];\r\n    worldToMesh.copyFrom(mesh.getWorldMatrix());\r\n    worldToMesh.invert();\r\n    Vector3.TransformCoordinatesToRef(sphere.center, worldToMesh, center);\r\n\r\n    for (let index = 0; index < subMeshes.length; index++) {\r\n        const subMesh = subMeshes[index];\r\n\r\n        subMesh.projectToRef(center, <Vector3[]>mesh._positions, <IndicesArray>mesh.getIndices(), tmpVec);\r\n\r\n        Vector3.TransformCoordinatesToRef(tmpVec, mesh.getWorldMatrix(), tmpVec);\r\n        tmp = Vector3.Distance(tmpVec, sphere.center);\r\n\r\n        // Check for finger inside of mesh\r\n        tmpDistanceSurfaceToCenter = Vector3.DistanceSquared(tmpVec, mesh.getAbsolutePosition());\r\n        tmpDistanceSphereToCenter = Vector3.DistanceSquared(sphere.center, mesh.getAbsolutePosition());\r\n        if (tmpDistanceSphereToCenter !== -1 && tmpDistanceSurfaceToCenter !== -1 && tmpDistanceSurfaceToCenter > tmpDistanceSphereToCenter) {\r\n            tmp = 0;\r\n            tmpVec.copyFrom(sphere.center);\r\n        }\r\n\r\n        if (tmp !== -1 && tmp < distance) {\r\n            distance = tmp;\r\n\r\n            // ray between the sphere center and the point on the mesh\r\n            Ray.CreateFromToToRef(sphere.center, tmpVec, tmpRay);\r\n            tmpRay.length = distance * 2;\r\n            intersectionInfo = tmpRay.intersectsMesh(mesh);\r\n\r\n            result.copyFrom(tmpVec);\r\n        }\r\n    }\r\n\r\n    if (distance < sphere.radius) {\r\n        pi.hit = true;\r\n        pi.distance = distance;\r\n        pi.pickedMesh = mesh;\r\n        pi.pickedPoint = result.clone();\r\n        if (intersectionInfo && intersectionInfo.bu !== null && intersectionInfo.bv !== null) {\r\n            pi.faceId = intersectionInfo.faceId;\r\n            pi.subMeshId = intersectionInfo.subMeshId;\r\n            pi.bu = intersectionInfo.bu;\r\n            pi.bv = intersectionInfo.bv;\r\n        }\r\n    }\r\n\r\n    return pi;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRNearInteraction.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRNearInteraction(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebXRNearInteraction.PickMeshWithSphere = WebXRNearInteractionPickMeshWithSphere;\r\n\r\n    //Register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRNearInteraction.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRNearInteraction(xrSessionManager, options);\r\n        },\r\n        WebXRNearInteraction.Version,\r\n        true\r\n    );\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type IDisposable, type Scene } from \"../scene\";\r\nimport { type WebXRExperienceHelper } from \"./webXRExperienceHelper\";\r\nimport { type WebXRRenderTarget, WebXRState } from \"./webXRTypes\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\n/**\r\n * Button which can be used to enter a different mode of XR\r\n */\r\nexport class WebXREnterExitUIButton {\r\n    /**\r\n     * Creates a WebXREnterExitUIButton\r\n     * @param element button element\r\n     * @param sessionMode XR initialization session mode\r\n     * @param referenceSpaceType the type of reference space to be used\r\n     */\r\n    constructor(\r\n        /** button element */\r\n        public element: HTMLElement,\r\n        /** XR initialization options for the button */\r\n        public sessionMode: XRSessionMode,\r\n        /** Reference space type */\r\n        public referenceSpaceType: XRReferenceSpaceType\r\n    ) {}\r\n\r\n    /**\r\n     * Extendable function which can be used to update the button's visuals when the state changes\r\n     * @param activeButton the current active button in the UI\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public update(activeButton: Nullable<WebXREnterExitUIButton>) {}\r\n}\r\n\r\n/**\r\n * Options to create the webXR UI\r\n */\r\nexport class WebXREnterExitUIOptions {\r\n    /**\r\n     * User provided buttons to enable/disable WebXR. The system will provide default if not set\r\n     */\r\n    customButtons?: Array<WebXREnterExitUIButton>;\r\n    /**\r\n     * A reference space type to use when creating the default button.\r\n     * Default is local-floor\r\n     */\r\n    referenceSpaceType?: XRReferenceSpaceType;\r\n    /**\r\n     * Context to enter xr with\r\n     */\r\n    renderTarget?: Nullable<WebXRRenderTarget>;\r\n    /**\r\n     * A session mode to use when creating the default button.\r\n     * Default is immersive-vr\r\n     */\r\n    sessionMode?: XRSessionMode;\r\n\r\n    /**\r\n     * A list of optional features to init the session with\r\n     */\r\n    optionalFeatures?: string[];\r\n\r\n    /**\r\n     * A list of optional features to init the session with\r\n     */\r\n    requiredFeatures?: string[];\r\n\r\n    /**\r\n     * If set, the `sessiongranted` event will not be registered. `sessiongranted` is used to move seamlessly between WebXR experiences.\r\n     * If set to true the user will be forced to press the \"enter XR\" button even if sessiongranted event was triggered.\r\n     * If not set and a sessiongranted event was triggered, the XR session will start automatically.\r\n     */\r\n    ignoreSessionGrantedEvent?: boolean;\r\n\r\n    /**\r\n     * If defined, this function will be executed if the UI encounters an error when entering XR\r\n     */\r\n    onError?: (error: any) => void;\r\n}\r\n/**\r\n * UI to allow the user to enter/exit XR mode\r\n */\r\nexport class WebXREnterExitUI implements IDisposable {\r\n    private _activeButton: Nullable<WebXREnterExitUIButton> = null;\r\n    private _buttons: Array<WebXREnterExitUIButton> = [];\r\n    private _helper: WebXRExperienceHelper;\r\n    private _renderTarget?: WebXRRenderTarget;\r\n    /**\r\n     * The HTML Div Element to which buttons are added.\r\n     */\r\n    public readonly overlay: HTMLDivElement;\r\n\r\n    /**\r\n     * Fired every time the active button is changed.\r\n     *\r\n     * When xr is entered via a button that launches xr that button will be the callback parameter\r\n     *\r\n     * When exiting xr the callback parameter will be null)\r\n     */\r\n    public activeButtonChangedObservable = new Observable<Nullable<WebXREnterExitUIButton>>();\r\n\r\n    /**\r\n     * Construct a new EnterExit UI class\r\n     *\r\n     * @param _scene babylon scene object to use\r\n     * @param options (read-only) version of the options passed to this UI\r\n     */\r\n    public constructor(\r\n        private _scene: Scene,\r\n        /** version of the options passed to this UI */\r\n        public options: WebXREnterExitUIOptions\r\n    ) {\r\n        this.overlay = document.createElement(\"div\");\r\n        this.overlay.classList.add(\"xr-button-overlay\");\r\n\r\n        // prepare for session granted event\r\n        if (!options.ignoreSessionGrantedEvent && (navigator as any).xr) {\r\n            (navigator as any).xr.addEventListener(\"sessiongranted\", this._onSessionGranted);\r\n        }\r\n\r\n        // if served over HTTP, warn people.\r\n        // Hopefully the browsers will catch up\r\n        if (typeof window !== \"undefined\") {\r\n            if (window.location && window.location.protocol === \"http:\" && window.location.hostname !== \"localhost\") {\r\n                Tools.Warn(\"WebXR can only be served over HTTPS\");\r\n                throw new Error(\"WebXR can only be served over HTTPS\");\r\n            }\r\n        }\r\n\r\n        if (options.customButtons) {\r\n            this._buttons = options.customButtons;\r\n        } else {\r\n            this.overlay.style.cssText = \"z-index:11;position: absolute; right: 20px;bottom: 50px;\";\r\n            const sessionMode = options.sessionMode || \"immersive-vr\";\r\n            const referenceSpaceType = options.referenceSpaceType || \"local-floor\";\r\n            const url =\r\n                typeof SVGSVGElement === \"undefined\"\r\n                    ? \"https://cdn.babylonjs.com/Assets/vrButton.png\"\r\n                    : \"data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%222048%22%20height%3D%221152%22%20viewBox%3D%220%200%202048%201152%22%20version%3D%221.1%22%3E%3Cpath%20transform%3D%22rotate%28180%201024%2C576.0000000000001%29%22%20d%3D%22m1109%2C896q17%2C0%2030%2C-12t13%2C-30t-12.5%2C-30.5t-30.5%2C-12.5l-170%2C0q-18%2C0%20-30.5%2C12.5t-12.5%2C30.5t13%2C30t30%2C12l170%2C0zm-85%2C256q59%2C0%20132.5%2C-1.5t154.5%2C-5.5t164.5%2C-11.5t163%2C-20t150%2C-30t124.5%2C-41.5q23%2C-11%2042%2C-24t38%2C-30q27%2C-25%2041%2C-61.5t14%2C-72.5l0%2C-257q0%2C-123%20-47%2C-232t-128%2C-190t-190%2C-128t-232%2C-47l-81%2C0q-37%2C0%20-68.5%2C14t-60.5%2C34.5t-55.5%2C45t-53%2C45t-53%2C34.5t-55.5%2C14t-55.5%2C-14t-53%2C-34.5t-53%2C-45t-55.5%2C-45t-60.5%2C-34.5t-68.5%2C-14l-81%2C0q-123%2C0%20-232%2C47t-190%2C128t-128%2C190t-47%2C232l0%2C257q0%2C68%2038%2C115t97%2C73q54%2C24%20124.5%2C41.5t150%2C30t163%2C20t164.5%2C11.5t154.5%2C5.5t132.5%2C1.5zm939%2C-298q0%2C39%20-24.5%2C67t-58.5%2C42q-54%2C23%20-122%2C39.5t-143.5%2C28t-155.5%2C19t-157%2C11t-148.5%2C5t-129.5%2C1.5q-59%2C0%20-130%2C-1.5t-148%2C-5t-157%2C-11t-155.5%2C-19t-143.5%2C-28t-122%2C-39.5q-34%2C-14%20-58.5%2C-42t-24.5%2C-67l0%2C-257q0%2C-106%2040.5%2C-199t110%2C-162.5t162.5%2C-109.5t199%2C-40l81%2C0q27%2C0%2052%2C14t50%2C34.5t51%2C44.5t55.5%2C44.5t63.5%2C34.5t74%2C14t74%2C-14t63.5%2C-34.5t55.5%2C-44.5t51%2C-44.5t50%2C-34.5t52%2C-14l14%2C0q37%2C0%2070%2C0.5t64.5%2C4.5t63.5%2C12t68%2C23q71%2C30%20128.5%2C78.5t98.5%2C110t63.5%2C133.5t22.5%2C149l0%2C257z%22%20fill%3D%22white%22%20/%3E%3C/svg%3E%0A\";\r\n            let css =\r\n                \".babylonVRicon { color: #868686; border-color: #868686; border-style: solid; margin-left: 10px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-image: url(\" +\r\n                url +\r\n                \"); background-size: 80%; background-repeat:no-repeat; background-position: center; border: none; outline: none; transition: transform 0.125s ease-out } .babylonVRicon:hover { transform: scale(1.05) } .babylonVRicon:active {background-color: rgba(51,51,51,1) } .babylonVRicon:focus {background-color: rgba(51,51,51,1) }\";\r\n            css += '.babylonVRicon.vrdisplaypresenting { background-image: none;} .vrdisplaypresenting::after { content: \"EXIT\"} .xr-error::after { content: \"ERROR\"}';\r\n\r\n            const style = document.createElement(\"style\");\r\n            style.appendChild(document.createTextNode(css));\r\n            document.getElementsByTagName(\"head\")[0].appendChild(style);\r\n            const hmdBtn = document.createElement(\"button\");\r\n            hmdBtn.className = \"babylonVRicon\";\r\n            hmdBtn.title = `${sessionMode} - ${referenceSpaceType}`;\r\n            this._buttons.push(new WebXREnterExitUIButton(hmdBtn, sessionMode, referenceSpaceType));\r\n            this._buttons[this._buttons.length - 1].update = function (activeButton: WebXREnterExitUIButton) {\r\n                this.element.style.display = activeButton === null || activeButton === this ? \"\" : \"none\";\r\n                hmdBtn.className = \"babylonVRicon\" + (activeButton === this ? \" vrdisplaypresenting\" : \"\");\r\n            };\r\n            this._updateButtons(null);\r\n        }\r\n\r\n        const renderCanvas = _scene.getEngine().getInputElement();\r\n        if (renderCanvas && renderCanvas.parentNode) {\r\n            renderCanvas.parentNode.appendChild(this.overlay);\r\n            _scene.onDisposeObservable.addOnce(() => {\r\n                this.dispose();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the helper to be used with this UI component.\r\n     * The UI is bound to an experience helper. If not provided the UI can still be used but the events should be registered by the developer.\r\n     *\r\n     * @param helper the experience helper to attach\r\n     * @param renderTarget an optional render target (in case it is created outside of the helper scope)\r\n     * @returns a promise that resolves when the ui is ready\r\n     */\r\n    public async setHelperAsync(helper: WebXRExperienceHelper, renderTarget?: WebXRRenderTarget): Promise<void> {\r\n        this._helper = helper;\r\n        this._renderTarget = renderTarget;\r\n        const supportedPromises = this._buttons.map(async (btn) => {\r\n            return await helper.sessionManager.isSessionSupportedAsync(btn.sessionMode);\r\n        });\r\n        helper.onStateChangedObservable.add((state) => {\r\n            if (state == WebXRState.NOT_IN_XR) {\r\n                this._updateButtons(null);\r\n            }\r\n        });\r\n        const results = await Promise.all(supportedPromises);\r\n        for (let i = 0; i < results.length; i++) {\r\n            const supported = results[i];\r\n            if (supported) {\r\n                this.overlay.appendChild(this._buttons[i].element);\r\n                this._buttons[i].element.onclick = this._enterXRWithButtonIndexAsync.bind(this, i);\r\n            } else {\r\n                Tools.Warn(`Session mode \"${this._buttons[i].sessionMode}\" not supported in browser`);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates UI to allow the user to enter/exit XR mode\r\n     * @param scene the scene to add the ui to\r\n     * @param helper the xr experience helper to enter/exit xr with\r\n     * @param options options to configure the UI\r\n     * @returns the created ui\r\n     */\r\n    public static async CreateAsync(scene: Scene, helper: WebXRExperienceHelper, options: WebXREnterExitUIOptions): Promise<WebXREnterExitUI> {\r\n        const ui = new WebXREnterExitUI(scene, options);\r\n        await ui.setHelperAsync(helper, options.renderTarget || undefined);\r\n        return ui;\r\n    }\r\n\r\n    private async _enterXRWithButtonIndexAsync(idx: number = 0) {\r\n        if (this._helper.state == WebXRState.IN_XR) {\r\n            await this._helper.exitXRAsync();\r\n            this._updateButtons(null);\r\n        } else if (this._helper.state == WebXRState.NOT_IN_XR) {\r\n            try {\r\n                await this._helper.enterXRAsync(this._buttons[idx].sessionMode, this._buttons[idx].referenceSpaceType, this._renderTarget, {\r\n                    optionalFeatures: this.options.optionalFeatures,\r\n                    requiredFeatures: this.options.requiredFeatures,\r\n                });\r\n                this._updateButtons(this._buttons[idx]);\r\n            } catch (e) {\r\n                // make sure button is visible\r\n                this._updateButtons(null);\r\n                const element = this._buttons[idx].element;\r\n                const prevTitle = element.title;\r\n                element.title = \"Error entering XR session : \" + prevTitle;\r\n                element.classList.add(\"xr-error\");\r\n                if (this.options.onError) {\r\n                    this.options.onError(e);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the XR UI component\r\n     */\r\n    public dispose() {\r\n        const renderCanvas = this._scene.getEngine().getInputElement();\r\n        if (renderCanvas && renderCanvas.parentNode && renderCanvas.parentNode.contains(this.overlay)) {\r\n            renderCanvas.parentNode.removeChild(this.overlay);\r\n        }\r\n        this.activeButtonChangedObservable.clear();\r\n        (navigator as any).xr.removeEventListener(\"sessiongranted\", this._onSessionGranted);\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _onSessionGranted = (evt: { session: XRSession }) => {\r\n        // This section is for future reference.\r\n        // As per specs, evt.session.mode should have the supported session mode, but no browser supports it for now.\r\n\r\n        // // check if the session granted is the same as the one requested\r\n        // const grantedMode = (evt.session as any).mode;\r\n        // if (grantedMode) {\r\n        //     this._buttons.some((btn, idx) => {\r\n        //         if (btn.sessionMode === grantedMode) {\r\n        //             this._enterXRWithButtonIndex(idx);\r\n        //             return true;\r\n        //         }\r\n        //         return false;\r\n        //     });\r\n        // } else\r\n\r\n        if (this._helper) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            this._enterXRWithButtonIndexAsync(0);\r\n        }\r\n    };\r\n\r\n    private _updateButtons(activeButton: Nullable<WebXREnterExitUIButton>) {\r\n        this._activeButton = activeButton;\r\n        for (const b of this._buttons) {\r\n            b.update(this._activeButton);\r\n        }\r\n        this.activeButtonChangedObservable.notifyObservers(this._activeButton);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IWebXRFeature, WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebXRInput } from \"../webXRInput\";\r\nimport { type WebXRInputSource } from \"../webXRInputSource\";\r\nimport { WebXRControllerComponent, type IWebXRMotionControllerAxesValue } from \"../motionController/webXRControllerComponent\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { Vector3, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { Ray, RegisterRay } from \"../../Culling/ray.pure\";\r\nimport { type Material } from \"../../Materials/material.pure\";\r\nimport { DynamicTexture } from \"../../Materials/Textures/dynamicTexture.pure\";\r\nimport { CreateCylinder } from \"../../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { SineEase, EasingFunction } from \"../../Animations/easing\";\r\nimport { Animation } from \"../../Animations/animation.pure\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial.pure\";\r\nimport { CreateGround } from \"../../Meshes/Builders/groundBuilder.pure\";\r\nimport { CreateTorus } from \"../../Meshes/Builders/torusBuilder.pure\";\r\nimport { type PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { Curve3 } from \"../../Maths/math.path\";\r\nimport { CreateLines } from \"../../Meshes/Builders/linesBuilder.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Color3, Color4 } from \"../../Maths/math.color.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer\";\r\nimport { PointerEventTypes } from \"../../Events/pointerEvents\";\r\nimport { setAndStartTimer } from \"../../Misc/timer\";\r\nimport { type LinesMesh } from \"../../Meshes/linesMesh.pure\";\r\n\r\n/**\r\n * The options container for the teleportation module\r\n */\r\nexport interface IWebXRTeleportationOptions {\r\n    /**\r\n     * if provided, this scene will be used to render meshes.\r\n     */\r\n    customUtilityLayerScene?: Scene;\r\n    /**\r\n     * Values to configure the default target mesh\r\n     */\r\n    defaultTargetMeshOptions?: {\r\n        /**\r\n         * Fill color of the teleportation area\r\n         */\r\n        teleportationFillColor?: string;\r\n        /**\r\n         * Border color for the teleportation area\r\n         */\r\n        teleportationBorderColor?: string;\r\n        /**\r\n         * Disable the mesh's animation sequence\r\n         */\r\n        disableAnimation?: boolean;\r\n        /**\r\n         * Disable lighting on the material or the ring and arrow\r\n         */\r\n        disableLighting?: boolean;\r\n        /**\r\n         * Override the default material of the torus and arrow\r\n         */\r\n        torusArrowMaterial?: Material;\r\n        /**\r\n         * Override the default material of the Landing Zone\r\n         */\r\n        teleportationCircleMaterial?: Material;\r\n    };\r\n    /**\r\n     * A list of meshes to use as floor meshes.\r\n     * Meshes can be added and removed after initializing the feature using the\r\n     * addFloorMesh and removeFloorMesh functions\r\n     * If empty, rotation will still work\r\n     */\r\n    floorMeshes?: AbstractMesh[];\r\n    /**\r\n     *  use this rendering group id for the meshes (optional)\r\n     */\r\n    renderingGroupId?: number;\r\n    /**\r\n     * Should teleportation move only to snap points\r\n     */\r\n    snapPointsOnly?: boolean;\r\n    /**\r\n     * An array of points to which the teleportation will snap to.\r\n     * If the teleportation ray is in the proximity of one of those points, it will be corrected to this point.\r\n     */\r\n    snapPositions?: Vector3[];\r\n    /**\r\n     * How close should the teleportation ray be in order to snap to position.\r\n     * Default to 0.8 units (meters)\r\n     */\r\n    snapToPositionRadius?: number;\r\n    /**\r\n     * Provide your own teleportation mesh instead of babylon's wonderful doughnut.\r\n     * If you want to support rotation, make sure your mesh has a direction indicator.\r\n     *\r\n     * When left untouched, the default mesh will be initialized.\r\n     */\r\n    teleportationTargetMesh?: AbstractMesh;\r\n    /**\r\n     * If main component is used (no thumbstick), how long in milliseconds should the \"long press\" take before teleport. Defaults to 3 seconds\r\n     */\r\n    timeToTeleport?: number;\r\n\r\n    /**\r\n     * If the main component is used, how long in milliseconds should the \"long press\" take before teleport starts. Defaults to 0\r\n     */\r\n    timeToTeleportStart?: number;\r\n    /**\r\n     * Disable using the thumbstick and use the main component (usually trigger) on long press.\r\n     * This will be automatically true if the controller doesn't have a thumbstick or touchpad.\r\n     */\r\n    useMainComponentOnly?: boolean;\r\n    /**\r\n     * Should meshes created here be added to a utility layer or the main scene\r\n     */\r\n    useUtilityLayer?: boolean;\r\n    /**\r\n     * Babylon XR Input class for controller\r\n     */\r\n    xrInput: WebXRInput;\r\n\r\n    /**\r\n     * Meshes that the teleportation ray cannot go through\r\n     */\r\n    pickBlockerMeshes?: AbstractMesh[];\r\n\r\n    /**\r\n     * define an optional predicate to select which meshes should block the teleportation ray\r\n     */\r\n    blockerMeshesPredicate?: (mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * Should the teleportation ray be blocked by all of the scene's pickable meshes?\r\n     * Defaults to false\r\n     */\r\n    blockAllPickableMeshes?: boolean;\r\n\r\n    /**\r\n     * Color of the teleportation ray when it is blocked by a mesh in the pickBlockerMeshes array\r\n     * Defaults to red.\r\n     */\r\n    blockedRayColor?: Color4;\r\n\r\n    /**\r\n     * Should teleport work only on a specific hand?\r\n     */\r\n    forceHandedness?: XRHandedness;\r\n\r\n    /**\r\n     * If provided, this function will be used to generate the ray mesh instead of the lines mesh being used per default\r\n     */\r\n    generateRayPathMesh?: (points: Vector3[], pickingInfo: PickingInfo) => AbstractMesh;\r\n}\r\n\r\n/**\r\n * This is a teleportation feature to be used with WebXR-enabled motion controllers.\r\n * When enabled and attached, the feature will allow a user to move around and rotate in the scene using\r\n * the input of the attached controllers.\r\n */\r\nexport class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {\r\n    private _controllers: {\r\n        [controllerUniqueId: string]: {\r\n            xrController: WebXRInputSource;\r\n            teleportationComponent?: WebXRControllerComponent;\r\n            teleportationState: {\r\n                forward: boolean;\r\n                backwards: boolean;\r\n                currentRotation: number;\r\n                baseRotation: number;\r\n                rotating: boolean;\r\n                blocked: boolean;\r\n                initialHit: boolean;\r\n                mainComponentUsed: boolean;\r\n            };\r\n            onAxisChangedObserver?: Nullable<Observer<IWebXRMotionControllerAxesValue>>;\r\n            onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n        };\r\n    } = {};\r\n    private _currentTeleportationControllerId: string;\r\n    private _floorMeshes: AbstractMesh[];\r\n    private _quadraticBezierCurve: Nullable<AbstractMesh>;\r\n    private _selectionFeature: Nullable<IWebXRFeature>;\r\n    private _snapToPositions: Vector3[];\r\n    private _snappedToPoint: boolean = false;\r\n    private _teleportationRingMaterial?: StandardMaterial;\r\n    private _blockedRayColor: Color4;\r\n    private _cachedColor4White = new Color4(1, 1, 1, 1);\r\n    private _tmpRay = new Ray(new Vector3(), new Vector3());\r\n    private _tmpVector = new Vector3();\r\n    private _tmpQuaternion = new Quaternion();\r\n    private _worldScaleObserver?: Nullable<Observer<{ previousScaleFactor: number; newScaleFactor: number }>> = null;\r\n\r\n    /**\r\n     * Skip the next teleportation. This can be controlled by the user to prevent the user from teleportation\r\n     * to sections that are not yet \"unlocked\", but should still show the teleportation mesh.\r\n     */\r\n    public skipNextTeleportation = false;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.TELEPORTATION;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the webxr specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Is movement backwards enabled\r\n     */\r\n    public backwardsMovementEnabled = true;\r\n    /**\r\n     * Distance to travel when moving backwards\r\n     */\r\n    public backwardsTeleportationDistance: number = 0.7;\r\n    /**\r\n     * The distance from the user to the inspection point in the direction of the controller\r\n     * A higher number will allow the user to move further\r\n     * defaults to 5 (meters, in xr units)\r\n     */\r\n    public parabolicCheckRadius: number = 5;\r\n    /**\r\n     * Should the module support parabolic ray on top of direct ray\r\n     * If enabled, the user will be able to point \"at the sky\" and move according to predefined radius distance\r\n     * Very helpful when moving between floors / different heights\r\n     */\r\n    public parabolicRayEnabled: boolean = true;\r\n\r\n    /**\r\n     * The second type of ray - straight line.\r\n     * Should it be enabled or should the parabolic line be the only one.\r\n     */\r\n    public straightRayEnabled: boolean = true;\r\n    /**\r\n     * How much rotation should be applied when rotating right and left\r\n     */\r\n    public rotationAngle: number = Math.PI / 8;\r\n\r\n    /**\r\n     * This observable will notify when the target mesh position was updated.\r\n     * The picking info it provides contains the point to which the target mesh will move ()\r\n     */\r\n    public onTargetMeshPositionUpdatedObservable: Observable<PickingInfo> = new Observable();\r\n\r\n    /**\r\n     * Is teleportation enabled. Can be used to allow rotation only.\r\n     */\r\n    public teleportationEnabled: boolean = true;\r\n\r\n    private _rotationEnabled: boolean = true;\r\n\r\n    /**\r\n     * Observable raised before camera rotation\r\n     */\r\n    public onBeforeCameraTeleportRotation = new Observable<number>();\r\n\r\n    /**\r\n     *  Observable raised after camera rotation\r\n     */\r\n    public onAfterCameraTeleportRotation = new Observable<Quaternion>();\r\n\r\n    /**\r\n     * Observable raised before camera teleportation\r\n     */\r\n    public onBeforeCameraTeleport: Observable<Vector3>;\r\n\r\n    /**\r\n     *  Observable raised after camera teleportation\r\n     */\r\n    public onAfterCameraTeleport: Observable<Vector3>;\r\n\r\n    /**\r\n     * Is rotation enabled when moving forward?\r\n     * Disabling this feature will prevent the user from deciding the direction when teleporting\r\n     */\r\n    public get rotationEnabled(): boolean {\r\n        return this._rotationEnabled;\r\n    }\r\n\r\n    /**\r\n     * Sets whether rotation is enabled or not\r\n     * @param enabled is rotation enabled when teleportation is shown\r\n     */\r\n    public set rotationEnabled(enabled: boolean) {\r\n        this._rotationEnabled = enabled;\r\n\r\n        if (this._options.teleportationTargetMesh) {\r\n            const children = this._options.teleportationTargetMesh.getChildMeshes(false, (node) => node.name === \"rotationCone\");\r\n            if (children[0]) {\r\n                children[0].setEnabled(enabled);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Exposes the currently set teleportation target mesh.\r\n     */\r\n    public get teleportationTargetMesh(): Nullable<AbstractMesh> {\r\n        return this._options.teleportationTargetMesh || null;\r\n    }\r\n\r\n    /**\r\n     * constructs a new teleportation system\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param _options configuration object for this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private _options: IWebXRTeleportationOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        // create default mesh if not provided\r\n        if (!this._options.teleportationTargetMesh) {\r\n            this._createDefaultTargetMesh();\r\n        }\r\n\r\n        this._floorMeshes = this._options.floorMeshes || [];\r\n        this._snapToPositions = this._options.snapPositions || [];\r\n        this._blockedRayColor = this._options.blockedRayColor || new Color4(1, 0, 0, 0.75);\r\n\r\n        this._setTargetMeshVisibility(false);\r\n\r\n        // set the observables\r\n        this.onBeforeCameraTeleport = _options.xrInput.xrCamera.onBeforeCameraTeleport;\r\n        this.onAfterCameraTeleport = _options.xrInput.xrCamera.onAfterCameraTeleport;\r\n\r\n        this.parabolicCheckRadius *= this._xrSessionManager.worldScalingFactor;\r\n        this._worldScaleObserver = _xrSessionManager.onWorldScaleFactorChangedObservable.add((values) => {\r\n            this.parabolicCheckRadius = (this.parabolicCheckRadius / values.previousScaleFactor) * values.newScaleFactor;\r\n            this._options.teleportationTargetMesh?.scaling.scaleInPlace(values.newScaleFactor / values.previousScaleFactor);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Get the snapPointsOnly flag\r\n     */\r\n    public get snapPointsOnly(): boolean {\r\n        return !!this._options.snapPointsOnly;\r\n    }\r\n\r\n    /**\r\n     * Sets the snapPointsOnly flag\r\n     * @param snapToPoints should teleportation be exclusively to snap points\r\n     */\r\n    public set snapPointsOnly(snapToPoints: boolean) {\r\n        this._options.snapPointsOnly = snapToPoints;\r\n    }\r\n\r\n    /**\r\n     * Add a new mesh to the floor meshes array\r\n     * @param mesh the mesh to use as floor mesh\r\n     */\r\n    public addFloorMesh(mesh: AbstractMesh) {\r\n        this._floorMeshes.push(mesh);\r\n    }\r\n\r\n    /**\r\n     * Add a mesh to the list of meshes blocking the teleportation ray\r\n     * @param mesh The mesh to add to the teleportation-blocking meshes\r\n     */\r\n    public addBlockerMesh(mesh: AbstractMesh) {\r\n        this._options.pickBlockerMeshes = this._options.pickBlockerMeshes || [];\r\n        this._options.pickBlockerMeshes.push(mesh);\r\n    }\r\n\r\n    /**\r\n     * Add a new snap-to point to fix teleportation to this position\r\n     * @param newSnapPoint The new Snap-To point\r\n     */\r\n    public addSnapPoint(newSnapPoint: Vector3) {\r\n        this._snapToPositions.push(newSnapPoint);\r\n    }\r\n\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        // Safety reset\r\n        this._currentTeleportationControllerId = \"\";\r\n\r\n        for (const controller of this._options.xrInput.controllers) {\r\n            this._attachController(controller);\r\n        }\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\r\n            // REMOVE the controller\r\n            this._detachController(controller.uniqueId);\r\n        });\r\n\r\n        return true;\r\n    }\r\n\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        const keys = Object.keys(this._controllers);\r\n\r\n        for (const controllerId of keys) {\r\n            this._detachController(controllerId);\r\n        }\r\n\r\n        this._setTargetMeshVisibility(false);\r\n        this._currentTeleportationControllerId = \"\";\r\n        this._controllers = {};\r\n\r\n        return true;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this._options.teleportationTargetMesh && this._options.teleportationTargetMesh.dispose(false, true);\r\n        if (this._worldScaleObserver) {\r\n            this._xrSessionManager.onWorldScaleFactorChangedObservable.remove(this._worldScaleObserver);\r\n        }\r\n        this.onTargetMeshPositionUpdatedObservable.clear();\r\n        this.onBeforeCameraTeleportRotation.clear();\r\n        this.onAfterCameraTeleportRotation.clear();\r\n        this.onBeforeCameraTeleport.clear();\r\n        this.onAfterCameraTeleport.clear();\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the floor meshes array\r\n     * @param mesh the mesh to remove\r\n     */\r\n    public removeFloorMesh(mesh: AbstractMesh) {\r\n        const index = this._floorMeshes.indexOf(mesh);\r\n        if (index !== -1) {\r\n            this._floorMeshes.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the blocker meshes array\r\n     * @param mesh the mesh to remove\r\n     */\r\n    public removeBlockerMesh(mesh: AbstractMesh) {\r\n        this._options.pickBlockerMeshes = this._options.pickBlockerMeshes || [];\r\n        const index = this._options.pickBlockerMeshes.indexOf(mesh);\r\n        if (index !== -1) {\r\n            this._options.pickBlockerMeshes.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the floor meshes array using its name\r\n     * @param name the mesh name to remove\r\n     */\r\n    public removeFloorMeshByName(name: string) {\r\n        const mesh = this._xrSessionManager.scene.getMeshByName(name);\r\n        if (mesh) {\r\n            this.removeFloorMesh(mesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This function will iterate through the array, searching for this point or equal to it. It will then remove it from the snap-to array\r\n     * @param snapPointToRemove the point (or a clone of it) to be removed from the array\r\n     * @returns was the point found and removed or not\r\n     */\r\n    public removeSnapPoint(snapPointToRemove: Vector3): boolean {\r\n        // check if the object is in the array\r\n        let index = this._snapToPositions.indexOf(snapPointToRemove);\r\n        // if not found as an object, compare to the points\r\n        if (index === -1) {\r\n            for (let i = 0; i < this._snapToPositions.length; ++i) {\r\n                // equals? index is i, break the loop\r\n                if (this._snapToPositions[i].equals(snapPointToRemove)) {\r\n                    index = i;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        // index is not -1? remove the object\r\n        if (index !== -1) {\r\n            this._snapToPositions.splice(index, 1);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * This function sets a selection feature that will be disabled when\r\n     * the forward ray is shown and will be reattached when hidden.\r\n     * This is used to remove the selection rays when moving.\r\n     * @param selectionFeature the feature to disable when forward movement is enabled\r\n     */\r\n    public setSelectionFeature(selectionFeature: Nullable<IWebXRFeature>) {\r\n        this._selectionFeature = selectionFeature;\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame) {\r\n        const frame = this._xrSessionManager.currentFrame;\r\n        const scene = this._xrSessionManager.scene;\r\n        if (!this.attached || !frame) {\r\n            return;\r\n        }\r\n\r\n        // render target if needed\r\n        const targetMesh = this._options.teleportationTargetMesh;\r\n        if (this._currentTeleportationControllerId) {\r\n            if (!targetMesh) {\r\n                return;\r\n            }\r\n            targetMesh.rotationQuaternion = targetMesh.rotationQuaternion || new Quaternion();\r\n            const controllerData = this._controllers[this._currentTeleportationControllerId];\r\n            if (controllerData && controllerData.teleportationState.forward) {\r\n                // set the rotation\r\n                Quaternion.RotationYawPitchRollToRef(\r\n                    controllerData.teleportationState.currentRotation + controllerData.teleportationState.baseRotation,\r\n                    0,\r\n                    0,\r\n                    targetMesh.rotationQuaternion\r\n                );\r\n                // set the ray and position\r\n\r\n                let hitPossible = false;\r\n                const controlSelectionFeature = controllerData.xrController.inputSource.targetRayMode !== \"transient-pointer\";\r\n                controllerData.xrController.getWorldPointerRayToRef(this._tmpRay);\r\n                if (this.straightRayEnabled) {\r\n                    // first check if direct ray possible\r\n                    // pick grounds that are LOWER only. upper will use parabolic path\r\n                    const pick = scene.pickWithRay(this._tmpRay, (o) => {\r\n                        if (this._options.blockerMeshesPredicate && this._options.blockerMeshesPredicate(o)) {\r\n                            return true;\r\n                        }\r\n                        if (this._options.blockAllPickableMeshes && o.isPickable) {\r\n                            return true;\r\n                        }\r\n                        // check for mesh-blockers\r\n                        if (this._options.pickBlockerMeshes && this._options.pickBlockerMeshes.indexOf(o) !== -1) {\r\n                            return true;\r\n                        }\r\n                        const index = this._floorMeshes.indexOf(o);\r\n                        if (index === -1) {\r\n                            return false;\r\n                        }\r\n                        return this._floorMeshes[index].absolutePosition.y < this._options.xrInput.xrCamera.globalPosition.y;\r\n                    });\r\n                    const floorMeshPicked = pick && pick.pickedMesh && this._floorMeshes.indexOf(pick.pickedMesh) !== -1;\r\n                    if (pick && pick.pickedMesh && !floorMeshPicked) {\r\n                        if (controllerData.teleportationState.mainComponentUsed && !controllerData.teleportationState.initialHit) {\r\n                            controllerData.teleportationState.forward = false;\r\n                            return;\r\n                        }\r\n                        controllerData.teleportationState.blocked = true;\r\n                        this._setTargetMeshVisibility(false, false, controlSelectionFeature);\r\n                        this._showParabolicPath(pick);\r\n                        return;\r\n                    } else if (pick && pick.pickedPoint) {\r\n                        controllerData.teleportationState.initialHit = true;\r\n                        controllerData.teleportationState.blocked = false;\r\n                        hitPossible = true;\r\n                        this._setTargetMeshPosition(pick);\r\n                        this._setTargetMeshVisibility(true, false, controlSelectionFeature);\r\n                        this._showParabolicPath(pick);\r\n                    }\r\n                }\r\n                // straight ray is still the main ray, but disabling the straight line will force parabolic line.\r\n                if (this.parabolicRayEnabled && !hitPossible && this._buildParabolicRay(this._tmpRay, this._tmpVector)) {\r\n                    const pick = scene.pickWithRay(this._tmpRay, (o) => {\r\n                        if (this._options.blockerMeshesPredicate && this._options.blockerMeshesPredicate(o)) {\r\n                            return true;\r\n                        }\r\n                        if (this._options.blockAllPickableMeshes && o.isPickable) {\r\n                            return true;\r\n                        }\r\n                        // check for mesh-blockers\r\n                        if (this._options.pickBlockerMeshes && this._options.pickBlockerMeshes.indexOf(o) !== -1) {\r\n                            return true;\r\n                        }\r\n                        return this._floorMeshes.indexOf(o) !== -1;\r\n                    });\r\n                    const floorMeshPicked = pick && pick.pickedMesh && this._floorMeshes.indexOf(pick.pickedMesh) !== -1;\r\n                    if (pick && pick.pickedMesh && !floorMeshPicked) {\r\n                        if (controllerData.teleportationState.mainComponentUsed && !controllerData.teleportationState.initialHit) {\r\n                            controllerData.teleportationState.forward = false;\r\n                            return;\r\n                        }\r\n                        controllerData.teleportationState.blocked = true;\r\n                        this._setTargetMeshVisibility(false, false, controlSelectionFeature);\r\n                        this._showParabolicPath(pick);\r\n                        return;\r\n                    } else if (pick && pick.pickedPoint) {\r\n                        controllerData.teleportationState.initialHit = true;\r\n                        controllerData.teleportationState.blocked = false;\r\n                        hitPossible = true;\r\n                        this._setTargetMeshPosition(pick);\r\n                        this._setTargetMeshVisibility(true, false, controlSelectionFeature);\r\n                        this._showParabolicPath(pick);\r\n                    }\r\n                }\r\n\r\n                // if needed, set visible:\r\n                this._setTargetMeshVisibility(hitPossible, false, controlSelectionFeature);\r\n            } else {\r\n                this._setTargetMeshVisibility(false, false, true);\r\n            }\r\n        } else {\r\n            this._disposeBezierCurve();\r\n            this._setTargetMeshVisibility(false, false, true);\r\n        }\r\n    }\r\n\r\n    private _attachController = (xrController: WebXRInputSource) => {\r\n        if (this._controllers[xrController.uniqueId] || (this._options.forceHandedness && xrController.inputSource.handedness !== this._options.forceHandedness)) {\r\n            // already attached\r\n            return;\r\n        }\r\n        this._controllers[xrController.uniqueId] = {\r\n            xrController,\r\n            teleportationState: {\r\n                forward: false,\r\n                backwards: false,\r\n                rotating: false,\r\n                currentRotation: 0,\r\n                baseRotation: 0,\r\n                blocked: false,\r\n                initialHit: false,\r\n                mainComponentUsed: false,\r\n            },\r\n        };\r\n        const controllerData = this._controllers[xrController.uniqueId];\r\n        // motion controller only available to gamepad-enabled input sources.\r\n        if (controllerData.xrController.inputSource.targetRayMode === \"tracked-pointer\" && controllerData.xrController.inputSource.gamepad) {\r\n            // motion controller support\r\n            const initMotionController = () => {\r\n                if (xrController.motionController) {\r\n                    const movementController =\r\n                        xrController.motionController.getComponentOfType(WebXRControllerComponent.THUMBSTICK_TYPE) ||\r\n                        xrController.motionController.getComponentOfType(WebXRControllerComponent.TOUCHPAD_TYPE);\r\n                    if (!movementController || this._options.useMainComponentOnly) {\r\n                        // use trigger to move on long press\r\n                        const mainComponent = xrController.motionController.getMainComponent();\r\n                        if (!mainComponent) {\r\n                            return;\r\n                        }\r\n                        controllerData.teleportationState.mainComponentUsed = true;\r\n                        controllerData.teleportationComponent = mainComponent;\r\n                        controllerData.onButtonChangedObserver = mainComponent.onButtonStateChangedObservable.add(() => {\r\n                            if (!this.teleportationEnabled) {\r\n                                return;\r\n                            }\r\n\r\n                            const teleportLocal = () => {\r\n                                // simulate \"forward\" thumbstick push\r\n                                controllerData.teleportationState.forward = true;\r\n                                controllerData.teleportationState.initialHit = false;\r\n                                this._currentTeleportationControllerId = controllerData.xrController.uniqueId;\r\n                                controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;\r\n                                controllerData.teleportationState.currentRotation = 0;\r\n                                const timeToSelect = this._options.timeToTeleport || 3000;\r\n                                setAndStartTimer({\r\n                                    timeout: timeToSelect,\r\n                                    contextObservable: this._xrSessionManager.onXRFrameObservable,\r\n                                    breakCondition: () => !mainComponent.pressed,\r\n                                    onEnded: () => {\r\n                                        if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {\r\n                                            this._teleportForward(xrController.uniqueId);\r\n                                        }\r\n                                    },\r\n                                });\r\n                            };\r\n                            // did \"pressed\" changed?\r\n                            if (mainComponent.changes.pressed) {\r\n                                if (mainComponent.changes.pressed.current) {\r\n                                    // delay if the start time is defined\r\n                                    if (this._options.timeToTeleportStart) {\r\n                                        setAndStartTimer({\r\n                                            timeout: this._options.timeToTeleportStart,\r\n                                            contextObservable: this._xrSessionManager.onXRFrameObservable,\r\n                                            onEnded: () => {\r\n                                                // check if still pressed\r\n                                                if (mainComponent.pressed) {\r\n                                                    teleportLocal();\r\n                                                }\r\n                                            },\r\n                                        });\r\n                                    } else {\r\n                                        teleportLocal();\r\n                                    }\r\n                                } else {\r\n                                    controllerData.teleportationState.forward = false;\r\n                                    this._currentTeleportationControllerId = \"\";\r\n                                }\r\n                            }\r\n                        });\r\n                    } else {\r\n                        controllerData.teleportationComponent = movementController;\r\n                        // use thumbstick (or touchpad if thumbstick not available)\r\n                        controllerData.onAxisChangedObserver = movementController.onAxisValueChangedObservable.add((axesData) => {\r\n                            if (axesData.y <= 0.7 && controllerData.teleportationState.backwards) {\r\n                                controllerData.teleportationState.backwards = false;\r\n                            }\r\n                            if (axesData.y > 0.7 && !controllerData.teleportationState.forward && this.backwardsMovementEnabled && !this.snapPointsOnly) {\r\n                                // teleport backwards\r\n\r\n                                // General gist: Go Back N units, cast a ray towards the floor. If collided, move.\r\n                                if (!controllerData.teleportationState.backwards) {\r\n                                    controllerData.teleportationState.backwards = true;\r\n                                    // teleport backwards ONCE\r\n                                    this._tmpQuaternion.copyFrom(this._options.xrInput.xrCamera.rotationQuaternion);\r\n                                    this._tmpQuaternion.toEulerAnglesToRef(this._tmpVector);\r\n                                    // get only the y rotation\r\n                                    this._tmpVector.x = 0;\r\n                                    this._tmpVector.z = 0;\r\n                                    // get the quaternion\r\n                                    Quaternion.FromEulerVectorToRef(this._tmpVector, this._tmpQuaternion);\r\n                                    this._tmpVector.set(0, 0, this.backwardsTeleportationDistance * (this._xrSessionManager.scene.useRightHandedSystem ? 1.0 : -1.0));\r\n                                    this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector);\r\n                                    this._tmpVector.addInPlace(this._options.xrInput.xrCamera.position);\r\n                                    this._tmpRay.origin.copyFrom(this._tmpVector);\r\n                                    // This will prevent the user from \"falling\" to a lower platform!\r\n                                    // TODO - should this be a flag? 'allow falling to lower platforms'?\r\n                                    this._tmpRay.length = this._options.xrInput.xrCamera.realWorldHeight + 0.1;\r\n                                    // Right handed system had here \"1\" instead of -1. This is unneeded.\r\n                                    this._tmpRay.direction.set(0, -1, 0);\r\n                                    const pick = this._xrSessionManager.scene.pickWithRay(this._tmpRay, (o) => {\r\n                                        return this._floorMeshes.indexOf(o) !== -1;\r\n                                    });\r\n\r\n                                    // pick must exist, but stay safe\r\n                                    if (pick && pick.pickedPoint) {\r\n                                        // Teleport the users feet to where they targeted. Ignore the Y axis.\r\n                                        // If the \"falling to lower platforms\" feature is implemented the Y axis should be set here as well\r\n                                        this._options.xrInput.xrCamera.position.x = pick.pickedPoint.x;\r\n                                        this._options.xrInput.xrCamera.position.z = pick.pickedPoint.z;\r\n                                    }\r\n                                }\r\n                            }\r\n                            if (axesData.y < -0.7 && !this._currentTeleportationControllerId && !controllerData.teleportationState.rotating && this.teleportationEnabled) {\r\n                                controllerData.teleportationState.forward = true;\r\n                                this._currentTeleportationControllerId = controllerData.xrController.uniqueId;\r\n                                controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;\r\n                            }\r\n                            if (axesData.x) {\r\n                                if (!controllerData.teleportationState.forward) {\r\n                                    if (!controllerData.teleportationState.rotating && Math.abs(axesData.x) > 0.7) {\r\n                                        // rotate in the right direction positive is right\r\n                                        controllerData.teleportationState.rotating = true;\r\n                                        const rotation = this.rotationAngle * (axesData.x > 0 ? 1 : -1) * (this._xrSessionManager.scene.useRightHandedSystem ? -1 : 1);\r\n                                        this.onBeforeCameraTeleportRotation.notifyObservers(rotation);\r\n                                        Quaternion.FromEulerAngles(0, rotation, 0).multiplyToRef(\r\n                                            this._options.xrInput.xrCamera.rotationQuaternion,\r\n                                            this._options.xrInput.xrCamera.rotationQuaternion\r\n                                        );\r\n                                        this.onAfterCameraTeleportRotation.notifyObservers(this._options.xrInput.xrCamera.rotationQuaternion);\r\n                                    }\r\n                                } else {\r\n                                    if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {\r\n                                        // set the rotation of the forward movement\r\n                                        if (this.rotationEnabled) {\r\n                                            setTimeout(() => {\r\n                                                controllerData.teleportationState.currentRotation = Math.atan2(\r\n                                                    axesData.x,\r\n                                                    axesData.y * (this._xrSessionManager.scene.useRightHandedSystem ? 1 : -1)\r\n                                                );\r\n                                            });\r\n                                        } else {\r\n                                            controllerData.teleportationState.currentRotation = 0;\r\n                                        }\r\n                                    }\r\n                                }\r\n                            } else {\r\n                                controllerData.teleportationState.rotating = false;\r\n                            }\r\n\r\n                            if (axesData.x === 0 && axesData.y === 0) {\r\n                                if (controllerData.teleportationState.blocked) {\r\n                                    controllerData.teleportationState.blocked = false;\r\n                                    this._setTargetMeshVisibility(false);\r\n                                }\r\n                                if (controllerData.teleportationState.forward) {\r\n                                    this._teleportForward(xrController.uniqueId);\r\n                                }\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            };\r\n            if (xrController.motionController) {\r\n                initMotionController();\r\n            } else {\r\n                xrController.onMotionControllerInitObservable.addOnce(() => {\r\n                    initMotionController();\r\n                });\r\n            }\r\n        } else {\r\n            controllerData.teleportationState.mainComponentUsed = true;\r\n            let breakObserver = false;\r\n            const teleportLocal = () => {\r\n                this._currentTeleportationControllerId = controllerData.xrController.uniqueId;\r\n                controllerData.teleportationState.forward = true;\r\n                controllerData.teleportationState.initialHit = false;\r\n                controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;\r\n                controllerData.teleportationState.currentRotation = 0;\r\n                const timeToSelect = this._options.timeToTeleport || 3000;\r\n                setAndStartTimer({\r\n                    timeout: timeToSelect,\r\n                    contextObservable: this._xrSessionManager.onXRFrameObservable,\r\n                    onEnded: () => {\r\n                        if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {\r\n                            this._teleportForward(xrController.uniqueId);\r\n                        }\r\n                    },\r\n                });\r\n            };\r\n            this._xrSessionManager.scene.onPointerObservable.add((pointerInfo) => {\r\n                if (pointerInfo.type === PointerEventTypes.POINTERDOWN) {\r\n                    breakObserver = false;\r\n                    // check if start time is defined\r\n                    if (this._options.timeToTeleportStart) {\r\n                        setAndStartTimer({\r\n                            timeout: this._options.timeToTeleportStart,\r\n                            contextObservable: this._xrSessionManager.onXRFrameObservable,\r\n                            onEnded: () => {\r\n                                // make sure pointer up was not triggered during this time\r\n                                if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {\r\n                                    teleportLocal();\r\n                                }\r\n                            },\r\n                            breakCondition: () => {\r\n                                if (breakObserver) {\r\n                                    breakObserver = false;\r\n                                    return true;\r\n                                }\r\n                                return false;\r\n                            },\r\n                        });\r\n                    } else {\r\n                        teleportLocal();\r\n                    }\r\n                } else if (pointerInfo.type === PointerEventTypes.POINTERUP) {\r\n                    breakObserver = true;\r\n                    controllerData.teleportationState.forward = false;\r\n                    this._currentTeleportationControllerId = \"\";\r\n                }\r\n            });\r\n        }\r\n    };\r\n\r\n    private _createDefaultTargetMesh() {\r\n        // set defaults\r\n        this._options.defaultTargetMeshOptions = this._options.defaultTargetMeshOptions || {};\r\n        const sceneToRenderTo = this._options.useUtilityLayer\r\n            ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene\r\n            : this._xrSessionManager.scene;\r\n        const teleportationTarget = CreateGround(\"teleportationTarget\", { width: 2, height: 2, subdivisions: 2 }, sceneToRenderTo);\r\n        teleportationTarget.isPickable = false;\r\n\r\n        if (this._options.defaultTargetMeshOptions.teleportationCircleMaterial) {\r\n            teleportationTarget.material = this._options.defaultTargetMeshOptions.teleportationCircleMaterial;\r\n        } else {\r\n            const length = 512;\r\n            const dynamicTexture = new DynamicTexture(\"teleportationPlaneDynamicTexture\", length, sceneToRenderTo, true);\r\n            dynamicTexture.hasAlpha = true;\r\n            const context = dynamicTexture.getContext();\r\n            const centerX = length / 2;\r\n            const centerY = length / 2;\r\n            const radius = 200;\r\n            context.beginPath();\r\n            context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);\r\n            context.fillStyle = this._options.defaultTargetMeshOptions.teleportationFillColor || \"#444444\";\r\n            context.fill();\r\n            context.lineWidth = 10;\r\n            context.strokeStyle = this._options.defaultTargetMeshOptions.teleportationBorderColor || \"#FFFFFF\";\r\n            context.stroke();\r\n            context.closePath();\r\n            dynamicTexture.update();\r\n            const teleportationCircleMaterial = new StandardMaterial(\"teleportationPlaneMaterial\", sceneToRenderTo);\r\n            teleportationCircleMaterial.diffuseTexture = dynamicTexture;\r\n            teleportationTarget.material = teleportationCircleMaterial;\r\n        }\r\n\r\n        const torus = CreateTorus(\r\n            \"torusTeleportation\",\r\n            {\r\n                diameter: 0.75,\r\n                thickness: 0.1,\r\n                tessellation: 20,\r\n            },\r\n            sceneToRenderTo\r\n        );\r\n        torus.isPickable = false;\r\n        torus.parent = teleportationTarget;\r\n        if (!this._options.defaultTargetMeshOptions.disableAnimation) {\r\n            const animationInnerCircle = new Animation(\"animationInnerCircle\", \"position.y\", 30, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE);\r\n            const keys: { frame: number; value: number }[] = [];\r\n            keys.push({\r\n                frame: 0,\r\n                value: 0,\r\n            });\r\n            keys.push({\r\n                frame: 30,\r\n                value: 0.4,\r\n            });\r\n            keys.push({\r\n                frame: 60,\r\n                value: 0,\r\n            });\r\n            animationInnerCircle.setKeys(keys);\r\n            const easingFunction = new SineEase();\r\n            easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);\r\n            animationInnerCircle.setEasingFunction(easingFunction);\r\n            torus.animations = [];\r\n            torus.animations.push(animationInnerCircle);\r\n            sceneToRenderTo.beginAnimation(torus, 0, 60, true);\r\n        }\r\n\r\n        const cone = CreateCylinder(\"rotationCone\", { diameterTop: 0, tessellation: 4 }, sceneToRenderTo);\r\n        cone.isPickable = false;\r\n        cone.scaling.set(0.5, 0.12, 0.2);\r\n\r\n        cone.rotate(Axis.X, Math.PI / 2);\r\n\r\n        cone.position.z = 0.6;\r\n        cone.parent = torus;\r\n\r\n        if (this._options.defaultTargetMeshOptions.torusArrowMaterial) {\r\n            torus.material = this._options.defaultTargetMeshOptions.torusArrowMaterial;\r\n            cone.material = this._options.defaultTargetMeshOptions.torusArrowMaterial;\r\n        } else {\r\n            const torusConeMaterial = new StandardMaterial(\"torusConsMat\", sceneToRenderTo);\r\n            torusConeMaterial.disableLighting = !!this._options.defaultTargetMeshOptions.disableLighting;\r\n            if (torusConeMaterial.disableLighting) {\r\n                torusConeMaterial.emissiveColor = new Color3(0.3, 0.3, 1.0);\r\n            } else {\r\n                torusConeMaterial.diffuseColor = new Color3(0.3, 0.3, 1.0);\r\n            }\r\n            torusConeMaterial.alpha = 0.9;\r\n            torus.material = torusConeMaterial;\r\n            cone.material = torusConeMaterial;\r\n            this._teleportationRingMaterial = torusConeMaterial;\r\n        }\r\n\r\n        if (this._options.renderingGroupId !== undefined) {\r\n            teleportationTarget.renderingGroupId = this._options.renderingGroupId;\r\n            torus.renderingGroupId = this._options.renderingGroupId;\r\n            cone.renderingGroupId = this._options.renderingGroupId;\r\n        }\r\n\r\n        this._options.teleportationTargetMesh = teleportationTarget;\r\n        this._options.teleportationTargetMesh.scaling.setAll(this._xrSessionManager.worldScalingFactor);\r\n        // hide the teleportation target mesh right after creating it.\r\n        this._setTargetMeshVisibility(false);\r\n    }\r\n\r\n    private _detachController(xrControllerUniqueId: string) {\r\n        const controllerData = this._controllers[xrControllerUniqueId];\r\n        if (!controllerData) {\r\n            return;\r\n        }\r\n        if (controllerData.teleportationComponent) {\r\n            if (controllerData.onAxisChangedObserver) {\r\n                controllerData.teleportationComponent.onAxisValueChangedObservable.remove(controllerData.onAxisChangedObserver);\r\n            }\r\n            if (controllerData.onButtonChangedObserver) {\r\n                controllerData.teleportationComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\r\n            }\r\n        }\r\n        // remove from the map\r\n        delete this._controllers[xrControllerUniqueId];\r\n    }\r\n\r\n    private _findClosestSnapPointWithRadius(realPosition: Vector3, radius: number = this._options.snapToPositionRadius || 0.8) {\r\n        let closestPoint: Nullable<Vector3> = null;\r\n        let closestDistance = Number.MAX_VALUE;\r\n        if (this._snapToPositions.length) {\r\n            const radiusSquared = radius * radius;\r\n            for (const position of this._snapToPositions) {\r\n                const dist = Vector3.DistanceSquared(position, realPosition);\r\n                if (dist <= radiusSquared && dist < closestDistance) {\r\n                    closestDistance = dist;\r\n                    closestPoint = position;\r\n                }\r\n            }\r\n        }\r\n        return closestPoint;\r\n    }\r\n\r\n    private _setTargetMeshPosition(pickInfo: PickingInfo) {\r\n        const newPosition = pickInfo.pickedPoint;\r\n        if (!this._options.teleportationTargetMesh || !newPosition) {\r\n            return;\r\n        }\r\n        const snapPosition = this._findClosestSnapPointWithRadius(newPosition);\r\n        this._snappedToPoint = !!snapPosition;\r\n        if (this.snapPointsOnly && !this._snappedToPoint && this._teleportationRingMaterial) {\r\n            this._teleportationRingMaterial.diffuseColor.set(1.0, 0.3, 0.3);\r\n        } else if (this.snapPointsOnly && this._snappedToPoint && this._teleportationRingMaterial) {\r\n            this._teleportationRingMaterial.diffuseColor.set(0.3, 0.3, 1.0);\r\n        }\r\n        this._options.teleportationTargetMesh.position.copyFrom(snapPosition || newPosition);\r\n        this._options.teleportationTargetMesh.position.y += 0.01;\r\n        this.onTargetMeshPositionUpdatedObservable.notifyObservers(pickInfo);\r\n    }\r\n\r\n    private _setTargetMeshVisibility(visible: boolean, force?: boolean, controlSelectionFeature?: boolean) {\r\n        if (!this._options.teleportationTargetMesh) {\r\n            return;\r\n        }\r\n        if (this._options.teleportationTargetMesh.isVisible === visible && !force) {\r\n            return;\r\n        }\r\n        this._options.teleportationTargetMesh.isVisible = visible;\r\n        const children = this._options.teleportationTargetMesh.getChildren(undefined, false);\r\n        for (const m of children) {\r\n            (<any>m).isVisible = visible;\r\n        }\r\n\r\n        if (!visible) {\r\n            if (this._quadraticBezierCurve) {\r\n                this._quadraticBezierCurve.dispose();\r\n                this._quadraticBezierCurve = null;\r\n            }\r\n            if (this._selectionFeature && controlSelectionFeature) {\r\n                this._selectionFeature.attach();\r\n            }\r\n        } else {\r\n            if (this._selectionFeature && controlSelectionFeature) {\r\n                this._selectionFeature.detach();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Computes the parabolic ray origin and direction for teleportation.\r\n     * The effective radius scales with the horizontal component of the controller direction,\r\n     * so pointing more vertically results in shorter landing distances.\r\n     * Note: the actual landing distance also depends on controller height above the floor;\r\n     * `parabolicCheckRadius` controls the forward offset, not a strict max ground distance.\r\n     * Modifies the ray in place — the new origin serves as both the raycast start\r\n     * and the Bezier control point for the visual arc.\r\n     * @param ray - The controller ray (origin at controller, direction is forward). Modified in place.\r\n     * @param tmpVector - Pre-allocated temporary vector for computation. Modified in place.\r\n     * @returns true if the parabolic ray was computed, false if direction is too vertical\r\n     */\r\n    private _buildParabolicRay(ray: Ray, tmpVector: Vector3): boolean {\r\n        const dir = ray.direction;\r\n        const horizontalLengthSq = dir.x * dir.x + dir.z * dir.z;\r\n        const horizontalLength = Math.sqrt(horizontalLengthSq);\r\n\r\n        // Skip if pointing almost straight up or down — no meaningful horizontal reach\r\n        if (horizontalLength < 0.01) {\r\n            return false;\r\n        }\r\n\r\n        // Effective radius scales with horizontal component of direction.\r\n        // Pointing horizontally (horizontalLength ~ 1) gives full reach.\r\n        // Pointing up (horizontalLength ~ 0) gives minimal reach.\r\n        const effectiveRadius = this.parabolicCheckRadius * horizontalLength;\r\n\r\n        // Place \"air point\" at effectiveRadius forward in controller direction, then flatten Y.\r\n        // This represents the far ground-level target the ray angles toward.\r\n        dir.scaleToRef(effectiveRadius, tmpVector);\r\n        tmpVector.addInPlace(ray.origin);\r\n        tmpVector.y = ray.origin.y;\r\n\r\n        // Move ray origin forward by half the effective radius along controller direction.\r\n        // This elevated midpoint serves as both the raycast start and the Bezier control point.\r\n        dir.scaleAndAddToRef(effectiveRadius * 0.5, ray.origin);\r\n\r\n        // Direction from the new origin toward the air point (angled downward)\r\n        tmpVector.subtractToRef(ray.origin, ray.direction);\r\n        ray.direction.normalize();\r\n\r\n        return true;\r\n    }\r\n\r\n    private _disposeBezierCurve() {\r\n        if (this._quadraticBezierCurve) {\r\n            this._quadraticBezierCurve.dispose();\r\n            this._quadraticBezierCurve = null;\r\n        }\r\n    }\r\n\r\n    private _colorArray: Color4[] = Array(24).fill(this._cachedColor4White);\r\n\r\n    private _showParabolicPath(pickInfo: PickingInfo) {\r\n        if (!pickInfo.pickedPoint || !this._currentTeleportationControllerId) {\r\n            return;\r\n        }\r\n\r\n        const sceneToRenderTo = this._options.useUtilityLayer\r\n            ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene\r\n            : this._xrSessionManager.scene;\r\n\r\n        const controllerData = this._controllers[this._currentTeleportationControllerId];\r\n\r\n        const quadraticBezierVectors = Curve3.CreateQuadraticBezier(controllerData.xrController.pointer.absolutePosition, pickInfo.ray!.origin, pickInfo.pickedPoint, 25);\r\n        const color = controllerData.teleportationState.blocked ? this._blockedRayColor : undefined;\r\n        const colorsArray = this._colorArray.fill(color || this._cachedColor4White);\r\n        // take out the first 2 points, to not start directly from the controller\r\n        const points = quadraticBezierVectors.getPoints();\r\n        points.shift();\r\n        points.shift();\r\n        if (!this._options.generateRayPathMesh) {\r\n            this._quadraticBezierCurve = CreateLines(\r\n                \"teleportation path line\",\r\n                { points: points, instance: this._quadraticBezierCurve as LinesMesh, updatable: true, colors: colorsArray },\r\n                sceneToRenderTo\r\n            );\r\n        } else {\r\n            this._quadraticBezierCurve = this._options.generateRayPathMesh(quadraticBezierVectors.getPoints(), pickInfo);\r\n        }\r\n        this._quadraticBezierCurve.isPickable = false;\r\n        if (this._options.renderingGroupId !== undefined) {\r\n            this._quadraticBezierCurve.renderingGroupId = this._options.renderingGroupId;\r\n        }\r\n    }\r\n\r\n    private _teleportForward(controllerId: string) {\r\n        const controllerData = this._controllers[controllerId];\r\n        if (!controllerData || !controllerData.teleportationState.forward || !this.teleportationEnabled) {\r\n            return;\r\n        }\r\n        controllerData.teleportationState.forward = false;\r\n        this._currentTeleportationControllerId = \"\";\r\n        if (this.snapPointsOnly && !this._snappedToPoint) {\r\n            return;\r\n        }\r\n\r\n        if (this.skipNextTeleportation) {\r\n            this.skipNextTeleportation = false;\r\n            return;\r\n        }\r\n        // do the movement forward here\r\n        if (this._options.teleportationTargetMesh && this._options.teleportationTargetMesh.isVisible) {\r\n            const height = this._options.xrInput.xrCamera.realWorldHeight;\r\n            this.onBeforeCameraTeleport.notifyObservers(this._options.xrInput.xrCamera.position);\r\n            this._options.xrInput.xrCamera.position.copyFrom(this._options.teleportationTargetMesh.position);\r\n            this._options.xrInput.xrCamera.position.y += height;\r\n            Quaternion.FromEulerAngles(0, controllerData.teleportationState.currentRotation - (this._xrSessionManager.scene.useRightHandedSystem ? Math.PI : 0), 0).multiplyToRef(\r\n                this._options.xrInput.xrCamera.rotationQuaternion,\r\n                this._options.xrInput.xrCamera.rotationQuaternion\r\n            );\r\n            this.onAfterCameraTeleport.notifyObservers(this._options.xrInput.xrCamera.position);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRControllerTeleportation.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRControllerTeleportation(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterRay();\r\n\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRMotionControllerTeleportation.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRMotionControllerTeleportation(xrSessionManager, options);\r\n        },\r\n        WebXRMotionControllerTeleportation.Version,\r\n        true\r\n    );\r\n}\r\n","import { type Vector3, type Quaternion } from \"../../Maths/math.vector\";\r\nimport { type IRaycastQuery, type PhysicsRaycastResult } from \"../physicsRaycastResult\";\r\nimport { type PhysicsBody } from \"./physicsBody\";\r\nimport { type PhysicsShape } from \"./physicsShape\";\r\nimport { type PhysicsConstraint } from \"./physicsConstraint\";\r\nimport { type BoundingBox } from \"../../Culling/boundingBox\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type PhysicsMaterial } from \"./physicsMaterial\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observable } from \"../../Misc/observable\";\r\nimport { type GroundMesh } from \"../../Meshes/groundMesh\";\r\n\r\n/** How a specific axis can be constrained */\r\nexport const enum PhysicsConstraintAxisLimitMode {\r\n    /**\r\n     * The axis is not restricted at all\r\n     */\r\n    FREE,\r\n    /**\r\n     * The axis has a minimum/maximum limit\r\n     */\r\n    LIMITED,\r\n    /**\r\n     * The axis allows no relative movement of the pivots\r\n     */\r\n    LOCKED,\r\n}\r\n\r\n/** The constraint specific axis to use when setting Friction, `ConstraintAxisLimitMode`, max force, ... */\r\nexport const enum PhysicsConstraintAxis {\r\n    /**\r\n     * Translation along the primary axis of the constraint (i.e. the\r\n     * direction specified by PhysicsConstraintParameters.axisA/axisB)\r\n     */\r\n    LINEAR_X,\r\n    /**\r\n     * Translation along the second axis of the constraint (i.e. the\r\n     * direction specified by PhysicsConstraintParameters.perpAxisA/perpAxisB)\r\n     */\r\n    LINEAR_Y,\r\n    /**\r\n     * Translation along the third axis of the constraint. This axis is\r\n     * computed from the cross product of axisA/axisB and perpAxisA/perpAxisB)\r\n     */\r\n    LINEAR_Z,\r\n    /**\r\n     * Rotation around the primary axis of the constraint (i.e. the\r\n     * axis specified by PhysicsConstraintParameters.axisA/axisB)\r\n     */\r\n    ANGULAR_X,\r\n    /**\r\n     * Rotation around the second axis of the constraint (i.e. the\r\n     * axis specified by PhysicsConstraintParameters.perpAxisA/perpAxisB)\r\n     */\r\n    ANGULAR_Y,\r\n    /**\r\n     * Rotation around the third axis of the constraint. This axis is\r\n     * computed from the cross product of axisA/axisB and perpAxisA/perpAxisB)\r\n     */\r\n    ANGULAR_Z,\r\n    /**\r\n     * A 3D distance limit; similar to specifying the LINEAR_X/Y/Z axes\r\n     * individually, but the distance calculation uses all three axes\r\n     * simultaneously, instead of individually.\r\n     */\r\n    LINEAR_DISTANCE,\r\n}\r\n\r\n/** Type of Constraint */\r\nexport const enum PhysicsConstraintType {\r\n    /**\r\n     * A ball and socket constraint will attempt to line up the pivot\r\n     * positions in each body, and have no restrictions on rotation\r\n     */\r\n    BALL_AND_SOCKET = 1,\r\n    /**\r\n     * A distance constraint will attempt to keep the pivot locations\r\n     * within a specified distance.\r\n     */\r\n    DISTANCE = 2,\r\n    /**\r\n     * A hinge constraint will keep the pivot positions aligned as well\r\n     * as two angular axes. The remaining angular axis will be free to rotate.\r\n     */\r\n    HINGE = 3,\r\n    /**\r\n     * A slider constraint allows bodies to translate along one axis and\r\n     * rotate about the same axis. The remaining two axes are locked in\r\n     * place\r\n     */\r\n    SLIDER = 4,\r\n    /**\r\n     * A lock constraint will attempt to keep the pivots completely lined\r\n     * up between both bodies, allowing no relative movement.\r\n     */\r\n    LOCK = 5,\r\n    /**\r\n     * A prismatic will lock the rotations of the bodies, and allow translation\r\n     * only along one axis\r\n     */\r\n    PRISMATIC = 6,\r\n    /**\r\n     * A generic constraint; this starts with no limits on how the bodies can\r\n     * move relative to each other, but limits can be added via the PhysicsConstraint\r\n     * interfaces. This can be used to specify a large variety of constraints\r\n     */\r\n    SIX_DOF = 7,\r\n}\r\n\r\n/** Type of Shape */\r\nexport const enum PhysicsShapeType {\r\n    SPHERE,\r\n    CAPSULE,\r\n    CYLINDER,\r\n    BOX,\r\n    CONVEX_HULL,\r\n    CONTAINER,\r\n    MESH,\r\n    HEIGHTFIELD,\r\n}\r\n\r\n/** Optional motor which attempts to move a body at a specific velocity, or at a specific position */\r\nexport const enum PhysicsConstraintMotorType {\r\n    NONE,\r\n    VELOCITY,\r\n    POSITION,\r\n}\r\n\r\nexport const enum PhysicsEventType {\r\n    COLLISION_STARTED = \"COLLISION_STARTED\",\r\n    COLLISION_CONTINUED = \"COLLISION_CONTINUED\",\r\n    COLLISION_FINISHED = \"COLLISION_FINISHED\",\r\n    TRIGGER_ENTERED = \"TRIGGER_ENTERED\",\r\n    TRIGGER_EXITED = \"TRIGGER_EXITED\",\r\n}\r\n\r\n/**\r\n * Base collision object\r\n */\r\nexport interface IBasePhysicsCollisionEvent {\r\n    /**\r\n     * 1st physics body that collided\r\n     */\r\n    collider: PhysicsBody;\r\n    /**\r\n     * 2nd physics body that collided\r\n     */\r\n    collidedAgainst: PhysicsBody;\r\n    /**\r\n     * index in instances array for the collider\r\n     */\r\n    colliderIndex: number;\r\n    /**\r\n     * index in instances array for the collidedAgainst\r\n     */\r\n    collidedAgainstIndex: number;\r\n    /**\r\n     * Event type\r\n     */\r\n    type: PhysicsEventType;\r\n}\r\n\r\n/**\r\n * Collision object that is the parameter when notification for collision fires.\r\n */\r\nexport interface IPhysicsCollisionEvent extends IBasePhysicsCollisionEvent {\r\n    /**\r\n     * World position where the collision occurred\r\n     */\r\n    point: Nullable<Vector3>;\r\n    /**\r\n     * Penetration distance\r\n     */\r\n    distance: number;\r\n    /**\r\n     * Impulse value computed by the solver response\r\n     */\r\n    impulse: number;\r\n    /**\r\n     * Collision world normal direction\r\n     */\r\n    normal: Nullable<Vector3>;\r\n}\r\n\r\n/**\r\n * Parameters used to describe the Shape\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsShapeParameters {\r\n    /**\r\n     * Shape center position\r\n     */\r\n    center?: Vector3;\r\n    /**\r\n     * Radius for cylinder, shape and capsule\r\n     */\r\n    radius?: number;\r\n    /**\r\n     * First point position that defines the cylinder or capsule\r\n     */\r\n    pointA?: Vector3;\r\n    /**\r\n     * Second point position that defines the cylinder or capsule\r\n     */\r\n    pointB?: Vector3;\r\n    /**\r\n     * Shape orientation\r\n     */\r\n    rotation?: Quaternion;\r\n    /**\r\n     * Dimension extents for the box\r\n     */\r\n    extents?: Vector3;\r\n    /**\r\n     * Mesh used for Mesh shape or convex hull. It can be different than the mesh the body is attached to.\r\n     */\r\n    mesh?: Mesh;\r\n    /**\r\n     * Use children hierarchy\r\n     */\r\n    includeChildMeshes?: boolean;\r\n    /**\r\n     * The size of the heightfield in the X axis\r\n     */\r\n    heightFieldSizeX?: number;\r\n    /**\r\n     * The size of the heightfield in the Z axis\r\n     */\r\n    heightFieldSizeZ?: number;\r\n    /**\r\n     * The number of samples along the X axis\r\n     */\r\n    numHeightFieldSamplesX?: number;\r\n    /**\r\n     * The number of samples along the Z axis\r\n     */\r\n    numHeightFieldSamplesZ?: number;\r\n    /**\r\n     * The data for the heightfield\r\n     */\r\n    heightFieldData?: Float32Array;\r\n    /**\r\n     * Ground mesh used for display\r\n     */\r\n    groundMesh?: GroundMesh;\r\n}\r\n\r\n/**\r\n * Parameters used to describe a Constraint\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsConstraintParameters {\r\n    /**\r\n     * Location of the constraint pivot in the space of first body\r\n     */\r\n    pivotA?: Vector3;\r\n    /**\r\n     * Location of the constraint pivot in the space of the second body\r\n     */\r\n    pivotB?: Vector3;\r\n    /**\r\n     * An axis in the space of the first body which determines how\r\n     * distances/angles are measured for LINEAR_X/ANGULAR_X limits.\r\n     */\r\n    axisA?: Vector3;\r\n    /**\r\n     * An axis in the space of the second body which determines how\r\n     * distances/angles are measured for LINEAR_X/ANGULAR_X limits.\r\n     */\r\n    axisB?: Vector3;\r\n\r\n    /**\r\n     * An axis in the space of the first body which determines how\r\n     * distances/angles are measured for LINEAR_Y/ANGULAR_Y limits.\r\n     */\r\n    perpAxisA?: Vector3;\r\n\r\n    /**\r\n     * An axis in the space of the second body which determines how\r\n     * distances/angles are measured for LINEAR_Y/ANGULAR_Y limits.\r\n     */\r\n    perpAxisB?: Vector3;\r\n\r\n    /**\r\n     * The maximum distance that can separate the two pivots.\r\n     * Only used for DISTANCE constraints\r\n     */\r\n    maxDistance?: number;\r\n\r\n    /**\r\n     * Determines if the connected bodies should collide. Generally,\r\n     * it is preferable to set this to false, especially if the constraint\r\n     * positions the bodies so that they overlap. Otherwise, the constraint\r\n     * will \"fight\" the collision detection and may cause jitter.\r\n     */\r\n    collision?: boolean;\r\n}\r\n\r\n/**\r\n * Parameters used to describe mass and inertia of the Physics Body\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsMassProperties {\r\n    /**\r\n     * The center of mass, in local space. This is The\r\n     * point the body will rotate around when applying\r\n     * an angular velocity.\r\n     *\r\n     * If not provided, the physics engine will compute\r\n     * an appropriate value.\r\n     */\r\n    centerOfMass?: Vector3;\r\n    /**\r\n     * The total mass of this object, in kilograms. This\r\n     * affects how easy it is to move the body. A value\r\n     * of zero will be used as an infinite mass.\r\n     *\r\n     * If not provided, the physics engine will compute\r\n     * an appropriate value.\r\n     */\r\n    mass?: number;\r\n    /**\r\n     * The principal moments of inertia of this object\r\n     * for a unit mass. This determines how easy it is\r\n     * for the body to rotate. A value of zero on any\r\n     * axis will be used as infinite inertia about that\r\n     * axis.\r\n     *\r\n     * If not provided, the physics engine will compute\r\n     * an appropriate value.\r\n     */\r\n    inertia?: Vector3;\r\n    /**\r\n     * The rotation rotating from inertia major axis space\r\n     * to parent space (i.e., the rotation which, when\r\n     * applied to the 3x3 inertia tensor causes the inertia\r\n     * tensor to become a diagonal matrix). This determines\r\n     * how the values of inertia are aligned with the parent\r\n     * object.\r\n     *\r\n     * If not provided, the physics engine will compute\r\n     * an appropriate value.\r\n     */\r\n    inertiaOrientation?: Quaternion;\r\n}\r\n\r\n/**\r\n * Indicates how the body will behave.\r\n */\r\nexport const enum PhysicsMotionType {\r\n    STATIC,\r\n    ANIMATED,\r\n    DYNAMIC,\r\n}\r\n\r\n/**\r\n * Indicates how to handle position/rotation change of transform node attached to a physics body\r\n */\r\nexport enum PhysicsPrestepType {\r\n    DISABLED,\r\n    TELEPORT,\r\n    ACTION,\r\n}\r\n\r\n/**\r\n * Controls the body sleep mode.\r\n */\r\nexport const enum PhysicsActivationControl {\r\n    SIMULATION_CONTROLLED,\r\n    ALWAYS_ACTIVE,\r\n    ALWAYS_INACTIVE,\r\n}\r\n\r\n/**\r\n * Represents a pair of bodies connected by a constraint.\r\n */\r\nexport type ConstrainedBodyPair = { parentBody: PhysicsBody; parentBodyIndex: number; childBody: PhysicsBody; childBodyIndex: number };\r\n\r\n/** @internal */\r\nexport interface IPhysicsEnginePluginV2 {\r\n    /**\r\n     * Physics plugin world instance\r\n     */\r\n    world: any;\r\n    /**\r\n     * Physics plugin name\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * Collision observable\r\n     */\r\n    onCollisionObservable: Observable<IPhysicsCollisionEvent>;\r\n    /**\r\n     * Collision ended observable\r\n     */\r\n    onCollisionEndedObservable: Observable<IBasePhysicsCollisionEvent>;\r\n    /**\r\n     * Trigger observable\r\n     */\r\n    onTriggerCollisionObservable: Observable<IBasePhysicsCollisionEvent>;\r\n\r\n    setGravity(gravity: Vector3): void;\r\n    setTimeStep(timeStep: number): void;\r\n    getTimeStep(): number;\r\n    executeStep(delta: number, bodies: Array<PhysicsBody>): void; //not forgetting pre and post events\r\n    getPluginVersion(): number;\r\n    setVelocityLimits(maxLinearVelocity: number, maxAngularVelocity: number): void;\r\n    getMaxLinearVelocity(): number;\r\n    getMaxAngularVelocity(): number;\r\n\r\n    // body\r\n    initBody(body: PhysicsBody, motionType: PhysicsMotionType, position: Vector3, orientation: Quaternion): void;\r\n    initBodyInstances(body: PhysicsBody, motionType: PhysicsMotionType, mesh: Mesh): void;\r\n    updateBodyInstances(body: PhysicsBody, mesh: Mesh): void;\r\n    removeBody(body: PhysicsBody): void;\r\n    sync(body: PhysicsBody): void;\r\n    syncTransform(body: PhysicsBody, transformNode: TransformNode): void;\r\n    setShape(body: PhysicsBody, shape: Nullable<PhysicsShape>): void;\r\n    getShape(body: PhysicsBody): Nullable<PhysicsShape>;\r\n    getShapeType(shape: PhysicsShape): PhysicsShapeType;\r\n    setEventMask(body: PhysicsBody, eventMask: number, instanceIndex?: number): void;\r\n    getEventMask(body: PhysicsBody, instanceIndex?: number): number;\r\n    setMotionType(body: PhysicsBody, motionType: PhysicsMotionType, instanceIndex?: number): void;\r\n    getMotionType(body: PhysicsBody, instanceIndex?: number): PhysicsMotionType;\r\n    computeMassProperties(body: PhysicsBody, instanceIndex?: number): PhysicsMassProperties;\r\n    setMassProperties(body: PhysicsBody, massProps: PhysicsMassProperties, instanceIndex?: number): void;\r\n    getMassProperties(body: PhysicsBody, instanceIndex?: number): PhysicsMassProperties;\r\n    setLinearDamping(body: PhysicsBody, damping: number, instanceIndex?: number): void;\r\n    getLinearDamping(body: PhysicsBody, instanceIndex?: number): number;\r\n    setAngularDamping(body: PhysicsBody, damping: number, instanceIndex?: number): void;\r\n    getAngularDamping(body: PhysicsBody, instanceIndex?: number): number;\r\n    setLinearVelocity(body: PhysicsBody, linVel: Vector3, instanceIndex?: number): void;\r\n    getLinearVelocityToRef(body: PhysicsBody, linVel: Vector3, instanceIndex?: number): void;\r\n    applyImpulse(body: PhysicsBody, impulse: Vector3, location: Vector3, instanceIndex?: number): void;\r\n    applyAngularImpulse(body: PhysicsBody, angularImpulse: Vector3, instanceIndex?: number): void;\r\n    applyForce(body: PhysicsBody, force: Vector3, location: Vector3, instanceIndex?: number): void;\r\n    applyTorque(body: PhysicsBody, torque: Vector3, instanceIndex?: number): void;\r\n    setAngularVelocity(body: PhysicsBody, angVel: Vector3, instanceIndex?: number): void;\r\n    getAngularVelocityToRef(body: PhysicsBody, angVel: Vector3, instanceIndex?: number): void;\r\n    getBodyGeometry(body: PhysicsBody): object;\r\n    disposeBody(body: PhysicsBody): void;\r\n    setCollisionCallbackEnabled(body: PhysicsBody, enabled: boolean, instanceIndex?: number): void;\r\n    setCollisionEndedCallbackEnabled(body: PhysicsBody, enabled: boolean, instanceIndex?: number): void;\r\n    addConstraint(body: PhysicsBody, childBody: PhysicsBody, constraint: PhysicsConstraint, instanceIndex?: number, childInstanceIndex?: number): void;\r\n    getCollisionObservable(body: PhysicsBody, instanceIndex?: number): Observable<IPhysicsCollisionEvent>;\r\n    getCollisionEndedObservable(body: PhysicsBody, instanceIndex?: number): Observable<IBasePhysicsCollisionEvent>;\r\n    setGravityFactor(body: PhysicsBody, factor: number, instanceIndex?: number): void;\r\n    getGravityFactor(body: PhysicsBody, instanceIndex?: number): number;\r\n    setTargetTransform(body: PhysicsBody, position: Vector3, rotation: Quaternion, instanceIndex?: number): void;\r\n\r\n    // shape\r\n    initShape(shape: PhysicsShape, type: PhysicsShapeType, options: PhysicsShapeParameters): void;\r\n    setShapeFilterMembershipMask(shape: PhysicsShape, membershipMask: number): void;\r\n    getShapeFilterMembershipMask(shape: PhysicsShape): number;\r\n    setShapeFilterCollideMask(shape: PhysicsShape, collideMask: number): void;\r\n    getShapeFilterCollideMask(shape: PhysicsShape): number;\r\n    setMaterial(shape: PhysicsShape, material: PhysicsMaterial): void;\r\n    getMaterial(shape: PhysicsShape): PhysicsMaterial;\r\n    setDensity(shape: PhysicsShape, density: number): void;\r\n    getDensity(shape: PhysicsShape): number;\r\n    addChild(shape: PhysicsShape, newChild: PhysicsShape, translation?: Vector3, rotation?: Quaternion, scale?: Vector3): void;\r\n    removeChild(shape: PhysicsShape, childIndex: number): void;\r\n    getNumChildren(shape: PhysicsShape): number;\r\n    getBoundingBox(shape: PhysicsShape): BoundingBox;\r\n    getBodyBoundingBox(body: PhysicsBody): BoundingBox;\r\n    disposeShape(shape: PhysicsShape): void;\r\n    setTrigger(shape: PhysicsShape, isTrigger: boolean): void;\r\n\r\n    // constraint\r\n    initConstraint(constraint: PhysicsConstraint, body: PhysicsBody, childBody: PhysicsBody): void;\r\n    setEnabled(constraint: PhysicsConstraint, isEnabled: boolean): void;\r\n    getEnabled(constraint: PhysicsConstraint): boolean;\r\n    setCollisionsEnabled(constraint: PhysicsConstraint, isEnabled: boolean): void;\r\n    getCollisionsEnabled(constraint: PhysicsConstraint): boolean;\r\n    setAxisFriction(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, friction: number): void;\r\n    getAxisFriction(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number>;\r\n    setAxisMode(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, limitMode: PhysicsConstraintAxisLimitMode): void;\r\n    getAxisMode(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<PhysicsConstraintAxisLimitMode>;\r\n    setAxisMinLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, minLimit: number): void;\r\n    getAxisMinLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number>;\r\n    setAxisMaxLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, limit: number): void;\r\n    getAxisMaxLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number>;\r\n    setAxisMotorType(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, motorType: PhysicsConstraintMotorType): void;\r\n    getAxisMotorType(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<PhysicsConstraintMotorType>;\r\n    setAxisMotorTarget(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, target: number): void;\r\n    getAxisMotorTarget(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number>;\r\n    setAxisMotorMaxForce(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, maxForce: number): void;\r\n    getAxisMotorMaxForce(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number>;\r\n    disposeConstraint(constraint: PhysicsConstraint): void;\r\n    getBodiesUsingConstraint(constraint: PhysicsConstraint): ConstrainedBodyPair[];\r\n\r\n    // raycast\r\n    raycast(from: Vector3, to: Vector3, result: PhysicsRaycastResult | Array<PhysicsRaycastResult>, query?: IRaycastQuery): void;\r\n\r\n    dispose(): void;\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\nimport { Mesh } from \"../../Meshes/mesh.pure\";\nimport { type WebXRInput } from \"../webXRInput\";\nimport { type WebXRInputSource } from \"../webXRInputSource\";\nimport { Matrix, Quaternion } from \"../../Maths/math.vector.pure\";\nimport { type Nullable } from \"../../types\";\nimport { PhysicsImpostor } from \"../../Physics/v1/physicsImpostor.pure\";\nimport { PhysicsAggregate } from \"../../Physics/v2/physicsAggregate\";\nimport { PhysicsMotionType, PhysicsShapeType } from \"../../Physics/v2/IPhysicsEnginePlugin\";\nimport { type IDisposable, type Scene } from \"../../scene.pure\";\nimport { Observable } from \"../../Misc/observable.pure\";\nimport { type Observer } from \"../../Misc/observable\";\nimport { type InstancedMesh, RegisterInstancedMesh } from \"../../Meshes/instancedMesh.pure\";\nimport { SceneLoader, type ISceneLoaderAsyncResult } from \"../../Loading/sceneLoader\";\n\nimport { Color3 } from \"../../Maths/math.color.pure\";\nimport { NodeMaterialParseFromFileAsync } from \"../../Materials/Node/nodeMaterial.pure\";\nimport { type InputBlock } from \"../../Materials/Node/Blocks/Input/inputBlock.pure\";\nimport { Material } from \"../../Materials/material.pure\";\nimport { CreateIcoSphere } from \"../../Meshes/Builders/icoSphereBuilder.pure\";\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\nimport { Axis } from \"../../Maths/math.axis\";\nimport { Constants } from \"../../Engines/constants\";\nimport { type WebXRCompositionLayerWrapper } from \"./Layers/WebXRCompositionLayer\";\nimport { Tools } from \"core/Misc/tools.pure\";\nimport { type WebXRCamera } from \"../webXRCamera\";\nimport { type Node } from \"../../node\";\n\ndeclare const XRHand: XRHand;\n\n/**\n * Configuration interface for the hand tracking feature\n */\nexport interface IWebXRHandTrackingOptions {\n    /**\n     * The xrInput that will be used as source for new hands\n     */\n    xrInput: WebXRInput;\n\n    /**\n     * Configuration object for the joint meshes.\n     */\n    jointMeshes?: {\n        /**\n         * Should the meshes created be invisible (defaults to false).\n         */\n        invisible?: boolean;\n        /**\n         * A source mesh to be used to create instances. Defaults to an icosphere with two subdivisions and smooth lighting.\n         * This mesh will be the source for all other (25) meshes.\n         * It should have the general size of a single unit, as the instances will be scaled according to the provided radius.\n         */\n        sourceMesh?: Mesh;\n        /**\n         * This function will be called after a mesh was created for a specific joint.\n         * Using this function you can either manipulate the instance or return a new mesh.\n         * When returning a new mesh the instance created before will be disposed.\n         * @param meshInstance An instance of the original joint mesh being used for the joint.\n         * @param jointId The joint's index, see https://immersive-web.github.io/webxr-hand-input/#skeleton-joints-section for more info.\n         * @param hand Which hand (\"left\", \"right\") the joint will be on.\n         */\n        onHandJointMeshGenerated?: (meshInstance: InstancedMesh, jointId: number, hand: XRHandedness) => AbstractMesh | undefined;\n        /**\n         * Should the source mesh stay visible (defaults to false).\n         */\n        keepOriginalVisible?: boolean;\n        /**\n         * Should each instance have its own physics impostor\n         */\n        enablePhysics?: boolean;\n        /**\n         * If enabled, override default physics properties\n         */\n        physicsProps?: { friction?: number; restitution?: number; impostorType?: number };\n        /**\n         * Scale factor for all joint meshes (defaults to 1)\n         */\n        scaleFactor?: number;\n    };\n\n    /**\n     * Configuration object for the hand meshes.\n     */\n    handMeshes?: {\n        /**\n         * Should the default hand mesh be disabled. In this case, the spheres will be visible (unless set invisible).\n         */\n        disableDefaultMeshes?: boolean;\n        /**\n         * Rigged hand meshes that will be tracked to the user's hands. This will override the default hand mesh.\n         */\n        customMeshes?: {\n            right: AbstractMesh;\n            left: AbstractMesh;\n        };\n        /**\n         * Are the meshes prepared for a left-handed system. Default hand meshes are right-handed.\n         */\n        meshesUseLeftHandedCoordinates?: boolean;\n        /**\n         * If a hand mesh was provided, this array will define what axis will update which node. This will override the default hand mesh\n         */\n        customRigMappings?: {\n            right: XRHandMeshRigMapping;\n            left: XRHandMeshRigMapping;\n        };\n\n        /**\n         * Override the colors of the hand meshes.\n         */\n        customColors?: {\n            base?: Color3;\n            fresnel?: Color3;\n            fingerColor?: Color3;\n            tipFresnel?: Color3;\n        };\n\n        /**\n         * Define whether or not the hand meshes should be disposed on just invisible when the session ends.\n         * Not setting, or setting to false, will maintain the hand meshes in the scene after the session ends, which will allow q quicker re-entry into XR.\n         */\n        disposeOnSessionEnd?: boolean;\n\n        /**\n         * Setting this will allow the developer to avoid loading the NME material and use the standard material instead.\n         */\n        disableHandShader?: boolean;\n    };\n}\n\n/**\n * Parts of the hands divided to writs and finger names\n */\nexport const enum HandPart {\n    /**\n     * HandPart - Wrist\n     */\n    WRIST = \"wrist\",\n    /**\n     * HandPart - The thumb\n     */\n    THUMB = \"thumb\",\n    /**\n     * HandPart - Index finger\n     */\n    INDEX = \"index\",\n    /**\n     * HandPart - Middle finger\n     */\n    MIDDLE = \"middle\",\n    /**\n     * HandPart - Ring finger\n     */\n    RING = \"ring\",\n    /**\n     * HandPart - Little finger\n     */\n    LITTLE = \"little\",\n}\n\n/**\n * Joints of the hand as defined by the WebXR specification.\n * https://immersive-web.github.io/webxr-hand-input/#skeleton-joints-section\n */\nexport const enum WebXRHandJoint {\n    /** Wrist */\n    WRIST = \"wrist\",\n\n    /** Thumb near wrist */\n    THUMB_METACARPAL = \"thumb-metacarpal\",\n    /** Thumb first knuckle */\n    THUMB_PHALANX_PROXIMAL = \"thumb-phalanx-proximal\",\n    /** Thumb second knuckle */\n    THUMB_PHALANX_DISTAL = \"thumb-phalanx-distal\",\n    /** Thumb tip */\n    THUMB_TIP = \"thumb-tip\",\n\n    /** Index finger near wrist */\n    INDEX_FINGER_METACARPAL = \"index-finger-metacarpal\",\n    /** Index finger first knuckle */\n    INDEX_FINGER_PHALANX_PROXIMAL = \"index-finger-phalanx-proximal\",\n    /** Index finger second knuckle */\n    INDEX_FINGER_PHALANX_INTERMEDIATE = \"index-finger-phalanx-intermediate\",\n    /** Index finger third knuckle */\n    INDEX_FINGER_PHALANX_DISTAL = \"index-finger-phalanx-distal\",\n    /** Index finger tip */\n    INDEX_FINGER_TIP = \"index-finger-tip\",\n\n    /** Middle finger near wrist */\n    MIDDLE_FINGER_METACARPAL = \"middle-finger-metacarpal\",\n    /** Middle finger first knuckle */\n    MIDDLE_FINGER_PHALANX_PROXIMAL = \"middle-finger-phalanx-proximal\",\n    /** Middle finger second knuckle */\n    MIDDLE_FINGER_PHALANX_INTERMEDIATE = \"middle-finger-phalanx-intermediate\",\n    /** Middle finger third knuckle */\n    MIDDLE_FINGER_PHALANX_DISTAL = \"middle-finger-phalanx-distal\",\n    /** Middle finger tip */\n    MIDDLE_FINGER_TIP = \"middle-finger-tip\",\n\n    /** Ring finger near wrist */\n    RING_FINGER_METACARPAL = \"ring-finger-metacarpal\",\n    /** Ring finger first knuckle */\n    RING_FINGER_PHALANX_PROXIMAL = \"ring-finger-phalanx-proximal\",\n    /** Ring finger second knuckle */\n    RING_FINGER_PHALANX_INTERMEDIATE = \"ring-finger-phalanx-intermediate\",\n    /** Ring finger third knuckle */\n    RING_FINGER_PHALANX_DISTAL = \"ring-finger-phalanx-distal\",\n    /** Ring finger tip */\n    RING_FINGER_TIP = \"ring-finger-tip\",\n\n    /** Pinky finger near wrist */\n    PINKY_FINGER_METACARPAL = \"pinky-finger-metacarpal\",\n    /** Pinky finger first knuckle */\n    PINKY_FINGER_PHALANX_PROXIMAL = \"pinky-finger-phalanx-proximal\",\n    /** Pinky finger second knuckle */\n    PINKY_FINGER_PHALANX_INTERMEDIATE = \"pinky-finger-phalanx-intermediate\",\n    /** Pinky finger third knuckle */\n    PINKY_FINGER_PHALANX_DISTAL = \"pinky-finger-phalanx-distal\",\n    /** Pinky finger tip */\n    PINKY_FINGER_TIP = \"pinky-finger-tip\",\n}\n\n/** A type encapsulating a dictionary mapping WebXR joints to bone names in a rigged hand mesh.  */\nexport type XRHandMeshRigMapping = { [webXRJointName in WebXRHandJoint]: string };\n\nconst HandJointReferenceArray: WebXRHandJoint[] = [\n    WebXRHandJoint.WRIST,\n    WebXRHandJoint.THUMB_METACARPAL,\n    WebXRHandJoint.THUMB_PHALANX_PROXIMAL,\n    WebXRHandJoint.THUMB_PHALANX_DISTAL,\n    WebXRHandJoint.THUMB_TIP,\n    WebXRHandJoint.INDEX_FINGER_METACARPAL,\n    WebXRHandJoint.INDEX_FINGER_PHALANX_PROXIMAL,\n    WebXRHandJoint.INDEX_FINGER_PHALANX_INTERMEDIATE,\n    WebXRHandJoint.INDEX_FINGER_PHALANX_DISTAL,\n    WebXRHandJoint.INDEX_FINGER_TIP,\n    WebXRHandJoint.MIDDLE_FINGER_METACARPAL,\n    WebXRHandJoint.MIDDLE_FINGER_PHALANX_PROXIMAL,\n    WebXRHandJoint.MIDDLE_FINGER_PHALANX_INTERMEDIATE,\n    WebXRHandJoint.MIDDLE_FINGER_PHALANX_DISTAL,\n    WebXRHandJoint.MIDDLE_FINGER_TIP,\n    WebXRHandJoint.RING_FINGER_METACARPAL,\n    WebXRHandJoint.RING_FINGER_PHALANX_PROXIMAL,\n    WebXRHandJoint.RING_FINGER_PHALANX_INTERMEDIATE,\n    WebXRHandJoint.RING_FINGER_PHALANX_DISTAL,\n    WebXRHandJoint.RING_FINGER_TIP,\n    WebXRHandJoint.PINKY_FINGER_METACARPAL,\n    WebXRHandJoint.PINKY_FINGER_PHALANX_PROXIMAL,\n    WebXRHandJoint.PINKY_FINGER_PHALANX_INTERMEDIATE,\n    WebXRHandJoint.PINKY_FINGER_PHALANX_DISTAL,\n    WebXRHandJoint.PINKY_FINGER_TIP,\n];\n\nconst HandPartsDefinition: { [key in HandPart]: WebXRHandJoint[] } = {\n    [HandPart.WRIST]: [WebXRHandJoint.WRIST],\n    [HandPart.THUMB]: [WebXRHandJoint.THUMB_METACARPAL, WebXRHandJoint.THUMB_PHALANX_PROXIMAL, WebXRHandJoint.THUMB_PHALANX_DISTAL, WebXRHandJoint.THUMB_TIP],\n    [HandPart.INDEX]: [\n        WebXRHandJoint.INDEX_FINGER_METACARPAL,\n        WebXRHandJoint.INDEX_FINGER_PHALANX_PROXIMAL,\n        WebXRHandJoint.INDEX_FINGER_PHALANX_INTERMEDIATE,\n        WebXRHandJoint.INDEX_FINGER_PHALANX_DISTAL,\n        WebXRHandJoint.INDEX_FINGER_TIP,\n    ],\n    [HandPart.MIDDLE]: [\n        WebXRHandJoint.MIDDLE_FINGER_METACARPAL,\n        WebXRHandJoint.MIDDLE_FINGER_PHALANX_PROXIMAL,\n        WebXRHandJoint.MIDDLE_FINGER_PHALANX_INTERMEDIATE,\n        WebXRHandJoint.MIDDLE_FINGER_PHALANX_DISTAL,\n        WebXRHandJoint.MIDDLE_FINGER_TIP,\n    ],\n    [HandPart.RING]: [\n        WebXRHandJoint.RING_FINGER_METACARPAL,\n        WebXRHandJoint.RING_FINGER_PHALANX_PROXIMAL,\n        WebXRHandJoint.RING_FINGER_PHALANX_INTERMEDIATE,\n        WebXRHandJoint.RING_FINGER_PHALANX_DISTAL,\n        WebXRHandJoint.RING_FINGER_TIP,\n    ],\n    [HandPart.LITTLE]: [\n        WebXRHandJoint.PINKY_FINGER_METACARPAL,\n        WebXRHandJoint.PINKY_FINGER_PHALANX_PROXIMAL,\n        WebXRHandJoint.PINKY_FINGER_PHALANX_INTERMEDIATE,\n        WebXRHandJoint.PINKY_FINGER_PHALANX_DISTAL,\n        WebXRHandJoint.PINKY_FINGER_TIP,\n    ],\n};\n\n/**\n * Representing a single hand (with its corresponding native XRHand object)\n */\nexport class WebXRHand implements IDisposable {\n    /**\n     * This observable will notify registered observers when the hand object has been set with a new mesh.\n     * you can get the hand mesh using `webxrHand.handMesh`\n     */\n    public onHandMeshSetObservable = new Observable<WebXRHand>();\n\n    private _scene: Scene;\n\n    /**\n     * Transform nodes that will directly receive the transforms from the WebXR matrix data.\n     */\n    private _jointTransforms = new Array<TransformNode>(HandJointReferenceArray.length);\n\n    /**\n     * The float array that will directly receive the transform matrix data from WebXR.\n     */\n    private _jointTransformMatrices = new Float32Array(HandJointReferenceArray.length * 16);\n    private _jointSpaces: XRJointSpace[] = new Array(HandJointReferenceArray.length);\n\n    private _tempJointMatrix = new Matrix();\n\n    /**\n     * The float array that will directly receive the joint radii from WebXR.\n     */\n    private _jointRadii = new Float32Array(HandJointReferenceArray.length);\n\n    /**\n     * The hand mesh's top-most parent, if any.\n     */\n    private _handMeshRoot: Nullable<Node> = null;\n\n    /**\n     * Get the hand mesh.\n     */\n    public get handMesh(): Nullable<AbstractMesh> {\n        return this._handMesh;\n    }\n\n    /**\n     * Get meshes of part of the hand.\n     * @param part The part of hand to get.\n     * @returns An array of meshes that correlate to the hand part requested.\n     */\n    public getHandPartMeshes(part: HandPart): AbstractMesh[] {\n        return HandPartsDefinition[part].map((name) => this._jointMeshes[HandJointReferenceArray.indexOf(name)]);\n    }\n\n    /**\n     * Retrieves a mesh linked to a named joint in the hand.\n     * @param jointName The name of the joint.\n     * @returns An AbstractMesh whose position corresponds with the joint position.\n     */\n    public getJointMesh(jointName: WebXRHandJoint): AbstractMesh {\n        return this._jointMeshes[HandJointReferenceArray.indexOf(jointName)];\n    }\n\n    /**\n     * Construct a new hand object\n     * @param xrController The controller to which the hand correlates.\n     * @param _jointMeshes The meshes to be used to track the hand joints.\n     * @param _handMesh An optional hand mesh.\n     * @param rigMapping An optional rig mapping for the hand mesh.\n     *                   If not provided (but a hand mesh is provided),\n     *                   it will be assumed that the hand mesh's bones are named\n     *                   directly after the WebXR bone names.\n     * @param _leftHandedMeshes Are the hand meshes left-handed-system meshes\n     * @param _jointsInvisible Are the tracked joint meshes visible\n     * @param _jointScaleFactor Scale factor for all joint meshes\n     */\n    constructor(\n        /** The controller to which the hand correlates. */\n        public readonly xrController: WebXRInputSource,\n        private readonly _jointMeshes: AbstractMesh[],\n        private _handMesh: Nullable<AbstractMesh>,\n        /** An optional rig mapping for the hand mesh. If not provided (but a hand mesh is provided),\n         * it will be assumed that the hand mesh's bones are named directly after the WebXR bone names. */\n        readonly rigMapping: Nullable<XRHandMeshRigMapping>,\n        private readonly _leftHandedMeshes: boolean = false,\n        private readonly _jointsInvisible: boolean = false,\n        private readonly _jointScaleFactor: number = 1\n    ) {\n        this._scene = _jointMeshes[0].getScene();\n\n        // Initialize the joint transform quaternions and link the transforms to the bones.\n        for (let jointIdx = 0; jointIdx < this._jointTransforms.length; jointIdx++) {\n            this._jointTransforms[jointIdx] = new TransformNode(HandJointReferenceArray[jointIdx], this._scene);\n            this._jointTransforms[jointIdx].rotationQuaternion = new Quaternion();\n\n            // Set the rotation quaternion so we can use it later for tracking.\n            if (!_jointMeshes[jointIdx].rotationQuaternion) {\n                _jointMeshes[jointIdx].rotationQuaternion = new Quaternion();\n            }\n            _jointMeshes[jointIdx].rotationQuaternion!.set(0, 0, 0, 1);\n        }\n\n        if (_handMesh) {\n            // Note that this logic needs to happen after we initialize the joint tracking transform nodes.\n            this.setHandMesh(_handMesh, rigMapping);\n        }\n\n        // hide the motion controller, if available/loaded\n        if (this.xrController.motionController) {\n            if (this.xrController.motionController.rootMesh) {\n                this.xrController.motionController.rootMesh.dispose(false, true);\n            }\n        }\n\n        this.xrController.onMotionControllerInitObservable.add((motionController) => {\n            motionController._doNotLoadControllerMesh = true;\n        });\n    }\n\n    /**\n     * Sets the current hand mesh to render for the WebXRHand.\n     * @param handMesh The rigged hand mesh that will be tracked to the user's hand.\n     * @param rigMapping The mapping from XRHandJoint to bone names to use with the mesh.\n     * @param _xrSessionManager The XRSessionManager used to initialize the hand mesh.\n     */\n    public setHandMesh(handMesh: AbstractMesh, rigMapping: Nullable<XRHandMeshRigMapping>, _xrSessionManager?: WebXRSessionManager) {\n        this._handMesh = handMesh;\n\n        this._handMeshRoot = this._handMesh;\n        while (this._handMeshRoot.parent) {\n            this._handMeshRoot = this._handMeshRoot.parent;\n        }\n\n        // Avoid any strange frustum culling. We will manually control visibility via attach and detach.\n        handMesh.alwaysSelectAsActiveMesh = true;\n        const children = handMesh.getChildMeshes();\n        for (const mesh of children) {\n            mesh.alwaysSelectAsActiveMesh = true;\n        }\n\n        // Link the bones in the hand mesh to the transform nodes that will be bound to the WebXR tracked joints.\n        if (this._handMesh.skeleton) {\n            const handMeshSkeleton = this._handMesh.skeleton;\n            for (let jointIdx = 0; jointIdx < HandJointReferenceArray.length; jointIdx++) {\n                const jointName = HandJointReferenceArray[jointIdx];\n                const jointBoneIdx = handMeshSkeleton.getBoneIndexByName(rigMapping ? rigMapping[jointName] : jointName);\n                if (jointBoneIdx !== -1) {\n                    handMeshSkeleton.bones[jointBoneIdx].linkTransformNode(this._jointTransforms[jointIdx]);\n                }\n            }\n        }\n\n        this.onHandMeshSetObservable.notifyObservers(this);\n    }\n\n    /**\n     * Update this hand from the latest xr frame.\n     * @param xrFrame The latest frame received from WebXR.\n     * @param referenceSpace The current viewer reference space.\n     * @param xrCamera the xr camera, used for parenting\n     */\n    public updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace, xrCamera: WebXRCamera) {\n        const hand = this.xrController.inputSource.hand;\n        if (!hand) {\n            return;\n        }\n\n        // TODO: Modify webxr.d.ts to better match WebXR IDL so we don't need this any cast.\n        const anyHand: any = hand;\n        for (let i = 0; i < HandJointReferenceArray.length; ++i) {\n            this._jointSpaces[i] = anyHand[HandJointReferenceArray[i]] || hand.get(HandJointReferenceArray[i]);\n        }\n        let trackingSuccessful = false;\n\n        if (xrFrame.fillPoses && xrFrame.fillJointRadii) {\n            trackingSuccessful = xrFrame.fillPoses(this._jointSpaces, referenceSpace, this._jointTransformMatrices) && xrFrame.fillJointRadii(this._jointSpaces, this._jointRadii);\n        } else if (xrFrame.getJointPose) {\n            trackingSuccessful = true;\n            // Warning: This codepath is slow by comparison, only here for compat.\n            for (let jointIdx = 0; jointIdx < this._jointSpaces.length; jointIdx++) {\n                const jointPose = xrFrame.getJointPose(this._jointSpaces[jointIdx], referenceSpace);\n                if (jointPose) {\n                    this._jointTransformMatrices.set(jointPose.transform.matrix, jointIdx * 16);\n                    this._jointRadii[jointIdx] = jointPose.radius || 0.008;\n                } else {\n                    trackingSuccessful = false;\n                    break;\n                }\n            }\n        }\n\n        if (!trackingSuccessful) {\n            return;\n        }\n\n        // L1 Cache Optimization: Invert to LHS in valid Babylon systems IN PLACE\n        // This linear loop is much faster than doing it per-object and avoids cache thrashing\n        if (!this._scene.useRightHandedSystem) {\n            for (let i = 0; i < HandJointReferenceArray.length; ++i) {\n                const offset = i * 16;\n                this._jointTransformMatrices[offset + 2] *= -1;\n                this._jointTransformMatrices[offset + 6] *= -1;\n                this._jointTransformMatrices[offset + 8] *= -1;\n                this._jointTransformMatrices[offset + 9] *= -1;\n                this._jointTransformMatrices[offset + 14] *= -1;\n            }\n        }\n\n        for (let jointIdx = 0; jointIdx < HandJointReferenceArray.length; jointIdx++) {\n            const jointTransform = this._jointTransforms[jointIdx];\n            Matrix.FromArrayToRef(this._jointTransformMatrices, jointIdx * 16, this._tempJointMatrix);\n            this._tempJointMatrix.decompose(undefined, jointTransform.rotationQuaternion!, jointTransform.position);\n\n            // The radius we need to make the joint in order for it to roughly cover the joints of the user's real hand.\n            const scaledJointRadius = this._jointRadii[jointIdx] * this._jointScaleFactor;\n\n            const jointMesh = this._jointMeshes[jointIdx];\n            jointMesh.isVisible = !this._handMesh && !this._jointsInvisible;\n            jointMesh.position.copyFrom(jointTransform.position);\n            jointMesh.rotationQuaternion!.copyFrom(jointTransform.rotationQuaternion!);\n            jointMesh.scaling.setAll(scaledJointRadius);\n            jointMesh.parent = xrCamera.parent;\n\n            // Restore correct transform for meshes that are NOT left-handed (e.g. default GLTF)\n            // The buffer is now LHS, so if the mesh expects RHS, we must un-flip.\n            if (!this._leftHandedMeshes && !this._scene.useRightHandedSystem && this._handMesh) {\n                jointTransform.position.z *= -1;\n                jointTransform.rotationQuaternion!.z *= -1;\n                jointTransform.rotationQuaternion!.w *= -1;\n            }\n        }\n\n        if (this._handMesh) {\n            this._handMesh.isVisible = true;\n\n            if (this._handMeshRoot) {\n                this._handMeshRoot.parent = xrCamera.parent;\n            }\n        }\n\n        this.xrController.pointer.parent = xrCamera.parent;\n    }\n\n    /**\n     * Dispose this Hand object\n     * @param disposeMeshes Should the meshes be disposed as well\n     */\n    public dispose(disposeMeshes = false) {\n        if (this._handMesh) {\n            if (disposeMeshes) {\n                this._handMesh.skeleton?.dispose();\n                this._handMesh.dispose(false, true);\n            } else {\n                this._handMesh.isVisible = false;\n            }\n        }\n        for (const transform of this._jointTransforms) {\n            transform.dispose();\n        }\n\n        this._jointTransforms.length = 0;\n        this.onHandMeshSetObservable.clear();\n    }\n}\n\n/**\n * WebXR Hand Joint tracking feature, available for selected browsers and devices\n */\nexport class WebXRHandTracking extends WebXRAbstractFeature {\n    /**\n     * The module's name\n     */\n    public static readonly Name = WebXRFeatureName.HAND_TRACKING;\n    /**\n     * The (Babylon) version of this module.\n     * This is an integer representing the implementation version.\n     * This number does not correspond to the WebXR specs version\n     */\n    public static readonly Version = 1;\n\n    /** The base URL for the default hand model. */\n    public static DEFAULT_HAND_MODEL_BASE_URL = \"https://assets.babylonjs.com/core/HandMeshes/\";\n    /** The filename to use for the default right hand model. */\n    public static DEFAULT_HAND_MODEL_RIGHT_FILENAME = \"r_hand_rhs.glb\";\n    /** The filename to use for the default left hand model. */\n    public static DEFAULT_HAND_MODEL_LEFT_FILENAME = \"l_hand_rhs.glb\";\n    /** The URL pointing to the default hand model NodeMaterial shader. */\n    public static DEFAULT_HAND_MODEL_SHADER_URL = \"https://assets.babylonjs.com/core/HandMeshes/handsShader.json\";\n\n    // We want to use lightweight models, diameter will initially be 1 but scaled to the values returned from WebXR.\n    private static readonly _ICOSPHERE_PARAMS = { radius: 0.5, flat: false, subdivisions: 2 };\n\n    private static _RightHandGLB: Nullable<ISceneLoaderAsyncResult> = null;\n    private static _LeftHandGLB: Nullable<ISceneLoaderAsyncResult> = null;\n\n    private static _GenerateTrackedJointMeshes(options: IWebXRHandTrackingOptions, originalMesh: AbstractMesh): { left: AbstractMesh[]; right: AbstractMesh[] } {\n        const meshes: { left: AbstractMesh[]; right: AbstractMesh[] } = { left: [], right: [] };\n\n        originalMesh.isVisible = !!options.jointMeshes?.keepOriginalVisible;\n        for (const handedness of [\"left\", \"right\"] as const) {\n            const h = handedness as \"left\" | \"right\";\n            const trackedMeshes: AbstractMesh[] = [];\n            for (let i = 0; i < HandJointReferenceArray.length; i++) {\n                let newInstance: AbstractMesh;\n                if (originalMesh instanceof Mesh) {\n                    newInstance = originalMesh.createInstance(`${handedness}-handJoint-${i}`);\n                } else {\n                    newInstance = originalMesh.clone(`${handedness}-handJoint-${i}`, null) as AbstractMesh;\n                }\n                if (options.jointMeshes?.onHandJointMeshGenerated) {\n                    const returnedMesh = options.jointMeshes.onHandJointMeshGenerated(newInstance as InstancedMesh, i, h);\n                    if (returnedMesh) {\n                        if (returnedMesh !== newInstance) {\n                            newInstance.dispose();\n                            newInstance = returnedMesh;\n                        }\n                    }\n                }\n                newInstance.isPickable = false;\n                if (options.jointMeshes?.enablePhysics) {\n                    const props = options.jointMeshes?.physicsProps;\n                    // downscale the instances so that physics will be initialized correctly\n                    newInstance.scaling.setAll(0.02);\n                    // Detect physics version\n                    const scene = newInstance.getScene();\n                    const physicsEngine = scene.getPhysicsEngine();\n                    const physicsVersion = physicsEngine?.getPluginVersion() || 1;\n\n                    if (physicsVersion === 2) {\n                        // V2 physics\n                        const impostorType = props?.impostorType !== undefined ? props.impostorType : PhysicsImpostor.SphereImpostor;\n                        let shapeType: PhysicsShapeType;\n\n                        // Map v1 impostor types to v2 shape types\n                        switch (impostorType) {\n                            case PhysicsImpostor.SphereImpostor:\n                                shapeType = PhysicsShapeType.SPHERE;\n                                break;\n                            case PhysicsImpostor.BoxImpostor:\n                                shapeType = PhysicsShapeType.BOX;\n                                break;\n                            case PhysicsImpostor.CapsuleImpostor:\n                                shapeType = PhysicsShapeType.CAPSULE;\n                                break;\n                            default:\n                                shapeType = PhysicsShapeType.SPHERE;\n                        }\n\n                        const aggregate = new PhysicsAggregate(\n                            newInstance,\n                            shapeType,\n                            {\n                                mass: 0,\n                                friction: props?.friction ?? 0.2,\n                                restitution: props?.restitution ?? 0.2,\n                            },\n                            scene\n                        );\n                        aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);\n                        aggregate.body.disableSync = true;\n                    } else {\n                        // V1 physics\n                        const type = props?.impostorType !== undefined ? props.impostorType : PhysicsImpostor.SphereImpostor;\n                        newInstance.physicsImpostor = new PhysicsImpostor(newInstance, type, props ? { mass: 0, ...props } : { mass: 0 });\n                    }\n                }\n                newInstance.isVisible = false;\n                newInstance.rotationQuaternion = new Quaternion();\n                trackedMeshes.push(newInstance);\n            }\n\n            meshes[h] = trackedMeshes;\n        }\n        return meshes;\n    }\n\n    private static async _GenerateDefaultHandMeshesAsync(\n        xrSessionManager: WebXRSessionManager,\n        options?: IWebXRHandTrackingOptions\n    ): Promise<{ left: AbstractMesh; right: AbstractMesh }> {\n        const scene = xrSessionManager.scene;\n        // eslint-disable-next-line no-async-promise-executor\n        return await new Promise(async (resolve) => {\n            const riggedMeshes: { [handedness: string]: AbstractMesh } = {};\n            // check the cache, defensive\n            if (WebXRHandTracking._RightHandGLB?.meshes[1]?.isDisposed()) {\n                WebXRHandTracking._RightHandGLB = null;\n            }\n            if (WebXRHandTracking._LeftHandGLB?.meshes[1]?.isDisposed()) {\n                WebXRHandTracking._LeftHandGLB = null;\n            }\n\n            const handsDefined = !!(WebXRHandTracking._RightHandGLB && WebXRHandTracking._LeftHandGLB);\n            // load them in parallel\n            const defaulrHandGLBUrl = Tools.GetAssetUrl(WebXRHandTracking.DEFAULT_HAND_MODEL_BASE_URL);\n            const handGLBs = await Promise.all([\n                WebXRHandTracking._RightHandGLB || SceneLoader.ImportMeshAsync(\"\", defaulrHandGLBUrl, WebXRHandTracking.DEFAULT_HAND_MODEL_RIGHT_FILENAME, scene),\n                WebXRHandTracking._LeftHandGLB || SceneLoader.ImportMeshAsync(\"\", defaulrHandGLBUrl, WebXRHandTracking.DEFAULT_HAND_MODEL_LEFT_FILENAME, scene),\n            ]);\n            // eslint-disable-next-line require-atomic-updates\n            WebXRHandTracking._RightHandGLB = handGLBs[0];\n            // eslint-disable-next-line require-atomic-updates\n            WebXRHandTracking._LeftHandGLB = handGLBs[1];\n            const shaderUrl = Tools.GetAssetUrl(WebXRHandTracking.DEFAULT_HAND_MODEL_SHADER_URL);\n            const handShader = await NodeMaterialParseFromFileAsync(\"handShader\", shaderUrl, scene, undefined, true);\n\n            // depth prepass and alpha mode\n            handShader.needDepthPrePass = true;\n            handShader.transparencyMode = Material.MATERIAL_ALPHABLEND;\n            handShader.alphaMode = Constants.ALPHA_COMBINE;\n\n            // build node materials\n            handShader.build(false);\n\n            // shader\n            const handColors = {\n                base: Color3.FromInts(116, 63, 203),\n                fresnel: Color3.FromInts(149, 102, 229),\n                fingerColor: Color3.FromInts(177, 130, 255),\n                tipFresnel: Color3.FromInts(220, 200, 255),\n                ...options?.handMeshes?.customColors,\n            };\n\n            const handNodes = {\n                base: handShader.getBlockByName(\"baseColor\") as InputBlock,\n                fresnel: handShader.getBlockByName(\"fresnelColor\") as InputBlock,\n                fingerColor: handShader.getBlockByName(\"fingerColor\") as InputBlock,\n                tipFresnel: handShader.getBlockByName(\"tipFresnelColor\") as InputBlock,\n            };\n\n            handNodes.base.value = handColors.base;\n            handNodes.fresnel.value = handColors.fresnel;\n            handNodes.fingerColor.value = handColors.fingerColor;\n            handNodes.tipFresnel.value = handColors.tipFresnel;\n            const isMultiview = (xrSessionManager._getBaseLayerWrapper() as WebXRCompositionLayerWrapper)?.isMultiview;\n            const hd = [\"left\", \"right\"];\n            for (const handedness of hd) {\n                const handGLB = handedness == \"left\" ? WebXRHandTracking._LeftHandGLB : WebXRHandTracking._RightHandGLB;\n                if (!handGLB) {\n                    // this should never happen!\n                    throw new Error(\"Could not load hand model\");\n                }\n                const handMesh = handGLB.meshes[1];\n                handMesh._internalAbstractMeshDataInfo._computeBonesUsingShaders = true;\n                if (handMesh.skeleton) {\n                    handMesh.skeleton.useTextureToStoreBoneMatrices = false;\n                }\n                // if in multiview do not use the material\n                if (!isMultiview && !options?.handMeshes?.disableHandShader) {\n                    handMesh.material = handShader.clone(`${handedness}HandShaderClone`, true);\n                    handMesh.material.freeze();\n                }\n                handMesh.isVisible = false;\n\n                riggedMeshes[handedness] = handMesh;\n\n                // single change for left handed systems\n                if (!handsDefined && !scene.useRightHandedSystem) {\n                    handGLB.meshes[1].rotate(Axis.Y, Math.PI);\n                }\n            }\n\n            handShader.dispose();\n            resolve({ left: riggedMeshes.left, right: riggedMeshes.right });\n        });\n    }\n\n    /**\n     * Generates a mapping from XRHandJoint to bone name for the default hand mesh.\n     * @param handedness The handedness being mapped for.\n     * @returns A mapping from XRHandJoint to bone name.\n     */\n    private static _GenerateDefaultHandMeshRigMapping(handedness: XRHandedness): XRHandMeshRigMapping {\n        const h = handedness == \"right\" ? \"R\" : \"L\";\n        return {\n            [WebXRHandJoint.WRIST]: `wrist_${h}`,\n            [WebXRHandJoint.THUMB_METACARPAL]: `thumb_metacarpal_${h}`,\n            [WebXRHandJoint.THUMB_PHALANX_PROXIMAL]: `thumb_proxPhalanx_${h}`,\n            [WebXRHandJoint.THUMB_PHALANX_DISTAL]: `thumb_distPhalanx_${h}`,\n            [WebXRHandJoint.THUMB_TIP]: `thumb_tip_${h}`,\n            [WebXRHandJoint.INDEX_FINGER_METACARPAL]: `index_metacarpal_${h}`,\n            [WebXRHandJoint.INDEX_FINGER_PHALANX_PROXIMAL]: `index_proxPhalanx_${h}`,\n            [WebXRHandJoint.INDEX_FINGER_PHALANX_INTERMEDIATE]: `index_intPhalanx_${h}`,\n            [WebXRHandJoint.INDEX_FINGER_PHALANX_DISTAL]: `index_distPhalanx_${h}`,\n            [WebXRHandJoint.INDEX_FINGER_TIP]: `index_tip_${h}`,\n            [WebXRHandJoint.MIDDLE_FINGER_METACARPAL]: `middle_metacarpal_${h}`,\n            [WebXRHandJoint.MIDDLE_FINGER_PHALANX_PROXIMAL]: `middle_proxPhalanx_${h}`,\n            [WebXRHandJoint.MIDDLE_FINGER_PHALANX_INTERMEDIATE]: `middle_intPhalanx_${h}`,\n            [WebXRHandJoint.MIDDLE_FINGER_PHALANX_DISTAL]: `middle_distPhalanx_${h}`,\n            [WebXRHandJoint.MIDDLE_FINGER_TIP]: `middle_tip_${h}`,\n            [WebXRHandJoint.RING_FINGER_METACARPAL]: `ring_metacarpal_${h}`,\n            [WebXRHandJoint.RING_FINGER_PHALANX_PROXIMAL]: `ring_proxPhalanx_${h}`,\n            [WebXRHandJoint.RING_FINGER_PHALANX_INTERMEDIATE]: `ring_intPhalanx_${h}`,\n            [WebXRHandJoint.RING_FINGER_PHALANX_DISTAL]: `ring_distPhalanx_${h}`,\n            [WebXRHandJoint.RING_FINGER_TIP]: `ring_tip_${h}`,\n            [WebXRHandJoint.PINKY_FINGER_METACARPAL]: `little_metacarpal_${h}`,\n            [WebXRHandJoint.PINKY_FINGER_PHALANX_PROXIMAL]: `little_proxPhalanx_${h}`,\n            [WebXRHandJoint.PINKY_FINGER_PHALANX_INTERMEDIATE]: `little_intPhalanx_${h}`,\n            [WebXRHandJoint.PINKY_FINGER_PHALANX_DISTAL]: `little_distPhalanx_${h}`,\n            [WebXRHandJoint.PINKY_FINGER_TIP]: `little_tip_${h}`,\n        };\n    }\n\n    private _attachedHands: {\n        [uniqueId: string]: WebXRHand;\n    } = {};\n\n    private _trackingHands: {\n        left: Nullable<WebXRHand>;\n        right: Nullable<WebXRHand>;\n    } = { left: null, right: null };\n\n    private _handResources: {\n        jointMeshes: Nullable<{ left: AbstractMesh[]; right: AbstractMesh[] }>;\n        handMeshes: Nullable<{ left: AbstractMesh; right: AbstractMesh }>;\n        rigMappings: Nullable<{ left: XRHandMeshRigMapping; right: XRHandMeshRigMapping }>;\n    } = { jointMeshes: null, handMeshes: null, rigMappings: null };\n\n    private _worldScaleObserver?: Nullable<Observer<{ previousScaleFactor: number; newScaleFactor: number }>> = null;\n\n    /**\n     * This observable will notify registered observers when a new hand object was added and initialized\n     */\n    public onHandAddedObservable: Observable<WebXRHand> = new Observable();\n    /**\n     * This observable will notify its observers right before the hand object is disposed\n     */\n    public onHandRemovedObservable: Observable<WebXRHand> = new Observable();\n\n    private _originalMesh?: Mesh;\n\n    /**\n     * Check if the needed objects are defined.\n     * This does not mean that the feature is enabled, but that the objects needed are well defined.\n     * @returns true if the needed objects for this feature are defined\n     */\n    public override isCompatible(): boolean {\n        return typeof XRHand !== \"undefined\";\n    }\n\n    /**\n     * Get the hand object according to the controller id\n     * @param controllerId the controller id to which we want to get the hand\n     * @returns null if not found or the WebXRHand object if found\n     */\n    public getHandByControllerId(controllerId: string): Nullable<WebXRHand> {\n        return this._attachedHands[controllerId];\n    }\n\n    /**\n     * Get a hand object according to the requested handedness\n     * @param handedness the handedness to request\n     * @returns null if not found or the WebXRHand object if found\n     */\n    public getHandByHandedness(handedness: XRHandedness): Nullable<WebXRHand> {\n        if (handedness == \"none\") {\n            return null;\n        }\n        return this._trackingHands[handedness];\n    }\n\n    /**\n     * Creates a new instance of the XR hand tracking feature.\n     * @param _xrSessionManager An instance of WebXRSessionManager.\n     * @param options Options to use when constructing this feature.\n     */\n    constructor(\n        _xrSessionManager: WebXRSessionManager,\n        /** Options to use when constructing this feature. */\n        public readonly options: IWebXRHandTrackingOptions\n    ) {\n        super(_xrSessionManager);\n        this.xrNativeFeatureName = \"hand-tracking\";\n\n        // Support legacy versions of the options object by copying over joint mesh properties\n        const anyOptions = options as any;\n        const anyJointMeshOptions = anyOptions.jointMeshes;\n        if (anyJointMeshOptions) {\n            if (typeof anyJointMeshOptions.disableDefaultHandMesh !== \"undefined\") {\n                options.handMeshes = options.handMeshes || {};\n                options.handMeshes.disableDefaultMeshes = anyJointMeshOptions.disableDefaultHandMesh;\n            }\n            if (typeof anyJointMeshOptions.handMeshes !== \"undefined\") {\n                options.handMeshes = options.handMeshes || {};\n                options.handMeshes.customMeshes = anyJointMeshOptions.handMeshes;\n            }\n            if (typeof anyJointMeshOptions.leftHandedSystemMeshes !== \"undefined\") {\n                options.handMeshes = options.handMeshes || {};\n                options.handMeshes.meshesUseLeftHandedCoordinates = anyJointMeshOptions.leftHandedSystemMeshes;\n            }\n            if (typeof anyJointMeshOptions.rigMapping !== \"undefined\") {\n                options.handMeshes = options.handMeshes || {};\n                const leftRigMapping = {};\n                const rightRigMapping = {};\n                const rigMappingTuples = [\n                    [anyJointMeshOptions.rigMapping.left, leftRigMapping],\n                    [anyJointMeshOptions.rigMapping.right, rightRigMapping],\n                ];\n\n                for (const rigMappingTuple of rigMappingTuples) {\n                    const legacyRigMapping = rigMappingTuple[0] as string[];\n                    const rigMapping = rigMappingTuple[1] as XRHandMeshRigMapping;\n                    for (let index = 0; index < legacyRigMapping.length; index++) {\n                        const modelJointName = legacyRigMapping[index];\n                        rigMapping[HandJointReferenceArray[index]] = modelJointName;\n                    }\n                }\n                options.handMeshes.customRigMappings = {\n                    left: leftRigMapping as XRHandMeshRigMapping,\n                    right: rightRigMapping as XRHandMeshRigMapping,\n                };\n            }\n        }\n    }\n\n    /**\n     * Attach this feature.\n     * Will usually be called by the features manager.\n     *\n     * @returns true if successful.\n     */\n    public override attach(): boolean {\n        if (!super.attach()) {\n            return false;\n        }\n\n        if (!this._handResources.jointMeshes) {\n            this._originalMesh =\n                this._originalMesh || this.options.jointMeshes?.sourceMesh || CreateIcoSphere(\"jointParent\", WebXRHandTracking._ICOSPHERE_PARAMS, this._xrSessionManager.scene);\n            this._originalMesh.isVisible = false;\n\n            this._handResources.jointMeshes = WebXRHandTracking._GenerateTrackedJointMeshes(this.options, this._originalMesh);\n        }\n        this._handResources.handMeshes = this.options.handMeshes?.customMeshes || null;\n        this._handResources.rigMappings = this.options.handMeshes?.customRigMappings || null;\n        // If they didn't supply custom meshes and are not disabling the default meshes...\n        if (!this.options.handMeshes?.customMeshes && !this.options.handMeshes?.disableDefaultMeshes) {\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\n            WebXRHandTracking._GenerateDefaultHandMeshesAsync(this._xrSessionManager, this.options).then((defaultHandMeshes) => {\n                this._handResources.handMeshes = defaultHandMeshes;\n                this._handResources.rigMappings = {\n                    left: WebXRHandTracking._GenerateDefaultHandMeshRigMapping(\"left\"),\n                    right: WebXRHandTracking._GenerateDefaultHandMeshRigMapping(\"right\"),\n                };\n\n                // Apply meshes to existing hands if already tracking.\n                this._trackingHands.left?.setHandMesh(this._handResources.handMeshes.left, this._handResources.rigMappings.left, this._xrSessionManager);\n                this._trackingHands.right?.setHandMesh(this._handResources.handMeshes.right, this._handResources.rigMappings.right, this._xrSessionManager);\n                this._handResources.handMeshes.left.scaling.setAll(this._xrSessionManager.worldScalingFactor);\n                this._handResources.handMeshes.right.scaling.setAll(this._xrSessionManager.worldScalingFactor);\n            });\n            this._worldScaleObserver = this._xrSessionManager.onWorldScaleFactorChangedObservable.add((scalingFactors) => {\n                if (this._handResources.handMeshes) {\n                    this._handResources.handMeshes.left.scaling.scaleInPlace(scalingFactors.newScaleFactor / scalingFactors.previousScaleFactor);\n                    this._handResources.handMeshes.right.scaling.scaleInPlace(scalingFactors.newScaleFactor / scalingFactors.previousScaleFactor);\n                }\n            });\n        }\n\n        for (const controller of this.options.xrInput.controllers) {\n            this._attachHand(controller);\n        }\n\n        this._addNewAttachObserver(this.options.xrInput.onControllerAddedObservable, this._attachHand);\n        this._addNewAttachObserver(this.options.xrInput.onControllerRemovedObservable, this._detachHand);\n\n        return true;\n    }\n\n    protected _onXRFrame(_xrFrame: XRFrame): void {\n        this._trackingHands.left?.updateFromXRFrame(_xrFrame, this._xrSessionManager.referenceSpace, this.options.xrInput.xrCamera);\n        this._trackingHands.right?.updateFromXRFrame(_xrFrame, this._xrSessionManager.referenceSpace, this.options.xrInput.xrCamera);\n    }\n\n    private _attachHand = (xrController: WebXRInputSource) => {\n        if (!xrController.inputSource.hand || xrController.inputSource.handedness == \"none\" || !this._handResources.jointMeshes) {\n            return;\n        }\n\n        const handedness = xrController.inputSource.handedness;\n        const webxrHand = new WebXRHand(\n            xrController,\n            this._handResources.jointMeshes && this._handResources.jointMeshes[handedness],\n            this._handResources.handMeshes && this._handResources.handMeshes[handedness],\n            this._handResources.rigMappings && this._handResources.rigMappings[handedness],\n            this.options.handMeshes?.meshesUseLeftHandedCoordinates,\n            this.options.jointMeshes?.invisible,\n            this.options.jointMeshes?.scaleFactor\n        );\n\n        this._attachedHands[xrController.uniqueId] = webxrHand;\n        this._trackingHands[handedness] = webxrHand;\n\n        this.onHandAddedObservable.notifyObservers(webxrHand);\n    };\n\n    private _detachHandById(controllerId: string, disposeMesh?: boolean) {\n        const hand = this.getHandByControllerId(controllerId);\n        if (hand) {\n            const handedness = hand.xrController.inputSource.handedness == \"left\" ? \"left\" : \"right\";\n            if (this._trackingHands[handedness]?.xrController.uniqueId === controllerId) {\n                this._trackingHands[handedness] = null;\n            }\n            this.onHandRemovedObservable.notifyObservers(hand);\n            hand.dispose(disposeMesh);\n            delete this._attachedHands[controllerId];\n        }\n    }\n\n    private _detachHand = (xrController: WebXRInputSource) => {\n        this._detachHandById(xrController.uniqueId);\n    };\n\n    /**\n     * Detach this feature.\n     * Will usually be called by the features manager.\n     *\n     * @returns true if successful.\n     */\n    public override detach(): boolean {\n        if (!super.detach()) {\n            return false;\n        }\n\n        const keys = Object.keys(this._attachedHands);\n        for (const uniqueId of keys) {\n            this._detachHandById(uniqueId, this.options.handMeshes?.disposeOnSessionEnd);\n        }\n\n        if (this.options.handMeshes?.disposeOnSessionEnd) {\n            if (this._handResources.jointMeshes) {\n                for (const trackedMesh of this._handResources.jointMeshes.left) {\n                    trackedMesh.dispose();\n                }\n                for (const trackedMesh of this._handResources.jointMeshes.right) {\n                    trackedMesh.dispose();\n                }\n                this._handResources.jointMeshes = null;\n            }\n\n            if (this._handResources.handMeshes) {\n                this._handResources.handMeshes.left.dispose();\n                this._handResources.handMeshes.right.dispose();\n                this._handResources.handMeshes = null;\n            }\n\n            if (WebXRHandTracking._RightHandGLB) {\n                for (const mesh of WebXRHandTracking._RightHandGLB.meshes) {\n                    mesh.dispose();\n                }\n            }\n            if (WebXRHandTracking._LeftHandGLB) {\n                for (const mesh of WebXRHandTracking._LeftHandGLB.meshes) {\n                    mesh.dispose();\n                }\n            }\n            WebXRHandTracking._RightHandGLB = null;\n            WebXRHandTracking._LeftHandGLB = null;\n            this._originalMesh?.dispose();\n            this._originalMesh = undefined;\n        }\n\n        // remove world scale observer\n        if (this._worldScaleObserver) {\n            this._xrSessionManager.onWorldScaleFactorChangedObservable.remove(this._worldScaleObserver);\n        }\n\n        return true;\n    }\n\n    /**\n     * Dispose this feature and all of the resources attached.\n     */\n    public override dispose(): void {\n        super.dispose();\n        this.onHandAddedObservable.clear();\n        this.onHandRemovedObservable.clear();\n\n        if (this._handResources.handMeshes && !this.options.handMeshes?.customMeshes) {\n            // this will dispose the cached meshes\n            this._handResources.handMeshes.left.dispose();\n            this._handResources.handMeshes.right.dispose();\n            // remove the cached meshes\n\n            if (WebXRHandTracking._RightHandGLB) {\n                for (const mesh of WebXRHandTracking._RightHandGLB.meshes) {\n                    mesh.dispose();\n                }\n            }\n            if (WebXRHandTracking._LeftHandGLB) {\n                for (const mesh of WebXRHandTracking._LeftHandGLB.meshes) {\n                    mesh.dispose();\n                }\n            }\n            WebXRHandTracking._RightHandGLB = null;\n            WebXRHandTracking._LeftHandGLB = null;\n        }\n\n        if (this._handResources.jointMeshes) {\n            for (const trackedMesh of this._handResources.jointMeshes.left) {\n                trackedMesh.dispose();\n            }\n            for (const trackedMesh of this._handResources.jointMeshes.right) {\n                trackedMesh.dispose();\n            }\n        }\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for webXRHandTracking.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterWebXRHandTracking(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterInstancedMesh();\n\n    //register the plugin\n    WebXRFeaturesManager.AddWebXRFeature(\n        WebXRHandTracking.Name,\n        (xrSessionManager, options) => {\n            return () => new WebXRHandTracking(xrSessionManager, options);\n        },\n        WebXRHandTracking.Version,\n        false\n    );\n}\n","import {\r\n    type IBasePhysicsCollisionEvent,\r\n    type IPhysicsCollisionEvent,\r\n    type IPhysicsEnginePluginV2,\r\n    type PhysicsMassProperties,\r\n    PhysicsMotionType,\r\n    PhysicsPrestepType,\r\n} from \"./IPhysicsEnginePlugin\";\r\nimport { type PhysicsShape } from \"./physicsShape\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type PhysicsEngine } from \"./physicsEngine\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type PhysicsConstraint } from \"./physicsConstraint\";\r\nimport { type Bone } from \"../../Bones/bone\";\r\nimport { Space } from \"../../Maths/math.axis\";\r\nimport { type Observable, type Observer } from \"../../Misc/observable\";\r\nimport { type Node } from \"../../node\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type BoundingBox } from \"../../Culling/boundingBox\";\r\n\r\n/**\r\n * PhysicsBody is useful for creating a physics body that can be used in a physics engine. It allows\r\n * the user to set the mass and velocity of the body, which can then be used to calculate the\r\n * motion of the body in the physics engine.\r\n */\r\nexport class PhysicsBody {\r\n    /**\r\n     * V2 Physics plugin private data for single Transform\r\n     */\r\n    public _pluginData: any = undefined;\r\n    /**\r\n     * V2 Physics plugin private data for instances\r\n     */\r\n    public _pluginDataInstances: Array<any> = [];\r\n    /**\r\n     * The V2 plugin used to create and manage this Physics Body\r\n     */\r\n    private _physicsPlugin: IPhysicsEnginePluginV2;\r\n    /**\r\n     * The engine used to create and manage this Physics Body\r\n     */\r\n    private _physicsEngine: PhysicsEngine;\r\n    /**\r\n     * If the collision callback is enabled\r\n     */\r\n    private _collisionCBEnabled: boolean = false;\r\n    /**\r\n     * If the collision ended callback is enabled\r\n     */\r\n    private _collisionEndedCBEnabled: boolean = false;\r\n    /**\r\n     * The transform node associated with this Physics Body\r\n     */\r\n    transformNode: TransformNode;\r\n\r\n    /**\r\n     * Disable pre-step that consists in updating Physics Body from Transform Node Translation/Orientation.\r\n     * True by default for maximum performance.\r\n     */\r\n    public get disablePreStep(): boolean {\r\n        return this._prestepType == PhysicsPrestepType.DISABLED;\r\n    }\r\n\r\n    public set disablePreStep(value: boolean) {\r\n        this._prestepType = value ? PhysicsPrestepType.DISABLED : PhysicsPrestepType.TELEPORT;\r\n    }\r\n\r\n    /**\r\n     * Disable sync from physics to transformNode. This value is set to true at body creation or at motionType setting when the body is not dynamic.\r\n     */\r\n    disableSync: boolean = false;\r\n\r\n    /**\r\n     * Physics engine will try to make this body sleeping and not active\r\n     */\r\n    public startAsleep: boolean;\r\n\r\n    private _nodeDisposeObserver: Nullable<Observer<Node>>;\r\n\r\n    private _isDisposed = false;\r\n\r\n    private _shape: Nullable<PhysicsShape> = null;\r\n\r\n    private _prestepType: PhysicsPrestepType = PhysicsPrestepType.DISABLED;\r\n    /**\r\n     * Constructs a new physics body for the given node.\r\n     * @param transformNode - The Transform Node to construct the physics body for. For better performance, it is advised that this node does not have a parent.\r\n     * @param motionType - The motion type of the physics body. The options are:\r\n     *  - PhysicsMotionType.STATIC - Static bodies are not moving and unaffected by forces or collisions. They are good for level boundaries or terrain.\r\n     *  - PhysicsMotionType.DYNAMIC - Dynamic bodies are fully simulated. They can move and collide with other objects.\r\n     *  - PhysicsMotionType.ANIMATED - They behave like dynamic bodies, but they won't be affected by other bodies, but still push other bodies out of the way.\r\n     * @param startsAsleep - Whether the physics body should start in a sleeping state (not a guarantee). Defaults to false.\r\n     * @param scene - The scene containing the physics engine.\r\n     *\r\n     * This code is useful for creating a physics body for a given Transform Node in a scene.\r\n     * It checks the version of the physics engine and the physics plugin, and initializes the body accordingly.\r\n     * It also sets the node's rotation quaternion if it is not already set. Finally, it adds the body to the physics engine.\r\n     */\r\n    constructor(transformNode: TransformNode, motionType: PhysicsMotionType, startsAsleep: boolean, scene: Scene) {\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        const physicsEngine = scene.getPhysicsEngine() as PhysicsEngine;\r\n        if (!physicsEngine) {\r\n            throw new Error(\"No Physics Engine available.\");\r\n        }\r\n        this._physicsEngine = physicsEngine;\r\n        if (physicsEngine.getPluginVersion() != 2) {\r\n            throw new Error(\"Plugin version is incorrect. Expected version 2.\");\r\n        }\r\n        const physicsPlugin = physicsEngine.getPhysicsPlugin();\r\n        if (!physicsPlugin) {\r\n            throw new Error(\"No Physics Plugin available.\");\r\n        }\r\n\r\n        this._physicsPlugin = physicsPlugin;\r\n        if (!transformNode.rotationQuaternion) {\r\n            transformNode.rotationQuaternion = Quaternion.FromEulerAngles(transformNode.rotation.x, transformNode.rotation.y, transformNode.rotation.z);\r\n        }\r\n\r\n        this.startAsleep = startsAsleep;\r\n\r\n        // only dynamic and animated body needs sync from physics to transformNode\r\n        this.disableSync = motionType == PhysicsMotionType.STATIC;\r\n\r\n        // instances?\r\n        const m = transformNode as Mesh;\r\n        if (m.hasThinInstances) {\r\n            this._physicsPlugin.initBodyInstances(this, motionType, m);\r\n        } else {\r\n            // single instance\r\n            if (transformNode.parent) {\r\n                // Force computation of world matrix so that the parent transforms are correctly reflected in absolutePosition/absoluteRotationQuaternion.\r\n                transformNode.computeWorldMatrix(true);\r\n            }\r\n            this._physicsPlugin.initBody(this, motionType, transformNode.absolutePosition, transformNode.absoluteRotationQuaternion);\r\n        }\r\n        this.transformNode = transformNode;\r\n        transformNode.physicsBody = this;\r\n        physicsEngine.addBody(this);\r\n\r\n        this._nodeDisposeObserver = transformNode.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"PhysicsBody\".\r\n     * @returns \"PhysicsBody\"\r\n     */\r\n    public getClassName() {\r\n        return \"PhysicsBody\";\r\n    }\r\n\r\n    /**\r\n     * Clone the PhysicsBody to a new body and assign it to the transformNode parameter\r\n     * @param transformNode transformNode that will be used for the cloned PhysicsBody\r\n     * @returns the newly cloned PhysicsBody\r\n     */\r\n    public clone(transformNode: TransformNode): PhysicsBody {\r\n        const clonedBody = new PhysicsBody(transformNode, this.getMotionType(), this.startAsleep, this.transformNode.getScene());\r\n        clonedBody.shape = this.shape;\r\n        clonedBody.setMassProperties(this.getMassProperties());\r\n        clonedBody.setLinearDamping(this.getLinearDamping());\r\n        clonedBody.setAngularDamping(this.getAngularDamping());\r\n        return clonedBody;\r\n    }\r\n\r\n    /**\r\n     * If a physics body is connected to an instanced node, update the number physic instances to match the number of node instances.\r\n     */\r\n    public updateBodyInstances() {\r\n        const m = this.transformNode as Mesh;\r\n        if (m.hasThinInstances) {\r\n            this._physicsPlugin.updateBodyInstances(this, m);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This returns the number of internal instances of the physics body\r\n     */\r\n    public get numInstances(): number {\r\n        return this._pluginDataInstances.length;\r\n    }\r\n\r\n    /**\r\n     * Get the motion type of the physics body. Can be STATIC, DYNAMIC, or ANIMATED.\r\n     */\r\n    public get motionType(): PhysicsMotionType {\r\n        return this._physicsPlugin.getMotionType(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the shape of the physics body.\r\n     * @param shape - The shape of the physics body.\r\n     *\r\n     * This method is useful for setting the shape of the physics body, which is necessary for the physics engine to accurately simulate the body's behavior.\r\n     * The shape is used to calculate the body's mass, inertia, and other properties.\r\n     */\r\n    public set shape(shape: Nullable<PhysicsShape>) {\r\n        this._shape = shape;\r\n        if (shape) {\r\n            this._physicsPlugin.setShape(this, shape);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Retrieves the physics shape associated with this object.\r\n     *\r\n     * @returns The physics shape associated with this object, or `undefined` if no\r\n     * shape is associated.\r\n     *\r\n     * This method is useful for retrieving the physics shape associated with this object,\r\n     * which can be used to apply physical forces to the object or to detect collisions.\r\n     */\r\n    public get shape(): Nullable<PhysicsShape> {\r\n        return this._shape;\r\n    }\r\n\r\n    /**\r\n     * Returns the bounding box of the physics body.\r\n     * @returns The bounding box of the physics body.\r\n     */\r\n    public getBoundingBox(): BoundingBox {\r\n        return this._physicsPlugin.getBodyBoundingBox(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the event mask for the physics engine.\r\n     *\r\n     * @param eventMask - A bitmask that determines which events will be sent to the physics engine.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to set the event mask for.\r\n     *\r\n     * This method is useful for setting the event mask for the physics engine, which determines which events\r\n     * will be sent to the physics engine. This allows the user to control which events the physics engine will respond to.\r\n     */\r\n    public setEventMask(eventMask: number, instanceIndex?: number) {\r\n        this._physicsPlugin.setEventMask(this, eventMask, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the event mask of the physics engine.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the event mask for.\r\n     * @returns The event mask of the physics engine.\r\n     *\r\n     * This method is useful for getting the event mask of the physics engine,\r\n     * which is used to determine which events the engine will respond to.\r\n     * This is important for ensuring that the engine is responding to the correct events and not\r\n     * wasting resources on unnecessary events.\r\n     */\r\n    public getEventMask(instanceIndex?: number): number {\r\n        return this._physicsPlugin.getEventMask(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the motion type of the physics body. Can be STATIC, DYNAMIC, or ANIMATED.\r\n     * @param motionType - The motion type to set.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to set the motion type for. If body is instanced but instanceIndex is undefined, the motion type will be set for all instances.\r\n     */\r\n    public setMotionType(motionType: PhysicsMotionType, instanceIndex?: number) {\r\n        this.disableSync = instanceIndex === undefined && motionType == PhysicsMotionType.STATIC;\r\n        this._physicsPlugin.setMotionType(this, motionType, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the motion type of the physics body. Can be STATIC, DYNAMIC, or ANIMATED.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the motion type for.\r\n     * @returns The motion type of the physics body.\r\n     */\r\n    public getMotionType(instanceIndex?: number): PhysicsMotionType {\r\n        return this._physicsPlugin.getMotionType(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Set the prestep type of the body\r\n     * @param prestepType prestep type provided by PhysicsPrestepType\r\n     */\r\n    public setPrestepType(prestepType: PhysicsPrestepType): void {\r\n        this._prestepType = prestepType;\r\n    }\r\n\r\n    /**\r\n     * Get the current prestep type of the body\r\n     * @returns the type of prestep associated with the body and its instance index\r\n     */\r\n    public getPrestepType(): PhysicsPrestepType {\r\n        return this._prestepType;\r\n    }\r\n\r\n    /**\r\n     * Computes the mass properties of the physics object, based on the set of physics shapes this body uses.\r\n     * This method is useful for computing the initial mass properties of a physics object, such as its mass,\r\n     * inertia, and center of mass; these values are important for accurately simulating the physics of the\r\n     * object in the physics engine, and computing values based on the shape will provide you with reasonable\r\n     * initial values, which you can then customize.\r\n     * @param instanceIndex - The index of the instance to compute the mass properties for.\r\n     * @returns The mass properties of the object.\r\n     */\r\n    public computeMassProperties(instanceIndex?: number): PhysicsMassProperties {\r\n        return this._physicsPlugin.computeMassProperties(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the mass properties of the physics object.\r\n     *\r\n     * @param massProps - The mass properties to set.\r\n     * @param instanceIndex - The index of the instance to set the mass properties for. If not defined, the mass properties will be set for all instances.\r\n     *\r\n     * This method is useful for setting the mass properties of a physics object, such as its mass,\r\n     * inertia, and center of mass. This is important for accurately simulating the physics of the object in the physics engine.\r\n     */\r\n    public setMassProperties(massProps: PhysicsMassProperties, instanceIndex?: number): void {\r\n        this._physicsPlugin.setMassProperties(this, massProps, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Retrieves the mass properties of the object.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the mass properties for.\r\n     * @returns The mass properties of the object.\r\n     *\r\n     * This method is useful for physics simulations, as it allows the user to\r\n     * retrieve the mass properties of the object, such as its mass, center of mass,\r\n     * and moment of inertia. This information is necessary for accurate physics\r\n     * simulations.\r\n     */\r\n    public getMassProperties(instanceIndex?: number): PhysicsMassProperties {\r\n        return this._physicsPlugin.getMassProperties(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the linear damping of the physics body.\r\n     *\r\n     * @param damping - The linear damping value.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to set the linear damping for.\r\n     *\r\n     * This method is useful for controlling the linear damping of the physics body,\r\n     * which is the rate at which the body's velocity decreases over time. This is useful for simulating\r\n     * the effects of air resistance or other forms of friction.\r\n     */\r\n    public setLinearDamping(damping: number, instanceIndex?: number) {\r\n        this._physicsPlugin.setLinearDamping(this, damping, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the linear damping of the physics body.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the linear damping for.\r\n     * @returns The linear damping of the physics body.\r\n     *\r\n     * This method is useful for retrieving the linear damping of the physics body, which is the amount of\r\n     * resistance the body has to linear motion. This is useful for simulating realistic physics behavior\r\n     * in a game.\r\n     */\r\n    public getLinearDamping(instanceIndex?: number): number {\r\n        return this._physicsPlugin.getLinearDamping(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the angular damping of the physics body.\r\n     * @param damping The angular damping of the body.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to set the angular damping for.\r\n     *\r\n     * This method is useful for controlling the angular velocity of a physics body.\r\n     * By setting the damping, the body's angular velocity will be reduced over time, simulating the effect of friction.\r\n     * This can be used to create realistic physical behavior in a physics engine.\r\n     */\r\n    public setAngularDamping(damping: number, instanceIndex?: number) {\r\n        this._physicsPlugin.setAngularDamping(this, damping, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the angular damping of the physics body.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the angular damping for.\r\n     *\r\n     * @returns The angular damping of the physics body.\r\n     *\r\n     * This method is useful for getting the angular damping of the physics body,\r\n     * which is the rate of reduction of the angular velocity over time.\r\n     * This is important for simulating realistic physics behavior in a game.\r\n     */\r\n    public getAngularDamping(instanceIndex?: number): number {\r\n        return this._physicsPlugin.getAngularDamping(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the linear velocity of the physics object.\r\n     * @param linVel - The linear velocity to set.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to set the linear velocity for.\r\n     *\r\n     * This method is useful for setting the linear velocity of a physics object,\r\n     * which is necessary for simulating realistic physics in a game engine.\r\n     * By setting the linear velocity, the physics object will move in the direction and speed specified by the vector.\r\n     * This allows for realistic physics simulations, such as simulating the motion of a ball rolling down a hill.\r\n     */\r\n    public setLinearVelocity(linVel: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.setLinearVelocity(this, linVel, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the linear velocity of the physics body and stores it in the given vector3.\r\n     * @param linVel - The vector3 to store the linear velocity in.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the linear velocity for.\r\n     *\r\n     * This method is useful for getting the linear velocity of a physics body in a physics engine.\r\n     * This can be used to determine the speed and direction of the body, which can be used to calculate the motion of the body.\r\n     */\r\n    public getLinearVelocityToRef(linVel: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.getLinearVelocityToRef(this, linVel, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the linear velocity of the physics body as a new vector3.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the linear velocity for.\r\n     * @returns The linear velocity of the physics body.\r\n     *\r\n     * This method is useful for getting the linear velocity of a physics body in a physics engine.\r\n     * This can be used to determine the speed and direction of the body, which can be used to calculate the motion of the body.\r\n     */\r\n    public getLinearVelocity(instanceIndex?: number): Vector3 {\r\n        const ref = new Vector3();\r\n        this.getLinearVelocityToRef(ref, instanceIndex);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Sets the angular velocity of the physics object.\r\n     * @param angVel - The angular velocity to set.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to set the angular velocity for.\r\n     *\r\n     * This method is useful for setting the angular velocity of a physics object, which is necessary for\r\n     * simulating realistic physics behavior. The angular velocity is used to determine the rate of rotation of the object,\r\n     * which is important for simulating realistic motion.\r\n     */\r\n    public setAngularVelocity(angVel: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.setAngularVelocity(this, angVel, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the angular velocity of the physics body and stores it in the given vector3.\r\n     * @param angVel - The vector3 to store the angular velocity in.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the angular velocity for.\r\n     *\r\n     * This method is useful for getting the angular velocity of a physics body, which can be used to determine the body's\r\n     * rotational speed. This information can be used to create realistic physics simulations.\r\n     */\r\n    public getAngularVelocityToRef(angVel: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.getAngularVelocityToRef(this, angVel, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the angular velocity of the physics body as a new vector3.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the angular velocity for.\r\n     * @returns The angular velocity of the physics body.\r\n     *\r\n     * This method is useful for getting the angular velocity of a physics body, which can be used to determine the body's\r\n     * rotational speed. This information can be used to create realistic physics simulations.\r\n     */\r\n    public getAngularVelocity(instanceIndex?: number): Vector3 {\r\n        const ref = new Vector3();\r\n        this.getAngularVelocityToRef(ref, instanceIndex);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Applies an impulse to the physics object.\r\n     *\r\n     * @param impulse The impulse vector.\r\n     * @param location The location of the impulse.\r\n     * @param instanceIndex For a instanced body, the instance to where the impulse should be applied. If not specified, the impulse is applied to all instances.\r\n     *\r\n     * This method is useful for applying an impulse to a physics object, which can be used to simulate physical forces such as gravity,\r\n     * collisions, and explosions. This can be used to create realistic physics simulations in a game or other application.\r\n     */\r\n    public applyImpulse(impulse: Vector3, location: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.applyImpulse(this, impulse, location, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Add torque to a physics body\r\n     * @param angularImpulse The angular impulse vector.\r\n     * @param instanceIndex For a instanced body, the instance to where the impulse should be applied. If not specified, the impulse is applied to all instances.\r\n     */\r\n    public applyAngularImpulse(angularImpulse: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.applyAngularImpulse(this, angularImpulse, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Applies a torque to the physics body.\r\n     *\r\n     * @param torque The torque vector.\r\n     * @param instanceIndex For a instanced body, the instance to where the torque should be applied. If not specified, the torque is applied to all instances.\r\n     *\r\n     * This method is useful for applying a torque to a physics body, which can be used to simulate rotational forces such as motors,\r\n     * angular momentum, and rotational dynamics. This can be used to create realistic physics simulations in a game or other application.\r\n     */\r\n    public applyTorque(torque: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.applyTorque(this, torque, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Applies a force to the physics object.\r\n     *\r\n     * @param force The force vector.\r\n     * @param location The location of the force.\r\n     * @param instanceIndex For a instanced body, the instance to where the force should be applied. If not specified, the force is applied to all instances.\r\n     *\r\n     * This method is useful for applying a force to a physics object, which can be used to simulate physical forces such as gravity,\r\n     * collisions, and explosions. This can be used to create realistic physics simulations in a game or other application.\r\n     */\r\n    public applyForce(force: Vector3, location: Vector3, instanceIndex?: number): void {\r\n        this._physicsPlugin.applyForce(this, force, location, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Retrieves the geometry of the body from the physics plugin.\r\n     *\r\n     * @returns The geometry of the body.\r\n     *\r\n     * This method is useful for retrieving the geometry of the body from the physics plugin, which can be used for various physics calculations.\r\n     */\r\n    public getGeometry(): object {\r\n        return this._physicsPlugin.getBodyGeometry(this);\r\n    }\r\n\r\n    /**\r\n     * Returns an observable that will be notified for when a collision starts or continues for this PhysicsBody\r\n     * @param instanceIndex - optionally, the index of the instance in the body\r\n     * @returns Observable\r\n     */\r\n    public getCollisionObservable(instanceIndex?: number): Observable<IPhysicsCollisionEvent> {\r\n        return this._physicsPlugin.getCollisionObservable(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Returns an observable that will be notified when the body has finished colliding with another body\r\n     * @param instanceIndex - optionally, the index of the instance in the body\r\n     * @returns Observable\r\n     */\r\n    public getCollisionEndedObservable(instanceIndex?: number): Observable<IBasePhysicsCollisionEvent> {\r\n        return this._physicsPlugin.getCollisionEndedObservable(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Enable or disable collision callback for this PhysicsBody.\r\n     * @param enabled true if PhysicsBody's collision will rise a collision event and notifies the observable\r\n     */\r\n    public setCollisionCallbackEnabled(enabled: boolean): void {\r\n        this._collisionCBEnabled = enabled;\r\n        this._physicsPlugin.setCollisionCallbackEnabled(this, enabled);\r\n    }\r\n\r\n    /**\r\n     * Enable or disable collision ended callback for this PhysicsBody.\r\n     * @param enabled true if PhysicsBody's collision ended will rise a collision event and notifies the observable\r\n     */\r\n    public setCollisionEndedCallbackEnabled(enabled: boolean): void {\r\n        this._collisionEndedCBEnabled = enabled;\r\n        this._physicsPlugin.setCollisionEndedCallbackEnabled(this, enabled);\r\n    }\r\n\r\n    /**\r\n     * Get the center of the object in world space.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the center for.\r\n     * @returns geometric center of the associated mesh\r\n     */\r\n    public getObjectCenterWorld(instanceIndex?: number): Vector3 {\r\n        const ref = new Vector3();\r\n        return this.getObjectCenterWorldToRef(ref, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Get the center of the object in world space.\r\n     * @param ref - The vector3 to store the result in.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to get the center for.\r\n     * @returns geometric center of the associated mesh\r\n     */\r\n    public getObjectCenterWorldToRef(ref: Vector3, instanceIndex?: number): Vector3 {\r\n        if (this._pluginDataInstances?.length > 0) {\r\n            const index = instanceIndex || 0;\r\n            const matrixData = (this.transformNode as Mesh)._thinInstanceDataStorage.matrixData;\r\n            if (matrixData) {\r\n                ref.set(matrixData[index * 16 + 12], matrixData[index * 16 + 13], matrixData[index * 16 + 14]);\r\n            }\r\n        } else {\r\n            ref.copyFrom(this.transformNode.position);\r\n        }\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Adds a constraint to the physics engine.\r\n     *\r\n     * @param childBody - The body to which the constraint will be applied.\r\n     * @param constraint - The constraint to be applied.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to which the constraint will be applied. If not specified, no constraint will be applied.\r\n     * @param childInstanceIndex - If the child body is instanced, the index of the instance to which the constraint will be applied. If not specified, no constraint will be applied.\r\n     *\r\n     */\r\n    public addConstraint(childBody: PhysicsBody, constraint: PhysicsConstraint, instanceIndex?: number, childInstanceIndex?: number): void {\r\n        this._physicsPlugin.addConstraint(this, childBody, constraint, instanceIndex, childInstanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sync with a bone\r\n     * @param bone The bone that the impostor will be synced to.\r\n     * @param boneMesh The mesh that the bone is influencing.\r\n     * @param jointPivot The pivot of the joint / bone in local space.\r\n     * @param distToJoint Optional distance from the impostor to the joint.\r\n     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.\r\n     * @param boneAxis Optional vector3 axis the bone is aligned with\r\n     */\r\n    public syncWithBone(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion, boneAxis?: Vector3) {\r\n        const mesh = this.transformNode;\r\n\r\n        if (mesh.rotationQuaternion) {\r\n            if (adjustRotation) {\r\n                const tempQuat = TmpVectors.Quaternion[0];\r\n                bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, tempQuat);\r\n                tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);\r\n            } else {\r\n                bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, mesh.rotationQuaternion);\r\n            }\r\n        }\r\n\r\n        const pos = TmpVectors.Vector3[0];\r\n        const boneDir = TmpVectors.Vector3[1];\r\n\r\n        if (!boneAxis) {\r\n            boneAxis = TmpVectors.Vector3[2];\r\n            boneAxis.x = 0;\r\n            boneAxis.y = 1;\r\n            boneAxis.z = 0;\r\n        }\r\n\r\n        bone.getDirectionToRef(boneAxis, boneMesh, boneDir);\r\n        bone.getAbsolutePositionToRef(boneMesh, pos);\r\n\r\n        if ((distToJoint === undefined || distToJoint === null) && jointPivot) {\r\n            distToJoint = jointPivot.length();\r\n        }\r\n\r\n        if (distToJoint !== undefined && distToJoint !== null) {\r\n            pos.x += boneDir.x * distToJoint;\r\n            pos.y += boneDir.y * distToJoint;\r\n            pos.z += boneDir.z * distToJoint;\r\n        }\r\n\r\n        mesh.setAbsolutePosition(pos);\r\n    }\r\n\r\n    /**\r\n     * Executes a callback on the body or all of the instances of a body\r\n     * @param callback the callback to execute\r\n     */\r\n    public iterateOverAllInstances(callback: (body: PhysicsBody, instanceIndex?: number) => void) {\r\n        if (this._pluginDataInstances?.length > 0) {\r\n            for (let i = 0; i < this._pluginDataInstances.length; i++) {\r\n                callback(this, i);\r\n            }\r\n        } else {\r\n            callback(this, undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the gravity factor of the physics body\r\n     * @param factor the gravity factor to set\r\n     * @param instanceIndex the instance of the body to set, if undefined all instances will be set\r\n     */\r\n    public setGravityFactor(factor: number, instanceIndex?: number) {\r\n        this._physicsPlugin.setGravityFactor(this, factor, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Gets the gravity factor of the physics body\r\n     * @param instanceIndex the instance of the body to get, if undefined the value of first instance will be returned\r\n     * @returns the gravity factor\r\n     */\r\n    public getGravityFactor(instanceIndex?: number): number {\r\n        return this._physicsPlugin.getGravityFactor(this, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Set the target transformation (position and rotation) of the body, such that the body will set its velocity to reach that target\r\n     * @param position The target position\r\n     * @param rotation The target rotation\r\n     * @param instanceIndex The index of the instance in an instanced body\r\n     */\r\n    public setTargetTransform(position: Vector3, rotation: Quaternion, instanceIndex?: number) {\r\n        this._physicsPlugin.setTargetTransform(this, position, rotation, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Returns if the body has been disposed.\r\n     * @returns true if disposed, false otherwise.\r\n     */\r\n    public get isDisposed() {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    /**\r\n     * Disposes the body from the physics engine.\r\n     *\r\n     * This method is useful for cleaning up the physics engine when a body is no longer needed. Disposing the body will free up resources and prevent memory leaks.\r\n     */\r\n    public dispose() {\r\n        if (this._isDisposed) {\r\n            return;\r\n        }\r\n        // Disable collisions CB so it doesn't fire when the body is disposed\r\n        if (this._collisionCBEnabled) {\r\n            this.setCollisionCallbackEnabled(false);\r\n        }\r\n        if (this._collisionEndedCBEnabled) {\r\n            this.setCollisionEndedCallbackEnabled(false);\r\n        }\r\n        if (this._nodeDisposeObserver) {\r\n            this.transformNode.onDisposeObservable.remove(this._nodeDisposeObserver);\r\n            this._nodeDisposeObserver = null;\r\n        }\r\n        this._physicsEngine.removeBody(this);\r\n        this._physicsPlugin.removeBody(this);\r\n        this._physicsPlugin.disposeBody(this);\r\n        this.transformNode.physicsBody = null;\r\n        this._pluginData = null;\r\n        this._pluginDataInstances.length = 0;\r\n        this._isDisposed = true;\r\n        this.shape = null;\r\n    }\r\n}\r\n","import { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { type BoundingBox } from \"../../Culling/boundingBox\";\r\nimport { PhysicsShapeType, type IPhysicsEnginePluginV2, type PhysicsShapeParameters } from \"./IPhysicsEnginePlugin\";\r\nimport { type PhysicsMaterial } from \"./physicsMaterial\";\r\nimport { Matrix, Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type GroundMesh } from \"../../Meshes/groundMesh\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Scene } from \"../../scene\";\r\n\r\n/**\r\n * Options for creating a physics shape\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicShapeOptions {\r\n    /**\r\n     * The type of the shape. This can be one of the following: SPHERE, BOX, CAPSULE, CYLINDER, CONVEX_HULL, MESH, HEIGHTFIELD, CONTAINER\r\n     */\r\n    type?: PhysicsShapeType;\r\n    /**\r\n     * The parameters of the shape. Varies depending of the shape type.\r\n     */\r\n    parameters?: PhysicsShapeParameters;\r\n    /**\r\n     * Reference to an already existing physics shape in the plugin.\r\n     */\r\n    pluginData?: any;\r\n}\r\n\r\n/**\r\n * PhysicsShape class.\r\n * This class is useful for creating a physics shape that can be used in a physics engine.\r\n * A Physic Shape determine how collision are computed. It must be attached to a body.\r\n */\r\nexport class PhysicsShape {\r\n    /**\r\n     * V2 Physics plugin private data for single shape\r\n     */\r\n    public _pluginData: any = undefined;\r\n    /**\r\n     * The V2 plugin used to create and manage this Physics Body\r\n     */\r\n    private _physicsPlugin: IPhysicsEnginePluginV2;\r\n\r\n    private _type: PhysicsShapeType;\r\n\r\n    private _material: PhysicsMaterial;\r\n\r\n    private _isTrigger: boolean = false;\r\n\r\n    private _isDisposed = false;\r\n\r\n    /**\r\n     * Constructs a new physics shape.\r\n     * @param options The options for the physics shape. These are:\r\n     *  * type: The type of the shape. This can be one of the following: SPHERE, BOX, CAPSULE, CYLINDER, CONVEX_HULL, MESH, HEIGHTFIELD, CONTAINER\r\n     *  * parameters: The parameters of the shape.\r\n     *  * pluginData: The plugin data of the shape. This is used if you already have a reference to the object on the plugin side.\r\n     * You need to specify either type or pluginData.\r\n     * @param scene The scene the shape belongs to.\r\n     *\r\n     * This code is useful for creating a new physics shape with the given type, options, and scene.\r\n     * It also checks that the physics engine and plugin version are correct.\r\n     * If not, it throws an error. This ensures that the shape is created with the correct parameters and is compatible with the physics engine.\r\n     */\r\n    constructor(options: PhysicShapeOptions, scene: Scene) {\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        const physicsEngine = scene.getPhysicsEngine();\r\n        if (!physicsEngine) {\r\n            throw new Error(\"No Physics Engine available.\");\r\n        }\r\n        if (physicsEngine.getPluginVersion() != 2) {\r\n            throw new Error(\"Plugin version is incorrect. Expected version 2.\");\r\n        }\r\n        const physicsPlugin = physicsEngine.getPhysicsPlugin();\r\n        if (!physicsPlugin) {\r\n            throw new Error(\"No Physics Plugin available.\");\r\n        }\r\n        this._physicsPlugin = physicsPlugin as IPhysicsEnginePluginV2;\r\n\r\n        if (options.pluginData !== undefined && options.pluginData !== null) {\r\n            this._pluginData = options.pluginData;\r\n            this._type = this._physicsPlugin.getShapeType(this);\r\n        } else if (options.type !== undefined && options.type !== null) {\r\n            this._type = options.type;\r\n            const parameters = options.parameters ?? {};\r\n            this._physicsPlugin.initShape(this, options.type, parameters);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"PhysicsShape\".\r\n     * @returns \"PhysicsShape\"\r\n     */\r\n    public getClassName() {\r\n        return \"PhysicsShape\";\r\n    }\r\n\r\n    /**\r\n     * Returns the type of the physics shape.\r\n     * @returns The type of the physics shape.\r\n     */\r\n    public get type(): PhysicsShapeType {\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Set the membership mask of a shape. This is a bitfield of arbitrary\r\n     * \"categories\" to which the shape is a member. This is used in combination\r\n     * with the collide mask to determine if this shape should collide with\r\n     * another.\r\n     *\r\n     * @param membershipMask Bitfield of categories of this shape.\r\n     */\r\n    public set filterMembershipMask(membershipMask: number) {\r\n        this._physicsPlugin.setShapeFilterMembershipMask(this, membershipMask);\r\n    }\r\n\r\n    /**\r\n     * Get the membership mask of a shape.\r\n     * @returns Bitmask of categories which this shape is a member of.\r\n     */\r\n    public get filterMembershipMask(): number {\r\n        return this._physicsPlugin.getShapeFilterMembershipMask(this);\r\n    }\r\n\r\n    /**\r\n     * Sets the collide mask of a shape. This is a bitfield of arbitrary\r\n     * \"categories\" to which this shape collides with. Given two shapes,\r\n     * the engine will check if the collide mask and membership overlap:\r\n     * shapeA.filterMembershipMask & shapeB.filterCollideMask\r\n     *\r\n     * If this value is zero (i.e. shapeB only collides with categories\r\n     * which shapeA is _not_ a member of) then the shapes will not collide.\r\n     *\r\n     * Note, the engine will also perform the same test with shapeA and\r\n     * shapeB swapped; the shapes will not collide if either shape has\r\n     * a collideMask which prevents collision with the other shape.\r\n     *\r\n     * @param collideMask Bitmask of categories this shape should collide with\r\n     */\r\n    public set filterCollideMask(collideMask: number) {\r\n        this._physicsPlugin.setShapeFilterCollideMask(this, collideMask);\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @returns Bitmask of categories that this shape should collide with\r\n     */\r\n    public get filterCollideMask(): number {\r\n        return this._physicsPlugin.getShapeFilterCollideMask(this);\r\n    }\r\n    /**\r\n     *\r\n     * @param material\r\n     */\r\n    public set material(material: PhysicsMaterial) {\r\n        this._physicsPlugin.setMaterial(this, material);\r\n        this._material = material;\r\n    }\r\n\r\n    /**\r\n     * Returns the material of the physics shape.\r\n     * @returns The material of the physics shape.\r\n     */\r\n    public get material(): PhysicsMaterial {\r\n        if (!this._material) {\r\n            this._material = this._physicsPlugin.getMaterial(this);\r\n        }\r\n        return this._material;\r\n    }\r\n\r\n    /**\r\n     * Sets the density of the physics shape.\r\n     * @param density The density of the physics shape.\r\n     */\r\n    public set density(density: number) {\r\n        this._physicsPlugin.setDensity(this, density);\r\n    }\r\n\r\n    /**\r\n     * Returns the density of the physics shape.\r\n     * @returns The density of the physics shape.\r\n     */\r\n    public get density(): number {\r\n        return this._physicsPlugin.getDensity(this);\r\n    }\r\n\r\n    /**\r\n     * Utility to add a child shape to this container,\r\n     * automatically computing the relative transform between\r\n     * the container shape and the child instance.\r\n     *\r\n     * @param parentTransform The transform node associated with this shape\r\n     * @param newChild The new PhysicsShape to add\r\n     * @param childTransform The transform node associated with the child shape\r\n     */\r\n    public addChildFromParent(parentTransform: TransformNode, newChild: PhysicsShape, childTransform: TransformNode): void {\r\n        const childToWorld = childTransform.computeWorldMatrix(true);\r\n        const parentToWorld = parentTransform.computeWorldMatrix(true);\r\n        const childToParent = TmpVectors.Matrix[0];\r\n        childToWorld.multiplyToRef(Matrix.Invert(parentToWorld), childToParent);\r\n        const translation = TmpVectors.Vector3[0];\r\n        const rotation = TmpVectors.Quaternion[0];\r\n        const scale = TmpVectors.Vector3[1];\r\n        childToParent.decompose(scale, rotation, translation);\r\n        this._physicsPlugin.addChild(this, newChild, translation, rotation, scale);\r\n    }\r\n\r\n    /**\r\n     * Adds a child shape to a container with an optional transform\r\n     * @param newChild The new PhysicsShape to add\r\n     * @param translation Optional position of the child shape relative to this shape\r\n     * @param rotation Optional rotation of the child shape relative to this shape\r\n     * @param scale Optional scale of the child shape relative to this shape\r\n     */\r\n    public addChild(newChild: PhysicsShape, translation?: Vector3, rotation?: Quaternion, scale?: Vector3): void {\r\n        this._physicsPlugin.addChild(this, newChild, translation, rotation, scale);\r\n    }\r\n\r\n    /**\r\n     * Removes a child shape from this shape.\r\n     * @param childIndex The index of the child shape to remove\r\n     */\r\n    public removeChild(childIndex: number): void {\r\n        this._physicsPlugin.removeChild(this, childIndex);\r\n    }\r\n\r\n    /**\r\n     * Returns the number of children of a physics shape.\r\n     * @returns The number of children of a physics shape.\r\n     */\r\n    public getNumChildren(): number {\r\n        return this._physicsPlugin.getNumChildren(this);\r\n    }\r\n\r\n    /**\r\n     * Returns the bounding box of the physics shape.\r\n     * @returns The bounding box of the physics shape.\r\n     */\r\n    public getBoundingBox(): BoundingBox {\r\n        return this._physicsPlugin.getBoundingBox(this);\r\n    }\r\n\r\n    public set isTrigger(isTrigger: boolean) {\r\n        if (this._isTrigger === isTrigger) {\r\n            return;\r\n        }\r\n        this._isTrigger = isTrigger;\r\n        this._physicsPlugin.setTrigger(this, isTrigger);\r\n    }\r\n\r\n    public get isTrigger(): boolean {\r\n        return this._isTrigger;\r\n    }\r\n\r\n    /**\r\n     * Dispose the shape and release its associated resources.\r\n     */\r\n    public dispose() {\r\n        if (this._isDisposed) {\r\n            return;\r\n        }\r\n        this._physicsPlugin.disposeShape(this);\r\n        this._isDisposed = true;\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a sphere shape\r\n */\r\nexport class PhysicsShapeSphere extends PhysicsShape {\r\n    /**\r\n     * Constructor for the Sphere Shape\r\n     * @param center local center of the sphere\r\n     * @param radius radius\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(center: Vector3, radius: number, scene: Scene) {\r\n        super({ type: PhysicsShapeType.SPHERE, parameters: { center: center, radius: radius } }, scene);\r\n    }\r\n\r\n    /**\r\n     * Derive an approximate sphere from the mesh.\r\n     * @param mesh node from which to derive the sphere shape\r\n     * @returns PhysicsShapeSphere\r\n     */\r\n    static FromMesh(mesh: AbstractMesh) {\r\n        const bounds = mesh.getBoundingInfo();\r\n        const centerLocal = bounds.boundingSphere.center;\r\n        const he = bounds.boundingBox.extendSize;\r\n        const radius = Math.max(he.x, he.y, he.z);\r\n        return new PhysicsShapeSphere(centerLocal, radius, mesh.getScene());\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a capsule shape\r\n */\r\nexport class PhysicsShapeCapsule extends PhysicsShape {\r\n    /**\r\n     *\r\n     * @param pointA Starting point that defines the capsule segment\r\n     * @param pointB ending point of that same segment\r\n     * @param radius radius\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(pointA: Vector3, pointB: Vector3, radius: number, scene: Scene) {\r\n        super({ type: PhysicsShapeType.CAPSULE, parameters: { pointA: pointA, pointB: pointB, radius: radius } }, scene);\r\n    }\r\n\r\n    /**\r\n     * Derive an approximate capsule from the mesh. Note, this is\r\n     * not the optimal bounding capsule.\r\n     * @param mesh Node from which to derive a cylinder shape\r\n     * @returns Physics Shape Capsule\r\n     */\r\n    static FromMesh(mesh: AbstractMesh): PhysicsShapeCapsule {\r\n        const boundsLocal = mesh.getBoundingInfo();\r\n        const radius = boundsLocal.boundingBox.extendSize.x;\r\n        const pointFromCenter = new Vector3(0, boundsLocal.boundingBox.extendSize.y - radius, 0);\r\n        const pointA = boundsLocal.boundingBox.center.add(pointFromCenter);\r\n        const pointB = boundsLocal.boundingBox.center.subtract(pointFromCenter);\r\n        return new PhysicsShapeCapsule(pointA, pointB, radius, mesh.getScene());\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a cylinder shape\r\n */\r\nexport class PhysicsShapeCylinder extends PhysicsShape {\r\n    /**\r\n     *\r\n     * @param pointA Starting point that defines the cylinder segment\r\n     * @param pointB ending point of that same segment\r\n     * @param radius radius\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(pointA: Vector3, pointB: Vector3, radius: number, scene: Scene) {\r\n        super({ type: PhysicsShapeType.CYLINDER, parameters: { pointA: pointA, pointB: pointB, radius: radius } }, scene);\r\n    }\r\n\r\n    /**\r\n     * Derive an approximate cylinder from the mesh. Note, this is\r\n     * not the optimal bounding cylinder.\r\n     * @param mesh Node from which to derive a cylinder shape\r\n     * @returns Physics Shape Cylinder\r\n     */\r\n    static FromMesh(mesh: AbstractMesh): PhysicsShapeCylinder {\r\n        const boundsLocal = mesh.getBoundingInfo();\r\n        const radius = boundsLocal.boundingBox.extendSize.x;\r\n        const pointFromCenter = new Vector3(0, boundsLocal.boundingBox.extendSize.y, 0);\r\n        const pointA = boundsLocal.boundingBox.center.add(pointFromCenter);\r\n        const pointB = boundsLocal.boundingBox.center.subtract(pointFromCenter);\r\n        return new PhysicsShapeCylinder(pointA, pointB, radius, mesh.getScene());\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a box shape\r\n */\r\nexport class PhysicsShapeBox extends PhysicsShape {\r\n    /**\r\n     *\r\n     * @param center local center of the box\r\n     * @param rotation local orientation\r\n     * @param extents size of the box in each direction\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(center: Vector3, rotation: Quaternion, extents: Vector3, scene: Scene) {\r\n        super({ type: PhysicsShapeType.BOX, parameters: { center: center, rotation: rotation, extents: extents } }, scene);\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @param mesh\r\n     * @returns PhysicsShapeBox\r\n     */\r\n    static FromMesh(mesh: AbstractMesh): PhysicsShapeBox {\r\n        const bounds = mesh.getBoundingInfo();\r\n        const centerLocal = bounds.boundingBox.center;\r\n        const extents = bounds.boundingBox.extendSize.scale(2.0); //<todo.eoin extendSize seems to really be half-extents?\r\n        return new PhysicsShapeBox(centerLocal, Quaternion.Identity(), extents, mesh.getScene());\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a convex hull shape\r\n */\r\nexport class PhysicsShapeConvexHull extends PhysicsShape {\r\n    /**\r\n     *\r\n     * @param mesh the mesh to be used as topology infos for the convex hull\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(mesh: Mesh, scene: Scene) {\r\n        super({ type: PhysicsShapeType.CONVEX_HULL, parameters: { mesh: mesh } }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a mesh shape\r\n */\r\nexport class PhysicsShapeMesh extends PhysicsShape {\r\n    /**\r\n     *\r\n     * @param mesh the mesh topology that will be used to create the shape\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(mesh: Mesh, scene: Scene) {\r\n        super({ type: PhysicsShapeType.MESH, parameters: { mesh: mesh } }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * A shape container holds a variable number of shapes. Use AddChild to append to newly created parent container.\r\n */\r\nexport class PhysicsShapeContainer extends PhysicsShape {\r\n    /**\r\n     * Constructor of the Shape container\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(scene: Scene) {\r\n        super({ type: PhysicsShapeType.CONTAINER, parameters: {} }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a heightfield Shape\r\n */\r\nexport class PhysicsShapeHeightField extends PhysicsShape {\r\n    /**\r\n     * Constructor of the Shape heightfield\r\n     * @param heightFieldSizeX The size of the heightfield in the X axis\r\n     * @param heightFieldSizeZ The size of the heightfield in the Z axis\r\n     * @param numHeightFieldSamplesX The number of samples along the X axis\r\n     * @param numHeightFieldSamplesZ The number of samples along the Z axis\r\n     * @param heightFieldData The data for the heightfield\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(heightFieldSizeX: number, heightFieldSizeZ: number, numHeightFieldSamplesX: number, numHeightFieldSamplesZ: number, heightFieldData: Float32Array, scene: Scene) {\r\n        super(\r\n            {\r\n                type: PhysicsShapeType.HEIGHTFIELD,\r\n                parameters: {\r\n                    heightFieldSizeX: heightFieldSizeX,\r\n                    heightFieldSizeZ: heightFieldSizeZ,\r\n                    numHeightFieldSamplesX: numHeightFieldSamplesX,\r\n                    numHeightFieldSamplesZ: numHeightFieldSamplesZ,\r\n                    heightFieldData: heightFieldData,\r\n                },\r\n            },\r\n            scene\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Helper object to create a ground mesh Shape\r\n */\r\nexport class PhysicsShapeGroundMesh extends PhysicsShape {\r\n    /**\r\n     * Constructor of the Shape heightfield\r\n     * @param groundMesh ground mesh used for display\r\n     * @param scene scene to attach to\r\n     */\r\n    constructor(groundMesh: GroundMesh, scene: Scene) {\r\n        super({ type: PhysicsShapeType.HEIGHTFIELD, parameters: { groundMesh: groundMesh } }, scene);\r\n    }\r\n}\r\n","import { PhysicsBody } from \"./physicsBody\";\r\nimport { type PhysicsMaterial } from \"./physicsMaterial\";\r\nimport { PhysicsShape } from \"./physicsShape\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { Quaternion, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { WithinEpsilon } from \"../../Maths/math.scalar.functions\";\r\nimport { PhysicsMotionType, PhysicsShapeType } from \"./IPhysicsEnginePlugin\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Node } from \"../../node\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { BoundingBox } from \"../../Culling/boundingBox\";\r\n\r\n/**\r\n * The interface for the physics aggregate parameters\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsAggregateParameters {\r\n    /**\r\n     * The mass of the physics aggregate\r\n     */\r\n    mass: number;\r\n\r\n    /**\r\n     * The friction of the physics aggregate\r\n     */\r\n    friction?: number;\r\n\r\n    /**\r\n     * The coefficient of restitution of the physics aggregate\r\n     */\r\n    restitution?: number;\r\n\r\n    /**\r\n     * Radius for sphere, cylinder and capsule\r\n     */\r\n    radius?: number;\r\n\r\n    /**\r\n     * Starting point for cylinder/capsule\r\n     */\r\n    pointA?: Vector3;\r\n\r\n    /**\r\n     * Ending point for cylinder/capsule\r\n     */\r\n    pointB?: Vector3;\r\n\r\n    /**\r\n     * Extents for box\r\n     */\r\n    extents?: Vector3;\r\n\r\n    /**\r\n     * Orientation for box\r\n     */\r\n    rotation?: Quaternion;\r\n\r\n    /**\r\n     * mesh local center\r\n     */\r\n    center?: Vector3;\r\n\r\n    /**\r\n     * mesh object. Used for mesh and convex hull aggregates.\r\n     */\r\n    mesh?: Mesh;\r\n\r\n    /**\r\n     * Physics engine will try to make this body sleeping and not active\r\n     */\r\n    startAsleep?: boolean;\r\n\r\n    /**\r\n     * If true, mark the created shape as a trigger shape\r\n     */\r\n    isTriggerShape?: boolean;\r\n}\r\n/**\r\n * Helper class to create and interact with a PhysicsAggregate.\r\n * This is a transition object that works like Physics Plugin V1 Impostors.\r\n * This helper instantiates all mandatory physics objects to get a body/shape and material.\r\n * It's less efficient than handling body and shapes independently but for prototyping or\r\n * a small numbers of physics objects, it's good enough.\r\n */\r\nexport class PhysicsAggregate {\r\n    /**\r\n     * The body that is associated with this aggregate\r\n     */\r\n    public body: PhysicsBody;\r\n\r\n    /**\r\n     * The shape that is associated with this aggregate\r\n     */\r\n    public shape: PhysicsShape;\r\n\r\n    /**\r\n     * The material that is associated with this aggregate\r\n     */\r\n    public material: PhysicsMaterial;\r\n\r\n    private _disposeShapeWhenDisposed = true;\r\n\r\n    private _nodeDisposeObserver: Nullable<Observer<Node>>;\r\n\r\n    private _options: PhysicsAggregateParameters;\r\n\r\n    constructor(\r\n        /**\r\n         * The physics-enabled object used as the physics aggregate\r\n         */\r\n        public transformNode: TransformNode,\r\n        /**\r\n         * The type of the physics aggregate\r\n         */\r\n        public type: PhysicsShapeType | PhysicsShape,\r\n        options: PhysicsAggregateParameters = { mass: 0 },\r\n        private _scene?: Scene\r\n    ) {\r\n        // Shallow-clone the options so we never mutate the caller's object.\r\n        // _addSizeOptions assigns to fields like .mesh, .center, .radius, etc.,\r\n        // which would otherwise leak stale references (e.g. a disposed mesh)\r\n        // into subsequent PhysicsAggregate constructions sharing the same options.\r\n        this._options = { ...options };\r\n\r\n        //sanity check!\r\n        if (!this.transformNode) {\r\n            Logger.Error(\"No object was provided. A physics object is obligatory\");\r\n            return;\r\n        }\r\n        const m = transformNode as Mesh;\r\n        if (this.transformNode.parent && this._options.mass !== 0 && m.hasThinInstances) {\r\n            Logger.Warn(\r\n                \"A physics body has been created for an object which has a parent and thin instances. Babylon physics currently works in local space so unexpected issues may occur.\"\r\n            );\r\n        }\r\n\r\n        // Legacy support for old syntax.\r\n        if (!this._scene && transformNode.getScene) {\r\n            this._scene = transformNode.getScene();\r\n        }\r\n\r\n        if (!this._scene) {\r\n            return;\r\n        }\r\n\r\n        //default options params\r\n        this._options.mass = this._options.mass === void 0 ? 0 : this._options.mass;\r\n        this._options.friction = this._options.friction === void 0 ? 0.2 : this._options.friction;\r\n        this._options.restitution = this._options.restitution === void 0 ? 0.2 : this._options.restitution;\r\n\r\n        const motionType = this._options.mass === 0 ? PhysicsMotionType.STATIC : PhysicsMotionType.DYNAMIC;\r\n        const startAsleep = this._options.startAsleep ?? false;\r\n        this.body = new PhysicsBody(transformNode, motionType, startAsleep, this._scene);\r\n        this._addSizeOptions();\r\n        if ((type as any).getClassName && (type as any).getClassName() === \"PhysicsShape\") {\r\n            this.shape = type as PhysicsShape;\r\n            this._disposeShapeWhenDisposed = false;\r\n        } else {\r\n            this.shape = new PhysicsShape({ type: type as PhysicsShapeType, parameters: this._options as any }, this._scene);\r\n        }\r\n\r\n        if (this._options.isTriggerShape) {\r\n            this.shape.isTrigger = true;\r\n        }\r\n\r\n        this.material = { friction: this._options.friction, restitution: this._options.restitution };\r\n        this.body.shape = this.shape;\r\n        this.shape.material = this.material;\r\n\r\n        this.body.setMassProperties({ mass: this._options.mass });\r\n\r\n        this._nodeDisposeObserver = this.transformNode.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n    }\r\n\r\n    private _getObjectBoundingBox() {\r\n        if ((this.transformNode as AbstractMesh).getRawBoundingInfo) {\r\n            return (this.transformNode as AbstractMesh).getRawBoundingInfo().boundingBox;\r\n        } else {\r\n            return new BoundingBox(new Vector3(-0.5, -0.5, -0.5), new Vector3(0.5, 0.5, 0.5));\r\n        }\r\n    }\r\n\r\n    private _hasVertices(node: TransformNode): boolean {\r\n        return (node as any)?.getTotalVertices() > 0;\r\n    }\r\n\r\n    private _addSizeOptions(): void {\r\n        this.transformNode.computeWorldMatrix(true);\r\n        const bb = this._getObjectBoundingBox();\r\n        const extents = TmpVectors.Vector3[0];\r\n        extents.copyFrom(bb.extendSize);\r\n        extents.scaleInPlace(2);\r\n        extents.multiplyInPlace(this.transformNode.absoluteScaling);\r\n        // In case we had any negative scaling, we need to take the absolute value of the extents.\r\n        extents.x = Math.abs(extents.x);\r\n        extents.y = Math.abs(extents.y);\r\n        extents.z = Math.abs(extents.z);\r\n\r\n        const min = TmpVectors.Vector3[1];\r\n        min.copyFrom(bb.minimum);\r\n        min.multiplyInPlace(this.transformNode.absoluteScaling);\r\n\r\n        if (!this._options.center) {\r\n            const center = new Vector3();\r\n            center.copyFrom(bb.center);\r\n            center.multiplyInPlace(this.transformNode.absoluteScaling);\r\n            this._options.center = center;\r\n        }\r\n\r\n        switch (this.type) {\r\n            case PhysicsShapeType.SPHERE:\r\n                if (!this._options.radius && WithinEpsilon(extents.x, extents.y, 0.0001) && WithinEpsilon(extents.x, extents.z, 0.0001)) {\r\n                    this._options.radius = extents.x / 2;\r\n                } else if (!this._options.radius) {\r\n                    Logger.Warn(\"Non uniform scaling is unsupported for sphere shapes. Setting the radius to the biggest bounding box extent.\");\r\n                    this._options.radius = Math.max(extents.x, extents.y, extents.z) / 2;\r\n                }\r\n                break;\r\n            case PhysicsShapeType.CAPSULE:\r\n                {\r\n                    const capRadius = extents.x / 2;\r\n                    this._options.radius = this._options.radius ?? capRadius;\r\n                    this._options.pointA = this._options.pointA ?? new Vector3(0, min.y + capRadius, 0);\r\n                    this._options.pointB = this._options.pointB ?? new Vector3(0, min.y + extents.y - capRadius, 0);\r\n                }\r\n                break;\r\n            case PhysicsShapeType.CYLINDER:\r\n                {\r\n                    const capRadius = extents.x / 2;\r\n                    this._options.radius = this._options.radius ?? capRadius;\r\n                    this._options.pointA = this._options.pointA ?? new Vector3(0, min.y, 0);\r\n                    this._options.pointB = this._options.pointB ?? new Vector3(0, min.y + extents.y, 0);\r\n                }\r\n                break;\r\n            case PhysicsShapeType.MESH:\r\n            case PhysicsShapeType.CONVEX_HULL:\r\n            case PhysicsShapeType.HEIGHTFIELD:\r\n                if (!this._options.mesh && this._hasVertices(this.transformNode)) {\r\n                    this._options.mesh = this.transformNode as Mesh;\r\n                } else if (!this._options.mesh || !this._hasVertices(this._options.mesh)) {\r\n                    throw new Error(\r\n                        \"No valid mesh was provided for mesh or convex hull shape parameter. Please provide a mesh with valid geometry (number of vertices greater than 0).\"\r\n                    );\r\n                }\r\n                break;\r\n            case PhysicsShapeType.BOX:\r\n                this._options.extents = this._options.extents ?? new Vector3(extents.x, extents.y, extents.z);\r\n                this._options.rotation = this._options.rotation ?? Quaternion.Identity();\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases the body, shape and material\r\n     */\r\n    public dispose(): void {\r\n        if (this._nodeDisposeObserver) {\r\n            this.body.transformNode.onDisposeObservable.remove(this._nodeDisposeObserver);\r\n            this._nodeDisposeObserver = null;\r\n        }\r\n        this.body.dispose();\r\n        if (this._disposeShapeWhenDisposed) {\r\n            this.shape.dispose();\r\n        }\r\n    }\r\n}\r\n","import { WebXRExperienceHelper } from \"./webXRExperienceHelper\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type IWebXRInputOptions, WebXRInput } from \"./webXRInput\";\r\nimport {\r\n    type IWebXRControllerPointerSelectionOptions,\r\n    RegisterWebXRControllerPointerSelection,\r\n    WebXRControllerPointerSelection,\r\n} from \"./features/WebXRControllerPointerSelection.pure\";\r\nimport { type IWebXRNearInteractionOptions, RegisterWebXRNearInteraction, WebXRNearInteraction } from \"./features/WebXRNearInteraction.pure\";\r\nimport { type WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { type WebXREnterExitUIOptions, WebXREnterExitUI } from \"./webXREnterExitUI\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type WebXRManagedOutputCanvasOptions } from \"./webXRManagedOutputCanvas\";\r\nimport { type IWebXRTeleportationOptions, RegisterWebXRControllerTeleportation, WebXRMotionControllerTeleportation } from \"./features/WebXRControllerTeleportation.pure\";\r\nimport { RegisterWebXRHandTracking, WebXRHandTracking, type IWebXRHandTrackingOptions } from \"./features/WebXRHandTracking.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\n/**\r\n * Options for the default xr helper\r\n */\r\nexport class WebXRDefaultExperienceOptions {\r\n    /**\r\n     * Enable or disable default UI to enter XR\r\n     */\r\n    public disableDefaultUI?: boolean;\r\n    /**\r\n     * Should pointer selection not initialize.\r\n     * Note that disabling pointer selection also disables teleportation.\r\n     * Defaults to false.\r\n     */\r\n    public disablePointerSelection?: boolean;\r\n    /**\r\n     * Should teleportation not initialize. Defaults to false.\r\n     */\r\n    public disableTeleportation?: boolean;\r\n    /**\r\n     * Should nearInteraction not initialize. Defaults to false.\r\n     */\r\n    public disableNearInteraction?: boolean;\r\n\r\n    /**\r\n     * Should hand tracking be disabled. Defaults to false.\r\n     */\r\n    public disableHandTracking?: boolean;\r\n    /**\r\n     * Floor meshes that will be used for teleport\r\n     */\r\n    public floorMeshes?: Array<AbstractMesh>;\r\n    /**\r\n     * If set to true, the first frame will not be used to reset position\r\n     * The first frame is mainly used when copying transformation from the old camera\r\n     * Mainly used in AR\r\n     */\r\n    public ignoreNativeCameraTransformation?: boolean;\r\n    /**\r\n     * Optional configuration for the XR input object\r\n     */\r\n    public inputOptions?: Partial<IWebXRInputOptions>;\r\n    /**\r\n     * optional configuration for pointer selection\r\n     */\r\n    public pointerSelectionOptions?: Partial<IWebXRControllerPointerSelectionOptions>;\r\n    /**\r\n     * optional configuration for near interaction\r\n     */\r\n    public nearInteractionOptions?: Partial<IWebXRNearInteractionOptions>;\r\n\r\n    /**\r\n     * optional configuration for hand tracking\r\n     */\r\n    public handSupportOptions?: Partial<IWebXRHandTrackingOptions>;\r\n    /**\r\n     * optional configuration for teleportation\r\n     */\r\n    public teleportationOptions?: Partial<IWebXRTeleportationOptions>;\r\n    /**\r\n     * optional configuration for the output canvas\r\n     */\r\n    public outputCanvasOptions?: WebXRManagedOutputCanvasOptions;\r\n    /**\r\n     * optional UI options. This can be used among other to change session mode and reference space type\r\n     */\r\n    public uiOptions?: Partial<WebXREnterExitUIOptions>;\r\n    /**\r\n     * When loading teleportation and pointer select, use stable versions instead of latest.\r\n     */\r\n    public useStablePlugins?: boolean;\r\n\r\n    /**\r\n     * An optional rendering group id that will be set globally for teleportation, pointer selection and default controller meshes\r\n     */\r\n    public renderingGroupId?: number;\r\n\r\n    /**\r\n     * A list of optional features to init the session with\r\n     * If set to true, all features we support will be added\r\n     */\r\n    public optionalFeatures?: boolean | string[];\r\n}\r\n\r\n/**\r\n * Default experience for webxr\r\n */\r\nexport class WebXRDefaultExperience {\r\n    /**\r\n     * Base experience\r\n     */\r\n    public baseExperience: WebXRExperienceHelper;\r\n    /**\r\n     * Enables ui for entering/exiting xr\r\n     */\r\n    public enterExitUI: WebXREnterExitUI;\r\n    /**\r\n     * Input experience extension\r\n     */\r\n    public input: WebXRInput;\r\n    /**\r\n     * Enables laser pointer and selection\r\n     */\r\n    public pointerSelection: WebXRControllerPointerSelection;\r\n    /**\r\n     * Default target xr should render to\r\n     */\r\n    public renderTarget: WebXRRenderTarget;\r\n    /**\r\n     * Enables teleportation\r\n     */\r\n    public teleportation: WebXRMotionControllerTeleportation;\r\n\r\n    /**\r\n     * Enables near interaction for hands/controllers\r\n     */\r\n    public nearInteraction: WebXRNearInteraction;\r\n\r\n    private constructor() {}\r\n\r\n    /**\r\n     * Creates the default xr experience\r\n     * @param scene scene\r\n     * @param options options for basic configuration\r\n     * @returns resulting WebXRDefaultExperience\r\n     */\r\n    public static async CreateAsync(scene: Scene, options: WebXRDefaultExperienceOptions = {}) {\r\n        RegisterWebXRControllerPointerSelection();\r\n        RegisterWebXRControllerTeleportation();\r\n        RegisterWebXRNearInteraction();\r\n        RegisterWebXRHandTracking();\r\n\r\n        const result = new WebXRDefaultExperience();\r\n        scene.onDisposeObservable.addOnce(() => {\r\n            result.dispose();\r\n        });\r\n        // init the UI right after construction\r\n        if (!options.disableDefaultUI) {\r\n            const uiOptions: WebXREnterExitUIOptions = {\r\n                renderTarget: result.renderTarget,\r\n                ...(options.uiOptions || {}),\r\n            };\r\n            if (options.optionalFeatures) {\r\n                if (typeof options.optionalFeatures === \"boolean\") {\r\n                    uiOptions.optionalFeatures = [\"hit-test\", \"anchors\", \"plane-detection\", \"hand-tracking\"];\r\n                } else {\r\n                    uiOptions.optionalFeatures = options.optionalFeatures;\r\n                }\r\n            }\r\n            result.enterExitUI = new WebXREnterExitUI(scene, uiOptions);\r\n        }\r\n\r\n        try {\r\n            // Create base experience\r\n            const xrHelper = await WebXRExperienceHelper.CreateAsync(scene);\r\n            // eslint-disable-next-line require-atomic-updates\r\n            result.baseExperience = xrHelper;\r\n\r\n            if (options.ignoreNativeCameraTransformation) {\r\n                // eslint-disable-next-line require-atomic-updates\r\n                result.baseExperience.camera.compensateOnFirstFrame = false;\r\n            }\r\n\r\n            // Add controller support\r\n            // eslint-disable-next-line require-atomic-updates\r\n            result.input = new WebXRInput(xrHelper.sessionManager, xrHelper.camera, {\r\n                controllerOptions: {\r\n                    renderingGroupId: options.renderingGroupId,\r\n                },\r\n                ...(options.inputOptions || {}),\r\n            });\r\n\r\n            if (!options.disablePointerSelection) {\r\n                // Add default pointer selection\r\n                const pointerSelectionOptions = {\r\n                    ...options.pointerSelectionOptions,\r\n                    xrInput: result.input,\r\n                    renderingGroupId: options.renderingGroupId,\r\n                };\r\n\r\n                result.pointerSelection = result.baseExperience.featuresManager.enableFeature(\r\n                    WebXRControllerPointerSelection.Name,\r\n                    options.useStablePlugins ? \"stable\" : \"latest\",\r\n                    <IWebXRControllerPointerSelectionOptions>pointerSelectionOptions\r\n                );\r\n\r\n                if (!options.disableTeleportation) {\r\n                    // Add default teleportation, including rotation\r\n                    result.teleportation = result.baseExperience.featuresManager.enableFeature(\r\n                        WebXRMotionControllerTeleportation.Name,\r\n                        options.useStablePlugins ? \"stable\" : \"latest\",\r\n                        <IWebXRTeleportationOptions>{\r\n                            floorMeshes: options.floorMeshes,\r\n                            xrInput: result.input,\r\n                            renderingGroupId: options.renderingGroupId,\r\n                            ...options.teleportationOptions,\r\n                        }\r\n                    );\r\n                    result.teleportation.setSelectionFeature(result.pointerSelection);\r\n                }\r\n            }\r\n\r\n            if (!options.disableNearInteraction) {\r\n                // Add default pointer selection\r\n                result.nearInteraction = result.baseExperience.featuresManager.enableFeature(WebXRNearInteraction.Name, options.useStablePlugins ? \"stable\" : \"latest\", <\r\n                    IWebXRNearInteractionOptions\r\n                >{\r\n                    xrInput: result.input,\r\n                    farInteractionFeature: result.pointerSelection,\r\n                    renderingGroupId: options.renderingGroupId,\r\n                    useUtilityLayer: true,\r\n                    enableNearInteractionOnAllControllers: true,\r\n                    ...options.nearInteractionOptions,\r\n                });\r\n            }\r\n\r\n            if (!options.disableHandTracking) {\r\n                // Add default hand tracking\r\n                result.baseExperience.featuresManager.enableFeature(\r\n                    WebXRHandTracking.Name,\r\n                    options.useStablePlugins ? \"stable\" : \"latest\",\r\n                    <IWebXRHandTrackingOptions>{\r\n                        xrInput: result.input,\r\n                        ...options.handSupportOptions,\r\n                    },\r\n                    undefined,\r\n                    false\r\n                );\r\n            }\r\n\r\n            // Create the WebXR output target\r\n            result.renderTarget = result.baseExperience.sessionManager.getWebXRRenderTarget(options.outputCanvasOptions);\r\n\r\n            if (!options.disableDefaultUI) {\r\n                // Create ui for entering/exiting xr\r\n                await result.enterExitUI.setHelperAsync(result.baseExperience, result.renderTarget);\r\n            }\r\n            return result;\r\n        } catch (error) {\r\n            Logger.Error(\"Error initializing XR\");\r\n            Logger.Error(error);\r\n            return result;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the experience helper\r\n     */\r\n    public dispose() {\r\n        if (this.baseExperience) {\r\n            this.baseExperience.dispose();\r\n        }\r\n        if (this.input) {\r\n            this.input.dispose();\r\n        }\r\n        if (this.enterExitUI) {\r\n            this.enterExitUI.dispose();\r\n        }\r\n        if (this.renderTarget) {\r\n            this.renderTarget.dispose();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { PBRMaterial } from \"../Materials/PBR/pbrMaterial.pure\";\r\nimport { HemisphericLight } from \"../Lights/hemisphericLight.pure\";\r\nimport { FreeCamera } from \"../Cameras/freeCamera.pure\";\r\nimport { ArcRotateCamera } from \"../Cameras/arcRotateCamera.pure\";\r\nimport { type TargetCamera } from \"../Cameras/targetCamera.pure\";\r\nimport { CreateBox } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type IEnvironmentHelperOptions, EnvironmentHelper } from \"./environmentHelper\";\r\nimport { type VRExperienceHelperOptions, VRExperienceHelper } from \"../Cameras/VR/vrExperienceHelper.pure\";\r\nimport { type WebXRDefaultExperienceOptions, WebXRDefaultExperience } from \"../XR/webXRDefaultExperience\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var _forceSceneHelpersToBundle = true;\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sceneHelpers.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSceneHelpers(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.createDefaultLight = function (replace = false): void {\r\n        // Dispose existing light in replace mode.\r\n        if (replace) {\r\n            if (this.lights) {\r\n                for (let i = 0; i < this.lights.length; i++) {\r\n                    this.lights[i].dispose();\r\n                }\r\n            }\r\n        }\r\n\r\n        // Light\r\n        if (this.lights.length === 0) {\r\n            new HemisphericLight(\"default light\", Vector3.Up(), this);\r\n        }\r\n    };\r\n\r\n    Scene.prototype.createDefaultCamera = function (createArcRotateCamera = false, replace = false, attachCameraControls = false): void {\r\n        // Dispose existing camera in replace mode.\r\n        if (replace) {\r\n            if (this.activeCamera) {\r\n                this.activeCamera.dispose();\r\n                this.activeCamera = null;\r\n            }\r\n        }\r\n\r\n        // Camera\r\n        if (!this.activeCamera) {\r\n            const worldExtends = this.getWorldExtends((mesh) => mesh.isVisible && mesh.isEnabled());\r\n            const worldSize = worldExtends.max.subtract(worldExtends.min);\r\n            const worldCenter = worldExtends.min.add(worldSize.scale(0.5));\r\n\r\n            let camera: TargetCamera;\r\n            let radius = worldSize.length() * 1.5;\r\n            // empty scene scenario!\r\n            if (!isFinite(radius) || radius === 0) {\r\n                radius = 1;\r\n                worldCenter.copyFromFloats(0, 0, 0);\r\n            }\r\n            if (createArcRotateCamera) {\r\n                const arcRotateCamera = new ArcRotateCamera(\"default camera\", -(Math.PI / 2), Math.PI / 2, radius, worldCenter, this);\r\n                arcRotateCamera.lowerRadiusLimit = radius * 0.01;\r\n                arcRotateCamera.wheelPrecision = 100 / radius;\r\n                camera = arcRotateCamera;\r\n            } else {\r\n                const freeCamera = new FreeCamera(\"default camera\", new Vector3(worldCenter.x, worldCenter.y, -radius), this);\r\n                freeCamera.setTarget(worldCenter);\r\n                camera = freeCamera;\r\n            }\r\n            camera.minZ = radius * 0.01;\r\n            camera.maxZ = radius * 1000;\r\n            camera.speed = radius * 0.2;\r\n            this.activeCamera = camera;\r\n\r\n            if (attachCameraControls) {\r\n                camera.attachControl();\r\n            }\r\n        }\r\n    };\r\n\r\n    Scene.prototype.createDefaultCameraOrLight = function (createArcRotateCamera = false, replace = false, attachCameraControls = false): void {\r\n        this.createDefaultLight(replace);\r\n        this.createDefaultCamera(createArcRotateCamera, replace, attachCameraControls);\r\n    };\r\n\r\n    Scene.prototype.createDefaultSkybox = function (environmentTexture?: BaseTexture, pbr = false, scale = 1000, blur = 0, setGlobalEnvTexture = true): Nullable<Mesh> {\r\n        if (!environmentTexture) {\r\n            Logger.Warn(\"Can not create default skybox without environment texture.\");\r\n            return null;\r\n        }\r\n\r\n        if (setGlobalEnvTexture) {\r\n            if (environmentTexture) {\r\n                this.environmentTexture = environmentTexture;\r\n            }\r\n        }\r\n\r\n        // Skybox\r\n        const hdrSkybox = CreateBox(\"hdrSkyBox\", { size: scale }, this);\r\n        if (pbr) {\r\n            const hdrSkyboxMaterial = new PBRMaterial(\"skyBox\", this);\r\n            hdrSkyboxMaterial.backFaceCulling = false;\r\n            hdrSkyboxMaterial.reflectionTexture = environmentTexture.clone();\r\n            if (hdrSkyboxMaterial.reflectionTexture) {\r\n                hdrSkyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE;\r\n            }\r\n            hdrSkyboxMaterial.microSurface = 1.0 - blur;\r\n            hdrSkyboxMaterial.disableLighting = true;\r\n            hdrSkyboxMaterial.twoSidedLighting = true;\r\n            hdrSkybox.material = hdrSkyboxMaterial;\r\n        } else {\r\n            const skyboxMaterial = new StandardMaterial(\"skyBox\", this);\r\n            skyboxMaterial.backFaceCulling = false;\r\n            skyboxMaterial.reflectionTexture = environmentTexture.clone();\r\n            if (skyboxMaterial.reflectionTexture) {\r\n                skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE;\r\n            }\r\n            skyboxMaterial.disableLighting = true;\r\n            hdrSkybox.material = skyboxMaterial;\r\n        }\r\n        hdrSkybox.isPickable = false;\r\n        hdrSkybox.infiniteDistance = true;\r\n        hdrSkybox.ignoreCameraMaxZ = true;\r\n        return hdrSkybox;\r\n    };\r\n\r\n    Scene.prototype.createDefaultEnvironment = function (options: Partial<IEnvironmentHelperOptions>): Nullable<EnvironmentHelper> {\r\n        if (EnvironmentHelper) {\r\n            return new EnvironmentHelper(options, this);\r\n        }\r\n        return null;\r\n    };\r\n\r\n    Scene.prototype.createDefaultVRExperience = function (webVROptions: VRExperienceHelperOptions = {}): VRExperienceHelper {\r\n        return new VRExperienceHelper(this, webVROptions);\r\n    };\r\n\r\n    Scene.prototype.createDefaultXRExperienceAsync = async function (options: WebXRDefaultExperienceOptions = {}): Promise<WebXRDefaultExperience> {\r\n        return await WebXRDefaultExperience.CreateAsync(this, options);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable, type Observer } from \"../../Misc/observable.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { IsExponentOfTwo } from \"../../Misc/tools.functions\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type ExternalTexture } from \"./externalTexture\";\r\nimport { type WebGPUEngine } from \"core/Engines\";\r\nimport { serialize } from \"core/Misc/decorators\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\nfunction RemoveSource(video: HTMLVideoElement): void {\r\n    // Remove any <source> elements, etc.\r\n    while (video.firstChild) {\r\n        video.removeChild(video.firstChild);\r\n    }\r\n\r\n    // detach srcObject\r\n    video.srcObject = null;\r\n\r\n    // Set a blank src (https://html.spec.whatwg.org/multipage/media.html#best-practices-for-authors-using-media-elements)\r\n    video.src = \"\";\r\n\r\n    // Prevent non-important errors maybe (https://twitter.com/beraliv/status/1205214277956775936)\r\n    video.removeAttribute(\"src\");\r\n}\r\n\r\n/**\r\n * Settings for finer control over video usage\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface VideoTextureSettings {\r\n    /**\r\n     * Applies `autoplay` to video, if specified\r\n     */\r\n    autoPlay?: boolean;\r\n\r\n    /**\r\n     * Applies `muted` to video, if specified\r\n     */\r\n    muted?: boolean;\r\n\r\n    /**\r\n     * Applies `loop` to video, if specified\r\n     */\r\n    loop?: boolean;\r\n\r\n    /**\r\n     * Automatically updates internal texture from video at every frame in the render loop\r\n     */\r\n    autoUpdateTexture: boolean;\r\n\r\n    /**\r\n     * Image src displayed during the video loading or until the user interacts with the video.\r\n     */\r\n    poster?: string;\r\n\r\n    /**\r\n     * Defines the associated texture format.\r\n     */\r\n    format?: number;\r\n\r\n    /**\r\n     * Notify babylon to not modify any video settings and not control the video's playback.\r\n     * Set this to true if you are controlling the way the video is being played, stopped and paused.\r\n     */\r\n    independentVideoSource?: boolean;\r\n}\r\n\r\n/**\r\n * If you want to display a video in your scene, this is the special texture for that.\r\n * This special texture works similar to other textures, with the exception of a few parameters.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/videoTexture\r\n */\r\nexport class VideoTexture extends Texture {\r\n    /**\r\n     * Tells whether textures will be updated automatically or user is required to call `updateTexture` manually\r\n     */\r\n    public readonly autoUpdateTexture: boolean;\r\n\r\n    /**\r\n     * The video instance used by the texture internally\r\n     */\r\n    public readonly video: HTMLVideoElement;\r\n\r\n    private _externalTexture: Nullable<ExternalTexture> = null;\r\n    private _snapshotRenderingObserver: Nullable<Observer<Scene>> = null;\r\n    private _onUserActionRequestedObservable: Nullable<Observable<Texture>> = null;\r\n\r\n    /**\r\n     * Event triggered when a dom action is required by the user to play the video.\r\n     * This happens due to recent changes in browser policies preventing video to auto start.\r\n     */\r\n    public get onUserActionRequestedObservable(): Observable<Texture> {\r\n        if (!this._onUserActionRequestedObservable) {\r\n            this._onUserActionRequestedObservable = new Observable<Texture>();\r\n        }\r\n        return this._onUserActionRequestedObservable;\r\n    }\r\n\r\n    private _generateMipMaps: boolean;\r\n    private _stillImageCaptured = false;\r\n    private _displayingPosterTexture = false;\r\n    @serialize(\"settings\")\r\n    private _settings: VideoTextureSettings;\r\n    private _createInternalTextureOnEvent: string;\r\n    private _frameId = -1;\r\n    @serialize(\"src\")\r\n    private _currentSrc: Nullable<string | string[] | HTMLVideoElement> = null;\r\n    private _onError?: Nullable<(message?: string, exception?: any) => void>;\r\n    private _errorFound = false;\r\n\r\n    /**\r\n     * Serialize the flag to define this texture as a video texture\r\n     */\r\n    @serialize()\r\n    public readonly isVideo = true;\r\n\r\n    private _processError(reason: any) {\r\n        this._errorFound = true;\r\n        if (this._onError) {\r\n            this._onError(reason?.message);\r\n        } else {\r\n            Logger.Error(reason?.message);\r\n        }\r\n    }\r\n\r\n    private _handlePlay() {\r\n        this._errorFound = false;\r\n        // eslint-disable-next-line github/no-then\r\n        this.video.play().catch((reason) => {\r\n            if (reason?.name === \"NotAllowedError\") {\r\n                if (this._onUserActionRequestedObservable && this._onUserActionRequestedObservable.hasObservers()) {\r\n                    this._onUserActionRequestedObservable.notifyObservers(this);\r\n                    return;\r\n                } else if (!this.video.muted) {\r\n                    Logger.Warn(\"Unable to autoplay a video with sound. Trying again with muted turned true\");\r\n                    this.video.muted = true;\r\n                    this._errorFound = false;\r\n                    // eslint-disable-next-line github/no-then\r\n                    this.video.play().catch((otherReason) => {\r\n                        this._processError(otherReason);\r\n                    });\r\n                    return;\r\n                }\r\n            }\r\n\r\n            this._processError(reason);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a video texture.\r\n     * If you want to display a video in your scene, this is the special texture for that.\r\n     * This special texture works similar to other textures, with the exception of a few parameters.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/videoTexture\r\n     * @param name optional name, will detect from video source, if not defined\r\n     * @param src can be used to provide an url, array of urls or an already setup HTML video element.\r\n     * @param scene is obviously the current scene.\r\n     * @param generateMipMaps can be used to turn on mipmaps (Can be expensive for videoTextures because they are often updated).\r\n     * @param invertY is false by default but can be used to invert video on Y axis\r\n     * @param samplingMode controls the sampling method and is set to TRILINEAR_SAMPLINGMODE by default\r\n     * @param settings allows finer control over video usage\r\n     * @param onError defines a callback triggered when an error occurred during the loading session\r\n     * @param format defines the texture format to use (Engine.TEXTUREFORMAT_RGBA by default)\r\n     */\r\n    constructor(\r\n        name: Nullable<string>,\r\n        src: string | string[] | HTMLVideoElement,\r\n        scene: Nullable<Scene>,\r\n        generateMipMaps = false,\r\n        invertY = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        settings: Partial<VideoTextureSettings> = {},\r\n        onError?: Nullable<(message?: string, exception?: any) => void>,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA\r\n    ) {\r\n        super(null, scene, !generateMipMaps, invertY);\r\n\r\n        this._settings = {\r\n            autoPlay: true,\r\n            loop: true,\r\n            autoUpdateTexture: true,\r\n            ...settings,\r\n        };\r\n\r\n        this._onError = onError;\r\n\r\n        this._generateMipMaps = generateMipMaps;\r\n        this._initialSamplingMode = samplingMode;\r\n        this.autoUpdateTexture = this._settings.autoUpdateTexture;\r\n\r\n        this._currentSrc = src;\r\n        this.name = name || this._getName(src);\r\n        this.video = this._getVideo(src);\r\n        const engineWebGPU = this._engine as Nullable<WebGPUEngine>;\r\n        const createExternalTexture = engineWebGPU?.createExternalTexture;\r\n        if (createExternalTexture) {\r\n            this._externalTexture = createExternalTexture.call(engineWebGPU, this.video);\r\n        }\r\n\r\n        if (this._externalTexture) {\r\n            // Under FAST snapshot rendering the active meshes are not re-evaluated each frame, so materials\r\n            // (and the video textures they bind) are never re-bound and VideoTexture.update() is never called.\r\n            // Drive the per-frame update from a scene hook so the video keeps playing while snapshot rendering is active.\r\n            const ownerScene = this.getScene();\r\n            if (ownerScene) {\r\n                this._snapshotRenderingObserver = ownerScene.onBeforeRenderObservable.add(this._updateWhileSnapshotRendering);\r\n            }\r\n        }\r\n\r\n        if (!this._settings.independentVideoSource) {\r\n            if (this._settings.poster) {\r\n                this.video.poster = this._settings.poster;\r\n            }\r\n            if (this._settings.autoPlay !== undefined) {\r\n                this.video.autoplay = this._settings.autoPlay;\r\n            }\r\n            if (this._settings.loop !== undefined) {\r\n                this.video.loop = this._settings.loop;\r\n            }\r\n            if (this._settings.muted !== undefined) {\r\n                this.video.muted = this._settings.muted;\r\n            }\r\n\r\n            this.video.setAttribute(\"playsinline\", \"\");\r\n            this.video.addEventListener(\"paused\", this._updateInternalTexture);\r\n            this.video.addEventListener(\"seeked\", this._updateInternalTexture);\r\n            this.video.addEventListener(\"loadeddata\", this._updateInternalTexture);\r\n            this.video.addEventListener(\"emptied\", this._reset);\r\n\r\n            if (this._settings.autoPlay) {\r\n                this._handlePlay();\r\n            }\r\n        }\r\n\r\n        this._createInternalTextureOnEvent = this._settings.poster && !this._settings.autoPlay ? \"play\" : \"canplay\";\r\n        this.video.addEventListener(this._createInternalTextureOnEvent, this._createInternalTexture);\r\n        this._format = format;\r\n\r\n        const videoHasEnoughData = this.video.readyState >= this.video.HAVE_CURRENT_DATA;\r\n        if (this._settings.poster && (!this._settings.autoPlay || !videoHasEnoughData)) {\r\n            this._texture = this._getEngine()!.createTexture(this._settings.poster, false, !this.invertY, scene);\r\n            this._displayingPosterTexture = true;\r\n        } else if (videoHasEnoughData) {\r\n            this._createInternalTexture();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the video texture useful for serialization or dynamic coding.\r\n     * @returns \"VideoTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VideoTexture\";\r\n    }\r\n\r\n    private _getName(src: string | string[] | HTMLVideoElement): string {\r\n        if (src instanceof HTMLVideoElement) {\r\n            return src.currentSrc;\r\n        }\r\n\r\n        if (typeof src === \"object\") {\r\n            return src.toString();\r\n        }\r\n\r\n        return src;\r\n    }\r\n\r\n    private _getVideo(src: string | string[] | HTMLVideoElement): HTMLVideoElement {\r\n        if ((<any>src).isNative) {\r\n            return <HTMLVideoElement>src;\r\n        }\r\n        if (src instanceof HTMLVideoElement) {\r\n            Tools.SetCorsBehavior(src.currentSrc, src);\r\n            return src;\r\n        }\r\n        const video: HTMLVideoElement = document.createElement(\"video\");\r\n        if (typeof src === \"string\") {\r\n            Tools.SetCorsBehavior(src, video);\r\n            video.src = src;\r\n        } else {\r\n            Tools.SetCorsBehavior(src[0], video);\r\n            for (const url of src) {\r\n                const source = document.createElement(\"source\");\r\n                source.src = url;\r\n                video.appendChild(source);\r\n            }\r\n        }\r\n\r\n        this.onDisposeObservable.addOnce(() => {\r\n            RemoveSource(video);\r\n        });\r\n\r\n        return video;\r\n    }\r\n\r\n    private _resizeInternalTexture = (): void => {\r\n        // Cleanup the old texture before replacing it\r\n        if (this._texture != null) {\r\n            this._texture.dispose();\r\n        }\r\n\r\n        if (!this._getEngine()!.needPOTTextures || (IsExponentOfTwo(this.video.videoWidth) && IsExponentOfTwo(this.video.videoHeight))) {\r\n            this.wrapU = Texture.WRAP_ADDRESSMODE;\r\n            this.wrapV = Texture.WRAP_ADDRESSMODE;\r\n        } else {\r\n            this.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n            this.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n            this._generateMipMaps = false;\r\n        }\r\n\r\n        this._texture = this._getEngine()!.createDynamicTexture(this.video.videoWidth, this.video.videoHeight, this._generateMipMaps, this.samplingMode);\r\n        this._texture.format = this._format ?? Constants.TEXTUREFORMAT_RGBA;\r\n\r\n        // The internal texture (bound by materials) was just recreated. A recorded FAST snapshot bundle still\r\n        // references the previous GPU texture, so force a snapshot reset to re-record against the new texture.\r\n        this._resetSnapshotRenderingIfFast();\r\n\r\n        // Reset the frame ID and update the new texture to ensure it pulls in the current video frame\r\n        this._frameId = -1;\r\n        this._updateInternalTexture();\r\n    };\r\n\r\n    private _createInternalTexture = (): void => {\r\n        if (this._texture != null) {\r\n            if (this._displayingPosterTexture) {\r\n                this._displayingPosterTexture = false;\r\n            } else {\r\n                return;\r\n            }\r\n        }\r\n\r\n        this.video.addEventListener(\"resize\", this._resizeInternalTexture);\r\n        this._resizeInternalTexture();\r\n\r\n        if (!this.video.autoplay && !this._settings.poster && !this._settings.independentVideoSource) {\r\n            const oldHandler = this.video.onplaying;\r\n            const oldMuted = this.video.muted;\r\n            this.video.muted = true;\r\n            this.video.onplaying = () => {\r\n                this.video.muted = oldMuted;\r\n                this.video.onplaying = oldHandler;\r\n                this._updateInternalTexture();\r\n                if (!this._errorFound) {\r\n                    this.video.pause();\r\n                }\r\n                if (this.onLoadObservable.hasObservers()) {\r\n                    this.onLoadObservable.notifyObservers(this);\r\n                }\r\n            };\r\n            this._handlePlay();\r\n        } else {\r\n            this._updateInternalTexture();\r\n            if (this.onLoadObservable.hasObservers()) {\r\n                this.onLoadObservable.notifyObservers(this);\r\n            }\r\n        }\r\n    };\r\n\r\n    private _reset = (): void => {\r\n        if (this._texture == null) {\r\n            return;\r\n        }\r\n\r\n        if (!this._displayingPosterTexture) {\r\n            this._texture.dispose();\r\n            this._texture = null;\r\n        }\r\n    };\r\n\r\n    /**\r\n     * @internal Internal method to initiate `update`.\r\n     */\r\n    public override _rebuild(): void {\r\n        this.update();\r\n    }\r\n\r\n    /**\r\n     * Update Texture in the `auto` mode. Does not do anything if `settings.autoUpdateTexture` is false.\r\n     */\r\n    public update(): void {\r\n        if (!this.autoUpdateTexture) {\r\n            // Expecting user to call `updateTexture` manually\r\n            return;\r\n        }\r\n\r\n        this.updateTexture(true);\r\n    }\r\n\r\n    /**\r\n     * Update Texture in `manual` mode. Does not do anything if not visible or paused.\r\n     * @param isVisible Visibility state, detected by user using `scene.getActiveMeshes()` or otherwise.\r\n     */\r\n    public updateTexture(isVisible: boolean): void {\r\n        if (!isVisible) {\r\n            return;\r\n        }\r\n        if (this.video.paused && this._stillImageCaptured) {\r\n            return;\r\n        }\r\n        this._stillImageCaptured = true;\r\n        this._updateInternalTexture();\r\n    }\r\n\r\n    private _updateWhileSnapshotRendering = (): void => {\r\n        const engine = this._engine;\r\n        if (engine && engine.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\r\n            this.update();\r\n        }\r\n    };\r\n\r\n    private _resetSnapshotRenderingIfFast(): void {\r\n        const engine = this._engine as Nullable<WebGPUEngine>;\r\n        if (engine?.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\r\n            engine.snapshotRenderingReset();\r\n        }\r\n    }\r\n\r\n    protected _updateInternalTexture = (): void => {\r\n        if (this._texture == null) {\r\n            return;\r\n        }\r\n        if (this.video.readyState < this.video.HAVE_CURRENT_DATA) {\r\n            return;\r\n        }\r\n        if (this._displayingPosterTexture) {\r\n            return;\r\n        }\r\n\r\n        const frameId = this.getScene()!.getFrameId();\r\n        if (this._frameId === frameId) {\r\n            return;\r\n        }\r\n\r\n        this._frameId = frameId;\r\n\r\n        this._getEngine()!.updateVideoTexture(this._texture, this._externalTexture ? this._externalTexture : this.video, this._invertY);\r\n    };\r\n\r\n    /**\r\n     * Get the underlying external texture (if supported by the current engine, else null)\r\n     */\r\n    public get externalTexture(): Nullable<ExternalTexture> {\r\n        return this._externalTexture;\r\n    }\r\n\r\n    /**\r\n     * Change video content. Changing video instance or setting multiple urls (as in constructor) is not supported.\r\n     * @param url New url.\r\n     */\r\n    public override updateURL(url: string): void {\r\n        this.video.src = url;\r\n        this._currentSrc = url;\r\n    }\r\n\r\n    /**\r\n     * Clones the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): VideoTexture {\r\n        return new VideoTexture(this.name, this._currentSrc!, this.getScene(), this._generateMipMaps, this.invertY, this.samplingMode, this._settings);\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        if (this._snapshotRenderingObserver) {\r\n            // Remove the per-frame snapshot rendering hook before super.dispose() clears the scene reference.\r\n            this.getScene()?.onBeforeRenderObservable.remove(this._snapshotRenderingObserver);\r\n            this._snapshotRenderingObserver = null;\r\n        }\r\n\r\n        super.dispose();\r\n\r\n        this._currentSrc = null;\r\n\r\n        if (this._onUserActionRequestedObservable) {\r\n            this._onUserActionRequestedObservable.clear();\r\n            this._onUserActionRequestedObservable = null;\r\n        }\r\n\r\n        this.video.removeEventListener(this._createInternalTextureOnEvent, this._createInternalTexture);\r\n        if (!this._settings.independentVideoSource) {\r\n            this.video.removeEventListener(\"paused\", this._updateInternalTexture);\r\n            this.video.removeEventListener(\"seeked\", this._updateInternalTexture);\r\n            this.video.removeEventListener(\"loadeddata\", this._updateInternalTexture);\r\n            this.video.removeEventListener(\"emptied\", this._reset);\r\n            this.video.removeEventListener(\"resize\", this._resizeInternalTexture);\r\n            this.video.pause();\r\n        }\r\n\r\n        this._externalTexture?.dispose();\r\n    }\r\n\r\n    /**\r\n     * Creates a video texture straight from a stream.\r\n     * @param scene Define the scene the texture should be created in\r\n     * @param stream Define the stream the texture should be created from\r\n     * @param constraints video constraints\r\n     * @param invertY Defines if the video should be stored with invert Y set to true (true by default)\r\n     * @returns The created video texture as a promise\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static CreateFromStreamAsync(scene: Scene, stream: MediaStream, constraints: any, invertY = true): Promise<VideoTexture> {\r\n        const video = scene.getEngine().createVideoElement(constraints);\r\n\r\n        if (scene.getEngine()._badOS) {\r\n            // Yes... I know and I hope to remove it soon...\r\n            document.body.appendChild(video);\r\n            video.style.transform = \"scale(0.0001, 0.0001)\";\r\n            video.style.opacity = \"0\";\r\n            video.style.position = \"fixed\";\r\n            video.style.bottom = \"0px\";\r\n            video.style.right = \"0px\";\r\n        }\r\n\r\n        video.setAttribute(\"autoplay\", \"\");\r\n        video.setAttribute(\"muted\", \"true\");\r\n        video.setAttribute(\"playsinline\", \"\");\r\n        video.muted = true;\r\n\r\n        if (video.isNative) {\r\n            // No additional configuration needed for native\r\n        } else {\r\n            if (typeof video.srcObject == \"object\") {\r\n                video.srcObject = stream;\r\n            } else {\r\n                // older API. See https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL#using_object_urls_for_media_streams\r\n                video.src = window.URL && window.URL.createObjectURL(stream as any);\r\n            }\r\n        }\r\n\r\n        return new Promise<VideoTexture>((resolve) => {\r\n            const onPlaying = () => {\r\n                const videoTexture = new VideoTexture(\"video\", video, scene, true, invertY, undefined, undefined, undefined, Constants.TEXTUREFORMAT_RGB);\r\n                if (scene.getEngine()._badOS) {\r\n                    videoTexture.onDisposeObservable.addOnce(() => {\r\n                        video.remove();\r\n                    });\r\n                }\r\n                videoTexture.onDisposeObservable.addOnce(() => {\r\n                    RemoveSource(video);\r\n                });\r\n\r\n                resolve(videoTexture);\r\n                video.removeEventListener(\"playing\", onPlaying);\r\n            };\r\n\r\n            video.addEventListener(\"playing\", onPlaying);\r\n            video.play();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a video texture straight from your WebCam video feed.\r\n     * @param scene Define the scene the texture should be created in\r\n     * @param constraints Define the constraints to use to create the web cam feed from WebRTC\r\n     * @param audioConstaints Define the audio constraints to use to create the web cam feed from WebRTC\r\n     * @param invertY Defines if the video should be stored with invert Y set to true (true by default)\r\n     * @returns The created video texture as a promise\r\n     */\r\n    public static async CreateFromWebCamAsync(\r\n        scene: Scene,\r\n        constraints: {\r\n            minWidth: number;\r\n            maxWidth: number;\r\n            minHeight: number;\r\n            maxHeight: number;\r\n            deviceId: string;\r\n        } & MediaTrackConstraints,\r\n        audioConstaints: boolean | MediaTrackConstraints = false,\r\n        invertY = true\r\n    ): Promise<VideoTexture> {\r\n        if (navigator.mediaDevices) {\r\n            const stream = await navigator.mediaDevices.getUserMedia({\r\n                video: constraints,\r\n                audio: audioConstaints,\r\n            });\r\n\r\n            const videoTexture = await this.CreateFromStreamAsync(scene, stream, constraints, invertY);\r\n            videoTexture.onDisposeObservable.addOnce(() => {\r\n                const tracks = stream.getTracks();\r\n                for (const track of tracks) {\r\n                    track.stop();\r\n                }\r\n            });\r\n\r\n            return videoTexture;\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/return-await, @typescript-eslint/prefer-promise-reject-errors\r\n        return Promise.reject(\"No support for userMedia on this device\");\r\n    }\r\n\r\n    /**\r\n     * Creates a video texture straight from your WebCam video feed.\r\n     * @param scene Defines the scene the texture should be created in\r\n     * @param onReady Defines a callback to triggered once the texture will be ready\r\n     * @param constraints Defines the constraints to use to create the web cam feed from WebRTC\r\n     * @param audioConstaints Defines the audio constraints to use to create the web cam feed from WebRTC\r\n     * @param invertY Defines if the video should be stored with invert Y set to true (true by default)\r\n     */\r\n    public static CreateFromWebCam(\r\n        scene: Scene,\r\n        onReady: (videoTexture: VideoTexture) => void,\r\n        constraints: {\r\n            minWidth: number;\r\n            maxWidth: number;\r\n            minHeight: number;\r\n            maxHeight: number;\r\n            deviceId: string;\r\n        } & MediaTrackConstraints,\r\n        audioConstaints: boolean | MediaTrackConstraints = false,\r\n        invertY = true\r\n    ): void {\r\n        this.CreateFromWebCamAsync(scene, constraints, audioConstaints, invertY)\r\n            // eslint-disable-next-line github/no-then\r\n            .then(function (videoTexture) {\r\n                if (onReady) {\r\n                    onReady(videoTexture);\r\n                }\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .catch(function (err) {\r\n                Logger.Error(err.name);\r\n            });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for videoTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVideoTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Texture._CreateVideoTexture = (\r\n        name: Nullable<string>,\r\n        src: string | string[] | HTMLVideoElement,\r\n        scene: Nullable<Scene>,\r\n        generateMipMaps = false,\r\n        invertY = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        settings: Partial<VideoTextureSettings> = {},\r\n        onError?: Nullable<(message?: string, exception?: any) => void>,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA\r\n    ) => {\r\n        return new VideoTexture(name, src, scene, generateMipMaps, invertY, samplingMode, settings, onError, format);\r\n    };\r\n\r\n    // Some exporters relies on Tools.Instantiate\r\n    RegisterClass(\"BABYLON.VideoTexture\", VideoTexture);\r\n}\r\n","import { type Scene } from \"../scene\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type VideoTextureSettings, VideoTexture } from \"../Materials/Textures/videoTexture.pure\";\r\nimport { TextureDome } from \"./textureDome\";\r\nimport { type PointerInfo, PointerEventTypes } from \"../Events/pointerEvents\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer } from \"../Misc/observable\";\r\n\r\n/**\r\n * Display a 360/180 degree video on an approximately spherical surface, useful for VR applications or skyboxes.\r\n * As a subclass of TransformNode, this allow parenting to the camera or multiple videos with different locations in the scene.\r\n * This class achieves its effect with a VideoTexture and a correctly configured BackgroundMaterial on an inverted sphere.\r\n * Potential additions to this helper include zoom and and non-infinite distance rendering effects.\r\n */\r\nexport class VideoDome extends TextureDome<VideoTexture> {\r\n    /**\r\n     * Define the video source as a Monoscopic panoramic 360 video.\r\n     */\r\n    public static override readonly MODE_MONOSCOPIC = TextureDome.MODE_MONOSCOPIC;\r\n    /**\r\n     * Define the video source as a Stereoscopic TopBottom/OverUnder panoramic 360 video.\r\n     */\r\n    public static override readonly MODE_TOPBOTTOM = TextureDome.MODE_TOPBOTTOM;\r\n    /**\r\n     * Define the video source as a Stereoscopic Side by Side panoramic 360 video.\r\n     */\r\n    public static override readonly MODE_SIDEBYSIDE = TextureDome.MODE_SIDEBYSIDE;\r\n\r\n    /**\r\n     * Get the video texture associated with this video dome\r\n     */\r\n    public get videoTexture(): VideoTexture {\r\n        return this._texture;\r\n    }\r\n    /**\r\n     * Get the video mode of this dome\r\n     */\r\n    public get videoMode(): number {\r\n        return this.textureMode;\r\n    }\r\n    /**\r\n     * Set the video mode of this dome.\r\n     * @see textureMode\r\n     */\r\n    public set videoMode(value: number) {\r\n        this.textureMode = value;\r\n    }\r\n\r\n    private _pointerObserver: Nullable<Observer<PointerInfo>>;\r\n    private _textureObserver: Nullable<Observer<Texture>>;\r\n\r\n    protected _initTexture(urlsOrElement: string | string[] | HTMLVideoElement, scene: Scene, options: any): VideoTexture {\r\n        const tempOptions: VideoTextureSettings = { loop: options.loop, autoPlay: options.autoPlay, autoUpdateTexture: true, poster: options.poster };\r\n        const texture = new VideoTexture(\r\n            (this.name || \"videoDome\") + \"_texture\",\r\n            urlsOrElement,\r\n            scene,\r\n            options.generateMipMaps,\r\n            this._useDirectMapping,\r\n            Texture.TRILINEAR_SAMPLINGMODE,\r\n            tempOptions\r\n        );\r\n        // optional configuration\r\n        if (options.clickToPlay) {\r\n            this._pointerObserver = scene.onPointerObservable.add((data) => {\r\n                if (data.pickInfo?.pickedMesh === this.mesh) {\r\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n                    this._texture.video.play();\r\n                }\r\n            }, PointerEventTypes.POINTERDOWN);\r\n        }\r\n        this._textureObserver = texture.onLoadObservable.add(() => {\r\n            this.onLoadObservable.notifyObservers();\r\n        });\r\n        return texture;\r\n    }\r\n\r\n    /**\r\n     * Releases resources associated with this node.\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false): void {\r\n        this._texture.onLoadObservable.remove(this._textureObserver);\r\n        this._scene.onPointerObservable.remove(this._pointerObserver);\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n}\r\n","import { Vector2 } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * Given the control points, solve for x based on a given t for a cubic bezier curve\r\n * @param t a value between 0 and 1\r\n * @param p0 first control point\r\n * @param p1 second control point\r\n * @param p2 third control point\r\n * @param p3 fourth control point\r\n * @returns number result of cubic bezier curve at the specified t\r\n */\r\nfunction CubicBezierCurve(t: number, p0: number, p1: number, p2: number, p3: number): number {\r\n    return (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3;\r\n}\r\n\r\n/**\r\n * Evaluates a specified specular power value to determine the appropriate roughness value,\r\n * based on a pre-defined cubic bezier curve with specular on the abscissa axis (x-axis)\r\n * and roughness on the ordinant axis (y-axis)\r\n * @param specularPower specular power of standard material\r\n * @param p0 first control point\r\n * @param p1 second control point\r\n * @param p2 third control point\r\n * @param p3 fourth control point\r\n * @returns Number representing the roughness value\r\n */\r\nexport function SpecularPowerToRoughness(specularPower: number, p0 = new Vector2(0, 1), p1 = new Vector2(0, 0.1), p2 = new Vector2(0, 0.1), p3 = new Vector2(1300, 0.1)): number {\r\n    // Given P0.x = 0, P1.x = 0, P2.x = 0\r\n    //   x = t * t * t * P3.x\r\n    //   t = (x / P3.x)^(1/3)\r\n    const t = Math.pow(specularPower / p3.x, 0.333333);\r\n    return CubicBezierCurve(t, p0.y, p1.y, p2.y, p3.y);\r\n}\r\n","import { type Observer } from \"../Misc/observable\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type IDisposable } from \"../scene\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\n/**\r\n * This class can be used to get instrumentation data from a Babylon engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n */\r\nexport class EngineInstrumentation implements IDisposable {\r\n    private _captureGPUFrameTime = false;\r\n\r\n    private _captureShaderCompilationTime = false;\r\n    private _shaderCompilationTime = new PerfCounter();\r\n\r\n    // Observers\r\n    private _onBeginFrameObserver: Nullable<Observer<AbstractEngine>> = null;\r\n    private _onEndFrameObserver: Nullable<Observer<AbstractEngine>> = null;\r\n    private _onBeforeShaderCompilationObserver: Nullable<Observer<AbstractEngine>> = null;\r\n    private _onAfterShaderCompilationObserver: Nullable<Observer<AbstractEngine>> = null;\r\n\r\n    private _disposed = false;\r\n\r\n    // Properties\r\n    /**\r\n     * Gets the perf counter used for GPU frame time\r\n     */\r\n    public get gpuFrameTimeCounter(): PerfCounter {\r\n        return this.engine.getGPUFrameTimeCounter();\r\n    }\r\n\r\n    /**\r\n     * Gets the GPU frame time capture status\r\n     */\r\n    public get captureGPUFrameTime(): boolean {\r\n        return this._captureGPUFrameTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the GPU frame time capture\r\n     */\r\n    public set captureGPUFrameTime(value: boolean) {\r\n        if (value === this._captureGPUFrameTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureGPUFrameTime = value;\r\n        this.engine.captureGPUFrameTime(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for shader compilation time\r\n     */\r\n    public get shaderCompilationTimeCounter(): PerfCounter {\r\n        return this._shaderCompilationTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the shader compilation time capture status\r\n     */\r\n    public get captureShaderCompilationTime(): boolean {\r\n        return this._captureShaderCompilationTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the shader compilation time capture\r\n     */\r\n    public set captureShaderCompilationTime(value: boolean) {\r\n        if (value === this._captureShaderCompilationTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureShaderCompilationTime = value;\r\n\r\n        if (value) {\r\n            this._onBeforeShaderCompilationObserver = this.engine.onBeforeShaderCompilationObservable.add(() => {\r\n                this._shaderCompilationTime.fetchNewFrame();\r\n                this._shaderCompilationTime.beginMonitoring();\r\n            });\r\n\r\n            this._onAfterShaderCompilationObserver = this.engine.onAfterShaderCompilationObservable.add(() => {\r\n                this._shaderCompilationTime.endMonitoring(false);\r\n                this._shaderCompilationTime.endFrame();\r\n            });\r\n        } else {\r\n            this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);\r\n            this._onBeforeShaderCompilationObserver = null;\r\n            this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);\r\n            this._onAfterShaderCompilationObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new engine instrumentation.\r\n     * This class can be used to get instrumentation data from a Babylon engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n     * @param engine Defines the engine to instrument\r\n     */\r\n    public constructor(\r\n        /**\r\n         * Define the instrumented engine.\r\n         */\r\n        public engine: AbstractEngine\r\n    ) {}\r\n\r\n    /**\r\n     * Dispose and release associated resources.\r\n     */\r\n    public dispose() {\r\n        if (this._disposed) {\r\n            return;\r\n        }\r\n\r\n        this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);\r\n        this._onBeginFrameObserver = null;\r\n\r\n        this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);\r\n        this._onEndFrameObserver = null;\r\n\r\n        this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);\r\n        this._onBeforeShaderCompilationObserver = null;\r\n\r\n        this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);\r\n        this._onAfterShaderCompilationObserver = null;\r\n\r\n        (<any>this.engine) = null;\r\n        this._disposed = true;\r\n    }\r\n}\r\n","import { Tools } from \"../Misc/tools.pure\";\r\nimport { type Observer } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport { type ObjectRenderer } from \"../Rendering/objectRenderer\";\r\n/**\r\n * This class can be used to get instrumentation data from a Babylon engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#sceneinstrumentation\r\n */\r\nexport class SceneInstrumentation implements IDisposable {\r\n    private _captureActiveMeshesEvaluationTime = false;\r\n    private _activeMeshesEvaluationTime = new PerfCounter();\r\n\r\n    private _captureRenderTargetsRenderTime = false;\r\n    private _renderTargetsRenderTime = new PerfCounter();\r\n\r\n    private _captureFrameTime = false;\r\n    private _frameTime = new PerfCounter();\r\n\r\n    private _captureRenderTime = false;\r\n    private _renderTime = new PerfCounter();\r\n\r\n    private _captureInterFrameTime = false;\r\n    private _interFrameTime = new PerfCounter();\r\n\r\n    private _captureParticlesRenderTime = false;\r\n    private _particlesRenderTime = new PerfCounter();\r\n\r\n    private _captureSpritesRenderTime = false;\r\n    private _spritesRenderTime = new PerfCounter();\r\n\r\n    private _capturePhysicsTime = false;\r\n    private _physicsTime = new PerfCounter();\r\n\r\n    private _captureAnimationsTime = false;\r\n    private _animationsTime = new PerfCounter();\r\n\r\n    private _captureCameraRenderTime = false;\r\n    private _cameraRenderTime = new PerfCounter();\r\n\r\n    // Observers\r\n    private _onBeforeActiveMeshesEvaluationObserver: Nullable<Observer<Scene>> = null;\r\n    private _onAfterActiveMeshesEvaluationObserver: Nullable<Observer<Scene>> = null;\r\n    private _onBeforeRenderTargetsRenderObserver: Nullable<Observer<ObjectRenderer>>[] = [];\r\n    private _onAfterRenderTargetsRenderObserver: Nullable<Observer<ObjectRenderer>>[] = [];\r\n\r\n    private _onAfterRenderObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    private _onBeforeDrawPhaseObserver: Nullable<Observer<Scene> | Observer<number>>[] = [];\r\n    private _onAfterDrawPhaseObserver: Nullable<Observer<Scene> | Observer<number>>[] = [];\r\n\r\n    private _onBeforeAnimationsObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    private _onBeforeParticlesRenderingObserver: Nullable<Observer<Scene>> = null;\r\n    private _onAfterParticlesRenderingObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    private _onBeforeSpritesRenderingObserver: Nullable<Observer<Scene>> = null;\r\n    private _onAfterSpritesRenderingObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    private _onBeforePhysicsObserver: Nullable<Observer<Scene>> = null;\r\n    private _onAfterPhysicsObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    private _onAfterAnimationsObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    private _onBeforeCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n    private _onAfterCameraRenderObserver: Nullable<Observer<Camera>> = null;\r\n\r\n    private _disposed = false;\r\n\r\n    // Properties\r\n    /**\r\n     * Gets the perf counter used for active meshes evaluation time\r\n     */\r\n    public get activeMeshesEvaluationTimeCounter(): PerfCounter {\r\n        return this._activeMeshesEvaluationTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the active meshes evaluation time capture status\r\n     */\r\n    public get captureActiveMeshesEvaluationTime(): boolean {\r\n        return this._captureActiveMeshesEvaluationTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the active meshes evaluation time capture\r\n     */\r\n    public set captureActiveMeshesEvaluationTime(value: boolean) {\r\n        if (value === this._captureActiveMeshesEvaluationTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureActiveMeshesEvaluationTime = value;\r\n\r\n        if (value) {\r\n            this._onBeforeActiveMeshesEvaluationObserver = this.scene.onBeforeActiveMeshesEvaluationObservable.add(() => {\r\n                Tools.StartPerformanceCounter(\"Active meshes evaluation\");\r\n                this._activeMeshesEvaluationTime.beginMonitoring();\r\n            });\r\n\r\n            this._onAfterActiveMeshesEvaluationObserver = this.scene.onAfterActiveMeshesEvaluationObservable.add(() => {\r\n                Tools.EndPerformanceCounter(\"Active meshes evaluation\");\r\n                this._activeMeshesEvaluationTime.endMonitoring(false);\r\n            });\r\n        } else {\r\n            this.scene.onBeforeActiveMeshesEvaluationObservable.remove(this._onBeforeActiveMeshesEvaluationObserver);\r\n            this._onBeforeActiveMeshesEvaluationObserver = null;\r\n\r\n            this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);\r\n            this._onAfterActiveMeshesEvaluationObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for render targets render time\r\n     */\r\n    public get renderTargetsRenderTimeCounter(): PerfCounter {\r\n        return this._renderTargetsRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the render targets render time capture status\r\n     */\r\n    public get captureRenderTargetsRenderTime(): boolean {\r\n        return this._captureRenderTargetsRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the render targets render time capture\r\n     */\r\n    public set captureRenderTargetsRenderTime(value: boolean) {\r\n        if (value === this._captureRenderTargetsRenderTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureRenderTargetsRenderTime = value;\r\n\r\n        if (value) {\r\n            for (const objectRenderer of this.scene.objectRenderers) {\r\n                this._onBeforeRenderTargetsRenderObserver.push(\r\n                    objectRenderer.onInitRenderingObservable.add(() => {\r\n                        Tools.StartPerformanceCounter(\"Render targets rendering\");\r\n                        this._renderTargetsRenderTime.beginMonitoring();\r\n                    })\r\n                );\r\n                this._onAfterRenderTargetsRenderObserver.push(\r\n                    objectRenderer.onFinishRenderingObservable.add(() => {\r\n                        Tools.EndPerformanceCounter(\"Render targets rendering\");\r\n                        this._renderTargetsRenderTime.endMonitoring(false);\r\n                    })\r\n                );\r\n            }\r\n        } else {\r\n            for (let i = 0; i < this.scene.objectRenderers.length; ++i) {\r\n                const objectRenderer = this.scene.objectRenderers[i];\r\n                objectRenderer.onInitRenderingObservable.remove(this._onBeforeRenderTargetsRenderObserver[i]);\r\n                objectRenderer.onFinishRenderingObservable.remove(this._onAfterRenderTargetsRenderObserver[i]);\r\n            }\r\n            this._onBeforeRenderTargetsRenderObserver.length = 0;\r\n            this._onAfterRenderTargetsRenderObserver.length = 0;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for particles render time\r\n     */\r\n    public get particlesRenderTimeCounter(): PerfCounter {\r\n        return this._particlesRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the particles render time capture status\r\n     */\r\n    public get captureParticlesRenderTime(): boolean {\r\n        return this._captureParticlesRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the particles render time capture\r\n     */\r\n    public set captureParticlesRenderTime(value: boolean) {\r\n        if (value === this._captureParticlesRenderTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureParticlesRenderTime = value;\r\n\r\n        if (value) {\r\n            this._onBeforeParticlesRenderingObserver = this.scene.onBeforeParticlesRenderingObservable.add(() => {\r\n                Tools.StartPerformanceCounter(\"Particles\");\r\n                this._particlesRenderTime.beginMonitoring();\r\n            });\r\n\r\n            this._onAfterParticlesRenderingObserver = this.scene.onAfterParticlesRenderingObservable.add(() => {\r\n                Tools.EndPerformanceCounter(\"Particles\");\r\n                this._particlesRenderTime.endMonitoring(false);\r\n            });\r\n        } else {\r\n            this.scene.onBeforeParticlesRenderingObservable.remove(this._onBeforeParticlesRenderingObserver);\r\n            this._onBeforeParticlesRenderingObserver = null;\r\n\r\n            this.scene.onAfterParticlesRenderingObservable.remove(this._onAfterParticlesRenderingObserver);\r\n            this._onAfterParticlesRenderingObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for sprites render time\r\n     */\r\n    public get spritesRenderTimeCounter(): PerfCounter {\r\n        return this._spritesRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the sprites render time capture status\r\n     */\r\n    public get captureSpritesRenderTime(): boolean {\r\n        return this._captureSpritesRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the sprites render time capture\r\n     */\r\n    public set captureSpritesRenderTime(value: boolean) {\r\n        if (value === this._captureSpritesRenderTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureSpritesRenderTime = value;\r\n\r\n        if (!this.scene.spriteManagers) {\r\n            return;\r\n        }\r\n\r\n        if (value) {\r\n            this._onBeforeSpritesRenderingObserver = this.scene.onBeforeSpritesRenderingObservable.add(() => {\r\n                Tools.StartPerformanceCounter(\"Sprites\");\r\n                this._spritesRenderTime.beginMonitoring();\r\n            });\r\n\r\n            this._onAfterSpritesRenderingObserver = this.scene.onAfterSpritesRenderingObservable.add(() => {\r\n                Tools.EndPerformanceCounter(\"Sprites\");\r\n                this._spritesRenderTime.endMonitoring(false);\r\n            });\r\n        } else {\r\n            this.scene.onBeforeSpritesRenderingObservable.remove(this._onBeforeSpritesRenderingObserver);\r\n            this._onBeforeSpritesRenderingObserver = null;\r\n\r\n            this.scene.onAfterSpritesRenderingObservable.remove(this._onAfterSpritesRenderingObserver);\r\n            this._onAfterSpritesRenderingObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for physics time\r\n     */\r\n    public get physicsTimeCounter(): PerfCounter {\r\n        return this._physicsTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the physics time capture status\r\n     */\r\n    public get capturePhysicsTime(): boolean {\r\n        return this._capturePhysicsTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the physics time capture\r\n     */\r\n    public set capturePhysicsTime(value: boolean) {\r\n        if (value === this._capturePhysicsTime) {\r\n            return;\r\n        }\r\n\r\n        if (!this.scene.onBeforePhysicsObservable) {\r\n            return;\r\n        }\r\n\r\n        this._capturePhysicsTime = value;\r\n\r\n        if (value) {\r\n            this._onBeforePhysicsObserver = this.scene.onBeforePhysicsObservable.add(() => {\r\n                Tools.StartPerformanceCounter(\"Physics\");\r\n                this._physicsTime.beginMonitoring();\r\n            });\r\n\r\n            this._onAfterPhysicsObserver = this.scene.onAfterPhysicsObservable.add(() => {\r\n                Tools.EndPerformanceCounter(\"Physics\");\r\n                this._physicsTime.endMonitoring();\r\n            });\r\n        } else {\r\n            this.scene.onBeforePhysicsObservable.remove(this._onBeforePhysicsObserver);\r\n            this._onBeforePhysicsObserver = null;\r\n\r\n            this.scene.onAfterPhysicsObservable.remove(this._onAfterPhysicsObserver);\r\n            this._onAfterPhysicsObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for animations time\r\n     */\r\n    public get animationsTimeCounter(): PerfCounter {\r\n        return this._animationsTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the animations time capture status\r\n     */\r\n    public get captureAnimationsTime(): boolean {\r\n        return this._captureAnimationsTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the animations time capture\r\n     */\r\n    public set captureAnimationsTime(value: boolean) {\r\n        if (value === this._captureAnimationsTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureAnimationsTime = value;\r\n\r\n        if (value) {\r\n            this._onAfterAnimationsObserver = this.scene.onAfterAnimationsObservable.add(() => {\r\n                this._animationsTime.endMonitoring();\r\n            });\r\n        } else {\r\n            this.scene.onAfterAnimationsObservable.remove(this._onAfterAnimationsObserver);\r\n            this._onAfterAnimationsObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for frame time capture\r\n     */\r\n    public get frameTimeCounter(): PerfCounter {\r\n        return this._frameTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the frame time capture status\r\n     */\r\n    public get captureFrameTime(): boolean {\r\n        return this._captureFrameTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the frame time capture\r\n     */\r\n    public set captureFrameTime(value: boolean) {\r\n        this._captureFrameTime = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for inter-frames time capture\r\n     */\r\n    public get interFrameTimeCounter(): PerfCounter {\r\n        return this._interFrameTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the inter-frames time capture status\r\n     */\r\n    public get captureInterFrameTime(): boolean {\r\n        return this._captureInterFrameTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the inter-frames time capture\r\n     */\r\n    public set captureInterFrameTime(value: boolean) {\r\n        this._captureInterFrameTime = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for render time capture\r\n     */\r\n    public get renderTimeCounter(): PerfCounter {\r\n        return this._renderTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the render time capture status\r\n     */\r\n    public get captureRenderTime(): boolean {\r\n        return this._captureRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the render time capture\r\n     */\r\n    public set captureRenderTime(value: boolean) {\r\n        if (value === this._captureRenderTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureRenderTime = value;\r\n\r\n        if (value) {\r\n            this._onBeforeDrawPhaseObserver.push(\r\n                this.scene.onBeforeDrawPhaseObservable.add(() => {\r\n                    this._renderTime.beginMonitoring();\r\n                    Tools.StartPerformanceCounter(\"Main render\");\r\n                })\r\n            );\r\n            this._onAfterDrawPhaseObserver.push(\r\n                this.scene.onAfterDrawPhaseObservable.add(() => {\r\n                    this._renderTime.endMonitoring(false);\r\n                    Tools.EndPerformanceCounter(\"Main render\");\r\n                })\r\n            );\r\n            for (const objectRenderer of this.scene.objectRenderers) {\r\n                this._onBeforeDrawPhaseObserver.push(\r\n                    objectRenderer.onBeforeRenderingManagerRenderObservable.add(() => {\r\n                        this._renderTime.beginMonitoring();\r\n                        Tools.StartPerformanceCounter(\"Main render\");\r\n                    })\r\n                );\r\n                this._onAfterDrawPhaseObserver.push(\r\n                    objectRenderer.onAfterRenderingManagerRenderObservable.add(() => {\r\n                        this._renderTime.endMonitoring(false);\r\n                        Tools.EndPerformanceCounter(\"Main render\");\r\n                    })\r\n                );\r\n            }\r\n        } else {\r\n            this._removeRenderTimeObservers();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for camera render time capture\r\n     */\r\n    public get cameraRenderTimeCounter(): PerfCounter {\r\n        return this._cameraRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the camera render time capture status\r\n     */\r\n    public get captureCameraRenderTime(): boolean {\r\n        return this._captureCameraRenderTime;\r\n    }\r\n\r\n    /**\r\n     * Enable or disable the camera render time capture\r\n     */\r\n    public set captureCameraRenderTime(value: boolean) {\r\n        if (value === this._captureCameraRenderTime) {\r\n            return;\r\n        }\r\n\r\n        this._captureCameraRenderTime = value;\r\n\r\n        if (value) {\r\n            this._onBeforeCameraRenderObserver = this.scene.onBeforeCameraRenderObservable.add((camera) => {\r\n                this._cameraRenderTime.beginMonitoring();\r\n                Tools.StartPerformanceCounter(`Rendering camera ${camera.name}`);\r\n            });\r\n\r\n            this._onAfterCameraRenderObserver = this.scene.onAfterCameraRenderObservable.add((camera) => {\r\n                this._cameraRenderTime.endMonitoring(false);\r\n                Tools.EndPerformanceCounter(`Rendering camera ${camera.name}`);\r\n            });\r\n        } else {\r\n            this.scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);\r\n            this._onBeforeCameraRenderObserver = null;\r\n            this.scene.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);\r\n            this._onAfterCameraRenderObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the perf counter used for draw calls\r\n     */\r\n    public get drawCallsCounter(): PerfCounter {\r\n        return this.scene.getEngine()._drawCalls;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new scene instrumentation.\r\n     * This class can be used to get instrumentation data from a Babylon engine\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#sceneinstrumentation\r\n     * @param scene Defines the scene to instrument\r\n     */\r\n    public constructor(\r\n        /**\r\n         * Defines the scene to instrument\r\n         */\r\n        public scene: Scene\r\n    ) {\r\n        // Before render\r\n        this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\r\n            if (this._captureActiveMeshesEvaluationTime) {\r\n                this._activeMeshesEvaluationTime.fetchNewFrame();\r\n            }\r\n\r\n            if (this._captureRenderTargetsRenderTime) {\r\n                this._renderTargetsRenderTime.fetchNewFrame();\r\n            }\r\n\r\n            if (this._captureFrameTime) {\r\n                Tools.StartPerformanceCounter(\"Scene rendering\");\r\n                this._frameTime.beginMonitoring();\r\n            }\r\n\r\n            if (this._captureInterFrameTime) {\r\n                this._interFrameTime.endMonitoring();\r\n            }\r\n\r\n            if (this._captureParticlesRenderTime) {\r\n                this._particlesRenderTime.fetchNewFrame();\r\n            }\r\n\r\n            if (this._captureSpritesRenderTime) {\r\n                this._spritesRenderTime.fetchNewFrame();\r\n            }\r\n\r\n            if (this._captureAnimationsTime) {\r\n                this._animationsTime.beginMonitoring();\r\n            }\r\n\r\n            if (this._captureRenderTime) {\r\n                this._renderTime.fetchNewFrame();\r\n            }\r\n\r\n            if (this._captureCameraRenderTime) {\r\n                this._cameraRenderTime.fetchNewFrame();\r\n            }\r\n\r\n            this.scene.getEngine()._drawCalls.fetchNewFrame();\r\n        });\r\n\r\n        // After render\r\n        this._onAfterRenderObserver = scene.onAfterRenderObservable.add(() => {\r\n            if (this._captureFrameTime) {\r\n                Tools.EndPerformanceCounter(\"Scene rendering\");\r\n                this._frameTime.endMonitoring();\r\n            }\r\n\r\n            if (this._captureRenderTime) {\r\n                this._renderTime.endMonitoring(false);\r\n            }\r\n\r\n            if (this._captureInterFrameTime) {\r\n                this._interFrameTime.beginMonitoring();\r\n            }\r\n\r\n            if (this._captureActiveMeshesEvaluationTime) {\r\n                this._activeMeshesEvaluationTime.endFrame();\r\n            }\r\n            if (this._captureRenderTargetsRenderTime) {\r\n                this._renderTargetsRenderTime.endFrame();\r\n            }\r\n            if (this._captureParticlesRenderTime) {\r\n                this._particlesRenderTime.endFrame();\r\n            }\r\n            if (this._captureSpritesRenderTime) {\r\n                this._spritesRenderTime.endFrame();\r\n            }\r\n            if (this._captureRenderTime) {\r\n                this._renderTime.endFrame();\r\n            }\r\n            if (this._captureCameraRenderTime) {\r\n                this._cameraRenderTime.endFrame();\r\n            }\r\n        });\r\n    }\r\n\r\n    private _removeRenderTargetsObservers() {\r\n        for (let i = 0; i < this.scene.objectRenderers.length; ++i) {\r\n            const objectRenderer = this.scene.objectRenderers[i];\r\n            objectRenderer.onInitRenderingObservable.remove(this._onBeforeRenderTargetsRenderObserver[i]);\r\n            objectRenderer.onFinishRenderingObservable.remove(this._onAfterRenderTargetsRenderObserver[i]);\r\n        }\r\n        this._onBeforeRenderTargetsRenderObserver.length = 0;\r\n        this._onAfterRenderTargetsRenderObserver.length = 0;\r\n    }\r\n\r\n    private _removeRenderTimeObservers() {\r\n        this.scene.onBeforeDrawPhaseObservable.remove(this._onBeforeDrawPhaseObserver[0] as Observer<Scene>);\r\n        this._onBeforeDrawPhaseObserver.length = 0;\r\n        this.scene.onAfterDrawPhaseObservable.remove(this._onAfterDrawPhaseObserver[0] as Observer<Scene>);\r\n        this._onAfterDrawPhaseObserver.length = 0;\r\n        for (let i = 1; i < this._onBeforeDrawPhaseObserver.length; i++) {\r\n            const objectRenderer = this.scene.objectRenderers[i - 1];\r\n            objectRenderer.onBeforeRenderingManagerRenderObservable.remove(this._onBeforeDrawPhaseObserver[i] as Observer<number>);\r\n            objectRenderer.onAfterRenderingManagerRenderObservable.remove(this._onAfterDrawPhaseObserver[i] as Observer<number>);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose and release associated resources.\r\n     */\r\n    public dispose() {\r\n        if (this._disposed) {\r\n            return;\r\n        }\r\n\r\n        this.scene.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n        this._onAfterRenderObserver = null;\r\n\r\n        this.scene.onBeforeActiveMeshesEvaluationObservable.remove(this._onBeforeActiveMeshesEvaluationObserver);\r\n        this._onBeforeActiveMeshesEvaluationObserver = null;\r\n\r\n        this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);\r\n        this._onAfterActiveMeshesEvaluationObserver = null;\r\n\r\n        this._removeRenderTargetsObservers();\r\n\r\n        this.scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);\r\n        this._onBeforeAnimationsObserver = null;\r\n\r\n        this.scene.onBeforeParticlesRenderingObservable.remove(this._onBeforeParticlesRenderingObserver);\r\n        this._onBeforeParticlesRenderingObserver = null;\r\n\r\n        this.scene.onAfterParticlesRenderingObservable.remove(this._onAfterParticlesRenderingObserver);\r\n        this._onAfterParticlesRenderingObserver = null;\r\n\r\n        if (this._onBeforeSpritesRenderingObserver) {\r\n            this.scene.onBeforeSpritesRenderingObservable.remove(this._onBeforeSpritesRenderingObserver);\r\n            this._onBeforeSpritesRenderingObserver = null;\r\n        }\r\n\r\n        if (this._onAfterSpritesRenderingObserver) {\r\n            this.scene.onAfterSpritesRenderingObservable.remove(this._onAfterSpritesRenderingObserver);\r\n            this._onAfterSpritesRenderingObserver = null;\r\n        }\r\n\r\n        this._removeRenderTimeObservers();\r\n\r\n        if (this._onBeforePhysicsObserver) {\r\n            this.scene.onBeforePhysicsObservable.remove(this._onBeforePhysicsObserver);\r\n            this._onBeforePhysicsObserver = null;\r\n        }\r\n\r\n        if (this._onAfterPhysicsObserver) {\r\n            this.scene.onAfterPhysicsObservable.remove(this._onAfterPhysicsObserver);\r\n            this._onAfterPhysicsObserver = null;\r\n        }\r\n\r\n        this.scene.onAfterAnimationsObservable.remove(this._onAfterAnimationsObserver);\r\n        this._onAfterAnimationsObserver = null;\r\n\r\n        this.scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);\r\n        this._onBeforeCameraRenderObserver = null;\r\n\r\n        this.scene.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);\r\n        this._onAfterCameraRenderObserver = null;\r\n\r\n        (<any>this.scene) = null;\r\n        this._disposed = true;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { SceneComponentConstants, type ISceneSerializableComponent } from \"../sceneComponent\";\r\n\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type EffectLayer } from \"./effectLayer\";\r\nimport { type AssetContainer } from \"../assetContainer\";\r\nimport { AddParser } from \"core/Loading/Plugins/babylonFileParser.function\";\r\n\r\n/**\r\n * Defines the layer scene component responsible to manage any effect layers\r\n * in a given scene.\r\n */\r\nexport class EffectLayerSceneComponent implements ISceneSerializableComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_EFFECTLAYER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    private _engine: AbstractEngine;\r\n    private _renderEffects = false;\r\n    private _needStencil = false;\r\n    private _previousStencilState = false;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene?: Scene) {\r\n        this.scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!this.scene) {\r\n            return;\r\n        }\r\n        this._engine = this.scene.getEngine();\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._isReadyForMeshStage.registerStep(SceneComponentConstants.STEP_ISREADYFORMESH_EFFECTLAYER, this, this._isReadyForMesh);\r\n\r\n        this.scene._cameraDrawRenderTargetStage.registerStep(SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER, this, this._renderMainTexture);\r\n\r\n        this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER, this, this._setStencil);\r\n\r\n        this.scene._afterRenderingGroupDrawStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW, this, this._drawRenderingGroup);\r\n\r\n        this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER, this, this._setStencilBack);\r\n        this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW, this, this._drawCamera);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        const layers = this.scene.effectLayers;\r\n        for (const effectLayer of layers) {\r\n            effectLayer._rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the component data to the specified json object\r\n     * @param serializationObject The object to serialize to\r\n     */\r\n    public serialize(serializationObject: any): void {\r\n        // Effect layers\r\n        serializationObject.effectLayers = [];\r\n\r\n        const layers = this.scene.effectLayers;\r\n        for (const effectLayer of layers) {\r\n            if (effectLayer.serialize) {\r\n                serializationObject.effectLayers.push(effectLayer.serialize());\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     * @param container the container holding the elements\r\n     */\r\n    public addFromContainer(container: IAssetContainer): void {\r\n        if (!container.effectLayers) {\r\n            return;\r\n        }\r\n        for (const o of container.effectLayers) {\r\n            this.scene.addEffectLayer(o);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     * @param container contains the elements to remove\r\n     * @param dispose if the removed element should be disposed (default: false)\r\n     */\r\n    public removeFromContainer(container: IAssetContainer, dispose?: boolean): void {\r\n        if (!container.effectLayers) {\r\n            return;\r\n        }\r\n        for (const o of container.effectLayers) {\r\n            this.scene.removeEffectLayer(o);\r\n            if (dispose) {\r\n                o.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        const layers = this.scene.effectLayers;\r\n        while (layers.length) {\r\n            layers[0].dispose();\r\n        }\r\n    }\r\n\r\n    private _isReadyForMesh(mesh: AbstractMesh, hardwareInstancedRendering: boolean): boolean {\r\n        const currentRenderPassId = this._engine.currentRenderPassId;\r\n        const layers = this.scene.effectLayers;\r\n        for (const layer of layers) {\r\n            if (!layer.hasMesh(mesh)) {\r\n                continue;\r\n            }\r\n\r\n            const renderTarget = <RenderTargetTexture>(<any>layer)._mainTexture;\r\n            this._engine.currentRenderPassId = renderTarget.renderPassId;\r\n\r\n            for (const subMesh of mesh.subMeshes) {\r\n                if (!layer.isReady(subMesh, hardwareInstancedRendering)) {\r\n                    this._engine.currentRenderPassId = currentRenderPassId;\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n        this._engine.currentRenderPassId = currentRenderPassId;\r\n        return true;\r\n    }\r\n\r\n    private _renderMainTexture(camera: Camera): boolean {\r\n        this._renderEffects = false;\r\n        this._needStencil = false;\r\n\r\n        let needRebind = false;\r\n\r\n        const layers = this.scene.effectLayers;\r\n        if (layers && layers.length > 0) {\r\n            this._previousStencilState = this._engine.getStencilBuffer();\r\n            for (const effectLayer of layers) {\r\n                if (\r\n                    effectLayer.shouldRender() &&\r\n                    (!effectLayer.camera ||\r\n                        (effectLayer.camera.cameraRigMode === Camera.RIG_MODE_NONE && camera === effectLayer.camera) ||\r\n                        (effectLayer.camera.cameraRigMode !== Camera.RIG_MODE_NONE && effectLayer.camera._rigCameras.indexOf(camera) > -1))\r\n                ) {\r\n                    this._renderEffects = true;\r\n                    this._needStencil = this._needStencil || effectLayer.needStencil();\r\n\r\n                    const renderTarget = <RenderTargetTexture>(<any>effectLayer)._mainTexture;\r\n                    if (renderTarget._shouldRender()) {\r\n                        this.scene.incrementRenderId();\r\n                        renderTarget.render(false, false);\r\n                        needRebind = true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.scene.incrementRenderId();\r\n        }\r\n\r\n        return needRebind;\r\n    }\r\n\r\n    private _setStencil() {\r\n        // Activate effect Layer stencil\r\n        if (this._needStencil) {\r\n            this._engine.setStencilBuffer(true);\r\n        }\r\n    }\r\n\r\n    private _setStencilBack() {\r\n        // Restore effect Layer stencil\r\n        if (this._needStencil) {\r\n            this._engine.setStencilBuffer(this._previousStencilState);\r\n        }\r\n    }\r\n\r\n    private _draw(renderingGroupId: number): void {\r\n        if (this._renderEffects) {\r\n            this._engine.setDepthBuffer(false);\r\n\r\n            const layers = this.scene.effectLayers;\r\n            for (let i = 0; i < layers.length; i++) {\r\n                const effectLayer = layers[i];\r\n                if (effectLayer.renderingGroupId === renderingGroupId) {\r\n                    if (effectLayer.shouldRender()) {\r\n                        effectLayer.render();\r\n                    }\r\n                }\r\n            }\r\n            this._engine.setDepthBuffer(true);\r\n        }\r\n    }\r\n\r\n    private _drawCamera(): void {\r\n        if (this._renderEffects) {\r\n            this._draw(-1);\r\n        }\r\n    }\r\n    private _drawRenderingGroup(index: number): void {\r\n        if (!this.scene._isInIntermediateRendering() && this._renderEffects) {\r\n            this._draw(index);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for effectLayerSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param effectLayerClass The EffectLayer class to register the component for\r\n */\r\nexport function RegisterEffectLayerSceneComponent(effectLayerClass: typeof EffectLayer): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Adds the parser to the scene parsers.\r\n    AddParser(SceneComponentConstants.NAME_EFFECTLAYER, (parsedData: any, scene: Scene, container: AssetContainer, rootUrl: string) => {\r\n        if (parsedData.effectLayers) {\r\n            if (!container.effectLayers) {\r\n                container.effectLayers = [] as EffectLayer[];\r\n            }\r\n\r\n            for (let index = 0; index < parsedData.effectLayers.length; index++) {\r\n                const effectLayer = effectLayerClass.Parse(parsedData.effectLayers[index], scene, rootUrl);\r\n                container.effectLayers.push(effectLayer);\r\n            }\r\n        }\r\n    });\r\n\r\n    effectLayerClass._SceneComponentInitialization = (scene: Scene) => {\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_EFFECTLAYER) as EffectLayerSceneComponent;\r\n        if (!component) {\r\n            component = new EffectLayerSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","import { serialize, serializeAsColor4, serializeAsCameraReference } from \"../Misc/decorators\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type ISize } from \"../Maths/math.size\";\r\nimport { type Color4 } from \"../Maths/math.color\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { RegisterEffectLayerSceneComponent } from \"./effectLayerSceneComponent.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type PostProcess } from \"../PostProcesses/postProcess\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { type Material } from \"../Materials/material\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { GetExponentOfTwo } from \"../Misc/tools.functions\";\r\nimport { type ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { ThinEffectLayer } from \"./thinEffectLayer\";\r\nimport { UniqueIdGenerator } from \"core/Misc/uniqueIdGenerator\";\r\n\r\n/**\r\n * Effect layer options. This helps customizing the behaviour\r\n * of the effect layer.\r\n */\r\nexport interface IEffectLayerOptions {\r\n    /**\r\n     * Multiplication factor apply to the canvas size to compute the render target size\r\n     * used to generated the objects (the smaller the faster). Default: 0.5\r\n     */\r\n    mainTextureRatio: number;\r\n\r\n    /**\r\n     * Enforces a fixed size texture to ensure effect stability across devices. Default: undefined\r\n     */\r\n    mainTextureFixedSize?: number;\r\n\r\n    /**\r\n     * Alpha blending mode used to apply the blur. Default depends of the implementation. Default: ALPHA_COMBINE\r\n     */\r\n    alphaBlendingMode: number;\r\n\r\n    /**\r\n     * The camera attached to the layer. Default: null\r\n     */\r\n    camera: Nullable<Camera>;\r\n\r\n    /**\r\n     * The rendering group to draw the layer in. Default: -1\r\n     */\r\n    renderingGroupId: number;\r\n\r\n    /**\r\n     * The type of the main texture. Default: TEXTURETYPE_UNSIGNED_BYTE\r\n     */\r\n    mainTextureType: number;\r\n\r\n    /**\r\n     * The format of the main texture. Default: TEXTUREFORMAT_RGBA\r\n     */\r\n    mainTextureFormat: number;\r\n\r\n    /**\r\n     * Whether or not to generate a stencil buffer. Default: false\r\n     */\r\n    generateStencilBuffer: boolean;\r\n}\r\n\r\n/**\r\n * The effect layer Helps adding post process effect blended with the main pass.\r\n *\r\n * This can be for instance use to generate glow or highlight effects on the scene.\r\n *\r\n * The effect layer class can not be used directly and is intented to inherited from to be\r\n * customized per effects.\r\n */\r\nexport abstract class EffectLayer {\r\n    private _effectLayerOptions: IEffectLayerOptions;\r\n    protected _mainTextureCreatedSize: ISize = { width: 0, height: 0 };\r\n\r\n    protected _scene: Scene;\r\n    protected _engine: AbstractEngine;\r\n    protected _maxSize: number = 0;\r\n    protected _mainTextureDesiredSize: ISize = { width: 0, height: 0 };\r\n    protected _mainTexture: RenderTargetTexture;\r\n    protected get _shouldRender() {\r\n        return this._thinEffectLayer._shouldRender;\r\n    }\r\n    protected set _shouldRender(value) {\r\n        this._thinEffectLayer._shouldRender = value;\r\n    }\r\n    protected _postProcesses: PostProcess[] = [];\r\n    protected _textures: BaseTexture[] = [];\r\n    protected get _emissiveTextureAndColor(): { texture: Nullable<BaseTexture>; color: Color4 } {\r\n        return this._thinEffectLayer._emissiveTextureAndColor;\r\n    }\r\n    protected set _emissiveTextureAndColor(value) {\r\n        this._thinEffectLayer._emissiveTextureAndColor = value;\r\n    }\r\n    protected get _effectIntensity(): { [meshUniqueId: number]: number } {\r\n        return this._thinEffectLayer._effectIntensity;\r\n    }\r\n    protected set _effectIntensity(value) {\r\n        this._thinEffectLayer._effectIntensity = value;\r\n    }\r\n    protected readonly _thinEffectLayer: ThinEffectLayer;\r\n    private readonly _internalThinEffectLayer: boolean;\r\n\r\n    /**\r\n     * Force all the effect layers to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static get ForceGLSL() {\r\n        return ThinEffectLayer.ForceGLSL;\r\n    }\r\n\r\n    public static set ForceGLSL(value: boolean) {\r\n        ThinEffectLayer.ForceGLSL = value;\r\n    }\r\n\r\n    /**\r\n     * The unique id of the layer\r\n     */\r\n    public readonly uniqueId = UniqueIdGenerator.UniqueId;\r\n\r\n    /**\r\n     * The name of the layer\r\n     */\r\n    @serialize()\r\n    public get name() {\r\n        return this._thinEffectLayer.name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._thinEffectLayer.name = value;\r\n    }\r\n\r\n    /**\r\n     * The clear color of the texture used to generate the glow map.\r\n     */\r\n    @serializeAsColor4()\r\n    public get neutralColor(): Color4 {\r\n        return this._thinEffectLayer.neutralColor;\r\n    }\r\n\r\n    public set neutralColor(value: Color4) {\r\n        this._thinEffectLayer.neutralColor = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether the highlight layer is enabled or not.\r\n     */\r\n    @serialize()\r\n    public get isEnabled(): boolean {\r\n        return this._thinEffectLayer.isEnabled;\r\n    }\r\n\r\n    public set isEnabled(value: boolean) {\r\n        this._thinEffectLayer.isEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the camera attached to the layer.\r\n     */\r\n    @serializeAsCameraReference()\r\n    public get camera(): Nullable<Camera> {\r\n        return this._thinEffectLayer.camera;\r\n    }\r\n\r\n    /**\r\n     * Gets the rendering group id the layer should render in.\r\n     */\r\n    @serialize()\r\n    public get renderingGroupId(): number {\r\n        return this._thinEffectLayer.renderingGroupId;\r\n    }\r\n    public set renderingGroupId(renderingGroupId: number) {\r\n        this._thinEffectLayer.renderingGroupId = renderingGroupId;\r\n    }\r\n\r\n    /**\r\n     * Specifies if the bounding boxes should be rendered normally or if they should undergo the effect of the layer\r\n     */\r\n    @serialize()\r\n    public get disableBoundingBoxesFromEffectLayer() {\r\n        return this._thinEffectLayer.disableBoundingBoxesFromEffectLayer;\r\n    }\r\n\r\n    public set disableBoundingBoxesFromEffectLayer(value: boolean) {\r\n        this._thinEffectLayer.disableBoundingBoxesFromEffectLayer = value;\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the effect layer has been disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the effect layer is about rendering the main texture with the glowy parts.\r\n     */\r\n    public onBeforeRenderMainTextureObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the generated texture is being merged in the scene.\r\n     */\r\n    public onBeforeComposeObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the mesh is rendered into the effect render target.\r\n     */\r\n    public onBeforeRenderMeshToEffect = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * An event triggered after the mesh has been rendered into the effect render target.\r\n     */\r\n    public onAfterRenderMeshToEffect = new Observable<AbstractMesh>();\r\n\r\n    /**\r\n     * An event triggered when the generated texture has been merged in the scene.\r\n     */\r\n    public onAfterComposeObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * An event triggered when the effect layer changes its size.\r\n     */\r\n    public onSizeChangedObservable = new Observable<EffectLayer>();\r\n\r\n    /**\r\n     * Gets the main texture where the effect is rendered\r\n     */\r\n    public get mainTexture() {\r\n        return this._mainTexture;\r\n    }\r\n\r\n    protected get _shaderLanguage(): ShaderLanguage {\r\n        return this._thinEffectLayer.shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._thinEffectLayer.shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"EffectLayerSceneComponent\");\r\n    };\r\n    /**\r\n     * Sets a specific material to be used to render a mesh/a list of meshes in the layer\r\n     * @param mesh mesh or array of meshes\r\n     * @param material material to use by the layer when rendering the mesh(es). If undefined is passed, the specific material created by the layer will be used.\r\n     */\r\n    public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material): void {\r\n        this._thinEffectLayer.setMaterialForRendering(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity of the effect for a specific mesh.\r\n     * @param mesh The mesh to get the effect intensity for\r\n     * @returns The intensity of the effect for the mesh\r\n     */\r\n    public getEffectIntensity(mesh: AbstractMesh) {\r\n        return this._thinEffectLayer.getEffectIntensity(mesh);\r\n    }\r\n\r\n    /**\r\n     * Sets the intensity of the effect for a specific mesh.\r\n     * @param mesh The mesh to set the effect intensity for\r\n     * @param intensity The intensity of the effect for the mesh\r\n     */\r\n    public setEffectIntensity(mesh: AbstractMesh, intensity: number): void {\r\n        this._thinEffectLayer.setEffectIntensity(mesh, intensity);\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new effect Layer and references it in the scene.\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     * @param thinEffectLayer The thin instance of the effect layer (optional)\r\n     */\r\n    constructor(\r\n        /** The Friendly of the effect in the scene */\r\n        name: string,\r\n        scene?: Scene,\r\n        forceGLSL = false,\r\n        thinEffectLayer?: ThinEffectLayer\r\n    ) {\r\n        this._internalThinEffectLayer = !thinEffectLayer;\r\n        if (!thinEffectLayer) {\r\n            thinEffectLayer = new ThinEffectLayer(name, scene, forceGLSL, false, this._importShadersAsync.bind(this));\r\n            thinEffectLayer.getEffectName = this.getEffectName.bind(this);\r\n            thinEffectLayer.isReady = this.isReady.bind(this);\r\n            thinEffectLayer._createMergeEffect = this._createMergeEffect.bind(this);\r\n            thinEffectLayer._createTextureAndPostProcesses = this._createTextureAndPostProcesses.bind(this);\r\n            thinEffectLayer._internalCompose = this._internalRender.bind(this);\r\n            thinEffectLayer._setEmissiveTextureAndColor = this._setEmissiveTextureAndColor.bind(this);\r\n            thinEffectLayer._numInternalDraws = this._numInternalDraws.bind(this);\r\n            thinEffectLayer._addCustomEffectDefines = this._addCustomEffectDefines.bind(this);\r\n            thinEffectLayer.hasMesh = this.hasMesh.bind(this);\r\n            thinEffectLayer.shouldRender = this.shouldRender.bind(this);\r\n            thinEffectLayer._shouldRenderMesh = this._shouldRenderMesh.bind(this);\r\n            thinEffectLayer._canRenderMesh = this._canRenderMesh.bind(this);\r\n            thinEffectLayer._useMeshMaterial = this._useMeshMaterial.bind(this);\r\n        }\r\n\r\n        this._thinEffectLayer = thinEffectLayer;\r\n        this.name = name;\r\n\r\n        this._scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        RegisterEffectLayerSceneComponent(EffectLayer);\r\n        EffectLayer._SceneComponentInitialization(this._scene);\r\n\r\n        this._engine = this._scene.getEngine();\r\n        this._maxSize = this._engine.getCaps().maxTextureSize;\r\n        this._scene.addEffectLayer(this);\r\n\r\n        this._thinEffectLayer.onDisposeObservable.add(() => {\r\n            this.onDisposeObservable.notifyObservers(this);\r\n        });\r\n\r\n        this._thinEffectLayer.onBeforeRenderLayerObservable.add(() => {\r\n            this.onBeforeRenderMainTextureObservable.notifyObservers(this);\r\n        });\r\n\r\n        this._thinEffectLayer.onBeforeComposeObservable.add(() => {\r\n            this.onBeforeComposeObservable.notifyObservers(this);\r\n        });\r\n\r\n        this._thinEffectLayer.onBeforeRenderMeshToEffect.add((mesh) => {\r\n            this.onBeforeRenderMeshToEffect.notifyObservers(mesh);\r\n        });\r\n\r\n        this._thinEffectLayer.onAfterRenderMeshToEffect.add((mesh) => {\r\n            this.onAfterRenderMeshToEffect.notifyObservers(mesh);\r\n        });\r\n\r\n        this._thinEffectLayer.onAfterComposeObservable.add(() => {\r\n            this.onAfterComposeObservable.notifyObservers(this);\r\n        });\r\n    }\r\n\r\n    protected get _shadersLoaded() {\r\n        return this._thinEffectLayer._shadersLoaded;\r\n    }\r\n\r\n    protected set _shadersLoaded(value: boolean) {\r\n        this._thinEffectLayer._shadersLoaded = value;\r\n    }\r\n\r\n    /**\r\n     * Get the effect name of the layer.\r\n     * @returns The effect name\r\n     */\r\n    public abstract getEffectName(): string;\r\n\r\n    /**\r\n     * Checks for the readiness of the element composing the layer.\r\n     * @param subMesh the mesh to check for\r\n     * @param useInstances specify whether or not to use instances to render the mesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    public abstract isReady(subMesh: SubMesh, useInstances: boolean): boolean;\r\n\r\n    /**\r\n     * Returns whether or not the layer needs stencil enabled during the mesh rendering.\r\n     * @returns true if the effect requires stencil during the main canvas render pass.\r\n     */\r\n    public abstract needStencil(): boolean;\r\n\r\n    /**\r\n     * Create the merge effect. This is the shader use to blit the information back\r\n     * to the main canvas at the end of the scene rendering.\r\n     * @returns The effect containing the shader used to merge the effect on the  main canvas\r\n     */\r\n    protected abstract _createMergeEffect(): Effect;\r\n\r\n    /**\r\n     * Creates the render target textures and post processes used in the effect layer.\r\n     */\r\n    protected abstract _createTextureAndPostProcesses(): void;\r\n\r\n    /**\r\n     * Implementation specific of rendering the generating effect on the main canvas.\r\n     * @param effect The effect used to render through\r\n     * @param renderNum Index of the _internalRender call (0 for the first time _internalRender is called, 1 for the second time, etc. _internalRender is called the number of times returned by _numInternalDraws())\r\n     */\r\n    protected abstract _internalRender(effect: Effect, renderIndex: number): void;\r\n\r\n    /**\r\n     * Sets the required values for both the emissive texture and and the main color.\r\n     */\r\n    protected abstract _setEmissiveTextureAndColor(mesh: Mesh, subMesh: SubMesh, material: Material): void;\r\n\r\n    /**\r\n     * Free any resources and references associated to a mesh.\r\n     * Internal use\r\n     * @param mesh The mesh to free.\r\n     */\r\n    public abstract _disposeMesh(mesh: Mesh): void;\r\n\r\n    /**\r\n     * Serializes this layer (Glow or Highlight for example)\r\n     * @returns a serialized layer object\r\n     */\r\n    public abstract serialize?(): any;\r\n\r\n    /**\r\n     * Number of times _internalRender will be called. Some effect layers need to render the mesh several times, so they should override this method with the number of times the mesh should be rendered\r\n     * @returns Number of times a mesh must be rendered in the layer\r\n     */\r\n    protected _numInternalDraws(): number {\r\n        return this._internalThinEffectLayer ? 1 : this._thinEffectLayer._numInternalDraws();\r\n    }\r\n\r\n    /**\r\n     * Initializes the effect layer with the required options.\r\n     * @param options Sets of none mandatory options to use with the layer (see IEffectLayerOptions for more information)\r\n     */\r\n    protected _init(options: Partial<IEffectLayerOptions>): void {\r\n        // Adapt options\r\n        this._effectLayerOptions = {\r\n            mainTextureRatio: 0.5,\r\n            alphaBlendingMode: Constants.ALPHA_COMBINE,\r\n            camera: null,\r\n            renderingGroupId: -1,\r\n            mainTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            mainTextureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            generateStencilBuffer: false,\r\n            ...options,\r\n        };\r\n\r\n        this._setMainTextureSize();\r\n        this._thinEffectLayer._init(options);\r\n        this._createMainTexture();\r\n        this._createTextureAndPostProcesses();\r\n    }\r\n\r\n    /**\r\n     * Sets the main texture desired size which is the closest power of two\r\n     * of the engine canvas size.\r\n     */\r\n    private _setMainTextureSize(): void {\r\n        if (this._effectLayerOptions.mainTextureFixedSize) {\r\n            this._mainTextureDesiredSize.width = this._effectLayerOptions.mainTextureFixedSize;\r\n            this._mainTextureDesiredSize.height = this._effectLayerOptions.mainTextureFixedSize;\r\n        } else {\r\n            this._mainTextureDesiredSize.width = this._engine.getRenderWidth() * this._effectLayerOptions.mainTextureRatio;\r\n            this._mainTextureDesiredSize.height = this._engine.getRenderHeight() * this._effectLayerOptions.mainTextureRatio;\r\n\r\n            this._mainTextureDesiredSize.width = this._engine.needPOTTextures\r\n                ? GetExponentOfTwo(this._mainTextureDesiredSize.width, this._maxSize)\r\n                : this._mainTextureDesiredSize.width;\r\n            this._mainTextureDesiredSize.height = this._engine.needPOTTextures\r\n                ? GetExponentOfTwo(this._mainTextureDesiredSize.height, this._maxSize)\r\n                : this._mainTextureDesiredSize.height;\r\n        }\r\n\r\n        this._mainTextureDesiredSize.width = Math.floor(this._mainTextureDesiredSize.width);\r\n        this._mainTextureDesiredSize.height = Math.floor(this._mainTextureDesiredSize.height);\r\n    }\r\n\r\n    /**\r\n     * Creates the main texture for the effect layer.\r\n     */\r\n    protected _createMainTexture(): void {\r\n        this._mainTexture = new RenderTargetTexture(\r\n            \"EffectLayerMainRTT\",\r\n            {\r\n                width: this._mainTextureDesiredSize.width,\r\n                height: this._mainTextureDesiredSize.height,\r\n            },\r\n            this._scene,\r\n            {\r\n                type: this._effectLayerOptions.mainTextureType,\r\n                format: this._effectLayerOptions.mainTextureFormat,\r\n                samplingMode: Texture.TRILINEAR_SAMPLINGMODE,\r\n                generateStencilBuffer: this._effectLayerOptions.generateStencilBuffer,\r\n                existingObjectRenderer: this._thinEffectLayer.objectRenderer,\r\n            }\r\n        );\r\n        this._mainTexture.activeCamera = this._effectLayerOptions.camera;\r\n        this._mainTexture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._mainTexture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._mainTexture.anisotropicFilteringLevel = 1;\r\n        this._mainTexture.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);\r\n        this._mainTexture.renderParticles = false;\r\n        this._mainTexture.renderList = null;\r\n        this._mainTexture.ignoreCameraViewport = true;\r\n\r\n        this._mainTexture.onClearObservable.add((engine: AbstractEngine) => {\r\n            engine.clear(this.neutralColor, true, true, true);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds specific effects defines.\r\n     * @param defines The defines to add specifics to.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _addCustomEffectDefines(defines: string[]): void {\r\n        // Nothing to add by default.\r\n    }\r\n\r\n    /**\r\n     * Checks for the readiness of the element composing the layer.\r\n     * @param subMesh the mesh to check for\r\n     * @param useInstances specify whether or not to use instances to render the mesh\r\n     * @param emissiveTexture the associated emissive texture used to generate the glow\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    protected _isReady(subMesh: SubMesh, useInstances: boolean, emissiveTexture: Nullable<BaseTexture>): boolean {\r\n        return this._internalThinEffectLayer\r\n            ? this._thinEffectLayer._internalIsSubMeshReady(subMesh, useInstances, emissiveTexture)\r\n            : this._thinEffectLayer._isSubMeshReady(subMesh, useInstances, emissiveTexture);\r\n    }\r\n\r\n    protected async _importShadersAsync(): Promise<void> {}\r\n\r\n    protected _arePostProcessAndMergeReady(): boolean {\r\n        return this._internalThinEffectLayer ? this._thinEffectLayer._internalIsLayerReady() : this._thinEffectLayer.isLayerReady();\r\n    }\r\n\r\n    /**\r\n     * Checks if the layer is ready to be used.\r\n     * @returns true if the layer is ready to be used\r\n     */\r\n    public isLayerReady(): boolean {\r\n        return this._arePostProcessAndMergeReady() && this._mainTexture.isReady();\r\n    }\r\n\r\n    /**\r\n     * Renders the glowing part of the scene by blending the blurred glowing meshes on top of the rendered scene.\r\n     */\r\n    public render(): void {\r\n        if (!this._thinEffectLayer.compose()) {\r\n            return;\r\n        }\r\n\r\n        // Handle size changes.\r\n        this._setMainTextureSize();\r\n        if (\r\n            (this._mainTextureCreatedSize.width !== this._mainTextureDesiredSize.width || this._mainTextureCreatedSize.height !== this._mainTextureDesiredSize.height) &&\r\n            this._mainTextureDesiredSize.width !== 0 &&\r\n            this._mainTextureDesiredSize.height !== 0\r\n        ) {\r\n            // Recreate RTT and post processes on size change.\r\n            this.onSizeChangedObservable.notifyObservers(this);\r\n            this._disposeTextureAndPostProcesses();\r\n            this._createMainTexture();\r\n            this._createTextureAndPostProcesses();\r\n            this._mainTextureCreatedSize.width = this._mainTextureDesiredSize.width;\r\n            this._mainTextureCreatedSize.height = this._mainTextureDesiredSize.height;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Determine if a given mesh will be used in the current effect.\r\n     * @param mesh mesh to test\r\n     * @returns true if the mesh will be used\r\n     */\r\n    public hasMesh(mesh: AbstractMesh): boolean {\r\n        return this._internalThinEffectLayer ? this._thinEffectLayer._internalHasMesh(mesh) : this._thinEffectLayer.hasMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the layer contains information to display, otherwise false.\r\n     * @returns true if the glow layer should be rendered\r\n     */\r\n    public shouldRender(): boolean {\r\n        return this._internalThinEffectLayer ? this._thinEffectLayer._internalShouldRender() : this._thinEffectLayer.shouldRender();\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh should render, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @returns true if it should render otherwise false\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _shouldRenderMesh(mesh: AbstractMesh): boolean {\r\n        return this._internalThinEffectLayer ? true : this._thinEffectLayer._shouldRenderMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh can be rendered, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @param material The material used on the mesh\r\n     * @returns true if it can be rendered otherwise false\r\n     */\r\n    protected _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {\r\n        return this._internalThinEffectLayer ? this._thinEffectLayer._internalCanRenderMesh(mesh, material) : this._thinEffectLayer._canRenderMesh(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh should render, otherwise false.\r\n     * @returns true if it should render otherwise false\r\n     */\r\n    protected _shouldRenderEmissiveTextureForMesh(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Defines whether the current material of the mesh should be use to render the effect.\r\n     * @param mesh defines the current mesh to render\r\n     * @returns true if the mesh material should be use\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _useMeshMaterial(mesh: AbstractMesh): boolean {\r\n        return this._internalThinEffectLayer ? false : this._thinEffectLayer._useMeshMaterial(mesh);\r\n    }\r\n\r\n    /**\r\n     * Rebuild the required buffers.\r\n     * @internal Internal use only.\r\n     */\r\n    public _rebuild(): void {\r\n        this._thinEffectLayer._rebuild();\r\n    }\r\n\r\n    /**\r\n     * Dispose only the render target textures and post process.\r\n     */\r\n    private _disposeTextureAndPostProcesses(): void {\r\n        this._mainTexture.dispose();\r\n\r\n        for (let i = 0; i < this._postProcesses.length; i++) {\r\n            if (this._postProcesses[i]) {\r\n                this._postProcesses[i].dispose();\r\n            }\r\n        }\r\n        this._postProcesses = [];\r\n\r\n        for (let i = 0; i < this._textures.length; i++) {\r\n            if (this._textures[i]) {\r\n                this._textures[i].dispose();\r\n            }\r\n        }\r\n        this._textures = [];\r\n    }\r\n\r\n    /**\r\n     * Dispose the highlight layer and free resources.\r\n     */\r\n    public dispose(): void {\r\n        this._thinEffectLayer.dispose();\r\n\r\n        // Clean textures and post processes\r\n        this._disposeTextureAndPostProcesses();\r\n\r\n        // Remove from scene\r\n        this._scene.removeEffectLayer(this);\r\n\r\n        // Callback\r\n        this.onDisposeObservable.clear();\r\n        this.onBeforeRenderMainTextureObservable.clear();\r\n        this.onBeforeComposeObservable.clear();\r\n        this.onBeforeRenderMeshToEffect.clear();\r\n        this.onAfterRenderMeshToEffect.clear();\r\n        this.onAfterComposeObservable.clear();\r\n        this.onSizeChangedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the effect layer\r\n     * @returns the string with the class name of the effect layer\r\n     */\r\n    public getClassName(): string {\r\n        return \"EffectLayer\";\r\n    }\r\n\r\n    /**\r\n     * Creates an effect layer from parsed effect layer data\r\n     * @param parsedEffectLayer defines effect layer data\r\n     * @param scene defines the current scene\r\n     * @param rootUrl defines the root URL containing the effect layer information\r\n     * @returns a parsed effect Layer\r\n     */\r\n    public static Parse(parsedEffectLayer: any, scene: Scene, rootUrl: string): EffectLayer {\r\n        const effectLayerType = Tools.Instantiate(parsedEffectLayer.customType);\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\r\n        return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { type PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { BlurPostProcess } from \"../PostProcesses/blurPostProcess.pure\";\r\nimport { ThinGlowLayer, type IThinGlowLayerOptions } from \"./thinGlowLayer\";\r\n\r\nimport { EffectLayer } from \"./effectLayer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Color4 } from \"core/Maths/math.color.pure\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { GetExponentOfTwo } from \"../Misc/tools.functions\";\r\nimport { type ThinBlurPostProcess } from \"core/PostProcesses/thinBlurPostProcess\";\r\nimport { type Nullable } from \"../types\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Glow layer options. This helps customizing the behaviour\r\n * of the glow layer.\r\n */\r\nexport interface IGlowLayerOptions extends IThinGlowLayerOptions {\r\n    /**\r\n     * Enable MSAA by choosing the number of samples. Default: 1\r\n     */\r\n    mainTextureSamples?: number;\r\n\r\n    /**\r\n     * Whether or not to generate a stencil buffer. Default: false\r\n     */\r\n    generateStencilBuffer?: boolean;\r\n}\r\n\r\n/**\r\n * The glow layer Helps adding a glow effect around the emissive parts of a mesh.\r\n *\r\n * Once instantiated in a scene, by default, all the emissive meshes will glow.\r\n *\r\n * Documentation: https://doc.babylonjs.com/features/featuresDeepDive/mesh/glowLayer\r\n */\r\nexport class GlowLayer extends EffectLayer {\r\n    /**\r\n     * Effect Name of the layer.\r\n     */\r\n    public static get EffectName() {\r\n        return ThinGlowLayer.EffectName;\r\n    }\r\n\r\n    /**\r\n     * The default blur kernel size used for the glow.\r\n     */\r\n    public static DefaultBlurKernelSize = 32;\r\n\r\n    /**\r\n     * The default texture size ratio used for the glow.\r\n     */\r\n    public static DefaultTextureRatio = 0.5;\r\n\r\n    /**\r\n     * Sets the kernel size of the blur.\r\n     */\r\n    public set blurKernelSize(value: number) {\r\n        this._thinEffectLayer.blurKernelSize = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the kernel size of the blur.\r\n     */\r\n    @serialize()\r\n    public get blurKernelSize(): number {\r\n        return this._thinEffectLayer.blurKernelSize;\r\n    }\r\n\r\n    /**\r\n     * Sets the glow intensity.\r\n     */\r\n    public set intensity(value: number) {\r\n        this._thinEffectLayer.intensity = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the glow intensity.\r\n     */\r\n    @serialize()\r\n    public get intensity(): number {\r\n        return this._thinEffectLayer.intensity;\r\n    }\r\n\r\n    @serialize(\"options\")\r\n    protected _options: IGlowLayerOptions;\r\n\r\n    declare protected readonly _thinEffectLayer: ThinGlowLayer;\r\n    private _horizontalBlurPostprocess1: BlurPostProcess;\r\n    private _verticalBlurPostprocess1: BlurPostProcess;\r\n    private _horizontalBlurPostprocess2: BlurPostProcess;\r\n    private _verticalBlurPostprocess2: BlurPostProcess;\r\n    private _blurTexture1: RenderTargetTexture;\r\n    private _blurTexture2: RenderTargetTexture;\r\n    private _postProcesses1: PostProcess[];\r\n    private _postProcesses2: PostProcess[];\r\n    /**\r\n     * Callback used to let the user override the color selection on a per mesh basis\r\n     */\r\n    public get customEmissiveColorSelector(): (mesh: Mesh, subMesh: SubMesh, material: Material, result: Color4) => void {\r\n        return this._thinEffectLayer.customEmissiveColorSelector;\r\n    }\r\n\r\n    public set customEmissiveColorSelector(value: (mesh: Mesh, subMesh: SubMesh, material: Material, result: Color4) => void) {\r\n        this._thinEffectLayer.customEmissiveColorSelector = value;\r\n    }\r\n\r\n    /**\r\n     * Callback used to let the user override the texture selection on a per mesh basis\r\n     */\r\n    public get customEmissiveTextureSelector(): (mesh: Mesh, subMesh: SubMesh, material: Material) => Texture {\r\n        return this._thinEffectLayer.customEmissiveTextureSelector;\r\n    }\r\n\r\n    public set customEmissiveTextureSelector(value: (mesh: Mesh, subMesh: SubMesh, material: Material) => Texture) {\r\n        this._thinEffectLayer.customEmissiveTextureSelector = value;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new glow Layer and references it to the scene.\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param options Sets of none mandatory options to use with the layer (see IGlowLayerOptions for more information)\r\n     */\r\n    constructor(name: string, scene?: Scene, options?: Partial<IGlowLayerOptions>) {\r\n        super(name, scene, false, new ThinGlowLayer(name, scene, options));\r\n\r\n        // Adapt options\r\n        this._options = {\r\n            mainTextureRatio: GlowLayer.DefaultTextureRatio,\r\n            blurKernelSize: 32,\r\n            mainTextureFixedSize: undefined,\r\n            camera: null,\r\n            mainTextureSamples: 1,\r\n            renderingGroupId: -1,\r\n            ldrMerge: false,\r\n            alphaBlendingMode: Constants.ALPHA_ADD,\r\n            mainTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            generateStencilBuffer: false,\r\n            excludeByDefault: false,\r\n            ...options,\r\n        };\r\n\r\n        // Initialize the layer\r\n        this._init(this._options);\r\n    }\r\n\r\n    /**\r\n     * Get the effect name of the layer.\r\n     * @returns The effect name\r\n     */\r\n    public getEffectName(): string {\r\n        return GlowLayer.EffectName;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Create the merge effect. This is the shader use to blit the information back\r\n     * to the main canvas at the end of the scene rendering.\r\n     */\r\n    protected _createMergeEffect(): Effect {\r\n        return this._thinEffectLayer._createMergeEffect();\r\n    }\r\n\r\n    /**\r\n     * Creates the render target textures and post processes used in the glow layer.\r\n     */\r\n    protected _createTextureAndPostProcesses(): void {\r\n        this._thinEffectLayer._renderPassId = this._mainTexture.renderPassId;\r\n\r\n        let blurTextureWidth = this._mainTextureDesiredSize.width;\r\n        let blurTextureHeight = this._mainTextureDesiredSize.height;\r\n        blurTextureWidth = this._engine.needPOTTextures ? GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;\r\n        blurTextureHeight = this._engine.needPOTTextures ? GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;\r\n\r\n        let textureType: number;\r\n        if (this._engine.getCaps().textureHalfFloatRender) {\r\n            textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        } else {\r\n            textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        }\r\n\r\n        this._blurTexture1 = new RenderTargetTexture(\r\n            \"GlowLayerBlurRTT\",\r\n            {\r\n                width: blurTextureWidth,\r\n                height: blurTextureHeight,\r\n            },\r\n            this._scene,\r\n            false,\r\n            true,\r\n            textureType\r\n        );\r\n        this._blurTexture1.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._blurTexture1.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._blurTexture1.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);\r\n        this._blurTexture1.renderParticles = false;\r\n        this._blurTexture1.ignoreCameraViewport = true;\r\n\r\n        const blurTextureWidth2 = Math.floor(blurTextureWidth / 2);\r\n        const blurTextureHeight2 = Math.floor(blurTextureHeight / 2);\r\n\r\n        this._blurTexture2 = new RenderTargetTexture(\r\n            \"GlowLayerBlurRTT2\",\r\n            {\r\n                width: blurTextureWidth2,\r\n                height: blurTextureHeight2,\r\n            },\r\n            this._scene,\r\n            false,\r\n            true,\r\n            textureType\r\n        );\r\n        this._blurTexture2.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._blurTexture2.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._blurTexture2.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);\r\n        this._blurTexture2.renderParticles = false;\r\n        this._blurTexture2.ignoreCameraViewport = true;\r\n\r\n        this._textures = [this._blurTexture1, this._blurTexture2];\r\n\r\n        this._thinEffectLayer.bindTexturesForCompose = (effect: Effect) => {\r\n            effect.setTexture(\"textureSampler\", this._blurTexture1);\r\n            effect.setTexture(\"textureSampler2\", this._blurTexture2);\r\n            effect.setFloat(\"offset\", this.intensity);\r\n        };\r\n\r\n        this._thinEffectLayer._createTextureAndPostProcesses();\r\n\r\n        const thinBlurPostProcesses1 = this._thinEffectLayer._postProcesses[0] as ThinBlurPostProcess;\r\n        this._horizontalBlurPostprocess1 = new BlurPostProcess(\"GlowLayerHBP1\", thinBlurPostProcesses1.direction, thinBlurPostProcesses1.kernel, {\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine: this._scene.getEngine(),\r\n            width: blurTextureWidth,\r\n            height: blurTextureHeight,\r\n            textureType,\r\n            effectWrapper: thinBlurPostProcesses1,\r\n        });\r\n        this._horizontalBlurPostprocess1.width = blurTextureWidth;\r\n        this._horizontalBlurPostprocess1.height = blurTextureHeight;\r\n        this._horizontalBlurPostprocess1.externalTextureSamplerBinding = true;\r\n        this._horizontalBlurPostprocess1.onApplyObservable.add((effect) => {\r\n            effect.setTexture(\"textureSampler\", this._mainTexture);\r\n        });\r\n\r\n        const thinBlurPostProcesses2 = this._thinEffectLayer._postProcesses[1] as ThinBlurPostProcess;\r\n        this._verticalBlurPostprocess1 = new BlurPostProcess(\"GlowLayerVBP1\", thinBlurPostProcesses2.direction, thinBlurPostProcesses2.kernel, {\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine: this._scene.getEngine(),\r\n            width: blurTextureWidth,\r\n            height: blurTextureHeight,\r\n            textureType,\r\n            effectWrapper: thinBlurPostProcesses2,\r\n        });\r\n\r\n        const thinBlurPostProcesses3 = this._thinEffectLayer._postProcesses[2] as ThinBlurPostProcess;\r\n        this._horizontalBlurPostprocess2 = new BlurPostProcess(\"GlowLayerHBP2\", thinBlurPostProcesses3.direction, thinBlurPostProcesses3.kernel, {\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine: this._scene.getEngine(),\r\n            width: blurTextureWidth2,\r\n            height: blurTextureHeight2,\r\n            textureType,\r\n            effectWrapper: thinBlurPostProcesses3,\r\n        });\r\n        this._horizontalBlurPostprocess2.width = blurTextureWidth2;\r\n        this._horizontalBlurPostprocess2.height = blurTextureHeight2;\r\n        this._horizontalBlurPostprocess2.externalTextureSamplerBinding = true;\r\n        this._horizontalBlurPostprocess2.onApplyObservable.add((effect) => {\r\n            effect.setTexture(\"textureSampler\", this._blurTexture1);\r\n        });\r\n\r\n        const thinBlurPostProcesses4 = this._thinEffectLayer._postProcesses[3] as ThinBlurPostProcess;\r\n        this._verticalBlurPostprocess2 = new BlurPostProcess(\"GlowLayerVBP2\", thinBlurPostProcesses4.direction, thinBlurPostProcesses4.kernel, {\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine: this._scene.getEngine(),\r\n            width: blurTextureWidth2,\r\n            height: blurTextureHeight2,\r\n            textureType,\r\n            effectWrapper: thinBlurPostProcesses4,\r\n        });\r\n\r\n        this._postProcesses = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1, this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];\r\n        this._postProcesses1 = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1];\r\n        this._postProcesses2 = [this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];\r\n\r\n        this._mainTexture.samples = this._options.mainTextureSamples!;\r\n        this._mainTexture.onAfterUnbindObservable.add(() => {\r\n            const internalTexture = this._blurTexture1.renderTarget;\r\n            if (internalTexture) {\r\n                this._scene.postProcessManager.directRender(this._postProcesses1, internalTexture, true);\r\n\r\n                const internalTexture2 = this._blurTexture2.renderTarget;\r\n                if (internalTexture2) {\r\n                    this._scene.postProcessManager.directRender(this._postProcesses2, internalTexture2, true);\r\n                }\r\n                this._engine.unBindFramebuffer(internalTexture2 ?? internalTexture, true);\r\n            }\r\n        });\r\n\r\n        // Prevent autoClear.\r\n        this._postProcesses.map((pp) => {\r\n            pp.autoClear = false;\r\n        });\r\n\r\n        this._mainTextureCreatedSize.width = this._mainTextureDesiredSize.width;\r\n        this._mainTextureCreatedSize.height = this._mainTextureDesiredSize.height;\r\n    }\r\n\r\n    /**\r\n     * Checks for the readiness of the element composing the layer.\r\n     * @param subMesh the mesh to check for\r\n     * @param useInstances specify whether or not to use instances to render the mesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        return this._thinEffectLayer.isReady(subMesh, useInstances);\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not the layer needs stencil enabled during the mesh rendering.\r\n     */\r\n    public needStencil(): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh can be rendered, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @param material The material used on the mesh\r\n     * @returns true if it can be rendered otherwise false\r\n     */\r\n    protected override _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {\r\n        return this._thinEffectLayer._canRenderMesh(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Implementation specific of rendering the generating effect on the main canvas.\r\n     * @param effect The effect used to render through\r\n     */\r\n    protected _internalRender(effect: Effect): void {\r\n        this._thinEffectLayer._internalCompose(effect);\r\n    }\r\n\r\n    /**\r\n     * Sets the required values for both the emissive texture and and the main color.\r\n     * @param mesh\r\n     * @param subMesh\r\n     * @param material\r\n     */\r\n    protected _setEmissiveTextureAndColor(mesh: Mesh, subMesh: SubMesh, material: Material): void {\r\n        this._thinEffectLayer._setEmissiveTextureAndColor(mesh, subMesh, material);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh should render, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @returns true if it should render otherwise false\r\n     */\r\n    protected override _shouldRenderMesh(mesh: Mesh): boolean {\r\n        return this._thinEffectLayer._shouldRenderMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Adds specific effects defines.\r\n     * @param defines The defines to add specifics to.\r\n     */\r\n    protected override _addCustomEffectDefines(defines: string[]): void {\r\n        this._thinEffectLayer._addCustomEffectDefines(defines);\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the exclusion list to prevent it to impact or being impacted by the glow layer.\r\n     * This will not have an effect if meshes are excluded by default (see setExcludedByDefault).\r\n     * @param mesh The mesh to exclude from the glow layer\r\n     */\r\n    public addExcludedMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer.addExcludedMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the exclusion list to let it impact or being impacted by the glow layer.\r\n     * This will not have an effect if meshes are excluded by default (see setExcludedByDefault).\r\n     * @param mesh The mesh to remove\r\n     */\r\n    public removeExcludedMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer.removeExcludedMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the inclusion list to impact or being impacted by the glow layer.\r\n     * @param mesh The mesh to include in the glow layer\r\n     */\r\n    public addIncludedOnlyMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer.addIncludedOnlyMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the Inclusion list to prevent it to impact or being impacted by the glow layer.\r\n     * @param mesh The mesh to remove\r\n     */\r\n    public removeIncludedOnlyMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer.removeIncludedOnlyMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Set the excluded by default option.\r\n     * If true, all meshes will be excluded by default unless they are added to the inclusion list.\r\n     * @param value The boolean value to set the excluded by default option to\r\n     */\r\n    public setExcludedByDefault(value: boolean): void {\r\n        this._thinEffectLayer.setExcludedByDefault(value);\r\n    }\r\n\r\n    /**\r\n     * Determine if a given mesh will be used in the glow layer\r\n     * @param mesh The mesh to test\r\n     * @returns true if the mesh will be highlighted by the current glow layer\r\n     */\r\n    public override hasMesh(mesh: AbstractMesh): boolean {\r\n        return this._thinEffectLayer.hasMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Defines whether the current material of the mesh should be use to render the effect.\r\n     * @param mesh defines the current mesh to render\r\n     * @returns true if the material of the mesh should be use to render the effect\r\n     */\r\n    protected override _useMeshMaterial(mesh: AbstractMesh): boolean {\r\n        return this._thinEffectLayer._useMeshMaterial(mesh);\r\n    }\r\n\r\n    /**\r\n     * Add a mesh to be rendered through its own material and not with emissive only.\r\n     * @param mesh The mesh for which we need to use its material\r\n     */\r\n    public referenceMeshToUseItsOwnMaterial(mesh: AbstractMesh): void {\r\n        this._thinEffectLayer.referenceMeshToUseItsOwnMaterial(mesh);\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from being rendered through its own material and not with emissive only.\r\n     * @param mesh The mesh for which we need to not use its material\r\n     */\r\n    public unReferenceMeshFromUsingItsOwnMaterial(mesh: AbstractMesh): void {\r\n        this._thinEffectLayer.unReferenceMeshFromUsingItsOwnMaterial(mesh, this._mainTexture.renderPassId);\r\n    }\r\n\r\n    /**\r\n     * Free any resources and references associated to a mesh.\r\n     * Internal use\r\n     * @param mesh The mesh to free.\r\n     * @internal\r\n     */\r\n    public _disposeMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer._disposeMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the effect layer\r\n     * @returns the string with the class name of the effect layer\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GlowLayer\";\r\n    }\r\n\r\n    /**\r\n     * Serializes this glow layer\r\n     * @returns a serialized glow layer object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        serializationObject.customType = \"BABYLON.GlowLayer\";\r\n\r\n        let index;\r\n\r\n        // Included meshes\r\n        serializationObject.includedMeshes = [];\r\n\r\n        const includedOnlyMeshes = this._thinEffectLayer._includedOnlyMeshes;\r\n        if (includedOnlyMeshes.length) {\r\n            for (index = 0; index < includedOnlyMeshes.length; index++) {\r\n                const mesh = this._scene.getMeshByUniqueId(includedOnlyMeshes[index]);\r\n                if (mesh) {\r\n                    serializationObject.includedMeshes.push(mesh.id);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Excluded meshes\r\n        serializationObject.excludedMeshes = [];\r\n\r\n        const excludedMeshes = this._thinEffectLayer._excludedMeshes;\r\n        if (excludedMeshes.length) {\r\n            for (index = 0; index < excludedMeshes.length; index++) {\r\n                const mesh = this._scene.getMeshByUniqueId(excludedMeshes[index]);\r\n                if (mesh) {\r\n                    serializationObject.excludedMeshes.push(mesh.id);\r\n                }\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Creates a Glow Layer from parsed glow layer data\r\n     * @param parsedGlowLayer defines glow layer data\r\n     * @param scene defines the current scene\r\n     * @param rootUrl defines the root URL containing the glow layer information\r\n     * @returns a parsed Glow Layer\r\n     */\r\n    public static override Parse(parsedGlowLayer: any, scene: Scene, rootUrl: string): GlowLayer {\r\n        const gl = SerializationHelper.Parse(() => new GlowLayer(parsedGlowLayer.name, scene, parsedGlowLayer.options), parsedGlowLayer, scene, rootUrl);\r\n        let index;\r\n\r\n        // Excluded meshes\r\n        for (index = 0; index < parsedGlowLayer.excludedMeshes.length; index++) {\r\n            const mesh = scene.getMeshById(parsedGlowLayer.excludedMeshes[index]);\r\n            if (mesh) {\r\n                gl.addExcludedMesh(<Mesh>mesh);\r\n            }\r\n        }\r\n\r\n        // Included meshes\r\n        for (index = 0; index < parsedGlowLayer.includedMeshes.length; index++) {\r\n            const mesh = scene.getMeshById(parsedGlowLayer.includedMeshes[index]);\r\n            if (mesh) {\r\n                gl.addIncludedOnlyMesh(<Mesh>mesh);\r\n            }\r\n        }\r\n\r\n        return gl;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for glowLayer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGlowLayer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.getGlowLayerByName = function (name: string): Nullable<GlowLayer> {\r\n        for (let index = 0; index < this.effectLayers?.length; index++) {\r\n            if (this.effectLayers[index].name === name && this.effectLayers[index].getEffectName() === GlowLayer.EffectName) {\r\n                return (<any>this.effectLayers[index]) as GlowLayer;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    RegisterClass(\"BABYLON.GlowLayer\", GlowLayer);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { type PostProcessOptions } from \"../PostProcesses/postProcess\";\r\nimport { PassPostProcess } from \"../PostProcesses/passPostProcess.pure\";\r\nimport { BlurPostProcess } from \"../PostProcesses/blurPostProcess.pure\";\r\nimport { EffectLayer } from \"./effectLayer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type Color4 } from \"../Maths/math.color\";\r\nimport { type ThinPassPostProcess } from \"core/PostProcesses/thinPassPostProcess\";\r\nimport { type ThinBlurPostProcess } from \"core/PostProcesses/thinBlurPostProcess\";\r\nimport { ThinHighlightLayer, type IThinHighlightLayerOptions } from \"./thinHighlightLayer\";\r\n\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { GetExponentOfTwo } from \"../Misc/tools.functions\";\r\nimport { ThinGlowBlurPostProcess } from \"./thinEffectLayer\";\r\nimport { type Nullable } from \"../types\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\ninterface IBlurPostProcess extends PostProcess {\r\n    kernel: number;\r\n}\r\n\r\n/**\r\n * Special Glow Blur post process only blurring the alpha channel\r\n * It enforces keeping the most luminous color in the color channel.\r\n */\r\nclass GlowBlurPostProcess extends PostProcess {\r\n    declare protected _effectWrapper: ThinGlowBlurPostProcess;\r\n\r\n    constructor(\r\n        name: string,\r\n        public direction: Vector2,\r\n        public kernel: number,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode: number = Texture.BILINEAR_SAMPLINGMODE,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinGlowBlurPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinGlowBlurPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinGlowBlurPostProcess(name, engine, direction, kernel, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.onApplyObservable.add(() => {\r\n            this._effectWrapper.textureWidth = this.width;\r\n            this._effectWrapper.textureHeight = this.height;\r\n        });\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/glowBlurPostProcess.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/glowBlurPostProcess.fragment\"));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n}\r\n\r\n/**\r\n * Highlight layer options. This helps customizing the behaviour\r\n * of the highlight layer.\r\n */\r\nexport interface IHighlightLayerOptions extends IThinHighlightLayerOptions {\r\n    /**\r\n     * Whether or not to generate a stencil buffer. Default: false\r\n     */\r\n    generateStencilBuffer?: boolean;\r\n}\r\n\r\n/**\r\n * The highlight layer Helps adding a glow effect around a mesh.\r\n *\r\n * Once instantiated in a scene, simply use the addMesh or removeMesh method to add or remove\r\n * glowy meshes to your scene.\r\n *\r\n * !!! THIS REQUIRES AN ACTIVE STENCIL BUFFER ON THE CANVAS !!!\r\n */\r\nexport class HighlightLayer extends EffectLayer {\r\n    /**\r\n     * Effect Name of the highlight layer.\r\n     */\r\n    public static readonly EffectName = \"HighlightLayer\";\r\n\r\n    /**\r\n     * The neutral color used during the preparation of the glow effect.\r\n     * This is black by default as the blend operation is a blend operation.\r\n     */\r\n    public static get NeutralColor() {\r\n        return ThinHighlightLayer.NeutralColor;\r\n    }\r\n\r\n    public static set NeutralColor(value: Color4) {\r\n        ThinHighlightLayer.NeutralColor = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the inner glow is ACTIVE in the layer.\r\n     */\r\n    @serialize()\r\n    public get innerGlow() {\r\n        return this._thinEffectLayer.innerGlow;\r\n    }\r\n\r\n    public set innerGlow(value: boolean) {\r\n        this._thinEffectLayer.innerGlow = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the outer glow is ACTIVE in the layer.\r\n     */\r\n    @serialize()\r\n    public get outerGlow() {\r\n        return this._thinEffectLayer.outerGlow;\r\n    }\r\n\r\n    public set outerGlow(value: boolean) {\r\n        this._thinEffectLayer.outerGlow = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies the horizontal size of the blur.\r\n     */\r\n    public set blurHorizontalSize(value: number) {\r\n        this._thinEffectLayer.blurHorizontalSize = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies the vertical size of the blur.\r\n     */\r\n    public set blurVerticalSize(value: number) {\r\n        this._thinEffectLayer.blurVerticalSize = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the horizontal size of the blur.\r\n     */\r\n    @serialize()\r\n    public get blurHorizontalSize(): number {\r\n        return this._thinEffectLayer.blurHorizontalSize;\r\n    }\r\n\r\n    /**\r\n     * Gets the vertical size of the blur.\r\n     */\r\n    @serialize()\r\n    public get blurVerticalSize(): number {\r\n        return this._thinEffectLayer.blurVerticalSize;\r\n    }\r\n\r\n    /**\r\n     * Number of stencil bits used by the highlight layer (default: 8).\r\n     * The layer uses the numStencilBits highest bits of the stencil buffer.\r\n     */\r\n    @serialize()\r\n    public get numStencilBits(): number {\r\n        return this._thinEffectLayer.numStencilBits;\r\n    }\r\n\r\n    public set numStencilBits(value: number) {\r\n        this._thinEffectLayer.numStencilBits = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the stencil reference value used for the meshes rendered by the highlight layer.\r\n     */\r\n    public get stencilReference(): number {\r\n        return this._thinEffectLayer.stencilReference;\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the highlight layer is being blurred.\r\n     */\r\n    public onBeforeBlurObservable = new Observable<HighlightLayer>();\r\n\r\n    /**\r\n     * An event triggered when the highlight layer has been blurred.\r\n     */\r\n    public onAfterBlurObservable = new Observable<HighlightLayer>();\r\n\r\n    @serialize(\"options\")\r\n    private _options: Required<IHighlightLayerOptions>;\r\n\r\n    declare protected readonly _thinEffectLayer: ThinHighlightLayer;\r\n    private _downSamplePostprocess: PassPostProcess;\r\n    private _horizontalBlurPostprocess: IBlurPostProcess;\r\n    private _verticalBlurPostprocess: IBlurPostProcess;\r\n    private _blurTexture: RenderTargetTexture;\r\n\r\n    /**\r\n     * Instantiates a new highlight Layer and references it to the scene..\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param options Sets of none mandatory options to use with the layer (see IHighlightLayerOptions for more information)\r\n     */\r\n    constructor(name: string, scene?: Scene, options?: Partial<IHighlightLayerOptions>) {\r\n        super(name, scene, options !== undefined ? !!options.forceGLSL : false, new ThinHighlightLayer(name, scene, options));\r\n\r\n        // Warn on stencil\r\n        if (!this._engine.isStencilEnable) {\r\n            Logger.Warn(\"Rendering the Highlight Layer requires the stencil to be active on the canvas. var engine = new Engine(canvas, antialias, { stencil: true }\");\r\n        }\r\n\r\n        // Adapt options\r\n        this._options = {\r\n            mainTextureRatio: 0.5,\r\n            blurTextureSizeRatio: 0.5,\r\n            mainTextureFixedSize: 0,\r\n            blurHorizontalSize: 1.0,\r\n            blurVerticalSize: 1.0,\r\n            alphaBlendingMode: Constants.ALPHA_COMBINE,\r\n            camera: null,\r\n            renderingGroupId: -1,\r\n            mainTextureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            mainTextureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            forceGLSL: false,\r\n            isStroke: false,\r\n            generateStencilBuffer: false,\r\n            ...options,\r\n        };\r\n\r\n        // Initialize the layer\r\n        this._init(this._options);\r\n\r\n        // Do not render as long as no meshes have been added\r\n        this._shouldRender = false;\r\n    }\r\n\r\n    /**\r\n     * Get the effect name of the layer.\r\n     * @returns The effect name\r\n     */\r\n    public getEffectName(): string {\r\n        return HighlightLayer.EffectName;\r\n    }\r\n\r\n    protected override _numInternalDraws(): number {\r\n        return 2; // we need two rendering, one for the inner glow and the other for the outer glow\r\n    }\r\n\r\n    /**\r\n     * Create the merge effect. This is the shader use to blit the information back\r\n     * to the main canvas at the end of the scene rendering.\r\n     * @returns The effect created\r\n     */\r\n    protected _createMergeEffect(): Effect {\r\n        return this._thinEffectLayer._createMergeEffect();\r\n    }\r\n\r\n    /**\r\n     * Creates the render target textures and post processes used in the highlight layer.\r\n     */\r\n    protected _createTextureAndPostProcesses(): void {\r\n        let blurTextureWidth = this._mainTextureDesiredSize.width * this._options.blurTextureSizeRatio;\r\n        let blurTextureHeight = this._mainTextureDesiredSize.height * this._options.blurTextureSizeRatio;\r\n        blurTextureWidth = this._engine.needPOTTextures ? GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;\r\n        blurTextureHeight = this._engine.needPOTTextures ? GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;\r\n\r\n        let textureType: number;\r\n        if (this._engine.getCaps().textureHalfFloatRender) {\r\n            textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        } else {\r\n            textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        }\r\n\r\n        this._blurTexture = new RenderTargetTexture(\r\n            \"HighlightLayerBlurRTT\",\r\n            {\r\n                width: blurTextureWidth,\r\n                height: blurTextureHeight,\r\n            },\r\n            this._scene,\r\n            false,\r\n            true,\r\n            textureType\r\n        );\r\n        this._blurTexture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._blurTexture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._blurTexture.anisotropicFilteringLevel = 16;\r\n        this._blurTexture.updateSamplingMode(Texture.TRILINEAR_SAMPLINGMODE);\r\n        this._blurTexture.renderParticles = false;\r\n        this._blurTexture.ignoreCameraViewport = true;\r\n\r\n        this._textures = [this._blurTexture];\r\n\r\n        this._thinEffectLayer.bindTexturesForCompose = (effect: Effect) => {\r\n            effect.setTexture(\"textureSampler\", this._blurTexture);\r\n        };\r\n\r\n        this._thinEffectLayer._createTextureAndPostProcesses();\r\n\r\n        if (this._options.alphaBlendingMode === Constants.ALPHA_COMBINE) {\r\n            this._downSamplePostprocess = new PassPostProcess(\"HighlightLayerPPP\", {\r\n                size: this._options.blurTextureSizeRatio,\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine: this._scene.getEngine(),\r\n                effectWrapper: this._thinEffectLayer._postProcesses[0] as ThinPassPostProcess,\r\n            });\r\n            this._downSamplePostprocess.externalTextureSamplerBinding = true;\r\n            this._downSamplePostprocess.onApplyObservable.add((effect) => {\r\n                effect.setTexture(\"textureSampler\", this._mainTexture);\r\n            });\r\n\r\n            this._horizontalBlurPostprocess = new GlowBlurPostProcess(\"HighlightLayerHBP\", new Vector2(1.0, 0), this._options.blurHorizontalSize, {\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine: this._scene.getEngine(),\r\n                effectWrapper: this._thinEffectLayer._postProcesses[1] as ThinGlowBlurPostProcess,\r\n            });\r\n            this._horizontalBlurPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setFloat2(\"screenSize\", blurTextureWidth, blurTextureHeight);\r\n            });\r\n\r\n            this._verticalBlurPostprocess = new GlowBlurPostProcess(\"HighlightLayerVBP\", new Vector2(0, 1.0), this._options.blurVerticalSize, {\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine: this._scene.getEngine(),\r\n                effectWrapper: this._thinEffectLayer._postProcesses[2] as ThinGlowBlurPostProcess,\r\n            });\r\n            this._verticalBlurPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setFloat2(\"screenSize\", blurTextureWidth, blurTextureHeight);\r\n            });\r\n\r\n            this._postProcesses = [this._downSamplePostprocess, this._horizontalBlurPostprocess, this._verticalBlurPostprocess];\r\n        } else {\r\n            this._horizontalBlurPostprocess = new BlurPostProcess(\"HighlightLayerHBP\", new Vector2(1.0, 0), this._options.blurHorizontalSize / 2, {\r\n                size: {\r\n                    width: blurTextureWidth,\r\n                    height: blurTextureHeight,\r\n                },\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine: this._scene.getEngine(),\r\n                textureType,\r\n                effectWrapper: this._thinEffectLayer._postProcesses[0] as ThinBlurPostProcess,\r\n            });\r\n            this._horizontalBlurPostprocess.width = blurTextureWidth;\r\n            this._horizontalBlurPostprocess.height = blurTextureHeight;\r\n            this._horizontalBlurPostprocess.externalTextureSamplerBinding = true;\r\n            this._horizontalBlurPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setTexture(\"textureSampler\", this._mainTexture);\r\n            });\r\n\r\n            this._verticalBlurPostprocess = new BlurPostProcess(\"HighlightLayerVBP\", new Vector2(0, 1.0), this._options.blurVerticalSize / 2, {\r\n                size: {\r\n                    width: blurTextureWidth,\r\n                    height: blurTextureHeight,\r\n                },\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine: this._scene.getEngine(),\r\n                textureType,\r\n            });\r\n\r\n            this._postProcesses = [this._horizontalBlurPostprocess, this._verticalBlurPostprocess];\r\n        }\r\n\r\n        this._mainTexture.onAfterUnbindObservable.add(() => {\r\n            this.onBeforeBlurObservable.notifyObservers(this);\r\n\r\n            const internalTexture = this._blurTexture.renderTarget;\r\n            if (internalTexture) {\r\n                this._scene.postProcessManager.directRender(this._postProcesses, internalTexture, true);\r\n                this._engine.unBindFramebuffer(internalTexture, true);\r\n            }\r\n\r\n            this.onAfterBlurObservable.notifyObservers(this);\r\n        });\r\n\r\n        // Prevent autoClear.\r\n        this._postProcesses.map((pp) => {\r\n            pp.autoClear = false;\r\n        });\r\n\r\n        this._mainTextureCreatedSize.width = this._mainTextureDesiredSize.width;\r\n        this._mainTextureCreatedSize.height = this._mainTextureDesiredSize.height;\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not the layer needs stencil enabled during the mesh rendering.\r\n     */\r\n    public needStencil(): boolean {\r\n        return this._thinEffectLayer.needStencil();\r\n    }\r\n\r\n    /**\r\n     * Checks for the readiness of the element composing the layer.\r\n     * @param subMesh the mesh to check for\r\n     * @param useInstances specify whether or not to use instances to render the mesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        return this._thinEffectLayer.isReady(subMesh, useInstances);\r\n    }\r\n\r\n    /**\r\n     * Implementation specific of rendering the generating effect on the main canvas.\r\n     * @param effect The effect used to render through\r\n     * @param renderIndex\r\n     */\r\n    protected _internalRender(effect: Effect, renderIndex: number): void {\r\n        this._thinEffectLayer._internalCompose(effect, renderIndex);\r\n    }\r\n\r\n    /**\r\n     * @returns true if the layer contains information to display, otherwise false.\r\n     */\r\n    public override shouldRender(): boolean {\r\n        return this._thinEffectLayer.shouldRender();\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh should render, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @returns true if it should render otherwise false\r\n     */\r\n    protected override _shouldRenderMesh(mesh: Mesh): boolean {\r\n        return this._thinEffectLayer._shouldRenderMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh can be rendered, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @param material The material used on the mesh\r\n     * @returns true if it can be rendered otherwise false\r\n     */\r\n    protected override _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {\r\n        return this._thinEffectLayer._canRenderMesh(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Adds specific effects defines.\r\n     * @param defines The defines to add specifics to.\r\n     */\r\n    protected override _addCustomEffectDefines(defines: string[]): void {\r\n        this._thinEffectLayer._addCustomEffectDefines(defines);\r\n    }\r\n\r\n    /**\r\n     * Sets the required values for both the emissive texture and and the main color.\r\n     * @param mesh\r\n     * @param subMesh\r\n     * @param material\r\n     */\r\n    protected _setEmissiveTextureAndColor(mesh: Mesh, subMesh: SubMesh, material: Material): void {\r\n        this._thinEffectLayer._setEmissiveTextureAndColor(mesh, subMesh, material);\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the exclusion list to prevent it to impact or being impacted by the highlight layer.\r\n     * @param mesh The mesh to exclude from the highlight layer\r\n     */\r\n    public addExcludedMesh(mesh: Mesh) {\r\n        this._thinEffectLayer.addExcludedMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the exclusion list to let it impact or being impacted by the highlight layer.\r\n     * @param mesh The mesh to highlight\r\n     */\r\n    public removeExcludedMesh(mesh: Mesh) {\r\n        this._thinEffectLayer.removeExcludedMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Determine if a given mesh will be highlighted by the current HighlightLayer\r\n     * @param mesh mesh to test\r\n     * @returns true if the mesh will be highlighted by the current HighlightLayer\r\n     */\r\n    public override hasMesh(mesh: AbstractMesh): boolean {\r\n        return this._thinEffectLayer.hasMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Add a mesh in the highlight layer in order to make it glow with the chosen color.\r\n     * @param mesh The mesh to highlight\r\n     * @param color The color of the highlight\r\n     * @param glowEmissiveOnly Extract the glow from the emissive texture\r\n     */\r\n    public addMesh(mesh: Mesh, color: Color3, glowEmissiveOnly = false) {\r\n        this._thinEffectLayer.addMesh(mesh, color, glowEmissiveOnly);\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the highlight layer in order to make it stop glowing.\r\n     * @param mesh The mesh to highlight\r\n     */\r\n    public removeMesh(mesh: Mesh) {\r\n        this._thinEffectLayer.removeMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Remove all the meshes currently referenced in the highlight layer\r\n     */\r\n    public removeAllMeshes(): void {\r\n        this._thinEffectLayer.removeAllMeshes();\r\n    }\r\n\r\n    /**\r\n     * Free any resources and references associated to a mesh.\r\n     * Internal use\r\n     * @param mesh The mesh to free.\r\n     * @internal\r\n     */\r\n    public _disposeMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer._disposeMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the effect layer\r\n     * @returns the string with the class name of the effect layer\r\n     */\r\n    public override getClassName(): string {\r\n        return \"HighlightLayer\";\r\n    }\r\n\r\n    /**\r\n     * Serializes this Highlight layer\r\n     * @returns a serialized Highlight layer object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        serializationObject.customType = \"BABYLON.HighlightLayer\";\r\n\r\n        // Highlighted meshes\r\n        serializationObject.meshes = [];\r\n\r\n        const meshes = this._thinEffectLayer._meshes;\r\n        if (meshes) {\r\n            for (const m in meshes) {\r\n                const mesh = meshes[m];\r\n\r\n                if (mesh) {\r\n                    serializationObject.meshes.push({\r\n                        glowEmissiveOnly: mesh.glowEmissiveOnly,\r\n                        color: mesh.color.asArray(),\r\n                        meshId: mesh.mesh.id,\r\n                    });\r\n                }\r\n            }\r\n        }\r\n\r\n        // Excluded meshes\r\n        serializationObject.excludedMeshes = [];\r\n\r\n        const excludedMeshes = this._thinEffectLayer._excludedMeshes;\r\n        if (excludedMeshes) {\r\n            for (const e in excludedMeshes) {\r\n                const excludedMesh = excludedMeshes[e];\r\n\r\n                if (excludedMesh) {\r\n                    serializationObject.excludedMeshes.push(excludedMesh.mesh.id);\r\n                }\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Creates a Highlight layer from parsed Highlight layer data\r\n     * @param parsedHightlightLayer defines the Highlight layer data\r\n     * @param scene defines the current scene\r\n     * @param rootUrl defines the root URL containing the Highlight layer information\r\n     * @returns a parsed Highlight layer\r\n     */\r\n    public static override Parse(parsedHightlightLayer: any, scene: Scene, rootUrl: string): HighlightLayer {\r\n        const hl = SerializationHelper.Parse(() => new HighlightLayer(parsedHightlightLayer.name, scene, parsedHightlightLayer.options), parsedHightlightLayer, scene, rootUrl);\r\n        let index;\r\n\r\n        // Excluded meshes\r\n        for (index = 0; index < parsedHightlightLayer.excludedMeshes.length; index++) {\r\n            const mesh = scene.getMeshById(parsedHightlightLayer.excludedMeshes[index]);\r\n            if (mesh) {\r\n                hl.addExcludedMesh(<Mesh>mesh);\r\n            }\r\n        }\r\n\r\n        // Included meshes\r\n        for (index = 0; index < parsedHightlightLayer.meshes.length; index++) {\r\n            const highlightedMesh = parsedHightlightLayer.meshes[index];\r\n            const mesh = scene.getMeshById(highlightedMesh.meshId);\r\n\r\n            if (mesh) {\r\n                hl.addMesh(<Mesh>mesh, Color3.FromArray(highlightedMesh.color), highlightedMesh.glowEmissiveOnly);\r\n            }\r\n        }\r\n\r\n        return hl;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for highlightLayer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterHighlightLayer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.getHighlightLayerByName = function (name: string): Nullable<HighlightLayer> {\r\n        for (let index = 0; index < this.effectLayers?.length; index++) {\r\n            if (this.effectLayers[index].name === name && this.effectLayers[index].getEffectName() === HighlightLayer.EffectName) {\r\n                return (<any>this.effectLayers[index]) as HighlightLayer;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    RegisterClass(\"BABYLON.HighlightLayer\", HighlightLayer);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsColor3 } from \"../Misc/decorators\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Material } from \"../Materials/material.pure\";\r\nimport { EffectLayer } from \"./effectLayer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { ThinSelectionOutlineLayer, type IThinSelectionOutlineLayerOptions } from \"./thinSelectionOutlineLayer\";\r\nimport { DepthRenderer } from \"../Rendering/depthRenderer.pure\";\r\nimport { RegisterDepthRendererSceneComponent } from \"../Rendering/depthRendererSceneComponent.pure\";\r\n\r\nimport { type Color3 } from \"../Maths/math.color.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Selection outline layer options. This helps customizing the behaviour\r\n * of the selection outline layer.\r\n */\r\nexport interface ISelectionOutlineLayerOptions extends IThinSelectionOutlineLayerOptions {\r\n    /**\r\n     * Enable MSAA by choosing the number of samples. Default: 1\r\n     */\r\n    mainTextureSamples?: number;\r\n}\r\n\r\n/**\r\n * The selection outline layer Helps adding a outline effect around a mesh.\r\n *\r\n * Once instantiated in a scene, simply use the addMesh or removeMesh method to add or remove\r\n * outlined meshes to your scene.\r\n */\r\nexport class SelectionOutlineLayer extends EffectLayer {\r\n    /**\r\n     * Effect Name of the selection outline layer.\r\n     */\r\n    public static get EffectName() {\r\n        return ThinSelectionOutlineLayer.EffectName;\r\n    }\r\n\r\n    /**\r\n     * The outline color (default (1, 0.5, 0))\r\n     */\r\n    @serializeAsColor3()\r\n    public get outlineColor(): Color3 {\r\n        return this._thinEffectLayer.outlineColor;\r\n    }\r\n\r\n    public set outlineColor(value: Color3) {\r\n        this._thinEffectLayer.outlineColor = value;\r\n    }\r\n\r\n    /**\r\n     * The thickness of the edges (default: 2.0)\r\n     */\r\n    @serialize()\r\n    public get outlineThickness(): number {\r\n        return this._thinEffectLayer.outlineThickness;\r\n    }\r\n\r\n    public set outlineThickness(value: number) {\r\n        this._thinEffectLayer.outlineThickness = value;\r\n    }\r\n\r\n    /**\r\n     * The strength of the occlusion effect (default: 0.8)\r\n     */\r\n    @serialize()\r\n    public get occlusionStrength(): number {\r\n        return this._thinEffectLayer.occlusionStrength;\r\n    }\r\n\r\n    public set occlusionStrength(value: number) {\r\n        this._thinEffectLayer.occlusionStrength = value;\r\n    }\r\n\r\n    /**\r\n     * The occlusion threshold (default: 0.01)\r\n     */\r\n    @serialize()\r\n    public get occlusionThreshold(): number {\r\n        return this._thinEffectLayer.occlusionThreshold;\r\n    }\r\n\r\n    public set occlusionThreshold(value: number) {\r\n        this._thinEffectLayer.occlusionThreshold = value;\r\n    }\r\n\r\n    /**\r\n     * Whether to use depth when drawing selection outlines.\r\n     * Disable this to avoid depth renderer usage; selected outlines will not be clipped by scene or selected geometry.\r\n     */\r\n    @serialize()\r\n    public get useDepthOcclusion(): boolean {\r\n        return this._thinEffectLayer.useDepthOcclusion;\r\n    }\r\n\r\n    public set useDepthOcclusion(value: boolean) {\r\n        this._thinEffectLayer.useDepthOcclusion = value;\r\n        this._options.useDepthOcclusion = value;\r\n    }\r\n\r\n    @serialize(\"options\")\r\n    private _options: Required<ISelectionOutlineLayerOptions>;\r\n\r\n    declare protected readonly _thinEffectLayer: ThinSelectionOutlineLayer;\r\n\r\n    /**\r\n     * Instantiates a new selection outline Layer and references it to the scene..\r\n     * @param name The name of the layer\r\n     * @param scene The scene to use the layer in\r\n     * @param options Sets of none mandatory options to use with the layer (see ISelectionOutlineLayerOptions for more information)\r\n     */\r\n    public constructor(name: string, scene?: Scene, options?: Partial<ISelectionOutlineLayerOptions>) {\r\n        super(name, scene, options !== undefined ? !!options.forceGLSL : false, new ThinSelectionOutlineLayer(name, scene, options));\r\n\r\n        // Adapt options\r\n        this._options = {\r\n            mainTextureRatio: 1.0,\r\n            mainTextureFixedSize: 0,\r\n            alphaBlendingMode: Constants.ALPHA_COMBINE,\r\n            camera: null,\r\n            mainTextureSamples: 1,\r\n            renderingGroupId: -1,\r\n            mainTextureType: Constants.TEXTURETYPE_FLOAT,\r\n            mainTextureFormat: Constants.TEXTUREFORMAT_RG,\r\n            forceGLSL: false,\r\n            storeCameraSpaceZ: false,\r\n            outlineMethod: Constants.OUTLINELAYER_SAMPLING_TRIDIRECTIONAL,\r\n            useDepthOcclusion: true,\r\n            ...options,\r\n        };\r\n\r\n        // Fall back to a supported mask texture type if the device doesn't support rendering to float framebuffers\r\n        // or linear filtering of float textures (e.g. OES_texture_float_linear missing on some iOS versions)\r\n        if (this._options.mainTextureType === Constants.TEXTURETYPE_FLOAT && !(this._engine.getCaps().textureFloatRender && this._engine.getCaps().textureFloatLinearFiltering)) {\r\n            this._options.mainTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        }\r\n        if (this._options.mainTextureType === Constants.TEXTURETYPE_HALF_FLOAT && !this._engine.getCaps().textureHalfFloatRender && !this._options.storeCameraSpaceZ) {\r\n            this._options.mainTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        }\r\n\r\n        // Initialize the layer\r\n        this._init(this._options);\r\n\r\n        // Do not render as long as no meshes have been added\r\n        this._shouldRender = false;\r\n    }\r\n\r\n    private _enableDepthRenderer(): DepthRenderer {\r\n        RegisterDepthRendererSceneComponent(DepthRenderer);\r\n        return this._scene.enableDepthRenderer();\r\n    }\r\n\r\n    /**\r\n     * Checks if the layer is ready to render.\r\n     * When selections are active and depth occlusion is enabled, this also\r\n     * lazily creates the depth renderer and checks that its depth map is ready.\r\n     * @returns true if the layer is ready\r\n     */\r\n    public override isLayerReady(): boolean {\r\n        if (!super.isLayerReady()) {\r\n            return false;\r\n        }\r\n\r\n        if (this.shouldRender() && this.useDepthOcclusion && this.occlusionStrength > 0) {\r\n            const depthRenderer = this._enableDepthRenderer();\r\n            if (!depthRenderer.getDepthMap().isReadyForRendering()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Get the effect name of the layer.\r\n     * @returns The effect name\r\n     */\r\n    public getEffectName(): string {\r\n        return SelectionOutlineLayer.EffectName;\r\n    }\r\n\r\n    protected override _numInternalDraws(): number {\r\n        return 1; // draw depth mask on main pass and outline on merge pass\r\n    }\r\n\r\n    /**\r\n     * Create the merge effect. This is the shader use to blit the information back\r\n     * to the main canvas at the end of the scene rendering.\r\n     * @returns The effect created\r\n     */\r\n    protected _createMergeEffect(): Effect {\r\n        return this._thinEffectLayer._createMergeEffect();\r\n    }\r\n\r\n    /**\r\n     * Creates the render target textures and post processes used in the selection outline layer.\r\n     */\r\n    protected _createTextureAndPostProcesses(): void {\r\n        this._textures = [];\r\n\r\n        this._thinEffectLayer.bindTexturesForCompose = (effect: Effect): void => {\r\n            effect.setTexture(\"maskSampler\", this._mainTexture);\r\n            if (this.useDepthOcclusion && this.occlusionStrength > 0) {\r\n                const depthRenderer = this._enableDepthRenderer();\r\n                effect.setTexture(\"depthSampler\", depthRenderer.getDepthMap());\r\n            }\r\n\r\n            const mainTextureDesiredSize = this._mainTextureDesiredSize;\r\n            this._thinEffectLayer.textureWidth = mainTextureDesiredSize.width;\r\n            this._thinEffectLayer.textureHeight = mainTextureDesiredSize.height;\r\n        };\r\n\r\n        this._thinEffectLayer._createTextureAndPostProcesses();\r\n\r\n        this._postProcesses = [];\r\n\r\n        this._mainTexture.samples = this._options.mainTextureSamples;\r\n        this._mainTexture.onAfterUnbindObservable.add(() => {\r\n            // glow layer and highlight layer both call this._scene.postProcessManager.directRender\r\n            // when you call this._scene.postProcessManager.directRender, it has 4 side effects:\r\n            // 1. binds the framebuffer\r\n            // 2. setAlphaMode(ALPHA_DISABLE)\r\n            // 3. setDepthBuffer(true)\r\n            // 4. setDepthWrite(true)\r\n            // glow layer and highlight layer are restore framebuffer and depends on other side effects\r\n            // but for now 3 and 4 are not needed to resolve the state management issue, so we just restore alpha mode\r\n            this._scene.getEngine().setAlphaMode(Constants.ALPHA_DISABLE);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates the main texture for the effect layer.\r\n     */\r\n    protected override _createMainTexture(): void {\r\n        super._createMainTexture();\r\n        // set the render list for selective rendering\r\n        this._mainTexture.renderList = this._thinEffectLayer._selection;\r\n    }\r\n\r\n    /**\r\n     * @returns whether or not the layer needs stencil enabled during the mesh rendering.\r\n     */\r\n    public needStencil(): boolean {\r\n        return this._thinEffectLayer.needStencil();\r\n    }\r\n\r\n    /**\r\n     * Checks for the readiness of the element composing the layer.\r\n     * @param subMesh the mesh to check for\r\n     * @param useInstances specify whether or not to use instances to render the mesh\r\n     * @returns true if ready otherwise, false\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        return this._thinEffectLayer.isReady(subMesh, useInstances);\r\n    }\r\n\r\n    /**\r\n     * Implementation specific of rendering the generating effect on the main canvas.\r\n     * @param effect The effect used to render through\r\n     * @param renderIndex\r\n     */\r\n    protected _internalRender(effect: Effect, renderIndex: number): void {\r\n        this._thinEffectLayer._internalCompose(effect, renderIndex);\r\n    }\r\n\r\n    /**\r\n     * @returns true if the layer contains information to display, otherwise false.\r\n     */\r\n    public override shouldRender(): boolean {\r\n        return this._thinEffectLayer.shouldRender();\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh should render, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @returns true if it should render otherwise false\r\n     */\r\n    protected override _shouldRenderMesh(mesh: Mesh): boolean {\r\n        return this._thinEffectLayer._shouldRenderMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Returns true if the mesh can be rendered, otherwise false.\r\n     * @param mesh The mesh to render\r\n     * @param material The material used on the mesh\r\n     * @returns true if it can be rendered otherwise false\r\n     */\r\n    protected override _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {\r\n        return this._thinEffectLayer._canRenderMesh(mesh, material);\r\n    }\r\n\r\n    /**\r\n     * Adds specific effects defines.\r\n     * @param defines The defines to add specifics to.\r\n     */\r\n    protected override _addCustomEffectDefines(defines: string[]): void {\r\n        this._thinEffectLayer._addCustomEffectDefines(defines);\r\n    }\r\n\r\n    /**\r\n     * Sets the required values for both the emissive texture and and the main color.\r\n     * @param mesh\r\n     * @param subMesh\r\n     * @param material\r\n     */\r\n    protected _setEmissiveTextureAndColor(mesh: Mesh, subMesh: SubMesh, material: Material): void {\r\n        this._thinEffectLayer._setEmissiveTextureAndColor(mesh, subMesh, material);\r\n    }\r\n\r\n    /**\r\n     * Determine if a given mesh will be highlighted by the current SelectionOutlineLayer\r\n     * @param mesh mesh to test\r\n     * @returns true if the mesh will be highlighted by the current SelectionOutlineLayer\r\n     */\r\n    public override hasMesh(mesh: AbstractMesh): boolean {\r\n        return this._thinEffectLayer.hasMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Remove all the meshes currently referenced in the selection outline layer\r\n     */\r\n    public clearSelection(): void {\r\n        this._thinEffectLayer.clearSelection();\r\n        this._mainTexture.renderList = this._thinEffectLayer._selection; // update render list\r\n    }\r\n\r\n    /**\r\n     * Adds mesh or group of mesh to the current selection\r\n     *\r\n     * If a group of meshes is provided, they will outline as a single unit\r\n     * @param meshOrGroup Meshes to add to the selection\r\n     */\r\n    public addSelection(meshOrGroup: AbstractMesh | AbstractMesh[]): void {\r\n        this._thinEffectLayer.addSelection(meshOrGroup);\r\n    }\r\n\r\n    /**\r\n     * Free any resources and references associated to a mesh.\r\n     * Internal use\r\n     * @param mesh The mesh to free.\r\n     * @internal\r\n     */\r\n    public _disposeMesh(mesh: Mesh): void {\r\n        this._thinEffectLayer._disposeMesh(mesh);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of the effect layer\r\n     * @returns the string with the class name of the effect layer\r\n     */\r\n    public override getClassName(): string {\r\n        return \"SelectionOutlineLayer\";\r\n    }\r\n\r\n    /**\r\n     * Serializes this SelectionOutline layer\r\n     * @returns a serialized SelectionOutline layer object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        serializationObject.customType = \"BABYLON.SelectionOutlineLayer\";\r\n\r\n        // Selected meshes\r\n        serializationObject.selection = [];\r\n\r\n        const selection = this._thinEffectLayer._selection;\r\n        if (selection) {\r\n            const meshUniqueIdToSelectionId = this._thinEffectLayer._meshUniqueIdToSelectionId;\r\n\r\n            // selection can be sparse since _removeMesh can remove entries\r\n            const selectionMap: {\r\n                [uniqueId: number]: {\r\n                    meshIds: string[];\r\n                };\r\n            } = {};\r\n\r\n            for (let i = 0; i < selection.length; ++i) {\r\n                const mesh = selection[i];\r\n                const selectionId = meshUniqueIdToSelectionId[mesh.uniqueId];\r\n\r\n                if (!selectionMap[selectionId]) {\r\n                    selectionMap[selectionId] = {\r\n                        meshIds: [],\r\n                    };\r\n                }\r\n                selectionMap[selectionId].meshIds.push(mesh.id);\r\n            }\r\n            serializationObject.selection = selectionMap;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Creates a SelectionOutline layer from parsed SelectionOutline layer data\r\n     * @param parsedSelectionOutlineLayer defines the SelectionOutline layer data\r\n     * @param scene defines the current scene\r\n     * @param rootUrl defines the root URL containing the SelectionOutline layer information\r\n     * @returns a parsed SelectionOutline layer\r\n     */\r\n    public static override Parse(parsedSelectionOutlineLayer: any, scene: Scene, rootUrl: string): SelectionOutlineLayer {\r\n        const selectionOutlineLayer = SerializationHelper.Parse(\r\n            () => new SelectionOutlineLayer(parsedSelectionOutlineLayer.name, scene, parsedSelectionOutlineLayer.options),\r\n            parsedSelectionOutlineLayer,\r\n            scene,\r\n            rootUrl\r\n        );\r\n\r\n        const selectionMap = parsedSelectionOutlineLayer.selection as { [uniqueId: number]: { meshIds: string[] } };\r\n\r\n        // Selected meshes\r\n        for (const outlinedMeshes of Object.values(selectionMap)) {\r\n            const meshes: AbstractMesh[] = [];\r\n            for (let meshIndex = 0; meshIndex < outlinedMeshes.meshIds.length; meshIndex++) {\r\n                const meshId = outlinedMeshes.meshIds[meshIndex];\r\n                const mesh = scene.getMeshById(meshId);\r\n                if (mesh) {\r\n                    meshes.push(mesh);\r\n                }\r\n            }\r\n\r\n            selectionOutlineLayer.addSelection(meshes);\r\n        }\r\n\r\n        return selectionOutlineLayer;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for selectionOutlineLayer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSelectionOutlineLayer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.getSelectionOutlineLayerByName = function (name: string): Nullable<SelectionOutlineLayer> {\r\n        for (let index = 0; index < this.effectLayers?.length; index++) {\r\n            if (this.effectLayers[index].name === name && this.effectLayers[index].getEffectName() === SelectionOutlineLayer.EffectName) {\r\n                return (<any>this.effectLayers[index]) as SelectionOutlineLayer;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    RegisterClass(\"BABYLON.SelectionOutlineLayer\", SelectionOutlineLayer);\r\n}\r\n","import { type Camera } from \"../Cameras/camera\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type ISceneComponent, SceneComponentConstants } from \"../sceneComponent\";\r\nimport { type Layer } from \"./layer\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\n\r\n/**\r\n * Defines the layer scene component responsible to manage any layers\r\n * in a given scene.\r\n */\r\nexport class LayerSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_LAYER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    private _engine: AbstractEngine;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene?: Scene) {\r\n        this.scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n        if (!this.scene) {\r\n            return;\r\n        }\r\n        this._engine = this.scene.getEngine();\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);\r\n        this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForegroundWithPostProcessing);\r\n        this.scene._afterCameraPostProcessStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERAPOSTPROCESS_LAYER, this, this._drawCameraForegroundWithoutPostProcessing);\r\n\r\n        this.scene._beforeRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);\r\n        this.scene._afterRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForegroundWithPostProcessing);\r\n        this.scene._afterRenderTargetPostProcessStage.registerStep(\r\n            SceneComponentConstants.STEP_AFTERRENDERTARGETPOSTPROCESS_LAYER,\r\n            this,\r\n            this._drawRenderTargetForegroundWithoutPostProcessing\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        const layers = this.scene.layers;\r\n\r\n        for (const layer of layers) {\r\n            layer._rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        const layers = this.scene.layers;\r\n\r\n        while (layers.length) {\r\n            layers[0].dispose();\r\n        }\r\n    }\r\n\r\n    private _draw(predicate: (layer: Layer) => boolean): void {\r\n        const layers = this.scene.layers;\r\n\r\n        if (layers.length) {\r\n            this._engine.setDepthBuffer(false);\r\n            for (const layer of layers) {\r\n                if (predicate(layer)) {\r\n                    layer.render();\r\n                }\r\n            }\r\n            this._engine.setDepthBuffer(true);\r\n        }\r\n    }\r\n\r\n    private _drawCameraPredicate(layer: Layer, isBackground: boolean, applyPostProcess: boolean, cameraLayerMask: number): boolean {\r\n        return (\r\n            !layer.renderOnlyInRenderTargetTextures &&\r\n            layer.isBackground === isBackground &&\r\n            layer.applyPostProcess === applyPostProcess &&\r\n            (layer.layerMask & cameraLayerMask) !== 0\r\n        );\r\n    }\r\n\r\n    private _drawCameraBackground(camera: Camera): void {\r\n        this._draw((layer: Layer) => {\r\n            return this._drawCameraPredicate(layer, true, true, camera.layerMask);\r\n        });\r\n    }\r\n\r\n    private _drawCameraForegroundWithPostProcessing(camera: Camera): void {\r\n        this._draw((layer: Layer) => {\r\n            return this._drawCameraPredicate(layer, false, true, camera.layerMask);\r\n        });\r\n    }\r\n\r\n    private _drawCameraForegroundWithoutPostProcessing(camera: Camera): void {\r\n        this._draw((layer: Layer) => {\r\n            return this._drawCameraPredicate(layer, false, false, camera.layerMask);\r\n        });\r\n    }\r\n\r\n    private _drawRenderTargetPredicate(layer: Layer, isBackground: boolean, applyPostProcess: boolean, cameraLayerMask: number, renderTargetTexture: RenderTargetTexture): boolean {\r\n        return (\r\n            layer.renderTargetTextures.length > 0 &&\r\n            layer.isBackground === isBackground &&\r\n            layer.applyPostProcess === applyPostProcess &&\r\n            layer.renderTargetTextures.indexOf(renderTargetTexture) > -1 &&\r\n            (layer.layerMask & cameraLayerMask) !== 0\r\n        );\r\n    }\r\n\r\n    private _drawRenderTargetBackground(renderTarget: RenderTargetTexture): void {\r\n        this._draw((layer: Layer) => {\r\n            return this._drawRenderTargetPredicate(layer, true, true, this.scene.activeCamera ? this.scene.activeCamera.layerMask : 0, renderTarget);\r\n        });\r\n    }\r\n\r\n    private _drawRenderTargetForegroundWithPostProcessing(renderTarget: RenderTargetTexture): void {\r\n        this._draw((layer: Layer) => {\r\n            return this._drawRenderTargetPredicate(layer, false, true, this.scene.activeCamera ? this.scene.activeCamera.layerMask : 0, renderTarget);\r\n        });\r\n    }\r\n\r\n    private _drawRenderTargetForegroundWithoutPostProcessing(renderTarget: RenderTargetTexture): void {\r\n        this._draw((layer: Layer) => {\r\n            return this._drawRenderTargetPredicate(layer, false, false, this.scene.activeCamera ? this.scene.activeCamera.layerMask : 0, renderTarget);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     * @param container the container holding the elements\r\n     */\r\n    public addFromContainer(container: IAssetContainer): void {\r\n        if (!container.layers) {\r\n            return;\r\n        }\r\n        for (const layer of container.layers) {\r\n            this.scene.layers.push(layer);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     * @param container contains the elements to remove\r\n     * @param dispose if the removed element should be disposed (default: false)\r\n     */\r\n    public removeFromContainer(container: IAssetContainer, dispose = false): void {\r\n        if (!container.layers) {\r\n            return;\r\n        }\r\n        for (const layer of container.layers) {\r\n            const index = this.scene.layers.indexOf(layer);\r\n            if (index !== -1) {\r\n                this.scene.layers.splice(index, 1);\r\n            }\r\n            if (dispose) {\r\n                layer.dispose();\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { SceneComponentConstants } from \"../sceneComponent\";\r\nimport { LayerSceneComponent } from \"./layerSceneComponent\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * This represents a full screen 2d layer.\r\n * This can be useful to display a picture in the  background of your scene for instance.\r\n * @see https://www.babylonjs-playground.com/#08A2BS#1\r\n */\r\nexport class Layer {\r\n    /**\r\n     * Force all the layers to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n    /**\r\n     * Define the texture the layer should display.\r\n     */\r\n    public texture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Is the layer in background or foreground.\r\n     */\r\n    public isBackground: boolean;\r\n\r\n    private _applyPostProcess: boolean = true;\r\n    /**\r\n     * Determines if the layer is drawn before (true) or after (false) post-processing.\r\n     * If the layer is background, it is always before.\r\n     */\r\n    public set applyPostProcess(value: boolean) {\r\n        this._applyPostProcess = value;\r\n    }\r\n    public get applyPostProcess(): boolean {\r\n        return this.isBackground || this._applyPostProcess;\r\n    }\r\n\r\n    /**\r\n     * Define the color of the layer (instead of texture).\r\n     */\r\n    public color: Color4;\r\n\r\n    /**\r\n     * Define the scale of the layer in order to zoom in out of the texture.\r\n     */\r\n    public scale = new Vector2(1, 1);\r\n\r\n    /**\r\n     * Define an offset for the layer in order to shift the texture.\r\n     */\r\n    public offset = new Vector2(0, 0);\r\n\r\n    /**\r\n     * Define the alpha blending mode used in the layer in case the texture or color has an alpha.\r\n     */\r\n    public alphaBlendingMode = Constants.ALPHA_COMBINE;\r\n\r\n    /**\r\n     * Define if the layer should alpha test or alpha blend with the rest of the scene.\r\n     * Alpha test will not mix with the background color in case of transparency.\r\n     * It will either use the texture color or the background depending on the alpha value of the current pixel.\r\n     */\r\n    public alphaTest: boolean;\r\n\r\n    /**\r\n     * Define a mask to restrict the layer to only some of the scene cameras.\r\n     */\r\n    public layerMask: number = 0x0fffffff;\r\n\r\n    /**\r\n     * Define the list of render target the layer is visible into.\r\n     */\r\n    public renderTargetTextures: RenderTargetTexture[] = [];\r\n\r\n    /**\r\n     * Define if the layer is only used in renderTarget or if it also\r\n     * renders in the main frame buffer of the canvas.\r\n     */\r\n    public renderOnlyInRenderTargetTextures = false;\r\n\r\n    /**\r\n     * Define if the colors of the layer should be generated in linear space (default: false)\r\n     */\r\n    public convertToLinearSpace = false;\r\n\r\n    /**\r\n     * Define if the layer is enabled (ie. should be displayed). Default: true\r\n     */\r\n    public isEnabled = true;\r\n\r\n    private _scene: Scene;\r\n    private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _drawWrapper: DrawWrapper;\r\n    private _previousDefines: string;\r\n\r\n    /**\r\n     * An event triggered when the layer is disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<Layer>();\r\n\r\n    private _onDisposeObserver: Nullable<Observer<Layer>>;\r\n    /**\r\n     * Back compatibility with callback before the onDisposeObservable existed.\r\n     * The set callback will be triggered when the layer has been disposed.\r\n     */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered before rendering the scene\r\n     */\r\n    public onBeforeRenderObservable = new Observable<Layer>();\r\n\r\n    private _onBeforeRenderObserver: Nullable<Observer<Layer>>;\r\n    /**\r\n     * Back compatibility with callback before the onBeforeRenderObservable existed.\r\n     * The set callback will be triggered just before rendering the layer.\r\n     */\r\n    public set onBeforeRender(callback: () => void) {\r\n        if (this._onBeforeRenderObserver) {\r\n            this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n        }\r\n        this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * An event triggered after rendering the scene\r\n     */\r\n    public onAfterRenderObservable = new Observable<Layer>();\r\n\r\n    private _onAfterRenderObserver: Nullable<Observer<Layer>>;\r\n    /**\r\n     * Back compatibility with callback before the onAfterRenderObservable existed.\r\n     * The set callback will be triggered just after rendering the layer.\r\n     */\r\n    public set onAfterRender(callback: () => void) {\r\n        if (this._onAfterRenderObserver) {\r\n            this.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n        }\r\n        this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);\r\n    }\r\n\r\n    /** Shader language used by the material */\r\n    private _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new layer.\r\n     * This represents a full screen 2d layer.\r\n     * This can be useful to display a picture in the  background of your scene for instance.\r\n     * @see https://www.babylonjs-playground.com/#08A2BS#1\r\n     * @param name Define the name of the layer in the scene\r\n     * @param imgUrl Define the url of the texture to display in the layer\r\n     * @param scene Define the scene the layer belongs to\r\n     * @param isBackground Defines whether the layer is displayed in front or behind the scene\r\n     * @param color Defines a color for the layer\r\n     * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false\r\n     */\r\n    constructor(\r\n        /**\r\n         * Define the name of the layer.\r\n         */\r\n        public name: string,\r\n        imgUrl: Nullable<string>,\r\n        scene: Nullable<Scene>,\r\n        isBackground?: boolean,\r\n        color?: Color4,\r\n        forceGLSL = false\r\n    ) {\r\n        if (!scene) {\r\n            scene = EngineStore.LastCreatedScene!;\r\n        }\r\n        this.layerMask = scene.defaultRenderableLayerMask;\r\n\r\n        this.texture = imgUrl ? new Texture(imgUrl, scene, true) : null;\r\n        this.isBackground = isBackground === undefined ? true : isBackground;\r\n        this.color = color === undefined ? new Color4(1, 1, 1, 1) : color;\r\n\r\n        this._scene = scene;\r\n\r\n        const engine = this._scene.getEngine();\r\n        if (engine.isWebGPU && !forceGLSL && !Layer.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        let layerComponent = this._scene._getComponent(SceneComponentConstants.NAME_LAYER) as LayerSceneComponent;\r\n        if (!layerComponent) {\r\n            layerComponent = new LayerSceneComponent(this._scene);\r\n            this._scene._addComponent(layerComponent);\r\n        }\r\n        this._scene.layers.push(this);\r\n\r\n        this._drawWrapper = new DrawWrapper(engine);\r\n\r\n        // VBO\r\n        const vertices = [];\r\n        vertices.push(1, 1);\r\n        vertices.push(-1, 1);\r\n        vertices.push(-1, -1);\r\n        vertices.push(1, -1);\r\n\r\n        const vertexBuffer = new VertexBuffer(engine, vertices, VertexBuffer.PositionKind, false, false, 2);\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = vertexBuffer;\r\n\r\n        this._createIndexBuffer();\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n\r\n    private _createIndexBuffer(): void {\r\n        const engine = this._scene.getEngine();\r\n\r\n        // Indices\r\n        const indices = [];\r\n        indices.push(0);\r\n        indices.push(1);\r\n        indices.push(2);\r\n\r\n        indices.push(0);\r\n        indices.push(2);\r\n        indices.push(3);\r\n\r\n        this._indexBuffer = engine.createIndexBuffer(indices);\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        const vb = this._vertexBuffers[VertexBuffer.PositionKind];\r\n\r\n        if (vb) {\r\n            vb._rebuild();\r\n        }\r\n\r\n        this._createIndexBuffer();\r\n    }\r\n\r\n    /**\r\n     * Checks if the layer is ready to be rendered\r\n     * @returns true if the layer is ready. False otherwise.\r\n     */\r\n    public isReady() {\r\n        const engine = this._scene.getEngine();\r\n\r\n        let defines = \"\";\r\n\r\n        if (this.alphaTest) {\r\n            defines = \"#define ALPHATEST\";\r\n        }\r\n\r\n        if (this.texture) {\r\n            if (this.texture.gammaSpace) {\r\n                if (this.convertToLinearSpace) {\r\n                    defines += \"\\n#define CONVERT_TO_LINEAR\";\r\n                }\r\n            } else if (!this.convertToLinearSpace) {\r\n                defines += \"\\n#define CONVERT_TO_GAMMA\";\r\n            }\r\n        }\r\n\r\n        if (this._previousDefines !== defines) {\r\n            this._previousDefines = defines;\r\n            this._drawWrapper.effect = engine.createEffect(\r\n                \"layer\",\r\n                [VertexBuffer.PositionKind],\r\n                [\"textureMatrix\", \"color\", \"scale\", \"offset\"],\r\n                [\"textureSampler\"],\r\n                defines,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                this._shaderLanguage,\r\n                this._shadersLoaded\r\n                    ? undefined\r\n                    : async () => {\r\n                          if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                              await Promise.all([import(\"../ShadersWGSL/layer.vertex\"), import(\"../ShadersWGSL/layer.fragment\")]);\r\n                          } else {\r\n                              await Promise.all([import(\"../Shaders/layer.vertex\"), import(\"../Shaders/layer.fragment\")]);\r\n                          }\r\n                          this._shadersLoaded = true;\r\n                      }\r\n            );\r\n        }\r\n\r\n        const currentEffect = this._drawWrapper.effect;\r\n\r\n        return !!currentEffect?.isReady() && (!this.texture || this.texture.isReady());\r\n    }\r\n\r\n    /**\r\n     * Renders the layer in the scene.\r\n     */\r\n    public render(): void {\r\n        if (!this.isEnabled) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        // Check\r\n        if (!this.isReady()) {\r\n            return;\r\n        }\r\n\r\n        const currentEffect = this._drawWrapper.effect!;\r\n\r\n        this.onBeforeRenderObservable.notifyObservers(this);\r\n\r\n        // Render\r\n        engine.enableEffect(this._drawWrapper);\r\n        engine.setState(false);\r\n\r\n        // Texture\r\n        if (this.texture) {\r\n            currentEffect.setTexture(\"textureSampler\", this.texture);\r\n            currentEffect.setMatrix(\"textureMatrix\", this.texture.getTextureMatrix());\r\n        }\r\n\r\n        // Color\r\n        currentEffect.setFloat4(\"color\", this.color.r, this.color.g, this.color.b, this.color.a);\r\n\r\n        // Scale / offset\r\n        currentEffect.setVector2(\"offset\", this.offset);\r\n        currentEffect.setVector2(\"scale\", this.scale);\r\n\r\n        // VBOs\r\n        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, currentEffect);\r\n\r\n        // Draw order\r\n        if (!this.alphaTest) {\r\n            engine.setAlphaMode(this.alphaBlendingMode);\r\n            engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n            engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        } else {\r\n            engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n        }\r\n\r\n        this.onAfterRenderObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Disposes and releases the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        const vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (vertexBuffer) {\r\n            vertexBuffer.dispose();\r\n            this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this._scene.getEngine()._releaseBuffer(this._indexBuffer);\r\n            this._indexBuffer = null;\r\n        }\r\n\r\n        if (this.texture) {\r\n            this.texture.dispose();\r\n            this.texture = null;\r\n        }\r\n\r\n        // Clean RTT list\r\n        this.renderTargetTextures = [];\r\n\r\n        // Remove from scene\r\n        const index = this._scene.layers.indexOf(this);\r\n        this._scene.layers.splice(index, 1);\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n\r\n        this.onDisposeObservable.clear();\r\n        this.onAfterRenderObservable.clear();\r\n        this.onBeforeRenderObservable.clear();\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"helperFunctions\";\nconst shader = `const float PI=3.1415926535897932384626433832795;const float TWO_PI=6.283185307179586;const float HALF_PI=1.5707963267948966;const float RECIPROCAL_PI=0.3183098861837907;const float RECIPROCAL_PI2=0.15915494309189535;const float RECIPROCAL_PI4=0.07957747154594767;const float HALF_MIN=5.96046448e-08; \nconst float LinearEncodePowerApprox=2.2;const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);const float Epsilon=0.0000001;\n#define saturate(x) clamp(x,0.0,1.0)\n#define absEps(x) abs(x)+Epsilon\n#define maxEps(x) max(x,Epsilon)\n#define saturateEps(x) clamp(x,Epsilon,1.0)\nmat3 transposeMat3(mat3 inMatrix) {vec3 i0=inMatrix[0];vec3 i1=inMatrix[1];vec3 i2=inMatrix[2];mat3 outMatrix=mat3(\nvec3(i0.x,i1.x,i2.x),\nvec3(i0.y,i1.y,i2.y),\nvec3(i0.z,i1.z,i2.z)\n);return outMatrix;}\nmat3 inverseMat3(mat3 inMatrix) {float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];float b01=a22*a11-a12*a21;float b11=-a22*a10+a12*a20;float b21=a21*a10-a11*a20;float det=a00*b01+a01*b11+a02*b21;return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),\nb11,(a22*a00-a02*a20),(-a12*a00+a02*a10),\nb21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;}\n#if USE_EXACT_SRGB_CONVERSIONS\nvec3 toLinearSpaceExact(vec3 color)\n{vec3 nearZeroSection=0.0773993808*color;vec3 remainingSection=pow(0.947867299*(color+vec3(0.055)),vec3(2.4));\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nreturn mix(remainingSection,nearZeroSection,lessThanEqual(color,vec3(0.04045)));\n#else\nreturn\nvec3(\ncolor.r<=0.04045 ? nearZeroSection.r : remainingSection.r,\ncolor.g<=0.04045 ? nearZeroSection.g : remainingSection.g,\ncolor.b<=0.04045 ? nearZeroSection.b : remainingSection.b);\n#endif\n}\nvec3 toGammaSpaceExact(vec3 color)\n{vec3 nearZeroSection=12.92*color;vec3 remainingSection=1.055*pow(color,vec3(0.41666))-vec3(0.055);\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nreturn mix(remainingSection,nearZeroSection,lessThanEqual(color,vec3(0.0031308)));\n#else\nreturn\nvec3(\ncolor.r<=0.0031308 ? nearZeroSection.r : remainingSection.r,\ncolor.g<=0.0031308 ? nearZeroSection.g : remainingSection.g,\ncolor.b<=0.0031308 ? nearZeroSection.b : remainingSection.b);\n#endif\n}\n#endif\nfloat toLinearSpace(float color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nfloat nearZeroSection=0.0773993808*color;float remainingSection=pow(0.947867299*(color+0.055),2.4);return color<=0.04045 ? nearZeroSection : remainingSection;\n#else\nreturn pow(color,LinearEncodePowerApprox);\n#endif\n}\nvec3 toLinearSpace(vec3 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toLinearSpaceExact(color);\n#else\nreturn pow(color,vec3(LinearEncodePowerApprox));\n#endif\n}\nvec4 toLinearSpace(vec4 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4(toLinearSpaceExact(color.rgb),color.a);\n#else\nreturn vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);\n#endif\n}\nfloat toGammaSpace(float color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nfloat nearZeroSection=12.92*color;float remainingSection=1.055*pow(color,0.41666)-0.055;return color<=0.0031308 ? nearZeroSection : remainingSection;\n#else\nreturn pow(color,GammaEncodePowerApprox);\n#endif\n}\nvec3 toGammaSpace(vec3 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toGammaSpaceExact(color);\n#else\nreturn pow(color,vec3(GammaEncodePowerApprox));\n#endif\n}\nvec4 toGammaSpace(vec4 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4(toGammaSpaceExact(color.rgb),color.a);\n#else\nreturn vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);\n#endif\n}\nfloat square(float value)\n{return value*value;}\nvec3 square(vec3 value)\n{return value*value;}\nfloat pow5(float value) {float sq=value*value;return sq*sq*value;}\nvec3 double_refract(vec3 I,vec3 N,float eta) {vec3 Tfront=refract(I,N,1.0/eta);vec3 Nback=normalize(reflect(N,Tfront));return refract(Tfront,-Nback,eta);}\nfloat getLuminanceUnclamped(vec3 color)\n{return dot(color,LuminanceEncodeApprox);}\nfloat getLuminance(vec3 color)\n{return saturate(getLuminanceUnclamped(color));}\nfloat getRand(vec2 seed) {return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);}\nfloat dither(vec2 seed,float varianceAmount) {float rand=getRand(seed);float normVariance=varianceAmount/255.0;float dither=mix(-normVariance,normVariance,rand);return dither;}\nconst float rgbdMaxRange=255.;vec4 toRGBD(vec3 color) {float maxRGB=maxEps(max(color.r,max(color.g,color.b)));float D =max(rgbdMaxRange/maxRGB,1.);D =saturate(floor(D)/255.);vec3 rgb=color.rgb*D;rgb=toGammaSpace(rgb);return vec4(saturate(rgb),D);}\nvec3 fromRGBD(vec4 rgbd) {rgbd.rgb=toLinearSpace(rgbd.rgb);return rgbd.rgb/rgbd.a;}\nvec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {vec3 invOrigVec=vec3(1.)/origVec;vec3 halfSize=cubeSize*0.5;vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);vec3 intersectPositionWS=vertexPos+origVec*distance;return intersectPositionWS-cubePos;}\nvec3 equirectangularToCubemapDirection(vec2 uv) {float longitude=uv.x*TWO_PI-PI;float latitude=HALF_PI-uv.y*PI;vec3 direction;direction.x=cos(latitude)*sin(longitude);direction.y=sin(latitude);direction.z=cos(latitude)*cos(longitude);return direction;}\nfloat sqrtClamped(float value) {return sqrt(max(value,0.));}\nfloat avg(vec3 value) {return dot(value,vec3(0.333333333));}\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nprecision highp int;uint extractBits(uint value,int offset,int width) {return (value>>offset) & ((1u<<width)-1u);}\nint onlyBitPosition(uint value) {return (floatBitsToInt(float(value))>>23)-0x7f;}\nvec3 singleScatterToMultiScatterAlbedo(vec3 rho_ss) {vec3 s=sqrt(max(vec3(1.0)-rho_ss,vec3(0.0)));return (vec3(1.0)-s)*(vec3(1.0)-vec3(0.139)*s)/(vec3(1.0)+vec3(1.17)*s);}\nvec3 multiScatterToSingleScatterAlbedo(vec3 rho_ms) {vec3 s=4.09712+4.20863*rho_ms-sqrt(9.59217+41.6808*rho_ms+17.7126*rho_ms*rho_ms);return 1.0-s*s;}\nvec3 multiScatterToSingleScatterAlbedo(vec3 rho_ms,float aniso) {vec3 s=4.09712+4.20863*rho_ms-sqrt(9.59217+41.6808*rho_ms+17.7126*rho_ms*rho_ms);return (1.0-s*s)/maxEps(1.0-aniso*s*s);}\nfloat min3(vec3 v) {return min(v.x,min(v.y,v.z));}\nfloat max3(vec3 v) {return max(v.x,max(v.y,v.z));}\nfloat uint2float(uint i) {return uintBitsToFloat(0x3F800000u | (i>>9u))-1.0;}\nvec2 plasticSequence(const uint rstate) {return vec2(uint2float(rstate*3242174889u),\nuint2float(rstate*2447445414u));}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const helperFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneFragmentDeclaration\";\nconst shader = `#ifdef CLIPPLANE\nvarying float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nvarying float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nvarying float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nvarying float fClipDistance4;\n#endif\n#ifdef CLIPPLANE5\nvarying float fClipDistance5;\n#endif\n#ifdef CLIPPLANE6\nvarying float fClipDistance6;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clipPlaneFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneFragment\";\nconst shader = `#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6)\nif (false) {}\n#endif\n#ifdef CLIPPLANE\nelse if (fClipDistance>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE2\nelse if (fClipDistance2>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE3\nelse if (fClipDistance3>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE4\nelse if (fClipDistance4>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE5\nelse if (fClipDistance5>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE6\nelse if (fClipDistance6>0.0)\n{discard;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clipPlaneFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"glowMapGenerationPixelShader\";\nconst shader = `#if defined(DIFFUSE_ISLINEAR) || defined(EMISSIVE_ISLINEAR)\n#include<helperFunctions>\n#endif\n#ifdef DIFFUSE\nvarying vec2 vUVDiffuse;uniform sampler2D diffuseSampler;\n#endif\n#ifdef OPACITY\nvarying vec2 vUVOpacity;uniform sampler2D opacitySampler;uniform float opacityIntensity;\n#endif\n#ifdef EMISSIVE\nvarying vec2 vUVEmissive;uniform sampler2D emissiveSampler;\n#endif\n#ifdef VERTEXALPHA\nvarying vec4 vColor;\n#endif\nuniform vec4 glowColor;uniform float glowIntensity;\n#include<clipPlaneFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{\n#include<clipPlaneFragment>\nvec4 finalColor=glowColor;\n#ifdef DIFFUSE\nvec4 albedoTexture=texture2D(diffuseSampler,vUVDiffuse);\n#ifdef DIFFUSE_ISLINEAR\nalbedoTexture=toGammaSpace(albedoTexture);\n#endif\n#ifdef GLOW\nfinalColor.a*=albedoTexture.a;\n#endif\n#ifdef HIGHLIGHT\nfinalColor.a=albedoTexture.a;\n#endif\n#endif\n#ifdef OPACITY\nvec4 opacityMap=texture2D(opacitySampler,vUVOpacity);\n#ifdef OPACITYRGB\nfinalColor.a*=getLuminance(opacityMap.rgb);\n#else\nfinalColor.a*=opacityMap.a;\n#endif\nfinalColor.a*=opacityIntensity;\n#endif\n#ifdef VERTEXALPHA\nfinalColor.a*=vColor.a;\n#endif\n#ifdef ALPHATEST\nif (finalColor.a<ALPHATESTVALUE)\ndiscard;\n#endif\n#ifdef EMISSIVE\nvec4 emissive=texture2D(emissiveSampler,vUVEmissive);\n#ifdef EMISSIVE_ISLINEAR\nemissive=toGammaSpace(emissive);\n#endif\ngl_FragColor=emissive*finalColor*glowIntensity;\n#else\ngl_FragColor=finalColor*glowIntensity;\n#endif\n#ifdef HIGHLIGHT\ngl_FragColor.a=glowColor.a;\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, clipPlaneFragmentDeclaration, clipPlaneFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const glowMapGenerationPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneVertexDeclaration\";\nconst shader = `#ifdef CLIPPLANE\nuniform vec4 vClipPlane;varying float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nuniform vec4 vClipPlane2;varying float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nuniform vec4 vClipPlane3;varying float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nuniform vec4 vClipPlane4;varying float fClipDistance4;\n#endif\n#ifdef CLIPPLANE5\nuniform vec4 vClipPlane5;varying float fClipDistance5;\n#endif\n#ifdef CLIPPLANE6\nuniform vec4 vClipPlane6;varying float fClipDistance6;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clipPlaneVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneVertex\";\nconst shader = `#ifdef CLIPPLANE\nfClipDistance=dot(worldPos,vClipPlane);\n#endif\n#ifdef CLIPPLANE2\nfClipDistance2=dot(worldPos,vClipPlane2);\n#endif\n#ifdef CLIPPLANE3\nfClipDistance3=dot(worldPos,vClipPlane3);\n#endif\n#ifdef CLIPPLANE4\nfClipDistance4=dot(worldPos,vClipPlane4);\n#endif\n#ifdef CLIPPLANE5\nfClipDistance5=dot(worldPos,vClipPlane5);\n#endif\n#ifdef CLIPPLANE6\nfClipDistance6=dot(worldPos,vClipPlane6);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clipPlaneVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"glowMapGenerationVertexShader\";\nconst shader = `attribute vec3 position;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\n#include<instancesDeclaration>\nuniform mat4 viewProjection;varying vec4 vPosition;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef DIFFUSE\nvarying vec2 vUVDiffuse;uniform mat4 diffuseMatrix;\n#endif\n#ifdef OPACITY\nvarying vec2 vUVOpacity;uniform mat4 opacityMatrix;\n#endif\n#ifdef EMISSIVE\nvarying vec2 vUVEmissive;uniform mat4 emissiveMatrix;\n#endif\n#ifdef VERTEXALPHA\nattribute vec4 color;varying vec4 vColor;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void)\n{vec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\n#ifdef CUBEMAP\nvPosition=worldPos;gl_Position=viewProjection*finalWorld*vec4(position,1.0);\n#else\nvPosition=viewProjection*worldPos;gl_Position=vPosition;\n#endif\n#ifdef DIFFUSE\n#ifdef DIFFUSEUV1\nvUVDiffuse=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef DIFFUSEUV2\nvUVDiffuse=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#ifdef OPACITY\n#ifdef OPACITYUV1\nvUVOpacity=vec2(opacityMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef OPACITYUV2\nvUVOpacity=vec2(opacityMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#ifdef EMISSIVE\n#ifdef EMISSIVEUV1\nvUVEmissive=vec2(emissiveMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef EMISSIVEUV2\nvUVEmissive=vec2(emissiveMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#ifdef VERTEXALPHA\nvColor=color;\n#endif\n#include<clipPlaneVertex>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, clipPlaneVertexDeclaration, instancesDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const glowMapGenerationVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneFragmentDeclaration\";\nconst shader = `#ifdef CLIPPLANE\nvarying fClipDistance: f32;\n#endif\n#ifdef CLIPPLANE2\nvarying fClipDistance2: f32;\n#endif\n#ifdef CLIPPLANE3\nvarying fClipDistance3: f32;\n#endif\n#ifdef CLIPPLANE4\nvarying fClipDistance4: f32;\n#endif\n#ifdef CLIPPLANE5\nvarying fClipDistance5: f32;\n#endif\n#ifdef CLIPPLANE6\nvarying fClipDistance6: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const clipPlaneFragmentDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneFragment\";\nconst shader = `#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6)\nif (false) {}\n#endif\n#ifdef CLIPPLANE\nelse if (fragmentInputs.fClipDistance>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE2\nelse if (fragmentInputs.fClipDistance2>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE3\nelse if (fragmentInputs.fClipDistance3>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE4\nelse if (fragmentInputs.fClipDistance4>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE5\nelse if (fragmentInputs.fClipDistance5>0.0)\n{discard;}\n#endif\n#ifdef CLIPPLANE6\nelse if (fragmentInputs.fClipDistance6>0.0)\n{discard;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const clipPlaneFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"glowMapGenerationPixelShader\";\nconst shader = `#if defined(DIFFUSE_ISLINEAR) || defined(EMISSIVE_ISLINEAR)\n#include<helperFunctions>\n#endif\n#ifdef DIFFUSE\nvarying vUVDiffuse: vec2f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#ifdef OPACITY\nvarying vUVOpacity: vec2f;var opacitySamplerSampler: sampler;var opacitySampler: texture_2d<f32>;uniform opacityIntensity: f32;\n#endif\n#ifdef EMISSIVE\nvarying vUVEmissive: vec2f;var emissiveSamplerSampler: sampler;var emissiveSampler: texture_2d<f32>;\n#endif\n#ifdef VERTEXALPHA\nvarying vColor: vec4f;\n#endif\nuniform glowColor: vec4f;uniform glowIntensity: f32;\n#include<clipPlaneFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#include<clipPlaneFragment>\nvar finalColor: vec4f=uniforms.glowColor;\n#ifdef DIFFUSE\nvar albedoTexture: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,fragmentInputs.vUVDiffuse);\n#ifdef DIFFUSE_ISLINEAR\nalbedoTexture=toGammaSpace(albedoTexture);\n#endif\n#ifdef GLOW\nfinalColor=vec4f(finalColor.rgb,finalColor.a*albedoTexture.a);\n#endif\n#ifdef HIGHLIGHT\nfinalColor=vec4f(finalColor.rgb,albedoTexture.a);\n#endif\n#endif\n#ifdef OPACITY\nvar opacityMap: vec4f=textureSample(opacitySampler,opacitySamplerSampler,fragmentInputs.vUVOpacity);\n#ifdef OPACITYRGB\nfinalColor=vec4f(finalColor.rgb,finalColor.a*getLuminance(opacityMap.rgb));\n#else\nfinalColor=vec4f(finalColor.rgb,finalColor.a*opacityMap.a);\n#endif\nfinalColor=vec4f(finalColor.rgb,finalColor.a*uniforms.opacityIntensity);\n#endif\n#ifdef VERTEXALPHA\nfinalColor=vec4f(finalColor.rgb,finalColor.a*fragmentInputs.vColor.a);\n#endif\n#ifdef ALPHATEST\nif (finalColor.a<ALPHATESTVALUE) {discard;}\n#endif\n#ifdef EMISSIVE\nvar emissive: vec4f=textureSample(emissiveSampler,emissiveSamplerSampler,fragmentInputs.vUVEmissive);\n#ifdef EMISSIVE_ISLINEAR\nemissive=toGammaSpace(emissive);\n#endif\nfragmentOutputs.color=emissive*finalColor*uniforms.glowIntensity;\n#else\nfragmentOutputs.color=finalColor*uniforms.glowIntensity;\n#endif\n#ifdef HIGHLIGHT\nfragmentOutputs.color=vec4f(fragmentOutputs.color.rgb,uniforms.glowColor.a);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, clipPlaneFragmentDeclarationWGSL, clipPlaneFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const glowMapGenerationPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneVertexDeclaration\";\nconst shader = `#ifdef CLIPPLANE\nuniform vClipPlane: vec4<f32>;varying fClipDistance: f32;\n#endif\n#ifdef CLIPPLANE2\nuniform vClipPlane2: vec4<f32>;varying fClipDistance2: f32;\n#endif\n#ifdef CLIPPLANE3\nuniform vClipPlane3: vec4<f32>;varying fClipDistance3: f32;\n#endif\n#ifdef CLIPPLANE4\nuniform vClipPlane4: vec4<f32>;varying fClipDistance4: f32;\n#endif\n#ifdef CLIPPLANE5\nuniform vClipPlane5: vec4<f32>;varying fClipDistance5: f32;\n#endif\n#ifdef CLIPPLANE6\nuniform vClipPlane6: vec4<f32>;varying fClipDistance6: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const clipPlaneVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneVertex\";\nconst shader = `#ifdef CLIPPLANE\nvertexOutputs.fClipDistance=dot(worldPos,uniforms.vClipPlane);\n#endif\n#ifdef CLIPPLANE2\nvertexOutputs.fClipDistance2=dot(worldPos,uniforms.vClipPlane2);\n#endif\n#ifdef CLIPPLANE3\nvertexOutputs.fClipDistance3=dot(worldPos,uniforms.vClipPlane3);\n#endif\n#ifdef CLIPPLANE4\nvertexOutputs.fClipDistance4=dot(worldPos,uniforms.vClipPlane4);\n#endif\n#ifdef CLIPPLANE5\nvertexOutputs.fClipDistance5=dot(worldPos,uniforms.vClipPlane5);\n#endif\n#ifdef CLIPPLANE6\nvertexOutputs.fClipDistance6=dot(worldPos,uniforms.vClipPlane6);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const clipPlaneVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"glowMapGenerationVertexShader\";\nconst shader = `attribute position: vec3f;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;varying vPosition: vec4f;\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#ifdef DIFFUSE\nvarying vUVDiffuse: vec2f;uniform diffuseMatrix: mat4x4f;\n#endif\n#ifdef OPACITY\nvarying vUVOpacity: vec2f;uniform opacityMatrix: mat4x4f;\n#endif\n#ifdef EMISSIVE\nvarying vUVEmissive: vec2f;uniform emissiveMatrix: mat4x4f;\n#endif\n#ifdef VERTEXALPHA\nattribute color: vec4f;varying vColor: vec4f;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld* vec4f(positionUpdated,1.0);\n#ifdef CUBEMAP\nvertexOutputs.vPosition=worldPos;vertexOutputs.position=uniforms.viewProjection*finalWorld* vec4f(vertexInputs.position,1.0);\n#else\nvertexOutputs.vPosition=uniforms.viewProjection*worldPos;vertexOutputs.position=vertexOutputs.vPosition;\n#endif\n#ifdef DIFFUSE\n#ifdef DIFFUSEUV1\nvertexOutputs.vUVDiffuse= (uniforms.diffuseMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef DIFFUSEUV2\nvertexOutputs.vUVDiffuse= (uniforms.diffuseMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef OPACITY\n#ifdef OPACITYUV1\nvertexOutputs.vUVOpacity= (uniforms.opacityMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef OPACITYUV2\nvertexOutputs.vUVOpacity= (uniforms.opacityMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef EMISSIVE\n#ifdef EMISSIVEUV1\nvertexOutputs.vUVEmissive= (uniforms.emissiveMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef EMISSIVEUV2\nvertexOutputs.vUVEmissive= (uniforms.emissiveMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef VERTEXALPHA\nvertexOutputs.vColor=vertexInputs.color;\n#endif\n#include<clipPlaneVertex>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, instancesDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const glowMapGenerationVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"glowMapMergePixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;\n#ifdef EMISSIVE\nuniform sampler2D textureSampler2;\n#endif\nuniform float offset;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec4 baseColor=texture2D(textureSampler,vUV);\n#ifdef EMISSIVE\nbaseColor+=texture2D(textureSampler2,vUV);baseColor*=offset;\n#else\nbaseColor.a=abs(offset-baseColor.a);\n#ifdef STROKE\nfloat alpha=smoothstep(.0,.1,baseColor.a);baseColor.a=alpha;baseColor.rgb=baseColor.rgb*alpha;\n#endif\n#endif\n#if LDR\nbaseColor=clamp(baseColor,0.,1.0);\n#endif\ngl_FragColor=baseColor;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const glowMapMergePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"glowMapMergeVertexShader\";\nconst shader = `attribute vec2 position;varying vec2 vUV;const vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvUV=position*madd+madd;gl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const glowMapMergeVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"glowBlurPostProcessPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec2 screenSize;uniform vec2 direction;uniform float blurWidth;float getLuminance(vec3 color)\n{return dot(color,vec3(0.2126,0.7152,0.0722));}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{float weights[7];weights[0]=0.05;weights[1]=0.1;weights[2]=0.2;weights[3]=0.3;weights[4]=0.2;weights[5]=0.1;weights[6]=0.05;vec2 texelSize=vec2(1.0/screenSize.x,1.0/screenSize.y);vec2 texelStep=texelSize*direction*blurWidth;vec2 start=vUV-3.0*texelStep;vec4 baseColor=vec4(0.,0.,0.,0.);vec2 texelOffset=vec2(0.,0.);for (int i=0; i<7; i++)\n{vec4 texel=texture2D(textureSampler,start+texelOffset);baseColor.a+=texel.a*weights[i];float luminance=getLuminance(baseColor.rgb);float luminanceTexel=getLuminance(texel.rgb);float choice=step(luminanceTexel,luminance);baseColor.rgb=choice*baseColor.rgb+(1.0-choice)*texel.rgb;texelOffset+=texelStep;}\ngl_FragColor=baseColor;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const glowBlurPostProcessPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"glowMapMergePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#ifdef EMISSIVE\nvar textureSampler2Sampler: sampler;var textureSampler2: texture_2d<f32>;\n#endif\nuniform offset: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvar baseColor: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);\n#ifdef EMISSIVE\nbaseColor+=textureSample(textureSampler2,textureSampler2Sampler,input.vUV);baseColor*=uniforms.offset;\n#else\nbaseColor=vec4f(baseColor.rgb,abs(uniforms.offset-baseColor.a));\n#ifdef STROKE\nvar alpha: f32=smoothstep(.0,.1,baseColor.a);baseColor=vec4f(baseColor.rgb*alpha,alpha);\n#endif\n#endif\n#if LDR\nbaseColor=clamp(baseColor,vec4f(0.),vec4f(1.0));\n#endif\nfragmentOutputs.color=baseColor;\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const glowMapMergePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"glowMapMergeVertexShader\";\nconst shader = `attribute position: vec2f;varying vUV: vec2f;\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {const madd: vec2f= vec2f(0.5,0.5);\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.vUV=vertexInputs.position*madd+madd;vertexOutputs.position= vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const glowMapMergeVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"glowBlurPostProcessPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform screenSize: vec2f;uniform direction: vec2f;uniform blurWidth: f32;fn getLuminance(color: vec3f)->f32\n{return dot(color, vec3f(0.2126,0.7152,0.0722));}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var weights: array<f32 ,7>;weights[0]=0.05;weights[1]=0.1;weights[2]=0.2;weights[3]=0.3;weights[4]=0.2;weights[5]=0.1;weights[6]=0.05;var texelSize: vec2f= vec2f(1.0/uniforms.screenSize.x,1.0/uniforms.screenSize.y);var texelStep: vec2f=texelSize*uniforms.direction*uniforms.blurWidth;var start: vec2f=input.vUV-3.0*texelStep;var baseColor: vec4f= vec4f(0.,0.,0.,0.);var texelOffset: vec2f= vec2f(0.,0.);for (var i: i32=0; i<7; i++)\n{var texel: vec4f=textureSample(textureSampler,textureSamplerSampler,start+texelOffset);baseColor=vec4f(baseColor.rgb,baseColor.a+texel.a*weights[i]);var luminance: f32=getLuminance(baseColor.rgb);var luminanceTexel: f32=getLuminance(texel.rgb);var choice: f32=step(luminanceTexel,luminance);baseColor=vec4f(choice*baseColor.rgb+(1.0-choice)*texel.rgb,baseColor.a);texelOffset+=texelStep;}\nfragmentOutputs.color=baseColor;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const glowBlurPostProcessPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"layerPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec4 color;\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec4 baseColor=texture2D(textureSampler,vUV);\n#if defined(CONVERT_TO_GAMMA)\nbaseColor.rgb=toGammaSpace(baseColor.rgb);\n#elif defined(CONVERT_TO_LINEAR)\nbaseColor.rgb=toLinearSpace(baseColor.rgb);\n#endif\n#ifdef ALPHATEST\nif (baseColor.a<0.4)\ndiscard;\n#endif\ngl_FragColor=baseColor*color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const layerPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"layerVertexShader\";\nconst shader = `attribute vec2 position;uniform vec2 scale;uniform vec2 offset;uniform mat4 textureMatrix;varying vec2 vUV;const vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec2 shiftedPosition=position*scale+offset;vUV=vec2(textureMatrix*vec4(shiftedPosition*madd+madd,1.0,0.0));gl_Position=vec4(shiftedPosition,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const layerVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"layerPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform color: vec4f;\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvar baseColor: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);\n#if defined(CONVERT_TO_GAMMA)\nbaseColor=toGammaSpace(baseColor);\n#elif defined(CONVERT_TO_LINEAR)\nbaseColor=toLinearSpaceVec4(baseColor);\n#endif\n#ifdef ALPHATEST\nif (baseColor.a<0.4) {discard;}\n#endif\nfragmentOutputs.color=baseColor*uniforms.color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const layerPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"layerVertexShader\";\nconst shader = `attribute position: vec2f;uniform scale: vec2f;uniform offset: vec2f;uniform textureMatrix: mat4x4f;varying vUV: vec2f;const madd: vec2f= vec2f(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvar shiftedPosition: vec2f=vertexInputs.position*uniforms.scale+uniforms.offset;vertexOutputs.vUV=(uniforms.textureMatrix* vec4f(shiftedPosition*madd+madd,1.0,0.0)).xy;vertexOutputs.position= vec4f(shiftedPosition,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const layerVertexShaderWGSL = { name, shader };\n","import { type Nullable } from \"../types\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type LensFlareSystem } from \"./lensFlareSystem\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\n/**\r\n * This represents one of the lens effect in a `lensFlareSystem`.\r\n * It controls one of the individual texture used in the effect.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n */\r\nexport class LensFlare {\r\n    /**\r\n     * Define the lens color.\r\n     */\r\n    public color: Color3;\r\n\r\n    /**\r\n     * Define the lens texture.\r\n     */\r\n    public texture: Nullable<Texture>;\r\n\r\n    /**\r\n     * Define the alpha mode to render this particular lens.\r\n     */\r\n    public alphaMode: number = Constants.ALPHA_ONEONE;\r\n\r\n    /** @internal */\r\n    public _drawWrapper: DrawWrapper;\r\n\r\n    private _system: LensFlareSystem;\r\n\r\n    /**\r\n     * Creates a new Lens Flare.\r\n     * This represents one of the lens effect in a `lensFlareSystem`.\r\n     * It controls one of the individual texture used in the effect.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n     * @param size Define the size of the lens flare (a floating value between 0 and 1)\r\n     * @param position Define the position of the lens flare in the system. (a floating value between -1 and 1). A value of 0 is located on the emitter. A value greater than 0 is beyond the emitter and a value lesser than 0 is behind.\r\n     * @param color Define the lens color\r\n     * @param imgUrl Define the lens texture url\r\n     * @param system Define the `lensFlareSystem` this flare is part of\r\n     * @returns The newly created Lens Flare\r\n     */\r\n    public static AddFlare(size: number, position: number, color: Color3, imgUrl: string, system: LensFlareSystem): LensFlare {\r\n        return new LensFlare(size, position, color, imgUrl, system);\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new Lens Flare.\r\n     * This represents one of the lens effect in a `lensFlareSystem`.\r\n     * It controls one of the individual texture used in the effect.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n     * @param size Define the size of the lens flare in the system (a floating value between 0 and 1)\r\n     * @param position Define the position of the lens flare in the system. (a floating value between -1 and 1). A value of 0 is located on the emitter. A value greater than 0 is beyond the emitter and a value lesser than 0 is behind.\r\n     * @param color Define the lens color\r\n     * @param imgUrl Define the lens texture url\r\n     * @param system Define the `lensFlareSystem` this flare is part of\r\n     */\r\n    constructor(\r\n        /**\r\n         * Define the size of the lens flare in the system (a floating value between 0 and 1)\r\n         */\r\n        public size: number,\r\n        /**\r\n         * Define the position of the lens flare in the system. (a floating value between -1 and 1). A value of 0 is located on the emitter. A value greater than 0 is beyond the emitter and a value lesser than 0 is behind.\r\n         */\r\n        public position: number,\r\n        color: Color3,\r\n        imgUrl: string,\r\n        system: LensFlareSystem\r\n    ) {\r\n        this.color = color || new Color3(1, 1, 1);\r\n        this.texture = imgUrl ? new Texture(imgUrl, system.getScene(), true) : null;\r\n        this._system = system;\r\n\r\n        const engine = system.scene.getEngine();\r\n\r\n        system._onShadersLoaded.addOnce(() => {\r\n            this._drawWrapper = new DrawWrapper(engine);\r\n            this._drawWrapper.effect = engine.createEffect(\r\n                \"lensFlare\",\r\n                [VertexBuffer.PositionKind],\r\n                [\"color\", \"viewportMatrix\"],\r\n                [\"textureSampler\"],\r\n                \"\",\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                system.shaderLanguage\r\n            );\r\n        });\r\n\r\n        system.lensFlares.push(this);\r\n    }\r\n\r\n    /**\r\n     * Dispose and release the lens flare with its associated resources.\r\n     */\r\n    public dispose(): void {\r\n        if (this.texture) {\r\n            this.texture.dispose();\r\n        }\r\n\r\n        // Remove from scene\r\n        const index = this._system.lensFlares.indexOf(this);\r\n        this._system.lensFlares.splice(index, 1);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneSerializableComponent } from \"../sceneComponent\";\r\n\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AssetContainer } from \"../assetContainer\";\r\nimport { AddParser } from \"core/Loading/Plugins/babylonFileParser.function\";\r\nimport { type LensFlareSystem } from \"./lensFlareSystem\";\r\n\r\n/**\r\n * Defines the lens flare scene component responsible to manage any lens flares\r\n * in a given scene.\r\n */\r\nexport class LensFlareSystemSceneComponent implements ISceneSerializableComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_LENSFLARESYSTEM;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_LENSFLARESYSTEM, this, this._draw);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        for (let index = 0; index < this.scene.lensFlareSystems.length; index++) {\r\n            this.scene.lensFlareSystems[index].rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     * @param container the container holding the elements\r\n     */\r\n    public addFromContainer(container: IAssetContainer): void {\r\n        if (!container.lensFlareSystems) {\r\n            return;\r\n        }\r\n        for (const o of container.lensFlareSystems) {\r\n            this.scene.addLensFlareSystem(o);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     * @param container contains the elements to remove\r\n     * @param dispose if the removed element should be disposed (default: false)\r\n     */\r\n    public removeFromContainer(container: IAssetContainer, dispose?: boolean): void {\r\n        if (!container.lensFlareSystems) {\r\n            return;\r\n        }\r\n        for (const o of container.lensFlareSystems) {\r\n            this.scene.removeLensFlareSystem(o);\r\n            if (dispose) {\r\n                o.dispose();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes the component data to the specified json object\r\n     * @param serializationObject The object to serialize to\r\n     */\r\n    public serialize(serializationObject: any): void {\r\n        // Lens flares\r\n        serializationObject.lensFlareSystems = [];\r\n        const lensFlareSystems = this.scene.lensFlareSystems;\r\n        for (const lensFlareSystem of lensFlareSystems) {\r\n            serializationObject.lensFlareSystems.push(lensFlareSystem.serialize());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        const lensFlareSystems = this.scene.lensFlareSystems;\r\n        while (lensFlareSystems.length) {\r\n            lensFlareSystems[0].dispose();\r\n        }\r\n    }\r\n\r\n    private _draw(camera: Camera): void {\r\n        // Lens flares\r\n        if (this.scene.lensFlaresEnabled) {\r\n            const lensFlareSystems = this.scene.lensFlareSystems;\r\n            Tools.StartPerformanceCounter(\"Lens flares\", lensFlareSystems.length > 0);\r\n            for (const lensFlareSystem of lensFlareSystems) {\r\n                if ((camera.layerMask & lensFlareSystem.layerMask) !== 0) {\r\n                    lensFlareSystem.render();\r\n                }\r\n            }\r\n            Tools.EndPerformanceCounter(\"Lens flares\", lensFlareSystems.length > 0);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for lensFlareSystemSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param lensFlareSystemClass The LensFlareSystem class to register the component for\r\n */\r\nexport function RegisterLensFlareSystemSceneComponent(lensFlareSystemClass: typeof LensFlareSystem): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Adds the parser to the scene parsers.\r\n    AddParser(SceneComponentConstants.NAME_LENSFLARESYSTEM, (parsedData: any, scene: Scene, container: AssetContainer, rootUrl: string) => {\r\n        // Lens flares\r\n        if (parsedData.lensFlareSystems !== undefined && parsedData.lensFlareSystems !== null) {\r\n            if (!container.lensFlareSystems) {\r\n                container.lensFlareSystems = [] as LensFlareSystem[];\r\n            }\r\n\r\n            for (let index = 0, cache = parsedData.lensFlareSystems.length; index < cache; index++) {\r\n                const parsedLensFlareSystem = parsedData.lensFlareSystems[index];\r\n                const lf = lensFlareSystemClass.Parse(parsedLensFlareSystem, scene, rootUrl);\r\n                container.lensFlareSystems.push(lf);\r\n            }\r\n        }\r\n    });\r\n\r\n    Scene.prototype.getLensFlareSystemByName = function (name: string): Nullable<LensFlareSystem> {\r\n        for (let index = 0; index < this.lensFlareSystems.length; index++) {\r\n            if (this.lensFlareSystems[index].name === name) {\r\n                return this.lensFlareSystems[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    Scene.prototype.getLensFlareSystemById = function (id: string): Nullable<LensFlareSystem> {\r\n        for (let index = 0; index < this.lensFlareSystems.length; index++) {\r\n            if (this.lensFlareSystems[index].id === id) {\r\n                return this.lensFlareSystems[index];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    Scene.prototype.getLensFlareSystemByID = function (id: string): Nullable<LensFlareSystem> {\r\n        return this.getLensFlareSystemById(id);\r\n    };\r\n\r\n    Scene.prototype.removeLensFlareSystem = function (toRemove: LensFlareSystem): number {\r\n        const index = this.lensFlareSystems.indexOf(toRemove);\r\n        if (index !== -1) {\r\n            this.lensFlareSystems.splice(index, 1);\r\n        }\r\n        return index;\r\n    };\r\n\r\n    Scene.prototype.addLensFlareSystem = function (newLensFlareSystem: LensFlareSystem): void {\r\n        this.lensFlareSystems.push(newLensFlareSystem);\r\n    };\r\n\r\n    lensFlareSystemClass._SceneComponentInitialization = (scene: Scene) => {\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_LENSFLARESYSTEM) as LensFlareSystemSceneComponent;\r\n        if (!component) {\r\n            component = new LensFlareSystemSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","import { Tools } from \"../Misc/tools.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Ray } from \"../Culling/ray.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { LensFlare } from \"./lensFlare\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type Viewport } from \"../Maths/math.viewport\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { RegisterLensFlareSystemSceneComponent } from \"./lensFlareSystemSceneComponent.pure\";\r\n\r\n/**\r\n * This represents a Lens Flare System or the shiny effect created by the light reflection on the  camera lenses.\r\n * It is usually composed of several `lensFlare`.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n */\r\nexport class LensFlareSystem {\r\n    /**\r\n     * Force all the lens flare systems to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * List of lens flares used in this system.\r\n     */\r\n    public lensFlares: LensFlare[] = [];\r\n\r\n    /**\r\n     * Define a limit from the border the lens flare can be visible.\r\n     */\r\n    public borderLimit = 300;\r\n\r\n    /**\r\n     * Define a viewport border we do not want to see the lens flare in.\r\n     */\r\n    public viewportBorder = 0;\r\n\r\n    /**\r\n     * Define a predicate which could limit the list of meshes able to occlude the effect.\r\n     */\r\n    public meshesSelectionPredicate: (mesh: AbstractMesh) => boolean;\r\n\r\n    /**\r\n     * Restricts the rendering of the effect to only the camera rendering this layer mask.\r\n     */\r\n    public layerMask: number = 0x0fffffff;\r\n\r\n    /** Gets the scene */\r\n    public get scene() {\r\n        return this._scene;\r\n    }\r\n\r\n    /** Shader language used by the system */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this system.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Define the id of the lens flare system in the scene.\r\n     * (equal to name by default)\r\n     */\r\n    public id: string;\r\n\r\n    private _scene: Scene;\r\n    private _emitter: any;\r\n    private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _positionX: number;\r\n    private _positionY: number;\r\n    private _isEnabled = true;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"LensFlareSystemSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * Instantiates a lens flare system.\r\n     * This represents a Lens Flare System or the shiny effect created by the light reflection on the  camera lenses.\r\n     * It is usually composed of several `lensFlare`.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare\r\n     * @param name Define the name of the lens flare system in the scene\r\n     * @param emitter Define the source (the emitter) of the lens flares (it can be a camera, a light or a mesh).\r\n     * @param scene Define the scene the lens flare system belongs to\r\n     */\r\n    constructor(\r\n        /**\r\n         * Define the name of the lens flare system\r\n         */\r\n        public name: string,\r\n        emitter: any,\r\n        scene: Scene\r\n    ) {\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        this.layerMask = this._scene.defaultRenderableLayerMask;\r\n\r\n        RegisterLensFlareSystemSceneComponent(LensFlareSystem);\r\n        LensFlareSystem._SceneComponentInitialization(this._scene);\r\n\r\n        this._emitter = emitter;\r\n        this.id = name;\r\n        scene.lensFlareSystems.push(this);\r\n\r\n        this.meshesSelectionPredicate = (m) =>\r\n            <boolean>(scene.activeCamera && m.material && m.isVisible && m.isEnabled() && m.isBlocker && (m.layerMask & scene.activeCamera.layerMask) != 0);\r\n\r\n        const engine = scene.getEngine();\r\n\r\n        // VBO\r\n        const vertices = [];\r\n        vertices.push(1, 1);\r\n        vertices.push(-1, 1);\r\n        vertices.push(-1, -1);\r\n        vertices.push(1, -1);\r\n\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, vertices, VertexBuffer.PositionKind, false, false, 2);\r\n\r\n        // Indices\r\n        this._createIndexBuffer();\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n    }\r\n\r\n    /** @internal */\r\n    public _onShadersLoaded = new Observable<void>(undefined, true);\r\n\r\n    private _shadersLoaded = false;\r\n\r\n    protected async _initShaderSourceAsync() {\r\n        const engine = this._scene.getEngine();\r\n\r\n        if (engine.isWebGPU && !LensFlareSystem.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([import(\"../ShadersWGSL/lensFlare.fragment\"), import(\"../ShadersWGSL/lensFlare.vertex\")]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/lensFlare.fragment\"), import(\"../Shaders/lensFlare.vertex\")]);\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n        this._onShadersLoaded.notifyObservers();\r\n    }\r\n\r\n    private _createIndexBuffer(): void {\r\n        const indices = [];\r\n        indices.push(0);\r\n        indices.push(1);\r\n        indices.push(2);\r\n\r\n        indices.push(0);\r\n        indices.push(2);\r\n        indices.push(3);\r\n\r\n        this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);\r\n    }\r\n\r\n    /**\r\n     * Define if the lens flare system is enabled.\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    public set isEnabled(value: boolean) {\r\n        this._isEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Get the scene the effects belongs to.\r\n     * @returns the scene holding the lens flare system\r\n     */\r\n    public getScene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Get the emitter of the lens flare system.\r\n     * It defines the source of the lens flares (it can be a camera, a light or a mesh).\r\n     * @returns the emitter of the lens flare system\r\n     */\r\n    public getEmitter(): any {\r\n        return this._emitter;\r\n    }\r\n\r\n    /**\r\n     * Set the emitter of the lens flare system.\r\n     * It defines the source of the lens flares (it can be a camera, a light or a mesh).\r\n     * @param newEmitter Define the new emitter of the system\r\n     */\r\n    public setEmitter(newEmitter: any): void {\r\n        this._emitter = newEmitter;\r\n    }\r\n\r\n    /**\r\n     * Get the lens flare system emitter position.\r\n     * The emitter defines the source of the lens flares (it can be a camera, a light or a mesh).\r\n     * @returns the position\r\n     */\r\n    public getEmitterPosition(): Vector3 {\r\n        return this._emitter.getAbsolutePosition ? this._emitter.getAbsolutePosition() : this._emitter.position;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public computeEffectivePosition(globalViewport: Viewport): boolean {\r\n        let position = this.getEmitterPosition();\r\n\r\n        position = Vector3.Project(position, Matrix.Identity(), this._scene.getTransformMatrix(), globalViewport);\r\n\r\n        this._positionX = position.x;\r\n        this._positionY = position.y;\r\n\r\n        position = Vector3.TransformCoordinates(this.getEmitterPosition(), this._scene.getViewMatrix());\r\n\r\n        if (this.viewportBorder > 0) {\r\n            globalViewport.x -= this.viewportBorder;\r\n            globalViewport.y -= this.viewportBorder;\r\n            globalViewport.width += this.viewportBorder * 2;\r\n            globalViewport.height += this.viewportBorder * 2;\r\n            position.x += this.viewportBorder;\r\n            position.y += this.viewportBorder;\r\n            this._positionX += this.viewportBorder;\r\n            this._positionY += this.viewportBorder;\r\n        }\r\n\r\n        const rhs = this._scene.useRightHandedSystem;\r\n        const okZ = (position.z > 0 && !rhs) || (position.z < 0 && rhs);\r\n\r\n        if (okZ) {\r\n            if (this._positionX > globalViewport.x && this._positionX < globalViewport.x + globalViewport.width) {\r\n                if (this._positionY > globalViewport.y && this._positionY < globalViewport.y + globalViewport.height) {\r\n                    return true;\r\n                }\r\n            }\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /** @internal */\r\n    public _isVisible(): boolean {\r\n        if (!this._isEnabled || !this._scene.activeCamera) {\r\n            return false;\r\n        }\r\n\r\n        const emitterPosition = this.getEmitterPosition();\r\n        const direction = emitterPosition.subtract(this._scene.activeCamera.globalPosition);\r\n        const distance = direction.length();\r\n        direction.normalize();\r\n\r\n        const ray = new Ray(this._scene.activeCamera.globalPosition, direction);\r\n        const pickInfo = this._scene.pickWithRay(ray, this.meshesSelectionPredicate, true);\r\n\r\n        return !pickInfo || !pickInfo.hit || pickInfo.distance > distance;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public render(): boolean {\r\n        if (!this._scene.activeCamera || !this._shadersLoaded) {\r\n            return false;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n        const viewport = this._scene.activeCamera.viewport;\r\n        const globalViewport = viewport.toGlobal(engine.getRenderWidth(true), engine.getRenderHeight(true));\r\n\r\n        // Position\r\n        if (!this.computeEffectivePosition(globalViewport)) {\r\n            return false;\r\n        }\r\n\r\n        // Visibility\r\n        if (!this._isVisible()) {\r\n            return false;\r\n        }\r\n\r\n        // Intensity\r\n        let awayX;\r\n        let awayY;\r\n\r\n        if (this._positionX < this.borderLimit + globalViewport.x) {\r\n            awayX = this.borderLimit + globalViewport.x - this._positionX;\r\n        } else if (this._positionX > globalViewport.x + globalViewport.width - this.borderLimit) {\r\n            awayX = this._positionX - globalViewport.x - globalViewport.width + this.borderLimit;\r\n        } else {\r\n            awayX = 0;\r\n        }\r\n\r\n        if (this._positionY < this.borderLimit + globalViewport.y) {\r\n            awayY = this.borderLimit + globalViewport.y - this._positionY;\r\n        } else if (this._positionY > globalViewport.y + globalViewport.height - this.borderLimit) {\r\n            awayY = this._positionY - globalViewport.y - globalViewport.height + this.borderLimit;\r\n        } else {\r\n            awayY = 0;\r\n        }\r\n\r\n        let away = awayX > awayY ? awayX : awayY;\r\n\r\n        away -= this.viewportBorder;\r\n\r\n        if (away > this.borderLimit) {\r\n            away = this.borderLimit;\r\n        }\r\n\r\n        let intensity = 1.0 - Clamp(away / this.borderLimit, 0, 1);\r\n        if (intensity < 0) {\r\n            return false;\r\n        }\r\n\r\n        if (intensity > 1.0) {\r\n            intensity = 1.0;\r\n        }\r\n\r\n        if (this.viewportBorder > 0) {\r\n            globalViewport.x += this.viewportBorder;\r\n            globalViewport.y += this.viewportBorder;\r\n            globalViewport.width -= this.viewportBorder * 2;\r\n            globalViewport.height -= this.viewportBorder * 2;\r\n            this._positionX -= this.viewportBorder;\r\n            this._positionY -= this.viewportBorder;\r\n        }\r\n\r\n        // Position\r\n        const centerX = globalViewport.x + globalViewport.width / 2;\r\n        const centerY = globalViewport.y + globalViewport.height / 2;\r\n        const distX = centerX - this._positionX;\r\n        const distY = centerY - this._positionY;\r\n\r\n        // Effects\r\n        engine.setState(false);\r\n        engine.setDepthBuffer(false);\r\n\r\n        // Flares\r\n        for (let index = 0; index < this.lensFlares.length; index++) {\r\n            const flare = this.lensFlares[index];\r\n\r\n            if (!flare._drawWrapper.effect!.isReady() || (flare.texture && !flare.texture.isReady())) {\r\n                continue;\r\n            }\r\n\r\n            engine.enableEffect(flare._drawWrapper);\r\n            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, flare._drawWrapper.effect!);\r\n\r\n            engine.setAlphaMode(flare.alphaMode);\r\n\r\n            const x = centerX - distX * flare.position;\r\n            const y = centerY - distY * flare.position;\r\n\r\n            const cw = flare.size;\r\n            const ch = flare.size * engine.getAspectRatio(this._scene.activeCamera, true);\r\n            const cx = 2 * ((x - globalViewport.x) / globalViewport.width) - 1.0;\r\n            const cy = 1.0 - 2 * ((y - globalViewport.y) / globalViewport.height);\r\n\r\n            const viewportMatrix = Matrix.FromValues(cw / 2, 0, 0, 0, 0, ch / 2, 0, 0, 0, 0, 1, 0, cx, cy, 0, 1);\r\n\r\n            flare._drawWrapper.effect!.setMatrix(\"viewportMatrix\", viewportMatrix);\r\n\r\n            // Texture\r\n            flare._drawWrapper.effect!.setTexture(\"textureSampler\", flare.texture);\r\n\r\n            // Color\r\n            flare._drawWrapper.effect!.setFloat4(\"color\", flare.color.r * intensity, flare.color.g * intensity, flare.color.b * intensity, 1.0);\r\n\r\n            // Draw order\r\n            engine.drawElementsType(Material.TriangleFillMode, 0, 6);\r\n        }\r\n\r\n        engine.setDepthBuffer(true);\r\n        engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the lens flare system\r\n     */\r\n    public rebuild(): void {\r\n        this._createIndexBuffer();\r\n\r\n        for (const key in this._vertexBuffers) {\r\n            this._vertexBuffers[key]?._rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose and release the lens flare with its associated resources.\r\n     */\r\n    public dispose(): void {\r\n        this._onShadersLoaded.clear();\r\n        const vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (vertexBuffer) {\r\n            vertexBuffer.dispose();\r\n            this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this._scene.getEngine()._releaseBuffer(this._indexBuffer);\r\n            this._indexBuffer = null;\r\n        }\r\n\r\n        while (this.lensFlares.length) {\r\n            this.lensFlares[0].dispose();\r\n        }\r\n\r\n        // Remove from scene\r\n        const index = this._scene.lensFlareSystems.indexOf(this);\r\n        this._scene.lensFlareSystems.splice(index, 1);\r\n    }\r\n\r\n    /**\r\n     * Parse a lens flare system from a JSON representation\r\n     * @param parsedLensFlareSystem Define the JSON to parse\r\n     * @param scene Define the scene the parsed system should be instantiated in\r\n     * @param rootUrl Define the rootUrl of the load sequence to easily find a load relative dependencies such as textures\r\n     * @returns the parsed system\r\n     */\r\n    public static Parse(parsedLensFlareSystem: any, scene: Scene, rootUrl: string): LensFlareSystem {\r\n        const emitter = scene.getLastEntryById(parsedLensFlareSystem.emitterId);\r\n\r\n        const name = parsedLensFlareSystem.name || \"lensFlareSystem#\" + parsedLensFlareSystem.emitterId;\r\n\r\n        const lensFlareSystem = new LensFlareSystem(name, emitter, scene);\r\n\r\n        lensFlareSystem.id = parsedLensFlareSystem.id || name;\r\n        lensFlareSystem.borderLimit = parsedLensFlareSystem.borderLimit;\r\n\r\n        for (let index = 0; index < parsedLensFlareSystem.flares.length; index++) {\r\n            const parsedFlare = parsedLensFlareSystem.flares[index];\r\n            LensFlare.AddFlare(\r\n                parsedFlare.size,\r\n                parsedFlare.position,\r\n                Color3.FromArray(parsedFlare.color),\r\n                parsedFlare.textureName ? rootUrl + parsedFlare.textureName : \"\",\r\n                lensFlareSystem\r\n            );\r\n        }\r\n\r\n        return lensFlareSystem;\r\n    }\r\n\r\n    /**\r\n     * Serialize the current Lens Flare System into a JSON representation.\r\n     * @returns the serialized JSON\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.id = this.id;\r\n        serializationObject.name = this.name;\r\n\r\n        serializationObject.emitterId = this.getEmitter().id;\r\n        serializationObject.borderLimit = this.borderLimit;\r\n\r\n        serializationObject.flares = [];\r\n        for (let index = 0; index < this.lensFlares.length; index++) {\r\n            const flare = this.lensFlares[index];\r\n\r\n            serializationObject.flares.push({\r\n                size: flare.size,\r\n                position: flare.position,\r\n                color: flare.color.asArray(),\r\n                textureName: Tools.GetFilename(flare.texture ? flare.texture.name : \"\"),\r\n            });\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lensFlarePixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec4 color;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec4 baseColor=texture2D(textureSampler,vUV);gl_FragColor=baseColor*color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lensFlarePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lensFlareVertexShader\";\nconst shader = `attribute vec2 position;uniform mat4 viewportMatrix;varying vec2 vUV;const vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvUV=position*madd+madd;gl_Position=viewportMatrix*vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lensFlareVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lensFlarePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform color: vec4f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvar baseColor: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);fragmentOutputs.color=baseColor*uniforms.color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lensFlarePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lensFlareVertexShader\";\nconst shader = `attribute position: vec2f;uniform viewportMatrix: mat4x4f;varying vUV: vec2f;const madd: vec2f= vec2f(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.vUV=vertexInputs.position*madd+madd;vertexOutputs.position=uniforms.viewportMatrix* vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lensFlareVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bayerDitherFunctions\";\nconst shader = `fn bayerDither2(_P: vec2f)->f32 {return ((2.0*_P.y+_P.x+1.0)%(4.0));}\nfn bayerDither4(_P: vec2f)->f32 {var P1: vec2f=((_P)%(2.0)); \nvar P2: vec2f=floor(0.5*((_P)%(4.0))); \nreturn 4.0*bayerDither2(P1)+bayerDither2(P2);}\nfn bayerDither8(_P: vec2f)->f32 {var P1: vec2f=((_P)%(2.0)); \nvar P2: vec2f=floor(0.5 *((_P)%(4.0))); \nvar P4: vec2f=floor(0.25*((_P)%(8.0))); \nreturn 4.0*(4.0*bayerDither2(P1)+bayerDither2(P2))+bayerDither2(P4);}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bayerDitherFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./packingFunctions\";\nimport \"./bayerDitherFunctions\";\nconst name = \"shadowMapFragmentExtraDeclaration\";\nconst shader = `#if SM_FLOAT==0\n#include<packingFunctions>\n#endif\n#if SM_SOFTTRANSPARENTSHADOW==1\n#include<bayerDitherFunctions>\nuniform softTransparentShadowSM: vec2f;\n#endif\nvarying vDepthMetricSM: f32;\n#if SM_USEDISTANCE==1\nuniform lightDataSM: vec3f;varying vPositionWSM: vec3f;\n#endif\nuniform biasAndScaleSM: vec3f;uniform depthValuesSM: vec2f;\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\nvarying zSM: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowMapFragmentExtraDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapFragment\";\nconst shader = `var depthSM: f32=fragmentInputs.vDepthMetricSM;\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\n#if SM_USEDISTANCE==1\ndepthSM=(length(fragmentInputs.vPositionWSM-uniforms.lightDataSM)+uniforms.depthValuesSM.x)/uniforms.depthValuesSM.y+uniforms.biasAndScaleSM.x;\n#else\n#ifdef USE_REVERSE_DEPTHBUFFER\ndepthSM=(-fragmentInputs.zSM+uniforms.depthValuesSM.x)/uniforms.depthValuesSM.y+uniforms.biasAndScaleSM.x;\n#else\ndepthSM=(fragmentInputs.zSM+uniforms.depthValuesSM.x)/uniforms.depthValuesSM.y+uniforms.biasAndScaleSM.x;\n#endif\n#endif\ndepthSM=clamp(depthSM,0.0,1.0);\n#ifdef USE_REVERSE_DEPTHBUFFER\nfragmentOutputs.fragDepth=clamp(1.0-depthSM,0.0,1.0);\n#else\nfragmentOutputs.fragDepth=clamp(depthSM,0.0,1.0); \n#endif\n#elif SM_USEDISTANCE==1\ndepthSM=(length(fragmentInputs.vPositionWSM-uniforms.lightDataSM)+uniforms.depthValuesSM.x)/uniforms.depthValuesSM.y+uniforms.biasAndScaleSM.x;\n#endif\n#if SM_ESM==1\ndepthSM=clamp(exp(-min(87.,uniforms.biasAndScaleSM.z*depthSM)),0.,1.);\n#endif\n#if SM_FLOAT==1\nfragmentOutputs.color= vec4f(depthSM,1.0,1.0,1.0);\n#else\nfragmentOutputs.color=pack(depthSM);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowMapFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { packingFunctionsWGSL } from \"./ShadersInclude/packingFunctions\";\nimport { bayerDitherFunctionsWGSL } from \"./ShadersInclude/bayerDitherFunctions\";\nimport { shadowMapFragmentExtraDeclarationWGSL } from \"./ShadersInclude/shadowMapFragmentExtraDeclaration\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { shadowMapFragmentWGSL } from \"./ShadersInclude/shadowMapFragment\";\n\nconst name = \"shadowMapPixelShader\";\nconst shader = `#include<shadowMapFragmentExtraDeclaration>\n#ifdef ALPHATEXTURE\nvarying vUV: vec2f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#include<clipPlaneFragment>\n#ifdef ALPHATEXTURE\nvar opacityMap: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,fragmentInputs.vUV);var alphaFromAlphaTexture: f32=opacityMap.a;\n#if SM_SOFTTRANSPARENTSHADOW==1\nif (uniforms.softTransparentShadowSM.y==1.0) {opacityMap=vec4f(opacityMap.rgb* vec3f(0.3,0.59,0.11),opacityMap.a);alphaFromAlphaTexture=opacityMap.x+opacityMap.y+opacityMap.z;}\n#endif\n#ifdef ALPHATESTVALUE\nif (alphaFromAlphaTexture<ALPHATESTVALUE) {discard;}\n#endif\n#endif\n#if SM_SOFTTRANSPARENTSHADOW==1\n#ifdef ALPHATEXTURE\nif ((bayerDither8(floor(((fragmentInputs.position.xy)%(8.0)))))/64.0>=uniforms.softTransparentShadowSM.x*alphaFromAlphaTexture) {discard;}\n#else\nif ((bayerDither8(floor(((fragmentInputs.position.xy)%(8.0)))))/64.0>=uniforms.softTransparentShadowSM.x) {discard;} \n#endif\n#endif\n#include<shadowMapFragment>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [packingFunctionsWGSL, bayerDitherFunctionsWGSL, shadowMapFragmentExtraDeclarationWGSL, clipPlaneFragmentDeclarationWGSL, clipPlaneFragmentWGSL, shadowMapFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const shadowMapPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapVertexExtraDeclaration\";\nconst shader = `#if SM_NORMALBIAS==1\nuniform lightDataSM: vec3f;\n#endif\nuniform biasAndScaleSM: vec3f;uniform depthValuesSM: vec2f;varying vDepthMetricSM: f32;\n#if SM_USEDISTANCE==1\nvarying vPositionWSM: vec3f;\n#endif\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\nvarying zSM: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexExtraDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapVertexNormalBias\";\nconst shader = `#if SM_NORMALBIAS==1\n#if SM_DIRECTIONINLIGHTDATA==1\nvar worldLightDirSM: vec3f=normalize(-uniforms.lightDataSM.xyz);\n#else\nvar directionToLightSM: vec3f=uniforms.lightDataSM.xyz-worldPos.xyz;var worldLightDirSM: vec3f=normalize(directionToLightSM);\n#endif\nvar ndlSM: f32=dot(vNormalW,worldLightDirSM);var sinNLSM: f32=sqrt(1.0-ndlSM*ndlSM);var normalBiasSM: f32=uniforms.biasAndScaleSM.y*sinNLSM;worldPos=vec4f(worldPos.xyz-vNormalW*normalBiasSM,worldPos.w);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexNormalBiasWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapVertexMetric\";\nconst shader = `#if SM_USEDISTANCE==1\nvertexOutputs.vPositionWSM=worldPos.xyz;\n#endif\n#if SM_DEPTHTEXTURE==1\n#ifdef IS_NDC_HALF_ZRANGE\n#define BIASFACTOR 0.5\n#else\n#define BIASFACTOR 1.0\n#endif\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.position.z-=uniforms.biasAndScaleSM.x*vertexOutputs.position.w*BIASFACTOR;\n#else\nvertexOutputs.position.z+=uniforms.biasAndScaleSM.x*vertexOutputs.position.w*BIASFACTOR;\n#endif\n#endif\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\nvertexOutputs.zSM=vertexOutputs.position.z;vertexOutputs.position.z=0.0;\n#elif SM_USEDISTANCE==0\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetricSM=(-vertexOutputs.position.z+uniforms.depthValuesSM.x)/uniforms.depthValuesSM.y+uniforms.biasAndScaleSM.x;\n#else\nvertexOutputs.vDepthMetricSM=(vertexOutputs.position.z+uniforms.depthValuesSM.x)/uniforms.depthValuesSM.y+uniforms.biasAndScaleSM.x;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexMetricWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { shadowMapVertexExtraDeclarationWGSL } from \"./ShadersInclude/shadowMapVertexExtraDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { shadowMapVertexNormalBiasWGSL } from \"./ShadersInclude/shadowMapVertexNormalBias\";\nimport { shadowMapVertexMetricWGSL } from \"./ShadersInclude/shadowMapVertexMetric\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"shadowMapVertexShader\";\nconst shader = `attribute position: vec3f;\n#ifdef NORMAL\nattribute normal: vec3f;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef INSTANCES\nattribute world0: vec4f;attribute world1: vec4f;attribute world2: vec4f;attribute world3: vec4f;\n#endif\n#include<helperFunctions>\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n#ifdef ALPHATEXTURE\nvarying vUV: vec2f;uniform diffuseMatrix: mat4x4f;\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#endif\n#include<shadowMapVertexExtraDeclaration>\n#include<clipPlaneVertexDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#ifdef NORMAL\nvar normalUpdated: vec3f=vertexInputs.normal;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld* vec4f(positionUpdated,1.0);\n#ifdef NORMAL\nvar normWorldSM: mat3x3f= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvar vNormalW: vec3f=normalUpdated/ vec3f(dot(normWorldSM[0],normWorldSM[0]),dot(normWorldSM[1],normWorldSM[1]),dot(normWorldSM[2],normWorldSM[2]));vNormalW=normalize(normWorldSM*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormWorldSM=transposeMat3(inverseMat3(normWorldSM));\n#endif\nvar vNormalW: vec3f=normalize(normWorldSM*normalUpdated);\n#endif\n#endif\n#include<shadowMapVertexNormalBias>\nvertexOutputs.position=scene.viewProjection*worldPos;\n#include<shadowMapVertexMetric>\n#ifdef ALPHATEXTURE\n#ifdef UV1\nvertexOutputs.vUV= (uniforms.diffuseMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef UV2\nvertexOutputs.vUV= (uniforms.diffuseMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#include<clipPlaneVertex>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, helperFunctionsWGSL, sceneUboDeclarationWGSL, meshUboDeclarationWGSL, shadowMapVertexExtraDeclarationWGSL, clipPlaneVertexDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, shadowMapVertexNormalBiasWGSL, shadowMapVertexMetricWGSL, clipPlaneVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const shadowMapVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"depthBoxBlurPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform screenSize: vec2f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var colorDepth: vec4f=vec4f(0.0);for (var x: i32=-OFFSET; x<=OFFSET; x++) {for (var y: i32=-OFFSET; y<=OFFSET; y++) {colorDepth+=textureSample(textureSampler,textureSamplerSampler,input.vUV+ vec2f(f32(x),f32(y))/uniforms.screenSize);}}\nfragmentOutputs.color=(colorDepth/ f32((OFFSET*2+1)*(OFFSET*2+1)));}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const depthBoxBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapFragmentSoftTransparentShadow\";\nconst shader = `#if SM_SOFTTRANSPARENTSHADOW==1\nif ((bayerDither8(floor(((fragmentInputs.position.xy)%(8.0)))))/64.0>=uniforms.softTransparentShadowSM.x*alpha) {discard;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowMapFragmentSoftTransparentShadowWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bayerDitherFunctions\";\nconst shader = `float bayerDither2(vec2 _P) {return mod(2.0*_P.y+_P.x+1.0,4.0);}\nfloat bayerDither4(vec2 _P) {vec2 P1=mod(_P,2.0); \nvec2 P2=floor(0.5*mod(_P,4.0)); \nreturn 4.0*bayerDither2(P1)+bayerDither2(P2);}\nfloat bayerDither8(vec2 _P) {vec2 P1=mod(_P,2.0); \nvec2 P2=floor(0.5 *mod(_P,4.0)); \nvec2 P4=floor(0.25*mod(_P,8.0)); \nreturn 4.0*(4.0*bayerDither2(P1)+bayerDither2(P2))+bayerDither2(P4);}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bayerDitherFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./packingFunctions\";\nimport \"./bayerDitherFunctions\";\nconst name = \"shadowMapFragmentExtraDeclaration\";\nconst shader = `#if SM_FLOAT==0\n#include<packingFunctions>\n#endif\n#if SM_SOFTTRANSPARENTSHADOW==1\n#include<bayerDitherFunctions>\nuniform vec2 softTransparentShadowSM;\n#endif\nvarying float vDepthMetricSM;\n#if SM_USEDISTANCE==1\nuniform vec3 lightDataSM;varying vec3 vPositionWSM;\n#endif\nuniform vec3 biasAndScaleSM;uniform vec2 depthValuesSM;\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\nvarying float zSM;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapFragmentExtraDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapFragment\";\nconst shader = `float depthSM=vDepthMetricSM;\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\n#if SM_USEDISTANCE==1\ndepthSM=(length(vPositionWSM-lightDataSM)+depthValuesSM.x)/depthValuesSM.y+biasAndScaleSM.x;\n#else\n#ifdef USE_REVERSE_DEPTHBUFFER\ndepthSM=(-zSM+depthValuesSM.x)/depthValuesSM.y+biasAndScaleSM.x;\n#else\ndepthSM=(zSM+depthValuesSM.x)/depthValuesSM.y+biasAndScaleSM.x;\n#endif\n#endif\ndepthSM=clamp(depthSM,0.0,1.0);\n#ifdef USE_REVERSE_DEPTHBUFFER\ngl_FragDepth=clamp(1.0-depthSM,0.0,1.0);\n#else\ngl_FragDepth=clamp(depthSM,0.0,1.0); \n#endif\n#elif SM_USEDISTANCE==1\ndepthSM=(length(vPositionWSM-lightDataSM)+depthValuesSM.x)/depthValuesSM.y+biasAndScaleSM.x;\n#endif\n#if SM_ESM==1\ndepthSM=clamp(exp(-min(87.,biasAndScaleSM.z*depthSM)),0.,1.);\n#endif\n#if SM_FLOAT==1\ngl_FragColor=vec4(depthSM,1.0,1.0,1.0);\n#else\ngl_FragColor=pack(depthSM);\n#endif\nreturn;`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { packingFunctions } from \"./ShadersInclude/packingFunctions\";\nimport { bayerDitherFunctions } from \"./ShadersInclude/bayerDitherFunctions\";\nimport { shadowMapFragmentExtraDeclaration } from \"./ShadersInclude/shadowMapFragmentExtraDeclaration\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { shadowMapFragment } from \"./ShadersInclude/shadowMapFragment\";\n\nconst name = \"shadowMapPixelShader\";\nconst shader = `#include<shadowMapFragmentExtraDeclaration>\n#ifdef ALPHATEXTURE\nvarying vec2 vUV;uniform sampler2D diffuseSampler;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{\n#include<clipPlaneFragment>\n#ifdef ALPHATEXTURE\nvec4 opacityMap=texture2D(diffuseSampler,vUV);float alphaFromAlphaTexture=opacityMap.a;\n#if SM_SOFTTRANSPARENTSHADOW==1\nif (softTransparentShadowSM.y==1.0) {opacityMap.rgb=opacityMap.rgb*vec3(0.3,0.59,0.11);alphaFromAlphaTexture=opacityMap.x+opacityMap.y+opacityMap.z;}\n#endif\n#ifdef ALPHATESTVALUE\nif (alphaFromAlphaTexture<ALPHATESTVALUE)\ndiscard;\n#endif\n#endif\n#if SM_SOFTTRANSPARENTSHADOW==1\n#ifdef ALPHATEXTURE\nif ((bayerDither8(floor(mod(gl_FragCoord.xy,8.0))))/64.0>=softTransparentShadowSM.x*alphaFromAlphaTexture) discard;\n#else\nif ((bayerDither8(floor(mod(gl_FragCoord.xy,8.0))))/64.0>=softTransparentShadowSM.x) discard;\n#endif\n#endif\n#include<shadowMapFragment>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [packingFunctions, bayerDitherFunctions, shadowMapFragmentExtraDeclaration, clipPlaneFragmentDeclaration, clipPlaneFragment, shadowMapFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const shadowMapPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"sceneVertexDeclaration\";\nconst shader = `uniform mat4 viewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;\n#endif\nuniform mat4 view;uniform mat4 projection;uniform vec4 vEyePosition;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const sceneVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"meshVertexDeclaration\";\nconst shader = `uniform mat4 world;uniform float visibility;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const meshVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneVertexDeclaration\";\nimport \"./meshVertexDeclaration\";\nconst name = \"shadowMapVertexDeclaration\";\nconst shader = `#include<sceneVertexDeclaration>\n#include<meshVertexDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"sceneUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Scene {mat4 viewProjection;\n#ifdef MULTIVIEW\nmat4 viewProjectionR;\n#endif \nmat4 view;mat4 projection;vec4 vEyePosition;mat4 inverseProjection;};\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const sceneUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"meshUboDeclaration\";\nconst shader = `#ifdef WEBGL2\nuniform mat4 world;uniform float visibility;\n#else\nlayout(std140,column_major) uniform;uniform Mesh\n{mat4 world;float visibility;};\n#endif\n#define WORLD_UBO\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const meshUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"shadowMapUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapVertexExtraDeclaration\";\nconst shader = `#if SM_NORMALBIAS==1\nuniform vec3 lightDataSM;\n#endif\nuniform vec3 biasAndScaleSM;uniform vec2 depthValuesSM;varying float vDepthMetricSM;\n#if SM_USEDISTANCE==1\nvarying vec3 vPositionWSM;\n#endif\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\nvarying float zSM;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexExtraDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapVertexNormalBias\";\nconst shader = `#if SM_NORMALBIAS==1\n#if SM_DIRECTIONINLIGHTDATA==1\nvec3 worldLightDirSM=normalize(-lightDataSM.xyz);\n#else\nvec3 directionToLightSM=lightDataSM.xyz-worldPos.xyz;vec3 worldLightDirSM=normalize(directionToLightSM);\n#endif\nfloat ndlSM=dot(vNormalW,worldLightDirSM);float sinNLSM=sqrt(1.0-ndlSM*ndlSM);float normalBiasSM=biasAndScaleSM.y*sinNLSM;worldPos.xyz-=vNormalW*normalBiasSM;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexNormalBias = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapVertexMetric\";\nconst shader = `#if SM_USEDISTANCE==1\nvPositionWSM=worldPos.xyz;\n#endif\n#if SM_DEPTHTEXTURE==1\n#ifdef IS_NDC_HALF_ZRANGE\n#define BIASFACTOR 0.5\n#else\n#define BIASFACTOR 1.0\n#endif\n#ifdef USE_REVERSE_DEPTHBUFFER\ngl_Position.z-=biasAndScaleSM.x*gl_Position.w*BIASFACTOR;\n#else\ngl_Position.z+=biasAndScaleSM.x*gl_Position.w*BIASFACTOR;\n#endif\n#endif\n#if defined(SM_DEPTHCLAMP) && SM_DEPTHCLAMP==1\nzSM=gl_Position.z;gl_Position.z=0.0;\n#elif SM_USEDISTANCE==0\n#ifdef USE_REVERSE_DEPTHBUFFER\nvDepthMetricSM=(-gl_Position.z+depthValuesSM.x)/depthValuesSM.y+biasAndScaleSM.x;\n#else\nvDepthMetricSM=(gl_Position.z+depthValuesSM.x)/depthValuesSM.y+biasAndScaleSM.x;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapVertexMetric = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { sceneVertexDeclaration } from \"./ShadersInclude/sceneVertexDeclaration\";\nimport { meshVertexDeclaration } from \"./ShadersInclude/meshVertexDeclaration\";\nimport { shadowMapVertexDeclaration } from \"./ShadersInclude/shadowMapVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { shadowMapUboDeclaration } from \"./ShadersInclude/shadowMapUboDeclaration\";\nimport { shadowMapVertexExtraDeclaration } from \"./ShadersInclude/shadowMapVertexExtraDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { shadowMapVertexNormalBias } from \"./ShadersInclude/shadowMapVertexNormalBias\";\nimport { shadowMapVertexMetric } from \"./ShadersInclude/shadowMapVertexMetric\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"shadowMapVertexShader\";\nconst shader = `attribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef INSTANCES\nattribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;\n#endif\n#include<helperFunctions>\n#include<__decl__shadowMapVertex>\n#ifdef ALPHATEXTURE\nvarying vec2 vUV;uniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#include<shadowMapVertexExtraDeclaration>\n#include<clipPlaneVertexDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void)\n{vec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#ifdef NORMAL\nvec3 normalUpdated=normal;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\n#ifdef NORMAL\nmat3 normWorldSM=mat3(finalWorld);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvec3 vNormalW=normalUpdated/vec3(dot(normWorldSM[0],normWorldSM[0]),dot(normWorldSM[1],normWorldSM[1]),dot(normWorldSM[2],normWorldSM[2]));vNormalW=normalize(normWorldSM*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormWorldSM=transposeMat3(inverseMat3(normWorldSM));\n#endif\nvec3 vNormalW=normalize(normWorldSM*normalUpdated);\n#endif\n#endif\n#include<shadowMapVertexNormalBias>\ngl_Position=viewProjection*worldPos;\n#include<shadowMapVertexMetric>\n#ifdef ALPHATEXTURE\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#include<clipPlaneVertex>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, helperFunctions, sceneVertexDeclaration, meshVertexDeclaration, shadowMapVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, shadowMapUboDeclaration, shadowMapVertexExtraDeclaration, clipPlaneVertexDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, shadowMapVertexNormalBias, shadowMapVertexMetric, clipPlaneVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const shadowMapVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"depthBoxBlurPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec2 screenSize;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec4 colorDepth=vec4(0.0);for (int x=-OFFSET; x<=OFFSET; x++)\nfor (int y=-OFFSET; y<=OFFSET; y++)\ncolorDepth+=texture2D(textureSampler,vUV+vec2(x,y)/screenSize);gl_FragColor=(colorDepth/float((OFFSET*2+1)*(OFFSET*2+1)));}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const depthBoxBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowMapFragmentSoftTransparentShadow\";\nconst shader = `#if SM_SOFTTRANSPARENTSHADOW==1\nif ((bayerDither8(floor(mod(gl_FragCoord.xy,8.0))))/64.0>=softTransparentShadowSM.x*alpha) discard;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowMapFragmentSoftTransparentShadow = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Light } from \"./light\";\r\nimport { ShadowLight } from \"./shadowLight\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Node } from \"../node\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * A point light is a light defined by an unique point in world space.\r\n * The light is emitted in every direction from this point.\r\n * A good example of a point light is a standard light bulb.\r\n * Documentation: https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n */\r\nexport class PointLight extends ShadowLight {\r\n    private _shadowAngle = Math.PI / 2;\r\n    /**\r\n     * Getter: In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback\r\n     * This specifies what angle the shadow will use to be created.\r\n     *\r\n     * It default to 90 degrees to work nicely with the cube texture generation for point lights shadow maps.\r\n     */\r\n    @serialize()\r\n    public get shadowAngle(): number {\r\n        return this._shadowAngle;\r\n    }\r\n    /**\r\n     * Setter: In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback\r\n     * This specifies what angle the shadow will use to be created.\r\n     *\r\n     * It default to 90 degrees to work nicely with the cube texture generation for point lights shadow maps.\r\n     */\r\n    public set shadowAngle(value: number) {\r\n        this._shadowAngle = value;\r\n        this.forceProjectionMatrixCompute();\r\n    }\r\n\r\n    /**\r\n     * Gets the direction if it has been set.\r\n     * In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback\r\n     */\r\n    public override get direction(): Vector3 {\r\n        return this._direction;\r\n    }\r\n\r\n    /**\r\n     * In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback\r\n     */\r\n    public override set direction(value: Vector3) {\r\n        const previousNeedCube = this.needCube();\r\n        this._direction = value;\r\n        if (this.needCube() !== previousNeedCube && this._shadowGenerators) {\r\n            const iterator = this._shadowGenerators.values();\r\n            for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                const shadowGenerator = key.value;\r\n                shadowGenerator.recreateShadowMap();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a PointLight object from the passed name and position (Vector3) and adds it in the scene.\r\n     * A PointLight emits the light in every direction.\r\n     * It can cast shadows.\r\n     * If the scene camera is already defined and you want to set your PointLight at the camera position, just set it :\r\n     * ```javascript\r\n     * var pointLight = new PointLight(\"pl\", camera.position, scene);\r\n     * ```\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     * @param name The light friendly name\r\n     * @param position The position of the point light in the scene\r\n     * @param scene The scene the lights belongs to\r\n     * @param dontAddToScene True to not add the light to the scene\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, dontAddToScene?: boolean) {\r\n        super(name, scene, dontAddToScene);\r\n        this.position = position;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"PointLight\"\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PointLight\";\r\n    }\r\n\r\n    /**\r\n     * Returns the integer 0.\r\n     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public override getTypeID(): number {\r\n        return Light.LIGHTTYPEID_POINTLIGHT;\r\n    }\r\n\r\n    /**\r\n     * Specifies whether or not the shadowmap should be a cube texture.\r\n     * @returns true if the shadowmap needs to be a cube texture.\r\n     */\r\n    public override needCube(): boolean {\r\n        return !this.direction;\r\n    }\r\n\r\n    /**\r\n     * Returns a new Vector3 aligned with the PointLight cube system according to the passed cube face index (integer).\r\n     * @param faceIndex The index of the face we are computed the direction to generate shadow\r\n     * @returns The set direction in 2d mode otherwise the direction to the cubemap face if needCube() is true\r\n     */\r\n    public override getShadowDirection(faceIndex?: number): Vector3 {\r\n        if (this.direction) {\r\n            return super.getShadowDirection(faceIndex);\r\n        } else {\r\n            switch (faceIndex) {\r\n                case 0:\r\n                    return new Vector3(1.0, 0.0, 0.0);\r\n                case 1:\r\n                    return new Vector3(-1.0, 0.0, 0.0);\r\n                case 2:\r\n                    return new Vector3(0.0, -1.0, 0.0);\r\n                case 3:\r\n                    return new Vector3(0.0, 1.0, 0.0);\r\n                case 4:\r\n                    return new Vector3(0.0, 0.0, 1.0);\r\n                case 5:\r\n                    return new Vector3(0.0, 0.0, -1.0);\r\n            }\r\n        }\r\n\r\n        return Vector3.Zero();\r\n    }\r\n\r\n    /**\r\n     * Sets the passed matrix \"matrix\" as a left-handed perspective projection matrix with the following settings :\r\n     * - fov = PI / 2\r\n     * - aspect ratio : 1.0\r\n     * - z-near and far equal to the active camera minZ and maxZ.\r\n     * Returns the PointLight.\r\n     * @param matrix\r\n     * @param viewMatrix\r\n     * @param renderList\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _setDefaultShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void {\r\n        const activeCamera = this.getScene().activeCamera;\r\n\r\n        const minZ = this.getDepthMinZ(activeCamera);\r\n        const maxZ = this.getDepthMaxZ(activeCamera);\r\n\r\n        const useReverseDepthBuffer = this.getScene().getEngine().useReverseDepthBuffer;\r\n\r\n        Matrix.PerspectiveFovLHToRef(\r\n            this.shadowAngle,\r\n            1.0,\r\n            useReverseDepthBuffer ? maxZ : minZ,\r\n            useReverseDepthBuffer ? minZ : maxZ,\r\n            matrix,\r\n            true,\r\n            this._scene.getEngine().isNDCHalfZRange,\r\n            undefined,\r\n            useReverseDepthBuffer\r\n        );\r\n    }\r\n\r\n    protected _buildUniformLayout(): void {\r\n        this._uniformBuffer.addUniform(\"vLightData\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\r\n        this._uniformBuffer.addUniform(\"vLightFalloff\", 4);\r\n        this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\r\n        this._uniformBuffer.addUniform(\"depthValues\", 2);\r\n        this._uniformBuffer.create();\r\n    }\r\n\r\n    /**\r\n     * Sets the passed Effect \"effect\" with the PointLight transformed position (or position, if none) and passed name (string).\r\n     * @param effect The effect to update\r\n     * @param lightIndex The index of the light in the effect to update\r\n     * @returns The point light\r\n     */\r\n    public transferToEffect(effect: Effect, lightIndex: string): PointLight {\r\n        const offset = this._scene.floatingOriginOffset;\r\n        if (this.computeTransformedInformation()) {\r\n            this._uniformBuffer.updateFloat4(\r\n                \"vLightData\",\r\n                this.transformedPosition.x - offset.x,\r\n                this.transformedPosition.y - offset.y,\r\n                this.transformedPosition.z - offset.z,\r\n                0.0,\r\n                lightIndex\r\n            );\r\n        } else {\r\n            this._uniformBuffer.updateFloat4(\"vLightData\", this.position.x - offset.x, this.position.y - offset.y, this.position.z - offset.z, 0, lightIndex);\r\n        }\r\n\r\n        this._uniformBuffer.updateFloat4(\"vLightFalloff\", this.range, this._inverseSquaredRange, 0, 0, lightIndex);\r\n        return this;\r\n    }\r\n\r\n    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {\r\n        const offset = this._scene.floatingOriginOffset;\r\n        if (this.computeTransformedInformation()) {\r\n            effect.setFloat3(lightDataUniformName, this.transformedPosition.x - offset.x, this.transformedPosition.y - offset.y, this.transformedPosition.z - offset.z);\r\n        } else {\r\n            effect.setFloat3(lightDataUniformName, this.position.x - offset.x, this.position.y - offset.y, this.position.z - offset.z);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Prepares the list of defines specific to the light type.\r\n     * @param defines the list of defines\r\n     * @param lightIndex defines the index of the light for the effect\r\n     */\r\n    public prepareLightSpecificDefines(defines: any, lightIndex: number): void {\r\n        defines[\"POINTLIGHT\" + lightIndex] = true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pointLight.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPointLight(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Node.AddNodeConstructor(\"Light_Type_0\", (name, scene) => {\r\n        return () => new PointLight(name, Vector3.Zero(), scene);\r\n    });\r\n\r\n    // Register Class Name\r\n    RegisterClass(\"BABYLON.PointLight\", PointLight);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { serializeAsVector3 } from \"core/Misc/decorators\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { DecodeLTCTextureDataAsync } from \"core/Lights/LTC/ltcTextureTool\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nfunction CreateSceneLTCTextures(scene: Scene): void {\r\n    const useDelayedTextureLoading = scene.useDelayedTextureLoading;\r\n    scene.useDelayedTextureLoading = false;\r\n\r\n    const previousState = scene._blockEntityCollection;\r\n    scene._blockEntityCollection = false;\r\n\r\n    scene._ltcTextures = {\r\n        LTC1: RawTexture.CreateRGBATexture(null, 64, 64, scene.getEngine(), false, false, Constants.TEXTURE_LINEAR_LINEAR, Constants.TEXTURETYPE_HALF_FLOAT, 0, false, true),\r\n        LTC2: RawTexture.CreateRGBATexture(null, 64, 64, scene.getEngine(), false, false, Constants.TEXTURE_LINEAR_LINEAR, Constants.TEXTURETYPE_HALF_FLOAT, 0, false, true),\r\n    };\r\n\r\n    scene._blockEntityCollection = previousState;\r\n\r\n    scene._ltcTextures.LTC1.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n    scene._ltcTextures.LTC1.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n\r\n    scene._ltcTextures.LTC2.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n    scene._ltcTextures.LTC2.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n\r\n    scene.useDelayedTextureLoading = useDelayedTextureLoading;\r\n\r\n    DecodeLTCTextureDataAsync()\r\n        // eslint-disable-next-line github/no-then\r\n        .then((textureData) => {\r\n            if (scene._ltcTextures) {\r\n                const ltc1 = scene._ltcTextures?.LTC1 as RawTexture;\r\n                ltc1.update(textureData[0]);\r\n\r\n                const ltc2 = scene._ltcTextures?.LTC2 as RawTexture;\r\n                ltc2.update(textureData[1]);\r\n\r\n                scene.onDisposeObservable.addOnce(() => {\r\n                    scene._ltcTextures?.LTC1.dispose();\r\n                    scene._ltcTextures?.LTC2.dispose();\r\n                });\r\n            }\r\n        })\r\n        // eslint-disable-next-line github/no-then\r\n        .catch((error) => {\r\n            Logger.Error(`Area Light fail to get LTC textures data. Error: ${error}`);\r\n        });\r\n}\r\n\r\n/**\r\n * Abstract Area Light class that servers as parent for all Area Lights implementations.\r\n * The light is emitted from the area in the -Z direction.\r\n */\r\nexport abstract class AreaLight extends Light {\r\n    /**\r\n     * Area Light position.\r\n     */\r\n    @serializeAsVector3()\r\n    public position: Vector3;\r\n\r\n    /**\r\n     * Creates a area light object.\r\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\r\n     * @param name The friendly name of the light\r\n     * @param position The position of the area light.\r\n     * @param scene The scene the light belongs to\r\n     * @param dontAddToScene True to not add the light to the scene\r\n     */\r\n    constructor(name: string, position: Vector3, scene?: Scene, dontAddToScene?: boolean) {\r\n        super(name, scene, dontAddToScene);\r\n        this.position = position;\r\n\r\n        if (!this._scene._ltcTextures) {\r\n            CreateSceneLTCTextures(this._scene);\r\n        }\r\n    }\r\n\r\n    public override transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\r\n        if (this._scene._ltcTextures) {\r\n            effect.setTexture(\"areaLightsLTC1Sampler\", this._scene._ltcTextures.LTC1);\r\n            effect.setTexture(\"areaLightsLTC2Sampler\", this._scene._ltcTextures.LTC2);\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Prepares the list of defines specific to the light type.\r\n     * @param defines the list of defines\r\n     * @param lightIndex defines the index of the light for the effect\r\n     */\r\n    public prepareLightSpecificDefines(defines: any, lightIndex: number): void {\r\n        defines[\"AREALIGHT\" + lightIndex] = true;\r\n        defines[\"AREALIGHTUSED\"] = true;\r\n    }\r\n\r\n    public override _isReady(): boolean {\r\n        if (this._scene._ltcTextures) {\r\n            return this._scene._ltcTextures.LTC1.isReady() && this._scene._ltcTextures.LTC2.isReady();\r\n        }\r\n\r\n        return false;\r\n    }\r\n}\r\n","import { type BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\nimport { type Tuple } from \"core/types\";\r\n\r\n/**\r\n * Linearly transformed cosine textures that are used in the Area Lights shaders.\r\n */\r\nexport type ILTCTextures = {\r\n    /**\r\n     * Linearly transformed cosine texture BRDF Approximation.\r\n     */\r\n    LTC1: BaseTexture;\r\n\r\n    /**\r\n     * Linearly transformed cosine texture Fresnel Approximation.\r\n     */\r\n    LTC2: BaseTexture;\r\n};\r\n\r\n/**\r\n * Loads LTC texture data from Babylon.js CDN.\r\n * @returns Promise with data for LTC1 and LTC2 textures for area lights.\r\n */\r\nexport async function DecodeLTCTextureDataAsync(): Promise<Tuple<Uint16Array, 2>> {\r\n    const ltc1 = new Uint16Array(64 * 64 * 4);\r\n    const ltc2 = new Uint16Array(64 * 64 * 4);\r\n    const file = await Tools.LoadFileAsync(Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/areaLights/areaLightsLTC.bin\"));\r\n    const ltcEncoded = new Uint16Array(file);\r\n\r\n    const pixelCount = ltcEncoded.length / 8;\r\n\r\n    for (let pixelIndex = 0; pixelIndex < pixelCount; pixelIndex++) {\r\n        ltc1[pixelIndex * 4] = ltcEncoded[pixelIndex * 8];\r\n        ltc1[pixelIndex * 4 + 1] = ltcEncoded[pixelIndex * 8 + 1];\r\n        ltc1[pixelIndex * 4 + 2] = ltcEncoded[pixelIndex * 8 + 2];\r\n        ltc1[pixelIndex * 4 + 3] = ltcEncoded[pixelIndex * 8 + 3];\r\n\r\n        ltc2[pixelIndex * 4] = ltcEncoded[pixelIndex * 8 + 4];\r\n        ltc2[pixelIndex * 4 + 1] = ltcEncoded[pixelIndex * 8 + 5];\r\n        ltc2[pixelIndex * 4 + 2] = ltcEncoded[pixelIndex * 8 + 6];\r\n        ltc2[pixelIndex * 4 + 3] = ltcEncoded[pixelIndex * 8 + 7];\r\n    }\r\n\r\n    return [ltc1, ltc2];\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\nimport { Light } from \"core/Lights/light\";\nimport { type Effect } from \"core/Materials/effect.pure\";\nimport { serialize } from \"core/Misc/decorators\";\nimport { type Scene } from \"core/scene.pure\";\nimport { AreaLight } from \"core/Lights/areaLight.pure\";\nimport { type Nullable } from \"core/types\";\nimport { type BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\nimport { GenerateBase64StringFromTexture, GenerateBase64StringFromTextureAsync } from \"core/Misc/copyTools\";\nimport { Constants } from \"core/Engines/constants\";\nimport { Node } from \"core/node\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * A rectangular area light defined by an unique point in world space, a width and a height.\n * The light is emitted from the rectangular area in the -Z direction.\n */\nexport class RectAreaLight extends AreaLight {\n    private readonly _width: Vector3;\n    private readonly _height: Vector3;\n    protected readonly _pointTransformedPosition: Vector3;\n    protected readonly _pointTransformedWidth: Vector3;\n    protected readonly _pointTransformedHeight: Vector3;\n    private _emissionTextureTexture: Nullable<BaseTexture> = null;\n\n    /**\n     * Gets Rect Area Light emission texture. (Note: This texture needs pre-processing! Use AreaLightTextureTools to pre-process the texture).\n     */\n    public get emissionTexture(): Nullable<BaseTexture> {\n        return this._emissionTextureTexture;\n    }\n\n    /**\n     * Sets Rect Area Light emission texture. (Note: This texture needs pre-processing! Use AreaLightTextureTools to pre-process the texture).\n     */\n    public set emissionTexture(value: Nullable<BaseTexture>) {\n        if (this._emissionTextureTexture === value) {\n            return;\n        }\n\n        this._emissionTextureTexture = value;\n\n        if (this._emissionTextureTexture) {\n            this._emissionTextureTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n            this._emissionTextureTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        }\n\n        if (this._emissionTextureTexture && RectAreaLight._IsTexture(this._emissionTextureTexture)) {\n            this._emissionTextureTexture.onLoadObservable.addOnce(() => {\n                this._markMeshesAsLightDirty();\n            });\n        }\n    }\n\n    /**\n     * Rect Area Light width.\n     */\n    @serialize()\n    public get width(): number {\n        return this._width.x;\n    }\n    /**\n     * Rect Area Light width.\n     */\n    public set width(value: number) {\n        this._width.x = value;\n    }\n\n    /**\n     * Rect Area Light height.\n     */\n    @serialize()\n    public get height(): number {\n        return this._height.y;\n    }\n    /**\n     * Rect Area Light height.\n     */\n    public set height(value: number) {\n        this._height.y = value;\n    }\n\n    /**\n     * Creates a rectangular area light object.\n     * Documentation : https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction\n     * @param name The friendly name of the light\n     * @param position The position of the area light.\n     * @param width The width of the area light.\n     * @param height The height of the area light.\n     * @param scene The scene the light belongs to\n     * @param dontAddToScene True to not add the light to the scene\n     */\n    constructor(name: string, position: Vector3, width: number, height: number, scene?: Scene, dontAddToScene?: boolean) {\n        super(name, position, scene, dontAddToScene);\n        this._width = new Vector3(width, 0, 0);\n        this._height = new Vector3(0, height, 0);\n        this._pointTransformedPosition = Vector3.Zero();\n        this._pointTransformedWidth = Vector3.Zero();\n        this._pointTransformedHeight = Vector3.Zero();\n    }\n\n    /**\n     * Returns the string \"RectAreaLight\"\n     * @returns the class name\n     */\n    public override getClassName(): string {\n        return \"RectAreaLight\";\n    }\n\n    /**\n     * Returns the integer 4.\n     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x\n     */\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    public override getTypeID(): number {\n        return Light.LIGHTTYPEID_RECT_AREALIGHT;\n    }\n\n    /**\n     * Serializes the rect area light into a serialization object.\n     * The emission texture is normally produced at runtime by AreaLightTextureTools and has no\n     * source URL, so its pixels are embedded as a base64 string to keep the scene self-contained.\n     * @returns the serialized object\n     */\n    public override serialize(): any {\n        const serializationObject = super.serialize();\n\n        if (this._emissionTextureTexture) {\n            const serializedEmissionTexture = this._serializeEmissionTexture(this._emissionTextureTexture);\n            if (serializedEmissionTexture) {\n                serializationObject.emissionTexture = serializedEmissionTexture;\n            }\n        }\n\n        return serializationObject;\n    }\n\n    private _serializeEmissionTexture(texture: BaseTexture): any {\n        // A regular URL-backed texture can be serialized by reference.\n        const referencedTexture = texture.serialize();\n        if (referencedTexture) {\n            return referencedTexture;\n        }\n\n        // The emission texture produced by AreaLightTextureTools is a runtime render-target texture\n        // with no source URL, so embed its pixels as a base64 PNG.\n        const internalTexture = texture.getInternalTexture();\n        if (!internalTexture) {\n            return null;\n        }\n\n        const invertY = internalTexture.invertY;\n        const hasAlpha = texture.hasAlpha;\n\n        // On engines with synchronous texture read (WebGL) the pixels are embedded immediately.\n        if (this._scene.getEngine()._features.supportSyncTextureRead) {\n            return RectAreaLight._BuildEmbeddedEmissionTexture(GenerateBase64StringFromTexture(texture), invertY, hasAlpha);\n        }\n\n        // On WebGPU/Native (no synchronous texture read) a promise for the entire texture object is\n        // returned so it resolves to null (and is skipped on parse) if the pixels cannot be read.\n        // SceneSerializer.SerializeAsync resolves the promise before producing the final JSON.\n        return RectAreaLight._BuildEmbeddedEmissionTextureAsync(GenerateBase64StringFromTextureAsync(texture), invertY, hasAlpha);\n    }\n\n    private static async _BuildEmbeddedEmissionTextureAsync(base64Promise: Promise<Nullable<string>>, invertY: boolean, hasAlpha: boolean): Promise<any> {\n        return RectAreaLight._BuildEmbeddedEmissionTexture(await base64Promise, invertY, hasAlpha);\n    }\n\n    private static _BuildEmbeddedEmissionTexture(base64String: Nullable<string>, invertY: boolean, hasAlpha: boolean): any {\n        if (!base64String) {\n            return null;\n        }\n\n        return {\n            name: \"areaLightEmissionTexture\",\n            base64String: base64String,\n            invertY: invertY,\n            hasAlpha: hasAlpha,\n        };\n    }\n\n    /**\n     * Restores the emission texture from the serialized data after the base light has been parsed.\n     * @param parsedLight The JSON representation of the light\n     * @param scene The scene the light belongs to\n     * @param rootUrl The root url to use to load the emission texture when serialized by reference\n     */\n    protected override _onParsed(parsedLight: any, scene: Scene, rootUrl: string = \"\"): void {\n        super._onParsed(parsedLight, scene, rootUrl);\n\n        if (parsedLight.emissionTexture) {\n            this.emissionTexture = Texture.Parse(parsedLight.emissionTexture, scene, rootUrl);\n        }\n    }\n\n    protected _buildUniformLayout(): void {\n        this._uniformBuffer.addUniform(\"vLightData\", 4);\n        this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\n        this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\n        this._uniformBuffer.addUniform(\"vLightWidth\", 4);\n        this._uniformBuffer.addUniform(\"vLightHeight\", 4);\n        this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\n        this._uniformBuffer.addUniform(\"depthValues\", 2);\n        this._uniformBuffer.create();\n    }\n\n    protected _computeTransformedInformation(): boolean {\n        if (this.parent && this.parent.getWorldMatrix) {\n            Vector3.TransformCoordinatesToRef(this.position, this.parent.getWorldMatrix(), this._pointTransformedPosition);\n            Vector3.TransformNormalToRef(this._width, this.parent.getWorldMatrix(), this._pointTransformedWidth);\n            Vector3.TransformNormalToRef(this._height, this.parent.getWorldMatrix(), this._pointTransformedHeight);\n            return true;\n        }\n\n        return false;\n    }\n\n    private static _IsTexture(texture: BaseTexture): texture is Texture {\n        return (texture as Texture).onLoadObservable !== undefined;\n    }\n\n    /**\n     * Sets the passed Effect \"effect\" with the PointLight transformed position (or position, if none) and passed name (string).\n     * @param effect The effect to update\n     * @param lightIndex The index of the light in the effect to update\n     * @returns The point light\n     */\n    public transferToEffect(effect: Effect, lightIndex: string): RectAreaLight {\n        const offset = this._scene.floatingOriginOffset;\n\n        if (this._computeTransformedInformation()) {\n            this._uniformBuffer.updateFloat4(\n                \"vLightData\",\n                this._pointTransformedPosition.x - offset.x,\n                this._pointTransformedPosition.y - offset.y,\n                this._pointTransformedPosition.z - offset.z,\n                0,\n                lightIndex\n            );\n            this._uniformBuffer.updateFloat4(\"vLightWidth\", this._pointTransformedWidth.x / 2, this._pointTransformedWidth.y / 2, this._pointTransformedWidth.z / 2, 0, lightIndex);\n            this._uniformBuffer.updateFloat4(\n                \"vLightHeight\",\n                this._pointTransformedHeight.x / 2,\n                this._pointTransformedHeight.y / 2,\n                this._pointTransformedHeight.z / 2,\n                0,\n                lightIndex\n            );\n        } else {\n            this._uniformBuffer.updateFloat4(\"vLightData\", this.position.x - offset.x, this.position.y - offset.y, this.position.z - offset.z, 0, lightIndex);\n            this._uniformBuffer.updateFloat4(\"vLightWidth\", this._width.x / 2, this._width.y / 2, this._width.z / 2, 0.0, lightIndex);\n            this._uniformBuffer.updateFloat4(\"vLightHeight\", this._height.x / 2, this._height.y / 2, this._height.z / 2, 0.0, lightIndex);\n        }\n        return this;\n    }\n\n    public override transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\n        super.transferTexturesToEffect(effect, lightIndex);\n\n        if (this._emissionTextureTexture && this._emissionTextureTexture.isReady()) {\n            effect.setTexture(\"rectAreaLightEmissionTexture\" + lightIndex, this._emissionTextureTexture);\n        }\n\n        return this;\n    }\n\n    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {\n        const offset = this._scene.floatingOriginOffset;\n\n        if (this._computeTransformedInformation()) {\n            effect.setFloat3(\n                lightDataUniformName,\n                this._pointTransformedPosition.x - offset.x,\n                this._pointTransformedPosition.y - offset.y,\n                this._pointTransformedPosition.z - offset.z\n            );\n        } else {\n            effect.setFloat3(lightDataUniformName, this.position.x - offset.x, this.position.y - offset.y, this.position.z - offset.z);\n        }\n        return this;\n    }\n\n    /**\n     * Prepares the list of defines specific to the light type.\n     * @param defines the list of defines\n     * @param lightIndex defines the index of the light for the effect\n     */\n    public override prepareLightSpecificDefines(defines: any, lightIndex: number): void {\n        super.prepareLightSpecificDefines(defines, lightIndex);\n        defines[\"RECTAREALIGHTEMISSIONTEXTURE\" + lightIndex] = this._emissionTextureTexture && this._emissionTextureTexture.isReady() ? true : false;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for rectAreaLight.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterRectAreaLight(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    Node.AddNodeConstructor(\"Light_Type_4\", (name, scene) => {\n        return () => new RectAreaLight(name, Vector3.Zero(), 1, 1, scene);\n    });\n\n    // Register Class Name\n    RegisterClass(\"BABYLON.RectAreaLight\", RectAreaLight);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type Scene } from \"core/scene.pure\";\nimport { SceneComponentConstants, type RenderTargetsStageAction, type ISceneComponent } from \"core/sceneComponent\";\nimport { type ClusteredLightContainer } from \"./clusteredLightContainer.pure\";\nimport { LightConstants } from \"../lightConstants\";\n\n/**\n * A scene component required for running the clustering step in clustered lights\n */\nexport class ClusteredLightingSceneComponent implements ISceneComponent {\n    /**\n     * The name of the component. Each component must have a unique name.\n     */\n    public name = SceneComponentConstants.NAME_CLUSTEREDLIGHTING;\n\n    /**\n     * The scene the component belongs to.\n     */\n    public scene: Scene;\n\n    /**\n     * Creates a new scene component.\n     * @param scene The scene the component belongs to\n     */\n    constructor(scene: Scene) {\n        this.scene = scene;\n    }\n\n    /**\n     * Disposes the component and the associated resources.\n     */\n    public dispose(): void {}\n\n    /**\n     * Rebuilds the elements related to this component in case of\n     * context lost for instance.\n     */\n    public rebuild(): void {}\n\n    /**\n     * Register the component to one instance of a scene.\n     */\n    public register(): void {\n        this.scene._gatherActiveCameraRenderTargetsStage.registerStep(\n            SceneComponentConstants.STEP_GATHERACTIVECAMERARENDERTARGETS_CLUSTEREDLIGHTING,\n            this,\n            this._gatherActiveCameraRenderTargets\n        );\n    }\n\n    private _gatherActiveCameraRenderTargets: RenderTargetsStageAction = (renderTargets) => {\n        for (const light of this.scene.lights) {\n            if (light.getTypeID() === LightConstants.LIGHTTYPEID_CLUSTERED_CONTAINER && (<ClusteredLightContainer>light).isSupported) {\n                renderTargets.push((<ClusteredLightContainer>light)._updateBatches());\n            }\n        }\n    };\n}\n\nlet _Registered = false;\n/**\n * Register side effects for clusteredLightingSceneComponent.\n * Safe to call multiple times; only the first call has an effect.\n * @param clusteredLightContainerClass The ClusteredLightContainer class to register the component for\n */\nexport function RegisterClusteredLightingSceneComponent(clusteredLightContainerClass: typeof ClusteredLightContainer): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    clusteredLightContainerClass._SceneComponentInitialization = (scene) => {\n        if (!scene._getComponent(SceneComponentConstants.NAME_CLUSTEREDLIGHTING)) {\n            scene._addComponent(new ClusteredLightingSceneComponent(scene));\n        }\n    };\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type DeepImmutableObject, type FloatArray } from \"../types\";\r\nimport { type Vector2, Vector3, TmpVectors, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { BoundingInfo } from \"core/Culling/boundingInfo\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { VertexBuffer, Buffer } from \"../Buffers/buffer.pure\";\r\n\r\nconst BakedVertexAnimationSettingsInstancedKind = \"bakedVertexAnimationSettingsInstanced\";\r\n\r\nfunction HasCpuReadableBakedVertexAnimationData(mesh: Mesh): boolean {\r\n    const textureData = mesh.bakedVertexAnimationManager?.texture?.getInternalTexture()?._bufferView;\r\n\r\n    return textureData instanceof Float32Array || textureData instanceof Uint16Array;\r\n}\r\n\r\nfunction ExtractMinAndMaxToRef(data: FloatArray, count: number, minimum: Vector3, maximum: Vector3): void {\r\n    minimum.setAll(Number.POSITIVE_INFINITY);\r\n    maximum.setAll(Number.NEGATIVE_INFINITY);\r\n\r\n    for (let index = 0; index < count * 3; index += 3) {\r\n        const x = data[index];\r\n        const y = data[index + 1];\r\n        const z = data[index + 2];\r\n\r\n        if (x < minimum.x) {\r\n            minimum.x = x;\r\n        }\r\n        if (y < minimum.y) {\r\n            minimum.y = y;\r\n        }\r\n        if (z < minimum.z) {\r\n            minimum.z = z;\r\n        }\r\n        if (x > maximum.x) {\r\n            maximum.x = x;\r\n        }\r\n        if (y > maximum.y) {\r\n            maximum.y = y;\r\n        }\r\n        if (z > maximum.z) {\r\n            maximum.z = z;\r\n        }\r\n    }\r\n}\r\n\r\nfunction ApplyBoundingBiasToMinAndMax(minimum: Vector3, maximum: Vector3, bias: Nullable<Vector2>): void {\r\n    if (!bias) {\r\n        return;\r\n    }\r\n\r\n    minimum.x -= minimum.x * bias.x + bias.y;\r\n    minimum.y -= minimum.y * bias.x + bias.y;\r\n    minimum.z -= minimum.z * bias.x + bias.y;\r\n    maximum.x += maximum.x * bias.x + bias.y;\r\n    maximum.y += maximum.y * bias.x + bias.y;\r\n    maximum.z += maximum.z * bias.x + bias.y;\r\n}\r\n\r\nfunction UpdateTransformedMinAndMaxToRef(minimum: Vector3, maximum: Vector3, matrix: Matrix, globalMinimum: Vector3, globalMaximum: Vector3): void {\r\n    const corner = TmpVectors.Vector3[7];\r\n    const transformed = TmpVectors.Vector3[8];\r\n\r\n    for (let x = 0; x < 2; ++x) {\r\n        for (let y = 0; y < 2; ++y) {\r\n            for (let z = 0; z < 2; ++z) {\r\n                corner.set(x ? maximum.x : minimum.x, y ? maximum.y : minimum.y, z ? maximum.z : minimum.z);\r\n                Vector3.TransformCoordinatesToRef(corner, matrix, transformed);\r\n                globalMinimum.minimizeInPlace(transformed);\r\n                globalMaximum.maximizeInPlace(transformed);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nfunction UpdateTransformedDataMinAndMaxToRef(data: FloatArray, count: number, matrix: Matrix, globalMinimum: Vector3, globalMaximum: Vector3): void {\r\n    const transformed = TmpVectors.Vector3[7];\r\n\r\n    for (let index = 0; index < count * 3; index += 3) {\r\n        Vector3.TransformCoordinatesFromFloatsToRef(data[index], data[index + 1], data[index + 2], matrix, transformed);\r\n        globalMinimum.minimizeInPlace(transformed);\r\n        globalMaximum.maximizeInPlace(transformed);\r\n    }\r\n}\r\n\r\nfunction UpdateRawBoundingVectors(vectors: Vector3[], rawBoundingInfo: BoundingInfo): void {\r\n    vectors.length = 0;\r\n\r\n    for (let v = 0; v < rawBoundingInfo.boundingBox.vectors.length; ++v) {\r\n        vectors.push(rawBoundingInfo.boundingBox.vectors[v].clone());\r\n    }\r\n}\r\n\r\nfunction TryUpdateBakedVertexAnimationThinInstanceBoundingInfo(mesh: Mesh, vectors: Vector3[], applyMorph: boolean): boolean {\r\n    const storage = mesh._userThinInstanceBuffersStorage;\r\n    const bakedVertexAnimationSettingsData = storage?.data[BakedVertexAnimationSettingsInstancedKind];\r\n    const bakedVertexAnimationSettingsStride = storage?.strides[BakedVertexAnimationSettingsInstancedKind];\r\n\r\n    if (!bakedVertexAnimationSettingsData || !bakedVertexAnimationSettingsStride || bakedVertexAnimationSettingsStride < 4 || !HasCpuReadableBakedVertexAnimationData(mesh)) {\r\n        return false;\r\n    }\r\n\r\n    const matrixData = mesh._thinInstanceDataStorage.matrixData;\r\n    if (!matrixData) {\r\n        return false;\r\n    }\r\n\r\n    const cache = {};\r\n    const settings = TmpVectors.Vector4[0];\r\n    const rawMinimum = TmpVectors.Vector3[1];\r\n    const rawMaximum = TmpVectors.Vector3[2];\r\n    const globalMinimum = TmpVectors.Vector3[3];\r\n    const globalMaximum = TmpVectors.Vector3[4];\r\n    const localMinimum = TmpVectors.Vector3[5];\r\n    const localMaximum = TmpVectors.Vector3[6];\r\n    const matrix = TmpVectors.Matrix[2];\r\n    const bias = mesh.geometry ? mesh.geometry.boundingBias : null;\r\n    const vertexCount = mesh.getTotalVertices();\r\n\r\n    rawMinimum.setAll(Number.POSITIVE_INFINITY);\r\n    rawMaximum.setAll(Number.NEGATIVE_INFINITY);\r\n    globalMinimum.setAll(Number.POSITIVE_INFINITY);\r\n    globalMaximum.setAll(Number.NEGATIVE_INFINITY);\r\n\r\n    for (let index = 0; index < mesh._thinInstanceDataStorage.instancesCount; ++index) {\r\n        const settingsOffset = index * bakedVertexAnimationSettingsStride;\r\n        settings.set(\r\n            bakedVertexAnimationSettingsData[settingsOffset],\r\n            bakedVertexAnimationSettingsData[settingsOffset + 1],\r\n            bakedVertexAnimationSettingsData[settingsOffset + 2],\r\n            bakedVertexAnimationSettingsData[settingsOffset + 3]\r\n        );\r\n\r\n        const positionData = mesh._getData(\r\n            {\r\n                applyMorph,\r\n                applyBakedVertexAnimation: true,\r\n                bakedVertexAnimationSettings: settings,\r\n                updatePositionsArray: false,\r\n                cache,\r\n            },\r\n            null,\r\n            VertexBuffer.PositionKind\r\n        );\r\n\r\n        if (!positionData) {\r\n            return false;\r\n        }\r\n\r\n        ExtractMinAndMaxToRef(positionData, vertexCount, localMinimum, localMaximum);\r\n        ApplyBoundingBiasToMinAndMax(localMinimum, localMaximum, bias);\r\n        rawMinimum.minimizeInPlace(localMinimum);\r\n        rawMaximum.maximizeInPlace(localMaximum);\r\n\r\n        Matrix.FromArrayToRef(matrixData, index * 16, matrix);\r\n        if (bias) {\r\n            UpdateTransformedMinAndMaxToRef(localMinimum, localMaximum, matrix, globalMinimum, globalMaximum);\r\n        } else {\r\n            UpdateTransformedDataMinAndMaxToRef(positionData, vertexCount, matrix, globalMinimum, globalMaximum);\r\n        }\r\n    }\r\n\r\n    if (!isFinite(rawMinimum.x) || !isFinite(globalMinimum.x)) {\r\n        return false;\r\n    }\r\n\r\n    const boundingInfo = mesh.getBoundingInfo();\r\n    boundingInfo.reConstruct(globalMinimum, globalMaximum);\r\n    mesh.rawBoundingInfo = new BoundingInfo(rawMinimum, rawMaximum);\r\n    UpdateRawBoundingVectors(vectors, mesh.rawBoundingInfo);\r\n\r\n    mesh._updateBoundingInfo();\r\n\r\n    return true;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for thinInstanceMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterThinInstanceMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh.prototype.thinInstanceAdd = function (matrix: DeepImmutableObject<Matrix> | Array<DeepImmutableObject<Matrix>>, refresh: boolean = true): number {\r\n        if (!this.getScene().getEngine().getCaps().instancedArrays) {\r\n            Logger.Error(\"Thin Instances are not supported on this device as Instanced Array extension not supported\");\r\n            return -1;\r\n        }\r\n\r\n        this._thinInstanceUpdateBufferSize(\"matrix\", Array.isArray(matrix) ? matrix.length : 1);\r\n\r\n        const index = this._thinInstanceDataStorage.instancesCount;\r\n\r\n        if (Array.isArray(matrix)) {\r\n            for (let i = 0; i < matrix.length; ++i) {\r\n                this.thinInstanceSetMatrixAt(this._thinInstanceDataStorage.instancesCount++, matrix[i], i === matrix.length - 1 && refresh);\r\n            }\r\n        } else {\r\n            this.thinInstanceSetMatrixAt(this._thinInstanceDataStorage.instancesCount++, matrix, refresh);\r\n        }\r\n\r\n        return index;\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceAddSelf = function (refresh: boolean = true): number {\r\n        return this.thinInstanceAdd(Matrix.IdentityReadOnly, refresh);\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceRegisterAttribute = function (kind: string, stride: number): void {\r\n        // preserve backward compatibility\r\n        if (kind === VertexBuffer.ColorKind) {\r\n            kind = VertexBuffer.ColorInstanceKind;\r\n        }\r\n\r\n        this.removeVerticesData(kind);\r\n\r\n        this._thinInstanceInitializeUserStorage();\r\n\r\n        this._userThinInstanceBuffersStorage.strides[kind] = stride;\r\n        this._userThinInstanceBuffersStorage.sizes[kind] = stride * Math.max(32, this._thinInstanceDataStorage.instancesCount); // Initial size\r\n        this._userThinInstanceBuffersStorage.data[kind] = new Float32Array(this._userThinInstanceBuffersStorage.sizes[kind]);\r\n        this._userThinInstanceBuffersStorage.vertexBuffers[kind] = new VertexBuffer(\r\n            this.getEngine(),\r\n            this._userThinInstanceBuffersStorage.data[kind],\r\n            kind,\r\n            true,\r\n            false,\r\n            stride,\r\n            true\r\n        );\r\n\r\n        this.setVerticesBuffer(this._userThinInstanceBuffersStorage.vertexBuffers[kind]!);\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceSetMatrixAt = function (index: number, matrix: DeepImmutableObject<Matrix>, refresh: boolean = true): boolean {\r\n        if (!this._thinInstanceDataStorage.matrixData || index >= this._thinInstanceDataStorage.instancesCount) {\r\n            return false;\r\n        }\r\n\r\n        const matrixData = this._thinInstanceDataStorage.matrixData;\r\n\r\n        matrix.copyToArray(matrixData, index * 16);\r\n\r\n        if (this._thinInstanceDataStorage.worldMatrices) {\r\n            this._thinInstanceDataStorage.worldMatrices[index] = matrix as Matrix;\r\n        }\r\n\r\n        if (refresh) {\r\n            this.thinInstanceBufferUpdated(\"matrix\");\r\n\r\n            if (!this.doNotSyncBoundingInfo) {\r\n                this.thinInstanceRefreshBoundingInfo(false);\r\n            }\r\n        }\r\n\r\n        return true;\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceSetAttributeAt = function (kind: string, index: number, value: Array<number>, refresh: boolean = true): boolean {\r\n        // preserve backward compatibility\r\n        if (kind === VertexBuffer.ColorKind) {\r\n            kind = VertexBuffer.ColorInstanceKind;\r\n        }\r\n\r\n        if (!this._userThinInstanceBuffersStorage || !this._userThinInstanceBuffersStorage.data[kind] || index >= this._thinInstanceDataStorage.instancesCount) {\r\n            return false;\r\n        }\r\n\r\n        this._thinInstanceUpdateBufferSize(kind, 0); // make sur the buffer for the kind attribute is big enough\r\n\r\n        this._userThinInstanceBuffersStorage.data[kind].set(value, index * this._userThinInstanceBuffersStorage.strides[kind]);\r\n\r\n        if (refresh) {\r\n            this.thinInstanceBufferUpdated(kind);\r\n        }\r\n\r\n        return true;\r\n    };\r\n\r\n    Object.defineProperty(Mesh.prototype, \"thinInstanceCount\", {\r\n        get: function (this: Mesh) {\r\n            return this._thinInstanceDataStorage.instancesCount;\r\n        },\r\n        set: function (this: Mesh, value: number) {\r\n            const matrixData = this._thinInstanceDataStorage.matrixData ?? this.source?._thinInstanceDataStorage.matrixData;\r\n            const numMaxInstances = matrixData ? matrixData.length / 16 : 0;\r\n\r\n            if (value <= numMaxInstances) {\r\n                this._thinInstanceDataStorage.instancesCount = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Mesh.prototype._thinInstanceCreateMatrixBuffer = function (kind: string, buffer: Float32Array, staticBuffer: boolean = true): Buffer {\r\n        const matrixBuffer = new Buffer(this.getEngine(), buffer, !staticBuffer, 16, false, true);\r\n\r\n        for (let i = 0; i < 4; i++) {\r\n            this.setVerticesBuffer(matrixBuffer.createVertexBuffer(kind + i, i * 4, 4));\r\n        }\r\n\r\n        return matrixBuffer;\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceSetBuffer = function (kind: string, buffer: Nullable<Float32Array>, stride: number = 0, staticBuffer: boolean = true): void {\r\n        stride = stride || 16;\r\n\r\n        if (kind === \"matrix\") {\r\n            this._thinInstanceDataStorage.matrixBuffer?.dispose();\r\n            this._thinInstanceDataStorage.matrixBuffer = null;\r\n            this._thinInstanceDataStorage.matrixBufferSize = buffer ? buffer.length : 32 * stride;\r\n            this._thinInstanceDataStorage.matrixData = buffer;\r\n            this._thinInstanceDataStorage.worldMatrices = null;\r\n\r\n            if (buffer !== null) {\r\n                this._thinInstanceDataStorage.instancesCount = buffer.length / stride;\r\n                this._thinInstanceDataStorage.matrixBuffer = this._thinInstanceCreateMatrixBuffer(\"world\", buffer, staticBuffer);\r\n\r\n                if (!this.doNotSyncBoundingInfo) {\r\n                    this.thinInstanceRefreshBoundingInfo(false);\r\n                }\r\n            } else {\r\n                this._thinInstanceDataStorage.instancesCount = 0;\r\n                if (!this.doNotSyncBoundingInfo) {\r\n                    // mesh has no more thin instances, so need to recompute the bounding box because it's the regular mesh that will now be displayed\r\n                    this.refreshBoundingInfo();\r\n                }\r\n            }\r\n        } else if (kind === \"previousMatrix\") {\r\n            this._thinInstanceDataStorage.previousMatrixBuffer?.dispose();\r\n            this._thinInstanceDataStorage.previousMatrixBuffer = null;\r\n            this._thinInstanceDataStorage.previousMatrixData = buffer;\r\n            if (buffer !== null) {\r\n                this._thinInstanceDataStorage.previousMatrixBuffer = this._thinInstanceCreateMatrixBuffer(\"previousWorld\", buffer, staticBuffer);\r\n            }\r\n        } else if (kind === \"splatIndex\" && buffer) {\r\n            this._thinInstanceInitializeUserStorage();\r\n            this._thinInstanceDataStorage.instancesCount = buffer.length / stride;\r\n            this._userThinInstanceBuffersStorage.data[kind] = buffer;\r\n            this._userThinInstanceBuffersStorage.strides[kind] = stride;\r\n            this._userThinInstanceBuffersStorage.sizes[kind] = buffer.length;\r\n            const splatInstancesBuffer = new Buffer(this.getEngine(), buffer, true, 16, false, true);\r\n            this._thinInstanceDataStorage.matrixBuffer = splatInstancesBuffer;\r\n            for (let i = 0; i < 4; i++) {\r\n                this.setVerticesBuffer(splatInstancesBuffer.createVertexBuffer(kind + i, i * 4, 4));\r\n            }\r\n        } else {\r\n            // color for instanced mesh is ColorInstanceKind and not ColorKind because of native that needs to do the differenciation\r\n            // hot switching kind here to preserve backward compatibility\r\n            if (kind === VertexBuffer.ColorKind) {\r\n                kind = VertexBuffer.ColorInstanceKind;\r\n            }\r\n\r\n            if (buffer === null) {\r\n                if (this._userThinInstanceBuffersStorage?.data[kind]) {\r\n                    this.removeVerticesData(kind);\r\n                    delete this._userThinInstanceBuffersStorage.data[kind];\r\n                    delete this._userThinInstanceBuffersStorage.strides[kind];\r\n                    delete this._userThinInstanceBuffersStorage.sizes[kind];\r\n                    delete this._userThinInstanceBuffersStorage.vertexBuffers[kind];\r\n                }\r\n            } else {\r\n                this._thinInstanceInitializeUserStorage();\r\n\r\n                this._userThinInstanceBuffersStorage.data[kind] = buffer;\r\n                this._userThinInstanceBuffersStorage.strides[kind] = stride;\r\n                this._userThinInstanceBuffersStorage.sizes[kind] = buffer.length;\r\n                this._userThinInstanceBuffersStorage.vertexBuffers[kind] = new VertexBuffer(this.getEngine(), buffer, kind, !staticBuffer, false, stride, true);\r\n\r\n                this.setVerticesBuffer(this._userThinInstanceBuffersStorage.vertexBuffers[kind]!);\r\n            }\r\n        }\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceBufferUpdated = function (kind: string): void {\r\n        if (kind === \"matrix\") {\r\n            if (this.thinInstanceAllowAutomaticStaticBufferRecreation && this._thinInstanceDataStorage.matrixBuffer && !this._thinInstanceDataStorage.matrixBuffer.isUpdatable()) {\r\n                this._thinInstanceRecreateBuffer(kind);\r\n            }\r\n            this._thinInstanceDataStorage.matrixBuffer?.updateDirectly(this._thinInstanceDataStorage.matrixData!, 0, this._thinInstanceDataStorage.instancesCount);\r\n        } else if (kind === \"previousMatrix\") {\r\n            if (\r\n                this.thinInstanceAllowAutomaticStaticBufferRecreation &&\r\n                this._thinInstanceDataStorage.previousMatrixBuffer &&\r\n                !this._thinInstanceDataStorage.previousMatrixBuffer.isUpdatable()\r\n            ) {\r\n                this._thinInstanceRecreateBuffer(kind);\r\n            }\r\n            this._thinInstanceDataStorage.previousMatrixBuffer?.updateDirectly(this._thinInstanceDataStorage.previousMatrixData!, 0, this._thinInstanceDataStorage.instancesCount);\r\n        } else if (kind === \"splatIndex\") {\r\n            this._thinInstanceDataStorage.matrixBuffer?.updateDirectly(this._userThinInstanceBuffersStorage.data[kind], 0, this._thinInstanceDataStorage.instancesCount);\r\n        } else {\r\n            // preserve backward compatibility\r\n            if (kind === VertexBuffer.ColorKind) {\r\n                kind = VertexBuffer.ColorInstanceKind;\r\n            }\r\n\r\n            if (this._userThinInstanceBuffersStorage?.vertexBuffers[kind]) {\r\n                if (this.thinInstanceAllowAutomaticStaticBufferRecreation && !this._userThinInstanceBuffersStorage.vertexBuffers[kind]!.isUpdatable()) {\r\n                    this._thinInstanceRecreateBuffer(kind);\r\n                }\r\n                this._userThinInstanceBuffersStorage.vertexBuffers[kind]!.updateDirectly(this._userThinInstanceBuffersStorage.data[kind], 0);\r\n            }\r\n        }\r\n    };\r\n\r\n    Mesh.prototype.thinInstancePartialBufferUpdate = function (kind: string, dataOrLength: Float32Array | number, offset: number): void {\r\n        if (kind === \"matrix\") {\r\n            if (this._thinInstanceDataStorage.matrixBuffer) {\r\n                if (typeof dataOrLength === \"number\") {\r\n                    this._thinInstanceDataStorage.matrixBuffer.updateDirectly(\r\n                        new Float32Array(\r\n                            this._thinInstanceDataStorage.matrixData!.buffer,\r\n                            this._thinInstanceDataStorage.matrixData!.byteOffset + offset * 16 * Float32Array.BYTES_PER_ELEMENT,\r\n                            dataOrLength * 16\r\n                        ),\r\n                        offset * 16\r\n                    );\r\n                } else {\r\n                    this._thinInstanceDataStorage.matrixBuffer.updateDirectly(dataOrLength, offset);\r\n                }\r\n            }\r\n        } else {\r\n            // preserve backward compatibility\r\n            if (kind === VertexBuffer.ColorKind) {\r\n                kind = VertexBuffer.ColorInstanceKind;\r\n            }\r\n\r\n            if (this._userThinInstanceBuffersStorage?.vertexBuffers[kind]) {\r\n                const buffer = this._userThinInstanceBuffersStorage.vertexBuffers[kind]!;\r\n                if (typeof dataOrLength === \"number\") {\r\n                    const data = new Float32Array(\r\n                        this._userThinInstanceBuffersStorage.data[kind].buffer,\r\n                        this._userThinInstanceBuffersStorage.data[kind].byteOffset + offset * this._userThinInstanceBuffersStorage.strides[kind] * Float32Array.BYTES_PER_ELEMENT,\r\n                        dataOrLength * this._userThinInstanceBuffersStorage.strides[kind]\r\n                    );\r\n                    this._userThinInstanceBuffersStorage.vertexBuffers[kind]!.updateDirectly(data, offset * this._userThinInstanceBuffersStorage.strides[kind]);\r\n                } else {\r\n                    buffer.updateDirectly(dataOrLength, offset);\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceGetWorldMatrices = function (): Matrix[] {\r\n        if (!this._thinInstanceDataStorage.matrixData || !this._thinInstanceDataStorage.matrixBuffer) {\r\n            return [];\r\n        }\r\n        const matrixData = this._thinInstanceDataStorage.matrixData;\r\n\r\n        if (!this._thinInstanceDataStorage.worldMatrices) {\r\n            this._thinInstanceDataStorage.worldMatrices = [] as Matrix[];\r\n\r\n            for (let i = 0; i < this._thinInstanceDataStorage.instancesCount; ++i) {\r\n                this._thinInstanceDataStorage.worldMatrices[i] = Matrix.FromArray(matrixData, i * 16);\r\n            }\r\n        }\r\n\r\n        return this._thinInstanceDataStorage.worldMatrices;\r\n    };\r\n\r\n    Mesh.prototype.thinInstanceRefreshBoundingInfo = function (\r\n        forceRefreshParentInfo: boolean = false,\r\n        applySkeleton: boolean = false,\r\n        applyMorph: boolean = false,\r\n        applyBakedVertexAnimation: boolean = false\r\n    ) {\r\n        if (!this._thinInstanceDataStorage.matrixData || !this._thinInstanceDataStorage.matrixBuffer) {\r\n            return;\r\n        }\r\n\r\n        const vectors = this._thinInstanceDataStorage.boundingVectors;\r\n\r\n        if (forceRefreshParentInfo || !this.rawBoundingInfo) {\r\n            vectors.length = 0;\r\n            if (applyBakedVertexAnimation && TryUpdateBakedVertexAnimationThinInstanceBoundingInfo(this, vectors, applyMorph)) {\r\n                return;\r\n            }\r\n\r\n            const useBakedVertexAnimation = applyBakedVertexAnimation && this.bakedVertexAnimationManager?.isEnabled && HasCpuReadableBakedVertexAnimationData(this);\r\n            if (useBakedVertexAnimation) {\r\n                this.refreshBoundingInfo({ applySkeleton, applyMorph, applyBakedVertexAnimation: true, updatePositionsArray: false });\r\n            } else {\r\n                this.refreshBoundingInfo(applySkeleton, applyMorph);\r\n            }\r\n            const boundingInfo = this.getBoundingInfo();\r\n            this.rawBoundingInfo = new BoundingInfo(boundingInfo.minimum, boundingInfo.maximum);\r\n        }\r\n\r\n        const boundingInfo = this.getBoundingInfo();\r\n        const matrixData = this._thinInstanceDataStorage.matrixData;\r\n\r\n        if (vectors.length === 0) {\r\n            for (let v = 0; v < boundingInfo.boundingBox.vectors.length; ++v) {\r\n                vectors.push(boundingInfo.boundingBox.vectors[v].clone());\r\n            }\r\n        }\r\n\r\n        TmpVectors.Vector3[0].setAll(Number.POSITIVE_INFINITY); // min\r\n        TmpVectors.Vector3[1].setAll(Number.NEGATIVE_INFINITY); // max\r\n\r\n        for (let i = 0; i < this._thinInstanceDataStorage.instancesCount; ++i) {\r\n            Matrix.FromArrayToRef(matrixData, i * 16, TmpVectors.Matrix[0]);\r\n\r\n            for (let v = 0; v < vectors.length; ++v) {\r\n                Vector3.TransformCoordinatesToRef(vectors[v], TmpVectors.Matrix[0], TmpVectors.Vector3[2]);\r\n                TmpVectors.Vector3[0].minimizeInPlace(TmpVectors.Vector3[2]);\r\n                TmpVectors.Vector3[1].maximizeInPlace(TmpVectors.Vector3[2]);\r\n            }\r\n        }\r\n\r\n        boundingInfo.reConstruct(TmpVectors.Vector3[0], TmpVectors.Vector3[1]);\r\n\r\n        this._updateBoundingInfo();\r\n    };\r\n\r\n    Mesh.prototype._thinInstanceRecreateBuffer = function (kind: string, staticBuffer: boolean = true) {\r\n        if (kind === \"matrix\") {\r\n            this._thinInstanceDataStorage.matrixBuffer?.dispose();\r\n            this._thinInstanceDataStorage.matrixBuffer = this._thinInstanceCreateMatrixBuffer(\"world\", this._thinInstanceDataStorage.matrixData, staticBuffer);\r\n        } else if (kind === \"previousMatrix\") {\r\n            if (this._scene.needsPreviousWorldMatrices) {\r\n                this._thinInstanceDataStorage.previousMatrixBuffer?.dispose();\r\n                this._thinInstanceDataStorage.previousMatrixBuffer = this._thinInstanceCreateMatrixBuffer(\r\n                    \"previousWorld\",\r\n                    this._thinInstanceDataStorage.previousMatrixData ?? this._thinInstanceDataStorage.matrixData,\r\n                    staticBuffer\r\n                );\r\n            }\r\n        } else {\r\n            if (kind === VertexBuffer.ColorKind) {\r\n                kind = VertexBuffer.ColorInstanceKind;\r\n            }\r\n\r\n            this._userThinInstanceBuffersStorage.vertexBuffers[kind]?.dispose();\r\n            this._userThinInstanceBuffersStorage.vertexBuffers[kind] = new VertexBuffer(\r\n                this.getEngine(),\r\n                this._userThinInstanceBuffersStorage.data[kind],\r\n                kind,\r\n                !staticBuffer,\r\n                false,\r\n                this._userThinInstanceBuffersStorage.strides[kind],\r\n                true\r\n            );\r\n            this.setVerticesBuffer(this._userThinInstanceBuffersStorage.vertexBuffers[kind]!);\r\n        }\r\n    };\r\n\r\n    Mesh.prototype._thinInstanceUpdateBufferSize = function (kind: string, numInstances: number = 1) {\r\n        // preserve backward compatibility\r\n        if (kind === VertexBuffer.ColorKind) {\r\n            kind = VertexBuffer.ColorInstanceKind;\r\n        }\r\n\r\n        const kindIsMatrix = kind === \"matrix\";\r\n\r\n        if (!kindIsMatrix && (!this._userThinInstanceBuffersStorage || !this._userThinInstanceBuffersStorage.strides[kind])) {\r\n            return;\r\n        }\r\n\r\n        const stride = kindIsMatrix ? 16 : this._userThinInstanceBuffersStorage.strides[kind];\r\n        const currentSize = kindIsMatrix ? this._thinInstanceDataStorage.matrixBufferSize : this._userThinInstanceBuffersStorage.sizes[kind];\r\n        let data = kindIsMatrix ? this._thinInstanceDataStorage.matrixData : this._userThinInstanceBuffersStorage.data[kind];\r\n\r\n        const bufferSize = (this._thinInstanceDataStorage.instancesCount + numInstances) * stride;\r\n\r\n        let newSize = currentSize;\r\n\r\n        while (newSize < bufferSize) {\r\n            newSize *= 2;\r\n        }\r\n\r\n        if (!data || currentSize != newSize) {\r\n            if (!data) {\r\n                data = new Float32Array(newSize);\r\n            } else {\r\n                const newData = new Float32Array(newSize);\r\n                newData.set(data, 0);\r\n                data = newData;\r\n            }\r\n\r\n            if (kindIsMatrix) {\r\n                this._thinInstanceDataStorage.matrixBuffer?.dispose();\r\n                this._thinInstanceDataStorage.matrixBuffer = this._thinInstanceCreateMatrixBuffer(\"world\", data, false);\r\n                this._thinInstanceDataStorage.matrixData = data;\r\n                this._thinInstanceDataStorage.matrixBufferSize = newSize;\r\n                if (this._scene.needsPreviousWorldMatrices && !this._thinInstanceDataStorage.previousMatrixData) {\r\n                    this._thinInstanceDataStorage.previousMatrixBuffer?.dispose();\r\n                    this._thinInstanceDataStorage.previousMatrixBuffer = this._thinInstanceCreateMatrixBuffer(\"previousWorld\", data, false);\r\n                }\r\n            } else {\r\n                this._userThinInstanceBuffersStorage.vertexBuffers[kind]?.dispose();\r\n\r\n                this._userThinInstanceBuffersStorage.data[kind] = data;\r\n                this._userThinInstanceBuffersStorage.sizes[kind] = newSize;\r\n                this._userThinInstanceBuffersStorage.vertexBuffers[kind] = new VertexBuffer(this.getEngine(), data, kind, true, false, stride, true);\r\n\r\n                this.setVerticesBuffer(this._userThinInstanceBuffersStorage.vertexBuffers[kind]!);\r\n            }\r\n        }\r\n    };\r\n\r\n    Mesh.prototype._thinInstanceInitializeUserStorage = function () {\r\n        if (!this._userThinInstanceBuffersStorage) {\r\n            this._userThinInstanceBuffersStorage = {\r\n                data: {},\r\n                sizes: {},\r\n                vertexBuffers: {},\r\n                strides: {},\r\n            };\r\n        }\r\n    };\r\n\r\n    Mesh.prototype._disposeThinInstanceSpecificData = function () {\r\n        if (this._thinInstanceDataStorage?.matrixBuffer) {\r\n            this._thinInstanceDataStorage.matrixBuffer.dispose();\r\n            this._thinInstanceDataStorage.matrixBuffer = null;\r\n        }\r\n        if (this._thinInstanceDataStorage?.previousMatrixBuffer) {\r\n            this._thinInstanceDataStorage.previousMatrixBuffer.dispose();\r\n            this._thinInstanceDataStorage.previousMatrixBuffer = null;\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { StorageBuffer } from \"core/Buffers/storageBuffer\";\nimport { type Camera } from \"core/Cameras/camera.pure\";\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\nimport { Constants } from \"core/Engines/constants\";\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine.pure\";\nimport { type Effect } from \"core/Materials/effect.pure\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial.pure\";\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture.pure\";\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\nimport { TmpColors } from \"core/Maths/math.color.pure\";\nimport { TmpVectors, Vector3 } from \"core/Maths/math.vector.pure\";\nimport { CreatePlane } from \"core/Meshes/Builders/planeBuilder.pure\";\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\nimport { serialize } from \"core/Misc/decorators\";\nimport { _WarnImport } from \"core/Misc/devTools\";\nimport { Logger } from \"core/Misc/logger\";\nimport { type Scene } from \"core/scene.pure\";\nimport { type Nullable } from \"core/types\";\nimport { Light } from \"../light\";\nimport { LightConstants } from \"../lightConstants\";\nimport { type PointLight } from \"../pointLight.pure\";\nimport { type SpotLight } from \"../spotLight.pure\";\nimport { type RenderTargetWrapper } from \"../../Engines/renderTargetWrapper\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\nimport { Node } from \"core/node\";\nimport { RegisterClusteredLightingSceneComponent } from \"./clusteredLightingSceneComponent.pure\";\nimport { RegisterEnginesExtensionsEngineRawTexture } from \"core/Engines/Extensions/engine.rawTexture.pure\";\nimport { RegisterEnginesExtensionsEngineRenderTarget } from \"core/Engines/Extensions/engine.renderTarget.pure\";\nimport { RegisterEnginesExtensionsEngineRenderTargetTexture } from \"core/Engines/Extensions/engine.renderTargetTexture.pure\";\nimport { RegisterThinInstanceMesh } from \"core/Meshes/thinInstanceMesh.pure\";\n\nconst DefaultDepthSlices = 16;\nconst MobileClusteredLightBatchSize = 8;\n\n/**\n * A special light that renders all its associated spot or point lights using a clustered or forward+ system.\n */\nexport class ClusteredLightContainer extends Light {\n    private static _GetEngineBatchSize(engine: AbstractEngine): number {\n        const caps = engine._caps;\n        if (!caps.texelFetch) {\n            return 0;\n        } else if (engine.isWebGPU) {\n            // On WebGPU we use atomic writes to storage buffers\n            return 32;\n        } else if (engine.version > 1) {\n            // On WebGL 2 we use additive float blending as the light mask\n            if (!caps.colorBufferFloat || !caps.blendFloat) {\n                return 0;\n            }\n            // Due to the use of floats we want to limit lights to the precision of floats\n            // The reduced precision for mobiles is because some devices (like Samsung Galaxy) report support for R32F but actually create the texture with less precision.\n            return engine.hostInformation.isMobile ? MobileClusteredLightBatchSize : caps.shaderFloatPrecision;\n        } else {\n            // WebGL 1 is not supported due to lack of dynamic for loops\n            return 0;\n        }\n    }\n\n    /**\n     * Checks if the clustered lighting system supports the given light with its current parameters.\n     * This will also check if the light's associated engine supports clustered lighting.\n     *\n     * @param light The light to test\n     * @returns true if the light and its engine is supported\n     */\n    public static IsLightSupported(light: Light): boolean {\n        if (ClusteredLightContainer._GetEngineBatchSize(light.getEngine()) === 0) {\n            return false;\n        }\n\n        if (light.shadowEnabled && light._scene.shadowsEnabled && light.getShadowGenerators()) {\n            // Shadows are not supported\n            return false;\n        }\n\n        if (light.falloffType !== Light.FALLOFF_DEFAULT) {\n            // Only the default falloff is supported\n            return false;\n        }\n\n        if (light.getTypeID() === LightConstants.LIGHTTYPEID_POINTLIGHT) {\n            return true;\n        }\n\n        if (light.getTypeID() === LightConstants.LIGHTTYPEID_SPOTLIGHT) {\n            // Extra texture bindings per light are not supported\n            return !(<SpotLight>light).projectionTexture && !(<SpotLight>light).iesProfileTexture;\n        }\n\n        // Currently only point and spot lights are supported\n        return false;\n    }\n\n    /** @internal */\n    public static _SceneComponentInitialization: (scene: Scene) => void = () => {\n        throw _WarnImport(\"ClusteredLightingSceneComponent\");\n    };\n\n    private readonly _batchSize: number;\n\n    /**\n     * True if clustered lighting is supported.\n     */\n    public get isSupported(): boolean {\n        return this._batchSize > 0;\n    }\n\n    private readonly _lights: Light[] = [];\n    /**\n     * Gets the current list of lights added to this clustering system.\n     */\n    public get lights(): readonly Light[] {\n        return this._lights;\n    }\n\n    private _camera: Nullable<Camera> = null;\n\n    // The lights sorted by depth\n    private readonly _sortedLights: (PointLight | SpotLight)[] = [];\n\n    private _lightDataBuffer: Float32Array;\n    private _lightDataTexture: RawTexture;\n    private _lightDataRenderId = -1;\n\n    private _tileMaskBatches = -1;\n    private _tileMaskTexture: RenderTargetTexture;\n    private _tileMaskBuffer: Nullable<StorageBuffer>;\n\n    private _horizontalTiles = 64;\n    /**\n     * The number of tiles in the horizontal direction to cluster lights into.\n     * A lower value will reduce memory and make the clustering step faster, while a higher value increases memory and makes the rendering step faster.\n     */\n    @serialize()\n    public get horizontalTiles(): number {\n        return this._horizontalTiles;\n    }\n\n    public set horizontalTiles(horizontal: number) {\n        if (this._horizontalTiles === horizontal) {\n            return;\n        }\n        this._horizontalTiles = horizontal;\n        // Force the batch data to be recreated\n        this._tileMaskBatches = -1;\n    }\n\n    private _verticalTiles = 64;\n    /**\n     * The number of tiles in the vertical direction to cluster lights into.\n     * A lower value will reduce memory and make the clustering step faster, while a higher value increases memory and makes the rendering step faster.\n     */\n    @serialize()\n    public get verticalTiles(): number {\n        return this._verticalTiles;\n    }\n\n    public set verticalTiles(vertical: number) {\n        if (this._verticalTiles === vertical) {\n            return;\n        }\n        this._verticalTiles = vertical;\n        // Force the batch data to be recreated\n        this._tileMaskBatches = -1;\n    }\n\n    private _sliceScale = 0;\n    private _sliceBias = 0;\n    // List of vec2's that keep track of the min and max index per slice\n    private _sliceRanges: Float32Array<ArrayBuffer>;\n    // Tracks the last lightIndex string passed to transferToEffect, or null if the cluster\n    // has not yet been bound. Used to refresh the camera-dependent UBO entries (vSliceData /\n    // vSliceRanges) every frame in cases where material binding is bypassed (e.g. WebGPU FAST\n    // snapshot rendering replays cached bundles and never re-runs Light._bindLight).\n    private _lastBoundLightIndex: Nullable<string> = null;\n\n    private _depthSlices = DefaultDepthSlices;\n    /**\n     * The number of slices to split the depth range by and cluster lights into.\n     */\n    @serialize()\n    public get depthSlices(): number {\n        return this._depthSlices;\n    }\n\n    public set depthSlices(slices: number) {\n        if (this._depthSlices === slices) {\n            return;\n        }\n        this._depthSlices = slices;\n        this._sliceRanges = new Float32Array(slices * 2);\n\n        // UBO size depends on the number of depth slices\n        this._uniformBuffer.dispose();\n        this._uniformBuffer = new UniformBuffer(this.getEngine(), undefined, undefined, this.name);\n        this._buildUniformLayout();\n        // The UBO has been recreated so previous bindings are no longer valid; transferToEffect will repopulate it.\n        this._lastBoundLightIndex = null;\n\n        // CLUSTLIGHT_SLICES is a shader define that sizes the vSliceRanges array in the UBO.\n        // Materials must recompile when depthSlices changes so the shader layout matches the rebuilt UBO.\n        // Otherwise, if depthSlices is reduced, the rebuilt UBO can be smaller than what the previously compiled shader expects, causing rendering to fail.\n        this._markMeshesAsLightDirty();\n    }\n\n    private readonly _proxyMaterial: ShaderMaterial;\n    private readonly _proxyMesh: Mesh;\n\n    private _maxRange = 16383;\n    private _minInverseSquaredRange = 1 / (this._maxRange * this._maxRange);\n    /**\n     * This limits the range of all the added lights, so even lights with extreme ranges will still have bounds for clustering.\n     */\n    @serialize()\n    public get maxRange(): number {\n        return this._maxRange;\n    }\n\n    public set maxRange(range: number) {\n        if (this._maxRange === range) {\n            return;\n        }\n        this._maxRange = range;\n        this._minInverseSquaredRange = 1 / (range * range);\n    }\n\n    /**\n     * Creates a new clustered light system with an initial set of lights.\n     *\n     * @param name The name of the clustered light container\n     * @param lights The initial set of lights to add\n     * @param scene The scene the clustered light container belongs to\n     */\n    constructor(name: string, lights: Light[] = [], scene?: Scene) {\n        super(name, scene);\n        const engine = this.getEngine();\n        this._batchSize = ClusteredLightContainer._GetEngineBatchSize(engine);\n\n        // Clustered lighting relies on engine and mesh side effects that are not part of the\n        // pure import baseline. Register them here (idempotently) so the feature works on the\n        // tree-shakeable path without requiring callers to import these extensions manually.\n        // Without this, createRawTexture/createRenderTargetTexture throw and the thin-instance\n        // setters silently no-op, leaving the scene unlit with no error.\n        RegisterEnginesExtensionsEngineRawTexture();\n        RegisterEnginesExtensionsEngineRenderTarget();\n        RegisterEnginesExtensionsEngineRenderTargetTexture();\n        RegisterThinInstanceMesh();\n\n        const proxyShader = { vertex: \"lightProxy\", fragment: \"lightProxy\" };\n        const defines = [`CLUSTLIGHT_BATCH ${this._batchSize}`];\n        if (this._scene.useRightHandedSystem) {\n            defines.push(\"#define RIGHT_HANDED\");\n        }\n        this._proxyMaterial = new ShaderMaterial(\"ProxyMaterial\", this._scene, proxyShader, {\n            attributes: [\"position\"],\n            uniforms: [\"view\", \"projection\", \"tileMaskResolution\"],\n            samplers: [\"lightDataTexture\"],\n            uniformBuffers: [\"Scene\"],\n            storageBuffers: [\"tileMaskBuffer\"],\n            defines,\n            shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n            extraInitializationsAsync: async () => {\n                if (engine.isWebGPU) {\n                    await Promise.all([import(\"../../ShadersWGSL/lightProxy.vertex\"), import(\"../../ShadersWGSL/lightProxy.fragment\")]);\n                } else {\n                    await Promise.all([import(\"../../Shaders/lightProxy.vertex\"), import(\"../../Shaders/lightProxy.fragment\")]);\n                }\n            },\n        });\n\n        // Additive blending is for merging masks on WebGL\n        this._proxyMaterial.transparencyMode = ShaderMaterial.MATERIAL_ALPHABLEND;\n        this._proxyMaterial.alphaMode = Constants.ALPHA_ADD;\n        this._proxyMaterial.sideOrientation = Constants.MATERIAL_CounterClockWiseSideOrientation;\n\n        this._proxyMesh = CreatePlane(\"ProxyMesh\", { size: 2 }, this._scene);\n        // Make sure it doesn't render for the default scene\n        this._scene.removeMesh(this._proxyMesh);\n        this._proxyMesh.material = this._proxyMaterial;\n\n        this._updateBatches();\n\n        this._sliceRanges = new Float32Array(this._depthSlices * 2);\n\n        if (this._batchSize > 0) {\n            RegisterClusteredLightingSceneComponent(ClusteredLightContainer);\n            ClusteredLightContainer._SceneComponentInitialization(this._scene);\n            for (const light of lights) {\n                this.addLight(light);\n            }\n        }\n    }\n\n    public override getClassName(): string {\n        return \"ClusteredLightContainer\";\n    }\n\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    public override getTypeID(): number {\n        return LightConstants.LIGHTTYPEID_CLUSTERED_CONTAINER;\n    }\n\n    /** @internal */\n    public _updateBatches(camera: Nullable<Camera> = null): RenderTargetTexture {\n        this._camera = camera;\n        this._proxyMesh.isVisible = this._sortedLights.length > 0;\n\n        // Ensure space for atleast 1 batch\n        const batches = Math.max(Math.ceil(this._sortedLights.length / this._batchSize), 1);\n        if (this._tileMaskBatches >= batches) {\n            this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n            return this._tileMaskTexture;\n        }\n        const engine = this.getEngine();\n        // Round up to a batch size so we don't have to reallocate as often\n        const maxLights = batches * this._batchSize;\n\n        this._lightDataBuffer = new Float32Array(20 * maxLights);\n        this._lightDataTexture?.dispose();\n        this._lightDataTexture = new RawTexture(\n            this._lightDataBuffer,\n            5,\n            maxLights,\n            Constants.TEXTUREFORMAT_RGBA,\n            this._scene,\n            false,\n            false,\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n            Constants.TEXTURETYPE_FLOAT\n        );\n        this._lightDataTexture.name = \"LightDataTexture_clustered_\" + this.name;\n        this._proxyMaterial.setTexture(\"lightDataTexture\", this._lightDataTexture);\n\n        this._tileMaskTexture?.dispose();\n        const textureSize = { width: this._horizontalTiles, height: this._verticalTiles };\n        if (!engine.isWebGPU) {\n            // In WebGL we shift the light proxy by the batch number\n            textureSize.height *= batches;\n        }\n        this._tileMaskTexture = new RenderTargetTexture(\"TileMaskTexture\", textureSize, this._scene, {\n            // We don't write anything on WebGPU so make it as small as possible\n            type: engine.isWebGPU ? Constants.TEXTURETYPE_UNSIGNED_BYTE : Constants.TEXTURETYPE_FLOAT,\n            format: Constants.TEXTUREFORMAT_RED,\n            generateDepthBuffer: false,\n        });\n\n        this._tileMaskTexture.renderParticles = false;\n        this._tileMaskTexture.renderSprites = false;\n        this._tileMaskTexture.noPrePassRenderer = true;\n        this._tileMaskTexture.renderList = [this._proxyMesh];\n\n        let currentRenderTarget: Nullable<RenderTargetWrapper> = null;\n\n        this._tileMaskTexture.onBeforeBindObservable.add(() => {\n            currentRenderTarget = engine._currentRenderTarget;\n            this._updateLightData();\n            // On WebGPU, clear the storage buffer here (before bindFramebuffer) because\n            // clearBuffer is a command encoder operation that cannot run while a render pass is open.\n            // In snapshot rendering mode, bindFramebuffer eagerly creates the render pass, so\n            // clearing must happen before that point.\n            if (engine.isWebGPU) {\n                this._tileMaskBuffer?.clear();\n            }\n        });\n\n        this._tileMaskTexture.onAfterUnbindObservable.add(() => {\n            if (engine._currentRenderTarget !== currentRenderTarget) {\n                if (!currentRenderTarget) {\n                    engine.restoreDefaultFramebuffer();\n                } else {\n                    engine.bindFramebuffer(currentRenderTarget);\n                }\n            }\n        });\n\n        this._tileMaskTexture.onClearObservable.add(() => {\n            if (!engine.isWebGPU) {\n                // Only clear the texture on WebGL\n                engine.clear({ r: 0, g: 0, b: 0, a: 1 }, true, false);\n            }\n        });\n\n        if (engine.isWebGPU) {\n            // WebGPU also needs a storage buffer to write to\n            this._tileMaskBuffer?.dispose();\n            const bufferSize = this._horizontalTiles * this._verticalTiles * batches * 4;\n            this._tileMaskBuffer = new StorageBuffer(<WebGPUEngine>engine, bufferSize);\n            this._proxyMaterial.setStorageBuffer(\"tileMaskBuffer\", this._tileMaskBuffer);\n        }\n\n        this._proxyMaterial.setVector3(\"tileMaskResolution\", new Vector3(this._horizontalTiles, this.verticalTiles, batches));\n\n        // We don't actually use the matrix data but we need enough capacity for the lights\n        if (this._proxyMesh.thinInstanceSetBuffer) {\n            this._proxyMesh.thinInstanceSetBuffer(\"matrix\", new Float32Array(maxLights * 16));\n        }\n        this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n        this._tileMaskBatches = batches;\n        return this._tileMaskTexture;\n    }\n\n    private _getSliceIndex(camera: Camera, depth: number): number {\n        if (depth < camera.minZ) {\n            // Prevent calling log on small or negative values\n            return -1;\n        }\n        return Math.floor(Math.log(depth) * this._sliceScale + this._sliceBias);\n    }\n\n    private _updateLightData(): void {\n        const camera = this._camera || this._scene.activeCamera;\n        const renderId = this._scene.getRenderId();\n        if (!camera || this._lightDataRenderId === renderId) {\n            return;\n        }\n        this._lightDataRenderId = renderId;\n\n        // Resort lights based on distance from camera\n        const view = camera.getViewMatrix();\n        for (const light of this._sortedLights) {\n            const position = light.computeTransformedInformation() ? light.transformedPosition : light.position;\n            const viewPosition = Vector3.TransformCoordinatesToRef(position, view, TmpVectors.Vector3[0]);\n            light._currentViewDepth = this._scene.useRightHandedSystem ? -viewPosition.z : viewPosition.z;\n        }\n        this._sortedLights.sort((a, b) => a._currentViewDepth - b._currentViewDepth);\n\n        // DOOM 2016 subdivision scheme, copied from: https://www.aortiz.me/2018/12/21/CG.html\n        const logFarNear = Math.log(camera.maxZ / camera.minZ);\n        this._sliceScale = this._depthSlices / logFarNear;\n        this._sliceBias = -(this._depthSlices * Math.log(camera.minZ)) / logFarNear;\n\n        this._sliceRanges.fill(0);\n        // Last slice which had had its min index updated\n        let minSlice = -1;\n\n        const buf = this._lightDataBuffer;\n        const offset = this._scene.floatingOriginOffset;\n\n        for (let i = 0; i < this._sortedLights.length; i += 1) {\n            const light = this._sortedLights[i];\n            const off = i * 20;\n            const computed = light.computeTransformedInformation();\n            const scaledIntensity = light.getScaledIntensity();\n\n            const position = computed ? light.transformedPosition : light.position;\n            const diffuse = light.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);\n            const specular = light.specular.scaleToRef(scaledIntensity, TmpColors.Color3[1]);\n            const range = Math.min(light.range, this.maxRange);\n            const inverseSquaredRange = Math.max(light._inverseSquaredRange, this._minInverseSquaredRange);\n\n            // vLightData\n            buf[off + 0] = position.x - offset.x;\n            buf[off + 1] = position.y - offset.y;\n            buf[off + 2] = position.z - offset.z;\n            buf[off + 3] = 0;\n            // vLightDiffuse\n            buf[off + 4] = diffuse.r;\n            buf[off + 5] = diffuse.g;\n            buf[off + 6] = diffuse.b;\n            buf[off + 7] = range;\n            // vLightSpecular\n            buf[off + 8] = specular.r;\n            buf[off + 9] = specular.g;\n            buf[off + 10] = specular.b;\n            buf[off + 11] = light.radius;\n            // vLightDirection\n            buf[off + 12] = 0;\n            buf[off + 13] = 0;\n            buf[off + 14] = 0;\n            buf[off + 15] = -1;\n            // vLightFalloff\n            buf[off + 16] = range;\n            buf[off + 17] = inverseSquaredRange;\n            buf[off + 18] = 0;\n            buf[off + 19] = 0;\n\n            if (light.getTypeID() === LightConstants.LIGHTTYPEID_SPOTLIGHT) {\n                const spotLight = <SpotLight>light;\n                const direction = Vector3.NormalizeToRef(computed ? spotLight.transformedDirection : spotLight.direction, TmpVectors.Vector3[0]);\n\n                // vLightData.a\n                buf[off + 3] = spotLight.exponent;\n                // vLightDirection\n                buf[off + 12] = direction.x;\n                buf[off + 13] = direction.y;\n                buf[off + 14] = direction.z;\n                buf[off + 15] = spotLight._cosHalfAngle;\n                // vLightFalloff.zw\n                buf[off + 18] = spotLight._lightAngleScale;\n                buf[off + 19] = spotLight._lightAngleOffset;\n            }\n\n            // Update the depth slices that include this light\n            const firstSlice = this._getSliceIndex(camera, light._currentViewDepth - range);\n            const lastSlice = this._getSliceIndex(camera, light._currentViewDepth + range);\n            for (let j = firstSlice; j <= lastSlice; j += 1) {\n                if (j < 0 || j >= this._depthSlices) {\n                    continue;\n                } else if (j > minSlice) {\n                    // Update min index\n                    this._sliceRanges[j * 2] = i;\n                    minSlice = j;\n                }\n                // Update max index\n                this._sliceRanges[j * 2 + 1] = i;\n            }\n        }\n\n        const engine = this.getEngine();\n        if (engine.isWebGPU) {\n            // Whenever the light data changes we have to flush pending WebGPU command buffers so that\n            // previous render passes use the old data and later render passes use the new data.\n            engine.flushFramebuffer();\n        }\n        this._lightDataTexture.update(this._lightDataBuffer);\n\n        // Refresh camera-dependent UBO fields when running under FAST snapshot rendering, where\n        // ObjectRenderer.render bypasses the rendering manager and Light._bindLight is not\n        // re-invoked each frame. Without this, transferToEffect would never run again after the\n        // recording frame and the slice data would stay frozen, producing visibly stale lighting\n        // as the camera moves. STANDARD snapshot mode and non-snapshot rendering still go through\n        // material binding each frame, so transferToEffect already keeps the UBO up to date.\n        if (this._lastBoundLightIndex !== null && engine.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\n            this._uniformBuffer.updateFloat2(\"vSliceData\", this._sliceScale, this._sliceBias, this._lastBoundLightIndex);\n            this._uniformBuffer.updateFloatArray(\"vSliceRanges\", this._sliceRanges, this._lastBoundLightIndex);\n            this._uniformBuffer.update();\n        }\n    }\n\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures?: boolean): void {\n        for (const light of this._lights) {\n            light.dispose(doNotRecurse, disposeMaterialAndTextures);\n        }\n        this._lightDataTexture.dispose();\n        this._tileMaskTexture.dispose();\n        this._tileMaskBuffer?.dispose();\n        this._proxyMesh.dispose(doNotRecurse, disposeMaterialAndTextures);\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\n    }\n\n    /**\n     * Adds a light to the clustering system.\n     * @param light The light to add\n     */\n    public addLight(light: Light): void {\n        if (!ClusteredLightContainer.IsLightSupported(light)) {\n            Logger.Warn(\"Attempting to add a light to cluster that does not support clustering\");\n            return;\n        }\n        if (light._clusteredContainer) {\n            Logger.Warn(\"Attempting to add a light to a cluster that is already owned by a clustered light container\");\n            return;\n        }\n        light._clusteredContainer = this;\n        // scene.removeLight returns -1 if the light wasn't in scene.lights. In that case the\n        // mesh.lightSources cleanup it normally performs didn't happen — but the light may still be\n        // there: lights constructed with `dontAddToScene = true` are pushed into mesh.lightSources\n        // by the Light constructor (the `includedOnlyMeshes` setter calls `_resyncMeshes`).\n        // Without explicit cleanup, the orphan would be picked up by PrepareDefinesForLights and\n        // rendered as a regular point/spot light, bypassing the cluster (notably ignoring `maxRange`).\n        if (this._scene.removeLight(light) === -1) {\n            for (const mesh of this._scene.meshes) {\n                mesh._removeLightSource(light, false);\n            }\n        }\n        this._lights.push(light);\n        this._sortedLights.push(<PointLight | SpotLight>light);\n\n        this._proxyMesh.isVisible = true;\n        this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n    }\n\n    /**\n     * Removes a light from the clustering system.\n     * @param light The light to remove\n     * @returns the index where the light was in the light list\n     */\n    public removeLight(light: Light): number {\n        // Convert to `Light` array without cast so `indexOf` has correct typing\n        const sortedLights: Light[] = this._sortedLights;\n        const sortedIndex = sortedLights.indexOf(light);\n        if (sortedIndex !== -1) {\n            sortedLights.splice(sortedIndex, 1);\n\n            this._proxyMesh.thinInstanceCount = sortedLights.length;\n            if (sortedLights.length === 0) {\n                this._proxyMesh.isVisible = false;\n            }\n        }\n\n        const index = this._lights.indexOf(light);\n        if (index !== -1) {\n            this._lights.splice(index, 1);\n            // We treat the unsorted array as the \"real\" one so only add back to the scene if it was found in that\n            if (light._clusteredContainer === this) {\n                light._clusteredContainer = null;\n            }\n            this._scene.addLight(light);\n        }\n        return index;\n    }\n\n    protected override _buildUniformLayout(): void {\n        this._uniformBuffer.addUniform(\"vLightData\", 4);\n        this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\n        this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\n        this._uniformBuffer.addUniform(\"vSliceData\", 2);\n        // _depthSlices might not be initialized yet\n        this._uniformBuffer.addUniform(\"vSliceRanges\", 2, this._depthSlices ?? DefaultDepthSlices);\n        this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\n        this._uniformBuffer.addUniform(\"depthValues\", 2);\n        this._uniformBuffer.create();\n    }\n\n    public override transferToEffect(effect: Effect, lightIndex: string): Light {\n        const engine = this.getEngine();\n        const hscale = this._horizontalTiles / engine.getRenderWidth();\n        const vscale = this._verticalTiles / engine.getRenderHeight();\n        this._uniformBuffer.updateFloat4(\"vLightData\", hscale, vscale, this._verticalTiles, this._tileMaskBatches, lightIndex);\n        this._uniformBuffer.updateFloat2(\"vSliceData\", this._sliceScale, this._sliceBias, lightIndex);\n        this._uniformBuffer.updateFloatArray(\"vSliceRanges\", this._sliceRanges, lightIndex);\n        this._lastBoundLightIndex = lightIndex;\n        return this;\n    }\n\n    public override transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\n        const engine = this.getEngine();\n        effect.setTexture(\"lightDataTexture\" + lightIndex, this._lightDataTexture);\n        if (engine.isWebGPU) {\n            (<WebGPUEngine>engine).setStorageBuffer(\"tileMaskBuffer\" + lightIndex, this._tileMaskBuffer);\n        } else {\n            effect.setTexture(\"tileMaskTexture\" + lightIndex, this._tileMaskTexture);\n        }\n        return this;\n    }\n\n    /**\n     * Transfers the effect to the node material effect\n     * @param _effect the effect to transfer to\n     * @returns the light\n     */\n    public override transferToNodeMaterialEffect(_effect: Effect): Light {\n        return this;\n    }\n\n    public override prepareLightSpecificDefines(defines: any, lightIndex: number): void {\n        defines[\"CLUSTLIGHT\" + lightIndex] = true;\n        defines[\"CLUSTLIGHT_BATCH\"] = this._batchSize;\n        defines[\"CLUSTLIGHT_SLICES\"] = this._depthSlices;\n    }\n\n    /**\n     * Returns whether this light is ready to be used\n     * @returns true if the light is ready\n     */\n    public override _isReady(): boolean {\n        this._updateBatches();\n        return this._proxyMesh.isReady(true, true);\n    }\n\n    /**\n     * Serializes the ClusteredLightContainer to a JSON object, including all child lights.\n     * @returns the serialized object\n     */\n    public override serialize(): any {\n        const serializationObject = super.serialize();\n\n        // Serialize child lights inline so they round-trip with the container.\n        // Child lights are removed from scene.lights by addLight(), so the scene\n        // serializer would not reach them on its own.\n        serializationObject.clusteredLights = [];\n        for (const light of this._lights) {\n            if (!light.doNotSerialize) {\n                serializationObject.clusteredLights.push(light.serialize());\n            }\n        }\n\n        return serializationObject;\n    }\n\n    protected override _onParsed(parsedLight: any, scene: Scene, rootUrl: string = \"\"): void {\n        if (parsedLight.clusteredLights) {\n            // Parse child lights first, but defer addLight() until after the loader\n            // fixup passes (parent resolution, excluded/included mesh resolution)\n            // have run on scene.lights. addLight() removes lights from scene.lights,\n            // which would cause those fixups to miss the child lights.\n            const parsedChildLights: Light[] = [];\n            for (const parsedChildLight of parsedLight.clusteredLights) {\n                const childLight = Light.Parse(parsedChildLight, scene, rootUrl);\n                if (childLight) {\n                    parsedChildLights.push(childLight);\n                }\n            }\n\n            if (parsedChildLights.length > 0) {\n                scene.onDataLoadedObservable.addOnce(() => {\n                    for (const childLight of parsedChildLights) {\n                        this.addLight(childLight);\n                    }\n                });\n            }\n        }\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for clusteredLightContainer.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterClusteredLightContainer(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    Node.AddNodeConstructor(\"Light_Type_5\", (name, scene) => {\n        return () => new ClusteredLightContainer(name, [], scene);\n    });\n\n    // Register Class Name\n    RegisterClass(\"BABYLON.ClusteredLightContainer\", ClusteredLightContainer);\n}\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lightProxyPixelShader\";\nconst shader = `flat varying vec2 vLimits;flat varying highp uint vMask;void main(void) {if (gl_FragCoord.y<vLimits.x || gl_FragCoord.y>vLimits.y) {discard;}\ngl_FragColor=vec4(vMask,0,0,1);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lightProxyPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clusteredLightingFunctions\";\nconst shader = `struct ClusteredLight {vec4 vLightData;vec4 vLightDiffuse;vec4 vLightSpecular;vec4 vLightDirection;vec4 vLightFalloff;};\n#define inline\nClusteredLight getClusteredLight(sampler2D lightDataTexture,int index) {return ClusteredLight(\ntexelFetch(lightDataTexture,ivec2(0,index),0),\ntexelFetch(lightDataTexture,ivec2(1,index),0),\ntexelFetch(lightDataTexture,ivec2(2,index),0),\ntexelFetch(lightDataTexture,ivec2(3,index),0),\ntexelFetch(lightDataTexture,ivec2(4,index),0)\n);}\nint getClusteredSliceIndex(vec2 sliceData,float viewDepth) {return int(log(viewDepth)*sliceData.x+sliceData.y);}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clusteredLightingFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneVertexDeclaration } from \"./ShadersInclude/sceneVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { clusteredLightingFunctions } from \"./ShadersInclude/clusteredLightingFunctions\";\n\nconst name = \"lightProxyVertexShader\";\nconst shader = `attribute vec3 position;flat varying vec2 vLimits;flat varying highp uint vMask;\n#include<__decl__sceneVertex>\nuniform sampler2D lightDataTexture;uniform vec3 tileMaskResolution;\n#include<clusteredLightingFunctions>\nvoid main(void) {ClusteredLight light=getClusteredLight(lightDataTexture,gl_InstanceID);float range=light.vLightFalloff.x;vec4 viewPosition=view*vec4(light.vLightData.xyz,1);vec4 viewPositionSq=viewPosition*viewPosition;vec2 distSq=viewPositionSq.xy+viewPositionSq.z;vec2 sinSq=(range*range)/distSq;vec2 cosSq=max(1.0-sinSq,0.01);vec2 sinCos=position.xy*sqrt(sinSq*cosSq);\n#ifdef RIGHT_HANDED\nvec2 rotatedX=mat2(cosSq.x,sinCos.x,-sinCos.x,cosSq.x)*viewPosition.xz;vec2 rotatedY=mat2(cosSq.y,sinCos.y,-sinCos.y,cosSq.y)*viewPosition.yz;\n#else\nvec2 rotatedX=mat2(cosSq.x,-sinCos.x,sinCos.x,cosSq.x)*viewPosition.xz;vec2 rotatedY=mat2(cosSq.y,-sinCos.y,sinCos.y,cosSq.y)*viewPosition.yz;\n#endif\nvec4 projX=projection*vec4(rotatedX.x,0,rotatedX.y,1);vec4 projY=projection*vec4(0,rotatedY.x,rotatedY.y,1);vec2 projPosition=vec2(projX.x/max(projX.w,0.01),projY.y/max(projY.w,0.01));projPosition=mix(position.xy,projPosition,greaterThan(cosSq,vec2(0.01)));vec2 halfTileRes=tileMaskResolution.xy/2.0;vec2 tilePosition=(projPosition+1.0)*halfTileRes;tilePosition=mix(floor(tilePosition)-0.01,ceil(tilePosition)+0.01,greaterThan(position.xy,vec2(0)));float offset=float(gl_InstanceID/CLUSTLIGHT_BATCH)*tileMaskResolution.y;tilePosition.y=(tilePosition.y+offset)/tileMaskResolution.z;gl_Position=vec4(tilePosition/halfTileRes-1.0,0,1);vLimits=vec2(offset,offset+tileMaskResolution.y);vMask=1u<<(gl_InstanceID % CLUSTLIGHT_BATCH);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [sceneVertexDeclaration, sceneUboDeclaration, clusteredLightingFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const lightProxyVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lightProxyPixelShader\";\nconst shader = `flat varying vOffset: u32;flat varying vMask: u32;uniform tileMaskResolution: vec3f;var<storage,read_write> tileMaskBuffer: array<atomic<u32>>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let maskResolution=vec2u(uniforms.tileMaskResolution.yz);let tilePosition=vec2u(fragmentInputs.position.xy);let tileIndex=(tilePosition.x*maskResolution.x+tilePosition.y)*maskResolution.y+fragmentInputs.vOffset;atomicOr(&tileMaskBuffer[tileIndex],fragmentInputs.vMask);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lightProxyPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clusteredLightingFunctions\";\nconst shader = `struct ClusteredLight {vLightData: vec4f,\nvLightDiffuse: vec4f,\nvLightSpecular: vec4f,\nvLightDirection: vec4f,\nvLightFalloff: vec4f,}\nfn getClusteredLight(lightDataTexture: texture_2d<f32>,index: u32)->ClusteredLight {return ClusteredLight(\ntextureLoad(lightDataTexture,vec2u(0,index),0),\ntextureLoad(lightDataTexture,vec2u(1,index),0),\ntextureLoad(lightDataTexture,vec2u(2,index),0),\ntextureLoad(lightDataTexture,vec2u(3,index),0),\ntextureLoad(lightDataTexture,vec2u(4,index),0)\n);}\nfn getClusteredSliceIndex(sliceData: vec2f,viewDepth: f32)->i32 {return i32(log(viewDepth)*sliceData.x+sliceData.y);}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const clusteredLightingFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { clusteredLightingFunctionsWGSL } from \"./ShadersInclude/clusteredLightingFunctions\";\n\nconst name = \"lightProxyVertexShader\";\nconst shader = `attribute position: vec3f;flat varying vOffset: u32;flat varying vMask: u32;\n#include<sceneUboDeclaration>\nvar lightDataTexture: texture_2d<f32>;uniform tileMaskResolution: vec3f;uniform halfTileRes: vec2f;\n#include<clusteredLightingFunctions>\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {let light=getClusteredLight(lightDataTexture,vertexInputs.instanceIndex);let range=light.vLightFalloff.x;let viewPosition=scene.view*vec4f(light.vLightData.xyz,1);let viewPositionSq=viewPosition*viewPosition;let distSq=viewPositionSq.xy+viewPositionSq.z;let sinSq=(range*range)/distSq;let cosSq=max(1.0-sinSq,vec2f(0.01));let sinCos=vertexInputs.position.xy*sqrt(sinSq*cosSq);\n#ifdef RIGHT_HANDED\nlet rotatedX=mat2x2f(cosSq.x,sinCos.x,-sinCos.x,cosSq.x)*viewPosition.xz;let rotatedY=mat2x2f(cosSq.y,sinCos.y,-sinCos.y,cosSq.y)*viewPosition.yz;\n#else\nlet rotatedX=mat2x2f(cosSq.x,-sinCos.x,sinCos.x,cosSq.x)*viewPosition.xz;let rotatedY=mat2x2f(cosSq.y,-sinCos.y,sinCos.y,cosSq.y)*viewPosition.yz;\n#endif\nlet projX=scene.projection*vec4f(rotatedX.x,0,rotatedX.y,1);let projY=scene.projection*vec4f(0,rotatedY.x,rotatedY.y,1);var projPosition=vec2f(projX.x/max(projX.w,0.01),projY.y/max(projY.w,0.01));projPosition=select(vertexInputs.position.xy,projPosition,cosSq>vec2(0.01));let halfTileRes=uniforms.tileMaskResolution.xy/2.0;var tilePosition=(projPosition+1.0)*halfTileRes;tilePosition=select(floor(tilePosition)-0.01,ceil(tilePosition)+0.01,vertexInputs.position.xy>vec2f(0));vertexOutputs.position=vec4f(tilePosition/halfTileRes-1.0,0,1);vertexOutputs.vOffset=vertexInputs.instanceIndex/CLUSTLIGHT_BATCH;vertexOutputs.vMask=1u<<(vertexInputs.instanceIndex % CLUSTLIGHT_BATCH);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, clusteredLightingFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const lightProxyVertexShaderWGSL = { name, shader };\n","import { Lerp } from \"core/Maths/math.scalar.functions\";\r\n\r\ninterface IIESData {\r\n    version: string;\r\n    tilt?: {};\r\n    numberOfLights?: number;\r\n    lumensPerLamp?: number;\r\n    numberOfVerticalAngles: number;\r\n    numberOfHorizontalAngles: number;\r\n    horizontalAngles: number[];\r\n    verticalAngles: number[];\r\n    photometricType?: number;\r\n    unitsType?: number;\r\n    width?: number;\r\n    length?: number;\r\n    height?: number;\r\n    candelaValues: number[][];\r\n}\r\n\r\ninterface IDataPointer {\r\n    lines: string[];\r\n    index: number;\r\n}\r\n\r\nfunction LineToArray(line: string): number[] {\r\n    return line\r\n        .split(\" \")\r\n        .filter((x) => x !== \"\")\r\n        .map((x) => parseFloat(x));\r\n}\r\n\r\nfunction ReadArray(dataPointer: IDataPointer, count: number, targetArray: number[]) {\r\n    while (targetArray.length !== count) {\r\n        const line = LineToArray(dataPointer.lines[dataPointer.index++]);\r\n        targetArray.push(...line);\r\n    }\r\n}\r\n\r\nfunction InterpolateCandelaValues(data: IIESData, phi: number, theta: number): number {\r\n    let phiIndex = 0;\r\n    let thetaIndex = 0;\r\n    let startTheta = 0;\r\n    let endTheta = 0;\r\n    let startPhi = 0;\r\n    let endPhi = 0;\r\n\r\n    // Check if the angle is outside the range\r\n    for (let index = 0; index < data.numberOfHorizontalAngles - 1; index++) {\r\n        if (theta < data.horizontalAngles[index + 1] || index === data.numberOfHorizontalAngles - 2) {\r\n            thetaIndex = index;\r\n            startTheta = data.horizontalAngles[index];\r\n            endTheta = data.horizontalAngles[index + 1];\r\n\r\n            break;\r\n        }\r\n    }\r\n\r\n    for (let index = 0; index < data.numberOfVerticalAngles - 1; index++) {\r\n        if (phi < data.verticalAngles[index + 1] || index === data.numberOfVerticalAngles - 2) {\r\n            phiIndex = index;\r\n            startPhi = data.verticalAngles[index];\r\n            endPhi = data.verticalAngles[index + 1];\r\n\r\n            break;\r\n        }\r\n    }\r\n\r\n    const deltaTheta = endTheta - startTheta;\r\n    const deltaPhi = endPhi - startPhi;\r\n\r\n    if (deltaPhi === 0) {\r\n        return 0;\r\n    }\r\n\r\n    // Interpolate\r\n    const t1 = deltaTheta === 0 ? 0 : (theta - startTheta) / deltaTheta;\r\n    const t2 = (phi - startPhi) / deltaPhi;\r\n\r\n    const nextThetaIndex = deltaTheta === 0 ? thetaIndex : thetaIndex + 1;\r\n\r\n    const v1 = Lerp(data.candelaValues[thetaIndex][phiIndex], data.candelaValues[nextThetaIndex][phiIndex], t1);\r\n    const v2 = Lerp(data.candelaValues[thetaIndex][phiIndex + 1], data.candelaValues[nextThetaIndex][phiIndex + 1], t1);\r\n    const v = Lerp(v1, v2, t2);\r\n\r\n    return v;\r\n}\r\n/**\r\n * Interface for IES texture data.\r\n */\r\nexport interface IIESTextureData {\r\n    /** The width of the texture */\r\n    width: number;\r\n    /** The height of the texture */\r\n    height: number;\r\n    /** The data of the texture */\r\n    data: Float32Array;\r\n}\r\n\r\n/**\r\n * Generates IES data buffer from a string representing the IES data.\r\n * @param uint8Array defines the IES data\r\n * @returns the IES data buffer\r\n * @see https://ieslibrary.com/browse\r\n * @see https://playground.babylonjs.com/#UQGPDT#1\r\n */\r\nexport function LoadIESData(uint8Array: Uint8Array): IIESTextureData {\r\n    const decoder = new TextDecoder(\"utf-8\");\r\n    const source = decoder.decode(uint8Array);\r\n\r\n    // Read data\r\n    const dataPointer: IDataPointer = {\r\n        lines: source.split(\"\\n\"),\r\n        index: 0,\r\n    };\r\n    const data: IIESData = { version: dataPointer.lines[0], candelaValues: [], horizontalAngles: [], verticalAngles: [], numberOfHorizontalAngles: 0, numberOfVerticalAngles: 0 };\r\n\r\n    // Skip metadata\r\n    dataPointer.index = 1;\r\n    while (dataPointer.lines.length > 0 && !dataPointer.lines[dataPointer.index].includes(\"TILT=\")) {\r\n        dataPointer.index++;\r\n    }\r\n\r\n    // Process tilt data?\r\n    if (dataPointer.lines[dataPointer.index].includes(\"INCLUDE\")) {\r\n        // Not supported yet as I did not manage to find an example :)\r\n    }\r\n    dataPointer.index++;\r\n\r\n    // Header\r\n    const header = LineToArray(dataPointer.lines[dataPointer.index++]);\r\n    data.numberOfLights = header[0];\r\n    data.lumensPerLamp = header[1];\r\n    data.numberOfVerticalAngles = header[3];\r\n    data.numberOfHorizontalAngles = header[4];\r\n    data.photometricType = header[5]; // We ignore cylindrical type for now. Will add support later if needed\r\n    data.unitsType = header[6];\r\n    data.width = header[7];\r\n    data.length = header[8];\r\n    data.height = header[9];\r\n\r\n    // The candela multiplier and ballast factors are global scales that cancel when\r\n    // this relative profile is normalized. The second value below is a ballast-lamp\r\n    // factor only in LM-63-1986/1991, is reserved in 1995/2002, and is file-generation\r\n    // metadata in 2019, so none of this record affects the texture data.\r\n    dataPointer.index++;\r\n\r\n    // Prepare arrays\r\n    for (let index = 0; index < data.numberOfHorizontalAngles; index++) {\r\n        data.candelaValues[index] = [];\r\n    }\r\n\r\n    // Vertical angles\r\n    ReadArray(dataPointer, data.numberOfVerticalAngles, data.verticalAngles);\r\n\r\n    // Horizontal angles\r\n    ReadArray(dataPointer, data.numberOfHorizontalAngles, data.horizontalAngles);\r\n\r\n    // Candela values\r\n    for (let index = 0; index < data.numberOfHorizontalAngles; index++) {\r\n        ReadArray(dataPointer, data.numberOfVerticalAngles, data.candelaValues[index]);\r\n    }\r\n\r\n    // Find the maximum candela value\r\n    let maxCandela = -1;\r\n    for (let index = 0; index < data.numberOfHorizontalAngles; index++) {\r\n        for (let subIndex = 0; subIndex < data.numberOfVerticalAngles; subIndex++) {\r\n            maxCandela = Math.max(maxCandela, data.candelaValues[index][subIndex]);\r\n        }\r\n    }\r\n\r\n    // Normalize candela values\r\n    if (maxCandela > 0) {\r\n        for (let index = 0; index < data.numberOfHorizontalAngles; index++) {\r\n            for (let subIndex = 0; subIndex < data.numberOfVerticalAngles; subIndex++) {\r\n                data.candelaValues[index][subIndex] /= maxCandela;\r\n            }\r\n        }\r\n    }\r\n\r\n    // Create the cylindrical texture\r\n    const height = 180;\r\n    const width = height * 2;\r\n    const size = width * height;\r\n    const arrayBuffer = new Float32Array(width * height);\r\n\r\n    // Fill the texture\r\n    const startTheta = data.horizontalAngles[0];\r\n    const endTheta = data.horizontalAngles[data.numberOfHorizontalAngles - 1];\r\n    for (let index = 0; index < size; index++) {\r\n        let theta = index % width;\r\n        const phi = Math.floor(index / width);\r\n\r\n        // Symmetry\r\n        if (endTheta - startTheta !== 0 && (theta < startTheta || theta >= endTheta)) {\r\n            theta %= endTheta * 2;\r\n            if (theta > endTheta) {\r\n                theta = endTheta * 2 - theta;\r\n            }\r\n        }\r\n\r\n        arrayBuffer[phi + theta * height] = InterpolateCandelaValues(data, phi, theta);\r\n    }\r\n\r\n    // So far we only need the first half of the first row of the texture as we only support IES for spot light. We can add support for other types later.\r\n    return {\r\n        width: width / 2,\r\n        height: 1,\r\n        data: arrayBuffer,\r\n    };\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lightingVolumeComputeShader\";\nconst shader = `struct Params {invViewProjMatrix: mat4x4f,\ninvViewMatrix: mat4x4f,\nstartVertexIndex: u32,\nstep: f32,\ntesselation: u32,\northoMin: vec3f,\northoMax: vec3f,};@group(0) @binding(0) var shadowMap : texture_depth_2d;@group(0) @binding(1) var<uniform> params : Params;@group(0) @binding(2) var<storage,read_write> positions : array<f32>;@compute @workgroup_size(8,8,1)\nfn updateFarPlaneVertices(@builtin(global_invocation_id) global_id : vec3u) {let coord=global_id.xy;\n#ifdef KEEP_EDGES\nif (any(coord>=vec2u(params.tesselation)) || any(coord<=vec2u(0))) {\n#else\nif (any(coord>vec2u(params.tesselation))) {\n#endif\nreturn;}\nlet stepY=floor(params.step*f32(coord.y));let depthCoord=vec2u(u32(floor(f32(coord.x)*params.step)),u32(stepY));var depth=textureLoad(shadowMap,depthCoord,0);\n#ifdef MOVE_FAR_DEPTH_TO_NEAR\nif (depth==1.0) {depth=0.0;}\n#endif\nlet halfTesselation=f32(params.tesselation>>1);let ndc=vec4f((f32(coord.x)-halfTesselation)/halfTesselation,(f32(coord.y)-halfTesselation)/halfTesselation,depth,1.0);var worldCoords=params.invViewProjMatrix*ndc;let idx=params.startVertexIndex+(coord.y*(params.tesselation+1)+coord.x)*3;positions[idx]=worldCoords.x/worldCoords.w;positions[idx+1]=worldCoords.y/worldCoords.w;positions[idx+2]=worldCoords.z/worldCoords.w;}\n@compute @workgroup_size(32,1,1)\nfn updatePlaneVertices(@builtin(global_invocation_id) global_id : vec3u) {_=textureDimensions(shadowMap);let uindex=global_id.x;let index=f32(uindex);if (uindex>params.tesselation) {return;}\nlet step=(params.orthoMax.xy-params.orthoMin.xy)/vec2f(f32(params.tesselation));var vr=params.invViewMatrix*vec4f(params.orthoMax.x,params.orthoMin.y+step.y*index,params.orthoMin.z,1.0);vr=vr/vr.w;positions[uindex*3+0]=vr.x;positions[uindex*3+1]=vr.y;positions[uindex*3+2]=vr.z;var vl=params.invViewMatrix*vec4f(params.orthoMin.x,params.orthoMin.y+step.y*index,params.orthoMin.z,1.0);vl=vl/vl.w;positions[uindex*3+0+(params.tesselation+1)*3]=vl.x;positions[uindex*3+1+(params.tesselation+1)*3]=vl.y;positions[uindex*3+2+(params.tesselation+1)*3]=vl.z;var vb=params.invViewMatrix*vec4f(params.orthoMin.x+step.x*index,params.orthoMin.y,params.orthoMin.z,1.0);vb=vb/vb.w;positions[uindex*3+0+(params.tesselation+1)*6]=vb.x;positions[uindex*3+1+(params.tesselation+1)*6]=vb.y;positions[uindex*3+2+(params.tesselation+1)*6]=vb.z;var vt=params.invViewMatrix*vec4f(params.orthoMin.x+step.x*index,params.orthoMax.y,params.orthoMin.z,1.0);vt=vt/vt.w;positions[uindex*3+0+(params.tesselation+1)*9]=vt.x;positions[uindex*3+1+(params.tesselation+1)*9]=vt.y;positions[uindex*3+2+(params.tesselation+1)*9]=vt.z;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lightingVolumeComputeShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { RegisterAbstractEngineLoadingScreen } from \"../Engines/AbstractEngine/abstractEngine.loadingScreen.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\n\r\n/**\r\n * Interface used to present a loading screen while loading a scene\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\nexport interface ILoadingScreen {\r\n    /**\r\n     * Function called to display the loading screen\r\n     */\r\n    displayLoadingUI: () => void;\r\n    /**\r\n     * Function called to hide the loading screen\r\n     */\r\n    hideLoadingUI: () => void;\r\n    /**\r\n     * Gets or sets the color to use for the background\r\n     */\r\n    loadingUIBackgroundColor: string;\r\n    /**\r\n     * Gets or sets the text to display while loading\r\n     */\r\n    loadingUIText: string;\r\n}\r\n\r\n/**\r\n * Class used for the default loading screen\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\nexport class DefaultLoadingScreen implements ILoadingScreen {\r\n    private _engine: Nullable<AbstractEngine>;\r\n    private _resizeObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _isLoading: boolean;\r\n    /**\r\n     * Maps a loading `HTMLDivElement` to a tuple containing the associated `HTMLCanvasElement`\r\n     * and its `DOMRect` (or `null` if not yet available).\r\n     */\r\n    private _loadingDivToRenderingCanvasMap: Map<HTMLDivElement, [HTMLCanvasElement, DOMRect | null]> = new Map();\r\n    private _loadingTextDiv: Nullable<HTMLDivElement>;\r\n    private _style: Nullable<HTMLStyleElement>;\r\n\r\n    /** Gets or sets the logo url to use for the default loading screen */\r\n    public static DefaultLogoUrl = \"\";\r\n\r\n    /** Gets or sets the spinner url to use for the default loading screen */\r\n    public static DefaultSpinnerUrl = \"\";\r\n\r\n    /**\r\n     * Creates a new default loading screen\r\n     * @param _renderingCanvas defines the canvas used to render the scene\r\n     * @param _loadingText defines the default text to display\r\n     * @param _loadingDivBackgroundColor defines the default background color\r\n     */\r\n    constructor(\r\n        private _renderingCanvas: HTMLCanvasElement,\r\n        private _loadingText = \"\",\r\n        private _loadingDivBackgroundColor = \"black\"\r\n    ) {}\r\n\r\n    /**\r\n     * Function called to display the loading screen\r\n     */\r\n    public displayLoadingUI(): void {\r\n        if (this._isLoading) {\r\n            // Do not add a loading screen if it is already loading\r\n            return;\r\n        }\r\n\r\n        this._isLoading = true;\r\n        // get current engine by rendering canvas\r\n        this._engine = EngineStore.Instances.find((engine) => engine.getRenderingCanvas() === this._renderingCanvas) as AbstractEngine;\r\n\r\n        const loadingDiv = document.createElement(\"div\");\r\n\r\n        loadingDiv.id = \"babylonjsLoadingDiv\";\r\n        loadingDiv.style.opacity = \"0\";\r\n        loadingDiv.style.transition = \"opacity 1.5s ease\";\r\n        loadingDiv.style.pointerEvents = \"none\";\r\n        loadingDiv.style.display = \"grid\";\r\n        loadingDiv.style.gridTemplateRows = \"100%\";\r\n        loadingDiv.style.gridTemplateColumns = \"100%\";\r\n        loadingDiv.style.justifyItems = \"center\";\r\n        loadingDiv.style.alignItems = \"center\";\r\n\r\n        // Loading text\r\n        this._loadingTextDiv = document.createElement(\"div\");\r\n        this._loadingTextDiv.style.position = \"absolute\";\r\n        this._loadingTextDiv.style.left = \"0\";\r\n        this._loadingTextDiv.style.top = \"50%\";\r\n        this._loadingTextDiv.style.marginTop = \"80px\";\r\n        this._loadingTextDiv.style.width = \"100%\";\r\n        this._loadingTextDiv.style.height = \"20px\";\r\n        this._loadingTextDiv.style.fontFamily = \"Arial\";\r\n        this._loadingTextDiv.style.fontSize = \"14px\";\r\n        this._loadingTextDiv.style.color = \"white\";\r\n        this._loadingTextDiv.style.textAlign = \"center\";\r\n        this._loadingTextDiv.style.zIndex = \"1\";\r\n        this._loadingTextDiv.innerHTML = \"Loading\";\r\n\r\n        loadingDiv.appendChild(this._loadingTextDiv);\r\n\r\n        //set the predefined text\r\n        this._loadingTextDiv.innerHTML = this._loadingText;\r\n\r\n        // Generating keyframes\r\n        this._style = document.createElement(\"style\");\r\n        const keyFrames = `@-webkit-keyframes spin1 {\\\r\n                            0% { -webkit-transform: rotate(0deg);}\r\n                            100% { -webkit-transform: rotate(360deg);}\r\n                        }\\\r\n                        @keyframes spin1 {\\\r\n                            0% { transform: rotate(0deg);}\r\n                            100% { transform: rotate(360deg);}\r\n                        }`;\r\n        this._style.innerHTML = keyFrames;\r\n        document.getElementsByTagName(\"head\")[0].appendChild(this._style);\r\n\r\n        const svgSupport = !!window.SVGSVGElement;\r\n        // Loading img\r\n        const imgBack = new Image();\r\n        if (!DefaultLoadingScreen.DefaultLogoUrl) {\r\n            imgBack.src = !svgSupport\r\n                ? \"https://cdn.babylonjs.com/Assets/babylonLogo.png\"\r\n                : `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODAuMTcgMjA4LjA0Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6I2UwNjg0Yjt9LmNscy0ze2ZpbGw6I2JiNDY0Yjt9LmNscy00e2ZpbGw6I2UwZGVkODt9LmNscy01e2ZpbGw6I2Q1ZDJjYTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPkJhYnlsb25Mb2dvPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iUGFnZV9FbGVtZW50cyIgZGF0YS1uYW1lPSJQYWdlIEVsZW1lbnRzIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik05MC4wOSwwLDAsNTJWMTU2bDkwLjA5LDUyLDkwLjA4LTUyVjUyWiIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxODAuMTcgNTIuMDEgMTUxLjk3IDM1LjczIDEyNC44NSA1MS4zOSAxNTMuMDUgNjcuNjcgMTgwLjE3IDUyLjAxIi8+PHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjI3LjEyIDY3LjY3IDExNy4yMSAxNS42NiA5MC4wOCAwIDAgNTIuMDEgMjcuMTIgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iNjEuODkgMTIwLjMgOTAuMDggMTM2LjU4IDExOC4yOCAxMjAuMyA5MC4wOCAxMDQuMDIgNjEuODkgMTIwLjMiLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDE1My4wNSAxNDAuMzcgOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyAwIDUyLjAxIDAgMTU2LjAzIDkwLjA4IDIwOC4wNCAxODAuMTcgMTU2LjAzIDE4MC4xNyA1Mi4wMSAxNTMuMDUgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iOTAuMDggNzEuNDYgNjEuODkgODcuNzQgNjEuODkgMTIwLjMgOTAuMDggMTA0LjAyIDExOC4yOCAxMjAuMyAxMTguMjggODcuNzQgOTAuMDggNzEuNDYiLz48cG9seWdvbiBjbGFzcz0iY2xzLTQiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDExOC4yOCA4Ny43NCAxMTguMjggMTIwLjMgOTAuMDggMTM2LjU4IDkwLjA4IDE3Ni43MiAxNTMuMDUgMTQwLjM3IDE1My4wNSA2Ny42NyIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtNSIgcG9pbnRzPSIyNy4xMiA2Ny42NyA2MS44OSA4Ny43NCA2MS44OSAxMjAuMyA5MC4wOCAxMzYuNTggOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyIvPjwvZz48L2c+PC9zdmc+`;\r\n        } else {\r\n            imgBack.src = DefaultLoadingScreen.DefaultLogoUrl;\r\n        }\r\n\r\n        imgBack.style.width = \"150px\";\r\n        imgBack.style.gridColumn = \"1\";\r\n        imgBack.style.gridRow = \"1\";\r\n        imgBack.style.top = \"50%\";\r\n        imgBack.style.left = \"50%\";\r\n        imgBack.style.transform = \"translate(-50%, -50%)\";\r\n        imgBack.style.position = \"absolute\";\r\n\r\n        const imageSpinnerContainer = document.createElement(\"div\");\r\n        imageSpinnerContainer.style.width = \"300px\";\r\n        imageSpinnerContainer.style.gridColumn = \"1\";\r\n        imageSpinnerContainer.style.gridRow = \"1\";\r\n        imageSpinnerContainer.style.top = \"50%\";\r\n        imageSpinnerContainer.style.left = \"50%\";\r\n        imageSpinnerContainer.style.transform = \"translate(-50%, -50%)\";\r\n        imageSpinnerContainer.style.position = \"absolute\";\r\n\r\n        // Loading spinner\r\n        const imgSpinner = new Image();\r\n\r\n        if (!DefaultLoadingScreen.DefaultSpinnerUrl) {\r\n            imgSpinner.src = !svgSupport\r\n                ? \"https://cdn.babylonjs.com/Assets/loadingIcon.png\"\r\n                : `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOTIgMzkyIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2UwNjg0Yjt9LmNscy0ye2ZpbGw6bm9uZTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlNwaW5uZXJJY29uPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iU3Bpbm5lciI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDAuMjEsMTI2LjQzYzMuNy03LjMxLDcuNjctMTQuNDQsMTItMjEuMzJsMy4zNi01LjEsMy41Mi01YzEuMjMtMS42MywyLjQxLTMuMjksMy42NS00LjkxczIuNTMtMy4yMSwzLjgyLTQuNzlBMTg1LjIsMTg1LjIsMCwwLDEsODMuNCw2Ny40M2EyMDgsMjA4LDAsMCwxLDE5LTE1LjY2YzMuMzUtMi40MSw2Ljc0LTQuNzgsMTAuMjUtN3M3LjExLTQuMjgsMTAuNzUtNi4zMmM3LjI5LTQsMTQuNzMtOCwyMi41My0xMS40OSwzLjktMS43Miw3Ljg4LTMuMywxMi00LjY0YTEwNC4yMiwxMDQuMjIsMCwwLDEsMTIuNDQtMy4yMyw2Mi40NCw2Mi40NCwwLDAsMSwxMi43OC0xLjM5QTI1LjkyLDI1LjkyLDAsMCwxLDE5NiwyMS40NGE2LjU1LDYuNTUsMCwwLDEsMi4wNSw5LDYuNjYsNi42NiwwLDAsMS0xLjY0LDEuNzhsLS40MS4yOWEyMi4wNywyMi4wNywwLDAsMS01Ljc4LDMsMzAuNDIsMzAuNDIsMCwwLDEtNS42NywxLjYyLDM3LjgyLDM3LjgyLDAsMCwxLTUuNjkuNzFjLTEsMC0xLjkuMTgtMi44NS4yNmwtMi44NS4yNHEtNS43Mi41MS0xMS40OCwxLjFjLTMuODQuNC03LjcxLjgyLTExLjU4LDEuNGExMTIuMzQsMTEyLjM0LDAsMCwwLTIyLjk0LDUuNjFjLTMuNzIsMS4zNS03LjM0LDMtMTAuOTQsNC42NHMtNy4xNCwzLjUxLTEwLjYsNS41MUExNTEuNiwxNTEuNiwwLDAsMCw2OC41Niw4N0M2Ny4yMyw4OC40OCw2Niw5MCw2NC42NCw5MS41NnMtMi41MSwzLjE1LTMuNzUsNC43M2wtMy41NCw0LjljLTEuMTMsMS42Ni0yLjIzLDMuMzUtMy4zMyw1YTEyNywxMjcsMCwwLDAtMTAuOTMsMjEuNDksMS41OCwxLjU4LDAsMSwxLTMtMS4xNVM0MC4xOSwxMjYuNDcsNDAuMjEsMTI2LjQzWiIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzOTIiLz48L2c+PC9nPjwvc3ZnPg==`;\r\n        } else {\r\n            imgSpinner.src = DefaultLoadingScreen.DefaultSpinnerUrl;\r\n        }\r\n\r\n        imgSpinner.style.animation = \"spin1 0.75s infinite linear\";\r\n        imgSpinner.style.transformOrigin = \"50% 50%\";\r\n\r\n        if (!svgSupport) {\r\n            const logoSize = { w: 16, h: 18.5 };\r\n            const loadingSize = { w: 30, h: 30 };\r\n            // set styling correctly\r\n            imgBack.style.width = `${logoSize.w}vh`;\r\n            imgBack.style.height = `${logoSize.h}vh`;\r\n            imgBack.style.left = `calc(50% - ${logoSize.w / 2}vh)`;\r\n            imgBack.style.top = `calc(50% - ${logoSize.h / 2}vh)`;\r\n\r\n            imgSpinner.style.width = `${loadingSize.w}vh`;\r\n            imgSpinner.style.height = `${loadingSize.h}vh`;\r\n            imgSpinner.style.left = `calc(50% - ${loadingSize.w / 2}vh)`;\r\n            imgSpinner.style.top = `calc(50% - ${loadingSize.h / 2}vh)`;\r\n        }\r\n\r\n        imageSpinnerContainer.appendChild(imgSpinner);\r\n\r\n        loadingDiv.appendChild(imgBack);\r\n        loadingDiv.appendChild(imageSpinnerContainer);\r\n        loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;\r\n        loadingDiv.style.opacity = \"1\";\r\n\r\n        const canvases: Array<HTMLCanvasElement> = [];\r\n        const views = this._engine.views;\r\n        if (views?.length) {\r\n            for (const view of views) {\r\n                if (view.enabled) {\r\n                    canvases.push(view.target);\r\n                }\r\n            }\r\n        } else {\r\n            canvases.push(this._renderingCanvas);\r\n        }\r\n        for (let i = 0; i < canvases.length; i++) {\r\n            const canvas = canvases[i];\r\n            const clonedLoadingDiv = loadingDiv.cloneNode(true) as HTMLDivElement;\r\n            clonedLoadingDiv.id += `-${i}`;\r\n            this._loadingDivToRenderingCanvasMap.set(clonedLoadingDiv, [canvas, null]);\r\n        }\r\n\r\n        this._resizeLoadingUI();\r\n\r\n        this._resizeObserver = this._engine.onResizeObservable.add(() => {\r\n            this._resizeLoadingUI();\r\n        });\r\n\r\n        this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n            document.body.appendChild(loadingDiv);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Function called to hide the loading screen\r\n     */\r\n    public hideLoadingUI(): void {\r\n        if (!this._isLoading) {\r\n            return;\r\n        }\r\n\r\n        let completedTransitions = 0;\r\n\r\n        const onTransitionEnd = (event: TransitionEvent) => {\r\n            const loadingDiv = event.target as HTMLDivElement;\r\n            // ensure that ending transition event is generated by one of the current loadingDivs\r\n            const isTransitionEndOnLoadingDiv = this._loadingDivToRenderingCanvasMap.has(loadingDiv);\r\n\r\n            if (isTransitionEndOnLoadingDiv) {\r\n                completedTransitions++;\r\n                loadingDiv.remove();\r\n\r\n                const allTransitionsCompleted = completedTransitions === this._loadingDivToRenderingCanvasMap.size;\r\n                if (allTransitionsCompleted) {\r\n                    if (this._loadingTextDiv) {\r\n                        this._loadingTextDiv.remove();\r\n                        this._loadingTextDiv = null;\r\n                    }\r\n                    if (this._style) {\r\n                        this._style.remove();\r\n                        this._style = null;\r\n                    }\r\n\r\n                    window.removeEventListener(\"transitionend\", onTransitionEnd);\r\n                    this._engine!.onResizeObservable.remove(this._resizeObserver);\r\n                    this._loadingDivToRenderingCanvasMap.clear();\r\n                    this._engine = null;\r\n                    this._isLoading = false;\r\n                }\r\n            }\r\n        };\r\n\r\n        this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n            loadingDiv.style.opacity = \"0\";\r\n        });\r\n\r\n        window.addEventListener(\"transitionend\", onTransitionEnd);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the text to display while loading\r\n     */\r\n    public set loadingUIText(text: string) {\r\n        this._loadingText = text;\r\n\r\n        if (this._loadingTextDiv) {\r\n            this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n                // set loadingTextDiv of current loadingDiv\r\n                loadingDiv.children[0].innerHTML = this._loadingText;\r\n            });\r\n        }\r\n    }\r\n\r\n    public get loadingUIText(): string {\r\n        return this._loadingText;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the color to use for the background\r\n     */\r\n    public get loadingUIBackgroundColor(): string {\r\n        return this._loadingDivBackgroundColor;\r\n    }\r\n\r\n    public set loadingUIBackgroundColor(color: string) {\r\n        this._loadingDivBackgroundColor = color;\r\n\r\n        if (!this._isLoading) {\r\n            return;\r\n        }\r\n\r\n        this._loadingDivToRenderingCanvasMap.forEach((_, loadingDiv) => {\r\n            loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Checks if the layout of the canvas has changed by comparing the current layout\r\n     * rectangle with the previous one.\r\n     *\r\n     * This function compares of the two `DOMRect` objects to determine if any of the layout dimensions have changed.\r\n     * If the layout has changed or if there is no previous layout (i.e., `previousCanvasRect` is `null`),\r\n     * it returns `true`. Otherwise, it returns `false`.\r\n     *\r\n     * @param previousCanvasRect defines the previously recorded `DOMRect` of the canvas, or `null` if no previous state exists.\r\n     * @param currentCanvasRect defines the current `DOMRect` of the canvas to compare against the previous layout.\r\n     * @returns `true` if the layout has changed, otherwise `false`.\r\n     */\r\n    private _isCanvasLayoutChanged(previousCanvasRect: DOMRect | null, currentCanvasRect: DOMRect) {\r\n        return (\r\n            !previousCanvasRect ||\r\n            previousCanvasRect.left !== currentCanvasRect.left ||\r\n            previousCanvasRect.top !== currentCanvasRect.top ||\r\n            previousCanvasRect.right !== currentCanvasRect.right ||\r\n            previousCanvasRect.bottom !== currentCanvasRect.bottom ||\r\n            previousCanvasRect.width !== currentCanvasRect.width ||\r\n            previousCanvasRect.height !== currentCanvasRect.height ||\r\n            previousCanvasRect.x !== currentCanvasRect.x ||\r\n            previousCanvasRect.y !== currentCanvasRect.y\r\n        );\r\n    }\r\n\r\n    // Resize\r\n    private _resizeLoadingUI = () => {\r\n        if (!this._isLoading) {\r\n            return;\r\n        }\r\n\r\n        this._loadingDivToRenderingCanvasMap.forEach(([canvas, previousCanvasRect], loadingDiv) => {\r\n            const currentCanvasRect = canvas.getBoundingClientRect();\r\n            if (this._isCanvasLayoutChanged(previousCanvasRect, currentCanvasRect)) {\r\n                const canvasPositioning = window.getComputedStyle(canvas).position;\r\n\r\n                loadingDiv.style.position = canvasPositioning === \"fixed\" ? \"fixed\" : \"absolute\";\r\n                loadingDiv.style.left = currentCanvasRect.left + window.scrollX + \"px\";\r\n                loadingDiv.style.top = currentCanvasRect.top + window.scrollY + \"px\";\r\n                loadingDiv.style.width = currentCanvasRect.width + \"px\";\r\n                loadingDiv.style.height = currentCanvasRect.height + \"px\";\r\n\r\n                this._loadingDivToRenderingCanvasMap.set(loadingDiv, [canvas, currentCanvasRect]);\r\n            }\r\n        });\r\n    };\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for loadingScreen.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLoadingScreen(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterAbstractEngineLoadingScreen();\r\n    AbstractEngine.DefaultLoadingScreenFactory = (canvas: HTMLCanvasElement) => {\r\n        return new DefaultLoadingScreen(canvas);\r\n    };\r\n}\r\n","import { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Clamp } from \"../../Maths/math.scalar.functions\";\r\nimport { SphericalPolynomial, SphericalHarmonics } from \"../../Maths/sphericalPolynomial\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type CubeMapInfo } from \"./panoramaToCubemap\";\r\nimport { ToLinearSpace } from \"../../Maths/math.constants\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\n\r\nclass FileFaceOrientation {\r\n    public name: string;\r\n    public worldAxisForNormal: Vector3; // the world axis corresponding to the normal to the face\r\n    public worldAxisForFileX: Vector3; // the world axis corresponding to texture right x-axis in file\r\n    public worldAxisForFileY: Vector3; // the world axis corresponding to texture down y-axis in file\r\n\r\n    public constructor(name: string, worldAxisForNormal: Vector3, worldAxisForFileX: Vector3, worldAxisForFileY: Vector3) {\r\n        this.name = name;\r\n        this.worldAxisForNormal = worldAxisForNormal;\r\n        this.worldAxisForFileX = worldAxisForFileX;\r\n        this.worldAxisForFileY = worldAxisForFileY;\r\n    }\r\n}\r\n\r\n/**\r\n * Helper class dealing with the extraction of spherical polynomial dataArray\r\n * from a cube map.\r\n */\r\nexport class CubeMapToSphericalPolynomialTools {\r\n    private static _FileFaces: FileFaceOrientation[] = [\r\n        new FileFaceOrientation(\"right\", new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(0, -1, 0)), // +X east\r\n        new FileFaceOrientation(\"left\", new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, -1, 0)), // -X west\r\n        new FileFaceOrientation(\"up\", new Vector3(0, 1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1)), // +Y north\r\n        new FileFaceOrientation(\"down\", new Vector3(0, -1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, -1)), // -Y south\r\n        new FileFaceOrientation(\"front\", new Vector3(0, 0, 1), new Vector3(1, 0, 0), new Vector3(0, -1, 0)), // +Z top\r\n        new FileFaceOrientation(\"back\", new Vector3(0, 0, -1), new Vector3(-1, 0, 0), new Vector3(0, -1, 0)), // -Z bottom\r\n    ];\r\n\r\n    /** @internal */\r\n    public static MAX_HDRI_VALUE = 4096;\r\n    /** @internal */\r\n    public static PRESERVE_CLAMPED_COLORS = false;\r\n\r\n    /**\r\n     * Clamp a value to the nearest power of two (rounding down).\r\n     * @param value The value to clamp\r\n     * @returns The nearest power of two less than or equal to value\r\n     */\r\n    private static _NearestPow2Floor(value: number): number {\r\n        // Ensure minimum of 1\r\n        if (value <= 1) {\r\n            return 1;\r\n        }\r\n        return 1 << Math.floor(Math.log2(value));\r\n    }\r\n\r\n    /**\r\n     * Converts a texture to the according Spherical Polynomial data.\r\n     * This extracts the first 3 orders only as they are the only one used in the lighting.\r\n     *\r\n     * @param texture The texture to extract the information from.\r\n     * @returns The Spherical Polynomial data.\r\n     */\r\n    public static ConvertCubeMapTextureToSphericalPolynomial(texture: BaseTexture): Nullable<Promise<SphericalPolynomial>> {\r\n        if (!texture.isCube) {\r\n            // Only supports cube Textures currently.\r\n            return null;\r\n        }\r\n\r\n        texture.getScene()?.getEngine().flushFramebuffer();\r\n\r\n        const size = texture.getSize().width;\r\n        const rawTargetSize = texture._sphericalPolynomialTargetSize;\r\n        const targetSize = rawTargetSize > 0 ? this._NearestPow2Floor(rawTargetSize) : 0;\r\n        const hasMipmaps = !texture.noMipmap && texture._texture?.generateMipMaps === true;\r\n        const useMip = targetSize > 0 && targetSize < size && hasMipmaps;\r\n        const mipLevel = useMip ? Math.max(0, Math.round(Math.log2(size / targetSize))) : 0;\r\n        const mipSize = useMip ? Math.max(1, Math.floor(size / Math.pow(2, mipLevel))) : size;\r\n\r\n        const rightPromise = texture.readPixels(0, mipLevel, undefined, false);\r\n        const leftPromise = texture.readPixels(1, mipLevel, undefined, false);\r\n\r\n        let upPromise: Nullable<Promise<ArrayBufferView>>;\r\n        let downPromise: Nullable<Promise<ArrayBufferView>>;\r\n        if (texture.isRenderTarget) {\r\n            upPromise = texture.readPixels(3, mipLevel, undefined, false);\r\n            downPromise = texture.readPixels(2, mipLevel, undefined, false);\r\n        } else {\r\n            upPromise = texture.readPixels(2, mipLevel, undefined, false);\r\n            downPromise = texture.readPixels(3, mipLevel, undefined, false);\r\n        }\r\n\r\n        const frontPromise = texture.readPixels(4, mipLevel, undefined, false);\r\n        const backPromise = texture.readPixels(5, mipLevel, undefined, false);\r\n\r\n        const gammaSpace = texture.gammaSpace;\r\n        // Always read as RGBA.\r\n        const format = Constants.TEXTUREFORMAT_RGBA;\r\n        const needsCpuDownsample = targetSize > 0 && targetSize < size && !useMip;\r\n\r\n        return new Promise((resolve) => {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            Promise.all([leftPromise, rightPromise, upPromise, downPromise, frontPromise, backPromise]).then(([left, right, up, down, front, back]) => {\r\n                let effectiveSize = mipSize;\r\n                if (needsCpuDownsample) {\r\n                    const stride = 4; // RGBA\r\n                    left = this._DownsampleFace(left!, size, targetSize, stride);\r\n                    right = this._DownsampleFace(right!, size, targetSize, stride);\r\n                    up = this._DownsampleFace(up!, size, targetSize, stride);\r\n                    down = this._DownsampleFace(down!, size, targetSize, stride);\r\n                    front = this._DownsampleFace(front!, size, targetSize, stride);\r\n                    back = this._DownsampleFace(back!, size, targetSize, stride);\r\n                    effectiveSize = targetSize;\r\n                }\r\n\r\n                const cubeInfo: CubeMapInfo = {\r\n                    size: effectiveSize,\r\n                    right,\r\n                    left,\r\n                    up,\r\n                    down,\r\n                    front,\r\n                    back,\r\n                    format,\r\n                    type: left instanceof Float32Array ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                    gammaSpace,\r\n                };\r\n\r\n                resolve(this.ConvertCubeMapToSphericalPolynomial(cubeInfo));\r\n            });\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Compute the area on the unit sphere of the rectangle defined by (x,y) and the origin\r\n     * See https://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/\r\n     * @param x\r\n     * @param y\r\n     * @returns the area\r\n     */\r\n    private static _AreaElement(x: number, y: number): number {\r\n        return Math.atan2(x * y, Math.sqrt(x * x + y * y + 1));\r\n    }\r\n\r\n    /**\r\n     * Box-filter downsample a single cubemap face.\r\n     * @param data Source face data\r\n     * @param srcSize Source face width/height\r\n     * @param dstSize Target face width/height\r\n     * @param stride Number of components per pixel\r\n     * @returns Downsampled face data\r\n     */\r\n    private static _DownsampleFace(data: ArrayBufferView, srcSize: number, dstSize: number, stride: number): ArrayBufferView {\r\n        // Build a Float32Array view over the source for uniform accumulation.\r\n        // Float32Array: use directly. Any integer typed array: convert element values.\r\n        const src = data instanceof Float32Array ? data : Float32Array.from(data as Uint8Array);\r\n        const dstLength = dstSize * dstSize * stride;\r\n        const avg = new Float32Array(dstLength);\r\n        const blockSize = srcSize / dstSize;\r\n        const invArea = 1.0 / (blockSize * blockSize);\r\n\r\n        for (let dy = 0; dy < dstSize; dy++) {\r\n            const sy0 = Math.floor(dy * blockSize);\r\n            const sy1 = Math.floor((dy + 1) * blockSize);\r\n            for (let dx = 0; dx < dstSize; dx++) {\r\n                const sx0 = Math.floor(dx * blockSize);\r\n                const sx1 = Math.floor((dx + 1) * blockSize);\r\n                const dstIdx = (dy * dstSize + dx) * stride;\r\n                for (let c = 0; c < stride; c++) {\r\n                    let sum = 0;\r\n                    for (let sy = sy0; sy < sy1; sy++) {\r\n                        for (let sx = sx0; sx < sx1; sx++) {\r\n                            sum += src[(sy * srcSize + sx) * stride + c];\r\n                        }\r\n                    }\r\n                    avg[dstIdx + c] = sum * invArea;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Return the same typed-array kind as the input so downstream type\r\n        // detection (Float32Array vs UNSIGNED_BYTE) keeps working.\r\n        if (data instanceof Float32Array) {\r\n            return avg;\r\n        }\r\n        // Integer path: round back into the original array type.\r\n        const ctor = (data as any).constructor as { new (length: number): ArrayBufferView };\r\n        const dst = new ctor(dstLength);\r\n        for (let i = 0; i < dstLength; i++) {\r\n            (dst as any)[i] = (avg[i] + 0.5) | 0;\r\n        }\r\n        return dst;\r\n    }\r\n\r\n    /**\r\n     * Converts a cubemap to the according Spherical Polynomial data.\r\n     * This extracts the first 3 orders only as they are the only one used in the lighting.\r\n     *\r\n     * @param cubeInfo The Cube map to extract the information from.\r\n     * @param targetSize Optional target face size for downsampling before integration. 0 = no downsampling (default).\r\n     * @returns The Spherical Polynomial data.\r\n     */\r\n    public static ConvertCubeMapToSphericalPolynomial(cubeInfo: CubeMapInfo, targetSize = 0): SphericalPolynomial {\r\n        // Clamp target to power of two and downsample faces if requested\r\n        const effectiveTarget = targetSize > 0 ? this._NearestPow2Floor(targetSize) : 0;\r\n        if (effectiveTarget > 0 && cubeInfo.size > effectiveTarget) {\r\n            const stride = cubeInfo.format === Constants.TEXTUREFORMAT_RGBA ? 4 : 3;\r\n            const faces = [\"right\", \"left\", \"up\", \"down\", \"front\", \"back\"] as const;\r\n            const downsampled: Record<string, ArrayBufferView> = {};\r\n            for (const face of faces) {\r\n                downsampled[face] = this._DownsampleFace((<any>cubeInfo)[face], cubeInfo.size, effectiveTarget, stride);\r\n            }\r\n            cubeInfo = { ...cubeInfo, ...downsampled, size: effectiveTarget };\r\n        }\r\n\r\n        const sphericalHarmonics = new SphericalHarmonics();\r\n        let totalSolidAngle = 0.0;\r\n\r\n        // The (u,v) range is [-1,+1], so the distance between each texel is 2/Size.\r\n        const du = 2.0 / cubeInfo.size;\r\n        const dv = du;\r\n\r\n        const halfTexel = 0.5 * du;\r\n\r\n        // The (u,v) of the first texel is half a texel from the corner (-1,-1).\r\n        const minUV = halfTexel - 1.0;\r\n\r\n        for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\r\n            const fileFace = this._FileFaces[faceIndex];\r\n            const dataArray = (<any>cubeInfo)[fileFace.name];\r\n            let v = minUV;\r\n\r\n            // TODO: we could perform the summation directly into a SphericalPolynomial (SP), which is more efficient than SphericalHarmonic (SH).\r\n            // This is possible because during the summation we do not need the SH-specific properties, e.g. orthogonality.\r\n            // Because SP is still linear, so summation is fine in that basis.\r\n            const stride = cubeInfo.format === Constants.TEXTUREFORMAT_RGBA ? 4 : 3;\r\n            for (let y = 0; y < cubeInfo.size; y++) {\r\n                let u = minUV;\r\n\r\n                for (let x = 0; x < cubeInfo.size; x++) {\r\n                    // World direction (not normalised)\r\n                    const worldDirection = fileFace.worldAxisForFileX.scale(u).add(fileFace.worldAxisForFileY.scale(v)).add(fileFace.worldAxisForNormal);\r\n                    worldDirection.normalize();\r\n\r\n                    const deltaSolidAngle =\r\n                        this._AreaElement(u - halfTexel, v - halfTexel) -\r\n                        this._AreaElement(u - halfTexel, v + halfTexel) -\r\n                        this._AreaElement(u + halfTexel, v - halfTexel) +\r\n                        this._AreaElement(u + halfTexel, v + halfTexel);\r\n\r\n                    let r = dataArray[y * cubeInfo.size * stride + x * stride + 0];\r\n                    let g = dataArray[y * cubeInfo.size * stride + x * stride + 1];\r\n                    let b = dataArray[y * cubeInfo.size * stride + x * stride + 2];\r\n\r\n                    // Prevent NaN harmonics with extreme HDRI data.\r\n                    if (isNaN(r)) {\r\n                        r = 0;\r\n                    }\r\n                    if (isNaN(g)) {\r\n                        g = 0;\r\n                    }\r\n                    if (isNaN(b)) {\r\n                        b = 0;\r\n                    }\r\n\r\n                    // Handle Integer types.\r\n                    if (cubeInfo.type === Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n                        r /= 255;\r\n                        g /= 255;\r\n                        b /= 255;\r\n                    }\r\n\r\n                    // Handle Gamma space textures.\r\n                    if (cubeInfo.gammaSpace) {\r\n                        r = Math.pow(Clamp(r), ToLinearSpace);\r\n                        g = Math.pow(Clamp(g), ToLinearSpace);\r\n                        b = Math.pow(Clamp(b), ToLinearSpace);\r\n                    }\r\n\r\n                    // Prevent to explode in case of really high dynamic ranges.\r\n                    // sh 3 would not be enough to accurately represent it.\r\n                    const max = this.MAX_HDRI_VALUE;\r\n                    if (this.PRESERVE_CLAMPED_COLORS) {\r\n                        const currentMax = Math.max(r, g, b);\r\n                        if (currentMax > max) {\r\n                            const factor = max / currentMax;\r\n                            r *= factor;\r\n                            g *= factor;\r\n                            b *= factor;\r\n                        }\r\n                    } else {\r\n                        r = Clamp(r, 0, max);\r\n                        g = Clamp(g, 0, max);\r\n                        b = Clamp(b, 0, max);\r\n                    }\r\n\r\n                    const color = new Color3(r, g, b);\r\n\r\n                    sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);\r\n\r\n                    totalSolidAngle += deltaSolidAngle;\r\n\r\n                    u += du;\r\n                }\r\n\r\n                v += dv;\r\n            }\r\n        }\r\n\r\n        // Solid angle for entire sphere is 4*pi\r\n        const sphereSolidAngle = 4.0 * Math.PI;\r\n\r\n        // Adjust the solid angle to allow for how many faces we processed.\r\n        const facesProcessed = 6.0;\r\n        const expectedSolidAngle = (sphereSolidAngle * facesProcessed) / 6.0;\r\n\r\n        // Adjust the harmonics so that the accumulated solid angle matches the expected solid angle.\r\n        // This is needed because the numerical integration over the cube uses a\r\n        // small angle approximation of solid angle for each texel (see deltaSolidAngle),\r\n        // and also to compensate for accumulative error due to float precision in the summation.\r\n        const correctionFactor = expectedSolidAngle / totalSolidAngle;\r\n        sphericalHarmonics.scaleInPlace(correctionFactor);\r\n\r\n        sphericalHarmonics.convertIncidentRadianceToIrradiance();\r\n        sphericalHarmonics.convertIrradianceToLambertianRadiance();\r\n\r\n        return SphericalPolynomial.FromHarmonics(sphericalHarmonics);\r\n    }\r\n}\r\n","import { Vector3 } from \"../../../Maths/math\";\r\nimport { ILog2 } from \"../../../Maths/math.scalar.functions\";\r\nimport { type BaseTexture } from \"../baseTexture\";\r\nimport { type AbstractEngine } from \"../../../Engines/abstractEngine\";\r\nimport { type Effect } from \"../../../Materials/effect\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { EffectWrapper, EffectRenderer } from \"../../../Materials/effectRenderer.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type RenderTargetWrapper } from \"../../../Engines/renderTargetWrapper\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Options for texture filtering\r\n */\r\ninterface IHDRFilteringOptions {\r\n    /**\r\n     * Scales pixel intensity for the input HDR map.\r\n     */\r\n    hdrScale?: number;\r\n\r\n    /**\r\n     * Quality of the filter. Should be `Constants.TEXTURE_FILTERING_QUALITY_OFFLINE` for prefiltering\r\n     */\r\n    quality?: number;\r\n}\r\n\r\n/**\r\n * Filters HDR maps to get correct renderings of PBR reflections\r\n */\r\nexport class HDRFiltering {\r\n    private _engine: AbstractEngine;\r\n    private _effectRenderer: EffectRenderer;\r\n    private _effectWrapper: EffectWrapper;\r\n\r\n    private _lodGenerationOffset: number = 0;\r\n    private _lodGenerationScale: number = 0.8;\r\n\r\n    /**\r\n     * Quality switch for prefiltering. Should be set to `Constants.TEXTURE_FILTERING_QUALITY_OFFLINE` unless\r\n     * you care about baking speed.\r\n     */\r\n    public quality: number = Constants.TEXTURE_FILTERING_QUALITY_OFFLINE;\r\n\r\n    /**\r\n     * Scales pixel intensity for the input HDR map.\r\n     */\r\n    public hdrScale: number = 1;\r\n\r\n    /**\r\n     * Instantiates HDR filter for reflection maps\r\n     *\r\n     * @param engine Thin engine\r\n     * @param options Options\r\n     */\r\n    constructor(engine: AbstractEngine, options: IHDRFilteringOptions = {}) {\r\n        // pass\r\n        this._engine = engine;\r\n        this.hdrScale = options.hdrScale || this.hdrScale;\r\n        this.quality = options.quality || this.quality;\r\n    }\r\n\r\n    private _createRenderTarget(size: number): RenderTargetWrapper {\r\n        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (this._engine.getCaps().textureHalfFloatRender) {\r\n            textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        } else if (this._engine.getCaps().textureFloatRender) {\r\n            textureType = Constants.TEXTURETYPE_FLOAT;\r\n        }\r\n\r\n        const rtWrapper = this._engine.createRenderTargetCubeTexture(size, {\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            type: textureType,\r\n            createMipMaps: true,\r\n            generateMipMaps: false,\r\n            generateDepthBuffer: false,\r\n            generateStencilBuffer: false,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            label: \"HDR_Radiance_Filtering_Target\",\r\n        });\r\n        this._engine.updateTextureWrappingMode(rtWrapper.texture!, Constants.TEXTURE_CLAMP_ADDRESSMODE, Constants.TEXTURE_CLAMP_ADDRESSMODE, Constants.TEXTURE_CLAMP_ADDRESSMODE);\r\n\r\n        this._engine.updateTextureSamplingMode(Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, rtWrapper.texture!, true);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    private _prefilterInternal(texture: BaseTexture): BaseTexture {\r\n        const width = texture.getSize().width;\r\n        const mipmapsCount = ILog2(width) + 1;\r\n\r\n        const effect = this._effectWrapper.effect;\r\n        const outputTexture = this._createRenderTarget(width);\r\n        this._effectRenderer.saveStates();\r\n        this._effectRenderer.setViewport();\r\n\r\n        const intTexture = texture.getInternalTexture();\r\n        if (intTexture) {\r\n            // Just in case generate fresh clean mips.\r\n            this._engine.updateTextureSamplingMode(Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, intTexture, true);\r\n        }\r\n\r\n        this._effectRenderer.applyEffectWrapper(this._effectWrapper);\r\n\r\n        const directions = [\r\n            [new Vector3(0, 0, -1), new Vector3(0, -1, 0), new Vector3(1, 0, 0)], // PositiveX\r\n            [new Vector3(0, 0, 1), new Vector3(0, -1, 0), new Vector3(-1, 0, 0)], // NegativeX\r\n            [new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0)], // PositiveY\r\n            [new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(0, -1, 0)], // NegativeY\r\n            [new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 0, 1)], // PositiveZ\r\n            [new Vector3(-1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 0, -1)], // NegativeZ\r\n        ];\r\n\r\n        effect.setFloat(\"hdrScale\", this.hdrScale);\r\n        effect.setFloat2(\"vFilteringInfo\", texture.getSize().width, mipmapsCount);\r\n        effect.setTexture(\"inputTexture\", texture);\r\n\r\n        for (let face = 0; face < 6; face++) {\r\n            effect.setVector3(\"up\", directions[face][0]);\r\n            effect.setVector3(\"right\", directions[face][1]);\r\n            effect.setVector3(\"front\", directions[face][2]);\r\n\r\n            for (let lod = 0; lod < mipmapsCount; lod++) {\r\n                this._engine.bindFramebuffer(outputTexture, face, undefined, undefined, true, lod);\r\n                this._effectRenderer.applyEffectWrapper(this._effectWrapper);\r\n\r\n                let alpha = Math.pow(2, (lod - this._lodGenerationOffset) / this._lodGenerationScale) / width;\r\n                if (lod === 0) {\r\n                    alpha = 0;\r\n                }\r\n\r\n                effect.setFloat(\"alphaG\", alpha);\r\n\r\n                this._effectRenderer.draw();\r\n            }\r\n        }\r\n\r\n        // Cleanup\r\n        this._effectRenderer.restoreStates();\r\n        this._engine.restoreDefaultFramebuffer();\r\n\r\n        // Preserve irradiance texture while swapping the main reflection texture.\r\n        // The release path disposes integrated irradiance by default, but radiance prefiltering\r\n        // should not invalidate an already generated irradiance texture.\r\n        const irradianceTexture = texture._texture!._irradianceTexture;\r\n        texture._texture!._irradianceTexture = null;\r\n        this._engine._releaseTexture(texture._texture!);\r\n\r\n        // Internal Swap\r\n        const type = outputTexture.texture!.type;\r\n        const format = outputTexture.texture!.format;\r\n\r\n        outputTexture._swapAndDie(texture._texture!);\r\n        texture._texture!._irradianceTexture = irradianceTexture;\r\n\r\n        texture._texture!.type = type;\r\n        texture._texture!.format = format;\r\n\r\n        // New settings\r\n        texture.gammaSpace = false;\r\n        texture.lodGenerationOffset = this._lodGenerationOffset;\r\n        texture.lodGenerationScale = this._lodGenerationScale;\r\n        texture._prefiltered = true;\r\n\r\n        return texture;\r\n    }\r\n\r\n    private _createEffect(texture: BaseTexture, onCompiled?: Nullable<(effect: Effect) => void>): EffectWrapper {\r\n        const defines = [];\r\n        if (texture.gammaSpace) {\r\n            defines.push(\"#define GAMMA_INPUT\");\r\n        }\r\n\r\n        defines.push(\"#define NUM_SAMPLES \" + this.quality + \"u\"); // unsigned int\r\n\r\n        const isWebGPU = this._engine.isWebGPU;\r\n\r\n        const effectWrapper = new EffectWrapper({\r\n            engine: this._engine,\r\n            name: \"hdrFiltering\",\r\n            vertexShader: \"hdrFiltering\",\r\n            fragmentShader: \"hdrFiltering\",\r\n            samplerNames: [\"inputTexture\"],\r\n            uniformNames: [\"vSampleDirections\", \"vWeights\", \"up\", \"right\", \"front\", \"vFilteringInfo\", \"hdrScale\", \"alphaG\"],\r\n            useShaderStore: true,\r\n            defines,\r\n            onCompiled: onCompiled,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../../ShadersWGSL/hdrFiltering.vertex\"), import(\"../../../ShadersWGSL/hdrFiltering.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../../Shaders/hdrFiltering.vertex\"), import(\"../../../Shaders/hdrFiltering.fragment\")]);\r\n                }\r\n            },\r\n        });\r\n\r\n        return effectWrapper;\r\n    }\r\n\r\n    /**\r\n     * Get a value indicating if the filter is ready to be used\r\n     * @param texture Texture to filter\r\n     * @returns true if the filter is ready\r\n     */\r\n    public isReady(texture: BaseTexture) {\r\n        return texture.isReady() && this._effectWrapper.effect.isReady();\r\n    }\r\n\r\n    /**\r\n     * Prefilters a cube texture to have mipmap levels representing roughness values.\r\n     * Prefiltering will be invoked at the end of next rendering pass.\r\n     * This has to be done once the map is loaded, and has not been prefiltered by a third party software.\r\n     * See http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf for more information\r\n     * @param texture Texture to filter\r\n     * @returns Promise called when prefiltering is done\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async prefilter(texture: BaseTexture): Promise<void> {\r\n        if (!this._engine._features.allowTexturePrefiltering) {\r\n            throw new Error(\"HDR prefiltering is not available in WebGL 1., you can use real time filtering instead.\");\r\n        }\r\n\r\n        this._effectRenderer = new EffectRenderer(this._engine);\r\n        this._effectWrapper = this._createEffect(texture);\r\n\r\n        await this._effectWrapper.effect.whenCompiledAsync();\r\n\r\n        this._prefilterInternal(texture);\r\n        this._effectRenderer.dispose();\r\n        this._effectWrapper.dispose();\r\n    }\r\n}\r\n","import { Vector3 } from \"../../../Maths/math\";\r\nimport { ILog2 } from \"../../../Maths/math.scalar.functions\";\r\nimport { BaseTexture } from \"../baseTexture.pure\";\r\nimport { type AbstractEngine } from \"../../../Engines/abstractEngine\";\r\nimport { type Effect } from \"../../../Materials/effect\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { EffectWrapper, EffectRenderer } from \"../../../Materials/effectRenderer.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type RenderTargetWrapper } from \"../../../Engines/renderTargetWrapper\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { IblCdfGenerator } from \"../../../Rendering/iblCdfGenerator\";\r\n\r\n/**\r\n * Options for texture filtering\r\n */\r\ninterface IHDRIrradianceFilteringOptions {\r\n    /**\r\n     * Scales pixel intensity for the input HDR map.\r\n     */\r\n    hdrScale?: number;\r\n\r\n    /**\r\n     * Quality of the filter. Should be `Constants.TEXTURE_FILTERING_QUALITY_OFFLINE` for prefiltering\r\n     */\r\n    quality?: number;\r\n\r\n    /**\r\n     * Use the Cumulative Distribution Function (CDF) for filtering\r\n     */\r\n    useCdf?: boolean;\r\n}\r\n\r\n/**\r\n * Filters HDR maps to get correct renderings of PBR reflections\r\n */\r\nexport class HDRIrradianceFiltering {\r\n    private _engine: AbstractEngine;\r\n    private _effectRenderer: EffectRenderer;\r\n    private _effectWrapper: EffectWrapper;\r\n    private _cdfGenerator: IblCdfGenerator;\r\n\r\n    /**\r\n     * Quality switch for prefiltering. Should be set to `Constants.TEXTURE_FILTERING_QUALITY_OFFLINE` unless\r\n     * you care about baking speed.\r\n     */\r\n    public quality: number = Constants.TEXTURE_FILTERING_QUALITY_OFFLINE;\r\n\r\n    /**\r\n     * Scales pixel intensity for the input HDR map.\r\n     */\r\n    public hdrScale: number = 1;\r\n\r\n    /**\r\n     * Use the Cumulative Distribution Function (CDF) for filtering\r\n     */\r\n    public useCdf: boolean = false;\r\n\r\n    /**\r\n     * Instantiates HDR filter for irradiance map\r\n     *\r\n     * @param engine Thin engine\r\n     * @param options Options\r\n     */\r\n    constructor(engine: AbstractEngine, options: IHDRIrradianceFilteringOptions = {}) {\r\n        // pass\r\n        this._engine = engine;\r\n        this.hdrScale = options.hdrScale || this.hdrScale;\r\n        this.quality = options.quality || this.quality;\r\n        this.useCdf = options.useCdf || this.useCdf;\r\n    }\r\n\r\n    private _createRenderTarget(size: number): RenderTargetWrapper {\r\n        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (this._engine.getCaps().textureHalfFloatRender) {\r\n            textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        } else if (this._engine.getCaps().textureFloatRender) {\r\n            textureType = Constants.TEXTURETYPE_FLOAT;\r\n        }\r\n\r\n        const rtWrapper = this._engine.createRenderTargetCubeTexture(size, {\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            type: textureType,\r\n            createMipMaps: false,\r\n            generateMipMaps: false,\r\n            generateDepthBuffer: false,\r\n            generateStencilBuffer: false,\r\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n            label: \"HDR_Irradiance_Filtering_Target\",\r\n        });\r\n        this._engine.updateTextureWrappingMode(rtWrapper.texture!, Constants.TEXTURE_CLAMP_ADDRESSMODE, Constants.TEXTURE_CLAMP_ADDRESSMODE, Constants.TEXTURE_CLAMP_ADDRESSMODE);\r\n\r\n        return rtWrapper;\r\n    }\r\n\r\n    private _prefilterInternal(texture: BaseTexture): BaseTexture {\r\n        const width = texture.getSize().width;\r\n        const mipmapsCount = ILog2(width);\r\n\r\n        const effect = this._effectWrapper.effect;\r\n        // Choose a power of 2 size for the irradiance map.\r\n        // It can be much smaller than the original texture.\r\n        const irradianceSize = Math.max(32, 1 << ILog2(width >> 3));\r\n        const outputTexture = this._createRenderTarget(irradianceSize);\r\n        this._effectRenderer.saveStates();\r\n        this._effectRenderer.setViewport();\r\n\r\n        this._effectRenderer.applyEffectWrapper(this._effectWrapper);\r\n\r\n        const directions = [\r\n            [new Vector3(0, 0, -1), new Vector3(0, -1, 0), new Vector3(1, 0, 0)], // PositiveX\r\n            [new Vector3(0, 0, 1), new Vector3(0, -1, 0), new Vector3(-1, 0, 0)], // NegativeX\r\n            [new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0)], // PositiveY\r\n            [new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(0, -1, 0)], // NegativeY\r\n            [new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 0, 1)], // PositiveZ\r\n            [new Vector3(-1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 0, -1)], // NegativeZ\r\n        ];\r\n\r\n        effect.setFloat(\"hdrScale\", this.hdrScale);\r\n        effect.setFloat2(\"vFilteringInfo\", texture.getSize().width, mipmapsCount);\r\n        effect.setTexture(\"inputTexture\", texture);\r\n        if (this._cdfGenerator) {\r\n            effect.setTexture(\"icdfTexture\", this._cdfGenerator.getIcdfTexture());\r\n        }\r\n\r\n        for (let face = 0; face < 6; face++) {\r\n            effect.setVector3(\"up\", directions[face][0]);\r\n            effect.setVector3(\"right\", directions[face][1]);\r\n            effect.setVector3(\"front\", directions[face][2]);\r\n\r\n            this._engine.bindFramebuffer(outputTexture, face, undefined, undefined, true);\r\n            this._effectRenderer.applyEffectWrapper(this._effectWrapper);\r\n\r\n            this._effectRenderer.draw();\r\n        }\r\n\r\n        // Cleanup\r\n        this._effectRenderer.restoreStates();\r\n        this._engine.restoreDefaultFramebuffer();\r\n        effect.setTexture(\"inputTexture\", null);\r\n        effect.setTexture(\"icdfTexture\", null);\r\n        const irradianceTexture = new BaseTexture(texture.getScene(), outputTexture.texture);\r\n        irradianceTexture.name = texture.name + \"_irradiance\";\r\n        irradianceTexture.displayName = texture.name + \"_irradiance\";\r\n        irradianceTexture.gammaSpace = false;\r\n        return irradianceTexture;\r\n    }\r\n\r\n    private _createEffect(texture: BaseTexture, onCompiled?: Nullable<(effect: Effect) => void>): EffectWrapper {\r\n        const defines = [];\r\n        if (texture.gammaSpace) {\r\n            defines.push(\"#define GAMMA_INPUT\");\r\n        }\r\n\r\n        defines.push(\"#define NUM_SAMPLES \" + this.quality + \"u\"); // unsigned int\r\n\r\n        const isWebGPU = this._engine.isWebGPU;\r\n        const samplers = [\"inputTexture\"];\r\n        if (this._cdfGenerator) {\r\n            samplers.push(\"icdfTexture\");\r\n            defines.push(\"#define IBL_CDF_FILTERING\");\r\n        }\r\n        const effectWrapper = new EffectWrapper({\r\n            engine: this._engine,\r\n            name: \"HDRIrradianceFiltering\",\r\n            vertexShader: \"hdrIrradianceFiltering\",\r\n            fragmentShader: \"hdrIrradianceFiltering\",\r\n            samplerNames: samplers,\r\n            uniformNames: [\"vSampleDirections\", \"vWeights\", \"up\", \"right\", \"front\", \"vFilteringInfo\", \"hdrScale\"],\r\n            useShaderStore: true,\r\n            defines,\r\n            onCompiled: onCompiled,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../../ShadersWGSL/hdrIrradianceFiltering.vertex\"), import(\"../../../ShadersWGSL/hdrIrradianceFiltering.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../../Shaders/hdrIrradianceFiltering.vertex\"), import(\"../../../Shaders/hdrIrradianceFiltering.fragment\")]);\r\n                }\r\n            },\r\n        });\r\n\r\n        return effectWrapper;\r\n    }\r\n\r\n    /**\r\n     * Get a value indicating if the filter is ready to be used\r\n     * @param texture Texture to filter\r\n     * @returns true if the filter is ready\r\n     */\r\n    public isReady(texture: BaseTexture) {\r\n        return texture.isReady() && this._effectWrapper.effect.isReady();\r\n    }\r\n\r\n    /**\r\n     * Prefilters a cube texture to contain IBL irradiance.\r\n     * Prefiltering will be invoked at the end of next rendering pass.\r\n     * This has to be done once the map is loaded, and has not been prefiltered by a third party software.\r\n     * See http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf for more information\r\n     * @param texture Texture to filter\r\n     * @returns Promise called when prefiltering is done\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async prefilter(texture: BaseTexture): Promise<BaseTexture> {\r\n        if (!this._engine._features.allowTexturePrefiltering) {\r\n            throw new Error(\"HDR prefiltering is not available in WebGL 1., you can use real time filtering instead.\");\r\n        }\r\n\r\n        if (this.useCdf) {\r\n            this._cdfGenerator = new IblCdfGenerator(this._engine);\r\n            this._cdfGenerator.iblSource = texture;\r\n\r\n            await this._cdfGenerator.renderWhenReady();\r\n        }\r\n\r\n        this._effectRenderer = new EffectRenderer(this._engine);\r\n        this._effectWrapper = this._createEffect(texture);\r\n        await this._effectWrapper.effect.whenCompiledAsync();\r\n\r\n        const irradianceTexture = this._prefilterInternal(texture);\r\n\r\n        if (this.useCdf) {\r\n            // eslint-disable-next-line github/no-then\r\n            await this._cdfGenerator.findDominantDirection().then((dir) => {\r\n                irradianceTexture._dominantDirection = dir;\r\n            });\r\n        }\r\n        this._effectRenderer.dispose();\r\n        this._effectWrapper.dispose();\r\n        this._cdfGenerator?.dispose();\r\n\r\n        return irradianceTexture;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { CubeMapToSphericalPolynomialTools } from \"../../Misc/HighDynamicRange/cubemapToSphericalPolynomial\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { TimingTools } from \"../../Misc/timingTools\";\r\nimport { ToGammaSpace } from \"../../Maths/math.constants\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { HDRFiltering } from \"../../Materials/Textures/Filtering/hdrFiltering\";\r\nimport { HDRIrradianceFiltering } from \"../../Materials/Textures/Filtering/hdrIrradianceFiltering\";\r\nimport { ToHalfFloat } from \"../../Misc/textureTools\";\r\nimport { type CubeMapInfo } from \"../../Misc/HighDynamicRange/panoramaToCubemap\";\r\nimport { SphericalPolynomial } from \"../../Maths/sphericalPolynomial.pure\";\r\n\r\n/**\r\n * This represents an environment base texture which could for instance be from HDR or EXR files.\r\n */\r\nexport abstract class EnvCubeTexture extends BaseTexture {\r\n    private static _FacesMapping = [\"right\", \"left\", \"up\", \"down\", \"front\", \"back\"];\r\n\r\n    protected _generateHarmonics = true;\r\n    protected _noMipmap: boolean;\r\n    protected _size: number;\r\n\r\n    private _prefilterOnLoad: boolean;\r\n    private _prefilterIrradianceOnLoad: boolean;\r\n    private _prefilterUsingCdf: boolean;\r\n    private _textureMatrix: Matrix;\r\n    private _supersample: boolean;\r\n    private _onLoad: () => void;\r\n    private _onError: Nullable<() => void> = null;\r\n\r\n    /**\r\n     * The texture URL.\r\n     */\r\n    public url: string;\r\n\r\n    protected _isBlocking: boolean = true;\r\n    /**\r\n     * Sets whether or not the texture is blocking during loading.\r\n     */\r\n    public override set isBlocking(value: boolean) {\r\n        this._isBlocking = value;\r\n    }\r\n    /**\r\n     * Gets whether or not the texture is blocking during loading.\r\n     */\r\n    public override get isBlocking(): boolean {\r\n        return this._isBlocking;\r\n    }\r\n\r\n    protected _rotationY: number = 0;\r\n    /**\r\n     * Sets texture matrix rotation angle around Y axis in radians.\r\n     */\r\n    public set rotationY(value: number) {\r\n        this._rotationY = value;\r\n        this.setReflectionTextureMatrix(Matrix.RotationY(this._rotationY));\r\n    }\r\n    /**\r\n     * Gets texture matrix rotation angle around Y axis radians.\r\n     */\r\n    public get rotationY(): number {\r\n        return this._rotationY;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the center of the bounding box associated with the cube texture\r\n     * It must define where the camera used to render the texture was set\r\n     */\r\n    public boundingBoxPosition = Vector3.Zero();\r\n\r\n    private _boundingBoxSize: Vector3;\r\n\r\n    /**\r\n     * Gets or sets the size of the bounding box associated with the cube texture\r\n     * When defined, the cubemap will switch to local mode\r\n     * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity\r\n     * @example https://www.babylonjs-playground.com/#RNASML\r\n     */\r\n    public set boundingBoxSize(value: Vector3) {\r\n        if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {\r\n            return;\r\n        }\r\n        this._boundingBoxSize = value;\r\n        const scene = this.getScene();\r\n        if (scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n        }\r\n    }\r\n    public get boundingBoxSize(): Vector3 {\r\n        return this._boundingBoxSize;\r\n    }\r\n\r\n    /**\r\n     * Observable triggered once the texture has been loaded.\r\n     */\r\n    public onLoadObservable: Observable<EnvCubeTexture> = new Observable<EnvCubeTexture>();\r\n\r\n    /**\r\n     * Instantiates an EnvCubeTexture from the following parameters.\r\n     *\r\n     * @param url The location of the raw data (Panorama stored in RGBE format)\r\n     * @param sceneOrEngine The scene or engine the texture will be used in\r\n     * @param size The cubemap desired size (the more it increases the longer the generation will be)\r\n     * @param noMipmap Forces to not generate the mipmap if true\r\n     * @param generateHarmonics Specifies whether you want to extract the polynomial harmonics during the generation process\r\n     * @param gammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)\r\n     * @param prefilterOnLoad Prefilters texture to allow use of this texture as a PBR reflection texture.\r\n     * @param onLoad on success callback function\r\n     * @param onError on error callback function\r\n     * @param supersample Defines if texture must be supersampled (default: false)\r\n     * @param prefilterIrradianceOnLoad Prefilters texture to allow use of this texture for irradiance lighting.\r\n     * @param prefilterUsingCdf Defines if the prefiltering should be done using a CDF instead of the default approach.\r\n     * @param sphericalPolynomialTargetSize Target face size for spherical polynomial computation. 0 = full resolution (default).\r\n     */\r\n    constructor(\r\n        url: string,\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        size: number,\r\n        noMipmap = false,\r\n        generateHarmonics = true,\r\n        gammaSpace = false,\r\n        prefilterOnLoad = false,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        supersample = false,\r\n        prefilterIrradianceOnLoad = false,\r\n        prefilterUsingCdf = false,\r\n        sphericalPolynomialTargetSize = 0\r\n    ) {\r\n        super(sceneOrEngine);\r\n\r\n        if (!url) {\r\n            return;\r\n        }\r\n\r\n        this._coordinatesMode = Texture.CUBIC_MODE;\r\n        this.name = url;\r\n        this.url = url;\r\n        this.hasAlpha = false;\r\n        this.isCube = true;\r\n        this._textureMatrix = Matrix.Identity();\r\n        this._prefilterOnLoad = prefilterOnLoad;\r\n        this._prefilterIrradianceOnLoad = prefilterIrradianceOnLoad;\r\n        this._prefilterUsingCdf = prefilterUsingCdf;\r\n        this._onLoad = () => {\r\n            this.onLoadObservable.notifyObservers(this);\r\n            if (onLoad) {\r\n                onLoad();\r\n            }\r\n        };\r\n\r\n        this._onError = onError;\r\n        this.gammaSpace = gammaSpace;\r\n\r\n        this._noMipmap = noMipmap;\r\n        this._size = size;\r\n        // CDF is very sensitive to lost precision due to downsampling. This can result in\r\n        // noticeable brightness differences with different resolutions. Enabling supersampling\r\n        // mitigates this.\r\n        this._supersample = supersample || prefilterUsingCdf;\r\n        this._generateHarmonics = generateHarmonics;\r\n        this._sphericalPolynomialTargetSize = sphericalPolynomialTargetSize;\r\n\r\n        this._texture = this._getFromCache(url, this._noMipmap, undefined, undefined, undefined, this.isCube);\r\n\r\n        if (!this._texture) {\r\n            if (!this.getScene()?.useDelayedTextureLoading) {\r\n                this._loadTexture();\r\n            } else {\r\n                this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n            }\r\n        } else {\r\n            if (this._texture.isReady) {\r\n                TimingTools.SetImmediate(() => this._onLoad());\r\n            } else {\r\n                this._texture.onLoadedObservable.add(this._onLoad);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the texture useful for serialization or dynamic coding.\r\n     * @returns \"EnvCubeTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"EnvCubeTexture\";\r\n    }\r\n\r\n    /**\r\n     * Convert the raw data from the server into cubemap faces\r\n     * @param buffer The buffer containing the texture data\r\n     * @param size The cubemap face size\r\n     * @param supersample Defines if texture must be supersampled\r\n     * @returns The cube map data\r\n     */\r\n    protected abstract _getCubeMapTextureDataAsync(buffer: ArrayBuffer, size: number, supersample: boolean): Promise<CubeMapInfo>;\r\n\r\n    /**\r\n     * Occurs when the file has been loaded.\r\n     */\r\n    private _loadTexture() {\r\n        const engine = this._getEngine()!;\r\n        const caps = engine.getCaps();\r\n\r\n        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (caps.textureFloat && caps.textureFloatLinearFiltering) {\r\n            textureType = Constants.TEXTURETYPE_FLOAT;\r\n        } else if (caps.textureHalfFloat && caps.textureHalfFloatLinearFiltering) {\r\n            textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        }\r\n\r\n        // eslint-disable-next-line no-restricted-syntax\r\n        const callback = async (buffer: ArrayBuffer): Promise<ArrayBufferView<ArrayBufferLike>[]> => {\r\n            this.lodGenerationOffset = 0.0;\r\n            this.lodGenerationScale = 0.8;\r\n\r\n            // Extract the raw linear data.\r\n            const data = await this._getCubeMapTextureDataAsync(buffer, this._size, this._supersample);\r\n\r\n            // Generate harmonics if needed. When prefiltering was requested but the engine cannot\r\n            // prefilter textures (e.g. Babylon Native or WebGL1), neither a prefiltered irradiance\r\n            // map nor a prefiltered radiance cube is produced. In that case fall back to\r\n            // CPU-computed spherical harmonics so diffuse IBL still has a source; without this the\r\n            // reflection texture keeps an empty spherical polynomial and diffuse IBL renders black.\r\n            const prefilterUnavailable = (this._prefilterOnLoad || this._prefilterIrradianceOnLoad) && !engine._features.allowTexturePrefiltering;\r\n            if (this._generateHarmonics || prefilterUnavailable) {\r\n                const sphericalPolynomial = CubeMapToSphericalPolynomialTools.ConvertCubeMapToSphericalPolynomial(data, this._sphericalPolynomialTargetSize);\r\n                this.sphericalPolynomial = sphericalPolynomial;\r\n            }\r\n\r\n            const results = [];\r\n\r\n            let byteArray: Nullable<Uint8Array> = null;\r\n            let shortArray: Nullable<Uint16Array> = null;\r\n\r\n            // Push each faces.\r\n            for (let j = 0; j < 6; j++) {\r\n                // Create fallback array\r\n                if (textureType === Constants.TEXTURETYPE_HALF_FLOAT) {\r\n                    shortArray = new Uint16Array(this._size * this._size * 3);\r\n                } else if (textureType === Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n                    // 3 channels of 1 bytes per pixel in bytes.\r\n                    byteArray = new Uint8Array(this._size * this._size * 3);\r\n                }\r\n\r\n                const dataFace = <Float32Array>(<any>data)[EnvCubeTexture._FacesMapping[j]];\r\n\r\n                // If special cases.\r\n                if (this.gammaSpace || shortArray || byteArray) {\r\n                    for (let i = 0; i < this._size * this._size; i++) {\r\n                        // Put in gamma space if requested.\r\n                        if (this.gammaSpace) {\r\n                            dataFace[i * 3 + 0] = Math.pow(dataFace[i * 3 + 0], ToGammaSpace);\r\n                            dataFace[i * 3 + 1] = Math.pow(dataFace[i * 3 + 1], ToGammaSpace);\r\n                            dataFace[i * 3 + 2] = Math.pow(dataFace[i * 3 + 2], ToGammaSpace);\r\n                        }\r\n\r\n                        // Convert to half float texture for fallback.\r\n                        if (shortArray) {\r\n                            shortArray[i * 3 + 0] = ToHalfFloat(dataFace[i * 3 + 0]);\r\n                            shortArray[i * 3 + 1] = ToHalfFloat(dataFace[i * 3 + 1]);\r\n                            shortArray[i * 3 + 2] = ToHalfFloat(dataFace[i * 3 + 2]);\r\n                        }\r\n\r\n                        // Convert to int texture for fallback.\r\n                        if (byteArray) {\r\n                            let r = Math.max(dataFace[i * 3 + 0] * 255, 0);\r\n                            let g = Math.max(dataFace[i * 3 + 1] * 255, 0);\r\n                            let b = Math.max(dataFace[i * 3 + 2] * 255, 0);\r\n\r\n                            // May use luminance instead if the result is not accurate.\r\n                            const max = Math.max(Math.max(r, g), b);\r\n                            if (max > 255) {\r\n                                const scale = 255 / max;\r\n                                r *= scale;\r\n                                g *= scale;\r\n                                b *= scale;\r\n                            }\r\n\r\n                            byteArray[i * 3 + 0] = r;\r\n                            byteArray[i * 3 + 1] = g;\r\n                            byteArray[i * 3 + 2] = b;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (shortArray) {\r\n                    results.push(shortArray);\r\n                } else if (byteArray) {\r\n                    results.push(byteArray);\r\n                } else {\r\n                    results.push(dataFace);\r\n                }\r\n            }\r\n\r\n            return results;\r\n        };\r\n\r\n        if (engine._features.allowTexturePrefiltering && (this._prefilterOnLoad || this._prefilterIrradianceOnLoad)) {\r\n            const previousOnLoad = this._onLoad;\r\n            const previousOnError = this._onError;\r\n            const hdrFiltering = new HDRFiltering(engine);\r\n            const prefilterPendingToken = {};\r\n            const scene = this.getScene();\r\n            scene?.addPendingData(prefilterPendingToken);\r\n            this._onError = () => {\r\n                // If the texture load itself fails, _onLoad never runs so the try/finally below\r\n                // never fires. Make sure the pending-data token is still cleared so the scene\r\n                // doesn't stay stuck in isLoading / executeWhenReady.\r\n                scene?.removePendingData(prefilterPendingToken);\r\n                if (previousOnError) {\r\n                    previousOnError();\r\n                }\r\n            };\r\n            this._onLoad = () => {\r\n                void (async () => {\r\n                    try {\r\n                        let irradianceTexture: Nullable<BaseTexture> = null;\r\n                        if (this._prefilterIrradianceOnLoad) {\r\n                            const hdrIrradianceFiltering = new HDRIrradianceFiltering(engine, { useCdf: this._prefilterUsingCdf });\r\n                            irradianceTexture = await hdrIrradianceFiltering.prefilter(this);\r\n                        }\r\n\r\n                        // Run irradiance prefiltering first because it samples the current source texture.\r\n                        // Radiance prefiltering mutates/swaps the source internal texture, so running both\r\n                        // concurrently can lead to stale/destroyed texture references on WebGPU.\r\n                        if (this._prefilterIrradianceOnLoad && irradianceTexture) {\r\n                            this.irradianceTexture = irradianceTexture;\r\n                            const innerScene = this.getScene();\r\n                            if (innerScene) {\r\n                                innerScene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n                            }\r\n                        }\r\n\r\n                        if (this._prefilterOnLoad) {\r\n                            await hdrFiltering.prefilter(this);\r\n                        }\r\n                    } finally {\r\n                        scene?.removePendingData(prefilterPendingToken);\r\n                    }\r\n\r\n                    if (previousOnLoad) {\r\n                        previousOnLoad();\r\n                    }\r\n                })();\r\n            };\r\n        }\r\n\r\n        this._texture = engine.createRawCubeTextureFromUrl(\r\n            this.url,\r\n            this.getScene(),\r\n            this._size,\r\n            Constants.TEXTUREFORMAT_RGB,\r\n            textureType,\r\n            this._noMipmap,\r\n            callback,\r\n            null,\r\n            this._onLoad,\r\n            this._onError\r\n        );\r\n\r\n        if (!this._generateHarmonics && !this._texture._sphericalPolynomial) {\r\n            this._texture._sphericalPolynomial = new SphericalPolynomial();\r\n        }\r\n    }\r\n\r\n    // Methods\r\n    public override delayLoad(): void {\r\n        if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            return;\r\n        }\r\n\r\n        this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\r\n        this._texture = this._getFromCache(this.url, this._noMipmap);\r\n\r\n        if (!this._texture) {\r\n            this._loadTexture();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the texture reflection matrix used to rotate/transform the reflection.\r\n     * @returns the reflection matrix\r\n     */\r\n    public override getReflectionTextureMatrix(): Matrix {\r\n        return this._textureMatrix;\r\n    }\r\n\r\n    /**\r\n     * Set the texture reflection matrix used to rotate/transform the reflection.\r\n     * @param value Define the reflection matrix to set\r\n     */\r\n    public setReflectionTextureMatrix(value: Matrix): void {\r\n        this._textureMatrix = value;\r\n\r\n        if (value.updateFlag === this._textureMatrix.updateFlag) {\r\n            return;\r\n        }\r\n\r\n        if (value.isIdentity() !== this._textureMatrix.isIdentity()) {\r\n            this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => mat.getActiveTextures().indexOf(this) !== -1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        this.onLoadObservable.clear();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Serializes the texture to a JSON representation.\r\n     * @returns the JSON representation\r\n     */\r\n    public override serialize(): any {\r\n        if (!this.name) {\r\n            return null;\r\n        }\r\n\r\n        const serializationObject: any = {};\r\n        serializationObject.name = this.name;\r\n        serializationObject.hasAlpha = this.hasAlpha;\r\n        serializationObject.isCube = true;\r\n        serializationObject.level = this.level;\r\n        serializationObject.size = this._size;\r\n        serializationObject.coordinatesMode = this.coordinatesMode;\r\n        serializationObject.useInGammaSpace = this.gammaSpace;\r\n        serializationObject.generateHarmonics = this._generateHarmonics;\r\n        serializationObject.noMipmap = this._noMipmap;\r\n        serializationObject.isBlocking = this._isBlocking;\r\n        serializationObject.rotationY = this._rotationY;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    protected abstract _instantiateClone(): this;\r\n\r\n    /**\r\n     * Clones the current texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): this {\r\n        const newTexture = this._instantiateClone();\r\n\r\n        // Base Texture\r\n        newTexture.level = this.level;\r\n        newTexture.wrapU = this.wrapU;\r\n        newTexture.wrapV = this.wrapV;\r\n        newTexture.coordinatesIndex = this.coordinatesIndex;\r\n        newTexture.coordinatesMode = this.coordinatesMode;\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    protected static _Parse(parsedTexture: any, texture: EnvCubeTexture): void {\r\n        texture.name = parsedTexture.name;\r\n        texture.hasAlpha = parsedTexture.hasAlpha;\r\n        texture.level = parsedTexture.level;\r\n        texture.coordinatesMode = parsedTexture.coordinatesMode;\r\n        texture.isBlocking = parsedTexture.isBlocking;\r\n        if (parsedTexture.boundingBoxPosition) {\r\n            texture.boundingBoxPosition = Vector3.FromArray(parsedTexture.boundingBoxPosition);\r\n        }\r\n        if (parsedTexture.boundingBoxSize) {\r\n            texture.boundingBoxSize = Vector3.FromArray(parsedTexture.boundingBoxSize);\r\n        }\r\n        if (parsedTexture.rotationY) {\r\n            texture.rotationY = parsedTexture.rotationY;\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../../types\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\n\r\n/**\r\n * CubeMap information grouping all the data for each faces as well as the cubemap size.\r\n */\r\nexport interface CubeMapInfo {\r\n    /**\r\n     * The pixel array for the front face.\r\n     * This is stored in format, left to right, up to down format.\r\n     */\r\n    front: Nullable<ArrayBufferView>;\r\n\r\n    /**\r\n     * The pixel array for the back face.\r\n     * This is stored in format, left to right, up to down format.\r\n     */\r\n    back: Nullable<ArrayBufferView>;\r\n\r\n    /**\r\n     * The pixel array for the left face.\r\n     * This is stored in format, left to right, up to down format.\r\n     */\r\n    left: Nullable<ArrayBufferView>;\r\n\r\n    /**\r\n     * The pixel array for the right face.\r\n     * This is stored in format, left to right, up to down format.\r\n     */\r\n    right: Nullable<ArrayBufferView>;\r\n\r\n    /**\r\n     * The pixel array for the up face.\r\n     * This is stored in format, left to right, up to down format.\r\n     */\r\n    up: Nullable<ArrayBufferView>;\r\n\r\n    /**\r\n     * The pixel array for the down face.\r\n     * This is stored in format, left to right, up to down format.\r\n     */\r\n    down: Nullable<ArrayBufferView>;\r\n\r\n    /**\r\n     * The size of the cubemap stored.\r\n     *\r\n     * Each faces will be size * size pixels.\r\n     */\r\n    size: number;\r\n\r\n    /**\r\n     * The format of the texture.\r\n     *\r\n     * RGBA, RGB.\r\n     */\r\n    format: number;\r\n\r\n    /**\r\n     * The type of the texture data.\r\n     *\r\n     * UNSIGNED_INT, FLOAT.\r\n     */\r\n    type: number;\r\n\r\n    /**\r\n     * Specifies whether the texture is in gamma space.\r\n     */\r\n    gammaSpace: boolean;\r\n}\r\n\r\n/**\r\n * Helper class useful to convert panorama picture to their cubemap representation in 6 faces.\r\n */\r\nexport class PanoramaToCubeMapTools {\r\n    private static FACE_LEFT = [new Vector3(-1.0, -1.0, -1.0), new Vector3(1.0, -1.0, -1.0), new Vector3(-1.0, 1.0, -1.0), new Vector3(1.0, 1.0, -1.0)];\r\n    private static FACE_RIGHT = [new Vector3(1.0, -1.0, 1.0), new Vector3(-1.0, -1.0, 1.0), new Vector3(1.0, 1.0, 1.0), new Vector3(-1.0, 1.0, 1.0)];\r\n    private static FACE_FRONT = [new Vector3(1.0, -1.0, -1.0), new Vector3(1.0, -1.0, 1.0), new Vector3(1.0, 1.0, -1.0), new Vector3(1.0, 1.0, 1.0)];\r\n    private static FACE_BACK = [new Vector3(-1.0, -1.0, 1.0), new Vector3(-1.0, -1.0, -1.0), new Vector3(-1.0, 1.0, 1.0), new Vector3(-1.0, 1.0, -1.0)];\r\n    private static FACE_DOWN = [new Vector3(1.0, 1.0, -1.0), new Vector3(1.0, 1.0, 1.0), new Vector3(-1.0, 1.0, -1.0), new Vector3(-1.0, 1.0, 1.0)];\r\n    private static FACE_UP = [new Vector3(-1.0, -1.0, -1.0), new Vector3(-1.0, -1.0, 1.0), new Vector3(1.0, -1.0, -1.0), new Vector3(1.0, -1.0, 1.0)];\r\n\r\n    /**\r\n     * Converts a panorama stored in RGB right to left up to down format into a cubemap (6 faces).\r\n     *\r\n     * @param float32Array The source data.\r\n     * @param inputWidth The width of the input panorama.\r\n     * @param inputHeight The height of the input panorama.\r\n     * @param size The willing size of the generated cubemap (each faces will be size * size pixels)\r\n     * @param supersample enable supersampling the cubemap\r\n     * @param invertY defines if the Y axis must be inverted\r\n     * @returns The cubemap data\r\n     */\r\n    public static ConvertPanoramaToCubemap(float32Array: Float32Array, inputWidth: number, inputHeight: number, size: number, supersample = false, invertY = true): CubeMapInfo {\r\n        if (!float32Array) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"ConvertPanoramaToCubemap: input cannot be null\";\r\n        }\r\n\r\n        let stride: number;\r\n        if (float32Array.length != inputWidth * inputHeight * 3) {\r\n            if (float32Array.length != inputWidth * inputHeight * 4) {\r\n                // eslint-disable-next-line no-throw-literal\r\n                throw \"ConvertPanoramaToCubemap: input size is wrong\";\r\n            } else {\r\n                stride = 4;\r\n            }\r\n        } else {\r\n            stride = 3;\r\n        }\r\n\r\n        const textureFront = this.CreateCubemapTexture(size, this.FACE_FRONT, float32Array, inputWidth, inputHeight, supersample, invertY, stride);\r\n        const textureBack = this.CreateCubemapTexture(size, this.FACE_BACK, float32Array, inputWidth, inputHeight, supersample, invertY, stride);\r\n        const textureLeft = this.CreateCubemapTexture(size, this.FACE_LEFT, float32Array, inputWidth, inputHeight, supersample, invertY, stride);\r\n        const textureRight = this.CreateCubemapTexture(size, this.FACE_RIGHT, float32Array, inputWidth, inputHeight, supersample, invertY, stride);\r\n        const textureUp = this.CreateCubemapTexture(size, this.FACE_UP, float32Array, inputWidth, inputHeight, supersample, invertY, stride);\r\n        const textureDown = this.CreateCubemapTexture(size, this.FACE_DOWN, float32Array, inputWidth, inputHeight, supersample, invertY, stride);\r\n\r\n        return {\r\n            front: textureFront,\r\n            back: textureBack,\r\n            left: textureLeft,\r\n            right: textureRight,\r\n            up: textureUp,\r\n            down: textureDown,\r\n            size: size,\r\n            type: Constants.TEXTURETYPE_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGB,\r\n            gammaSpace: false,\r\n        };\r\n    }\r\n\r\n    private static CreateCubemapTexture(\r\n        texSize: number,\r\n        faceData: Vector3[],\r\n        float32Array: Float32Array,\r\n        inputWidth: number,\r\n        inputHeight: number,\r\n        supersample: boolean,\r\n        invertY: boolean,\r\n        stride: number\r\n    ): Float32Array {\r\n        const buffer = new ArrayBuffer(texSize * texSize * 4 * 3);\r\n        const textureArray = new Float32Array(buffer);\r\n\r\n        // If supersampling, determine number of samples needed when source texture width is divided for 4 cube faces\r\n        const samples = supersample ? Math.max(1, Math.round(inputWidth / 4 / texSize)) : 1;\r\n        const sampleFactor = 1 / samples;\r\n        const sampleFactorSqr = sampleFactor * sampleFactor;\r\n\r\n        const rotDX1 = faceData[1].subtract(faceData[0]).scale(sampleFactor / texSize);\r\n        const rotDX2 = faceData[3].subtract(faceData[2]).scale(sampleFactor / texSize);\r\n\r\n        const dy = 1 / texSize;\r\n        let fy = 0;\r\n\r\n        for (let y = 0; y < texSize; y++) {\r\n            for (let sy = 0; sy < samples; sy++) {\r\n                let xv1 = faceData[0];\r\n                let xv2 = faceData[2];\r\n\r\n                for (let x = 0; x < texSize; x++) {\r\n                    for (let sx = 0; sx < samples; sx++) {\r\n                        const v = xv2.subtract(xv1).scale(fy).add(xv1);\r\n                        v.normalize();\r\n\r\n                        const color = this.CalcProjectionSpherical(v, float32Array, inputWidth, inputHeight, stride, invertY);\r\n\r\n                        // 3 channels per pixels\r\n                        textureArray[y * texSize * 3 + x * 3 + 0] += color.r * sampleFactorSqr;\r\n                        textureArray[y * texSize * 3 + x * 3 + 1] += color.g * sampleFactorSqr;\r\n                        textureArray[y * texSize * 3 + x * 3 + 2] += color.b * sampleFactorSqr;\r\n\r\n                        xv1 = xv1.add(rotDX1);\r\n                        xv2 = xv2.add(rotDX2);\r\n                    }\r\n                }\r\n\r\n                fy += dy * sampleFactor;\r\n            }\r\n        }\r\n\r\n        return textureArray;\r\n    }\r\n\r\n    private static CalcProjectionSpherical(vDir: Vector3, float32Array: Float32Array, inputWidth: number, inputHeight: number, stride: number, invertY: boolean): any {\r\n        let theta = Math.atan2(vDir.z, vDir.x);\r\n        const phi = Math.acos(vDir.y);\r\n\r\n        while (theta < -Math.PI) {\r\n            theta += 2 * Math.PI;\r\n        }\r\n        while (theta > Math.PI) {\r\n            theta -= 2 * Math.PI;\r\n        }\r\n\r\n        let dx = theta / Math.PI;\r\n        const dy = phi / Math.PI;\r\n\r\n        // recenter.\r\n        dx = dx * 0.5 + 0.5;\r\n\r\n        let px = Math.round(dx * inputWidth);\r\n        if (px < 0) {\r\n            px = 0;\r\n        } else if (px >= inputWidth) {\r\n            px = inputWidth - 1;\r\n        }\r\n\r\n        let py = Math.round(dy * inputHeight);\r\n        if (py < 0) {\r\n            py = 0;\r\n        } else if (py >= inputHeight) {\r\n            py = inputHeight - 1;\r\n        }\r\n\r\n        const inputY = invertY ? inputHeight - py - 1 : py;\r\n        const r = float32Array[inputY * inputWidth * stride + px * stride + 0];\r\n        const g = float32Array[inputY * inputWidth * stride + px * stride + 1];\r\n        const b = float32Array[inputY * inputWidth * stride + px * stride + 2];\r\n\r\n        return {\r\n            r: r,\r\n            g: g,\r\n            b: b,\r\n        };\r\n    }\r\n}\r\n","import { type CubeMapInfo, PanoramaToCubeMapTools } from \"./panoramaToCubemap\";\r\n\r\n/**\r\n * Header information of HDR texture files.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface HDRInfo {\r\n    /**\r\n     * The height of the texture in pixels.\r\n     */\r\n    height: number;\r\n\r\n    /**\r\n     * The width of the texture in pixels.\r\n     */\r\n    width: number;\r\n\r\n    /**\r\n     * The index of the beginning of the data in the binary file.\r\n     */\r\n    dataPosition: number;\r\n}\r\n\r\n/* This groups tools to convert HDR texture to native colors array. */\r\n\r\nfunction Ldexp(mantissa: number, exponent: number): number {\r\n    if (exponent > 1023) {\r\n        return mantissa * Math.pow(2, 1023) * Math.pow(2, exponent - 1023);\r\n    }\r\n\r\n    if (exponent < -1074) {\r\n        return mantissa * Math.pow(2, -1074) * Math.pow(2, exponent + 1074);\r\n    }\r\n\r\n    return mantissa * Math.pow(2, exponent);\r\n}\r\n\r\nfunction Rgbe2float(float32array: Float32Array, red: number, green: number, blue: number, exponent: number, index: number) {\r\n    if (exponent > 0) {\r\n        /*nonzero pixel*/\r\n        exponent = Ldexp(1.0, exponent - (128 + 8));\r\n\r\n        float32array[index + 0] = red * exponent;\r\n        float32array[index + 1] = green * exponent;\r\n        float32array[index + 2] = blue * exponent;\r\n    } else {\r\n        float32array[index + 0] = 0;\r\n        float32array[index + 1] = 0;\r\n        float32array[index + 2] = 0;\r\n    }\r\n}\r\n\r\nfunction ReadStringLine(uint8array: Uint8Array, startIndex: number): string {\r\n    let line = \"\";\r\n    let character: string;\r\n\r\n    for (let i = startIndex; i < uint8array.length - startIndex; i++) {\r\n        character = String.fromCharCode(uint8array[i]);\r\n\r\n        if (character == \"\\n\") {\r\n            break;\r\n        }\r\n\r\n        line += character;\r\n    }\r\n\r\n    return line;\r\n}\r\n\r\n/**\r\n * Reads header information from an RGBE texture stored in a native array.\r\n * More information on this format are available here:\r\n * https://en.wikipedia.org/wiki/RGBE_image_format\r\n *\r\n * @param uint8array The binary file stored in  native array.\r\n * @returns The header information.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RGBE_ReadHeader(uint8array: Uint8Array): HDRInfo {\r\n    let line = ReadStringLine(uint8array, 0);\r\n    if (line[0] != \"#\" || line[1] != \"?\") {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"Bad HDR Format.\";\r\n    }\r\n\r\n    let endOfHeader = false;\r\n    let findFormat = false;\r\n    let lineIndex: number = 0;\r\n\r\n    do {\r\n        lineIndex += line.length + 1;\r\n        line = ReadStringLine(uint8array, lineIndex);\r\n\r\n        if (line == \"FORMAT=32-bit_rle_rgbe\") {\r\n            findFormat = true;\r\n        } else if (line.length == 0) {\r\n            endOfHeader = true;\r\n        }\r\n    } while (!endOfHeader);\r\n\r\n    if (!findFormat) {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"HDR Bad header format, unsupported FORMAT\";\r\n    }\r\n\r\n    lineIndex += line.length + 1;\r\n    line = ReadStringLine(uint8array, lineIndex);\r\n\r\n    const sizeRegexp = /^-Y (.*) \\+X (.*)$/g;\r\n    const match = sizeRegexp.exec(line);\r\n\r\n    // TODO. Support +Y and -X if needed.\r\n    if (!match || match.length < 3) {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"HDR Bad header format, no size\";\r\n    }\r\n    const width = parseInt(match[2]);\r\n    const height = parseInt(match[1]);\r\n\r\n    if (width < 8 || width > 0x7fff) {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"HDR Bad header format, unsupported size\";\r\n    }\r\n\r\n    lineIndex += line.length + 1;\r\n\r\n    return {\r\n        height: height,\r\n        width: width,\r\n        dataPosition: lineIndex,\r\n    };\r\n}\r\n\r\n/**\r\n * Returns the cubemap information (each faces texture data) extracted from an RGBE texture.\r\n * This RGBE texture needs to store the information as a panorama.\r\n *\r\n * More information on this format are available here:\r\n * https://en.wikipedia.org/wiki/RGBE_image_format\r\n *\r\n * @param buffer The binary file stored in an array buffer.\r\n * @param size The expected size of the extracted cubemap.\r\n * @param supersample enable supersampling the cubemap (default: false)\r\n * @returns The Cube Map information.\r\n */\r\nexport function GetCubeMapTextureData(buffer: ArrayBuffer, size: number, supersample = false): CubeMapInfo {\r\n    const uint8array = new Uint8Array(buffer);\r\n    const hdrInfo = RGBE_ReadHeader(uint8array);\r\n    const data = RGBE_ReadPixels(uint8array, hdrInfo);\r\n\r\n    const cubeMapData = PanoramaToCubeMapTools.ConvertPanoramaToCubemap(data, hdrInfo.width, hdrInfo.height, size, supersample);\r\n\r\n    return cubeMapData;\r\n}\r\n\r\n/**\r\n * Returns the pixels data extracted from an RGBE texture.\r\n * This pixels will be stored left to right up to down in the R G B order in one array.\r\n *\r\n * More information on this format are available here:\r\n * https://en.wikipedia.org/wiki/RGBE_image_format\r\n *\r\n * @param uint8array The binary file stored in an array buffer.\r\n * @param hdrInfo The header information of the file.\r\n * @returns The pixels data in RGB right to left up to down order.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RGBE_ReadPixels(uint8array: Uint8Array, hdrInfo: HDRInfo): Float32Array {\r\n    return ReadRGBEPixelsRLE(uint8array, hdrInfo);\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction ReadRGBEPixelsRLE(uint8array: Uint8Array, hdrInfo: HDRInfo): Float32Array {\r\n    let numScanlines = hdrInfo.height;\r\n    const scanlineWidth = hdrInfo.width;\r\n\r\n    let a: number, b: number, c: number, d: number, count: number;\r\n    let dataIndex = hdrInfo.dataPosition;\r\n    let index: number, endIndex: number, i: number;\r\n\r\n    const scanLineArrayBuffer = new ArrayBuffer(scanlineWidth * 4); // four channel R G B E\r\n    const scanLineArray = new Uint8Array(scanLineArrayBuffer);\r\n\r\n    // 3 channels of 4 bytes per pixel in float.\r\n    const resultBuffer = new ArrayBuffer(hdrInfo.width * hdrInfo.height * 4 * 3);\r\n    const resultArray = new Float32Array(resultBuffer);\r\n\r\n    // read in each successive scanline\r\n    while (numScanlines > 0) {\r\n        a = uint8array[dataIndex++];\r\n        b = uint8array[dataIndex++];\r\n        c = uint8array[dataIndex++];\r\n        d = uint8array[dataIndex++];\r\n\r\n        if (a != 2 || b != 2 || c & 0x80 || hdrInfo.width < 8 || hdrInfo.width > 32767) {\r\n            return ReadRGBEPixelsNotRLE(uint8array, hdrInfo);\r\n        }\r\n\r\n        if (((c << 8) | d) != scanlineWidth) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"HDR Bad header format, wrong scan line width\";\r\n        }\r\n\r\n        index = 0;\r\n\r\n        // read each of the four channels for the scanline into the buffer\r\n        for (i = 0; i < 4; i++) {\r\n            endIndex = (i + 1) * scanlineWidth;\r\n\r\n            while (index < endIndex) {\r\n                a = uint8array[dataIndex++];\r\n                b = uint8array[dataIndex++];\r\n\r\n                if (a > 128) {\r\n                    // a run of the same value\r\n                    count = a - 128;\r\n                    if (count == 0 || count > endIndex - index) {\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"HDR Bad Format, bad scanline data (run)\";\r\n                    }\r\n\r\n                    while (count-- > 0) {\r\n                        scanLineArray[index++] = b;\r\n                    }\r\n                } else {\r\n                    // a non-run\r\n                    count = a;\r\n                    if (count == 0 || count > endIndex - index) {\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"HDR Bad Format, bad scanline data (non-run)\";\r\n                    }\r\n\r\n                    scanLineArray[index++] = b;\r\n                    if (--count > 0) {\r\n                        for (let j = 0; j < count; j++) {\r\n                            scanLineArray[index++] = uint8array[dataIndex++];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // now convert data from buffer into floats\r\n        for (i = 0; i < scanlineWidth; i++) {\r\n            a = scanLineArray[i];\r\n            b = scanLineArray[i + scanlineWidth];\r\n            c = scanLineArray[i + 2 * scanlineWidth];\r\n            d = scanLineArray[i + 3 * scanlineWidth];\r\n\r\n            Rgbe2float(resultArray, a, b, c, d, (hdrInfo.height - numScanlines) * scanlineWidth * 3 + i * 3);\r\n        }\r\n\r\n        numScanlines--;\r\n    }\r\n\r\n    return resultArray;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction ReadRGBEPixelsNotRLE(uint8array: Uint8Array, hdrInfo: HDRInfo): Float32Array {\r\n    // this file is not run length encoded\r\n    // read values sequentially\r\n\r\n    let numScanlines = hdrInfo.height;\r\n    const scanlineWidth = hdrInfo.width;\r\n\r\n    let a: number, b: number, c: number, d: number, i: number;\r\n    let dataIndex = hdrInfo.dataPosition;\r\n\r\n    // 3 channels of 4 bytes per pixel in float.\r\n    const resultBuffer = new ArrayBuffer(hdrInfo.width * hdrInfo.height * 4 * 3);\r\n    const resultArray = new Float32Array(resultBuffer);\r\n\r\n    // read in each successive scanline\r\n    while (numScanlines > 0) {\r\n        for (i = 0; i < hdrInfo.width; i++) {\r\n            a = uint8array[dataIndex++];\r\n            b = uint8array[dataIndex++];\r\n            c = uint8array[dataIndex++];\r\n            d = uint8array[dataIndex++];\r\n\r\n            Rgbe2float(resultArray, a, b, c, d, (hdrInfo.height - numScanlines) * scanlineWidth * 3 + i * 3);\r\n        }\r\n\r\n        numScanlines--;\r\n    }\r\n\r\n    return resultArray;\r\n}\r\n\r\n/**\r\n * @deprecated Use functions separately\r\n */\r\nexport const HDRTools = {\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    RGBE_ReadHeader,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    GetCubeMapTextureData,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    RGBE_ReadPixels,\r\n};\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { EnvCubeTexture } from \"./envCubeTexture.pure\";\r\nimport { GetCubeMapTextureData } from \"../../Misc/HighDynamicRange/hdr\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { type CubeMapInfo } from \"../../Misc/HighDynamicRange/panoramaToCubemap\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * This represents a texture coming from an HDR input.\r\n *\r\n * The supported format is currently panorama picture stored in RGBE format.\r\n * Example of such files can be found on Poly Haven: https://polyhaven.com/hdris\r\n */\r\nexport class HDRCubeTexture extends EnvCubeTexture {\r\n    /**\r\n     * Instantiates an HDRTexture from the following parameters.\r\n     *\r\n     * @param url The location of the HDR raw data (Panorama stored in RGBE format)\r\n     * @param sceneOrEngine The scene or engine the texture will be used in\r\n     * @param size The cubemap desired size (the more it increases the longer the generation will be)\r\n     * @param noMipmap Forces to not generate the mipmap if true\r\n     * @param generateHarmonics Specifies whether you want to extract the polynomial harmonics during the generation process\r\n     * @param gammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)\r\n     * @param prefilterOnLoad Prefilters HDR texture to allow use of this texture as a PBR reflection texture.\r\n     * @param onLoad on success callback function\r\n     * @param onError on error callback function\r\n     * @param supersample Defines if texture must be supersampled (default: false)\r\n     * @param prefilterIrradianceOnLoad Prefilters HDR texture to allow use of this texture for irradiance lighting.\r\n     * @param prefilterUsingCdf Defines if the prefiltering should be done using a CDF instead of the default approach.\r\n     * @param sphericalPolynomialTargetSize Target face size for spherical polynomial computation. 0 = full resolution (default).\r\n     */\r\n    constructor(\r\n        url: string,\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        size: number,\r\n        noMipmap = false,\r\n        generateHarmonics = true,\r\n        gammaSpace = false,\r\n        prefilterOnLoad = false,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        supersample = false,\r\n        prefilterIrradianceOnLoad = false,\r\n        prefilterUsingCdf = false,\r\n        sphericalPolynomialTargetSize = 0\r\n    ) {\r\n        super(\r\n            url,\r\n            sceneOrEngine,\r\n            size,\r\n            noMipmap,\r\n            generateHarmonics,\r\n            gammaSpace,\r\n            prefilterOnLoad,\r\n            onLoad,\r\n            onError,\r\n            supersample,\r\n            prefilterIrradianceOnLoad,\r\n            prefilterUsingCdf,\r\n            sphericalPolynomialTargetSize\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the texture useful for serialization or dynamic coding.\r\n     * @returns \"HDRCubeTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"HDRCubeTexture\";\r\n    }\r\n\r\n    /**\r\n     * Convert the raw data from the server into cubemap faces\r\n     * @param buffer The buffer containing the texture data\r\n     * @param size The cubemap face size\r\n     * @param supersample Defines if texture must be supersampled\r\n     * @returns The cube map data\r\n     */\r\n    protected async _getCubeMapTextureDataAsync(buffer: ArrayBuffer, size: number, supersample: boolean): Promise<CubeMapInfo> {\r\n        return GetCubeMapTextureData(buffer, size, supersample);\r\n    }\r\n\r\n    protected _instantiateClone(): this {\r\n        return new HDRCubeTexture(this.url, this.getScene() || this._getEngine()!, this._size, this._noMipmap, this._generateHarmonics, this.gammaSpace) as this;\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture to a JSON representation.\r\n     * @returns The JSON representation of the texture\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        if (!serializationObject) {\r\n            return null;\r\n        }\r\n\r\n        serializationObject.customType = \"BABYLON.HDRCubeTexture\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON representation of an HDR Texture in order to create the texture\r\n     * @param parsedTexture Define the JSON representation\r\n     * @param scene Define the scene the texture should be created in\r\n     * @param rootUrl Define the root url in case we need to load relative dependencies\r\n     * @returns the newly created texture after parsing\r\n     */\r\n    public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable<HDRCubeTexture> {\r\n        if (!parsedTexture.name || parsedTexture.isRenderTarget) {\r\n            return null;\r\n        }\r\n\r\n        const texture = new HDRCubeTexture(\r\n            rootUrl + parsedTexture.name,\r\n            scene,\r\n            parsedTexture.size,\r\n            parsedTexture.noMipmap,\r\n            parsedTexture.generateHarmonics,\r\n            parsedTexture.useInGammaSpace\r\n        );\r\n        this._Parse(parsedTexture, texture);\r\n        return texture;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for hdrCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterHdrCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.HDRCubeTexture\", HDRCubeTexture);\r\n}\r\n","import { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type Nullable, type FloatArray } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type AnimationPropertiesOverride } from \"../Animations/animationPropertiesOverride\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { GetClass } from \"../Misc/typeStore\";\r\nimport { type Animation } from \"../Animations/animation\";\r\nimport { type MorphTargetManager } from \"./morphTargetManager\";\r\n\r\n/**\r\n * Defines a target to use with MorphTargetManager\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/morphTargets\r\n */\r\nexport class MorphTarget implements IAnimatable {\r\n    /**\r\n     * Gets or sets the list of animations\r\n     */\r\n    public animations: Animation[] = [];\r\n\r\n    private _scene: Nullable<Scene>;\r\n    private _positions: Nullable<FloatArray> = null;\r\n    private _normals: Nullable<FloatArray> = null;\r\n    private _tangents: Nullable<FloatArray> = null;\r\n    private _uvs: Nullable<FloatArray> = null;\r\n    private _uv2s: Nullable<FloatArray> = null;\r\n    private _colors: Nullable<FloatArray> = null;\r\n    private _influence: number;\r\n    private _uniqueId = 0;\r\n\r\n    /**\r\n     * Observable raised when the influence changes\r\n     */\r\n    public onInfluenceChanged = new Observable<boolean>();\r\n\r\n    /** @internal */\r\n    public _onDataLayoutChanged = new Observable<void>();\r\n\r\n    /**\r\n     * Gets or sets the influence of this target (ie. its weight in the overall morphing)\r\n     */\r\n    public get influence(): number {\r\n        return this._influence;\r\n    }\r\n\r\n    public set influence(influence: number) {\r\n        if (this._influence === influence) {\r\n            return;\r\n        }\r\n\r\n        const previous = this._influence;\r\n        this._influence = influence;\r\n\r\n        if (this.onInfluenceChanged.hasObservers()) {\r\n            this.onInfluenceChanged.notifyObservers(previous === 0 || influence === 0);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the id of the morph Target\r\n     */\r\n    @serialize()\r\n    public id: string;\r\n\r\n    /**\r\n     * Gets or sets the morph target manager this morph target is associated with\r\n     */\r\n    @serialize()\r\n    public morphTargetManager: Nullable<MorphTargetManager> = null;\r\n\r\n    private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;\r\n\r\n    /**\r\n     * Gets or sets the animation properties override\r\n     */\r\n    public get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n        if (!this._animationPropertiesOverride && this._scene) {\r\n            return this._scene.animationPropertiesOverride;\r\n        }\r\n        return this._animationPropertiesOverride;\r\n    }\r\n\r\n    public set animationPropertiesOverride(value: Nullable<AnimationPropertiesOverride>) {\r\n        this._animationPropertiesOverride = value;\r\n    }\r\n\r\n    /**\r\n     * Creates a new MorphTarget\r\n     * @param name defines the name of the target\r\n     * @param influence defines the influence to use\r\n     * @param scene defines the scene the morphtarget belongs to\r\n     * @param morphTargetManager morph target manager this morph target is associated with\r\n     */\r\n    public constructor(\r\n        public name: string,\r\n        influence = 0,\r\n        scene: Nullable<Scene> = null,\r\n        morphTargetManager: Nullable<MorphTargetManager> = null\r\n    ) {\r\n        this.id = name;\r\n        this.morphTargetManager = morphTargetManager;\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        this.influence = influence;\r\n\r\n        if (this._scene) {\r\n            this._uniqueId = this._scene.getUniqueId();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the unique ID of this manager\r\n     */\r\n    public get uniqueId(): number {\r\n        return this._uniqueId;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean defining if the target contains position data\r\n     */\r\n    public get hasPositions(): boolean {\r\n        return !!this._positions;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean defining if the target contains normal data\r\n     */\r\n    public get hasNormals(): boolean {\r\n        return !!this._normals;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean defining if the target contains tangent data\r\n     */\r\n    public get hasTangents(): boolean {\r\n        return !!this._tangents;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean defining if the target contains texture coordinates data\r\n     */\r\n    public get hasUVs(): boolean {\r\n        return !!this._uvs;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean defining if the target contains texture coordinates 2 data\r\n     */\r\n    public get hasUV2s(): boolean {\r\n        return !!this._uv2s;\r\n    }\r\n\r\n    public get hasColors(): boolean {\r\n        return !!this._colors;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of vertices stored in this target\r\n     */\r\n    public get vertexCount(): number {\r\n        return this._positions\r\n            ? this._positions.length / 3\r\n            : this._normals\r\n              ? this._normals.length / 3\r\n              : this._tangents\r\n                ? this._tangents.length / 3\r\n                : this._uvs\r\n                  ? this._uvs.length / 2\r\n                  : this._uv2s\r\n                    ? this._uv2s.length / 2\r\n                    : this._colors\r\n                      ? this._colors.length / 4\r\n                      : 0;\r\n    }\r\n\r\n    /**\r\n     * Affects position data to this target\r\n     * @param data defines the position data to use\r\n     */\r\n    public setPositions(data: Nullable<FloatArray>) {\r\n        const hadPositions = this.hasPositions;\r\n\r\n        this._positions = data;\r\n\r\n        if (hadPositions !== this.hasPositions) {\r\n            this._onDataLayoutChanged.notifyObservers(undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the position data stored in this target\r\n     * @returns a FloatArray containing the position data (or null if not present)\r\n     */\r\n    public getPositions(): Nullable<FloatArray> {\r\n        return this._positions;\r\n    }\r\n\r\n    /**\r\n     * Affects normal data to this target\r\n     * @param data defines the normal data to use\r\n     */\r\n    public setNormals(data: Nullable<FloatArray>) {\r\n        const hadNormals = this.hasNormals;\r\n\r\n        this._normals = data;\r\n\r\n        if (hadNormals !== this.hasNormals) {\r\n            this._onDataLayoutChanged.notifyObservers(undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the normal data stored in this target\r\n     * @returns a FloatArray containing the normal data (or null if not present)\r\n     */\r\n    public getNormals(): Nullable<FloatArray> {\r\n        return this._normals;\r\n    }\r\n\r\n    /**\r\n     * Affects tangent data to this target\r\n     * @param data defines the tangent data to use\r\n     */\r\n    public setTangents(data: Nullable<FloatArray>) {\r\n        const hadTangents = this.hasTangents;\r\n\r\n        this._tangents = data;\r\n\r\n        if (hadTangents !== this.hasTangents) {\r\n            this._onDataLayoutChanged.notifyObservers(undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the tangent data stored in this target\r\n     * @returns a FloatArray containing the tangent data (or null if not present)\r\n     */\r\n    public getTangents(): Nullable<FloatArray> {\r\n        return this._tangents;\r\n    }\r\n\r\n    /**\r\n     * Affects texture coordinates data to this target\r\n     * @param data defines the texture coordinates data to use\r\n     */\r\n    public setUVs(data: Nullable<FloatArray>) {\r\n        const hadUVs = this.hasUVs;\r\n\r\n        this._uvs = data;\r\n\r\n        if (hadUVs !== this.hasUVs) {\r\n            this._onDataLayoutChanged.notifyObservers(undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the texture coordinates data stored in this target\r\n     * @returns a FloatArray containing the texture coordinates data (or null if not present)\r\n     */\r\n    public getUVs(): Nullable<FloatArray> {\r\n        return this._uvs;\r\n    }\r\n\r\n    /**\r\n     * Affects texture coordinates 2 data to this target\r\n     * @param data defines the texture coordinates 2 data to use\r\n     */\r\n    public setUV2s(data: Nullable<FloatArray>) {\r\n        const hadUV2s = this.hasUV2s;\r\n\r\n        this._uv2s = data;\r\n\r\n        if (hadUV2s !== this.hasUV2s) {\r\n            this._onDataLayoutChanged.notifyObservers(undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the texture coordinates 2 data stored in this target\r\n     * @returns a FloatArray containing the texture coordinates 2 data (or null if not present)\r\n     */\r\n    public getUV2s(): Nullable<FloatArray> {\r\n        return this._uv2s;\r\n    }\r\n\r\n    /**\r\n     * Affects color data to this target\r\n     * @param data defines the color data to use\r\n     */\r\n    public setColors(data: Nullable<FloatArray>) {\r\n        const hadColors = this.hasColors;\r\n\r\n        this._colors = data;\r\n\r\n        if (hadColors !== this.hasColors) {\r\n            this._onDataLayoutChanged.notifyObservers(undefined);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the color data stored in this target\r\n     * @returns a FloatArray containing the color data (or null if not present)\r\n     */\r\n    public getColors(): Nullable<FloatArray> {\r\n        return this._colors;\r\n    }\r\n\r\n    /**\r\n     * Clone the current target\r\n     * @returns a new MorphTarget\r\n     */\r\n    public clone(): MorphTarget {\r\n        const newOne = SerializationHelper.Clone(() => new MorphTarget(this.name, this.influence, this._scene, this.morphTargetManager), this);\r\n\r\n        newOne._positions = this._positions;\r\n        newOne._normals = this._normals;\r\n        newOne._tangents = this._tangents;\r\n        newOne._uvs = this._uvs;\r\n        newOne._uv2s = this._uv2s;\r\n        newOne._colors = this._colors;\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Serializes the current target into a Serialization object\r\n     * @returns the serialized object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.influence = this.influence;\r\n\r\n        if (this.id != null) {\r\n            serializationObject.id = this.id;\r\n        }\r\n        serializationObject.uniqueId = this.uniqueId;\r\n\r\n        serializationObject.positions = Array.prototype.slice.call(this.getPositions());\r\n        if (this.hasNormals) {\r\n            serializationObject.normals = Array.prototype.slice.call(this.getNormals());\r\n        }\r\n        if (this.hasTangents) {\r\n            serializationObject.tangents = Array.prototype.slice.call(this.getTangents());\r\n        }\r\n        if (this.hasUVs) {\r\n            serializationObject.uvs = Array.prototype.slice.call(this.getUVs());\r\n        }\r\n        if (this.hasUV2s) {\r\n            serializationObject.uv2s = Array.prototype.slice.call(this.getUV2s());\r\n        }\r\n        if (this.hasColors) {\r\n            serializationObject.colors = Array.prototype.slice.call(this.getColors());\r\n        }\r\n\r\n        // Animations\r\n        SerializationHelper.AppendSerializedAnimations(this, serializationObject);\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"MorphTarget\"\r\n     * @returns \"MorphTarget\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"MorphTarget\";\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Creates a new target from serialized data\r\n     * @param serializationObject defines the serialized data to use\r\n     * @param scene defines the hosting scene\r\n     * @param morphTargetManager morph target manager this morph target is associated with\r\n     * @returns a new MorphTarget\r\n     */\r\n    public static Parse(serializationObject: any, scene?: Scene, morphTargetManager: Nullable<MorphTargetManager> = null): MorphTarget {\r\n        const result = new MorphTarget(serializationObject.name, serializationObject.influence, scene, morphTargetManager);\r\n\r\n        result.setPositions(serializationObject.positions);\r\n\r\n        if (serializationObject.id != null) {\r\n            result.id = serializationObject.id;\r\n        }\r\n        if (serializationObject.normals) {\r\n            result.setNormals(serializationObject.normals);\r\n        }\r\n        if (serializationObject.tangents) {\r\n            result.setTangents(serializationObject.tangents);\r\n        }\r\n        if (serializationObject.uvs) {\r\n            result.setUVs(serializationObject.uvs);\r\n        }\r\n        if (serializationObject.uv2s) {\r\n            result.setUV2s(serializationObject.uv2s);\r\n        }\r\n        if (serializationObject.colors) {\r\n            result.setColors(serializationObject.colors);\r\n        }\r\n\r\n        // Animations\r\n        if (serializationObject.animations) {\r\n            for (let animationIndex = 0; animationIndex < serializationObject.animations.length; animationIndex++) {\r\n                const parsedAnimation = serializationObject.animations[animationIndex];\r\n                const internalClass = GetClass(\"BABYLON.Animation\");\r\n                if (internalClass) {\r\n                    result.animations.push(internalClass.Parse(parsedAnimation));\r\n                }\r\n            }\r\n\r\n            if (serializationObject.autoAnimate && scene) {\r\n                scene.beginAnimation(\r\n                    result,\r\n                    serializationObject.autoAnimateFrom,\r\n                    serializationObject.autoAnimateTo,\r\n                    serializationObject.autoAnimateLoop,\r\n                    serializationObject.autoAnimateSpeed || 1.0\r\n                );\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a MorphTarget from mesh data\r\n     * @param mesh defines the source mesh\r\n     * @param name defines the name to use for the new target\r\n     * @param influence defines the influence to attach to the target\r\n     * @returns a new MorphTarget\r\n     */\r\n    public static FromMesh(mesh: AbstractMesh, name?: string, influence?: number): MorphTarget {\r\n        if (!name) {\r\n            name = mesh.name;\r\n        }\r\n\r\n        const result = new MorphTarget(name, influence, mesh.getScene(), mesh.morphTargetManager);\r\n\r\n        result.setPositions(<FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind));\r\n\r\n        if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {\r\n            result.setNormals(<FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind));\r\n        }\r\n        if (mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {\r\n            result.setTangents(<FloatArray>mesh.getVerticesData(VertexBuffer.TangentKind));\r\n        }\r\n        if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n            result.setUVs(<FloatArray>mesh.getVerticesData(VertexBuffer.UVKind));\r\n        }\r\n        if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n            result.setUV2s(<FloatArray>mesh.getVerticesData(VertexBuffer.UV2Kind));\r\n        }\r\n        if (mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {\r\n            result.setColors(<FloatArray>mesh.getVerticesData(VertexBuffer.ColorKind));\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n","import { Texture } from \"./texture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\nimport { type Scene } from \"../../scene\";\r\n\r\n/**\r\n * Class used to store 2D array textures containing user data\r\n */\r\nexport class RawTexture2DArray extends Texture {\r\n    private _depth: number;\r\n\r\n    /**\r\n     * Gets the number of layers of the texture\r\n     */\r\n    public get depth() {\r\n        return this._depth;\r\n    }\r\n\r\n    /**\r\n     * Create a new RawTexture2DArray\r\n     * @param data defines the data of the texture\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @param depth defines the number of layers of the texture\r\n     * @param format defines the texture format to use\r\n     * @param scene defines the hosting scene\r\n     * @param generateMipMaps defines a boolean indicating if mip levels should be generated (true by default)\r\n     * @param invertY defines if texture must be stored with Y axis inverted\r\n     * @param samplingMode defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default)\r\n     * @param textureType defines the texture Type (Engine.TEXTURETYPE_UNSIGNED_BYTE, Engine.TEXTURETYPE_FLOAT...)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     * @param mipLevelCount defines the number of mip levels to allocate for the texture\r\n     */\r\n    constructor(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        /** Gets or sets the texture format to use */\r\n        public format: number,\r\n        scene: Scene,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags?: number,\r\n        mipLevelCount?: number\r\n    ) {\r\n        super(null, scene, !generateMipMaps, invertY);\r\n\r\n        this._texture = scene\r\n            .getEngine()\r\n            .createRawTexture2DArray(data, width, height, depth, format, generateMipMaps, invertY, samplingMode, null, textureType, creationFlags ?? 0, mipLevelCount);\r\n\r\n        this._depth = depth;\r\n        this.is2DArray = true;\r\n    }\r\n\r\n    /**\r\n     * Update the texture with new data\r\n     * @param data defines the data to store in the texture\r\n     */\r\n    public update(data: ArrayBufferView): void {\r\n        this.updateMipLevel(data, 0);\r\n    }\r\n\r\n    /**\r\n     * Updates a specific mip level of the texture.\r\n     * @param data The new data for the mip level\r\n     * @param mipLevel The mip level to update (0 is the base level)\r\n     */\r\n    public updateMipLevel(data: ArrayBufferView, mipLevel: number): void {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n        this._getEngine()!.updateRawTexture2DArray(this._texture, data, this._texture.format, this._texture.invertY, null, this._texture.type, mipLevel);\r\n    }\r\n\r\n    /**\r\n     * Creates a RGBA texture from some data.\r\n     * @param data Define the texture data\r\n     * @param width Define the width of the texture\r\n     * @param height Define the height of the texture\r\n     * @param depth defines the number of layers of the texture\r\n     * @param scene defines the scene the texture will belong to\r\n     * @param generateMipMaps Define whether or not to create mip maps for the texture\r\n     * @param invertY define if the data should be flipped on Y when uploaded to the GPU\r\n     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)\r\n     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)\r\n     * @returns the RGBA texture\r\n     */\r\n    public static CreateRGBATexture(\r\n        data: ArrayBufferView,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        scene: Scene,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ): RawTexture2DArray {\r\n        return new RawTexture2DArray(data, width, height, depth, Constants.TEXTUREFORMAT_RGBA, scene, generateMipMaps, invertY, samplingMode, type);\r\n    }\r\n}\r\n","import { type Observer } from \"../Misc/observable\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type IDisposable, type Scene } from \"../scene\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { MorphTarget } from \"./morphTarget\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { RawTexture2DArray } from \"../Materials/Textures/rawTexture2DArray\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\n/**\r\n * This class is used to deform meshes using morphing between different targets\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/morphTargets\r\n */\r\nexport class MorphTargetManager implements IDisposable {\r\n    /** Enable storing morph target data into textures when set to true (true by default) */\r\n    public static EnableTextureStorage = true;\r\n\r\n    /** Maximum number of active morph targets supported in the \"vertex attribute\" mode (i.e., not the \"texture\" mode) */\r\n    public static MaxActiveMorphTargetsInVertexAttributeMode = 8;\r\n\r\n    /**\r\n     * When used in texture mode, if greather than 0, this will override the the morph manager numMaxInfluencers value.\r\n     */\r\n    public static ConstantTargetCountForTextureMode = 0;\r\n\r\n    private _targets = new Array<MorphTarget>();\r\n    private _targetInfluenceChangedObservers = new Array<Nullable<Observer<boolean>>>();\r\n    private _targetDataLayoutChangedObservers = new Array<Nullable<Observer<void>>>();\r\n    private _activeTargets = new SmartArray<MorphTarget>(16);\r\n    private _scene: Nullable<Scene>;\r\n    private _influences: Float32Array;\r\n    private _supportsPositions = false;\r\n    private _supportsNormals = false;\r\n    private _supportsTangents = false;\r\n    private _supportsUVs = false;\r\n    private _supportsUV2s = false;\r\n    private _supportsColors = false;\r\n    private _vertexCount = 0;\r\n    private _uniqueId = 0;\r\n    private _tempInfluences = new Array<number>();\r\n    private _canUseTextureForTargets = false;\r\n    private _blockCounter = 0;\r\n    private _mustSynchronize = true;\r\n    private _forceUpdateWhenUnfrozen = false;\r\n\r\n    /** @internal */\r\n    public _textureVertexStride = 0;\r\n\r\n    /** @internal */\r\n    public _textureWidth = 0;\r\n\r\n    /** @internal */\r\n    public _textureHeight = 1;\r\n\r\n    /** @internal */\r\n    public _morphTargetTextureIndices: Float32Array;\r\n\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /** @internal */\r\n    public _targetStoreTexture: Nullable<RawTexture2DArray>;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if influencers must be optimized (eg. recompiling the shader if less influencers are used)\r\n     */\r\n    public optimizeInfluencers = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if positions must be morphed\r\n     */\r\n    public enablePositionMorphing = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if normals must be morphed\r\n     */\r\n    public enableNormalMorphing = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if tangents must be morphed\r\n     */\r\n    public enableTangentMorphing = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if UV must be morphed\r\n     */\r\n    public enableUVMorphing = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if UV2 must be morphed\r\n     */\r\n    public enableUV2Morphing = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if colors must be morphed\r\n     */\r\n    public enableColorMorphing = true;\r\n\r\n    /**\r\n     * Sets a boolean indicating that adding new target or updating an existing target will not update the underlying data buffers\r\n     */\r\n    public set areUpdatesFrozen(block: boolean) {\r\n        if (block) {\r\n            this._blockCounter++;\r\n        } else {\r\n            this._blockCounter--;\r\n            if (this._blockCounter <= 0) {\r\n                this._blockCounter = 0;\r\n\r\n                this._syncActiveTargets(this._forceUpdateWhenUnfrozen);\r\n                this._forceUpdateWhenUnfrozen = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    public get areUpdatesFrozen() {\r\n        return this._blockCounter > 0;\r\n    }\r\n\r\n    /**\r\n     * Creates a new MorphTargetManager\r\n     * @param scene defines the current scene\r\n     * @param meshName name of the mesh this morph target manager is associated with\r\n     */\r\n    public constructor(\r\n        scene: Nullable<Scene> = null,\r\n        public meshName?: string\r\n    ) {\r\n        if (!scene) {\r\n            scene = EngineStore.LastCreatedScene;\r\n        }\r\n\r\n        this._scene = scene;\r\n\r\n        if (this._scene) {\r\n            this._scene.addMorphTargetManager(this);\r\n\r\n            this._uniqueId = this._scene.getUniqueId();\r\n\r\n            const engineCaps = this._scene.getEngine().getCaps();\r\n            this._canUseTextureForTargets =\r\n                engineCaps.canUseGLVertexID && engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0 && engineCaps.texture2DArrayMaxLayerCount > 1;\r\n        }\r\n    }\r\n\r\n    private _numMaxInfluencers = 0;\r\n\r\n    /**\r\n     * Gets or sets the maximum number of influencers (targets) (default value: 0).\r\n     * Setting a value for this property can lead to a smoother experience, as only one shader will be compiled, which will use this value as the maximum number of influencers.\r\n     * If you leave the value at 0 (default), a new shader will be compiled every time the number of active influencers changes. This can cause problems, as compiling a shader takes time.\r\n     * If you assign a non-zero value to this property, you need to ensure that this value is greater than the maximum number of (active) influencers you'll need for this morph manager.\r\n     * Otherwise, the number of active influencers will be truncated at the value you set for this property, which can lead to unexpected results.\r\n     * Note that this property has no effect if \"useTextureToStoreTargets\" is false.\r\n     * Note as well that if MorphTargetManager.ConstantTargetCountForTextureMode is greater than 0, this property will be ignored and the constant value will be used instead.\r\n     */\r\n    public get numMaxInfluencers(): number {\r\n        if (MorphTargetManager.ConstantTargetCountForTextureMode > 0 && this.isUsingTextureForTargets) {\r\n            return MorphTargetManager.ConstantTargetCountForTextureMode;\r\n        }\r\n        return this._numMaxInfluencers;\r\n    }\r\n\r\n    public set numMaxInfluencers(value: number) {\r\n        if (this._numMaxInfluencers === value) {\r\n            return;\r\n        }\r\n\r\n        this._numMaxInfluencers = value;\r\n        this._mustSynchronize = true;\r\n        this._syncActiveTargets();\r\n    }\r\n\r\n    /**\r\n     * Gets the unique ID of this manager\r\n     */\r\n    public get uniqueId(): number {\r\n        return this._uniqueId;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of vertices handled by this manager\r\n     */\r\n    public get vertexCount(): number {\r\n        return this._vertexCount;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager supports morphing of positions\r\n     */\r\n    public get supportsPositions(): boolean {\r\n        return this._supportsPositions && this.enablePositionMorphing;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager supports morphing of normals\r\n     */\r\n    public get supportsNormals(): boolean {\r\n        return this._supportsNormals && this.enableNormalMorphing;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager supports morphing of tangents\r\n     */\r\n    public get supportsTangents(): boolean {\r\n        return this._supportsTangents && this.enableTangentMorphing;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager supports morphing of texture coordinates\r\n     */\r\n    public get supportsUVs(): boolean {\r\n        return this._supportsUVs && this.enableUVMorphing;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager supports morphing of texture coordinates 2\r\n     */\r\n    public get supportsUV2s(): boolean {\r\n        return this._supportsUV2s && this.enableUV2Morphing;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager supports morphing of colors\r\n     */\r\n    public get supportsColors(): boolean {\r\n        return this._supportsColors && this.enableColorMorphing;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager has data for morphing positions\r\n     */\r\n    public get hasPositions(): boolean {\r\n        return this._supportsPositions;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager has data for morphing normals\r\n     */\r\n    public get hasNormals(): boolean {\r\n        return this._supportsNormals;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager has data for morphing tangents\r\n     */\r\n    public get hasTangents(): boolean {\r\n        return this._supportsTangents;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager has data for morphing texture coordinates\r\n     */\r\n    public get hasUVs(): boolean {\r\n        return this._supportsUVs;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager has data for morphing texture coordinates 2\r\n     */\r\n    public get hasUV2s(): boolean {\r\n        return this._supportsUV2s;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this manager has data for morphing colors\r\n     */\r\n    public get hasColors(): boolean {\r\n        return this._supportsColors;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of targets stored in this manager\r\n     */\r\n    public get numTargets(): number {\r\n        return this._targets.length;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of influencers (ie. the number of targets with influences > 0)\r\n     */\r\n    public get numInfluencers(): number {\r\n        if (this._influencesAreDirty) {\r\n            this._syncActiveTargets();\r\n        }\r\n        return this._activeTargets.length;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of influences (one per target)\r\n     */\r\n    public get influences(): Float32Array {\r\n        if (this._influencesAreDirty) {\r\n            this._syncActiveTargets();\r\n        }\r\n        return this._influences;\r\n    }\r\n\r\n    private _useTextureToStoreTargets = true;\r\n    /**\r\n     * Gets or sets a boolean indicating that targets should be stored as a texture instead of using vertex attributes (default is true).\r\n     * Please note that this option is not available if the hardware does not support it\r\n     */\r\n    public get useTextureToStoreTargets(): boolean {\r\n        return this._useTextureToStoreTargets;\r\n    }\r\n\r\n    public set useTextureToStoreTargets(value: boolean) {\r\n        if (this._useTextureToStoreTargets === value) {\r\n            return;\r\n        }\r\n        this._useTextureToStoreTargets = value;\r\n        this._mustSynchronize = true;\r\n        this._syncActiveTargets();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the targets are stored into a texture (instead of as attributes)\r\n     */\r\n    public get isUsingTextureForTargets() {\r\n        return (\r\n            MorphTargetManager.EnableTextureStorage &&\r\n            this.useTextureToStoreTargets &&\r\n            this._canUseTextureForTargets &&\r\n            !this._scene?.getEngine().getCaps().disableMorphTargetTexture\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the MorphTargetManager\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /**\r\n     * Gets the active target at specified index. An active target is a target with an influence > 0\r\n     * @param index defines the index to check\r\n     * @returns the requested target\r\n     */\r\n    public getActiveTarget(index: number): MorphTarget {\r\n        if (this._influencesAreDirty) {\r\n            this._syncActiveTargets();\r\n        }\r\n        return this._activeTargets.data[index];\r\n    }\r\n\r\n    /**\r\n     * Gets the target at specified index\r\n     * @param index defines the index to check\r\n     * @returns the requested target\r\n     */\r\n    public getTarget(index: number): MorphTarget {\r\n        return this._targets[index];\r\n    }\r\n\r\n    /**\r\n     * Gets the first target with the specified name\r\n     * @param name defines the name to check\r\n     * @returns the requested target\r\n     */\r\n    public getTargetByName(name: string): Nullable<MorphTarget> {\r\n        for (const target of this._targets) {\r\n            if (target.name === name) {\r\n                return target;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    private _influencesAreDirty = false;\r\n    private _needUpdateInfluences = false;\r\n\r\n    /**\r\n     * Add a new target to this manager\r\n     * @param target defines the target to add\r\n     */\r\n    public addTarget(target: MorphTarget): void {\r\n        this._targets.push(target);\r\n        this._targetInfluenceChangedObservers.push(\r\n            target.onInfluenceChanged.add((needUpdate) => {\r\n                if (this.areUpdatesFrozen && needUpdate) {\r\n                    this._forceUpdateWhenUnfrozen = true;\r\n                }\r\n                this._influencesAreDirty = true;\r\n                this._needUpdateInfluences = this._needUpdateInfluences || needUpdate;\r\n            })\r\n        );\r\n        this._targetDataLayoutChangedObservers.push(\r\n            target._onDataLayoutChanged.add(() => {\r\n                this._mustSynchronize = true;\r\n                this._syncActiveTargets();\r\n            })\r\n        );\r\n        this._mustSynchronize = true;\r\n        this._syncActiveTargets();\r\n    }\r\n\r\n    /**\r\n     * Removes a target from the manager\r\n     * @param target defines the target to remove\r\n     */\r\n    public removeTarget(target: MorphTarget): void {\r\n        const index = this._targets.indexOf(target);\r\n        if (index >= 0) {\r\n            this._targets.splice(index, 1);\r\n\r\n            target.onInfluenceChanged.remove(this._targetInfluenceChangedObservers.splice(index, 1)[0]);\r\n            target._onDataLayoutChanged.remove(this._targetDataLayoutChangedObservers.splice(index, 1)[0]);\r\n            this._mustSynchronize = true;\r\n            this._syncActiveTargets();\r\n        }\r\n\r\n        if (this._scene) {\r\n            this._scene.stopAnimation(target);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _bind(effect: Effect) {\r\n        if (this._influencesAreDirty) {\r\n            this._syncActiveTargets();\r\n        }\r\n        effect.setFloat3(\"morphTargetTextureInfo\", this._textureVertexStride, this._textureWidth, this._textureHeight);\r\n        effect.setFloatArray(\"morphTargetTextureIndices\", this._morphTargetTextureIndices);\r\n        effect.setTexture(\"morphTargets\", this._targetStoreTexture);\r\n        effect.setFloat(\"morphTargetCount\", this.numInfluencers);\r\n    }\r\n\r\n    /**\r\n     * Clone the current manager\r\n     * @returns a new MorphTargetManager\r\n     */\r\n    public clone(): MorphTargetManager {\r\n        const copy = new MorphTargetManager(this._scene);\r\n        copy.areUpdatesFrozen = true;\r\n\r\n        for (const target of this._targets) {\r\n            copy.addTarget(target.clone());\r\n        }\r\n        copy.areUpdatesFrozen = false;\r\n\r\n        copy.enablePositionMorphing = this.enablePositionMorphing;\r\n        copy.enableNormalMorphing = this.enableNormalMorphing;\r\n        copy.enableTangentMorphing = this.enableTangentMorphing;\r\n        copy.enableUVMorphing = this.enableUVMorphing;\r\n        copy.enableUV2Morphing = this.enableUV2Morphing;\r\n        copy.enableColorMorphing = this.enableColorMorphing;\r\n        copy.metadata = this.metadata;\r\n\r\n        return copy;\r\n    }\r\n\r\n    /**\r\n     * Serializes the current manager into a Serialization object\r\n     * @returns the serialized object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.id = this.uniqueId;\r\n        serializationObject.meshName = this.meshName;\r\n\r\n        serializationObject.targets = [];\r\n        for (const target of this._targets) {\r\n            serializationObject.targets.push(target.serialize());\r\n        }\r\n\r\n        if (this.metadata) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    private _syncActiveTargets(needUpdate = false): void {\r\n        if (this.areUpdatesFrozen) {\r\n            return;\r\n        }\r\n\r\n        needUpdate = needUpdate || this._needUpdateInfluences;\r\n\r\n        this._needUpdateInfluences = false;\r\n        this._influencesAreDirty = false;\r\n\r\n        const wasUsingTextureForTargets = !!this._targetStoreTexture;\r\n        const isUsingTextureForTargets = this.isUsingTextureForTargets;\r\n\r\n        if (this._mustSynchronize || wasUsingTextureForTargets !== isUsingTextureForTargets) {\r\n            this._mustSynchronize = false;\r\n            this.synchronize();\r\n        }\r\n\r\n        let influenceCount = 0;\r\n        this._activeTargets.reset();\r\n\r\n        if (!this._morphTargetTextureIndices || this._morphTargetTextureIndices.length !== this._targets.length) {\r\n            this._morphTargetTextureIndices = new Float32Array(this._targets.length);\r\n        }\r\n\r\n        let targetIndex = -1;\r\n        for (const target of this._targets) {\r\n            targetIndex++;\r\n            if (target.influence === 0 && this.optimizeInfluencers) {\r\n                continue;\r\n            }\r\n\r\n            if (this._activeTargets.length >= MorphTargetManager.MaxActiveMorphTargetsInVertexAttributeMode && !this.isUsingTextureForTargets) {\r\n                break;\r\n            }\r\n\r\n            this._activeTargets.push(target);\r\n            this._morphTargetTextureIndices[influenceCount] = targetIndex;\r\n            this._tempInfluences[influenceCount++] = target.influence;\r\n        }\r\n\r\n        if (this._morphTargetTextureIndices.length !== influenceCount) {\r\n            this._morphTargetTextureIndices = this._morphTargetTextureIndices.slice(0, influenceCount);\r\n        }\r\n\r\n        if (!this._influences || this._influences.length !== influenceCount) {\r\n            this._influences = new Float32Array(influenceCount);\r\n        }\r\n\r\n        for (let index = 0; index < influenceCount; index++) {\r\n            this._influences[index] = this._tempInfluences[index];\r\n        }\r\n\r\n        if (needUpdate && this._scene) {\r\n            for (const mesh of this._scene.meshes) {\r\n                if ((<any>mesh).morphTargetManager === this) {\r\n                    if (isUsingTextureForTargets) {\r\n                        mesh._markSubMeshesAsAttributesDirty();\r\n                    } else {\r\n                        (<Mesh>mesh)._syncGeometryWithMorphTargetManager();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Synchronize the targets with all the meshes using this morph target manager\r\n     */\r\n    public synchronize(): void {\r\n        if (!this._scene || this.areUpdatesFrozen) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        this._supportsPositions = true;\r\n        this._supportsNormals = true;\r\n        this._supportsTangents = true;\r\n        this._supportsUVs = true;\r\n        this._supportsUV2s = true;\r\n        this._supportsColors = true;\r\n        this._vertexCount = 0;\r\n\r\n        this._targetStoreTexture?.dispose();\r\n        this._targetStoreTexture = null;\r\n\r\n        if (this.isUsingTextureForTargets && this._targets.length > engine.getCaps().texture2DArrayMaxLayerCount) {\r\n            this.useTextureToStoreTargets = false;\r\n        }\r\n\r\n        for (const target of this._targets) {\r\n            this._supportsPositions = this._supportsPositions && target.hasPositions;\r\n            this._supportsNormals = this._supportsNormals && target.hasNormals;\r\n            this._supportsTangents = this._supportsTangents && target.hasTangents;\r\n            this._supportsUVs = this._supportsUVs && target.hasUVs;\r\n            this._supportsUV2s = this._supportsUV2s && target.hasUV2s;\r\n            this._supportsColors = this._supportsColors && target.hasColors;\r\n\r\n            const vertexCount = target.vertexCount;\r\n            if (this._vertexCount === 0) {\r\n                this._vertexCount = vertexCount;\r\n            } else if (this._vertexCount !== vertexCount) {\r\n                Logger.Error(\r\n                    `Incompatible target. Targets must all have the same vertices count. Current vertex count: ${this._vertexCount}, vertex count for target \"${target.name}\": ${vertexCount}`\r\n                );\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (this.isUsingTextureForTargets) {\r\n            this._textureVertexStride = 0;\r\n\r\n            this._supportsPositions && this._textureVertexStride++;\r\n            this._supportsNormals && this._textureVertexStride++;\r\n            this._supportsTangents && this._textureVertexStride++;\r\n            this._supportsUVs && this._textureVertexStride++;\r\n            this._supportsUV2s && this._textureVertexStride++;\r\n            this._supportsColors && this._textureVertexStride++;\r\n\r\n            this._textureWidth = this._vertexCount * this._textureVertexStride || 1;\r\n            this._textureHeight = 1;\r\n\r\n            const maxTextureSize = engine.getCaps().maxTextureSize;\r\n            if (this._textureWidth > maxTextureSize) {\r\n                this._textureHeight = Math.ceil(this._textureWidth / maxTextureSize);\r\n                this._textureWidth = maxTextureSize;\r\n            }\r\n\r\n            const targetCount = this._targets.length;\r\n            const data = new Float32Array(targetCount * this._textureWidth * this._textureHeight * 4);\r\n\r\n            let offset: number;\r\n            for (let index = 0; index < targetCount; index++) {\r\n                const target = this._targets[index];\r\n\r\n                const positions = target.getPositions();\r\n                const normals = target.getNormals();\r\n                const uvs = target.getUVs();\r\n                const tangents = target.getTangents();\r\n                const uv2s = target.getUV2s();\r\n                const colors = target.getColors();\r\n\r\n                offset = index * this._textureWidth * this._textureHeight * 4;\r\n                for (let vertex = 0; vertex < this._vertexCount; vertex++) {\r\n                    if (this._supportsPositions && positions) {\r\n                        data[offset] = positions[vertex * 3];\r\n                        data[offset + 1] = positions[vertex * 3 + 1];\r\n                        data[offset + 2] = positions[vertex * 3 + 2];\r\n                        offset += 4;\r\n                    }\r\n\r\n                    if (this._supportsNormals && normals) {\r\n                        data[offset] = normals[vertex * 3];\r\n                        data[offset + 1] = normals[vertex * 3 + 1];\r\n                        data[offset + 2] = normals[vertex * 3 + 2];\r\n                        offset += 4;\r\n                    }\r\n\r\n                    if (this._supportsUVs && uvs) {\r\n                        data[offset] = uvs[vertex * 2];\r\n                        data[offset + 1] = uvs[vertex * 2 + 1];\r\n                        offset += 4;\r\n                    }\r\n\r\n                    if (this._supportsTangents && tangents) {\r\n                        data[offset] = tangents[vertex * 3];\r\n                        data[offset + 1] = tangents[vertex * 3 + 1];\r\n                        data[offset + 2] = tangents[vertex * 3 + 2];\r\n                        offset += 4;\r\n                    }\r\n\r\n                    if (this._supportsUV2s && uv2s) {\r\n                        data[offset] = uv2s[vertex * 2];\r\n                        data[offset + 1] = uv2s[vertex * 2 + 1];\r\n                        offset += 4;\r\n                    }\r\n\r\n                    if (this._supportsColors && colors) {\r\n                        data[offset] = colors[vertex * 4];\r\n                        data[offset + 1] = colors[vertex * 4 + 1];\r\n                        data[offset + 2] = colors[vertex * 4 + 2];\r\n                        data[offset + 3] = colors[vertex * 4 + 3];\r\n                        offset += 4;\r\n                    }\r\n                }\r\n            }\r\n\r\n            this._targetStoreTexture = RawTexture2DArray.CreateRGBATexture(\r\n                data,\r\n                this._textureWidth,\r\n                this._textureHeight,\r\n                targetCount,\r\n                this._scene,\r\n                false,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                Constants.TEXTURETYPE_FLOAT\r\n            );\r\n            this._targetStoreTexture.name = `Morph texture_${this.uniqueId}`;\r\n        }\r\n\r\n        // Flag meshes as dirty to resync with the active targets\r\n        for (const mesh of this._scene.meshes) {\r\n            if ((<any>mesh).morphTargetManager === this) {\r\n                (<Mesh>mesh)._syncGeometryWithMorphTargetManager();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release all resources\r\n     */\r\n    public dispose() {\r\n        if (this._targetStoreTexture) {\r\n            this._targetStoreTexture.dispose();\r\n        }\r\n\r\n        this._targetStoreTexture = null;\r\n        this.metadata = null;\r\n\r\n        // Remove from scene\r\n        if (this._scene) {\r\n            this._scene.removeMorphTargetManager(this);\r\n\r\n            if (this._parentContainer) {\r\n                const index = this._parentContainer.morphTargetManagers.indexOf(this);\r\n                if (index > -1) {\r\n                    this._parentContainer.morphTargetManagers.splice(index, 1);\r\n                }\r\n                this._parentContainer = null;\r\n            }\r\n\r\n            for (const morph of this._targets) {\r\n                this._scene.stopAnimation(morph);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Statics\r\n\r\n    /**\r\n     * Creates a new MorphTargetManager from serialized data\r\n     * @param serializationObject defines the serialized data\r\n     * @param scene defines the hosting scene\r\n     * @returns the new MorphTargetManager\r\n     */\r\n    public static Parse(serializationObject: any, scene: Scene): MorphTargetManager {\r\n        const result = new MorphTargetManager(scene);\r\n\r\n        for (const targetData of serializationObject.targets) {\r\n            result.addTarget(MorphTarget.Parse(targetData, scene, result));\r\n        }\r\n\r\n        if (serializationObject.metadata) {\r\n            result.metadata = serializationObject.metadata;\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { serializeAsMeshReference, serializeAsVector3 } from \"../Misc/decorators\";\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\nimport { type Nullable } from \"../types\";\nimport { Scene } from \"../scene.pure\";\nimport { Constants } from \"../Engines/constants\";\nimport { type UniformBuffer } from \"../Materials/uniformBuffer\";\nimport { type IAssetContainer } from \"core/IAssetContainer\";\n\n/**\n * Class used to generate realtime reflection / refraction cube textures\n * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/reflectionProbes\n */\nexport class ReflectionProbe {\n    private _scene: Scene;\n    private _renderTargetTexture: RenderTargetTexture;\n    private _projectionMatrix: Matrix;\n    private _viewMatrix = Matrix.Identity();\n    private _target = Vector3.Zero();\n    private _add = Vector3.Zero();\n    @serializeAsMeshReference()\n    private _attachedMesh: Nullable<AbstractMesh>;\n\n    private _invertYAxis = false;\n    private _sceneUBOs: UniformBuffer[];\n    private _currentSceneUBO: UniformBuffer;\n\n    /** Gets or sets probe position (center of the cube map) */\n    @serializeAsVector3()\n    public position = Vector3.Zero();\n\n    /**\n     * Gets or sets an object used to store user defined information for the reflection probe.\n     */\n    public metadata: any = null;\n\n    /** @internal */\n    public _parentContainer: Nullable<IAssetContainer> = null;\n\n    /**\n     * Creates a new reflection probe\n     * @param name defines the name of the probe\n     * @param size defines the texture resolution (for each face)\n     * @param scene defines the hosting scene\n     * @param generateMipMaps defines if mip maps should be generated automatically (true by default)\n     * @param useFloat defines if HDR data (float data) should be used to store colors (false by default)\n     * @param linearSpace defines if the probe should be generated in linear space or not (false by default)\n     */\n    constructor(\n        /** defines the name of the probe */\n        public name: string,\n        size: number,\n        scene: Scene,\n        generateMipMaps = true,\n        useFloat = false,\n        linearSpace = false\n    ) {\n        this._scene = scene;\n\n        // Create the scene field if not exist.\n        if (!this._scene.reflectionProbes) {\n            this._scene.reflectionProbes = [] as ReflectionProbe[];\n        }\n        this._scene.reflectionProbes.push(this);\n\n        if (scene.getEngine().supportsUniformBuffers) {\n            this._sceneUBOs = [];\n            for (let i = 0; i < 6; ++i) {\n                this._sceneUBOs.push(scene.createSceneUniformBuffer(`Scene for Reflection Probe (name \"${name}\") face #${i}`, { forceMono: true }));\n            }\n        }\n\n        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\n        if (useFloat) {\n            const caps = this._scene.getEngine().getCaps();\n            if (caps.textureHalfFloatRender) {\n                textureType = Constants.TEXTURETYPE_HALF_FLOAT;\n            } else if (caps.textureFloatRender) {\n                textureType = Constants.TEXTURETYPE_FLOAT;\n            }\n        }\n        this._renderTargetTexture = new RenderTargetTexture(name, size, scene, generateMipMaps, true, textureType, true);\n        this._renderTargetTexture.gammaSpace = !linearSpace;\n        this._renderTargetTexture.invertZ = scene.useRightHandedSystem;\n\n        const useReverseDepthBuffer = scene.getEngine().useReverseDepthBuffer;\n\n        this._renderTargetTexture.onBeforeRenderObservable.add((faceIndex: number) => {\n            if (this._sceneUBOs) {\n                scene.setSceneUniformBuffer(this._sceneUBOs[faceIndex]);\n                scene.getSceneUniformBuffer().unbindEffect();\n            }\n            switch (faceIndex) {\n                case 0:\n                    this._add.copyFromFloats(1, 0, 0);\n                    break;\n                case 1:\n                    this._add.copyFromFloats(-1, 0, 0);\n                    break;\n                case 2:\n                    this._add.copyFromFloats(0, this._invertYAxis ? 1 : -1, 0);\n                    break;\n                case 3:\n                    this._add.copyFromFloats(0, this._invertYAxis ? -1 : 1, 0);\n                    break;\n                case 4:\n                    this._add.copyFromFloats(0, 0, scene.useRightHandedSystem ? -1 : 1);\n                    break;\n                case 5:\n                    this._add.copyFromFloats(0, 0, scene.useRightHandedSystem ? 1 : -1);\n                    break;\n            }\n\n            if (this._attachedMesh) {\n                this.position.copyFrom(this._attachedMesh.getAbsolutePosition());\n            }\n\n            this.position.addToRef(this._add, this._target);\n\n            const lookAtFunction = scene.useRightHandedSystem ? Matrix.LookAtRHToRef : Matrix.LookAtLHToRef;\n            const perspectiveFunction = scene.useRightHandedSystem ? Matrix.PerspectiveFovRH : Matrix.PerspectiveFovLH;\n\n            lookAtFunction(this.position, this._target, Vector3.Up(), this._viewMatrix);\n\n            if (scene.activeCamera) {\n                this._projectionMatrix = perspectiveFunction(\n                    Math.PI / 2,\n                    1,\n                    useReverseDepthBuffer ? scene.activeCamera.maxZ : scene.activeCamera.minZ,\n                    useReverseDepthBuffer ? scene.activeCamera.minZ : scene.activeCamera.maxZ,\n                    this._scene.getEngine().isNDCHalfZRange\n                );\n                scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);\n                if (scene.activeCamera.isRigCamera && !this._renderTargetTexture.activeCamera) {\n                    this._renderTargetTexture.activeCamera = scene.activeCamera.rigParent || null;\n                }\n            }\n            if (this._sceneUBOs) {\n                scene.finalizeSceneUbo();\n            }\n            scene._forcedViewPosition = this.position;\n        });\n\n        let currentApplyByPostProcess: boolean;\n\n        this._renderTargetTexture.onBeforeBindObservable.add(() => {\n            const engine = scene.getEngine();\n            this._currentSceneUBO = scene.getSceneUniformBuffer();\n            if (engine._enableGPUDebugMarkers) {\n                engine._debugPushGroup?.(`reflection probe generation for ${name}`);\n            }\n            currentApplyByPostProcess = this._scene.imageProcessingConfiguration.applyByPostProcess;\n            if (linearSpace) {\n                scene.imageProcessingConfiguration.applyByPostProcess = true;\n            }\n        });\n\n        this._renderTargetTexture.onAfterUnbindObservable.add(() => {\n            const engine = scene.getEngine();\n            scene.imageProcessingConfiguration.applyByPostProcess = currentApplyByPostProcess;\n            scene._forcedViewPosition = null;\n            if (this._sceneUBOs) {\n                scene.setSceneUniformBuffer(this._currentSceneUBO);\n            }\n            scene.updateTransformMatrix(true);\n            if (engine._enableGPUDebugMarkers) {\n                engine._debugPopGroup?.();\n            }\n        });\n    }\n\n    /** Gets or sets the number of samples to use for multi-sampling (0 by default). Required WebGL2 */\n    public get samples(): number {\n        return this._renderTargetTexture.samples;\n    }\n\n    public set samples(value: number) {\n        this._renderTargetTexture.samples = value;\n    }\n\n    /** Gets or sets the refresh rate to use (on every frame by default) */\n    public get refreshRate(): number {\n        return this._renderTargetTexture.refreshRate;\n    }\n\n    public set refreshRate(value: number) {\n        this._renderTargetTexture.refreshRate = value;\n    }\n\n    /**\n     * Gets the hosting scene\n     * @returns a Scene\n     */\n    public getScene(): Scene {\n        return this._scene;\n    }\n\n    /** Gets the internal CubeTexture used to render to */\n    public get cubeTexture(): RenderTargetTexture {\n        return this._renderTargetTexture;\n    }\n\n    /** Gets or sets the list of meshes to render */\n    public get renderList(): Nullable<AbstractMesh[]> {\n        return this._renderTargetTexture.renderList;\n    }\n\n    public set renderList(value: Nullable<AbstractMesh[]>) {\n        this._renderTargetTexture.renderList = value;\n    }\n\n    /**\n     * Attach the probe to a specific mesh (Rendering will be done from attached mesh's position)\n     * @param mesh defines the mesh to attach to\n     */\n    public attachToMesh(mesh: Nullable<AbstractMesh>): void {\n        this._attachedMesh = mesh;\n    }\n\n    /**\n     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups\n     * @param renderingGroupId The rendering group id corresponding to its index\n     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\n     */\n    public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean): void {\n        this._renderTargetTexture.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);\n    }\n\n    /**\n     * Clean all associated resources\n     */\n    public dispose() {\n        const index = this._scene.reflectionProbes.indexOf(this);\n\n        if (index !== -1) {\n            // Remove from the scene if found\n            this._scene.reflectionProbes.splice(index, 1);\n        }\n\n        if (this._parentContainer) {\n            const index = this._parentContainer.reflectionProbes.indexOf(this);\n            if (index > -1) {\n                this._parentContainer.reflectionProbes.splice(index, 1);\n            }\n            this._parentContainer = null;\n        }\n\n        if (this._renderTargetTexture) {\n            this._renderTargetTexture.dispose();\n            (<any>this._renderTargetTexture) = null;\n        }\n\n        if (this._sceneUBOs) {\n            for (const ubo of this._sceneUBOs) {\n                ubo.dispose();\n            }\n            this._sceneUBOs = [];\n        }\n    }\n\n    /**\n     * Converts the reflection probe information to a readable string for debug purpose.\n     * @param fullDetails Supports for multiple levels of logging within scene loading\n     * @returns the human readable reflection probe info\n     */\n    public toString(fullDetails?: boolean): string {\n        let ret = \"Name: \" + this.name;\n\n        if (fullDetails) {\n            ret += \", position: \" + this.position.toString();\n\n            if (this._attachedMesh) {\n                ret += \", attached mesh: \" + this._attachedMesh.name;\n            }\n        }\n\n        return ret;\n    }\n\n    /**\n     * Get the class name of the refection probe.\n     * @returns \"ReflectionProbe\"\n     */\n    public getClassName(): string {\n        return \"ReflectionProbe\";\n    }\n\n    /**\n     * Serialize the reflection probe to a JSON representation we can easily use in the respective Parse function.\n     * @returns The JSON representation of the texture\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this, this._renderTargetTexture.serialize());\n        serializationObject.isReflectionProbe = true;\n        serializationObject.metadata = this.metadata;\n\n        return serializationObject;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parse the JSON representation of a reflection probe in order to recreate the reflection probe in the given scene.\n * @param parsedReflectionProbe Define the JSON representation of the reflection probe\n * @param scene Define the scene the parsed reflection probe should be instantiated in\n * @param rootUrl Define the root url of the parsing sequence in the case of relative dependencies\n * @returns The parsed reflection probe if successful\n */\nexport function ReflectionProbeParse(parsedReflectionProbe: any, scene: Scene, rootUrl: string): Nullable<ReflectionProbe> {\n    let reflectionProbe: Nullable<ReflectionProbe> = null;\n    if (scene.reflectionProbes) {\n        for (let index = 0; index < scene.reflectionProbes.length; index++) {\n            const rp = scene.reflectionProbes[index];\n            if (rp.name === parsedReflectionProbe.name) {\n                reflectionProbe = rp;\n                break;\n            }\n        }\n    }\n\n    reflectionProbe = SerializationHelper.Parse(\n        () => reflectionProbe || new ReflectionProbe(parsedReflectionProbe.name, parsedReflectionProbe.renderTargetSize, scene, parsedReflectionProbe._generateMipMaps),\n        parsedReflectionProbe,\n        scene,\n        rootUrl\n    );\n    reflectionProbe.cubeTexture._waitingRenderList = parsedReflectionProbe.renderList;\n\n    if (parsedReflectionProbe._attachedMesh) {\n        reflectionProbe.attachToMesh(scene.getMeshById(parsedReflectionProbe._attachedMesh));\n    }\n\n    if (parsedReflectionProbe.metadata) {\n        reflectionProbe.metadata = parsedReflectionProbe.metadata;\n    }\n\n    return reflectionProbe;\n}\n\n/**\n * Register side effects for reflectionProbe.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterReflectionProbe(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    ReflectionProbe.Parse = ReflectionProbeParse;\n\n    Scene.prototype.removeReflectionProbe = function (toRemove: ReflectionProbe): number {\n        if (!this.reflectionProbes) {\n            return -1;\n        }\n\n        const index = this.reflectionProbes.indexOf(toRemove);\n        if (index !== -1) {\n            this.reflectionProbes.splice(index, 1);\n        }\n\n        return index;\n    };\n\n    Scene.prototype.addReflectionProbe = function (newReflectionProbe: ReflectionProbe): void {\n        if (!this.reflectionProbes) {\n            this.reflectionProbes = [];\n        }\n\n        this.reflectionProbes.push(newReflectionProbe);\n    };\n}\n","import { type IVector3Like, type IColor4Like } from \"../Maths/math.like\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * ThinSprite Class used to represent a thin sprite\r\n * This is the base class for sprites but can also directly be used with ThinEngine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/sprites\r\n */\r\nexport class ThinSprite {\r\n    /** Gets or sets the cell index in the sprite sheet */\r\n    public cellIndex: number;\r\n    /** Gets or sets the cell reference in the sprite sheet, uses sprite's filename when added to sprite sheet */\r\n    public cellRef: string;\r\n    /** Gets or sets the current world position */\r\n    public position: IVector3Like;\r\n    /** Gets or sets the main color */\r\n    public color: IColor4Like;\r\n    /** Gets or sets the width */\r\n    public width = 1.0;\r\n    /** Gets or sets the height */\r\n    public height = 1.0;\r\n    /** Gets or sets rotation angle */\r\n    public angle = 0;\r\n    /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */\r\n    public invertU = false;\r\n    /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */\r\n    public invertV = false;\r\n    /** Gets or sets a boolean indicating if the sprite is visible (renderable). Default is true */\r\n    public isVisible = true;\r\n\r\n    /**\r\n     * Returns a boolean indicating if the animation is started\r\n     */\r\n    public get animationStarted() {\r\n        return this._animationStarted;\r\n    }\r\n\r\n    /** Gets the initial key for the animation (setting it will restart the animation)  */\r\n    public get fromIndex() {\r\n        return this._fromIndex;\r\n    }\r\n\r\n    /** Gets or sets the end key for the animation (setting it will restart the animation)  */\r\n    public get toIndex() {\r\n        return this._toIndex;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */\r\n    public get loopAnimation() {\r\n        return this._loopAnimation;\r\n    }\r\n\r\n    /** Gets or sets the delay between cell changes (setting it will restart the animation)  */\r\n    public get delay() {\r\n        return Math.max(this._delay, 1);\r\n    }\r\n\r\n    /** @internal */\r\n    public _xOffset: number;\r\n    /** @internal */\r\n    public _yOffset: number;\r\n    /** @internal */\r\n    public _xSize: number;\r\n    /** @internal */\r\n    public _ySize: number;\r\n    /** @internal */\r\n    public _animationFrameId = -1;\r\n    /** @internal */\r\n    public _animationSceneId = -1;\r\n\r\n    private _animationStarted = false;\r\n    protected _loopAnimation = false;\r\n    protected _fromIndex = 0;\r\n    protected _toIndex = 0;\r\n    protected _delay = 0;\r\n    private _direction = 1;\r\n    private _time = 0;\r\n    private _onBaseAnimationEnd: Nullable<() => void> = null;\r\n\r\n    /**\r\n     * Creates a new Thin Sprite\r\n     */\r\n    constructor() {\r\n        this.position = { x: 1.0, y: 1.0, z: 1.0 };\r\n        this.color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n    }\r\n\r\n    /**\r\n     * Starts an animation\r\n     * @param from defines the initial key\r\n     * @param to defines the end key\r\n     * @param loop defines if the animation must loop\r\n     * @param delay defines the start delay (in ms)\r\n     * @param onAnimationEnd defines a callback for when the animation ends\r\n     */\r\n    public playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: Nullable<() => void>): void {\r\n        this._fromIndex = from;\r\n        this._toIndex = to;\r\n        this._loopAnimation = loop;\r\n        this._delay = delay || 1;\r\n        this._animationStarted = true;\r\n        this._onBaseAnimationEnd = onAnimationEnd;\r\n\r\n        if (from < to) {\r\n            this._direction = 1;\r\n        } else {\r\n            this._direction = -1;\r\n            this._toIndex = from;\r\n            this._fromIndex = to;\r\n        }\r\n\r\n        this.cellIndex = from;\r\n        this._time = 0;\r\n    }\r\n\r\n    /** Stops current animation (if any) */\r\n    public stopAnimation(): void {\r\n        this._animationStarted = false;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _animate(deltaTime: number): void {\r\n        if (!this._animationStarted) {\r\n            return;\r\n        }\r\n\r\n        this._time += deltaTime;\r\n        if (this._time > this._delay) {\r\n            this._time = this._time % this._delay;\r\n            this.cellIndex += this._direction;\r\n            if ((this._direction > 0 && this.cellIndex > this._toIndex) || (this._direction < 0 && this.cellIndex < this._fromIndex)) {\r\n                if (this._loopAnimation) {\r\n                    this.cellIndex = this._direction > 0 ? this._fromIndex : this._toIndex;\r\n                } else {\r\n                    this.cellIndex = this._direction > 0 ? this._toIndex : this._fromIndex;\r\n                    this._animationStarted = false;\r\n                    if (this._onBaseAnimationEnd) {\r\n                        this._onBaseAnimationEnd();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type ActionManager } from \"../Actions/actionManager\";\r\nimport { type ISpriteManager, type SpriteManager } from \"./spriteManager\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { ThinSprite } from \"./thinSprite\";\r\n\r\nimport { type Animation } from \"../Animations/animation\";\r\n\r\n/**\r\n * Class used to represent a sprite\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/sprites\r\n */\r\nexport class Sprite extends ThinSprite implements IAnimatable {\r\n    /** Gets or sets the current world position */\r\n    public override position: Vector3;\r\n    /** Gets or sets the main color */\r\n    public override color: Color4;\r\n    /** Gets or sets a boolean indicating that this sprite should be disposed after animation ends */\r\n    public disposeWhenFinishedAnimating: boolean;\r\n    /** Gets the list of attached animations */\r\n    public animations: Nullable<Array<Animation>> = new Array<Animation>();\r\n    /** Gets or sets a boolean indicating if the sprite can be picked */\r\n    public isPickable = false;\r\n    /** Gets or sets a boolean indicating that sprite texture alpha will be used for precise picking (false by default) */\r\n    public useAlphaForPicking = false;\r\n\r\n    /**\r\n     * Gets or sets the associated action manager\r\n     */\r\n    public actionManager: Nullable<ActionManager>;\r\n\r\n    /**\r\n     * An event triggered when the control has been disposed\r\n     */\r\n    public onDisposeObservable = new Observable<Sprite>();\r\n\r\n    private _manager: ISpriteManager;\r\n    private _onAnimationEnd: Nullable<() => void> = null;\r\n\r\n    /**\r\n     * Gets or sets the sprite size\r\n     */\r\n    public get size(): number {\r\n        return this.width;\r\n    }\r\n\r\n    public set size(value: number) {\r\n        this.width = value;\r\n        this.height = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the unique id of the sprite\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Gets the manager of this sprite\r\n     */\r\n    public get manager() {\r\n        return this._manager;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Sprite\r\n     * @param name defines the name\r\n     * @param manager defines the manager\r\n     */\r\n    constructor(\r\n        /** defines the name */\r\n        public name: string,\r\n        manager: ISpriteManager\r\n    ) {\r\n        super();\r\n        this.color = new Color4(1.0, 1.0, 1.0, 1.0);\r\n        this.position = Vector3.Zero();\r\n\r\n        this._manager = manager;\r\n        this._manager.sprites.push(this);\r\n        this.uniqueId = this._manager.scene.getUniqueId();\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"Sprite\"\r\n     * @returns \"Sprite\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Sprite\";\r\n    }\r\n\r\n    /** Gets or sets the initial key for the animation (setting it will restart the animation)  */\r\n    public override get fromIndex() {\r\n        return this._fromIndex;\r\n    }\r\n    public override set fromIndex(value: number) {\r\n        this.playAnimation(value, this._toIndex, this._loopAnimation, this._delay, this._onAnimationEnd);\r\n    }\r\n\r\n    /** Gets or sets the end key for the animation (setting it will restart the animation)  */\r\n    public override get toIndex() {\r\n        return this._toIndex;\r\n    }\r\n    public override set toIndex(value: number) {\r\n        this.playAnimation(this._fromIndex, value, this._loopAnimation, this._delay, this._onAnimationEnd);\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the animation is looping (setting it will restart the animation)  */\r\n    public override get loopAnimation() {\r\n        return this._loopAnimation;\r\n    }\r\n    public override set loopAnimation(value: boolean) {\r\n        this.playAnimation(this._fromIndex, this._toIndex, value, this._delay, this._onAnimationEnd);\r\n    }\r\n\r\n    /** Gets or sets the delay between cell changes (setting it will restart the animation)  */\r\n    public override get delay() {\r\n        return Math.max(this._delay, 1);\r\n    }\r\n    public override set delay(value: number) {\r\n        this.playAnimation(this._fromIndex, this._toIndex, this._loopAnimation, value, this._onAnimationEnd);\r\n    }\r\n\r\n    /**\r\n     * Starts an animation\r\n     * @param from defines the initial key\r\n     * @param to defines the end key\r\n     * @param loop defines if the animation must loop\r\n     * @param delay defines the start delay (in ms)\r\n     * @param onAnimationEnd defines a callback to call when animation ends\r\n     */\r\n    public override playAnimation(from: number, to: number, loop: boolean, delay: number, onAnimationEnd: Nullable<() => void> = null): void {\r\n        this._onAnimationEnd = onAnimationEnd;\r\n\r\n        super.playAnimation(from, to, loop, delay, this._endAnimation);\r\n    }\r\n\r\n    private _endAnimation = () => {\r\n        if (this._onAnimationEnd) {\r\n            this._onAnimationEnd();\r\n        }\r\n        if (this.disposeWhenFinishedAnimating) {\r\n            this.dispose();\r\n        }\r\n    };\r\n\r\n    /** Release associated resources */\r\n    public dispose(): void {\r\n        for (let i = 0; i < this._manager.sprites.length; i++) {\r\n            if (this._manager.sprites[i] == this) {\r\n                this._manager.sprites.splice(i, 1);\r\n            }\r\n        }\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Serializes the sprite to a JSON object\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.position = this.position.asArray();\r\n        serializationObject.color = this.color.asArray();\r\n        serializationObject.width = this.width;\r\n        serializationObject.height = this.height;\r\n        serializationObject.angle = this.angle;\r\n        serializationObject.cellIndex = this.cellIndex;\r\n        serializationObject.cellRef = this.cellRef;\r\n        serializationObject.invertU = this.invertU;\r\n        serializationObject.invertV = this.invertV;\r\n        serializationObject.disposeWhenFinishedAnimating = this.disposeWhenFinishedAnimating;\r\n        serializationObject.isPickable = this.isPickable;\r\n        serializationObject.isVisible = this.isVisible;\r\n        serializationObject.useAlphaForPicking = this.useAlphaForPicking;\r\n\r\n        serializationObject.animationStarted = this.animationStarted;\r\n        serializationObject.fromIndex = this.fromIndex;\r\n        serializationObject.toIndex = this.toIndex;\r\n        serializationObject.loopAnimation = this.loopAnimation;\r\n        serializationObject.delay = this.delay;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON object to create a new sprite\r\n     * @param parsedSprite The JSON object to parse\r\n     * @param manager defines the hosting manager\r\n     * @returns the new sprite\r\n     */\r\n    public static Parse(parsedSprite: any, manager: SpriteManager): Sprite {\r\n        const sprite = new Sprite(parsedSprite.name, manager);\r\n\r\n        sprite.position = Vector3.FromArray(parsedSprite.position);\r\n        sprite.color = Color4.FromArray(parsedSprite.color);\r\n        sprite.width = parsedSprite.width;\r\n        sprite.height = parsedSprite.height;\r\n        sprite.angle = parsedSprite.angle;\r\n        sprite.cellIndex = parsedSprite.cellIndex;\r\n        sprite.cellRef = parsedSprite.cellRef;\r\n        sprite.invertU = parsedSprite.invertU;\r\n        sprite.invertV = parsedSprite.invertV;\r\n        sprite.disposeWhenFinishedAnimating = parsedSprite.disposeWhenFinishedAnimating;\r\n        sprite.isPickable = parsedSprite.isPickable;\r\n        sprite.isVisible = parsedSprite.isVisible;\r\n        sprite.useAlphaForPicking = parsedSprite.useAlphaForPicking;\r\n\r\n        sprite._fromIndex = parsedSprite.fromIndex;\r\n        sprite._toIndex = parsedSprite.toIndex;\r\n        sprite._loopAnimation = parsedSprite.loopAnimation;\r\n        sprite._delay = parsedSprite.delay;\r\n\r\n        if (parsedSprite.animationStarted) {\r\n            sprite.playAnimation(sprite.fromIndex, sprite.toIndex, sprite.loopAnimation, sprite.delay);\r\n        }\r\n\r\n        return sprite;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { Ray, CreatePickingRayInCameraSpace, CreatePickingRayInCameraSpaceToRef } from \"../Culling/ray.core\";\r\nimport { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { ActionEvent } from \"../Actions/actionEvent\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type IPointerEvent } from \"../Events/deviceInputEvents\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Sprite } from \"./sprite\";\r\nimport { type ISpriteManager } from \"./spriteManager\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\n\r\n/** @internal */\r\nexport type InternalSpriteAugmentedScene = Scene & {\r\n    _onNewSpriteManagerAddedObservable?: Observable<ISpriteManager>;\r\n    _onSpriteManagerRemovedObservable?: Observable<ISpriteManager>;\r\n};\r\n\r\n/**\r\n * Defines the sprite scene component responsible to manage sprites\r\n * in a given scene.\r\n */\r\nexport class SpriteSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpfull to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_SPRITE;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /** @internal */\r\n    private _spritePredicate: (sprite: Sprite) => boolean;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n        this.scene.spriteManagers = [] as ISpriteManager[];\r\n        // This ray is used to pick sprites in the scene\r\n        this.scene._tempSpritePickingRay = Ray ? Ray.Zero() : null;\r\n        this.scene.onBeforeSpritesRenderingObservable = new Observable<Scene>();\r\n        this.scene.onAfterSpritesRenderingObservable = new Observable<Scene>();\r\n        this._spritePredicate = (sprite: Sprite): boolean => {\r\n            if (!sprite.actionManager) {\r\n                return false;\r\n            }\r\n            return sprite.isPickable && sprite.actionManager.hasPointerTriggers;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._pointerMoveStage.registerStep(SceneComponentConstants.STEP_POINTERMOVE_SPRITE, this, this._pointerMove);\r\n        this.scene._pointerDownStage.registerStep(SceneComponentConstants.STEP_POINTERDOWN_SPRITE, this, this._pointerDown);\r\n        this.scene._pointerUpStage.registerStep(SceneComponentConstants.STEP_POINTERUP_SPRITE, this, this._pointerUp);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        /** Nothing to do for sprites */\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        this.scene.onBeforeSpritesRenderingObservable.clear();\r\n        this.scene.onAfterSpritesRenderingObservable.clear();\r\n\r\n        const spriteManagers = this.scene.spriteManagers;\r\n        if (!spriteManagers) {\r\n            return;\r\n        }\r\n        while (spriteManagers.length) {\r\n            spriteManagers[0].dispose();\r\n        }\r\n    }\r\n\r\n    private _pickSpriteButKeepRay(originalPointerInfo: Nullable<PickingInfo>, x: number, y: number, fastCheck?: boolean, camera?: Camera): Nullable<PickingInfo> {\r\n        const result = this.scene.pickSprite(x, y, this._spritePredicate, fastCheck, camera);\r\n        if (result) {\r\n            result.ray = originalPointerInfo ? originalPointerInfo.ray : null;\r\n        }\r\n        return result;\r\n    }\r\n\r\n    private _pointerMove(\r\n        unTranslatedPointerX: number,\r\n        unTranslatedPointerY: number,\r\n        pickResult: Nullable<PickingInfo>,\r\n        isMeshPicked: boolean,\r\n        element: Nullable<HTMLElement>\r\n    ): Nullable<PickingInfo> {\r\n        const scene = this.scene;\r\n        if (isMeshPicked) {\r\n            scene.setPointerOverSprite(null);\r\n        } else {\r\n            pickResult = this._pickSpriteButKeepRay(pickResult, unTranslatedPointerX, unTranslatedPointerY, false, scene.cameraToUseForPointers || undefined);\r\n\r\n            if (pickResult && pickResult.hit && pickResult.pickedSprite) {\r\n                scene.setPointerOverSprite(pickResult.pickedSprite);\r\n                if (!scene.doNotHandleCursors && element) {\r\n                    if (scene._pointerOverSprite && scene._pointerOverSprite.actionManager && scene._pointerOverSprite.actionManager.hoverCursor) {\r\n                        element.style.cursor = scene._pointerOverSprite.actionManager.hoverCursor;\r\n                    } else {\r\n                        element.style.cursor = scene.hoverCursor;\r\n                    }\r\n                }\r\n            } else {\r\n                scene.setPointerOverSprite(null);\r\n            }\r\n        }\r\n\r\n        return pickResult;\r\n    }\r\n\r\n    private _pointerDown(unTranslatedPointerX: number, unTranslatedPointerY: number, pickResult: Nullable<PickingInfo>, evt: IPointerEvent): Nullable<PickingInfo> {\r\n        const scene = this.scene;\r\n        scene._pickedDownSprite = null;\r\n        if (scene.spriteManagers && scene.spriteManagers.length > 0) {\r\n            pickResult = scene.pickSprite(unTranslatedPointerX, unTranslatedPointerY, this._spritePredicate, false, scene.cameraToUseForPointers || undefined);\r\n\r\n            if (pickResult && pickResult.hit && pickResult.pickedSprite) {\r\n                if (pickResult.pickedSprite.actionManager) {\r\n                    scene._pickedDownSprite = pickResult.pickedSprite;\r\n                    switch (evt.button) {\r\n                        case 0:\r\n                            pickResult.pickedSprite.actionManager.processTrigger(\r\n                                Constants.ACTION_OnLeftPickTrigger,\r\n                                ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, scene, evt)\r\n                            );\r\n                            break;\r\n                        case 1:\r\n                            pickResult.pickedSprite.actionManager.processTrigger(\r\n                                Constants.ACTION_OnCenterPickTrigger,\r\n                                ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, scene, evt)\r\n                            );\r\n                            break;\r\n                        case 2:\r\n                            pickResult.pickedSprite.actionManager.processTrigger(\r\n                                Constants.ACTION_OnRightPickTrigger,\r\n                                ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, scene, evt)\r\n                            );\r\n                            break;\r\n                    }\r\n                    if (pickResult.pickedSprite.actionManager) {\r\n                        pickResult.pickedSprite.actionManager.processTrigger(\r\n                            Constants.ACTION_OnPickDownTrigger,\r\n                            ActionEvent.CreateNewFromSprite(pickResult.pickedSprite, scene, evt)\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return pickResult;\r\n    }\r\n\r\n    private _pointerUp(\r\n        unTranslatedPointerX: number,\r\n        unTranslatedPointerY: number,\r\n        pickResult: Nullable<PickingInfo>,\r\n        evt: IPointerEvent,\r\n        doubleClick: boolean\r\n    ): Nullable<PickingInfo> {\r\n        const scene = this.scene;\r\n        if (scene.spriteManagers && scene.spriteManagers.length > 0) {\r\n            const spritePickResult = scene.pickSprite(unTranslatedPointerX, unTranslatedPointerY, this._spritePredicate, false, scene.cameraToUseForPointers || undefined);\r\n\r\n            if (spritePickResult) {\r\n                if (spritePickResult.hit && spritePickResult.pickedSprite) {\r\n                    if (spritePickResult.pickedSprite.actionManager) {\r\n                        spritePickResult.pickedSprite.actionManager.processTrigger(\r\n                            Constants.ACTION_OnPickUpTrigger,\r\n                            ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, scene, evt)\r\n                        );\r\n\r\n                        if (spritePickResult.pickedSprite.actionManager) {\r\n                            if (!this.scene._inputManager._isPointerSwiping()) {\r\n                                spritePickResult.pickedSprite.actionManager.processTrigger(\r\n                                    Constants.ACTION_OnPickTrigger,\r\n                                    ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, scene, evt)\r\n                                );\r\n                            }\r\n\r\n                            if (doubleClick) {\r\n                                spritePickResult.pickedSprite.actionManager.processTrigger(\r\n                                    Constants.ACTION_OnDoublePickTrigger,\r\n                                    ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, scene, evt)\r\n                                );\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                if (scene._pickedDownSprite && scene._pickedDownSprite.actionManager && scene._pickedDownSprite !== spritePickResult.pickedSprite) {\r\n                    scene._pickedDownSprite.actionManager.processTrigger(Constants.ACTION_OnPickOutTrigger, ActionEvent.CreateNewFromSprite(scene._pickedDownSprite, scene, evt));\r\n                }\r\n            }\r\n        }\r\n\r\n        return pickResult;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for spriteSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSpriteSceneComponent(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"onNewSpriteManagerAddedObservable\", {\r\n        get: function (this: InternalSpriteAugmentedScene) {\r\n            if (!this.isDisposed && !this._onNewSpriteManagerAddedObservable) {\r\n                const onNewSpriteManagerAddedObservable = (this._onNewSpriteManagerAddedObservable = new Observable<ISpriteManager>());\r\n                this.onDisposeObservable.addOnce(() => onNewSpriteManagerAddedObservable.clear());\r\n            }\r\n            return this._onNewSpriteManagerAddedObservable;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"onSpriteManagerRemovedObservable\", {\r\n        get: function (this: InternalSpriteAugmentedScene) {\r\n            if (!this.isDisposed && !this._onSpriteManagerRemovedObservable) {\r\n                const onSpriteManagerRemovedObservable = (this._onSpriteManagerRemovedObservable = new Observable<ISpriteManager>());\r\n                this.onDisposeObservable.addOnce(() => onSpriteManagerRemovedObservable.clear());\r\n            }\r\n            return this._onSpriteManagerRemovedObservable;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype._internalPickSprites = function (ray: Ray, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean, camera?: Camera): Nullable<PickingInfo> {\r\n        if (!PickingInfo) {\r\n            return null;\r\n        }\r\n\r\n        let pickingInfo = null;\r\n\r\n        if (!camera) {\r\n            if (!this.activeCamera) {\r\n                return null;\r\n            }\r\n            camera = this.activeCamera;\r\n        }\r\n\r\n        if (this.spriteManagers && this.spriteManagers.length > 0) {\r\n            for (let spriteIndex = 0; spriteIndex < this.spriteManagers.length; spriteIndex++) {\r\n                const spriteManager = this.spriteManagers[spriteIndex];\r\n\r\n                if (!spriteManager.isPickable) {\r\n                    continue;\r\n                }\r\n\r\n                const result = spriteManager.intersects(ray, camera, predicate, fastCheck);\r\n                if (!result || !result.hit) {\r\n                    continue;\r\n                }\r\n\r\n                if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {\r\n                    continue;\r\n                }\r\n\r\n                pickingInfo = result;\r\n\r\n                if (fastCheck) {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        return pickingInfo || new PickingInfo();\r\n    };\r\n\r\n    Scene.prototype._internalMultiPickSprites = function (ray: Ray, predicate?: (sprite: Sprite) => boolean, camera?: Camera): Nullable<PickingInfo[]> {\r\n        if (!PickingInfo) {\r\n            return null;\r\n        }\r\n\r\n        let pickingInfos: PickingInfo[] = [];\r\n\r\n        if (!camera) {\r\n            if (!this.activeCamera) {\r\n                return null;\r\n            }\r\n            camera = this.activeCamera;\r\n        }\r\n\r\n        if (this.spriteManagers && this.spriteManagers.length > 0) {\r\n            for (let spriteIndex = 0; spriteIndex < this.spriteManagers.length; spriteIndex++) {\r\n                const spriteManager = this.spriteManagers[spriteIndex];\r\n\r\n                if (!spriteManager.isPickable) {\r\n                    continue;\r\n                }\r\n\r\n                const results = spriteManager.multiIntersects(ray, camera, predicate);\r\n\r\n                if (results !== null) {\r\n                    pickingInfos = pickingInfos.concat(results);\r\n                }\r\n            }\r\n        }\r\n\r\n        return pickingInfos;\r\n    };\r\n\r\n    Scene.prototype.pickSprite = function (x: number, y: number, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean, camera?: Camera): Nullable<PickingInfo> {\r\n        if (!this._tempSpritePickingRay) {\r\n            return null;\r\n        }\r\n\r\n        CreatePickingRayInCameraSpaceToRef(this, x, y, this._tempSpritePickingRay, camera);\r\n\r\n        const result = this._internalPickSprites(this._tempSpritePickingRay, predicate, fastCheck, camera);\r\n        if (result) {\r\n            result.ray = CreatePickingRayInCameraSpace(this, x, y, camera);\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    Scene.prototype.pickSpriteWithRay = function (ray: Ray, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean, camera?: Camera): Nullable<PickingInfo> {\r\n        if (!this._tempSpritePickingRay) {\r\n            return null;\r\n        }\r\n\r\n        if (!camera) {\r\n            if (!this.activeCamera) {\r\n                return null;\r\n            }\r\n            camera = this.activeCamera;\r\n        }\r\n\r\n        Ray.TransformToRef(ray, camera.getViewMatrix(), this._tempSpritePickingRay);\r\n\r\n        const result = this._internalPickSprites(this._tempSpritePickingRay, predicate, fastCheck, camera);\r\n        if (result) {\r\n            result.ray = ray;\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    Scene.prototype.multiPickSprite = function (x: number, y: number, predicate?: (sprite: Sprite) => boolean, camera?: Camera): Nullable<PickingInfo[]> {\r\n        CreatePickingRayInCameraSpaceToRef(this, x, y, this._tempSpritePickingRay!, camera);\r\n\r\n        return this._internalMultiPickSprites(this._tempSpritePickingRay!, predicate, camera);\r\n    };\r\n\r\n    Scene.prototype.multiPickSpriteWithRay = function (ray: Ray, predicate?: (sprite: Sprite) => boolean, camera?: Camera): Nullable<PickingInfo[]> {\r\n        if (!this._tempSpritePickingRay) {\r\n            return null;\r\n        }\r\n\r\n        if (!camera) {\r\n            if (!this.activeCamera) {\r\n                return null;\r\n            }\r\n            camera = this.activeCamera;\r\n        }\r\n\r\n        Ray.TransformToRef(ray, camera.getViewMatrix(), this._tempSpritePickingRay);\r\n\r\n        return this._internalMultiPickSprites(this._tempSpritePickingRay, predicate, camera);\r\n    };\r\n\r\n    Scene.prototype.setPointerOverSprite = function (sprite: Nullable<Sprite>): void {\r\n        if (this._pointerOverSprite === sprite) {\r\n            return;\r\n        }\r\n\r\n        if (this._pointerOverSprite && this._pointerOverSprite.actionManager) {\r\n            this._pointerOverSprite.actionManager.processTrigger(Constants.ACTION_OnPointerOutTrigger, ActionEvent.CreateNewFromSprite(this._pointerOverSprite, this));\r\n        }\r\n\r\n        this._pointerOverSprite = sprite;\r\n        if (this._pointerOverSprite && this._pointerOverSprite.actionManager) {\r\n            this._pointerOverSprite.actionManager.processTrigger(Constants.ACTION_OnPointerOverTrigger, ActionEvent.CreateNewFromSprite(this._pointerOverSprite, this));\r\n        }\r\n    };\r\n\r\n    Scene.prototype.getPointerOverSprite = function (): Nullable<Sprite> {\r\n        return this._pointerOverSprite;\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type IMatrixLike } from \"../Maths/math.like\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { Buffer, VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { type ThinSprite } from \"./thinSprite\";\r\nimport { type ISize } from \"../Maths/math.size\";\r\n\r\nimport { type ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { BindLogDepth } from \"../Materials/materialHelper.functions\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { MaterialHelperGeometryRendering, type GeometryRenderingConfiguration } from \"../Materials/materialHelper.geometryrendering\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../Materials/effect\";\r\nimport { Observable, type Observer } from \"../Misc/observable.pure\";\r\n\r\ntype SpriteRendererSpriteHistory = {\r\n    previousX: number;\r\n    previousY: number;\r\n    previousZ: number;\r\n    previousAngle: number;\r\n    previousWidth: number;\r\n    previousHeight: number;\r\n    currentX: number;\r\n    currentY: number;\r\n    currentZ: number;\r\n    currentAngle: number;\r\n    currentWidth: number;\r\n    currentHeight: number;\r\n    frameId: number;\r\n};\r\n\r\ntype SpriteRendererCameraHistory = {\r\n    previousView: Matrix;\r\n    previousProjection: Matrix;\r\n    currentView: Matrix;\r\n    currentProjection: Matrix;\r\n    sprites: WeakMap<ThinSprite, SpriteRendererSpriteHistory>;\r\n    frameId: number;\r\n};\r\n\r\ntype SpriteRendererDrawCache = {\r\n    drawWrapperBase: DrawWrapper;\r\n    drawWrapperDepth: DrawWrapper;\r\n    defines: string;\r\n    geometryDefines?: string;\r\n    geometryConfiguration?: GeometryRenderingConfiguration;\r\n    variantKey: number;\r\n    vertexBuffers: { [key: string]: VertexBuffer };\r\n    vertexArrayObject?: WebGLVertexArrayObject;\r\n    usesGeometryRendering: boolean;\r\n    usesVelocity: boolean;\r\n    usesObjectId: boolean;\r\n    usesMeshBlendTag: boolean;\r\n    usesInverseView: boolean;\r\n    usesNormals: boolean;\r\n    usesNormalizedDepth: boolean;\r\n    cameraHistories?: WeakMap<object, SpriteRendererCameraHistory>;\r\n};\r\n\r\n/**\r\n * Options for the SpriteRenderer\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SpriteRendererOptions {\r\n    /**\r\n     * Sets a boolean indicating if the renderer must render sprites with pixel perfect rendering.\r\n     * In this mode, sprites are rendered as \"pixel art\", which means that they appear as pixelated but remain stable when moving or when rotated or scaled.\r\n     * Note that for this mode to work as expected, the sprite texture must use the BILINEAR sampling mode, not NEAREST!\r\n     * Default is false.\r\n     */\r\n    pixelPerfect?: boolean;\r\n}\r\n\r\n/**\r\n * Class used to render sprites.\r\n *\r\n * It can be used either to render Sprites or ThinSprites with ThinEngine only.\r\n */\r\nexport class SpriteRenderer {\r\n    /**\r\n     * Force all the sprites to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n    /**\r\n     * Defines the texture of the spritesheet\r\n     */\r\n    public texture: Nullable<ThinTexture>;\r\n\r\n    /**\r\n     * Defines the default width of a cell in the spritesheet\r\n     */\r\n    public cellWidth: number;\r\n\r\n    /**\r\n     * Defines the default height of a cell in the spritesheet\r\n     */\r\n    public cellHeight: number;\r\n\r\n    /**\r\n     * Blend mode use to render the particle, it can be any of\r\n     * the static Constants.ALPHA_x properties provided in this class.\r\n     * Default value is Constants.ALPHA_COMBINE\r\n     */\r\n    public blendMode = Constants.ALPHA_COMBINE;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if alpha mode is automatically\r\n     * reset.\r\n     */\r\n    public autoResetAlpha = true;\r\n\r\n    /**\r\n     * Disables writing to the depth buffer when rendering the sprites.\r\n     * It can be handy to disable depth writing when using textures without alpha channel\r\n     * and setting some specific blend modes.\r\n     */\r\n    public disableDepthWrite: boolean = false;\r\n\r\n    private _fogEnabled = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the manager must consider scene fog when rendering\r\n     */\r\n    public get fogEnabled() {\r\n        return this._fogEnabled;\r\n    }\r\n\r\n    public set fogEnabled(value: boolean) {\r\n        if (this._fogEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._fogEnabled = value;\r\n        this._createEffects();\r\n    }\r\n\r\n    protected _useLogarithmicDepth: boolean;\r\n\r\n    /**\r\n     * In case the depth buffer does not allow enough depth precision for your scene (might be the case in large scenes)\r\n     * You can try switching to logarithmic depth.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/logarithmicDepthBuffer\r\n     */\r\n    public get useLogarithmicDepth(): boolean {\r\n        return this._useLogarithmicDepth;\r\n    }\r\n\r\n    public set useLogarithmicDepth(value: boolean) {\r\n        const fragmentDepthSupported = !!this._scene?.getEngine().getCaps().fragmentDepthSupported;\r\n\r\n        if (value && !fragmentDepthSupported) {\r\n            Logger.Warn(\"Logarithmic depth has been requested for a sprite renderer on a device that doesn't support it.\");\r\n        }\r\n\r\n        this._useLogarithmicDepth = value && fragmentDepthSupported;\r\n        this._createEffects();\r\n    }\r\n\r\n    /**\r\n     * Gets the capacity of the manager\r\n     */\r\n    public get capacity() {\r\n        return this._capacity;\r\n    }\r\n\r\n    private _pixelPerfect = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the renderer must render sprites with pixel perfect rendering\r\n     * Note that pixel perfect mode is not supported in WebGL 1\r\n     */\r\n    public get pixelPerfect() {\r\n        return this._pixelPerfect;\r\n    }\r\n\r\n    public set pixelPerfect(value: boolean) {\r\n        if (this._pixelPerfect === value) {\r\n            return;\r\n        }\r\n\r\n        this._pixelPerfect = value;\r\n        this._createEffects();\r\n    }\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this renderer.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _useVAO: boolean = false;\r\n    private readonly _useInstancing: boolean = false;\r\n    private readonly _scene: Nullable<Scene>;\r\n\r\n    private readonly _capacity: number;\r\n    private readonly _epsilon: number;\r\n\r\n    private _vertexBufferSize: number;\r\n    private _vertexData: Float32Array;\r\n    private _buffer: Buffer;\r\n    private _vertexBuffers: { [key: string]: VertexBuffer } = {};\r\n    private _previousVertexData: Nullable<Float32Array> = null;\r\n    private _previousBuffer: Nullable<Buffer> = null;\r\n    private _vertexBuffersWithPrevious: Nullable<{ [key: string]: VertexBuffer }> = null;\r\n    private _spriteBuffer: Nullable<Buffer>;\r\n    private _indexBuffer: DataBuffer;\r\n    /** @internal */\r\n    public _drawWrapperBase: DrawWrapper;\r\n    /** @internal */\r\n    public _drawWrapperDepth: DrawWrapper;\r\n    private _drawCaches: Array<SpriteRendererDrawCache | undefined> = [];\r\n    private _inverseViewMatrix: Nullable<Matrix> = null;\r\n    private _isDisposed = false;\r\n    private _renderPassObserver: Nullable<Observer<number>> = null;\r\n\r\n    /**\r\n     * Creates a new sprite renderer\r\n     * @param engine defines the engine the renderer works with\r\n     * @param capacity defines the maximum allowed number of sprites\r\n     * @param epsilon defines the epsilon value to align texture (0.01 by default)\r\n     * @param scene defines the hosting scene\r\n     * @param rendererOptions options for the sprite renderer\r\n     */\r\n    constructor(engine: AbstractEngine, capacity: number, epsilon: number = 0.01, scene: Nullable<Scene> = null, rendererOptions?: SpriteRendererOptions) {\r\n        this._pixelPerfect = rendererOptions?.pixelPerfect ?? false;\r\n        this._capacity = capacity;\r\n        this._epsilon = epsilon;\r\n\r\n        this._engine = engine;\r\n        this._useInstancing = engine.getCaps().instancedArrays && engine._features.supportSpriteInstancing;\r\n        this._useVAO = engine.getCaps().vertexArrayObject && !engine.disableVertexArrayObjects;\r\n        this._scene = scene;\r\n\r\n        if (!this._useInstancing) {\r\n            this._buildIndexBuffer();\r\n        }\r\n\r\n        // VBO\r\n        // 18 floats per sprite (x, y, z, angle, sizeX, sizeY, offsetX, offsetY, invertU, invertV, cellLeft, cellTop, cellWidth, cellHeight, color r, color g, color b, color a)\r\n        // 16 when using instances\r\n        this._vertexBufferSize = this._useInstancing ? 16 : 18;\r\n        this._vertexData = new Float32Array(capacity * this._vertexBufferSize * (this._useInstancing ? 1 : 4));\r\n        this._buffer = new Buffer(engine, this._vertexData, true, this._vertexBufferSize);\r\n\r\n        const positions = this._buffer.createVertexBuffer(VertexBuffer.PositionKind, 0, 4, this._vertexBufferSize, this._useInstancing);\r\n        const options = this._buffer.createVertexBuffer(\"options\", 4, 2, this._vertexBufferSize, this._useInstancing);\r\n\r\n        let offset = 6;\r\n        let offsets: VertexBuffer;\r\n\r\n        if (this._useInstancing) {\r\n            const spriteData = new Float32Array([\r\n                this._epsilon,\r\n                this._epsilon,\r\n                1 - this._epsilon,\r\n                this._epsilon,\r\n                this._epsilon,\r\n                1 - this._epsilon,\r\n                1 - this._epsilon,\r\n                1 - this._epsilon,\r\n            ]);\r\n            this._spriteBuffer = new Buffer(engine, spriteData, false, 2);\r\n            offsets = this._spriteBuffer.createVertexBuffer(\"offsets\", 0, 2);\r\n        } else {\r\n            offsets = this._buffer.createVertexBuffer(\"offsets\", offset, 2, this._vertexBufferSize, this._useInstancing);\r\n            offset += 2;\r\n        }\r\n\r\n        const inverts = this._buffer.createVertexBuffer(\"inverts\", offset, 2, this._vertexBufferSize, this._useInstancing);\r\n        const cellInfo = this._buffer.createVertexBuffer(\"cellInfo\", offset + 2, 4, this._vertexBufferSize, this._useInstancing);\r\n        const colors = this._buffer.createVertexBuffer(VertexBuffer.ColorKind, offset + 6, 4, this._vertexBufferSize, this._useInstancing);\r\n\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = positions;\r\n        this._vertexBuffers[\"options\"] = options;\r\n        this._vertexBuffers[\"offsets\"] = offsets;\r\n        this._vertexBuffers[\"inverts\"] = inverts;\r\n        this._vertexBuffers[\"cellInfo\"] = cellInfo;\r\n        this._vertexBuffers[VertexBuffer.ColorKind] = colors;\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n\r\n    private async _initShaderSourceAsync() {\r\n        const engine = this._engine;\r\n\r\n        if (engine.isWebGPU && !SpriteRenderer.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([import(\"../ShadersWGSL/sprites.vertex\"), import(\"../ShadersWGSL/sprites.fragment\")]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/sprites.vertex\"), import(\"../Shaders/sprites.fragment\")]);\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n        this._createEffects();\r\n    }\r\n\r\n    /**\r\n     * Checks whether the texture and shader variant for the current render pass are ready.\r\n     * This prepares the effect without updating or drawing any sprites.\r\n     * @returns true when the renderer can draw sprites\r\n     * @see https://playground.babylonjs.com/#PVK3RV#2\r\n     */\r\n    public isReady(): boolean {\r\n        if (this._isDisposed || !this._shadersLoaded || !this.texture?.isReady()) {\r\n            return false;\r\n        }\r\n        const renderPassId = this._engine._features.supportRenderPasses ? this._engine.currentRenderPassId : Constants.RENDERPASS_MAIN;\r\n        return !!this._getDrawCache(renderPassId).drawWrapperBase.effect?.isReady();\r\n    }\r\n\r\n    private _createEffects() {\r\n        if (this._isDisposed || !this._shadersLoaded) {\r\n            return;\r\n        }\r\n\r\n        this._disposeDrawCaches();\r\n\r\n        const mainCache = this._getDrawCache(Constants.RENDERPASS_MAIN);\r\n        this._drawWrapperBase = mainCache.drawWrapperBase;\r\n        this._drawWrapperDepth = mainCache.drawWrapperDepth;\r\n    }\r\n\r\n    private _getDrawCache(renderPassId: number): SpriteRendererDrawCache {\r\n        const fogEnabled = !!(this._scene && this._scene.fogEnabled && this._scene.fogMode !== 0 && this._fogEnabled);\r\n        const variantKey = (this._pixelPerfect ? 1 : 0) | (fogEnabled ? 2 : 0) | (this._useLogarithmicDepth ? 4 : 0);\r\n        const geometryConfiguration = MaterialHelperGeometryRendering.GetConfiguration(renderPassId);\r\n        const geometryDefines = geometryConfiguration?._defines;\r\n        let cache = this._drawCaches[renderPassId];\r\n\r\n        if (cache?.variantKey === variantKey && cache.geometryDefines === geometryDefines && cache.geometryConfiguration === geometryConfiguration) {\r\n            return cache;\r\n        }\r\n\r\n        const defines: string[] = [];\r\n\r\n        if (this._pixelPerfect) {\r\n            defines.push(\"#define PIXEL_PERFECT\");\r\n        }\r\n        if (fogEnabled) {\r\n            defines.push(\"#define FOG\");\r\n        }\r\n        if (this._useLogarithmicDepth) {\r\n            defines.push(\"#define LOGARITHMICDEPTH\");\r\n        }\r\n\r\n        const usesGeometryRendering = MaterialHelperGeometryRendering._PrepareStringDefines(renderPassId, defines);\r\n        const mrtCount = usesGeometryRendering ? (MaterialHelperGeometryRendering.GetConfiguration(renderPassId)._mrtCount ?? 0) : 0;\r\n        if (!usesGeometryRendering) {\r\n            defines.push(\"#define SCENE_MRT_COUNT 0\");\r\n        }\r\n        const joinedDefines = defines.join(\"\\n\");\r\n\r\n        if (cache) {\r\n            this._disposeDrawCache(cache);\r\n            this._drawCaches[renderPassId] = undefined;\r\n        }\r\n\r\n        const usesVelocity = joinedDefines.indexOf(\"#define PREPASS_VELOCITY\\n\") !== -1 || joinedDefines.indexOf(\"#define PREPASS_VELOCITY_LINEAR\\n\") !== -1;\r\n        const usesObjectId = joinedDefines.indexOf(\"#define PREPASS_OBJECT_ID\\n\") !== -1;\r\n        const usesMeshBlendTag = joinedDefines.indexOf(\"#define PREPASS_MESH_BLEND_TAG\\n\") !== -1;\r\n        const attributes = [VertexBuffer.PositionKind, \"options\", \"offsets\", \"inverts\", \"cellInfo\", VertexBuffer.ColorKind];\r\n        let vertexBuffers = this._vertexBuffers;\r\n\r\n        if (usesVelocity) {\r\n            vertexBuffers = this._ensurePreviousVertexBuffer();\r\n            attributes.push(\"previousPosition\", \"previousOptions\");\r\n        }\r\n\r\n        const uniforms = [\r\n            \"view\",\r\n            \"projection\",\r\n            \"textureInfos\",\r\n            \"alphaTest\",\r\n            \"vFogInfos\",\r\n            \"vFogColor\",\r\n            \"logarithmicDepthConstant\",\r\n            \"invView\",\r\n            \"cameraInfo\",\r\n            \"spriteNormalSign\",\r\n            \"previousView\",\r\n            \"previousProjection\",\r\n            \"objectId\",\r\n            \"meshBlendTag\",\r\n            \"geometryZeroAlphaDiscard\",\r\n        ];\r\n        const drawWrapperBase = new DrawWrapper(this._engine);\r\n        const drawWrapperDepth = new DrawWrapper(this._engine, false);\r\n\r\n        if (drawWrapperBase.drawContext) {\r\n            drawWrapperBase.drawContext.useInstancing = this._useInstancing;\r\n        }\r\n        if (drawWrapperDepth.drawContext) {\r\n            drawWrapperDepth.drawContext.useInstancing = this._useInstancing;\r\n        }\r\n\r\n        const effectOptions: IEffectCreationOptions = {\r\n            attributes,\r\n            uniformsNames: uniforms,\r\n            samplers: [\"diffuseSampler\"],\r\n            defines: joinedDefines,\r\n            fallbacks: null,\r\n            onCompiled: null,\r\n            onError: null,\r\n            indexParameters: { SCENE_MRT_COUNT: mrtCount },\r\n            multiTarget: usesGeometryRendering,\r\n            shaderLanguage: this._shaderLanguage,\r\n        };\r\n        const effect = this._engine.createEffect(\"sprites\", effectOptions, this._engine);\r\n\r\n        drawWrapperBase.effect = effect;\r\n        drawWrapperBase.defines = joinedDefines;\r\n        drawWrapperDepth.effect = effect;\r\n        effect._refCount++;\r\n        drawWrapperDepth.defines = joinedDefines;\r\n        drawWrapperDepth.materialContext = drawWrapperBase.materialContext;\r\n\r\n        cache = {\r\n            drawWrapperBase,\r\n            drawWrapperDepth,\r\n            defines: joinedDefines,\r\n            geometryDefines,\r\n            geometryConfiguration,\r\n            variantKey,\r\n            vertexBuffers,\r\n            usesGeometryRendering,\r\n            usesVelocity,\r\n            usesObjectId,\r\n            usesMeshBlendTag,\r\n            usesInverseView: geometryConfiguration?.defines.PREPASS_POSITION_INDEX !== undefined || geometryConfiguration?.defines.PREPASS_WORLD_NORMAL_INDEX !== undefined,\r\n            usesNormals: geometryConfiguration?.defines.PREPASS_NORMAL_INDEX !== undefined || geometryConfiguration?.defines.PREPASS_WORLD_NORMAL_INDEX !== undefined,\r\n            usesNormalizedDepth: geometryConfiguration?.defines.PREPASS_NORMALIZED_VIEW_DEPTH_INDEX !== undefined,\r\n            cameraHistories: usesVelocity ? new WeakMap<object, SpriteRendererCameraHistory>() : undefined,\r\n        };\r\n        this._drawCaches[renderPassId] = cache;\r\n        if (renderPassId !== Constants.RENDERPASS_MAIN && !this._renderPassObserver) {\r\n            this._renderPassObserver = (this._engine._onReleaseRenderPassObservable ??= new Observable<number>()).add((id) => {\r\n                const releasedCache = this._drawCaches[id];\r\n                if (releasedCache) {\r\n                    this._disposeDrawCache(releasedCache);\r\n                    delete this._drawCaches[id];\r\n                    this._disposePreviousVertexBufferIfUnused();\r\n                }\r\n            });\r\n        }\r\n        this._disposePreviousVertexBufferIfUnused();\r\n\r\n        return cache;\r\n    }\r\n\r\n    private _ensurePreviousVertexBuffer(): { [key: string]: VertexBuffer } {\r\n        if (this._vertexBuffersWithPrevious) {\r\n            return this._vertexBuffersWithPrevious;\r\n        }\r\n\r\n        const previousVertexBufferSize = 6;\r\n        this._previousVertexData = new Float32Array(this._capacity * previousVertexBufferSize * (this._useInstancing ? 1 : 4));\r\n        this._previousBuffer = new Buffer(this._engine, this._previousVertexData, true, previousVertexBufferSize);\r\n        this._vertexBuffersWithPrevious = { ...this._vertexBuffers };\r\n        this._vertexBuffersWithPrevious[\"previousPosition\"] = this._previousBuffer.createVertexBuffer(\"previousPosition\", 0, 4, previousVertexBufferSize, this._useInstancing);\r\n        this._vertexBuffersWithPrevious[\"previousOptions\"] = this._previousBuffer.createVertexBuffer(\"previousOptions\", 4, 2, previousVertexBufferSize, this._useInstancing);\r\n\r\n        return this._vertexBuffersWithPrevious;\r\n    }\r\n\r\n    private _disposeDrawCache(cache: SpriteRendererDrawCache): void {\r\n        if (cache.vertexArrayObject) {\r\n            (this._engine as ThinEngine).releaseVertexArrayObject(cache.vertexArrayObject);\r\n        }\r\n        cache.drawWrapperBase.dispose();\r\n        cache.drawWrapperDepth.dispose();\r\n    }\r\n\r\n    private _disposeDrawCaches(): void {\r\n        for (const cache of this._drawCaches) {\r\n            if (cache) {\r\n                this._disposeDrawCache(cache);\r\n            }\r\n        }\r\n        this._drawCaches = [];\r\n        this._disposePreviousVertexBuffer();\r\n    }\r\n\r\n    private _disposePreviousVertexBufferIfUnused(): void {\r\n        for (const cache of this._drawCaches) {\r\n            if (cache?.usesVelocity) {\r\n                return;\r\n            }\r\n        }\r\n        this._disposePreviousVertexBuffer();\r\n    }\r\n\r\n    private _disposePreviousVertexBuffer(): void {\r\n        if (this._previousBuffer) {\r\n            this._previousBuffer.dispose();\r\n            this._previousBuffer = null;\r\n            this._previousVertexData = null;\r\n            this._vertexBuffersWithPrevious = null;\r\n        }\r\n    }\r\n\r\n    private _bindVertexBuffers(cache: SpriteRendererDrawCache, effect: Effect): void {\r\n        if (this._useVAO) {\r\n            if (!cache.vertexArrayObject) {\r\n                cache.vertexArrayObject = (this._engine as ThinEngine).recordVertexArrayObject(cache.vertexBuffers, this._indexBuffer, effect);\r\n            }\r\n            (this._engine as ThinEngine).bindVertexArrayObject(cache.vertexArrayObject, this._indexBuffer);\r\n        } else {\r\n            this._engine.bindBuffers(cache.vertexBuffers, this._indexBuffer, effect);\r\n        }\r\n    }\r\n\r\n    private _getCameraHistory(cache: SpriteRendererDrawCache, viewMatrix: IMatrixLike, projectionMatrix: IMatrixLike, frameId: number): SpriteRendererCameraHistory {\r\n        const cameraKey = (this._scene?.activeCamera ?? viewMatrix) as object;\r\n        let history = cache.cameraHistories!.get(cameraKey);\r\n\r\n        if (!history) {\r\n            const currentView = Matrix.FromArray(viewMatrix.asArray());\r\n            const currentProjection = Matrix.FromArray(projectionMatrix.asArray());\r\n            history = {\r\n                previousView: currentView.clone(),\r\n                previousProjection: currentProjection.clone(),\r\n                currentView,\r\n                currentProjection,\r\n                sprites: new WeakMap<ThinSprite, SpriteRendererSpriteHistory>(),\r\n                frameId,\r\n            };\r\n            cache.cameraHistories!.set(cameraKey, history);\r\n        } else {\r\n            if (history.frameId !== frameId) {\r\n                if (history.frameId === frameId - 1) {\r\n                    history.previousView.copyFrom(history.currentView);\r\n                    history.previousProjection.copyFrom(history.currentProjection);\r\n                } else {\r\n                    Matrix.FromArrayToRef(viewMatrix.asArray(), 0, history.previousView);\r\n                    Matrix.FromArrayToRef(projectionMatrix.asArray(), 0, history.previousProjection);\r\n                    history.sprites = new WeakMap<ThinSprite, SpriteRendererSpriteHistory>();\r\n                }\r\n                history.frameId = frameId;\r\n            }\r\n            Matrix.FromArrayToRef(viewMatrix.asArray(), 0, history.currentView);\r\n            Matrix.FromArrayToRef(projectionMatrix.asArray(), 0, history.currentProjection);\r\n        }\r\n\r\n        return history;\r\n    }\r\n\r\n    private _prepareSpriteHistory(history: SpriteRendererCameraHistory, sprite: ThinSprite, frameId: number): Nullable<SpriteRendererSpriteHistory> {\r\n        const spriteHistory = history.sprites.get(sprite);\r\n        if (spriteHistory && spriteHistory.frameId !== frameId) {\r\n            if (spriteHistory.frameId !== frameId - 1) {\r\n                history.sprites.delete(sprite);\r\n                return null;\r\n            }\r\n            spriteHistory.previousX = spriteHistory.currentX;\r\n            spriteHistory.previousY = spriteHistory.currentY;\r\n            spriteHistory.previousZ = spriteHistory.currentZ;\r\n            spriteHistory.previousAngle = spriteHistory.currentAngle;\r\n            spriteHistory.previousWidth = spriteHistory.currentWidth;\r\n            spriteHistory.previousHeight = spriteHistory.currentHeight;\r\n            spriteHistory.frameId = frameId;\r\n        }\r\n        return spriteHistory ?? null;\r\n    }\r\n\r\n    private _updateSpriteHistory(\r\n        history: SpriteRendererCameraHistory,\r\n        sprite: ThinSprite,\r\n        spriteHistory: Nullable<SpriteRendererSpriteHistory>,\r\n        floatingOriginOffset: Vector3,\r\n        frameId: number\r\n    ): void {\r\n        const x = sprite.position.x - floatingOriginOffset.x;\r\n        const y = sprite.position.y - floatingOriginOffset.y;\r\n        const z = sprite.position.z - floatingOriginOffset.z;\r\n\r\n        if (!spriteHistory) {\r\n            history.sprites.set(sprite, {\r\n                previousX: x,\r\n                previousY: y,\r\n                previousZ: z,\r\n                previousAngle: sprite.angle,\r\n                previousWidth: sprite.width,\r\n                previousHeight: sprite.height,\r\n                currentX: x,\r\n                currentY: y,\r\n                currentZ: z,\r\n                currentAngle: sprite.angle,\r\n                currentWidth: sprite.width,\r\n                currentHeight: sprite.height,\r\n                frameId,\r\n            });\r\n            return;\r\n        }\r\n\r\n        if (spriteHistory.frameId === frameId) {\r\n            spriteHistory.currentX = x;\r\n            spriteHistory.currentY = y;\r\n            spriteHistory.currentZ = z;\r\n            spriteHistory.currentAngle = sprite.angle;\r\n            spriteHistory.currentWidth = sprite.width;\r\n            spriteHistory.currentHeight = sprite.height;\r\n        }\r\n    }\r\n\r\n    private _animateSprite(sprite: ThinSprite, deltaTime: number): void {\r\n        if (!this._scene) {\r\n            sprite._animate(deltaTime);\r\n            return;\r\n        }\r\n\r\n        const frameId = this._scene.getFrameId();\r\n        const frameGraphRendering = !!this._scene.frameGraph || !!MaterialHelperGeometryRendering.GetConfiguration(this._engine.currentRenderPassId);\r\n        if (!frameGraphRendering || sprite._animationFrameId !== frameId || sprite._animationSceneId !== this._scene.uniqueId) {\r\n            sprite._animationFrameId = frameId;\r\n            sprite._animationSceneId = this._scene.uniqueId;\r\n            sprite._animate(deltaTime);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Render all child sprites\r\n     * @param sprites defines the list of sprites to render\r\n     * @param deltaTime defines the time since last frame\r\n     * @param viewMatrix defines the viewMatrix to use to render the sprites\r\n     * @param projectionMatrix defines the projectionMatrix to use to render the sprites\r\n     * @param customSpriteUpdate defines a custom function to update the sprites data before they render\r\n     */\r\n    public render(\r\n        sprites: ThinSprite[],\r\n        deltaTime: number,\r\n        viewMatrix: IMatrixLike,\r\n        projectionMatrix: IMatrixLike,\r\n        customSpriteUpdate: Nullable<(sprite: ThinSprite, baseSize: ISize) => void> = null\r\n    ): void {\r\n        if (!this._shadersLoaded || !this.texture || !this.texture.isReady() || !sprites.length) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._engine;\r\n        const renderPassId = engine._features.supportRenderPasses ? engine.currentRenderPassId : Constants.RENDERPASS_MAIN;\r\n        const drawCache = this._getDrawCache(renderPassId);\r\n        const drawWrapper = drawCache.drawWrapperBase;\r\n        const drawWrapperDepth = drawCache.drawWrapperDepth;\r\n        const shouldRenderFog = this.fogEnabled && this._scene && this._scene.fogEnabled && this._scene.fogMode !== 0;\r\n\r\n        const effect = drawWrapper.effect!;\r\n\r\n        // Check\r\n        if (!effect.isReady()) {\r\n            return;\r\n        }\r\n\r\n        const useRightHandedSystem = !!(this._scene && this._scene.useRightHandedSystem);\r\n        const frameId = this._scene?.getFrameId() ?? engine.frameId;\r\n        const usesVelocity = drawCache.usesVelocity;\r\n        const cameraHistory = usesVelocity ? this._getCameraHistory(drawCache, viewMatrix, projectionMatrix, frameId) : null;\r\n\r\n        // Sprites\r\n        const max = Math.min(this._capacity, sprites.length);\r\n\r\n        let offset = 0;\r\n        let noSprite = true;\r\n        const floatingOriginOffset = this._scene?.floatingOriginOffset || Vector3.ZeroReadOnly;\r\n        for (let index = 0; index < max; index++) {\r\n            const sprite = sprites[index];\r\n            if (!sprite || !sprite.isVisible) {\r\n                continue;\r\n            }\r\n\r\n            noSprite = false;\r\n            this._animateSprite(sprite, deltaTime);\r\n            const baseSize = this.texture.getBaseSize(); // This could be change by the user inside the animate callback (like onAnimationEnd)\r\n            const spriteHistory = cameraHistory ? this._prepareSpriteHistory(cameraHistory, sprite, frameId) : null;\r\n\r\n            this._appendSpriteVertex(offset++, sprite, 0, 0, baseSize, useRightHandedSystem, customSpriteUpdate, floatingOriginOffset, spriteHistory, usesVelocity);\r\n            if (!this._useInstancing) {\r\n                this._appendSpriteVertex(offset++, sprite, 1, 0, baseSize, useRightHandedSystem, customSpriteUpdate, floatingOriginOffset, spriteHistory, usesVelocity);\r\n                this._appendSpriteVertex(offset++, sprite, 1, 1, baseSize, useRightHandedSystem, customSpriteUpdate, floatingOriginOffset, spriteHistory, usesVelocity);\r\n                this._appendSpriteVertex(offset++, sprite, 0, 1, baseSize, useRightHandedSystem, customSpriteUpdate, floatingOriginOffset, spriteHistory, usesVelocity);\r\n            }\r\n\r\n            if (cameraHistory) {\r\n                this._updateSpriteHistory(cameraHistory, sprite, spriteHistory, floatingOriginOffset, frameId);\r\n            }\r\n        }\r\n\r\n        if (noSprite) {\r\n            return;\r\n        }\r\n\r\n        this._buffer.update(this._vertexData);\r\n        if (usesVelocity) {\r\n            this._previousBuffer!.update(this._previousVertexData!);\r\n        }\r\n\r\n        const culling = !!engine.depthCullingState.cull;\r\n        const zOffset = engine.depthCullingState.zOffset;\r\n        const zOffsetUnits = engine.depthCullingState.zOffsetUnits;\r\n\r\n        engine.setState(culling, zOffset, false, false, undefined, undefined, zOffsetUnits);\r\n\r\n        // Render\r\n        engine.enableEffect(drawWrapper);\r\n\r\n        effect.setTexture(\"diffuseSampler\", this.texture);\r\n        effect.setMatrix(\"view\", viewMatrix);\r\n        effect.setMatrix(\"projection\", projectionMatrix);\r\n\r\n        if (drawCache.usesGeometryRendering) {\r\n            if (drawCache.usesInverseView) {\r\n                this._inverseViewMatrix ??= Matrix.Identity();\r\n                Matrix.FromArrayToRef(viewMatrix.asArray(), 0, this._inverseViewMatrix).invertToRef(this._inverseViewMatrix);\r\n                effect.setMatrix(\"invView\", this._inverseViewMatrix);\r\n            }\r\n            if (drawCache.usesNormals) {\r\n                effect.setFloat(\"spriteNormalSign\", useRightHandedSystem ? 1 : -1);\r\n            }\r\n            if (drawCache.usesNormalizedDepth) {\r\n                const camera = this._scene?.activeCamera;\r\n                effect.setFloat2(\"cameraInfo\", camera?.minZ ?? 0, camera?.maxZ ?? 1);\r\n            }\r\n\r\n            if (drawCache.usesObjectId) {\r\n                effect.setFloat(\"objectId\", 0);\r\n            }\r\n            if (drawCache.usesMeshBlendTag) {\r\n                effect.setInt(\"meshBlendTag\", 0);\r\n            }\r\n            if (cameraHistory) {\r\n                effect.setMatrix(\"previousView\", cameraHistory.previousView);\r\n                effect.setMatrix(\"previousProjection\", cameraHistory.previousProjection);\r\n            }\r\n        }\r\n\r\n        // Scene Info\r\n        if (shouldRenderFog) {\r\n            const scene = this._scene;\r\n\r\n            // Fog\r\n            effect.setFloat4(\"vFogInfos\", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);\r\n            effect.setColor3(\"vFogColor\", scene.fogColor);\r\n        }\r\n\r\n        // Log. depth\r\n        if (this.useLogarithmicDepth && this._scene) {\r\n            BindLogDepth(drawWrapper.defines, effect, this._scene);\r\n        }\r\n\r\n        this._bindVertexBuffers(drawCache, effect);\r\n\r\n        // Draw order\r\n        engine.depthCullingState.depthFunc = engine.useReverseDepthBuffer ? Constants.GEQUAL : Constants.LEQUAL;\r\n        if (!this.disableDepthWrite) {\r\n            effect.setBool(\"alphaTest\", true);\r\n            engine.setColorWrite(false);\r\n            engine.enableEffect(drawWrapperDepth);\r\n            if (this._useInstancing) {\r\n                engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, offset);\r\n            } else {\r\n                engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, (offset / 4) * 6);\r\n            }\r\n            engine.enableEffect(drawWrapper);\r\n            engine.setColorWrite(true);\r\n            effect.setBool(\"alphaTest\", false);\r\n        }\r\n\r\n        engine.setAlphaMode(this.blendMode);\r\n        if (drawCache.usesGeometryRendering) {\r\n            MaterialHelperGeometryRendering._BindZeroAlphaDiscard(engine, effect);\r\n        }\r\n        try {\r\n            if (MaterialHelperGeometryRendering._BindAttachmentsForEffect(engine, effect)) {\r\n                if (this._useInstancing) {\r\n                    engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, offset);\r\n                } else {\r\n                    engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, (offset / 4) * 6);\r\n                }\r\n            }\r\n        } finally {\r\n            MaterialHelperGeometryRendering._RestoreAttachments(engine);\r\n        }\r\n\r\n        if (this.autoResetAlpha) {\r\n            engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        }\r\n\r\n        // Restore Right Handed\r\n        if (useRightHandedSystem) {\r\n            this._scene.getEngine().setState(culling, zOffset, false, true, undefined, undefined, zOffsetUnits);\r\n        }\r\n\r\n        engine.unbindInstanceAttributes();\r\n    }\r\n\r\n    private _appendSpriteVertex(\r\n        index: number,\r\n        sprite: ThinSprite,\r\n        offsetX: number,\r\n        offsetY: number,\r\n        baseSize: ISize,\r\n        useRightHandedSystem: boolean,\r\n        customSpriteUpdate: Nullable<(sprite: ThinSprite, baseSize: ISize) => void>,\r\n        floatingOriginOffset: Vector3,\r\n        spriteHistory: Nullable<SpriteRendererSpriteHistory>,\r\n        writeHistory: boolean\r\n    ): void {\r\n        let arrayOffset = index * this._vertexBufferSize;\r\n\r\n        if (offsetX === 0) {\r\n            offsetX = this._epsilon;\r\n        } else if (offsetX === 1) {\r\n            offsetX = 1 - this._epsilon;\r\n        }\r\n\r\n        if (offsetY === 0) {\r\n            offsetY = this._epsilon;\r\n        } else if (offsetY === 1) {\r\n            offsetY = 1 - this._epsilon;\r\n        }\r\n\r\n        if (customSpriteUpdate) {\r\n            customSpriteUpdate(sprite, baseSize);\r\n        } else {\r\n            if (!sprite.cellIndex) {\r\n                sprite.cellIndex = 0;\r\n            }\r\n\r\n            const rowSize = baseSize.width / this.cellWidth;\r\n            const offset = (sprite.cellIndex / rowSize) >> 0;\r\n            sprite._xOffset = ((sprite.cellIndex - offset * rowSize) * this.cellWidth) / baseSize.width;\r\n            sprite._yOffset = (offset * this.cellHeight) / baseSize.height;\r\n            sprite._xSize = this.cellWidth;\r\n            sprite._ySize = this.cellHeight;\r\n        }\r\n\r\n        // Positions\r\n        this._vertexData[arrayOffset] = sprite.position.x - floatingOriginOffset.x;\r\n        this._vertexData[arrayOffset + 1] = sprite.position.y - floatingOriginOffset.y;\r\n        this._vertexData[arrayOffset + 2] = sprite.position.z - floatingOriginOffset.z;\r\n        this._vertexData[arrayOffset + 3] = sprite.angle;\r\n        // Options\r\n        this._vertexData[arrayOffset + 4] = sprite.width;\r\n        this._vertexData[arrayOffset + 5] = sprite.height;\r\n\r\n        if (!this._useInstancing) {\r\n            this._vertexData[arrayOffset + 6] = offsetX;\r\n            this._vertexData[arrayOffset + 7] = offsetY;\r\n        } else {\r\n            arrayOffset -= 2;\r\n        }\r\n\r\n        // Inverts according to Right Handed\r\n        if (useRightHandedSystem) {\r\n            this._vertexData[arrayOffset + 8] = sprite.invertU ? 0 : 1;\r\n        } else {\r\n            this._vertexData[arrayOffset + 8] = sprite.invertU ? 1 : 0;\r\n        }\r\n\r\n        this._vertexData[arrayOffset + 9] = sprite.invertV ? 1 : 0;\r\n\r\n        this._vertexData[arrayOffset + 10] = sprite._xOffset;\r\n        this._vertexData[arrayOffset + 11] = sprite._yOffset;\r\n        this._vertexData[arrayOffset + 12] = sprite._xSize / baseSize.width;\r\n        this._vertexData[arrayOffset + 13] = sprite._ySize / baseSize.height;\r\n\r\n        // Color\r\n        this._vertexData[arrayOffset + 14] = sprite.color.r;\r\n        this._vertexData[arrayOffset + 15] = sprite.color.g;\r\n        this._vertexData[arrayOffset + 16] = sprite.color.b;\r\n        this._vertexData[arrayOffset + 17] = sprite.color.a;\r\n\r\n        if (writeHistory && this._previousVertexData) {\r\n            const previousArrayOffset = index * 6;\r\n            this._previousVertexData[previousArrayOffset] = spriteHistory?.previousX ?? sprite.position.x - floatingOriginOffset.x;\r\n            this._previousVertexData[previousArrayOffset + 1] = spriteHistory?.previousY ?? sprite.position.y - floatingOriginOffset.y;\r\n            this._previousVertexData[previousArrayOffset + 2] = spriteHistory?.previousZ ?? sprite.position.z - floatingOriginOffset.z;\r\n            this._previousVertexData[previousArrayOffset + 3] = spriteHistory?.previousAngle ?? sprite.angle;\r\n            this._previousVertexData[previousArrayOffset + 4] = spriteHistory?.previousWidth ?? sprite.width;\r\n            this._previousVertexData[previousArrayOffset + 5] = spriteHistory?.previousHeight ?? sprite.height;\r\n        }\r\n    }\r\n\r\n    private _buildIndexBuffer(): void {\r\n        const indices = [];\r\n        let index = 0;\r\n        for (let count = 0; count < this._capacity; count++) {\r\n            indices.push(index);\r\n            indices.push(index + 1);\r\n            indices.push(index + 2);\r\n            indices.push(index);\r\n            indices.push(index + 2);\r\n            indices.push(index + 3);\r\n            index += 4;\r\n        }\r\n\r\n        this._indexBuffer = this._engine.createIndexBuffer(indices);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the renderer (after a context lost, for eg)\r\n     */\r\n    public rebuild(): void {\r\n        if (this._indexBuffer) {\r\n            this._buildIndexBuffer();\r\n        }\r\n\r\n        if (this._useVAO) {\r\n            for (const cache of this._drawCaches) {\r\n                if (cache) {\r\n                    cache.vertexArrayObject = undefined;\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const cache of this._drawCaches) {\r\n            if (cache?.usesVelocity) {\r\n                cache.cameraHistories = new WeakMap<object, SpriteRendererCameraHistory>();\r\n            }\r\n        }\r\n\r\n        this._buffer._rebuild();\r\n\r\n        for (const key in this._vertexBuffers) {\r\n            const vertexBuffer = this._vertexBuffers[key];\r\n            vertexBuffer._rebuild();\r\n        }\r\n\r\n        this._spriteBuffer?._rebuild();\r\n        this._previousBuffer?._rebuild();\r\n    }\r\n\r\n    /**\r\n     * Release associated resources\r\n     */\r\n    public dispose(): void {\r\n        this._engine._onReleaseRenderPassObservable?.remove(this._renderPassObserver);\r\n        this._renderPassObserver = null;\r\n        this._disposeDrawCaches();\r\n\r\n        if (this._buffer) {\r\n            this._buffer.dispose();\r\n            (<any>this._buffer) = null;\r\n        }\r\n\r\n        if (this._spriteBuffer) {\r\n            this._spriteBuffer.dispose();\r\n            (<any>this._spriteBuffer) = null;\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this._engine._releaseBuffer(this._indexBuffer);\r\n            (<any>this._indexBuffer) = null;\r\n        }\r\n\r\n        if (this.texture) {\r\n            this.texture.dispose();\r\n            (<any>this.texture) = null;\r\n        }\r\n        this._isDisposed = true;\r\n    }\r\n}\r\n","import { type IDisposable, type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer, Observable } from \"../Misc/observable\";\r\nimport { Vector3, TmpVectors, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { Sprite } from \"./sprite\";\r\nimport { RegisterSpriteSceneComponent, SpriteSceneComponent, type InternalSpriteAugmentedScene } from \"./spriteSceneComponent.pure\";\r\nimport { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { SceneComponentConstants } from \"../sceneComponent\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { WebRequest } from \"../Misc/webRequest\";\r\nimport { type SpriteRendererOptions, SpriteRenderer } from \"./spriteRenderer\";\r\nimport { type ThinSprite } from \"./thinSprite\";\r\nimport { type ISize } from \"../Maths/math.size\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { type Ray } from \"../Culling/ray\";\r\nimport { type IAssetContainer } from \"../IAssetContainer\";\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect\r\ndeclare const Reflect: any;\r\n\r\n/**\r\n * Defines the minimum interface to fulfill in order to be a sprite manager.\r\n */\r\nexport interface ISpriteManager extends IDisposable {\r\n    /**\r\n     * Gets or sets the unique id of the sprite manager\r\n     */\r\n    uniqueId: number;\r\n\r\n    /**\r\n     * Gets manager's name\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * Restricts the camera to viewing objects with the same layerMask.\r\n     * A camera with a layerMask of 1 will render spriteManager.layerMask & camera.layerMask!== 0\r\n     */\r\n    layerMask: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mesh can be picked (by scene.pick for instance or through actions). Default is true\r\n     */\r\n    isPickable: boolean;\r\n\r\n    /**\r\n     * Gets the hosting scene\r\n     */\r\n    scene: Scene;\r\n\r\n    /**\r\n     * Specifies the rendering group id for this mesh (0 by default)\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering#rendering-groups\r\n     */\r\n    renderingGroupId: number;\r\n\r\n    /**\r\n     * Defines the list of sprites managed by the manager.\r\n     */\r\n    sprites: Array<Sprite>;\r\n\r\n    /**\r\n     * Gets or sets the spritesheet texture\r\n     */\r\n    texture: Texture;\r\n\r\n    /** Defines the default width of a cell in the spritesheet */\r\n    cellWidth: number;\r\n    /** Defines the default height of a cell in the spritesheet */\r\n    cellHeight: number;\r\n\r\n    /** @internal */\r\n    _wasDispatched: boolean;\r\n\r\n    /**\r\n     * Specifies if the sprite manager should be serialized\r\n     */\r\n    doNotSerialize?: boolean;\r\n\r\n    /**\r\n     * Tests the intersection of a sprite with a specific ray.\r\n     * @param ray The ray we are sending to test the collision\r\n     * @param camera The camera space we are sending rays in\r\n     * @param predicate A predicate allowing excluding sprites from the list of object to test\r\n     * @param fastCheck defines if the first intersection will be used (and not the closest)\r\n     * @returns picking info or null.\r\n     */\r\n    intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): Nullable<PickingInfo>;\r\n\r\n    /**\r\n     * Intersects the sprites with a ray\r\n     * @param ray defines the ray to intersect with\r\n     * @param camera defines the current active camera\r\n     * @param predicate defines a predicate used to select candidate sprites\r\n     * @returns null if no hit or a PickingInfo array\r\n     */\r\n    multiIntersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean): Nullable<PickingInfo[]>;\r\n\r\n    /**\r\n     * Checks whether this manager can render its sprites in the current render pass.\r\n     * Optional for custom sprite manager implementations.\r\n     * @returns true when the manager is ready to render\r\n     */\r\n    isReady?(): boolean;\r\n\r\n    /**\r\n     * Renders the list of sprites on screen.\r\n     */\r\n    render(): void;\r\n\r\n    /**\r\n     * Rebuilds the manager (after a context lost, for eg)\r\n     */\r\n    rebuild(): void;\r\n\r\n    /**\r\n     * Serializes the sprite manager to a JSON object\r\n     * @param serializeTexture defines whether the texture must be serialized as well (false by default)\r\n     */\r\n    serialize(serializeTexture?: boolean): any;\r\n}\r\n\r\n/**\r\n * Options for the SpriteManager\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SpriteManagerOptions {\r\n    /** Options for the sprite renderer */\r\n    spriteRendererOptions: SpriteRendererOptions;\r\n}\r\n\r\n/**\r\n * Class used to manage multiple sprites on the same spritesheet\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/sprites\r\n */\r\nexport class SpriteManager implements ISpriteManager {\r\n    /** @internal */\r\n    public _parentContainer: Nullable<IAssetContainer> = null;\r\n\r\n    /** Define the Url to load snippets */\r\n    public static SnippetUrl = Constants.SnippetUrl;\r\n\r\n    /** Snippet ID if the manager was created from the snippet server */\r\n    public snippetId: string;\r\n\r\n    /** Gets the list of sprites */\r\n    public sprites: Sprite[] = [];\r\n    /** Gets or sets the rendering group id (0 by default) */\r\n    public renderingGroupId = 0;\r\n    /** Gets or sets camera layer mask */\r\n    public layerMask: number = 0x0fffffff;\r\n    /** Gets or sets a boolean indicating if the sprites are pickable */\r\n    public isPickable = false;\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the sprite manager\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /** @internal */\r\n    public _wasDispatched = false;\r\n\r\n    /**\r\n     * An event triggered when the manager is disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<SpriteManager>();\r\n\r\n    /**\r\n     * Callback called when the manager is disposed\r\n     */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the unique id of the sprite\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Specifies if the sprite manager should be serialized\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    /**\r\n     * Gets the array of sprites\r\n     */\r\n    public get children() {\r\n        return this.sprites;\r\n    }\r\n\r\n    /**\r\n     * Gets the hosting scene\r\n     */\r\n    public get scene() {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets the capacity of the manager\r\n     */\r\n    public get capacity() {\r\n        return this._spriteRenderer.capacity;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the spritesheet texture\r\n     */\r\n    public get texture(): Texture {\r\n        return this._spriteRenderer.texture as Texture;\r\n    }\r\n    public set texture(value: Texture) {\r\n        value.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        value.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._spriteRenderer.texture = value;\r\n        this._textureContent = null;\r\n    }\r\n\r\n    /** Defines the default width of a cell in the spritesheet */\r\n    public get cellWidth(): number {\r\n        return this._spriteRenderer.cellWidth;\r\n    }\r\n    public set cellWidth(value: number) {\r\n        this._spriteRenderer.cellWidth = value;\r\n    }\r\n\r\n    /** Defines the default height of a cell in the spritesheet */\r\n    public get cellHeight(): number {\r\n        return this._spriteRenderer.cellHeight;\r\n    }\r\n    public set cellHeight(value: number) {\r\n        this._spriteRenderer.cellHeight = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the manager must consider scene fog when rendering */\r\n    public get fogEnabled(): boolean {\r\n        return this._spriteRenderer.fogEnabled;\r\n    }\r\n    public set fogEnabled(value: boolean) {\r\n        this._spriteRenderer.fogEnabled = value;\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the manager must use logarithmic depth when rendering */\r\n    public get useLogarithmicDepth(): boolean {\r\n        return this._spriteRenderer.useLogarithmicDepth;\r\n    }\r\n    public set useLogarithmicDepth(value: boolean) {\r\n        this._spriteRenderer.useLogarithmicDepth = value;\r\n    }\r\n\r\n    /**\r\n     * Blend mode use to render the particle, it can be any of\r\n     * the static Constants.ALPHA_x properties provided in this class.\r\n     * Default value is Constants.ALPHA_COMBINE\r\n     */\r\n    public get blendMode() {\r\n        return this._spriteRenderer.blendMode;\r\n    }\r\n    public set blendMode(blendMode: number) {\r\n        this._spriteRenderer.blendMode = blendMode;\r\n    }\r\n\r\n    private _disableDepthWrite: boolean = false;\r\n    /** Disables writing to the depth buffer when rendering the sprites.\r\n     *  It can be handy to disable depth writing when using textures without alpha channel\r\n     *  and setting some specific blend modes.\r\n     */\r\n    public get disableDepthWrite() {\r\n        return this._disableDepthWrite;\r\n    }\r\n\r\n    public set disableDepthWrite(value: boolean) {\r\n        this._disableDepthWrite = value;\r\n        this._spriteRenderer.disableDepthWrite = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the renderer must render sprites with pixel perfect rendering\r\n     * In this mode, sprites are rendered as \"pixel art\", which means that they appear as pixelated but remain stable when moving or when rotated or scaled.\r\n     * Note that for this mode to work as expected, the sprite texture must use the BILINEAR sampling mode, not NEAREST!\r\n     */\r\n    public get pixelPerfect() {\r\n        return this._spriteRenderer.pixelPerfect;\r\n    }\r\n\r\n    public set pixelPerfect(value: boolean) {\r\n        this._spriteRenderer.pixelPerfect = value;\r\n        if (value && this.texture.samplingMode !== Constants.TEXTURE_TRILINEAR_SAMPLINGMODE) {\r\n            this.texture.updateSamplingMode(Constants.TEXTURE_TRILINEAR_SAMPLINGMODE);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the sprite renderer associated with this manager\r\n     */\r\n    public get spriteRenderer() {\r\n        return this._spriteRenderer;\r\n    }\r\n\r\n    private _spriteRenderer: SpriteRenderer;\r\n    /** Associative array from JSON sprite data file */\r\n    private _cellData: any;\r\n    /** Array of sprite names from JSON sprite data file */\r\n    private _spriteMap: Array<string>;\r\n    /** True when packed cell data from JSON file is ready*/\r\n    private _packedAndReady: boolean = false;\r\n    private _textureContent: Nullable<Uint8Array>;\r\n    private _onDisposeObserver: Nullable<Observer<SpriteManager>>;\r\n    private _fromPacked: boolean;\r\n    private _scene: InternalSpriteAugmentedScene;\r\n\r\n    /**\r\n     * Creates a new sprite manager\r\n     * @param name defines the manager's name\r\n     * @param imgUrl defines the sprite sheet url\r\n     * @param capacity defines the maximum allowed number of sprites\r\n     * @param cellSize defines the size of a sprite cell\r\n     * @param scene defines the hosting scene\r\n     * @param epsilon defines the epsilon value to align texture (0.01 by default)\r\n     * @param samplingMode defines the sampling mode to use with spritesheet\r\n     * @param fromPacked set to false; do not alter\r\n     * @param spriteJSON null otherwise a JSON object defining sprite sheet data; do not alter\r\n     * @param options options used to create the SpriteManager instance\r\n     */\r\n    constructor(\r\n        /** defines the manager's name */\r\n        public name: string,\r\n        imgUrl: string,\r\n        capacity: number,\r\n        cellSize: any,\r\n        scene: Scene,\r\n        epsilon: number = 0.01,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        fromPacked: boolean = false,\r\n        spriteJSON: null | string = null,\r\n        options?: SpriteManagerOptions\r\n    ) {\r\n        if (!scene) {\r\n            scene = EngineStore.LastCreatedScene!;\r\n        }\r\n        this.layerMask = scene.defaultRenderableLayerMask;\r\n\r\n        RegisterSpriteSceneComponent();\r\n\r\n        if (!scene._getComponent(SceneComponentConstants.NAME_SPRITE)) {\r\n            scene._addComponent(new SpriteSceneComponent(scene));\r\n        }\r\n        this._fromPacked = fromPacked;\r\n\r\n        this._scene = scene as InternalSpriteAugmentedScene;\r\n        const engine = this._scene.getEngine();\r\n        this._spriteRenderer = new SpriteRenderer(engine, capacity, epsilon, scene, options?.spriteRendererOptions);\r\n\r\n        if (cellSize.width && cellSize.height) {\r\n            this.cellWidth = cellSize.width;\r\n            this.cellHeight = cellSize.height;\r\n        } else if (cellSize !== undefined) {\r\n            this.cellWidth = cellSize;\r\n            this.cellHeight = cellSize;\r\n        } else {\r\n            this._spriteRenderer = <any>null;\r\n            return;\r\n        }\r\n\r\n        this._scene.spriteManagers && this._scene.spriteManagers.push(this);\r\n        this.uniqueId = this.scene.getUniqueId();\r\n\r\n        if (imgUrl) {\r\n            this.texture = new Texture(imgUrl, scene, true, false, samplingMode);\r\n        }\r\n\r\n        if (this._fromPacked) {\r\n            this._makePacked(imgUrl, spriteJSON);\r\n        }\r\n\r\n        this._scene._onNewSpriteManagerAddedObservable?.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"SpriteManager\"\r\n     * @returns \"SpriteManager\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"SpriteManager\";\r\n    }\r\n\r\n    private _makePacked(imgUrl: string, spriteJSON: any) {\r\n        if (spriteJSON !== null) {\r\n            try {\r\n                //Get the JSON and Check its structure.  If its an array parse it if its a JSON string etc...\r\n                let celldata: any;\r\n                if (typeof spriteJSON === \"string\") {\r\n                    celldata = JSON.parse(spriteJSON);\r\n                } else {\r\n                    celldata = spriteJSON;\r\n                }\r\n\r\n                if (celldata.frames.length) {\r\n                    const frametemp: any = {};\r\n                    for (let i = 0; i < celldata.frames.length; i++) {\r\n                        const _f = celldata.frames[i];\r\n                        if (typeof Object.keys(_f)[0] !== \"string\") {\r\n                            throw new Error(\"Invalid JSON Format.  Check the frame values and make sure the name is the first parameter.\");\r\n                        }\r\n\r\n                        const name: string = _f[Object.keys(_f)[0]];\r\n                        frametemp[name] = _f;\r\n                    }\r\n                    celldata.frames = frametemp;\r\n                }\r\n\r\n                const spritemap = <string[]>Reflect.ownKeys(celldata.frames);\r\n\r\n                this._spriteMap = spritemap;\r\n                this._packedAndReady = true;\r\n                this._cellData = celldata.frames;\r\n            } catch (e) {\r\n                this._fromPacked = false;\r\n                this._packedAndReady = false;\r\n                throw new Error(\"Invalid JSON from string. Spritesheet managed with constant cell size.\", { cause: e });\r\n            }\r\n        } else {\r\n            const re = /\\./g;\r\n            let li: number;\r\n            do {\r\n                li = re.lastIndex;\r\n                re.test(imgUrl);\r\n            } while (re.lastIndex > 0);\r\n            const jsonUrl = imgUrl.substring(0, li - 1) + \".json\";\r\n            const onerror = () => {\r\n                Logger.Error(\"JSON ERROR: Unable to load JSON file.\");\r\n                this._fromPacked = false;\r\n                this._packedAndReady = false;\r\n            };\r\n            const onload = (data: string | ArrayBuffer) => {\r\n                try {\r\n                    const celldata = JSON.parse(data as string);\r\n                    const spritemap = <string[]>Reflect.ownKeys(celldata.frames);\r\n                    this._spriteMap = spritemap;\r\n                    this._packedAndReady = true;\r\n                    this._cellData = celldata.frames;\r\n                } catch (e) {\r\n                    this._fromPacked = false;\r\n                    this._packedAndReady = false;\r\n                    throw new Error(\"Invalid JSON format. Please check documentation for format specifications.\", { cause: e });\r\n                }\r\n            };\r\n            Tools.LoadFile(jsonUrl, onload, undefined, undefined, false, onerror);\r\n        }\r\n    }\r\n\r\n    private _checkTextureAlpha(sprite: Sprite, ray: Ray, distance: number, min: Vector3, max: Vector3) {\r\n        if (!sprite.useAlphaForPicking || !this.texture?.isReady()) {\r\n            return true;\r\n        }\r\n\r\n        const textureSize = this.texture.getSize();\r\n        if (!this._textureContent) {\r\n            this._textureContent = new Uint8Array(textureSize.width * textureSize.height * 4);\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            this.texture.readPixels(0, 0, this._textureContent);\r\n        }\r\n\r\n        const contactPoint = TmpVectors.Vector3[0];\r\n\r\n        contactPoint.copyFrom(ray.direction);\r\n\r\n        contactPoint.normalize();\r\n        contactPoint.scaleInPlace(distance);\r\n        contactPoint.addInPlace(ray.origin);\r\n\r\n        const contactPointU = (contactPoint.x - min.x) / (max.x - min.x);\r\n        const contactPointV = 1.0 - (contactPoint.y - min.y) / (max.y - min.y);\r\n\r\n        const u = (sprite._xOffset * textureSize.width + contactPointU * sprite._xSize) | 0;\r\n        const v = (sprite._yOffset * textureSize.height + contactPointV * sprite._ySize) | 0;\r\n\r\n        const alpha = this._textureContent[(u + v * textureSize.width) * 4 + 3];\r\n\r\n        return alpha > 0.5;\r\n    }\r\n\r\n    /**\r\n     * Intersects the sprites with a ray\r\n     * @param ray defines the ray to intersect with\r\n     * @param camera defines the current active camera\r\n     * @param predicate defines a predicate used to select candidate sprites\r\n     * @param fastCheck defines if a fast check only must be done (the first potential sprite is will be used and not the closer)\r\n     * @returns null if no hit or a PickingInfo\r\n     */\r\n    public intersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean): Nullable<PickingInfo> {\r\n        const count = Math.min(this.capacity, this.sprites.length);\r\n        const min = Vector3.Zero();\r\n        const max = Vector3.Zero();\r\n        let distance = Number.MAX_VALUE;\r\n        let currentSprite: Nullable<Sprite> = null;\r\n        const pickedPoint = TmpVectors.Vector3[0];\r\n        const cameraSpacePosition = TmpVectors.Vector3[1];\r\n        const cameraView = camera.getViewMatrix();\r\n        let activeRay: Ray;\r\n        let pickedRay!: Ray;\r\n\r\n        for (let index = 0; index < count; index++) {\r\n            const sprite = this.sprites[index];\r\n            if (!sprite) {\r\n                continue;\r\n            }\r\n\r\n            if (predicate) {\r\n                if (!predicate(sprite)) {\r\n                    continue;\r\n                }\r\n            } else if (!sprite.isPickable) {\r\n                continue;\r\n            }\r\n\r\n            Vector3.TransformCoordinatesToRef(sprite.position, cameraView, cameraSpacePosition);\r\n\r\n            if (sprite.angle) {\r\n                // Create a rotation matrix to rotate the ray to the sprite's rotation\r\n                Matrix.TranslationToRef(-cameraSpacePosition.x, -cameraSpacePosition.y, 0, TmpVectors.Matrix[1]);\r\n                Matrix.TranslationToRef(cameraSpacePosition.x, cameraSpacePosition.y, 0, TmpVectors.Matrix[2]);\r\n                Matrix.RotationZToRef(-sprite.angle, TmpVectors.Matrix[3]);\r\n\r\n                // inv translation x rotation x translation\r\n                TmpVectors.Matrix[1].multiplyToRef(TmpVectors.Matrix[3], TmpVectors.Matrix[4]);\r\n                TmpVectors.Matrix[4].multiplyToRef(TmpVectors.Matrix[2], TmpVectors.Matrix[0]);\r\n\r\n                activeRay = ray.clone();\r\n                Vector3.TransformCoordinatesToRef(ray.origin, TmpVectors.Matrix[0], activeRay.origin);\r\n                Vector3.TransformNormalToRef(ray.direction, TmpVectors.Matrix[0], activeRay.direction);\r\n            } else {\r\n                activeRay = ray;\r\n            }\r\n\r\n            min.copyFromFloats(cameraSpacePosition.x - sprite.width / 2, cameraSpacePosition.y - sprite.height / 2, cameraSpacePosition.z);\r\n            max.copyFromFloats(cameraSpacePosition.x + sprite.width / 2, cameraSpacePosition.y + sprite.height / 2, cameraSpacePosition.z);\r\n\r\n            if (activeRay.intersectsBoxMinMax(min, max)) {\r\n                const currentDistance = Vector3.Distance(cameraSpacePosition, activeRay.origin);\r\n\r\n                if (distance > currentDistance) {\r\n                    if (!this._checkTextureAlpha(sprite, activeRay, currentDistance, min, max)) {\r\n                        continue;\r\n                    }\r\n\r\n                    pickedRay = activeRay;\r\n                    distance = currentDistance;\r\n                    currentSprite = sprite;\r\n\r\n                    if (fastCheck) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (currentSprite) {\r\n            const result = new PickingInfo();\r\n\r\n            cameraView.invertToRef(TmpVectors.Matrix[0]);\r\n            result.hit = true;\r\n            result.pickedSprite = currentSprite;\r\n            result.distance = distance;\r\n\r\n            // Get picked point\r\n            const direction = TmpVectors.Vector3[2];\r\n            direction.copyFrom(pickedRay.direction);\r\n            direction.normalize();\r\n            direction.scaleInPlace(distance);\r\n\r\n            pickedRay.origin.addToRef(direction, pickedPoint);\r\n            result.pickedPoint = Vector3.TransformCoordinates(pickedPoint, TmpVectors.Matrix[0]);\r\n\r\n            return result;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Intersects the sprites with a ray\r\n     * @param ray defines the ray to intersect with\r\n     * @param camera defines the current active camera\r\n     * @param predicate defines a predicate used to select candidate sprites\r\n     * @returns null if no hit or a PickingInfo array\r\n     */\r\n    public multiIntersects(ray: Ray, camera: Camera, predicate?: (sprite: Sprite) => boolean): Nullable<PickingInfo[]> {\r\n        const count = Math.min(this.capacity, this.sprites.length);\r\n        const min = Vector3.Zero();\r\n        const max = Vector3.Zero();\r\n        let distance: number;\r\n        const results: Nullable<PickingInfo[]> = [];\r\n        const pickedPoint = TmpVectors.Vector3[0].copyFromFloats(0, 0, 0);\r\n        const cameraSpacePosition = TmpVectors.Vector3[1].copyFromFloats(0, 0, 0);\r\n        const cameraView = camera.getViewMatrix();\r\n\r\n        for (let index = 0; index < count; index++) {\r\n            const sprite = this.sprites[index];\r\n            if (!sprite) {\r\n                continue;\r\n            }\r\n\r\n            if (predicate) {\r\n                if (!predicate(sprite)) {\r\n                    continue;\r\n                }\r\n            } else if (!sprite.isPickable) {\r\n                continue;\r\n            }\r\n\r\n            Vector3.TransformCoordinatesToRef(sprite.position, cameraView, cameraSpacePosition);\r\n\r\n            min.copyFromFloats(cameraSpacePosition.x - sprite.width / 2, cameraSpacePosition.y - sprite.height / 2, cameraSpacePosition.z);\r\n            max.copyFromFloats(cameraSpacePosition.x + sprite.width / 2, cameraSpacePosition.y + sprite.height / 2, cameraSpacePosition.z);\r\n\r\n            if (ray.intersectsBoxMinMax(min, max)) {\r\n                distance = Vector3.Distance(cameraSpacePosition, ray.origin);\r\n\r\n                if (!this._checkTextureAlpha(sprite, ray, distance, min, max)) {\r\n                    continue;\r\n                }\r\n\r\n                const result = new PickingInfo();\r\n                results.push(result);\r\n\r\n                cameraView.invertToRef(TmpVectors.Matrix[0]);\r\n                result.hit = true;\r\n                result.pickedSprite = sprite;\r\n                result.distance = distance;\r\n\r\n                // Get picked point\r\n                const direction = TmpVectors.Vector3[2];\r\n                direction.copyFrom(ray.direction);\r\n                direction.normalize();\r\n                direction.scaleInPlace(distance);\r\n\r\n                ray.origin.addToRef(direction, pickedPoint);\r\n                result.pickedPoint = Vector3.TransformCoordinates(pickedPoint, TmpVectors.Matrix[0]);\r\n            }\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    /**\r\n     * Checks whether the sprite data, texture and current render-pass shader are ready.\r\n     * An empty sprite manager is ready without preparing rendering resources.\r\n     * @returns true when all required resources are ready\r\n     * @see https://playground.babylonjs.com/#PVK3RV#2\r\n     */\r\n    public isReady(): boolean {\r\n        if (this.sprites.length === 0) {\r\n            return true;\r\n        }\r\n        if (this._fromPacked && (!this._packedAndReady || !this._spriteMap || !this._cellData)) {\r\n            return false;\r\n        }\r\n        return this._spriteRenderer.isReady();\r\n    }\r\n\r\n    /**\r\n     * Render all child sprites\r\n     */\r\n    public render(): void {\r\n        // Check\r\n        if (this._fromPacked && (!this._packedAndReady || !this._spriteMap || !this._cellData)) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._scene.getEngine();\r\n        const deltaTime = engine.getDeltaTime();\r\n        if (this._packedAndReady) {\r\n            this._spriteRenderer.render(this.sprites, deltaTime, this._scene.getViewMatrix(), this._scene.getProjectionMatrix(), this._customUpdate);\r\n        } else {\r\n            this._spriteRenderer.render(this.sprites, deltaTime, this._scene.getViewMatrix(), this._scene.getProjectionMatrix());\r\n        }\r\n    }\r\n\r\n    private _customUpdate = (sprite: ThinSprite, baseSize: ISize): void => {\r\n        if (!sprite.cellRef) {\r\n            sprite.cellIndex = 0;\r\n        }\r\n        const num = sprite.cellIndex;\r\n        if (typeof num === \"number\" && isFinite(num) && Math.floor(num) === num) {\r\n            sprite.cellRef = this._spriteMap[sprite.cellIndex];\r\n        }\r\n        sprite._xOffset = this._cellData[sprite.cellRef].frame.x / baseSize.width;\r\n        sprite._yOffset = this._cellData[sprite.cellRef].frame.y / baseSize.height;\r\n        sprite._xSize = this._cellData[sprite.cellRef].frame.w;\r\n        sprite._ySize = this._cellData[sprite.cellRef].frame.h;\r\n    };\r\n\r\n    /**\r\n     * Rebuilds the manager (after a context lost, for eg)\r\n     */\r\n    public rebuild(): void {\r\n        this._spriteRenderer?.rebuild();\r\n    }\r\n\r\n    /**\r\n     * Release associated resources\r\n     */\r\n    public dispose(): void {\r\n        if (this._spriteRenderer) {\r\n            this._spriteRenderer.dispose();\r\n            (<any>this._spriteRenderer) = null;\r\n        }\r\n\r\n        this._textureContent = null;\r\n\r\n        // Remove from scene\r\n        if (this._scene.spriteManagers) {\r\n            const index = this._scene.spriteManagers.indexOf(this);\r\n            this._scene.spriteManagers.splice(index, 1);\r\n            this._scene._onSpriteManagerRemovedObservable?.notifyObservers(this);\r\n        }\r\n\r\n        if (this._parentContainer && this._parentContainer.spriteManagers) {\r\n            const index = this._parentContainer.spriteManagers.indexOf(this);\r\n            if (index > -1) {\r\n                this._parentContainer.spriteManagers.splice(index, 1);\r\n            }\r\n            this._parentContainer = null;\r\n        }\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n\r\n        this.metadata = null;\r\n    }\r\n\r\n    /**\r\n     * Serializes the sprite manager to a JSON object\r\n     * @param serializeTexture defines if the texture must be serialized as well\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(serializeTexture = false): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.capacity = this.capacity;\r\n        serializationObject.cellWidth = this.cellWidth;\r\n        serializationObject.cellHeight = this.cellHeight;\r\n        serializationObject.fogEnabled = this.fogEnabled;\r\n        serializationObject.blendMode = this.blendMode;\r\n        serializationObject.disableDepthWrite = this.disableDepthWrite;\r\n        serializationObject.pixelPerfect = this.pixelPerfect;\r\n        serializationObject.useLogarithmicDepth = this.useLogarithmicDepth;\r\n\r\n        if (this.texture) {\r\n            if (serializeTexture) {\r\n                serializationObject.texture = this.texture.serialize();\r\n            } else {\r\n                serializationObject.textureUrl = this.texture.name;\r\n                serializationObject.invertY = this.texture._invertY;\r\n            }\r\n        }\r\n\r\n        serializationObject.sprites = [];\r\n\r\n        for (const sprite of this.sprites) {\r\n            serializationObject.sprites.push(sprite.serialize());\r\n        }\r\n\r\n        serializationObject.metadata = this.metadata;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON object to create a new sprite manager.\r\n     * @param parsedManager The JSON object to parse\r\n     * @param scene The scene to create the sprite manager\r\n     * @param rootUrl The root url to use to load external dependencies like texture\r\n     * @returns the new sprite manager\r\n     */\r\n    public static Parse(parsedManager: any, scene: Scene, rootUrl: string): SpriteManager {\r\n        const manager = new SpriteManager(\r\n            parsedManager.name,\r\n            \"\",\r\n            parsedManager.capacity,\r\n            {\r\n                width: parsedManager.cellWidth,\r\n                height: parsedManager.cellHeight,\r\n            },\r\n            scene\r\n        );\r\n\r\n        if (parsedManager.fogEnabled !== undefined) {\r\n            manager.fogEnabled = parsedManager.fogEnabled;\r\n        }\r\n        if (parsedManager.blendMode !== undefined) {\r\n            manager.blendMode = parsedManager.blendMode;\r\n        }\r\n        if (parsedManager.disableDepthWrite !== undefined) {\r\n            manager.disableDepthWrite = parsedManager.disableDepthWrite;\r\n        }\r\n        if (parsedManager.pixelPerfect !== undefined) {\r\n            manager.pixelPerfect = parsedManager.pixelPerfect;\r\n        }\r\n        if (parsedManager.useLogarithmicDepth !== undefined) {\r\n            manager.useLogarithmicDepth = parsedManager.useLogarithmicDepth;\r\n        }\r\n\r\n        if (parsedManager.metadata !== undefined) {\r\n            manager.metadata = parsedManager.metadata;\r\n        }\r\n\r\n        if (parsedManager.texture) {\r\n            manager.texture = Texture.Parse(parsedManager.texture, scene, rootUrl) as Texture;\r\n        } else if (parsedManager.textureName) {\r\n            manager.texture = new Texture(rootUrl + parsedManager.textureUrl, scene, false, parsedManager.invertY !== undefined ? parsedManager.invertY : true);\r\n        }\r\n\r\n        for (const parsedSprite of parsedManager.sprites) {\r\n            Sprite.Parse(parsedSprite, manager);\r\n        }\r\n\r\n        return manager;\r\n    }\r\n\r\n    /**\r\n     * Creates a sprite manager from a snippet saved in a remote file\r\n     * @param name defines the name of the sprite manager to create (can be null or empty to use the one from the json data)\r\n     * @param url defines the url to load from\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @returns a promise that will resolve to the new sprite manager\r\n     */\r\n    public static async ParseFromFileAsync(name: Nullable<string>, url: string, scene: Scene, rootUrl: string = \"\"): Promise<SpriteManager> {\r\n        return await new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const serializationObject = JSON.parse(request.responseText);\r\n                        const output = SpriteManager.Parse(serializationObject, scene || EngineStore.LastCreatedScene, rootUrl);\r\n\r\n                        if (name) {\r\n                            output.name = name;\r\n                        }\r\n\r\n                        resolve(output);\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the sprite manager\");\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", url);\r\n            request.send();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a sprite manager from a snippet saved by the sprite editor\r\n     * @param snippetId defines the snippet to load (can be set to _BLANK to create a default one)\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @returns a promise that will resolve to the new sprite manager\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl: string = \"\"): Promise<SpriteManager> {\r\n        if (snippetId === \"_BLANK\") {\r\n            return Promise.resolve(new SpriteManager(\"Default sprite manager\", \"//playground.babylonjs.com/textures/player.png\", 500, 64, scene));\r\n        }\r\n\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n                        const serializationObject = JSON.parse(snippet.spriteManager);\r\n                        const output = SpriteManager.Parse(serializationObject, scene || EngineStore.LastCreatedScene, rootUrl);\r\n\r\n                        output.snippetId = snippetId;\r\n\r\n                        resolve(output);\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the snippet \" + snippetId);\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", this.SnippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\r\n            request.send();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a sprite manager from a snippet saved by the sprite editor\r\n     * @deprecated Please use ParseFromSnippetAsync instead\r\n     * @param snippetId defines the snippet to load (can be set to _BLANK to create a default one)\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @returns a promise that will resolve to the new sprite manager\r\n     */\r\n    public static CreateFromSnippetAsync = SpriteManager.ParseFromSnippetAsync;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable, type FloatArray } from \"../../../types\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { Vector3, Matrix, Quaternion } from \"../../../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../../../Buffers/buffer.pure\";\r\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh.pure\";\r\nimport { type IPhysicsEnginePlugin, type PhysicsImpostorJoint } from \"../IPhysicsEnginePlugin\";\r\nimport { PhysicsImpostor } from \"../physicsImpostor.pure\";\r\nimport { type IPhysicsEnabledObject } from \"../physicsImpostor\";\r\nimport { PhysicsJoint, type IMotorEnabledJoint, type DistanceJointData, type SpringJointData } from \"../physicsJoint\";\r\n\r\nimport { PhysicsRaycastResult } from \"../../physicsRaycastResult\";\r\nimport { type TransformNode } from \"../../../Meshes/transformNode.pure\";\r\nimport { Epsilon } from \"../../../Maths/math.constants\";\r\nimport { PhysicsEngine } from \"../physicsEngine\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unsafe-return */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n//declare var require: any;\r\ndeclare let CANNON: any;\r\n\r\n/** @internal */\r\nexport class CannonJSPlugin implements IPhysicsEnginePlugin {\r\n    public world: any;\r\n    public name: string = \"CannonJSPlugin\";\r\n    private _physicsMaterials: any[] = [];\r\n    private _fixedTimeStep: number = 1 / 60;\r\n    private _cannonRaycastResult: any;\r\n    private _raycastResult: PhysicsRaycastResult;\r\n    private _physicsBodiesToRemoveAfterStep = new Array<any>();\r\n    private _firstFrame = true;\r\n    private _tmpQuaternion: Quaternion = new Quaternion();\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public BJSCANNON: any;\r\n\r\n    public constructor(\r\n        private _useDeltaForWorldStep: boolean = true,\r\n        iterations: number = 10,\r\n        cannonInjection = CANNON\r\n    ) {\r\n        this.BJSCANNON = cannonInjection;\r\n        if (!this.isSupported()) {\r\n            Logger.Error(\"CannonJS is not available. Please make sure you included the js file.\");\r\n            return;\r\n        }\r\n\r\n        this._extendNamespace();\r\n\r\n        this.world = new this.BJSCANNON.World();\r\n        this.world.broadphase = new this.BJSCANNON.NaiveBroadphase();\r\n        this.world.solver.iterations = iterations;\r\n        this._cannonRaycastResult = new this.BJSCANNON.RaycastResult();\r\n        this._raycastResult = new PhysicsRaycastResult();\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @returns plugin version\r\n     */\r\n    public getPluginVersion(): number {\r\n        return 1;\r\n    }\r\n\r\n    public setGravity(gravity: Vector3): void {\r\n        const vec = gravity;\r\n        this.world.gravity.set(vec.x, vec.y, vec.z);\r\n    }\r\n\r\n    public setTimeStep(timeStep: number) {\r\n        this._fixedTimeStep = timeStep;\r\n    }\r\n\r\n    public getTimeStep(): number {\r\n        return this._fixedTimeStep;\r\n    }\r\n\r\n    public executeStep(delta: number, impostors: Array<PhysicsImpostor>): void {\r\n        // due to cannon's architecture, the first frame's before-step is skipped.\r\n        if (this._firstFrame) {\r\n            this._firstFrame = false;\r\n            for (const impostor of impostors) {\r\n                if (!(impostor.type == PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.PlaneImpostor)) {\r\n                    impostor.beforeStep();\r\n                }\r\n            }\r\n        }\r\n        this.world.step(this._useDeltaForWorldStep ? delta : this._fixedTimeStep);\r\n        this._removeMarkedPhysicsBodiesFromWorld();\r\n    }\r\n\r\n    private _removeMarkedPhysicsBodiesFromWorld(): void {\r\n        if (this._physicsBodiesToRemoveAfterStep.length > 0) {\r\n            for (const physicsBody of this._physicsBodiesToRemoveAfterStep) {\r\n                if (typeof this.world.removeBody === \"function\") {\r\n                    this.world.removeBody(physicsBody);\r\n                } else {\r\n                    this.world.remove(physicsBody);\r\n                }\r\n            }\r\n            this._physicsBodiesToRemoveAfterStep.length = 0;\r\n        }\r\n    }\r\n\r\n    public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {\r\n        const worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);\r\n        const impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);\r\n\r\n        impostor.physicsBody.applyImpulse(impulse, worldPoint);\r\n    }\r\n\r\n    public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {\r\n        const worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);\r\n        const impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);\r\n\r\n        impostor.physicsBody.applyForce(impulse, worldPoint);\r\n    }\r\n\r\n    public generatePhysicsBody(impostor: PhysicsImpostor) {\r\n        // When calling forceUpdate generatePhysicsBody is called again, ensure that the updated body does not instantly collide with removed body\r\n        this._removeMarkedPhysicsBodiesFromWorld();\r\n\r\n        //parent-child relationship. Does this impostor have a parent impostor?\r\n        if (impostor.parent) {\r\n            if (impostor.physicsBody) {\r\n                this.removePhysicsBody(impostor);\r\n                //TODO is that needed?\r\n                impostor.forceUpdate();\r\n            }\r\n            return;\r\n        }\r\n\r\n        //should a new body be created for this impostor?\r\n        if (impostor.isBodyInitRequired()) {\r\n            const shape = this._createShape(impostor);\r\n            if (!shape) {\r\n                Logger.Warn(\"It was not possible to create a physics body for this object.\");\r\n                return;\r\n            }\r\n\r\n            //unregister events if body is being changed\r\n            const oldBody = impostor.physicsBody;\r\n            if (oldBody) {\r\n                this.removePhysicsBody(impostor);\r\n            }\r\n\r\n            //create the body and material\r\n            const material = this._addMaterial(\"mat-\" + impostor.uniqueId, impostor.getParam(\"friction\"), impostor.getParam(\"restitution\"));\r\n\r\n            const bodyCreationObject = {\r\n                mass: impostor.getParam(\"mass\"),\r\n                material: material,\r\n            };\r\n            // A simple extend, in case native options were used.\r\n            const nativeOptions = impostor.getParam(\"nativeOptions\");\r\n            for (const key in nativeOptions) {\r\n                if (Object.prototype.hasOwnProperty.call(nativeOptions, key)) {\r\n                    (<any>bodyCreationObject)[key] = nativeOptions[key];\r\n                }\r\n            }\r\n            impostor.physicsBody = new this.BJSCANNON.Body(bodyCreationObject);\r\n            impostor.physicsBody.addEventListener(\"collide\", impostor.onCollide);\r\n            this.world.addEventListener(\"preStep\", impostor.beforeStep);\r\n            this.world.addEventListener(\"postStep\", impostor.afterStep);\r\n            impostor.physicsBody.addShape(shape);\r\n            if (typeof this.world.addBody === \"function\") {\r\n                this.world.addBody(impostor.physicsBody);\r\n            } else {\r\n                this.world.add(impostor.physicsBody);\r\n            }\r\n\r\n            //try to keep the body moving in the right direction by taking old properties.\r\n            //Should be tested!\r\n            if (oldBody) {\r\n                const props = [\"force\", \"torque\", \"velocity\", \"angularVelocity\"];\r\n                for (const param of props) {\r\n                    const vec = oldBody[param];\r\n                    impostor.physicsBody[param].set(vec.x, vec.y, vec.z);\r\n                }\r\n            }\r\n            this._processChildMeshes(impostor);\r\n        }\r\n\r\n        //now update the body's transformation\r\n        this._updatePhysicsBodyTransformation(impostor);\r\n    }\r\n\r\n    private _processChildMeshes(mainImpostor: PhysicsImpostor) {\r\n        const meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes(true) : [];\r\n        const mainRotation: Nullable<Quaternion> = mainImpostor.object.rotationQuaternion;\r\n        if (mainRotation) {\r\n            mainRotation.conjugateToRef(this._tmpQuaternion);\r\n        } else {\r\n            this._tmpQuaternion.set(0, 0, 0, 1);\r\n        }\r\n\r\n        if (meshChildren.length) {\r\n            const processMesh = (mesh: AbstractMesh) => {\r\n                if (!mesh.rotationQuaternion) {\r\n                    return;\r\n                }\r\n\r\n                const childImpostor = mesh.getPhysicsImpostor();\r\n                if (childImpostor) {\r\n                    const parent = childImpostor.parent;\r\n                    if (parent !== mainImpostor && mesh.parent) {\r\n                        const pPosition = mesh.getAbsolutePosition().subtract((mesh.parent as TransformNode).getAbsolutePosition());\r\n                        const q = mesh.rotationQuaternion.multiply(this._tmpQuaternion);\r\n\r\n                        if (childImpostor.physicsBody) {\r\n                            this.removePhysicsBody(childImpostor);\r\n                            childImpostor.physicsBody = null;\r\n                        }\r\n                        childImpostor.parent = mainImpostor;\r\n                        childImpostor.resetUpdateFlags();\r\n                        mainImpostor.physicsBody.addShape(\r\n                            this._createShape(childImpostor),\r\n                            new this.BJSCANNON.Vec3(pPosition.x, pPosition.y, pPosition.z),\r\n                            new this.BJSCANNON.Quaternion(q.x, q.y, q.z, q.w)\r\n                        );\r\n                        //Add the mass of the children.\r\n                        mainImpostor.physicsBody.mass += childImpostor.getParam(\"mass\");\r\n                    }\r\n                }\r\n                const meshes = mesh.getChildMeshes(true).filter((m) => !!m.physicsImpostor);\r\n\r\n                for (const mesh of meshes) {\r\n                    processMesh(mesh);\r\n                }\r\n            };\r\n            const meshes = meshChildren.filter((m) => !!m.physicsImpostor);\r\n\r\n            for (const mesh of meshes) {\r\n                processMesh(mesh);\r\n            }\r\n        }\r\n    }\r\n\r\n    public removePhysicsBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.removeEventListener(\"collide\", impostor.onCollide);\r\n        this.world.removeEventListener(\"preStep\", impostor.beforeStep);\r\n        this.world.removeEventListener(\"postStep\", impostor.afterStep);\r\n\r\n        // Only remove the physics body after the physics step to avoid disrupting cannon's internal state\r\n        if (this._physicsBodiesToRemoveAfterStep.indexOf(impostor.physicsBody) === -1) {\r\n            this._physicsBodiesToRemoveAfterStep.push(impostor.physicsBody);\r\n        }\r\n    }\r\n\r\n    public generateJoint(impostorJoint: PhysicsImpostorJoint) {\r\n        const mainBody = impostorJoint.mainImpostor.physicsBody;\r\n        const connectedBody = impostorJoint.connectedImpostor.physicsBody;\r\n        if (!mainBody || !connectedBody) {\r\n            return;\r\n        }\r\n        let constraint: any;\r\n        const jointData = impostorJoint.joint.jointData;\r\n        //TODO - https://github.com/schteppe/this.BJSCANNON.js/blob/gh-pages/demos/collisionFilter.html\r\n        const constraintData = {\r\n            pivotA: jointData.mainPivot ? new this.BJSCANNON.Vec3().set(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z) : null,\r\n            pivotB: jointData.connectedPivot ? new this.BJSCANNON.Vec3().set(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z) : null,\r\n            axisA: jointData.mainAxis ? new this.BJSCANNON.Vec3().set(jointData.mainAxis.x, jointData.mainAxis.y, jointData.mainAxis.z) : null,\r\n            axisB: jointData.connectedAxis ? new this.BJSCANNON.Vec3().set(jointData.connectedAxis.x, jointData.connectedAxis.y, jointData.connectedAxis.z) : null,\r\n            maxForce: jointData.nativeParams.maxForce,\r\n            collideConnected: !!jointData.collision,\r\n        };\r\n        switch (impostorJoint.joint.type) {\r\n            case PhysicsJoint.HingeJoint:\r\n            case PhysicsJoint.Hinge2Joint:\r\n                constraint = new this.BJSCANNON.HingeConstraint(mainBody, connectedBody, constraintData);\r\n                break;\r\n            case PhysicsJoint.DistanceJoint:\r\n                constraint = new this.BJSCANNON.DistanceConstraint(mainBody, connectedBody, (<DistanceJointData>jointData).maxDistance || 2);\r\n                break;\r\n            case PhysicsJoint.SpringJoint: {\r\n                const springData = <SpringJointData>jointData;\r\n                constraint = new this.BJSCANNON.Spring(mainBody, connectedBody, {\r\n                    restLength: springData.length,\r\n                    stiffness: springData.stiffness,\r\n                    damping: springData.damping,\r\n                    localAnchorA: constraintData.pivotA,\r\n                    localAnchorB: constraintData.pivotB,\r\n                });\r\n                break;\r\n            }\r\n            case PhysicsJoint.LockJoint:\r\n                constraint = new this.BJSCANNON.LockConstraint(mainBody, connectedBody, constraintData);\r\n                break;\r\n            case PhysicsJoint.PointToPointJoint:\r\n            case PhysicsJoint.BallAndSocketJoint:\r\n            default:\r\n                constraint = new this.BJSCANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotB, constraintData.maxForce);\r\n                break;\r\n        }\r\n        //set the collideConnected flag after the creation, since DistanceJoint ignores it.\r\n        constraint.collideConnected = !!jointData.collision;\r\n        impostorJoint.joint.physicsJoint = constraint;\r\n        //don't add spring as constraint, as it is not one.\r\n        if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {\r\n            this.world.addConstraint(constraint);\r\n        } else {\r\n            (<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback =\r\n                (<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback ||\r\n                function () {\r\n                    constraint.applyForce();\r\n                };\r\n            impostorJoint.mainImpostor.registerAfterPhysicsStep((<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback);\r\n        }\r\n    }\r\n\r\n    public removeJoint(impostorJoint: PhysicsImpostorJoint) {\r\n        if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {\r\n            this.world.removeConstraint(impostorJoint.joint.physicsJoint);\r\n        } else {\r\n            impostorJoint.mainImpostor.unregisterAfterPhysicsStep((<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback);\r\n        }\r\n    }\r\n\r\n    private _addMaterial(name: string, friction: number, restitution: number) {\r\n        let index;\r\n        let mat;\r\n\r\n        for (index = 0; index < this._physicsMaterials.length; index++) {\r\n            mat = this._physicsMaterials[index];\r\n\r\n            if (mat.friction === friction && mat.restitution === restitution) {\r\n                return mat;\r\n            }\r\n        }\r\n\r\n        const currentMat = new this.BJSCANNON.Material(name);\r\n        currentMat.friction = friction;\r\n        currentMat.restitution = restitution;\r\n\r\n        this._physicsMaterials.push(currentMat);\r\n        return currentMat;\r\n    }\r\n\r\n    private _checkWithEpsilon(value: number): number {\r\n        return value < Epsilon ? Epsilon : value;\r\n    }\r\n\r\n    private _createShape(impostor: PhysicsImpostor) {\r\n        const object = impostor.object;\r\n\r\n        let returnValue;\r\n        const impostorExtents = impostor.getObjectExtents();\r\n        switch (impostor.type) {\r\n            case PhysicsImpostor.SphereImpostor: {\r\n                const radiusX = impostorExtents.x;\r\n                const radiusY = impostorExtents.y;\r\n                const radiusZ = impostorExtents.z;\r\n\r\n                returnValue = new this.BJSCANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);\r\n\r\n                break;\r\n            }\r\n            //TMP also for cylinder - TODO Cannon supports cylinder natively.\r\n            case PhysicsImpostor.CylinderImpostor: {\r\n                let nativeParams = impostor.getParam(\"nativeOptions\");\r\n                if (!nativeParams) {\r\n                    nativeParams = {};\r\n                }\r\n                const radiusTop = nativeParams.radiusTop !== undefined ? nativeParams.radiusTop : this._checkWithEpsilon(impostorExtents.x) / 2;\r\n                const radiusBottom = nativeParams.radiusBottom !== undefined ? nativeParams.radiusBottom : this._checkWithEpsilon(impostorExtents.x) / 2;\r\n                const height = nativeParams.height !== undefined ? nativeParams.height : this._checkWithEpsilon(impostorExtents.y);\r\n                const numSegments = nativeParams.numSegments !== undefined ? nativeParams.numSegments : 16;\r\n                returnValue = new this.BJSCANNON.Cylinder(radiusTop, radiusBottom, height, numSegments);\r\n\r\n                // Rotate 90 degrees as this shape is horizontal in cannon\r\n                const quat = new this.BJSCANNON.Quaternion();\r\n                quat.setFromAxisAngle(new this.BJSCANNON.Vec3(1, 0, 0), -Math.PI / 2);\r\n                const translation = new this.BJSCANNON.Vec3(0, 0, 0);\r\n                returnValue.transformAllPoints(translation, quat);\r\n                break;\r\n            }\r\n            case PhysicsImpostor.BoxImpostor: {\r\n                const box = impostorExtents.scale(0.5);\r\n                returnValue = new this.BJSCANNON.Box(new this.BJSCANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));\r\n                break;\r\n            }\r\n            case PhysicsImpostor.PlaneImpostor:\r\n                Logger.Warn(\"Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead\");\r\n                returnValue = new this.BJSCANNON.Plane();\r\n                break;\r\n            case PhysicsImpostor.MeshImpostor: {\r\n                // should transform the vertex data to world coordinates!!\r\n                const rawVerts = object.getVerticesData ? object.getVerticesData(VertexBuffer.PositionKind) : [];\r\n                const rawFaces = object.getIndices ? object.getIndices() : [];\r\n                if (!rawVerts) {\r\n                    Logger.Warn(\"Tried to create a MeshImpostor for an object without vertices. This will fail.\");\r\n                    return;\r\n                }\r\n                // get only scale! so the object could transform correctly.\r\n                const oldPosition = object.position.clone();\r\n                const oldRotation = object.rotation && object.rotation.clone();\r\n                const oldQuaternion = object.rotationQuaternion && object.rotationQuaternion.clone();\r\n                object.position.copyFromFloats(0, 0, 0);\r\n                object.rotation && object.rotation.copyFromFloats(0, 0, 0);\r\n                object.rotationQuaternion && object.rotationQuaternion.copyFrom(impostor.getParentsRotation());\r\n\r\n                object.rotationQuaternion && object.parent && object.rotationQuaternion.conjugateInPlace();\r\n\r\n                const transform = object.computeWorldMatrix(true);\r\n                // convert rawVerts to object space\r\n                const transformedVertices: number[] = [];\r\n                let index: number;\r\n                for (index = 0; index < rawVerts.length; index += 3) {\r\n                    Vector3.TransformCoordinates(Vector3.FromArray(rawVerts, index), transform).toArray(transformedVertices, index);\r\n                }\r\n\r\n                Logger.Warn(\"MeshImpostor only collides against spheres.\");\r\n                returnValue = new this.BJSCANNON.Trimesh(transformedVertices, <number[]>rawFaces);\r\n                //now set back the transformation!\r\n                object.position.copyFrom(oldPosition);\r\n                oldRotation && object.rotation && object.rotation.copyFrom(oldRotation);\r\n                oldQuaternion && object.rotationQuaternion && object.rotationQuaternion.copyFrom(oldQuaternion);\r\n                break;\r\n            }\r\n            case PhysicsImpostor.HeightmapImpostor: {\r\n                const oldPosition2 = object.position.clone();\r\n                const oldRotation2 = object.rotation && object.rotation.clone();\r\n                const oldQuaternion2 = object.rotationQuaternion && object.rotationQuaternion.clone();\r\n                object.position.copyFromFloats(0, 0, 0);\r\n                object.rotation && object.rotation.copyFromFloats(0, 0, 0);\r\n                object.rotationQuaternion && object.rotationQuaternion.copyFrom(impostor.getParentsRotation());\r\n                object.rotationQuaternion && object.parent && object.rotationQuaternion.conjugateInPlace();\r\n                object.rotationQuaternion && object.rotationQuaternion.multiplyInPlace(this._minus90X);\r\n\r\n                returnValue = this._createHeightmap(object);\r\n                object.position.copyFrom(oldPosition2);\r\n                oldRotation2 && object.rotation && object.rotation.copyFrom(oldRotation2);\r\n                oldQuaternion2 && object.rotationQuaternion && object.rotationQuaternion.copyFrom(oldQuaternion2);\r\n                object.computeWorldMatrix(true);\r\n                break;\r\n            }\r\n            case PhysicsImpostor.ParticleImpostor:\r\n                returnValue = new this.BJSCANNON.Particle();\r\n                break;\r\n            case PhysicsImpostor.NoImpostor:\r\n                returnValue = new this.BJSCANNON.Box(new this.BJSCANNON.Vec3(0, 0, 0));\r\n                break;\r\n        }\r\n\r\n        return returnValue;\r\n    }\r\n\r\n    private _createHeightmap(object: IPhysicsEnabledObject, pointDepth?: number) {\r\n        let pos = <FloatArray>object.getVerticesData(VertexBuffer.PositionKind);\r\n        const transform = object.computeWorldMatrix(true);\r\n        // convert rawVerts to object space\r\n        const transformedVertices: number[] = [];\r\n        let index: number;\r\n        for (index = 0; index < pos.length; index += 3) {\r\n            Vector3.TransformCoordinates(Vector3.FromArray(pos, index), transform).toArray(transformedVertices, index);\r\n        }\r\n        pos = transformedVertices;\r\n        const matrix = new Array<Array<any>>();\r\n\r\n        //For now pointDepth will not be used and will be automatically calculated.\r\n        //Future reference - try and find the best place to add a reference to the pointDepth variable.\r\n        const arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);\r\n        const boundingInfo = object.getBoundingInfo();\r\n        const dim = Math.min(boundingInfo.boundingBox.extendSizeWorld.x, boundingInfo.boundingBox.extendSizeWorld.y);\r\n        const minY = boundingInfo.boundingBox.extendSizeWorld.z;\r\n\r\n        const elementSize = (dim * 2) / arraySize;\r\n\r\n        for (let i = 0; i < pos.length; i = i + 3) {\r\n            const x = Math.round(pos[i + 0] / elementSize + arraySize / 2);\r\n            const z = Math.round((pos[i + 1] / elementSize - arraySize / 2) * -1);\r\n            const y = -pos[i + 2] + minY;\r\n            if (!matrix[x]) {\r\n                matrix[x] = [];\r\n            }\r\n            if (!matrix[x][z]) {\r\n                matrix[x][z] = y;\r\n            }\r\n            matrix[x][z] = Math.max(y, matrix[x][z]);\r\n        }\r\n\r\n        for (let x = 0; x <= arraySize; ++x) {\r\n            if (!matrix[x]) {\r\n                let loc = 1;\r\n                while (!matrix[(x + loc) % arraySize]) {\r\n                    loc++;\r\n                }\r\n                matrix[x] = matrix[(x + loc) % arraySize].slice();\r\n                //console.log(\"missing x\", x);\r\n            }\r\n            for (let z = 0; z <= arraySize; ++z) {\r\n                if (!matrix[x][z]) {\r\n                    let loc = 1;\r\n                    let newValue;\r\n                    while (newValue === undefined) {\r\n                        newValue = matrix[x][(z + loc++) % arraySize];\r\n                    }\r\n                    matrix[x][z] = newValue;\r\n                }\r\n            }\r\n        }\r\n\r\n        const shape = new this.BJSCANNON.Heightfield(matrix, {\r\n            elementSize: elementSize,\r\n        });\r\n\r\n        //For future reference, needed for body transformation\r\n        shape.minY = minY;\r\n\r\n        return shape;\r\n    }\r\n\r\n    private _minus90X = new Quaternion(-0.7071067811865475, 0, 0, 0.7071067811865475);\r\n    private _plus90X = new Quaternion(0.7071067811865475, 0, 0, 0.7071067811865475);\r\n    private _tmpPosition: Vector3 = Vector3.Zero();\r\n    private _tmpDeltaPosition: Vector3 = Vector3.Zero();\r\n    private _tmpUnityRotation: Quaternion = new Quaternion();\r\n\r\n    private _updatePhysicsBodyTransformation(impostor: PhysicsImpostor) {\r\n        const object = impostor.object;\r\n        //make sure it is updated...\r\n        object.computeWorldMatrix && object.computeWorldMatrix(true);\r\n        if (!object.getBoundingInfo()) {\r\n            return;\r\n        }\r\n        const center = impostor.getObjectCenter();\r\n        //m.getAbsolutePosition().subtract(m.getBoundingInfo().boundingBox.centerWorld)\r\n        // The delta between the mesh position and the mesh bounding box center\r\n        this._tmpDeltaPosition.copyFrom(object.getAbsolutePivotPoint().subtract(center));\r\n        this._tmpDeltaPosition.divideInPlace(impostor.object.scaling);\r\n        this._tmpPosition.copyFrom(center);\r\n        let quaternion = object.rotationQuaternion;\r\n\r\n        if (!quaternion) {\r\n            return;\r\n        }\r\n\r\n        //is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.\r\n        //ideally these would be rotated at time of creation like cylinder but they dont extend ConvexPolyhedron\r\n        if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor) {\r\n            //-90 DEG in X, precalculated\r\n            quaternion = quaternion.multiply(this._minus90X);\r\n            //Invert! (Precalculated, 90 deg in X)\r\n            //No need to clone. this will never change.\r\n            impostor.setDeltaRotation(this._plus90X);\r\n        }\r\n\r\n        //If it is a heightfield, if should be centered.\r\n        if (impostor.type === PhysicsImpostor.HeightmapImpostor) {\r\n            const mesh = <AbstractMesh>(<any>object);\r\n            let boundingInfo = mesh.getBoundingInfo();\r\n            //calculate the correct body position:\r\n            const rotationQuaternion = mesh.rotationQuaternion;\r\n            mesh.rotationQuaternion = this._tmpUnityRotation;\r\n            mesh.computeWorldMatrix(true);\r\n\r\n            //get original center with no rotation\r\n            const c = center.clone();\r\n\r\n            let oldPivot = mesh.getPivotMatrix();\r\n            if (oldPivot) {\r\n                // create a copy the pivot Matrix as it is modified in place\r\n                oldPivot = oldPivot.clone();\r\n            } else {\r\n                oldPivot = Matrix.Identity();\r\n            }\r\n\r\n            //calculate the new center using a pivot (since this.BJSCANNON.js doesn't center height maps)\r\n            const p = Matrix.Translation(boundingInfo.boundingBox.extendSizeWorld.x, 0, -boundingInfo.boundingBox.extendSizeWorld.z);\r\n            mesh.setPreTransformMatrix(p);\r\n            mesh.computeWorldMatrix(true);\r\n            // force bounding box recomputation\r\n            boundingInfo = mesh.getBoundingInfo();\r\n\r\n            //calculate the translation\r\n            const translation = boundingInfo.boundingBox.centerWorld.subtract(center).subtract(mesh.position).negate();\r\n\r\n            this._tmpPosition.copyFromFloats(translation.x, translation.y - boundingInfo.boundingBox.extendSizeWorld.y, translation.z);\r\n            //add it inverted to the delta\r\n            this._tmpDeltaPosition.copyFrom(boundingInfo.boundingBox.centerWorld.subtract(c));\r\n            this._tmpDeltaPosition.y += boundingInfo.boundingBox.extendSizeWorld.y;\r\n            //rotation is back\r\n            mesh.rotationQuaternion = rotationQuaternion;\r\n\r\n            mesh.setPreTransformMatrix(oldPivot);\r\n            mesh.computeWorldMatrix(true);\r\n        } else if (impostor.type === PhysicsImpostor.MeshImpostor) {\r\n            this._tmpDeltaPosition.copyFromFloats(0, 0, 0);\r\n        }\r\n\r\n        impostor.setDeltaPosition(this._tmpDeltaPosition);\r\n        //Now update the impostor object\r\n        impostor.physicsBody.position.set(this._tmpPosition.x, this._tmpPosition.y, this._tmpPosition.z);\r\n        impostor.physicsBody.quaternion.set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);\r\n    }\r\n\r\n    public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {\r\n        impostor.object.position.set(impostor.physicsBody.position.x, impostor.physicsBody.position.y, impostor.physicsBody.position.z);\r\n        if (impostor.object.rotationQuaternion) {\r\n            const q = impostor.physicsBody.quaternion;\r\n            impostor.object.rotationQuaternion.set(q.x, q.y, q.z, q.w);\r\n        }\r\n    }\r\n\r\n    public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {\r\n        impostor.physicsBody.position.set(newPosition.x, newPosition.y, newPosition.z);\r\n        impostor.physicsBody.quaternion.set(newRotation.x, newRotation.y, newRotation.z, newRotation.w);\r\n    }\r\n\r\n    public isSupported(): boolean {\r\n        return this.BJSCANNON !== undefined;\r\n    }\r\n\r\n    public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {\r\n        impostor.physicsBody.velocity.set(velocity.x, velocity.y, velocity.z);\r\n    }\r\n\r\n    public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {\r\n        impostor.physicsBody.angularVelocity.set(velocity.x, velocity.y, velocity.z);\r\n    }\r\n\r\n    public getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {\r\n        const v = impostor.physicsBody.velocity;\r\n        if (!v) {\r\n            return null;\r\n        }\r\n        return new Vector3(v.x, v.y, v.z);\r\n    }\r\n    public getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {\r\n        const v = impostor.physicsBody.angularVelocity;\r\n        if (!v) {\r\n            return null;\r\n        }\r\n        return new Vector3(v.x, v.y, v.z);\r\n    }\r\n\r\n    public setBodyMass(impostor: PhysicsImpostor, mass: number) {\r\n        impostor.physicsBody.mass = mass;\r\n        impostor.physicsBody.updateMassProperties();\r\n    }\r\n\r\n    public getBodyMass(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.mass;\r\n    }\r\n\r\n    public getBodyFriction(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.material.friction;\r\n    }\r\n\r\n    public setBodyFriction(impostor: PhysicsImpostor, friction: number) {\r\n        impostor.physicsBody.material.friction = friction;\r\n    }\r\n\r\n    public getBodyRestitution(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.material.restitution;\r\n    }\r\n\r\n    public setBodyRestitution(impostor: PhysicsImpostor, restitution: number) {\r\n        impostor.physicsBody.material.restitution = restitution;\r\n    }\r\n\r\n    public sleepBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.sleep();\r\n    }\r\n\r\n    public wakeUpBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.wakeUp();\r\n    }\r\n\r\n    public updateDistanceJoint(joint: PhysicsJoint, maxDistance: number) {\r\n        joint.physicsJoint.distance = maxDistance;\r\n    }\r\n\r\n    public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number, motorIndex?: number) {\r\n        if (!motorIndex) {\r\n            joint.physicsJoint.enableMotor();\r\n            joint.physicsJoint.setMotorSpeed(speed);\r\n            if (maxForce) {\r\n                this.setLimit(joint, maxForce);\r\n            }\r\n        }\r\n    }\r\n\r\n    public setLimit(joint: IMotorEnabledJoint, minForce: number, maxForce?: number) {\r\n        joint.physicsJoint.motorEquation.maxForce = maxForce;\r\n        joint.physicsJoint.motorEquation.minForce = minForce === void 0 ? -minForce : minForce;\r\n    }\r\n\r\n    public syncMeshWithImpostor(mesh: AbstractMesh, impostor: PhysicsImpostor) {\r\n        const body = impostor.physicsBody;\r\n\r\n        mesh.position.x = body.position.x;\r\n        mesh.position.y = body.position.y;\r\n        mesh.position.z = body.position.z;\r\n\r\n        if (mesh.rotationQuaternion) {\r\n            mesh.rotationQuaternion.x = body.quaternion.x;\r\n            mesh.rotationQuaternion.y = body.quaternion.y;\r\n            mesh.rotationQuaternion.z = body.quaternion.z;\r\n            mesh.rotationQuaternion.w = body.quaternion.w;\r\n        }\r\n    }\r\n\r\n    public getRadius(impostor: PhysicsImpostor): number {\r\n        const shape = impostor.physicsBody.shapes[0];\r\n        return shape.boundingSphereRadius;\r\n    }\r\n\r\n    public getBoxSizeToRef(impostor: PhysicsImpostor, result: Vector3): void {\r\n        const shape = impostor.physicsBody.shapes[0];\r\n        result.x = shape.halfExtents.x * 2;\r\n        result.y = shape.halfExtents.y * 2;\r\n        result.z = shape.halfExtents.z * 2;\r\n    }\r\n\r\n    public dispose() {}\r\n\r\n    private _extendNamespace() {\r\n        //this will force cannon to execute at least one step when using interpolation\r\n        const step_tmp1 = new this.BJSCANNON.Vec3();\r\n        const engine = this.BJSCANNON;\r\n        this.BJSCANNON.World.prototype.step = function (dt: number, timeSinceLastCalled: number, maxSubSteps: number) {\r\n            maxSubSteps = maxSubSteps || 10;\r\n            timeSinceLastCalled = timeSinceLastCalled || 0;\r\n            if (timeSinceLastCalled === 0) {\r\n                this.internalStep(dt);\r\n                this.time += dt;\r\n            } else {\r\n                let internalSteps = Math.floor((this.time + timeSinceLastCalled) / dt) - Math.floor(this.time / dt);\r\n                internalSteps = Math.min(internalSteps, maxSubSteps) || 1;\r\n                const t0 = performance.now();\r\n                for (let i = 0; i !== internalSteps; i++) {\r\n                    this.internalStep(dt);\r\n                    if (performance.now() - t0 > dt * 1000) {\r\n                        break;\r\n                    }\r\n                }\r\n                this.time += timeSinceLastCalled;\r\n                const h = this.time % dt;\r\n                const h_div_dt = h / dt;\r\n                const interpvelo = step_tmp1;\r\n                const bodies = this.bodies;\r\n                for (let j = 0; j !== bodies.length; j++) {\r\n                    const b = bodies[j];\r\n                    if (b.type !== engine.Body.STATIC && b.sleepState !== engine.Body.SLEEPING) {\r\n                        b.position.vsub(b.previousPosition, interpvelo);\r\n                        interpvelo.scale(h_div_dt, interpvelo);\r\n                        b.position.vadd(interpvelo, b.interpolatedPosition);\r\n                    } else {\r\n                        b.interpolatedPosition.set(b.position.x, b.position.y, b.position.z);\r\n                        b.interpolatedQuaternion.set(b.quaternion.x, b.quaternion.y, b.quaternion.z, b.quaternion.w);\r\n                    }\r\n                }\r\n            }\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @returns PhysicsRaycastResult\r\n     */\r\n    public raycast(from: Vector3, to: Vector3): PhysicsRaycastResult {\r\n        this._raycastResult.reset(from, to);\r\n        this.raycastToRef(from, to, this._raycastResult);\r\n        return this._raycastResult;\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param result resulting PhysicsRaycastResult\r\n     */\r\n    public raycastToRef(from: Vector3, to: Vector3, result: PhysicsRaycastResult): void {\r\n        this._cannonRaycastResult.reset();\r\n        this.world.raycastClosest(from, to, {}, this._cannonRaycastResult);\r\n\r\n        result.reset(from, to);\r\n        if (this._cannonRaycastResult.hasHit) {\r\n            // TODO: do we also want to get the body it hit?\r\n            result.setHitData(\r\n                {\r\n                    x: this._cannonRaycastResult.hitNormalWorld.x,\r\n                    y: this._cannonRaycastResult.hitNormalWorld.y,\r\n                    z: this._cannonRaycastResult.hitNormalWorld.z,\r\n                },\r\n                {\r\n                    x: this._cannonRaycastResult.hitPointWorld.x,\r\n                    y: this._cannonRaycastResult.hitPointWorld.y,\r\n                    z: this._cannonRaycastResult.hitPointWorld.z,\r\n                }\r\n            );\r\n            result.setHitDistance(this._cannonRaycastResult.distance);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cannonJSPlugin.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCannonJSPlugin(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    PhysicsEngine.DefaultPluginFactory = () => {\r\n        return new CannonJSPlugin();\r\n    };\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type IPhysicsEnabledObject, PhysicsImpostor } from \"../physicsImpostor.pure\";\r\nimport { type IMotorEnabledJoint, type DistanceJointData, type SpringJointData, PhysicsJoint } from \"../physicsJoint\";\r\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh\";\r\nimport { Vector3, Quaternion } from \"../../../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { PhysicsRaycastResult } from \"../../physicsRaycastResult\";\r\nimport { type IPhysicsEnginePlugin, type PhysicsImpostorJoint } from \"../IPhysicsEnginePlugin\";\r\nimport { Epsilon } from \"../../../Maths/math.constants\";\r\n\r\ndeclare let OIMO: any;\r\n\r\n/** @internal */\r\nexport class OimoJSPlugin implements IPhysicsEnginePlugin {\r\n    public world: any;\r\n    public name: string = \"OimoJSPlugin\";\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public BJSOIMO: any;\r\n    private _raycastResult: PhysicsRaycastResult;\r\n    private _fixedTimeStep: number = 1 / 60;\r\n\r\n    constructor(\r\n        private _useDeltaForWorldStep: boolean = true,\r\n        iterations?: number,\r\n        oimoInjection = OIMO\r\n    ) {\r\n        this.BJSOIMO = oimoInjection;\r\n        this.world = new this.BJSOIMO.World({\r\n            iterations: iterations,\r\n        });\r\n        this.world.clear();\r\n        this._raycastResult = new PhysicsRaycastResult();\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @returns plugin version\r\n     */\r\n    public getPluginVersion(): number {\r\n        return 1;\r\n    }\r\n\r\n    public setGravity(gravity: Vector3) {\r\n        this.world.gravity.set(gravity.x, gravity.y, gravity.z);\r\n    }\r\n\r\n    public setTimeStep(timeStep: number) {\r\n        this.world.timeStep = timeStep;\r\n    }\r\n\r\n    public getTimeStep(): number {\r\n        return this.world.timeStep;\r\n    }\r\n\r\n    private _tmpImpostorsArray: Array<PhysicsImpostor> = [];\r\n\r\n    public executeStep(delta: number, impostors: Array<PhysicsImpostor>) {\r\n        for (const impostor of impostors) {\r\n            impostor.beforeStep();\r\n        }\r\n\r\n        this.world.timeStep = this._useDeltaForWorldStep ? delta : this._fixedTimeStep;\r\n        this.world.step();\r\n\r\n        for (const impostor of impostors) {\r\n            impostor.afterStep();\r\n            //update the ordered impostors array\r\n            this._tmpImpostorsArray[impostor.uniqueId] = impostor;\r\n        }\r\n\r\n        //check for collisions\r\n        let contact = this.world.contacts;\r\n\r\n        while (contact !== null) {\r\n            if (contact.touching && !contact.body1.sleeping && !contact.body2.sleeping) {\r\n                contact = contact.next;\r\n                continue;\r\n            }\r\n            //is this body colliding with any other? get the impostor\r\n            const mainImpostor = this._tmpImpostorsArray[+contact.body1.name];\r\n            const collidingImpostor = this._tmpImpostorsArray[+contact.body2.name];\r\n\r\n            if (!mainImpostor || !collidingImpostor) {\r\n                contact = contact.next;\r\n                continue;\r\n            }\r\n\r\n            mainImpostor.onCollide({ body: collidingImpostor.physicsBody, point: null, distance: 0, impulse: 0, normal: null });\r\n            collidingImpostor.onCollide({ body: mainImpostor.physicsBody, point: null, distance: 0, impulse: 0, normal: null });\r\n            contact = contact.next;\r\n        }\r\n    }\r\n\r\n    public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {\r\n        const mass = impostor.physicsBody.mass;\r\n        impostor.physicsBody.applyImpulse(contactPoint.scale(this.world.invScale), force.scale(this.world.invScale * mass));\r\n    }\r\n    public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {\r\n        Logger.Warn(\"Oimo doesn't support applying force. Using impulse instead.\");\r\n        this.applyImpulse(impostor, force, contactPoint);\r\n    }\r\n    public generatePhysicsBody(impostor: PhysicsImpostor) {\r\n        //parent-child relationship. Does this impostor has a parent impostor?\r\n        if (impostor.parent) {\r\n            if (impostor.physicsBody) {\r\n                this.removePhysicsBody(impostor);\r\n                //TODO is that needed?\r\n                impostor.forceUpdate();\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (impostor.isBodyInitRequired()) {\r\n            const bodyConfig: any = {\r\n                name: impostor.uniqueId,\r\n                //Oimo must have mass, also for static objects.\r\n                config: [impostor.getParam(\"mass\") || 0.001, impostor.getParam(\"friction\"), impostor.getParam(\"restitution\")],\r\n                size: [],\r\n                type: [],\r\n                pos: [],\r\n                posShape: [],\r\n                rot: [],\r\n                rotShape: [],\r\n                move: impostor.getParam(\"mass\") !== 0,\r\n                density: impostor.getParam(\"mass\"),\r\n                friction: impostor.getParam(\"friction\"),\r\n                restitution: impostor.getParam(\"restitution\"),\r\n                //Supporting older versions of Oimo\r\n                world: this.world,\r\n            };\r\n\r\n            const impostors = [impostor];\r\n            const addToArray = (parent: IPhysicsEnabledObject) => {\r\n                if (!parent.getChildMeshes) {\r\n                    return;\r\n                }\r\n                const meshes = parent.getChildMeshes();\r\n                for (const m of meshes) {\r\n                    if (m.physicsImpostor) {\r\n                        impostors.push(m.physicsImpostor);\r\n                        //m.physicsImpostor._init();\r\n                    }\r\n                }\r\n            };\r\n            addToArray(impostor.object);\r\n\r\n            const checkWithEpsilon = (value: number): number => {\r\n                return Math.max(value, Epsilon);\r\n            };\r\n\r\n            const globalQuaternion: Quaternion = new Quaternion();\r\n\r\n            for (const i of impostors) {\r\n                if (!i.object.rotationQuaternion) {\r\n                    continue;\r\n                }\r\n                //get the correct bounding box\r\n                const oldQuaternion = i.object.rotationQuaternion;\r\n                globalQuaternion.copyFrom(oldQuaternion);\r\n\r\n                i.object.rotationQuaternion.set(0, 0, 0, 1);\r\n                i.object.computeWorldMatrix(true);\r\n\r\n                const rot = globalQuaternion.toEulerAngles();\r\n                const impostorExtents = i.getObjectExtents();\r\n\r\n                // eslint-disable-next-line no-loss-of-precision\r\n                const radToDeg = 57.295779513082320876;\r\n\r\n                if (i === impostor) {\r\n                    const center = impostor.getObjectCenter();\r\n\r\n                    impostor.object.getAbsolutePivotPoint().subtractToRef(center, this._tmpPositionVector);\r\n                    this._tmpPositionVector.divideInPlace(impostor.object.scaling);\r\n\r\n                    //Can also use Array.prototype.push.apply\r\n                    bodyConfig.pos.push(center.x);\r\n                    bodyConfig.pos.push(center.y);\r\n                    bodyConfig.pos.push(center.z);\r\n                    bodyConfig.posShape.push(0, 0, 0);\r\n\r\n                    bodyConfig.rotShape.push(0, 0, 0);\r\n                } else {\r\n                    const localPosition = i.object.position.clone();\r\n                    bodyConfig.posShape.push(localPosition.x);\r\n                    bodyConfig.posShape.push(localPosition.y);\r\n                    bodyConfig.posShape.push(localPosition.z);\r\n\r\n                    // bodyConfig.pos.push(0, 0, 0);\r\n\r\n                    bodyConfig.rotShape.push(rot.x * radToDeg, rot.y * radToDeg, rot.z * radToDeg);\r\n                }\r\n\r\n                i.object.rotationQuaternion.copyFrom(globalQuaternion);\r\n\r\n                // register mesh\r\n                switch (i.type) {\r\n                    case PhysicsImpostor.ParticleImpostor:\r\n                        Logger.Warn(\"No Particle support in OIMO.js. using SphereImpostor instead\");\r\n                    // eslint-disable-next-line no-fallthrough\r\n                    case PhysicsImpostor.SphereImpostor: {\r\n                        const radiusX = impostorExtents.x;\r\n                        const radiusY = impostorExtents.y;\r\n                        const radiusZ = impostorExtents.z;\r\n\r\n                        const size = Math.max(checkWithEpsilon(radiusX), checkWithEpsilon(radiusY), checkWithEpsilon(radiusZ)) / 2;\r\n\r\n                        bodyConfig.type.push(\"sphere\");\r\n                        //due to the way oimo works with compounds, add 3 times\r\n                        bodyConfig.size.push(size);\r\n                        bodyConfig.size.push(size);\r\n                        bodyConfig.size.push(size);\r\n                        break;\r\n                    }\r\n                    case PhysicsImpostor.CylinderImpostor: {\r\n                        const sizeX = checkWithEpsilon(impostorExtents.x) / 2;\r\n                        const sizeY = checkWithEpsilon(impostorExtents.y);\r\n                        bodyConfig.type.push(\"cylinder\");\r\n                        bodyConfig.size.push(sizeX);\r\n                        bodyConfig.size.push(sizeY);\r\n                        //due to the way oimo works with compounds, add one more value.\r\n                        bodyConfig.size.push(sizeY);\r\n                        break;\r\n                    }\r\n                    case PhysicsImpostor.PlaneImpostor:\r\n                    case PhysicsImpostor.BoxImpostor:\r\n                    default: {\r\n                        const sizeX = checkWithEpsilon(impostorExtents.x);\r\n                        const sizeY = checkWithEpsilon(impostorExtents.y);\r\n                        const sizeZ = checkWithEpsilon(impostorExtents.z);\r\n\r\n                        bodyConfig.type.push(\"box\");\r\n                        //if (i === impostor) {\r\n                        bodyConfig.size.push(sizeX);\r\n                        bodyConfig.size.push(sizeY);\r\n                        bodyConfig.size.push(sizeZ);\r\n                        //} else {\r\n                        //    bodyConfig.size.push(0,0,0);\r\n                        //}\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                //actually not needed, but hey...\r\n                i.object.rotationQuaternion = oldQuaternion;\r\n            }\r\n            impostor.physicsBody = this.world.add(bodyConfig);\r\n            // set the quaternion, ignoring the previously defined (euler) rotation\r\n            impostor.physicsBody.resetQuaternion(globalQuaternion);\r\n            // update with delta 0, so the body will receive the new rotation.\r\n            impostor.physicsBody.updatePosition(0);\r\n        } else {\r\n            this._tmpPositionVector.copyFromFloats(0, 0, 0);\r\n        }\r\n\r\n        impostor.setDeltaPosition(this._tmpPositionVector);\r\n\r\n        //this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);\r\n        //this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);\r\n    }\r\n\r\n    private _tmpPositionVector: Vector3 = Vector3.Zero();\r\n\r\n    public removePhysicsBody(impostor: PhysicsImpostor) {\r\n        //impostor.physicsBody.dispose();\r\n        this.world.removeRigidBody(impostor.physicsBody);\r\n    }\r\n\r\n    public generateJoint(impostorJoint: PhysicsImpostorJoint) {\r\n        const mainBody = impostorJoint.mainImpostor.physicsBody;\r\n        const connectedBody = impostorJoint.connectedImpostor.physicsBody;\r\n\r\n        if (!mainBody || !connectedBody) {\r\n            return;\r\n        }\r\n        const jointData = impostorJoint.joint.jointData;\r\n        const options = jointData.nativeParams || {};\r\n        let type;\r\n        const nativeJointData: any = {\r\n            body1: mainBody,\r\n            body2: connectedBody,\r\n\r\n            axe1: options.axe1 || (jointData.mainAxis ? jointData.mainAxis.asArray() : null),\r\n            axe2: options.axe2 || (jointData.connectedAxis ? jointData.connectedAxis.asArray() : null),\r\n            pos1: options.pos1 || (jointData.mainPivot ? jointData.mainPivot.asArray() : null),\r\n            pos2: options.pos2 || (jointData.connectedPivot ? jointData.connectedPivot.asArray() : null),\r\n\r\n            min: options.min,\r\n            max: options.max,\r\n            collision: options.collision || jointData.collision,\r\n            spring: options.spring,\r\n\r\n            //supporting older version of Oimo\r\n            world: this.world,\r\n        };\r\n        switch (impostorJoint.joint.type) {\r\n            case PhysicsJoint.BallAndSocketJoint:\r\n                type = \"jointBall\";\r\n                break;\r\n            case PhysicsJoint.SpringJoint: {\r\n                Logger.Warn(\"OIMO.js doesn't support Spring Constraint. Simulating using DistanceJoint instead\");\r\n                const springData = <SpringJointData>jointData;\r\n                nativeJointData.min = springData.length || nativeJointData.min;\r\n                //Max should also be set, just make sure it is at least min\r\n                nativeJointData.max = Math.max(nativeJointData.min, nativeJointData.max);\r\n            }\r\n            // eslint-disable-next-line no-fallthrough\r\n            case PhysicsJoint.DistanceJoint:\r\n                type = \"jointDistance\";\r\n                nativeJointData.max = (<DistanceJointData>jointData).maxDistance;\r\n                break;\r\n            case PhysicsJoint.PrismaticJoint:\r\n                type = \"jointPrisme\";\r\n                break;\r\n            case PhysicsJoint.SliderJoint:\r\n                type = \"jointSlide\";\r\n                break;\r\n            case PhysicsJoint.WheelJoint:\r\n                type = \"jointWheel\";\r\n                break;\r\n            case PhysicsJoint.HingeJoint:\r\n            default:\r\n                type = \"jointHinge\";\r\n                break;\r\n        }\r\n        nativeJointData.type = type;\r\n        impostorJoint.joint.physicsJoint = this.world.add(nativeJointData);\r\n    }\r\n\r\n    public removeJoint(impostorJoint: PhysicsImpostorJoint) {\r\n        //Bug in Oimo prevents us from disposing a joint in the playground\r\n        //joint.joint.physicsJoint.dispose();\r\n        //So we will bruteforce it!\r\n        try {\r\n            this.world.removeJoint(impostorJoint.joint.physicsJoint);\r\n        } catch (e) {\r\n            Logger.Warn(e);\r\n        }\r\n    }\r\n\r\n    public isSupported(): boolean {\r\n        return this.BJSOIMO !== undefined;\r\n    }\r\n\r\n    public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {\r\n        if (!impostor.physicsBody.sleeping) {\r\n            if (impostor.physicsBody.shapes.next) {\r\n                let parent = impostor.physicsBody.shapes;\r\n                while (parent.next) {\r\n                    parent = parent.next;\r\n                }\r\n                impostor.object.position.set(parent.position.x, parent.position.y, parent.position.z);\r\n            } else {\r\n                const pos = impostor.physicsBody.getPosition();\r\n                impostor.object.position.set(pos.x, pos.y, pos.z);\r\n            }\r\n\r\n            if (impostor.object.rotationQuaternion) {\r\n                const quat = impostor.physicsBody.getQuaternion();\r\n                impostor.object.rotationQuaternion.set(quat.x, quat.y, quat.z, quat.w);\r\n            }\r\n        }\r\n    }\r\n\r\n    public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {\r\n        const body = impostor.physicsBody;\r\n        // disable bidirectional for compound meshes\r\n        if (impostor.physicsBody.shapes.next) {\r\n            return;\r\n        }\r\n        body.position.set(newPosition.x, newPosition.y, newPosition.z);\r\n        body.orientation.set(newRotation.x, newRotation.y, newRotation.z, newRotation.w);\r\n        body.syncShapes();\r\n        body.awake();\r\n    }\r\n\r\n    /*private _getLastShape(body: any): any {\r\n        var lastShape = body.shapes;\r\n        while (lastShape.next) {\r\n            lastShape = lastShape.next;\r\n        }\r\n        return lastShape;\r\n    }*/\r\n\r\n    public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {\r\n        impostor.physicsBody.linearVelocity.set(velocity.x, velocity.y, velocity.z);\r\n    }\r\n\r\n    public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {\r\n        impostor.physicsBody.angularVelocity.set(velocity.x, velocity.y, velocity.z);\r\n    }\r\n\r\n    public getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {\r\n        const v = impostor.physicsBody.linearVelocity;\r\n        if (!v) {\r\n            return null;\r\n        }\r\n        return new Vector3(v.x, v.y, v.z);\r\n    }\r\n    public getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {\r\n        const v = impostor.physicsBody.angularVelocity;\r\n        if (!v) {\r\n            return null;\r\n        }\r\n        return new Vector3(v.x, v.y, v.z);\r\n    }\r\n\r\n    public setBodyMass(impostor: PhysicsImpostor, mass: number) {\r\n        const staticBody: boolean = mass === 0;\r\n        //this will actually set the body's density and not its mass.\r\n        //But this is how oimo treats the mass variable.\r\n        impostor.physicsBody.shapes.density = staticBody ? 1 : mass;\r\n        impostor.physicsBody.setupMass(staticBody ? 0x2 : 0x1);\r\n    }\r\n\r\n    public getBodyMass(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.shapes.density;\r\n    }\r\n\r\n    public getBodyFriction(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.shapes.friction;\r\n    }\r\n\r\n    public setBodyFriction(impostor: PhysicsImpostor, friction: number) {\r\n        impostor.physicsBody.shapes.friction = friction;\r\n    }\r\n\r\n    public getBodyRestitution(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.shapes.restitution;\r\n    }\r\n\r\n    public setBodyRestitution(impostor: PhysicsImpostor, restitution: number) {\r\n        impostor.physicsBody.shapes.restitution = restitution;\r\n    }\r\n\r\n    public sleepBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.sleep();\r\n    }\r\n\r\n    public wakeUpBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.awake();\r\n    }\r\n\r\n    public updateDistanceJoint(joint: PhysicsJoint, maxDistance: number, minDistance?: number) {\r\n        joint.physicsJoint.limitMotor.upperLimit = maxDistance;\r\n        if (minDistance !== void 0) {\r\n            joint.physicsJoint.limitMotor.lowerLimit = minDistance;\r\n        }\r\n    }\r\n\r\n    public setMotor(joint: IMotorEnabledJoint, speed: number, force?: number, motorIndex?: number) {\r\n        if (force !== undefined) {\r\n            Logger.Warn(\"OimoJS plugin currently has unexpected behavior when using setMotor with force parameter\");\r\n        } else {\r\n            force = 1e6;\r\n        }\r\n        speed *= -1;\r\n\r\n        //TODO separate rotational and transational motors.\r\n        const motor = motorIndex\r\n            ? joint.physicsJoint.rotationalLimitMotor2\r\n            : joint.physicsJoint.rotationalLimitMotor1 || joint.physicsJoint.rotationalLimitMotor || joint.physicsJoint.limitMotor;\r\n        if (motor) {\r\n            motor.setMotor(speed, force);\r\n        }\r\n    }\r\n\r\n    public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number, motorIndex?: number) {\r\n        //TODO separate rotational and transational motors.\r\n        const motor = motorIndex\r\n            ? joint.physicsJoint.rotationalLimitMotor2\r\n            : joint.physicsJoint.rotationalLimitMotor1 || joint.physicsJoint.rotationalLimitMotor || joint.physicsJoint.limitMotor;\r\n        if (motor) {\r\n            motor.setLimit(upperLimit, lowerLimit === void 0 ? -upperLimit : lowerLimit);\r\n        }\r\n    }\r\n\r\n    public syncMeshWithImpostor(mesh: AbstractMesh, impostor: PhysicsImpostor) {\r\n        const body = impostor.physicsBody;\r\n\r\n        mesh.position.x = body.position.x;\r\n        mesh.position.y = body.position.y;\r\n        mesh.position.z = body.position.z;\r\n\r\n        if (mesh.rotationQuaternion) {\r\n            mesh.rotationQuaternion.x = body.orientation.x;\r\n            mesh.rotationQuaternion.y = body.orientation.y;\r\n            mesh.rotationQuaternion.z = body.orientation.z;\r\n            mesh.rotationQuaternion.w = body.orientation.w;\r\n        }\r\n    }\r\n\r\n    public getRadius(impostor: PhysicsImpostor): number {\r\n        return impostor.physicsBody.shapes.radius;\r\n    }\r\n\r\n    public getBoxSizeToRef(impostor: PhysicsImpostor, result: Vector3): void {\r\n        const shape = impostor.physicsBody.shapes;\r\n        result.x = shape.halfWidth * 2;\r\n        result.y = shape.halfHeight * 2;\r\n        result.z = shape.halfDepth * 2;\r\n    }\r\n\r\n    public dispose() {\r\n        this.world.clear();\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @returns PhysicsRaycastResult\r\n     */\r\n    public raycast(from: Vector3, to: Vector3): PhysicsRaycastResult {\r\n        Logger.Warn(\"raycast is not currently supported by the Oimo physics plugin\");\r\n\r\n        this._raycastResult.reset(from, to);\r\n\r\n        return this._raycastResult;\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param result resulting PhysicsRaycastResult\r\n     */\r\n    public raycastToRef(from: Vector3, to: Vector3, result: PhysicsRaycastResult): void {\r\n        Logger.Warn(\"raycast is not currently supported by the Oimo physics plugin\");\r\n\r\n        result.reset(from, to);\r\n    }\r\n}\r\n","import { Quaternion, Vector3, Matrix } from \"../../../Maths/math.vector.pure\";\r\nimport { type IPhysicsEnginePlugin, type PhysicsImpostorJoint } from \"../IPhysicsEnginePlugin\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { type IPhysicsEnabledObject, PhysicsImpostor } from \"../physicsImpostor.pure\";\r\nimport { type IMotorEnabledJoint, type DistanceJointData, PhysicsJoint } from \"../physicsJoint\";\r\nimport { VertexBuffer } from \"../../../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../../../Meshes/mesh.vertexData\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../../../Meshes/mesh\";\r\nimport { ExtrudeShape } from \"../../../Meshes/Builders/shapeBuilder.pure\";\r\nimport { CreateLines } from \"../../../Meshes/Builders/linesBuilder.pure\";\r\nimport { type LinesMesh } from \"../../../Meshes/linesMesh\";\r\nimport { PhysicsRaycastResult } from \"../../physicsRaycastResult\";\r\nimport { WithinEpsilon } from \"../../../Maths/math.scalar.functions\";\r\nimport { Epsilon } from \"../../../Maths/math.constants\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare let Ammo: any;\r\n\r\n/**\r\n * AmmoJS Physics plugin\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n * @see https://github.com/kripken/ammo.js/\r\n */\r\nexport class AmmoJSPlugin implements IPhysicsEnginePlugin {\r\n    /**\r\n     * Reference to the Ammo library\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public bjsAMMO: any = {};\r\n    /**\r\n     * Created ammoJS world which physics bodies are added to\r\n     */\r\n    public world: any;\r\n    /**\r\n     * Name of the plugin\r\n     */\r\n    public name: string = \"AmmoJSPlugin\";\r\n\r\n    private _timeStep: number = 1 / 60;\r\n    private _fixedTimeStep: number = 1 / 60;\r\n    private _maxSteps = 5;\r\n    private _tmpQuaternion = new Quaternion();\r\n    private _tmpAmmoTransform: any;\r\n    private _tmpAmmoQuaternion: any;\r\n    private _tmpAmmoConcreteContactResultCallback: any;\r\n    private _collisionConfiguration: any;\r\n    private _dispatcher: any;\r\n    private _overlappingPairCache: any;\r\n    private _solver: any;\r\n    private _softBodySolver: any;\r\n    private _tmpAmmoVectorA: any;\r\n    private _tmpAmmoVectorB: any;\r\n    private _tmpAmmoVectorC: any;\r\n    private _tmpAmmoVectorD: any;\r\n    private _tmpContactCallbackResult = false;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _tmpAmmoVectorRCA: any;\r\n    private _tmpAmmoVectorRCB: any;\r\n    private _raycastResult: PhysicsRaycastResult;\r\n    private _tmpContactPoint = new Vector3();\r\n    private _tmpContactNormal = new Vector3();\r\n    private _tmpContactDistance: number;\r\n    private _tmpContactImpulse: number;\r\n    private _tmpVec3 = new Vector3();\r\n\r\n    private static readonly _DISABLE_COLLISION_FLAG = 4;\r\n    private static readonly _KINEMATIC_FLAG = 2;\r\n    private static readonly _DISABLE_DEACTIVATION_FLAG = 4;\r\n\r\n    /**\r\n     * Initializes the ammoJS plugin\r\n     * @param _useDeltaForWorldStep if the time between frames should be used when calculating physics steps (Default: true)\r\n     * @param ammoInjection can be used to inject your own ammo reference\r\n     * @param overlappingPairCache can be used to specify your own overlapping pair cache\r\n     */\r\n    public constructor(\r\n        private _useDeltaForWorldStep: boolean = true,\r\n        ammoInjection: any = Ammo,\r\n        overlappingPairCache: any = null\r\n    ) {\r\n        if (typeof ammoInjection === \"function\") {\r\n            Logger.Error(\"AmmoJS is not ready. Please make sure you await Ammo() before using the plugin.\");\r\n            return;\r\n        } else {\r\n            this.bjsAMMO = ammoInjection;\r\n        }\r\n\r\n        if (!this.isSupported()) {\r\n            Logger.Error(\"AmmoJS is not available. Please make sure you included the js file.\");\r\n            return;\r\n        }\r\n\r\n        // Initialize the physics world\r\n        this._collisionConfiguration = new this.bjsAMMO.btSoftBodyRigidBodyCollisionConfiguration();\r\n        this._dispatcher = new this.bjsAMMO.btCollisionDispatcher(this._collisionConfiguration);\r\n        this._overlappingPairCache = overlappingPairCache || new this.bjsAMMO.btDbvtBroadphase();\r\n        this._solver = new this.bjsAMMO.btSequentialImpulseConstraintSolver();\r\n        this._softBodySolver = new this.bjsAMMO.btDefaultSoftBodySolver();\r\n        this.world = new this.bjsAMMO.btSoftRigidDynamicsWorld(this._dispatcher, this._overlappingPairCache, this._solver, this._collisionConfiguration, this._softBodySolver);\r\n\r\n        this._tmpAmmoConcreteContactResultCallback = new this.bjsAMMO.ConcreteContactResultCallback();\r\n        this._tmpAmmoConcreteContactResultCallback.addSingleResult = (contactPoint: any) => {\r\n            contactPoint = this.bjsAMMO.wrapPointer(contactPoint, this.bjsAMMO.btManifoldPoint);\r\n            const worldPoint = contactPoint.getPositionWorldOnA();\r\n            const worldNormal = contactPoint.m_normalWorldOnB;\r\n            this._tmpContactPoint.x = worldPoint.x();\r\n            this._tmpContactPoint.y = worldPoint.y();\r\n            this._tmpContactPoint.z = worldPoint.z();\r\n            this._tmpContactNormal.x = worldNormal.x();\r\n            this._tmpContactNormal.y = worldNormal.y();\r\n            this._tmpContactNormal.z = worldNormal.z();\r\n            this._tmpContactImpulse = contactPoint.getAppliedImpulse();\r\n            this._tmpContactDistance = contactPoint.getDistance();\r\n            this._tmpContactCallbackResult = true;\r\n        };\r\n\r\n        this._raycastResult = new PhysicsRaycastResult();\r\n\r\n        // Create temp ammo variables\r\n        this._tmpAmmoTransform = new this.bjsAMMO.btTransform();\r\n        this._tmpAmmoTransform.setIdentity();\r\n        this._tmpAmmoQuaternion = new this.bjsAMMO.btQuaternion(0, 0, 0, 1);\r\n        this._tmpAmmoVectorA = new this.bjsAMMO.btVector3(0, 0, 0);\r\n        this._tmpAmmoVectorB = new this.bjsAMMO.btVector3(0, 0, 0);\r\n        this._tmpAmmoVectorC = new this.bjsAMMO.btVector3(0, 0, 0);\r\n        this._tmpAmmoVectorD = new this.bjsAMMO.btVector3(0, 0, 0);\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @returns plugin version\r\n     */\r\n    public getPluginVersion(): number {\r\n        return 1;\r\n    }\r\n\r\n    /**\r\n     * Sets the gravity of the physics world (m/(s^2))\r\n     * @param gravity Gravity to set\r\n     */\r\n    public setGravity(gravity: Vector3): void {\r\n        this._tmpAmmoVectorA.setValue(gravity.x, gravity.y, gravity.z);\r\n        this.world.setGravity(this._tmpAmmoVectorA);\r\n        this.world.getWorldInfo().set_m_gravity(this._tmpAmmoVectorA);\r\n    }\r\n\r\n    /**\r\n     * Amount of time to step forward on each frame (only used if useDeltaForWorldStep is false in the constructor)\r\n     * @param timeStep timestep to use in seconds\r\n     */\r\n    public setTimeStep(timeStep: number) {\r\n        this._timeStep = timeStep;\r\n    }\r\n\r\n    /**\r\n     * Increment to step forward in the physics engine (If timeStep is set to 1/60 and fixedTimeStep is set to 1/120 the physics engine should run 2 steps per frame) (Default: 1/60)\r\n     * @param fixedTimeStep fixedTimeStep to use in seconds\r\n     */\r\n    public setFixedTimeStep(fixedTimeStep: number) {\r\n        this._fixedTimeStep = fixedTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum number of steps by the physics engine per frame (Default: 5)\r\n     * @param maxSteps the maximum number of steps by the physics engine per frame\r\n     */\r\n    public setMaxSteps(maxSteps: number) {\r\n        this._maxSteps = maxSteps;\r\n    }\r\n\r\n    /**\r\n     * Gets the current timestep (only used if useDeltaForWorldStep is false in the constructor)\r\n     * @returns the current timestep in seconds\r\n     */\r\n    public getTimeStep(): number {\r\n        return this._timeStep;\r\n    }\r\n\r\n    /**\r\n     * The create custom shape handler function to be called when using BABYLON.PhysicsImposter.CustomImpostor\r\n     */\r\n    public onCreateCustomShape: (impostor: PhysicsImpostor) => any;\r\n\r\n    /**\r\n     * The create custom mesh impostor handler function to support building custom mesh impostor vertex data\r\n     */\r\n    public onCreateCustomMeshImpostor: (impostor: PhysicsImpostor) => any;\r\n\r\n    /**\r\n     * The create custom convex hull impostor handler function to support building custom convex hull impostor vertex data\r\n     */\r\n    public onCreateCustomConvexHullImpostor: (impostor: PhysicsImpostor) => any;\r\n\r\n    // Ammo's contactTest and contactPairTest take a callback that runs synchronously, wrap them so that they are easier to consume\r\n    private _isImpostorInContact(impostor: PhysicsImpostor) {\r\n        this._tmpContactCallbackResult = false;\r\n        this.world.contactTest(impostor.physicsBody, this._tmpAmmoConcreteContactResultCallback);\r\n        return this._tmpContactCallbackResult;\r\n    }\r\n    // Ammo's collision events have some weird quirks\r\n    // contactPairTest fires too many events as it fires events even when objects are close together but contactTest does not\r\n    // so only fire event if both contactTest and contactPairTest have a hit\r\n    private _isImpostorPairInContact(impostorA: PhysicsImpostor, impostorB: PhysicsImpostor) {\r\n        this._tmpContactCallbackResult = false;\r\n        this.world.contactPairTest(impostorA.physicsBody, impostorB.physicsBody, this._tmpAmmoConcreteContactResultCallback);\r\n        return this._tmpContactCallbackResult;\r\n    }\r\n\r\n    // Ammo's behavior when maxSteps > 0 does not behave as described in docs\r\n    // @see http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World\r\n    //\r\n    // When maxSteps is 0 do the entire simulation in one step\r\n    // When maxSteps is > 0, run up to maxStep times, if on the last step the (remaining step - fixedTimeStep) is < fixedTimeStep, the remainder will be used for the step. (eg. if remainder is 1.001 and fixedTimeStep is 1 the last step will be 1.001, if instead it did 2 steps (1, 0.001) issues occuered when having a tiny step in ammo)\r\n    // Note: To get deterministic physics, timeStep would always need to be divisible by fixedTimeStep\r\n    private _stepSimulation(timeStep: number = 1 / 60, maxSteps: number = 10, fixedTimeStep: number = 1 / 60) {\r\n        if (maxSteps == 0) {\r\n            this.world.stepSimulation(timeStep, 0);\r\n        } else {\r\n            while (maxSteps > 0 && timeStep > 0) {\r\n                if (timeStep - fixedTimeStep < fixedTimeStep) {\r\n                    this.world.stepSimulation(timeStep, 0);\r\n                    timeStep = 0;\r\n                } else {\r\n                    timeStep -= fixedTimeStep;\r\n                    this.world.stepSimulation(fixedTimeStep, 0);\r\n                }\r\n                maxSteps--;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Moves the physics simulation forward delta seconds and updates the given physics imposters\r\n     * Prior to the step the imposters physics location is set to the position of the babylon meshes\r\n     * After the step the babylon meshes are set to the position of the physics imposters\r\n     * @param delta amount of time to step forward\r\n     * @param impostors array of imposters to update before/after the step\r\n     */\r\n    public executeStep(delta: number, impostors: Array<PhysicsImpostor>): void {\r\n        for (const impostor of impostors) {\r\n            // Update physics world objects to match babylon world\r\n            if (!impostor.soft) {\r\n                impostor.beforeStep();\r\n            }\r\n        }\r\n\r\n        this._stepSimulation(this._useDeltaForWorldStep ? delta : this._timeStep, this._maxSteps, this._fixedTimeStep);\r\n\r\n        for (const mainImpostor of impostors) {\r\n            // After physics update make babylon world objects match physics world objects\r\n            if (mainImpostor.soft) {\r\n                this._afterSoftStep(mainImpostor);\r\n            } else {\r\n                mainImpostor.afterStep();\r\n            }\r\n\r\n            // Handle collision event\r\n            if (mainImpostor._onPhysicsCollideCallbacks.length > 0) {\r\n                if (this._isImpostorInContact(mainImpostor)) {\r\n                    for (const collideCallback of mainImpostor._onPhysicsCollideCallbacks) {\r\n                        for (const otherImpostor of collideCallback.otherImpostors) {\r\n                            if (mainImpostor.physicsBody.isActive() || otherImpostor.physicsBody.isActive()) {\r\n                                if (this._isImpostorPairInContact(mainImpostor, otherImpostor)) {\r\n                                    mainImpostor.onCollide({\r\n                                        body: otherImpostor.physicsBody,\r\n                                        point: this._tmpContactPoint,\r\n                                        distance: this._tmpContactDistance,\r\n                                        impulse: this._tmpContactImpulse,\r\n                                        normal: this._tmpContactNormal,\r\n                                    });\r\n                                    otherImpostor.onCollide({\r\n                                        body: mainImpostor.physicsBody,\r\n                                        point: this._tmpContactPoint,\r\n                                        distance: this._tmpContactDistance,\r\n                                        impulse: this._tmpContactImpulse,\r\n                                        normal: this._tmpContactNormal,\r\n                                    });\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update babylon mesh to match physics world object\r\n     * @param impostor imposter to match\r\n     */\r\n    private _afterSoftStep(impostor: PhysicsImpostor): void {\r\n        if (impostor.type === PhysicsImpostor.RopeImpostor) {\r\n            this._ropeStep(impostor);\r\n        } else {\r\n            this._softbodyOrClothStep(impostor);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update babylon mesh vertices vertices to match physics world softbody or cloth\r\n     * @param impostor imposter to match\r\n     */\r\n    private _ropeStep(impostor: PhysicsImpostor): void {\r\n        const bodyVertices = impostor.physicsBody.get_m_nodes();\r\n        const nbVertices = bodyVertices.size();\r\n        let node: any;\r\n        let nodePositions: any;\r\n        let x, y, z: number;\r\n        const path: Array<Vector3> = [];\r\n        for (let n = 0; n < nbVertices; n++) {\r\n            node = bodyVertices.at(n);\r\n            nodePositions = node.get_m_x();\r\n            x = nodePositions.x();\r\n            y = nodePositions.y();\r\n            z = nodePositions.z();\r\n            path.push(new Vector3(x, y, z));\r\n        }\r\n        const object = impostor.object;\r\n        const shape = impostor.getParam(\"shape\");\r\n        if (impostor._isFromLine) {\r\n            impostor.object = CreateLines(\"lines\", { points: path, instance: <LinesMesh>object });\r\n        } else {\r\n            impostor.object = ExtrudeShape(\"ext\", { shape: shape, path: path, instance: <Mesh>object });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update babylon mesh vertices vertices to match physics world softbody or cloth\r\n     * @param impostor imposter to match\r\n     */\r\n    private _softbodyOrClothStep(impostor: PhysicsImpostor): void {\r\n        const normalDirection = impostor.type === PhysicsImpostor.ClothImpostor ? 1 : -1;\r\n        const object = impostor.object;\r\n        let vertexPositions = object.getVerticesData(VertexBuffer.PositionKind);\r\n        if (!vertexPositions) {\r\n            vertexPositions = [];\r\n        }\r\n        let vertexNormals = object.getVerticesData(VertexBuffer.NormalKind);\r\n        if (!vertexNormals) {\r\n            vertexNormals = [];\r\n        }\r\n\r\n        const nbVertices = vertexPositions.length / 3;\r\n        const bodyVertices = impostor.physicsBody.get_m_nodes();\r\n        let node: any;\r\n        let nodePositions: any;\r\n        let x, y, z: number;\r\n        let nx, ny, nz: number;\r\n        for (let n = 0; n < nbVertices; n++) {\r\n            node = bodyVertices.at(n);\r\n            nodePositions = node.get_m_x();\r\n            x = nodePositions.x();\r\n            y = nodePositions.y();\r\n            z = nodePositions.z() * normalDirection;\r\n            const nodeNormals = node.get_m_n();\r\n            nx = nodeNormals.x();\r\n            ny = nodeNormals.y();\r\n            nz = nodeNormals.z() * normalDirection;\r\n\r\n            vertexPositions[3 * n] = x;\r\n            vertexPositions[3 * n + 1] = y;\r\n            vertexPositions[3 * n + 2] = z;\r\n            vertexNormals[3 * n] = nx;\r\n            vertexNormals[3 * n + 1] = ny;\r\n            vertexNormals[3 * n + 2] = nz;\r\n        }\r\n\r\n        const vertexData = new VertexData();\r\n\r\n        vertexData.positions = vertexPositions;\r\n        vertexData.normals = vertexNormals;\r\n        vertexData.uvs = object.getVerticesData(VertexBuffer.UVKind);\r\n        vertexData.colors = object.getVerticesData(VertexBuffer.ColorKind);\r\n        if (object && object.getIndices) {\r\n            vertexData.indices = object.getIndices();\r\n        }\r\n\r\n        vertexData.applyToMesh(<Mesh>object);\r\n    }\r\n\r\n    private _tmpMatrix = new Matrix();\r\n    /**\r\n     * Applies an impulse on the imposter\r\n     * @param impostor imposter to apply impulse to\r\n     * @param force amount of force to be applied to the imposter\r\n     * @param contactPoint the location to apply the impulse on the imposter\r\n     */\r\n    public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {\r\n        if (!impostor.soft) {\r\n            impostor.physicsBody.activate();\r\n            const worldPoint = this._tmpAmmoVectorA;\r\n            const impulse = this._tmpAmmoVectorB;\r\n\r\n            // Convert contactPoint relative to center of mass\r\n            if (impostor.object && impostor.object.getWorldMatrix) {\r\n                contactPoint.subtractInPlace(impostor.object.getWorldMatrix().getTranslation());\r\n            }\r\n\r\n            worldPoint.setValue(contactPoint.x, contactPoint.y, contactPoint.z);\r\n            impulse.setValue(force.x, force.y, force.z);\r\n\r\n            impostor.physicsBody.applyImpulse(impulse, worldPoint);\r\n        } else {\r\n            Logger.Warn(\"Cannot be applied to a soft body\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Applies a force on the imposter\r\n     * @param impostor imposter to apply force\r\n     * @param force amount of force to be applied to the imposter\r\n     * @param contactPoint the location to apply the force on the imposter\r\n     */\r\n    public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {\r\n        if (!impostor.soft) {\r\n            impostor.physicsBody.activate();\r\n            const worldPoint = this._tmpAmmoVectorA;\r\n            const impulse = this._tmpAmmoVectorB;\r\n\r\n            // Convert contactPoint relative to center of mass\r\n            if (impostor.object && impostor.object.getWorldMatrix) {\r\n                const localTranslation = impostor.object.getWorldMatrix().getTranslation();\r\n                worldPoint.setValue(contactPoint.x - localTranslation.x, contactPoint.y - localTranslation.y, contactPoint.z - localTranslation.z);\r\n            } else {\r\n                worldPoint.setValue(contactPoint.x, contactPoint.y, contactPoint.z);\r\n            }\r\n\r\n            impulse.setValue(force.x, force.y, force.z);\r\n\r\n            impostor.physicsBody.applyForce(impulse, worldPoint);\r\n        } else {\r\n            Logger.Warn(\"Cannot be applied to a soft body\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a physics body using the plugin\r\n     * @param impostor the imposter to create the physics body on\r\n     */\r\n    public generatePhysicsBody(impostor: PhysicsImpostor) {\r\n        // Note: this method will not be called on child imposotrs for compound impostors\r\n\r\n        impostor._pluginData.toDispose = [];\r\n\r\n        //parent-child relationship\r\n        if (impostor.parent) {\r\n            if (impostor.physicsBody) {\r\n                this.removePhysicsBody(impostor);\r\n                impostor.forceUpdate();\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (impostor.isBodyInitRequired()) {\r\n            const colShape = this._createShape(impostor);\r\n            const mass = impostor.getParam(\"mass\");\r\n            impostor._pluginData.mass = mass;\r\n            if (impostor.soft) {\r\n                colShape.get_m_cfg().set_collisions(0x11);\r\n                colShape.get_m_cfg().set_kDP(impostor.getParam(\"damping\"));\r\n                this.bjsAMMO.castObject(colShape, this.bjsAMMO.btCollisionObject).getCollisionShape().setMargin(impostor.getParam(\"margin\"));\r\n                colShape.setActivationState(AmmoJSPlugin._DISABLE_DEACTIVATION_FLAG);\r\n                this.world.addSoftBody(colShape, 1, -1);\r\n                impostor.physicsBody = colShape;\r\n                impostor._pluginData.toDispose.push(colShape);\r\n                this.setBodyPressure(impostor, 0);\r\n                if (impostor.type === PhysicsImpostor.SoftbodyImpostor) {\r\n                    this.setBodyPressure(impostor, impostor.getParam(\"pressure\"));\r\n                }\r\n                this.setBodyStiffness(impostor, impostor.getParam(\"stiffness\"));\r\n                this.setBodyVelocityIterations(impostor, impostor.getParam(\"velocityIterations\"));\r\n                this.setBodyPositionIterations(impostor, impostor.getParam(\"positionIterations\"));\r\n            } else {\r\n                const localInertia = new this.bjsAMMO.btVector3(0, 0, 0);\r\n                const startTransform = new this.bjsAMMO.btTransform();\r\n                impostor.object.computeWorldMatrix(true);\r\n                startTransform.setIdentity();\r\n                if (mass !== 0) {\r\n                    colShape.calculateLocalInertia(mass, localInertia);\r\n                }\r\n                this._tmpAmmoVectorA.setValue(impostor.object.position.x, impostor.object.position.y, impostor.object.position.z);\r\n                this._tmpAmmoQuaternion.setValue(\r\n                    impostor.object.rotationQuaternion!.x,\r\n                    impostor.object.rotationQuaternion!.y,\r\n                    impostor.object.rotationQuaternion!.z,\r\n                    impostor.object.rotationQuaternion!.w\r\n                );\r\n                startTransform.setOrigin(this._tmpAmmoVectorA);\r\n                startTransform.setRotation(this._tmpAmmoQuaternion);\r\n                const myMotionState = new this.bjsAMMO.btDefaultMotionState(startTransform);\r\n                const rbInfo = new this.bjsAMMO.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);\r\n                const body = new this.bjsAMMO.btRigidBody(rbInfo);\r\n\r\n                // Make objects kinematic if it's mass is 0\r\n                if (mass === 0) {\r\n                    body.setCollisionFlags(body.getCollisionFlags() | AmmoJSPlugin._KINEMATIC_FLAG);\r\n                    body.setActivationState(AmmoJSPlugin._DISABLE_DEACTIVATION_FLAG);\r\n                }\r\n\r\n                // Disable collision if NoImpostor, but keep collision if shape is btCompoundShape\r\n                if (impostor.type == PhysicsImpostor.NoImpostor && !colShape.getChildShape) {\r\n                    body.setCollisionFlags(body.getCollisionFlags() | AmmoJSPlugin._DISABLE_COLLISION_FLAG);\r\n                }\r\n\r\n                // compute delta position: compensate the difference between shape center and mesh origin\r\n                if (impostor.type !== PhysicsImpostor.MeshImpostor && impostor.type !== PhysicsImpostor.NoImpostor) {\r\n                    const boundingInfo = impostor.object.getBoundingInfo();\r\n                    this._tmpVec3.copyFrom(impostor.object.getAbsolutePosition());\r\n                    this._tmpVec3.subtractInPlace(boundingInfo.boundingBox.centerWorld);\r\n                    this._tmpVec3.x /= impostor.object.scaling.x;\r\n                    this._tmpVec3.y /= impostor.object.scaling.y;\r\n                    this._tmpVec3.z /= impostor.object.scaling.z;\r\n                    impostor.setDeltaPosition(this._tmpVec3);\r\n                }\r\n\r\n                const group = impostor.getParam(\"group\");\r\n                const mask = impostor.getParam(\"mask\");\r\n                if (group && mask) {\r\n                    this.world.addRigidBody(body, group, mask);\r\n                } else {\r\n                    this.world.addRigidBody(body);\r\n                }\r\n                impostor.physicsBody = body;\r\n                impostor._pluginData.toDispose = impostor._pluginData.toDispose.concat([body, rbInfo, myMotionState, startTransform, localInertia, colShape]);\r\n            }\r\n            this.setBodyRestitution(impostor, impostor.getParam(\"restitution\"));\r\n            this.setBodyFriction(impostor, impostor.getParam(\"friction\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes the physics body from the imposter and disposes of the body's memory\r\n     * @param impostor imposter to remove the physics body from\r\n     */\r\n    public removePhysicsBody(impostor: PhysicsImpostor) {\r\n        if (this.world) {\r\n            if (impostor.soft) {\r\n                this.world.removeSoftBody(impostor.physicsBody);\r\n            } else {\r\n                this.world.removeRigidBody(impostor.physicsBody);\r\n            }\r\n\r\n            if (impostor._pluginData) {\r\n                for (const d of impostor._pluginData.toDispose) {\r\n                    this.bjsAMMO.destroy(d);\r\n                }\r\n                impostor._pluginData.toDispose = [];\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Generates a joint\r\n     * @param impostorJoint the imposter joint to create the joint with\r\n     */\r\n    public generateJoint(impostorJoint: PhysicsImpostorJoint) {\r\n        const mainBody = impostorJoint.mainImpostor.physicsBody;\r\n        const connectedBody = impostorJoint.connectedImpostor.physicsBody;\r\n        if (!mainBody || !connectedBody) {\r\n            return;\r\n        }\r\n\r\n        // if the joint is already created, don't create it again for preventing memory leaks\r\n        if (impostorJoint.joint.physicsJoint) {\r\n            return;\r\n        }\r\n\r\n        const jointData = impostorJoint.joint.jointData;\r\n        if (!jointData.mainPivot) {\r\n            jointData.mainPivot = new Vector3(0, 0, 0);\r\n        }\r\n        if (!jointData.connectedPivot) {\r\n            jointData.connectedPivot = new Vector3(0, 0, 0);\r\n        }\r\n\r\n        let joint: any;\r\n        switch (impostorJoint.joint.type) {\r\n            case PhysicsJoint.DistanceJoint: {\r\n                const distance = (<DistanceJointData>jointData).maxDistance;\r\n                if (distance) {\r\n                    jointData.mainPivot = new Vector3(0, -distance / 2, 0);\r\n                    jointData.connectedPivot = new Vector3(0, distance / 2, 0);\r\n                }\r\n\r\n                const mainPivot = this._tmpAmmoVectorA;\r\n                mainPivot.setValue(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z);\r\n\r\n                const connectedPivot = this._tmpAmmoVectorB;\r\n                connectedPivot.setValue(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z);\r\n\r\n                joint = new this.bjsAMMO.btPoint2PointConstraint(mainBody, connectedBody, mainPivot, connectedPivot);\r\n                break;\r\n            }\r\n            case PhysicsJoint.HingeJoint: {\r\n                if (!jointData.mainAxis) {\r\n                    jointData.mainAxis = new Vector3(0, 0, 0);\r\n                }\r\n                if (!jointData.connectedAxis) {\r\n                    jointData.connectedAxis = new Vector3(0, 0, 0);\r\n                }\r\n\r\n                const mainPivot = this._tmpAmmoVectorA;\r\n                mainPivot.setValue(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z);\r\n\r\n                const connectedPivot = this._tmpAmmoVectorB;\r\n                connectedPivot.setValue(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z);\r\n\r\n                const mainAxis = this._tmpAmmoVectorC;\r\n                mainAxis.setValue(jointData.mainAxis.x, jointData.mainAxis.y, jointData.mainAxis.z);\r\n\r\n                const connectedAxis = this._tmpAmmoVectorD;\r\n                connectedAxis.setValue(jointData.connectedAxis.x, jointData.connectedAxis.y, jointData.connectedAxis.z);\r\n\r\n                joint = new this.bjsAMMO.btHingeConstraint(mainBody, connectedBody, mainPivot, connectedPivot, mainAxis, connectedAxis);\r\n                break;\r\n            }\r\n            case PhysicsJoint.BallAndSocketJoint: {\r\n                const mainPivot = this._tmpAmmoVectorA;\r\n                mainPivot.setValue(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z);\r\n\r\n                const connectedPivot = this._tmpAmmoVectorB;\r\n                connectedPivot.setValue(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z);\r\n\r\n                joint = new this.bjsAMMO.btPoint2PointConstraint(mainBody, connectedBody, mainPivot, connectedPivot);\r\n                break;\r\n            }\r\n            default: {\r\n                Logger.Warn(\"JointType not currently supported by the Ammo plugin, falling back to PhysicsJoint.BallAndSocketJoint\");\r\n\r\n                const mainPivot = this._tmpAmmoVectorA;\r\n                mainPivot.setValue(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z);\r\n\r\n                const connectedPivot = this._tmpAmmoVectorB;\r\n                connectedPivot.setValue(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z);\r\n\r\n                joint = new this.bjsAMMO.btPoint2PointConstraint(mainBody, connectedBody, mainPivot, connectedPivot);\r\n                break;\r\n            }\r\n        }\r\n        this.world.addConstraint(joint, !impostorJoint.joint.jointData.collision);\r\n        impostorJoint.joint.physicsJoint = joint;\r\n    }\r\n\r\n    /**\r\n     * Removes a joint\r\n     * @param impostorJoint the imposter joint to remove the joint from\r\n     */\r\n    public removeJoint(impostorJoint: PhysicsImpostorJoint) {\r\n        if (this.world) {\r\n            this.world.removeConstraint(impostorJoint.joint.physicsJoint);\r\n        }\r\n        this.bjsAMMO.destroy(impostorJoint.joint.physicsJoint);\r\n    }\r\n\r\n    // adds all verticies (including child verticies) to the triangle mesh\r\n    private _addMeshVerts(btTriangleMesh: any, topLevelObject: IPhysicsEnabledObject, object: IPhysicsEnabledObject) {\r\n        let triangleCount = 0;\r\n        if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {\r\n            let indices = object.getIndices();\r\n            if (!indices) {\r\n                indices = [];\r\n            }\r\n            let vertexPositions = object.getVerticesData(VertexBuffer.PositionKind);\r\n            if (!vertexPositions) {\r\n                vertexPositions = [];\r\n            }\r\n\r\n            let localMatrix;\r\n\r\n            if (topLevelObject && topLevelObject !== object) {\r\n                // top level matrix used for shape transform doesn't take scale into account.\r\n                // Moreover, every children vertex position must be in that space.\r\n                // So, each vertex position here is transform by (mesh world matrix * toplevelMatrix -1)\r\n                let topLevelQuaternion;\r\n                if (topLevelObject.rotationQuaternion) {\r\n                    topLevelQuaternion = topLevelObject.rotationQuaternion;\r\n                } else if (topLevelObject.rotation) {\r\n                    topLevelQuaternion = Quaternion.FromEulerAngles(topLevelObject.rotation.x, topLevelObject.rotation.y, topLevelObject.rotation.z);\r\n                } else {\r\n                    topLevelQuaternion = Quaternion.Identity();\r\n                }\r\n                const topLevelMatrix = Matrix.Compose(Vector3.One(), topLevelQuaternion, topLevelObject.position);\r\n                topLevelMatrix.invertToRef(this._tmpMatrix);\r\n                const wm = object.computeWorldMatrix(false);\r\n                localMatrix = wm.multiply(this._tmpMatrix);\r\n            } else {\r\n                // current top level is same as object level -> only use local scaling\r\n                Matrix.ScalingToRef(object.scaling.x, object.scaling.y, object.scaling.z, this._tmpMatrix);\r\n                localMatrix = this._tmpMatrix;\r\n            }\r\n            const faceCount = indices.length / 3;\r\n            for (let i = 0; i < faceCount; i++) {\r\n                const triPoints = [];\r\n                for (let point = 0; point < 3; point++) {\r\n                    let v = new Vector3(\r\n                        vertexPositions[indices[i * 3 + point] * 3 + 0],\r\n                        vertexPositions[indices[i * 3 + point] * 3 + 1],\r\n                        vertexPositions[indices[i * 3 + point] * 3 + 2]\r\n                    );\r\n\r\n                    v = Vector3.TransformCoordinates(v, localMatrix);\r\n\r\n                    let vec: any;\r\n                    if (point == 0) {\r\n                        vec = this._tmpAmmoVectorA;\r\n                    } else if (point == 1) {\r\n                        vec = this._tmpAmmoVectorB;\r\n                    } else {\r\n                        vec = this._tmpAmmoVectorC;\r\n                    }\r\n                    vec.setValue(v.x, v.y, v.z);\r\n\r\n                    triPoints.push(vec);\r\n                }\r\n                btTriangleMesh.addTriangle(triPoints[0], triPoints[1], triPoints[2]);\r\n                triangleCount++;\r\n            }\r\n\r\n            const childMeshes = object.getChildMeshes();\r\n            for (const m of childMeshes) {\r\n                triangleCount += this._addMeshVerts(btTriangleMesh, topLevelObject, m);\r\n            }\r\n        }\r\n        return triangleCount;\r\n    }\r\n\r\n    /**\r\n     * Initialise the soft body vertices to match its object's (mesh) vertices\r\n     * Softbody vertices (nodes) are in world space and to match this\r\n     * The object's position and rotation is set to zero and so its vertices are also then set in world space\r\n     * @param impostor to create the softbody for\r\n     * @returns the number of vertices added to the softbody\r\n     */\r\n    private _softVertexData(impostor: PhysicsImpostor): VertexData {\r\n        const object = impostor.object;\r\n        if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {\r\n            let vertexPositions = object.getVerticesData(VertexBuffer.PositionKind);\r\n            if (!vertexPositions) {\r\n                vertexPositions = [];\r\n            }\r\n            let vertexNormals = object.getVerticesData(VertexBuffer.NormalKind);\r\n            if (!vertexNormals) {\r\n                vertexNormals = [];\r\n            }\r\n            object.computeWorldMatrix(false);\r\n            const newPoints = [];\r\n            const newNorms = [];\r\n            for (let i = 0; i < vertexPositions.length; i += 3) {\r\n                let v = new Vector3(vertexPositions[i], vertexPositions[i + 1], vertexPositions[i + 2]);\r\n                let n = new Vector3(vertexNormals[i], vertexNormals[i + 1], vertexNormals[i + 2]);\r\n                v = Vector3.TransformCoordinates(v, object.getWorldMatrix());\r\n                n = Vector3.TransformNormal(n, object.getWorldMatrix());\r\n                newPoints.push(v.x, v.y, v.z);\r\n                newNorms.push(n.x, n.y, n.z);\r\n            }\r\n\r\n            const vertexData = new VertexData();\r\n\r\n            vertexData.positions = newPoints;\r\n            vertexData.normals = newNorms;\r\n            vertexData.uvs = object.getVerticesData(VertexBuffer.UVKind);\r\n            vertexData.colors = object.getVerticesData(VertexBuffer.ColorKind);\r\n            if (object && object.getIndices) {\r\n                vertexData.indices = object.getIndices();\r\n            }\r\n\r\n            vertexData.applyToMesh(<Mesh>object);\r\n\r\n            object.position = Vector3.Zero();\r\n            object.rotationQuaternion = null;\r\n            object.rotation = Vector3.Zero();\r\n            object.computeWorldMatrix(true);\r\n\r\n            return vertexData;\r\n        }\r\n        return VertexData.ExtractFromMesh(<Mesh>object);\r\n    }\r\n\r\n    /**\r\n     * Create an impostor's soft body\r\n     * @param impostor to create the softbody for\r\n     * @returns the softbody\r\n     */\r\n    private _createSoftbody(impostor: PhysicsImpostor) {\r\n        const object = impostor.object;\r\n        if (object && object.getIndices) {\r\n            let indices = object.getIndices();\r\n            if (!indices) {\r\n                indices = [];\r\n            }\r\n\r\n            const vertexData = this._softVertexData(impostor);\r\n            const vertexPositions = vertexData.positions;\r\n            const vertexNormals = vertexData.normals;\r\n\r\n            if (vertexPositions === null || vertexNormals === null) {\r\n                return new this.bjsAMMO.btCompoundShape();\r\n            } else {\r\n                const triPoints = [];\r\n                const triNorms = [];\r\n                for (let i = 0; i < vertexPositions.length; i += 3) {\r\n                    const v = new Vector3(vertexPositions[i], vertexPositions[i + 1], vertexPositions[i + 2]);\r\n                    const n = new Vector3(vertexNormals[i], vertexNormals[i + 1], vertexNormals[i + 2]);\r\n                    triPoints.push(v.x, v.y, -v.z);\r\n                    triNorms.push(n.x, n.y, -n.z);\r\n                }\r\n                const softBody = new this.bjsAMMO.btSoftBodyHelpers().CreateFromTriMesh(this.world.getWorldInfo(), triPoints, object.getIndices(), indices.length / 3, true);\r\n\r\n                const nbVertices = vertexPositions.length / 3;\r\n                const bodyVertices = softBody.get_m_nodes();\r\n                let node: any;\r\n                let nodeNormals: any;\r\n                for (let i = 0; i < nbVertices; i++) {\r\n                    node = bodyVertices.at(i);\r\n                    nodeNormals = node.get_m_n();\r\n                    nodeNormals.setX(triNorms[3 * i]);\r\n                    nodeNormals.setY(triNorms[3 * i + 1]);\r\n                    nodeNormals.setZ(triNorms[3 * i + 2]);\r\n                }\r\n                return softBody;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create cloth for an impostor\r\n     * @param impostor to create the softbody for\r\n     * @returns the cloth\r\n     */\r\n    private _createCloth(impostor: PhysicsImpostor) {\r\n        const object = impostor.object;\r\n        if (object && object.getIndices) {\r\n            const vertexData = this._softVertexData(impostor);\r\n            const vertexPositions = vertexData.positions;\r\n            const vertexNormals = vertexData.normals;\r\n\r\n            if (vertexPositions === null || vertexNormals === null) {\r\n                return new this.bjsAMMO.btCompoundShape();\r\n            } else {\r\n                const len = vertexPositions.length;\r\n                const segments = Math.sqrt(len / 3);\r\n                impostor.segments = segments;\r\n                const segs = segments - 1;\r\n                this._tmpAmmoVectorA.setValue(vertexPositions[0], vertexPositions[1], vertexPositions[2]);\r\n                this._tmpAmmoVectorB.setValue(vertexPositions[3 * segs], vertexPositions[3 * segs + 1], vertexPositions[3 * segs + 2]);\r\n                this._tmpAmmoVectorD.setValue(vertexPositions[len - 3], vertexPositions[len - 2], vertexPositions[len - 1]);\r\n                this._tmpAmmoVectorC.setValue(vertexPositions[len - 3 - 3 * segs], vertexPositions[len - 2 - 3 * segs], vertexPositions[len - 1 - 3 * segs]);\r\n\r\n                const clothBody = new this.bjsAMMO.btSoftBodyHelpers().CreatePatch(\r\n                    this.world.getWorldInfo(),\r\n                    this._tmpAmmoVectorA,\r\n                    this._tmpAmmoVectorB,\r\n                    this._tmpAmmoVectorC,\r\n                    this._tmpAmmoVectorD,\r\n                    segments,\r\n                    segments,\r\n                    impostor.getParam(\"fixedPoints\"),\r\n                    true\r\n                );\r\n                return clothBody;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create rope for an impostor\r\n     * @param impostor to create the softbody for\r\n     * @returns the rope\r\n     */\r\n    private _createRope(impostor: PhysicsImpostor) {\r\n        let len: number;\r\n        let segments: number;\r\n        const vertexData = this._softVertexData(impostor);\r\n        const vertexPositions = vertexData.positions;\r\n        const vertexNormals = vertexData.normals;\r\n\r\n        if (vertexPositions === null || vertexNormals === null) {\r\n            return new this.bjsAMMO.btCompoundShape();\r\n        }\r\n\r\n        //force the mesh to be updatable\r\n        vertexData.applyToMesh(<Mesh>impostor.object, true);\r\n\r\n        impostor._isFromLine = true;\r\n\r\n        // If in lines mesh all normals will be zero\r\n        const vertexSquared: Array<number> = <Array<number>>vertexNormals.map((x: number) => x * x);\r\n        const reducer = (accumulator: number, currentValue: number): number => accumulator + currentValue;\r\n        const reduced: number = vertexSquared.reduce(reducer);\r\n\r\n        if (reduced === 0) {\r\n            // line mesh\r\n            len = vertexPositions.length;\r\n            segments = len / 3 - 1;\r\n            this._tmpAmmoVectorA.setValue(vertexPositions[0], vertexPositions[1], vertexPositions[2]);\r\n            this._tmpAmmoVectorB.setValue(vertexPositions[len - 3], vertexPositions[len - 2], vertexPositions[len - 1]);\r\n        } else {\r\n            //extruded mesh\r\n            impostor._isFromLine = false;\r\n            const pathVectors = impostor.getParam(\"path\");\r\n            const shape = impostor.getParam(\"shape\");\r\n            if (shape === null) {\r\n                Logger.Warn(\"No shape available for extruded mesh\");\r\n                return new this.bjsAMMO.btCompoundShape();\r\n            }\r\n            len = pathVectors.length;\r\n            segments = len - 1;\r\n            this._tmpAmmoVectorA.setValue(pathVectors[0].x, pathVectors[0].y, pathVectors[0].z);\r\n            this._tmpAmmoVectorB.setValue(pathVectors[len - 1].x, pathVectors[len - 1].y, pathVectors[len - 1].z);\r\n        }\r\n\r\n        impostor.segments = segments;\r\n\r\n        let fixedPoints = impostor.getParam(\"fixedPoints\");\r\n        fixedPoints = fixedPoints > 3 ? 3 : fixedPoints;\r\n\r\n        const ropeBody = new this.bjsAMMO.btSoftBodyHelpers().CreateRope(this.world.getWorldInfo(), this._tmpAmmoVectorA, this._tmpAmmoVectorB, segments - 1, fixedPoints);\r\n        ropeBody.get_m_cfg().set_collisions(0x11);\r\n        return ropeBody;\r\n    }\r\n\r\n    /**\r\n     * Create a custom physics impostor shape using the plugin's onCreateCustomShape handler\r\n     * @param impostor to create the custom physics shape for\r\n     * @returns the custom physics shape\r\n     */\r\n    private _createCustom(impostor: PhysicsImpostor): any {\r\n        let returnValue: any = null;\r\n        if (this.onCreateCustomShape) {\r\n            returnValue = this.onCreateCustomShape(impostor);\r\n        }\r\n        if (returnValue == null) {\r\n            returnValue = new this.bjsAMMO.btCompoundShape();\r\n        }\r\n        return returnValue;\r\n    }\r\n\r\n    // adds all verticies (including child verticies) to the convex hull shape\r\n    private _addHullVerts(btConvexHullShape: any, topLevelObject: IPhysicsEnabledObject, object: IPhysicsEnabledObject) {\r\n        let triangleCount = 0;\r\n        if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {\r\n            let indices = object.getIndices();\r\n            if (!indices) {\r\n                indices = [];\r\n            }\r\n            let vertexPositions = object.getVerticesData(VertexBuffer.PositionKind);\r\n            if (!vertexPositions) {\r\n                vertexPositions = [];\r\n            }\r\n            object.computeWorldMatrix(false);\r\n            const faceCount = indices.length / 3;\r\n            for (let i = 0; i < faceCount; i++) {\r\n                const triPoints = [];\r\n                for (let point = 0; point < 3; point++) {\r\n                    let v = new Vector3(\r\n                        vertexPositions[indices[i * 3 + point] * 3 + 0],\r\n                        vertexPositions[indices[i * 3 + point] * 3 + 1],\r\n                        vertexPositions[indices[i * 3 + point] * 3 + 2]\r\n                    );\r\n\r\n                    // Adjust for initial scaling\r\n                    Matrix.ScalingToRef(object.scaling.x, object.scaling.y, object.scaling.z, this._tmpMatrix);\r\n                    v = Vector3.TransformCoordinates(v, this._tmpMatrix);\r\n\r\n                    let vec: any;\r\n                    if (point == 0) {\r\n                        vec = this._tmpAmmoVectorA;\r\n                    } else if (point == 1) {\r\n                        vec = this._tmpAmmoVectorB;\r\n                    } else {\r\n                        vec = this._tmpAmmoVectorC;\r\n                    }\r\n                    vec.setValue(v.x, v.y, v.z);\r\n\r\n                    triPoints.push(vec);\r\n                }\r\n                btConvexHullShape.addPoint(triPoints[0], true);\r\n                btConvexHullShape.addPoint(triPoints[1], true);\r\n                btConvexHullShape.addPoint(triPoints[2], true);\r\n                triangleCount++;\r\n            }\r\n\r\n            const childMeshes = object.getChildMeshes();\r\n            for (const m of childMeshes) {\r\n                triangleCount += this._addHullVerts(btConvexHullShape, topLevelObject, m);\r\n            }\r\n        }\r\n        return triangleCount;\r\n    }\r\n\r\n    private _createShape(impostor: PhysicsImpostor, ignoreChildren = false) {\r\n        const object = impostor.object;\r\n\r\n        let returnValue: any;\r\n        const impostorExtents = impostor.getObjectExtents();\r\n\r\n        if (!ignoreChildren) {\r\n            const meshChildren = impostor.object.getChildMeshes ? impostor.object.getChildMeshes(true) : [];\r\n            returnValue = new this.bjsAMMO.btCompoundShape();\r\n\r\n            // Add shape of all children to the compound shape\r\n            let childrenAdded = 0;\r\n            for (const childMesh of meshChildren) {\r\n                const childImpostor = childMesh.getPhysicsImpostor();\r\n                if (childImpostor) {\r\n                    if (childImpostor.type == PhysicsImpostor.MeshImpostor) {\r\n                        // eslint-disable-next-line no-throw-literal\r\n                        throw \"A child MeshImpostor is not supported. Only primitive impostors are supported as children (eg. box or sphere)\";\r\n                    }\r\n                    const shape = this._createShape(childImpostor);\r\n\r\n                    // Position needs to be scaled based on parent's scaling\r\n                    const parentMat = childMesh.parent!.getWorldMatrix().clone();\r\n                    const s = new Vector3();\r\n                    parentMat.decompose(s);\r\n                    this._tmpAmmoTransform.getOrigin().setValue(childMesh.position.x * s.x, childMesh.position.y * s.y, childMesh.position.z * s.z);\r\n\r\n                    this._tmpAmmoQuaternion.setValue(\r\n                        childMesh.rotationQuaternion!.x,\r\n                        childMesh.rotationQuaternion!.y,\r\n                        childMesh.rotationQuaternion!.z,\r\n                        childMesh.rotationQuaternion!.w\r\n                    );\r\n                    this._tmpAmmoTransform.setRotation(this._tmpAmmoQuaternion);\r\n                    returnValue.addChildShape(this._tmpAmmoTransform, shape);\r\n                    childImpostor.dispose();\r\n                    childrenAdded++;\r\n                }\r\n            }\r\n\r\n            if (childrenAdded > 0) {\r\n                // Add parents shape as a child if present\r\n                if (impostor.type != PhysicsImpostor.NoImpostor) {\r\n                    const shape = this._createShape(impostor, true);\r\n                    if (shape) {\r\n                        this._tmpAmmoTransform.getOrigin().setValue(0, 0, 0);\r\n                        this._tmpAmmoQuaternion.setValue(0, 0, 0, 1);\r\n                        this._tmpAmmoTransform.setRotation(this._tmpAmmoQuaternion);\r\n\r\n                        returnValue.addChildShape(this._tmpAmmoTransform, shape);\r\n                    }\r\n                }\r\n                return returnValue;\r\n            } else {\r\n                // If no children with impostors create the actual shape below instead\r\n                this.bjsAMMO.destroy(returnValue);\r\n                returnValue = null;\r\n            }\r\n        }\r\n\r\n        switch (impostor.type) {\r\n            case PhysicsImpostor.SphereImpostor:\r\n                // Is there a better way to compare floats number? With an epsilon or with a Math function\r\n                if (WithinEpsilon(impostorExtents.x, impostorExtents.y, 0.0001) && WithinEpsilon(impostorExtents.x, impostorExtents.z, 0.0001)) {\r\n                    returnValue = new this.bjsAMMO.btSphereShape(impostorExtents.x / 2);\r\n                } else {\r\n                    // create a btMultiSphereShape because it's not possible to set a local scaling on a btSphereShape\r\n                    this._tmpAmmoVectorA.setValue(0, 0, 0);\r\n                    const positions = [this._tmpAmmoVectorA];\r\n                    const radii = [1];\r\n                    returnValue = new this.bjsAMMO.btMultiSphereShape(positions, radii, 1);\r\n\r\n                    this._tmpAmmoVectorA.setValue(impostorExtents.x / 2, impostorExtents.y / 2, impostorExtents.z / 2);\r\n                    returnValue.setLocalScaling(this._tmpAmmoVectorA);\r\n                }\r\n                break;\r\n            case PhysicsImpostor.CapsuleImpostor:\r\n                {\r\n                    // https://pybullet.org/Bullet/BulletFull/classbtCapsuleShape.html#details\r\n                    // Height is just the height between the center of each 'sphere' of the capsule caps\r\n                    const capRadius = impostorExtents.x / 2;\r\n                    returnValue = new this.bjsAMMO.btCapsuleShape(capRadius, impostorExtents.y - capRadius * 2);\r\n                }\r\n                break;\r\n            case PhysicsImpostor.CylinderImpostor:\r\n                this._tmpAmmoVectorA.setValue(impostorExtents.x / 2, impostorExtents.y / 2, impostorExtents.z / 2);\r\n                returnValue = new this.bjsAMMO.btCylinderShape(this._tmpAmmoVectorA);\r\n                break;\r\n            case PhysicsImpostor.PlaneImpostor:\r\n            case PhysicsImpostor.BoxImpostor:\r\n                this._tmpAmmoVectorA.setValue(impostorExtents.x / 2, impostorExtents.y / 2, impostorExtents.z / 2);\r\n                returnValue = new this.bjsAMMO.btBoxShape(this._tmpAmmoVectorA);\r\n                break;\r\n            case PhysicsImpostor.MeshImpostor: {\r\n                if (impostor.getParam(\"mass\") == 0) {\r\n                    // Only create btBvhTriangleMeshShape if the impostor is static\r\n                    // See https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=7283\r\n                    if (this.onCreateCustomMeshImpostor) {\r\n                        returnValue = this.onCreateCustomMeshImpostor(impostor);\r\n                    } else {\r\n                        const triMesh = new this.bjsAMMO.btTriangleMesh();\r\n                        impostor._pluginData.toDispose.push(triMesh);\r\n                        const triangleCount = this._addMeshVerts(triMesh, object, object);\r\n                        if (triangleCount == 0) {\r\n                            returnValue = new this.bjsAMMO.btCompoundShape();\r\n                        } else {\r\n                            returnValue = new this.bjsAMMO.btBvhTriangleMeshShape(triMesh);\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n            // Otherwise create convexHullImpostor\r\n            // eslint-disable-next-line no-fallthrough\r\n            case PhysicsImpostor.ConvexHullImpostor: {\r\n                if (this.onCreateCustomConvexHullImpostor) {\r\n                    returnValue = this.onCreateCustomConvexHullImpostor(impostor);\r\n                } else {\r\n                    const convexHull = new this.bjsAMMO.btConvexHullShape();\r\n                    const triangleCount = this._addHullVerts(convexHull, object, object);\r\n                    if (triangleCount == 0) {\r\n                        // Cleanup Unused Convex Hull Shape\r\n                        impostor._pluginData.toDispose.push(convexHull);\r\n                        returnValue = new this.bjsAMMO.btCompoundShape();\r\n                    } else {\r\n                        returnValue = convexHull;\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n            case PhysicsImpostor.NoImpostor:\r\n                // Fill with sphere but collision is disabled on the rigid body in generatePhysicsBody, using an empty shape caused unexpected movement with joints\r\n                returnValue = new this.bjsAMMO.btSphereShape(impostorExtents.x / 2);\r\n                break;\r\n            case PhysicsImpostor.CustomImpostor:\r\n                // Only usable when the plugin's onCreateCustomShape is set\r\n                returnValue = this._createCustom(impostor);\r\n                break;\r\n            case PhysicsImpostor.SoftbodyImpostor:\r\n                // Only usable with a mesh that has sufficient and shared vertices\r\n                returnValue = this._createSoftbody(impostor);\r\n                break;\r\n            case PhysicsImpostor.ClothImpostor:\r\n                // Only usable with a ground mesh that has sufficient and shared vertices\r\n                returnValue = this._createCloth(impostor);\r\n                break;\r\n            case PhysicsImpostor.RopeImpostor:\r\n                // Only usable with a line mesh or an extruded mesh that is updatable\r\n                returnValue = this._createRope(impostor);\r\n                break;\r\n            default:\r\n                Logger.Warn(\"The impostor type is not currently supported by the ammo plugin.\");\r\n                break;\r\n        }\r\n\r\n        return returnValue;\r\n    }\r\n\r\n    /**\r\n     * Sets the mesh body position/rotation from the babylon impostor\r\n     * @param impostor imposter containing the physics body and babylon object\r\n     */\r\n    public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.getMotionState().getWorldTransform(this._tmpAmmoTransform);\r\n        impostor.object.position.set(this._tmpAmmoTransform.getOrigin().x(), this._tmpAmmoTransform.getOrigin().y(), this._tmpAmmoTransform.getOrigin().z());\r\n\r\n        if (!impostor.object.rotationQuaternion) {\r\n            if (impostor.object.rotation) {\r\n                this._tmpQuaternion.set(\r\n                    this._tmpAmmoTransform.getRotation().x(),\r\n                    this._tmpAmmoTransform.getRotation().y(),\r\n                    this._tmpAmmoTransform.getRotation().z(),\r\n                    this._tmpAmmoTransform.getRotation().w()\r\n                );\r\n                this._tmpQuaternion.toEulerAnglesToRef(impostor.object.rotation);\r\n            }\r\n        } else {\r\n            impostor.object.rotationQuaternion.set(\r\n                this._tmpAmmoTransform.getRotation().x(),\r\n                this._tmpAmmoTransform.getRotation().y(),\r\n                this._tmpAmmoTransform.getRotation().z(),\r\n                this._tmpAmmoTransform.getRotation().w()\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the babylon object's position/rotation from the physics body's position/rotation\r\n     * @param impostor imposter containing the physics body and babylon object\r\n     * @param newPosition new position\r\n     * @param newRotation new rotation\r\n     */\r\n    public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {\r\n        const trans = impostor.physicsBody.getWorldTransform();\r\n\r\n        // If rotation/position has changed update and activate rigged body\r\n        if (\r\n            Math.abs(trans.getOrigin().x() - newPosition.x) > Epsilon ||\r\n            Math.abs(trans.getOrigin().y() - newPosition.y) > Epsilon ||\r\n            Math.abs(trans.getOrigin().z() - newPosition.z) > Epsilon ||\r\n            Math.abs(trans.getRotation().x() - newRotation.x) > Epsilon ||\r\n            Math.abs(trans.getRotation().y() - newRotation.y) > Epsilon ||\r\n            Math.abs(trans.getRotation().z() - newRotation.z) > Epsilon ||\r\n            Math.abs(trans.getRotation().w() - newRotation.w) > Epsilon\r\n        ) {\r\n            this._tmpAmmoVectorA.setValue(newPosition.x, newPosition.y, newPosition.z);\r\n            trans.setOrigin(this._tmpAmmoVectorA);\r\n\r\n            this._tmpAmmoQuaternion.setValue(newRotation.x, newRotation.y, newRotation.z, newRotation.w);\r\n            trans.setRotation(this._tmpAmmoQuaternion);\r\n            impostor.physicsBody.setWorldTransform(trans);\r\n\r\n            if (impostor.mass == 0) {\r\n                // Kinematic objects must be updated using motion state\r\n                const motionState = impostor.physicsBody.getMotionState();\r\n                if (motionState) {\r\n                    motionState.setWorldTransform(trans);\r\n                }\r\n            } else {\r\n                impostor.physicsBody.activate();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * If this plugin is supported\r\n     * @returns true if its supported\r\n     */\r\n    public isSupported(): boolean {\r\n        return this.bjsAMMO !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Sets the linear velocity of the physics body\r\n     * @param impostor imposter to set the velocity on\r\n     * @param velocity velocity to set\r\n     */\r\n    public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {\r\n        this._tmpAmmoVectorA.setValue(velocity.x, velocity.y, velocity.z);\r\n        if (impostor.soft) {\r\n            impostor.physicsBody.linearVelocity(this._tmpAmmoVectorA);\r\n        } else {\r\n            impostor.physicsBody.setLinearVelocity(this._tmpAmmoVectorA);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the angular velocity of the physics body\r\n     * @param impostor imposter to set the velocity on\r\n     * @param velocity velocity to set\r\n     */\r\n    public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {\r\n        this._tmpAmmoVectorA.setValue(velocity.x, velocity.y, velocity.z);\r\n        if (impostor.soft) {\r\n            impostor.physicsBody.angularVelocity(this._tmpAmmoVectorA);\r\n        } else {\r\n            impostor.physicsBody.setAngularVelocity(this._tmpAmmoVectorA);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * gets the linear velocity\r\n     * @param impostor imposter to get linear velocity from\r\n     * @returns linear velocity\r\n     */\r\n    public getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {\r\n        let v: any;\r\n        if (impostor.soft) {\r\n            v = impostor.physicsBody.linearVelocity();\r\n        } else {\r\n            v = impostor.physicsBody.getLinearVelocity();\r\n        }\r\n        if (!v) {\r\n            return null;\r\n        }\r\n        const result = new Vector3(v.x(), v.y(), v.z());\r\n        this.bjsAMMO.destroy(v);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * gets the angular velocity\r\n     * @param impostor imposter to get angular velocity from\r\n     * @returns angular velocity\r\n     */\r\n    public getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {\r\n        let v: any;\r\n        if (impostor.soft) {\r\n            v = impostor.physicsBody.angularVelocity();\r\n        } else {\r\n            v = impostor.physicsBody.getAngularVelocity();\r\n        }\r\n        if (!v) {\r\n            return null;\r\n        }\r\n        const result = new Vector3(v.x(), v.y(), v.z());\r\n        this.bjsAMMO.destroy(v);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Sets the mass of physics body\r\n     * @param impostor imposter to set the mass on\r\n     * @param mass mass to set\r\n     */\r\n    public setBodyMass(impostor: PhysicsImpostor, mass: number) {\r\n        if (impostor.soft) {\r\n            impostor.physicsBody.setTotalMass(mass, false);\r\n        } else {\r\n            impostor.physicsBody.setMassProps(mass);\r\n        }\r\n        impostor._pluginData.mass = mass;\r\n    }\r\n\r\n    /**\r\n     * Gets the mass of the physics body\r\n     * @param impostor imposter to get the mass from\r\n     * @returns mass\r\n     */\r\n    public getBodyMass(impostor: PhysicsImpostor): number {\r\n        return impostor._pluginData.mass || 0;\r\n    }\r\n\r\n    /**\r\n     * Gets friction of the impostor\r\n     * @param impostor impostor to get friction from\r\n     * @returns friction value\r\n     */\r\n    public getBodyFriction(impostor: PhysicsImpostor): number {\r\n        return impostor._pluginData.friction || 0;\r\n    }\r\n\r\n    /**\r\n     * Sets friction of the impostor\r\n     * @param impostor impostor to set friction on\r\n     * @param friction friction value\r\n     */\r\n    public setBodyFriction(impostor: PhysicsImpostor, friction: number) {\r\n        if (impostor.soft) {\r\n            impostor.physicsBody.get_m_cfg().set_kDF(friction);\r\n        } else {\r\n            impostor.physicsBody.setFriction(friction);\r\n        }\r\n        impostor._pluginData.friction = friction;\r\n    }\r\n\r\n    /**\r\n     * Gets restitution of the impostor\r\n     * @param impostor impostor to get restitution from\r\n     * @returns restitution value\r\n     */\r\n    public getBodyRestitution(impostor: PhysicsImpostor): number {\r\n        return impostor._pluginData.restitution || 0;\r\n    }\r\n\r\n    /**\r\n     * Sets restitution of the impostor\r\n     * @param impostor impostor to set resitution on\r\n     * @param restitution resitution value\r\n     */\r\n    public setBodyRestitution(impostor: PhysicsImpostor, restitution: number) {\r\n        impostor.physicsBody.setRestitution(restitution);\r\n        impostor._pluginData.restitution = restitution;\r\n    }\r\n\r\n    /**\r\n     * Gets pressure inside the impostor\r\n     * @param impostor impostor to get pressure from\r\n     * @returns pressure value\r\n     */\r\n    public getBodyPressure(impostor: PhysicsImpostor): number {\r\n        if (!impostor.soft) {\r\n            Logger.Warn(\"Pressure is not a property of a rigid body\");\r\n            return 0;\r\n        }\r\n        return impostor._pluginData.pressure || 0;\r\n    }\r\n\r\n    /**\r\n     * Sets pressure inside a soft body impostor\r\n     * Cloth and rope must remain 0 pressure\r\n     * @param impostor impostor to set pressure on\r\n     * @param pressure pressure value\r\n     */\r\n    public setBodyPressure(impostor: PhysicsImpostor, pressure: number) {\r\n        if (impostor.soft) {\r\n            if (impostor.type === PhysicsImpostor.SoftbodyImpostor) {\r\n                impostor.physicsBody.get_m_cfg().set_kPR(pressure);\r\n                impostor._pluginData.pressure = pressure;\r\n            } else {\r\n                impostor.physicsBody.get_m_cfg().set_kPR(0);\r\n                impostor._pluginData.pressure = 0;\r\n            }\r\n        } else {\r\n            Logger.Warn(\"Pressure can only be applied to a softbody\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets stiffness of the impostor\r\n     * @param impostor impostor to get stiffness from\r\n     * @returns pressure value\r\n     */\r\n    public getBodyStiffness(impostor: PhysicsImpostor): number {\r\n        if (!impostor.soft) {\r\n            Logger.Warn(\"Stiffness is not a property of a rigid body\");\r\n            return 0;\r\n        }\r\n        return impostor._pluginData.stiffness || 0;\r\n    }\r\n\r\n    /**\r\n     * Sets stiffness of the impostor\r\n     * @param impostor impostor to set stiffness on\r\n     * @param stiffness stiffness value from 0 to 1\r\n     */\r\n    public setBodyStiffness(impostor: PhysicsImpostor, stiffness: number) {\r\n        if (impostor.soft) {\r\n            stiffness = stiffness < 0 ? 0 : stiffness;\r\n            stiffness = stiffness > 1 ? 1 : stiffness;\r\n            impostor.physicsBody.get_m_materials().at(0).set_m_kLST(stiffness);\r\n            impostor._pluginData.stiffness = stiffness;\r\n        } else {\r\n            Logger.Warn(\"Stiffness cannot be applied to a rigid body\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets velocityIterations of the impostor\r\n     * @param impostor impostor to get velocity iterations from\r\n     * @returns velocityIterations value\r\n     */\r\n    public getBodyVelocityIterations(impostor: PhysicsImpostor): number {\r\n        if (!impostor.soft) {\r\n            Logger.Warn(\"Velocity iterations is not a property of a rigid body\");\r\n            return 0;\r\n        }\r\n        return impostor._pluginData.velocityIterations || 0;\r\n    }\r\n\r\n    /**\r\n     * Sets velocityIterations of the impostor\r\n     * @param impostor impostor to set velocity iterations on\r\n     * @param velocityIterations velocityIterations value\r\n     */\r\n    public setBodyVelocityIterations(impostor: PhysicsImpostor, velocityIterations: number) {\r\n        if (impostor.soft) {\r\n            velocityIterations = velocityIterations < 0 ? 0 : velocityIterations;\r\n            impostor.physicsBody.get_m_cfg().set_viterations(velocityIterations);\r\n            impostor._pluginData.velocityIterations = velocityIterations;\r\n        } else {\r\n            Logger.Warn(\"Velocity iterations cannot be applied to a rigid body\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets positionIterations of the impostor\r\n     * @param impostor impostor to get position iterations from\r\n     * @returns positionIterations value\r\n     */\r\n    public getBodyPositionIterations(impostor: PhysicsImpostor): number {\r\n        if (!impostor.soft) {\r\n            Logger.Warn(\"Position iterations is not a property of a rigid body\");\r\n            return 0;\r\n        }\r\n        return impostor._pluginData.positionIterations || 0;\r\n    }\r\n\r\n    /**\r\n     * Sets positionIterations of the impostor\r\n     * @param impostor impostor to set position on\r\n     * @param positionIterations positionIterations value\r\n     */\r\n    public setBodyPositionIterations(impostor: PhysicsImpostor, positionIterations: number) {\r\n        if (impostor.soft) {\r\n            positionIterations = positionIterations < 0 ? 0 : positionIterations;\r\n            impostor.physicsBody.get_m_cfg().set_piterations(positionIterations);\r\n            impostor._pluginData.positionIterations = positionIterations;\r\n        } else {\r\n            Logger.Warn(\"Position iterations cannot be applied to a rigid body\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Append an anchor to a cloth object\r\n     * @param impostor is the cloth impostor to add anchor to\r\n     * @param otherImpostor is the rigid impostor to anchor to\r\n     * @param width ratio across width from 0 to 1\r\n     * @param height ratio up height from 0 to 1\r\n     * @param influence the elasticity between cloth impostor and anchor from 0, very stretchy to 1, little stretch\r\n     * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false\r\n     */\r\n    public appendAnchor(\r\n        impostor: PhysicsImpostor,\r\n        otherImpostor: PhysicsImpostor,\r\n        width: number,\r\n        height: number,\r\n        influence: number = 1,\r\n        noCollisionBetweenLinkedBodies: boolean = false\r\n    ) {\r\n        const segs = impostor.segments;\r\n        const nbAcross = Math.round((segs - 1) * width);\r\n        const nbUp = Math.round((segs - 1) * height);\r\n        const nbDown = segs - 1 - nbUp;\r\n        const node = nbAcross + segs * nbDown;\r\n        impostor.physicsBody.appendAnchor(node, otherImpostor.physicsBody, noCollisionBetweenLinkedBodies, influence);\r\n    }\r\n\r\n    /**\r\n     * Append an hook to a rope object\r\n     * @param impostor is the rope impostor to add hook to\r\n     * @param otherImpostor is the rigid impostor to hook to\r\n     * @param length ratio along the rope from 0 to 1\r\n     * @param influence the elasticity between soft impostor and anchor from 0, very stretchy to 1, little stretch\r\n     * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false\r\n     */\r\n    public appendHook(impostor: PhysicsImpostor, otherImpostor: PhysicsImpostor, length: number, influence: number = 1, noCollisionBetweenLinkedBodies: boolean = false) {\r\n        const node = Math.round(impostor.segments * length);\r\n        impostor.physicsBody.appendAnchor(node, otherImpostor.physicsBody, noCollisionBetweenLinkedBodies, influence);\r\n    }\r\n\r\n    /**\r\n     * Sleeps the physics body and stops it from being active\r\n     * @param impostor impostor to sleep\r\n     */\r\n    public sleepBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.forceActivationState(0);\r\n    }\r\n\r\n    /**\r\n     * Activates the physics body\r\n     * @param impostor impostor to activate\r\n     */\r\n    public wakeUpBody(impostor: PhysicsImpostor) {\r\n        impostor.physicsBody.activate();\r\n    }\r\n\r\n    /**\r\n     * Updates the distance parameters of the joint\r\n     */\r\n    public updateDistanceJoint() {\r\n        Logger.Warn(\"updateDistanceJoint is not currently supported by the Ammo physics plugin\");\r\n    }\r\n\r\n    /**\r\n     * Sets a motor on the joint\r\n     * @param joint joint to set motor on\r\n     * @param speed speed of the motor\r\n     * @param maxForce maximum force of the motor\r\n     */\r\n    public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number) {\r\n        joint.physicsJoint.enableAngularMotor(true, speed, maxForce);\r\n    }\r\n\r\n    /**\r\n     * Sets the motors limit\r\n     */\r\n    public setLimit() {\r\n        Logger.Warn(\"setLimit is not currently supported by the Ammo physics plugin\");\r\n    }\r\n\r\n    /**\r\n     * Syncs the position and rotation of a mesh with the impostor\r\n     * @param mesh mesh to sync\r\n     * @param impostor impostor to update the mesh with\r\n     */\r\n    public syncMeshWithImpostor(mesh: AbstractMesh, impostor: PhysicsImpostor) {\r\n        const body = impostor.physicsBody;\r\n\r\n        body.getMotionState().getWorldTransform(this._tmpAmmoTransform);\r\n\r\n        mesh.position.x = this._tmpAmmoTransform.getOrigin().x();\r\n        mesh.position.y = this._tmpAmmoTransform.getOrigin().y();\r\n        mesh.position.z = this._tmpAmmoTransform.getOrigin().z();\r\n\r\n        if (mesh.rotationQuaternion) {\r\n            mesh.rotationQuaternion.x = this._tmpAmmoTransform.getRotation().x();\r\n            mesh.rotationQuaternion.y = this._tmpAmmoTransform.getRotation().y();\r\n            mesh.rotationQuaternion.z = this._tmpAmmoTransform.getRotation().z();\r\n            mesh.rotationQuaternion.w = this._tmpAmmoTransform.getRotation().w();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the radius of the impostor\r\n     * @param impostor impostor to get radius from\r\n     * @returns the radius\r\n     */\r\n    public getRadius(impostor: PhysicsImpostor): number {\r\n        const extents = impostor.getObjectExtents();\r\n        return extents.x / 2;\r\n    }\r\n\r\n    /**\r\n     * Gets the box size of the impostor\r\n     * @param impostor impostor to get box size from\r\n     * @param result the resulting box size\r\n     */\r\n    public getBoxSizeToRef(impostor: PhysicsImpostor, result: Vector3): void {\r\n        const extents = impostor.getObjectExtents();\r\n        result.x = extents.x;\r\n        result.y = extents.y;\r\n        result.z = extents.z;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the impostor\r\n     */\r\n    public dispose() {\r\n        // Dispose of world\r\n        this.bjsAMMO.destroy(this.world);\r\n        this.bjsAMMO.destroy(this._softBodySolver);\r\n        this.bjsAMMO.destroy(this._solver);\r\n        this.bjsAMMO.destroy(this._overlappingPairCache);\r\n        this.bjsAMMO.destroy(this._dispatcher);\r\n        this.bjsAMMO.destroy(this._collisionConfiguration);\r\n\r\n        // Dispose of temp variables\r\n        this.bjsAMMO.destroy(this._tmpAmmoVectorA);\r\n        this.bjsAMMO.destroy(this._tmpAmmoVectorB);\r\n        this.bjsAMMO.destroy(this._tmpAmmoVectorC);\r\n        this.bjsAMMO.destroy(this._tmpAmmoVectorD);\r\n        this.bjsAMMO.destroy(this._tmpAmmoTransform);\r\n        this.bjsAMMO.destroy(this._tmpAmmoQuaternion);\r\n        this.bjsAMMO.destroy(this._tmpAmmoConcreteContactResultCallback);\r\n\r\n        this.world = null;\r\n    }\r\n\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from where should the ray start?\r\n     * @param to where should the ray end?\r\n     * @returns PhysicsRaycastResult\r\n     */\r\n    public raycast(from: Vector3, to: Vector3): PhysicsRaycastResult {\r\n        this.raycastToRef(from, to, this._raycastResult);\r\n        return this._raycastResult;\r\n    }\r\n    /**\r\n     * Does a raycast in the physics world\r\n     * @param from when should the ray start?\r\n     * @param to when should the ray end?\r\n     * @param result resulting PhysicsRaycastResult\r\n     */\r\n    public raycastToRef(from: Vector3, to: Vector3, result: PhysicsRaycastResult): void {\r\n        this._tmpAmmoVectorRCA = new this.bjsAMMO.btVector3(from.x, from.y, from.z);\r\n        this._tmpAmmoVectorRCB = new this.bjsAMMO.btVector3(to.x, to.y, to.z);\r\n\r\n        const rayCallback = new this.bjsAMMO.ClosestRayResultCallback(this._tmpAmmoVectorRCA, this._tmpAmmoVectorRCB);\r\n        this.world.rayTest(this._tmpAmmoVectorRCA, this._tmpAmmoVectorRCB, rayCallback);\r\n\r\n        result.reset(from, to);\r\n        if (rayCallback.hasHit()) {\r\n            // TODO: do we want/need the body? If so, set all the data\r\n            /*\r\n            var rigidBody = this.bjsAMMO.btRigidBody.prototype.upcast(\r\n                rayCallback.get_m_collisionObject()\r\n            );\r\n            var body = {};\r\n            */\r\n            result.setHitData(\r\n                {\r\n                    x: rayCallback.get_m_hitNormalWorld().x(),\r\n                    y: rayCallback.get_m_hitNormalWorld().y(),\r\n                    z: rayCallback.get_m_hitNormalWorld().z(),\r\n                },\r\n                {\r\n                    x: rayCallback.get_m_hitPointWorld().x(),\r\n                    y: rayCallback.get_m_hitPointWorld().y(),\r\n                    z: rayCallback.get_m_hitPointWorld().z(),\r\n                }\r\n            );\r\n            result.calculateHitDistance();\r\n        }\r\n        this.bjsAMMO.destroy(rayCallback);\r\n        this.bjsAMMO.destroy(this._tmpAmmoVectorRCA);\r\n        this.bjsAMMO.destroy(this._tmpAmmoVectorRCB);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Camera, RegisterCamera } from \"../../Cameras/camera.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Geometry } from \"../../Meshes/geometry\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Material } from \"../../Materials/material.pure\";\r\nimport { MultiMaterial } from \"../../Materials/multiMaterial.pure\";\r\nimport { CubeTexture, CubeTextureCreateFromPrefilteredData, CubeTextureParse, RegisterCubeTexture } from \"../../Materials/Textures/cubeTexture.pure\";\r\nimport { HDRCubeTexture } from \"../../Materials/Textures/hdrCubeTexture.pure\";\r\nimport { RegisterTexture } from \"../../Materials/Textures/texture.pure\";\r\nimport { AnimationGroupParse } from \"../../Animations/animationGroup.pure\";\r\nimport { Light } from \"../../Lights/light\";\r\nimport { SceneLoaderFlags } from \"../sceneLoaderFlags\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { AssetContainer } from \"../../assetContainer\";\r\nimport { ActionManager } from \"../../Actions/actionManager\";\r\nimport { Skeleton } from \"../../Bones/skeleton\";\r\nimport { MorphTargetManager } from \"../../Morph/morphTargetManager\";\r\nimport { ReflectionProbe } from \"../../Probes/reflectionProbe.pure\";\r\nimport { GetClass } from \"../../Misc/typeStore\";\r\nimport { PostProcess } from \"../../PostProcesses/postProcess.pure\";\r\nimport { SpriteManager } from \"core/Sprites/spriteManager\";\r\nimport { Parse, GetIndividualParser } from \"./babylonFileParser.function\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type MorphTarget } from \"../../Morph/morphTarget\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Node } from \"../../node\";\r\nimport { SceneComponentConstants } from \"../../sceneComponent\";\r\nimport { RegisterSceneLoaderPlugin } from \"../../Loading/sceneLoader\";\r\nimport { type IParticleSystem } from \"../../Particles/IParticleSystem\";\r\nimport { CannonJSPlugin } from \"../../Physics/v1/Plugins/cannonJSPlugin.pure\";\r\nimport { OimoJSPlugin } from \"../../Physics/v1/Plugins/oimoJSPlugin\";\r\nimport { AmmoJSPlugin } from \"../../Physics/v1/Plugins/ammoJSPlugin\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention, no-var\r\nexport var _BabylonLoaderRegistered = true;\r\n\r\n/**\r\n * Helps setting up some configuration for the babylon file loader.\r\n */\r\nexport class BabylonFileLoaderConfiguration {\r\n    /**\r\n     * The loader does not allow injecting custom physics engine into the plugins.\r\n     * Unfortunately in ES6, we need to manually inject them into the plugin.\r\n     * So you could set this variable to your engine import to make it work.\r\n     */\r\n    public static LoaderInjectedPhysicsEngine: any = undefined;\r\n}\r\n\r\nlet TempIndexContainer: { [key: string]: Node } = {};\r\nexport let TempMaterialIndexContainer: { [key: string]: Material } = {};\r\nlet TempMorphTargetIndexContainer: { [key: number]: MorphTarget } = {};\r\nexport let TempMorphTargetManagerIndexContainer: { [key: string]: MorphTargetManager } = {};\r\nexport let TempSkeletonIndexContainer: { [key: number]: Skeleton } = {};\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const logOperation = (operation: string, producer: { file: string; name: string; version: string; exporter_version: string }) => {\r\n    return (\r\n        operation +\r\n        \" of \" +\r\n        (producer ? producer.file + \" from \" + producer.name + \" version: \" + producer.version + \", exporter version: \" + producer.exporter_version : \"unknown\")\r\n    );\r\n};\r\n\r\nexport const LoadDetailLevels = (scene: Scene, mesh: AbstractMesh) => {\r\n    const mastermesh: Mesh = mesh as Mesh;\r\n\r\n    // Every value specified in the ids array of the lod data points to another mesh which should be used as the lower LOD level.\r\n    // The distances (or coverages) array values specified are used along with the lod mesh ids as a hint to determine the switching threshold for the various LODs.\r\n    if (mesh._waitingData.lods) {\r\n        if (mesh._waitingData.lods.ids && mesh._waitingData.lods.ids.length > 0) {\r\n            const lodmeshes: string[] = mesh._waitingData.lods.ids;\r\n            const wasenabled: boolean = mastermesh.isEnabled(false);\r\n            if (mesh._waitingData.lods.distances) {\r\n                const distances: number[] = mesh._waitingData.lods.distances;\r\n                if (distances.length >= lodmeshes.length) {\r\n                    const culling: number = distances.length > lodmeshes.length ? distances[distances.length - 1] : 0;\r\n                    mastermesh.setEnabled(false);\r\n                    for (let index = 0; index < lodmeshes.length; index++) {\r\n                        const lodid: string = lodmeshes[index];\r\n                        const lodmesh: Mesh = scene.getMeshById(lodid) as Mesh;\r\n                        if (lodmesh != null) {\r\n                            mastermesh.addLODLevel(distances[index], lodmesh);\r\n                        }\r\n                    }\r\n                    if (culling > 0) {\r\n                        mastermesh.addLODLevel(culling, null);\r\n                    }\r\n                    if (wasenabled === true) {\r\n                        mastermesh.setEnabled(true);\r\n                    }\r\n                } else {\r\n                    Logger.Warn(\"Invalid level of detail distances for \" + mesh.name);\r\n                }\r\n            }\r\n        }\r\n        mesh._waitingData.lods = null;\r\n    }\r\n};\r\n\r\nconst FindParent = (parentId: any, parentInstanceIndex: any, scene: Scene) => {\r\n    if (typeof parentId !== \"number\") {\r\n        const parentEntry = scene.getLastEntryById(parentId);\r\n        if (parentEntry && parentInstanceIndex !== undefined && parentInstanceIndex !== null) {\r\n            const instance = (parentEntry as Mesh).instances[parseInt(parentInstanceIndex)];\r\n            return instance;\r\n        }\r\n        return parentEntry;\r\n    }\r\n\r\n    const parent = TempIndexContainer[parentId];\r\n    if (parent && parentInstanceIndex !== undefined && parentInstanceIndex !== null) {\r\n        const instance = (parent as Mesh).instances[parseInt(parentInstanceIndex)];\r\n        return instance;\r\n    }\r\n\r\n    return parent;\r\n};\r\n\r\nexport const FindMaterial = (materialId: any, scene: Scene) => {\r\n    if (typeof materialId !== \"number\") {\r\n        return scene.getLastMaterialById(materialId, true);\r\n    }\r\n\r\n    return TempMaterialIndexContainer[materialId];\r\n};\r\n\r\n/**\r\n * @experimental\r\n * Loads an AssetContainer from a serialized Babylon scene.\r\n * @param scene The scene to load the asset container into.\r\n * @param serializedScene The serialized scene data. This can be either a JSON string, or an object (e.g. from a call to JSON.parse).\r\n * @param rootUrl The root URL for loading assets.\r\n * @returns The loaded AssetContainer.\r\n */\r\nexport function LoadAssetContainerFromSerializedScene(scene: Scene, serializedScene: string | object, rootUrl: string): AssetContainer {\r\n    return LoadAssetContainer(scene, serializedScene, rootUrl);\r\n}\r\n\r\nexport const LoadAssetContainer = (\r\n    scene: Scene,\r\n    data: string | object,\r\n    rootUrl: string,\r\n    onError?: (message: string, exception?: any) => void,\r\n    addToScene = false\r\n): AssetContainer => {\r\n    const container = new AssetContainer(scene);\r\n\r\n    // When loading into a container (not directly into the scene), suppress entity-added\r\n    // observables to prevent scene events during loading. Entities still get added to scene\r\n    // arrays (so the linking code can find them), but no events fire.\r\n    // They are removed from the scene at the end via container.removeAllFromScene().\r\n    let savedObservables: Record<string, Observable<any>> | undefined;\r\n    if (!addToScene) {\r\n        savedObservables = {\r\n            mesh: scene.onNewMeshAddedObservable,\r\n            transformNode: scene.onNewTransformNodeAddedObservable,\r\n            light: scene.onNewLightAddedObservable,\r\n            camera: scene.onNewCameraAddedObservable,\r\n            material: scene.onNewMaterialAddedObservable,\r\n            multiMaterial: scene.onNewMultiMaterialAddedObservable,\r\n            texture: scene.onNewTextureAddedObservable,\r\n            skeleton: scene.onNewSkeletonAddedObservable,\r\n            geometry: scene.onNewGeometryAddedObservable,\r\n            animationGroup: scene.onNewAnimationGroupAddedObservable,\r\n            particleSystem: scene.onNewParticleSystemAddedObservable,\r\n        };\r\n        scene.onNewMeshAddedObservable = new Observable();\r\n        scene.onNewTransformNodeAddedObservable = new Observable();\r\n        scene.onNewLightAddedObservable = new Observable();\r\n        scene.onNewCameraAddedObservable = new Observable();\r\n        scene.onNewMaterialAddedObservable = new Observable();\r\n        scene.onNewMultiMaterialAddedObservable = new Observable();\r\n        scene.onNewTextureAddedObservable = new Observable();\r\n        scene.onNewSkeletonAddedObservable = new Observable();\r\n        scene.onNewGeometryAddedObservable = new Observable();\r\n        scene.onNewAnimationGroupAddedObservable = new Observable();\r\n        scene.onNewParticleSystemAddedObservable = new Observable();\r\n    }\r\n\r\n    // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details\r\n    // when SceneLoader.debugLogging = true (default), or exception encountered.\r\n    // Everything stored in var log instead of writing separate lines to support only writing in exception,\r\n    // and avoid problems with multiple concurrent .babylon loads.\r\n    let log = \"importScene has failed JSON parse\";\r\n    try {\r\n        // eslint-disable-next-line no-var\r\n        var parsedData = typeof data === \"object\" ? data : JSON.parse(data);\r\n        log = \"\";\r\n        const fullDetails = SceneLoaderFlags.loggingLevel === Constants.SCENELOADER_DETAILED_LOGGING;\r\n\r\n        let index: number;\r\n        let cache: number;\r\n\r\n        // Environment texture\r\n        if (parsedData.environmentTexture !== undefined && parsedData.environmentTexture !== null) {\r\n            // PBR needed for both HDR texture (gamma space) & a sky box\r\n            const isPBR = parsedData.isPBR !== undefined ? parsedData.isPBR : true;\r\n            if (parsedData.environmentTextureType && parsedData.environmentTextureType === \"BABYLON.HDRCubeTexture\") {\r\n                const hdrSize: number = parsedData.environmentTextureSize ? parsedData.environmentTextureSize : 128;\r\n                const hdrTexture = new HDRCubeTexture(\r\n                    (parsedData.environmentTexture.match(/https?:\\/\\//g) ? \"\" : rootUrl) + parsedData.environmentTexture,\r\n                    scene,\r\n                    hdrSize,\r\n                    true,\r\n                    !isPBR,\r\n                    undefined,\r\n                    parsedData.environmentTexturePrefilterOnLoad\r\n                );\r\n                if (parsedData.environmentTextureRotationY) {\r\n                    hdrTexture.rotationY = parsedData.environmentTextureRotationY;\r\n                }\r\n                scene.environmentTexture = hdrTexture;\r\n            } else {\r\n                if (typeof parsedData.environmentTexture === \"object\") {\r\n                    const environmentTexture = CubeTextureParse(parsedData.environmentTexture, scene, rootUrl);\r\n                    scene.environmentTexture = environmentTexture;\r\n                } else if ((parsedData.environmentTexture as string).endsWith(\".env\")) {\r\n                    const compressedTexture = new CubeTexture(\r\n                        (parsedData.environmentTexture.match(/https?:\\/\\//g) ? \"\" : rootUrl) + parsedData.environmentTexture,\r\n                        scene,\r\n                        parsedData.environmentTextureForcedExtension\r\n                    );\r\n                    if (parsedData.environmentTextureRotationY) {\r\n                        compressedTexture.rotationY = parsedData.environmentTextureRotationY;\r\n                    }\r\n                    scene.environmentTexture = compressedTexture;\r\n                } else {\r\n                    const cubeTexture = CubeTextureCreateFromPrefilteredData(\r\n                        (parsedData.environmentTexture.match(/https?:\\/\\//g) ? \"\" : rootUrl) + parsedData.environmentTexture,\r\n                        scene,\r\n                        parsedData.environmentTextureForcedExtension\r\n                    );\r\n                    if (parsedData.environmentTextureRotationY) {\r\n                        cubeTexture.rotationY = parsedData.environmentTextureRotationY;\r\n                    }\r\n                    scene.environmentTexture = cubeTexture;\r\n                }\r\n            }\r\n            if (parsedData.createDefaultSkybox === true) {\r\n                const skyboxScale = scene.activeCamera !== undefined && scene.activeCamera !== null ? (scene.activeCamera.maxZ - scene.activeCamera.minZ) / 2 : 1000;\r\n                const skyboxBlurLevel = parsedData.skyboxBlurLevel || 0;\r\n                scene.createDefaultSkybox(scene.environmentTexture, isPBR, skyboxScale, skyboxBlurLevel);\r\n            }\r\n            container.environmentTexture = scene.environmentTexture;\r\n        }\r\n\r\n        // Environment Intensity\r\n        if (parsedData.environmentIntensity !== undefined && parsedData.environmentIntensity !== null) {\r\n            scene.environmentIntensity = parsedData.environmentIntensity;\r\n        }\r\n\r\n        // IBL Intensity\r\n        if (parsedData.iblIntensity !== undefined && parsedData.iblIntensity !== null) {\r\n            scene.iblIntensity = parsedData.iblIntensity;\r\n        }\r\n\r\n        // Lights\r\n        if (parsedData.lights !== undefined && parsedData.lights !== null) {\r\n            for (index = 0, cache = parsedData.lights.length; index < cache; index++) {\r\n                const parsedLight = parsedData.lights[index];\r\n                const light = Light.Parse(parsedLight, scene, rootUrl);\r\n                if (light) {\r\n                    TempIndexContainer[parsedLight.uniqueId] = light;\r\n                    container.lights.push(light);\r\n                    light._parentContainer = container;\r\n                    log += index === 0 ? \"\\n\\tLights:\" : \"\";\r\n                    log += \"\\n\\t\\t\" + light.toString(fullDetails);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Reflection probes\r\n        if (parsedData.reflectionProbes !== undefined && parsedData.reflectionProbes !== null) {\r\n            for (index = 0, cache = parsedData.reflectionProbes.length; index < cache; index++) {\r\n                const parsedReflectionProbe = parsedData.reflectionProbes[index];\r\n                const reflectionProbe = ReflectionProbe.Parse(parsedReflectionProbe, scene, rootUrl);\r\n                if (reflectionProbe) {\r\n                    container.reflectionProbes.push(reflectionProbe);\r\n                    reflectionProbe._parentContainer = container;\r\n                    log += index === 0 ? \"\\n\\tReflection Probes:\" : \"\";\r\n                    log += \"\\n\\t\\t\" + reflectionProbe.toString(fullDetails);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Animations\r\n        if (parsedData.animations !== undefined && parsedData.animations !== null) {\r\n            for (index = 0, cache = parsedData.animations.length; index < cache; index++) {\r\n                const parsedAnimation = parsedData.animations[index];\r\n                const internalClass = GetClass(\"BABYLON.Animation\");\r\n                if (internalClass) {\r\n                    const animation = internalClass.Parse(parsedAnimation);\r\n                    scene.animations.push(animation);\r\n                    container.animations.push(animation);\r\n                    log += index === 0 ? \"\\n\\tAnimations:\" : \"\";\r\n                    log += \"\\n\\t\\t\" + animation.toString(fullDetails);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Materials\r\n        if (parsedData.materials !== undefined && parsedData.materials !== null) {\r\n            for (index = 0, cache = parsedData.materials.length; index < cache; index++) {\r\n                const parsedMaterial = parsedData.materials[index];\r\n                const mat = Material.Parse(parsedMaterial, scene, rootUrl);\r\n                if (mat) {\r\n                    TempMaterialIndexContainer[parsedMaterial.uniqueId || parsedMaterial.id] = mat;\r\n                    container.materials.push(mat);\r\n                    mat._parentContainer = container;\r\n                    log += index === 0 ? \"\\n\\tMaterials:\" : \"\";\r\n                    log += \"\\n\\t\\t\" + mat.toString(fullDetails);\r\n\r\n                    // Textures\r\n                    const textures = mat.getActiveTextures();\r\n                    for (const t of textures) {\r\n                        if (container.textures.indexOf(t) == -1) {\r\n                            container.textures.push(t);\r\n                            t._parentContainer = container;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (parsedData.multiMaterials !== undefined && parsedData.multiMaterials !== null) {\r\n            for (index = 0, cache = parsedData.multiMaterials.length; index < cache; index++) {\r\n                const parsedMultiMaterial = parsedData.multiMaterials[index];\r\n                const mmat = MultiMaterial.ParseMultiMaterial(parsedMultiMaterial, scene);\r\n                TempMaterialIndexContainer[parsedMultiMaterial.uniqueId || parsedMultiMaterial.id] = mmat;\r\n                container.multiMaterials.push(mmat);\r\n                mmat._parentContainer = container;\r\n\r\n                log += index === 0 ? \"\\n\\tMultiMaterials:\" : \"\";\r\n                log += \"\\n\\t\\t\" + mmat.toString(fullDetails);\r\n\r\n                // Textures\r\n                const textures = mmat.getActiveTextures();\r\n                for (const t of textures) {\r\n                    if (container.textures.indexOf(t) == -1) {\r\n                        container.textures.push(t);\r\n                        t._parentContainer = container;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Morph target managers\r\n        if (parsedData.morphTargetManagers !== undefined && parsedData.morphTargetManagers !== null) {\r\n            for (const parsedManager of parsedData.morphTargetManagers) {\r\n                const manager = MorphTargetManager.Parse(parsedManager, scene);\r\n                TempMorphTargetManagerIndexContainer[parsedManager.id] = manager;\r\n                container.morphTargetManagers.push(manager);\r\n                manager._parentContainer = container;\r\n\r\n                // Morph targets - add to TempMorphTargetIndexContainer to later connect animations -> morph targets\r\n                for (let index = 0; index < parsedManager.targets.length; index++) {\r\n                    const parsedTarget = parsedManager.targets[index];\r\n                    if (parsedTarget.uniqueId !== undefined && parsedTarget.uniqueId !== null) {\r\n                        const target = manager.getTarget(index);\r\n                        TempMorphTargetIndexContainer[parsedTarget.uniqueId] = target;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Skeletons\r\n        if (parsedData.skeletons !== undefined && parsedData.skeletons !== null) {\r\n            for (index = 0, cache = parsedData.skeletons.length; index < cache; index++) {\r\n                const parsedSkeleton = parsedData.skeletons[index];\r\n                const skeleton = Skeleton.Parse(parsedSkeleton, scene);\r\n                if (parsedSkeleton.uniqueId !== undefined && parsedSkeleton.uniqueId !== null) {\r\n                    TempSkeletonIndexContainer[parsedSkeleton.uniqueId] = skeleton;\r\n                }\r\n                container.skeletons.push(skeleton);\r\n                skeleton._parentContainer = container;\r\n                log += index === 0 ? \"\\n\\tSkeletons:\" : \"\";\r\n                log += \"\\n\\t\\t\" + skeleton.toString(fullDetails);\r\n\r\n                // Bones - add to TempIndexContainer to later connect animations -> bones\r\n                for (let boneIndex = 0; boneIndex < parsedSkeleton.bones.length; boneIndex++) {\r\n                    const parsedBone = parsedSkeleton.bones[boneIndex];\r\n                    const bone = skeleton.bones[boneIndex]; // This was instantiated in Skeleton.Parse\r\n                    TempIndexContainer[parsedBone.uniqueId] = bone;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Geometries\r\n        const geometries = parsedData.geometries;\r\n        if (geometries !== undefined && geometries !== null) {\r\n            const addedGeometry = new Array<Nullable<Geometry>>();\r\n\r\n            // VertexData\r\n            const vertexData = geometries.vertexData;\r\n            if (vertexData !== undefined && vertexData !== null) {\r\n                for (index = 0, cache = vertexData.length; index < cache; index++) {\r\n                    const parsedVertexData = vertexData[index];\r\n\r\n                    addedGeometry.push(Geometry.Parse(parsedVertexData, scene, rootUrl));\r\n                }\r\n            }\r\n\r\n            for (const g of addedGeometry) {\r\n                if (g) {\r\n                    container.geometries.push(g);\r\n                    g._parentContainer = container;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Transform nodes\r\n        if (parsedData.transformNodes !== undefined && parsedData.transformNodes !== null) {\r\n            for (index = 0, cache = parsedData.transformNodes.length; index < cache; index++) {\r\n                const parsedTransformNode = parsedData.transformNodes[index];\r\n                const node = TransformNode.Parse(parsedTransformNode, scene, rootUrl);\r\n                TempIndexContainer[parsedTransformNode.uniqueId] = node;\r\n                container.transformNodes.push(node);\r\n                node._parentContainer = container;\r\n            }\r\n        }\r\n\r\n        // Meshes\r\n        if (parsedData.meshes !== undefined && parsedData.meshes !== null) {\r\n            for (index = 0, cache = parsedData.meshes.length; index < cache; index++) {\r\n                const parsedMesh = parsedData.meshes[index];\r\n                const mesh = <AbstractMesh>Mesh.Parse(parsedMesh, scene, rootUrl);\r\n                TempIndexContainer[parsedMesh.uniqueId] = mesh;\r\n                container.meshes.push(mesh);\r\n                mesh._parentContainer = container;\r\n                if (mesh.hasInstances) {\r\n                    for (const instance of (mesh as Mesh).instances) {\r\n                        container.meshes.push(instance);\r\n                        instance._parentContainer = container;\r\n                    }\r\n                }\r\n                // Load partProxies from GaussianSplattingMesh into AssetContainer\r\n                if (mesh.getClassName() === \"GaussianSplattingMesh\") {\r\n                    const partProxies = (mesh as any)._partProxies as AbstractMesh[] | Map<number, AbstractMesh> | undefined;\r\n                    const proxies = Array.isArray(partProxies) ? partProxies : partProxies ? Array.from(partProxies.values()) : [];\r\n                    for (const partProxy of proxies) {\r\n                        if (!partProxy) {\r\n                            continue;\r\n                        }\r\n                        container.meshes.push(partProxy);\r\n                        partProxy._parentContainer = container;\r\n                        if (partProxy._waitingParsedUniqueId != null) {\r\n                            TempIndexContainer[partProxy._waitingParsedUniqueId] = partProxy;\r\n                        }\r\n                    }\r\n                }\r\n                log += index === 0 ? \"\\n\\tMeshes:\" : \"\";\r\n                log += \"\\n\\t\\t\" + mesh.toString(fullDetails);\r\n            }\r\n        }\r\n\r\n        // Cameras\r\n        if (parsedData.cameras !== undefined && parsedData.cameras !== null) {\r\n            for (index = 0, cache = parsedData.cameras.length; index < cache; index++) {\r\n                const parsedCamera = parsedData.cameras[index];\r\n                const camera = Camera.Parse(parsedCamera, scene);\r\n                TempIndexContainer[parsedCamera.uniqueId] = camera;\r\n                container.cameras.push(camera);\r\n                camera._parentContainer = container;\r\n                log += index === 0 ? \"\\n\\tCameras:\" : \"\";\r\n                log += \"\\n\\t\\t\" + camera.toString(fullDetails);\r\n            }\r\n        }\r\n\r\n        // Postprocesses\r\n        if (parsedData.postProcesses !== undefined && parsedData.postProcesses !== null) {\r\n            for (index = 0, cache = parsedData.postProcesses.length; index < cache; index++) {\r\n                const parsedPostProcess = parsedData.postProcesses[index];\r\n                const postProcess = PostProcess.Parse(parsedPostProcess, scene, rootUrl);\r\n                if (postProcess) {\r\n                    container.postProcesses.push(postProcess);\r\n                    postProcess._parentContainer = container;\r\n                    log += index === 0 ? \"\\nPostprocesses:\" : \"\";\r\n                    log += \"\\n\\t\\t\" + postProcess.toString();\r\n                }\r\n            }\r\n        }\r\n\r\n        // Animation Groups\r\n        if (parsedData.animationGroups !== undefined && parsedData.animationGroups !== null && parsedData.animationGroups.length) {\r\n            // Build the nodeMap only for scenes with animationGroups.\r\n            let nodeMap: Nullable<Map<Node[\"id\"], Node>> = null;\r\n\r\n            // Helper to get nodes by id more efficiently, building the nodeMap only on first access.\r\n            const getNodeById = (id: Node[\"id\"]) => {\r\n                if (!nodeMap) {\r\n                    nodeMap = new Map<Node[\"id\"], Node>();\r\n\r\n                    // Nodes in scene does not change when parsing animationGroups, so it's safe to build a map.\r\n                    // This follows the order of scene.getNodeById: mesh, transformNode, light, camera, bone\r\n                    for (let index = 0; index < scene.meshes.length; index++) {\r\n                        // This follows the behavior of scene.getXXXById, which picks the first match\r\n                        if (!nodeMap.has(scene.meshes[index].id)) {\r\n                            nodeMap.set(scene.meshes[index].id, scene.meshes[index]);\r\n                        }\r\n                    }\r\n                    for (let index = 0; index < scene.transformNodes.length; index++) {\r\n                        if (!nodeMap.has(scene.transformNodes[index].id)) {\r\n                            nodeMap.set(scene.transformNodes[index].id, scene.transformNodes[index]);\r\n                        }\r\n                    }\r\n                    for (let index = 0; index < scene.lights.length; index++) {\r\n                        if (!nodeMap.has(scene.lights[index].id)) {\r\n                            nodeMap.set(scene.lights[index].id, scene.lights[index]);\r\n                        }\r\n                    }\r\n                    for (let index = 0; index < scene.cameras.length; index++) {\r\n                        if (!nodeMap.has(scene.cameras[index].id)) {\r\n                            nodeMap.set(scene.cameras[index].id, scene.cameras[index]);\r\n                        }\r\n                    }\r\n                    for (let skeletonIndex = 0; skeletonIndex < scene.skeletons.length; skeletonIndex++) {\r\n                        const skeleton = scene.skeletons[skeletonIndex];\r\n                        for (let boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {\r\n                            if (!nodeMap.has(skeleton.bones[boneIndex].id)) {\r\n                                nodeMap.set(skeleton.bones[boneIndex].id, skeleton.bones[boneIndex]);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return nodeMap.get(id);\r\n            };\r\n\r\n            const targetLookup = (parsedTargetAnimation: any) => {\r\n                let target = null;\r\n                const isMorphTarget = parsedTargetAnimation.animation.property === \"influence\";\r\n                const uniqueId = parsedTargetAnimation.targetUniqueId;\r\n\r\n                // Attempt to find animation targets by uniqueId first (tracked in TempXXXIndexContainer).\r\n                if (uniqueId !== undefined && uniqueId !== null) {\r\n                    target = isMorphTarget ? TempMorphTargetIndexContainer[uniqueId] : TempIndexContainer[uniqueId];\r\n                }\r\n\r\n                // Backwards compatibility: If no uniqueId is provided or no match is found,\r\n                // fall back to searching by id in the scene.\r\n                if (!target) {\r\n                    const id = parsedTargetAnimation.targetId;\r\n                    target = isMorphTarget ? scene.getMorphTargetById(id) : getNodeById(id);\r\n                }\r\n\r\n                return target;\r\n            };\r\n\r\n            for (index = 0, cache = parsedData.animationGroups.length; index < cache; index++) {\r\n                const parsedAnimationGroup = parsedData.animationGroups[index];\r\n                const animationGroup = AnimationGroupParse(parsedAnimationGroup, scene, targetLookup);\r\n                container.animationGroups.push(animationGroup);\r\n                animationGroup._parentContainer = container;\r\n                log += index === 0 ? \"\\n\\tAnimationGroups:\" : \"\";\r\n                log += \"\\n\\t\\t\" + animationGroup.toString(fullDetails);\r\n            }\r\n        }\r\n\r\n        // Sprites\r\n        if (parsedData.spriteManagers) {\r\n            for (let index = 0, cache = parsedData.spriteManagers.length; index < cache; index++) {\r\n                const parsedSpriteManager = parsedData.spriteManagers[index];\r\n                const spriteManager = SpriteManager.Parse(parsedSpriteManager, scene, rootUrl);\r\n                container.spriteManagers.push(spriteManager);\r\n                spriteManager._parentContainer = container;\r\n                log += \"\\n\\t\\tSpriteManager \" + spriteManager.name;\r\n            }\r\n        }\r\n\r\n        // Browsing all the graph to connect the dots\r\n        for (index = 0, cache = scene.cameras.length; index < cache; index++) {\r\n            const camera = scene.cameras[index];\r\n            if (camera._waitingParentId !== null) {\r\n                camera.parent = FindParent(camera._waitingParentId, camera._waitingParentInstanceIndex, scene);\r\n                camera._waitingParentId = null;\r\n                camera._waitingParentInstanceIndex = null;\r\n            }\r\n        }\r\n\r\n        for (index = 0, cache = scene.lights.length; index < cache; index++) {\r\n            const light = scene.lights[index];\r\n            if (light && light._waitingParentId !== null) {\r\n                light.parent = FindParent(light._waitingParentId, light._waitingParentInstanceIndex, scene);\r\n                light._waitingParentId = null;\r\n                light._waitingParentInstanceIndex = null;\r\n            }\r\n        }\r\n\r\n        // Connect parents & children and parse actions and lods\r\n        for (index = 0, cache = scene.transformNodes.length; index < cache; index++) {\r\n            const transformNode = scene.transformNodes[index];\r\n            if (transformNode._waitingParentId !== null) {\r\n                transformNode.parent = FindParent(transformNode._waitingParentId, transformNode._waitingParentInstanceIndex, scene);\r\n                transformNode._waitingParentId = null;\r\n                transformNode._waitingParentInstanceIndex = null;\r\n            }\r\n        }\r\n        for (index = 0, cache = scene.meshes.length; index < cache; index++) {\r\n            const mesh = scene.meshes[index];\r\n            if (mesh._waitingParentId !== null) {\r\n                mesh.parent = FindParent(mesh._waitingParentId, mesh._waitingParentInstanceIndex, scene);\r\n                mesh._waitingParentId = null;\r\n                mesh._waitingParentInstanceIndex = null;\r\n            }\r\n            if (mesh._waitingData.lods) {\r\n                LoadDetailLevels(scene, mesh);\r\n            }\r\n        }\r\n\r\n        // link multimats with materials\r\n        for (const multimat of scene.multiMaterials) {\r\n            for (const subMaterial of multimat._waitingSubMaterialsUniqueIds) {\r\n                multimat.subMaterials.push(FindMaterial(subMaterial, scene));\r\n            }\r\n            multimat._waitingSubMaterialsUniqueIds = [];\r\n        }\r\n\r\n        // link meshes with materials\r\n        for (const mesh of scene.meshes) {\r\n            if (mesh._waitingMaterialId !== null) {\r\n                mesh.material = FindMaterial(mesh._waitingMaterialId, scene);\r\n                mesh._waitingMaterialId = null;\r\n            }\r\n        }\r\n\r\n        // link meshes with morph target managers\r\n        for (const mesh of scene.meshes) {\r\n            if (mesh._waitingMorphTargetManagerId !== null) {\r\n                mesh.morphTargetManager = TempMorphTargetManagerIndexContainer[mesh._waitingMorphTargetManagerId];\r\n                mesh._waitingMorphTargetManagerId = null;\r\n            }\r\n        }\r\n\r\n        // link meshes with skeletons\r\n        for (const mesh of scene.meshes) {\r\n            // First try to get it via uniqueId\r\n            if (mesh._waitingSkeletonUniqueId !== null) {\r\n                mesh.skeleton = TempSkeletonIndexContainer[mesh._waitingSkeletonUniqueId];\r\n            }\r\n\r\n            // If not possible or not found, try to get it from the scene (backwards compatibility)\r\n            if (mesh._waitingSkeletonId !== null && !mesh.skeleton) {\r\n                mesh.skeleton = scene.getLastSkeletonById(mesh._waitingSkeletonId);\r\n            }\r\n\r\n            mesh._waitingSkeletonId = null;\r\n            mesh._waitingSkeletonUniqueId = null;\r\n        }\r\n\r\n        // link bones to transform nodes\r\n        for (index = 0, cache = scene.skeletons.length; index < cache; index++) {\r\n            const skeleton = scene.skeletons[index];\r\n            if (skeleton._hasWaitingData) {\r\n                if (skeleton.bones != null) {\r\n                    for (const bone of skeleton.bones) {\r\n                        let linkTransformNode: Nullable<Node> = null;\r\n                        // First try to get it via uniqueId\r\n                        if (bone._waitingTransformNodeUniqueId !== null) {\r\n                            linkTransformNode = TempIndexContainer[bone._waitingTransformNodeUniqueId];\r\n                        }\r\n\r\n                        // If not possible or not found, try to get it from the scene (backwards compatibility)\r\n                        if (bone._waitingTransformNodeId !== null && !linkTransformNode) {\r\n                            linkTransformNode = scene.getLastEntryById(bone._waitingTransformNodeId);\r\n                        }\r\n\r\n                        if (linkTransformNode) {\r\n                            bone.linkTransformNode(linkTransformNode as TransformNode);\r\n                        }\r\n\r\n                        bone._waitingTransformNodeId = null;\r\n                        bone._waitingTransformNodeUniqueId = null;\r\n                    }\r\n                }\r\n\r\n                skeleton._hasWaitingData = null;\r\n            }\r\n        }\r\n\r\n        // freeze world matrix application\r\n        for (index = 0, cache = scene.transformNodes.length; index < cache; index++) {\r\n            const currentTransformNode = scene.transformNodes[index];\r\n            if (currentTransformNode._waitingFreezeWorldMatrix) {\r\n                currentTransformNode.freezeWorldMatrix();\r\n                currentTransformNode._waitingFreezeWorldMatrix = null;\r\n            }\r\n        }\r\n        for (index = 0, cache = scene.meshes.length; index < cache; index++) {\r\n            const currentMesh = scene.meshes[index];\r\n            if (currentMesh._waitingData.freezeWorldMatrix) {\r\n                currentMesh.freezeWorldMatrix();\r\n                currentMesh._waitingData.freezeWorldMatrix = null;\r\n            } else {\r\n                currentMesh.computeWorldMatrix(true);\r\n            }\r\n        }\r\n\r\n        // Lights exclusions / inclusions\r\n        for (index = 0, cache = scene.lights.length; index < cache; index++) {\r\n            const light = scene.lights[index];\r\n            // Excluded check\r\n            if (light._excludedMeshesIds.length > 0) {\r\n                for (let excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {\r\n                    const excludedMesh = scene.getMeshById(light._excludedMeshesIds[excludedIndex]);\r\n\r\n                    if (excludedMesh) {\r\n                        light.excludedMeshes.push(excludedMesh);\r\n                    }\r\n                }\r\n\r\n                light._excludedMeshesIds = [];\r\n            }\r\n\r\n            // Included check\r\n            if (light._includedOnlyMeshesIds.length > 0) {\r\n                for (let includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {\r\n                    const includedOnlyMesh = scene.getMeshById(light._includedOnlyMeshesIds[includedOnlyIndex]);\r\n\r\n                    if (includedOnlyMesh) {\r\n                        light.includedOnlyMeshes.push(includedOnlyMesh);\r\n                    }\r\n                }\r\n\r\n                light._includedOnlyMeshesIds = [];\r\n            }\r\n        }\r\n\r\n        for (const g of scene.geometries) {\r\n            g._loadedUniqueId = \"\";\r\n        }\r\n\r\n        Parse(parsedData, scene, container, rootUrl);\r\n\r\n        // Actions (scene) Done last as it can access other objects.\r\n        for (index = 0, cache = scene.meshes.length; index < cache; index++) {\r\n            const mesh = scene.meshes[index];\r\n            if (mesh._waitingData.actions) {\r\n                ActionManager.Parse(mesh._waitingData.actions, mesh, scene);\r\n                mesh._waitingData.actions = null;\r\n            }\r\n        }\r\n        if (parsedData.actions !== undefined && parsedData.actions !== null) {\r\n            ActionManager.Parse(parsedData.actions, null, scene);\r\n        }\r\n    } catch (err) {\r\n        const msg = logOperation(\"loadAssets\", parsedData ? parsedData.producer : \"Unknown\") + log;\r\n        if (onError) {\r\n            onError(msg, err);\r\n        } else {\r\n            Logger.Log(msg);\r\n            throw err;\r\n        }\r\n    } finally {\r\n        TempIndexContainer = {};\r\n        TempMaterialIndexContainer = {};\r\n        TempMorphTargetIndexContainer = {};\r\n        TempMorphTargetManagerIndexContainer = {};\r\n        TempSkeletonIndexContainer = {};\r\n\r\n        if (!addToScene) {\r\n            // Restore observables before removing from scene\r\n            if (savedObservables) {\r\n                scene.onNewMeshAddedObservable = savedObservables.mesh;\r\n                scene.onNewTransformNodeAddedObservable = savedObservables.transformNode;\r\n                scene.onNewLightAddedObservable = savedObservables.light;\r\n                scene.onNewCameraAddedObservable = savedObservables.camera;\r\n                scene.onNewMaterialAddedObservable = savedObservables.material;\r\n                scene.onNewMultiMaterialAddedObservable = savedObservables.multiMaterial;\r\n                scene.onNewTextureAddedObservable = savedObservables.texture;\r\n                scene.onNewSkeletonAddedObservable = savedObservables.skeleton;\r\n                scene.onNewGeometryAddedObservable = savedObservables.geometry;\r\n                scene.onNewAnimationGroupAddedObservable = savedObservables.animationGroup;\r\n                scene.onNewParticleSystemAddedObservable = savedObservables.particleSystem;\r\n            }\r\n            // Removes entities from scene arrays and moves them to the container\r\n            container.removeAllFromScene();\r\n        }\r\n        if (log !== null && SceneLoaderFlags.loggingLevel !== Constants.SCENELOADER_NO_LOGGING) {\r\n            Logger.Log(\r\n                logOperation(\"loadAssets\", parsedData ? parsedData.producer : \"Unknown\") + (SceneLoaderFlags.loggingLevel !== Constants.SCENELOADER_MINIMAL_LOGGING ? log : \"\")\r\n            );\r\n        }\r\n    }\r\n\r\n    return container;\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for babylonFileLoader.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBabylonFileLoader(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // The loader parses cameras through the Camera.Parse static, which is only\r\n    // installed by the render-time camera registration. Because this module imports\r\n    // camera.pure (side-effect free), pull the registration in here so a tree-shaken\r\n    // build that only imports the .babylon loader can still parse cameras. Without\r\n    // this, Camera.Parse throws mid-load and the scene ends up with no active camera.\r\n    RegisterCamera();\r\n\r\n    // The loader parses textures through SerializationHelper._TextureParser and cube\r\n    // textures through Texture._CubeTextureParser. These hooks are installed by the\r\n    // texture / cube texture registrations. Because this module imports the pure\r\n    // texture modules (side-effect free), pull the registrations in here so material\r\n    // textures (diffuse, reflection, etc.) actually load. Without this, materials\r\n    // parse but their textures are silently dropped (meshes render untextured).\r\n    RegisterTexture();\r\n    RegisterCubeTexture();\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const ParseMaterialByPredicate = (predicate: (parsedMaterial: any) => boolean, parsedData: any, scene: Scene, rootUrl: string) => {\r\n        if (!parsedData.materials) {\r\n            return null;\r\n        }\r\n\r\n        for (let index = 0, cache = parsedData.materials.length; index < cache; index++) {\r\n            const parsedMaterial = parsedData.materials[index];\r\n            if (predicate(parsedMaterial)) {\r\n                return { parsedMaterial, material: Material.Parse(parsedMaterial, scene, rootUrl) };\r\n            }\r\n        }\r\n        return null;\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const IsDescendantOf = (mesh: any, names: Array<any>, hierarchyIds: Array<number>) => {\r\n        for (const i in names) {\r\n            if (mesh.name === names[i]) {\r\n                hierarchyIds.push(mesh.id);\r\n                return true;\r\n            }\r\n        }\r\n        if (mesh.parentId !== undefined && hierarchyIds.indexOf(mesh.parentId) !== -1) {\r\n            hierarchyIds.push(mesh.id);\r\n            return true;\r\n        }\r\n        return false;\r\n    };\r\n\r\n    RegisterSceneLoaderPlugin({\r\n        name: \"babylon.js\",\r\n        extensions: \".babylon\",\r\n        canDirectLoad: (data: string) => {\r\n            if (data.indexOf(\"babylon\") !== -1) {\r\n                // We consider that the producer string is filled\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        },\r\n        importMesh: (\r\n            meshesNames: any,\r\n            scene: Scene,\r\n            data: any,\r\n            rootUrl: string,\r\n            meshes: AbstractMesh[],\r\n            particleSystems: IParticleSystem[],\r\n            skeletons: Skeleton[],\r\n            onError?: (message: string, exception?: any) => void\r\n        ): boolean => {\r\n            // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details\r\n            // when SceneLoader.debugLogging = true (default), or exception encountered.\r\n            // Everything stored in var log instead of writing separate lines to support only writing in exception,\r\n            // and avoid problems with multiple concurrent .babylon loads.\r\n            let log = \"importMesh has failed JSON parse\";\r\n            try {\r\n                // eslint-disable-next-line no-var\r\n                var parsedData = JSON.parse(data);\r\n                log = \"\";\r\n                const fullDetails = SceneLoaderFlags.loggingLevel === Constants.SCENELOADER_DETAILED_LOGGING;\r\n                if (!meshesNames) {\r\n                    meshesNames = null;\r\n                } else if (!Array.isArray(meshesNames)) {\r\n                    meshesNames = [meshesNames];\r\n                }\r\n\r\n                const hierarchyIds: number[] = [];\r\n                const parsedIdToNodeMap = new Map<number, Node>();\r\n\r\n                // Transform nodes (the overall idea is to load all of them as this is super fast and then get rid of the ones we don't need)\r\n                const loadedTransformNodes = [];\r\n                if (parsedData.transformNodes !== undefined && parsedData.transformNodes !== null) {\r\n                    for (let index = 0, cache = parsedData.transformNodes.length; index < cache; index++) {\r\n                        const parsedJSONTransformNode = parsedData.transformNodes[index];\r\n                        const parsedTransformNode = TransformNode.Parse(parsedJSONTransformNode, scene, rootUrl);\r\n                        loadedTransformNodes.push(parsedTransformNode);\r\n                        parsedIdToNodeMap.set(parsedTransformNode._waitingParsedUniqueId!, parsedTransformNode);\r\n                        parsedTransformNode._waitingParsedUniqueId = null;\r\n                    }\r\n                }\r\n                if (parsedData.meshes !== undefined && parsedData.meshes !== null) {\r\n                    const loadedSkeletonsIds = [];\r\n                    const loadedMaterialsIds: string[] = [];\r\n                    const loadedMaterialsUniqueIds: string[] = [];\r\n                    const loadedMorphTargetManagerIds: number[] = [];\r\n                    for (let index = 0, cache = parsedData.meshes.length; index < cache; index++) {\r\n                        const parsedMesh = parsedData.meshes[index];\r\n\r\n                        if (meshesNames === null || IsDescendantOf(parsedMesh, meshesNames, hierarchyIds)) {\r\n                            if (meshesNames !== null) {\r\n                                // Remove found mesh name from list.\r\n                                delete meshesNames[meshesNames.indexOf(parsedMesh.name)];\r\n                            }\r\n\r\n                            //Geometry?\r\n                            if (parsedMesh.geometryId !== undefined && parsedMesh.geometryId !== null) {\r\n                                //does the file contain geometries?\r\n                                if (parsedData.geometries !== undefined && parsedData.geometries !== null) {\r\n                                    //find the correct geometry and add it to the scene\r\n                                    let found: boolean = false;\r\n                                    const geoms = [\"boxes\", \"spheres\", \"cylinders\", \"toruses\", \"grounds\", \"planes\", \"torusKnots\", \"vertexData\"];\r\n                                    for (const geometryType of geoms) {\r\n                                        if (!parsedData.geometries[geometryType] || !Array.isArray(parsedData.geometries[geometryType])) {\r\n                                            continue;\r\n                                        }\r\n                                        const geom = parsedData.geometries[geometryType];\r\n                                        for (const parsedGeometryData of geom) {\r\n                                            if (parsedGeometryData.id === parsedMesh.geometryId) {\r\n                                                switch (geometryType) {\r\n                                                    case \"vertexData\":\r\n                                                        Geometry.Parse(parsedGeometryData, scene, rootUrl);\r\n                                                        break;\r\n                                                }\r\n                                                found = true;\r\n                                                break;\r\n                                            }\r\n                                        }\r\n\r\n                                        if (found) {\r\n                                            break;\r\n                                        }\r\n                                    }\r\n                                    if (found === false) {\r\n                                        Logger.Warn(\"Geometry not found for mesh \" + parsedMesh.id);\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            // Material ?\r\n                            if (parsedMesh.materialUniqueId || parsedMesh.materialId) {\r\n                                // if we have a unique ID, look up and store in loadedMaterialsUniqueIds, else use loadedMaterialsIds\r\n                                const materialArray = parsedMesh.materialUniqueId ? loadedMaterialsUniqueIds : loadedMaterialsIds;\r\n                                let materialFound = materialArray.indexOf(parsedMesh.materialUniqueId || parsedMesh.materialId) !== -1;\r\n                                if (materialFound === false && parsedData.multiMaterials !== undefined && parsedData.multiMaterials !== null) {\r\n                                    // Loads a submaterial of a multimaterial\r\n                                    const loadSubMaterial = (subMatId: string, predicate: (parsedMaterial: any) => boolean) => {\r\n                                        materialArray.push(subMatId);\r\n                                        const mat = ParseMaterialByPredicate(predicate, parsedData, scene, rootUrl);\r\n                                        if (mat && mat.material) {\r\n                                            TempMaterialIndexContainer[mat.parsedMaterial.uniqueId || mat.parsedMaterial.id] = mat.material;\r\n                                            log += \"\\n\\tMaterial \" + mat.material.toString(fullDetails);\r\n                                        }\r\n                                    };\r\n                                    for (let multimatIndex = 0, multimatCache = parsedData.multiMaterials.length; multimatIndex < multimatCache; multimatIndex++) {\r\n                                        const parsedMultiMaterial = parsedData.multiMaterials[multimatIndex];\r\n                                        if (\r\n                                            (parsedMesh.materialUniqueId && parsedMultiMaterial.uniqueId === parsedMesh.materialUniqueId) ||\r\n                                            parsedMultiMaterial.id === parsedMesh.materialId\r\n                                        ) {\r\n                                            if (parsedMultiMaterial.materialsUniqueIds) {\r\n                                                // if the materials inside the multimat are stored by unique id\r\n                                                for (const subMatId of parsedMultiMaterial.materialsUniqueIds) {\r\n                                                    loadSubMaterial(subMatId, (parsedMaterial) => parsedMaterial.uniqueId === subMatId);\r\n                                                }\r\n                                            } else {\r\n                                                // if the mats are stored by id instead\r\n                                                for (const subMatId of parsedMultiMaterial.materials) {\r\n                                                    loadSubMaterial(subMatId, (parsedMaterial) => parsedMaterial.id === subMatId);\r\n                                                }\r\n                                            }\r\n                                            materialArray.push(parsedMultiMaterial.uniqueId || parsedMultiMaterial.id);\r\n                                            const mmat = MultiMaterial.ParseMultiMaterial(parsedMultiMaterial, scene);\r\n                                            TempMaterialIndexContainer[parsedMultiMaterial.uniqueId || parsedMultiMaterial.id] = mmat;\r\n                                            if (mmat) {\r\n                                                materialFound = true;\r\n                                                log += \"\\n\\tMulti-Material \" + mmat.toString(fullDetails);\r\n                                            }\r\n                                            break;\r\n                                        }\r\n                                    }\r\n                                }\r\n\r\n                                if (materialFound === false) {\r\n                                    materialArray.push(parsedMesh.materialUniqueId || parsedMesh.materialId);\r\n                                    const mat = ParseMaterialByPredicate(\r\n                                        (parsedMaterial) =>\r\n                                            (parsedMesh.materialUniqueId && parsedMaterial.uniqueId === parsedMesh.materialUniqueId) || parsedMaterial.id === parsedMesh.materialId,\r\n                                        parsedData,\r\n                                        scene,\r\n                                        rootUrl\r\n                                    );\r\n                                    if (!mat || !mat.material) {\r\n                                        Logger.Warn(\"Material not found for mesh \" + parsedMesh.id);\r\n                                    } else {\r\n                                        TempMaterialIndexContainer[mat.parsedMaterial.uniqueId || mat.parsedMaterial.id] = mat.material;\r\n                                        log += \"\\n\\tMaterial \" + mat.material.toString(fullDetails);\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            // Skeleton ?\r\n                            if (\r\n                                parsedMesh.skeletonId !== null &&\r\n                                parsedMesh.skeletonId !== undefined &&\r\n                                parsedData.skeletonId !== -1 &&\r\n                                parsedData.skeletons !== undefined &&\r\n                                parsedData.skeletons !== null\r\n                            ) {\r\n                                const skeletonAlreadyLoaded = loadedSkeletonsIds.indexOf(parsedMesh.skeletonId) > -1;\r\n                                if (!skeletonAlreadyLoaded) {\r\n                                    for (let skeletonIndex = 0, skeletonCache = parsedData.skeletons.length; skeletonIndex < skeletonCache; skeletonIndex++) {\r\n                                        const parsedSkeleton = parsedData.skeletons[skeletonIndex];\r\n                                        if (parsedSkeleton.id === parsedMesh.skeletonId) {\r\n                                            const skeleton = Skeleton.Parse(parsedSkeleton, scene);\r\n                                            loadedSkeletonsIds.push(parsedSkeleton.id);\r\n                                            if (parsedSkeleton.uniqueId !== undefined && parsedSkeleton.uniqueId !== null) {\r\n                                                TempSkeletonIndexContainer[parsedSkeleton.uniqueId] = skeleton;\r\n                                            }\r\n                                            skeletons.push(skeleton);\r\n                                            log += \"\\n\\tSkeleton \" + skeleton.toString(fullDetails);\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            // Morph target managers ?\r\n                            if (parsedMesh.morphTargetManagerId > -1 && parsedData.morphTargetManagers !== undefined && parsedData.morphTargetManagers !== null) {\r\n                                const morphTargetManagerAlreadyLoaded = loadedMorphTargetManagerIds.indexOf(parsedMesh.morphTargetManagerId) > -1;\r\n                                if (!morphTargetManagerAlreadyLoaded) {\r\n                                    for (let morphTargetManagerIndex = 0; morphTargetManagerIndex < parsedData.morphTargetManagers.length; morphTargetManagerIndex++) {\r\n                                        const parsedManager = parsedData.morphTargetManagers[morphTargetManagerIndex];\r\n                                        if (parsedManager.id === parsedMesh.morphTargetManagerId) {\r\n                                            const morphTargetManager = MorphTargetManager.Parse(parsedManager, scene);\r\n                                            TempMorphTargetManagerIndexContainer[parsedManager.id] = morphTargetManager;\r\n                                            loadedMorphTargetManagerIds.push(parsedManager.id);\r\n                                            log += \"\\nMorph target manager\" + morphTargetManager.toString();\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            const mesh = Mesh.Parse(parsedMesh, scene, rootUrl);\r\n                            meshes.push(mesh);\r\n                            parsedIdToNodeMap.set(mesh._waitingParsedUniqueId!, mesh);\r\n                            mesh._waitingParsedUniqueId = null;\r\n                            if (mesh.getClassName() === \"GaussianSplattingMesh\") {\r\n                                const partProxies = (mesh as any)._partProxies as AbstractMesh[] | Map<number, AbstractMesh> | undefined;\r\n                                const proxies = Array.isArray(partProxies) ? partProxies : partProxies ? Array.from(partProxies.values()) : [];\r\n                                for (const partProxy of proxies) {\r\n                                    if (!partProxy || partProxy._waitingParsedUniqueId == null) {\r\n                                        continue;\r\n                                    }\r\n                                    parsedIdToNodeMap.set(partProxy._waitingParsedUniqueId, partProxy);\r\n                                    partProxy._waitingParsedUniqueId = null;\r\n                                }\r\n                            }\r\n                            log += \"\\n\\tMesh \" + mesh.toString(fullDetails);\r\n                        }\r\n                    }\r\n\r\n                    // link multimats with materials\r\n                    for (const multimat of scene.multiMaterials) {\r\n                        for (const subMaterial of multimat._waitingSubMaterialsUniqueIds) {\r\n                            multimat.subMaterials.push(FindMaterial(subMaterial, scene));\r\n                        }\r\n                        multimat._waitingSubMaterialsUniqueIds = [];\r\n                    }\r\n\r\n                    // link meshes with materials\r\n                    for (const mesh of scene.meshes) {\r\n                        if (mesh._waitingMaterialId !== null) {\r\n                            mesh.material = FindMaterial(mesh._waitingMaterialId, scene);\r\n                            mesh._waitingMaterialId = null;\r\n                        }\r\n                    }\r\n\r\n                    // link meshes with morph target managers\r\n                    for (const mesh of scene.meshes) {\r\n                        if (mesh._waitingMorphTargetManagerId !== null) {\r\n                            mesh.morphTargetManager = TempMorphTargetManagerIndexContainer[mesh._waitingMorphTargetManagerId];\r\n                            mesh._waitingMorphTargetManagerId = null;\r\n                        }\r\n                    }\r\n\r\n                    // Connecting parents and lods\r\n                    for (let index = 0, cache = scene.transformNodes.length; index < cache; index++) {\r\n                        const transformNode = scene.transformNodes[index];\r\n                        if (transformNode._waitingParentId !== null) {\r\n                            let parent = parsedIdToNodeMap.get(parseInt(transformNode._waitingParentId)) || null;\r\n                            if (parent === null) {\r\n                                parent = scene.getLastEntryById(transformNode._waitingParentId);\r\n                            }\r\n                            let parentNode = parent;\r\n                            if (transformNode._waitingParentInstanceIndex) {\r\n                                parentNode = (parent as Mesh).instances[parseInt(transformNode._waitingParentInstanceIndex)];\r\n                                transformNode._waitingParentInstanceIndex = null;\r\n                            }\r\n                            transformNode.parent = parentNode;\r\n                            transformNode._waitingParentId = null;\r\n                        }\r\n                    }\r\n                    let currentMesh: AbstractMesh;\r\n                    for (let index = 0, cache = scene.meshes.length; index < cache; index++) {\r\n                        currentMesh = scene.meshes[index];\r\n                        if (currentMesh._waitingParentId) {\r\n                            let parent = parsedIdToNodeMap.get(parseInt(currentMesh._waitingParentId)) || null;\r\n                            if (parent === null) {\r\n                                parent = scene.getLastEntryById(currentMesh._waitingParentId);\r\n                            }\r\n                            let parentNode = parent;\r\n                            if (currentMesh._waitingParentInstanceIndex) {\r\n                                parentNode = (parent as Mesh).instances[parseInt(currentMesh._waitingParentInstanceIndex)];\r\n                                currentMesh._waitingParentInstanceIndex = null;\r\n                            }\r\n                            currentMesh.parent = parentNode;\r\n                            currentMesh._waitingParentId = null;\r\n                        }\r\n                        if (currentMesh._waitingData.lods) {\r\n                            LoadDetailLevels(scene, currentMesh);\r\n                        }\r\n                    }\r\n\r\n                    // Remove unused transform nodes\r\n                    for (const transformNode of loadedTransformNodes) {\r\n                        const childMeshes = transformNode.getChildMeshes(false);\r\n                        if (!childMeshes.length) {\r\n                            transformNode.dispose();\r\n                        }\r\n                    }\r\n\r\n                    // link meshes with skeletons\r\n                    for (const mesh of scene.meshes) {\r\n                        // First try to get it via uniqueId\r\n                        if (mesh._waitingSkeletonUniqueId !== null) {\r\n                            mesh.skeleton = TempSkeletonIndexContainer[mesh._waitingSkeletonUniqueId];\r\n                        }\r\n\r\n                        // If not possible or not found, try to get it from the scene (backwards compatibility)\r\n                        if (mesh._waitingSkeletonId !== null && !mesh.skeleton) {\r\n                            mesh.skeleton = scene.getLastSkeletonById(mesh._waitingSkeletonId);\r\n                        }\r\n\r\n                        mesh._waitingSkeletonId = null;\r\n                        mesh._waitingSkeletonUniqueId = null;\r\n                    }\r\n\r\n                    // link bones to transform nodes\r\n                    for (let index = 0, cache = scene.skeletons.length; index < cache; index++) {\r\n                        const skeleton = scene.skeletons[index];\r\n                        if (skeleton._hasWaitingData) {\r\n                            if (skeleton.bones != null) {\r\n                                for (const bone of skeleton.bones) {\r\n                                    let linkTransformNode: Nullable<Node> = null;\r\n                                    // First try to get it via uniqueId\r\n                                    if (bone._waitingTransformNodeUniqueId !== null) {\r\n                                        linkTransformNode = parsedIdToNodeMap.get(bone._waitingTransformNodeUniqueId) ?? null;\r\n                                    }\r\n\r\n                                    // If not possible or not found, try to get it from the scene (backwards compatibility)\r\n                                    if (bone._waitingTransformNodeId !== null && !linkTransformNode) {\r\n                                        linkTransformNode = scene.getLastEntryById(bone._waitingTransformNodeId);\r\n                                    }\r\n\r\n                                    if (linkTransformNode) {\r\n                                        bone.linkTransformNode(linkTransformNode as TransformNode);\r\n                                    }\r\n\r\n                                    bone._waitingTransformNodeId = null;\r\n                                    bone._waitingTransformNodeUniqueId = null;\r\n                                }\r\n                            }\r\n\r\n                            skeleton._hasWaitingData = null;\r\n                        }\r\n                    }\r\n\r\n                    // freeze and compute world matrix application\r\n                    for (let index = 0, cache = scene.transformNodes.length; index < cache; index++) {\r\n                        const currentTransformNode = scene.transformNodes[index];\r\n                        if (currentTransformNode._waitingFreezeWorldMatrix) {\r\n                            currentTransformNode.freezeWorldMatrix();\r\n                            currentTransformNode._waitingFreezeWorldMatrix = null;\r\n                        }\r\n                    }\r\n                    for (let index = 0, cache = scene.meshes.length; index < cache; index++) {\r\n                        currentMesh = scene.meshes[index];\r\n                        if (currentMesh._waitingData.freezeWorldMatrix) {\r\n                            currentMesh.freezeWorldMatrix();\r\n                            currentMesh._waitingData.freezeWorldMatrix = null;\r\n                        } else {\r\n                            currentMesh.computeWorldMatrix(true);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Particles\r\n                if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {\r\n                    const parser = GetIndividualParser(SceneComponentConstants.NAME_PARTICLESYSTEM);\r\n                    if (parser) {\r\n                        for (let index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {\r\n                            const parsedParticleSystem = parsedData.particleSystems[index];\r\n                            if (hierarchyIds.indexOf(parsedParticleSystem.emitterId) !== -1) {\r\n                                particleSystems.push(parser(parsedParticleSystem, scene, rootUrl));\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                for (const g of scene.geometries) {\r\n                    g._loadedUniqueId = \"\";\r\n                }\r\n\r\n                return true;\r\n            } catch (err) {\r\n                const msg = logOperation(\"importMesh\", parsedData ? parsedData.producer : \"Unknown\") + log;\r\n                if (onError) {\r\n                    onError(msg, err);\r\n                } else {\r\n                    Logger.Log(msg);\r\n                    throw err;\r\n                }\r\n            } finally {\r\n                if (log !== null && SceneLoaderFlags.loggingLevel !== Constants.SCENELOADER_NO_LOGGING) {\r\n                    Logger.Log(\r\n                        logOperation(\"importMesh\", parsedData ? parsedData.producer : \"Unknown\") +\r\n                            (SceneLoaderFlags.loggingLevel !== Constants.SCENELOADER_MINIMAL_LOGGING ? log : \"\")\r\n                    );\r\n                }\r\n                TempMaterialIndexContainer = {};\r\n                TempMorphTargetManagerIndexContainer = {};\r\n                TempSkeletonIndexContainer = {};\r\n            }\r\n\r\n            return false;\r\n        },\r\n        load: (scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): boolean => {\r\n            // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details\r\n            // when SceneLoader.debugLogging = true (default), or exception encountered.\r\n            // Everything stored in var log instead of writing separate lines to support only writing in exception,\r\n            // and avoid problems with multiple concurrent .babylon loads.\r\n            let log = \"importScene has failed JSON parse\";\r\n            try {\r\n                // eslint-disable-next-line no-var\r\n                var parsedData = JSON.parse(data);\r\n                log = \"\";\r\n\r\n                // Scene\r\n                if (parsedData.useDelayedTextureLoading !== undefined && parsedData.useDelayedTextureLoading !== null) {\r\n                    scene.useDelayedTextureLoading = parsedData.useDelayedTextureLoading && !SceneLoaderFlags.ForceFullSceneLoadingForIncremental;\r\n                }\r\n                if (parsedData.autoClear !== undefined && parsedData.autoClear !== null) {\r\n                    scene.autoClear = parsedData.autoClear;\r\n                }\r\n                if (parsedData.clearColor !== undefined && parsedData.clearColor !== null) {\r\n                    scene.clearColor = Color4.FromArray(parsedData.clearColor);\r\n                }\r\n                if (parsedData.ambientColor !== undefined && parsedData.ambientColor !== null) {\r\n                    scene.ambientColor = Color3.FromArray(parsedData.ambientColor);\r\n                }\r\n                if (parsedData.gravity !== undefined && parsedData.gravity !== null) {\r\n                    scene.gravity = Vector3.FromArray(parsedData.gravity);\r\n                }\r\n\r\n                if (parsedData.useRightHandedSystem !== undefined) {\r\n                    scene.useRightHandedSystem = !!parsedData.useRightHandedSystem;\r\n                }\r\n\r\n                // Fog\r\n                if (parsedData.fogMode !== undefined && parsedData.fogMode !== null) {\r\n                    scene.fogMode = parsedData.fogMode;\r\n                }\r\n                if (parsedData.fogColor !== undefined && parsedData.fogColor !== null) {\r\n                    scene.fogColor = Color3.FromArray(parsedData.fogColor);\r\n                }\r\n                if (parsedData.fogStart !== undefined && parsedData.fogStart !== null) {\r\n                    scene.fogStart = parsedData.fogStart;\r\n                }\r\n                if (parsedData.fogEnd !== undefined && parsedData.fogEnd !== null) {\r\n                    scene.fogEnd = parsedData.fogEnd;\r\n                }\r\n                if (parsedData.fogDensity !== undefined && parsedData.fogDensity !== null) {\r\n                    scene.fogDensity = parsedData.fogDensity;\r\n                }\r\n                log += \"\\tFog mode for scene:  \";\r\n                switch (scene.fogMode) {\r\n                    case 0:\r\n                        log += \"none\\n\";\r\n                        break;\r\n                    // getters not compiling, so using hardcoded\r\n                    case 1:\r\n                        log += \"exp\\n\";\r\n                        break;\r\n                    case 2:\r\n                        log += \"exp2\\n\";\r\n                        break;\r\n                    case 3:\r\n                        log += \"linear\\n\";\r\n                        break;\r\n                }\r\n\r\n                //Physics\r\n                if (parsedData.physicsEnabled) {\r\n                    let physicsPlugin;\r\n                    if (parsedData.physicsEngine === \"cannon\" || parsedData.physicsEngine === CannonJSPlugin.name) {\r\n                        physicsPlugin = new CannonJSPlugin(undefined, undefined, BabylonFileLoaderConfiguration.LoaderInjectedPhysicsEngine);\r\n                    } else if (parsedData.physicsEngine === \"oimo\" || parsedData.physicsEngine === OimoJSPlugin.name) {\r\n                        physicsPlugin = new OimoJSPlugin(undefined, BabylonFileLoaderConfiguration.LoaderInjectedPhysicsEngine);\r\n                    } else if (parsedData.physicsEngine === \"ammo\" || parsedData.physicsEngine === AmmoJSPlugin.name) {\r\n                        physicsPlugin = new AmmoJSPlugin(undefined, BabylonFileLoaderConfiguration.LoaderInjectedPhysicsEngine, undefined);\r\n                    }\r\n                    log = \"\\tPhysics engine \" + (parsedData.physicsEngine ? parsedData.physicsEngine : \"oimo\") + \" enabled\\n\";\r\n                    //else - default engine, which is currently oimo\r\n                    const physicsGravity = parsedData.gravity\r\n                        ? Vector3.FromArray(parsedData.gravity)\r\n                        : parsedData.physicsGravity\r\n                          ? Vector3.FromArray(parsedData.physicsGravity)\r\n                          : null;\r\n                    scene.enablePhysics(physicsGravity, physicsPlugin);\r\n                }\r\n\r\n                // Metadata\r\n                if (parsedData.metadata !== undefined && parsedData.metadata !== null) {\r\n                    scene.metadata = parsedData.metadata;\r\n                }\r\n\r\n                //collisions, if defined. otherwise, default is true\r\n                if (parsedData.collisionsEnabled !== undefined && parsedData.collisionsEnabled !== null) {\r\n                    scene.collisionsEnabled = parsedData.collisionsEnabled;\r\n                }\r\n\r\n                const container = LoadAssetContainer(scene, data, rootUrl, onError, true);\r\n                if (!container) {\r\n                    return false;\r\n                }\r\n\r\n                if (parsedData.autoAnimate) {\r\n                    scene.beginAnimation(scene, parsedData.autoAnimateFrom, parsedData.autoAnimateTo, parsedData.autoAnimateLoop, parsedData.autoAnimateSpeed || 1.0);\r\n                }\r\n\r\n                if (parsedData.activeCameraID !== undefined && parsedData.activeCameraID !== null) {\r\n                    scene.setActiveCameraById(parsedData.activeCameraID);\r\n                }\r\n\r\n                // If no active camera has been resolved (e.g. the serialized activeCameraID\r\n                // does not match any loaded camera) but the scene does contain cameras,\r\n                // fall back to the first one so the scene can still be rendered.\r\n                if (!scene.activeCamera && scene.cameras.length > 0) {\r\n                    scene.activeCamera = scene.cameras[0];\r\n                }\r\n\r\n                // Finish\r\n                return true;\r\n            } catch (err) {\r\n                const msg = logOperation(\"importScene\", parsedData ? parsedData.producer : \"Unknown\") + log;\r\n                if (onError) {\r\n                    onError(msg, err);\r\n                } else {\r\n                    Logger.Log(msg);\r\n                    throw err;\r\n                }\r\n            } finally {\r\n                if (log !== null && SceneLoaderFlags.loggingLevel !== Constants.SCENELOADER_NO_LOGGING) {\r\n                    Logger.Log(\r\n                        logOperation(\"importScene\", parsedData ? parsedData.producer : \"Unknown\") +\r\n                            (SceneLoaderFlags.loggingLevel !== Constants.SCENELOADER_MINIMAL_LOGGING ? log : \"\")\r\n                    );\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n        loadAssetContainer: (scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): AssetContainer => {\r\n            const container = LoadAssetContainer(scene, data, rootUrl, onError);\r\n            return container;\r\n        },\r\n    });\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nconst name = \"backgroundUboDeclaration\";\nconst shader = `uniform vPrimaryColor: vec4f;uniform vPrimaryColorShadow: vec4f;uniform vDiffuseInfos : vec2f;uniform diffuseMatrix : mat4x4f;uniform fFovMultiplier: f32;uniform pointSize: f32;uniform shadowLevel: f32;uniform alpha: f32;uniform vBackgroundCenter: vec3f;uniform vReflectionControl: vec4f;uniform projectedGroundInfos: vec2f;uniform vReflectionInfos : vec2f;uniform reflectionMatrix : mat4x4f;uniform vReflectionMicrosurfaceInfos : vec3f;\n#include<sceneUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const backgroundUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogVertexDeclaration\";\nconst shader = `#ifdef FOG\nvarying vFogDistance: vec3f;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const fogVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightVxUboDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nstruct Light{X}\n{vLightData: vec4f,\nvLightDiffuse: vec4f,\nvLightSpecular: vec4f,\n#ifdef SPOTLIGHT{X}\nvLightDirection: vec4f,\nvLightFalloff: vec4f,\n#elif defined(POINTLIGHT{X})\nvLightFalloff: vec4f,\n#elif defined(HEMILIGHT{X})\nvLightGround: vec3f,\n#elif defined(CLUSTLIGHT{X})\nvSliceData: vec2f,\nvSliceRanges: array<vec4f,CLUSTLIGHT_SLICES>,\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvLightWidth: vec4f,\nvLightHeight: vec4f,\n#endif\nshadowsInfo: vec4f,\ndepthValues: vec2f} ;var<uniform> light{X} : Light{X};\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform lightMatrix{X}: array<mat4x4f,SHADOWCSMNUM_CASCADES{X}>;varying vPositionFromLight{X}_0: vec4f;varying vDepthMetric{X}_0: f32;varying vPositionFromLight{X}_1: vec4f;varying vDepthMetric{X}_1: f32;varying vPositionFromLight{X}_2: vec4f;varying vDepthMetric{X}_2: f32;varying vPositionFromLight{X}_3: vec4f;varying vDepthMetric{X}_3: f32;varying vPositionFromCamera{X}: vec4f;\n#elif defined(SHADOWCUBE{X})\n#else\nvarying vPositionFromLight{X}: vec4f;varying vDepthMetric{X}: f32;uniform lightMatrix{X}: mat4x4f;\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const lightVxUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"logDepthDeclaration\";\nconst shader = `#ifdef LOGARITHMICDEPTH\nuniform logarithmicDepthConstant: f32;varying vFragmentDepth: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const logDepthDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogVertex\";\nconst shader = `#ifdef FOG\n#ifdef SCENE_UBO\nvertexOutputs.vFogDistance=(scene.view*worldPos).xyz;\n#else\nvertexOutputs.vFogDistance=(uniforms.view*worldPos).xyz;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const fogVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowsVertex\";\nconst shader = `#ifdef SHADOWS\n#if defined(SHADOWCSM{X})\n#ifdef SCENE_UBO\nvertexOutputs.vPositionFromCamera{X}=scene.view*worldPos;\n#else\nvertexOutputs.vPositionFromCamera{X}=uniforms.view*worldPos;\n#endif\n#if SHADOWCSMNUM_CASCADES{X}>0\nvertexOutputs.vPositionFromLight{X}_0=uniforms.lightMatrix{X}[0]*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric{X}_0=(-vertexOutputs.vPositionFromLight{X}_0.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvertexOutputs.vDepthMetric{X}_0= (vertexOutputs.vPositionFromLight{X}_0.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n#endif\n#if SHADOWCSMNUM_CASCADES{X}>1\nvertexOutputs.vPositionFromLight{X}_1=uniforms.lightMatrix{X}[1]*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric{X}_1=(-vertexOutputs.vPositionFromLight{X}_1.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvertexOutputs.vDepthMetric{X}_1= (vertexOutputs.vPositionFromLight{X}_1.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n#endif \n#if SHADOWCSMNUM_CASCADES{X}>2\nvertexOutputs.vPositionFromLight{X}_2=uniforms.lightMatrix{X}[2]*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric{X}_2=(-vertexOutputs.vPositionFromLight{X}_2.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvertexOutputs.vDepthMetric{X}_2= (vertexOutputs.vPositionFromLight{X}_2.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n#endif \n#if SHADOWCSMNUM_CASCADES{X}>3\nvertexOutputs.vPositionFromLight{X}_3=uniforms.lightMatrix{X}[3]*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric{X}_3=(-vertexOutputs.vPositionFromLight{X}_3.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvertexOutputs.vDepthMetric{X}_3= (vertexOutputs.vPositionFromLight{X}_3.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n#endif \n#elif defined(SHADOW{X}) && !defined(SHADOWCUBE{X})\nvertexOutputs.vPositionFromLight{X}=uniforms.lightMatrix{X}*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric{X}=(-vertexOutputs.vPositionFromLight{X}.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvertexOutputs.vDepthMetric{X}=(vertexOutputs.vPositionFromLight{X}.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowsVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"logDepthVertex\";\nconst shader = `#ifdef LOGARITHMICDEPTH\nvertexOutputs.vFragmentDepth=1.0+vertexOutputs.position.w;vertexOutputs.position.z=log2(max(0.000001,vertexOutputs.vFragmentDepth))*uniforms.logarithmicDepthConstant;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const logDepthVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { backgroundUboDeclarationWGSL } from \"./ShadersInclude/backgroundUboDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxUboDeclarationWGSL } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertexWGSL } from \"./ShadersInclude/shadowsVertex\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"backgroundVertexShader\";\nconst shader = `#include<backgroundUboDeclaration>\n#include<helperFunctions>\nattribute position: vec3f;\n#ifdef NORMAL\nattribute normal: vec3f;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\nvarying vPositionW: vec3f;\n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#endif\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#ifdef MAINUV1\nvarying vMainUV1: vec2f;\n#endif\n#ifdef MAINUV2\nvarying vMainUV2: vec2f;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV==0\nvarying vDiffuseUV: vec2f;\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<lightVxUboDeclaration>[0..maxSimultaneousLights]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef REFLECTIONMAP_SKYBOX\nvertexOutputs.vPositionUVW=vertexInputs.position;\n#endif\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {vertexOutputs.position=scene.viewProjection*finalWorld* vec4f(vertexInputs.position,1.0);} else {vertexOutputs.position=scene.viewProjectionR*finalWorld* vec4f(vertexInputs.position,1.0);}\n#else\nvertexOutputs.position=scene.viewProjection*finalWorld* vec4f(vertexInputs.position,1.0);\n#endif\nvar worldPos: vec4f=finalWorld* vec4f(vertexInputs.position,1.0);vertexOutputs.vPositionW= worldPos.xyz;\n#ifdef NORMAL\nvar normalWorld: mat3x3f=mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvertexOutputs.vNormalW=normalize(normalWorld*vertexInputs.normal);\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvertexOutputs.vDirectionW=normalize((finalWorld*vec4f(vertexInputs.position,0.0)).xyz);\n#ifdef EQUIRECTANGULAR_RELFECTION_FOV\nvar screenToWorld: mat3x3f=inverseMat3( mat3x3f(finalWorld*scene.viewProjection));var segment: vec3f=mix(vertexOutputs.vDirectionW,screenToWorld* vec3f(0.0,0.0,1.0),abs(fFovMultiplier-1.0));if (fFovMultiplier<=1.0) {vertexOutputs.vDirectionW=normalize(segment);} else {vertexOutputs.vDirectionW=normalize(vertexOutputs.vDirectionW+(vertexOutputs.vDirectionW-segment));}\n#endif\n#endif\n#ifndef UV1\nvar uv: vec2f=vec2f(0.,0.);\n#else\nvar uv=vertexInputs.uv;\n#endif\n#ifndef UV2\nvar uv2: vec2f=vec2f(0.,0.);\n#else\nvar uv2=vertexInputs.uv2;\n#endif\n#ifdef MAINUV1\nvertexOutputs.vMainUV1=uv;\n#endif\n#ifdef MAINUV2\nvertexOutputs.vMainUV2=uv2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV==0\nif (uniforms.vDiffuseInfos.x==0.)\n{vertexOutputs.vDiffuseUV= (uniforms.diffuseMatrix* vec4f(uv,1.0,0.0)).xy;}\nelse\n{vertexOutputs.vDiffuseUV= (uniforms.diffuseMatrix* vec4f(uv2,1.0,0.0)).xy;}\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#ifdef VERTEXCOLOR\nvertexOutputs.vColor=vertexInputs.color;\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, backgroundUboDeclarationWGSL, helperFunctionsWGSL, bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, instancesDeclarationWGSL, clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, lightVxUboDeclarationWGSL, logDepthDeclarationWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL, fogVertexWGSL, shadowsVertexWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const backgroundVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"reflectionFunction\";\nconst shader = `fn computeFixedEquirectangularCoords(worldPos: vec4f,worldNormal: vec3f,direction: vec3f)->vec3f\n{var lon: f32=atan2(direction.z,direction.x);var lat: f32=acos(direction.y);var sphereCoords: vec2f= vec2f(lon,lat)*RECIPROCAL_PI2*2.0;var s: f32=sphereCoords.x*0.5+0.5;var t: f32=sphereCoords.y;return vec3f(s,t,0); }\nfn computeMirroredFixedEquirectangularCoords(worldPos: vec4f,worldNormal: vec3f,direction: vec3f)->vec3f\n{var lon: f32=atan2(direction.z,direction.x);var lat: f32=acos(direction.y);var sphereCoords: vec2f= vec2f(lon,lat)*RECIPROCAL_PI2*2.0;var s: f32=sphereCoords.x*0.5+0.5;var t: f32=sphereCoords.y;return vec3f(1.0-s,t,0); }\nfn computeEquirectangularCoords(worldPos: vec4f,worldNormal: vec3f,eyePosition: vec3f,reflectionMatrix: mat4x4f)->vec3f\n{var cameraToVertex: vec3f=normalize(worldPos.xyz-eyePosition);var r: vec3f=normalize(reflect(cameraToVertex,worldNormal));r= (reflectionMatrix* vec4f(r,0)).xyz;var lon: f32=atan2(r.z,r.x);var lat: f32=acos(r.y);var sphereCoords: vec2f= vec2f(lon,lat)*RECIPROCAL_PI2*2.0;var s: f32=sphereCoords.x*0.5+0.5;var t: f32=sphereCoords.y;return vec3f(s,t,0);}\nfn computeSphericalCoords(worldPos: vec4f,worldNormal: vec3f,view: mat4x4f,reflectionMatrix: mat4x4f)->vec3f\n{var viewDir: vec3f=normalize((view*worldPos).xyz);var viewNormal: vec3f=normalize((view* vec4f(worldNormal,0.0)).xyz);var r: vec3f=reflect(viewDir,viewNormal);r= (reflectionMatrix* vec4f(r,0)).xyz;r.z=r.z-1.0;var m: f32=2.0*length(r);return vec3f(r.x/m+0.5,1.0-r.y/m-0.5,0);}\nfn computePlanarCoords(worldPos: vec4f,worldNormal: vec3f,eyePosition: vec3f,reflectionMatrix: mat4x4f)->vec3f\n{var viewDir: vec3f=worldPos.xyz-eyePosition;var coords: vec3f=normalize(reflect(viewDir,worldNormal));return (reflectionMatrix* vec4f(coords,1)).xyz;}\nfn computeCubicCoords(worldPos: vec4f,worldNormal: vec3f,eyePosition: vec3f,reflectionMatrix: mat4x4f)->vec3f\n{var viewDir: vec3f=normalize(worldPos.xyz-eyePosition);var coords: vec3f=reflect(viewDir,worldNormal);coords= (reflectionMatrix* vec4f(coords,0)).xyz;\n#ifdef INVERTCUBICMAP\ncoords.y*=-1.0;\n#endif\nreturn coords;}\nfn computeCubicLocalCoords(worldPos: vec4f,worldNormal: vec3f,eyePosition: vec3f,reflectionMatrix: mat4x4f,reflectionSize: vec3f,reflectionPosition: vec3f)->vec3f\n{var viewDir: vec3f=normalize(worldPos.xyz-eyePosition);var coords: vec3f=reflect(viewDir,worldNormal);coords=parallaxCorrectNormal(worldPos.xyz,coords,reflectionSize,reflectionPosition);coords=(reflectionMatrix* vec4f(coords,0)).xyz;\n#ifdef INVERTCUBICMAP\ncoords.y*=-1.0;\n#endif\nreturn coords;}\nfn computeProjectionCoords(worldPos: vec4f,view: mat4x4f,reflectionMatrix: mat4x4f)->vec3f\n{return (reflectionMatrix*(view*worldPos)).xyz;}\nfn computeSkyBoxCoords(positionW: vec3f,reflectionMatrix: mat4x4f)->vec3f\n{return (reflectionMatrix* vec4f(positionW,1.)).xyz;}\n#ifdef REFLECTION\nfn computeReflectionCoords(worldPos: vec4f,worldNormal: vec3f)->vec3f\n{\n#ifdef REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED\nvar direction: vec3f=normalize(fragmentInputs.vDirectionW);return computeMirroredFixedEquirectangularCoords(worldPos,worldNormal,direction);\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED\nvar direction: vec3f=normalize(fragmentInputs.vDirectionW);return computeFixedEquirectangularCoords(worldPos,worldNormal,direction);\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR\nreturn computeEquirectangularCoords(worldPos,worldNormal,scene.vEyePosition.xyz,uniforms.reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_SPHERICAL\nreturn computeSphericalCoords(worldPos,worldNormal,scene.view,uniforms.reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_PLANAR\nreturn computePlanarCoords(worldPos,worldNormal,scene.vEyePosition.xyz,uniforms.reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_CUBIC\n#ifdef USE_LOCAL_REFLECTIONMAP_CUBIC\nreturn computeCubicLocalCoords(worldPos,worldNormal,scene.vEyePosition.xyz,uniforms.reflectionMatrix,uniforms.vReflectionSize,uniforms.vReflectionPosition);\n#else\nreturn computeCubicCoords(worldPos,worldNormal,scene.vEyePosition.xyz,uniforms.reflectionMatrix);\n#endif\n#endif\n#ifdef REFLECTIONMAP_PROJECTION\nreturn computeProjectionCoords(worldPos,scene.view,uniforms.reflectionMatrix);\n#endif\n#ifndef REFLECTIONMAP_CUBIC\n#ifdef REFLECTIONMAP_SKYBOX\nreturn computeSkyBoxCoords(fragmentInputs.vPositionUVW,uniforms.reflectionMatrix);\n#endif\n#endif\n#ifdef REFLECTIONMAP_EXPLICIT\nreturn vec3f(0,0,0);\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const reflectionFunctionWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"imageProcessingDeclaration\";\nconst shader = `#ifdef EXPOSURE\nuniform exposureLinear: f32;\n#endif\n#ifdef CONTRAST\nuniform contrast: f32;\n#endif\n#ifdef WHITEBALANCE\nuniform whiteBalanceMatrix: mat3x3f;\n#endif\n#if defined(VIGNETTE) || defined(DITHER)\nuniform vInverseScreenSize: vec2f;\n#endif\n#ifdef VIGNETTE\nuniform vignetteSettings1: vec4f;uniform vignetteSettings2: vec4f;\n#endif\n#ifdef COLORCURVES\nuniform vCameraColorCurveNegative: vec4f;uniform vCameraColorCurveNeutral: vec4f;uniform vCameraColorCurvePositive: vec4f;\n#endif\n#ifdef COLORGRADING\n#ifdef COLORGRADING3D\nvar txColorTransformSampler: sampler;var txColorTransform: texture_3d<f32>;\n#else\nvar txColorTransformSampler: sampler;var txColorTransform: texture_2d<f32>;\n#endif\nuniform colorTransformSettings: vec4f;\n#endif\n#ifdef DITHER\nuniform ditherIntensity: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const imageProcessingDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightUboDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nstruct Light{X}\n{vLightData: vec4f,\nvLightDiffuse: vec4f,\nvLightSpecular: vec4f,\n#ifdef SPOTLIGHT{X}\nvLightDirection: vec4f,\nvLightFalloff: vec4f,\n#elif defined(POINTLIGHT{X})\nvLightFalloff: vec4f,\n#elif defined(HEMILIGHT{X})\nvLightGround: vec3f,\n#elif defined(CLUSTLIGHT{X})\nvSliceData: vec2f,\nvSliceRanges: array<vec4f,CLUSTLIGHT_SLICES>,\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvLightWidth: vec4f,\nvLightHeight: vec4f,\n#endif\nshadowsInfo: vec4f,\ndepthValues: vec2f} ;var<uniform> light{X} : Light{X};\n#ifdef IESLIGHTTEXTURE{X}\nvar iesLightTexture{X}Sampler: sampler;var iesLightTexture{X}: texture_2d<f32>;\n#endif\n#ifdef RECTAREALIGHTEMISSIONTEXTURE{X}\nvar rectAreaLightEmissionTexture{X}Sampler: sampler;var rectAreaLightEmissionTexture{X}: texture_2d<f32>;\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nuniform textureProjectionMatrix{X}: mat4x4f;var projectionLightTexture{X}Sampler: sampler;var projectionLightTexture{X}: texture_2d<f32>;\n#endif\n#ifdef CLUSTLIGHT{X}\nvar lightDataTexture{X}: texture_2d<f32>;var<storage,read> tileMaskBuffer{X}: array<u32>;\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform lightMatrix{X}: array<mat4x4f,SHADOWCSMNUM_CASCADES{X}>;uniform viewFrustumZ{X}: array<f32,SHADOWCSMNUM_CASCADES{X}>;uniform frustumLengths{X}: array<f32,SHADOWCSMNUM_CASCADES{X}>;uniform cascadeBlendFactor{X}: f32;varying vPositionFromLight{X}_0: vec4f;varying vDepthMetric{X}_0: f32;varying vPositionFromLight{X}_1: vec4f;varying vDepthMetric{X}_1: f32;varying vPositionFromLight{X}_2: vec4f;varying vDepthMetric{X}_2: f32;varying vPositionFromLight{X}_3: vec4f;varying vDepthMetric{X}_3: f32;varying vPositionFromCamera{X}: vec4f;var<private> vPositionFromLight{X}: array<vec4f,4>;var<private> vDepthMetric{X} : array<f32,4>;\n#if defined(SHADOWPCSS{X})\nvar shadowTexture{X}Sampler: sampler_comparison; \nvar shadowTexture{X}: texture_depth_2d_array;var depthTexture{X}Sampler: sampler;var depthTexture{X}: texture_2d_array<f32>;uniform lightSizeUVCorrection{X}: array<vec2f,SHADOWCSMNUM_CASCADES{X}>;uniform depthCorrection{X}: array<f32,SHADOWCSMNUM_CASCADES{X}>;uniform penumbraDarkness{X}: f32;\n#elif defined(SHADOWPCF{X})\nvar shadowTexture{X}Sampler: sampler_comparison;var shadowTexture{X}: texture_depth_2d_array;\n#else \nvar shadowTexture{X}Sampler: sampler; \nvar shadowTexture{X}: texture_2d_array<f32>;\n#endif\n#ifdef SHADOWCSMDEBUG{X}\nconst vCascadeColorsMultiplier{X}: array<vec3f,8>=array<vec3f,8>\n(\nvec3f ( 1.5,0.0,0.0 ),\nvec3f ( 0.0,1.5,0.0 ),\nvec3f ( 0.0,0.0,5.5 ),\nvec3f ( 1.5,0.0,5.5 ),\nvec3f ( 1.5,1.5,0.0 ),\nvec3f ( 1.0,1.0,1.0 ),\nvec3f ( 0.0,1.0,5.5 ),\nvec3f ( 0.5,3.5,0.75 )\n);\n#endif\n#elif defined(SHADOWCUBE{X})\nvar shadowTexture{X}Sampler: sampler;var shadowTexture{X}: texture_cube<f32>;\n#else\nvarying vPositionFromLight{X}: vec4f;varying vDepthMetric{X}: f32;\n#if defined(SHADOWPCSS{X})\nvar shadowTexture{X}Sampler: sampler_comparison; \nvar shadowTexture{X}: texture_depth_2d;var depthTexture{X}Sampler: sampler; \nvar depthTexture{X}: texture_2d<f32>;\n#elif defined(SHADOWPCF{X})\nvar shadowTexture{X}Sampler: sampler_comparison;var shadowTexture{X}: texture_depth_2d;\n#else\nvar shadowTexture{X}Sampler: sampler; \nvar shadowTexture{X}: texture_2d<f32>;\n#endif\nuniform lightMatrix{X}: mat4x4f;\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const lightUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"ltcHelperFunctions\";\nconst shader = `fn LTCUv(N: vec3f,V: vec3f,roughness: f32)->vec2f {var LUTSIZE: f32=64.0;var LUTSCALE: f32=( LUTSIZE-1.0 )/LUTSIZE;var LUTBIAS:f32=0.5/LUTSIZE;var dotNV:f32=saturate( dot( N,V ) );var uv:vec2f=vec2f( roughness,sqrt( 1.0-dotNV ) );uv=uv*LUTSCALE+LUTBIAS;return uv;}\nfn LTCClippedSphereFormFactor( f:vec3f )->f32 {var l: f32=length( f );return max( ( l*l+f.z )/( l+1.0 ),0.0 );}\nfn LTCEdgeVectorFormFactor( v1:vec3f,v2:vec3f )->vec3f {var x:f32=dot( v1,v2 );var y:f32=abs( x );var a:f32=0.8543985+( 0.4965155+0.0145206*y )*y;var b:f32=3.4175940+( 4.1616724+y )*y;var v:f32=a/b;var thetaSintheta:f32=0.0;if( x>0.0 )\n{thetaSintheta=v;}\nelse\n{thetaSintheta=0.5*inverseSqrt( max( 1.0-x*x,0.00000001 ) )-v;}\nreturn cross( v1,v2 )*thetaSintheta;}\nfn LTCEvaluate( N:vec3f,V:vec3f,P:vec3f,mInv: mat3x3<f32>,rectCoords0:vec3f,rectCoords1:vec3f,rectCoords2:vec3f,rectCoords3:vec3f )->vec3f {var v1:vec3f=rectCoords1-rectCoords0;var v2:vec3f=rectCoords3-rectCoords0;var lightNormal:vec3f=cross( v1,v2 );if( dot( lightNormal,P-rectCoords0 )<0.0 ){return vec3f( 0.0 );}\nvar T1:vec3f=normalize( V-N*dot( V,N ) );var T2:vec3f=- cross( N,T1 ); \nvar mat: mat3x3<f32>=mInv*transposeMat3( mat3x3<f32>( T1,T2,N ) );var coords0: vec3f=mat*( rectCoords0-P );var coords1: vec3f=mat*( rectCoords1-P );var coords2: vec3f=mat*( rectCoords2-P );var coords3: vec3f=mat*( rectCoords3-P );coords0=normalize( coords0 );coords1=normalize( coords1 );coords2=normalize( coords2 );coords3=normalize( coords3 );var vectorFormFactor:vec3f=vec3( 0.0 );vectorFormFactor+=LTCEdgeVectorFormFactor( coords0,coords1 );vectorFormFactor+=LTCEdgeVectorFormFactor( coords1,coords2 );vectorFormFactor+=LTCEdgeVectorFormFactor( coords2,coords3 );vectorFormFactor+=LTCEdgeVectorFormFactor( coords3,coords0 );var result:f32=LTCClippedSphereFormFactor( vectorFormFactor );return vec3f( result );}\nstruct areaLightData\n{Diffuse: vec3f,\nSpecular: vec3f,\nFresnel: vec4f};fn computeAreaLightSpecularDiffuseFresnel(ltc1: texture_2d<f32>,ltc1Sampler:sampler,ltc2:texture_2d<f32>,ltc2Sampler:sampler,viewDir: vec3f,normal:vec3f,position:vec3f,lightPos:vec3f,halfWidth:vec3f, halfHeight:vec3f,roughness:f32)->areaLightData {var result: areaLightData;var rectCoords0:vec3f=lightPos+halfWidth-halfHeight; \nvar rectCoords1:vec3f=lightPos-halfWidth-halfHeight;var rectCoords2:vec3f=lightPos-halfWidth+halfHeight;var rectCoords3:vec3f=lightPos+halfWidth+halfHeight;\n#ifdef SPECULARTERM\nvar uv:vec2f=LTCUv( normal,viewDir,roughness );var t1:vec4f=textureSample( ltc1,ltc1Sampler,uv );var t2:vec4f=textureSample( ltc2,ltc2Sampler,uv );var mInv:mat3x3<f32>=mat3x3<f32>(\nvec3f( t1.x,0,t1.y ),\nvec3f( 0,1, 0 ),\nvec3f( t1.z,0,t1.w )\n);result.Fresnel=t2;result.Specular=LTCEvaluate( normal,viewDir,position,mInv,rectCoords0,rectCoords1,rectCoords2,rectCoords3 );\n#endif\nvar mInvEmpty:mat3x3<f32>=mat3x3<f32>(\nvec3f( 1,0,0 ),\nvec3f( 0,1,0 ),\nvec3f( 0,0,1 )\n);result.Diffuse+=LTCEvaluate( normal,viewDir,position,mInvEmpty,rectCoords0,rectCoords1,rectCoords2,rectCoords3 );return result;}\nfn FetchDiffuseFilteredTexture(texLightFiltered: texture_2d<f32>,texLightFilteredSampler: sampler,p1_: vec3f,p2_: vec3f,p3_: vec3f,p4_: vec3f)->vec3f {var V1: vec3f=p2_-p1_;var V2: vec3f=p4_-p1_;var planeOrtho: vec3f=cross(V1,V2);var planeAreaSquared: f32=dot(planeOrtho,planeOrtho);var planeDistxPlaneArea: f32=dot(planeOrtho,p1_);var P: vec3f=planeDistxPlaneArea*planeOrtho/planeAreaSquared-p1_;var dot_V1_V2: f32=dot(V1,V2);var inv_dot_V1_V1: f32=1.0/dot(V1,V1);var V2_: vec3f=V2-V1*dot_V1_V2*inv_dot_V1_V1;var Puv: vec2f;Puv.y=dot(V2_,P)/dot(V2_,V2_);Puv.x=dot(V1,P)*inv_dot_V1_V1-dot_V1_V2*inv_dot_V1_V1*Puv.y;var d: f32=abs(planeDistxPlaneArea)/pow(planeAreaSquared,0.75);var sampleLOD: f32=log(2048.0*d)/log(3.0);var sampleUV: vec2f=vec2f(0.125,0.125)+(vec2f(0.75)*Puv);sampleUV.x=1.0-sampleUV.x;return textureSampleLevel(texLightFiltered,texLightFilteredSampler,sampleUV,sampleLOD).rgb;}\nfn LTCEvaluateWithEmission(N: vec3f,V: vec3f,P: vec3f,mInv: mat3x3<f32>,rectCoords0: vec3f,rectCoords1: vec3f,rectCoords2: vec3f,rectCoords3: vec3f,texFilteredMap: texture_2d<f32>,texFilteredMapSampler: sampler)->vec3f {var v1: vec3f=rectCoords1-rectCoords0;var v2: vec3f=rectCoords3-rectCoords0;var lightNormal: vec3f=cross(v1,v2);if (dot(lightNormal,P-rectCoords0)<0.0) {return vec3f(0.0);}\nvar T1: vec3f=normalize(V-N*dot(V,N));var T2: vec3f=-cross(N,T1);var mat: mat3x3<f32>=mInv*transposeMat3(mat3x3<f32>(T1,T2,N));var coords0: vec3f=mat*(rectCoords0-P);var coords1: vec3f=mat*(rectCoords1-P);var coords2: vec3f=mat*(rectCoords2-P);var coords3: vec3f=mat*(rectCoords3-P);var textureLight: vec3f=FetchDiffuseFilteredTexture(texFilteredMap,texFilteredMapSampler,coords0,coords1,coords2,coords3);coords0=normalize(coords0);coords1=normalize(coords1);coords2=normalize(coords2);coords3=normalize(coords3);var vectorFormFactor: vec3f=vec3f(0.0);vectorFormFactor+=LTCEdgeVectorFormFactor(coords0,coords1);vectorFormFactor+=LTCEdgeVectorFormFactor(coords1,coords2);vectorFormFactor+=LTCEdgeVectorFormFactor(coords2,coords3);vectorFormFactor+=LTCEdgeVectorFormFactor(coords3,coords0);var result: f32=LTCClippedSphereFormFactor(vectorFormFactor);return vec3f(result)*textureLight;}\nfn computeAreaLightSpecularDiffuseFresnelWithEmission(ltc1: texture_2d<f32>,ltc1Sampler:sampler,ltc2:texture_2d<f32>,ltc2Sampler:sampler,emissionTexture: texture_2d<f32>,emissionTextureSampler:sampler,viewDir: vec3f,normal:vec3f,position:vec3f,lightPos:vec3f,halfWidth:vec3f, halfHeight:vec3f,roughness:f32)->areaLightData {var result: areaLightData;var rectCoords0: vec3f=lightPos+halfWidth-halfHeight; \nvar rectCoords1: vec3f=lightPos-halfWidth-halfHeight;var rectCoords2: vec3f=lightPos-halfWidth+halfHeight;var rectCoords3: vec3f=lightPos+halfWidth+halfHeight;\n#ifdef SPECULARTERM\nvar uv: vec2f=LTCUv(normal,viewDir,roughness);var t1: vec4f=textureSample(ltc1,ltc1Sampler,uv);var t2: vec4f=textureSample(ltc2,ltc2Sampler,uv);var mInv: mat3x3<f32>=mat3x3<f32>(\nvec3f(t1.x,0,t1.y),\nvec3f(0,1,0),\nvec3f(t1.z,0,t1.w)\n);result.Specular=LTCEvaluateWithEmission(normal,viewDir,position,mInv,rectCoords0,rectCoords1,rectCoords2,rectCoords3,emissionTexture,emissionTextureSampler);result.Fresnel=t2;\n#endif\nvar mInvEmpty: mat3x3<f32>=mat3x3<f32>(\nvec3f(1,0,0),\nvec3f(0,1,0),\nvec3f(0,0,1)\n);result.Diffuse=LTCEvaluateWithEmission(normal,viewDir,position,mInvEmpty,rectCoords0,rectCoords1,rectCoords2,rectCoords3,emissionTexture,emissionTextureSampler);return result;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const ltcHelperFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clusteredLightingCompute\";\nconst shader = `#if defined(CLUSTLIGHT{X}) && defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nfn computeClusteredLighting{X}(\nlightDataTexture: texture_2d<f32>,\nviewDirectionW: vec3f,\nvNormal: vec3f,\nlightData: vec4f,\nsliceRange: vec2u,\nglossiness: f32\n)->lightingInfo {var result: lightingInfo;let tilePosition=vec2u(fragmentInputs.position.xy*lightData.xy);let maskResolution=vec2u(lightData.zw);var tileIndex=(tilePosition.x*maskResolution.x+tilePosition.y)*maskResolution.y;let batchRange=sliceRange/CLUSTLIGHT_BATCH;var batchOffset=batchRange.x*CLUSTLIGHT_BATCH;tileIndex+=batchRange.x;for (var i=batchRange.x; i<=batchRange.y; i+=1) {var mask=tileMaskBuffer{X}[tileIndex];tileIndex+=1;let maskOffset=max(sliceRange.x,batchOffset)-batchOffset; \nlet maskWidth=min(sliceRange.y-batchOffset+1,CLUSTLIGHT_BATCH);mask=extractBits(mask,maskOffset,maskWidth);while mask != 0 {let trailing=firstTrailingBit(mask);mask ^= 1u<<trailing;let light=getClusteredLight(lightDataTexture,batchOffset+maskOffset+trailing);var info: lightingInfo;if light.vLightDirection.w<0.0 {info=computeLighting(viewDirectionW,vNormal,light.vLightData,light.vLightDiffuse.rgb,light.vLightSpecular.rgb,light.vLightDiffuse.a,glossiness);} else {info=computeSpotLighting(viewDirectionW,vNormal,light.vLightData,light.vLightDirection,light.vLightDiffuse.rgb,light.vLightSpecular.rgb,light.vLightDiffuse.a,glossiness);}\nresult.diffuse+=info.diffuse;\n#ifdef SPECULARTERM\nresult.specular+=info.specular;\n#endif\n}\nbatchOffset+=CLUSTLIGHT_BATCH;}\nreturn result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const clusteredLightingComputeWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./ltcHelperFunctions\";\nimport \"./clusteredLightingFunctions\";\nimport \"./clusteredLightingCompute\";\nconst name = \"lightsFragmentFunctions\";\nconst shader = `struct lightingInfo\n{diffuse: vec3f,\n#ifdef SPECULARTERM\nspecular: vec3f,\n#endif\n#ifdef NDOTL\nndl: f32,\n#endif\n};fn computeLighting(viewDirectionW: vec3f,vNormal: vec3f,lightData: vec4f,diffuseColor: vec3f,specularColor: vec3f,range: f32,glossiness: f32)->lightingInfo {var result: lightingInfo;var lightVectorW: vec3f;var attenuation: f32=1.0;if (lightData.w==0.)\n{var direction: vec3f=lightData.xyz-fragmentInputs.vPositionW;attenuation=max(0.,1.0-length(direction)/range);lightVectorW=normalize(direction);}\nelse\n{lightVectorW=normalize(-lightData.xyz);}\nvar ndl: f32=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\nvar angleW: vec3f=normalize(viewDirectionW+lightVectorW);var specComp: f32=max(0.,dot(vNormal,angleW));specComp=pow(specComp,max(1.,glossiness));result.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;}\nfn getAttenuation(cosAngle: f32,exponent: f32)->f32 {return max(0.,pow(cosAngle,exponent));}\nfn getIESAttenuation(cosAngle: f32,iesLightTexture: texture_2d<f32>,iesLightTextureSampler: sampler)->f32 {var angle=acos(cosAngle)/PI;return textureSampleLevel(iesLightTexture,iesLightTextureSampler,vec2f(angle,0),0.).r;}\nfn computeBasicSpotLighting(viewDirectionW: vec3f,lightVectorW: vec3f,vNormal: vec3f,attenuation: f32,diffuseColor: vec3f,specularColor: vec3f,glossiness: f32)->lightingInfo {var result: lightingInfo;var ndl: f32=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\nvar angleW: vec3f=normalize(viewDirectionW+lightVectorW);var specComp: f32=max(0.,dot(vNormal,angleW));specComp=pow(specComp,max(1.,glossiness));result.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;}\nfn computeIESSpotLighting(viewDirectionW: vec3f,vNormal: vec3f,lightData: vec4f,lightDirection: vec4f,diffuseColor: vec3f,specularColor: vec3f,range: f32,glossiness: f32,iesLightTexture: texture_2d<f32>,iesLightTextureSampler: sampler)->lightingInfo {var direction: vec3f=lightData.xyz-fragmentInputs.vPositionW;var lightVectorW: vec3f=normalize(direction);var attenuation: f32=max(0.,1.0-length(direction)/range);var dotProduct=dot(lightDirection.xyz,-lightVectorW);var cosAngle: f32=max(0.,dotProduct);if (cosAngle>=lightDirection.w)\n{attenuation*=getIESAttenuation(dotProduct,iesLightTexture,iesLightTextureSampler);return computeBasicSpotLighting(viewDirectionW,lightVectorW,vNormal,attenuation,diffuseColor,specularColor,glossiness);}\nvar result: lightingInfo;result.diffuse=vec3f(0.);\n#ifdef SPECULARTERM\nresult.specular=vec3f(0.);\n#endif\n#ifdef NDOTL\nresult.ndl=0.;\n#endif\nreturn result;}\nfn computeSpotLighting(viewDirectionW: vec3f,vNormal: vec3f ,lightData: vec4f,lightDirection: vec4f,diffuseColor: vec3f,specularColor: vec3f,range: f32,glossiness: f32)->lightingInfo {var direction: vec3f=lightData.xyz-fragmentInputs.vPositionW;var lightVectorW: vec3f=normalize(direction);var attenuation: f32=max(0.,1.0-length(direction)/range);var cosAngle: f32=max(0.,dot(lightDirection.xyz,-lightVectorW));if (cosAngle>=lightDirection.w)\n{attenuation*=getAttenuation(cosAngle,lightData.w);return computeBasicSpotLighting(viewDirectionW,lightVectorW,vNormal,attenuation,diffuseColor,specularColor,glossiness);}\nvar result: lightingInfo;result.diffuse=vec3f(0.);\n#ifdef SPECULARTERM\nresult.specular=vec3f(0.);\n#endif\n#ifdef NDOTL\nresult.ndl=0.;\n#endif\nreturn result;}\nfn computeHemisphericLighting(viewDirectionW: vec3f,vNormal: vec3f,lightData: vec4f,diffuseColor: vec3f,specularColor: vec3f,groundColor: vec3f,glossiness: f32)->lightingInfo {var result: lightingInfo;var ndl: f32=dot(vNormal,lightData.xyz)*0.5+0.5;\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=mix(groundColor,diffuseColor,ndl);\n#ifdef SPECULARTERM\nvar angleW: vec3f=normalize(viewDirectionW+lightData.xyz);var specComp: f32=max(0.,dot(vNormal,angleW));specComp=pow(specComp,max(1.,glossiness));result.specular=specComp*specularColor;\n#endif\nreturn result;}\nfn computeProjectionTextureDiffuseLighting(projectionLightTexture: texture_2d<f32>,projectionLightSampler: sampler,textureProjectionMatrix: mat4x4f,posW: vec3f)->vec3f {var strq: vec4f=textureProjectionMatrix*vec4f(posW,1.0);strq/=strq.w;var textureColor: vec3f=textureSample(projectionLightTexture,projectionLightSampler,strq.xy).rgb;return textureColor;}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#include<ltcHelperFunctions>\nvar areaLightsLTC1SamplerSampler: sampler;var areaLightsLTC1Sampler: texture_2d<f32>;var areaLightsLTC2SamplerSampler: sampler;var areaLightsLTC2Sampler: texture_2d<f32>;fn computeAreaLighting(ltc1: texture_2d<f32>,ltc1Sampler:sampler,ltc2:texture_2d<f32>,ltc2Sampler:sampler,viewDirectionW: vec3f,vNormal:vec3f,vPosition:vec3f,lightPosition:vec3f,halfWidth:vec3f, halfHeight:vec3f,diffuseColor:vec3f,specularColor:vec3f,roughness:f32 )->lightingInfo\n{var result: lightingInfo;var data: areaLightData=computeAreaLightSpecularDiffuseFresnel(ltc1,ltc1Sampler,ltc2,ltc2Sampler,viewDirectionW,vNormal,vPosition,lightPosition,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nvar fresnel:vec3f=( specularColor*data.Fresnel.x+( vec3f( 1.0 )-specularColor )*data.Fresnel.y );result.specular+=specularColor*fresnel*data.Specular;\n#endif\nresult.diffuse+=diffuseColor*data.Diffuse;return result;}\nfn computeAreaLightingWithTexture(ltc1: texture_2d<f32>,ltc1Sampler:sampler,ltc2:texture_2d<f32>,ltc2Sampler:sampler,emissionTexture: texture_2d<f32>,emissionTextureSampler:sampler,viewDirectionW: vec3f,vNormal:vec3f,vPosition:vec3f,lightPosition:vec3f,halfWidth:vec3f, halfHeight:vec3f,diffuseColor:vec3f,specularColor:vec3f,roughness:f32 )->lightingInfo\n{var result: lightingInfo;var data: areaLightData=computeAreaLightSpecularDiffuseFresnelWithEmission(ltc1,ltc1Sampler,ltc2,ltc2Sampler,emissionTexture,emissionTextureSampler,viewDirectionW,vNormal,vPosition,lightPosition,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nvar fresnel: vec3f=( specularColor*data.Fresnel.x+( vec3f( 1.0 )-specularColor )*data.Fresnel.y );result.specular+=specularColor*fresnel*data.Specular;\n#endif\nresult.diffuse+=diffuseColor*data.Diffuse;return result;}\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#include<clusteredLightingFunctions>\n#include<clusteredLightingCompute>[0..maxSimultaneousLights]\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const lightsFragmentFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowsFragmentFunctions\";\nconst shader = `#ifdef SHADOWS\n#ifndef SHADOWFLOAT\nfn unpack(color: vec4f)->f32\n{const bit_shift: vec4f= vec4f(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);return dot(color,bit_shift);}\n#endif\nfn computeFallOff(value: f32,clipSpace: vec2f,frustumEdgeFalloff: f32)->f32\n{var mask: f32=smoothstep(1.0-frustumEdgeFalloff,1.00000012,clamp(dot(clipSpace,clipSpace),0.,1.));return mix(value,1.0,mask);}\nfn computeShadowCube(worldPos: vec3f,lightPosition: vec3f,shadowTexture: texture_cube<f32>,shadowSampler: sampler,darkness: f32,depthValues: vec2f)->f32\n{var directionToLight: vec3f=worldPos-lightPosition;var depth: f32=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);depth=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nvar shadow: f32=unpack(textureSample(shadowTexture,shadowSampler,directionToLight));\n#else\nvar shadow: f32=textureSample(shadowTexture,shadowSampler,directionToLight).x;\n#endif\nreturn select(1.0,darkness,depth>shadow);}\nfn computeShadowWithPoissonSamplingCube(worldPos: vec3f,lightPosition: vec3f,shadowTexture: texture_cube<f32>,shadowSampler: sampler,mapSize: f32,darkness: f32,depthValues: vec2f)->f32\n{var directionToLight: vec3f=worldPos-lightPosition;var depth: f32=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);depth=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;var visibility: f32=1.;var poissonDisk: array<vec3f,4>;poissonDisk[0]= vec3f(-1.0,1.0,-1.0);poissonDisk[1]= vec3f(1.0,-1.0,-1.0);poissonDisk[2]= vec3f(-1.0,-1.0,-1.0);poissonDisk[3]= vec3f(1.0,-1.0,1.0);\n#ifndef SHADOWFLOAT\nif (unpack(textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) {visibility-=0.25;};if (unpack(textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) {visibility-=0.25;};if (unpack(textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) {visibility-=0.25;};if (unpack(textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) {visibility-=0.25;};\n#else\nif (textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) {visibility-=0.25;};if (textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) {visibility-=0.25;};if (textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) {visibility-=0.25;};if (textureSample(shadowTexture,shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) {visibility-=0.25;};\n#endif\nreturn min(1.0,visibility+darkness);}\nfn computeShadowWithESMCube(worldPos: vec3f,lightPosition: vec3f,shadowTexture: texture_cube<f32>,shadowSampler: sampler,darkness: f32,depthScale: f32,depthValues: vec2f)->f32\n{var directionToLight: vec3f=worldPos-lightPosition;var depth: f32=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);var shadowPixelDepth: f32=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nvar shadowMapSample: f32=unpack(textureSample(shadowTexture,shadowSampler,directionToLight));\n#else\nvar shadowMapSample: f32=textureSample(shadowTexture,shadowSampler,directionToLight).x;\n#endif\nvar esm: f32=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);return esm;}\nfn computeShadowWithCloseESMCube(worldPos: vec3f,lightPosition: vec3f,shadowTexture: texture_cube<f32>,shadowSampler: sampler,darkness: f32,depthScale: f32,depthValues: vec2f)->f32\n{var directionToLight: vec3f=worldPos-lightPosition;var depth: f32=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);var shadowPixelDepth: f32=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nvar shadowMapSample: f32=unpack(textureSample(shadowTexture,shadowSampler,directionToLight));\n#else\nvar shadowMapSample: f32=textureSample(shadowTexture,shadowSampler,directionToLight).x;\n#endif\nvar esm: f32=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);return esm;}\nfn computeShadowCSM(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_2d_array<f32>,shadowSampler: sampler,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uv: vec2f=0.5*clipSpace.xy+ vec2f(0.5);var shadowPixelDepth: f32=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nvar shadow: f32=unpack(textureSample(shadowTexture,shadowSampler,uv,layer));\n#else\nvar shadow: f32=textureSample(shadowTexture,shadowSampler,uv,layer).x;\n#endif\nreturn select(1.,computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff),shadowPixelDepth>shadow );}\nfn computeShadow(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_2d<f32>,shadowSampler: sampler,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uv: vec2f=0.5*clipSpace.xy+ vec2f(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{var shadowPixelDepth: f32=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nvar shadow: f32=unpack(textureSampleLevel(shadowTexture,shadowSampler,uv,0.));\n#else\nvar shadow: f32=textureSampleLevel(shadowTexture,shadowSampler,uv,0.).x;\n#endif\nreturn select(1.,computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff),shadowPixelDepth>shadow );}}\nfn computeShadowWithPoissonSampling(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_2d<f32>,shadowSampler: sampler,mapSize: f32,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uv: vec2f=0.5*clipSpace.xy+ vec2f(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{var shadowPixelDepth: f32=clamp(depthMetric,0.,1.0);var visibility: f32=1.;var poissonDisk: array<vec2f,4>;poissonDisk[0]= vec2f(-0.94201624,-0.39906216);poissonDisk[1]= vec2f(0.94558609,-0.76890725);poissonDisk[2]= vec2f(-0.094184101,-0.92938870);poissonDisk[3]= vec2f(0.34495938,0.29387760);\n#ifndef SHADOWFLOAT\nif (unpack(textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[0]*mapSize,0.))<shadowPixelDepth) {visibility-=0.25;}\nif (unpack(textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[1]*mapSize,0.))<shadowPixelDepth) {visibility-=0.25;}\nif (unpack(textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[2]*mapSize,0.))<shadowPixelDepth) {visibility-=0.25;}\nif (unpack(textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[3]*mapSize,0.))<shadowPixelDepth) {visibility-=0.25;}\n#else\nif (textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[0]*mapSize,0.).x<shadowPixelDepth) {visibility-=0.25;}\nif (textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[1]*mapSize,0.).x<shadowPixelDepth) {visibility-=0.25;}\nif (textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[2]*mapSize,0.).x<shadowPixelDepth) {visibility-=0.25;}\nif (textureSampleLevel(shadowTexture,shadowSampler,uv+poissonDisk[3]*mapSize,0.).x<shadowPixelDepth) {visibility-=0.25;}\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);}}\nfn computeShadowWithESM(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_2d<f32>,shadowSampler: sampler,darkness: f32,depthScale: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uv: vec2f=0.5*clipSpace.xy+ vec2f(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{var shadowPixelDepth: f32=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nvar shadowMapSample: f32=unpack(textureSampleLevel(shadowTexture,shadowSampler,uv,0.));\n#else\nvar shadowMapSample: f32=textureSampleLevel(shadowTexture,shadowSampler,uv,0.).x;\n#endif\nvar esm: f32=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);return computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);}}\nfn computeShadowWithCloseESM(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_2d<f32>,shadowSampler: sampler,darkness: f32,depthScale: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uv: vec2f=0.5*clipSpace.xy+ vec2f(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{var shadowPixelDepth: f32=clamp(depthMetric,0.,1.0); \n#ifndef SHADOWFLOAT\nvar shadowMapSample: f32=unpack(textureSampleLevel(shadowTexture,shadowSampler,uv,0.));\n#else\nvar shadowMapSample: f32=textureSampleLevel(shadowTexture,shadowSampler,uv,0.).x;\n#endif\nvar esm: f32=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);return computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);}}\nfn getZInClip(clipSpace: vec3f,uvDepth: vec3f)->f32\n{\n#ifdef IS_NDC_HALF_ZRANGE\nreturn clipSpace.z;\n#else\nreturn uvDepth.z;\n#endif\n}\nconst GREATEST_LESS_THAN_ONE: f32=0.99999994;\n#define DISABLE_UNIFORMITY_ANALYSIS\nfn computeShadowWithCSMPCF1(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=clamp(getZInClip(clipSpace,uvDepth),0.,GREATEST_LESS_THAN_ONE);var shadow: f32=textureSampleCompare(shadowTexture,shadowSampler,uvDepth.xy,layer,uvDepth.z);shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\nfn computeShadowWithCSMPCF3(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,shadowMapSizeAndInverse: vec2f,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=clamp(getZInClip(clipSpace,uvDepth),0.,GREATEST_LESS_THAN_ONE);var uv: vec2f=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvar st: vec2f=fract(uv); \nvar base_uv: vec2f=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvar uvw0: vec2f=3.-2.*st;var uvw1: vec2f=1.+2.*st;var u: vec2f= vec2f((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;var v: vec2f= vec2f((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;var shadow: f32=0.;shadow+=uvw0.x*uvw0.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[0]),layer,uvDepth.z);shadow+=uvw1.x*uvw0.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[0]),layer,uvDepth.z);shadow+=uvw0.x*uvw1.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[1]),layer,uvDepth.z);shadow+=uvw1.x*uvw1.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[1]),layer,uvDepth.z);shadow=shadow/16.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\nfn computeShadowWithCSMPCF5(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,shadowMapSizeAndInverse: vec2f,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=clamp(getZInClip(clipSpace,uvDepth),0.,GREATEST_LESS_THAN_ONE);var uv: vec2f=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvar st: vec2f=fract(uv); \nvar base_uv: vec2f=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvar uvw0: vec2f=4.-3.*st;var uvw1: vec2f= vec2f(7.);var uvw2: vec2f=1.+3.*st;var u: vec3f= vec3f((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;var v: vec3f= vec3f((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;var shadow: f32=0.;shadow+=uvw0.x*uvw0.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[0]),layer,uvDepth.z);shadow+=uvw1.x*uvw0.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[0]),layer,uvDepth.z);shadow+=uvw2.x*uvw0.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[2],v[0]),layer,uvDepth.z);shadow+=uvw0.x*uvw1.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[1]),layer,uvDepth.z);shadow+=uvw1.x*uvw1.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[1]),layer,uvDepth.z);shadow+=uvw2.x*uvw1.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[2],v[1]),layer,uvDepth.z);shadow+=uvw0.x*uvw2.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[2]),layer,uvDepth.z);shadow+=uvw1.x*uvw2.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[2]),layer,uvDepth.z);shadow+=uvw2.x*uvw2.y*textureSampleCompare(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[2],v[2]),layer,uvDepth.z);shadow=shadow/144.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\nfn computeShadowWithPCF1(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=getZInClip(clipSpace,uvDepth);if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {var shadow: f32=textureSampleCompareLevel(shadowTexture,shadowSampler,uvDepth.xy,uvDepth.z);shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\nfn computeShadowWithPCF3(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,shadowMapSizeAndInverse: vec2f,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=getZInClip(clipSpace,uvDepth);if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {var uv: vec2f=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvar st: vec2f=fract(uv); \nvar base_uv: vec2f=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvar uvw0: vec2f=3.-2.*st;var uvw1: vec2f=1.+2.*st;var u: vec2f= vec2f((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;var v: vec2f= vec2f((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;var shadow: f32=0.;shadow+=uvw0.x*uvw0.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[0]),uvDepth.z);shadow+=uvw1.x*uvw0.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[0]),uvDepth.z);shadow+=uvw0.x*uvw1.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[1]),uvDepth.z);shadow+=uvw1.x*uvw1.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[1]),uvDepth.z);shadow=shadow/16.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\nfn computeShadowWithPCF5(vPositionFromLight: vec4f,depthMetric: f32,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,shadowMapSizeAndInverse: vec2f,darkness: f32,frustumEdgeFalloff: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=getZInClip(clipSpace,uvDepth);if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {var uv: vec2f=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvar st: vec2f=fract(uv); \nvar base_uv: vec2f=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvar uvw0: vec2f=4.-3.*st;var uvw1: vec2f= vec2f(7.);var uvw2: vec2f=1.+3.*st;var u: vec3f= vec3f((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;var v: vec3f= vec3f((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;var shadow: f32=0.;shadow+=uvw0.x*uvw0.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[0]),uvDepth.z);shadow+=uvw1.x*uvw0.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[0]),uvDepth.z);shadow+=uvw2.x*uvw0.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[2],v[0]),uvDepth.z);shadow+=uvw0.x*uvw1.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[1]),uvDepth.z);shadow+=uvw1.x*uvw1.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[1]),uvDepth.z);shadow+=uvw2.x*uvw1.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[2],v[1]),uvDepth.z);shadow+=uvw0.x*uvw2.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[0],v[2]),uvDepth.z);shadow+=uvw1.x*uvw2.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[1],v[2]),uvDepth.z);shadow+=uvw2.x*uvw2.y*textureSampleCompareLevel(shadowTexture,shadowSampler, base_uv.xy+ vec2f(u[2],v[2]),uvDepth.z);shadow=shadow/144.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\nconst PoissonSamplers32: array<vec3f,64>=array<vec3f,64> (\nvec3f(0.06407013,0.05409927,0.),\nvec3f(0.7366577,0.5789394,0.),\nvec3f(-0.6270542,-0.5320278,0.),\nvec3f(-0.4096107,0.8411095,0.),\nvec3f(0.6849564,-0.4990818,0.),\nvec3f(-0.874181,-0.04579735,0.),\nvec3f(0.9989998,0.0009880066,0.),\nvec3f(-0.004920578,-0.9151649,0.),\nvec3f(0.1805763,0.9747483,0.),\nvec3f(-0.2138451,0.2635818,0.),\nvec3f(0.109845,0.3884785,0.),\nvec3f(0.06876755,-0.3581074,0.),\nvec3f(0.374073,-0.7661266,0.),\nvec3f(0.3079132,-0.1216763,0.),\nvec3f(-0.3794335,-0.8271583,0.),\nvec3f(-0.203878,-0.07715034,0.),\nvec3f(0.5912697,0.1469799,0.),\nvec3f(-0.88069,0.3031784,0.),\nvec3f(0.5040108,0.8283722,0.),\nvec3f(-0.5844124,0.5494877,0.),\nvec3f(0.6017799,-0.1726654,0.),\nvec3f(-0.5554981,0.1559997,0.),\nvec3f(-0.3016369,-0.3900928,0.),\nvec3f(-0.5550632,-0.1723762,0.),\nvec3f(0.925029,0.2995041,0.),\nvec3f(-0.2473137,0.5538505,0.),\nvec3f(0.9183037,-0.2862392,0.),\nvec3f(0.2469421,0.6718712,0.),\nvec3f(0.3916397,-0.4328209,0.),\nvec3f(-0.03576927,-0.6220032,0.),\nvec3f(-0.04661255,0.7995201,0.),\nvec3f(0.4402924,0.3640312,0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.),\nvec3f(0.)\n);const PoissonSamplers64: array<vec3f,64>=array<vec3f,64> (\nvec3f(-0.613392,0.617481,0.),\nvec3f(0.170019,-0.040254,0.),\nvec3f(-0.299417,0.791925,0.),\nvec3f(0.645680,0.493210,0.),\nvec3f(-0.651784,0.717887,0.),\nvec3f(0.421003,0.027070,0.),\nvec3f(-0.817194,-0.271096,0.),\nvec3f(-0.705374,-0.668203,0.),\nvec3f(0.977050,-0.108615,0.),\nvec3f(0.063326,0.142369,0.),\nvec3f(0.203528,0.214331,0.),\nvec3f(-0.667531,0.326090,0.),\nvec3f(-0.098422,-0.295755,0.),\nvec3f(-0.885922,0.215369,0.),\nvec3f(0.566637,0.605213,0.),\nvec3f(0.039766,-0.396100,0.),\nvec3f(0.751946,0.453352,0.),\nvec3f(0.078707,-0.715323,0.),\nvec3f(-0.075838,-0.529344,0.),\nvec3f(0.724479,-0.580798,0.),\nvec3f(0.222999,-0.215125,0.),\nvec3f(-0.467574,-0.405438,0.),\nvec3f(-0.248268,-0.814753,0.),\nvec3f(0.354411,-0.887570,0.),\nvec3f(0.175817,0.382366,0.),\nvec3f(0.487472,-0.063082,0.),\nvec3f(-0.084078,0.898312,0.),\nvec3f(0.488876,-0.783441,0.),\nvec3f(0.470016,0.217933,0.),\nvec3f(-0.696890,-0.549791,0.),\nvec3f(-0.149693,0.605762,0.),\nvec3f(0.034211,0.979980,0.),\nvec3f(0.503098,-0.308878,0.),\nvec3f(-0.016205,-0.872921,0.),\nvec3f(0.385784,-0.393902,0.),\nvec3f(-0.146886,-0.859249,0.),\nvec3f(0.643361,0.164098,0.),\nvec3f(0.634388,-0.049471,0.),\nvec3f(-0.688894,0.007843,0.),\nvec3f(0.464034,-0.188818,0.),\nvec3f(-0.440840,0.137486,0.),\nvec3f(0.364483,0.511704,0.),\nvec3f(0.034028,0.325968,0.),\nvec3f(0.099094,-0.308023,0.),\nvec3f(0.693960,-0.366253,0.),\nvec3f(0.678884,-0.204688,0.),\nvec3f(0.001801,0.780328,0.),\nvec3f(0.145177,-0.898984,0.),\nvec3f(0.062655,-0.611866,0.),\nvec3f(0.315226,-0.604297,0.),\nvec3f(-0.780145,0.486251,0.),\nvec3f(-0.371868,0.882138,0.),\nvec3f(0.200476,0.494430,0.),\nvec3f(-0.494552,-0.711051,0.),\nvec3f(0.612476,0.705252,0.),\nvec3f(-0.578845,-0.768792,0.),\nvec3f(-0.772454,-0.090976,0.),\nvec3f(0.504440,0.372295,0.),\nvec3f(0.155736,0.065157,0.),\nvec3f(0.391522,0.849605,0.),\nvec3f(-0.620106,-0.328104,0.),\nvec3f(0.789239,-0.419965,0.),\nvec3f(-0.545396,0.538133,0.),\nvec3f(-0.178564,-0.596057,0.)\n);fn computeShadowWithCSMPCSS(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d_array<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32,searchTapCount: i32,pcfTapCount: i32,poissonSamplers: array<vec3f,64>,lightSizeUVCorrection: vec2f,depthCorrection: f32,penumbraDarkness: f32)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=clamp(getZInClip(clipSpace,uvDepth),0.,GREATEST_LESS_THAN_ONE);var uvDepthLayer: vec4f= vec4f(uvDepth.x,uvDepth.y,f32(layer),uvDepth.z);var blockerDepth: f32=0.0;var sumBlockerDepth: f32=0.0;var numBlocker: f32=0.0;for (var i: i32=0; i<searchTapCount; i ++) {blockerDepth=textureSample(depthTexture,depthSampler, uvDepth.xy+(lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse*PoissonSamplers32[i].xy),layer).r;numBlocker+=select(0.,1.,blockerDepth<depthMetric);sumBlockerDepth+=select(0.,blockerDepth,blockerDepth<depthMetric);}\nvar avgBlockerDepth: f32=sumBlockerDepth/numBlocker;var AAOffset: f32=shadowMapSizeInverse*10.;var penumbraRatio: f32=((depthMetric-avgBlockerDepth)*depthCorrection+AAOffset);var filterRadius: vec4f= vec4f(penumbraRatio*lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse,0.,0.);var random: f32=getRand(vPositionFromLight.xy);var rotationAngle: f32=random*3.1415926;var rotationVector: vec2f= vec2f(cos(rotationAngle),sin(rotationAngle));var shadow: f32=0.;for (var i: i32=0; i<pcfTapCount; i++) {var offset: vec4f= vec4f(poissonSamplers[i],0.);offset= vec4f(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.,0.);let coords=uvDepthLayer+offset*filterRadius;shadow+=textureSampleCompare(shadowTexture,shadowSampler,coords.xy,i32(coords.z),coords.w);}\nshadow/= f32(pcfTapCount);shadow=mix(shadow,1.,min((depthMetric-avgBlockerDepth)*depthCorrection*penumbraDarkness,1.));shadow=mix(darkness,1.,shadow);return select(computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff),1.0,numBlocker<1.0);}\nfn computeShadowWithPCSS(vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32,searchTapCount: i32,pcfTapCount: i32,poissonSamplers: array<vec3f,64>)->f32\n{var clipSpace: vec3f=vPositionFromLight.xyz/vPositionFromLight.w;var uvDepth: vec3f= vec3f(0.5*clipSpace.xyz+ vec3f(0.5));uvDepth.z=getZInClip(clipSpace,uvDepth);if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;}\nvar blockerDepth: f32=0.0;var sumBlockerDepth: f32=0.0;var numBlocker: f32=0.0;for (var i: i32=0; i<searchTapCount; i ++) {blockerDepth=textureSampleLevel(depthTexture,depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy),0).r;numBlocker+=select(0.,1.,blockerDepth<depthMetric);sumBlockerDepth+=select(0.,blockerDepth,blockerDepth<depthMetric);}\nif (numBlocker<1.0) {return 1.0;}\nvar avgBlockerDepth: f32=sumBlockerDepth/numBlocker;var AAOffset: f32=shadowMapSizeInverse*10.;var penumbraRatio: f32=((depthMetric-avgBlockerDepth)+AAOffset);var filterRadius: f32=penumbraRatio*lightSizeUV*shadowMapSizeInverse;var random: f32=getRand(vPositionFromLight.xy);var rotationAngle: f32=random*3.1415926;var rotationVector: vec2f= vec2f(cos(rotationAngle),sin(rotationAngle));var shadow: f32=0.;for (var i: i32=0; i<pcfTapCount; i++) {var offset: vec3f=poissonSamplers[i];offset= vec3f(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);let coords=uvDepth+offset*filterRadius;shadow+=textureSampleCompareLevel(shadowTexture,shadowSampler,coords.xy,coords.z);}\nshadow/= f32(pcfTapCount);shadow=mix(shadow,1.,depthMetric-avgBlockerDepth);shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\nfn computeShadowWithPCSS16(vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32)->f32\n{return computeShadowWithPCSS(vPositionFromLight,depthMetric,depthTexture,depthSampler,shadowTexture,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);}\nfn computeShadowWithPCSS32(vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32)->f32\n{return computeShadowWithPCSS(vPositionFromLight,depthMetric,depthTexture,depthSampler,shadowTexture,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);}\nfn computeShadowWithPCSS64(vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32)->f32\n{return computeShadowWithPCSS(vPositionFromLight,depthMetric,depthTexture,depthSampler,shadowTexture,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);}\nfn computeShadowWithCSMPCSS16(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d_array<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32,lightSizeUVCorrection: vec2f,depthCorrection: f32,penumbraDarkness: f32)->f32\n{return computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthTexture,depthSampler,shadowTexture,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);}\nfn computeShadowWithCSMPCSS32(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d_array<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32,lightSizeUVCorrection: vec2f,depthCorrection: f32,penumbraDarkness: f32)->f32\n{return computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthTexture,depthSampler,shadowTexture,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);}\nfn computeShadowWithCSMPCSS64(layer: i32,vPositionFromLight: vec4f,depthMetric: f32,depthTexture: texture_2d_array<f32>,depthSampler: sampler,shadowTexture: texture_depth_2d_array,shadowSampler: sampler_comparison,shadowMapSizeInverse: f32,lightSizeUV: f32,darkness: f32,frustumEdgeFalloff: f32,lightSizeUVCorrection: vec2f,depthCorrection: f32,penumbraDarkness: f32)->f32\n{return computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthTexture,depthSampler,shadowTexture,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64,lightSizeUVCorrection,depthCorrection,penumbraDarkness);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const shadowsFragmentFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"imageProcessingFunctions\";\nconst shader = `#if TONEMAPPING==3\nconst PBRNeutralStartCompression: f32=0.8-0.04;const PBRNeutralDesaturation: f32=0.15;fn PBRNeutralToneMapping( color: vec3f )->vec3f {var x: f32=min(color.r,min(color.g,color.b));var offset: f32=select(0.04,x-6.25*x*x,x<0.08);var result=color;result-=offset;var peak: f32=max(result.r,max(result.g,result.b));if (peak<PBRNeutralStartCompression) {return result;}\nvar d: f32=1.-PBRNeutralStartCompression;var newPeak: f32=1.-d*d/(peak+d-PBRNeutralStartCompression);result*=newPeak/peak;var g: f32=1.-1./(PBRNeutralDesaturation*(peak-newPeak)+1.);return mix(result,newPeak* vec3f(1,1,1),g);}\n#endif\n#if TONEMAPPING==2\nconst ACESInputMat: mat3x3f= mat3x3f(\nvec3f(0.59719,0.07600,0.02840),\nvec3f(0.35458,0.90834,0.13383),\nvec3f(0.04823,0.01566,0.83777)\n);const ACESOutputMat: mat3x3f= mat3x3f(\nvec3f( 1.60475,-0.10208,-0.00327),\nvec3f(-0.53108, 1.10813,-0.07276),\nvec3f(-0.07367,-0.00605, 1.07602)\n);fn RRTAndODTFit(v: vec3f)->vec3f\n{var a: vec3f=v*(v+0.0245786)-0.000090537;var b: vec3f=v*(0.983729*v+0.4329510)+0.238081;return a/b;}\nfn ACESFitted(color: vec3f)->vec3f\n{var output=ACESInputMat*color;output=RRTAndODTFit(output);output=ACESOutputMat*output;output=saturateVec3(output);return output;}\n#endif\n#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_DEFINITIONS\nfn applyImageProcessing(result: vec4f)->vec4f {\n#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATSTART\nvar rgb=result.rgb;;\n#ifdef WHITEBALANCE\nrgb=uniforms.whiteBalanceMatrix*rgb;rgb=max(rgb,vec3f(0.0));\n#endif\n#ifdef EXPOSURE\nrgb*=uniforms.exposureLinear;\n#endif\n#ifdef VIGNETTE\nvar viewportXY: vec2f=fragmentInputs.position.xy*uniforms.vInverseScreenSize;viewportXY=viewportXY*2.0-1.0;var vignetteXY1: vec3f= vec3f(viewportXY*uniforms.vignetteSettings1.xy+uniforms.vignetteSettings1.zw,1.0);var vignetteTerm: f32=dot(vignetteXY1,vignetteXY1);var vignette: f32=pow(vignetteTerm,uniforms.vignetteSettings2.w);var vignetteColor: vec3f=uniforms.vignetteSettings2.rgb;\n#ifdef VIGNETTEBLENDMODEMULTIPLY\nvar vignetteColorMultiplier: vec3f=mix(vignetteColor, vec3f(1,1,1),vignette);rgb*=vignetteColorMultiplier;\n#endif\n#ifdef VIGNETTEBLENDMODEOPAQUE\nrgb=mix(vignetteColor,rgb,vignette);\n#endif\n#endif\n#if TONEMAPPING==3\nrgb=PBRNeutralToneMapping(rgb);\n#elif TONEMAPPING==2\nrgb=ACESFitted(rgb);\n#elif TONEMAPPING==1\nconst tonemappingCalibration: f32=1.590579;rgb=1.0-exp2(-tonemappingCalibration*rgb);\n#endif\nrgb=toGammaSpaceVec3(rgb);rgb=saturateVec3(rgb);\n#ifdef CONTRAST\nvar resultHighContrast: vec3f=rgb*rgb*(3.0-2.0*rgb);if (uniforms.contrast<1.0) {rgb=mix( vec3f(0.5,0.5,0.5),rgb,uniforms.contrast);} else {rgb=mix(rgb,resultHighContrast,uniforms.contrast-1.0);}\nrgb=max(rgb,vec3f(0.));\n#endif\n#ifdef COLORGRADING\nvar colorTransformInput: vec3f=rgb*uniforms.colorTransformSettings.xxx+uniforms.colorTransformSettings.yyy;\n#ifdef COLORGRADING3D\nvar colorTransformOutput: vec3f=textureSample(txColorTransform,txColorTransformSampler,colorTransformInput).rgb;\n#else\nvar colorTransformOutput: vec3f=textureSample(txColorTransform,txColorTransformSampler,colorTransformInput,uniforms.colorTransformSettings.yz).rgb;\n#endif\nrgb=mix(rgb,colorTransformOutput,uniforms.colorTransformSettings.www);\n#endif\n#ifdef COLORCURVES\nvar luma: f32=getLuminance(rgb);var curveMix: vec2f=clamp( vec2f(luma*3.0-1.5,luma*-3.0+1.5), vec2f(0.0), vec2f(1.0));var colorCurve: vec4f=uniforms.vCameraColorCurveNeutral+curveMix.x*uniforms.vCameraColorCurvePositive-curveMix.y*uniforms.vCameraColorCurveNegative;rgb*=colorCurve.rgb;rgb=mix( vec3f(luma),rgb,colorCurve.a);\n#endif\n#ifdef DITHER\nvar rand: f32=getRand(fragmentInputs.position.xy*uniforms.vInverseScreenSize);var dither: f32=mix(-uniforms.ditherIntensity,uniforms.ditherIntensity,rand);rgb=saturateVec3(rgb+ vec3f(dither));\n#endif\n#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATEND\nreturn vec4f(rgb,result.a);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const imageProcessingFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogFragmentDeclaration\";\nconst shader = `#ifdef FOG\n#define FOGMODE_NONE 0.\n#define FOGMODE_EXP 1.\n#define FOGMODE_EXP2 2.\n#define FOGMODE_LINEAR 3.\nconst E=2.71828;uniform vFogInfos: vec4f;uniform vFogColor: vec3f;varying vFogDistance: vec3f;fn CalcFogFactor()->f32\n{var fogCoeff: f32=1.0;var fogStart: f32=uniforms.vFogInfos.y;var fogEnd: f32=uniforms.vFogInfos.z;var fogDensity: f32=uniforms.vFogInfos.w;var fogDistance: f32=length(fragmentInputs.vFogDistance);if (FOGMODE_LINEAR==uniforms.vFogInfos.x)\n{fogCoeff=(fogEnd-fogDistance)/(fogEnd-fogStart);}\nelse if (FOGMODE_EXP==uniforms.vFogInfos.x)\n{fogCoeff=1.0/pow(E,fogDistance*fogDensity);}\nelse if (FOGMODE_EXP2==uniforms.vFogInfos.x)\n{fogCoeff=1.0/pow(E,fogDistance*fogDistance*fogDensity*fogDensity);}\nreturn clamp(fogCoeff,0.0,1.0);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const fogFragmentDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"intersectionFunctions\";\nconst shader = `fn diskIntersectWithBackFaceCulling(ro: vec3f,rd: vec3f,c: vec3f,r: f32)->f32 {var d: f32=rd.y;if(d>0.0) { return 1e6; }\nvar o: vec3f=ro-c;var t: f32=-o.y/d;var q: vec3f=o+rd*t;return select(1e6,t,(dot(q,q)<r*r));}\nfn sphereIntersect(ro: vec3f,rd: vec3f,ce: vec3f,ra: f32)->vec2f {var oc: vec3f=ro-ce;var b: f32=dot(oc,rd);var c: f32=dot(oc,oc)-ra*ra;var h: f32=b*b-c;if(h<0.0) { return vec2f(-1.,-1.); }\nh=sqrt(h);return vec2f(-b+h,-b-h);}\nfn sphereIntersectFromOrigin(ro: vec3f,rd: vec3f,ra: f32)->vec2f {var b: f32=dot(ro,rd);var c: f32=dot(ro,ro)-ra*ra;var h: f32=b*b-c;if(h<0.0) { return vec2f(-1.,-1.); }\nh=sqrt(h);return vec2f(-b+h,-b-h);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const intersectionFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightFragment\";\nconst shader = `#ifdef LIGHT{X}\n#if defined(SHADOWONLY) || defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})\n#else\nvar diffuse{X}: vec4f=light{X}.vLightDiffuse;\n#define CUSTOM_LIGHT{X}_COLOR \n#if defined(PBR) && defined(CLUSTLIGHT{X})\n{let sliceIndex=min(getClusteredSliceIndex(light{X}.vSliceData,fragmentInputs.vViewDepth),CLUSTLIGHT_SLICES-1);info=computeClusteredLighting{X}(\nlightDataTexture{X},\nlight{X}.vLightData,\nvec2u(light{X}.vSliceRanges[sliceIndex].xy),\nviewDirectionW,\nnormalW,\nfragmentInputs.vPositionW,\nsurfaceAlbedo,\nreflectivityOut,\n#ifdef IRIDESCENCE\niridescenceIntensity,\n#endif\n#ifdef SS_TRANSLUCENCY\nsubSurfaceOut,\n#endif\n#ifdef SPECULARTERM\nAARoughnessFactors.x,\n#endif\n#ifdef ANISOTROPIC\nanisotropicOut,\n#endif\n#ifdef SHEEN\nsheenOut,\n#endif\n#ifdef CLEARCOAT\nclearcoatOut,\n#endif\n);}\n#elif defined(PBR)\n#ifdef SPOTLIGHT{X}\npreInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,fragmentInputs.vPositionW);\n#elif defined(POINTLIGHT{X})\npreInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,fragmentInputs.vPositionW);\n#elif defined(HEMILIGHT{X})\npreInfo=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(DIRLIGHT{X})\npreInfo=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#if defined(RECTAREALIGHTEMISSIONTEXTURE{X})\npreInfo=computeAreaPreLightingInfoWithTexture(areaLightsLTC1Sampler,areaLightsLTC1SamplerSampler,areaLightsLTC2Sampler,areaLightsLTC2SamplerSampler,rectAreaLightEmissionTexture{X},rectAreaLightEmissionTexture{X}Sampler,viewDirectionW,normalW,fragmentInputs.vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,roughness);\n#else\npreInfo=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC1SamplerSampler,areaLightsLTC2Sampler,areaLightsLTC2SamplerSampler,viewDirectionW,normalW,fragmentInputs.vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,roughness);\n#endif\n#endif\npreInfo.NdotV=NdotV;\n#ifdef SPOTLIGHT{X}\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X},iesLightTexture{X}Sampler);\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff_GLTF(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X},iesLightTexture{X}Sampler);\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff_Physical(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w);\n#endif\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X},iesLightTexture{X}Sampler);\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff_Standard(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w);\n#endif\n#else\npreInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X},iesLightTexture{X}Sampler);\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#endif\n#elif defined(POINTLIGHT{X})\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n#else\npreInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#endif\n#else\npreInfo.attenuation=1.0;\n#endif\n#if defined(HEMILIGHT{X})\npreInfo.roughness=roughness;\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\npreInfo.roughness=roughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(roughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n#endif\npreInfo.diffuseRoughness=diffuseRoughness;preInfo.surfaceAlbedo=surfaceAlbedo;\n#ifdef IRIDESCENCE\npreInfo.iridescenceIntensity=iridescenceIntensity;\n#endif\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission=vec3f(0.0);\n#endif\n#ifdef HEMILIGHT{X}\ninfo.diffuse=computeHemisphericDiffuseLighting(preInfo,diffuse{X}.rgb,light{X}.vLightGround);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\ninfo.diffuse=computeAreaDiffuseLighting(preInfo,diffuse{X}.rgb);\n#elif defined(SS_TRANSLUCENCY)\n#ifndef SS_TRANSLUCENCY_LEGACY\ninfo.diffuse=computeDiffuseLighting(preInfo,diffuse{X}.rgb)*(1.0-subSurfaceOut.translucencyIntensity);info.diffuseTransmission=computeDiffuseTransmittedLighting(preInfo,diffuse{X}.rgb,subSurfaceOut.transmittance); \n#else\ninfo.diffuse=computeDiffuseTransmittedLighting(preInfo,diffuse{X}.rgb,subSurfaceOut.transmittance);\n#endif\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,diffuse{X}.rgb);\n#endif\n#ifdef SPECULARTERM\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\ninfo.specular=computeAreaSpecularLighting(preInfo,light{X}.vLightSpecular.rgb,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90);\n#else\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\n{let metalFresnel: vec3f=vec3f(reflectivityOut.specularWeight)*getF82Specular(preInfo.VdotH,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90,reflectivityOut.roughness);let dielectricFresnel: vec3f=fresnelSchlickGGXVec3(preInfo.VdotH,reflectivityOut.dielectricColorF0,reflectivityOut.colorReflectanceF90);coloredFresnel=mix(dielectricFresnel,metalFresnel,reflectivityOut.metallic);}\n#else\ncoloredFresnel=fresnelSchlickGGXVec3(preInfo.VdotH,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90);\n#endif\n#ifndef LEGACY_SPECULAR_ENERGY_CONSERVATION\n{let NdotH: f32=dot(normalW,preInfo.H);let fresnel: vec3f=fresnelSchlickGGXVec3(NdotH,vec3f(reflectanceF0),specularEnvironmentR90);info.diffuse*=(vec3f(1.0)-fresnel);}\n#endif\n#ifdef ANISOTROPIC\ninfo.specular=computeAnisotropicSpecularLighting(preInfo,viewDirectionW,normalW,anisotropicOut.anisotropicTangent,anisotropicOut.anisotropicBitangent,anisotropicOut.anisotropy,clearcoatOut.specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactors.x,diffuse{X}.rgb);\n#else\ninfo.specular=computeSpecularLighting(preInfo,normalW,clearcoatOut.specularEnvironmentR0,coloredFresnel,AARoughnessFactors.x,diffuse{X}.rgb);\n#endif\n#endif\n#endif\n#ifndef AREALIGHT{X}\n#ifdef SHEEN\n#ifdef SHEEN_LINKWITHALBEDO\npreInfo.roughness=sheenOut.sheenIntensity;\n#else\n#ifdef HEMILIGHT{X}\npreInfo.roughness=sheenOut.sheenRoughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(sheenOut.sheenRoughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n#endif\n#endif\ninfo.sheen=computeSheenLighting(preInfo,normalW,sheenOut.sheenColor,specularEnvironmentR90,AARoughnessFactors.x,diffuse{X}.rgb);\n#endif\n#ifdef CLEARCOAT\n#ifdef HEMILIGHT{X}\npreInfo.roughness=clearcoatOut.clearCoatRoughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(clearcoatOut.clearCoatRoughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n#endif\ninfo.clearCoat=computeClearCoatLighting(preInfo,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatAARoughnessFactors.x,clearcoatOut.clearCoatIntensity,diffuse{X}.rgb);\n#ifdef CLEARCOAT_TINT\nabsorption=computeClearCoatLightingAbsorption(clearcoatOut.clearCoatNdotVRefract,preInfo.L,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatColor,clearcoatOut.clearCoatThickness,clearcoatOut.clearCoatIntensity);info.diffuse*=absorption;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=absorption;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=absorption;\n#endif\n#endif\ninfo.diffuse*=info.clearCoat.w;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=info.clearCoat.w;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=info.clearCoat.w;\n#endif\n#ifdef SHEEN\ninfo.sheen*=info.clearCoat.w;\n#endif\n#endif\n#endif\n#else\n#ifdef SPOTLIGHT{X}\n#ifdef IESLIGHTTEXTURE{X}\ninfo=computeIESSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,diffuse{X}.a,glossiness,iesLightTexture{X},iesLightTexture{X}Sampler);\n#else\ninfo=computeSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,diffuse{X}.a,glossiness);\n#endif\n#elif defined(HEMILIGHT{X})\ninfo=computeHemisphericLighting(viewDirectionW,normalW,light{X}.vLightData,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,light{X}.vLightGround,glossiness);\n#elif defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})\ninfo=computeLighting(viewDirectionW,normalW,light{X}.vLightData,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,diffuse{X}.a,glossiness);\n#elif define(AREALIGHT{X}) && defined(AREALIGHTSUPPORTED)\n#if defined(RECTAREALIGHTEMISSIONTEXTURE{X})\ninfo=computeAreaLightingWithTexture(areaLightsLTC1Sampler,areaLightsLTC1SamplerSampler,areaLightsLTC2Sampler,areaLightsLTC2SamplerSampler,rectAreaLightEmissionTexture{X},rectAreaLightEmissionTexture{X}Sampler,viewDirectionW,normalW,fragmentInputs.vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,\n#ifdef AREALIGHTNOROUGHTNESS\n0.5\n#else\nuniforms.vReflectionInfos.y\n#endif\n);\n#else\ninfo=computeAreaLighting(areaLightsLTC1Sampler,areaLightsLTC1SamplerSampler,areaLightsLTC2Sampler,areaLightsLTC2SamplerSampler,viewDirectionW,normalW,fragmentInputs.vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,\n#ifdef AREALIGHTNOROUGHTNESS\n0.5\n#else\nuniforms.vReflectionInfos.y\n#endif\n);\n#endif\n#elif defined(CLUSTLIGHT{X})\n{let sliceIndex=min(getClusteredSliceIndex(light{X}.vSliceData,fragmentInputs.vViewDepth),CLUSTLIGHT_SLICES-1);info=computeClusteredLighting{X}(lightDataTexture{X},viewDirectionW,normalW,light{X}.vLightData,vec2u(light{X}.vSliceRanges[sliceIndex].xy),glossiness);}\n#endif\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\ninfo.diffuse*=computeProjectionTextureDiffuseLighting(projectionLightTexture{X},projectionLightTexture{X}Sampler,uniforms.textureProjectionMatrix{X},fragmentInputs.vPositionW);\n#endif\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSMDEBUG{X}\nvar shadowDebug{X}: vec3f;\n#endif\n#ifdef SHADOWCSM{X}\n#ifdef SHADOWCSMUSESHADOWMAXZ{X}\nvar index{X}: i32=-1;\n#else\nvar index{X}: i32=SHADOWCSMNUM_CASCADES{X}-1;\n#endif\nvar diff{X}: f32=0.;vPositionFromLight{X}[0]=fragmentInputs.vPositionFromLight{X}_0;vPositionFromLight{X}[1]=fragmentInputs.vPositionFromLight{X}_1;vPositionFromLight{X}[2]=fragmentInputs.vPositionFromLight{X}_2;vPositionFromLight{X}[3]=fragmentInputs.vPositionFromLight{X}_3;vDepthMetric{X}[0]=fragmentInputs.vDepthMetric{X}_0;vDepthMetric{X}[1]=fragmentInputs.vDepthMetric{X}_1;vDepthMetric{X}[2]=fragmentInputs.vDepthMetric{X}_2;vDepthMetric{X}[3]=fragmentInputs.vDepthMetric{X}_3;for (var i:i32=0; i<SHADOWCSMNUM_CASCADES{X}; i++)\n{\n#ifdef SHADOWCSM_RIGHTHANDED{X}\ndiff{X}=uniforms.viewFrustumZ{X}[i]+fragmentInputs.vPositionFromCamera{X}.z;\n#else\ndiff{X}=uniforms.viewFrustumZ{X}[i]-fragmentInputs.vPositionFromCamera{X}.z;\n#endif\nif (diff{X}>=0.) {index{X}=i;break;}}\n#ifdef SHADOWCSMUSESHADOWMAXZ{X}\nif (index{X}>=0)\n#endif\n{\n#if defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithCSMPCF1(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithCSMPCF3(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithCSMPCF5(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithCSMPCSS16(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,uniforms.lightSizeUVCorrection{X}[index{X}],uniforms.depthCorrection{X}[index{X}],uniforms.penumbraDarkness{X});\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithCSMPCSS32(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,uniforms.lightSizeUVCorrection{X}[index{X}],uniforms.depthCorrection{X}[index{X}],uniforms.penumbraDarkness{X});\n#else\nshadow=computeShadowWithCSMPCSS64(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,uniforms.lightSizeUVCorrection{X}[index{X}],uniforms.depthCorrection{X}[index{X}],uniforms.penumbraDarkness{X});\n#endif\n#else\nshadow=computeShadowCSM(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#ifdef SHADOWCSMDEBUG{X}\nshadowDebug{X}=vec3f(shadow)*vCascadeColorsMultiplier{X}[index{X}];\n#endif\n#ifndef SHADOWCSMNOBLEND{X}\nvar frustumLength:f32=uniforms.frustumLengths{X}[index{X}];var diffRatio:f32=clamp(diff{X}/frustumLength,0.,1.)*uniforms.cascadeBlendFactor{X};if (index{X}<(SHADOWCSMNUM_CASCADES{X}-1) && diffRatio<1.)\n{index{X}+=1;var nextShadow: f32=0.;\n#if defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nnextShadow=computeShadowWithCSMPCF1(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nnextShadow=computeShadowWithCSMPCF3(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nnextShadow=computeShadowWithCSMPCF5(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nnextShadow=computeShadowWithCSMPCSS16(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,uniforms.lightSizeUVCorrection{X}[index{X}],uniforms.depthCorrection{X}[index{X}],uniforms.penumbraDarkness{X});\n#elif defined(SHADOWMEDIUMQUALITY{X})\nnextShadow=computeShadowWithCSMPCSS32(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,uniforms.lightSizeUVCorrection{X}[index{X}],uniforms.depthCorrection{X}[index{X}],uniforms.penumbraDarkness{X});\n#else\nnextShadow=computeShadowWithCSMPCSS64(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,uniforms.lightSizeUVCorrection{X}[index{X}],uniforms.depthCorrection{X}[index{X}],uniforms.penumbraDarkness{X});\n#endif\n#else\nnextShadow=computeShadowCSM(index{X},vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\nshadow=mix(nextShadow,shadow,diffRatio);\n#ifdef SHADOWCSMDEBUG{X}\nshadowDebug{X}=mix(vec3(nextShadow)*vCascadeColorsMultiplier{X}[index{X}],shadowDebug{X},diffRatio);\n#endif\n}\n#endif\n}\n#elif defined(SHADOWCLOSEESM{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithCloseESMCube(fragmentInputs.vPositionW,light{X}.vLightData.xyz,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithCloseESM(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWESM{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithESMCube(fragmentInputs.vPositionW,light{X}.vLightData.xyz,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithESM(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPOISSON{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithPoissonSamplingCube(fragmentInputs.vPositionW,light{X}.vLightData.xyz,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadowWithPoissonSampling(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithPCF1(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithPCF3(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithPCF5(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithPCSS16(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithPCSS32(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithPCSS64(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},depthTexture{X},depthTexture{X}Sampler,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#else\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowCube(fragmentInputs.vPositionW,light{X}.vLightData.xyz,shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadow(fragmentInputs.vPositionFromLight{X},fragmentInputs.vDepthMetric{X},shadowTexture{X},shadowTexture{X}Sampler,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#endif\n#ifdef SHADOWONLY\n#ifndef SHADOWINUSE\n#define SHADOWINUSE\n#endif\nglobalShadow+=shadow;shadowLightCount+=1.0;\n#endif\n#else\nshadow=1.;\n#endif\naggShadow+=shadow;numLights+=1.0;\n#ifndef SHADOWONLY\n#ifdef CUSTOMUSERLIGHTING\ndiffuseBase+=computeCustomDiffuseLighting(info,diffuseBase,shadow);\n#ifdef SPECULARTERM\nspecularBase+=computeCustomSpecularLighting(info,specularBase,shadow);\n#endif\n#elif defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X})\ndiffuseBase+=lightmapColor.rgb*shadow;\n#ifdef SPECULARTERM\n#ifndef LIGHTMAPNOSPECULAR{X}\nspecularBase+=info.specular*shadow*lightmapColor.rgb;\n#endif\n#endif\n#ifdef CLEARCOAT\n#ifndef LIGHTMAPNOSPECULAR{X}\nclearCoatBase+=info.clearCoat.rgb*shadow*lightmapColor.rgb;\n#endif\n#endif\n#ifdef SHEEN\n#ifndef LIGHTMAPNOSPECULAR{X}\nsheenBase+=info.sheen.rgb*shadow;\n#endif\n#endif\n#else\n#ifdef SHADOWCSMDEBUG{X}\ndiffuseBase+=info.diffuse*shadowDebug{X};\n#else\ndiffuseBase+=info.diffuse*shadow;\n#endif\n#ifdef SS_TRANSLUCENCY\ndiffuseTransmissionBase+=info.diffuseTransmission*shadow;\n#endif\n#ifdef SPECULARTERM\nspecularBase+=info.specular*shadow;\n#endif\n#ifdef CLEARCOAT\nclearCoatBase+=info.clearCoat.rgb*shadow;\n#endif\n#ifdef SHEEN\nsheenBase+=info.sheen.rgb*shadow;\n#endif\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const lightFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"logDepthFragment\";\nconst shader = `#ifdef LOGARITHMICDEPTH\nfragmentOutputs.fragDepth=log2(fragmentInputs.vFragmentDepth)*uniforms.logarithmicDepthConstant*0.5;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const logDepthFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogFragment\";\nconst shader = `#ifdef FOG\nvar fog: f32=CalcFogFactor();\n#ifdef PBR\nfog=toLinearSpace(fog);\n#endif\ncolor= vec4f(mix(uniforms.vFogColor,color.rgb,fog),color.a);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const fogFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { backgroundUboDeclarationWGSL } from \"./ShadersInclude/backgroundUboDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { reflectionFunctionWGSL } from \"./ShadersInclude/reflectionFunction\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { lightUboDeclarationWGSL } from \"./ShadersInclude/lightUboDeclaration\";\nimport { ltcHelperFunctionsWGSL } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { clusteredLightingFunctionsWGSL } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { clusteredLightingComputeWGSL } from \"./ShadersInclude/clusteredLightingCompute\";\nimport { lightsFragmentFunctionsWGSL } from \"./ShadersInclude/lightsFragmentFunctions\";\nimport { shadowsFragmentFunctionsWGSL } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { intersectionFunctionsWGSL } from \"./ShadersInclude/intersectionFunctions\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { lightFragmentWGSL } from \"./ShadersInclude/lightFragment\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\n\nconst name = \"backgroundPixelShader\";\nconst shader = `#include<backgroundUboDeclaration>\n#include<helperFunctions>\nvarying vPositionW: vec3f;\n#ifdef MAINUV1\nvarying vMainUV1: vec2f;\n#endif \n#ifdef MAINUV2 \nvarying vMainUV2: vec2f; \n#endif \n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#endif\n#ifdef DIFFUSE\n#if DIFFUSEDIRECTUV==1\n#define vDiffuseUV vMainUV1\n#elif DIFFUSEDIRECTUV==2\n#define vDiffuseUV vMainUV2\n#else\nvarying vDiffuseUV: vec2f;\n#endif\nvar diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nvar reflectionSamplerSampler: sampler;var reflectionSampler: texture_cube<f32>;\n#ifdef TEXTURELODSUPPORT\n#else\nvar reflectionLowSamplerSampler: sampler;var reflectionLowSampler: texture_cube<f32>;var reflectionHighSamplerSampler: sampler;var reflectionHighSampler: texture_cube<f32>;\n#endif\n#else\nvar reflectionSamplerSampler: sampler;var reflectionSampler: texture_2d<f32>;\n#ifdef TEXTURELODSUPPORT\n#else\nvar reflectionLowSamplerSampler: sampler;var reflectionLowSampler: texture_2d<f32>;var reflectionHighSamplerSampler: sampler;var reflectionHighSampler: texture_2d<f32>;\n#endif\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE;\n#endif\n#ifndef SHADOWONLY\n#define SHADOWONLY;\n#endif\n#include<imageProcessingDeclaration>\n#include<lightUboDeclaration>[0..maxSimultaneousLights]\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n#include<imageProcessingFunctions>\n#include<logDepthDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<fogFragmentDeclaration>\n#ifdef REFLECTIONFRESNEL\n#define FRESNEL_MAXIMUM_ON_ROUGH 0.25\nfn fresnelSchlickEnvironmentGGX(VdotN: f32,reflectance0: vec3f,reflectance90: vec3f,smoothness: f32)->vec3f\n{var weight: f32=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);return reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));}\n#endif\n#ifdef PROJECTED_GROUND\n#include<intersectionFunctions>\nfn project(viewDirectionW: vec3f,eyePosition: vec3f)->vec3f {var radius: f32=uniforms.projectedGroundInfos.x;var height: f32=uniforms.projectedGroundInfos.y;var camDir: vec3f=-viewDirectionW;var skySphereDistance: f32=sphereIntersectFromOrigin(eyePosition,camDir,radius).x;var skySpherePositionW: vec3f=eyePosition+camDir*skySphereDistance;var p: vec3f=normalize(skySpherePositionW);var upEyePosition=vec3f(eyePosition.x,eyePosition.y-height,eyePosition.z);var sIntersection: f32=sphereIntersectFromOrigin(upEyePosition,p,radius).x;var h: vec3f= vec3f(0.0,-height,0.0);var dIntersection: f32=diskIntersectWithBackFaceCulling(upEyePosition,p,h,radius);p=(upEyePosition+min(sIntersection,dIntersection)*p);return p;}\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvar viewDirectionW: vec3f=normalize(scene.vEyePosition.xyz-input.vPositionW);\n#ifdef NORMAL\nvar normalW: vec3f=normalize(fragmentInputs.vNormalW);\n#else\nvar normalW: vec3f= vec3f(0.0,1.0,0.0);\n#endif\nvar shadow: f32=1.;var globalShadow: f32=0.;var shadowLightCount: f32=0.;var aggShadow: f32=0.;var numLights: f32=0.;\n#include<lightFragment>[0..maxSimultaneousLights]\n#ifdef SHADOWINUSE\nglobalShadow/=shadowLightCount;\n#else\nglobalShadow=1.0;\n#endif\n#ifndef BACKMAT_SHADOWONLY\nvar reflectionColor: vec4f= vec4f(1.,1.,1.,1.);\n#ifdef REFLECTION\n#ifdef PROJECTED_GROUND\nvar reflectionVector: vec3f=project(viewDirectionW,scene.vEyePosition.xyz);reflectionVector= (uniforms.reflectionMatrix*vec4f(reflectionVector,1.)).xyz;\n#else\nvar reflectionVector: vec3f=computeReflectionCoords( vec4f(fragmentInputs.vPositionW,1.0),normalW);\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nvar reflectionCoords: vec3f=reflectionVector;\n#else\nvar reflectionCoords: vec2f=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\n#ifdef REFLECTIONBLUR\nvar reflectionLOD: f32=uniforms.vReflectionInfos.y;\n#ifdef TEXTURELODSUPPORT\nreflectionLOD=reflectionLOD*log2(uniforms.vReflectionMicrosurfaceInfos.x)*uniforms.vReflectionMicrosurfaceInfos.y+uniforms.vReflectionMicrosurfaceInfos.z;reflectionColor=textureSampleLevel(reflectionSampler,reflectionSamplerSampler,reflectionCoords,reflectionLOD);\n#else\nvar lodReflectionNormalized: f32=saturate(reflectionLOD);var lodReflectionNormalizedDoubled: f32=lodReflectionNormalized*2.0;var reflectionSpecularMid: vec4f=textureSample(reflectionSampler,reflectionSamplerSampler,reflectionCoords);if(lodReflectionNormalizedDoubled<1.0){reflectionColor=mix(\ntextureSample(reflectionrHighSampler,reflectionrHighSamplerSampler,reflectionCoords),\nreflectionSpecularMid,\nlodReflectionNormalizedDoubled\n);} else {reflectionColor=mix(\nreflectionSpecularMid,\ntextureSample(reflectionLowSampler,reflectionLowSamplerSampler,reflectionCoords),\nlodReflectionNormalizedDoubled-1.0\n);}\n#endif\n#else\nvar reflectionSample: vec4f=textureSample(reflectionSampler,reflectionSamplerSampler,reflectionCoords);reflectionColor=reflectionSample;\n#endif\n#ifdef RGBDREFLECTION\nreflectionColor=vec4f(fromRGBD(reflectionColor).rgb,reflectionColor.a);\n#endif\n#ifdef GAMMAREFLECTION\nreflectionColor=vec4f(toLinearSpaceVec3(reflectionColor.rgb),reflectionColor.a);\n#endif\n#ifdef REFLECTIONBGR\nreflectionColor=vec4f(reflectionColor.bgr,reflectionColor.a);\n#endif\nreflectionColor=vec4f(reflectionColor.rgb*uniforms.vReflectionInfos.x,reflectionColor.a);\n#endif\nvar diffuseColor: vec3f= vec3f(1.,1.,1.);var finalAlpha: f32=uniforms.alpha;\n#ifdef DIFFUSE\nvar diffuseMap: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,input.vDiffuseUV);\n#ifdef GAMMADIFFUSE\ndiffuseMap=vec4f(toLinearSpaceVec3(diffuseMap.rgb),diffuseMap.a);\n#endif\ndiffuseMap=vec4f(diffuseMap.rgb *uniforms.vDiffuseInfos.y,diffuseMap.a);\n#ifdef DIFFUSEHASALPHA\nfinalAlpha*=diffuseMap.a;\n#endif\ndiffuseColor=diffuseMap.rgb;\n#endif\n#ifdef REFLECTIONFRESNEL\nvar colorBase: vec3f=diffuseColor;\n#else\nvar colorBase: vec3f=reflectionColor.rgb*diffuseColor;\n#endif\ncolorBase=max(colorBase,vec3f(0.0));\n#ifdef USERGBCOLOR\nvar finalColor: vec3f=colorBase;\n#else\n#ifdef USEHIGHLIGHTANDSHADOWCOLORS\nvar mainColor: vec3f=mix(uniforms.vPrimaryColorShadow.rgb,uniforms.vPrimaryColor.rgb,colorBase);\n#else\nvar mainColor: vec3f=uniforms.vPrimaryColor.rgb;\n#endif\nvar finalColor: vec3f=colorBase*mainColor;\n#endif\n#ifdef REFLECTIONFRESNEL\nvar reflectionAmount: vec3f=uniforms.vReflectionControl.xxx;var reflectionReflectance0: vec3f=uniforms.vReflectionControl.yyy;var reflectionReflectance90: vec3f=uniforms.vReflectionControl.zzz;var VdotN: f32=dot(normalize(scene.vEyePosition.xyz),normalW);var planarReflectionFresnel: vec3f=fresnelSchlickEnvironmentGGX(saturate(VdotN),reflectionReflectance0,reflectionReflectance90,1.0);reflectionAmount*=planarReflectionFresnel;\n#ifdef REFLECTIONFALLOFF\nvar reflectionDistanceFalloff: f32=1.0-saturate(length(fragmentInputs.vPositionW.xyz-uniforms.vBackgroundCenter)*uniforms.vReflectionControl.w);reflectionDistanceFalloff*=reflectionDistanceFalloff;reflectionAmount*=reflectionDistanceFalloff;\n#endif\nfinalColor=mix(finalColor,reflectionColor.rgb,saturateVec3(reflectionAmount));\n#endif\n#ifdef OPACITYFRESNEL\nvar viewAngleToFloor: f32=dot(normalW,normalize(scene.vEyePosition.xyz-uniforms.vBackgroundCenter));const startAngle: f32=0.1;var fadeFactor: f32=saturate(viewAngleToFloor/startAngle);finalAlpha*=fadeFactor*fadeFactor;\n#endif\n#ifdef SHADOWINUSE\nfinalColor=mix(finalColor*uniforms.shadowLevel,finalColor,globalShadow);\n#endif\nvar color: vec4f= vec4f(finalColor,finalAlpha);\n#else\nvar color: vec4f= vec4f(uniforms.vPrimaryColor.rgb,(1.0-clamp(globalShadow,0.,1.))*uniforms.alpha);\n#endif\n#include<logDepthFragment>\n#include<fogFragment>\n#ifdef IMAGEPROCESSINGPOSTPROCESS\n#if !defined(SKIPFINALCOLORCLAMP)\ncolor=vec4f(clamp(color.rgb,vec3f(0.),vec3f(30.0)),color.a);\n#endif\n#else\ncolor=applyImageProcessing(color);\n#endif\n#ifdef PREMULTIPLYALPHA\ncolor=vec4f(color.rgb *color.a,color.a);\n#endif\n#ifdef NOISE\ncolor=vec4f(color.rgb+dither(fragmentInputs.vPositionW.xy,0.5),color.a);color=max(color,vec4f(0.0));\n#endif\nfragmentOutputs.color=color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, backgroundUboDeclarationWGSL, helperFunctionsWGSL, reflectionFunctionWGSL, imageProcessingDeclarationWGSL, lightUboDeclarationWGSL, ltcHelperFunctionsWGSL, clusteredLightingFunctionsWGSL, clusteredLightingComputeWGSL, lightsFragmentFunctionsWGSL, shadowsFragmentFunctionsWGSL, imageProcessingFunctionsWGSL, logDepthDeclarationWGSL, clipPlaneFragmentDeclarationWGSL, fogFragmentDeclarationWGSL, intersectionFunctionsWGSL, clipPlaneFragmentWGSL, lightFragmentWGSL, logDepthFragmentWGSL, fogFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const backgroundPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"backgroundVertexDeclaration\";\nconst shader = `uniform mat4 view;uniform mat4 viewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;\n#endif\nuniform float shadowLevel;\n#ifdef DIFFUSE\nuniform mat4 diffuseMatrix;uniform vec2 vDiffuseInfos;\n#endif\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;uniform mat4 reflectionMatrix;uniform vec3 vReflectionMicrosurfaceInfos;uniform float fFovMultiplier;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const backgroundVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nconst name = \"backgroundUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Material\n{uniform vec4 vPrimaryColor;uniform vec4 vPrimaryColorShadow;uniform vec2 vDiffuseInfos;uniform mat4 diffuseMatrix;uniform float fFovMultiplier;uniform float pointSize;uniform float shadowLevel;uniform float alpha;uniform vec3 vBackgroundCenter;uniform vec4 vReflectionControl;uniform vec2 projectedGroundInfos;uniform vec2 vReflectionInfos;uniform mat4 reflectionMatrix;uniform vec3 vReflectionMicrosurfaceInfos;};\n#include<sceneUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const backgroundUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogVertexDeclaration\";\nconst shader = `#ifdef FOG\nvarying vec3 vFogDistance;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const fogVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightVxFragmentDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nuniform vec4 vLightData{X};uniform vec4 vLightDiffuse{X};\n#ifdef SPECULARTERM\nuniform vec4 vLightSpecular{X};\n#else\nvec4 vLightSpecular{X}=vec4(0.);\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform mat4 lightMatrix{X}[SHADOWCSMNUM_CASCADES{X}];varying vec4 vPositionFromLight{X}[SHADOWCSMNUM_CASCADES{X}];varying float vDepthMetric{X}[SHADOWCSMNUM_CASCADES{X}];varying vec4 vPositionFromCamera{X};\n#elif defined(SHADOWCUBE{X})\n#else\nvarying vec4 vPositionFromLight{X};varying float vDepthMetric{X};uniform mat4 lightMatrix{X};\n#endif\nuniform vec4 shadowsInfo{X};uniform vec2 depthValues{X};\n#endif\n#ifdef SPOTLIGHT{X}\nuniform vec4 vLightDirection{X};uniform vec4 vLightFalloff{X};\n#elif defined(POINTLIGHT{X})\nuniform vec4 vLightFalloff{X};\n#elif defined(HEMILIGHT{X})\nuniform vec3 vLightGround{X};\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nuniform vec4 vLightWidth{X};uniform vec4 vLightHeight{X};\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lightVxFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightVxUboDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nuniform Light{X}\n{vec4 vLightData;vec4 vLightDiffuse;vec4 vLightSpecular;\n#ifdef SPOTLIGHT{X}\nvec4 vLightDirection;vec4 vLightFalloff;\n#elif defined(POINTLIGHT{X})\nvec4 vLightFalloff;\n#elif defined(HEMILIGHT{X})\nvec3 vLightGround;\n#elif defined(CLUSTLIGHT{X})\nvec2 vSliceData;vec2 vSliceRanges[CLUSTLIGHT_SLICES];\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvec4 vLightWidth;vec4 vLightHeight;\n#endif\nvec4 shadowsInfo;vec2 depthValues;} light{X};\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform mat4 lightMatrix{X}[SHADOWCSMNUM_CASCADES{X}];varying vec4 vPositionFromLight{X}[SHADOWCSMNUM_CASCADES{X}];varying float vDepthMetric{X}[SHADOWCSMNUM_CASCADES{X}];varying vec4 vPositionFromCamera{X};\n#elif defined(SHADOWCUBE{X})\n#else\nvarying vec4 vPositionFromLight{X};varying float vDepthMetric{X};uniform mat4 lightMatrix{X};\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lightVxUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"logDepthDeclaration\";\nconst shader = `#ifdef LOGARITHMICDEPTH\nuniform float logarithmicDepthConstant;varying float vFragmentDepth;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const logDepthDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogVertex\";\nconst shader = `#ifdef FOG\nvFogDistance=(view*worldPos).xyz;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const fogVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowsVertex\";\nconst shader = `#ifdef SHADOWS\n#if defined(SHADOWCSM{X})\nvPositionFromCamera{X}=view*worldPos;for (int i=0; i<SHADOWCSMNUM_CASCADES{X}; i++) {vPositionFromLight{X}[i]=lightMatrix{X}[i]*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvDepthMetric{X}[i]=(-vPositionFromLight{X}[i].z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvDepthMetric{X}[i]=(vPositionFromLight{X}[i].z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n}\n#elif defined(SHADOW{X}) && !defined(SHADOWCUBE{X})\nvPositionFromLight{X}=lightMatrix{X}*worldPos;\n#ifdef USE_REVERSE_DEPTHBUFFER\nvDepthMetric{X}=(-vPositionFromLight{X}.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#else\nvDepthMetric{X}=(vPositionFromLight{X}.z+light{X}.depthValues.x)/light{X}.depthValues.y;\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowsVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"logDepthVertex\";\nconst shader = `#ifdef LOGARITHMICDEPTH\nvFragmentDepth=1.0+gl_Position.w;gl_Position.z=log2(max(0.000001,vFragmentDepth))*logarithmicDepthConstant;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const logDepthVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { backgroundVertexDeclaration } from \"./ShadersInclude/backgroundVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { backgroundUboDeclaration } from \"./ShadersInclude/backgroundUboDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxFragmentDeclaration } from \"./ShadersInclude/lightVxFragmentDeclaration\";\nimport { lightVxUboDeclaration } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertex } from \"./ShadersInclude/shadowsVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"backgroundVertexShader\";\nconst shader = `precision highp float;\n#include<__decl__backgroundVertex>\n#include<helperFunctions>\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV==0\nvarying vec2 vDiffuseUV;\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightVxFragment>[0..maxSimultaneousLights]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef REFLECTIONMAP_SKYBOX\nvPositionUVW=position;\n#endif\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {gl_Position=viewProjection*finalWorld*vec4(position,1.0);} else {gl_Position=viewProjectionR*finalWorld*vec4(position,1.0);}\n#else\ngl_Position=viewProjection*finalWorld*vec4(position,1.0);\n#endif\nvec4 worldPos=finalWorld*vec4(position,1.0);vPositionW=vec3(worldPos);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normal);\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(position,0.0)));\n#ifdef EQUIRECTANGULAR_RELFECTION_FOV\nmat3 screenToWorld=inverseMat3(mat3(finalWorld*viewProjection));vec3 segment=mix(vDirectionW,screenToWorld*vec3(0.0,0.0,1.0),abs(fFovMultiplier-1.0));if (fFovMultiplier<=1.0) {vDirectionW=normalize(segment);} else {vDirectionW=normalize(vDirectionW+(vDirectionW-segment));}\n#endif\n#endif\n#ifndef UV1\nvec2 uv=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uv;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV==0\nif (vDiffuseInfos.x==0.)\n{vDiffuseUV=vec2(diffuseMatrix*vec4(uv,1.0,0.0));}\nelse\n{vDiffuseUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));}\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#ifdef VERTEXCOLOR\nvColor=colorUpdated;\n#endif\n#if defined(POINTSIZE) && !defined(WEBGPU)\ngl_PointSize=pointSize;\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [backgroundVertexDeclaration, sceneUboDeclaration, backgroundUboDeclaration, helperFunctions, bonesDeclaration, bakedVertexAnimationDeclaration, instancesDeclaration, clipPlaneVertexDeclaration, fogVertexDeclaration, lightVxFragmentDeclaration, lightVxUboDeclaration, logDepthDeclaration, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex, fogVertex, shadowsVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const backgroundVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"backgroundFragmentDeclaration\";\nconst shader = `uniform vec4 vEyePosition;uniform vec4 vPrimaryColor;\n#ifdef USEHIGHLIGHTANDSHADOWCOLORS\nuniform vec4 vPrimaryColorShadow;\n#endif\nuniform float shadowLevel;uniform float alpha;\n#ifdef DIFFUSE\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;uniform mat4 reflectionMatrix;uniform vec3 vReflectionMicrosurfaceInfos;\n#endif\n#if defined(REFLECTIONFRESNEL) || defined(OPACITYFRESNEL)\nuniform vec3 vBackgroundCenter;\n#endif\n#ifdef REFLECTIONFRESNEL\nuniform vec4 vReflectionControl;\n#endif\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(REFRACTION)\nuniform mat4 view;\n#endif\n#ifdef PROJECTED_GROUND\nuniform vec2 projectedGroundInfos;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const backgroundFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"reflectionFunction\";\nconst shader = `vec3 computeFixedEquirectangularCoords(vec4 worldPos,vec3 worldNormal,vec3 direction)\n{float lon=atan(direction.z,direction.x);float lat=acos(direction.y);vec2 sphereCoords=vec2(lon,lat)*RECIPROCAL_PI2*2.0;float s=sphereCoords.x*0.5+0.5;float t=sphereCoords.y;return vec3(s,t,0); }\nvec3 computeMirroredFixedEquirectangularCoords(vec4 worldPos,vec3 worldNormal,vec3 direction)\n{float lon=atan(direction.z,direction.x);float lat=acos(direction.y);vec2 sphereCoords=vec2(lon,lat)*RECIPROCAL_PI2*2.0;float s=sphereCoords.x*0.5+0.5;float t=sphereCoords.y;return vec3(1.0-s,t,0); }\nvec3 computeEquirectangularCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix)\n{vec3 cameraToVertex=normalize(worldPos.xyz-eyePosition);vec3 r=normalize(reflect(cameraToVertex,worldNormal));r=vec3(reflectionMatrix*vec4(r,0));float lon=atan(r.z,r.x);float lat=acos(r.y);vec2 sphereCoords=vec2(lon,lat)*RECIPROCAL_PI2*2.0;float s=sphereCoords.x*0.5+0.5;float t=sphereCoords.y;return vec3(s,t,0);}\nvec3 computeSphericalCoords(vec4 worldPos,vec3 worldNormal,mat4 view,mat4 reflectionMatrix)\n{vec3 viewDir=normalize(vec3(view*worldPos));vec3 viewNormal=normalize(vec3(view*vec4(worldNormal,0.0)));vec3 r=reflect(viewDir,viewNormal);r=vec3(reflectionMatrix*vec4(r,0));r.z=r.z-1.0;float m=2.0*length(r);return vec3(r.x/m+0.5,1.0-r.y/m-0.5,0);}\nvec3 computePlanarCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix)\n{vec3 viewDir=worldPos.xyz-eyePosition;vec3 coords=normalize(reflect(viewDir,worldNormal));return vec3(reflectionMatrix*vec4(coords,1));}\nvec3 computeCubicCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix)\n{vec3 viewDir=normalize(worldPos.xyz-eyePosition);vec3 coords=reflect(viewDir,worldNormal);coords=vec3(reflectionMatrix*vec4(coords,0));\n#ifdef INVERTCUBICMAP\ncoords.y*=-1.0;\n#endif\nreturn coords;}\nvec3 computeCubicLocalCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix,vec3 reflectionSize,vec3 reflectionPosition)\n{vec3 viewDir=normalize(worldPos.xyz-eyePosition);vec3 coords=reflect(viewDir,worldNormal);coords=parallaxCorrectNormal(worldPos.xyz,coords,reflectionSize,reflectionPosition);coords=vec3(reflectionMatrix*vec4(coords,0));\n#ifdef INVERTCUBICMAP\ncoords.y*=-1.0;\n#endif\nreturn coords;}\nvec3 computeProjectionCoords(vec4 worldPos,mat4 view,mat4 reflectionMatrix)\n{return vec3(reflectionMatrix*(view*worldPos));}\nvec3 computeSkyBoxCoords(vec3 positionW,mat4 reflectionMatrix)\n{return vec3(reflectionMatrix*vec4(positionW,1.));}\n#ifdef REFLECTION\nvec3 computeReflectionCoords(vec4 worldPos,vec3 worldNormal)\n{\n#ifdef REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED\nvec3 direction=normalize(vDirectionW);return computeMirroredFixedEquirectangularCoords(worldPos,worldNormal,direction);\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED\nvec3 direction=normalize(vDirectionW);return computeFixedEquirectangularCoords(worldPos,worldNormal,direction);\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR\nreturn computeEquirectangularCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_SPHERICAL\nreturn computeSphericalCoords(worldPos,worldNormal,view,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_PLANAR\nreturn computePlanarCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_CUBIC\n#ifdef USE_LOCAL_REFLECTIONMAP_CUBIC\nreturn computeCubicLocalCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix,vReflectionSize,vReflectionPosition);\n#else\nreturn computeCubicCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix);\n#endif\n#endif\n#ifdef REFLECTIONMAP_PROJECTION\nreturn computeProjectionCoords(worldPos,view,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nreturn computeSkyBoxCoords(vPositionUVW,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_EXPLICIT\nreturn vec3(0,0,0);\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const reflectionFunction = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"imageProcessingDeclaration\";\nconst shader = `#ifdef EXPOSURE\nuniform float exposureLinear;\n#endif\n#ifdef CONTRAST\nuniform float contrast;\n#endif\n#ifdef WHITEBALANCE\nuniform mat3 whiteBalanceMatrix;\n#endif\n#if defined(VIGNETTE) || defined(DITHER)\nuniform vec2 vInverseScreenSize;\n#endif\n#ifdef VIGNETTE\nuniform vec4 vignetteSettings1;uniform vec4 vignetteSettings2;\n#endif\n#ifdef COLORCURVES\nuniform vec4 vCameraColorCurveNegative;uniform vec4 vCameraColorCurveNeutral;uniform vec4 vCameraColorCurvePositive;\n#endif\n#ifdef COLORGRADING\n#ifdef COLORGRADING3D\nuniform highp sampler3D txColorTransform;\n#else\nuniform sampler2D txColorTransform;\n#endif\nuniform vec4 colorTransformSettings;\n#endif\n#ifdef DITHER\nuniform float ditherIntensity;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const imageProcessingDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightFragmentDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nuniform vec4 vLightData{X};uniform vec4 vLightDiffuse{X};\n#ifdef SPECULARTERM\nuniform vec4 vLightSpecular{X};\n#else\nvec4 vLightSpecular{X}=vec4(0.);\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform mat4 lightMatrix{X}[SHADOWCSMNUM_CASCADES{X}];uniform float viewFrustumZ{X}[SHADOWCSMNUM_CASCADES{X}];uniform float frustumLengths{X}[SHADOWCSMNUM_CASCADES{X}];uniform float cascadeBlendFactor{X};varying vec4 vPositionFromLight{X}[SHADOWCSMNUM_CASCADES{X}];varying float vDepthMetric{X}[SHADOWCSMNUM_CASCADES{X}];varying vec4 vPositionFromCamera{X};\n#if defined(SHADOWPCSS{X})\nuniform highp sampler2DArrayShadow shadowTexture{X};uniform highp sampler2DArray depthTexture{X};uniform vec2 lightSizeUVCorrection{X}[SHADOWCSMNUM_CASCADES{X}];uniform float depthCorrection{X}[SHADOWCSMNUM_CASCADES{X}];uniform float penumbraDarkness{X};\n#elif defined(SHADOWPCF{X})\nuniform highp sampler2DArrayShadow shadowTexture{X};\n#else\nuniform highp sampler2DArray shadowTexture{X};\n#endif\n#ifdef SHADOWCSMDEBUG{X}\nconst vec3 vCascadeColorsMultiplier{X}[8]=vec3[8]\n(\nvec3 ( 1.5,0.0,0.0 ),\nvec3 ( 0.0,1.5,0.0 ),\nvec3 ( 0.0,0.0,5.5 ),\nvec3 ( 1.5,0.0,5.5 ),\nvec3 ( 1.5,1.5,0.0 ),\nvec3 ( 1.0,1.0,1.0 ),\nvec3 ( 0.0,1.0,5.5 ),\nvec3 ( 0.5,3.5,0.75 )\n);vec3 shadowDebug{X};\n#endif\n#ifdef SHADOWCSMUSESHADOWMAXZ{X}\nint index{X}=-1;\n#else\nint index{X}=SHADOWCSMNUM_CASCADES{X}-1;\n#endif\nfloat diff{X}=0.;\n#elif defined(SHADOWCUBE{X})\nuniform samplerCube shadowTexture{X};\n#else\nvarying vec4 vPositionFromLight{X};varying float vDepthMetric{X};\n#if defined(SHADOWPCSS{X})\nuniform highp sampler2DShadow shadowTexture{X};uniform highp sampler2D depthTexture{X};\n#elif defined(SHADOWPCF{X})\nuniform highp sampler2DShadow shadowTexture{X};\n#else\nuniform sampler2D shadowTexture{X};\n#endif\nuniform mat4 lightMatrix{X};\n#endif\nuniform vec4 shadowsInfo{X};uniform vec2 depthValues{X};\n#endif\n#ifdef SPOTLIGHT{X}\nuniform vec4 vLightDirection{X};uniform vec4 vLightFalloff{X};\n#elif defined(POINTLIGHT{X})\nuniform vec4 vLightFalloff{X};\n#elif defined(HEMILIGHT{X})\nuniform vec3 vLightGround{X};\n#endif\n#ifdef AREALIGHT{X}\nuniform vec4 vLightWidth{X};uniform vec4 vLightHeight{X};\n#ifdef RECTAREALIGHTEMISSIONTEXTURE{X}\nuniform sampler2D rectAreaLightEmissionTexture{X};\n#endif\n#endif\n#ifdef IESLIGHTTEXTURE{X}\nuniform sampler2D iesLightTexture{X};\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nuniform mat4 textureProjectionMatrix{X};uniform sampler2D projectionLightTexture{X};\n#endif\n#ifdef CLUSTLIGHT{X}\nuniform vec2 vSliceData{X};uniform vec2 vSliceRanges{X}[CLUSTLIGHT_SLICES];uniform sampler2D lightDataTexture{X};uniform highp sampler2D tileMaskTexture{X};\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lightFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightUboDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nuniform Light{X}\n{vec4 vLightData;vec4 vLightDiffuse;vec4 vLightSpecular;\n#ifdef SPOTLIGHT{X}\nvec4 vLightDirection;vec4 vLightFalloff;\n#elif defined(POINTLIGHT{X})\nvec4 vLightFalloff;\n#elif defined(HEMILIGHT{X})\nvec3 vLightGround;\n#elif defined(CLUSTLIGHT{X})\nvec2 vSliceData;vec2 vSliceRanges[CLUSTLIGHT_SLICES];\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvec4 vLightWidth;vec4 vLightHeight;\n#endif\nvec4 shadowsInfo;vec2 depthValues;} light{X};\n#ifdef IESLIGHTTEXTURE{X}\nuniform sampler2D iesLightTexture{X};\n#endif\n#ifdef RECTAREALIGHTEMISSIONTEXTURE{X}\nuniform sampler2D rectAreaLightEmissionTexture{X};\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nuniform mat4 textureProjectionMatrix{X};uniform sampler2D projectionLightTexture{X};\n#endif\n#ifdef CLUSTLIGHT{X}\nuniform sampler2D lightDataTexture{X};uniform highp sampler2D tileMaskTexture{X};\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform mat4 lightMatrix{X}[SHADOWCSMNUM_CASCADES{X}];uniform float viewFrustumZ{X}[SHADOWCSMNUM_CASCADES{X}];uniform float frustumLengths{X}[SHADOWCSMNUM_CASCADES{X}];uniform float cascadeBlendFactor{X};varying vec4 vPositionFromLight{X}[SHADOWCSMNUM_CASCADES{X}];varying float vDepthMetric{X}[SHADOWCSMNUM_CASCADES{X}];varying vec4 vPositionFromCamera{X};\n#if defined(SHADOWPCSS{X})\nuniform highp sampler2DArrayShadow shadowTexture{X};uniform highp sampler2DArray depthTexture{X};uniform vec2 lightSizeUVCorrection{X}[SHADOWCSMNUM_CASCADES{X}];uniform float depthCorrection{X}[SHADOWCSMNUM_CASCADES{X}];uniform float penumbraDarkness{X};\n#elif defined(SHADOWPCF{X})\nuniform highp sampler2DArrayShadow shadowTexture{X};\n#else\nuniform highp sampler2DArray shadowTexture{X};\n#endif\n#ifdef SHADOWCSMDEBUG{X}\nconst vec3 vCascadeColorsMultiplier{X}[8]=vec3[8]\n(\nvec3 ( 1.5,0.0,0.0 ),\nvec3 ( 0.0,1.5,0.0 ),\nvec3 ( 0.0,0.0,5.5 ),\nvec3 ( 1.5,0.0,5.5 ),\nvec3 ( 1.5,1.5,0.0 ),\nvec3 ( 1.0,1.0,1.0 ),\nvec3 ( 0.0,1.0,5.5 ),\nvec3 ( 0.5,3.5,0.75 )\n);vec3 shadowDebug{X};\n#endif\n#ifdef SHADOWCSMUSESHADOWMAXZ{X}\nint index{X}=-1;\n#else\nint index{X}=SHADOWCSMNUM_CASCADES{X}-1;\n#endif\nfloat diff{X}=0.;\n#elif defined(SHADOWCUBE{X})\nuniform samplerCube shadowTexture{X}; \n#else\nvarying vec4 vPositionFromLight{X};varying float vDepthMetric{X};\n#if defined(SHADOWPCSS{X})\nuniform highp sampler2DShadow shadowTexture{X};uniform highp sampler2D depthTexture{X};\n#elif defined(SHADOWPCF{X})\nuniform highp sampler2DShadow shadowTexture{X};\n#else\nuniform sampler2D shadowTexture{X};\n#endif\nuniform mat4 lightMatrix{X};\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lightUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"ltcHelperFunctions\";\nconst shader = `vec2 LTCUv( const in vec3 N,const in vec3 V,const in float roughness ) {const float LUTSIZE=64.0;const float LUTSCALE=( LUTSIZE-1.0 )/LUTSIZE;const float LUTBIAS=0.5/LUTSIZE;float dotNV=saturate( dot( N,V ) );vec2 uv=vec2( roughness,sqrt( 1.0-dotNV ) );uv=uv*LUTSCALE+LUTBIAS;return uv;}\nfloat LTCClippedSphereFormFactor( const in vec3 f ) {float l=length( f );return max( ( l*l+f.z )/( l+1.0 ),0.0 );}\nvec3 LTCEdgeVectorFormFactor( const in vec3 v1,const in vec3 v2 ) {float x=dot( v1,v2 );float y=abs( x );float a=0.8543985+( 0.4965155+0.0145206*y )*y;float b=3.4175940+( 4.1616724+y )*y;float v=a/b;float thetaSintheta=0.0;if( x>0.0 )\n{thetaSintheta=v;}\nelse\n{thetaSintheta=0.5*inversesqrt( max( 1.0-x*x,1e-7 ) )-v;}\nreturn cross( v1,v2 )*thetaSintheta;}\nvec3 LTCEvaluate( const in vec3 N,const in vec3 V,const in vec3 P,const in mat3 mInv,const in vec3 rectCoords[ 4 ] ) {vec3 v1=rectCoords[ 1 ]-rectCoords[ 0 ];vec3 v2=rectCoords[ 3 ]-rectCoords[ 0 ];vec3 lightNormal=cross( v1,v2 );if( dot( lightNormal,P-rectCoords[ 0 ] )<0.0 ) return vec3( 0.0 );vec3 T1,T2;T1=normalize( V-N*dot( V,N ) );T2=- cross( N,T1 ); \nmat3 mat=mInv*transposeMat3( mat3( T1,T2,N ) );vec3 coords[ 4 ];coords[ 0 ]=mat*( rectCoords[ 0 ]-P );coords[ 1 ]=mat*( rectCoords[ 1 ]-P );coords[ 2 ]=mat*( rectCoords[ 2 ]-P );coords[ 3 ]=mat*( rectCoords[ 3 ]-P );coords[ 0 ]=normalize( coords[ 0 ] );coords[ 1 ]=normalize( coords[ 1 ] );coords[ 2 ]=normalize( coords[ 2 ] );coords[ 3 ]=normalize( coords[ 3 ] );vec3 vectorFormFactor=vec3( 0.0 );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 0 ],coords[ 1 ] );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 1 ],coords[ 2 ] );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 2 ],coords[ 3 ] );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 3 ],coords[ 0 ] );float result=LTCClippedSphereFormFactor( vectorFormFactor );return vec3( result );}\nvec3 FetchDiffuseFilteredTexture(sampler2D texLightFiltered,vec3 p1_,vec3 p2_,vec3 p3_,vec3 p4_)\n{vec3 V1=p2_-p1_;vec3 V2=p4_-p1_;vec3 planeOrtho=(cross(V1,V2));float planeAreaSquared=dot(planeOrtho,planeOrtho);float planeDistxPlaneArea=dot(planeOrtho,p1_);vec3 P=planeDistxPlaneArea*planeOrtho/planeAreaSquared-p1_;float dot_V1_V2=dot(V1,V2);float inv_dot_V1_V1=1.0/dot(V1,V1);vec3 V2_=V2-V1*dot_V1_V2*inv_dot_V1_V1;vec2 Puv;Puv.y=dot(V2_,P)/dot(V2_,V2_);Puv.x=dot(V1,P)*inv_dot_V1_V1-dot_V1_V2*inv_dot_V1_V1*Puv.y ;float d=abs(planeDistxPlaneArea)/pow(planeAreaSquared,0.75);float sampleLOD=log(2048.0*d)/log(3.0);vec2 sampleUV=vec2(0.125,0.125)+(vec2(0.75)*Puv);sampleUV.x=1.0-sampleUV.x;return texture2DLodEXT(texLightFiltered,sampleUV,sampleLOD).rgb;}\nvec3 LTCEvaluateWithEmission( const in vec3 N,const in vec3 V,const in vec3 P,const in mat3 mInv,const in vec3 rectCoords[ 4 ],const in sampler2D texFilteredMap ) {vec3 v1=rectCoords[ 1 ]-rectCoords[ 0 ];vec3 v2=rectCoords[ 3 ]-rectCoords[ 0 ];vec3 lightNormal=cross( v1,v2 );if( dot( lightNormal,P-rectCoords[ 0 ] )<0.0 ) return vec3( 0.0 );vec3 T1,T2;T1=normalize( V-N*dot( V,N ) );T2=- cross( N,T1 ); \nmat3 mat=mInv*transposeMat3( mat3( T1,T2,N ) );vec3 coords[ 4 ];coords[ 0 ]=mat*( rectCoords[ 0 ]-P );coords[ 1 ]=mat*( rectCoords[ 1 ]-P );coords[ 2 ]=mat*( rectCoords[ 2 ]-P );coords[ 3 ]=mat*( rectCoords[ 3 ]-P );vec3 textureLight=FetchDiffuseFilteredTexture(texFilteredMap,coords[0],coords[1],coords[2],coords[3]);coords[ 0 ]=normalize( coords[ 0 ] );coords[ 1 ]=normalize( coords[ 1 ] );coords[ 2 ]=normalize( coords[ 2 ] );coords[ 3 ]=normalize( coords[ 3 ] );vec3 vectorFormFactor=vec3( 0.0 );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 0 ],coords[ 1 ] );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 1 ],coords[ 2 ] );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 2 ],coords[ 3 ] );vectorFormFactor+=LTCEdgeVectorFormFactor( coords[ 3 ],coords[ 0 ] );float result=LTCClippedSphereFormFactor( vectorFormFactor );return vec3( result )*textureLight;}\nstruct areaLightData\n{vec3 Diffuse;vec3 Specular;vec4 Fresnel;};\n#define inline\nareaLightData computeAreaLightSpecularDiffuseFresnel(const in sampler2D ltc1,const in sampler2D ltc2,const in vec3 viewDir,const in vec3 normal,const in vec3 position,const in vec3 lightPos,const in vec3 halfWidth,const in vec3 halfHeight,const in float roughness) \n{areaLightData result;vec3 rectCoords[ 4 ];rectCoords[ 0 ]=lightPos+halfWidth-halfHeight; \nrectCoords[ 1 ]=lightPos-halfWidth-halfHeight;rectCoords[ 2 ]=lightPos-halfWidth+halfHeight;rectCoords[ 3 ]=lightPos+halfWidth+halfHeight;\n#ifdef SPECULARTERM\nvec2 uv=LTCUv( normal,viewDir,roughness );vec4 t1=texture2D( ltc1,uv );vec4 t2=texture2D( ltc2,uv );mat3 mInv=mat3(\nvec3( t1.x,0,t1.y ),\nvec3( 0,1, 0 ),\nvec3( t1.z,0,t1.w )\n);result.Specular=LTCEvaluate( normal,viewDir,position,mInv,rectCoords );result.Fresnel=t2;\n#endif\nresult.Diffuse=LTCEvaluate( normal,viewDir,position,mat3( 1.0 ),rectCoords );return result;}\n#define inline\nareaLightData computeAreaLightSpecularDiffuseFresnelWithEmission(const in sampler2D ltc1,const in sampler2D ltc2,const in sampler2D texFilteredMap,const in vec3 viewDir,const in vec3 normal,const in vec3 position,const in vec3 lightPos,const in vec3 halfWidth,const in vec3 halfHeight,const in float roughness) \n{areaLightData result;vec3 rectCoords[ 4 ];rectCoords[ 0 ]=lightPos+halfWidth-halfHeight; \nrectCoords[ 1 ]=lightPos-halfWidth-halfHeight;rectCoords[ 2 ]=lightPos-halfWidth+halfHeight;rectCoords[ 3 ]=lightPos+halfWidth+halfHeight;\n#ifdef SPECULARTERM\nvec2 uv=LTCUv( normal,viewDir,roughness );vec4 t1=texture2D( ltc1,uv );vec4 t2=texture2D( ltc2,uv );mat3 mInv=mat3(\nvec3( t1.x,0,t1.y ),\nvec3( 0,1, 0 ),\nvec3( t1.z,0,t1.w )\n);result.Specular=LTCEvaluateWithEmission( normal,viewDir,position,mInv,rectCoords,texFilteredMap );result.Fresnel=t2;\n#endif\nresult.Diffuse=LTCEvaluateWithEmission( normal,viewDir,position,mat3( 1.0 ),rectCoords,texFilteredMap );return result;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const ltcHelperFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./ltcHelperFunctions\";\nimport \"./clusteredLightingFunctions\";\nconst name = \"lightsFragmentFunctions\";\nconst shader = `struct lightingInfo\n{vec3 diffuse;\n#ifdef SPECULARTERM\nvec3 specular;\n#endif\n#ifdef NDOTL\nfloat ndl;\n#endif\n};lightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {lightingInfo result;vec3 lightVectorW;float attenuation=1.0;if (lightData.w==0.)\n{vec3 direction=lightData.xyz-vPositionW;attenuation=max(0.,1.0-length(direction)/range);lightVectorW=normalize(direction);}\nelse\n{lightVectorW=normalize(-lightData.xyz);}\nfloat ndl=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\nvec3 angleW=normalize(viewDirectionW+lightVectorW);float specComp=max(0.,dot(vNormal,angleW));specComp=pow(specComp,max(1.,glossiness));result.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;}\nfloat getAttenuation(float cosAngle,float exponent) {return max(0.,pow(cosAngle,exponent));}\nfloat getIESAttenuation(float cosAngle,sampler2D iesLightSampler) {float angle=acos(cosAngle)/PI;return texture2D(iesLightSampler,vec2(angle,0.)).r;}\nlightingInfo basicSpotLighting(vec3 viewDirectionW,vec3 lightVectorW,vec3 vNormal,float attenuation,vec3 diffuseColor,vec3 specularColor,float glossiness) {lightingInfo result; \nfloat ndl=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\nvec3 angleW=normalize(viewDirectionW+lightVectorW);float specComp=max(0.,dot(vNormal,angleW));specComp=pow(specComp,max(1.,glossiness));result.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;}\nlightingInfo computeIESSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness,sampler2D iesLightSampler) { \nvec3 direction=lightData.xyz-vPositionW;vec3 lightVectorW=normalize(direction);float attenuation=max(0.,1.0-length(direction)/range);float dotProduct=dot(lightDirection.xyz,-lightVectorW);float cosAngle=max(0.,dotProduct);if (cosAngle>=lightDirection.w)\n{ \nattenuation*=getIESAttenuation(dotProduct,iesLightSampler);return basicSpotLighting(viewDirectionW,lightVectorW,vNormal,attenuation,diffuseColor,specularColor,glossiness);}\nlightingInfo result;result.diffuse=vec3(0.);\n#ifdef SPECULARTERM\nresult.specular=vec3(0.);\n#endif\n#ifdef NDOTL\nresult.ndl=0.;\n#endif\nreturn result;}\nlightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {vec3 direction=lightData.xyz-vPositionW;vec3 lightVectorW=normalize(direction);float attenuation=max(0.,1.0-length(direction)/range);float cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));if (cosAngle>=lightDirection.w)\n{ \nattenuation*=getAttenuation(cosAngle,lightData.w);return basicSpotLighting(viewDirectionW,lightVectorW,vNormal,attenuation,diffuseColor,specularColor,glossiness);}\nlightingInfo result;result.diffuse=vec3(0.);\n#ifdef SPECULARTERM\nresult.specular=vec3(0.);\n#endif\n#ifdef NDOTL\nresult.ndl=0.;\n#endif\nreturn result;}\nlightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {lightingInfo result;float ndl=dot(vNormal,lightData.xyz)*0.5+0.5;\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=mix(groundColor,diffuseColor,ndl);\n#ifdef SPECULARTERM\nvec3 angleW=normalize(viewDirectionW+lightData.xyz);float specComp=max(0.,dot(vNormal,angleW));specComp=pow(specComp,max(1.,glossiness));result.specular=specComp*specularColor;\n#endif\nreturn result;}\n#define inline\nvec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler,mat4 textureProjectionMatrix,vec3 posW){vec4 strq=textureProjectionMatrix*vec4(posW,1.0);strq/=strq.w;vec3 textureColor=texture2D(projectionLightSampler,strq.xy).rgb;return textureColor;}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#include<ltcHelperFunctions>\nuniform sampler2D areaLightsLTC1Sampler;uniform sampler2D areaLightsLTC2Sampler;\n#define inline\nlightingInfo computeAreaLighting(sampler2D ltc1,sampler2D ltc2,vec3 viewDirectionW,vec3 vNormal,vec3 vPosition,vec3 lightPosition,vec3 halfWidth,vec3 halfHeight,vec3 diffuseColor,vec3 specularColor,float roughness) \n{lightingInfo result;areaLightData data=computeAreaLightSpecularDiffuseFresnel(ltc1,ltc2,viewDirectionW,vNormal,vPosition,lightPosition,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nvec3 fresnel=( specularColor*data.Fresnel.x+( vec3( 1.0 )-specularColor )*data.Fresnel.y );result.specular+=specularColor*fresnel*data.Specular;\n#endif\nresult.diffuse+=diffuseColor*data.Diffuse;return result;}\nlightingInfo computeAreaLightingWithTexture(sampler2D ltc1,sampler2D ltc2,sampler2D emissionTexture,vec3 viewDirectionW,vec3 vNormal,vec3 vPosition,vec3 lightPosition,vec3 halfWidth,vec3 halfHeight,vec3 diffuseColor,vec3 specularColor,float roughness) \n{lightingInfo result;areaLightData data=computeAreaLightSpecularDiffuseFresnelWithEmission(ltc1,ltc2,emissionTexture,viewDirectionW,vNormal,vPosition,lightPosition,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nvec3 fresnel=( specularColor*data.Fresnel.x+( vec3( 1.0 )-specularColor )*data.Fresnel.y );result.specular+=specularColor*fresnel*data.Specular;\n#endif\nresult.diffuse+=diffuseColor*data.Diffuse;return result;}\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#include<clusteredLightingFunctions>\n#define inline\nlightingInfo computeClusteredLighting(\nsampler2D lightDataTexture,\nsampler2D tileMaskTexture,\nvec3 viewDirectionW,\nvec3 vNormal,\nvec4 lightData,\nivec2 sliceRange,\nfloat glossiness\n) {lightingInfo result;ivec2 tilePosition=ivec2(gl_FragCoord.xy*lightData.xy);int maskHeight=int(lightData.z);tilePosition.y=min(tilePosition.y,maskHeight-1);ivec2 batchRange=sliceRange/CLUSTLIGHT_BATCH;int batchOffset=batchRange.x*CLUSTLIGHT_BATCH;tilePosition.y+=maskHeight*batchRange.x;for (int i=batchRange.x; i<=batchRange.y; i+=1) {uint mask=uint(texelFetch(tileMaskTexture,tilePosition,0).r);tilePosition.y+=maskHeight;int maskOffset=max(sliceRange.x-batchOffset,0);int maskWidth=min(sliceRange.y-batchOffset+1,CLUSTLIGHT_BATCH);mask=extractBits(mask,maskOffset,maskWidth);while (mask != 0u) {uint bit=mask & -mask;mask ^= bit;int position=onlyBitPosition(bit);ClusteredLight light=getClusteredLight(lightDataTexture,batchOffset+maskOffset+position);lightingInfo info;if (light.vLightDirection.w<0.0) {info=computeLighting(viewDirectionW,vNormal,light.vLightData,light.vLightDiffuse.rgb,light.vLightSpecular.rgb,light.vLightDiffuse.a,glossiness);} else {info=computeSpotLighting(viewDirectionW,vNormal,light.vLightData,light.vLightDirection,light.vLightDiffuse.rgb,light.vLightSpecular.rgb,light.vLightDiffuse.a,glossiness);}\nresult.diffuse+=info.diffuse;\n#ifdef SPECULARTERM\nresult.specular+=info.specular;\n#endif\n}\nbatchOffset+=CLUSTLIGHT_BATCH;}\nreturn result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lightsFragmentFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"shadowsFragmentFunctions\";\nconst shader = `#ifdef SHADOWS\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,l) texture2DLodEXT(s,c,l)\n#else\n#define TEXTUREFUNC(s,c,b) texture2D(s,c,b)\n#endif\n#ifndef SHADOWFLOAT\nfloat unpack(vec4 color)\n{const vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);return dot(color,bit_shift);}\n#endif\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{float mask=smoothstep(1.0-frustumEdgeFalloff,1.00000012,clamp(dot(clipSpace,clipSpace),0.,1.));return mix(value,1.0,mask);}\n#define inline\nfloat computeShadowCube(vec3 worldPos,vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{vec3 directionToLight=worldPos-lightPosition;float depth=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);depth=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nreturn depth>shadow ? darkness : 1.0;}\n#define inline\nfloat computeShadowWithPoissonSamplingCube(vec3 worldPos,vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{vec3 directionToLight=worldPos-lightPosition;float depth=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);depth=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;float visibility=1.;vec3 poissonDisk[4];poissonDisk[0]=vec3(-1.0,1.0,-1.0);poissonDisk[1]=vec3(1.0,-1.0,-1.0);poissonDisk[2]=vec3(-1.0,-1.0,-1.0);poissonDisk[3]=vec3(1.0,-1.0,1.0);\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;if (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;if (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;if (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;if (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;if (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;if (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);}\n#define inline\nfloat computeShadowWithESMCube(vec3 worldPos,vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{vec3 directionToLight=worldPos-lightPosition;float depth=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);float shadowPixelDepth=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);return esm;}\n#define inline\nfloat computeShadowWithCloseESMCube(vec3 worldPos,vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{vec3 directionToLight=worldPos-lightPosition;float depth=length(directionToLight);depth=(depth+depthValues.x)/(depthValues.y);float shadowPixelDepth=clamp(depth,0.,1.0);directionToLight=normalize(directionToLight);directionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);return esm;}\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define inline\nfloat computeShadowCSM(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray shadowSampler,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec2 uv=0.5*clipSpace.xy+vec2(0.5);vec3 uvLayer=vec3(uv.x,uv.y,layer);float shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uvLayer));\n#else\nfloat shadow=texture2D(shadowSampler,uvLayer).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;}\n#endif\n#define inline\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec2 uv=0.5*clipSpace.xy+vec2(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{float shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(TEXTUREFUNC(shadowSampler,uv,0.));\n#else\nfloat shadow=TEXTUREFUNC(shadowSampler,uv,0.).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;}}\n#define inline\nfloat computeShadowWithPoissonSampling(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec2 uv=0.5*clipSpace.xy+vec2(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{float shadowPixelDepth=clamp(depthMetric,0.,1.0);float visibility=1.;vec2 poissonDisk[4];poissonDisk[0]=vec2(-0.94201624,-0.39906216);poissonDisk[1]=vec2(0.94558609,-0.76890725);poissonDisk[2]=vec2(-0.094184101,-0.92938870);poissonDisk[3]=vec2(0.34495938,0.29387760);\n#ifndef SHADOWFLOAT\nif (unpack(TEXTUREFUNC(shadowSampler,uv+poissonDisk[0]*mapSize,0.))<shadowPixelDepth) visibility-=0.25;if (unpack(TEXTUREFUNC(shadowSampler,uv+poissonDisk[1]*mapSize,0.))<shadowPixelDepth) visibility-=0.25;if (unpack(TEXTUREFUNC(shadowSampler,uv+poissonDisk[2]*mapSize,0.))<shadowPixelDepth) visibility-=0.25;if (unpack(TEXTUREFUNC(shadowSampler,uv+poissonDisk[3]*mapSize,0.))<shadowPixelDepth) visibility-=0.25;\n#else\nif (TEXTUREFUNC(shadowSampler,uv+poissonDisk[0]*mapSize,0.).x<shadowPixelDepth) visibility-=0.25;if (TEXTUREFUNC(shadowSampler,uv+poissonDisk[1]*mapSize,0.).x<shadowPixelDepth) visibility-=0.25;if (TEXTUREFUNC(shadowSampler,uv+poissonDisk[2]*mapSize,0.).x<shadowPixelDepth) visibility-=0.25;if (TEXTUREFUNC(shadowSampler,uv+poissonDisk[3]*mapSize,0.).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);}}\n#define inline\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec2 uv=0.5*clipSpace.xy+vec2(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{float shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(TEXTUREFUNC(shadowSampler,uv,0.));\n#else\nfloat shadowMapSample=TEXTUREFUNC(shadowSampler,uv,0.).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);return computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);}}\n#define inline\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec2 uv=0.5*clipSpace.xy+vec2(0.5);if (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{return 1.0;}\nelse\n{float shadowPixelDepth=clamp(depthMetric,0.,1.0); \n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(TEXTUREFUNC(shadowSampler,uv,0.));\n#else\nfloat shadowMapSample=TEXTUREFUNC(shadowSampler,uv,0.).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);return computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);}}\n#ifdef IS_NDC_HALF_ZRANGE\n#define ZINCLIP clipSpace.z\n#else\n#define ZINCLIP uvDepth.z\n#endif\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define SMALLEST_ABOVE_ZERO 1.1754943508e-38\n#define GREATEST_LESS_THAN_ONE 0.99999994\n#define DISABLE_UNIFORMITY_ANALYSIS\n#define inline\nfloat computeShadowWithCSMPCF1(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\n#ifdef USE_REVERSE_DEPTHBUFFER\nuvDepth.z=clamp(ZINCLIP,SMALLEST_ABOVE_ZERO,1.);\n#else\nuvDepth.z=clamp(ZINCLIP,0.,GREATEST_LESS_THAN_ONE);\n#endif\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);float shadow=texture2D(shadowSampler,uvDepthLayer);shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\n#define inline\nfloat computeShadowWithCSMPCF3(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\n#ifdef USE_REVERSE_DEPTHBUFFER\nuvDepth.z=clamp(ZINCLIP,SMALLEST_ABOVE_ZERO,1.);\n#else\nuvDepth.z=clamp(ZINCLIP,0.,GREATEST_LESS_THAN_ONE);\n#endif\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvec2 st=fract(uv); \nvec2 base_uv=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvec2 uvw0=3.-2.*st;vec2 uvw1=1.+2.*st;vec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;vec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;float shadow=0.;shadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));shadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));shadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));shadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));shadow=shadow/16.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\n#define inline\nfloat computeShadowWithCSMPCF5(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\n#ifdef USE_REVERSE_DEPTHBUFFER\nuvDepth.z=clamp(ZINCLIP,SMALLEST_ABOVE_ZERO,1.);\n#else\nuvDepth.z=clamp(ZINCLIP,0.,GREATEST_LESS_THAN_ONE);\n#endif\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvec2 st=fract(uv); \nvec2 base_uv=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvec2 uvw0=4.-3.*st;vec2 uvw1=vec2(7.);vec2 uvw2=1.+3.*st;vec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;vec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;float shadow=0.;shadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));shadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));shadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[0]),layer,uvDepth.z));shadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));shadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));shadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[1]),layer,uvDepth.z));shadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[2]),layer,uvDepth.z));shadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[2]),layer,uvDepth.z));shadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[2]),layer,uvDepth.z));shadow=shadow/144.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}\n#define inline\nfloat computeShadowWithPCF1(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));uvDepth.z=ZINCLIP;if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {float shadow=TEXTUREFUNC(shadowSampler,uvDepth,0.);shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\n#define inline\nfloat computeShadowWithPCF3(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));uvDepth.z=ZINCLIP;if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {vec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvec2 st=fract(uv); \nvec2 base_uv=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvec2 uvw0=3.-2.*st;vec2 uvw1=1.+2.*st;vec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;vec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;float shadow=0.;shadow+=uvw0.x*uvw0.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z),0.);shadow+=uvw1.x*uvw0.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z),0.);shadow+=uvw0.x*uvw1.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z),0.);shadow+=uvw1.x*uvw1.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z),0.);shadow=shadow/16.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\n#define inline\nfloat computeShadowWithPCF5(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));uvDepth.z=ZINCLIP;if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {vec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x; \nuv+=0.5; \nvec2 st=fract(uv); \nvec2 base_uv=floor(uv)-0.5; \nbase_uv*=shadowMapSizeAndInverse.y; \nvec2 uvw0=4.-3.*st;vec2 uvw1=vec2(7.);vec2 uvw2=1.+3.*st;vec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;vec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;float shadow=0.;shadow+=uvw0.x*uvw0.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z),0.);shadow+=uvw1.x*uvw0.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z),0.);shadow+=uvw2.x*uvw0.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[0]),uvDepth.z),0.);shadow+=uvw0.x*uvw1.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z),0.);shadow+=uvw1.x*uvw1.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z),0.);shadow+=uvw2.x*uvw1.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[1]),uvDepth.z),0.);shadow+=uvw0.x*uvw2.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[2]),uvDepth.z),0.);shadow+=uvw1.x*uvw2.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[2]),uvDepth.z),0.);shadow+=uvw2.x*uvw2.y*TEXTUREFUNC(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[2]),uvDepth.z),0.);shadow=shadow/144.;shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\nconst vec3 PoissonSamplers32[64]=vec3[64](\nvec3(0.06407013,0.05409927,0.),\nvec3(0.7366577,0.5789394,0.),\nvec3(-0.6270542,-0.5320278,0.),\nvec3(-0.4096107,0.8411095,0.),\nvec3(0.6849564,-0.4990818,0.),\nvec3(-0.874181,-0.04579735,0.),\nvec3(0.9989998,0.0009880066,0.),\nvec3(-0.004920578,-0.9151649,0.),\nvec3(0.1805763,0.9747483,0.),\nvec3(-0.2138451,0.2635818,0.),\nvec3(0.109845,0.3884785,0.),\nvec3(0.06876755,-0.3581074,0.),\nvec3(0.374073,-0.7661266,0.),\nvec3(0.3079132,-0.1216763,0.),\nvec3(-0.3794335,-0.8271583,0.),\nvec3(-0.203878,-0.07715034,0.),\nvec3(0.5912697,0.1469799,0.),\nvec3(-0.88069,0.3031784,0.),\nvec3(0.5040108,0.8283722,0.),\nvec3(-0.5844124,0.5494877,0.),\nvec3(0.6017799,-0.1726654,0.),\nvec3(-0.5554981,0.1559997,0.),\nvec3(-0.3016369,-0.3900928,0.),\nvec3(-0.5550632,-0.1723762,0.),\nvec3(0.925029,0.2995041,0.),\nvec3(-0.2473137,0.5538505,0.),\nvec3(0.9183037,-0.2862392,0.),\nvec3(0.2469421,0.6718712,0.),\nvec3(0.3916397,-0.4328209,0.),\nvec3(-0.03576927,-0.6220032,0.),\nvec3(-0.04661255,0.7995201,0.),\nvec3(0.4402924,0.3640312,0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.),\nvec3(0.)\n);const vec3 PoissonSamplers64[64]=vec3[64](\nvec3(-0.613392,0.617481,0.),\nvec3(0.170019,-0.040254,0.),\nvec3(-0.299417,0.791925,0.),\nvec3(0.645680,0.493210,0.),\nvec3(-0.651784,0.717887,0.),\nvec3(0.421003,0.027070,0.),\nvec3(-0.817194,-0.271096,0.),\nvec3(-0.705374,-0.668203,0.),\nvec3(0.977050,-0.108615,0.),\nvec3(0.063326,0.142369,0.),\nvec3(0.203528,0.214331,0.),\nvec3(-0.667531,0.326090,0.),\nvec3(-0.098422,-0.295755,0.),\nvec3(-0.885922,0.215369,0.),\nvec3(0.566637,0.605213,0.),\nvec3(0.039766,-0.396100,0.),\nvec3(0.751946,0.453352,0.),\nvec3(0.078707,-0.715323,0.),\nvec3(-0.075838,-0.529344,0.),\nvec3(0.724479,-0.580798,0.),\nvec3(0.222999,-0.215125,0.),\nvec3(-0.467574,-0.405438,0.),\nvec3(-0.248268,-0.814753,0.),\nvec3(0.354411,-0.887570,0.),\nvec3(0.175817,0.382366,0.),\nvec3(0.487472,-0.063082,0.),\nvec3(-0.084078,0.898312,0.),\nvec3(0.488876,-0.783441,0.),\nvec3(0.470016,0.217933,0.),\nvec3(-0.696890,-0.549791,0.),\nvec3(-0.149693,0.605762,0.),\nvec3(0.034211,0.979980,0.),\nvec3(0.503098,-0.308878,0.),\nvec3(-0.016205,-0.872921,0.),\nvec3(0.385784,-0.393902,0.),\nvec3(-0.146886,-0.859249,0.),\nvec3(0.643361,0.164098,0.),\nvec3(0.634388,-0.049471,0.),\nvec3(-0.688894,0.007843,0.),\nvec3(0.464034,-0.188818,0.),\nvec3(-0.440840,0.137486,0.),\nvec3(0.364483,0.511704,0.),\nvec3(0.034028,0.325968,0.),\nvec3(0.099094,-0.308023,0.),\nvec3(0.693960,-0.366253,0.),\nvec3(0.678884,-0.204688,0.),\nvec3(0.001801,0.780328,0.),\nvec3(0.145177,-0.898984,0.),\nvec3(0.062655,-0.611866,0.),\nvec3(0.315226,-0.604297,0.),\nvec3(-0.780145,0.486251,0.),\nvec3(-0.371868,0.882138,0.),\nvec3(0.200476,0.494430,0.),\nvec3(-0.494552,-0.711051,0.),\nvec3(0.612476,0.705252,0.),\nvec3(-0.578845,-0.768792,0.),\nvec3(-0.772454,-0.090976,0.),\nvec3(0.504440,0.372295,0.),\nvec3(0.155736,0.065157,0.),\nvec3(0.391522,0.849605,0.),\nvec3(-0.620106,-0.328104,0.),\nvec3(0.789239,-0.419965,0.),\nvec3(-0.545396,0.538133,0.),\nvec3(-0.178564,-0.596057,0.)\n);\n#define inline\nfloat computeShadowWithCSMPCSS(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\n#ifdef USE_REVERSE_DEPTHBUFFER\nuvDepth.z=clamp(ZINCLIP,SMALLEST_ABOVE_ZERO,1.);\n#else\nuvDepth.z=clamp(ZINCLIP,0.,GREATEST_LESS_THAN_ONE);\n#endif\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);float blockerDepth=0.0;float sumBlockerDepth=0.0;float numBlocker=0.0;for (int i=0; i<searchTapCount; i ++) {blockerDepth=texture2D(depthSampler,vec3(uvDepth.xy+(lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse*PoissonSamplers32[i].xy),layer)).r;if (blockerDepth<depthMetric) {sumBlockerDepth+=blockerDepth;numBlocker++;}}\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;float AAOffset=shadowMapSizeInverse*10.;float penumbraRatio=((depthMetric-avgBlockerDepth)*depthCorrection+AAOffset);vec4 filterRadius=vec4(penumbraRatio*lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse,0.,0.);float random=getRand(vPositionFromLight.xy);float rotationAngle=random*3.1415926;vec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));float shadow=0.;for (int i=0; i<pcfTapCount; i++) {vec4 offset=vec4(poissonSamplers[i],0.);offset=vec4(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.,0.);shadow+=texture2D(shadowSampler,uvDepthLayer+offset*filterRadius);}\nshadow/=float(pcfTapCount);shadow=mix(shadow,1.,min((depthMetric-avgBlockerDepth)*depthCorrection*penumbraDarkness,1.));shadow=mix(darkness,1.,shadow);if (numBlocker<1.0) {return 1.0;}\nelse\n{return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}\n#define inline\nfloat computeShadowWithPCSS(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers)\n{vec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;vec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));uvDepth.z=ZINCLIP;if (depthMetric<0.0 || depthMetric>1.0 || uvDepth.x<0. || uvDepth.x>1.0 || uvDepth.y<0. || uvDepth.y>1.0) {return 1.0;} else {float blockerDepth=0.0;float sumBlockerDepth=0.0;float numBlocker=0.0;for (int i=0; i<searchTapCount; i ++) {blockerDepth=TEXTUREFUNC(depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy),0.).r;if (blockerDepth<depthMetric) {sumBlockerDepth+=blockerDepth;numBlocker++;}}\nif (numBlocker<1.0) {return 1.0;}\nelse\n{float avgBlockerDepth=sumBlockerDepth/numBlocker;float AAOffset=shadowMapSizeInverse*10.;float penumbraRatio=((depthMetric-avgBlockerDepth)+AAOffset);float filterRadius=penumbraRatio*lightSizeUV*shadowMapSizeInverse;float random=getRand(vPositionFromLight.xy);float rotationAngle=random*3.1415926;vec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));float shadow=0.;for (int i=0; i<pcfTapCount; i++) {vec3 offset=poissonSamplers[i];offset=vec3(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);shadow+=TEXTUREFUNC(shadowSampler,uvDepth+offset*filterRadius,0.);}\nshadow/=float(pcfTapCount);shadow=mix(shadow,1.,depthMetric-avgBlockerDepth);shadow=mix(darkness,1.,shadow);return computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);}}}\n#define inline\nfloat computeShadowWithPCSS16(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{return computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);}\n#define inline\nfloat computeShadowWithPCSS32(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{return computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);}\n#define inline\nfloat computeShadowWithPCSS64(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{return computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);}\n#define inline\nfloat computeShadowWithCSMPCSS16(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{return computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);}\n#define inline\nfloat computeShadowWithCSMPCSS32(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{return computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);}\n#define inline\nfloat computeShadowWithCSMPCSS64(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{return computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64,lightSizeUVCorrection,depthCorrection,penumbraDarkness);}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const shadowsFragmentFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"imageProcessingFunctions\";\nconst shader = `#if defined(COLORGRADING) && !defined(COLORGRADING3D)\n/** \n* Polyfill for SAMPLE_TEXTURE_3D,which is unsupported in WebGL.\n* sampler3dSetting.x=textureOffset (0.5/textureSize).\n* sampler3dSetting.y=textureSize.\n*/\n#define inline\nvec3 sampleTexture3D(sampler2D colorTransform,vec3 color,vec2 sampler3dSetting)\n{float sliceSize=2.0*sampler3dSetting.x; \n#ifdef SAMPLER3DGREENDEPTH\nfloat sliceContinuous=(color.g-sampler3dSetting.x)*sampler3dSetting.y;\n#else\nfloat sliceContinuous=(color.b-sampler3dSetting.x)*sampler3dSetting.y;\n#endif\nfloat sliceInteger=floor(sliceContinuous);float sliceFraction=sliceContinuous-sliceInteger;\n#ifdef SAMPLER3DGREENDEPTH\nvec2 sliceUV=color.rb;\n#else\nvec2 sliceUV=color.rg;\n#endif\nsliceUV.x*=sliceSize;sliceUV.x+=sliceInteger*sliceSize;sliceUV=saturate(sliceUV);vec4 slice0Color=texture2D(colorTransform,sliceUV);sliceUV.x+=sliceSize;sliceUV=saturate(sliceUV);vec4 slice1Color=texture2D(colorTransform,sliceUV);vec3 result=mix(slice0Color.rgb,slice1Color.rgb,sliceFraction);\n#ifdef SAMPLER3DBGRMAP\ncolor.rgb=result.rgb;\n#else\ncolor.rgb=result.bgr;\n#endif\nreturn color;}\n#endif\n#if TONEMAPPING==3\nconst float PBRNeutralStartCompression=0.8-0.04;const float PBRNeutralDesaturation=0.15;vec3 PBRNeutralToneMapping( vec3 color ) {float x=min(color.r,min(color.g,color.b));float offset=x<0.08 ? x-6.25*x*x : 0.04;color-=offset;float peak=max(color.r,max(color.g,color.b));if (peak<PBRNeutralStartCompression) return color;float d=1.-PBRNeutralStartCompression;float newPeak=1.-d*d/(peak+d-PBRNeutralStartCompression);color*=newPeak/peak;float g=1.-1./(PBRNeutralDesaturation*(peak-newPeak)+1.);return mix(color,newPeak*vec3(1,1,1),g);}\n#endif\n#if TONEMAPPING==2\nconst mat3 ACESInputMat=mat3(\nvec3(0.59719,0.07600,0.02840),\nvec3(0.35458,0.90834,0.13383),\nvec3(0.04823,0.01566,0.83777)\n);const mat3 ACESOutputMat=mat3(\nvec3( 1.60475,-0.10208,-0.00327),\nvec3(-0.53108, 1.10813,-0.07276),\nvec3(-0.07367,-0.00605, 1.07602)\n);vec3 RRTAndODTFit(vec3 v)\n{vec3 a=v*(v+0.0245786)-0.000090537;vec3 b=v*(0.983729*v+0.4329510)+0.238081;return a/b;}\nvec3 ACESFitted(vec3 color)\n{color=ACESInputMat*color;color=RRTAndODTFit(color);color=ACESOutputMat*color;color=saturate(color);return color;}\n#endif\n#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_DEFINITIONS\nvec4 applyImageProcessing(vec4 result) {\n#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATSTART\n#ifdef WHITEBALANCE\nresult.rgb=whiteBalanceMatrix*result.rgb;result.rgb=max(result.rgb,0.0);\n#endif\n#ifdef EXPOSURE\nresult.rgb*=exposureLinear;\n#endif\n#ifdef VIGNETTE\nvec2 viewportXY=gl_FragCoord.xy*vInverseScreenSize;viewportXY=viewportXY*2.0-1.0;vec3 vignetteXY1=vec3(viewportXY*vignetteSettings1.xy+vignetteSettings1.zw,1.0);float vignetteTerm=dot(vignetteXY1,vignetteXY1);float vignette=pow(vignetteTerm,vignetteSettings2.w);vec3 vignetteColor=vignetteSettings2.rgb;\n#ifdef VIGNETTEBLENDMODEMULTIPLY\nvec3 vignetteColorMultiplier=mix(vignetteColor,vec3(1,1,1),vignette);result.rgb*=vignetteColorMultiplier;\n#endif\n#ifdef VIGNETTEBLENDMODEOPAQUE\nresult.rgb=mix(vignetteColor,result.rgb,vignette);\n#endif\n#endif\n#if TONEMAPPING==3\nresult.rgb=PBRNeutralToneMapping(result.rgb);\n#elif TONEMAPPING==2\nresult.rgb=ACESFitted(result.rgb);\n#elif TONEMAPPING==1\nconst float tonemappingCalibration=1.590579;result.rgb=1.0-exp2(-tonemappingCalibration*result.rgb);\n#endif\nresult.rgb=toGammaSpace(result.rgb);result.rgb=saturate(result.rgb);\n#ifdef CONTRAST\nvec3 resultHighContrast=result.rgb*result.rgb*(3.0-2.0*result.rgb);if (contrast<1.0) {result.rgb=mix(vec3(0.5,0.5,0.5),result.rgb,contrast);} else {result.rgb=mix(result.rgb,resultHighContrast,contrast-1.0);}\nresult.rgb=max(result.rgb,0.);\n#endif\n#ifdef COLORGRADING\nvec3 colorTransformInput=result.rgb*colorTransformSettings.xxx+colorTransformSettings.yyy;\n#ifdef COLORGRADING3D\nvec3 colorTransformOutput=texture(txColorTransform,colorTransformInput).rgb;\n#else\nvec3 colorTransformOutput=sampleTexture3D(txColorTransform,colorTransformInput,colorTransformSettings.yz).rgb;\n#endif\nresult.rgb=mix(result.rgb,colorTransformOutput,colorTransformSettings.www);\n#endif\n#ifdef COLORCURVES\nfloat luma=getLuminance(result.rgb);vec2 curveMix=clamp(vec2(luma*3.0-1.5,luma*-3.0+1.5),vec2(0.0),vec2(1.0));vec4 colorCurve=vCameraColorCurveNeutral+curveMix.x*vCameraColorCurvePositive-curveMix.y*vCameraColorCurveNegative;result.rgb*=colorCurve.rgb;result.rgb=mix(vec3(luma),result.rgb,colorCurve.a);\n#endif\n#ifdef DITHER\nfloat rand=getRand(gl_FragCoord.xy*vInverseScreenSize);float dither=mix(-ditherIntensity,ditherIntensity,rand);result.rgb=saturate(result.rgb+vec3(dither));\n#endif\n#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATEND\nreturn result;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const imageProcessingFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogFragmentDeclaration\";\nconst shader = `#ifdef FOG\n#define FOGMODE_NONE 0.\n#define FOGMODE_EXP 1.\n#define FOGMODE_EXP2 2.\n#define FOGMODE_LINEAR 3.\n#define E 2.71828\nuniform vec4 vFogInfos;uniform vec3 vFogColor;varying vec3 vFogDistance;float CalcFogFactor()\n{float fogCoeff=1.0;float fogStart=vFogInfos.y;float fogEnd=vFogInfos.z;float fogDensity=vFogInfos.w;float fogDistance=length(vFogDistance);if (FOGMODE_LINEAR==vFogInfos.x)\n{fogCoeff=(fogEnd-fogDistance)/(fogEnd-fogStart);}\nelse if (FOGMODE_EXP==vFogInfos.x)\n{fogCoeff=1.0/pow(E,fogDistance*fogDensity);}\nelse if (FOGMODE_EXP2==vFogInfos.x)\n{fogCoeff=1.0/pow(E,fogDistance*fogDistance*fogDensity*fogDensity);}\nreturn clamp(fogCoeff,0.0,1.0);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const fogFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"intersectionFunctions\";\nconst shader = `float diskIntersectWithBackFaceCulling(vec3 ro,vec3 rd,vec3 c,float r) {float d=rd.y;if(d>0.0) { return 1e6; }\nvec3 o=ro-c;float t=-o.y/d;vec3 q=o+rd*t;return (dot(q,q)<r*r) ? t : 1e6;}\nvec2 sphereIntersect(vec3 ro,vec3 rd,vec3 ce,float ra) {vec3 oc=ro-ce;float b=dot(oc,rd);float c=dot(oc,oc)-ra*ra;float h=b*b-c;if(h<0.0) { return vec2(-1.0,-1.0); }\nh=sqrt(h);return vec2(-b+h,-b-h);}\nvec2 sphereIntersectFromOrigin(vec3 ro,vec3 rd,float ra) {float b=dot(ro,rd);float c=dot(ro,ro)-ra*ra;float h=b*b-c;if(h<0.0) { return vec2(-1.0,-1.0); }\nh=sqrt(h);return vec2(-b+h,-b-h);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const intersectionFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightFragment\";\nconst shader = `#ifdef LIGHT{X}\n#if defined(SHADOWONLY) || defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})\n#else\nvec4 diffuse{X}=light{X}.vLightDiffuse;\n#define CUSTOM_LIGHT{X}_COLOR \n#if defined(PBR) && defined(CLUSTLIGHT{X}) && defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n{int sliceIndex=min(getClusteredSliceIndex(light{X}.vSliceData,vViewDepth),CLUSTLIGHT_SLICES-1);info=computeClusteredLighting(\nlightDataTexture{X},\ntileMaskTexture{X},\nlight{X}.vLightData,\nivec2(light{X}.vSliceRanges[sliceIndex]),\nviewDirectionW,\nnormalW,\nvPositionW,\nsurfaceAlbedo,\nreflectivityOut\n#ifdef IRIDESCENCE\n,iridescenceIntensity\n#endif\n#ifdef SS_TRANSLUCENCY\n,subSurfaceOut\n#endif\n#ifdef SPECULARTERM\n,AARoughnessFactors.x\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#ifdef SHEEN\n,sheenOut\n#endif\n#ifdef CLEARCOAT\n,clearcoatOut\n#endif\n);}\n#elif defined(PBR)\n#ifdef SPOTLIGHT{X}\npreInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,vPositionW);\n#elif defined(POINTLIGHT{X})\npreInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,vPositionW);\n#elif defined(HEMILIGHT{X})\npreInfo=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(DIRLIGHT{X})\npreInfo=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#if defined(RECTAREALIGHTEMISSIONTEXTURE{X})\npreInfo=computeAreaPreLightingInfoWithTexture(areaLightsLTC1Sampler,areaLightsLTC2Sampler,rectAreaLightEmissionTexture{X},viewDirectionW,normalW,vPositionW,light{X}.vLightData,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,roughness);\n#else\npreInfo=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC2Sampler,viewDirectionW,normalW,vPositionW,light{X}.vLightData,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,roughness);\n#endif\n#endif\npreInfo.NdotV=NdotV;\n#ifdef SPOTLIGHT{X}\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X});\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff_GLTF(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X});\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff_Physical(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w);\n#endif\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X});\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff_Standard(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w);\n#endif\n#else\npreInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo.L,iesLightTexture{X});\n#else\npreInfo.attenuation*=computeDirectionalLightFalloff(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#endif\n#elif defined(POINTLIGHT{X})\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n#else\npreInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#endif\n#else\npreInfo.attenuation=1.0;\n#endif\n#if defined(HEMILIGHT{X})\npreInfo.roughness=roughness;\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\npreInfo.roughness=roughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(roughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n#endif\npreInfo.diffuseRoughness=diffuseRoughness;preInfo.surfaceAlbedo=surfaceAlbedo;\n#ifdef IRIDESCENCE\npreInfo.iridescenceIntensity=iridescenceIntensity;\n#endif\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission=vec3(0.0);\n#endif\n#ifdef HEMILIGHT{X}\ninfo.diffuse=computeHemisphericDiffuseLighting(preInfo,diffuse{X}.rgb,light{X}.vLightGround);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\ninfo.diffuse=computeAreaDiffuseLighting(preInfo,diffuse{X}.rgb);\n#elif defined(SS_TRANSLUCENCY)\n#ifndef SS_TRANSLUCENCY_LEGACY\ninfo.diffuse=computeDiffuseLighting(preInfo,diffuse{X}.rgb)*(1.0-subSurfaceOut.translucencyIntensity);info.diffuseTransmission=computeDiffuseTransmittedLighting(preInfo,diffuse{X}.rgb,subSurfaceOut.transmittance); \n#else\ninfo.diffuse=computeDiffuseTransmittedLighting(preInfo,diffuse{X}.rgb,subSurfaceOut.transmittance);\n#endif\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,diffuse{X}.rgb);\n#endif\n#ifdef SPECULARTERM\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\ninfo.specular=computeAreaSpecularLighting(preInfo,light{X}.vLightSpecular.rgb,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90);\n#else\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\n{vec3 metalFresnel=reflectivityOut.specularWeight*getF82Specular(preInfo.VdotH,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90,reflectivityOut.roughness);vec3 dielectricFresnel=fresnelSchlickGGX(preInfo.VdotH,reflectivityOut.dielectricColorF0,reflectivityOut.colorReflectanceF90);coloredFresnel=mix(dielectricFresnel,metalFresnel,reflectivityOut.metallic);}\n#else\ncoloredFresnel=fresnelSchlickGGX(preInfo.VdotH,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90);\n#endif\n#ifndef LEGACY_SPECULAR_ENERGY_CONSERVATION\n{float NdotH=dot(normalW,preInfo.H);vec3 fresnel=fresnelSchlickGGX(NdotH,vec3(reflectanceF0),specularEnvironmentR90);info.diffuse*=(vec3(1.0)-fresnel);}\n#endif\n#ifdef ANISOTROPIC\ninfo.specular=computeAnisotropicSpecularLighting(preInfo,viewDirectionW,normalW,anisotropicOut.anisotropicTangent,anisotropicOut.anisotropicBitangent,anisotropicOut.anisotropy,clearcoatOut.specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactors.x,diffuse{X}.rgb);\n#else\ninfo.specular=computeSpecularLighting(preInfo,normalW,clearcoatOut.specularEnvironmentR0,coloredFresnel,AARoughnessFactors.x,diffuse{X}.rgb);\n#endif\n#endif\n#endif\n#ifndef AREALIGHT{X}\n#ifdef SHEEN\n#ifdef SHEEN_LINKWITHALBEDO\npreInfo.roughness=sheenOut.sheenIntensity;\n#else\n#ifdef HEMILIGHT{X}\npreInfo.roughness=sheenOut.sheenRoughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(sheenOut.sheenRoughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n#endif\n#endif\ninfo.sheen=computeSheenLighting(preInfo,normalW,sheenOut.sheenColor,specularEnvironmentR90,AARoughnessFactors.x,diffuse{X}.rgb);\n#endif\n#ifdef CLEARCOAT\n#ifdef HEMILIGHT{X}\npreInfo.roughness=clearcoatOut.clearCoatRoughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(clearcoatOut.clearCoatRoughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n#endif\ninfo.clearCoat=computeClearCoatLighting(preInfo,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatAARoughnessFactors.x,clearcoatOut.clearCoatIntensity,diffuse{X}.rgb);\n#ifdef CLEARCOAT_TINT\nabsorption=computeClearCoatLightingAbsorption(clearcoatOut.clearCoatNdotVRefract,preInfo.L,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatColor,clearcoatOut.clearCoatThickness,clearcoatOut.clearCoatIntensity);info.diffuse*=absorption;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=absorption;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=absorption;\n#endif\n#endif\ninfo.diffuse*=info.clearCoat.w;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=info.clearCoat.w;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=info.clearCoat.w;\n#endif\n#ifdef SHEEN\ninfo.sheen*=info.clearCoat.w;\n#endif\n#endif\n#endif\n#else\n#ifdef SPOTLIGHT{X}\n#ifdef IESLIGHTTEXTURE{X}\ninfo=computeIESSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,diffuse{X}.a,glossiness,iesLightTexture{X});\n#else\ninfo=computeSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,diffuse{X}.a,glossiness);\n#endif\n#elif defined(HEMILIGHT{X})\ninfo=computeHemisphericLighting(viewDirectionW,normalW,light{X}.vLightData,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,light{X}.vLightGround,glossiness);\n#elif defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})\ninfo=computeLighting(viewDirectionW,normalW,light{X}.vLightData,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,diffuse{X}.a,glossiness);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#if defined(RECTAREALIGHTEMISSIONTEXTURE{X})\ninfo=computeAreaLightingWithTexture(areaLightsLTC1Sampler,areaLightsLTC2Sampler,rectAreaLightEmissionTexture{X},viewDirectionW,normalW,vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.rgb,light{X}.vLightHeight.rgb,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,\n#ifdef AREALIGHTNOROUGHTNESS\n0.5\n#else\nvReflectionInfos.y\n#endif\n#else\ninfo=computeAreaLighting(areaLightsLTC1Sampler,areaLightsLTC2Sampler,viewDirectionW,normalW,vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.rgb,light{X}.vLightHeight.rgb,diffuse{X}.rgb,light{X}.vLightSpecular.rgb,\n#ifdef AREALIGHTNOROUGHTNESS\n0.5\n#else\nvReflectionInfos.y\n#endif\n#endif\n);\n#elif defined(CLUSTLIGHT{X}) && CLUSTLIGHT_BATCH>0\n{int sliceIndex=min(getClusteredSliceIndex(light{X}.vSliceData,vViewDepth),CLUSTLIGHT_SLICES-1);info=computeClusteredLighting(lightDataTexture{X},tileMaskTexture{X},viewDirectionW,normalW,light{X}.vLightData,ivec2(light{X}.vSliceRanges[sliceIndex]),glossiness);}\n#endif\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\ninfo.diffuse*=computeProjectionTextureDiffuseLighting(projectionLightTexture{X},textureProjectionMatrix{X},vPositionW);\n#endif\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nfor (int i=0; i<SHADOWCSMNUM_CASCADES{X}; i++)\n{\n#ifdef SHADOWCSM_RIGHTHANDED{X}\ndiff{X}=viewFrustumZ{X}[i]+vPositionFromCamera{X}.z;\n#else\ndiff{X}=viewFrustumZ{X}[i]-vPositionFromCamera{X}.z;\n#endif\nif (diff{X}>=0.) {index{X}=i;break;}}\n#ifdef SHADOWCSMUSESHADOWMAXZ{X}\nif (index{X}>=0)\n#endif\n{\n#if defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithCSMPCF1(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithCSMPCF3(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithCSMPCF5(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithCSMPCSS16(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithCSMPCSS32(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n#else\nshadow=computeShadowWithCSMPCSS64(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n#endif\n#else\nshadow=computeShadowCSM(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#ifdef SHADOWCSMDEBUG{X}\nshadowDebug{X}=vec3(shadow)*vCascadeColorsMultiplier{X}[index{X}];\n#endif\n#ifndef SHADOWCSMNOBLEND{X}\nfloat frustumLength=frustumLengths{X}[index{X}];float diffRatio=clamp(diff{X}/frustumLength,0.,1.)*cascadeBlendFactor{X};if (index{X}<(SHADOWCSMNUM_CASCADES{X}-1) && diffRatio<1.)\n{index{X}+=1;float nextShadow=0.;\n#if defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nnextShadow=computeShadowWithCSMPCF1(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nnextShadow=computeShadowWithCSMPCF3(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nnextShadow=computeShadowWithCSMPCF5(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nnextShadow=computeShadowWithCSMPCSS16(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n#elif defined(SHADOWMEDIUMQUALITY{X})\nnextShadow=computeShadowWithCSMPCSS32(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n#else\nnextShadow=computeShadowWithCSMPCSS64(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n#endif\n#else\nnextShadow=computeShadowCSM(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\nshadow=mix(nextShadow,shadow,diffRatio);\n#ifdef SHADOWCSMDEBUG{X}\nshadowDebug{X}=mix(vec3(nextShadow)*vCascadeColorsMultiplier{X}[index{X}],shadowDebug{X},diffRatio);\n#endif\n}\n#endif\n}\n#elif defined(SHADOWCLOSEESM{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithCloseESMCube(vPositionW,light{X}.vLightData.xyz,shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithCloseESM(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWESM{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithESMCube(vPositionW,light{X}.vLightData.xyz,shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithESM(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPOISSON{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithPoissonSamplingCube(vPositionW,light{X}.vLightData.xyz,shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadowWithPoissonSampling(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithPCF1(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithPCF3(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithPCF5(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithPCSS16(vPositionFromLight{X},vDepthMetric{X},depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithPCSS32(vPositionFromLight{X},vDepthMetric{X},depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithPCSS64(vPositionFromLight{X},vDepthMetric{X},depthTexture{X},shadowTexture{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#else\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowCube(vPositionW,light{X}.vLightData.xyz,shadowTexture{X},light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadow(vPositionFromLight{X},vDepthMetric{X},shadowTexture{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#endif\n#ifdef SHADOWONLY\n#ifndef SHADOWINUSE\n#define SHADOWINUSE\n#endif\nglobalShadow+=shadow;shadowLightCount+=1.0;\n#endif\n#else\nshadow=1.;\n#endif\naggShadow+=shadow;numLights+=1.0;\n#ifndef SHADOWONLY\n#ifdef CUSTOMUSERLIGHTING\ndiffuseBase+=computeCustomDiffuseLighting(info,diffuseBase,shadow);\n#ifdef SPECULARTERM\nspecularBase+=computeCustomSpecularLighting(info,specularBase,shadow);\n#endif\n#elif defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X})\ndiffuseBase+=lightmapColor.rgb*shadow;\n#ifdef SPECULARTERM\n#ifndef LIGHTMAPNOSPECULAR{X}\nspecularBase+=info.specular*shadow*lightmapColor.rgb;\n#endif\n#endif\n#ifdef CLEARCOAT\n#ifndef LIGHTMAPNOSPECULAR{X}\nclearCoatBase+=info.clearCoat.rgb*shadow*lightmapColor.rgb;\n#endif\n#endif\n#ifdef SHEEN\n#ifndef LIGHTMAPNOSPECULAR{X}\nsheenBase+=info.sheen.rgb*shadow;\n#endif\n#endif\n#else\n#ifdef SHADOWCSMDEBUG{X}\ndiffuseBase+=info.diffuse*shadowDebug{X};\n#else\ndiffuseBase+=info.diffuse*shadow;\n#endif\n#ifdef SS_TRANSLUCENCY\ndiffuseTransmissionBase+=info.diffuseTransmission*shadow;\n#endif\n#ifdef SPECULARTERM\nspecularBase+=info.specular*shadow;\n#endif\n#ifdef CLEARCOAT\nclearCoatBase+=info.clearCoat.rgb*shadow;\n#endif\n#ifdef SHEEN\nsheenBase+=info.sheen.rgb*shadow;\n#endif\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lightFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"logDepthFragment\";\nconst shader = `#ifdef LOGARITHMICDEPTH\ngl_FragDepthEXT=log2(vFragmentDepth)*logarithmicDepthConstant*0.5;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const logDepthFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fogFragment\";\nconst shader = `#ifdef FOG\nfloat fog=CalcFogFactor();\n#ifdef PBR\nfog=toLinearSpace(fog);\n#endif\ncolor.rgb=mix(vFogColor,color.rgb,fog);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const fogFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { backgroundFragmentDeclaration } from \"./ShadersInclude/backgroundFragmentDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { backgroundUboDeclaration } from \"./ShadersInclude/backgroundUboDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { reflectionFunction } from \"./ShadersInclude/reflectionFunction\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { lightFragmentDeclaration } from \"./ShadersInclude/lightFragmentDeclaration\";\nimport { lightUboDeclaration } from \"./ShadersInclude/lightUboDeclaration\";\nimport { ltcHelperFunctions } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { clusteredLightingFunctions } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { lightsFragmentFunctions } from \"./ShadersInclude/lightsFragmentFunctions\";\nimport { shadowsFragmentFunctions } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { intersectionFunctions } from \"./ShadersInclude/intersectionFunctions\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { lightFragment } from \"./ShadersInclude/lightFragment\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\n\nconst name = \"backgroundPixelShader\";\nconst shader = `#ifdef TEXTURELODSUPPORT\n#extension GL_EXT_shader_texture_lod : enable\n#endif\nprecision highp float;\n#include<__decl__backgroundFragment>\n#include<helperFunctions>\nvarying vec3 vPositionW;\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif \n#ifdef MAINUV2 \nvarying vec2 vMainUV2; \n#endif \n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef DIFFUSE\n#if DIFFUSEDIRECTUV==1\n#define vDiffuseUV vMainUV1\n#elif DIFFUSEDIRECTUV==2\n#define vDiffuseUV vMainUV2\n#else\nvarying vec2 vDiffuseUV;\n#endif\nuniform sampler2D diffuseSampler;\n#endif\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\n#define sampleReflection(s,c) textureCube(s,c)\nuniform samplerCube reflectionSampler;\n#ifdef TEXTURELODSUPPORT\n#define sampleReflectionLod(s,c,l) textureCubeLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;uniform samplerCube reflectionSamplerHigh;\n#endif\n#else\n#define sampleReflection(s,c) texture2D(s,c)\nuniform sampler2D reflectionSampler;\n#ifdef TEXTURELODSUPPORT\n#define sampleReflectionLod(s,c,l) texture2DLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;uniform samplerCube reflectionSamplerHigh;\n#endif\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE;\n#endif\n#ifndef SHADOWONLY\n#define SHADOWONLY;\n#endif\n#include<imageProcessingDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n#include<imageProcessingFunctions>\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#include<logDepthDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<fogFragmentDeclaration>\n#ifdef REFLECTIONFRESNEL\n#define FRESNEL_MAXIMUM_ON_ROUGH 0.25\nvec3 fresnelSchlickEnvironmentGGX(float VdotN,vec3 reflectance0,vec3 reflectance90,float smoothness)\n{float weight=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);return reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));}\n#endif\n#ifdef PROJECTED_GROUND\n#include<intersectionFunctions>\nvec3 project(vec3 viewDirectionW,vec3 eyePosition) {float radius=projectedGroundInfos.x;float height=projectedGroundInfos.y;vec3 camDir=-viewDirectionW;float skySphereDistance=sphereIntersectFromOrigin(eyePosition,camDir,radius).x;vec3 skySpherePositionW=eyePosition+camDir*skySphereDistance;vec3 p=normalize(skySpherePositionW);eyePosition.y-=height;float sIntersection=sphereIntersectFromOrigin(eyePosition,p,radius).x;vec3 h=vec3(0.0,-height,0.0);float dIntersection=diskIntersectWithBackFaceCulling(eyePosition,p,h,radius);p=(eyePosition+min(sIntersection,dIntersection)*p);return p;}\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=vec3(0.0,1.0,0.0);\n#endif\nfloat shadow=1.;float globalShadow=0.;float shadowLightCount=0.;float aggShadow=0.;float numLights=0.;\n#include<lightFragment>[0..maxSimultaneousLights]\n#ifdef SHADOWINUSE\nglobalShadow/=shadowLightCount;\n#else\nglobalShadow=1.0;\n#endif\n#ifndef BACKMAT_SHADOWONLY\nvec4 reflectionColor=vec4(1.,1.,1.,1.);\n#ifdef REFLECTION\n#ifdef PROJECTED_GROUND\nvec3 reflectionVector=project(viewDirectionW,vEyePosition.xyz);reflectionVector=vec3(reflectionMatrix*vec4(reflectionVector,1.));\n#else\nvec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=reflectionVector;\n#else\nvec2 reflectionCoords=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\n#ifdef REFLECTIONBLUR\nfloat reflectionLOD=vReflectionInfos.y;\n#ifdef TEXTURELODSUPPORT\nreflectionLOD=reflectionLOD*log2(vReflectionMicrosurfaceInfos.x)*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;reflectionColor=sampleReflectionLod(reflectionSampler,reflectionCoords,reflectionLOD);\n#else\nfloat lodReflectionNormalized=saturate(reflectionLOD);float lodReflectionNormalizedDoubled=lodReflectionNormalized*2.0;vec4 reflectionSpecularMid=sampleReflection(reflectionSampler,reflectionCoords);if(lodReflectionNormalizedDoubled<1.0){reflectionColor=mix(\nsampleReflection(reflectionSamplerHigh,reflectionCoords),\nreflectionSpecularMid,\nlodReflectionNormalizedDoubled\n);} else {reflectionColor=mix(\nreflectionSpecularMid,\nsampleReflection(reflectionSamplerLow,reflectionCoords),\nlodReflectionNormalizedDoubled-1.0\n);}\n#endif\n#else\nvec4 reflectionSample=sampleReflection(reflectionSampler,reflectionCoords);reflectionColor=reflectionSample;\n#endif\n#ifdef RGBDREFLECTION\nreflectionColor.rgb=fromRGBD(reflectionColor);\n#endif\n#ifdef GAMMAREFLECTION\nreflectionColor.rgb=toLinearSpace(reflectionColor.rgb);\n#endif\n#ifdef REFLECTIONBGR\nreflectionColor.rgb=reflectionColor.bgr;\n#endif\nreflectionColor.rgb*=vReflectionInfos.x;\n#endif\nvec3 diffuseColor=vec3(1.,1.,1.);float finalAlpha=alpha;\n#ifdef DIFFUSE\nvec4 diffuseMap=texture2D(diffuseSampler,vDiffuseUV);\n#ifdef GAMMADIFFUSE\ndiffuseMap.rgb=toLinearSpace(diffuseMap.rgb);\n#endif\ndiffuseMap.rgb*=vDiffuseInfos.y;\n#ifdef DIFFUSEHASALPHA\nfinalAlpha*=diffuseMap.a;\n#endif\ndiffuseColor=diffuseMap.rgb;\n#endif\n#ifdef REFLECTIONFRESNEL\nvec3 colorBase=diffuseColor;\n#else\nvec3 colorBase=reflectionColor.rgb*diffuseColor;\n#endif\ncolorBase=max(colorBase,0.0);\n#ifdef USERGBCOLOR\nvec3 finalColor=colorBase;\n#else\n#ifdef USEHIGHLIGHTANDSHADOWCOLORS\nvec3 mainColor=mix(vPrimaryColorShadow.rgb,vPrimaryColor.rgb,colorBase);\n#else\nvec3 mainColor=vPrimaryColor.rgb;\n#endif\nvec3 finalColor=colorBase*mainColor;\n#endif\n#ifdef REFLECTIONFRESNEL\nvec3 reflectionAmount=vReflectionControl.xxx;vec3 reflectionReflectance0=vReflectionControl.yyy;vec3 reflectionReflectance90=vReflectionControl.zzz;float VdotN=dot(normalize(vEyePosition.xyz),normalW);vec3 planarReflectionFresnel=fresnelSchlickEnvironmentGGX(saturate(VdotN),reflectionReflectance0,reflectionReflectance90,1.0);reflectionAmount*=planarReflectionFresnel;\n#ifdef REFLECTIONFALLOFF\nfloat reflectionDistanceFalloff=1.0-saturate(length(vPositionW.xyz-vBackgroundCenter)*vReflectionControl.w);reflectionDistanceFalloff*=reflectionDistanceFalloff;reflectionAmount*=reflectionDistanceFalloff;\n#endif\nfinalColor=mix(finalColor,reflectionColor.rgb,saturate(reflectionAmount));\n#endif\n#ifdef OPACITYFRESNEL\nfloat viewAngleToFloor=dot(normalW,normalize(vEyePosition.xyz-vBackgroundCenter));const float startAngle=0.1;float fadeFactor=saturate(viewAngleToFloor/startAngle);finalAlpha*=fadeFactor*fadeFactor;\n#endif\n#ifdef SHADOWINUSE\nfinalColor=mix(finalColor*shadowLevel,finalColor,globalShadow);\n#endif\nvec4 color=vec4(finalColor,finalAlpha);\n#else\nvec4 color=vec4(vPrimaryColor.rgb,(1.0-clamp(globalShadow,0.,1.))*alpha);\n#endif\n#include<logDepthFragment>\n#include<fogFragment>\n#ifdef IMAGEPROCESSINGPOSTPROCESS\n#if !defined(SKIPFINALCOLORCLAMP)\ncolor.rgb=clamp(color.rgb,0.,30.0);\n#endif\n#else\ncolor=applyImageProcessing(color);\n#endif\n#ifdef PREMULTIPLYALPHA\ncolor.rgb*=color.a;\n#endif\n#ifdef NOISE\ncolor.rgb+=dither(vPositionW.xy,0.5);color=max(color,0.0);\n#endif\ngl_FragColor=color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [backgroundFragmentDeclaration, sceneUboDeclaration, backgroundUboDeclaration, helperFunctions, reflectionFunction, imageProcessingDeclaration, lightFragmentDeclaration, lightUboDeclaration, ltcHelperFunctions, clusteredLightingFunctions, lightsFragmentFunctions, shadowsFragmentFunctions, imageProcessingFunctions, logDepthDeclaration, clipPlaneFragmentDeclaration, fogFragmentDeclaration, intersectionFunctions, clipPlaneFragment, lightFragment, logDepthFragment, fogFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const backgroundPixelShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\n\nimport { DeepCopier } from \"../Misc/deepCopier\";\nimport { type DeepImmutable } from \"../types\";\nimport { Color3 } from \"../Maths/math.color.pure\";\nimport { Constants } from \"../Engines/constants\";\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\n\n/**\n * Options to be used when creating a FresnelParameters.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IFresnelParametersCreationOptions = {\n    /**\n     * Define the color used on edges (grazing angle)\n     */\n    leftColor?: Color3;\n\n    /**\n     * Define the color used on center\n     */\n    rightColor?: Color3;\n\n    /**\n     * Define bias applied to computed fresnel term\n     */\n    bias?: number;\n\n    /**\n     * Defined the power exponent applied to fresnel term\n     */\n    power?: number;\n\n    /**\n     * Define if the fresnel effect is enable or not.\n     */\n    isEnabled?: boolean;\n};\n\n/**\n * Serialized format for FresnelParameters.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IFresnelParametersSerialized = {\n    /**\n     * Define the color used on edges (grazing angle) [as an array]\n     */\n    leftColor: number[];\n\n    /**\n     * Define the color used on center [as an array]\n     */\n    rightColor: number[];\n\n    /**\n     * Define bias applied to computed fresnel term\n     */\n    bias: number;\n\n    /**\n     * Defined the power exponent applied to fresnel term\n     */\n    power?: number;\n\n    /**\n     * Define if the fresnel effect is enable or not.\n     */\n    isEnabled: boolean;\n};\n\n/**\n * This represents all the required information to add a fresnel effect on a material:\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters\n */\nexport class FresnelParameters {\n    private _isEnabled = true;\n    /**\n     * Define if the fresnel effect is enable or not.\n     */\n    public get isEnabled(): boolean {\n        return this._isEnabled;\n    }\n    public set isEnabled(value: boolean) {\n        if (this._isEnabled === value) {\n            return;\n        }\n\n        this._isEnabled = value;\n        AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_FresnelDirtyFlag | Constants.MATERIAL_MiscDirtyFlag);\n    }\n\n    /**\n     * Define the color used on edges (grazing angle)\n     */\n    public leftColor: Color3;\n\n    /**\n     * Define the color used on center\n     */\n    public rightColor: Color3;\n\n    /**\n     * Define bias applied to computed fresnel term\n     */\n    public bias: number;\n\n    /**\n     * Defined the power exponent applied to fresnel term\n     */\n    public power: number;\n\n    /**\n     * Creates a new FresnelParameters object.\n     *\n     * @param options provide your own settings to optionally to override defaults\n     */\n    public constructor(options: IFresnelParametersCreationOptions = {}) {\n        this.bias = options.bias === undefined ? 0 : options.bias;\n        this.power = options.power === undefined ? 1 : options.power;\n        this.leftColor = options.leftColor || Color3.White();\n        this.rightColor = options.rightColor || Color3.Black();\n        if (options.isEnabled === false) {\n            this.isEnabled = false;\n        }\n    }\n\n    /**\n     * Clones the current fresnel and its values\n     * @returns a clone fresnel configuration\n     */\n    public clone(): FresnelParameters {\n        const newFresnelParameters = new FresnelParameters();\n\n        DeepCopier.DeepCopy(this, newFresnelParameters);\n\n        return newFresnelParameters;\n    }\n\n    /**\n     * Determines equality between FresnelParameters objects\n     * @param otherFresnelParameters defines the second operand\n     * @returns true if the power, bias, leftColor, rightColor and isEnabled values are equal to the given ones\n     */\n    public equals(otherFresnelParameters: DeepImmutable<FresnelParameters>): boolean {\n        return (\n            otherFresnelParameters &&\n            this.bias === otherFresnelParameters.bias &&\n            this.power === otherFresnelParameters.power &&\n            this.leftColor.equals(otherFresnelParameters.leftColor) &&\n            this.rightColor.equals(otherFresnelParameters.rightColor) &&\n            this.isEnabled === otherFresnelParameters.isEnabled\n        );\n    }\n\n    /**\n     * Serializes the current fresnel parameters to a JSON representation.\n     * @returns the JSON serialization\n     */\n    public serialize(): IFresnelParametersSerialized {\n        return {\n            isEnabled: this.isEnabled,\n            leftColor: this.leftColor.asArray(),\n            rightColor: this.rightColor.asArray(),\n            bias: this.bias,\n            power: this.power,\n        };\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parse a JSON object and deserialize it to a new Fresnel parameter object.\n * @param parsedFresnelParameters Define the JSON representation\n * @returns the parsed parameters\n */\nexport function FresnelParametersParse(parsedFresnelParameters: IFresnelParametersSerialized): FresnelParameters {\n    return new FresnelParameters({\n        isEnabled: parsedFresnelParameters.isEnabled,\n        leftColor: Color3.FromArray(parsedFresnelParameters.leftColor),\n        rightColor: Color3.FromArray(parsedFresnelParameters.rightColor),\n        bias: parsedFresnelParameters.bias,\n        power: parsedFresnelParameters.power || 1.0,\n    });\n}\n\n/**\n * Register side effects for fresnelParameters.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFresnelParameters(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    // References the dependencies.\n    FresnelParameters.Parse = FresnelParametersParse;\n\n    SerializationHelper._FresnelParametersParser = FresnelParametersParse;\n}\n","import { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { type PrePassConfiguration } from \"../Materials/prePassConfiguration\";\r\n\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type Effect, type IEffectCreationOptions } from \"./effect\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { type EffectFallbacks } from \"./effectFallbacks\";\r\nimport { type Material } from \"./material\";\r\nimport {\r\n    BindBonesParameters,\r\n    BindFogParameters,\r\n    BindLight,\r\n    BindLightProperties,\r\n    BindLights,\r\n    BindLogDepth,\r\n    BindMorphTargetParameters,\r\n    BindSceneUniformBuffer,\r\n    BindTextureMatrix,\r\n    GetFogState,\r\n    HandleFallbacksForShadows,\r\n    PrepareAttributesForBakedVertexAnimation,\r\n    PrepareAttributesForBones,\r\n    PrepareAttributesForInstances,\r\n    PrepareAttributesForMorphTargets,\r\n    PrepareAttributesForMorphTargetsInfluencers,\r\n    PrepareDefinesForAttributes,\r\n    PrepareDefinesForBakedVertexAnimation,\r\n    PrepareDefinesForBones,\r\n    PrepareDefinesForCamera,\r\n    PrepareDefinesForFrameBoundValues,\r\n    PrepareDefinesForLight,\r\n    PrepareDefinesForLights,\r\n    PrepareDefinesForMergedUV,\r\n    PrepareDefinesForMisc,\r\n    PrepareDefinesForMorphTargets,\r\n    PrepareDefinesForMultiview,\r\n    PrepareDefinesForOIT,\r\n    PrepareDefinesForPrePass,\r\n    PrepareUniformsAndSamplersForLight,\r\n    PrepareUniformsAndSamplersList,\r\n    PushAttributesForInstances,\r\n} from \"./materialHelper.functions\";\r\n\r\n/**\r\n * \"Static Class\" containing the most commonly used helper while dealing with material for rendering purpose.\r\n *\r\n * It contains the basic tools to help defining defines, binding uniform for the common part of the materials.\r\n *\r\n * This works by convention in BabylonJS but is meant to be use only with shader following the in place naming rules and conventions.\r\n */\r\nexport class MaterialHelper {\r\n    /**\r\n     * Binds the scene's uniform buffer to the effect.\r\n     * @param effect defines the effect to bind to the scene uniform buffer\r\n     * @param sceneUbo defines the uniform buffer storing scene data\r\n     */\r\n    public static BindSceneUniformBuffer: (effect: Effect, sceneUbo: UniformBuffer) => void = BindSceneUniformBuffer;\r\n\r\n    /**\r\n     * Helps preparing the defines values about the UVs in used in the effect.\r\n     * UVs are shared as much as we can across channels in the shaders.\r\n     * @param texture The texture we are preparing the UVs for\r\n     * @param defines The defines to update\r\n     * @param key The channel key \"diffuse\", \"specular\"... used in the shader\r\n     */\r\n    public static PrepareDefinesForMergedUV: (texture: BaseTexture, defines: any, key: string) => void = PrepareDefinesForMergedUV;\r\n\r\n    /**\r\n     * Binds a texture matrix value to its corresponding uniform\r\n     * @param texture The texture to bind the matrix for\r\n     * @param uniformBuffer The uniform buffer receiving the data\r\n     * @param key The channel key \"diffuse\", \"specular\"... used in the shader\r\n     */\r\n    public static BindTextureMatrix: (texture: BaseTexture, uniformBuffer: UniformBuffer, key: string) => void = BindTextureMatrix;\r\n\r\n    /**\r\n     * Gets the current status of the fog (should it be enabled?)\r\n     * @param mesh defines the mesh to evaluate for fog support\r\n     * @param scene defines the hosting scene\r\n     * @returns true if fog must be enabled\r\n     */\r\n    public static GetFogState: (mesh: AbstractMesh, scene: Scene) => boolean = GetFogState;\r\n\r\n    /**\r\n     * Helper used to prepare the list of defines associated with misc. values for shader compilation\r\n     * @param mesh defines the current mesh\r\n     * @param scene defines the current scene\r\n     * @param useLogarithmicDepth defines if logarithmic depth has to be turned on\r\n     * @param pointsCloud defines if point cloud rendering has to be turned on\r\n     * @param fogEnabled defines if fog has to be turned on\r\n     * @param alphaTest defines if alpha testing has to be turned on\r\n     * @param defines defines the current list of defines\r\n     * @param applyDecalAfterDetail Defines if the decal is applied after or before the detail\r\n     */\r\n    public static PrepareDefinesForMisc: (\r\n        mesh: AbstractMesh,\r\n        scene: Scene,\r\n        useLogarithmicDepth: boolean,\r\n        pointsCloud: boolean,\r\n        fogEnabled: boolean,\r\n        alphaTest: boolean,\r\n        defines: any,\r\n        applyDecalAfterDetail?: boolean\r\n    ) => void = PrepareDefinesForMisc;\r\n\r\n    /**\r\n     * Helper used to prepare the defines relative to the active camera\r\n     * @param scene defines the current scene\r\n     * @param defines specifies the list of active defines\r\n     * @returns true if the defines have been updated, else false\r\n     */\r\n    public static PrepareDefinesForCamera: (scene: Scene, defines: any) => boolean = PrepareDefinesForCamera;\r\n\r\n    /**\r\n     * Helper used to prepare the list of defines associated with frame values for shader compilation\r\n     * @param scene defines the current scene\r\n     * @param engine defines the current engine\r\n     * @param material defines the material we are compiling the shader for\r\n     * @param defines specifies the list of active defines\r\n     * @param useInstances defines if instances have to be turned on\r\n     * @param useClipPlane defines if clip plane have to be turned on\r\n     * @param useThinInstances defines if thin instances have to be turned on\r\n     */\r\n    public static PrepareDefinesForFrameBoundValues: (\r\n        scene: Scene,\r\n        engine: AbstractEngine,\r\n        material: Material,\r\n        defines: any,\r\n        useInstances: boolean,\r\n        useClipPlane?: Nullable<boolean>,\r\n        useThinInstances?: boolean\r\n    ) => void = PrepareDefinesForFrameBoundValues;\r\n\r\n    /**\r\n     * Prepares the defines for bones\r\n     * @param mesh The mesh containing the geometry data we will draw\r\n     * @param defines The defines to update\r\n     */\r\n    public static PrepareDefinesForBones: (mesh: AbstractMesh, defines: any) => void = PrepareDefinesForBones;\r\n\r\n    /**\r\n     * Prepares the defines for morph targets\r\n     * @param mesh The mesh containing the geometry data we will draw\r\n     * @param defines The defines to update\r\n     */\r\n    public static PrepareDefinesForMorphTargets: (mesh: AbstractMesh, defines: any) => void = PrepareDefinesForMorphTargets;\r\n\r\n    /**\r\n     * Prepares the defines for baked vertex animation\r\n     * @param mesh The mesh containing the geometry data we will draw\r\n     * @param defines The defines to update\r\n     */\r\n    public static PrepareDefinesForBakedVertexAnimation: (mesh: AbstractMesh, defines: any) => void = PrepareDefinesForBakedVertexAnimation;\r\n\r\n    /**\r\n     * Prepares the defines used in the shader depending on the attributes data available in the mesh\r\n     * @param mesh The mesh containing the geometry data we will draw\r\n     * @param defines The defines to update\r\n     * @param useVertexColor Precise whether vertex colors should be used or not (override mesh info)\r\n     * @param useBones Precise whether bones should be used or not (override mesh info)\r\n     * @param useMorphTargets Precise whether morph targets should be used or not (override mesh info)\r\n     * @param useVertexAlpha Precise whether vertex alpha should be used or not (override mesh info)\r\n     * @param useBakedVertexAnimation Precise whether baked vertex animation should be used or not (override mesh info)\r\n     * @returns false if defines are considered not dirty and have not been checked\r\n     */\r\n    public static PrepareDefinesForAttributes: (\r\n        mesh: AbstractMesh,\r\n        defines: any,\r\n        useVertexColor: boolean,\r\n        useBones: boolean,\r\n        useMorphTargets?: boolean,\r\n        useVertexAlpha?: boolean,\r\n        useBakedVertexAnimation?: boolean\r\n    ) => boolean = PrepareDefinesForAttributes;\r\n\r\n    /**\r\n     * Prepares the defines related to multiview\r\n     * @param scene The scene we are intending to draw\r\n     * @param defines The defines to update\r\n     */\r\n    public static PrepareDefinesForMultiview: (scene: Scene, defines: any) => void = PrepareDefinesForMultiview;\r\n\r\n    /**\r\n     * Prepares the defines related to order independant transparency\r\n     * @param scene The scene we are intending to draw\r\n     * @param defines The defines to update\r\n     * @param needAlphaBlending Determines if the material needs alpha blending\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static PrepareDefinesForOIT: (scene: Scene, defines: any, needAlphaBlending: boolean) => void = PrepareDefinesForOIT;\r\n\r\n    /**\r\n     * Prepares the defines related to the prepass\r\n     * @param scene The scene we are intending to draw\r\n     * @param defines The defines to update\r\n     * @param canRenderToMRT Indicates if this material renders to several textures in the prepass\r\n     */\r\n    public static PrepareDefinesForPrePass: (scene: Scene, defines: any, canRenderToMRT: boolean) => void = PrepareDefinesForPrePass;\r\n\r\n    /**\r\n     * Prepares the defines related to the light information passed in parameter\r\n     * @param scene The scene we are intending to draw\r\n     * @param mesh The mesh the effect is compiling for\r\n     * @param light The light the effect is compiling for\r\n     * @param lightIndex The index of the light\r\n     * @param defines The defines to update\r\n     * @param specularSupported Specifies whether specular is supported or not (override lights data)\r\n     * @param state Defines the current state regarding what is needed (normals, etc...)\r\n     * @param state.needNormals\r\n     * @param state.needRebuild\r\n     * @param state.shadowEnabled\r\n     * @param state.specularEnabled\r\n     * @param state.lightmapMode\r\n     */\r\n    public static PrepareDefinesForLight: (\r\n        scene: Scene,\r\n        mesh: AbstractMesh,\r\n        light: Light,\r\n        lightIndex: number,\r\n        defines: any,\r\n        specularSupported: boolean,\r\n        state: {\r\n            needNormals: boolean;\r\n            needRebuild: boolean;\r\n            shadowEnabled: boolean;\r\n            specularEnabled: boolean;\r\n            lightmapMode: boolean;\r\n        }\r\n    ) => void = PrepareDefinesForLight;\r\n\r\n    /**\r\n     * Prepares the defines related to the light information passed in parameter\r\n     * @param scene The scene we are intending to draw\r\n     * @param mesh The mesh the effect is compiling for\r\n     * @param defines The defines to update\r\n     * @param specularSupported Specifies whether specular is supported or not (override lights data)\r\n     * @param maxSimultaneousLights Specifies how manuy lights can be added to the effect at max\r\n     * @param disableLighting Specifies whether the lighting is disabled (override scene and light)\r\n     * @returns true if normals will be required for the rest of the effect\r\n     */\r\n    public static PrepareDefinesForLights: (\r\n        scene: Scene,\r\n        mesh: AbstractMesh,\r\n        defines: any,\r\n        specularSupported: boolean,\r\n        maxSimultaneousLights?: number,\r\n        disableLighting?: boolean\r\n    ) => boolean = PrepareDefinesForLights;\r\n\r\n    /**\r\n     * Prepares the uniforms and samplers list to be used in the effect (for a specific light)\r\n     * @param lightIndex defines the light index\r\n     * @param uniformsList The uniform list\r\n     * @param samplersList The sampler list\r\n     * @param projectedLightTexture defines if projected texture must be used\r\n     * @param uniformBuffersList defines an optional list of uniform buffers\r\n     * @param updateOnlyBuffersList True to only update the uniformBuffersList array\r\n     */\r\n    public static PrepareUniformsAndSamplersForLight: (\r\n        lightIndex: number,\r\n        uniformsList: string[],\r\n        samplersList: string[],\r\n        projectedLightTexture?: any,\r\n        uniformBuffersList?: Nullable<string[]>,\r\n        updateOnlyBuffersList?: boolean\r\n    ) => void = PrepareUniformsAndSamplersForLight;\r\n\r\n    /**\r\n     * Prepares the uniforms and samplers list to be used in the effect\r\n     * @param uniformsListOrOptions The uniform names to prepare or an EffectCreationOptions containing the list and extra information\r\n     * @param samplersList The sampler list\r\n     * @param defines The defines helping in the list generation\r\n     * @param maxSimultaneousLights The maximum number of simultaneous light allowed in the effect\r\n     */\r\n    public static PrepareUniformsAndSamplersList: (\r\n        uniformsListOrOptions: string[] | IEffectCreationOptions,\r\n        samplersList?: string[],\r\n        defines?: any,\r\n        maxSimultaneousLights?: number\r\n    ) => void = PrepareUniformsAndSamplersList;\r\n\r\n    /**\r\n     * This helps decreasing rank by rank the shadow quality (0 being the highest rank and quality)\r\n     * @param defines The defines to update while falling back\r\n     * @param fallbacks The authorized effect fallbacks\r\n     * @param maxSimultaneousLights The maximum number of lights allowed\r\n     * @param rank the current rank of the Effect\r\n     * @returns The newly affected rank\r\n     */\r\n    public static HandleFallbacksForShadows: (defines: any, fallbacks: EffectFallbacks, maxSimultaneousLights?: number, rank?: number) => number = HandleFallbacksForShadows;\r\n\r\n    /**\r\n     * Prepares the list of attributes required for morph targets according to the effect defines.\r\n     * @param attribs The current list of supported attribs\r\n     * @param mesh The mesh to prepare the morph targets attributes for\r\n     * @param influencers The number of influencers\r\n     */\r\n    public static PrepareAttributesForMorphTargetsInfluencers: (attribs: string[], mesh: AbstractMesh, influencers: number) => void = PrepareAttributesForMorphTargetsInfluencers;\r\n\r\n    /**\r\n     * Prepares the list of attributes required for morph targets according to the effect defines.\r\n     * @param attribs The current list of supported attribs\r\n     * @param mesh The mesh to prepare the morph targets attributes for\r\n     * @param defines The current Defines of the effect\r\n     */\r\n    public static PrepareAttributesForMorphTargets: (attribs: string[], mesh: AbstractMesh, defines: any) => void = PrepareAttributesForMorphTargets;\r\n\r\n    /**\r\n     * Prepares the list of attributes required for baked vertex animations according to the effect defines.\r\n     * @param attribs The current list of supported attribs\r\n     * @param mesh The mesh to prepare for baked vertex animations\r\n     * @param defines The current Defines of the effect\r\n     */\r\n    public static PrepareAttributesForBakedVertexAnimation: (attribs: string[], mesh: AbstractMesh, defines: any) => void = PrepareAttributesForBakedVertexAnimation;\r\n\r\n    /**\r\n     * Prepares the list of attributes required for bones according to the effect defines.\r\n     * @param attribs The current list of supported attribs\r\n     * @param mesh The mesh to prepare the bones attributes for\r\n     * @param defines The current Defines of the effect\r\n     * @param fallbacks The current effect fallback strategy\r\n     */\r\n    public static PrepareAttributesForBones: (attribs: string[], mesh: AbstractMesh, defines: any, fallbacks: EffectFallbacks) => void = PrepareAttributesForBones;\r\n\r\n    /**\r\n     * Check and prepare the list of attributes required for instances according to the effect defines.\r\n     * @param attribs The current list of supported attribs\r\n     * @param defines The current MaterialDefines of the effect\r\n     */\r\n    public static PrepareAttributesForInstances: (attribs: string[], defines: MaterialDefines) => void = PrepareAttributesForInstances;\r\n\r\n    /**\r\n     * Add the list of attributes required for instances to the attribs array.\r\n     * @param attribs The current list of supported attribs\r\n     * @param needsPreviousMatrices If the shader needs previous matrices\r\n     */\r\n    public static PushAttributesForInstances: (attribs: string[], needsPreviousMatrices?: boolean) => void = PushAttributesForInstances;\r\n\r\n    /**\r\n     * Binds the light information to the effect.\r\n     * @param light The light containing the generator\r\n     * @param effect The effect we are binding the data to\r\n     * @param lightIndex The light index in the effect used to render\r\n     */\r\n    public static BindLightProperties: (light: Light, effect: Effect, lightIndex: number) => void = BindLightProperties;\r\n\r\n    /**\r\n     * Binds the lights information from the scene to the effect for the given mesh.\r\n     * @param light Light to bind\r\n     * @param lightIndex Light index\r\n     * @param scene The scene where the light belongs to\r\n     * @param effect The effect we are binding the data to\r\n     * @param useSpecular Defines if specular is supported\r\n     * @param receiveShadows Defines if the effect (mesh) we bind the light for receives shadows\r\n     */\r\n    public static BindLight: (light: Light, lightIndex: number, scene: Scene, effect: Effect, useSpecular: boolean, receiveShadows?: boolean) => void = BindLight;\r\n\r\n    /**\r\n     * Binds the lights information from the scene to the effect for the given mesh.\r\n     * @param scene The scene the lights belongs to\r\n     * @param mesh The mesh we are binding the information to render\r\n     * @param effect The effect we are binding the data to\r\n     * @param defines The generated defines for the effect\r\n     * @param maxSimultaneousLights The maximum number of light that can be bound to the effect\r\n     */\r\n    public static BindLights: (scene: Scene, mesh: AbstractMesh, effect: Effect, defines: any, maxSimultaneousLights?: number) => void = BindLights;\r\n\r\n    /**\r\n     * Binds the fog information from the scene to the effect for the given mesh.\r\n     * @param scene The scene the lights belongs to\r\n     * @param mesh The mesh we are binding the information to render\r\n     * @param effect The effect we are binding the data to\r\n     * @param linearSpace Defines if the fog effect is applied in linear space\r\n     */\r\n    public static BindFogParameters: (scene: Scene, mesh?: AbstractMesh, effect?: Effect, linearSpace?: boolean) => void = BindFogParameters;\r\n\r\n    /**\r\n     * Binds the bones information from the mesh to the effect.\r\n     * @param mesh The mesh we are binding the information to render\r\n     * @param effect The effect we are binding the data to\r\n     * @param prePassConfiguration Configuration for the prepass, in case prepass is activated\r\n     */\r\n    public static BindBonesParameters: (mesh?: AbstractMesh, effect?: Effect, prePassConfiguration?: PrePassConfiguration) => void = BindBonesParameters;\r\n\r\n    /**\r\n     * Binds the morph targets information from the mesh to the effect.\r\n     * @param abstractMesh The mesh we are binding the information to render\r\n     * @param effect The effect we are binding the data to\r\n     */\r\n    public static BindMorphTargetParameters: (abstractMesh: AbstractMesh, effect: Effect) => void = BindMorphTargetParameters;\r\n\r\n    /**\r\n     * Binds the logarithmic depth information from the scene to the effect for the given defines.\r\n     * @param defines The generated defines used in the effect\r\n     * @param effect The effect we are binding the data to\r\n     * @param scene The scene we are willing to render with logarithmic scale for\r\n     */\r\n    public static BindLogDepth: (defines: any, effect: Effect, scene: Scene) => void = BindLogDepth;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { ShaderMaterial } from \"../shaderMaterial.pure\";\r\n\r\n/**\r\n * A material to use for fast depth-only rendering.\r\n * @since 5.0.0\r\n */\r\nexport class OcclusionMaterial extends ShaderMaterial {\r\n    constructor(name: string, scene: Scene) {\r\n        super(name, scene, \"color\", {\r\n            attributes: [\"position\"],\r\n            uniforms: [\"world\", \"viewProjection\", \"color\"],\r\n        });\r\n        this.disableColorWrite = true;\r\n        this.forceDepthWrite = true;\r\n        this.setColor4(\"color\", new Color4(0, 0, 0, 1));\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\n\nconst name = \"colorPixelShader\";\nconst shader = `#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\n#define VERTEXCOLOR\nvarying vec4 vColor;\n#else\nuniform vec4 color;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\ngl_FragColor=vColor;\n#else\ngl_FragColor=color;\n#endif\n#include<fogFragment>(color,gl_FragColor)\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclaration, fogFragmentDeclaration, clipPlaneFragment, fogFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const colorPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"vertexColorMixing\";\nconst shader = `#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvColor=vec4(1.0);\n#ifdef VERTEXCOLOR\n#ifdef VERTEXALPHA\nvColor*=colorUpdated;\n#else\nvColor.rgb*=colorUpdated.rgb;\n#endif\n#endif\n#ifdef INSTANCESCOLOR\nvColor*=instanceColor;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const vertexColorMixing = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { vertexColorMixing } from \"./ShadersInclude/vertexColorMixing\";\n\nconst name = \"colorVertexShader\";\nconst shader = `attribute vec3 position;\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#ifdef FOG\nuniform mat4 view;\n#endif\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vec4 vColor;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef VERTEXCOLOR\nvec4 colorUpdated=color;\n#endif\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(position,1.0);\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {gl_Position=viewProjection*worldPos;} else {gl_Position=viewProjectionR*worldPos;}\n#else\ngl_Position=viewProjection*worldPos;\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<vertexColorMixing>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, clipPlaneVertexDeclaration, fogVertexDeclaration, instancesDeclaration, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex, fogVertex, vertexColorMixing];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const colorVertexShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { CubeMapToSphericalPolynomialTools } from \"../../Misc/HighDynamicRange/cubemapToSphericalPolynomial\";\r\nimport { type SphericalPolynomial } from \"../../Maths/sphericalPolynomial.pure\";\r\nimport { BaseTexture } from \"./baseTexture.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for baseTexturePolynomial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBaseTexturePolynomial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    BaseTexture.prototype._sphericalPolynomialTargetSize = 0;\r\n\r\n    BaseTexture.prototype.forceSphericalPolynomialsRecompute = function (): void {\r\n        if (this._texture) {\r\n            this._texture._sphericalPolynomial = null;\r\n            this._texture._sphericalPolynomialPromise = null;\r\n            this._texture._sphericalPolynomialComputed = false;\r\n        }\r\n    };\r\n\r\n    Object.defineProperty(BaseTexture.prototype, \"sphericalPolynomial\", {\r\n        get: function (this: BaseTexture) {\r\n            if (this._texture) {\r\n                if (this._texture._sphericalPolynomial || this._texture._sphericalPolynomialComputed) {\r\n                    return this._texture._sphericalPolynomial;\r\n                }\r\n\r\n                if (this._texture.isReady) {\r\n                    if (!this._texture._sphericalPolynomialPromise) {\r\n                        this._texture._sphericalPolynomialPromise = CubeMapToSphericalPolynomialTools.ConvertCubeMapTextureToSphericalPolynomial(this);\r\n                        if (this._texture._sphericalPolynomialPromise === null) {\r\n                            this._texture._sphericalPolynomialComputed = true;\r\n                        } else {\r\n                            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                            this._texture._sphericalPolynomialPromise.then((sphericalPolynomial) => {\r\n                                this._texture!._sphericalPolynomial = sphericalPolynomial;\r\n                                this._texture!._sphericalPolynomialComputed = true;\r\n                            });\r\n                        }\r\n                    }\r\n\r\n                    return null;\r\n                }\r\n            }\r\n\r\n            return null;\r\n        },\r\n        set: function (this: BaseTexture, value: Nullable<SphericalPolynomial>) {\r\n            if (this._texture) {\r\n                this._texture._sphericalPolynomial = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","import { serialize, serializeAsColor3, expandToProperty, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { PBRBaseMaterial } from \"./pbrBaseMaterial.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * The Physically based simple base material of BJS.\r\n *\r\n * This enables better naming and convention enforcements on top of the pbrMaterial.\r\n * It is used as the base class for both the specGloss and metalRough conventions.\r\n */\r\nexport abstract class PBRBaseSimpleMaterial extends PBRBaseMaterial {\r\n    /**\r\n     * Number of Simultaneous lights allowed on the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor maxSimultaneousLights = 4;\r\n\r\n    /**\r\n     * If sets to true, disables all the lights affecting the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsLightsDirty\")\r\n    public accessor disableLighting = false;\r\n\r\n    /**\r\n     * Environment Texture used in the material (this is use for both reflection and environment lighting).\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_reflectionTexture\")\r\n    public accessor environmentTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * If sets to true, x component of normal map value will invert (x = 1.0 - x).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapX = false;\r\n\r\n    /**\r\n     * If sets to true, y component of normal map value will invert (y = 1.0 - y).\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor invertNormalMapY = false;\r\n\r\n    /**\r\n     * Normal map used in the model.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_bumpTexture\")\r\n    public accessor normalTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Emissivie color used to self-illuminate the model.\r\n     */\r\n    @serializeAsColor3(\"emissive\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor emissiveColor = new Color3(0, 0, 0);\r\n\r\n    /**\r\n     * Emissivie texture used to self-illuminate the model.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor emissiveTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Occlusion Channel Strength.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_ambientTextureStrength\")\r\n    public accessor occlusionStrength: number = 1.0;\r\n\r\n    /**\r\n     * Occlusion Texture of the material (adding extra occlusion effects).\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_ambientTexture\")\r\n    public accessor occlusionTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_alphaCutOff\")\r\n    public accessor alphaCutOff: number;\r\n\r\n    /**\r\n     * Gets the current double sided mode.\r\n     */\r\n    @serialize()\r\n    public get doubleSided(): boolean {\r\n        return this._twoSidedLighting;\r\n    }\r\n    /**\r\n     * If sets to true and backfaceCulling is false, normals will be flipped on the backside.\r\n     */\r\n    public set doubleSided(value: boolean) {\r\n        if (this._twoSidedLighting === value) {\r\n            return;\r\n        }\r\n        this._twoSidedLighting = value;\r\n        this.backFaceCulling = !value;\r\n        this._markAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * Stores the pre-calculated light information of a mesh in a texture.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", null)\r\n    public accessor lightmapTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * If true, the light map contains occlusion information instead of lighting info.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor useLightmapAsShadowmap = false;\r\n\r\n    /**\r\n     * Instantiates a new PBRMaterial instance.\r\n     *\r\n     * @param name The material name\r\n     * @param scene The scene the material will be use in.\r\n     */\r\n    constructor(name: string, scene?: Scene) {\r\n        super(name, scene);\r\n\r\n        this._useAlphaFromAlbedoTexture = true;\r\n        this._useAmbientInGrayScale = true;\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"PBRBaseSimpleMaterial\";\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsColor3, expandToProperty, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { PBRBaseSimpleMaterial } from \"./pbrBaseSimpleMaterial\";\r\nimport { RegisterImageProcessingConfiguration } from \"../imageProcessingConfiguration.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * The PBR material of BJS following the metal roughness convention.\r\n *\r\n * This fits to the PBR convention in the GLTF definition:\r\n * https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/README.md\r\n */\r\nexport class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial {\r\n    /**\r\n     * The base color has two different interpretations depending on the value of metalness.\r\n     * When the material is a metal, the base color is the specific measured reflectance value\r\n     * at normal incidence (F0). For a non-metal the base color represents the reflected diffuse color\r\n     * of the material.\r\n     */\r\n    @serializeAsColor3()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_albedoColor\")\r\n    public accessor baseColor: Color3;\r\n\r\n    /**\r\n     * Base texture of the metallic workflow. It contains both the baseColor information in RGB as\r\n     * well as opacity information in the alpha channel.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_albedoTexture\")\r\n    public accessor baseTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Specifies the metallic scalar value of the material.\r\n     * Can also be used to scale the metalness values of the metallic texture.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor metallic: number;\r\n\r\n    /**\r\n     * Specifies the roughness scalar value of the material.\r\n     * Can also be used to scale the roughness values of the metallic texture.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor roughness: number;\r\n\r\n    /**\r\n     * Texture containing both the metallic value in the B channel and the\r\n     * roughness value in the G channel to keep better precision.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_metallicTexture\")\r\n    public accessor metallicRoughnessTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Instantiates a new PBRMetalRoughnessMaterial instance.\r\n     *\r\n     * @param name The material name\r\n     * @param scene The scene the material will be use in.\r\n     */\r\n    constructor(name: string, scene?: Scene) {\r\n        super(name, scene);\r\n        this._useRoughnessFromMetallicTextureAlpha = false;\r\n        this._useRoughnessFromMetallicTextureGreen = true;\r\n        this._useMetallnessFromMetallicTextureBlue = true;\r\n        this.metallic = 1.0;\r\n        this.roughness = 1.0;\r\n    }\r\n\r\n    /**\r\n     * @returns the current class name of the material.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PBRMetallicRoughnessMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current material.\r\n     * @param name - name to use for the new material.\r\n     * @returns cloned material instance\r\n     */\r\n    public override clone(name: string): PBRMetallicRoughnessMaterial {\r\n        const clone = SerializationHelper.Clone(() => new PBRMetallicRoughnessMaterial(name, this.getScene()), this);\r\n\r\n        clone.id = name;\r\n        clone.name = name;\r\n\r\n        this.clearCoat.copyTo(clone.clearCoat);\r\n        this.anisotropy.copyTo(clone.anisotropy);\r\n        this.brdf.copyTo(clone.brdf);\r\n        this.sheen.copyTo(clone.sheen);\r\n        this.subSurface.copyTo(clone.subSurface);\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serialize the material to a parsable JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        serializationObject.customType = \"BABYLON.PBRMetallicRoughnessMaterial\";\r\n\r\n        if (!this.clearCoat.doNotSerialize) {\r\n            serializationObject.clearCoat = this.clearCoat.serialize();\r\n        }\r\n        if (!this.anisotropy.doNotSerialize) {\r\n            serializationObject.anisotropy = this.anisotropy.serialize();\r\n        }\r\n        if (!this.brdf.doNotSerialize) {\r\n            serializationObject.brdf = this.brdf.serialize();\r\n        }\r\n        if (!this.sheen.doNotSerialize) {\r\n            serializationObject.sheen = this.sheen.serialize();\r\n        }\r\n        if (!this.subSurface.doNotSerialize) {\r\n            serializationObject.subSurface = this.subSurface.serialize();\r\n        }\r\n        if (!this.iridescence.doNotSerialize) {\r\n            serializationObject.iridescence = this.iridescence.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON object corresponding to the serialize function.\r\n     * @param source - JSON source object.\r\n     * @param scene - Defines the scene we are parsing for\r\n     * @param rootUrl - Defines the rootUrl of this parsed object\r\n     * @returns a new PBRMetalRoughnessMaterial\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): PBRMetallicRoughnessMaterial {\r\n        const material = SerializationHelper.Parse(() => new PBRMetallicRoughnessMaterial(source.name, scene), source, scene, rootUrl);\r\n        if (source.clearCoat) {\r\n            material.clearCoat.parse(source.clearCoat, scene, rootUrl);\r\n        }\r\n        if (source.anisotropy) {\r\n            material.anisotropy.parse(source.anisotropy, scene, rootUrl);\r\n        }\r\n        if (source.brdf) {\r\n            material.brdf.parse(source.brdf, scene, rootUrl);\r\n        }\r\n        if (source.sheen) {\r\n            material.sheen.parse(source.sheen, scene, rootUrl);\r\n        }\r\n        if (source.subSurface) {\r\n            material.subSurface.parse(source.subSurface, scene, rootUrl);\r\n        }\r\n        if (source.iridescence) {\r\n            material.iridescence.parse(source.iridescence, scene, rootUrl);\r\n        }\r\n        return material;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pbrMetallicRoughnessMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPbrMetallicRoughnessMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // PBRMetallicRoughnessMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\r\n    RegisterImageProcessingConfiguration();\r\n\r\n    RegisterClass(\"BABYLON.PBRMetallicRoughnessMaterial\", PBRMetallicRoughnessMaterial);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, serializeAsColor3, expandToProperty, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { PBRBaseSimpleMaterial } from \"./pbrBaseSimpleMaterial\";\r\nimport { RegisterImageProcessingConfiguration } from \"../imageProcessingConfiguration.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * The PBR material of BJS following the specular glossiness convention.\r\n *\r\n * This fits to the PBR convention in the GLTF definition:\r\n * https://github.com/KhronosGroup/glTF/tree/2.0/extensions/Khronos/KHR_materials_pbrSpecularGlossiness\r\n */\r\nexport class PBRSpecularGlossinessMaterial extends PBRBaseSimpleMaterial {\r\n    /**\r\n     * Specifies the diffuse color of the material.\r\n     */\r\n    @serializeAsColor3(\"diffuse\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_albedoColor\")\r\n    public accessor diffuseColor: Color3;\r\n\r\n    /**\r\n     * Specifies the diffuse texture of the material. This can also contains the opacity value in its alpha\r\n     * channel.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_albedoTexture\")\r\n    public accessor diffuseTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Specifies the specular color of the material. This indicates how reflective is the material (none to mirror).\r\n     */\r\n    @serializeAsColor3(\"specular\")\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_reflectivityColor\")\r\n    public accessor specularColor: Color3;\r\n\r\n    /**\r\n     * Specifies the glossiness of the material. This indicates \"how sharp is the reflection\".\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_microSurface\")\r\n    public accessor glossiness: number;\r\n\r\n    /**\r\n     * Specifies both the specular color RGB and the glossiness A of the material per pixels.\r\n     */\r\n    @serializeAsTexture()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\", \"_reflectivityTexture\")\r\n    public accessor specularGlossinessTexture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.\r\n     */\r\n    public get useMicroSurfaceFromReflectivityMapAlpha() {\r\n        return this._useMicroSurfaceFromReflectivityMapAlpha;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new PBRSpecularGlossinessMaterial instance.\r\n     *\r\n     * @param name The material name\r\n     * @param scene The scene the material will be use in.\r\n     */\r\n    constructor(name: string, scene?: Scene) {\r\n        super(name, scene);\r\n        this._useMicroSurfaceFromReflectivityMapAlpha = true;\r\n    }\r\n\r\n    /**\r\n     * @returns the current class name of the material.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"PBRSpecularGlossinessMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current material.\r\n     * @param name - name to use for the new material.\r\n     * @returns cloned material instance\r\n     */\r\n    public override clone(name: string): PBRSpecularGlossinessMaterial {\r\n        const clone = SerializationHelper.Clone(() => new PBRSpecularGlossinessMaterial(name, this.getScene()), this);\r\n\r\n        clone.id = name;\r\n        clone.name = name;\r\n\r\n        this.clearCoat.copyTo(clone.clearCoat);\r\n        this.anisotropy.copyTo(clone.anisotropy);\r\n        this.brdf.copyTo(clone.brdf);\r\n        this.sheen.copyTo(clone.sheen);\r\n        this.subSurface.copyTo(clone.subSurface);\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serialize the material to a parsable JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = SerializationHelper.Serialize(this);\r\n        serializationObject.customType = \"BABYLON.PBRSpecularGlossinessMaterial\";\r\n\r\n        if (!this.clearCoat.doNotSerialize) {\r\n            serializationObject.clearCoat = this.clearCoat.serialize();\r\n        }\r\n        if (!this.anisotropy.doNotSerialize) {\r\n            serializationObject.anisotropy = this.anisotropy.serialize();\r\n        }\r\n        if (!this.brdf.doNotSerialize) {\r\n            serializationObject.brdf = this.brdf.serialize();\r\n        }\r\n        if (!this.sheen.doNotSerialize) {\r\n            serializationObject.sheen = this.sheen.serialize();\r\n        }\r\n        if (!this.subSurface.doNotSerialize) {\r\n            serializationObject.subSurface = this.subSurface.serialize();\r\n        }\r\n        if (!this.iridescence.doNotSerialize) {\r\n            serializationObject.iridescence = this.iridescence.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON object corresponding to the serialize function.\r\n     * @param source - JSON source object.\r\n     * @param scene - the scene to parse to.\r\n     * @param rootUrl - root url of the assets.\r\n     * @returns a new PBRSpecularGlossinessMaterial.\r\n     */\r\n    public static override Parse(source: any, scene: Scene, rootUrl: string): PBRSpecularGlossinessMaterial {\r\n        const material = SerializationHelper.Parse(() => new PBRSpecularGlossinessMaterial(source.name, scene), source, scene, rootUrl);\r\n        if (source.clearCoat) {\r\n            material.clearCoat.parse(source.clearCoat, scene, rootUrl);\r\n        }\r\n        if (source.anisotropy) {\r\n            material.anisotropy.parse(source.anisotropy, scene, rootUrl);\r\n        }\r\n        if (source.brdf) {\r\n            material.brdf.parse(source.brdf, scene, rootUrl);\r\n        }\r\n        if (source.sheen) {\r\n            material.sheen.parse(source.sheen, scene, rootUrl);\r\n        }\r\n        if (source.subSurface) {\r\n            material.subSurface.parse(source.subSurface, scene, rootUrl);\r\n        }\r\n        if (source.iridescence) {\r\n            material.iridescence.parse(source.iridescence, scene, rootUrl);\r\n        }\r\n        return material;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pbrSpecularGlossinessMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPbrSpecularGlossinessMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // PBRSpecularGlossinessMaterial serializes its image processing configuration, so the parser must be registered for clone/parse to work.\r\n    RegisterImageProcessingConfiguration();\r\n\r\n    RegisterClass(\"BABYLON.PBRSpecularGlossinessMaterial\", PBRSpecularGlossinessMaterial);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"pbrUboDeclaration\";\nconst shader = `uniform vAlbedoInfos: vec2f;uniform vBaseWeightInfos: vec2f;uniform vBaseDiffuseRoughnessInfos: vec2f;uniform vAmbientInfos: vec4f;uniform vOpacityInfos: vec2f;uniform vEmissiveInfos: vec2f;uniform vLightmapInfos: vec2f;uniform vReflectivityInfos: vec3f;uniform vMicroSurfaceSamplerInfos: vec2f;uniform vBumpInfos: vec3f;uniform albedoMatrix: mat4x4f;uniform baseWeightMatrix: mat4x4f;uniform baseDiffuseRoughnessMatrix: mat4x4f;uniform ambientMatrix: mat4x4f;uniform opacityMatrix: mat4x4f;uniform emissiveMatrix: mat4x4f;uniform lightmapMatrix: mat4x4f;uniform reflectivityMatrix: mat4x4f;uniform microSurfaceSamplerMatrix: mat4x4f;uniform bumpMatrix: mat4x4f;uniform vTangentSpaceParams: vec2f;uniform vAlbedoColor: vec4f;uniform baseWeight: f32;uniform baseDiffuseRoughness: f32;uniform vLightingIntensity: vec4f;uniform pointSize: f32;uniform vReflectivityColor: vec4f;uniform vEmissiveColor: vec3f;uniform vAmbientColor: vec3f;uniform vDebugMode: vec2f;uniform vMetallicReflectanceFactors: vec4f;uniform vMetallicReflectanceInfos: vec2f;uniform metallicReflectanceMatrix: mat4x4f;uniform vReflectanceInfos: vec2f;uniform reflectanceMatrix: mat4x4f;uniform cameraInfo: vec4f;uniform vTextureRepetitionHexTilingParams: vec4f;uniform vReflectionInfos: vec2f;uniform reflectionMatrix: mat4x4f;uniform vReflectionMicrosurfaceInfos: vec3f;uniform vReflectionPosition: vec3f;uniform vReflectionSize: vec3f;uniform vReflectionFilteringInfo: vec2f;uniform vReflectionDominantDirection: vec3f;uniform vReflectionColor: vec3f;uniform vSphericalL00: vec3f;uniform vSphericalL1_1: vec3f;uniform vSphericalL10: vec3f;uniform vSphericalL11: vec3f;uniform vSphericalL2_2: vec3f;uniform vSphericalL2_1: vec3f;uniform vSphericalL20: vec3f;uniform vSphericalL21: vec3f;uniform vSphericalL22: vec3f;uniform vSphericalX: vec3f;uniform vSphericalY: vec3f;uniform vSphericalZ: vec3f;uniform vSphericalXX_ZZ: vec3f;uniform vSphericalYY_ZZ: vec3f;uniform vSphericalZZ: vec3f;uniform vSphericalXY: vec3f;uniform vSphericalYZ: vec3f;uniform vSphericalZX: vec3f;\n#define ADDITIONAL_UBO_DECLARATION\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"uvAttributeDeclaration\";\nconst shader = `#if defined(UV{X}) && !defined(USE_VERTEX_PULLING)\nattribute uv{X}: vec2f;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const uvAttributeDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"mainUVVaryingDeclaration\";\nconst shader = `#ifdef MAINUV{X}\nvarying vMainUV{X}: vec2f;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const mainUVVaryingDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBRDFFunctions\";\nconst shader = `#define FRESNEL_MAXIMUM_ON_ROUGH 0.25\n#define BRDF_DIFFUSE_MODEL_EON 0\n#define BRDF_DIFFUSE_MODEL_BURLEY 1\n#define BRDF_DIFFUSE_MODEL_LAMBERT 2\n#define BRDF_DIFFUSE_MODEL_LEGACY 3\n#define DIELECTRIC_SPECULAR_MODEL_GLTF 0\n#define DIELECTRIC_SPECULAR_MODEL_OPENPBR 1\n#define CONDUCTOR_SPECULAR_MODEL_GLTF 0\n#define CONDUCTOR_SPECULAR_MODEL_OPENPBR 1\n#if !defined(PBR_VERTEX_SHADER) && !defined(OPENPBR_VERTEX_SHADER)\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nfn getEnergyConservationFactor(specularEnvironmentR0: vec3f,environmentBrdf: vec3f)->vec3f {return 1.0+specularEnvironmentR0*(1.0/environmentBrdf.y-1.0);}\n#endif\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nconst F82_COS_THETA_MAX: f32 =0.142857143;const F82_ONE_MINUS_CTM_POW5: f32 =0.462664366;const F82_ONE_MINUS_CTM_POW6: f32 =0.396569457;const F82_B_DENOMINATOR_RECIP: f32 =17.6512785;const BRDF_Z_SCALE: f32 =16.0;fn getF82Specular(NdotV: f32,F0: vec3f,edgeTint: vec3f,roughness: f32)->vec3f {let white_minus_F0: vec3f=vec3f(1.0f)-F0;let b_numerator: vec3f=(F0+white_minus_F0*F82_ONE_MINUS_CTM_POW5)*(vec3f(1.0)-edgeTint);let b: vec3f=b_numerator*F82_B_DENOMINATOR_RECIP;let cos_theta: f32=max(roughness,NdotV);let one_minus_cos_theta: f32=1.0-cos_theta;let offset_from_F0: vec3f=(white_minus_F0-b*cos_theta*one_minus_cos_theta)*pow(one_minus_cos_theta,5.0f);return clamp(F0+offset_from_F0,vec3f(0.0f),vec3f(1.0f));}\nfn getF82B(F0: vec3f,edgeTint: vec3f)->vec3f {return (F0+(vec3f(1.0)-F0)*F82_ONE_MINUS_CTM_POW5)*(vec3f(1.0)-edgeTint)*F82_B_DENOMINATOR_RECIP;}\nfn getF82DirectionalAlbedo(F0: vec3f,F90: vec3f,b: vec3f,environmentBrdf: vec3f)->vec3f {return (F90-F0)*environmentBrdf.x+F0*environmentBrdf.y-b*environmentBrdf.z;}\nfn getF82AverageFresnel(F0: vec3f,b: vec3f)->vec3f {return F0+(vec3f(1.0)-F0)/21.0-b/126.0;}\n#endif\n#ifdef FUZZENVIRONMENTBRDF\nfn getFuzzBRDFLookup(NdotV: f32,perceptualRoughness: f32)->vec3f {let UV: vec2f=vec2f(perceptualRoughness,NdotV);var brdfLookup: vec4f=textureSample(environmentFuzzBrdfSampler,environmentFuzzBrdfSamplerSampler,UV);const RiRange: vec2f=vec2f(0.0f,0.75f);const ARange: vec2f=vec2f(0.005f,0.88f);const BRange: vec2f=vec2f(-0.18f,0.002f);brdfLookup.r=mix(ARange.x, ARange.y, brdfLookup.r);brdfLookup.g=mix(BRange.x, BRange.y, brdfLookup.g);brdfLookup.b=mix(RiRange.x,RiRange.y,brdfLookup.b);return brdfLookup.rgb;}\n#endif\n#ifdef ENVIRONMENTBRDF\nfn getBRDFLookup(NdotV: f32,perceptualRoughness: f32)->vec3f {var UV: vec2f= vec2f(NdotV,perceptualRoughness);var brdfLookup: vec4f= textureSample(environmentBrdfSampler,environmentBrdfSamplerSampler,UV);\n#ifdef ENVIRONMENTBRDF_RGBD\nbrdfLookup=vec4f(fromRGBD(brdfLookup.rgba),brdfLookup.a);\n#endif\nreturn brdfLookup.rgb;}\nfn getReflectanceFromBRDFWithEnvLookup(specularEnvironmentR0: vec3f,specularEnvironmentR90: vec3f,environmentBrdf: vec3f)->vec3f {\n#ifdef BRDF_V_HEIGHT_CORRELATED\nvar reflectance: vec3f=(specularEnvironmentR90-specularEnvironmentR0)*environmentBrdf.x+specularEnvironmentR0*environmentBrdf.y;\n#else\nvar reflectance: vec3f=specularEnvironmentR0*environmentBrdf.x+specularEnvironmentR90*environmentBrdf.y;\n#endif\nreturn reflectance;}\nfn getReflectanceFromBRDFLookup(specularEnvironmentR0: vec3f,environmentBrdf: vec3f)->vec3f {\n#ifdef BRDF_V_HEIGHT_CORRELATED\nvar reflectance: vec3f=mix(environmentBrdf.xxx,environmentBrdf.yyy,specularEnvironmentR0);\n#else\nvar reflectance: vec3f=specularEnvironmentR0*environmentBrdf.x+environmentBrdf.y;\n#endif\nreturn reflectance;}\n#endif\n/* NOT USED\n#if defined(SHEEN) && defined(SHEEN_SOFTER)\nfn getBRDFLookupCharlieSheen(NdotV: f32,perceptualRoughness: f32)->f32\n{var c: f32=1.0-NdotV;var c3: f32=c*c*c;return 0.65584461*c3+1.0/(4.16526551+exp(-7.97291361*perceptualRoughness+6.33516894));}\n#endif\n*/\n#if !defined(ENVIRONMENTBRDF) || defined(REFLECTIONMAP_SKYBOX) || defined(ALPHAFRESNEL)\nfn getReflectanceFromAnalyticalBRDFLookup_Jones(VdotN: f32,reflectance0: vec3f,reflectance90: vec3f,smoothness: f32)->vec3f\n{var weight: f32=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);return reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));}\n#endif\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF)\n/**\n* The sheen BRDF not containing F can be easily stored in the blue channel of the BRDF texture.\n* The blue channel contains DCharlie*VAshikhmin*NdotL as a lokkup table\n*/\nfn getSheenReflectanceFromBRDFLookup(reflectance0: vec3f,environmentBrdf: vec3f)->vec3f {var sheenEnvironmentReflectance: vec3f=reflectance0*environmentBrdf.b;return sheenEnvironmentReflectance;}\n#endif\nfn fresnelSchlickGGXVec3(VdotH: f32,reflectance0: vec3f,reflectance90: vec3f)->vec3f\n{return reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);}\nfn fresnelSchlickGGX(VdotH: f32,reflectance0: f32,reflectance90: f32)->f32\n{return reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);}\n#ifdef CLEARCOAT\nfn getR0RemappedForClearCoat(f0: vec3f)->vec3f {\n#ifdef CLEARCOAT_DEFAULTIOR\n#ifdef MOBILE\nreturn saturateVec3(f0*(f0*0.526868+0.529324)-0.0482256);\n#else\nreturn saturateVec3(f0*(f0*(0.941892-0.263008*f0)+0.346479)-0.0285998);\n#endif\n#else\nvar s: vec3f=sqrt(f0);var t: vec3f=(uniforms.vClearCoatRefractionParams.z+uniforms.vClearCoatRefractionParams.w*s)/(uniforms.vClearCoatRefractionParams.w+uniforms.vClearCoatRefractionParams.z*s);return squareVec3(t);\n#endif\n}\n#endif\n#ifdef IRIDESCENCE\nconst XYZ_TO_REC709: mat3x3f= mat3x3f(\n3.2404542,-0.9692660, 0.0556434,\n-1.5371385, 1.8760108,-0.2040259,\n-0.4985314, 0.0415560, 1.0572252\n);fn getIORTfromAirToSurfaceR0(f0: vec3f)->vec3f {var sqrtF0: vec3f=sqrt(f0);return (1.+sqrtF0)/(1.-sqrtF0);}\nfn getR0fromIORsVec3(iorT: vec3f,iorI: f32)->vec3f {return squareVec3((iorT- vec3f(iorI))/(iorT+ vec3f(iorI)));}\nfn getR0fromIORs(iorT: f32,iorI: f32)->f32 {return square((iorT-iorI)/(iorT+iorI));}\nfn evalSensitivity(opd: f32,shift: vec3f)->vec3f {var phase: f32=2.0*PI*opd*1.0e-9;const val: vec3f= vec3f(5.4856e-13,4.4201e-13,5.2481e-13);const pos: vec3f= vec3f(1.6810e+06,1.7953e+06,2.2084e+06);const vr: vec3f= vec3f(4.3278e+09,9.3046e+09,6.6121e+09);var xyz: vec3f=val*sqrt(2.0*PI*vr)*cos(pos*phase+shift)*exp(-square(phase)*vr);xyz.x+=9.7470e-14*sqrt(2.0*PI*4.5282e+09)*cos(2.2399e+06*phase+shift[0])*exp(-4.5282e+09*square(phase));xyz/=1.0685e-7;var srgb: vec3f=XYZ_TO_REC709*xyz;return srgb;}\nfn evalIridescence(outsideIOR: f32,eta2: f32,cosTheta1: f32,thinFilmThickness: f32,baseF0: vec3f)->vec3f {var I: vec3f= vec3f(1.0);var iridescenceIOR: f32=mix(outsideIOR,eta2,smoothstep(0.0,0.03,thinFilmThickness));var sinTheta2Sq: f32=square(outsideIOR/iridescenceIOR)*(1.0-square(cosTheta1));var cosTheta2Sq: f32=1.0-sinTheta2Sq;if (cosTheta2Sq<0.0) {return I;}\nvar cosTheta2: f32=sqrt(cosTheta2Sq);var R0: f32=getR0fromIORs(iridescenceIOR,outsideIOR);var R12: f32=fresnelSchlickGGX(cosTheta1,R0,1.);var R21: f32=R12;var T121: f32=1.0-R12;var phi12: f32=0.0;if (iridescenceIOR<outsideIOR) {phi12=PI;}\nvar phi21: f32=PI-phi12;var baseIOR: vec3f=getIORTfromAirToSurfaceR0(clamp(baseF0,vec3f(0.0),vec3f(0.9999))); \nvar R1: vec3f=getR0fromIORsVec3(baseIOR,iridescenceIOR);let maxR1: f32=max(R1.r,max(R1.g,R1.b));if (maxR1<1e-6) {return max(vec3f(R12),vec3f(0.0));}\nvar R23: vec3f=fresnelSchlickGGXVec3(cosTheta2,R1,vec3f(1.));var phi23: vec3f=vec3f(0.0);if (baseIOR[0]<iridescenceIOR) {phi23[0]=PI;}\nif (baseIOR[1]<iridescenceIOR) {phi23[1]=PI;}\nif (baseIOR[2]<iridescenceIOR) {phi23[2]=PI;}\nvar opd: f32=2.0*iridescenceIOR*thinFilmThickness*cosTheta2;var phi: vec3f=vec3f(phi21)+phi23;var R123: vec3f=clamp(R12*R23,vec3f(1e-5),vec3f(0.9999));var r123: vec3f=sqrt(R123);var Rs: vec3f=(T121*T121)*R23/(vec3f(1.0)-R123);var C0: vec3f=R12+Rs;I=C0;var Cm: vec3f=Rs-T121;for (var m: i32=1; m<=2; m++)\n{Cm*=r123;var Sm: vec3f=2.0*evalSensitivity(f32(m)*opd,f32(m)*phi);I+=Cm*Sm;}\nreturn max(I,vec3f(0.0));}\n#endif\nfn normalDistributionFunction_TrowbridgeReitzGGX(NdotH: f32,alphaG: f32)->f32\n{var a2: f32=alphaG*alphaG;var d: f32=NdotH*NdotH*(a2-1.0)+1.0;return a2/(PI*d*d);}\n#ifdef SHEEN\nfn normalDistributionFunction_CharlieSheen(NdotH: f32,alphaG: f32)->f32\n{var invR: f32=1./alphaG;var cos2h: f32=NdotH*NdotH;var sin2h: f32=1.-cos2h;return (2.+invR)*pow(sin2h,invR*.5)/(2.*PI);}\n#endif\n#ifdef ANISOTROPIC\nfn normalDistributionFunction_BurleyGGX_Anisotropic(NdotH: f32,TdotH: f32,BdotH: f32,alphaTB: vec2f)->f32 {var a2: f32=alphaTB.x*alphaTB.y;var v: vec3f= vec3f(alphaTB.y*TdotH,alphaTB.x *BdotH,a2*NdotH);var v2: f32=dot(v,v);var w2: f32=a2/v2;return a2*w2*w2*RECIPROCAL_PI;}\n#endif\n#ifdef BRDF_V_HEIGHT_CORRELATED\nfn smithVisibility_GGXCorrelated(NdotL: f32,NdotV: f32,alphaG: f32)->f32 {\n#ifdef MOBILE\nvar GGXV: f32=NdotL*(NdotV*(1.0-alphaG)+alphaG);var GGXL: f32=NdotV*(NdotL*(1.0-alphaG)+alphaG);return 0.5/(GGXV+GGXL);\n#else\nvar a2: f32=alphaG*alphaG;var GGXV: f32=NdotL*sqrt(NdotV*(NdotV-a2*NdotV)+a2);var GGXL: f32=NdotV*sqrt(NdotL*(NdotL-a2*NdotL)+a2);return 0.5/(GGXV+GGXL);\n#endif\n}\n#else\nfn smithVisibilityG1_TrowbridgeReitzGGXFast(dot: f32,alphaG: f32)->f32\n{\n#ifdef MOBILE\nreturn 1.0/(dot+alphaG+(1.0-alphaG)*dot ));\n#else\nvar alphaSquared: f32=alphaG*alphaG;return 1.0/(dot+sqrt(alphaSquared+(1.0-alphaSquared)*dot*dot));\n#endif\n}\nfn smithVisibility_TrowbridgeReitzGGXFast(NdotL: f32,NdotV: f32,alphaG: f32)->f32\n{var visibility: f32=smithVisibilityG1_TrowbridgeReitzGGXFast(NdotL,alphaG)*smithVisibilityG1_TrowbridgeReitzGGXFast(NdotV,alphaG);return visibility;}\n#endif\n#ifdef ANISOTROPIC\nfn smithVisibility_GGXCorrelated_Anisotropic(NdotL: f32,NdotV: f32,TdotV: f32,BdotV: f32,TdotL: f32,BdotL: f32,alphaTB: vec2f)->f32 {var lambdaV: f32=NdotL*length( vec3f(alphaTB.x*TdotV,alphaTB.y*BdotV,NdotV));var lambdaL: f32=NdotV*length( vec3f(alphaTB.x*TdotL,alphaTB.y*BdotL,NdotL));var v: f32=0.5/(lambdaV+lambdaL);return v;}\n#endif\n#ifdef CLEARCOAT\nfn visibility_Kelemen(VdotH: f32)->f32 {return 0.25/(VdotH*VdotH); }\n#endif\n#ifdef SHEEN\nfn visibility_Ashikhmin(NdotL: f32,NdotV: f32)->f32\n{return 1./(4.*(NdotL+NdotV-NdotL*NdotV));}\n/* NOT USED\n#ifdef SHEEN_SOFTER\nfn l(x: f32,alphaG: f32)->f32\n{var oneMinusAlphaSq: f32=(1.0-alphaG)*(1.0-alphaG);var a: f32=mix(21.5473,25.3245,oneMinusAlphaSq);var b: f32=mix(3.82987,3.32435,oneMinusAlphaSq);var c: f32=mix(0.19823,0.16801,oneMinusAlphaSq);var d: f32=mix(-1.97760,-1.27393,oneMinusAlphaSq);var e: f32=mix(-4.32054,-4.85967,oneMinusAlphaSq);return a/(1.0+b*pow(x,c))+d*x+e;}\nfn lambdaSheen(cosTheta: f32,alphaG: f32)->f32\n{return abs(cosTheta)<0.5 ? exp(l(cosTheta,alphaG)) : exp(2.0*l(0.5,alphaG)-l(1.0-cosTheta,alphaG));}\nfn visibility_CharlieSheen(NdotL: f32,NdotV: f32,alphaG: f32)->f32\n{var G: f32=1.0/(1.0+lambdaSheen(NdotV,alphaG)+lambdaSheen(NdotL,alphaG));return G/(4.0*NdotV*NdotL);}\n#endif\n*/\n#endif\nconst constant1_FON: f32=0.5f-2.0f/(3.0f*PI);const constant2_FON: f32=2.0f/3.0f-28.0f/(15.0f*PI);fn E_FON_approx(mu: f32,roughness: f32)->f32\n{var sigma: f32=roughness; \nvar mucomp: f32=1.0f-mu;var mucomp2: f32=mucomp*mucomp;const Gcoeffs: mat2x2f=mat2x2f(0.0571085289f,-0.332181442f,\n0.491881867f,0.0714429953f);var GoverPi: f32=dot(Gcoeffs*vec2f(mucomp,mucomp2),vec2f(1.0f,mucomp2));return (1.0f+sigma*GoverPi)/(1.0f+constant1_FON*sigma);}\nfn diffuseBRDF_EON(albedo: vec3f,roughness: f32,NdotL: f32,NdotV: f32,LdotV: f32)->vec3f\n{var rho: vec3f=albedo;var sigma: f32=roughness; \nvar mu_i: f32=NdotL; \nvar mu_o: f32=NdotV; \nvar s: f32=LdotV-mu_i*mu_o; \nvar sovertF: f32=select(s,s/max(mu_i,mu_o),s>0.0f); \nvar AF: f32=1.0f/(1.0f+constant1_FON*sigma); \nvar f_ss: vec3f=(rho*RECIPROCAL_PI)*AF*(1.0f+sigma*sovertF); \nvar EFo: f32=E_FON_approx(mu_o,sigma); \nvar EFi: f32=E_FON_approx(mu_i,sigma); \nvar avgEF: f32=AF*(1.0f+constant2_FON*sigma); \nvar rho_ms: vec3f=(rho*rho)*avgEF/(vec3f(1.0f)-rho*(1.0f-avgEF));const eps: f32=1.0e-7f;var f_ms: vec3f=(rho_ms*RECIPROCAL_PI)*max(eps,1.0f-EFo) \n* max(eps,1.0f-EFi)\n/ max(eps,1.0f-avgEF);return (f_ss+f_ms);}\nfn diffuseBRDF_Burley(NdotL: f32,NdotV: f32,VdotH: f32,roughness: f32)->f32 {var diffuseFresnelNV: f32=pow5(saturateEps(1.0-NdotL));var diffuseFresnelNL: f32=pow5(saturateEps(1.0-NdotV));var diffuseFresnel90: f32=0.5+2.0*VdotH*VdotH*roughness;var fresnel: f32 =\n(1.0+(diffuseFresnel90-1.0)*diffuseFresnelNL) *\n(1.0+(diffuseFresnel90-1.0)*diffuseFresnelNV);return fresnel/PI;}\n#ifdef SS_TRANSLUCENCY\nfn transmittanceBRDF_Burley(tintColor: vec3f,diffusionDistance: vec3f,thickness: f32)->vec3f {var S: vec3f=1./maxEpsVec3(diffusionDistance);var temp: vec3f=exp((-0.333333333*thickness)*S);return tintColor.rgb*0.25*(temp*temp*temp+3.0*temp);}\nfn computeWrappedDiffuseNdotL(NdotL: f32,w: f32)->f32 {var t: f32=1.0+w;var invt2: f32=1.0/(t*t);return saturate((NdotL+w)*invt2);}\n#endif\n#endif \n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBRDFFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"prePassVertexDeclaration\";\nconst shader = `#ifdef PREPASS\n#ifdef PREPASS_LOCAL_POSITION\nvarying vPosition : vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vViewPos: vec3f;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vNormViewDepth: f32;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nuniform previousViewProjection: mat4x4f;varying vCurrentPosition: vec4f;varying vPreviousPosition: vec4f;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const prePassVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerVertexDeclaration\";\nconst shader = `#if defined(_DEFINENAME_) && _DEFINENAME_DIRECTUV==0\nvarying v_VARYINGNAME_UV: vec2f;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const samplerVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"harmonicsFunctions\";\nconst shader = `#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nfn computeEnvironmentIrradiance(normal: vec3f)->vec3f {return uniforms.vSphericalL00\n+ uniforms.vSphericalL1_1*(normal.y)\n+ uniforms.vSphericalL10*(normal.z)\n+ uniforms.vSphericalL11*(normal.x)\n+ uniforms.vSphericalL2_2*(normal.y*normal.x)\n+ uniforms.vSphericalL2_1*(normal.y*normal.z)\n+ uniforms.vSphericalL20*((3.0*normal.z*normal.z)-1.0)\n+ uniforms.vSphericalL21*(normal.z*normal.x)\n+ uniforms.vSphericalL22*(normal.x*normal.x-(normal.y*normal.y));}\n#else\nfn computeEnvironmentIrradiance(normal: vec3f)->vec3f {var Nx: f32=normal.x;var Ny: f32=normal.y;var Nz: f32=normal.z;var C1: vec3f=uniforms.vSphericalZZ.rgb;var Cx: vec3f=uniforms.vSphericalX.rgb;var Cy: vec3f=uniforms.vSphericalY.rgb;var Cz: vec3f=uniforms.vSphericalZ.rgb;var Cxx_zz: vec3f=uniforms.vSphericalXX_ZZ.rgb;var Cyy_zz: vec3f=uniforms.vSphericalYY_ZZ.rgb;var Cxy: vec3f=uniforms.vSphericalXY.rgb;var Cyz: vec3f=uniforms.vSphericalYZ.rgb;var Czx: vec3f=uniforms.vSphericalZX.rgb;var a1: vec3f=Cyy_zz*Ny+Cy;var a2: vec3f=Cyz*Nz+a1;var b1: vec3f=Czx*Nz+Cx;var b2: vec3f=Cxy*Ny+b1;var b3: vec3f=Cxx_zz*Nx+b2;var t1: vec3f=Cz *Nz+C1;var t2: vec3f=a2 *Ny+t1;var t3: vec3f=b3 *Nx+t2;return t3;}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const harmonicsFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpVertexDeclaration\";\nconst shader = `#if defined(BUMP) || defined(PARALLAX) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL) \nvarying vTBN0: vec3f;varying vTBN1: vec3f;varying vTBN2: vec3f;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bumpVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"vertexPullingDeclaration\";\nconst shader = `#ifdef USE_VERTEX_PULLING\n#ifdef VERTEX_PULLING_USE_INDEX_BUFFER\nvar<storage,read> indices : array<u32>;\n#endif\nvar<storage,read> position : array<f32>;uniform vp_position_info : vec4f;\n#ifdef NORMAL\nvar<storage,read> normal : array<f32>;uniform vp_normal_info : vec4f;\n#endif\n#ifdef TANGENT\nvar<storage,read> tangent : array<f32>;uniform vp_tangent_info : vec4f;\n#endif\n#ifdef UV1\nvar<storage,read> uv : array<f32>;uniform vp_uv_info : vec4f;\n#define VP_UV1_SUPPORTED\n#endif\n#ifdef UV2\nvar<storage,read> uv2 : array<f32>;uniform vp_uv2_info : vec4f;\n#define VP_UV2_SUPPORTED\n#endif\n#ifdef UV3\nvar<storage,read> uv3 : array<f32>;uniform vp_uv3_info : vec4f;\n#define VP_UV3_SUPPORTED\n#endif\n#ifdef UV4\nvar<storage,read> uv4 : array<f32>;uniform vp_uv4_info : vec4f;\n#define VP_UV4_SUPPORTED\n#endif\n#ifdef UV5\nvar<storage,read> uv5 : array<f32>;uniform vp_uv5_info : vec4f;\n#define VP_UV5_SUPPORTED\n#endif\n#ifdef UV6\nvar<storage,read> uv6 : array<f32>;uniform vp_uv6_info : vec4f;\n#define VP_UV6_SUPPORTED\n#endif\n#ifdef VERTEXCOLOR\nvar<storage,read> color : array<f32>;uniform vp_color_info : vec4f;\n#endif\n#if NUM_BONE_INFLUENCERS>0\nvar<storage,read> matricesIndices : array<u32>;var<storage,read> matricesWeights : array<f32>;uniform vp_matricesIndices_info : vec4f;uniform vp_matricesWeights_info : vec4f;\n#if NUM_BONE_INFLUENCERS>4\nvar<storage,read> matricesIndicesExtra : array<u32>;var<storage,read> matricesWeightsExtra : array<f32>;uniform vp_matricesIndicesExtra_info : vec4f;uniform vp_matricesWeightsExtra_info : vec4f;\n#endif\n#endif\nfn vp_convertToFloat(word : u32,byteInWord : u32,dataType : u32,normalized : bool)->f32 {switch (dataType) {case 5120u: { \nlet shift=byteInWord*8u;let value=(word>>shift) & 0xFFu;let signedValue=f32(i32(value<<24u)>>24u);if (normalized) { return signedValue/127.0; }\nreturn signedValue;}\ncase 5121u: { \nlet shift=byteInWord*8u;let value=(word>>shift) & 0xFFu;if (normalized) { return f32(value)/255.0; }\nreturn f32(value);}\ncase 5122u: { \nlet shift=(byteInWord & 0xFFFFFFFEu)*8u;let value=(word>>shift) & 0xFFFFu;let signedValue=f32(i32(value<<16u)>>16u);if (normalized) { return signedValue/32767.0; }\nreturn signedValue;}\ncase 5123u: { \nlet shift=(byteInWord & 0xFFFFFFFEu)*8u;let value=(word>>shift) & 0xFFFFu;if (normalized) { return f32(value)/65535.0; }\nreturn f32(value);}\ncase 5126u: { \nreturn bitcast<f32>(word);}\ndefault: { return 0.0; }}}\nfn vp_componentSize(dataType : u32)->u32 {return select(select(2u,1u,dataType==5120u || dataType==5121u),4u,dataType==5126u);}\nfn vp_readVertexIndex(index : u32)->u32 {\n#ifndef VERTEX_PULLING_USE_INDEX_BUFFER\nreturn index;\n#else\n#ifdef VERTEX_PULLING_INDEX_BUFFER_32BITS\nreturn indices[index];\n#else\nlet u32_index=index/2u;let bit_offset=(index & 1u)*16u;return (indices[u32_index]>>bit_offset) & 0xFFFFu;\n#endif\n#endif\n}\nfn vp_readPositionValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(position[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readPosition(info : vec4f,vertexIndex : u32)->vec3f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec3f(\nvp_readPositionValue(offset,dataType,normalized),\nvp_readPositionValue(offset+cs,dataType,normalized),\nvp_readPositionValue(offset+cs*2u,dataType,normalized)\n);}\n#ifdef NORMAL\nfn vp_readNormalValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(normal[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readNormal(info : vec4f,vertexIndex : u32)->vec3f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec3f(\nvp_readNormalValue(offset,dataType,normalized),\nvp_readNormalValue(offset+cs,dataType,normalized),\nvp_readNormalValue(offset+cs*2u,dataType,normalized)\n);}\n#endif\n#ifdef TANGENT\nfn vp_readTangentValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(tangent[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readTangent(info : vec4f,vertexIndex : u32)->vec4f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec4f(\nvp_readTangentValue(offset,dataType,normalized),\nvp_readTangentValue(offset+cs,dataType,normalized),\nvp_readTangentValue(offset+cs*2u,dataType,normalized),\nvp_readTangentValue(offset+cs*3u,dataType,normalized)\n);}\n#endif\n#ifdef UV1\nfn vp_readUVValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(uv[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readUV(info : vec4f,vertexIndex : u32)->vec2f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec2f(\nvp_readUVValue(offset,dataType,normalized),\nvp_readUVValue(offset+cs,dataType,normalized)\n);}\n#endif\n#ifdef UV2\nfn vp_readUV2Value(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(uv2[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readUV2(info : vec4f,vertexIndex : u32)->vec2f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec2f(\nvp_readUV2Value(offset,dataType,normalized),\nvp_readUV2Value(offset+cs,dataType,normalized)\n);}\n#endif\n#ifdef UV3\nfn vp_readUV3Value(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(uv3[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readUV3(info : vec4f,vertexIndex : u32)->vec2f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec2f(\nvp_readUV3Value(offset,dataType,normalized),\nvp_readUV3Value(offset+cs,dataType,normalized)\n);}\n#endif\n#ifdef UV4\nfn vp_readUV4Value(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(uv4[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readUV4(info : vec4f,vertexIndex : u32)->vec2f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec2f(\nvp_readUV4Value(offset,dataType,normalized),\nvp_readUV4Value(offset+cs,dataType,normalized)\n);}\n#endif\n#ifdef UV5\nfn vp_readUV5Value(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(uv5[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readUV5(info : vec4f,vertexIndex : u32)->vec2f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec2f(\nvp_readUV5Value(offset,dataType,normalized),\nvp_readUV5Value(offset+cs,dataType,normalized)\n);}\n#endif\n#ifdef UV6\nfn vp_readUV6Value(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(uv6[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readUV6(info : vec4f,vertexIndex : u32)->vec2f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec2f(\nvp_readUV6Value(offset,dataType,normalized),\nvp_readUV6Value(offset+cs,dataType,normalized)\n);}\n#endif\n#ifdef VERTEXCOLOR\nfn vp_readColorValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(color[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readColor(info : vec4f,vertexIndex : u32)->vec4f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec4f(\nvp_readColorValue(offset,dataType,normalized),\nvp_readColorValue(offset+cs,dataType,normalized),\nvp_readColorValue(offset+cs*2u,dataType,normalized),\nvp_readColorValue(offset+cs*3u,dataType,normalized)\n);}\n#endif\n#if NUM_BONE_INFLUENCERS>0\nfn vp_readMatrixIndexValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(matricesIndices[byteOffset/4u],byteOffset % 4u,dataType,normalized);}\nfn vp_readBoneIndices(info : vec4f,vertexIndex : u32)->vec4f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec4f(\nvp_readMatrixIndexValue(offset,dataType,normalized),\nvp_readMatrixIndexValue(offset+cs,dataType,normalized),\nvp_readMatrixIndexValue(offset+cs*2u,dataType,normalized),\nvp_readMatrixIndexValue(offset+cs*3u,dataType,normalized)\n);}\nfn vp_readMatrixWeightValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(matricesWeights[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readBoneWeights(info : vec4f,vertexIndex : u32)->vec4f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec4f(\nvp_readMatrixWeightValue(offset,dataType,normalized),\nvp_readMatrixWeightValue(offset+cs,dataType,normalized),\nvp_readMatrixWeightValue(offset+cs*2u,dataType,normalized),\nvp_readMatrixWeightValue(offset+cs*3u,dataType,normalized)\n);}\n#if NUM_BONE_INFLUENCERS>4\nfn vp_readMatrixIndexExtraValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(matricesIndicesExtra[byteOffset/4u],byteOffset % 4u,dataType,normalized);}\nfn vp_readBoneIndicesExtra(info : vec4f,vertexIndex : u32)->vec4f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec4f(\nvp_readMatrixIndexExtraValue(offset,dataType,normalized),\nvp_readMatrixIndexExtraValue(offset+cs,dataType,normalized),\nvp_readMatrixIndexExtraValue(offset+cs*2u,dataType,normalized),\nvp_readMatrixIndexExtraValue(offset+cs*3u,dataType,normalized)\n);}\nfn vp_readMatrixWeightExtraValue(byteOffset : u32,dataType : u32,normalized : bool)->f32 {return vp_convertToFloat(bitcast<u32>(matricesWeightsExtra[byteOffset/4u]),byteOffset % 4u,dataType,normalized);}\nfn vp_readBoneWeightsExtra(info : vec4f,vertexIndex : u32)->vec4f {let baseOffset=u32(info.x);let stride=u32(info.y);let dataType=u32(info.z);let normalized=info.w != 0.0;let offset=baseOffset+vertexIndex*stride;let cs=vp_componentSize(dataType);return vec4f(\nvp_readMatrixWeightExtraValue(offset,dataType,normalized),\nvp_readMatrixWeightExtraValue(offset+cs,dataType,normalized),\nvp_readMatrixWeightExtraValue(offset+cs*2u,dataType,normalized),\nvp_readMatrixWeightExtraValue(offset+cs*3u,dataType,normalized)\n);}\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const vertexPullingDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"vertexPullingVertex\";\nconst shader = `#ifdef USE_VERTEX_PULLING\nlet vpVertexIndex: u32=vp_readVertexIndex(vertexInputs.vertexIndex);positionUpdated=vp_readPosition(uniforms.vp_position_info,vpVertexIndex);\n#ifdef NORMAL\nnormalUpdated=vp_readNormal(uniforms.vp_normal_info,vpVertexIndex);\n#endif\n#ifdef TANGENT\ntangentUpdated=vp_readTangent(uniforms.vp_tangent_info,vpVertexIndex);\n#endif\n#ifdef UV1\nuvUpdated=vp_readUV(uniforms.vp_uv_info,vpVertexIndex);\n#endif\n#ifdef UV2\nuv2Updated=vp_readUV2(uniforms.vp_uv2_info,vpVertexIndex);\n#endif\n#ifdef UV3\nvar uv3Updated: vec2f=vp_readUV3(uniforms.vp_uv3_info,vpVertexIndex);\n#endif\n#ifdef UV4\nvar uv4Updated: vec2f=vp_readUV4(uniforms.vp_uv4_info,vpVertexIndex);\n#endif\n#ifdef UV5\nvar uv5Updated: vec2f=vp_readUV5(uniforms.vp_uv5_info,vpVertexIndex);\n#endif\n#ifdef UV6\nvar uv6Updated: vec2f=vp_readUV6(uniforms.vp_uv6_info,vpVertexIndex);\n#endif\n#ifdef VERTEXCOLOR\ncolorUpdated=vp_readColor(uniforms.vp_color_info,vpVertexIndex);\n#endif\n#ifdef MORPHTARGETS\nlet vp_basePosition: vec3f=positionUpdated;\n#ifdef NORMAL\nlet vp_baseNormal: vec3f=normalUpdated;\n#endif\n#ifdef TANGENT\nlet vp_baseTangent: vec4f=tangentUpdated;\n#endif\n#ifdef UV1\nlet vp_baseUV: vec2f=uvUpdated;\n#endif\n#ifdef UV2\nlet vp_baseUV2: vec2f=uv2Updated;\n#endif\n#ifdef VERTEXCOLOR\nlet vp_baseColor: vec4f=colorUpdated;\n#endif\n#endif\n#if NUM_BONE_INFLUENCERS>0\nvar vp_matricesIndices: vec4f=vp_readBoneIndices(uniforms.vp_matricesIndices_info,vpVertexIndex);var vp_matricesWeights: vec4f=vp_readBoneWeights(uniforms.vp_matricesWeights_info,vpVertexIndex);\n#if NUM_BONE_INFLUENCERS>4\nvar vp_matricesIndicesExtra: vec4f=vp_readBoneIndicesExtra(uniforms.vp_matricesIndicesExtra_info,vpVertexIndex);var vp_matricesWeightsExtra: vec4f=vp_readBoneWeightsExtra(uniforms.vp_matricesWeightsExtra_info,vpVertexIndex);\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const vertexPullingVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"prePassVertex\";\nconst shader = `#ifdef PREPASS_DEPTH\nvertexOutputs.vViewPos=(scene.view*worldPos).rgb;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvertexOutputs.vNormViewDepth=((scene.view*worldPos).z-uniforms.cameraInfo.x)/(uniforms.cameraInfo.y-uniforms.cameraInfo.x);\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvertexOutputs.vPosition=positionUpdated.xyz;\n#endif\n#if (defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && defined(BONES_VELOCITY_ENABLED)\nvertexOutputs.vCurrentPosition=scene.viewProjection*worldPos;\n#if NUM_BONE_INFLUENCERS>0\nvar previousInfluence: mat4x4f;previousInfluence=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[0])]*vertexInputs.matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[1])]*vertexInputs.matricesWeights[1];\n#endif \n#if NUM_BONE_INFLUENCERS>2\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[2])]*vertexInputs.matricesWeights[2];\n#endif \n#if NUM_BONE_INFLUENCERS>3\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[3])]*vertexInputs.matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[0])]*vertexInputs.matricesWeightsExtra[0];\n#endif \n#if NUM_BONE_INFLUENCERS>5\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[1])]*vertexInputs.matricesWeightsExtra[1];\n#endif \n#if NUM_BONE_INFLUENCERS>6\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[2])]*vertexInputs.matricesWeightsExtra[2];\n#endif \n#if NUM_BONE_INFLUENCERS>7\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[3])]*vertexInputs.matricesWeightsExtra[3];\n#endif\nvertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld*previousInfluence* vec4f(positionUpdated,1.0);\n#else\nvertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld* vec4f(positionUpdated,1.0);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const prePassVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"uvVariableDeclaration\";\nconst shader = `#ifdef MAINUV{X}\n#if !defined(UV{X})\nvar uv{X}: vec2f=vec2f(0.,0.);\n#elif defined(USE_VERTEX_PULLING)\nvar uv{X}: vec2f=uv{X}Updated;\n#else\nvar uv{X}: vec2f=vertexInputs.uv{X};\n#endif\nvertexOutputs.vMainUV{X}=uv{X};\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const uvVariableDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerVertexImplementation\";\nconst shader = `#if defined(_DEFINENAME_) && _DEFINENAME_DIRECTUV==0\nif (uniforms.v_INFONAME_==0.)\n{vertexOutputs.v_VARYINGNAME_UV= (uniforms._MATRIXNAME_Matrix* vec4f(uvUpdated,1.0,0.0)).xy;}\n#ifdef UV2\nelse if (uniforms.v_INFONAME_==1.)\n{vertexOutputs.v_VARYINGNAME_UV= (uniforms._MATRIXNAME_Matrix* vec4f(uv2Updated,1.0,0.0)).xy;}\n#endif\n#ifdef UV3\nelse if (uniforms.v_INFONAME_==2.)\n{vertexOutputs.v_VARYINGNAME_UV= (uniforms._MATRIXNAME_Matrix* vec4f(vertexInputs.uv3,1.0,0.0)).xy;}\n#endif\n#ifdef UV4\nelse if (uniforms.v_INFONAME_==3.)\n{vertexOutputs.v_VARYINGNAME_UV= (uniforms._MATRIXNAME_Matrix* vec4f(vertexInputs.uv4,1.0,0.0)).xy;}\n#endif\n#ifdef UV5\nelse if (uniforms.v_INFONAME_==4.)\n{vertexOutputs.v_VARYINGNAME_UV= (uniforms._MATRIXNAME_Matrix* vec4f(vertexInputs.uv5,1.0,0.0)).xy;}\n#endif\n#ifdef UV6\nelse if (uniforms.v_INFONAME_==5.)\n{vertexOutputs.v_VARYINGNAME_UV= (uniforms._MATRIXNAME_Matrix* vec4f(vertexInputs.uv6,1.0,0.0)).xy;}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const samplerVertexImplementationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpVertex\";\nconst shader = `#if defined(BUMP) || defined(PARALLAX) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL)\nvar tbnNormal: vec3f=normalize(normalUpdated);var tbnTangent: vec3f=normalize(tangentUpdated.xyz);var tbnBitangent: vec3f=cross(tbnNormal,tbnTangent)*tangentUpdated.w;var matTemp= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz)* mat3x3f(tbnTangent,tbnBitangent,tbnNormal);vertexOutputs.vTBN0=matTemp[0];vertexOutputs.vTBN1=matTemp[1];vertexOutputs.vTBN2=matTemp[2];\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bumpVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"vertexColorMixing\";\nconst shader = `#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvertexOutputs.vColor=vec4f(1.0);\n#ifdef VERTEXCOLOR\n#ifdef VERTEXALPHA\nvertexOutputs.vColor*=colorUpdated;\n#else\nvertexOutputs.vColor=vec4f(vertexOutputs.vColor.rgb*colorUpdated.rgb,vertexOutputs.vColor.a);\n#endif\n#endif\n#ifdef INSTANCESCOLOR\nvertexOutputs.vColor*=vertexInputs.instanceColor;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const vertexColorMixingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { pbrUboDeclarationWGSL } from \"./ShadersInclude/pbrUboDeclaration\";\nimport { uvAttributeDeclarationWGSL } from \"./ShadersInclude/uvAttributeDeclaration\";\nimport { mainUVVaryingDeclarationWGSL } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { prePassVertexDeclarationWGSL } from \"./ShadersInclude/prePassVertexDeclaration\";\nimport { samplerVertexDeclarationWGSL } from \"./ShadersInclude/samplerVertexDeclaration\";\nimport { harmonicsFunctionsWGSL } from \"./ShadersInclude/harmonicsFunctions\";\nimport { bumpVertexDeclarationWGSL } from \"./ShadersInclude/bumpVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxUboDeclarationWGSL } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { vertexPullingDeclarationWGSL } from \"./ShadersInclude/vertexPullingDeclaration\";\nimport { vertexPullingVertexWGSL } from \"./ShadersInclude/vertexPullingVertex\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { prePassVertexWGSL } from \"./ShadersInclude/prePassVertex\";\nimport { uvVariableDeclarationWGSL } from \"./ShadersInclude/uvVariableDeclaration\";\nimport { samplerVertexImplementationWGSL } from \"./ShadersInclude/samplerVertexImplementation\";\nimport { bumpVertexWGSL } from \"./ShadersInclude/bumpVertex\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertexWGSL } from \"./ShadersInclude/shadowsVertex\";\nimport { vertexColorMixingWGSL } from \"./ShadersInclude/vertexColorMixing\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"pbrVertexShader\";\nconst shader = `#define PBR_VERTEX_SHADER\n#include<pbrUboDeclaration>\n#define CUSTOM_VERTEX_BEGIN\n#ifndef USE_VERTEX_PULLING\nattribute position: vec3f;\n#ifdef NORMAL\nattribute normal: vec3f;\n#endif\n#ifdef TANGENT\nattribute tangent: vec4f;\n#endif\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#include<uvAttributeDeclaration>[2..7]\n#ifdef VERTEXCOLOR\nattribute color: vec4f;\n#endif\n#endif\n#include<mainUVVaryingDeclaration>[1..7]\n#include<helperFunctions>\n#include<pbrBRDFFunctions>\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<prePassVertexDeclaration>\n#include<samplerVertexDeclaration>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail)\n#include<samplerVertexDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient)\n#include<samplerVertexDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive)\n#include<samplerVertexDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap)\n#include<samplerVertexDeclaration>(_DEFINENAME_,REFLECTIVITY,_VARYINGNAME_,Reflectivity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,MICROSURFACEMAP,_VARYINGNAME_,MicroSurfaceSampler)\n#include<samplerVertexDeclaration>(_DEFINENAME_,METALLIC_REFLECTANCE,_VARYINGNAME_,MetallicReflectance)\n#include<samplerVertexDeclaration>(_DEFINENAME_,REFLECTANCE,_VARYINGNAME_,Reflectance)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal)\n#ifdef CLEARCOAT\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE,_VARYINGNAME_,ClearCoat)\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE_ROUGHNESS,_VARYINGNAME_,ClearCoatRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_BUMP,_VARYINGNAME_,ClearCoatBump)\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_TINT_TEXTURE,_VARYINGNAME_,ClearCoatTint)\n#endif\n#ifdef IRIDESCENCE\n#include<samplerVertexDeclaration>(_DEFINENAME_,IRIDESCENCE_TEXTURE,_VARYINGNAME_,Iridescence)\n#include<samplerVertexDeclaration>(_DEFINENAME_,IRIDESCENCE_THICKNESS_TEXTURE,_VARYINGNAME_,IridescenceThickness)\n#endif\n#ifdef SHEEN\n#include<samplerVertexDeclaration>(_DEFINENAME_,SHEEN_TEXTURE,_VARYINGNAME_,Sheen)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SHEEN_TEXTURE_ROUGHNESS,_VARYINGNAME_,SheenRoughness)\n#endif\n#ifdef ANISOTROPIC\n#include<samplerVertexDeclaration>(_DEFINENAME_,ANISOTROPIC_TEXTURE,_VARYINGNAME_,Anisotropy)\n#endif\n#ifdef SUBSURFACE\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor)\n#endif\nvarying vPositionW: vec3f;\n#if DEBUGMODE>0\nvarying vClipSpacePosition: vec4f;\n#endif\n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vEnvironmentIrradiance: vec3f;\n#include<harmonicsFunctions>\n#endif\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vColor: vec4f;\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<lightVxUboDeclaration>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying vViewDepth: f32;\n#endif\n#include<logDepthDeclaration>\n#include<vertexPullingDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef USE_VERTEX_PULLING\nvar positionUpdated: vec3f=vec3f(0.0);\n#ifdef NORMAL\nvar normalUpdated: vec3f=vec3f(0.0);\n#endif\n#ifdef TANGENT\nvar tangentUpdated: vec4f=vec4f(0.0);\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vec2f(0.0);\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vec2f(0.0);\n#endif\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vec4f(0.0);\n#endif\n#else\nvar positionUpdated: vec3f=vertexInputs.position;\n#ifdef NORMAL\nvar normalUpdated: vec3f=vertexInputs.normal;\n#endif\n#ifdef TANGENT\nvar tangentUpdated: vec4f=vertexInputs.tangent;\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vertexInputs.color;\n#endif\n#endif\n#include<vertexPullingVertex>\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvertexOutputs.vPositionUVW=positionUpdated;\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#if defined(PREPASS) && ((defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvertexOutputs.vCurrentPosition=scene.viewProjection*finalWorld*vec4f(positionUpdated,1.0);vertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld*vec4f(positionUpdated,1.0);\n#endif\n#ifdef USE_VERTEX_PULLING\n#include<bonesVertex>(vertexInputs.matricesIndices,vp_matricesIndices,vertexInputs.matricesWeights,vp_matricesWeights,vertexInputs.matricesIndicesExtra,vp_matricesIndicesExtra,vertexInputs.matricesWeightsExtra,vp_matricesWeightsExtra)\n#include<bakedVertexAnimation>(vertexInputs.matricesIndices,vp_matricesIndices,vertexInputs.matricesWeights,vp_matricesWeights,vertexInputs.matricesIndicesExtra,vp_matricesIndicesExtra,vertexInputs.matricesWeightsExtra,vp_matricesWeightsExtra)\n#else\n#include<bonesVertex>\n#include<bakedVertexAnimation>\n#endif\nvar worldPos: vec4f=finalWorld* vec4f(positionUpdated,1.0);vertexOutputs.vPositionW= worldPos.xyz;\n#ifdef PREPASS\n#include<prePassVertex>\n#endif\n#ifdef NORMAL\nvar normalWorld: mat3x3f= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvertexOutputs.vNormalW=normalUpdated/ vec3f(dot(normalWorld[0],normalWorld[0]),dot(normalWorld[1],normalWorld[1]),dot(normalWorld[2],normalWorld[2]));vertexOutputs.vNormalW=normalize(normalWorld*vertexOutputs.vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvertexOutputs.vNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\nvar viewDirectionW: vec3f=normalize(scene.vEyePosition.xyz-vertexOutputs.vPositionW);var NdotV: f32=max(dot(vertexOutputs.vNormalW,viewDirectionW),0.0);var roughNormal: vec3f=mix(vertexOutputs.vNormalW,viewDirectionW,(0.5*(1.0-NdotV))*uniforms.baseDiffuseRoughness);var reflectionVector: vec3f= (uniforms.reflectionMatrix* vec4f(roughNormal,0)).xyz;\n#else\nvar reflectionVector: vec3f= (uniforms.reflectionMatrix* vec4f(vertexOutputs.vNormalW,0)).xyz;\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\nvertexOutputs.vEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector);\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_WORLDPOS\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {vertexOutputs.position=scene.viewProjection*worldPos;} else {vertexOutputs.position=scene.viewProjectionR*worldPos;}\n#else\nvertexOutputs.position=scene.viewProjection*worldPos;\n#endif\n#if DEBUGMODE>0\nvertexOutputs.vClipSpacePosition=vertexOutputs.position;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvertexOutputs.vDirectionW=normalize((finalWorld*vec4f(positionUpdated,0.0)).xyz);\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#ifdef RIGHT_HANDED\nvertexOutputs.vViewDepth=-(scene.view*worldPos).z;\n#else\nvertexOutputs.vViewDepth=(scene.view*worldPos).z;\n#endif\n#endif\n#ifndef UV1\nvar uvUpdated: vec2f= vec2f(0.,0.);\n#endif\n#ifdef MAINUV1\nvertexOutputs.vMainUV1=uvUpdated;\n#endif\n#ifndef UV2\nvar uv2Updated: vec2f= vec2f(0.,0.);\n#endif\n#ifdef MAINUV2\nvertexOutputs.vMainUV2=uv2Updated;\n#endif\n#include<uvVariableDeclaration>[3..7]\n#include<samplerVertexImplementation>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo,_MATRIXNAME_,albedo,_INFONAME_,AlbedoInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_MATRIXNAME_,baseWeight,_INFONAME_,BaseWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_MATRIXNAME_,baseDiffuseRoughness,_INFONAME_,BaseDiffuseRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_MATRIXNAME_,detail,_INFONAME_,DetailInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_MATRIXNAME_,ambient,_INFONAME_,AmbientInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_MATRIXNAME_,opacity,_INFONAME_,OpacityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_MATRIXNAME_,emissive,_INFONAME_,EmissiveInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_MATRIXNAME_,lightmap,_INFONAME_,LightmapInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,REFLECTIVITY,_VARYINGNAME_,Reflectivity,_MATRIXNAME_,reflectivity,_INFONAME_,ReflectivityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,MICROSURFACEMAP,_VARYINGNAME_,MicroSurfaceSampler,_MATRIXNAME_,microSurfaceSampler,_INFONAME_,MicroSurfaceSamplerInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,METALLIC_REFLECTANCE,_VARYINGNAME_,MetallicReflectance,_MATRIXNAME_,metallicReflectance,_INFONAME_,MetallicReflectanceInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,REFLECTANCE,_VARYINGNAME_,Reflectance,_MATRIXNAME_,reflectance,_INFONAME_,ReflectanceInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_MATRIXNAME_,bump,_INFONAME_,BumpInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_MATRIXNAME_,decal,_INFONAME_,DecalInfos.x)\n#ifdef CLEARCOAT\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_TEXTURE,_VARYINGNAME_,ClearCoat,_MATRIXNAME_,clearCoat,_INFONAME_,ClearCoatInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_TEXTURE_ROUGHNESS,_VARYINGNAME_,ClearCoatRoughness,_MATRIXNAME_,clearCoatRoughness,_INFONAME_,ClearCoatInfos.z)\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_BUMP,_VARYINGNAME_,ClearCoatBump,_MATRIXNAME_,clearCoatBump,_INFONAME_,ClearCoatBumpInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_TINT_TEXTURE,_VARYINGNAME_,ClearCoatTint,_MATRIXNAME_,clearCoatTint,_INFONAME_,ClearCoatTintInfos.x)\n#endif\n#ifdef IRIDESCENCE\n#include<samplerVertexImplementation>(_DEFINENAME_,IRIDESCENCE_TEXTURE,_VARYINGNAME_,Iridescence,_MATRIXNAME_,iridescence,_INFONAME_,IridescenceInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,IRIDESCENCE_THICKNESS_TEXTURE,_VARYINGNAME_,IridescenceThickness,_MATRIXNAME_,iridescenceThickness,_INFONAME_,IridescenceInfos.z)\n#endif\n#ifdef SHEEN\n#include<samplerVertexImplementation>(_DEFINENAME_,SHEEN_TEXTURE,_VARYINGNAME_,Sheen,_MATRIXNAME_,sheen,_INFONAME_,SheenInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SHEEN_TEXTURE_ROUGHNESS,_VARYINGNAME_,SheenRoughness,_MATRIXNAME_,sheenRoughness,_INFONAME_,SheenInfos.z)\n#endif\n#ifdef ANISOTROPIC\n#include<samplerVertexImplementation>(_DEFINENAME_,ANISOTROPIC_TEXTURE,_VARYINGNAME_,Anisotropy,_MATRIXNAME_,anisotropy,_INFONAME_,AnisotropyInfos.x)\n#endif\n#ifdef SUBSURFACE\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness,_MATRIXNAME_,thickness,_INFONAME_,ThicknessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity,_MATRIXNAME_,refractionIntensity,_INFONAME_,RefractionIntensityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity,_MATRIXNAME_,translucencyIntensity,_INFONAME_,TranslucencyIntensityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor,_MATRIXNAME_,translucencyColor,_INFONAME_,TranslucencyColorInfos.x)\n#endif\n#include<bumpVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#include<vertexColorMixing>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, pbrUboDeclarationWGSL, uvAttributeDeclarationWGSL, mainUVVaryingDeclarationWGSL, helperFunctionsWGSL, pbrBRDFFunctionsWGSL, bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, instancesDeclarationWGSL, prePassVertexDeclarationWGSL, samplerVertexDeclarationWGSL, harmonicsFunctionsWGSL, bumpVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, lightVxUboDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, logDepthDeclarationWGSL, vertexPullingDeclarationWGSL, vertexPullingVertexWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, prePassVertexWGSL, uvVariableDeclarationWGSL, samplerVertexImplementationWGSL, bumpVertexWGSL, clipPlaneVertexWGSL, fogVertexWGSL, shadowsVertexWGSL, vertexColorMixingWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pbrVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"objectIdFunctions\";\nconst shader = `fn encodeObjectId(objectId: f32)->vec4f {\n#ifdef PREPASS_OBJECT_ID_R8\nreturn vec4f(objectId/255.0,0.0,0.0,1.0);\n#else\nlet id=i32(objectId);let encodedId=vec3f(\nf32((id>>16) & 0xFF),\nf32((id>>8) & 0xFF),\nf32(id & 0xFF)\n)/255.0;return vec4f(encodedId,select(0.0,1.0,id>0));\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const objectIdFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./objectIdFunctions\";\nconst name = \"prePassDeclaration\";\nconst shader = `#ifdef PREPASS\n#ifndef PREPASS_CUSTOM_VARYINGS\n#ifdef PREPASS_LOCAL_POSITION\nvarying vPosition : vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vViewPos: vec3f;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vNormViewDepth: f32;\n#endif\n#if (defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(PREPASS_VELOCITY_ZERO)\nvarying vCurrentPosition: vec4f;varying vPreviousPosition: vec4f;\n#endif\n#endif\n#ifdef PREPASS_OBJECT_ID\nuniform objectId: f32;\n#include<objectIdFunctions>\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nuniform meshBlendTag: i32;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const prePassDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"oitDeclaration\";\nconst shader = `#ifdef ORDER_INDEPENDENT_TRANSPARENCY\n#define MAX_DEPTH 99999.0\nvar oitDepthSamplerSampler: sampler;var oitDepthSampler: texture_2d<f32>;var oitFrontColorSamplerSampler: sampler;var oitFrontColorSampler: texture_2d<f32>;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const oitDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./mainUVVaryingDeclaration\";\nconst name = \"pbrFragmentExtraDeclaration\";\nconst shader = `varying vPositionW: vec3f;\n#if DEBUGMODE>0\nvarying vClipSpacePosition: vec4f;\n#endif\n#include<mainUVVaryingDeclaration>[1..7]\n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vEnvironmentIrradiance: vec3f;\n#endif\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vColor: vec4f;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying vViewDepth: f32;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentExtraDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerFragmentDeclaration\";\nconst shader = `#ifdef _DEFINENAME_\n#if _DEFINENAME_DIRECTUV==1\n#define v_VARYINGNAME_UV vMainUV1\n#elif _DEFINENAME_DIRECTUV==2\n#define v_VARYINGNAME_UV vMainUV2\n#elif _DEFINENAME_DIRECTUV==3\n#define v_VARYINGNAME_UV vMainUV3\n#elif _DEFINENAME_DIRECTUV==4\n#define v_VARYINGNAME_UV vMainUV4\n#elif _DEFINENAME_DIRECTUV==5\n#define v_VARYINGNAME_UV vMainUV5\n#elif _DEFINENAME_DIRECTUV==6\n#define v_VARYINGNAME_UV vMainUV6\n#else\nvarying v_VARYINGNAME_UV: vec2f;\n#endif\nvar _SAMPLERNAME_SamplerSampler: sampler;var _SAMPLERNAME_Sampler: texture_2d<f32>;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const samplerFragmentDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerFragmentAlternateDeclaration\";\nconst shader = `#ifdef _DEFINENAME_\n#if _DEFINENAME_DIRECTUV==1\n#define v_VARYINGNAME_UV vMainUV1\n#elif _DEFINENAME_DIRECTUV==2\n#define v_VARYINGNAME_UV vMainUV2\n#elif _DEFINENAME_DIRECTUV==3\n#define v_VARYINGNAME_UV vMainUV3\n#elif _DEFINENAME_DIRECTUV==4\n#define v_VARYINGNAME_UV vMainUV4\n#elif _DEFINENAME_DIRECTUV==5\n#define v_VARYINGNAME_UV vMainUV5\n#elif _DEFINENAME_DIRECTUV==6\n#define v_VARYINGNAME_UV vMainUV6\n#else\nvarying v_VARYINGNAME_UV: vec2f;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const samplerFragmentAlternateDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrFragmentReflectionDeclaration\";\nconst shader = `#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nvar reflectionSamplerSampler: sampler;var reflectionSampler: texture_cube<f32>;\n#ifdef LODBASEDMICROSFURACE\n#else\nvar reflectionLowSamplerSampler: sampler;var reflectionLowSampler: texture_cube<f32>;var reflectionHighSamplerSampler: sampler;var reflectionHighSampler: texture_cube<f32>;\n#endif\n#ifdef USEIRRADIANCEMAP\nvar irradianceSamplerSampler: sampler;var irradianceSampler: texture_cube<f32>;\n#endif\n#else\nvar reflectionSamplerSampler: sampler;var reflectionSampler: texture_2d<f32>;\n#ifdef LODBASEDMICROSFURACE\n#else\nvar reflectionLowSamplerSampler: sampler;var reflectionLowSampler: texture_2d<f32>;var reflectionHighSamplerSampler: sampler;var reflectionHighSampler: texture_2d<f32>;\n#endif\n#ifdef USEIRRADIANCEMAP\nvar irradianceSamplerSampler: sampler;var irradianceSampler: texture_2d<f32>;\n#endif\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentReflectionDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nimport \"./samplerFragmentAlternateDeclaration\";\nimport \"./pbrFragmentReflectionDeclaration\";\nconst name = \"pbrFragmentSamplersDeclaration\";\nconst shader = `#include<samplerFragmentDeclaration>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo,_SAMPLERNAME_,albedo)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_SAMPLERNAME_,baseWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_SAMPLERNAME_,baseDiffuseRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_SAMPLERNAME_,ambient)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_SAMPLERNAME_,opacity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_SAMPLERNAME_,emissive)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_SAMPLERNAME_,lightmap)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,REFLECTIVITY,_VARYINGNAME_,Reflectivity,_SAMPLERNAME_,reflectivity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,MICROSURFACEMAP,_VARYINGNAME_,MicroSurfaceSampler,_SAMPLERNAME_,microSurface)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,METALLIC_REFLECTANCE,_VARYINGNAME_,MetallicReflectance,_SAMPLERNAME_,metallicReflectance)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,REFLECTANCE,_VARYINGNAME_,Reflectance,_SAMPLERNAME_,reflectance)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_SAMPLERNAME_,decal)\n#ifdef CLEARCOAT\n#include<samplerFragmentDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE,_VARYINGNAME_,ClearCoat,_SAMPLERNAME_,clearCoat)\n#include<samplerFragmentAlternateDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE_ROUGHNESS,_VARYINGNAME_,ClearCoatRoughness)\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS)\nvar clearCoatRoughnessSamplerSampler: sampler;var clearCoatRoughnessSampler: texture_2d<f32>;\n#endif\n#include<samplerFragmentDeclaration>(_DEFINENAME_,CLEARCOAT_BUMP,_VARYINGNAME_,ClearCoatBump,_SAMPLERNAME_,clearCoatBump)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,CLEARCOAT_TINT_TEXTURE,_VARYINGNAME_,ClearCoatTint,_SAMPLERNAME_,clearCoatTint)\n#endif\n#ifdef IRIDESCENCE\n#include<samplerFragmentDeclaration>(_DEFINENAME_,IRIDESCENCE_TEXTURE,_VARYINGNAME_,Iridescence,_SAMPLERNAME_,iridescence)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,IRIDESCENCE_THICKNESS_TEXTURE,_VARYINGNAME_,IridescenceThickness,_SAMPLERNAME_,iridescenceThickness)\n#endif\n#ifdef SHEEN\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SHEEN_TEXTURE,_VARYINGNAME_,Sheen,_SAMPLERNAME_,sheen)\n#include<samplerFragmentAlternateDeclaration>(_DEFINENAME_,SHEEN_TEXTURE_ROUGHNESS,_VARYINGNAME_,SheenRoughness)\n#if defined(SHEEN_ROUGHNESS) && defined(SHEEN_TEXTURE_ROUGHNESS)\nvar sheenRoughnessSamplerSampler: sampler;var sheenRoughnessSampler: texture_2d<f32>;\n#endif\n#endif\n#ifdef ANISOTROPIC\n#include<samplerFragmentDeclaration>(_DEFINENAME_,ANISOTROPIC_TEXTURE,_VARYINGNAME_,Anisotropy,_SAMPLERNAME_,anisotropy)\n#endif\n#include<pbrFragmentReflectionDeclaration>\n#ifdef ENVIRONMENTBRDF\nvar environmentBrdfSamplerSampler: sampler;var environmentBrdfSampler: texture_2d<f32>;\n#endif\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\n#ifdef SS_REFRACTIONMAP_3D\nvar refractionSamplerSampler: sampler;var refractionSampler: texture_cube<f32>;\n#ifdef LODBASEDMICROSFURACE\n#else\nvar refractionLowSamplerSampler: sampler;var refractionLowSampler: texture_cube<f32>;var refractionHighSamplerSampler: sampler;var refractionHighSampler: texture_cube<f32>;\n#endif\n#else\nvar refractionSamplerSampler: sampler;var refractionSampler: texture_2d<f32>;\n#ifdef LODBASEDMICROSFURACE\n#else\nvar refractionLowSamplerSampler: sampler;var refractionLowSampler: texture_2d<f32>;var refractionHighSamplerSampler: sampler;var refractionHighSampler: texture_2d<f32>;\n#endif\n#endif\n#endif\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness,_SAMPLERNAME_,thickness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity,_SAMPLERNAME_,refractionIntensity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity,_SAMPLERNAME_,translucencyIntensity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor,_SAMPLERNAME_,translucencyColor)\n#endif\n#ifdef IBL_CDF_FILTERING\nvar icdfSamplerSampler: sampler;var icdfSampler: texture_2d<f32>;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentSamplersDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"textureRepetitionFunctions\";\nconst shader = `#if TEXTURE_REPETITION_MODE>0\nfn _texRepHash4(p: vec2f)->vec4f {return fract(sin(vec4f(\n1.0+dot(p,vec2f(37.0,17.0)),\n2.0+dot(p,vec2f(11.0,47.0)),\n3.0+dot(p,vec2f(41.0,29.0)),\n4.0+dot(p,vec2f(23.0,31.0))\n))*103.0);}\n#endif\n#if TEXTURE_REPETITION_MODE==1\nfn _texRepSample(tex: texture_2d<f32>,samp: sampler,uv: vec2f)->vec4f {var k: f32=textureSample(tex,samp,0.005*uv).x;var index: f32=k*8.0;var f: f32=fract(index);var i: f32=floor(index+0.5);var ib: f32=floor(index);f=min(f,1.0-f)*2.0;var offa: vec2f=sin(vec2f(3.0,7.0)*i);var offb: vec2f=sin(vec2f(3.0,7.0)*ib);var dx: vec2f=dpdx(uv);var dy: vec2f=dpdy(uv);var cola: vec4f=textureSampleGrad(tex,samp,uv+0.3*offa,dx,dy);var colb: vec4f=textureSampleGrad(tex,samp,uv+0.3*offb,dx,dy);var colSum: f32=cola.x+cola.y+cola.z-colb.x-colb.y-colb.z;return mix(cola,colb,vec4f(smoothstep(0.2,0.8,f-0.1*colSum)));}\n#elif TEXTURE_REPETITION_MODE==2\nfn _texRepHexHash(p: vec2f)->vec2f {var r: vec2f=mat2x2f(127.1,269.5,311.7,183.3)*p;return fract(sin(r)*43758.5453);}\nstruct _TexRepTriGrid {w1: f32,\nw2: f32,\nw3: f32,\nvertex1: vec2i,\nvertex2: vec2i,\nvertex3: vec2i,};fn _texRepTriangleGrid(st_in: vec2f)->_TexRepTriGrid {var st: vec2f=st_in*2.0*sqrt(3.0);var gridToSkewedGrid: mat2x2f=mat2x2f(1.0,0.0,-0.57735027,1.15470054);var skewedCoord: vec2f=gridToSkewedGrid*st;var baseId: vec2i=vec2i(floor(skewedCoord));var temp: vec3f=vec3f(fract(skewedCoord),0.0);temp.z=1.0-temp.x-temp.y;var s: f32=step(0.0,-temp.z);var s2: f32=2.0*s-1.0;var result: _TexRepTriGrid;result.w1=-temp.z*s2;result.w2=s-temp.y*s2;result.w3=s-temp.x*s2;result.vertex1=baseId+vec2i(i32(s),i32(s));result.vertex2=baseId+vec2i(i32(s),i32(1.0-s));result.vertex3=baseId+vec2i(i32(1.0-s),i32(s));return result;}\nfn _texRepMakeCenST(Vertex: vec2i)->vec2f {var invSkewMat: mat2x2f=mat2x2f(1.0,0.0,0.5,1.0/1.15470054);return (invSkewMat*vec2f(Vertex))/(2.0*sqrt(3.0));}\nfn _texRepLoadRot2x2(idx: vec2i,rotStr: f32)->mat2x2f {var angle: f32=f32(abs(idx.x*idx.y)+abs(idx.x+idx.y))+3.14159265358979;angle=angle % (2.0*3.14159265358979);if (angle<0.0) { angle+=2.0*3.14159265358979; }\nif (angle>3.14159265358979) { angle-=3.14159265358979; }\nangle*=rotStr;var cs: f32=cos(angle);var si: f32=sin(angle);return mat2x2f(cs,si,-si,cs);}\nfn _texRepGain3(x: vec3f,r: f32)->vec3f {var k: f32=log(1.0-r)/log(0.5);var s: vec3f=2.0*step(vec3f(0.5),x);var m: vec3f=2.0*(1.0-s);var res: vec3f=0.5*s+0.25*m*pow(max(vec3f(0.0),s+x*m),vec3f(k));return res/(res.x+res.y+res.z);}\nfn _texRepSample(tex: texture_2d<f32>,samp: sampler,uv: vec2f)->vec4f {var rotStrength: f32=uniforms.vTextureRepetitionHexTilingParams.x;var fallOffContrast: f32=uniforms.vTextureRepetitionHexTilingParams.y;var expVal: f32=uniforms.vTextureRepetitionHexTilingParams.z;var r: f32=uniforms.vTextureRepetitionHexTilingParams.w;var dSTdx: vec2f=dpdx(uv);var dSTdy: vec2f=dpdy(uv);var grid: _TexRepTriGrid=_texRepTriangleGrid(uv);var rot1: mat2x2f=_texRepLoadRot2x2(grid.vertex1,rotStrength);var rot2: mat2x2f=_texRepLoadRot2x2(grid.vertex2,rotStrength);var rot3: mat2x2f=_texRepLoadRot2x2(grid.vertex3,rotStrength);var cen1: vec2f=_texRepMakeCenST(grid.vertex1);var cen2: vec2f=_texRepMakeCenST(grid.vertex2);var cen3: vec2f=_texRepMakeCenST(grid.vertex3);var st1: vec2f=(uv-cen1)*rot1+cen1+_texRepHexHash(vec2f(grid.vertex1));var st2: vec2f=(uv-cen2)*rot2+cen2+_texRepHexHash(vec2f(grid.vertex2));var st3: vec2f=(uv-cen3)*rot3+cen3+_texRepHexHash(vec2f(grid.vertex3));var c1: vec4f=textureSampleGrad(tex,samp,st1,dSTdx*rot1,dSTdy*rot1);var c2: vec4f=textureSampleGrad(tex,samp,st2,dSTdx*rot2,dSTdy*rot2);var c3: vec4f=textureSampleGrad(tex,samp,st3,dSTdx*rot3,dSTdy*rot3);var Lw: vec3f=vec3f(0.299,0.587,0.114);var Dw: vec3f=vec3f(dot(c1.rgb,Lw),dot(c2.rgb,Lw),dot(c3.rgb,Lw));Dw=mix(vec3f(1.0),Dw,fallOffContrast);var W: vec3f=Dw*pow(vec3f(grid.w1,grid.w2,grid.w3),vec3f(expVal));W=W/(W.x+W.y+W.z);if (r != 0.5) {W=_texRepGain3(W,r);}\nreturn W.x*c1+W.y*c2+W.z*c3;}\n#elif TEXTURE_REPETITION_MODE==3\nfn _texRepSample(tex: texture_2d<f32>,samp: sampler,uv: vec2f)->vec4f {var iuv: vec2f=floor(uv);var fuv: vec2f=fract(uv);var ofa: vec4f=_texRepHash4(iuv+vec2f(0.0,0.0));var ofb: vec4f=_texRepHash4(iuv+vec2f(1.0,0.0));var ofc: vec4f=_texRepHash4(iuv+vec2f(0.0,1.0));var ofd: vec4f=_texRepHash4(iuv+vec2f(1.0,1.0));var dx: vec2f=dpdx(uv);var dy: vec2f=dpdy(uv);ofa=vec4f(ofa.xy,sign(ofa.zw-0.5));ofb=vec4f(ofb.xy,sign(ofb.zw-0.5));ofc=vec4f(ofc.xy,sign(ofc.zw-0.5));ofd=vec4f(ofd.xy,sign(ofd.zw-0.5));var uva: vec2f=uv*ofa.zw+ofa.xy; var ddxa: vec2f=dx*ofa.zw; var ddya: vec2f=dy*ofa.zw;var uvb: vec2f=uv*ofb.zw+ofb.xy; var ddxb: vec2f=dx*ofb.zw; var ddyb: vec2f=dy*ofb.zw;var uvc: vec2f=uv*ofc.zw+ofc.xy; var ddxc: vec2f=dx*ofc.zw; var ddyc: vec2f=dy*ofc.zw;var uvd: vec2f=uv*ofd.zw+ofd.xy; var ddxd: vec2f=dx*ofd.zw; var ddyd: vec2f=dy*ofd.zw;var b: vec2f=smoothstep(vec2f(0.25),vec2f(0.75),fuv);return mix(\nmix(textureSampleGrad(tex,samp,uva,ddxa,ddya),textureSampleGrad(tex,samp,uvb,ddxb,ddyb),b.x),\nmix(textureSampleGrad(tex,samp,uvc,ddxc,ddyc),textureSampleGrad(tex,samp,uvd,ddxd,ddyd),b.x),\nb.y\n);}\n#elif TEXTURE_REPETITION_MODE==4\nfn _texRepSample(tex: texture_2d<f32>,samp: sampler,uv: vec2f)->vec4f {var p: vec2f=floor(uv);var f: vec2f=fract(uv);var dx: vec2f=dpdx(uv);var dy: vec2f=dpdy(uv);var va: vec4f=vec4f(0.0);var wt: f32=0.0;var w2: f32=0.0;for (var j: i32=-1; j<=1; j++) {for (var i: i32=-1; i<=1; i++) {var g: vec2f=vec2f(f32(i),f32(j));var o: vec4f=_texRepHash4(p+g);var r: vec2f=g-f+o.xy;var d: f32=dot(r,r);var w: f32=exp(-5.0*d);var c: vec4f=textureSampleGrad(tex,samp,uv+o.zw,dx,dy);va+=w*c;wt+=w;w2+=w*w;}}\nvar mean: f32=0.3;var res: vec4f=mean+(va-wt*mean)/sqrt(w2);return mix(va/wt,res,0.4);}\n#endif\n#if TEXTURE_REPETITION_MODE>0\nfn TEXRD(t: texture_2d<f32>,ts: sampler,uv: vec2f)->vec4f {return _texRepSample(t,ts,uv);}\n#else\nfn TEXRD(t: texture_2d<f32>,ts: sampler,uv: vec2f)->vec4f {return textureSample(t,ts,uv);}\n#endif\n#define TEXRD_DEFINED\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const textureRepetitionFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"subSurfaceScatteringFunctions\";\nconst shader = `fn testLightingForSSS(diffusionProfile: f32)->bool\n{return diffusionProfile<1.;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const subSurfaceScatteringFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"importanceSampling\";\nconst shader = `fn hemisphereCosSample(u: vec2f)->vec3f {var phi: f32=2.*PI*u.x;var cosTheta2: f32=1.-u.y;var cosTheta: f32=sqrt(cosTheta2);var sinTheta: f32=sqrt(1.-cosTheta2);return vec3f(sinTheta*cos(phi),sinTheta*sin(phi),cosTheta);}\nfn hemisphereImportanceSampleDggx(u: vec2f,a: f32)->vec3f {var phi: f32=2.*PI*u.x;var cosTheta2: f32=(1.-u.y)/(1.+(a+1.)*((a-1.)*u.y));var cosTheta: f32=sqrt(cosTheta2);var sinTheta: f32=sqrt(1.-cosTheta2);return vec3f(sinTheta*cos(phi),sinTheta*sin(phi),cosTheta);}\nfn hemisphereImportanceSampleDggxAnisotropic(Xi: vec2f,alphaTangent: f32,alphaBitangent: f32)->vec3f\n{let alphaT: f32=max(alphaTangent,0.0001);let alphaB: f32=max(alphaBitangent,0.0001);var phi: f32=atan(alphaB/alphaT*tan(2.0f*PI*Xi.x));if (Xi.x>0.5) {phi+=PI; }\nlet cosPhi: f32=cos(phi);let sinPhi: f32=sin(phi);let alpha2: f32=(cosPhi*cosPhi)/(alphaT*alphaT) +\n(sinPhi*sinPhi)/(alphaB*alphaB);let tanTheta2: f32=Xi.y/(1.0f-Xi.y)/alpha2;let cosTheta: f32=1.0f/sqrt(1.0f+tanTheta2);let sinTheta: f32=sqrt(max(0.0f,1.0f-cosTheta*cosTheta));return vec3f(sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);}\nfn hemisphereImportanceSampleDCharlie(u: vec2f,a: f32)->vec3f { \nvar phi: f32=2.*PI*u.x;var sinTheta: f32=pow(u.y,a/(2.*a+1.));var cosTheta: f32=sqrt(1.-sinTheta*sinTheta);return vec3f(sinTheta*cos(phi),sinTheta*sin(phi),cosTheta);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const importanceSamplingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrHelperFunctions\";\nconst shader = `#define MINIMUMVARIANCE 0.0005\n#ifndef TEXRD_DEFINED\nfn TEXRD(t: texture_2d<f32>,ts: sampler,uv: vec2f)->vec4f {return textureSample(t,ts,uv);}\n#define TEXRD_DEFINED\n#endif\nfn convertRoughnessToAverageSlope(roughness: f32)->f32\n{return roughness*roughness+MINIMUMVARIANCE;}\nfn fresnelGrazingReflectance(reflectance0: f32)->f32 {var reflectance90: f32=saturate(reflectance0*25.0);return reflectance90;}\nfn getAARoughnessFactors(normalVector: vec3f)->vec2f {\n#ifdef SPECULARAA\nvar nDfdx: vec3f=dpdx(normalVector.xyz);var nDfdy: vec3f=dpdy(normalVector.xyz);var slopeSquare: f32=max(dot(nDfdx,nDfdx),dot(nDfdy,nDfdy));var geometricRoughnessFactor: f32=pow(saturate(slopeSquare),0.333);var geometricAlphaGFactor: f32=sqrt(slopeSquare);geometricAlphaGFactor*=0.75;return vec2f(geometricRoughnessFactor,geometricAlphaGFactor);\n#else\nreturn vec2f(0.);\n#endif\n}\n#ifdef ANISOTROPIC\n#ifdef ANISOTROPIC_LEGACY\nfn getAnisotropicRoughness(alphaG: f32,anisotropy: f32)->vec2f {var alphaT: f32=max(alphaG*(1.0+anisotropy),MINIMUMVARIANCE);var alphaB: f32=max(alphaG*(1.0-anisotropy),MINIMUMVARIANCE);return vec2f(alphaT,alphaB);}\nfn getAnisotropicBentNormals(T: vec3f,B: vec3f,N: vec3f,V: vec3f,anisotropy: f32,roughness: f32)->vec3f {var anisotropicFrameDirection: vec3f=select(T,B,anisotropy>=0.0);var anisotropicFrameTangent: vec3f=cross(normalize(anisotropicFrameDirection),V);var anisotropicFrameNormal: vec3f=cross(anisotropicFrameTangent,anisotropicFrameDirection);var anisotropicNormal: vec3f=normalize(mix(N,anisotropicFrameNormal,abs(anisotropy)));return anisotropicNormal;}\n#elif ANISOTROPIC_OPENPBR\nfn getAnisotropicRoughness(alphaG: f32,anisotropy: f32)->vec2f {var alphaT: f32=max(alphaG*alphaG*sqrt(2.0/(1.0+(1.0-anisotropy)*(1.0-anisotropy))),MINIMUMVARIANCE);var alphaB: f32=max(alphaT*(1.0-anisotropy),MINIMUMVARIANCE);return vec2f(alphaT,alphaB);}\n#else\nfn getAnisotropicRoughness(alphaG: f32,anisotropy: f32)->vec2f {var alphaT: f32=max(mix(alphaG,1.0,anisotropy*anisotropy),MINIMUMVARIANCE);var alphaB: f32=max(alphaG,MINIMUMVARIANCE);return vec2f(alphaT,alphaB);}\nfn getAnisotropicBentNormals(T: vec3f,B: vec3f,N: vec3f,V: vec3f,anisotropy: f32,roughness: f32)->vec3f {var bentNormal: vec3f=cross(B,V);bentNormal=normalize(cross(bentNormal,B));var sq=1.0-anisotropy*(1.0-roughness);var a: f32=sq*sq*sq*sq;bentNormal=normalize(mix(bentNormal,N,a));return bentNormal;}\n#endif\n#endif\n#if defined(CLEARCOAT) || defined(SS_REFRACTION)\nfn cocaLambertVec3(alpha: vec3f,distance: f32)->vec3f {return exp(-alpha*distance);}\nfn cocaLambert(NdotVRefract: f32,NdotLRefract: f32,alpha: vec3f,thickness: f32)->vec3f {return cocaLambertVec3(alpha,(thickness*((NdotLRefract+NdotVRefract)/(NdotLRefract*NdotVRefract))));}\nfn computeColorAtDistanceInMedia(color: vec3f,distance: f32)->vec3f {return -log(color)/distance;}\nfn computeClearCoatAbsorption(NdotVRefract: f32,NdotLRefract: f32,clearCoatColor: vec3f,clearCoatThickness: f32,clearCoatIntensity: f32)->vec3f {var clearCoatAbsorption: vec3f=mix( vec3f(1.0),\ncocaLambert(NdotVRefract,NdotLRefract,clearCoatColor,clearCoatThickness),\nclearCoatIntensity);return clearCoatAbsorption;}\n#endif\n#ifdef MICROSURFACEAUTOMATIC\nfn computeDefaultMicroSurface(microSurface: f32,reflectivityColor: vec3f)->f32\n{const kReflectivityNoAlphaWorkflow_SmoothnessMax: f32=0.95;var reflectivityLuminance: f32=getLuminance(reflectivityColor);var reflectivityLuma: f32=sqrt(reflectivityLuminance);var resultMicroSurface=reflectivityLuma*kReflectivityNoAlphaWorkflow_SmoothnessMax;return resultMicroSurface;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrHelperFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./ltcHelperFunctions\";\nconst name = \"pbrDirectLightingSetupFunctions\";\nconst shader = `struct preLightingInfo\n{lightOffset: vec3f,\nlightDistanceSquared: f32,\nlightDistance: f32,\nattenuation: f32,\nL: vec3f,\nH: vec3f,\nNdotV: f32,\nNdotLUnclamped: f32,\nNdotL: f32,\nVdotH: f32,\nLdotV: f32,\nroughness: f32,\ndiffuseRoughness: f32,\nsurfaceAlbedo: vec3f,\n#ifdef IRIDESCENCE\niridescenceIntensity: f32\n#endif\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nareaLightDiffuse: vec3f,\n#ifdef SPECULARTERM\nareaLightSpecular: vec3f,\nareaLightFresnel: vec4f\n#endif\n#endif\n};fn computePointAndSpotPreLightingInfo(lightData: vec4f,V: vec3f,N: vec3f,posW: vec3f)->preLightingInfo {var result: preLightingInfo;result.lightOffset=lightData.xyz-posW;result.lightDistanceSquared=dot(result.lightOffset,result.lightOffset);result.lightDistance=sqrt(result.lightDistanceSquared);result.L=normalize(result.lightOffset);result.H=normalize(V+result.L);result.VdotH=saturate(dot(V,result.H));result.NdotLUnclamped=dot(N,result.L);result.NdotL=saturateEps(result.NdotLUnclamped);return result;}\nfn computeDirectionalPreLightingInfo(lightData: vec4f,V: vec3f,N: vec3f)->preLightingInfo {var result: preLightingInfo;result.lightDistance=length(-lightData.xyz);result.L=normalize(-lightData.xyz);result.H=normalize(V+result.L);result.VdotH=saturate(dot(V,result.H));result.NdotLUnclamped=dot(N,result.L);result.NdotL=saturateEps(result.NdotLUnclamped);result.LdotV=dot(result.L,V);return result;}\nfn computeHemisphericPreLightingInfo(lightData: vec4f,V: vec3f,N: vec3f)->preLightingInfo {var result: preLightingInfo;result.NdotL=dot(N,lightData.xyz)*0.5+0.5;result.NdotL=saturateEps(result.NdotL);result.NdotLUnclamped=result.NdotL;\n#ifdef SPECULARTERM\nresult.L=normalize(lightData.xyz);result.H=normalize(V+result.L);result.VdotH=saturate(dot(V,result.H));\n#endif\nreturn result;}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#include<ltcHelperFunctions>\nvar areaLightsLTC1SamplerSampler: sampler;var areaLightsLTC1Sampler: texture_2d<f32>;var areaLightsLTC2SamplerSampler: sampler;var areaLightsLTC2Sampler: texture_2d<f32>;fn computeAreaPreLightingInfo(ltc1: texture_2d<f32>,ltc1Sampler:sampler,ltc2:texture_2d<f32>,ltc2Sampler:sampler,viewDirectionW: vec3f,vNormal:vec3f,vPosition:vec3f,lightCenter:vec3f,halfWidth:vec3f, halfHeight:vec3f,roughness:f32)->preLightingInfo {var result: preLightingInfo;var data: areaLightData=computeAreaLightSpecularDiffuseFresnel(ltc1,ltc1Sampler,ltc2,ltc2Sampler,viewDirectionW,vNormal,vPosition,lightCenter,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nresult.areaLightFresnel=data.Fresnel;result.areaLightSpecular=data.Specular;\n#endif\nresult.areaLightDiffuse+=data.Diffuse;return result;}\nfn computeAreaPreLightingInfoWithTexture(ltc1: texture_2d<f32>,ltc1Sampler:sampler,ltc2:texture_2d<f32>,ltc2Sampler:sampler,emissionTexture:texture_2d<f32>,emissionTextureSampler:sampler,viewDirectionW: vec3f,vNormal:vec3f,vPosition:vec3f,lightCenter:vec3f,halfWidth:vec3f, halfHeight:vec3f,roughness:f32)->preLightingInfo {var result: preLightingInfo;result.lightOffset=lightCenter-vPosition;result.lightDistanceSquared=dot(result.lightOffset,result.lightOffset);result.lightDistance=sqrt(result.lightDistanceSquared);var data: areaLightData=computeAreaLightSpecularDiffuseFresnelWithEmission(ltc1,ltc1Sampler,ltc2,ltc2Sampler,emissionTexture,emissionTextureSampler,viewDirectionW,vNormal,vPosition,lightCenter,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nresult.areaLightFresnel=data.Fresnel;result.areaLightSpecular=data.Specular;\n#endif\nresult.areaLightDiffuse=data.Diffuse;result.LdotV=0.;result.roughness=0.;result.diffuseRoughness=0.;result.surfaceAlbedo=vec3f(0.);return result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrDirectLightingSetupFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrDirectLightingFalloffFunctions\";\nconst shader = `fn computeDistanceLightFalloff_Standard(lightOffset: vec3f,range: f32)->f32\n{return max(0.,1.0-length(lightOffset)/range);}\nfn computeDistanceLightFalloff_Physical(lightDistanceSquared: f32)->f32\n{return 1.0/maxEps(lightDistanceSquared);}\nfn computeDistanceLightFalloff_GLTF(lightDistanceSquared: f32,inverseSquaredRange: f32)->f32\n{var lightDistanceFalloff: f32=1.0/maxEps(lightDistanceSquared);var factor: f32=lightDistanceSquared*inverseSquaredRange;var attenuation: f32=saturate(1.0-factor*factor);attenuation*=attenuation;lightDistanceFalloff*=attenuation;return lightDistanceFalloff;}\nfn computeDirectionalLightFalloff_IES(lightDirection: vec3f,directionToLightCenterW: vec3f,iesLightTexture: texture_2d<f32>,iesLightTextureSampler: sampler)->f32\n{var cosAngle: f32=dot(-lightDirection,directionToLightCenterW);var angle=acos(cosAngle)/PI;return textureSampleLevel(iesLightTexture,iesLightTextureSampler,vec2f(angle,0),0.).r;}\nfn computeDistanceLightFalloff(lightOffset: vec3f,lightDistanceSquared: f32,range: f32,inverseSquaredRange: f32)->f32\n{\n#ifdef USEPHYSICALLIGHTFALLOFF\nreturn computeDistanceLightFalloff_Physical(lightDistanceSquared);\n#elif defined(USEGLTFLIGHTFALLOFF)\nreturn computeDistanceLightFalloff_GLTF(lightDistanceSquared,inverseSquaredRange);\n#else\nreturn computeDistanceLightFalloff_Standard(lightOffset,range);\n#endif\n}\nfn computeDirectionalLightFalloff_Standard(lightDirection: vec3f,directionToLightCenterW: vec3f,cosHalfAngle: f32,exponent: f32)->f32\n{var falloff: f32=0.0;var cosAngle: f32=maxEps(dot(-lightDirection,directionToLightCenterW));if (cosAngle>=cosHalfAngle)\n{falloff=max(0.,pow(cosAngle,exponent));}\nreturn falloff;}\nfn computeDirectionalLightFalloff_Physical(lightDirection: vec3f,directionToLightCenterW: vec3f,cosHalfAngle: f32)->f32\n{const kMinusLog2ConeAngleIntensityRatio: f32=6.64385618977; \nvar concentrationKappa: f32=kMinusLog2ConeAngleIntensityRatio/(1.0-cosHalfAngle);var lightDirectionSpreadSG: vec4f= vec4f(-lightDirection*concentrationKappa,-concentrationKappa);var falloff: f32=exp2(dot( vec4f(directionToLightCenterW,1.0),lightDirectionSpreadSG));return falloff;}\nfn computeDirectionalLightFalloff_GLTF(lightDirection: vec3f,directionToLightCenterW: vec3f,lightAngleScale: f32,lightAngleOffset: f32)->f32\n{var cd: f32=dot(-lightDirection,directionToLightCenterW);var falloff: f32=saturate(cd*lightAngleScale+lightAngleOffset);falloff*=falloff;return falloff;}\nfn computeDirectionalLightFalloff(lightDirection: vec3f,directionToLightCenterW: vec3f,cosHalfAngle: f32,exponent: f32,lightAngleScale: f32,lightAngleOffset: f32)->f32\n{\n#ifdef USEPHYSICALLIGHTFALLOFF\nreturn computeDirectionalLightFalloff_Physical(lightDirection,directionToLightCenterW,cosHalfAngle);\n#elif defined(USEGLTFLIGHTFALLOFF)\nreturn computeDirectionalLightFalloff_GLTF(lightDirection,directionToLightCenterW,lightAngleScale,lightAngleOffset);\n#else\nreturn computeDirectionalLightFalloff_Standard(lightDirection,directionToLightCenterW,cosHalfAngle,exponent);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrDirectLightingFalloffFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"hdrFilteringFunctions\";\nconst shader = `#ifdef NUM_SAMPLES\n#if NUM_SAMPLES>0\nfn radicalInverse_VdC(value: u32)->f32 \n{var bits=(value<<16u) | (value>>16u);bits=((bits & 0x55555555u)<<1u) | ((bits & 0xAAAAAAAAu)>>1u);bits=((bits & 0x33333333u)<<2u) | ((bits & 0xCCCCCCCCu)>>2u);bits=((bits & 0x0F0F0F0Fu)<<4u) | ((bits & 0xF0F0F0F0u)>>4u);bits=((bits & 0x00FF00FFu)<<8u) | ((bits & 0xFF00FF00u)>>8u);return f32(bits)*2.3283064365386963e-10; }\nfn hammersley(i: u32,N: u32)->vec2f\n{return vec2f( f32(i)/ f32(N),radicalInverse_VdC(i));}\nfn log4(x: f32)->f32 {return log2(x)/2.;}\nfn uv_to_normal(uv: vec2f)->vec3f {var N: vec3f;var uvRange: vec2f=uv;var theta: f32=uvRange.x*2.0*PI;var phi: f32=uvRange.y*PI;N.x=cos(theta)*sin(phi);N.z=sin(theta)*sin(phi);N.y=cos(phi);return N;}\nconst NUM_SAMPLES_FLOAT: f32= f32(NUM_SAMPLES);const NUM_SAMPLES_FLOAT_INVERSED: f32=1./NUM_SAMPLES_FLOAT;const K: f32=4.;fn irradiance(\n#ifdef CUSTOM_IRRADIANCE_FILTERING_INPUT\nCUSTOM_IRRADIANCE_FILTERING_INPUT\n#else\ninputTexture: texture_cube<f32>,inputSampler: sampler,\n#endif\ninputN: vec3f,\nfilteringInfo: vec2f,\ndiffuseRoughness: f32,\nsurfaceAlbedo: vec3f,\ninputV: vec3f\n#ifdef IBL_CDF_FILTERING\n,icdfSampler: texture_2d<f32>,icdfSamplerSampler: sampler\n#endif\n)->vec3f\n{var n: vec3f=normalize(inputN);var result: vec3f= vec3f(0.0);\n#ifndef IBL_CDF_FILTERING\nvar tangent: vec3f=select(vec3f(1.,0.,0.),vec3f(0.,0.,1.),abs(n.z)<0.999);tangent=normalize(cross(tangent,n));var bitangent: vec3f=cross(n,tangent);var tbn: mat3x3f= mat3x3f(tangent,bitangent,n);var tbnInverse: mat3x3f=transpose(tbn);\n#endif\nvar maxLevel: f32=filteringInfo.y;var dim0: f32=filteringInfo.x;var omegaP: f32=(4.*PI)/(6.*dim0*dim0);var clampedAlbedo: vec3f=clamp(surfaceAlbedo,vec3f(0.1),vec3f(1.0));for(var i: u32=0u; i<NUM_SAMPLES; i++)\n{var Xi: vec2f=hammersley(i,NUM_SAMPLES);\n#ifdef IBL_CDF_FILTERING\nvar T: vec2f;T.x=textureSampleLevel(icdfSampler,icdfSamplerSampler,vec2(Xi.x,0.0),0.0).x;T.y=textureSampleLevel(icdfSampler,icdfSamplerSampler,vec2(T.x,Xi.y),0.0).y;var Ls: vec3f=uv_to_normal(vec2f(1.0-fract(T.x+0.25),T.y));var NoL: f32=dot(n,Ls);var NoV: f32=dot(n,inputV);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvar LoV: f32=dot(Ls,inputV);\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvar H: vec3f=(inputV+Ls)*0.5;var VoH: f32=dot(inputV,H);\n#endif \n#else\nvar Ls: vec3f=hemisphereCosSample(Xi);Ls=normalize(Ls);var Ns: vec3f= vec3f(0.,0.,1.);var NoL: f32=dot(Ns,Ls);var V: vec3f=tbnInverse*inputV;var NoV: f32=dot(Ns,V);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvar LoV: f32=dot(Ls,V);\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvar H: vec3f=(V+Ls)*0.5;var VoH: f32=dot(V,H);\n#endif\n#endif\nif (NoL>0.) {\n#ifdef IBL_CDF_FILTERING\nvar pdf: f32=textureSampleLevel(icdfSampler,icdfSamplerSampler,T,0.0).z;var c: vec3f=textureSampleLevel(inputTexture,inputSampler,Ls,0.0).rgb;\n#else\nvar pdf_inversed: f32=PI/NoL;var omegaS: f32=NUM_SAMPLES_FLOAT_INVERSED*pdf_inversed;var l: f32=log4(omegaS)-log4(omegaP)+log4(K);var mipLevel: f32=clamp(l,0.0,maxLevel);\n#ifdef CUSTOM_IRRADIANCE_FILTERING_FUNCTION\nCUSTOM_IRRADIANCE_FILTERING_FUNCTION\n#else\nvar c: vec3f=textureSampleLevel(inputTexture,inputSampler,tbn*Ls,mipLevel).rgb;\n#endif\n#endif\n#ifdef GAMMA_INPUT\nc=toLinearSpaceVec3(c);\n#endif\nvar diffuseRoughnessTerm: vec3f=vec3f(1.0);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\ndiffuseRoughnessTerm=diffuseBRDF_EON(clampedAlbedo,diffuseRoughness,NoL,NoV,LoV)*PI;\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\ndiffuseRoughnessTerm=vec3f(diffuseBRDF_Burley(NoL,NoV,VoH,diffuseRoughness)*PI);\n#endif\n#ifdef IBL_CDF_FILTERING\nvar light: vec3f=vec3f(0.0);if (pdf>1e-6) {light=vec3f(1.0)/vec3f(pdf)*c;}\nresult+=NoL*diffuseRoughnessTerm*light;\n#else\nresult+=c*diffuseRoughnessTerm;\n#endif\n}}\nresult=result*NUM_SAMPLES_FLOAT_INVERSED;\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nresult=result/clampedAlbedo;\n#endif\nreturn result;}\nfn radiance(alphaG: f32,inputTexture: texture_cube<f32>,inputSampler: sampler,inputN: vec3f,filteringInfo: vec2f)->vec3f\n{var n: vec3f=normalize(inputN);var c: vec3f=textureSampleLevel(inputTexture,inputSampler,n,0.0).rgb; \nif (alphaG==0.) {\n#ifdef GAMMA_INPUT\nc=toLinearSpaceVec3(c);\n#endif\nreturn c;} else {var result: vec3f= vec3f(0.);var tangent: vec3f=select(vec3f(1.,0.,0.),vec3f(0.,0.,1.),abs(n.z)<0.999);tangent=normalize(cross(tangent,n));var bitangent: vec3f=cross(n,tangent);var tbn: mat3x3f= mat3x3f(tangent,bitangent,n);var maxLevel: f32=filteringInfo.y;var dim0: f32=filteringInfo.x;var omegaP: f32=(4.*PI)/(6.*dim0*dim0);var weight: f32=0.;for(var i: u32=0u; i<NUM_SAMPLES; i++)\n{var Xi: vec2f=hammersley(i,NUM_SAMPLES);var H: vec3f=hemisphereImportanceSampleDggx(Xi,alphaG);var NoV: f32=1.;var NoH: f32=H.z;var NoH2: f32=H.z*H.z;var NoL: f32=2.*NoH2-1.;var L: vec3f= vec3f(2.*NoH*H.x,2.*NoH*H.y,NoL);L=normalize(L);if (NoL>0.) {var pdf_inversed: f32=4./normalDistributionFunction_TrowbridgeReitzGGX(NoH,alphaG);var omegaS: f32=NUM_SAMPLES_FLOAT_INVERSED*pdf_inversed;var l: f32=log4(omegaS)-log4(omegaP)+log4(K);var mipLevel: f32=clamp( f32(l),0.0,maxLevel);weight+=NoL;var c: vec3f=textureSampleLevel(inputTexture,inputSampler,tbn*L,mipLevel).rgb;\n#ifdef GAMMA_INPUT\nc=toLinearSpaceVec3(c);\n#endif\nresult+=c*NoL;}}\nresult=result/weight;return result;}}\n#ifdef ANISOTROPIC\nfn radianceAnisotropic(\nalphaTangent: f32, \nalphaBitangent: f32, \ninputTexture: texture_cube<f32>,\ninputSampler: sampler,\ninputView: vec3f, \ninputTangent: vec3f, \ninputBitangent: vec3f, \ninputNormal: vec3f, \nfilteringInfo: vec2f,\nnoiseInput: vec2f, \nisRefraction: bool,\nior: f32 \n)->vec3f {var V: vec3f=inputView;var N: vec3f=inputNormal;var T: vec3f=inputTangent;var B: vec3f=inputBitangent;var result: vec3f=vec3f(0.f);var maxLevel: f32=filteringInfo.y;var dim0: f32=filteringInfo.x;let clampedAlphaT: f32=max(alphaTangent,MINIMUMVARIANCE);let clampedAlphaB: f32=max(alphaBitangent,MINIMUMVARIANCE);var effectiveDim: f32=dim0*sqrt(clampedAlphaT*clampedAlphaB);var omegaP: f32=(4.f*PI)/(6.f*effectiveDim*effectiveDim);let noiseScale: f32=clamp(log2(f32(NUM_SAMPLES))/12.0f,0.0f,1.0f);var weight: f32=0.f;for(var i: u32=0u; i<NUM_SAMPLES; i++)\n{var Xi: vec2f=hammersley(i,NUM_SAMPLES);Xi=fract(Xi+noiseInput*mix(0.5f,0.015f,noiseScale)); \nvar H_tangent: vec3f=hemisphereImportanceSampleDggxAnisotropic(Xi,clampedAlphaT,clampedAlphaB);var H: vec3f=normalize(H_tangent.x*T+H_tangent.y*B+H_tangent.z*N);var L: vec3f;if (isRefraction) {L=refract(-V,H,1.0/ior);} else {L=reflect(-V,H);}\nvar NoH: f32=max(dot(N,H),0.001f);var VoH: f32=max(dot(V,H),0.001f);var NoL: f32=max(dot(N,L),0.001f);if (NoL>0.f) {var pdf_inversed: f32=4./normalDistributionFunction_BurleyGGX_Anisotropic(\nH_tangent.z,H_tangent.x,H_tangent.y,vec2f(clampedAlphaT,clampedAlphaB)\n);var omegaS: f32=NUM_SAMPLES_FLOAT_INVERSED*pdf_inversed;var l: f32=log4(omegaS)-log4(omegaP)+log4(K);var mipLevel: f32=clamp(l,0.0f,maxLevel);weight+=NoL;var c: vec3f=textureSampleLevel(inputTexture,inputSampler,L,mipLevel).rgb;\n#if GAMMA_INPUT\nc=toLinearSpaceVec3(c);\n#endif\nresult+=c*NoL;}}\nresult=result/weight;return result;}\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const hdrFilteringFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflectance0\";\nconst shader = `var reflectanceF0: f32=reflectivityOut.reflectanceF0;var specularEnvironmentR0: vec3f=reflectivityOut.colorReflectanceF0;var specularEnvironmentR90: vec3f= reflectivityOut.reflectanceF90;\n#ifdef ALPHAFRESNEL\nvar reflectance90: f32=fresnelGrazingReflectance(reflectanceF0);specularEnvironmentR90=specularEnvironmentR90*reflectance90;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectance0WGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./pbrBlockReflectance0\";\nconst name = \"pbrClusteredLightingFunctions\";\nconst shader = `#if defined(CLUSTLIGHT{X}) && defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nfn computeClusteredLighting{X}(\nlightDataTexture: texture_2d<f32>,\nlightData: vec4f,\nsliceRange: vec2u,\nV: vec3f,\nN: vec3f,\nposW: vec3f,\nsurfaceAlbedo: vec3f,\nreflectivityOut: reflectivityOutParams,\n#ifdef IRIDESCENCE\niridescenceIntensity: f32,\n#endif\n#ifdef SS_TRANSLUCENCY\nsubSurfaceOut: subSurfaceOutParams,\n#endif\n#ifdef SPECULARTERM\nAARoughnessFactor: f32,\n#endif\n#ifdef ANISOTROPIC\nanisotropicOut: anisotropicOutParams,\n#endif\n#ifdef SHEEN\nsheenOut: sheenOutParams,\n#endif\n#ifdef CLEARCOAT\nclearcoatOut: clearcoatOutParams,\n#endif\n)->lightingInfo {let NdotV=absEps(dot(N,V));\n#include<pbrBlockReflectance0>\n#ifdef CLEARCOAT\nspecularEnvironmentR0=clearcoatOut.specularEnvironmentR0;\n#endif\nvar result: lightingInfo;let tilePosition=vec2u(fragmentInputs.position.xy*lightData.xy);let maskResolution=vec2u(lightData.zw);var tileIndex=(tilePosition.x*maskResolution.x+tilePosition.y)*maskResolution.y;let batchRange=sliceRange/CLUSTLIGHT_BATCH;var batchOffset=batchRange.x*CLUSTLIGHT_BATCH;tileIndex+=batchRange.x;for (var i=batchRange.x; i<=batchRange.y; i+=1) {var mask=tileMaskBuffer{X}[tileIndex];tileIndex+=1;let maskOffset=max(sliceRange.x,batchOffset)-batchOffset; \nlet maskWidth=min(sliceRange.y-batchOffset+1,CLUSTLIGHT_BATCH);mask=extractBits(mask,maskOffset,maskWidth);while mask != 0 {let trailing=firstTrailingBit(mask);mask ^= 1u<<trailing;let light=getClusteredLight(lightDataTexture,batchOffset+maskOffset+trailing);var preInfo=computePointAndSpotPreLightingInfo(light.vLightData,V,N,posW);preInfo.NdotV=NdotV;preInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light.vLightFalloff.x,light.vLightFalloff.y);if light.vLightDirection.w>=0.0 {preInfo.attenuation*=computeDirectionalLightFalloff(light.vLightDirection.xyz,preInfo.L,light.vLightDirection.w,light.vLightData.w,light.vLightFalloff.z,light.vLightFalloff.w);}\npreInfo.roughness=adjustRoughnessFromLightProperties(reflectivityOut.roughness,light.vLightSpecular.a,preInfo.lightDistance);preInfo.diffuseRoughness=reflectivityOut.diffuseRoughness;preInfo.surfaceAlbedo=surfaceAlbedo;\n#ifdef IRIDESCENCE\npreInfo.iridescenceIntensity=iridescenceIntensity;\n#endif\nvar info: lightingInfo;\n#ifdef SS_TRANSLUCENCY\n#ifdef SS_TRANSLUCENCY_LEGACY\ninfo.diffuse=computeDiffuseTransmittedLighting(preInfo,light.vLightDiffuse.rgb,subSurfaceOut.transmittance);info.diffuseTransmission=vec3(0);\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,light.vLightDiffuse.rgb)*(1.0-subSurfaceOut.translucencyIntensity);info.diffuseTransmission=computeDiffuseTransmittedLighting(preInfo,light.vLightDiffuse.rgb,subSurfaceOut.transmittance);\n#endif\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,light.vLightDiffuse.rgb);\n#endif\n#ifdef SPECULARTERM\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nlet metalFresnel=reflectivityOut.specularWeight*getF82Specular(preInfo.VdotH,specularEnvironmentR0,reflectivityOut.colorReflectanceF90,reflectivityOut.roughness);let dielectricFresnel=fresnelSchlickGGXVec3(preInfo.VdotH,reflectivityOut.dielectricColorF0,reflectivityOut.colorReflectanceF90);let coloredFresnel=mix(dielectricFresnel,metalFresnel,reflectivityOut.metallic);\n#else\nlet coloredFresnel=fresnelSchlickGGXVec3(preInfo.VdotH,specularEnvironmentR0,reflectivityOut.colorReflectanceF90);\n#endif\n#ifndef LEGACY_SPECULAR_ENERGY_CONSERVATION\nlet NdotH=dot(N,preInfo.H);let fresnel=fresnelSchlickGGXVec3(NdotH,vec3(reflectanceF0),specularEnvironmentR90);info.diffuse*=(vec3(1.0)-fresnel);\n#endif\n#ifdef ANISOTROPIC\ninfo.specular=computeAnisotropicSpecularLighting(preInfo,V,N,anisotropicOut.anisotropicTangent,anisotropicOut.anisotropicBitangent,anisotropicOut.anisotropy,specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactor,light.vLightDiffuse.rgb);\n#else\ninfo.specular=computeSpecularLighting(preInfo,N,specularEnvironmentR0,coloredFresnel,AARoughnessFactor,light.vLightDiffuse.rgb);\n#endif\n#endif\n#ifdef SHEEN\n#ifdef SHEEN_LINKWITHALBEDO\npreInfo.roughness=sheenOut.sheenIntensity;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(sheenOut.sheenRoughness,light.vLightSpecular.a,preInfo.lightDistance);\n#endif\ninfo.sheen=computeSheenLighting(preInfo,normalW,sheenOut.sheenColor,specularEnvironmentR90,AARoughnessFactor,light.vLightDiffuse.rgb);\n#endif\n#ifdef CLEARCOAT\npreInfo.roughness=adjustRoughnessFromLightProperties(clearcoatOut.clearCoatRoughness,light.vLightSpecular.a,preInfo.lightDistance);info.clearCoat=computeClearCoatLighting(preInfo,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatAARoughnessFactors.x,clearcoatOut.clearCoatIntensity,light.vLightDiffuse.rgb);\n#ifdef CLEARCOAT_TINT\nlet absorption=computeClearCoatLightingAbsorption(clearcoatOut.clearCoatNdotVRefract,preInfo.L,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatColor,clearcoatOut.clearCoatThickness,clearcoatOut.clearCoatIntensity);info.diffuse*=absorption;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=absorption;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=absorption;\n#endif\n#endif\ninfo.diffuse*=info.clearCoat.w;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=info.clearCoat.w;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=info.clearCoat.w;\n#endif\n#ifdef SHEEN\ninfo.sheen*=info.clearCoat.w;\n#endif\n#endif\nresult.diffuse+=info.diffuse;\n#ifdef SS_TRANSLUCENCY\nresult.diffuseTransmission+=info.diffuseTransmission;\n#endif\n#ifdef SPECULARTERM\nresult.specular+=info.specular;\n#endif\n#ifdef CLEARCOAT\nresult.clearCoat+=info.clearCoat;\n#endif\n#ifdef SHEEN\nresult.sheen+=info.sheen;\n#endif\n}\nbatchOffset+=CLUSTLIGHT_BATCH;}\nreturn result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrClusteredLightingFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./clusteredLightingFunctions\";\nimport \"./pbrClusteredLightingFunctions\";\nconst name = \"pbrDirectLightingFunctions\";\nconst shader = `#define CLEARCOATREFLECTANCE90 1.0\nstruct lightingInfo\n{diffuse: vec3f,\n#ifdef SS_TRANSLUCENCY\ndiffuseTransmission: vec3f,\n#endif\n#ifdef SPECULARTERM\nspecular: vec3f,\n#endif\n#ifdef CLEARCOAT\nclearCoat: vec4f,\n#endif\n#ifdef SHEEN\nsheen: vec3f\n#endif\n};fn adjustRoughnessFromLightProperties(roughness: f32,lightRadius: f32,lightDistance: f32)->f32 {\n#if defined(USEPHYSICALLIGHTFALLOFF) || defined(USEGLTFLIGHTFALLOFF)\nvar lightRoughness: f32=lightRadius/lightDistance;var totalRoughness: f32=saturate(lightRoughness+roughness);return totalRoughness;\n#else\nreturn roughness;\n#endif\n}\nfn computeHemisphericDiffuseLighting(info: preLightingInfo,lightColor: vec3f,groundColor: vec3f)->vec3f {return mix(groundColor,lightColor,info.NdotL);}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nfn computeAreaDiffuseLighting(info: preLightingInfo,lightColor: vec3f)->vec3f {return info.areaLightDiffuse*lightColor;}\n#endif\nfn computeDiffuseLighting(info: preLightingInfo,lightColor: vec3f)->vec3f {var diffuseTerm: vec3f=vec3f(1.0/PI);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_LEGACY\ndiffuseTerm=vec3f(diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.roughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\ndiffuseTerm=vec3f(diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.diffuseRoughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvar clampedAlbedo: vec3f=clamp(info.surfaceAlbedo,vec3f(0.1),vec3f(1.0));diffuseTerm=diffuseBRDF_EON(clampedAlbedo,info.diffuseRoughness,info.NdotL,info.NdotV,info.LdotV);diffuseTerm/=clampedAlbedo;\n#endif\nreturn diffuseTerm*info.attenuation*info.NdotL*lightColor;}\nfn computeProjectionTextureDiffuseLighting(projectionLightTexture: texture_2d<f32>,projectionLightSampler: sampler,textureProjectionMatrix: mat4x4f,posW: vec3f)->vec3f{var strq: vec4f=textureProjectionMatrix* vec4f(posW,1.0);strq/=strq.w;var textureColor: vec3f=textureSample(projectionLightTexture,projectionLightSampler,strq.xy).rgb;return toLinearSpaceVec3(textureColor);}\n#ifdef SS_TRANSLUCENCY\nfn computeDiffuseTransmittedLighting(info: preLightingInfo,lightColor: vec3f,transmittance: vec3f)->vec3f {var transmittanceNdotL=vec3f(0.0);var NdotL: f32=absEps(info.NdotLUnclamped);\n#ifndef SS_TRANSLUCENCY_LEGACY\nif (info.NdotLUnclamped<0.0) {\n#endif\nvar wrapNdotL: f32=computeWrappedDiffuseNdotL(NdotL,0.02);var trAdapt: f32=step(0.,info.NdotLUnclamped);transmittanceNdotL=mix(transmittance*wrapNdotL, vec3f(wrapNdotL),trAdapt);\n#ifndef SS_TRANSLUCENCY_LEGACY\n}\nvar diffuseTerm : vec3f=vec3f(1.0/PI);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_LEGACY\ndiffuseTerm=vec3f(diffuseBRDF_Burley(\ninfo.NdotL,info.NdotV,info.VdotH,info.roughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\ndiffuseTerm=vec3f(diffuseBRDF_Burley(\ninfo.NdotL,info.NdotV,info.VdotH,info.diffuseRoughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvar clampedAlbedo: vec3f=clamp(info.surfaceAlbedo,vec3f(0.1),vec3f(1.0));diffuseTerm=diffuseBRDF_EON(clampedAlbedo,info.diffuseRoughness,\ninfo.NdotL,info.NdotV,info.LdotV);diffuseTerm/=clampedAlbedo;\n#endif\nreturn (transmittanceNdotL*diffuseTerm)*info.attenuation*lightColor;\n#else\nlet diffuseTerm=diffuseBRDF_Burley(NdotL,info.NdotV,info.VdotH,info.roughness);return diffuseTerm*transmittanceNdotL*info.attenuation*lightColor;\n#endif\n}\n#endif\n#ifdef SPECULARTERM\nfn computeSpecularLighting(info: preLightingInfo,N: vec3f,reflectance0: vec3f,fresnel: vec3f,geometricRoughnessFactor: f32,lightColor: vec3f)->vec3f {var NdotH: f32=saturateEps(dot(N,info.H));var roughness: f32=max(info.roughness,geometricRoughnessFactor);var alphaG: f32=convertRoughnessToAverageSlope(roughness);var modifiedFresnel: vec3f=fresnel;\n#ifdef IRIDESCENCE\nmodifiedFresnel=mix(fresnel,reflectance0,info.iridescenceIntensity);\n#endif\nvar distribution: f32=normalDistributionFunction_TrowbridgeReitzGGX(NdotH,alphaG);\n#ifdef BRDF_V_HEIGHT_CORRELATED\nvar smithVisibility: f32=smithVisibility_GGXCorrelated(info.NdotL,info.NdotV,alphaG);\n#else\nvar smithVisibility: f32=smithVisibility_TrowbridgeReitzGGXFast(info.NdotL,info.NdotV,alphaG);\n#endif\nvar specTerm: vec3f=modifiedFresnel*distribution*smithVisibility;return specTerm*info.attenuation*info.NdotL*lightColor;}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nfn computeAreaSpecularLighting(info: preLightingInfo,specularColor: vec3f,reflectance0: vec3f,reflectance90: vec3f)->vec3f {var fresnel:vec3f =reflectance0*specularColor*info.areaLightFresnel.x+( vec3f( 1.0 )-specularColor )*info.areaLightFresnel.y*reflectance90;return specularColor*fresnel*info.areaLightSpecular;}\nfn computeOpenPBRAreaSpecularLighting(info: preLightingInfo,lightColor: vec3f,reflectance0: vec3f,reflectance90: vec3f)->vec3f {let fresnel: vec3f=reflectance0*info.areaLightFresnel.x+(reflectance90-reflectance0)*info.areaLightFresnel.y;return lightColor*fresnel*info.areaLightSpecular;}\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nfn computeOpenPBRAreaConductorSpecularLighting(info: preLightingInfo,lightColor: vec3f,reflectance0: vec3f,edgeTint: vec3f)->vec3f {let b: vec3f=getF82B(reflectance0,edgeTint);let normalizedSchlickMoment: f32=clamp(info.areaLightFresnel.y/max(info.areaLightFresnel.x,Epsilon),0.0f,1.0f);let representativeOneMinusCosTheta: f32=pow(normalizedSchlickMoment,0.2f);let f82DipMoment: f32=info.areaLightFresnel.y*representativeOneMinusCosTheta*(1.0f-representativeOneMinusCosTheta);let fresnel: vec3f=reflectance0*info.areaLightFresnel.x+(vec3f(1.0f)-reflectance0)*info.areaLightFresnel.y-b*f82DipMoment;return lightColor*clamp(fresnel,vec3f(0.0f),vec3f(info.areaLightFresnel.x))*info.areaLightSpecular;}\n#endif\nfn computeOpenPBRAreaFresnel(info: preLightingInfo,reflectance0: f32,reflectance90: f32)->f32 {return reflectance0*info.areaLightFresnel.x+(reflectance90-reflectance0)*info.areaLightFresnel.y;}\n#endif\n#endif\n#ifdef FUZZ\nfn evalFuzz(L: vec3f,NdotL: f32,NdotV: f32,T: vec3f,B: vec3f,ltcLut: vec3f)->f32\n{if (NdotL<=0.0f || NdotV<=0.0f) {return 0.0f;}\nlet M=mat3x3f(\nvec3f(ltcLut.r,0.0f,0.0f),\nvec3f(ltcLut.g,1.0f,0.0f),\nvec3f(0.0f,0.0f,1.0f)\n);let Llocal: vec3f=vec3f(dot(L,T),dot(L,B),NdotL);let Lwarp: vec3f=normalize(M*Llocal);let cosThetaWarp: f32=max(Lwarp.z,0.0f);return cosThetaWarp*NdotL;}\n#endif\n#if defined(ANISOTROPIC) && defined(ANISOTROPIC_OPENPBR)\nfn computeAnisotropicSpecularLighting(info: preLightingInfo,V: vec3f,N: vec3f,T: vec3f,B: vec3f,anisotropy: f32,geometricRoughnessFactor: f32,lightColor: vec3f)->vec3f {var NdotH: f32=saturateEps(dot(N,info.H));var TdotH: f32=dot(T,info.H);var BdotH: f32=dot(B,info.H);var TdotV: f32=dot(T,V);var BdotV: f32=dot(B,V);var TdotL: f32=dot(T,info.L);var BdotL: f32=dot(B,info.L);var alphaG: f32=convertRoughnessToAverageSlope(info.roughness);var alphaTB: vec2f=getAnisotropicRoughness(alphaG,anisotropy);var distribution: f32=normalDistributionFunction_BurleyGGX_Anisotropic(NdotH,TdotH,BdotH,alphaTB);var smithVisibility: f32=smithVisibility_GGXCorrelated_Anisotropic(info.NdotL,info.NdotV,TdotV,BdotV,TdotL,BdotL,alphaTB);var specTerm: vec3f=vec3f(distribution*smithVisibility);return specTerm*info.attenuation*info.NdotL*lightColor;}\n#elif defined(ANISOTROPIC)\nfn computeAnisotropicSpecularLighting(info: preLightingInfo,V: vec3f,N: vec3f,T: vec3f,B: vec3f,anisotropy: f32,reflectance0: vec3f,reflectance90: vec3f,geometricRoughnessFactor: f32,lightColor: vec3f)->vec3f {var NdotH: f32=saturateEps(dot(N,info.H));var TdotH: f32=dot(T,info.H);var BdotH: f32=dot(B,info.H);var TdotV: f32=dot(T,V);var BdotV: f32=dot(B,V);var TdotL: f32=dot(T,info.L);var BdotL: f32=dot(B,info.L);var alphaG: f32=convertRoughnessToAverageSlope(info.roughness);var alphaTB: vec2f=getAnisotropicRoughness(alphaG,anisotropy);alphaTB=max(alphaTB,vec2f(geometricRoughnessFactor*geometricRoughnessFactor));var fresnel: vec3f=fresnelSchlickGGXVec3(info.VdotH,reflectance0,reflectance90);\n#ifdef IRIDESCENCE\nfresnel=mix(fresnel,reflectance0,info.iridescenceIntensity);\n#endif\nvar distribution: f32=normalDistributionFunction_BurleyGGX_Anisotropic(NdotH,TdotH,BdotH,alphaTB);var smithVisibility: f32=smithVisibility_GGXCorrelated_Anisotropic(info.NdotL,info.NdotV,TdotV,BdotV,TdotL,BdotL,alphaTB);var specTerm: vec3f=fresnel*distribution*smithVisibility;return specTerm*info.attenuation*info.NdotL*lightColor;}\n#endif\n#ifdef CLEARCOAT\nfn computeClearCoatLighting(info: preLightingInfo,Ncc: vec3f,geometricRoughnessFactor: f32,clearCoatIntensity: f32,lightColor: vec3f)->vec4f {var NccdotL: f32=saturateEps(dot(Ncc,info.L));var NccdotH: f32=saturateEps(dot(Ncc,info.H));var clearCoatRoughness: f32=max(info.roughness,geometricRoughnessFactor);var alphaG: f32=convertRoughnessToAverageSlope(clearCoatRoughness);var fresnel: f32=fresnelSchlickGGX(info.VdotH,uniforms.vClearCoatRefractionParams.x,CLEARCOATREFLECTANCE90);fresnel*=clearCoatIntensity;var distribution: f32=normalDistributionFunction_TrowbridgeReitzGGX(NccdotH,alphaG);var kelemenVisibility: f32=visibility_Kelemen(info.VdotH);var clearCoatTerm: f32=fresnel*distribution*kelemenVisibility;return vec4f(\nclearCoatTerm*info.attenuation*NccdotL*lightColor,\n1.0-fresnel\n);}\nfn computeClearCoatLightingAbsorption(NdotVRefract: f32,L: vec3f,Ncc: vec3f,clearCoatColor: vec3f,clearCoatThickness: f32,clearCoatIntensity: f32)->vec3f {var LRefract: vec3f=-refract(L,Ncc,uniforms.vClearCoatRefractionParams.y);var NdotLRefract: f32=saturateEps(dot(Ncc,LRefract));var absorption: vec3f=computeClearCoatAbsorption(NdotVRefract,NdotLRefract,clearCoatColor,clearCoatThickness,clearCoatIntensity);return absorption;}\n#endif\n#ifdef SHEEN\nfn computeSheenLighting(info: preLightingInfo,N: vec3f,reflectance0: vec3f,reflectance90: vec3f,geometricRoughnessFactor: f32,lightColor: vec3f)->vec3f {var NdotH: f32=saturateEps(dot(N,info.H));var roughness: f32=max(info.roughness,geometricRoughnessFactor);var alphaG: f32=convertRoughnessToAverageSlope(roughness);var fresnel: f32=1.;var distribution: f32=normalDistributionFunction_CharlieSheen(NdotH,alphaG);/*#ifdef SHEEN_SOFTER\nvar visibility: f32=visibility_CharlieSheen(info.NdotL,info.NdotV,alphaG);\n#else */\nvar visibility: f32=visibility_Ashikhmin(info.NdotL,info.NdotV);/* #endif */\nvar sheenTerm: f32=fresnel*distribution*visibility;return sheenTerm*info.attenuation*info.NdotL*lightColor;}\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#include<clusteredLightingFunctions>\n#include<pbrClusteredLightingFunctions>[0..maxSimultaneousLights]\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrDirectLightingFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrIBLFunctions\";\nconst shader = `#if defined(REFLECTION) || defined(SS_REFRACTION)\nfn getLodFromAlphaG(cubeMapDimensionPixels: f32,microsurfaceAverageSlope: f32)->f32 {var microsurfaceAverageSlopeTexels: f32=cubeMapDimensionPixels*microsurfaceAverageSlope;var lod: f32=log2(microsurfaceAverageSlopeTexels);return lod;}\nfn getLinearLodFromRoughness(cubeMapDimensionPixels: f32,roughness: f32)->f32 {var lod: f32=log2(cubeMapDimensionPixels)*roughness;return lod;}\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(RADIANCEOCCLUSION)\nfn environmentRadianceOcclusion(ambientOcclusion: f32,NdotVUnclamped: f32)->f32 {var temp: f32=NdotVUnclamped+ambientOcclusion;return saturate(temp*temp-1.0+ambientOcclusion);}\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(HORIZONOCCLUSION)\nfn environmentHorizonOcclusion(view: vec3f,normal: vec3f,geometricNormal: vec3f)->f32 {var reflection: vec3f=reflect(view,normal);var temp: f32=saturate(1.0+1.1*dot(reflection,geometricNormal));return temp*temp;}\n#endif\n#if defined(LODINREFLECTIONALPHA) || defined(SS_LODINREFRACTIONALPHA)\nfn UNPACK_LOD(x: f32)->f32 {return (1.0-x)*255.0;}\nfn getLodFromAlphaGNdotV(cubeMapDimensionPixels: f32,alphaG: f32,NdotV: f32)->f32 {var microsurfaceAverageSlope: f32=alphaG;microsurfaceAverageSlope*=sqrt(abs(NdotV));return getLodFromAlphaG(cubeMapDimensionPixels,microsurfaceAverageSlope);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrIBLFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpFragmentMainFunctions\";\nconst shader = `#ifndef TEXRD_DEFINED\nfn TEXRD(t: texture_2d<f32>,ts: sampler,uv: vec2f)->vec4f {return textureSample(t,ts,uv);}\n#define TEXRD_DEFINED\n#endif\n#if defined(BUMP) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC) || defined(DETAIL)\n#if defined(TANGENT) && defined(NORMAL) \nvarying vTBN0: vec3f;varying vTBN1: vec3f;varying vTBN2: vec3f;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nuniform normalMatrix: mat4x4f;fn toNormalMatrix(m: mat4x4f)->mat4x4f\n{var a00=m[0][0];var a01=m[0][1];var a02=m[0][2];var a03=m[0][3];var a10=m[1][0];var a11=m[1][1];var a12=m[1][2];var a13=m[1][3];var a20=m[2][0]; \nvar a21=m[2][1];var a22=m[2][2];var a23=m[2][3];var a30=m[3][0]; \nvar a31=m[3][1];var a32=m[3][2];var a33=m[3][3];var b00=a00*a11-a01*a10;var b01=a00*a12-a02*a10;var b02=a00*a13-a03*a10;var b03=a01*a12-a02*a11;var b04=a01*a13-a03*a11;var b05=a02*a13-a03*a12;var b06=a20*a31-a21*a30;var b07=a20*a32-a22*a30;var b08=a20*a33-a23*a30;var b09=a21*a32-a22*a31;var b10=a21*a33-a23*a31;var b11=a22*a33-a23*a32;var det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;var mi=mat4x4<f32>(\n(a11*b11-a12*b10+a13*b09)/det,\n(a02*b10-a01*b11-a03*b09)/det,\n(a31*b05-a32*b04+a33*b03)/det,\n(a22*b04-a21*b05-a23*b03)/det,\n(a12*b08-a10*b11-a13*b07)/det,\n(a00*b11-a02*b08+a03*b07)/det,\n(a32*b02-a30*b05-a33*b01)/det,\n(a20*b05-a22*b02+a23*b01)/det,\n(a10*b10-a11*b08+a13*b06)/det,\n(a01*b08-a00*b10-a03*b06)/det,\n(a30*b04-a31*b02+a33*b00)/det,\n(a21*b02-a20*b04-a23*b00)/det,\n(a11*b07-a10*b09-a12*b06)/det,\n(a00*b09-a01*b07+a02*b06)/det,\n(a31*b01-a30*b03-a32*b00)/det,\n(a20*b03-a21*b01+a22*b00)/det);return mat4x4<f32>(mi[0][0],mi[1][0],mi[2][0],mi[3][0],\nmi[0][1],mi[1][1],mi[2][1],mi[3][1],\nmi[0][2],mi[1][2],mi[2][2],mi[3][2],\nmi[0][3],mi[1][3],mi[2][3],mi[3][3]);}\n#endif\nfn perturbNormalBase(cotangentFrame: mat3x3f,normal: vec3f,scale: f32)->vec3f\n{var output=normal;\n#ifdef NORMALXYSCALE\noutput=normalize(output* vec3f(scale,scale,1.0));\n#endif\nreturn normalize(cotangentFrame*output);}\nfn perturbNormal(cotangentFrame: mat3x3f,textureSample: vec3f,scale: f32)->vec3f\n{return perturbNormalBase(cotangentFrame,textureSample*2.0-1.0,scale);}\nfn cotangent_frame(normal: vec3f,p: vec3f,uv: vec2f,tangentSpaceParams: vec2f)->mat3x3f\n{var dp1: vec3f=dpdx(p);var dp2: vec3f=dpdy(p);var duv1: vec2f=dpdx(uv);var duv2: vec2f=dpdy(uv);var dp2perp: vec3f=cross(dp2,normal);var dp1perp: vec3f=cross(normal,dp1);var tangent: vec3f=dp2perp*duv1.x+dp1perp*duv2.x;var bitangent: vec3f=dp2perp*duv1.y+dp1perp*duv2.y;tangent*=tangentSpaceParams.x;bitangent*=tangentSpaceParams.y;var det: f32=max(dot(tangent,tangent),dot(bitangent,bitangent));var invmax: f32=select(inverseSqrt(det),0.0,det==0.0);return mat3x3f(tangent*invmax,bitangent*invmax,normal);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bumpFragmentMainFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nconst name = \"bumpFragmentFunctions\";\nconst shader = `#if defined(BUMP)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_SAMPLERNAME_,bump)\n#endif\n#if defined(DETAIL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_SAMPLERNAME_,detail)\n#endif\n#if defined(BUMP) && defined(PARALLAX)\nconst minSamples: f32=4.;const maxSamples: f32=15.;const iMaxSamples: i32=15;fn parallaxOcclusion(vViewDirCoT: vec3f,vNormalCoT: vec3f,texCoord: vec2f,parallaxScale: f32)->vec2f {var parallaxLimit: f32=length(vViewDirCoT.xy)/vViewDirCoT.z;parallaxLimit*=parallaxScale;var vOffsetDir: vec2f=normalize(vViewDirCoT.xy);var vMaxOffset: vec2f=vOffsetDir*parallaxLimit;var numSamples: f32=maxSamples+(dot(vViewDirCoT,vNormalCoT)*(minSamples-maxSamples));var stepSize: f32=1.0/numSamples;var currRayHeight: f32=1.0;var vCurrOffset: vec2f= vec2f(0,0);var vLastOffset: vec2f= vec2f(0,0);var lastSampledHeight: f32=1.0;var currSampledHeight: f32=1.0;var keepWorking: bool=true;for (var i: i32=0; i<iMaxSamples; i++)\n{currSampledHeight=textureSample(bumpSampler,bumpSamplerSampler,texCoord+vCurrOffset).w;if (!keepWorking)\n{}\nelse if (currSampledHeight>currRayHeight)\n{var delta1: f32=currSampledHeight-currRayHeight;var delta2: f32=(currRayHeight+stepSize)-lastSampledHeight;var ratio: f32=delta1/(delta1+delta2);vCurrOffset=(ratio)* vLastOffset+(1.0-ratio)*vCurrOffset;keepWorking=false;}\nelse\n{currRayHeight-=stepSize;vLastOffset=vCurrOffset;\n#ifdef PARALLAX_RHS\nvCurrOffset-=stepSize*vMaxOffset;\n#else\nvCurrOffset+=stepSize*vMaxOffset;\n#endif\nlastSampledHeight=currSampledHeight;}}\nreturn vCurrOffset;}\nfn parallaxOffset(viewDir: vec3f,heightScale: f32)->vec2f\n{var height: f32=textureSample(bumpSampler,bumpSamplerSampler,fragmentInputs.vBumpUV).w;var texCoordOffset: vec2f=heightScale*viewDir.xy*height;\n#ifdef PARALLAX_RHS\nreturn texCoordOffset;\n#else\nreturn -texCoordOffset;\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bumpFragmentFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./decalFragment\";\nconst name = \"pbrBlockAlbedoOpacity\";\nconst shader = `struct albedoOpacityOutParams\n{surfaceAlbedo: vec3f,\nalpha: f32};\n#define pbr_inline\nfn albedoOpacityBlock(\nvAlbedoColor: vec4f\n#ifdef ALBEDO\n,albedoTexture: vec4f\n,albedoInfos: vec2f\n#endif\n,baseWeight: f32\n#ifdef BASE_WEIGHT\n,baseWeightTexture: vec4f\n,vBaseWeightInfos: vec2f\n#endif\n#ifdef OPACITY\n,opacityMap: vec4f\n,vOpacityInfos: vec2f\n#endif\n#ifdef DETAIL\n,detailColor: vec4f\n,vDetailInfos: vec4f\n#endif\n#ifdef DECAL\n,decalColor: vec4f\n,vDecalInfos: vec4f\n#endif\n)->albedoOpacityOutParams\n{var outParams: albedoOpacityOutParams;var surfaceAlbedo: vec3f=vAlbedoColor.rgb;var alpha: f32=vAlbedoColor.a;\n#ifdef ALBEDO\n#if defined(ALPHAFROMALBEDO) || defined(ALPHATEST)\nalpha*=albedoTexture.a;\n#endif\n#ifdef GAMMAALBEDO\nsurfaceAlbedo*=toLinearSpaceVec3(albedoTexture.rgb);\n#else\nsurfaceAlbedo*=albedoTexture.rgb;\n#endif\nsurfaceAlbedo*=albedoInfos.y;\n#endif\n#ifndef DECAL_AFTER_DETAIL\n#include<decalFragment>\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nsurfaceAlbedo*=fragmentInputs.vColor.rgb;\n#endif\n#ifdef DETAIL\nvar detailAlbedo: f32=2.0*mix(0.5,detailColor.r,vDetailInfos.y);surfaceAlbedo=surfaceAlbedo.rgb*detailAlbedo*detailAlbedo; \n#endif\n#ifdef DECAL_AFTER_DETAIL\n#include<decalFragment>\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALBEDO\nsurfaceAlbedo*=baseWeight;\n#ifdef BASE_WEIGHT\nsurfaceAlbedo*=baseWeightTexture.r;\n#endif\n#ifdef OPACITY\n#ifdef OPACITYRGB\nalpha=getLuminance(opacityMap.rgb);\n#else\nalpha*=opacityMap.a;\n#endif\nalpha*=vOpacityInfos.y;\n#endif\n#if defined(VERTEXALPHA) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nalpha*=fragmentInputs.vColor.a;\n#endif\n#if !defined(SS_LINKREFRACTIONTOTRANSPARENCY) && !defined(ALPHAFRESNEL)\n#ifdef ALPHATEST\n#if DEBUGMODE != 88\nif (alpha<ALPHATESTVALUE) {discard;}\n#endif\n#ifndef ALPHABLEND\nalpha=1.0;\n#endif\n#endif\n#endif\noutParams.surfaceAlbedo=surfaceAlbedo;outParams.alpha=alpha;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAlbedoOpacityWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflectivity\";\nconst shader = `struct reflectivityOutParams\n{microSurface: f32,\nroughness: f32,\ndiffuseRoughness: f32,\nreflectanceF0: f32,\nreflectanceF90: vec3f,\ncolorReflectanceF0: vec3f,\ncolorReflectanceF90: vec3f,\n#ifdef METALLICWORKFLOW\nsurfaceAlbedo: vec3f,\nmetallic: f32,\nspecularWeight: f32,\ndielectricColorF0: vec3f,\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\nambientOcclusionColor: vec3f,\n#endif\n#if DEBUGMODE>0\n#ifdef METALLICWORKFLOW\n#ifdef REFLECTIVITY\nsurfaceMetallicColorMap: vec4f,\n#endif\nmetallicF0: vec3f,\n#else\n#ifdef REFLECTIVITY\nsurfaceReflectivityColorMap: vec4f,\n#endif\n#endif\n#endif\n};\n#define pbr_inline\nfn reflectivityBlock(\nreflectivityColor: vec4f\n#ifdef METALLICWORKFLOW\n,surfaceAlbedo: vec3f\n,metallicReflectanceFactors: vec4f\n#endif\n,baseDiffuseRoughness: f32\n#ifdef BASE_DIFFUSE_ROUGHNESS\n,baseDiffuseRoughnessTexture: f32\n,baseDiffuseRoughnessInfos: vec2f\n#endif\n#ifdef REFLECTIVITY\n,reflectivityInfos: vec3f\n,surfaceMetallicOrReflectivityColorMap: vec4f\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\n,ambientOcclusionColorIn: vec3f\n#endif\n#ifdef MICROSURFACEMAP\n,microSurfaceTexel: vec4f\n#endif\n#ifdef DETAIL\n,detailColor: vec4f\n,vDetailInfos: vec4f\n#endif\n)->reflectivityOutParams\n{var outParams: reflectivityOutParams;var microSurface: f32=reflectivityColor.a;var surfaceReflectivityColor: vec3f=reflectivityColor.rgb;\n#ifdef METALLICWORKFLOW\nvar metallicRoughness: vec2f=surfaceReflectivityColor.rg;var ior: f32=surfaceReflectivityColor.b;\n#ifdef REFLECTIVITY\n#if DEBUGMODE>0\noutParams.surfaceMetallicColorMap=surfaceMetallicOrReflectivityColorMap;\n#endif\n#ifdef AOSTOREINMETALMAPRED\nvar aoStoreInMetalMap: vec3f= vec3f(surfaceMetallicOrReflectivityColorMap.r,surfaceMetallicOrReflectivityColorMap.r,surfaceMetallicOrReflectivityColorMap.r);outParams.ambientOcclusionColor=mix(ambientOcclusionColorIn,aoStoreInMetalMap,reflectivityInfos.z);\n#endif\n#ifdef METALLNESSSTOREINMETALMAPBLUE\nmetallicRoughness.r*=surfaceMetallicOrReflectivityColorMap.b;\n#else\nmetallicRoughness.r*=surfaceMetallicOrReflectivityColorMap.r;\n#endif\n#ifdef ROUGHNESSSTOREINMETALMAPALPHA\nmetallicRoughness.g*=surfaceMetallicOrReflectivityColorMap.a;\n#else\n#ifdef ROUGHNESSSTOREINMETALMAPGREEN\nmetallicRoughness.g*=surfaceMetallicOrReflectivityColorMap.g;\n#endif\n#endif\n#endif\n#ifdef DETAIL\nvar detailRoughness: f32=mix(0.5,detailColor.b,vDetailInfos.w);var loLerp: f32=mix(0.,metallicRoughness.g,detailRoughness*2.);var hiLerp: f32=mix(metallicRoughness.g,1.,(detailRoughness-0.5)*2.);metallicRoughness.g=mix(loLerp,hiLerp,step(detailRoughness,0.5));\n#endif\n#ifdef MICROSURFACEMAP\nmetallicRoughness.g*=microSurfaceTexel.r;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_METALLICROUGHNESS\nmicroSurface=1.0-metallicRoughness.g;var baseColor: vec3f=surfaceAlbedo;outParams.metallic=metallicRoughness.r;outParams.specularWeight=metallicReflectanceFactors.a;var dielectricF0 : f32=reflectivityColor.a*outParams.specularWeight;surfaceReflectivityColor=metallicReflectanceFactors.rgb;\n#if DEBUGMODE>0\noutParams.metallicF0=dielectricF0*surfaceReflectivityColor;\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\noutParams.surfaceAlbedo=baseColor.rgb*(vec3f(1.0)-vec3f(dielectricF0)*surfaceReflectivityColor)*(1.0-outParams.metallic);\n#else\noutParams.surfaceAlbedo=baseColor.rgb;\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\n{let reflectivityColor: vec3f=mix(dielectricF0*surfaceReflectivityColor,baseColor.rgb,outParams.metallic);outParams.reflectanceF0=max(reflectivityColor.r,max(reflectivityColor.g,reflectivityColor.b));}\n#else\n#if DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_GLTF\nlet maxF0: f32=max(surfaceReflectivityColor.r,max(surfaceReflectivityColor.g,surfaceReflectivityColor.b));outParams.reflectanceF0=mix(dielectricF0*maxF0,1.0f,outParams.metallic);\n#else\noutParams.reflectanceF0=mix(dielectricF0,1.0,outParams.metallic);\n#endif\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\noutParams.reflectanceF90=vec3(outParams.specularWeight);var f90Scale: f32=1.0;\n#else\nvar f90Scale: f32=clamp(2.0*(ior-1.0),0.0,1.0);outParams.reflectanceF90=vec3(mix(\noutParams.specularWeight*f90Scale,1.0,outParams.metallic));\n#endif\noutParams.dielectricColorF0=vec3f(dielectricF0*surfaceReflectivityColor);var metallicColorF0: vec3f=baseColor.rgb;outParams.colorReflectanceF0=mix(outParams.dielectricColorF0,metallicColorF0,outParams.metallic);\n#if (DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_OPENPBR)\nlet dielectricColorF90\n: vec3f=surfaceReflectivityColor *\nvec3f(outParams.specularWeight*f90Scale);\n#else\nlet dielectricColorF90\n: vec3f=vec3f(outParams.specularWeight*f90Scale);\n#endif\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nlet conductorColorF90: vec3f=surfaceReflectivityColor;\n#else\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\nlet conductorColorF90: vec3f=outParams.reflectanceF90;\n#else\nlet conductorColorF90: vec3f=vec3f(1.0f);\n#endif\n#endif\noutParams.colorReflectanceF90=mix(dielectricColorF90,conductorColorF90,outParams.metallic);\n#else\n#ifdef REFLECTIVITY\nsurfaceReflectivityColor*=surfaceMetallicOrReflectivityColorMap.rgb;\n#if DEBUGMODE>0\noutParams.surfaceReflectivityColorMap=surfaceMetallicOrReflectivityColorMap;\n#endif\n#ifdef MICROSURFACEFROMREFLECTIVITYMAP\nmicroSurface*=surfaceMetallicOrReflectivityColorMap.a;microSurface*=reflectivityInfos.z;\n#else\n#ifdef MICROSURFACEAUTOMATIC\nmicroSurface*=computeDefaultMicroSurface(microSurface,surfaceReflectivityColor);\n#endif\n#ifdef MICROSURFACEMAP\nmicroSurface*=microSurfaceTexel.r;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_MICROSURFACE\n#endif\n#endif\noutParams.colorReflectanceF0=surfaceReflectivityColor;outParams.reflectanceF0=max(surfaceReflectivityColor.r,max(surfaceReflectivityColor.g,surfaceReflectivityColor.b));outParams.reflectanceF90=vec3f(1.0);\n#if (DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_OPENPBR)\noutParams.colorReflectanceF90=surfaceReflectivityColor;\n#else\noutParams.colorReflectanceF90=vec3(1.0);\n#endif\n#endif\nmicroSurface=saturate(microSurface);var roughness: f32=1.-microSurface;var diffuseRoughness: f32=baseDiffuseRoughness;\n#ifdef BASE_DIFFUSE_ROUGHNESS\ndiffuseRoughness*=baseDiffuseRoughnessTexture*baseDiffuseRoughnessInfos.y;\n#endif\noutParams.microSurface=microSurface;outParams.roughness=roughness;outParams.diffuseRoughness=diffuseRoughness;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectivityWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockAmbientOcclusion\";\nconst shader = `struct ambientOcclusionOutParams\n{ambientOcclusionColor: vec3f,\n#if DEBUGMODE>0 && defined(AMBIENT)\nambientOcclusionColorMap: vec3f\n#endif\n};\n#define pbr_inline\nfn ambientOcclusionBlock(\n#ifdef AMBIENT\nambientOcclusionColorMap_: vec3f,\nvAmbientInfos: vec4f\n#endif\n)->ambientOcclusionOutParams\n{ \nvar outParams: ambientOcclusionOutParams;var ambientOcclusionColor: vec3f= vec3f(1.,1.,1.);\n#ifdef AMBIENT\nvar ambientOcclusionColorMap: vec3f=ambientOcclusionColorMap_*vAmbientInfos.y;\n#ifdef AMBIENTINGRAYSCALE\nambientOcclusionColorMap= vec3f(ambientOcclusionColorMap.r,ambientOcclusionColorMap.r,ambientOcclusionColorMap.r);\n#endif\nambientOcclusionColor=mix(ambientOcclusionColor,ambientOcclusionColorMap,vAmbientInfos.z);\n#if DEBUGMODE>0\noutParams.ambientOcclusionColorMap=ambientOcclusionColorMap;\n#endif\n#endif\noutParams.ambientOcclusionColor=ambientOcclusionColor;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAmbientOcclusionWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockAlphaFresnel\";\nconst shader = `#ifdef ALPHAFRESNEL\n#if defined(ALPHATEST) || defined(ALPHABLEND)\nstruct alphaFresnelOutParams\n{alpha: f32};fn faceforward(N: vec3<f32>,I: vec3<f32>,Nref: vec3<f32>)->vec3<f32> {return select(N,-N,dot(Nref,I)>0.0);}\n#define pbr_inline\nfn alphaFresnelBlock(\nnormalW: vec3f,\nviewDirectionW: vec3f,\nalpha: f32,\nmicroSurface: f32\n)->alphaFresnelOutParams\n{var outParams: alphaFresnelOutParams;var opacityPerceptual: f32=alpha;\n#ifdef LINEARALPHAFRESNEL\nvar opacity0: f32=opacityPerceptual;\n#else\nvar opacity0: f32=opacityPerceptual*opacityPerceptual;\n#endif\nvar opacity90: f32=fresnelGrazingReflectance(opacity0);var normalForward: vec3f=faceforward(normalW,-viewDirectionW,normalW);outParams.alpha=getReflectanceFromAnalyticalBRDFLookup_Jones(saturate(dot(viewDirectionW,normalForward)), vec3f(opacity0), vec3f(opacity90),sqrt(microSurface)).x;\n#ifdef ALPHATEST\nif (outParams.alpha<ALPHATESTVALUE) {discard;}\n#ifndef ALPHABLEND\noutParams.alpha=1.0;\n#endif\n#endif\nreturn outParams;}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAlphaFresnelWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockAnisotropic\";\nconst shader = `#ifdef ANISOTROPIC\nstruct anisotropicOutParams\n{anisotropy: f32,\nanisotropicTangent: vec3f,\nanisotropicBitangent: vec3f,\nanisotropicNormal: vec3f,\n#if DEBUGMODE>0 && defined(ANISOTROPIC_TEXTURE)\nanisotropyMapData: vec3f\n#endif\n};\n#define pbr_inline\nfn anisotropicBlock(\nvAnisotropy: vec3f,\nroughness: f32,\n#ifdef ANISOTROPIC_TEXTURE\nanisotropyMapData: vec3f,\n#endif\nTBN: mat3x3f,\nnormalW: vec3f,\nviewDirectionW: vec3f\n)->anisotropicOutParams\n{ \nvar outParams: anisotropicOutParams;var anisotropy: f32=vAnisotropy.b;var anisotropyDirection: vec3f= vec3f(vAnisotropy.xy,0.);\n#ifdef ANISOTROPIC_TEXTURE\nvar amd=anisotropyMapData.rg;anisotropy*=anisotropyMapData.b;\n#if DEBUGMODE>0\noutParams.anisotropyMapData=anisotropyMapData;\n#endif\namd=amd*2.0-1.0;\n#ifdef ANISOTROPIC_LEGACY\nanisotropyDirection=vec3f(anisotropyDirection.xy*amd,anisotropyDirection.z);\n#else\nanisotropyDirection=vec3f(mat2x2f(anisotropyDirection.x,anisotropyDirection.y,-anisotropyDirection.y,anisotropyDirection.x)*normalize(amd),anisotropyDirection.z);\n#endif\n#endif\nvar anisoTBN: mat3x3f= mat3x3f(normalize(TBN[0]),normalize(TBN[1]),normalize(TBN[2]));var anisotropicTangent: vec3f=normalize(anisoTBN*anisotropyDirection);var anisotropicBitangent: vec3f=normalize(cross(anisoTBN[2],anisotropicTangent));outParams.anisotropy=anisotropy;outParams.anisotropicTangent=anisotropicTangent;outParams.anisotropicBitangent=anisotropicBitangent;outParams.anisotropicNormal=getAnisotropicBentNormals(anisotropicTangent,anisotropicBitangent,normalW,viewDirectionW,anisotropy,roughness);return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAnisotropicWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflection\";\nconst shader = `#ifdef REFLECTION\nstruct reflectionOutParams\n{environmentRadiance: vec4f\n,environmentIrradiance: vec3f\n#ifdef REFLECTIONMAP_3D\n,reflectionCoords: vec3f\n#else\n,reflectionCoords: vec2f\n#endif\n#ifdef SS_TRANSLUCENCY\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\n,irradianceVector: vec3f\n#endif\n#endif\n#endif\n};\n#define pbr_inline\n#ifdef REFLECTIONMAP_3D\nfn createReflectionCoords(\nvPositionW: vec3f,\nnormalW: vec3f,\n#ifdef ANISOTROPIC\nanisotropicOut: anisotropicOutParams,\n#endif\n)->vec3f\n{var reflectionCoords: vec3f;\n#else\nfn createReflectionCoords(\nvPositionW: vec3f,\nnormalW: vec3f,\n#ifdef ANISOTROPIC\nanisotropicOut: anisotropicOutParams,\n#endif\n)->vec2f\n{ \nvar reflectionCoords: vec2f;\n#endif\n#ifdef ANISOTROPIC\nvar reflectionVector: vec3f=computeReflectionCoords( vec4f(vPositionW,1.0),anisotropicOut.anisotropicNormal);\n#else\nvar reflectionVector: vec3f=computeReflectionCoords( vec4f(vPositionW,1.0),normalW);\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nreflectionCoords=reflectionVector;\n#else\nreflectionCoords=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\nreturn reflectionCoords;}\n#define pbr_inline\nfn sampleReflectionTexture(\nalphaG: f32\n,vReflectionMicrosurfaceInfos: vec3f\n,vReflectionInfos: vec2f\n,vReflectionColor: vec3f\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,NdotVUnclamped: f32\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,roughness: f32\n#endif\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n,reflectionCoords: vec3f\n#else\n,reflectionSampler: texture_2d<f32>\n,reflectionSamplerSampler: sampler\n,reflectionCoords: vec2f\n#endif\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,reflectionLowSampler: texture_cube<f32>\n,reflectionLowSamplerSampler: sampler\n,reflectionHighSampler: texture_cube<f32>\n,reflectionHighSamplerSampler: sampler\n#else\n,reflectionLowSampler: texture_2d<f32>\n,reflectionLowSamplerSampler: sampler\n,reflectionHighSampler: texture_2d<f32>\n,reflectionHighSamplerSampler: sampler\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo: vec2f\n#endif \n)->vec4f\n{var environmentRadiance: vec4f;\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nvar reflectionLOD: f32=getLodFromAlphaGNdotV(vReflectionMicrosurfaceInfos.x,alphaG,NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nvar reflectionLOD: f32=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,roughness);\n#else\nvar reflectionLOD: f32=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG);\n#endif\n#ifdef LODBASEDMICROSFURACE\nreflectionLOD=reflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\n#ifdef LODINREFLECTIONALPHA\nvar automaticReflectionLOD: f32=UNPACK_LOD(textureSample(reflectionSampler,reflectionSamplerSampler,reflectionCoords).a);var requestedReflectionLOD: f32=max(automaticReflectionLOD,reflectionLOD);\n#else\nvar requestedReflectionLOD: f32=reflectionLOD;\n#endif\n#ifdef REALTIME_FILTERING\nenvironmentRadiance= vec4f(radiance(alphaG,reflectionSampler,reflectionSamplerSampler,reflectionCoords,vReflectionFilteringInfo),1.0);\n#else\nenvironmentRadiance=textureSampleLevel(reflectionSampler,reflectionSamplerSampler,reflectionCoords,reflectionLOD);\n#endif\n#else\nvar lodReflectionNormalized: f32=saturate(reflectionLOD/log2(vReflectionMicrosurfaceInfos.x));var lodReflectionNormalizedDoubled: f32=lodReflectionNormalized*2.0;var environmentMid: vec4f=textureSample(reflectionSampler,reflectionSamplerSampler,reflectionCoords);if (lodReflectionNormalizedDoubled<1.0){environmentRadiance=mix(\ntextureSample(reflectionHighSampler,reflectionHighSamplerSampler,reflectionCoords),\nenvironmentMid,\nlodReflectionNormalizedDoubled\n);} else {environmentRadiance=mix(\nenvironmentMid,\ntextureSample(reflectionLowSampler,reflectionLowSamplerSampler,reflectionCoords),\nlodReflectionNormalizedDoubled-1.0\n);}\n#endif\nvar envRadiance=environmentRadiance.rgb;\n#ifdef RGBDREFLECTION\nenvRadiance=fromRGBD(environmentRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvRadiance=toLinearSpaceVec3(environmentRadiance.rgb);\n#endif\nenvRadiance*=vReflectionInfos.x;envRadiance*=vReflectionColor.rgb;return vec4f(envRadiance,environmentRadiance.a);}\n#define pbr_inline\nfn reflectionBlock(\nvPositionW: vec3f\n,normalW: vec3f\n,alphaG: f32\n,vReflectionMicrosurfaceInfos: vec3f\n,vReflectionInfos: vec2f\n,vReflectionColor: vec3f\n#ifdef ANISOTROPIC\n,anisotropicOut: anisotropicOutParams\n#endif\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,NdotVUnclamped: f32\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,roughness: f32\n#endif\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n#else\n,reflectionSampler: texture_2d<f32>\n,reflectionSamplerSampler: sampler\n#endif\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance: vec3f\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,reflectionMatrix: mat4x4f\n#endif\n#ifdef USEIRRADIANCEMAP\n#ifdef REFLECTIONMAP_3D\n,irradianceSampler: texture_cube<f32>\n,irradianceSamplerSampler: sampler \n#else\n,irradianceSampler: texture_2d<f32>\n,irradianceSamplerSampler: sampler \n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,reflectionDominantDirection: vec3f\n#endif\n#endif\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,reflectionLowSampler: texture_cube<f32>\n,reflectionLowSamplerSampler: sampler \n,reflectionHighSampler: texture_cube<f32>\n,reflectionHighSamplerSampler: sampler \n#else\n,reflectionLowSampler: texture_2d<f32>\n,reflectionLowSamplerSampler: sampler \n,reflectionHighSampler: texture_2d<f32>\n,reflectionHighSamplerSampler: sampler \n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo: vec2f\n#ifdef IBL_CDF_FILTERING\n,icdfSampler: texture_2d<f32>\n,icdfSamplerSampler: sampler\n#endif\n#endif\n,viewDirectionW: vec3f\n,diffuseRoughness: f32\n,surfaceAlbedo: vec3f\n)->reflectionOutParams\n{var outParams: reflectionOutParams;var environmentRadiance: vec4f= vec4f(0.,0.,0.,0.);\n#ifdef REFLECTIONMAP_3D\nvar reflectionCoords: vec3f= vec3f(0.);\n#else\nvar reflectionCoords: vec2f= vec2f(0.);\n#endif\nreflectionCoords=createReflectionCoords(\nvPositionW,\nnormalW,\n#ifdef ANISOTROPIC\nanisotropicOut,\n#endif \n);environmentRadiance=sampleReflectionTexture(\nalphaG\n,vReflectionMicrosurfaceInfos\n,vReflectionInfos\n,vReflectionColor\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,NdotVUnclamped\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,roughness\n#endif\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler\n,reflectionSamplerSampler\n,reflectionCoords\n#else\n,reflectionSampler\n,reflectionSamplerSampler\n,reflectionCoords\n#endif\n#ifndef LODBASEDMICROSFURACE\n,reflectionLowSampler\n,reflectionLowSamplerSampler\n,reflectionHighSampler\n,reflectionHighSamplerSampler\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif \n);var environmentIrradiance: vec3f= vec3f(0.,0.,0.);\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n#ifdef ANISOTROPIC\nvar irradianceVector: vec3f= (reflectionMatrix* vec4f(anisotropicOut.anisotropicNormal,0)).xyz;\n#else\nvar irradianceVector: vec3f= (reflectionMatrix* vec4f(normalW,0)).xyz;\n#endif\nvar irradianceView: vec3f= (reflectionMatrix* vec4f(viewDirectionW,0)).xyz;\n#if !defined(USE_IRRADIANCE_DOMINANT_DIRECTION) && !defined(REALTIME_FILTERING)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\nvar NdotV: f32=max(dot(normalW,viewDirectionW),0.0);irradianceVector=mix(irradianceVector,irradianceView,(0.5*(1.0-NdotV))*diffuseRoughness);\n#endif\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;irradianceView.z*=-1.0;\n#endif\n#ifdef INVERTCUBICMAP\nirradianceVector.y*=-1.0;irradianceView.y*=-1.0;\n#endif\n#endif\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\nenvironmentIrradiance=vEnvironmentIrradiance;\n#else\n#if defined(REALTIME_FILTERING)\nenvironmentIrradiance=irradiance(reflectionSampler,reflectionSamplerSampler,irradianceVector,vReflectionFilteringInfo,diffuseRoughness,surfaceAlbedo,irradianceView\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n);\n#else\nenvironmentIrradiance=computeEnvironmentIrradiance(irradianceVector);\n#endif\n#ifdef SS_TRANSLUCENCY\noutParams.irradianceVector=irradianceVector;\n#endif\n#endif\n#elif defined(USEIRRADIANCEMAP)\n#ifdef REFLECTIONMAP_3D\nvar environmentIrradiance4: vec4f=textureSample(irradianceSampler,irradianceSamplerSampler,irradianceVector);\n#else\nvar environmentIrradiance4: vec4f=textureSample(irradianceSampler,irradianceSamplerSampler,reflectionCoords);\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\nvar Ls: vec3f=normalize(reflectionDominantDirection);var NoL: f32=dot(irradianceVector,Ls);var NoV: f32=dot(irradianceVector,irradianceView);var diffuseRoughnessTerm: vec3f=vec3f(1.0);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvar LoV: f32=dot(Ls,irradianceView);var mag: f32=length(reflectionDominantDirection)*2.0f;var clampedAlbedo: vec3f=clamp(surfaceAlbedo,vec3f(0.1),vec3f(1.0));diffuseRoughnessTerm=diffuseBRDF_EON(clampedAlbedo,diffuseRoughness,NoL,NoV,LoV)*PI;diffuseRoughnessTerm=diffuseRoughnessTerm/clampedAlbedo;diffuseRoughnessTerm=mix(vec3f(1.0),diffuseRoughnessTerm,sqrt(clamp(mag*NoV,0.0,1.0f)));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvar H: vec3f=(irradianceView+Ls)*0.5f;var VoH: f32=dot(irradianceView,H);diffuseRoughnessTerm=vec3f(diffuseBRDF_Burley(NoL,NoV,VoH,diffuseRoughness)*PI);\n#endif\nenvironmentIrradiance=environmentIrradiance4.rgb*diffuseRoughnessTerm;\n#else\nenvironmentIrradiance=environmentIrradiance4.rgb;\n#endif\n#ifdef RGBDREFLECTION\nenvironmentIrradiance=fromRGBD(environmentIrradiance4);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentIrradiance=toLinearSpaceVec3(environmentIrradiance.rgb);\n#endif\n#endif\nenvironmentIrradiance*=vReflectionColor.rgb*vReflectionInfos.x;\n#ifdef MIX_IBL_RADIANCE_WITH_IRRADIANCE\noutParams.environmentRadiance=vec4f(mix(environmentRadiance.rgb,environmentIrradiance,alphaG),environmentRadiance.a);\n#else\noutParams.environmentRadiance=environmentRadiance;\n#endif\noutParams.environmentIrradiance=environmentIrradiance;outParams.reflectionCoords=reflectionCoords;return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectionWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockSheen\";\nconst shader = `#ifdef SHEEN\nstruct sheenOutParams\n{sheenIntensity: f32\n,sheenColor: vec3f\n,sheenRoughness: f32\n#ifdef SHEEN_LINKWITHALBEDO\n,surfaceAlbedo: vec3f\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\n,sheenAlbedoScaling: f32\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\n,finalSheenRadianceScaled: vec3f\n#endif\n#if DEBUGMODE>0\n#ifdef SHEEN_TEXTURE\n,sheenMapData: vec4f\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\n,sheenEnvironmentReflectance: vec3f\n#endif\n#endif\n};\n#define pbr_inline\nfn sheenBlock(\nvSheenColor: vec4f\n#ifdef SHEEN_ROUGHNESS\n,vSheenRoughness: f32\n#if defined(SHEEN_TEXTURE_ROUGHNESS) && !defined(SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,sheenMapRoughnessData: vec4f\n#endif\n#endif\n,roughness: f32\n#ifdef SHEEN_TEXTURE\n,sheenMapData: vec4f\n,sheenMapLevel: f32\n#endif\n,reflectance: f32\n#ifdef SHEEN_LINKWITHALBEDO\n,baseColor: vec3f\n,surfaceAlbedo: vec3f\n#endif\n#ifdef ENVIRONMENTBRDF\n,NdotV: f32\n,environmentBrdf: vec3f\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\n,AARoughnessFactors: vec2f\n,vReflectionMicrosurfaceInfos: vec3f\n,vReflectionInfos: vec2f\n,vReflectionColor: vec3f\n,vLightingIntensity: vec4f\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n,reflectionCoords: vec3f\n#else\n,reflectionSampler: texture_2d<f32>\n,reflectionSamplerSampler: sampler\n,reflectionCoords: vec2f\n#endif\n,NdotVUnclamped: f32\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,reflectionLowSampler: texture_cube<f32>\n,reflectionLowSamplerSampler: sampler \n,reflectionHighSampler: texture_cube<f32>\n,reflectionHighSamplerSampler: sampler \n#else\n,reflectionLowSampler: texture_2d<f32>\n,reflectionLowSamplerSampler: sampler \n,reflectionHighSampler: texture_2d<f32>\n,reflectionHighSamplerSampler: sampler \n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo: vec2f\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(RADIANCEOCCLUSION)\n,seo: f32\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\n,eho: f32\n#endif\n#endif\n)->sheenOutParams\n{var outParams: sheenOutParams;var sheenIntensity: f32=vSheenColor.a;\n#ifdef SHEEN_TEXTURE\n#if DEBUGMODE>0\noutParams.sheenMapData=sheenMapData;\n#endif\n#endif\n#ifdef SHEEN_LINKWITHALBEDO\nvar sheenFactor: f32=pow5(1.0-sheenIntensity);var sheenColor: vec3f=baseColor.rgb*(1.0-sheenFactor);var sheenRoughness: f32=sheenIntensity;outParams.surfaceAlbedo=surfaceAlbedo*sheenFactor;\n#ifdef SHEEN_TEXTURE\nsheenIntensity*=sheenMapData.a;\n#endif\n#else\nvar sheenColor: vec3f=vSheenColor.rgb;\n#ifdef SHEEN_TEXTURE\n#ifdef SHEEN_GAMMATEXTURE\nsheenColor*=toLinearSpaceVec3(sheenMapData.rgb);\n#else\nsheenColor*=sheenMapData.rgb;\n#endif\nsheenColor*=sheenMapLevel;\n#endif\n#ifdef SHEEN_ROUGHNESS\nvar sheenRoughness: f32=vSheenRoughness;\n#ifdef SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE\n#if defined(SHEEN_TEXTURE)\nsheenRoughness*=sheenMapData.a;\n#endif\n#elif defined(SHEEN_TEXTURE_ROUGHNESS)\nsheenRoughness*=sheenMapRoughnessData.a;\n#endif\n#else\nvar sheenRoughness: f32=roughness;\n#ifdef SHEEN_TEXTURE\nsheenIntensity*=sheenMapData.a;\n#endif\n#endif\n#if !defined(SHEEN_ALBEDOSCALING)\nsheenIntensity*=(1.-reflectance);\n#endif\nsheenColor*=sheenIntensity;\n#endif\n#ifdef ENVIRONMENTBRDF\n/*#ifdef SHEEN_SOFTER\nvar environmentSheenBrdf: vec3f= vec3f(0.,0.,getBRDFLookupCharlieSheen(NdotV,sheenRoughness));\n#else*/\n#ifdef SHEEN_ROUGHNESS\nvar environmentSheenBrdf: vec3f=getBRDFLookup(NdotV,sheenRoughness);\n#else\nvar environmentSheenBrdf: vec3f=environmentBrdf;\n#endif\n/*#endif*/\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\nvar sheenAlphaG: f32=convertRoughnessToAverageSlope(sheenRoughness);\n#ifdef SPECULARAA\nsheenAlphaG+=AARoughnessFactors.y;\n#endif\nvar environmentSheenRadiance: vec4f= vec4f(0.,0.,0.,0.);environmentSheenRadiance=sampleReflectionTexture(\nsheenAlphaG\n,vReflectionMicrosurfaceInfos\n,vReflectionInfos\n,vReflectionColor\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,NdotVUnclamped\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,sheenRoughness\n#endif\n,reflectionSampler\n,reflectionSamplerSampler\n,reflectionCoords\n#ifndef LODBASEDMICROSFURACE\n,reflectionLowSampler\n,reflectionLowSamplerSampler\n,reflectionHighSampler\n,reflectionHighSamplerSampler\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);var sheenEnvironmentReflectance: vec3f=getSheenReflectanceFromBRDFLookup(sheenColor,environmentSheenBrdf);\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(RADIANCEOCCLUSION)\nsheenEnvironmentReflectance*=seo;\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\nsheenEnvironmentReflectance*=eho;\n#endif\n#if DEBUGMODE>0\noutParams.sheenEnvironmentReflectance=sheenEnvironmentReflectance;\n#endif\noutParams.finalSheenRadianceScaled=\nenvironmentSheenRadiance.rgb *\nsheenEnvironmentReflectance *\nvLightingIntensity.z;\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\noutParams.sheenAlbedoScaling=1.0-sheenIntensity*max(max(sheenColor.r,sheenColor.g),sheenColor.b)*environmentSheenBrdf.b;\n#endif\noutParams.sheenIntensity=sheenIntensity;outParams.sheenColor=sheenColor;outParams.sheenRoughness=sheenRoughness;return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockSheenWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockClearcoat\";\nconst shader = `struct clearcoatOutParams\n{specularEnvironmentR0: vec3f,\nconservationFactor: f32,\nclearCoatNormalW: vec3f,\nclearCoatAARoughnessFactors: vec2f,\nclearCoatIntensity: f32,\nclearCoatRoughness: f32,\n#ifdef REFLECTION\nfinalClearCoatRadianceScaled: vec3f,\n#endif\n#ifdef CLEARCOAT_TINT\nabsorption: vec3f,\nclearCoatNdotVRefract: f32,\nclearCoatColor: vec3f,\nclearCoatThickness: f32,\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nenergyConservationFactorClearCoat: vec3f,\n#endif\n#if DEBUGMODE>0\n#ifdef CLEARCOAT_BUMP\nTBNClearCoat: mat3x3f,\n#endif\n#ifdef CLEARCOAT_TEXTURE\nclearCoatMapData: vec2f,\n#endif\n#if defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\nclearCoatTintMapData: vec4f,\n#endif\n#ifdef REFLECTION\nenvironmentClearCoatRadiance: vec4f,\nclearCoatEnvironmentReflectance: vec3f,\n#endif\nclearCoatNdotV: f32\n#endif\n};\n#ifdef CLEARCOAT\n#define pbr_inline\nfn clearcoatBlock(\nvPositionW: vec3f\n,geometricNormalW: vec3f\n,viewDirectionW: vec3f\n,vClearCoatParams: vec2f\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_TEXTURE_ROUGHNESS_IDENTICAL) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,clearCoatMapRoughnessData: vec4f\n#endif\n,specularEnvironmentR0: vec3f\n#ifdef CLEARCOAT_TEXTURE\n,clearCoatMapData: vec2f\n#endif\n#ifdef CLEARCOAT_TINT\n,vClearCoatTintParams: vec4f\n,clearCoatColorAtDistance: f32\n,vClearCoatRefractionParams: vec4f\n#ifdef CLEARCOAT_TINT_TEXTURE\n,clearCoatTintMapData: vec4f\n#endif\n#endif\n#ifdef CLEARCOAT_BUMP\n,vClearCoatBumpInfos: vec2f\n,clearCoatBumpMapData: vec4f\n,vClearCoatBumpUV: vec2f\n#if defined(TANGENT) && defined(NORMAL)\n,vTBN: mat3x3f\n#else\n,vClearCoatTangentSpaceParams: vec2f\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n,normalMatrix: mat4x4f\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\n,faceNormal: vec3f\n#endif\n#ifdef REFLECTION\n,vReflectionMicrosurfaceInfos: vec3f\n,vReflectionInfos: vec2f\n,vReflectionColor: vec3f\n,vLightingIntensity: vec4f\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n#else\n,reflectionSampler: texture_2d<f32>\n,reflectionSamplerSampler: sampler\n#endif\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,reflectionLowSampler: texture_cube<f32>\n,reflectionLowSamplerSampler: sampler \n,reflectionHighSampler: texture_cube<f32>\n,reflectionHighSamplerSampler: sampler \n#else\n,reflectionLowSampler: texture_2d<f32>\n,reflectionLowSamplerSampler: sampler \n,reflectionHighSampler: texture_2d<f32>\n,reflectionHighSamplerSampler: sampler \n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo: vec2f\n#endif\n#endif\n#if defined(CLEARCOAT_BUMP) || defined(TWOSIDEDLIGHTING)\n,frontFacingMultiplier: f32\n#endif \n)->clearcoatOutParams\n{var outParams: clearcoatOutParams;var clearCoatIntensity: f32=vClearCoatParams.x;var clearCoatRoughness: f32=vClearCoatParams.y;\n#ifdef CLEARCOAT_TEXTURE\nclearCoatIntensity*=clearCoatMapData.x;\n#ifdef CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE\nclearCoatRoughness*=clearCoatMapData.y;\n#endif\n#if DEBUGMODE>0\noutParams.clearCoatMapData=clearCoatMapData;\n#endif\n#endif\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\nclearCoatRoughness*=clearCoatMapRoughnessData.y;\n#endif\noutParams.clearCoatIntensity=clearCoatIntensity;outParams.clearCoatRoughness=clearCoatRoughness;\n#ifdef CLEARCOAT_TINT\nvar clearCoatColor: vec3f=vClearCoatTintParams.rgb;var clearCoatThickness: f32=vClearCoatTintParams.a;\n#ifdef CLEARCOAT_TINT_TEXTURE\n#ifdef CLEARCOAT_TINT_GAMMATEXTURE\nclearCoatColor*=toLinearSpaceVec3(clearCoatTintMapData.rgb);\n#else\nclearCoatColor*=clearCoatTintMapData.rgb;\n#endif\nclearCoatThickness*=clearCoatTintMapData.a;\n#if DEBUGMODE>0\noutParams.clearCoatTintMapData=clearCoatTintMapData;\n#endif\n#endif\noutParams.clearCoatColor=computeColorAtDistanceInMedia(clearCoatColor,clearCoatColorAtDistance);outParams.clearCoatThickness=clearCoatThickness;\n#endif\n#ifdef CLEARCOAT_REMAP_F0\nvar specularEnvironmentR0Updated: vec3f=getR0RemappedForClearCoat(specularEnvironmentR0);\n#else\nvar specularEnvironmentR0Updated: vec3f=specularEnvironmentR0;\n#endif\noutParams.specularEnvironmentR0=mix(specularEnvironmentR0,specularEnvironmentR0Updated,clearCoatIntensity);var clearCoatNormalW: vec3f=geometricNormalW;\n#ifdef CLEARCOAT_BUMP\n#ifdef NORMALXYSCALE\nvar clearCoatNormalScale: f32=1.0;\n#else\nvar clearCoatNormalScale: f32=vClearCoatBumpInfos.y;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nvar TBNClearCoat: mat3x3f=vTBN;\n#else\nvar TBNClearCoatUV: vec2f=vClearCoatBumpUV*frontFacingMultiplier;var TBNClearCoat: mat3x3f=cotangent_frame(clearCoatNormalW*clearCoatNormalScale,vPositionW,TBNClearCoatUV,vClearCoatTangentSpaceParams);\n#endif\n#if DEBUGMODE>0\noutParams.TBNClearCoat=TBNClearCoat;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nclearCoatNormalW=normalize(clearCoatBumpMapData.xyz *2.0-1.0);clearCoatNormalW=normalize( mat3x3f(normalMatrix[0].xyz,normalMatrix[1].xyz,normalMatrix[2].xyz)*clearCoatNormalW);\n#else\nclearCoatNormalW=perturbNormal(TBNClearCoat,clearCoatBumpMapData.xyz,vClearCoatBumpInfos.y);\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nclearCoatNormalW*=sign(dot(clearCoatNormalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\nclearCoatNormalW=clearCoatNormalW*frontFacingMultiplier;\n#endif\noutParams.clearCoatNormalW=clearCoatNormalW;outParams.clearCoatAARoughnessFactors=getAARoughnessFactors(clearCoatNormalW.xyz);var clearCoatNdotVUnclamped: f32=dot(clearCoatNormalW,viewDirectionW);var clearCoatNdotV: f32=absEps(clearCoatNdotVUnclamped);\n#if DEBUGMODE>0\noutParams.clearCoatNdotV=clearCoatNdotV;\n#endif\n#ifdef CLEARCOAT_TINT\nvar clearCoatVRefract: vec3f=refract(-viewDirectionW,clearCoatNormalW,vClearCoatRefractionParams.y);outParams.clearCoatNdotVRefract=absEps(dot(clearCoatNormalW,clearCoatVRefract));\n#endif\n#if defined(ENVIRONMENTBRDF) && (!defined(REFLECTIONMAP_SKYBOX) || defined(MS_BRDF_ENERGY_CONSERVATION))\nvar environmentClearCoatBrdf: vec3f=getBRDFLookup(clearCoatNdotV,clearCoatRoughness);\n#endif\n#if defined(REFLECTION)\nvar clearCoatAlphaG: f32=convertRoughnessToAverageSlope(clearCoatRoughness);\n#ifdef SPECULARAA\nclearCoatAlphaG+=outParams.clearCoatAARoughnessFactors.y;\n#endif\nvar environmentClearCoatRadiance: vec4f= vec4f(0.,0.,0.,0.);var clearCoatReflectionVector: vec3f=computeReflectionCoords( vec4f(vPositionW,1.0),clearCoatNormalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nclearCoatReflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nvar clearCoatReflectionCoords: vec3f=clearCoatReflectionVector;\n#else\nvar clearCoatReflectionCoords: vec2f=clearCoatReflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nclearCoatReflectionCoords/=clearCoatReflectionVector.z;\n#endif\nclearCoatReflectionCoords.y=1.0-clearCoatReflectionCoords.y;\n#endif\nenvironmentClearCoatRadiance=sampleReflectionTexture(\nclearCoatAlphaG\n,vReflectionMicrosurfaceInfos\n,vReflectionInfos\n,vReflectionColor\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,clearCoatNdotVUnclamped\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,clearCoatRoughness\n#endif\n,reflectionSampler\n,reflectionSamplerSampler\n,clearCoatReflectionCoords\n#ifndef LODBASEDMICROSFURACE\n,reflectionLowSampler\n,reflectionLowSamplerSampler\n,reflectionHighSampler\n,reflectionHighSamplerSampler\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif \n);\n#if DEBUGMODE>0\noutParams.environmentClearCoatRadiance=environmentClearCoatRadiance;\n#endif\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\nvar clearCoatEnvironmentReflectance: vec3f=getReflectanceFromBRDFLookup(vec3f(uniforms.vClearCoatRefractionParams.x),environmentClearCoatBrdf);\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nvar clearCoatEho: f32=environmentHorizonOcclusion(-viewDirectionW,clearCoatNormalW,geometricNormalW);clearCoatEnvironmentReflectance*=clearCoatEho;\n#endif\n#endif\n#endif\n#else\nvar clearCoatEnvironmentReflectance: vec3f=getReflectanceFromAnalyticalBRDFLookup_Jones(clearCoatNdotV, vec3f(1.), vec3f(1.),sqrt(1.-clearCoatRoughness));\n#endif\nclearCoatEnvironmentReflectance*=clearCoatIntensity;\n#if DEBUGMODE>0\noutParams.clearCoatEnvironmentReflectance=clearCoatEnvironmentReflectance;\n#endif\noutParams.finalClearCoatRadianceScaled=\nenvironmentClearCoatRadiance.rgb *\nclearCoatEnvironmentReflectance *\nvLightingIntensity.z;\n#endif\n#if defined(CLEARCOAT_TINT)\noutParams.absorption=computeClearCoatAbsorption(outParams.clearCoatNdotVRefract,outParams.clearCoatNdotVRefract,outParams.clearCoatColor,clearCoatThickness,clearCoatIntensity);\n#endif\nvar fresnelIBLClearCoat: f32=fresnelSchlickGGX(clearCoatNdotV,uniforms.vClearCoatRefractionParams.x,CLEARCOATREFLECTANCE90);fresnelIBLClearCoat*=clearCoatIntensity;outParams.conservationFactor=(1.-fresnelIBLClearCoat);\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\noutParams.energyConservationFactorClearCoat=getEnergyConservationFactor(outParams.specularEnvironmentR0,environmentClearCoatBrdf);\n#endif\nreturn outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockClearcoatWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockIridescence\";\nconst shader = `struct iridescenceOutParams\n{iridescenceIntensity: f32,\niridescenceIOR: f32,\niridescenceThickness: f32,\nspecularEnvironmentR0: vec3f};\n#ifdef IRIDESCENCE\nfn iridescenceBlock(\nvIridescenceParams: vec4f\n,viewAngle_: f32\n,specularEnvironmentR0: vec3f\n#ifdef IRIDESCENCE_TEXTURE\n,iridescenceMapData: vec2f\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\n,iridescenceThicknessMapData: vec2f\n#endif\n#ifdef CLEARCOAT\n,NdotVUnclamped: f32\n,vClearCoatParams: vec2f\n#ifdef CLEARCOAT_TEXTURE\n,clearCoatMapData: vec2f\n#endif\n#endif\n)->iridescenceOutParams\n{var outParams: iridescenceOutParams;var iridescenceIntensity: f32=vIridescenceParams.x;var iridescenceIOR: f32=vIridescenceParams.y;var iridescenceThicknessMin: f32=vIridescenceParams.z;var iridescenceThicknessMax: f32=vIridescenceParams.w;var iridescenceThicknessWeight: f32=1.;var viewAngle=viewAngle_;\n#ifdef IRIDESCENCE_TEXTURE\niridescenceIntensity*=iridescenceMapData.x;\n#endif\n#if defined(IRIDESCENCE_THICKNESS_TEXTURE)\niridescenceThicknessWeight=iridescenceThicknessMapData.g;\n#endif\nvar iridescenceThickness: f32=mix(iridescenceThicknessMin,iridescenceThicknessMax,iridescenceThicknessWeight);var topIor: f32=1.; \n#ifdef CLEARCOAT\nvar clearCoatIntensity: f32=vClearCoatParams.x;\n#ifdef CLEARCOAT_TEXTURE\nclearCoatIntensity*=clearCoatMapData.x;\n#endif\ntopIor=mix(1.0,uniforms.vClearCoatRefractionParams.w-1.,clearCoatIntensity);viewAngle=sqrt(1.0+((1.0/topIor)*(1.0/topIor))*((NdotVUnclamped*NdotVUnclamped)-1.0));\n#endif\nvar iridescenceFresnel: vec3f=evalIridescence(topIor,iridescenceIOR,viewAngle,iridescenceThickness,specularEnvironmentR0);outParams.specularEnvironmentR0=mix(specularEnvironmentR0,iridescenceFresnel,iridescenceIntensity);outParams.iridescenceIntensity=iridescenceIntensity;outParams.iridescenceThickness=iridescenceThickness;outParams.iridescenceIOR=iridescenceIOR;return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockIridescenceWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockSubSurface\";\nconst shader = `struct subSurfaceOutParams\n{specularEnvironmentReflectance: vec3f,\n#ifdef SS_REFRACTION\nfinalRefraction: vec3f,\nsurfaceAlbedo: vec3f,\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nalpha: f32,\n#endif\nrefractionOpacity: f32,\n#endif\n#ifdef SS_TRANSLUCENCY\ntransmittance: vec3f,\ntranslucencyIntensity: f32,\n#ifdef REFLECTION\nrefractionIrradiance: vec3f,\n#endif\n#endif\n#if DEBUGMODE>0\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nthicknessMap: vec4f,\n#endif\n#ifdef SS_REFRACTION\nenvironmentRefraction: vec4f,\nrefractionTransmittance: vec3f\n#endif\n#endif\n};\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\n#define pbr_inline\nfn sampleEnvironmentRefraction(\nior: f32\n,thickness: f32\n,refractionLOD: f32\n,normalW: vec3f\n,vPositionW: vec3f\n,viewDirectionW: vec3f\n,view: mat4x4f\n,vRefractionInfos: vec4f\n,refractionMatrix: mat4x4f\n,vRefractionMicrosurfaceInfos: vec4f\n,alphaG: f32\n#ifdef SS_REFRACTIONMAP_3D\n,refractionSampler: texture_cube<f32>\n,refractionSamplerSampler: sampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler: texture_cube<f32>\n,refractionLowSamplerSampler: sampler\n,refractionHighSampler: texture_cube<f32>\n,refractionHighSamplerSampler: sampler \n#endif\n#else\n,refractionSampler: texture_2d<f32>\n,refractionSamplerSampler: sampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler: texture_2d<f32>\n,refractionLowSamplerSampler: sampler\n,refractionHighSampler: texture_2d<f32>\n,refractionHighSamplerSampler: sampler \n#endif\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut: anisotropicOutParams\n#endif\n#ifdef REALTIME_FILTERING\n,vRefractionFilteringInfo: vec2f\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,refractionPosition: vec3f\n,refractionSize: vec3f\n#endif\n)->vec4f {var environmentRefraction: vec4f= vec4f(0.,0.,0.,0.);\n#ifdef ANISOTROPIC\nvar refractionVector: vec3f=refract(-viewDirectionW,anisotropicOut.anisotropicNormal,ior);\n#else\nvar refractionVector: vec3f=refract(-viewDirectionW,normalW,ior);\n#endif\n#ifdef SS_REFRACTIONMAP_OPPOSITEZ\nrefractionVector.z*=-1.0;\n#endif\n#ifdef SS_REFRACTIONMAP_3D\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\nrefractionVector=parallaxCorrectNormal(vPositionW,refractionVector,refractionSize,refractionPosition);\n#endif\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;var refractionCoords: vec3f=refractionVector;refractionCoords= (refractionMatrix* vec4f(refractionCoords,0)).xyz;\n#else\n#ifdef SS_USE_THICKNESS_AS_DEPTH\nvar vRefractionUVW: vec3f= (refractionMatrix*(view* vec4f(vPositionW+refractionVector*thickness,1.0))).xyz;\n#else\nvar vRefractionUVW: vec3f= (refractionMatrix*(view* vec4f(vPositionW+refractionVector*vRefractionInfos.z,1.0))).xyz;\n#endif\nvar refractionCoords: vec2f=vRefractionUVW.xy/vRefractionUVW.z;refractionCoords.y=1.0-refractionCoords.y;\n#endif\n#ifdef LODBASEDMICROSFURACE\nvar lod=refractionLOD*vRefractionMicrosurfaceInfos.y+vRefractionMicrosurfaceInfos.z;\n#ifdef SS_LODINREFRACTIONALPHA\nvar automaticRefractionLOD: f32=UNPACK_LOD(textureSample(refractionSampler,refractionSamplerSampler,refractionCoords).a);var requestedRefractionLOD: f32=max(automaticRefractionLOD,lod);\n#else\nvar requestedRefractionLOD: f32=lod;\n#endif\n#if defined(REALTIME_FILTERING) && defined(SS_REFRACTIONMAP_3D)\nenvironmentRefraction= vec4f(radiance(alphaG,refractionSampler,refractionSamplerSampler,refractionCoords,vRefractionFilteringInfo),1.0);\n#else\nenvironmentRefraction=textureSampleLevel(refractionSampler,refractionSamplerSampler,refractionCoords,requestedRefractionLOD);\n#endif\n#else\nvar lodRefractionNormalized: f32=saturate(refractionLOD/log2(vRefractionMicrosurfaceInfos.x));var lodRefractionNormalizedDoubled: f32=lodRefractionNormalized*2.0;var environmentRefractionMid: vec4f=textureSample(refractionSampler,refractionSamplerSampler,refractionCoords);if (lodRefractionNormalizedDoubled<1.0){environmentRefraction=mix(\ntextureSample(refractionHighSampler,refractionHighSamplerSampler,refractionCoords),\nenvironmentRefractionMid,\nlodRefractionNormalizedDoubled\n);} else {environmentRefraction=mix(\nenvironmentRefractionMid,\ntextureSample(refractionLowSampler,refractionLowSamplerSampler,refractionCoords),\nlodRefractionNormalizedDoubled-1.0\n);}\n#endif\nvar refraction=environmentRefraction.rgb;\n#ifdef SS_RGBDREFRACTION\nrefraction=fromRGBD(environmentRefraction);\n#endif\n#ifdef SS_GAMMAREFRACTION\nrefraction=toLinearSpaceVec3(environmentRefraction.rgb);\n#endif\nreturn vec4f(refraction,environmentRefraction.a);}\n#endif\n#define pbr_inline\nfn subSurfaceBlock(\nvSubSurfaceIntensity: vec3f\n,vThicknessParam: vec2f\n,vTintColor: vec4f\n,normalW: vec3f\n,specularEnvironmentReflectance: vec3f\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n,thicknessMap: vec4f\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\n,refractionIntensityMap: vec4f\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\n,translucencyIntensityMap: vec4f\n#endif\n#ifdef REFLECTION\n#ifdef SS_TRANSLUCENCY\n,reflectionMatrix: mat4x4f\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\n,irradianceVector_: vec3f\n#endif\n#if defined(REALTIME_FILTERING)\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n,vReflectionFilteringInfo: vec2f\n#ifdef IBL_CDF_FILTERING\n,icdfSampler: texture_2d<f32>\n,icdfSamplerSampler: sampler\n#endif\n#endif\n#endif\n#ifdef USEIRRADIANCEMAP\n#ifdef REFLECTIONMAP_3D\n,irradianceSampler: texture_cube<f32>\n,irradianceSamplerSampler: sampler\n#else\n,irradianceSampler: texture_2d<f32>\n,irradianceSamplerSampler: sampler\n#endif\n#endif\n#endif\n#endif\n#if defined(SS_REFRACTION) || defined(SS_TRANSLUCENCY)\n,surfaceAlbedo: vec3f\n#endif\n#ifdef SS_REFRACTION\n,vPositionW: vec3f\n,viewDirectionW: vec3f\n,view: mat4x4f\n,vRefractionInfos: vec4f\n,refractionMatrix: mat4x4f\n,vRefractionMicrosurfaceInfos: vec4f\n,vLightingIntensity: vec4f\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\n,alpha: f32\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\n,NdotVUnclamped: f32\n#endif\n#ifdef SS_LINEARSPECULARREFRACTION\n,roughness: f32\n#endif\n,alphaG: f32\n#ifdef SS_REFRACTIONMAP_3D\n,refractionSampler: texture_cube<f32>\n,refractionSamplerSampler: sampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler: texture_cube<f32>\n,refractionLowSamplerSampler: sampler\n,refractionHighSampler: texture_cube<f32>\n,refractionHighSamplerSampler: sampler \n#endif\n#else\n,refractionSampler: texture_2d<f32>\n,refractionSamplerSampler: sampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler: texture_2d<f32>\n,refractionLowSamplerSampler: sampler\n,refractionHighSampler: texture_2d<f32>\n,refractionHighSamplerSampler: sampler \n#endif\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut: anisotropicOutParams\n#endif\n#ifdef REALTIME_FILTERING\n,vRefractionFilteringInfo: vec2f\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,refractionPosition: vec3f\n,refractionSize: vec3f\n#endif\n#ifdef SS_DISPERSION\n,dispersion: f32\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\n,vDiffusionDistance: vec3f\n,vTranslucencyColor: vec4f\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\n,translucencyColorMap: vec4f\n#endif\n#endif\n)->subSurfaceOutParams\n{var outParams: subSurfaceOutParams;outParams.specularEnvironmentReflectance=specularEnvironmentReflectance;\n#ifdef SS_REFRACTION\nvar refractionIntensity: f32=vSubSurfaceIntensity.x;\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nrefractionIntensity*=(1.0-alpha);outParams.alpha=1.0;\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\nvar translucencyIntensity: f32=vSubSurfaceIntensity.y;\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n#ifdef SS_USE_GLTF_TEXTURES\nvar thickness: f32=thicknessMap.g*vThicknessParam.y+vThicknessParam.x;\n#else\nvar thickness: f32=thicknessMap.r*vThicknessParam.y+vThicknessParam.x;\n#endif\n#if DEBUGMODE>0\noutParams.thicknessMap=thicknessMap;\n#endif\n#if defined(SS_REFRACTION) && defined(SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS)\n#ifdef SS_USE_GLTF_TEXTURES\nrefractionIntensity*=thicknessMap.r;\n#else\nrefractionIntensity*=thicknessMap.g;\n#endif\n#endif\n#if defined(SS_TRANSLUCENCY) && defined(SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS)\n#ifdef SS_USE_GLTF_TEXTURES\ntranslucencyIntensity*=thicknessMap.a;\n#else\ntranslucencyIntensity*=thicknessMap.b;\n#endif\n#endif\n#else\nvar thickness: f32=vThicknessParam.y;\n#endif\n#if defined(SS_REFRACTION) && defined(SS_REFRACTIONINTENSITY_TEXTURE)\n#ifdef SS_USE_GLTF_TEXTURES\nrefractionIntensity*=refractionIntensityMap.r;\n#else\nrefractionIntensity*=refractionIntensityMap.g;\n#endif\n#endif\n#if defined(SS_TRANSLUCENCY) && defined(SS_TRANSLUCENCYINTENSITY_TEXTURE)\n#ifdef SS_USE_GLTF_TEXTURES\ntranslucencyIntensity*=translucencyIntensityMap.a;\n#else\ntranslucencyIntensity*=translucencyIntensityMap.b;\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\nthickness=maxEps(thickness);var translucencyColor: vec4f=vTranslucencyColor;\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\ntranslucencyColor*=translucencyColorMap;\n#endif\nvar transmittance: vec3f=transmittanceBRDF_Burley(translucencyColor.rgb,vDiffusionDistance,thickness);transmittance*=translucencyIntensity;outParams.transmittance=transmittance;outParams.translucencyIntensity=translucencyIntensity;\n#endif\n#ifdef SS_REFRACTION\nvar environmentRefraction: vec4f= vec4f(0.,0.,0.,0.);\n#ifdef SS_HAS_THICKNESS\nvar ior: f32=vRefractionInfos.y;\n#else\nvar ior: f32=vRefractionMicrosurfaceInfos.w;\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\nvar refractionAlphaG: f32=alphaG;refractionAlphaG=mix(alphaG,0.0,clamp(ior*3.0-2.0,0.0,1.0));var refractionLOD: f32=getLodFromAlphaGNdotV(vRefractionMicrosurfaceInfos.x,refractionAlphaG,NdotVUnclamped);\n#elif defined(SS_LINEARSPECULARREFRACTION)\nvar refractionRoughness: f32=alphaG;refractionRoughness=mix(alphaG,0.0,clamp(ior*3.0-2.0,0.0,1.0));var refractionLOD: f32=getLinearLodFromRoughness(vRefractionMicrosurfaceInfos.x,refractionRoughness);\n#else\nvar refractionAlphaG: f32=alphaG;refractionAlphaG=mix(alphaG,0.0,clamp(ior*3.0-2.0,0.0,1.0));var refractionLOD: f32=getLodFromAlphaG(vRefractionMicrosurfaceInfos.x,refractionAlphaG);\n#endif\nvar refraction_ior: f32=vRefractionInfos.y;\n#ifdef SS_DISPERSION\nvar realIOR: f32=1.0/refraction_ior;var iorDispersionSpread: f32=0.04*dispersion*(realIOR-1.0);var iors: vec3f= vec3f(1.0/(realIOR-iorDispersionSpread),refraction_ior,1.0/(realIOR+iorDispersionSpread));for (var i: i32=0; i<3; i++) {refraction_ior=iors[i];\n#endif\nvar envSample: vec4f=sampleEnvironmentRefraction(refraction_ior,thickness,refractionLOD,normalW,vPositionW,viewDirectionW,view,vRefractionInfos,refractionMatrix,vRefractionMicrosurfaceInfos,alphaG\n#ifdef SS_REFRACTIONMAP_3D\n,refractionSampler\n,refractionSamplerSampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler\n,refractionLowSamplerSampler\n,refractionHighSampler\n,refractionHighSamplerSampler\n#endif\n#else\n,refractionSampler\n,refractionSamplerSampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler\n,refractionLowSamplerSampler\n,refractionHighSampler\n,refractionHighSamplerSampler\n#endif\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#ifdef REALTIME_FILTERING\n,vRefractionFilteringInfo\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,refractionPosition\n,refractionSize\n#endif\n);\n#ifdef SS_DISPERSION\nenvironmentRefraction[i]=envSample[i];}\n#else\nenvironmentRefraction=envSample;\n#endif\nenvironmentRefraction=vec4f(environmentRefraction.rgb*vRefractionInfos.x,environmentRefraction.a);\n#endif\n#ifdef SS_REFRACTION\nvar refractionTransmittance: vec3f= vec3f(refractionIntensity);\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvar volumeAlbedo: vec3f=computeColorAtDistanceInMedia(vTintColor.rgb,vTintColor.w);refractionTransmittance*=cocaLambertVec3(volumeAlbedo,thickness);\n#elif defined(SS_LINKREFRACTIONTOTRANSPARENCY)\nvar maxChannel: f32=max(max(surfaceAlbedo.r,surfaceAlbedo.g),surfaceAlbedo.b);var volumeAlbedo: vec3f=saturateVec3(maxChannel*surfaceAlbedo);environmentRefraction=vec4f(environmentRefraction.rgb*volumeAlbedo,environmentRefraction.a);\n#else\nvar volumeAlbedo: vec3f=computeColorAtDistanceInMedia(vTintColor.rgb,vTintColor.w);refractionTransmittance*=cocaLambertVec3(volumeAlbedo,vThicknessParam.y);\n#endif\n#ifdef SS_ALBEDOFORREFRACTIONTINT\nenvironmentRefraction=vec4f(environmentRefraction.rgb*surfaceAlbedo.rgb,environmentRefraction.a);\n#endif\noutParams.surfaceAlbedo=surfaceAlbedo;outParams.refractionOpacity=1.-refractionIntensity;\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\noutParams.surfaceAlbedo*=outParams.refractionOpacity;\n#endif\n#ifdef UNUSED_MULTIPLEBOUNCES\nvar bounceSpecularEnvironmentReflectance: vec3f=(2.0*specularEnvironmentReflectance)/(1.0+specularEnvironmentReflectance);outParams.specularEnvironmentReflectance=mix(bounceSpecularEnvironmentReflectance,specularEnvironmentReflectance,refractionIntensity);\n#endif\n#if DEBUGMODE>0\noutParams.refractionTransmittance=refractionTransmittance;\n#endif\noutParams.finalRefraction=environmentRefraction.rgb*refractionTransmittance*vLightingIntensity.z;outParams.finalRefraction*=vec3f(1.0)-specularEnvironmentReflectance;\n#if DEBUGMODE>0\noutParams.environmentRefraction=environmentRefraction;\n#endif\n#endif\n#if defined(REFLECTION) && defined(SS_TRANSLUCENCY)\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX) || !defined(USESPHERICALFROMREFLECTIONMAP)\nvar irradianceVector: vec3f= (reflectionMatrix* vec4f(normalW,0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;\n#endif\n#ifdef INVERTCUBICMAP\nirradianceVector.y*=-1.0;\n#endif\n#else\nvar irradianceVector: vec3f=irradianceVector_;\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP)\n#if defined(REALTIME_FILTERING)\nvar refractionIrradiance: vec3f=irradiance(reflectionSampler,reflectionSamplerSampler,-irradianceVector,vReflectionFilteringInfo,0.0,surfaceAlbedo,irradianceVector\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n);\n#else\nvar refractionIrradiance: vec3f=computeEnvironmentIrradiance(-irradianceVector);\n#endif\n#elif defined(USEIRRADIANCEMAP)\n#ifdef REFLECTIONMAP_3D\nvar irradianceCoords: vec3f=irradianceVector;\n#else\nvar irradianceCoords: vec2f=irradianceVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nirradianceCoords/=irradianceVector.z;\n#endif\nirradianceCoords.y=1.0-irradianceCoords.y;\n#endif\nvar temp: vec4f=textureSample(irradianceSampler,irradianceSamplerSampler,-irradianceCoords);var refractionIrradiance=temp.rgb;\n#ifdef RGBDREFLECTION\nrefractionIrradiance=fromRGBD(temp).rgb;\n#endif\n#ifdef GAMMAREFLECTION\nrefractionIrradiance=toLinearSpaceVec3(refractionIrradiance);\n#endif\n#else\nvar refractionIrradiance: vec3f= vec3f(0.);\n#endif\nrefractionIrradiance*=transmittance;\n#ifdef SS_ALBEDOFORTRANSLUCENCYTINT\nrefractionIrradiance*=surfaceAlbedo.rgb;\n#endif\noutParams.refractionIrradiance=refractionIrradiance;\n#endif\nreturn outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockSubSurfaceWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockNormalGeometric\";\nconst shader = `var viewDirectionW: vec3f=normalize(scene.vEyePosition.xyz-input.vPositionW);\n#ifdef NORMAL\nvar normalW: vec3f=normalize(input.vNormalW);\n#else\nvar normalW: vec3f=normalize(cross(dpdx(input.vPositionW),dpdy(input.vPositionW)))*scene.vEyePosition.w;\n#endif\nvar geometricNormalW: vec3f=normalW;\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\ngeometricNormalW=select(-geometricNormalW,geometricNormalW,fragmentInputs.frontFacing);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockNormalGeometricWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpFragment\";\nconst shader = `var uvOffset: vec2f= vec2f(0.0,0.0);\n#if defined(BUMP) || defined(PARALLAX) || defined(DETAIL)\n#ifdef NORMALXYSCALE\nvar normalScale: f32=1.0;\n#elif defined(BUMP)\nvar normalScale: f32=uniforms.vBumpInfos.y;\n#else\nvar normalScale: f32=1.0;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nvar TBN: mat3x3f=mat3x3<f32>(input.vTBN0,input.vTBN1,input.vTBN2); \n#elif defined(BUMP)\nvar TBNUV: vec2f=select(-fragmentInputs.vBumpUV,fragmentInputs.vBumpUV,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW*normalScale,input.vPositionW,TBNUV,uniforms.vTangentSpaceParams);\n#else\nvar TBNUV: vec2f=select(-fragmentInputs.vDetailUV,fragmentInputs.vDetailUV,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW*normalScale,input.vPositionW,TBNUV, vec2f(1.,1.));\n#endif\n#elif defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL)\nvar TBN: mat3x3f=mat3x3<f32>(input.vTBN0,input.vTBN1,input.vTBN2); \n#else\nvar TBNUV: vec2f=select( -fragmentInputs.vMainUV1,fragmentInputs.vMainUV1,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW,input.vPositionW,TBNUV, vec2f(1.,1.));\n#endif\n#endif\n#ifdef PARALLAX\nvar invTBN: mat3x3f=transposeMat3(TBN);\n#ifdef PARALLAXOCCLUSION\nuvOffset=parallaxOcclusion(invTBN*-viewDirectionW,invTBN*normalW,fragmentInputs.vBumpUV,uniforms.vBumpInfos.z);\n#else\nuvOffset=parallaxOffset(invTBN*viewDirectionW,uniforms.vBumpInfos.z);\n#endif\n#endif\n#ifdef DETAIL\nvar detailColor: vec4f=textureSample(detailSampler,detailSamplerSampler,fragmentInputs.vDetailUV+uvOffset);var detailNormalRG: vec2f=detailColor.wy*2.0-1.0;var detailNormalB: f32=sqrt(1.-saturate(dot(detailNormalRG,detailNormalRG)));var detailNormal: vec3f= vec3f(detailNormalRG,detailNormalB);\n#endif\n#ifdef BUMP\n#ifdef OBJECTSPACE_NORMALMAP\n#define CUSTOM_FRAGMENT_BUMP_FRAGMENT\nnormalW=normalize(TEXRD(bumpSampler,bumpSamplerSampler,fragmentInputs.vBumpUV).xyz *2.0-1.0);normalW=normalize(mat3x3f(uniforms.normalMatrix[0].xyz,uniforms.normalMatrix[1].xyz,uniforms.normalMatrix[2].xyz)*normalW);\n#elif !defined(DETAIL)\nnormalW=perturbNormal(TBN,TEXRD(bumpSampler,bumpSamplerSampler,fragmentInputs.vBumpUV+uvOffset).xyz,uniforms.vBumpInfos.y);\n#else\nvar bumpNormal: vec3f=TEXRD(bumpSampler,bumpSamplerSampler,fragmentInputs.vBumpUV+uvOffset).xyz*2.0-1.0;\n#if DETAIL_NORMALBLENDMETHOD==0 \ndetailNormal=vec3f(detailNormal.xy*uniforms.vDetailInfos.z,detailNormal.z);var blendedNormal: vec3f=normalize( vec3f(bumpNormal.xy+detailNormal.xy,bumpNormal.z*detailNormal.z));\n#elif DETAIL_NORMALBLENDMETHOD==1 \ndetailNormal=vec3f(detailNormal.xy*uniforms.vDetailInfos.z,detailNormal.z);bumpNormal+= vec3f(0.0,0.0,1.0);detailNormal*= vec3f(-1.0,-1.0,1.0);var blendedNormal: vec3f=bumpNormal*dot(bumpNormal,detailNormal)/bumpNormal.z-detailNormal;\n#endif\nnormalW=perturbNormalBase(TBN,blendedNormal,uniforms.vBumpInfos.y);\n#endif\n#elif defined(DETAIL)\ndetailNormal=vec3f(detailNormal.xy*uniforms.vDetailInfos.z,detailNormal.z);normalW=perturbNormalBase(TBN,detailNormal,uniforms.vDetailInfos.z);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const bumpFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockNormalFinal\";\nconst shader = `#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nvar faceNormal: vec3f=normalize(cross(dpdx(fragmentInputs.vPositionW),dpdy(fragmentInputs.vPositionW)))*scene.vEyePosition.w;\n#if defined(TWOSIDEDLIGHTING)\nfaceNormal=select(-faceNormal,faceNormal,fragmentInputs.frontFacing);\n#endif\nnormalW*=sign(dot(normalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\n#if defined(MIRRORED)\nnormalW=select(normalW,-normalW,fragmentInputs.frontFacing);\n#else\nnormalW=select(-normalW,normalW,fragmentInputs.frontFacing);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockNormalFinalWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"depthPrePass\";\nconst shader = `#ifdef DEPTHPREPASS\n#if !defined(PREPASS) && !defined(ORDER_INDEPENDENT_TRANSPARENCY)\nfragmentOutputs.color= vec4f(0.,0.,0.,1.0);\n#endif\n#ifndef DEPTHPREPASS_SKIP_EARLY_RETURN\nreturn fragmentOutputs;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const depthPrePassWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockLightmapInit\";\nconst shader = `#ifdef LIGHTMAP\nvar lightmapColor: vec4f=TEXRD(lightmapSampler,lightmapSamplerSampler,fragmentInputs.vLightmapUV+uvOffset);\n#ifdef RGBDLIGHTMAP\nlightmapColor=vec4f(fromRGBD(lightmapColor),lightmapColor.a);\n#endif\n#ifdef GAMMALIGHTMAP\nlightmapColor=vec4f(toLinearSpaceVec3(lightmapColor.rgb),lightmapColor.a);\n#endif\nlightmapColor=vec4f(lightmapColor.rgb*uniforms.vLightmapInfos.y,lightmapColor.a);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockLightmapInitWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockGeometryInfo\";\nconst shader = `var NdotVUnclamped: f32=dot(normalW,viewDirectionW);var NdotV: f32=absEps(NdotVUnclamped);var alphaG: f32=convertRoughnessToAverageSlope(roughness);var AARoughnessFactors: vec2f=getAARoughnessFactors(normalW.xyz);\n#ifdef SPECULARAA\nalphaG+=AARoughnessFactors.y;\n#endif\n#if defined(ENVIRONMENTBRDF)\nvar environmentBrdf: vec3f=getBRDFLookup(NdotV,roughness);\n#endif\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\n#ifdef RADIANCEOCCLUSION\n#ifdef AMBIENTINGRAYSCALE\nvar ambientMonochrome: f32=aoOut.ambientOcclusionColor.r;\n#else\nvar ambientMonochrome: f32=getLuminance(aoOut.ambientOcclusionColor);\n#endif\nvar seo: f32=environmentRadianceOcclusion(ambientMonochrome,NdotVUnclamped);\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nvar eho: f32=environmentHorizonOcclusion(-viewDirectionW,normalW,geometricNormalW);\n#endif\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockGeometryInfoWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflectance\";\nconst shader = `#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\nvar baseSpecularEnvironmentReflectance: vec3f=getReflectanceFromBRDFWithEnvLookup(vec3f(reflectanceF0),vec3f(reflectivityOut.reflectanceF90),environmentBrdf);\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nlet metalEnvironmentReflectance: vec3f=vec3f(reflectivityOut.specularWeight)*getF82Specular(NdotV,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90,reflectivityOut.roughness);let dielectricEnvironmentReflectance=getReflectanceFromBRDFWithEnvLookup(reflectivityOut.dielectricColorF0,reflectivityOut.colorReflectanceF90,environmentBrdf);var colorSpecularEnvironmentReflectance: vec3f=mix(dielectricEnvironmentReflectance,metalEnvironmentReflectance,reflectivityOut.metallic);\n#else\nvar colorSpecularEnvironmentReflectance=getReflectanceFromBRDFWithEnvLookup(clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90,environmentBrdf);\n#endif\n#ifdef RADIANCEOCCLUSION\ncolorSpecularEnvironmentReflectance*=seo;\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\ncolorSpecularEnvironmentReflectance*=eho;\n#endif\n#endif\n#endif\n#else\nvar colorSpecularEnvironmentReflectance: vec3f=getReflectanceFromAnalyticalBRDFLookup_Jones(NdotV,clearcoatOut.specularEnvironmentR0,specularEnvironmentR90,sqrt(microSurface));var baseSpecularEnvironmentReflectance: vec3f=getReflectanceFromAnalyticalBRDFLookup_Jones(NdotV,vec3f(reflectanceF0),vec3f(reflectivityOut.reflectanceF90),sqrt(microSurface));\n#endif\n#ifdef CLEARCOAT\ncolorSpecularEnvironmentReflectance*=clearcoatOut.conservationFactor;\n#if defined(CLEARCOAT_TINT)\ncolorSpecularEnvironmentReflectance*=clearcoatOut.absorption;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectanceWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockDirectLighting\";\nconst shader = `var diffuseBase: vec3f=vec3f(0.,0.,0.);\n#ifdef SS_TRANSLUCENCY\nvar diffuseTransmissionBase: vec3f=vec3f(0.,0.,0.);\n#endif\n#ifdef SPECULARTERM\nvar specularBase: vec3f=vec3f(0.,0.,0.);\n#endif\n#ifdef CLEARCOAT\nvar clearCoatBase: vec3f=vec3f(0.,0.,0.);\n#endif\n#ifdef SHEEN\nvar sheenBase: vec3f=vec3f(0.,0.,0.);\n#endif\n#if defined(SPECULARTERM) && defined(LIGHT0)\nvar coloredFresnel: vec3f=vec3f(0.,0.,0.);\n#endif\nvar preInfo: preLightingInfo;var info: lightingInfo;var shadow: f32=1.; \nvar aggShadow: f32=0.;var numLights: f32=0.;\n#if defined(CLEARCOAT) && defined(CLEARCOAT_TINT)\nvar absorption: vec3f=vec3f(0.);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockDirectLightingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockFinalLitComponents\";\nconst shader = `aggShadow=aggShadow/numLights;\n#if defined(ENVIRONMENTBRDF)\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nvar baseSpecularEnergyConservationFactor: vec3f=getEnergyConservationFactor(vec3f(reflectanceF0),environmentBrdf);var coloredEnergyConservationFactor: vec3f=getEnergyConservationFactor(clearcoatOut.specularEnvironmentR0,environmentBrdf);\n#endif\n#endif\n#if defined(SHEEN) && defined(SHEEN_ALBEDOSCALING) && defined(ENVIRONMENTBRDF)\nsurfaceAlbedo=sheenOut.sheenAlbedoScaling*surfaceAlbedo.rgb;\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\n#ifndef METALLICWORKFLOW\n#ifdef SPECULAR_GLOSSINESS_ENERGY_CONSERVATION\nsurfaceAlbedo=vec3f(1.-reflectanceF0)*surfaceAlbedo.rgb;\n#endif\n#endif\n#endif\n#ifdef REFLECTION\nvar finalIrradiance: vec3f=reflectionOut.environmentIrradiance;\n#ifndef LEGACY_SPECULAR_ENERGY_CONSERVATION\n#if defined(METALLICWORKFLOW) || defined(SPECULAR_GLOSSINESS_ENERGY_CONSERVATION)\nvar baseSpecularEnergy: vec3f=vec3f(baseSpecularEnvironmentReflectance);\n#if defined(ENVIRONMENTBRDF)\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nbaseSpecularEnergy*=baseSpecularEnergyConservationFactor;\n#endif\n#endif\nfinalIrradiance*=clamp(vec3f(1.0)-baseSpecularEnergy,vec3f(0.0),vec3f(1.0));\n#endif\n#endif\n#if defined(CLEARCOAT)\nfinalIrradiance*=clearcoatOut.conservationFactor;\n#if defined(CLEARCOAT_TINT)\nfinalIrradiance*=clearcoatOut.absorption;\n#endif\n#endif\n#ifndef SS_APPLY_ALBEDO_AFTER_SUBSURFACE\nfinalIrradiance*=surfaceAlbedo.rgb;\n#endif\n#if defined(SS_REFRACTION) && !defined(LEGACY_SPECULAR_ENERGY_CONSERVATION) \nfinalIrradiance*=subSurfaceOut.refractionOpacity;\n#endif\n#if defined(SS_TRANSLUCENCY)\nfinalIrradiance*=(1.0-subSurfaceOut.translucencyIntensity);finalIrradiance+=subSurfaceOut.refractionIrradiance;\n#endif\n#ifdef SS_APPLY_ALBEDO_AFTER_SUBSURFACE\nfinalIrradiance*=surfaceAlbedo.rgb;\n#endif\nfinalIrradiance*=uniforms.vLightingIntensity.z;finalIrradiance*=aoOut.ambientOcclusionColor;\n#endif\n#ifdef SPECULARTERM\nvar finalSpecular: vec3f=specularBase;finalSpecular=max(finalSpecular,vec3f(0.0));var finalSpecularScaled: vec3f=finalSpecular*uniforms.vLightingIntensity.x*uniforms.vLightingIntensity.w;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalSpecularScaled*=coloredEnergyConservationFactor;\n#endif\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\nfinalSpecularScaled*=sheenOut.sheenAlbedoScaling;\n#endif\n#endif\n#ifdef REFLECTION\nvar finalRadiance: vec3f=reflectionOut.environmentRadiance.rgb;finalRadiance*=colorSpecularEnvironmentReflectance;;var finalRadianceScaled: vec3f=finalRadiance*uniforms.vLightingIntensity.z;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalRadianceScaled*=coloredEnergyConservationFactor;\n#endif\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\nfinalRadianceScaled*=sheenOut.sheenAlbedoScaling;\n#endif\n#endif\n#ifdef SHEEN\nvar finalSheen: vec3f=sheenBase*sheenOut.sheenColor;finalSheen=max(finalSheen,vec3f(0.0));var finalSheenScaled: vec3f=finalSheen*uniforms.vLightingIntensity.x*uniforms.vLightingIntensity.w;\n#if defined(CLEARCOAT) && defined(REFLECTION) && defined(ENVIRONMENTBRDF)\nsheenOut.finalSheenRadianceScaled*=clearcoatOut.conservationFactor;\n#if defined(CLEARCOAT_TINT)\nsheenOut.finalSheenRadianceScaled*=clearcoatOut.absorption;\n#endif\n#endif\n#endif\n#ifdef CLEARCOAT\nvar finalClearCoat: vec3f=clearCoatBase;finalClearCoat=max(finalClearCoat,vec3f(0.0));var finalClearCoatScaled: vec3f=finalClearCoat*uniforms.vLightingIntensity.x*uniforms.vLightingIntensity.w;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalClearCoatScaled*=clearcoatOut.energyConservationFactorClearCoat;\n#endif\n#ifdef SS_REFRACTION\nsubSurfaceOut.finalRefraction*=clearcoatOut.conservationFactor;\n#ifdef CLEARCOAT_TINT\nsubSurfaceOut.finalRefraction*=clearcoatOut.absorption;\n#endif\n#endif\n#endif\n#ifdef ALPHABLEND\nvar luminanceOverAlpha: f32=0.0;\n#if defined(REFLECTION) && defined(RADIANCEOVERALPHA)\nluminanceOverAlpha+=getLuminance(finalRadianceScaled);\n#if defined(CLEARCOAT)\nluminanceOverAlpha+=getLuminance(clearcoatOut.finalClearCoatRadianceScaled);\n#endif\n#endif\n#if defined(SPECULARTERM) && defined(SPECULAROVERALPHA)\nluminanceOverAlpha+=getLuminance(finalSpecularScaled);\n#endif\n#if defined(CLEARCOAT) && defined(CLEARCOATOVERALPHA)\nluminanceOverAlpha+=getLuminance(finalClearCoatScaled);\n#endif\n#if defined(RADIANCEOVERALPHA) || defined(SPECULAROVERALPHA) || defined(CLEARCOATOVERALPHA)\nalpha=saturate(alpha+luminanceOverAlpha*luminanceOverAlpha);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockFinalLitComponentsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockFinalUnlitComponents\";\nconst shader = `var finalDiffuse: vec3f=diffuseBase;finalDiffuse*=surfaceAlbedo;\n#if defined(SS_REFRACTION) && !defined(UNLIT) && !defined(LEGACY_SPECULAR_ENERGY_CONSERVATION)\nfinalDiffuse*=subSurfaceOut.refractionOpacity;\n#endif\n#if defined(SS_TRANSLUCENCY) && !defined(UNLIT)\nfinalDiffuse+=diffuseTransmissionBase;\n#endif\nfinalDiffuse=max(finalDiffuse,vec3f(0.0));finalDiffuse*=uniforms.vLightingIntensity.x;var finalAmbient: vec3f=uniforms.vAmbientColor;finalAmbient=finalAmbient*surfaceAlbedo.rgb;var finalEmissive: vec3f=uniforms.vEmissiveColor;\n#ifdef EMISSIVE\nvar emissiveColorTex: vec3f=TEXRD(emissiveSampler,emissiveSamplerSampler,fragmentInputs.vEmissiveUV+uvOffset).rgb;\n#ifdef GAMMAEMISSIVE\nfinalEmissive*=toLinearSpaceVec3(emissiveColorTex.rgb);\n#else\nfinalEmissive*=emissiveColorTex.rgb;\n#endif\nfinalEmissive*= uniforms.vEmissiveInfos.y;\n#endif\nfinalEmissive*=uniforms.vLightingIntensity.y;\n#ifdef AMBIENT\nvar ambientOcclusionForDirectDiffuse: vec3f=mix( vec3f(1.),aoOut.ambientOcclusionColor,uniforms.vAmbientInfos.w);\n#else\nvar ambientOcclusionForDirectDiffuse: vec3f=aoOut.ambientOcclusionColor;\n#endif\nfinalAmbient*=aoOut.ambientOcclusionColor;finalDiffuse*=ambientOcclusionForDirectDiffuse;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockFinalUnlitComponentsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockFinalColorComposition\";\nconst shader = `var finalColor: vec4f= vec4f(\n#ifndef UNLIT\n#ifdef REFLECTION\nfinalIrradiance +\n#endif\n#ifdef SPECULARTERM\nfinalSpecularScaled +\n#endif\n#ifdef SHEEN\nfinalSheenScaled +\n#endif\n#ifdef CLEARCOAT\nfinalClearCoatScaled +\n#endif\n#ifdef REFLECTION\nfinalRadianceScaled +\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF)\nsheenOut.finalSheenRadianceScaled +\n#endif\n#ifdef CLEARCOAT\nclearcoatOut.finalClearCoatRadianceScaled +\n#endif\n#endif\n#ifdef SS_REFRACTION\nsubSurfaceOut.finalRefraction +\n#endif\n#endif\nfinalAmbient +\nfinalDiffuse,\nalpha);\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\nfinalColor=vec4f(finalColor.rgb*lightmapColor.rgb,finalColor.a);\n#else\nfinalColor=vec4f(finalColor.rgb+lightmapColor.rgb,finalColor.a);\n#endif\n#endif\n#endif\nfinalColor=vec4f(finalColor.rgb+finalEmissive,finalColor.a);\n#define CUSTOM_FRAGMENT_BEFORE_FOG\nfinalColor=max(finalColor,vec4f(0.0));\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockFinalColorCompositionWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockImageProcessing\";\nconst shader = `#if defined(IMAGEPROCESSINGPOSTPROCESS) || defined(SS_SCATTERING)\n#if !defined(SKIPFINALCOLORCLAMP)\nfinalColor=vec4f(clamp(finalColor.rgb,vec3f(0.),vec3f(30.0)),finalColor.a);\n#endif\n#else\nfinalColor=applyImageProcessing(finalColor);\n#endif\nfinalColor=vec4f(finalColor.rgb,finalColor.a*mesh.visibility);\n#ifdef PREMULTIPLYALPHA\nfinalColor=vec4f(finalColor.rgb*finalColor.a,finalColor.a);;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockImageProcessingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"meshBlendTagFragmentOutput\";\nconst shader = `#if SCENE_MRT_COUNT>{X}\n#if defined(PREPASS_MESH_BLEND_TAG) && PREPASS_MESH_BLEND_TAG_INDEX=={X}\nfragmentOutputs.fragData{X}=meshBlendTagOutput;\n#else\nfragmentOutputs.fragData{X}=fragData[{X}];\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const meshBlendTagFragmentOutputWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./meshBlendTagFragmentOutput\";\nconst name = \"pbrBlockPrePass\";\nconst shader = `#if SCENE_MRT_COUNT>0\n#ifdef ALPHATEST\nvar writeGeometryInfo: f32=1.0;\n#else\nvar writeGeometryInfo: f32=select(0.0,1.0,finalColor.a>ALPHATESTVALUE);\n#endif\nvar fragData: array<vec4<f32>,SCENE_MRT_COUNT>;\n#ifdef PREPASS_MESH_BLEND_TAG\nvar meshBlendTagOutput: vec4<u32>=vec4u(0u);if (writeGeometryInfo>0.0) {meshBlendTagOutput=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);}\n#endif\n#ifdef PREPASS_POSITION\nfragData[PREPASS_POSITION_INDEX]= vec4f(fragmentInputs.vPositionW,writeGeometryInfo);\n#endif\n#ifdef PREPASS_OBJECT_ID\nfragData[PREPASS_OBJECT_ID_INDEX]=encodeObjectId(uniforms.objectId)*writeGeometryInfo;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nfragData[PREPASS_LOCAL_POSITION_INDEX]=vec4f(fragmentInputs.vPosition,writeGeometryInfo);\n#endif\n#ifdef PREPASS_VELOCITY\nvar a: vec2f=(fragmentInputs.vCurrentPosition.xy/fragmentInputs.vCurrentPosition.w)*0.5+0.5;var b: vec2f=(fragmentInputs.vPreviousPosition.xy/fragmentInputs.vPreviousPosition.w)*0.5+0.5;var velocity: vec2f=abs(a-b);velocity= vec2f(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;fragData[PREPASS_VELOCITY_INDEX]= vec4f(velocity,0.0,writeGeometryInfo);\n#elif defined(PREPASS_VELOCITY_LINEAR)\nvar velocity : vec2f=vec2f(0.5)*((fragmentInputs.vPreviousPosition.xy/fragmentInputs.vPreviousPosition.w) -\n(fragmentInputs.vCurrentPosition.xy/fragmentInputs.vCurrentPosition.w));fragData[PREPASS_VELOCITY_LINEAR_INDEX]=vec4f(velocity,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO\nfragData[PREPASS_ALBEDO_INDEX]=vec4f(surfaceAlbedo,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nvar sqAlbedo : vec3f=sqrt(surfaceAlbedo); \n#endif\n#ifdef PREPASS_IRRADIANCE_LEGACY\nvar irradiance : vec3f=finalDiffuse;\n#ifndef UNLIT\n#ifdef REFLECTION\nirradiance+=finalIrradiance;\n#endif\n#endif\n#ifdef SS_SCATTERING\n#ifdef PREPASS_COLOR\nfragData[PREPASS_COLOR_INDEX]=vec4f(finalColor.rgb-irradiance,finalColor.a); \n#endif\nirradiance/=sqAlbedo;fragData[PREPASS_IRRADIANCE_LEGACY_INDEX]=vec4f(clamp(irradiance,vec3f(0.),vec3f(1.)),writeGeometryInfo*uniforms.scatteringDiffusionProfile/255.); \n#else\n#ifdef PREPASS_COLOR\nfragData[PREPASS_COLOR_INDEX]=finalColor; \n#endif\nfragData[PREPASS_IRRADIANCE_LEGACY_INDEX]=vec4f(clamp(irradiance,vec3f(0.),vec3f(1.)),writeGeometryInfo); \n#endif\n#else\n#ifdef PREPASS_IRRADIANCE\nvar irradiance : vec3f=finalDiffuse;\n#ifndef UNLIT\n#ifdef REFLECTION\nirradiance+=finalIrradiance;\n#endif\n#endif\nfragData[PREPASS_IRRADIANCE_INDEX]=vec4f(irradiance,writeGeometryInfo);\n#endif\n#ifdef PREPASS_COLOR\nfragData[PREPASS_COLOR_INDEX]=vec4f(finalColor.rgb,finalColor.a);\n#endif\n#endif\n#ifdef PREPASS_DEPTH\nfragData[PREPASS_DEPTH_INDEX]=vec4f(fragmentInputs.vViewPos.z,0.0,0.0,writeGeometryInfo); \n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nfragData[PREPASS_SCREENSPACE_DEPTH_INDEX]=vec4f(fragmentInputs.position.z,0.0,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfragData[PREPASS_NORMALIZED_VIEW_DEPTH_INDEX]=vec4f(fragmentInputs.vNormViewDepth,0.0,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_NORMAL\n#ifdef PREPASS_NORMAL_WORLDSPACE\nfragData[PREPASS_NORMAL_INDEX]=vec4f(normalW,writeGeometryInfo);\n#else\nfragData[PREPASS_NORMAL_INDEX]=vec4f(normalize((scene.view*vec4f(normalW,0.0)).rgb),writeGeometryInfo);\n#endif\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nfragData[PREPASS_WORLD_NORMAL_INDEX]=vec4f(normalW*0.5+0.5,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nfragData[PREPASS_ALBEDO_SQRT_INDEX]=vec4f(sqAlbedo,writeGeometryInfo);\n#endif\n#ifdef PREPASS_REFLECTIVITY\n#ifndef UNLIT\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(specularEnvironmentR0,microSurface)*writeGeometryInfo;\n#else\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(0.0,0.0,0.0,1.0)*writeGeometryInfo;\n#endif\n#endif\n#include<meshBlendTagFragmentOutput>[0..8]\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrBlockPrePassWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"oitFragment\";\nconst shader = `#ifdef ORDER_INDEPENDENT_TRANSPARENCY\nvar fragDepth: f32=fragmentInputs.position.z; \n#ifdef ORDER_INDEPENDENT_TRANSPARENCY_16BITS\nvar halfFloat: u32=pack2x16float( vec2f(fragDepth));var full: vec2f=unpack2x16float(halfFloat);fragDepth=full.x;\n#endif\nvar fragCoord: vec2i=vec2i(fragmentInputs.position.xy);var lastDepth: vec2f=textureLoad(oitDepthSampler,fragCoord,0).rg;var lastFrontColor: vec4f=textureLoad(oitFrontColorSampler,fragCoord,0);fragmentOutputs.depth=vec2f(-MAX_DEPTH);fragmentOutputs.frontColor=lastFrontColor;fragmentOutputs.backColor= vec4f(0.0);\n#ifdef USE_REVERSE_DEPTHBUFFER\nvar furthestDepth: f32=-lastDepth.x;var nearestDepth: f32=lastDepth.y;\n#else\nvar nearestDepth: f32=-lastDepth.x;var furthestDepth: f32=lastDepth.y;\n#endif\nvar alphaMultiplier: f32=1.0-lastFrontColor.a;\n#ifdef USE_REVERSE_DEPTHBUFFER\nif (fragDepth>nearestDepth || fragDepth<furthestDepth) {\n#else\nif (fragDepth<nearestDepth || fragDepth>furthestDepth) {\n#endif\nreturn fragmentOutputs;}\n#ifdef USE_REVERSE_DEPTHBUFFER\nif (fragDepth<nearestDepth && fragDepth>furthestDepth) {\n#else\nif (fragDepth>nearestDepth && fragDepth<furthestDepth) {\n#endif\nfragmentOutputs.depth=vec2f(-fragDepth,fragDepth);return fragmentOutputs;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const oitFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrDebug\";\nconst shader = `#if DEBUGMODE>0\nif (input.vClipSpacePosition.x/input.vClipSpacePosition.w>=uniforms.vDebugMode.x) {var color: vec3f;\n#if DEBUGMODE==1\ncolor=fragmentInputs.vPositionW.rgb;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==2 && defined(NORMAL)\ncolor=fragmentInputs.vNormalW.rgb;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==3 && defined(BUMP) || DEBUGMODE==3 && defined(PARALLAX) || DEBUGMODE==3 && defined(ANISOTROPIC)\ncolor=TBN[0];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==4 && defined(BUMP) || DEBUGMODE==4 && defined(PARALLAX) || DEBUGMODE==4 && defined(ANISOTROPIC)\ncolor=TBN[1];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==5\ncolor=normalW;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==6 && defined(MAINUV1)\ncolor= vec3f(input.vMainUV1,0.0);\n#elif DEBUGMODE==7 && defined(MAINUV2)\ncolor= vec3f(input.vMainUV2,0.0);\n#elif DEBUGMODE==8 && defined(CLEARCOAT) && defined(CLEARCOAT_BUMP)\ncolor=clearcoatOut.TBNClearCoat[0];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==9 && defined(CLEARCOAT) && defined(CLEARCOAT_BUMP)\ncolor=clearcoatOut.TBNClearCoat[1];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==10 && defined(CLEARCOAT)\ncolor=clearcoatOut.clearCoatNormalW;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==11 && defined(ANISOTROPIC)\ncolor=anisotropicOut.anisotropicNormal;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==12 && defined(ANISOTROPIC)\ncolor=anisotropicOut.anisotropicTangent;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==13 && defined(ANISOTROPIC)\ncolor=anisotropicOut.anisotropicBitangent;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==20 && defined(ALBEDO)\ncolor=albedoTexture.rgb;\n#ifndef GAMMAALBEDO\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==21 && defined(AMBIENT)\ncolor=aoOut.ambientOcclusionColorMap.rgb;\n#elif DEBUGMODE==22 && defined(OPACITY)\ncolor=opacityMap.rgb;\n#elif DEBUGMODE==23 && defined(EMISSIVE)\ncolor=emissiveColorTex.rgb;\n#ifndef GAMMAEMISSIVE\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==24 && defined(LIGHTMAP)\ncolor=lightmapColor;\n#ifndef GAMMALIGHTMAP\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==25 && defined(REFLECTIVITY) && defined(METALLICWORKFLOW)\ncolor=reflectivityOut.surfaceMetallicColorMap.rgb;\n#elif DEBUGMODE==26 && defined(REFLECTIVITY) && !defined(METALLICWORKFLOW)\ncolor=reflectivityOut.surfaceReflectivityColorMap.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==27 && defined(CLEARCOAT) && defined(CLEARCOAT_TEXTURE)\ncolor= vec3f(clearcoatOut.clearCoatMapData.rg,0.0);\n#elif DEBUGMODE==28 && defined(CLEARCOAT) && defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\ncolor=clearcoatOut.clearCoatTintMapData.rgb;\n#elif DEBUGMODE==29 && defined(SHEEN) && defined(SHEEN_TEXTURE)\ncolor=sheenOut.sheenMapData.rgb;\n#elif DEBUGMODE==30 && defined(ANISOTROPIC) && defined(ANISOTROPIC_TEXTURE)\ncolor=anisotropicOut.anisotropyMapData.rgb;\n#elif DEBUGMODE==31 && defined(SUBSURFACE) && defined(SS_THICKNESSANDMASK_TEXTURE)\ncolor=subSurfaceOut.thicknessMap.rgb;\n#elif DEBUGMODE==32 && defined(BUMP)\ncolor=textureSample(bumpSampler,bumpSamplerSampler,fragmentInputs.vBumpUV).rgb;\n#elif DEBUGMODE==40 && defined(SS_REFRACTION)\ncolor=subSurfaceOut.environmentRefraction.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==41 && defined(REFLECTION)\ncolor=reflectionOut.environmentRadiance.rgb;\n#ifndef GAMMAREFLECTION\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==42 && defined(CLEARCOAT) && defined(REFLECTION)\ncolor=clearcoatOut.environmentClearCoatRadiance.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==50\ncolor=diffuseBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==51 && defined(SPECULARTERM)\ncolor=specularBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==52 && defined(CLEARCOAT)\ncolor=clearCoatBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==53 && defined(SHEEN)\ncolor=sheenBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==54 && defined(REFLECTION)\ncolor=reflectionOut.environmentIrradiance.rgb;\n#ifndef GAMMAREFLECTION\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==60\ncolor=surfaceAlbedo.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==61\ncolor=clearcoatOut.specularEnvironmentR0;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==62 && defined(METALLICWORKFLOW)\ncolor= vec3f(reflectivityOut.metallic);\n#elif DEBUGMODE==71 && defined(METALLICWORKFLOW)\ncolor=reflectivityOut.metallicF0;\n#elif DEBUGMODE==63\ncolor= vec3f(roughness);\n#elif DEBUGMODE==64\ncolor= vec3f(alphaG);\n#elif DEBUGMODE==65\ncolor= vec3f(NdotV);\n#elif DEBUGMODE==66 && defined(CLEARCOAT) && defined(CLEARCOAT_TINT)\ncolor=clearcoatOut.clearCoatColor;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==67 && defined(CLEARCOAT)\ncolor= vec3f(clearcoatOut.clearCoatRoughness);\n#elif DEBUGMODE==68 && defined(CLEARCOAT)\ncolor= vec3f(clearcoatOut.clearCoatNdotV);\n#elif DEBUGMODE==69 && defined(SUBSURFACE) && defined(SS_TRANSLUCENCY)\ncolor=subSurfaceOut.transmittance;\n#elif DEBUGMODE==70 && defined(SUBSURFACE) && defined(SS_REFRACTION)\ncolor=subSurfaceOut.refractionTransmittance;\n#elif DEBUGMODE==72\ncolor= vec3f(microSurface);\n#elif DEBUGMODE==73\ncolor=uniforms.vAlbedoColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==74 && !defined(METALLICWORKFLOW)\ncolor=uniforms.vReflectivityColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==75\ncolor=uniforms.vEmissiveColor;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==80 && defined(RADIANCEOCCLUSION)\ncolor= vec3f(seo);\n#elif DEBUGMODE==81 && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\ncolor= vec3f(eho);\n#elif DEBUGMODE==82 && defined(MS_BRDF_ENERGY_CONSERVATION)\ncolor= vec3f(energyConservationFactor);\n#elif DEBUGMODE==83 && defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\ncolor=baseSpecularEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==84 && defined(CLEARCOAT) && defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\ncolor=clearcoatOut.clearCoatEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==85 && defined(SHEEN) && defined(REFLECTION)\ncolor=sheenOut.sheenEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==86 && defined(ALPHABLEND)\ncolor= vec3f(luminanceOverAlpha);\n#elif DEBUGMODE==87\ncolor= vec3f(alpha);\n#elif DEBUGMODE==88 && defined(ALBEDO)\ncolor= vec3f(albedoTexture.a);\n#elif DEBUGMODE==89\ncolor=aoOut.ambientOcclusionColor;\n#else\nvar stripeWidth: f32=30.;var stripePos: f32=abs(floor(input.position.x/stripeWidth));var whichColor: f32=((stripePos)%(2.));var color1: vec3f= vec3f(.6,.2,.2);var color2: vec3f= vec3f(.3,.1,.1);color=mix(color1,color2,whichColor);\n#endif\ncolor*=uniforms.vDebugMode.y;\n#ifdef DEBUGMODE_NORMALIZE\ncolor=normalize(color)*0.5+0.5;\n#endif\n#ifdef DEBUGMODE_GAMMA\ncolor=toGammaSpaceVec3(color);\n#endif\nfragmentOutputs.color=vec4f(color,1.0);\n#ifdef PREPASS\n#if SCENE_MRT_COUNT>0 && (!defined(PREPASS_MESH_BLEND_TAG) || PREPASS_MESH_BLEND_TAG_INDEX != 0) && (!defined(PREPASS_OBJECT_ID) || PREPASS_OBJECT_ID_INDEX != 0)\nfragmentOutputs.fragData0=vec4f(toLinearSpaceVec3(color),1.0); \n#endif\n#if SCENE_MRT_COUNT>1 && (!defined(PREPASS_MESH_BLEND_TAG) || PREPASS_MESH_BLEND_TAG_INDEX != 1) && (!defined(PREPASS_OBJECT_ID) || PREPASS_OBJECT_ID_INDEX != 1)\nfragmentOutputs.fragData1=vec4f(0.,0.,0.,0.); \n#endif\n#endif\n#ifdef DEBUGMODE_FORCERETURN\nreturn fragmentOutputs;\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const pbrDebugWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { oitDeclarationWGSL } from \"./ShadersInclude/oitDeclaration\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { pbrUboDeclarationWGSL } from \"./ShadersInclude/pbrUboDeclaration\";\nimport { mainUVVaryingDeclarationWGSL } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { pbrFragmentExtraDeclarationWGSL } from \"./ShadersInclude/pbrFragmentExtraDeclaration\";\nimport { lightUboDeclarationWGSL } from \"./ShadersInclude/lightUboDeclaration\";\nimport { samplerFragmentDeclarationWGSL } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { samplerFragmentAlternateDeclarationWGSL } from \"./ShadersInclude/samplerFragmentAlternateDeclaration\";\nimport { pbrFragmentReflectionDeclarationWGSL } from \"./ShadersInclude/pbrFragmentReflectionDeclaration\";\nimport { pbrFragmentSamplersDeclarationWGSL } from \"./ShadersInclude/pbrFragmentSamplersDeclaration\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { textureRepetitionFunctionsWGSL } from \"./ShadersInclude/textureRepetitionFunctions\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { subSurfaceScatteringFunctionsWGSL } from \"./ShadersInclude/subSurfaceScatteringFunctions\";\nimport { importanceSamplingWGSL } from \"./ShadersInclude/importanceSampling\";\nimport { pbrHelperFunctionsWGSL } from \"./ShadersInclude/pbrHelperFunctions\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { shadowsFragmentFunctionsWGSL } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { harmonicsFunctionsWGSL } from \"./ShadersInclude/harmonicsFunctions\";\nimport { ltcHelperFunctionsWGSL } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { pbrDirectLightingSetupFunctionsWGSL } from \"./ShadersInclude/pbrDirectLightingSetupFunctions\";\nimport { pbrDirectLightingFalloffFunctionsWGSL } from \"./ShadersInclude/pbrDirectLightingFalloffFunctions\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctionsWGSL } from \"./ShadersInclude/hdrFilteringFunctions\";\nimport { clusteredLightingFunctionsWGSL } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { pbrBlockReflectance0WGSL } from \"./ShadersInclude/pbrBlockReflectance0\";\nimport { pbrClusteredLightingFunctionsWGSL } from \"./ShadersInclude/pbrClusteredLightingFunctions\";\nimport { pbrDirectLightingFunctionsWGSL } from \"./ShadersInclude/pbrDirectLightingFunctions\";\nimport { pbrIBLFunctionsWGSL } from \"./ShadersInclude/pbrIBLFunctions\";\nimport { bumpFragmentMainFunctionsWGSL } from \"./ShadersInclude/bumpFragmentMainFunctions\";\nimport { bumpFragmentFunctionsWGSL } from \"./ShadersInclude/bumpFragmentFunctions\";\nimport { reflectionFunctionWGSL } from \"./ShadersInclude/reflectionFunction\";\nimport { decalFragmentWGSL } from \"./ShadersInclude/decalFragment\";\nimport { pbrBlockAlbedoOpacityWGSL } from \"./ShadersInclude/pbrBlockAlbedoOpacity\";\nimport { pbrBlockReflectivityWGSL } from \"./ShadersInclude/pbrBlockReflectivity\";\nimport { pbrBlockAmbientOcclusionWGSL } from \"./ShadersInclude/pbrBlockAmbientOcclusion\";\nimport { pbrBlockAlphaFresnelWGSL } from \"./ShadersInclude/pbrBlockAlphaFresnel\";\nimport { pbrBlockAnisotropicWGSL } from \"./ShadersInclude/pbrBlockAnisotropic\";\nimport { pbrBlockReflectionWGSL } from \"./ShadersInclude/pbrBlockReflection\";\nimport { pbrBlockSheenWGSL } from \"./ShadersInclude/pbrBlockSheen\";\nimport { pbrBlockClearcoatWGSL } from \"./ShadersInclude/pbrBlockClearcoat\";\nimport { pbrBlockIridescenceWGSL } from \"./ShadersInclude/pbrBlockIridescence\";\nimport { pbrBlockSubSurfaceWGSL } from \"./ShadersInclude/pbrBlockSubSurface\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { pbrBlockNormalGeometricWGSL } from \"./ShadersInclude/pbrBlockNormalGeometric\";\nimport { bumpFragmentWGSL } from \"./ShadersInclude/bumpFragment\";\nimport { pbrBlockNormalFinalWGSL } from \"./ShadersInclude/pbrBlockNormalFinal\";\nimport { depthPrePassWGSL } from \"./ShadersInclude/depthPrePass\";\nimport { pbrBlockLightmapInitWGSL } from \"./ShadersInclude/pbrBlockLightmapInit\";\nimport { pbrBlockGeometryInfoWGSL } from \"./ShadersInclude/pbrBlockGeometryInfo\";\nimport { pbrBlockReflectanceWGSL } from \"./ShadersInclude/pbrBlockReflectance\";\nimport { pbrBlockDirectLightingWGSL } from \"./ShadersInclude/pbrBlockDirectLighting\";\nimport { lightFragmentWGSL } from \"./ShadersInclude/lightFragment\";\nimport { pbrBlockFinalLitComponentsWGSL } from \"./ShadersInclude/pbrBlockFinalLitComponents\";\nimport { pbrBlockFinalUnlitComponentsWGSL } from \"./ShadersInclude/pbrBlockFinalUnlitComponents\";\nimport { pbrBlockFinalColorCompositionWGSL } from \"./ShadersInclude/pbrBlockFinalColorComposition\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { pbrBlockImageProcessingWGSL } from \"./ShadersInclude/pbrBlockImageProcessing\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { pbrBlockPrePassWGSL } from \"./ShadersInclude/pbrBlockPrePass\";\nimport { oitFragmentWGSL } from \"./ShadersInclude/oitFragment\";\nimport { pbrDebugWGSL } from \"./ShadersInclude/pbrDebug\";\n\nconst name = \"pbrPixelShader\";\nconst shader = `#define PBR_FRAGMENT_SHADER\n#define CUSTOM_FRAGMENT_BEGIN\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<oitDeclaration>\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE\n#endif\n#include<pbrUboDeclaration>\n#include<pbrFragmentExtraDeclaration>\n#include<lightUboDeclaration>[0..maxSimultaneousLights]\n#include<pbrFragmentSamplersDeclaration>\n#include<imageProcessingDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#include<textureRepetitionFunctions>\n#include<helperFunctions>\n#include<subSurfaceScatteringFunctions>\n#include<importanceSampling>\n#include<pbrHelperFunctions>\n#include<imageProcessingFunctions>\n#include<shadowsFragmentFunctions>\n#include<harmonicsFunctions>\n#include<pbrDirectLightingSetupFunctions>\n#include<pbrDirectLightingFalloffFunctions>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\n#include<pbrDirectLightingFunctions>\n#include<pbrIBLFunctions>\n#include<bumpFragmentMainFunctions>\n#include<bumpFragmentFunctions>\n#ifdef REFLECTION\n#include<reflectionFunction>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#include<pbrBlockAlbedoOpacity>\n#include<pbrBlockReflectivity>\n#include<pbrBlockAmbientOcclusion>\n#include<pbrBlockAlphaFresnel>\n#include<pbrBlockAnisotropic>\n#include<pbrBlockReflection>\n#include<pbrBlockSheen>\n#include<pbrBlockClearcoat>\n#include<pbrBlockIridescence>\n#include<pbrBlockSubSurface>\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#include<pbrBlockNormalGeometric>\n#include<bumpFragment>\n#include<pbrBlockNormalFinal>\nvar albedoOpacityOut: albedoOpacityOutParams;\n#ifdef ALBEDO\nvar albedoTexture: vec4f=TEXRD(albedoSampler,albedoSamplerSampler,fragmentInputs.vAlbedoUV+uvOffset);\n#endif\n#ifdef BASE_WEIGHT\nvar baseWeightTexture: vec4f=TEXRD(baseWeightSampler,baseWeightSamplerSampler,fragmentInputs.vBaseWeightUV+uvOffset);\n#endif\n#ifdef OPACITY\nvar opacityMap: vec4f=TEXRD(opacitySampler,opacitySamplerSampler,fragmentInputs.vOpacityUV+uvOffset);\n#endif\n#ifdef DECAL\nvar decalColor: vec4f=textureSample(decalSampler,decalSamplerSampler,fragmentInputs.vDecalUV+uvOffset);\n#endif\nalbedoOpacityOut=albedoOpacityBlock(\nuniforms.vAlbedoColor\n#ifdef ALBEDO\n,albedoTexture\n,uniforms.vAlbedoInfos\n#endif\n,uniforms.baseWeight\n#ifdef BASE_WEIGHT\n,baseWeightTexture\n,uniforms.vBaseWeightInfos\n#endif\n#ifdef OPACITY\n,opacityMap\n,uniforms.vOpacityInfos\n#endif\n#ifdef DETAIL\n,detailColor\n,uniforms.vDetailInfos\n#endif\n#ifdef DECAL\n,decalColor\n,uniforms.vDecalInfos\n#endif\n);var surfaceAlbedo: vec3f=albedoOpacityOut.surfaceAlbedo;var alpha: f32=albedoOpacityOut.alpha;\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\n#define DEPTHPREPASS_SKIP_EARLY_RETURN\n#include<depthPrePass>\n#ifndef DEPTHPREPASS\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\nvar aoOut: ambientOcclusionOutParams;\n#ifdef AMBIENT\nvar ambientOcclusionColorMap: vec3f=TEXRD(ambientSampler,ambientSamplerSampler,fragmentInputs.vAmbientUV+uvOffset).rgb;\n#endif\naoOut=ambientOcclusionBlock(\n#ifdef AMBIENT\nambientOcclusionColorMap,\nuniforms.vAmbientInfos\n#endif\n);\n#include<pbrBlockLightmapInit>\n#ifdef UNLIT\nvar diffuseBase: vec3f= vec3f(1.,1.,1.);\n#else\nvar baseColor: vec3f=surfaceAlbedo;var reflectivityOut: reflectivityOutParams;\n#if defined(REFLECTIVITY)\nvar surfaceMetallicOrReflectivityColorMap: vec4f=TEXRD(reflectivitySampler,reflectivitySamplerSampler,fragmentInputs.vReflectivityUV+uvOffset);var baseReflectivity: vec4f=surfaceMetallicOrReflectivityColorMap;\n#ifndef METALLICWORKFLOW\n#ifdef REFLECTIVITY_GAMMA\nsurfaceMetallicOrReflectivityColorMap=toLinearSpaceVec4(surfaceMetallicOrReflectivityColorMap);\n#endif\nsurfaceMetallicOrReflectivityColorMap=vec4f(surfaceMetallicOrReflectivityColorMap.rgb*uniforms.vReflectivityInfos.y,surfaceMetallicOrReflectivityColorMap.a);\n#endif\n#endif\n#if defined(MICROSURFACEMAP)\nvar microSurfaceTexel: vec4f=TEXRD(microSurfaceSampler,microSurfaceSamplerSampler,fragmentInputs.vMicroSurfaceSamplerUV+uvOffset)*uniforms.vMicroSurfaceSamplerInfos.y;\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nvar baseDiffuseRoughnessTexture: f32=TEXRD(baseDiffuseRoughnessSampler,baseDiffuseRoughnessSamplerSampler,fragmentInputs.vBaseDiffuseRoughnessUV+uvOffset).x;\n#endif\n#ifdef METALLICWORKFLOW\nvar metallicReflectanceFactors: vec4f=uniforms.vMetallicReflectanceFactors;\n#ifdef REFLECTANCE\nvar reflectanceFactorsMap: vec4f=TEXRD(reflectanceSampler,reflectanceSamplerSampler,fragmentInputs.vReflectanceUV+uvOffset);\n#ifdef REFLECTANCE_GAMMA\nreflectanceFactorsMap=toLinearSpaceVec4(reflectanceFactorsMap);\n#endif\nmetallicReflectanceFactors=vec4f(metallicReflectanceFactors.rgb*reflectanceFactorsMap.rgb,metallicReflectanceFactors.a);\n#endif\n#ifdef METALLIC_REFLECTANCE\nvar metallicReflectanceFactorsMap: vec4f=TEXRD(metallicReflectanceSampler,metallicReflectanceSamplerSampler,fragmentInputs.vMetallicReflectanceUV+uvOffset);\n#ifdef METALLIC_REFLECTANCE_GAMMA\nmetallicReflectanceFactorsMap=toLinearSpaceVec4(metallicReflectanceFactorsMap);\n#endif\n#ifndef METALLIC_REFLECTANCE_USE_ALPHA_ONLY\nmetallicReflectanceFactors=vec4f(metallicReflectanceFactors.rgb*metallicReflectanceFactorsMap.rgb,metallicReflectanceFactors.a);\n#endif\nmetallicReflectanceFactors.a*=metallicReflectanceFactorsMap.a;\n#endif\n#endif\nreflectivityOut=reflectivityBlock(\nuniforms.vReflectivityColor\n#ifdef METALLICWORKFLOW\n,surfaceAlbedo\n,metallicReflectanceFactors\n#endif\n,uniforms.baseDiffuseRoughness\n#ifdef BASE_DIFFUSE_ROUGHNESS\n,baseDiffuseRoughnessTexture\n,uniforms.vBaseDiffuseRoughnessInfos\n#endif\n#ifdef REFLECTIVITY\n,uniforms.vReflectivityInfos\n,surfaceMetallicOrReflectivityColorMap\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\n,aoOut.ambientOcclusionColor\n#endif\n#ifdef MICROSURFACEMAP\n,microSurfaceTexel\n#endif\n#ifdef DETAIL\n,detailColor\n,uniforms.vDetailInfos\n#endif\n);var microSurface: f32=reflectivityOut.microSurface;var roughness: f32=reflectivityOut.roughness;var diffuseRoughness: f32=reflectivityOut.diffuseRoughness;\n#ifdef METALLICWORKFLOW\nsurfaceAlbedo=reflectivityOut.surfaceAlbedo;\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\naoOut.ambientOcclusionColor=reflectivityOut.ambientOcclusionColor;\n#endif\n#ifdef ALPHAFRESNEL\n#if defined(ALPHATEST) || defined(ALPHABLEND)\nvar alphaFresnelOut: alphaFresnelOutParams;alphaFresnelOut=alphaFresnelBlock(\nnormalW,\nviewDirectionW,\nalpha,\nmicroSurface\n);alpha=alphaFresnelOut.alpha;\n#endif\n#endif\n#include<pbrBlockGeometryInfo>\n#ifdef ANISOTROPIC\nvar anisotropicOut: anisotropicOutParams;\n#ifdef ANISOTROPIC_TEXTURE\nvar anisotropyMapData: vec3f=TEXRD(anisotropySampler,anisotropySamplerSampler,fragmentInputs.vAnisotropyUV+uvOffset).rgb*uniforms.vAnisotropyInfos.y;\n#endif\nanisotropicOut=anisotropicBlock(\nuniforms.vAnisotropy,\nroughness,\n#ifdef ANISOTROPIC_TEXTURE\nanisotropyMapData,\n#endif\nTBN,\nnormalW,\nviewDirectionW\n);\n#endif\n#ifdef REFLECTION\nvar reflectionOut: reflectionOutParams;\n#ifndef USE_CUSTOM_REFLECTION\nreflectionOut=reflectionBlock(\nfragmentInputs.vPositionW\n,normalW\n,alphaG\n,uniforms.vReflectionMicrosurfaceInfos\n,uniforms.vReflectionInfos\n,uniforms.vReflectionColor\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,NdotVUnclamped\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,roughness\n#endif\n,reflectionSampler\n,reflectionSamplerSampler\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,fragmentInputs.vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,uniforms.reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n,irradianceSamplerSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,uniforms.vReflectionDominantDirection\n#endif\n#endif\n#ifndef LODBASEDMICROSFURACE\n,reflectionLowSampler\n,reflectionLowSamplerSampler\n,reflectionHighSampler\n,reflectionHighSamplerSampler\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n#endif\n,viewDirectionW\n,diffuseRoughness\n,surfaceAlbedo\n);\n#else\n#define CUSTOM_REFLECTION\n#endif\n#endif\n#include<pbrBlockReflectance0>\n#ifdef SHEEN\nvar sheenOut: sheenOutParams;\n#ifdef SHEEN_TEXTURE\nvar sheenMapData: vec4f=TEXRD(sheenSampler,sheenSamplerSampler,fragmentInputs.vSheenUV+uvOffset);\n#endif\n#if defined(SHEEN_ROUGHNESS) && defined(SHEEN_TEXTURE_ROUGHNESS) && !defined(SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE)\nvar sheenMapRoughnessData: vec4f=TEXRD(sheenRoughnessSampler,sheenRoughnessSamplerSampler,fragmentInputs.vSheenRoughnessUV+uvOffset)*uniforms.vSheenInfos.w;\n#endif\nsheenOut=sheenBlock(\nuniforms.vSheenColor\n#ifdef SHEEN_ROUGHNESS\n,uniforms.vSheenRoughness\n#if defined(SHEEN_TEXTURE_ROUGHNESS) && !defined(SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,sheenMapRoughnessData\n#endif\n#endif\n,roughness\n#ifdef SHEEN_TEXTURE\n,sheenMapData\n,uniforms.vSheenInfos.y\n#endif\n,reflectanceF0\n#ifdef SHEEN_LINKWITHALBEDO\n,baseColor\n,surfaceAlbedo\n#endif\n#ifdef ENVIRONMENTBRDF\n,NdotV\n,environmentBrdf\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\n,AARoughnessFactors\n,uniforms.vReflectionMicrosurfaceInfos\n,uniforms.vReflectionInfos\n,uniforms.vReflectionColor\n,uniforms.vLightingIntensity\n,reflectionSampler\n,reflectionSamplerSampler\n,reflectionOut.reflectionCoords\n,NdotVUnclamped\n#ifndef LODBASEDMICROSFURACE\n,reflectionLowSampler\n,reflectionLowSamplerSampler\n,reflectionHighSampler\n,reflectionHighSamplerSampler\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(RADIANCEOCCLUSION)\n,seo\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\n,eho\n#endif\n#endif\n);\n#ifdef SHEEN_LINKWITHALBEDO\nsurfaceAlbedo=sheenOut.surfaceAlbedo;\n#endif\n#endif\n#ifdef CLEARCOAT\n#ifdef CLEARCOAT_TEXTURE\nvar clearCoatMapData: vec2f=TEXRD(clearCoatSampler,clearCoatSamplerSampler,fragmentInputs.vClearCoatUV+uvOffset).rg*uniforms.vClearCoatInfos.y;\n#endif\n#endif\n#ifdef IRIDESCENCE\nvar iridescenceOut: iridescenceOutParams;\n#ifdef IRIDESCENCE_TEXTURE\nvar iridescenceMapData: vec2f=TEXRD(iridescenceSampler,iridescenceSamplerSampler,fragmentInputs.vIridescenceUV+uvOffset).rg*uniforms.vIridescenceInfos.y;\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\nvar iridescenceThicknessMapData: vec2f=TEXRD(iridescenceThicknessSampler,iridescenceThicknessSamplerSampler,fragmentInputs.vIridescenceThicknessUV+uvOffset).rg*uniforms.vIridescenceInfos.w;\n#endif\niridescenceOut=iridescenceBlock(\nuniforms.vIridescenceParams\n,NdotV\n,specularEnvironmentR0\n#ifdef IRIDESCENCE_TEXTURE\n,iridescenceMapData\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\n,iridescenceThicknessMapData\n#endif\n#ifdef CLEARCOAT\n,NdotVUnclamped\n,uniforms.vClearCoatParams\n#ifdef CLEARCOAT_TEXTURE\n,clearCoatMapData\n#endif\n#endif\n);var iridescenceIntensity: f32=iridescenceOut.iridescenceIntensity;specularEnvironmentR0=iridescenceOut.specularEnvironmentR0;\n#endif\nvar clearcoatOut: clearcoatOutParams;\n#ifdef CLEARCOAT\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\nvar clearCoatMapRoughnessData: vec4f=TEXRD(clearCoatRoughnessSampler,clearCoatRoughnessSamplerSampler,fragmentInputs.vClearCoatRoughnessUV+uvOffset)*uniforms.vClearCoatInfos.w;\n#endif\n#if defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\nvar clearCoatTintMapData: vec4f=TEXRD(clearCoatTintSampler,clearCoatTintSamplerSampler,fragmentInputs.vClearCoatTintUV+uvOffset);\n#endif\n#ifdef CLEARCOAT_BUMP\nvar clearCoatBumpMapData: vec4f=TEXRD(clearCoatBumpSampler,clearCoatBumpSamplerSampler,fragmentInputs.vClearCoatBumpUV+uvOffset);\n#endif\nclearcoatOut=clearcoatBlock(\nfragmentInputs.vPositionW\n,geometricNormalW\n,viewDirectionW\n,uniforms.vClearCoatParams\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,clearCoatMapRoughnessData\n#endif\n,specularEnvironmentR0\n#ifdef CLEARCOAT_TEXTURE\n,clearCoatMapData\n#endif\n#ifdef CLEARCOAT_TINT\n,uniforms.vClearCoatTintParams\n,uniforms.clearCoatColorAtDistance\n,uniforms.vClearCoatRefractionParams\n#ifdef CLEARCOAT_TINT_TEXTURE\n,clearCoatTintMapData\n#endif\n#endif\n#ifdef CLEARCOAT_BUMP\n,uniforms.vClearCoatBumpInfos\n,clearCoatBumpMapData\n,fragmentInputs.vClearCoatBumpUV\n#if defined(TANGENT) && defined(NORMAL)\n,mat3x3<f32>(input.vTBN0,input.vTBN1,input.vTBN2)\n#else\n,uniforms.vClearCoatTangentSpaceParams\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n,uniforms.normalMatrix\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\n,faceNormal\n#endif\n#ifdef REFLECTION\n,uniforms.vReflectionMicrosurfaceInfos\n,uniforms.vReflectionInfos\n,uniforms.vReflectionColor\n,uniforms.vLightingIntensity\n,reflectionSampler\n,reflectionSamplerSampler\n#ifndef LODBASEDMICROSFURACE\n,reflectionLowSampler\n,reflectionLowSamplerSampler\n,reflectionHighSampler\n,reflectionHighSamplerSampler\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n#endif\n#if defined(CLEARCOAT_BUMP) || defined(TWOSIDEDLIGHTING)\n,select(-1.,1.,fragmentInputs.frontFacing)\n#endif\n);\n#else\nclearcoatOut.specularEnvironmentR0=specularEnvironmentR0;\n#endif\n#include<pbrBlockReflectance>\nvar subSurfaceOut: subSurfaceOutParams;\n#ifdef SUBSURFACE\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvar thicknessMap: vec4f=TEXRD(thicknessSampler,thicknessSamplerSampler,fragmentInputs.vThicknessUV+uvOffset);\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\nvar refractionIntensityMap: vec4f=TEXRD(refractionIntensitySampler,refractionIntensitySamplerSampler,fragmentInputs.vRefractionIntensityUV+uvOffset);\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\nvar translucencyIntensityMap: vec4f=TEXRD(translucencyIntensitySampler,translucencyIntensitySamplerSampler,fragmentInputs.vTranslucencyIntensityUV+uvOffset);\n#endif\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\nvar translucencyColorMap: vec4f=TEXRD(translucencyColorSampler,translucencyColorSamplerSampler,fragmentInputs.vTranslucencyColorUV+uvOffset);\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE_GAMMA\ntranslucencyColorMap=toLinearSpaceVec4(translucencyColorMap);\n#endif\n#endif\nsubSurfaceOut=subSurfaceBlock(\nuniforms.vSubSurfaceIntensity\n,uniforms.vThicknessParam\n,uniforms.vTintColor\n,normalW\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\n,vec3f(max(colorSpecularEnvironmentReflectance.r,max(colorSpecularEnvironmentReflectance.g,colorSpecularEnvironmentReflectance.b)))\n#else\n,baseSpecularEnvironmentReflectance\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n,thicknessMap\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\n,refractionIntensityMap\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\n,translucencyIntensityMap\n#endif\n#ifdef REFLECTION\n#ifdef SS_TRANSLUCENCY\n,uniforms.reflectionMatrix\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\n,reflectionOut.irradianceVector\n#endif\n#if defined(REALTIME_FILTERING)\n,reflectionSampler\n,reflectionSamplerSampler\n,uniforms.vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n#endif\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n,irradianceSamplerSampler\n#endif\n#endif\n#endif\n#if defined(SS_REFRACTION) || defined(SS_TRANSLUCENCY)\n,surfaceAlbedo\n#endif\n#ifdef SS_REFRACTION\n,fragmentInputs.vPositionW\n,viewDirectionW\n,scene.view\n,uniforms.vRefractionInfos\n,uniforms.refractionMatrix\n,uniforms.vRefractionMicrosurfaceInfos\n,uniforms.vLightingIntensity\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\n,alpha\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\n,NdotVUnclamped\n#endif\n#ifdef SS_LINEARSPECULARREFRACTION\n,roughness\n#endif\n,alphaG\n,refractionSampler\n,refractionSamplerSampler\n#ifndef LODBASEDMICROSFURACE\n,refractionLowSampler\n,refractionLowSamplerSampler\n,refractionHighSampler\n,refractionHighSamplerSampler\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vRefractionFilteringInfo\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,uniforms.vRefractionPosition\n,uniforms.vRefractionSize\n#endif\n#ifdef SS_DISPERSION\n,uniforms.dispersion\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\n,uniforms.vDiffusionDistance\n,uniforms.vTranslucencyColor\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\n,translucencyColorMap\n#endif\n#endif\n);\n#ifdef SS_REFRACTION\nsurfaceAlbedo=subSurfaceOut.surfaceAlbedo;\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nalpha=subSurfaceOut.alpha;\n#endif\n#endif\n#else\nsubSurfaceOut.specularEnvironmentReflectance=colorSpecularEnvironmentReflectance;\n#endif\n#include<pbrBlockDirectLighting>\n#include<lightFragment>[0..maxSimultaneousLights]\n#include<pbrBlockFinalLitComponents>\n#endif \n#include<pbrBlockFinalUnlitComponents>\n#define CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION\n#include<pbrBlockFinalColorComposition>\n#include<logDepthFragment>\n#include<fogFragment>(color,finalColor)\n#include<pbrBlockImageProcessing>\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\n#include<pbrBlockPrePass>\n#endif\n#if !defined(PREPASS) && !defined(ORDER_INDEPENDENT_TRANSPARENCY)\nfragmentOutputs.color=finalColor;\n#endif\n#include<oitFragment>\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {fragmentOutputs.frontColor=vec4f(fragmentOutputs.frontColor.rgb+finalColor.rgb*finalColor.a*alphaMultiplier,1.0-alphaMultiplier*(1.0-finalColor.a));} else {fragmentOutputs.backColor+=finalColor;}\n#endif\n#include<pbrDebug>\n#define CUSTOM_FRAGMENT_MAIN_END\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [objectIdFunctionsWGSL, prePassDeclarationWGSL, oitDeclarationWGSL, sceneUboDeclarationWGSL, meshUboDeclarationWGSL, pbrUboDeclarationWGSL, mainUVVaryingDeclarationWGSL, pbrFragmentExtraDeclarationWGSL, lightUboDeclarationWGSL, samplerFragmentDeclarationWGSL, samplerFragmentAlternateDeclarationWGSL, pbrFragmentReflectionDeclarationWGSL, pbrFragmentSamplersDeclarationWGSL, imageProcessingDeclarationWGSL, clipPlaneFragmentDeclarationWGSL, logDepthDeclarationWGSL, fogFragmentDeclarationWGSL, textureRepetitionFunctionsWGSL, helperFunctionsWGSL, subSurfaceScatteringFunctionsWGSL, importanceSamplingWGSL, pbrHelperFunctionsWGSL, imageProcessingFunctionsWGSL, shadowsFragmentFunctionsWGSL, harmonicsFunctionsWGSL, ltcHelperFunctionsWGSL, pbrDirectLightingSetupFunctionsWGSL, pbrDirectLightingFalloffFunctionsWGSL, pbrBRDFFunctionsWGSL, hdrFilteringFunctionsWGSL, clusteredLightingFunctionsWGSL, pbrBlockReflectance0WGSL, pbrClusteredLightingFunctionsWGSL, pbrDirectLightingFunctionsWGSL, pbrIBLFunctionsWGSL, bumpFragmentMainFunctionsWGSL, bumpFragmentFunctionsWGSL, reflectionFunctionWGSL, decalFragmentWGSL, pbrBlockAlbedoOpacityWGSL, pbrBlockReflectivityWGSL, pbrBlockAmbientOcclusionWGSL, pbrBlockAlphaFresnelWGSL, pbrBlockAnisotropicWGSL, pbrBlockReflectionWGSL, pbrBlockSheenWGSL, pbrBlockClearcoatWGSL, pbrBlockIridescenceWGSL, pbrBlockSubSurfaceWGSL, clipPlaneFragmentWGSL, pbrBlockNormalGeometricWGSL, bumpFragmentWGSL, pbrBlockNormalFinalWGSL, depthPrePassWGSL, pbrBlockLightmapInitWGSL, pbrBlockGeometryInfoWGSL, pbrBlockReflectanceWGSL, pbrBlockDirectLightingWGSL, lightFragmentWGSL, pbrBlockFinalLitComponentsWGSL, pbrBlockFinalUnlitComponentsWGSL, pbrBlockFinalColorCompositionWGSL, logDepthFragmentWGSL, fogFragmentWGSL, pbrBlockImageProcessingWGSL, meshBlendTagFragmentOutputWGSL, pbrBlockPrePassWGSL, oitFragmentWGSL, pbrDebugWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pbrPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"decalVertexDeclaration\";\nconst shader = `#ifdef DECAL\nuniform vec4 vDecalInfos;uniform mat4 decalMatrix;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const decalVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./decalVertexDeclaration\";\nconst name = \"pbrVertexDeclaration\";\nconst shader = `uniform mat4 view;uniform mat4 viewProjection;uniform vec4 vEyePosition;\n#ifdef MULTIVIEW\nmat4 viewProjectionR;\n#endif\n#ifdef ALBEDO\nuniform mat4 albedoMatrix;uniform vec2 vAlbedoInfos;\n#endif\n#ifdef BASE_WEIGHT\nuniform mat4 baseWeightMatrix;uniform vec2 vBaseWeightInfos;\n#endif\nuniform float baseDiffuseRoughness;\n#ifdef BASE_DIFFUSE_ROUGHNESS\nuniform mat4 baseDiffuseRoughnessMatrix;uniform vec2 vBaseDiffuseRoughnessInfos;\n#endif\n#ifdef AMBIENT\nuniform mat4 ambientMatrix;uniform vec4 vAmbientInfos;\n#endif\n#ifdef OPACITY\nuniform mat4 opacityMatrix;uniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;uniform mat4 emissiveMatrix;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;uniform mat4 lightmapMatrix;\n#endif\n#ifdef REFLECTIVITY\nuniform vec3 vReflectivityInfos;uniform mat4 reflectivityMatrix;\n#endif\n#ifdef METALLIC_REFLECTANCE\nuniform vec2 vMetallicReflectanceInfos;uniform mat4 metallicReflectanceMatrix;\n#endif\n#ifdef REFLECTANCE\nuniform vec2 vReflectanceInfos;uniform mat4 reflectanceMatrix;\n#endif\n#ifdef MICROSURFACEMAP\nuniform vec2 vMicroSurfaceSamplerInfos;uniform mat4 microSurfaceSamplerMatrix;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;uniform mat4 bumpMatrix;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\nuniform vec4 cameraInfo;uniform vec4 vTextureRepetitionHexTilingParams;\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;uniform mat4 reflectionMatrix;\n#endif\n#ifdef CLEARCOAT\n#if defined(CLEARCOAT_TEXTURE) || defined(CLEARCOAT_TEXTURE_ROUGHNESS)\nuniform vec4 vClearCoatInfos;\n#endif\n#ifdef CLEARCOAT_TEXTURE\nuniform mat4 clearCoatMatrix;\n#endif\n#ifdef CLEARCOAT_TEXTURE_ROUGHNESS\nuniform mat4 clearCoatRoughnessMatrix;\n#endif\n#ifdef CLEARCOAT_BUMP\nuniform vec2 vClearCoatBumpInfos;uniform mat4 clearCoatBumpMatrix;\n#endif\n#ifdef CLEARCOAT_TINT_TEXTURE\nuniform vec2 vClearCoatTintInfos;uniform mat4 clearCoatTintMatrix;\n#endif\n#endif\n#ifdef IRIDESCENCE\n#if defined(IRIDESCENCE_TEXTURE) || defined(IRIDESCENCE_THICKNESS_TEXTURE)\nuniform vec4 vIridescenceInfos;\n#endif\n#ifdef IRIDESCENCE_TEXTURE\nuniform mat4 iridescenceMatrix;\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\nuniform mat4 iridescenceThicknessMatrix;\n#endif\n#endif\n#ifdef ANISOTROPIC\n#ifdef ANISOTROPIC_TEXTURE\nuniform vec2 vAnisotropyInfos;uniform mat4 anisotropyMatrix;\n#endif\n#endif\n#ifdef SHEEN\n#if defined(SHEEN_TEXTURE) || defined(SHEEN_TEXTURE_ROUGHNESS)\nuniform vec4 vSheenInfos;\n#endif\n#ifdef SHEEN_TEXTURE\nuniform mat4 sheenMatrix;\n#endif\n#ifdef SHEEN_TEXTURE_ROUGHNESS\nuniform mat4 sheenRoughnessMatrix;\n#endif\n#endif\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\nuniform vec4 vRefractionInfos;uniform mat4 refractionMatrix;\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nuniform vec2 vThicknessInfos;uniform mat4 thicknessMatrix;\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\nuniform vec2 vRefractionIntensityInfos;uniform mat4 refractionIntensityMatrix;\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\nuniform vec2 vTranslucencyIntensityInfos;uniform mat4 translucencyIntensityMatrix;\n#endif\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\nuniform vec2 vTranslucencyColorInfos;uniform mat4 translucencyColorMatrix;\n#endif\n#endif\n#ifdef NORMAL\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;uniform vec3 vSphericalL1_1;uniform vec3 vSphericalL10;uniform vec3 vSphericalL11;uniform vec3 vSphericalL2_2;uniform vec3 vSphericalL2_1;uniform vec3 vSphericalL20;uniform vec3 vSphericalL21;uniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;uniform vec3 vSphericalY;uniform vec3 vSphericalZ;uniform vec3 vSphericalXX_ZZ;uniform vec3 vSphericalYY_ZZ;uniform vec3 vSphericalZZ;uniform vec3 vSphericalXY;uniform vec3 vSphericalYZ;uniform vec3 vSphericalZX;\n#endif\n#endif\n#endif\n#endif\n#ifdef DETAIL\nuniform vec4 vDetailInfos;uniform mat4 detailMatrix;\n#endif\n#include<decalVertexDeclaration>\n#define ADDITIONAL_VERTEX_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"pbrUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Material {vec2 vAlbedoInfos;vec2 vBaseWeightInfos;vec2 vBaseDiffuseRoughnessInfos;vec4 vAmbientInfos;vec2 vOpacityInfos;vec2 vEmissiveInfos;vec2 vLightmapInfos;vec3 vReflectivityInfos;vec2 vMicroSurfaceSamplerInfos;vec3 vBumpInfos;mat4 albedoMatrix;mat4 baseWeightMatrix;mat4 baseDiffuseRoughnessMatrix;mat4 ambientMatrix;mat4 opacityMatrix;mat4 emissiveMatrix;mat4 lightmapMatrix;mat4 reflectivityMatrix;mat4 microSurfaceSamplerMatrix;mat4 bumpMatrix;vec2 vTangentSpaceParams;vec4 vAlbedoColor;float baseWeight;float baseDiffuseRoughness;vec4 vLightingIntensity;float pointSize;vec4 vReflectivityColor;vec3 vEmissiveColor;vec3 vAmbientColor;vec2 vDebugMode;vec4 vMetallicReflectanceFactors;vec2 vMetallicReflectanceInfos;mat4 metallicReflectanceMatrix;vec2 vReflectanceInfos;mat4 reflectanceMatrix;vec4 cameraInfo;vec4 vTextureRepetitionHexTilingParams;vec2 vReflectionInfos;mat4 reflectionMatrix;vec3 vReflectionMicrosurfaceInfos;vec3 vReflectionPosition;vec3 vReflectionSize;vec2 vReflectionFilteringInfo;vec3 vReflectionDominantDirection;vec3 vReflectionColor;vec3 vSphericalL00;vec3 vSphericalL1_1;vec3 vSphericalL10;vec3 vSphericalL11;vec3 vSphericalL2_2;vec3 vSphericalL2_1;vec3 vSphericalL20;vec3 vSphericalL21;vec3 vSphericalL22;vec3 vSphericalX;vec3 vSphericalY;vec3 vSphericalZ;vec3 vSphericalXX_ZZ;vec3 vSphericalYY_ZZ;vec3 vSphericalZZ;vec3 vSphericalXY;vec3 vSphericalYZ;vec3 vSphericalZX;\n#define ADDITIONAL_UBO_DECLARATION\n};\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"uvAttributeDeclaration\";\nconst shader = `#ifdef UV{X}\nattribute vec2 uv{X};\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const uvAttributeDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"mainUVVaryingDeclaration\";\nconst shader = `#ifdef MAINUV{X}\nvarying vec2 vMainUV{X};\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const mainUVVaryingDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBRDFFunctions\";\nconst shader = `#define FRESNEL_MAXIMUM_ON_ROUGH 0.25\n#define BRDF_DIFFUSE_MODEL_EON 0\n#define BRDF_DIFFUSE_MODEL_BURLEY 1\n#define BRDF_DIFFUSE_MODEL_LAMBERT 2\n#define BRDF_DIFFUSE_MODEL_LEGACY 3\n#define DIELECTRIC_SPECULAR_MODEL_GLTF 0\n#define DIELECTRIC_SPECULAR_MODEL_OPENPBR 1\n#define CONDUCTOR_SPECULAR_MODEL_GLTF 0\n#define CONDUCTOR_SPECULAR_MODEL_OPENPBR 1\n#if !defined(PBR_VERTEX_SHADER) && !defined(OPENPBR_VERTEX_SHADER)\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nvec3 getEnergyConservationFactor(const vec3 specularEnvironmentR0,const vec3 environmentBrdf) {return 1.0+specularEnvironmentR0*(1.0/environmentBrdf.y-1.0);}\n#endif\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\n#define F82_COS_THETA_MAX 0.142857143\n#define F82_ONE_MINUS_CTM_POW5 0.462664366 \n#define F82_ONE_MINUS_CTM_POW6 0.396569457 \n#define F82_B_DENOMINATOR_RECIP 17.6512785 \n#define BRDF_Z_SCALE 16.0\nvec3 getF82Specular(float NdotV,vec3 F0,vec3 edgeTint,float roughness) {vec3 white_minus_F0=vec3(1.0)-F0;vec3 b=(F0+white_minus_F0*F82_ONE_MINUS_CTM_POW5)*(vec3(1.0)-edgeTint)*F82_B_DENOMINATOR_RECIP;float cos_theta=max(roughness,NdotV);float one_minus_cos_theta=1.0-cos_theta;vec3 offset_from_F0=(white_minus_F0-b*cos_theta*one_minus_cos_theta)*pow(one_minus_cos_theta,5.0);return clamp(F0+offset_from_F0,0.0,1.0);}\nvec3 getF82B(vec3 F0,vec3 edgeTint) {return (F0+(vec3(1.0)-F0)*F82_ONE_MINUS_CTM_POW5)*(vec3(1.0)-edgeTint)*F82_B_DENOMINATOR_RECIP;}\nvec3 getF82DirectionalAlbedo(vec3 F0,vec3 F90,vec3 b,vec3 environmentBrdf) {return (F90-F0)*environmentBrdf.x+F0*environmentBrdf.y-b*environmentBrdf.z;}\nvec3 getF82AverageFresnel(vec3 F0,vec3 b) {return F0+(vec3(1.0)-F0)/21.0-b/126.0;}\n#endif\n#ifdef FUZZENVIRONMENTBRDF\nvec3 getFuzzBRDFLookup(float NdotV,float perceptualRoughness) {vec2 UV=vec2(perceptualRoughness,NdotV);vec4 brdfLookup=texture2D(environmentFuzzBrdfSampler,UV);const vec2 RiRange=vec2(0.0,0.75);const vec2 ARange =vec2(0.005,0.88);const vec2 BRange =vec2(-0.18,0.002);brdfLookup.r=mix(ARange.x, ARange.y, brdfLookup.r);brdfLookup.g=mix(BRange.x, BRange.y, brdfLookup.g);brdfLookup.b=mix(RiRange.x,RiRange.y,brdfLookup.b);return brdfLookup.rgb;}\n#endif\n#ifdef ENVIRONMENTBRDF\nvec3 getBRDFLookup(float NdotV,float perceptualRoughness) {vec2 UV=vec2(NdotV,perceptualRoughness);vec4 brdfLookup=texture2D(environmentBrdfSampler,UV);\n#ifdef ENVIRONMENTBRDF_RGBD\nbrdfLookup.rgb=fromRGBD(brdfLookup.rgba);\n#endif\nreturn brdfLookup.rgb;}\nvec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0,const vec3 specularEnvironmentR90,const vec3 environmentBrdf) {\n#ifdef BRDF_V_HEIGHT_CORRELATED\nvec3 reflectance=(specularEnvironmentR90-specularEnvironmentR0)*environmentBrdf.x+specularEnvironmentR0*environmentBrdf.y;\n#else\nvec3 reflectance=specularEnvironmentR0*environmentBrdf.x+specularEnvironmentR90*environmentBrdf.y;\n#endif\nreturn reflectance;}\nvec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0,const vec3 environmentBrdf) {\n#ifdef BRDF_V_HEIGHT_CORRELATED\nvec3 reflectance=mix(environmentBrdf.xxx,environmentBrdf.yyy,specularEnvironmentR0);\n#else\nvec3 reflectance=specularEnvironmentR0*environmentBrdf.x+environmentBrdf.y;\n#endif\nreturn reflectance;}\n#endif\n/* NOT USED\n#if defined(SHEEN) && defined(SHEEN_SOFTER)\nfloat getBRDFLookupCharlieSheen(float NdotV,float perceptualRoughness)\n{float c=1.0-NdotV;float c3=c*c*c;return 0.65584461*c3+1.0/(4.16526551+exp(-7.97291361*perceptualRoughness+6.33516894));}\n#endif\n*/\n#if !defined(ENVIRONMENTBRDF) || defined(REFLECTIONMAP_SKYBOX) || defined(ALPHAFRESNEL)\nvec3 getReflectanceFromAnalyticalBRDFLookup_Jones(float VdotN,vec3 reflectance0,vec3 reflectance90,float smoothness)\n{float weight=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);return reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));}\n#endif\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF)\n/**\n* The sheen BRDF not containing F can be easily stored in the blue channel of the BRDF texture.\n* The blue channel contains DCharlie*VAshikhmin*NdotL as a lokkup table\n*/\nvec3 getSheenReflectanceFromBRDFLookup(const vec3 reflectance0,const vec3 environmentBrdf) {vec3 sheenEnvironmentReflectance=reflectance0*environmentBrdf.b;return sheenEnvironmentReflectance;}\n#endif\nvec3 fresnelSchlickGGX(float VdotH,vec3 reflectance0,vec3 reflectance90)\n{return reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);}\nfloat fresnelSchlickGGX(float VdotH,float reflectance0,float reflectance90)\n{return reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);}\n#ifdef CLEARCOAT\nvec3 getR0RemappedForClearCoat(vec3 f0) {\n#ifdef CLEARCOAT_DEFAULTIOR\n#ifdef MOBILE\nreturn saturate(f0*(f0*0.526868+0.529324)-0.0482256);\n#else\nreturn saturate(f0*(f0*(0.941892-0.263008*f0)+0.346479)-0.0285998);\n#endif\n#else\nvec3 s=sqrt(f0);vec3 t=(vClearCoatRefractionParams.z+vClearCoatRefractionParams.w*s)/(vClearCoatRefractionParams.w+vClearCoatRefractionParams.z*s);return square(t);\n#endif\n}\n#endif\n#ifdef IRIDESCENCE\nconst mat3 XYZ_TO_REC709=mat3(\n3.2404542,-0.9692660, 0.0556434,\n-1.5371385, 1.8760108,-0.2040259,\n-0.4985314, 0.0415560, 1.0572252\n);vec3 getIORTfromAirToSurfaceR0(vec3 f0) {vec3 sqrtF0=sqrt(f0);return (1.+sqrtF0)/(1.-sqrtF0);}\nvec3 getR0fromIORs(vec3 iorT,float iorI) {return square((iorT-vec3(iorI))/(iorT+vec3(iorI)));}\nfloat getR0fromIORs(float iorT,float iorI) {return square((iorT-iorI)/(iorT+iorI));}\nvec3 evalSensitivity(float opd,vec3 shift) {float phase=2.0*PI*opd*1.0e-9;const vec3 val=vec3(5.4856e-13,4.4201e-13,5.2481e-13);const vec3 pos=vec3(1.6810e+06,1.7953e+06,2.2084e+06);const vec3 var=vec3(4.3278e+09,9.3046e+09,6.6121e+09);vec3 xyz=val*sqrt(2.0*PI*var)*cos(pos*phase+shift)*exp(-square(phase)*var);xyz.x+=9.7470e-14*sqrt(2.0*PI*4.5282e+09)*cos(2.2399e+06*phase+shift[0])*exp(-4.5282e+09*square(phase));xyz/=1.0685e-7;vec3 srgb=XYZ_TO_REC709*xyz;return srgb;}\nvec3 evalIridescence(float outsideIOR,float eta2,float cosTheta1,float thinFilmThickness,vec3 baseF0) {vec3 I=vec3(1.0);float iridescenceIOR=mix(outsideIOR,eta2,smoothstep(0.0,0.03,thinFilmThickness));float sinTheta2Sq=square(outsideIOR/iridescenceIOR)*(1.0-square(cosTheta1));float cosTheta2Sq=1.0-sinTheta2Sq;if (cosTheta2Sq<0.0) {return I;}\nfloat cosTheta2=sqrt(cosTheta2Sq);float R0=getR0fromIORs(iridescenceIOR,outsideIOR);float R12=fresnelSchlickGGX(cosTheta1,R0,1.);float R21=R12;float T121=1.0-R12;float phi12=0.0;if (iridescenceIOR<outsideIOR) phi12=PI;float phi21=PI-phi12;vec3 baseIOR=getIORTfromAirToSurfaceR0(clamp(baseF0,0.0,0.9999)); \nvec3 R1=getR0fromIORs(baseIOR,iridescenceIOR);float maxR1=max(R1.r,max(R1.g,R1.b));if (maxR1<1e-6) {return max(vec3(R12),vec3(0.0));}\nvec3 R23=fresnelSchlickGGX(cosTheta2,R1,vec3(1.));vec3 phi23=vec3(0.0);if (baseIOR[0]<iridescenceIOR) phi23[0]=PI;if (baseIOR[1]<iridescenceIOR) phi23[1]=PI;if (baseIOR[2]<iridescenceIOR) phi23[2]=PI;float opd=2.0*iridescenceIOR*thinFilmThickness*cosTheta2;vec3 phi=vec3(phi21)+phi23;vec3 R123=clamp(R12*R23,1e-5,0.9999);vec3 r123=sqrt(R123);vec3 Rs=square(T121)*R23/(vec3(1.0)-R123);vec3 C0=R12+Rs;I=C0;vec3 Cm=Rs-T121;for (int m=1; m<=2; ++m)\n{Cm*=r123;vec3 Sm=2.0*evalSensitivity(float(m)*opd,float(m)*phi);I+=Cm*Sm;}\nreturn max(I,vec3(0.0));}\n#endif\nfloat normalDistributionFunction_TrowbridgeReitzGGX(float NdotH,float alphaG)\n{float a2=square(alphaG);float d=NdotH*NdotH*(a2-1.0)+1.0;return a2/(PI*d*d);}\n#ifdef SHEEN\nfloat normalDistributionFunction_CharlieSheen(float NdotH,float alphaG)\n{float invR=1./alphaG;float cos2h=NdotH*NdotH;float sin2h=1.-cos2h;return (2.+invR)*pow(sin2h,invR*.5)/(2.*PI);}\n#endif\n#ifdef ANISOTROPIC\nfloat normalDistributionFunction_BurleyGGX_Anisotropic(float NdotH,float TdotH,float BdotH,const vec2 alphaTB) {float a2=alphaTB.x*alphaTB.y;vec3 v=vec3(alphaTB.y*TdotH,alphaTB.x *BdotH,a2*NdotH);float v2=dot(v,v);float w2=a2/v2;return a2*w2*w2*RECIPROCAL_PI;}\n#endif\n#ifdef BRDF_V_HEIGHT_CORRELATED\nfloat smithVisibility_GGXCorrelated(float NdotL,float NdotV,float alphaG) {\n#ifdef MOBILE\nfloat GGXV=NdotL*(NdotV*(1.0-alphaG)+alphaG);float GGXL=NdotV*(NdotL*(1.0-alphaG)+alphaG);return 0.5/(GGXV+GGXL);\n#else\nfloat a2=alphaG*alphaG;float GGXV=NdotL*sqrt(NdotV*(NdotV-a2*NdotV)+a2);float GGXL=NdotV*sqrt(NdotL*(NdotL-a2*NdotL)+a2);return 0.5/(GGXV+GGXL);\n#endif\n}\n#else\nfloat smithVisibilityG1_TrowbridgeReitzGGXFast(float dot,float alphaG)\n{\n#ifdef MOBILE\nreturn 1.0/(dot+alphaG+(1.0-alphaG)*dot ));\n#else\nfloat alphaSquared=alphaG*alphaG;return 1.0/(dot+sqrt(alphaSquared+(1.0-alphaSquared)*dot*dot));\n#endif\n}\nfloat smithVisibility_TrowbridgeReitzGGXFast(float NdotL,float NdotV,float alphaG)\n{float visibility=smithVisibilityG1_TrowbridgeReitzGGXFast(NdotL,alphaG)*smithVisibilityG1_TrowbridgeReitzGGXFast(NdotV,alphaG);return visibility;}\n#endif\n#ifdef ANISOTROPIC\nfloat smithVisibility_GGXCorrelated_Anisotropic(float NdotL,float NdotV,float TdotV,float BdotV,float TdotL,float BdotL,const vec2 alphaTB) {float lambdaV=NdotL*length(vec3(alphaTB.x*TdotV,alphaTB.y*BdotV,NdotV));float lambdaL=NdotV*length(vec3(alphaTB.x*TdotL,alphaTB.y*BdotL,NdotL));float v=0.5/(lambdaV+lambdaL);return v;}\n#endif\n#ifdef CLEARCOAT\nfloat visibility_Kelemen(float VdotH) {return 0.25/(VdotH*VdotH); }\n#endif\n#ifdef SHEEN\nfloat visibility_Ashikhmin(float NdotL,float NdotV)\n{return 1./(4.*(NdotL+NdotV-NdotL*NdotV));}\n/* NOT USED\n#ifdef SHEEN_SOFTER\nfloat l(float x,float alphaG)\n{float oneMinusAlphaSq=(1.0-alphaG)*(1.0-alphaG);float a=mix(21.5473,25.3245,oneMinusAlphaSq);float b=mix(3.82987,3.32435,oneMinusAlphaSq);float c=mix(0.19823,0.16801,oneMinusAlphaSq);float d=mix(-1.97760,-1.27393,oneMinusAlphaSq);float e=mix(-4.32054,-4.85967,oneMinusAlphaSq);return a/(1.0+b*pow(x,c))+d*x+e;}\nfloat lambdaSheen(float cosTheta,float alphaG)\n{return abs(cosTheta)<0.5 ? exp(l(cosTheta,alphaG)) : exp(2.0*l(0.5,alphaG)-l(1.0-cosTheta,alphaG));}\nfloat visibility_CharlieSheen(float NdotL,float NdotV,float alphaG)\n{float G=1.0/(1.0+lambdaSheen(NdotV,alphaG)+lambdaSheen(NdotL,alphaG));return G/(4.0*NdotV*NdotL);}\n#endif\n*/\n#endif\nfloat diffuseBRDF_Burley(float NdotL,float NdotV,float VdotH,float roughness) {float diffuseFresnelNV=pow5(saturateEps(1.0-NdotL));float diffuseFresnelNL=pow5(saturateEps(1.0-NdotV));float diffuseFresnel90=0.5+2.0*VdotH*VdotH*roughness;float fresnel =\n(1.0+(diffuseFresnel90-1.0)*diffuseFresnelNL) *\n(1.0+(diffuseFresnel90-1.0)*diffuseFresnelNV);return fresnel/PI;}\nconst float constant1_FON=0.5-2.0/(3.0*PI);const float constant2_FON=2.0/3.0-28.0/(15.0*PI);float E_FON_approx(float mu,float roughness)\n{float sigma=roughness; \nfloat mucomp=1.0-mu;float mucomp2=mucomp*mucomp;const mat2 Gcoeffs=mat2(0.0571085289,-0.332181442,\n0.491881867,0.0714429953);float GoverPi=dot(Gcoeffs*vec2(mucomp,mucomp2),vec2(1.0,mucomp2));return (1.0+sigma*GoverPi)/(1.0+constant1_FON*sigma);}\nvec3 diffuseBRDF_EON(vec3 albedo,float roughness,float NdotL,float NdotV,float LdotV)\n{vec3 rho=albedo;float sigma=roughness; \nfloat mu_i=NdotL; \nfloat mu_o=NdotV; \nfloat s=LdotV-mu_i*mu_o; \nfloat sovertF=s>0.0 ? s/max(mu_i,mu_o) : s; \nfloat AF=1.0/(1.0+constant1_FON*sigma); \nvec3 f_ss=(rho*RECIPROCAL_PI)*AF*(1.0+sigma*sovertF); \nfloat EFo=E_FON_approx(mu_o,sigma); \nfloat EFi=E_FON_approx(mu_i,sigma); \nfloat avgEF=AF*(1.0+constant2_FON*sigma); \nvec3 rho_ms=(rho*rho)*avgEF/(vec3(1.0)-rho*(1.0-avgEF));const float eps=1.0e-7;vec3 f_ms=(rho_ms*RECIPROCAL_PI)*max(eps,1.0-EFo) \n* max(eps,1.0-EFi)\n/ max(eps,1.0-avgEF);return (f_ss+f_ms);}\n#ifdef SS_TRANSLUCENCY\nvec3 transmittanceBRDF_Burley(const vec3 tintColor,const vec3 diffusionDistance,float thickness) {vec3 S=1./maxEps(diffusionDistance);vec3 temp=exp((-0.333333333*thickness)*S);return tintColor.rgb*0.25*(temp*temp*temp+3.0*temp);}\nfloat computeWrappedDiffuseNdotL(float NdotL,float w) {float t=1.0+w;float invt2=1.0/square(t);return saturate((NdotL+w)*invt2);}\n#endif\n#endif \n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBRDFFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"prePassVertexDeclaration\";\nconst shader = `#ifdef PREPASS\n#ifdef PREPASS_LOCAL_POSITION\nvarying vec3 vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vec3 vViewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying float vNormViewDepth;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nuniform mat4 previousViewProjection;varying vec4 vCurrentPosition;varying vec4 vPreviousPosition;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const prePassVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerVertexDeclaration\";\nconst shader = `#if defined(_DEFINENAME_) && _DEFINENAME_DIRECTUV==0\nvarying vec2 v_VARYINGNAME_UV;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const samplerVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"harmonicsFunctions\";\nconst shader = `#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nvec3 computeEnvironmentIrradiance(vec3 normal) {return vSphericalL00\n+ vSphericalL1_1*(normal.y)\n+ vSphericalL10*(normal.z)\n+ vSphericalL11*(normal.x)\n+ vSphericalL2_2*(normal.y*normal.x)\n+ vSphericalL2_1*(normal.y*normal.z)\n+ vSphericalL20*((3.0*normal.z*normal.z)-1.0)\n+ vSphericalL21*(normal.z*normal.x)\n+ vSphericalL22*(normal.x*normal.x-(normal.y*normal.y));}\n#else\nvec3 computeEnvironmentIrradiance(vec3 normal) {float Nx=normal.x;float Ny=normal.y;float Nz=normal.z;vec3 C1=vSphericalZZ.rgb;vec3 Cx=vSphericalX.rgb;vec3 Cy=vSphericalY.rgb;vec3 Cz=vSphericalZ.rgb;vec3 Cxx_zz=vSphericalXX_ZZ.rgb;vec3 Cyy_zz=vSphericalYY_ZZ.rgb;vec3 Cxy=vSphericalXY.rgb;vec3 Cyz=vSphericalYZ.rgb;vec3 Czx=vSphericalZX.rgb;vec3 a1=Cyy_zz*Ny+Cy;vec3 a2=Cyz*Nz+a1;vec3 b1=Czx*Nz+Cx;vec3 b2=Cxy*Ny+b1;vec3 b3=Cxx_zz*Nx+b2;vec3 t1=Cz *Nz+C1;vec3 t2=a2 *Ny+t1;vec3 t3=b3 *Nx+t2;return t3;}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const harmonicsFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpVertexDeclaration\";\nconst shader = `#if defined(BUMP) || defined(PARALLAX) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bumpVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"prePassVertex\";\nconst shader = `#ifdef PREPASS_DEPTH\nvViewPos=(view*worldPos).rgb;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvNormViewDepth=((view*worldPos).z-cameraInfo.x)/(cameraInfo.y-cameraInfo.x);\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvPosition=positionUpdated.xyz;\n#endif\n#if (defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*worldPos;\n#if NUM_BONE_INFLUENCERS>0\nmat4 previousInfluence;previousInfluence=mPreviousBones[int(matricesIndices[0])]*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\npreviousInfluence+=mPreviousBones[int(matricesIndices[1])]*matricesWeights[1];\n#endif \n#if NUM_BONE_INFLUENCERS>2\npreviousInfluence+=mPreviousBones[int(matricesIndices[2])]*matricesWeights[2];\n#endif \n#if NUM_BONE_INFLUENCERS>3\npreviousInfluence+=mPreviousBones[int(matricesIndices[3])]*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[0])]*matricesWeightsExtra[0];\n#endif \n#if NUM_BONE_INFLUENCERS>5\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[1])]*matricesWeightsExtra[1];\n#endif \n#if NUM_BONE_INFLUENCERS>6\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[2])]*matricesWeightsExtra[2];\n#endif \n#if NUM_BONE_INFLUENCERS>7\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[3])]*matricesWeightsExtra[3];\n#endif\nvPreviousPosition=previousViewProjection*finalPreviousWorld*previousInfluence*vec4(positionUpdated,1.0);\n#else\nvPreviousPosition=previousViewProjection*finalPreviousWorld*vec4(positionUpdated,1.0);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const prePassVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"uvVariableDeclaration\";\nconst shader = `#if !defined(UV{X}) && defined(MAINUV{X})\nvec2 uv{X}=vec2(0.,0.);\n#endif\n#ifdef MAINUV{X}\nvMainUV{X}=uv{X};\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const uvVariableDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerVertexImplementation\";\nconst shader = `#if defined(_DEFINENAME_) && _DEFINENAME_DIRECTUV==0\nif (v_INFONAME_==0.)\n{v_VARYINGNAME_UV=vec2(_MATRIXNAME_Matrix*vec4(uvUpdated,1.0,0.0));}\n#ifdef UV2\nelse if (v_INFONAME_==1.)\n{v_VARYINGNAME_UV=vec2(_MATRIXNAME_Matrix*vec4(uv2Updated,1.0,0.0));}\n#endif\n#ifdef UV3\nelse if (v_INFONAME_==2.)\n{v_VARYINGNAME_UV=vec2(_MATRIXNAME_Matrix*vec4(uv3,1.0,0.0));}\n#endif\n#ifdef UV4\nelse if (v_INFONAME_==3.)\n{v_VARYINGNAME_UV=vec2(_MATRIXNAME_Matrix*vec4(uv4,1.0,0.0));}\n#endif\n#ifdef UV5\nelse if (v_INFONAME_==4.)\n{v_VARYINGNAME_UV=vec2(_MATRIXNAME_Matrix*vec4(uv5,1.0,0.0));}\n#endif\n#ifdef UV6\nelse if (v_INFONAME_==5.)\n{v_VARYINGNAME_UV=vec2(_MATRIXNAME_Matrix*vec4(uv6,1.0,0.0));}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const samplerVertexImplementation = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpVertex\";\nconst shader = `#if defined(BUMP) || defined(PARALLAX) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL)\nvec3 tbnNormal=normalize(normalUpdated);vec3 tbnTangent=normalize(tangentUpdated.xyz);vec3 tbnBitangent=cross(tbnNormal,tbnTangent)*tangentUpdated.w;vTBN=mat3(finalWorld)*mat3(tbnTangent,tbnBitangent,tbnNormal);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bumpVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { decalVertexDeclaration } from \"./ShadersInclude/decalVertexDeclaration\";\nimport { pbrVertexDeclaration } from \"./ShadersInclude/pbrVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { pbrUboDeclaration } from \"./ShadersInclude/pbrUboDeclaration\";\nimport { uvAttributeDeclaration } from \"./ShadersInclude/uvAttributeDeclaration\";\nimport { mainUVVaryingDeclaration } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { prePassVertexDeclaration } from \"./ShadersInclude/prePassVertexDeclaration\";\nimport { samplerVertexDeclaration } from \"./ShadersInclude/samplerVertexDeclaration\";\nimport { harmonicsFunctions } from \"./ShadersInclude/harmonicsFunctions\";\nimport { bumpVertexDeclaration } from \"./ShadersInclude/bumpVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxFragmentDeclaration } from \"./ShadersInclude/lightVxFragmentDeclaration\";\nimport { lightVxUboDeclaration } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { prePassVertex } from \"./ShadersInclude/prePassVertex\";\nimport { uvVariableDeclaration } from \"./ShadersInclude/uvVariableDeclaration\";\nimport { samplerVertexImplementation } from \"./ShadersInclude/samplerVertexImplementation\";\nimport { bumpVertex } from \"./ShadersInclude/bumpVertex\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertex } from \"./ShadersInclude/shadowsVertex\";\nimport { vertexColorMixing } from \"./ShadersInclude/vertexColorMixing\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"pbrVertexShader\";\nconst shader = `#define PBR_VERTEX_SHADER\n#define CUSTOM_VERTEX_EXTENSION\nprecision highp float;\n#include<__decl__pbrVertex>\n#define CUSTOM_VERTEX_BEGIN\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#include<uvAttributeDeclaration>[2..7]\n#include<mainUVVaryingDeclaration>[1..7]\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<helperFunctions>\n#include<pbrBRDFFunctions>\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<prePassVertexDeclaration>\n#include<samplerVertexDeclaration>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail)\n#include<samplerVertexDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient)\n#include<samplerVertexDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive)\n#include<samplerVertexDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap)\n#include<samplerVertexDeclaration>(_DEFINENAME_,REFLECTIVITY,_VARYINGNAME_,Reflectivity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,MICROSURFACEMAP,_VARYINGNAME_,MicroSurfaceSampler)\n#include<samplerVertexDeclaration>(_DEFINENAME_,METALLIC_REFLECTANCE,_VARYINGNAME_,MetallicReflectance)\n#include<samplerVertexDeclaration>(_DEFINENAME_,REFLECTANCE,_VARYINGNAME_,Reflectance)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal)\n#ifdef CLEARCOAT\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE,_VARYINGNAME_,ClearCoat)\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE_ROUGHNESS,_VARYINGNAME_,ClearCoatRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_BUMP,_VARYINGNAME_,ClearCoatBump)\n#include<samplerVertexDeclaration>(_DEFINENAME_,CLEARCOAT_TINT_TEXTURE,_VARYINGNAME_,ClearCoatTint)\n#endif\n#ifdef IRIDESCENCE\n#include<samplerVertexDeclaration>(_DEFINENAME_,IRIDESCENCE_TEXTURE,_VARYINGNAME_,Iridescence)\n#include<samplerVertexDeclaration>(_DEFINENAME_,IRIDESCENCE_THICKNESS_TEXTURE,_VARYINGNAME_,IridescenceThickness)\n#endif\n#ifdef SHEEN\n#include<samplerVertexDeclaration>(_DEFINENAME_,SHEEN_TEXTURE,_VARYINGNAME_,Sheen)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SHEEN_TEXTURE_ROUGHNESS,_VARYINGNAME_,SheenRoughness)\n#endif\n#ifdef ANISOTROPIC\n#include<samplerVertexDeclaration>(_DEFINENAME_,ANISOTROPIC_TEXTURE,_VARYINGNAME_,Anisotropy)\n#endif\n#ifdef SUBSURFACE\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor)\n#endif\nvarying vec3 vPositionW;\n#if DEBUGMODE>0\nvarying vec4 vClipSpacePosition;\n#endif\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vec3 vEnvironmentIrradiance;\n#include<harmonicsFunctions>\n#endif\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vec4 vColor;\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightVxFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying float vViewDepth;\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#ifdef NORMAL\nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#ifdef VERTEXCOLOR\nvec4 colorUpdated=color;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvPositionUVW=positionUpdated;\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#if defined(PREPASS) && ((defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);vPreviousPosition=previousViewProjection*finalPreviousWorld*vec4(positionUpdated,1.0);\n#endif\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);vPositionW=vec3(worldPos);\n#ifdef PREPASS\n#include<prePassVertex>\n#endif\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvNormalW=normalUpdated/vec3(dot(normalWorld[0],normalWorld[0]),dot(normalWorld[1],normalWorld[1]),dot(normalWorld[2],normalWorld[2]));vNormalW=normalize(normalWorld*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\nvec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);float NdotV=max(dot(vNormalW,viewDirectionW),0.0);vec3 roughNormal=mix(vNormalW,viewDirectionW,(0.5*(1.0-NdotV))*baseDiffuseRoughness);vec3 reflectionVector=vec3(reflectionMatrix*vec4(roughNormal,0)).xyz;\n#else\nvec3 reflectionVector=vec3(reflectionMatrix*vec4(vNormalW,0)).xyz;\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\nvEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector);\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_WORLDPOS\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {gl_Position=viewProjection*worldPos;} else {gl_Position=viewProjectionR*worldPos;}\n#else\ngl_Position=viewProjection*worldPos;\n#endif\n#if DEBUGMODE>0\nvClipSpacePosition=gl_Position;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#ifdef RIGHT_HANDED\nvViewDepth=-(view*worldPos).z;\n#else\nvViewDepth=(view*worldPos).z;\n#endif\n#endif\n#ifndef UV1\nvec2 uvUpdated=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2Updated=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uvUpdated;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2Updated;\n#endif\n#include<uvVariableDeclaration>[3..7]\n#include<samplerVertexImplementation>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo,_MATRIXNAME_,albedo,_INFONAME_,AlbedoInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_MATRIXNAME_,baseWeight,_INFONAME_,BaseWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_MATRIXNAME_,baseDiffuseRoughness,_INFONAME_,BaseDiffuseRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_MATRIXNAME_,detail,_INFONAME_,DetailInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_MATRIXNAME_,ambient,_INFONAME_,AmbientInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_MATRIXNAME_,opacity,_INFONAME_,OpacityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_MATRIXNAME_,emissive,_INFONAME_,EmissiveInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_MATRIXNAME_,lightmap,_INFONAME_,LightmapInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,REFLECTIVITY,_VARYINGNAME_,Reflectivity,_MATRIXNAME_,reflectivity,_INFONAME_,ReflectivityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,MICROSURFACEMAP,_VARYINGNAME_,MicroSurfaceSampler,_MATRIXNAME_,microSurfaceSampler,_INFONAME_,MicroSurfaceSamplerInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,METALLIC_REFLECTANCE,_VARYINGNAME_,MetallicReflectance,_MATRIXNAME_,metallicReflectance,_INFONAME_,MetallicReflectanceInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,REFLECTANCE,_VARYINGNAME_,Reflectance,_MATRIXNAME_,reflectance,_INFONAME_,ReflectanceInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_MATRIXNAME_,bump,_INFONAME_,BumpInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_MATRIXNAME_,decal,_INFONAME_,DecalInfos.x)\n#ifdef CLEARCOAT\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_TEXTURE,_VARYINGNAME_,ClearCoat,_MATRIXNAME_,clearCoat,_INFONAME_,ClearCoatInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_TEXTURE_ROUGHNESS,_VARYINGNAME_,ClearCoatRoughness,_MATRIXNAME_,clearCoatRoughness,_INFONAME_,ClearCoatInfos.z)\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_BUMP,_VARYINGNAME_,ClearCoatBump,_MATRIXNAME_,clearCoatBump,_INFONAME_,ClearCoatBumpInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,CLEARCOAT_TINT_TEXTURE,_VARYINGNAME_,ClearCoatTint,_MATRIXNAME_,clearCoatTint,_INFONAME_,ClearCoatTintInfos.x)\n#endif\n#ifdef IRIDESCENCE\n#include<samplerVertexImplementation>(_DEFINENAME_,IRIDESCENCE_TEXTURE,_VARYINGNAME_,Iridescence,_MATRIXNAME_,iridescence,_INFONAME_,IridescenceInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,IRIDESCENCE_THICKNESS_TEXTURE,_VARYINGNAME_,IridescenceThickness,_MATRIXNAME_,iridescenceThickness,_INFONAME_,IridescenceInfos.z)\n#endif\n#ifdef SHEEN\n#include<samplerVertexImplementation>(_DEFINENAME_,SHEEN_TEXTURE,_VARYINGNAME_,Sheen,_MATRIXNAME_,sheen,_INFONAME_,SheenInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SHEEN_TEXTURE_ROUGHNESS,_VARYINGNAME_,SheenRoughness,_MATRIXNAME_,sheenRoughness,_INFONAME_,SheenInfos.z)\n#endif\n#ifdef ANISOTROPIC\n#include<samplerVertexImplementation>(_DEFINENAME_,ANISOTROPIC_TEXTURE,_VARYINGNAME_,Anisotropy,_MATRIXNAME_,anisotropy,_INFONAME_,AnisotropyInfos.x)\n#endif\n#ifdef SUBSURFACE\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness,_MATRIXNAME_,thickness,_INFONAME_,ThicknessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity,_MATRIXNAME_,refractionIntensity,_INFONAME_,RefractionIntensityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity,_MATRIXNAME_,translucencyIntensity,_INFONAME_,TranslucencyIntensityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor,_MATRIXNAME_,translucencyColor,_INFONAME_,TranslucencyColorInfos.x)\n#endif\n#include<bumpVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#include<vertexColorMixing>\n#if defined(POINTSIZE) && !defined(WEBGPU)\ngl_PointSize=pointSize;\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [decalVertexDeclaration, pbrVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, pbrUboDeclaration, uvAttributeDeclaration, mainUVVaryingDeclaration, helperFunctions, pbrBRDFFunctions, bonesDeclaration, bakedVertexAnimationDeclaration, instancesDeclaration, prePassVertexDeclaration, samplerVertexDeclaration, harmonicsFunctions, bumpVertexDeclaration, clipPlaneVertexDeclaration, fogVertexDeclaration, lightVxFragmentDeclaration, lightVxUboDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, logDepthDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, prePassVertex, uvVariableDeclaration, samplerVertexImplementation, bumpVertex, clipPlaneVertex, fogVertex, shadowsVertex, vertexColorMixing, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pbrVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"objectIdFunctions\";\nconst shader = `highp vec4 encodeObjectId(highp float objectId) {\n#ifdef PREPASS_OBJECT_ID_R8\nreturn vec4(objectId/255.0,0.0,0.0,1.0);\n#else\nhighp float id=floor(objectId);highp vec3 encodedId=vec3(\nfloor(mod(id,16777216.0)/65536.0),\nfloor(mod(id,65536.0)/256.0),\nmod(id,256.0)\n)/255.0;return vec4(encodedId,step(0.5,id));\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const objectIdFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./objectIdFunctions\";\nconst name = \"prePassDeclaration\";\nconst shader = `#ifdef PREPASS\n#extension GL_EXT_draw_buffers : require\n#ifdef PREPASS_MESH_BLEND_TAG\n#if {X}>0\n#if PREPASS_MESH_BLEND_TAG_INDEX==0\nlayout(location=0) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=0) out highp vec4 glFragData0;\n#endif\n#endif\n#if {X}>1\n#if PREPASS_MESH_BLEND_TAG_INDEX==1\nlayout(location=1) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=1) out highp vec4 glFragData1;\n#endif\n#endif\n#if {X}>2\n#if PREPASS_MESH_BLEND_TAG_INDEX==2\nlayout(location=2) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=2) out highp vec4 glFragData2;\n#endif\n#endif\n#if {X}>3\n#if PREPASS_MESH_BLEND_TAG_INDEX==3\nlayout(location=3) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=3) out highp vec4 glFragData3;\n#endif\n#endif\n#if {X}>4\n#if PREPASS_MESH_BLEND_TAG_INDEX==4\nlayout(location=4) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=4) out highp vec4 glFragData4;\n#endif\n#endif\n#if {X}>5\n#if PREPASS_MESH_BLEND_TAG_INDEX==5\nlayout(location=5) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=5) out highp vec4 glFragData5;\n#endif\n#endif\n#if {X}>6\n#if PREPASS_MESH_BLEND_TAG_INDEX==6\nlayout(location=6) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=6) out highp vec4 glFragData6;\n#endif\n#endif\n#if {X}>7\n#if PREPASS_MESH_BLEND_TAG_INDEX==7\nlayout(location=7) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=7) out highp vec4 glFragData7;\n#endif\n#endif\nvoid writeGeometryFragmentOutput(highp int index,highp vec4 value) {\n#if {X}>0 && PREPASS_MESH_BLEND_TAG_INDEX != 0\nif (index==0) { glFragData0=value; }\n#endif\n#if {X}>1 && PREPASS_MESH_BLEND_TAG_INDEX != 1\nif (index==1) { glFragData1=value; }\n#endif\n#if {X}>2 && PREPASS_MESH_BLEND_TAG_INDEX != 2\nif (index==2) { glFragData2=value; }\n#endif\n#if {X}>3 && PREPASS_MESH_BLEND_TAG_INDEX != 3\nif (index==3) { glFragData3=value; }\n#endif\n#if {X}>4 && PREPASS_MESH_BLEND_TAG_INDEX != 4\nif (index==4) { glFragData4=value; }\n#endif\n#if {X}>5 && PREPASS_MESH_BLEND_TAG_INDEX != 5\nif (index==5) { glFragData5=value; }\n#endif\n#if {X}>6 && PREPASS_MESH_BLEND_TAG_INDEX != 6\nif (index==6) { glFragData6=value; }\n#endif\n#if {X}>7 && PREPASS_MESH_BLEND_TAG_INDEX != 7\nif (index==7) { glFragData7=value; }\n#endif\n}\n#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX,VALUE) writeGeometryFragmentOutput(INDEX,VALUE)\n#else\nlayout(location=0) out highp vec4 glFragData[{X}];\n#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX,VALUE) gl_FragData[INDEX]=VALUE\n#endif\nhighp vec4 gl_FragColor;\n#ifndef PREPASS_CUSTOM_VARYINGS\n#ifdef PREPASS_LOCAL_POSITION\nvarying highp vec3 vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nvarying highp vec3 vViewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying highp float vNormViewDepth;\n#endif\n#if (defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(PREPASS_VELOCITY_ZERO)\nvarying highp vec4 vCurrentPosition;varying highp vec4 vPreviousPosition;\n#endif\n#endif\n#ifdef PREPASS_OBJECT_ID\nuniform highp float objectId;\n#include<objectIdFunctions>\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nuniform highp int meshBlendTag;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const prePassDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"oitDeclaration\";\nconst shader = `#ifdef ORDER_INDEPENDENT_TRANSPARENCY\n#extension GL_EXT_draw_buffers : require\nlayout(location=0) out vec2 depth; \nlayout(location=1) out vec4 frontColor;layout(location=2) out vec4 backColor;\n#define MAX_DEPTH 99999.0\nhighp vec4 gl_FragColor;uniform sampler2D oitDepthSampler;uniform sampler2D oitFrontColorSampler;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const oitDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"decalFragmentDeclaration\";\nconst shader = `#ifdef DECAL\nuniform vec4 vDecalInfos;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const decalFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./decalFragmentDeclaration\";\nconst name = \"pbrFragmentDeclaration\";\nconst shader = `uniform vec4 vEyePosition;uniform vec3 vReflectionColor;uniform vec4 vAlbedoColor;uniform float baseWeight;uniform float baseDiffuseRoughness;uniform vec4 vLightingIntensity;uniform vec4 vReflectivityColor;uniform vec4 vMetallicReflectanceFactors;uniform vec3 vEmissiveColor;uniform float visibility;uniform vec3 vAmbientColor;\n#ifdef ALBEDO\nuniform vec2 vAlbedoInfos;\n#endif\n#ifdef BASE_WEIGHT\nuniform vec2 vBaseWeightInfos;\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nuniform vec2 vBaseDiffuseRoughnessInfos;\n#endif\n#ifdef AMBIENT\nuniform vec4 vAmbientInfos;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;uniform vec2 vTangentSpaceParams;\n#endif\n#ifdef OPACITY\nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\n#endif\n#ifdef REFLECTIVITY\nuniform vec3 vReflectivityInfos;\n#endif\n#ifdef MICROSURFACEMAP\nuniform vec2 vMicroSurfaceSamplerInfos;\n#endif\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(SS_REFRACTION) || defined(PREPASS)\nuniform mat4 view;\n#endif\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\n#ifdef REALTIME_FILTERING\nuniform vec2 vReflectionFilteringInfo;\n#endif\nuniform mat4 reflectionMatrix;uniform vec3 vReflectionMicrosurfaceInfos;\n#if defined(USEIRRADIANCEMAP) && defined(USE_IRRADIANCE_DOMINANT_DIRECTION)\nuniform vec3 vReflectionDominantDirection;\n#endif\n#if defined(USE_LOCAL_REFLECTIONMAP_CUBIC) && defined(REFLECTIONMAP_CUBIC)\nuniform vec3 vReflectionPosition;uniform vec3 vReflectionSize;\n#endif\n#endif\n#if defined(SS_REFRACTION) && defined(SS_USE_LOCAL_REFRACTIONMAP_CUBIC)\nuniform vec3 vRefractionPosition;uniform vec3 vRefractionSize;\n#endif\n#ifdef CLEARCOAT\nuniform vec2 vClearCoatParams;uniform vec4 vClearCoatRefractionParams;\n#if defined(CLEARCOAT_TEXTURE) || defined(CLEARCOAT_TEXTURE_ROUGHNESS)\nuniform vec4 vClearCoatInfos;\n#endif\n#ifdef CLEARCOAT_TEXTURE\nuniform mat4 clearCoatMatrix;\n#endif\n#ifdef CLEARCOAT_TEXTURE_ROUGHNESS\nuniform mat4 clearCoatRoughnessMatrix;\n#endif\n#ifdef CLEARCOAT_BUMP\nuniform vec2 vClearCoatBumpInfos;uniform vec2 vClearCoatTangentSpaceParams;uniform mat4 clearCoatBumpMatrix;\n#endif\n#ifdef CLEARCOAT_TINT\nuniform vec4 vClearCoatTintParams;uniform float clearCoatColorAtDistance;\n#ifdef CLEARCOAT_TINT_TEXTURE\nuniform vec2 vClearCoatTintInfos;uniform mat4 clearCoatTintMatrix;\n#endif\n#endif\n#endif\n#ifdef IRIDESCENCE\nuniform vec4 vIridescenceParams;\n#if defined(IRIDESCENCE_TEXTURE) || defined(IRIDESCENCE_THICKNESS_TEXTURE)\nuniform vec4 vIridescenceInfos;\n#endif\n#ifdef IRIDESCENCE_TEXTURE\nuniform mat4 iridescenceMatrix;\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\nuniform mat4 iridescenceThicknessMatrix;\n#endif\n#endif\n#ifdef ANISOTROPIC\nuniform vec3 vAnisotropy;\n#ifdef ANISOTROPIC_TEXTURE\nuniform vec2 vAnisotropyInfos;uniform mat4 anisotropyMatrix;\n#endif\n#endif\n#ifdef SHEEN\nuniform vec4 vSheenColor;\n#ifdef SHEEN_ROUGHNESS\nuniform float vSheenRoughness;\n#endif\n#if defined(SHEEN_TEXTURE) || defined(SHEEN_TEXTURE_ROUGHNESS)\nuniform vec4 vSheenInfos;\n#endif\n#ifdef SHEEN_TEXTURE\nuniform mat4 sheenMatrix;\n#endif\n#ifdef SHEEN_TEXTURE_ROUGHNESS\nuniform mat4 sheenRoughnessMatrix;\n#endif\n#endif\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\nuniform vec4 vRefractionMicrosurfaceInfos;uniform vec4 vRefractionInfos;uniform mat4 refractionMatrix;\n#ifdef REALTIME_FILTERING\nuniform vec2 vRefractionFilteringInfo;\n#endif\n#ifdef SS_DISPERSION\nuniform float dispersion;\n#endif\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nuniform vec2 vThicknessInfos;uniform mat4 thicknessMatrix;\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\nuniform vec2 vRefractionIntensityInfos;uniform mat4 refractionIntensityMatrix;\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\nuniform vec2 vTranslucencyIntensityInfos;uniform mat4 translucencyIntensityMatrix;\n#endif\nuniform vec2 vThicknessParam;uniform vec3 vDiffusionDistance;uniform vec4 vTintColor;uniform vec3 vSubSurfaceIntensity;uniform vec4 vTranslucencyColor;\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\nuniform vec2 vTranslucencyColorInfos;uniform mat4 translucencyColorMatrix;\n#endif\n#endif\n#ifdef PREPASS\n#ifdef SS_SCATTERING\nuniform float scatteringDiffusionProfile;\n#endif\n#endif\n#if DEBUGMODE>0\nuniform vec2 vDebugMode;\n#endif\n#ifdef DETAIL\nuniform vec4 vDetailInfos;\n#endif\n#include<decalFragmentDeclaration>\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;uniform vec3 vSphericalL1_1;uniform vec3 vSphericalL10;uniform vec3 vSphericalL11;uniform vec3 vSphericalL2_2;uniform vec3 vSphericalL2_1;uniform vec3 vSphericalL20;uniform vec3 vSphericalL21;uniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;uniform vec3 vSphericalY;uniform vec3 vSphericalZ;uniform vec3 vSphericalXX_ZZ;uniform vec3 vSphericalYY_ZZ;uniform vec3 vSphericalZZ;uniform vec3 vSphericalXY;uniform vec3 vSphericalYZ;uniform vec3 vSphericalZX;\n#endif\n#endif\n#if TEXTURE_REPETITION_MODE>0\nuniform vec4 vTextureRepetitionHexTilingParams;\n#endif\n#define ADDITIONAL_FRAGMENT_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./mainUVVaryingDeclaration\";\nconst name = \"pbrFragmentExtraDeclaration\";\nconst shader = `varying vec3 vPositionW;\n#if DEBUGMODE>0\nvarying vec4 vClipSpacePosition;\n#endif\n#include<mainUVVaryingDeclaration>[1..7]\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vec3 vEnvironmentIrradiance;\n#endif\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vec4 vColor;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying float vViewDepth;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentExtraDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerFragmentDeclaration\";\nconst shader = `#ifdef _DEFINENAME_\n#if _DEFINENAME_DIRECTUV==1\n#define v_VARYINGNAME_UV vMainUV1\n#elif _DEFINENAME_DIRECTUV==2\n#define v_VARYINGNAME_UV vMainUV2\n#elif _DEFINENAME_DIRECTUV==3\n#define v_VARYINGNAME_UV vMainUV3\n#elif _DEFINENAME_DIRECTUV==4\n#define v_VARYINGNAME_UV vMainUV4\n#elif _DEFINENAME_DIRECTUV==5\n#define v_VARYINGNAME_UV vMainUV5\n#elif _DEFINENAME_DIRECTUV==6\n#define v_VARYINGNAME_UV vMainUV6\n#else\nvarying vec2 v_VARYINGNAME_UV;\n#endif\nuniform sampler2D _SAMPLERNAME_Sampler;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const samplerFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"samplerFragmentAlternateDeclaration\";\nconst shader = `#ifdef _DEFINENAME_\n#if _DEFINENAME_DIRECTUV==1\n#define v_VARYINGNAME_UV vMainUV1\n#elif _DEFINENAME_DIRECTUV==2\n#define v_VARYINGNAME_UV vMainUV2\n#elif _DEFINENAME_DIRECTUV==3\n#define v_VARYINGNAME_UV vMainUV3\n#elif _DEFINENAME_DIRECTUV==4\n#define v_VARYINGNAME_UV vMainUV4\n#elif _DEFINENAME_DIRECTUV==5\n#define v_VARYINGNAME_UV vMainUV5\n#elif _DEFINENAME_DIRECTUV==6\n#define v_VARYINGNAME_UV vMainUV6\n#else\nvarying vec2 v_VARYINGNAME_UV;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const samplerFragmentAlternateDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrFragmentReflectionDeclaration\";\nconst shader = `#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\n#define sampleReflection(s,c) textureCube(s,c)\nuniform samplerCube reflectionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleReflectionLod(s,c,l) textureCubeLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;uniform samplerCube reflectionSamplerHigh;\n#endif\n#ifdef USEIRRADIANCEMAP\nuniform samplerCube irradianceSampler;\n#endif\n#else\n#define sampleReflection(s,c) texture2D(s,c)\nuniform sampler2D reflectionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleReflectionLod(s,c,l) texture2DLodEXT(s,c,l)\n#else\nuniform sampler2D reflectionSamplerLow;uniform sampler2D reflectionSamplerHigh;\n#endif\n#ifdef USEIRRADIANCEMAP\nuniform sampler2D irradianceSampler;\n#endif\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentReflectionDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nimport \"./samplerFragmentAlternateDeclaration\";\nimport \"./pbrFragmentReflectionDeclaration\";\nconst name = \"pbrFragmentSamplersDeclaration\";\nconst shader = `#include<samplerFragmentDeclaration>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo,_SAMPLERNAME_,albedo)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_SAMPLERNAME_,baseWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_SAMPLERNAME_,baseDiffuseRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_SAMPLERNAME_,ambient)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_SAMPLERNAME_,opacity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_SAMPLERNAME_,emissive)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_SAMPLERNAME_,lightmap)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,REFLECTIVITY,_VARYINGNAME_,Reflectivity,_SAMPLERNAME_,reflectivity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,MICROSURFACEMAP,_VARYINGNAME_,MicroSurfaceSampler,_SAMPLERNAME_,microSurface)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,METALLIC_REFLECTANCE,_VARYINGNAME_,MetallicReflectance,_SAMPLERNAME_,metallicReflectance)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,REFLECTANCE,_VARYINGNAME_,Reflectance,_SAMPLERNAME_,reflectance)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_SAMPLERNAME_,decal)\n#ifdef CLEARCOAT\n#include<samplerFragmentDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE,_VARYINGNAME_,ClearCoat,_SAMPLERNAME_,clearCoat)\n#include<samplerFragmentAlternateDeclaration>(_DEFINENAME_,CLEARCOAT_TEXTURE_ROUGHNESS,_VARYINGNAME_,ClearCoatRoughness)\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS)\nuniform sampler2D clearCoatRoughnessSampler;\n#endif\n#include<samplerFragmentDeclaration>(_DEFINENAME_,CLEARCOAT_BUMP,_VARYINGNAME_,ClearCoatBump,_SAMPLERNAME_,clearCoatBump)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,CLEARCOAT_TINT_TEXTURE,_VARYINGNAME_,ClearCoatTint,_SAMPLERNAME_,clearCoatTint)\n#endif\n#ifdef IRIDESCENCE\n#include<samplerFragmentDeclaration>(_DEFINENAME_,IRIDESCENCE_TEXTURE,_VARYINGNAME_,Iridescence,_SAMPLERNAME_,iridescence)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,IRIDESCENCE_THICKNESS_TEXTURE,_VARYINGNAME_,IridescenceThickness,_SAMPLERNAME_,iridescenceThickness)\n#endif\n#ifdef SHEEN\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SHEEN_TEXTURE,_VARYINGNAME_,Sheen,_SAMPLERNAME_,sheen)\n#include<samplerFragmentAlternateDeclaration>(_DEFINENAME_,SHEEN_TEXTURE_ROUGHNESS,_VARYINGNAME_,SheenRoughness)\n#if defined(SHEEN_ROUGHNESS) && defined(SHEEN_TEXTURE_ROUGHNESS)\nuniform sampler2D sheenRoughnessSampler;\n#endif\n#endif\n#ifdef ANISOTROPIC\n#include<samplerFragmentDeclaration>(_DEFINENAME_,ANISOTROPIC_TEXTURE,_VARYINGNAME_,Anisotropy,_SAMPLERNAME_,anisotropy)\n#endif\n#include<pbrFragmentReflectionDeclaration>\n#ifdef ENVIRONMENTBRDF\nuniform sampler2D environmentBrdfSampler;\n#endif\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\n#ifdef SS_REFRACTIONMAP_3D\n#define sampleRefraction(s,c) textureCube(s,c)\nuniform samplerCube refractionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleRefractionLod(s,c,l) textureCubeLodEXT(s,c,l)\n#else\nuniform samplerCube refractionSamplerLow;uniform samplerCube refractionSamplerHigh;\n#endif\n#else\n#define sampleRefraction(s,c) texture2D(s,c)\nuniform sampler2D refractionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleRefractionLod(s,c,l) texture2DLodEXT(s,c,l)\n#else\nuniform sampler2D refractionSamplerLow;uniform sampler2D refractionSamplerHigh;\n#endif\n#endif\n#endif\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_THICKNESSANDMASK_TEXTURE,_VARYINGNAME_,Thickness,_SAMPLERNAME_,thickness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_REFRACTIONINTENSITY_TEXTURE,_VARYINGNAME_,RefractionIntensity,_SAMPLERNAME_,refractionIntensity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYINTENSITY_TEXTURE,_VARYINGNAME_,TranslucencyIntensity,_SAMPLERNAME_,translucencyIntensity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SS_TRANSLUCENCYCOLOR_TEXTURE,_VARYINGNAME_,TranslucencyColor,_SAMPLERNAME_,translucencyColor)\n#endif\n#ifdef IBL_CDF_FILTERING\nuniform sampler2D icdfSampler;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrFragmentSamplersDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"textureRepetitionFunctions\";\nconst shader = `#if TEXTURE_REPETITION_MODE>0\nvec4 _texRepHash4(vec2 p) {return fract(sin(vec4(\n1.0+dot(p,vec2(37.0,17.0)),\n2.0+dot(p,vec2(11.0,47.0)),\n3.0+dot(p,vec2(41.0,29.0)),\n4.0+dot(p,vec2(23.0,31.0))\n))*103.0);}\n#endif\n#if TEXTURE_REPETITION_MODE==1\nvec4 _texRepSample(sampler2D samp,vec2 uv) {float k=texture2D(samp,0.005*uv).x;float index=k*8.0;float f=fract(index);float i=floor(index+0.5);float ib=floor(index);f=min(f,1.0-f)*2.0;vec2 offa=sin(vec2(3.0,7.0)*i);vec2 offb=sin(vec2(3.0,7.0)*ib);vec2 dx=dFdx(uv);vec2 dy=dFdy(uv);vec4 cola=textureGrad(samp,uv+0.3*offa,dx,dy);vec4 colb=textureGrad(samp,uv+0.3*offb,dx,dy);float colSum=cola.x+cola.y+cola.z-colb.x-colb.y-colb.z;return mix(cola,colb,smoothstep(0.2,0.8,f-0.1*colSum));}\n#elif TEXTURE_REPETITION_MODE==2\n#ifndef TEXTURE_REPETITION_M_PI\n#define TEXTURE_REPETITION_M_PI 3.14159265358979\n#endif\nvec2 _texRepHexHash(vec2 p) {vec2 r=mat2(127.1,269.5,311.7,183.3)*p;return fract(sin(r)*43758.5453);}\nvoid _texRepTriangleGrid(\nout float w1,out float w2,out float w3,\nout ivec2 vertex1,out ivec2 vertex2,out ivec2 vertex3,\nvec2 st\n) {st*=2.0*sqrt(3.0);mat2 gridToSkewedGrid=mat2(1.0,0.0,-0.57735027,1.15470054);vec2 skewedCoord=gridToSkewedGrid*st;ivec2 baseId=ivec2(floor(skewedCoord));vec3 temp=vec3(fract(skewedCoord),0.0);temp.z=1.0-temp.x-temp.y;float s=step(0.0,-temp.z);float s2=2.0*s-1.0;w1=-temp.z*s2;w2=s-temp.y*s2;w3=s-temp.x*s2;vertex1=baseId+ivec2(int(s),int(s));vertex2=baseId+ivec2(int(s),int(1.0-s));vertex3=baseId+ivec2(int(1.0-s),int(s));}\nvec2 _texRepMakeCenST(ivec2 Vertex) {mat2 invSkewMat=mat2(1.0,0.0,0.5,1.0/1.15470054);return (invSkewMat*vec2(Vertex))/(2.0*sqrt(3.0));}\nmat2 _texRepLoadRot2x2(ivec2 idx,float rotStr) {float angle=float(abs(idx.x*idx.y)+abs(idx.x+idx.y))+TEXTURE_REPETITION_M_PI;angle=mod(angle,2.0*TEXTURE_REPETITION_M_PI);if (angle<0.0) angle+=2.0*TEXTURE_REPETITION_M_PI;if (angle>TEXTURE_REPETITION_M_PI) angle-=TEXTURE_REPETITION_M_PI;angle*=rotStr;float cs=cos(angle);float si=sin(angle);return mat2(cs,si,-si,cs);}\nvec3 _texRepGain3(vec3 x,float r) {float k=log(1.0-r)/log(0.5);vec3 s=2.0*step(0.5,x);vec3 m=2.0*(1.0-s);vec3 res=0.5*s+0.25*m*pow(max(vec3(0.0),s+x*m),vec3(k));return res/(res.x+res.y+res.z);}\nvec4 _texRepSample(sampler2D samp,vec2 uv) {float rotStrength=vTextureRepetitionHexTilingParams.x;float fallOffContrast=vTextureRepetitionHexTilingParams.y;float expVal=vTextureRepetitionHexTilingParams.z;float r=vTextureRepetitionHexTilingParams.w;vec2 dSTdx=dFdx(uv);vec2 dSTdy=dFdy(uv);float w1,w2,w3;ivec2 vertex1,vertex2,vertex3;_texRepTriangleGrid(w1,w2,w3,vertex1,vertex2,vertex3,uv);mat2 rot1=_texRepLoadRot2x2(vertex1,rotStrength);mat2 rot2=_texRepLoadRot2x2(vertex2,rotStrength);mat2 rot3=_texRepLoadRot2x2(vertex3,rotStrength);vec2 cen1=_texRepMakeCenST(vertex1);vec2 cen2=_texRepMakeCenST(vertex2);vec2 cen3=_texRepMakeCenST(vertex3);vec2 st1=(uv-cen1)*rot1+cen1+_texRepHexHash(vec2(vertex1));vec2 st2=(uv-cen2)*rot2+cen2+_texRepHexHash(vec2(vertex2));vec2 st3=(uv-cen3)*rot3+cen3+_texRepHexHash(vec2(vertex3));vec4 c1=textureGrad(samp,st1,dSTdx*rot1,dSTdy*rot1);vec4 c2=textureGrad(samp,st2,dSTdx*rot2,dSTdy*rot2);vec4 c3=textureGrad(samp,st3,dSTdx*rot3,dSTdy*rot3);vec3 Lw=vec3(0.299,0.587,0.114);vec3 Dw=vec3(dot(c1.rgb,Lw),dot(c2.rgb,Lw),dot(c3.rgb,Lw));Dw=mix(vec3(1.0),Dw,fallOffContrast);vec3 W=Dw*pow(vec3(w1,w2,w3),vec3(expVal));W/=(W.x+W.y+W.z);if (r != 0.5) {W=_texRepGain3(W,r);}\nreturn W.x*c1+W.y*c2+W.z*c3;}\n#elif TEXTURE_REPETITION_MODE==3\nvec4 _texRepSample(sampler2D samp,vec2 uv) {vec2 iuv=floor(uv);vec2 fuv=fract(uv);vec4 ofa=_texRepHash4(iuv+vec2(0.0,0.0));vec4 ofb=_texRepHash4(iuv+vec2(1.0,0.0));vec4 ofc=_texRepHash4(iuv+vec2(0.0,1.0));vec4 ofd=_texRepHash4(iuv+vec2(1.0,1.0));vec2 dx=dFdx(uv);vec2 dy=dFdy(uv);ofa.zw=sign(ofa.zw-0.5);ofb.zw=sign(ofb.zw-0.5);ofc.zw=sign(ofc.zw-0.5);ofd.zw=sign(ofd.zw-0.5);vec2 uva=uv*ofa.zw+ofa.xy; vec2 ddxa=dx*ofa.zw; vec2 ddya=dy*ofa.zw;vec2 uvb=uv*ofb.zw+ofb.xy; vec2 ddxb=dx*ofb.zw; vec2 ddyb=dy*ofb.zw;vec2 uvc=uv*ofc.zw+ofc.xy; vec2 ddxc=dx*ofc.zw; vec2 ddyc=dy*ofc.zw;vec2 uvd=uv*ofd.zw+ofd.xy; vec2 ddxd=dx*ofd.zw; vec2 ddyd=dy*ofd.zw;vec2 b=smoothstep(0.25,0.75,fuv);return mix(\nmix(textureGrad(samp,uva,ddxa,ddya),textureGrad(samp,uvb,ddxb,ddyb),b.x),\nmix(textureGrad(samp,uvc,ddxc,ddyc),textureGrad(samp,uvd,ddxd,ddyd),b.x),\nb.y\n);}\n#elif TEXTURE_REPETITION_MODE==4\nvec4 _texRepSample(sampler2D samp,vec2 uv) {vec2 p=floor(uv);vec2 f=fract(uv);vec2 dx=dFdx(uv);vec2 dy=dFdy(uv);vec4 va=vec4(0.0);float wt=0.0;float w2=0.0;for (int j=-1; j<=1; j++) {for (int i=-1; i<=1; i++) {vec2 g=vec2(float(i),float(j));vec4 o=_texRepHash4(p+g);vec2 r=g-f+o.xy;float d=dot(r,r);float w=exp(-5.0*d);vec4 c=textureGrad(samp,uv+o.zw,dx,dy);va+=w*c;wt+=w;w2+=w*w;}}\nfloat mean=0.3;vec4 res=mean+(va-wt*mean)/sqrt(w2);return mix(va/wt,res,0.4);}\n#endif\n#if TEXTURE_REPETITION_MODE>0\n#define TEXRD(s,uv) _texRepSample(s,uv)\n#else\n#define TEXRD(s,uv) texture2D(s,uv)\n#endif\n#define TEXRD_DEFINED\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const textureRepetitionFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"subSurfaceScatteringFunctions\";\nconst shader = `bool testLightingForSSS(float diffusionProfile)\n{return diffusionProfile<1.;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const subSurfaceScatteringFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"importanceSampling\";\nconst shader = `vec3 hemisphereCosSample(vec2 u) {float phi=2.*PI*u.x;float cosTheta2=1.-u.y;float cosTheta=sqrt(cosTheta2);float sinTheta=sqrt(1.-cosTheta2);return vec3(sinTheta*cos(phi),sinTheta*sin(phi),cosTheta);}\nvec3 hemisphereImportanceSampleDggx(vec2 u,float a) {float phi=2.*PI*u.x;float cosTheta2=(1.-u.y)/(1.+(a+1.)*((a-1.)*u.y));float cosTheta=sqrt(cosTheta2);float sinTheta=sqrt(1.-cosTheta2);return vec3(sinTheta*cos(phi),sinTheta*sin(phi),cosTheta);}\nvec3 hemisphereImportanceSampleDggxAnisotropic(vec2 Xi,float alphaTangent,float alphaBitangent)\n{alphaTangent=max(alphaTangent,0.0001);alphaBitangent=max(alphaBitangent,0.0001);float phi=atan(alphaBitangent/alphaTangent*tan(2.0*3.14159265*Xi.x));if (Xi.x>0.5) phi+=3.14159265; \nfloat cosPhi=cos(phi);float sinPhi=sin(phi);float alpha2=(cosPhi*cosPhi)/(alphaTangent*alphaTangent) +\n(sinPhi*sinPhi)/(alphaBitangent*alphaBitangent);float tanTheta2=Xi.y/(1.0-Xi.y)/alpha2;float cosTheta=1.0/sqrt(1.0+tanTheta2);float sinTheta=sqrt(max(0.0,1.0-cosTheta*cosTheta));return vec3(sinTheta*cosPhi,sinTheta*sinPhi,cosTheta);}\nvec3 hemisphereImportanceSampleDCharlie(vec2 u,float a) { \nfloat phi=2.*PI*u.x;float sinTheta=pow(u.y,a/(2.*a+1.));float cosTheta=sqrt(1.-sinTheta*sinTheta);return vec3(sinTheta*cos(phi),sinTheta*sin(phi),cosTheta);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const importanceSampling = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrHelperFunctions\";\nconst shader = `#define MINIMUMVARIANCE 0.0005\n#ifndef TEXRD_DEFINED\n#define TEXRD(s,uv) texture2D(s,uv)\n#define TEXRD_DEFINED\n#endif\nfloat convertRoughnessToAverageSlope(float roughness)\n{return square(roughness)+MINIMUMVARIANCE;}\nfloat fresnelGrazingReflectance(float reflectance0) {float reflectance90=saturate(reflectance0*25.0);return reflectance90;}\nvec2 getAARoughnessFactors(vec3 normalVector) {\n#ifdef SPECULARAA\nvec3 nDfdx=dFdx(normalVector.xyz);vec3 nDfdy=dFdy(normalVector.xyz);float slopeSquare=max(dot(nDfdx,nDfdx),dot(nDfdy,nDfdy));float geometricRoughnessFactor=pow(saturate(slopeSquare),0.333);float geometricAlphaGFactor=sqrt(slopeSquare);geometricAlphaGFactor*=0.75;return vec2(geometricRoughnessFactor,geometricAlphaGFactor);\n#else\nreturn vec2(0.);\n#endif\n}\n#ifdef ANISOTROPIC\n#ifdef ANISOTROPIC_LEGACY\nvec2 getAnisotropicRoughness(float alphaG,float anisotropy) {float alphaT=max(alphaG*(1.0+anisotropy),MINIMUMVARIANCE);float alphaB=max(alphaG*(1.0-anisotropy),MINIMUMVARIANCE);return vec2(alphaT,alphaB);}\nvec3 getAnisotropicBentNormals(const vec3 T,const vec3 B,const vec3 N,const vec3 V,float anisotropy,float roughness) {vec3 anisotropicFrameDirection;if (anisotropy>=0.0) {anisotropicFrameDirection=B;} else {anisotropicFrameDirection=T;}\nvec3 anisotropicFrameTangent=cross(normalize(anisotropicFrameDirection),V);vec3 anisotropicFrameNormal=cross(anisotropicFrameTangent,anisotropicFrameDirection);vec3 anisotropicNormal=normalize(mix(N,anisotropicFrameNormal,abs(anisotropy)));return anisotropicNormal;}\n#elif ANISOTROPIC_OPENPBR\nvec2 getAnisotropicRoughness(float alphaG,float anisotropy) {float alphaT=max(alphaG*alphaG*sqrt(2.0/(1.0+(1.0-anisotropy)*(1.0-anisotropy))),MINIMUMVARIANCE);float alphaB=max(alphaT*(1.0-anisotropy),MINIMUMVARIANCE);return vec2(alphaT,alphaB);}\n#else\nvec2 getAnisotropicRoughness(float alphaG,float anisotropy) {float alphaT=max(mix(alphaG,1.0,anisotropy*anisotropy),MINIMUMVARIANCE);float alphaB=max(alphaG,MINIMUMVARIANCE);return vec2(alphaT,alphaB);}\nvec3 getAnisotropicBentNormals(const vec3 T,const vec3 B,const vec3 N,const vec3 V,float anisotropy,float roughness) {vec3 bentNormal=cross(B,V);bentNormal=normalize(cross(bentNormal,B));float a=square(square(1.0-anisotropy*(1.0-roughness)));bentNormal=normalize(mix(bentNormal,N,a));return bentNormal;}\n#endif\n#endif\n#if defined(CLEARCOAT) || defined(SS_REFRACTION)\nvec3 cocaLambert(vec3 alpha,float distance) {return exp(-alpha*distance);}\nvec3 cocaLambert(float NdotVRefract,float NdotLRefract,vec3 alpha,float thickness) {return cocaLambert(alpha,(thickness*((NdotLRefract+NdotVRefract)/(NdotLRefract*NdotVRefract))));}\nvec3 computeColorAtDistanceInMedia(vec3 color,float distance) {return -log(color)/distance;}\nvec3 computeClearCoatAbsorption(float NdotVRefract,float NdotLRefract,vec3 clearCoatColor,float clearCoatThickness,float clearCoatIntensity) {vec3 clearCoatAbsorption=mix(vec3(1.0),\ncocaLambert(NdotVRefract,NdotLRefract,clearCoatColor,clearCoatThickness),\nclearCoatIntensity);return clearCoatAbsorption;}\n#endif\n#ifdef MICROSURFACEAUTOMATIC\nfloat computeDefaultMicroSurface(float microSurface,vec3 reflectivityColor)\n{const float kReflectivityNoAlphaWorkflow_SmoothnessMax=0.95;float reflectivityLuminance=getLuminance(reflectivityColor);float reflectivityLuma=sqrt(reflectivityLuminance);microSurface=reflectivityLuma*kReflectivityNoAlphaWorkflow_SmoothnessMax;return microSurface;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrHelperFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./ltcHelperFunctions\";\nconst name = \"pbrDirectLightingSetupFunctions\";\nconst shader = `struct preLightingInfo\n{vec3 lightOffset;float lightDistanceSquared;float lightDistance;float attenuation;vec3 L;vec3 H;float NdotV;float NdotLUnclamped;float NdotL;float VdotH;float LdotV;float roughness;float diffuseRoughness;vec3 surfaceAlbedo;\n#ifdef IRIDESCENCE\nfloat iridescenceIntensity;\n#endif\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvec3 areaLightDiffuse;\n#ifdef SPECULARTERM\nvec3 areaLightSpecular;vec4 areaLightFresnel;\n#endif\n#endif\n};preLightingInfo computePointAndSpotPreLightingInfo(vec4 lightData,vec3 V,vec3 N,vec3 posW) {preLightingInfo result;result.lightOffset=lightData.xyz-posW;result.lightDistanceSquared=dot(result.lightOffset,result.lightOffset);result.lightDistance=sqrt(result.lightDistanceSquared);result.L=normalize(result.lightOffset);result.H=normalize(V+result.L);result.VdotH=saturate(dot(V,result.H));result.NdotLUnclamped=dot(N,result.L);result.NdotL=saturateEps(result.NdotLUnclamped);result.LdotV=0.;result.roughness=0.;result.diffuseRoughness=0.;result.surfaceAlbedo=vec3(0.);return result;}\npreLightingInfo computeDirectionalPreLightingInfo(vec4 lightData,vec3 V,vec3 N) {preLightingInfo result;result.lightDistance=length(-lightData.xyz);result.L=normalize(-lightData.xyz);result.H=normalize(V+result.L);result.VdotH=saturate(dot(V,result.H));result.NdotLUnclamped=dot(N,result.L);result.NdotL=saturateEps(result.NdotLUnclamped);result.LdotV=dot(result.L,V);result.roughness=0.;result.diffuseRoughness=0.;result.surfaceAlbedo=vec3(0.);return result;}\npreLightingInfo computeHemisphericPreLightingInfo(vec4 lightData,vec3 V,vec3 N) {preLightingInfo result;result.NdotL=dot(N,lightData.xyz)*0.5+0.5;result.NdotL=saturateEps(result.NdotL);result.NdotLUnclamped=result.NdotL;\n#ifdef SPECULARTERM\nresult.L=normalize(lightData.xyz);result.H=normalize(V+result.L);result.VdotH=saturate(dot(V,result.H));\n#endif\nresult.LdotV=0.;result.roughness=0.;result.diffuseRoughness=0.;result.surfaceAlbedo=vec3(0.);return result;}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#include<ltcHelperFunctions>\nuniform sampler2D areaLightsLTC1Sampler;uniform sampler2D areaLightsLTC2Sampler;preLightingInfo computeAreaPreLightingInfo(sampler2D ltc1,sampler2D ltc2,vec3 viewDirectionW,vec3 vNormal,vec3 vPosition,vec4 lightData,vec3 halfWidth,vec3 halfHeight,float roughness )\n{preLightingInfo result;result.lightOffset=lightData.xyz-vPosition;result.lightDistanceSquared=dot(result.lightOffset,result.lightOffset);result.lightDistance=sqrt(result.lightDistanceSquared);areaLightData data=computeAreaLightSpecularDiffuseFresnel(ltc1,ltc2,viewDirectionW,vNormal,vPosition,lightData.xyz,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nresult.areaLightFresnel=data.Fresnel;result.areaLightSpecular=data.Specular;\n#endif\nresult.areaLightDiffuse=data.Diffuse;result.LdotV=0.;result.roughness=0.;result.diffuseRoughness=0.;result.surfaceAlbedo=vec3(0.);return result;}\npreLightingInfo computeAreaPreLightingInfoWithTexture(sampler2D ltc1,sampler2D ltc2,sampler2D emissionTexture,vec3 viewDirectionW,vec3 vNormal,vec3 vPosition,vec4 lightData,vec3 halfWidth,vec3 halfHeight,float roughness )\n{preLightingInfo result;result.lightOffset=lightData.xyz-vPosition;result.lightDistanceSquared=dot(result.lightOffset,result.lightOffset);result.lightDistance=sqrt(result.lightDistanceSquared);areaLightData data=computeAreaLightSpecularDiffuseFresnelWithEmission(ltc1,ltc2,emissionTexture,viewDirectionW,vNormal,vPosition,lightData.xyz,halfWidth,halfHeight,roughness);\n#ifdef SPECULARTERM\nresult.areaLightFresnel=data.Fresnel;result.areaLightSpecular=data.Specular;\n#endif\nresult.areaLightDiffuse=data.Diffuse;result.LdotV=0.;result.roughness=0.;result.diffuseRoughness=0.;result.surfaceAlbedo=vec3(0.);return result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrDirectLightingSetupFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrDirectLightingFalloffFunctions\";\nconst shader = `float computeDistanceLightFalloff_Standard(vec3 lightOffset,float range)\n{return max(0.,1.0-length(lightOffset)/range);}\nfloat computeDistanceLightFalloff_Physical(float lightDistanceSquared)\n{return 1.0/maxEps(lightDistanceSquared);}\nfloat computeDistanceLightFalloff_GLTF(float lightDistanceSquared,float inverseSquaredRange)\n{float lightDistanceFalloff=1.0/maxEps(lightDistanceSquared);float factor=lightDistanceSquared*inverseSquaredRange;float attenuation=saturate(1.0-factor*factor);attenuation*=attenuation;lightDistanceFalloff*=attenuation;return lightDistanceFalloff;}\nfloat computeDistanceLightFalloff(vec3 lightOffset,float lightDistanceSquared,float range,float inverseSquaredRange)\n{\n#ifdef USEPHYSICALLIGHTFALLOFF\nreturn computeDistanceLightFalloff_Physical(lightDistanceSquared);\n#elif defined(USEGLTFLIGHTFALLOFF)\nreturn computeDistanceLightFalloff_GLTF(lightDistanceSquared,inverseSquaredRange);\n#else\nreturn computeDistanceLightFalloff_Standard(lightOffset,range);\n#endif\n}\nfloat computeDirectionalLightFalloff_Standard(vec3 lightDirection,vec3 directionToLightCenterW,float cosHalfAngle,float exponent)\n{float falloff=0.0;float cosAngle=maxEps(dot(-lightDirection,directionToLightCenterW));if (cosAngle>=cosHalfAngle)\n{falloff=max(0.,pow(cosAngle,exponent));}\nreturn falloff;}\nfloat computeDirectionalLightFalloff_IES(vec3 lightDirection,vec3 directionToLightCenterW,sampler2D iesLightSampler)\n{float cosAngle=dot(-lightDirection,directionToLightCenterW);float angle=acos(cosAngle)/PI;return texture2D(iesLightSampler,vec2(angle,0.)).r;}\nfloat computeDirectionalLightFalloff_Physical(vec3 lightDirection,vec3 directionToLightCenterW,float cosHalfAngle)\n{const float kMinusLog2ConeAngleIntensityRatio=6.64385618977; \nfloat concentrationKappa=kMinusLog2ConeAngleIntensityRatio/(1.0-cosHalfAngle);vec4 lightDirectionSpreadSG=vec4(-lightDirection*concentrationKappa,-concentrationKappa);float falloff=exp2(dot(vec4(directionToLightCenterW,1.0),lightDirectionSpreadSG));return falloff;}\nfloat computeDirectionalLightFalloff_GLTF(vec3 lightDirection,vec3 directionToLightCenterW,float lightAngleScale,float lightAngleOffset)\n{float cd=dot(-lightDirection,directionToLightCenterW);float falloff=saturate(cd*lightAngleScale+lightAngleOffset);falloff*=falloff;return falloff;}\nfloat computeDirectionalLightFalloff(vec3 lightDirection,vec3 directionToLightCenterW,float cosHalfAngle,float exponent,float lightAngleScale,float lightAngleOffset)\n{\n#ifdef USEPHYSICALLIGHTFALLOFF\nreturn computeDirectionalLightFalloff_Physical(lightDirection,directionToLightCenterW,cosHalfAngle);\n#elif defined(USEGLTFLIGHTFALLOFF)\nreturn computeDirectionalLightFalloff_GLTF(lightDirection,directionToLightCenterW,lightAngleScale,lightAngleOffset);\n#else\nreturn computeDirectionalLightFalloff_Standard(lightDirection,directionToLightCenterW,cosHalfAngle,exponent);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrDirectLightingFalloffFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"hdrFilteringFunctions\";\nconst shader = `#if NUM_SAMPLES\n#if NUM_SAMPLES>0\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nprecision highp int;float radicalInverse_VdC(uint bits)\n{bits=(bits<<16u) | (bits>>16u);bits=((bits & 0x55555555u)<<1u) | ((bits & 0xAAAAAAAAu)>>1u);bits=((bits & 0x33333333u)<<2u) | ((bits & 0xCCCCCCCCu)>>2u);bits=((bits & 0x0F0F0F0Fu)<<4u) | ((bits & 0xF0F0F0F0u)>>4u);bits=((bits & 0x00FF00FFu)<<8u) | ((bits & 0xFF00FF00u)>>8u);return float(bits)*2.3283064365386963e-10; }\nvec2 hammersley(uint i,uint N)\n{return vec2(float(i)/float(N),radicalInverse_VdC(i));}\n#else\nfloat vanDerCorpus(int n,int base)\n{float invBase=1.0/float(base);float denom =1.0;float result =0.0;for(int i=0; i<32; ++i)\n{if(n>0)\n{denom =mod(float(n),2.0);result+=denom*invBase;invBase=invBase/2.0;n =int(float(n)/2.0);}}\nreturn result;}\nvec2 hammersley(int i,int N)\n{return vec2(float(i)/float(N),vanDerCorpus(i,2));}\n#endif\nfloat log4(float x) {return log2(x)/2.;}\nvec3 uv_to_normal(vec2 uv) {vec3 N;vec2 uvRange=uv;float theta=uvRange.x*2.*PI;float phi=uvRange.y*PI;float sinPhi=sin(phi);N.x=cos(theta)*sinPhi;N.z=sin(theta)*sinPhi;N.y=cos(phi);return N;}\nconst float NUM_SAMPLES_FLOAT=float(NUM_SAMPLES);const float NUM_SAMPLES_FLOAT_INVERSED=1./NUM_SAMPLES_FLOAT;const float K=4.;\n#define inline\nvec3 irradiance(\n#ifdef CUSTOM_IRRADIANCE_FILTERING_INPUT\nCUSTOM_IRRADIANCE_FILTERING_INPUT\n#else\nsamplerCube inputTexture,\n#endif\nvec3 inputN,vec2 filteringInfo,\nfloat diffuseRoughness,\nvec3 surfaceAlbedo,\nvec3 inputV\n#if IBL_CDF_FILTERING\n,sampler2D icdfSampler\n#endif\n)\n{vec3 n=normalize(inputN);vec3 result=vec3(0.);\n#ifndef IBL_CDF_FILTERING\nvec3 tangent=abs(n.z)<0.999 ? vec3(0.,0.,1.) : vec3(1.,0.,0.);tangent=normalize(cross(tangent,n));vec3 bitangent=cross(n,tangent);mat3 tbn=mat3(tangent,bitangent,n);mat3 tbnInverse=mat3(tangent.x,bitangent.x,n.x,tangent.y,bitangent.y,n.y,tangent.z,bitangent.z,n.z);\n#endif\nfloat maxLevel=filteringInfo.y;float dim0=filteringInfo.x;float omegaP=(4.*PI)/(6.*dim0*dim0);vec3 clampedAlbedo=clamp(surfaceAlbedo,vec3(0.1),vec3(1.0));\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nfor(uint i=0u; i<NUM_SAMPLES; ++i)\n#else\nfor(int i=0; i<NUM_SAMPLES; ++i)\n#endif\n{vec2 Xi=hammersley(i,NUM_SAMPLES);\n#if IBL_CDF_FILTERING\nvec2 T;T.x=texture2D(icdfSampler,vec2(Xi.x,0.)).x;T.y=texture2D(icdfSampler,vec2(T.x,Xi.y)).y;vec3 Ls=uv_to_normal(vec2(1.0-fract(T.x+0.25),T.y));float NoL=dot(n,Ls);float NoV=dot(n,inputV);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nfloat LoV=dot (Ls,inputV);\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvec3 H=(inputV+Ls)*0.5;float VoH=dot(inputV,H);\n#endif\n#else\nvec3 Ls=hemisphereCosSample(Xi);Ls=normalize(Ls);float NoL=Ls.z; \nvec3 V=tbnInverse*inputV;float NoV=V.z; \n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nfloat LoV=dot (Ls,V);\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvec3 H=(V+Ls)*0.5;float VoH=dot(V,H);\n#endif\n#endif\nif (NoL>0.) {\n#if IBL_CDF_FILTERING\nfloat pdf=texture2D(icdfSampler,T).z;vec3 c=textureCubeLodEXT(inputTexture,Ls,0.).rgb;\n#else\nfloat pdf_inversed=PI/NoL;float omegaS=NUM_SAMPLES_FLOAT_INVERSED*pdf_inversed;float l=log4(omegaS)-log4(omegaP)+log4(K);float mipLevel=clamp(l,0.,maxLevel);\n#ifdef CUSTOM_IRRADIANCE_FILTERING_FUNCTION\nCUSTOM_IRRADIANCE_FILTERING_FUNCTION\n#else\nvec3 c=textureCubeLodEXT(inputTexture,tbn*Ls,mipLevel).rgb;\n#endif\n#endif\n#if GAMMA_INPUT\nc=toLinearSpace(c);\n#endif\nvec3 diffuseRoughnessTerm=vec3(1.0);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\ndiffuseRoughnessTerm=diffuseBRDF_EON(clampedAlbedo,diffuseRoughness,NoL,NoV,LoV)*PI;\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\ndiffuseRoughnessTerm=vec3(diffuseBRDF_Burley(NoL,NoV,VoH,diffuseRoughness)*PI);\n#endif\n#if IBL_CDF_FILTERING\nvec3 light=pdf<1e-6 ? vec3(0.0) : vec3(1.0)/vec3(pdf)*c;result+=NoL*diffuseRoughnessTerm*light;\n#else\nresult+=c*diffuseRoughnessTerm;\n#endif\n}}\nresult=result*NUM_SAMPLES_FLOAT_INVERSED;\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nresult=result/clampedAlbedo;\n#endif\nreturn result;}\n#define inline\nvec3 radiance(float alphaG,samplerCube inputTexture,vec3 inputN,vec2 filteringInfo)\n{vec3 n=normalize(inputN);vec3 c=textureCubeLodEXT(inputTexture,n,0.).rgb; \nif (alphaG==0.) {\n#if GAMMA_INPUT\nc=toLinearSpace(c);\n#endif\nreturn c;} else {vec3 result=vec3(0.);vec3 tangent=abs(n.z)<0.999 ? vec3(0.,0.,1.) : vec3(1.,0.,0.);tangent=normalize(cross(tangent,n));vec3 bitangent=cross(n,tangent);mat3 tbn=mat3(tangent,bitangent,n);float maxLevel=filteringInfo.y;float dim0=filteringInfo.x;float omegaP=(4.*PI)/(6.*dim0*dim0);float weight=0.;\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nfor(uint i=0u; i<NUM_SAMPLES; ++i)\n#else\nfor(int i=0; i<NUM_SAMPLES; ++i)\n#endif\n{vec2 Xi=hammersley(i,NUM_SAMPLES);vec3 H=hemisphereImportanceSampleDggx(Xi,alphaG);float NoV=1.;float NoH=H.z;float NoH2=H.z*H.z;float NoL=2.*NoH2-1.;vec3 L=vec3(2.*NoH*H.x,2.*NoH*H.y,NoL);L=normalize(L);if (NoL>0.) {float pdf_inversed=4./normalDistributionFunction_TrowbridgeReitzGGX(NoH,alphaG);float omegaS=NUM_SAMPLES_FLOAT_INVERSED*pdf_inversed;float l=log4(omegaS)-log4(omegaP)+log4(K);float mipLevel=clamp(float(l),0.0,maxLevel);weight+=NoL;vec3 c=textureCubeLodEXT(inputTexture,tbn*L,mipLevel).rgb;\n#if GAMMA_INPUT\nc=toLinearSpace(c);\n#endif\nresult+=c*NoL;}}\nresult=result/weight;return result;}}\n#ifdef ANISOTROPIC\n#define inline\nvec3 radianceAnisotropic(\nfloat alphaTangent, \nfloat alphaBitangent, \nsamplerCube inputTexture,\nvec3 inputView, \nvec3 inputTangent, \nvec3 inputBitangent, \nvec3 inputNormal, \nvec2 filteringInfo,\nvec2 noiseInput, \nbool isRefraction,\nfloat ior \n)\n{vec3 V=inputView;vec3 N=inputNormal;vec3 T=inputTangent;vec3 B=inputBitangent;vec3 result=vec3(0.);float maxLevel=filteringInfo.y;float dim0=filteringInfo.x;float clampedAlphaT=max(alphaTangent,MINIMUMVARIANCE);float clampedAlphaB=max(alphaBitangent,MINIMUMVARIANCE);float effectiveDim=dim0*sqrt(clampedAlphaT*clampedAlphaB);float omegaP=(4.*PI)/(6.*effectiveDim*effectiveDim);const float noiseScale=clamp(log2(float(NUM_SAMPLES))/12.0,0.0,1.0);float weight=0.;\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nfor(uint i=0u; i<NUM_SAMPLES; ++i)\n#else\nfor(int i=0; i<NUM_SAMPLES; ++i)\n#endif\n{vec2 Xi=hammersley(i,NUM_SAMPLES);Xi=fract(Xi+noiseInput*mix(0.5,0.015,noiseScale)); \nvec3 H_tangent=hemisphereImportanceSampleDggxAnisotropic(Xi,clampedAlphaT,clampedAlphaB);vec3 H=normalize(H_tangent.x*T+H_tangent.y*B+H_tangent.z*N);vec3 L;if (isRefraction) {L=refract(-V,H,1.0/ior);} else {L=reflect(-V,H);}\nfloat NoH=max(dot(N,H),0.001);float VoH=max(dot(V,H),0.001);float NoL=max(dot(N,L),0.001);if (NoL>0.) {float pdf_inversed=4./normalDistributionFunction_BurleyGGX_Anisotropic(\nH_tangent.z,H_tangent.x,H_tangent.y,vec2(clampedAlphaT,clampedAlphaB)\n);float omegaS=NUM_SAMPLES_FLOAT_INVERSED*pdf_inversed;float l=log4(omegaS)-log4(omegaP)+log4(K);float mipLevel=clamp(float(l),0.0,maxLevel);weight+=NoL;vec3 c=textureCubeLodEXT(inputTexture,L,mipLevel).rgb;\n#if GAMMA_INPUT\nc=toLinearSpace(c);\n#endif\nresult+=c*NoL;}}\nresult=result/weight;return result;}\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const hdrFilteringFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrDirectLightingFunctions\";\nconst shader = `#define CLEARCOATREFLECTANCE90 1.0\nstruct lightingInfo\n{vec3 diffuse;\n#ifdef SS_TRANSLUCENCY\nvec3 diffuseTransmission;\n#endif\n#ifdef SPECULARTERM\nvec3 specular;\n#endif\n#ifdef CLEARCOAT\nvec4 clearCoat;\n#endif\n#ifdef SHEEN\nvec3 sheen;\n#endif\n};float adjustRoughnessFromLightProperties(float roughness,float lightRadius,float lightDistance) {\n#if defined(USEPHYSICALLIGHTFALLOFF) || defined(USEGLTFLIGHTFALLOFF)\nfloat lightRoughness=lightRadius/lightDistance;float totalRoughness=saturate(lightRoughness+roughness);return totalRoughness;\n#else\nreturn roughness;\n#endif\n}\nvec3 computeHemisphericDiffuseLighting(preLightingInfo info,vec3 lightColor,vec3 groundColor) {return mix(groundColor,lightColor,info.NdotL);}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvec3 computeAreaDiffuseLighting(preLightingInfo info,vec3 lightColor) {return info.areaLightDiffuse*lightColor;}\n#endif\nvec3 computeDiffuseLighting(preLightingInfo info,vec3 lightColor) {vec3 diffuseTerm=vec3(1.0/PI);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_LEGACY\ndiffuseTerm=vec3(diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.roughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\ndiffuseTerm=vec3(diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.diffuseRoughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvec3 clampedAlbedo=clamp(info.surfaceAlbedo,vec3(0.1),vec3(1.0));diffuseTerm=diffuseBRDF_EON(clampedAlbedo,info.diffuseRoughness,info.NdotL,info.NdotV,info.LdotV);diffuseTerm/=clampedAlbedo;\n#endif\nreturn diffuseTerm*info.attenuation*info.NdotL*lightColor;}\n#define inline\nvec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler,mat4 textureProjectionMatrix,vec3 posW){vec4 strq=textureProjectionMatrix*vec4(posW,1.0);strq/=strq.w;vec3 textureColor=texture2D(projectionLightSampler,strq.xy).rgb;return toLinearSpace(textureColor);}\n#ifdef SS_TRANSLUCENCY\nvec3 computeDiffuseTransmittedLighting(preLightingInfo info,vec3 lightColor,vec3 transmittance) {vec3 transmittanceNdotL=vec3(0.);float NdotL=absEps(info.NdotLUnclamped);\n#ifndef SS_TRANSLUCENCY_LEGACY\nif (info.NdotLUnclamped<0.0) {\n#endif\nfloat wrapNdotL=computeWrappedDiffuseNdotL(NdotL,0.02);float trAdapt=step(0.,info.NdotLUnclamped);transmittanceNdotL=mix(transmittance*wrapNdotL,vec3(wrapNdotL),trAdapt);\n#ifndef SS_TRANSLUCENCY_LEGACY\n}\nvec3 diffuseTerm=vec3(1.0/PI);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_LEGACY\ndiffuseTerm=vec3(diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.roughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\ndiffuseTerm=vec3(diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.diffuseRoughness));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nvec3 clampedAlbedo=clamp(info.surfaceAlbedo,vec3(0.1),vec3(1.0));diffuseTerm=diffuseBRDF_EON(clampedAlbedo,info.diffuseRoughness,info.NdotL,info.NdotV,info.LdotV);diffuseTerm/=clampedAlbedo;\n#endif\n#else\nfloat diffuseTerm=diffuseBRDF_Burley(NdotL,info.NdotV,info.VdotH,info.roughness);\n#endif\nreturn diffuseTerm*transmittanceNdotL*info.attenuation*lightColor;}\n#endif\n#ifdef SPECULARTERM\nvec3 computeSpecularLighting(preLightingInfo info,vec3 N,vec3 reflectance0,vec3 fresnel,float geometricRoughnessFactor,vec3 lightColor) {float NdotH=saturateEps(dot(N,info.H));float roughness=max(info.roughness,geometricRoughnessFactor);float alphaG=convertRoughnessToAverageSlope(roughness);\n#ifdef IRIDESCENCE\nfresnel=mix(fresnel,reflectance0,info.iridescenceIntensity);\n#endif\nfloat distribution=normalDistributionFunction_TrowbridgeReitzGGX(NdotH,alphaG);\n#ifdef BRDF_V_HEIGHT_CORRELATED\nfloat smithVisibility=smithVisibility_GGXCorrelated(info.NdotL,info.NdotV,alphaG);\n#else\nfloat smithVisibility=smithVisibility_TrowbridgeReitzGGXFast(info.NdotL,info.NdotV,alphaG);\n#endif\nvec3 specTerm=fresnel*distribution*smithVisibility;return specTerm*info.attenuation*info.NdotL*lightColor;}\n#if defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvec3 computeAreaSpecularLighting(preLightingInfo info,vec3 specularColor,vec3 reflectance0,vec3 reflectance90) {vec3 fresnel=specularColor*info.areaLightFresnel.x*reflectance0+( vec3( 1.0 )-specularColor )*info.areaLightFresnel.y*reflectance90;return specularColor*fresnel*info.areaLightSpecular;}\nvec3 computeOpenPBRAreaSpecularLighting(preLightingInfo info,vec3 lightColor,vec3 reflectance0,vec3 reflectance90) {vec3 fresnel=reflectance0*info.areaLightFresnel.x+(reflectance90-reflectance0)*info.areaLightFresnel.y;return lightColor*fresnel*info.areaLightSpecular;}\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nvec3 computeOpenPBRAreaConductorSpecularLighting(preLightingInfo info,vec3 lightColor,vec3 reflectance0,vec3 edgeTint) {vec3 b=getF82B(reflectance0,edgeTint);float normalizedSchlickMoment=clamp(info.areaLightFresnel.y/max(info.areaLightFresnel.x,Epsilon),0.0,1.0);float representativeOneMinusCosTheta=pow(normalizedSchlickMoment,0.2);float f82DipMoment=info.areaLightFresnel.y*representativeOneMinusCosTheta*(1.0-representativeOneMinusCosTheta);vec3 fresnel=reflectance0*info.areaLightFresnel.x+(vec3(1.0)-reflectance0)*info.areaLightFresnel.y-b*f82DipMoment;return lightColor*clamp(fresnel,vec3(0.0),vec3(info.areaLightFresnel.x))*info.areaLightSpecular;}\n#endif\nfloat computeOpenPBRAreaFresnel(preLightingInfo info,float reflectance0,float reflectance90) {return reflectance0*info.areaLightFresnel.x+(reflectance90-reflectance0)*info.areaLightFresnel.y;}\n#endif\n#endif\n#ifdef FUZZ\nfloat evalFuzz(vec3 L,float NdotL,float NdotV,vec3 T,vec3 B,vec3 ltcLut)\n{if (NdotL<=0.0 || NdotV<=0.0)\nreturn 0.0;mat3 M=mat3(\nvec3(ltcLut.r,0.0,0.0),\nvec3(ltcLut.g,1.0,0.0),\nvec3(0.0,0.0,1.0)\n);vec3 Llocal=vec3(dot(L,T),dot(L,B),NdotL);vec3 Lwarp=normalize(M*Llocal);float cosThetaWarp=max(Lwarp.z,0.0);return cosThetaWarp*NdotL;}\n#endif\n#if defined(ANISOTROPIC) && defined(ANISOTROPIC_OPENPBR)\nvec3 computeAnisotropicSpecularLighting(preLightingInfo info,vec3 V,vec3 N,vec3 T,vec3 B,float anisotropy,float geometricRoughnessFactor,vec3 lightColor) {float NdotH=saturateEps(dot(N,info.H));float TdotH=dot(T,info.H);float BdotH=dot(B,info.H);float TdotV=dot(T,V);float BdotV=dot(B,V);float TdotL=dot(T,info.L);float BdotL=dot(B,info.L);float alphaG=convertRoughnessToAverageSlope(info.roughness);vec2 alphaTB=getAnisotropicRoughness(alphaG,anisotropy);float distribution=normalDistributionFunction_BurleyGGX_Anisotropic(NdotH,TdotH,BdotH,alphaTB);float smithVisibility=smithVisibility_GGXCorrelated_Anisotropic(info.NdotL,info.NdotV,TdotV,BdotV,TdotL,BdotL,alphaTB);vec3 specTerm=vec3(distribution*smithVisibility);return specTerm*info.attenuation*info.NdotL*lightColor;}\n#elif defined(ANISOTROPIC)\nvec3 computeAnisotropicSpecularLighting(preLightingInfo info,vec3 V,vec3 N,vec3 T,vec3 B,float anisotropy,vec3 reflectance0,vec3 reflectance90,float geometricRoughnessFactor,vec3 lightColor) {float NdotH=saturateEps(dot(N,info.H));float TdotH=dot(T,info.H);float BdotH=dot(B,info.H);float TdotV=dot(T,V);float BdotV=dot(B,V);float TdotL=dot(T,info.L);float BdotL=dot(B,info.L);float alphaG=convertRoughnessToAverageSlope(info.roughness);vec2 alphaTB=getAnisotropicRoughness(alphaG,anisotropy);alphaTB=max(alphaTB,square(geometricRoughnessFactor));vec3 fresnel=fresnelSchlickGGX(info.VdotH,reflectance0,reflectance90);\n#ifdef IRIDESCENCE\nfresnel=mix(fresnel,reflectance0,info.iridescenceIntensity);\n#endif\nfloat distribution=normalDistributionFunction_BurleyGGX_Anisotropic(NdotH,TdotH,BdotH,alphaTB);float smithVisibility=smithVisibility_GGXCorrelated_Anisotropic(info.NdotL,info.NdotV,TdotV,BdotV,TdotL,BdotL,alphaTB);vec3 specTerm=fresnel*distribution*smithVisibility;return specTerm*info.attenuation*info.NdotL*lightColor;}\n#endif\n#ifdef CLEARCOAT\nvec4 computeClearCoatLighting(preLightingInfo info,vec3 Ncc,float geometricRoughnessFactor,float clearCoatIntensity,vec3 lightColor) {float NccdotL=saturateEps(dot(Ncc,info.L));float NccdotH=saturateEps(dot(Ncc,info.H));float clearCoatRoughness=max(info.roughness,geometricRoughnessFactor);float alphaG=convertRoughnessToAverageSlope(clearCoatRoughness);float fresnel=fresnelSchlickGGX(info.VdotH,vClearCoatRefractionParams.x,CLEARCOATREFLECTANCE90);fresnel*=clearCoatIntensity;float distribution=normalDistributionFunction_TrowbridgeReitzGGX(NccdotH,alphaG);float kelemenVisibility=visibility_Kelemen(info.VdotH);float clearCoatTerm=fresnel*distribution*kelemenVisibility;return vec4(\nclearCoatTerm*info.attenuation*NccdotL*lightColor,\n1.0-fresnel\n);}\nvec3 computeClearCoatLightingAbsorption(float NdotVRefract,vec3 L,vec3 Ncc,vec3 clearCoatColor,float clearCoatThickness,float clearCoatIntensity) {vec3 LRefract=-refract(L,Ncc,vClearCoatRefractionParams.y);float NdotLRefract=saturateEps(dot(Ncc,LRefract));vec3 absorption=computeClearCoatAbsorption(NdotVRefract,NdotLRefract,clearCoatColor,clearCoatThickness,clearCoatIntensity);return absorption;}\n#endif\n#ifdef SHEEN\nvec3 computeSheenLighting(preLightingInfo info,vec3 N,vec3 reflectance0,vec3 reflectance90,float geometricRoughnessFactor,vec3 lightColor) {float NdotH=saturateEps(dot(N,info.H));float roughness=max(info.roughness,geometricRoughnessFactor);float alphaG=convertRoughnessToAverageSlope(roughness);float fresnel=1.;float distribution=normalDistributionFunction_CharlieSheen(NdotH,alphaG);/*#ifdef SHEEN_SOFTER\nfloat visibility=visibility_CharlieSheen(info.NdotL,info.NdotV,alphaG);\n#else */\nfloat visibility=visibility_Ashikhmin(info.NdotL,info.NdotV);/* #endif */\nfloat sheenTerm=fresnel*distribution*visibility;return sheenTerm*info.attenuation*info.NdotL*lightColor;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrDirectLightingFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrIBLFunctions\";\nconst shader = `#if defined(REFLECTION) || defined(SS_REFRACTION)\nfloat getLodFromAlphaG(float cubeMapDimensionPixels,float microsurfaceAverageSlope) {float microsurfaceAverageSlopeTexels=cubeMapDimensionPixels*microsurfaceAverageSlope;float lod=log2(microsurfaceAverageSlopeTexels);return lod;}\nfloat getLinearLodFromRoughness(float cubeMapDimensionPixels,float roughness) {float lod=log2(cubeMapDimensionPixels)*roughness;return lod;}\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(RADIANCEOCCLUSION)\nfloat environmentRadianceOcclusion(float ambientOcclusion,float NdotVUnclamped) {float temp=NdotVUnclamped+ambientOcclusion;return saturate(square(temp)-1.0+ambientOcclusion);}\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(HORIZONOCCLUSION)\nfloat environmentHorizonOcclusion(vec3 view,vec3 normal,vec3 geometricNormal) {vec3 reflection=reflect(view,normal);float temp=saturate(1.0+1.1*dot(reflection,geometricNormal));return square(temp);}\n#endif\n#if defined(LODINREFLECTIONALPHA) || defined(SS_LODINREFRACTIONALPHA)\n#define UNPACK_LOD(x) (1.0-x)*255.0\nfloat getLodFromAlphaG(float cubeMapDimensionPixels,float alphaG,float NdotV) {float microsurfaceAverageSlope=alphaG;microsurfaceAverageSlope*=sqrt(abs(NdotV));return getLodFromAlphaG(cubeMapDimensionPixels,microsurfaceAverageSlope);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrIBLFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpFragmentMainFunctions\";\nconst shader = `#ifndef TEXRD_DEFINED\n#define TEXRD(s,uv) texture2D(s,uv)\n#define TEXRD_DEFINED\n#endif\n#if defined(BUMP) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC) || defined(DETAIL)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nuniform mat4 normalMatrix;\n#if defined(WEBGL2) || defined(WEBGPU)\nmat4 toNormalMatrix(mat4 wMatrix)\n{mat4 ret=inverse(wMatrix);ret=transpose(ret);ret[0][3]=0.;ret[1][3]=0.;ret[2][3]=0.;ret[3]=vec4(0.,0.,0.,1.);return ret;}\n#else\nmat4 toNormalMatrix(mat4 m)\n{float\na00=m[0][0],a01=m[0][1],a02=m[0][2],a03=m[0][3],\na10=m[1][0],a11=m[1][1],a12=m[1][2],a13=m[1][3],\na20=m[2][0],a21=m[2][1],a22=m[2][2],a23=m[2][3],\na30=m[3][0],a31=m[3][1],a32=m[3][2],a33=m[3][3],\nb00=a00*a11-a01*a10,\nb01=a00*a12-a02*a10,\nb02=a00*a13-a03*a10,\nb03=a01*a12-a02*a11,\nb04=a01*a13-a03*a11,\nb05=a02*a13-a03*a12,\nb06=a20*a31-a21*a30,\nb07=a20*a32-a22*a30,\nb08=a20*a33-a23*a30,\nb09=a21*a32-a22*a31,\nb10=a21*a33-a23*a31,\nb11=a22*a33-a23*a32,\ndet=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;mat4 mi=mat4(\na11*b11-a12*b10+a13*b09,\na02*b10-a01*b11-a03*b09,\na31*b05-a32*b04+a33*b03,\na22*b04-a21*b05-a23*b03,\na12*b08-a10*b11-a13*b07,\na00*b11-a02*b08+a03*b07,\na32*b02-a30*b05-a33*b01,\na20*b05-a22*b02+a23*b01,\na10*b10-a11*b08+a13*b06,\na01*b08-a00*b10-a03*b06,\na30*b04-a31*b02+a33*b00,\na21*b02-a20*b04-a23*b00,\na11*b07-a10*b09-a12*b06,\na00*b09-a01*b07+a02*b06,\na31*b01-a30*b03-a32*b00,\na20*b03-a21*b01+a22*b00)/det;return mat4(mi[0][0],mi[1][0],mi[2][0],mi[3][0],\nmi[0][1],mi[1][1],mi[2][1],mi[3][1],\nmi[0][2],mi[1][2],mi[2][2],mi[3][2],\nmi[0][3],mi[1][3],mi[2][3],mi[3][3]);}\n#endif\n#endif\nvec3 perturbNormalBase(mat3 cotangentFrame,vec3 normal,float scale)\n{\n#ifdef NORMALXYSCALE\nnormal=normalize(normal*vec3(scale,scale,1.0));\n#endif\nreturn normalize(cotangentFrame*normal);}\nvec3 perturbNormal(mat3 cotangentFrame,vec3 textureSample,float scale)\n{return perturbNormalBase(cotangentFrame,textureSample*2.0-1.0,scale);}\nmat3 cotangent_frame(vec3 normal,vec3 p,vec2 uv,vec2 tangentSpaceParams)\n{vec3 dp1=dFdx(p);vec3 dp2=dFdy(p);vec2 duv1=dFdx(uv);vec2 duv2=dFdy(uv);vec3 dp2perp=cross(dp2,normal);vec3 dp1perp=cross(normal,dp1);vec3 tangent=dp2perp*duv1.x+dp1perp*duv2.x;vec3 bitangent=dp2perp*duv1.y+dp1perp*duv2.y;tangent*=tangentSpaceParams.x;bitangent*=tangentSpaceParams.y;float det=max(dot(tangent,tangent),dot(bitangent,bitangent));float invmax=det==0.0 ? 0.0 : inversesqrt(det);return mat3(tangent*invmax,bitangent*invmax,normal);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bumpFragmentMainFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nconst name = \"bumpFragmentFunctions\";\nconst shader = `#if defined(BUMP)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_SAMPLERNAME_,bump)\n#endif\n#if defined(DETAIL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_SAMPLERNAME_,detail)\n#endif\n#if defined(BUMP) && defined(PARALLAX)\nconst float minSamples=4.;const float maxSamples=15.;const int iMaxSamples=15;vec2 parallaxOcclusion(vec3 vViewDirCoT,vec3 vNormalCoT,vec2 texCoord,float parallaxScale) {float parallaxLimit=length(vViewDirCoT.xy)/vViewDirCoT.z;parallaxLimit*=parallaxScale;vec2 vOffsetDir=normalize(vViewDirCoT.xy);vec2 vMaxOffset=vOffsetDir*parallaxLimit;float numSamples=maxSamples+(dot(vViewDirCoT,vNormalCoT)*(minSamples-maxSamples));float stepSize=1.0/numSamples;float currRayHeight=1.0;vec2 vCurrOffset=vec2(0,0);vec2 vLastOffset=vec2(0,0);float lastSampledHeight=1.0;float currSampledHeight=1.0;bool keepWorking=true;for (int i=0; i<iMaxSamples; i++)\n{currSampledHeight=texture2D(bumpSampler,texCoord+vCurrOffset).w;if (!keepWorking)\n{}\nelse if (currSampledHeight>currRayHeight)\n{float delta1=currSampledHeight-currRayHeight;float delta2=(currRayHeight+stepSize)-lastSampledHeight;float ratio=delta1/(delta1+delta2);vCurrOffset=(ratio)* vLastOffset+(1.0-ratio)*vCurrOffset;keepWorking=false;}\nelse\n{currRayHeight-=stepSize;vLastOffset=vCurrOffset;\n#ifdef PARALLAX_RHS\nvCurrOffset-=stepSize*vMaxOffset;\n#else\nvCurrOffset+=stepSize*vMaxOffset;\n#endif\nlastSampledHeight=currSampledHeight;}}\nreturn vCurrOffset;}\nvec2 parallaxOffset(vec3 viewDir,float heightScale)\n{float height=texture2D(bumpSampler,vBumpUV).w;vec2 texCoordOffset=heightScale*viewDir.xy*height;\n#ifdef PARALLAX_RHS\nreturn texCoordOffset;\n#else\nreturn -texCoordOffset;\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bumpFragmentFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"decalFragment\";\nconst shader = `#ifdef DECAL\n#ifdef GAMMADECAL\ndecalColor.rgb=toLinearSpace(decalColor.rgb);\n#endif\n#ifdef DECAL_SMOOTHALPHA\ndecalColor.a*=decalColor.a;\n#endif\nsurfaceAlbedo.rgb=mix(surfaceAlbedo.rgb,decalColor.rgb,decalColor.a);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const decalFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./decalFragment\";\nconst name = \"pbrBlockAlbedoOpacity\";\nconst shader = `struct albedoOpacityOutParams\n{vec3 surfaceAlbedo;float alpha;};\n#define pbr_inline\nalbedoOpacityOutParams albedoOpacityBlock(\nin vec4 vAlbedoColor\n#ifdef ALBEDO\n,in vec4 albedoTexture\n,in vec2 albedoInfos\n#endif\n,in float baseWeight\n#ifdef BASE_WEIGHT\n,in vec4 baseWeightTexture\n,in vec2 vBaseWeightInfos\n#endif\n#ifdef OPACITY\n,in vec4 opacityMap\n,in vec2 vOpacityInfos\n#endif\n#ifdef DETAIL\n,in vec4 detailColor\n,in vec4 vDetailInfos\n#endif\n#ifdef DECAL\n,in vec4 decalColor\n,in vec4 vDecalInfos\n#endif\n)\n{albedoOpacityOutParams outParams;vec3 surfaceAlbedo=vAlbedoColor.rgb;float alpha=vAlbedoColor.a;\n#ifdef ALBEDO\n#if defined(ALPHAFROMALBEDO) || defined(ALPHATEST)\nalpha*=albedoTexture.a;\n#endif\n#ifdef GAMMAALBEDO\nsurfaceAlbedo*=toLinearSpace(albedoTexture.rgb);\n#else\nsurfaceAlbedo*=albedoTexture.rgb;\n#endif\nsurfaceAlbedo*=albedoInfos.y;\n#endif\n#ifndef DECAL_AFTER_DETAIL\n#include<decalFragment>\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nsurfaceAlbedo*=vColor.rgb;\n#endif\n#ifdef DETAIL\nfloat detailAlbedo=2.0*mix(0.5,detailColor.r,vDetailInfos.y);surfaceAlbedo.rgb=surfaceAlbedo.rgb*detailAlbedo*detailAlbedo; \n#endif\n#ifdef DECAL_AFTER_DETAIL\n#include<decalFragment>\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALBEDO\nsurfaceAlbedo*=baseWeight;\n#ifdef BASE_WEIGHT\nsurfaceAlbedo*=baseWeightTexture.r;\n#endif\n#ifdef OPACITY\n#ifdef OPACITYRGB\nalpha=getLuminance(opacityMap.rgb);\n#else\nalpha*=opacityMap.a;\n#endif\nalpha*=vOpacityInfos.y;\n#endif\n#if defined(VERTEXALPHA) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nalpha*=vColor.a;\n#endif\n#if !defined(SS_LINKREFRACTIONTOTRANSPARENCY) && !defined(ALPHAFRESNEL)\n#ifdef ALPHATEST\n#if DEBUGMODE != 88\nif (alpha<ALPHATESTVALUE)\ndiscard;\n#endif\n#ifndef ALPHABLEND\nalpha=1.0;\n#endif\n#endif\n#endif\noutParams.surfaceAlbedo=surfaceAlbedo;outParams.alpha=alpha;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAlbedoOpacity = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflectivity\";\nconst shader = `struct reflectivityOutParams\n{float microSurface;float roughness;float diffuseRoughness;float reflectanceF0;vec3 reflectanceF90;vec3 colorReflectanceF0;vec3 colorReflectanceF90;\n#ifdef METALLICWORKFLOW\nvec3 surfaceAlbedo;float metallic;float specularWeight;vec3 dielectricColorF0;\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\nvec3 ambientOcclusionColor;\n#endif\n#if DEBUGMODE>0\n#ifdef METALLICWORKFLOW\n#ifdef REFLECTIVITY\nvec4 surfaceMetallicColorMap;\n#endif\nvec3 metallicF0;\n#else\n#ifdef REFLECTIVITY\nvec4 surfaceReflectivityColorMap;\n#endif\n#endif\n#endif\n};\n#define pbr_inline\nreflectivityOutParams reflectivityBlock(\nin vec4 reflectivityColor\n#ifdef METALLICWORKFLOW\n,in vec3 surfaceAlbedo\n,in vec4 metallicReflectanceFactors\n#endif\n,in float baseDiffuseRoughness\n#ifdef BASE_DIFFUSE_ROUGHNESS\n,in float baseDiffuseRoughnessTexture\n,in vec2 baseDiffuseRoughnessInfos\n#endif\n#ifdef REFLECTIVITY\n,in vec3 reflectivityInfos\n,in vec4 surfaceMetallicOrReflectivityColorMap\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\n,in vec3 ambientOcclusionColorIn\n#endif\n#ifdef MICROSURFACEMAP\n,in vec4 microSurfaceTexel\n#endif\n#ifdef DETAIL\n,in vec4 detailColor\n,in vec4 vDetailInfos\n#endif\n)\n{reflectivityOutParams outParams;float microSurface=reflectivityColor.a;vec3 surfaceReflectivityColor=reflectivityColor.rgb;\n#ifdef METALLICWORKFLOW\nvec2 metallicRoughness=surfaceReflectivityColor.rg;float ior=surfaceReflectivityColor.b;\n#ifdef REFLECTIVITY\n#if DEBUGMODE>0\noutParams.surfaceMetallicColorMap=surfaceMetallicOrReflectivityColorMap;\n#endif\n#ifdef AOSTOREINMETALMAPRED\nvec3 aoStoreInMetalMap=vec3(surfaceMetallicOrReflectivityColorMap.r,surfaceMetallicOrReflectivityColorMap.r,surfaceMetallicOrReflectivityColorMap.r);outParams.ambientOcclusionColor=mix(ambientOcclusionColorIn,aoStoreInMetalMap,reflectivityInfos.z);\n#endif\n#ifdef METALLNESSSTOREINMETALMAPBLUE\nmetallicRoughness.r*=surfaceMetallicOrReflectivityColorMap.b;\n#else\nmetallicRoughness.r*=surfaceMetallicOrReflectivityColorMap.r;\n#endif\n#ifdef ROUGHNESSSTOREINMETALMAPALPHA\nmetallicRoughness.g*=surfaceMetallicOrReflectivityColorMap.a;\n#else\n#ifdef ROUGHNESSSTOREINMETALMAPGREEN\nmetallicRoughness.g*=surfaceMetallicOrReflectivityColorMap.g;\n#endif\n#endif\n#endif\n#ifdef DETAIL\nfloat detailRoughness=mix(0.5,detailColor.b,vDetailInfos.w);float loLerp=mix(0.,metallicRoughness.g,detailRoughness*2.);float hiLerp=mix(metallicRoughness.g,1.,(detailRoughness-0.5)*2.);metallicRoughness.g=mix(loLerp,hiLerp,step(detailRoughness,0.5));\n#endif\n#ifdef MICROSURFACEMAP\nmetallicRoughness.g*=microSurfaceTexel.r;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_METALLICROUGHNESS\nmicroSurface=1.0-metallicRoughness.g;vec3 baseColor=surfaceAlbedo;outParams.metallic=metallicRoughness.r;outParams.specularWeight=metallicReflectanceFactors.a;float dielectricF0=reflectivityColor.a*outParams.specularWeight;surfaceReflectivityColor=metallicReflectanceFactors.rgb;\n#if DEBUGMODE>0\noutParams.metallicF0=vec3(dielectricF0)*surfaceReflectivityColor;\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\noutParams.surfaceAlbedo=baseColor.rgb*(vec3(1.0)-vec3(dielectricF0)*surfaceReflectivityColor)*(1.0-outParams.metallic);\n#else\noutParams.surfaceAlbedo=baseColor.rgb;\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\n{vec3 reflectivityColor=mix(dielectricF0*surfaceReflectivityColor,baseColor.rgb,outParams.metallic);outParams.reflectanceF0=max(reflectivityColor.r,max(reflectivityColor.g,reflectivityColor.b));}\n#else\n#if DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_GLTF\nfloat maxF0=max(surfaceReflectivityColor.r,max(surfaceReflectivityColor.g,surfaceReflectivityColor.b));outParams.reflectanceF0=mix(dielectricF0*maxF0,1.0,outParams.metallic);\n#else\noutParams.reflectanceF0=mix(dielectricF0,1.0,outParams.metallic);\n#endif\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\noutParams.reflectanceF90=vec3(outParams.specularWeight);float f90Scale=1.0;\n#else\nfloat f90Scale=clamp(2.0*(ior-1.0),0.0,1.0);outParams.reflectanceF90=vec3(mix(outParams.specularWeight*f90Scale,1.0,outParams.metallic));\n#endif\noutParams.dielectricColorF0=vec3(dielectricF0*surfaceReflectivityColor);vec3 metallicColorF0=baseColor.rgb;outParams.colorReflectanceF0=mix(outParams.dielectricColorF0,metallicColorF0,outParams.metallic);\n#if (DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_OPENPBR)\nvec3 dielectricColorF90=surfaceReflectivityColor*vec3(outParams.specularWeight)*vec3(f90Scale);\n#else\nvec3 dielectricColorF90=vec3(outParams.specularWeight*f90Scale);\n#endif\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nvec3 conductorColorF90=surfaceReflectivityColor;\n#else\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\nvec3 conductorColorF90=outParams.reflectanceF90;\n#else\nvec3 conductorColorF90=vec3(1.0);\n#endif\n#endif\noutParams.colorReflectanceF90=mix(dielectricColorF90,conductorColorF90,outParams.metallic);\n#else\n#ifdef REFLECTIVITY\nsurfaceReflectivityColor*=surfaceMetallicOrReflectivityColorMap.rgb;\n#if DEBUGMODE>0\noutParams.surfaceReflectivityColorMap=surfaceMetallicOrReflectivityColorMap;\n#endif\n#ifdef MICROSURFACEFROMREFLECTIVITYMAP\nmicroSurface*=surfaceMetallicOrReflectivityColorMap.a;microSurface*=reflectivityInfos.z;\n#else\n#ifdef MICROSURFACEAUTOMATIC\nmicroSurface*=computeDefaultMicroSurface(microSurface,surfaceReflectivityColor);\n#endif\n#ifdef MICROSURFACEMAP\nmicroSurface*=microSurfaceTexel.r;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_MICROSURFACE\n#endif\n#endif\noutParams.colorReflectanceF0=surfaceReflectivityColor;outParams.reflectanceF0=max(surfaceReflectivityColor.r,max(surfaceReflectivityColor.g,surfaceReflectivityColor.b));outParams.reflectanceF90=vec3(1.0);\n#if (DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_OPENPBR)\noutParams.colorReflectanceF90=surfaceReflectivityColor;\n#else\noutParams.colorReflectanceF90=vec3(1.0);\n#endif\n#endif\nmicroSurface=saturate(microSurface);float roughness=1.-microSurface;float diffuseRoughness=baseDiffuseRoughness;\n#ifdef BASE_DIFFUSE_ROUGHNESS\ndiffuseRoughness*=baseDiffuseRoughnessTexture*baseDiffuseRoughnessInfos.y;\n#endif\noutParams.microSurface=microSurface;outParams.roughness=roughness;outParams.diffuseRoughness=diffuseRoughness;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectivity = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockAmbientOcclusion\";\nconst shader = `struct ambientOcclusionOutParams\n{vec3 ambientOcclusionColor;\n#if DEBUGMODE>0 && defined(AMBIENT)\nvec3 ambientOcclusionColorMap;\n#endif\n};ambientOcclusionOutParams ambientOcclusionBlock(\n#ifdef AMBIENT\nin vec3 ambientOcclusionColorMap_,\nin vec4 vAmbientInfos\n#endif\n)\n{ambientOcclusionOutParams outParams;vec3 ambientOcclusionColor=vec3(1.,1.,1.);\n#ifdef AMBIENT\nvec3 ambientOcclusionColorMap=ambientOcclusionColorMap_*vAmbientInfos.y;\n#ifdef AMBIENTINGRAYSCALE\nambientOcclusionColorMap=vec3(ambientOcclusionColorMap.r,ambientOcclusionColorMap.r,ambientOcclusionColorMap.r);\n#endif\nambientOcclusionColor=mix(ambientOcclusionColor,ambientOcclusionColorMap,vAmbientInfos.z);\n#if DEBUGMODE>0\noutParams.ambientOcclusionColorMap=ambientOcclusionColorMap;\n#endif\n#endif\noutParams.ambientOcclusionColor=ambientOcclusionColor;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAmbientOcclusion = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockAlphaFresnel\";\nconst shader = `#ifdef ALPHAFRESNEL\n#if defined(ALPHATEST) || defined(ALPHABLEND)\nstruct alphaFresnelOutParams\n{float alpha;};\n#define pbr_inline\nalphaFresnelOutParams alphaFresnelBlock(\nin vec3 normalW,\nin vec3 viewDirectionW,\nin float alpha,\nin float microSurface\n)\n{alphaFresnelOutParams outParams;float opacityPerceptual=alpha;\n#ifdef LINEARALPHAFRESNEL\nfloat opacity0=opacityPerceptual;\n#else\nfloat opacity0=opacityPerceptual*opacityPerceptual;\n#endif\nfloat opacity90=fresnelGrazingReflectance(opacity0);vec3 normalForward=faceforward(normalW,-viewDirectionW,normalW);outParams.alpha=getReflectanceFromAnalyticalBRDFLookup_Jones(saturate(dot(viewDirectionW,normalForward)),vec3(opacity0),vec3(opacity90),sqrt(microSurface)).x;\n#ifdef ALPHATEST\nif (outParams.alpha<ALPHATESTVALUE)\ndiscard;\n#ifndef ALPHABLEND\noutParams.alpha=1.0;\n#endif\n#endif\nreturn outParams;}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAlphaFresnel = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockAnisotropic\";\nconst shader = `#ifdef ANISOTROPIC\nstruct anisotropicOutParams\n{float anisotropy;vec3 anisotropicTangent;vec3 anisotropicBitangent;vec3 anisotropicNormal;\n#if DEBUGMODE>0 && defined(ANISOTROPIC_TEXTURE)\nvec3 anisotropyMapData;\n#endif\n};\n#define pbr_inline\nanisotropicOutParams anisotropicBlock(\nin vec3 vAnisotropy,\nin float roughness,\n#ifdef ANISOTROPIC_TEXTURE\nin vec3 anisotropyMapData,\n#endif\nin mat3 TBN,\nin vec3 normalW,\nin vec3 viewDirectionW\n)\n{anisotropicOutParams outParams;float anisotropy=vAnisotropy.b;vec3 anisotropyDirection=vec3(vAnisotropy.xy,0.);\n#ifdef ANISOTROPIC_TEXTURE\nanisotropy*=anisotropyMapData.b;\n#if DEBUGMODE>0\noutParams.anisotropyMapData=anisotropyMapData;\n#endif\nanisotropyMapData.rg=anisotropyMapData.rg*2.0-1.0;\n#ifdef ANISOTROPIC_LEGACY\nanisotropyDirection.rg*=anisotropyMapData.rg;\n#else\nanisotropyDirection.xy=mat2(anisotropyDirection.x,anisotropyDirection.y,-anisotropyDirection.y,anisotropyDirection.x)*normalize(anisotropyMapData.rg);\n#endif\n#endif\nmat3 anisoTBN=mat3(normalize(TBN[0]),normalize(TBN[1]),normalize(TBN[2]));vec3 anisotropicTangent=normalize(anisoTBN*anisotropyDirection);vec3 anisotropicBitangent=normalize(cross(anisoTBN[2],anisotropicTangent));outParams.anisotropy=anisotropy;outParams.anisotropicTangent=anisotropicTangent;outParams.anisotropicBitangent=anisotropicBitangent;outParams.anisotropicNormal=getAnisotropicBentNormals(anisotropicTangent,anisotropicBitangent,normalW,viewDirectionW,anisotropy,roughness);return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockAnisotropic = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflection\";\nconst shader = `#ifdef REFLECTION\nstruct reflectionOutParams\n{vec4 environmentRadiance;vec3 environmentIrradiance;\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords;\n#else\nvec2 reflectionCoords;\n#endif\n#ifdef SS_TRANSLUCENCY\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\nvec3 irradianceVector;\n#endif\n#endif\n#endif\n};\n#define pbr_inline\nvoid createReflectionCoords(\nin vec3 vPositionW,\nin vec3 normalW,\n#ifdef ANISOTROPIC\nin anisotropicOutParams anisotropicOut,\n#endif\n#ifdef REFLECTIONMAP_3D\nout vec3 reflectionCoords\n#else\nout vec2 reflectionCoords\n#endif\n)\n{\n#ifdef ANISOTROPIC\nvec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),anisotropicOut.anisotropicNormal);\n#else\nvec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nreflectionCoords=reflectionVector;\n#else\nreflectionCoords=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\n}\n#define pbr_inline\n#define inline\nvoid sampleReflectionTexture(\nin float alphaG,\nin vec3 vReflectionMicrosurfaceInfos,\nin vec2 vReflectionInfos,\nin vec3 vReflectionColor,\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nin float NdotVUnclamped,\n#endif\n#ifdef LINEARSPECULARREFLECTION\nin float roughness,\n#endif\n#ifdef REFLECTIONMAP_3D\nin samplerCube reflectionSampler,\nconst vec3 reflectionCoords,\n#else\nin sampler2D reflectionSampler,\nconst vec2 reflectionCoords,\n#endif\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\nin samplerCube reflectionSamplerLow,\nin samplerCube reflectionSamplerHigh,\n#else\nin sampler2D reflectionSamplerLow,\nin sampler2D reflectionSamplerHigh,\n#endif\n#endif\n#ifdef REALTIME_FILTERING\nin vec2 vReflectionFilteringInfo,\n#endif\nout vec4 environmentRadiance\n)\n{\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG,NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nfloat reflectionLOD=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,roughness);\n#else\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG);\n#endif\n#ifdef LODBASEDMICROSFURACE\nreflectionLOD=reflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\n#ifdef LODINREFLECTIONALPHA\nfloat automaticReflectionLOD=UNPACK_LOD(sampleReflection(reflectionSampler,reflectionCoords).a);float requestedReflectionLOD=max(automaticReflectionLOD,reflectionLOD);\n#else\nfloat requestedReflectionLOD=reflectionLOD;\n#endif\n#ifdef REALTIME_FILTERING\nenvironmentRadiance=vec4(radiance(alphaG,reflectionSampler,reflectionCoords,vReflectionFilteringInfo),1.0);\n#else\nenvironmentRadiance=sampleReflectionLod(reflectionSampler,reflectionCoords,reflectionLOD);\n#endif\n#else\nfloat lodReflectionNormalized=saturate(reflectionLOD/log2(vReflectionMicrosurfaceInfos.x));float lodReflectionNormalizedDoubled=lodReflectionNormalized*2.0;vec4 environmentMid=sampleReflection(reflectionSampler,reflectionCoords);if (lodReflectionNormalizedDoubled<1.0){environmentRadiance=mix(\nsampleReflection(reflectionSamplerHigh,reflectionCoords),\nenvironmentMid,\nlodReflectionNormalizedDoubled\n);} else {environmentRadiance=mix(\nenvironmentMid,\nsampleReflection(reflectionSamplerLow,reflectionCoords),\nlodReflectionNormalizedDoubled-1.0\n);}\n#endif\n#ifdef RGBDREFLECTION\nenvironmentRadiance.rgb=fromRGBD(environmentRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentRadiance.rgb=toLinearSpace(environmentRadiance.rgb);\n#endif\nenvironmentRadiance.rgb*=vReflectionInfos.x;environmentRadiance.rgb*=vReflectionColor.rgb;}\n#define pbr_inline\n#define inline\nreflectionOutParams reflectionBlock(\nin vec3 vPositionW\n,in vec3 normalW\n,in float alphaG\n,in vec3 vReflectionMicrosurfaceInfos\n,in vec2 vReflectionInfos\n,in vec3 vReflectionColor\n#ifdef ANISOTROPIC\n,in anisotropicOutParams anisotropicOut\n#endif\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,in float NdotVUnclamped\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,in float roughness\n#endif\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSampler\n#else\n,in sampler2D reflectionSampler\n#endif\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,in vec3 vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,in mat4 reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n#ifdef REFLECTIONMAP_3D\n,in samplerCube irradianceSampler\n#else\n,in sampler2D irradianceSampler\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,in vec3 reflectionDominantDirection\n#endif\n#endif\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSamplerLow\n,in samplerCube reflectionSamplerHigh\n#else\n,in sampler2D reflectionSamplerLow\n,in sampler2D reflectionSamplerHigh\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,in sampler2D icdfSampler\n#endif\n#endif\n,in vec3 viewDirectionW\n,in float diffuseRoughness\n,in vec3 surfaceAlbedo\n)\n{reflectionOutParams outParams;vec4 environmentRadiance=vec4(0.,0.,0.,0.);\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=vec3(0.);\n#else\nvec2 reflectionCoords=vec2(0.);\n#endif\ncreateReflectionCoords(\nvPositionW,\nnormalW,\n#ifdef ANISOTROPIC\nanisotropicOut,\n#endif\nreflectionCoords\n);sampleReflectionTexture(\nalphaG,\nvReflectionMicrosurfaceInfos,\nvReflectionInfos,\nvReflectionColor,\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nNdotVUnclamped,\n#endif\n#ifdef LINEARSPECULARREFLECTION\nroughness,\n#endif\n#ifdef REFLECTIONMAP_3D\nreflectionSampler,\nreflectionCoords,\n#else\nreflectionSampler,\nreflectionCoords,\n#endif\n#ifndef LODBASEDMICROSFURACE\nreflectionSamplerLow,\nreflectionSamplerHigh,\n#endif\n#ifdef REALTIME_FILTERING\nvReflectionFilteringInfo,\n#endif\nenvironmentRadiance\n);vec3 environmentIrradiance=vec3(0.,0.,0.);\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n#ifdef ANISOTROPIC\nvec3 irradianceVector=vec3(reflectionMatrix*vec4(anisotropicOut.anisotropicNormal,0)).xyz;\n#else\nvec3 irradianceVector=vec3(reflectionMatrix*vec4(normalW,0)).xyz;\n#endif\nvec3 irradianceView=vec3(reflectionMatrix*vec4(viewDirectionW,0)).xyz;\n#if !defined(USE_IRRADIANCE_DOMINANT_DIRECTION) && !defined(REALTIME_FILTERING)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\nfloat NdotV=max(dot(normalW,viewDirectionW),0.0);irradianceVector=mix(irradianceVector,irradianceView,(0.5*(1.0-NdotV))*diffuseRoughness);\n#endif\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;irradianceView.z*=-1.0;\n#endif\n#ifdef INVERTCUBICMAP\nirradianceVector.y*=-1.0;irradianceView.y*=-1.0;\n#endif\n#endif\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\nenvironmentIrradiance=vEnvironmentIrradiance;\n#else\n#if defined(REALTIME_FILTERING)\nenvironmentIrradiance=irradiance(reflectionSampler,irradianceVector,vReflectionFilteringInfo,diffuseRoughness,surfaceAlbedo,irradianceView\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n);\n#else\nenvironmentIrradiance=computeEnvironmentIrradiance(irradianceVector);\n#endif\n#ifdef SS_TRANSLUCENCY\noutParams.irradianceVector=irradianceVector;\n#endif\n#endif\n#elif defined(USEIRRADIANCEMAP)\n#ifdef REFLECTIONMAP_3D\nvec4 environmentIrradiance4=sampleReflection(irradianceSampler,irradianceVector);\n#else\nvec4 environmentIrradiance4=sampleReflection(irradianceSampler,reflectionCoords);\n#endif\nenvironmentIrradiance=environmentIrradiance4.rgb;\n#ifdef RGBDREFLECTION\nenvironmentIrradiance.rgb=fromRGBD(environmentIrradiance4);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentIrradiance.rgb=toLinearSpace(environmentIrradiance.rgb);\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\nvec3 Ls=normalize(reflectionDominantDirection);float NoL=dot(irradianceVector,Ls);float NoV=dot(irradianceVector,irradianceView);vec3 diffuseRoughnessTerm=vec3(1.0);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nfloat LoV=dot (Ls,irradianceView);float mag=length(reflectionDominantDirection)*2.0;vec3 clampedAlbedo=clamp(surfaceAlbedo,vec3(0.1),vec3(1.0));diffuseRoughnessTerm=diffuseBRDF_EON(clampedAlbedo,diffuseRoughness,NoL,NoV,LoV)*PI;diffuseRoughnessTerm=diffuseRoughnessTerm/clampedAlbedo;diffuseRoughnessTerm=mix(vec3(1.0),diffuseRoughnessTerm,sqrt(clamp(mag*NoV,0.0,1.0)));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvec3 H=(irradianceView+Ls)*0.5;float VoH=dot(irradianceView,H);diffuseRoughnessTerm=vec3(diffuseBRDF_Burley(NoL,NoV,VoH,diffuseRoughness)*PI);\n#endif\nenvironmentIrradiance=environmentIrradiance.rgb*diffuseRoughnessTerm;\n#endif\n#endif\nenvironmentIrradiance*=vReflectionColor.rgb*vReflectionInfos.x;\n#ifdef MIX_IBL_RADIANCE_WITH_IRRADIANCE\noutParams.environmentRadiance=vec4(mix(environmentRadiance.rgb,environmentIrradiance,alphaG),environmentRadiance.a);\n#else\noutParams.environmentRadiance=environmentRadiance;\n#endif\noutParams.environmentIrradiance=environmentIrradiance;outParams.reflectionCoords=reflectionCoords;return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflection = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockSheen\";\nconst shader = `#ifdef SHEEN\nstruct sheenOutParams\n{float sheenIntensity;vec3 sheenColor;float sheenRoughness;\n#ifdef SHEEN_LINKWITHALBEDO\nvec3 surfaceAlbedo;\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\nfloat sheenAlbedoScaling;\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\nvec3 finalSheenRadianceScaled;\n#endif\n#if DEBUGMODE>0\n#ifdef SHEEN_TEXTURE\nvec4 sheenMapData;\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\nvec3 sheenEnvironmentReflectance;\n#endif\n#endif\n};\n#define pbr_inline\n#define inline\nsheenOutParams sheenBlock(\nin vec4 vSheenColor\n#ifdef SHEEN_ROUGHNESS\n,in float vSheenRoughness\n#if defined(SHEEN_TEXTURE_ROUGHNESS) && !defined(SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,in vec4 sheenMapRoughnessData\n#endif\n#endif\n,in float roughness\n#ifdef SHEEN_TEXTURE\n,in vec4 sheenMapData\n,in float sheenMapLevel\n#endif\n,in float reflectance\n#ifdef SHEEN_LINKWITHALBEDO\n,in vec3 baseColor\n,in vec3 surfaceAlbedo\n#endif\n#ifdef ENVIRONMENTBRDF\n,in float NdotV\n,in vec3 environmentBrdf\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\n,in vec2 AARoughnessFactors\n,in vec3 vReflectionMicrosurfaceInfos\n,in vec2 vReflectionInfos\n,in vec3 vReflectionColor\n,in vec4 vLightingIntensity\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSampler\n,in vec3 reflectionCoords\n#else\n,in sampler2D reflectionSampler\n,in vec2 reflectionCoords\n#endif\n,in float NdotVUnclamped\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSamplerLow\n,in samplerCube reflectionSamplerHigh\n#else\n,in sampler2D reflectionSamplerLow\n,in sampler2D reflectionSamplerHigh\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vReflectionFilteringInfo\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(RADIANCEOCCLUSION)\n,in float seo\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\n,in float eho\n#endif\n#endif\n)\n{sheenOutParams outParams;float sheenIntensity=vSheenColor.a;\n#ifdef SHEEN_TEXTURE\n#if DEBUGMODE>0\noutParams.sheenMapData=sheenMapData;\n#endif\n#endif\n#ifdef SHEEN_LINKWITHALBEDO\nfloat sheenFactor=pow5(1.0-sheenIntensity);vec3 sheenColor=baseColor.rgb*(1.0-sheenFactor);float sheenRoughness=sheenIntensity;outParams.surfaceAlbedo=surfaceAlbedo*sheenFactor;\n#ifdef SHEEN_TEXTURE\nsheenIntensity*=sheenMapData.a;\n#endif\n#else\nvec3 sheenColor=vSheenColor.rgb;\n#ifdef SHEEN_TEXTURE\n#ifdef SHEEN_GAMMATEXTURE\nsheenColor.rgb*=toLinearSpace(sheenMapData.rgb);\n#else\nsheenColor.rgb*=sheenMapData.rgb;\n#endif\nsheenColor.rgb*=sheenMapLevel;\n#endif\n#ifdef SHEEN_ROUGHNESS\nfloat sheenRoughness=vSheenRoughness;\n#ifdef SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE\n#if defined(SHEEN_TEXTURE)\nsheenRoughness*=sheenMapData.a;\n#endif\n#elif defined(SHEEN_TEXTURE_ROUGHNESS)\nsheenRoughness*=sheenMapRoughnessData.a;\n#endif\n#else\nfloat sheenRoughness=roughness;\n#ifdef SHEEN_TEXTURE\nsheenIntensity*=sheenMapData.a;\n#endif\n#endif\n#if !defined(SHEEN_ALBEDOSCALING)\nsheenIntensity*=(1.-reflectance);\n#endif\nsheenColor*=sheenIntensity;\n#endif\n#ifdef ENVIRONMENTBRDF\n/*#ifdef SHEEN_SOFTER\nvec3 environmentSheenBrdf=vec3(0.,0.,getBRDFLookupCharlieSheen(NdotV,sheenRoughness));\n#else*/\n#ifdef SHEEN_ROUGHNESS\nvec3 environmentSheenBrdf=getBRDFLookup(NdotV,sheenRoughness);\n#else\nvec3 environmentSheenBrdf=environmentBrdf;\n#endif\n/*#endif*/\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\nfloat sheenAlphaG=convertRoughnessToAverageSlope(sheenRoughness);\n#ifdef SPECULARAA\nsheenAlphaG+=AARoughnessFactors.y;\n#endif\nvec4 environmentSheenRadiance=vec4(0.,0.,0.,0.);sampleReflectionTexture(\nsheenAlphaG,\nvReflectionMicrosurfaceInfos,\nvReflectionInfos,\nvReflectionColor,\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nNdotVUnclamped,\n#endif\n#ifdef LINEARSPECULARREFLECTION\nsheenRoughness,\n#endif\nreflectionSampler,\nreflectionCoords,\n#ifndef LODBASEDMICROSFURACE\nreflectionSamplerLow,\nreflectionSamplerHigh,\n#endif\n#ifdef REALTIME_FILTERING\nvReflectionFilteringInfo,\n#endif\nenvironmentSheenRadiance\n);vec3 sheenEnvironmentReflectance=getSheenReflectanceFromBRDFLookup(sheenColor,environmentSheenBrdf);\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(RADIANCEOCCLUSION)\nsheenEnvironmentReflectance*=seo;\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\nsheenEnvironmentReflectance*=eho;\n#endif\n#if DEBUGMODE>0\noutParams.sheenEnvironmentReflectance=sheenEnvironmentReflectance;\n#endif\noutParams.finalSheenRadianceScaled=\nenvironmentSheenRadiance.rgb *\nsheenEnvironmentReflectance *\nvLightingIntensity.z;\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\noutParams.sheenAlbedoScaling=1.0-sheenIntensity*max(max(sheenColor.r,sheenColor.g),sheenColor.b)*environmentSheenBrdf.b;\n#endif\noutParams.sheenIntensity=sheenIntensity;outParams.sheenColor=sheenColor;outParams.sheenRoughness=sheenRoughness;return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockSheen = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockClearcoat\";\nconst shader = `struct clearcoatOutParams\n{vec3 specularEnvironmentR0;float conservationFactor;vec3 clearCoatNormalW;vec2 clearCoatAARoughnessFactors;float clearCoatIntensity;float clearCoatRoughness;\n#ifdef REFLECTION\nvec3 finalClearCoatRadianceScaled;\n#endif\n#ifdef CLEARCOAT_TINT\nvec3 absorption;float clearCoatNdotVRefract;vec3 clearCoatColor;float clearCoatThickness;\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nvec3 energyConservationFactorClearCoat;\n#endif\n#if DEBUGMODE>0\n#ifdef CLEARCOAT_BUMP\nmat3 TBNClearCoat;\n#endif\n#ifdef CLEARCOAT_TEXTURE\nvec2 clearCoatMapData;\n#endif\n#if defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\nvec4 clearCoatTintMapData;\n#endif\n#ifdef REFLECTION\nvec4 environmentClearCoatRadiance;vec3 clearCoatEnvironmentReflectance;\n#endif\nfloat clearCoatNdotV;\n#endif\n};\n#ifdef CLEARCOAT\n#define pbr_inline\n#define inline\nclearcoatOutParams clearcoatBlock(\nin vec3 vPositionW\n,in vec3 geometricNormalW\n,in vec3 viewDirectionW\n,in vec2 vClearCoatParams\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_TEXTURE_ROUGHNESS_IDENTICAL) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,in vec4 clearCoatMapRoughnessData\n#endif\n,in vec3 specularEnvironmentR0\n#ifdef CLEARCOAT_TEXTURE\n,in vec2 clearCoatMapData\n#endif\n#ifdef CLEARCOAT_TINT\n,in vec4 vClearCoatTintParams\n,in float clearCoatColorAtDistance\n,in vec4 vClearCoatRefractionParams\n#ifdef CLEARCOAT_TINT_TEXTURE\n,in vec4 clearCoatTintMapData\n#endif\n#endif\n#ifdef CLEARCOAT_BUMP\n,in vec2 vClearCoatBumpInfos\n,in vec4 clearCoatBumpMapData\n,in vec2 vClearCoatBumpUV\n#if defined(TANGENT) && defined(NORMAL)\n,in mat3 vTBN\n#else\n,in vec2 vClearCoatTangentSpaceParams\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n,in mat4 normalMatrix\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\n,in vec3 faceNormal\n#endif\n#ifdef REFLECTION\n,in vec3 vReflectionMicrosurfaceInfos\n,in vec2 vReflectionInfos\n,in vec3 vReflectionColor\n,in vec4 vLightingIntensity\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSampler\n#else\n,in sampler2D reflectionSampler\n#endif\n#ifndef LODBASEDMICROSFURACE\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSamplerLow\n,in samplerCube reflectionSamplerHigh\n#else\n,in sampler2D reflectionSamplerLow\n,in sampler2D reflectionSamplerHigh\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vReflectionFilteringInfo\n#endif\n#endif\n#if defined(CLEARCOAT_BUMP) || defined(TWOSIDEDLIGHTING)\n,in float frontFacingMultiplier\n#endif\n)\n{clearcoatOutParams outParams;float clearCoatIntensity=vClearCoatParams.x;float clearCoatRoughness=vClearCoatParams.y;\n#ifdef CLEARCOAT_TEXTURE\nclearCoatIntensity*=clearCoatMapData.x;\n#ifdef CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE\nclearCoatRoughness*=clearCoatMapData.y;\n#endif\n#if DEBUGMODE>0\noutParams.clearCoatMapData=clearCoatMapData;\n#endif\n#endif\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\nclearCoatRoughness*=clearCoatMapRoughnessData.y;\n#endif\noutParams.clearCoatIntensity=clearCoatIntensity;outParams.clearCoatRoughness=clearCoatRoughness;\n#ifdef CLEARCOAT_TINT\nvec3 clearCoatColor=vClearCoatTintParams.rgb;float clearCoatThickness=vClearCoatTintParams.a;\n#ifdef CLEARCOAT_TINT_TEXTURE\n#ifdef CLEARCOAT_TINT_GAMMATEXTURE\nclearCoatColor*=toLinearSpace(clearCoatTintMapData.rgb);\n#else\nclearCoatColor*=clearCoatTintMapData.rgb;\n#endif\nclearCoatThickness*=clearCoatTintMapData.a;\n#if DEBUGMODE>0\noutParams.clearCoatTintMapData=clearCoatTintMapData;\n#endif\n#endif\noutParams.clearCoatColor=computeColorAtDistanceInMedia(clearCoatColor,clearCoatColorAtDistance);outParams.clearCoatThickness=clearCoatThickness;\n#endif\n#ifdef CLEARCOAT_REMAP_F0\nvec3 specularEnvironmentR0Updated=getR0RemappedForClearCoat(specularEnvironmentR0);\n#else\nvec3 specularEnvironmentR0Updated=specularEnvironmentR0;\n#endif\noutParams.specularEnvironmentR0=mix(specularEnvironmentR0,specularEnvironmentR0Updated,clearCoatIntensity);vec3 clearCoatNormalW=geometricNormalW;\n#ifdef CLEARCOAT_BUMP\n#ifdef NORMALXYSCALE\nfloat clearCoatNormalScale=1.0;\n#else\nfloat clearCoatNormalScale=vClearCoatBumpInfos.y;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBNClearCoat=vTBN;\n#else\nvec2 TBNClearCoatUV=vClearCoatBumpUV*frontFacingMultiplier;mat3 TBNClearCoat=cotangent_frame(clearCoatNormalW*clearCoatNormalScale,vPositionW,TBNClearCoatUV,vClearCoatTangentSpaceParams);\n#endif\n#if DEBUGMODE>0\noutParams.TBNClearCoat=TBNClearCoat;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nclearCoatNormalW=normalize(clearCoatBumpMapData.xyz *2.0-1.0);clearCoatNormalW=normalize(mat3(normalMatrix)*clearCoatNormalW);\n#else\nclearCoatNormalW=perturbNormal(TBNClearCoat,clearCoatBumpMapData.xyz,vClearCoatBumpInfos.y);\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nclearCoatNormalW*=sign(dot(clearCoatNormalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\nclearCoatNormalW=clearCoatNormalW*frontFacingMultiplier;\n#endif\noutParams.clearCoatNormalW=clearCoatNormalW;outParams.clearCoatAARoughnessFactors=getAARoughnessFactors(clearCoatNormalW.xyz);float clearCoatNdotVUnclamped=dot(clearCoatNormalW,viewDirectionW);float clearCoatNdotV=absEps(clearCoatNdotVUnclamped);\n#if DEBUGMODE>0\noutParams.clearCoatNdotV=clearCoatNdotV;\n#endif\n#ifdef CLEARCOAT_TINT\nvec3 clearCoatVRefract=refract(-viewDirectionW,clearCoatNormalW,vClearCoatRefractionParams.y);outParams.clearCoatNdotVRefract=absEps(dot(clearCoatNormalW,clearCoatVRefract));\n#endif\n#if defined(ENVIRONMENTBRDF) && (!defined(REFLECTIONMAP_SKYBOX) || defined(MS_BRDF_ENERGY_CONSERVATION))\nvec3 environmentClearCoatBrdf=getBRDFLookup(clearCoatNdotV,clearCoatRoughness);\n#endif\n#if defined(REFLECTION)\nfloat clearCoatAlphaG=convertRoughnessToAverageSlope(clearCoatRoughness);\n#ifdef SPECULARAA\nclearCoatAlphaG+=outParams.clearCoatAARoughnessFactors.y;\n#endif\nvec4 environmentClearCoatRadiance=vec4(0.,0.,0.,0.);vec3 clearCoatReflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),clearCoatNormalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nclearCoatReflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nvec3 clearCoatReflectionCoords=clearCoatReflectionVector;\n#else\nvec2 clearCoatReflectionCoords=clearCoatReflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nclearCoatReflectionCoords/=clearCoatReflectionVector.z;\n#endif\nclearCoatReflectionCoords.y=1.0-clearCoatReflectionCoords.y;\n#endif\nsampleReflectionTexture(\nclearCoatAlphaG,\nvReflectionMicrosurfaceInfos,\nvReflectionInfos,\nvReflectionColor,\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nclearCoatNdotVUnclamped,\n#endif\n#ifdef LINEARSPECULARREFLECTION\nclearCoatRoughness,\n#endif\nreflectionSampler,\nclearCoatReflectionCoords,\n#ifndef LODBASEDMICROSFURACE\nreflectionSamplerLow,\nreflectionSamplerHigh,\n#endif\n#ifdef REALTIME_FILTERING\nvReflectionFilteringInfo,\n#endif\nenvironmentClearCoatRadiance\n);\n#if DEBUGMODE>0\noutParams.environmentClearCoatRadiance=environmentClearCoatRadiance;\n#endif\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\nvec3 clearCoatEnvironmentReflectance=getReflectanceFromBRDFLookup(vec3(vClearCoatRefractionParams.x),environmentClearCoatBrdf);\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nfloat clearCoatEho=environmentHorizonOcclusion(-viewDirectionW,clearCoatNormalW,geometricNormalW);clearCoatEnvironmentReflectance*=clearCoatEho;\n#endif\n#endif\n#endif\n#else\nvec3 clearCoatEnvironmentReflectance=getReflectanceFromAnalyticalBRDFLookup_Jones(clearCoatNdotV,vec3(1.),vec3(1.),sqrt(1.-clearCoatRoughness));\n#endif\nclearCoatEnvironmentReflectance*=clearCoatIntensity;\n#if DEBUGMODE>0\noutParams.clearCoatEnvironmentReflectance=clearCoatEnvironmentReflectance;\n#endif\noutParams.finalClearCoatRadianceScaled=\nenvironmentClearCoatRadiance.rgb *\nclearCoatEnvironmentReflectance *\nvLightingIntensity.z;\n#endif\n#if defined(CLEARCOAT_TINT)\noutParams.absorption=computeClearCoatAbsorption(outParams.clearCoatNdotVRefract,outParams.clearCoatNdotVRefract,outParams.clearCoatColor,clearCoatThickness,clearCoatIntensity);\n#endif\nfloat fresnelIBLClearCoat=fresnelSchlickGGX(clearCoatNdotV,vClearCoatRefractionParams.x,CLEARCOATREFLECTANCE90);fresnelIBLClearCoat*=clearCoatIntensity;outParams.conservationFactor=(1.-fresnelIBLClearCoat);\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\noutParams.energyConservationFactorClearCoat=getEnergyConservationFactor(outParams.specularEnvironmentR0,environmentClearCoatBrdf);\n#endif\nreturn outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockClearcoat = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockIridescence\";\nconst shader = `struct iridescenceOutParams\n{float iridescenceIntensity;float iridescenceIOR;float iridescenceThickness;vec3 specularEnvironmentR0;};\n#ifdef IRIDESCENCE\n#define pbr_inline\n#define inline\niridescenceOutParams iridescenceBlock(\nin vec4 vIridescenceParams\n,in float viewAngle\n,in vec3 specularEnvironmentR0\n#ifdef IRIDESCENCE_TEXTURE\n,in vec2 iridescenceMapData\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\n,in vec2 iridescenceThicknessMapData\n#endif\n#ifdef CLEARCOAT\n,in float NdotVUnclamped\n,in vec2 vClearCoatParams\n#ifdef CLEARCOAT_TEXTURE\n,in vec2 clearCoatMapData\n#endif\n#endif\n)\n{iridescenceOutParams outParams;float iridescenceIntensity=vIridescenceParams.x;float iridescenceIOR=vIridescenceParams.y;float iridescenceThicknessMin=vIridescenceParams.z;float iridescenceThicknessMax=vIridescenceParams.w;float iridescenceThicknessWeight=1.;\n#ifdef IRIDESCENCE_TEXTURE\niridescenceIntensity*=iridescenceMapData.x;\n#endif\n#if defined(IRIDESCENCE_THICKNESS_TEXTURE)\niridescenceThicknessWeight=iridescenceThicknessMapData.g;\n#endif\nfloat iridescenceThickness=mix(iridescenceThicknessMin,iridescenceThicknessMax,iridescenceThicknessWeight);float topIor=1.; \n#ifdef CLEARCOAT\nfloat clearCoatIntensity=vClearCoatParams.x;\n#ifdef CLEARCOAT_TEXTURE\nclearCoatIntensity*=clearCoatMapData.x;\n#endif\ntopIor=mix(1.0,vClearCoatRefractionParams.w-1.,clearCoatIntensity);viewAngle=sqrt(1.0+square(1.0/topIor)*(square(NdotVUnclamped)-1.0));\n#endif\nvec3 iridescenceFresnel=evalIridescence(topIor,iridescenceIOR,viewAngle,iridescenceThickness,specularEnvironmentR0);outParams.specularEnvironmentR0=mix(specularEnvironmentR0,iridescenceFresnel,iridescenceIntensity);outParams.iridescenceIntensity=iridescenceIntensity;outParams.iridescenceThickness=iridescenceThickness;outParams.iridescenceIOR=iridescenceIOR;return outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockIridescence = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockSubSurface\";\nconst shader = `struct subSurfaceOutParams\n{vec3 specularEnvironmentReflectance;\n#ifdef SS_REFRACTION\nvec3 finalRefraction;vec3 surfaceAlbedo;\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nfloat alpha;\n#endif\nfloat refractionOpacity;\n#endif\n#ifdef SS_TRANSLUCENCY\nvec3 transmittance;float translucencyIntensity;\n#ifdef REFLECTION\nvec3 refractionIrradiance;\n#endif\n#endif\n#if DEBUGMODE>0\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvec4 thicknessMap;\n#endif\n#ifdef SS_REFRACTION\nvec4 environmentRefraction;vec3 refractionTransmittance;\n#endif\n#endif\n};\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\n#define pbr_inline\n#define inline\nvec4 sampleEnvironmentRefraction(\nin float ior\n,in float thickness\n,in float refractionLOD\n,in vec3 normalW\n,in vec3 vPositionW\n,in vec3 viewDirectionW\n,in mat4 view\n,in vec4 vRefractionInfos\n,in mat4 refractionMatrix\n,in vec4 vRefractionMicrosurfaceInfos\n,in float alphaG\n#ifdef SS_REFRACTIONMAP_3D\n,in samplerCube refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,in samplerCube refractionSamplerLow\n,in samplerCube refractionSamplerHigh\n#endif\n#else\n,in sampler2D refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,in sampler2D refractionSamplerLow\n,in sampler2D refractionSamplerHigh\n#endif\n#endif\n#ifdef ANISOTROPIC\n,in anisotropicOutParams anisotropicOut\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vRefractionFilteringInfo\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,in vec3 refractionPosition\n,in vec3 refractionSize\n#endif\n) {vec4 environmentRefraction=vec4(0.,0.,0.,0.);\n#ifdef ANISOTROPIC\nvec3 refractionVector=refract(-viewDirectionW,anisotropicOut.anisotropicNormal,ior);\n#else\nvec3 refractionVector=refract(-viewDirectionW,normalW,ior);\n#endif\n#ifdef SS_REFRACTIONMAP_OPPOSITEZ\nrefractionVector.z*=-1.0;\n#endif\n#ifdef SS_REFRACTIONMAP_3D\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\nrefractionVector=parallaxCorrectNormal(vPositionW,refractionVector,refractionSize,refractionPosition);\n#endif\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;vec3 refractionCoords=refractionVector;refractionCoords=vec3(refractionMatrix*vec4(refractionCoords,0));\n#else\n#ifdef SS_USE_THICKNESS_AS_DEPTH\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*thickness,1.0)));\n#else\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*vRefractionInfos.z,1.0)));\n#endif\nvec2 refractionCoords=vRefractionUVW.xy/vRefractionUVW.z;refractionCoords.y=1.0-refractionCoords.y;\n#endif\n#ifdef LODBASEDMICROSFURACE\nrefractionLOD=refractionLOD*vRefractionMicrosurfaceInfos.y+vRefractionMicrosurfaceInfos.z;\n#ifdef SS_LODINREFRACTIONALPHA\nfloat automaticRefractionLOD=UNPACK_LOD(sampleRefraction(refractionSampler,refractionCoords).a);float requestedRefractionLOD=max(automaticRefractionLOD,refractionLOD);\n#else\nfloat requestedRefractionLOD=refractionLOD;\n#endif\n#if defined(REALTIME_FILTERING) && defined(SS_REFRACTIONMAP_3D)\nenvironmentRefraction=vec4(radiance(alphaG,refractionSampler,refractionCoords,vRefractionFilteringInfo),1.0);\n#else\nenvironmentRefraction=sampleRefractionLod(refractionSampler,refractionCoords,requestedRefractionLOD);\n#endif\n#else\nfloat lodRefractionNormalized=saturate(refractionLOD/log2(vRefractionMicrosurfaceInfos.x));float lodRefractionNormalizedDoubled=lodRefractionNormalized*2.0;vec4 environmentRefractionMid=sampleRefraction(refractionSampler,refractionCoords);if (lodRefractionNormalizedDoubled<1.0){environmentRefraction=mix(\nsampleRefraction(refractionSamplerHigh,refractionCoords),\nenvironmentRefractionMid,\nlodRefractionNormalizedDoubled\n);} else {environmentRefraction=mix(\nenvironmentRefractionMid,\nsampleRefraction(refractionSamplerLow,refractionCoords),\nlodRefractionNormalizedDoubled-1.0\n);}\n#endif\n#ifdef SS_RGBDREFRACTION\nenvironmentRefraction.rgb=fromRGBD(environmentRefraction);\n#endif\n#ifdef SS_GAMMAREFRACTION\nenvironmentRefraction.rgb=toLinearSpace(environmentRefraction.rgb);\n#endif\nreturn environmentRefraction;}\n#endif\n#define pbr_inline\n#define inline\nsubSurfaceOutParams subSurfaceBlock(\nin vec3 vSubSurfaceIntensity\n,in vec2 vThicknessParam\n,in vec4 vTintColor\n,in vec3 normalW\n,in vec3 vSpecularEnvironmentReflectance\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n,in vec4 thicknessMap\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\n,in vec4 refractionIntensityMap\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\n,in vec4 translucencyIntensityMap\n#endif\n#ifdef REFLECTION\n#ifdef SS_TRANSLUCENCY\n,in mat4 reflectionMatrix\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\n,in vec3 irradianceVector_\n#endif\n#if defined(REALTIME_FILTERING)\n,in samplerCube reflectionSampler\n,in vec2 vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,in sampler2D icdfSampler\n#endif\n#endif\n#endif\n#ifdef USEIRRADIANCEMAP\n#ifdef REFLECTIONMAP_3D\n,in samplerCube irradianceSampler\n#else\n,in sampler2D irradianceSampler\n#endif\n#endif\n#endif\n#endif\n#if defined(SS_REFRACTION) || defined(SS_TRANSLUCENCY)\n,in vec3 surfaceAlbedo\n#endif\n#ifdef SS_REFRACTION\n,in vec3 vPositionW\n,in vec3 viewDirectionW\n,in mat4 view\n,in vec4 vRefractionInfos\n,in mat4 refractionMatrix\n,in vec4 vRefractionMicrosurfaceInfos\n,in vec4 vLightingIntensity\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\n,in float alpha\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\n,in float NdotVUnclamped\n#endif\n#ifdef SS_LINEARSPECULARREFRACTION\n,in float roughness\n#endif\n,in float alphaG\n#ifdef SS_REFRACTIONMAP_3D\n,in samplerCube refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,in samplerCube refractionSamplerLow\n,in samplerCube refractionSamplerHigh\n#endif\n#else\n,in sampler2D refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,in sampler2D refractionSamplerLow\n,in sampler2D refractionSamplerHigh\n#endif\n#endif\n#ifdef ANISOTROPIC\n,in anisotropicOutParams anisotropicOut\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vRefractionFilteringInfo\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,in vec3 refractionPosition\n,in vec3 refractionSize\n#endif\n#ifdef SS_DISPERSION\n,in float dispersion\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\n,in vec3 vDiffusionDistance\n,in vec4 vTranslucencyColor\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\n,in vec4 translucencyColorMap\n#endif\n#endif\n)\n{subSurfaceOutParams outParams;outParams.specularEnvironmentReflectance=vSpecularEnvironmentReflectance;\n#ifdef SS_REFRACTION\nfloat refractionIntensity=vSubSurfaceIntensity.x;\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nrefractionIntensity*=(1.0-alpha);outParams.alpha=1.0;\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\nfloat translucencyIntensity=vSubSurfaceIntensity.y;\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n#ifdef SS_USE_GLTF_TEXTURES\nfloat thickness=thicknessMap.g*vThicknessParam.y+vThicknessParam.x;\n#else\nfloat thickness=thicknessMap.r*vThicknessParam.y+vThicknessParam.x;\n#endif\n#if DEBUGMODE>0\noutParams.thicknessMap=thicknessMap;\n#endif\n#if defined(SS_REFRACTION) && defined(SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS)\n#ifdef SS_USE_GLTF_TEXTURES\nrefractionIntensity*=thicknessMap.r;\n#else\nrefractionIntensity*=thicknessMap.g;\n#endif\n#endif\n#if defined(SS_TRANSLUCENCY) && defined(SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS)\n#ifdef SS_USE_GLTF_TEXTURES\ntranslucencyIntensity*=thicknessMap.a;\n#else\ntranslucencyIntensity*=thicknessMap.b;\n#endif\n#endif\n#else\nfloat thickness=vThicknessParam.y;\n#endif\n#if defined(SS_REFRACTION) && defined(SS_REFRACTIONINTENSITY_TEXTURE)\n#ifdef SS_USE_GLTF_TEXTURES\nrefractionIntensity*=refractionIntensityMap.r;\n#else\nrefractionIntensity*=refractionIntensityMap.g;\n#endif\n#endif\n#if defined(SS_TRANSLUCENCY) && defined(SS_TRANSLUCENCYINTENSITY_TEXTURE)\n#ifdef SS_USE_GLTF_TEXTURES\ntranslucencyIntensity*=translucencyIntensityMap.a;\n#else\ntranslucencyIntensity*=translucencyIntensityMap.b;\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\nthickness=maxEps(thickness);vec4 translucencyColor=vTranslucencyColor;\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\ntranslucencyColor*=translucencyColorMap;\n#endif\nvec3 transmittance=transmittanceBRDF_Burley(translucencyColor.rgb,vDiffusionDistance,thickness);transmittance*=translucencyIntensity;outParams.transmittance=transmittance;outParams.translucencyIntensity=translucencyIntensity;\n#endif\n#ifdef SS_REFRACTION\nvec4 environmentRefraction=vec4(0.,0.,0.,0.);\n#ifdef SS_HAS_THICKNESS\nfloat ior=vRefractionInfos.y;\n#else\nfloat ior=vRefractionMicrosurfaceInfos.w;\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\nfloat refractionAlphaG=alphaG;refractionAlphaG=mix(alphaG,0.0,clamp(ior*3.0-2.0,0.0,1.0));float refractionLOD=getLodFromAlphaG(vRefractionMicrosurfaceInfos.x,refractionAlphaG,NdotVUnclamped);\n#elif defined(SS_LINEARSPECULARREFRACTION)\nfloat refractionRoughness=alphaG;refractionRoughness=mix(alphaG,0.0,clamp(ior*3.0-2.0,0.0,1.0));float refractionLOD=getLinearLodFromRoughness(vRefractionMicrosurfaceInfos.x,refractionRoughness);\n#else\nfloat refractionAlphaG=alphaG;refractionAlphaG=mix(alphaG,0.0,clamp(ior*3.0-2.0,0.0,1.0));float refractionLOD=getLodFromAlphaG(vRefractionMicrosurfaceInfos.x,refractionAlphaG);\n#endif\nfloat refraction_ior=vRefractionInfos.y;\n#ifdef SS_DISPERSION\nfloat realIOR=1.0/refraction_ior;float iorDispersionSpread=0.04*dispersion*(realIOR-1.0);vec3 iors=vec3(1.0/(realIOR-iorDispersionSpread),refraction_ior,1.0/(realIOR+iorDispersionSpread));for (int i=0; i<3; i++) {refraction_ior=iors[i];\n#endif\nvec4 envSample=sampleEnvironmentRefraction(refraction_ior,thickness,refractionLOD,normalW,vPositionW,viewDirectionW,view,vRefractionInfos,refractionMatrix,vRefractionMicrosurfaceInfos,alphaG\n#ifdef SS_REFRACTIONMAP_3D\n,refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,refractionSamplerLow\n,refractionSamplerHigh\n#endif\n#else\n,refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,refractionSamplerLow\n,refractionSamplerHigh\n#endif\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#ifdef REALTIME_FILTERING\n,vRefractionFilteringInfo\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,refractionPosition\n,refractionSize\n#endif\n);\n#ifdef SS_DISPERSION\nenvironmentRefraction[i]=envSample[i];}\n#else\nenvironmentRefraction=envSample;\n#endif\nenvironmentRefraction.rgb*=vRefractionInfos.x;\n#endif\n#ifdef SS_REFRACTION\nvec3 refractionTransmittance=vec3(refractionIntensity);\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvec3 volumeAlbedo=computeColorAtDistanceInMedia(vTintColor.rgb,vTintColor.w);refractionTransmittance*=cocaLambert(volumeAlbedo,thickness);\n#elif defined(SS_LINKREFRACTIONTOTRANSPARENCY)\nfloat maxChannel=max(max(surfaceAlbedo.r,surfaceAlbedo.g),surfaceAlbedo.b);vec3 volumeAlbedo=saturate(maxChannel*surfaceAlbedo);environmentRefraction.rgb*=volumeAlbedo;\n#else\nvec3 volumeAlbedo=computeColorAtDistanceInMedia(vTintColor.rgb,vTintColor.w);refractionTransmittance*=cocaLambert(volumeAlbedo,vThicknessParam.y);\n#endif\n#ifdef SS_ALBEDOFORREFRACTIONTINT\nenvironmentRefraction.rgb*=surfaceAlbedo.rgb;\n#endif\noutParams.surfaceAlbedo=surfaceAlbedo;outParams.refractionOpacity=1.-refractionIntensity;\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\noutParams.surfaceAlbedo*=outParams.refractionOpacity;\n#endif\n#ifdef UNUSED_MULTIPLEBOUNCES\nvec3 bounceSpecularEnvironmentReflectance=(2.0*vSpecularEnvironmentReflectance)/(1.0+vSpecularEnvironmentReflectance);outParams.specularEnvironmentReflectance=mix(bounceSpecularEnvironmentReflectance,vSpecularEnvironmentReflectance,refractionIntensity);\n#endif\n#if DEBUGMODE>0\noutParams.refractionTransmittance=refractionTransmittance;\n#endif\noutParams.finalRefraction=environmentRefraction.rgb*refractionTransmittance*vLightingIntensity.z;outParams.finalRefraction*=vec3(1.0)-vSpecularEnvironmentReflectance;\n#if DEBUGMODE>0\noutParams.environmentRefraction=environmentRefraction;\n#endif\n#endif\n#if defined(REFLECTION) && defined(SS_TRANSLUCENCY)\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX) || !defined(USESPHERICALFROMREFLECTIONMAP)\nvec3 irradianceVector=vec3(reflectionMatrix*vec4(normalW,0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;\n#endif\n#ifdef INVERTCUBICMAP\nirradianceVector.y*=-1.0;\n#endif\n#else\nvec3 irradianceVector=irradianceVector_;\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP)\n#if defined(REALTIME_FILTERING)\nvec3 refractionIrradiance=irradiance(reflectionSampler,-irradianceVector,vReflectionFilteringInfo,0.0,surfaceAlbedo,irradianceVector\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n);\n#else\nvec3 refractionIrradiance=computeEnvironmentIrradiance(-irradianceVector);\n#endif\n#elif defined(USEIRRADIANCEMAP)\n#ifdef REFLECTIONMAP_3D\nvec3 irradianceCoords=irradianceVector;\n#else\nvec2 irradianceCoords=irradianceVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nirradianceCoords/=irradianceVector.z;\n#endif\nirradianceCoords.y=1.0-irradianceCoords.y;\n#endif\nvec4 refractionIrradiance=sampleReflection(irradianceSampler,-irradianceCoords);\n#ifdef RGBDREFLECTION\nrefractionIrradiance.rgb=fromRGBD(refractionIrradiance);\n#endif\n#ifdef GAMMAREFLECTION\nrefractionIrradiance.rgb=toLinearSpace(refractionIrradiance.rgb);\n#endif\n#else\nvec4 refractionIrradiance=vec4(0.);\n#endif\nrefractionIrradiance.rgb*=transmittance;\n#ifdef SS_ALBEDOFORTRANSLUCENCYTINT\nrefractionIrradiance.rgb*=surfaceAlbedo.rgb;\n#endif\noutParams.refractionIrradiance=refractionIrradiance.rgb;\n#endif\nreturn outParams;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockSubSurface = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflectance0\";\nconst shader = `float reflectanceF0=reflectivityOut.reflectanceF0;vec3 specularEnvironmentR0=reflectivityOut.colorReflectanceF0;vec3 specularEnvironmentR90=reflectivityOut.colorReflectanceF90;\n#ifdef ALPHAFRESNEL\nfloat reflectance90=fresnelGrazingReflectance(reflectanceF0);specularEnvironmentR90=specularEnvironmentR90*reflectance90;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectance0 = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./clusteredLightingFunctions\";\nimport \"./pbrBlockReflectance0\";\nconst name = \"pbrClusteredLightingFunctions\";\nconst shader = `#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#include<clusteredLightingFunctions>\n#define inline\nlightingInfo computeClusteredLighting(\nsampler2D lightDataTexture,\nsampler2D tileMaskTexture,\nvec4 lightData,\nivec2 sliceRange,\nvec3 V,\nvec3 N,\nvec3 posW,\nvec3 surfaceAlbedo,\nreflectivityOutParams reflectivityOut\n#ifdef IRIDESCENCE\n,float iridescenceIntensity\n#endif\n#ifdef SS_TRANSLUCENCY\n,subSurfaceOutParams subSurfaceOut\n#endif\n#ifdef SPECULARTERM\n,float AARoughnessFactor\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOutParams anisotropicOut\n#endif\n#ifdef SHEEN\n,sheenOutParams sheenOut\n#endif\n#ifdef CLEARCOAT\n,clearcoatOutParams clearcoatOut\n#endif\n) {float NdotV=absEps(dot(N,V));\n#include<pbrBlockReflectance0>\n#ifdef CLEARCOAT\nspecularEnvironmentR0=clearcoatOut.specularEnvironmentR0;\n#endif\nlightingInfo result;ivec2 tilePosition=ivec2(gl_FragCoord.xy*lightData.xy);int maskHeight=int(lightData.z);tilePosition.y=min(tilePosition.y,maskHeight-1);ivec2 batchRange=sliceRange/CLUSTLIGHT_BATCH;int batchOffset=batchRange.x*CLUSTLIGHT_BATCH;tilePosition.y+=maskHeight*batchRange.x;for (int i=batchRange.x; i<=batchRange.y; i+=1) {uint mask=uint(texelFetch(tileMaskTexture,tilePosition,0).r);tilePosition.y+=maskHeight;int maskOffset=max(sliceRange.x-batchOffset,0);int maskWidth=min(sliceRange.y-batchOffset+1,CLUSTLIGHT_BATCH);mask=extractBits(mask,maskOffset,maskWidth);while (mask != 0u) {uint bit=mask & -mask;mask ^= bit;int position=onlyBitPosition(bit);ClusteredLight light=getClusteredLight(lightDataTexture,batchOffset+maskOffset+position);preLightingInfo preInfo=computePointAndSpotPreLightingInfo(light.vLightData,V,N,posW);preInfo.NdotV=NdotV;preInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light.vLightFalloff.x,light.vLightFalloff.y);if (light.vLightDirection.w>=0.0) {preInfo.attenuation*=computeDirectionalLightFalloff(light.vLightDirection.xyz,preInfo.L,light.vLightDirection.w,light.vLightData.w,light.vLightFalloff.z,light.vLightFalloff.w);}\npreInfo.roughness=adjustRoughnessFromLightProperties(reflectivityOut.roughness,light.vLightSpecular.a,preInfo.lightDistance);preInfo.diffuseRoughness=reflectivityOut.diffuseRoughness;preInfo.surfaceAlbedo=surfaceAlbedo;\n#ifdef IRIDESCENCE\npreInfo.iridescenceIntensity=iridescenceIntensity;\n#endif\nlightingInfo info;\n#ifdef SS_TRANSLUCENCY\n#ifdef SS_TRANSLUCENCY_LEGACY\ninfo.diffuse=computeDiffuseTransmittedLighting(preInfo,light.vLightDiffuse.rgb,subSurfaceOut.transmittance);info.diffuseTransmission=vec3(0);\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,light.vLightDiffuse.rgb)*(1.0-subSurfaceOut.translucencyIntensity);info.diffuseTransmission=computeDiffuseTransmittedLighting(preInfo,light.vLightDiffuse.rgb,subSurfaceOut.transmittance);\n#endif\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,light.vLightDiffuse.rgb);\n#endif\n#ifdef SPECULARTERM\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nvec3 metalFresnel=reflectivityOut.specularWeight*getF82Specular(preInfo.VdotH,specularEnvironmentR0,reflectivityOut.colorReflectanceF90,reflectivityOut.roughness);vec3 dielectricFresnel=fresnelSchlickGGX(preInfo.VdotH,reflectivityOut.dielectricColorF0,reflectivityOut.colorReflectanceF90);vec3 coloredFresnel=mix(dielectricFresnel,metalFresnel,reflectivityOut.metallic);\n#else\nvec3 coloredFresnel=fresnelSchlickGGX(preInfo.VdotH,specularEnvironmentR0,reflectivityOut.colorReflectanceF90);\n#endif\n#ifndef LEGACY_SPECULAR_ENERGY_CONSERVATION\nfloat NdotH=dot(N,preInfo.H);vec3 fresnel=fresnelSchlickGGX(NdotH,vec3(reflectanceF0),specularEnvironmentR90);info.diffuse*=(vec3(1.0)-fresnel);\n#endif\n#ifdef ANISOTROPIC\ninfo.specular=computeAnisotropicSpecularLighting(preInfo,V,N,anisotropicOut.anisotropicTangent,anisotropicOut.anisotropicBitangent,anisotropicOut.anisotropy,specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactor,light.vLightDiffuse.rgb);\n#else\ninfo.specular=computeSpecularLighting(preInfo,N,specularEnvironmentR0,coloredFresnel,AARoughnessFactor,light.vLightDiffuse.rgb);\n#endif\n#endif\n#ifdef SHEEN\n#ifdef SHEEN_LINKWITHALBEDO\npreInfo.roughness=sheenOut.sheenIntensity;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(sheenOut.sheenRoughness,light.vLightSpecular.a,preInfo.lightDistance);\n#endif\ninfo.sheen=computeSheenLighting(preInfo,normalW,sheenOut.sheenColor,specularEnvironmentR90,AARoughnessFactor,light.vLightDiffuse.rgb);\n#endif\n#ifdef CLEARCOAT\npreInfo.roughness=adjustRoughnessFromLightProperties(clearcoatOut.clearCoatRoughness,light.vLightSpecular.a,preInfo.lightDistance);info.clearCoat=computeClearCoatLighting(preInfo,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatAARoughnessFactors.x,clearcoatOut.clearCoatIntensity,light.vLightDiffuse.rgb);\n#ifdef CLEARCOAT_TINT\nfloat absorption=computeClearCoatLightingAbsorption(clearcoatOut.clearCoatNdotVRefract,preInfo.L,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatColor,clearcoatOut.clearCoatThickness,clearcoatOut.clearCoatIntensity);info.diffuse*=absorption;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=absorption;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=absorption;\n#endif\n#endif\ninfo.diffuse*=info.clearCoat.w;\n#ifdef SS_TRANSLUCENCY\ninfo.diffuseTransmission*=info.clearCoat.w;\n#endif\n#ifdef SPECULARTERM\ninfo.specular*=info.clearCoat.w;\n#endif\n#ifdef SHEEN\ninfo.sheen*=info.clearCoat.w;\n#endif\n#endif\nresult.diffuse+=info.diffuse;\n#ifdef SS_TRANSLUCENCY\nresult.diffuseTransmission+=info.diffuseTransmission;\n#endif\n#ifdef SPECULARTERM\nresult.specular+=info.specular;\n#endif\n#ifdef CLEARCOAT\nresult.clearCoat+=info.clearCoat;\n#endif\n#ifdef SHEEN\nresult.sheen+=info.sheen;\n#endif\n}\nbatchOffset+=CLUSTLIGHT_BATCH;}\nreturn result;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrClusteredLightingFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockNormalGeometric\";\nconst shader = `vec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=normalize(cross(dFdx(vPositionW),dFdy(vPositionW)))*vEyePosition.w;\n#endif\nvec3 geometricNormalW=normalW;\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\ngeometricNormalW=gl_FrontFacing ? geometricNormalW : -geometricNormalW;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockNormalGeometric = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"bumpFragment\";\nconst shader = `vec2 uvOffset=vec2(0.0,0.0);\n#if defined(BUMP) || defined(PARALLAX) || defined(DETAIL)\n#ifdef NORMALXYSCALE\nfloat normalScale=1.0;\n#elif defined(BUMP)\nfloat normalScale=vBumpInfos.y;\n#else\nfloat normalScale=1.0;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#elif defined(BUMP)\nvec2 TBNUV=gl_FrontFacing ? vBumpUV : -vBumpUV;mat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,TBNUV,vTangentSpaceParams);\n#else\nvec2 TBNUV=gl_FrontFacing ? vDetailUV : -vDetailUV;mat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,TBNUV,vec2(1.,1.));\n#endif\n#elif defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#else\nvec2 TBNUV=gl_FrontFacing ? vMainUV1 : -vMainUV1;mat3 TBN=cotangent_frame(normalW,vPositionW,TBNUV,vec2(1.,1.));\n#endif\n#endif\n#ifdef PARALLAX\nmat3 invTBN=transposeMat3(TBN);\n#ifdef PARALLAXOCCLUSION\nuvOffset=parallaxOcclusion(invTBN*-viewDirectionW,invTBN*normalW,vBumpUV,vBumpInfos.z);\n#else\nuvOffset=parallaxOffset(invTBN*viewDirectionW,vBumpInfos.z);\n#endif\n#endif\n#ifdef DETAIL\nvec4 detailColor=texture2D(detailSampler,vDetailUV+uvOffset);vec2 detailNormalRG=detailColor.wy*2.0-1.0;float detailNormalB=sqrt(1.-saturate(dot(detailNormalRG,detailNormalRG)));vec3 detailNormal=vec3(detailNormalRG,detailNormalB);\n#endif\n#ifdef BUMP\n#ifdef OBJECTSPACE_NORMALMAP\n#define CUSTOM_FRAGMENT_BUMP_FRAGMENT\nnormalW=normalize(TEXRD(bumpSampler,vBumpUV).xyz *2.0-1.0);normalW=normalize(mat3(normalMatrix)*normalW);\n#elif !defined(DETAIL)\nnormalW=perturbNormal(TBN,TEXRD(bumpSampler,vBumpUV+uvOffset).xyz,vBumpInfos.y);\n#else\nvec3 bumpNormal=TEXRD(bumpSampler,vBumpUV+uvOffset).xyz*2.0-1.0;\n#if DETAIL_NORMALBLENDMETHOD==0 \ndetailNormal.xy*=vDetailInfos.z;vec3 blendedNormal=normalize(vec3(bumpNormal.xy+detailNormal.xy,bumpNormal.z*detailNormal.z));\n#elif DETAIL_NORMALBLENDMETHOD==1 \ndetailNormal.xy*=vDetailInfos.z;bumpNormal+=vec3(0.0,0.0,1.0);detailNormal*=vec3(-1.0,-1.0,1.0);vec3 blendedNormal=bumpNormal*dot(bumpNormal,detailNormal)/bumpNormal.z-detailNormal;\n#endif\nnormalW=perturbNormalBase(TBN,blendedNormal,vBumpInfos.y);\n#endif\n#elif defined(DETAIL)\ndetailNormal.xy*=vDetailInfos.z;normalW=perturbNormalBase(TBN,detailNormal,vDetailInfos.z);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const bumpFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockNormalFinal\";\nconst shader = `#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nvec3 faceNormal=normalize(cross(dFdx(vPositionW),dFdy(vPositionW)))*vEyePosition.w;\n#if defined(TWOSIDEDLIGHTING)\nfaceNormal=gl_FrontFacing ? faceNormal : -faceNormal;\n#endif\nnormalW*=sign(dot(normalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\n#if defined(MIRRORED)\nnormalW=gl_FrontFacing ? -normalW : normalW;\n#else\nnormalW=gl_FrontFacing ? normalW : -normalW;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockNormalFinal = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"depthPrePass\";\nconst shader = `#ifdef DEPTHPREPASS\ngl_FragColor=vec4(0.,0.,0.,1.0);return;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const depthPrePass = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockLightmapInit\";\nconst shader = `#ifdef LIGHTMAP\nvec4 lightmapColor=TEXRD(lightmapSampler,vLightmapUV+uvOffset);\n#ifdef RGBDLIGHTMAP\nlightmapColor.rgb=fromRGBD(lightmapColor);\n#endif\n#ifdef GAMMALIGHTMAP\nlightmapColor.rgb=toLinearSpace(lightmapColor.rgb);\n#endif\nlightmapColor.rgb*=vLightmapInfos.y;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockLightmapInit = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockGeometryInfo\";\nconst shader = `float NdotVUnclamped=dot(normalW,viewDirectionW);float NdotV=absEps(NdotVUnclamped);float alphaG=convertRoughnessToAverageSlope(roughness);vec2 AARoughnessFactors=getAARoughnessFactors(normalW.xyz);\n#ifdef SPECULARAA\nalphaG+=AARoughnessFactors.y;\n#endif\n#if defined(ENVIRONMENTBRDF)\nvec3 environmentBrdf=getBRDFLookup(NdotV,roughness);\n#endif\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\n#ifdef RADIANCEOCCLUSION\n#ifdef AMBIENTINGRAYSCALE\nfloat ambientMonochrome=aoOut.ambientOcclusionColor.r;\n#else\nfloat ambientMonochrome=getLuminance(aoOut.ambientOcclusionColor);\n#endif\nfloat seo=environmentRadianceOcclusion(ambientMonochrome,NdotVUnclamped);\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nfloat eho=environmentHorizonOcclusion(-viewDirectionW,normalW,geometricNormalW);\n#endif\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockGeometryInfo = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockReflectance\";\nconst shader = `#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\nvec3 baseSpecularEnvironmentReflectance=getReflectanceFromBRDFLookup(vec3(reflectanceF0),reflectivityOut.reflectanceF90,environmentBrdf);\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nvec3 metalEnvironmentReflectance=reflectivityOut.specularWeight*getF82Specular(NdotV,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90,reflectivityOut.roughness);vec3 dielectricEnvironmentReflectance=getReflectanceFromBRDFLookup(reflectivityOut.dielectricColorF0,reflectivityOut.colorReflectanceF90,environmentBrdf);vec3 colorSpecularEnvironmentReflectance=mix(dielectricEnvironmentReflectance,metalEnvironmentReflectance,reflectivityOut.metallic);\n#else\nvec3 colorSpecularEnvironmentReflectance=getReflectanceFromBRDFLookup(clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90,environmentBrdf);\n#endif\n#ifdef RADIANCEOCCLUSION\ncolorSpecularEnvironmentReflectance*=seo;\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\ncolorSpecularEnvironmentReflectance*=eho;\n#endif\n#endif\n#endif\n#else\nvec3 colorSpecularEnvironmentReflectance=getReflectanceFromAnalyticalBRDFLookup_Jones(NdotV,clearcoatOut.specularEnvironmentR0,specularEnvironmentR90,sqrt(microSurface));vec3 baseSpecularEnvironmentReflectance=getReflectanceFromAnalyticalBRDFLookup_Jones(NdotV,vec3(reflectanceF0),reflectivityOut.reflectanceF90,sqrt(microSurface));\n#endif\n#ifdef CLEARCOAT\ncolorSpecularEnvironmentReflectance*=clearcoatOut.conservationFactor;\n#if defined(CLEARCOAT_TINT)\ncolorSpecularEnvironmentReflectance*=clearcoatOut.absorption;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockReflectance = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockDirectLighting\";\nconst shader = `vec3 diffuseBase=vec3(0.,0.,0.);\n#ifdef SS_TRANSLUCENCY\nvec3 diffuseTransmissionBase=vec3(0.,0.,0.);\n#endif\n#ifdef SPECULARTERM\nvec3 specularBase=vec3(0.,0.,0.);\n#endif\n#ifdef CLEARCOAT\nvec3 clearCoatBase=vec3(0.,0.,0.);\n#endif\n#ifdef SHEEN\nvec3 sheenBase=vec3(0.,0.,0.);\n#endif\n#if defined(SPECULARTERM) && defined(LIGHT0)\nvec3 coloredFresnel;\n#endif\npreLightingInfo preInfo;lightingInfo info;float shadow=1.; \nfloat aggShadow=0.;float numLights=0.;\n#if defined(CLEARCOAT) && defined(CLEARCOAT_TINT)\nvec3 absorption=vec3(0.);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockDirectLighting = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockFinalLitComponents\";\nconst shader = `aggShadow=aggShadow/numLights;\n#if defined(ENVIRONMENTBRDF)\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nvec3 baseSpecularEnergyConservationFactor=getEnergyConservationFactor(vec3(reflectanceF0),environmentBrdf);vec3 coloredEnergyConservationFactor=getEnergyConservationFactor(clearcoatOut.specularEnvironmentR0,environmentBrdf);\n#endif\n#endif\n#if defined(SHEEN) && defined(SHEEN_ALBEDOSCALING) && defined(ENVIRONMENTBRDF)\nsurfaceAlbedo.rgb=sheenOut.sheenAlbedoScaling*surfaceAlbedo.rgb;\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\n#ifndef METALLICWORKFLOW\n#ifdef SPECULAR_GLOSSINESS_ENERGY_CONSERVATION\nsurfaceAlbedo.rgb=(1.-reflectanceF0)*surfaceAlbedo.rgb;\n#endif\n#endif\n#endif\n#ifdef REFLECTION\nvec3 finalIrradiance=reflectionOut.environmentIrradiance;\n#ifndef LEGACY_SPECULAR_ENERGY_CONSERVATION\n#if defined(METALLICWORKFLOW) || defined(SPECULAR_GLOSSINESS_ENERGY_CONSERVATION)\nvec3 baseSpecularEnergy=vec3(baseSpecularEnvironmentReflectance);\n#if defined(ENVIRONMENTBRDF)\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nbaseSpecularEnergy*=baseSpecularEnergyConservationFactor;\n#endif\n#endif\nfinalIrradiance*=clamp(vec3(1.0)-baseSpecularEnergy,0.0,1.0);\n#endif\n#endif\n#if defined(CLEARCOAT)\nfinalIrradiance*=clearcoatOut.conservationFactor;\n#if defined(CLEARCOAT_TINT)\nfinalIrradiance*=clearcoatOut.absorption;\n#endif\n#endif\n#ifndef SS_APPLY_ALBEDO_AFTER_SUBSURFACE\nfinalIrradiance*=surfaceAlbedo.rgb;\n#endif\n#if defined(SS_REFRACTION) && !defined(LEGACY_SPECULAR_ENERGY_CONSERVATION) \nfinalIrradiance*=subSurfaceOut.refractionOpacity;\n#endif\n#if defined(SS_TRANSLUCENCY)\nfinalIrradiance*=(1.0-subSurfaceOut.translucencyIntensity);finalIrradiance+=subSurfaceOut.refractionIrradiance;\n#endif\n#ifdef SS_APPLY_ALBEDO_AFTER_SUBSURFACE\nfinalIrradiance*=surfaceAlbedo.rgb;\n#endif\nfinalIrradiance*=vLightingIntensity.z;finalIrradiance*=aoOut.ambientOcclusionColor;\n#endif\n#ifdef SPECULARTERM\nvec3 finalSpecular=specularBase;finalSpecular=max(finalSpecular,0.0);vec3 finalSpecularScaled=finalSpecular*vLightingIntensity.x*vLightingIntensity.w;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalSpecularScaled*=coloredEnergyConservationFactor;\n#endif\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\nfinalSpecularScaled*=sheenOut.sheenAlbedoScaling;\n#endif\n#endif\n#ifdef REFLECTION\nvec3 finalRadiance=reflectionOut.environmentRadiance.rgb;finalRadiance*=colorSpecularEnvironmentReflectance;vec3 finalRadianceScaled=finalRadiance*vLightingIntensity.z;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalRadianceScaled*=coloredEnergyConservationFactor;\n#endif\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF) && defined(SHEEN_ALBEDOSCALING)\nfinalRadianceScaled*=sheenOut.sheenAlbedoScaling;\n#endif\n#endif\n#ifdef SHEEN\nvec3 finalSheen=sheenBase*sheenOut.sheenColor;finalSheen=max(finalSheen,0.0);vec3 finalSheenScaled=finalSheen*vLightingIntensity.x*vLightingIntensity.w;\n#if defined(CLEARCOAT) && defined(REFLECTION) && defined(ENVIRONMENTBRDF)\nsheenOut.finalSheenRadianceScaled*=clearcoatOut.conservationFactor;\n#if defined(CLEARCOAT_TINT)\nsheenOut.finalSheenRadianceScaled*=clearcoatOut.absorption;\n#endif\n#endif\n#endif\n#ifdef CLEARCOAT\nvec3 finalClearCoat=clearCoatBase;finalClearCoat=max(finalClearCoat,0.0);vec3 finalClearCoatScaled=finalClearCoat*vLightingIntensity.x*vLightingIntensity.w;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalClearCoatScaled*=clearcoatOut.energyConservationFactorClearCoat;\n#endif\n#ifdef SS_REFRACTION\nsubSurfaceOut.finalRefraction*=clearcoatOut.conservationFactor;\n#ifdef CLEARCOAT_TINT\nsubSurfaceOut.finalRefraction*=clearcoatOut.absorption;\n#endif\n#endif\n#endif\n#ifdef ALPHABLEND\nfloat luminanceOverAlpha=0.0;\n#if defined(REFLECTION) && defined(RADIANCEOVERALPHA)\nluminanceOverAlpha+=getLuminance(finalRadianceScaled);\n#if defined(CLEARCOAT)\nluminanceOverAlpha+=getLuminance(clearcoatOut.finalClearCoatRadianceScaled);\n#endif\n#endif\n#if defined(SPECULARTERM) && defined(SPECULAROVERALPHA)\nluminanceOverAlpha+=getLuminance(finalSpecularScaled);\n#endif\n#if defined(CLEARCOAT) && defined(CLEARCOATOVERALPHA)\nluminanceOverAlpha+=getLuminance(finalClearCoatScaled);\n#endif\n#if defined(RADIANCEOVERALPHA) || defined(SPECULAROVERALPHA) || defined(CLEARCOATOVERALPHA)\nalpha=saturate(alpha+luminanceOverAlpha*luminanceOverAlpha);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockFinalLitComponents = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockFinalUnlitComponents\";\nconst shader = `vec3 finalDiffuse=diffuseBase;finalDiffuse*=surfaceAlbedo;\n#if defined(SS_REFRACTION) && !defined(UNLIT) && !defined(LEGACY_SPECULAR_ENERGY_CONSERVATION)\nfinalDiffuse*=subSurfaceOut.refractionOpacity;\n#endif\n#if defined(SS_TRANSLUCENCY) && !defined(UNLIT)\nfinalDiffuse+=diffuseTransmissionBase;\n#endif\nfinalDiffuse=max(finalDiffuse,0.0);finalDiffuse*=vLightingIntensity.x;vec3 finalAmbient=vAmbientColor;finalAmbient*=surfaceAlbedo.rgb;vec3 finalEmissive=vEmissiveColor;\n#ifdef EMISSIVE\nvec3 emissiveColorTex=TEXRD(emissiveSampler,vEmissiveUV+uvOffset).rgb;\n#ifdef GAMMAEMISSIVE\nfinalEmissive*=toLinearSpace(emissiveColorTex.rgb);\n#else\nfinalEmissive*=emissiveColorTex.rgb;\n#endif\nfinalEmissive*= vEmissiveInfos.y;\n#endif\nfinalEmissive*=vLightingIntensity.y;\n#ifdef AMBIENT\nvec3 ambientOcclusionForDirectDiffuse=mix(vec3(1.),aoOut.ambientOcclusionColor,vAmbientInfos.w);\n#else\nvec3 ambientOcclusionForDirectDiffuse=aoOut.ambientOcclusionColor;\n#endif\nfinalAmbient*=aoOut.ambientOcclusionColor;finalDiffuse*=ambientOcclusionForDirectDiffuse;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockFinalUnlitComponents = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockFinalColorComposition\";\nconst shader = `vec4 finalColor=vec4(\n#ifndef UNLIT\n#ifdef REFLECTION\nfinalIrradiance +\n#endif\n#ifdef SPECULARTERM\nfinalSpecularScaled +\n#endif\n#ifdef SHEEN\nfinalSheenScaled +\n#endif\n#ifdef CLEARCOAT\nfinalClearCoatScaled +\n#endif\n#ifdef REFLECTION\nfinalRadianceScaled +\n#if defined(SHEEN) && defined(ENVIRONMENTBRDF)\nsheenOut.finalSheenRadianceScaled +\n#endif\n#ifdef CLEARCOAT\nclearcoatOut.finalClearCoatRadianceScaled +\n#endif\n#endif\n#ifdef SS_REFRACTION\nsubSurfaceOut.finalRefraction +\n#endif\n#endif\nfinalAmbient +\nfinalDiffuse,\nalpha);\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\nfinalColor.rgb*=lightmapColor.rgb;\n#else\nfinalColor.rgb+=lightmapColor.rgb;\n#endif\n#endif\n#endif\nfinalColor.rgb+=finalEmissive;\n#define CUSTOM_FRAGMENT_BEFORE_FOG\nfinalColor=max(finalColor,0.0);\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockFinalColorComposition = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockImageProcessing\";\nconst shader = `#if defined(IMAGEPROCESSINGPOSTPROCESS) || defined(SS_SCATTERING)\n#if !defined(SKIPFINALCOLORCLAMP)\nfinalColor.rgb=clamp(finalColor.rgb,0.,30.0);\n#endif\n#else\nfinalColor=applyImageProcessing(finalColor);\n#endif\nfinalColor.a*=visibility;\n#ifdef PREMULTIPLYALPHA\nfinalColor.rgb*=finalColor.a;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockImageProcessing = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrBlockPrePass\";\nconst shader = `#if SCENE_MRT_COUNT>0\n#ifdef ALPHATEST\nfloat writeGeometryInfo=1.0;\n#else\nfloat writeGeometryInfo=finalColor.a>ALPHATESTVALUE ? 1.0 : 0.0;\n#endif\n#ifdef PREPASS_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_POSITION_INDEX,vec4(vPositionW,writeGeometryInfo));\n#endif\n#ifdef PREPASS_OBJECT_ID\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_OBJECT_ID_INDEX,encodeObjectId(objectId)*writeGeometryInfo);\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nmeshBlendTagOutput=writeGeometryInfo>0.0 ? uvec4(uint(meshBlendTag),0u,0u,0u) : uvec4(0u);\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_LOCAL_POSITION_INDEX,vec4(vPosition,writeGeometryInfo));\n#endif\n#if defined(PREPASS_VELOCITY)\nvec2 a=(vCurrentPosition.xy/vCurrentPosition.w)*0.5+0.5;vec2 b=(vPreviousPosition.xy/vPreviousPosition.w)*0.5+0.5;vec2 velocity=abs(a-b);velocity=vec2(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;WRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_INDEX,vec4(velocity,0.0,writeGeometryInfo));\n#elif defined(PREPASS_VELOCITY_LINEAR)\nvec2 velocity=vec2(0.5)*((vPreviousPosition.xy/vPreviousPosition.w)-(vCurrentPosition.xy/vCurrentPosition.w));WRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_LINEAR_INDEX,vec4(velocity,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_ALBEDO\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_INDEX,vec4(surfaceAlbedo,writeGeometryInfo));\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nvec3 sqAlbedo=sqrt(surfaceAlbedo); \n#endif\n#ifdef PREPASS_IRRADIANCE_LEGACY\nvec3 irradiance=finalDiffuse;\n#ifndef UNLIT\n#ifdef REFLECTION\nirradiance+=finalIrradiance;\n#endif\n#endif\n#ifdef SS_SCATTERING\n#ifdef PREPASS_COLOR\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_COLOR_INDEX,vec4(finalColor.rgb-irradiance,finalColor.a)); \n#endif\nirradiance/=sqAlbedo;\n#else\n#ifdef PREPASS_COLOR\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_COLOR_INDEX,finalColor); \n#endif\nfloat scatteringDiffusionProfile=255.;\n#endif\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_IRRADIANCE_LEGACY_INDEX,vec4(clamp(irradiance,vec3(0.),vec3(1.)),writeGeometryInfo*scatteringDiffusionProfile/255.)); \n#else\n#ifdef PREPASS_IRRADIANCE\nvec3 irradiance=finalDiffuse;\n#ifndef UNLIT\n#ifdef REFLECTION\nirradiance+=finalIrradiance;\n#endif\n#endif\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_IRRADIANCE_INDEX,vec4(irradiance,writeGeometryInfo));\n#endif\n#if defined(PREPASS_COLOR)\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_COLOR_INDEX,vec4(finalColor.rgb,finalColor.a));\n#endif\n#endif\n#ifdef PREPASS_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_DEPTH_INDEX,vec4(vViewPos.z,0.0,0.0,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_SCREENSPACE_DEPTH_INDEX,vec4(gl_FragCoord.z,0.0,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMALIZED_VIEW_DEPTH_INDEX,vec4(vNormViewDepth,0.0,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_NORMAL\n#ifdef PREPASS_NORMAL_WORLDSPACE\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(normalW,writeGeometryInfo));\n#else\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(normalize((view*vec4(normalW,0.0)).rgb),writeGeometryInfo));\n#endif\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_WORLD_NORMAL_INDEX,vec4(normalW*0.5+0.5,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_SQRT_INDEX,vec4(sqAlbedo,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_REFLECTIVITY\n#ifndef UNLIT\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4(specularEnvironmentR0,microSurface)*writeGeometryInfo);\n#else\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4( 0.0,0.0,0.0,1.0 )*writeGeometryInfo);\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrBlockPrePass = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"oitFragment\";\nconst shader = `#ifdef ORDER_INDEPENDENT_TRANSPARENCY\nfloat fragDepth=gl_FragCoord.z; \n#ifdef ORDER_INDEPENDENT_TRANSPARENCY_16BITS\nuint halfFloat=packHalf2x16(vec2(fragDepth));vec2 full=unpackHalf2x16(halfFloat);fragDepth=full.x;\n#endif\nivec2 fragCoord=ivec2(gl_FragCoord.xy);vec2 lastDepth=texelFetch(oitDepthSampler,fragCoord,0).rg;vec4 lastFrontColor=texelFetch(oitFrontColorSampler,fragCoord,0);depth.rg=vec2(-MAX_DEPTH);frontColor=lastFrontColor;backColor=vec4(0.0);\n#ifdef USE_REVERSE_DEPTHBUFFER\nfloat furthestDepth=-lastDepth.x;float nearestDepth=lastDepth.y;\n#else\nfloat nearestDepth=-lastDepth.x;float furthestDepth=lastDepth.y;\n#endif\nfloat alphaMultiplier=1.0-lastFrontColor.a;\n#ifdef USE_REVERSE_DEPTHBUFFER\nif (fragDepth>nearestDepth || fragDepth<furthestDepth) {\n#else\nif (fragDepth<nearestDepth || fragDepth>furthestDepth) {\n#endif\nreturn;}\n#ifdef USE_REVERSE_DEPTHBUFFER\nif (fragDepth<nearestDepth && fragDepth>furthestDepth) {\n#else\nif (fragDepth>nearestDepth && fragDepth<furthestDepth) {\n#endif\ndepth.rg=vec2(-fragDepth,fragDepth);return;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const oitFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pbrDebug\";\nconst shader = `#if DEBUGMODE>0\nif (vClipSpacePosition.x/vClipSpacePosition.w>=vDebugMode.x) {\n#if DEBUGMODE==1\ngl_FragColor.rgb=vPositionW.rgb;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==2 && defined(NORMAL)\ngl_FragColor.rgb=vNormalW.rgb;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==3 && defined(BUMP) || DEBUGMODE==3 && defined(PARALLAX) || DEBUGMODE==3 && defined(ANISOTROPIC)\ngl_FragColor.rgb=TBN[0];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==4 && defined(BUMP) || DEBUGMODE==4 && defined(PARALLAX) || DEBUGMODE==4 && defined(ANISOTROPIC)\ngl_FragColor.rgb=TBN[1];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==5\ngl_FragColor.rgb=normalW;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==6 && defined(MAINUV1)\ngl_FragColor.rgb=vec3(vMainUV1,0.0);\n#elif DEBUGMODE==7 && defined(MAINUV2)\ngl_FragColor.rgb=vec3(vMainUV2,0.0);\n#elif DEBUGMODE==8 && defined(CLEARCOAT) && defined(CLEARCOAT_BUMP)\ngl_FragColor.rgb=clearcoatOut.TBNClearCoat[0];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==9 && defined(CLEARCOAT) && defined(CLEARCOAT_BUMP)\ngl_FragColor.rgb=clearcoatOut.TBNClearCoat[1];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==10 && defined(CLEARCOAT)\ngl_FragColor.rgb=clearcoatOut.clearCoatNormalW;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==11 && defined(ANISOTROPIC)\ngl_FragColor.rgb=anisotropicOut.anisotropicNormal;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==12 && defined(ANISOTROPIC)\ngl_FragColor.rgb=anisotropicOut.anisotropicTangent;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==13 && defined(ANISOTROPIC)\ngl_FragColor.rgb=anisotropicOut.anisotropicBitangent;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE==20 && defined(ALBEDO)\ngl_FragColor.rgb=albedoTexture.rgb;\n#ifndef GAMMAALBEDO\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==21 && defined(AMBIENT)\ngl_FragColor.rgb=aoOut.ambientOcclusionColorMap.rgb;\n#elif DEBUGMODE==22 && defined(OPACITY)\ngl_FragColor.rgb=opacityMap.rgb;\n#elif DEBUGMODE==23 && defined(EMISSIVE)\ngl_FragColor.rgb=emissiveColorTex.rgb;\n#ifndef GAMMAEMISSIVE\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==24 && defined(LIGHTMAP)\ngl_FragColor.rgb=lightmapColor.rgb;\n#ifndef GAMMALIGHTMAP\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==25 && defined(REFLECTIVITY) && defined(METALLICWORKFLOW)\ngl_FragColor.rgb=reflectivityOut.surfaceMetallicColorMap.rgb;\n#elif DEBUGMODE==26 && defined(REFLECTIVITY) && !defined(METALLICWORKFLOW)\ngl_FragColor.rgb=reflectivityOut.surfaceReflectivityColorMap.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==27 && defined(CLEARCOAT) && defined(CLEARCOAT_TEXTURE)\ngl_FragColor.rgb=vec3(clearcoatOut.clearCoatMapData.rg,0.0);\n#elif DEBUGMODE==28 && defined(CLEARCOAT) && defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\ngl_FragColor.rgb=clearcoatOut.clearCoatTintMapData.rgb;\n#elif DEBUGMODE==29 && defined(SHEEN) && defined(SHEEN_TEXTURE)\ngl_FragColor.rgb=sheenOut.sheenMapData.rgb;\n#elif DEBUGMODE==30 && defined(ANISOTROPIC) && defined(ANISOTROPIC_TEXTURE)\ngl_FragColor.rgb=anisotropicOut.anisotropyMapData.rgb;\n#elif DEBUGMODE==31 && defined(SUBSURFACE) && defined(SS_THICKNESSANDMASK_TEXTURE)\ngl_FragColor.rgb=subSurfaceOut.thicknessMap.rgb;\n#elif DEBUGMODE==32 && defined(BUMP)\ngl_FragColor.rgb=texture2D(bumpSampler,vBumpUV).rgb;\n#elif DEBUGMODE==40 && defined(SS_REFRACTION)\ngl_FragColor.rgb=subSurfaceOut.environmentRefraction.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==41 && defined(REFLECTION)\ngl_FragColor.rgb=reflectionOut.environmentRadiance.rgb;\n#ifndef GAMMAREFLECTION\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==42 && defined(CLEARCOAT) && defined(REFLECTION)\ngl_FragColor.rgb=clearcoatOut.environmentClearCoatRadiance.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==50\ngl_FragColor.rgb=diffuseBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==51 && defined(SPECULARTERM)\ngl_FragColor.rgb=specularBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==52 && defined(CLEARCOAT)\ngl_FragColor.rgb=clearCoatBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==53 && defined(SHEEN)\ngl_FragColor.rgb=sheenBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==54 && defined(REFLECTION)\ngl_FragColor.rgb=reflectionOut.environmentIrradiance.rgb;\n#ifndef GAMMAREFLECTION\n#define DEBUGMODE_GAMMA\n#endif\n#elif DEBUGMODE==60\ngl_FragColor.rgb=surfaceAlbedo.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==61\ngl_FragColor.rgb=clearcoatOut.specularEnvironmentR0;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==62 && defined(METALLICWORKFLOW)\ngl_FragColor.rgb=vec3(reflectivityOut.metallic);\n#elif DEBUGMODE==71 && defined(METALLICWORKFLOW)\ngl_FragColor.rgb=reflectivityOut.metallicF0;\n#elif DEBUGMODE==63\ngl_FragColor.rgb=vec3(roughness);\n#elif DEBUGMODE==64\ngl_FragColor.rgb=vec3(alphaG);\n#elif DEBUGMODE==65\ngl_FragColor.rgb=vec3(NdotV);\n#elif DEBUGMODE==66 && defined(CLEARCOAT) && defined(CLEARCOAT_TINT)\ngl_FragColor.rgb=clearcoatOut.clearCoatColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==67 && defined(CLEARCOAT)\ngl_FragColor.rgb=vec3(clearcoatOut.clearCoatRoughness);\n#elif DEBUGMODE==68 && defined(CLEARCOAT)\ngl_FragColor.rgb=vec3(clearcoatOut.clearCoatNdotV);\n#elif DEBUGMODE==69 && defined(SUBSURFACE) && defined(SS_TRANSLUCENCY)\ngl_FragColor.rgb=subSurfaceOut.transmittance;\n#elif DEBUGMODE==70 && defined(SUBSURFACE) && defined(SS_REFRACTION)\ngl_FragColor.rgb=subSurfaceOut.refractionTransmittance;\n#elif DEBUGMODE==72\ngl_FragColor.rgb=vec3(microSurface);\n#elif DEBUGMODE==73\ngl_FragColor.rgb=vAlbedoColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==74 && !defined(METALLICWORKFLOW)\ngl_FragColor.rgb=vReflectivityColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==75\ngl_FragColor.rgb=vEmissiveColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==80 && defined(RADIANCEOCCLUSION)\ngl_FragColor.rgb=vec3(seo);\n#elif DEBUGMODE==81 && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\ngl_FragColor.rgb=vec3(eho);\n#elif DEBUGMODE==82 && defined(MS_BRDF_ENERGY_CONSERVATION)\ngl_FragColor.rgb=vec3(energyConservationFactor);\n#elif DEBUGMODE==83 && defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\ngl_FragColor.rgb=baseSpecularEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==84 && defined(CLEARCOAT) && defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\ngl_FragColor.rgb=clearcoatOut.clearCoatEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==85 && defined(SHEEN) && defined(REFLECTION)\ngl_FragColor.rgb=sheenOut.sheenEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE==86 && defined(ALPHABLEND)\ngl_FragColor.rgb=vec3(luminanceOverAlpha);\n#elif DEBUGMODE==87\ngl_FragColor.rgb=vec3(alpha);\n#elif DEBUGMODE==88 && defined(ALBEDO)\ngl_FragColor.rgb=vec3(albedoTexture.a);\n#elif DEBUGMODE==89\ngl_FragColor.rgb=aoOut.ambientOcclusionColor.rgb;\n#else\nfloat stripeWidth=30.;float stripePos=floor(gl_FragCoord.x/stripeWidth);float whichColor=mod(stripePos,2.);vec3 color1=vec3(.6,.2,.2);vec3 color2=vec3(.3,.1,.1);gl_FragColor.rgb=mix(color1,color2,whichColor);\n#endif\ngl_FragColor.rgb*=vDebugMode.y;\n#ifdef DEBUGMODE_NORMALIZE\ngl_FragColor.rgb=normalize(gl_FragColor.rgb)*0.5+0.5;\n#endif\n#ifdef DEBUGMODE_GAMMA\ngl_FragColor.rgb=toGammaSpace(gl_FragColor.rgb);\n#endif\ngl_FragColor.a=1.0;\n#ifdef PREPASS\n#if !defined(PREPASS_OBJECT_ID) || PREPASS_OBJECT_ID_INDEX != 0\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(0,toLinearSpace(gl_FragColor)); \n#endif\n#if !defined(PREPASS_OBJECT_ID) || PREPASS_OBJECT_ID_INDEX != 1\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(1,vec4(0.,0.,0.,0.)); \n#endif\n#endif\n#ifdef DEBUGMODE_FORCERETURN\nreturn;\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pbrDebug = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { oitDeclaration } from \"./ShadersInclude/oitDeclaration\";\nimport { decalFragmentDeclaration } from \"./ShadersInclude/decalFragmentDeclaration\";\nimport { pbrFragmentDeclaration } from \"./ShadersInclude/pbrFragmentDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { pbrUboDeclaration } from \"./ShadersInclude/pbrUboDeclaration\";\nimport { mainUVVaryingDeclaration } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { pbrFragmentExtraDeclaration } from \"./ShadersInclude/pbrFragmentExtraDeclaration\";\nimport { lightFragmentDeclaration } from \"./ShadersInclude/lightFragmentDeclaration\";\nimport { lightUboDeclaration } from \"./ShadersInclude/lightUboDeclaration\";\nimport { samplerFragmentDeclaration } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { samplerFragmentAlternateDeclaration } from \"./ShadersInclude/samplerFragmentAlternateDeclaration\";\nimport { pbrFragmentReflectionDeclaration } from \"./ShadersInclude/pbrFragmentReflectionDeclaration\";\nimport { pbrFragmentSamplersDeclaration } from \"./ShadersInclude/pbrFragmentSamplersDeclaration\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { textureRepetitionFunctions } from \"./ShadersInclude/textureRepetitionFunctions\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { subSurfaceScatteringFunctions } from \"./ShadersInclude/subSurfaceScatteringFunctions\";\nimport { importanceSampling } from \"./ShadersInclude/importanceSampling\";\nimport { pbrHelperFunctions } from \"./ShadersInclude/pbrHelperFunctions\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { shadowsFragmentFunctions } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { harmonicsFunctions } from \"./ShadersInclude/harmonicsFunctions\";\nimport { ltcHelperFunctions } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { pbrDirectLightingSetupFunctions } from \"./ShadersInclude/pbrDirectLightingSetupFunctions\";\nimport { pbrDirectLightingFalloffFunctions } from \"./ShadersInclude/pbrDirectLightingFalloffFunctions\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctions } from \"./ShadersInclude/hdrFilteringFunctions\";\nimport { pbrDirectLightingFunctions } from \"./ShadersInclude/pbrDirectLightingFunctions\";\nimport { pbrIBLFunctions } from \"./ShadersInclude/pbrIBLFunctions\";\nimport { bumpFragmentMainFunctions } from \"./ShadersInclude/bumpFragmentMainFunctions\";\nimport { bumpFragmentFunctions } from \"./ShadersInclude/bumpFragmentFunctions\";\nimport { reflectionFunction } from \"./ShadersInclude/reflectionFunction\";\nimport { decalFragment } from \"./ShadersInclude/decalFragment\";\nimport { pbrBlockAlbedoOpacity } from \"./ShadersInclude/pbrBlockAlbedoOpacity\";\nimport { pbrBlockReflectivity } from \"./ShadersInclude/pbrBlockReflectivity\";\nimport { pbrBlockAmbientOcclusion } from \"./ShadersInclude/pbrBlockAmbientOcclusion\";\nimport { pbrBlockAlphaFresnel } from \"./ShadersInclude/pbrBlockAlphaFresnel\";\nimport { pbrBlockAnisotropic } from \"./ShadersInclude/pbrBlockAnisotropic\";\nimport { pbrBlockReflection } from \"./ShadersInclude/pbrBlockReflection\";\nimport { pbrBlockSheen } from \"./ShadersInclude/pbrBlockSheen\";\nimport { pbrBlockClearcoat } from \"./ShadersInclude/pbrBlockClearcoat\";\nimport { pbrBlockIridescence } from \"./ShadersInclude/pbrBlockIridescence\";\nimport { pbrBlockSubSurface } from \"./ShadersInclude/pbrBlockSubSurface\";\nimport { clusteredLightingFunctions } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { pbrBlockReflectance0 } from \"./ShadersInclude/pbrBlockReflectance0\";\nimport { pbrClusteredLightingFunctions } from \"./ShadersInclude/pbrClusteredLightingFunctions\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { pbrBlockNormalGeometric } from \"./ShadersInclude/pbrBlockNormalGeometric\";\nimport { bumpFragment } from \"./ShadersInclude/bumpFragment\";\nimport { pbrBlockNormalFinal } from \"./ShadersInclude/pbrBlockNormalFinal\";\nimport { depthPrePass } from \"./ShadersInclude/depthPrePass\";\nimport { pbrBlockLightmapInit } from \"./ShadersInclude/pbrBlockLightmapInit\";\nimport { pbrBlockGeometryInfo } from \"./ShadersInclude/pbrBlockGeometryInfo\";\nimport { pbrBlockReflectance } from \"./ShadersInclude/pbrBlockReflectance\";\nimport { pbrBlockDirectLighting } from \"./ShadersInclude/pbrBlockDirectLighting\";\nimport { lightFragment } from \"./ShadersInclude/lightFragment\";\nimport { pbrBlockFinalLitComponents } from \"./ShadersInclude/pbrBlockFinalLitComponents\";\nimport { pbrBlockFinalUnlitComponents } from \"./ShadersInclude/pbrBlockFinalUnlitComponents\";\nimport { pbrBlockFinalColorComposition } from \"./ShadersInclude/pbrBlockFinalColorComposition\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { pbrBlockImageProcessing } from \"./ShadersInclude/pbrBlockImageProcessing\";\nimport { pbrBlockPrePass } from \"./ShadersInclude/pbrBlockPrePass\";\nimport { oitFragment } from \"./ShadersInclude/oitFragment\";\nimport { pbrDebug } from \"./ShadersInclude/pbrDebug\";\n\nconst name = \"pbrPixelShader\";\nconst shader = `#define PBR_FRAGMENT_SHADER\n#define CUSTOM_FRAGMENT_EXTENSION\n#if defined(BUMP) || !defined(NORMAL) || defined(FORCENORMALFORWARD) || defined(SPECULARAA) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#ifdef LODBASEDMICROSFURACE\n#extension GL_EXT_shader_texture_lod : enable\n#endif\n#define CUSTOM_FRAGMENT_BEGIN\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#if SCENE_MRT_COUNT>0\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#endif\nprecision highp float;\n#include<oitDeclaration>\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE\n#endif\n#include<__decl__pbrFragment>\n#include<pbrFragmentExtraDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<pbrFragmentSamplersDeclaration>\n#include<imageProcessingDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#include<textureRepetitionFunctions>\n#include<helperFunctions>\n#include<subSurfaceScatteringFunctions>\n#include<importanceSampling>\n#include<pbrHelperFunctions>\n#include<imageProcessingFunctions>\n#include<shadowsFragmentFunctions>\n#include<harmonicsFunctions>\n#include<pbrDirectLightingSetupFunctions>\n#include<pbrDirectLightingFalloffFunctions>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\n#include<pbrDirectLightingFunctions>\n#include<pbrIBLFunctions>\n#include<bumpFragmentMainFunctions>\n#include<bumpFragmentFunctions>\n#ifdef REFLECTION\n#include<reflectionFunction>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#include<pbrBlockAlbedoOpacity>\n#include<pbrBlockReflectivity>\n#include<pbrBlockAmbientOcclusion>\n#include<pbrBlockAlphaFresnel>\n#include<pbrBlockAnisotropic>\n#include<pbrBlockReflection>\n#include<pbrBlockSheen>\n#include<pbrBlockClearcoat>\n#include<pbrBlockIridescence>\n#include<pbrBlockSubSurface>\n#include<pbrClusteredLightingFunctions>\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#include<pbrBlockNormalGeometric>\n#include<bumpFragment>\n#include<pbrBlockNormalFinal>\nalbedoOpacityOutParams albedoOpacityOut;\n#ifdef ALBEDO\nvec4 albedoTexture=TEXRD(albedoSampler,vAlbedoUV+uvOffset);\n#endif\n#ifdef BASE_WEIGHT\nvec4 baseWeightTexture=TEXRD(baseWeightSampler,vBaseWeightUV+uvOffset);\n#endif\n#ifdef OPACITY\nvec4 opacityMap=TEXRD(opacitySampler,vOpacityUV+uvOffset);\n#endif\n#ifdef DECAL\nvec4 decalColor=texture2D(decalSampler,vDecalUV+uvOffset);\n#endif\nalbedoOpacityOut=albedoOpacityBlock(\nvAlbedoColor\n#ifdef ALBEDO\n,albedoTexture\n,vAlbedoInfos\n#endif\n,baseWeight\n#ifdef BASE_WEIGHT\n,baseWeightTexture\n,vBaseWeightInfos\n#endif\n#ifdef OPACITY\n,opacityMap\n,vOpacityInfos\n#endif\n#ifdef DETAIL\n,detailColor\n,vDetailInfos\n#endif\n#ifdef DECAL\n,decalColor\n,vDecalInfos\n#endif\n);vec3 surfaceAlbedo=albedoOpacityOut.surfaceAlbedo;float alpha=albedoOpacityOut.alpha;\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\n#include<depthPrePass>\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\nambientOcclusionOutParams aoOut;\n#ifdef AMBIENT\nvec3 ambientOcclusionColorMap=TEXRD(ambientSampler,vAmbientUV+uvOffset).rgb;\n#endif\naoOut=ambientOcclusionBlock(\n#ifdef AMBIENT\nambientOcclusionColorMap,\nvAmbientInfos\n#endif\n);\n#include<pbrBlockLightmapInit>\n#ifdef UNLIT\nvec3 diffuseBase=vec3(1.,1.,1.);\n#else \nvec3 baseColor=surfaceAlbedo;reflectivityOutParams reflectivityOut;\n#if defined(REFLECTIVITY)\nvec4 surfaceMetallicOrReflectivityColorMap=TEXRD(reflectivitySampler,vReflectivityUV+uvOffset);vec4 baseReflectivity=surfaceMetallicOrReflectivityColorMap;\n#ifndef METALLICWORKFLOW\n#ifdef REFLECTIVITY_GAMMA\nsurfaceMetallicOrReflectivityColorMap=toLinearSpace(surfaceMetallicOrReflectivityColorMap);\n#endif\nsurfaceMetallicOrReflectivityColorMap.rgb*=vReflectivityInfos.y;\n#endif\n#endif\n#if defined(MICROSURFACEMAP)\nvec4 microSurfaceTexel=TEXRD(microSurfaceSampler,vMicroSurfaceSamplerUV+uvOffset)*vMicroSurfaceSamplerInfos.y;\n#endif\n#ifdef METALLICWORKFLOW\nvec4 metallicReflectanceFactors=vMetallicReflectanceFactors;\n#ifdef REFLECTANCE\nvec4 reflectanceFactorsMap=TEXRD(reflectanceSampler,vReflectanceUV+uvOffset);\n#ifdef REFLECTANCE_GAMMA\nreflectanceFactorsMap=toLinearSpace(reflectanceFactorsMap);\n#endif\nmetallicReflectanceFactors.rgb*=reflectanceFactorsMap.rgb;\n#endif\n#ifdef METALLIC_REFLECTANCE\nvec4 metallicReflectanceFactorsMap=TEXRD(metallicReflectanceSampler,vMetallicReflectanceUV+uvOffset);\n#ifdef METALLIC_REFLECTANCE_GAMMA\nmetallicReflectanceFactorsMap=toLinearSpace(metallicReflectanceFactorsMap);\n#endif\n#ifndef METALLIC_REFLECTANCE_USE_ALPHA_ONLY\nmetallicReflectanceFactors.rgb*=metallicReflectanceFactorsMap.rgb;\n#endif\nmetallicReflectanceFactors.a*=metallicReflectanceFactorsMap.a;\n#endif\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nfloat baseDiffuseRoughnessTexture=TEXRD(baseDiffuseRoughnessSampler,vBaseDiffuseRoughnessUV+uvOffset).r;\n#endif\nreflectivityOut=reflectivityBlock(\nvReflectivityColor\n#ifdef METALLICWORKFLOW\n,surfaceAlbedo\n,metallicReflectanceFactors\n#endif\n,baseDiffuseRoughness\n#ifdef BASE_DIFFUSE_ROUGHNESS\n,baseDiffuseRoughnessTexture\n,vBaseDiffuseRoughnessInfos\n#endif\n#ifdef REFLECTIVITY\n,vReflectivityInfos\n,surfaceMetallicOrReflectivityColorMap\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\n,aoOut.ambientOcclusionColor\n#endif\n#ifdef MICROSURFACEMAP\n,microSurfaceTexel\n#endif\n#ifdef DETAIL\n,detailColor\n,vDetailInfos\n#endif\n);float microSurface=reflectivityOut.microSurface;float roughness=reflectivityOut.roughness;float diffuseRoughness=reflectivityOut.diffuseRoughness;\n#ifdef METALLICWORKFLOW\nsurfaceAlbedo=reflectivityOut.surfaceAlbedo;\n#endif\n#if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\naoOut.ambientOcclusionColor=reflectivityOut.ambientOcclusionColor;\n#endif\n#ifdef ALPHAFRESNEL\n#if defined(ALPHATEST) || defined(ALPHABLEND)\nalphaFresnelOutParams alphaFresnelOut;alphaFresnelOut=alphaFresnelBlock(\nnormalW,\nviewDirectionW,\nalpha,\nmicroSurface\n);alpha=alphaFresnelOut.alpha;\n#endif\n#endif\n#include<pbrBlockGeometryInfo>\n#ifdef ANISOTROPIC\nanisotropicOutParams anisotropicOut;\n#ifdef ANISOTROPIC_TEXTURE\nvec3 anisotropyMapData=TEXRD(anisotropySampler,vAnisotropyUV+uvOffset).rgb*vAnisotropyInfos.y;\n#endif\nanisotropicOut=anisotropicBlock(\nvAnisotropy,\nroughness,\n#ifdef ANISOTROPIC_TEXTURE\nanisotropyMapData,\n#endif\nTBN,\nnormalW,\nviewDirectionW\n);\n#endif\n#ifdef REFLECTION\nreflectionOutParams reflectionOut;\n#ifndef USE_CUSTOM_REFLECTION\nreflectionOut=reflectionBlock(\nvPositionW\n,normalW\n,alphaG\n,vReflectionMicrosurfaceInfos\n,vReflectionInfos\n,vReflectionColor\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\n,NdotVUnclamped\n#endif\n#ifdef LINEARSPECULARREFLECTION\n,roughness\n#endif\n,reflectionSampler\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,vReflectionDominantDirection\n#endif\n#endif\n#ifndef LODBASEDMICROSFURACE\n,reflectionSamplerLow\n,reflectionSamplerHigh\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n#endif\n,viewDirectionW\n,diffuseRoughness\n,baseColor\n);\n#else\n#define CUSTOM_REFLECTION\n#endif\n#endif\n#include<pbrBlockReflectance0>\n#ifdef SHEEN\nsheenOutParams sheenOut;\n#ifdef SHEEN_TEXTURE\nvec4 sheenMapData=TEXRD(sheenSampler,vSheenUV+uvOffset);\n#endif\n#if defined(SHEEN_ROUGHNESS) && defined(SHEEN_TEXTURE_ROUGHNESS) && !defined(SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE)\nvec4 sheenMapRoughnessData=TEXRD(sheenRoughnessSampler,vSheenRoughnessUV+uvOffset)*vSheenInfos.w;\n#endif\nsheenOut=sheenBlock(\nvSheenColor\n#ifdef SHEEN_ROUGHNESS\n,vSheenRoughness\n#if defined(SHEEN_TEXTURE_ROUGHNESS) && !defined(SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,sheenMapRoughnessData\n#endif\n#endif\n,roughness\n#ifdef SHEEN_TEXTURE\n,sheenMapData\n,vSheenInfos.y\n#endif\n,reflectanceF0\n#ifdef SHEEN_LINKWITHALBEDO\n,baseColor\n,surfaceAlbedo\n#endif\n#ifdef ENVIRONMENTBRDF\n,NdotV\n,environmentBrdf\n#endif\n#if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\n,AARoughnessFactors\n,vReflectionMicrosurfaceInfos\n,vReflectionInfos\n,vReflectionColor\n,vLightingIntensity\n,reflectionSampler\n,reflectionOut.reflectionCoords\n,NdotVUnclamped\n#ifndef LODBASEDMICROSFURACE\n,reflectionSamplerLow\n,reflectionSamplerHigh\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(RADIANCEOCCLUSION)\n,seo\n#endif\n#if !defined(REFLECTIONMAP_SKYBOX) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(REFLECTIONMAP_3D)\n,eho\n#endif\n#endif\n);\n#ifdef SHEEN_LINKWITHALBEDO\nsurfaceAlbedo=sheenOut.surfaceAlbedo;\n#endif\n#endif\n#ifdef CLEARCOAT\n#ifdef CLEARCOAT_TEXTURE\nvec2 clearCoatMapData=TEXRD(clearCoatSampler,vClearCoatUV+uvOffset).rg*vClearCoatInfos.y;\n#endif\n#endif\n#ifdef IRIDESCENCE\niridescenceOutParams iridescenceOut;\n#ifdef IRIDESCENCE_TEXTURE\nvec2 iridescenceMapData=TEXRD(iridescenceSampler,vIridescenceUV+uvOffset).rg*vIridescenceInfos.y;\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\nvec2 iridescenceThicknessMapData=TEXRD(iridescenceThicknessSampler,vIridescenceThicknessUV+uvOffset).rg*vIridescenceInfos.w;\n#endif\niridescenceOut=iridescenceBlock(\nvIridescenceParams\n,NdotV\n,specularEnvironmentR0\n#ifdef IRIDESCENCE_TEXTURE\n,iridescenceMapData\n#endif\n#ifdef IRIDESCENCE_THICKNESS_TEXTURE\n,iridescenceThicknessMapData\n#endif\n#ifdef CLEARCOAT\n,NdotVUnclamped\n,vClearCoatParams\n#ifdef CLEARCOAT_TEXTURE\n,clearCoatMapData\n#endif\n#endif\n);float iridescenceIntensity=iridescenceOut.iridescenceIntensity;specularEnvironmentR0=iridescenceOut.specularEnvironmentR0;\n#endif\nclearcoatOutParams clearcoatOut;\n#ifdef CLEARCOAT\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\nvec4 clearCoatMapRoughnessData=TEXRD(clearCoatRoughnessSampler,vClearCoatRoughnessUV+uvOffset)*vClearCoatInfos.w;\n#endif\n#if defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\nvec4 clearCoatTintMapData=TEXRD(clearCoatTintSampler,vClearCoatTintUV+uvOffset);\n#endif\n#ifdef CLEARCOAT_BUMP\nvec4 clearCoatBumpMapData=TEXRD(clearCoatBumpSampler,vClearCoatBumpUV+uvOffset);\n#endif\nclearcoatOut=clearcoatBlock(\nvPositionW\n,geometricNormalW\n,viewDirectionW\n,vClearCoatParams\n#if defined(CLEARCOAT_TEXTURE_ROUGHNESS) && !defined(CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE)\n,clearCoatMapRoughnessData\n#endif\n,specularEnvironmentR0\n#ifdef CLEARCOAT_TEXTURE\n,clearCoatMapData\n#endif\n#ifdef CLEARCOAT_TINT\n,vClearCoatTintParams\n,clearCoatColorAtDistance\n,vClearCoatRefractionParams\n#ifdef CLEARCOAT_TINT_TEXTURE\n,clearCoatTintMapData\n#endif\n#endif\n#ifdef CLEARCOAT_BUMP\n,vClearCoatBumpInfos\n,clearCoatBumpMapData\n,vClearCoatBumpUV\n#if defined(TANGENT) && defined(NORMAL)\n,vTBN\n#else\n,vClearCoatTangentSpaceParams\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n,normalMatrix\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\n,faceNormal\n#endif\n#ifdef REFLECTION\n,vReflectionMicrosurfaceInfos\n,vReflectionInfos\n,vReflectionColor\n,vLightingIntensity\n,reflectionSampler\n#ifndef LODBASEDMICROSFURACE\n,reflectionSamplerLow\n,reflectionSamplerHigh\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n#endif\n#if defined(CLEARCOAT_BUMP) || defined(TWOSIDEDLIGHTING)\n,(gl_FrontFacing ? 1. : -1.)\n#endif\n);\n#else\nclearcoatOut.specularEnvironmentR0=specularEnvironmentR0;\n#endif\n#include<pbrBlockReflectance>\nsubSurfaceOutParams subSurfaceOut;\n#ifdef SUBSURFACE\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvec4 thicknessMap=TEXRD(thicknessSampler,vThicknessUV+uvOffset);\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\nvec4 refractionIntensityMap=TEXRD(refractionIntensitySampler,vRefractionIntensityUV+uvOffset);\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\nvec4 translucencyIntensityMap=TEXRD(translucencyIntensitySampler,vTranslucencyIntensityUV+uvOffset);\n#endif\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\nvec4 translucencyColorMap=TEXRD(translucencyColorSampler,vTranslucencyColorUV+uvOffset);\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE_GAMMA\ntranslucencyColorMap=toLinearSpace(translucencyColorMap);\n#endif\n#endif\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\nvec3 vSpecularEnvironmentReflectance=vec3(max(colorSpecularEnvironmentReflectance.r,max(colorSpecularEnvironmentReflectance.g,colorSpecularEnvironmentReflectance.b)));\n#endif\nsubSurfaceOut=subSurfaceBlock(\nvSubSurfaceIntensity\n,vThicknessParam\n,vTintColor\n,normalW\n#ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\n,vSpecularEnvironmentReflectance\n#else\n,baseSpecularEnvironmentReflectance\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n,thicknessMap\n#endif\n#ifdef SS_REFRACTIONINTENSITY_TEXTURE\n,refractionIntensityMap\n#endif\n#ifdef SS_TRANSLUCENCYINTENSITY_TEXTURE\n,translucencyIntensityMap\n#endif\n#ifdef REFLECTION\n#ifdef SS_TRANSLUCENCY\n,reflectionMatrix\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\n,reflectionOut.irradianceVector\n#endif\n#if defined(REALTIME_FILTERING)\n,reflectionSampler\n,vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n#endif\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n#endif\n#endif\n#endif\n#if defined(SS_REFRACTION) || defined(SS_TRANSLUCENCY)\n,surfaceAlbedo\n#endif\n#ifdef SS_REFRACTION\n,vPositionW\n,viewDirectionW\n,view\n,vRefractionInfos\n,refractionMatrix\n,vRefractionMicrosurfaceInfos\n,vLightingIntensity\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\n,alpha\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\n,NdotVUnclamped\n#endif\n#ifdef SS_LINEARSPECULARREFRACTION\n,roughness\n#endif\n,alphaG\n,refractionSampler\n#ifndef LODBASEDMICROSFURACE\n,refractionSamplerLow\n,refractionSamplerHigh\n#endif\n#ifdef ANISOTROPIC\n,anisotropicOut\n#endif\n#ifdef REALTIME_FILTERING\n,vRefractionFilteringInfo\n#endif\n#ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\n,vRefractionPosition\n,vRefractionSize\n#endif\n#ifdef SS_DISPERSION\n,dispersion\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\n,vDiffusionDistance\n,vTranslucencyColor\n#ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\n,translucencyColorMap\n#endif\n#endif\n);\n#ifdef SS_REFRACTION\nsurfaceAlbedo=subSurfaceOut.surfaceAlbedo;\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nalpha=subSurfaceOut.alpha;\n#endif\n#endif\n#else\nsubSurfaceOut.specularEnvironmentReflectance=colorSpecularEnvironmentReflectance;\n#endif\n#include<pbrBlockDirectLighting>\n#include<lightFragment>[0..maxSimultaneousLights]\n#include<pbrBlockFinalLitComponents>\n#endif \n#include<pbrBlockFinalUnlitComponents>\n#define CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION\n#include<pbrBlockFinalColorComposition>\n#include<logDepthFragment>\n#include<fogFragment>(color,finalColor)\n#include<pbrBlockImageProcessing>\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\n#include<pbrBlockPrePass>\n#endif\n#if !defined(PREPASS) || defined(WEBGL2)\ngl_FragColor=finalColor;\n#endif\n#include<oitFragment>\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {frontColor.rgb+=finalColor.rgb*finalColor.a*alphaMultiplier;frontColor.a=1.0-alphaMultiplier*(1.0-finalColor.a);} else {backColor+=finalColor;}\n#endif\n#include<pbrDebug>\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [objectIdFunctions, prePassDeclaration, oitDeclaration, decalFragmentDeclaration, pbrFragmentDeclaration, sceneUboDeclaration, meshUboDeclaration, pbrUboDeclaration, mainUVVaryingDeclaration, pbrFragmentExtraDeclaration, lightFragmentDeclaration, lightUboDeclaration, samplerFragmentDeclaration, samplerFragmentAlternateDeclaration, pbrFragmentReflectionDeclaration, pbrFragmentSamplersDeclaration, imageProcessingDeclaration, clipPlaneFragmentDeclaration, logDepthDeclaration, fogFragmentDeclaration, textureRepetitionFunctions, helperFunctions, subSurfaceScatteringFunctions, importanceSampling, pbrHelperFunctions, imageProcessingFunctions, shadowsFragmentFunctions, harmonicsFunctions, ltcHelperFunctions, pbrDirectLightingSetupFunctions, pbrDirectLightingFalloffFunctions, pbrBRDFFunctions, hdrFilteringFunctions, pbrDirectLightingFunctions, pbrIBLFunctions, bumpFragmentMainFunctions, bumpFragmentFunctions, reflectionFunction, decalFragment, pbrBlockAlbedoOpacity, pbrBlockReflectivity, pbrBlockAmbientOcclusion, pbrBlockAlphaFresnel, pbrBlockAnisotropic, pbrBlockReflection, pbrBlockSheen, pbrBlockClearcoat, pbrBlockIridescence, pbrBlockSubSurface, clusteredLightingFunctions, pbrBlockReflectance0, pbrClusteredLightingFunctions, clipPlaneFragment, pbrBlockNormalGeometric, bumpFragment, pbrBlockNormalFinal, depthPrePass, pbrBlockLightmapInit, pbrBlockGeometryInfo, pbrBlockReflectance, pbrBlockDirectLighting, lightFragment, pbrBlockFinalLitComponents, pbrBlockFinalUnlitComponents, pbrBlockFinalColorComposition, logDepthFragment, fogFragment, pbrBlockImageProcessing, pbrBlockPrePass, oitFragment, pbrDebug];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const pbrPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"openpbrUboDeclaration\";\nconst shader = `uniform vTangentSpaceParams: vec2f;uniform vLightingIntensity: vec4f;uniform pointSize: f32;uniform vDebugMode: vec2f;uniform renderTargetSize: vec2f;uniform cameraInfo: vec4f;uniform vTextureRepetitionHexTilingParams: vec4f;uniform backgroundRefractionMatrix: mat4x4f;uniform vBackgroundRefractionInfos: vec3f;uniform vReflectionInfos: vec2f;uniform reflectionMatrix: mat4x4f;uniform vReflectionMicrosurfaceInfos: vec3f;uniform vReflectionPosition: vec3f;uniform vReflectionSize: vec3f;uniform vReflectionFilteringInfo: vec2f;uniform vReflectionDominantDirection: vec3f;uniform vReflectionColor: vec3f;uniform vSphericalL00: vec3f;uniform vSphericalL1_1: vec3f;uniform vSphericalL10: vec3f;uniform vSphericalL11: vec3f;uniform vSphericalL2_2: vec3f;uniform vSphericalL2_1: vec3f;uniform vSphericalL20: vec3f;uniform vSphericalL21: vec3f;uniform vSphericalL22: vec3f;uniform vSphericalX: vec3f;uniform vSphericalY: vec3f;uniform vSphericalZ: vec3f;uniform vSphericalXX_ZZ: vec3f;uniform vSphericalYY_ZZ: vec3f;uniform vSphericalZZ: vec3f;uniform vSphericalXY: vec3f;uniform vSphericalYZ: vec3f;uniform vSphericalZX: vec3f;uniform vBaseWeight: f32;uniform vBaseColor: vec4f;uniform vBaseDiffuseRoughness: f32;uniform vReflectanceInfo: vec4f;uniform vSpecularColor: vec4f;uniform vSpecularAnisotropy: vec3f;uniform vTransmissionWeight : f32;uniform vTransmissionColor : vec3f;uniform vTransmissionDepth : f32;uniform vTransmissionScatter : vec3f;uniform vTransmissionScatterAnisotropy : f32;uniform vTransmissionDispersionScale : f32;uniform vTransmissionDispersionAbbeNumber : f32;uniform vSubsurfaceWeight: f32;uniform vSubsurfaceColor: vec3f;uniform vSubsurfaceRadius: f32;uniform vSubsurfaceRadiusScale: vec3f;uniform vSubsurfaceScatterAnisotropy: f32;uniform vCoatWeight: f32;uniform vCoatColor: vec3f;uniform vCoatRoughness: f32;uniform vCoatRoughnessAnisotropy: f32;uniform vCoatIor: f32;uniform vCoatDarkening : f32;uniform vFuzzWeight: f32;uniform vFuzzColor: vec3f;uniform vFuzzRoughness: f32;uniform vGeometryThinWalled: f32;uniform vGeometryCoatTangent: vec2f;uniform vGeometryThickness: f32;uniform vEmissionColor: vec3f;uniform vThinFilmWeight: f32;uniform vThinFilmThickness: vec2f;uniform vThinFilmIor: f32;uniform vBaseWeightInfos: vec2f;uniform baseWeightMatrix: mat4x4f;uniform vBaseColorInfos: vec2f;uniform baseColorMatrix: mat4x4f;uniform vBaseDiffuseRoughnessInfos: vec2f;uniform baseDiffuseRoughnessMatrix: mat4x4f;uniform vBaseMetalnessInfos: vec2f;uniform baseMetalnessMatrix: mat4x4f;uniform vSpecularWeightInfos: vec2f;uniform specularWeightMatrix: mat4x4f;uniform vSpecularColorInfos: vec2f;uniform specularColorMatrix: mat4x4f;uniform vSpecularRoughnessInfos: vec2f;uniform specularRoughnessMatrix: mat4x4f;uniform vSpecularRoughnessAnisotropyInfos: vec2f;uniform specularRoughnessAnisotropyMatrix: mat4x4f;uniform vTransmissionWeightInfos : vec2f;uniform transmissionWeightMatrix : mat4x4f;uniform vTransmissionColorInfos : vec2f;uniform transmissionColorMatrix : mat4x4f;uniform vTransmissionDepthInfos : vec2f;uniform transmissionDepthMatrix : mat4x4f;uniform vTransmissionScatterInfos : vec2f;uniform transmissionScatterMatrix : mat4x4f;uniform vTransmissionDispersionScaleInfos : vec2f;uniform transmissionDispersionScaleMatrix : mat4x4f;uniform vSubsurfaceWeightInfos: vec2f;uniform subsurfaceWeightMatrix: mat4x4f;uniform vSubsurfaceColorInfos: vec2f;uniform subsurfaceColorMatrix: mat4x4f;uniform vSubsurfaceRadiusScaleInfos: vec2f;uniform subsurfaceRadiusScaleMatrix: mat4x4f;uniform vCoatWeightInfos: vec2f;uniform coatWeightMatrix: mat4x4f;uniform vCoatColorInfos: vec2f;uniform coatColorMatrix: mat4x4f;uniform vCoatRoughnessInfos: vec2f;uniform coatRoughnessMatrix: mat4x4f;uniform vCoatRoughnessAnisotropyInfos: vec2f;uniform coatRoughnessAnisotropyMatrix: mat4x4f;uniform vCoatDarkeningInfos : vec2f;uniform coatDarkeningMatrix : mat4x4f;uniform vFuzzWeightInfos: vec2f;uniform fuzzWeightMatrix: mat4x4f;uniform vFuzzColorInfos: vec2f;uniform fuzzColorMatrix: mat4x4f;uniform vFuzzRoughnessInfos: vec2f;uniform fuzzRoughnessMatrix: mat4x4f;uniform vGeometryNormalInfos: vec2f;uniform geometryNormalMatrix: mat4x4f;uniform vGeometryTangentInfos: vec2f;uniform geometryTangentMatrix: mat4x4f;uniform vGeometryCoatNormalInfos: vec2f;uniform geometryCoatNormalMatrix: mat4x4f;uniform vGeometryCoatTangentInfos: vec2f;uniform geometryCoatTangentMatrix: mat4x4f;uniform vGeometryOpacityInfos: vec2f;uniform geometryOpacityMatrix: mat4x4f;uniform vGeometryThicknessInfos: vec2f;uniform geometryThicknessMatrix: mat4x4f;uniform vEmissionColorInfos: vec2f;uniform emissionColorMatrix: mat4x4f;uniform vThinFilmWeightInfos: vec2f;uniform thinFilmWeightMatrix: mat4x4f;uniform vThinFilmThicknessInfos: vec2f;uniform thinFilmThicknessMatrix: mat4x4f;uniform vAmbientOcclusionInfos: vec2f;uniform ambientOcclusionMatrix: mat4x4f;\n#define ADDITIONAL_UBO_DECLARATION\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapVertexDeclaration\";\nconst shader = `#if defined(GEOMETRY_NORMAL) || defined(PARALLAX) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC) || defined(FUZZ)\n#if defined(TANGENT) && defined(NORMAL) \nvarying vTBN0: vec3f;varying vTBN1: vec3f;varying vTBN2: vec3f;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapVertex\";\nconst shader = `#if defined(GEOMETRY_NORMAL) || defined(PARALLAX) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC) || defined(FUZZ)\n#if defined(TANGENT) && defined(NORMAL)\nvar tbnNormal: vec3f=normalize(normalUpdated);var tbnTangent: vec3f=normalize(tangentUpdated.xyz);var tbnBitangent: vec3f=cross(tbnNormal,tbnTangent)*tangentUpdated.w;var matTemp= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz)* mat3x3f(tbnTangent,tbnBitangent,tbnNormal);vertexOutputs.vTBN0=matTemp[0];vertexOutputs.vTBN1=matTemp[1];vertexOutputs.vTBN2=matTemp[2];\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { openpbrUboDeclarationWGSL } from \"./ShadersInclude/openpbrUboDeclaration\";\nimport { uvAttributeDeclarationWGSL } from \"./ShadersInclude/uvAttributeDeclaration\";\nimport { mainUVVaryingDeclarationWGSL } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { prePassVertexDeclarationWGSL } from \"./ShadersInclude/prePassVertexDeclaration\";\nimport { samplerVertexDeclarationWGSL } from \"./ShadersInclude/samplerVertexDeclaration\";\nimport { harmonicsFunctionsWGSL } from \"./ShadersInclude/harmonicsFunctions\";\nimport { openpbrNormalMapVertexDeclarationWGSL } from \"./ShadersInclude/openpbrNormalMapVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxUboDeclarationWGSL } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { vertexPullingDeclarationWGSL } from \"./ShadersInclude/vertexPullingDeclaration\";\nimport { vertexPullingVertexWGSL } from \"./ShadersInclude/vertexPullingVertex\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { prePassVertexWGSL } from \"./ShadersInclude/prePassVertex\";\nimport { uvVariableDeclarationWGSL } from \"./ShadersInclude/uvVariableDeclaration\";\nimport { samplerVertexImplementationWGSL } from \"./ShadersInclude/samplerVertexImplementation\";\nimport { openpbrNormalMapVertexWGSL } from \"./ShadersInclude/openpbrNormalMapVertex\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertexWGSL } from \"./ShadersInclude/shadowsVertex\";\nimport { vertexColorMixingWGSL } from \"./ShadersInclude/vertexColorMixing\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"openpbrVertexShader\";\nconst shader = `#define OPENPBR_VERTEX_SHADER\n#include<openpbrUboDeclaration>\n#define CUSTOM_VERTEX_BEGIN\n#ifndef USE_VERTEX_PULLING\nattribute position: vec3f;\n#ifdef NORMAL\nattribute normal: vec3f;\n#endif\n#ifdef TANGENT\nattribute tangent: vec4f;\n#endif\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#include<uvAttributeDeclaration>[2..7]\n#ifdef VERTEXCOLOR\nattribute color: vec4f;\n#endif\n#endif\n#include<mainUVVaryingDeclaration>[1..7]\n#include<helperFunctions>\n#include<pbrBRDFFunctions>\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<prePassVertexDeclaration>\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_COLOR,_VARYINGNAME_,BaseColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_METALNESS,_VARYINGNAME_,BaseMetalness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_WEIGHT,_VARYINGNAME_,SpecularWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_COLOR,_VARYINGNAME_,SpecularColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS,_VARYINGNAME_,SpecularRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,SpecularRoughnessAnisotropy)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_COLOR,_VARYINGNAME_,TransmissionColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_DEPTH,_VARYINGNAME_,TransmissionDepth)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_SCATTER,_VARYINGNAME_,TransmissionScatter)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_DISPERSION_SCALE,_VARYINGNAME_,TransmissionDispersionScale)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SUBSURFACE_COLOR,_VARYINGNAME_,SubsurfaceColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SUBSURFACE_RADIUS_SCALE,_VARYINGNAME_,SubsurfaceRadiusScale)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_WEIGHT,_VARYINGNAME_,CoatWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_COLOR,_VARYINGNAME_,CoatColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_ROUGHNESS,_VARYINGNAME_,CoatRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,CoatRoughnessAnisotropy)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_DARKENING,_VARYINGNAME_,CoatDarkening)\n#include<samplerVertexDeclaration>(_DEFINENAME_,FUZZ_WEIGHT,_VARYINGNAME_,FuzzWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,FUZZ_COLOR,_VARYINGNAME_,FuzzColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,FUZZ_ROUGHNESS,_VARYINGNAME_,FuzzRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_NORMAL,_VARYINGNAME_,GeometryNormal)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_TANGENT,_VARYINGNAME_,GeometryTangent)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_COAT_NORMAL,_VARYINGNAME_,GeometryCoatNormal)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_OPACITY,_VARYINGNAME_,GeometryOpacity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_THICKNESS,_VARYINGNAME_,GeometryThickness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,EMISSION_COLOR,_VARYINGNAME_,EmissionColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,THIN_FILM_WEIGHT,_VARYINGNAME_,ThinFilmWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,THIN_FILM_THICKNESS,_VARYINGNAME_,ThinFilmThickness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,AMBIENT_OCCLUSION,_VARYINGNAME_,AmbientOcclusion)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail)\nvarying vPositionW: vec3f;\n#if DEBUGMODE>0\nvarying vClipSpacePosition: vec4f;\n#endif\n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vEnvironmentIrradiance: vec3f;\n#include<harmonicsFunctions>\n#endif\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vColor: vec4f;\n#endif\n#include<openpbrNormalMapVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<lightVxUboDeclaration>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#include<logDepthDeclaration>\n#include<vertexPullingDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef USE_VERTEX_PULLING\nvar positionUpdated: vec3f=vec3f(0.0);\n#ifdef NORMAL\nvar normalUpdated: vec3f=vec3f(0.0);\n#endif\n#ifdef TANGENT\nvar tangentUpdated: vec4f=vec4f(0.0);\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vec2f(0.0);\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vec2f(0.0);\n#endif\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vec4f(0.0);\n#endif\n#else\nvar positionUpdated: vec3f=vertexInputs.position;\n#ifdef NORMAL\nvar normalUpdated: vec3f=vertexInputs.normal;\n#endif\n#ifdef TANGENT\nvar tangentUpdated: vec4f=vertexInputs.tangent;\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vertexInputs.color;\n#endif\n#endif\n#include<vertexPullingVertex>\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvertexOutputs.vPositionUVW=positionUpdated;\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#if defined(PREPASS) && ((defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvertexOutputs.vCurrentPosition=scene.viewProjection*finalWorld*vec4f(positionUpdated,1.0);vertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld*vec4f(positionUpdated,1.0);\n#endif\n#ifdef USE_VERTEX_PULLING\n#include<bonesVertex>(vertexInputs.matricesIndices,vp_matricesIndices,vertexInputs.matricesWeights,vp_matricesWeights,vertexInputs.matricesIndicesExtra,vp_matricesIndicesExtra,vertexInputs.matricesWeightsExtra,vp_matricesWeightsExtra)\n#include<bakedVertexAnimation>(vertexInputs.matricesIndices,vp_matricesIndices,vertexInputs.matricesWeights,vp_matricesWeights,vertexInputs.matricesIndicesExtra,vp_matricesIndicesExtra,vertexInputs.matricesWeightsExtra,vp_matricesWeightsExtra)\n#else\n#include<bonesVertex>\n#include<bakedVertexAnimation>\n#endif\nvar worldPos: vec4f=finalWorld* vec4f(positionUpdated,1.0);vertexOutputs.vPositionW= worldPos.xyz;\n#ifdef PREPASS\n#include<prePassVertex>\n#endif\n#ifdef NORMAL\nvar normalWorld: mat3x3f= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvertexOutputs.vNormalW=normalUpdated/ vec3f(dot(normalWorld[0],normalWorld[0]),dot(normalWorld[1],normalWorld[1]),dot(normalWorld[2],normalWorld[2]));vertexOutputs.vNormalW=normalize(normalWorld*vertexOutputs.vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvertexOutputs.vNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\nvar viewDirectionW: vec3f=normalize(scene.vEyePosition.xyz-vertexOutputs.vPositionW);var NdotV: f32=max(dot(vertexOutputs.vNormalW,viewDirectionW),0.0);var roughNormal: vec3f=mix(vertexOutputs.vNormalW,viewDirectionW,(0.5*(1.0-NdotV))*uniforms.vBaseDiffuseRoughness);var reflectionVector: vec3f= (uniforms.reflectionMatrix* vec4f(roughNormal,0)).xyz;\n#else\nvar reflectionVector: vec3f= (uniforms.reflectionMatrix* vec4f(vertexOutputs.vNormalW,0)).xyz;\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\nvertexOutputs.vEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector);\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_WORLDPOS\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {vertexOutputs.position=scene.viewProjection*worldPos;} else {vertexOutputs.position=scene.viewProjectionR*worldPos;}\n#else\nvertexOutputs.position=scene.viewProjection*worldPos;\n#endif\n#if DEBUGMODE>0\nvertexOutputs.vClipSpacePosition=vertexOutputs.position;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvertexOutputs.vDirectionW=normalize((finalWorld*vec4f(positionUpdated,0.0)).xyz);\n#endif\n#ifndef UV1\nvar uvUpdated: vec2f= vec2f(0.,0.);\n#endif\n#ifdef MAINUV1\nvertexOutputs.vMainUV1=uvUpdated;\n#endif\n#ifndef UV2\nvar uv2Updated: vec2f= vec2f(0.,0.);\n#endif\n#ifdef MAINUV2\nvertexOutputs.vMainUV2=uv2Updated;\n#endif\n#include<uvVariableDeclaration>[3..7]\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_COLOR,_VARYINGNAME_,BaseColor,_MATRIXNAME_,baseColor,_INFONAME_,BaseColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_MATRIXNAME_,baseWeight,_INFONAME_,BaseWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_MATRIXNAME_,baseDiffuseRoughness,_INFONAME_,BaseDiffuseRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_METALNESS,_VARYINGNAME_,BaseMetalness,_MATRIXNAME_,baseMetalness,_INFONAME_,BaseMetalnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_WEIGHT,_VARYINGNAME_,SpecularWeight,_MATRIXNAME_,specularWeight,_INFONAME_,SpecularWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_COLOR,_VARYINGNAME_,SpecularColor,_MATRIXNAME_,specularColor,_INFONAME_,SpecularColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_ROUGHNESS,_VARYINGNAME_,SpecularRoughness,_MATRIXNAME_,specularRoughness,_INFONAME_,SpecularRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,SpecularRoughnessAnisotropy,_MATRIXNAME_,specularRoughnessAnisotropy,_INFONAME_,SpecularRoughnessAnisotropyInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight,_MATRIXNAME_,transmissionWeight,_INFONAME_,TransmissionWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_COLOR,_VARYINGNAME_,TransmissionColor,_MATRIXNAME_,transmissionColor,_INFONAME_,TransmissionColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_DEPTH,_VARYINGNAME_,TransmissionDepth,_MATRIXNAME_,transmissionDepth,_INFONAME_,TransmissionDepthInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_SCATTER,_VARYINGNAME_,TransmissionScatter,_MATRIXNAME_,transmissionScatter,_INFONAME_,TransmissionScatterInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_DISPERSION_SCALE,_VARYINGNAME_,TransmissionDispersionScale,_MATRIXNAME_,transmissionDispersionScale,_INFONAME_,TransmissionDispersionScaleInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight,_MATRIXNAME_,subsurfaceWeight,_INFONAME_,SubsurfaceWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SUBSURFACE_COLOR,_VARYINGNAME_,SubsurfaceColor,_MATRIXNAME_,subsurfaceColor,_INFONAME_,SubsurfaceColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SUBSURFACE_RADIUS_SCALE,_VARYINGNAME_,SubsurfaceRadiusScale,_MATRIXNAME_,subsurfaceRadiusScale,_INFONAME_,SubsurfaceRadiusScaleInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,COAT_WEIGHT,_VARYINGNAME_,CoatWeight,_MATRIXNAME_,coatWeight,_INFONAME_,CoatWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,COAT_COLOR,_VARYINGNAME_,CoatColor,_MATRIXNAME_,coatColor,_INFONAME_,CoatColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,COAT_ROUGHNESS,_VARYINGNAME_,CoatRoughness,_MATRIXNAME_,coatRoughness,_INFONAME_,CoatRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,COAT_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,CoatRoughnessAnisotropy,_MATRIXNAME_,coatRoughnessAnisotropy,_INFONAME_,CoatRoughnessAnisotropyInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,COAT_DARKENING,_VARYINGNAME_,CoatDarkening,_MATRIXNAME_,coatDarkening,_INFONAME_,CoatDarkeningInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,FUZZ_WEIGHT,_VARYINGNAME_,FuzzWeight,_MATRIXNAME_,fuzzWeight,_INFONAME_,FuzzWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,FUZZ_COLOR,_VARYINGNAME_,FuzzColor,_MATRIXNAME_,fuzzColor,_INFONAME_,FuzzColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,FUZZ_ROUGHNESS,_VARYINGNAME_,FuzzRoughness,_MATRIXNAME_,fuzzRoughness,_INFONAME_,FuzzRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_NORMAL,_VARYINGNAME_,GeometryNormal,_MATRIXNAME_,geometryNormal,_INFONAME_,GeometryNormalInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_TANGENT,_VARYINGNAME_,GeometryTangent,_MATRIXNAME_,geometryTangent,_INFONAME_,GeometryTangentInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_COAT_NORMAL,_VARYINGNAME_,GeometryCoatNormal,_MATRIXNAME_,geometryCoatNormal,_INFONAME_,GeometryCoatNormalInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_OPACITY,_VARYINGNAME_,GeometryOpacity,_MATRIXNAME_,geometryOpacity,_INFONAME_,GeometryOpacityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_THICKNESS,_VARYINGNAME_,GeometryThickness,_MATRIXNAME_,geometryThickness,_INFONAME_,GeometryThicknessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,EMISSION_COLOR,_VARYINGNAME_,EmissionColor,_MATRIXNAME_,emissionColor,_INFONAME_,EmissionColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,THIN_FILM_WEIGHT,_VARYINGNAME_,ThinFilmWeight,_MATRIXNAME_,thinFilmWeight,_INFONAME_,ThinFilmWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,THIN_FILM_THICKNESS,_VARYINGNAME_,ThinFilmThickness,_MATRIXNAME_,thinFilmThickness,_INFONAME_,ThinFilmThicknessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,AMBIENT_OCCLUSION,_VARYINGNAME_,AmbientOcclusion,_MATRIXNAME_,ambientOcclusion,_INFONAME_,AmbientOcclusionInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_MATRIXNAME_,decal,_INFONAME_,DecalInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_MATRIXNAME_,detail,_INFONAME_,DetailInfos.x)\n#include<openpbrNormalMapVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#include<vertexColorMixing>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, openpbrUboDeclarationWGSL, uvAttributeDeclarationWGSL, mainUVVaryingDeclarationWGSL, helperFunctionsWGSL, pbrBRDFFunctionsWGSL, bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, instancesDeclarationWGSL, prePassVertexDeclarationWGSL, samplerVertexDeclarationWGSL, harmonicsFunctionsWGSL, openpbrNormalMapVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, lightVxUboDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, logDepthDeclarationWGSL, vertexPullingDeclarationWGSL, vertexPullingVertexWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, prePassVertexWGSL, uvVariableDeclarationWGSL, samplerVertexImplementationWGSL, openpbrNormalMapVertexWGSL, clipPlaneVertexWGSL, fogVertexWGSL, shadowsVertexWGSL, vertexColorMixingWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const openpbrVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nimport \"./pbrFragmentReflectionDeclaration\";\nconst name = \"openpbrFragmentSamplersDeclaration\";\nconst shader = `#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_COLOR,_VARYINGNAME_,BaseColor,_SAMPLERNAME_,baseColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_SAMPLERNAME_,baseWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_SAMPLERNAME_,baseDiffuseRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_METALNESS,_VARYINGNAME_,BaseMetalness,_SAMPLERNAME_,baseMetalness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_WEIGHT,_VARYINGNAME_,SpecularWeight,_SAMPLERNAME_,specularWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_COLOR,_VARYINGNAME_,SpecularColor,_SAMPLERNAME_,specularColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS,_VARYINGNAME_,SpecularRoughness,_SAMPLERNAME_,specularRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,SpecularRoughnessAnisotropy,_SAMPLERNAME_,specularRoughnessAnisotropy)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight,_SAMPLERNAME_,transmissionWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_COLOR,_VARYINGNAME_,TransmissionColor,_SAMPLERNAME_,transmissionColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_DEPTH,_VARYINGNAME_,TransmissionDepth,_SAMPLERNAME_,transmissionDepth)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_SCATTER,_VARYINGNAME_,TransmissionScatter,_SAMPLERNAME_,transmissionScatter)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_DISPERSION_SCALE,_VARYINGNAME_,TransmissionDispersionScale,_SAMPLERNAME_,transmissionDispersionScale)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight,_SAMPLERNAME_,subsurfaceWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_COLOR,_VARYINGNAME_,SubsurfaceColor,_SAMPLERNAME_,subsurfaceColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_RADIUS_SCALE,_VARYINGNAME_,SubsurfaceRadiusScale,_SAMPLERNAME_,subsurfaceRadiusScale)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_WEIGHT,_VARYINGNAME_,CoatWeight,_SAMPLERNAME_,coatWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_COLOR,_VARYINGNAME_,CoatColor,_SAMPLERNAME_,coatColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_ROUGHNESS,_VARYINGNAME_,CoatRoughness,_SAMPLERNAME_,coatRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,CoatRoughnessAnisotropy,_SAMPLERNAME_,coatRoughnessAnisotropy)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_DARKENING,_VARYINGNAME_,CoatDarkening,_SAMPLERNAME_,coatDarkening)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,FUZZ_WEIGHT,_VARYINGNAME_,FuzzWeight,_SAMPLERNAME_,fuzzWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,FUZZ_COLOR,_VARYINGNAME_,FuzzColor,_SAMPLERNAME_,fuzzColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,FUZZ_ROUGHNESS,_VARYINGNAME_,FuzzRoughness,_SAMPLERNAME_,fuzzRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_OPACITY,_VARYINGNAME_,GeometryOpacity,_SAMPLERNAME_,geometryOpacity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_TANGENT,_VARYINGNAME_,GeometryTangent,_SAMPLERNAME_,geometryTangent)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_COAT_TANGENT,_VARYINGNAME_,GeometryCoatTangent,_SAMPLERNAME_,geometryCoatTangent)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_THICKNESS,_VARYINGNAME_,GeometryThickness,_SAMPLERNAME_,geometryThickness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSION_COLOR,_VARYINGNAME_,EmissionColor,_SAMPLERNAME_,emissionColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,THIN_FILM_WEIGHT,_VARYINGNAME_,ThinFilmWeight,_SAMPLERNAME_,thinFilmWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,THIN_FILM_THICKNESS,_VARYINGNAME_,ThinFilmThickness,_SAMPLERNAME_,thinFilmThickness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT_OCCLUSION,_VARYINGNAME_,AmbientOcclusion,_SAMPLERNAME_,ambientOcclusion)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_SAMPLERNAME_,decal)\n#include<pbrFragmentReflectionDeclaration>\n#ifdef ENVIRONMENTBRDF\nvar environmentBrdfSamplerSampler: sampler;var environmentBrdfSampler: texture_2d<f32>;\n#endif\n#ifdef FUZZENVIRONMENTBRDF\nvar environmentFuzzBrdfSamplerSampler: sampler;var environmentFuzzBrdfSampler: texture_2d<f32>;\n#endif\n#ifdef REFRACTED_BACKGROUND\nvar backgroundRefractionSamplerSampler: sampler;var backgroundRefractionSampler: texture_2d<f32>;\n#endif\n#ifdef USE_IRRADIANCE_TEXTURE_FOR_SCATTERING\nvar sceneIrradianceSampler: texture_2d<f32>;var sceneDepthSampler: texture_2d<f32>;\n#endif\n#if defined(ANISOTROPIC) || defined(FUZZ) || defined(REFRACTED_BACKGROUND) || defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING)\nvar blueNoiseSamplerSampler: sampler;var blueNoiseSampler: texture_2d<f32>;\n#endif\n#ifdef IBL_CDF_FILTERING\nvar icdfSamplerSampler: sampler;var icdfSampler: texture_2d<f32>;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrFragmentSamplersDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapFragmentMainFunctions\";\nconst shader = `#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL) || defined(ANISOTROPIC) || defined(FUZZ) || defined(DETAIL)\n#if defined(TANGENT) && defined(NORMAL) \nvarying vTBN0: vec3f;varying vTBN1: vec3f;varying vTBN2: vec3f;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nuniform normalMatrix: mat4x4f;fn toNormalMatrix(m: mat4x4f)->mat4x4f\n{var a00=m[0][0];var a01=m[0][1];var a02=m[0][2];var a03=m[0][3];var a10=m[1][0];var a11=m[1][1];var a12=m[1][2];var a13=m[1][3];var a20=m[2][0]; \nvar a21=m[2][1];var a22=m[2][2];var a23=m[2][3];var a30=m[3][0]; \nvar a31=m[3][1];var a32=m[3][2];var a33=m[3][3];var b00=a00*a11-a01*a10;var b01=a00*a12-a02*a10;var b02=a00*a13-a03*a10;var b03=a01*a12-a02*a11;var b04=a01*a13-a03*a11;var b05=a02*a13-a03*a12;var b06=a20*a31-a21*a30;var b07=a20*a32-a22*a30;var b08=a20*a33-a23*a30;var b09=a21*a32-a22*a31;var b10=a21*a33-a23*a31;var b11=a22*a33-a23*a32;var det=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;var mi=mat4x4<f32>(\n(a11*b11-a12*b10+a13*b09)/det,\n(a02*b10-a01*b11-a03*b09)/det,\n(a31*b05-a32*b04+a33*b03)/det,\n(a22*b04-a21*b05-a23*b03)/det,\n(a12*b08-a10*b11-a13*b07)/det,\n(a00*b11-a02*b08+a03*b07)/det,\n(a32*b02-a30*b05-a33*b01)/det,\n(a20*b05-a22*b02+a23*b01)/det,\n(a10*b10-a11*b08+a13*b06)/det,\n(a01*b08-a00*b10-a03*b06)/det,\n(a30*b04-a31*b02+a33*b00)/det,\n(a21*b02-a20*b04-a23*b00)/det,\n(a11*b07-a10*b09-a12*b06)/det,\n(a00*b09-a01*b07+a02*b06)/det,\n(a31*b01-a30*b03-a32*b00)/det,\n(a20*b03-a21*b01+a22*b00)/det);return mat4x4<f32>(mi[0][0],mi[1][0],mi[2][0],mi[3][0],\nmi[0][1],mi[1][1],mi[2][1],mi[3][1],\nmi[0][2],mi[1][2],mi[2][2],mi[3][2],\nmi[0][3],mi[1][3],mi[2][3],mi[3][3]);}\n#endif\nfn perturbNormalBase(cotangentFrame: mat3x3f,normal: vec3f,scale: f32)->vec3f\n{var output=normal;\n#ifdef NORMALXYSCALE\noutput=normalize(output* vec3f(scale,scale,1.0));\n#endif\nreturn normalize(cotangentFrame*output);}\nfn perturbNormal(cotangentFrame: mat3x3f,textureSample: vec3f,scale: f32)->vec3f\n{return perturbNormalBase(cotangentFrame,textureSample*2.0-1.0,scale);}\nfn cotangent_frame(normal: vec3f,p: vec3f,uv: vec2f,tangentSpaceParams: vec2f)->mat3x3f\n{var dp1: vec3f=dpdx(p);var dp2: vec3f=dpdy(p);var duv1: vec2f=dpdx(uv);var duv2: vec2f=dpdy(uv);var dp2perp: vec3f=cross(dp2,normal);var dp1perp: vec3f=cross(normal,dp1);var tangent: vec3f=dp2perp*duv1.x+dp1perp*duv2.x;var bitangent: vec3f=dp2perp*duv1.y+dp1perp*duv2.y;tangent*=tangentSpaceParams.x;bitangent*=tangentSpaceParams.y;var det: f32=max(dot(tangent,tangent),dot(bitangent,bitangent));var invmax: f32=select(inverseSqrt(det),0.0,det==0.0);return mat3x3f(tangent*invmax,bitangent*invmax,normal);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapFragmentMainFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nconst name = \"openpbrNormalMapFragmentFunctions\";\nconst shader = `#if defined(GEOMETRY_NORMAL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_NORMAL,_VARYINGNAME_,GeometryNormal,_SAMPLERNAME_,geometryNormal)\n#endif\n#if defined(GEOMETRY_COAT_NORMAL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_COAT_NORMAL,_VARYINGNAME_,GeometryCoatNormal,_SAMPLERNAME_,geometryCoatNormal)\n#endif\n#if defined(DETAIL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_SAMPLERNAME_,detail)\n#endif\n#if defined(GEOMETRY_NORMAL) && defined(PARALLAX)\nconst minSamples: f32=4.;const maxSamples: f32=15.;const iMaxSamples: i32=15;fn parallaxOcclusion(vViewDirCoT: vec3f,vNormalCoT: vec3f,texCoord: vec2f,parallaxScale: f32)->vec2f {var parallaxLimit: f32=length(vViewDirCoT.xy)/vViewDirCoT.z;parallaxLimit*=parallaxScale;var vOffsetDir: vec2f=normalize(vViewDirCoT.xy);var vMaxOffset: vec2f=vOffsetDir*parallaxLimit;var numSamples: f32=maxSamples+(dot(vViewDirCoT,vNormalCoT)*(minSamples-maxSamples));var stepSize: f32=1.0/numSamples;var currRayHeight: f32=1.0;var vCurrOffset: vec2f= vec2f(0,0);var vLastOffset: vec2f= vec2f(0,0);var lastSampledHeight: f32=1.0;var currSampledHeight: f32=1.0;var keepWorking: bool=true;for (var i: i32=0; i<iMaxSamples; i++)\n{currSampledHeight=textureSample(geometryNormalSampler,geometryNormalSamplerSampler,texCoord+vCurrOffset).w;if (!keepWorking)\n{}\nelse if (currSampledHeight>currRayHeight)\n{var delta1: f32=currSampledHeight-currRayHeight;var delta2: f32=(currRayHeight+stepSize)-lastSampledHeight;var ratio: f32=delta1/(delta1+delta2);vCurrOffset=(ratio)* vLastOffset+(1.0-ratio)*vCurrOffset;keepWorking=false;}\nelse\n{currRayHeight-=stepSize;vLastOffset=vCurrOffset;\n#ifdef PARALLAX_RHS\nvCurrOffset-=stepSize*vMaxOffset;\n#else\nvCurrOffset+=stepSize*vMaxOffset;\n#endif\nlastSampledHeight=currSampledHeight;}}\nreturn vCurrOffset;}\nfn parallaxOffset(viewDir: vec3f,heightScale: f32)->vec2f\n{var height: f32=textureSample(geometryNormalSampler,geometryNormalSamplerSampler,fragmentInputs.vGeometryNormalUV).w;var texCoordOffset: vec2f=heightScale*viewDir.xy*height;\n#ifdef PARALLAX_RHS\nreturn texCoordOffset;\n#else\nreturn -texCoordOffset;\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapFragmentFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrDielectricReflectance\";\nconst shader = `struct ReflectanceParams\n{F0: f32,\nF90: f32,\ncoloredF0: vec3f,\ncoloredF90: vec3f,};\n#define pbr_inline\nfn dielectricReflectance(\ninsideIOR: f32,outsideIOR: f32,specularColor: vec3f,specularWeight: f32\n)->ReflectanceParams\n{var outParams: ReflectanceParams;let dielectricF0=pow((insideIOR-outsideIOR)/(insideIOR+outsideIOR),2.0);let f90Scale=clamp(2.0f*abs(insideIOR-outsideIOR),0.0f,1.0f);\n#if (DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_OPENPBR)\nlet dielectricColorF90: vec3f=specularColor.rgb*vec3f(f90Scale);\n#else\nlet dielectricColorF90: vec3f=vec3f(f90Scale);\n#endif\n#if DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_GLTF\nlet maxF0=max(specularColor.r,max(specularColor.g,specularColor.b));outParams.F0=dielectricF0*maxF0*specularWeight;\n#else\noutParams.F0=dielectricF0*specularWeight;\n#endif\noutParams.F90=f90Scale*specularWeight;outParams.coloredF0=vec3f(dielectricF0*specularWeight)*specularColor.rgb;outParams.coloredF90=dielectricColorF90*vec3f(specularWeight);return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrDielectricReflectanceWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrConductorReflectance\";\nconst shader = `#define pbr_inline\nfn conductorReflectance(baseColor: vec3f,specularColor: vec3f,specularWeight: f32)->ReflectanceParams\n{var outParams: ReflectanceParams;\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\noutParams.coloredF0=baseColor*specularWeight;outParams.coloredF90=specularColor*specularWeight;\n#else\noutParams.coloredF0=baseColor;outParams.coloredF90=vec3f(1.0f);\n#endif\noutParams.F0=1.0f;outParams.F90=1.0f;return outParams;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrConductorReflectanceWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrAmbientOcclusionFunctions\";\nconst shader = `fn compute_specular_occlusion(n_dot_v: f32,metallic: f32,ambient_occlusion: f32,roughness: f32)->f32\n{let specular_occlusion: f32=saturate(pow(n_dot_v+ambient_occlusion,exp2(-16.0*roughness-1.0))-1.0+ambient_occlusion);return mix(specular_occlusion,1.0,metallic*square(1.0-roughness));}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrAmbientOcclusionFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrGeometryInfo\";\nconst shader = `struct geometryInfoOutParams\n{NdotV: f32,\nNdotVUnclamped: f32,\nenvironmentBrdf: vec3f,\nhorizonOcclusion: f32};struct geometryInfoAnisoOutParams\n{NdotV: f32,\nNdotVUnclamped: f32,\nenvironmentBrdf: vec3f,\nhorizonOcclusion: f32,\nanisotropy: f32,\nanisotropicTangent: vec3f,\nanisotropicBitangent: vec3f,\nTBN: mat3x3<f32>};fn geometryInfo(\nnormalW: vec3f,viewDirectionW: vec3f,roughness: f32,geometricNormalW: vec3f\n)->geometryInfoOutParams\n{var outParams: geometryInfoOutParams;outParams.NdotVUnclamped=dot(normalW,viewDirectionW);outParams.NdotV=absEps(outParams.NdotVUnclamped);\n#if defined(ENVIRONMENTBRDF)\noutParams.environmentBrdf=getBRDFLookup(outParams.NdotV,roughness);\n#else\noutParams.environmentBrdf=vec3f(0.0);\n#endif\noutParams.horizonOcclusion=1.0f;\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\n#ifdef HORIZONOCCLUSION\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL)\n#ifdef REFLECTIONMAP_3D\noutParams.horizonOcclusion=environmentHorizonOcclusion(-viewDirectionW,normalW,geometricNormalW);\n#endif\n#endif\n#endif\n#endif\nreturn outParams;}\nfn geometryInfoAniso(\nnormalW: vec3f,viewDirectionW: vec3f,roughness: f32,geometricNormalW: vec3f\n,vAnisotropy: vec3f,TBN: mat3x3<f32>\n)->geometryInfoAnisoOutParams\n{let geoInfo: geometryInfoOutParams=geometryInfo(normalW,viewDirectionW,roughness,geometricNormalW);var outParams: geometryInfoAnisoOutParams;outParams.NdotV=geoInfo.NdotV;outParams.NdotVUnclamped=geoInfo.NdotVUnclamped;outParams.environmentBrdf=geoInfo.environmentBrdf;outParams.horizonOcclusion=geoInfo.horizonOcclusion;outParams.anisotropy=vAnisotropy.b;let anisotropyDirection: vec3f=vec3f(vAnisotropy.xy,0.);let anisoTBN: mat3x3<f32>=mat3x3<f32>(normalize(TBN[0]),normalize(TBN[1]),normalize(TBN[2]));outParams.anisotropicTangent=normalize(anisoTBN*anisotropyDirection);outParams.anisotropicBitangent=normalize(cross(anisoTBN[2],outParams.anisotropicTangent));outParams.TBN=TBN;return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrGeometryInfoWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrIblFunctions\";\nconst shader = `#ifdef REFLECTION\nfn sampleIrradiance(\nsurfaceNormal: vec3f\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradianceSH: vec3f\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,iblMatrix: mat4x4f\n#endif\n#ifdef USEIRRADIANCEMAP\n#ifdef REFLECTIONMAP_3D\n,irradianceSampler: texture_cube<f32>\n,irradianceSamplerSampler: sampler\n#else\n,irradianceSampler: texture_2d<f32>\n,irradianceSamplerSampler: sampler\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,reflectionDominantDirection: vec3f\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,reflectionFilteringInfo: vec2f\n#ifdef IBL_CDF_FILTERING\n,icdfSampler: texture_2d<f32>\n,icdfSamplerSampler: sampler\n#endif\n#endif\n,reflectionInfos: vec2f\n,viewDirectionW: vec3f\n,diffuseRoughness: f32\n,surfaceAlbedo: vec3f\n)->vec3f {var environmentIrradiance=vec3f(0.,0.,0.);\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\nvar irradianceVector=(iblMatrix*vec4f(surfaceNormal,0.0f)).xyz;var irradianceView=(iblMatrix*vec4f(viewDirectionW,0.0f)).xyz;\n#if !defined(USE_IRRADIANCE_DOMINANT_DIRECTION) && !defined(REALTIME_FILTERING)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\n{let NdotV=max(dot(surfaceNormal,viewDirectionW),0.0f);irradianceVector=mix(irradianceVector,irradianceView,(0.5f*(1.0f-NdotV))*diffuseRoughness);}\n#endif\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;irradianceView.z*=-1.0;\n#endif\n#ifdef INVERTCUBICMAP\nirradianceVector.y*=-1.0;irradianceView.y*=-1.0;\n#endif\n#endif\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\nenvironmentIrradiance=vEnvironmentIrradianceSH;\n#else\n#if defined(REALTIME_FILTERING)\nenvironmentIrradiance=irradiance(reflectionSampler,reflectionSamplerSampler,irradianceVector,reflectionFilteringInfo,diffuseRoughness,surfaceAlbedo,irradianceView\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n);\n#else\nenvironmentIrradiance=computeEnvironmentIrradiance(irradianceVector);\n#endif\n#endif\n#elif defined(USEIRRADIANCEMAP)\n#ifdef REFLECTIONMAP_3D\nlet environmentIrradianceFromTexture: vec4f=textureSample(irradianceSampler,irradianceSamplerSampler,irradianceVector);\n#else\nlet environmentIrradianceFromTexture: vec4f=textureSample(irradianceSampler,irradianceSamplerSampler,reflectionCoords);\n#endif\nenvironmentIrradiance=environmentIrradianceFromTexture.rgb;\n#ifdef RGBDREFLECTION\nenvironmentIrradiance.rgb=fromRGBD(environmentIrradianceFromTexture);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentIrradiance.rgb=toLinearSpaceVec3(environmentIrradiance.rgb);\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\nlet Ls: vec3f=normalize(reflectionDominantDirection);let NoL: f32=dot(irradianceVector,Ls);let NoV: f32=dot(irradianceVector,irradianceView);var diffuseRoughnessTerm=vec3f(1.0f);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nlet LoV: f32=dot (Ls,irradianceView);let mag: f32=length(reflectionDominantDirection)*2.0f;let clampedAlbedo: vec3f=clamp(surfaceAlbedo,vec3f(0.1f),vec3f(1.0f));diffuseRoughnessTerm=diffuseBRDF_EON(clampedAlbedo,diffuseRoughness,NoL,NoV,LoV)*PI;diffuseRoughnessTerm=diffuseRoughnessTerm/clampedAlbedo;diffuseRoughnessTerm=mix(vec3f(1.0f),diffuseRoughnessTerm,sqrt(clamp(mag*NoV,0.0f,1.0f)));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nlet H: vec3f=(irradianceView+Ls)*0.5f;let VoH: f32=dot(irradianceView,H);diffuseRoughnessTerm=vec3f(diffuseBRDF_Burley(NoL,NoV,VoH,diffuseRoughness)*PI);\n#endif\nenvironmentIrradiance=environmentIrradiance.rgb*diffuseRoughnessTerm;\n#endif\n#endif\nenvironmentIrradiance*=reflectionInfos.x;return environmentIrradiance;}\n#ifdef REFLECTIONMAP_3D\nfn createReflectionCoords(vPositionW: vec3f,normalW: vec3f)->vec3f\n#else\nfn createReflectionCoords(vPositionW: vec3f,normalW: vec3f)->vec2f\n#endif\n{var reflectionVector: vec3f=computeReflectionCoords(vec4f(vPositionW,1.0f),normalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nvar reflectionCoords: vec3f=reflectionVector;\n#else\nvar reflectionCoords: vec2f=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0f-reflectionCoords.y;\n#endif\nreturn reflectionCoords;}\nfn sampleRadiance(\nalphaG: f32\n,reflectionMicrosurfaceInfos: vec3f\n,reflectionInfos: vec2f\n,geoInfo: geometryInfoOutParams\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n,reflectionCoords: vec3f\n#else\n,reflectionSampler: texture_2d<f32>\n,reflectionSamplerSampler: sampler\n,reflectionCoords: vec2f\n#endif\n#ifdef REALTIME_FILTERING\n,reflectionFilteringInfo: vec2f\n#endif\n)->vec3f {var environmentRadiance: vec4f=vec4f(0.f,0.f,0.f,0.f);\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nvar reflectionLOD: f32=getLodFromAlphaG(reflectionMicrosurfaceInfos.x,alphaG,geoInfo.NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nvar reflectionLOD: f32=getLinearLodFromRoughness(reflectionMicrosurfaceInfos.x,roughness);\n#else\nvar reflectionLOD: f32=getLodFromAlphaG(reflectionMicrosurfaceInfos.x,alphaG);\n#endif\nreflectionLOD=reflectionLOD*reflectionMicrosurfaceInfos.y+reflectionMicrosurfaceInfos.z;\n#ifdef REALTIME_FILTERING\nenvironmentRadiance=vec4f(radiance(alphaG,reflectionSampler,reflectionSamplerSampler,reflectionCoords,reflectionFilteringInfo),1.0f);\n#else\nenvironmentRadiance=textureSampleLevel(reflectionSampler,reflectionSamplerSampler,reflectionCoords,reflectionLOD);\n#endif\nvar envRadiance: vec3f=environmentRadiance.rgb;\n#ifdef RGBDREFLECTION\nenvRadiance=fromRGBD(environmentRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvRadiance=toLinearSpaceVec3(environmentRadiance.rgb);\n#endif\nenvRadiance*=reflectionInfos.x;return envRadiance;}\n#if defined(ANISOTROPIC)\nfn sampleRadianceAnisotropic(\nalphaG: f32\n,reflectionMicrosurfaceInfos: vec3f\n,reflectionInfos: vec2f\n,geoInfo: geometryInfoAnisoOutParams\n,normalW: vec3f\n,viewDirectionW: vec3f\n,positionW: vec3f\n,noise: vec3f\n,isRefraction: bool\n,ior: f32\n#ifdef REFLECTIONMAP_3D\n,reflectionSampler: texture_cube<f32>\n,reflectionSamplerSampler: sampler\n#else\n,reflectionSampler: texture_2d<f32>\n,reflectionSamplerSampler: sampler\n#endif\n#ifdef REALTIME_FILTERING\n,reflectionFilteringInfo: vec2f\n#endif\n)->vec3f {var environmentRadiance: vec4f=vec4f(0.f,0.f,0.f,0.f);let alphaT=alphaG*sqrt(2.0f/(1.0f+(1.0f-geoInfo.anisotropy)*(1.0f-geoInfo.anisotropy)));let alphaB=(1.0f-geoInfo.anisotropy)*alphaT;let modifiedAlphaG=alphaB;\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nvar reflectionLOD: f32=getLodFromAlphaG(reflectionMicrosurfaceInfos.x,modifiedAlphaG,geoInfo.NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nvar reflectionLOD: f32=getLinearLodFromRoughness(reflectionMicrosurfaceInfos.x,roughness);\n#else\nvar reflectionLOD: f32=getLodFromAlphaG(reflectionMicrosurfaceInfos.x,modifiedAlphaG);\n#endif\nreflectionLOD=reflectionLOD*reflectionMicrosurfaceInfos.y+reflectionMicrosurfaceInfos.z;\n#ifdef REALTIME_FILTERING\nvar view=(uniforms.reflectionMatrix*vec4f(viewDirectionW,0.0f)).xyz;var tangent=(uniforms.reflectionMatrix*vec4f(geoInfo.anisotropicTangent,0.0f)).xyz;var bitangent=(uniforms.reflectionMatrix*vec4f(geoInfo.anisotropicBitangent,0.0f)).xyz;var normal=(uniforms.reflectionMatrix*vec4f(normalW,0.0f)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nview.z*=-1.0f;tangent.z*=-1.0f;bitangent.z*=-1.0f;normal.z*=-1.0f;\n#endif\nenvironmentRadiance =\nvec4f(radianceAnisotropic(alphaT,alphaB,reflectionSampler,reflectionSamplerSampler,\nview,tangent,\nbitangent,normal,\nreflectionFilteringInfo,noise.xy,isRefraction,ior),\n1.0f);\n#else\nconst samples: i32=16;var radianceSample=vec4f(0.0);var accumulatedRadiance=vec3f(0.0);var sample_weight=0.0f;var total_weight=0.0f;let step=1.0f/f32(max(samples-1,1));for (var i: i32=0; i<samples; i++) {var t: f32=mix(-1.0,1.0,f32(i)*step);t+=step*2.0*noise.x;sample_weight=max(1.0-abs(t),0.001);sample_weight*=sample_weight;t*=min(4.0*alphaT*geoInfo.anisotropy,1.0);var bentNormal: vec3f;if (t<0.0) {let blend: f32=t+1.0;bentNormal=normalize(mix(-geoInfo.anisotropicTangent,normalW,blend));} else if (t>0.0) {let blend: f32=t;bentNormal=normalize(mix(normalW,geoInfo.anisotropicTangent,blend));} else {bentNormal=normalW;}\n#ifdef REFLECTIONMAP_3D\nvar reflectionCoords: vec3f;if (isRefraction) {reflectionCoords=double_refract(-viewDirectionW,bentNormal,ior);} else {reflectionCoords=reflect(-viewDirectionW,bentNormal);}\nreflectionCoords=(uniforms.reflectionMatrix*vec4f(reflectionCoords,0.f)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionCoords.z*=-1.0f;\n#endif\n#else\nvar sampleDirection: vec3f;if (isRefraction) {sampleDirection=double_refract(-viewDirectionW,bentNormal,ior);} else {sampleDirection=reflect(-viewDirectionW,bentNormal);}\nlet originalViewDirectionW: vec3f=normalize(scene.vEyePosition.xyz-positionW);let mappingNormalCandidate: vec3f=originalViewDirectionW+sampleDirection;var mappingNormal: vec3f;if (dot(mappingNormalCandidate,mappingNormalCandidate)>Epsilon) {mappingNormal=normalize(mappingNormalCandidate);} else {let perpendicularAxis: vec3f=select(vec3f(0.0f,1.0f,0.0f),vec3f(1.0f,0.0f,0.0f),abs(originalViewDirectionW.x)<0.9f);mappingNormal=normalize(cross(originalViewDirectionW,perpendicularAxis));}\nlet reflectionCoords: vec2f=createReflectionCoords(positionW,mappingNormal);\n#endif\nradianceSample=textureSampleLevel(reflectionSampler,reflectionSamplerSampler,reflectionCoords,reflectionLOD);\n#ifdef RGBDREFLECTION\naccumulatedRadiance+=vec3f(sample_weight)*fromRGBD(radianceSample);\n#elif defined(GAMMAREFLECTION)\naccumulatedRadiance+=vec3f(sample_weight)*toLinearSpaceVec3(radianceSample.rgb);\n#else\naccumulatedRadiance+=vec3f(sample_weight)*radianceSample.rgb;\n#endif\ntotal_weight+=sample_weight;}\nenvironmentRadiance=vec4f(accumulatedRadiance/vec3f(total_weight),1.0f);\n#endif\nenvironmentRadiance=vec4f(environmentRadiance.rgb*reflectionInfos.xxx,environmentRadiance.a);return environmentRadiance.rgb;}\n#endif\n#endif\n#ifdef ENVIRONMENTBRDF\nfn computeDielectricIblFresnel(reflectance: ReflectanceParams,environmentBrdf: vec3f)->f32\n{let dielectricIblFresnel: f32=getReflectanceFromBRDFWithEnvLookup(vec3f(reflectance.F0),vec3f(reflectance.F90),environmentBrdf).r;let dielectricECF: f32=1.0+reflectance.F0*(1.0/environmentBrdf.y-1.0);return clamp(dielectricIblFresnel*dielectricECF,0.0,1.0);}\nfn computeConductorIblFresnel(reflectance: ReflectanceParams,environmentBrdf: vec3f)->vec3f\n{\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nlet openPBRBrdf: vec3f=vec3f(environmentBrdf.xy,environmentBrdf.z/BRDF_Z_SCALE);let b: vec3f =getF82B(reflectance.coloredF0,reflectance.coloredF90);let E_F82: vec3f=getF82DirectionalAlbedo(reflectance.coloredF0,vec3f(1.0),b,openPBRBrdf);let F_avg: vec3f=getF82AverageFresnel(reflectance.coloredF0,b);let ECF: vec3f =vec3f(1.0)+F_avg*(vec3f(1.0)/openPBRBrdf.y-vec3f(1.0));return clamp(E_F82*ECF,vec3f(0.0),vec3f(1.0));\n#else\nreturn getReflectanceFromBRDFLookup(reflectance.coloredF0,reflectance.coloredF90,environmentBrdf);\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrIblFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrVolumeFunctions\";\nconst shader = `struct OpenPBRHomogeneousVolume {extinction_coeff: vec3f, \nss_albedo: vec3f, \nmulti_scatter_color: vec3f, \nabsorption_coeff: vec3f, \nscatter_coeff: vec3f, \nanisotropy: f32, };fn computeOpenPBRTransmissionVolume(\ntransmission_color: vec3f,\ntransmission_depth: f32,\ntransmission_scatter: vec3f,\nanisotropy: f32\n)->OpenPBRHomogeneousVolume\n{var volumeParams: OpenPBRHomogeneousVolume;volumeParams.absorption_coeff=vec3f(0.0f);volumeParams.scatter_coeff=vec3f(0.0f);volumeParams.anisotropy=anisotropy;\n#ifdef GEOMETRY_THIN_WALLED\nvolumeParams.scatter_coeff=vec3f(1.0f);volumeParams.anisotropy=1.0f; \nvolumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=vec3f(1.0f);\n#else\nif (transmission_depth>0.0f) {let invDepth: vec3f=vec3f(1.f/maxEps(transmission_depth));volumeParams.extinction_coeff=-log(maxEpsVec3(transmission_color.rgb))*invDepth;volumeParams.scatter_coeff=transmission_scatter.rgb*invDepth;volumeParams.absorption_coeff=volumeParams.extinction_coeff-volumeParams.scatter_coeff.rgb;let minCoeff: f32=min3(volumeParams.absorption_coeff);if (minCoeff<0.0f) {volumeParams.absorption_coeff-=vec3f(minCoeff);}\nvolumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=volumeParams.scatter_coeff/(volumeParams.extinction_coeff);} else {volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=vec3f(0.0f);}\n#endif\nreturn volumeParams;}\nfn computeOpenPBRSubsurfaceVolume(\nsubsurface_color: vec3f,\nsubsurface_radius: f32,\nsubsurface_radius_scale: vec3f,\nanisotropy: f32\n)->OpenPBRHomogeneousVolume\n{var volumeParams: OpenPBRHomogeneousVolume;volumeParams.absorption_coeff=vec3f(0.0f);volumeParams.scatter_coeff=vec3f(0.0f);volumeParams.anisotropy=anisotropy;volumeParams.multi_scatter_color=subsurface_color;let mfp: vec3f=subsurface_radius_scale*vec3f(subsurface_radius);volumeParams.extinction_coeff=vec3f(1.0f)/maxEpsVec3(mfp);volumeParams.ss_albedo=multiScatterToSingleScatterAlbedoWithAniso(subsurface_color,anisotropy);volumeParams.scatter_coeff=volumeParams.ss_albedo*volumeParams.extinction_coeff;volumeParams.absorption_coeff=volumeParams.extinction_coeff-volumeParams.scatter_coeff.rgb;let minCoeff: f32=min3(volumeParams.absorption_coeff);if (minCoeff<0.0f) {volumeParams.absorption_coeff-=vec3f(minCoeff);}\nvolumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;return volumeParams;}\nfn sss_pdf(r: f32,d: vec3f)->vec3f\n{let d_clamped=max(vec3f(1e-4f),d);return (exp(-r/d_clamped)+exp(-r/(3.0f*d_clamped)))/max(vec3f(1e-5f),8.0f*PI*d_clamped*r);}\nfn sss_samples_pdf(r: f32,d: f32)->f32\n{let d_clamped=max(1e-4f,d);return exp(-r/(3.0f*d_clamped))/(6.0f*PI*d_clamped*r);}\nfn sss_samples_icdf(x: f32,d: f32)->f32\n{let d_clamped=max(1e-4f,d);let x_clamped=max(1e-4f,x);return -3.0f*log(x_clamped)*d_clamped;}\nfn samples_scale(x: f32,d: f32)->f32\n{return 1.0f-exp(-x/(3.0f*d));}\nfn sss_get_position(depth_texture: texture_2d<f32>,tex_coord: vec2f,render_resolution: vec2f,inv_proj: mat4x4f)->vec3f\n{var P: vec4f=vec4f(tex_coord,textureLoad(depth_texture,vec2i(tex_coord*render_resolution),0).x,1.0f);P.x=2.0f*P.x-1.0f;P.y=2.0f*P.y-1.0f;P=inv_proj*P;return P.xyz/P.w;}\nfn sss_filter_scale(currZ: f32,proj: mat4x4f)->f32\n{return 1.0f/dot(vec2f(proj[2].w,proj[3].w),vec2f(currZ,1.0f));}\nfn projective_to_pixels(proj_dist: f32,proj: mat4x4f,resolution: vec2f)->f32\n{return proj_dist*proj[1][1]*resolution.y;}\nfn pixels_to_projective(pixel_dist: f32,proj: mat4x4f,resolution: vec2f)->f32\n{return pixel_dist/(proj[1][1]*resolution.y);}\nfn sss_convolve(sss_irradiance_texture: texture_2d<f32>,depth_texture: texture_2d<f32>,render_resolution: vec2f,d: vec3f,proj: mat4x4f,inv_proj: mat4x4f,sample_count: i32,noise: vec2f)->vec3f\n{let tex_coord: vec2f=fragmentInputs.position.xy/render_resolution;let unconvolved_irradiance: vec3f=textureLoad(sss_irradiance_texture,vec2i(fragmentInputs.position.xy),0).rgb;let curr_pos: vec3f=sss_get_position(depth_texture,tex_coord,render_resolution,inv_proj);var dmax: f32=max3(d);let max_dmax: f32=0.1*f32(sample_count);var d_adjusted=d;if (dmax>max_dmax)\n{d_adjusted*=max_dmax/dmax;dmax=max_dmax;}\nvar dz: f32=dmax*sss_filter_scale(curr_pos.z,proj);let projMat2d: mat2x2f=mat2x2f(proj[0].xy,proj[1].xy);if (determinant(projMat2d)*dz<1e-4f) {return unconvolved_irradiance;}\nlet overscan_size_in_pixels: f32=max(render_resolution.x,render_resolution.y)*0.1;let filter_crop_ratio: f32=0.8f; \nlet crop_radius: f32=projective_to_pixels(sss_samples_icdf(1.0f-filter_crop_ratio,dz),proj,render_resolution);if (crop_radius>overscan_size_in_pixels)\n{d_adjusted*=overscan_size_in_pixels/crop_radius;dz*=overscan_size_in_pixels/crop_radius;}\nlet filter_samples_scale: f32=samples_scale(pixels_to_projective(overscan_size_in_pixels,proj,render_resolution),dz);var irradiance_sum: vec3f=vec3f(0.0f);var weight_sum: vec3f=vec3f(0.0f);for (var i: i32=0; i<sample_count; i++)\n{var r: vec2f=fract(plasticSequence(u32(i))+noise);r.x*=TWO_PI;r.y*=filter_samples_scale;let icdf: f32=sss_samples_icdf(1.0-r.y,dz);let sample_uv: vec2f=tex_coord+icdf*projMat2d*vec2f(cos(r.x),sin(r.x));let sss_irradiance: vec4f=textureLoad(sss_irradiance_texture,vec2i(sample_uv*render_resolution),0);let dist: f32=distance(curr_pos,sss_get_position(depth_texture,sample_uv,render_resolution,inv_proj));if (dist>0.0f)\n{let weights: vec3f=sss_irradiance.a/sss_samples_pdf(icdf,dz)*sss_pdf(dist,d_adjusted);irradiance_sum+=weights*sss_irradiance.rgb;weight_sum+=weights;}}\nreturn vec3f(select(unconvolved_irradiance.r,irradiance_sum.r/weight_sum.r,weight_sum.r>=1e-5f),\nselect(unconvolved_irradiance.g,irradiance_sum.g/weight_sum.g,weight_sum.g>=1e-5f),\nselect(unconvolved_irradiance.b,irradiance_sum.b/weight_sum.b,weight_sum.b>=1e-5f));}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrVolumeFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapFragment\";\nconst shader = `var uvOffset: vec2f= vec2f(0.0,0.0);\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL) || defined(PARALLAX) || defined(DETAIL)\n#ifdef NORMALXYSCALE\nvar normalScale: f32=1.0;\n#elif defined(GEOMETRY_NORMAL)\nvar normalScale: f32=uniforms.vGeometryNormalInfos.y;\n#else\nvar normalScale: f32=1.0;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nvar TBN: mat3x3f=mat3x3<f32>(input.vTBN0,input.vTBN1,input.vTBN2); \n#elif defined(GEOMETRY_NORMAL)\nvar TBNUV: vec2f=select(-fragmentInputs.vGeometryNormalUV,fragmentInputs.vGeometryNormalUV,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW*normalScale,input.vPositionW,TBNUV,uniforms.vTangentSpaceParams);\n#elif defined(GEOMETRY_COAT_NORMAL)\nvar TBNUV: vec2f=select(-fragmentInputs.vGeometryCoatNormalUV,fragmentInputs.vGeometryCoatNormalUV,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW*normalScale,input.vPositionW,TBNUV,uniforms.vTangentSpaceParams);\n#else\nvar TBNUV: vec2f=select(-fragmentInputs.vDetailUV,fragmentInputs.vDetailUV,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW*normalScale,input.vPositionW,TBNUV, vec2f(1.,1.));\n#endif\n#elif defined(ANISOTROPIC) || defined(FUZZ)\n#if defined(TANGENT) && defined(NORMAL)\nvar TBN: mat3x3f=mat3x3<f32>(input.vTBN0,input.vTBN1,input.vTBN2);\n#else\nvar TBNUV: vec2f=select( -fragmentInputs.vMainUV1,fragmentInputs.vMainUV1,fragmentInputs.frontFacing);var TBN: mat3x3f=cotangent_frame(normalW,input.vPositionW,TBNUV, vec2f(1.,1.));\n#endif\n#endif\n#ifdef PARALLAX\nvar invTBN: mat3x3f=transposeMat3(TBN);\n#ifdef PARALLAXOCCLUSION\n#else\n#endif\n#endif\n#ifdef DETAIL\nvar detailColor: vec4f=textureSample(detailSampler,detailSamplerSampler,fragmentInputs.vDetailUV+uvOffset);var detailNormalRG: vec2f=detailColor.wy*2.0-1.0;var detailNormalB: f32=sqrt(1.-saturate(dot(detailNormalRG,detailNormalRG)));var detailNormal: vec3f= vec3f(detailNormalRG,detailNormalB);\n#endif\n#ifdef GEOMETRY_COAT_NORMAL\ncoatNormalW=perturbNormal(TBN,TEXRD(geometryCoatNormalSampler,geometryCoatNormalSamplerSampler,fragmentInputs.vGeometryCoatNormalUV+uvOffset).xyz,uniforms.vGeometryCoatNormalInfos.y);\n#endif\n#ifdef GEOMETRY_NORMAL\n#ifdef OBJECTSPACE_NORMALMAP\n#define CUSTOM_FRAGMENT_BUMP_FRAGMENT\nnormalW=normalize(TEXRD(geometryNormalSampler,geometryNormalSamplerSampler,fragmentInputs.vGeometryNormalUV).xyz *2.0-1.0);normalW=normalize(mat3x3f(uniforms.normalMatrix[0].xyz,uniforms.normalMatrix[1].xyz,uniforms.normalMatrix[2].xyz)*normalW);\n#elif !defined(DETAIL)\nnormalW=perturbNormal(TBN,TEXRD(geometryNormalSampler,geometryNormalSamplerSampler,fragmentInputs.vGeometryNormalUV+uvOffset).xyz,uniforms.vGeometryNormalInfos.y);\n#else\nvar sampledNormal: vec3f=TEXRD(geometryNormalSampler,geometryNormalSamplerSampler,fragmentInputs.vGeometryNormalUV+uvOffset).xyz*2.0-1.0;\n#if DETAIL_NORMALBLENDMETHOD==0 \ndetailNormal=vec3f(detailNormal.xy*uniforms.vDetailInfos.z,detailNormal.z);var blendedNormal: vec3f=normalize( vec3f(sampledNormal.xy+detailNormal.xy,sampledNormal.z*detailNormal.z));\n#elif DETAIL_NORMALBLENDMETHOD==1 \ndetailNormal=vec3f(detailNormal.xy*uniforms.vDetailInfos.z,detailNormal.z);sampledNormal+= vec3f(0.0,0.0,1.0);detailNormal*= vec3f(-1.0,-1.0,1.0);var blendedNormal: vec3f=sampledNormal*dot(sampledNormal,detailNormal)/sampledNormal.z-detailNormal;\n#endif\nnormalW=perturbNormalBase(TBN,blendedNormal,uniforms.vGeometryNormalInfos.y);\n#endif\n#elif defined(DETAIL)\ndetailNormal=vec3f(detailNormal.xy*uniforms.vDetailInfos.z,detailNormal.z);normalW=perturbNormalBase(TBN,detailNormal,uniforms.vDetailInfos.z);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBlockNormalFinal\";\nconst shader = `#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nvar faceNormal: vec3f=normalize(cross(dpdx(fragmentInputs.vPositionW),dpdy(fragmentInputs.vPositionW)))*scene.vEyePosition.w;\n#if defined(TWOSIDEDLIGHTING)\nfaceNormal=select(-faceNormal,faceNormal,fragmentInputs.frontFacing);\n#endif\nnormalW*=sign(dot(normalW,faceNormal));coatNormalW*=sign(dot(coatNormalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\n#if defined(MIRRORED)\nnormalW=select(normalW,-normalW,fragmentInputs.frontFacing);coatNormalW=select(coatNormalW,-coatNormalW,fragmentInputs.frontFacing);\n#else\nnormalW=select(-normalW,normalW,fragmentInputs.frontFacing);coatNormalW=select(-coatNormalW,coatNormalW,fragmentInputs.frontFacing);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrBlockNormalFinalWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBaseLayerData\";\nconst shader = `var base_color=vec3f(0.8);var base_metalness: f32=0.0;var base_diffuse_roughness: f32=0.0;var specular_weight: f32=1.0;var specular_roughness: f32=0.3;var specular_color: vec3f=vec3f(1.0);var specular_roughness_anisotropy: f32=0.0;var specular_ior: f32=1.5;var alpha: f32=1.0;var geometry_tangent: vec2f=vec2f(1.0,0.0);var geometry_thickness: f32=0.0;\n#ifdef BASE_WEIGHT\nlet baseWeightFromTexture: vec4f=TEXRD(baseWeightSampler,baseWeightSamplerSampler,fragmentInputs.vBaseWeightUV+uvOffset);\n#endif\n#ifdef BASE_COLOR\nlet baseColorFromTexture: vec4f=TEXRD(baseColorSampler,baseColorSamplerSampler,fragmentInputs.vBaseColorUV+uvOffset);\n#endif\n#ifdef BASE_METALNESS\nlet metallicFromTexture: vec4f=TEXRD(baseMetalnessSampler,baseMetalnessSamplerSampler,fragmentInputs.vBaseMetalnessUV+uvOffset);\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nlet baseDiffuseRoughnessFromTexture: f32=TEXRD(baseDiffuseRoughnessSampler,baseDiffuseRoughnessSamplerSampler,fragmentInputs.vBaseDiffuseRoughnessUV+uvOffset).r;\n#endif\n#ifdef GEOMETRY_TANGENT\nlet geometryTangentFromTexture: vec3f=TEXRD(geometryTangentSampler,geometryTangentSamplerSampler,fragmentInputs.vGeometryTangentUV+uvOffset).rgb;\n#endif\n#ifdef SPECULAR_ROUGHNESS_ANISOTROPY\nlet anisotropyFromTexture: f32=TEXRD(specularRoughnessAnisotropySampler,specularRoughnessAnisotropySamplerSampler,fragmentInputs.vSpecularRoughnessAnisotropyUV+uvOffset).r*uniforms.vSpecularRoughnessAnisotropyInfos.y;\n#endif\n#ifdef GEOMETRY_OPACITY\nlet opacityFromTexture: vec4f=TEXRD(geometryOpacitySampler,geometryOpacitySamplerSampler,fragmentInputs.vGeometryOpacityUV+uvOffset);\n#endif\n#ifdef GEOMETRY_THICKNESS\nlet thicknessFromTexture: vec4f=TEXRD(geometryThicknessSampler,geometryThicknessSamplerSampler,fragmentInputs.vGeometryThicknessUV+uvOffset);\n#endif\n#ifdef DECAL\nlet decalFromTexture: vec4f=textureSample(decalSampler,decalSamplerSampler,fragmentInputs.vDecalUV+uvOffset);\n#endif\n#ifdef SPECULAR_COLOR\nlet specularColorFromTexture: vec4f=TEXRD(specularColorSampler,specularColorSamplerSampler,fragmentInputs.vSpecularColorUV+uvOffset);\n#endif\n#if defined(SPECULAR_WEIGHT)\n#ifdef SPECULAR_WEIGHT_IN_ALPHA\nlet specularWeightFromTexture: f32=TEXRD(specularWeightSampler,specularWeightSamplerSampler,fragmentInputs.vSpecularWeightUV+uvOffset).a;\n#else\nlet specularWeightFromTexture: f32=TEXRD(specularWeightSampler,specularWeightSamplerSampler,fragmentInputs.vSpecularWeightUV+uvOffset).r;\n#endif\n#endif\n#if defined(ANISOTROPIC) || defined(FUZZ) || defined(REFRACTED_BACKGROUND) || defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING)\nlet noise=vec3f(2.0)*textureSample(blueNoiseSampler,blueNoiseSamplerSampler,fragmentInputs.position.xy/256.0).xyz-vec3f(1.0);\n#endif\n#if defined(SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN) && defined(BASE_METALNESS)\nlet roughnessFromTexture: f32=metallicFromTexture.g;\n#elif defined(SPECULAR_ROUGHNESS)\nlet roughnessFromTexture: f32=TEXRD(specularRoughnessSampler,specularRoughnessSamplerSampler,fragmentInputs.vSpecularRoughnessUV+uvOffset).r;\n#endif\nbase_color=uniforms.vBaseColor.rgb;\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nbase_color*=fragmentInputs.vColor.rgb;\n#endif\n#if defined(VERTEXALPHA) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nalpha*=fragmentInputs.vColor.a;\n#endif\nbase_color*=vec3(uniforms.vBaseWeight);alpha=uniforms.vBaseColor.a;base_metalness=uniforms.vReflectanceInfo.x;base_diffuse_roughness=uniforms.vBaseDiffuseRoughness;specular_roughness=uniforms.vReflectanceInfo.y;specular_color=uniforms.vSpecularColor.rgb;specular_weight=uniforms.vReflectanceInfo.a;specular_ior=uniforms.vReflectanceInfo.z;specular_roughness_anisotropy=uniforms.vSpecularAnisotropy.b;geometry_tangent=uniforms.vSpecularAnisotropy.rg;geometry_thickness=uniforms.vGeometryThickness;\n#ifdef BASE_COLOR\n#ifdef BASE_COLOR_GAMMA\nbase_color*=toLinearSpaceVec3(baseColorFromTexture.rgb);\n#else\nbase_color*=baseColorFromTexture.rgb;\n#endif\nbase_color*=uniforms.vBaseColorInfos.y;\n#endif\n#ifdef BASE_WEIGHT\nbase_color*=baseWeightFromTexture.r;\n#endif\n#if defined(BASE_COLOR) && defined(ALPHA_FROM_BASE_COLOR_TEXTURE)\nalpha*=baseColorFromTexture.a;\n#elif defined(GEOMETRY_OPACITY)\nalpha*=opacityFromTexture.r;alpha*=uniforms.vGeometryOpacityInfos.y;\n#endif\n#ifdef GEOMETRY_THICKNESS\n#ifdef GEOMETRY_THICKNESS_FROM_GREEN_CHANNEL\ngeometry_thickness*=thicknessFromTexture.g;\n#else\ngeometry_thickness*=thicknessFromTexture.r;\n#endif\ngeometry_thickness*=uniforms.vGeometryThicknessInfos.y;\n#endif\n#ifdef ALPHATEST\n#if DEBUGMODE != 88\nif (alpha<ALPHATESTVALUE) {discard;}\n#endif\n#ifndef ALPHABLEND\nalpha=1.0;\n#endif\n#endif\n#ifdef BASE_METALNESS\n#ifdef BASE_METALNESS_FROM_METALNESS_TEXTURE_BLUE\nbase_metalness*=metallicFromTexture.b;\n#else\nbase_metalness*=metallicFromTexture.r;\n#endif\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nbase_diffuse_roughness*=baseDiffuseRoughnessFromTexture*uniforms.vBaseDiffuseRoughnessInfos.y;\n#endif\n#ifdef SPECULAR_COLOR\n#ifdef SPECULAR_COLOR_GAMMA\nspecular_color*=toLinearSpaceVec3(specularColorFromTexture.rgb);\n#else\nspecular_color*=specularColorFromTexture.rgb;\n#endif\n#ifdef SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE\nspecular_weight*=specularColorFromTexture.a;\n#elif defined(SPECULAR_WEIGHT)\nspecular_weight*=specularWeightFromTexture;\n#endif\n#endif\n#if defined(SPECULAR_ROUGHNESS) || (defined(SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN) && defined(BASE_METALNESS))\nspecular_roughness*=roughnessFromTexture;\n#endif\n#ifdef GEOMETRY_TANGENT\n{let tangentFromTexture: vec2f=normalize(geometryTangentFromTexture.xy*vec2f(2.0f)-vec2f(1.0f));let tangent_angle_texture: f32=atan2(tangentFromTexture.y,tangentFromTexture.x);let tangent_angle_uniform: f32=atan2(geometry_tangent.y,geometry_tangent.x);let tangent_angle: f32=tangent_angle_texture+tangent_angle_uniform;geometry_tangent=vec2f(cos(tangent_angle),sin(tangent_angle));}\n#endif\n#if defined(GEOMETRY_TANGENT) && defined(SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE)\nspecular_roughness_anisotropy*=geometryTangentFromTexture.b;\n#elif defined(SPECULAR_ROUGHNESS_ANISOTROPY)\nspecular_roughness_anisotropy*=anisotropyFromTexture;\n#endif\n#ifdef DETAIL\nlet detailRoughness: f32=mix(0.5f,detailColor.b,vDetailInfos.w);let loLerp: f32=mix(0.f,specular_roughness,detailRoughness*2.f);let hiLerp: f32=mix(specular_roughness,1.f,(detailRoughness-0.5f)*2.f);specular_roughness=mix(loLerp,hiLerp,step(detailRoughness,0.5f));\n#endif\n#ifdef USE_GLTF_STYLE_ANISOTROPY\nlet baseAlpha: f32=specular_roughness*specular_roughness;let roughnessT: f32=mix(baseAlpha,1.0f,specular_roughness_anisotropy*specular_roughness_anisotropy);let roughnessB: f32=baseAlpha;specular_roughness_anisotropy=1.0f-roughnessB/max(roughnessT,0.00001f);specular_roughness=sqrt(roughnessT/sqrt(2.0f/(1.0f+(1.0f-specular_roughness_anisotropy)*(1.0f-specular_roughness_anisotropy))));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrBaseLayerDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrTransmissionLayerData\";\nconst shader = `var transmission_weight: f32=uniforms.vTransmissionWeight;var transmission_color: vec3f=uniforms.vTransmissionColor.rgb;var transmission_depth: f32=uniforms.vTransmissionDepth;var transmission_scatter: vec3f=uniforms.vTransmissionScatter.rgb;var transmission_scatter_anisotropy: f32=clamp(uniforms.vTransmissionScatterAnisotropy,-0.9999f,0.9999f);var transmission_dispersion_scale: f32=uniforms.vTransmissionDispersionScale;var transmission_dispersion_abbe_number: f32=uniforms.vTransmissionDispersionAbbeNumber;\n#ifdef TRANSMISSION_WEIGHT\nlet transmissionWeightFromTexture: vec4f=TEXRD(transmissionWeightSampler,transmissionWeightSamplerSampler,fragmentInputs.vTransmissionWeightUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_COLOR\nlet transmissionColorFromTexture: vec4f=TEXRD(transmissionColorSampler,transmissionColorSamplerSampler,fragmentInputs.vTransmissionColorUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_DEPTH\nlet transmissionDepthFromTexture: vec4f=TEXRD(transmissionDepthSampler,transmissionDepthSamplerSampler,fragmentInputs.vTransmissionDepthUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_SCATTER\nlet transmissionScatterFromTexture: vec4f=TEXRD(transmissionScatterSampler,transmissionScatterSamplerSampler,fragmentInputs.vTransmissionScatterUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_DISPERSION_SCALE\nlet transmissionDispersionScaleFromTexture: vec4f=TEXRD(transmissionDispersionScaleSampler,transmissionDispersionScaleSamplerSampler,fragmentInputs.vTransmissionDispersionScaleUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_WEIGHT\ntransmission_weight*=transmissionWeightFromTexture.r;\n#endif\n#ifdef TRANSMISSION_COLOR\n#ifdef TRANSMISSION_COLOR_GAMMA\ntransmission_color*=toLinearSpaceVec3(transmissionColorFromTexture.rgb);\n#else\ntransmission_color*=transmissionColorFromTexture.rgb;\n#endif\ntransmission_color*=uniforms.vTransmissionColorInfos.y;\n#endif\n#ifdef TRANSMISSION_DEPTH\ntransmission_depth*=transmissionDepthFromTexture.r;\n#endif\n#ifdef TRANSMISSION_SCATTER\ntransmission_scatter*=transmissionScatterFromTexture.rgb;\n#endif\n#ifdef TRANSMISSION_DISPERSION_SCALE\ntransmission_dispersion_scale*=transmissionDispersionScaleFromTexture.r;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrTransmissionLayerDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrSubsurfaceLayerData\";\nconst shader = `var subsurface_weight: f32=uniforms.vSubsurfaceWeight;var subsurface_color: vec3f=uniforms.vSubsurfaceColor.rgb;var subsurface_radius: f32=uniforms.vSubsurfaceRadius;var subsurface_radius_scale: vec3f=uniforms.vSubsurfaceRadiusScale;var subsurface_scatter_anisotropy: f32=clamp(uniforms.vSubsurfaceScatterAnisotropy,-0.9999f,0.9999f);\n#ifdef SUBSURFACE_WEIGHT\nlet subsurfaceWeightFromTexture: vec4f=TEXRD(subsurfaceWeightSampler,subsurfaceWeightSamplerSampler,fragmentInputs.vSubsurfaceWeightUV+uvOffset);\n#endif\n#ifdef SUBSURFACE_COLOR\nlet subsurfaceColorFromTexture: vec4f=TEXRD(subsurfaceColorSampler,subsurfaceColorSamplerSampler,fragmentInputs.vSubsurfaceColorUV+uvOffset);\n#endif\n#ifdef SUBSURFACE_RADIUS_SCALE\nlet subsurfaceRadiusScaleFromTexture: vec4f=TEXRD(subsurfaceRadiusScaleSampler,subsurfaceRadiusScaleSamplerSampler,fragmentInputs.vSubsurfaceRadiusScaleUV+uvOffset);\n#endif\n#ifdef SUBSURFACE_WEIGHT\n#ifdef SUBSURFACE_WEIGHT_FROM_TEXTURE_ALPHA\nsubsurface_weight*=subsurfaceWeightFromTexture.a;\n#else\nsubsurface_weight*=subsurfaceWeightFromTexture.r;\n#endif\n#endif\n#ifdef SUBSURFACE_COLOR\n#ifdef SUBSURFACE_COLOR_GAMMA\nsubsurface_color*=toLinearSpaceVec3(subsurfaceColorFromTexture.rgb);\n#else\nsubsurface_color*=subsurfaceColorFromTexture.rgb;\n#endif\nsubsurface_color*=uniforms.vSubsurfaceColorInfos.y;\n#endif\n#ifdef SUBSURFACE_RADIUS_SCALE\nsubsurface_radius_scale*=subsurfaceRadiusScaleFromTexture.rgb;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrSubsurfaceLayerDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrCoatLayerData\";\nconst shader = `var coat_weight: f32=0.0f;var coat_color: vec3f=vec3f(1.0f);var coat_roughness: f32=0.0f;var coat_roughness_anisotropy: f32=0.0f;var coat_ior: f32=1.6f;var coat_darkening: f32=1.0f;var geometry_coat_tangent: vec2f=vec2f(1.0f,0.0f);\n#ifdef COAT_WEIGHT\nvar coatWeightFromTexture: vec4f=TEXRD(coatWeightSampler,coatWeightSamplerSampler,fragmentInputs.vCoatWeightUV+uvOffset);\n#endif\n#ifdef COAT_COLOR\nvar coatColorFromTexture: vec4f=TEXRD(coatColorSampler,coatColorSamplerSampler,fragmentInputs.vCoatColorUV+uvOffset);\n#endif\n#ifdef COAT_ROUGHNESS\nvar coatRoughnessFromTexture: vec4f=TEXRD(coatRoughnessSampler,coatRoughnessSamplerSampler,fragmentInputs.vCoatRoughnessUV+uvOffset);\n#endif\n#ifdef COAT_ROUGHNESS_ANISOTROPY\nvar coatRoughnessAnisotropyFromTexture: f32=TEXRD(coatRoughnessAnisotropySampler,coatRoughnessAnisotropySamplerSampler,fragmentInputs.vCoatRoughnessAnisotropyUV+uvOffset).r;\n#endif\n#ifdef COAT_DARKENING\nvar coatDarkeningFromTexture: vec4f=TEXRD(coatDarkeningSampler,coatDarkeningSamplerSampler,fragmentInputs.vCoatDarkeningUV+uvOffset);\n#endif\n#ifdef GEOMETRY_COAT_TANGENT\nvar geometryCoatTangentFromTexture: vec3f=TEXRD(geometryCoatTangentSampler,geometryCoatTangentSamplerSampler,fragmentInputs.vGeometryCoatTangentUV+uvOffset).rgb;\n#endif\ncoat_color=uniforms.vCoatColor.rgb;coat_weight=uniforms.vCoatWeight;coat_roughness=uniforms.vCoatRoughness;coat_roughness_anisotropy=uniforms.vCoatRoughnessAnisotropy;coat_ior=uniforms.vCoatIor;coat_darkening=uniforms.vCoatDarkening;geometry_coat_tangent=uniforms.vGeometryCoatTangent.rg;\n#ifdef COAT_WEIGHT\ncoat_weight*=coatWeightFromTexture.r;\n#endif\n#ifdef COAT_COLOR\n#ifdef COAT_COLOR_GAMMA\ncoat_color*=toLinearSpaceVec3(coatColorFromTexture.rgb);\n#else\ncoat_color*=coatColorFromTexture.rgb;\n#endif\ncoat_color*=uniforms.vCoatColorInfos.y;\n#endif\n#ifdef COAT_ROUGHNESS\n#ifdef COAT_ROUGHNESS_FROM_GREEN_CHANNEL\ncoat_roughness*=coatRoughnessFromTexture.g;\n#else\ncoat_roughness*=coatRoughnessFromTexture.r;\n#endif\n#endif\n#if defined(GEOMETRY_COAT_TANGENT) && defined(COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE)\ncoat_roughness_anisotropy*=geometryCoatTangentFromTexture.b;\n#elif defined(COAT_ROUGHNESS_ANISOTROPY)\ncoat_roughness_anisotropy*=coatRoughnessAnisotropyFromTexture;\n#endif\n#ifdef COAT_DARKENING\ncoat_darkening*=coatDarkeningFromTexture.r;\n#endif\n#ifdef GEOMETRY_COAT_TANGENT\n{let tangentFromTexture: vec2f=normalize(geometryCoatTangentFromTexture.xy*vec2f(2.0f)-vec2f(1.0f));let tangent_angle_texture: f32=atan2(tangentFromTexture.y,tangentFromTexture.x);let tangent_angle_uniform: f32=atan2(geometry_coat_tangent.y,geometry_coat_tangent.x);let tangent_angle: f32=tangent_angle_texture+tangent_angle_uniform;geometry_coat_tangent=vec2f(cos(tangent_angle),sin(tangent_angle));}\n#endif\n#ifdef USE_GLTF_STYLE_ANISOTROPY\nlet coatAlpha: f32=coat_roughness*coat_roughness;let coatRoughnessT: f32=mix(coatAlpha,1.0f,coat_roughness_anisotropy*coat_roughness_anisotropy);let coatRoughnessB: f32=coatAlpha;coat_roughness_anisotropy=1.0f-coatRoughnessB/max(coatRoughnessT,0.00001f);coat_roughness=sqrt(coatRoughnessT/sqrt(2.0f/(1.0f+(1.0f-coat_roughness_anisotropy)*(1.0f-coat_roughness_anisotropy))));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrCoatLayerDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrThinFilmLayerData\";\nconst shader = `#ifdef THIN_FILM\nvar thin_film_weight: f32=uniforms.vThinFilmWeight;var thin_film_thickness: f32=uniforms.vThinFilmThickness.r*1000.0f; \nvar thin_film_ior: f32=uniforms.vThinFilmIor;\n#ifdef THIN_FILM_WEIGHT\nvar thinFilmWeightFromTexture: f32=TEXRD(thinFilmWeightSampler,thinFilmWeightSamplerSampler,fragmentInputs.vThinFilmWeightUV+uvOffset).r*uniforms.vThinFilmWeightInfos.y;\n#endif\n#ifdef THIN_FILM_THICKNESS\nvar thinFilmThicknessFromTexture: f32=TEXRD(thinFilmThicknessSampler,thinFilmThicknessSamplerSampler,fragmentInputs.vThinFilmThicknessUV+uvOffset).g*uniforms.vThinFilmThicknessInfos.y;\n#endif\n#ifdef THIN_FILM_WEIGHT\nthin_film_weight*=thinFilmWeightFromTexture;\n#endif\n#ifdef THIN_FILM_THICKNESS\nthin_film_thickness*=thinFilmThicknessFromTexture;\n#endif\nlet thin_film_ior_scale: f32=clamp(2.0f*abs(thin_film_ior-1.0f),0.0f,1.0f);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrThinFilmLayerDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrFuzzLayerData\";\nconst shader = `var fuzz_weight: f32=0.0f;var fuzz_color: vec3f=vec3f(1.0f);var fuzz_roughness: f32=0.0f;\n#ifdef FUZZ\n#ifdef FUZZ_WEIGHT\nlet fuzzWeightFromTexture: vec4f=TEXRD(fuzzWeightSampler,fuzzWeightSamplerSampler,fragmentInputs.vFuzzWeightUV+uvOffset);\n#endif\n#ifdef FUZZ_COLOR\nvar fuzzColorFromTexture: vec4f=TEXRD(fuzzColorSampler,fuzzColorSamplerSampler,fragmentInputs.vFuzzColorUV+uvOffset);\n#endif\n#ifdef FUZZ_ROUGHNESS\nlet fuzzRoughnessFromTexture: vec4f=TEXRD(fuzzRoughnessSampler,fuzzRoughnessSamplerSampler,fragmentInputs.vFuzzRoughnessUV+uvOffset);\n#endif\nfuzz_color=uniforms.vFuzzColor.rgb;fuzz_weight=uniforms.vFuzzWeight;fuzz_roughness=uniforms.vFuzzRoughness;\n#ifdef FUZZ_WEIGHT\nfuzz_weight*=fuzzWeightFromTexture.r;\n#endif\n#ifdef FUZZ_COLOR\n#ifdef FUZZ_COLOR_GAMMA\nfuzz_color*=toLinearSpaceVec3(fuzzColorFromTexture.rgb);\n#else\nfuzz_color*=fuzzColorFromTexture.rgb;\n#endif\nfuzz_color*=uniforms.vFuzzColorInfos.y;\n#endif\n#if defined(FUZZ_ROUGHNESS) && defined(FUZZ_ROUGHNESS_FROM_TEXTURE_ALPHA)\nfuzz_roughness*=fuzzRoughnessFromTexture.a;\n#elif defined(FUZZ_ROUGHNESS)\nfuzz_roughness*=fuzzRoughnessFromTexture.r;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrFuzzLayerDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrAmbientOcclusionData\";\nconst shader = `var ambient_occlusion: vec3f=vec3f(1.0f,1.0f,1.0f);var specular_ambient_occlusion: f32=1.0f;var coat_specular_ambient_occlusion: f32=1.0f;\n#ifdef AMBIENT_OCCLUSION\nvar ambientOcclusionFromTexture: vec3f=TEXRD(ambientOcclusionSampler,ambientOcclusionSamplerSampler,fragmentInputs.vAmbientOcclusionUV+uvOffset).rgb;ambient_occlusion=vec3f(ambientOcclusionFromTexture.r*uniforms.vAmbientOcclusionInfos.y+(1.0f-uniforms.vAmbientOcclusionInfos.y));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrAmbientOcclusionDataWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBackgroundTransmission\";\nconst shader = `var slab_translucent_background: vec4f=vec4f(0.,0.,0.,1.);\n#ifdef REFRACTED_BACKGROUND\n{let refractionLOD: f32=min(transmission_roughness,0.8)*uniforms.vBackgroundRefractionInfos.x;let lodTexelSize: f32=pow(2.0f,refractionLOD-uniforms.vBackgroundRefractionInfos.x);\n#ifdef DISPERSION\n{\n#ifdef REFRACTION_HIGH_QUALITY_BLUR\n{var dispResult: vec3f=vec3f(0.0);var dispWeight: vec3f=vec3f(0.0);let noiseOffset: vec2f=noise.xy*select(0.0f,lodTexelSize,refractionLOD>0.0f);for (var k: i32=0; k<6; k++) {let t: f32=(f32(k)+noise.y)/6.0f;let t_rg: f32=clamp(t*2.0f,0.0f,1.0f);let t_gb: f32=clamp((t-0.5f)*2.0f,0.0f,1.0f);let refVec: vec3f=mix(mix(refractedViewVectors[0],refractedViewVectors[1],t_rg),refractedViewVectors[2],t_gb);let uvw: vec3f=vec3f((uniforms.backgroundRefractionMatrix*(scene.view*vec4f(fragmentInputs.vPositionW+refVec*geometry_thickness,1.0f))).xyz);var coords: vec2f=uvw.xy/uvw.z;coords.y=1.0f-coords.y;let s: vec4f=textureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,coords+noiseOffset,refractionLOD);let rw: f32=max(0.0f,1.0f-2.0f*t);let gw: f32=max(0.0f,1.0f-abs(2.0f*t-1.0f));let bw: f32=max(0.0f,2.0f*t-1.0f);let w: vec3f=vec3f(rw,gw,bw);dispResult+=s.rgb*w;dispWeight+=w;}\nslab_translucent_background=vec4f(dispResult/max(dispWeight,vec3f(1e-6)),1.0f);}\n#else\nfor (var i: i32=0; i<3; i++) {let refractedViewVector: vec3f=refractedViewVectors[i];let uvw: vec3f=vec3f((uniforms.backgroundRefractionMatrix*(scene.view*vec4f(fragmentInputs.vPositionW+refractedViewVector*geometry_thickness,1.0f))).xyz);var coords: vec2f=uvw.xy/uvw.z;coords.y=1.0f-coords.y;if (refractionLOD>0.0f) {let noiseOffset: vec2f=noise.xy*lodTexelSize;slab_translucent_background[i]=textureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,coords+noiseOffset,refractionLOD)[i];} else {slab_translucent_background[i]=textureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,coords,0.0f)[i];}}\n#endif\n}\n#else\n{let refractionUVW: vec3f=vec3f((uniforms.backgroundRefractionMatrix*(scene.view*vec4f(fragmentInputs.vPositionW+refractedViewVector*geometry_thickness,1.0f))).xyz);var refractionCoords: vec2f=refractionUVW.xy/refractionUVW.z;refractionCoords.y=1.0f-refractionCoords.y;if (refractionLOD>0.0f) {\n#ifdef REFRACTION_HIGH_QUALITY_BLUR\nlet cosA: f32=cos(noise.x*PI);let sinA: f32=sin(noise.x*PI);let u: vec2f=vec2f( cosA,sinA)*(0.5f*lodTexelSize);let v: vec2f=vec2f(-sinA,cosA)*(0.5f*lodTexelSize);slab_translucent_background=0.25f*(\ntextureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,refractionCoords+u+v,refractionLOD) +\ntextureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,refractionCoords-u+v,refractionLOD) +\ntextureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,refractionCoords+u-v,refractionLOD) +\ntextureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,refractionCoords-u-v,refractionLOD)\n);\n#else\nlet noiseOffset: vec2f=noise.xy*lodTexelSize;slab_translucent_background=textureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,refractionCoords+noiseOffset,refractionLOD);\n#endif\n} else {slab_translucent_background=textureSampleLevel(backgroundRefractionSampler,backgroundRefractionSamplerSampler,refractionCoords,0.0f);}}\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrBackgroundTransmissionWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrEnvironmentLighting\";\nconst shader = `#if defined(REFLECTION) || defined(REFRACTED_BACKGROUND)\nvar coatAbsorption=vec3f(1.0f);var coatIblFresnel: f32=0.0;if (coat_weight>0.0) {coatIblFresnel=computeDielectricIblFresnel(coatReflectance,coatGeoInfo.environmentBrdf);let hemisphere_avg_fresnel: f32=coatReflectance.F0+0.5f*(1.0f-coatReflectance.F0);var averageReflectance: f32=(coatIblFresnel+hemisphere_avg_fresnel)*0.5f;let roughnessFactor=1.0f-coat_roughness*0.5f;averageReflectance*=roughnessFactor;var darkened_transmission: f32=(1.0f-averageReflectance)*(1.0f-averageReflectance);darkened_transmission=mix(1.0,darkened_transmission,coat_darkening);var sin2: f32=1.0f-coatGeoInfo.NdotV*coatGeoInfo.NdotV;sin2=sin2/(coat_ior*coat_ior)*coat_weight;let cos_t: f32=sqrt(1.0f-sin2);let coatPathLength=1.0f/cos_t;let effectivePathLength=coatPathLength*coat_weight;let colored_transmission: vec3f=pow(coat_color,vec3f(effectivePathLength));coatAbsorption=colored_transmission*mix(1.0f,darkened_transmission,coat_weight);}\n#endif\n#ifdef REFLECTION\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nlet environmentFuzzBrdf: vec3f=getFuzzBRDFLookup(fuzzGeoInfo.NdotV,sqrt(fuzz_roughness));\n#endif\nvar baseDiffuseEnvironmentLight: vec3f=sampleIrradiance(\nnormalW\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance \n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,uniforms.reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n,irradianceSamplerSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,uniforms.vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n#endif\n,uniforms.vReflectionInfos\n,viewDirectionW\n,base_diffuse_roughness\n,base_color\n);\n#ifdef REFLECTIONMAP_3D\nvar reflectionCoords: vec3f=vec3f(0.f,0.f,0.f);\n#else\nvar reflectionCoords: vec2f=vec2f(0.f,0.f);\n#endif\nlet specularAlphaG: f32=specular_roughness*specular_roughness;\n#ifdef ANISOTROPIC_BASE\nvar baseSpecularEnvironmentLight: vec3f=sampleRadianceAnisotropic(specularAlphaG,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,baseGeoInfo\n,normalW\n,viewDirectionW\n,fragmentInputs.vPositionW\n,noise\n,false \n,1.0 \n,reflectionSampler\n,reflectionSamplerSampler\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);\n#else\nreflectionCoords=createReflectionCoords(fragmentInputs.vPositionW,normalW);var baseSpecularEnvironmentLight: vec3f=sampleRadiance(specularAlphaG,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,baseGeoInfo\n,reflectionSampler\n,reflectionSamplerSampler\n,reflectionCoords\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);\n#endif\n#ifdef ANISOTROPIC_BASE\nbaseSpecularEnvironmentLight=mix(baseSpecularEnvironmentLight.rgb,baseDiffuseEnvironmentLight,specularAlphaG*specularAlphaG *max(1.0f-baseGeoInfo.anisotropy,0.3f));\n#else\nbaseSpecularEnvironmentLight=mix(baseSpecularEnvironmentLight.rgb,baseDiffuseEnvironmentLight,specularAlphaG);\n#endif\nvar coatEnvironmentLight: vec3f=vec3f(0.f,0.f,0.f);if (coat_weight>0.0) {\n#ifdef REFLECTIONMAP_3D\nvar reflectionCoords: vec3f=vec3f(0.f,0.f,0.f);\n#else\nvar reflectionCoords: vec2f=vec2f(0.f,0.f);\n#endif\nreflectionCoords=createReflectionCoords(fragmentInputs.vPositionW,coatNormalW);var coatAlphaG: f32=coat_roughness*coat_roughness;\n#ifdef ANISOTROPIC_COAT\ncoatEnvironmentLight=sampleRadianceAnisotropic(coatAlphaG,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,coatGeoInfo\n,coatNormalW\n,viewDirectionW\n,fragmentInputs.vPositionW\n,noise\n,false \n,1.0 \n,reflectionSampler\n,reflectionSamplerSampler\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);\n#else\ncoatEnvironmentLight=sampleRadiance(coatAlphaG,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,coatGeoInfo\n,reflectionSampler\n,reflectionSamplerSampler\n,reflectionCoords\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);\n#endif\n}\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nlet modifiedFuzzRoughness: f32=clamp(fuzz_roughness*fuzz_roughness*(1.0f+0.5f*environmentFuzzBrdf.y),0.0f,1.0f);var fuzzEnvironmentLight=vec3f(0.0f,0.0f,0.0f);let fuzzIblFresnel: f32=min(environmentFuzzBrdf.z*2.0f,1.0f);let viewTangent: vec2f=vec2f(dot(viewDirectionW,fuzzTangent),dot(viewDirectionW,fuzzBitangent));let centerAngle: f32=atan2(viewTangent.y,viewTangent.x);for (var i: i32=0; i<i32(FUZZ_IBL_SAMPLES); i++) {let angle: f32=centerAngle+(f32(i)/f32(FUZZ_IBL_SAMPLES)-0.5f+noise.x/f32(FUZZ_IBL_SAMPLES))*3.141592f;let fiberCylinderNormal: vec3f=normalize(cos(angle)*fuzzTangent+sin(angle)*fuzzBitangent);let fuzzReflectionCoords: vec3f=(uniforms.reflectionMatrix*vec4f(fiberCylinderNormal,0.0f)).xyz;let radianceSample: vec3f=sampleRadiance(modifiedFuzzRoughness,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,fuzzGeoInfo\n,reflectionSampler\n,reflectionSamplerSampler\n,fuzzReflectionCoords\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);fuzzEnvironmentLight+=radianceSample;}\nfuzzEnvironmentLight/=f32(FUZZ_IBL_SAMPLES);\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL)\nvar fuzzDiffuseEnvironmentLight: vec3f=sampleIrradiance(\nfuzzNormalW\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance \n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,uniforms.reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n,irradianceSamplerSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,uniforms.vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n#endif\n,uniforms.vReflectionInfos\n,viewDirectionW\n,0.0f\n,vec3f(1.0f)\n);\n#else\nvar fuzzDiffuseEnvironmentLight: vec3f=baseDiffuseEnvironmentLight;\n#endif\nfuzzEnvironmentLight=mix(min(fuzzEnvironmentLight,fuzzDiffuseEnvironmentLight),fuzzDiffuseEnvironmentLight,modifiedFuzzRoughness);\n#endif\nvar dielectricIblFresnel: f32=computeDielectricIblFresnel(baseDielectricReflectance,baseGeoInfo.environmentBrdf);var dielectricIblColoredFresnel: vec3f=dielectricIblFresnel*specular_color;\n#ifdef THIN_FILM\nlet thin_film_cos_theta: f32=max(baseGeoInfo.NdotV,specularAlphaG);let thin_film_desaturation_scale=(thin_film_ior-1.0)*sqrt(thin_film_thickness*0.001f*thin_film_cos_theta);let tf_brdf_x: f32=baseGeoInfo.environmentBrdf.x;let tf_E_ss: f32 =baseGeoInfo.environmentBrdf.y;var thinFilmDielectricF0: vec3f=evalIridescence(thin_film_outside_ior,thin_film_ior,1.0,thin_film_thickness,vec3f(baseDielectricReflectance.F0));thinFilmDielectricF0=mix(thinFilmDielectricF0,vec3(dot(thinFilmDielectricF0,vec3f(0.3333f))),thin_film_desaturation_scale);var thinFilmDielectricDir: vec3f=evalIridescence(thin_film_outside_ior,thin_film_ior,thin_film_cos_theta,thin_film_thickness,vec3f(baseDielectricReflectance.F0));thinFilmDielectricDir=mix(thinFilmDielectricDir,vec3(dot(thinFilmDielectricDir,vec3f(0.3333f))),thin_film_desaturation_scale);let tf_f0d_avg: f32 =dot(thinFilmDielectricF0, vec3f(0.3333f));let tf_dird_avg: f32=dot(thinFilmDielectricDir,vec3f(0.3333f));var thin_film_dielectric: vec3f=thinFilmDielectricDir*(tf_f0d_avg/max(tf_dird_avg,1e-5));let tf_E_dielectric: vec3f=(vec3f(1.0)-thin_film_dielectric)*vec3f(tf_brdf_x)+thin_film_dielectric*vec3f(tf_E_ss);let tf_F_avg_dielectric: vec3f=thin_film_dielectric+(vec3f(1.0)-thin_film_dielectric)/21.0;let tf_ECF_dielectric: vec3f=vec3f(1.0)+tf_F_avg_dielectric*(vec3f(1.0)/vec3f(tf_E_ss)-vec3f(1.0));thin_film_dielectric=clamp(tf_E_dielectric*tf_ECF_dielectric,vec3f(0.0),vec3f(1.0));dielectricIblColoredFresnel=mix(dielectricIblColoredFresnel,thin_film_dielectric*specular_color,thin_film_weight*thin_film_ior_scale);dielectricIblFresnel=max(dielectricIblColoredFresnel.r,max(dielectricIblColoredFresnel.g,dielectricIblColoredFresnel.b));\n#endif\nvar conductorIblFresnel: vec3f=computeConductorIblFresnel(baseConductorReflectance,baseGeoInfo.environmentBrdf);\n#ifdef THIN_FILM\nvar thinFilmConductorF0: vec3f=evalIridescence(thin_film_outside_ior,thin_film_ior,1.0,thin_film_thickness,baseConductorReflectance.coloredF0);thinFilmConductorF0=mix(thinFilmConductorF0,vec3(dot(thinFilmConductorF0,vec3f(0.3333f))),thin_film_desaturation_scale);var thinFilmConductorDir: vec3f=evalIridescence(thin_film_outside_ior,thin_film_ior,thin_film_cos_theta,thin_film_thickness,baseConductorReflectance.coloredF0);thinFilmConductorDir=mix(thinFilmConductorDir,vec3(dot(thinFilmConductorDir,vec3f(0.3333f))),thin_film_desaturation_scale);let tf_f0c_avg: f32 =dot(thinFilmConductorF0, vec3f(0.3333f));let tf_dirc_avg: f32=dot(thinFilmConductorDir,vec3f(0.3333f));var thinFilmConductorRaw: vec3f=thinFilmConductorDir*(tf_f0c_avg/max(tf_dirc_avg,1e-5));\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR) && defined(ENVIRONMENTBRDF)\nlet tf_b: vec3f=getF82B(baseConductorReflectance.coloredF0,baseConductorReflectance.coloredF90);let tf_brdf_z: f32=baseGeoInfo.environmentBrdf.z/BRDF_Z_SCALE;let tf_E_conductor: vec3f=(vec3f(1.0)-thinFilmConductorRaw)*vec3f(tf_brdf_x)+thinFilmConductorRaw*vec3f(tf_E_ss)-tf_b*vec3f(tf_brdf_z);let tf_F_avg_conductor: vec3f=thinFilmConductorRaw+(vec3f(1.0)-thinFilmConductorRaw)/21.0-tf_b/126.0;\n#else\nlet tf_E_conductor: vec3f=(vec3f(1.0)-thinFilmConductorRaw)*vec3f(tf_brdf_x)+thinFilmConductorRaw*vec3f(tf_E_ss);let tf_F_avg_conductor: vec3f=thinFilmConductorRaw+(vec3f(1.0)-thinFilmConductorRaw)/21.0;\n#endif\nlet tf_ECF_conductor: vec3f=vec3f(1.0)+tf_F_avg_conductor*(vec3f(1.0)/vec3f(tf_E_ss)-vec3f(1.0));var thinFilmConductorFresnel: vec3f=specular_weight*clamp(tf_E_conductor*tf_ECF_conductor,vec3f(0.0),vec3f(1.0));conductorIblFresnel=mix(conductorIblFresnel,thinFilmConductorFresnel,thin_film_weight*thin_film_ior_scale);\n#endif\nvar slab_diffuse_ibl: vec3f=vec3f(0.,0.,0.);var slab_glossy_ibl: vec3f=vec3f(0.,0.,0.);var slab_metal_ibl: vec3f=vec3f(0.,0.,0.);var slab_coat_ibl: vec3f=vec3f(0.,0.,0.);slab_diffuse_ibl=baseDiffuseEnvironmentLight*uniforms.vLightingIntensity.z;\n#ifdef AMBIENT_OCCLUSION\nspecular_ambient_occlusion=compute_specular_occlusion(baseGeoInfo.NdotV,base_metalness,ambient_occlusion.x,specular_roughness);\n#endif\nslab_glossy_ibl=baseSpecularEnvironmentLight*uniforms.vLightingIntensity.z;slab_metal_ibl=baseSpecularEnvironmentLight*conductorIblFresnel*uniforms.vLightingIntensity.z;if (coat_weight>0.0) {slab_coat_ibl=coatEnvironmentLight*uniforms.vLightingIntensity.z;\n#ifdef AMBIENT_OCCLUSION\ncoat_specular_ambient_occlusion=compute_specular_occlusion(coatGeoInfo.NdotV,0.0,ambient_occlusion.x,coat_roughness);\n#endif\n}\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nvar slab_fuzz_ibl=fuzzEnvironmentLight*uniforms.vLightingIntensity.z;\n#endif\nvar slab_translucent_base_ibl: vec3f=vec3f(0.0f,0.0f,0.0f);\n#ifdef REFRACTED_ENVIRONMENT\n#ifdef ANISOTROPIC_BASE\nvar forwardScatteredEnvironmentLight: vec3f=sampleRadianceAnisotropic(transmission_roughness_alpha,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,baseGeoInfo\n#ifdef GEOMETRY_THIN_WALLED\n,viewDirectionW\n#else\n,normalW\n#endif\n,viewDirectionW\n,fragmentInputs.vPositionW\n,noise\n,true \n#ifdef GEOMETRY_THIN_WALLED\n,1.05f \n#else\n,specular_ior \n#endif\n,reflectionSampler\n,reflectionSamplerSampler\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);\n#else\nvar forwardScatteredEnvironmentLight: vec3f=vec3f(0.,0.,0.);\n#ifdef DISPERSION\nfor (var i: i32=0; i<3; i++) {var iblRefractionCoords: vec3f=refractedViewVectors[i];\n#else\nvar iblRefractionCoords: vec3f=refractedViewVector;\n#endif\n#ifdef REFRACTED_ENVIRONMENT_OPPOSITEZ\niblRefractionCoords.z*=-1.0f;\n#endif\n#ifdef REFRACTED_ENVIRONMENT_LOCAL_CUBE\niblRefractionCoords=parallaxCorrectNormal(fragmentInputs.vPositionW,refractedViewVector,uniforms.refractionSize,uniforms.refractionPosition);\n#endif\niblRefractionCoords=(uniforms.reflectionMatrix*vec4f(iblRefractionCoords,0.0f)).xyz;\n#ifdef DISPERSION\nforwardScatteredEnvironmentLight[i]=sampleRadiance(transmission_roughness_alpha,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,baseGeoInfo\n,reflectionSampler\n,reflectionSamplerSampler\n,iblRefractionCoords\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n)[i];\n#else\nforwardScatteredEnvironmentLight=sampleRadiance(transmission_roughness_alpha,uniforms.vReflectionMicrosurfaceInfos.rgb,uniforms.vReflectionInfos\n,baseGeoInfo\n,reflectionSampler\n,reflectionSamplerSampler\n,iblRefractionCoords\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#endif\n);\n#endif\n#ifdef DISPERSION\n}\n#endif\n#endif\n#ifdef REFRACTED_BACKGROUND\n#ifdef GEOMETRY_THIN_WALLED\nforwardScatteredEnvironmentLight=mix(slab_translucent_background.rgb,forwardScatteredEnvironmentLight.rgb,0.2*transmission_roughness_alpha);\n#else\nforwardScatteredEnvironmentLight=max(slab_translucent_background.rgb,mix(slab_translucent_background.rgb,forwardScatteredEnvironmentLight,transmission_roughness_alpha));\n#endif\n#endif\n#ifdef SCATTERING\n#ifdef GEOMETRY_THIN_WALLED\nvar scatterVector: vec3f=normalW;\n#else\n#if defined(USEIRRADIANCEMAP) && defined(USE_IRRADIANCE_DOMINANT_DIRECTION)\nvar scatterVector: vec3f=mix(uniforms.vReflectionDominantDirection,normalW,max3(iso_scatter_density));\n#else\nvar scatterVector: vec3f=normalW;\n#endif\nscatterVector=mix(viewDirectionW,scatterVector,back_to_iso_scattering_blend);\n#endif\n#if defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) && !defined(GEOMETRY_THIN_WALLED)\nvar scatteredEnvironmentLight: vec3f=scattered_light_from_irradiance_texture;\n#else\nvar scatteredEnvironmentLight: vec3f=sampleIrradiance(\nscatterVector\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance \n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,uniforms.reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n,irradianceSamplerSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,uniforms.vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n#endif\n,uniforms.vReflectionInfos\n,viewDirectionW\n#if defined(GEOMETRY_THIN_WALLED)\n,base_diffuse_roughness\n,subsurface_color.rgb\n#else\n,1.0f\n,volumeParams.multi_scatter_color\n#endif\n);\n#endif\n#ifdef GEOMETRY_THIN_WALLED\nlet forward_scattered_light: vec3f=forwardScatteredEnvironmentLight*transmission_tint*volumeParams.multi_scatter_color;let back_scattered_light: vec3f=scatteredEnvironmentLight*volumeParams.multi_scatter_color;slab_translucent_base_ibl=mix(back_scattered_light,forward_scattered_light,0.5f+0.5f*volumeParams.anisotropy);\n#else\nlet forward_scattered_light: vec3f=forwardScatteredEnvironmentLight*volume_absorption;let back_scattered_light: vec3f=mix(forward_scattered_light,scatteredEnvironmentLight*backscatter_color,iso_scatter_density);let iso_scattered_light: vec3f=mix(forward_scattered_light,scatteredEnvironmentLight*volumeParams.multi_scatter_color,iso_scatter_density);slab_translucent_base_ibl=mix(back_scattered_light,iso_scattered_light,back_to_iso_scattering_blend);slab_translucent_base_ibl=mix(slab_translucent_base_ibl,forward_scattered_light,iso_to_forward_scattering_blend)*transmission_tint;\n#endif\n#else\nslab_translucent_base_ibl+=forwardScatteredEnvironmentLight*transmission_tint*volume_absorption;\n#endif\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_IBLLAYERCOMPOSITION\nslab_diffuse_ibl*=ambient_occlusion;slab_metal_ibl*=specular_ambient_occlusion;slab_glossy_ibl*=specular_ambient_occlusion;slab_coat_ibl*=coat_specular_ambient_occlusion;let material_dielectric_base_ibl: vec3f=mix(slab_diffuse_ibl*base_color.rgb,slab_translucent_base_ibl,surface_translucency_weight);let material_dielectric_gloss_ibl: vec3f=material_dielectric_base_ibl*(1.0-dielectricIblFresnel)+slab_glossy_ibl*dielectricIblColoredFresnel;let material_base_substrate_ibl: vec3f=mix(material_dielectric_gloss_ibl,slab_metal_ibl,base_metalness);let material_coated_base_ibl: vec3f=layer(material_base_substrate_ibl,slab_coat_ibl,coatIblFresnel,coatAbsorption,vec3f(1.0f));\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nslab_fuzz_ibl*=min(vec3(specular_ambient_occlusion),ambient_occlusion);material_surface_ibl=layer(material_coated_base_ibl,slab_fuzz_ibl,fuzzIblFresnel*fuzz_weight,vec3f(1.0f),fuzz_color);\n#else\nmaterial_surface_ibl=material_coated_base_ibl;\n#endif\n#elif defined(REFRACTED_BACKGROUND)\nlet black=vec3f(0.0f);var slab_translucent_base_ibl: vec3f=vec3f(0.0f);\n#ifdef GEOMETRY_THIN_WALLED\n#ifdef SCATTERING\nlet forward_scattered_light: vec3f=slab_translucent_background.rgb*transmission_tint*volumeParams.multi_scatter_color;slab_translucent_base_ibl=mix(black,forward_scattered_light,0.5f+0.5f*volumeParams.anisotropy);\n#else\nslab_translucent_base_ibl=slab_translucent_background.rgb*transmission_tint;\n#endif\n#else\n#ifdef SCATTERING\nlet forward_scattered_light: vec3f=slab_translucent_background.rgb*volume_absorption;let iso_scattered_light: vec3f=(1.0f-iso_scatter_density)*forward_scattered_light;slab_translucent_base_ibl=mix(black,iso_scattered_light,back_to_iso_scattering_blend);slab_translucent_base_ibl=mix(slab_translucent_base_ibl,forward_scattered_light,iso_to_forward_scattering_blend)*transmission_tint;\n#else\nslab_translucent_base_ibl=slab_translucent_background.rgb*volume_absorption*transmission_tint;\n#endif\n#endif\nlet material_dielectric_base_ibl: vec3f=mix(black,slab_translucent_base_ibl.rgb,surface_translucency_weight);let material_dielectric_gloss_ibl: vec3f=material_dielectric_base_ibl*(baseGeoInfo.NdotV);let material_base_substrate_ibl: vec3f=mix(material_dielectric_gloss_ibl,black,base_metalness);let material_coated_base_ibl: vec3f=layer(material_base_substrate_ibl,black,coatIblFresnel,coatAbsorption,vec3f(1.0f));material_surface_ibl=material_coated_base_ibl;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrEnvironmentLightingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrDirectLightingInit\";\nconst shader = `#ifdef LIGHT{X}\nvar preInfo{X}: preLightingInfo;var preInfoCoat{X}: preLightingInfo;let lightColor{X}: vec4f=light{X}.vLightDiffuse;var shadow{X}: f32=1.0f;\n#if defined(SHADOWONLY) || defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})\n#else\n#define CUSTOM_LIGHT{X}_COLOR \n#ifdef SPOTLIGHT{X}\npreInfo{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,fragmentInputs.vPositionW);preInfoCoat{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW,fragmentInputs.vPositionW);\n#elif defined(POINTLIGHT{X})\npreInfo{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,fragmentInputs.vPositionW);preInfoCoat{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW,fragmentInputs.vPositionW);\n#elif defined(HEMILIGHT{X})\npreInfo{X}=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);preInfoCoat{X}=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW);\n#elif defined(DIRLIGHT{X})\npreInfo{X}=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);preInfoCoat{X}=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\npreInfo{X}=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC1SamplerSampler,areaLightsLTC2Sampler,areaLightsLTC2SamplerSampler,viewDirectionW,normalW,fragmentInputs.vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,specular_roughness);preInfoCoat{X}=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC1SamplerSampler,areaLightsLTC2Sampler,areaLightsLTC2SamplerSampler,viewDirectionW,coatNormalW,fragmentInputs.vPositionW,light{X}.vLightData.xyz,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,coat_roughness);\n#endif\npreInfo{X}.NdotV=baseGeoInfo.NdotV;preInfoCoat{X}.NdotV=coatGeoInfo.NdotV;\n#ifdef SPOTLIGHT{X}\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo{X}.attenuation=computeDistanceLightFalloff_GLTF(preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_GLTF(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Physical(preInfo{X}.lightDistanceSquared);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_Physical(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightDirection.w);\n#endif\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Standard(preInfo{X}.lightOffset,light{X}.vLightFalloff.x);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_Standard(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightDirection.w,light{X}.vLightData.w);\n#endif\n#else\npreInfo{X}.attenuation=computeDistanceLightFalloff(preInfo{X}.lightOffset,preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightDirection.w,light{X}.vLightData.w,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#endif\n#elif defined(POINTLIGHT{X})\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo{X}.attenuation=computeDistanceLightFalloff_GLTF(preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.y);\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Physical(preInfo{X}.lightDistanceSquared);\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Standard(preInfo{X}.lightOffset,light{X}.vLightFalloff.x);\n#else\npreInfo{X}.attenuation=computeDistanceLightFalloff(preInfo{X}.lightOffset,preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#endif\n#else\npreInfo{X}.attenuation=1.0f;\n#endif\npreInfoCoat{X}.attenuation=preInfo{X}.attenuation;\n#if defined(HEMILIGHT{X})\npreInfo{X}.roughness=specular_roughness;preInfoCoat{X}.roughness=coat_roughness;\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\npreInfo{X}.roughness=specular_roughness;preInfoCoat{X}.roughness=coat_roughness;\n#else\npreInfo{X}.roughness=adjustRoughnessFromLightProperties(specular_roughness,light{X}.vLightSpecular.a,preInfo{X}.lightDistance);preInfoCoat{X}.roughness=adjustRoughnessFromLightProperties(coat_roughness,light{X}.vLightSpecular.a,preInfoCoat{X}.lightDistance);\n#endif\npreInfo{X}.diffuseRoughness=base_diffuse_roughness;preInfo{X}.surfaceAlbedo=base_color.rgb;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrDirectLightingInitWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrDirectLighting\";\nconst shader = `#ifdef LIGHT{X}\n{var slab_diffuse: vec3f=vec3f(0.f,0.f,0.f);var slab_translucent: vec3f=vec3f(0.f,0.f,0.f);var slab_glossy: vec3f=vec3f(0.f,0.f,0.f);var specularFresnel: f32=0.0f;var specularColoredFresnel: vec3f=vec3f(0.f,0.f,0.f);var slab_metal: vec3f=vec3f(0.f,0.f,0.f);var slab_coat: vec3f=vec3f(0.f,0.f,0.f);var coatFresnel: f32=0.0f;var slab_fuzz: vec3f=vec3f(0.f,0.f,0.f);var fuzzFresnel: f32=0.0f;\n#ifdef HEMILIGHT{X}\nslab_diffuse=computeHemisphericDiffuseLighting(preInfo{X},lightColor{X}.rgb,light{X}.vLightGround);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nslab_diffuse=computeAreaDiffuseLighting(preInfo{X},lightColor{X}.rgb);\n#else\nslab_diffuse=computeDiffuseLighting(preInfo{X},lightColor{X}.rgb);\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nslab_diffuse*=computeProjectionTextureDiffuseLighting(projectionLightTexture{X},textureProjectionMatrix{X},fragmentInputs.vPositionW);\n#endif\n#ifdef FUZZ\nlet fuzzNdotH: f32=max(dot(fuzzNormalW,preInfo{X}.H),0.0f);let fuzzBrdf: vec3f=getFuzzBRDFLookup(fuzzNdotH,sqrt(fuzz_roughness));\n#endif\n#ifdef THIN_FILM\nlet thin_film_desaturation_scale: f32=(thin_film_ior-1.0f)*sqrt(thin_film_thickness*0.001f);\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nslab_glossy=computeOpenPBRAreaSpecularLighting(\npreInfo{X},\nlight{X}.vLightSpecular.rgb,\nbaseDielectricReflectance.coloredF0,\nbaseDielectricReflectance.coloredF90\n);specularFresnel=computeOpenPBRAreaFresnel(preInfo{X},baseDielectricReflectance.F0,baseDielectricReflectance.F90);\n#else\n{\n#ifdef ANISOTROPIC_BASE\nslab_glossy=computeAnisotropicSpecularLighting(preInfo{X},viewDirectionW,normalW,\nbaseGeoInfo.anisotropicTangent,baseGeoInfo.anisotropicBitangent,baseGeoInfo.anisotropy,\n0.0f,lightColor{X}.rgb);\n#else\nslab_glossy=computeSpecularLighting(preInfo{X},normalW,vec3(1.0),vec3(1.0),specular_roughness,lightColor{X}.rgb);\n#endif\nspecularFresnel=fresnelSchlickGGX(preInfo{X}.VdotH,baseDielectricReflectance.F0,baseDielectricReflectance.F90);specularColoredFresnel=specularFresnel*specular_color;\n#ifdef THIN_FILM\nvar thinFilmDielectricFresnel: vec3f=evalIridescence(thin_film_outside_ior,thin_film_ior,preInfo{X}.VdotH,thin_film_thickness,vec3f(baseDielectricReflectance.F0));thinFilmDielectricFresnel=mix(thinFilmDielectricFresnel,vec3f(dot(thinFilmDielectricFresnel,vec3f(0.3333f))),thin_film_desaturation_scale);specularColoredFresnel=mix(specularColoredFresnel,thinFilmDielectricFresnel*specular_color,thin_film_weight*thin_film_ior_scale);\n#endif\n}\n#endif\n#ifdef REFRACTED_LIGHTS\nvar forwardScatteredLight: vec3f=vec3f(0.0f);\n#if AREALIGHT{X}\n#else\n{var preInfoTrans=preInfo{X};\n#ifdef SCATTERING\npreInfoTrans.roughness=sqrt(sqrt(max(transmission_roughness_alpha,0.05f)));\n#else\npreInfoTrans.roughness=transmission_roughness;\n#endif\nif (preInfoTrans.NdotLUnclamped<=0.0) {specularFresnel=0.0;specularColoredFresnel=specularFresnel*specular_color;}\n#ifdef GEOMETRY_THIN_WALLED\nlet refractNormalW: vec3f=viewDirectionW;\n#else\nlet refractNormalW: vec3f=normalW;\n#endif\npreInfoTrans.NdotL=0.5f*max(dot(-refractNormalW,preInfoTrans.L),0.0f)+0.5f;\n#if defined(DISPERSION) && !defined(GEOMETRY_THIN_WALLED)\nvar dispersion_iors_local: vec3f=dispersion_iors;let diff: f32=min(dispersion_iors_local[2]-dispersion_iors_local[0],max(dispersion_iors_local[0]-1.0f,1.0f));dispersion_iors_local[2]+=diff;dispersion_iors_local[0]-=diff;for (var i: i32=0; i<3; i++) {let eta: f32=1.0f/dispersion_iors_local[i];\n#elif defined(GEOMETRY_THIN_WALLED)\nlet eta: f32=1.0f;\n#else\nlet eta: f32=1.0f/specular_ior;\n#endif\npreInfoTrans.H=preInfoTrans.L+min(eta,0.95f)*viewDirectionW;let len2: f32=dot(preInfoTrans.H,preInfoTrans.H);if (len2<1e-6f) {preInfoTrans.H=preInfoTrans.L;} else {preInfoTrans.H=preInfoTrans.H*inverseSqrt(len2);}\n#ifdef ANISOTROPIC_BASE\npreInfoTrans.H=-preInfoTrans.H;\n#endif\npreInfoTrans.VdotH=dot(viewDirectionW,preInfoTrans.H);\n#if defined(DISPERSION) && !defined(GEOMETRY_THIN_WALLED)\nforwardScatteredLight[i]+=\n#else\nforwardScatteredLight+=\n#endif\n#if defined(ANISOTROPIC_BASE)\ncomputeAnisotropicSpecularLighting(preInfoTrans,viewDirectionW,refractNormalW,\nbaseGeoInfo.anisotropicTangent,baseGeoInfo.anisotropicBitangent,baseGeoInfo.anisotropy,\ntransmission_roughness_alpha,lightColor{X}.rgb\n#else\ncomputeSpecularLighting(preInfoTrans,-refractNormalW,vec3f(1.0f),vec3f(1.0f),transmission_roughness_alpha,lightColor{X}.rgb\n#endif\n#if defined(DISPERSION) && !defined(GEOMETRY_THIN_WALLED)\n)[i];}\n#else\n);\n#endif\n#if !defined(GEOMETRY_THIN_WALLED)\nforwardScatteredLight=mix(forwardScatteredLight,0.25f*preInfoTrans.attenuation*lightColor{X}.rgb,clamp(1.0f-pow(baseGeoInfo.NdotV,transmission_roughness_alpha),0.0f,1.0f));\n#endif\n#ifdef REFRACTED_BACKGROUND\n#ifdef GEOMETRY_THIN_WALLED\nforwardScatteredLight=mix(vec3f(0.0f),forwardScatteredLight.rgb,0.2*transmission_roughness_alpha);\n#else\nforwardScatteredLight=max(vec3f(0.0f),mix(vec3f(0.0f),forwardScatteredLight,transmission_roughness_alpha));\n#endif\n#endif\n#ifdef SCATTERING\n#if !defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) || defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER)\npreInfoTrans.roughness=1.0f;let diffused_forward_scattered_light: vec3f=computeSpecularLighting(preInfoTrans,normalW,vec3f(1.0f),vec3f(1.0f),1.0f,lightColor{X}.rgb)*volume_absorption;\n#endif\n#ifdef GEOMETRY_THIN_WALLED\nlet forward_scattered_light: vec3f=forwardScatteredLight*transmission_tint*volumeParams.multi_scatter_color;let back_scattered_light: vec3f=slab_diffuse*volumeParams.multi_scatter_color;slab_translucent=mix(back_scattered_light,forward_scattered_light,0.5f+0.5f*volumeParams.anisotropy);\n#else\nlet back_scattered_normal: vec3f=normalize(normalW+viewDirectionW);preInfoTrans.NdotL=max(dot(back_scattered_normal,preInfoTrans.L),0.0f);preInfoTrans.NdotV=dot(back_scattered_normal,viewDirectionW);preInfoTrans.H=normalize(viewDirectionW+preInfoTrans.L);preInfoTrans.VdotH=clamp(dot(viewDirectionW,preInfoTrans.H),0.0f,1.0f);preInfoTrans.roughness=0.2f;let back_scattered_light: vec3f=computeSpecularLighting(preInfoTrans,viewDirectionW,vec3f(1.0f),vec3f(0.08f),0.0f,lightColor{X}.rgb);let forward_scattered_light: vec3f=(forwardScatteredLight*volume_absorption);let iso_scattered_light: vec3f=slab_diffuse;let back_scattering: vec3f=mix(forward_scattered_light,forward_scattered_light+back_scattered_light*backscatter_color,iso_scatter_density);\n#if defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) && !defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER)\nlet iso_scattering: vec3f=mix(forward_scattered_light,scattered_light_from_irradiance_texture*volumeParams.multi_scatter_color,iso_scatter_density);\n#else\nlet iso_scattering: vec3f=mix(forward_scattered_light,(diffused_forward_scattered_light+iso_scattered_light)*volumeParams.multi_scatter_color,iso_scatter_density);\n#endif\nslab_translucent=mix(back_scattering,iso_scattering,back_to_iso_scattering_blend);slab_translucent=mix(slab_translucent,forward_scattered_light,iso_to_forward_scattering_blend)*transmission_tint;\n#endif\n#else\nslab_translucent=forwardScatteredLight*transmission_tint*volume_absorption;\n#endif\n}\n#endif\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nslab_metal=computeOpenPBRAreaConductorSpecularLighting(\npreInfo{X},\nlight{X}.vLightSpecular.rgb,\nbaseConductorReflectance.coloredF0,\nbaseConductorReflectance.coloredF90\n);\n#else\nslab_metal=computeOpenPBRAreaSpecularLighting(\npreInfo{X},\nlight{X}.vLightSpecular.rgb,\nbaseConductorReflectance.coloredF0,\nbaseConductorReflectance.coloredF90\n);\n#endif\n#else\n{\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nvar coloredFresnel: vec3f=getF82Specular(preInfo{X}.VdotH,baseConductorReflectance.coloredF0,baseConductorReflectance.coloredF90,specular_roughness);\n#else\nvar coloredFresnel: vec3f=fresnelSchlickGGX(preInfo{X}.VdotH,baseConductorReflectance.coloredF0,baseConductorReflectance.coloredF90);\n#endif\n#ifdef THIN_FILM\nlet thinFilmConductorAngle: f32=max(preInfo{X}.VdotH,specular_roughness);var thinFilmConductorFresnel: vec3f=evalIridescence(thin_film_outside_ior,thin_film_ior,thinFilmConductorAngle,thin_film_thickness,baseConductorReflectance.coloredF0);thinFilmConductorFresnel=mix(thinFilmConductorFresnel,vec3f(dot(thinFilmConductorFresnel,vec3f(0.3333f))),thin_film_desaturation_scale);coloredFresnel=mix(coloredFresnel,specular_weight*thinFilmConductorFresnel,thin_film_weight*thin_film_ior_scale);\n#endif\n#ifdef ANISOTROPIC_BASE\nslab_metal=computeAnisotropicSpecularLighting(preInfo{X},viewDirectionW,normalW,baseGeoInfo.anisotropicTangent,baseGeoInfo.anisotropicBitangent,baseGeoInfo.anisotropy,0.0,lightColor{X}.rgb);\n#else\nslab_metal=computeSpecularLighting(preInfo{X},normalW,vec3f(1.0f),coloredFresnel,specular_roughness,lightColor{X}.rgb);\n#endif\n}\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nslab_coat=computeOpenPBRAreaSpecularLighting(\npreInfoCoat{X},\nlight{X}.vLightSpecular.rgb,\nvec3f(coatReflectance.F0),\nvec3f(coatReflectance.F90)\n);\n#else\n{\n#ifdef ANISOTROPIC_COAT\nslab_coat=computeAnisotropicSpecularLighting(preInfoCoat{X},viewDirectionW,coatNormalW,\ncoatGeoInfo.anisotropicTangent,coatGeoInfo.anisotropicBitangent,coatGeoInfo.anisotropy,0.0,\nlightColor{X}.rgb);\n#else\nslab_coat=computeSpecularLighting(preInfoCoat{X},coatNormalW,vec3f(coatReflectance.F0),vec3f(1.0f),coat_roughness,lightColor{X}.rgb);\n#endif\nlet NdotH: f32=saturateEps(dot(coatNormalW,preInfoCoat{X}.H));coatFresnel=fresnelSchlickGGX(NdotH,coatReflectance.F0,coatReflectance.F90);}\n#endif\nvar coatAbsorption=vec3f(1.0f);if (coat_weight>0.0) {let cosTheta_view: f32=max(preInfoCoat{X}.NdotV,0.001f);let cosTheta_light: f32=max(preInfoCoat{X}.NdotL,0.001f);let fresnel_view: f32=coatReflectance.F0+(1.0f-coatReflectance.F0)*pow(1.0f-cosTheta_view,5.0);let fresnel_light: f32=coatReflectance.F0+(1.0f-coatReflectance.F0)*pow(1.0f-cosTheta_light,5.0);let averageReflectance: f32=(fresnel_view+fresnel_light)*0.5;var darkened_transmission: f32=(1.0f-averageReflectance)/(1.0f+averageReflectance);darkened_transmission=mix(1.0f,darkened_transmission,coat_darkening);var sin2: f32=1.0f-coatGeoInfo.NdotV*coatGeoInfo.NdotV;sin2=sin2/(coat_ior*coat_ior)*coat_weight;let cos_t: f32=sqrt(1.0f-sin2);let coatPathLength=1.0f/cos_t;let effectivePathLength=coatPathLength*coat_weight;let colored_transmission: vec3f=pow(coat_color,vec3f(effectivePathLength));coatAbsorption=colored_transmission*mix(1.0f,darkened_transmission,coat_weight);}\n#ifdef FUZZ\nfuzzFresnel=fuzzBrdf.z;let fuzzNormalW=mix(normalW,coatNormalW,coat_weight);let fuzzNdotV: f32=max(dot(fuzzNormalW,viewDirectionW.xyz),0.0f);let fuzzNdotL: f32=max(dot(fuzzNormalW,preInfo{X}.L),0.0);slab_fuzz=lightColor{X}.rgb*preInfo{X}.attenuation*evalFuzz(preInfo{X}.L,fuzzNdotL,fuzzNdotV,fuzzTangent,fuzzBitangent,fuzzBrdf);\n#else\nlet fuzz_color=vec3f(0.0);\n#endif\n#ifdef PREPASS_IRRADIANCE\ntotal_direct_diffuse+=slab_diffuse;\n#endif\nlet material_dielectric_base: vec3f=mix(slab_diffuse*base_color.rgb,slab_translucent,surface_translucency_weight);\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nlet material_dielectric_gloss: vec3f=material_dielectric_base*(1.0f-specularFresnel)+slab_glossy;\n#else\nlet material_dielectric_gloss: vec3f=material_dielectric_base*(1.0f-specularFresnel)+slab_glossy*specularColoredFresnel;\n#endif\nlet material_base_substrate: vec3f=mix(material_dielectric_gloss,slab_metal,base_metalness);let material_coated_base: vec3f=layer(material_base_substrate,slab_coat,coatFresnel,coatAbsorption,vec3f(1.0f));material_surface_direct+=layer(material_coated_base,slab_fuzz,fuzzFresnel*fuzz_weight,vec3f(1.0f),fuzz_color);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrDirectLightingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./meshBlendTagFragmentOutput\";\nconst name = \"openpbrBlockPrePass\";\nconst shader = `#if SCENE_MRT_COUNT>0\n#ifdef ALPHATEST\nvar writeGeometryInfo: f32=1.0;\n#else\nvar writeGeometryInfo: f32=select(0.0,1.0,finalColor.a>ALPHATESTVALUE);\n#endif\nvar fragData: array<vec4<f32>,SCENE_MRT_COUNT>;\n#ifdef PREPASS_MESH_BLEND_TAG\nvar meshBlendTagOutput: vec4<u32>=vec4u(0u);if (writeGeometryInfo>0.0) {meshBlendTagOutput=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);}\n#endif\n#ifdef PREPASS_POSITION\nfragData[PREPASS_POSITION_INDEX]= vec4f(fragmentInputs.vPositionW,writeGeometryInfo);\n#endif\n#ifdef PREPASS_OBJECT_ID\nfragData[PREPASS_OBJECT_ID_INDEX]=encodeObjectId(uniforms.objectId)*writeGeometryInfo;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nfragData[PREPASS_LOCAL_POSITION_INDEX]=vec4f(fragmentInputs.vPosition,writeGeometryInfo);\n#endif\n#ifdef PREPASS_VELOCITY\nvar a: vec2f=(fragmentInputs.vCurrentPosition.xy/fragmentInputs.vCurrentPosition.w)*0.5+0.5;var b: vec2f=(fragmentInputs.vPreviousPosition.xy/fragmentInputs.vPreviousPosition.w)*0.5+0.5;var velocity: vec2f=abs(a-b);velocity= vec2f(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;fragData[PREPASS_VELOCITY_INDEX]= vec4f(velocity,0.0,writeGeometryInfo);\n#elif defined(PREPASS_VELOCITY_LINEAR)\nvar velocity : vec2f=vec2f(0.5)*((fragmentInputs.vPreviousPosition.xy/fragmentInputs.vPreviousPosition.w) -\n(fragmentInputs.vCurrentPosition.xy/fragmentInputs.vCurrentPosition.w));fragData[PREPASS_VELOCITY_LINEAR_INDEX]=vec4f(velocity,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO\nfragData[PREPASS_ALBEDO_INDEX]=vec4f(surfaceAlbedo,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nvar sqAlbedo : vec3f=sqrt(surfaceAlbedo); \n#endif\n#ifdef PREPASS_IRRADIANCE\nvar irradiance : vec3f=total_direct_diffuse;\n#ifndef UNLIT\n#ifdef REFLECTION\nirradiance+=slab_diffuse_ibl;\n#endif\n#endif\n#ifdef SCATTERING\nlet scatter_mask: f32=min(subsurface_weight+transmission_weight,1.0);\n#else\nlet scatter_mask: f32=0.0;\n#endif\nfragData[PREPASS_IRRADIANCE_INDEX]=vec4f(irradiance,writeGeometryInfo*scatter_mask);\n#elif defined(PREPASS_COLOR)\nfragData[PREPASS_COLOR_INDEX]=vec4f(finalColor.rgb,finalColor.a);\n#endif\n#ifdef PREPASS_DEPTH\nfragData[PREPASS_DEPTH_INDEX]=vec4f(fragmentInputs.vViewPos.z,0.0,0.0,writeGeometryInfo); \n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nfragData[PREPASS_SCREENSPACE_DEPTH_INDEX]=vec4f(fragmentInputs.position.z,0.0,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfragData[PREPASS_NORMALIZED_VIEW_DEPTH_INDEX]=vec4f(fragmentInputs.vNormViewDepth,0.0,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_NORMAL\n#ifdef PREPASS_NORMAL_WORLDSPACE\nfragData[PREPASS_NORMAL_INDEX]=vec4f(normalW,writeGeometryInfo);\n#else\nfragData[PREPASS_NORMAL_INDEX]=vec4f(normalize((scene.view*vec4f(normalW,0.0)).rgb),writeGeometryInfo);\n#endif\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nfragData[PREPASS_WORLD_NORMAL_INDEX]=vec4f(normalW*0.5+0.5,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nfragData[PREPASS_ALBEDO_SQRT_INDEX]=vec4f(sqAlbedo,writeGeometryInfo);\n#endif\n#ifdef PREPASS_REFLECTIVITY\n#ifndef UNLIT\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(specularEnvironmentR0,microSurface)*writeGeometryInfo;\n#else\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(0.0,0.0,0.0,1.0)*writeGeometryInfo;\n#endif\n#endif\n#include<meshBlendTagFragmentOutput>[0..8]\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const openpbrBlockPrePassWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { oitDeclarationWGSL } from \"./ShadersInclude/oitDeclaration\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { openpbrUboDeclarationWGSL } from \"./ShadersInclude/openpbrUboDeclaration\";\nimport { mainUVVaryingDeclarationWGSL } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { pbrFragmentExtraDeclarationWGSL } from \"./ShadersInclude/pbrFragmentExtraDeclaration\";\nimport { lightUboDeclarationWGSL } from \"./ShadersInclude/lightUboDeclaration\";\nimport { samplerFragmentDeclarationWGSL } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { pbrFragmentReflectionDeclarationWGSL } from \"./ShadersInclude/pbrFragmentReflectionDeclaration\";\nimport { openpbrFragmentSamplersDeclarationWGSL } from \"./ShadersInclude/openpbrFragmentSamplersDeclaration\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { textureRepetitionFunctionsWGSL } from \"./ShadersInclude/textureRepetitionFunctions\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { subSurfaceScatteringFunctionsWGSL } from \"./ShadersInclude/subSurfaceScatteringFunctions\";\nimport { importanceSamplingWGSL } from \"./ShadersInclude/importanceSampling\";\nimport { pbrHelperFunctionsWGSL } from \"./ShadersInclude/pbrHelperFunctions\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { shadowsFragmentFunctionsWGSL } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { harmonicsFunctionsWGSL } from \"./ShadersInclude/harmonicsFunctions\";\nimport { ltcHelperFunctionsWGSL } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { pbrDirectLightingSetupFunctionsWGSL } from \"./ShadersInclude/pbrDirectLightingSetupFunctions\";\nimport { pbrDirectLightingFalloffFunctionsWGSL } from \"./ShadersInclude/pbrDirectLightingFalloffFunctions\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctionsWGSL } from \"./ShadersInclude/hdrFilteringFunctions\";\nimport { clusteredLightingFunctionsWGSL } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { pbrBlockReflectance0WGSL } from \"./ShadersInclude/pbrBlockReflectance0\";\nimport { pbrClusteredLightingFunctionsWGSL } from \"./ShadersInclude/pbrClusteredLightingFunctions\";\nimport { pbrDirectLightingFunctionsWGSL } from \"./ShadersInclude/pbrDirectLightingFunctions\";\nimport { pbrIBLFunctionsWGSL } from \"./ShadersInclude/pbrIBLFunctions\";\nimport { openpbrNormalMapFragmentMainFunctionsWGSL } from \"./ShadersInclude/openpbrNormalMapFragmentMainFunctions\";\nimport { openpbrNormalMapFragmentFunctionsWGSL } from \"./ShadersInclude/openpbrNormalMapFragmentFunctions\";\nimport { reflectionFunctionWGSL } from \"./ShadersInclude/reflectionFunction\";\nimport { openpbrDielectricReflectanceWGSL } from \"./ShadersInclude/openpbrDielectricReflectance\";\nimport { openpbrConductorReflectanceWGSL } from \"./ShadersInclude/openpbrConductorReflectance\";\nimport { openpbrAmbientOcclusionFunctionsWGSL } from \"./ShadersInclude/openpbrAmbientOcclusionFunctions\";\nimport { openpbrGeometryInfoWGSL } from \"./ShadersInclude/openpbrGeometryInfo\";\nimport { openpbrIblFunctionsWGSL } from \"./ShadersInclude/openpbrIblFunctions\";\nimport { openpbrVolumeFunctionsWGSL } from \"./ShadersInclude/openpbrVolumeFunctions\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { pbrBlockNormalGeometricWGSL } from \"./ShadersInclude/pbrBlockNormalGeometric\";\nimport { openpbrNormalMapFragmentWGSL } from \"./ShadersInclude/openpbrNormalMapFragment\";\nimport { openpbrBlockNormalFinalWGSL } from \"./ShadersInclude/openpbrBlockNormalFinal\";\nimport { openpbrBaseLayerDataWGSL } from \"./ShadersInclude/openpbrBaseLayerData\";\nimport { openpbrTransmissionLayerDataWGSL } from \"./ShadersInclude/openpbrTransmissionLayerData\";\nimport { openpbrSubsurfaceLayerDataWGSL } from \"./ShadersInclude/openpbrSubsurfaceLayerData\";\nimport { openpbrCoatLayerDataWGSL } from \"./ShadersInclude/openpbrCoatLayerData\";\nimport { openpbrThinFilmLayerDataWGSL } from \"./ShadersInclude/openpbrThinFilmLayerData\";\nimport { openpbrFuzzLayerDataWGSL } from \"./ShadersInclude/openpbrFuzzLayerData\";\nimport { openpbrAmbientOcclusionDataWGSL } from \"./ShadersInclude/openpbrAmbientOcclusionData\";\nimport { depthPrePassWGSL } from \"./ShadersInclude/depthPrePass\";\nimport { openpbrBackgroundTransmissionWGSL } from \"./ShadersInclude/openpbrBackgroundTransmission\";\nimport { openpbrEnvironmentLightingWGSL } from \"./ShadersInclude/openpbrEnvironmentLighting\";\nimport { openpbrDirectLightingInitWGSL } from \"./ShadersInclude/openpbrDirectLightingInit\";\nimport { openpbrDirectLightingWGSL } from \"./ShadersInclude/openpbrDirectLighting\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { pbrBlockImageProcessingWGSL } from \"./ShadersInclude/pbrBlockImageProcessing\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { openpbrBlockPrePassWGSL } from \"./ShadersInclude/openpbrBlockPrePass\";\nimport { oitFragmentWGSL } from \"./ShadersInclude/oitFragment\";\nimport { pbrDebugWGSL } from \"./ShadersInclude/pbrDebug\";\n\nconst name = \"openpbrPixelShader\";\nconst shader = `#define OPENPBR_FRAGMENT_SHADER\n#define CUSTOM_FRAGMENT_BEGIN\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<oitDeclaration>\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE\n#endif\n#include<openpbrUboDeclaration>\n#include<pbrFragmentExtraDeclaration>\n#include<lightUboDeclaration>[0..maxSimultaneousLights]\n#include<openpbrFragmentSamplersDeclaration>\n#include<imageProcessingDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#include<textureRepetitionFunctions>\n#include<helperFunctions>\n#include<subSurfaceScatteringFunctions>\n#include<importanceSampling>\n#include<pbrHelperFunctions>\n#include<imageProcessingFunctions>\n#include<shadowsFragmentFunctions>\n#include<harmonicsFunctions>\n#include<pbrDirectLightingSetupFunctions>\n#include<pbrDirectLightingFalloffFunctions>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\n#include<pbrDirectLightingFunctions>\n#include<pbrIBLFunctions>\n#include<openpbrNormalMapFragmentMainFunctions>\n#include<openpbrNormalMapFragmentFunctions>\n#ifdef REFLECTION\n#include<reflectionFunction>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#include<openpbrDielectricReflectance>\n#include<openpbrConductorReflectance>\n#include<openpbrAmbientOcclusionFunctions>\n#include<openpbrGeometryInfo>\n#include<openpbrIblFunctions>\n#include<openpbrVolumeFunctions>\nfn layer(slab_bottom: vec3f,slab_top: vec3f,lerp_factor: f32,bottom_multiplier: vec3f,top_multiplier: vec3f)->vec3f {return mix(slab_bottom*bottom_multiplier,slab_top*top_multiplier,lerp_factor);}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#ifdef PREPASS_IRRADIANCE\nvar total_direct_diffuse: vec3f=vec3f(0.0f);\n#endif\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#include<pbrBlockNormalGeometric>\nvar coatNormalW: vec3f=normalW;\n#include<openpbrNormalMapFragment>\n#include<openpbrBlockNormalFinal>\n#include<openpbrBaseLayerData>\n#include<openpbrTransmissionLayerData>\n#include<openpbrSubsurfaceLayerData>\n#include<openpbrCoatLayerData>\n#include<openpbrThinFilmLayerData>\n#include<openpbrFuzzLayerData>\n#include<openpbrAmbientOcclusionData>\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\n#define DEPTHPREPASS_SKIP_EARLY_RETURN\n#include<depthPrePass>\n#ifndef DEPTHPREPASS\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\n#ifdef ANISOTROPIC_COAT\nlet coatGeoInfo: geometryInfoAnisoOutParams=geometryInfoAniso(\ncoatNormalW,viewDirectionW.xyz,coat_roughness,geometricNormalW\n,vec3f(geometry_coat_tangent.x,geometry_coat_tangent.y,coat_roughness_anisotropy),TBN\n);\n#else\nlet coatGeoInfo: geometryInfoOutParams=geometryInfo(\ncoatNormalW,viewDirectionW.xyz,coat_roughness,geometricNormalW\n);\n#endif\nspecular_roughness=mix(specular_roughness,pow(min(1.0f,pow(specular_roughness,4.0f)+2.0f*pow(coat_roughness,4.0f)),0.25f),coat_weight);\n#ifdef ANISOTROPIC_BASE\nlet baseGeoInfo: geometryInfoAnisoOutParams=geometryInfoAniso(\nnormalW,viewDirectionW.xyz,specular_roughness,geometricNormalW\n,vec3f(geometry_tangent.x,geometry_tangent.y,specular_roughness_anisotropy),TBN\n);\n#else\nlet baseGeoInfo: geometryInfoOutParams=geometryInfo(\nnormalW,viewDirectionW.xyz,specular_roughness,geometricNormalW\n);\n#endif\n#ifdef FUZZ\nlet fuzzNormalW=normalize(mix(normalW,coatNormalW,coat_weight));var fuzzTangent=normalize(TBN[0]);fuzzTangent=normalize(fuzzTangent-dot(fuzzTangent,fuzzNormalW)*fuzzNormalW);let fuzzBitangent=cross(fuzzNormalW,fuzzTangent);let fuzzGeoInfo: geometryInfoOutParams=geometryInfo(\nfuzzNormalW,viewDirectionW.xyz,fuzz_roughness,geometricNormalW\n);\n#endif\nlet coatReflectance: ReflectanceParams=dielectricReflectance(\ncoat_ior \n,1.0f \n,vec3f(1.0f)\n,coat_weight\n);\n#ifdef THIN_FILM\nlet thin_film_outside_ior: f32=mix(1.0f,coat_ior,coat_weight);\n#endif\nlet baseDielectricReflectance: ReflectanceParams=dielectricReflectance(\nspecular_ior \n,mix(1.0f,coat_ior,coat_weight) \n,specular_color\n,specular_weight\n);let baseConductorReflectance: ReflectanceParams=conductorReflectance(base_color,specular_color,specular_weight);var volume_absorption: vec3f=vec3f(1.0f);var transmission_tint: vec3f=vec3f(1.0f);var surface_translucency_weight: f32=0.0f;\n#if defined(REFRACTED_BACKGROUND) || defined(REFRACTED_ENVIRONMENT) || defined(REFRACTED_LIGHTS)\n#if defined(GEOMETRY_THIN_WALLED)\nlet refractedViewVector: vec3f=-viewDirectionW;\n#else\n#ifdef DISPERSION\nvar refractedViewVectors: array<vec3f,3>;let iorDispersionSpread: f32=transmission_dispersion_scale/transmission_dispersion_abbe_number*(specular_ior-1.0f);let dispersion_iors: vec3f=vec3f(specular_ior-iorDispersionSpread,specular_ior,specular_ior+iorDispersionSpread);for (var i: i32=0; i<3; i++) {refractedViewVectors[i]=double_refract(-viewDirectionW,normalW,dispersion_iors[i]); }\n#else\nlet refractedViewVector: vec3f=double_refract(-viewDirectionW,normalW,specular_ior);\n#endif\n#endif\n#ifdef GEOMETRY_THIN_WALLED\nvar transmission_roughness: f32=specular_roughness;\n#else\nvar transmission_roughness: f32=specular_roughness*clamp(4.0f*(specular_ior-1.0f),0.001f,1.0f);\n#endif\n#if (defined(TRANSMISSION_SLAB) || defined(SUBSURFACE_SLAB))\nvar volumeParams: OpenPBRHomogeneousVolume;{\n#if defined(TRANSMISSION_SLAB)\nlet transmissionVolumeParams: OpenPBRHomogeneousVolume=computeOpenPBRTransmissionVolume(\ntransmission_color.rgb,\ntransmission_depth,\ntransmission_scatter.rgb,\ntransmission_scatter_anisotropy\n);\n#endif\n#if defined(SUBSURFACE_SLAB)\nlet subsurfaceVolumeParams: OpenPBRHomogeneousVolume=computeOpenPBRSubsurfaceVolume(\nsubsurface_color.rgb,\nsubsurface_radius,\nsubsurface_radius_scale.rgb,\nsubsurface_scatter_anisotropy\n);\n#endif\n#if !defined(TRANSMISSION_SLAB)\nvolumeParams=subsurfaceVolumeParams;surface_translucency_weight=subsurface_weight;\n#elif !defined(SUBSURFACE_SLAB)\nvolumeParams=transmissionVolumeParams;\n#ifdef TRANSMISSION_SLAB_VOLUME\nvolumeParams.multi_scatter_color=singleScatterToMultiScatterAlbedo(volumeParams.ss_albedo);\n#endif\nsurface_translucency_weight=transmission_weight;\n#else\nlet subsurface_fraction_of_dielectric: f32=(1.0f-transmission_weight)*subsurface_weight;let subsurface_and_transmission_fraction_of_dielectric: f32=subsurface_fraction_of_dielectric+transmission_weight;let reciprocal_of_subsurface_and_transmission_fraction_of_dielectric: f32 =\n1.0f/maxEps(subsurface_and_transmission_fraction_of_dielectric);let trans_weight: f32=transmission_weight*reciprocal_of_subsurface_and_transmission_fraction_of_dielectric;let subsurf_weight: f32=subsurface_fraction_of_dielectric*reciprocal_of_subsurface_and_transmission_fraction_of_dielectric;volumeParams.scatter_coeff=transmissionVolumeParams.scatter_coeff*trans_weight+subsurfaceVolumeParams.scatter_coeff*subsurf_weight;volumeParams.absorption_coeff=transmissionVolumeParams.absorption_coeff*trans_weight+subsurfaceVolumeParams.absorption_coeff*subsurf_weight;volumeParams.anisotropy=(transmissionVolumeParams.anisotropy*trans_weight+subsurfaceVolumeParams.anisotropy*subsurf_weight)/maxEps(trans_weight+subsurf_weight);volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=volumeParams.scatter_coeff/maxEpsVec3(volumeParams.extinction_coeff);volumeParams.multi_scatter_color=singleScatterToMultiScatterAlbedo(volumeParams.ss_albedo);surface_translucency_weight=subsurface_and_transmission_fraction_of_dielectric;\n#endif\n}\nvolume_absorption=exp(-volumeParams.absorption_coeff*geometry_thickness);var backscatter_color: vec3f=vec3f(1.0f);{let reduced_scatter: vec3f=volumeParams.scatter_coeff*vec3f(1.0f-volumeParams.anisotropy);let reduced_albedo: vec3f=reduced_scatter/(volumeParams.absorption_coeff+reduced_scatter);let sqrt_term: vec3f=max(sqrt(vec3f(1.0f)-reduced_albedo),vec3f(0.0001f));backscatter_color=(vec3f(1.0f)-sqrt_term)/(vec3f(1.0f)+sqrt_term);}\n#elif defined(TRANSMISSION_SLAB)\nsurface_translucency_weight=transmission_weight;\n#endif\n#ifdef SCATTERING\n#ifdef GEOMETRY_THIN_WALLED\nvar iso_scatter_density: vec3f=vec3f(1.0f);\n#else\n#ifdef USE_IRRADIANCE_TEXTURE_FOR_SCATTERING\nlet mfp: vec3f=vec3f(100.0f)/volumeParams.extinction_coeff;var scattered_light_from_irradiance_texture: vec3f=sss_convolve(sceneIrradianceSampler,sceneDepthSampler,uniforms.renderTargetSize,mfp,scene.projection,scene.inverseProjection,SSS_SAMPLE_COUNT,noise.xy);var numLights=f32(LIGHTCOUNT);\n#ifdef REFLECTION\nnumLights+=1.0f;\n#endif\nscattered_light_from_irradiance_texture/=vec3f(numLights);\n#else\nlet scattered_light_from_irradiance_texture: vec3f=vec3f(0.0f);\n#endif\nlet back_to_iso_scattering_blend: f32=min(1.0f+volumeParams.anisotropy,1.0f);let iso_to_forward_scattering_blend: f32=max(volumeParams.anisotropy,0.0f);let iso_scatter_transmittance: vec3f=pow(exp(-volumeParams.scatter_coeff*geometry_thickness),vec3f(0.2f));var iso_scatter_density: vec3f=clamp(vec3f(1.0f)-iso_scatter_transmittance,vec3f(0.0f),vec3f(1.0f));transmission_roughness=min(transmission_roughness+pow((1.0f-abs(volumeParams.anisotropy))*max3(iso_scatter_density*iso_scatter_density),3.0f),1.0f);\n#endif\nvolumeParams.multi_scatter_color=mix(volumeParams.ss_albedo,volumeParams.multi_scatter_color,max3(iso_scatter_density));\n#endif\n#if defined(TRANSMISSION_SLAB) && (!defined(TRANSMISSION_SLAB_VOLUME) || defined(GEOMETRY_THIN_WALLED))\ntransmission_tint*=transmission_color.rgb;\n#ifdef GEOMETRY_THIN_WALLED\nvar sin2: f32=1.0f-baseGeoInfo.NdotV*baseGeoInfo.NdotV;sin2=sin2/(specular_ior*specular_ior);let cos_t: f32=sqrt(1.0f-sin2);let pathLength: f32=1.0f/cos_t;transmission_tint=pow(transmission_tint,vec3f(pathLength));\n#else\ntransmission_tint*=transmission_color.rgb;\n#endif\n#endif\n#if defined(SUBSURFACE_SLAB) && defined(GEOMETRY_THIN_WALLED)\nlet unweighted_translucency: f32=max(mix(subsurface_weight,1.0f,transmission_weight),0.0001f);transmission_tint=mix(vec3f(1.0f),transmission_tint,transmission_weight/unweighted_translucency);transmission_roughness=mix(1.0f,transmission_roughness,transmission_weight/unweighted_translucency);\n#endif\nlet transmission_roughness_alpha: f32=transmission_roughness*transmission_roughness;\n#endif\n#include<openpbrBackgroundTransmission>\nvar material_surface_ibl: vec3f=vec3f(0.f,0.f,0.f);\n#include<openpbrEnvironmentLighting>\nvar material_surface_direct: vec3f=vec3f(0.f,0.f,0.f);\n#if defined(LIGHT0)\nvar aggShadow: f32=0.f;\n#include<openpbrDirectLightingInit>[0..maxSimultaneousLights]\n#include<openpbrDirectLighting>[0..maxSimultaneousLights]\n#endif\nvar material_surface_emission: vec3f=uniforms.vEmissionColor;\n#ifdef EMISSION_COLOR\nlet emissionColorTex: vec3f=textureSample(emissionColorSampler,emissionColorSamplerSampler,fragmentInputs.vEmissionColorUV+uvOffset).rgb;\n#ifdef EMISSION_COLOR_GAMMA\nmaterial_surface_emission*=toLinearSpaceVec3(emissionColorTex.rgb);\n#else\nmaterial_surface_emission*=emissionColorTex.rgb;\n#endif\nmaterial_surface_emission*= uniforms.vEmissionColorInfos.y;\n#endif\nmaterial_surface_emission*=uniforms.vLightingIntensity.y;\n#define CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION\nvar finalColor: vec4f=vec4f(material_surface_ibl+material_surface_direct+material_surface_emission,alpha);\n#define CUSTOM_FRAGMENT_BEFORE_FOG\nfinalColor=max(finalColor,vec4f(0.0));\n#include<logDepthFragment>\n#include<fogFragment>(color,finalColor)\n#include<pbrBlockImageProcessing>\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\n#include<openpbrBlockPrePass>\n#endif\n#if !defined(PREPASS) && !defined(ORDER_INDEPENDENT_TRANSPARENCY)\nfragmentOutputs.color=finalColor;\n#endif\n#include<oitFragment>\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {fragmentOutputs.frontColor=vec4f(fragmentOutputs.frontColor.rgb+finalColor.rgb*finalColor.a*alphaMultiplier,1.0-alphaMultiplier*(1.0-finalColor.a));} else {fragmentOutputs.backColor+=finalColor;}\n#endif\n#include<pbrDebug>\n#define CUSTOM_FRAGMENT_MAIN_END\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [objectIdFunctionsWGSL, prePassDeclarationWGSL, oitDeclarationWGSL, sceneUboDeclarationWGSL, meshUboDeclarationWGSL, openpbrUboDeclarationWGSL, mainUVVaryingDeclarationWGSL, pbrFragmentExtraDeclarationWGSL, lightUboDeclarationWGSL, samplerFragmentDeclarationWGSL, pbrFragmentReflectionDeclarationWGSL, openpbrFragmentSamplersDeclarationWGSL, imageProcessingDeclarationWGSL, clipPlaneFragmentDeclarationWGSL, logDepthDeclarationWGSL, fogFragmentDeclarationWGSL, textureRepetitionFunctionsWGSL, helperFunctionsWGSL, subSurfaceScatteringFunctionsWGSL, importanceSamplingWGSL, pbrHelperFunctionsWGSL, imageProcessingFunctionsWGSL, shadowsFragmentFunctionsWGSL, harmonicsFunctionsWGSL, ltcHelperFunctionsWGSL, pbrDirectLightingSetupFunctionsWGSL, pbrDirectLightingFalloffFunctionsWGSL, pbrBRDFFunctionsWGSL, hdrFilteringFunctionsWGSL, clusteredLightingFunctionsWGSL, pbrBlockReflectance0WGSL, pbrClusteredLightingFunctionsWGSL, pbrDirectLightingFunctionsWGSL, pbrIBLFunctionsWGSL, openpbrNormalMapFragmentMainFunctionsWGSL, openpbrNormalMapFragmentFunctionsWGSL, reflectionFunctionWGSL, openpbrDielectricReflectanceWGSL, openpbrConductorReflectanceWGSL, openpbrAmbientOcclusionFunctionsWGSL, openpbrGeometryInfoWGSL, openpbrIblFunctionsWGSL, openpbrVolumeFunctionsWGSL, clipPlaneFragmentWGSL, pbrBlockNormalGeometricWGSL, openpbrNormalMapFragmentWGSL, openpbrBlockNormalFinalWGSL, openpbrBaseLayerDataWGSL, openpbrTransmissionLayerDataWGSL, openpbrSubsurfaceLayerDataWGSL, openpbrCoatLayerDataWGSL, openpbrThinFilmLayerDataWGSL, openpbrFuzzLayerDataWGSL, openpbrAmbientOcclusionDataWGSL, depthPrePassWGSL, openpbrBackgroundTransmissionWGSL, openpbrEnvironmentLightingWGSL, openpbrDirectLightingInitWGSL, openpbrDirectLightingWGSL, logDepthFragmentWGSL, fogFragmentWGSL, pbrBlockImageProcessingWGSL, meshBlendTagFragmentOutputWGSL, openpbrBlockPrePassWGSL, oitFragmentWGSL, pbrDebugWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const openpbrPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneVertexDeclaration\";\nimport \"./decalVertexDeclaration\";\nconst name = \"openpbrVertexDeclaration\";\nconst shader = `#include<sceneVertexDeclaration>\n#ifdef BASE_COLOR\nuniform vec2 vBaseColorInfos;uniform mat4 baseColorMatrix;\n#endif\n#ifdef BASE_WEIGHT\nuniform mat4 baseWeightMatrix;uniform vec2 vBaseWeightInfos;\n#endif\nuniform float vBaseDiffuseRoughness;\n#ifdef BASE_DIFFUSE_ROUGHNESS\nuniform mat4 baseDiffuseRoughnessMatrix;uniform vec2 vBaseDiffuseRoughnessInfos;\n#endif\n#ifdef AMBIENT_OCCLUSION\nuniform vec2 vAmbientOcclusionInfos;uniform mat4 ambientOcclusionMatrix;\n#endif\n#ifdef EMISSION_COLOR\nuniform vec2 vEmissionColorInfos;uniform mat4 emissionColorMatrix;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;uniform mat4 lightmapMatrix;\n#endif\n#ifdef BASE_METALNESS\nuniform vec2 vBaseMetalnessInfos;uniform mat4 baseMetalnessMatrix;\n#endif\n#ifdef SPECULAR_WEIGHT\nuniform vec2 vSpecularWeightInfos;uniform mat4 specularWeightMatrix;\n#endif\n#ifdef SPECULAR_COLOR\nuniform vec2 vSpecularColorInfos;uniform mat4 specularColorMatrix;\n#endif\n#ifdef SPECULAR_ROUGHNESS\nuniform vec2 vSpecularRoughnessInfos;uniform mat4 specularRoughnessMatrix;\n#endif\n#ifdef SPECULAR_ROUGHNESS_ANISOTROPY\nuniform vec2 vSpecularRoughnessAnisotropyInfos;uniform mat4 specularRoughnessAnisotropyMatrix;\n#endif\n#ifdef TRANSMISSION_WEIGHT\nuniform vec2 vTransmissionWeightInfos;uniform mat4 transmissionWeightMatrix;\n#endif\n#ifdef TRANSMISSION_COLOR\nuniform vec2 vTransmissionColorInfos;uniform mat4 transmissionColorMatrix;\n#endif\n#ifdef TRANSMISSION_DEPTH\nuniform vec2 vTransmissionDepthInfos;uniform mat4 transmissionDepthMatrix;\n#endif\n#ifdef TRANSMISSION_DISPERSION_SCALE\nuniform vec2 vTransmissionDispersionScaleInfos;uniform mat4 transmissionDispersionScaleMatrix;\n#endif\n#ifdef SUBSURFACE_WEIGHT\nuniform vec2 vSubsurfaceWeightInfos;uniform mat4 subsurfaceWeightMatrix;\n#endif\n#ifdef SUBSURFACE_COLOR\nuniform vec2 vSubsurfaceColorInfos;uniform mat4 subsurfaceColorMatrix;\n#endif\n#ifdef SUBSURFACE_RADIUS_SCALE\nuniform vec2 vSubsurfaceRadiusScaleInfos;uniform mat4 subsurfaceRadiusScaleMatrix;\n#endif\n#ifdef COAT_WEIGHT\nuniform vec2 vCoatWeightInfos;uniform mat4 coatWeightMatrix;\n#endif\n#ifdef COAT_COLOR\nuniform vec2 vCoatColorInfos;uniform mat4 coatColorMatrix;\n#endif\n#ifdef COAT_ROUGHNESS\nuniform vec2 vCoatRoughnessInfos;uniform mat4 coatRoughnessMatrix;\n#endif\n#ifdef COAT_ROUGHNESS_ANISOTROPY\nuniform vec2 vCoatRoughnessAnisotropyInfos;uniform mat4 coatRoughnessAnisotropyMatrix;\n#endif\n#ifdef COAT_IOR\nuniform vec2 vCoatIorInfos;uniform mat4 coatIorMatrix;\n#endif\n#ifdef COAT_DARKENING\nuniform vec2 vCoatDarkeningInfos;uniform mat4 coatDarkeningMatrix;\n#endif\n#ifdef FUZZ_WEIGHT\nuniform vec2 vFuzzWeightInfos;uniform mat4 fuzzWeightMatrix;\n#endif\n#ifdef FUZZ_COLOR\nuniform vec2 vFuzzColorInfos;uniform mat4 fuzzColorMatrix;\n#endif\n#ifdef FUZZ_ROUGHNESS\nuniform vec2 vFuzzRoughnessInfos;uniform mat4 fuzzRoughnessMatrix;\n#endif\n#ifdef GEOMETRY_NORMAL\nuniform vec2 vGeometryNormalInfos;uniform mat4 geometryNormalMatrix;\n#endif\n#ifdef GEOMETRY_TANGENT\nuniform vec2 vGeometryTangentInfos;uniform mat4 geometryTangentMatrix;\n#endif\n#ifdef GEOMETRY_COAT_NORMAL\nuniform vec2 vGeometryCoatNormalInfos;uniform mat4 geometryCoatNormalMatrix;\n#endif\n#ifdef THIN_FILM_WEIGHT\nuniform vec2 vThinFilmWeightInfos;uniform mat4 thinFilmWeightMatrix;\n#endif\n#ifdef THIN_FILM_THICKNESS\nuniform vec2 vThinFilmThicknessInfos;uniform mat4 thinFilmThicknessMatrix;\n#endif\n#ifdef GEOMETRY_OPACITY\nuniform mat4 geometryOpacityMatrix;uniform vec2 vGeometryOpacityInfos;\n#endif\n#ifdef GEOMETRY_THICKNESS\nuniform mat4 geometryThicknessMatrix;uniform vec2 vGeometryThicknessInfos;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\nuniform vec4 cameraInfo;uniform vec4 vTextureRepetitionHexTilingParams;\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;uniform mat4 reflectionMatrix;\n#endif\n#ifdef NORMAL\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;uniform vec3 vSphericalL1_1;uniform vec3 vSphericalL10;uniform vec3 vSphericalL11;uniform vec3 vSphericalL2_2;uniform vec3 vSphericalL2_1;uniform vec3 vSphericalL20;uniform vec3 vSphericalL21;uniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;uniform vec3 vSphericalY;uniform vec3 vSphericalZ;uniform vec3 vSphericalXX_ZZ;uniform vec3 vSphericalYY_ZZ;uniform vec3 vSphericalZZ;uniform vec3 vSphericalXY;uniform vec3 vSphericalYZ;uniform vec3 vSphericalZX;\n#endif\n#endif\n#endif\n#endif\n#ifdef DETAIL\nuniform vec4 vDetailInfos;uniform mat4 detailMatrix;\n#endif\n#include<decalVertexDeclaration>\n#define ADDITIONAL_VERTEX_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"openpbrUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Material {vec2 vTangentSpaceParams;vec4 vLightingIntensity;float pointSize;vec2 vDebugMode;vec2 renderTargetSize;vec4 cameraInfo;vec4 vTextureRepetitionHexTilingParams;mat4 backgroundRefractionMatrix;vec3 vBackgroundRefractionInfos;vec2 vReflectionInfos;mat4 reflectionMatrix;vec3 vReflectionMicrosurfaceInfos;vec3 vReflectionPosition;vec3 vReflectionSize;vec2 vReflectionFilteringInfo;vec3 vReflectionDominantDirection;vec3 vReflectionColor;vec3 vSphericalL00;vec3 vSphericalL1_1;vec3 vSphericalL10;vec3 vSphericalL11;vec3 vSphericalL2_2;vec3 vSphericalL2_1;vec3 vSphericalL20;vec3 vSphericalL21;vec3 vSphericalL22;vec3 vSphericalX;vec3 vSphericalY;vec3 vSphericalZ;vec3 vSphericalXX_ZZ;vec3 vSphericalYY_ZZ;vec3 vSphericalZZ;vec3 vSphericalXY;vec3 vSphericalYZ;vec3 vSphericalZX;float vBaseWeight;vec4 vBaseColor;float vBaseDiffuseRoughness;vec4 vReflectanceInfo;vec4 vSpecularColor;vec3 vSpecularAnisotropy;float vTransmissionWeight;vec3 vTransmissionColor;float vTransmissionDepth;vec3 vTransmissionScatter;float vTransmissionScatterAnisotropy;float vTransmissionDispersionScale;float vTransmissionDispersionAbbeNumber;float vSubsurfaceWeight;vec3 vSubsurfaceColor;float vSubsurfaceRadius;vec3 vSubsurfaceRadiusScale;float vSubsurfaceScatterAnisotropy;float vCoatWeight;vec3 vCoatColor;float vCoatRoughness;float vCoatRoughnessAnisotropy;float vCoatIor;float vCoatDarkening;float vFuzzWeight;vec3 vFuzzColor;float vFuzzRoughness;float vGeometryThinWalled;vec2 vGeometryCoatTangent;float vGeometryThickness;vec3 vEmissionColor;float vThinFilmWeight;vec2 vThinFilmThickness;float vThinFilmIor;vec2 vBaseWeightInfos;mat4 baseWeightMatrix;vec2 vBaseColorInfos;mat4 baseColorMatrix;vec2 vBaseDiffuseRoughnessInfos;mat4 baseDiffuseRoughnessMatrix;vec2 vBaseMetalnessInfos;mat4 baseMetalnessMatrix;vec2 vSpecularWeightInfos;mat4 specularWeightMatrix;vec2 vSpecularColorInfos;mat4 specularColorMatrix;vec2 vSpecularRoughnessInfos;mat4 specularRoughnessMatrix;vec2 vSpecularRoughnessAnisotropyInfos;mat4 specularRoughnessAnisotropyMatrix;vec2 vTransmissionWeightInfos;mat4 transmissionWeightMatrix;vec2 vTransmissionColorInfos;mat4 transmissionColorMatrix;vec2 vTransmissionDepthInfos;mat4 transmissionDepthMatrix;vec2 vTransmissionScatterInfos;mat4 transmissionScatterMatrix;vec2 vTransmissionDispersionScaleInfos;mat4 transmissionDispersionScaleMatrix;vec2 vSubsurfaceWeightInfos;mat4 subsurfaceWeightMatrix;vec2 vSubsurfaceColorInfos;mat4 subsurfaceColorMatrix;vec2 vSubsurfaceRadiusScaleInfos;mat4 subsurfaceRadiusScaleMatrix;vec2 vCoatWeightInfos;mat4 coatWeightMatrix;vec2 vCoatColorInfos;mat4 coatColorMatrix;vec2 vCoatRoughnessInfos;mat4 coatRoughnessMatrix;vec2 vCoatRoughnessAnisotropyInfos;mat4 coatRoughnessAnisotropyMatrix;vec2 vCoatDarkeningInfos;mat4 coatDarkeningMatrix;vec2 vFuzzWeightInfos;mat4 fuzzWeightMatrix;vec2 vFuzzColorInfos;mat4 fuzzColorMatrix;vec2 vFuzzRoughnessInfos;mat4 fuzzRoughnessMatrix;vec2 vGeometryNormalInfos;mat4 geometryNormalMatrix;vec2 vGeometryTangentInfos;mat4 geometryTangentMatrix;vec2 vGeometryCoatNormalInfos;mat4 geometryCoatNormalMatrix;vec2 vGeometryCoatTangentInfos;mat4 geometryCoatTangentMatrix;vec2 vGeometryOpacityInfos;mat4 geometryOpacityMatrix;vec2 vGeometryThicknessInfos;mat4 geometryThicknessMatrix;vec2 vEmissionColorInfos;mat4 emissionColorMatrix;vec2 vThinFilmWeightInfos;mat4 thinFilmWeightMatrix;vec2 vThinFilmThicknessInfos;mat4 thinFilmThicknessMatrix;vec2 vAmbientOcclusionInfos;mat4 ambientOcclusionMatrix;\n#define ADDITIONAL_UBO_DECLARATION\n};\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapVertexDeclaration\";\nconst shader = `#if defined(GEOMETRY_NORMAL) || defined(PARALLAX) || defined(GEOMETRY_COAT_NORMAL) || defined(ANISOTROPIC) || defined(FUZZ)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapVertex\";\nconst shader = `#if defined(GEOMETRY_NORMAL) || defined(PARALLAX) || defined(GEOMETRY_COAT_NORMAL) || defined(ANISOTROPIC) || defined(FUZZ)\n#if defined(TANGENT) && defined(NORMAL)\nvec3 tbnNormal=normalize(normalUpdated);vec3 tbnTangent=normalize(tangentUpdated.xyz);vec3 tbnBitangent=cross(tbnNormal,tbnTangent)*tangentUpdated.w;vTBN=mat3(finalWorld)*mat3(tbnTangent,tbnBitangent,tbnNormal);\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneVertexDeclaration } from \"./ShadersInclude/sceneVertexDeclaration\";\nimport { decalVertexDeclaration } from \"./ShadersInclude/decalVertexDeclaration\";\nimport { openpbrVertexDeclaration } from \"./ShadersInclude/openpbrVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { openpbrUboDeclaration } from \"./ShadersInclude/openpbrUboDeclaration\";\nimport { uvAttributeDeclaration } from \"./ShadersInclude/uvAttributeDeclaration\";\nimport { mainUVVaryingDeclaration } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { prePassVertexDeclaration } from \"./ShadersInclude/prePassVertexDeclaration\";\nimport { samplerVertexDeclaration } from \"./ShadersInclude/samplerVertexDeclaration\";\nimport { harmonicsFunctions } from \"./ShadersInclude/harmonicsFunctions\";\nimport { openpbrNormalMapVertexDeclaration } from \"./ShadersInclude/openpbrNormalMapVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxFragmentDeclaration } from \"./ShadersInclude/lightVxFragmentDeclaration\";\nimport { lightVxUboDeclaration } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { prePassVertex } from \"./ShadersInclude/prePassVertex\";\nimport { uvVariableDeclaration } from \"./ShadersInclude/uvVariableDeclaration\";\nimport { samplerVertexImplementation } from \"./ShadersInclude/samplerVertexImplementation\";\nimport { openpbrNormalMapVertex } from \"./ShadersInclude/openpbrNormalMapVertex\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertex } from \"./ShadersInclude/shadowsVertex\";\nimport { vertexColorMixing } from \"./ShadersInclude/vertexColorMixing\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"openpbrVertexShader\";\nconst shader = `#define OPENPBR_VERTEX_SHADER\n#define CUSTOM_VERTEX_EXTENSION\nprecision highp float;\n#include<__decl__openpbrVertex>\n#define CUSTOM_VERTEX_BEGIN\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#include<uvAttributeDeclaration>[2..7]\n#include<mainUVVaryingDeclaration>[1..7]\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<helperFunctions>\n#include<pbrBRDFFunctions>\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<prePassVertexDeclaration>\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_COLOR,_VARYINGNAME_,BaseColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,BASE_METALNESS,_VARYINGNAME_,BaseMetalness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_WEIGHT,_VARYINGNAME_,SpecularWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_COLOR,_VARYINGNAME_,SpecularColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS,_VARYINGNAME_,SpecularRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,SpecularRoughnessAnisotropy)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_COLOR,_VARYINGNAME_,TransmissionColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_DEPTH,_VARYINGNAME_,TransmissionDepth)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_SCATTER,_VARYINGNAME_,TransmissionScatter)\n#include<samplerVertexDeclaration>(_DEFINENAME_,TRANSMISSION_DISPERSION_SCALE,_VARYINGNAME_,TransmissionDispersionScale)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SUBSURFACE_COLOR,_VARYINGNAME_,SubsurfaceColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SUBSURFACE_RADIUS_SCALE,_VARYINGNAME_,SubsurfaceRadiusScale)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_WEIGHT,_VARYINGNAME_,CoatWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_COLOR,_VARYINGNAME_,CoatColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_ROUGHNESS,_VARYINGNAME_,CoatRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,CoatRoughnessAnisotropy)\n#include<samplerVertexDeclaration>(_DEFINENAME_,COAT_DARKENING,_VARYINGNAME_,CoatDarkening)\n#include<samplerVertexDeclaration>(_DEFINENAME_,FUZZ_WEIGHT,_VARYINGNAME_,FuzzWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,FUZZ_COLOR,_VARYINGNAME_,FuzzColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,FUZZ_ROUGHNESS,_VARYINGNAME_,FuzzRoughness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_NORMAL,_VARYINGNAME_,GeometryNormal)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_TANGENT,_VARYINGNAME_,GeometryTangent)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_COAT_NORMAL,_VARYINGNAME_,GeometryCoatNormal)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_OPACITY,_VARYINGNAME_,GeometryOpacity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,GEOMETRY_THICKNESS,_VARYINGNAME_,GeometryThickness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,EMISSION_COLOR,_VARYINGNAME_,EmissionColor)\n#include<samplerVertexDeclaration>(_DEFINENAME_,THIN_FILM_WEIGHT,_VARYINGNAME_,ThinFilmWeight)\n#include<samplerVertexDeclaration>(_DEFINENAME_,THIN_FILM_THICKNESS,_VARYINGNAME_,ThinFilmThickness)\n#include<samplerVertexDeclaration>(_DEFINENAME_,AMBIENT_OCCLUSION,_VARYINGNAME_,AmbientOcclusion)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail)\nvarying vec3 vPositionW;\n#if DEBUGMODE>0\nvarying vec4 vClipSpacePosition;\n#endif\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vec3 vEnvironmentIrradiance;\n#include<harmonicsFunctions>\n#endif\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vec4 vColor;\n#endif\n#include<openpbrNormalMapVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightVxFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#ifdef NORMAL\nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#ifdef VERTEXCOLOR\nvec4 colorUpdated=color;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvPositionUVW=positionUpdated;\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#if defined(PREPASS) && ((defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);vPreviousPosition=previousViewProjection*finalPreviousWorld*vec4(positionUpdated,1.0);\n#endif\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);vPositionW=vec3(worldPos);\n#ifdef PREPASS\n#include<prePassVertex>\n#endif\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvNormalW=normalUpdated/vec3(dot(normalWorld[0],normalWorld[0]),dot(normalWorld[1],normalWorld[1]),dot(normalWorld[2],normalWorld[2]));vNormalW=normalize(normalWorld*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\nvec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);\n#if !defined(NATIVE) && !defined(WEBGPU)\nbool bbb=any(isnan(position));if (bbb) { }\n#endif\nfloat NdotV=max(dot(vNormalW,viewDirectionW),0.0);vec3 roughNormal=mix(vNormalW,viewDirectionW,(0.5*(1.0-NdotV))*vBaseDiffuseRoughness);vec3 reflectionVector=vec3(reflectionMatrix*vec4(roughNormal,0)).xyz;\n#else\nvec3 reflectionVector=vec3(reflectionMatrix*vec4(vNormalW,0)).xyz;\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\nvEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector);\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_WORLDPOS\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {gl_Position=viewProjection*worldPos;} else {gl_Position=viewProjectionR*worldPos;}\n#else\ngl_Position=viewProjection*worldPos;\n#endif\n#if DEBUGMODE>0\nvClipSpacePosition=gl_Position;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n#ifndef UV1\nvec2 uvUpdated=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2Updated=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uvUpdated;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2Updated;\n#endif\n#include<uvVariableDeclaration>[3..7]\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_COLOR,_VARYINGNAME_,BaseColor,_MATRIXNAME_,baseColor,_INFONAME_,BaseColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_MATRIXNAME_,baseWeight,_INFONAME_,BaseWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_MATRIXNAME_,baseDiffuseRoughness,_INFONAME_,BaseDiffuseRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,BASE_METALNESS,_VARYINGNAME_,BaseMetalness,_MATRIXNAME_,baseMetalness,_INFONAME_,BaseMetalnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_WEIGHT,_VARYINGNAME_,SpecularWeight,_MATRIXNAME_,specularWeight,_INFONAME_,SpecularWeightInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_COLOR,_VARYINGNAME_,SpecularColor,_MATRIXNAME_,specularColor,_INFONAME_,SpecularColorInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_ROUGHNESS,_VARYINGNAME_,SpecularRoughness,_MATRIXNAME_,specularRoughness,_INFONAME_,SpecularRoughnessInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,SpecularRoughnessAnisotropy,_MATRIXNAME_,specularRoughnessAnisotropy,_INFONAME_,SpecularRoughnessAnisotropyInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight,_MATRIXNAME_,transmissionWeight,_INFONAME_,TransmissionWeightInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_COLOR,_VARYINGNAME_,TransmissionColor,_MATRIXNAME_,transmissionColor,_INFONAME_,TransmissionColorInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_DEPTH,_VARYINGNAME_,TransmissionDepth,_MATRIXNAME_,transmissionDepth,_INFONAME_,TransmissionDepthInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_SCATTER,_VARYINGNAME_,TransmissionScatter,_MATRIXNAME_,transmissionScatter,_INFONAME_,TransmissionScatterInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,TRANSMISSION_DISPERSION_SCALE,_VARYINGNAME_,TransmissionDispersionScale,_MATRIXNAME_,transmissionDispersionScale,_INFONAME_,TransmissionDispersionScaleInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight,_MATRIXNAME_,subsurfaceWeight,_INFONAME_,SubsurfaceWeightInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,SUBSURFACE_COLOR,_VARYINGNAME_,SubsurfaceColor,_MATRIXNAME_,subsurfaceColor,_INFONAME_,SubsurfaceColorInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,SUBSURFACE_RADIUS_SCALE,_VARYINGNAME_,SubsurfaceRadiusScale,_MATRIXNAME_,subsurfaceRadiusScale,_INFONAME_,SubsurfaceRadiusScaleInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,COAT_WEIGHT,_VARYINGNAME_,CoatWeight,_MATRIXNAME_,coatWeight,_INFONAME_,CoatWeightInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,COAT_COLOR,_VARYINGNAME_,CoatColor,_MATRIXNAME_,coatColor,_INFONAME_,CoatColorInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,COAT_ROUGHNESS,_VARYINGNAME_,CoatRoughness,_MATRIXNAME_,coatRoughness,_INFONAME_,CoatRoughnessInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,COAT_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,CoatRoughnessAnisotropy,_MATRIXNAME_,coatRoughnessAnisotropy,_INFONAME_,CoatRoughnessAnisotropyInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,COAT_DARKENING,_VARYINGNAME_,CoatDarkening,_MATRIXNAME_,coatDarkening,_INFONAME_,CoatDarkeningInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,FUZZ_WEIGHT,_VARYINGNAME_,FuzzWeight,_MATRIXNAME_,fuzzWeight,_INFONAME_,FuzzWeightInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,FUZZ_COLOR,_VARYINGNAME_,FuzzColor,_MATRIXNAME_,fuzzColor,_INFONAME_,FuzzColorInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,FUZZ_ROUGHNESS,_VARYINGNAME_,FuzzRoughness,_MATRIXNAME_,fuzzRoughness,_INFONAME_,FuzzRoughnessInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_NORMAL,_VARYINGNAME_,GeometryNormal,_MATRIXNAME_,geometryNormal,_INFONAME_,GeometryNormalInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_COAT_NORMAL,_VARYINGNAME_,GeometryCoatNormal,_MATRIXNAME_,geometryCoatNormal,_INFONAME_,GeometryCoatNormalInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_OPACITY,_VARYINGNAME_,GeometryOpacity,_MATRIXNAME_,geometryOpacity,_INFONAME_,GeometryOpacityInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_THICKNESS,_VARYINGNAME_,GeometryThickness,_MATRIXNAME_,geometryThickness,_INFONAME_,GeometryThicknessInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,GEOMETRY_TANGENT,_VARYINGNAME_,GeometryTangent,_MATRIXNAME_,geometryTangent,_INFONAME_,GeometryTangentInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,EMISSION_COLOR,_VARYINGNAME_,EmissionColor,_MATRIXNAME_,emissionColor,_INFONAME_,EmissionColorInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,THIN_FILM_WEIGHT,_VARYINGNAME_,ThinFilmWeight,_MATRIXNAME_,thinFilmWeight,_INFONAME_,ThinFilmWeightInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,THIN_FILM_THICKNESS,_VARYINGNAME_,ThinFilmThickness,_MATRIXNAME_,thinFilmThickness,_INFONAME_,ThinFilmThicknessInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,AMBIENT_OCCLUSION,_VARYINGNAME_,AmbientOcclusion,_MATRIXNAME_,ambientOcclusion,_INFONAME_,AmbientOcclusionInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_MATRIXNAME_,decal,_INFONAME_,DecalInfos.x)\n#include <samplerVertexImplementation>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_MATRIXNAME_,detail,_INFONAME_,DetailInfos.x)\n#include<openpbrNormalMapVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#include<vertexColorMixing>\n#if defined(POINTSIZE) && !defined(WEBGPU)\ngl_PointSize=pointSize;\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [sceneVertexDeclaration, decalVertexDeclaration, openpbrVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, openpbrUboDeclaration, uvAttributeDeclaration, mainUVVaryingDeclaration, helperFunctions, pbrBRDFFunctions, bonesDeclaration, bakedVertexAnimationDeclaration, instancesDeclaration, prePassVertexDeclaration, samplerVertexDeclaration, harmonicsFunctions, openpbrNormalMapVertexDeclaration, clipPlaneVertexDeclaration, fogVertexDeclaration, lightVxFragmentDeclaration, lightVxUboDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, logDepthDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, prePassVertex, uvVariableDeclaration, samplerVertexImplementation, openpbrNormalMapVertex, clipPlaneVertex, fogVertex, shadowsVertex, vertexColorMixing, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const openpbrVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"sceneFragmentDeclaration\";\nconst shader = `uniform mat4 viewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;\n#endif\nuniform mat4 view;uniform mat4 projection;uniform vec4 vEyePosition;uniform mat4 inverseProjection;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const sceneFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneFragmentDeclaration\";\nimport \"./decalFragmentDeclaration\";\nconst name = \"openpbrFragmentDeclaration\";\nconst shader = `uniform float vBaseWeight;uniform vec4 vBaseColor;uniform float vBaseDiffuseRoughness;uniform vec4 vReflectanceInfo;uniform vec4 vSpecularColor;uniform vec3 vSpecularAnisotropy;uniform float vTransmissionWeight;uniform vec3 vTransmissionColor;uniform float vTransmissionDepth;uniform vec3 vTransmissionScatter;uniform float vTransmissionScatterAnisotropy;uniform float vTransmissionDispersionScale;uniform float vTransmissionDispersionAbbeNumber;uniform float vSubsurfaceWeight;uniform vec3 vSubsurfaceColor;uniform float vSubsurfaceRadius;uniform vec3 vSubsurfaceRadiusScale;uniform float vSubsurfaceScatterAnisotropy;uniform float vCoatWeight;uniform vec3 vCoatColor;uniform float vCoatRoughness;uniform float vCoatRoughnessAnisotropy;uniform float vCoatIor;uniform float vCoatDarkening;uniform float vFuzzWeight;uniform vec3 vFuzzColor;uniform float vFuzzRoughness;uniform vec2 vGeometryCoatTangent;uniform float vGeometryThickness;uniform vec3 vEmissionColor;uniform float vThinFilmWeight;uniform vec2 vThinFilmThickness;uniform float vThinFilmIor;uniform float vGeometryThinWalled;uniform vec4 vLightingIntensity;uniform float visibility;uniform vec2 renderTargetSize;\n#ifdef BASE_COLOR\nuniform vec2 vBaseColorInfos;\n#endif\n#ifdef BASE_WEIGHT\nuniform vec2 vBaseWeightInfos;\n#endif\n#ifdef BASE_METALNESS\nuniform vec2 vBaseMetalnessInfos;\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nuniform vec2 vBaseDiffuseRoughnessInfos;\n#endif\n#ifdef SPECULAR_WEIGHT\nuniform vec2 vSpecularWeightInfos;\n#endif\n#ifdef SPECULAR_COLOR\nuniform vec2 vSpecularColorInfos;\n#endif\n#ifdef SPECULAR_ROUGHNESS\nuniform vec2 vSpecularRoughnessInfos;\n#endif\n#ifdef SPECULAR_ROUGHNESS_ANISOTROPY\nuniform vec2 vSpecularRoughnessAnisotropyInfos;\n#endif\n#ifdef SPECULAR_IOR\nuniform vec2 vSpecularIorInfos;\n#endif\n#ifdef AMBIENT_OCCLUSION\nuniform vec2 vAmbientOcclusionInfos;\n#endif\n#ifdef GEOMETRY_NORMAL\nuniform vec2 vGeometryNormalInfos;\n#endif\n#ifdef GEOMETRY_TANGENT\nuniform vec2 vGeometryTangentInfos;\n#endif\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL)\nuniform vec2 vTangentSpaceParams;\n#endif\n#ifdef GEOMETRY_COAT_NORMAL\nuniform vec2 vGeometryCoatNormalInfos;\n#endif\n#ifdef GEOMETRY_OPACITY\nuniform vec2 vGeometryOpacityInfos;\n#endif\n#ifdef GEOMETRY_THICKNESS\nuniform vec2 vGeometryThicknessInfos;\n#endif\n#ifdef EMISSION_COLOR\nuniform vec2 vEmissionColorInfos;\n#endif\n#ifdef TRANSMISSION_WEIGHT\nuniform vec2 vTransmissionWeightInfos;\n#endif\n#ifdef TRANSMISSION_COLOR\nuniform vec2 vTransmissionColorInfos;\n#endif\n#ifdef TRANSMISSION_DEPTH\nuniform vec2 vTransmissionDepthInfos;\n#endif\n#ifdef TRANSMISSION_SCATTER\nuniform vec2 vTransmissionScatterInfos;\n#endif\n#ifdef TRANSMISSION_DISPERSION_SCALE\nuniform vec2 vTransmissionDispersionScaleInfos;\n#endif\n#ifdef SUBSURFACE_WEIGHT\nuniform vec2 vSubsurfaceWeightInfos;\n#endif\n#ifdef SUBSURFACE_COLOR\nuniform vec2 vSubsurfaceColorInfos;\n#endif\n#ifdef SUBSURFACE_RADIUS_SCALE\nuniform vec2 vSubsurfaceRadiusScaleInfos;\n#endif\n#ifdef COAT_WEIGHT\nuniform vec2 vCoatWeightInfos;\n#endif\n#ifdef COAT_COLOR\nuniform vec2 vCoatColorInfos;\n#endif\n#ifdef COAT_ROUGHNESS\nuniform vec2 vCoatRoughnessInfos;\n#endif\n#ifdef COAT_ROUGHNESS_ANISOTROPY\nuniform vec2 vCoatRoughnessAnisotropyInfos;\n#endif\n#ifdef COAT_IOR\nuniform vec2 vCoatIorInfos;\n#endif\n#ifdef COAT_DARKENING\nuniform vec2 vCoatDarkeningInfos;\n#endif\n#ifdef FUZZ_WEIGHT\nuniform vec2 vFuzzWeightInfos;\n#endif\n#ifdef FUZZ_COLOR\nuniform vec2 vFuzzColorInfos;\n#endif\n#ifdef FUZZ_ROUGHNESS\nuniform vec2 vFuzzRoughnessInfos;\n#endif\n#ifdef GEOMETRY_COAT_TANGENT\nuniform vec2 vGeometryCoatTangentInfos;\n#endif\n#ifdef THIN_FILM_WEIGHT\nuniform vec2 vThinFilmWeightInfos;\n#endif\n#ifdef THIN_FILM_THICKNESS\nuniform vec2 vThinFilmThicknessInfos;\n#endif\n#include<sceneFragmentDeclaration>\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\n#ifdef REALTIME_FILTERING\nuniform vec2 vReflectionFilteringInfo;\n#endif\nuniform mat4 reflectionMatrix;uniform vec3 vReflectionMicrosurfaceInfos;\n#if defined(USEIRRADIANCEMAP) && defined(USE_IRRADIANCE_DOMINANT_DIRECTION)\nuniform vec3 vReflectionDominantDirection;\n#endif\n#if defined(USE_LOCAL_REFLECTIONMAP_CUBIC) && defined(REFLECTIONMAP_CUBIC)\nuniform vec3 vReflectionPosition;uniform vec3 vReflectionSize;\n#endif\n#endif\n#ifdef PREPASS\n#ifdef SS_SCATTERING\nuniform float scatteringDiffusionProfile;\n#endif\n#endif\n#if DEBUGMODE>0\nuniform vec2 vDebugMode;\n#endif\n#ifdef DETAIL\nuniform vec4 vDetailInfos;\n#endif\n#include<decalFragmentDeclaration>\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;uniform vec3 vSphericalL1_1;uniform vec3 vSphericalL10;uniform vec3 vSphericalL11;uniform vec3 vSphericalL2_2;uniform vec3 vSphericalL2_1;uniform vec3 vSphericalL20;uniform vec3 vSphericalL21;uniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;uniform vec3 vSphericalY;uniform vec3 vSphericalZ;uniform vec3 vSphericalXX_ZZ;uniform vec3 vSphericalYY_ZZ;uniform vec3 vSphericalZZ;uniform vec3 vSphericalXY;uniform vec3 vSphericalYZ;uniform vec3 vSphericalZX;\n#endif\n#endif\n#ifdef REFRACTED_BACKGROUND\nuniform mat4 backgroundRefractionMatrix;uniform vec3 vBackgroundRefractionInfos;\n#endif\n#if TEXTURE_REPETITION_MODE>0\nuniform vec4 vTextureRepetitionHexTilingParams;\n#endif\n#define ADDITIONAL_FRAGMENT_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nimport \"./pbrFragmentReflectionDeclaration\";\nconst name = \"openpbrFragmentSamplersDeclaration\";\nconst shader = `#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_COLOR,_VARYINGNAME_,BaseColor,_SAMPLERNAME_,baseColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_WEIGHT,_VARYINGNAME_,BaseWeight,_SAMPLERNAME_,baseWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_DIFFUSE_ROUGHNESS,_VARYINGNAME_,BaseDiffuseRoughness,_SAMPLERNAME_,baseDiffuseRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,BASE_METALNESS,_VARYINGNAME_,BaseMetalness,_SAMPLERNAME_,baseMetalness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_WEIGHT,_VARYINGNAME_,SpecularWeight,_SAMPLERNAME_,specularWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_COLOR,_VARYINGNAME_,SpecularColor,_SAMPLERNAME_,specularColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS,_VARYINGNAME_,SpecularRoughness,_SAMPLERNAME_,specularRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,SpecularRoughnessAnisotropy,_SAMPLERNAME_,specularRoughnessAnisotropy)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight,_SAMPLERNAME_,transmissionWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_COLOR,_VARYINGNAME_,TransmissionColor,_SAMPLERNAME_,transmissionColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_DEPTH,_VARYINGNAME_,TransmissionDepth,_SAMPLERNAME_,transmissionDepth)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_SCATTER,_VARYINGNAME_,TransmissionScatter,_SAMPLERNAME_,transmissionScatter)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_DISPERSION_SCALE,_VARYINGNAME_,TransmissionDispersionScale,_SAMPLERNAME_,transmissionDispersionScale)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight,_SAMPLERNAME_,subsurfaceWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_COLOR,_VARYINGNAME_,SubsurfaceColor,_SAMPLERNAME_,subsurfaceColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_RADIUS_SCALE,_VARYINGNAME_,SubsurfaceRadiusScale,_SAMPLERNAME_,subsurfaceRadiusScale)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_WEIGHT,_VARYINGNAME_,CoatWeight,_SAMPLERNAME_,coatWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_COLOR,_VARYINGNAME_,CoatColor,_SAMPLERNAME_,coatColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_ROUGHNESS,_VARYINGNAME_,CoatRoughness,_SAMPLERNAME_,coatRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_ROUGHNESS_ANISOTROPY,_VARYINGNAME_,CoatRoughnessAnisotropy,_SAMPLERNAME_,coatRoughnessAnisotropy)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,COAT_DARKENING,_VARYINGNAME_,CoatDarkening,_SAMPLERNAME_,coatDarkening)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,FUZZ_WEIGHT,_VARYINGNAME_,FuzzWeight,_SAMPLERNAME_,fuzzWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,FUZZ_COLOR,_VARYINGNAME_,FuzzColor,_SAMPLERNAME_,fuzzColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,FUZZ_ROUGHNESS,_VARYINGNAME_,FuzzRoughness,_SAMPLERNAME_,fuzzRoughness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_OPACITY,_VARYINGNAME_,GeometryOpacity,_SAMPLERNAME_,geometryOpacity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_TANGENT,_VARYINGNAME_,GeometryTangent,_SAMPLERNAME_,geometryTangent)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_COAT_TANGENT,_VARYINGNAME_,GeometryCoatTangent,_SAMPLERNAME_,geometryCoatTangent)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_THICKNESS,_VARYINGNAME_,GeometryThickness,_SAMPLERNAME_,geometryThickness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSION_COLOR,_VARYINGNAME_,EmissionColor,_SAMPLERNAME_,emissionColor)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,THIN_FILM_WEIGHT,_VARYINGNAME_,ThinFilmWeight,_SAMPLERNAME_,thinFilmWeight)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,THIN_FILM_THICKNESS,_VARYINGNAME_,ThinFilmThickness,_SAMPLERNAME_,thinFilmThickness)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT_OCCLUSION,_VARYINGNAME_,AmbientOcclusion,_SAMPLERNAME_,ambientOcclusion)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_SAMPLERNAME_,decal)\n#include<pbrFragmentReflectionDeclaration>\n#ifdef ENVIRONMENTBRDF\nuniform sampler2D environmentBrdfSampler;\n#endif\n#ifdef FUZZENVIRONMENTBRDF\nuniform sampler2D environmentFuzzBrdfSampler;\n#endif\n#ifdef REFRACTED_BACKGROUND\nuniform sampler2D backgroundRefractionSampler;\n#endif\n#ifdef USE_IRRADIANCE_TEXTURE_FOR_SCATTERING\nuniform sampler2D sceneIrradianceSampler;uniform sampler2D sceneDepthSampler;\n#endif\n#if defined(ANISOTROPIC) || defined(FUZZ) || defined(REFRACTED_BACKGROUND) || defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING)\nuniform sampler2D blueNoiseSampler;\n#endif\n#ifdef IBL_CDF_FILTERING\nuniform sampler2D icdfSampler;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrFragmentSamplersDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapFragmentMainFunctions\";\nconst shader = `#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL) || defined(ANISOTROPIC) || defined(FUZZ) || defined(DETAIL)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nuniform mat4 normalMatrix;\n#if defined(WEBGL2) || defined(WEBGPU)\nmat4 toNormalMatrix(mat4 wMatrix)\n{mat4 ret=inverse(wMatrix);ret=transpose(ret);ret[0][3]=0.;ret[1][3]=0.;ret[2][3]=0.;ret[3]=vec4(0.,0.,0.,1.);return ret;}\n#else\nmat4 toNormalMatrix(mat4 m)\n{float\na00=m[0][0],a01=m[0][1],a02=m[0][2],a03=m[0][3],\na10=m[1][0],a11=m[1][1],a12=m[1][2],a13=m[1][3],\na20=m[2][0],a21=m[2][1],a22=m[2][2],a23=m[2][3],\na30=m[3][0],a31=m[3][1],a32=m[3][2],a33=m[3][3],\nb00=a00*a11-a01*a10,\nb01=a00*a12-a02*a10,\nb02=a00*a13-a03*a10,\nb03=a01*a12-a02*a11,\nb04=a01*a13-a03*a11,\nb05=a02*a13-a03*a12,\nb06=a20*a31-a21*a30,\nb07=a20*a32-a22*a30,\nb08=a20*a33-a23*a30,\nb09=a21*a32-a22*a31,\nb10=a21*a33-a23*a31,\nb11=a22*a33-a23*a32,\ndet=b00*b11-b01*b10+b02*b09+b03*b08-b04*b07+b05*b06;mat4 mi=mat4(\na11*b11-a12*b10+a13*b09,\na02*b10-a01*b11-a03*b09,\na31*b05-a32*b04+a33*b03,\na22*b04-a21*b05-a23*b03,\na12*b08-a10*b11-a13*b07,\na00*b11-a02*b08+a03*b07,\na32*b02-a30*b05-a33*b01,\na20*b05-a22*b02+a23*b01,\na10*b10-a11*b08+a13*b06,\na01*b08-a00*b10-a03*b06,\na30*b04-a31*b02+a33*b00,\na21*b02-a20*b04-a23*b00,\na11*b07-a10*b09-a12*b06,\na00*b09-a01*b07+a02*b06,\na31*b01-a30*b03-a32*b00,\na20*b03-a21*b01+a22*b00)/det;return mat4(mi[0][0],mi[1][0],mi[2][0],mi[3][0],\nmi[0][1],mi[1][1],mi[2][1],mi[3][1],\nmi[0][2],mi[1][2],mi[2][2],mi[3][2],\nmi[0][3],mi[1][3],mi[2][3],mi[3][3]);}\n#endif\n#endif\nvec3 perturbNormalBase(mat3 cotangentFrame,vec3 normal,float scale)\n{\n#ifdef NORMALXYSCALE\nnormal=normalize(normal*vec3(scale,scale,1.0));\n#endif\nreturn normalize(cotangentFrame*normal);}\nvec3 perturbNormal(mat3 cotangentFrame,vec3 textureSample,float scale)\n{return perturbNormalBase(cotangentFrame,textureSample*2.0-1.0,scale);}\nmat3 cotangent_frame(vec3 normal,vec3 p,vec2 uv,vec2 tangentSpaceParams)\n{vec3 dp1=dFdx(p);vec3 dp2=dFdy(p);vec2 duv1=dFdx(uv);vec2 duv2=dFdy(uv);vec3 dp2perp=cross(dp2,normal);vec3 dp1perp=cross(normal,dp1);vec3 tangent=dp2perp*duv1.x+dp1perp*duv2.x;vec3 bitangent=dp2perp*duv1.y+dp1perp*duv2.y;tangent*=tangentSpaceParams.x;bitangent*=tangentSpaceParams.y;float det=max(dot(tangent,tangent),dot(bitangent,bitangent));float invmax=det==0.0 ? 0.0 : inversesqrt(det);return mat3(tangent*invmax,bitangent*invmax,normal);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapFragmentMainFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./samplerFragmentDeclaration\";\nconst name = \"openpbrNormalMapFragmentFunctions\";\nconst shader = `#if defined(GEOMETRY_NORMAL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_NORMAL,_VARYINGNAME_,GeometryNormal,_SAMPLERNAME_,geometryNormal)\n#endif\n#if defined(GEOMETRY_COAT_NORMAL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,GEOMETRY_COAT_NORMAL,_VARYINGNAME_,GeometryCoatNormal,_SAMPLERNAME_,geometryCoatNormal)\n#endif\n#if defined(DETAIL)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_SAMPLERNAME_,detail)\n#endif\n#if defined(GEOMETRY_NORMAL) && defined(PARALLAX)\nconst float minSamples=4.;const float maxSamples=15.;const int iMaxSamples=15;vec2 parallaxOcclusion(vec3 vViewDirCoT,vec3 vNormalCoT,vec2 texCoord,float parallaxScale) {float parallaxLimit=length(vViewDirCoT.xy)/vViewDirCoT.z;parallaxLimit*=parallaxScale;vec2 vOffsetDir=normalize(vViewDirCoT.xy);vec2 vMaxOffset=vOffsetDir*parallaxLimit;float numSamples=maxSamples+(dot(vViewDirCoT,vNormalCoT)*(minSamples-maxSamples));float stepSize=1.0/numSamples;float currRayHeight=1.0;vec2 vCurrOffset=vec2(0,0);vec2 vLastOffset=vec2(0,0);float lastSampledHeight=1.0;float currSampledHeight=1.0;bool keepWorking=true;for (int i=0; i<iMaxSamples; i++)\n{currSampledHeight=texture2D(geometryNormalSampler,texCoord+vCurrOffset).w;if (!keepWorking)\n{}\nelse if (currSampledHeight>currRayHeight)\n{float delta1=currSampledHeight-currRayHeight;float delta2=(currRayHeight+stepSize)-lastSampledHeight;float ratio=delta1/(delta1+delta2);vCurrOffset=(ratio)* vLastOffset+(1.0-ratio)*vCurrOffset;keepWorking=false;}\nelse\n{currRayHeight-=stepSize;vLastOffset=vCurrOffset;\n#ifdef PARALLAX_RHS\nvCurrOffset-=stepSize*vMaxOffset;\n#else\nvCurrOffset+=stepSize*vMaxOffset;\n#endif\nlastSampledHeight=currSampledHeight;}}\nreturn vCurrOffset;}\nvec2 parallaxOffset(vec3 viewDir,float heightScale)\n{float height=texture2D(geometryNormalSampler,vGeometryNormalUV).w;vec2 texCoordOffset=heightScale*viewDir.xy*height;\n#ifdef PARALLAX_RHS\nreturn texCoordOffset;\n#else\nreturn -texCoordOffset;\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapFragmentFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrDielectricReflectance\";\nconst shader = `struct ReflectanceParams\n{float F0;float F90;vec3 coloredF0;vec3 coloredF90;};\n#define pbr_inline\nReflectanceParams dielectricReflectance(\nin float insideIOR,in float outsideIOR,in vec3 specularColor,in float specularWeight\n)\n{ReflectanceParams outParams;float dielectricF0=pow((insideIOR-outsideIOR)/(insideIOR+outsideIOR),2.0);float f90Scale=clamp(2.0*abs(insideIOR-outsideIOR),0.0,1.0);\n#if (DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_OPENPBR)\nvec3 dielectricColorF90=specularColor.rgb*vec3(f90Scale);\n#else\nvec3 dielectricColorF90=vec3(f90Scale);\n#endif\n#if DIELECTRIC_SPECULAR_MODEL==DIELECTRIC_SPECULAR_MODEL_GLTF\nfloat maxF0=max(specularColor.r,max(specularColor.g,specularColor.b));outParams.F0=dielectricF0*specularWeight*maxF0;\n#else\noutParams.F0=dielectricF0*specularWeight;\n#endif\noutParams.F90=f90Scale*specularWeight;outParams.coloredF0=vec3(dielectricF0*specularWeight)*specularColor.rgb;outParams.coloredF90=dielectricColorF90*vec3(specularWeight);return outParams;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrDielectricReflectance = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrConductorReflectance\";\nconst shader = `#define pbr_inline\nReflectanceParams conductorReflectance(in vec3 baseColor,in vec3 specularColor,in float specularWeight)\n{ReflectanceParams outParams;\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\noutParams.coloredF0=baseColor*specularWeight;outParams.coloredF90=specularColor*specularWeight;\n#else\noutParams.coloredF0=baseColor;outParams.coloredF90=vec3(1.0);\n#endif\noutParams.F0=1.0;outParams.F90=1.0;return outParams;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrConductorReflectance = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrAmbientOcclusionFunctions\";\nconst shader = `float compute_specular_occlusion(const float n_dot_v,const float metallic,const float ambient_occlusion,const float roughness)\n{float specular_occlusion=saturate(pow(n_dot_v+ambient_occlusion,exp2(-16.0*roughness-1.0))-1.0+ambient_occlusion);return mix(specular_occlusion,1.0,metallic*square(1.0-roughness));}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrAmbientOcclusionFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrGeometryInfo\";\nconst shader = `struct geometryInfoOutParams\n{float NdotV;float NdotVUnclamped;vec3 environmentBrdf;float horizonOcclusion;};struct geometryInfoAnisoOutParams\n{float NdotV;float NdotVUnclamped;vec3 environmentBrdf;float horizonOcclusion;float anisotropy;vec3 anisotropicTangent;vec3 anisotropicBitangent;mat3 TBN;};\n#define pbr_inline\ngeometryInfoOutParams geometryInfo(\nin vec3 normalW,in vec3 viewDirectionW,in float roughness,in vec3 geometricNormalW\n)\n{geometryInfoOutParams outParams;outParams.NdotVUnclamped=dot(normalW,viewDirectionW);outParams.NdotV=absEps(outParams.NdotVUnclamped);\n#if defined(ENVIRONMENTBRDF)\noutParams.environmentBrdf=getBRDFLookup(outParams.NdotV,roughness);\n#else\noutParams.environmentBrdf=vec3(0.0);\n#endif\noutParams.horizonOcclusion=1.0;\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\n#ifdef HORIZONOCCLUSION\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL)\n#ifdef REFLECTIONMAP_3D\noutParams.horizonOcclusion=environmentHorizonOcclusion(-viewDirectionW,normalW,geometricNormalW);\n#endif\n#endif\n#endif\n#endif\nreturn outParams;}\n#define pbr_inline\ngeometryInfoAnisoOutParams geometryInfoAniso(\nin vec3 normalW,in vec3 viewDirectionW,in float roughness,in vec3 geometricNormalW\n,in vec3 vAnisotropy,in mat3 TBN\n)\n{geometryInfoOutParams geoInfo=geometryInfo(normalW,viewDirectionW,roughness,geometricNormalW);geometryInfoAnisoOutParams outParams;outParams.NdotV=geoInfo.NdotV;outParams.NdotVUnclamped=geoInfo.NdotVUnclamped;outParams.environmentBrdf=geoInfo.environmentBrdf;outParams.horizonOcclusion=geoInfo.horizonOcclusion;outParams.anisotropy=vAnisotropy.b;vec3 anisotropyDirection=vec3(vAnisotropy.xy,0.);mat3 anisoTBN=mat3(normalize(TBN[0]),normalize(TBN[1]),normalize(TBN[2]));outParams.anisotropicTangent=normalize(anisoTBN*anisotropyDirection);outParams.anisotropicBitangent=normalize(cross(anisoTBN[2],outParams.anisotropicTangent));outParams.TBN=TBN;return outParams;}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrGeometryInfo = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrIblFunctions\";\nconst shader = `#ifdef REFLECTION\nvec3 sampleIrradiance(\nin vec3 surfaceNormal\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,in vec3 vEnvironmentIrradianceSH\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,in mat4 iblMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n#ifdef REFLECTIONMAP_3D\n,in samplerCube irradianceSampler\n#else\n,in sampler2D irradianceSampler\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,in vec3 reflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,in sampler2D icdfSampler\n#endif\n#endif\n,in vec2 vReflectionInfos\n,in vec3 viewDirectionW\n,in float diffuseRoughness\n,in vec3 surfaceAlbedo\n) {vec3 environmentIrradiance=vec3(0.,0.,0.);\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\nvec3 irradianceVector=(iblMatrix*vec4(surfaceNormal,0)).xyz;vec3 irradianceView=(iblMatrix*vec4(viewDirectionW,0)).xyz;\n#if !defined(USE_IRRADIANCE_DOMINANT_DIRECTION) && !defined(REALTIME_FILTERING)\n#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY\n{float NdotV=max(dot(surfaceNormal,viewDirectionW),0.0);irradianceVector=mix(irradianceVector,irradianceView,(0.5*(1.0-NdotV))*diffuseRoughness);}\n#endif\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;irradianceView.z*=-1.0;\n#endif\n#ifdef INVERTCUBICMAP\nirradianceVector.y*=-1.0;irradianceView.y*=-1.0;\n#endif\n#endif\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\nenvironmentIrradiance=vEnvironmentIrradianceSH;\n#else\n#if defined(REALTIME_FILTERING)\nenvironmentIrradiance=irradiance(reflectionSampler,irradianceVector,vReflectionFilteringInfo,diffuseRoughness,surfaceAlbedo,irradianceView\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n);\n#else\nenvironmentIrradiance=computeEnvironmentIrradiance(irradianceVector);\n#endif\n#endif\n#elif defined(USEIRRADIANCEMAP)\n#ifdef REFLECTIONMAP_3D\nvec4 environmentIrradianceFromTexture=sampleReflection(irradianceSampler,irradianceVector);\n#else\nvec4 environmentIrradianceFromTexture=sampleReflection(irradianceSampler,reflectionCoords);\n#endif\nenvironmentIrradiance=environmentIrradianceFromTexture.rgb;\n#ifdef RGBDREFLECTION\nenvironmentIrradiance.rgb=fromRGBD(environmentIrradianceFromTexture);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentIrradiance.rgb=toLinearSpace(environmentIrradiance.rgb);\n#endif\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\nvec3 Ls=normalize(reflectionDominantDirection);float NoL=dot(irradianceVector,Ls);float NoV=dot(irradianceVector,irradianceView);vec3 diffuseRoughnessTerm=vec3(1.0);\n#if BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_EON\nfloat LoV=dot (Ls,irradianceView);float mag=length(reflectionDominantDirection)*2.0;vec3 clampedAlbedo=clamp(surfaceAlbedo,vec3(0.1),vec3(1.0));diffuseRoughnessTerm=diffuseBRDF_EON(clampedAlbedo,diffuseRoughness,NoL,NoV,LoV)*PI;diffuseRoughnessTerm=diffuseRoughnessTerm/clampedAlbedo;diffuseRoughnessTerm=mix(vec3(1.0),diffuseRoughnessTerm,sqrt(clamp(mag*NoV,0.0,1.0)));\n#elif BASE_DIFFUSE_MODEL==BRDF_DIFFUSE_MODEL_BURLEY\nvec3 H=(irradianceView+Ls)*0.5;float VoH=dot(irradianceView,H);diffuseRoughnessTerm=vec3(diffuseBRDF_Burley(NoL,NoV,VoH,diffuseRoughness)*PI);\n#endif\nenvironmentIrradiance=environmentIrradiance.rgb*diffuseRoughnessTerm;\n#endif\n#endif\nenvironmentIrradiance*=vReflectionInfos.x;return environmentIrradiance;}\n#define pbr_inline\n#ifdef REFLECTIONMAP_3D\nvec3 createReflectionCoords(\n#else\nvec2 createReflectionCoords(\n#endif\nin vec3 vPositionW\n,in vec3 normalW\n)\n{vec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=reflectionVector;\n#else\nvec2 reflectionCoords=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\nreturn reflectionCoords;}\n#define pbr_inline\n#define inline\nvec3 sampleRadiance(\nin float alphaG\n,in vec3 vReflectionMicrosurfaceInfos\n,in vec2 vReflectionInfos\n,in geometryInfoOutParams geoInfo\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSampler\n,const vec3 reflectionCoords\n#else\n,in sampler2D reflectionSampler\n,const vec2 reflectionCoords\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vReflectionFilteringInfo\n#endif\n)\n{vec4 environmentRadiance=vec4(0.,0.,0.,0.);\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG,geoInfo.NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nfloat reflectionLOD=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,roughness);\n#else\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG);\n#endif\nreflectionLOD=reflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\n#ifdef REALTIME_FILTERING\nenvironmentRadiance=vec4(radiance(alphaG,reflectionSampler,reflectionCoords,vReflectionFilteringInfo),1.0);\n#else\nenvironmentRadiance=sampleReflectionLod(reflectionSampler,reflectionCoords,reflectionLOD);\n#endif\n#ifdef RGBDREFLECTION\nenvironmentRadiance.rgb=fromRGBD(environmentRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentRadiance.rgb=toLinearSpace(environmentRadiance.rgb);\n#endif\nenvironmentRadiance.rgb*=vec3(vReflectionInfos.x);return environmentRadiance.rgb;}\n#if defined(ANISOTROPIC)\n#define pbr_inline\n#define inline\nvec3 sampleRadianceAnisotropic(\nin float alphaG\n,in vec3 vReflectionMicrosurfaceInfos\n,in vec2 vReflectionInfos\n,in geometryInfoAnisoOutParams geoInfo\n,const vec3 normalW\n,const vec3 viewDirectionW\n,const vec3 positionW\n,const vec3 noise\n,bool isRefraction\n,float ior\n#ifdef REFLECTIONMAP_3D\n,in samplerCube reflectionSampler\n#else\n,in sampler2D reflectionSampler\n#endif\n#ifdef REALTIME_FILTERING\n,in vec2 vReflectionFilteringInfo\n#endif\n)\n{vec4 environmentRadiance=vec4(0.,0.,0.,0.);float alphaT=alphaG*sqrt(2.0/(1.0+(1.0-geoInfo.anisotropy)*(1.0-geoInfo.anisotropy)));float alphaB=(1.0-geoInfo.anisotropy)*alphaT;alphaG=alphaB;\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG,geoInfo.NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nfloat reflectionLOD=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,roughness);\n#else\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG);\n#endif\nreflectionLOD=reflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\n#ifdef REALTIME_FILTERING\nvec3 view=(reflectionMatrix*vec4(viewDirectionW,0.0)).xyz;vec3 tangent=(reflectionMatrix*vec4(geoInfo.anisotropicTangent,0.0)).xyz;vec3 bitangent=(reflectionMatrix*vec4(geoInfo.anisotropicBitangent,0.0)).xyz;vec3 normal=(reflectionMatrix*vec4(normalW,0.0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nview.z*=-1.0;tangent.z*=-1.0;bitangent.z*=-1.0;normal.z*=-1.0;\n#endif\nenvironmentRadiance=vec4(radianceAnisotropic(alphaT,alphaB,reflectionSampler,view,tangent,bitangent,normal,vReflectionFilteringInfo,noise.xy,isRefraction,ior),1.0);\n#else\nconst int samples=16;vec4 radianceSample=vec4(0.0);float sample_weight=0.0;float total_weight=0.0;float step=1.0/float(max(samples-1,1));for (int i=0; i<samples; ++i) {float t=mix(-1.0,1.0,float(i)*step);t+=step*2.0*noise.x;sample_weight=max(1.0-abs(t),0.001);sample_weight*=sample_weight;t*=min(4.0*alphaT*geoInfo.anisotropy,1.0);vec3 bentNormal;if (t<0.0) {float blend=t+1.0;bentNormal=normalize(mix(-geoInfo.anisotropicTangent,normalW,blend));} else if (t>0.0) {float blend=t;bentNormal=normalize(mix(normalW,geoInfo.anisotropicTangent,blend));} else {bentNormal=normalW;}\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords;if (isRefraction) {reflectionCoords=double_refract(-viewDirectionW,bentNormal,ior);} else {reflectionCoords=reflect(-viewDirectionW,bentNormal);}\nreflectionCoords=vec3(reflectionMatrix*vec4(reflectionCoords,0));\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionCoords.z*=-1.0;\n#endif\n#else\nvec3 sampleDirection;if (isRefraction) {sampleDirection=double_refract(-viewDirectionW,bentNormal,ior);} else {sampleDirection=reflect(-viewDirectionW,bentNormal);}\nvec3 originalViewDirectionW=normalize(vEyePosition.xyz-positionW);vec3 mappingNormalCandidate=originalViewDirectionW+sampleDirection;vec3 mappingNormal;if (dot(mappingNormalCandidate,mappingNormalCandidate)>Epsilon) {mappingNormal=normalize(mappingNormalCandidate);} else {vec3 perpendicularAxis=abs(originalViewDirectionW.x)<0.9 ? vec3(1.0,0.0,0.0) : vec3(0.0,1.0,0.0);mappingNormal=normalize(cross(originalViewDirectionW,perpendicularAxis));}\nvec2 reflectionCoords=createReflectionCoords(positionW,mappingNormal);\n#endif\nradianceSample=sampleReflectionLod(reflectionSampler,reflectionCoords,reflectionLOD);\n#ifdef RGBDREFLECTION\nenvironmentRadiance.rgb+=sample_weight*fromRGBD(radianceSample);\n#elif defined(GAMMAREFLECTION)\nenvironmentRadiance.rgb+=sample_weight*toLinearSpace(radianceSample.rgb);\n#else\nenvironmentRadiance.rgb+=sample_weight*radianceSample.rgb;\n#endif\ntotal_weight+=sample_weight;}\nenvironmentRadiance=vec4(environmentRadiance.xyz/float(total_weight),1.0);\n#endif\nenvironmentRadiance.rgb*=vec3(vReflectionInfos.x);return environmentRadiance.rgb;}\n#endif\n#endif\n#if defined(ENVIRONMENTBRDF)\n#define pbr_inline\nfloat computeDielectricIblFresnel(in ReflectanceParams reflectance,in vec3 environmentBrdf)\n{float dielectricIblFresnel=getReflectanceFromBRDFLookup(vec3(reflectance.F0),vec3(reflectance.F90),environmentBrdf).r;float dielectricECF=1.0+reflectance.F0*(1.0/environmentBrdf.y-1.0);return clamp(dielectricIblFresnel*dielectricECF,0.0,1.0);}\n#define pbr_inline\nvec3 computeConductorIblFresnel(in ReflectanceParams reflectance,in vec3 environmentBrdf)\n{\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR) && defined(ENVIRONMENTBRDF)\nvec3 openPBRBrdf=vec3(environmentBrdf.xy,environmentBrdf.z/BRDF_Z_SCALE);vec3 b =getF82B(reflectance.coloredF0,reflectance.coloredF90);vec3 E_F82=getF82DirectionalAlbedo(reflectance.coloredF0,vec3(1.0),b,openPBRBrdf);vec3 F_avg=getF82AverageFresnel(reflectance.coloredF0,b);vec3 ECF =vec3(1.0)+F_avg*(vec3(1.0)/openPBRBrdf.y-vec3(1.0));return clamp(E_F82*ECF,vec3(0.0),vec3(1.0));\n#else\nreturn getReflectanceFromBRDFLookup(reflectance.coloredF0,reflectance.coloredF90,environmentBrdf);\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrIblFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrVolumeFunctions\";\nconst shader = `struct OpenPBRHomogeneousVolume {vec3 extinction_coeff; \nvec3 ss_albedo; \nvec3 multi_scatter_color; \nvec3 absorption_coeff; \nvec3 scatter_coeff; \nfloat anisotropy; };OpenPBRHomogeneousVolume computeOpenPBRTransmissionVolume(\nin vec3 transmission_color,\nin float transmission_depth,\nin vec3 transmission_scatter,\nin float anisotropy\n)\n{OpenPBRHomogeneousVolume volumeParams;volumeParams.absorption_coeff=vec3(0.0);volumeParams.scatter_coeff=vec3(0.0);volumeParams.anisotropy=anisotropy;\n#ifdef GEOMETRY_THIN_WALLED\nvolumeParams.scatter_coeff=vec3(1.0);volumeParams.anisotropy=1.0; \nvolumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=vec3(1.0);\n#else\nif (transmission_depth>0.0) {vec3 invDepth=vec3(1./maxEps(transmission_depth));volumeParams.extinction_coeff=-log(maxEps(transmission_color.rgb))*invDepth;volumeParams.scatter_coeff=transmission_scatter.rgb*invDepth;volumeParams.absorption_coeff=volumeParams.extinction_coeff-volumeParams.scatter_coeff.rgb;float minCoeff=min3(volumeParams.absorption_coeff);if (minCoeff<0.0) {volumeParams.absorption_coeff-=vec3(minCoeff);}\nvolumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=volumeParams.scatter_coeff/(volumeParams.extinction_coeff);} else {volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=vec3(0.0);}\n#endif\nreturn volumeParams;}\nOpenPBRHomogeneousVolume computeOpenPBRSubsurfaceVolume(\nin vec3 subsurface_color,\nin float subsurface_radius,\nin vec3 subsurface_radius_scale,\nin float anisotropy\n)\n{OpenPBRHomogeneousVolume volumeParams;volumeParams.absorption_coeff=vec3(0.0);volumeParams.scatter_coeff=vec3(0.0);volumeParams.anisotropy=anisotropy;volumeParams.multi_scatter_color=subsurface_color;vec3 mfp=subsurface_radius_scale*vec3(subsurface_radius);volumeParams.extinction_coeff=vec3(1.0)/maxEps(mfp);volumeParams.ss_albedo=multiScatterToSingleScatterAlbedo(subsurface_color,anisotropy);volumeParams.scatter_coeff=volumeParams.ss_albedo*volumeParams.extinction_coeff;volumeParams.absorption_coeff=volumeParams.extinction_coeff-volumeParams.scatter_coeff.rgb;float minCoeff=min3(volumeParams.absorption_coeff);if (minCoeff<0.0) {volumeParams.absorption_coeff-=vec3(minCoeff);}\nvolumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;return volumeParams;}\nvec3 sss_pdf(float r,vec3 d)\n{d=max(vec3(1e-4f),d);return (exp(-r/d)+exp(-r/(3.0f*d)))/max(vec3(1e-5f),8.0f*PI*d*r);}\nfloat sss_samples_pdf(float r,float d)\n{d=max(1e-4f,d);return exp(-r/(3.0f*d))/(6.0f*PI*d*r);}\nfloat sss_samples_icdf(float x,float d)\n{d=max(1e-4f,d);x=max(1e-4f,x);return -3.0f*log(x)*d;}\nfloat samples_scale(float x,float d)\n{return 1.0f-exp(-x/(3.0f*d));}\nvec3 sss_get_position(sampler2D depth_texture,vec2 tex_coord,vec2 render_resolution,mat4 inv_proj)\n{vec4 P=vec4(tex_coord,texelFetch(depth_texture,ivec2(tex_coord*render_resolution),0).x,1.0f);P.xy=2.0f*P.xy-1.0f;P=inv_proj*P;return P.xyz/P.w;}\nfloat sss_filter_scale(float currZ,mat4 proj)\n{return 1.0f/dot(vec2(proj[2].w,proj[3].w),vec2(currZ,1.0f));}\nfloat projective_to_pixels(float proj_dist,mat4 proj,vec2 resolution)\n{return proj_dist*proj[1][1]*resolution.y;}\nfloat pixels_to_projective(float pixel_dist,mat4 proj,vec2 resolution)\n{return pixel_dist/(proj[1][1]*resolution.y);}\nvec3 sss_convolve(sampler2D sss_irradiance_texture,sampler2D depth_texture,vec2 render_resolution,vec3 d,mat4 proj,mat4 inv_proj,int sample_count,vec2 noise)\n{vec2 tex_coord=gl_FragCoord.xy/render_resolution;vec3 unconvolved_irradiance=texelFetch(sss_irradiance_texture,ivec2(gl_FragCoord.xy),0).rgb;vec3 curr_pos=sss_get_position(depth_texture,tex_coord,render_resolution,inv_proj);float dmax=max3(d);float max_dmax=0.1*float(sample_count);if (dmax>max_dmax)\n{d.rgb*=max_dmax/dmax;dmax=max_dmax;}\nfloat dz=dmax*sss_filter_scale(curr_pos.z,proj);mat2 projMat2d=mat2(proj);if (determinant(projMat2d)*dz<1e-4f)\nreturn unconvolved_irradiance;float overscan_size_in_pixels=max(render_resolution.x,render_resolution.y)*0.1;const float filter_crop_ratio=0.8f; \nfloat crop_radius=projective_to_pixels(sss_samples_icdf(1.0f-filter_crop_ratio,dz),proj,render_resolution);if (crop_radius>overscan_size_in_pixels)\n{d.rgb*=overscan_size_in_pixels/crop_radius;dz*=overscan_size_in_pixels/crop_radius;}\nfloat filter_samples_scale=samples_scale(pixels_to_projective(overscan_size_in_pixels,proj,render_resolution),dz);vec3 irradiance_sum=vec3(0.0f);vec3 weight_sum=vec3(0.0f);for (int i=0; i<sample_count; i++)\n{vec2 r=fract(plasticSequence(uint(i))+noise);r.x*=TWO_PI;r.y*=filter_samples_scale;float icdf=sss_samples_icdf(1.0-r.y,dz);vec2 sample_uv=tex_coord+icdf*projMat2d*vec2(cos(r.x),sin(r.x));vec4 sss_irradiance=texelFetch(sss_irradiance_texture,ivec2(sample_uv*render_resolution),0);float dist=distance(curr_pos,sss_get_position(depth_texture,sample_uv,render_resolution,inv_proj));if (dist>0.0f)\n{vec3 weights=sss_irradiance.a/sss_samples_pdf(icdf,dz)*sss_pdf(dist,d.rgb);irradiance_sum+=weights*sss_irradiance.rgb;weight_sum+=weights;}}\nreturn vec3(weight_sum.r<1e-5f ? unconvolved_irradiance.r : irradiance_sum.r/weight_sum.r,\nweight_sum.g<1e-5f ? unconvolved_irradiance.g : irradiance_sum.g/weight_sum.g,\nweight_sum.b<1e-5f ? unconvolved_irradiance.b : irradiance_sum.b/weight_sum.b);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrVolumeFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrNormalMapFragment\";\nconst shader = `vec2 uvOffset=vec2(0.0,0.0);\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL) || defined(PARALLAX) || defined(DETAIL)\n#ifdef NORMALXYSCALE\nfloat normalScale=1.0;\n#elif defined(GEOMETRY_NORMAL)\nfloat normalScale=vGeometryNormalInfos.y;\n#else\nfloat normalScale=1.0;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#elif defined(GEOMETRY_NORMAL)\nvec2 TBNUV=gl_FrontFacing ? vGeometryNormalUV : -vGeometryNormalUV;mat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,TBNUV,vTangentSpaceParams);\n#elif defined(GEOMETRY_COAT_NORMAL)\nvec2 TBNUV=gl_FrontFacing ? vGeometryCoatNormalUV : -vGeometryCoatNormalUV;mat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,TBNUV,vTangentSpaceParams);\n#else\nvec2 TBNUV=gl_FrontFacing ? vDetailUV : -vDetailUV;mat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,TBNUV,vec2(1.,1.));\n#endif\n#elif defined(ANISOTROPIC) || defined(FUZZ)\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#else\nvec2 TBNUV=gl_FrontFacing ? vMainUV1 : -vMainUV1;mat3 TBN=cotangent_frame(normalW,vPositionW,TBNUV,vec2(1.,1.));\n#endif\n#endif\n#ifdef PARALLAX\nmat3 invTBN=transposeMat3(TBN);\n#ifdef PARALLAXOCCLUSION\n#else\n#endif\n#endif\n#ifdef DETAIL\nvec4 detailColor=texture2D(detailSampler,vDetailUV+uvOffset);vec2 detailNormalRG=detailColor.wy*2.0-1.0;float detailNormalB=sqrt(1.-saturate(dot(detailNormalRG,detailNormalRG)));vec3 detailNormal=vec3(detailNormalRG,detailNormalB);\n#endif\n#ifdef GEOMETRY_COAT_NORMAL\ncoatNormalW=perturbNormal(TBN,TEXRD(geometryCoatNormalSampler,vGeometryCoatNormalUV+uvOffset).xyz,vGeometryCoatNormalInfos.y);\n#endif\n#ifdef GEOMETRY_NORMAL\n#ifdef OBJECTSPACE_NORMALMAP\n#define CUSTOM_FRAGMENT_BUMP_FRAGMENT\nnormalW=normalize(TEXRD(geometryNormalSampler,vGeometryNormalUV).xyz *2.0-1.0);normalW=normalize(mat3(normalMatrix)*normalW);\n#elif !defined(DETAIL)\nnormalW=perturbNormal(TBN,TEXRD(geometryNormalSampler,vGeometryNormalUV+uvOffset).xyz,vGeometryNormalInfos.y);\n#else\nvec3 sampledNormal=TEXRD(geometryNormalSampler,vGeometryNormalUV+uvOffset).xyz*2.0-1.0;\n#if DETAIL_NORMALBLENDMETHOD==0 \ndetailNormal.xy*=vDetailInfos.z;vec3 blendedNormal=normalize(vec3(sampledNormal.xy+detailNormal.xy,sampledNormal.z*detailNormal.z));\n#elif DETAIL_NORMALBLENDMETHOD==1 \ndetailNormal.xy*=vDetailInfos.z;sampledNormal+=vec3(0.0,0.0,1.0);detailNormal*=vec3(-1.0,-1.0,1.0);vec3 blendedNormal=sampledNormal*dot(sampledNormal,detailNormal)/sampledNormal.z-detailNormal;\n#endif\nnormalW=perturbNormalBase(TBN,blendedNormal,vGeometryNormalInfos.y);\n#endif\n#elif defined(DETAIL)\ndetailNormal.xy*=vDetailInfos.z;normalW=perturbNormalBase(TBN,detailNormal,vDetailInfos.z);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrNormalMapFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBlockNormalFinal\";\nconst shader = `#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nvec3 faceNormal=normalize(cross(dFdx(vPositionW),dFdy(vPositionW)))*vEyePosition.w;\n#if defined(TWOSIDEDLIGHTING)\nfaceNormal=gl_FrontFacing ? faceNormal : -faceNormal;\n#endif\nnormalW*=sign(dot(normalW,faceNormal));coatNormalW*=sign(dot(coatNormalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\n#if defined(MIRRORED)\nnormalW=gl_FrontFacing ? -normalW : normalW;coatNormalW=gl_FrontFacing ? -coatNormalW : coatNormalW;\n#else\nnormalW=gl_FrontFacing ? normalW : -normalW;coatNormalW=gl_FrontFacing ? coatNormalW : -coatNormalW;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrBlockNormalFinal = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBaseLayerData\";\nconst shader = `vec3 base_color=vec3(0.8);float base_metalness=0.0;float base_diffuse_roughness=0.0;float specular_weight=1.0;float specular_roughness=0.3;vec3 specular_color=vec3(1.0);float specular_roughness_anisotropy=0.0;float specular_ior=1.5;float alpha=1.0;vec2 geometry_tangent=vec2(1.0,0.0);float geometry_thickness=0.0;\n#ifdef BASE_WEIGHT\nvec4 baseWeightFromTexture=TEXRD(baseWeightSampler,vBaseWeightUV+uvOffset);\n#endif\n#ifdef BASE_COLOR\nvec4 baseColorFromTexture=TEXRD(baseColorSampler,vBaseColorUV+uvOffset);\n#endif\n#ifdef BASE_METALNESS\nvec4 metallicFromTexture=TEXRD(baseMetalnessSampler,vBaseMetalnessUV+uvOffset);\n#endif\n#if defined(SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN) && defined(BASE_METALNESS)\nfloat roughnessFromTexture=metallicFromTexture.g;\n#elif defined(SPECULAR_ROUGHNESS)\nfloat roughnessFromTexture=TEXRD(specularRoughnessSampler,vSpecularRoughnessUV+uvOffset).r;\n#endif\n#ifdef GEOMETRY_TANGENT\nvec3 geometryTangentFromTexture=TEXRD(geometryTangentSampler,vGeometryTangentUV+uvOffset).rgb;\n#endif\n#ifdef SPECULAR_ROUGHNESS_ANISOTROPY\nfloat anisotropyFromTexture=TEXRD(specularRoughnessAnisotropySampler,vSpecularRoughnessAnisotropyUV+uvOffset).r*vSpecularRoughnessAnisotropyInfos.y;\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nfloat baseDiffuseRoughnessFromTexture=TEXRD(baseDiffuseRoughnessSampler,vBaseDiffuseRoughnessUV+uvOffset).r;\n#endif\n#ifdef GEOMETRY_OPACITY\nvec4 opacityFromTexture=TEXRD(geometryOpacitySampler,vGeometryOpacityUV+uvOffset);\n#endif\n#ifdef GEOMETRY_THICKNESS\nvec4 thicknessFromTexture=TEXRD(geometryThicknessSampler,vGeometryThicknessUV+uvOffset);\n#endif\n#ifdef DECAL\nvec4 decalFromTexture=texture2D(decalSampler,vDecalUV+uvOffset);\n#endif\n#ifdef SPECULAR_COLOR\nvec4 specularColorFromTexture=TEXRD(specularColorSampler,vSpecularColorUV+uvOffset);\n#endif\n#ifdef SPECULAR_WEIGHT\n#ifdef SPECULAR_WEIGHT_IN_ALPHA\nfloat specularWeightFromTexture=TEXRD(specularWeightSampler,vSpecularWeightUV+uvOffset).a;\n#else\nfloat specularWeightFromTexture=TEXRD(specularWeightSampler,vSpecularWeightUV+uvOffset).r;\n#endif\n#endif\n#if defined(ANISOTROPIC) || defined(FUZZ) || defined(REFRACTED_BACKGROUND) || defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING)\nvec3 noise=vec3(2.0)*TEXRD(blueNoiseSampler,gl_FragCoord.xy/256.0).xyz-vec3(1.0);\n#endif\nbase_color=vBaseColor.rgb;\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nbase_color*=vColor.rgb;\n#endif\n#if defined(VERTEXALPHA) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nalpha*=vColor.a;\n#endif\nbase_color*=vec3(vBaseWeight);alpha=vBaseColor.a;base_metalness=vReflectanceInfo.x;base_diffuse_roughness=vBaseDiffuseRoughness;specular_roughness=vReflectanceInfo.y;specular_color=vSpecularColor.rgb;specular_weight=vReflectanceInfo.a;specular_ior=vReflectanceInfo.z;specular_roughness_anisotropy=vSpecularAnisotropy.b;geometry_tangent=vSpecularAnisotropy.rg;geometry_thickness=vGeometryThickness;\n#ifdef BASE_COLOR\n#ifdef BASE_COLOR_GAMMA\nbase_color*=toLinearSpace(baseColorFromTexture.rgb);\n#else\nbase_color*=baseColorFromTexture.rgb;\n#endif\nbase_color*=vBaseColorInfos.y;\n#endif\n#ifdef BASE_WEIGHT\nbase_color*=baseWeightFromTexture.r;\n#endif\n#if defined(BASE_COLOR) && defined(ALPHA_FROM_BASE_COLOR_TEXTURE)\nalpha*=baseColorFromTexture.a;\n#elif defined(GEOMETRY_OPACITY)\nalpha*=opacityFromTexture.r;alpha*=vGeometryOpacityInfos.y;\n#endif\n#ifdef GEOMETRY_THICKNESS\n#ifdef GEOMETRY_THICKNESS_FROM_GREEN_CHANNEL\ngeometry_thickness*=thicknessFromTexture.g;\n#else\ngeometry_thickness*=thicknessFromTexture.r;\n#endif\ngeometry_thickness*=vGeometryThicknessInfos.y;\n#endif\n#ifdef ALPHATEST\n#if DEBUGMODE != 88\nif (alpha<ALPHATESTVALUE)\ndiscard;\n#endif\n#ifndef ALPHABLEND\nalpha=1.0;\n#endif\n#endif\n#ifdef BASE_METALNESS\n#ifdef BASE_METALNESS_FROM_METALNESS_TEXTURE_BLUE\nbase_metalness*=metallicFromTexture.b;\n#else\nbase_metalness*=metallicFromTexture.r;\n#endif\n#endif\n#ifdef BASE_DIFFUSE_ROUGHNESS\nbase_diffuse_roughness*=baseDiffuseRoughnessFromTexture*vBaseDiffuseRoughnessInfos.y;\n#endif\n#ifdef SPECULAR_COLOR\n#ifdef SPECULAR_COLOR_GAMMA\nspecular_color*=toLinearSpace(specularColorFromTexture.rgb);\n#else\nspecular_color*=specularColorFromTexture.rgb;\n#endif\n#ifdef SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE\nspecular_weight*=specularColorFromTexture.a;\n#elif defined(SPECULAR_WEIGHT)\nspecular_weight*=specularWeightFromTexture;\n#endif\n#endif\n#if defined(SPECULAR_ROUGHNESS) || (defined(SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN) && defined(BASE_METALNESS))\nspecular_roughness*=roughnessFromTexture;\n#endif\n#ifdef GEOMETRY_TANGENT\n{vec2 tangentFromTexture=normalize(geometryTangentFromTexture.xy*2.0-1.0);float tangent_angle_texture=atan(tangentFromTexture.y,tangentFromTexture.x);float tangent_angle_uniform=atan(geometry_tangent.y,geometry_tangent.x);float tangent_angle=tangent_angle_texture+tangent_angle_uniform;geometry_tangent=vec2(cos(tangent_angle),sin(tangent_angle));}\n#endif\n#if defined(GEOMETRY_TANGENT) && \\\ndefined(SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE)\nspecular_roughness_anisotropy*=geometryTangentFromTexture.b;\n#elif defined(SPECULAR_ROUGHNESS_ANISOTROPY)\nspecular_roughness_anisotropy*=anisotropyFromTexture;\n#endif\n#ifdef DETAIL\nfloat detailRoughness=mix(0.5,detailColor.b,vDetailInfos.w);float loLerp=mix(0.,specular_roughness,detailRoughness*2.);float hiLerp=mix(specular_roughness,1.,(detailRoughness-0.5)*2.);specular_roughness=mix(loLerp,hiLerp,step(detailRoughness,0.5));\n#endif\n#ifdef USE_GLTF_STYLE_ANISOTROPY\nfloat baseAlpha=specular_roughness*specular_roughness;float roughnessT=mix(baseAlpha,1.0,specular_roughness_anisotropy*specular_roughness_anisotropy);float roughnessB=baseAlpha;specular_roughness_anisotropy=1.0-roughnessB/max(roughnessT,0.00001);specular_roughness=sqrt(roughnessT/sqrt(2.0/(1.0+(1.0-specular_roughness_anisotropy)*(1.0-specular_roughness_anisotropy))));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrBaseLayerData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrTransmissionLayerData\";\nconst shader = `float transmission_weight=vTransmissionWeight;vec3 transmission_color=vTransmissionColor.rgb;float transmission_depth=vTransmissionDepth;vec3 transmission_scatter=vTransmissionScatter.rgb;float transmission_scatter_anisotropy=clamp(vTransmissionScatterAnisotropy,-0.9999,0.9999);float transmission_dispersion_scale=vTransmissionDispersionScale;float transmission_dispersion_abbe_number=vTransmissionDispersionAbbeNumber;\n#ifdef TRANSMISSION_WEIGHT\nvec4 transmissionWeightFromTexture=TEXRD(transmissionWeightSampler,vTransmissionWeightUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_COLOR\nvec4 transmissionColorFromTexture=TEXRD(transmissionColorSampler,vTransmissionColorUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_DEPTH\nvec4 transmissionDepthFromTexture=TEXRD(transmissionDepthSampler,vTransmissionDepthUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_SCATTER\nvec4 transmissionScatterFromTexture=TEXRD(transmissionScatterSampler,vTransmissionScatterUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_DISPERSION_SCALE\nvec4 transmissionDispersionScaleFromTexture=TEXRD(transmissionDispersionScaleSampler,vTransmissionDispersionScaleUV+uvOffset);\n#endif\n#ifdef TRANSMISSION_WEIGHT\ntransmission_weight*=transmissionWeightFromTexture.r;\n#endif\n#ifdef TRANSMISSION_COLOR\n#ifdef TRANSMISSION_COLOR_GAMMA\ntransmission_color*=toLinearSpace(transmissionColorFromTexture.rgb);\n#else\ntransmission_color*=transmissionColorFromTexture.rgb;\n#endif\ntransmission_color*=vTransmissionColorInfos.y;\n#endif\n#ifdef TRANSMISSION_DEPTH\ntransmission_depth*=transmissionDepthFromTexture.r;\n#endif\n#ifdef TRANSMISSION_SCATTER\ntransmission_scatter*=transmissionScatterFromTexture.rgb;\n#endif\n#ifdef TRANSMISSION_DISPERSION_SCALE\ntransmission_dispersion_scale*=transmissionDispersionScaleFromTexture.r;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrTransmissionLayerData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrSubsurfaceLayerData\";\nconst shader = `float subsurface_weight=vSubsurfaceWeight;vec3 subsurface_color=vSubsurfaceColor.rgb;float subsurface_radius=vSubsurfaceRadius;vec3 subsurface_radius_scale=vSubsurfaceRadiusScale;float subsurface_scatter_anisotropy=clamp(vSubsurfaceScatterAnisotropy,-0.9999,0.9999);\n#ifdef SUBSURFACE_WEIGHT\nvec4 subsurfaceWeightFromTexture=TEXRD(subsurfaceWeightSampler,vSubsurfaceWeightUV+uvOffset);\n#endif\n#ifdef SUBSURFACE_COLOR\nvec4 subsurfaceColorFromTexture=TEXRD(subsurfaceColorSampler,vSubsurfaceColorUV+uvOffset);\n#endif\n#ifdef SUBSURFACE_RADIUS_SCALE\nvec4 subsurfaceRadiusScaleFromTexture=TEXRD(subsurfaceRadiusScaleSampler,vSubsurfaceRadiusScaleUV+uvOffset);\n#endif\n#ifdef SUBSURFACE_WEIGHT\n#ifdef SUBSURFACE_WEIGHT_FROM_TEXTURE_ALPHA\nsubsurface_weight*=subsurfaceWeightFromTexture.a;\n#else\nsubsurface_weight*=subsurfaceWeightFromTexture.r;\n#endif\n#endif\n#ifdef SUBSURFACE_COLOR\n#ifdef SUBSURFACE_COLOR_GAMMA\nsubsurface_color*=toLinearSpace(subsurfaceColorFromTexture.rgb);\n#else\nsubsurface_color*=subsurfaceColorFromTexture.rgb;\n#endif\nsubsurface_color*=vSubsurfaceColorInfos.y;\n#endif\n#ifdef SUBSURFACE_RADIUS_SCALE\nsubsurface_radius_scale*=subsurfaceRadiusScaleFromTexture.rgb;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrSubsurfaceLayerData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrCoatLayerData\";\nconst shader = `float coat_weight=0.0;vec3 coat_color=vec3(1.0);float coat_roughness=0.0;float coat_roughness_anisotropy=0.0;float coat_ior=1.6;float coat_darkening=1.0;vec2 geometry_coat_tangent=vec2(1.0,0.0);\n#ifdef COAT_WEIGHT\nvec4 coatWeightFromTexture=TEXRD(coatWeightSampler,vCoatWeightUV+uvOffset);\n#endif\n#ifdef COAT_COLOR\nvec4 coatColorFromTexture=TEXRD(coatColorSampler,vCoatColorUV+uvOffset);\n#endif\n#ifdef COAT_ROUGHNESS\nvec4 coatRoughnessFromTexture=TEXRD(coatRoughnessSampler,vCoatRoughnessUV+uvOffset);\n#endif\n#ifdef COAT_ROUGHNESS_ANISOTROPY\nfloat coatRoughnessAnisotropyFromTexture=TEXRD(coatRoughnessAnisotropySampler,vCoatRoughnessAnisotropyUV+uvOffset).r;\n#endif\n#ifdef COAT_DARKENING\nvec4 coatDarkeningFromTexture=TEXRD(coatDarkeningSampler,vCoatDarkeningUV+uvOffset);\n#endif\n#ifdef GEOMETRY_COAT_TANGENT\nvec3 geometryCoatTangentFromTexture=TEXRD(geometryCoatTangentSampler,vGeometryCoatTangentUV+uvOffset).rgb;\n#endif\ncoat_color=vCoatColor.rgb;coat_weight=vCoatWeight;coat_roughness=vCoatRoughness;coat_roughness_anisotropy=vCoatRoughnessAnisotropy;coat_ior=vCoatIor;coat_darkening=vCoatDarkening;geometry_coat_tangent=vGeometryCoatTangent.rg;\n#ifdef COAT_WEIGHT\ncoat_weight*=coatWeightFromTexture.r;\n#endif\n#ifdef COAT_COLOR\n#ifdef COAT_COLOR_GAMMA\ncoat_color*=toLinearSpace(coatColorFromTexture.rgb);\n#else\ncoat_color*=coatColorFromTexture.rgb;\n#endif\ncoat_color*=vCoatColorInfos.y;\n#endif\n#ifdef COAT_ROUGHNESS\n#ifdef COAT_ROUGHNESS_FROM_GREEN_CHANNEL\ncoat_roughness*=coatRoughnessFromTexture.g;\n#else\ncoat_roughness*=coatRoughnessFromTexture.r;\n#endif\n#endif\n#if defined(GEOMETRY_COAT_TANGENT) && defined(COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE)\ncoat_roughness_anisotropy*=geometryCoatTangentFromTexture.b;\n#elif defined(COAT_ROUGHNESS_ANISOTROPY)\ncoat_roughness_anisotropy*=coatRoughnessAnisotropyFromTexture;\n#endif\n#ifdef COAT_DARKENING\ncoat_darkening*=coatDarkeningFromTexture.r;\n#endif\n#ifdef GEOMETRY_COAT_TANGENT\n{vec2 tangentFromTexture=normalize(geometryCoatTangentFromTexture.xy*2.0-1.0);float tangent_angle_texture=atan(tangentFromTexture.y,tangentFromTexture.x);float tangent_angle_uniform=atan(geometry_coat_tangent.y,geometry_coat_tangent.x);float tangent_angle=tangent_angle_texture+tangent_angle_uniform;geometry_coat_tangent=vec2(cos(tangent_angle),sin(tangent_angle));}\n#endif\n#ifdef USE_GLTF_STYLE_ANISOTROPY\nfloat coatAlpha=coat_roughness*coat_roughness;float coatRoughnessT=mix(coatAlpha,1.0,coat_roughness_anisotropy*coat_roughness_anisotropy);float coatRoughnessB=coatAlpha;coat_roughness_anisotropy=1.0-coatRoughnessB/max(coatRoughnessT,0.00001);coat_roughness=sqrt(coatRoughnessT/sqrt(2.0/(1.0+(1.0-coat_roughness_anisotropy)*(1.0-coat_roughness_anisotropy))));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrCoatLayerData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrThinFilmLayerData\";\nconst shader = `#ifdef THIN_FILM\nfloat thin_film_weight=vThinFilmWeight;float thin_film_thickness=vThinFilmThickness.r*1000.0; \nfloat thin_film_ior=vThinFilmIor;\n#ifdef THIN_FILM_WEIGHT\nfloat thinFilmWeightFromTexture=TEXRD(thinFilmWeightSampler,vThinFilmWeightUV+uvOffset).r*vThinFilmWeightInfos.y;\n#endif\n#ifdef THIN_FILM_THICKNESS\nfloat thinFilmThicknessFromTexture=TEXRD(thinFilmThicknessSampler,vThinFilmThicknessUV+uvOffset).g*vThinFilmThicknessInfos.y;\n#endif\n#ifdef THIN_FILM_WEIGHT\nthin_film_weight*=thinFilmWeightFromTexture;\n#endif\n#ifdef THIN_FILM_THICKNESS\nthin_film_thickness*=thinFilmThicknessFromTexture;\n#endif\nfloat thin_film_ior_scale=clamp(2.0f*abs(thin_film_ior-1.0f),0.0f,1.0f);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrThinFilmLayerData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrFuzzLayerData\";\nconst shader = `float fuzz_weight=0.0;vec3 fuzz_color=vec3(1.0);float fuzz_roughness=0.0;\n#ifdef FUZZ\n#ifdef FUZZ_WEIGHT\nvec4 fuzzWeightFromTexture=TEXRD(fuzzWeightSampler,vFuzzWeightUV+uvOffset);\n#endif\n#ifdef FUZZ_COLOR\nvec4 fuzzColorFromTexture=TEXRD(fuzzColorSampler,vFuzzColorUV+uvOffset);\n#endif\n#ifdef FUZZ_ROUGHNESS\nvec4 fuzzRoughnessFromTexture=TEXRD(fuzzRoughnessSampler,vFuzzRoughnessUV+uvOffset);\n#endif\nfuzz_color=vFuzzColor.rgb;fuzz_weight=vFuzzWeight;fuzz_roughness=vFuzzRoughness;\n#ifdef FUZZ_WEIGHT\nfuzz_weight*=fuzzWeightFromTexture.r;\n#endif\n#ifdef FUZZ_COLOR\n#ifdef FUZZ_COLOR_GAMMA\nfuzz_color*=toLinearSpace(fuzzColorFromTexture.rgb);\n#else\nfuzz_color*=fuzzColorFromTexture.rgb;\n#endif\nfuzz_color*=vFuzzColorInfos.y;\n#endif\n#if defined(FUZZ_ROUGHNESS) && defined(FUZZ_ROUGHNESS_FROM_TEXTURE_ALPHA)\nfuzz_roughness*=fuzzRoughnessFromTexture.a;\n#elif defined(FUZZ_ROUGHNESS)\nfuzz_roughness*=fuzzRoughnessFromTexture.r;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrFuzzLayerData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrAmbientOcclusionData\";\nconst shader = `vec3 ambient_occlusion=vec3(1.0);float specular_ambient_occlusion=1.0;float coat_specular_ambient_occlusion=1.0;\n#ifdef AMBIENT_OCCLUSION\nvec3 ambientOcclusionFromTexture=TEXRD(ambientOcclusionSampler,vAmbientOcclusionUV+uvOffset).rgb;ambient_occlusion=vec3(ambientOcclusionFromTexture.r*vAmbientOcclusionInfos.y+(1.0-vAmbientOcclusionInfos.y));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrAmbientOcclusionData = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBackgroundTransmission\";\nconst shader = `vec4 slab_translucent_background=vec4(0.,0.,0.,1.);\n#ifdef REFRACTED_BACKGROUND\n{float refractionLOD=min(transmission_roughness,0.8)*vBackgroundRefractionInfos.x;float lodTexelSize=pow(2.0,refractionLOD-vBackgroundRefractionInfos.x);\n#ifdef DISPERSION\n{\n#ifdef REFRACTION_HIGH_QUALITY_BLUR\n{vec3 dispResult=vec3(0.0);vec3 dispWeight=vec3(0.0);vec2 noiseOffset=noise.xy*(refractionLOD>0.0 ? lodTexelSize : 0.0);for (int k=0; k<6; k++) {float t=(float(k)+noise.y)/6.0;float t_rg=clamp(t*2.0,0.0,1.0);float t_gb=clamp((t-0.5)*2.0,0.0,1.0);vec3 refVec=mix(mix(refractedViewVectors[0],refractedViewVectors[1],t_rg),refractedViewVectors[2],t_gb);vec3 uvw=vec3(backgroundRefractionMatrix*(view*vec4(vPositionW+refVec*geometry_thickness,1.0)));vec2 coords=uvw.xy/uvw.z;coords.y=1.0-coords.y;vec4 s=texture2DLodEXT(backgroundRefractionSampler,coords+noiseOffset,refractionLOD);float rw=max(0.0,1.0-2.0*t);float gw=max(0.0,1.0-abs(2.0*t-1.0));float bw=max(0.0,2.0*t-1.0);vec3 w=vec3(rw,gw,bw);dispResult+=s.rgb*w;dispWeight+=w;}\nslab_translucent_background=vec4(dispResult/max(dispWeight,vec3(1e-6)),1.0);}\n#else\nfor (int i=0; i<3; i++) {vec3 refractedViewVector=refractedViewVectors[i];vec3 uvw=vec3(backgroundRefractionMatrix*(view*vec4(vPositionW+refractedViewVector*geometry_thickness,1.0)));vec2 coords=uvw.xy/uvw.z;coords.y=1.0-coords.y;if (refractionLOD>0.0) {vec2 noiseOffset=noise.xy*lodTexelSize;slab_translucent_background[i]=texture2DLodEXT(backgroundRefractionSampler,coords+noiseOffset,refractionLOD)[i];} else {slab_translucent_background[i]=texture2DLodEXT(backgroundRefractionSampler,coords,0.0)[i];}}\n#endif\n}\n#else\n{vec3 refractionUVW=vec3(backgroundRefractionMatrix*(view*vec4(vPositionW+refractedViewVector*geometry_thickness,1.0)));vec2 refractionCoords=refractionUVW.xy/refractionUVW.z;refractionCoords.y=1.0-refractionCoords.y;if (refractionLOD>0.0) {\n#ifdef REFRACTION_HIGH_QUALITY_BLUR\nfloat cosA=cos(noise.x*PI);float sinA=sin(noise.x*PI);vec2 u=vec2( cosA,sinA)*(0.5*lodTexelSize);vec2 v=vec2(-sinA,cosA)*(0.5*lodTexelSize);slab_translucent_background=0.25*(\ntexture2DLodEXT(backgroundRefractionSampler,refractionCoords+u+v,refractionLOD) +\ntexture2DLodEXT(backgroundRefractionSampler,refractionCoords-u+v,refractionLOD) +\ntexture2DLodEXT(backgroundRefractionSampler,refractionCoords+u-v,refractionLOD) +\ntexture2DLodEXT(backgroundRefractionSampler,refractionCoords-u-v,refractionLOD)\n);\n#else\nvec2 noiseOffset=noise.xy*lodTexelSize;slab_translucent_background=texture2DLodEXT(backgroundRefractionSampler,refractionCoords+noiseOffset,refractionLOD);\n#endif\n} else {slab_translucent_background=texture2DLodEXT(backgroundRefractionSampler,refractionCoords,0.0);}}\n#endif\n}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrBackgroundTransmission = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrEnvironmentLighting\";\nconst shader = `#if defined(REFLECTION) || defined(REFRACTED_BACKGROUND)\nvec3 coatAbsorption=vec3(1.0);float coatIblFresnel=0.0;if (coat_weight>0.0) {coatIblFresnel=computeDielectricIblFresnel(coatReflectance,coatGeoInfo.environmentBrdf);float hemisphere_avg_fresnel=coatReflectance.F0+0.5*(1.0-coatReflectance.F0);float averageReflectance=(coatIblFresnel+hemisphere_avg_fresnel)*0.5;float roughnessFactor=1.0-coat_roughness*0.5;averageReflectance*=roughnessFactor;float darkened_transmission=(1.0-averageReflectance)*(1.0-averageReflectance);darkened_transmission=mix(1.0,darkened_transmission,coat_darkening);float sin2=1.0-coatGeoInfo.NdotV*coatGeoInfo.NdotV;sin2=sin2/(coat_ior*coat_ior)*coat_weight;float cos_t=sqrt(1.0-sin2);float coatPathLength=1.0/cos_t;float effectivePathLength=coatPathLength*coat_weight;vec3 colored_transmission=pow(coat_color,vec3(effectivePathLength));coatAbsorption=colored_transmission*mix(1.0,darkened_transmission,coat_weight);}\n#endif\n#ifdef REFLECTION\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nvec3 environmentFuzzBrdf=getFuzzBRDFLookup(fuzzGeoInfo.NdotV,sqrt(fuzz_roughness));\n#endif\nvec3 baseDiffuseEnvironmentLight=sampleIrradiance(\nnormalW\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n#endif\n,vReflectionInfos\n,viewDirectionW\n,base_diffuse_roughness\n,base_color\n);\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=vec3(0.,0.,0.);\n#else\nvec2 reflectionCoords=vec2(0.,0.);\n#endif\nfloat specularAlphaG=specular_roughness*specular_roughness;\n#ifdef ANISOTROPIC_BASE\nvec3 baseSpecularEnvironmentLight=sampleRadianceAnisotropic(specularAlphaG,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,baseGeoInfo\n,normalW\n,viewDirectionW\n,vPositionW\n,noise\n,false \n,1.0 \n,reflectionSampler\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);\n#else\nreflectionCoords=createReflectionCoords(vPositionW,normalW);vec3 baseSpecularEnvironmentLight=sampleRadiance(specularAlphaG,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,baseGeoInfo\n,reflectionSampler\n,reflectionCoords\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);\n#endif\n#ifdef ANISOTROPIC_BASE\nbaseSpecularEnvironmentLight=mix(baseSpecularEnvironmentLight.rgb,baseDiffuseEnvironmentLight,specularAlphaG*specularAlphaG*max(1.0-baseGeoInfo.anisotropy,0.3));\n#else\nbaseSpecularEnvironmentLight=mix(baseSpecularEnvironmentLight.rgb,baseDiffuseEnvironmentLight,specularAlphaG);\n#endif\nvec3 coatEnvironmentLight=vec3(0.,0.,0.);if (coat_weight>0.0) {\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=vec3(0.,0.,0.);\n#else\nvec2 reflectionCoords=vec2(0.,0.);\n#endif\nreflectionCoords=createReflectionCoords(vPositionW,coatNormalW);float coatAlphaG=coat_roughness*coat_roughness;\n#ifdef ANISOTROPIC_COAT\ncoatEnvironmentLight=sampleRadianceAnisotropic(coatAlphaG,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,coatGeoInfo\n,coatNormalW\n,viewDirectionW\n,vPositionW\n,noise\n,false \n,1.0 \n,reflectionSampler\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);\n#else\ncoatEnvironmentLight=sampleRadiance(coatAlphaG,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,coatGeoInfo\n,reflectionSampler\n,reflectionCoords\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);\n#endif\n}\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nfloat modifiedFuzzRoughness=clamp(fuzz_roughness*fuzz_roughness*(1.0+0.5*environmentFuzzBrdf.y),0.0,1.0);vec3 fuzzEnvironmentLight=vec3(0.0);float fuzzIblFresnel=min(environmentFuzzBrdf.z*2.0,1.0);vec2 viewTangent=vec2(dot(viewDirectionW,fuzzTangent),dot(viewDirectionW,fuzzBitangent));float centerAngle=atan(viewTangent.y,viewTangent.x);for (int i=0; i<FUZZ_IBL_SAMPLES; ++i) {float angle=centerAngle+(float(i)/float(FUZZ_IBL_SAMPLES)-0.5+noise.x/float(FUZZ_IBL_SAMPLES))*3.141592;vec3 fiberCylinderNormal=normalize(cos(angle)*fuzzTangent+sin(angle)*fuzzBitangent);vec3 fuzzReflectionCoords=vec3(reflectionMatrix*vec4(fiberCylinderNormal,0));vec3 radianceSample=sampleRadiance(modifiedFuzzRoughness,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,fuzzGeoInfo\n,reflectionSampler\n,fuzzReflectionCoords\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);fuzzEnvironmentLight+=radianceSample;}\nfuzzEnvironmentLight/=float(FUZZ_IBL_SAMPLES);\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL)\nvec3 fuzzDiffuseEnvironmentLight=sampleIrradiance(\nfuzzNormalW\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n#endif\n,vReflectionInfos\n,viewDirectionW\n,0.0\n,vec3(1.0)\n);\n#else\nvec3 fuzzDiffuseEnvironmentLight=baseDiffuseEnvironmentLight;\n#endif\nfuzzEnvironmentLight=mix(min(fuzzEnvironmentLight,fuzzDiffuseEnvironmentLight),fuzzDiffuseEnvironmentLight,modifiedFuzzRoughness);\n#endif\nfloat dielectricIblFresnel=computeDielectricIblFresnel(baseDielectricReflectance,baseGeoInfo.environmentBrdf);vec3 dielectricIblColoredFresnel=dielectricIblFresnel*specular_color;\n#ifdef THIN_FILM\nfloat thin_film_cos_theta=max(baseGeoInfo.NdotV,specularAlphaG);float thin_film_desaturation_scale=(thin_film_ior-1.0)*sqrt(thin_film_thickness*0.001*thin_film_cos_theta);float tf_brdf_x=baseGeoInfo.environmentBrdf.x;float tf_E_ss =baseGeoInfo.environmentBrdf.y;vec3 thinFilmDielectricF0=evalIridescence(thin_film_outside_ior,thin_film_ior,1.0,thin_film_thickness,vec3(baseDielectricReflectance.F0));thinFilmDielectricF0=mix(thinFilmDielectricF0,vec3(dot(thinFilmDielectricF0,vec3(0.3333))),thin_film_desaturation_scale);vec3 thinFilmDielectricDir=evalIridescence(thin_film_outside_ior,thin_film_ior,thin_film_cos_theta,thin_film_thickness,vec3(baseDielectricReflectance.F0));thinFilmDielectricDir=mix(thinFilmDielectricDir,vec3(dot(thinFilmDielectricDir,vec3(0.3333))),thin_film_desaturation_scale);float tf_f0d_avg =dot(thinFilmDielectricF0, vec3(0.3333));float tf_dird_avg=dot(thinFilmDielectricDir,vec3(0.3333));vec3 thinFilmDielectricFresnel=thinFilmDielectricDir*(tf_f0d_avg/max(tf_dird_avg,1e-5));vec3 tf_E_dielectric=(vec3(1.0)-thinFilmDielectricFresnel)*vec3(tf_brdf_x)+thinFilmDielectricFresnel*vec3(tf_E_ss);vec3 tf_F_avg_dielectric=thinFilmDielectricFresnel+(vec3(1.0)-thinFilmDielectricFresnel)/21.0;vec3 tf_ECF_dielectric=vec3(1.0)+tf_F_avg_dielectric*(vec3(1.0)/vec3(tf_E_ss)-vec3(1.0));thinFilmDielectricFresnel=clamp(tf_E_dielectric*tf_ECF_dielectric,vec3(0.0),vec3(1.0));dielectricIblColoredFresnel=mix(dielectricIblColoredFresnel,thinFilmDielectricFresnel*specular_color,thin_film_weight*thin_film_ior_scale);dielectricIblFresnel=max(dielectricIblColoredFresnel.r,max(dielectricIblColoredFresnel.g,dielectricIblColoredFresnel.b));\n#endif\nvec3 conductorIblFresnel=computeConductorIblFresnel(baseConductorReflectance,baseGeoInfo.environmentBrdf);\n#ifdef THIN_FILM\nvec3 thinFilmConductorF0=evalIridescence(thin_film_outside_ior,thin_film_ior,1.0,thin_film_thickness,baseConductorReflectance.coloredF0);thinFilmConductorF0=mix(thinFilmConductorF0,vec3(dot(thinFilmConductorF0,vec3(0.3333))),thin_film_desaturation_scale);vec3 thinFilmConductorDir=evalIridescence(thin_film_outside_ior,thin_film_ior,thin_film_cos_theta,thin_film_thickness,baseConductorReflectance.coloredF0);thinFilmConductorDir=mix(thinFilmConductorDir,vec3(dot(thinFilmConductorDir,vec3(0.3333))),thin_film_desaturation_scale);float tf_f0c_avg =dot(thinFilmConductorF0, vec3(0.3333));float tf_dirc_avg=dot(thinFilmConductorDir,vec3(0.3333));vec3 thinFilmConductorRaw=thinFilmConductorDir*(tf_f0c_avg/max(tf_dirc_avg,1e-5));\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR) && defined(ENVIRONMENTBRDF)\nvec3 tf_b=getF82B(baseConductorReflectance.coloredF0,baseConductorReflectance.coloredF90);float tf_brdf_z=baseGeoInfo.environmentBrdf.z/BRDF_Z_SCALE;vec3 tf_E_conductor=(vec3(1.0)-thinFilmConductorRaw)*vec3(tf_brdf_x)+thinFilmConductorRaw*vec3(tf_E_ss)-tf_b*vec3(tf_brdf_z);vec3 tf_F_avg_conductor=thinFilmConductorRaw+(vec3(1.0)-thinFilmConductorRaw)/21.0-tf_b/126.0;\n#else\nvec3 tf_E_conductor=(vec3(1.0)-thinFilmConductorRaw)*vec3(tf_brdf_x)+thinFilmConductorRaw*vec3(tf_E_ss);vec3 tf_F_avg_conductor=thinFilmConductorRaw+(vec3(1.0)-thinFilmConductorRaw)/21.0;\n#endif\nvec3 tf_ECF_conductor=vec3(1.0)+tf_F_avg_conductor*(vec3(1.0)/vec3(tf_E_ss)-vec3(1.0));vec3 thinFilmConductorFresnel=specular_weight*clamp(tf_E_conductor*tf_ECF_conductor,vec3(0.0),vec3(1.0));conductorIblFresnel=mix(conductorIblFresnel,thinFilmConductorFresnel,thin_film_weight*thin_film_ior_scale);\n#endif\nvec3 slab_diffuse_ibl=vec3(0.,0.,0.);vec3 slab_glossy_ibl=vec3(0.,0.,0.);vec3 slab_metal_ibl=vec3(0.,0.,0.);vec3 slab_coat_ibl=vec3(0.,0.,0.);slab_diffuse_ibl=baseDiffuseEnvironmentLight*vLightingIntensity.z;\n#ifdef AMBIENT_OCCLUSION\nspecular_ambient_occlusion=compute_specular_occlusion(baseGeoInfo.NdotV,base_metalness,ambient_occlusion.x,specular_roughness);\n#endif\nslab_glossy_ibl=baseSpecularEnvironmentLight*vLightingIntensity.z;slab_metal_ibl=baseSpecularEnvironmentLight*conductorIblFresnel*vLightingIntensity.z;if (coat_weight>0.0) {slab_coat_ibl=coatEnvironmentLight*vLightingIntensity.z;\n#ifdef AMBIENT_OCCLUSION\ncoat_specular_ambient_occlusion=compute_specular_occlusion(coatGeoInfo.NdotV,0.0,ambient_occlusion.x,coat_roughness);\n#endif\n}\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nvec3 slab_fuzz_ibl=fuzzEnvironmentLight*vLightingIntensity.z;\n#endif\nvec3 slab_translucent_base_ibl=vec3(0.0);vec3 slab_subsurface_ibl=vec3(0.,0.,0.);\n#ifdef REFRACTED_ENVIRONMENT\n#ifdef ANISOTROPIC_BASE\nvec3 forwardScatteredEnvironmentLight=sampleRadianceAnisotropic(transmission_roughness_alpha,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,baseGeoInfo\n#ifdef GEOMETRY_THIN_WALLED\n,viewDirectionW\n#else\n,normalW\n#endif\n,viewDirectionW\n,vPositionW\n,noise\n,true \n#ifdef GEOMETRY_THIN_WALLED\n,1.05 \n#else\n,specular_ior \n#endif\n,reflectionSampler\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);\n#else\nvec3 forwardScatteredEnvironmentLight=vec3(0.,0.,0.);\n#ifdef DISPERSION\nfor (int i=0; i<3; i++) {vec3 iblRefractionCoords=refractedViewVectors[i];\n#else\nvec3 iblRefractionCoords=refractedViewVector;\n#endif\n#ifdef REFRACTED_ENVIRONMENT_OPPOSITEZ\niblRefractionCoords.z*=-1.0;\n#endif\n#ifdef REFRACTED_ENVIRONMENT_LOCAL_CUBE\niblRefractionCoords=parallaxCorrectNormal(vPositionW,refractedViewVector,refractionSize,refractionPosition);\n#endif\niblRefractionCoords=vec3(reflectionMatrix*vec4(iblRefractionCoords,0));\n#ifdef DISPERSION\nforwardScatteredEnvironmentLight[i]=sampleRadiance(transmission_roughness_alpha,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,baseGeoInfo\n,reflectionSampler\n,iblRefractionCoords\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n)[i];\n#else\nforwardScatteredEnvironmentLight=sampleRadiance(transmission_roughness_alpha,vReflectionMicrosurfaceInfos.rgb,vReflectionInfos\n,baseGeoInfo\n,reflectionSampler\n,iblRefractionCoords\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#endif\n);\n#endif\n#ifdef DISPERSION\n}\n#endif\n#endif\n#ifdef REFRACTED_BACKGROUND\n#ifdef GEOMETRY_THIN_WALLED\nforwardScatteredEnvironmentLight=mix(slab_translucent_background.rgb,forwardScatteredEnvironmentLight.rgb,0.2*transmission_roughness_alpha);\n#else\nforwardScatteredEnvironmentLight=max(slab_translucent_background.rgb,mix(slab_translucent_background.rgb,forwardScatteredEnvironmentLight,transmission_roughness_alpha));\n#endif\n#endif\n#ifdef SCATTERING\n#ifdef GEOMETRY_THIN_WALLED\nvec3 scatterVector=normalW;\n#else\n#if defined(USEIRRADIANCEMAP) && defined(USE_IRRADIANCE_DOMINANT_DIRECTION)\nvec3 scatterVector=mix(vReflectionDominantDirection,normalW,max3(iso_scatter_density));\n#else\nvec3 scatterVector=normalW;\n#endif\nscatterVector=mix(viewDirectionW,scatterVector,back_to_iso_scattering_blend);\n#endif\n#if defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) && !defined(GEOMETRY_THIN_WALLED)\nvec3 scatteredEnvironmentLight=scattered_light_from_irradiance_texture;\n#else\nvec3 scatteredEnvironmentLight=sampleIrradiance(\nscatterVector\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n#endif\n,vReflectionInfos\n,viewDirectionW\n#if defined(GEOMETRY_THIN_WALLED)\n,base_diffuse_roughness\n,subsurface_color.rgb\n#else\n,1.0\n,volumeParams.multi_scatter_color\n#endif\n);\n#endif\n#ifdef GEOMETRY_THIN_WALLED\nvec3 forward_scattered_light=forwardScatteredEnvironmentLight*transmission_tint*volumeParams.multi_scatter_color;vec3 back_scattered_light=scatteredEnvironmentLight*volumeParams.multi_scatter_color;slab_translucent_base_ibl=mix(back_scattered_light,forward_scattered_light,0.5+0.5*volumeParams.anisotropy);\n#else\nvec3 forward_scattered_light=forwardScatteredEnvironmentLight*volume_absorption;vec3 back_scattered_light=mix(forward_scattered_light,scatteredEnvironmentLight*backscatter_color,iso_scatter_density);vec3 iso_scattered_light=mix(forward_scattered_light,scatteredEnvironmentLight*volumeParams.multi_scatter_color,iso_scatter_density);slab_translucent_base_ibl=mix(back_scattered_light,iso_scattered_light,back_to_iso_scattering_blend);slab_translucent_base_ibl=mix(slab_translucent_base_ibl,forward_scattered_light,iso_to_forward_scattering_blend)*transmission_tint;\n#endif\n#else\nslab_translucent_base_ibl+=forwardScatteredEnvironmentLight*transmission_tint*volume_absorption;\n#endif\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_IBLLAYERCOMPOSITION\nslab_diffuse_ibl*=ambient_occlusion;slab_metal_ibl*=specular_ambient_occlusion;slab_glossy_ibl*=specular_ambient_occlusion;slab_coat_ibl*=coat_specular_ambient_occlusion;vec3 material_dielectric_base_ibl=mix(slab_diffuse_ibl*base_color.rgb,slab_translucent_base_ibl,surface_translucency_weight);vec3 material_dielectric_gloss_ibl=material_dielectric_base_ibl*(1.0-dielectricIblFresnel)+slab_glossy_ibl*dielectricIblColoredFresnel;vec3 material_base_substrate_ibl=mix(material_dielectric_gloss_ibl,slab_metal_ibl,base_metalness);vec3 material_coated_base_ibl=layer(material_base_substrate_ibl,slab_coat_ibl,coatIblFresnel,coatAbsorption,vec3(1.0));\n#if defined(FUZZ) && defined(FUZZENVIRONMENTBRDF)\nslab_fuzz_ibl*=min(vec3(specular_ambient_occlusion),ambient_occlusion);material_surface_ibl=layer(material_coated_base_ibl,slab_fuzz_ibl,fuzzIblFresnel*fuzz_weight,vec3(1.0),fuzz_color);\n#else\nmaterial_surface_ibl=material_coated_base_ibl;\n#endif\n#elif defined(REFRACTED_BACKGROUND)\nvec3 black=vec3(0.0);vec3 slab_translucent_base_ibl=vec3(0.0);\n#ifdef GEOMETRY_THIN_WALLED\n#ifdef SCATTERING\nvec3 forward_scattered_light=slab_translucent_background.rgb*transmission_tint*volumeParams.multi_scatter_color;slab_translucent_base_ibl=mix(black,forward_scattered_light,0.5+0.5*volumeParams.anisotropy);\n#else\nslab_translucent_base_ibl=slab_translucent_background.rgb*transmission_tint;\n#endif\n#else\n#ifdef SCATTERING\nvec3 forward_scattered_light=slab_translucent_background.rgb*volume_absorption;vec3 iso_scattered_light=(1.0-iso_scatter_density)*forward_scattered_light;slab_translucent_base_ibl=mix(black,iso_scattered_light,back_to_iso_scattering_blend);slab_translucent_base_ibl=mix(slab_translucent_base_ibl,forward_scattered_light,iso_to_forward_scattering_blend)*transmission_tint;\n#else\nslab_translucent_base_ibl=slab_translucent_background.rgb*volume_absorption*transmission_tint;\n#endif\n#endif\nvec3 material_dielectric_base_ibl=mix(black,slab_translucent_base_ibl.rgb,surface_translucency_weight);vec3 material_dielectric_gloss_ibl=material_dielectric_base_ibl*(baseGeoInfo.NdotV);vec3 material_base_substrate_ibl=mix(material_dielectric_gloss_ibl,black,base_metalness);vec3 material_coated_base_ibl=layer(material_base_substrate_ibl,black,coatIblFresnel,coatAbsorption,vec3(1.0));material_surface_ibl=material_coated_base_ibl;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrEnvironmentLighting = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrDirectLightingInit\";\nconst shader = `#ifdef LIGHT{X}\npreLightingInfo preInfo{X};preLightingInfo preInfoCoat{X};vec4 lightColor{X}=light{X}.vLightDiffuse;float shadow{X}=1.;\n#if defined(SHADOWONLY) || defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})\n#else\n#define CUSTOM_LIGHT{X}_COLOR \n#ifdef SPOTLIGHT{X}\npreInfo{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,vPositionW);preInfoCoat{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW,vPositionW);\n#elif defined(POINTLIGHT{X})\npreInfo{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW,vPositionW);preInfoCoat{X}=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW,vPositionW);\n#elif defined(HEMILIGHT{X})\npreInfo{X}=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);preInfoCoat{X}=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW);\n#elif defined(DIRLIGHT{X})\npreInfo{X}=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);preInfoCoat{X}=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,coatNormalW);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\npreInfo{X}=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC2Sampler,viewDirectionW,normalW,vPositionW,light{X}.vLightData,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,specular_roughness);preInfoCoat{X}=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC2Sampler,viewDirectionW,coatNormalW,vPositionW,light{X}.vLightData,light{X}.vLightWidth.xyz,light{X}.vLightHeight.xyz,coat_roughness);\n#endif\npreInfo{X}.NdotV=baseGeoInfo.NdotV;preInfoCoat{X}.NdotV=coatGeoInfo.NdotV;\n#ifdef SPOTLIGHT{X}\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo{X}.attenuation=computeDistanceLightFalloff_GLTF(preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_GLTF(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Physical(preInfo{X}.lightDistanceSquared);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_Physical(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightDirection.w);\n#endif\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Standard(preInfo{X}.lightOffset,light{X}.vLightFalloff.x);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_Standard(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightDirection.w,light{X}.vLightData.w);\n#endif\n#else\npreInfo{X}.attenuation=computeDistanceLightFalloff(preInfo{X}.lightOffset,preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#ifdef IESLIGHTTEXTURE{X}\npreInfo{X}.attenuation*=computeDirectionalLightFalloff_IES(light{X}.vLightDirection.xyz,preInfo{X}.L,iesLightTexture{X});\n#else\npreInfo{X}.attenuation*=computeDirectionalLightFalloff(light{X}.vLightDirection.xyz,preInfo{X}.L,light{X}.vLightDirection.w,light{X}.vLightData.w,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#endif\n#elif defined(POINTLIGHT{X})\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo{X}.attenuation=computeDistanceLightFalloff_GLTF(preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.y);\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Physical(preInfo{X}.lightDistanceSquared);\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo{X}.attenuation=computeDistanceLightFalloff_Standard(preInfo{X}.lightOffset,light{X}.vLightFalloff.x);\n#else\npreInfo{X}.attenuation=computeDistanceLightFalloff(preInfo{X}.lightOffset,preInfo{X}.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#endif\n#else\npreInfo{X}.attenuation=1.0;\n#endif\npreInfoCoat{X}.attenuation=preInfo{X}.attenuation;\n#if defined(HEMILIGHT{X})\npreInfo{X}.roughness=specular_roughness;preInfoCoat{X}.roughness=coat_roughness;\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\npreInfo{X}.roughness=specular_roughness;preInfoCoat{X}.roughness=coat_roughness;\n#else\npreInfo{X}.roughness=adjustRoughnessFromLightProperties(specular_roughness,light{X}.vLightSpecular.a,preInfo{X}.lightDistance);preInfoCoat{X}.roughness=adjustRoughnessFromLightProperties(coat_roughness,light{X}.vLightSpecular.a,preInfoCoat{X}.lightDistance);\n#endif\npreInfo{X}.diffuseRoughness=base_diffuse_roughness;preInfo{X}.surfaceAlbedo=base_color.rgb;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrDirectLightingInit = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrDirectLighting\";\nconst shader = `#ifdef LIGHT{X}\n{vec3 slab_diffuse=vec3(0.,0.,0.);vec3 slab_translucent=vec3(0.,0.,0.);vec3 slab_glossy=vec3(0.,0.,0.);float specularFresnel=0.0;vec3 specularColoredFresnel=vec3(0.,0.,0.);vec3 slab_metal=vec3(0.,0.,0.);vec3 slab_coat=vec3(0.,0.,0.);float coatFresnel=0.0;vec3 slab_fuzz=vec3(0.,0.,0.);float fuzzFresnel=0.0;\n#ifdef HEMILIGHT{X}\nslab_diffuse=computeHemisphericDiffuseLighting(preInfo{X},lightColor{X}.rgb,light{X}.vLightGround);\n#elif defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nslab_diffuse=computeAreaDiffuseLighting(preInfo{X},lightColor{X}.rgb);\n#else\nslab_diffuse=computeDiffuseLighting(preInfo{X},lightColor{X}.rgb);\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nslab_diffuse*=computeProjectionTextureDiffuseLighting(projectionLightTexture{X},textureProjectionMatrix{X},vPositionW);\n#endif\n#ifdef FUZZ\nfloat fuzzNdotH=max(dot(fuzzNormalW,preInfo{X}.H),0.0);vec3 fuzzBrdf=getFuzzBRDFLookup(fuzzNdotH,sqrt(fuzz_roughness));\n#endif\n#ifdef THIN_FILM\nfloat thin_film_desaturation_scale=(thin_film_ior-1.0)*sqrt(thin_film_thickness*0.001);\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nslab_glossy=computeOpenPBRAreaSpecularLighting(\npreInfo{X},\nlight{X}.vLightSpecular.rgb,\nbaseDielectricReflectance.coloredF0,\nbaseDielectricReflectance.coloredF90\n);specularFresnel=computeOpenPBRAreaFresnel(preInfo{X},baseDielectricReflectance.F0,baseDielectricReflectance.F90);\n#else\n{\n#ifdef ANISOTROPIC_BASE\nslab_glossy=computeAnisotropicSpecularLighting(preInfo{X},viewDirectionW,normalW,\nbaseGeoInfo.anisotropicTangent,baseGeoInfo.anisotropicBitangent,baseGeoInfo.anisotropy,\n0.0,lightColor{X}.rgb);\n#else\nslab_glossy=computeSpecularLighting(preInfo{X},normalW,vec3(1.0),vec3(1.0),specular_roughness,lightColor{X}.rgb);\n#endif\nspecularFresnel=fresnelSchlickGGX(preInfo{X}.VdotH,baseDielectricReflectance.F0,baseDielectricReflectance.F90);specularColoredFresnel=specularFresnel*specular_color;\n#ifdef THIN_FILM\nvec3 thinFilmDielectricFresnel=evalIridescence(thin_film_outside_ior,thin_film_ior,preInfo{X}.VdotH,thin_film_thickness,vec3(baseDielectricReflectance.F0));thinFilmDielectricFresnel=mix(thinFilmDielectricFresnel,vec3(dot(thinFilmDielectricFresnel,vec3(0.3333))),thin_film_desaturation_scale);specularColoredFresnel=mix(specularColoredFresnel,thinFilmDielectricFresnel*specular_color,thin_film_weight*thin_film_ior_scale);\n#endif\n}\n#endif\n#ifdef REFRACTED_LIGHTS\nvec3 forwardScatteredLight=vec3(0.0);\n#if AREALIGHT{X}\n#else\n{preLightingInfo preInfoTrans=preInfo{X};\n#ifdef SCATTERING\npreInfoTrans.roughness=sqrt(sqrt(max(transmission_roughness_alpha,0.05)));\n#else\npreInfoTrans.roughness=transmission_roughness;\n#endif\nif (preInfoTrans.NdotLUnclamped<=0.0) {specularFresnel=0.0;specularColoredFresnel=specularFresnel*specular_color;}\n#ifdef GEOMETRY_THIN_WALLED\nvec3 refractNormalW=viewDirectionW;\n#else\nvec3 refractNormalW=normalW;\n#endif\npreInfoTrans.NdotL=0.5*max(dot(-refractNormalW,preInfoTrans.L),0.0)+0.5;\n#if defined(DISPERSION) && !defined(GEOMETRY_THIN_WALLED)\nfloat diff=min(dispersion_iors[2]-dispersion_iors[0],max(dispersion_iors[0]-1.0,1.0));dispersion_iors[2]+=diff;dispersion_iors[0]-=diff;for (int i=0; i<3; i++) {float eta=1.0/dispersion_iors[i];\n#elif defined(GEOMETRY_THIN_WALLED)\nfloat eta=1.0;\n#else\nfloat eta=1.0/specular_ior;\n#endif\npreInfoTrans.H=preInfoTrans.L+min(eta,0.95)*viewDirectionW;float len2=dot(preInfoTrans.H,preInfoTrans.H);if (len2<1e-6) {preInfoTrans.H=preInfoTrans.L;} else {preInfoTrans.H=preInfoTrans.H*inversesqrt(len2);}\n#ifdef ANISOTROPIC_BASE\npreInfoTrans.H=-preInfoTrans.H;\n#endif\npreInfoTrans.VdotH=dot(viewDirectionW,preInfoTrans.H);\n#if defined(DISPERSION) && !defined(GEOMETRY_THIN_WALLED)\nforwardScatteredLight[i]+=\n#else\nforwardScatteredLight+=\n#endif\n#if defined(ANISOTROPIC_BASE)\ncomputeAnisotropicSpecularLighting(preInfoTrans,viewDirectionW,refractNormalW,\nbaseGeoInfo.anisotropicTangent,baseGeoInfo.anisotropicBitangent,baseGeoInfo.anisotropy,\ntransmission_roughness_alpha,lightColor{X}.rgb\n#else\ncomputeSpecularLighting(preInfoTrans,-refractNormalW,vec3(1.0),vec3(1.0),transmission_roughness_alpha,lightColor{X}.rgb\n#endif\n#if defined(DISPERSION) && !defined(GEOMETRY_THIN_WALLED)\n)[i];}\n#else\n);\n#endif\n#if !defined(GEOMETRY_THIN_WALLED)\nforwardScatteredLight=mix(forwardScatteredLight,0.25*preInfoTrans.attenuation*lightColor{X}.rgb,clamp(1.0-pow(baseGeoInfo.NdotV,transmission_roughness_alpha),0.0,1.0));\n#endif\n#ifdef REFRACTED_BACKGROUND\n#ifdef GEOMETRY_THIN_WALLED\nforwardScatteredLight=mix(vec3(0.0),forwardScatteredLight.rgb,0.2*transmission_roughness_alpha);\n#else\nforwardScatteredLight=max(vec3(0.0),mix(vec3(0.0),forwardScatteredLight,transmission_roughness_alpha));\n#endif\n#endif\n#ifdef SCATTERING\n#if !defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) || defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER)\npreInfoTrans.roughness=1.0;vec3 diffused_forward_scattered_light=computeSpecularLighting(preInfoTrans,normalW,vec3(1.0),vec3(1.0),1.0,lightColor{X}.rgb)*volume_absorption;\n#endif\n#ifdef GEOMETRY_THIN_WALLED\nvec3 forward_scattered_light=forwardScatteredLight*transmission_tint*volumeParams.multi_scatter_color;vec3 back_scattered_light=slab_diffuse*volumeParams.multi_scatter_color;slab_translucent=mix(back_scattered_light,forward_scattered_light,0.5+0.5*volumeParams.anisotropy);\n#else\nvec3 back_scattered_normal=normalize(normalW+viewDirectionW);preInfoTrans.NdotL=max(dot(back_scattered_normal,preInfoTrans.L),0.0);preInfoTrans.NdotV=dot(back_scattered_normal,viewDirectionW);preInfoTrans.H=normalize(viewDirectionW+preInfoTrans.L);preInfoTrans.VdotH=clamp(dot(viewDirectionW,preInfoTrans.H),0.0,1.0);preInfoTrans.roughness=0.2;vec3 back_scattered_light=computeSpecularLighting(preInfoTrans,viewDirectionW,vec3(1.0),vec3(0.08),0.0,lightColor{X}.rgb);vec3 forward_scattered_light=(forwardScatteredLight*volume_absorption);vec3 iso_scattered_light=slab_diffuse;vec3 back_scattering=mix(forward_scattered_light,forward_scattered_light+back_scattered_light*backscatter_color,iso_scatter_density);\n#if defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING) && !defined(USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER)\nvec3 iso_scattering=mix(forward_scattered_light,scattered_light_from_irradiance_texture*volumeParams.multi_scatter_color,iso_scatter_density);\n#else\nvec3 iso_scattering=mix(forward_scattered_light,(diffused_forward_scattered_light+iso_scattered_light)*volumeParams.multi_scatter_color,iso_scatter_density);\n#endif\nslab_translucent=mix(back_scattering,iso_scattering,back_to_iso_scattering_blend);slab_translucent=mix(slab_translucent,forward_scattered_light,iso_to_forward_scattering_blend)*transmission_tint;\n#endif\n#else\nslab_translucent=forwardScatteredLight*transmission_tint*volume_absorption;\n#endif\n}\n#endif\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\n#if CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR\nslab_metal=computeOpenPBRAreaConductorSpecularLighting(\npreInfo{X},\nlight{X}.vLightSpecular.rgb,\nbaseConductorReflectance.coloredF0,\nbaseConductorReflectance.coloredF90\n);\n#else\nslab_metal=computeOpenPBRAreaSpecularLighting(\npreInfo{X},\nlight{X}.vLightSpecular.rgb,\nbaseConductorReflectance.coloredF0,\nbaseConductorReflectance.coloredF90\n);\n#endif\n#else\n{\n#if (CONDUCTOR_SPECULAR_MODEL==CONDUCTOR_SPECULAR_MODEL_OPENPBR)\nvec3 coloredFresnel=getF82Specular(preInfo{X}.VdotH,baseConductorReflectance.coloredF0,baseConductorReflectance.coloredF90,specular_roughness);\n#else\nvec3 coloredFresnel=fresnelSchlickGGX(preInfo{X}.VdotH,baseConductorReflectance.coloredF0,baseConductorReflectance.coloredF90);\n#endif\n#ifdef THIN_FILM\nfloat thinFilmConductorAngle=max(preInfo{X}.VdotH,specular_roughness);vec3 thinFilmConductorFresnel=evalIridescence(thin_film_outside_ior,thin_film_ior,thinFilmConductorAngle,thin_film_thickness,baseConductorReflectance.coloredF0);thinFilmConductorFresnel=mix(thinFilmConductorFresnel,vec3(dot(thinFilmConductorFresnel,vec3(0.3333))),thin_film_desaturation_scale);coloredFresnel=mix(coloredFresnel,specular_weight*thinFilmConductorFresnel,thin_film_weight*thin_film_ior_scale);\n#endif\n#ifdef ANISOTROPIC_BASE\nslab_metal=computeAnisotropicSpecularLighting(preInfo{X},viewDirectionW,normalW,baseGeoInfo.anisotropicTangent,baseGeoInfo.anisotropicBitangent,baseGeoInfo.anisotropy,0.0,lightColor{X}.rgb);\n#else\nslab_metal=computeSpecularLighting(preInfo{X},normalW,vec3(1.0),coloredFresnel,specular_roughness,lightColor{X}.rgb);\n#endif\n}\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nslab_coat=computeOpenPBRAreaSpecularLighting(\npreInfoCoat{X},\nlight{X}.vLightSpecular.rgb,\nvec3(coatReflectance.F0),\nvec3(coatReflectance.F90)\n);\n#else\n{\n#ifdef ANISOTROPIC_COAT\nslab_coat=computeAnisotropicSpecularLighting(preInfoCoat{X},viewDirectionW,coatNormalW,\ncoatGeoInfo.anisotropicTangent,coatGeoInfo.anisotropicBitangent,coatGeoInfo.anisotropy,\n0.0,lightColor{X}.rgb);\n#else\nslab_coat=computeSpecularLighting(preInfoCoat{X},coatNormalW,vec3(coatReflectance.F0),vec3(1.0),coat_roughness,lightColor{X}.rgb);\n#endif\nfloat NdotH=max(dot(coatNormalW,preInfoCoat{X}.H),0.0);coatFresnel=fresnelSchlickGGX(NdotH,coatReflectance.F0,coatReflectance.F90);}\n#endif\nvec3 coatAbsorption=vec3(1.0);if (coat_weight>0.0) {float cosTheta_view=max(preInfoCoat{X}.NdotV,0.001);float cosTheta_light=max(preInfoCoat{X}.NdotL,0.001);float fresnel_view=coatReflectance.F0+(1.0-coatReflectance.F0)*pow(1.0-cosTheta_view,5.0);float fresnel_light=coatReflectance.F0+(1.0-coatReflectance.F0)*pow(1.0-cosTheta_light,5.0);float averageReflectance=(fresnel_view+fresnel_light)*0.5;float darkened_transmission=(1.0-averageReflectance)/(1.0+averageReflectance);darkened_transmission=mix(1.0,darkened_transmission,coat_darkening);float sin2=1.0-cosTheta_view*cosTheta_view;sin2=sin2/(coat_ior*coat_ior)*coat_weight;float cos_t=sqrt(1.0-sin2);float coatPathLength=1.0/cos_t;float effectivePathLength=coatPathLength*coat_weight;vec3 colored_transmission=pow(coat_color,vec3(effectivePathLength));coatAbsorption=colored_transmission*mix(1.0,darkened_transmission,coat_weight);}\n#ifdef FUZZ\nfuzzFresnel=fuzzBrdf.z;vec3 fuzzNormalW=mix(normalW,coatNormalW,coat_weight);float fuzzNdotV=max(dot(fuzzNormalW,viewDirectionW.xyz),0.0);float fuzzNdotL=max(dot(fuzzNormalW,preInfo{X}.L),0.0);slab_fuzz=lightColor{X}.rgb*preInfo{X}.attenuation*evalFuzz(preInfo{X}.L,fuzzNdotL,fuzzNdotV,fuzzTangent,fuzzBitangent,fuzzBrdf);\n#else\nvec3 fuzz_color=vec3(0.0);\n#endif\n#ifdef PREPASS_IRRADIANCE\ntotal_direct_diffuse+=slab_diffuse;\n#endif\nvec3 material_dielectric_base=mix(slab_diffuse*base_color.rgb,slab_translucent,surface_translucency_weight);\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nvec3 material_dielectric_gloss=material_dielectric_base*(1.0-specularFresnel)+slab_glossy;\n#else\nvec3 material_dielectric_gloss=material_dielectric_base*(1.0-specularFresnel)+slab_glossy*specularColoredFresnel;\n#endif\nvec3 material_base_substrate=mix(material_dielectric_gloss,slab_metal,base_metalness);vec3 material_coated_base=layer(material_base_substrate,slab_coat,coatFresnel,coatAbsorption,vec3(1.0));material_surface_direct+=layer(material_coated_base,slab_fuzz,fuzzFresnel*fuzz_weight,vec3(1.0),fuzz_color);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrDirectLighting = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"openpbrBlockPrePass\";\nconst shader = `#if SCENE_MRT_COUNT>0\n#ifdef ALPHATEST\nfloat writeGeometryInfo=1.0;\n#else\nfloat writeGeometryInfo=finalColor.a>ALPHATESTVALUE ? 1.0 : 0.0;\n#endif\n#ifdef PREPASS_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_POSITION_INDEX,vec4(vPositionW,writeGeometryInfo));\n#endif\n#ifdef PREPASS_OBJECT_ID\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_OBJECT_ID_INDEX,encodeObjectId(objectId)*writeGeometryInfo);\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nmeshBlendTagOutput=writeGeometryInfo>0.0 ? uvec4(uint(meshBlendTag),0u,0u,0u) : uvec4(0u);\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_LOCAL_POSITION_INDEX,vec4(vPosition,writeGeometryInfo));\n#endif\n#if defined(PREPASS_VELOCITY)\nvec2 a=(vCurrentPosition.xy/vCurrentPosition.w)*0.5+0.5;vec2 b=(vPreviousPosition.xy/vPreviousPosition.w)*0.5+0.5;vec2 velocity=abs(a-b);velocity=vec2(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;WRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_INDEX,vec4(velocity,0.0,writeGeometryInfo));\n#elif defined(PREPASS_VELOCITY_LINEAR)\nvec2 velocity=vec2(0.5)*((vPreviousPosition.xy/vPreviousPosition.w)-(vCurrentPosition.xy/vCurrentPosition.w));WRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_LINEAR_INDEX,vec4(velocity,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_ALBEDO\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_INDEX,vec4(base_color,writeGeometryInfo));\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nvec3 sqAlbedo=sqrt(base_color);\n#endif\n#ifdef PREPASS_IRRADIANCE\nvec3 irradiance=total_direct_diffuse;\n#ifndef UNLIT\n#ifdef REFLECTION\nirradiance+=slab_diffuse_ibl;\n#endif\n#endif\n#ifdef SCATTERING\nfloat scatter_mask=min(subsurface_weight+transmission_weight,1.0);\n#else\nfloat scatter_mask=0.0;\n#endif\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_IRRADIANCE_INDEX,vec4(irradiance,writeGeometryInfo*scatter_mask));\n#endif\n#if defined(PREPASS_COLOR)\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_COLOR_INDEX,vec4(finalColor.rgb,finalColor.a));\n#endif\n#ifdef PREPASS_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_DEPTH_INDEX,vec4(vViewPos.z,0.0,0.0,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_SCREENSPACE_DEPTH_INDEX,vec4(gl_FragCoord.z,0.0,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMALIZED_VIEW_DEPTH_INDEX,vec4(vNormViewDepth,0.0,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_NORMAL\n#ifdef PREPASS_NORMAL_WORLDSPACE\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(normalW,writeGeometryInfo));\n#else\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(normalize((view*vec4(normalW,0.0)).rgb),writeGeometryInfo));\n#endif\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_WORLD_NORMAL_INDEX,vec4(normalW*0.5+0.5,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_SQRT_INDEX,vec4(sqAlbedo,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_REFLECTIVITY\n#ifndef UNLIT\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4(specularEnvironmentR0,microSurface)*writeGeometryInfo);\n#else\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4( 0.0,0.0,0.0,1.0 )*writeGeometryInfo);\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const openpbrBlockPrePass = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { oitDeclaration } from \"./ShadersInclude/oitDeclaration\";\nimport { sceneFragmentDeclaration } from \"./ShadersInclude/sceneFragmentDeclaration\";\nimport { decalFragmentDeclaration } from \"./ShadersInclude/decalFragmentDeclaration\";\nimport { openpbrFragmentDeclaration } from \"./ShadersInclude/openpbrFragmentDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { openpbrUboDeclaration } from \"./ShadersInclude/openpbrUboDeclaration\";\nimport { mainUVVaryingDeclaration } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { pbrFragmentExtraDeclaration } from \"./ShadersInclude/pbrFragmentExtraDeclaration\";\nimport { lightFragmentDeclaration } from \"./ShadersInclude/lightFragmentDeclaration\";\nimport { lightUboDeclaration } from \"./ShadersInclude/lightUboDeclaration\";\nimport { samplerFragmentDeclaration } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { pbrFragmentReflectionDeclaration } from \"./ShadersInclude/pbrFragmentReflectionDeclaration\";\nimport { openpbrFragmentSamplersDeclaration } from \"./ShadersInclude/openpbrFragmentSamplersDeclaration\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { textureRepetitionFunctions } from \"./ShadersInclude/textureRepetitionFunctions\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { subSurfaceScatteringFunctions } from \"./ShadersInclude/subSurfaceScatteringFunctions\";\nimport { importanceSampling } from \"./ShadersInclude/importanceSampling\";\nimport { pbrHelperFunctions } from \"./ShadersInclude/pbrHelperFunctions\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { shadowsFragmentFunctions } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { harmonicsFunctions } from \"./ShadersInclude/harmonicsFunctions\";\nimport { ltcHelperFunctions } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { pbrDirectLightingSetupFunctions } from \"./ShadersInclude/pbrDirectLightingSetupFunctions\";\nimport { pbrDirectLightingFalloffFunctions } from \"./ShadersInclude/pbrDirectLightingFalloffFunctions\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctions } from \"./ShadersInclude/hdrFilteringFunctions\";\nimport { pbrDirectLightingFunctions } from \"./ShadersInclude/pbrDirectLightingFunctions\";\nimport { pbrIBLFunctions } from \"./ShadersInclude/pbrIBLFunctions\";\nimport { openpbrNormalMapFragmentMainFunctions } from \"./ShadersInclude/openpbrNormalMapFragmentMainFunctions\";\nimport { openpbrNormalMapFragmentFunctions } from \"./ShadersInclude/openpbrNormalMapFragmentFunctions\";\nimport { reflectionFunction } from \"./ShadersInclude/reflectionFunction\";\nimport { openpbrDielectricReflectance } from \"./ShadersInclude/openpbrDielectricReflectance\";\nimport { openpbrConductorReflectance } from \"./ShadersInclude/openpbrConductorReflectance\";\nimport { openpbrAmbientOcclusionFunctions } from \"./ShadersInclude/openpbrAmbientOcclusionFunctions\";\nimport { openpbrGeometryInfo } from \"./ShadersInclude/openpbrGeometryInfo\";\nimport { openpbrIblFunctions } from \"./ShadersInclude/openpbrIblFunctions\";\nimport { openpbrVolumeFunctions } from \"./ShadersInclude/openpbrVolumeFunctions\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { pbrBlockNormalGeometric } from \"./ShadersInclude/pbrBlockNormalGeometric\";\nimport { openpbrNormalMapFragment } from \"./ShadersInclude/openpbrNormalMapFragment\";\nimport { openpbrBlockNormalFinal } from \"./ShadersInclude/openpbrBlockNormalFinal\";\nimport { openpbrBaseLayerData } from \"./ShadersInclude/openpbrBaseLayerData\";\nimport { openpbrTransmissionLayerData } from \"./ShadersInclude/openpbrTransmissionLayerData\";\nimport { openpbrSubsurfaceLayerData } from \"./ShadersInclude/openpbrSubsurfaceLayerData\";\nimport { openpbrCoatLayerData } from \"./ShadersInclude/openpbrCoatLayerData\";\nimport { openpbrThinFilmLayerData } from \"./ShadersInclude/openpbrThinFilmLayerData\";\nimport { openpbrFuzzLayerData } from \"./ShadersInclude/openpbrFuzzLayerData\";\nimport { openpbrAmbientOcclusionData } from \"./ShadersInclude/openpbrAmbientOcclusionData\";\nimport { depthPrePass } from \"./ShadersInclude/depthPrePass\";\nimport { openpbrBackgroundTransmission } from \"./ShadersInclude/openpbrBackgroundTransmission\";\nimport { openpbrEnvironmentLighting } from \"./ShadersInclude/openpbrEnvironmentLighting\";\nimport { openpbrDirectLightingInit } from \"./ShadersInclude/openpbrDirectLightingInit\";\nimport { openpbrDirectLighting } from \"./ShadersInclude/openpbrDirectLighting\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { pbrBlockImageProcessing } from \"./ShadersInclude/pbrBlockImageProcessing\";\nimport { openpbrBlockPrePass } from \"./ShadersInclude/openpbrBlockPrePass\";\nimport { oitFragment } from \"./ShadersInclude/oitFragment\";\nimport { pbrDebug } from \"./ShadersInclude/pbrDebug\";\n\nconst name = \"openpbrPixelShader\";\nconst shader = `#define OPENPBR_FRAGMENT_SHADER\n#define CUSTOM_FRAGMENT_EXTENSION\n#if defined(GEOMETRY_NORMAL) || defined(GEOMETRY_COAT_NORMAL) || !defined(NORMAL) || defined(FORCENORMALFORWARD) || defined(SPECULARAA)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#ifdef LODBASEDMICROSFURACE\n#extension GL_EXT_shader_texture_lod : enable\n#endif\n#define CUSTOM_FRAGMENT_BEGIN\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\nprecision highp float;\n#include<oitDeclaration>\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE\n#endif\n#include<__decl__openpbrFragment>\n#include<pbrFragmentExtraDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<openpbrFragmentSamplersDeclaration>\n#include<imageProcessingDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#include<textureRepetitionFunctions>\n#include<helperFunctions>\n#include<subSurfaceScatteringFunctions>\n#include<importanceSampling>\n#include<pbrHelperFunctions>\n#include<imageProcessingFunctions>\n#include<shadowsFragmentFunctions>\n#include<harmonicsFunctions>\n#include<pbrDirectLightingSetupFunctions>\n#include<pbrDirectLightingFalloffFunctions>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\n#include<pbrDirectLightingFunctions>\n#include<pbrIBLFunctions>\n#include<openpbrNormalMapFragmentMainFunctions>\n#include<openpbrNormalMapFragmentFunctions>\n#ifdef REFLECTION\n#include<reflectionFunction>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#include<openpbrDielectricReflectance>\n#include<openpbrConductorReflectance>\n#include<openpbrAmbientOcclusionFunctions>\n#include<openpbrGeometryInfo>\n#include<openpbrIblFunctions>\n#include<openpbrVolumeFunctions>\nvec3 layer(vec3 slab_bottom,vec3 slab_top,float lerp_factor,vec3 bottom_multiplier,vec3 top_multiplier) {return mix(slab_bottom*bottom_multiplier,slab_top*top_multiplier,lerp_factor);}\nvoid main(void) {\n#ifdef PREPASS_IRRADIANCE\nvec3 total_direct_diffuse=vec3(0.0);\n#endif\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#include<pbrBlockNormalGeometric>\nvec3 coatNormalW=normalW;\n#include<openpbrNormalMapFragment>\n#include<openpbrBlockNormalFinal>\n#include<openpbrBaseLayerData>\n#include<openpbrTransmissionLayerData>\n#include<openpbrSubsurfaceLayerData>\n#include<openpbrCoatLayerData>\n#include<openpbrThinFilmLayerData>\n#include<openpbrFuzzLayerData>\n#include<openpbrAmbientOcclusionData>\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\n#include<depthPrePass>\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\n#ifdef ANISOTROPIC_COAT\ngeometryInfoAnisoOutParams coatGeoInfo=geometryInfoAniso(\ncoatNormalW,viewDirectionW.xyz,coat_roughness,geometricNormalW\n,vec3(geometry_coat_tangent.x,geometry_coat_tangent.y,coat_roughness_anisotropy),TBN\n);\n#else\ngeometryInfoOutParams coatGeoInfo=geometryInfo(\ncoatNormalW,viewDirectionW.xyz,coat_roughness,geometricNormalW\n);\n#endif\nspecular_roughness=mix(specular_roughness,pow(min(1.0,pow(specular_roughness,4.0)+2.0*pow(coat_roughness,4.0)),0.25),coat_weight);\n#ifdef ANISOTROPIC_BASE\ngeometryInfoAnisoOutParams baseGeoInfo=geometryInfoAniso(\nnormalW,viewDirectionW.xyz,specular_roughness,geometricNormalW\n,vec3(geometry_tangent.x,geometry_tangent.y,specular_roughness_anisotropy),TBN\n);\n#else\ngeometryInfoOutParams baseGeoInfo=geometryInfo(\nnormalW,viewDirectionW.xyz,specular_roughness,geometricNormalW\n);\n#endif\n#ifdef FUZZ\nvec3 fuzzNormalW=normalize(mix(normalW,coatNormalW,coat_weight));vec3 fuzzTangent=normalize(TBN[0]);fuzzTangent=normalize(fuzzTangent-dot(fuzzTangent,fuzzNormalW)*fuzzNormalW);vec3 fuzzBitangent=cross(fuzzNormalW,fuzzTangent);geometryInfoOutParams fuzzGeoInfo=geometryInfo(\nfuzzNormalW,viewDirectionW.xyz,fuzz_roughness,geometricNormalW\n);\n#endif\nReflectanceParams coatReflectance;coatReflectance=dielectricReflectance(\ncoat_ior \n,1.0 \n,vec3(1.0)\n,coat_weight\n);\n#ifdef THIN_FILM\nfloat thin_film_outside_ior=mix(1.0,coat_ior,coat_weight);\n#endif\nReflectanceParams baseDielectricReflectance;{float effectiveCoatIor=mix(1.0,coat_ior,coat_weight);baseDielectricReflectance=dielectricReflectance(\nspecular_ior \n,effectiveCoatIor \n,specular_color\n,specular_weight\n);}\nReflectanceParams baseConductorReflectance;baseConductorReflectance=conductorReflectance(base_color,specular_color,specular_weight);vec3 volume_absorption=vec3(1.0);vec3 transmission_tint=vec3(1.0);float surface_translucency_weight=0.0;\n#if defined(REFRACTED_BACKGROUND) || defined(REFRACTED_ENVIRONMENT) || defined(REFRACTED_LIGHTS)\n#if defined(GEOMETRY_THIN_WALLED)\nvec3 refractedViewVector=-viewDirectionW;\n#else\n#ifdef DISPERSION\nvec3 refractedViewVectors[3];float iorDispersionSpread=transmission_dispersion_scale/transmission_dispersion_abbe_number*(specular_ior-1.0);vec3 dispersion_iors=vec3(specular_ior-iorDispersionSpread,specular_ior,specular_ior+iorDispersionSpread);for (int i=0; i<3; i++) {refractedViewVectors[i]=double_refract(-viewDirectionW,normalW,dispersion_iors[i]); }\n#else\nvec3 refractedViewVector=double_refract(-viewDirectionW,normalW,specular_ior);\n#endif\n#endif\n#ifdef GEOMETRY_THIN_WALLED\nfloat transmission_roughness=specular_roughness;\n#else\nfloat transmission_roughness=specular_roughness*clamp(4.0*(specular_ior-1.0),0.001,1.0);\n#endif\n#if (defined(TRANSMISSION_SLAB) || defined(SUBSURFACE_SLAB))\nOpenPBRHomogeneousVolume volumeParams;{\n#if defined(TRANSMISSION_SLAB)\nOpenPBRHomogeneousVolume transmissionVolumeParams=computeOpenPBRTransmissionVolume(\ntransmission_color.rgb,\ntransmission_depth,\ntransmission_scatter.rgb,\ntransmission_scatter_anisotropy\n);\n#endif\n#if defined(SUBSURFACE_SLAB)\nOpenPBRHomogeneousVolume subsurfaceVolumeParams=computeOpenPBRSubsurfaceVolume(\nsubsurface_color.rgb,\nsubsurface_radius,\nsubsurface_radius_scale.rgb,\nsubsurface_scatter_anisotropy\n);\n#endif\n#if !defined(TRANSMISSION_SLAB)\nvolumeParams=subsurfaceVolumeParams;surface_translucency_weight=subsurface_weight;\n#elif !defined(SUBSURFACE_SLAB)\nvolumeParams=transmissionVolumeParams;\n#ifdef TRANSMISSION_SLAB_VOLUME\nvolumeParams.multi_scatter_color=singleScatterToMultiScatterAlbedo(volumeParams.ss_albedo);\n#endif\nsurface_translucency_weight=transmission_weight;\n#else\nfloat subsurface_fraction_of_dielectric=(1.0f-transmission_weight)*subsurface_weight;float subsurface_and_transmission_fraction_of_dielectric=subsurface_fraction_of_dielectric+transmission_weight;float reciprocal_of_subsurface_and_transmission_fraction_of_dielectric =\n1.0f/maxEps(subsurface_and_transmission_fraction_of_dielectric);float trans_weight=transmission_weight*reciprocal_of_subsurface_and_transmission_fraction_of_dielectric;float subsurf_weight=subsurface_fraction_of_dielectric*reciprocal_of_subsurface_and_transmission_fraction_of_dielectric;volumeParams.scatter_coeff=transmissionVolumeParams.scatter_coeff*trans_weight+subsurfaceVolumeParams.scatter_coeff*subsurf_weight;volumeParams.absorption_coeff=transmissionVolumeParams.absorption_coeff*trans_weight+subsurfaceVolumeParams.absorption_coeff*subsurf_weight;volumeParams.anisotropy=(transmissionVolumeParams.anisotropy*trans_weight+subsurfaceVolumeParams.anisotropy*subsurf_weight)/maxEps(trans_weight+subsurf_weight);volumeParams.extinction_coeff=volumeParams.absorption_coeff+volumeParams.scatter_coeff;volumeParams.ss_albedo=volumeParams.scatter_coeff/maxEps(volumeParams.extinction_coeff);volumeParams.multi_scatter_color=singleScatterToMultiScatterAlbedo(volumeParams.ss_albedo);surface_translucency_weight=subsurface_and_transmission_fraction_of_dielectric;\n#endif\n}\nvolume_absorption=exp(-volumeParams.absorption_coeff*geometry_thickness);vec3 backscatter_color=vec3(1.0);{vec3 reduced_scatter=volumeParams.scatter_coeff*vec3(1.0-volumeParams.anisotropy);vec3 reduced_albedo=reduced_scatter/(volumeParams.absorption_coeff+reduced_scatter);vec3 sqrt_term=max(sqrt(1.0-reduced_albedo),0.0001);backscatter_color=(1.0-sqrt_term)/(1.0+sqrt_term);}\n#elif defined(TRANSMISSION_SLAB)\nsurface_translucency_weight=transmission_weight;\n#endif\n#ifdef SCATTERING\n#ifdef GEOMETRY_THIN_WALLED\nvec3 iso_scatter_density=vec3(1.0);\n#else\n#ifdef USE_IRRADIANCE_TEXTURE_FOR_SCATTERING\nvec3 mfp=vec3(100.0)/volumeParams.extinction_coeff;vec3 scattered_light_from_irradiance_texture=sss_convolve(sceneIrradianceSampler,sceneDepthSampler,renderTargetSize,mfp,projection,inverseProjection,SSS_SAMPLE_COUNT,noise.xy);float numLights=float(LIGHTCOUNT);\n#ifdef REFLECTION\nnumLights+=1.0;\n#endif\nscattered_light_from_irradiance_texture/=numLights;\n#else\nvec3 scattered_light_from_irradiance_texture=vec3(0.0);\n#endif\nfloat back_to_iso_scattering_blend=min(1.0+volumeParams.anisotropy,1.0);float iso_to_forward_scattering_blend=max(volumeParams.anisotropy,0.0);vec3 iso_scatter_transmittance=pow(exp(-volumeParams.scatter_coeff*geometry_thickness),vec3(0.2));vec3 iso_scatter_density=clamp(vec3(1.0)-iso_scatter_transmittance,0.0,1.0);transmission_roughness=min(transmission_roughness+pow((1.0-abs(volumeParams.anisotropy))*max3(iso_scatter_density*iso_scatter_density),3.0),1.0);\n#endif\nvolumeParams.multi_scatter_color=mix(volumeParams.ss_albedo,volumeParams.multi_scatter_color,max3(iso_scatter_density));\n#endif\n#if defined(TRANSMISSION_SLAB) && (!defined(TRANSMISSION_SLAB_VOLUME) || defined(GEOMETRY_THIN_WALLED))\ntransmission_tint*=transmission_color.rgb;\n#ifdef GEOMETRY_THIN_WALLED\nfloat sin2=1.0-baseGeoInfo.NdotV*baseGeoInfo.NdotV;sin2=sin2/(specular_ior*specular_ior);float cos_t=sqrt(1.0-sin2);float pathLength=1.0/cos_t;transmission_tint=pow(transmission_tint,vec3(pathLength));\n#else\ntransmission_tint*=transmission_color.rgb;\n#endif\n#endif\n#if defined(SUBSURFACE_SLAB) && defined(GEOMETRY_THIN_WALLED)\nfloat unweighted_translucency=max(mix(subsurface_weight,1.0f,transmission_weight),0.0001);transmission_tint=mix(vec3(1.0),transmission_tint,transmission_weight/unweighted_translucency);transmission_roughness=mix(1.0,transmission_roughness,transmission_weight/unweighted_translucency);\n#endif\nfloat transmission_roughness_alpha=transmission_roughness*transmission_roughness;\n#endif\n#include<openpbrBackgroundTransmission>\nvec3 material_surface_ibl=vec3(0.,0.,0.);\n#include<openpbrEnvironmentLighting>\nvec3 material_surface_direct=vec3(0.,0.,0.);\n#if defined(LIGHT0)\nfloat aggShadow=0.;\n#include<openpbrDirectLightingInit>[0..maxSimultaneousLights]\n#include<openpbrDirectLighting>[0..maxSimultaneousLights]\n#endif\nvec3 material_surface_emission=vEmissionColor;\n#ifdef EMISSION_COLOR\nvec3 emissionColorTex=TEXRD(emissionColorSampler,vEmissionColorUV+uvOffset).rgb;\n#ifdef EMISSION_COLOR_GAMMA\nmaterial_surface_emission*=toLinearSpace(emissionColorTex.rgb);\n#else\nmaterial_surface_emission*=emissionColorTex.rgb;\n#endif\nmaterial_surface_emission*= vEmissionColorInfos.y;\n#endif\nmaterial_surface_emission*=vLightingIntensity.y;\n#define CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION\nvec4 finalColor=vec4(material_surface_ibl+material_surface_direct+material_surface_emission,alpha);\n#define CUSTOM_FRAGMENT_BEFORE_FOG\nfinalColor=max(finalColor,0.0);\n#include<logDepthFragment>\n#include<fogFragment>(color,finalColor)\n#include<pbrBlockImageProcessing>\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\n#include<openpbrBlockPrePass>\n#endif\n#if !defined(PREPASS) || defined(WEBGL2)\ngl_FragColor=finalColor;\n#endif\n#include<oitFragment>\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {frontColor.rgb+=finalColor.rgb*finalColor.a*alphaMultiplier;frontColor.a=1.0-alphaMultiplier*(1.0-finalColor.a);} else {backColor+=finalColor;}\n#endif\n#include<pbrDebug>\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [objectIdFunctions, prePassDeclaration, oitDeclaration, sceneFragmentDeclaration, decalFragmentDeclaration, openpbrFragmentDeclaration, sceneUboDeclaration, meshUboDeclaration, openpbrUboDeclaration, mainUVVaryingDeclaration, pbrFragmentExtraDeclaration, lightFragmentDeclaration, lightUboDeclaration, samplerFragmentDeclaration, pbrFragmentReflectionDeclaration, openpbrFragmentSamplersDeclaration, imageProcessingDeclaration, clipPlaneFragmentDeclaration, logDepthDeclaration, fogFragmentDeclaration, textureRepetitionFunctions, helperFunctions, subSurfaceScatteringFunctions, importanceSampling, pbrHelperFunctions, imageProcessingFunctions, shadowsFragmentFunctions, harmonicsFunctions, ltcHelperFunctions, pbrDirectLightingSetupFunctions, pbrDirectLightingFalloffFunctions, pbrBRDFFunctions, hdrFilteringFunctions, pbrDirectLightingFunctions, pbrIBLFunctions, openpbrNormalMapFragmentMainFunctions, openpbrNormalMapFragmentFunctions, reflectionFunction, openpbrDielectricReflectance, openpbrConductorReflectance, openpbrAmbientOcclusionFunctions, openpbrGeometryInfo, openpbrIblFunctions, openpbrVolumeFunctions, clipPlaneFragment, pbrBlockNormalGeometric, openpbrNormalMapFragment, openpbrBlockNormalFinal, openpbrBaseLayerData, openpbrTransmissionLayerData, openpbrSubsurfaceLayerData, openpbrCoatLayerData, openpbrThinFilmLayerData, openpbrFuzzLayerData, openpbrAmbientOcclusionData, depthPrePass, openpbrBackgroundTransmission, openpbrEnvironmentLighting, openpbrDirectLightingInit, openpbrDirectLighting, logDepthFragment, fogFragment, pbrBlockImageProcessing, openpbrBlockPrePass, oitFragment, pbrDebug];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const openpbrPixelShader = { name, shader };\n","/**\r\n * Language of the shader code\r\n */\r\nexport const enum ShaderLanguage {\r\n    /** language is GLSL (used by WebGL) */\r\n    GLSL,\r\n    /** language is WGSL (used by WebGPU) */\r\n    WGSL,\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../../types\";\nimport { type Scene } from \"../../scene.pure\";\nimport { Matrix } from \"../../Maths/math.vector.pure\";\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\nimport { Constants } from \"../../Engines/constants\";\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\nimport { RegisterClass } from \"../../Misc/typeStore\";\n\n/**\n * This represents a color grading texture. This acts as a lookup table LUT, useful during post process\n * It can help converting any input color in a desired output one. This can then be used to create effects\n * from sepia, black and white to sixties or futuristic rendering...\n *\n * The only supported format is currently 3dl.\n * More information on LUT: https://en.wikipedia.org/wiki/3D_lookup_table\n */\nexport class ColorGradingTexture extends BaseTexture {\n    /**\n     * The texture URL.\n     */\n    public url: string;\n\n    /**\n     * Empty line regex stored for GC.\n     */\n    private static _NoneEmptyLineRegex = /\\S+/;\n\n    private _textureMatrix: Matrix;\n    private _onLoad: Nullable<() => void>;\n\n    /**\n     * Instantiates a ColorGradingTexture from the following parameters.\n     *\n     * @param url The location of the color grading data (currently only supporting 3dl)\n     * @param sceneOrEngine The scene or engine the texture will be used in\n     * @param onLoad defines a callback triggered when the texture has been loaded\n     */\n    constructor(url: string, sceneOrEngine: Scene | AbstractEngine, onLoad: Nullable<() => void> = null) {\n        super(sceneOrEngine);\n\n        if (!url) {\n            return;\n        }\n\n        this._textureMatrix = Matrix.Identity();\n        this.name = url;\n        this.url = url;\n        this._onLoad = onLoad;\n\n        this._texture = this._getFromCache(url, true);\n\n        if (!this._texture) {\n            const scene = this.getScene();\n            if (scene) {\n                if (!scene.useDelayedTextureLoading) {\n                    this._loadTexture();\n                } else {\n                    this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\n                }\n            } else {\n                this._loadTexture();\n            }\n        } else {\n            this._triggerOnLoad();\n        }\n    }\n\n    /**\n     * Fires the onload event from the constructor if requested.\n     */\n    private _triggerOnLoad(): void {\n        if (this._onLoad) {\n            this._onLoad();\n        }\n    }\n\n    /**\n     * @returns the texture matrix used in most of the material.\n     * This is not used in color grading but keep for troubleshooting purpose (easily swap diffuse by colorgrading to look in).\n     */\n    public override getTextureMatrix(): Matrix {\n        return this._textureMatrix;\n    }\n\n    /**\n     * Occurs when the file being loaded is a .3dl LUT file.\n     * @returns the 3D LUT texture\n     */\n    private _load3dlTexture() {\n        const engine = this._getEngine()!;\n        let texture: InternalTexture;\n        if (!engine._features.support3DTextures) {\n            texture = engine.createRawTexture(\n                null,\n                1,\n                1,\n                Constants.TEXTUREFORMAT_RGBA,\n                false,\n                false,\n                Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n                null,\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n        } else {\n            texture = engine.createRawTexture3D(\n                null,\n                1,\n                1,\n                1,\n                Constants.TEXTUREFORMAT_RGBA,\n                false,\n                false,\n                Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n                null,\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n        }\n\n        this._texture = texture;\n        this._texture.isReady = false;\n\n        this.isCube = false;\n        this.is3D = engine._features.support3DTextures;\n        this.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        this.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        this.wrapR = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        this.anisotropicFilteringLevel = 1;\n\n        const callback = (text: string | ArrayBuffer) => {\n            if (typeof text !== \"string\") {\n                return;\n            }\n\n            let data: Nullable<Uint8Array> = null;\n            let tempData: Nullable<Float32Array> = null;\n\n            let line: string;\n            const lines = text.split(\"\\n\");\n            let size = 0,\n                pixelIndexW = 0,\n                pixelIndexH = 0,\n                pixelIndexSlice = 0;\n            let maxColor = 0;\n\n            for (let i = 0; i < lines.length; i++) {\n                line = lines[i];\n\n                if (!ColorGradingTexture._NoneEmptyLineRegex.test(line)) {\n                    continue;\n                }\n\n                if (line.indexOf(\"#\") === 0) {\n                    continue;\n                }\n\n                const words = line.split(\" \");\n                if (size === 0) {\n                    // Number of space + one\n                    size = words.length;\n                    data = new Uint8Array(size * size * size * 4); // volume texture of side size and rgb 8\n                    tempData = new Float32Array(size * size * size * 4);\n                    continue;\n                }\n\n                if (size != 0) {\n                    const r = Math.max(parseInt(words[0]), 0);\n                    const g = Math.max(parseInt(words[1]), 0);\n                    const b = Math.max(parseInt(words[2]), 0);\n\n                    maxColor = Math.max(r, maxColor);\n                    maxColor = Math.max(g, maxColor);\n                    maxColor = Math.max(b, maxColor);\n\n                    const pixelStorageIndex = (pixelIndexW + pixelIndexSlice * size + pixelIndexH * size * size) * 4;\n\n                    if (tempData) {\n                        tempData[pixelStorageIndex + 0] = r;\n                        tempData[pixelStorageIndex + 1] = g;\n                        tempData[pixelStorageIndex + 2] = b;\n                    }\n\n                    // Keep for reference in case of back compat problems.\n                    // pixelIndexSlice++;\n                    // if (pixelIndexSlice % size == 0) {\n                    //     pixelIndexH++;\n                    //     pixelIndexSlice = 0;\n                    //     if (pixelIndexH % size == 0) {\n                    //         pixelIndexW++;\n                    //         pixelIndexH = 0;\n                    //     }\n                    // }\n\n                    pixelIndexH++;\n                    if (pixelIndexH % size == 0) {\n                        pixelIndexSlice++;\n                        pixelIndexH = 0;\n                        if (pixelIndexSlice % size == 0) {\n                            pixelIndexW++;\n                            pixelIndexSlice = 0;\n                        }\n                    }\n                }\n            }\n\n            if (tempData && data) {\n                for (let i = 0; i < tempData.length; i++) {\n                    if (i > 0 && (i + 1) % 4 === 0) {\n                        data[i] = 255;\n                    } else {\n                        const value = tempData[i];\n                        data[i] = (value / maxColor) * 255;\n                    }\n                }\n            }\n\n            if (texture.is3D) {\n                texture.updateSize(size, size, size);\n                engine.updateRawTexture3D(texture, data, Constants.TEXTUREFORMAT_RGBA, false);\n            } else {\n                texture.updateSize(size * size, size);\n                engine.updateRawTexture(texture, data, Constants.TEXTUREFORMAT_RGBA, false);\n            }\n\n            texture.isReady = true;\n            this._triggerOnLoad();\n        };\n\n        const scene = this.getScene();\n        if (scene) {\n            scene._loadFile(this.url, callback);\n        } else {\n            engine._loadFile(this.url, callback);\n        }\n\n        return this._texture;\n    }\n\n    /**\n     * Starts the loading process of the texture.\n     */\n    private _loadTexture() {\n        if (this.url) {\n            const url = this.url.toLocaleLowerCase();\n            if (url.endsWith(\".3dl\") || url.startsWith(\"blob:\")) {\n                this._load3dlTexture();\n            }\n        }\n    }\n\n    /**\n     * Clones the color grading texture.\n     * @returns the cloned texture\n     */\n    public override clone(): ColorGradingTexture {\n        const newTexture = new ColorGradingTexture(this.url, this.getScene() || this._getEngine()!);\n\n        // Base texture\n        newTexture.level = this.level;\n\n        return newTexture;\n    }\n\n    /**\n     * Called during delayed load for textures.\n     */\n    public override delayLoad(): void {\n        if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {\n            return;\n        }\n\n        this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\n        this._texture = this._getFromCache(this.url, true);\n\n        if (!this._texture) {\n            this._loadTexture();\n        }\n    }\n\n    /**\n     * Serializes the LUT texture to json format.\n     * @returns The JSON representation of the texture\n     */\n    public override serialize(): any {\n        if (!this.name) {\n            return null;\n        }\n\n        const serializationObject: any = {};\n        serializationObject.name = this.name;\n        serializationObject.level = this.level;\n        serializationObject.customType = \"BABYLON.ColorGradingTexture\";\n\n        return serializationObject;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parses a color grading texture serialized by Babylon.\n * @param parsedTexture The texture information being parsedTexture\n * @param scene The scene to load the texture in\n * @returns A color grading texture\n */\nexport function ColorGradingTextureParse(parsedTexture: any, scene: Scene): Nullable<ColorGradingTexture> {\n    let texture = null;\n    if (parsedTexture.name && !parsedTexture.isRenderTarget) {\n        texture = new ColorGradingTexture(parsedTexture.name, scene);\n        texture.name = parsedTexture.name;\n        texture.level = parsedTexture.level;\n    }\n    return texture;\n}\n\n/**\n * Register side effects for colorGradingTexture.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterColorGradingTexture(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    ColorGradingTexture.Parse = ColorGradingTextureParse;\n\n    RegisterClass(\"BABYLON.ColorGradingTexture\", ColorGradingTexture);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { PanoramaToCubeMapTools } from \"../../Misc/HighDynamicRange/panoramaToCubemap\";\r\nimport { BaseTexture } from \"./baseTexture.pure\";\r\nimport { Texture } from \"./texture.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { TimingTools } from \"../../Misc/timingTools\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { LoadImage } from \"../../Misc/fileTools.pure\";\r\nimport { IsDocumentAvailable } from \"core/Misc/domManagement\";\r\n\r\n/**\r\n * This represents a texture coming from an equirectangular image supported by the web browser canvas.\r\n */\r\nexport class EquiRectangularCubeTexture extends BaseTexture {\r\n    /** The six faces of the cube. */\r\n    private static _FacesMapping = [\"right\", \"left\", \"up\", \"down\", \"front\", \"back\"];\r\n\r\n    private _noMipmap: boolean;\r\n    private _onLoad: Nullable<() => void> = null;\r\n    private _onError: Nullable<() => void> = null;\r\n\r\n    /** The size of the cubemap. */\r\n    private _size: number;\r\n\r\n    /** Whether to supersample the input image */\r\n    private _supersample: boolean;\r\n\r\n    /** The buffer of the image. */\r\n    private _buffer: ArrayBuffer;\r\n\r\n    /** The width of the input image. */\r\n    private _width: number;\r\n\r\n    /** The height of the input image. */\r\n    private _height: number;\r\n\r\n    /** The URL to the image. */\r\n    public url: string;\r\n\r\n    /**\r\n     * Instantiates an EquiRectangularCubeTexture from the following parameters.\r\n     * @param url The location of the image\r\n     * @param scene The scene the texture will be used in\r\n     * @param size The cubemap desired size (the more it increases the longer the generation will be)\r\n     * @param noMipmap Forces to not generate the mipmap if true\r\n     * @param gammaSpace Specifies if the texture will be used in gamma or linear space\r\n     * (the PBR material requires those textures in linear space, but the standard material would require them in Gamma space)\r\n     * @param onLoad — defines a callback called when texture is loaded\r\n     * @param onError — defines a callback called if there is an error\r\n     * @param supersample — defines if texture must be supersampled (default: false)\r\n     * @param sphericalPolynomialTargetSize — target face size for spherical polynomial computation. 0 = full resolution (default).\r\n     */\r\n    constructor(\r\n        url: string,\r\n        scene: Scene,\r\n        size: number,\r\n        noMipmap: boolean = false,\r\n        gammaSpace: boolean = true,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        supersample = false,\r\n        sphericalPolynomialTargetSize = 0\r\n    ) {\r\n        super(scene);\r\n\r\n        if (!url) {\r\n            throw new Error(\"Image url is not set\");\r\n        }\r\n\r\n        this._coordinatesMode = Texture.CUBIC_MODE;\r\n        this.name = url;\r\n        this.url = url;\r\n        this._size = size;\r\n        this._supersample = supersample;\r\n        this._noMipmap = noMipmap;\r\n        this.gammaSpace = gammaSpace;\r\n        this._onLoad = onLoad;\r\n        this._onError = onError;\r\n        this._sphericalPolynomialTargetSize = sphericalPolynomialTargetSize;\r\n\r\n        this.hasAlpha = false;\r\n        this.isCube = true;\r\n\r\n        this._texture = this._getFromCache(url, this._noMipmap, undefined, undefined, undefined, this.isCube);\r\n\r\n        if (!this._texture) {\r\n            if (!scene.useDelayedTextureLoading) {\r\n                this._loadImage(() => this._loadTexture(), this._onError);\r\n            } else {\r\n                this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n            }\r\n        } else if (onLoad) {\r\n            if (this._texture.isReady) {\r\n                TimingTools.SetImmediate(() => onLoad());\r\n            } else {\r\n                this._texture.onLoadedObservable.add(onLoad);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Load the image data, by putting the image on a canvas and extracting its buffer.\r\n     * @param loadTextureCallback\r\n     * @param onError\r\n     */\r\n    private _loadImage(loadTextureCallback: () => void, onError: Nullable<(message?: string, exception?: any) => void>): void {\r\n        const scene = this.getScene();\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        // Create texture before loading\r\n        const texture = scene\r\n            .getEngine()\r\n            .createRawCubeTexture(\r\n                null,\r\n                this._size,\r\n                Constants.TEXTUREFORMAT_RGB,\r\n                scene.getEngine().getCaps().textureFloat ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_INTEGER,\r\n                !this._noMipmap,\r\n                false,\r\n                Constants.TEXTURE_TRILINEAR_SAMPLINGMODE\r\n            );\r\n        texture.generateMipMaps = !this._noMipmap;\r\n        scene.addPendingData(texture);\r\n        texture.url = this.url;\r\n        texture.isReady = false;\r\n        scene.getEngine()._internalTexturesCache.push(texture);\r\n        this._texture = texture;\r\n\r\n        LoadImage(\r\n            this.url,\r\n            (image) => {\r\n                this._width = image.width;\r\n                this._height = image.height;\r\n                let canvas: HTMLCanvasElement | OffscreenCanvas;\r\n\r\n                if (IsDocumentAvailable()) {\r\n                    canvas = document.createElement(\"canvas\");\r\n                    canvas.width = this._width;\r\n                    canvas.height = this._height;\r\n                } else {\r\n                    // Canvas is not available in the current environment\r\n                    canvas = new OffscreenCanvas(this._width, this._height);\r\n                }\r\n\r\n                const ctx = canvas.getContext(\"2d\") as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\r\n                ctx.drawImage(image, 0, 0);\r\n\r\n                const imageData = ctx.getImageData(0, 0, image.width, image.height);\r\n                this._buffer = imageData.data.buffer as ArrayBuffer;\r\n\r\n                if ((canvas as HTMLCanvasElement).remove) {\r\n                    (canvas as HTMLCanvasElement).remove();\r\n                }\r\n                loadTextureCallback();\r\n            },\r\n            (_, e) => {\r\n                scene.removePendingData(texture);\r\n                if (onError) {\r\n                    onError(`${this.getClassName()} could not be loaded`, e);\r\n                }\r\n            },\r\n            scene ? scene.offlineProvider : null\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Convert the image buffer into a cubemap and create a CubeTexture.\r\n     */\r\n    private _loadTexture(): void {\r\n        const scene = this.getScene();\r\n        const callback = (): ArrayBufferView[] => {\r\n            const imageData = this._getFloat32ArrayFromArrayBuffer(this._buffer);\r\n\r\n            // Extract the raw linear data.\r\n            const data = PanoramaToCubeMapTools.ConvertPanoramaToCubemap(imageData, this._width, this._height, this._size, this._supersample);\r\n\r\n            const results = [];\r\n\r\n            // Push each faces.\r\n            for (let i = 0; i < 6; i++) {\r\n                const dataFace = (data as any)[EquiRectangularCubeTexture._FacesMapping[i]];\r\n                results.push(dataFace);\r\n            }\r\n\r\n            return results;\r\n        };\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n        const faceDataArrays = callback();\r\n\r\n        const texture = this._texture!;\r\n        scene.getEngine().updateRawCubeTexture(texture, faceDataArrays, texture.format, texture.type, texture.invertY);\r\n        texture.isReady = true;\r\n        scene.removePendingData(texture);\r\n\r\n        texture.onLoadedObservable.notifyObservers(texture);\r\n        texture.onLoadedObservable.clear();\r\n\r\n        if (this._onLoad) {\r\n            this._onLoad();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Convert the ArrayBuffer into a Float32Array and drop the transparency channel.\r\n     * @param buffer The ArrayBuffer that should be converted.\r\n     * @returns The buffer as Float32Array.\r\n     */\r\n    private _getFloat32ArrayFromArrayBuffer(buffer: ArrayBuffer): Float32Array {\r\n        const dataView = new DataView(buffer);\r\n        const floatImageData = new Float32Array((buffer.byteLength * 3) / 4);\r\n\r\n        let k = 0;\r\n        for (let i = 0; i < buffer.byteLength; i++) {\r\n            // We drop the transparency channel, because we do not need/want it\r\n            if ((i + 1) % 4 !== 0) {\r\n                floatImageData[k++] = dataView.getUint8(i) / 255;\r\n            }\r\n        }\r\n\r\n        return floatImageData;\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the texture useful for serialization or dynamic coding.\r\n     * @returns \"EquiRectangularCubeTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"EquiRectangularCubeTexture\";\r\n    }\r\n\r\n    /**\r\n     * Create a clone of the current EquiRectangularCubeTexture and return it.\r\n     * @returns A clone of the current EquiRectangularCubeTexture.\r\n     */\r\n    public override clone(): EquiRectangularCubeTexture {\r\n        const scene = this.getScene();\r\n        if (!scene) {\r\n            return this;\r\n        }\r\n\r\n        const newTexture = new EquiRectangularCubeTexture(this.url, scene, this._size, this._noMipmap, this.gammaSpace);\r\n\r\n        // Base texture\r\n        newTexture.level = this.level;\r\n        newTexture.wrapU = this.wrapU;\r\n        newTexture.wrapV = this.wrapV;\r\n        newTexture.coordinatesIndex = this.coordinatesIndex;\r\n        newTexture.coordinatesMode = this.coordinatesMode;\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Finish the loading sequence of a texture flagged as delayed load.\r\n     * @internal\r\n     */\r\n    public override delayLoad(): void {\r\n        if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {\r\n            return;\r\n        }\r\n\r\n        this._texture = this._getFromCache(this.url, this._noMipmap, undefined, undefined, undefined, this.isCube);\r\n        this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\r\n\r\n        if (!this._texture) {\r\n            this._loadImage(() => {\r\n                this._loadTexture();\r\n            }, this._onError);\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"core/types\";\r\nimport { type DataCursor } from \"./exrLoader.core\";\r\n\r\nexport const INT32_SIZE = 4;\r\nexport const FLOAT32_SIZE = 4;\r\nexport const INT8_SIZE = 1;\r\nexport const INT16_SIZE = 2;\r\nexport const ULONG_SIZE = 8;\r\nexport const USHORT_RANGE = 1 << 16;\r\nexport const BITMAP_SIZE = USHORT_RANGE >> 3;\r\nexport const HUF_ENCBITS = 16;\r\nexport const HUF_DECBITS = 14;\r\nexport const HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1;\r\nexport const HUF_DECSIZE = 1 << HUF_DECBITS;\r\nexport const HUF_DECMASK = HUF_DECSIZE - 1;\r\nexport const SHORT_ZEROCODE_RUN = 59;\r\nexport const LONG_ZEROCODE_RUN = 63;\r\nexport const SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;\r\n\r\nexport interface IEXRCHannel {\r\n    name: string;\r\n    pixelType: number;\r\n}\r\n\r\nexport interface IDecodeChannel {\r\n    [name: string]: number;\r\n}\r\n\r\n/**\r\n * Interface used to define the EXR header\r\n */\r\nexport interface IEXRHeader {\r\n    /** Version */\r\n    version: number;\r\n    /** Specifications */\r\n    spec: {\r\n        singleTile: boolean;\r\n        longName: boolean;\r\n        deepFormat: boolean;\r\n        multiPart: boolean;\r\n    };\r\n    /** Data window */\r\n    dataWindow: {\r\n        xMin: number;\r\n        xMax: number;\r\n        yMin: number;\r\n        yMax: number;\r\n    };\r\n    /** Channels */\r\n    channels: IEXRCHannel[];\r\n    /** Extra data */\r\n    [name: string]: any;\r\n}\r\n\r\nexport interface IEXRDecoder {\r\n    size: number;\r\n    viewer: DataView;\r\n    array: Uint8Array;\r\n    byteArray: Nullable<Float32Array | Uint16Array>;\r\n    offset: DataCursor;\r\n    width: number;\r\n    height: number;\r\n    channels: number;\r\n    channelLineOffsets: IDecodeChannel;\r\n    scanOrder: (value: number) => number;\r\n    bytesPerLine: number;\r\n    outLineWidth: number;\r\n    lines: number;\r\n    scanlineBlockSize: number;\r\n    inputSize: Nullable<number>;\r\n    type: number;\r\n    uncompress: Nullable<(decoder: IEXRDecoder) => DataView>;\r\n    getter: (dataView: DataView, offset: DataCursor) => number;\r\n    format: number;\r\n    outputChannels: number;\r\n    decodeChannels: IDecodeChannel;\r\n    blockCount: Nullable<number>;\r\n    linearSpace: boolean;\r\n    textureType: number;\r\n}\r\n","import { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport { FromHalfFloat, MaxHalfFloat, ToHalfFloat } from \"core/Misc/halfFloat\";\r\nimport { FLOAT32_SIZE, INT16_SIZE, INT32_SIZE, INT8_SIZE, ULONG_SIZE } from \"./exrLoader.interfaces\";\r\n\r\n/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\nexport enum CompressionCodes {\r\n    NO_COMPRESSION,\r\n    RLE_COMPRESSION,\r\n    ZIPS_COMPRESSION,\r\n    ZIP_COMPRESSION,\r\n    PIZ_COMPRESSION,\r\n    PXR24_COMPRESSION,\r\n}\r\n\r\nenum LineOrders {\r\n    INCREASING_Y,\r\n    DECREASING_Y,\r\n}\r\n\r\n/**\r\n * Interface used to define the cursor position in the data\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface DataCursor {\r\n    /** Curosr position */\r\n    value: number;\r\n}\r\n\r\n/**\r\n * Parse a null terminated string from the buffer\r\n * @param buffer buffer to read from\r\n * @param offset current offset in the buffer\r\n * @returns a string\r\n */\r\nexport function ParseNullTerminatedString(buffer: ArrayBufferLike, offset: DataCursor) {\r\n    const uintBuffer = new Uint8Array(buffer);\r\n    let endOffset = 0;\r\n\r\n    while (uintBuffer[offset.value + endOffset] != 0) {\r\n        endOffset += 1;\r\n    }\r\n\r\n    const stringValue = new TextDecoder().decode(uintBuffer.slice(offset.value, offset.value + endOffset));\r\n\r\n    offset.value = offset.value + endOffset + 1;\r\n\r\n    return stringValue;\r\n}\r\n\r\n/**\r\n * Parse an int32 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns an int32\r\n */\r\nexport function ParseInt32(dataView: DataView, offset: DataCursor) {\r\n    const value = dataView.getInt32(offset.value, true);\r\n\r\n    offset.value += INT32_SIZE;\r\n\r\n    return value;\r\n}\r\n\r\n/**\r\n * Parse an uint32 from the buffer\r\n * @param dataView data view to read from\r\n * @param offset offset in the data view\r\n * @returns an uint32\r\n */\r\nexport function ParseUint32(dataView: DataView, offset: DataCursor) {\r\n    const value = dataView.getUint32(offset.value, true);\r\n\r\n    offset.value += INT32_SIZE;\r\n\r\n    return value;\r\n}\r\n\r\n/**\r\n * Parse an uint8 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns an uint8\r\n */\r\nexport function ParseUint8(dataView: DataView, offset: DataCursor) {\r\n    const value = dataView.getUint8(offset.value);\r\n\r\n    offset.value += INT8_SIZE;\r\n\r\n    return value;\r\n}\r\n\r\n/**\r\n * Parse an uint16 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns an uint16\r\n */\r\nexport function ParseUint16(dataView: DataView, offset: DataCursor) {\r\n    const value = dataView.getUint16(offset.value, true);\r\n\r\n    offset.value += INT16_SIZE;\r\n\r\n    return value;\r\n}\r\n\r\n/**\r\n * Parse an uint8 from an array buffer\r\n * @param array array buffer\r\n * @param offset current offset in the data view\r\n * @returns an uint16\r\n */\r\nexport function ParseUint8Array(array: Uint8Array, offset: DataCursor) {\r\n    const value = array[offset.value];\r\n\r\n    offset.value += INT8_SIZE;\r\n\r\n    return value;\r\n}\r\n\r\n/**\r\n * Parse an int64 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns an int64\r\n */\r\nexport function ParseInt64(dataView: DataView, offset: DataCursor) {\r\n    let int;\r\n\r\n    if (\"getBigInt64\" in DataView.prototype) {\r\n        int = Number(dataView.getBigInt64(offset.value, true));\r\n    } else {\r\n        int = dataView.getUint32(offset.value + 4, true) + Number(dataView.getUint32(offset.value, true) << 32);\r\n    }\r\n\r\n    offset.value += ULONG_SIZE;\r\n\r\n    return int;\r\n}\r\n\r\n/**\r\n * Parse a float32 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns a float32\r\n */\r\nexport function ParseFloat32(dataView: DataView, offset: DataCursor) {\r\n    const value = dataView.getFloat32(offset.value, true);\r\n\r\n    offset.value += FLOAT32_SIZE;\r\n\r\n    return value;\r\n}\r\n\r\n/**\r\n * Parse a float16 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns a float16\r\n */\r\nexport function ParseFloat16(dataView: DataView, offset: DataCursor) {\r\n    return FromHalfFloat(ParseUint16(dataView, offset));\r\n}\r\n\r\n/**\r\n * Decode a float32 from the buffer\r\n * @param dataView dataview on the data\r\n * @param offset current offset in the data view\r\n * @returns a float16\r\n */\r\nexport function DecodeFloat32(dataView: DataView, offset: DataCursor) {\r\n    // EXR FLOAT channels are HDR and can exceed the half-float range. Clamp to the largest finite half\r\n    return ToHalfFloat(Clamp(ParseFloat32(dataView, offset), -MaxHalfFloat, MaxHalfFloat));\r\n}\r\n\r\nfunction ParseFixedLengthString(buffer: ArrayBufferLike, offset: DataCursor, size: number) {\r\n    const stringValue = new TextDecoder().decode(new Uint8Array(buffer).slice(offset.value, offset.value + size));\r\n\r\n    offset.value = offset.value + size;\r\n\r\n    return stringValue;\r\n}\r\n\r\nfunction ParseRational(dataView: DataView, offset: DataCursor) {\r\n    const x = ParseInt32(dataView, offset);\r\n    const y = ParseUint32(dataView, offset);\r\n\r\n    return [x, y];\r\n}\r\n\r\nfunction ParseTimecode(dataView: DataView, offset: DataCursor) {\r\n    const x = ParseUint32(dataView, offset);\r\n    const y = ParseUint32(dataView, offset);\r\n\r\n    return [x, y];\r\n}\r\n\r\nfunction ParseV2f(dataView: DataView, offset: DataCursor) {\r\n    const x = ParseFloat32(dataView, offset);\r\n    const y = ParseFloat32(dataView, offset);\r\n\r\n    return [x, y];\r\n}\r\n\r\nfunction ParseV3f(dataView: DataView, offset: DataCursor) {\r\n    const x = ParseFloat32(dataView, offset);\r\n    const y = ParseFloat32(dataView, offset);\r\n    const z = ParseFloat32(dataView, offset);\r\n\r\n    return [x, y, z];\r\n}\r\n\r\nfunction ParseChlist(dataView: DataView, offset: DataCursor, size: number) {\r\n    const startOffset = offset.value;\r\n    const channels = [];\r\n\r\n    while (offset.value < startOffset + size - 1) {\r\n        const name = ParseNullTerminatedString(dataView.buffer, offset);\r\n        const pixelType = ParseInt32(dataView, offset);\r\n        const pLinear = ParseUint8(dataView, offset);\r\n        offset.value += 3; // reserved, three chars\r\n        const xSampling = ParseInt32(dataView, offset);\r\n        const ySampling = ParseInt32(dataView, offset);\r\n\r\n        channels.push({\r\n            name: name,\r\n            pixelType: pixelType,\r\n            pLinear: pLinear,\r\n            xSampling: xSampling,\r\n            ySampling: ySampling,\r\n        });\r\n    }\r\n\r\n    offset.value += 1;\r\n\r\n    return channels;\r\n}\r\n\r\nfunction ParseChromaticities(dataView: DataView, offset: DataCursor) {\r\n    const redX = ParseFloat32(dataView, offset);\r\n    const redY = ParseFloat32(dataView, offset);\r\n    const greenX = ParseFloat32(dataView, offset);\r\n    const greenY = ParseFloat32(dataView, offset);\r\n    const blueX = ParseFloat32(dataView, offset);\r\n    const blueY = ParseFloat32(dataView, offset);\r\n    const whiteX = ParseFloat32(dataView, offset);\r\n    const whiteY = ParseFloat32(dataView, offset);\r\n\r\n    return { redX: redX, redY: redY, greenX: greenX, greenY: greenY, blueX: blueX, blueY: blueY, whiteX: whiteX, whiteY: whiteY };\r\n}\r\n\r\nfunction ParseCompression(dataView: DataView, offset: DataCursor) {\r\n    return ParseUint8(dataView, offset);\r\n}\r\n\r\nfunction ParseBox2i(dataView: DataView, offset: DataCursor) {\r\n    const xMin = ParseInt32(dataView, offset);\r\n    const yMin = ParseInt32(dataView, offset);\r\n    const xMax = ParseInt32(dataView, offset);\r\n    const yMax = ParseInt32(dataView, offset);\r\n\r\n    return { xMin: xMin, yMin: yMin, xMax: xMax, yMax: yMax };\r\n}\r\n\r\nfunction ParseLineOrder(dataView: DataView, offset: DataCursor) {\r\n    const lineOrder = ParseUint8(dataView, offset);\r\n\r\n    return LineOrders[lineOrder];\r\n}\r\n\r\n/**\r\n * Parse a value from the data view\r\n * @param dataView defines the data view to read from\r\n * @param offset defines the current offset in the data view\r\n * @param type defines the type of the value to read\r\n * @param size defines the size of the value to read\r\n * @returns the parsed value\r\n */\r\nexport function ParseValue(dataView: DataView, offset: DataCursor, type: string, size: number) {\r\n    switch (type) {\r\n        case \"string\":\r\n        case \"stringvector\":\r\n        case \"iccProfile\":\r\n            return ParseFixedLengthString(dataView.buffer, offset, size);\r\n        case \"chlist\":\r\n            return ParseChlist(dataView, offset, size);\r\n        case \"chromaticities\":\r\n            return ParseChromaticities(dataView, offset);\r\n        case \"compression\":\r\n            return ParseCompression(dataView, offset);\r\n        case \"box2i\":\r\n            return ParseBox2i(dataView, offset);\r\n        case \"lineOrder\":\r\n            return ParseLineOrder(dataView, offset);\r\n        case \"float\":\r\n            return ParseFloat32(dataView, offset);\r\n        case \"v2f\":\r\n            return ParseV2f(dataView, offset);\r\n        case \"v3f\":\r\n            return ParseV3f(dataView, offset);\r\n        case \"int\":\r\n            return ParseInt32(dataView, offset);\r\n        case \"rational\":\r\n            return ParseRational(dataView, offset);\r\n        case \"timecode\":\r\n            return ParseTimecode(dataView, offset);\r\n        case \"preview\":\r\n            offset.value += size;\r\n            return \"skipped\";\r\n        default:\r\n            offset.value += size;\r\n            return undefined;\r\n    }\r\n}\r\n\r\n/**\r\n * Revert the endianness of the data\r\n * @param source defines the source\r\n */\r\nexport function Predictor(source: Uint8Array) {\r\n    for (let t = 1; t < source.length; t++) {\r\n        const d = source[t - 1] + source[t] - 128;\r\n        source[t] = d;\r\n    }\r\n}\r\n\r\n/**\r\n * Interleave pixels\r\n * @param source defines the data source\r\n * @param out defines the output\r\n */\r\nexport function InterleaveScalar(source: Uint8Array, out: Uint8Array) {\r\n    let t1 = 0;\r\n    let t2 = Math.floor((source.length + 1) / 2);\r\n    let s = 0;\r\n    const stop = source.length - 1;\r\n\r\n    // eslint-disable-next-line no-constant-condition\r\n    while (true) {\r\n        if (s > stop) {\r\n            break;\r\n        }\r\n        out[s++] = source[t1++];\r\n\r\n        if (s > stop) {\r\n            break;\r\n        }\r\n        out[s++] = source[t2++];\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type DataCursor, ParseNullTerminatedString, ParseUint32, ParseValue } from \"./exrLoader.core\";\r\nimport { type IEXRHeader } from \"./exrLoader.interfaces\";\r\n\r\n/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\nconst EXR_MAGIC = 20000630;\r\n\r\n/**\r\n * Gets the EXR header\r\n * @param dataView defines the data view to read from\r\n * @param offset defines the offset to start reading from\r\n * @returns the header\r\n */\r\nexport function GetExrHeader(dataView: DataView, offset: DataCursor): IEXRHeader {\r\n    if (dataView.getUint32(0, true) != EXR_MAGIC) {\r\n        throw new Error(\"Incorrect OpenEXR format\");\r\n    }\r\n\r\n    const version = dataView.getUint8(4);\r\n\r\n    const specData = dataView.getUint8(5); // fullMask\r\n    const spec = {\r\n        singleTile: !!(specData & 2),\r\n        longName: !!(specData & 4),\r\n        deepFormat: !!(specData & 8),\r\n        multiPart: !!(specData & 16),\r\n    };\r\n\r\n    offset.value = 8;\r\n\r\n    const headerData: any = {};\r\n\r\n    let keepReading = true;\r\n\r\n    while (keepReading) {\r\n        const attributeName = ParseNullTerminatedString(dataView.buffer, offset);\r\n\r\n        if (!attributeName) {\r\n            keepReading = false;\r\n        } else {\r\n            const attributeType = ParseNullTerminatedString(dataView.buffer, offset);\r\n            const attributeSize = ParseUint32(dataView, offset);\r\n            const attributeValue = ParseValue(dataView, offset, attributeType, attributeSize);\r\n\r\n            if (attributeValue === undefined) {\r\n                Logger.Warn(`Unknown header attribute type ${attributeType}'.`);\r\n            } else {\r\n                headerData[attributeName] = attributeValue;\r\n            }\r\n        }\r\n    }\r\n\r\n    if ((specData & ~0x04) != 0) {\r\n        throw new Error(\"Unsupported file format\");\r\n    }\r\n\r\n    return { version: version, spec: spec, ...headerData };\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"core/types\";\r\nimport { type DataCursor, ParseUint32, ParseUint8Array } from \"./exrLoader.core\";\r\nimport { HUF_DECBITS, HUF_DECMASK, HUF_DECSIZE, HUF_ENCSIZE, LONG_ZEROCODE_RUN, SHORT_ZEROCODE_RUN, SHORTEST_LONG_RUN, USHORT_RANGE } from \"./exrLoader.interfaces\";\r\n\r\n/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\nconst NBITS = 16;\r\nconst A_OFFSET = 1 << (NBITS - 1);\r\nconst MOD_MASK = (1 << NBITS) - 1;\r\n\r\ninterface IGetBits {\r\n    l: number;\r\n    c: number;\r\n    lc: number;\r\n}\r\n\r\ninterface IGetChar {\r\n    c: number;\r\n    lc: number;\r\n}\r\n\r\n/** @internal */\r\nexport function ReverseLutFromBitmap(bitmap: Uint8Array, lut: Uint16Array) {\r\n    let k = 0;\r\n\r\n    for (let i = 0; i < USHORT_RANGE; ++i) {\r\n        if (i == 0 || bitmap[i >> 3] & (1 << (i & 7))) {\r\n            lut[k++] = i;\r\n        }\r\n    }\r\n\r\n    const n = k - 1;\r\n\r\n    while (k < USHORT_RANGE) {\r\n        lut[k++] = 0;\r\n    }\r\n\r\n    return n;\r\n}\r\n\r\nfunction HufClearDecTable(hdec: Array<any>) {\r\n    for (let i = 0; i < HUF_DECSIZE; i++) {\r\n        hdec[i] = {};\r\n        hdec[i].len = 0;\r\n        hdec[i].lit = 0;\r\n        hdec[i].p = null;\r\n    }\r\n}\r\n\r\nfunction GetBits(nBits: number, c: number, lc: number, array: Uint8Array, offset: DataCursor): IGetBits {\r\n    while (lc < nBits) {\r\n        c = (c << 8) | ParseUint8Array(array, offset);\r\n        lc += 8;\r\n    }\r\n\r\n    lc -= nBits;\r\n\r\n    return {\r\n        l: (c >> lc) & ((1 << nBits) - 1),\r\n        c,\r\n        lc,\r\n    };\r\n}\r\n\r\nfunction GetChar(c: number, lc: number, array: Uint8Array, offset: DataCursor): IGetChar {\r\n    c = (c << 8) | ParseUint8Array(array, offset);\r\n    lc += 8;\r\n\r\n    return {\r\n        c,\r\n        lc,\r\n    };\r\n}\r\n\r\nfunction GetCode(\r\n    po: number,\r\n    rlc: number,\r\n    c: number,\r\n    lc: number,\r\n    array: Uint8Array,\r\n    offset: DataCursor,\r\n    outBuffer: Uint16Array,\r\n    outBufferOffset: DataCursor,\r\n    outBufferEndOffset: number\r\n): Nullable<IGetChar> {\r\n    if (po == rlc) {\r\n        if (lc < 8) {\r\n            const gc = GetChar(c, lc, array, offset);\r\n            c = gc.c;\r\n            lc = gc.lc;\r\n        }\r\n\r\n        lc -= 8;\r\n\r\n        let cs = c >> lc;\r\n        cs = new Uint8Array([cs])[0];\r\n\r\n        if (outBufferOffset.value + cs > outBufferEndOffset) {\r\n            return null;\r\n        }\r\n\r\n        const s = outBuffer[outBufferOffset.value - 1];\r\n\r\n        while (cs-- > 0) {\r\n            outBuffer[outBufferOffset.value++] = s;\r\n        }\r\n    } else if (outBufferOffset.value < outBufferEndOffset) {\r\n        outBuffer[outBufferOffset.value++] = po;\r\n    } else {\r\n        return null;\r\n    }\r\n\r\n    return { c, lc };\r\n}\r\n\r\nconst HufTableBuffer = new Array(59);\r\n\r\nfunction HufCanonicalCodeTable(hcode: Array<any>) {\r\n    for (let i = 0; i <= 58; ++i) {\r\n        HufTableBuffer[i] = 0;\r\n    }\r\n    for (let i = 0; i < HUF_ENCSIZE; ++i) {\r\n        HufTableBuffer[hcode[i]] += 1;\r\n    }\r\n\r\n    let c = 0;\r\n\r\n    for (let i = 58; i > 0; --i) {\r\n        const nc = (c + HufTableBuffer[i]) >> 1;\r\n        HufTableBuffer[i] = c;\r\n        c = nc;\r\n    }\r\n\r\n    for (let i = 0; i < HUF_ENCSIZE; ++i) {\r\n        const l = hcode[i];\r\n        if (l > 0) {\r\n            hcode[i] = l | (HufTableBuffer[l]++ << 6);\r\n        }\r\n    }\r\n}\r\n\r\nfunction HufUnpackEncTable(array: Uint8Array, offset: DataCursor, ni: number, im: number, iM: number, hcode: Array<any>) {\r\n    const p = offset;\r\n    let c = 0;\r\n    let lc = 0;\r\n\r\n    for (; im <= iM; im++) {\r\n        if (p.value - offset.value > ni) {\r\n            return;\r\n        }\r\n\r\n        let gb = GetBits(6, c, lc, array, p);\r\n\r\n        const l = gb.l;\r\n        c = gb.c;\r\n        lc = gb.lc;\r\n\r\n        hcode[im] = l;\r\n\r\n        if (l == LONG_ZEROCODE_RUN) {\r\n            if (p.value - offset.value > ni) {\r\n                throw new Error(\"Error in HufUnpackEncTable\");\r\n            }\r\n\r\n            gb = GetBits(8, c, lc, array, p);\r\n\r\n            let zerun = gb.l + SHORTEST_LONG_RUN;\r\n            c = gb.c;\r\n            lc = gb.lc;\r\n\r\n            if (im + zerun > iM + 1) {\r\n                throw new Error(\"Error in HufUnpackEncTable\");\r\n            }\r\n\r\n            while (zerun--) {\r\n                hcode[im++] = 0;\r\n            }\r\n\r\n            im--;\r\n        } else if (l >= SHORT_ZEROCODE_RUN) {\r\n            let zerun = l - SHORT_ZEROCODE_RUN + 2;\r\n\r\n            if (im + zerun > iM + 1) {\r\n                throw new Error(\"Error in HufUnpackEncTable\");\r\n            }\r\n\r\n            while (zerun--) {\r\n                hcode[im++] = 0;\r\n            }\r\n\r\n            im--;\r\n        }\r\n    }\r\n\r\n    HufCanonicalCodeTable(hcode);\r\n}\r\n\r\nfunction HufLength(code: number) {\r\n    return code & 63;\r\n}\r\n\r\nfunction HufCode(code: number) {\r\n    return code >> 6;\r\n}\r\n\r\nfunction HufBuildDecTable(hcode: Array<any>, im: number, iM: number, hdecod: Array<any>) {\r\n    for (; im <= iM; im++) {\r\n        const c = HufCode(hcode[im]);\r\n        const l = HufLength(hcode[im]);\r\n\r\n        if (c >> l) {\r\n            throw new Error(\"Invalid table entry\");\r\n        }\r\n\r\n        if (l > HUF_DECBITS) {\r\n            const pl = hdecod[c >> (l - HUF_DECBITS)];\r\n\r\n            if (pl.len) {\r\n                throw new Error(\"Invalid table entry\");\r\n            }\r\n\r\n            pl.lit++;\r\n\r\n            if (pl.p) {\r\n                const p = pl.p;\r\n                pl.p = new Array(pl.lit);\r\n\r\n                for (let i = 0; i < pl.lit - 1; ++i) {\r\n                    pl.p[i] = p[i];\r\n                }\r\n            } else {\r\n                pl.p = new Array(1);\r\n            }\r\n\r\n            pl.p[pl.lit - 1] = im;\r\n        } else if (l) {\r\n            let plOffset = 0;\r\n\r\n            for (let i = 1 << (HUF_DECBITS - l); i > 0; i--) {\r\n                const pl = hdecod[(c << (HUF_DECBITS - l)) + plOffset];\r\n\r\n                if (pl.len || pl.p) {\r\n                    throw new Error(\"Invalid table entry\");\r\n                }\r\n\r\n                pl.len = l;\r\n                pl.lit = im;\r\n\r\n                plOffset++;\r\n            }\r\n        }\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nfunction HufDecode(\r\n    encodingTable: Array<any>,\r\n    decodingTable: Array<any>,\r\n    array: Uint8Array,\r\n    offset: DataCursor,\r\n    ni: number,\r\n    rlc: number,\r\n    no: number,\r\n    outBuffer: Uint16Array,\r\n    outOffset: DataCursor\r\n) {\r\n    let c = 0;\r\n    let lc = 0;\r\n    const outBufferEndOffset = no;\r\n    const inOffsetEnd = Math.trunc(offset.value + (ni + 7) / 8);\r\n\r\n    while (offset.value < inOffsetEnd) {\r\n        let gc = GetChar(c, lc, array, offset);\r\n\r\n        c = gc.c;\r\n        lc = gc.lc;\r\n\r\n        while (lc >= HUF_DECBITS) {\r\n            const index = (c >> (lc - HUF_DECBITS)) & HUF_DECMASK;\r\n            const pl = decodingTable[index];\r\n\r\n            if (pl.len) {\r\n                lc -= pl.len;\r\n\r\n                const gCode = GetCode(pl.lit, rlc, c, lc, array, offset, outBuffer, outOffset, outBufferEndOffset);\r\n                if (gCode) {\r\n                    c = gCode.c;\r\n                    lc = gCode.lc;\r\n                }\r\n            } else {\r\n                if (!pl.p) {\r\n                    throw new Error(\"hufDecode issues\");\r\n                }\r\n\r\n                let j;\r\n\r\n                for (j = 0; j < pl.lit; j++) {\r\n                    const l = HufLength(encodingTable[pl.p[j]]);\r\n\r\n                    while (lc < l && offset.value < inOffsetEnd) {\r\n                        gc = GetChar(c, lc, array, offset);\r\n\r\n                        c = gc.c;\r\n                        lc = gc.lc;\r\n                    }\r\n\r\n                    if (lc >= l) {\r\n                        if (HufCode(encodingTable[pl.p[j]]) == ((c >> (lc - l)) & ((1 << l) - 1))) {\r\n                            lc -= l;\r\n\r\n                            const gCode = GetCode(pl.p[j], rlc, c, lc, array, offset, outBuffer, outOffset, outBufferEndOffset);\r\n\r\n                            if (gCode) {\r\n                                c = gCode.c;\r\n                                lc = gCode.lc;\r\n                            }\r\n\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (j == pl.lit) {\r\n                    throw new Error(\"HufDecode issues\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    const i = (8 - ni) & 7;\r\n\r\n    c >>= i;\r\n    lc -= i;\r\n\r\n    while (lc > 0) {\r\n        const pl = decodingTable[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];\r\n\r\n        if (pl.len) {\r\n            lc -= pl.len;\r\n\r\n            const gCode = GetCode(pl.lit, rlc, c, lc, array, offset, outBuffer, outOffset, outBufferEndOffset);\r\n            if (gCode) {\r\n                c = gCode.c;\r\n                lc = gCode.lc;\r\n            }\r\n        } else {\r\n            throw new Error(\"HufDecode issues\");\r\n        }\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\n/** @internal */\r\nexport function HufUncompress(array: Uint8Array, dataView: DataView, offset: DataCursor, nCompressed: number, outBuffer: Uint16Array, nRaw: number) {\r\n    const outOffset: DataCursor = { value: 0 };\r\n    const initialInOffset = offset.value;\r\n\r\n    const im = ParseUint32(dataView, offset);\r\n    const iM = ParseUint32(dataView, offset);\r\n\r\n    offset.value += 4;\r\n\r\n    const nBits = ParseUint32(dataView, offset);\r\n\r\n    offset.value += 4;\r\n\r\n    if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE) {\r\n        throw new Error(\"Wrong HUF_ENCSIZE\");\r\n    }\r\n\r\n    const freq = new Array(HUF_ENCSIZE);\r\n    const hdec = new Array(HUF_DECSIZE);\r\n\r\n    HufClearDecTable(hdec);\r\n\r\n    const ni = nCompressed - (offset.value - initialInOffset);\r\n\r\n    HufUnpackEncTable(array, offset, ni, im, iM, freq);\r\n\r\n    if (nBits > 8 * (nCompressed - (offset.value - initialInOffset))) {\r\n        throw new Error(\"Wrong hufUncompress\");\r\n    }\r\n\r\n    HufBuildDecTable(freq, im, iM, hdec);\r\n\r\n    HufDecode(freq, hdec, array, offset, nBits, iM, nRaw, outBuffer, outOffset);\r\n}\r\n\r\nfunction UInt16(value: number) {\r\n    return value & 0xffff;\r\n}\r\n\r\nfunction Int16(value: number) {\r\n    const ref = UInt16(value);\r\n    return ref > 0x7fff ? ref - 0x10000 : ref;\r\n}\r\n\r\nfunction Wdec14(l: number, h: number) {\r\n    const ls = Int16(l);\r\n    const hs = Int16(h);\r\n\r\n    const hi = hs;\r\n    const ai = ls + (hi & 1) + (hi >> 1);\r\n\r\n    const as = ai;\r\n    const bs = ai - hi;\r\n\r\n    return { a: as, b: bs };\r\n}\r\n\r\nfunction Wdec16(l: number, h: number) {\r\n    const m = UInt16(l);\r\n    const d = UInt16(h);\r\n\r\n    const bb = (m - (d >> 1)) & MOD_MASK;\r\n    const aa = (d + bb - A_OFFSET) & MOD_MASK;\r\n\r\n    return { a: aa, b: bb };\r\n}\r\n\r\n/** @internal */\r\nexport function Wav2Decode(buffer: Uint16Array, j: number, nx: number, ox: number, ny: number, oy: number, mx: number) {\r\n    const w14 = mx < 1 << 14;\r\n    const n = nx > ny ? ny : nx;\r\n    let p = 1;\r\n    let p2;\r\n    let py;\r\n\r\n    while (p <= n) {\r\n        p <<= 1;\r\n    }\r\n\r\n    p >>= 1;\r\n    p2 = p;\r\n    p >>= 1;\r\n\r\n    while (p >= 1) {\r\n        py = 0;\r\n        const ey = py + oy * (ny - p2);\r\n        const oy1 = oy * p;\r\n        const oy2 = oy * p2;\r\n        const ox1 = ox * p;\r\n        const ox2 = ox * p2;\r\n        let i00, i01, i10, i11;\r\n\r\n        for (; py <= ey; py += oy2) {\r\n            let px = py;\r\n            const ex = py + ox * (nx - p2);\r\n\r\n            for (; px <= ex; px += ox2) {\r\n                const p01 = px + ox1;\r\n                const p10 = px + oy1;\r\n                const p11 = p10 + ox1;\r\n\r\n                if (w14) {\r\n                    let result = Wdec14(buffer[px + j], buffer[p10 + j]);\r\n\r\n                    i00 = result.a;\r\n                    i10 = result.b;\r\n\r\n                    result = Wdec14(buffer[p01 + j], buffer[p11 + j]);\r\n\r\n                    i01 = result.a;\r\n                    i11 = result.b;\r\n\r\n                    result = Wdec14(i00, i01);\r\n\r\n                    buffer[px + j] = result.a;\r\n                    buffer[p01 + j] = result.b;\r\n\r\n                    result = Wdec14(i10, i11);\r\n\r\n                    buffer[p10 + j] = result.a;\r\n                    buffer[p11 + j] = result.b;\r\n                } else {\r\n                    let result = Wdec16(buffer[px + j], buffer[p10 + j]);\r\n\r\n                    i00 = result.a;\r\n                    i10 = result.b;\r\n\r\n                    result = Wdec16(buffer[p01 + j], buffer[p11 + j]);\r\n\r\n                    i01 = result.a;\r\n                    i11 = result.b;\r\n\r\n                    result = Wdec16(i00, i01);\r\n\r\n                    buffer[px + j] = result.a;\r\n                    buffer[p01 + j] = result.b;\r\n\r\n                    result = Wdec16(i10, i11);\r\n\r\n                    buffer[p10 + j] = result.a;\r\n                    buffer[p11 + j] = result.b;\r\n                }\r\n            }\r\n\r\n            if (nx & p) {\r\n                const p10 = px + oy1;\r\n                let result;\r\n                if (w14) {\r\n                    result = Wdec14(buffer[px + j], buffer[p10 + j]);\r\n                } else {\r\n                    result = Wdec16(buffer[px + j], buffer[p10 + j]);\r\n                }\r\n\r\n                i00 = result.a;\r\n                buffer[p10 + j] = result.b;\r\n\r\n                buffer[px + j] = i00;\r\n            }\r\n        }\r\n\r\n        if (ny & p) {\r\n            let px = py;\r\n            const ex = py + ox * (nx - p2);\r\n\r\n            for (; px <= ex; px += ox2) {\r\n                const p01 = px + ox1;\r\n                let result;\r\n\r\n                if (w14) {\r\n                    result = Wdec14(buffer[px + j], buffer[p01 + j]);\r\n                } else {\r\n                    result = Wdec16(buffer[px + j], buffer[p01 + j]);\r\n                }\r\n\r\n                i00 = result.a;\r\n                buffer[p01 + j] = result.b;\r\n\r\n                buffer[px + j] = i00;\r\n            }\r\n        }\r\n\r\n        p2 = p;\r\n        p >>= 1;\r\n    }\r\n\r\n    return py;\r\n}\r\n\r\n/** @internal */\r\nexport function ApplyLut(lut: Uint16Array, data: Uint16Array, nData: number) {\r\n    for (let i = 0; i < nData; ++i) {\r\n        data[i] = lut[data[i]];\r\n    }\r\n}\r\n","/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\n/** @internal */\r\nexport function DecodeRunLength(source: ArrayBufferLike) {\r\n    let size = source.byteLength;\r\n    const out = [];\r\n    let p = 0;\r\n\r\n    const reader = new DataView(source);\r\n\r\n    while (size > 0) {\r\n        const l = reader.getInt8(p++);\r\n\r\n        if (l < 0) {\r\n            const count = -l;\r\n            size -= count + 1;\r\n\r\n            for (let i = 0; i < count; i++) {\r\n                out.push(reader.getUint8(p++));\r\n            }\r\n        } else {\r\n            const count = l;\r\n            size -= 2;\r\n\r\n            const value = reader.getUint8(p++);\r\n\r\n            for (let i = 0; i < count + 1; i++) {\r\n                out.push(value);\r\n            }\r\n        }\r\n    }\r\n\r\n    return out;\r\n}\r\n","import { ApplyLut, HufUncompress, ReverseLutFromBitmap, Wav2Decode } from \"./exrLoader.compression.huf\";\r\nimport { DecodeRunLength } from \"./exrLoader.compression.rle\";\r\nimport { InterleaveScalar, ParseUint16, ParseUint32, ParseUint8, Predictor } from \"./exrLoader.core\";\r\nimport { BITMAP_SIZE, INT16_SIZE, USHORT_RANGE, type IEXRDecoder } from \"./exrLoader.interfaces\";\r\n\r\n/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\n// FFlate access\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare const fflate: any;\r\n\r\n/**\r\n * No compression\r\n * @param decoder defines the decoder to use\r\n * @returns a decompressed data view\r\n */\r\nexport function UncompressRAW(decoder: IEXRDecoder): DataView {\r\n    return new DataView(decoder.array.buffer, decoder.offset.value, decoder.size);\r\n}\r\n\r\n/**\r\n * RLE compression\r\n * @param decoder defines the decoder to use\r\n * @returns a decompressed data view\r\n */\r\nexport function UncompressRLE(decoder: IEXRDecoder): DataView {\r\n    const compressed = decoder.viewer.buffer.slice(decoder.offset.value, decoder.offset.value + decoder.size);\r\n\r\n    const rawBuffer = new Uint8Array(DecodeRunLength(compressed));\r\n    const tmpBuffer = new Uint8Array(rawBuffer.length);\r\n\r\n    Predictor(rawBuffer);\r\n\r\n    InterleaveScalar(rawBuffer, tmpBuffer);\r\n\r\n    return new DataView(tmpBuffer.buffer);\r\n}\r\n\r\n/**\r\n * Zip compression\r\n * @param decoder defines the decoder to use\r\n * @returns a decompressed data view\r\n */\r\nexport function UncompressZIP(decoder: IEXRDecoder): DataView {\r\n    const compressed = decoder.array.slice(decoder.offset.value, decoder.offset.value + decoder.size);\r\n\r\n    const rawBuffer = fflate.unzlibSync(compressed);\r\n    const tmpBuffer = new Uint8Array(rawBuffer.length);\r\n\r\n    Predictor(rawBuffer);\r\n\r\n    InterleaveScalar(rawBuffer, tmpBuffer);\r\n\r\n    return new DataView(tmpBuffer.buffer);\r\n}\r\n\r\n/**\r\n * PXR compression\r\n * @param decoder defines the decoder to use\r\n * @returns a decompressed data view\r\n */\r\nexport function UncompressPXR(decoder: IEXRDecoder): DataView {\r\n    const compressed = decoder.array.slice(decoder.offset.value, decoder.offset.value + decoder.size);\r\n\r\n    const rawBuffer = fflate.unzlibSync(compressed);\r\n\r\n    const sz = decoder.lines * decoder.channels * decoder.width;\r\n    const tmpBuffer = decoder.type == 1 ? new Uint16Array(sz) : new Uint32Array(sz);\r\n\r\n    let tmpBufferEnd = 0;\r\n    let writePtr = 0;\r\n    const ptr = new Array(4);\r\n\r\n    for (let y = 0; y < decoder.lines; y++) {\r\n        for (let c = 0; c < decoder.channels; c++) {\r\n            let pixel = 0;\r\n\r\n            switch (decoder.type) {\r\n                case 1:\r\n                    ptr[0] = tmpBufferEnd;\r\n                    ptr[1] = ptr[0] + decoder.width;\r\n                    tmpBufferEnd = ptr[1] + decoder.width;\r\n\r\n                    for (let j = 0; j < decoder.width; ++j) {\r\n                        const diff = (rawBuffer[ptr[0]++] << 8) | rawBuffer[ptr[1]++];\r\n\r\n                        pixel += diff;\r\n\r\n                        tmpBuffer[writePtr] = pixel;\r\n                        writePtr++;\r\n                    }\r\n\r\n                    break;\r\n\r\n                case 2:\r\n                    ptr[0] = tmpBufferEnd;\r\n                    ptr[1] = ptr[0] + decoder.width;\r\n                    ptr[2] = ptr[1] + decoder.width;\r\n                    tmpBufferEnd = ptr[2] + decoder.width;\r\n\r\n                    for (let j = 0; j < decoder.width; ++j) {\r\n                        const diff = (rawBuffer[ptr[0]++] << 24) | (rawBuffer[ptr[1]++] << 16) | (rawBuffer[ptr[2]++] << 8);\r\n\r\n                        pixel += diff;\r\n\r\n                        tmpBuffer[writePtr] = pixel;\r\n                        writePtr++;\r\n                    }\r\n\r\n                    break;\r\n            }\r\n        }\r\n    }\r\n\r\n    return new DataView(tmpBuffer.buffer);\r\n}\r\n\r\n/**\r\n * PIZ compression\r\n * @param decoder defines the decoder to use\r\n * @returns a decompressed data view\r\n */\r\nexport function UncompressPIZ(decoder: IEXRDecoder): DataView {\r\n    const inDataView = decoder.viewer;\r\n    const inOffset = { value: decoder.offset.value };\r\n\r\n    const outBuffer = new Uint16Array(decoder.width * decoder.scanlineBlockSize * (decoder.channels * decoder.type));\r\n    const bitmap = new Uint8Array(BITMAP_SIZE);\r\n\r\n    // Setup channel info\r\n    let outBufferEnd = 0;\r\n    const pizChannelData = new Array(decoder.channels);\r\n    for (let i = 0; i < decoder.channels; i++) {\r\n        pizChannelData[i] = {};\r\n        pizChannelData[i][\"start\"] = outBufferEnd;\r\n        pizChannelData[i][\"end\"] = pizChannelData[i][\"start\"];\r\n        pizChannelData[i][\"nx\"] = decoder.width;\r\n        pizChannelData[i][\"ny\"] = decoder.lines;\r\n        pizChannelData[i][\"size\"] = decoder.type;\r\n\r\n        outBufferEnd += pizChannelData[i].nx * pizChannelData[i].ny * pizChannelData[i].size;\r\n    }\r\n\r\n    // Read range compression data\r\n    const minNonZero = ParseUint16(inDataView, inOffset);\r\n    const maxNonZero = ParseUint16(inDataView, inOffset);\r\n\r\n    if (maxNonZero >= BITMAP_SIZE) {\r\n        throw new Error(\"Wrong PIZ_COMPRESSION BITMAP_SIZE\");\r\n    }\r\n\r\n    if (minNonZero <= maxNonZero) {\r\n        for (let i = 0; i < maxNonZero - minNonZero + 1; i++) {\r\n            bitmap[i + minNonZero] = ParseUint8(inDataView, inOffset);\r\n        }\r\n    }\r\n\r\n    // Reverse LUT\r\n    const lut = new Uint16Array(USHORT_RANGE);\r\n    const maxValue = ReverseLutFromBitmap(bitmap, lut);\r\n\r\n    const length = ParseUint32(inDataView, inOffset);\r\n\r\n    // Huffman decoding\r\n    HufUncompress(decoder.array, inDataView, inOffset, length, outBuffer, outBufferEnd);\r\n\r\n    // Wavelet decoding\r\n    for (let i = 0; i < decoder.channels; ++i) {\r\n        const cd = pizChannelData[i];\r\n\r\n        for (let j = 0; j < pizChannelData[i].size; ++j) {\r\n            Wav2Decode(outBuffer, cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size, maxValue);\r\n        }\r\n    }\r\n\r\n    // Expand the pixel data to their original range\r\n    ApplyLut(lut, outBuffer, outBufferEnd);\r\n\r\n    // Rearrange the pixel data into the format expected by the caller.\r\n    let tmpOffset = 0;\r\n    const tmpBuffer = new Uint8Array(outBuffer.buffer.byteLength);\r\n    for (let y = 0; y < decoder.lines; y++) {\r\n        for (let c = 0; c < decoder.channels; c++) {\r\n            const cd = pizChannelData[c];\r\n\r\n            const n = cd.nx * cd.size;\r\n            const cp = new Uint8Array(outBuffer.buffer, cd.end * INT16_SIZE, n * INT16_SIZE);\r\n\r\n            tmpBuffer.set(cp, tmpOffset);\r\n            tmpOffset += n * INT16_SIZE;\r\n            cd.end += n;\r\n        }\r\n    }\r\n\r\n    return new DataView(tmpBuffer.buffer);\r\n}\r\n","export enum EXROutputType {\r\n    Float = 0,\r\n    HalfFloat = 1,\r\n}\r\n\r\n/**\r\n * Class used to store configuration of the exr loader\r\n */\r\nexport class ExrLoaderGlobalConfiguration {\r\n    /**\r\n     * Defines the default output type to use (Half float by default)\r\n     */\r\n    public static DefaultOutputType: EXROutputType = EXROutputType.HalfFloat;\r\n    /**\r\n     * Url to use to load the fflate library (for zip decompression)\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public static FFLATEUrl = \"https://unpkg.com/fflate@0.8.2\";\r\n}\r\n","import { type DataCursor, CompressionCodes, DecodeFloat32, ParseFloat16, ParseFloat32, ParseInt32, ParseInt64, ParseUint16, ParseUint32 } from \"./exrLoader.core\";\r\nimport { UncompressPIZ, UncompressPXR, UncompressRAW, UncompressRLE, UncompressZIP } from \"./exrLoader.compression\";\r\nimport { FLOAT32_SIZE, INT16_SIZE, type IEXRDecoder, type IEXRHeader } from \"./exrLoader.interfaces\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\nimport { ExrLoaderGlobalConfiguration, EXROutputType } from \"./exrLoader.configuration\";\r\n\r\n/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\n/**\r\n * Create a decoder for the exr file\r\n * @param header header of the exr file\r\n * @param dataView dataview of the exr file\r\n * @param offset current offset\r\n * @param outputType expected output type (float or half float)\r\n * @returns a promise that resolves with the decoder\r\n */\r\nexport async function CreateDecoderAsync(header: IEXRHeader, dataView: DataView, offset: DataCursor, outputType: EXROutputType): Promise<IEXRDecoder> {\r\n    const decoder: IEXRDecoder = {\r\n        size: 0,\r\n        viewer: dataView,\r\n        array: new Uint8Array(dataView.buffer),\r\n        offset: offset,\r\n        width: header.dataWindow.xMax - header.dataWindow.xMin + 1,\r\n        height: header.dataWindow.yMax - header.dataWindow.yMin + 1,\r\n        channels: header.channels.length,\r\n        channelLineOffsets: {},\r\n        scanOrder: () => 0,\r\n        bytesPerLine: 0,\r\n        outLineWidth: 0,\r\n        lines: 0,\r\n        scanlineBlockSize: 0,\r\n        inputSize: null,\r\n        type: 0,\r\n        uncompress: null,\r\n        getter: () => 0,\r\n        format: Constants.TEXTUREFORMAT_RGBA,\r\n        outputChannels: 0,\r\n        decodeChannels: {},\r\n        blockCount: null,\r\n        byteArray: null,\r\n        linearSpace: false,\r\n        textureType: 0,\r\n    };\r\n\r\n    switch (header.compression) {\r\n        case CompressionCodes.NO_COMPRESSION:\r\n            decoder.lines = 1;\r\n            decoder.uncompress = UncompressRAW;\r\n            break;\r\n\r\n        case CompressionCodes.RLE_COMPRESSION:\r\n            decoder.lines = 1;\r\n            decoder.uncompress = UncompressRLE;\r\n            break;\r\n\r\n        case CompressionCodes.ZIPS_COMPRESSION:\r\n            decoder.lines = 1;\r\n            decoder.uncompress = UncompressZIP;\r\n            await Tools.LoadScriptAsync(ExrLoaderGlobalConfiguration.FFLATEUrl);\r\n            break;\r\n\r\n        case CompressionCodes.ZIP_COMPRESSION:\r\n            decoder.lines = 16;\r\n            decoder.uncompress = UncompressZIP;\r\n            await Tools.LoadScriptAsync(ExrLoaderGlobalConfiguration.FFLATEUrl);\r\n            break;\r\n\r\n        case CompressionCodes.PIZ_COMPRESSION:\r\n            decoder.lines = 32;\r\n            decoder.uncompress = UncompressPIZ;\r\n            break;\r\n\r\n        case CompressionCodes.PXR24_COMPRESSION:\r\n            decoder.lines = 16;\r\n            decoder.uncompress = UncompressPXR;\r\n            await Tools.LoadScriptAsync(ExrLoaderGlobalConfiguration.FFLATEUrl);\r\n            break;\r\n\r\n        default:\r\n            throw new Error(CompressionCodes[header.compression] + \" is unsupported\");\r\n    }\r\n\r\n    decoder.scanlineBlockSize = decoder.lines;\r\n\r\n    const channels: {\r\n        [key: string]: boolean;\r\n    } = {};\r\n    for (const channel of header.channels) {\r\n        switch (channel.name) {\r\n            case \"R\":\r\n            case \"G\":\r\n            case \"B\":\r\n            case \"A\":\r\n                channels[channel.name] = true;\r\n                decoder.type = channel.pixelType;\r\n                break;\r\n            case \"Y\":\r\n                channels[channel.name] = true;\r\n                decoder.type = channel.pixelType;\r\n                // Note: 'Y' is deprecated in OpenGL 3.0+; prefer 'R' for single-channel EXRs.\r\n                break;\r\n            default:\r\n                // Skip unsupported channels\r\n                break;\r\n        }\r\n    }\r\n\r\n    // RGB images will be converted to RGBA format, preventing software emulation in select devices.\r\n    let fillAlpha = false;\r\n\r\n    if (channels.R && channels.G && channels.B && channels.A) {\r\n        decoder.outputChannels = 4;\r\n        decoder.decodeChannels = { R: 0, G: 1, B: 2, A: 3 };\r\n    } else if (channels.R && channels.G && channels.B) {\r\n        fillAlpha = true;\r\n        decoder.outputChannels = 4;\r\n        decoder.decodeChannels = { R: 0, G: 1, B: 2, A: 3 };\r\n    } else if (channels.R && channels.G) {\r\n        decoder.outputChannels = 2;\r\n        decoder.decodeChannels = { R: 0, G: 1 };\r\n    } else if (channels.R) {\r\n        decoder.outputChannels = 1;\r\n        decoder.decodeChannels = { R: 0 };\r\n    } else if (channels.Y) {\r\n        decoder.outputChannels = 1;\r\n        decoder.decodeChannels = { Y: 0 };\r\n        // Note: Supporting 'Y' channel for legacy compatibility; prefer 'R' in new EXRs.\r\n    } else {\r\n        throw new Error(\"EXRLoader.parse: file contains unsupported data channels.\");\r\n    }\r\n\r\n    if (decoder.type === 1) {\r\n        // half\r\n        switch (outputType) {\r\n            case EXROutputType.Float:\r\n                decoder.getter = ParseFloat16;\r\n                decoder.inputSize = INT16_SIZE;\r\n                break;\r\n\r\n            case EXROutputType.HalfFloat:\r\n                decoder.getter = ParseUint16;\r\n                decoder.inputSize = INT16_SIZE;\r\n                break;\r\n        }\r\n    } else if (decoder.type === 2) {\r\n        // float\r\n        switch (outputType) {\r\n            case EXROutputType.Float:\r\n                decoder.getter = ParseFloat32;\r\n                decoder.inputSize = FLOAT32_SIZE;\r\n                break;\r\n\r\n            case EXROutputType.HalfFloat:\r\n                decoder.getter = DecodeFloat32;\r\n                decoder.inputSize = FLOAT32_SIZE;\r\n        }\r\n    } else {\r\n        throw new Error(\"Unsupported pixelType \" + decoder.type + \" for \" + header.compression);\r\n    }\r\n\r\n    decoder.blockCount = decoder.height / decoder.scanlineBlockSize;\r\n\r\n    for (let i = 0; i < decoder.blockCount; i++) {\r\n        ParseInt64(dataView, offset); // scanlineOffset\r\n    }\r\n\r\n    // we should be passed the scanline offset table, ready to start reading pixel data.\r\n    const size = decoder.width * decoder.height * decoder.outputChannels;\r\n\r\n    switch (outputType) {\r\n        case EXROutputType.Float:\r\n            decoder.byteArray = new Float32Array(size);\r\n            decoder.textureType = Constants.TEXTURETYPE_FLOAT;\r\n\r\n            // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten\r\n            if (fillAlpha) {\r\n                decoder.byteArray.fill(1, 0, size);\r\n            }\r\n\r\n            break;\r\n\r\n        case EXROutputType.HalfFloat:\r\n            decoder.byteArray = new Uint16Array(size);\r\n            decoder.textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n\r\n            if (fillAlpha) {\r\n                decoder.byteArray.fill(0x3c00, 0, size); // Uint16Array holds half float data, 0x3C00 is 1\r\n            }\r\n\r\n            break;\r\n\r\n        default:\r\n            throw new Error(\"Unsupported type: \" + outputType);\r\n    }\r\n\r\n    let byteOffset = 0;\r\n    for (const channel of header.channels) {\r\n        if (decoder.decodeChannels[channel.name] !== undefined) {\r\n            decoder.channelLineOffsets[channel.name] = byteOffset * decoder.width;\r\n        }\r\n\r\n        byteOffset += channel.pixelType * 2;\r\n    }\r\n\r\n    decoder.bytesPerLine = decoder.width * byteOffset;\r\n    decoder.outLineWidth = decoder.width * decoder.outputChannels;\r\n\r\n    if (header.lineOrder === \"INCREASING_Y\") {\r\n        decoder.scanOrder = (y) => y;\r\n    } else {\r\n        decoder.scanOrder = (y) => decoder.height - 1 - y;\r\n    }\r\n\r\n    if (decoder.outputChannels == 4) {\r\n        decoder.format = Constants.TEXTUREFORMAT_RGBA;\r\n        decoder.linearSpace = true;\r\n    } else {\r\n        decoder.format = Constants.TEXTUREFORMAT_R;\r\n        decoder.linearSpace = false;\r\n    }\r\n\r\n    return decoder;\r\n}\r\n\r\n/**\r\n * Scan the data of the exr file\r\n * @param decoder decoder to use\r\n * @param header header of the exr file\r\n * @param dataView dataview of the exr file\r\n * @param offset current offset\r\n */\r\nexport function ScanData(decoder: IEXRDecoder, header: IEXRHeader, dataView: DataView, offset: DataCursor): void {\r\n    const tmpOffset = { value: 0 };\r\n\r\n    for (let scanlineBlockIdx = 0; scanlineBlockIdx < decoder.height / decoder.scanlineBlockSize; scanlineBlockIdx++) {\r\n        const line = ParseInt32(dataView, offset) - header.dataWindow.yMin; // line_no\r\n        decoder.size = ParseUint32(dataView, offset); // data_len\r\n        decoder.lines = line + decoder.scanlineBlockSize > decoder.height ? decoder.height - line : decoder.scanlineBlockSize;\r\n\r\n        const isCompressed = decoder.size < decoder.lines * decoder.bytesPerLine;\r\n        const viewer = isCompressed && decoder.uncompress ? decoder.uncompress(decoder) : UncompressRAW(decoder);\r\n\r\n        offset.value += decoder.size;\r\n\r\n        for (let lineY = 0; lineY < decoder.scanlineBlockSize; lineY++) {\r\n            const scanY = scanlineBlockIdx * decoder.scanlineBlockSize;\r\n            const trueY = lineY + decoder.scanOrder(scanY);\r\n            if (trueY >= decoder.height) {\r\n                continue;\r\n            }\r\n\r\n            const lineOffset = lineY * decoder.bytesPerLine;\r\n            const outLineOffset = (decoder.height - 1 - trueY) * decoder.outLineWidth;\r\n\r\n            for (let channelID = 0; channelID < decoder.channels; channelID++) {\r\n                const name = header.channels[channelID].name;\r\n                const lOff = decoder.channelLineOffsets[name];\r\n                const cOff = decoder.decodeChannels[name];\r\n\r\n                if (cOff === undefined) {\r\n                    continue;\r\n                }\r\n\r\n                tmpOffset.value = lineOffset + lOff;\r\n\r\n                for (let x = 0; x < decoder.width; x++) {\r\n                    const outIndex = outLineOffset + x * decoder.outputChannels + cOff;\r\n                    if (decoder.byteArray) {\r\n                        decoder.byteArray[outIndex] = decoder.getter(viewer, tmpOffset);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"core/types\";\r\nimport { type InternalTexture } from \"../internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { GetExrHeader } from \"./EXR/exrLoader.header\";\r\nimport { CreateDecoderAsync, ScanData } from \"./EXR/exrLoader.decoder\";\r\nimport { ExrLoaderGlobalConfiguration, EXROutputType } from \"./EXR/exrLoader.configuration\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Inspired by https://github.com/sciecode/three.js/blob/dev/examples/jsm/loaders/EXRLoader.js\r\n * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita\r\n * implementation.\r\n */\r\n\r\n// /*\r\n// Copyright (c) 2014 - 2017, Syoyo Fujita\r\n// All rights reserved.\r\n\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are met:\r\n//     * Redistributions of source code must retain the above copyright\r\n//       notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above copyright\r\n//       notice, this list of conditions and the following disclaimer in the\r\n//       documentation and/or other materials provided with the distribution.\r\n//     * Neither the name of the Syoyo Fujita nor the\r\n//       names of its contributors may be used to endorse or promote products\r\n//       derived from this software without specific prior written permission.\r\n\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\n// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// */\r\n\r\n// // TinyEXR contains some OpenEXR code, which is licensed under ------------\r\n\r\n// ///////////////////////////////////////////////////////////////////////////\r\n// //\r\n// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas\r\n// // Digital Ltd. LLC\r\n// //\r\n// // All rights reserved.\r\n// //\r\n// // Redistribution and use in source and binary forms, with or without\r\n// // modification, are permitted provided that the following conditions are\r\n// // met:\r\n// // *       Redistributions of source code must retain the above copyright\r\n// // notice, this list of conditions and the following disclaimer.\r\n// // *       Redistributions in binary form must reproduce the above\r\n// // copyright notice, this list of conditions and the following disclaimer\r\n// // in the documentation and/or other materials provided with the\r\n// // distribution.\r\n// // *       Neither the name of Industrial Light & Magic nor the names of\r\n// // its contributors may be used to endorse or promote products derived\r\n// // from this software without specific prior written permission.\r\n// //\r\n// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n// //\r\n// ///////////////////////////////////////////////////////////////////////////\r\n\r\n// // End of OpenEXR license -------------------------------------------------\r\n\r\n/**\r\n * Loader for .exr file format\r\n * @see [PIZ compression](https://playground.babylonjs.com/#4RN0VF#151)\r\n * @see [ZIP compression](https://playground.babylonjs.com/#4RN0VF#146)\r\n * @see [RLE compression](https://playground.babylonjs.com/#4RN0VF#149)\r\n * @see [PXR24 compression](https://playground.babylonjs.com/#4RN0VF#150)\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _ExrTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     * @param _data contains the texture data\r\n     * @param _texture defines the BabylonJS internal texture\r\n     * @param _createPolynomials will be true if polynomials have been requested\r\n     * @param _onLoad defines the callback to trigger once the texture is ready\r\n     * @param _onError defines the callback to trigger in case of error\r\n     * Cube texture are not supported by .exr files\r\n     */\r\n    public loadCubeData(\r\n        _data: ArrayBufferView | ArrayBufferView[],\r\n        _texture: InternalTexture,\r\n        _createPolynomials: boolean,\r\n        _onLoad: Nullable<(data?: any) => void>,\r\n        _onError: Nullable<(message?: string, exception?: any) => void>\r\n    ): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \".exr not supported in Cube.\";\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, failedLoading?: boolean) => void\r\n    ) {\r\n        const dataView = new DataView(data.buffer);\r\n\r\n        const offset = { value: 0 };\r\n        const header = GetExrHeader(dataView, offset);\r\n        CreateDecoderAsync(header, dataView, offset, ExrLoaderGlobalConfiguration.DefaultOutputType)\r\n            // eslint-disable-next-line github/no-then\r\n            .then((decoder) => {\r\n                ScanData(decoder, header, dataView, offset);\r\n\r\n                // Updating texture\r\n                const width = header.dataWindow.xMax - header.dataWindow.xMin + 1;\r\n                const height = header.dataWindow.yMax - header.dataWindow.yMin + 1;\r\n                callback(width, height, texture.generateMipMaps, false, () => {\r\n                    const engine = texture.getEngine();\r\n                    texture.format = header.format;\r\n                    texture.type = decoder.textureType;\r\n                    texture.invertY = false;\r\n                    texture._gammaSpace = !header.linearSpace;\r\n                    if (decoder.byteArray) {\r\n                        engine._uploadDataToTextureDirectly(texture, decoder.byteArray, 0, 0, undefined, true);\r\n                    }\r\n                });\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .catch((error) => {\r\n                Logger.Error(\"Failed to load EXR texture: \", error);\r\n            });\r\n    }\r\n}\r\n\r\n/**\r\n * Read the EXR data from an ArrayBufferView asynchronously.\r\n * @param data ArrayBufferView containing the EXR data\r\n * @returns An object containing the width, height, and data of the EXR texture.\r\n */\r\nexport async function ReadExrDataAsync(data: ArrayBuffer): Promise<{ width: number; height: number; data: Nullable<Float32Array> }> {\r\n    const dataView = new DataView(data);\r\n\r\n    const offset = { value: 0 };\r\n    const header = GetExrHeader(dataView, offset);\r\n    try {\r\n        const decoder = await CreateDecoderAsync(header, dataView, offset, EXROutputType.Float);\r\n        ScanData(decoder, header, dataView, offset);\r\n\r\n        if (!decoder.byteArray) {\r\n            Logger.Error(\"Failed to decode EXR data: No byte array available.\");\r\n            return { width: 0, height: 0, data: null };\r\n        }\r\n\r\n        return {\r\n            width: header.dataWindow.xMax - header.dataWindow.xMin + 1,\r\n            height: header.dataWindow.yMax - header.dataWindow.yMin + 1,\r\n            data: new Float32Array(decoder.byteArray),\r\n        };\r\n    } catch (error) {\r\n        Logger.Error(\"Failed to load EXR data: \", error);\r\n    }\r\n\r\n    return { width: 0, height: 0, data: null };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { EnvCubeTexture } from \"./envCubeTexture.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { PanoramaToCubeMapTools, type CubeMapInfo } from \"../../Misc/HighDynamicRange/panoramaToCubemap\";\r\n\r\nimport { ReadExrDataAsync } from \"./Loaders/exrTextureLoader\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * This represents a texture coming from an EXR input.\r\n */\r\nexport class EXRCubeTexture extends EnvCubeTexture {\r\n    /**\r\n     * Instantiates an HDRTexture from the following parameters.\r\n     *\r\n     * @param url The location of the HDR raw data (Panorama stored in RGBE format)\r\n     * @param sceneOrEngine The scene or engine the texture will be used in\r\n     * @param size The cubemap desired size (the more it increases the longer the generation will be)\r\n     * @param noMipmap Forces to not generate the mipmap if true\r\n     * @param generateHarmonics Specifies whether you want to extract the polynomial harmonics during the generation process\r\n     * @param gammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)\r\n     * @param prefilterOnLoad Prefilters HDR texture to allow use of this texture as a PBR reflection texture.\r\n     * @param onLoad on success callback function\r\n     * @param onError on error callback function\r\n     * @param supersample Defines if texture must be supersampled (default: false)\r\n     * @param prefilterIrradianceOnLoad Prefilters HDR texture to allow use of this texture for irradiance lighting.\r\n     * @param prefilterUsingCdf Defines if the prefiltering should be done using a CDF instead of the default approach.\r\n     */\r\n    constructor(\r\n        url: string,\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        size: number,\r\n        noMipmap = false,\r\n        generateHarmonics = true,\r\n        gammaSpace = false,\r\n        prefilterOnLoad = false,\r\n        onLoad: Nullable<() => void> = null,\r\n        onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n        supersample = false,\r\n        prefilterIrradianceOnLoad = false,\r\n        prefilterUsingCdf = false\r\n    ) {\r\n        super(url, sceneOrEngine, size, noMipmap, generateHarmonics, gammaSpace, prefilterOnLoad, onLoad, onError, supersample, prefilterIrradianceOnLoad, prefilterUsingCdf);\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the texture useful for serialization or dynamic coding.\r\n     * @returns \"EXRCubeTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"EXRCubeTexture\";\r\n    }\r\n\r\n    /**\r\n     * Convert the raw data from the server into cubemap faces\r\n     * @param buffer The buffer containing the texture data\r\n     * @param size The cubemap face size\r\n     * @param supersample Defines if texture must be supersampled\r\n     * @returns The cube map data\r\n     */\r\n    protected async _getCubeMapTextureDataAsync(buffer: ArrayBuffer, size: number, supersample: boolean): Promise<CubeMapInfo> {\r\n        const exrData = await ReadExrDataAsync(buffer);\r\n        if (!exrData.data) {\r\n            throw new Error(\"EXR data could not be decoded.\");\r\n        }\r\n\r\n        const cubeMapData = PanoramaToCubeMapTools.ConvertPanoramaToCubemap(exrData.data, exrData.width, exrData.height, size, supersample, false);\r\n        return cubeMapData;\r\n    }\r\n\r\n    protected _instantiateClone(): this {\r\n        return new EXRCubeTexture(this.url, this.getScene() || this._getEngine()!, this._size, this._noMipmap, this._generateHarmonics, this.gammaSpace) as this;\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture to a JSON representation.\r\n     * @returns The JSON representation of the texture\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        if (!serializationObject) {\r\n            return null;\r\n        }\r\n\r\n        serializationObject.customType = \"BABYLON.EXRCubeTexture\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON representation of an EXR Texture in order to create the texture\r\n     * @param parsedTexture Define the JSON representation\r\n     * @param scene Define the scene the texture should be created in\r\n     * @param rootUrl Define the root url in case we need to load relative dependencies\r\n     * @returns the newly created texture after parsing\r\n     */\r\n    public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable<EXRCubeTexture> {\r\n        if (!parsedTexture.name || parsedTexture.isRenderTarget) {\r\n            return null;\r\n        }\r\n\r\n        const texture = new EXRCubeTexture(\r\n            rootUrl + parsedTexture.name,\r\n            scene,\r\n            parsedTexture.size,\r\n            parsedTexture.noMipmap,\r\n            parsedTexture.generateHarmonics,\r\n            parsedTexture.useInGammaSpace\r\n        );\r\n        this._Parse(parsedTexture, texture);\r\n        return texture;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for exrCubeTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterExrCubeTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.EXRCubeTexture\", EXRCubeTexture);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type ExternalTexture } from \"./externalTexture\";\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine.pure\";\r\nimport { RegisterEnginesExtensionsEngineDynamicTexture } from \"../../Engines/Extensions/engine.dynamicTexture.pure\";\r\nimport { RegisterEnginesExtensionsEngineVideoTexture } from \"../../Engines/Extensions/engine.videoTexture.pure\";\r\n\r\n/**\r\n * Defines the options related to the creation of an HtmlElementTexture\r\n */\r\nexport interface IHtmlElementTextureOptions {\r\n    /**\r\n     * Defines whether mip maps should be created or not.\r\n     */\r\n    generateMipMaps?: boolean;\r\n    /**\r\n     * Defines the sampling mode of the texture.\r\n     */\r\n    samplingMode?: number;\r\n    /**\r\n     * Defines the associated texture format.\r\n     */\r\n    format?: number;\r\n    /**\r\n     * Defines the engine instance to use the texture with. It is not mandatory if you define a scene.\r\n     */\r\n    engine: Nullable<AbstractEngine>;\r\n    /**\r\n     * Defines the scene the texture belongs to. It is not mandatory if you define an engine.\r\n     */\r\n    scene: Nullable<Scene>;\r\n}\r\n\r\n/**\r\n * This represents the smallest workload to use an already existing element (Canvas or Video) as a texture.\r\n * To be as efficient as possible depending on your constraints nothing aside the first upload\r\n * is automatically managed.\r\n * It is a cheap VideoTexture or DynamicTexture if you prefer to keep full control of the elements\r\n * in your application.\r\n *\r\n * As the update is not automatic, you need to call them manually.\r\n */\r\nexport class HtmlElementTexture extends BaseTexture {\r\n    /**\r\n     * The texture URL.\r\n     */\r\n    public element: HTMLVideoElement | HTMLCanvasElement;\r\n\r\n    /**\r\n     * Observable triggered once the texture has been loaded.\r\n     */\r\n    public onLoadObservable: Observable<HtmlElementTexture> = new Observable<HtmlElementTexture>();\r\n\r\n    private static readonly _DefaultOptions: IHtmlElementTextureOptions = {\r\n        generateMipMaps: false,\r\n        samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n        format: Constants.TEXTUREFORMAT_RGBA,\r\n        engine: null,\r\n        scene: null,\r\n    };\r\n\r\n    private readonly _format: number;\r\n    private _textureMatrix: Matrix;\r\n    private _isVideo: boolean;\r\n    private _generateMipMaps: boolean;\r\n    private _samplingMode: number;\r\n    private _externalTexture: Nullable<ExternalTexture>;\r\n\r\n    /**\r\n     * Instantiates a HtmlElementTexture from the following parameters.\r\n     *\r\n     * @param name Defines the name of the texture\r\n     * @param element Defines the video or canvas the texture is filled with\r\n     * @param options Defines the other none mandatory texture creation options\r\n     */\r\n    constructor(name: string, element: HTMLVideoElement | HTMLCanvasElement, options: IHtmlElementTextureOptions) {\r\n        super(options.scene || options.engine);\r\n\r\n        RegisterEnginesExtensionsEngineDynamicTexture();\r\n        RegisterEnginesExtensionsEngineVideoTexture();\r\n\r\n        if (!element || (!options.engine && !options.scene)) {\r\n            return;\r\n        }\r\n\r\n        options = {\r\n            ...HtmlElementTexture._DefaultOptions,\r\n            ...options,\r\n        };\r\n\r\n        this._generateMipMaps = options.generateMipMaps!;\r\n        this._samplingMode = options.samplingMode!;\r\n        this._textureMatrix = Matrix.Identity();\r\n        this._format = options.format!;\r\n\r\n        this.name = name;\r\n        this.element = element;\r\n        this._isVideo = !!(element as HTMLVideoElement).getVideoPlaybackQuality;\r\n\r\n        if (this._isVideo) {\r\n            const engineWebGPU = this._engine as Nullable<WebGPUEngine>;\r\n            const createExternalTexture = engineWebGPU?.createExternalTexture;\r\n            if (createExternalTexture) {\r\n                this._externalTexture = createExternalTexture.call(engineWebGPU, element as HTMLVideoElement);\r\n            }\r\n        }\r\n\r\n        this.anisotropicFilteringLevel = 1;\r\n\r\n        this._createInternalTexture();\r\n    }\r\n\r\n    private _createInternalTexture(): void {\r\n        let width: number;\r\n        let height: number;\r\n        if (this._isVideo) {\r\n            width = (this.element as HTMLVideoElement).videoWidth;\r\n            height = (this.element as HTMLVideoElement).videoHeight;\r\n        } else {\r\n            width = this.element.width;\r\n            height = this.element.height;\r\n        }\r\n\r\n        const engine = this._getEngine();\r\n        if (engine) {\r\n            this._texture = engine.createDynamicTexture(width, height, this._generateMipMaps, this._samplingMode);\r\n            this._texture.format = this._format;\r\n        }\r\n\r\n        this.update();\r\n    }\r\n\r\n    /**\r\n     * @returns the texture matrix used in most of the material.\r\n     */\r\n    public override getTextureMatrix(): Matrix {\r\n        return this._textureMatrix;\r\n    }\r\n\r\n    /**\r\n     * Updates the content of the texture.\r\n     * @param invertY Defines whether the texture should be inverted on Y (false by default on video and true on canvas)\r\n     */\r\n    public update(invertY: Nullable<boolean> = null): void {\r\n        const engine = this._getEngine();\r\n        if (this._texture == null || engine == null) {\r\n            return;\r\n        }\r\n\r\n        const wasReady = this.isReady();\r\n        if (this._isVideo) {\r\n            const videoElement = this.element as HTMLVideoElement;\r\n            if (videoElement.readyState < videoElement.HAVE_CURRENT_DATA) {\r\n                return;\r\n            }\r\n\r\n            engine.updateVideoTexture(this._texture, this._externalTexture ? this._externalTexture : videoElement, invertY === null ? true : invertY);\r\n        } else {\r\n            const canvasElement = this.element as HTMLCanvasElement;\r\n            engine.updateDynamicTexture(this._texture, canvasElement, invertY === null ? true : invertY, false, this._format);\r\n        }\r\n\r\n        if (!wasReady && this.isReady()) {\r\n            this.onLoadObservable.notifyObservers(this);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     */\r\n    public override dispose(): void {\r\n        this.onLoadObservable.clear();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This module has no top-level side effects: the engine extension it depends on is registered lazily from the constructor */\n\nimport { type Nullable } from \"../../../types\";\nimport { BaseTexture } from \"../baseTexture.pure\";\nimport { Constants } from \"../../../Engines/constants\";\nimport { Matrix } from \"../../../Maths/math.vector.pure\";\nimport { Observable } from \"../../../Misc/observable.pure\";\nimport { Logger } from \"../../../Misc/logger\";\nimport { IsWindowObjectExist } from \"../../../Misc/domManagement\";\nimport { RegisterEnginesExtensionsEngineDynamicTexture } from \"../../../Engines/Extensions/engine.dynamicTexture.pure\";\n\nimport { type AbstractEngine } from \"../../../Engines/abstractEngine.pure\";\nimport { type ThinEngine } from \"../../../Engines/thinEngine.pure\";\nimport { type WebGPUEngine } from \"../../../Engines/webgpuEngine.pure\";\nimport { type WebGPUHardwareTexture } from \"../../../Engines/WebGPU/webgpuHardwareTexture\";\nimport { type InternalTexture } from \"../internalTexture\";\nimport { type Scene } from \"../../../scene.pure\";\n\nlet _HasWarnedAboutMissingApi = false;\n\nfunction _WarnMissingApi(apiName: string): void {\n    if (_HasWarnedAboutMissingApi) {\n        return;\n    }\n    _HasWarnedAboutMissingApi = true;\n    Logger.Warn(\n        `HTML-in-Canvas: ${apiName} is not available. Enable chrome://flags/#canvas-draw-element, the built-in SVG fallback, or the three-html-render polyfill to use HtmlTexture.`\n    );\n}\n\nlet _HasWarnedAboutSvgFallback = false;\n\nfunction _WarnSvgFallback(): void {\n    if (_HasWarnedAboutSvgFallback) {\n        return;\n    }\n    _HasWarnedAboutSvgFallback = true;\n    Logger.Warn(\"HTML-in-Canvas: the SVG fallback could not rasterize the element. This usually means it references cross-origin or external resources, which taint the snapshot.\");\n}\n\nlet _HasWarnedAboutUploadFailure = false;\n\nfunction _WarnUploadFailure(error: unknown): void {\n    if (_HasWarnedAboutUploadFailure) {\n        return;\n    }\n    _HasWarnedAboutUploadFailure = true;\n    const message = error instanceof Error ? error.message : String(error);\n    Logger.Warn(\n        `HTML-in-Canvas: the native upload failed (${message}). The element must be a direct child of the engine's rendering canvas, which must carry the \\`layoutsubtree\\` attribute, and the upload must run during a paint event.`\n    );\n}\n\n/**\n * Detects whether the engine can upload an HTML element through the native (or polyfilled) WICG\n * HTML-in-Canvas API, without emitting any warning. Used to decide whether the SVG fallback is needed.\n * @param engine defines the engine to test\n * @returns true when the WICG upload API is available for this engine\n */\nexport function IsHtmlInCanvasUploadSupported(engine: AbstractEngine): boolean {\n    if (engine.isWebGPU) {\n        const queue = (engine as WebGPUEngine)._device?.queue;\n        return !!queue && typeof queue.copyElementImageToTexture === \"function\";\n    }\n\n    const gl = (engine as ThinEngine)._gl as Nullable<WebGL2RenderingContext>;\n    return !!gl && typeof gl.texElementImage2D === \"function\";\n}\n\n/**\n * Uploads a live HTML element (or a captured ElementImage) into an existing 2D texture using the WICG\n * HTML-in-Canvas API (https://github.com/WICG/html-in-canvas).\n *\n * This is a side-effect-free helper - it is only reachable when {@link HtmlTexture} (or a direct caller)\n * is imported, so it adds nothing to bundles that do not use it. It relies on\n * `WebGLRenderingContext.texElementImage2D` (WebGL) or `GPUQueue.copyElementImageToTexture` (WebGPU),\n * available either natively (behind chrome://flags/#canvas-draw-element) or through the\n * three-html-render polyfill.\n * @param engine defines the engine that owns the texture\n * @param texture defines the internal texture to update\n * @param element defines the source HTML element (or captured ElementImage) to upload\n * @param invertY defines if data must be stored with Y axis inverted (true by default)\n * @param config defines an optional source rectangle and sizing configuration\n * @returns true if the upload succeeded, false otherwise (e.g. the API is unavailable)\n */\nexport function UploadHtmlElementToTexture(\n    engine: AbstractEngine,\n    texture: Nullable<InternalTexture>,\n    element: Element | ElementImage,\n    invertY: boolean = true,\n    config?: WebGLCopyElementImageConfig\n): boolean {\n    if (!texture || texture._isDisabled) {\n        return false;\n    }\n\n    if (engine.isWebGPU) {\n        return _UploadHtmlElementToWebGPUTexture(engine as WebGPUEngine, texture, element, invertY, config);\n    }\n\n    return _UploadHtmlElementToWebGLTexture(engine as ThinEngine, texture, element, invertY, config);\n}\n\n// The texElementImage2D signature was changed mid-flight in the WICG proposal (see\n// https://github.com/WICG/html-in-canvas#idl-changes): the current spec form is\n// texElementImage2D(target, internalformat, element, config?), but older Chrome Canary builds (and the\n// three-html-render polyfill) still ship the legacy texImage2D-shaped overload\n// texElementImage2D(target, level, internalformat, format, type, element). We prefer the new form and\n// fall back to the legacy one when the implementation rejects it for the wrong number of arguments. The\n// detected shape is cached so we only pay the failed call once.\nlet _UseLegacyTexElementImage2D = false;\n\nfunction _CallTexElementImage2D(gl: WebGL2RenderingContext, internalFormat: number, element: Element | ElementImage, config?: WebGLCopyElementImageConfig): void {\n    if (!_UseLegacyTexElementImage2D) {\n        try {\n            gl.texElementImage2D(gl.TEXTURE_2D, internalFormat, element, config);\n            return;\n        } catch (error) {\n            // Only a wrong-arity TypeError means we are talking to the legacy signature; anything else\n            // (e.g. the element is not a canvas child) is a genuine upload failure and must propagate.\n            // Native rejects the new form with \"N arguments required, but only M present\"; the\n            // three-html-render polyfill rejects it with \"unexpected argument count N\".\n            if (!(error instanceof TypeError) || !/arguments required|argument count/.test((error as Error).message)) {\n                throw error;\n            }\n            _UseLegacyTexElementImage2D = true;\n        }\n    }\n\n    // Legacy overload: texElementImage2D(target, level, internalformat, format, type, element).\n    gl.texElementImage2D(gl.TEXTURE_2D, 0, internalFormat, gl.RGBA, gl.UNSIGNED_BYTE, element);\n}\n\nfunction _UploadHtmlElementToWebGLTexture(\n    engine: ThinEngine,\n    texture: InternalTexture,\n    element: Element | ElementImage,\n    invertY: boolean,\n    config?: WebGLCopyElementImageConfig\n): boolean {\n    // texElementImage2D is provided either natively (behind a flag) or by the three-html-render polyfill.\n    // Engines without a WebGL context (e.g. NullEngine) have no _gl and are handled by this guard.\n    const gl = engine._gl as Nullable<WebGL2RenderingContext>;\n    if (!gl || typeof gl.texElementImage2D !== \"function\") {\n        _WarnMissingApi(\"texElementImage2D\");\n        return false;\n    }\n\n    // texElementImage2D requires a *sized* internal format (RGBA8, SRGB8_ALPHA8, RGBA16F or RGBA32F);\n    // the unsized gl.RGBA returned by _getInternalFormat is rejected.\n    const internalFormat = engine._getRGBABufferInternalSizedFormat(texture.type, texture.format, texture._useSRGBBuffer);\n    const wasPreviouslyBound = engine._bindTextureDirectly(gl.TEXTURE_2D, texture, true);\n    engine._unpackFlipY(invertY);\n\n    try {\n        _CallTexElementImage2D(gl, internalFormat, element, config);\n\n        if (texture.generateMipMaps) {\n            gl.generateMipmap(gl.TEXTURE_2D);\n        }\n\n        if (!wasPreviouslyBound) {\n            engine._bindTextureDirectly(gl.TEXTURE_2D, null);\n        }\n\n        texture.invertY = invertY;\n        texture.isReady = true;\n        return true;\n    } catch (error) {\n        // Reaching here means the snapshot upload failed - usually a real misconfiguration (the element is\n        // not a child of the rendering canvas, or `layoutsubtree` is missing), though a stray call before\n        // the first paint snapshot can also throw. Either way we must NOT disable the texture, so a later\n        // paint-driven update can still succeed; we surface a one-time diagnostic to help debugging.\n        _WarnUploadFailure(error);\n        return false;\n    }\n}\n\nfunction _UploadHtmlElementToWebGPUTexture(\n    engine: WebGPUEngine,\n    texture: InternalTexture,\n    element: Element | ElementImage,\n    invertY: boolean,\n    config?: WebGLCopyElementImageConfig\n): boolean {\n    // copyElementImageToTexture is provided either natively (behind a flag) or by the three-html-render polyfill.\n    const device = engine._device;\n    const queue = device && device.queue;\n    if (!device || !queue || typeof queue.copyElementImageToTexture !== \"function\") {\n        _WarnMissingApi(\"GPUQueue.copyElementImageToTexture\");\n        return false;\n    }\n\n    const gpuTexture = (texture._hardwareTexture as Nullable<WebGPUHardwareTexture>)?.underlyingResource;\n    if (!gpuTexture) {\n        return false;\n    }\n\n    try {\n        const source: GPUCopyElementImageSource = { source: element };\n        if (config) {\n            source.sx = config.sx;\n            source.sy = config.sy;\n            source.swidth = config.swidth;\n            source.sheight = config.sheight;\n        }\n\n        queue.copyElementImageToTexture(source, {\n            destination: { texture: gpuTexture },\n            width: config?.width ?? texture.width,\n            height: config?.height ?? texture.height,\n        });\n\n        if (texture.generateMipMaps) {\n            engine._generateMipmaps(texture);\n        }\n\n        // The WICG copyElementImageToTexture API has no flipY option; the destination orientation is\n        // determined by the source. We record the requested value for downstream sampling conventions.\n        texture.invertY = invertY;\n        texture.isReady = true;\n        return true;\n    } catch (error) {\n        // Reaching here means the snapshot upload failed - usually a real misconfiguration (the element is\n        // not a child of the rendering canvas, or `layoutsubtree` is missing), though a stray call before\n        // the first paint snapshot can also throw. Either way we must NOT disable the texture, so a later\n        // paint-driven update can still succeed; we surface a one-time diagnostic to help debugging.\n        _WarnUploadFailure(error);\n        return false;\n    }\n}\n\n/**\n * Defines the options used to create an {@link HtmlTexture}.\n */\nexport interface IHtmlTextureOptions {\n    /** Defines the width of the texture in pixels (defaults to the element's offset width, then 256). */\n    width?: number;\n    /** Defines the height of the texture in pixels (defaults to the element's offset height, then 256). */\n    height?: number;\n    /** Defines whether mip maps should be created or not (default: false). */\n    generateMipMaps?: boolean;\n    /** Defines the sampling mode of the texture (default: TEXTURE_BILINEAR_SAMPLINGMODE). */\n    samplingMode?: number;\n    /** Defines the associated texture format (default: TEXTUREFORMAT_RGBA). */\n    format?: number;\n    /** Defines whether the texture is automatically updated when the host canvas emits a paint event (default: true). */\n    autoUpdate?: boolean;\n    /**\n     * Defines whether to fall back to an SVG `<foreignObject>` rasterization when the native WICG\n     * HTML-in-Canvas API is unavailable (default: true). The fallback works in any browser but only\n     * captures same-origin, inline-styled content as a static snapshot (see the documentation for caveats).\n     */\n    useSvgFallback?: boolean;\n    /** Defines the engine instance to use the texture with. Not mandatory if a scene is provided. */\n    engine?: Nullable<AbstractEngine>;\n    /** Defines the scene the texture belongs to. Not mandatory if an engine is provided. */\n    scene?: Nullable<Scene>;\n}\n\n/**\n * A texture whose content is rendered from a live HTML element using the WICG HTML-in-Canvas API\n * (https://github.com/WICG/html-in-canvas).\n *\n * The element is hosted as a child of the engine's rendering canvas (which is marked `layoutsubtree`) so\n * the browser can lay it out and snapshot it; the WICG API requires the source element to be a direct\n * child of the canvas whose context performs the upload. Content is uploaded through\n * `WebGLRenderingContext.texElementImage2D` (WebGL) or `GPUQueue.copyElementImageToTexture` (WebGPU),\n * available either natively (behind chrome://flags/#canvas-draw-element) or via the three-html-render\n * polyfill (https://github.com/repalash/three-html-render). When neither is present, a built-in SVG\n * `<foreignObject>` fallback is used instead (see `useSvgFallback`).\n *\n * As with {@link HtmlElementTexture}, updates are not automatic unless `autoUpdate` is enabled; in\n * that case the texture refreshes whenever the host canvas reports a paint change.\n */\nexport class HtmlTexture extends BaseTexture {\n    /**\n     * The HTML element rendered into the texture.\n     */\n    public readonly element: HTMLElement;\n\n    /**\n     * The element that hosts {@link element} in the document. This is the engine's rendering canvas when one\n     * is available (required by the WICG API, which can only capture the element from that canvas), or a\n     * hidden helper `<div>` otherwise - in which case only the SVG fallback can render.\n     */\n    public readonly host: Nullable<HTMLElement>;\n\n    /**\n     * Observable triggered once the texture has been rendered for the first time.\n     */\n    public onLoadObservable: Observable<HtmlTexture> = new Observable<HtmlTexture>();\n\n    private static readonly _DefaultOptions: Required<Pick<IHtmlTextureOptions, \"generateMipMaps\" | \"samplingMode\" | \"format\" | \"autoUpdate\" | \"useSvgFallback\">> = {\n        generateMipMaps: false,\n        samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n        format: Constants.TEXTUREFORMAT_RGBA,\n        autoUpdate: true,\n        useSvgFallback: true,\n    };\n\n    private readonly _format: number;\n    private readonly _generateMipMaps: boolean;\n    private readonly _samplingMode: number;\n    private readonly _useSvgFallback: boolean;\n    private readonly _textureMatrix: Matrix;\n    private _paintHandler: Nullable<(event: PaintEvent) => void> = null;\n    private _ownsHost: boolean = false;\n    private _originalParent: Nullable<Node & ParentNode> = null;\n    private _originalNextSibling: Nullable<ChildNode> = null;\n    private _addedInert: boolean = false;\n    private _width: number;\n    private _height: number;\n\n    /**\n     * Instantiates an HtmlTexture from an HTML element.\n     * @param name Defines the name of the texture\n     * @param element Defines the HTML element to render into the texture\n     * @param options Defines the texture creation options\n     */\n    constructor(name: string, element: HTMLElement, options: IHtmlTextureOptions) {\n        super(options.scene || options.engine);\n\n        this.element = element;\n        this._textureMatrix = Matrix.Identity();\n\n        if (!element || (!options.engine && !options.scene)) {\n            this.host = null;\n            this._width = 0;\n            this._height = 0;\n            this._format = HtmlTexture._DefaultOptions.format;\n            this._generateMipMaps = HtmlTexture._DefaultOptions.generateMipMaps;\n            this._samplingMode = HtmlTexture._DefaultOptions.samplingMode;\n            this._useSvgFallback = HtmlTexture._DefaultOptions.useSvgFallback;\n            return;\n        }\n\n        this._generateMipMaps = options.generateMipMaps ?? HtmlTexture._DefaultOptions.generateMipMaps;\n        this._samplingMode = options.samplingMode ?? HtmlTexture._DefaultOptions.samplingMode;\n        this._format = options.format ?? HtmlTexture._DefaultOptions.format;\n        this._useSvgFallback = options.useSvgFallback ?? HtmlTexture._DefaultOptions.useSvgFallback;\n        const autoUpdate = options.autoUpdate ?? HtmlTexture._DefaultOptions.autoUpdate;\n\n        this._width = options.width || element.offsetWidth || 256;\n        this._height = options.height || element.offsetHeight || 256;\n\n        this.name = name;\n        this.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        this.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        this.anisotropicFilteringLevel = 1;\n\n        this.host = this._createHost();\n\n        // The native WICG API has no content until the first paint snapshot is recorded, so the initial\n        // upload must happen from a paint event. The rendering canvas emits `paint`; listen for at least the\n        // first one and, when auto-update is disabled, detach after that first refresh. A non-canvas helper\n        // host never emits `paint`, so this listener is simply never invoked there.\n        if (this.host) {\n            this._paintHandler = (event: PaintEvent) => {\n                // A single `paint` event covers every changed child of the shared rendering canvas. When the\n                // browser reports which elements changed, skip the upload unless ours is among them, so that\n                // multiple HTML textures hosted on the same canvas don't all re-upload on every unrelated change.\n                if (event.changedElements && !event.changedElements.some((changed) => this.element === changed || this.element.contains(changed))) {\n                    return;\n                }\n                this.update();\n                if (!autoUpdate && this._paintHandler && this.host) {\n                    this.host.removeEventListener(\"paint\", this._paintHandler as EventListener);\n                    this._paintHandler = null;\n                }\n            };\n            this.host.addEventListener(\"paint\", this._paintHandler as EventListener);\n        }\n\n        this._createInternalTexture();\n    }\n\n    private _createHost(): Nullable<HTMLElement> {\n        if (!IsWindowObjectExist() || typeof document === \"undefined\") {\n            return null;\n        }\n\n        // Remember where the caller had the element so dispose() can put it back: we are about to re-parent it\n        // into the host (the element must be a direct child of the host to be captured and laid out).\n        this._originalParent = this.element.parentNode;\n        this._originalNextSibling = this.element.nextSibling;\n\n        // Per the WICG spec, the source element must be a *direct child* of the same canvas whose WebGL/WebGPU\n        // context performs the upload, and that canvas must opt its subtree into layout via `layoutsubtree`.\n        // The engine already owns our texture through its rendering canvas, so the element has to live inside\n        // that canvas: it is the only one whose context can snapshot the element via texElementImage2D /\n        // copyElementImageToTexture. A separate canvas would lay the element out but could never be captured\n        // into the engine's texture (this is why nothing rendered on the native path before).\n        const renderingCanvas = this._getEngine()?.getRenderingCanvas() ?? null;\n        if (renderingCanvas) {\n            renderingCanvas.layoutSubtree = true;\n            // `layoutsubtree` opts children into hit testing; mark ours inert so it never steals pointer events\n            // from the canvas (e.g. camera controls). Synthetic event dispatch still reaches inert elements, so\n            // HtmlRaycastInteractionManager keeps working; HtmlInteractionManager clears it to enable native input.\n            this._addedInert = !this.element.hasAttribute(\"inert\");\n            this.element.setAttribute(\"inert\", \"\");\n            renderingCanvas.appendChild(this.element);\n            this._ownsHost = false;\n            return renderingCanvas;\n        }\n\n        // No rendering canvas (e.g. NullEngine / offscreen): the native upload paths cannot run, because they\n        // capture from the engine's canvas and there is none. Only the SVG fallback renders here, and it builds\n        // from the element's serialized markup rather than from a canvas - so a host *canvas* would buy nothing.\n        // Host the element in a hidden, off-screen <div> purely so it is laid out in the document (giving\n        // correct measured sizes); there is no canvas to capture into on this path.\n        const host = document.createElement(\"div\");\n        host.style.position = \"absolute\";\n        host.style.left = \"-99999px\";\n        host.style.top = \"0px\";\n        host.style.pointerEvents = \"none\";\n        host.setAttribute(\"aria-hidden\", \"true\");\n\n        host.appendChild(this.element);\n        document.body.appendChild(host);\n        this._ownsHost = true;\n\n        return host;\n    }\n\n    private _createInternalTexture(): void {\n        const engine = this._getEngine();\n        if (engine) {\n            // createDynamicTexture is an engine extension; register it lazily (idempotent) so this module stays free of top-level side effects.\n            RegisterEnginesExtensionsEngineDynamicTexture();\n            this._texture = engine.createDynamicTexture(this._width, this._height, this._generateMipMaps, this._samplingMode);\n            this._texture.format = this._format;\n        }\n\n        // Trigger the initial render. On the native path this requests a paint so the first upload happens\n        // once a snapshot exists (calling the WICG API before the first snapshot throws); otherwise the\n        // SVG fallback (or a direct update) renders immediately.\n        this.requestUpdate();\n    }\n\n    /**\n     * @returns the texture matrix used in most of the material.\n     */\n    public override getTextureMatrix(): Matrix {\n        return this._textureMatrix;\n    }\n\n    /**\n     * Requests the host canvas to emit a paint event on the next rendering update. When auto-update is\n     * enabled, this triggers a texture refresh in sync with the DOM. Falls back to an immediate update\n     * when the WICG API is not available.\n     */\n    public requestUpdate(): void {\n        // `requestPaint` only exists on a WICG-capable rendering canvas; the helper <div> host has no such\n        // method, so fall back to an immediate update there.\n        const canvasHost = this.host as Nullable<HTMLCanvasElement>;\n        if (canvasHost && typeof canvasHost.requestPaint === \"function\") {\n            canvasHost.requestPaint();\n        } else {\n            this.update();\n        }\n    }\n\n    /**\n     * Updates the content of the texture from the current state of the HTML element.\n     * @param invertY Defines whether the texture should be inverted on Y (true by default)\n     */\n    public update(invertY: boolean = true): void {\n        const engine = this._getEngine();\n        if (this._texture == null || engine == null) {\n            return;\n        }\n\n        // When the native WICG upload API is unavailable, render through the SVG <foreignObject> fallback\n        // (unless it was explicitly disabled, in which case the upload helper emits a one-time warning).\n        if (this._useSvgFallback && !IsHtmlInCanvasUploadSupported(engine)) {\n            this._updateFromSvgFallback(engine, invertY);\n            return;\n        }\n\n        const wasReady = this.isReady();\n\n        UploadHtmlElementToTexture(engine, this._texture, this.element, invertY);\n\n        if (!wasReady && this.isReady()) {\n            this.onLoadObservable.notifyObservers(this);\n        }\n    }\n\n    /**\n     * Renders the element through an SVG `<foreignObject>` snapshot and uploads it to the texture. This\n     * fallback works in any browser but only captures same-origin, inline-styled content as a static image.\n     * @param engine defines the engine that owns the texture\n     * @param invertY defines whether the texture should be inverted on Y\n     */\n    private _updateFromSvgFallback(engine: AbstractEngine, invertY: boolean): void {\n        if (typeof document === \"undefined\" || typeof Image === \"undefined\" || typeof XMLSerializer === \"undefined\") {\n            return;\n        }\n\n        const svgUrl = this._buildSvgDataUrl();\n        if (!svgUrl) {\n            return;\n        }\n\n        const image = new Image();\n        image.onload = () => {\n            if (this._texture == null) {\n                return;\n            }\n            const wasReady = this.isReady();\n            try {\n                engine.updateDynamicTexture(this._texture, image, invertY, false, this._format);\n            } catch {\n                _WarnSvgFallback();\n                return;\n            }\n            if (!wasReady && this.isReady()) {\n                this.onLoadObservable.notifyObservers(this);\n            }\n        };\n        image.onerror = () => {\n            _WarnSvgFallback();\n        };\n        image.src = svgUrl;\n    }\n\n    /**\n     * Serializes the element into an SVG `<foreignObject>` data URL sized to the texture.\n     * @returns a data URL, or null if serialization failed\n     */\n    private _buildSvgDataUrl(): Nullable<string> {\n        try {\n            const clone = this.element.cloneNode(true) as HTMLElement;\n            clone.setAttribute(\"xmlns\", \"http://www.w3.org/1999/xhtml\");\n            const serialized = new XMLSerializer().serializeToString(clone);\n            const svg =\n                `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${this._width}\" height=\"${this._height}\">` +\n                `<foreignObject x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">${serialized}</foreignObject>` +\n                `</svg>`;\n            return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n        } catch {\n            return null;\n        }\n    }\n\n    /**\n     * Gets the current class name of the texture useful for serialization or dynamic coding.\n     * @returns \"HtmlTexture\"\n     */\n    public override getClassName(): string {\n        return \"HtmlTexture\";\n    }\n\n    /**\n     * Dispose the texture and release its associated resources.\n     */\n    public override dispose(): void {\n        if (this.host) {\n            if (this._paintHandler) {\n                this.host.removeEventListener(\"paint\", this._paintHandler as EventListener);\n                this._paintHandler = null;\n            }\n            // Remove the `inert` attribute we added so the caller gets the element back as they passed it.\n            if (this._addedInert) {\n                this.element.removeAttribute(\"inert\");\n                this._addedInert = false;\n            }\n            // Restore the element to where the caller had it before we re-parented it into the host, rather\n            // than silently deleting their node from the document.\n            if (this._originalParent) {\n                const reference = this._originalNextSibling && this._originalNextSibling.parentNode === this._originalParent ? this._originalNextSibling : null;\n                this._originalParent.insertBefore(this.element, reference);\n            } else {\n                this.element.remove();\n            }\n            // Remove the helper host we created (never the engine's borrowed rendering canvas).\n            if (this._ownsHost) {\n                this.host.remove();\n            }\n        }\n\n        this.onLoadObservable.clear();\n        super.dispose();\n    }\n}\n","import { type Scene } from \"../../../scene.pure\";\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh.pure\";\nimport { type HtmlTexture } from \"./htmlTexture\";\nimport { type Observer } from \"../../../Misc/observable.pure\";\nimport { type Nullable } from \"../../../types\";\n\nimport { Matrix, Vector3 } from \"../../../Maths/math.vector.pure\";\nimport { Viewport } from \"../../../Maths/math.viewport\";\n\n// Attribution: the overlay-and-hit-test technique used here is prior art from `three-html-render`\n// (Palash Bansal, MIT), three.js' `InteractionManager`, and Jake Archibald's `curved-markup` demo.\n// The implementation below is a clean-room rewrite against Babylon.js' own projection APIs.\n\n/**\n * Builds the CSS `transform` string that positions an overlay element over the projected face of a mesh.\n *\n * The transform is applied with `transform-origin: 0 0`. Reading right to left it centers the element on\n * its own origin, scales and rotates it to match the projected face, then translates it to the projected\n * center (in CSS pixels, top-left origin).\n * @param centerX projected center X in CSS pixels\n * @param centerY projected center Y in CSS pixels\n * @param scaleX horizontal scale to apply to the element\n * @param scaleY vertical scale to apply to the element\n * @param rotation in-plane rotation in radians\n * @param elementWidth element width in pixels\n * @param elementHeight element height in pixels\n * @returns the CSS transform string\n */\nexport function ComputeOverlayCssTransform(\n    centerX: number,\n    centerY: number,\n    scaleX: number,\n    scaleY: number,\n    rotation: number,\n    elementWidth: number,\n    elementHeight: number\n): string {\n    return `translate(${centerX}px, ${centerY}px) rotate(${rotation}rad) scale(${scaleX}, ${scaleY}) translate(${-elementWidth / 2}px, ${-elementHeight / 2}px)`;\n}\n\n/**\n * Options for {@link HtmlInteractionManager}.\n */\nexport interface IHtmlInteractionManagerOptions {\n    /** The DOM element to overlay (defaults to the texture's element). */\n    targetElement?: HTMLElement;\n    /** Whether the overlay element captures pointer events so the browser hit-tests it natively (default true). */\n    enablePointerEvents?: boolean;\n}\n\n/**\n * Overlays the live HTML element of an {@link HtmlTexture} on top of the projected face of a planar mesh,\n * so the browser hit-tests the real DOM element natively (enabling focus, text selection and form input).\n *\n * Each frame the mesh face is projected to screen space and the element is translated, scaled and rotated\n * to match. This is best suited to planar, camera-facing surfaces. For arbitrary or curved meshes, use the\n * UV-based {@link HtmlRaycastInteractionManager} instead.\n *\n * The overlay is screen-aligned (position, size and in-plane rotation); it does not apply a full\n * perspective skew, so steeply oblique faces will not be perspective-correct.\n */\nexport class HtmlInteractionManager {\n    private readonly _scene: Scene;\n    private readonly _mesh: AbstractMesh;\n    private readonly _element: HTMLElement;\n    private _observer: Nullable<Observer<Scene>>;\n    private _previousTransform: string = \"\";\n\n    // Reused across frames to avoid per-frame allocations.\n    private readonly _viewport = new Viewport(0, 0, 0, 0);\n    private readonly _center = new Vector3();\n    private readonly _xAxis = new Vector3();\n    private readonly _yAxis = new Vector3();\n    private readonly _projectedCenter = new Vector3();\n    private readonly _projectedX = new Vector3();\n    private readonly _projectedY = new Vector3();\n    private readonly _corner = new Vector3();\n    private _restoreInertOnDispose: boolean = false;\n\n    /**\n     * Creates an overlay interaction manager.\n     * @param scene the scene whose camera drives the projection\n     * @param texture the HTML texture whose element should be overlaid\n     * @param mesh the planar mesh displaying the texture\n     * @param options optional configuration\n     */\n    constructor(scene: Scene, texture: HtmlTexture, mesh: AbstractMesh, options: IHtmlInteractionManagerOptions = {}) {\n        this._scene = scene;\n        this._mesh = mesh;\n        this._element = options.targetElement ?? texture.element;\n\n        this._element.style.position = \"absolute\";\n        this._element.style.left = \"0px\";\n        this._element.style.top = \"0px\";\n        this._element.style.transformOrigin = \"0 0\";\n        this._element.style.pointerEvents = (options.enablePointerEvents ?? true) ? \"auto\" : \"none\";\n\n        // This manager relies on native browser hit testing of the element. HtmlTexture marks the element\n        // `inert` while hosting it inside the rendering canvas (so it does not steal input from the canvas);\n        // clear that here so native interaction works, and restore it on dispose.\n        this._restoreInertOnDispose = this._element.hasAttribute(\"inert\");\n        if (this._restoreInertOnDispose) {\n            this._element.removeAttribute(\"inert\");\n        }\n\n        this._observer = scene.onAfterRenderObservable.add(() => this._update());\n    }\n\n    private _update(): void {\n        const camera = this._scene.activeCamera;\n        const engine = this._scene.getEngine();\n        if (!camera) {\n            return;\n        }\n\n        const boundingBox = this._mesh.getBoundingInfo().boundingBox;\n        const world = this._mesh.getWorldMatrix();\n        const extend = boundingBox.extendSize;\n\n        this._center.copyFrom(boundingBox.centerWorld);\n        // World-space half-axis directions of the mesh face.\n        Vector3.TransformNormalFromFloatsToRef(extend.x, 0, 0, world, this._xAxis);\n        Vector3.TransformNormalFromFloatsToRef(0, extend.y, 0, world, this._yAxis);\n\n        const transform = this._scene.getTransformMatrix();\n        camera.viewport.toGlobalToRef(engine.getRenderWidth(), engine.getRenderHeight(), this._viewport);\n\n        Vector3.ProjectToRef(this._center, Matrix.IdentityReadOnly, transform, this._viewport, this._projectedCenter);\n        this._center.addToRef(this._xAxis, this._corner);\n        Vector3.ProjectToRef(this._corner, Matrix.IdentityReadOnly, transform, this._viewport, this._projectedX);\n        this._center.addToRef(this._yAxis, this._corner);\n        Vector3.ProjectToRef(this._corner, Matrix.IdentityReadOnly, transform, this._viewport, this._projectedY);\n\n        // Hide the overlay when the face is behind the camera.\n        if (this._projectedCenter.z < 0 || this._projectedCenter.z > 1) {\n            this._setTransform(\"translate(-99999px, -99999px)\");\n            return;\n        }\n\n        const dpr = engine.getHardwareScalingLevel();\n        const centerX = this._projectedCenter.x * dpr;\n        const centerY = this._projectedCenter.y * dpr;\n\n        const halfWidth = Math.hypot(this._projectedX.x - this._projectedCenter.x, this._projectedX.y - this._projectedCenter.y) * dpr;\n        const halfHeight = Math.hypot(this._projectedY.x - this._projectedCenter.x, this._projectedY.y - this._projectedCenter.y) * dpr;\n        const rotation = Math.atan2(this._projectedX.y - this._projectedCenter.y, this._projectedX.x - this._projectedCenter.x);\n\n        const elementWidth = this._element.offsetWidth || 1;\n        const elementHeight = this._element.offsetHeight || 1;\n        const scaleX = (2 * halfWidth) / elementWidth;\n        const scaleY = (2 * halfHeight) / elementHeight;\n\n        this._setTransform(ComputeOverlayCssTransform(centerX, centerY, scaleX, scaleY, rotation, elementWidth, elementHeight));\n    }\n\n    private _setTransform(transform: string): void {\n        if (transform === this._previousTransform) {\n            return;\n        }\n        this._previousTransform = transform;\n        this._element.style.transform = transform;\n    }\n\n    /**\n     * Detaches the manager and stops updating the overlay.\n     */\n    public dispose(): void {\n        if (this._restoreInertOnDispose) {\n            this._element.setAttribute(\"inert\", \"\");\n            this._restoreInertOnDispose = false;\n        }\n        if (this._observer) {\n            this._scene.onAfterRenderObservable.remove(this._observer);\n            this._observer = null;\n        }\n    }\n}\n","import { type Scene } from \"../../../scene.pure\";\nimport { type AbstractMesh } from \"../../../Meshes/abstractMesh.pure\";\nimport { type HtmlTexture } from \"./htmlTexture\";\nimport { type Observer } from \"../../../Misc/observable.pure\";\nimport { type PointerInfo, PointerEventTypes } from \"../../../Events/pointerEvents\";\nimport { type Nullable } from \"../../../types\";\n\n// Attribution: the raycast/UV event-routing technique used here is prior art from\n// `three-html-render` (Palash Bansal, MIT) and Jake Archibald's `curved-markup` demo.\n// The implementation below is a clean-room rewrite against Babylon.js' own picking APIs.\n\n/**\n * Maps a UV coordinate sampled from an {@link HtmlTexture} to a pixel position inside the source element.\n *\n * When `invertY` is true (the default, matching {@link HtmlTexture}'s default upload orientation) the V\n * axis is flipped so that `v = 1` maps to the top of the element, matching the top-left origin used by\n * DOM layout.\n * @param u horizontal texture coordinate, normally in [0, 1]\n * @param v vertical texture coordinate, normally in [0, 1]\n * @param width element width in pixels\n * @param height element height in pixels\n * @param invertY whether the texture content is stored Y-inverted (default true)\n * @returns the pixel position `{ x, y }` within the element\n */\nexport function GetElementPixelFromUv(u: number, v: number, width: number, height: number, invertY: boolean = true): { x: number; y: number } {\n    return { x: u * width, y: (invertY ? 1 - v : v) * height };\n}\n\n/**\n * Options for {@link HtmlRaycastInteractionManager}.\n */\nexport interface IHtmlRaycastInteractionManagerOptions {\n    /** The DOM element that receives the forwarded pointer events (defaults to the texture's element). */\n    targetElement?: HTMLElement;\n    /** Whether hits on back-facing geometry are ignored (default true). */\n    backFaceCulling?: boolean;\n    /** Whether the texture content is stored Y-inverted, used when mapping UVs to element pixels (default true). */\n    invertY?: boolean;\n}\n\n/**\n * Routes Babylon pointer events to a live HTML element rendered through an {@link HtmlTexture}.\n *\n * On every pointer event the scene is picked; when the configured mesh is hit, the picked UV is mapped to\n * a pixel inside the source element and an equivalent DOM pointer (and mouse) event is dispatched there.\n * This works for arbitrary meshes (planes, boxes, curved surfaces) because it relies on UV coordinates\n * rather than a flat CSS overlay. For a perspective-correct overlay on planar surfaces, see\n * {@link HtmlInteractionManager}.\n */\nexport class HtmlRaycastInteractionManager {\n    private readonly _scene: Scene;\n    private readonly _mesh: AbstractMesh;\n    private readonly _element: HTMLElement;\n    private readonly _backFaceCulling: boolean;\n    private readonly _invertY: boolean;\n    private _observer: Nullable<Observer<PointerInfo>>;\n    private _downTarget: Nullable<EventTarget>;\n    private readonly _containHandler: (evt: Event) => void;\n    private readonly _rectCache = new Map<HTMLElement, DOMRect>();\n    private _rectCacheValid = false;\n    private readonly _invalidateRectCache: () => void;\n    private _resizeObserver: Nullable<ResizeObserver> = null;\n    private _mutationObserver: Nullable<MutationObserver> = null;\n\n    /**\n     * Creates a raycast interaction manager.\n     * @param scene the scene to listen to for pointer events\n     * @param texture the HTML texture whose element should receive the forwarded events\n     * @param mesh the mesh displaying the texture; only hits on this mesh are forwarded\n     * @param options optional configuration\n     */\n    constructor(scene: Scene, texture: HtmlTexture, mesh: AbstractMesh, options: IHtmlRaycastInteractionManagerOptions = {}) {\n        this._scene = scene;\n        this._mesh = mesh;\n        this._element = options.targetElement ?? texture.element;\n        this._backFaceCulling = options.backFaceCulling ?? true;\n        this._invertY = options.invertY ?? true;\n\n        // The hosted element is a child of the engine's rendering canvas, where Babylon's own input\n        // listeners live. The synthetic events we dispatch bubble, so without this they would reach the\n        // canvas and be re-interpreted as real input - moving the camera and re-entering this manager in a\n        // feedback loop. Stopping propagation at the host element keeps them inside the HTML subtree (so\n        // event delegation still works) while never leaking back to the engine.\n        this._containHandler = (evt: Event) => evt.stopPropagation();\n        for (const type of _ContainedEventTypes) {\n            this._element.addEventListener(type, this._containHandler);\n        }\n\n        // Resolving the target reads layout (getBoundingClientRect) for the element and its descendants on\n        // every pointer event. Cache those rects and only re-read them when layout can actually change - on\n        // size changes, DOM mutations, or viewport scroll/resize - so high-frequency pointermove events stay\n        // pure arithmetic instead of forcing a synchronous reflow each time.\n        this._invalidateRectCache = () => {\n            this._rectCacheValid = false;\n        };\n        if (typeof ResizeObserver !== \"undefined\") {\n            this._resizeObserver = new ResizeObserver(this._invalidateRectCache);\n            this._resizeObserver.observe(this._element);\n        }\n        if (typeof MutationObserver !== \"undefined\") {\n            this._mutationObserver = new MutationObserver(this._invalidateRectCache);\n            this._mutationObserver.observe(this._element, { attributes: true, childList: true, characterData: true, subtree: true });\n        }\n        if (typeof window !== \"undefined\") {\n            window.addEventListener(\"resize\", this._invalidateRectCache);\n            window.addEventListener(\"scroll\", this._invalidateRectCache, true);\n        }\n\n        this._observer = scene.onPointerObservable.add((pointerInfo) => this._onPointer(pointerInfo));\n    }\n\n    private _onPointer(pointerInfo: PointerInfo): void {\n        const domName = _PointerTypeToDomEvent(pointerInfo.type);\n        if (!domName) {\n            return;\n        }\n\n        const pickInfo = pointerInfo.pickInfo;\n        if (!pickInfo || !pickInfo.hit || pickInfo.pickedMesh !== this._mesh) {\n            return;\n        }\n\n        if (this._backFaceCulling && this._isBackFace(pointerInfo)) {\n            return;\n        }\n\n        const uv = pickInfo.getTextureCoordinates();\n        if (!uv) {\n            return;\n        }\n\n        const rect = this._getRect(this._element);\n        const { x, y } = GetElementPixelFromUv(uv.x, uv.y, rect.width || this._element.offsetWidth, rect.height || this._element.offsetHeight, this._invertY);\n\n        this._dispatch(domName, rect.left + x, rect.top + y, pointerInfo);\n    }\n\n    private _isBackFace(pointerInfo: PointerInfo): boolean {\n        const pickInfo = pointerInfo.pickInfo!;\n        const normal = pickInfo.getNormal(true, true);\n        if (!normal || !pickInfo.pickedPoint) {\n            return false;\n        }\n        const camera = this._scene.activeCamera;\n        if (!camera) {\n            return false;\n        }\n        // The face is back-facing when its world normal points away from the camera-to-surface direction.\n        const toSurface = pickInfo.pickedPoint.subtract(camera.globalPosition);\n        return normal.dot(toSurface) > 0;\n    }\n\n    private _dispatch(domName: string, clientX: number, clientY: number, pointerInfo: PointerInfo): void {\n        if (typeof PointerEvent === \"undefined\") {\n            return;\n        }\n\n        const sourceEvent = pointerInfo.event as Partial<PointerEvent>;\n        // document.elementFromPoint is unreliable here: the element is hosted inside the engine's rendering\n        // canvas (whose painted WebGL/WebGPU content covers the DOM children) and is marked `inert`, so the\n        // browser's own hit testing skips it. Resolve the deepest descendant under the mapped point manually\n        // from the laid-out subtree instead; synthetic dispatch still triggers listeners on inert elements.\n        const target = this._resolveTarget(clientX, clientY);\n\n        const init: PointerEventInit = {\n            bubbles: true,\n            cancelable: true,\n            clientX,\n            clientY,\n            button: sourceEvent.button ?? 0,\n            buttons: sourceEvent.buttons ?? 0,\n            pointerId: sourceEvent.pointerId ?? 1,\n            pointerType: sourceEvent.pointerType ?? \"mouse\",\n        };\n\n        target.dispatchEvent(new PointerEvent(domName, init));\n\n        const mouseName = _PointerToMouseEvent(domName);\n        if (mouseName) {\n            target.dispatchEvent(new MouseEvent(mouseName, init));\n        }\n\n        // The browser synthesizes a \"click\" from a native down/up pair, but synthetic mouse events do not,\n        // so we emit it ourselves: on pointerdown remember the target, then on pointerup dispatch a click\n        // when the release lands on the same element (matching native click semantics closely enough).\n        // Native browsers only synthesize \"click\" for the primary button, so gate on button 0.\n        if (domName === \"pointerdown\") {\n            this._downTarget = target;\n        } else if (domName === \"pointerup\") {\n            if (this._downTarget === target && init.button === 0) {\n                target.dispatchEvent(new MouseEvent(\"click\", init));\n            }\n            this._downTarget = null;\n        }\n    }\n\n    /**\n     * Resolves the deepest descendant of the hosted element whose layout box contains the given client point.\n     * @param clientX horizontal client coordinate\n     * @param clientY vertical client coordinate\n     * @returns the deepest matching element, or the hosted element itself when no descendant matches\n     */\n    private _resolveTarget(clientX: number, clientY: number): HTMLElement {\n        let target: HTMLElement = this._element;\n        let advanced = true;\n        while (advanced) {\n            advanced = false;\n            const children = target.children;\n            for (let i = children.length - 1; i >= 0; i--) {\n                const child = children[i] as HTMLElement;\n                const rect = this._getRect(child);\n                if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {\n                    target = child;\n                    advanced = true;\n                    break;\n                }\n            }\n        }\n        return target;\n    }\n\n    /**\n     * Returns the client rect of an element, served from a cache that is rebuilt only when layout may have\n     * changed (see the constructor). This keeps pointer routing free of per-event layout reads.\n     * @param element the element whose bounding rect is needed\n     * @returns the element's cached {@link DOMRect}\n     */\n    private _getRect(element: HTMLElement): DOMRect {\n        if (!this._rectCacheValid) {\n            this._rectCache.clear();\n            this._rectCacheValid = true;\n        }\n        let rect = this._rectCache.get(element);\n        if (!rect) {\n            rect = element.getBoundingClientRect();\n            this._rectCache.set(element, rect);\n        }\n        return rect;\n    }\n\n    /**\n     * Detaches the manager and stops forwarding pointer events.\n     */\n    public dispose(): void {\n        for (const type of _ContainedEventTypes) {\n            this._element.removeEventListener(type, this._containHandler);\n        }\n        if (this._resizeObserver) {\n            this._resizeObserver.disconnect();\n            this._resizeObserver = null;\n        }\n        if (this._mutationObserver) {\n            this._mutationObserver.disconnect();\n            this._mutationObserver = null;\n        }\n        if (typeof window !== \"undefined\") {\n            window.removeEventListener(\"resize\", this._invalidateRectCache);\n            window.removeEventListener(\"scroll\", this._invalidateRectCache, true);\n        }\n        this._rectCache.clear();\n        if (this._observer) {\n            this._scene.onPointerObservable.remove(this._observer);\n            this._observer = null;\n        }\n    }\n}\n\nfunction _PointerTypeToDomEvent(type: number): Nullable<string> {\n    switch (type) {\n        case PointerEventTypes.POINTERDOWN:\n            return \"pointerdown\";\n        case PointerEventTypes.POINTERUP:\n            return \"pointerup\";\n        case PointerEventTypes.POINTERMOVE:\n            return \"pointermove\";\n        default:\n            return null;\n    }\n}\n\nfunction _PointerToMouseEvent(domName: string): Nullable<string> {\n    switch (domName) {\n        case \"pointerdown\":\n            return \"mousedown\";\n        case \"pointerup\":\n            return \"mouseup\";\n        case \"pointermove\":\n            return \"mousemove\";\n        default:\n            return null;\n    }\n}\n\n// Synthetic event types we dispatch into the hosted element; they are contained at the host so they do\n// not bubble back into the engine's rendering canvas (see the constructor for the rationale).\nconst _ContainedEventTypes = [\"pointerdown\", \"pointerup\", \"pointermove\", \"mousedown\", \"mouseup\", \"mousemove\", \"click\"] as const;\n","/** This module has no top-level side effects: it only declares the optional HTML-in-Canvas polyfill installer */\n\nimport { type Nullable } from \"../../../types\";\nimport { Logger } from \"../../../Misc/logger\";\n\n// Attribution: the WICG HTML-in-Canvas polyfill is `three-html-render` by Palash Bansal (`repalash`),\n// MIT. It is consumed as an optional, lazily-imported dependency and is never bundled into Babylon.\n\n/**\n * Shape of the `three-html-render` polyfill module (only the parts this wrapper uses).\n */\nexport interface IHtmlInCanvasPolyfillModule {\n    /** Installs the WICG HTML-in-Canvas polyfill onto the relevant DOM prototypes. */\n    installHtmlInCanvasPolyfill?: (options?: { force?: boolean }) => void;\n    /** Removes a previously installed polyfill. */\n    uninstallHtmlInCanvasPolyfill?: () => void;\n}\n\n/**\n * Options for {@link InstallHtmlInCanvasPolyfill}.\n */\nexport interface IInstallHtmlInCanvasPolyfillOptions {\n    /** Install the polyfill even when the browser already supports the API natively (default false). */\n    force?: boolean;\n    /** Module specifier to lazily import the polyfill from (default `\"three-html-render\"`). */\n    moduleSpecifier?: string;\n    /** A pre-imported polyfill module to use instead of dynamically importing one. */\n    polyfillModule?: IHtmlInCanvasPolyfillModule;\n}\n\nlet _InstalledModule: Nullable<IHtmlInCanvasPolyfillModule> = null;\n\n/**\n * Detects whether the browser supports the WICG HTML-in-Canvas API natively (or already has it installed).\n * @returns true when an HTMLCanvasElement exposes `captureElementImage`\n */\nexport function IsHtmlInCanvasSupportedNatively(): boolean {\n    if (typeof document === \"undefined\") {\n        return false;\n    }\n    const canvas = document.createElement(\"canvas\") as HTMLCanvasElement & { captureElementImage?: unknown };\n    return typeof canvas.captureElementImage === \"function\";\n}\n\n/**\n * Lazily installs the WICG HTML-in-Canvas polyfill (`three-html-render`) so that {@link HtmlTexture} and the\n * interaction managers work in browsers that do not yet ship the native API.\n *\n * The polyfill is an optional dependency: it is imported on demand and never bundled into Babylon. When the\n * browser already supports the API natively, this is a no-op unless `force` is set or the `?polyfillHIC` URL\n * flag is present.\n * @param options optional installation configuration\n * @returns a promise that resolves to true when the polyfill was installed, false otherwise\n */\nexport async function InstallHtmlInCanvasPolyfill(options: IInstallHtmlInCanvasPolyfillOptions = {}): Promise<boolean> {\n    const force = options.force ?? _HasPolyfillUrlFlag();\n\n    if (!force && IsHtmlInCanvasSupportedNatively()) {\n        return false;\n    }\n\n    const module = options.polyfillModule ?? (await _ImportPolyfill(options.moduleSpecifier ?? \"three-html-render\"));\n    if (!module || typeof module.installHtmlInCanvasPolyfill !== \"function\") {\n        Logger.Warn(\"HTML-in-Canvas: the polyfill module does not expose installHtmlInCanvasPolyfill; nothing was installed.\");\n        return false;\n    }\n\n    module.installHtmlInCanvasPolyfill(force ? { force: true } : undefined);\n    _InstalledModule = module;\n    return true;\n}\n\n/**\n * Removes a polyfill previously installed by {@link InstallHtmlInCanvasPolyfill}.\n */\nexport function UninstallHtmlInCanvasPolyfill(): void {\n    if (_InstalledModule && typeof _InstalledModule.uninstallHtmlInCanvasPolyfill === \"function\") {\n        _InstalledModule.uninstallHtmlInCanvasPolyfill();\n    }\n    _InstalledModule = null;\n}\n\nasync function _ImportPolyfill(specifier: string): Promise<Nullable<IHtmlInCanvasPolyfillModule>> {\n    try {\n        // The specifier is a variable so bundlers leave this as a runtime import and the optional package is\n        // not required to be installed at build time. The UMD/global build cannot resolve a bare module\n        // specifier, so this dynamic import is neutralized there (see rewriteDynamicExternalImportsPlugin);\n        // UMD consumers should pass `polyfillModule` instead.\n        return (await import(/* @vite-ignore */ /* webpackIgnore: true */ specifier)) as IHtmlInCanvasPolyfillModule;\n    } catch {\n        Logger.Warn(`HTML-in-Canvas: could not load polyfill module \"${specifier}\". Install three-html-render or pass a polyfillModule.`);\n        return null;\n    }\n}\n\nfunction _HasPolyfillUrlFlag(): boolean {\n    return typeof window !== \"undefined\" && !!window.location && /[?&]polyfillHIC\\b/i.test(window.location.search);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport { type SphericalPolynomial } from \"../Maths/sphericalPolynomial.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { CubeMapToSphericalPolynomialTools } from \"../Misc/HighDynamicRange/cubemapToSphericalPolynomial\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { FromHalfFloat, ToHalfFloat } from \"./textureTools\";\r\n\r\n// Based on demo done by Brandon Jones - http://media.tojicode.com/webgl-samples/dds.html\r\n// All values and structures referenced from:\r\n// http://msdn.microsoft.com/en-us/library/bb943991.aspx/\r\nconst DDS_MAGIC = 0x20534444;\r\n\r\nconst //DDSD_CAPS = 0x1,\r\n    //DDSD_HEIGHT = 0x2,\r\n    //DDSD_WIDTH = 0x4,\r\n    //DDSD_PITCH = 0x8,\r\n    //DDSD_PIXELFORMAT = 0x1000,\r\n    DDSD_MIPMAPCOUNT = 0x20000;\r\n//DDSD_LINEARSIZE = 0x80000,\r\n//DDSD_DEPTH = 0x800000;\r\n\r\n// var DDSCAPS_COMPLEX = 0x8,\r\n//     DDSCAPS_MIPMAP = 0x400000,\r\n//     DDSCAPS_TEXTURE = 0x1000;\r\n\r\nconst DDSCAPS2_CUBEMAP = 0x200;\r\n// DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,\r\n// DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,\r\n// DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,\r\n// DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,\r\n// DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,\r\n// DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,\r\n// DDSCAPS2_VOLUME = 0x200000;\r\n\r\nconst //DDPF_ALPHAPIXELS = 0x1,\r\n    //DDPF_ALPHA = 0x2,\r\n    DDPF_FOURCC = 0x4,\r\n    DDPF_RGB = 0x40,\r\n    //DDPF_YUV = 0x200,\r\n    DDPF_LUMINANCE = 0x20000;\r\n\r\nfunction FourCCToInt32(value: string) {\r\n    return value.charCodeAt(0) + (value.charCodeAt(1) << 8) + (value.charCodeAt(2) << 16) + (value.charCodeAt(3) << 24);\r\n}\r\n\r\nfunction Int32ToFourCC(value: number) {\r\n    return String.fromCharCode(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, (value >> 24) & 0xff);\r\n}\r\n\r\nconst FOURCC_DXT1 = /*#__PURE__*/ FourCCToInt32(\"DXT1\");\r\nconst FOURCC_DXT3 = /*#__PURE__*/ FourCCToInt32(\"DXT3\");\r\nconst FOURCC_DXT5 = /*#__PURE__*/ FourCCToInt32(\"DXT5\");\r\nconst FOURCC_DX10 = /*#__PURE__*/ FourCCToInt32(\"DX10\");\r\nconst FOURCC_D3DFMT_R16G16B16A16F = 113;\r\nconst FOURCC_D3DFMT_R32G32B32A32F = 116;\r\n\r\nconst DXGI_FORMAT_R32G32B32A32_FLOAT = 2;\r\nconst DXGI_FORMAT_R16G16B16A16_FLOAT = 10;\r\nconst DXGI_FORMAT_B8G8R8X8_UNORM = 88;\r\n\r\nconst headerLengthInt = 31; // The header length in 32 bit ints\r\n\r\n// Offsets into the header array\r\nconst off_magic = 0;\r\n\r\nconst off_size = 1;\r\nconst off_flags = 2;\r\nconst off_height = 3;\r\nconst off_width = 4;\r\n\r\nconst off_mipmapCount = 7;\r\n\r\nconst off_pfFlags = 20;\r\nconst off_pfFourCC = 21;\r\nconst off_RGBbpp = 22;\r\nconst off_RMask = 23;\r\nconst off_GMask = 24;\r\nconst off_BMask = 25;\r\nconst off_AMask = 26;\r\n// var off_caps1 = 27;\r\nconst off_caps2 = 28;\r\n// var off_caps3 = 29;\r\n// var off_caps4 = 30;\r\nconst off_dxgiFormat = 32;\r\n\r\n/**\r\n * Direct draw surface info\r\n * @see https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dx-graphics-dds-pguide\r\n */\r\nexport interface DDSInfo {\r\n    /**\r\n     * Width of the texture\r\n     */\r\n    width: number;\r\n    /**\r\n     * Width of the texture\r\n     */\r\n    height: number;\r\n    /**\r\n     * Number of Mipmaps for the texture\r\n     * @see https://en.wikipedia.org/wiki/Mipmap\r\n     */\r\n    mipmapCount: number;\r\n    /**\r\n     * If the textures format is a known fourCC format\r\n     * @see https://www.fourcc.org/\r\n     */\r\n    isFourCC: boolean;\r\n    /**\r\n     * If the texture is an RGB format eg. DXGI_FORMAT_B8G8R8X8_UNORM format\r\n     */\r\n    isRGB: boolean;\r\n    /**\r\n     * If the texture is a lumincance format\r\n     */\r\n    isLuminance: boolean;\r\n    /**\r\n     * If this is a cube texture\r\n     * @see https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dds-file-layout-for-cubic-environment-maps\r\n     */\r\n    isCube: boolean;\r\n    /**\r\n     * If the texture is a compressed format eg. FOURCC_DXT1\r\n     */\r\n    isCompressed: boolean;\r\n    /**\r\n     * The dxgiFormat of the texture\r\n     * @see https://docs.microsoft.com/en-us/windows/desktop/api/dxgiformat/ne-dxgiformat-dxgi_format\r\n     */\r\n    dxgiFormat: number;\r\n    /**\r\n     * Texture type eg. Engine.TEXTURETYPE_UNSIGNED_BYTE, Engine.TEXTURETYPE_FLOAT\r\n     */\r\n    textureType: number;\r\n    /**\r\n     * Sphericle polynomial created for the dds texture\r\n     */\r\n    sphericalPolynomial?: SphericalPolynomial;\r\n}\r\n\r\n/**\r\n * Class used to provide DDS decompression tools\r\n */\r\nexport class DDSTools {\r\n    /**\r\n     * Gets or sets a boolean indicating that LOD info is stored in alpha channel (false by default)\r\n     */\r\n    public static StoreLODInAlphaChannel = false;\r\n\r\n    /**\r\n     * Gets DDS information from an array buffer\r\n     * @param data defines the array buffer view to read data from\r\n     * @returns the DDS information\r\n     */\r\n    public static GetDDSInfo(data: ArrayBufferView): DDSInfo {\r\n        const header = new Int32Array(data.buffer, data.byteOffset, headerLengthInt);\r\n        const extendedHeader = new Int32Array(data.buffer, data.byteOffset, headerLengthInt + 4);\r\n\r\n        let mipmapCount = 1;\r\n        if (header[off_flags] & DDSD_MIPMAPCOUNT) {\r\n            mipmapCount = Math.max(1, header[off_mipmapCount]);\r\n        }\r\n\r\n        const fourCC = header[off_pfFourCC];\r\n        const dxgiFormat = fourCC === FOURCC_DX10 ? extendedHeader[off_dxgiFormat] : 0;\r\n        let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n        switch (fourCC) {\r\n            case FOURCC_D3DFMT_R16G16B16A16F:\r\n                textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n                break;\r\n            case FOURCC_D3DFMT_R32G32B32A32F:\r\n                textureType = Constants.TEXTURETYPE_FLOAT;\r\n                break;\r\n            case FOURCC_DX10:\r\n                if (dxgiFormat === DXGI_FORMAT_R16G16B16A16_FLOAT) {\r\n                    textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n                    break;\r\n                }\r\n                if (dxgiFormat === DXGI_FORMAT_R32G32B32A32_FLOAT) {\r\n                    textureType = Constants.TEXTURETYPE_FLOAT;\r\n                    break;\r\n                }\r\n        }\r\n\r\n        return {\r\n            width: header[off_width],\r\n            height: header[off_height],\r\n            mipmapCount: mipmapCount,\r\n            isFourCC: (header[off_pfFlags] & DDPF_FOURCC) === DDPF_FOURCC,\r\n            isRGB: (header[off_pfFlags] & DDPF_RGB) === DDPF_RGB,\r\n            isLuminance: (header[off_pfFlags] & DDPF_LUMINANCE) === DDPF_LUMINANCE,\r\n            isCube: (header[off_caps2] & DDSCAPS2_CUBEMAP) === DDSCAPS2_CUBEMAP,\r\n            isCompressed: fourCC === FOURCC_DXT1 || fourCC === FOURCC_DXT3 || fourCC === FOURCC_DXT5,\r\n            dxgiFormat: dxgiFormat,\r\n            textureType: textureType,\r\n        };\r\n    }\r\n\r\n    private static _GetHalfFloatAsFloatRGBAArrayBuffer(\r\n        width: number,\r\n        height: number,\r\n        dataOffset: number,\r\n        dataLength: number,\r\n        arrayBuffer: ArrayBufferLike,\r\n        lod: number\r\n    ): Float32Array {\r\n        const destArray = new Float32Array(dataLength);\r\n        const srcData = new Uint16Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcPos = (x + y * width) * 4;\r\n                destArray[index] = FromHalfFloat(srcData[srcPos]);\r\n                destArray[index + 1] = FromHalfFloat(srcData[srcPos + 1]);\r\n                destArray[index + 2] = FromHalfFloat(srcData[srcPos + 2]);\r\n                if (DDSTools.StoreLODInAlphaChannel) {\r\n                    destArray[index + 3] = lod;\r\n                } else {\r\n                    destArray[index + 3] = FromHalfFloat(srcData[srcPos + 3]);\r\n                }\r\n                index += 4;\r\n            }\r\n        }\r\n\r\n        return destArray;\r\n    }\r\n\r\n    private static _GetHalfFloatRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBufferLike, lod: number): Uint16Array {\r\n        if (DDSTools.StoreLODInAlphaChannel) {\r\n            const destArray = new Uint16Array(dataLength);\r\n            const srcData = new Uint16Array(arrayBuffer, dataOffset);\r\n            let index = 0;\r\n            for (let y = 0; y < height; y++) {\r\n                for (let x = 0; x < width; x++) {\r\n                    const srcPos = (x + y * width) * 4;\r\n                    destArray[index] = srcData[srcPos];\r\n                    destArray[index + 1] = srcData[srcPos + 1];\r\n                    destArray[index + 2] = srcData[srcPos + 2];\r\n                    destArray[index + 3] = ToHalfFloat(lod);\r\n                    index += 4;\r\n                }\r\n            }\r\n\r\n            return destArray;\r\n        }\r\n\r\n        return new Uint16Array(arrayBuffer, dataOffset, dataLength);\r\n    }\r\n\r\n    private static _GetFloatRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBufferLike, lod: number): Float32Array {\r\n        if (DDSTools.StoreLODInAlphaChannel) {\r\n            const destArray = new Float32Array(dataLength);\r\n            const srcData = new Float32Array(arrayBuffer, dataOffset);\r\n            let index = 0;\r\n            for (let y = 0; y < height; y++) {\r\n                for (let x = 0; x < width; x++) {\r\n                    const srcPos = (x + y * width) * 4;\r\n                    destArray[index] = srcData[srcPos];\r\n                    destArray[index + 1] = srcData[srcPos + 1];\r\n                    destArray[index + 2] = srcData[srcPos + 2];\r\n                    destArray[index + 3] = lod;\r\n                    index += 4;\r\n                }\r\n            }\r\n\r\n            return destArray;\r\n        }\r\n        return new Float32Array(arrayBuffer, dataOffset, dataLength);\r\n    }\r\n\r\n    private static _GetFloatAsHalfFloatRGBAArrayBuffer(\r\n        width: number,\r\n        height: number,\r\n        dataOffset: number,\r\n        dataLength: number,\r\n        arrayBuffer: ArrayBufferLike,\r\n        lod: number\r\n    ): Uint16Array {\r\n        const destArray = new Uint16Array(dataLength);\r\n        const srcData = new Float32Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                destArray[index] = ToHalfFloat(srcData[index]);\r\n                destArray[index + 1] = ToHalfFloat(srcData[index + 1]);\r\n                destArray[index + 2] = ToHalfFloat(srcData[index + 2]);\r\n                if (DDSTools.StoreLODInAlphaChannel) {\r\n                    destArray[index + 3] = ToHalfFloat(lod);\r\n                } else {\r\n                    destArray[index + 3] = ToHalfFloat(srcData[index + 3]);\r\n                }\r\n                index += 4;\r\n            }\r\n        }\r\n\r\n        return destArray;\r\n    }\r\n\r\n    private static _GetFloatAsUIntRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBufferLike, lod: number): Uint8Array {\r\n        const destArray = new Uint8Array(dataLength);\r\n        const srcData = new Float32Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcPos = (x + y * width) * 4;\r\n                destArray[index] = Clamp(srcData[srcPos]) * 255;\r\n                destArray[index + 1] = Clamp(srcData[srcPos + 1]) * 255;\r\n                destArray[index + 2] = Clamp(srcData[srcPos + 2]) * 255;\r\n                if (DDSTools.StoreLODInAlphaChannel) {\r\n                    destArray[index + 3] = lod;\r\n                } else {\r\n                    destArray[index + 3] = Clamp(srcData[srcPos + 3]) * 255;\r\n                }\r\n                index += 4;\r\n            }\r\n        }\r\n\r\n        return destArray;\r\n    }\r\n\r\n    private static _GetHalfFloatAsUIntRGBAArrayBuffer(\r\n        width: number,\r\n        height: number,\r\n        dataOffset: number,\r\n        dataLength: number,\r\n        arrayBuffer: ArrayBufferLike,\r\n        lod: number\r\n    ): Uint8Array {\r\n        const destArray = new Uint8Array(dataLength);\r\n        const srcData = new Uint16Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcPos = (x + y * width) * 4;\r\n                destArray[index] = Clamp(FromHalfFloat(srcData[srcPos])) * 255;\r\n                destArray[index + 1] = Clamp(FromHalfFloat(srcData[srcPos + 1])) * 255;\r\n                destArray[index + 2] = Clamp(FromHalfFloat(srcData[srcPos + 2])) * 255;\r\n                if (DDSTools.StoreLODInAlphaChannel) {\r\n                    destArray[index + 3] = lod;\r\n                } else {\r\n                    destArray[index + 3] = Clamp(FromHalfFloat(srcData[srcPos + 3])) * 255;\r\n                }\r\n                index += 4;\r\n            }\r\n        }\r\n\r\n        return destArray;\r\n    }\r\n\r\n    private static _GetRGBAArrayBuffer(\r\n        width: number,\r\n        height: number,\r\n        dataOffset: number,\r\n        dataLength: number,\r\n        arrayBuffer: ArrayBufferLike,\r\n        rOffset: number,\r\n        gOffset: number,\r\n        bOffset: number,\r\n        aOffset: number\r\n    ): Uint8Array {\r\n        const byteArray = new Uint8Array(dataLength);\r\n        const srcData = new Uint8Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcPos = (x + y * width) * 4;\r\n\r\n                byteArray[index] = srcData[srcPos + rOffset];\r\n                byteArray[index + 1] = srcData[srcPos + gOffset];\r\n                byteArray[index + 2] = srcData[srcPos + bOffset];\r\n                byteArray[index + 3] = srcData[srcPos + aOffset];\r\n                index += 4;\r\n            }\r\n        }\r\n\r\n        return byteArray;\r\n    }\r\n\r\n    private static _ExtractLongWordOrder(value: number): number {\r\n        if (value === 0 || value === 255 || value === -16777216) {\r\n            return 0;\r\n        }\r\n\r\n        return 1 + DDSTools._ExtractLongWordOrder(value >> 8);\r\n    }\r\n\r\n    private static _GetRGBArrayBuffer(\r\n        width: number,\r\n        height: number,\r\n        dataOffset: number,\r\n        dataLength: number,\r\n        arrayBuffer: ArrayBufferLike,\r\n        rOffset: number,\r\n        gOffset: number,\r\n        bOffset: number\r\n    ): Uint8Array {\r\n        const byteArray = new Uint8Array(dataLength);\r\n        const srcData = new Uint8Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcPos = (x + y * width) * 3;\r\n\r\n                byteArray[index] = srcData[srcPos + rOffset];\r\n                byteArray[index + 1] = srcData[srcPos + gOffset];\r\n                byteArray[index + 2] = srcData[srcPos + bOffset];\r\n                index += 3;\r\n            }\r\n        }\r\n\r\n        return byteArray;\r\n    }\r\n\r\n    private static _GetLuminanceArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBufferLike): Uint8Array {\r\n        const byteArray = new Uint8Array(dataLength);\r\n        const srcData = new Uint8Array(arrayBuffer, dataOffset);\r\n        let index = 0;\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcPos = x + y * width;\r\n                byteArray[index] = srcData[srcPos];\r\n                index++;\r\n            }\r\n        }\r\n\r\n        return byteArray;\r\n    }\r\n\r\n    /**\r\n     * Uploads DDS Levels to a Babylon Texture\r\n     * @internal\r\n     */\r\n    public static UploadDDSLevels(\r\n        engine: AbstractEngine,\r\n        texture: InternalTexture,\r\n        data: ArrayBufferView,\r\n        info: DDSInfo,\r\n        loadMipmaps: boolean,\r\n        faces: number,\r\n        lodIndex = -1,\r\n        currentFace?: number,\r\n        destTypeMustBeFilterable = true\r\n    ) {\r\n        let sphericalPolynomialFaces: Nullable<Array<ArrayBufferView>> = null;\r\n        if (info.sphericalPolynomial) {\r\n            sphericalPolynomialFaces = [] as ArrayBufferView[];\r\n        }\r\n        const ext = !!engine.getCaps().s3tc;\r\n\r\n        // TODO WEBGPU Once generateMipMaps is split into generateMipMaps + hasMipMaps in InternalTexture this line can be removed\r\n        texture.generateMipMaps = loadMipmaps;\r\n\r\n        const header = new Int32Array(data.buffer, data.byteOffset, headerLengthInt);\r\n        let fourCC: number,\r\n            width: number,\r\n            height: number,\r\n            dataLength: number = 0,\r\n            dataOffset: number;\r\n        let byteArray: Uint8Array, mipmapCount: number, mip: number;\r\n        let internalCompressedFormat = 0;\r\n        let blockBytes = 1;\r\n\r\n        if (header[off_magic] !== DDS_MAGIC) {\r\n            Logger.Error(\"Invalid magic number in DDS header\");\r\n            return;\r\n        }\r\n\r\n        if (!info.isFourCC && !info.isRGB && !info.isLuminance) {\r\n            Logger.Error(\"Unsupported format, must contain a FourCC, RGB or LUMINANCE code\");\r\n            return;\r\n        }\r\n\r\n        if (info.isCompressed && !ext) {\r\n            Logger.Error(\"Compressed textures are not supported on this platform.\");\r\n            return;\r\n        }\r\n\r\n        let bpp = header[off_RGBbpp];\r\n        dataOffset = header[off_size] + 4;\r\n\r\n        let computeFormats = false;\r\n\r\n        if (info.isFourCC) {\r\n            fourCC = header[off_pfFourCC];\r\n            switch (fourCC) {\r\n                case FOURCC_DXT1:\r\n                    blockBytes = 8;\r\n                    internalCompressedFormat = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1;\r\n                    break;\r\n                case FOURCC_DXT3:\r\n                    blockBytes = 16;\r\n                    internalCompressedFormat = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3;\r\n                    break;\r\n                case FOURCC_DXT5:\r\n                    blockBytes = 16;\r\n                    internalCompressedFormat = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5;\r\n                    break;\r\n                case FOURCC_D3DFMT_R16G16B16A16F:\r\n                    computeFormats = true;\r\n                    bpp = 64;\r\n                    break;\r\n                case FOURCC_D3DFMT_R32G32B32A32F:\r\n                    computeFormats = true;\r\n                    bpp = 128;\r\n                    break;\r\n                case FOURCC_DX10: {\r\n                    // There is an additionnal header so dataOffset need to be changed\r\n                    dataOffset += 5 * 4; // 5 uints\r\n\r\n                    let supported = false;\r\n                    switch (info.dxgiFormat) {\r\n                        case DXGI_FORMAT_R16G16B16A16_FLOAT:\r\n                            computeFormats = true;\r\n                            bpp = 64;\r\n                            supported = true;\r\n                            break;\r\n                        case DXGI_FORMAT_R32G32B32A32_FLOAT:\r\n                            computeFormats = true;\r\n                            bpp = 128;\r\n                            supported = true;\r\n                            break;\r\n                        case DXGI_FORMAT_B8G8R8X8_UNORM:\r\n                            info.isRGB = true;\r\n                            info.isFourCC = false;\r\n                            bpp = 32;\r\n                            supported = true;\r\n                            break;\r\n                    }\r\n\r\n                    if (supported) {\r\n                        break;\r\n                    }\r\n                }\r\n                // eslint-disable-next-line no-fallthrough\r\n                default:\r\n                    Logger.Error([\"Unsupported FourCC code:\", Int32ToFourCC(fourCC)]);\r\n                    return;\r\n            }\r\n        }\r\n\r\n        const rOffset = DDSTools._ExtractLongWordOrder(header[off_RMask]);\r\n        const gOffset = DDSTools._ExtractLongWordOrder(header[off_GMask]);\r\n        const bOffset = DDSTools._ExtractLongWordOrder(header[off_BMask]);\r\n        const aOffset = DDSTools._ExtractLongWordOrder(header[off_AMask]);\r\n\r\n        if (computeFormats) {\r\n            internalCompressedFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);\r\n        }\r\n\r\n        mipmapCount = 1;\r\n        if (header[off_flags] & DDSD_MIPMAPCOUNT && loadMipmaps !== false) {\r\n            mipmapCount = Math.max(1, header[off_mipmapCount]);\r\n        }\r\n\r\n        const startFace = currentFace || 0;\r\n        const caps = engine.getCaps();\r\n        for (let face = startFace; face < faces; face++) {\r\n            width = header[off_width];\r\n            height = header[off_height];\r\n\r\n            for (mip = 0; mip < mipmapCount; ++mip) {\r\n                if (lodIndex === -1 || lodIndex === mip) {\r\n                    // In case of fixed LOD, if the lod has just been uploaded, early exit.\r\n                    const i = lodIndex === -1 ? mip : 0;\r\n\r\n                    if (!info.isCompressed && info.isFourCC) {\r\n                        texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n                        dataLength = width * height * 4;\r\n                        let floatArray: Nullable<ArrayBufferView> = null;\r\n\r\n                        if (engine._badOS || engine._badDesktopOS || (!caps.textureHalfFloat && !caps.textureFloat)) {\r\n                            // Required because iOS has many issues with float and half float generation\r\n                            if (bpp === 128) {\r\n                                floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);\r\n                                if (sphericalPolynomialFaces && i == 0) {\r\n                                    sphericalPolynomialFaces.push(DDSTools._GetFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i));\r\n                                }\r\n                            } else if (bpp === 64) {\r\n                                floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);\r\n                                if (sphericalPolynomialFaces && i == 0) {\r\n                                    sphericalPolynomialFaces.push(\r\n                                        DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i)\r\n                                    );\r\n                                }\r\n                            }\r\n\r\n                            texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                        } else {\r\n                            const floatAvailable = caps.textureFloat && ((destTypeMustBeFilterable && caps.textureFloatLinearFiltering) || !destTypeMustBeFilterable);\r\n                            const halfFloatAvailable = caps.textureHalfFloat && ((destTypeMustBeFilterable && caps.textureHalfFloatLinearFiltering) || !destTypeMustBeFilterable);\r\n\r\n                            const destType =\r\n                                (bpp === 128 || (bpp === 64 && !halfFloatAvailable)) && floatAvailable\r\n                                    ? Constants.TEXTURETYPE_FLOAT\r\n                                    : (bpp === 64 || (bpp === 128 && !floatAvailable)) && halfFloatAvailable\r\n                                      ? Constants.TEXTURETYPE_HALF_FLOAT\r\n                                      : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n                            let dataGetter: (width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBufferLike, lod: number) => ArrayBufferView;\r\n                            let dataGetterPolynomial: Nullable<\r\n                                (width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBufferLike, lod: number) => ArrayBufferView\r\n                            > = null;\r\n\r\n                            switch (bpp) {\r\n                                case 128: {\r\n                                    switch (destType) {\r\n                                        case Constants.TEXTURETYPE_FLOAT:\r\n                                            dataGetter = DDSTools._GetFloatRGBAArrayBuffer;\r\n                                            dataGetterPolynomial = null;\r\n                                            break;\r\n                                        case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                                            dataGetter = DDSTools._GetFloatAsHalfFloatRGBAArrayBuffer;\r\n                                            dataGetterPolynomial = DDSTools._GetFloatRGBAArrayBuffer;\r\n                                            break;\r\n                                        case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                                            dataGetter = DDSTools._GetFloatAsUIntRGBAArrayBuffer;\r\n                                            dataGetterPolynomial = DDSTools._GetFloatRGBAArrayBuffer;\r\n                                            break;\r\n                                    }\r\n                                    break;\r\n                                }\r\n                                default: {\r\n                                    // 64 bpp\r\n                                    switch (destType) {\r\n                                        case Constants.TEXTURETYPE_FLOAT:\r\n                                            dataGetter = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer;\r\n                                            dataGetterPolynomial = null;\r\n                                            break;\r\n                                        case Constants.TEXTURETYPE_HALF_FLOAT:\r\n                                            dataGetter = DDSTools._GetHalfFloatRGBAArrayBuffer;\r\n                                            dataGetterPolynomial = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer;\r\n                                            break;\r\n                                        case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n                                            dataGetter = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer;\r\n                                            dataGetterPolynomial = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer;\r\n                                            break;\r\n                                    }\r\n                                    break;\r\n                                }\r\n                            }\r\n\r\n                            texture.type = destType;\r\n\r\n                            floatArray = dataGetter(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);\r\n\r\n                            if (sphericalPolynomialFaces && i == 0) {\r\n                                sphericalPolynomialFaces.push(\r\n                                    dataGetterPolynomial ? dataGetterPolynomial(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i) : floatArray\r\n                                );\r\n                            }\r\n                        }\r\n\r\n                        if (floatArray) {\r\n                            engine._uploadDataToTextureDirectly(texture, floatArray, face, i);\r\n                        }\r\n                    } else if (info.isRGB) {\r\n                        texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                        if (bpp === 24) {\r\n                            texture.format = Constants.TEXTUREFORMAT_RGB;\r\n                            dataLength = width * height * 3;\r\n                            byteArray = DDSTools._GetRGBArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, rOffset, gOffset, bOffset);\r\n                            engine._uploadDataToTextureDirectly(texture, byteArray, face, i);\r\n                        } else {\r\n                            // 32\r\n                            texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n                            dataLength = width * height * 4;\r\n                            byteArray = DDSTools._GetRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, rOffset, gOffset, bOffset, aOffset);\r\n                            engine._uploadDataToTextureDirectly(texture, byteArray, face, i);\r\n                        }\r\n                    } else if (info.isLuminance) {\r\n                        const unpackAlignment = engine._getUnpackAlignement();\r\n                        const unpaddedRowSize = width;\r\n                        const paddedRowSize = Math.floor((width + unpackAlignment - 1) / unpackAlignment) * unpackAlignment;\r\n                        dataLength = paddedRowSize * (height - 1) + unpaddedRowSize;\r\n\r\n                        byteArray = DDSTools._GetLuminanceArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer);\r\n                        texture.format = Constants.TEXTUREFORMAT_LUMINANCE;\r\n                        texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n                        engine._uploadDataToTextureDirectly(texture, byteArray, face, i);\r\n                    } else {\r\n                        dataLength = (((Math.max(4, width) / 4) * Math.max(4, height)) / 4) * blockBytes;\r\n                        byteArray = new Uint8Array(data.buffer, data.byteOffset + dataOffset, dataLength);\r\n\r\n                        texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                        engine._uploadCompressedDataToTextureDirectly(texture, internalCompressedFormat, width, height, byteArray, face, i);\r\n                    }\r\n                }\r\n                dataOffset += bpp ? width * height * (bpp / 8) : dataLength;\r\n                width *= 0.5;\r\n                height *= 0.5;\r\n\r\n                width = Math.max(1.0, width);\r\n                height = Math.max(1.0, height);\r\n            }\r\n\r\n            if (currentFace !== undefined) {\r\n                // Loading a single face\r\n                break;\r\n            }\r\n        }\r\n        if (sphericalPolynomialFaces && sphericalPolynomialFaces.length > 0) {\r\n            info.sphericalPolynomial = CubeMapToSphericalPolynomialTools.ConvertCubeMapToSphericalPolynomial({\r\n                size: header[off_width],\r\n                right: sphericalPolynomialFaces[0],\r\n                left: sphericalPolynomialFaces[1],\r\n                up: sphericalPolynomialFaces[2],\r\n                down: sphericalPolynomialFaces[3],\r\n                front: sphericalPolynomialFaces[4],\r\n                back: sphericalPolynomialFaces[5],\r\n                format: Constants.TEXTUREFORMAT_RGBA,\r\n                type: Constants.TEXTURETYPE_FLOAT,\r\n                gammaSpace: false,\r\n            });\r\n        } else {\r\n            info.sphericalPolynomial = undefined;\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../../../types\";\r\nimport { SphericalPolynomial } from \"../../../Maths/sphericalPolynomial\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { type DDSInfo, DDSTools } from \"../../../Misc/dds.pure\";\r\n\r\nimport { type Engine } from \"core/Engines/engine\";\r\n\r\n/**\r\n * Implementation of the DDS Texture Loader.\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _DDSTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = true;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     * @param imgs contains the cube maps\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param createPolynomials will be true if polynomials have been requested\r\n     * @param onLoad defines the callback to trigger once the texture is ready\r\n     */\r\n    public loadCubeData(imgs: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>): void {\r\n        const engine = texture.getEngine() as Engine;\r\n        let info: DDSInfo | undefined;\r\n        let loadMipmap: boolean = false;\r\n        let maxLevel: number = 1000;\r\n        if (Array.isArray(imgs)) {\r\n            for (let index = 0; index < imgs.length; index++) {\r\n                const data = imgs[index];\r\n                info = DDSTools.GetDDSInfo(data);\r\n\r\n                texture.width = info.width;\r\n                texture.height = info.height;\r\n\r\n                loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && texture.generateMipMaps;\r\n\r\n                engine._unpackFlipY(info.isCompressed);\r\n\r\n                DDSTools.UploadDDSLevels(engine, texture, data, info, loadMipmap, 6, -1, index);\r\n\r\n                if (!info.isFourCC && info.mipmapCount === 1) {\r\n                    engine.generateMipMapsForCubemap(texture);\r\n                } else {\r\n                    maxLevel = info.mipmapCount - 1;\r\n                }\r\n            }\r\n        } else {\r\n            const data = imgs;\r\n            info = DDSTools.GetDDSInfo(data);\r\n\r\n            texture.width = info.width;\r\n            texture.height = info.height;\r\n\r\n            if (createPolynomials) {\r\n                info.sphericalPolynomial = new SphericalPolynomial();\r\n            }\r\n\r\n            loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && texture.generateMipMaps;\r\n            engine._unpackFlipY(info.isCompressed);\r\n\r\n            DDSTools.UploadDDSLevels(engine, texture, data, info, loadMipmap, 6);\r\n\r\n            if (!info.isFourCC && info.mipmapCount === 1) {\r\n                // Do not unbind as we still need to set the parameters.\r\n                engine.generateMipMapsForCubemap(texture, false);\r\n            } else {\r\n                maxLevel = info.mipmapCount - 1;\r\n            }\r\n        }\r\n        engine._setCubeMapTextureParams(texture, loadMipmap, maxLevel);\r\n        texture.isReady = true;\r\n        texture.onLoadedObservable.notifyObservers(texture);\r\n        texture.onLoadedObservable.clear();\r\n\r\n        if (onLoad) {\r\n            onLoad({ isDDS: true, width: texture.width, info, data: imgs, texture });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     */\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void\r\n    ): void {\r\n        const info = DDSTools.GetDDSInfo(data);\r\n\r\n        const loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && texture.generateMipMaps && Math.max(info.width, info.height) >> (info.mipmapCount - 1) === 1;\r\n        callback(info.width, info.height, loadMipmap, info.isFourCC, () => {\r\n            DDSTools.UploadDDSLevels(texture.getEngine(), texture, data, info, loadMipmap, 1);\r\n        });\r\n    }\r\n}\r\n","import { GetEnvInfo, UploadEnvLevelsAsync, UploadEnvSpherical } from \"../../../Misc/environmentTextureTools.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { RegisterBaseTexturePolynomial } from \"../baseTexture.polynomial.pure\";\r\n\r\n/**\r\n * Implementation of the ENV Texture Loader.\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _ENVTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param createPolynomials will be true if polynomials have been requested\r\n     * @param onLoad defines the callback to trigger once the texture is ready\r\n     * @param onError defines the callback to trigger in case of error\r\n     */\r\n    public loadCubeData(\r\n        data: ArrayBufferView | ArrayBufferView[],\r\n        texture: InternalTexture,\r\n        createPolynomials: boolean,\r\n        onLoad: Nullable<(data?: any) => void>,\r\n        onError: Nullable<(message?: string, exception?: any) => void>\r\n    ): void {\r\n        if (Array.isArray(data)) {\r\n            return;\r\n        }\r\n\r\n        const info = GetEnvInfo(data);\r\n        if (info) {\r\n            texture.width = info.width;\r\n            texture.height = info.width;\r\n\r\n            try {\r\n                RegisterBaseTexturePolynomial();\r\n                UploadEnvSpherical(texture, info);\r\n                // eslint-disable-next-line github/no-then\r\n                UploadEnvLevelsAsync(texture, data, info).then(\r\n                    () => {\r\n                        texture.isReady = true;\r\n                        texture.onLoadedObservable.notifyObservers(texture);\r\n                        texture.onLoadedObservable.clear();\r\n                        if (onLoad) {\r\n                            onLoad();\r\n                        }\r\n                    },\r\n                    (reason) => {\r\n                        onError?.(\"Can not upload environment levels\", reason);\r\n                    }\r\n                );\r\n            } catch (e) {\r\n                onError?.(\"Can not upload environment file\", e);\r\n            }\r\n        } else if (onError) {\r\n            onError(\"Can not parse the environment file\", null);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     */\r\n    public loadData(): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \".env not supported in 2d.\";\r\n    }\r\n}\r\n","export enum SourceTextureFormat {\r\n    ETC1S,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    UASTC4x4,\r\n    /** Uncompressed 8 bits per channel RGBA data, stored as-is in the container (no transcoding required) */\r\n    RGBA32,\r\n}\r\n\r\nexport enum TranscodeTarget {\r\n    ASTC_4X4_RGBA,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    ASTC_4x4_RGBA = ASTC_4X4_RGBA,\r\n    BC7_RGBA,\r\n    BC3_RGBA,\r\n    BC1_RGB,\r\n    PVRTC1_4_RGBA,\r\n    PVRTC1_4_RGB,\r\n    ETC2_RGBA,\r\n    ETC1_RGB,\r\n    RGBA32,\r\n    R8,\r\n    RG8,\r\n}\r\n\r\nexport const enum EngineFormat {\r\n    COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8e8c,\r\n    COMPRESSED_RGBA_ASTC_4X4_KHR = 0x93b0,\r\n    COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83f0,\r\n    COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83f3,\r\n    COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8c02,\r\n    COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8c00,\r\n    COMPRESSED_RGBA8_ETC2_EAC = 0x9278,\r\n    COMPRESSED_RGB8_ETC2 = 0x9274,\r\n    COMPRESSED_RGB_ETC1_WEBGL = 0x8d64,\r\n    RGBA8Format = 0x8058,\r\n    R8Format = 0x8229,\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    RG8Format = 0x822b,\r\n}\r\n\r\n/**\r\n * Leaf node of a decision tree\r\n * It defines the transcoding format to use to transcode the texture as well as the corresponding format to use at the engine level when creating the texture\r\n */\r\nexport interface ILeaf {\r\n    /**\r\n     * The format to transcode to\r\n     */\r\n    transcodeFormat: TranscodeTarget;\r\n\r\n    /**\r\n     * The format to use when creating the texture at the engine level after it has been transcoded to transcodeFormat\r\n     */\r\n    engineFormat: EngineFormat;\r\n\r\n    /**\r\n     * Whether the texture must be rounded to a multiple of 4 (should normally be the case for all compressed formats). Default: true\r\n     */\r\n    roundToMultiple4?: boolean;\r\n}\r\n\r\n/**\r\n * Regular node of a decision tree\r\n *\r\n * Each property (except for \"yes\" and \"no\"), if not empty, will be checked in order to determine the next node to select.\r\n * If all checks are successful, the \"yes\" node will be selected, else the \"no\" node will be selected.\r\n */\r\nexport interface INode {\r\n    /**\r\n     * The name of the capability to check. Can be one of the following:\r\n     *      astc\r\n     *      bptc\r\n     *      s3tc\r\n     *      pvrtc\r\n     *      etc2\r\n     *      etc1\r\n     */\r\n    cap?: string;\r\n\r\n    /**\r\n     * The name of the option to check from the options object passed to the KTX2 decode function. {@link IKTX2DecoderOptions}\r\n     */\r\n    option?: string;\r\n\r\n    /**\r\n     * Checks if alpha is present in the texture\r\n     */\r\n    alpha?: boolean;\r\n\r\n    /**\r\n     * Checks the currently selected transcoding format.\r\n     */\r\n    transcodeFormat?: TranscodeTarget | TranscodeTarget[];\r\n\r\n    /**\r\n     * Checks that the texture is a power of two\r\n     */\r\n    needsPowerOfTwo?: boolean;\r\n\r\n    /**\r\n     * The node to select if all checks are successful\r\n     */\r\n    yes?: INode | ILeaf;\r\n\r\n    /**\r\n     * The node to select if at least one check is not successful\r\n     */\r\n    no?: INode | ILeaf;\r\n}\r\n\r\n/**\r\n * Decision tree used to determine the transcoding format to use for a given source texture format\r\n */\r\nexport interface IDecisionTree {\r\n    /**\r\n     * textureFormat can be either UASTC, ETC1S or RGBA32\r\n     */\r\n    [textureFormat: string]: INode | ILeaf;\r\n}\r\n\r\n/**\r\n * Result of the KTX2 decode function\r\n */\r\nexport interface IDecodedData {\r\n    /**\r\n     * Width of the texture\r\n     */\r\n    width: number;\r\n\r\n    /**\r\n     * Height of the texture\r\n     */\r\n    height: number;\r\n\r\n    /**\r\n     * The format to use when creating the texture at the engine level\r\n     * This corresponds to the engineFormat property of the leaf node of the decision tree\r\n     */\r\n    transcodedFormat: number;\r\n\r\n    /**\r\n     * List of mipmap levels.\r\n     * The first element is the base level, the last element is the smallest mipmap level (if more than one mipmap level is present)\r\n     * For array textures (layerCount greater than 1), each level contributes layerCount consecutive entries, ordered by layer.\r\n     */\r\n    mipmaps: Array<IMipmap>;\r\n\r\n    /**\r\n     * Number of array layers of the texture. 1 for a regular (non array) texture\r\n     */\r\n    layerCount: number;\r\n\r\n    /**\r\n     * Whether the texture data is in gamma space or not\r\n     */\r\n    isInGammaSpace: boolean;\r\n\r\n    /**\r\n     * Whether the texture has an alpha channel or not\r\n     */\r\n    hasAlpha: boolean;\r\n\r\n    /**\r\n     * The name of the transcoder used to transcode the texture\r\n     */\r\n    transcoderName: string;\r\n\r\n    /**\r\n     * The errors (if any) encountered during the decoding process\r\n     */\r\n    errors?: string;\r\n}\r\n\r\n/**\r\n * Defines a mipmap level\r\n */\r\nexport interface IMipmap {\r\n    /**\r\n     * The data of the mipmap level\r\n     */\r\n    data: Uint8Array | null;\r\n\r\n    /**\r\n     * The width of the mipmap level\r\n     */\r\n    width: number;\r\n\r\n    /**\r\n     * The height of the mipmap level\r\n     */\r\n    height: number;\r\n\r\n    /**\r\n     * The array layer this mipmap level belongs to. 0 for a regular (non array) texture\r\n     */\r\n    layerIndex: number;\r\n}\r\n\r\n/**\r\n * The compressed texture formats supported by the browser\r\n */\r\nexport interface ICompressedFormatCapabilities {\r\n    /**\r\n     * Whether the browser supports ASTC\r\n     */\r\n    astc?: boolean;\r\n\r\n    /**\r\n     * Whether the browser supports BPTC\r\n     */\r\n    bptc?: boolean;\r\n\r\n    /**\r\n     * Whether the browser supports S3TC\r\n     */\r\n    s3tc?: boolean;\r\n\r\n    /**\r\n     * Whether the browser supports PVRTC\r\n     */\r\n    pvrtc?: boolean;\r\n\r\n    /**\r\n     * Whether the browser supports ETC2\r\n     */\r\n    etc2?: boolean;\r\n\r\n    /**\r\n     * Whether the browser supports ETC1\r\n     */\r\n    etc1?: boolean;\r\n}\r\n\r\n/**\r\n * Options passed to the KTX2 decode function\r\n */\r\nexport interface IKTX2DecoderOptions {\r\n    /** use RGBA format if ASTC and BC7 are not available as transcoded format */\r\n    useRGBAIfASTCBC7NotAvailableWhenUASTC?: boolean;\r\n\r\n    /** force to always use (uncompressed) RGBA for transcoded format */\r\n    forceRGBA?: boolean;\r\n\r\n    /** force to always use (uncompressed) R8 for transcoded format */\r\n    forceR8?: boolean;\r\n\r\n    /** force to always use (uncompressed) RG8 for transcoded format */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    forceRG8?: boolean;\r\n\r\n    /**\r\n     * list of transcoders to bypass when looking for a suitable transcoder. The available transcoders are:\r\n     *      UniversalTranscoder_UASTC_ASTC\r\n     *      UniversalTranscoder_UASTC_BC7\r\n     *      UniversalTranscoder_UASTC_RGBA_UNORM\r\n     *      UniversalTranscoder_UASTC_RGBA_SRGB\r\n     *      UniversalTranscoder_UASTC_R8_UNORM\r\n     *      UniversalTranscoder_UASTC_RG8_UNORM\r\n     *      MSCTranscoder\r\n     */\r\n    bypassTranscoders?: string[];\r\n\r\n    /**\r\n     * Custom decision tree to apply after the default decision tree has selected a transcoding format.\r\n     * Allows the user to override the default decision tree selection.\r\n     * The decision tree can use the INode.transcodeFormat property to base its decision on the transcoding format selected by the default decision tree.\r\n     */\r\n    transcodeFormatDecisionTree?: IDecisionTree;\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\n\r\n/**\r\n * for description see https://www.khronos.org/opengles/sdk/tools/KTX/\r\n * for file layout see https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/\r\n */\r\nexport class KhronosTextureContainer {\r\n    private static HEADER_LEN = 12 + 13 * 4; // identifier + header elements (not including key value meta-data pairs)\r\n\r\n    // load types\r\n    private static COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D()\r\n    private static COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D()\r\n    private static TEX_2D = 2; // uses a gl.texImage2D()\r\n    private static TEX_3D = 3; // uses a gl.texImage3D()\r\n\r\n    // elements of the header\r\n    /**\r\n     * Gets the openGL type\r\n     */\r\n    public glType: number;\r\n    /**\r\n     * Gets the openGL type size\r\n     */\r\n    public glTypeSize: number;\r\n    /**\r\n     * Gets the openGL format\r\n     */\r\n    public glFormat: number;\r\n    /**\r\n     * Gets the openGL internal format\r\n     */\r\n    public glInternalFormat: number;\r\n    /**\r\n     * Gets the base internal format\r\n     */\r\n    public glBaseInternalFormat: number;\r\n    /**\r\n     * Gets image width in pixel\r\n     */\r\n    public pixelWidth: number;\r\n    /**\r\n     * Gets image height in pixel\r\n     */\r\n    public pixelHeight: number;\r\n    /**\r\n     * Gets image depth in pixels\r\n     */\r\n    public pixelDepth: number;\r\n    /**\r\n     * Gets the number of array elements\r\n     */\r\n    public numberOfArrayElements: number;\r\n    /**\r\n     * Gets the number of faces\r\n     */\r\n    public numberOfFaces: number;\r\n    /**\r\n     * Gets the number of mipmap levels\r\n     */\r\n    public numberOfMipmapLevels: number;\r\n    /**\r\n     * Gets the bytes of key value data\r\n     */\r\n    public bytesOfKeyValueData: number;\r\n    /**\r\n     * Gets the load type\r\n     */\r\n    public loadType: number;\r\n    /**\r\n     * If the container has been made invalid (eg. constructor failed to correctly load array buffer)\r\n     */\r\n    public isInvalid = false;\r\n\r\n    /**\r\n     * Creates a new KhronosTextureContainer\r\n     * @param data contents of the KTX container file\r\n     * @param facesExpected should be either 1 or 6, based whether a cube texture or or\r\n     */\r\n    public constructor(\r\n        /** contents of the KTX container file */\r\n        public data: ArrayBufferView,\r\n        facesExpected: number\r\n    ) {\r\n        if (!KhronosTextureContainer.IsValid(data)) {\r\n            this.isInvalid = true;\r\n            Logger.Error(\"texture missing KTX identifier\");\r\n            return;\r\n        }\r\n\r\n        // load the reset of the header in native 32 bit uint\r\n        const dataSize = Uint32Array.BYTES_PER_ELEMENT;\r\n        const headerDataView = new DataView(this.data.buffer, this.data.byteOffset + 12, 13 * dataSize);\r\n        const endianness = headerDataView.getUint32(0, true);\r\n        const littleEndian = endianness === 0x04030201;\r\n\r\n        this.glType = headerDataView.getUint32(1 * dataSize, littleEndian); // must be 0 for compressed textures\r\n        this.glTypeSize = headerDataView.getUint32(2 * dataSize, littleEndian); // must be 1 for compressed textures\r\n        this.glFormat = headerDataView.getUint32(3 * dataSize, littleEndian); // must be 0 for compressed textures\r\n        this.glInternalFormat = headerDataView.getUint32(4 * dataSize, littleEndian); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)\r\n        this.glBaseInternalFormat = headerDataView.getUint32(5 * dataSize, littleEndian); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)\r\n        this.pixelWidth = headerDataView.getUint32(6 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)\r\n        this.pixelHeight = headerDataView.getUint32(7 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)\r\n        this.pixelDepth = headerDataView.getUint32(8 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)\r\n        this.numberOfArrayElements = headerDataView.getUint32(9 * dataSize, littleEndian); // used for texture arrays\r\n        this.numberOfFaces = headerDataView.getUint32(10 * dataSize, littleEndian); // used for cubemap textures, should either be 1 or 6\r\n        this.numberOfMipmapLevels = headerDataView.getUint32(11 * dataSize, littleEndian); // number of levels; disregard possibility of 0 for compressed textures\r\n        this.bytesOfKeyValueData = headerDataView.getUint32(12 * dataSize, littleEndian); // the amount of space after the header for meta-data\r\n\r\n        // Make sure we have a compressed type.  Not only reduces work, but probably better to let dev know they are not compressing.\r\n        if (this.glType !== 0) {\r\n            Logger.Error(\"only compressed formats currently supported\");\r\n            this.isInvalid = true;\r\n            return;\r\n        } else {\r\n            // value of zero is an indication to generate mipmaps @ runtime.  Not usually allowed for compressed, so disregard.\r\n            this.numberOfMipmapLevels = Math.max(1, this.numberOfMipmapLevels);\r\n        }\r\n\r\n        if (this.pixelHeight === 0 || this.pixelDepth !== 0) {\r\n            Logger.Error(\"only 2D textures currently supported\");\r\n            this.isInvalid = true;\r\n            return;\r\n        }\r\n\r\n        if (this.numberOfArrayElements !== 0) {\r\n            Logger.Error(\"texture arrays not currently supported\");\r\n            this.isInvalid = true;\r\n            return;\r\n        }\r\n\r\n        if (this.numberOfFaces !== facesExpected) {\r\n            Logger.Error(\"number of faces expected\" + facesExpected + \", but found \" + this.numberOfFaces);\r\n            this.isInvalid = true;\r\n            return;\r\n        }\r\n\r\n        // we now have a completely validated file, so could use existence of loadType as success\r\n        // would need to make this more elaborate & adjust checks above to support more than one load type\r\n        this.loadType = KhronosTextureContainer.COMPRESSED_2D;\r\n    }\r\n\r\n    /**\r\n     * Uploads KTX content to a Babylon Texture.\r\n     * It is assumed that the texture has already been created & is currently bound\r\n     * @internal\r\n     */\r\n    public uploadLevels(texture: InternalTexture, loadMipmaps: boolean): void {\r\n        switch (this.loadType) {\r\n            case KhronosTextureContainer.COMPRESSED_2D:\r\n                this._upload2DCompressedLevels(texture, loadMipmaps);\r\n                break;\r\n\r\n            case KhronosTextureContainer.TEX_2D:\r\n            case KhronosTextureContainer.COMPRESSED_3D:\r\n            case KhronosTextureContainer.TEX_3D:\r\n        }\r\n    }\r\n\r\n    private _upload2DCompressedLevels(texture: InternalTexture, loadMipmaps: boolean): void {\r\n        // initialize width & height for level 1\r\n        let dataOffset = KhronosTextureContainer.HEADER_LEN + this.bytesOfKeyValueData;\r\n        let width = this.pixelWidth;\r\n        let height = this.pixelHeight;\r\n\r\n        const mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;\r\n        for (let level = 0; level < mipmapCount; level++) {\r\n            const imageSize = new Int32Array(this.data.buffer, this.data.byteOffset + dataOffset, 1)[0]; // size per face, since not supporting array cubemaps\r\n            dataOffset += 4; //image data starts from next multiple of 4 offset. Each face refers to same imagesize field above.\r\n            for (let face = 0; face < this.numberOfFaces; face++) {\r\n                const byteArray = new Uint8Array(this.data.buffer, this.data.byteOffset + dataOffset, imageSize);\r\n\r\n                const engine = texture.getEngine();\r\n                engine._uploadCompressedDataToTextureDirectly(texture, texture.format, width, height, byteArray, face, level);\r\n\r\n                dataOffset += imageSize; // add size of the image for the next face/mipmap\r\n                dataOffset += 3 - ((imageSize + 3) % 4); // add padding for odd sized image\r\n            }\r\n            width = Math.max(1.0, width * 0.5);\r\n            height = Math.max(1.0, height * 0.5);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if the given data starts with a KTX file identifier.\r\n     * @param data the data to check\r\n     * @returns true if the data is a KTX file or false otherwise\r\n     */\r\n    public static IsValid(data: ArrayBufferView): boolean {\r\n        if (data.byteLength >= 12) {\r\n            // '«', 'K', 'T', 'X', ' ', '1', '1', '»', '\\r', '\\n', '\\x1A', '\\n'\r\n            const identifier = new Uint8Array(data.buffer, data.byteOffset, 12);\r\n            if (\r\n                identifier[0] === 0xab &&\r\n                identifier[1] === 0x4b &&\r\n                identifier[2] === 0x54 &&\r\n                identifier[3] === 0x58 &&\r\n                identifier[4] === 0x20 &&\r\n                identifier[5] === 0x31 &&\r\n                identifier[6] === 0x31 &&\r\n                identifier[7] === 0xbb &&\r\n                identifier[8] === 0x0d &&\r\n                identifier[9] === 0x0a &&\r\n                identifier[10] === 0x1a &&\r\n                identifier[11] === 0x0a\r\n            ) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n}\r\n","import { type IDisposable } from \"../scene\";\r\n\r\ninterface IWorkerInfo {\r\n    workerPromise: Promise<Worker>;\r\n    idle: boolean;\r\n    timeoutId?: ReturnType<typeof setTimeout>;\r\n}\r\n\r\n/**\r\n * Helper class to push actions to a pool of workers.\r\n */\r\nexport class WorkerPool implements IDisposable {\r\n    protected _workerInfos: Array<IWorkerInfo>;\r\n    protected _pendingActions = new Array<(worker: Worker, onComplete: () => void) => void>();\r\n\r\n    /**\r\n     * Constructor\r\n     * @param workers Array of workers to use for actions\r\n     */\r\n    constructor(workers: Array<Worker>) {\r\n        this._workerInfos = workers.map((worker) => ({\r\n            workerPromise: Promise.resolve(worker),\r\n            idle: true,\r\n        }));\r\n    }\r\n\r\n    /**\r\n     * Terminates all workers and clears any pending actions.\r\n     */\r\n    public dispose(): void {\r\n        for (const workerInfo of this._workerInfos) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            workerInfo.workerPromise.then((worker) => {\r\n                worker.terminate();\r\n            });\r\n        }\r\n\r\n        this._workerInfos.length = 0;\r\n        this._pendingActions.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Pushes an action to the worker pool. If all the workers are active, the action will be\r\n     * pended until a worker has completed its action.\r\n     * @param action The action to perform. Call onComplete when the action is complete.\r\n     */\r\n    public push(action: (worker: Worker, onComplete: () => void) => void): void {\r\n        if (!this._executeOnIdleWorker(action)) {\r\n            this._pendingActions.push(action);\r\n        }\r\n    }\r\n\r\n    protected _executeOnIdleWorker(action: (worker: Worker, onComplete: () => void) => void): boolean {\r\n        for (const workerInfo of this._workerInfos) {\r\n            if (workerInfo.idle) {\r\n                this._execute(workerInfo, action);\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    protected _execute(workerInfo: IWorkerInfo, action: (worker: Worker, onComplete: () => void) => void): void {\r\n        workerInfo.idle = false;\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        workerInfo.workerPromise.then((worker) => {\r\n            action(worker, () => {\r\n                const nextAction = this._pendingActions.shift();\r\n                if (nextAction) {\r\n                    this._execute(workerInfo, nextAction);\r\n                } else {\r\n                    workerInfo.idle = true;\r\n                }\r\n            });\r\n        });\r\n    }\r\n}\r\n\r\n/**\r\n * Options for AutoReleaseWorkerPool\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface AutoReleaseWorkerPoolOptions {\r\n    /**\r\n     * Idle time elapsed before workers are terminated.\r\n     */\r\n    idleTimeElapsedBeforeRelease: number;\r\n}\r\n\r\n/**\r\n * Similar to the WorkerPool class except it creates and destroys workers automatically with a maximum of `maxWorkers` workers.\r\n * Workers are terminated when it is idle for at least `idleTimeElapsedBeforeRelease` milliseconds.\r\n */\r\nexport class AutoReleaseWorkerPool extends WorkerPool {\r\n    /**\r\n     * Default options for the constructor.\r\n     * Override to change the defaults.\r\n     */\r\n    public static DefaultOptions: AutoReleaseWorkerPoolOptions = {\r\n        idleTimeElapsedBeforeRelease: 1000,\r\n    };\r\n\r\n    private readonly _maxWorkers: number;\r\n    private readonly _createWorkerAsync: () => Promise<Worker>;\r\n    private readonly _options: AutoReleaseWorkerPoolOptions;\r\n\r\n    constructor(maxWorkers: number, createWorkerAsync: () => Promise<Worker>, options = AutoReleaseWorkerPool.DefaultOptions) {\r\n        super([]);\r\n\r\n        this._maxWorkers = maxWorkers;\r\n        this._createWorkerAsync = createWorkerAsync;\r\n        this._options = options;\r\n    }\r\n\r\n    public override push(action: (worker: Worker, onComplete: () => void) => void): void {\r\n        if (!this._executeOnIdleWorker(action)) {\r\n            if (this._workerInfos.length < this._maxWorkers) {\r\n                const workerInfo: IWorkerInfo = {\r\n                    workerPromise: this._createWorkerAsync(),\r\n                    idle: false,\r\n                };\r\n                this._workerInfos.push(workerInfo);\r\n                this._execute(workerInfo, action);\r\n            } else {\r\n                this._pendingActions.push(action);\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _execute(workerInfo: IWorkerInfo, action: (worker: Worker, onComplete: () => void) => void): void {\r\n        // Reset the idle timeout.\r\n        if (workerInfo.timeoutId) {\r\n            clearTimeout(workerInfo.timeoutId);\r\n            delete workerInfo.timeoutId;\r\n        }\r\n\r\n        super._execute(workerInfo, (worker, onComplete) => {\r\n            action(worker, () => {\r\n                onComplete();\r\n\r\n                if (workerInfo.idle) {\r\n                    // Schedule the worker to be terminated after the elapsed time.\r\n                    workerInfo.timeoutId = setTimeout(() => {\r\n                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                        workerInfo.workerPromise.then((worker) => {\r\n                            worker.terminate();\r\n                        });\r\n\r\n                        const indexOf = this._workerInfos.indexOf(workerInfo);\r\n                        if (indexOf !== -1) {\r\n                            this._workerInfos.splice(indexOf, 1);\r\n                        }\r\n                    }, this._options.idleTimeElapsedBeforeRelease);\r\n                }\r\n            });\r\n        });\r\n    }\r\n}\r\n","import { type IDecodedData } from \"core/Materials/Textures/ktx2decoderTypes\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nexport type AllowedKeys =\r\n    | \"wasmBaseUrl\"\r\n    | \"wasmUASTCToASTC\"\r\n    | \"wasmUASTCToBC7\"\r\n    | \"wasmUASTCToRGBA_UNORM\"\r\n    | \"wasmUASTCToRGBA_SRGB\"\r\n    | \"wasmUASTCToR8_UNORM\"\r\n    | \"wasmUASTCToRG8_UNORM\"\r\n    | \"wasmMSCTranscoder\"\r\n    | \"wasmZSTDDecoder\"\r\n    | \"jsDecoderModule\"\r\n    | \"jsMSCTranscoder\";\r\n\r\ndeclare function importScripts(...urls: string[]): void;\r\ndeclare function postMessage(message: any, transfer?: any[]): void;\r\ndeclare let KTX2DECODER: any;\r\n\r\nexport function applyConfig(urls?: { [key in AllowedKeys]: string }, binariesAndModulesContainer?: { [key in AllowedKeys]: ArrayBuffer | any }): void {\r\n    const KTX2DecoderModule = binariesAndModulesContainer?.jsDecoderModule || KTX2DECODER;\r\n\r\n    if (urls) {\r\n        if (urls.wasmBaseUrl) {\r\n            KTX2DecoderModule.Transcoder.WasmBaseUrl = urls.wasmBaseUrl;\r\n        }\r\n\r\n        if (urls.wasmUASTCToASTC) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_ASTC.WasmModuleURL = urls.wasmUASTCToASTC;\r\n        }\r\n\r\n        if (urls.wasmUASTCToBC7) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_BC7.WasmModuleURL = urls.wasmUASTCToBC7;\r\n        }\r\n\r\n        if (urls.wasmUASTCToRGBA_UNORM) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_RGBA_UNORM.WasmModuleURL = urls.wasmUASTCToRGBA_UNORM;\r\n        }\r\n\r\n        if (urls.wasmUASTCToRGBA_SRGB) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_RGBA_SRGB.WasmModuleURL = urls.wasmUASTCToRGBA_SRGB;\r\n        }\r\n\r\n        if (urls.wasmUASTCToR8_UNORM) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_R8_UNORM.WasmModuleURL = urls.wasmUASTCToR8_UNORM;\r\n        }\r\n\r\n        if (urls.wasmUASTCToRG8_UNORM) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_RG8_UNORM.WasmModuleURL = urls.wasmUASTCToRG8_UNORM;\r\n        }\r\n\r\n        if (urls.jsMSCTranscoder) {\r\n            KTX2DecoderModule.MSCTranscoder.JSModuleURL = urls.jsMSCTranscoder;\r\n        }\r\n\r\n        if (urls.wasmMSCTranscoder) {\r\n            KTX2DecoderModule.MSCTranscoder.WasmModuleURL = urls.wasmMSCTranscoder;\r\n        }\r\n\r\n        if (urls.wasmZSTDDecoder) {\r\n            KTX2DecoderModule.ZSTDDecoder.WasmModuleURL = urls.wasmZSTDDecoder;\r\n        }\r\n    }\r\n    if (binariesAndModulesContainer) {\r\n        if (binariesAndModulesContainer.wasmUASTCToASTC) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_ASTC.WasmBinary = binariesAndModulesContainer.wasmUASTCToASTC;\r\n        }\r\n        if (binariesAndModulesContainer.wasmUASTCToBC7) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_BC7.WasmBinary = binariesAndModulesContainer.wasmUASTCToBC7;\r\n        }\r\n        if (binariesAndModulesContainer.wasmUASTCToRGBA_UNORM) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_RGBA_UNORM.WasmBinary = binariesAndModulesContainer.wasmUASTCToRGBA_UNORM;\r\n        }\r\n        if (binariesAndModulesContainer.wasmUASTCToRGBA_SRGB) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_RGBA_SRGB.WasmBinary = binariesAndModulesContainer.wasmUASTCToRGBA_SRGB;\r\n        }\r\n        if (binariesAndModulesContainer.wasmUASTCToR8_UNORM) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_R8_UNORM.WasmBinary = binariesAndModulesContainer.wasmUASTCToR8_UNORM;\r\n        }\r\n        if (binariesAndModulesContainer.wasmUASTCToRG8_UNORM) {\r\n            KTX2DecoderModule.LiteTranscoder_UASTC_RG8_UNORM.WasmBinary = binariesAndModulesContainer.wasmUASTCToRG8_UNORM;\r\n        }\r\n        if (binariesAndModulesContainer.jsMSCTranscoder) {\r\n            KTX2DecoderModule.MSCTranscoder.JSModule = binariesAndModulesContainer.jsMSCTranscoder;\r\n        }\r\n        if (binariesAndModulesContainer.wasmMSCTranscoder) {\r\n            KTX2DecoderModule.MSCTranscoder.WasmBinary = binariesAndModulesContainer.wasmMSCTranscoder;\r\n        }\r\n        if (binariesAndModulesContainer.wasmZSTDDecoder) {\r\n            KTX2DecoderModule.ZSTDDecoder.WasmBinary = binariesAndModulesContainer.wasmZSTDDecoder;\r\n        }\r\n    }\r\n}\r\n\r\nexport function workerFunction(KTX2DecoderModule: any): void {\r\n    if (typeof KTX2DecoderModule === \"undefined\" && typeof KTX2DECODER !== \"undefined\") {\r\n        KTX2DecoderModule = KTX2DECODER;\r\n    }\r\n    let ktx2Decoder: any;\r\n\r\n    onmessage = (event) => {\r\n        if (!event.data) {\r\n            return;\r\n        }\r\n        switch (event.data.action) {\r\n            case \"init\": {\r\n                const urls = event.data.urls;\r\n                if (urls) {\r\n                    if (urls.jsDecoderModule && typeof KTX2DecoderModule === \"undefined\") {\r\n                        importScripts(urls.jsDecoderModule);\r\n                        // assuming global namespace populated by the script (UMD pattern)\r\n                        KTX2DecoderModule = KTX2DECODER;\r\n                    }\r\n                    applyConfig(urls);\r\n                }\r\n                if (event.data.wasmBinaries) {\r\n                    applyConfig(undefined, { ...event.data.wasmBinaries, jsDecoderModule: KTX2DecoderModule });\r\n                }\r\n                ktx2Decoder = new KTX2DecoderModule.KTX2Decoder();\r\n                postMessage({ action: \"init\" });\r\n                break;\r\n            }\r\n            case \"setDefaultDecoderOptions\": {\r\n                KTX2DecoderModule.KTX2Decoder.DefaultDecoderOptions = event.data.options;\r\n                break;\r\n            }\r\n            case \"decode\":\r\n                ktx2Decoder\r\n                    .decode(event.data.data, event.data.caps, event.data.options)\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((data: IDecodedData) => {\r\n                        const buffers = [];\r\n                        for (let mip = 0; mip < data.mipmaps.length; ++mip) {\r\n                            const mipmap = data.mipmaps[mip];\r\n                            if (mipmap && mipmap.data) {\r\n                                buffers.push(mipmap.data.buffer);\r\n                            }\r\n                        }\r\n                        postMessage({ action: \"decoded\", success: true, decodedData: data }, buffers);\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((reason: any) => {\r\n                        postMessage({ action: \"decoded\", success: false, msg: reason });\r\n                    });\r\n                break;\r\n        }\r\n    };\r\n}\r\n\r\nexport async function initializeWebWorker(worker: Worker, wasmBinaries?: { [key in AllowedKeys]?: ArrayBuffer }, urls?: { [key in AllowedKeys]: string }): Promise<Worker> {\r\n    return await new Promise((resolve, reject) => {\r\n        const onError = (error: ErrorEvent) => {\r\n            worker.removeEventListener(\"error\", onError);\r\n            worker.removeEventListener(\"message\", onMessage);\r\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n            reject(error);\r\n        };\r\n\r\n        const onMessage = (message: MessageEvent) => {\r\n            if (message.data.action === \"init\") {\r\n                worker.removeEventListener(\"error\", onError);\r\n                worker.removeEventListener(\"message\", onMessage);\r\n                resolve(worker);\r\n            }\r\n        };\r\n\r\n        worker.addEventListener(\"error\", onError);\r\n        worker.addEventListener(\"message\", onMessage);\r\n\r\n        worker.postMessage({\r\n            action: \"init\",\r\n            urls,\r\n            wasmBinaries,\r\n        });\r\n    });\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { AutoReleaseWorkerPool } from \"./workerPool\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type ICompressedFormatCapabilities, type IDecodedData, type IKTX2DecoderOptions, EngineFormat, TranscodeTarget } from \"core/Materials/Textures/ktx2decoderTypes\";\r\nimport { type AllowedKeys, applyConfig, initializeWebWorker, workerFunction } from \"./khronosTextureContainer2Worker\";\r\n\r\ndeclare let KTX2DECODER: any;\r\n\r\n/**\r\n * Class that defines the default KTX2 decoder options.\r\n *\r\n * This class is useful for providing options to the KTX2 decoder to control how the source data is transcoded.\r\n */\r\nexport class DefaultKTX2DecoderOptions {\r\n    private _isDirty = true;\r\n\r\n    /**\r\n     * Gets the dirty flag\r\n     */\r\n    public get isDirty() {\r\n        return this._isDirty;\r\n    }\r\n\r\n    private _useRGBAIfASTCBC7NotAvailableWhenUASTC?: boolean;\r\n    /**\r\n     * force a (uncompressed) RGBA transcoded format if transcoding a UASTC source format and ASTC + BC7 are not available as a compressed transcoded format\r\n     */\r\n    public get useRGBAIfASTCBC7NotAvailableWhenUASTC() {\r\n        return this._useRGBAIfASTCBC7NotAvailableWhenUASTC;\r\n    }\r\n\r\n    public set useRGBAIfASTCBC7NotAvailableWhenUASTC(value: boolean | undefined) {\r\n        if (this._useRGBAIfASTCBC7NotAvailableWhenUASTC === value) {\r\n            return;\r\n        }\r\n        this._useRGBAIfASTCBC7NotAvailableWhenUASTC = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    private _useRGBAIfOnlyBC1BC3AvailableWhenUASTC?: boolean = true;\r\n    /**\r\n     * force a (uncompressed) RGBA transcoded format if transcoding a UASTC source format and only BC1 or BC3 are available as a compressed transcoded format.\r\n     * This property is true by default to favor speed over memory, because currently transcoding from UASTC to BC1/3 is slow because the transcoder transcodes\r\n     * to uncompressed and then recompresses the texture\r\n     */\r\n    public get useRGBAIfOnlyBC1BC3AvailableWhenUASTC() {\r\n        return this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC;\r\n    }\r\n\r\n    public set useRGBAIfOnlyBC1BC3AvailableWhenUASTC(value: boolean | undefined) {\r\n        if (this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC === value) {\r\n            return;\r\n        }\r\n        this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    private _forceRGBA?: boolean;\r\n    /**\r\n     * force to always use (uncompressed) RGBA for transcoded format\r\n     */\r\n    public get forceRGBA() {\r\n        return this._forceRGBA;\r\n    }\r\n\r\n    public set forceRGBA(value: boolean | undefined) {\r\n        if (this._forceRGBA === value) {\r\n            return;\r\n        }\r\n        this._forceRGBA = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    private _forceR8?: boolean;\r\n    /**\r\n     * force to always use (uncompressed) R8 for transcoded format\r\n     */\r\n    public get forceR8() {\r\n        return this._forceR8;\r\n    }\r\n\r\n    public set forceR8(value: boolean | undefined) {\r\n        if (this._forceR8 === value) {\r\n            return;\r\n        }\r\n        this._forceR8 = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    private _forceRG8?: boolean;\r\n    /**\r\n     * force to always use (uncompressed) RG8 for transcoded format\r\n     */\r\n    public get forceRG8() {\r\n        return this._forceRG8;\r\n    }\r\n\r\n    public set forceRG8(value: boolean | undefined) {\r\n        if (this._forceRG8 === value) {\r\n            return;\r\n        }\r\n        this._forceRG8 = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    private _bypassTranscoders?: string[];\r\n    /**\r\n     * list of transcoders to bypass when looking for a suitable transcoder. The available transcoders are:\r\n     *      UniversalTranscoder_UASTC_ASTC\r\n     *      UniversalTranscoder_UASTC_BC7\r\n     *      UniversalTranscoder_UASTC_RGBA_UNORM\r\n     *      UniversalTranscoder_UASTC_RGBA_SRGB\r\n     *      UniversalTranscoder_UASTC_R8_UNORM\r\n     *      UniversalTranscoder_UASTC_RG8_UNORM\r\n     *      MSCTranscoder\r\n     */\r\n    public get bypassTranscoders() {\r\n        return this._bypassTranscoders;\r\n    }\r\n\r\n    public set bypassTranscoders(value: string[] | undefined) {\r\n        if (this._bypassTranscoders === value) {\r\n            return;\r\n        }\r\n        this._bypassTranscoders = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    private _ktx2DecoderOptions: IKTX2DecoderOptions = {};\r\n\r\n    /** @internal */\r\n    public _getKTX2DecoderOptions(): IKTX2DecoderOptions {\r\n        if (!this._isDirty) {\r\n            return this._ktx2DecoderOptions;\r\n        }\r\n\r\n        this._isDirty = false;\r\n\r\n        const options: IKTX2DecoderOptions = {};\r\n\r\n        if (this._useRGBAIfASTCBC7NotAvailableWhenUASTC !== undefined) {\r\n            options.useRGBAIfASTCBC7NotAvailableWhenUASTC = this._useRGBAIfASTCBC7NotAvailableWhenUASTC;\r\n        }\r\n        if (this._forceRGBA !== undefined) {\r\n            options.forceRGBA = this._forceRGBA;\r\n        }\r\n        if (this._forceR8 !== undefined) {\r\n            options.forceR8 = this._forceR8;\r\n        }\r\n        if (this._forceRG8 !== undefined) {\r\n            options.forceRG8 = this._forceRG8;\r\n        }\r\n        if (this._bypassTranscoders !== undefined) {\r\n            options.bypassTranscoders = this._bypassTranscoders;\r\n        }\r\n\r\n        if (this.useRGBAIfOnlyBC1BC3AvailableWhenUASTC) {\r\n            options.transcodeFormatDecisionTree = {\r\n                UASTC: {\r\n                    transcodeFormat: [TranscodeTarget.BC1_RGB, TranscodeTarget.BC3_RGBA],\r\n                    yes: {\r\n                        transcodeFormat: TranscodeTarget.RGBA32,\r\n                        engineFormat: EngineFormat.RGBA8Format,\r\n                        roundToMultiple4: false,\r\n                    },\r\n                },\r\n            };\r\n        }\r\n\r\n        this._ktx2DecoderOptions = options;\r\n\r\n        return options;\r\n    }\r\n}\r\n\r\n/**\r\n * Options for the KTX2 decoder\r\n */\r\nexport interface IKhronosTextureContainer2Options {\r\n    /**\r\n     * Number of workers to use for async operations. Specify `0` to disable web workers and run synchronously in the current context.\r\n     */\r\n    numWorkers?: number;\r\n    /**\r\n     * Worker pool to use for async operations. If set, `numWorkers` will be ignored.\r\n     */\r\n    workerPool?: AutoReleaseWorkerPool;\r\n    /**\r\n     * Optional container for the KTX2 decoder module and its dependencies. If set, the module will be used from this container and the URLs will be ignored.\r\n     */\r\n    // No need for | any here\r\n    // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\r\n    binariesAndModulesContainer?: { [key in AllowedKeys]?: ArrayBuffer | any };\r\n}\r\n\r\n/**\r\n * Class for loading KTX2 files\r\n */\r\nexport class KhronosTextureContainer2 {\r\n    private static _WorkerPoolPromise?: Promise<AutoReleaseWorkerPool>;\r\n    private static _DecoderModulePromise?: Promise<any>;\r\n    private static _KTX2DecoderModule?: any;\r\n\r\n    /**\r\n     * URLs to use when loading the KTX2 decoder module as well as its dependencies\r\n     * If a url is null, the default url is used (pointing to https://preview.babylonjs.com)\r\n     * Note that jsDecoderModule can't be null and that the other dependencies will only be loaded if necessary\r\n     * Urls you can change:\r\n     *     URLConfig.jsDecoderModule\r\n     *     URLConfig.wasmUASTCToASTC\r\n     *     URLConfig.wasmUASTCToBC7\r\n     *     URLConfig.wasmUASTCToRGBA_UNORM\r\n     *     URLConfig.wasmUASTCToRGBA_SRGB\r\n     *     URLConfig.wasmUASTCToR8_UNORM\r\n     *     URLConfig.wasmUASTCToRG8_UNORM\r\n     *     URLConfig.jsMSCTranscoder\r\n     *     URLConfig.wasmMSCTranscoder\r\n     *     URLConfig.wasmZSTDDecoder\r\n     * You can see their default values in this PG: https://playground.babylonjs.com/#EIJH8L#29\r\n     */\r\n    public static URLConfig: {\r\n        jsDecoderModule: string;\r\n        wasmUASTCToASTC: Nullable<string>;\r\n        wasmUASTCToBC7: Nullable<string>;\r\n        wasmUASTCToRGBA_UNORM: Nullable<string>;\r\n        wasmUASTCToRGBA_SRGB: Nullable<string>;\r\n        wasmUASTCToR8_UNORM: Nullable<string>;\r\n        wasmUASTCToRG8_UNORM: Nullable<string>;\r\n        jsMSCTranscoder: Nullable<string>;\r\n        wasmMSCTranscoder: Nullable<string>;\r\n        wasmZSTDDecoder: Nullable<string>;\r\n    } = {\r\n        jsDecoderModule: \"https://cdn.babylonjs.com/babylon.ktx2Decoder.js\",\r\n        wasmUASTCToASTC: null,\r\n        wasmUASTCToBC7: null,\r\n        wasmUASTCToRGBA_UNORM: null,\r\n        wasmUASTCToRGBA_SRGB: null,\r\n        wasmUASTCToR8_UNORM: null,\r\n        wasmUASTCToRG8_UNORM: null,\r\n        jsMSCTranscoder: null,\r\n        wasmMSCTranscoder: null,\r\n        wasmZSTDDecoder: null,\r\n    };\r\n\r\n    /**\r\n     * If provided, this worker pool will be used instead of creating a new one.\r\n     * This is useful when loading the WASM and the js modules on your own and\r\n     * you want to use the ktxTextureLoader and not construct this class directly.\r\n     */\r\n    public static WorkerPool?: AutoReleaseWorkerPool;\r\n\r\n    /**\r\n     * Default number of workers used to handle data decoding\r\n     */\r\n    public static DefaultNumWorkers = KhronosTextureContainer2.GetDefaultNumWorkers();\r\n\r\n    /**\r\n     * Default configuration for the KTX2 decoder.\r\n     * The options defined in this way have priority over those passed when creating a KTX2 texture with new Texture(...).\r\n     */\r\n    public static DefaultDecoderOptions = new DefaultKTX2DecoderOptions();\r\n\r\n    private static GetDefaultNumWorkers(): number {\r\n        if (typeof navigator !== \"object\" || !navigator.hardwareConcurrency) {\r\n            return 1;\r\n        }\r\n\r\n        // Use 50% of the available logical processors but capped at 4.\r\n        return Math.min(Math.floor(navigator.hardwareConcurrency * 0.5), 4);\r\n    }\r\n\r\n    private _engine: AbstractEngine;\r\n\r\n    private static _Initialize(numWorkers: number): void {\r\n        if (KhronosTextureContainer2._WorkerPoolPromise || KhronosTextureContainer2._DecoderModulePromise) {\r\n            return;\r\n        }\r\n\r\n        const urls = {\r\n            wasmBaseUrl: Tools.ScriptBaseUrl,\r\n            jsDecoderModule: Tools.GetBabylonScriptURL(this.URLConfig.jsDecoderModule, true),\r\n            wasmUASTCToASTC: Tools.GetBabylonScriptURL(this.URLConfig.wasmUASTCToASTC, true),\r\n            wasmUASTCToBC7: Tools.GetBabylonScriptURL(this.URLConfig.wasmUASTCToBC7, true),\r\n            wasmUASTCToRGBA_UNORM: Tools.GetBabylonScriptURL(this.URLConfig.wasmUASTCToRGBA_UNORM, true),\r\n            wasmUASTCToRGBA_SRGB: Tools.GetBabylonScriptURL(this.URLConfig.wasmUASTCToRGBA_SRGB, true),\r\n            wasmUASTCToR8_UNORM: Tools.GetBabylonScriptURL(this.URLConfig.wasmUASTCToR8_UNORM, true),\r\n            wasmUASTCToRG8_UNORM: Tools.GetBabylonScriptURL(this.URLConfig.wasmUASTCToRG8_UNORM, true),\r\n            jsMSCTranscoder: Tools.GetBabylonScriptURL(this.URLConfig.jsMSCTranscoder, true),\r\n            wasmMSCTranscoder: Tools.GetBabylonScriptURL(this.URLConfig.wasmMSCTranscoder, true),\r\n            wasmZSTDDecoder: Tools.GetBabylonScriptURL(this.URLConfig.wasmZSTDDecoder, true),\r\n        };\r\n\r\n        if (numWorkers && typeof Worker === \"function\" && typeof URL !== \"undefined\") {\r\n            KhronosTextureContainer2._WorkerPoolPromise = new Promise((resolve) => {\r\n                // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\r\n                const workerContent = `${applyConfig}(${workerFunction})()`;\r\n                const workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: \"application/javascript\" }));\r\n                resolve(new AutoReleaseWorkerPool(numWorkers, async () => await initializeWebWorker(new Worker(workerBlobUrl), undefined, urls)));\r\n            });\r\n        } else {\r\n            if (typeof KhronosTextureContainer2._KTX2DecoderModule === \"undefined\") {\r\n                // eslint-disable-next-line github/no-then\r\n                KhronosTextureContainer2._DecoderModulePromise = Tools.LoadBabylonScriptAsync(urls.jsDecoderModule).then(() => {\r\n                    KhronosTextureContainer2._KTX2DecoderModule = KTX2DECODER;\r\n                    KhronosTextureContainer2._KTX2DecoderModule.MSCTranscoder.UseFromWorkerThread = false;\r\n                    KhronosTextureContainer2._KTX2DecoderModule.WASMMemoryManager.LoadBinariesFromCurrentThread = true;\r\n                    applyConfig(urls, KhronosTextureContainer2._KTX2DecoderModule);\r\n                    // eslint-disable-next-line @typescript-eslint/no-unsafe-return\r\n                    return new KhronosTextureContainer2._KTX2DecoderModule.KTX2Decoder();\r\n                });\r\n            } else {\r\n                KhronosTextureContainer2._KTX2DecoderModule.MSCTranscoder.UseFromWorkerThread = false;\r\n                KhronosTextureContainer2._KTX2DecoderModule.WASMMemoryManager.LoadBinariesFromCurrentThread = true;\r\n                KhronosTextureContainer2._DecoderModulePromise = Promise.resolve(new KhronosTextureContainer2._KTX2DecoderModule.KTX2Decoder());\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Constructor\r\n     * @param engine The engine to use\r\n     * @param numWorkersOrOptions The number of workers for async operations. Specify `0` to disable web workers and run synchronously in the current context.\r\n     */\r\n    public constructor(engine: AbstractEngine, numWorkersOrOptions: number | IKhronosTextureContainer2Options = KhronosTextureContainer2.DefaultNumWorkers) {\r\n        this._engine = engine;\r\n        const workerPoolOption = (typeof numWorkersOrOptions === \"object\" && numWorkersOrOptions.workerPool) || KhronosTextureContainer2.WorkerPool;\r\n        if (workerPoolOption) {\r\n            KhronosTextureContainer2._WorkerPoolPromise = Promise.resolve(workerPoolOption);\r\n        } else {\r\n            // set the KTX2 decoder module\r\n            if (typeof numWorkersOrOptions === \"object\") {\r\n                KhronosTextureContainer2._KTX2DecoderModule = numWorkersOrOptions?.binariesAndModulesContainer?.jsDecoderModule;\r\n            } else if (typeof KTX2DECODER !== \"undefined\") {\r\n                KhronosTextureContainer2._KTX2DecoderModule = KTX2DECODER;\r\n            }\r\n            const numberOfWorkers = typeof numWorkersOrOptions === \"number\" ? numWorkersOrOptions : (numWorkersOrOptions.numWorkers ?? KhronosTextureContainer2.DefaultNumWorkers);\r\n            KhronosTextureContainer2._Initialize(numberOfWorkers);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public async _uploadAsync(data: ArrayBufferView, internalTexture: InternalTexture, options?: IKTX2DecoderOptions & IDecodedData): Promise<void> {\r\n        const decodedData = await this._decodeAsync(data, options);\r\n        this._createTexture(decodedData, internalTexture, options);\r\n    }\r\n\r\n    /**\r\n     * Decodes a KTX2 file and returns the decoded data, without uploading it to a texture.\r\n     * Kept separate from _uploadAsync so consumers that build their own texture (2D array textures, for eg)\r\n     * can reuse the worker pool, decoder module and url configuration handled here.\r\n     * @param data defines the KTX2 file content\r\n     * @param options defines the options to use when decoding\r\n     * @returns a promise resolved with the decoded data\r\n     * @internal\r\n     */\r\n    public async _decodeAsync(data: ArrayBufferView, options?: IKTX2DecoderOptions): Promise<IDecodedData> {\r\n        const caps = this._engine.getCaps();\r\n\r\n        const compressedTexturesCaps: ICompressedFormatCapabilities = {\r\n            astc: !!caps.astc,\r\n            bptc: !!caps.bptc,\r\n            s3tc: !!caps.s3tc,\r\n            pvrtc: !!caps.pvrtc,\r\n            etc2: !!caps.etc2,\r\n            etc1: !!caps.etc1,\r\n        };\r\n\r\n        if (KhronosTextureContainer2._WorkerPoolPromise) {\r\n            const workerPool = await KhronosTextureContainer2._WorkerPoolPromise;\r\n            return await new Promise((resolve, reject) => {\r\n                workerPool.push((worker, onComplete) => {\r\n                    const onError = (error: ErrorEvent) => {\r\n                        worker.removeEventListener(\"error\", onError);\r\n                        worker.removeEventListener(\"message\", onMessage);\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(error);\r\n                        onComplete();\r\n                    };\r\n\r\n                    const onMessage = (message: MessageEvent) => {\r\n                        if (message.data.action === \"decoded\") {\r\n                            worker.removeEventListener(\"error\", onError);\r\n                            worker.removeEventListener(\"message\", onMessage);\r\n                            if (!message.data.success) {\r\n                                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                                reject({ message: message.data.msg });\r\n                            } else {\r\n                                resolve(message.data.decodedData);\r\n                            }\r\n                            onComplete();\r\n                        }\r\n                    };\r\n\r\n                    worker.addEventListener(\"error\", onError);\r\n                    worker.addEventListener(\"message\", onMessage);\r\n                    worker.postMessage({ action: \"setDefaultDecoderOptions\", options: KhronosTextureContainer2.DefaultDecoderOptions._getKTX2DecoderOptions() });\r\n\r\n                    const dataCopy = new Uint8Array(data.byteLength);\r\n                    dataCopy.set(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));\r\n\r\n                    worker.postMessage({ action: \"decode\", data: dataCopy, caps: compressedTexturesCaps, options }, [dataCopy.buffer]);\r\n                });\r\n            });\r\n        } else if (KhronosTextureContainer2._DecoderModulePromise) {\r\n            const decoder = await KhronosTextureContainer2._DecoderModulePromise;\r\n            if (KhronosTextureContainer2.DefaultDecoderOptions.isDirty) {\r\n                KhronosTextureContainer2._KTX2DecoderModule.KTX2Decoder.DefaultDecoderOptions = KhronosTextureContainer2.DefaultDecoderOptions._getKTX2DecoderOptions();\r\n            }\r\n            return await new Promise((resolve, reject) => {\r\n                decoder\r\n                    .decode(data, caps, options)\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((decodedData: IDecodedData) => {\r\n                        resolve(decodedData);\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((reason: any) => {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject({ message: reason });\r\n                    });\r\n            });\r\n        }\r\n\r\n        throw new Error(\"KTX2 decoder module is not available\");\r\n    }\r\n\r\n    protected _createTexture(data: IDecodedData, internalTexture: InternalTexture, options?: IKTX2DecoderOptions & IDecodedData): void {\r\n        // The decoder can now return array textures (one mipmap entry per layer per level), but this\r\n        // upload path is 2D only: it binds gl.TEXTURE_2D and walks mipmaps as if each entry were a\r\n        // distinct level. Fail loudly rather than silently uploading layer data as mip levels.\r\n        if ((data.layerCount ?? 1) > 1) {\r\n            throw new Error(\"KTX2 container - array textures are not supported by this texture loader.\");\r\n        }\r\n\r\n        const oglTexture2D = 3553; // gl.TEXTURE_2D\r\n\r\n        this._engine._bindTextureDirectly(oglTexture2D, internalTexture);\r\n\r\n        if (options) {\r\n            // return back some information about the decoded data\r\n            options.transcodedFormat = data.transcodedFormat;\r\n            options.isInGammaSpace = data.isInGammaSpace;\r\n            options.hasAlpha = data.hasAlpha;\r\n            options.transcoderName = data.transcoderName;\r\n        }\r\n\r\n        let isUncompressedFormat = true;\r\n\r\n        switch (data.transcodedFormat) {\r\n            case 0x8058 /* RGBA8 */:\r\n                internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                internalTexture.format = Constants.TEXTUREFORMAT_RGBA;\r\n                break;\r\n            case 0x8229 /* R8 */:\r\n                internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                internalTexture.format = Constants.TEXTUREFORMAT_R;\r\n                break;\r\n            case 0x822b /* RG8 */:\r\n                internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                internalTexture.format = Constants.TEXTUREFORMAT_RG;\r\n                break;\r\n            default:\r\n                internalTexture.format = data.transcodedFormat;\r\n                isUncompressedFormat = false;\r\n                break;\r\n        }\r\n\r\n        internalTexture._gammaSpace = data.isInGammaSpace;\r\n        internalTexture.generateMipMaps = data.mipmaps.length > 1;\r\n        internalTexture.width = data.mipmaps[0].width;\r\n        internalTexture.height = data.mipmaps[0].height;\r\n\r\n        if (data.errors) {\r\n            throw new Error(\"KTX2 container - could not transcode the data. \" + data.errors);\r\n        }\r\n\r\n        for (let t = 0; t < data.mipmaps.length; ++t) {\r\n            const mipmap = data.mipmaps[t];\r\n\r\n            if (!mipmap || !mipmap.data) {\r\n                throw new Error(\"KTX2 container - could not transcode one of the image\");\r\n            }\r\n\r\n            if (isUncompressedFormat) {\r\n                // uncompressed RGBA / R8 / RG8\r\n                internalTexture.width = mipmap.width; // need to set width/height so that the call to _uploadDataToTextureDirectly uses the right dimensions\r\n                internalTexture.height = mipmap.height;\r\n\r\n                this._engine._uploadDataToTextureDirectly(internalTexture, mipmap.data, 0, t, undefined, true);\r\n            } else {\r\n                this._engine._uploadCompressedDataToTextureDirectly(internalTexture, data.transcodedFormat, mipmap.width, mipmap.height, mipmap.data, 0, t);\r\n            }\r\n        }\r\n\r\n        internalTexture._extension = \".ktx2\";\r\n        internalTexture.isReady = true;\r\n\r\n        this._engine._bindTextureDirectly(oglTexture2D, null);\r\n    }\r\n\r\n    /**\r\n     * Checks if the given data starts with a KTX2 file identifier.\r\n     * @param data the data to check\r\n     * @returns true if the data is a KTX2 file or false otherwise\r\n     */\r\n    public static IsValid(data: ArrayBufferView): boolean {\r\n        if (data.byteLength >= 12) {\r\n            // '«', 'K', 'T', 'X', ' ', '2', '0', '»', '\\r', '\\n', '\\x1A', '\\n'\r\n            const identifier = new Uint8Array(data.buffer, data.byteOffset, 12);\r\n            if (\r\n                identifier[0] === 0xab &&\r\n                identifier[1] === 0x4b &&\r\n                identifier[2] === 0x54 &&\r\n                identifier[3] === 0x58 &&\r\n                identifier[4] === 0x20 &&\r\n                identifier[5] === 0x32 &&\r\n                identifier[6] === 0x30 &&\r\n                identifier[7] === 0xbb &&\r\n                identifier[8] === 0x0d &&\r\n                identifier[9] === 0x0a &&\r\n                identifier[10] === 0x1a &&\r\n                identifier[11] === 0x0a\r\n            ) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n}\r\n","import { KhronosTextureContainer } from \"../../../Misc/khronosTextureContainer\";\r\nimport { KhronosTextureContainer2 } from \"../../../Misc/khronosTextureContainer2\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\n\r\nfunction MapSRGBToLinear(format: number): Nullable<number> {\r\n    switch (format) {\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12;\r\n        case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:\r\n            return Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM;\r\n    }\r\n\r\n    return null;\r\n}\r\n\r\n/**\r\n * Implementation of the KTX Texture Loader.\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _KTXTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param createPolynomials will be true if polynomials have been requested\r\n     * @param onLoad defines the callback to trigger once the texture is ready\r\n     */\r\n    public loadCubeData(data: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>): void {\r\n        if (Array.isArray(data)) {\r\n            return;\r\n        }\r\n\r\n        // Need to invert vScale as invertY via UNPACK_FLIP_Y_WEBGL is not supported by compressed texture\r\n        texture._invertVScale = !texture.invertY;\r\n        const engine = texture.getEngine();\r\n        const ktx = new KhronosTextureContainer(data, 6);\r\n\r\n        const mappedFormat = MapSRGBToLinear(ktx.glInternalFormat);\r\n        if (mappedFormat !== null) {\r\n            texture.format = mappedFormat;\r\n            texture._useSRGBBuffer = engine._getUseSRGBBuffer(true, !texture.generateMipMaps);\r\n            texture._gammaSpace = true;\r\n        } else {\r\n            texture.format = ktx.glInternalFormat;\r\n        }\r\n\r\n        const loadMipmap = ktx.numberOfMipmapLevels > 1 && texture.generateMipMaps;\r\n\r\n        engine._unpackFlipY(true);\r\n\r\n        ktx.uploadLevels(texture, texture.generateMipMaps);\r\n\r\n        texture.width = ktx.pixelWidth;\r\n        texture.height = ktx.pixelHeight;\r\n\r\n        engine._setCubeMapTextureParams(texture, loadMipmap, ktx.numberOfMipmapLevels - 1);\r\n        texture.isReady = true;\r\n        texture.onLoadedObservable.notifyObservers(texture);\r\n        texture.onLoadedObservable.clear();\r\n\r\n        if (onLoad) {\r\n            onLoad();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     * @param options\r\n     */\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, loadFailed: boolean) => void,\r\n        options?: any\r\n    ): void {\r\n        if (KhronosTextureContainer.IsValid(data)) {\r\n            // Need to invert vScale as invertY via UNPACK_FLIP_Y_WEBGL is not supported by compressed texture\r\n            texture._invertVScale = !texture.invertY;\r\n            const ktx = new KhronosTextureContainer(data, 1);\r\n\r\n            const mappedFormat = MapSRGBToLinear(ktx.glInternalFormat);\r\n            if (mappedFormat !== null) {\r\n                texture.format = mappedFormat;\r\n                texture._useSRGBBuffer = texture.getEngine()._getUseSRGBBuffer(true, !texture.generateMipMaps);\r\n                texture._gammaSpace = true;\r\n            } else {\r\n                texture.format = ktx.glInternalFormat;\r\n            }\r\n\r\n            callback(\r\n                ktx.pixelWidth,\r\n                ktx.pixelHeight,\r\n                texture.generateMipMaps,\r\n                true,\r\n                () => {\r\n                    ktx.uploadLevels(texture, texture.generateMipMaps);\r\n                },\r\n                ktx.isInvalid\r\n            );\r\n        } else if (KhronosTextureContainer2.IsValid(data)) {\r\n            const ktx2 = new KhronosTextureContainer2(texture.getEngine());\r\n            // eslint-disable-next-line github/no-then\r\n            ktx2._uploadAsync(data, texture, options).then(\r\n                () => {\r\n                    callback(texture.width, texture.height, texture.generateMipMaps, true, () => {}, false);\r\n                },\r\n                (error) => {\r\n                    Logger.Warn(`Failed to load KTX2 texture data: ${error.message}`);\r\n                    callback(0, 0, false, false, () => {}, true);\r\n                }\r\n            );\r\n        } else {\r\n            Logger.Error(\"texture missing KTX identifier\");\r\n            callback(0, 0, false, false, () => {}, true);\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\n//private static _TYPE_NO_DATA = 0;\r\nconst _TYPE_INDEXED = 1;\r\nconst _TYPE_RGB = 2;\r\nconst _TYPE_GREY = 3;\r\nconst _TYPE_RLE_INDEXED = 9;\r\nconst _TYPE_RLE_RGB = 10;\r\nconst _TYPE_RLE_GREY = 11;\r\nconst _ORIGIN_MASK = 0x30;\r\nconst _ORIGIN_SHIFT = 0x04;\r\nconst _ORIGIN_BL = 0x00;\r\nconst _ORIGIN_BR = 0x01;\r\nconst _ORIGIN_UL = 0x02;\r\nconst _ORIGIN_UR = 0x03;\r\n\r\n/**\r\n * Gets the header of a TGA file\r\n * @param data defines the TGA data\r\n * @returns the header\r\n */\r\nexport function GetTGAHeader(data: Uint8Array): any {\r\n    let offset = 0;\r\n\r\n    const header = {\r\n        id_length: data[offset++],\r\n        colormap_type: data[offset++],\r\n        image_type: data[offset++],\r\n        colormap_index: data[offset++] | (data[offset++] << 8),\r\n        colormap_length: data[offset++] | (data[offset++] << 8),\r\n        colormap_size: data[offset++],\r\n        origin: [data[offset++] | (data[offset++] << 8), data[offset++] | (data[offset++] << 8)],\r\n        width: data[offset++] | (data[offset++] << 8),\r\n        height: data[offset++] | (data[offset++] << 8),\r\n        pixel_size: data[offset++],\r\n        flags: data[offset],\r\n    };\r\n\r\n    return header;\r\n}\r\n\r\n/**\r\n * Uploads TGA content to a Babylon Texture\r\n * @internal\r\n */\r\nexport function UploadContent(texture: InternalTexture, data: Uint8Array): void {\r\n    // Not enough data to contain header ?\r\n    if (data.length < 19) {\r\n        Logger.Error(\"Unable to load TGA file - Not enough data to contain header\");\r\n        return;\r\n    }\r\n\r\n    // Read Header\r\n    let offset = 18;\r\n    const header = GetTGAHeader(data);\r\n\r\n    // Assume it's a valid Targa file.\r\n    if (header.id_length + offset > data.length) {\r\n        Logger.Error(\"Unable to load TGA file - Not enough data\");\r\n        return;\r\n    }\r\n\r\n    // Skip not needed data\r\n    offset += header.id_length;\r\n\r\n    let use_rle = false;\r\n    let use_pal = false;\r\n    let use_grey = false;\r\n\r\n    // Get some informations.\r\n    switch (header.image_type) {\r\n        case _TYPE_RLE_INDEXED:\r\n            use_rle = true;\r\n        // eslint-disable-next-line no-fallthrough\r\n        case _TYPE_INDEXED:\r\n            use_pal = true;\r\n            break;\r\n\r\n        case _TYPE_RLE_RGB:\r\n            use_rle = true;\r\n        // eslint-disable-next-line no-fallthrough\r\n        case _TYPE_RGB:\r\n            // use_rgb = true;\r\n            break;\r\n\r\n        case _TYPE_RLE_GREY:\r\n            use_rle = true;\r\n        // eslint-disable-next-line no-fallthrough\r\n        case _TYPE_GREY:\r\n            use_grey = true;\r\n            break;\r\n    }\r\n\r\n    let pixel_data;\r\n\r\n    // var numAlphaBits = header.flags & 0xf;\r\n    const pixel_size = header.pixel_size >> 3;\r\n    const pixel_total = header.width * header.height * pixel_size;\r\n\r\n    // Read palettes\r\n    let palettes;\r\n\r\n    if (use_pal) {\r\n        palettes = data.subarray(offset, (offset += header.colormap_length * (header.colormap_size >> 3)));\r\n    }\r\n\r\n    // Read LRE\r\n    if (use_rle) {\r\n        pixel_data = new Uint8Array(pixel_total);\r\n\r\n        let c, count, i;\r\n        let localOffset = 0;\r\n        const pixels = new Uint8Array(pixel_size);\r\n\r\n        while (offset < pixel_total && localOffset < pixel_total) {\r\n            c = data[offset++];\r\n            count = (c & 0x7f) + 1;\r\n\r\n            // RLE pixels\r\n            if (c & 0x80) {\r\n                // Bind pixel tmp array\r\n                for (i = 0; i < pixel_size; ++i) {\r\n                    pixels[i] = data[offset++];\r\n                }\r\n\r\n                // Copy pixel array\r\n                for (i = 0; i < count; ++i) {\r\n                    pixel_data.set(pixels, localOffset + i * pixel_size);\r\n                }\r\n\r\n                localOffset += pixel_size * count;\r\n            }\r\n            // Raw pixels\r\n            else {\r\n                count *= pixel_size;\r\n                for (i = 0; i < count; ++i) {\r\n                    pixel_data[localOffset + i] = data[offset++];\r\n                }\r\n                localOffset += count;\r\n            }\r\n        }\r\n    }\r\n    // RAW Pixels\r\n    else {\r\n        pixel_data = data.subarray(offset, offset + (use_pal ? header.width * header.height : pixel_total));\r\n    }\r\n\r\n    // Load to texture\r\n    let x_start, y_start, x_step, y_step, y_end, x_end;\r\n\r\n    switch ((header.flags & _ORIGIN_MASK) >> _ORIGIN_SHIFT) {\r\n        default:\r\n        case _ORIGIN_UL:\r\n            x_start = 0;\r\n            x_step = 1;\r\n            x_end = header.width;\r\n            y_start = 0;\r\n            y_step = 1;\r\n            y_end = header.height;\r\n            break;\r\n\r\n        case _ORIGIN_BL:\r\n            x_start = 0;\r\n            x_step = 1;\r\n            x_end = header.width;\r\n            y_start = header.height - 1;\r\n            y_step = -1;\r\n            y_end = -1;\r\n            break;\r\n\r\n        case _ORIGIN_UR:\r\n            x_start = header.width - 1;\r\n            x_step = -1;\r\n            x_end = -1;\r\n            y_start = 0;\r\n            y_step = 1;\r\n            y_end = header.height;\r\n            break;\r\n\r\n        case _ORIGIN_BR:\r\n            x_start = header.width - 1;\r\n            x_step = -1;\r\n            x_end = -1;\r\n            y_start = header.height - 1;\r\n            y_step = -1;\r\n            y_end = -1;\r\n            break;\r\n    }\r\n\r\n    // Load the specify method\r\n    const func = \"_getImageData\" + (use_grey ? \"Grey\" : \"\") + header.pixel_size + \"bits\";\r\n    const imageData = (<any>TGATools)[func](header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);\r\n\r\n    const engine = texture.getEngine();\r\n    engine._uploadDataToTextureDirectly(texture, imageData);\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nfunction GetImageData8bits(\r\n    header: any,\r\n    palettes: Uint8Array,\r\n    pixel_data: Uint8Array,\r\n    y_start: number,\r\n    y_step: number,\r\n    y_end: number,\r\n    x_start: number,\r\n    x_step: number,\r\n    x_end: number\r\n): Uint8Array {\r\n    const image = pixel_data,\r\n        colormap = palettes;\r\n    const width = header.width,\r\n        height = header.height;\r\n    let color,\r\n        i = 0,\r\n        x,\r\n        y;\r\n\r\n    const imageData = new Uint8Array(width * height * 4);\r\n\r\n    for (y = y_start; y !== y_end; y += y_step) {\r\n        for (x = x_start; x !== x_end; x += x_step, i++) {\r\n            color = image[i];\r\n            imageData[(x + width * y) * 4 + 3] = 255;\r\n            imageData[(x + width * y) * 4 + 2] = colormap[color * 3 + 0];\r\n            imageData[(x + width * y) * 4 + 1] = colormap[color * 3 + 1];\r\n            imageData[(x + width * y) * 4 + 0] = colormap[color * 3 + 2];\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nfunction GetImageData16bits(\r\n    header: any,\r\n    palettes: Uint8Array,\r\n    pixel_data: Uint8Array,\r\n    y_start: number,\r\n    y_step: number,\r\n    y_end: number,\r\n    x_start: number,\r\n    x_step: number,\r\n    x_end: number\r\n): Uint8Array {\r\n    const image = pixel_data;\r\n    const width = header.width,\r\n        height = header.height;\r\n    let color,\r\n        i = 0,\r\n        x,\r\n        y;\r\n\r\n    const imageData = new Uint8Array(width * height * 4);\r\n\r\n    for (y = y_start; y !== y_end; y += y_step) {\r\n        for (x = x_start; x !== x_end; x += x_step, i += 2) {\r\n            color = image[i + 0] + (image[i + 1] << 8); // Inversed ?\r\n            const r = ((((color & 0x7c00) >> 10) * 255) / 0x1f) | 0;\r\n            const g = ((((color & 0x03e0) >> 5) * 255) / 0x1f) | 0;\r\n            const b = (((color & 0x001f) * 255) / 0x1f) | 0;\r\n\r\n            imageData[(x + width * y) * 4 + 0] = r;\r\n            imageData[(x + width * y) * 4 + 1] = g;\r\n            imageData[(x + width * y) * 4 + 2] = b;\r\n            imageData[(x + width * y) * 4 + 3] = color & 0x8000 ? 0 : 255;\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nfunction GetImageData24bits(\r\n    header: any,\r\n    palettes: Uint8Array,\r\n    pixel_data: Uint8Array,\r\n    y_start: number,\r\n    y_step: number,\r\n    y_end: number,\r\n    x_start: number,\r\n    x_step: number,\r\n    x_end: number\r\n): Uint8Array {\r\n    const image = pixel_data;\r\n    const width = header.width,\r\n        height = header.height;\r\n    let i = 0,\r\n        x,\r\n        y;\r\n\r\n    const imageData = new Uint8Array(width * height * 4);\r\n\r\n    for (y = y_start; y !== y_end; y += y_step) {\r\n        for (x = x_start; x !== x_end; x += x_step, i += 3) {\r\n            imageData[(x + width * y) * 4 + 3] = 255;\r\n            imageData[(x + width * y) * 4 + 2] = image[i + 0];\r\n            imageData[(x + width * y) * 4 + 1] = image[i + 1];\r\n            imageData[(x + width * y) * 4 + 0] = image[i + 2];\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nfunction GetImageData32bits(\r\n    header: any,\r\n    palettes: Uint8Array,\r\n    pixel_data: Uint8Array,\r\n    y_start: number,\r\n    y_step: number,\r\n    y_end: number,\r\n    x_start: number,\r\n    x_step: number,\r\n    x_end: number\r\n): Uint8Array {\r\n    const image = pixel_data;\r\n    const width = header.width,\r\n        height = header.height;\r\n    let i = 0,\r\n        x,\r\n        y;\r\n\r\n    const imageData = new Uint8Array(width * height * 4);\r\n\r\n    for (y = y_start; y !== y_end; y += y_step) {\r\n        for (x = x_start; x !== x_end; x += x_step, i += 4) {\r\n            imageData[(x + width * y) * 4 + 2] = image[i + 0];\r\n            imageData[(x + width * y) * 4 + 1] = image[i + 1];\r\n            imageData[(x + width * y) * 4 + 0] = image[i + 2];\r\n            imageData[(x + width * y) * 4 + 3] = image[i + 3];\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nfunction GetImageDataGrey8bits(\r\n    header: any,\r\n    palettes: Uint8Array,\r\n    pixel_data: Uint8Array,\r\n    y_start: number,\r\n    y_step: number,\r\n    y_end: number,\r\n    x_start: number,\r\n    x_step: number,\r\n    x_end: number\r\n): Uint8Array {\r\n    const image = pixel_data;\r\n    const width = header.width,\r\n        height = header.height;\r\n    let color,\r\n        i = 0,\r\n        x,\r\n        y;\r\n\r\n    const imageData = new Uint8Array(width * height * 4);\r\n\r\n    for (y = y_start; y !== y_end; y += y_step) {\r\n        for (x = x_start; x !== x_end; x += x_step, i++) {\r\n            color = image[i];\r\n            imageData[(x + width * y) * 4 + 0] = color;\r\n            imageData[(x + width * y) * 4 + 1] = color;\r\n            imageData[(x + width * y) * 4 + 2] = color;\r\n            imageData[(x + width * y) * 4 + 3] = 255;\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nfunction GetImageDataGrey16bits(\r\n    header: any,\r\n    palettes: Uint8Array,\r\n    pixel_data: Uint8Array,\r\n    y_start: number,\r\n    y_step: number,\r\n    y_end: number,\r\n    x_start: number,\r\n    x_step: number,\r\n    x_end: number\r\n): Uint8Array {\r\n    const image = pixel_data;\r\n    const width = header.width,\r\n        height = header.height;\r\n    let i = 0,\r\n        x,\r\n        y;\r\n\r\n    const imageData = new Uint8Array(width * height * 4);\r\n\r\n    for (y = y_start; y !== y_end; y += y_step) {\r\n        for (x = x_start; x !== x_end; x += x_step, i += 2) {\r\n            imageData[(x + width * y) * 4 + 0] = image[i + 0];\r\n            imageData[(x + width * y) * 4 + 1] = image[i + 0];\r\n            imageData[(x + width * y) * 4 + 2] = image[i + 0];\r\n            imageData[(x + width * y) * 4 + 3] = image[i + 1];\r\n        }\r\n    }\r\n\r\n    return imageData;\r\n}\r\n\r\n/**\r\n * Based on jsTGALoader - Javascript loader for TGA file\r\n * By Vincent Thibault\r\n * @see http://blog.robrowser.com/javascript-tga-loader.html\r\n */\r\nexport const TGATools = {\r\n    /**\r\n     * Gets the header of a TGA file\r\n     * @param data defines the TGA data\r\n     * @returns the header\r\n     */\r\n    GetTGAHeader,\r\n\r\n    /**\r\n     * Uploads TGA content to a Babylon Texture\r\n     * @internal\r\n     */\r\n    UploadContent,\r\n\r\n    /** @internal */\r\n    _getImageData8bits: GetImageData8bits,\r\n\r\n    /** @internal */\r\n    _getImageData16bits: GetImageData16bits,\r\n    /** @internal */\r\n    _getImageData24bits: GetImageData24bits,\r\n\r\n    /** @internal */\r\n    _getImageData32bits: GetImageData32bits,\r\n\r\n    /** @internal */\r\n    _getImageDataGrey8bits: GetImageDataGrey8bits,\r\n    /** @internal */\r\n    _getImageDataGrey16bits: GetImageDataGrey16bits,\r\n};\r\n","import { GetTGAHeader, UploadContent } from \"../../../Misc/tga\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\n\r\n/**\r\n * Implementation of the TGA Texture Loader.\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _TGATextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     */\r\n    public loadCubeData(): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \".env not supported in Cube.\";\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     */\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void\r\n    ): void {\r\n        const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\r\n\r\n        const header = GetTGAHeader(bytes);\r\n        callback(header.width, header.height, texture.generateMipMaps, false, () => {\r\n            UploadContent(texture, bytes);\r\n        });\r\n    }\r\n}\r\n","import { RGBE_ReadHeader, RGBE_ReadPixels } from \"../../../Misc/HighDynamicRange/hdr\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\n\r\n/**\r\n * Implementation of the HDR Texture Loader.\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _HDRTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     * Cube texture are not supported by .hdr files\r\n     */\r\n    public loadCubeData(): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \".hdr not supported in Cube.\";\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     */\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void\r\n    ): void {\r\n        const uint8array = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\r\n        const hdrInfo = RGBE_ReadHeader(uint8array);\r\n        const pixelsDataRGB32 = RGBE_ReadPixels(uint8array, hdrInfo);\r\n\r\n        const pixels = hdrInfo.width * hdrInfo.height;\r\n        const pixelsDataRGBA32 = new Float32Array(pixels * 4);\r\n        for (let i = 0; i < pixels; i += 1) {\r\n            pixelsDataRGBA32[i * 4] = pixelsDataRGB32[i * 3];\r\n            pixelsDataRGBA32[i * 4 + 1] = pixelsDataRGB32[i * 3 + 1];\r\n            pixelsDataRGBA32[i * 4 + 2] = pixelsDataRGB32[i * 3 + 2];\r\n            pixelsDataRGBA32[i * 4 + 3] = 1;\r\n        }\r\n\r\n        callback(hdrInfo.width, hdrInfo.height, texture.generateMipMaps, false, () => {\r\n            const engine = texture.getEngine();\r\n            texture.type = Constants.TEXTURETYPE_FLOAT;\r\n            texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n            texture._gammaSpace = false;\r\n            engine._uploadDataToTextureDirectly(texture, pixelsDataRGBA32);\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { Logger } from \"./logger\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { initializeWebWorker, workerFunction } from \"./basisWorker\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { type Engine } from \"core/Engines/engine.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * Info about the .basis files\r\n */\r\nexport class BasisFileInfo {\r\n    /**\r\n     * If the file has alpha\r\n     */\r\n    public hasAlpha: boolean;\r\n    /**\r\n     * Info about each image of the basis file\r\n     */\r\n    public images: Array<{ levels: Array<{ width: number; height: number; transcodedPixels: ArrayBufferView }> }>;\r\n}\r\n\r\n/**\r\n * Result of transcoding a basis file\r\n */\r\nclass TranscodeResult {\r\n    /**\r\n     * Info about the .basis file\r\n     */\r\n    public fileInfo: BasisFileInfo;\r\n    /**\r\n     * Format to use when loading the file\r\n     */\r\n    public format: number;\r\n}\r\n\r\n/**\r\n * Configuration options for the Basis transcoder\r\n */\r\nexport class BasisTranscodeConfiguration {\r\n    /**\r\n     * Supported compression formats used to determine the supported output format of the transcoder\r\n     */\r\n    supportedCompressionFormats?: {\r\n        /**\r\n         * etc1 compression format\r\n         */\r\n        etc1?: boolean;\r\n        /**\r\n         * s3tc compression format\r\n         */\r\n        s3tc?: boolean;\r\n        /**\r\n         * pvrtc compression format\r\n         */\r\n        pvrtc?: boolean;\r\n        /**\r\n         * etc2 compression format\r\n         */\r\n        etc2?: boolean;\r\n        /**\r\n         * astc compression format\r\n         */\r\n        astc?: boolean;\r\n        /**\r\n         * bc7 compression format\r\n         */\r\n        bc7?: boolean;\r\n    };\r\n    /**\r\n     * If mipmap levels should be loaded for transcoded images (Default: true)\r\n     */\r\n    loadMipmapLevels?: boolean;\r\n    /**\r\n     * Index of a single image to load (Default: all images)\r\n     */\r\n    loadSingleImage?: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n * Enum of basis transcoder formats\r\n */\r\nenum BASIS_FORMATS {\r\n    cTFETC1 = 0,\r\n    cTFETC2 = 1,\r\n    cTFBC1 = 2,\r\n    cTFBC3 = 3,\r\n    cTFBC4 = 4,\r\n    cTFBC5 = 5,\r\n    cTFBC7 = 6,\r\n    cTFPVRTC1_4_RGB = 8,\r\n    cTFPVRTC1_4_RGBA = 9,\r\n    cTFASTC_4x4 = 10,\r\n    cTFATC_RGB = 11,\r\n    cTFATC_RGBA_INTERPOLATED_ALPHA = 12,\r\n    cTFRGBA32 = 13,\r\n    cTFRGB565 = 14,\r\n    cTFBGR565 = 15,\r\n    cTFRGBA4444 = 16,\r\n    cTFFXT1_RGB = 17,\r\n    cTFPVRTC2_4_RGB = 18,\r\n    cTFPVRTC2_4_RGBA = 19,\r\n    cTFETC2_EAC_R11 = 20,\r\n    cTFETC2_EAC_RG11 = 21,\r\n}\r\n\r\n/**\r\n * Used to load .Basis files\r\n * See https://github.com/BinomialLLC/basis_universal/tree/master/webgl\r\n */\r\nexport const BasisToolsOptions = {\r\n    /**\r\n     * URL to use when loading the basis transcoder\r\n     */\r\n    JSModuleURL: `${Tools._DefaultCdnUrl}/basisTranscoder/1/basis_transcoder.js`,\r\n    /**\r\n     * URL to use when loading the wasm module for the transcoder\r\n     */\r\n    WasmModuleURL: `${Tools._DefaultCdnUrl}/basisTranscoder/1/basis_transcoder.wasm`,\r\n};\r\n\r\n/**\r\n * Get the internal format to be passed to texImage2D corresponding to the .basis format value\r\n * @param basisFormat format chosen from GetSupportedTranscodeFormat\r\n * @param engine\r\n * @returns internal format corresponding to the Basis format\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nexport const GetInternalFormatFromBasisFormat = (basisFormat: number, engine: AbstractEngine) => {\r\n    let format;\r\n    switch (basisFormat) {\r\n        case BASIS_FORMATS.cTFETC1:\r\n            format = Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL;\r\n            break;\r\n        case BASIS_FORMATS.cTFBC1:\r\n            format = Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1;\r\n            break;\r\n        case BASIS_FORMATS.cTFBC4:\r\n            format = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5;\r\n            break;\r\n        case BASIS_FORMATS.cTFASTC_4x4:\r\n            format = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4;\r\n            break;\r\n        case BASIS_FORMATS.cTFETC2:\r\n            format = Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC;\r\n            break;\r\n        case BASIS_FORMATS.cTFBC7:\r\n            format = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM;\r\n            break;\r\n    }\r\n\r\n    if (format === undefined) {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \"The chosen Basis transcoder format is not currently supported\";\r\n    }\r\n\r\n    return format;\r\n};\r\n\r\nlet WorkerPromise: Nullable<Promise<Worker>> = null;\r\nlet LocalWorker: Nullable<Worker> = null;\r\nlet ActionId = 0;\r\nconst IgnoreSupportedFormats = false;\r\nconst CreateWorkerAsync = async () => {\r\n    if (!WorkerPromise) {\r\n        WorkerPromise = new Promise((res, reject) => {\r\n            if (LocalWorker) {\r\n                res(LocalWorker);\r\n            } else {\r\n                Tools.LoadFileAsync(Tools.GetBabylonScriptURL(BasisToolsOptions.WasmModuleURL))\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((wasmBinary) => {\r\n                        if (typeof URL !== \"function\") {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            return reject(\"Basis transcoder requires an environment with a URL constructor\");\r\n                        }\r\n                        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\r\n                        const workerBlobUrl = URL.createObjectURL(new Blob([`(${workerFunction})()`], { type: \"application/javascript\" }));\r\n                        LocalWorker = new Worker(workerBlobUrl);\r\n                        // eslint-disable-next-line github/no-then\r\n                        initializeWebWorker(LocalWorker, wasmBinary, BasisToolsOptions.JSModuleURL).then(res, reject);\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch(reject);\r\n            }\r\n        });\r\n    }\r\n    return await WorkerPromise;\r\n};\r\n\r\n/**\r\n * Set the worker to use for transcoding\r\n * @param worker The worker that will be used for transcoding\r\n */\r\nexport const SetBasisTranscoderWorker = (worker: Worker) => {\r\n    LocalWorker = worker;\r\n};\r\n\r\n/**\r\n * Transcodes a loaded image file to compressed pixel data\r\n * @param data image data to transcode\r\n * @param config configuration options for the transcoding\r\n * @returns a promise resulting in the transcoded image\r\n */\r\nexport const TranscodeAsync = async (data: ArrayBuffer | ArrayBufferView, config: BasisTranscodeConfiguration): Promise<TranscodeResult> => {\r\n    const dataView = data instanceof ArrayBuffer ? new Uint8Array(data) : data;\r\n\r\n    return await new Promise((res, rej) => {\r\n        // eslint-disable-next-line github/no-then\r\n        CreateWorkerAsync().then(\r\n            () => {\r\n                const actionId = ActionId++;\r\n                const messageHandler = (msg: any) => {\r\n                    if (msg.data.action === \"transcode\" && msg.data.id === actionId) {\r\n                        LocalWorker!.removeEventListener(\"message\", messageHandler);\r\n                        if (!msg.data.success) {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            rej(\"Transcode is not supported on this device\");\r\n                        } else {\r\n                            res(msg.data);\r\n                        }\r\n                    }\r\n                };\r\n                LocalWorker!.addEventListener(\"message\", messageHandler);\r\n\r\n                const dataViewCopy = new Uint8Array(dataView.byteLength);\r\n                dataViewCopy.set(new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength));\r\n                LocalWorker!.postMessage({ action: \"transcode\", id: actionId, imageData: dataViewCopy, config: config, ignoreSupportedFormats: IgnoreSupportedFormats }, [\r\n                    dataViewCopy.buffer,\r\n                ]);\r\n            },\r\n            (error) => {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                rej(error);\r\n            }\r\n        );\r\n    });\r\n};\r\n\r\n/**\r\n * Binds a texture according to its underlying target.\r\n * @param texture texture to bind\r\n * @param engine the engine to bind the texture in\r\n */\r\nconst BindTexture = (texture: InternalTexture, engine: Engine): void => {\r\n    let target: GLenum = engine._gl?.TEXTURE_2D;\r\n    if (texture.isCube) {\r\n        target = engine._gl?.TEXTURE_CUBE_MAP;\r\n    }\r\n\r\n    engine._bindTextureDirectly(target, texture, true);\r\n};\r\n\r\n/**\r\n * Loads a texture from the transcode result\r\n * @param texture texture load to\r\n * @param transcodeResult the result of transcoding the basis file to load from\r\n */\r\nexport const LoadTextureFromTranscodeResult = (texture: InternalTexture, transcodeResult: TranscodeResult) => {\r\n    const engine = texture.getEngine() as Engine;\r\n    for (let i = 0; i < transcodeResult.fileInfo.images.length; i++) {\r\n        const rootImage = transcodeResult.fileInfo.images[i].levels[0];\r\n        texture._invertVScale = texture.invertY;\r\n        if (transcodeResult.format === -1 || transcodeResult.format === BASIS_FORMATS.cTFRGB565) {\r\n            // No compatable compressed format found, fallback to RGB\r\n            texture.type = Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5;\r\n            texture.format = Constants.TEXTUREFORMAT_RGB;\r\n\r\n            if (engine._features.basisNeedsPOT && (Math.log2(rootImage.width) % 1 !== 0 || Math.log2(rootImage.height) % 1 !== 0)) {\r\n                // Create non power of two texture\r\n                const source = new InternalTexture(engine, InternalTextureSource.Temp);\r\n\r\n                texture._invertVScale = texture.invertY;\r\n                source.type = Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5;\r\n                source.format = Constants.TEXTUREFORMAT_RGB;\r\n                // Fallback requires aligned width/height\r\n                source.width = (rootImage.width + 3) & ~3;\r\n                source.height = (rootImage.height + 3) & ~3;\r\n                BindTexture(source, engine);\r\n                engine._uploadDataToTextureDirectly(source, new Uint16Array(rootImage.transcodedPixels.buffer), i, 0, Constants.TEXTUREFORMAT_RGB, true);\r\n\r\n                // Resize to power of two\r\n                engine._rescaleTexture(source, texture, engine.scenes[0], engine._getInternalFormat(Constants.TEXTUREFORMAT_RGB), () => {\r\n                    engine._releaseTexture(source);\r\n                    BindTexture(texture, engine);\r\n                });\r\n            } else {\r\n                // Fallback is already inverted\r\n                texture._invertVScale = !texture.invertY;\r\n\r\n                // Upload directly\r\n                texture.width = (rootImage.width + 3) & ~3;\r\n                texture.height = (rootImage.height + 3) & ~3;\r\n                texture.samplingMode = Constants.TEXTURE_LINEAR_LINEAR;\r\n                BindTexture(texture, engine);\r\n                engine._uploadDataToTextureDirectly(texture, new Uint16Array(rootImage.transcodedPixels.buffer), i, 0, Constants.TEXTUREFORMAT_RGB, true);\r\n            }\r\n        } else {\r\n            texture.width = rootImage.width;\r\n            texture.height = rootImage.height;\r\n            texture.generateMipMaps = transcodeResult.fileInfo.images[i].levels.length > 1;\r\n\r\n            const format = BasisTools.GetInternalFormatFromBasisFormat(transcodeResult.format, engine);\r\n            texture.format = format;\r\n\r\n            BindTexture(texture, engine);\r\n\r\n            // Upload all mip levels in the file\r\n            const levels = transcodeResult.fileInfo.images[i].levels;\r\n\r\n            for (let index = 0; index < levels.length; index++) {\r\n                const level = levels[index];\r\n                engine._uploadCompressedDataToTextureDirectly(texture, format, level.width, level.height, level.transcodedPixels, i, index);\r\n            }\r\n\r\n            if (engine._features.basisNeedsPOT && (Math.log2(texture.width) % 1 !== 0 || Math.log2(texture.height) % 1 !== 0)) {\r\n                Logger.Warn(\r\n                    \"Loaded .basis texture width and height are not a power of two. Texture wrapping will be set to Texture.CLAMP_ADDRESSMODE as other modes are not supported with non power of two dimensions in webGL 1.\"\r\n                );\r\n                texture._cachedWrapU = Texture.CLAMP_ADDRESSMODE;\r\n                texture._cachedWrapV = Texture.CLAMP_ADDRESSMODE;\r\n            }\r\n        }\r\n    }\r\n};\r\n\r\n/**\r\n * Used to load .Basis files\r\n * See https://github.com/BinomialLLC/basis_universal/tree/master/webgl\r\n */\r\nexport const BasisTools = {\r\n    /**\r\n     * URL to use when loading the basis transcoder\r\n     */\r\n    JSModuleURL: BasisToolsOptions.JSModuleURL,\r\n    /**\r\n     * URL to use when loading the wasm module for the transcoder\r\n     */\r\n    WasmModuleURL: BasisToolsOptions.WasmModuleURL,\r\n\r\n    /**\r\n     * Get the internal format to be passed to texImage2D corresponding to the .basis format value\r\n     * @param basisFormat format chosen from GetSupportedTranscodeFormat\r\n     * @returns internal format corresponding to the Basis format\r\n     */\r\n    GetInternalFormatFromBasisFormat,\r\n\r\n    /**\r\n     * Transcodes a loaded image file to compressed pixel data\r\n     * @param data image data to transcode\r\n     * @param config configuration options for the transcoding\r\n     * @returns a promise resulting in the transcoded image\r\n     */\r\n    TranscodeAsync,\r\n\r\n    /**\r\n     * Loads a texture from the transcode result\r\n     * @param texture texture load to\r\n     * @param transcodeResult the result of transcoding the basis file to load from\r\n     */\r\n    LoadTextureFromTranscodeResult,\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for basis.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBasis(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(BasisTools, \"JSModuleURL\", {\r\n        get: function (this: null) {\r\n            return BasisToolsOptions.JSModuleURL;\r\n        },\r\n        set: function (this: null, value: string) {\r\n            BasisToolsOptions.JSModuleURL = value;\r\n        },\r\n    });\r\n\r\n    Object.defineProperty(BasisTools, \"WasmModuleURL\", {\r\n        get: function (this: null) {\r\n            return BasisToolsOptions.WasmModuleURL;\r\n        },\r\n        set: function (this: null, value: string) {\r\n            BasisToolsOptions.WasmModuleURL = value;\r\n        },\r\n    });\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"core/types\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { type BasisFileInfo, type BasisTranscodeConfiguration } from \"./basis\";\r\n\r\n// WorkerGlobalScope\r\ndeclare function importScripts(...urls: string[]): void;\r\ndeclare function postMessage(message: any, transfer?: any[]): void;\r\ndeclare let BASIS: any;\r\n/**\r\n * The worker function that gets converted to a blob url to pass into a worker.\r\n * To be used if a developer wants to create their own worker instance and inject it instead of using the default worker.\r\n */\r\nexport function workerFunction(): void {\r\n    const _BASIS_FORMAT = {\r\n        cTFETC1: 0,\r\n        cTFETC2: 1,\r\n        cTFBC1: 2,\r\n        cTFBC3: 3,\r\n        cTFBC4: 4,\r\n        cTFBC5: 5,\r\n        cTFBC7: 6,\r\n        cTFPVRTC1_4_RGB: 8,\r\n        cTFPVRTC1_4_RGBA: 9,\r\n        cTFASTC_4x4: 10,\r\n        cTFATC_RGB: 11,\r\n        cTFATC_RGBA_INTERPOLATED_ALPHA: 12,\r\n        cTFRGBA32: 13,\r\n        cTFRGB565: 14,\r\n        cTFBGR565: 15,\r\n        cTFRGBA4444: 16,\r\n        cTFFXT1_RGB: 17,\r\n        cTFPVRTC2_4_RGB: 18,\r\n        cTFPVRTC2_4_RGBA: 19,\r\n        cTFETC2_EAC_R11: 20,\r\n        cTFETC2_EAC_RG11: 21,\r\n    };\r\n    let transcoderModulePromise: Nullable<PromiseLike<any>> = null;\r\n    onmessage = (event) => {\r\n        if (event.data.action === \"init\") {\r\n            // Load the transcoder if it hasn't been yet\r\n            if (event.data.url) {\r\n                // make sure we loaded the script correctly\r\n                try {\r\n                    importScripts(event.data.url);\r\n                } catch (e) {\r\n                    postMessage({ action: \"error\", error: e });\r\n                }\r\n            }\r\n            if (!transcoderModulePromise) {\r\n                transcoderModulePromise = BASIS({\r\n                    // Override wasm binary\r\n                    wasmBinary: event.data.wasmBinary,\r\n                });\r\n            }\r\n            if (transcoderModulePromise !== null) {\r\n                // eslint-disable-next-line github/no-then\r\n                transcoderModulePromise.then((m) => {\r\n                    BASIS = m;\r\n                    m.initializeBasis();\r\n                    postMessage({ action: \"init\" });\r\n                });\r\n            }\r\n        } else if (event.data.action === \"transcode\") {\r\n            // Transcode the basis image and return the resulting pixels\r\n            const config: BasisTranscodeConfiguration = event.data.config;\r\n            const imgData = event.data.imageData;\r\n            const loadedFile = new BASIS.BasisFile(imgData);\r\n            const fileInfo = GetFileInfo(loadedFile);\r\n            let format = event.data.ignoreSupportedFormats ? null : GetSupportedTranscodeFormat(event.data.config, fileInfo);\r\n\r\n            let needsConversion = false;\r\n            if (format === null) {\r\n                needsConversion = true;\r\n                format = fileInfo.hasAlpha ? _BASIS_FORMAT.cTFBC3 : _BASIS_FORMAT.cTFBC1;\r\n            }\r\n\r\n            // Begin transcode\r\n            let success = true;\r\n            if (!loadedFile.startTranscoding()) {\r\n                success = false;\r\n            }\r\n\r\n            const buffers: Array<any> = [];\r\n            for (let imageIndex = 0; imageIndex < fileInfo.images.length; imageIndex++) {\r\n                if (!success) {\r\n                    break;\r\n                }\r\n                const image = fileInfo.images[imageIndex];\r\n                if (config.loadSingleImage === undefined || config.loadSingleImage === imageIndex) {\r\n                    let mipCount = image.levels.length;\r\n                    if (config.loadMipmapLevels === false) {\r\n                        mipCount = 1;\r\n                    }\r\n                    for (let levelIndex = 0; levelIndex < mipCount; levelIndex++) {\r\n                        const levelInfo = image.levels[levelIndex];\r\n\r\n                        const pixels = TranscodeLevel(loadedFile, imageIndex, levelIndex, format, needsConversion);\r\n                        if (!pixels) {\r\n                            success = false;\r\n                            break;\r\n                        }\r\n                        levelInfo.transcodedPixels = pixels;\r\n                        buffers.push(levelInfo.transcodedPixels.buffer);\r\n                    }\r\n                }\r\n            }\r\n            // Close file\r\n            loadedFile.close();\r\n            loadedFile.delete();\r\n\r\n            if (needsConversion) {\r\n                format = -1;\r\n            }\r\n            if (!success) {\r\n                postMessage({ action: \"transcode\", success: success, id: event.data.id });\r\n            } else {\r\n                postMessage({ action: \"transcode\", success: success, id: event.data.id, fileInfo: fileInfo, format: format }, buffers);\r\n            }\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Detects the supported transcode format for the file\r\n     * @param config transcode config\r\n     * @param fileInfo info about the file\r\n     * @returns the chosed format or null if none are supported\r\n     */\r\n    function GetSupportedTranscodeFormat(config: BasisTranscodeConfiguration, fileInfo: BasisFileInfo): Nullable<number> {\r\n        let format = null;\r\n        if (config.supportedCompressionFormats) {\r\n            if (config.supportedCompressionFormats.astc) {\r\n                format = _BASIS_FORMAT.cTFASTC_4x4;\r\n            } else if (config.supportedCompressionFormats.bc7) {\r\n                format = _BASIS_FORMAT.cTFBC7;\r\n            } else if (config.supportedCompressionFormats.s3tc) {\r\n                format = fileInfo.hasAlpha ? _BASIS_FORMAT.cTFBC3 : _BASIS_FORMAT.cTFBC1;\r\n            } else if (config.supportedCompressionFormats.pvrtc) {\r\n                format = fileInfo.hasAlpha ? _BASIS_FORMAT.cTFPVRTC1_4_RGBA : _BASIS_FORMAT.cTFPVRTC1_4_RGB;\r\n            } else if (config.supportedCompressionFormats.etc2) {\r\n                format = _BASIS_FORMAT.cTFETC2;\r\n            } else if (config.supportedCompressionFormats.etc1) {\r\n                format = _BASIS_FORMAT.cTFETC1;\r\n            } else {\r\n                format = _BASIS_FORMAT.cTFRGB565;\r\n            }\r\n        }\r\n        return format;\r\n    }\r\n\r\n    /**\r\n     * Retrieves information about the basis file eg. dimensions\r\n     * @param basisFile the basis file to get the info from\r\n     * @returns information about the basis file\r\n     */\r\n    function GetFileInfo(basisFile: any): BasisFileInfo {\r\n        const hasAlpha = basisFile.getHasAlpha();\r\n        const imageCount = basisFile.getNumImages();\r\n        const images = [];\r\n        for (let i = 0; i < imageCount; i++) {\r\n            const imageInfo = {\r\n                levels: [] as Array<any>,\r\n            };\r\n            const levelCount = basisFile.getNumLevels(i);\r\n            for (let level = 0; level < levelCount; level++) {\r\n                const levelInfo = {\r\n                    width: basisFile.getImageWidth(i, level),\r\n                    height: basisFile.getImageHeight(i, level),\r\n                };\r\n                imageInfo.levels.push(levelInfo);\r\n            }\r\n            images.push(imageInfo);\r\n        }\r\n        const info = { hasAlpha, images };\r\n        return info;\r\n    }\r\n\r\n    function TranscodeLevel(loadedFile: any, imageIndex: number, levelIndex: number, format: number, convertToRgb565: boolean): Nullable<Uint8Array | Uint16Array> {\r\n        const dstSize = loadedFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);\r\n        let dst: Uint8Array | Uint16Array = new Uint8Array(dstSize);\r\n        if (!loadedFile.transcodeImage(dst, imageIndex, levelIndex, format, 1, 0)) {\r\n            return null;\r\n        }\r\n        // If no supported format is found, load as dxt and convert to rgb565\r\n        if (convertToRgb565) {\r\n            const alignedWidth = (loadedFile.getImageWidth(imageIndex, levelIndex) + 3) & ~3;\r\n            const alignedHeight = (loadedFile.getImageHeight(imageIndex, levelIndex) + 3) & ~3;\r\n            dst = ConvertDxtToRgb565(dst, 0, alignedWidth, alignedHeight);\r\n        }\r\n        return dst;\r\n    }\r\n\r\n    /**\r\n     * From https://github.com/BinomialLLC/basis_universal/blob/master/webgl/texture/dxt-to-rgb565.js\r\n     * An unoptimized version of dxtToRgb565.  Also, the floating\r\n     * point math used to compute the colors actually results in\r\n     * slightly different colors compared to hardware DXT decoders.\r\n     * @param src dxt src pixels\r\n     * @param srcByteOffset offset for the start of src\r\n     * @param  width aligned width of the image\r\n     * @param  height aligned height of the image\r\n     * @returns the converted pixels\r\n     */\r\n    function ConvertDxtToRgb565(src: Uint8Array, srcByteOffset: number, width: number, height: number): Uint16Array {\r\n        const c = new Uint16Array(4);\r\n        const dst = new Uint16Array(width * height);\r\n\r\n        const blockWidth = width / 4;\r\n        const blockHeight = height / 4;\r\n        for (let blockY = 0; blockY < blockHeight; blockY++) {\r\n            for (let blockX = 0; blockX < blockWidth; blockX++) {\r\n                const i = srcByteOffset + 8 * (blockY * blockWidth + blockX);\r\n                c[0] = src[i] | (src[i + 1] << 8);\r\n                c[1] = src[i + 2] | (src[i + 3] << 8);\r\n                c[2] =\r\n                    ((2 * (c[0] & 0x1f) + 1 * (c[1] & 0x1f)) / 3) |\r\n                    (((2 * (c[0] & 0x7e0) + 1 * (c[1] & 0x7e0)) / 3) & 0x7e0) |\r\n                    (((2 * (c[0] & 0xf800) + 1 * (c[1] & 0xf800)) / 3) & 0xf800);\r\n                c[3] =\r\n                    ((2 * (c[1] & 0x1f) + 1 * (c[0] & 0x1f)) / 3) |\r\n                    (((2 * (c[1] & 0x7e0) + 1 * (c[0] & 0x7e0)) / 3) & 0x7e0) |\r\n                    (((2 * (c[1] & 0xf800) + 1 * (c[0] & 0xf800)) / 3) & 0xf800);\r\n                for (let row = 0; row < 4; row++) {\r\n                    const m = src[i + 4 + row];\r\n                    let dstI = (blockY * 4 + row) * width + blockX * 4;\r\n                    dst[dstI++] = c[m & 0x3];\r\n                    dst[dstI++] = c[(m >> 2) & 0x3];\r\n                    dst[dstI++] = c[(m >> 4) & 0x3];\r\n                    dst[dstI] = c[(m >> 6) & 0x3];\r\n                }\r\n            }\r\n        }\r\n        return dst;\r\n    }\r\n}\r\n\r\n/**\r\n * Initialize a web worker with the basis transcoder\r\n * @param worker the worker to initialize\r\n * @param wasmBinary the wasm binary to load into the worker\r\n * @param moduleUrl the url to the basis transcoder module\r\n * @returns a promise that resolves when the worker is initialized\r\n */\r\n// eslint-disable-next-line no-restricted-syntax\r\nexport async function initializeWebWorker(worker: Worker, wasmBinary: ArrayBuffer, moduleUrl?: string) {\r\n    return await new Promise<Worker>((res, reject) => {\r\n        const initHandler = (msg: any) => {\r\n            if (msg.data.action === \"init\") {\r\n                worker.removeEventListener(\"message\", initHandler);\r\n                res(worker);\r\n            } else if (msg.data.action === \"error\") {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                reject(msg.data.error || \"error initializing worker\");\r\n            }\r\n        };\r\n        worker.addEventListener(\"message\", initHandler);\r\n        // we can use transferable objects here because the worker will own the ArrayBuffer\r\n        worker.postMessage({ action: \"init\", url: moduleUrl ? Tools.GetBabylonScriptURL(moduleUrl) : undefined, wasmBinary }, [wasmBinary]);\r\n    });\r\n}\r\n","import { type Nullable } from \"../../../types\";\r\nimport { type InternalTexture } from \"../../../Materials/Textures/internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { LoadTextureFromTranscodeResult, TranscodeAsync } from \"../../../Misc/basis.pure\";\r\nimport { Tools } from \"../../../Misc/tools.pure\";\r\n\r\n/**\r\n * Loader for .basis file format\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _BasisTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param createPolynomials will be true if polynomials have been requested\r\n     * @param onLoad defines the callback to trigger once the texture is ready\r\n     * @param onError defines the callback to trigger in case of error\r\n     */\r\n    public loadCubeData(\r\n        data: ArrayBufferView | ArrayBufferView[],\r\n        texture: InternalTexture,\r\n        createPolynomials: boolean,\r\n        onLoad: Nullable<(data?: any) => void>,\r\n        onError: Nullable<(message?: string, exception?: any) => void>\r\n    ): void {\r\n        if (Array.isArray(data)) {\r\n            return;\r\n        }\r\n        const caps = texture.getEngine().getCaps();\r\n        const transcodeConfig = {\r\n            supportedCompressionFormats: {\r\n                etc1: caps.etc1 ? true : false,\r\n                s3tc: caps.s3tc ? true : false,\r\n                pvrtc: caps.pvrtc ? true : false,\r\n                etc2: caps.etc2 ? true : false,\r\n                astc: caps.astc ? true : false,\r\n                bc7: caps.bptc ? true : false,\r\n            },\r\n        };\r\n        TranscodeAsync(data, transcodeConfig)\r\n            // eslint-disable-next-line github/no-then\r\n            .then((result) => {\r\n                const hasMipmap = result.fileInfo.images[0].levels.length > 1 && texture.generateMipMaps;\r\n                LoadTextureFromTranscodeResult(texture, result);\r\n                texture.getEngine()._setCubeMapTextureParams(texture, hasMipmap);\r\n                texture.isReady = true;\r\n                texture.onLoadedObservable.notifyObservers(texture);\r\n                texture.onLoadedObservable.clear();\r\n                if (onLoad) {\r\n                    onLoad();\r\n                }\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .catch((err) => {\r\n                const errorMessage = \"Failed to transcode Basis file, transcoding may not be supported on this device\";\r\n                Tools.Warn(errorMessage);\r\n                texture.isReady = true;\r\n                if (onError) {\r\n                    onError(err);\r\n                }\r\n            });\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     */\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, failedLoading?: boolean) => void\r\n    ): void {\r\n        const caps = texture.getEngine().getCaps();\r\n        const transcodeConfig = {\r\n            supportedCompressionFormats: {\r\n                etc1: caps.etc1 ? true : false,\r\n                s3tc: caps.s3tc ? true : false,\r\n                pvrtc: caps.pvrtc ? true : false,\r\n                etc2: caps.etc2 ? true : false,\r\n                astc: caps.astc ? true : false,\r\n                bc7: caps.bptc ? true : false,\r\n            },\r\n        };\r\n        TranscodeAsync(data, transcodeConfig)\r\n            // eslint-disable-next-line github/no-then\r\n            .then((result) => {\r\n                const rootImage = result.fileInfo.images[0].levels[0];\r\n                const hasMipmap = result.fileInfo.images[0].levels.length > 1 && texture.generateMipMaps;\r\n                callback(rootImage.width, rootImage.height, hasMipmap, result.format !== -1, () => {\r\n                    LoadTextureFromTranscodeResult(texture, result);\r\n                });\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .catch((err) => {\r\n                Tools.Warn(\"Failed to transcode Basis file, transcoding may not be supported on this device\");\r\n                Tools.Warn(`Failed to transcode Basis file: ${err}`);\r\n                callback(0, 0, false, false, () => {}, true);\r\n            });\r\n    }\r\n}\r\n","import { type InternalTexture } from \"../internalTexture\";\r\nimport { type IInternalTextureLoader } from \"./internalTextureLoader\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { LoadIESData } from \"core/Lights/IES/iesLoader\";\r\n\r\n/**\r\n * Implementation of the IES Texture Loader.\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class _IESTextureLoader implements IInternalTextureLoader {\r\n    /**\r\n     * Defines whether the loader supports cascade loading the different faces.\r\n     */\r\n    public readonly supportCascades = false;\r\n\r\n    /**\r\n     * Uploads the cube texture data to the WebGL texture. It has already been bound.\r\n     */\r\n    public loadCubeData(): void {\r\n        // eslint-disable-next-line no-throw-literal\r\n        throw \".ies not supported in Cube.\";\r\n    }\r\n\r\n    /**\r\n     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.\r\n     * @param data contains the texture data\r\n     * @param texture defines the BabylonJS internal texture\r\n     * @param callback defines the method to call once ready to upload\r\n     */\r\n    public loadData(\r\n        data: ArrayBufferView,\r\n        texture: InternalTexture,\r\n        callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void\r\n    ): void {\r\n        const uint8array = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\r\n\r\n        const textureData = LoadIESData(uint8array);\r\n\r\n        callback(textureData.width, textureData.height, !!texture.useMipMaps, false, () => {\r\n            const engine = texture.getEngine();\r\n            texture.type = Constants.TEXTURETYPE_FLOAT;\r\n            texture.format = Constants.TEXTUREFORMAT_R;\r\n            texture._gammaSpace = false;\r\n            engine._uploadDataToTextureDirectly(texture, textureData.data);\r\n        });\r\n    }\r\n}\r\n","import { type Vector2 } from \"../../../Maths/math.vector\";\r\n\r\n/**\r\n * Defines the basic options interface of a TexturePacker Frame\r\n */\r\nexport interface ITexturePackerFrame {\r\n    /**\r\n     * The frame ID\r\n     */\r\n    id: number;\r\n\r\n    /**\r\n     * The frames Scale\r\n     */\r\n    scale: Vector2;\r\n\r\n    /**\r\n     * The Frames offset\r\n     */\r\n    offset: Vector2;\r\n}\r\n\r\n/**\r\n * This is a support class for frame Data on texture packer sets.\r\n */\r\nexport class TexturePackerFrame implements ITexturePackerFrame {\r\n    /**\r\n     * The frame ID\r\n     */\r\n    public id: number;\r\n\r\n    /**\r\n     * The frames Scale\r\n     */\r\n    public scale: Vector2;\r\n\r\n    /**\r\n     * The Frames offset\r\n     */\r\n    public offset: Vector2;\r\n\r\n    /**\r\n     * Initializes a texture package frame.\r\n     * @param id The numerical frame identifier\r\n     * @param scale Scalar Vector2 for UV frame\r\n     * @param offset Vector2 for the frame position in UV units.\r\n     * @returns TexturePackerFrame\r\n     */\r\n    constructor(id: number, scale: Vector2, offset: Vector2) {\r\n        this.id = id;\r\n        this.scale = scale;\r\n        this.offset = offset;\r\n    }\r\n}\r\n","import { type AbstractMesh } from \"../../../Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"../../../Buffers/buffer.pure\";\r\nimport { type Scene } from \"../../../scene\";\r\nimport { type Material } from \"../../material\";\r\nimport { Texture } from \"../texture.pure\";\r\nimport { DynamicTexture } from \"../dynamicTexture.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Vector2 } from \"../../../Maths/math.vector.pure\";\r\nimport { Color3, Color4 } from \"../../../Maths/math.color.pure\";\r\nimport { TexturePackerFrame } from \"./frame\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { Tools } from \"../../../Misc/tools.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\n/**\r\n * Defines the basic options interface of a TexturePacker\r\n */\r\nexport interface ITexturePackerOptions {\r\n    /**\r\n     * Custom targets for the channels of a texture packer.  Default is all the channels of the Standard Material\r\n     */\r\n    map?: string[];\r\n\r\n    /**\r\n     * the UV input targets, as a single value for all meshes. Defaults to VertexBuffer.UVKind\r\n     */\r\n    uvsIn?: string;\r\n\r\n    /**\r\n     * the UV output targets, as a single value for all meshes.  Defaults to VertexBuffer.UVKind\r\n     */\r\n    uvsOut?: string;\r\n\r\n    /**\r\n     * number representing the layout style. Defaults to LAYOUT_STRIP\r\n     */\r\n    layout?: number;\r\n\r\n    /**\r\n     * number of columns if using custom column count layout(2).  This defaults to 4.\r\n     */\r\n    colnum?: number;\r\n\r\n    /**\r\n     * flag to update the input meshes to the new packed texture after compilation. Defaults to true.\r\n     */\r\n    updateInputMeshes?: boolean;\r\n\r\n    /**\r\n     * boolean flag to dispose all the source textures.  Defaults to true.\r\n     */\r\n    disposeSources?: boolean;\r\n\r\n    /**\r\n     * Fills the blank cells in a set to the customFillColor.  Defaults to true.\r\n     */\r\n    fillBlanks?: boolean;\r\n\r\n    /**\r\n     * string value representing the context fill style color.  Defaults to 'black'.\r\n     */\r\n    customFillColor?: string;\r\n\r\n    /**\r\n     * Width and Height Value of each Frame in the TexturePacker Sets\r\n     */\r\n    frameSize?: number;\r\n\r\n    /**\r\n     * Ratio of the value to add padding wise to each cell.  Defaults to 0.0115\r\n     */\r\n    paddingRatio?: number;\r\n\r\n    /**\r\n     * Number that declares the fill method for the padding gutter.\r\n     */\r\n    paddingMode?: number;\r\n\r\n    /**\r\n     * If in SUBUV_COLOR padding mode what color to use.\r\n     */\r\n    paddingColor?: Color3 | Color4;\r\n}\r\n\r\n/**\r\n * Defines the basic interface of a TexturePacker JSON File\r\n */\r\nexport interface ITexturePackerJSON {\r\n    /**\r\n     * The frame ID\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * The base64 channel data\r\n     */\r\n    sets: any;\r\n\r\n    /**\r\n     * The options of the Packer\r\n     */\r\n    options: ITexturePackerOptions;\r\n\r\n    /**\r\n     * The frame data of the Packer\r\n     */\r\n    frames: Array<number>;\r\n}\r\n\r\n/**\r\n * This is a support class that generates a series of packed texture sets.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction\r\n */\r\nexport class TexturePacker {\r\n    /** Packer Layout Constant 0 */\r\n    public static readonly LAYOUT_STRIP = 0;\r\n    /** Packer Layout Constant 1 */\r\n    public static readonly LAYOUT_POWER2 = 1;\r\n    /** Packer Layout Constant 2 */\r\n    public static readonly LAYOUT_COLNUM = 2;\r\n\r\n    /** Packer Layout Constant 0 */\r\n    public static readonly SUBUV_WRAP = 0;\r\n    /** Packer Layout Constant 1 */\r\n    public static readonly SUBUV_EXTEND = 1;\r\n    /** Packer Layout Constant 2 */\r\n    public static readonly SUBUV_COLOR = 2;\r\n\r\n    /** The Name of the Texture Package */\r\n    public name: string;\r\n\r\n    /** The scene scope of the TexturePacker */\r\n    public scene: Scene;\r\n\r\n    /** The Meshes to target */\r\n    public meshes: AbstractMesh[];\r\n\r\n    /** Arguments passed with the Constructor */\r\n    public options: ITexturePackerOptions;\r\n\r\n    /** The promise that is started upon initialization */\r\n    public promise: Nullable<Promise<TexturePacker | string>>;\r\n\r\n    /** The Container object for the channel sets that are generated */\r\n    public sets: object;\r\n\r\n    /** The Container array for the frames that are generated */\r\n    public frames: TexturePackerFrame[];\r\n\r\n    /** The expected number of textures the system is parsing. */\r\n    private _expecting: number;\r\n\r\n    /** The padding value from Math.ceil(frameSize * paddingRatio) */\r\n    private _paddingValue: number;\r\n\r\n    /**\r\n     * Initializes a texture package series from an array of meshes or a single mesh.\r\n     * @param name The name of the package\r\n     * @param meshes The target meshes to compose the package from\r\n     * @param options The arguments that texture packer should follow while building.\r\n     * @param scene The scene which the textures are scoped to.\r\n     * @returns TexturePacker\r\n     */\r\n    constructor(name: string, meshes: AbstractMesh[], options: ITexturePackerOptions, scene: Scene) {\r\n        this.name = name;\r\n        this.meshes = meshes;\r\n        this.scene = scene;\r\n\r\n        /**\r\n         * Run through the options and set what ever defaults are needed that where not declared.\r\n         */\r\n        this.options = options;\r\n        this.options.map = this.options.map ?? [\r\n            \"ambientTexture\",\r\n            \"bumpTexture\",\r\n            \"diffuseTexture\",\r\n            \"emissiveTexture\",\r\n            \"lightmapTexture\",\r\n            \"opacityTexture\",\r\n            \"reflectionTexture\",\r\n            \"refractionTexture\",\r\n            \"specularTexture\",\r\n        ];\r\n\r\n        this.options.uvsIn = this.options.uvsIn ?? VertexBuffer.UVKind;\r\n        this.options.uvsOut = this.options.uvsOut ?? VertexBuffer.UVKind;\r\n        this.options.layout = this.options.layout ?? TexturePacker.LAYOUT_STRIP;\r\n\r\n        if (this.options.layout === TexturePacker.LAYOUT_COLNUM) {\r\n            this.options.colnum = this.options.colnum ?? 8;\r\n        }\r\n\r\n        this.options.updateInputMeshes = this.options.updateInputMeshes ?? true;\r\n        this.options.disposeSources = this.options.disposeSources ?? true;\r\n        this._expecting = 0;\r\n\r\n        this.options.fillBlanks = this.options.fillBlanks ?? true;\r\n\r\n        if (this.options.fillBlanks === true) {\r\n            this.options.customFillColor = this.options.customFillColor ?? \"black\";\r\n        }\r\n\r\n        this.options.frameSize = this.options.frameSize ?? 256;\r\n        this.options.paddingRatio = this.options.paddingRatio ?? 0.0115;\r\n\r\n        this._paddingValue = Math.ceil(this.options.frameSize * this.options.paddingRatio);\r\n\r\n        //Make it an even padding Number.\r\n        if (this._paddingValue % 2 !== 0) {\r\n            this._paddingValue++;\r\n        }\r\n\r\n        this.options.paddingMode = this.options.paddingMode ?? TexturePacker.SUBUV_WRAP;\r\n\r\n        if (this.options.paddingMode === TexturePacker.SUBUV_COLOR) {\r\n            this.options.paddingColor = this.options.paddingColor ?? new Color4(0, 0, 0, 1.0);\r\n        }\r\n\r\n        this.sets = {};\r\n        this.frames = [];\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Starts the package process\r\n     * @param resolve The promises resolution function\r\n     */\r\n    private _createFrames(resolve: () => void) {\r\n        const dtSize = this._calculateSize();\r\n        const dtUnits = new Vector2(1, 1).divide(dtSize);\r\n        let doneCount = 0;\r\n        const expecting = this._expecting;\r\n        const meshLength = this.meshes.length;\r\n\r\n        const sKeys = Object.keys(this.sets);\r\n        for (let i = 0; i < sKeys.length; i++) {\r\n            const setName = sKeys[i];\r\n\r\n            const dt = new DynamicTexture(\r\n                this.name + \".TexturePack.\" + setName + \"Set\",\r\n                { width: dtSize.x, height: dtSize.y },\r\n                this.scene,\r\n                true, //Generate Mips\r\n                Texture.TRILINEAR_SAMPLINGMODE,\r\n                Constants.TEXTUREFORMAT_RGBA\r\n            );\r\n\r\n            const dtx = dt.getContext();\r\n            dtx.fillStyle = \"rgba(0,0,0,0)\";\r\n            dtx.fillRect(0, 0, dtSize.x, dtSize.y);\r\n            dt.update(false);\r\n            (this.sets as any)[setName] = dt;\r\n        }\r\n\r\n        const baseSize = this.options.frameSize || 256;\r\n        const padding = this._paddingValue;\r\n        const tcs = baseSize + 2 * padding;\r\n\r\n        const done = () => {\r\n            this._calculateMeshUVFrames(baseSize, padding, dtSize, dtUnits, this.options.updateInputMeshes || false);\r\n        };\r\n\r\n        //Update the Textures\r\n        for (let i = 0; i < meshLength; i++) {\r\n            const m = this.meshes[i];\r\n            const mat = m.material;\r\n\r\n            //Check if the material has the texture\r\n            //Create a temporary canvas the same size as 1 frame\r\n            //Then apply the texture to the center and the 8 offsets\r\n            //Copy the Context and place in the correct frame on the DT\r\n\r\n            for (let j = 0; j < sKeys.length; j++) {\r\n                const tempTexture = new DynamicTexture(\"temp\", tcs, this.scene, true);\r\n                const tcx = tempTexture.getContext();\r\n                const offset = this._getFrameOffset(i);\r\n\r\n                const updateDt = () => {\r\n                    doneCount++;\r\n                    tempTexture.update(false);\r\n                    const iDat = tcx.getImageData(0, 0, tcs, tcs);\r\n\r\n                    //Update Set\r\n                    const dt = (this.sets as any)[setName];\r\n                    const dtx = dt.getContext();\r\n                    dtx.putImageData(iDat, dtSize.x * offset.x, dtSize.y * offset.y);\r\n                    tempTexture.dispose();\r\n                    dt.update(false);\r\n                    if (doneCount == expecting) {\r\n                        done();\r\n                        resolve();\r\n                        return;\r\n                    }\r\n                };\r\n\r\n                const setName = sKeys[j] || \"_blank\";\r\n                if (!mat || (mat as any)[setName] === null) {\r\n                    tcx.fillStyle = \"rgba(0,0,0,0)\";\r\n\r\n                    if (this.options.fillBlanks) {\r\n                        tcx.fillStyle = this.options.customFillColor as string;\r\n                    }\r\n\r\n                    tcx.fillRect(0, 0, tcs, tcs);\r\n\r\n                    updateDt();\r\n                } else {\r\n                    const setTexture = (mat as any)[setName];\r\n                    const img = new Image();\r\n\r\n                    if (setTexture instanceof DynamicTexture) {\r\n                        img.src = setTexture.getContext().canvas.toDataURL(\"image/png\");\r\n                    } else {\r\n                        img.src = setTexture!.url;\r\n                    }\r\n                    Tools.SetCorsBehavior(img.src, img);\r\n\r\n                    img.onload = () => {\r\n                        tcx.fillStyle = \"rgba(0,0,0,0)\";\r\n                        tcx.fillRect(0, 0, tcs, tcs);\r\n                        tempTexture.update(false);\r\n\r\n                        tcx.setTransform(1, 0, 0, -1, 0, 0);\r\n                        const cellOffsets = [0, 0, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1 - 1, 0, -1, 1, -1];\r\n\r\n                        switch (this.options.paddingMode) {\r\n                            //Wrap Mode\r\n                            case 0:\r\n                                for (let i = 0; i < 9; i++) {\r\n                                    tcx.drawImage(\r\n                                        img,\r\n                                        0,\r\n                                        0,\r\n                                        img.width,\r\n                                        img.height,\r\n                                        padding + baseSize * cellOffsets[i],\r\n                                        padding + baseSize * cellOffsets[i + 1] - tcs,\r\n                                        baseSize,\r\n                                        baseSize\r\n                                    );\r\n                                }\r\n                                break;\r\n                            //Extend Mode\r\n                            case 1:\r\n                                for (let i = 0; i < padding; i++) {\r\n                                    tcx.drawImage(img, 0, 0, img.width, img.height, i + baseSize * cellOffsets[0], padding - tcs, baseSize, baseSize);\r\n\r\n                                    tcx.drawImage(img, 0, 0, img.width, img.height, padding * 2 - i, padding - tcs, baseSize, baseSize);\r\n\r\n                                    tcx.drawImage(img, 0, 0, img.width, img.height, padding, i - tcs, baseSize, baseSize);\r\n\r\n                                    tcx.drawImage(img, 0, 0, img.width, img.height, padding, padding * 2 - i - tcs, baseSize, baseSize);\r\n                                }\r\n\r\n                                tcx.drawImage(img, 0, 0, img.width, img.height, padding + baseSize * cellOffsets[0], padding + baseSize * cellOffsets[1] - tcs, baseSize, baseSize);\r\n\r\n                                break;\r\n                            //Color Mode\r\n                            case 2:\r\n                                tcx.fillStyle = (this.options.paddingColor || Color3.Black()).toHexString();\r\n                                tcx.fillRect(0, 0, tcs, -tcs);\r\n                                tcx.clearRect(padding, padding, baseSize, baseSize);\r\n                                tcx.drawImage(img, 0, 0, img.width, img.height, padding + baseSize * cellOffsets[0], padding + baseSize * cellOffsets[1] - tcs, baseSize, baseSize);\r\n\r\n                                break;\r\n                        }\r\n\r\n                        tcx.setTransform(1, 0, 0, 1, 0, 0);\r\n\r\n                        updateDt();\r\n                    };\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Calculates the Size of the Channel Sets\r\n     * @returns Vector2\r\n     */\r\n    private _calculateSize(): Vector2 {\r\n        const meshLength: number = this.meshes.length || 0;\r\n        const baseSize: number = this.options.frameSize || 0;\r\n        const padding: number = this._paddingValue || 0;\r\n\r\n        switch (this.options.layout) {\r\n            case 0: {\r\n                //STRIP_LAYOUT\r\n                return new Vector2(baseSize * meshLength + 2 * padding * meshLength, baseSize + 2 * padding);\r\n            }\r\n            case 1: {\r\n                //POWER2\r\n                const sqrtCount = Math.max(2, Math.ceil(Math.sqrt(meshLength)));\r\n                const size = baseSize * sqrtCount + 2 * padding * sqrtCount;\r\n                return new Vector2(size, size);\r\n            }\r\n            case 2: {\r\n                //COLNUM\r\n                const cols = this.options.colnum || 1;\r\n                const rowCnt = Math.max(1, Math.ceil(meshLength / cols));\r\n                return new Vector2(baseSize * cols + 2 * padding * cols, baseSize * rowCnt + 2 * padding * rowCnt);\r\n            }\r\n        }\r\n\r\n        return Vector2.Zero();\r\n    }\r\n\r\n    /**\r\n     * Calculates the UV data for the frames.\r\n     * @param baseSize the base frameSize\r\n     * @param padding the base frame padding\r\n     * @param dtSize size of the Dynamic Texture for that channel\r\n     * @param dtUnits is 1/dtSize\r\n     * @param update flag to update the input meshes\r\n     */\r\n    private _calculateMeshUVFrames(baseSize: number, padding: number, dtSize: Vector2, dtUnits: Vector2, update: boolean) {\r\n        const meshLength = this.meshes.length;\r\n\r\n        for (let i = 0; i < meshLength; i++) {\r\n            const m = this.meshes[i];\r\n\r\n            const scale = new Vector2(baseSize / dtSize.x, baseSize / dtSize.y);\r\n\r\n            const pOffset: Vector2 = dtUnits.clone().scale(padding);\r\n            const frameOffset: Vector2 = this._getFrameOffset(i);\r\n            const offset: Vector2 = frameOffset.add(pOffset);\r\n\r\n            const frame: TexturePackerFrame = new TexturePackerFrame(i, scale, offset);\r\n\r\n            this.frames.push(frame);\r\n\r\n            //Update Output UVs\r\n            if (update) {\r\n                this._updateMeshUV(m, i);\r\n                this._updateTextureReferences(m);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Calculates the frames Offset.\r\n     * @param index of the frame\r\n     * @returns Vector2\r\n     */\r\n    private _getFrameOffset(index: number): Vector2 {\r\n        const meshLength = this.meshes.length;\r\n        let uvStep, yStep, xStep;\r\n\r\n        switch (this.options.layout) {\r\n            case 0: {\r\n                //STRIP_LAYOUT\r\n                uvStep = 1 / meshLength;\r\n                return new Vector2(index * uvStep, 0);\r\n            }\r\n            case 1: {\r\n                //POWER2\r\n                const sqrtCount = Math.max(2, Math.ceil(Math.sqrt(meshLength)));\r\n                yStep = Math.floor(index / sqrtCount);\r\n                xStep = index - yStep * sqrtCount;\r\n                uvStep = 1 / sqrtCount;\r\n                return new Vector2(xStep * uvStep, yStep * uvStep);\r\n            }\r\n            case 2: {\r\n                //COLNUM\r\n                const cols = this.options.colnum || 1;\r\n                const rowCnt = Math.max(1, Math.ceil(meshLength / cols));\r\n                xStep = Math.floor(index / rowCnt);\r\n                yStep = index - xStep * rowCnt;\r\n                uvStep = new Vector2(1 / cols, 1 / rowCnt);\r\n                return new Vector2(xStep * uvStep.x, yStep * uvStep.y);\r\n            }\r\n        }\r\n\r\n        return Vector2.Zero();\r\n    }\r\n\r\n    /**\r\n     * Updates a Mesh to the frame data\r\n     * @param mesh that is the target\r\n     * @param frameID or the frame index\r\n     */\r\n    private _updateMeshUV(mesh: AbstractMesh, frameID: number): void {\r\n        const frame: TexturePackerFrame = (this.frames as any)[frameID];\r\n        const uvIn = mesh.getVerticesData(this.options.uvsIn || VertexBuffer.UVKind);\r\n        const uvOut = [];\r\n        let toCount = 0;\r\n\r\n        if (uvIn!.length) {\r\n            toCount = uvIn!.length || 0;\r\n        }\r\n\r\n        for (let i = 0; i < toCount; i += 2) {\r\n            uvOut.push((uvIn as any)[i] * frame.scale.x + frame.offset.x, (uvIn as any)[i + 1] * frame.scale.y + frame.offset.y);\r\n        }\r\n\r\n        mesh.setVerticesData(this.options.uvsOut || VertexBuffer.UVKind, uvOut);\r\n    }\r\n\r\n    /**\r\n     * Updates a Meshes materials to use the texture packer channels\r\n     * @param m is the mesh to target\r\n     * @param force all channels on the packer to be set.\r\n     */\r\n    private _updateTextureReferences(m: AbstractMesh, force: boolean = false): void {\r\n        const mat = m.material;\r\n        const sKeys = Object.keys(this.sets);\r\n\r\n        const _dispose = (_t: any) => {\r\n            if (_t.dispose) {\r\n                _t.dispose();\r\n            }\r\n        };\r\n\r\n        for (let i = 0; i < sKeys.length; i++) {\r\n            const setName = sKeys[i];\r\n            if (!force) {\r\n                if (!mat) {\r\n                    return;\r\n                }\r\n                if ((mat as any)[setName] !== null) {\r\n                    _dispose((mat as any)[setName]);\r\n                    (mat as any)[setName] = (this.sets as any)[setName];\r\n                }\r\n            } else {\r\n                if ((mat as any)[setName] !== null) {\r\n                    _dispose((mat as any)[setName]);\r\n                }\r\n                (mat as any)[setName] = (this.sets as any)[setName];\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Public method to set a Mesh to a frame\r\n     * @param m that is the target\r\n     * @param frameID or the frame index\r\n     * @param updateMaterial trigger for if the Meshes attached Material be updated?\r\n     */\r\n    public setMeshToFrame(m: AbstractMesh, frameID: number, updateMaterial: boolean = false): void {\r\n        this._updateMeshUV(m, frameID);\r\n        if (updateMaterial) {\r\n            this._updateTextureReferences(m, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Starts the async promise to compile the texture packer.\r\n     * @returns Promise<void>\r\n     */\r\n    public async processAsync(): Promise<void> {\r\n        return await new Promise((resolve, reject) => {\r\n            try {\r\n                if (this.meshes.length === 0) {\r\n                    //Must be a JSON load!\r\n                    resolve();\r\n                    return;\r\n                }\r\n                let done = 0;\r\n                const doneCheck = (mat: Material) => {\r\n                    done++;\r\n                    //Check Status of all Textures on all meshes, till they are ready.\r\n                    if (this.options.map) {\r\n                        for (let j = 0; j < this.options.map.length; j++) {\r\n                            const index: string = this.options.map[j];\r\n                            const t: Texture | DynamicTexture = (mat as any)[index];\r\n\r\n                            if (t !== null) {\r\n                                if (!(this.sets as any)[this.options.map[j]]) {\r\n                                    (this.sets as any)[this.options.map[j]] = true;\r\n                                }\r\n\r\n                                this._expecting++;\r\n                            }\r\n                        }\r\n\r\n                        if (done === this.meshes.length) {\r\n                            this._createFrames(resolve);\r\n                        }\r\n                    }\r\n                };\r\n\r\n                for (let i = 0; i < this.meshes.length; i++) {\r\n                    const mesh = this.meshes[i];\r\n                    const material: Nullable<Material> = mesh.material;\r\n\r\n                    if (!material) {\r\n                        done++;\r\n                        if (done === this.meshes.length) {\r\n                            return this._createFrames(resolve);\r\n                        }\r\n                        continue;\r\n                    }\r\n\r\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                    material.forceCompilationAsync(mesh).then(() => {\r\n                        doneCheck(material);\r\n                    });\r\n                }\r\n            } catch (e) {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                return reject(e);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Disposes all textures associated with this packer\r\n     */\r\n    public dispose(): void {\r\n        const sKeys = Object.keys(this.sets);\r\n        for (let i = 0; i < sKeys.length; i++) {\r\n            const channel = sKeys[i];\r\n            (this.sets as any)[channel].dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Starts the download process for all the channels converting them to base64 data and embedding it all in a JSON file.\r\n     * @param imageType is the image type to use.\r\n     * @param quality of the image if downloading as jpeg, Ranges from >0 to 1.\r\n     */\r\n    public download(imageType: string = \"png\", quality: number = 1): void {\r\n        setTimeout(() => {\r\n            const pack = {\r\n                name: this.name,\r\n                sets: {},\r\n                options: {},\r\n                frames: [],\r\n            };\r\n\r\n            const sKeys = Object.keys(this.sets);\r\n            const oKeys = Object.keys(this.options);\r\n            try {\r\n                for (let i = 0; i < sKeys.length; i++) {\r\n                    const channel: string = sKeys[i];\r\n                    const dt = (this.sets as any)[channel];\r\n                    (pack.sets as any)[channel] = dt.getContext().canvas.toDataURL(\"image/\" + imageType, quality);\r\n                }\r\n                for (let i = 0; i < oKeys.length; i++) {\r\n                    const opt: string = oKeys[i];\r\n                    (pack.options as any)[opt] = (this.options as any)[opt];\r\n                }\r\n                for (let i = 0; i < this.frames.length; i++) {\r\n                    const _f = this.frames[i];\r\n                    (pack.frames as Array<number>).push(_f.scale.x, _f.scale.y, _f.offset.x, _f.offset.y);\r\n                }\r\n            } catch (err) {\r\n                Logger.Warn(\"Unable to download: \" + err);\r\n                return;\r\n            }\r\n\r\n            const data = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(pack, null, 4));\r\n            const _a = document.createElement(\"a\");\r\n            _a.setAttribute(\"href\", data);\r\n            _a.setAttribute(\"download\", this.name + \"_texurePackage.json\");\r\n            document.body.appendChild(_a);\r\n            _a.click();\r\n            _a.remove();\r\n        }, 0);\r\n    }\r\n\r\n    /**\r\n     * Public method to load a texturePacker JSON file.\r\n     * @param data of the JSON file in string format.\r\n     */\r\n    public updateFromJSON(data: string): void {\r\n        try {\r\n            const parsedData: ITexturePackerJSON = JSON.parse(data);\r\n            this.name = parsedData.name;\r\n            const _options = Object.keys(parsedData.options);\r\n\r\n            for (let i = 0; i < _options.length; i++) {\r\n                (this.options as any)[_options[i]] = (parsedData.options as any)[_options[i]];\r\n            }\r\n\r\n            for (let i = 0; i < parsedData.frames.length; i += 4) {\r\n                const frame: TexturePackerFrame = new TexturePackerFrame(\r\n                    i / 4,\r\n                    new Vector2(parsedData.frames[i], parsedData.frames[i + 1]),\r\n                    new Vector2(parsedData.frames[i + 2], parsedData.frames[i + 3])\r\n                );\r\n                this.frames.push(frame);\r\n            }\r\n\r\n            const channels = Object.keys(parsedData.sets);\r\n\r\n            for (let i = 0; i < channels.length; i++) {\r\n                const _t = new Texture(parsedData.sets[channels[i]], this.scene, false, false);\r\n                (this.sets as any)[channels[i]] = _t;\r\n            }\r\n        } catch (err) {\r\n            Logger.Warn(\"Unable to update from JSON: \" + err);\r\n        }\r\n    }\r\n}\r\n","import { Logger } from \"../../../Misc/logger\";\r\nimport { type Scene } from \"../../../scene\";\r\nimport { Vector3, Vector2 } from \"../../../Maths/math.vector.pure\";\r\nimport { Color4, Color3 } from \"../../../Maths/math.color.pure\";\r\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\r\nimport { type IProceduralTextureCreationOptions, ProceduralTexture } from \"./proceduralTexture.pure\";\r\nimport { WebRequest } from \"../../../Misc/webRequest\";\r\nimport { type TextureSize } from \"../../../Materials/Textures/textureCreationOptions\";\r\n\r\n/**\r\n * Options to create a Custom Procedural Texture.\r\n */\r\nexport interface ICustomProceduralTextureCreationOptions extends IProceduralTextureCreationOptions {\r\n    /**\r\n     * Define a boolena indicating that there is no json config file to load\r\n     */\r\n    skipJson?: boolean;\r\n}\r\n\r\n/**\r\n * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes called 'refMaps' or 'sampler' images.\r\n * Custom Procedural textures are the easiest way to create your own procedural in your application.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/proceduralTextures#creating-custom-procedural-textures\r\n */\r\nexport class CustomProceduralTexture extends ProceduralTexture {\r\n    private _animate: boolean = true;\r\n    private _time: number = 0;\r\n    private _config: any;\r\n    private _texturePath: string;\r\n\r\n    /**\r\n     * Instantiates a new Custom Procedural Texture.\r\n     * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes called 'refMaps' or 'sampler' images.\r\n     * Custom Procedural textures are the easiest way to create your own procedural in your application.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/proceduralTextures#creating-custom-procedural-textures\r\n     * @param name Define the name of the texture\r\n     * @param texturePath Define the folder path containing all the custom texture related files (config, shaders...)\r\n     * @param size Define the size of the texture to create\r\n     * @param scene Define the scene the texture belongs to\r\n     * @param fallbackTexture Define a fallback texture in case there were issues to create the custom texture\r\n     * @param generateMipMaps Define if the texture should creates mip maps or not\r\n     * @param skipJson Define a boolena indicating that there is no json config file to load\r\n     */\r\n    constructor(\r\n        name: string,\r\n        texturePath: string,\r\n        size: TextureSize,\r\n        scene: Scene,\r\n        fallbackTexture?: Texture | ICustomProceduralTextureCreationOptions,\r\n        generateMipMaps?: boolean,\r\n        skipJson?: boolean\r\n    ) {\r\n        super(name, size, null, scene, fallbackTexture, generateMipMaps);\r\n        this._texturePath = texturePath;\r\n\r\n        if (fallbackTexture && !(fallbackTexture instanceof Texture)) {\r\n            skipJson = !!fallbackTexture.skipJson;\r\n        }\r\n\r\n        if (!skipJson) {\r\n            //Try to load json\r\n            this._loadJson(texturePath);\r\n        } else {\r\n            this.setFragment(this._texturePath);\r\n        }\r\n        this.refreshRate = 1;\r\n    }\r\n\r\n    private _loadJson(jsonUrl: string): void {\r\n        const noConfigFile = () => {\r\n            try {\r\n                this.setFragment(this._texturePath);\r\n            } catch (ex) {\r\n                Logger.Log(\"No json or ShaderStore or DOM element found for CustomProceduralTexture\");\r\n            }\r\n        };\r\n\r\n        const configFileUrl = jsonUrl + \"/config.json\";\r\n        const xhr = new WebRequest();\r\n\r\n        xhr.open(\"GET\", configFileUrl);\r\n        xhr.addEventListener(\r\n            \"load\",\r\n            () => {\r\n                if (xhr.status === 200 || (xhr.responseText && xhr.responseText.length > 0)) {\r\n                    try {\r\n                        this._config = JSON.parse(xhr.response);\r\n\r\n                        this.updateShaderUniforms();\r\n                        this.updateTextures();\r\n                        this.setFragment(this._texturePath + \"/custom\");\r\n\r\n                        this._animate = this._config.animate;\r\n                        this.refreshRate = this._config.refreshrate;\r\n                    } catch (ex) {\r\n                        noConfigFile();\r\n                    }\r\n                } else {\r\n                    noConfigFile();\r\n                }\r\n            },\r\n            false\r\n        );\r\n\r\n        xhr.addEventListener(\r\n            \"error\",\r\n            () => {\r\n                noConfigFile();\r\n            },\r\n            false\r\n        );\r\n\r\n        try {\r\n            xhr.send();\r\n        } catch (ex) {\r\n            Logger.Error(\"CustomProceduralTexture: Error on XHR send request.\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Is the texture ready to be used ? (rendered at least once)\r\n     * @returns true if ready, otherwise, false.\r\n     */\r\n    public override isReady(): boolean {\r\n        if (!super.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        for (const name in this._textures) {\r\n            const texture = this._textures[name];\r\n\r\n            if (!texture.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Render the texture to its associated render target.\r\n     * @param useCameraPostProcess Define if camera post process should be applied to the texture\r\n     */\r\n    public override render(useCameraPostProcess?: boolean): void {\r\n        const scene = this.getScene();\r\n        if (this._animate && scene) {\r\n            this._time += scene.getAnimationRatio() * 0.03;\r\n            this.updateShaderUniforms();\r\n        }\r\n\r\n        super.render(useCameraPostProcess);\r\n    }\r\n\r\n    /**\r\n     * Update the list of dependant textures samplers in the shader.\r\n     */\r\n    public updateTextures(): void {\r\n        for (let i = 0; i < this._config.sampler2Ds.length; i++) {\r\n            this.setTexture(this._config.sampler2Ds[i].sample2Dname, new Texture(this._texturePath + \"/\" + this._config.sampler2Ds[i].textureRelativeUrl, this.getScene()));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the uniform values of the procedural texture in the shader.\r\n     */\r\n    public updateShaderUniforms(): void {\r\n        if (this._config) {\r\n            for (let j = 0; j < this._config.uniforms.length; j++) {\r\n                const uniform = this._config.uniforms[j];\r\n\r\n                switch (uniform.type) {\r\n                    case \"float\":\r\n                        this.setFloat(uniform.name, uniform.value);\r\n                        break;\r\n                    case \"color3\":\r\n                        this.setColor3(uniform.name, new Color3(uniform.r, uniform.g, uniform.b));\r\n                        break;\r\n                    case \"color4\":\r\n                        this.setColor4(uniform.name, new Color4(uniform.r, uniform.g, uniform.b, uniform.a));\r\n                        break;\r\n                    case \"vector2\":\r\n                        this.setVector2(uniform.name, new Vector2(uniform.x, uniform.y));\r\n                        break;\r\n                    case \"vector3\":\r\n                        this.setVector3(uniform.name, new Vector3(uniform.x, uniform.y, uniform.z));\r\n                        break;\r\n                }\r\n            }\r\n        }\r\n\r\n        this.setFloat(\"time\", this._time);\r\n    }\r\n\r\n    /**\r\n     * Define if the texture animates or not.\r\n     */\r\n    public get animate(): boolean {\r\n        return this._animate;\r\n    }\r\n\r\n    public set animate(value: boolean) {\r\n        this._animate = value;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { EngineStore } from \"../../../Engines/engineStore\";\r\nimport { type Texture } from \"../../../Materials/Textures/texture.pure\";\r\nimport { type IProceduralTextureCreationOptions, ProceduralTexture } from \"./proceduralTexture.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { ShaderLanguage } from \"../../../Materials/shaderLanguage\";\r\n\r\nlet _NoiseProceduralTextureGlslShaderPromise: Promise<void> | undefined;\r\nlet _NoiseProceduralTextureWgslShaderPromise: Promise<void> | undefined;\r\n\r\nasync function _EnsureNoiseProceduralTextureShaderAsync(shaderLanguage: ShaderLanguage = ShaderLanguage.GLSL): Promise<void> {\r\n    if (shaderLanguage === ShaderLanguage.WGSL) {\r\n        _NoiseProceduralTextureWgslShaderPromise ??= (async () => {\r\n            await import(\"../../../ShadersWGSL/noise.fragment\");\r\n        })();\r\n        await _NoiseProceduralTextureWgslShaderPromise;\r\n        return;\r\n    }\r\n\r\n    _NoiseProceduralTextureGlslShaderPromise ??= (async () => {\r\n        await import(\"../../../Shaders/noise.fragment\");\r\n    })();\r\n    await _NoiseProceduralTextureGlslShaderPromise;\r\n}\r\n\r\n/**\r\n * Class used to generate noise procedural textures\r\n */\r\nexport class NoiseProceduralTexture extends ProceduralTexture {\r\n    /** Gets or sets the start time (default is 0) */\r\n    public time: number = 0.0;\r\n\r\n    /** Gets or sets a value between 0 and 1 indicating the overall brightness of the texture (default is 0.2) */\r\n    public brightness = 0.2;\r\n\r\n    /** Defines the number of octaves to process */\r\n    public octaves = 3;\r\n\r\n    /** Defines the level of persistence (0.8 by default) */\r\n    public persistence = 0.8;\r\n\r\n    /** Gets or sets animation speed factor (default is 1) */\r\n    public animationSpeedFactor = 1;\r\n\r\n    /**\r\n     * Creates a new NoiseProceduralTexture\r\n     * @param name defines the name fo the texture\r\n     * @param size defines the size of the texture (default is 256)\r\n     * @param scene defines the hosting scene\r\n     * @param fallbackTexture defines the texture to use if the NoiseProceduralTexture can't be created\r\n     * @param generateMipMaps defines if mipmaps must be generated (true by default)\r\n     */\r\n    constructor(name: string, size: number = 256, scene: Nullable<Scene> = EngineStore.LastCreatedScene, fallbackTexture?: Texture, generateMipMaps?: boolean) {\r\n        const shaderLanguage = scene?.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n        const creationOptions: IProceduralTextureCreationOptions = {\r\n            fallbackTexture,\r\n            shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                await _EnsureNoiseProceduralTextureShaderAsync(shaderLanguage);\r\n            },\r\n        };\r\n\r\n        super(name, size, \"noise\", scene, creationOptions, generateMipMaps);\r\n        this.autoClear = false;\r\n        this._updateShaderUniforms();\r\n    }\r\n\r\n    private _updateShaderUniforms() {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return;\r\n        }\r\n\r\n        this.time += scene.getAnimationRatio() * this.animationSpeedFactor * 0.01;\r\n\r\n        this.setFloat(\"brightness\", this.brightness);\r\n        this.setFloat(\"persistence\", this.persistence);\r\n        this.setFloat(\"timeScale\", this.time);\r\n    }\r\n\r\n    protected override _getDefines(): string {\r\n        return \"#define OCTAVES \" + (this.octaves | 0);\r\n    }\r\n\r\n    /**\r\n     * Generate the current state of the procedural texture\r\n     * @param useCameraPostProcess Define if camera post process should be applied to the texture\r\n     */\r\n    public override render(useCameraPostProcess?: boolean) {\r\n        this._updateShaderUniforms();\r\n        super.render(useCameraPostProcess);\r\n    }\r\n\r\n    /**\r\n     * Serializes this noise procedural texture\r\n     * @returns a serialized noise procedural texture object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.customType = \"BABYLON.NoiseProceduralTexture\";\r\n\r\n        serializationObject.brightness = this.brightness;\r\n        serializationObject.octaves = this.octaves;\r\n        serializationObject.persistence = this.persistence;\r\n        serializationObject.animationSpeedFactor = this.animationSpeedFactor;\r\n        serializationObject.size = this.getSize().width;\r\n        serializationObject.generateMipMaps = this._generateMipMaps;\r\n        serializationObject.time = this.time;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Clone the texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): NoiseProceduralTexture {\r\n        const textureSize = this.getSize();\r\n        const newTexture = new NoiseProceduralTexture(\r\n            this.name,\r\n            textureSize.width,\r\n            this.getScene(),\r\n            this._fallbackTexture ? this._fallbackTexture : undefined,\r\n            this._generateMipMaps\r\n        );\r\n\r\n        // Base texture\r\n        newTexture.hasAlpha = this.hasAlpha;\r\n        newTexture.level = this.level;\r\n\r\n        // RenderTarget Texture\r\n        newTexture.coordinatesMode = this.coordinatesMode;\r\n\r\n        // Noise Specifics\r\n        newTexture.brightness = this.brightness;\r\n        newTexture.octaves = this.octaves;\r\n        newTexture.persistence = this.persistence;\r\n        newTexture.animationSpeedFactor = this.animationSpeedFactor;\r\n        newTexture.time = this.time;\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Creates a NoiseProceduralTexture from parsed noise procedural texture data\r\n     * @param parsedTexture defines parsed texture data\r\n     * @param scene defines the current scene\r\n     * @returns a parsed NoiseProceduralTexture\r\n     */\r\n    public static override Parse(parsedTexture: any, scene: Scene): NoiseProceduralTexture {\r\n        const texture = new NoiseProceduralTexture(parsedTexture.name, parsedTexture.size, scene, undefined, parsedTexture.generateMipMaps);\r\n\r\n        texture.brightness = parsedTexture.brightness;\r\n        texture.octaves = parsedTexture.octaves;\r\n        texture.persistence = parsedTexture.persistence;\r\n        texture.animationSpeedFactor = parsedTexture.animationSpeedFactor;\r\n        texture.time = parsedTexture.time ?? 0;\r\n\r\n        return texture;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for noiseProceduralTexture.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNoiseProceduralTexture(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    void _EnsureNoiseProceduralTextureShaderAsync();\r\n    RegisterClass(\"BABYLON.NoiseProceduralTexture\", NoiseProceduralTexture);\r\n}\r\n","import { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { _UpdateRGBDAsync as UpdateRGBDAsyncEnvTools } from \"../../Misc/environmentTextureTools.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type SphericalPolynomial } from \"../../Maths/sphericalPolynomial\";\r\nimport { InternalTextureSource } from \"./internalTexture\";\r\nimport { CubeTexture } from \"./cubeTexture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\n\r\n/**\r\n * Raw cube texture where the raw buffers are passed in\r\n */\r\nexport class RawCubeTexture extends CubeTexture {\r\n    /**\r\n     * Creates a cube texture where the raw buffers are passed in.\r\n     * @param scene defines the scene the texture is attached to\r\n     * @param data defines the array of data to use to create each face\r\n     * @param size defines the size of the textures\r\n     * @param format defines the format of the data\r\n     * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_BYTE)\r\n     * @param generateMipMaps  defines if the engine should generate the mip levels\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)\r\n     * @param compression defines the compression used (null by default)\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        data: Nullable<ArrayBufferView[]>,\r\n        size: number,\r\n        format: number = Constants.TEXTUREFORMAT_RGBA,\r\n        type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        generateMipMaps: boolean = false,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n        compression: Nullable<string> = null\r\n    ) {\r\n        super(\"\", scene);\r\n\r\n        this._texture = scene.getEngine().createRawCubeTexture(data, size, format, type, generateMipMaps, invertY, samplingMode, compression);\r\n    }\r\n\r\n    /**\r\n     * Updates the raw cube texture.\r\n     * @param data defines the data to store\r\n     * @param format defines the data format\r\n     * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_BYTE by default)\r\n     * @param invertY defines if data must be stored with Y axis inverted\r\n     * @param compression defines the compression used (null by default)\r\n     */\r\n    public update(data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string> = null): void {\r\n        this._texture!.getEngine().updateRawCubeTexture(this._texture!, data, format, type, invertY, compression);\r\n    }\r\n\r\n    /**\r\n     * Updates a raw cube texture with RGBD encoded data.\r\n     * @param data defines the array of data [mipmap][face] to use to create each face\r\n     * @param sphericalPolynomial defines the spherical polynomial for irradiance\r\n     * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness\r\n     * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness\r\n     * @returns a promise that resolves when the operation is complete\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public updateRGBDAsync(data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial> = null, lodScale: number = 0.8, lodOffset: number = 0): Promise<void> {\r\n        // eslint-disable-next-line github/no-then\r\n        return UpdateRGBDAsyncEnvTools(this._texture!, data, sphericalPolynomial, lodScale, lodOffset).then(() => {});\r\n    }\r\n\r\n    /**\r\n     * Clones the raw cube texture.\r\n     * @returns a new cube texture\r\n     */\r\n    public override clone(): CubeTexture {\r\n        return SerializationHelper.Clone(() => {\r\n            const scene = this.getScene()!;\r\n            const internalTexture = this._texture!;\r\n\r\n            const texture = new RawCubeTexture(\r\n                scene,\r\n                internalTexture._bufferViewArray,\r\n                internalTexture.width,\r\n                internalTexture.format,\r\n                internalTexture.type,\r\n                internalTexture.generateMipMaps,\r\n                internalTexture.invertY,\r\n                internalTexture.samplingMode,\r\n                internalTexture._compression\r\n            );\r\n\r\n            if (internalTexture.source === InternalTextureSource.CubeRawRGBD) {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n                texture.updateRGBDAsync(\r\n                    internalTexture._bufferViewArrayArray!,\r\n                    internalTexture._sphericalPolynomial,\r\n                    internalTexture._lodGenerationScale,\r\n                    internalTexture._lodGenerationOffset\r\n                );\r\n            }\r\n\r\n            return texture;\r\n        }, this);\r\n    }\r\n}\r\n","import { type ImageSource } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { _IsSideEffectImplemented, _WarnImport } from \"../../Misc/devTools\";\r\nimport { RawTexture2DArray } from \"./rawTexture2DArray\";\r\n\r\n/**\r\n * These helpers populate 2D array texture layers from decoded image sources.\r\n * They rely on the AbstractEngine.updateTextureArrayLayerFromImageSource engine extension. The full\r\n * Engine build registers it for both backends at load time. On the side-effect-free (pure /\r\n * tree-shaken) path it is opt-in: import the matching module for your backend before use:\r\n * - WebGL2:  import \"core/Engines/Extensions/engine.texture2DArrayImageSource\";\r\n * - WebGPU:  import \"core/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource\";\r\n *\r\n * Consuming the result: the built-in way to sample a chosen layer is Node Material's Texture block,\r\n * which exposes a `layer` input (feed it a Float) and samples the array at that layer for you — no\r\n * custom shader code required. If you instead write your own shader, declare a `sampler2DArray`\r\n * (GLSL) / `texture_2d_array<f32>` (WGSL) uniform and sample it with an explicit integer layer index;\r\n * the classic StandardMaterial / PBRMaterial texture slots are plain 2D and cannot read an array layer.\r\n */\r\n\r\n/**\r\n * Options controlling how an image source is uploaded into a 2D array texture layer.\r\n */\r\nexport interface IUploadImageToTexture2DArrayLayerOptions {\r\n    /** Defines if the source must be stored with the Y axis inverted (false by default) */\r\n    invertY?: boolean;\r\n    /** Defines if the source alpha must be premultiplied (false by default) */\r\n    premultiplyAlpha?: boolean;\r\n}\r\n\r\n/**\r\n * Options controlling the creation of a 2D array texture from a list of image urls.\r\n */\r\nexport interface ICreateTexture2DArrayFromImageUrlsOptions extends IUploadImageToTexture2DArrayLayerOptions {\r\n    /** Defines if mip levels should be generated (true by default) */\r\n    generateMipMaps?: boolean;\r\n    /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */\r\n    samplingMode?: number;\r\n    /** Defines the texture type (Constants.TEXTURETYPE_UNSIGNED_BYTE by default) */\r\n    textureType?: number;\r\n    /** Options forwarded to createImageBitmap when decoding each url */\r\n    imageBitmapOptions?: ImageBitmapOptions;\r\n}\r\n\r\n/**\r\n * Uploads a decoded image source (ImageBitmap, canvas, video, image element...) into a single layer of a 2D array texture.\r\n * This is the image-source counterpart to RawTexture2DArray.update, which only accepts raw bytes.\r\n * @param texture defines the 2D array texture to upload into\r\n * @param source defines the image source to upload\r\n * @param layer defines the array layer to upload into\r\n * @param options defines optional upload settings (invertY, premultiplyAlpha)\r\n */\r\nexport function UploadImageToTexture2DArrayLayer(texture: RawTexture2DArray, source: ImageSource, layer: number, options?: IUploadImageToTexture2DArrayLayerOptions): void {\r\n    const internalTexture = texture.getInternalTexture();\r\n    if (!internalTexture) {\r\n        throw new Error(\"Cannot upload to a 2D array texture that has no internal texture.\");\r\n    }\r\n\r\n    if (!Number.isInteger(layer) || layer < 0 || layer >= texture.depth) {\r\n        throw new Error(`Layer ${layer} is out of range for a 2D array texture with ${texture.depth} layers.`);\r\n    }\r\n\r\n    const scene = texture.getScene();\r\n    if (!scene) {\r\n        throw new Error(\"Cannot upload to a 2D array texture that is not attached to a scene.\");\r\n    }\r\n\r\n    const engine = scene.getEngine();\r\n    // updateTextureArrayLayerFromImageSource is an opt-in engine extension. When the consumer never\r\n    // imported it, the augmented method is missing, so fail early with the standard side-effect import\r\n    // message (matching the engine.rawTexture family) instead of a generic \"is not a function\" error.\r\n    if (!_IsSideEffectImplemented(engine.updateTextureArrayLayerFromImageSource)) {\r\n        throw _WarnImport(\"engine.texture2DArrayImageSource\");\r\n    }\r\n\r\n    engine.updateTextureArrayLayerFromImageSource(internalTexture, source, layer, options?.invertY ?? false, options?.premultiplyAlpha ?? false);\r\n}\r\n\r\n/**\r\n * Fetches an image from a url, decodes it and uploads it into a single layer of a 2D array texture.\r\n * @param texture defines the 2D array texture to upload into\r\n * @param url defines the url of the image to load\r\n * @param layer defines the array layer to upload into\r\n * @param options defines optional upload settings (invertY, premultiplyAlpha)\r\n * @returns a promise resolved once the layer has been uploaded\r\n */\r\nexport async function LoadImageToTexture2DArrayLayerAsync(\r\n    texture: RawTexture2DArray,\r\n    url: string,\r\n    layer: number,\r\n    options?: IUploadImageToTexture2DArrayLayerOptions\r\n): Promise<void> {\r\n    const response = await fetch(url);\r\n    if (!response.ok) {\r\n        throw new Error(`Failed to fetch image \"${url}\": ${response.status} ${response.statusText}`);\r\n    }\r\n    const blob = await response.blob();\r\n    const bitmap = await createImageBitmap(blob);\r\n    try {\r\n        UploadImageToTexture2DArrayLayer(texture, bitmap, layer, options);\r\n    } finally {\r\n        bitmap.close();\r\n    }\r\n}\r\n\r\n/**\r\n * Options controlling the creation of a 2D array texture from a KTX2 file.\r\n */\r\nexport interface ICreateTexture2DArrayFromKTX2Options {\r\n    /** Defines if mip levels should be generated (true by default) */\r\n    generateMipMaps?: boolean;\r\n    /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */\r\n    samplingMode?: number;\r\n    /** Defines if the texture must be stored with the Y axis inverted (false by default) */\r\n    invertY?: boolean;\r\n}\r\n\r\n/**\r\n * Creates a 2D array texture from a single KTX2 file holding several array layers (layerCount greater than 1).\r\n * This is the single-file counterpart to CreateTexture2DArrayFromImageUrlsAsync: rather than fetching one image\r\n * per layer, the whole array travels in one container.\r\n *\r\n * The data is transcoded to uncompressed RGBA. Keeping the texture in its transcoded compressed form would\r\n * require compressedTexImage3D support in the engine raw texture path, which does not exist yet, so the\r\n * GPU cost here matches a plain RGBA array texture.\r\n *\r\n * Only the base mip level stored in the file is uploaded; when generateMipMaps is on, the remaining levels are\r\n * regenerated by the engine. Uploading the file's own mip chain needs per-mip array uploads, which WebGL's\r\n * updateRawTexture2DArray does not support today.\r\n * @param scene defines the hosting scene\r\n * @param data defines the url of the KTX2 file, or its already fetched content\r\n * @param options defines optional creation settings\r\n * @returns a promise resolved with the created RawTexture2DArray\r\n */\r\nexport async function CreateTexture2DArrayFromKTX2Async(scene: Scene, data: string | ArrayBufferView, options?: ICreateTexture2DArrayFromKTX2Options): Promise<RawTexture2DArray> {\r\n    let buffer: ArrayBufferView;\r\n    if (typeof data === \"string\") {\r\n        const response = await fetch(data);\r\n        if (!response.ok) {\r\n            throw new Error(`Failed to fetch KTX2 file \"${data}\": ${response.status} ${response.statusText}`);\r\n        }\r\n        buffer = new Uint8Array(await response.arrayBuffer());\r\n    } else {\r\n        buffer = data;\r\n    }\r\n\r\n    const { KhronosTextureContainer2 } = await import(\"../../Misc/khronosTextureContainer2\");\r\n\r\n    if (!KhronosTextureContainer2.IsValid(buffer)) {\r\n        throw new Error(\"The provided data is not a valid KTX2 file.\");\r\n    }\r\n\r\n    const container = new KhronosTextureContainer2(scene.getEngine());\r\n\r\n    // forceRGBA: the transcoded compressed formats cannot be uploaded to an array texture yet (see above).\r\n    const decodedData = await container._decodeAsync(buffer, { forceRGBA: true });\r\n\r\n    if (decodedData.errors) {\r\n        throw new Error(\"Failed to decode the KTX2 file. \" + decodedData.errors);\r\n    }\r\n\r\n    const layerCount = Math.max(decodedData.layerCount ?? 1, 1);\r\n    // mipmaps are ordered level by level, and within a level layer by layer, so the base level occupies\r\n    // the first layerCount entries and its layers are already in ascending order.\r\n    const baseLevel = decodedData.mipmaps.slice(0, layerCount);\r\n\r\n    if (baseLevel.length !== layerCount) {\r\n        throw new Error(`Failed to decode the KTX2 file: expected ${layerCount} layers for the base mip level but got ${baseLevel.length}.`);\r\n    }\r\n\r\n    // Every layer of a level shares the level's dimensions, and forceRGBA above means each one must be exactly\r\n    // width * height * 4 bytes. RawTexture2DArray takes all the layers as one flat buffer and cannot detect a\r\n    // short or mismatched layer, so validate here rather than uploading malformed data.\r\n    const { width, height } = baseLevel[0];\r\n    const expectedLayerByteLength = width * height * 4;\r\n\r\n    for (const mipmap of baseLevel) {\r\n        if (!mipmap.data) {\r\n            throw new Error(`Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level is empty.`);\r\n        }\r\n        if (mipmap.width !== width || mipmap.height !== height) {\r\n            throw new Error(\r\n                `Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level is ${mipmap.width}x${mipmap.height} but layer 0 is ${width}x${height}.`\r\n            );\r\n        }\r\n        if (mipmap.data.byteLength !== expectedLayerByteLength) {\r\n            throw new Error(\r\n                `Failed to decode the KTX2 file: layer ${mipmap.layerIndex} of the base mip level holds ${mipmap.data.byteLength} bytes but ${expectedLayerByteLength} were expected.`\r\n            );\r\n        }\r\n    }\r\n\r\n    // A 2D array texture is uploaded as a single buffer holding every layer back to back.\r\n    const textureData = new Uint8Array(expectedLayerByteLength * layerCount);\r\n    let byteOffset = 0;\r\n    for (const mipmap of baseLevel) {\r\n        textureData.set(mipmap.data!, byteOffset);\r\n        byteOffset += mipmap.data!.byteLength;\r\n    }\r\n\r\n    return new RawTexture2DArray(\r\n        textureData,\r\n        width,\r\n        height,\r\n        layerCount,\r\n        Constants.TEXTUREFORMAT_RGBA,\r\n        scene,\r\n        options?.generateMipMaps ?? true,\r\n        options?.invertY ?? false,\r\n        options?.samplingMode,\r\n        Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    );\r\n}\r\n\r\n/**\r\n * Creates a 2D array texture and fills each layer from a list of image urls.\r\n * All images must share the same dimensions.\r\n * @param scene defines the hosting scene\r\n * @param urls defines the url of the image for each layer (at least one)\r\n * @param options defines optional creation and upload settings\r\n * @returns a promise resolved with the created RawTexture2DArray\r\n */\r\nexport async function CreateTexture2DArrayFromImageUrlsAsync(\r\n    scene: Scene,\r\n    urls: readonly [string, ...string[]],\r\n    options?: ICreateTexture2DArrayFromImageUrlsOptions\r\n): Promise<RawTexture2DArray> {\r\n    // allSettled (not all): a rejected fetch/decode must not leak the layers that\r\n    // already decoded. Promise.all rejects on the first failure and never enters the\r\n    // try/finally below, orphaning every ImageBitmap that resolved. Close the\r\n    // fulfilled ones here, then rethrow the original failure.\r\n    const results = await Promise.allSettled(\r\n        urls.map(async (url) => {\r\n            const response = await fetch(url);\r\n            if (!response.ok) {\r\n                throw new Error(`Failed to fetch image \"${url}\": ${response.status} ${response.statusText}`);\r\n            }\r\n            return await createImageBitmap(await response.blob(), options?.imageBitmapOptions);\r\n        })\r\n    );\r\n\r\n    const firstRejection = results.find((result): result is PromiseRejectedResult => result.status === \"rejected\");\r\n    if (firstRejection) {\r\n        for (const result of results) {\r\n            if (result.status === \"fulfilled\") {\r\n                result.value.close();\r\n            }\r\n        }\r\n        throw firstRejection.reason;\r\n    }\r\n\r\n    const bitmaps = results.filter((result): result is PromiseFulfilledResult<ImageBitmap> => result.status === \"fulfilled\").map((result) => result.value) as [\r\n        ImageBitmap,\r\n        ...ImageBitmap[],\r\n    ];\r\n\r\n    try {\r\n        const width = bitmaps[0].width;\r\n        const height = bitmaps[0].height;\r\n\r\n        for (let index = 1; index < bitmaps.length; index++) {\r\n            const bitmap = bitmaps[index];\r\n            if (bitmap.width !== width || bitmap.height !== height) {\r\n                throw new Error(`All images must share the same dimensions. Image at index ${index} is ${bitmap.width}x${bitmap.height}, expected ${width}x${height}.`);\r\n            }\r\n        }\r\n\r\n        const texture = new RawTexture2DArray(\r\n            null,\r\n            width,\r\n            height,\r\n            bitmaps.length,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            scene,\r\n            options?.generateMipMaps ?? true,\r\n            options?.invertY ?? false,\r\n            options?.samplingMode,\r\n            options?.textureType\r\n        );\r\n\r\n        try {\r\n            const uploadOptions: IUploadImageToTexture2DArrayLayerOptions = {\r\n                invertY: options?.invertY ?? false,\r\n                premultiplyAlpha: options?.premultiplyAlpha ?? false,\r\n            };\r\n\r\n            // updateTextureArrayLayerFromImageSource rebuilds the whole mip chain on each upload when mips\r\n            // are enabled. Uploading N layers that way is O(N) redundant mip generation, so suppress it\r\n            // per-layer and let only the final upload regenerate the mips once — a single generateMipmap\r\n            // covers every layer of the array.\r\n            const internalTexture = texture.getInternalTexture();\r\n            const generateMipMaps = internalTexture?.generateMipMaps ?? false;\r\n            if (internalTexture && generateMipMaps) {\r\n                internalTexture.generateMipMaps = false;\r\n            }\r\n\r\n            for (let layer = 0; layer < bitmaps.length; layer++) {\r\n                if (internalTexture && generateMipMaps && layer === bitmaps.length - 1) {\r\n                    internalTexture.generateMipMaps = true;\r\n                }\r\n                UploadImageToTexture2DArrayLayer(texture, bitmaps[layer], layer, uploadOptions);\r\n            }\r\n\r\n            return texture;\r\n        } catch (error) {\r\n            // A layer upload can throw (out-of-range layer, missing engine extension, backend upload\r\n            // failure). Dispose the freshly allocated GPU texture so it does not leak, then rethrow.\r\n            texture.dispose();\r\n            throw error;\r\n        }\r\n    } finally {\r\n        for (let index = 0; index < bitmaps.length; index++) {\r\n            bitmaps[index].close();\r\n        }\r\n    }\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { Texture } from \"./texture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { type Nullable } from \"../../types\";\r\n/**\r\n * Class used to store 3D textures containing user data\r\n */\r\nexport class RawTexture3D extends Texture {\r\n    /**\r\n     * Gets the width of the texture\r\n     */\r\n    public get width(): number {\r\n        return this._texture ? this._texture.width : 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the height of the texture\r\n     */\r\n    public get height(): number {\r\n        return this._texture ? this._texture.height : 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the depth of the texture\r\n     */\r\n    public get depth(): number {\r\n        return this._texture ? this._texture.depth : 0;\r\n    }\r\n\r\n    /**\r\n     * Create a new RawTexture3D\r\n     * @param data defines the data of the texture\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     * @param depth defines the depth of the texture\r\n     * @param format defines the texture format to use\r\n     * @param scene defines the hosting scene\r\n     * @param generateMipMaps defines a boolean indicating if mip levels should be generated (true by default)\r\n     * @param invertY defines if texture must be stored with Y axis inverted\r\n     * @param samplingMode defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default)\r\n     * @param textureType defines the texture Type (Engine.TEXTURETYPE_UNSIGNED_BYTE, Engine.TEXTURETYPE_FLOAT...)\r\n     * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n     */\r\n    constructor(\r\n        data: Nullable<ArrayBufferView>,\r\n        width: number,\r\n        height: number,\r\n        depth: number,\r\n        /** Gets or sets the texture format to use */\r\n        public format: number,\r\n        scene: Scene,\r\n        generateMipMaps: boolean = true,\r\n        invertY: boolean = false,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        creationFlags?: number\r\n    ) {\r\n        super(null, scene, !generateMipMaps, invertY);\r\n\r\n        this._texture = scene.getEngine().createRawTexture3D(data, width, height, depth, format, generateMipMaps, invertY, samplingMode, null, textureType, creationFlags);\r\n\r\n        this.is3D = true;\r\n    }\r\n\r\n    /**\r\n     * Update the texture with new data\r\n     * @param data defines the data to store in the texture\r\n     */\r\n    public update(data: ArrayBufferView): void {\r\n        if (!this._texture) {\r\n            return;\r\n        }\r\n        this._getEngine()!.updateRawTexture3D(this._texture, data, this._texture.format, this._texture.invertY, null, this._texture.type);\r\n    }\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { Plane } from \"../../Maths/math.plane\";\r\nimport { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\n/**\r\n * Creates a refraction texture used by refraction channel of the standard material.\r\n * It is like a mirror but to see through a material.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#refractiontexture\r\n */\r\nexport class RefractionTexture extends RenderTargetTexture {\r\n    /**\r\n     * Define the reflection plane we want to use. The refractionPlane is usually set to the constructed refractor.\r\n     * It is possible to directly set the refractionPlane by directly using a Plane(a, b, c, d) where a, b and c give the plane normal vector (a, b, c) and d is a scalar displacement from the refractionPlane to the origin. However in all but the very simplest of situations it is more straight forward to set it to the refractor as stated in the doc.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#refraction\r\n     */\r\n    public refractionPlane = new Plane(0, 1, 0, 1);\r\n\r\n    /**\r\n     * Define how deep under the surface we should see.\r\n     */\r\n    public depth = 2.0;\r\n\r\n    /**\r\n     * Creates a refraction texture used by refraction channel of the standard material.\r\n     * It is like a mirror but to see through a material.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#refraction\r\n     * @param name Define the texture name\r\n     * @param size Define the size of the underlying texture\r\n     * @param scene Define the scene the refraction belongs to\r\n     * @param generateMipMaps Define if we need to generate mips level for the refraction\r\n     */\r\n    constructor(name: string, size: number, scene?: Scene, generateMipMaps?: boolean) {\r\n        super(name, size, scene, generateMipMaps, true);\r\n\r\n        this.onBeforeRenderObservable.add(() => {\r\n            this.getScene()!.clipPlane = this.refractionPlane;\r\n        });\r\n\r\n        this.onAfterRenderObservable.add(() => {\r\n            this.getScene()!.clipPlane = null;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Clone the refraction texture.\r\n     * @returns the cloned texture\r\n     */\r\n    public override clone(): RefractionTexture {\r\n        const scene = this.getScene();\r\n\r\n        if (!scene) {\r\n            return this;\r\n        }\r\n\r\n        const textureSize = this.getSize();\r\n        const newTexture = new RefractionTexture(this.name, textureSize.width, scene, this._generateMipMaps);\r\n\r\n        // Base texture\r\n        newTexture.hasAlpha = this.hasAlpha;\r\n        newTexture.level = this.level;\r\n\r\n        // Refraction Texture\r\n        newTexture.refractionPlane = this.refractionPlane.clone();\r\n        if (this.renderList) {\r\n            newTexture.renderList = this.renderList.slice(0);\r\n        }\r\n        newTexture.depth = this.depth;\r\n\r\n        return newTexture;\r\n    }\r\n\r\n    /**\r\n     * Serialize the texture to a JSON representation you could use in Parse later on\r\n     * @returns the serialized JSON representation\r\n     */\r\n    public override serialize(): any {\r\n        if (!this.name) {\r\n            return null;\r\n        }\r\n\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.mirrorPlane = this.refractionPlane.asArray();\r\n        serializationObject.depth = this.depth;\r\n\r\n        return serializationObject;\r\n    }\r\n}\r\n","import { type Scene } from \"../../scene\";\nimport { type IProceduralTextureCreationOptions } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\nimport { ProceduralTexture } from \"./Procedurals/proceduralTexture.pure\";\nimport { type BaseTexture } from \"./baseTexture\";\nimport { type TextureSize } from \"./textureCreationOptions\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { Constants } from \"../../Engines/constants\";\nimport { type Texture } from \"./texture\";\n\n/**\n * Configuration for a texture input source\n */\nexport interface ITextureChannelInput {\n    /** The texture to use as input */\n    texture: BaseTexture;\n    /** Source channel to read from (0=R, 1=G, 2=B, 3=A) */\n    sourceChannel: number;\n}\n\n/**\n * Configuration for a constant value input source\n */\nexport interface IConstantChannelInput {\n    /** Constant value between 0.0 and 1.0 */\n    value: number;\n}\n\n/**\n * Union type for channel input sources\n */\nexport type ChannelInput = ITextureChannelInput | IConstantChannelInput;\n\n/**\n * Configuration for texture merging operation\n */\nexport interface ITextureMergeConfiguration {\n    /** Configuration for red output channel */\n    red: ChannelInput;\n    /** Configuration for green output channel (optional, defaults to 0) */\n    green?: ChannelInput;\n    /** Configuration for blue output channel (optional, defaults to 0) */\n    blue?: ChannelInput;\n    /** Configuration for alpha output channel (optional, defaults to 1) */\n    alpha?: ChannelInput;\n    /** Output texture size. If not specified, uses the largest input texture size */\n    outputSize?: TextureSize;\n    /** Whether to generate mipmaps for the output texture */\n    generateMipMaps?: boolean;\n}\n\nconst _ShaderName = \"textureMerger\";\n\n/**\n * @internal\n * Check if a channel input is a texture input\n * @param input The channel input to check\n * @returns True if the input is a texture input, false otherwise\n */\nfunction IsTextureInput(input: ChannelInput): input is ITextureChannelInput {\n    return \"texture\" in input;\n}\n\n/**\n * @internal\n * Check if a channel input is a constant input\n * @param input The channel input to check\n * @returns True if the input is a constant input, false otherwise\n */\nfunction IsConstantInput(input: ChannelInput): input is IConstantChannelInput {\n    return \"value\" in input;\n}\n\n/**\n * @internal\n * Copy texture transformation properties from one texture to another\n * @param source The source texture\n * @param destination The destination texture\n */\nfunction CopyTextureTransform(source: Texture, destination: Texture) {\n    destination.uOffset = source.uOffset;\n    destination.vOffset = source.vOffset;\n    destination.uScale = source.uScale;\n    destination.vScale = source.vScale;\n    destination.uAng = source.uAng;\n    destination.vAng = source.vAng;\n    destination.wAng = source.wAng;\n    destination.uRotationCenter = source.uRotationCenter;\n    destination.vRotationCenter = source.vRotationCenter;\n}\n\n/**\n * @internal\n * Merge multiple texture channels into a single texture\n * @param name Name for the resulting texture\n * @param config Merge configuration\n * @param scene Scene to create the texture in\n * @returns The merged texture\n */\nexport async function MergeTexturesAsync(name: string, config: ITextureMergeConfiguration, scene: Scene): Promise<ProceduralTexture> {\n    const channels = [config.red, config.green, config.blue, config.alpha];\n    const textureInputs: BaseTexture[] = [];\n    const textureInputMap: number[] = []; // Maps channel index to texture input index (-1 for constants)\n\n    // Collect unique textures and validate inputs\n    for (let channelIndex = 0; channelIndex < 4; channelIndex++) {\n        const channel = channels[channelIndex];\n        if (channel) {\n            if (IsTextureInput(channel)) {\n                // Validate source channel\n                if (channel.sourceChannel < 0 || channel.sourceChannel > 3) {\n                    throw new Error(\"Source channel must be between 0 and 3 (R, G, B, A)\");\n                }\n\n                // Find or add texture to inputs\n                let textureIndex = textureInputs.indexOf(channel.texture);\n                if (textureIndex === -1) {\n                    textureIndex = textureInputs.length;\n                    textureInputs.push(channel.texture);\n                }\n                textureInputMap[channelIndex] = textureIndex;\n            } else if (IsConstantInput(channel)) {\n                // Validate constant value\n                if (channel.value < 0 || channel.value > 1) {\n                    throw new Error(\"Constant value must be between 0.0 and 1.0\");\n                }\n                textureInputMap[channelIndex] = -1;\n            } else {\n                throw new Error(\"Invalid channel input configuration\");\n            }\n        } else {\n            textureInputMap[channelIndex] = -1;\n        }\n    }\n\n    // Determine output size\n    let outputSize = config.outputSize;\n    if (!outputSize && textureInputs.length > 0) {\n        // Use the largest texture size\n        let maxSize = 0;\n        for (const texture of textureInputs) {\n            const size = texture.getSize();\n            const currentSize = Math.max(size.width, size.height);\n            if (currentSize > maxSize) {\n                maxSize = currentSize;\n                outputSize = size.width === size.height ? maxSize : size;\n            }\n        }\n    }\n    outputSize = outputSize || 512; // Fallback size\n\n    // Generate shader defines\n    const defines: string[] = [];\n    const usedTextures = new Set<number>();\n\n    for (let channelIndex = 0; channelIndex < 4; channelIndex++) {\n        const channel = channels[channelIndex];\n        const channelName = [\"RED\", \"GREEN\", \"BLUE\", \"ALPHA\"][channelIndex];\n\n        if (channel && IsTextureInput(channel)) {\n            defines.push(`${channelName}_FROM_TEXTURE`);\n            const textureIndex = textureInputMap[channelIndex];\n            usedTextures.add(textureIndex);\n        }\n    }\n\n    // Add texture defines for used textures\n    usedTextures.forEach((textureIndex) => {\n        defines.push(`USE_TEXTURE${textureIndex}`);\n    });\n\n    // Create the procedural texture\n    const outputTextureOptions: IProceduralTextureCreationOptions = {\n        type: Constants.TEXTURETYPE_HALF_FLOAT,\n        format: Constants.TEXTUREFORMAT_RGBA,\n        samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n        generateDepthBuffer: false,\n        generateMipMaps: false,\n        shaderLanguage: scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n        extraInitializationsAsync: async () => {\n            if (scene.getEngine().isWebGPU) {\n                await Promise.all([import(\"../../ShadersWGSL/textureMerger.fragment\")]);\n            } else {\n                await Promise.all([import(\"../../Shaders/textureMerger.fragment\")]);\n            }\n        },\n        skipSceneRegistration: true,\n    };\n    const proceduralTexture = new ProceduralTexture(name, outputSize, _ShaderName, scene, outputTextureOptions);\n    proceduralTexture.refreshRate = -1; // Do not auto-refresh\n\n    // Set the defines\n    proceduralTexture.defines = defines.length > 0 ? \"#define \" + defines.join(\"\\n#define \") + \"\\n\" : \"\";\n\n    // Set up texture inputs\n    for (let i = 0; i < textureInputs.length; i++) {\n        CopyTextureTransform(textureInputs[i] as Texture, proceduralTexture);\n        proceduralTexture.setTexture(`inputTexture${i}`, textureInputs[i]);\n    }\n\n    // Set up channel configuration\n    for (let channelIndex = 0; channelIndex < 4; channelIndex++) {\n        const channel = channels[channelIndex];\n        const channelName = [\"red\", \"green\", \"blue\", \"alpha\"][channelIndex];\n\n        if (channel && IsTextureInput(channel)) {\n            const textureIndex = textureInputMap[channelIndex];\n            proceduralTexture.setInt(`${channelName}TextureIndex`, textureIndex);\n            proceduralTexture.setInt(`${channelName}SourceChannel`, channel.sourceChannel);\n        } else {\n            // Use constant value (either provided or default)\n            let constantValue: number;\n            if (channel && IsConstantInput(channel)) {\n                constantValue = channel.value;\n            } else {\n                // Use default values: 0 for RGB, 1 for alpha\n                constantValue = channelIndex === 3 ? 1.0 : 0.0;\n            }\n            proceduralTexture.setFloat(`${channelName}ConstantValue`, constantValue);\n        }\n    }\n\n    return await new Promise<ProceduralTexture>((resolve, reject) => {\n        // Compile and render\n        proceduralTexture.executeWhenReady(() => {\n            try {\n                proceduralTexture.render();\n                resolve(proceduralTexture);\n            } catch (error) {\n                reject(error instanceof Error ? error : new Error(String(error)));\n            }\n        });\n    });\n}\n\n/**\n * @internal\n * Create a texture input configuration\n * @param texture The texture to read from\n * @param sourceChannel The channel to read (0=R, 1=G, 2=B, 3=A)\n * @returns Texture channel input configuration\n */\nexport function CreateTextureInput(texture: BaseTexture, sourceChannel: number): ITextureChannelInput {\n    return { texture, sourceChannel };\n}\n\n/**\n * @internal\n * Create a constant value input configuration\n * @param value The constant value (0.0-1.0)\n * @returns Constant channel input configuration\n */\nexport function CreateConstantInput(value: number): IConstantChannelInput {\n    return { value };\n}\n\n/**\n * @internal\n * Create a simple RGBA channel packing configuration\n * @param red Input for red channel\n * @param green Input for green channel (optional, defaults to 0)\n * @param blue Input for blue channel (optional, defaults to 0)\n * @param alpha Input for alpha channel (optional, defaults to 1)\n * @returns Texture merge configuration\n */\nexport function CreateRGBAConfiguration(red: ChannelInput, green?: ChannelInput, blue?: ChannelInput, alpha?: ChannelInput): ITextureMergeConfiguration {\n    return { red, green, blue, alpha };\n}\n","import { type Scene } from \"../../scene\";\nimport { type IProceduralTextureCreationOptions } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\nimport { ProceduralTexture } from \"./Procedurals/proceduralTexture.pure\";\nimport { type BaseTexture } from \"./baseTexture\";\nimport { type Nullable } from \"../../types\";\nimport { type Texture } from \"./texture\";\nimport { type TextureSize } from \"./textureCreationOptions\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { Constants } from \"../../Engines/constants\";\nimport { Color4 } from \"core/Maths/math.color.pure\";\n\nconst _ShaderName = \"textureProcessor\";\n\n/**\n * Specifies the color space of a texture operand.\n * When `sRGB` is set the sampled RGB values are converted to linear space before any channel\n * swizzle, factor multiplication, or arithmetic operation. Alpha is always treated as linear.\n */\nexport enum TextureColorSpace {\n    /** Texture data is already in linear space (default). No conversion applied. */\n    Linear = 0,\n    /** Texture data is in sRGB (gamma) space. RGB channels are linearized (IEC 61966-2-1) before use. */\n    SRGB = 1,\n}\n\n/**\n * Bitmask controlling which channels are written to the output texture by a processing operation.\n * Channels excluded from the mask receive a sensible default: `0.0` for RGB channels, `1.0` for alpha.\n * Use `ChannelMask.RGBA` (or omit the parameter) to pass all channels through unchanged.\n *\n * | Flag | Channels written | Excluded channels |\n * |------|-----------------|-------------------|\n * | R    | red             | G=0, B=0, A=1     |\n * | G    | green           | R=0, B=0, A=1     |\n * | B    | blue            | R=0, G=0, A=1     |\n * | A    | alpha           | R=0, G=0, B=0     |\n * | RGB  | red, green, blue | A=1              |\n * | RGBA | all four        | (none)            |\n */\nexport enum ChannelMask {\n    /** Pass only the red channel; G=0, B=0, A=1. */\n    R = 0x1,\n    /** Pass only the green channel; R=0, B=0, A=1. */\n    G = 0x2,\n    /** Pass only the blue channel; R=0, G=0, A=1. */\n    B = 0x4,\n    /** Pass only the alpha channel; R=0, G=0, B=0. */\n    A = 0x8,\n    /** Pass red, green, and blue; alpha is forced to 1.0. */\n    RGB = 0x7,\n    /** Pass all four channels unchanged (default — no masking). */\n    RGBA = 0xf,\n}\n\n/**\n * Specifies which channel of a texture to read for an operation.\n * When a single channel is selected its scalar value is broadcast to RGB; alpha\n * is either preserved from the original sample or replicated when `A` is chosen.\n *\n * | Value | Swizzle |\n * |-------|---------|\n * | RGBA  | (r, g, b, a) — no swizzle (default) |\n * | R     | (r, r, r, a) |\n * | G     | (g, g, g, a) |\n * | B     | (b, b, b, a) |\n * | A     | (a, a, a, a) |\n */\nexport enum TextureChannel {\n    /** Use all four channels as sampled (default). */\n    RGBA = 0,\n    /** Broadcast the red channel to RGB; preserve alpha: RRRA. */\n    R = 1,\n    /** Broadcast the green channel to RGB; preserve alpha: GGGA. */\n    G = 2,\n    /** Broadcast the blue channel to RGB; preserve alpha: BBBA. */\n    B = 3,\n    /** Broadcast the alpha channel to all four components: AAAA. */\n    A = 4,\n}\n\n/**\n * Represents an operand for a texture processing operation, or the result of one.\n *\n * As an operand, the value evaluates to a vec4 per texel:\n * - `texture` only → `sample(texture)`\n * - `factor` only → `factor` (constant)\n * - both → `sample(texture) * factor`\n *\n * As a result returned by a processing function:\n * - `texture` holds the GPU-processed output; `dispose()` releases it when no longer needed.\n * - `factor` holds a CPU-folded constant when all inputs were texture-free; no `dispose` is set.\n *\n * Results are directly usable as operands to subsequent operations. When a result with a\n * `dispose` function is passed as an operand, the next operation automatically calls `dispose`\n * after consuming it, so intermediate textures are cleaned up without manual tracking.\n *\n * At least one of `texture` or `factor` must be provided when used as an operand.\n */\nexport interface ITextureProcessOperand {\n    /**\n     * Texture to sample. When combined with `factor`, the sampled value is multiplied\n     * component-wise by the factor. Null when the operand or result is a constant.\n     */\n    texture: Nullable<BaseTexture>;\n    /**\n     * Optional constant RGBA factor. If `texture` is also set, the sampled value is\n     * multiplied by this factor. If `texture` is not set, this becomes the constant output.\n     * When omitted and `texture` is set, defaults to (1, 1, 1, 1) — no scaling.\n     */\n    factor?: Color4;\n    /**\n     * Optional channel selection applied to the sampled texture value before any factor\n     * multiplication. When omitted or set to `TextureChannel.RGBA`, the sample is used\n     * as-is. When set to a single channel, that channel's scalar is broadcast to RGB\n     * (or all four components for `TextureChannel.A`). Only meaningful when `texture` is set.\n     */\n    channel?: TextureChannel;\n\n    /**\n     * Color space of the texture data. When set to `TextureColorSpace.SRGB`, the sampled\n     * RGB channels are converted from sRGB to linear space (IEC 61966-2-1) before the channel\n     * swizzle, factor multiplication, and any arithmetic operation. Alpha is always linear.\n     * Defaults to `TextureColorSpace.Linear` (no conversion). Only meaningful when `texture` is set.\n     */\n    colorSpace?: TextureColorSpace;\n\n    /**\n     * Disposes the texture produced by a processing operation. Only present on results\n     * returned by the texture processing functions. When a result is passed as an operand\n     * to the next operation in a chain, its `dispose` is called automatically after the\n     * GPU pass completes. Call `dispose` explicitly on the final result when the texture\n     * is no longer needed (or skip it if transferring ownership to a material).\n     */\n    dispose?: () => void;\n}\n\n/**\n * Controls the GPU texture created by a texture processing operation.\n */\nexport interface ITextureProcessorOutputOptions {\n    /**\n     * Texture type used by the render target. Defaults to `Constants.TEXTURETYPE_UNSIGNED_BYTE`.\n     */\n    textureType?: number;\n    /**\n     * Sampling mode used by the output texture. Defaults to `Constants.TEXTURE_BILINEAR_SAMPLINGMODE`.\n     */\n    samplingMode?: number;\n    /**\n     * Whether mipmaps are generated for the output texture. Defaults to `false`.\n     */\n    generateMipMaps?: boolean;\n}\n\n/**\n * Create an operand from a texture alone (no constant factor scaling).\n * @param texture - The texture to sample, or null to produce an identity (1,1,1,1) constant operand\n * @param channel - Optional channel selection. When set, the sampled value is swizzled before use\n *   (e.g. `TextureChannel.R` → RRRA). Defaults to `TextureChannel.RGBA` (no swizzle).\n * @param colorSpace - Optional color space. When `TextureColorSpace.SRGB`, the sampled RGB channels\n *   are linearized before use. Defaults to `TextureColorSpace.Linear`.\n * @returns An operand that evaluates to the sampled texture value\n */\nexport function CreateTextureOperand(texture: Nullable<BaseTexture>, channel?: TextureChannel, colorSpace?: TextureColorSpace): ITextureProcessOperand {\n    const op: ITextureProcessOperand = { texture };\n    if (channel) {\n        op.channel = channel;\n    }\n    if (colorSpace) {\n        op.colorSpace = colorSpace;\n    }\n    return op;\n}\n\n/**\n * Create an operand from a constant RGBA factor with no texture.\n * @param factor - The constant RGBA value\n * @returns An operand that evaluates to the constant factor\n */\nexport function CreateFactorOperand(factor: Color4): ITextureProcessOperand {\n    return { texture: null, factor };\n}\n\n/**\n * Create an operand from a texture multiplied by a constant RGBA factor.\n * This is the standard glTF pattern (e.g. baseColorTexture * baseColorFactor).\n * If `texture` is null, returns a factor-only operand.\n * @param texture - The texture to sample, or null to use the factor alone\n * @param factor - The constant factor to multiply by\n * @param channel - Optional channel selection. When set, the sampled value is swizzled before\n *   factor multiplication (e.g. `TextureChannel.G` → GGGA, then multiplied by factor).\n *   Defaults to `TextureChannel.RGBA` (no swizzle).\n * @param colorSpace - Optional color space. When `TextureColorSpace.SRGB`, the sampled RGB channels\n *   are linearized before factor multiplication. Defaults to `TextureColorSpace.Linear`.\n * @returns An operand that evaluates to `sample(texture) * factor`, or `factor` if texture is null\n */\nexport function CreateTextureWithFactorOperand(texture: Nullable<BaseTexture>, factor: Color4, channel?: TextureChannel, colorSpace?: TextureColorSpace): ITextureProcessOperand {\n    const op: ITextureProcessOperand = { texture, factor };\n    if (channel) {\n        op.channel = channel;\n    }\n    if (colorSpace) {\n        op.colorSpace = colorSpace;\n    }\n    return op;\n}\n\n/**\n * @internal\n * Evaluate the effective constant Color4 of an operand.\n * When a texture-only operand omits factor, the implicit value is (1, 1, 1, 1).\n */\nfunction _EvalConstant(op: ITextureProcessOperand): Color4 {\n    return op.factor ?? new Color4(1, 1, 1, 1);\n}\n\n/** @internal */\nfunction _MultiplyConstants(a: Color4, b: Color4): Color4 {\n    return new Color4(a.r * b.r, a.g * b.g, a.b * b.b, a.a * b.a);\n}\n\n/** @internal */\nfunction _MaxConstants(a: Color4, b: Color4): Color4 {\n    return new Color4(Math.max(a.r, b.r), Math.max(a.g, b.g), Math.max(a.b, b.b), Math.max(a.a, b.a));\n}\n\n/** @internal */\nfunction _LerpConstants(a: Color4, b: Color4, t: Color4): Color4 {\n    return new Color4(a.r + (b.r - a.r) * t.r, a.g + (b.g - a.g) * t.g, a.b + (b.b - a.b) * t.b, a.a + (b.a - a.a) * t.a);\n}\n\n/**\n * @internal\n * Determine the output texture size from a list of operands, using the largest input texture.\n */\nfunction _ResolveOutputSize(operands: ITextureProcessOperand[]): TextureSize {\n    let maxDim = 0;\n    let result: TextureSize = 512;\n    for (const op of operands) {\n        if (op.texture) {\n            const size = op.texture.getSize();\n            const dim = Math.max(size.width, size.height);\n            if (dim > maxDim) {\n                maxDim = dim;\n                result = size.width === size.height ? dim : size;\n            }\n        }\n    }\n    return result;\n}\n\n/**\n * @internal\n * Returns true when the texture has a non-identity UV transform (offset, scale, or rotation).\n */\nfunction _HasNonIdentityTransform(texture: BaseTexture): boolean {\n    return !texture.getTextureMatrix().isIdentity();\n}\n\n/**\n * @internal\n * Returns true when every texture in the list shares the same UV transform matrix.\n * A single texture (or empty list) trivially satisfies this.\n */\nfunction _AllTransformsMatch(textures: BaseTexture[]): boolean {\n    if (textures.length <= 1) {\n        return true;\n    }\n    const ref = textures[0].getTextureMatrix();\n    for (let i = 1; i < textures.length; i++) {\n        if (!ref.equals(textures[i].getTextureMatrix())) {\n            return false;\n        }\n    }\n    return true;\n}\n\n/**\n * @internal\n * Copy sampling metadata from a source texture onto the output ProceduralTexture.\n * `coordinatesIndex` and wrap modes are always copied.\n * When `includeTransform` is true the UV offset/scale/rotation are also copied\n * (used when all inputs share the same transform and it is propagated rather than baked).\n */\nfunction _CopyTextureMetadata(from: BaseTexture, to: ProceduralTexture, includeTransform: boolean): void {\n    to.coordinatesIndex = from.coordinatesIndex;\n    to.wrapU = from.wrapU;\n    to.wrapV = from.wrapV;\n    if (includeTransform) {\n        const src = from as Texture;\n        to.uOffset = src.uOffset ?? 0;\n        to.vOffset = src.vOffset ?? 0;\n        to.uScale = src.uScale ?? 1;\n        to.vScale = src.vScale ?? 1;\n        to.wAng = src.wAng ?? 0;\n    }\n}\n\n/**\n * @internal\n * Return the shader define suffix for a TextureChannel (e.g. TextureChannel.R → \"R\").\n * Returns an empty string for RGBA (no swizzle needed).\n */\nfunction _ChannelDefine(channel: TextureChannel): string {\n    switch (channel) {\n        case TextureChannel.R:\n            return \"R\";\n        case TextureChannel.G:\n            return \"G\";\n        case TextureChannel.B:\n            return \"B\";\n        case TextureChannel.A:\n            return \"A\";\n        default:\n            return \"\";\n    }\n}\n\n/**\n * @internal\n * Apply a channel swizzle to a constant Color4, matching the GPU behaviour for TextureChannel.\n */\nfunction _ApplyChannelSwizzle(c: Color4, channel: TextureChannel): Color4 {\n    switch (channel) {\n        case TextureChannel.R:\n            return new Color4(c.r, c.r, c.r, c.a);\n        case TextureChannel.G:\n            return new Color4(c.g, c.g, c.g, c.a);\n        case TextureChannel.B:\n            return new Color4(c.b, c.b, c.b, c.a);\n        case TextureChannel.A:\n            return new Color4(c.a, c.a, c.a, c.a);\n        default:\n            return c;\n    }\n}\n\n/**\n * @internal\n * Build the OP_INVERT define plus per-channel INVERT_R/G/B/A defines from an ChannelMask bitmask.\n */\nfunction _BuildInvertDefines(channels: ChannelMask): string[] {\n    const defines: string[] = [\"OP_INVERT\"];\n    if (channels & ChannelMask.R) {\n        defines.push(\"INVERT_R\");\n    }\n    if (channels & ChannelMask.G) {\n        defines.push(\"INVERT_G\");\n    }\n    if (channels & ChannelMask.B) {\n        defines.push(\"INVERT_B\");\n    }\n    if (channels & ChannelMask.A) {\n        defines.push(\"INVERT_A\");\n    }\n    return defines;\n}\n\n/**\n * @internal\n * Build OUTPUT_MASK_X_ZERO / OUTPUT_MASK_A_ONE defines for excluded channels.\n * Channels present in the mask pass through; excluded channels get defaults (0.0 for RGB, 1.0 for A).\n * Returns an empty array for ChannelMask.RGBA (no masking needed).\n */\nfunction _BuildOutputChannelMaskDefines(mask: ChannelMask): string[] {\n    const defines: string[] = [];\n    if (!(mask & ChannelMask.R)) {\n        defines.push(\"OUTPUT_MASK_R_ZERO\");\n    }\n    if (!(mask & ChannelMask.G)) {\n        defines.push(\"OUTPUT_MASK_G_ZERO\");\n    }\n    if (!(mask & ChannelMask.B)) {\n        defines.push(\"OUTPUT_MASK_B_ZERO\");\n    }\n    if (!(mask & ChannelMask.A)) {\n        defines.push(\"OUTPUT_MASK_A_ONE\");\n    }\n    return defines;\n}\n\n/**\n * @internal\n * Apply a ChannelMask to a constant Color4: included channels pass through,\n * excluded color channels become 0, excluded alpha becomes 1.\n */\nfunction _ApplyOutputChannelMask(c: Color4, mask: ChannelMask): Color4 {\n    return new Color4(mask & ChannelMask.R ? c.r : 0, mask & ChannelMask.G ? c.g : 0, mask & ChannelMask.B ? c.b : 0, mask & ChannelMask.A ? c.a : 1);\n}\n\n/**\n * @internal\n * Build shader defines for a standard A/B operand.\n * When `bakeTransform` is true and the texture has a non-identity UV transform,\n * the OPERAND_X_MATRIX define is emitted so the shader applies the matrix when sampling.\n */\nfunction _BuildOperandDefines(operand: ITextureProcessOperand, prefix: \"A\" | \"B\", bakeTransform: boolean): string[] {\n    const defines: string[] = [];\n    if (operand.texture) {\n        defines.push(`OPERAND_${prefix}_TEXTURE`);\n        if (bakeTransform && _HasNonIdentityTransform(operand.texture)) {\n            defines.push(`OPERAND_${prefix}_MATRIX`);\n        }\n        if (operand.colorSpace) {\n            defines.push(`OPERAND_${prefix}_SRGB`);\n        }\n        if (operand.channel) {\n            defines.push(`OPERAND_${prefix}_CHANNEL_${_ChannelDefine(operand.channel)}`);\n        }\n    }\n    if (operand.factor !== undefined || !operand.texture) {\n        defines.push(`OPERAND_${prefix}_FACTOR`);\n    }\n    return defines;\n}\n\n/**\n * @internal\n * Build shader defines for the lerp blend operand.\n * When `bakeTransform` is true and the texture has a non-identity UV transform,\n * the LERP_T_MATRIX define is emitted.\n */\nfunction _BuildLerpBlendDefines(t: ITextureProcessOperand, bakeTransform: boolean): string[] {\n    const defines: string[] = [];\n    if (t.texture) {\n        defines.push(\"LERP_T_TEXTURE\");\n        if (bakeTransform && _HasNonIdentityTransform(t.texture)) {\n            defines.push(\"LERP_T_MATRIX\");\n        }\n        if (t.factor !== undefined) {\n            defines.push(\"LERP_T_FACTOR\");\n        }\n        if (t.colorSpace) {\n            defines.push(\"LERP_T_SRGB\");\n        }\n        if (t.channel) {\n            defines.push(`LERP_T_CHANNEL_${_ChannelDefine(t.channel)}`);\n        }\n    }\n    // factor-only: no additional defines needed; the shader uses factorT when LERP_T_TEXTURE is absent.\n    return defines;\n}\n\n/**\n * @internal\n * Set uniforms and textures for a standard A/B operand on a procedural texture.\n * When `bakeTransform` is true and the texture has a non-identity UV matrix,\n * that matrix is uploaded as `<textureName>Matrix` for the shader to apply when sampling.\n */\nfunction _SetOperandUniforms(pt: ProceduralTexture, operand: ITextureProcessOperand, textureName: string, factorName: string, bakeTransform: boolean): void {\n    if (operand.texture) {\n        pt.setTexture(textureName, operand.texture as Texture);\n        if (bakeTransform && _HasNonIdentityTransform(operand.texture)) {\n            pt.setMatrix(`${textureName}Matrix`, operand.texture.getTextureMatrix());\n        }\n    }\n    const needsFactor = operand.factor !== undefined || !operand.texture;\n    if (needsFactor) {\n        pt.setColor4(factorName, _EvalConstant(operand));\n    }\n}\n\n/**\n * @internal\n * Set uniforms and textures for the lerp blend operand.\n * When `bakeTransform` is true and the texture has a non-identity UV matrix,\n * that matrix is uploaded as `textureTMatrix`.\n */\nfunction _SetLerpBlendUniforms(pt: ProceduralTexture, t: ITextureProcessOperand, bakeTransform: boolean): void {\n    if (t.texture) {\n        pt.setTexture(\"textureT\", t.texture as Texture);\n        if (bakeTransform && _HasNonIdentityTransform(t.texture)) {\n            pt.setMatrix(\"textureTMatrix\", t.texture.getTextureMatrix());\n        }\n        if (t.factor !== undefined) {\n            pt.setColor4(\"factorT\", t.factor);\n        }\n    } else {\n        pt.setColor4(\"factorT\", _EvalConstant(t));\n    }\n}\n\n/**\n * @internal\n * Create a textureProcessor procedural texture with the given defines. The returned texture\n * is not yet rendered — uniforms must be set on it before calling _RenderAsync.\n */\nfunction _CreateProcessorTexture(\n    name: string,\n    defines: string[],\n    outputSize: TextureSize,\n    scene: Scene,\n    outputColorSpace: TextureColorSpace = TextureColorSpace.Linear,\n    outputOptions?: ITextureProcessorOutputOptions\n): ProceduralTexture {\n    const options: IProceduralTextureCreationOptions = {\n        type: outputOptions?.textureType ?? Constants.TEXTURETYPE_UNSIGNED_BYTE,\n        format: Constants.TEXTUREFORMAT_RGBA,\n        samplingMode: outputOptions?.samplingMode ?? Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n        generateDepthBuffer: false,\n        generateMipMaps: outputOptions?.generateMipMaps ?? false,\n        gammaSpace: outputColorSpace === TextureColorSpace.SRGB,\n        shaderLanguage: scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n        extraInitializationsAsync: async () => {\n            if (scene.getEngine().isWebGPU) {\n                await Promise.all([import(\"../../ShadersWGSL/textureProcessor.fragment\")]);\n            } else {\n                await Promise.all([import(\"../../Shaders/textureProcessor.fragment\")]);\n            }\n        },\n        // Opt out of scene-managed rendering. _shouldRender() would re-render the texture\n        // on the first scene frame regardless of refreshRate (because _currentRefreshId starts\n        // at -1 and is only advanced by _shouldRender() itself, not by a direct render() call).\n        // That re-render would sample already-disposed input textures, producing blank output.\n        skipSceneRegistration: true,\n    };\n\n    const pt = new ProceduralTexture(name, outputSize, _ShaderName, scene, options);\n    pt.refreshRate = -1; // render on demand only\n    pt.defines = defines.length > 0 ? \"#define \" + defines.join(\"\\n#define \") + \"\\n\" : \"\";\n    return pt;\n}\n\n/**\n * @internal\n * Wait for a procedural texture's shader to compile then render it. Uniforms must be set\n * on the texture before calling this.\n */\nasync function _RenderAsync(pt: ProceduralTexture): Promise<void> {\n    return await new Promise<void>((resolve, reject) => {\n        pt.executeWhenReady(() => {\n            try {\n                pt.render();\n                resolve();\n            } catch (error) {\n                reject(error instanceof Error ? error : new Error(String(error)));\n            }\n        });\n    });\n}\n\n/**\n * Multiply two texture operands together, component-wise: `result = a * b`.\n *\n * Each operand can be a texture, a constant factor, or a texture scaled by a factor.\n * This is useful for applying glTF-style factors to textures (e.g. `baseColorTexture * baseColorFactor`),\n * or for modulating one texture by another.\n *\n * If both operands are constant (no textures), the multiplication is performed on the CPU and\n * the result is returned as a factor-only operand with no texture allocated.\n *\n * When operands are results of previous operations (i.e. they carry a `dispose` function),\n * their intermediate textures are automatically released after the GPU pass completes.\n *\n * @param name - Name for the resulting procedural texture (used only when a GPU pass is needed)\n * @param a - First operand\n * @param b - Second operand\n * @param scene - Scene to create the texture in (used only when a GPU pass is needed)\n * @param outputColorSpace - Optional output color space. When `TextureColorSpace.SRGB`, the linear\n *   result is converted to sRGB (IEC 61966-2-1) before being written. Defaults to `TextureColorSpace.Linear`.\n * @param outputChannelMask - Optional bitmask of channels to write. Excluded color channels are set to\n *   `0.0`; excluded alpha is set to `1.0`. Defaults to `ChannelMask.RGBA` (all channels written).\n * @param outputOptions - Optional render-target type, sampling, and mipmap settings.\n * @returns An operand whose `texture` holds the GPU result, or whose `factor` holds the CPU-folded constant\n */\nexport async function MultiplyTexturesAsync(\n    name: string,\n    a: ITextureProcessOperand,\n    b: ITextureProcessOperand,\n    scene: Scene,\n    outputColorSpace?: TextureColorSpace,\n    outputChannelMask?: ChannelMask,\n    outputOptions?: ITextureProcessorOutputOptions\n): Promise<ITextureProcessOperand> {\n    if (!a.texture && !b.texture) {\n        const factor = _MultiplyConstants(_EvalConstant(a), _EvalConstant(b));\n        return { texture: null, factor: outputChannelMask ? _ApplyOutputChannelMask(factor, outputChannelMask) : factor };\n    }\n\n    const allTextures: BaseTexture[] = [];\n    if (a.texture) {\n        allTextures.push(a.texture);\n    }\n    if (b.texture) {\n        allTextures.push(b.texture);\n    }\n    const canPropagate = _AllTransformsMatch(allTextures);\n    const bakeTransform = !canPropagate;\n\n    const defines = [\n        ..._BuildOperandDefines(a, \"A\", bakeTransform),\n        ..._BuildOperandDefines(b, \"B\", bakeTransform),\n        ...(outputChannelMask ? _BuildOutputChannelMaskDefines(outputChannelMask) : []),\n    ];\n    if (outputColorSpace) {\n        defines.push(\"OUTPUT_SRGB\");\n    }\n    const pt = _CreateProcessorTexture(name, defines, _ResolveOutputSize([a, b]), scene, outputColorSpace, outputOptions);\n    _SetOperandUniforms(pt, a, \"textureA\", \"factorA\", bakeTransform);\n    _SetOperandUniforms(pt, b, \"textureB\", \"factorB\", bakeTransform);\n    try {\n        await _RenderAsync(pt);\n    } catch (error) {\n        a.dispose?.();\n        b.dispose?.();\n        throw error;\n    }\n\n    a.dispose?.();\n    b.dispose?.();\n\n    _CopyTextureMetadata(allTextures[0], pt, canPropagate);\n    const result: ITextureProcessOperand = { texture: pt, dispose: () => pt.dispose() };\n    if (outputColorSpace) {\n        result.colorSpace = outputColorSpace;\n    }\n    return result;\n}\n\n/**\n * Take the component-wise maximum of two texture operands: `result = max(a, b)`.\n *\n * Each operand can be a texture, a constant factor, or a texture scaled by a factor.\n * Useful for operations such as combining ambient occlusion maps or taking the\n * brightest contribution from two sources.\n *\n * If both operands are constant (no textures), the operation is performed on the CPU and\n * the result is returned as a factor-only operand with no texture allocated.\n *\n * When operands are results of previous operations (i.e. they carry a `dispose` function),\n * their intermediate textures are automatically released after the GPU pass completes.\n *\n * @param name - Name for the resulting procedural texture (used only when a GPU pass is needed)\n * @param a - First operand\n * @param b - Second operand\n * @param scene - Scene to create the texture in (used only when a GPU pass is needed)\n * @param outputColorSpace - Optional output color space. When `TextureColorSpace.SRGB`, the linear\n *   result is converted to sRGB (IEC 61966-2-1) before being written. Defaults to `TextureColorSpace.Linear`.\n * @param outputChannelMask - Optional bitmask of channels to write. Excluded color channels are set to\n *   `0.0`; excluded alpha is set to `1.0`. Defaults to `ChannelMask.RGBA` (all channels written).\n * @param outputOptions - Optional render-target type, sampling, and mipmap settings.\n * @returns An operand whose `texture` holds the GPU result, or whose `factor` holds the CPU-folded constant\n */\nexport async function MaxTexturesAsync(\n    name: string,\n    a: ITextureProcessOperand,\n    b: ITextureProcessOperand,\n    scene: Scene,\n    outputColorSpace?: TextureColorSpace,\n    outputChannelMask?: ChannelMask,\n    outputOptions?: ITextureProcessorOutputOptions\n): Promise<ITextureProcessOperand> {\n    if (!a.texture && !b.texture) {\n        const factor = _MaxConstants(_EvalConstant(a), _EvalConstant(b));\n        return { texture: null, factor: outputChannelMask ? _ApplyOutputChannelMask(factor, outputChannelMask) : factor };\n    }\n\n    const allTextures: BaseTexture[] = [];\n    if (a.texture) {\n        allTextures.push(a.texture);\n    }\n    if (b.texture) {\n        allTextures.push(b.texture);\n    }\n    const canPropagate = _AllTransformsMatch(allTextures);\n    const bakeTransform = !canPropagate;\n\n    const defines = [\n        \"OP_MAX\",\n        ..._BuildOperandDefines(a, \"A\", bakeTransform),\n        ..._BuildOperandDefines(b, \"B\", bakeTransform),\n        ...(outputChannelMask ? _BuildOutputChannelMaskDefines(outputChannelMask) : []),\n    ];\n    if (outputColorSpace) {\n        defines.push(\"OUTPUT_SRGB\");\n    }\n    const pt = _CreateProcessorTexture(name, defines, _ResolveOutputSize([a, b]), scene, outputColorSpace, outputOptions);\n    _SetOperandUniforms(pt, a, \"textureA\", \"factorA\", bakeTransform);\n    _SetOperandUniforms(pt, b, \"textureB\", \"factorB\", bakeTransform);\n    try {\n        await _RenderAsync(pt);\n    } catch (error) {\n        a.dispose?.();\n        b.dispose?.();\n        throw error;\n    }\n\n    a.dispose?.();\n    b.dispose?.();\n\n    _CopyTextureMetadata(allTextures[0], pt, canPropagate);\n    const result: ITextureProcessOperand = { texture: pt, dispose: () => pt.dispose() };\n    if (outputColorSpace) {\n        result.colorSpace = outputColorSpace;\n    }\n    return result;\n}\n\n/**\n * Linearly interpolate between two texture operands: `result = mix(a, b, t)`.\n *\n * Each operand can be a texture, a constant factor, or a texture scaled by a factor.\n * The `t` operand controls the blend weight per texel, per channel — a value of 0 returns `a`,\n * a value of 1 returns `b`. Use a grayscale texture or a scalar `Color4(v, v, v, v)` for\n * uniform blending across all channels.\n *\n * If all three operands are constant (no textures), the interpolation is performed on the CPU and\n * the result is returned as a factor-only operand with no texture allocated.\n *\n * When operands are results of previous operations (i.e. they carry a `dispose` function),\n * their intermediate textures are automatically released after the GPU pass completes.\n *\n * @param name - Name for the resulting procedural texture (used only when a GPU pass is needed)\n * @param a - Start value operand (returned when t = 0)\n * @param b - End value operand (returned when t = 1)\n * @param t - Blend weight operand. Each channel independently controls the blend for the corresponding output channel.\n * @param scene - Scene to create the texture in (used only when a GPU pass is needed)\n * @param outputColorSpace - Optional output color space. When `TextureColorSpace.SRGB`, the linear\n *   result is converted to sRGB (IEC 61966-2-1) before being written. Defaults to `TextureColorSpace.Linear`.\n * @param outputChannelMask - Optional bitmask of channels to write. Excluded color channels are set to\n *   `0.0`; excluded alpha is set to `1.0`. Defaults to `ChannelMask.RGBA` (all channels written).\n * @param outputOptions - Optional render-target type, sampling, and mipmap settings.\n * @returns An operand whose `texture` holds the GPU result, or whose `factor` holds the CPU-folded constant\n */\nexport async function LerpTexturesAsync(\n    name: string,\n    a: ITextureProcessOperand,\n    b: ITextureProcessOperand,\n    t: ITextureProcessOperand,\n    scene: Scene,\n    outputColorSpace?: TextureColorSpace,\n    outputChannelMask?: ChannelMask,\n    outputOptions?: ITextureProcessorOutputOptions\n): Promise<ITextureProcessOperand> {\n    if (!a.texture && !b.texture && !t.texture) {\n        const factor = _LerpConstants(_EvalConstant(a), _EvalConstant(b), _EvalConstant(t));\n        return { texture: null, factor: outputChannelMask ? _ApplyOutputChannelMask(factor, outputChannelMask) : factor };\n    }\n\n    const allTextures: BaseTexture[] = [];\n    if (a.texture) {\n        allTextures.push(a.texture);\n    }\n    if (b.texture) {\n        allTextures.push(b.texture);\n    }\n    if (t.texture) {\n        allTextures.push(t.texture);\n    }\n    const canPropagate = _AllTransformsMatch(allTextures);\n    const bakeTransform = !canPropagate;\n\n    const defines = [\n        \"OP_LERP\",\n        ..._BuildOperandDefines(a, \"A\", bakeTransform),\n        ..._BuildOperandDefines(b, \"B\", bakeTransform),\n        ..._BuildLerpBlendDefines(t, bakeTransform),\n        ...(outputChannelMask ? _BuildOutputChannelMaskDefines(outputChannelMask) : []),\n    ];\n    if (outputColorSpace) {\n        defines.push(\"OUTPUT_SRGB\");\n    }\n    const pt = _CreateProcessorTexture(name, defines, _ResolveOutputSize([a, b, t]), scene, outputColorSpace, outputOptions);\n    _SetOperandUniforms(pt, a, \"textureA\", \"factorA\", bakeTransform);\n    _SetOperandUniforms(pt, b, \"textureB\", \"factorB\", bakeTransform);\n    _SetLerpBlendUniforms(pt, t, bakeTransform);\n    try {\n        await _RenderAsync(pt);\n    } catch (error) {\n        a.dispose?.();\n        b.dispose?.();\n        t.dispose?.();\n        throw error;\n    }\n\n    a.dispose?.();\n    b.dispose?.();\n    t.dispose?.();\n\n    _CopyTextureMetadata(allTextures[0], pt, canPropagate);\n    const result: ITextureProcessOperand = { texture: pt, dispose: () => pt.dispose() };\n    if (outputColorSpace) {\n        result.colorSpace = outputColorSpace;\n    }\n    return result;\n}\n\n/**\n * Invert selected channels of a texture operand: `result[ch] = 1 - input[ch]`.\n *\n * The `channels` bitmask selects which channels are inverted; unselected channels pass through\n * unchanged. Use `ChannelMask.RGB` for the common roughness↔smoothness conversion, or\n * `ChannelMask.RGBA` (the default) to invert the entire texture.\n *\n * This is a unary operation — only operand A is used. Any `colorSpace` or `channel` properties\n * on the input operand are honoured (sRGB linearization and channel swizzle applied before\n * the invert).\n *\n * If the input is constant (no texture), the invert is performed on the CPU.\n *\n * When the input is the result of a previous operation (i.e. it carries a `dispose` function),\n * its intermediate texture is automatically released after the GPU pass completes.\n *\n * @param name - Name for the resulting procedural texture (used only when a GPU pass is needed)\n * @param input - Operand to invert\n * @param scene - Scene to create the texture in (used only when a GPU pass is needed)\n * @param channels - Bitmask of channels to invert. Defaults to `ChannelMask.RGBA`.\n * @param outputColorSpace - Optional output color space. When `TextureColorSpace.SRGB`, the linear\n *   result is converted to sRGB (IEC 61966-2-1) before being written. Defaults to `TextureColorSpace.Linear`.\n * @param outputChannelMask - Optional bitmask of channels to write. Excluded color channels are set to\n *   `0.0`; excluded alpha is set to `1.0`. Defaults to `ChannelMask.RGBA` (all channels written).\n * @param outputOptions - Optional render-target type, sampling, and mipmap settings.\n * @returns An operand whose `texture` holds the GPU result, or whose `factor` holds the CPU-folded constant\n */\nexport async function InvertTextureAsync(\n    name: string,\n    input: ITextureProcessOperand,\n    scene: Scene,\n    channels: ChannelMask = ChannelMask.RGBA,\n    outputColorSpace?: TextureColorSpace,\n    outputChannelMask?: ChannelMask,\n    outputOptions?: ITextureProcessorOutputOptions\n): Promise<ITextureProcessOperand> {\n    if (!input.texture) {\n        const c = _EvalConstant(input);\n        const factor = new Color4(\n            channels & ChannelMask.R ? 1 - c.r : c.r,\n            channels & ChannelMask.G ? 1 - c.g : c.g,\n            channels & ChannelMask.B ? 1 - c.b : c.b,\n            channels & ChannelMask.A ? 1 - c.a : c.a\n        );\n        return { texture: null, factor: outputChannelMask ? _ApplyOutputChannelMask(factor, outputChannelMask) : factor };\n    }\n\n    // Single input: UV transform is always propagated (no bake needed).\n    const defines = [..._BuildOperandDefines(input, \"A\", false), ..._BuildInvertDefines(channels), ...(outputChannelMask ? _BuildOutputChannelMaskDefines(outputChannelMask) : [])];\n    if (outputColorSpace) {\n        defines.push(\"OUTPUT_SRGB\");\n    }\n    const pt = _CreateProcessorTexture(name, defines, _ResolveOutputSize([input]), scene, outputColorSpace, outputOptions);\n    _SetOperandUniforms(pt, input, \"textureA\", \"factorA\", false);\n    try {\n        await _RenderAsync(pt);\n    } catch (error) {\n        input.dispose?.();\n        throw error;\n    }\n\n    input.dispose?.();\n\n    _CopyTextureMetadata(input.texture, pt, true);\n    const result: ITextureProcessOperand = { texture: pt, dispose: () => pt.dispose() };\n    if (outputColorSpace) {\n        result.colorSpace = outputColorSpace;\n    }\n    return result;\n}\n\n/**\n * Extract the per-texel maximum channel value from a texture and broadcast it to all output\n * channels, producing a single-value (greyscale) texture in a single GPU pass.\n *\n * For each texel, computes `max(r, g, b)` — or `max(r, g, b, a)` when `includeAlpha` is true —\n * and writes that scalar to the output:\n * - `includeAlpha = false` (default): output is `(m, m, m, a)` where `m = max(r, g, b)`\n * - `includeAlpha = true`:            output is `(m, m, m, m)` where `m = max(r, g, b, a)`\n *\n * This is more efficient than chaining `ExtractChannelAsync` calls through `MaxTexturesAsync`,\n * which would require multiple intermediate textures and GPU passes.\n *\n * Any `colorSpace` or `channel` properties on the input operand are honoured (sRGB linearization\n * and channel swizzle applied before the max reduction).\n *\n * If the input is constant (no texture), the reduction is performed on the CPU.\n *\n * When the input is the result of a previous operation (i.e. it carries a `dispose` function),\n * its intermediate texture is automatically released after the GPU pass completes.\n *\n * @param name - Name for the resulting procedural texture (used only when a GPU pass is needed)\n * @param input - Operand to reduce\n * @param scene - Scene to create the texture in (used only when a GPU pass is needed)\n * @param includeAlpha - When true, alpha participates in the max and is also set to the result.\n *   Defaults to false (alpha is preserved from the input).\n * @param outputColorSpace - Optional output color space. When `TextureColorSpace.SRGB`, the linear\n *   result is converted to sRGB (IEC 61966-2-1) before being written. Defaults to `TextureColorSpace.Linear`.\n * @param outputChannelMask - Optional bitmask of channels to write. Excluded color channels are set to\n *   `0.0`; excluded alpha is set to `1.0`. Defaults to `ChannelMask.RGBA` (all channels written).\n * @param outputOptions - Optional render-target type, sampling, and mipmap settings.\n * @returns An operand whose `texture` holds the GPU result, or whose `factor` holds the CPU-folded constant\n */\nexport async function ExtractMaxChannelAsync(\n    name: string,\n    input: ITextureProcessOperand,\n    scene: Scene,\n    includeAlpha: boolean = false,\n    outputColorSpace?: TextureColorSpace,\n    outputChannelMask?: ChannelMask,\n    outputOptions?: ITextureProcessorOutputOptions\n): Promise<ITextureProcessOperand> {\n    if (!input.texture) {\n        const c = _EvalConstant(input);\n        const m = includeAlpha ? Math.max(c.r, c.g, c.b, c.a) : Math.max(c.r, c.g, c.b);\n        const factor = new Color4(m, m, m, includeAlpha ? m : c.a);\n        return { texture: null, factor: outputChannelMask ? _ApplyOutputChannelMask(factor, outputChannelMask) : factor };\n    }\n\n    // Single input: UV transform is always propagated (no bake needed).\n    const defines = [..._BuildOperandDefines(input, \"A\", false), \"OP_CHANNEL_MAX\", ...(outputChannelMask ? _BuildOutputChannelMaskDefines(outputChannelMask) : [])];\n    if (includeAlpha) {\n        defines.push(\"CHANNEL_MAX_INCLUDE_ALPHA\");\n    }\n    if (outputColorSpace) {\n        defines.push(\"OUTPUT_SRGB\");\n    }\n    const pt = _CreateProcessorTexture(name, defines, _ResolveOutputSize([input]), scene, outputColorSpace, outputOptions);\n    _SetOperandUniforms(pt, input, \"textureA\", \"factorA\", false);\n    try {\n        await _RenderAsync(pt);\n    } catch (error) {\n        input.dispose?.();\n        throw error;\n    }\n\n    input.dispose?.();\n\n    _CopyTextureMetadata(input.texture, pt, true);\n    const result: ITextureProcessOperand = { texture: pt, dispose: () => pt.dispose() };\n    if (outputColorSpace) {\n        result.colorSpace = outputColorSpace;\n    }\n    return result;\n}\n\n/**\n * Extract a single channel from a texture and broadcast it to RGB (or all four components for\n * `TextureChannel.A`), producing a new texture. This is a convenience wrapper over\n * `MultiplyTexturesAsync` with a `(1,1,1,1)` factor and the requested channel swizzle applied\n * to the input.\n *\n * Swizzle results per channel:\n * - `TextureChannel.R` → (r, r, r, a)\n * - `TextureChannel.G` → (g, g, g, a)\n * - `TextureChannel.B` → (b, b, b, a)\n * - `TextureChannel.A` → (a, a, a, a)\n *\n * If the input is constant (no texture), the swizzle is applied on the CPU.\n *\n * Any `colorSpace` property on the input operand is honoured (sRGB linearization applied before\n * the swizzle). Any existing `channel` on the input is replaced by the `channel` argument.\n *\n * When the input is the result of a previous operation (i.e. it carries a `dispose` function),\n * its intermediate texture is automatically released after the GPU pass completes.\n *\n * @param name - Name for the resulting procedural texture (used only when a GPU pass is needed)\n * @param input - Operand to extract the channel from\n * @param channel - The channel to extract and broadcast\n * @param scene - Scene to create the texture in (used only when a GPU pass is needed)\n * @param outputColorSpace - Optional output color space. When `TextureColorSpace.SRGB`, the linear\n *   result is converted to sRGB (IEC 61966-2-1) before being written. Defaults to `TextureColorSpace.Linear`.\n * @param outputChannelMask - Optional bitmask of channels to write. Excluded color channels are set to\n *   `0.0`; excluded alpha is set to `1.0`. Defaults to `ChannelMask.RGBA` (all channels written).\n * @param outputOptions - Optional render-target type, sampling, and mipmap settings.\n * @returns An operand whose `texture` holds the GPU result, or whose `factor` holds the CPU-folded constant\n */\nexport async function ExtractChannelAsync(\n    name: string,\n    input: ITextureProcessOperand,\n    channel: TextureChannel,\n    scene: Scene,\n    outputColorSpace?: TextureColorSpace,\n    outputChannelMask?: ChannelMask,\n    outputOptions?: ITextureProcessorOutputOptions\n): Promise<ITextureProcessOperand> {\n    if (!input.texture) {\n        const swizzled = _ApplyChannelSwizzle(_EvalConstant(input), channel);\n        return { texture: null, factor: outputChannelMask ? _ApplyOutputChannelMask(swizzled, outputChannelMask) : swizzled };\n    }\n    return await MultiplyTexturesAsync(name, { ...input, channel }, CreateFactorOperand(new Color4(1, 1, 1, 1)), scene, outputColorSpace, outputChannelMask, outputOptions);\n}\n","import { type Nullable } from \"../../types\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type IRenderTargetTexture, type RenderTargetWrapper } from \"../../Engines/renderTargetWrapper\";\r\nimport { ThinTexture } from \"./thinTexture\";\r\nimport { type TextureSize, type RenderTargetCreationOptions } from \"./textureCreationOptions\";\r\n\r\n/**\r\n * This is a tiny helper class to wrap a RenderTargetWrapper in a texture\r\n * usable as the input of an effect.\r\n */\r\nexport class ThinRenderTargetTexture extends ThinTexture implements IRenderTargetTexture {\r\n    private readonly _renderTargetOptions: RenderTargetCreationOptions;\r\n\r\n    private _renderTarget: Nullable<RenderTargetWrapper> = null;\r\n    private _size: TextureSize;\r\n\r\n    /**\r\n     * Gets the render target wrapper associated with this render target\r\n     */\r\n    public get renderTarget(): Nullable<RenderTargetWrapper> {\r\n        return this._renderTarget;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new ThinRenderTargetTexture.\r\n     * Tiny helper class to wrap a RenderTargetWrapper in a texture.\r\n     * This can be used as an internal texture wrapper to benefit from the cache and to hold on the associated RTT\r\n     * @param engine Define the engine used to create and host the render target\r\n     * @param size Define the size of the RTT to create\r\n     * @param options Define rendertarget options\r\n     */\r\n    constructor(engine: AbstractEngine, size: TextureSize, options: RenderTargetCreationOptions) {\r\n        super(null);\r\n        this._engine = engine;\r\n        this._renderTargetOptions = options;\r\n        this.resize(size);\r\n    }\r\n\r\n    /**\r\n     * Resize the texture to a new desired size.\r\n     * Be careful as it will recreate all the data in the new texture.\r\n     * @param size Define the new size. It can be:\r\n     *   - a number for squared texture,\r\n     *   - an object containing { width: number, height: number }\r\n     */\r\n    public resize(size: TextureSize): void {\r\n        this._renderTarget?.dispose();\r\n        this._renderTarget = null;\r\n        this._texture = null;\r\n        this._size = size;\r\n\r\n        if (this._engine) {\r\n            this._renderTarget = this._engine.createRenderTargetTexture(this._size, this._renderTargetOptions);\r\n        }\r\n        this._texture = this.renderTarget!.texture;\r\n    }\r\n\r\n    /**\r\n     * Get the underlying lower level texture from Babylon.\r\n     * @returns the internal texture\r\n     */\r\n    public override getInternalTexture(): Nullable<InternalTexture> {\r\n        return this._texture;\r\n    }\r\n\r\n    /**\r\n     * Get the class name of the texture.\r\n     * @returns \"ThinRenderTargetTexture\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ThinRenderTargetTexture\";\r\n    }\r\n\r\n    /**\r\n     * Dispose the texture and release its associated resources.\r\n     * @param disposeOnlyFramebuffers if set to true it will dispose only the frame buffers (default: false)\r\n     */\r\n    public override dispose(disposeOnlyFramebuffers = false): void {\r\n        this._renderTarget?.dispose(true);\r\n        this._renderTarget = null;\r\n\r\n        if (!disposeOnlyFramebuffers) {\r\n            super.dispose();\r\n        }\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"proceduralVertexShader\";\nconst shader = `attribute position: vec2f;varying vPosition: vec2f;varying vUV: vec2f;const madd: vec2f= vec2f(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.vPosition=vertexInputs.position;vertexOutputs.vUV=vertexInputs.position*madd+madd;vertexOutputs.position= vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const proceduralVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"proceduralVertexShader\";\nconst shader = `attribute vec2 position;varying vec2 vPosition;varying vec2 vUV;const vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvPosition=position;vUV=position*madd+madd;gl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const proceduralVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"hdrFilteringVertexShader\";\nconst shader = `attribute vec2 position;varying vec3 direction;uniform vec3 up;uniform vec3 right;uniform vec3 front;\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nmat3 view=mat3(up,right,front);direction=view*vec3(position,1.0);gl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const hdrFilteringVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { importanceSampling } from \"./ShadersInclude/importanceSampling\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctions } from \"./ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"hdrFilteringPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nuniform float alphaG;uniform samplerCube inputTexture;uniform vec2 vFilteringInfo;uniform float hdrScale;varying vec3 direction;void main() {vec3 color=radiance(alphaG,inputTexture,direction,vFilteringInfo);gl_FragColor=vec4(color*hdrScale,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, importanceSampling, pbrBRDFFunctions, hdrFilteringFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const hdrFilteringPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"hdrFilteringVertexShader\";\nconst shader = `attribute position: vec2f;varying direction: vec3f;uniform up: vec3f;uniform right: vec3f;uniform front: vec3f;\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvar view: mat3x3f= mat3x3f(uniforms.up,uniforms.right,uniforms.front);vertexOutputs.direction=view*vec3f(vertexInputs.position,1.0);vertexOutputs.position= vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const hdrFilteringVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { importanceSamplingWGSL } from \"./ShadersInclude/importanceSampling\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctionsWGSL } from \"./ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"hdrFilteringPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nuniform alphaG: f32;var inputTextureSampler: sampler;var inputTexture: texture_cube<f32>;uniform vFilteringInfo: vec2f;uniform hdrScale: f32;varying direction: vec3f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var color: vec3f=radiance(uniforms.alphaG,inputTexture,inputTextureSampler,input.direction,uniforms.vFilteringInfo);fragmentOutputs.color= vec4f(color*uniforms.hdrScale,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, importanceSamplingWGSL, pbrBRDFFunctionsWGSL, hdrFilteringFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const hdrFilteringPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"hdrIrradianceFilteringVertexShader\";\nconst shader = `attribute vec2 position;varying vec3 direction;uniform vec3 up;uniform vec3 right;uniform vec3 front;\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nmat3 view=mat3(up,right,front);direction=view*vec3(position,1.0);gl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const hdrIrradianceFilteringVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { importanceSampling } from \"./ShadersInclude/importanceSampling\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctions } from \"./ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"hdrIrradianceFilteringPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nuniform samplerCube inputTexture;\n#ifdef IBL_CDF_FILTERING\nuniform sampler2D icdfTexture;\n#endif\nuniform vec2 vFilteringInfo;uniform float hdrScale;varying vec3 direction;void main() {vec3 color=irradiance(inputTexture,direction,vFilteringInfo,0.0,vec3(1.0),direction\n#ifdef IBL_CDF_FILTERING\n,icdfTexture\n#endif\n);gl_FragColor=vec4(color*hdrScale,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, importanceSampling, pbrBRDFFunctions, hdrFilteringFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const hdrIrradianceFilteringPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"hdrIrradianceFilteringVertexShader\";\nconst shader = `attribute position: vec2f;varying direction: vec3f;uniform up: vec3f;uniform right: vec3f;uniform front: vec3f;\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvar view: mat3x3f= mat3x3f(uniforms.up,uniforms.right,uniforms.front);vertexOutputs.direction=view*vec3f(vertexInputs.position,1.0);vertexOutputs.position= vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const hdrIrradianceFilteringVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { importanceSamplingWGSL } from \"./ShadersInclude/importanceSampling\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctionsWGSL } from \"./ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"hdrIrradianceFilteringPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nvar inputTextureSampler: sampler;var inputTexture: texture_cube<f32>;\n#ifdef IBL_CDF_FILTERING\nvar icdfTextureSampler: sampler;var icdfTexture: texture_2d<f32>;\n#endif\nuniform vFilteringInfo: vec2f;uniform hdrScale: f32;varying direction: vec3f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var color: vec3f=irradiance(inputTexture,inputTextureSampler,input.direction,uniforms.vFilteringInfo,0.0,vec3f(1.0),input.direction\n#ifdef IBL_CDF_FILTERING\n,icdfTexture,icdfTextureSampler\n#endif\n);fragmentOutputs.color= vec4f(color*uniforms.hdrScale,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, importanceSamplingWGSL, pbrBRDFFunctionsWGSL, hdrFilteringFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const hdrIrradianceFilteringPixelShaderWGSL = { name, shader };\n","/**\r\n * Enum defining the mode of a NodeMaterialBlockConnectionPoint\r\n */\r\nexport const enum NodeMaterialBlockConnectionPointMode {\r\n    /** Value is an uniform */\r\n    Uniform,\r\n    /** Value is a mesh attribute */\r\n    Attribute,\r\n    /** Value is a varying between vertex and fragment shaders */\r\n    Varying,\r\n    /** Mode is undefined */\r\n    Undefined,\r\n}\r\n","import { type NodeMaterialBlock } from \"./nodeMaterialBlock\";\r\nimport { type NodeMaterialConnectionPointDirection, NodeMaterialConnectionPoint, NodeMaterialConnectionPointCompatibilityStates } from \"./nodeMaterialBlockConnectionPoint\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Defines a connection point to be used for points with a custom object type\r\n */\r\nexport class NodeMaterialConnectionPointCustomObject<T extends NodeMaterialBlock> extends NodeMaterialConnectionPoint {\r\n    /**\r\n     * Creates a new connection point\r\n     * @param name defines the connection point name\r\n     * @param ownerBlock defines the block hosting this connection point\r\n     * @param direction defines the direction of the connection point\r\n     * @param _blockType\r\n     * @param _blockName\r\n     */\r\n    public constructor(\r\n        name: string,\r\n        ownerBlock: NodeMaterialBlock,\r\n        direction: NodeMaterialConnectionPointDirection,\r\n        // @internal\r\n        public _blockType: new (...args: any[]) => T,\r\n        private _blockName: string\r\n    ) {\r\n        super(name, ownerBlock, direction);\r\n\r\n        this.needDualDirectionValidation = true;\r\n    }\r\n\r\n    /**\r\n     * Gets a number indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a number defining the compatibility state\r\n     */\r\n    public override checkCompatibilityState(connectionPoint: NodeMaterialConnectionPoint): NodeMaterialConnectionPointCompatibilityStates {\r\n        return connectionPoint instanceof NodeMaterialConnectionPointCustomObject && connectionPoint._blockName === this._blockName\r\n            ? NodeMaterialConnectionPointCompatibilityStates.Compatible\r\n            : NodeMaterialConnectionPointCompatibilityStates.TypeIncompatible;\r\n    }\r\n\r\n    /**\r\n     * Creates a block suitable to be used as an input for this input point.\r\n     * If null is returned, a block based on the point type will be created.\r\n     * @returns The returned string parameter is the name of the output point of NodeMaterialBlock (first parameter of the returned array) that can be connected to the input\r\n     */\r\n    public override createCustomInputBlock(): Nullable<[NodeMaterialBlock, string]> {\r\n        return [new this._blockType(this._blockName), this.name];\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { VertexBuffer } from \"core/Meshes/buffer\";\r\nimport { type GaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplattingMesh.pure\";\r\nimport { _IsGaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplatting.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used for the Gaussian Splatting\r\n */\r\nexport class GaussianSplattingBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new GaussianSplattingBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"splatPosition\", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"splatScale\", NodeMaterialBlockConnectionPointTypes.Vector2, true, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"projection\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerOutput(\"splatVertex\", NodeMaterialBlockConnectionPointTypes.Vector4, NodeMaterialBlockTargets.Vertex);\r\n        this.registerOutput(\"SH\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Vertex);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GaussianSplattingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get splatPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the scale input component\r\n     */\r\n    public get splatScale(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the View matrix input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the View matrix input component\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the projection matrix input component\r\n     */\r\n    public get projection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the splatVertex output component\r\n     */\r\n    public get splatVertex(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the SH output contribution\r\n     */\r\n    public get SH(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"focal\");\r\n        state._excludeVariableName(\"invViewport\");\r\n        state._excludeVariableName(\"kernelSize\");\r\n        state._excludeVariableName(\"minPixelSize\");\r\n        state._excludeVariableName(\"eyePosition\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/gaussianSplatting\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/gaussianSplattingVertexDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/gaussianSplatting\"),\r\n                import(\"../../../../Shaders/ShadersInclude/helperFunctions\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n    /**\r\n     * Update defines for shader compilation\r\n     * @param defines defines the material defines to update\r\n     * @param nodeMaterial defines the node material requesting the update\r\n     * @param mesh defines the mesh to be rendered\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        if (_IsGaussianSplattingMesh(mesh)) {\r\n            defines.setValue(\"SH_DEGREE\", (<GaussianSplattingMesh>mesh).shDegree, true);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            return;\r\n        }\r\n\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"gaussianSplattingVertexDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"gaussianSplatting\", comments);\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n        state._emitUniformFromString(\"focal\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        state._emitUniformFromString(\"invViewport\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        state._emitUniformFromString(\"kernelSize\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        state._emitUniformFromString(\"minPixelSize\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        state._emitUniformFromString(\"eyePosition\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        state.attributes.push(VertexBuffer.PositionKind);\r\n        state.attributes.push(\"splatIndex0\");\r\n        state.attributes.push(\"splatIndex1\");\r\n        state.attributes.push(\"splatIndex2\");\r\n        state.attributes.push(\"splatIndex3\");\r\n        state.sharedData.nodeMaterial.backFaceCulling = false;\r\n\r\n        const splatPosition = this.splatPosition;\r\n        const splatScale = this.splatScale;\r\n        const world = this.world;\r\n        const view = this.view;\r\n        const projection = this.projection;\r\n        const output = this.splatVertex;\r\n        const sh = this.SH;\r\n\r\n        const addF = state.fSuffix;\r\n        let splatScaleParameter = `vec2${addF}(1.,1.)`;\r\n        if (splatScale.isConnected) {\r\n            splatScaleParameter = splatScale.associatedVariableName;\r\n        }\r\n\r\n        let input = \"position\";\r\n        let uniforms = \"\";\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            input = \"input.position\";\r\n            uniforms = \", uniforms.focal, uniforms.invViewport, uniforms.kernelSize, uniforms.minPixelSize\";\r\n        }\r\n        if (this.SH.isConnected) {\r\n            state.compilationString += `#if SH_DEGREE > 0\\n`;\r\n\r\n            if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                state.compilationString += `let worldRot: mat3x3f =  mat3x3f(${world.associatedVariableName}[0].xyz, ${world.associatedVariableName}[1].xyz, ${world.associatedVariableName}[2].xyz);`;\r\n                state.compilationString += `let normWorldRot: mat3x3f = inverseMat3(worldRot);`;\r\n                state.compilationString += `var eyeToSplatLocalSpace: vec3f = normalize(normWorldRot * (${splatPosition.associatedVariableName}.xyz - uniforms.eyePosition));\\n`;\r\n            } else {\r\n                state.compilationString += `mat3 worldRot = mat3(${world.associatedVariableName});`;\r\n                state.compilationString += `mat3 normWorldRot = inverseMat3(worldRot);`;\r\n                state.compilationString += `vec3 eyeToSplatLocalSpace = normalize(normWorldRot * (${splatPosition.associatedVariableName}.xyz - eyePosition));\\n`;\r\n            }\r\n\r\n            state.compilationString += `${state._declareOutput(sh)} = computeSH(splat, eyeToSplatLocalSpace);\\n`;\r\n            state.compilationString += `#else\\n`;\r\n            state.compilationString += `${state._declareOutput(sh)} = vec3${addF}(0.,0.,0.);\\n`;\r\n            state.compilationString += `#endif;\\n`;\r\n        } else {\r\n            state.compilationString += `${state._declareOutput(sh)} = vec3${addF}(0.,0.,0.);`;\r\n        }\r\n\r\n        state.compilationString += `${state._declareOutput(output)} = gaussianSplatting(${input}.xy, ${splatPosition.associatedVariableName}, ${splatScaleParameter}, covA, covB, ${world.associatedVariableName}, ${view.associatedVariableName}, ${projection.associatedVariableName}${uniforms});\\n`;\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GaussianSplattingBlock\", GaussianSplattingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used for the Gaussian Splatting Fragment part\r\n */\r\nexport class GaussianBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new GaussianBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = false;\r\n\r\n        this.registerInput(\"splatColor\", NodeMaterialBlockConnectionPointTypes.Color4, false, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"alpha\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GaussianBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get splatColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba output component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb output component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the alpha output component\r\n     */\r\n    public get alpha(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"vPosition\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/clipPlaneFragmentDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/logDepthDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/fogFragmentDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/gaussianSplattingFragmentDeclaration\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/clipPlaneFragmentDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/logDepthDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/fogFragmentDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/gaussianSplattingFragmentDeclaration\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            return;\r\n        }\r\n\r\n        // Emit code\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"clipPlaneFragmentDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"logDepthDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"fogFragmentDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"gaussianSplattingFragmentDeclaration\", comments);\r\n        state._emitVaryingFromString(\"vPosition\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        const tempSplatColor = state._getFreeVariableName(\"tempSplatColor\");\r\n        const color = this.splatColor;\r\n        const rgba = this._outputs[0];\r\n        const rgb = this._outputs[1];\r\n        const alpha = this._outputs[2];\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            state.compilationString += `let ${tempSplatColor}:vec4f = gaussianColor(${color.associatedVariableName}, input.vPosition);\\n`;\r\n        } else {\r\n            state.compilationString += `vec4 ${tempSplatColor} = gaussianColor(${color.associatedVariableName});\\n`;\r\n        }\r\n\r\n        state.compilationString += `${state._declareOutput(rgba)} = ${tempSplatColor}.rgba;`;\r\n        state.compilationString += `${state._declareOutput(rgb)} = ${tempSplatColor}.rgb;`;\r\n        state.compilationString += `${state._declareOutput(alpha)} = ${tempSplatColor}.a;`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GaussianBlock\", GaussianBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { GaussianSplattingMaterial } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used for Reading components of the Gaussian Splatting\r\n */\r\nexport class SplatReaderBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new SplatReaderBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"splatIndex\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerOutput(\"splatPosition\", NodeMaterialBlockConnectionPointTypes.Vector3, NodeMaterialBlockTargets.Vertex);\r\n        this.registerOutput(\"splatColor\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Vertex);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SplatReaderBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the splat index input component\r\n     */\r\n    public get splatIndex(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the splatPosition output component\r\n     */\r\n    public get splatPosition(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the splatColor output component\r\n     */\r\n    public get splatColor(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"covA\");\r\n        state._excludeVariableName(\"covB\");\r\n        state._excludeVariableName(\"vPosition\");\r\n        state._excludeVariableName(\"covariancesATexture\");\r\n        state._excludeVariableName(\"covariancesBTexture\");\r\n        state._excludeVariableName(\"centersTexture\");\r\n        state._excludeVariableName(\"colorsTexture\");\r\n        state._excludeVariableName(\"dataTextureSize\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/gaussianSplatting\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([import(\"../../../../Shaders/ShadersInclude/gaussianSplattingVertexDeclaration\"), import(\"../../../../Shaders/ShadersInclude/gaussianSplatting\")]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - defines the effect to bind data to\r\n     * @param nodeMaterial - defines the node material\r\n     * @param mesh - defines the mesh to bind data for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n        const scene = mesh.getScene();\r\n        GaussianSplattingMaterial.BindEffect(mesh, effect, scene);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            return;\r\n        }\r\n\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        // Emit code\r\n        const comments = `//${this.name}`;\r\n        state._emit2DSampler(\"covariancesATexture\");\r\n        state._emit2DSampler(\"covariancesBTexture\");\r\n        state._emit2DSampler(\"centersTexture\");\r\n        state._emit2DSampler(\"colorsTexture\");\r\n        state._emit2DSampler(\"shTexture0\", \"SH_DEGREE > 0\", undefined, undefined, true, \"highp\");\r\n        state._emit2DSampler(\"shTexture1\", \"SH_DEGREE > 0\", undefined, undefined, true, \"highp\");\r\n        state._emit2DSampler(\"shTexture2\", \"SH_DEGREE > 0\", undefined, undefined, true, \"highp\");\r\n\r\n        state._emitFunctionFromInclude(\"gaussianSplattingVertexDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"gaussianSplatting\", comments);\r\n        state._emitVaryingFromString(\"vPosition\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        state._emitUniformFromString(\"dataTextureSize\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        const splatPosition = this.splatPosition;\r\n        const splatColor = this.splatColor;\r\n\r\n        const splatVariablename = state._getFreeVariableName(\"splat\");\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            state.compilationString += `let splatIndex: f32 = getSplatIndex(i32(input.position.z + 0.5), input.splatIndex0, input.splatIndex1, input.splatIndex2, input.splatIndex3);`;\r\n            state.compilationString += `var ${splatVariablename}: Splat = readSplat(splatIndex, uniforms.dataTextureSize);\\n`;\r\n            state.compilationString += `var covA: vec3f = splat.covA.xyz; var covB: vec3f = vec3f(splat.covA.w, splat.covB.xy);\\n`;\r\n            state.compilationString += \"vertexOutputs.vPosition = input.position.xy;\\n\";\r\n        } else {\r\n            state.compilationString += `float splatIndex = getSplatIndex(int(position.z + 0.5));`;\r\n            state.compilationString += `Splat ${splatVariablename} = readSplat(splatIndex);\\n`;\r\n            state.compilationString += `vec3 covA = splat.covA.xyz; vec3 covB = vec3(splat.covA.w, splat.covB.xy);\\n`;\r\n            state.compilationString += \"vPosition = position.xy;\\n\";\r\n        }\r\n        state.compilationString += `${state._declareOutput(splatPosition)} = ${splatVariablename}.center.xyz;\\n`;\r\n        state.compilationString += `${state._declareOutput(splatColor)} = ${splatVariablename}.color;\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for splatReaderBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSplatReaderBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SplatReaderBlock\", SplatReaderBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { ThinTexture } from \"../../../Textures/thinTexture\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { type AbstractEngine } from \"../../../../Engines/abstractEngine.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { EngineStore } from \"../../../../Engines/engineStore\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used to provide an image for a TextureBlock\r\n */\r\nexport class ImageSourceBlock extends NodeMaterialBlock {\r\n    private static _DefaultTextureByEngine = /*#__PURE__*/ new WeakMap<AbstractEngine, ThinTexture>();\r\n\r\n    private _samplerName: string;\r\n    protected _texture: Nullable<Texture>;\r\n\r\n    private static _GetDefaultTexture(engine: AbstractEngine): ThinTexture {\r\n        let texture = ImageSourceBlock._DefaultTextureByEngine.get(engine);\r\n\r\n        if (!texture) {\r\n            texture = new ThinTexture(engine.emptyTexture);\r\n            ImageSourceBlock._DefaultTextureByEngine.set(engine, texture);\r\n        }\r\n\r\n        return texture;\r\n    }\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public get texture(): Nullable<Texture> {\r\n        return this._texture;\r\n    }\r\n\r\n    public set texture(texture: Nullable<Texture>) {\r\n        if (this._texture === texture) {\r\n            return;\r\n        }\r\n\r\n        const scene = texture?.getScene() ?? EngineStore.LastCreatedScene;\r\n\r\n        if (!texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this._texture!);\r\n            });\r\n        }\r\n\r\n        this._texture = texture;\r\n\r\n        if (texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(texture);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get samplerName(): string {\r\n        return this._samplerName;\r\n    }\r\n\r\n    /**\r\n     * Creates a new ImageSourceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this.registerOutput(\r\n            \"source\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n\r\n        this.registerOutput(\"dimensions\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param _nodeMaterial - the node material\r\n     */\r\n    public override bind(effect: Effect, _nodeMaterial: NodeMaterial) {\r\n        if (!this.texture) {\r\n            const engine = effect.getEngine();\r\n            if (engine.isWebGPU) {\r\n                effect.setTexture(this._samplerName, ImageSourceBlock._GetDefaultTexture(engine));\r\n            }\r\n            return;\r\n        }\r\n\r\n        effect.setTexture(this._samplerName, this.texture);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        if (this.texture && !this.texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ImageSourceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get source(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the dimension component\r\n     */\r\n    public get dimensions(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            this._samplerName = state._getFreeVariableName(this.name);\r\n\r\n            // Declarations\r\n            state.sharedData.blockingBlocks.push(this);\r\n            state.sharedData.textureBlocks.push(this);\r\n            state.sharedData.bindableBlocks.push(this);\r\n        }\r\n\r\n        if (this.dimensions.isConnected) {\r\n            let affect: string;\r\n            if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                affect = `vec2f(textureDimensions(${this._samplerName}, 0).xy)`;\r\n            } else {\r\n                affect = `vec2(textureSize(${this._samplerName}, 0).xy)`;\r\n            }\r\n\r\n            state.compilationString += `${state._declareOutput(this.dimensions)} = ${affect};\\n`;\r\n        }\r\n\r\n        if (this._texture?._texture?.is2DArray) {\r\n            state._emit2DArraySampler(this._samplerName);\r\n        } else {\r\n            state._emit2DSampler(this._samplerName);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode(ignoreTexture = false) {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        if (!this.texture || ignoreTexture) {\r\n            return codeString;\r\n        }\r\n\r\n        codeString += `${this._codeVariableName}.texture = new BABYLON.Texture(\"${this.texture.name}\", null, ${this.texture.noMipmap}, ${this.texture.invertY}, ${this.texture.samplingMode});\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wrapU = ${this.texture.wrapU};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wrapV = ${this.texture.wrapV};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uAng = ${this.texture.uAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vAng = ${this.texture.vAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wAng = ${this.texture.wAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uOffset = ${this.texture.uOffset};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vOffset = ${this.texture.vOffset};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uScale = ${this.texture.uScale};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vScale = ${this.texture.vScale};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @param ignoreTexture - whether to skip texture serialization\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(ignoreTexture = false): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        if (\r\n            !ignoreTexture &&\r\n            this.texture &&\r\n            (NodeMaterial.AllowSerializationOfRenderTargetTextures || !this.texture.isRenderTarget) &&\r\n            this.texture.getClassName() !== \"VideoTexture\"\r\n        ) {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     * @param urlRewriter - optional url rewriter\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string, urlRewriter?: (url: string) => string) {\r\n        super._deserialize(serializationObject, scene, rootUrl, urlRewriter);\r\n\r\n        if (serializationObject.texture && !NodeMaterial.IgnoreTexturesAtLoadTime) {\r\n            if (serializationObject.texture.url !== undefined) {\r\n                if (serializationObject.texture.url.indexOf(\"data:\") === 0) {\r\n                    rootUrl = \"\";\r\n                } else if (urlRewriter) {\r\n                    serializationObject.texture.url = urlRewriter(serializationObject.texture.url);\r\n                    serializationObject.texture.name = serializationObject.texture.url;\r\n                }\r\n            }\r\n            if (serializationObject.texture.base64String || serializationObject.texture.url !== undefined) {\r\n                this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl) as Texture;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for imageSourceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterImageSourceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ImageSourceBlock\", ImageSourceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\nimport { CurrentScreenBlock } from \"./currentScreenBlock.pure\";\nimport { InputBlock } from \"../Input/inputBlock.pure\";\nimport { type NodeMaterialBlock } from \"../../nodeMaterialBlock\";\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\nimport { type Scene } from \"core/scene.pure\";\nimport { SfeModeDefine } from \"../Fragment/smartFilterFragmentOutputBlock.pure\";\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\nimport { type Nullable } from \"../../../../types\";\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\nimport { ImageSourceBlock } from \"./imageSourceBlock.pure\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Base block used for creating Smart Filter shader blocks for the SFE framework.\n * This block extends the functionality of CurrentScreenBlock, as both are used\n * to represent arbitrary 2D textures to compose, and work similarly.\n */\nexport class SmartFilterTextureBlock extends CurrentScreenBlock {\n    private _firstInit: boolean = true;\n\n    /**\n     * A boolean indicating whether this block should be the main input for the SFE pipeline.\n     * If true, it can be used in SFE for auto-disabling.\n     */\n    public isMainInput: boolean = false;\n\n    /**\n     * Gets the sampler name associated with this texture\n     */\n    public override get samplerName(): string {\n        if (this.source.connectedPoint) {\n            return (this.source.connectedPoint.ownerBlock as ImageSourceBlock).samplerName;\n        }\n        return this._samplerName;\n    }\n\n    /**\n     * Gets or sets the texture associated with this block\n     */\n    public override get texture(): Nullable<BaseTexture> {\n        if (this.source.connectedPoint) {\n            return (this.source.connectedPoint.ownerBlock as ImageSourceBlock).texture;\n        }\n        return this._texture;\n    }\n    public override set texture(value: Nullable<BaseTexture>) {\n        this._texture = value;\n    }\n\n    /**\n     * Create a new SmartFilterTextureBlock\n     * @param name defines the block name\n     */\n    public constructor(name: string) {\n        super(name);\n\n        this.registerInput(\n            \"source\",\n            NodeMaterialBlockConnectionPointTypes.Object,\n            true,\n            NodeMaterialBlockTargets.VertexAndFragment,\n            new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\n        );\n    }\n\n    /**\n     * Gets the source input component\n     */\n    public get source(): NodeMaterialConnectionPoint {\n        return this._inputs[1];\n    }\n\n    /**\n     * Gets a boolean indicating that this block is linked to an ImageSourceBlock\n     */\n    public get hasImageSource(): boolean {\n        return this.source.isConnected;\n    }\n\n    /**\n     * Gets the current class name\n     * @returns the class name\n     */\n    public override getClassName() {\n        return \"SmartFilterTextureBlock\";\n    }\n\n    /**\n     * Initialize the block and prepare the context for build\n     * @param state defines the state that will be used for the build\n     */\n    public override initialize(state: NodeMaterialBuildState) {\n        if (this._firstInit) {\n            this._samplerName = state._getFreeVariableName(this.name);\n            this._firstInit = false;\n        }\n    }\n\n    protected override _getMainUvName(state: NodeMaterialBuildState): string {\n        // Get the ScreenUVBlock's name, which is required for SFE and should be vUV.\n        // NOTE: In the future, when we move to vertex shaders, update this to check for the nearest vec2 varying output.\n        const screenUv = state.sharedData.nodeMaterial.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"postprocess_uv\");\n        if (!screenUv || !screenUv.isAnAncestorOf(this)) {\n            state.sharedData.raiseBuildError(\"SmartFilterTextureBlock: 'postprocess_uv' attribute from ScreenUVBlock is required.\");\n            return \"\";\n        }\n        return screenUv.associatedVariableName;\n    }\n\n    protected override _emitUvAndSampler(state: NodeMaterialBuildState): void {\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\n            // Wrap the varying in a define, as it won't be needed in SFE.\n            state._emitVaryingFromString(this._mainUVName, NodeMaterialBlockConnectionPointTypes.Vector2, SfeModeDefine, true);\n\n            if (!this.hasImageSource) {\n                // Append `// main` to denote this as the main input texture to composite\n                const annotation = this.isMainInput ? \"// main\" : undefined;\n                state._emit2DSampler(this._samplerName, undefined, undefined, annotation);\n            }\n        }\n    }\n\n    /**\n     * Auto configure the block based on the material\n     * @param material - the node material\n     * @param additionalFilteringInfo - optional filtering info\n     */\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\n        if (!this.uv.isConnected) {\n            let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"postprocess_uv\" && additionalFilteringInfo(b));\n\n            if (!uvInput) {\n                uvInput = new InputBlock(\"uv\");\n                uvInput.setAsAttribute(\"postprocess_uv\");\n            }\n            uvInput.output.connectTo(this.uv);\n        }\n    }\n\n    /** {@inheritDoc} */\n    public override _postBuildBlock(): void {\n        this._firstInit = true;\n    }\n\n    /**\n     * Serializes the block\n     * @returns the serialized object\n     */\n    public override serialize(): any {\n        const serializationObject = super.serialize();\n        serializationObject.isMainInput = this.isMainInput;\n        return serializationObject;\n    }\n\n    /**\n     * Deserializes the block\n     * @param serializationObject - the serialization object\n     * @param scene - the scene\n     * @param rootUrl - the root url\n     */\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\n        super._deserialize(serializationObject, scene, rootUrl);\n        this.isMainInput = serializationObject.isMainInput;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for smartFilterTextureBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterSmartFilterTextureBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(\"BABYLON.SmartFilterTextureBlock\", SmartFilterTextureBlock);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { BaseMathBlock } from \"./baseMathBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add 2 vectors\r\n */\r\nexport class AddBlock extends BaseMathBlock {\r\n    /**\r\n     * Creates a new AddBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"AddBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.left.associatedVariableName} + ${this.right.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for addBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAddBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AddBlock\", AddBlock);\r\n}\r\n","import { TransformBlock } from \"./Blocks/transformBlock.pure\";\r\nimport { VertexOutputBlock } from \"./Blocks/Vertex/vertexOutputBlock.pure\";\r\nimport { FragmentOutputBlock } from \"./Blocks/Fragment/fragmentOutputBlock.pure\";\r\nimport { InputBlock } from \"./Blocks/Input/inputBlock.pure\";\r\nimport { GaussianSplattingBlock } from \"./Blocks/GaussianSplatting/gaussianSplattingBlock.pure\";\r\nimport { GaussianBlock } from \"./Blocks/GaussianSplatting/gaussianBlock.pure\";\r\nimport { SplatReaderBlock } from \"./Blocks/GaussianSplatting/splatReaderBlock.pure\";\r\nimport { NodeMaterialModes } from \"./Enums/nodeMaterialModes\";\r\nimport { NodeMaterialSystemValues } from \"./Enums/nodeMaterialSystemValues\";\r\nimport { type NodeMaterial } from \"./nodeMaterial\";\r\nimport { MultiplyBlock } from \"./Blocks/multiplyBlock.pure\";\r\nimport { Texture } from \"../Textures/texture.pure\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\nimport { SmartFilterTextureBlock } from \"./Blocks/Dual/smartFilterTextureBlock.pure\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { AddBlock } from \"./Blocks/addBlock.pure\";\r\nimport { SmartFilterFragmentOutputBlock } from \"./Blocks/Fragment/smartFilterFragmentOutputBlock.pure\";\r\n\r\n/**\r\n * Clear the material and set it to a default state for gaussian splatting\r\n * @param nodeMaterial node material to use\r\n */\r\nexport function SetToDefaultGaussianSplatting(nodeMaterial: NodeMaterial): void {\r\n    nodeMaterial.clear();\r\n\r\n    nodeMaterial.editorData = null;\r\n\r\n    // reading splat datas\r\n    const splatIndex = new InputBlock(\"SplatIndex\");\r\n    splatIndex.setAsAttribute(\"splatIndex\");\r\n\r\n    const splatReader = new SplatReaderBlock(\"SplatReader\");\r\n    splatIndex.connectTo(splatReader);\r\n\r\n    // transforming datas into renderable positions\r\n    const gs = new GaussianSplattingBlock(\"GaussianSplatting\");\r\n    splatReader.connectTo(gs);\r\n\r\n    // world transformation\r\n    const worldInput = new InputBlock(\"World\");\r\n    worldInput.setAsSystemValue(NodeMaterialSystemValues.World);\r\n\r\n    const worldPos = new TransformBlock(\"WorldPos\");\r\n\r\n    splatReader.connectTo(worldPos);\r\n    worldInput.connectTo(worldPos);\r\n    worldPos.connectTo(gs, { output: \"xyz\", input: \"splatPosition\" });\r\n\r\n    // view and projections\r\n\r\n    const view = new InputBlock(\"view\");\r\n    view.setAsSystemValue(NodeMaterialSystemValues.View);\r\n\r\n    const projection = new InputBlock(\"Projection\");\r\n    projection.setAsSystemValue(NodeMaterialSystemValues.Projection);\r\n\r\n    worldInput.connectTo(gs, { input: \"world\" });\r\n    view.connectTo(gs, { input: \"view\" });\r\n    projection.connectTo(gs, { input: \"projection\" });\r\n\r\n    const addBlock = new AddBlock(\"Add SH\");\r\n\r\n    // from color to gaussian color\r\n    const gaussian = new GaussianBlock(\"Gaussian\");\r\n    splatReader.connectTo(gaussian, { input: \"splatColor\", output: \"splatColor\" });\r\n\r\n    // fragment and vertex outputs\r\n    const fragmentOutput = new FragmentOutputBlock(\"FragmentOutput\");\r\n\r\n    gs.SH.connectTo(addBlock.left);\r\n    gaussian.rgb.connectTo(addBlock.right);\r\n    addBlock.output.connectTo(fragmentOutput.rgb);\r\n    gaussian.alpha.connectTo(fragmentOutput.a);\r\n\r\n    const vertexOutput = new VertexOutputBlock(\"VertexOutput\");\r\n    gs.connectTo(vertexOutput);\r\n\r\n    // Add to nodes\r\n    nodeMaterial.addOutputNode(vertexOutput);\r\n    nodeMaterial.addOutputNode(fragmentOutput);\r\n\r\n    nodeMaterial._mode = NodeMaterialModes.GaussianSplatting;\r\n}\r\n\r\n/**\r\n * Clear the material and set it to a default state for Smart Filter effects\r\n * @param nodeMaterial node material to use\r\n */\r\nexport function SetToDefaultSFE(nodeMaterial: NodeMaterial): void {\r\n    nodeMaterial.clear();\r\n\r\n    nodeMaterial.editorData = null;\r\n\r\n    const uv = new InputBlock(\"uv\");\r\n    uv.setAsAttribute(\"postprocess_uv\");\r\n    uv.comments = \"Normalized screen position to sample our texture with.\";\r\n\r\n    const currentScreen = new SmartFilterTextureBlock(\"Input Texture\");\r\n    currentScreen.comments = \"A placeholder that represents the input texture to compose.\";\r\n    uv.connectTo(currentScreen);\r\n    const textureUrl = Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/nme/currentScreenPostProcess.png\");\r\n    currentScreen.texture = new Texture(textureUrl, nodeMaterial.getScene());\r\n\r\n    const color = new InputBlock(\"Color4\");\r\n    color.value = new Color4(1, 0, 0, 1);\r\n\r\n    const multiply = new MultiplyBlock(\"Multiply\");\r\n    color.connectTo(multiply);\r\n    currentScreen.connectTo(multiply);\r\n\r\n    const fragmentOutput = new SmartFilterFragmentOutputBlock(\"FragmentOutput\");\r\n    multiply.connectTo(fragmentOutput);\r\n\r\n    nodeMaterial.addOutputNode(fragmentOutput);\r\n\r\n    nodeMaterial._mode = NodeMaterialModes.SFE;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\n\r\nimport { type EffectFallbacks } from \"../../../effectFallbacks\";\r\nimport { BindBonesParameters, PrepareDefinesForBones } from \"../../../materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add support for vertex skinning (bones)\r\n */\r\nexport class BonesBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new BonesBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerInput(\"matricesIndices\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"matricesWeights\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"matricesIndicesExtra\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"matricesWeightsExtra\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"boneSampler\");\r\n        state._excludeVariableName(\"boneTextureInfo\");\r\n        state._excludeVariableName(\"mBones\");\r\n        state._excludeVariableName(\"BonesPerMesh\");\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([import(\"../../../../ShadersWGSL/ShadersInclude/bonesDeclaration\"), import(\"../../../../ShadersWGSL/ShadersInclude/bonesVertex\")]);\r\n        } else {\r\n            await Promise.all([import(\"../../../../Shaders/ShadersInclude/bonesDeclaration\"), import(\"../../../../Shaders/ShadersInclude/bonesVertex\")]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BonesBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix indices input component\r\n     */\r\n    public get matricesIndices(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix weights input component\r\n     */\r\n    public get matricesWeights(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the extra matrix indices input component\r\n     */\r\n    public get matricesIndicesExtra(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the extra matrix weights input component\r\n     */\r\n    public get matricesWeightsExtra(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the world input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.matricesIndices.isConnected) {\r\n            let matricesIndicesInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"matricesIndices\" && additionalFilteringInfo(b));\r\n\r\n            if (!matricesIndicesInput) {\r\n                matricesIndicesInput = new InputBlock(\"matricesIndices\");\r\n                matricesIndicesInput.setAsAttribute(\"matricesIndices\");\r\n            }\r\n            matricesIndicesInput.output.connectTo(this.matricesIndices);\r\n        }\r\n        if (!this.matricesWeights.isConnected) {\r\n            let matricesWeightsInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"matricesWeights\" && additionalFilteringInfo(b));\r\n\r\n            if (!matricesWeightsInput) {\r\n                matricesWeightsInput = new InputBlock(\"matricesWeights\");\r\n                matricesWeightsInput.setAsAttribute(\"matricesWeights\");\r\n            }\r\n            matricesWeightsInput.output.connectTo(this.matricesWeights);\r\n        }\r\n        if (!this.world.isConnected) {\r\n            let worldInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.World && additionalFilteringInfo(b));\r\n\r\n            if (!worldInput) {\r\n                worldInput = new InputBlock(\"world\");\r\n                worldInput.setAsSystemValue(NodeMaterialSystemValues.World);\r\n            }\r\n            worldInput.output.connectTo(this.world);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Provides the fallbacks\r\n     * @param fallbacks - the effect fallbacks\r\n     * @param mesh - the mesh\r\n     */\r\n    public override provideFallbacks(fallbacks: EffectFallbacks, mesh?: AbstractMesh) {\r\n        if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n            fallbacks.addCPUSkinningFallback(0, mesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        BindBonesParameters(mesh, effect);\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!defines._areAttributesDirty || !mesh) {\r\n            return;\r\n        }\r\n        PrepareDefinesForBones(mesh, defines);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        // Register for compilation fallbacks\r\n        state.sharedData.blocksWithFallbacks.push(this);\r\n\r\n        // Register for binding\r\n        state.sharedData.forcedBindableBlocks.push(this);\r\n\r\n        // Register for defines\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        // Register internal uniforms and samplers\r\n        state.uniforms.push(\"boneTextureInfo\");\r\n        state.uniforms.push(\"mBones\");\r\n\r\n        state.samplers.push(\"boneSampler\");\r\n\r\n        // Emit code\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"bonesDeclaration\", comments, {\r\n            removeAttributes: true,\r\n            removeUniforms: false,\r\n            removeVaryings: true,\r\n            removeIfDef: false,\r\n        });\r\n\r\n        const influenceVariablename = state._getFreeVariableName(\"influence\");\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"bonesVertex\", comments, {\r\n            replaceStrings: [\r\n                {\r\n                    search: /finalWorld=finalWorld\\*influence;/,\r\n                    replace: \"\",\r\n                },\r\n                {\r\n                    search: /influence/gm,\r\n                    replace: influenceVariablename,\r\n                },\r\n            ],\r\n        });\r\n\r\n        const output = this._outputs[0];\r\n        const worldInput = this.world;\r\n\r\n        state.compilationString += `#if NUM_BONE_INFLUENCERS>0\\n`;\r\n        state.compilationString += state._declareOutput(output) + ` = ${worldInput.associatedVariableName} * ${influenceVariablename};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += state._declareOutput(output) + ` = ${worldInput.associatedVariableName};\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for bonesBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBonesBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BonesBlock\", BonesBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type SubMesh } from \"../../../../Meshes/subMesh.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add support for instances\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances\r\n */\r\nexport class InstancesBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new InstancesBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerInput(\"world0\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"world1\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"world2\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"world3\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix, true);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this.registerOutput(\"instanceID\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstancesBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the first world row input component\r\n     */\r\n    public get world0(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the second world row input component\r\n     */\r\n    public get world1(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the third world row input component\r\n     */\r\n    public get world2(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the forth world row input component\r\n     */\r\n    public get world3(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the world input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the instanceID component\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get instanceID(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.world0.connectedPoint) {\r\n            let world0Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"world0\" && additionalFilteringInfo(b));\r\n\r\n            if (!world0Input) {\r\n                world0Input = new InputBlock(\"world0\");\r\n                world0Input.setAsAttribute(\"world0\");\r\n            }\r\n            world0Input.output.connectTo(this.world0);\r\n        }\r\n        if (!this.world1.connectedPoint) {\r\n            let world1Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"world1\" && additionalFilteringInfo(b));\r\n\r\n            if (!world1Input) {\r\n                world1Input = new InputBlock(\"world1\");\r\n                world1Input.setAsAttribute(\"world1\");\r\n            }\r\n            world1Input.output.connectTo(this.world1);\r\n        }\r\n        if (!this.world2.connectedPoint) {\r\n            let world2Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"world2\" && additionalFilteringInfo(b));\r\n\r\n            if (!world2Input) {\r\n                world2Input = new InputBlock(\"world2\");\r\n                world2Input.setAsAttribute(\"world2\");\r\n            }\r\n            world2Input.output.connectTo(this.world2);\r\n        }\r\n        if (!this.world3.connectedPoint) {\r\n            let world3Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"world3\" && additionalFilteringInfo(b));\r\n\r\n            if (!world3Input) {\r\n                world3Input = new InputBlock(\"world3\");\r\n                world3Input.setAsAttribute(\"world3\");\r\n            }\r\n            world3Input.output.connectTo(this.world3);\r\n        }\r\n        if (!this.world.connectedPoint) {\r\n            let worldInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"world\" && additionalFilteringInfo(b));\r\n\r\n            if (!worldInput) {\r\n                worldInput = new InputBlock(\"world\");\r\n                worldInput.setAsSystemValue(NodeMaterialSystemValues.World);\r\n            }\r\n            worldInput.output.connectTo(this.world);\r\n        }\r\n\r\n        this.world.define = \"!INSTANCES || THIN_INSTANCES\";\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     * @param useInstances - whether to use instances\r\n     * @param subMesh - the sub mesh\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh, useInstances: boolean = false, subMesh?: SubMesh) {\r\n        let changed = false;\r\n        if (defines[\"INSTANCES\"] !== useInstances) {\r\n            defines.setValue(\"INSTANCES\", useInstances);\r\n            changed = true;\r\n        }\r\n\r\n        if (subMesh && defines[\"THIN_INSTANCES\"] !== !!subMesh?.getRenderingMesh().hasThinInstances) {\r\n            defines.setValue(\"THIN_INSTANCES\", !!subMesh?.getRenderingMesh().hasThinInstances);\r\n            changed = true;\r\n        }\r\n\r\n        if (changed) {\r\n            defines.markAsUnprocessed();\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const engine = state.sharedData.scene.getEngine();\r\n\r\n        // Register for defines\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        // Emit code\r\n        const output = this._outputs[0];\r\n        const instanceID = this._outputs[1];\r\n        const world0 = this.world0;\r\n        const world1 = this.world1;\r\n        const world2 = this.world2;\r\n        const world3 = this.world3;\r\n\r\n        let mat4 = \"mat4\";\r\n        let instance = \"gl_InstanceID\";\r\n        let floatCast = \"float\";\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            mat4 = \"mat4x4f\";\r\n            instance = \"vertexInputs.instanceIndex\";\r\n            floatCast = \"f32\";\r\n        }\r\n\r\n        state.compilationString += `#ifdef INSTANCES\\n`;\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = ${mat4}(${world0.associatedVariableName}, ${world1.associatedVariableName}, ${world2.associatedVariableName}, ${world3.associatedVariableName});\\n`;\r\n        state.compilationString += `#ifdef THIN_INSTANCES\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = ${this.world.associatedVariableName} * ${output.associatedVariableName};\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n        if (engine._caps.canUseGLInstanceID) {\r\n            state.compilationString += state._declareOutput(instanceID) + ` = ${floatCast}(${instance});\\n`;\r\n        } else {\r\n            state.compilationString += state._declareOutput(instanceID) + ` = 0.0;\\n`;\r\n        }\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.world.associatedVariableName};\\n`;\r\n        state.compilationString += state._declareOutput(instanceID) + ` = 0.0;\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instancesBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstancesBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstancesBlock\", InstancesBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { VertexBuffer } from \"../../../../Buffers/buffer.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\n\r\nimport { BindMorphTargetParameters, PrepareDefinesForMorphTargets } from \"../../../materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add morph targets support to vertex shader\r\n */\r\nexport class MorphTargetsBlock extends NodeMaterialBlock {\r\n    private _repeatableContentAnchor: string;\r\n\r\n    /**\r\n     * Create a new MorphTargetsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerInput(\"position\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"normal\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"tangent\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.tangent.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color4 | NodeMaterialBlockConnectionPointTypes.Vector4 | NodeMaterialBlockConnectionPointTypes.Vector3\r\n        );\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"uv2\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.Color4);\r\n        this.registerOutput(\"positionOutput\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"normalOutput\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"tangentOutput\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"uvOutput\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"uv2Output\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"colorOutput\", NodeMaterialBlockConnectionPointTypes.Color4);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MorphTargetsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get position(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal input component\r\n     */\r\n    public get normal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the tangent input component\r\n     */\r\n    public get tangent(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv2 input component\r\n     */\r\n    public get uv2(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the position output component\r\n     */\r\n    public get positionOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal output component\r\n     */\r\n    public get normalOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the tangent output component\r\n     */\r\n    public get tangentOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv output component\r\n     */\r\n    public get uvOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv2 output component\r\n     */\r\n    public get uv2Output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the color output component\r\n     */\r\n    public get colorOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block\r\n     * @param state - the build state\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"morphTargetInfluences\");\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/morphTargetsVertex\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/morphTargetsVertexDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/morphTargetsVertexGlobal\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/morphTargetsVertexGlobalDeclaration\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/morphTargetsVertex\"),\r\n                import(\"../../../../Shaders/ShadersInclude/morphTargetsVertexDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/morphTargetsVertexGlobal\"),\r\n                import(\"../../../../Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.position.isConnected) {\r\n            let positionInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"position\" && additionalFilteringInfo(b));\r\n\r\n            if (!positionInput) {\r\n                positionInput = new InputBlock(\"position\");\r\n                positionInput.setAsAttribute();\r\n            }\r\n            positionInput.output.connectTo(this.position);\r\n        }\r\n        if (!this.normal.isConnected) {\r\n            let normalInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"normal\" && additionalFilteringInfo(b));\r\n\r\n            if (!normalInput) {\r\n                normalInput = new InputBlock(\"normal\");\r\n                normalInput.setAsAttribute(\"normal\");\r\n            }\r\n            normalInput.output.connectTo(this.normal);\r\n        }\r\n        if (!this.tangent.isConnected) {\r\n            let tangentInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"tangent\" && additionalFilteringInfo(b));\r\n\r\n            if (!tangentInput) {\r\n                tangentInput = new InputBlock(\"tangent\");\r\n                tangentInput.setAsAttribute(\"tangent\");\r\n            }\r\n            tangentInput.output.connectTo(this.tangent);\r\n        }\r\n        if (!this.uv.isConnected) {\r\n            let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"uv\" && additionalFilteringInfo(b));\r\n\r\n            if (!uvInput) {\r\n                uvInput = new InputBlock(\"uv\");\r\n                uvInput.setAsAttribute(\"uv\");\r\n            }\r\n            uvInput.output.connectTo(this.uv);\r\n        }\r\n        if (!this.uv2.isConnected) {\r\n            let uv2Input = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"uv2\" && additionalFilteringInfo(b));\r\n\r\n            if (!uv2Input) {\r\n                uv2Input = new InputBlock(\"uv2\");\r\n                uv2Input.setAsAttribute(\"uv2\");\r\n            }\r\n            uv2Input.output.connectTo(this.uv2);\r\n        }\r\n        if (!this.color.isConnected) {\r\n            let colorInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"color\" && additionalFilteringInfo(b));\r\n\r\n            if (!colorInput) {\r\n                colorInput = new InputBlock(\"color\");\r\n                colorInput.setAsAttribute(\"color\");\r\n            }\r\n            colorInput.output.connectTo(this.color);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        if ((<Mesh>mesh).morphTargetManager) {\r\n            const morphTargetManager = (<Mesh>mesh).morphTargetManager;\r\n\r\n            if (morphTargetManager?.isUsingTextureForTargets && (morphTargetManager.numMaxInfluencers || morphTargetManager.numInfluencers) !== defines[\"NUM_MORPH_INFLUENCERS\"]) {\r\n                defines.markAsAttributesDirty();\r\n            }\r\n        }\r\n\r\n        if (!defines._areAttributesDirty) {\r\n            return;\r\n        }\r\n\r\n        PrepareDefinesForMorphTargets(mesh, defines);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (mesh && mesh.morphTargetManager && mesh.morphTargetManager.numInfluencers > 0) {\r\n            BindMorphTargetParameters(mesh, effect);\r\n\r\n            if (mesh.morphTargetManager.isUsingTextureForTargets) {\r\n                mesh.morphTargetManager._bind(effect);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Replace repeatable content\r\n     * @param vertexShaderState - the vertex shader build state\r\n     * @param defines - the list of defines\r\n     * @param mesh - the mesh\r\n     */\r\n    public override replaceRepeatableContent(vertexShaderState: NodeMaterialBuildState, defines: NodeMaterialDefines, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const position = this.position;\r\n        const normal = this.normal;\r\n        const tangent = this.tangent;\r\n        const uv = this.uv;\r\n        const uv2 = this.uv2;\r\n        const color = this.color;\r\n        const positionOutput = this.positionOutput;\r\n        const normalOutput = this.normalOutput;\r\n        const tangentOutput = this.tangentOutput;\r\n        const uvOutput = this.uvOutput;\r\n        const uv2Output = this.uv2Output;\r\n        const colorOutput = this.colorOutput;\r\n        const state = vertexShaderState;\r\n        const repeatCount = defines.NUM_MORPH_INFLUENCERS;\r\n\r\n        const manager = (<Mesh>mesh).morphTargetManager;\r\n        const supportPositions = manager && manager.supportsPositions;\r\n        const supportNormals = manager && manager.supportsNormals;\r\n        const supportTangents = manager && manager.supportsTangents;\r\n        const supportUVs = manager && manager.supportsUVs;\r\n        const supportUV2s = manager && manager.supportsUV2s;\r\n        const supportColors = manager && manager.supportsColors;\r\n\r\n        let injectionCode = \"\";\r\n\r\n        if (manager?.isUsingTextureForTargets && repeatCount > 0) {\r\n            injectionCode += `${state._declareLocalVar(\"vertexID\", NodeMaterialBlockConnectionPointTypes.Float)};\\n`;\r\n        }\r\n\r\n        injectionCode += `#ifdef MORPHTARGETS\\n`;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const uniformsPrefix = isWebGPU ? \"uniforms.\" : \"\";\r\n        if (manager?.isUsingTextureForTargets) {\r\n            injectionCode += `for (${isWebGPU ? \"var\" : \"int\"} i = 0; i < NUM_MORPH_INFLUENCERS; i++) {\\n`;\r\n            injectionCode += `if (${isWebGPU ? \"f32\" : \"float\"}(i) >= ${uniformsPrefix}morphTargetCount) { break; }\\n`;\r\n\r\n            injectionCode += `vertexID = ${isWebGPU ? \"f32(vertexInputs.vertexIndex\" : \"float(gl_VertexID\"}) * ${uniformsPrefix}morphTargetTextureInfo.x;\\n`;\r\n            if (supportPositions) {\r\n                injectionCode += `#ifdef MORPHTARGETS_POSITION\\n`;\r\n                injectionCode += `${positionOutput.associatedVariableName} += (readVector3FromRawSampler(i, vertexID) - ${position.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[i];\\n`;\r\n                injectionCode += `#endif\\n`;\r\n            }\r\n            injectionCode += `#ifdef MORPHTARGETTEXTURE_HASPOSITIONS\\n`;\r\n            injectionCode += `vertexID += 1.0;\\n`;\r\n            injectionCode += `#endif\\n`;\r\n\r\n            if (supportNormals) {\r\n                injectionCode += `#ifdef MORPHTARGETS_NORMAL\\n`;\r\n                injectionCode += `${normalOutput.associatedVariableName} += (readVector3FromRawSampler(i, vertexID) - ${normal.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[i];\\n`;\r\n                injectionCode += `#endif\\n`;\r\n            }\r\n            injectionCode += `#ifdef MORPHTARGETTEXTURE_HASNORMALS\\n`;\r\n            injectionCode += `vertexID += 1.0;\\n`;\r\n            injectionCode += `#endif\\n`;\r\n\r\n            if (supportUVs) {\r\n                injectionCode += `#ifdef MORPHTARGETS_UV\\n`;\r\n                injectionCode += `${uvOutput.associatedVariableName} += (readVector3FromRawSampler(i, vertexID).xy - ${uv.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[i];\\n`;\r\n                injectionCode += `#endif\\n`;\r\n            }\r\n            injectionCode += `#ifdef MORPHTARGETTEXTURE_HASUVS\\n`;\r\n            injectionCode += `vertexID += 1.0;\\n`;\r\n            injectionCode += `#endif\\n`;\r\n\r\n            if (supportTangents) {\r\n                injectionCode += `#ifdef MORPHTARGETS_TANGENT\\n`;\r\n                injectionCode += `${tangentOutput.associatedVariableName}.xyz += (readVector3FromRawSampler(i, vertexID) - ${tangent.associatedVariableName}.xyz) * ${uniformsPrefix}morphTargetInfluences[i];\\n`;\r\n\r\n                if (tangent.type === NodeMaterialBlockConnectionPointTypes.Vector4) {\r\n                    injectionCode += `${tangentOutput.associatedVariableName}.w = ${tangent.associatedVariableName}.w;\\n`;\r\n                } else {\r\n                    injectionCode += `${tangentOutput.associatedVariableName}.w = 1.;\\n`;\r\n                }\r\n                injectionCode += `#endif\\n`;\r\n            }\r\n            injectionCode += `#ifdef MORPHTARGETTEXTURE_HASTANGENTS\\n`;\r\n            injectionCode += `vertexID += 1.0;\\n`;\r\n            injectionCode += `#endif\\n`;\r\n\r\n            if (supportUV2s) {\r\n                injectionCode += `#ifdef MORPHTARGETS_UV2\\n`;\r\n                injectionCode += `${uv2Output.associatedVariableName} += (readVector3FromRawSampler(i, vertexID).xy - ${uv2.associatedVariableName}) * morphTargetInfluences[i];\\n`;\r\n                injectionCode += `#endif\\n`;\r\n            }\r\n            injectionCode += `#ifdef MORPHTARGETTEXTURE_HASUV2S\\n`;\r\n            injectionCode += `vertexID += 1.0;\\n`;\r\n            injectionCode += `#endif\\n`;\r\n\r\n            if (supportColors) {\r\n                injectionCode += `#ifdef MORPHTARGETS_COLOR\\n`;\r\n                injectionCode += `${colorOutput.associatedVariableName} += (readVector4FromRawSampler(i, vertexID) - ${color.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[i];\\n`;\r\n                injectionCode += `#endif\\n`;\r\n            }\r\n\r\n            injectionCode += \"}\\n\";\r\n        } else {\r\n            for (let index = 0; index < repeatCount; index++) {\r\n                if (supportPositions) {\r\n                    injectionCode += `#ifdef MORPHTARGETS_POSITION\\n`;\r\n                    injectionCode += `${positionOutput.associatedVariableName} += (position${index} - ${position.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[${index}];\\n`;\r\n                    injectionCode += `#endif\\n`;\r\n                }\r\n\r\n                if (supportNormals && defines[\"NORMAL\"]) {\r\n                    injectionCode += `#ifdef MORPHTARGETS_NORMAL\\n`;\r\n                    injectionCode += `${normalOutput.associatedVariableName} += (normal${index} - ${normal.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[${index}];\\n`;\r\n                    injectionCode += `#endif\\n`;\r\n                }\r\n\r\n                if (supportUVs && defines[\"UV1\"]) {\r\n                    injectionCode += `#ifdef MORPHTARGETS_UV\\n`;\r\n                    injectionCode += `${uvOutput.associatedVariableName}.xy += (uv_${index} - ${uv.associatedVariableName}.xy) * ${uniformsPrefix}morphTargetInfluences[${index}];\\n`;\r\n                    injectionCode += `#endif\\n`;\r\n                }\r\n\r\n                if (supportTangents && defines[\"TANGENT\"]) {\r\n                    injectionCode += `#ifdef MORPHTARGETS_TANGENT\\n`;\r\n                    injectionCode += `${tangentOutput.associatedVariableName}.xyz += (tangent${index} - ${tangent.associatedVariableName}.xyz) * ${uniformsPrefix}morphTargetInfluences[${index}];\\n`;\r\n\r\n                    if (tangent.type === NodeMaterialBlockConnectionPointTypes.Vector4) {\r\n                        injectionCode += `${tangentOutput.associatedVariableName}.w = ${tangent.associatedVariableName}.w;\\n`;\r\n                    } else {\r\n                        injectionCode += `${tangentOutput.associatedVariableName}.w = 1.;\\n`;\r\n                    }\r\n                    injectionCode += `#endif\\n`;\r\n                }\r\n\r\n                if (supportUV2s && defines[\"UV2\"]) {\r\n                    injectionCode += `#ifdef MORPHTARGETS_UV2\\n`;\r\n                    injectionCode += `${uv2Output.associatedVariableName}.xy += (uv2_${index} - ${uv2.associatedVariableName}.xy) * morphTargetInfluences[${index}];\\n`;\r\n                    injectionCode += `#endif\\n`;\r\n                }\r\n\r\n                if (supportColors && defines[\"VERTEXCOLOR_NME\"]) {\r\n                    injectionCode += `#ifdef MORPHTARGETS_COLOR\\n`;\r\n                    injectionCode += `${colorOutput.associatedVariableName} += (color${index} - ${color.associatedVariableName}) * ${uniformsPrefix}morphTargetInfluences[${index}];\\n`;\r\n                    injectionCode += `#endif\\n`;\r\n                }\r\n            }\r\n        }\r\n        injectionCode += `#endif\\n`;\r\n\r\n        state.compilationString = state.compilationString.replace(this._repeatableContentAnchor, injectionCode);\r\n\r\n        if (repeatCount > 0) {\r\n            for (let index = 0; index < repeatCount; index++) {\r\n                if (supportPositions) {\r\n                    state.attributes.push(VertexBuffer.PositionKind + index);\r\n                }\r\n\r\n                if (supportNormals && defines[\"NORMAL\"]) {\r\n                    state.attributes.push(VertexBuffer.NormalKind + index);\r\n                }\r\n\r\n                if (supportTangents && defines[\"TANGENT\"]) {\r\n                    state.attributes.push(VertexBuffer.TangentKind + index);\r\n                }\r\n\r\n                if (supportUVs && defines[\"UV1\"]) {\r\n                    state.attributes.push(VertexBuffer.UVKind + \"_\" + index);\r\n                }\r\n\r\n                if (supportUV2s && defines[\"UV2\"]) {\r\n                    state.attributes.push(VertexBuffer.UV2Kind + \"_\" + index);\r\n                }\r\n\r\n                if (supportColors && defines[\"VERTEXCOLOR_NME\"]) {\r\n                    state.attributes.push(VertexBuffer.ColorKind + index);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        // Register for defines\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        // Register for binding\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        // Register for repeatable content generation\r\n        state.sharedData.repeatableContentBlocks.push(this);\r\n\r\n        // Emit code\r\n        const position = this.position;\r\n        const normal = this.normal;\r\n        const tangent = this.tangent;\r\n        const uv = this.uv;\r\n        const uv2 = this.uv2;\r\n        const color = this.color;\r\n        const positionOutput = this.positionOutput;\r\n        const normalOutput = this.normalOutput;\r\n        const tangentOutput = this.tangentOutput;\r\n        const uvOutput = this.uvOutput;\r\n        const uv2Output = this.uv2Output;\r\n        const colorOutput = this.colorOutput;\r\n        const comments = `//${this.name}`;\r\n\r\n        state.uniforms.push(\"morphTargetInfluences\");\r\n        state.uniforms.push(\"morphTargetCount\");\r\n        state.uniforms.push(\"morphTargetTextureInfo\");\r\n        state.uniforms.push(\"morphTargetTextureIndices\");\r\n        state.samplers.push(\"morphTargets\");\r\n\r\n        state._emitFunctionFromInclude(\"morphTargetsVertexGlobalDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"morphTargetsVertexDeclaration\", comments, {\r\n            repeatKey: \"maxSimultaneousMorphTargets\",\r\n        });\r\n\r\n        state.compilationString += `${state._declareOutput(positionOutput)} = ${position.associatedVariableName};\\n`;\r\n        state.compilationString += `#ifdef NORMAL\\n`;\r\n        state.compilationString += `${state._declareOutput(normalOutput)} = ${normal.associatedVariableName};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += `${state._declareOutput(normalOutput)} = vec3(0., 0., 0.);\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n        state.compilationString += `#ifdef TANGENT\\n`;\r\n        state.compilationString += `${state._declareOutput(tangentOutput)} = ${tangent.associatedVariableName};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += `${state._declareOutput(tangentOutput)} = vec4(0., 0., 0., 0.);\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n        state.compilationString += `#ifdef UV1\\n`;\r\n        state.compilationString += `${state._declareOutput(uvOutput)} = ${uv.associatedVariableName};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += `${state._declareOutput(uvOutput)} = vec2(0., 0.);\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n        state.compilationString += `#ifdef UV2\\n`;\r\n        state.compilationString += `${state._declareOutput(uv2Output)} = ${uv2.associatedVariableName};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += `${state._declareOutput(uv2Output)} = vec2(0., 0.);\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n        state.compilationString += `#ifdef VERTEXCOLOR_NME\\n`;\r\n        state.compilationString += `${state._declareOutput(colorOutput)} = ${color.associatedVariableName};\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += `${state._declareOutput(colorOutput)} = vec4(0., 0., 0., 0.);\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        // Repeatable content\r\n        this._repeatableContentAnchor = state._repeatableContentAnchor;\r\n        state.compilationString += this._repeatableContentAnchor;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for morphTargetsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMorphTargetsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MorphTargetsBlock\", MorphTargetsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Light } from \"../../../../Lights/light\";\r\nimport { PointLight } from \"../../../../Lights/pointLight.pure\";\r\nimport { type ShadowGenerator } from \"../../../../Lights/Shadows/shadowGenerator\";\r\nimport { type ShadowLight } from \"../../../../Lights\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get data information from a light\r\n */\r\nexport class LightInformationBlock extends NodeMaterialBlock {\r\n    private _lightDataUniformName: string;\r\n    private _lightColorUniformName: string;\r\n    private _lightShadowUniformName: string;\r\n    private _lightShadowExtraUniformName: string;\r\n    private _lightTypeDefineName: string;\r\n    private _forcePrepareDefines: boolean;\r\n\r\n    /**\r\n     * Gets or sets the light associated with this block\r\n     */\r\n    public light: Nullable<Light>;\r\n\r\n    /**\r\n     * Creates a new LightInformationBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerOutput(\"direction\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"color\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n        this.registerOutput(\"intensity\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"shadowBias\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"shadowNormalBias\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"shadowDepthScale\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"shadowDepthRange\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"LightInformationBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction output component\r\n     */\r\n    public get direction(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction output component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction output component\r\n     */\r\n    public get intensity(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow bias output component\r\n     */\r\n    public get shadowBias(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow normal bias output component\r\n     */\r\n    public get shadowNormalBias(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow depth scale component\r\n     */\r\n    public get shadowDepthScale(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow depth range component\r\n     */\r\n    public get shadowDepthRange(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        if (this.light && this.light.isDisposed()) {\r\n            this.light = null;\r\n        }\r\n\r\n        let light = this.light;\r\n        const scene = nodeMaterial.getScene();\r\n\r\n        if (!light && scene.lights.length) {\r\n            light = this.light = scene.lights[0];\r\n            this._forcePrepareDefines = true;\r\n        }\r\n\r\n        if (!light || !light.isEnabled) {\r\n            effect.setFloat3(this._lightDataUniformName, 0, 0, 0);\r\n            effect.setFloat4(this._lightColorUniformName, 0, 0, 0, 0);\r\n            return;\r\n        }\r\n\r\n        light.transferToNodeMaterialEffect(effect, this._lightDataUniformName);\r\n\r\n        effect.setColor4(this._lightColorUniformName, light.diffuse, light.intensity);\r\n\r\n        const generator = light.getShadowGenerator() as ShadowGenerator;\r\n        if (this.shadowBias.hasEndpoints || this.shadowNormalBias.hasEndpoints || this.shadowDepthScale.hasEndpoints) {\r\n            if (generator) {\r\n                effect.setFloat3(this._lightShadowUniformName, generator.bias, generator.normalBias, generator.depthScale);\r\n            } else {\r\n                effect.setFloat3(this._lightShadowUniformName, 0, 0, 0);\r\n            }\r\n        }\r\n\r\n        if (this.shadowDepthRange) {\r\n            if (generator && scene.activeCamera) {\r\n                const shadowLight = light as ShadowLight;\r\n                effect.setFloat2(\r\n                    this._lightShadowExtraUniformName,\r\n                    shadowLight.getDepthMinZ(scene.activeCamera),\r\n                    shadowLight.getDepthMinZ(scene.activeCamera) + shadowLight.getDepthMaxZ(scene.activeCamera)\r\n                );\r\n            } else {\r\n                effect.setFloat2(this._lightShadowExtraUniformName, 0, 0);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        if (!defines._areLightsDirty && !this._forcePrepareDefines) {\r\n            return;\r\n        }\r\n\r\n        this._forcePrepareDefines = false;\r\n\r\n        const light = this.light;\r\n        defines.setValue(this._lightTypeDefineName, light && light instanceof PointLight ? true : false, true);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        state.sharedData.bindableBlocks.push(this);\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        const direction = this.direction;\r\n        const color = this.color;\r\n        const intensity = this.intensity;\r\n        const shadowBias = this.shadowBias;\r\n        const shadowNormalBias = this.shadowNormalBias;\r\n        const shadowDepthScale = this.shadowDepthScale;\r\n        const shadowDepthRange = this.shadowDepthRange;\r\n\r\n        this._lightDataUniformName = state._getFreeVariableName(\"lightData\");\r\n        this._lightColorUniformName = state._getFreeVariableName(\"lightColor\");\r\n        this._lightShadowUniformName = state._getFreeVariableName(\"shadowData\");\r\n        this._lightShadowExtraUniformName = state._getFreeVariableName(\"shadowExtraData\");\r\n        this._lightTypeDefineName = state._getFreeDefineName(\"LIGHTPOINTTYPE\");\r\n\r\n        const uniformAdd = state.shaderLanguage === ShaderLanguage.WGSL ? \"uniforms.\" : \"\";\r\n\r\n        state._emitUniformFromString(this._lightDataUniformName, NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        state._emitUniformFromString(this._lightColorUniformName, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        state.compilationString += `#ifdef ${this._lightTypeDefineName}\\n`;\r\n        state.compilationString +=\r\n            state._declareOutput(direction) + ` = normalize(${this.worldPosition.associatedVariableName}.xyz - ${uniformAdd}${this._lightDataUniformName});\\n`;\r\n        state.compilationString += `#else\\n`;\r\n        state.compilationString += state._declareOutput(direction) + ` = ${uniformAdd}${this._lightDataUniformName};\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        state.compilationString += state._declareOutput(color) + ` = ${uniformAdd}${this._lightColorUniformName}.rgb;\\n`;\r\n        state.compilationString += state._declareOutput(intensity) + ` = ${uniformAdd}${this._lightColorUniformName}.a;\\n`;\r\n\r\n        if (shadowBias.hasEndpoints || shadowNormalBias.hasEndpoints || shadowDepthScale.hasEndpoints) {\r\n            state._emitUniformFromString(this._lightShadowUniformName, NodeMaterialBlockConnectionPointTypes.Vector3);\r\n            if (shadowBias.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(shadowBias) + ` = ${uniformAdd}${this._lightShadowUniformName}.x;\\n`;\r\n            }\r\n            if (shadowNormalBias.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(shadowNormalBias) + ` = ${uniformAdd}${this._lightShadowUniformName}.y;\\n`;\r\n            }\r\n            if (shadowDepthScale.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(shadowDepthScale) + ` = ${uniformAdd}${this._lightShadowUniformName}.z;\\n`;\r\n            }\r\n        }\r\n\r\n        if (shadowDepthRange.hasEndpoints) {\r\n            state._emitUniformFromString(this._lightShadowExtraUniformName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n            state.compilationString += state._declareOutput(shadowDepthRange) + ` = ${this._lightShadowUniformName};\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        if (this.light) {\r\n            serializationObject.lightId = this.light.id;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        if (serializationObject.lightId) {\r\n            this.light = scene.getLightById(serializationObject.lightId);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for lightInformationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLightInformationBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.LightInformationBlock\", LightInformationBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add image processing support to fragment shader\r\n */\r\nexport class ImageProcessingBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ImageProcessingBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Color4);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Defines if the input should be converted to linear space (default: true)\r\n     */\r\n    @editableInPropertyPage(\"Convert input to linear space\", PropertyTypeForEdition.Boolean, \"ADVANCED\")\r\n    public convertInputToLinearSpace: boolean = true;\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ImageProcessingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"whiteBalanceMatrix\");\r\n        state._excludeVariableName(\"exposureLinear\");\r\n        state._excludeVariableName(\"contrast\");\r\n        state._excludeVariableName(\"vInverseScreenSize\");\r\n        state._excludeVariableName(\"vignetteSettings1\");\r\n        state._excludeVariableName(\"vignetteSettings2\");\r\n        state._excludeVariableName(\"vCameraColorCurveNegative\");\r\n        state._excludeVariableName(\"vCameraColorCurveNeutral\");\r\n        state._excludeVariableName(\"vCameraColorCurvePositive\");\r\n        state._excludeVariableName(\"txColorTransform\");\r\n        state._excludeVariableName(\"colorTransformSettings\");\r\n        state._excludeVariableName(\"ditherIntensity\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/imageProcessingDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/imageProcessingFunctions\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/helperFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/imageProcessingDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/imageProcessingFunctions\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @param mesh - the mesh to check\r\n     * @param nodeMaterial - the node material\r\n     * @param defines - the material defines\r\n     * @returns true if ready\r\n     */\r\n    public override isReady(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {\r\n        if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {\r\n            if (!nodeMaterial.imageProcessingConfiguration.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     * @param nodeMaterial - the node material\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial) {\r\n        if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {\r\n            nodeMaterial.imageProcessingConfiguration.prepareDefines(defines);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        if (!nodeMaterial.imageProcessingConfiguration) {\r\n            return;\r\n        }\r\n\r\n        nodeMaterial.imageProcessingConfiguration.bind(effect);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        // Register for defines\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        // Register for blocking\r\n        state.sharedData.blockingBlocks.push(this);\r\n\r\n        // Register for binding\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        // Uniforms\r\n        state.uniforms.push(\"whiteBalanceMatrix\");\r\n        state.uniforms.push(\"exposureLinear\");\r\n        state.uniforms.push(\"contrast\");\r\n        state.uniforms.push(\"vInverseScreenSize\");\r\n        state.uniforms.push(\"vignetteSettings1\");\r\n        state.uniforms.push(\"vignetteSettings2\");\r\n        state.uniforms.push(\"vCameraColorCurveNegative\");\r\n        state.uniforms.push(\"vCameraColorCurveNeutral\");\r\n        state.uniforms.push(\"vCameraColorCurvePositive\");\r\n        state.uniforms.push(\"txColorTransform\");\r\n        state.uniforms.push(\"colorTransformSettings\");\r\n        state.uniforms.push(\"ditherIntensity\");\r\n\r\n        // Emit code\r\n        const color = this.color;\r\n        const output = this._outputs[0];\r\n        const comments = `//${this.name}`;\r\n        const overrideText = state.shaderLanguage === ShaderLanguage.WGSL ? \"Vec3\" : \"\";\r\n\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n        state._emitFunctionFromInclude(\"imageProcessingDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"imageProcessingFunctions\", comments);\r\n\r\n        if (color.connectedPoint?.isConnected) {\r\n            const isVec4Input =\r\n                color.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Color4 || color.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4;\r\n            // For vec3 inputs (Color3/Vector3), use 1.0 for alpha since they have no .a component\r\n            const alpha = isVec4Input ? `${color.associatedVariableName}.a` : \"1.0\";\r\n\r\n            if (isVec4Input) {\r\n                state.compilationString += `${state._declareOutput(output)} = ${color.associatedVariableName};\\n`;\r\n            } else {\r\n                state.compilationString += `${state._declareOutput(output)} = vec4${state.fSuffix}(${color.associatedVariableName}, 1.0);\\n`;\r\n            }\r\n            state.compilationString += `#ifdef IMAGEPROCESSINGPOSTPROCESS\\n`;\r\n            if (this.convertInputToLinearSpace) {\r\n                state.compilationString += `${output.associatedVariableName} = vec4${state.fSuffix}(toLinearSpace${overrideText}(${color.associatedVariableName}.rgb), ${alpha});\\n`;\r\n            }\r\n            state.compilationString += `#else\\n`;\r\n            state.compilationString += `#ifdef IMAGEPROCESSING\\n`;\r\n            if (this.convertInputToLinearSpace) {\r\n                state.compilationString += `${output.associatedVariableName} = vec4${state.fSuffix}(toLinearSpace${overrideText}(${color.associatedVariableName}.rgb), ${alpha});\\n`;\r\n            }\r\n            state.compilationString += `${output.associatedVariableName} = applyImageProcessing(${output.associatedVariableName});\\n`;\r\n            state.compilationString += `#endif\\n`;\r\n            state.compilationString += `#endif\\n`;\r\n\r\n            if (this.rgb.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(this.rgb) + ` = ${this.output.associatedVariableName}.xyz;\\n`;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.convertInputToLinearSpace = ${this.convertInputToLinearSpace};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.convertInputToLinearSpace = this.convertInputToLinearSpace;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.convertInputToLinearSpace = serializationObject.convertInputToLinearSpace ?? true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for imageProcessingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterImageProcessingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ImageProcessingBlock\", ImageProcessingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement TBN matrix\r\n */\r\nexport class TBNBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new TBNBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment, true);\r\n\r\n        this.registerInput(\"normal\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false);\r\n        this.normal.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color4 | NodeMaterialBlockConnectionPointTypes.Vector4 | NodeMaterialBlockConnectionPointTypes.Vector3\r\n        );\r\n        this.registerInput(\"tangent\", NodeMaterialBlockConnectionPointTypes.Vector4, false);\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix, false);\r\n\r\n        this.registerOutput(\r\n            \"TBN\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"TBN\", this, NodeMaterialConnectionPointDirection.Output, TBNBlock, \"TBNBlock\")\r\n        );\r\n\r\n        this.registerOutput(\"row0\", NodeMaterialBlockConnectionPointTypes.Vector3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"row1\", NodeMaterialBlockConnectionPointTypes.Vector3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"row2\", NodeMaterialBlockConnectionPointTypes.Vector3, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TBNBlock\";\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"tbnNormal\");\r\n        state._excludeVariableName(\"tbnTangent\");\r\n        state._excludeVariableName(\"tbnBitangent\");\r\n        state._excludeVariableName(\"TBN\");\r\n    }\r\n\r\n    /**\r\n     * Gets the normal input component\r\n     */\r\n    public get normal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the tangent input component\r\n     */\r\n    public get tangent(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the world matrix input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the TBN output component\r\n     */\r\n    public get TBN(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the row0 of the output matrix\r\n     */\r\n    public get row0(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the row1 of the output matrix\r\n     */\r\n    public get row1(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the row2 of the output matrix\r\n     */\r\n    public get row2(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the block target\r\n     */\r\n    public override get target() {\r\n        return NodeMaterialBlockTargets.Fragment;\r\n    }\r\n\r\n    /**\r\n     * Sets the block target\r\n     */\r\n    public override set target(value: NodeMaterialBlockTargets) {}\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - defines the hosting NodeMaterial\r\n     * @param additionalFilteringInfo - defines additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.world.isConnected) {\r\n            let worldInput = material.getInputBlockByPredicate((b) => b.isSystemValue && b.systemValue === NodeMaterialSystemValues.World && additionalFilteringInfo(b));\r\n\r\n            if (!worldInput) {\r\n                worldInput = new InputBlock(\"world\");\r\n                worldInput.setAsSystemValue(NodeMaterialSystemValues.World);\r\n            }\r\n            worldInput.output.connectTo(this.world);\r\n        }\r\n\r\n        if (!this.normal.isConnected) {\r\n            let normalInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"normal\" && additionalFilteringInfo(b));\r\n\r\n            if (!normalInput) {\r\n                normalInput = new InputBlock(\"normal\");\r\n                normalInput.setAsAttribute(\"normal\");\r\n            }\r\n            normalInput.output.connectTo(this.normal);\r\n        }\r\n\r\n        if (!this.tangent.isConnected) {\r\n            let tangentInput = material.getInputBlockByPredicate(\r\n                (b) => b.isAttribute && b.name === \"tangent\" && b.type === NodeMaterialBlockConnectionPointTypes.Vector4 && additionalFilteringInfo(b)\r\n            );\r\n\r\n            if (!tangentInput) {\r\n                tangentInput = new InputBlock(\"tangent\");\r\n                tangentInput.setAsAttribute(\"tangent\");\r\n            }\r\n            tangentInput.output.connectTo(this.tangent);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - defines the list of defines to update\r\n     * @param nodeMaterial - defines the node material requesting the update\r\n     * @param mesh - defines the mesh to bind data for\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const normal = this.normal;\r\n        const tangent = this.tangent;\r\n\r\n        let normalAvailable = normal.isConnected;\r\n        if (normal.connectInputBlock?.isAttribute && !mesh.isVerticesDataPresent(normal.connectInputBlock?.name)) {\r\n            normalAvailable = false;\r\n        }\r\n\r\n        let tangentAvailable = tangent.isConnected;\r\n        if (tangent.connectInputBlock?.isAttribute && !mesh.isVerticesDataPresent(tangent.connectInputBlock?.name)) {\r\n            tangentAvailable = false;\r\n        }\r\n\r\n        const useTBNBlock = normalAvailable && tangentAvailable;\r\n\r\n        defines.setValue(\"TBNBLOCK\", useTBNBlock, true);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const normal = this.normal;\r\n        const tangent = this.tangent;\r\n        const world = this.world;\r\n        const tbn = this.TBN;\r\n        const row0 = this.row0;\r\n        const row1 = this.row1;\r\n        const row2 = this.row2;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const mat3 = isWebGPU ? \"mat3x3f\" : \"mat3\";\r\n        const fSuffix = isWebGPU ? \"f\" : \"\";\r\n\r\n        // Fragment\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `\r\n                // ${this.name}\r\n                ${state._declareLocalVar(\"tbnNormal\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${normal.associatedVariableName}).xyz;\r\n                ${state._declareLocalVar(\"tbnTangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${tangent.associatedVariableName}.xyz);\r\n                ${state._declareLocalVar(\"tbnBitangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = cross(tbnNormal, tbnTangent) * ${tangent.associatedVariableName}.w;\r\n                ${isWebGPU ? \"var\" : \"mat3\"} ${tbn.associatedVariableName} = ${mat3}(${world.associatedVariableName}[0].xyz, ${world.associatedVariableName}[1].xyz, ${world.associatedVariableName}[2].xyz) * ${mat3}(tbnTangent, tbnBitangent, tbnNormal);\r\n            `;\r\n\r\n            if (row0.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(row0) +\r\n                    ` = vec3${fSuffix}(${tbn.associatedVariableName}[0][0], ${tbn.associatedVariableName}[0][1], ${tbn.associatedVariableName}[0][2]);\\n`;\r\n            }\r\n            if (row1.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(row1) +\r\n                    ` = vec3${fSuffix}(${tbn.associatedVariableName}[1][0], ${tbn.associatedVariableName}[1][1], ${tbn.associatedVariableName}[1][2]);\\n`;\r\n            }\r\n            if (row2.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(row2) +\r\n                    ` = vec3${fSuffix}(${tbn.associatedVariableName}[2][0], ${tbn.associatedVariableName}[2][1], ${tbn.associatedVariableName}[2][2]);\\n`;\r\n            }\r\n\r\n            state.sharedData.blocksWithDefines.push(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for tBNBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTBNBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TBNBlock\", TBNBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type TextureBlock } from \"../Dual/textureBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { TBNBlock } from \"./TBNBlock.pure\";\r\n\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to perturb normals based on a normal map\r\n */\r\nexport class PerturbNormalBlock extends NodeMaterialBlock {\r\n    private _tangentSpaceParameterName = \"\";\r\n    private _tangentCorrectionFactorName = \"\";\r\n    private _worldMatrixName = \"\";\r\n\r\n    /** Gets or sets a boolean indicating that normal should be inverted on X axis */\r\n    @editableInPropertyPage(\"Invert X axis\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true, notifiers: { update: true } })\r\n    public invertX = false;\r\n    /** Gets or sets a boolean indicating that normal should be inverted on Y axis */\r\n    @editableInPropertyPage(\"Invert Y axis\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true, notifiers: { update: true } })\r\n    public invertY = false;\r\n    /** Gets or sets a boolean indicating that parallax occlusion should be enabled */\r\n    @editableInPropertyPage(\"Use parallax occlusion\", PropertyTypeForEdition.Boolean, undefined, {\r\n        embedded: true,\r\n        notifiers: {\r\n            update: true,\r\n            callback: (_scene: Nullable<Scene>, block: PerturbNormalBlock) => {\r\n                block.parallaxScale._isInactive = block.useParallaxOcclusion;\r\n                block.parallaxHeight._isInactive = block.useParallaxOcclusion;\r\n                return true;\r\n            },\r\n        },\r\n    })\r\n    public useParallaxOcclusion = false;\r\n    /** Gets or sets a boolean indicating that sampling mode is in Object space */\r\n    @editableInPropertyPage(\"Object Space Mode\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true, notifiers: { update: true } })\r\n    public useObjectSpaceNormalMap = false;\r\n\r\n    /**\r\n     * Create a new PerturbNormalBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        // Vertex\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.Vector4, false);\r\n        this.registerInput(\"worldTangent\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.Vector2, false);\r\n        this.registerInput(\"normalMapColor\", NodeMaterialBlockConnectionPointTypes.Color3, false);\r\n        this.registerInput(\"strength\", NodeMaterialBlockConnectionPointTypes.Float, false);\r\n        this.registerInput(\"viewDirection\", NodeMaterialBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"parallaxScale\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"parallaxHeight\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\r\n            \"TBN\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"TBN\", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, \"TBNBlock\")\r\n        );\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix, true);\r\n\r\n        // Fragment\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"uvOffset\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PerturbNormalBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the world tangent input component\r\n     */\r\n    public get worldTangent(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal map color input component\r\n     */\r\n    public get normalMapColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the strength input component\r\n     */\r\n    public get strength(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the view direction input component\r\n     */\r\n    public get viewDirection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the parallax scale input component\r\n     */\r\n    public get parallaxScale(): NodeMaterialConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the parallax height input component\r\n     */\r\n    public get parallaxHeight(): NodeMaterialConnectionPoint {\r\n        return this._inputs[8];\r\n    }\r\n\r\n    /**\r\n     * Gets the TBN input component\r\n     */\r\n    public get TBN(): NodeMaterialConnectionPoint {\r\n        return this._inputs[9];\r\n    }\r\n\r\n    /**\r\n     * Gets the World input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[10];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv offset output component\r\n     */\r\n    public get uvOffset(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block\r\n     * @param state - defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/bumpFragment\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/bumpFragmentMainFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/bumpFragmentFunctions\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/bumpFragment\"),\r\n                import(\"../../../../Shaders/ShadersInclude/bumpFragmentMainFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/bumpFragmentFunctions\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - defines the list of defines to update\r\n     * @param nodeMaterial - defines the node material requesting the update\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial) {\r\n        const normalSamplerName = (this.normalMapColor.connectedPoint!._ownerBlock as TextureBlock).samplerName;\r\n        const useParallax =\r\n            this.viewDirection.isConnected && ((this.useParallaxOcclusion && !!normalSamplerName) || (!this.useParallaxOcclusion && this.parallaxHeight.isConnected));\r\n\r\n        defines.setValue(\"BUMP\", true);\r\n        defines.setValue(\"PARALLAX\", useParallax, true);\r\n        defines.setValue(\"PARALLAX_RHS\", nodeMaterial.getScene().useRightHandedSystem, true);\r\n        defines.setValue(\"PARALLAXOCCLUSION\", this.useParallaxOcclusion, true);\r\n        defines.setValue(\"OBJECTSPACE_NORMALMAP\", this.useObjectSpaceNormalMap, true);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - defines the effect to bind data to\r\n     * @param nodeMaterial - defines the node material\r\n     * @param mesh - defines the mesh to bind data for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (nodeMaterial.getScene()._mirroredCameraPosition) {\r\n            effect.setFloat2(this._tangentSpaceParameterName, this.invertX ? 1.0 : -1.0, this.invertY ? 1.0 : -1.0);\r\n        } else {\r\n            effect.setFloat2(this._tangentSpaceParameterName, this.invertX ? -1.0 : 1.0, this.invertY ? -1.0 : 1.0);\r\n        }\r\n\r\n        if (mesh) {\r\n            effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1);\r\n\r\n            if (this.useObjectSpaceNormalMap && !this.world.isConnected) {\r\n                // World default to the mesh world matrix\r\n                effect.setMatrix(this._worldMatrixName, mesh.getWorldMatrix());\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - defines the hosting NodeMaterial\r\n     * @param additionalFilteringInfo - defines additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.uv.isConnected) {\r\n            let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"uv\" && additionalFilteringInfo(b));\r\n\r\n            if (!uvInput) {\r\n                uvInput = new InputBlock(\"uv\");\r\n                uvInput.setAsAttribute();\r\n            }\r\n            uvInput.output.connectTo(this.uv);\r\n        }\r\n\r\n        if (!this.strength.isConnected) {\r\n            const strengthInput = new InputBlock(\"strength\");\r\n            strengthInput.value = 1.0;\r\n            strengthInput.output.connectTo(this.strength);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const comments = `//${this.name}`;\r\n        const uv = this.uv;\r\n        const worldPosition = this.worldPosition;\r\n        const worldNormal = this.worldNormal;\r\n        const worldTangent = this.worldTangent;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const mat3 = isWebGPU ? \"mat3x3f\" : \"mat3\";\r\n        const fSuffix = isWebGPU ? \"f\" : \"\";\r\n        const uniformPrefix = isWebGPU ? \"uniforms.\" : \"\";\r\n        const fragmentInputsPrefix = isWebGPU ? \"fragmentInputs.\" : \"\";\r\n\r\n        state.sharedData.blocksWithDefines.push(this);\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        this._tangentSpaceParameterName = state._getFreeDefineName(\"tangentSpaceParameter\");\r\n\r\n        state._emitUniformFromString(this._tangentSpaceParameterName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        this._tangentCorrectionFactorName = state._getFreeDefineName(\"tangentCorrectionFactor\");\r\n\r\n        state._emitUniformFromString(this._tangentCorrectionFactorName, NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._worldMatrixName = state._getFreeDefineName(\"perturbNormalWorldMatrix\");\r\n\r\n        state._emitUniformFromString(this._worldMatrixName, NodeMaterialBlockConnectionPointTypes.Matrix);\r\n\r\n        let normalSamplerName = null;\r\n        if (this.normalMapColor.connectedPoint) {\r\n            normalSamplerName = (this.normalMapColor.connectedPoint._ownerBlock as TextureBlock).samplerName;\r\n        }\r\n        const useParallax =\r\n            this.viewDirection.isConnected && ((this.useParallaxOcclusion && !!normalSamplerName) || (!this.useParallaxOcclusion && this.parallaxHeight.isConnected));\r\n\r\n        const replaceForParallaxInfos = !this.parallaxScale.isConnectedToInputBlock\r\n            ? \"0.05\"\r\n            : this.parallaxScale.connectInputBlock!.isConstant\r\n              ? state._emitFloat(this.parallaxScale.connectInputBlock!.value)\r\n              : this.parallaxScale.associatedVariableName;\r\n\r\n        const replaceForBumpInfos =\r\n            this.strength.isConnectedToInputBlock && this.strength.connectInputBlock!.isConstant\r\n                ? `\\n#if !defined(NORMALXYSCALE)\\n1.0/\\n#endif\\n${state._emitFloat(this.strength.connectInputBlock!.value)}`\r\n                : `\\n#if !defined(NORMALXYSCALE)\\n1.0/\\n#endif\\n${this.strength.associatedVariableName}`;\r\n\r\n        if (!isWebGPU) {\r\n            state._emitExtension(\"derivatives\", \"#extension GL_OES_standard_derivatives : enable\");\r\n        }\r\n\r\n        const tangentReplaceString = { search: /defined\\(TANGENT\\)/g, replace: worldTangent.isConnected ? \"defined(TANGENT)\" : \"defined(IGNORE)\" };\r\n        const tbnVarying = { search: /varying mat3 vTBN;/g, replace: \"\" };\r\n        const normalMatrixReplaceString = { search: isWebGPU ? /uniform normalMatrix: mat4x4f;/g : /uniform mat4 normalMatrix;/g, replace: \"\" };\r\n\r\n        const tbn = this.TBN;\r\n        if (tbn.isConnected) {\r\n            state.compilationString += `\r\n            #ifdef TBNBLOCK\r\n            ${isWebGPU ? \"var\" : \"mat3\"} vTBN = ${tbn.associatedVariableName};\r\n            #endif\r\n            `;\r\n        } else if (worldTangent.isConnected) {\r\n            state.compilationString += `${state._declareLocalVar(\"tbnNormal\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${worldNormal.associatedVariableName}.xyz);\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"tbnTangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${worldTangent.associatedVariableName}.xyz);\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"tbnBitangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = cross(tbnNormal, tbnTangent) * ${uniformPrefix}${this._tangentCorrectionFactorName};\\n`;\r\n            state.compilationString += `${isWebGPU ? \"var\" : \"mat3\"} vTBN = ${mat3}(tbnTangent, tbnBitangent, tbnNormal);\\n`;\r\n        }\r\n\r\n        let replaceStrings = [tangentReplaceString, tbnVarying, normalMatrixReplaceString];\r\n\r\n        if (isWebGPU) {\r\n            replaceStrings.push({ search: /varying vTBN0: vec3f;/g, replace: \"\" });\r\n            replaceStrings.push({ search: /varying vTBN1: vec3f;/g, replace: \"\" });\r\n            replaceStrings.push({ search: /varying vTBN2: vec3f;/g, replace: \"\" });\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"bumpFragmentMainFunctions\", comments, {\r\n            replaceStrings: replaceStrings,\r\n        });\r\n\r\n        const replaceString0 = isWebGPU\r\n            ? \"fn parallaxOcclusion(vViewDirCoT: vec3f, vNormalCoT: vec3f, texCoord: vec2f, parallaxScale:f32, bumpSampler: texture_2d<f32>, bumpSamplerSampler: sampler)\"\r\n            : \"#define inline\\nvec2 parallaxOcclusion(vec3 vViewDirCoT, vec3 vNormalCoT, vec2 texCoord, float parallaxScale, sampler2D bumpSampler)\";\r\n\r\n        const searchExp0 = isWebGPU\r\n            ? /fn parallaxOcclusion\\(vViewDirCoT: vec3f,vNormalCoT: vec3f,texCoord: vec2f,parallaxScale: f32\\)/g\r\n            : /vec2 parallaxOcclusion\\(vec3 vViewDirCoT,vec3 vNormalCoT,vec2 texCoord,float parallaxScale\\)/g;\r\n\r\n        const replaceString1 = isWebGPU\r\n            ? \"fn parallaxOffset(viewDir: vec3f, heightScale: f32, height_: f32)\"\r\n            : \"vec2 parallaxOffset(vec3 viewDir, float heightScale, float height_)\";\r\n\r\n        const searchExp1 = isWebGPU ? /fn parallaxOffset\\(viewDir: vec3f,heightScale: f32\\)/g : /vec2 parallaxOffset\\(vec3 viewDir,float heightScale\\)/g;\r\n\r\n        state._emitFunctionFromInclude(\"bumpFragmentFunctions\", comments, {\r\n            replaceStrings: [\r\n                { search: /#include<samplerFragmentDeclaration>\\(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_SAMPLERNAME_,bump\\)/g, replace: \"\" },\r\n                { search: /uniform sampler2D bumpSampler;/g, replace: \"\" },\r\n                {\r\n                    search: searchExp0,\r\n                    replace: replaceString0,\r\n                },\r\n                { search: searchExp1, replace: replaceString1 },\r\n                { search: /(?:texture2D|textureSample|TEXRD)\\(bumpSampler,.*?vBumpUV\\)\\.w/g, replace: \"height_\" },\r\n            ],\r\n        });\r\n\r\n        const normalRead = isWebGPU ? `textureSample(${normalSamplerName}, ${normalSamplerName + Constants.AUTOSAMPLERSUFFIX}` : `texture2D(${normalSamplerName}`;\r\n\r\n        const uvForPerturbNormal = !useParallax || !normalSamplerName ? this.normalMapColor.associatedVariableName : `${normalRead}, ${uv.associatedVariableName} + uvOffset).xyz`;\r\n\r\n        const tempOutput = state._getFreeVariableName(\"tempOutput\");\r\n        state.compilationString += state._declareLocalVar(tempOutput, NodeMaterialBlockConnectionPointTypes.Vector3) + ` = vec3${fSuffix}(0.);\\n`;\r\n\r\n        replaceStrings = [\r\n            {\r\n                search: new RegExp(`(?:${isWebGPU ? \"textureSample\" : \"texture2D\"}|TEXRD)\\\\(bumpSampler${isWebGPU ? \",bumpSamplerSampler,fragmentInputs.\" : \",\"}vBumpUV\\\\)`, \"g\"),\r\n                replace: `${uvForPerturbNormal}`,\r\n            },\r\n            {\r\n                search: /#define CUSTOM_FRAGMENT_BUMP_FRAGMENT/g,\r\n                replace: `${state._declareLocalVar(\"normalMatrix\", NodeMaterialBlockConnectionPointTypes.Matrix)} = toNormalMatrix(${this.world.isConnected ? this.world.associatedVariableName : uniformPrefix + this._worldMatrixName});`,\r\n            },\r\n            {\r\n                search: new RegExp(\r\n                    `perturbNormal\\\\(TBN,(?:${isWebGPU ? \"textureSample\" : \"texture2D\"}|TEXRD)\\\\(bumpSampler${isWebGPU ? \",bumpSamplerSampler,fragmentInputs.\" : \",\"}vBumpUV\\\\+uvOffset\\\\).xyz,${uniformPrefix}vBumpInfos.y\\\\)`,\r\n                    \"g\"\r\n                ),\r\n                replace: `perturbNormal(TBN, ${uvForPerturbNormal}, ${uniformPrefix}vBumpInfos.y)`,\r\n            },\r\n            {\r\n                search: /parallaxOcclusion\\(invTBN\\*-viewDirectionW,invTBN\\*normalW,(fragmentInputs\\.)?vBumpUV,(uniforms\\.)?vBumpInfos.z\\)/g,\r\n                replace: `parallaxOcclusion((invTBN * -viewDirectionW), (invTBN * normalW), ${fragmentInputsPrefix}vBumpUV, ${uniformPrefix}vBumpInfos.z, ${\r\n                    isWebGPU\r\n                        ? useParallax && this.useParallaxOcclusion\r\n                            ? `${normalSamplerName}, ${normalSamplerName + Constants.AUTOSAMPLERSUFFIX}`\r\n                            : \"bump, bumpSampler\"\r\n                        : useParallax && this.useParallaxOcclusion\r\n                          ? normalSamplerName\r\n                          : \"bumpSampler\"\r\n                })`,\r\n            },\r\n            {\r\n                search: /parallaxOffset\\(invTBN\\*viewDirectionW,vBumpInfos\\.z\\)/g,\r\n                replace: `parallaxOffset(invTBN * viewDirectionW, ${uniformPrefix}vBumpInfos.z, ${useParallax ? this.parallaxHeight.associatedVariableName : \"0.\"})`,\r\n            },\r\n            { search: isWebGPU ? /uniforms.vBumpInfos.y/g : /vBumpInfos.y/g, replace: replaceForBumpInfos },\r\n            { search: isWebGPU ? /uniforms.vBumpInfos.z/g : /vBumpInfos.z/g, replace: replaceForParallaxInfos },\r\n            { search: /normalW=/g, replace: tempOutput + \" = \" },\r\n            isWebGPU\r\n                ? {\r\n                      search: /mat3x3f\\(uniforms\\.normalMatrix\\[0\\].xyz,uniforms\\.normalMatrix\\[1\\]\\.xyz,uniforms\\.normalMatrix\\[2\\].xyz\\)\\*normalW/g,\r\n                      replace: `${mat3}(normalMatrix[0].xyz, normalMatrix[1].xyz, normalMatrix[2].xyz) * ` + tempOutput,\r\n                  }\r\n                : {\r\n                      search: /mat3\\(normalMatrix\\)\\*normalW/g,\r\n                      replace: `${mat3}(normalMatrix) * ` + tempOutput,\r\n                  },\r\n            { search: /normalW/g, replace: worldNormal.associatedVariableName + \".xyz\" },\r\n            { search: /viewDirectionW/g, replace: useParallax ? this.viewDirection.associatedVariableName : `vec3${fSuffix}(0.)` },\r\n            tangentReplaceString,\r\n        ];\r\n\r\n        if (isWebGPU) {\r\n            replaceStrings.push({ search: /fragmentInputs.vBumpUV/g, replace: uv.associatedVariableName });\r\n            replaceStrings.push({ search: /input.vPositionW/g, replace: worldPosition.associatedVariableName + \".xyz\" });\r\n            replaceStrings.push({ search: /uniforms.vTangentSpaceParams/g, replace: uniformPrefix + this._tangentSpaceParameterName });\r\n            replaceStrings.push({ search: /var TBN: mat3x3f=mat3x3<f32>\\(input.vTBN0,input.vTBN1,input.vTBN2\\);/g, replace: `var TBN = vTBN;` });\r\n        } else {\r\n            replaceStrings.push({ search: /vBumpUV/g, replace: uv.associatedVariableName });\r\n            replaceStrings.push({ search: /vPositionW/g, replace: worldPosition.associatedVariableName + \".xyz\" });\r\n            replaceStrings.push({ search: /vTangentSpaceParams/g, replace: uniformPrefix + this._tangentSpaceParameterName });\r\n        }\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"bumpFragment\", comments, {\r\n            replaceStrings: replaceStrings,\r\n        });\r\n\r\n        state.compilationString += state._declareOutput(this.output) + ` = vec4${fSuffix}(${tempOutput}, 0.);\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.invertX = ${this.invertX};\\n`;\r\n\r\n        codeString += `${this._codeVariableName}.invertY = ${this.invertY};\\n`;\r\n        codeString += `${this._codeVariableName}.useParallaxOcclusion = ${this.useParallaxOcclusion};\\n`;\r\n        codeString += `${this._codeVariableName}.useObjectSpaceNormalMap = ${this.useObjectSpaceNormalMap};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.invertX = this.invertX;\r\n        serializationObject.invertY = this.invertY;\r\n        serializationObject.useParallaxOcclusion = this.useParallaxOcclusion;\r\n        serializationObject.useObjectSpaceNormalMap = this.useObjectSpaceNormalMap;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - defines the serialized object\r\n     * @param scene - defines the hosting scene\r\n     * @param rootUrl - defines the root URL to use for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.invertX = serializationObject.invertX;\r\n        this.invertY = serializationObject.invertY;\r\n        this.useParallaxOcclusion = !!serializationObject.useParallaxOcclusion;\r\n        this.useObjectSpaceNormalMap = !!serializationObject.useObjectSpaceNormalMap;\r\n\r\n        this.parallaxScale._isInactive = this.useParallaxOcclusion;\r\n        this.parallaxHeight._isInactive = this.useParallaxOcclusion;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for perturbNormalBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPerturbNormalBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PerturbNormalBlock\", PerturbNormalBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used to discard a pixel if a value is smaller than a cutoff\r\n */\r\nexport class DiscardBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new DiscardBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment, true);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"cutoff\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DiscardBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the cutoff input component\r\n     */\r\n    public get cutoff(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        state.sharedData.hints.needAlphaTesting = true;\r\n\r\n        if (!this.cutoff.isConnected || !this.value.isConnected) {\r\n            return;\r\n        }\r\n\r\n        state.compilationString += `if (${this.value.associatedVariableName} < ${this.cutoff.associatedVariableName}) { discard; }\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for discardBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDiscardBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DiscardBlock\", DiscardBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used to test if the fragment shader is front facing\r\n */\r\nexport class FrontFacingBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new FrontFacingBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"FrontFacingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            state.sharedData.raiseBuildError(\"FrontFacingBlock must only be used in a fragment shader\");\r\n            return this;\r\n        }\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = ${state._generateTernary(\"1.0\", \"0.0\", state.shaderLanguage === ShaderLanguage.GLSL ? \"gl_FrontFacing\" : \"fragmentInputs.frontFacing\")};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for frontFacingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFrontFacingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FrontFacingBlock\", FrontFacingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get the derivative value on x and y of a given input\r\n */\r\nexport class DerivativeBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new DerivativeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false);\r\n        this.registerOutput(\"dx\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n        this.registerOutput(\"dy\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._outputs[1]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DerivativeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the derivative output on x\r\n     */\r\n    public get dx(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the derivative output on y\r\n     */\r\n    public get dy(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const dx = this._outputs[0];\r\n        const dy = this._outputs[1];\r\n\r\n        state._emitExtension(\"derivatives\", \"#extension GL_OES_standard_derivatives : enable\");\r\n        let dpdx = \"dFdx\";\r\n        let dpdy = \"dFdy\";\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            dpdx = \"dpdx\";\r\n            dpdy = \"dpdy\";\r\n        }\r\n\r\n        if (dx.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(dx) + ` = ${dpdx}(${this.input.associatedVariableName});\\n`;\r\n        }\r\n\r\n        if (dy.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(dy) + ` = ${dpdy}(${this.input.associatedVariableName});\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for derivativeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDerivativeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DerivativeBlock\", DerivativeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to make gl_FragCoord available\r\n */\r\nexport class FragCoordBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new FragCoordBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"xy\", NodeMaterialBlockConnectionPointTypes.Vector2, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"xyz\", NodeMaterialBlockConnectionPointTypes.Vector3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"xyzw\", NodeMaterialBlockConnectionPointTypes.Vector4, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"x\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"y\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"z\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"w\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"FragCoordBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component\r\n     */\r\n    public get xy(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component\r\n     */\r\n    public get xyz(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component\r\n     */\r\n    public get xyzw(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component\r\n     */\r\n    public get z(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected writeOutputs(state: NodeMaterialBuildState): string {\r\n        let code = \"\";\r\n\r\n        const coord = state.shaderLanguage === ShaderLanguage.WGSL ? \"fragmentInputs.position\" : \"gl_FragCoord\";\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                code += `${state._declareOutput(output)} = ${coord}.${output.name};\\n`;\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            state.sharedData.raiseBuildError(\"FragCoordBlock must only be used in a fragment shader\");\r\n            return this;\r\n        }\r\n\r\n        state.compilationString += this.writeOutputs(state);\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fragCoordBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFragCoordBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FragCoordBlock\", FragCoordBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to transform a vector3 or a vector4 into screen space\r\n */\r\nexport class ScreenSpaceBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ScreenSpaceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\"vector\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"worldViewProjection\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"x\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"y\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ScreenSpaceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the vector input\r\n     */\r\n    public get vector(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the worldViewProjection transform input\r\n     */\r\n    public get worldViewProjection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the x output component\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the y output component\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - defines the hosting NodeMaterial\r\n     * @param additionalFilteringInfo - defines additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.worldViewProjection.isConnected) {\r\n            let worldViewProjectionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.WorldViewProjection && additionalFilteringInfo(b));\r\n\r\n            if (!worldViewProjectionInput) {\r\n                worldViewProjectionInput = new InputBlock(\"worldViewProjection\");\r\n                worldViewProjectionInput.setAsSystemValue(NodeMaterialSystemValues.WorldViewProjection);\r\n            }\r\n            worldViewProjectionInput.output.connectTo(this.worldViewProjection);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const vector = this.vector;\r\n        const worldViewProjection = this.worldViewProjection;\r\n\r\n        if (!vector.connectedPoint) {\r\n            return;\r\n        }\r\n\r\n        const worldViewProjectionName = worldViewProjection.associatedVariableName;\r\n\r\n        const tempVariableName = state._getFreeVariableName(\"screenSpaceTemp\");\r\n\r\n        switch (vector.connectedPoint.type) {\r\n            case NodeMaterialBlockConnectionPointTypes.Vector3:\r\n                state.compilationString += `${state._declareLocalVar(tempVariableName, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${worldViewProjectionName} * vec4${state.fSuffix}(${vector.associatedVariableName}, 1.0);\\n`;\r\n                break;\r\n            case NodeMaterialBlockConnectionPointTypes.Vector4:\r\n                state.compilationString += `${state._declareLocalVar(tempVariableName, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${worldViewProjectionName} * ${vector.associatedVariableName};\\n`;\r\n                break;\r\n        }\r\n\r\n        state.compilationString += `${tempVariableName} = vec4${state.fSuffix}(${tempVariableName}.xy / ${tempVariableName}.w, ${tempVariableName}.zw);`;\r\n        state.compilationString += `${tempVariableName} = vec4${state.fSuffix}(${tempVariableName}.xy * 0.5 + vec2${state.fSuffix}(0.5, 0.5), ${tempVariableName}.zw);`;\r\n\r\n        if (this.output.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.output) + ` = ${tempVariableName}.xy;\\n`;\r\n        }\r\n        if (this.x.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.x) + ` = ${tempVariableName}.x;\\n`;\r\n        }\r\n        if (this.y.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.y) + ` = ${tempVariableName}.y;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for screenSpaceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScreenSpaceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ScreenSpaceBlock\", ScreenSpaceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { Vector2 } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to generate a twirl\r\n */\r\nexport class TwirlBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new TwirlBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"strength\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"center\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"offset\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"x\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"y\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TwirlBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the strength component\r\n     */\r\n    public get strength(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the center component\r\n     */\r\n    public get center(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset component\r\n     */\r\n    public get offset(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the x output component\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the y output component\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     */\r\n    public override autoConfigure() {\r\n        if (!this.center.isConnected) {\r\n            const centerInput = new InputBlock(\"center\");\r\n            centerInput.value = new Vector2(0.5, 0.5);\r\n\r\n            centerInput.output.connectTo(this.center);\r\n        }\r\n\r\n        if (!this.strength.isConnected) {\r\n            const strengthInput = new InputBlock(\"strength\");\r\n            strengthInput.value = 1.0;\r\n\r\n            strengthInput.output.connectTo(this.strength);\r\n        }\r\n\r\n        if (!this.offset.isConnected) {\r\n            const offsetInput = new InputBlock(\"offset\");\r\n            offsetInput.value = new Vector2(0, 0);\r\n\r\n            offsetInput.output.connectTo(this.offset);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const tempDelta = state._getFreeVariableName(\"delta\");\r\n        const tempAngle = state._getFreeVariableName(\"angle\");\r\n        const tempX = state._getFreeVariableName(\"x\");\r\n        const tempY = state._getFreeVariableName(\"y\");\r\n        const tempResult = state._getFreeVariableName(\"result\");\r\n\r\n        state.compilationString += `        \r\n            ${state._declareLocalVar(tempDelta, NodeMaterialBlockConnectionPointTypes.Vector2)} = ${this.input.associatedVariableName} - ${this.center.associatedVariableName};\r\n            ${state._declareLocalVar(tempAngle, NodeMaterialBlockConnectionPointTypes.Float)} = ${this.strength.associatedVariableName} * length(${tempDelta});\r\n            ${state._declareLocalVar(tempX, NodeMaterialBlockConnectionPointTypes.Float)} = cos(${tempAngle}) * ${tempDelta}.x - sin(${tempAngle}) * ${tempDelta}.y;\r\n            ${state._declareLocalVar(tempY, NodeMaterialBlockConnectionPointTypes.Float)} = sin(${tempAngle}) * ${tempDelta}.x + cos(${tempAngle}) * ${tempDelta}.y;\r\n            ${state._declareLocalVar(tempResult, NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2(${tempX} + ${this.center.associatedVariableName}.x + ${this.offset.associatedVariableName}.x, ${tempY} + ${this.center.associatedVariableName}.y + ${this.offset.associatedVariableName}.y);\r\n        `;\r\n\r\n        if (this.output.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.output) + ` = ${tempResult};\\n`;\r\n        }\r\n\r\n        if (this.x.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.x) + ` = ${tempResult}.x;\\n`;\r\n        }\r\n\r\n        if (this.y.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.y) + ` = ${tempResult}.y;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for twirlBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTwirlBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TwirlBlock\", TwirlBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to convert a height vector to a normal\r\n */\r\nexport class HeightToNormalBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new HeightToNormalBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"worldTangent\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"xyz\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._inputs[3].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Defines if the output should be generated in world or tangent space.\r\n     * Note that in tangent space the result is also scaled by 0.5 and offsetted by 0.5 so that it can directly be used as a PerturbNormal.normalMapColor input\r\n     */\r\n    @editableInPropertyPage(\"Generate in world space instead of tangent space\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { notifiers: { update: true } })\r\n    public generateInWorldSpace: boolean = false;\r\n\r\n    /**\r\n     * Defines that the worldNormal input will be normalized by the HeightToNormal block before being used\r\n     */\r\n    @editableInPropertyPage(\"Force normalization for the worldNormal input\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { notifiers: { update: true } })\r\n    public automaticNormalizationNormal: boolean = true;\r\n\r\n    /**\r\n     * Defines that the worldTangent input will be normalized by the HeightToNormal block before being used\r\n     */\r\n    @editableInPropertyPage(\"Force normalization for the worldTangent input\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { notifiers: { update: true } })\r\n    public automaticNormalizationTangent: boolean = true;\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"HeightToNormalBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the position component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the tangent component\r\n     */\r\n    public get worldTangent(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component\r\n     */\r\n    public get xyz(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const fPrefix = state.fSuffix;\r\n\r\n        if (!this.generateInWorldSpace && !this.worldTangent.isConnected) {\r\n            state.sharedData.raiseBuildError(`You must connect the 'worldTangent' input of the ${this.name} block!`);\r\n        }\r\n\r\n        const startCode = this.generateInWorldSpace\r\n            ? \"\"\r\n            : `\r\n            vec3 biTangent = cross(norm, tgt);\r\n            mat3 TBN = mat3(tgt, biTangent, norm);\r\n            `;\r\n\r\n        const endCode = this.generateInWorldSpace\r\n            ? \"\"\r\n            : `\r\n            result = TBN * result;\r\n            result = result * vec3(0.5) + vec3(0.5);\r\n            `;\r\n\r\n        let heightToNormal = `\r\n            vec4 heightToNormal(float height, vec3 position, vec3 tangent, vec3 normal) {\r\n                vec3 tgt = ${this.automaticNormalizationTangent ? \"normalize(tangent);\" : \"tangent;\"}\r\n                vec3 norm = ${this.automaticNormalizationNormal ? \"normalize(normal);\" : \"normal;\"}\r\n                ${startCode}\r\n                vec3 worlddX = dFdx(position);\r\n                vec3 worlddY = dFdy(position);\r\n                vec3 crossX = cross(norm, worlddX);\r\n                vec3 crossY = cross(worlddY, norm);\r\n                float d = abs(dot(crossY, worlddX));\r\n                vec3 inToNormal = vec3(((((height + dFdx(height)) - height) * crossY) + (((height + dFdy(height)) - height) * crossX)) * sign(d));\r\n                inToNormal.y *= -1.0;\r\n                vec3 result = normalize((d * norm) - inToNormal);\r\n                ${endCode}\r\n                return vec4(result, 0.);\r\n            }`;\r\n\r\n        if (isWebGPU) {\r\n            heightToNormal = state._babylonSLtoWGSL(heightToNormal);\r\n        } else {\r\n            state._emitExtension(\"derivatives\", \"#extension GL_OES_standard_derivatives : enable\");\r\n        }\r\n        state._emitFunction(\"heightToNormal\", heightToNormal, \"// heightToNormal\");\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = heightToNormal(${this.input.associatedVariableName}, ${this.worldPosition.associatedVariableName}, ${\r\n                this.worldTangent.isConnected ? this.worldTangent.associatedVariableName : `vec3${fPrefix}(0.)`\r\n            }.xyz, ${this.worldNormal.associatedVariableName});\\n`;\r\n\r\n        if (this.xyz.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.xyz) + ` = ${this.output.associatedVariableName}.xyz;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n        codeString += `${this._codeVariableName}.generateInWorldSpace = ${this.generateInWorldSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.automaticNormalizationNormal = ${this.automaticNormalizationNormal};\\n`;\r\n        codeString += `${this._codeVariableName}.automaticNormalizationTangent = ${this.automaticNormalizationTangent};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.generateInWorldSpace = this.generateInWorldSpace;\r\n        serializationObject.automaticNormalizationNormal = this.automaticNormalizationNormal;\r\n        serializationObject.automaticNormalizationTangent = this.automaticNormalizationTangent;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.generateInWorldSpace = serializationObject.generateInWorldSpace;\r\n        this.automaticNormalizationNormal = serializationObject.automaticNormalizationNormal;\r\n        this.automaticNormalizationTangent = serializationObject.automaticNormalizationTangent;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for heightToNormalBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterHeightToNormalBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.HeightToNormalBlock\", HeightToNormalBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used to write the fragment depth\r\n */\r\nexport class FragDepthBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new FragDepthBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment, true);\r\n\r\n        this.registerInput(\"depth\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"worldPos\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"viewProjection\", NodeMaterialBlockConnectionPointTypes.Matrix, true);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"FragDepthBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the depth input component\r\n     */\r\n    public get depth(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the worldPos input component\r\n     */\r\n    public get worldPos(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the viewProjection input component\r\n     */\r\n    public get viewProjection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const fragDepth = state.shaderLanguage === ShaderLanguage.GLSL ? \"gl_FragDepth\" : \"fragmentOutputs.fragDepth\";\r\n\r\n        if (this.depth.isConnected) {\r\n            state.compilationString += `${fragDepth} = ${this.depth.associatedVariableName};\\n`;\r\n        } else if (this.worldPos.isConnected && this.viewProjection.isConnected) {\r\n            state.compilationString += `\r\n                ${state._declareLocalVar(\"p\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this.viewProjection.associatedVariableName} * ${this.worldPos.associatedVariableName};\r\n                ${state._declareLocalVar(\"v\", NodeMaterialBlockConnectionPointTypes.Float)} = p.z / p.w;\r\n                #ifndef IS_NDC_HALF_ZRANGE\r\n                    v = v * 0.5 + 0.5;\r\n                #endif\r\n                ${fragDepth} = v;\r\n    \r\n            `;\r\n        } else {\r\n            Logger.Warn(\"FragDepthBlock: either the depth input or both the worldPos and viewProjection inputs must be connected!\");\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fragDepthBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFragDepthBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FragDepthBlock\", FragDepthBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to output the depth to a shadow map\r\n */\r\nexport class ShadowMapBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ShadowMapBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false);\r\n        this.registerInput(\"viewProjection\", NodeMaterialBlockConnectionPointTypes.Matrix, false);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerOutput(\"depth\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this.worldNormal.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ShadowMapBlock\";\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"vPositionWSM\");\r\n        state._excludeVariableName(\"lightDataSM\");\r\n        state._excludeVariableName(\"biasAndScaleSM\");\r\n        state._excludeVariableName(\"depthValuesSM\");\r\n        state._excludeVariableName(\"clipPos\");\r\n        state._excludeVariableName(\"worldPos\");\r\n        state._excludeVariableName(\"zSM\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/shadowMapVertexMetric\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/packingFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/shadowMapFragment\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/shadowMapVertexMetric\"),\r\n                import(\"../../../../Shaders/ShadersInclude/packingFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/shadowMapFragment\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the view x projection input component\r\n     */\r\n    public get viewProjection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth output component\r\n     */\r\n    public get depth(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const comments = `//${this.name}`;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        state._emitUniformFromString(\"biasAndScaleSM\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        state._emitUniformFromString(\"lightDataSM\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        state._emitUniformFromString(\"depthValuesSM\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        state._emitFunctionFromInclude(\"packingFunctions\", comments);\r\n\r\n        state.compilationString += `${state._declareLocalVar(\"worldPos\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this.worldPosition.associatedVariableName};\\n`;\r\n        state.compilationString += `${state._declareLocalVar(\"vPositionWSM\", NodeMaterialBlockConnectionPointTypes.Vector3)};\\n`;\r\n        state.compilationString += `${state._declareLocalVar(\"vDepthMetricSM\", NodeMaterialBlockConnectionPointTypes.Float)} = 0.0;\\n`;\r\n        state.compilationString += `${state._declareLocalVar(\"zSM\", NodeMaterialBlockConnectionPointTypes.Float)};\\n`;\r\n\r\n        if (this.worldNormal.isConnected) {\r\n            state.compilationString += `${state._declareLocalVar(\"vNormalW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this.worldNormal.associatedVariableName}.xyz;\\n`;\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowMapVertexNormalBias\", comments);\r\n        }\r\n\r\n        state.compilationString += `${state._declareLocalVar(\"clipPos\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this.viewProjection.associatedVariableName} * worldPos;\\n`;\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"shadowMapVertexMetric\", comments, {\r\n            replaceStrings: [\r\n                {\r\n                    search: /gl_Position/g,\r\n                    replace: \"clipPos\",\r\n                },\r\n                {\r\n                    search: /vertexOutputs.position/g,\r\n                    replace: \"clipPos\",\r\n                },\r\n                {\r\n                    search: /vertexOutputs\\.vDepthMetricSM/g,\r\n                    replace: \"vDepthMetricSM\",\r\n                },\r\n            ],\r\n        });\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"shadowMapFragment\", comments, {\r\n            replaceStrings: [\r\n                {\r\n                    search: /return;/g,\r\n                    replace: \"\",\r\n                },\r\n                {\r\n                    search: /fragmentInputs\\.vDepthMetricSM/g,\r\n                    replace: \"vDepthMetricSM\",\r\n                },\r\n            ],\r\n        });\r\n        const output = isWebGPU ? \"fragmentOutputs.fragDepth\" : \"gl_FragDepth\";\r\n        state.compilationString += `\r\n            #if SM_DEPTHTEXTURE == 1\r\n                #ifdef IS_NDC_HALF_ZRANGE\r\n                    ${output} = (clipPos.z / clipPos.w);\r\n                #else\r\n                    ${output} = (clipPos.z / clipPos.w) * 0.5 + 0.5;\r\n                #endif\r\n            #endif\r\n        `;\r\n\r\n        state.compilationString += `${state._declareOutput(this.depth)} = vec3${state.fSuffix}(depthSM, 1., 1.);\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for shadowMapBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterShadowMapBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ShadowMapBlock\", ShadowMapBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to output values on the prepass textures\r\n * @see https://playground.babylonjs.com/#WW65SN#9\r\n */\r\nexport class PrePassOutputBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new PrePassOutputBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment, true);\r\n\r\n        this.registerInput(\"viewDepth\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"screenDepth\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"localPosition\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"viewNormal\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"reflectivity\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"velocity\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"velocityLinear\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.inputs[2].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.inputs[3].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.inputs[4].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.inputs[5].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.inputs[6].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n        this.inputs[7].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.inputs[8].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PrePassOutputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the view depth component\r\n     */\r\n    public get viewDepth(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the screen depth component\r\n     */\r\n    public get screenDepth(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the world position component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the position in local space component\r\n     */\r\n    public get localPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the view normal component\r\n     */\r\n    public get viewNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the reflectivity component\r\n     */\r\n    public get reflectivity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the velocity component\r\n     */\r\n    public get velocity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the linear velocity component\r\n     */\r\n    public get velocityLinear(): NodeMaterialConnectionPoint {\r\n        return this._inputs[8];\r\n    }\r\n\r\n    private _getFragData(isWebGPU: boolean, index: number) {\r\n        return isWebGPU ? `fragmentOutputs.fragData${index}` : `gl_FragData[${index}]`;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const worldPosition = this.worldPosition;\r\n        const localPosition = this.localPosition;\r\n        const viewNormal = this.viewNormal;\r\n        const worldNormal = this.worldNormal;\r\n        const viewDepth = this.viewDepth;\r\n        const reflectivity = this.reflectivity;\r\n        const screenDepth = this.screenDepth;\r\n        const velocity = this.velocity;\r\n        const velocityLinear = this.velocityLinear;\r\n\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        const comments = `//${this.name}`;\r\n        const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n        state._emitUniformFromString(\"meshBlendTag\", NodeMaterialBlockConnectionPointTypes.Int, \"PREPASS_MESH_BLEND_TAG\");\r\n\r\n        state.compilationString += `#if defined(PREPASS)\\r\\n`;\r\n        state.compilationString += isWebGPU ? `var fragData: array<vec4<f32>, SCENE_MRT_COUNT>;\\r\\n` : `vec4 fragData[SCENE_MRT_COUNT];\\r\\n`;\r\n\r\n        state.compilationString += `#ifdef PREPASS_DEPTH\\r\\n`;\r\n        if (viewDepth.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_DEPTH_INDEX] = ${vec4}(${viewDepth.associatedVariableName}, 0.0, 0.0, 1.0);\\r\\n`;\r\n        } else {\r\n            // We have to write something on the viewDepth output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_DEPTH_INDEX] = ${vec4}(0.0, 0.0, 0.0, 0.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_SCREENSPACE_DEPTH\\r\\n`;\r\n        if (screenDepth.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_SCREENSPACE_DEPTH_INDEX] = ${vec4}(${screenDepth.associatedVariableName}, 0.0, 0.0, 1.0);\\r\\n`;\r\n        } else {\r\n            // We have to write something on the viewDepth output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_SCREENSPACE_DEPTH_INDEX] = ${vec4}(0.0, 0.0, 0.0, 0.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_POSITION\\r\\n`;\r\n        if (worldPosition.connectedPoint) {\r\n            state.compilationString += `fragData[PREPASS_POSITION_INDEX] = ${vec4}(${worldPosition.associatedVariableName}.rgb, ${\r\n                worldPosition.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? worldPosition.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the position output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_POSITION_INDEX] = ${vec4}(0.0, 0.0, 0.0, 0.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_LOCAL_POSITION\\r\\n`;\r\n        if (localPosition.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_LOCAL_POSITION_INDEX] = ${vec4}(${localPosition.associatedVariableName}.rgb, ${\r\n                localPosition.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? localPosition.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the position output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_LOCAL_POSITION_INDEX] = ${vec4}(0.0, 0.0, 0.0, 0.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_NORMAL\\r\\n`;\r\n        if (viewNormal.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_NORMAL_INDEX] = ${vec4}(${viewNormal.associatedVariableName}.rgb, ${\r\n                viewNormal.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? viewNormal.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the normal output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_NORMAL_INDEX] = ${vec4}(0.0, 0.0, 0.0, 0.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_WORLD_NORMAL\\r\\n`;\r\n        if (worldNormal.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_WORLD_NORMAL_INDEX] = ${vec4}(${worldNormal.associatedVariableName}.rgb, ${\r\n                worldNormal.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? worldNormal.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the normal output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_WORLD_NORMAL_INDEX] = ${vec4}(0.0, 0.0, 0.0, 0.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_REFLECTIVITY\\r\\n`;\r\n        if (reflectivity.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_REFLECTIVITY_INDEX] = ${vec4}(${reflectivity.associatedVariableName}.rgb, ${\r\n                reflectivity.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? reflectivity.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the reflectivity output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_REFLECTIVITY_INDEX] = ${vec4}(0.0, 0.0, 0.0, 1.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_VELOCITY\\r\\n`;\r\n        if (velocity.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_VELOCITY_INDEX] = ${vec4}(${velocity.associatedVariableName}.rgb, ${\r\n                velocity.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? velocity.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the reflectivity output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_VELOCITY_INDEX] = ${vec4}(0.0, 0.0, 0.0, 1.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n        state.compilationString += `#ifdef PREPASS_VELOCITY_LINEAR\\r\\n`;\r\n        if (velocityLinear.connectedPoint) {\r\n            state.compilationString += ` fragData[PREPASS_VELOCITY_LINEAR_INDEX] = ${vec4}(${velocityLinear.associatedVariableName}.rgb, ${\r\n                velocityLinear.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4 ? velocityLinear.associatedVariableName + \".a\" : \"1.0\"\r\n            });\\r\\n`;\r\n        } else {\r\n            // We have to write something on the reflectivity output or it will raise a gl error\r\n            state.compilationString += ` fragData[PREPASS_VELOCITY_LINEAR_INDEX] = ${vec4}(0.0, 0.0, 0.0, 1.0);\\r\\n`;\r\n        }\r\n        state.compilationString += `#endif\\r\\n`;\r\n\r\n        for (let index = 0; index < 8; index++) {\r\n            state.compilationString += `#if SCENE_MRT_COUNT > ${index} && (!defined(PREPASS_COLOR) || PREPASS_COLOR_INDEX != ${index}) && (!defined(PREPASS_OBJECT_ID) || PREPASS_OBJECT_ID_INDEX != ${index}) && (!defined(PREPASS_MESH_BLEND_TAG) || PREPASS_MESH_BLEND_TAG_INDEX != ${index})\\r\\n`;\r\n            state.compilationString += isWebGPU\r\n                ? `${this._getFragData(true, index)} = fragData[${index}];\\r\\n`\r\n                : `WRITE_GEOMETRY_FRAGMENT_OUTPUT(${index}, fragData[${index}]);\\r\\n`;\r\n            state.compilationString += `#endif\\r\\n`;\r\n        }\r\n\r\n        if (isWebGPU) {\r\n            for (let index = 0; index < 8; index++) {\r\n                state.compilationString += `#if defined(PREPASS_MESH_BLEND_TAG) && PREPASS_MESH_BLEND_TAG_INDEX == ${index}\\r\\n`;\r\n                state.compilationString += `fragmentOutputs.fragData${index} = vec4u(u32(uniforms.meshBlendTag), 0u, 0u, 0u);\\r\\n`;\r\n                state.compilationString += `#endif\\r\\n`;\r\n            }\r\n        } else {\r\n            state.compilationString += `#ifdef PREPASS_MESH_BLEND_TAG\\r\\n`;\r\n            state.compilationString += `meshBlendTagOutput = uvec4(uint(meshBlendTag), 0u, 0u, 0u);\\r\\n`;\r\n            state.compilationString += `#endif\\r\\n`;\r\n        }\r\n\r\n        state.compilationString += `#endif\\r\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for prePassOutputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPrePassOutputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PrePassOutputBlock\", PrePassOutputBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { RandomRange } from \"../../../../Maths/math.scalar.functions\";\r\nimport { RawTexture } from \"../../../Textures/rawTexture\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type AbstractEngine } from \"../../../../Engines/abstractEngine.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { ImageSourceBlock } from \"../Dual/imageSourceBlock.pure\";\r\nimport { type DepthSourceBlock } from \"../Dual/depthSourceBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to evaluate screen spaceambient occlusion in a shader\r\n */\r\nexport class AmbientOcclusionBlock extends NodeMaterialBlock {\r\n    private _randomTexture: Texture;\r\n    private _randomSamplerName: string;\r\n\r\n    /**\r\n     * Defines the radius around the analyzed pixel used by the SSAO post-process\r\n     */\r\n    @editableInPropertyPage(\"radius\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n        min: 0.0001,\r\n    })\r\n    public radius = 0.0001;\r\n\r\n    /**\r\n     * Related to fallOff, used to interpolate SSAO samples (first interpolate function input) based on the occlusion difference of each pixel\r\n     * Must not be equal to fallOff and superior to fallOff.\r\n     */\r\n    @editableInPropertyPage(\"area\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n        min: 0,\r\n    })\r\n    public area = 0.0075;\r\n\r\n    /**\r\n     * Related to area, used to interpolate SSAO samples (second interpolate function input) based on the occlusion difference of each pixel\r\n     * Must not be equal to area and inferior to area.\r\n     */\r\n    @editableInPropertyPage(\"fallOff\", PropertyTypeForEdition.Float, \"ADVANCED\", {\r\n        min: 0,\r\n    })\r\n    public fallOff = 0.000001;\r\n\r\n    /**\r\n     * Create a new AmbientOcclusionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerInput(\r\n            \"source\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerInput(\"screenSize\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"occlusion\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"AmbientOcclusionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the source component\r\n     */\r\n    public get source(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the screenSize component\r\n     */\r\n    public get screenSize(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the occlusion output\r\n     */\r\n    public get occlusion(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     */\r\n    public override bind(effect: Effect) {\r\n        if (!this._randomTexture) {\r\n            this._createRandomTexture(effect.getEngine());\r\n        }\r\n\r\n        effect.setTexture(this._randomSamplerName, this._randomTexture);\r\n    }\r\n\r\n    private _createRandomTexture(engine: AbstractEngine): void {\r\n        const size = 512;\r\n\r\n        const data = new Uint8Array(size * size * 4);\r\n        for (let index = 0; index < data.length;) {\r\n            data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n            data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n            data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n            data[index++] = 255;\r\n        }\r\n\r\n        const texture = RawTexture.CreateRGBATexture(data, size, size, engine, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n        texture.name = \"SSAORandomTexture\";\r\n        texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n        texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n        this._randomTexture = texture;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.source.connectedPoint) {\r\n            return this;\r\n        }\r\n\r\n        state.sharedData.bindableBlocks.push(this);\r\n        const depthSource = this.source.connectedPoint!.ownerBlock as DepthSourceBlock;\r\n\r\n        const occlusion = this._outputs[0];\r\n        const screenSize = this.screenSize;\r\n\r\n        let functionString: string;\r\n\r\n        // Get view position from depth\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = `fn normalFromDepth(depth: f32, coords: vec2f, radius: f32) -> vec3f {\r\n                let offset1: vec2f = vec2f(0.0, radius);\r\n                let offset2: vec2f = vec2f(radius, 0.0);\r\n\r\n                let depth1: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, coords + offset1, 0.0).r;\r\n                let depth2: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, coords + offset2, 0.0).r;\r\n\r\n                let p1: vec3f = vec3f(offset1, depth1 - depth);\r\n                let p2: vec3f = vec3f(offset2, depth2 - depth);\r\n\r\n                var normal: vec3f = cross(p1, p2);\r\n                normal.z = -normal.z;\r\n\r\n                return normalize(normal);\r\n            }\r\n            `;\r\n        } else {\r\n            functionString = `vec3 normalFromDepth(float depth, vec2 coords, float radius) {\r\n                vec2 offset1 = vec2(0.0, radius);\r\n                vec2 offset2 = vec2(radius, 0.0);\r\n\r\n                float depth1 = textureLod(${depthSource.samplerName}, coords + offset1, 0.0).r;\r\n                float depth2 = textureLod(${depthSource.samplerName}, coords + offset2, 0.0).r;\r\n\r\n                vec3 p1 = vec3(offset1, depth1 - depth);\r\n                vec3 p2 = vec3(offset2, depth2 - depth);\r\n\r\n                vec3 normal = cross(p1, p2);\r\n                normal.z = -normal.z;\r\n\r\n                return normalize(normal);\r\n            }\r\n            `;\r\n        }\r\n\r\n        state._emitFunction(\"normalFromDepth\", functionString, \"// normalFromDepth function\");\r\n\r\n        // Calculate ambient occlusion\r\n        this._randomSamplerName = state._getFreeVariableName(\"randomSampler\");\r\n\r\n        state._emit2DSampler(this._randomSamplerName);\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = `\r\n            const sampleSphere: array<vec3f, 16> = array<vec3f, 16>(\r\n                vec3f( 0.5381,  0.1856, -0.4319),\r\n                vec3f( 0.1379,  0.2486,  0.4430),\r\n                vec3f( 0.3371,  0.5679, -0.0057),\r\n                vec3f(-0.6999, -0.0451, -0.0019),\r\n                vec3f( 0.0689, -0.1598, -0.8547),\r\n                vec3f( 0.0560,  0.0069, -0.1843),\r\n                vec3f(-0.0146,  0.1402,  0.0762),\r\n                vec3f( 0.0100, -0.1924, -0.0344),\r\n                vec3f(-0.3577, -0.5301, -0.4358),\r\n                vec3f(-0.3169,  0.1063,  0.0158),\r\n                vec3f( 0.0103, -0.5869,  0.0046),\r\n                vec3f(-0.0897, -0.4940,  0.3287),\r\n                vec3f( 0.7119, -0.0154, -0.0918),\r\n                vec3f(-0.0533,  0.0596, -0.5411),\r\n                vec3f( 0.0352, -0.0631,  0.5460),\r\n                vec3f(-0.4776,  0.2847, -0.0271)\r\n            );\r\n\r\n            fn computeOcclusion(screenSize: vec2f) -> f32 {\r\n                let uv: vec2f = fragmentInputs.position.xy / screenSize;\r\n                let random: vec3f = normalize(textureSampleLevel(${this._randomSamplerName}, ${this._randomSamplerName}Sampler, uv * 4.0, 0.0).rgb);\r\n                let depth: f32 = textureSampleLevel(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, uv, 0.0).r;\r\n                let position: vec3f = vec3f(uv, depth);\r\n                let normal: vec3f = normalFromDepth(depth, uv, ${this.radius}f);\r\n\r\n                let radiusDepth: f32 = ${this.radius}f / depth;\r\n                var occlusion: f32 = 0.0;\r\n\r\n                var ray: vec3f;\r\n                var hemiRay: vec3f;\r\n                var occlusionDepth: f32;\r\n                var difference: f32;\r\n\r\n                for (var i: i32 = 0; i < 16; i++)\r\n                {\r\n                    ray = radiusDepth * reflect(sampleSphere[i], random);\r\n                    hemiRay = position + sign(dot(ray, normal)) * ray;\r\n\r\n                    occlusionDepth = textureSample(${depthSource.samplerName}, ${depthSource.samplerName}Sampler, clamp(hemiRay.xy, vec2f(0.001, 0.001), vec2f(0.999, 0.999))).r;\r\n                    difference = depth - occlusionDepth;\r\n\r\n                    occlusion += step(${this.fallOff}f, difference) * (1.0 - smoothstep(${this.fallOff}f, ${this.area}f, difference));\r\n                }\r\n\r\n                return clamp(1.0 - occlusion / 16.0, 0.0, 1.0);\r\n            }\r\n            `;\r\n        } else {\r\n            functionString = `\r\n            const vec3 sampleSphere[16] = vec3[](\r\n                vec3( 0.5381,  0.1856, -0.4319),\r\n                vec3( 0.1379,  0.2486,  0.4430),\r\n                vec3( 0.3371,  0.5679, -0.0057),\r\n                vec3(-0.6999, -0.0451, -0.0019),\r\n                vec3( 0.0689, -0.1598, -0.8547),\r\n                vec3( 0.0560,  0.0069, -0.1843),\r\n                vec3(-0.0146,  0.1402,  0.0762),\r\n                vec3( 0.0100, -0.1924, -0.0344),\r\n                vec3(-0.3577, -0.5301, -0.4358),\r\n                vec3(-0.3169,  0.1063,  0.0158),\r\n                vec3( 0.0103, -0.5869,  0.0046),\r\n                vec3(-0.0897, -0.4940,  0.3287),\r\n                vec3( 0.7119, -0.0154, -0.0918),\r\n                vec3(-0.0533,  0.0596, -0.5411),\r\n                vec3( 0.0352, -0.0631,  0.5460),\r\n                vec3(-0.4776,  0.2847, -0.0271)\r\n            );\r\n\r\n            float computeOcclusion(vec2 screenSize) {\r\n                vec2 uv = gl_FragCoord.xy / screenSize;\r\n                vec3 random = normalize(textureLod(${this._randomSamplerName}, uv * 4., 0.0).rgb);\r\n                float depth = textureLod(${depthSource.samplerName}, uv, 0.0).r;              \r\n                vec3 position = vec3(uv, depth);\r\n                vec3 normal = normalFromDepth(depth, uv, ${this.radius} );\r\n\r\n                float radiusDepth = ${this.radius} / depth;\r\n                float occlusion = 0.0;\r\n\r\n                vec3 ray;\r\n                vec3 hemiRay;\r\n                float occlusionDepth;\r\n                float difference;\r\n\r\n                for (int i = 0; i < 16; i++)\r\n                {\r\n                    ray = radiusDepth * reflect(sampleSphere[i], random);\r\n                    hemiRay = position + sign(dot(ray, normal)) * ray;\r\n\r\n                    occlusionDepth = texture2D(${depthSource.samplerName}, clamp(hemiRay.xy, vec2(0.001, 0.001), vec2(0.999, 0.999))).r;\r\n                    difference = depth - occlusionDepth;\r\n\r\n                    occlusion += step(${this.fallOff}, difference) * (1.0 - smoothstep(${this.fallOff}, ${this.area}, difference));\r\n                }\r\n\r\n                return clamp(1.0 - occlusion / 16.0, 0.0, 1.0);\r\n            }\r\n            `;\r\n        }\r\n\r\n        state._emitFunction(\"computeOcclusion\", functionString, \"// computeOcclusion function\");\r\n\r\n        state.compilationString += state._declareOutput(occlusion) + ` = computeOcclusion(${screenSize.associatedVariableName});`;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Releases the resources held by the block\r\n     */\r\n    public override dispose(): void {\r\n        if (this._randomTexture) {\r\n            this._randomTexture.dispose();\r\n            this._randomTexture = null!;\r\n        }\r\n        super.dispose();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for ambientOcclusionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAmbientOcclusionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AmbientOcclusionBlock\", AmbientOcclusionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\n\r\nimport { GetFogState } from \"core/Materials/materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add support for scene fog\r\n */\r\nexport class FogBlock extends NodeMaterialBlock {\r\n    private _fogDistanceName: string;\r\n    private _fogParameters: string;\r\n\r\n    /**\r\n     * Create a new FogBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment, false);\r\n\r\n        // Vertex\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);\r\n\r\n        // Fragment\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"fogColor\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.input.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n        this.fogColor.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"FogBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the view input component\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the fog color input component\r\n     */\r\n    public get fogColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block\r\n     * @param state - the build state\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/fogFragmentDeclaration\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/fogFragmentDeclaration\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - optional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.view.isConnected) {\r\n            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View && additionalFilteringInfo(b));\r\n\r\n            if (!viewInput) {\r\n                viewInput = new InputBlock(\"view\");\r\n                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);\r\n            }\r\n            viewInput.output.connectTo(this.view);\r\n        }\r\n        if (!this.fogColor.isConnected) {\r\n            let fogColorInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.FogColor && additionalFilteringInfo(b));\r\n\r\n            if (!fogColorInput) {\r\n                fogColorInput = new InputBlock(\"fogColor\", undefined, NodeMaterialBlockConnectionPointTypes.Color3);\r\n                fogColorInput.setAsSystemValue(NodeMaterialSystemValues.FogColor);\r\n            }\r\n            fogColorInput.output.connectTo(this.fogColor);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to prepare for\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n        defines.setValue(\"FOG\", nodeMaterial.fogEnabled && GetFogState(mesh, scene));\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n        effect.setFloat4(this._fogParameters, scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.sharedData.blocksWithDefines.push(this);\r\n            state.sharedData.bindableBlocks.push(this);\r\n\r\n            let replaceStrings: { search: RegExp; replace: string }[];\r\n            let prefix1 = \"\";\r\n            let prefix2 = \"\";\r\n\r\n            if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n                replaceStrings = [\r\n                    { search: /fn CalcFogFactor\\(\\)/, replace: \"fn CalcFogFactor(vFogDistance: vec3f, vFogInfos: vec4f)\" },\r\n                    { search: /uniforms.vFogInfos/g, replace: \"vFogInfos\" },\r\n                    { search: /fragmentInputs.vFogDistance/g, replace: \"vFogDistance\" },\r\n                ];\r\n\r\n                prefix1 = \"fragmentInputs.\";\r\n                prefix2 = \"uniforms.\";\r\n            } else {\r\n                replaceStrings = [{ search: /float CalcFogFactor\\(\\)/, replace: \"float CalcFogFactor(vec3 vFogDistance, vec4 vFogInfos)\" }];\r\n            }\r\n\r\n            state._emitFunctionFromInclude(\"fogFragmentDeclaration\", `//${this.name}`, {\r\n                removeUniforms: true,\r\n                removeVaryings: true,\r\n                removeIfDef: false,\r\n                replaceStrings: replaceStrings,\r\n            });\r\n\r\n            const tempFogVariablename = state._getFreeVariableName(\"fog\");\r\n            const color = this.input;\r\n            const fogColor = this.fogColor;\r\n            this._fogParameters = state._getFreeVariableName(\"fogParameters\");\r\n            const output = this._outputs[0];\r\n\r\n            state._emitUniformFromString(this._fogParameters, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n            state.compilationString += `#ifdef FOG\\n`;\r\n            state.compilationString += `${state._declareLocalVar(tempFogVariablename, NodeMaterialBlockConnectionPointTypes.Float)} = CalcFogFactor(${prefix1}${this._fogDistanceName}, ${prefix2}${this._fogParameters});\\n`;\r\n            state.compilationString +=\r\n                state._declareOutput(output) +\r\n                ` = ${tempFogVariablename} * ${color.associatedVariableName}.rgb + (1.0 - ${tempFogVariablename}) * ${fogColor.associatedVariableName}.rgb;\\n`;\r\n            state.compilationString += `#else\\n${state._declareOutput(output)} =  ${color.associatedVariableName}.rgb;\\n`;\r\n            state.compilationString += `#endif\\n`;\r\n        } else {\r\n            const worldPos = this.worldPosition;\r\n            const view = this.view;\r\n            this._fogDistanceName = state._getFreeVariableName(\"vFogDistance\");\r\n            state._emitVaryingFromString(this._fogDistanceName, NodeMaterialBlockConnectionPointTypes.Vector3);\r\n            const prefix = state.shaderLanguage === ShaderLanguage.WGSL ? \"vertexOutputs.\" : \"\";\r\n            state.compilationString += `${prefix}${this._fogDistanceName} = (${view.associatedVariableName} * ${worldPos.associatedVariableName}).xyz;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fogBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFogBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FogBlock\", FogBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type Light } from \"../../../../Lights/light\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { Logger } from \"../../../../Misc/logger\";\r\nimport { BindLight, BindLights, PrepareDefinesForLight, PrepareDefinesForLights, PrepareUniformsAndSamplersForLight } from \"../../../materialHelper.functions\";\r\nimport { ShaderLanguage } from \"../../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to add light in the fragment shader\r\n */\r\nexport class LightBlock extends NodeMaterialBlock {\r\n    private _lightId: number = 0;\r\n\r\n    /**\r\n     * Gets or sets the light associated with this block\r\n     */\r\n    public light: Nullable<Light>;\r\n\r\n    /** Indicates that no code should be generated in the vertex shader. Can be useful in some specific circumstances (like when doing ray marching for eg) */\r\n    @editableInPropertyPage(\"Generate only fragment code\", PropertyTypeForEdition.Boolean, \"ADVANCED\", {\r\n        notifiers: { rebuild: true, update: true, onValidation: (block, prop) => LightBlock._OnGenerateOnlyFragmentCodeChanged(block, prop) },\r\n    })\r\n    public generateOnlyFragmentCode = false;\r\n\r\n    private static _OnGenerateOnlyFragmentCodeChanged(block: NodeMaterialBlock, _propertyName: string): boolean {\r\n        const that = block as LightBlock;\r\n\r\n        if (that.worldPosition.isConnected) {\r\n            that.generateOnlyFragmentCode = !that.generateOnlyFragmentCode;\r\n            Logger.Error(\"The worldPosition input must not be connected to be able to switch!\");\r\n            return false;\r\n        }\r\n\r\n        that._setTarget();\r\n\r\n        return true;\r\n    }\r\n\r\n    private _setTarget(): void {\r\n        this._setInitialTarget(this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.VertexAndFragment);\r\n        this.getInputByName(\"worldPosition\")!.target = this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.Vertex;\r\n    }\r\n\r\n    /**\r\n     * Create a new LightBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"cameraPosition\", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"glossiness\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"glossPower\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"diffuseColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"specularColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix, true);\r\n\r\n        this.registerOutput(\"diffuseOutput\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"specularOutput\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"shadow\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"LightBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera (or eye) position component\r\n     */\r\n    public get cameraPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the glossiness component\r\n     */\r\n    public get glossiness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the glossiness power component\r\n     */\r\n    public get glossPower(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the diffuse color component\r\n     */\r\n    public get diffuseColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the specular color component\r\n     */\r\n    public get specularColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the view matrix component\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the diffuse output component\r\n     */\r\n    public get diffuseOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the specular output component\r\n     */\r\n    public get specularOutput(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow output component\r\n     */\r\n    public get shadow(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block\r\n     * @param state - the build state\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n\r\n        state._excludeVariableName(\"vViewDepth\");\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/lightFragment\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/lightUboDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/lightVxUboDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/lightsFragmentFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/shadowsFragmentFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/shadowsVertex\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/lightFragmentDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/lightFragment\"),\r\n                import(\"../../../../Shaders/ShadersInclude/lightUboDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/lightVxUboDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/lightVxFragmentDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/helperFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/lightsFragmentFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/shadowsFragmentFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/shadowsVertex\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - optional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.cameraPosition.isConnected) {\r\n            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.CameraPosition && additionalFilteringInfo(b));\r\n\r\n            if (!cameraPositionInput) {\r\n                cameraPositionInput = new InputBlock(\"cameraPosition\");\r\n                cameraPositionInput.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);\r\n            }\r\n            cameraPositionInput.output.connectTo(this.cameraPosition);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to prepare for\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh || !defines._areLightsDirty) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n\r\n        if (!this.light) {\r\n            PrepareDefinesForLights(scene, mesh, defines, true, nodeMaterial.maxSimultaneousLights);\r\n        } else {\r\n            const state = {\r\n                needNormals: false,\r\n                needRebuild: false,\r\n                lightmapMode: false,\r\n                shadowEnabled: false,\r\n                specularEnabled: false,\r\n            };\r\n\r\n            PrepareDefinesForLight(scene, mesh, this.light, this._lightId, defines, true, state);\r\n\r\n            if (state.needRebuild) {\r\n                defines.rebuild();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @param mesh - the mesh to check\r\n     * @param nodeMaterial - the node material\r\n     * @param defines - the list of defines\r\n     * @returns true if ready\r\n     */\r\n    public override isReady(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {\r\n        if (this.light && !this.light.areLightTexturesReady()) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Update the uniforms and samples\r\n     * @param state - the build state\r\n     * @param nodeMaterial - the node material\r\n     * @param defines - the material defines\r\n     * @param uniformBuffers - the uniform buffers\r\n     */\r\n    public override updateUniformsAndSamples(state: NodeMaterialBuildState, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, uniformBuffers: string[]) {\r\n        state.samplers.push(\"areaLightsLTC1Sampler\");\r\n        state.samplers.push(\"areaLightsLTC2Sampler\");\r\n        for (let lightIndex = 0; lightIndex < nodeMaterial.maxSimultaneousLights; lightIndex++) {\r\n            if (!defines[\"LIGHT\" + lightIndex]) {\r\n                break;\r\n            }\r\n            const onlyUpdateBuffersList = state.uniforms.indexOf(\"vLightData\" + lightIndex) >= 0;\r\n            PrepareUniformsAndSamplersForLight(\r\n                lightIndex,\r\n                state.uniforms,\r\n                state.samplers,\r\n                defines[\"PROJECTEDLIGHTTEXTURE\" + lightIndex],\r\n                uniformBuffers,\r\n                onlyUpdateBuffersList,\r\n                defines[\"IESLIGHTTEXTURE\" + lightIndex],\r\n                defines[\"CLUSTLIGHT\" + lightIndex],\r\n                defines[\"RECTAREALIGHTEMISSIONTEXTURE\" + lightIndex],\r\n                state.shaderLanguage === ShaderLanguage.WGSL\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n\r\n        if (!this.light) {\r\n            BindLights(scene, mesh, effect, true, nodeMaterial.maxSimultaneousLights);\r\n        } else {\r\n            BindLight(this.light, this._lightId, scene, effect, true);\r\n        }\r\n    }\r\n\r\n    private _injectVertexCode(state: NodeMaterialBuildState) {\r\n        const worldPos = this.worldPosition;\r\n        const comments = `//${this.name}`;\r\n        const scene = state.sharedData.nodeMaterial.getScene();\r\n\r\n        // Declaration\r\n        if (!this.light) {\r\n            // Emit for all lights\r\n            state._emitFunctionFromInclude(state.supportUniformBuffers ? \"lightVxUboDeclaration\" : \"lightVxFragmentDeclaration\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n            });\r\n            this._lightId = 0;\r\n\r\n            state.sharedData.dynamicUniformBlocks.push(this);\r\n        } else {\r\n            this._lightId = (state.counters[\"lightCounter\"] !== undefined ? state.counters[\"lightCounter\"] : -1) + 1;\r\n            state.counters[\"lightCounter\"] = this._lightId;\r\n\r\n            state._emitFunctionFromInclude(\r\n                state.supportUniformBuffers ? \"lightVxUboDeclaration\" : \"lightVxFragmentDeclaration\",\r\n                comments,\r\n                {\r\n                    replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }],\r\n                },\r\n                this._lightId.toString()\r\n            );\r\n        }\r\n\r\n        // Inject code in vertex\r\n        const worldPosVaryingName = \"v_\" + worldPos.associatedVariableName;\r\n\r\n        if (state._emitVaryingFromString(worldPosVaryingName, NodeMaterialBlockConnectionPointTypes.Vector4)) {\r\n            state.compilationString += (state.shaderLanguage === ShaderLanguage.WGSL ? \"vertexOutputs.\" : \"\") + `${worldPosVaryingName} = ${worldPos.associatedVariableName};\\n`;\r\n        }\r\n\r\n        if (this.light) {\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowsVertex\", comments, {\r\n                replaceStrings: [\r\n                    { search: /{X}/g, replace: this._lightId.toString() },\r\n                    { search: /worldPos/g, replace: worldPos.associatedVariableName },\r\n                ],\r\n            });\r\n        } else {\r\n            state.compilationString += `${state._declareLocalVar(\"worldPos\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${worldPos.associatedVariableName};\\n`;\r\n            if (this.view.isConnected) {\r\n                state.compilationString += `${state._declareLocalVar(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix)} = ${this.view.associatedVariableName};\\n`;\r\n                state._emitVaryingFromString(\"vViewDepth\", NodeMaterialBlockConnectionPointTypes.Float);\r\n                state.compilationString +=\r\n                    (state.shaderLanguage === ShaderLanguage.WGSL ? \"vertexOutputs.\" : \"\") +\r\n                    `vViewDepth = ${scene.useRightHandedSystem ? \"-\" : \"\"}(${this.view.associatedVariableName} * ${worldPos.associatedVariableName}).z;\\n`;\r\n            }\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowsVertex\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n            });\r\n        }\r\n    }\r\n\r\n    private _injectUBODeclaration(state: NodeMaterialBuildState) {\r\n        const comments = `//${this.name}`;\r\n\r\n        if (!this.light) {\r\n            // Emit for all lights\r\n            state._emitFunctionFromInclude(state.supportUniformBuffers ? \"lightUboDeclaration\" : \"lightFragmentDeclaration\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n                substitutionVars: this.generateOnlyFragmentCode ? \"varying,\" : undefined,\r\n            });\r\n        } else {\r\n            state._emitFunctionFromInclude(\r\n                state.supportUniformBuffers ? \"lightUboDeclaration\" : \"lightFragmentDeclaration\",\r\n                comments,\r\n                {\r\n                    replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }],\r\n                },\r\n                this._lightId.toString()\r\n            );\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const isWGSL = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const addF = isWGSL ? \"f\" : \"\";\r\n\r\n        const comments = `//${this.name}`;\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            // Vertex\r\n            this._injectVertexCode(state); // won't be executed if this.generateOnlyFragmentCode is true\r\n            return;\r\n        }\r\n\r\n        if (this.generateOnlyFragmentCode) {\r\n            state.sharedData.dynamicUniformBlocks.push(this);\r\n        }\r\n        // Fragment\r\n        const accessor = isWGSL ? \"fragmentInputs.\" : \"\";\r\n        state.sharedData.forcedBindableBlocks.push(this);\r\n        state.sharedData.blocksWithDefines.push(this);\r\n        if (this.light) {\r\n            state.sharedData.blockingBlocks.push(this);\r\n        }\r\n        const worldPos = this.worldPosition;\r\n\r\n        let worldPosVariableName = worldPos.associatedVariableName;\r\n        if (this.generateOnlyFragmentCode) {\r\n            worldPosVariableName = state._getFreeVariableName(\"globalWorldPos\");\r\n            state._emitFunction(\"light_globalworldpos\", `${state._declareLocalVar(worldPosVariableName, NodeMaterialBlockConnectionPointTypes.Vector3, false, true)};\\n`, comments);\r\n            state.compilationString += `${worldPosVariableName} = ${worldPos.associatedVariableName}.xyz;\\n`;\r\n\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowsVertex\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n                substitutionVars: `worldPos,${worldPos.associatedVariableName}`,\r\n            });\r\n        } else {\r\n            worldPosVariableName = accessor + \"v_\" + worldPosVariableName + \".xyz\";\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n\r\n        let replaceString = { search: /vPositionW/g, replace: worldPosVariableName };\r\n\r\n        if (isWGSL) {\r\n            replaceString = { search: /fragmentInputs\\.vPositionW/g, replace: worldPosVariableName };\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"lightsFragmentFunctions\", comments, {\r\n            replaceStrings: [replaceString],\r\n        });\r\n\r\n        state._emitFunctionFromInclude(\"shadowsFragmentFunctions\", comments, {\r\n            replaceStrings: [replaceString],\r\n        });\r\n\r\n        this._injectUBODeclaration(state);\r\n\r\n        // Code\r\n        if (this._lightId === 0) {\r\n            if (state._registerTempVariable(\"viewDirectionW\")) {\r\n                state.compilationString += `${state._declareLocalVar(\"viewDirectionW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${this.cameraPosition.associatedVariableName} - ${worldPosVariableName});\\n`;\r\n            }\r\n            if (this.generateOnlyFragmentCode && this.view.isConnected) {\r\n                state.compilationString += `${state._declareLocalVar(\"vViewDepth\", NodeMaterialBlockConnectionPointTypes.Float)} = (${this.view.associatedVariableName} * ${worldPos.associatedVariableName}).z;\\n`;\r\n            }\r\n\r\n            state.compilationString += isWGSL ? `var info: lightingInfo;\\n` : `lightingInfo info;\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"shadow\", NodeMaterialBlockConnectionPointTypes.Float)} = 1.;\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"aggShadow\", NodeMaterialBlockConnectionPointTypes.Float)} = 0.;\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"numLights\", NodeMaterialBlockConnectionPointTypes.Float)} = 0.;\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"glossiness\", NodeMaterialBlockConnectionPointTypes.Float)} = ${this.glossiness.isConnected ? this.glossiness.associatedVariableName : \"1.0\"} * ${\r\n                this.glossPower.isConnected ? this.glossPower.associatedVariableName : \"1024.0\"\r\n            };\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"diffuseBase\", NodeMaterialBlockConnectionPointTypes.Vector3)} = vec3${addF}(0., 0., 0.);\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"specularBase\", NodeMaterialBlockConnectionPointTypes.Vector3)}  = vec3${addF}(0., 0., 0.);\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"normalW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this.worldNormal.associatedVariableName}.xyz;\\n`;\r\n        }\r\n\r\n        if (this.light) {\r\n            let replaceString = [{ search: /vPositionW/g, replace: worldPosVariableName + \".xyz\" }];\r\n\r\n            if (isWGSL) {\r\n                replaceString = [\r\n                    { search: /fragmentInputs\\.vPositionW/g, replace: worldPosVariableName + \".xyz\" },\r\n                    { search: /uniforms\\.vReflectivityColor/g, replace: \"vReflectivityColor\" },\r\n                ];\r\n            }\r\n\r\n            state.compilationString += state._emitCodeFromInclude(\"lightFragment\", comments, {\r\n                replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }, ...replaceString],\r\n            });\r\n        } else {\r\n            let substitutionVars = `vPositionW,${worldPosVariableName}.xyz`;\r\n\r\n            if (isWGSL) {\r\n                substitutionVars = `fragmentInputs.vPositionW,${worldPosVariableName}.xyz`;\r\n                if (this.generateOnlyFragmentCode) {\r\n                    substitutionVars += `,fragmentInputs.vViewDepth,vViewDepth`;\r\n                }\r\n            }\r\n            state.compilationString += state._emitCodeFromInclude(\"lightFragment\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n                substitutionVars: substitutionVars,\r\n            });\r\n        }\r\n\r\n        if (this._lightId === 0) {\r\n            state.compilationString += `aggShadow = aggShadow / numLights;\\n`;\r\n        }\r\n\r\n        const diffuseOutput = this.diffuseOutput;\r\n        const specularOutput = this.specularOutput;\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(diffuseOutput) + ` = diffuseBase${this.diffuseColor.isConnected ? \" * \" + this.diffuseColor.associatedVariableName : \"\"};\\n`;\r\n        if (specularOutput.hasEndpoints) {\r\n            state.compilationString +=\r\n                state._declareOutput(specularOutput) + ` = specularBase${this.specularColor.isConnected ? \" * \" + this.specularColor.associatedVariableName : \"\"};\\n`;\r\n        }\r\n\r\n        if (this.shadow.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.shadow) + ` = aggShadow;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.generateOnlyFragmentCode = this.generateOnlyFragmentCode;\r\n\r\n        if (this.light) {\r\n            serializationObject.lightId = this.light.id;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        if (serializationObject.lightId) {\r\n            this.light = scene.getLightById(serializationObject.lightId);\r\n        }\r\n\r\n        this.generateOnlyFragmentCode = serializationObject.generateOnlyFragmentCode;\r\n\r\n        this._setTarget();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for lightBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLightBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.LightBlock\", LightBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\n\r\nimport { NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { type NodeMaterialDefines } from \"../../nodeMaterial\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { ThinTexture } from \"../../../Textures/thinTexture\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { NodeMaterialModes } from \"../../Enums/nodeMaterialModes\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { type AbstractEngine } from \"../../../../Engines/abstractEngine.pure\";\r\nimport { ImageSourceBlock } from \"./imageSourceBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { EngineStore } from \"../../../../Engines/engineStore\";\r\nimport { type PrePassTextureBlock } from \"../Input/prePassTextureBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to read a texture from a sampler\r\n */\r\nexport class TextureBlock extends NodeMaterialBlock {\r\n    private static _DefaultTextureByEngine = /*#__PURE__*/ new WeakMap<AbstractEngine, ThinTexture>();\r\n\r\n    private _defineName: string;\r\n    private _linearDefineName: string;\r\n    private _gammaDefineName: string;\r\n    private _tempTextureRead: string;\r\n    private _samplerName: string;\r\n    private _transformedUVName: string;\r\n    private _textureTransformName: string;\r\n    private _textureInfoName: string;\r\n    private _mainUVName: string;\r\n    private _mainUVDefineName: string;\r\n    private _fragmentOnly: boolean;\r\n    private _imageSource: Nullable<ImageSourceBlock | PrePassTextureBlock>;\r\n\r\n    protected _texture: Nullable<Texture>;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the block is used in fragment shader only\r\n     * If false the system will allow optimizations to use it in vertex shader when possible for the uv computation\r\n     */\r\n    public get fragmentOnly(): boolean {\r\n        return this._fragmentOnly;\r\n    }\r\n\r\n    public set fragmentOnly(value: boolean) {\r\n        this._fragmentOnly = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public get texture(): Nullable<Texture> {\r\n        if (this.source.isConnected) {\r\n            return (this.source.connectedPoint?.ownerBlock as ImageSourceBlock).texture;\r\n        }\r\n        return this._texture;\r\n    }\r\n\r\n    public set texture(texture: Nullable<Texture>) {\r\n        if (this._texture === texture) {\r\n            return;\r\n        }\r\n\r\n        const scene = texture?.getScene() ?? EngineStore.LastCreatedScene;\r\n\r\n        if (!texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this._texture!);\r\n            });\r\n        }\r\n\r\n        this._texture = texture;\r\n\r\n        if (texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(texture);\r\n            });\r\n        }\r\n    }\r\n\r\n    private static _IsPrePassTextureBlock(block: Nullable<ImageSourceBlock | PrePassTextureBlock>): block is PrePassTextureBlock {\r\n        return block?.getClassName() === \"PrePassTextureBlock\";\r\n    }\r\n\r\n    private static _GetDefaultTexture(engine: AbstractEngine): ThinTexture {\r\n        let defaultTexture = TextureBlock._DefaultTextureByEngine.get(engine);\r\n        if (!defaultTexture || defaultTexture.getInternalTexture() !== engine.emptyTexture) {\r\n            defaultTexture = new ThinTexture(engine.emptyTexture);\r\n            TextureBlock._DefaultTextureByEngine.set(engine, defaultTexture);\r\n        }\r\n        return defaultTexture;\r\n    }\r\n\r\n    private get _isSourcePrePass() {\r\n        return TextureBlock._IsPrePassTextureBlock(this._imageSource);\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this texture\r\n     */\r\n    public get samplerName(): string {\r\n        if (this._imageSource) {\r\n            if (!TextureBlock._IsPrePassTextureBlock(this._imageSource)) {\r\n                return this._imageSource.samplerName;\r\n            }\r\n            if (this.source.connectedPoint) {\r\n                return this._imageSource.getSamplerName(this.source.connectedPoint);\r\n            }\r\n        }\r\n        return this._samplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block is linked to an ImageSourceBlock\r\n     */\r\n    public get hasImageSource(): boolean {\r\n        return this.source.isConnected;\r\n    }\r\n\r\n    private _convertToGammaSpace = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to gamma space\r\n     */\r\n    public set convertToGammaSpace(value: boolean) {\r\n        if (value === this._convertToGammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._convertToGammaSpace = value;\r\n        if (this.texture) {\r\n            const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;\r\n            scene?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this.texture!);\r\n            });\r\n        }\r\n    }\r\n    public get convertToGammaSpace(): boolean {\r\n        return this._convertToGammaSpace;\r\n    }\r\n\r\n    private _convertToLinearSpace = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to linear space\r\n     */\r\n    public set convertToLinearSpace(value: boolean) {\r\n        if (value === this._convertToLinearSpace) {\r\n            return;\r\n        }\r\n\r\n        this._convertToLinearSpace = value;\r\n        if (this.texture) {\r\n            const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;\r\n            scene?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this.texture!);\r\n            });\r\n        }\r\n    }\r\n    public get convertToLinearSpace(): boolean {\r\n        return this._convertToLinearSpace;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if multiplication of texture with level should be disabled\r\n     */\r\n    public disableLevelMultiplication = false;\r\n\r\n    /**\r\n     * Create a new TextureBlock\r\n     * @param name defines the block name\r\n     * @param fragmentOnly\r\n     */\r\n    public constructor(name: string, fragmentOnly = false) {\r\n        super(name, fragmentOnly ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this._fragmentOnly = fragmentOnly;\r\n\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.VertexAndFragment);\r\n        this.registerInput(\r\n            \"source\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerInput(\"layer\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"lod\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"r\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"g\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"b\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerOutput(\"level\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector2 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n\r\n        this._inputs[0]._prioritizeVertex = !fragmentOnly;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TextureBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the source input component\r\n     */\r\n    public get source(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the layer input component\r\n     */\r\n    public get layer(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the LOD input component\r\n     */\r\n    public get lod(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba output component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb output component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the r output component\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the g output component\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the b output component\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the a output component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the level output component\r\n     */\r\n    public get level(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    private _isTiedToFragment(input: NodeMaterialConnectionPoint) {\r\n        if (input.target === NodeMaterialBlockTargets.Fragment) {\r\n            return true;\r\n        }\r\n\r\n        if (input.target === NodeMaterialBlockTargets.Vertex) {\r\n            return false;\r\n        }\r\n\r\n        if (input.target === NodeMaterialBlockTargets.Neutral || input.target === NodeMaterialBlockTargets.VertexAndFragment) {\r\n            const parentBlock = input.ownerBlock;\r\n\r\n            if (parentBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n                return true;\r\n            }\r\n\r\n            for (const input of parentBlock.inputs) {\r\n                if (!input.isConnected) {\r\n                    continue;\r\n                }\r\n                if (this._isTiedToFragment(input.connectedPoint!)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    private _getEffectiveTarget() {\r\n        if (this._fragmentOnly) {\r\n            return NodeMaterialBlockTargets.Fragment;\r\n        }\r\n\r\n        // TextureBlock has a special optimizations for uvs that come from the vertex shaders as they can be packed into a single varyings.\r\n        // But we need to detect uvs coming from fragment then\r\n        if (!this.uv.isConnected) {\r\n            return NodeMaterialBlockTargets.VertexAndFragment;\r\n        }\r\n\r\n        if (this.uv.sourceBlock!.isInput) {\r\n            return NodeMaterialBlockTargets.VertexAndFragment;\r\n        }\r\n\r\n        if (this._isTiedToFragment(this.uv.connectedPoint!)) {\r\n            return NodeMaterialBlockTargets.Fragment;\r\n        }\r\n\r\n        return NodeMaterialBlockTargets.VertexAndFragment;\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get target() {\r\n        return this._getEffectiveTarget();\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override set target(value: NodeMaterialBlockTargets) {}\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - optional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.uv.isConnected) {\r\n            if (material.mode === NodeMaterialModes.PostProcess) {\r\n                const uvInput = material.getBlockByPredicate((b) => b.name === \"uv\" && additionalFilteringInfo(b));\r\n\r\n                if (uvInput) {\r\n                    uvInput.connectTo(this);\r\n                }\r\n            } else if (material.mode !== NodeMaterialModes.ProceduralTexture) {\r\n                const attributeName = material.mode === NodeMaterialModes.Particle ? \"particle_uv\" : \"uv\";\r\n\r\n                let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === attributeName && additionalFilteringInfo(b));\r\n\r\n                if (!uvInput) {\r\n                    uvInput = new InputBlock(\"uv\");\r\n                    uvInput.setAsAttribute(attributeName);\r\n                }\r\n                uvInput.output.connectTo(this.uv);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Initialize the list of defines\r\n     * @param defines - the material defines\r\n     */\r\n    public override initializeDefines(defines: NodeMaterialDefines) {\r\n        if (!defines._areTexturesDirty) {\r\n            return;\r\n        }\r\n\r\n        if (this._mainUVDefineName !== undefined) {\r\n            defines.setValue(this._mainUVDefineName, false, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        if (!defines._areTexturesDirty) {\r\n            return;\r\n        }\r\n\r\n        if (!this.texture || !this.texture.getTextureMatrix) {\r\n            if (this._isMixed) {\r\n                defines.setValue(this._defineName, false, true);\r\n                defines.setValue(this._mainUVDefineName, true, true);\r\n            }\r\n            return;\r\n        }\r\n\r\n        const toGamma = this.convertToGammaSpace && this.texture && !this.texture.gammaSpace;\r\n        const toLinear = this.convertToLinearSpace && this.texture && this.texture.gammaSpace;\r\n\r\n        // Not a bug... Name defines the texture space not the required conversion\r\n        defines.setValue(this._linearDefineName, toGamma, true);\r\n        defines.setValue(this._gammaDefineName, toLinear, true);\r\n\r\n        if (this._isMixed) {\r\n            if (!this.texture.getTextureMatrix().isIdentityAs3x2()) {\r\n                defines.setValue(this._defineName, true);\r\n                if (defines[this._mainUVDefineName] == undefined) {\r\n                    defines.setValue(this._mainUVDefineName, false, true);\r\n                }\r\n            } else {\r\n                defines.setValue(this._defineName, false, true);\r\n                defines.setValue(this._mainUVDefineName, true, true);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        if (this._isSourcePrePass) {\r\n            return true;\r\n        }\r\n\r\n        if (this.texture && !this.texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     */\r\n    public override bind(effect: Effect) {\r\n        if (this._isSourcePrePass) {\r\n            effect.setFloat(this._textureInfoName, 1);\r\n        }\r\n\r\n        const texture = this.texture;\r\n        if (!texture) {\r\n            const engine = effect.getEngine();\r\n            if (engine.isWebGPU && !this._imageSource) {\r\n                effect.setTexture(this._samplerName, TextureBlock._GetDefaultTexture(engine));\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (this._isMixed) {\r\n            effect.setFloat(this._textureInfoName, texture.level);\r\n            effect.setMatrix(this._textureTransformName, texture.getTextureMatrix());\r\n        }\r\n\r\n        if (!this._imageSource) {\r\n            effect.setTexture(this._samplerName, texture);\r\n        }\r\n    }\r\n\r\n    private get _isMixed() {\r\n        return this.target !== NodeMaterialBlockTargets.Fragment;\r\n    }\r\n\r\n    private _injectVertexCode(state: NodeMaterialBuildState) {\r\n        const uvInput = this.uv;\r\n\r\n        // Inject code in vertex\r\n        this._defineName = state._getFreeDefineName(\"UVTRANSFORM\");\r\n        this._mainUVDefineName = \"VMAIN\" + uvInput.declarationVariableName.toUpperCase();\r\n\r\n        this._mainUVName = \"vMain\" + uvInput.declarationVariableName;\r\n        this._transformedUVName = state._getFreeVariableName(\"transformedUV\");\r\n        this._textureTransformName = state._getFreeVariableName(\"textureTransform\");\r\n        this._textureInfoName = state._getFreeVariableName(\"textureInfoName\");\r\n\r\n        this.level.associatedVariableName = this._textureInfoName;\r\n\r\n        state._emitVaryingFromString(this._transformedUVName, NodeMaterialBlockConnectionPointTypes.Vector2, this._defineName);\r\n        state._emitVaryingFromString(this._mainUVName, NodeMaterialBlockConnectionPointTypes.Vector2, this._mainUVDefineName);\r\n\r\n        state._emitUniformFromString(this._textureTransformName, NodeMaterialBlockConnectionPointTypes.Matrix, this._defineName);\r\n\r\n        const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        const vec2 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        state.compilationString += `#ifdef ${this._defineName}\\n`;\r\n        state.compilationString += `${state._getVaryingName(this._transformedUVName)} = ${vec2}(${this._textureTransformName} * ${vec4}(${uvInput.associatedVariableName}.xy, 1.0, 0.0));\\n`;\r\n        state.compilationString += `#elif defined(${this._mainUVDefineName})\\n`;\r\n\r\n        let automaticPrefix = \"\";\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            if (uvInput.isConnectedToInputBlock && uvInput.associatedVariableName.indexOf(\"vertexInputs.\") === -1) {\r\n                automaticPrefix = \"vertexInputs.\"; // Force the prefix\r\n            }\r\n        }\r\n\r\n        state.compilationString += `${state._getVaryingName(this._mainUVName)} = ${automaticPrefix}${uvInput.associatedVariableName}.xy;\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n\r\n        if (!this._outputs.some((o) => o.isConnectedInVertexShader)) {\r\n            return;\r\n        }\r\n\r\n        this._writeTextureRead(state, true);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints && output.name !== \"level\") {\r\n                this._writeOutput(state, output, output.name, true);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _getUVW(uvName: string): string {\r\n        let coords = uvName;\r\n\r\n        const is2DArrayTexture = this._texture?._texture?.is2DArray ?? false;\r\n        const is3D = this._texture?._texture?.is3D ?? false;\r\n\r\n        if (is2DArrayTexture) {\r\n            const layerValue = this.layer.isConnected ? this.layer.associatedVariableName : \"0\";\r\n            coords = `vec3(${uvName}, ${layerValue})`;\r\n        } else if (is3D) {\r\n            const layerValue = this.layer.isConnected ? this.layer.associatedVariableName : \"0\";\r\n            coords = `vec3(${uvName}, ${layerValue})`;\r\n        }\r\n\r\n        return coords;\r\n    }\r\n\r\n    private _samplerFunc(state: NodeMaterialBuildState) {\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return state.target === NodeMaterialBlockTargets.Vertex ? \"textureSampleLevel\" : \"textureSample\";\r\n        }\r\n        return this.lod.isConnected ? \"texture2DLodEXT\" : \"texture2D\";\r\n    }\r\n\r\n    private get _samplerLodSuffix() {\r\n        return this.lod.isConnected ? `, ${this.lod.associatedVariableName}` : \"\";\r\n    }\r\n\r\n    private _generateTextureSample(uv: string, state: NodeMaterialBuildState) {\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            const isVertex = state.target === NodeMaterialBlockTargets.Vertex;\r\n            return `${this._samplerFunc(state)}(${this.samplerName},${this.samplerName + Constants.AUTOSAMPLERSUFFIX}, ${this._getUVW(uv)}${this._samplerLodSuffix}${isVertex ? \", 0\" : \"\"})`;\r\n        }\r\n        return `${this._samplerFunc(state)}(${this.samplerName}, ${this._getUVW(uv)}${this._samplerLodSuffix})`;\r\n    }\r\n\r\n    private _generateTextureLookup(state: NodeMaterialBuildState): void {\r\n        state.compilationString += `#ifdef ${this._defineName}\\n`;\r\n        state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(state._getVaryingName(this._transformedUVName), state)};\\n`;\r\n        state.compilationString += `#elif defined(${this._mainUVDefineName})\\n`;\r\n        state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(this._mainUVName ? state._getVaryingName(this._mainUVName) : this.uv.associatedVariableName, state)}${this._samplerLodSuffix};\\n`;\r\n        state.compilationString += `#endif\\n`;\r\n    }\r\n\r\n    private _writeTextureRead(state: NodeMaterialBuildState, vertexMode = false) {\r\n        const uvInput = this.uv;\r\n\r\n        if (vertexMode) {\r\n            if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n                return;\r\n            }\r\n\r\n            this._generateTextureLookup(state);\r\n            return;\r\n        }\r\n\r\n        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(uvInput.associatedVariableName, state)}${this._samplerLodSuffix};\\n`;\r\n            return;\r\n        }\r\n\r\n        this._generateTextureLookup(state);\r\n    }\r\n\r\n    private _generateConversionCode(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string): void {\r\n        if (swizzle !== \"a\") {\r\n            // no conversion if the output is \"a\" (alpha)\r\n            if (!this.texture || !this.texture.gammaSpace) {\r\n                state.compilationString += `#ifdef ${this._linearDefineName}\r\n                    ${output.associatedVariableName} = toGammaSpace(${output.associatedVariableName});\r\n                    #endif\r\n                `;\r\n            }\r\n\r\n            state.compilationString += `#ifdef ${this._gammaDefineName}\r\n                ${output.associatedVariableName} = ${state._toLinearSpace(output)};\r\n                #endif\r\n            `;\r\n        }\r\n    }\r\n\r\n    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string, vertexMode = false) {\r\n        if (vertexMode) {\r\n            if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n                return;\r\n            }\r\n\r\n            state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n            this._generateConversionCode(state, output, swizzle);\r\n            return;\r\n        }\r\n\r\n        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n            this._generateConversionCode(state, output, swizzle);\r\n            return;\r\n        }\r\n        let complement = \"\";\r\n\r\n        if (!this.disableLevelMultiplication) {\r\n            complement = ` * ${(state.shaderLanguage === ShaderLanguage.WGSL ? \"uniforms.\" : \"\") + this._textureInfoName}`;\r\n        }\r\n\r\n        state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle}${complement};\\n`;\r\n        this._generateConversionCode(state, output, swizzle);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (this.source.isConnected) {\r\n            this._imageSource = this.source.connectedPoint!.ownerBlock as ImageSourceBlock;\r\n        } else {\r\n            this._imageSource = null;\r\n        }\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex || this._fragmentOnly || state.target === NodeMaterialBlockTargets.Fragment) {\r\n            this._tempTextureRead = state._getFreeVariableName(\"tempTextureRead\");\r\n            this._linearDefineName = state._getFreeDefineName(\"ISLINEAR\");\r\n            this._gammaDefineName = state._getFreeDefineName(\"ISGAMMA\");\r\n        }\r\n\r\n        if ((!this._isMixed && state.target === NodeMaterialBlockTargets.Fragment) || (this._isMixed && state.target === NodeMaterialBlockTargets.Vertex)) {\r\n            if (!this._imageSource) {\r\n                const varName = state._getFreeVariableName(this.name);\r\n                this._samplerName = varName + \"Texture\";\r\n\r\n                if (this._texture?._texture?.is2DArray) {\r\n                    state._emit2DArraySampler(this._samplerName);\r\n                } else {\r\n                    state._emit2DSampler(this._samplerName);\r\n                }\r\n            }\r\n\r\n            // Declarations\r\n            state.sharedData.blockingBlocks.push(this);\r\n            state.sharedData.textureBlocks.push(this);\r\n            state.sharedData.blocksWithDefines.push(this);\r\n            state.sharedData.bindableBlocks.push(this);\r\n        }\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            // Vertex\r\n            this._injectVertexCode(state);\r\n            return;\r\n        }\r\n\r\n        // Fragment\r\n        if (!this._outputs.some((o) => o.isConnectedInFragmentShader)) {\r\n            return;\r\n        }\r\n\r\n        if (this._isMixed && !this._imageSource) {\r\n            // Reexport the sampler\r\n            if (this._texture?._texture?.is2DArray) {\r\n                state._emit2DArraySampler(this._samplerName);\r\n            } else {\r\n                state._emit2DSampler(this._samplerName);\r\n            }\r\n        }\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n\r\n        if (this._isMixed) {\r\n            state._emitUniformFromString(this._textureInfoName, NodeMaterialBlockConnectionPointTypes.Float);\r\n        }\r\n\r\n        this._writeTextureRead(state);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints && output.name !== \"level\") {\r\n                this._writeOutput(state, output, output.name);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.convertToGammaSpace = ${this.convertToGammaSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.convertToLinearSpace = ${this.convertToLinearSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.disableLevelMultiplication = ${this.disableLevelMultiplication};\\n`;\r\n\r\n        if (!this.texture) {\r\n            return codeString;\r\n        }\r\n\r\n        codeString += `${this._codeVariableName}.texture = new BABYLON.Texture(\"${this.texture.name}\", null, ${this.texture.noMipmap}, ${this.texture.invertY}, ${this.texture.samplingMode});\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wrapU = ${this.texture.wrapU};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wrapV = ${this.texture.wrapV};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uAng = ${this.texture.uAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vAng = ${this.texture.vAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wAng = ${this.texture.wAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uOffset = ${this.texture.uOffset};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vOffset = ${this.texture.vOffset};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uScale = ${this.texture.uScale};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vScale = ${this.texture.vScale};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.convertToGammaSpace = this.convertToGammaSpace;\r\n        serializationObject.convertToLinearSpace = this.convertToLinearSpace;\r\n        serializationObject.fragmentOnly = this._fragmentOnly;\r\n        serializationObject.disableLevelMultiplication = this.disableLevelMultiplication;\r\n        if (\r\n            !this.hasImageSource &&\r\n            this.texture &&\r\n            (NodeMaterial.AllowSerializationOfRenderTargetTextures || !this.texture.isRenderTarget) &&\r\n            this.texture.getClassName() !== \"VideoTexture\"\r\n        ) {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     * @param urlRewriter - optional url rewriter\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string, urlRewriter?: (url: string) => string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.convertToGammaSpace = serializationObject.convertToGammaSpace;\r\n        this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;\r\n        this._fragmentOnly = !!serializationObject.fragmentOnly;\r\n        this.disableLevelMultiplication = !!serializationObject.disableLevelMultiplication;\r\n\r\n        if (serializationObject.texture && !NodeMaterial.IgnoreTexturesAtLoadTime) {\r\n            if (serializationObject.texture.url !== undefined) {\r\n                if (serializationObject.texture.url.indexOf(\"data:\") === 0) {\r\n                    rootUrl = \"\";\r\n                } else if (urlRewriter) {\r\n                    serializationObject.texture.url = urlRewriter(serializationObject.texture.url);\r\n                    serializationObject.texture.name = serializationObject.texture.url;\r\n                }\r\n            }\r\n            if (serializationObject.texture.base64String || serializationObject.texture.url !== undefined) {\r\n                this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl) as Texture;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for textureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TextureBlock\", TextureBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { type NodeMaterialDefines, NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\n\r\nimport { CubeTextureParse, type CubeTexture } from \"../../../Textures/cubeTexture.pure\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { EngineStore } from \"../../../../Engines/engineStore\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type SubMesh } from \"../../../..//Meshes/subMesh.pure\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Base block used to read a reflection texture from a sampler\r\n */\r\nexport abstract class ReflectionTextureBaseBlock extends NodeMaterialBlock {\r\n    /** @internal */\r\n    public _define3DName: string;\r\n    /** @internal */\r\n    public _defineCubicName: string;\r\n    /** @internal */\r\n    public _defineExplicitName: string;\r\n    /** @internal */\r\n    public _defineProjectionName: string;\r\n    /** @internal */\r\n    public _defineLocalCubicName: string;\r\n    /** @internal */\r\n    public _defineSphericalName: string;\r\n    /** @internal */\r\n    public _definePlanarName: string;\r\n    /** @internal */\r\n    public _defineEquirectangularName: string;\r\n    /** @internal */\r\n    public _defineMirroredEquirectangularFixedName: string;\r\n    /** @internal */\r\n    public _defineEquirectangularFixedName: string;\r\n    /** @internal */\r\n    public _defineSkyboxName: string;\r\n    /** @internal */\r\n    public _defineOppositeZ: string;\r\n    /** @internal */\r\n    public _cubeSamplerName: string;\r\n    /** @internal */\r\n    public _2DSamplerName: string;\r\n    /** @internal */\r\n    public _reflectionPositionName: string;\r\n    /** @internal */\r\n    public _reflectionSizeName: string;\r\n\r\n    protected _positionUVWName: string;\r\n    protected _directionWname: string;\r\n    protected _reflectionVectorName: string;\r\n    /** @internal */\r\n    public _reflectionCoordsName: string;\r\n    /** @internal */\r\n    public _reflectionMatrixName: string;\r\n    protected _reflectionColorName: string;\r\n    protected _worldPositionNameInFragmentOnlyMode: string;\r\n\r\n    protected _texture: Nullable<BaseTexture>;\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public get texture(): Nullable<BaseTexture> {\r\n        return this._texture;\r\n    }\r\n\r\n    public set texture(texture: Nullable<BaseTexture>) {\r\n        if (this._texture === texture) {\r\n            return;\r\n        }\r\n\r\n        const scene = texture?.getScene() ?? EngineStore.LastCreatedScene;\r\n\r\n        if (!texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this._texture!);\r\n            });\r\n        }\r\n\r\n        this._texture = texture;\r\n\r\n        if (texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(texture);\r\n            });\r\n        }\r\n    }\r\n\r\n    /** Indicates that no code should be generated in the vertex shader. Can be useful in some specific circumstances (like when doing ray marching for eg) */\r\n    @editableInPropertyPage(\"Generate only fragment code\", PropertyTypeForEdition.Boolean, \"ADVANCED\", {\r\n        notifiers: { rebuild: true, update: true, onValidation: (block, prop) => ReflectionTextureBaseBlock._OnGenerateOnlyFragmentCodeChanged(block, prop) },\r\n    })\r\n    public generateOnlyFragmentCode = false;\r\n\r\n    protected static _OnGenerateOnlyFragmentCodeChanged(block: NodeMaterialBlock, _propertyName: string): boolean {\r\n        const that = block as ReflectionTextureBaseBlock;\r\n        return that._onGenerateOnlyFragmentCodeChanged();\r\n    }\r\n\r\n    protected _onGenerateOnlyFragmentCodeChanged(): boolean {\r\n        this._setTarget();\r\n        return true;\r\n    }\r\n\r\n    protected _setTarget(): void {\r\n        this._setInitialTarget(this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.VertexAndFragment);\r\n    }\r\n\r\n    /**\r\n     * Create a new ReflectionTextureBaseBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ReflectionTextureBaseBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public abstract get position(): NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public abstract get worldPosition(): NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public abstract get worldNormal(): NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Gets the world input component\r\n     */\r\n    public abstract get world(): NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Gets the camera (or eye) position component\r\n     */\r\n    public abstract get cameraPosition(): NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Gets the view input component\r\n     */\r\n    public abstract get view(): NodeMaterialConnectionPoint;\r\n\r\n    protected _getTexture(): Nullable<BaseTexture> {\r\n        return this.texture;\r\n    }\r\n\r\n    /**\r\n     * Initialize the block\r\n     * @param state - the build state\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\"), import(\"../../../../ShadersWGSL/ShadersInclude/reflectionFunction\")]);\r\n        } else {\r\n            await Promise.all([import(\"../../../../Shaders/ShadersInclude/helperFunctions\"), import(\"../../../../Shaders/ShadersInclude/reflectionFunction\")]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the node based on the existing material\r\n     * @param material defines the material to configure\r\n     * @param additionalFilteringInfo defines additional info to be used when filtering inputs (we might want to skip some non relevant blocks)\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.position.isConnected) {\r\n            let positionInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === \"position\" && additionalFilteringInfo(b));\r\n\r\n            if (!positionInput) {\r\n                positionInput = new InputBlock(\"position\");\r\n                positionInput.setAsAttribute();\r\n            }\r\n            positionInput.output.connectTo(this.position);\r\n        }\r\n\r\n        if (!this.world.isConnected) {\r\n            let worldInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.World && additionalFilteringInfo(b));\r\n\r\n            if (!worldInput) {\r\n                worldInput = new InputBlock(\"world\");\r\n                worldInput.setAsSystemValue(NodeMaterialSystemValues.World);\r\n            }\r\n            worldInput.output.connectTo(this.world);\r\n        }\r\n\r\n        if (this.view && !this.view.isConnected) {\r\n            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View && additionalFilteringInfo(b));\r\n\r\n            if (!viewInput) {\r\n                viewInput = new InputBlock(\"view\");\r\n                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);\r\n            }\r\n            viewInput.output.connectTo(this.view);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the material defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        if (!defines._areTexturesDirty) {\r\n            return;\r\n        }\r\n\r\n        const texture = this._getTexture();\r\n\r\n        if (!texture || !texture.getTextureMatrix) {\r\n            return;\r\n        }\r\n\r\n        defines.setValue(this._define3DName, texture.isCube, true);\r\n        defines.setValue(this._defineLocalCubicName, (<any>texture).boundingBoxSize ? true : false, true);\r\n        defines.setValue(this._defineExplicitName, texture.coordinatesMode === Constants.TEXTURE_EXPLICIT_MODE, true);\r\n        defines.setValue(this._defineSkyboxName, texture.coordinatesMode === Constants.TEXTURE_SKYBOX_MODE, true);\r\n        defines.setValue(this._defineCubicName, texture.coordinatesMode === Constants.TEXTURE_CUBIC_MODE || texture.coordinatesMode === Constants.TEXTURE_INVCUBIC_MODE, true);\r\n        defines.setValue(\"INVERTCUBICMAP\", texture.coordinatesMode === Constants.TEXTURE_INVCUBIC_MODE, true);\r\n        defines.setValue(this._defineSphericalName, texture.coordinatesMode === Constants.TEXTURE_SPHERICAL_MODE, true);\r\n        defines.setValue(this._definePlanarName, texture.coordinatesMode === Constants.TEXTURE_PLANAR_MODE, true);\r\n        defines.setValue(this._defineProjectionName, texture.coordinatesMode === Constants.TEXTURE_PROJECTION_MODE, true);\r\n        defines.setValue(this._defineEquirectangularName, texture.coordinatesMode === Constants.TEXTURE_EQUIRECTANGULAR_MODE, true);\r\n        defines.setValue(this._defineEquirectangularFixedName, texture.coordinatesMode === Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE, true);\r\n        defines.setValue(this._defineMirroredEquirectangularFixedName, texture.coordinatesMode === Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE, true);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        const texture = this._getTexture();\r\n\r\n        if (texture && !texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind for\r\n     * @param _subMesh - the submesh\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh, _subMesh?: SubMesh) {\r\n        const texture = this._getTexture();\r\n\r\n        if (!mesh || !texture) {\r\n            return;\r\n        }\r\n\r\n        effect.setMatrix(this._reflectionMatrixName, texture.getReflectionTextureMatrix());\r\n\r\n        if (texture.isCube) {\r\n            effect.setTexture(this._cubeSamplerName, texture);\r\n        } else {\r\n            effect.setTexture(this._2DSamplerName, texture);\r\n        }\r\n\r\n        if ((<any>texture).boundingBoxSize) {\r\n            const cubeTexture = <CubeTexture>texture;\r\n            effect.setVector3(this._reflectionPositionName, cubeTexture.boundingBoxPosition);\r\n            effect.setVector3(this._reflectionSizeName, cubeTexture.boundingBoxSize);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the code to inject in the vertex shader\r\n     * @param state current state of the node material building\r\n     * @returns the shader code\r\n     */\r\n    public handleVertexSide(state: NodeMaterialBuildState): string {\r\n        if (this.generateOnlyFragmentCode && state.target === NodeMaterialBlockTargets.Vertex) {\r\n            return \"\";\r\n        }\r\n\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        this._define3DName = state._getFreeDefineName(\"REFLECTIONMAP_3D\");\r\n        this._defineCubicName = state._getFreeDefineName(\"REFLECTIONMAP_CUBIC\");\r\n        this._defineSphericalName = state._getFreeDefineName(\"REFLECTIONMAP_SPHERICAL\");\r\n        this._definePlanarName = state._getFreeDefineName(\"REFLECTIONMAP_PLANAR\");\r\n        this._defineProjectionName = state._getFreeDefineName(\"REFLECTIONMAP_PROJECTION\");\r\n        this._defineExplicitName = state._getFreeDefineName(\"REFLECTIONMAP_EXPLICIT\");\r\n        this._defineEquirectangularName = state._getFreeDefineName(\"REFLECTIONMAP_EQUIRECTANGULAR\");\r\n        this._defineLocalCubicName = state._getFreeDefineName(\"USE_LOCAL_REFLECTIONMAP_CUBIC\");\r\n        this._defineMirroredEquirectangularFixedName = state._getFreeDefineName(\"REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED\");\r\n        this._defineEquirectangularFixedName = state._getFreeDefineName(\"REFLECTIONMAP_EQUIRECTANGULAR_FIXED\");\r\n        this._defineSkyboxName = state._getFreeDefineName(\"REFLECTIONMAP_SKYBOX\");\r\n        this._defineOppositeZ = state._getFreeDefineName(\"REFLECTIONMAP_OPPOSITEZ\");\r\n\r\n        this._reflectionMatrixName = state._getFreeVariableName(\"reflectionMatrix\");\r\n\r\n        state._emitUniformFromString(this._reflectionMatrixName, NodeMaterialBlockConnectionPointTypes.Matrix);\r\n\r\n        let code = \"\";\r\n\r\n        this._worldPositionNameInFragmentOnlyMode = state._getFreeVariableName(\"worldPosition\");\r\n\r\n        const worldPosVaryingName = this.generateOnlyFragmentCode ? this._worldPositionNameInFragmentOnlyMode : \"v_\" + this.worldPosition.associatedVariableName;\r\n        if (this.generateOnlyFragmentCode || state._emitVaryingFromString(worldPosVaryingName, NodeMaterialBlockConnectionPointTypes.Vector4)) {\r\n            if (this.generateOnlyFragmentCode) {\r\n                code += `${state._declareLocalVar(worldPosVaryingName, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this.worldPosition.associatedVariableName};\\n`;\r\n            } else {\r\n                code += `${isWebGPU ? \"vertexOutputs.\" : \"\"}${worldPosVaryingName} = ${this.worldPosition.associatedVariableName};\\n`;\r\n            }\r\n        }\r\n\r\n        this._positionUVWName = state._getFreeVariableName(\"positionUVW\");\r\n        this._directionWname = state._getFreeVariableName(\"directionW\");\r\n\r\n        if (this.generateOnlyFragmentCode || state._emitVaryingFromString(this._positionUVWName, NodeMaterialBlockConnectionPointTypes.Vector3, this._defineSkyboxName)) {\r\n            code += `#ifdef ${this._defineSkyboxName}\\n`;\r\n            if (this.generateOnlyFragmentCode) {\r\n                code += `${state._declareLocalVar(this._positionUVWName, NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this.position.associatedVariableName}.xyz;\\n`;\r\n            } else {\r\n                code += `${isWebGPU ? \"vertexOutputs.\" : \"\"}${this._positionUVWName} = ${this.position.associatedVariableName}.xyz;\\n`;\r\n            }\r\n            code += `#endif\\n`;\r\n        }\r\n\r\n        if (\r\n            this.generateOnlyFragmentCode ||\r\n            state._emitVaryingFromString(\r\n                this._directionWname,\r\n                NodeMaterialBlockConnectionPointTypes.Vector3,\r\n                `defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})`\r\n            )\r\n        ) {\r\n            code += `#if defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})\\n`;\r\n            if (this.generateOnlyFragmentCode) {\r\n                code += `${state._declareLocalVar(this._directionWname, NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(vec3${state.fSuffix}(${this.world.associatedVariableName} * vec4${state.fSuffix}(${\r\n                    this.position.associatedVariableName\r\n                }.xyz, 0.0)));\\n`;\r\n            } else {\r\n                code += `${isWebGPU ? \"vertexOutputs.\" : \"\"}${this._directionWname} = normalize(vec3${state.fSuffix}(${this.world.associatedVariableName} * vec4${state.fSuffix}(${\r\n                    this.position.associatedVariableName\r\n                }.xyz, 0.0)));\\n`;\r\n            }\r\n            code += `#endif\\n`;\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Handles the inits for the fragment code path\r\n     * @param state node material build state\r\n     */\r\n    public handleFragmentSideInits(state: NodeMaterialBuildState) {\r\n        state.sharedData.blockingBlocks.push(this);\r\n        state.sharedData.textureBlocks.push(this);\r\n\r\n        // Samplers\r\n        this._cubeSamplerName = state._getFreeVariableName(this.name + \"CubeSampler\");\r\n        state.samplers.push(this._cubeSamplerName);\r\n\r\n        this._2DSamplerName = state._getFreeVariableName(this.name + \"2DSampler\");\r\n        state.samplers.push(this._2DSamplerName);\r\n\r\n        state._samplerDeclaration += `#ifdef ${this._define3DName}\\n`;\r\n        state._emitCubeSampler(this._cubeSamplerName, \"\", true);\r\n        state._samplerDeclaration += `#else\\n`;\r\n        state._emit2DSampler(this._2DSamplerName, \"\", true);\r\n        state._samplerDeclaration += `#endif\\n`;\r\n\r\n        // Fragment\r\n        state.sharedData.blocksWithDefines.push(this);\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n        state._emitFunctionFromInclude(\"reflectionFunction\", comments, {\r\n            replaceStrings: [\r\n                { search: /vec3 computeReflectionCoords/g, replace: \"void DUMMYFUNC\" },\r\n                { search: /fn computeReflectionCoords\\(worldPos: vec4f,worldNormal: vec3f\\)->vec3f/g, replace: \"fn DUMMYFUNC()\" },\r\n            ],\r\n        });\r\n\r\n        this._reflectionColorName = state._getFreeVariableName(\"reflectionColor\");\r\n        this._reflectionVectorName = state._getFreeVariableName(\"reflectionUVW\");\r\n        this._reflectionCoordsName = state._getFreeVariableName(\"reflectionCoords\");\r\n\r\n        this._reflectionPositionName = state._getFreeVariableName(\"vReflectionPosition\");\r\n        state._emitUniformFromString(this._reflectionPositionName, NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._reflectionSizeName = state._getFreeVariableName(\"vReflectionPosition\");\r\n        state._emitUniformFromString(this._reflectionSizeName, NodeMaterialBlockConnectionPointTypes.Vector3);\r\n    }\r\n\r\n    /**\r\n     * Generates the reflection coords code for the fragment code path\r\n     * @param state defines the build state\r\n     * @param worldNormalVarName name of the world normal variable\r\n     * @param worldPos name of the world position variable. If not provided, will use the world position connected to this block\r\n     * @param onlyReflectionVector if true, generates code only for the reflection vector computation, not for the reflection coordinates\r\n     * @param doNotEmitInvertZ if true, does not emit the invertZ code\r\n     * @returns the shader code\r\n     */\r\n    public handleFragmentSideCodeReflectionCoords(\r\n        state: NodeMaterialBuildState,\r\n        worldNormalVarName: string,\r\n        worldPos?: string,\r\n        onlyReflectionVector = false,\r\n        doNotEmitInvertZ = false\r\n    ): string {\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const reflectionMatrix = (isWebGPU ? \"uniforms.\" : \"\") + this._reflectionMatrixName;\r\n        const direction = `normalize(${this._directionWname})`;\r\n        const positionUVW = `${this._positionUVWName}`;\r\n        const vEyePosition = `${this.cameraPosition.associatedVariableName}`;\r\n        const view = `${this.view.associatedVariableName}`;\r\n        const fragmentInputsPrefix = isWebGPU ? \"fragmentInputs.\" : \"\";\r\n\r\n        if (!worldPos) {\r\n            worldPos = this.generateOnlyFragmentCode ? this._worldPositionNameInFragmentOnlyMode : `${fragmentInputsPrefix}v_${this.worldPosition.associatedVariableName}`;\r\n        }\r\n\r\n        worldNormalVarName += \".xyz\";\r\n\r\n        let code = `\r\n            #ifdef ${this._defineMirroredEquirectangularFixedName}\r\n               ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeMirroredFixedEquirectangularCoords(${worldPos}, ${worldNormalVarName}, ${direction});\r\n            #endif\r\n\r\n            #ifdef ${this._defineEquirectangularFixedName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeFixedEquirectangularCoords(${worldPos}, ${worldNormalVarName}, ${direction});\r\n            #endif\r\n\r\n            #ifdef ${this._defineEquirectangularName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeEquirectangularCoords(${worldPos}, ${worldNormalVarName}, ${vEyePosition}.xyz, ${reflectionMatrix});\r\n            #endif\r\n\r\n            #ifdef ${this._defineSphericalName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeSphericalCoords(${worldPos}, ${worldNormalVarName}, ${view}, ${reflectionMatrix});\r\n            #endif\r\n\r\n            #ifdef ${this._definePlanarName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computePlanarCoords(${worldPos}, ${worldNormalVarName}, ${vEyePosition}.xyz, ${reflectionMatrix});\r\n            #endif\r\n\r\n            #ifdef ${this._defineCubicName}\r\n                #ifdef ${this._defineLocalCubicName}\r\n                    ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeCubicLocalCoords(${worldPos}, ${worldNormalVarName}, ${vEyePosition}.xyz, ${reflectionMatrix}, ${this._reflectionSizeName}, ${this._reflectionPositionName});\r\n                #else\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeCubicCoords(${worldPos}, ${worldNormalVarName}, ${vEyePosition}.xyz, ${reflectionMatrix});\r\n                #endif\r\n            #endif\r\n\r\n            #ifdef ${this._defineProjectionName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeProjectionCoords(${worldPos}, ${view}, ${reflectionMatrix});\r\n            #endif\r\n\r\n            #ifdef ${this._defineSkyboxName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = computeSkyBoxCoords(${positionUVW}, ${reflectionMatrix});\r\n            #endif\r\n\r\n            #ifdef ${this._defineExplicitName}\r\n                ${state._declareLocalVar(this._reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = vec3(0, 0, 0);\r\n            #endif\\n`;\r\n\r\n        if (!doNotEmitInvertZ) {\r\n            code += `#ifdef ${this._defineOppositeZ}\r\n                ${this._reflectionVectorName}.z *= -1.0;\r\n            #endif\\n`;\r\n        }\r\n\r\n        if (!onlyReflectionVector) {\r\n            code += `\r\n                #ifdef ${this._define3DName}\r\n                    ${state._declareLocalVar(this._reflectionCoordsName, NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this._reflectionVectorName};\r\n                #else\r\n                    ${state._declareLocalVar(this._reflectionCoordsName, NodeMaterialBlockConnectionPointTypes.Vector2)} = ${this._reflectionVectorName}.xy;\r\n                    #ifdef ${this._defineProjectionName}\r\n                        ${this._reflectionCoordsName} /= ${this._reflectionVectorName}.z;\r\n                    #endif\r\n                    ${this._reflectionCoordsName}.y = 1.0 - ${this._reflectionCoordsName}.y;\r\n                #endif\\n`;\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Generates the reflection color code for the fragment code path\r\n     * @param state defines the build state\r\n     * @param lodVarName name of the lod variable\r\n     * @param swizzleLookupTexture swizzle to use for the final color variable\r\n     * @returns the shader code\r\n     */\r\n    public handleFragmentSideCodeReflectionColor(state: NodeMaterialBuildState, lodVarName?: string, swizzleLookupTexture = \".rgb\"): string {\r\n        let colorType = NodeMaterialBlockConnectionPointTypes.Vector4;\r\n\r\n        if (swizzleLookupTexture.length === 3) {\r\n            colorType = NodeMaterialBlockConnectionPointTypes.Vector3;\r\n        }\r\n\r\n        let code = `${state._declareLocalVar(this._reflectionColorName, colorType)};\r\n            #ifdef ${this._define3DName}\\n`;\r\n\r\n        if (lodVarName) {\r\n            code += `${this._reflectionColorName} = ${state._generateTextureSampleCubeLOD(this._reflectionVectorName, this._cubeSamplerName, lodVarName)}${swizzleLookupTexture};\\n`;\r\n        } else {\r\n            code += `${this._reflectionColorName} = ${state._generateTextureSampleCube(this._reflectionVectorName, this._cubeSamplerName)}${swizzleLookupTexture};\\n`;\r\n        }\r\n\r\n        code += `\r\n            #else\\n`;\r\n\r\n        if (lodVarName) {\r\n            code += `${this._reflectionColorName} =${state._generateTextureSampleLOD(this._reflectionCoordsName, this._2DSamplerName, lodVarName)}${swizzleLookupTexture};\\n`;\r\n        } else {\r\n            code += `${this._reflectionColorName} = ${state._generateTextureSample(this._reflectionCoordsName, this._2DSamplerName)}${swizzleLookupTexture};\\n`;\r\n        }\r\n\r\n        code += `#endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Generates the code corresponding to the connected output points\r\n     * @param state node material build state\r\n     * @param varName name of the variable to output\r\n     * @returns the shader code\r\n     */\r\n    public writeOutputs(state: NodeMaterialBuildState, varName: string): string {\r\n        let code = \"\";\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            for (const output of this._outputs) {\r\n                if (output.hasEndpoints) {\r\n                    code += `${state._declareOutput(output)} = ${varName}.${output.name};\\n`;\r\n                }\r\n            }\r\n        }\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        if (!this.texture) {\r\n            return codeString;\r\n        }\r\n\r\n        if (this.texture.isCube) {\r\n            const forcedExtension = (this.texture as CubeTexture).forcedExtension;\r\n            codeString += `${this._codeVariableName}.texture = new BABYLON.CubeTexture(\"${this.texture.name}\", undefined, undefined, ${\r\n                this.texture.noMipmap\r\n            }, null, undefined, undefined, undefined, ${this.texture._prefiltered}, ${forcedExtension ? '\"' + forcedExtension + '\"' : \"null\"});\\n`;\r\n        } else {\r\n            codeString += `${this._codeVariableName}.texture = new BABYLON.Texture(\"${this.texture.name}\", null);\\n`;\r\n        }\r\n        codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        if (this.texture && !this.texture.isRenderTarget) {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        serializationObject.generateOnlyFragmentCode = this.generateOnlyFragmentCode;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        if (serializationObject.texture && !NodeMaterial.IgnoreTexturesAtLoadTime) {\r\n            rootUrl = serializationObject.texture.url.indexOf(\"data:\") === 0 ? \"\" : rootUrl;\r\n            if (serializationObject.texture.isCube) {\r\n                this.texture = CubeTextureParse(serializationObject.texture, scene, rootUrl);\r\n            } else {\r\n                this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl);\r\n            }\r\n        }\r\n\r\n        this.generateOnlyFragmentCode = serializationObject.generateOnlyFragmentCode;\r\n\r\n        this._setTarget();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for reflectionTextureBaseBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReflectionTextureBaseBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ReflectionTextureBaseBlock\", ReflectionTextureBaseBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { ReflectionTextureBaseBlock } from \"./reflectionTextureBaseBlock.pure\";\r\nimport { type NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to read a reflection texture from a sampler\r\n */\r\nexport class ReflectionTextureBlock extends ReflectionTextureBaseBlock {\r\n    protected override _onGenerateOnlyFragmentCodeChanged(): boolean {\r\n        if (this.position.isConnected) {\r\n            this.generateOnlyFragmentCode = !this.generateOnlyFragmentCode;\r\n            Logger.Error(\"The position input must not be connected to be able to switch!\");\r\n            return false;\r\n        }\r\n\r\n        if (this.worldPosition.isConnected) {\r\n            this.generateOnlyFragmentCode = !this.generateOnlyFragmentCode;\r\n            Logger.Error(\"The worldPosition input must not be connected to be able to switch!\");\r\n            return false;\r\n        }\r\n\r\n        this._setTarget();\r\n\r\n        return true;\r\n    }\r\n\r\n    protected override _setTarget(): void {\r\n        super._setTarget();\r\n        this.getInputByName(\"position\")!.target = this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.Vertex;\r\n        this.getInputByName(\"worldPosition\")!.target = this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.Vertex;\r\n    }\r\n\r\n    /**\r\n     * Create a new ReflectionTextureBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"position\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment); // Flagging as fragment as the normal can be changed by fragment code\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);\r\n\r\n        this.registerInput(\"cameraPosition\", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"r\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"g\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"b\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ReflectionTextureBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get position(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the world input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera (or eye) position component\r\n     */\r\n    public get cameraPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the view input component\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb output component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba output component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the r output component\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the g output component\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the b output component\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the a output component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - optional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        super.autoConfigure(material);\r\n\r\n        if (!this.cameraPosition.isConnected) {\r\n            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.CameraPosition && additionalFilteringInfo(b));\r\n\r\n            if (!cameraPositionInput) {\r\n                cameraPositionInput = new InputBlock(\"cameraPosition\");\r\n                cameraPositionInput.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);\r\n            }\r\n            cameraPositionInput.output.connectTo(this.cameraPosition);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.texture) {\r\n            state.compilationString += this.writeOutputs(state, `vec4${state.fSuffix}(0.)`);\r\n            return this;\r\n        }\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += this.handleVertexSide(state);\r\n            return this;\r\n        }\r\n\r\n        if (this.generateOnlyFragmentCode) {\r\n            state.compilationString += this.handleVertexSide(state);\r\n        }\r\n\r\n        this.handleFragmentSideInits(state);\r\n\r\n        const normalWUnit = state._getFreeVariableName(\"normalWUnit\");\r\n\r\n        state.compilationString += `${state._declareLocalVar(normalWUnit, NodeMaterialBlockConnectionPointTypes.Vector4)} = normalize(${this.worldNormal.associatedVariableName});\\n`;\r\n\r\n        state.compilationString += this.handleFragmentSideCodeReflectionCoords(state, normalWUnit);\r\n\r\n        state.compilationString += this.handleFragmentSideCodeReflectionColor(state, undefined, \"\");\r\n\r\n        state.compilationString += this.writeOutputs(state, this._reflectionColorName);\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for reflectionTextureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReflectionTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ReflectionTextureBlock\", ReflectionTextureBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to retrieve the depth (zbuffer) of the scene\r\n * @since 5.0.0\r\n */\r\nexport class SceneDepthBlock extends NodeMaterialBlock {\r\n    private _samplerName: string;\r\n    private _mainUVName: string;\r\n    private _tempTextureRead: string;\r\n\r\n    /**\r\n     * Defines if the depth renderer should be setup in non linear mode\r\n     */\r\n    @editableInPropertyPage(\"Use non linear depth\", PropertyTypeForEdition.Boolean, \"ADVANCED\", {\r\n        embedded: true,\r\n        notifiers: {\r\n            activatePreviewCommand: true,\r\n            callback: (scene, block) => {\r\n                const sceneDepthBlock = block as SceneDepthBlock;\r\n                let retVal = false;\r\n                if (sceneDepthBlock.useNonLinearDepth) {\r\n                    sceneDepthBlock.storeCameraSpaceZ = false;\r\n                    retVal = true;\r\n                }\r\n                if (scene) {\r\n                    scene.disableDepthRenderer();\r\n                }\r\n                return retVal;\r\n            },\r\n        },\r\n    })\r\n    public useNonLinearDepth = false;\r\n\r\n    /**\r\n     * Defines if the depth renderer should be setup in camera space Z mode (if set, useNonLinearDepth has no effect)\r\n     */\r\n    @editableInPropertyPage(\"Store Camera space Z\", PropertyTypeForEdition.Boolean, \"ADVANCED\", {\r\n        notifiers: {\r\n            activatePreviewCommand: true,\r\n            callback: (scene, block) => {\r\n                const sceneDepthBlock = block as SceneDepthBlock;\r\n                let retVal = false;\r\n                if (sceneDepthBlock.storeCameraSpaceZ) {\r\n                    sceneDepthBlock.useNonLinearDepth = false;\r\n                    retVal = true;\r\n                }\r\n                if (scene) {\r\n                    scene.disableDepthRenderer();\r\n                }\r\n                return retVal;\r\n            },\r\n        },\r\n    })\r\n    public storeCameraSpaceZ = false;\r\n\r\n    /**\r\n     * Defines if the depth renderer should be setup in full 32 bits float mode\r\n     */\r\n    @editableInPropertyPage(\"Force 32 bits float\", PropertyTypeForEdition.Boolean, \"ADVANCED\", {\r\n        notifiers: { activatePreviewCommand: true, callback: (scene) => scene?.disableDepthRenderer() },\r\n    })\r\n    public force32itsFloat = false;\r\n\r\n    /**\r\n     * Create a new SceneDepthBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this.registerOutput(\"depth\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector2 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n\r\n        this._inputs[0]._prioritizeVertex = false;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SceneDepthBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth output component\r\n     */\r\n    public get depth(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"textureSampler\");\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get target() {\r\n        if (!this.uv.isConnected) {\r\n            return NodeMaterialBlockTargets.VertexAndFragment;\r\n        }\r\n\r\n        if (this.uv.sourceBlock!.isInput) {\r\n            return NodeMaterialBlockTargets.VertexAndFragment;\r\n        }\r\n\r\n        return NodeMaterialBlockTargets.Fragment;\r\n    }\r\n\r\n    private _getTexture(scene: Scene): BaseTexture {\r\n        const depthRenderer = scene.enableDepthRenderer(undefined, this.useNonLinearDepth, this.force32itsFloat, undefined, this.storeCameraSpaceZ);\r\n\r\n        return depthRenderer.getDepthMap();\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial) {\r\n        const texture = this._getTexture(nodeMaterial.getScene());\r\n\r\n        effect.setTexture(this._samplerName, texture);\r\n    }\r\n\r\n    private _injectVertexCode(state: NodeMaterialBuildState) {\r\n        const uvInput = this.uv;\r\n\r\n        if (uvInput.connectedPoint!.ownerBlock.isInput) {\r\n            const uvInputOwnerBlock = uvInput.connectedPoint!.ownerBlock as InputBlock;\r\n\r\n            if (!uvInputOwnerBlock.isAttribute) {\r\n                state._emitUniformFromString(\r\n                    uvInput.associatedVariableName,\r\n                    uvInput.type === NodeMaterialBlockConnectionPointTypes.Vector3\r\n                        ? NodeMaterialBlockConnectionPointTypes.Vector3\r\n                        : uvInput.type === NodeMaterialBlockConnectionPointTypes.Vector4\r\n                          ? NodeMaterialBlockConnectionPointTypes.Vector4\r\n                          : NodeMaterialBlockConnectionPointTypes.Vector2\r\n                );\r\n            }\r\n        }\r\n\r\n        this._mainUVName = \"vMain\" + uvInput.associatedVariableName;\r\n\r\n        state._emitVaryingFromString(this._mainUVName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        state.compilationString += `${this._mainUVName} = ${uvInput.associatedVariableName}.xy;\\n`;\r\n\r\n        if (!this._outputs.some((o) => o.isConnectedInVertexShader)) {\r\n            return;\r\n        }\r\n\r\n        this._writeTextureRead(state, true);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                this._writeOutput(state, output, \"r\", true);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _writeTextureRead(state: NodeMaterialBuildState, vertexMode = false) {\r\n        const uvInput = this.uv;\r\n\r\n        if (vertexMode) {\r\n            if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n                return;\r\n            }\r\n            const textureReadFunc =\r\n                state.shaderLanguage === ShaderLanguage.GLSL\r\n                    ? `texture2D(${this._samplerName},`\r\n                    : `textureSampleLevel(${this._samplerName}, ${this._samplerName + Constants.AUTOSAMPLERSUFFIX},`;\r\n\r\n            const complement = state.shaderLanguage === ShaderLanguage.GLSL ? \"\" : \", 0\";\r\n\r\n            state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)}=  ${textureReadFunc} ${uvInput.associatedVariableName}.xy${complement});\\n`;\r\n            return;\r\n        }\r\n\r\n        const textureReadFunc =\r\n            state.shaderLanguage === ShaderLanguage.GLSL\r\n                ? `texture2D(${this._samplerName},`\r\n                : `textureSample(${this._samplerName}, ${this._samplerName + Constants.AUTOSAMPLERSUFFIX},`;\r\n\r\n        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${textureReadFunc} ${uvInput.associatedVariableName}.xy);\\n`;\r\n            return;\r\n        }\r\n\r\n        state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${textureReadFunc} ${this._mainUVName});\\n`;\r\n    }\r\n\r\n    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string, vertexMode = false) {\r\n        if (vertexMode) {\r\n            if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n                return;\r\n            }\r\n\r\n            state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n            return;\r\n        }\r\n\r\n        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n            return;\r\n        }\r\n\r\n        state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\\n`;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._samplerName = state._getFreeVariableName(this.name + \"Sampler\");\r\n        this._tempTextureRead = state._getFreeVariableName(\"tempTextureRead\");\r\n\r\n        if (state.sharedData.bindableBlocks.indexOf(this) < 0) {\r\n            state.sharedData.bindableBlocks.push(this);\r\n        }\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            // Vertex\r\n            state._emit2DSampler(this._samplerName);\r\n            this._injectVertexCode(state);\r\n            return;\r\n        }\r\n\r\n        // Fragment\r\n        if (!this._outputs.some((o) => o.isConnectedInFragmentShader)) {\r\n            return;\r\n        }\r\n\r\n        state._emit2DSampler(this._samplerName);\r\n\r\n        this._writeTextureRead(state);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                this._writeOutput(state, output, \"r\");\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.useNonLinearDepth = this.useNonLinearDepth;\r\n        serializationObject.storeCameraSpaceZ = this.storeCameraSpaceZ;\r\n        serializationObject.force32itsFloat = this.force32itsFloat;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root url\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.useNonLinearDepth = serializationObject.useNonLinearDepth;\r\n        this.storeCameraSpaceZ = !!serializationObject.storeCameraSpaceZ;\r\n        this.force32itsFloat = serializationObject.force32itsFloat;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sceneDepthBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSceneDepthBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SceneDepthBlock\", SceneDepthBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { ImageSourceBlock } from \"./imageSourceBlock.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type Texture } from \"../../../Textures/texture.pure\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide an depth texture for a TextureBlock\r\n */\r\nexport class DepthSourceBlock extends ImageSourceBlock {\r\n    /**\r\n     * Creates a new DepthSourceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public override get texture(): Nullable<Texture> {\r\n        return this._texture;\r\n    }\r\n\r\n    public override set texture(texture: Nullable<Texture>) {\r\n        // Do nothing, we always use the depth texture from the scene\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial) {\r\n        const scene = nodeMaterial.getScene();\r\n        const renderer = scene.enableDepthRenderer();\r\n\r\n        this._texture = renderer.getDepthMap();\r\n\r\n        super.bind(effect, nodeMaterial);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DepthSourceBlock\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        return super._dumpPropertiesCode(true);\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        return super.serialize(true);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for depthSourceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDepthSourceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DepthSourceBlock\", DepthSourceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { BindClipPlane } from \"../../../../Materials/clipPlaneMaterialHelper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used to implement clip planes\r\n */\r\nexport class ClipPlanesBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ClipPlanesBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment, true);\r\n\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ClipPlanesBlock\";\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"vClipPlane\");\r\n        state._excludeVariableName(\"fClipDistance\");\r\n        state._excludeVariableName(\"vClipPlane2\");\r\n        state._excludeVariableName(\"fClipDistance2\");\r\n        state._excludeVariableName(\"vClipPlane3\");\r\n        state._excludeVariableName(\"fClipDistance3\");\r\n        state._excludeVariableName(\"vClipPlane4\");\r\n        state._excludeVariableName(\"fClipDistance4\");\r\n        state._excludeVariableName(\"vClipPlane5\");\r\n        state._excludeVariableName(\"fClipDistance5\");\r\n        state._excludeVariableName(\"vClipPlane6\");\r\n        state._excludeVariableName(\"fClipDistance6\");\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/clipPlaneFragment\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/clipPlaneFragmentDeclaration\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/clipPlaneVertex\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/clipPlaneVertexDeclaration\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/clipPlaneFragment\"),\r\n                import(\"../../../../Shaders/ShadersInclude/clipPlaneFragmentDeclaration\"),\r\n                import(\"../../../../Shaders/ShadersInclude/clipPlaneVertex\"),\r\n                import(\"../../../../Shaders/ShadersInclude/clipPlaneVertexDeclaration\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the worldPosition input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override get target() {\r\n        return NodeMaterialBlockTargets.VertexAndFragment;\r\n    }\r\n\r\n    /** {@inheritDoc} */\r\n    public override set target(value: NodeMaterialBlockTargets) {}\r\n\r\n    /**\r\n     * Prepares the shader defines related to clip planes for the given mesh\r\n     * @param defines - the material defines\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to prepare for\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n\r\n        const useClipPlane1 = (nodeMaterial.clipPlane ?? scene.clipPlane) ? true : false;\r\n        const useClipPlane2 = (nodeMaterial.clipPlane2 ?? scene.clipPlane2) ? true : false;\r\n        const useClipPlane3 = (nodeMaterial.clipPlane3 ?? scene.clipPlane3) ? true : false;\r\n        const useClipPlane4 = (nodeMaterial.clipPlane4 ?? scene.clipPlane4) ? true : false;\r\n        const useClipPlane5 = (nodeMaterial.clipPlane5 ?? scene.clipPlane5) ? true : false;\r\n        const useClipPlane6 = (nodeMaterial.clipPlane6 ?? scene.clipPlane6) ? true : false;\r\n\r\n        defines.setValue(\"CLIPPLANE\", useClipPlane1, true);\r\n        defines.setValue(\"CLIPPLANE2\", useClipPlane2, true);\r\n        defines.setValue(\"CLIPPLANE3\", useClipPlane3, true);\r\n        defines.setValue(\"CLIPPLANE4\", useClipPlane4, true);\r\n        defines.setValue(\"CLIPPLANE5\", useClipPlane5, true);\r\n        defines.setValue(\"CLIPPLANE6\", useClipPlane6, true);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n\r\n        BindClipPlane(effect, nodeMaterial, scene);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const comments = `//${this.name}`;\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            // Vertex\r\n            const worldPos = this.worldPosition;\r\n\r\n            state._emitFunctionFromInclude(\"clipPlaneVertexDeclaration\", comments, {\r\n                replaceStrings: [{ search: /uniform vec4 vClipPlane\\d*;/g, replace: \"\" }],\r\n            });\r\n            state.compilationString += state._emitCodeFromInclude(\"clipPlaneVertex\", comments, {\r\n                replaceStrings: [{ search: /worldPos/g, replace: worldPos.associatedVariableName }],\r\n            });\r\n\r\n            state._emitUniformFromString(\"vClipPlane\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n            state._emitUniformFromString(\"vClipPlane2\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n            state._emitUniformFromString(\"vClipPlane3\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n            state._emitUniformFromString(\"vClipPlane4\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n            state._emitUniformFromString(\"vClipPlane5\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n            state._emitUniformFromString(\"vClipPlane6\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n            return;\r\n        }\r\n\r\n        // Fragment\r\n        state.sharedData.bindableBlocks.push(this);\r\n        state.sharedData.blocksWithDefines.push(this);\r\n\r\n        state._emitFunctionFromInclude(\"clipPlaneFragmentDeclaration\", comments);\r\n        state.compilationString += state._emitCodeFromInclude(\"clipPlaneFragment\", comments);\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for clipPlanesBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterClipPlanesBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ClipPlanesBlock\", ClipPlanesBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type Effect } from \"../../../../Materials/effect.pure\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterial } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { ImageSourceBlock } from \"../Dual/imageSourceBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to read from prepass textures\r\n */\r\nexport class PrePassTextureBlock extends NodeMaterialBlock {\r\n    private _positionSamplerName: string;\r\n    private _localPositionSamplerName: string;\r\n    private _depthSamplerName: string;\r\n    private _screenSpaceDepthSamplerName: string;\r\n    private _normalSamplerName: string;\r\n    private _worldNormalSamplerName: string;\r\n\r\n    /**\r\n     * The texture associated with the node is the prepass texture\r\n     */\r\n    public get texture() {\r\n        return null;\r\n    }\r\n\r\n    public set texture(value: any) {\r\n        return;\r\n    }\r\n\r\n    /**\r\n     * Creates a new PrePassTextureBlock\r\n     * @param name defines the block name\r\n     * @param target defines the target of that block (VertexAndFragment by default)\r\n     */\r\n    public constructor(name: string, target = NodeMaterialBlockTargets.VertexAndFragment) {\r\n        super(name, target, false);\r\n\r\n        this.registerOutput(\r\n            \"position\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"position\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerOutput(\r\n            \"localPosition\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"localPosition\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerOutput(\r\n            \"depth\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"depth\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerOutput(\r\n            \"screenDepth\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"screenDepth\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerOutput(\r\n            \"normal\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"normal\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerOutput(\r\n            \"worldNormal\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"worldNormal\", this, NodeMaterialConnectionPointDirection.Output, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Returns the sampler name associated with the node connection point\r\n     * @param output defines the connection point to get the associated sampler name\r\n     * @returns\r\n     */\r\n    public getSamplerName(output: NodeMaterialConnectionPoint): string {\r\n        if (output === this._outputs[0]) {\r\n            return this._positionSamplerName;\r\n        }\r\n\r\n        if (output === this._outputs[1]) {\r\n            return this._localPositionSamplerName;\r\n        }\r\n\r\n        if (output === this._outputs[2]) {\r\n            return this._depthSamplerName;\r\n        }\r\n\r\n        if (output === this._outputs[3]) {\r\n            return this._screenSpaceDepthSamplerName;\r\n        }\r\n\r\n        if (output === this._outputs[4]) {\r\n            return this._normalSamplerName;\r\n        }\r\n\r\n        if (output === this._outputs[5]) {\r\n            return this._worldNormalSamplerName;\r\n        }\r\n\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * Gets the position texture\r\n     */\r\n    public get position(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the local position texture\r\n     */\r\n    public get localPosition(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth texture\r\n     */\r\n    public get depth(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the screen depth texture\r\n     */\r\n    public get screenDepth(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal texture\r\n     */\r\n    public get normal(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal texture\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get positionSamplerName(): string {\r\n        return this._positionSamplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get localPositionSamplerName(): string {\r\n        return this._localPositionSamplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get normalSamplerName(): string {\r\n        return this._normalSamplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get worldNormalSamplerName(): string {\r\n        return this._worldNormalSamplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get depthSamplerName(): string {\r\n        return this._depthSamplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this image source\r\n     */\r\n    public get linearDepthSamplerName(): string {\r\n        return this._screenSpaceDepthSamplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PrePassTextureBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Vertex) {\r\n            return;\r\n        }\r\n\r\n        this._positionSamplerName = \"prepassPositionSampler\";\r\n        this._depthSamplerName = \"prepassDepthSampler\";\r\n        this._normalSamplerName = \"prepassNormalSampler\";\r\n        this._worldNormalSamplerName = \"prepassWorldNormalSampler\";\r\n        this._localPositionSamplerName = \"prepassLocalPositionSampler\";\r\n        this._screenSpaceDepthSamplerName = \"prepassScreenSpaceDepthSampler\";\r\n\r\n        // Unique sampler names for every prepasstexture block\r\n        state.sharedData.variableNames.prepassPositionSampler = 0;\r\n        state.sharedData.variableNames.prepassDepthSampler = 0;\r\n        state.sharedData.variableNames.prepassNormalSampler = 0;\r\n        state.sharedData.variableNames.prepassWorldNormalSampler = 0;\r\n        state.sharedData.variableNames.prepassLocalPositionSampler = 0;\r\n        state.sharedData.variableNames.prepassScreenSpaceDepthSampler = 0;\r\n\r\n        // Declarations\r\n        state.sharedData.textureBlocks.push(this);\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        if (this.position.isConnected) {\r\n            state._emit2DSampler(this._positionSamplerName);\r\n        }\r\n        if (this.depth.isConnected) {\r\n            state._emit2DSampler(this._depthSamplerName);\r\n        }\r\n        if (this.normal.isConnected) {\r\n            state._emit2DSampler(this._normalSamplerName);\r\n        }\r\n        if (this.worldNormal.isConnected) {\r\n            state._emit2DSampler(this._worldNormalSamplerName);\r\n        }\r\n        if (this.localPosition.isConnected) {\r\n            state._emit2DSampler(this._localPositionSamplerName);\r\n        }\r\n        if (this.screenDepth.isConnected) {\r\n            state._emit2DSampler(this._screenSpaceDepthSamplerName);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - defines the effect to bind data to\r\n     * @param nodeMaterial - defines the node material\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial) {\r\n        const scene = nodeMaterial.getScene();\r\n        const prePassRenderer = scene.enablePrePassRenderer();\r\n        if (!prePassRenderer) {\r\n            return;\r\n        }\r\n\r\n        const sceneRT = prePassRenderer.defaultRT;\r\n        if (!sceneRT.textures) {\r\n            return;\r\n        }\r\n\r\n        if (this.position.isConnected) {\r\n            effect.setTexture(this._positionSamplerName, sceneRT.textures[prePassRenderer.getIndex(Constants.PREPASS_POSITION_TEXTURE_TYPE)]);\r\n        }\r\n        if (this.localPosition.isConnected) {\r\n            effect.setTexture(this._localPositionSamplerName, sceneRT.textures[prePassRenderer.getIndex(Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE)]);\r\n        }\r\n        if (this.depth.isConnected) {\r\n            effect.setTexture(this._depthSamplerName, sceneRT.textures[prePassRenderer.getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE)]);\r\n        }\r\n        if (this.screenDepth.isConnected) {\r\n            effect.setTexture(this._screenSpaceDepthSamplerName, sceneRT.textures[prePassRenderer.getIndex(Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE)]);\r\n        }\r\n        if (this.normal.isConnected) {\r\n            effect.setTexture(this._normalSamplerName, sceneRT.textures[prePassRenderer.getIndex(Constants.PREPASS_NORMAL_TEXTURE_TYPE)]);\r\n        }\r\n        if (this.worldNormal.isConnected) {\r\n            effect.setTexture(this._worldNormalSamplerName, sceneRT.textures[prePassRenderer.getIndex(Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE)]);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for prePassTextureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPrePassTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PrePassTextureBlock\", PrePassTextureBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type NodeMaterialTeleportOutBlock } from \"./teleportOutBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to teleport a value to an endpoint\r\n */\r\nexport class NodeMaterialTeleportInBlock extends NodeMaterialBlock {\r\n    private _endpoints: NodeMaterialTeleportOutBlock[] = [];\r\n\r\n    /** Gets the list of attached endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the target of the block\r\n     */\r\n    public override get target() {\r\n        const input = this._inputs[0];\r\n        if (input.isConnected) {\r\n            const block = input.connectedPoint!.ownerBlock;\r\n            if (block.target !== NodeMaterialBlockTargets.VertexAndFragment) {\r\n                return block.target;\r\n            }\r\n\r\n            if (input.connectedPoint!.target !== NodeMaterialBlockTargets.VertexAndFragment) {\r\n                return input.connectedPoint!.target;\r\n            }\r\n        }\r\n\r\n        return this._target;\r\n    }\r\n\r\n    public override set target(value: NodeMaterialBlockTargets) {\r\n        if ((this._target & value) !== 0) {\r\n            return;\r\n        }\r\n        this._target = value;\r\n    }\r\n\r\n    /**\r\n     * Create a new NodeMaterialTeleportInBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeMaterialTeleportInBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * @returns a boolean indicating that this connection will be used in the fragment shader\r\n     */\r\n    public override isConnectedInFragmentShader() {\r\n        return this.endpoints.some((e) => e.output.isConnectedInFragmentShader);\r\n    }\r\n\r\n    /**\r\n     * Checks if the input is connected to a uniform input block\r\n     */\r\n    public get isConnectedToUniform() {\r\n        return this.input.isConnected && this.input.connectedPoint!.ownerBlock.isInput && (this.input.connectedPoint!.ownerBlock as InputBlock).isUniform;\r\n    }\r\n\r\n    /**\r\n     * Dumps the code for the block\r\n     * @param uniqueNames - the unique names\r\n     * @param alreadyDumped - the already dumped blocks\r\n     * @returns the code string\r\n     */\r\n    public override _dumpCode(uniqueNames: string[], alreadyDumped: NodeMaterialBlock[]) {\r\n        let codeString = super._dumpCode(uniqueNames, alreadyDumped);\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            if (alreadyDumped.indexOf(endpoint) === -1) {\r\n                codeString += endpoint._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOf(block: NodeMaterialBlock): boolean {\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint === block) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.isAnAncestorOf(block)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Add an enpoint to this block\r\n     * @param endpoint define the endpoint to attach to\r\n     */\r\n    public attachToEndpoint(endpoint: NodeMaterialTeleportOutBlock) {\r\n        endpoint.detach();\r\n\r\n        this._endpoints.push(endpoint);\r\n        endpoint._entryPoint = this;\r\n        endpoint._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        endpoint._tempEntryPointUniqueId = null;\r\n        endpoint.name = \"> \" + this.name;\r\n\r\n        this._outputs = this._endpoints.map((e) => e.output);\r\n    }\r\n\r\n    /**\r\n     * Remove enpoint from this block\r\n     * @param endpoint define the endpoint to remove\r\n     */\r\n    public detachFromEndpoint(endpoint: NodeMaterialTeleportOutBlock) {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index !== -1) {\r\n            this._endpoints.splice(index, 1);\r\n            endpoint._outputs[0]._typeConnectionSource = null;\r\n            endpoint._entryPoint = null;\r\n\r\n            this._outputs = this._endpoints.map((e) => e.output);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n\r\n        for (const endpoint of this._endpoints) {\r\n            this.detachFromEndpoint(endpoint);\r\n        }\r\n\r\n        this._endpoints = [];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialsNodeBlocksTeleportTeleportInBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialsNodeBlocksTeleportTeleportInBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeMaterialTeleportInBlock\", NodeMaterialTeleportInBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type NodeMaterialTeleportInBlock } from \"./teleportInBlock.pure\";\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialConnectionPoint } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to receive a value from a teleport entry point\r\n */\r\nexport class NodeMaterialTeleportOutBlock extends NodeMaterialBlock {\r\n    /** @internal */\r\n    public _entryPoint: Nullable<NodeMaterialTeleportInBlock> = null;\r\n    /** @internal */\r\n    public _tempEntryPointUniqueId: Nullable<number> = null;\r\n\r\n    /**\r\n     * Create a new TeleportOutBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n    }\r\n\r\n    /**\r\n     * Gets the entry point\r\n     */\r\n    public get entryPoint() {\r\n        return this._entryPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeMaterialTeleportOutBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the target of the block\r\n     */\r\n    public override get target() {\r\n        return this._entryPoint ? this._entryPoint.target : this._target;\r\n    }\r\n\r\n    public override set target(value: NodeMaterialBlockTargets) {\r\n        if ((this._target & value) !== 0) {\r\n            return;\r\n        }\r\n        this._target = value;\r\n    }\r\n\r\n    /** Detach from entry point */\r\n    public detach() {\r\n        if (!this._entryPoint) {\r\n            return;\r\n        }\r\n\r\n        this._entryPoint.detachFromEndpoint(this);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.entryPoint) {\r\n            return;\r\n        }\r\n\r\n        if (this.entryPoint.isConnectedToUniform) {\r\n            // We skip the build if the entry point is connected to a uniform\r\n            this.output.associatedVariableName = this.entryPoint.input.associatedVariableName;\r\n            return;\r\n        }\r\n\r\n        state.compilationString += state._declareOutput(this.output) + ` = ${this.entryPoint.input.associatedVariableName};\\n`;\r\n\r\n        if (this.entryPoint.endpoints.length > 1) {\r\n            // Check if all the endpoints are in the same shader stage\r\n            const firstConnected = this.entryPoint.endpoints.find((e) => e.output.isConnected);\r\n            if (firstConnected) {\r\n                const firstTarget = firstConnected.output.isConnectedInVertexShader;\r\n                for (const endpoint of this.entryPoint.endpoints) {\r\n                    if (endpoint === firstConnected) {\r\n                        continue;\r\n                    }\r\n                    if (endpoint.output.isConnected && endpoint.output.isConnectedInVertexShader !== firstTarget) {\r\n                        state.sharedData.raiseBuildError(\r\n                            `TeleportInBlock \"${this.entryPoint.name}\" cannot have outputs in different shader stages. All the outputs must be in the same shader stage (vertex or fragment but not both).`\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @param scene defines the hosting scene\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @returns a copy of the current block\r\n     */\r\n    public override clone(scene: Scene, rootUrl: string = \"\") {\r\n        const clone = super.clone(scene, rootUrl);\r\n\r\n        if (this.entryPoint) {\r\n            this.entryPoint.attachToEndpoint(clone as NodeMaterialTeleportOutBlock);\r\n        }\r\n\r\n        return clone;\r\n    }\r\n\r\n    protected override _customBuildStep(state: NodeMaterialBuildState, activeBlocks: NodeMaterialBlock[]): void {\r\n        if (this.entryPoint) {\r\n            this.entryPoint.build(state, activeBlocks);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dumps the code for the block\r\n     * @param uniqueNames - the unique names\r\n     * @param alreadyDumped - the already dumped blocks\r\n     * @returns the code string\r\n     */\r\n    public override _dumpCode(uniqueNames: string[], alreadyDumped: NodeMaterialBlock[]) {\r\n        let codeString: string = \"\";\r\n        if (this.entryPoint) {\r\n            if (alreadyDumped.indexOf(this.entryPoint) === -1) {\r\n                codeString += this.entryPoint._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        return codeString + super._dumpCode(uniqueNames, alreadyDumped);\r\n    }\r\n\r\n    /**\r\n     * Dumps the code for output connections\r\n     * @param alreadyDumped - the already dumped blocks\r\n     * @returns the code string\r\n     */\r\n    public override _dumpCodeForOutputConnections(alreadyDumped: NodeMaterialBlock[]) {\r\n        let codeString = super._dumpCodeForOutputConnections(alreadyDumped);\r\n\r\n        if (this.entryPoint) {\r\n            codeString += this.entryPoint._dumpCodeForOutputConnections(alreadyDumped);\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        if (this.entryPoint) {\r\n            codeString += `${this.entryPoint._codeVariableName}.attachToEndpoint(${this._codeVariableName});\\n`;\r\n        }\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.entryPoint = this.entryPoint?.uniqueId ?? \"\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this._tempEntryPointUniqueId = serializationObject.entryPoint;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialsNodeBlocksTeleportTeleportOutBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialsNodeBlocksTeleportTeleportOutBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeMaterialTeleportOutBlock\", NodeMaterialTeleportOutBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to scale a vector by a float\r\n */\r\nexport class ScaleBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ScaleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"factor\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ScaleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the factor input component\r\n     */\r\n    public get factor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.input.associatedVariableName} * ${this.factor.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for scaleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScaleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ScaleBlock\", ScaleBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clamp a float\r\n */\r\nexport class ClampBlock extends NodeMaterialBlock {\r\n    /** Gets or sets the minimum range */\r\n    @editableInPropertyPage(\"Minimum\", PropertyTypeForEdition.Float, undefined, { embedded: true })\r\n    public minimum = 0.0;\r\n    /** Gets or sets the maximum range */\r\n    @editableInPropertyPage(\"Maximum\", PropertyTypeForEdition.Float, undefined, { embedded: true })\r\n    public maximum = 1.0;\r\n\r\n    /**\r\n     * Creates a new ClampBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ClampBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        const cast = state.shaderLanguage === ShaderLanguage.WGSL ? state._getShaderType(this.value.type) : \"\";\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = clamp(${this.value.associatedVariableName}, ${cast}(${this._writeFloat(this.minimum)}), ${cast}(${this._writeFloat(this.maximum)}));\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.minimum = ${this.minimum};\\n`;\r\n\r\n        codeString += `${this._codeVariableName}.maximum = ${this.maximum};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.minimum = this.minimum;\r\n        serializationObject.maximum = this.maximum;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.minimum = serializationObject.minimum;\r\n        this.maximum = serializationObject.maximum;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for clampBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterClampBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ClampBlock\", ClampBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to apply a cross product between 2 vectors\r\n */\r\nexport class CrossBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new CrossBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CrossBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = cross(${this.left.associatedVariableName}.xyz, ${this.right.associatedVariableName}.xyz);\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for crossBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCrossBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CrossBlock\", CrossBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { ImageSourceBlock } from \"./Dual/imageSourceBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../nodeMaterialConnectionPointCustomObject\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Custom block created from user-defined json\r\n */\r\nexport class CustomBlock extends NodeMaterialBlock {\r\n    private _options: any;\r\n    private _code: string;\r\n    private _inputSamplers: string[];\r\n\r\n    /**\r\n     * Gets or sets the options for this custom block\r\n     */\r\n    public get options() {\r\n        return this._options;\r\n    }\r\n\r\n    public set options(options: any) {\r\n        this._deserializeOptions(options);\r\n    }\r\n\r\n    /**\r\n     * Creates a new CustomBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CustomBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        let code = this._code;\r\n\r\n        let functionName = this._options.functionName;\r\n\r\n        // Replace the TYPE_XXX placeholders (if any)\r\n        for (const input of this._inputs) {\r\n            const rexp = new RegExp(\"\\\\{TYPE_\" + input.name + \"\\\\}\", \"gm\");\r\n            const type = state._getGLType(input.type);\r\n            code = code.replace(rexp, type);\r\n            functionName = functionName.replace(rexp, type);\r\n        }\r\n        for (const output of this._outputs) {\r\n            const rexp = new RegExp(\"\\\\{TYPE_\" + output.name + \"\\\\}\", \"gm\");\r\n            const type = state._getGLType(output.type);\r\n            code = code.replace(rexp, type);\r\n            functionName = functionName.replace(rexp, type);\r\n        }\r\n\r\n        state._emitFunction(functionName, code, \"\");\r\n\r\n        // Declare the output variables\r\n        for (const output of this._outputs) {\r\n            state.compilationString += state._declareOutput(output) + \";\\n\";\r\n        }\r\n\r\n        // Generate the function call\r\n        state.compilationString += functionName + \"(\";\r\n\r\n        let hasInput = false;\r\n        for (let i = 0; i < this._inputs.length; i++) {\r\n            const input = this._inputs[i];\r\n            if (i > 0) {\r\n                state.compilationString += \", \";\r\n            }\r\n            if (this._inputSamplers && this._inputSamplers.indexOf(input.name) !== -1) {\r\n                state.compilationString += (input.connectedPoint?.ownerBlock as ImageSourceBlock)?.samplerName ?? input.associatedVariableName;\r\n            } else {\r\n                state.compilationString += input.associatedVariableName;\r\n            }\r\n            hasInput = true;\r\n        }\r\n\r\n        for (let i = 0; i < this._outputs.length; i++) {\r\n            const output = this._outputs[i];\r\n            if (i > 0 || hasInput) {\r\n                state.compilationString += \", \";\r\n            }\r\n            state.compilationString += output.associatedVariableName;\r\n        }\r\n\r\n        state.compilationString += \");\\n\";\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.options = ${JSON.stringify(this._options)};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.options = this._options;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        this._deserializeOptions(serializationObject.options);\r\n\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n    }\r\n\r\n    private _deserializeOptions(options: any) {\r\n        this._options = options;\r\n        this._code = options.code.join(\"\\n\") + \"\\n\";\r\n        this.name = this.name || options.name;\r\n        this.target = (<any>NodeMaterialBlockTargets)[options.target];\r\n\r\n        if (options.inParameters) {\r\n            for (let i = 0; i < options.inParameters.length; i++) {\r\n                const input = options.inParameters[i];\r\n                const type = (<any>NodeMaterialBlockConnectionPointTypes)[input.type];\r\n                if (input.type === \"sampler2D\" || input.type === \"samplerCube\" || input.type === \"sampler2DArray\") {\r\n                    this._inputSamplers = this._inputSamplers || [];\r\n                    this._inputSamplers.push(input.name);\r\n                    this.registerInput(\r\n                        input.name,\r\n                        NodeMaterialBlockConnectionPointTypes.Object,\r\n                        true,\r\n                        NodeMaterialBlockTargets.VertexAndFragment,\r\n                        new NodeMaterialConnectionPointCustomObject(input.name, this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n                    );\r\n                } else {\r\n                    this.registerInput(input.name, type);\r\n                }\r\n\r\n                Object.defineProperty(this, input.name, {\r\n                    get: function () {\r\n                        return this._inputs[i];\r\n                    },\r\n                    enumerable: true,\r\n                    configurable: true,\r\n                });\r\n            }\r\n        }\r\n\r\n        if (options.outParameters) {\r\n            for (let i = 0; i < options.outParameters.length; i++) {\r\n                const output = options.outParameters[i];\r\n\r\n                this.registerOutput(output.name, (<any>NodeMaterialBlockConnectionPointTypes)[output.type]);\r\n\r\n                Object.defineProperty(this, output.name, {\r\n                    get: function () {\r\n                        return this._outputs[i];\r\n                    },\r\n                    enumerable: true,\r\n                    configurable: true,\r\n                });\r\n\r\n                if (output.type === \"BasedOnInput\") {\r\n                    this._outputs[i]._typeConnectionSource = this._findInputByName(output.typeFromInput)![0];\r\n                }\r\n            }\r\n        }\r\n\r\n        if (options.inLinkedConnectionTypes) {\r\n            for (const connection of options.inLinkedConnectionTypes) {\r\n                this._linkConnectionTypes(this._findInputByName(connection.input1)![1], this._findInputByName(connection.input2)![1]);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _findInputByName(name: string): Nullable<[NodeMaterialConnectionPoint, number]> {\r\n        if (!name) {\r\n            return null;\r\n        }\r\n\r\n        for (let i = 0; i < this._inputs.length; i++) {\r\n            if (this._inputs[i].name === name) {\r\n                return [this._inputs[i], i];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for customBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCustomBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CustomBlock\", CustomBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to apply a dot product between 2 vectors\r\n */\r\nexport class DotBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new DotBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DotBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = dot(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for dotBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDotBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DotBlock\", DotBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to normalize a vector\r\n */\r\nexport class NormalizeBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new NormalizeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NormalizeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input = this._inputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = normalize(${input.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for normalizeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNormalizeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NormalizeBlock\", NormalizeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to create a Color3/4 out of individual inputs (one for each component)\r\n */\r\nexport class ColorMergerBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the swizzle for r (meaning which component to affect to the output.r)\r\n     */\r\n    public rSwizzle: \"r\" | \"g\" | \"b\" | \"a\" = \"r\";\r\n    /**\r\n     * Gets or sets the swizzle for g (meaning which component to affect to the output.g)\r\n     */\r\n    public gSwizzle: \"r\" | \"g\" | \"b\" | \"a\" = \"g\";\r\n    /**\r\n     * Gets or sets the swizzle for b (meaning which component to affect to the output.b)\r\n     */\r\n    public bSwizzle: \"r\" | \"g\" | \"b\" | \"a\" = \"b\";\r\n    /**\r\n     * Gets or sets the swizzle for a (meaning which component to affect to the output.a)\r\n     */\r\n    public aSwizzle: \"r\" | \"g\" | \"b\" | \"a\" = \"a\";\r\n\r\n    /**\r\n     * Create a new ColorMergerBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"rgb \", NodeMaterialBlockConnectionPointTypes.Color3, true);\r\n        this.registerInput(\"r\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"g\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"b\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ColorMergerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component (input)\r\n     */\r\n    public get rgbIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the r component (input)\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the g component (input)\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the b component (input)\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the a component (input)\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba component (output)\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component (output)\r\n     */\r\n    public get rgbOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component (output)\r\n     * @deprecated Please use rgbOut instead.\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this.rgbOut;\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"rgb \") {\r\n            return \"rgbIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _outputRename(name: string) {\r\n        if (name === \"rgb\") {\r\n            return \"rgbOut\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    private _buildSwizzle(len: number) {\r\n        const swizzle = this.rSwizzle + this.gSwizzle + this.bSwizzle + this.aSwizzle;\r\n        return \".\" + swizzle.substring(0, len);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const rInput = this.r;\r\n        const gInput = this.g;\r\n        const bInput = this.b;\r\n        const aInput = this.a;\r\n        const rgbInput = this.rgbIn;\r\n\r\n        const color4Output = this._outputs[0];\r\n        const color3Output = this._outputs[1];\r\n\r\n        const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        const vec3 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        if (rgbInput.isConnected) {\r\n            if (color4Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(color4Output) +\r\n                    ` = ${vec4}(${rgbInput.associatedVariableName}, ${aInput.isConnected ? this._writeVariable(aInput) : \"0.0\"})${this._buildSwizzle(4)};\\n`;\r\n            }\r\n\r\n            if (color3Output.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(color3Output) + ` = ${rgbInput.associatedVariableName}${this._buildSwizzle(3)};\\n`;\r\n            }\r\n        } else {\r\n            if (color4Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(color4Output) +\r\n                    ` = ${vec4}(${rInput.isConnected ? this._writeVariable(rInput) : \"0.0\"}, ${gInput.isConnected ? this._writeVariable(gInput) : \"0.0\"}, ${\r\n                        bInput.isConnected ? this._writeVariable(bInput) : \"0.0\"\r\n                    }, ${aInput.isConnected ? this._writeVariable(aInput) : \"0.0\"})${this._buildSwizzle(4)};\\n`;\r\n            }\r\n\r\n            if (color3Output.hasEndpoints) {\r\n                state.compilationString +=\r\n                    state._declareOutput(color3Output) +\r\n                    ` = ${vec3}(${rInput.isConnected ? this._writeVariable(rInput) : \"0.0\"}, ${gInput.isConnected ? this._writeVariable(gInput) : \"0.0\"}, ${\r\n                        bInput.isConnected ? this._writeVariable(bInput) : \"0.0\"\r\n                    })${this._buildSwizzle(3)};\\n`;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.rSwizzle = this.rSwizzle;\r\n        serializationObject.gSwizzle = this.gSwizzle;\r\n        serializationObject.bSwizzle = this.bSwizzle;\r\n        serializationObject.aSwizzle = this.aSwizzle;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.rSwizzle = serializationObject.rSwizzle ?? \"r\";\r\n        this.gSwizzle = serializationObject.gSwizzle ?? \"g\";\r\n        this.bSwizzle = serializationObject.bSwizzle ?? \"b\";\r\n        this.aSwizzle = serializationObject.aSwizzle ?? \"a\";\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n        codeString += `${this._codeVariableName}.rSwizzle = \"${this.rSwizzle}\";\\n`;\r\n        codeString += `${this._codeVariableName}.gSwizzle = \"${this.gSwizzle}\";\\n`;\r\n        codeString += `${this._codeVariableName}.bSwizzle = \"${this.bSwizzle}\";\\n`;\r\n        codeString += `${this._codeVariableName}.aSwizzle = \"${this.aSwizzle}\";\\n`;\r\n\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for colorMergerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterColorMergerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ColorMergerBlock\", ColorMergerBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to expand a Vector3/4 into 4 outputs (one for each component)\r\n */\r\nexport class VectorSplitterBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new VectorSplitterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"xyzw\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"xyz \", NodeMaterialBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"xy \", NodeMaterialBlockConnectionPointTypes.Vector2, true);\r\n\r\n        this.registerOutput(\"xyz\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"xy\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"zw\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"x\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"y\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"z\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"w\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.inputsAreExclusive = true;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"VectorSplitterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component (input)\r\n     */\r\n    public get xyzw(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (input)\r\n     */\r\n    public get xyzIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (input)\r\n     */\r\n    public get xyIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (output)\r\n     */\r\n    public get xyzOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (output)\r\n     */\r\n    public get xyOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (output)\r\n     */\r\n    public get zw(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component (output)\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component (output)\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component (output)\r\n     */\r\n    public get z(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component (output)\r\n     */\r\n    public get w(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        switch (name) {\r\n            case \"xy \":\r\n                return \"xyIn\";\r\n            case \"xyz \":\r\n                return \"xyzIn\";\r\n            default:\r\n                return name;\r\n        }\r\n    }\r\n\r\n    protected override _outputRename(name: string) {\r\n        switch (name) {\r\n            case \"xy\":\r\n                return \"xyOut\";\r\n            case \"xyz\":\r\n                return \"xyzOut\";\r\n            default:\r\n                return name;\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const input = this.xyzw.isConnected ? this.xyzw : this.xyzIn.isConnected ? this.xyzIn : this.xyIn;\r\n\r\n        const xyzOutput = this._outputs[0];\r\n        const xyOutput = this._outputs[1];\r\n        const zwOutput = this._outputs[2];\r\n        const xOutput = this._outputs[3];\r\n        const yOutput = this._outputs[4];\r\n        const zOutput = this._outputs[5];\r\n        const wOutput = this._outputs[6];\r\n\r\n        const vec3 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        if (xyzOutput.hasEndpoints) {\r\n            if (input === this.xyIn) {\r\n                state.compilationString += state._declareOutput(xyzOutput) + ` = ${vec3}(${input.associatedVariableName}, 0.0);\\n`;\r\n            } else {\r\n                state.compilationString += state._declareOutput(xyzOutput) + ` = ${input.associatedVariableName}.xyz;\\n`;\r\n            }\r\n        }\r\n        if (zwOutput.hasEndpoints && this.xyzw.isConnected) {\r\n            state.compilationString += state._declareOutput(zwOutput) + ` = ${this.xyzw.associatedVariableName}.zw;\\n`;\r\n        }\r\n        if (xyOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(xyOutput) + ` = ${input.associatedVariableName}.xy;\\n`;\r\n        }\r\n        if (xOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(xOutput) + ` = ${input.associatedVariableName}.x;\\n`;\r\n        }\r\n        if (yOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(yOutput) + ` = ${input.associatedVariableName}.y;\\n`;\r\n        }\r\n        if (zOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(zOutput) + ` = ${input.associatedVariableName}.z;\\n`;\r\n        }\r\n        if (wOutput.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(wOutput) + ` = ${input.associatedVariableName}.w;\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vectorSplitterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVectorSplitterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.VectorSplitterBlock\", VectorSplitterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to lerp between 2 values\r\n */\r\nexport class LerpBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new LerpBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"gradient\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n        this._linkConnectionTypes(1, 2, true);\r\n\r\n        this._inputs[2].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"LerpBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) + ` = mix(${this.left.associatedVariableName} , ${this.right.associatedVariableName}, ${this.gradient.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for lerpBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLerpBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.LerpBlock\", LerpBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { BaseMathBlock } from \"./baseMathBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to divide 2 vectors\r\n */\r\nexport class DivideBlock extends BaseMathBlock {\r\n    /**\r\n     * Creates a new DivideBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DivideBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.left.associatedVariableName} / ${this.right.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for divideBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDivideBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DivideBlock\", DivideBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { BaseMathBlock } from \"./baseMathBlock\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to subtract 2 vectors\r\n */\r\nexport class SubtractBlock extends BaseMathBlock {\r\n    /**\r\n     * Creates a new SubtractBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SubtractBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.left.associatedVariableName} - ${this.right.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for subtractBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSubtractBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SubtractBlock\", SubtractBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to step a value\r\n */\r\nexport class StepBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new StepBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"edge\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"StepBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the edge operand input component\r\n     */\r\n    public get edge(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = step(${this.edge.associatedVariableName}, ${this.value.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for stepBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStepBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.StepBlock\", StepBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the opposite (1 - x) of a value\r\n */\r\nexport class OneMinusBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new OneMinusBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._outputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"OneMinusBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = 1. - ${this.input.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for oneMinusBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterOneMinusBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.OneMinusBlock\", OneMinusBlock);\r\n    RegisterClass(\"BABYLON.OppositeBlock\", OneMinusBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterial } from \"../nodeMaterial.pure\";\r\nimport { NodeMaterialSystemValues } from \"../Enums/nodeMaterialSystemValues\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the view direction\r\n */\r\nexport class ViewDirectionBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ViewDirectionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"cameraPosition\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ViewDirectionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera position component\r\n     */\r\n    public get cameraPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.cameraPosition.isConnected) {\r\n            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.CameraPosition && additionalFilteringInfo(b));\r\n\r\n            if (!cameraPositionInput) {\r\n                cameraPositionInput = new InputBlock(\"cameraPosition\");\r\n                cameraPositionInput.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);\r\n            }\r\n            cameraPositionInput.output.connectTo(this.cameraPosition);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) + ` = normalize(${this.cameraPosition.associatedVariableName} - ${this.worldPosition.associatedVariableName}.xyz);\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for viewDirectionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterViewDirectionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ViewDirectionBlock\", ViewDirectionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { type NodeMaterial } from \"../nodeMaterial.pure\";\r\nimport { ViewDirectionBlock } from \"./viewDirectionBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to compute fresnel value\r\n */\r\nexport class FresnelBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new FresnelBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"viewDirection\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"bias\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"power\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.registerOutput(\"fresnel\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"FresnelBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the view direction input component\r\n     */\r\n    public get viewDirection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the bias input component\r\n     */\r\n    public get bias(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera (or eye) position component\r\n     */\r\n    public get power(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the fresnel output component\r\n     */\r\n    public get fresnel(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../ShadersWGSL/ShadersInclude/fresnelFunction\");\r\n        } else {\r\n            await import(\"../../../Shaders/ShadersInclude/fresnelFunction\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     */\r\n    public override autoConfigure(material: NodeMaterial) {\r\n        if (!this.viewDirection.isConnected) {\r\n            const viewDirectionInput = new ViewDirectionBlock(\"View direction\");\r\n            viewDirectionInput.output.connectTo(this.viewDirection);\r\n            viewDirectionInput.autoConfigure(material);\r\n        }\r\n\r\n        if (!this.bias.isConnected) {\r\n            const biasInput = new InputBlock(\"bias\");\r\n            biasInput.value = 0;\r\n            biasInput.output.connectTo(this.bias);\r\n        }\r\n\r\n        if (!this.power.isConnected) {\r\n            const powerInput = new InputBlock(\"power\");\r\n            powerInput.value = 1;\r\n            powerInput.output.connectTo(this.power);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const comments = `//${this.name}`;\r\n\r\n        state._emitFunctionFromInclude(\"fresnelFunction\", comments, { removeIfDef: true });\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(this.fresnel) +\r\n            ` = computeFresnelTerm(${this.viewDirection.associatedVariableName}.xyz, ${this.worldNormal.associatedVariableName}.xyz, ${this.bias.associatedVariableName}, ${this.power.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fresnelBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFresnelBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FresnelBlock\", FresnelBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the max of 2 values\r\n */\r\nexport class MaxBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MaxBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MaxBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = max(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for maxBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaxBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MaxBlock\", MaxBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the min of 2 values\r\n */\r\nexport class MinBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MinBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MinBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = min(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for minBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMinBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MinBlock\", MinBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the distance between 2 values\r\n */\r\nexport class DistanceBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new DistanceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DistanceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = length(${this.left.associatedVariableName} - ${this.right.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for distanceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDistanceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DistanceBlock\", DistanceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the length of a vector\r\n */\r\nexport class LengthBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new LengthBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"LengthBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = length(${this.value.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for lengthBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLengthBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.LengthBlock\", LengthBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get negative version of a value (i.e. x * -1)\r\n */\r\nexport class NegateBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new NegateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NegateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = -1.0 * ${this.value.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for negateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNegateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NegateBlock\", NegateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the value of the first parameter raised to the power of the second\r\n */\r\nexport class PowBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new PowBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"power\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PowBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the power operand input component\r\n     */\r\n    public get power(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const zero = `${state._getShaderType(output.type)}(0.)`;\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = pow(max(${this.value.associatedVariableName}, ${zero}), ${this.power.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for powBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPowBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PowBlock\", PowBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a random number\r\n */\r\nexport class RandomNumberBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new RandomNumberBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"seed\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector2 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RandomNumberBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the seed input component\r\n     */\r\n    public get seed(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = getRand(${this.seed.associatedVariableName}.xy);\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for randomNumberBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRandomNumberBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RandomNumberBlock\", RandomNumberBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to compute arc tangent of 2 values\r\n */\r\nexport class ArcTan2Block extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ArcTan2Block\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"x\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"y\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ArcTan2Block\";\r\n    }\r\n\r\n    /**\r\n     * Gets the x operand input component\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the y operand input component\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        const func = state.shaderLanguage === ShaderLanguage.WGSL ? \"atan2\" : \"atan\";\r\n        state.compilationString += state._declareOutput(output) + ` = ${func}(${this.x.associatedVariableName}, ${this.y.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for arcTan2Block.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterArcTan2Block(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ArcTan2Block\", ArcTan2Block);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to smooth step a value\r\n */\r\nexport class SmoothStepBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new SmoothStepBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"edge0\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"edge1\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SmoothStepBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the first edge operand input component\r\n     */\r\n    public get edge0(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the second edge operand input component\r\n     */\r\n    public get edge1(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const cast = state._getShaderType(this.value.type);\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = smoothstep(${cast}(${this.edge0.associatedVariableName}), ${cast}(${this.edge1.associatedVariableName}), ${this.value.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for smoothStepBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSmoothStepBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SmoothStepBlock\", SmoothStepBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the reciprocal (1 / x) of a value\r\n */\r\nexport class ReciprocalBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ReciprocalBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ReciprocalBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        if (this.input.type === NodeMaterialBlockConnectionPointTypes.Matrix) {\r\n            state.compilationString += state._declareOutput(output) + ` = inverse(${this.input.associatedVariableName});\\n`;\r\n        } else {\r\n            state.compilationString += state._declareOutput(output) + ` = 1. / ${this.input.associatedVariableName};\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for reciprocalBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReciprocalBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ReciprocalBlock\", ReciprocalBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to replace a color by another one\r\n */\r\nexport class ReplaceColorBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ReplaceColorBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"reference\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"distance\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"replacement\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n        this._linkConnectionTypes(0, 3);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[3].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n        this._inputs[3].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ReplaceColorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the reference input component\r\n     */\r\n    public get reference(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the distance input component\r\n     */\r\n    public get distance(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the replacement input component\r\n     */\r\n    public get replacement(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + `;\\n`;\r\n        state.compilationString += `if (length(${this.value.associatedVariableName} - ${this.reference.associatedVariableName}) < ${this.distance.associatedVariableName}) {\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = ${this.replacement.associatedVariableName};\\n`;\r\n        state.compilationString += `} else {\\n`;\r\n        state.compilationString += `${output.associatedVariableName} = ${this.value.associatedVariableName};\\n`;\r\n        state.compilationString += `}\\n`;\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for replaceColorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReplaceColorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ReplaceColorBlock\", ReplaceColorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to posterize a value\r\n * @see https://en.wikipedia.org/wiki/Posterization\r\n */\r\nexport class PosterizeBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new PosterizeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"steps\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PosterizeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the steps input component\r\n     */\r\n    public get steps(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = floor(${this.value.associatedVariableName} / (1.0 / ${this.steps.associatedVariableName})) * (1.0 / ${this.steps.associatedVariableName});\\n`;\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for posterizeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPosterizeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PosterizeBlock\", PosterizeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Wave block\r\n */\r\nexport const enum WaveBlockKind {\r\n    /** SawTooth */\r\n    SawTooth,\r\n    /** Square */\r\n    Square,\r\n    /** Triangle */\r\n    Triangle,\r\n}\r\n\r\n/**\r\n * Block used to apply wave operation to floats\r\n */\r\nexport class WaveBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the kibnd of wave to be applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Kind\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"SawTooth\", value: WaveBlockKind.SawTooth },\r\n            { label: \"Square\", value: WaveBlockKind.Square },\r\n            { label: \"Triangle\", value: WaveBlockKind.Triangle },\r\n        ],\r\n    })\r\n    public kind = WaveBlockKind.SawTooth;\r\n\r\n    /**\r\n     * Creates a new WaveBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"WaveBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        switch (this.kind) {\r\n            case WaveBlockKind.SawTooth: {\r\n                state.compilationString += state._declareOutput(output) + ` = ${this.input.associatedVariableName} - floor(0.5 + ${this.input.associatedVariableName});\\n`;\r\n                break;\r\n            }\r\n            case WaveBlockKind.Square: {\r\n                state.compilationString += state._declareOutput(output) + ` = 1.0 - 2.0 * round(fract(${this.input.associatedVariableName}));\\n`;\r\n                break;\r\n            }\r\n            case WaveBlockKind.Triangle: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) + ` = 2.0 * abs(2.0 * (${this.input.associatedVariableName} - floor(0.5 + ${this.input.associatedVariableName}))) - 1.0;\\n`;\r\n                break;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.kind = this.kind;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.kind = serializationObject.kind;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for waveBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWaveBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.WaveBlock\", WaveBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { Color3 } from \"../../../Maths/math.color.pure\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { Observable } from \"../../../Misc/observable.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Class used to store a color step for the GradientBlock\r\n */\r\nexport class GradientBlockColorStep {\r\n    private _step: number;\r\n    /**\r\n     * Gets value indicating which step this color is associated with (between 0 and 1)\r\n     */\r\n    public get step(): number {\r\n        return this._step;\r\n    }\r\n\r\n    /**\r\n     * Sets a value indicating which step this color is associated with (between 0 and 1)\r\n     */\r\n    public set step(val: number) {\r\n        this._step = val;\r\n    }\r\n\r\n    private _color: Color3;\r\n\r\n    /**\r\n     * Gets the color associated with this step\r\n     */\r\n    public get color(): Color3 {\r\n        return this._color;\r\n    }\r\n\r\n    /**\r\n     * Sets the color associated with this step\r\n     */\r\n    public set color(val: Color3) {\r\n        this._color = val;\r\n    }\r\n\r\n    /**\r\n     * Creates a new GradientBlockColorStep\r\n     * @param step defines a value indicating which step this color is associated with (between 0 and 1)\r\n     * @param color defines the color associated with this step\r\n     */\r\n    public constructor(step: number, color: Color3) {\r\n        this.step = step;\r\n        this.color = color;\r\n    }\r\n}\r\n\r\n/**\r\n * Block used to return a color from a gradient based on an input value between 0 and 1\r\n */\r\nexport class GradientBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the list of color steps\r\n     */\r\n    public colorSteps: GradientBlockColorStep[] = [new GradientBlockColorStep(0, Color3.Black()), new GradientBlockColorStep(1.0, Color3.White())];\r\n\r\n    /** Gets an observable raised when the value is changed */\r\n    public onValueChangedObservable = new Observable<GradientBlock>();\r\n\r\n    /** calls observable when the value is changed*/\r\n    public colorStepsUpdated() {\r\n        this.onValueChangedObservable.notifyObservers(this);\r\n    }\r\n    /**\r\n     * Creates a new GradientBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"gradient\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Float |\r\n                NodeMaterialBlockConnectionPointTypes.Vector2 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GradientBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient input component\r\n     */\r\n    public get gradient(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _writeColorConstant(index: number, vec3: string) {\r\n        const step = this.colorSteps[index];\r\n        return `${vec3}(${step.color.r}, ${step.color.g}, ${step.color.b})`;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const vec3 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        if (!this.colorSteps.length || !this.gradient.connectedPoint) {\r\n            state.compilationString += state._declareOutput(output) + ` = ${vec3}(0., 0., 0.);\\n`;\r\n            return;\r\n        }\r\n\r\n        const tempColor = state._getFreeVariableName(\"gradientTempColor\");\r\n        const tempPosition = state._getFreeVariableName(\"gradientTempPosition\");\r\n\r\n        state.compilationString += `${state._declareLocalVar(tempColor, NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this._writeColorConstant(0, vec3)};\\n`;\r\n        state.compilationString += `${state._declareLocalVar(tempPosition, NodeMaterialBlockConnectionPointTypes.Float)};\\n`;\r\n\r\n        let gradientSource = this.gradient.associatedVariableName;\r\n\r\n        if (this.gradient.connectedPoint.type !== NodeMaterialBlockConnectionPointTypes.Float) {\r\n            gradientSource += \".x\";\r\n        }\r\n\r\n        for (let index = 1; index < this.colorSteps.length; index++) {\r\n            const step = this.colorSteps[index];\r\n            const previousStep = this.colorSteps[index - 1];\r\n            state.compilationString += `${tempPosition} = clamp((${gradientSource} - ${state._emitFloat(previousStep.step)}) / (${state._emitFloat(\r\n                step.step\r\n            )} -  ${state._emitFloat(previousStep.step)}), 0.0, 1.0) * step(${state._emitFloat(index)}, ${state._emitFloat(this.colorSteps.length - 1)});\\n`;\r\n            state.compilationString += `${tempColor} = mix(${tempColor}, ${this._writeColorConstant(index, vec3)}, ${tempPosition});\\n`;\r\n        }\r\n        state.compilationString += state._declareOutput(output) + ` = ${tempColor};\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.colorSteps = [];\r\n\r\n        for (const step of this.colorSteps) {\r\n            serializationObject.colorSteps.push({\r\n                step: step.step,\r\n                color: {\r\n                    r: step.color.r,\r\n                    g: step.color.g,\r\n                    b: step.color.b,\r\n                },\r\n            });\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.colorSteps.length = 0;\r\n\r\n        for (const step of serializationObject.colorSteps) {\r\n            this.colorSteps.push(new GradientBlockColorStep(step.step, new Color3(step.color.r, step.color.g, step.color.b)));\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.colorSteps = [];\\n`;\r\n\r\n        for (const colorStep of this.colorSteps) {\r\n            codeString += `${this._codeVariableName}.colorSteps.push(new BABYLON.GradientBlockColorStep(${colorStep.step}, new BABYLON.Color3(${colorStep.color.r}, ${colorStep.color.g}, ${colorStep.color.b})));\\n`;\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gradientBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGradientBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GradientBlock\", GradientBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to normalize lerp between 2 values\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class NLerpBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new NLerpBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"gradient\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n        this._linkConnectionTypes(1, 2, true);\r\n\r\n        this._inputs[2].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NLerpBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = normalize(mix(${this.left.associatedVariableName} , ${this.right.associatedVariableName}, ${this.gradient.associatedVariableName}));\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for nLerpBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RegisterNLerpBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NLerpBlock\", NLerpBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { ShaderLanguage } from \"../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * block used to Generate a Worley Noise 3D Noise Pattern\r\n */\r\n\r\n//  Source: https://github.com/Erkaman/glsl-worley\r\n//  Converted to BJS by Pryme8\r\n//\r\n//  Worley Noise 3D\r\n//  Return vec2 value range of -1.0->1.0, F1-F2 respectivly\r\n\r\n/** Block used to generate Worley Noise 3D */\r\nexport class WorleyNoise3DBlock extends NodeMaterialBlock {\r\n    /** Gets or sets a boolean indicating that normal should be inverted on X axis */\r\n    @editableInPropertyPage(\"Use Manhattan Distance\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true, notifiers: { update: false } })\r\n    public manhattanDistance = false;\r\n\r\n    /**\r\n     * Creates a new WorleyNoise3DBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n        this.registerInput(\"seed\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"jitter\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"x\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"y\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"WorleyNoise3DBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the seed input component\r\n     */\r\n    public get seed(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the jitter input component\r\n     */\r\n    public get jitter(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component\r\n     */\r\n    public get x(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component\r\n     */\r\n    public get y(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.seed.isConnected) {\r\n            return;\r\n        }\r\n\r\n        if (!this.output.hasEndpoints && !this.x.hasEndpoints && !this.y.hasEndpoints) {\r\n            return;\r\n        }\r\n\r\n        let functionString = `vec3 permute(vec3 x){\\n`;\r\n        functionString += `    return mod((34.0 * x + 1.0) * x, 289.0);\\n`;\r\n        functionString += `}\\n\\n`;\r\n\r\n        functionString += `vec3 dist(vec3 x, vec3 y, vec3 z,  bool manhattanDistance){\\n`;\r\n        functionString += `    return [manhattanDistance ?  abs(x) + abs(y) + abs(z) :  (x * x + y * y + z * z)];\\n`;\r\n        functionString += `}\\n\\n`;\r\n\r\n        functionString += `vec2 worley(vec3 P, float jitter, bool manhattanDistance){\\n`;\r\n        functionString += `    float K = 0.142857142857; // 1/7\\n`;\r\n        functionString += `    float Ko = 0.428571428571; // 1/2-K/2\\n`;\r\n        functionString += `    float  K2 = 0.020408163265306; // 1/(7*7)\\n`;\r\n        functionString += `    float Kz = 0.166666666667; // 1/6\\n`;\r\n        functionString += `    float Kzo = 0.416666666667; // 1/2-1/6*2\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 Pi = mod(floor(P), 289.0);\\n`;\r\n        functionString += `    vec3 Pf = fract(P) - 0.5;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 Pfx = Pf.x + vec3(1.0, 0.0, -1.0);\\n`;\r\n        functionString += `    vec3 Pfy = Pf.y + vec3(1.0, 0.0, -1.0);\\n`;\r\n        functionString += `    vec3 Pfz = Pf.z + vec3(1.0, 0.0, -1.0);\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 p = permute(Pi.x + vec3(-1.0, 0.0, 1.0));\\n`;\r\n        functionString += `    vec3 p1 = permute(p + Pi.y - 1.0);\\n`;\r\n        functionString += `    vec3 p2 = permute(p + Pi.y);\\n`;\r\n        functionString += `    vec3 p3 = permute(p + Pi.y + 1.0);\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 p11 = permute(p1 + Pi.z - 1.0);\\n`;\r\n        functionString += `    vec3 p12 = permute(p1 + Pi.z);\\n`;\r\n        functionString += `    vec3 p13 = permute(p1 + Pi.z + 1.0);\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 p21 = permute(p2 + Pi.z - 1.0);\\n`;\r\n        functionString += `    vec3 p22 = permute(p2 + Pi.z);\\n`;\r\n        functionString += `    vec3 p23 = permute(p2 + Pi.z + 1.0);\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 p31 = permute(p3 + Pi.z - 1.0);\\n`;\r\n        functionString += `    vec3 p32 = permute(p3 + Pi.z);\\n`;\r\n        functionString += `    vec3 p33 = permute(p3 + Pi.z + 1.0);\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox11 = fract(p11*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy11 = mod(floor(p11*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz11 = floor(p11*K2)*Kz - Kzo; // p11 < 289 guaranteed\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox12 = fract(p12*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy12 = mod(floor(p12*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz12 = floor(p12*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox13 = fract(p13*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy13 = mod(floor(p13*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz13 = floor(p13*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox21 = fract(p21*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy21 = mod(floor(p21*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz21 = floor(p21*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox22 = fract(p22*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy22 = mod(floor(p22*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz22 = floor(p22*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox23 = fract(p23*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy23 = mod(floor(p23*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz23 = floor(p23*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox31 = fract(p31*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy31 = mod(floor(p31*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz31 = floor(p31*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox32 = fract(p32*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy32 = mod(floor(p32*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz32 = floor(p32*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 ox33 = fract(p33*K) - Ko;\\n`;\r\n        functionString += `    vec3 oy33 = mod(floor(p33*K), 7.0)*K - Ko;\\n`;\r\n        functionString += `    vec3 oz33 = floor(p33*K2)*Kz - Kzo;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx11 = Pfx + jitter*ox11;\\n`;\r\n        functionString += `    vec3 dy11 = Pfy.x + jitter*oy11;\\n`;\r\n        functionString += `    vec3 dz11 = Pfz.x + jitter*oz11;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx12 = Pfx + jitter*ox12;\\n`;\r\n        functionString += `    vec3 dy12 = Pfy.x + jitter*oy12;\\n`;\r\n        functionString += `    vec3 dz12 = Pfz.y + jitter*oz12;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx13 = Pfx + jitter*ox13;\\n`;\r\n        functionString += `    vec3 dy13 = Pfy.x + jitter*oy13;\\n`;\r\n        functionString += `    vec3 dz13 = Pfz.z + jitter*oz13;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx21 = Pfx + jitter*ox21;\\n`;\r\n        functionString += `    vec3 dy21 = Pfy.y + jitter*oy21;\\n`;\r\n        functionString += `    vec3 dz21 = Pfz.x + jitter*oz21;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx22 = Pfx + jitter*ox22;\\n`;\r\n        functionString += `    vec3 dy22 = Pfy.y + jitter*oy22;\\n`;\r\n        functionString += `    vec3 dz22 = Pfz.y + jitter*oz22;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx23 = Pfx + jitter*ox23;\\n`;\r\n        functionString += `    vec3 dy23 = Pfy.y + jitter*oy23;\\n`;\r\n        functionString += `    vec3 dz23 = Pfz.z + jitter*oz23;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx31 = Pfx + jitter*ox31;\\n`;\r\n        functionString += `    vec3 dy31 = Pfy.z + jitter*oy31;\\n`;\r\n        functionString += `    vec3 dz31 = Pfz.x + jitter*oz31;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx32 = Pfx + jitter*ox32;\\n`;\r\n        functionString += `    vec3 dy32 = Pfy.z + jitter*oy32;\\n`;\r\n        functionString += `    vec3 dz32 = Pfz.y + jitter*oz32;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 dx33 = Pfx + jitter*ox33;\\n`;\r\n        functionString += `    vec3 dy33 = Pfy.z + jitter*oy33;\\n`;\r\n        functionString += `    vec3 dz33 = Pfz.z + jitter*oz33;\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 d11 = dist(dx11, dy11, dz11, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d12 = dist(dx12, dy12, dz12, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d13 = dist(dx13, dy13, dz13, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d21 = dist(dx21, dy21, dz21, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d22 = dist(dx22, dy22, dz22, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d23 = dist(dx23, dy23, dz23, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d31 = dist(dx31, dy31, dz31, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d32 = dist(dx32, dy32, dz32, manhattanDistance);\\n`;\r\n        functionString += `    vec3 d33 = dist(dx33, dy33, dz33, manhattanDistance);\\n`;\r\n        functionString += `\\n`;\r\n        functionString += `    vec3 d1a = min(d11, d12);\\n`;\r\n        functionString += `    d12 = max(d11, d12);\\n`;\r\n        functionString += `    d11 = min(d1a, d13); // Smallest now not in d12 or d13\\n`;\r\n        functionString += `    d13 = max(d1a, d13);\\n`;\r\n        functionString += `    d12 = min(d12, d13); // 2nd smallest now not in d13\\n`;\r\n        functionString += `    vec3 d2a = min(d21, d22);\\n`;\r\n        functionString += `    d22 = max(d21, d22);\\n`;\r\n        functionString += `    d21 = min(d2a, d23); // Smallest now not in d22 or d23\\n`;\r\n        functionString += `    d23 = max(d2a, d23);\\n`;\r\n        functionString += `    d22 = min(d22, d23); // 2nd smallest now not in d23\\n`;\r\n        functionString += `    vec3 d3a = min(d31, d32);\\n`;\r\n        functionString += `    d32 = max(d31, d32);\\n`;\r\n        functionString += `    d31 = min(d3a, d33); // Smallest now not in d32 or d33\\n`;\r\n        functionString += `    d33 = max(d3a, d33);\\n`;\r\n        functionString += `    d32 = min(d32, d33); // 2nd smallest now not in d33\\n`;\r\n        functionString += `    vec3 da = min(d11, d21);\\n`;\r\n        functionString += `    d21 = max(d11, d21);\\n`;\r\n        functionString += `    d11 = min(da, d31); // Smallest now in d11\\n`;\r\n        functionString += `    d31 = max(da, d31); // 2nd smallest now not in d31\\n`;\r\n        functionString += `    if (d11.x >= d11.y) { vec2 temp = d11.yx; d11.x = temp.x; d11.y = temp.y; }\\n`;\r\n        functionString += `    if (d11.x >= d11.z) { vec2 temp = d11.zx; d11.x = temp.x; d11.z = temp.y; }\\n`;\r\n        functionString += `    d12 = min(d12, d21); // 2nd smallest now not in d21\\n`;\r\n        functionString += `    d12 = min(d12, d22); // nor in d22\\n`;\r\n        functionString += `    d12 = min(d12, d31); // nor in d31\\n`;\r\n        functionString += `    d12 = min(d12, d32); // nor in d32\\n`;\r\n        functionString += `    vec2 temp2 = min(d11.yz, d12.xy); // nor in d12.yz\\n`;\r\n        functionString += `    d11.y = temp2.x;\\n`;\r\n        functionString += `    d11.z = temp2.y;\\n`;\r\n        functionString += `    d11.y = min(d11.y, d12.z); // Only two more to go\\n`;\r\n        functionString += `    d11.y = min(d11.y, d11.z); // Done! (Phew!)\\n`;\r\n        functionString += `    return sqrt(d11.xy); // F1, F2\\n`;\r\n        functionString += `}\\n\\n`;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = state._babylonSLtoWGSL(functionString);\r\n        } else {\r\n            functionString = state._babylonSLtoGLSL(functionString);\r\n        }\r\n\r\n        state._emitFunction(\"worley3D\", functionString, \"// Worley3D\");\r\n\r\n        const tempVariable = state._getFreeVariableName(\"worleyTemp\");\r\n\r\n        state.compilationString += `${state._declareLocalVar(tempVariable, NodeMaterialBlockConnectionPointTypes.Vector2)} = worley(${this.seed.associatedVariableName}, ${this.jitter.associatedVariableName}, ${this.manhattanDistance});\\n`;\r\n\r\n        if (this.output.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.output) + ` = ${tempVariable};\\n`;\r\n        }\r\n\r\n        if (this.x.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.x) + ` = ${tempVariable}.x;\\n`;\r\n        }\r\n\r\n        if (this.y.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.y) + ` = ${tempVariable}.y;\\n`;\r\n        }\r\n        return this;\r\n    }\r\n    /**\r\n     * Exposes the properties to the UI?\r\n     * @returns - boolean indicating if the block has properties or not\r\n     */\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.manhattanDistance = ${this.manhattanDistance};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n    /**\r\n     * Exposes the properties to the Serialize?\r\n     * @returns - a serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.manhattanDistance = this.manhattanDistance;\r\n\r\n        return serializationObject;\r\n    }\r\n    /**\r\n     * Exposes the properties to the deserialize?\r\n     * @param serializationObject\r\n     * @param scene\r\n     * @param rootUrl\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.manhattanDistance = serializationObject.manhattanDistance;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for worleyNoise3DBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWorleyNoise3DBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.WorleyNoise3DBlock\", WorleyNoise3DBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * block used to Generate a Simplex Perlin 3d Noise Pattern\r\n */\r\n//\r\n//  Wombat\r\n//  An efficient texture-free GLSL procedural noise library\r\n//  Source: https://github.com/BrianSharpe/Wombat\r\n//  Derived from: https://github.com/BrianSharpe/GPU-Noise-Lib\r\n//\r\n//  I'm not one for copyrights.  Use the code however you wish.\r\n//  All I ask is that credit be given back to the blog or myself when appropriate.\r\n//  And also to let me know if you come up with any changes, improvements, thoughts or interesting uses for this stuff. :)\r\n//  Thanks!\r\n//\r\n//  Brian Sharpe\r\n//  brisharpe CIRCLE_A yahoo DOT com\r\n//  http://briansharpe.wordpress.com\r\n//  https://github.com/BrianSharpe\r\n//\r\n//\r\n//  This is a modified version of Stefan Gustavson's and Ian McEwan's work at http://github.com/ashima/webgl-noise\r\n//  Modifications are...\r\n//  - faster random number generation\r\n//  - analytical final normalization\r\n//  - space scaled can have an approx feature size of 1.0\r\n//  - filter kernel changed to fix discontinuities at tetrahedron boundaries\r\n//\r\n//  Converted to BJS by Pryme8\r\n//\r\n//  Simplex Perlin Noise 3D\r\n//  Return value range of -1.0->1.0\r\n//\r\nexport class SimplexPerlin3DBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new SimplexPerlin3DBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n        this.registerInput(\"seed\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SimplexPerlin3DBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the seed operand input component\r\n     */\r\n    public get seed(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.seed.isConnected) {\r\n            return;\r\n        }\r\n\r\n        if (!this._outputs[0].hasEndpoints) {\r\n            return;\r\n        }\r\n\r\n        let functionString = `const float SKEWFACTOR = 1.0/3.0;\\n`;\r\n        functionString += `const float UNSKEWFACTOR = 1.0/6.0;\\n`;\r\n        functionString += `const float SIMPLEX_CORNER_POS = 0.5;\\n`;\r\n        functionString += `const float SIMPLEX_TETRAHADRON_HEIGHT = 0.70710678118654752440084436210485;\\n`;\r\n        functionString += `float SimplexPerlin3D( vec3 source ){\\n`;\r\n        functionString += `    vec3 P = source;\\n`;\r\n        functionString += `    P.x = [P.x == 0. && P.y == 0. && P.z == 0. ? 0.00001 : P.x];\\n`;\r\n        functionString += `    P *= SIMPLEX_TETRAHADRON_HEIGHT;\\n`;\r\n        functionString += `    vec3 Pi = floor( P + dot( P, vec3( SKEWFACTOR) ) );`;\r\n        functionString += `    vec3 x0 = P - Pi + dot(Pi, vec3( UNSKEWFACTOR ) );\\n`;\r\n        functionString += `    vec3 g = step(x0.yzx, x0.xyz);\\n`;\r\n        functionString += `    vec3 l = 1.0 - g;\\n`;\r\n        functionString += `    vec3 Pi_1 = min( g.xyz, l.zxy );\\n`;\r\n        functionString += `    vec3 Pi_2 = max( g.xyz, l.zxy );\\n`;\r\n        functionString += `    vec3 x1 = x0 - Pi_1 + UNSKEWFACTOR;\\n`;\r\n        functionString += `    vec3 x2 = x0 - Pi_2 + SKEWFACTOR;\\n`;\r\n        functionString += `    vec3 x3 = x0 - SIMPLEX_CORNER_POS;\\n`;\r\n        functionString += `    vec4 v1234_x = vec4( x0.x, x1.x, x2.x, x3.x );\\n`;\r\n        functionString += `    vec4 v1234_y = vec4( x0.y, x1.y, x2.y, x3.y );\\n`;\r\n        functionString += `    vec4 v1234_z = vec4( x0.z, x1.z, x2.z, x3.z );\\n`;\r\n        functionString += `    Pi = Pi.xyz - floor(Pi.xyz * ( 1.0 / 69.0 )) * 69.0;\\n`;\r\n        functionString += `    vec3 Pi_inc1 = step( Pi, vec3( 69.0 - 1.5 ) ) * ( Pi + 1.0 );\\n`;\r\n        functionString += `    vec4 Pt = vec4( Pi.xy, Pi_inc1.xy ) + vec2( 50.0, 161.0 ).xyxy;\\n`;\r\n        functionString += `    Pt *= Pt;\\n`;\r\n        functionString += `    vec4 V1xy_V2xy = mix( Pt.xyxy, Pt.zwzw, vec4( Pi_1.xy, Pi_2.xy ) );\\n`;\r\n        functionString += `    Pt = vec4( Pt.x, V1xy_V2xy.xz, Pt.z ) * vec4( Pt.y, V1xy_V2xy.yw, Pt.w );\\n`;\r\n        functionString += `    const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );\\n`;\r\n        functionString += `    const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );\\n`;\r\n        functionString += `    vec3 lowz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi.zzz * ZINC.xyz ) );\\n`;\r\n        functionString += `    vec3 highz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi_inc1.zzz * ZINC.xyz ) );\\n`;\r\n        functionString += `    Pi_1 = [( Pi_1.z < 0.5 ) ? lowz_mods : highz_mods];\\n`;\r\n        functionString += `    Pi_2 = [( Pi_2.z < 0.5 ) ? lowz_mods : highz_mods];\\n`;\r\n        functionString += `    vec4 hash_0 = fract( Pt * vec4( lowz_mods.x, Pi_1.x, Pi_2.x, highz_mods.x ) ) - 0.49999;\\n`;\r\n        functionString += `    vec4 hash_1 = fract( Pt * vec4( lowz_mods.y, Pi_1.y, Pi_2.y, highz_mods.y ) ) - 0.49999;\\n`;\r\n        functionString += `    vec4 hash_2 = fract( Pt * vec4( lowz_mods.z, Pi_1.z, Pi_2.z, highz_mods.z ) ) - 0.49999;\\n`;\r\n        functionString += `    vec4 grad_results = inversesqrt( hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2 ) * ( hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z );\\n`;\r\n        functionString += `    const float FINAL_NORMALIZATION = 37.837227241611314102871574478976;\\n`;\r\n        functionString += `    vec4 kernel_weights = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;\\n`;\r\n        functionString += `    kernel_weights = max(0.5 - kernel_weights, vec4(0.));\\n`;\r\n        functionString += `    kernel_weights = kernel_weights*kernel_weights*kernel_weights;\\n`;\r\n        functionString += `    return dot( kernel_weights, grad_results ) * FINAL_NORMALIZATION;\\n`;\r\n        functionString += `}\\n`;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = state._babylonSLtoWGSL(functionString);\r\n        } else {\r\n            functionString = state._babylonSLtoGLSL(functionString);\r\n        }\r\n\r\n        state._emitFunction(\"SimplexPerlin3D\", functionString, \"// SimplexPerlin3D\");\r\n        state.compilationString += state._declareOutput(this._outputs[0]) + ` = SimplexPerlin3D(${this.seed.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for simplexPerlin3DBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSimplexPerlin3DBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SimplexPerlin3DBlock\", SimplexPerlin3DBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to blend normals\r\n */\r\nexport class NormalBlendBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new NormalBlendBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"normalMap0\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"normalMap1\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n\r\n        this._inputs[1].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NormalBlendBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the first input component\r\n     */\r\n    public get normalMap0(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the second input component\r\n     */\r\n    public get normalMap1(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input0 = this._inputs[0];\r\n        const input1 = this._inputs[1];\r\n        const stepR = state._getFreeVariableName(\"stepR\");\r\n        const stepG = state._getFreeVariableName(\"stepG\");\r\n\r\n        state.compilationString += `${state._declareLocalVar(stepR, NodeMaterialBlockConnectionPointTypes.Float)} = step(0.5, ${input0.associatedVariableName}.r);\\n`;\r\n        state.compilationString += `${state._declareLocalVar(stepG, NodeMaterialBlockConnectionPointTypes.Float)} = step(0.5, ${input0.associatedVariableName}.g);\\n`;\r\n        state.compilationString += state._declareOutput(output) + `;\\n`;\r\n        state.compilationString += `${output.associatedVariableName}.r = (1.0 - ${stepR}) * ${input0.associatedVariableName}.r * ${input1.associatedVariableName}.r * 2.0 + ${stepR} * (1.0 - (1.0 - ${input0.associatedVariableName}.r) * (1.0 - ${input1.associatedVariableName}.r) * 2.0);\\n`;\r\n        state.compilationString += `${output.associatedVariableName}.g = (1.0 - ${stepG}) * ${input0.associatedVariableName}.g * ${input1.associatedVariableName}.g * 2.0 + ${stepG} * (1.0 - (1.0 - ${input0.associatedVariableName}.g) * (1.0 - ${input1.associatedVariableName}.g) * 2.0);\\n`;\r\n        state.compilationString += `${output.associatedVariableName}.b = ${input0.associatedVariableName}.b * ${input1.associatedVariableName}.b;\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for normalBlendBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNormalBlendBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NormalBlendBlock\", NormalBlendBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to rotate a 2d vector by a given angle\r\n */\r\nexport class Rotate2dBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new Rotate2dBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"angle\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"Rotate2dBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input vector\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the input angle\r\n     */\r\n    public get angle(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** Auto configure the block based on the material */\r\n    public override autoConfigure() {\r\n        if (!this.angle.isConnected) {\r\n            const angleInput = new InputBlock(\"angle\");\r\n            angleInput.value = 0;\r\n            angleInput.output.connectTo(this.angle);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const angle = this.angle;\r\n        const input = this.input;\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = vec2(cos(${angle.associatedVariableName}) * ${input.associatedVariableName}.x - sin(${angle.associatedVariableName}) * ${input.associatedVariableName}.y, sin(${angle.associatedVariableName}) * ${input.associatedVariableName}.x + cos(${angle.associatedVariableName}) * ${input.associatedVariableName}.y);\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for rotate2dBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRotate2dBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.Rotate2dBlock\", Rotate2dBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the reflected vector from a direction and a normal\r\n */\r\nexport class ReflectBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ReflectBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"incident\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"normal\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n        this._inputs[1].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ReflectBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the incident component\r\n     */\r\n    public get incident(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal component\r\n     */\r\n    public get normal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = reflect(${this.incident.associatedVariableName}.xyz, ${this.normal.associatedVariableName}.xyz);\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for reflectBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReflectBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ReflectBlock\", ReflectBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the refracted vector from a direction and a normal\r\n */\r\nexport class RefractBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new RefractBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"incident\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"normal\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"ior\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n        this._inputs[1].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Vector3 |\r\n                NodeMaterialBlockConnectionPointTypes.Vector4 |\r\n                NodeMaterialBlockConnectionPointTypes.Color3 |\r\n                NodeMaterialBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RefractBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the incident component\r\n     */\r\n    public get incident(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal component\r\n     */\r\n    public get normal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the index of refraction component\r\n     */\r\n    public get ior(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = refract(${this.incident.associatedVariableName}.xyz, ${this.normal.associatedVariableName}.xyz, ${this.ior.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for refractBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRefractBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RefractBlock\", RefractBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to desaturate a color\r\n */\r\nexport class DesaturateBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new DesaturateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n        this.registerInput(\"level\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DesaturateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color operand input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the level operand input component\r\n     */\r\n    public get level(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const color = this.color;\r\n        const colorName = color.associatedVariableName;\r\n        const tempMin = state._getFreeVariableName(\"colorMin\");\r\n        const tempMax = state._getFreeVariableName(\"colorMax\");\r\n        const tempMerge = state._getFreeVariableName(\"colorMerge\");\r\n\r\n        state.compilationString += `${state._declareLocalVar(tempMin, NodeMaterialBlockConnectionPointTypes.Float)} = min(min(${colorName}.x, ${colorName}.y), ${colorName}.z);\\n`;\r\n        state.compilationString += `${state._declareLocalVar(tempMax, NodeMaterialBlockConnectionPointTypes.Float)} = max(max(${colorName}.x, ${colorName}.y), ${colorName}.z);\\n`;\r\n        state.compilationString += `${state._declareLocalVar(tempMerge, NodeMaterialBlockConnectionPointTypes.Float)} = 0.5 * (${tempMin} + ${tempMax});\\n`;\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = mix(${colorName}, ${state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3)}(${tempMerge}, ${tempMerge}, ${tempMerge}), ${this.level.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for desaturateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDesaturateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DesaturateBlock\", DesaturateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type ReflectionBlock } from \"./reflectionBlock.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the sheen module of the PBR material\r\n */\r\nexport class SheenBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new SheenBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"intensity\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"roughness\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\r\n            \"sheen\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"sheen\", this, NodeMaterialConnectionPointDirection.Output, SheenBlock, \"SheenBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.\r\n     * It allows the strength of the sheen effect to not depend on the base color of the material,\r\n     * making it easier to setup and tweak the effect\r\n     */\r\n    @editableInPropertyPage(\"Albedo scaling\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true, notifiers: { update: true } })\r\n    public albedoScaling: boolean = false;\r\n\r\n    /**\r\n     * Defines if the sheen is linked to the sheen color.\r\n     */\r\n    @editableInPropertyPage(\"Link sheen with albedo\", PropertyTypeForEdition.Boolean, \"PROPERTIES\", { embedded: true, notifiers: { update: true } })\r\n    public linkSheenWithAlbedo: boolean = false;\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"sheenOut\");\r\n        state._excludeVariableName(\"sheenMapData\");\r\n        state._excludeVariableName(\"vSheenColor\");\r\n        state._excludeVariableName(\"vSheenRoughness\");\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SheenBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity input component\r\n     */\r\n    public get intensity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the roughness input component\r\n     */\r\n    public get roughness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the sheen object output component\r\n     */\r\n    public get sheen(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        defines.setValue(\"SHEEN\", true);\r\n        defines.setValue(\"SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE\", true, true);\r\n        defines.setValue(\"SHEEN_LINKWITHALBEDO\", this.linkSheenWithAlbedo, true);\r\n        defines.setValue(\"SHEEN_ROUGHNESS\", this.roughness.isConnected, true);\r\n        defines.setValue(\"SHEEN_ALBEDOSCALING\", this.albedoScaling, true);\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param reflectionBlock instance of a ReflectionBlock null if the code must be generated without an active reflection module\r\n     * @param state define the build state\r\n     * @returns the shader code\r\n     */\r\n    public getCode(reflectionBlock: Nullable<ReflectionBlock>, state: NodeMaterialBuildState): string {\r\n        const color = this.color.isConnected ? this.color.associatedVariableName : `vec3${state.fSuffix}(1.)`;\r\n        const intensity = this.intensity.isConnected ? this.intensity.associatedVariableName : \"1.\";\r\n        const roughness = this.roughness.isConnected ? this.roughness.associatedVariableName : \"0.\";\r\n        const texture = `vec4${state.fSuffix}(0.)`;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        const code = `#ifdef SHEEN\r\n            ${isWebGPU ? \"var sheenOut: sheenOutParams\" : \"sheenOutParams sheenOut\"};\r\n\r\n            ${state._declareLocalVar(\"vSheenColor\", NodeMaterialBlockConnectionPointTypes.Vector4)} = vec4${state.fSuffix}(${color}, ${intensity});\r\n\r\n            sheenOut = sheenBlock(\r\n                vSheenColor\r\n            #ifdef SHEEN_ROUGHNESS\r\n                , ${roughness}\r\n            #endif\r\n                , roughness\r\n            #ifdef SHEEN_TEXTURE\r\n                , ${texture}\r\n                ${isWebGPU ? `, ${texture}Sampler` : \"\"}\r\n                , 1.0\r\n            #endif\r\n                , reflectanceF0\r\n            #ifdef SHEEN_LINKWITHALBEDO\r\n                , baseColor\r\n                , surfaceAlbedo\r\n            #endif\r\n            #ifdef ENVIRONMENTBRDF\r\n                , NdotV\r\n                , environmentBrdf\r\n            #endif\r\n            #if defined(REFLECTION) && defined(ENVIRONMENTBRDF)\r\n                , AARoughnessFactors\r\n                , ${isWebGPU ? \"uniforms.\" : \"\"}${reflectionBlock?._vReflectionMicrosurfaceInfosName}\r\n                , ${reflectionBlock?._vReflectionInfosName}\r\n                , ${reflectionBlock?.reflectionColor}\r\n                , ${isWebGPU ? \"uniforms.\" : \"\"}vLightingIntensity\r\n                #ifdef ${reflectionBlock?._define3DName}\r\n                    , ${reflectionBlock?._cubeSamplerName}                                      \r\n                    ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                #else\r\n                    , ${reflectionBlock?._2DSamplerName}\r\n                    ${isWebGPU ? `, ${reflectionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                #endif\r\n                , reflectionOut.reflectionCoords\r\n                , NdotVUnclamped\r\n                #ifndef LODBASEDMICROSFURACE\r\n                    #ifdef ${reflectionBlock?._define3DName}\r\n                        , ${reflectionBlock?._cubeSamplerName}                        \r\n                        ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                        , ${reflectionBlock?._cubeSamplerName}\r\n                        ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                    #else\r\n                        , ${reflectionBlock?._2DSamplerName}\r\n                        ${isWebGPU ? `, ${reflectionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                        , ${reflectionBlock?._2DSamplerName}\r\n                        ${isWebGPU ? `, ${reflectionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                    #endif\r\n                #endif\r\n                #if !defined(${reflectionBlock?._defineSkyboxName}) && defined(RADIANCEOCCLUSION)\r\n                    , seo\r\n                #endif\r\n                #if !defined(${reflectionBlock?._defineSkyboxName}) && defined(HORIZONOCCLUSION) && defined(BUMP) && defined(${reflectionBlock?._define3DName})\r\n                    , eho\r\n                #endif\r\n            #endif\r\n            );\r\n\r\n            #ifdef SHEEN_LINKWITHALBEDO\r\n                surfaceAlbedo = sheenOut.surfaceAlbedo;\r\n            #endif\r\n        #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.sharedData.blocksWithDefines.push(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.albedoScaling = ${this.albedoScaling};\\n`;\r\n        codeString += `${this._codeVariableName}.linkSheenWithAlbedo = ${this.linkSheenWithAlbedo};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.albedoScaling = this.albedoScaling;\r\n        serializationObject.linkSheenWithAlbedo = this.linkSheenWithAlbedo;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.albedoScaling = serializationObject.albedoScaling;\r\n        this.linkSheenWithAlbedo = serializationObject.linkSheenWithAlbedo;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sheenBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSheenBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SheenBlock\", SheenBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { TBNBlock } from \"../Fragment/TBNBlock.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the anisotropy module of the PBR material\r\n */\r\nexport class AnisotropyBlock extends NodeMaterialBlock {\r\n    private _tangentCorrectionFactorName = \"\";\r\n\r\n    /**\r\n     * The two properties below are set by the main PBR block prior to calling methods of this class.\r\n     * This is to avoid having to add them as inputs here whereas they are already inputs of the main block, so already known.\r\n     * It's less burden on the user side in the editor part.\r\n     */\r\n\r\n    /** @internal */\r\n    public worldPositionConnectionPoint: NodeMaterialConnectionPoint;\r\n    /** @internal */\r\n    public worldNormalConnectionPoint: NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Create a new AnisotropyBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"intensity\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"direction\", NodeMaterialBlockConnectionPointTypes.Vector2, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.Vector2, true); // need this property and the next one in case there's no PerturbNormal block connected to the main PBR block\r\n        this.registerInput(\"worldTangent\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\r\n            \"TBN\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"TBN\", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, \"TBNBlock\")\r\n        );\r\n        this.registerInput(\"roughness\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\r\n            \"anisotropy\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"anisotropy\", this, NodeMaterialConnectionPointDirection.Output, AnisotropyBlock, \"AnisotropyBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"anisotropicOut\");\r\n        state._excludeVariableName(\"TBN\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/bumpFragmentMainFunctions\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/bumpFragmentMainFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"AnisotropyBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity input component\r\n     */\r\n    public get intensity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction input component\r\n     */\r\n    public get direction(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the worldTangent input component\r\n     */\r\n    public get worldTangent(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the TBN input component\r\n     */\r\n    public get TBN(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the roughness input component\r\n     */\r\n    public get roughness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the anisotropy object output component\r\n     */\r\n    public get anisotropy(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _generateTBNSpace(state: NodeMaterialBuildState) {\r\n        let code = \"\";\r\n\r\n        const comments = `//${this.name}`;\r\n        const uv = this.uv;\r\n        const worldPosition = this.worldPositionConnectionPoint;\r\n        const worldNormal = this.worldNormalConnectionPoint;\r\n        const worldTangent = this.worldTangent;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        if (!uv.isConnected) {\r\n            // we must set the uv input as optional because we may not end up in this method (in case a PerturbNormal block is linked to the PBR material)\r\n            // in which case uv is not required. But if we do come here, we do need the uv, so we have to raise an error but not with throw, else\r\n            // it will stop the building of the node material and will lead to errors in the editor!\r\n            state.sharedData.raiseBuildError(`You must connect the 'uv' input of the ${this.name} block!`);\r\n        }\r\n\r\n        state._emitExtension(\"derivatives\", \"#extension GL_OES_standard_derivatives : enable\");\r\n\r\n        const tangentReplaceString = { search: /defined\\(TANGENT\\)/g, replace: worldTangent.isConnected ? \"defined(TANGENT)\" : \"defined(IGNORE)\" };\r\n\r\n        const tbn = this.TBN;\r\n        if (tbn.isConnected) {\r\n            state.compilationString += `\r\n            #ifdef TBNBLOCK\r\n            ${isWebGPU ? \"var TBN\" : \"mat3 TBN\"} = ${tbn.associatedVariableName};\r\n            #endif\r\n            `;\r\n        } else if (worldTangent.isConnected) {\r\n            code += `${state._declareLocalVar(\"tbnNormal\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${worldNormal.associatedVariableName}.xyz);\\n`;\r\n            code += `${state._declareLocalVar(\"tbnTangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${worldTangent.associatedVariableName}.xyz);\\n`;\r\n            code += `${state._declareLocalVar(\"tbnBitangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = cross(tbnNormal, tbnTangent) * ${this._tangentCorrectionFactorName};\\n`;\r\n            code += `${isWebGPU ? \"var vTBN\" : \"mat3 vTBN\"} = ${isWebGPU ? \"mat3x3f\" : \"mat3\"}(tbnTangent, tbnBitangent, tbnNormal);\\n`;\r\n        }\r\n\r\n        code += `\r\n            #if defined(${worldTangent.isConnected ? \"TANGENT\" : \"IGNORE\"}) && defined(NORMAL)\r\n                ${isWebGPU ? \"var TBN\" : \"mat3 TBN\"} = vTBN;\r\n            #else\r\n                ${isWebGPU ? \"var TBN\" : \"mat3 TBN\"} = cotangent_frame(${worldNormal.associatedVariableName + \".xyz\"}, ${\"v_\" + worldPosition.associatedVariableName + \".xyz\"}, ${\r\n                    uv.isConnected ? uv.associatedVariableName : \"vec2(0.)\"\r\n                }, vec2${state.fSuffix}(1., 1.));\r\n            #endif\\n`;\r\n\r\n        state._emitFunctionFromInclude(\"bumpFragmentMainFunctions\", comments, {\r\n            replaceStrings: [tangentReplaceString],\r\n        });\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param state current state of the node material building\r\n     * @param generateTBNSpace if true, the code needed to create the TBN coordinate space is generated\r\n     * @returns the shader code\r\n     */\r\n    public getCode(state: NodeMaterialBuildState, generateTBNSpace = false): string {\r\n        let code = \"\";\r\n\r\n        if (generateTBNSpace) {\r\n            code += this._generateTBNSpace(state);\r\n        }\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        const intensity = this.intensity.isConnected ? this.intensity.associatedVariableName : \"1.0\";\r\n        const direction = this.direction.isConnected ? this.direction.associatedVariableName : \"vec2(1., 0.)\";\r\n        const roughness = this.roughness.isConnected ? this.roughness.associatedVariableName : \"0.\";\r\n\r\n        code += `${isWebGPU ? \"var anisotropicOut: anisotropicOutParams\" : \"anisotropicOutParams anisotropicOut\"};\r\n            anisotropicOut = anisotropicBlock(\r\n                vec3(${direction}, ${intensity}),\r\n                ${roughness},\r\n            #ifdef ANISOTROPIC_TEXTURE\r\n                vec3(0.),\r\n            #endif\r\n                TBN,\r\n                normalW,\r\n                viewDirectionW\r\n            );\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines to update\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        defines.setValue(\"ANISOTROPIC\", true);\r\n        defines.setValue(\"ANISOTROPIC_TEXTURE\", false, true);\r\n        defines.setValue(\"ANISOTROPIC_LEGACY\", !this.roughness.isConnected);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind data to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind data for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        super.bind(effect, nodeMaterial, mesh);\r\n\r\n        if (mesh) {\r\n            effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.sharedData.blocksWithDefines.push(this);\r\n            state.sharedData.bindableBlocks.push(this);\r\n\r\n            this._tangentCorrectionFactorName = state._getFreeDefineName(\"tangentCorrectionFactor\");\r\n            state._emitUniformFromString(this._tangentCorrectionFactorName, NodeMaterialBlockConnectionPointTypes.Float);\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for anisotropyBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAnisotropyBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AnisotropyBlock\", AnisotropyBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { ReflectionTextureBaseBlock } from \"../Dual/reflectionTextureBaseBlock.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type SubMesh } from \"../../../../Meshes/subMesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the reflection module of the PBR material\r\n */\r\nexport class ReflectionBlock extends ReflectionTextureBaseBlock {\r\n    /** @internal */\r\n    public _defineLODReflectionAlpha: string;\r\n    /** @internal */\r\n    public _defineLinearSpecularReflection: string;\r\n    private _vEnvironmentIrradianceName: string;\r\n    /** @internal */\r\n    public _vReflectionMicrosurfaceInfosName: string;\r\n    /** @internal */\r\n    public _vReflectionInfosName: string;\r\n    /** @internal */\r\n    public _vReflectionFilteringInfoName: string;\r\n    private _scene: Scene;\r\n    private _iblIntensityName: string;\r\n\r\n    /**\r\n     * The properties below are set by the main PBR block prior to calling methods of this class.\r\n     * This is to avoid having to add them as inputs here whereas they are already inputs of the main block, so already known.\r\n     * It's less burden on the user side in the editor part.\r\n     */\r\n\r\n    /** @internal */\r\n    public worldPositionConnectionPoint: NodeMaterialConnectionPoint;\r\n    /** @internal */\r\n    public worldNormalConnectionPoint: NodeMaterialConnectionPoint;\r\n    /** @internal */\r\n    public cameraPositionConnectionPoint: NodeMaterialConnectionPoint;\r\n    /** @internal */\r\n    public viewConnectionPoint: NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * Defines if the material uses spherical harmonics vs spherical polynomials for the\r\n     * diffuse part of the IBL.\r\n     */\r\n    @editableInPropertyPage(\"Spherical Harmonics\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { update: true } })\r\n    public useSphericalHarmonics: boolean = true;\r\n\r\n    /**\r\n     * Force the shader to compute irradiance in the fragment shader in order to take bump in account.\r\n     */\r\n    @editableInPropertyPage(\"Force irradiance in fragment\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { update: true } })\r\n    public forceIrradianceInFragment: boolean = false;\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initReflectionBlockShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initReflectionBlockShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/helperFunctions\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/reflectionFunction\"),\r\n                import(\"../../../../ShadersWGSL/ShadersInclude/harmonicsFunctions\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../../../Shaders/ShadersInclude/helperFunctions\"),\r\n                import(\"../../../../Shaders/ShadersInclude/reflectionFunction\"),\r\n                import(\"../../../../Shaders/ShadersInclude/harmonicsFunctions\"),\r\n            ]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    protected override _onGenerateOnlyFragmentCodeChanged(): boolean {\r\n        if (this.position.isConnected) {\r\n            this.generateOnlyFragmentCode = !this.generateOnlyFragmentCode;\r\n            Logger.Error(\"The position input must not be connected to be able to switch!\");\r\n            return false;\r\n        }\r\n\r\n        this._setTarget();\r\n\r\n        return true;\r\n    }\r\n\r\n    protected override _setTarget(): void {\r\n        super._setTarget();\r\n        this.getInputByName(\"position\")!.target = this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.Vertex;\r\n        if (this.generateOnlyFragmentCode) {\r\n            this.forceIrradianceInFragment = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a new ReflectionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"position\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"world\", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"color\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\r\n            \"reflection\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"reflection\", this, NodeMaterialConnectionPointDirection.Output, ReflectionBlock, \"ReflectionBlock\")\r\n        );\r\n\r\n        this.position.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ReflectionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get position(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this.worldPositionConnectionPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this.worldNormalConnectionPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the world input component\r\n     */\r\n    public get world(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera (or eye) position component\r\n     */\r\n    public get cameraPosition(): NodeMaterialConnectionPoint {\r\n        return this.cameraPositionConnectionPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the view input component\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this.viewConnectionPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the reflection object output component\r\n     */\r\n    public get reflection(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Returns true if the block has a texture (either its own texture or the environment texture from the scene, if set)\r\n     */\r\n    public get hasTexture(): boolean {\r\n        return !!this._getTexture();\r\n    }\r\n\r\n    /**\r\n     * Gets the reflection color (either the name of the variable if the color input is connected, else a default value)\r\n     */\r\n    public get reflectionColor(): string {\r\n        return this.color.isConnected ? this.color.associatedVariableName : \"vec3(1., 1., 1.)\";\r\n    }\r\n\r\n    protected override _getTexture(): Nullable<BaseTexture> {\r\n        if (this.texture) {\r\n            return this.texture;\r\n        }\r\n\r\n        return this._scene.environmentTexture;\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines to update\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        super.prepareDefines(defines);\r\n\r\n        const reflectionTexture = this._getTexture();\r\n        const reflection = reflectionTexture && reflectionTexture.getTextureMatrix;\r\n\r\n        defines.setValue(\"REFLECTION\", reflection, true);\r\n\r\n        if (!reflection) {\r\n            return;\r\n        }\r\n\r\n        defines.setValue(this._defineLODReflectionAlpha, reflectionTexture.lodLevelInAlpha, true);\r\n        defines.setValue(this._defineLinearSpecularReflection, reflectionTexture.linearSpecularLOD, true);\r\n        defines.setValue(this._defineOppositeZ, this._scene.useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ, true);\r\n\r\n        defines.setValue(\"SPHERICAL_HARMONICS\", this.useSphericalHarmonics, true);\r\n        defines.setValue(\"GAMMAREFLECTION\", reflectionTexture.gammaSpace, true);\r\n        defines.setValue(\"RGBDREFLECTION\", reflectionTexture.isRGBD, true);\r\n\r\n        if (reflectionTexture && reflectionTexture.coordinatesMode !== Texture.SKYBOX_MODE) {\r\n            if (reflectionTexture.isCube) {\r\n                defines.setValue(\"USESPHERICALFROMREFLECTIONMAP\", true);\r\n                defines.setValue(\"USEIRRADIANCEMAP\", false);\r\n                if (this.forceIrradianceInFragment || this._scene.getEngine().getCaps().maxVaryingVectors <= 8) {\r\n                    defines.setValue(\"USESPHERICALINVERTEX\", false);\r\n                } else {\r\n                    defines.setValue(\"USESPHERICALINVERTEX\", true);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind data to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind data for\r\n     * @param subMesh - the submesh to bind data for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh, subMesh?: SubMesh) {\r\n        super.bind(effect, nodeMaterial, mesh);\r\n\r\n        const reflectionTexture = this._getTexture();\r\n\r\n        if (!reflectionTexture || !subMesh) {\r\n            return;\r\n        }\r\n\r\n        if (reflectionTexture.isCube) {\r\n            effect.setTexture(this._cubeSamplerName, reflectionTexture);\r\n        } else {\r\n            effect.setTexture(this._2DSamplerName, reflectionTexture);\r\n        }\r\n\r\n        effect.setFloat(this._iblIntensityName, this._scene.iblIntensity * reflectionTexture.level);\r\n\r\n        const width = reflectionTexture.getSize().width;\r\n\r\n        effect.setFloat3(this._vReflectionMicrosurfaceInfosName, width, reflectionTexture.lodGenerationScale, reflectionTexture.lodGenerationOffset);\r\n        effect.setFloat2(this._vReflectionFilteringInfoName, width, Math.log2(width));\r\n\r\n        const defines = subMesh.materialDefines as NodeMaterialDefines;\r\n\r\n        const polynomials = reflectionTexture.sphericalPolynomial;\r\n        if (defines.USESPHERICALFROMREFLECTIONMAP && polynomials) {\r\n            if (defines.SPHERICAL_HARMONICS) {\r\n                const preScaledHarmonics = polynomials.preScaledHarmonics;\r\n                effect.setVector3(\"vSphericalL00\", preScaledHarmonics.l00);\r\n                effect.setVector3(\"vSphericalL1_1\", preScaledHarmonics.l1_1);\r\n                effect.setVector3(\"vSphericalL10\", preScaledHarmonics.l10);\r\n                effect.setVector3(\"vSphericalL11\", preScaledHarmonics.l11);\r\n                effect.setVector3(\"vSphericalL2_2\", preScaledHarmonics.l2_2);\r\n                effect.setVector3(\"vSphericalL2_1\", preScaledHarmonics.l2_1);\r\n                effect.setVector3(\"vSphericalL20\", preScaledHarmonics.l20);\r\n                effect.setVector3(\"vSphericalL21\", preScaledHarmonics.l21);\r\n                effect.setVector3(\"vSphericalL22\", preScaledHarmonics.l22);\r\n            } else {\r\n                effect.setFloat3(\"vSphericalX\", polynomials.x.x, polynomials.x.y, polynomials.x.z);\r\n                effect.setFloat3(\"vSphericalY\", polynomials.y.x, polynomials.y.y, polynomials.y.z);\r\n                effect.setFloat3(\"vSphericalZ\", polynomials.z.x, polynomials.z.y, polynomials.z.z);\r\n                effect.setFloat3(\"vSphericalXX_ZZ\", polynomials.xx.x - polynomials.zz.x, polynomials.xx.y - polynomials.zz.y, polynomials.xx.z - polynomials.zz.z);\r\n                effect.setFloat3(\"vSphericalYY_ZZ\", polynomials.yy.x - polynomials.zz.x, polynomials.yy.y - polynomials.zz.y, polynomials.yy.z - polynomials.zz.z);\r\n                effect.setFloat3(\"vSphericalZZ\", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z);\r\n                effect.setFloat3(\"vSphericalXY\", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z);\r\n                effect.setFloat3(\"vSphericalYZ\", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z);\r\n                effect.setFloat3(\"vSphericalZX\", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the code to inject in the vertex shader\r\n     * @param state current state of the node material building\r\n     * @returns the shader code\r\n     */\r\n    public override handleVertexSide(state: NodeMaterialBuildState): string {\r\n        let code = super.handleVertexSide(state);\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        state._emitFunctionFromInclude(\"harmonicsFunctions\", `//${this.name}`, {\r\n            replaceStrings: [\r\n                { search: /uniform vec3 vSphericalL00;[\\s\\S]*?uniform vec3 vSphericalL22;/g, replace: \"\" },\r\n                { search: /uniform vec3 vSphericalX;[\\s\\S]*?uniform vec3 vSphericalZX;/g, replace: \"\" },\r\n            ],\r\n        });\r\n\r\n        const reflectionVectorName = state._getFreeVariableName(\"reflectionVector\");\r\n\r\n        this._vEnvironmentIrradianceName = state._getFreeVariableName(\"vEnvironmentIrradiance\");\r\n\r\n        state._emitVaryingFromString(\r\n            this._vEnvironmentIrradianceName,\r\n            NodeMaterialBlockConnectionPointTypes.Vector3,\r\n            \"defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\"\r\n        );\r\n\r\n        state._emitUniformFromString(\"vSphericalL00\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL1_1\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL10\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL11\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL2_2\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL2_1\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL20\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL21\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n        state._emitUniformFromString(\"vSphericalL22\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\");\r\n\r\n        state._emitUniformFromString(\"vSphericalX\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalY\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalZ\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalXX_ZZ\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalYY_ZZ\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalZZ\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalXY\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalYZ\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n        state._emitUniformFromString(\"vSphericalZX\", NodeMaterialBlockConnectionPointTypes.Vector3, \"SPHERICAL_HARMONICS\", true);\r\n\r\n        code += `#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\r\n                ${state._declareLocalVar(reflectionVectorName, NodeMaterialBlockConnectionPointTypes.Vector3)} = (${(isWebGPU ? \"uniforms.\" : \"\") + this._reflectionMatrixName} * vec4${state.fSuffix}(normalize(${this.worldNormal.associatedVariableName}).xyz, 0)).xyz;\r\n                #ifdef ${this._defineOppositeZ}\r\n                    ${reflectionVectorName}.z *= -1.0;\r\n                #endif\r\n                ${isWebGPU ? \"vertexOutputs.\" : \"\"}${this._vEnvironmentIrradianceName} = computeEnvironmentIrradiance(${reflectionVectorName});\r\n            #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param state current state of the node material building\r\n     * @param normalVarName name of the existing variable corresponding to the normal\r\n     * @returns the shader code\r\n     */\r\n    public getCode(state: NodeMaterialBuildState, normalVarName: string): string {\r\n        let code = \"\";\r\n\r\n        this.handleFragmentSideInits(state);\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        state._emitFunctionFromInclude(\"harmonicsFunctions\", `//${this.name}`, {\r\n            replaceStrings: [\r\n                { search: /uniform vec3 vSphericalL00;[\\s\\S]*?uniform vec3 vSphericalL22;/g, replace: \"\" },\r\n                { search: /uniform vec3 vSphericalX;[\\s\\S]*?uniform vec3 vSphericalZX;/g, replace: \"\" },\r\n            ],\r\n        });\r\n\r\n        if (!isWebGPU) {\r\n            state._emitFunction(\r\n                \"sampleReflection\",\r\n                `\r\n                #ifdef ${this._define3DName}\r\n                    #define sampleReflection(s, c) textureCube(s, c)\r\n                #else\r\n                    #define sampleReflection(s, c) texture2D(s, c)\r\n                #endif\\n`,\r\n                `//${this.name}`\r\n            );\r\n\r\n            state._emitFunction(\r\n                \"sampleReflectionLod\",\r\n                `\r\n                #ifdef ${this._define3DName}\r\n                    #define sampleReflectionLod(s, c, l) textureCubeLodEXT(s, c, l)\r\n                #else\r\n                    #define sampleReflectionLod(s, c, l) texture2DLodEXT(s, c, l)\r\n                #endif\\n`,\r\n                `//${this.name}`\r\n            );\r\n        }\r\n\r\n        const computeReflectionCoordsFunc = isWebGPU\r\n            ? `\r\n            fn computeReflectionCoordsPBR(worldPos: vec4f, worldNormal: vec3f) -> vec3f {\r\n                ${this.handleFragmentSideCodeReflectionCoords(state, \"worldNormal\", \"worldPos\", true, true)}\r\n                return ${this._reflectionVectorName};\r\n            }\\n`\r\n            : `\r\n            vec3 computeReflectionCoordsPBR(vec4 worldPos, vec3 worldNormal) {\r\n                ${this.handleFragmentSideCodeReflectionCoords(state, \"worldNormal\", \"worldPos\", true, true)}\r\n                return ${this._reflectionVectorName};\r\n            }\\n`;\r\n\r\n        state._emitFunction(\"computeReflectionCoordsPBR\", computeReflectionCoordsFunc, `//${this.name}`);\r\n\r\n        this._vReflectionMicrosurfaceInfosName = state._getFreeVariableName(\"vReflectionMicrosurfaceInfos\");\r\n\r\n        state._emitUniformFromString(this._vReflectionMicrosurfaceInfosName, NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        this._vReflectionInfosName = state._getFreeVariableName(\"vReflectionInfos\");\r\n\r\n        this._vReflectionFilteringInfoName = state._getFreeVariableName(\"vReflectionFilteringInfo\");\r\n\r\n        state._emitUniformFromString(this._vReflectionFilteringInfoName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        this._iblIntensityName = state._getFreeVariableName(\"iblIntensity\");\r\n\r\n        state._emitUniformFromString(this._iblIntensityName, NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        code += `#ifdef REFLECTION\r\n            ${state._declareLocalVar(this._vReflectionInfosName, NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2${state.fSuffix}(${(isWebGPU ? \"uniforms.\" : \"\") + this._iblIntensityName}, 0.);\r\n\r\n            ${isWebGPU ? \"var reflectionOut: reflectionOutParams\" : \"reflectionOutParams reflectionOut\"};\r\n\r\n            reflectionOut = reflectionBlock(\r\n                ${this.generateOnlyFragmentCode ? this._worldPositionNameInFragmentOnlyMode : (isWebGPU ? \"input.\" : \"\") + \"v_\" + this.worldPosition.associatedVariableName}.xyz\r\n                , ${normalVarName}\r\n                , alphaG\r\n                , ${(isWebGPU ? \"uniforms.\" : \"\") + this._vReflectionMicrosurfaceInfosName}\r\n                , ${this._vReflectionInfosName}\r\n                , ${this.reflectionColor}\r\n            #ifdef ANISOTROPIC\r\n                ,anisotropicOut\r\n            #endif\r\n            #if defined(${this._defineLODReflectionAlpha}) && !defined(${this._defineSkyboxName})\r\n                ,NdotVUnclamped\r\n            #endif\r\n            #ifdef ${this._defineLinearSpecularReflection}\r\n                , roughness\r\n            #endif\r\n            #ifdef ${this._define3DName}\r\n                , ${this._cubeSamplerName}\r\n                ${isWebGPU ? `, ${this._cubeSamplerName}Sampler` : \"\"}\r\n            #else\r\n                , ${this._2DSamplerName}\r\n                ${isWebGPU ? `, ${this._2DSamplerName}Sampler` : \"\"}\r\n            #endif\r\n            #if defined(NORMAL) && defined(USESPHERICALINVERTEX)\r\n                , ${isWebGPU ? \"input.\" : \"\"}${this._vEnvironmentIrradianceName}\r\n            #endif\r\n            #if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\r\n                    , ${this._reflectionMatrixName}\r\n            #endif\r\n            #ifdef USEIRRADIANCEMAP\r\n                , irradianceSampler         // ** not handled **\r\n                ${isWebGPU ? `, irradianceSamplerSampler` : \"\"}\r\n                #ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\r\n                , vReflectionDominantDirection\r\n                #endif\r\n            #endif\r\n            #ifndef LODBASEDMICROSFURACE\r\n                #ifdef ${this._define3DName}\r\n                    , ${this._cubeSamplerName}\r\n                    ${isWebGPU ? `, ${this._cubeSamplerName}Sampler` : \"\"}\r\n                    , ${this._cubeSamplerName}\r\n                    ${isWebGPU ? `, ${this._cubeSamplerName}Sampler` : \"\"}\r\n                #else\r\n                    , ${this._2DSamplerName}\r\n                    ${isWebGPU ? `, ${this._2DSamplerName}Sampler` : \"\"}\r\n                    , ${this._2DSamplerName}                    \r\n                    ${isWebGPU ? `, ${this._2DSamplerName}Sampler` : \"\"}\r\n                #endif\r\n            #endif\r\n            #ifdef REALTIME_FILTERING\r\n                , ${this._vReflectionFilteringInfoName}\r\n                #ifdef IBL_CDF_FILTERING\r\n                    , icdfSampler         // ** not handled **\r\n                    ${isWebGPU ? `, icdfSamplerSampler` : \"\"}\r\n                #endif\r\n            #endif\r\n            , viewDirectionW\r\n            , diffuseRoughness\r\n            , surfaceAlbedo\r\n            );\r\n        #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        this._scene = state.sharedData.scene;\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            this._defineLODReflectionAlpha = state._getFreeDefineName(\"LODINREFLECTIONALPHA\");\r\n            this._defineLinearSpecularReflection = state._getFreeDefineName(\"LINEARSPECULARREFLECTION\");\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        if (this.texture) {\r\n            codeString += `${this._codeVariableName}.texture.gammaSpace = ${this.texture.gammaSpace};\\n`;\r\n        }\r\n        codeString += `${this._codeVariableName}.useSphericalHarmonics = ${this.useSphericalHarmonics};\\n`;\r\n        codeString += `${this._codeVariableName}.forceIrradianceInFragment = ${this.forceIrradianceInFragment};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.useSphericalHarmonics = this.useSphericalHarmonics;\r\n        serializationObject.forceIrradianceInFragment = this.forceIrradianceInFragment;\r\n        serializationObject.gammaSpace = this.texture?.gammaSpace ?? true;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the scene to deserialize in\r\n     * @param rootUrl - the root URL for assets\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.useSphericalHarmonics = serializationObject.useSphericalHarmonics;\r\n        this.forceIrradianceInFragment = serializationObject.forceIrradianceInFragment;\r\n        if (this.texture) {\r\n            this.texture.gammaSpace = serializationObject.gammaSpace;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for reflectionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReflectionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ReflectionBlock\", ReflectionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type ReflectionBlock } from \"./reflectionBlock.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type PBRMetallicRoughnessBlock } from \"./pbrMetallicRoughnessBlock.pure\";\r\nimport { type PerturbNormalBlock } from \"../Fragment/perturbNormalBlock.pure\";\r\nimport { PBRClearCoatConfiguration } from \"../../../PBR/pbrClearCoatConfiguration\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { TBNBlock } from \"../Fragment/TBNBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the clear coat module of the PBR material\r\n */\r\nexport class ClearCoatBlock extends NodeMaterialBlock {\r\n    private _scene: Scene;\r\n    private _tangentCorrectionFactorName = \"\";\r\n\r\n    /**\r\n     * Create a new ClearCoatBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"intensity\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"roughness\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"indexOfRefraction\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"normalMapColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.Vector2, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"tintColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"tintAtDistance\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"tintThickness\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"worldTangent\", NodeMaterialBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.worldNormal.addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color4 | NodeMaterialBlockConnectionPointTypes.Vector4 | NodeMaterialBlockConnectionPointTypes.Vector3\r\n        );\r\n        this.registerInput(\r\n            \"TBN\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"TBN\", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, \"TBNBlock\")\r\n        );\r\n\r\n        this.registerOutput(\r\n            \"clearcoat\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"clearcoat\", this, NodeMaterialConnectionPointDirection.Output, ClearCoatBlock, \"ClearCoatBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Defines if the F0 value should be remapped to account for the interface change in the material.\r\n     */\r\n    @editableInPropertyPage(\"Remap F0 on interface change\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true })\r\n    public remapF0OnInterfaceChange: boolean = true;\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"clearcoatOut\");\r\n        state._excludeVariableName(\"vClearCoatParams\");\r\n        state._excludeVariableName(\"vClearCoatTintParams\");\r\n        state._excludeVariableName(\"vClearCoatRefractionParams\");\r\n        state._excludeVariableName(\"vClearCoatTangentSpaceParams\");\r\n        state._excludeVariableName(\"vGeometricNormaClearCoatW\");\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../../ShadersWGSL/ShadersInclude/bumpFragmentMainFunctions\");\r\n        } else {\r\n            await import(\"../../../../Shaders/ShadersInclude/bumpFragmentMainFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ClearCoatBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity input component\r\n     */\r\n    public get intensity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the roughness input component\r\n     */\r\n    public get roughness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the ior input component\r\n     */\r\n    public get indexOfRefraction(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the bump texture input component\r\n     */\r\n    public get normalMapColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the tint color input component\r\n     */\r\n    public get tintColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the tint \"at distance\" input component\r\n     */\r\n    public get tintAtDistance(): NodeMaterialConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the tint thickness input component\r\n     */\r\n    public get tintThickness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the world tangent input component\r\n     */\r\n    public get worldTangent(): NodeMaterialConnectionPoint {\r\n        return this._inputs[8];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[9];\r\n    }\r\n\r\n    /**\r\n     * Gets the TBN input component\r\n     */\r\n    public get TBN(): NodeMaterialConnectionPoint {\r\n        return this._inputs[10];\r\n    }\r\n\r\n    /**\r\n     * Gets the clear coat object output component\r\n     */\r\n    public get clearcoat(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     */\r\n    public override autoConfigure() {\r\n        if (!this.intensity.isConnected) {\r\n            const intensityInput = new InputBlock(\"ClearCoat intensity\", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);\r\n            intensityInput.value = 1;\r\n            intensityInput.output.connectTo(this.intensity);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines to update\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        defines.setValue(\"CLEARCOAT\", true);\r\n        defines.setValue(\"CLEARCOAT_TEXTURE\", false, true);\r\n        defines.setValue(\"CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE\", true, true);\r\n        defines.setValue(\"CLEARCOAT_TINT\", this.tintColor.isConnected || this.tintThickness.isConnected || this.tintAtDistance.isConnected, true);\r\n        defines.setValue(\"CLEARCOAT_BUMP\", this.normalMapColor.isConnected, true);\r\n        defines.setValue(\r\n            \"CLEARCOAT_DEFAULTIOR\",\r\n            this.indexOfRefraction.isConnected ? this.indexOfRefraction.connectInputBlock!.value === PBRClearCoatConfiguration._DefaultIndexOfRefraction : true,\r\n            true\r\n        );\r\n        defines.setValue(\"CLEARCOAT_REMAP_F0\", this.remapF0OnInterfaceChange, true);\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind data to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind data for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        super.bind(effect, nodeMaterial, mesh);\r\n\r\n        // Clear Coat Refraction params\r\n        const indexOfRefraction = this.indexOfRefraction.connectInputBlock?.value ?? PBRClearCoatConfiguration._DefaultIndexOfRefraction;\r\n\r\n        const a = 1 - indexOfRefraction;\r\n        const b = 1 + indexOfRefraction;\r\n        const f0 = Math.pow(-a / b, 2); // Schlicks approx: (ior1 - ior2) / (ior1 + ior2) where ior2 for air is close to vacuum = 1.\r\n        const eta = 1 / indexOfRefraction;\r\n\r\n        effect.setFloat4(\"vClearCoatRefractionParams\", f0, eta, a, b);\r\n\r\n        // Clear Coat tangent space params\r\n        const mainPBRBlock = this.clearcoat.hasEndpoints ? (this.clearcoat.endpoints[0].ownerBlock as PBRMetallicRoughnessBlock) : null;\r\n        const perturbedNormalBlock = mainPBRBlock?.perturbedNormal.isConnected ? (mainPBRBlock.perturbedNormal.connectedPoint!.ownerBlock as PerturbNormalBlock) : null;\r\n\r\n        if (this._scene._mirroredCameraPosition) {\r\n            effect.setFloat2(\"vClearCoatTangentSpaceParams\", perturbedNormalBlock?.invertX ? 1.0 : -1.0, perturbedNormalBlock?.invertY ? 1.0 : -1.0);\r\n        } else {\r\n            effect.setFloat2(\"vClearCoatTangentSpaceParams\", perturbedNormalBlock?.invertX ? -1.0 : 1.0, perturbedNormalBlock?.invertY ? -1.0 : 1.0);\r\n        }\r\n\r\n        if (mesh) {\r\n            effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1);\r\n        }\r\n    }\r\n\r\n    private _generateTBNSpace(state: NodeMaterialBuildState, worldPositionVarName: string, worldNormalVarName: string) {\r\n        let code = \"\";\r\n\r\n        const comments = `//${this.name}`;\r\n        const worldTangent = this.worldTangent;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        if (!isWebGPU) {\r\n            state._emitExtension(\"derivatives\", \"#extension GL_OES_standard_derivatives : enable\");\r\n        }\r\n\r\n        const tangentReplaceString = { search: /defined\\(TANGENT\\)/g, replace: worldTangent.isConnected ? \"defined(TANGENT)\" : \"defined(IGNORE)\" };\r\n\r\n        const tbn = this.TBN;\r\n        if (tbn.isConnected) {\r\n            state.compilationString += `\r\n            #ifdef TBNBLOCK\r\n                ${isWebGPU ? \"var TBN\" : \"mat3 TBN\"} = ${tbn.associatedVariableName};\r\n            #endif\r\n            `;\r\n        } else if (worldTangent.isConnected) {\r\n            code += `${state._declareLocalVar(\"tbnNormal\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${worldNormalVarName}.xyz);\\n`;\r\n            code += `${state._declareLocalVar(\"tbnTangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${worldTangent.associatedVariableName}.xyz);\\n`;\r\n            code += `${state._declareLocalVar(\"tbnBitangent\", NodeMaterialBlockConnectionPointTypes.Vector3)} = cross(tbnNormal, tbnTangent) * ${this._tangentCorrectionFactorName};\\n`;\r\n            code += `${isWebGPU ? \"var vTBN\" : \"mat3 vTBN\"} = ${isWebGPU ? \"mat3x3f\" : \"mat3\"}(tbnTangent, tbnBitangent, tbnNormal);\\n`;\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"bumpFragmentMainFunctions\", comments, {\r\n            replaceStrings: [tangentReplaceString],\r\n        });\r\n\r\n        return code;\r\n    }\r\n\r\n    /** @internal */\r\n    public static _GetInitializationCode(state: NodeMaterialBuildState, ccBlock: Nullable<ClearCoatBlock>): string {\r\n        let code = \"\";\r\n\r\n        const intensity = ccBlock?.intensity.isConnected ? ccBlock.intensity.associatedVariableName : \"1.\";\r\n        const roughness = ccBlock?.roughness.isConnected ? ccBlock.roughness.associatedVariableName : \"0.\";\r\n\r\n        const tintColor = ccBlock?.tintColor.isConnected ? ccBlock.tintColor.associatedVariableName : `vec3${state.fSuffix}(1.)`;\r\n        const tintThickness = ccBlock?.tintThickness.isConnected ? ccBlock.tintThickness.associatedVariableName : \"1.\";\r\n\r\n        code += `\r\n            #ifdef CLEARCOAT\r\n                ${state._declareLocalVar(\"vClearCoatParams\", NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2${state.fSuffix}(${intensity}, ${roughness});\r\n                ${state._declareLocalVar(\"vClearCoatTintParams\", NodeMaterialBlockConnectionPointTypes.Vector4)} = vec4${state.fSuffix}(${tintColor}, ${tintThickness});\r\n            #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param state current state of the node material building\r\n     * @param ccBlock instance of a ClearCoatBlock or null if the code must be generated without an active clear coat module\r\n     * @param reflectionBlock instance of a ReflectionBlock null if the code must be generated without an active reflection module\r\n     * @param worldPosVarName name of the variable holding the world position\r\n     * @param generateTBNSpace if true, the code needed to create the TBN coordinate space is generated\r\n     * @param vTBNAvailable indicate that the vTBN variable is already existing because it has already been generated by another block (PerturbNormal or Anisotropy)\r\n     * @param worldNormalVarName name of the variable holding the world normal\r\n     * @returns the shader code\r\n     */\r\n    public static GetCode(\r\n        state: NodeMaterialBuildState,\r\n        ccBlock: Nullable<ClearCoatBlock>,\r\n        reflectionBlock: Nullable<ReflectionBlock>,\r\n        worldPosVarName: string,\r\n        generateTBNSpace: boolean,\r\n        vTBNAvailable: boolean,\r\n        worldNormalVarName: string\r\n    ): string {\r\n        let code = \"\";\r\n\r\n        const normalMapColor = ccBlock?.normalMapColor.isConnected ? ccBlock.normalMapColor.associatedVariableName : `vec3${state.fSuffix}(0.)`;\r\n        const uv = ccBlock?.uv.isConnected ? ccBlock.uv.associatedVariableName : `vec2${state.fSuffix}(0.)`;\r\n\r\n        const tintAtDistance = ccBlock?.tintAtDistance.isConnected ? ccBlock.tintAtDistance.associatedVariableName : \"1.\";\r\n        const tintTexture = `vec4${state.fSuffix}(0.)`;\r\n\r\n        if (ccBlock) {\r\n            state._emitUniformFromString(\"vClearCoatRefractionParams\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n            state._emitUniformFromString(\"vClearCoatTangentSpaceParams\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n            const normalShading = ccBlock.worldNormal;\r\n            code += `${state._declareLocalVar(\"vGeometricNormaClearCoatW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = ${normalShading.isConnected ? \"normalize(\" + normalShading.associatedVariableName + \".xyz)\" : \"geometricNormalW\"};\\n`;\r\n        } else {\r\n            code += `${state._declareLocalVar(\"vGeometricNormaClearCoatW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = geometricNormalW;\\n`;\r\n        }\r\n\r\n        if (generateTBNSpace && ccBlock) {\r\n            code += ccBlock._generateTBNSpace(state, worldPosVarName, worldNormalVarName);\r\n            vTBNAvailable = ccBlock.worldTangent.isConnected;\r\n        }\r\n\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        code += `${isWebGPU ? \"var clearcoatOut: clearcoatOutParams\" : \"clearcoatOutParams clearcoatOut\"};\r\n\r\n        #ifdef CLEARCOAT\r\n            clearcoatOut = clearcoatBlock(\r\n                ${worldPosVarName}.xyz\r\n                , vGeometricNormaClearCoatW\r\n                , viewDirectionW\r\n                , vClearCoatParams\r\n                , specularEnvironmentR0\r\n            #ifdef CLEARCOAT_TEXTURE\r\n                , vec2${state.fSuffix}(0.)\r\n            #endif\r\n            #ifdef CLEARCOAT_TINT\r\n                , vClearCoatTintParams\r\n                , ${tintAtDistance}\r\n                , ${isWebGPU ? \"uniforms.\" : \"\"}vClearCoatRefractionParams\r\n                #ifdef CLEARCOAT_TINT_TEXTURE\r\n                    , ${tintTexture}\r\n                #endif\r\n            #endif\r\n            #ifdef CLEARCOAT_BUMP\r\n                , vec2${state.fSuffix}(0., 1.)\r\n                , vec4${state.fSuffix}(${normalMapColor}, 0.)\r\n                , ${uv}\r\n                #if defined(${vTBNAvailable ? \"TANGENT\" : \"IGNORE\"}) && defined(NORMAL)\r\n                    , vTBN\r\n                #else\r\n                    , ${isWebGPU ? \"uniforms.\" : \"\"}vClearCoatTangentSpaceParams\r\n                #endif\r\n                #ifdef OBJECTSPACE_NORMALMAP\r\n                    , normalMatrix\r\n                #endif\r\n            #endif\r\n            #if defined(FORCENORMALFORWARD) && defined(NORMAL)\r\n                , faceNormal\r\n            #endif\r\n            #ifdef REFLECTION\r\n                , ${isWebGPU ? \"uniforms.\" : \"\"}${reflectionBlock?._vReflectionMicrosurfaceInfosName}\r\n                , ${reflectionBlock?._vReflectionInfosName}\r\n                , ${reflectionBlock?.reflectionColor}\r\n                , ${isWebGPU ? \"uniforms.\" : \"\"}vLightingIntensity\r\n                #ifdef ${reflectionBlock?._define3DName}\r\n                    , ${reflectionBlock?._cubeSamplerName}       \r\n                    ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                #else\r\n                    , ${reflectionBlock?._2DSamplerName}       \r\n                    ${isWebGPU ? `, ${reflectionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                #endif\r\n                #ifndef LODBASEDMICROSFURACE\r\n                    #ifdef ${reflectionBlock?._define3DName}\r\n                        , ${reflectionBlock?._cubeSamplerName}       \r\n                        ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                        , ${reflectionBlock?._cubeSamplerName}\r\n                        ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                    #else\r\n                        , ${reflectionBlock?._2DSamplerName}\r\n                        ${isWebGPU ? `, ${reflectionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                        , ${reflectionBlock?._2DSamplerName}\r\n                        ${isWebGPU ? `, ${reflectionBlock?._2DSamplerName}Sampler` : \"\"}                        \r\n                    #endif\r\n                #endif\r\n            #endif\r\n            #if defined(CLEARCOAT_BUMP) || defined(TWOSIDEDLIGHTING)\r\n                , (${state._generateTernary(\"1.\", \"-1.\", isWebGPU ? \"fragmentInputs.frontFacing\" : \"gl_FrontFacing\")})\r\n            #endif\r\n            );\r\n        #else\r\n            clearcoatOut.specularEnvironmentR0 = specularEnvironmentR0;\r\n        #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        this._scene = state.sharedData.scene;\r\n\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.sharedData.bindableBlocks.push(this);\r\n            state.sharedData.blocksWithDefines.push(this);\r\n\r\n            this._tangentCorrectionFactorName = state._getFreeDefineName(\"tangentCorrectionFactor\");\r\n            state._emitUniformFromString(this._tangentCorrectionFactorName, NodeMaterialBlockConnectionPointTypes.Float);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.remapF0OnInterfaceChange = ${this.remapF0OnInterfaceChange};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.remapF0OnInterfaceChange = this.remapF0OnInterfaceChange;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the scene to deserialize in\r\n     * @param rootUrl - the root URL for assets\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.remapF0OnInterfaceChange = serializationObject.remapF0OnInterfaceChange ?? true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for clearCoatBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterClearCoatBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ClearCoatBlock\", ClearCoatBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { PBRIridescenceConfiguration } from \"../../../../Materials/PBR/pbrIridescenceConfiguration\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the iridescence module of the PBR material\r\n */\r\nexport class IridescenceBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new IridescenceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"intensity\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"indexOfRefraction\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"thickness\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\r\n            \"iridescence\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"iridescence\", this, NodeMaterialConnectionPointDirection.Output, IridescenceBlock, \"IridescenceBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"iridescenceOut\");\r\n        state._excludeVariableName(\"vIridescenceParams\");\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"IridescenceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity input component\r\n     */\r\n    public get intensity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the indexOfRefraction input component\r\n     */\r\n    public get indexOfRefraction(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the thickness input component\r\n     */\r\n    public get thickness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the iridescence object output component\r\n     */\r\n    public get iridescence(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     */\r\n    public override autoConfigure() {\r\n        if (!this.intensity.isConnected) {\r\n            const intensityInput = new InputBlock(\"Iridescence intensity\", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);\r\n            intensityInput.value = 1;\r\n            intensityInput.output.connectTo(this.intensity);\r\n\r\n            const indexOfRefractionInput = new InputBlock(\"Iridescence ior\", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);\r\n            indexOfRefractionInput.value = 1.3;\r\n            indexOfRefractionInput.output.connectTo(this.indexOfRefraction);\r\n\r\n            const thicknessInput = new InputBlock(\"Iridescence thickness\", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);\r\n            thicknessInput.value = 400;\r\n            thicknessInput.output.connectTo(this.thickness);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines to update\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        defines.setValue(\"IRIDESCENCE\", true, true);\r\n        defines.setValue(\"IRIDESCENCE_TEXTURE\", false, true);\r\n        defines.setValue(\"IRIDESCENCE_THICKNESS_TEXTURE\", false, true);\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param iridescenceBlock instance of a IridescenceBlock or null if the code must be generated without an active iridescence module\r\n     * @param state defines the build state\r\n     * @returns the shader code\r\n     */\r\n    public static GetCode(iridescenceBlock: Nullable<IridescenceBlock>, state: NodeMaterialBuildState): string {\r\n        let code = \"\";\r\n\r\n        const intensityName = iridescenceBlock?.intensity.isConnected ? iridescenceBlock.intensity.associatedVariableName : \"1.\";\r\n        const indexOfRefraction = iridescenceBlock?.indexOfRefraction.isConnected\r\n            ? iridescenceBlock.indexOfRefraction.associatedVariableName\r\n            : PBRIridescenceConfiguration._DefaultIndexOfRefraction;\r\n        const thickness = iridescenceBlock?.thickness.isConnected ? iridescenceBlock.thickness.associatedVariableName : PBRIridescenceConfiguration._DefaultMaximumThickness;\r\n\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        code += `${isWebGPU ? \"var iridescenceOut: iridescenceOutParams\" : \"iridescenceOutParams iridescenceOut\"};\r\n\r\n        #ifdef IRIDESCENCE\r\n            iridescenceOut = iridescenceBlock(\r\n                vec4(${intensityName}, ${indexOfRefraction}, 1., ${thickness})\r\n                , NdotV\r\n                , specularEnvironmentR0\r\n                #ifdef CLEARCOAT\r\n                    , NdotVUnclamped\r\n                    , vClearCoatParams\r\n                #endif                \r\n            );\r\n\r\n            ${isWebGPU ? \"let\" : \"float\"} iridescenceIntensity = iridescenceOut.iridescenceIntensity;\r\n            specularEnvironmentR0 = iridescenceOut.specularEnvironmentR0;\r\n        #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.sharedData.bindableBlocks.push(this);\r\n            state.sharedData.blocksWithDefines.push(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the scene to deserialize in\r\n     * @param rootUrl - the root URL for assets\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for iridescenceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterIridescenceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.IridescenceBlock\", IridescenceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { CubeTextureParse, type CubeTexture } from \"../../../Textures/cubeTexture.pure\";\r\nimport { Texture } from \"../../../Textures/texture.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the refraction part of the sub surface module of the PBR material\r\n */\r\nexport class RefractionBlock extends NodeMaterialBlock {\r\n    /** @internal */\r\n    public _define3DName: string;\r\n    /** @internal */\r\n    public _refractionMatrixName: string;\r\n    /** @internal */\r\n    public _defineLODRefractionAlpha: string;\r\n    /** @internal */\r\n    public _defineLinearSpecularRefraction: string;\r\n    /** @internal */\r\n    public _defineOppositeZ: string;\r\n    /** @internal */\r\n    public _cubeSamplerName: string;\r\n    /** @internal */\r\n    public _2DSamplerName: string;\r\n    /** @internal */\r\n    public _vRefractionMicrosurfaceInfosName: string;\r\n    /** @internal */\r\n    public _vRefractionInfosName: string;\r\n    /** @internal */\r\n    public _vRefractionFilteringInfoName: string;\r\n\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * The properties below are set by the main PBR block prior to calling methods of this class.\r\n     * This is to avoid having to add them as inputs here whereas they are already inputs of the main block, so already known.\r\n     * It's less burden on the user side in the editor part.\r\n     */\r\n\r\n    /** @internal */\r\n    public viewConnectionPoint: NodeMaterialConnectionPoint;\r\n\r\n    /** @internal */\r\n    public indexOfRefractionConnectionPoint: NodeMaterialConnectionPoint;\r\n\r\n    /**\r\n     * This parameters will make the material used its opacity to control how much it is refracting against not.\r\n     * Materials half opaque for instance using refraction could benefit from this control.\r\n     */\r\n    @editableInPropertyPage(\"Link refraction to transparency\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { update: true } })\r\n    public linkRefractionWithTransparency: boolean = false;\r\n\r\n    /**\r\n     * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.\r\n     */\r\n    @editableInPropertyPage(\"Invert refraction Y\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { update: true } })\r\n    public invertRefractionY: boolean = false;\r\n\r\n    /**\r\n     * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.\r\n     */\r\n    @editableInPropertyPage(\"Use thickness as depth\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { update: true } })\r\n    public useThicknessAsDepth: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public texture: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Create a new RefractionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"intensity\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"tintAtDistance\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"volumeIndexOfRefraction\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\r\n            \"refraction\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"refraction\", this, NodeMaterialConnectionPointDirection.Output, RefractionBlock, \"RefractionBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"vRefractionPosition\");\r\n        state._excludeVariableName(\"vRefractionSize\");\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RefractionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the intensity input component\r\n     */\r\n    public get intensity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the tint at distance input component\r\n     */\r\n    public get tintAtDistance(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the volume index of refraction input component\r\n     */\r\n    public get volumeIndexOfRefraction(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the view input component\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this.viewConnectionPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the refraction object output component\r\n     */\r\n    public get refraction(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Returns true if the block has a texture\r\n     */\r\n    public get hasTexture(): boolean {\r\n        return !!this._getTexture();\r\n    }\r\n\r\n    protected _getTexture(): Nullable<BaseTexture> {\r\n        if (this.texture) {\r\n            return this.texture;\r\n        }\r\n\r\n        return this._scene.environmentTexture;\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.intensity.isConnected) {\r\n            const intensityInput = new InputBlock(\"Refraction intensity\", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);\r\n            intensityInput.value = 1;\r\n            intensityInput.output.connectTo(this.intensity);\r\n        }\r\n\r\n        if (this.view && !this.view.isConnected) {\r\n            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View && additionalFilteringInfo(b));\r\n\r\n            if (!viewInput) {\r\n                viewInput = new InputBlock(\"view\");\r\n                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);\r\n            }\r\n            viewInput.output.connectTo(this.view);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        const refractionTexture = this._getTexture();\r\n        const refraction = refractionTexture && refractionTexture.getTextureMatrix;\r\n\r\n        defines.setValue(\"SS_REFRACTION\", refraction, true);\r\n\r\n        if (!refraction) {\r\n            return;\r\n        }\r\n\r\n        defines.setValue(this._define3DName, refractionTexture.isCube, true);\r\n        defines.setValue(this._defineLODRefractionAlpha, refractionTexture.lodLevelInAlpha, true);\r\n        defines.setValue(this._defineLinearSpecularRefraction, refractionTexture.linearSpecularLOD, true);\r\n        defines.setValue(this._defineOppositeZ, this._scene.useRightHandedSystem && refractionTexture.isCube ? !refractionTexture.invertZ : refractionTexture.invertZ, true);\r\n\r\n        defines.setValue(\"SS_LINKREFRACTIONTOTRANSPARENCY\", this.linkRefractionWithTransparency, true);\r\n        defines.setValue(\"SS_GAMMAREFRACTION\", refractionTexture.gammaSpace, true);\r\n        defines.setValue(\"SS_RGBDREFRACTION\", refractionTexture.isRGBD, true);\r\n        defines.setValue(\"SS_USE_LOCAL_REFRACTIONMAP_CUBIC\", (<any>refractionTexture).boundingBoxSize ? true : false, true);\r\n        defines.setValue(\"SS_USE_THICKNESS_AS_DEPTH\", this.useThicknessAsDepth, true);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if ready\r\n     */\r\n    public override isReady() {\r\n        const texture = this._getTexture();\r\n\r\n        if (texture && !texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        super.bind(effect, nodeMaterial, mesh);\r\n\r\n        const refractionTexture = this._getTexture();\r\n\r\n        if (!refractionTexture) {\r\n            return;\r\n        }\r\n\r\n        if (refractionTexture.isCube) {\r\n            effect.setTexture(this._cubeSamplerName, refractionTexture);\r\n        } else {\r\n            effect.setTexture(this._2DSamplerName, refractionTexture);\r\n        }\r\n\r\n        effect.setMatrix(this._refractionMatrixName, refractionTexture.getRefractionTextureMatrix());\r\n\r\n        let depth = 1.0;\r\n        if (!refractionTexture.isCube) {\r\n            if ((<any>refractionTexture).depth) {\r\n                depth = (<any>refractionTexture).depth;\r\n            }\r\n        }\r\n\r\n        const indexOfRefraction = this.volumeIndexOfRefraction.connectInputBlock?.value ?? this.indexOfRefractionConnectionPoint.connectInputBlock?.value ?? 1.5;\r\n\r\n        effect.setFloat4(this._vRefractionInfosName, refractionTexture.level, 1 / indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);\r\n\r\n        effect.setFloat4(\r\n            this._vRefractionMicrosurfaceInfosName,\r\n            refractionTexture.getSize().width,\r\n            refractionTexture.lodGenerationScale,\r\n            refractionTexture.lodGenerationOffset,\r\n            1 / indexOfRefraction\r\n        );\r\n\r\n        const width = refractionTexture.getSize().width;\r\n\r\n        effect.setFloat2(this._vRefractionFilteringInfoName, width, Math.log2(width));\r\n\r\n        if ((<any>refractionTexture).boundingBoxSize) {\r\n            const cubeTexture = <CubeTexture>refractionTexture;\r\n            effect.setVector3(\"vRefractionPosition\", cubeTexture.boundingBoxPosition);\r\n            effect.setVector3(\"vRefractionSize\", cubeTexture.boundingBoxSize);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param state current state of the node material building\r\n     * @returns the shader code\r\n     */\r\n    public getCode(state: NodeMaterialBuildState): string {\r\n        const code = \"\";\r\n\r\n        state.sharedData.blockingBlocks.push(this);\r\n        state.sharedData.textureBlocks.push(this);\r\n\r\n        // Samplers\r\n        this._cubeSamplerName = state._getFreeVariableName(this.name + \"CubeSampler\");\r\n        state.samplers.push(this._cubeSamplerName);\r\n\r\n        this._2DSamplerName = state._getFreeVariableName(this.name + \"2DSampler\");\r\n        state.samplers.push(this._2DSamplerName);\r\n\r\n        this._define3DName = state._getFreeDefineName(\"SS_REFRACTIONMAP_3D\");\r\n        const refractionTexture = this._getTexture();\r\n\r\n        if (refractionTexture) {\r\n            state._samplerDeclaration += `#ifdef ${this._define3DName}\\n`;\r\n            state._emitCubeSampler(this._cubeSamplerName, undefined, true);\r\n            state._samplerDeclaration += `#else\\n`;\r\n            state._emit2DSampler(this._2DSamplerName, undefined, true);\r\n            state._samplerDeclaration += `#endif\\n`;\r\n        }\r\n\r\n        // Fragment\r\n        state.sharedData.blocksWithDefines.push(this);\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        this._defineLODRefractionAlpha = state._getFreeDefineName(\"SS_LODINREFRACTIONALPHA\");\r\n        this._defineLinearSpecularRefraction = state._getFreeDefineName(\"SS_LINEARSPECULARREFRACTION\");\r\n        this._defineOppositeZ = state._getFreeDefineName(\"SS_REFRACTIONMAP_OPPOSITEZ\");\r\n\r\n        this._refractionMatrixName = state._getFreeVariableName(\"refractionMatrix\");\r\n\r\n        state._emitUniformFromString(this._refractionMatrixName, NodeMaterialBlockConnectionPointTypes.Matrix);\r\n\r\n        if (state.shaderLanguage !== ShaderLanguage.WGSL) {\r\n            state._emitFunction(\r\n                \"sampleRefraction\",\r\n                `\r\n                #ifdef ${this._define3DName}\r\n                    #define sampleRefraction(s, c) textureCube(s, c)\r\n                #else\r\n                    #define sampleRefraction(s, c) texture2D(s, c)\r\n                #endif\\n`,\r\n                `//${this.name}`\r\n            );\r\n\r\n            state._emitFunction(\r\n                \"sampleRefractionLod\",\r\n                `\r\n                #ifdef ${this._define3DName}\r\n                    #define sampleRefractionLod(s, c, l) textureCubeLodEXT(s, c, l)\r\n                #else\r\n                    #define sampleRefractionLod(s, c, l) texture2DLodEXT(s, c, l)\r\n                #endif\\n`,\r\n                `//${this.name}`\r\n            );\r\n        }\r\n\r\n        this._vRefractionMicrosurfaceInfosName = state._getFreeVariableName(\"vRefractionMicrosurfaceInfos\");\r\n\r\n        state._emitUniformFromString(this._vRefractionMicrosurfaceInfosName, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        this._vRefractionInfosName = state._getFreeVariableName(\"vRefractionInfos\");\r\n\r\n        state._emitUniformFromString(this._vRefractionInfosName, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        this._vRefractionFilteringInfoName = state._getFreeVariableName(\"vRefractionFilteringInfo\");\r\n\r\n        state._emitUniformFromString(this._vRefractionFilteringInfoName, NodeMaterialBlockConnectionPointTypes.Vector2);\r\n\r\n        state._emitUniformFromString(\"vRefractionPosition\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        state._emitUniformFromString(\"vRefractionSize\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        this._scene = state.sharedData.scene;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        if (this.texture) {\r\n            if (this.texture.isCube) {\r\n                codeString = `${this._codeVariableName}.texture = new BABYLON.CubeTexture(\"${this.texture.name}\");\\n`;\r\n            } else {\r\n                codeString = `${this._codeVariableName}.texture = new BABYLON.Texture(\"${this.texture.name}\");\\n`;\r\n            }\r\n            codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\\n`;\r\n        }\r\n\r\n        codeString += `${this._codeVariableName}.linkRefractionWithTransparency = ${this.linkRefractionWithTransparency};\\n`;\r\n        codeString += `${this._codeVariableName}.invertRefractionY = ${this.invertRefractionY};\\n`;\r\n        codeString += `${this._codeVariableName}.useThicknessAsDepth = ${this.useThicknessAsDepth};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        if (this.texture && !this.texture.isRenderTarget) {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        serializationObject.linkRefractionWithTransparency = this.linkRefractionWithTransparency;\r\n        serializationObject.invertRefractionY = this.invertRefractionY;\r\n        serializationObject.useThicknessAsDepth = this.useThicknessAsDepth;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        if (serializationObject.texture) {\r\n            rootUrl = serializationObject.texture.url.indexOf(\"data:\") === 0 ? \"\" : rootUrl;\r\n            if (serializationObject.texture.isCube) {\r\n                this.texture = CubeTextureParse(serializationObject.texture, scene, rootUrl);\r\n            } else {\r\n                this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl);\r\n            }\r\n        }\r\n\r\n        this.linkRefractionWithTransparency = serializationObject.linkRefractionWithTransparency;\r\n        this.invertRefractionY = serializationObject.invertRefractionY;\r\n        this.useThicknessAsDepth = !!serializationObject.useThicknessAsDepth;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for refractionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRefractionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RefractionBlock\", RefractionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { type ReflectionBlock } from \"./reflectionBlock.pure\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { RefractionBlock } from \"./refractionBlock.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { PBRSubSurfaceConfiguration } from \"core/Materials/PBR/pbrSubSurfaceConfiguration\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to implement the sub surface module of the PBR material\r\n */\r\nexport class SubSurfaceBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new SubSurfaceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"thickness\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"tintColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"translucencyIntensity\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"translucencyDiffusionDist\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\r\n            \"refraction\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"refraction\", this, NodeMaterialConnectionPointDirection.Input, RefractionBlock, \"RefractionBlock\")\r\n        );\r\n        this.registerInput(\"dispersion\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n\r\n        this.registerOutput(\r\n            \"subsurface\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"subsurface\", this, NodeMaterialConnectionPointDirection.Output, SubSurfaceBlock, \"SubSurfaceBlock\")\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Set it to true if your rendering in 8.0+ is different from that in 7 when you use sub-surface properties (transmission, refraction, etc.)\r\n     */\r\n    @editableInPropertyPage(\"Apply albedo after sub-surface\", PropertyTypeForEdition.Boolean, \"ADVANCED\")\r\n    public applyAlbedoAfterSubSurface: boolean = PBRSubSurfaceConfiguration.DEFAULT_APPLY_ALBEDO_AFTERSUBSURFACE;\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"subSurfaceOut\");\r\n        state._excludeVariableName(\"vThicknessParam\");\r\n        state._excludeVariableName(\"vTintColor\");\r\n        state._excludeVariableName(\"vTranslucencyColor\");\r\n        state._excludeVariableName(\"vSubSurfaceIntensity\");\r\n        state._excludeVariableName(\"dispersion\");\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SubSurfaceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the thickness component\r\n     */\r\n    public get thickness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the tint color input component\r\n     */\r\n    public get tintColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the translucency intensity input component\r\n     */\r\n    public get translucencyIntensity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the translucency diffusion distance input component\r\n     */\r\n    public get translucencyDiffusionDist(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the refraction object parameters\r\n     */\r\n    public get refraction(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the dispersion input component\r\n     */\r\n    public get dispersion(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the sub surface object output component\r\n     */\r\n    public get subsurface(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     */\r\n    public override autoConfigure() {\r\n        if (!this.thickness.isConnected) {\r\n            const thicknessInput = new InputBlock(\"SubSurface thickness\", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);\r\n            thicknessInput.value = 0;\r\n            thicknessInput.output.connectTo(this.thickness);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        const translucencyEnabled = this.translucencyDiffusionDist.isConnected || this.translucencyIntensity.isConnected;\r\n\r\n        defines.setValue(\"SUBSURFACE\", translucencyEnabled || this.refraction.isConnected, true);\r\n        defines.setValue(\"SS_TRANSLUCENCY\", translucencyEnabled, true);\r\n        defines.setValue(\"SS_THICKNESSANDMASK_TEXTURE\", false, true);\r\n        defines.setValue(\"SS_REFRACTIONINTENSITY_TEXTURE\", false, true);\r\n        defines.setValue(\"SS_TRANSLUCENCYINTENSITY_TEXTURE\", false, true);\r\n        defines.setValue(\"SS_USE_GLTF_TEXTURES\", false, true);\r\n        defines.setValue(\"SS_DISPERSION\", this.dispersion.isConnected, true);\r\n        defines.setValue(\"SS_APPLY_ALBEDO_AFTER_SUBSURFACE\", this.applyAlbedoAfterSubSurface, true);\r\n    }\r\n\r\n    /**\r\n     * Gets the main code of the block (fragment side)\r\n     * @param state current state of the node material building\r\n     * @param ssBlock instance of a SubSurfaceBlock or null if the code must be generated without an active sub surface module\r\n     * @param reflectionBlock instance of a ReflectionBlock null if the code must be generated without an active reflection module\r\n     * @param worldPosVarName name of the variable holding the world position\r\n     * @returns the shader code\r\n     */\r\n    public static GetCode(state: NodeMaterialBuildState, ssBlock: Nullable<SubSurfaceBlock>, reflectionBlock: Nullable<ReflectionBlock>, worldPosVarName: string): string {\r\n        let code = \"\";\r\n\r\n        const thickness = ssBlock?.thickness.isConnected ? ssBlock.thickness.associatedVariableName : \"0.\";\r\n        const tintColor = ssBlock?.tintColor.isConnected ? ssBlock.tintColor.associatedVariableName : \"vec3(1.)\";\r\n        const translucencyIntensity = ssBlock?.translucencyIntensity.isConnected ? ssBlock?.translucencyIntensity.associatedVariableName : \"1.\";\r\n        const translucencyDiffusionDistance = ssBlock?.translucencyDiffusionDist.isConnected ? ssBlock?.translucencyDiffusionDist.associatedVariableName : \"vec3(1.)\";\r\n\r\n        const refractionBlock: Nullable<RefractionBlock> = (ssBlock?.refraction.isConnected ? ssBlock?.refraction.connectedPoint?.ownerBlock : null) as Nullable<RefractionBlock>;\r\n\r\n        const refractionTintAtDistance = refractionBlock?.tintAtDistance.isConnected ? refractionBlock.tintAtDistance.associatedVariableName : \"1.\";\r\n        const refractionIntensity = refractionBlock?.intensity.isConnected ? refractionBlock.intensity.associatedVariableName : \"1.\";\r\n        const refractionView = refractionBlock?.view.isConnected ? refractionBlock.view.associatedVariableName : \"\";\r\n\r\n        const dispersion = ssBlock?.dispersion.isConnected ? ssBlock?.dispersion.associatedVariableName : \"0.0\";\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        code += refractionBlock?.getCode(state) ?? \"\";\r\n\r\n        code += `${isWebGPU ? \"var subSurfaceOut: subSurfaceOutParams\" : \"subSurfaceOutParams subSurfaceOut\"};\r\n\r\n        #ifdef SUBSURFACE\r\n            ${state._declareLocalVar(\"vThicknessParam\", NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2${state.fSuffix}(0., ${thickness});\r\n            ${state._declareLocalVar(\"vTintColor\", NodeMaterialBlockConnectionPointTypes.Vector4)} = vec4${state.fSuffix}(${tintColor}, ${refractionTintAtDistance});\r\n            ${state._declareLocalVar(\"vSubSurfaceIntensity\", NodeMaterialBlockConnectionPointTypes.Vector3)} = vec3(${refractionIntensity}, ${translucencyIntensity}, 0.);\r\n            ${state._declareLocalVar(\"dispersion\", NodeMaterialBlockConnectionPointTypes.Float)} = ${dispersion};\r\n            subSurfaceOut = subSurfaceBlock(\r\n                vSubSurfaceIntensity\r\n                , vThicknessParam\r\n                , vTintColor\r\n                , normalW\r\n            #ifdef LEGACY_SPECULAR_ENERGY_CONSERVATION\r\n        `;\r\n\r\n        code += isWebGPU\r\n            ? `, vec3f(max(colorSpecularEnvironmentReflectance.r, max(colorSpecularEnvironmentReflectance.g, colorSpecularEnvironmentReflectance.b)))/n`\r\n            : `, vec3(max(colorSpecularEnvironmentReflectance.r, max(colorSpecularEnvironmentReflectance.g, colorSpecularEnvironmentReflectance.b)))/n`;\r\n\r\n        code += `#else\r\n                , baseSpecularEnvironmentReflectance\r\n            #endif\r\n            #ifdef SS_THICKNESSANDMASK_TEXTURE\r\n                , vec4${state.fSuffix}(0.)\r\n            #endif\r\n            #ifdef REFLECTION\r\n                #ifdef SS_TRANSLUCENCY\r\n                    , ${(isWebGPU ? \"uniforms.\" : \"\") + reflectionBlock?._reflectionMatrixName}\r\n                    #ifdef USESPHERICALFROMREFLECTIONMAP\r\n                        #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)\r\n                            , reflectionOut.irradianceVector\r\n                        #endif\r\n                        #if defined(REALTIME_FILTERING)\r\n                            , ${reflectionBlock?._cubeSamplerName}\r\n                            ${isWebGPU ? `, ${reflectionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                            , ${reflectionBlock?._vReflectionFilteringInfoName}\r\n                        #endif\r\n                        #endif\r\n                    #ifdef USEIRRADIANCEMAP\r\n                        , irradianceSampler\r\n                        ${isWebGPU ? `, irradianceSamplerSampler` : \"\"}\r\n                    #endif\r\n                #endif\r\n            #endif\r\n            #if defined(SS_REFRACTION) || defined(SS_TRANSLUCENCY)\r\n                , surfaceAlbedo\r\n            #endif\r\n            #ifdef SS_REFRACTION\r\n                , ${worldPosVarName}.xyz\r\n                , viewDirectionW\r\n                , ${refractionView}\r\n                , ${(isWebGPU ? \"uniforms.\" : \"\") + (refractionBlock?._vRefractionInfosName ?? \"\")}\r\n                , ${(isWebGPU ? \"uniforms.\" : \"\") + (refractionBlock?._refractionMatrixName ?? \"\")}\r\n                , ${(isWebGPU ? \"uniforms.\" : \"\") + (refractionBlock?._vRefractionMicrosurfaceInfosName ?? \"\")}\r\n                , ${isWebGPU ? \"uniforms.\" : \"\"}vLightingIntensity\r\n                #ifdef SS_LINKREFRACTIONTOTRANSPARENCY\r\n                    , alpha\r\n                #endif\r\n                #ifdef ${refractionBlock?._defineLODRefractionAlpha ?? \"IGNORE\"}\r\n                    , NdotVUnclamped\r\n                #endif\r\n                #ifdef ${refractionBlock?._defineLinearSpecularRefraction ?? \"IGNORE\"}\r\n                    , roughness\r\n                #endif\r\n                , alphaG\r\n                #ifdef ${refractionBlock?._define3DName ?? \"IGNORE\"}\r\n                    , ${refractionBlock?._cubeSamplerName ?? \"\"}\r\n                    ${isWebGPU ? `, ${refractionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                #else\r\n                    , ${refractionBlock?._2DSamplerName ?? \"\"}\r\n                    ${isWebGPU ? `, ${refractionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                #endif\r\n                #ifndef LODBASEDMICROSFURACE\r\n                    #ifdef ${refractionBlock?._define3DName ?? \"IGNORE\"}\r\n                        , ${refractionBlock?._cubeSamplerName ?? \"\"}                        \r\n                        ${isWebGPU ? `, ${refractionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                        , ${refractionBlock?._cubeSamplerName ?? \"\"}                        \r\n                        ${isWebGPU ? `, ${refractionBlock?._cubeSamplerName}Sampler` : \"\"}\r\n                    #else\r\n                        , ${refractionBlock?._2DSamplerName ?? \"\"}\r\n                        ${isWebGPU ? `, ${refractionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                        , ${refractionBlock?._2DSamplerName ?? \"\"}\r\n                        ${isWebGPU ? `, ${refractionBlock?._2DSamplerName}Sampler` : \"\"}\r\n                    #endif\r\n                #endif\r\n                #ifdef ANISOTROPIC\r\n                    , anisotropicOut\r\n                #endif\r\n                #ifdef REALTIME_FILTERING\r\n                    , ${refractionBlock?._vRefractionFilteringInfoName ?? \"\"}\r\n                #endif\r\n                #ifdef SS_USE_LOCAL_REFRACTIONMAP_CUBIC\r\n                    , vRefractionPosition\r\n                    , vRefractionSize\r\n                #endif\r\n                #ifdef SS_DISPERSION\r\n                    , dispersion\r\n                #endif\r\n            #endif\r\n            #ifdef SS_TRANSLUCENCY\r\n                , ${translucencyDiffusionDistance}\r\n                , vTintColor\r\n                #ifdef SS_TRANSLUCENCYCOLOR_TEXTURE\r\n                    , vec4${state.fSuffix}(0.)\r\n                #endif\r\n            #endif                \r\n            );\r\n\r\n            #ifdef SS_REFRACTION\r\n                surfaceAlbedo = subSurfaceOut.surfaceAlbedo;\r\n                #ifdef SS_LINKREFRACTIONTOTRANSPARENCY\r\n                    alpha = subSurfaceOut.alpha;\r\n                #endif\r\n            #endif\r\n        #else\r\n            subSurfaceOut.specularEnvironmentReflectance = colorSpecularEnvironmentReflectance;\r\n        #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        if (state.target === NodeMaterialBlockTargets.Fragment) {\r\n            state.sharedData.blocksWithDefines.push(this);\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for subSurfaceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSubSurfaceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SubSurfaceBlock\", SubSurfaceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from \"../../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterial, type NodeMaterialDefines } from \"../../nodeMaterial.pure\";\r\nimport { NodeMaterialSystemValues } from \"../../Enums/nodeMaterialSystemValues\";\r\nimport { InputBlock } from \"../Input/inputBlock.pure\";\r\nimport { type Light } from \"../../../../Lights/light\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type AbstractMesh } from \"../../../../Meshes/abstractMesh.pure\";\r\nimport { type Effect } from \"../../../effect.pure\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { PBRBaseMaterial } from \"../../../PBR/pbrBaseMaterial.pure\";\r\nimport { type Scene } from \"../../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../../nodeMaterialConnectionPointCustomObject\";\r\nimport { SheenBlock } from \"./sheenBlock.pure\";\r\nimport { type BaseTexture } from \"../../../Textures/baseTexture.pure\";\r\nimport { GetEnvironmentBRDFTexture } from \"../../../../Misc/brdfTextureTools\";\r\nimport { MaterialFlags } from \"../../../materialFlags\";\r\nimport { AnisotropyBlock } from \"./anisotropyBlock.pure\";\r\nimport { ReflectionBlock } from \"./reflectionBlock.pure\";\r\nimport { ClearCoatBlock } from \"./clearCoatBlock.pure\";\r\nimport { IridescenceBlock } from \"./iridescenceBlock.pure\";\r\nimport { SubSurfaceBlock } from \"./subSurfaceBlock.pure\";\r\nimport { type RefractionBlock } from \"./refractionBlock.pure\";\r\nimport { type PerturbNormalBlock } from \"../Fragment/perturbNormalBlock.pure\";\r\nimport { Constants } from \"../../../../Engines/constants\";\r\nimport { Color3 } from \"../../../../Maths/math.color.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport {\r\n    BindLight,\r\n    BindLights,\r\n    PrepareDefinesForLight,\r\n    PrepareDefinesForLights,\r\n    PrepareDefinesForMultiview,\r\n    PrepareUniformsAndSamplersForLight,\r\n} from \"../../../materialHelper.functions\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\nconst MapOutputToVariable: { [name: string]: [string, string] } = {\r\n    ambientClr: [\"finalAmbient\", \"\"],\r\n    diffuseDir: [\"finalDiffuse\", \"\"],\r\n    specularDir: [\"finalSpecularScaled\", \"!defined(UNLIT) && defined(SPECULARTERM)\"],\r\n    clearcoatDir: [\"finalClearCoatScaled\", \"!defined(UNLIT) && defined(CLEARCOAT)\"],\r\n    sheenDir: [\"finalSheenScaled\", \"!defined(UNLIT) && defined(SHEEN)\"],\r\n    diffuseInd: [\"finalIrradiance\", \"!defined(UNLIT) && defined(REFLECTION)\"],\r\n    specularInd: [\"finalRadianceScaled\", \"!defined(UNLIT) && defined(REFLECTION)\"],\r\n    clearcoatInd: [\"clearcoatOut.finalClearCoatRadianceScaled\", \"!defined(UNLIT) && defined(REFLECTION) && defined(CLEARCOAT)\"],\r\n    sheenInd: [\"sheenOut.finalSheenRadianceScaled\", \"!defined(UNLIT) && defined(REFLECTION) && defined(SHEEN) && defined(ENVIRONMENTBRDF)\"],\r\n    refraction: [\"subSurfaceOut.finalRefraction\", \"!defined(UNLIT) && defined(SS_REFRACTION)\"],\r\n    lighting: [\"finalColor.rgb\", \"\"],\r\n    shadow: [\"aggShadow\", \"\"],\r\n    alpha: [\"alpha\", \"\"],\r\n};\r\n\r\n/**\r\n * Block used to implement the PBR metallic/roughness model\r\n * @see https://playground.babylonjs.com/#D8AK3Z#80\r\n */\r\nexport class PBRMetallicRoughnessBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the light associated with this block\r\n     */\r\n    public light: Nullable<Light>;\r\n\r\n    private static _OnGenerateOnlyFragmentCodeChanged(block: NodeMaterialBlock, _propertyName: string): boolean {\r\n        const that = block as PBRMetallicRoughnessBlock;\r\n\r\n        if (that.worldPosition.isConnected || that.worldNormal.isConnected) {\r\n            that.generateOnlyFragmentCode = !that.generateOnlyFragmentCode;\r\n            Logger.Error(\"The worldPosition and worldNormal inputs must not be connected to be able to switch!\");\r\n            return false;\r\n        }\r\n\r\n        that._setTarget();\r\n\r\n        return true;\r\n    }\r\n\r\n    private _setTarget(): void {\r\n        this._setInitialTarget(this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.VertexAndFragment);\r\n        this.getInputByName(\"worldPosition\")!.target = this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.Vertex;\r\n        this.getInputByName(\"worldNormal\")!.target = this.generateOnlyFragmentCode ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.Vertex;\r\n    }\r\n\r\n    private _lightId: number;\r\n    private _scene: Scene;\r\n    private _environmentBRDFTexture: Nullable<BaseTexture> = null;\r\n    private _environmentBrdfSamplerName: string;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _vNormalWName: string;\r\n    private _invertNormalName: string;\r\n    private _metallicReflectanceColor: Color3 = Color3.White();\r\n    private _metallicF0Factor = 1;\r\n    private _vMetallicReflectanceFactorsName: string;\r\n    private _baseDiffuseRoughnessName: string;\r\n\r\n    /**\r\n     * Create a new ReflectionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.VertexAndFragment);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"worldPosition\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"worldNormal\", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);\r\n        this.registerInput(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix, false);\r\n        this.registerInput(\"cameraPosition\", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"perturbedNormal\", NodeMaterialBlockConnectionPointTypes.Vector4, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"baseColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"metallic\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"roughness\", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"ambientOcc\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"opacity\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"indexOfRefraction\", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\"ambientColor\", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);\r\n        this.registerInput(\r\n            \"reflection\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"reflection\", this, NodeMaterialConnectionPointDirection.Input, ReflectionBlock, \"ReflectionBlock\")\r\n        );\r\n        this.registerInput(\r\n            \"clearcoat\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"clearcoat\", this, NodeMaterialConnectionPointDirection.Input, ClearCoatBlock, \"ClearCoatBlock\")\r\n        );\r\n        this.registerInput(\r\n            \"sheen\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"sheen\", this, NodeMaterialConnectionPointDirection.Input, SheenBlock, \"SheenBlock\")\r\n        );\r\n        this.registerInput(\r\n            \"subsurface\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"subsurface\", this, NodeMaterialConnectionPointDirection.Input, SubSurfaceBlock, \"SubSurfaceBlock\")\r\n        );\r\n        this.registerInput(\r\n            \"anisotropy\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"anisotropy\", this, NodeMaterialConnectionPointDirection.Input, AnisotropyBlock, \"AnisotropyBlock\")\r\n        );\r\n        this.registerInput(\r\n            \"iridescence\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.Fragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"iridescence\", this, NodeMaterialConnectionPointDirection.Input, IridescenceBlock, \"IridescenceBlock\")\r\n        );\r\n\r\n        this.registerOutput(\"ambientClr\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"diffuseDir\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"specularDir\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"clearcoatDir\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"sheenDir\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"diffuseInd\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"specularInd\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"clearcoatInd\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"sheenInd\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"refraction\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"lighting\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"shadow\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\"alpha\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n    }\r\n\r\n    /**\r\n     * Intensity of the direct lights e.g. the four lights available in your scene.\r\n     * This impacts both the direct diffuse and specular highlights.\r\n     */\r\n    @editableInPropertyPage(\"Direct lights\", PropertyTypeForEdition.Float, \"INTENSITY\", { min: 0, max: 1, notifiers: { update: true } })\r\n    public directIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Intensity of the environment e.g. how much the environment will light the object\r\n     * either through harmonics for rough material or through the reflection for shiny ones.\r\n     */\r\n    @editableInPropertyPage(\"Environment lights\", PropertyTypeForEdition.Float, \"INTENSITY\", { min: 0, max: 1, notifiers: { update: true } })\r\n    public environmentIntensity: number = 1.0;\r\n\r\n    /**\r\n     * This is a special control allowing the reduction of the specular highlights coming from the\r\n     * four lights of the scene. Those highlights may not be needed in full environment lighting.\r\n     */\r\n    @editableInPropertyPage(\"Specular highlights\", PropertyTypeForEdition.Float, \"INTENSITY\", { min: 0, max: 1, notifiers: { update: true } })\r\n    public specularIntensity: number = 1.0;\r\n\r\n    /**\r\n     * Defines the  falloff type used in this material.\r\n     * It by default is Physical.\r\n     */\r\n    @editableInPropertyPage(\"Light falloff\", PropertyTypeForEdition.List, \"LIGHTING & COLORS\", {\r\n        notifiers: { update: true },\r\n        options: [\r\n            { label: \"Physical\", value: PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL },\r\n            { label: \"GLTF\", value: PBRBaseMaterial.LIGHTFALLOFF_GLTF },\r\n            { label: \"Standard\", value: PBRBaseMaterial.LIGHTFALLOFF_STANDARD },\r\n        ],\r\n    })\r\n    public lightFalloff = 0;\r\n\r\n    /**\r\n     * Specifies that alpha test should be used\r\n     */\r\n    @editableInPropertyPage(\"Alpha Testing\", PropertyTypeForEdition.Boolean, \"OPACITY\")\r\n    public useAlphaTest: boolean = false;\r\n\r\n    /**\r\n     * Defines the alpha limits in alpha test mode.\r\n     */\r\n    @editableInPropertyPage(\"Alpha CutOff\", PropertyTypeForEdition.Float, \"OPACITY\", { min: 0, max: 1, notifiers: { update: true } })\r\n    public alphaTestCutoff: number = 0.5;\r\n\r\n    /**\r\n     * Specifies that alpha blending should be used\r\n     */\r\n    @editableInPropertyPage(\"Alpha blending\", PropertyTypeForEdition.Boolean, \"OPACITY\")\r\n    public useAlphaBlending: boolean = false;\r\n\r\n    /**\r\n     * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good example of that. When the street lights reflects on it you can not see what is behind.\r\n     */\r\n    @editableInPropertyPage(\"Radiance over alpha\", PropertyTypeForEdition.Boolean, \"RENDERING\", { notifiers: { update: true } })\r\n    public useRadianceOverAlpha: boolean = true;\r\n\r\n    /**\r\n     * Specifies that the material will keeps the specular highlights over a transparent surface (only the most luminous ones).\r\n     * A car glass is a good example of that. When sun reflects on it you can not see what is behind.\r\n     */\r\n    @editableInPropertyPage(\"Specular over alpha\", PropertyTypeForEdition.Boolean, \"RENDERING\", { notifiers: { update: true } })\r\n    public useSpecularOverAlpha: boolean = true;\r\n\r\n    /**\r\n     * Enables specular anti aliasing in the PBR shader.\r\n     * It will both interacts on the Geometry for analytical and IBL lighting.\r\n     * It also prefilter the roughness map based on the bump values.\r\n     */\r\n    @editableInPropertyPage(\"Specular anti-aliasing\", PropertyTypeForEdition.Boolean, \"RENDERING\", { notifiers: { update: true } })\r\n    public enableSpecularAntiAliasing: boolean = false;\r\n\r\n    /**\r\n     * Enables realtime filtering on the texture.\r\n     */\r\n    @editableInPropertyPage(\"Realtime filtering\", PropertyTypeForEdition.Boolean, \"RENDERING\", { notifiers: { update: true } })\r\n    public realTimeFiltering: boolean = false;\r\n\r\n    /**\r\n     * Quality switch for realtime filtering\r\n     */\r\n    @editableInPropertyPage(\"Realtime filtering quality\", PropertyTypeForEdition.List, \"RENDERING\", {\r\n        notifiers: { update: true },\r\n        options: [\r\n            { label: \"Low\", value: Constants.TEXTURE_FILTERING_QUALITY_LOW },\r\n            { label: \"Medium\", value: Constants.TEXTURE_FILTERING_QUALITY_MEDIUM },\r\n            { label: \"High\", value: Constants.TEXTURE_FILTERING_QUALITY_HIGH },\r\n        ],\r\n    })\r\n    public realTimeFilteringQuality = Constants.TEXTURE_FILTERING_QUALITY_LOW;\r\n\r\n    /**\r\n     * Base Diffuse Model\r\n     */\r\n    @editableInPropertyPage(\"Diffuse Model\", PropertyTypeForEdition.List, \"RENDERING\", {\r\n        notifiers: { update: true },\r\n        options: [\r\n            { label: \"Lambert\", value: Constants.MATERIAL_DIFFUSE_MODEL_LAMBERT },\r\n            { label: \"Burley\", value: Constants.MATERIAL_DIFFUSE_MODEL_BURLEY },\r\n            { label: \"Oren-Nayar\", value: Constants.MATERIAL_DIFFUSE_MODEL_E_OREN_NAYAR },\r\n            { label: \"Legacy\", value: Constants.MATERIAL_DIFFUSE_MODEL_LEGACY },\r\n        ],\r\n    })\r\n    public baseDiffuseModel = Constants.MATERIAL_DIFFUSE_MODEL_E_OREN_NAYAR;\r\n\r\n    /**\r\n     * Defines if the material uses energy conservation.\r\n     */\r\n    @editableInPropertyPage(\"Energy Conservation\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { update: true } })\r\n    public useEnergyConservation: boolean = true;\r\n\r\n    /**\r\n     * This parameters will enable/disable radiance occlusion by preventing the radiance to lit\r\n     * too much the area relying on ambient texture to define their ambient occlusion.\r\n     */\r\n    @editableInPropertyPage(\"Radiance occlusion\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { update: true } })\r\n    public useRadianceOcclusion: boolean = true;\r\n\r\n    /**\r\n     * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal\r\n     * makes the reflect vector face the model (under horizon).\r\n     */\r\n    @editableInPropertyPage(\"Horizon occlusion\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { update: true } })\r\n    public useHorizonOcclusion: boolean = true;\r\n\r\n    /**\r\n     * If set to true, no lighting calculations will be applied.\r\n     */\r\n    @editableInPropertyPage(\"Unlit\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { update: true } })\r\n    public unlit: boolean = false;\r\n\r\n    /**\r\n     * Force normal to face away from face.\r\n     */\r\n    @editableInPropertyPage(\"Force normal forward\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { update: true } })\r\n    public forceNormalForward: boolean = false;\r\n\r\n    /** Indicates that no code should be generated in the vertex shader. Can be useful in some specific circumstances (like when doing ray marching for eg) */\r\n    @editableInPropertyPage(\"Generate only fragment code\", PropertyTypeForEdition.Boolean, \"ADVANCED\", {\r\n        notifiers: { rebuild: true, update: true, onValidation: (block, prop) => PBRMetallicRoughnessBlock._OnGenerateOnlyFragmentCodeChanged(block, prop) },\r\n    })\r\n    public generateOnlyFragmentCode = false;\r\n\r\n    /**\r\n     * Defines the material debug mode.\r\n     * It helps seeing only some components of the material while troubleshooting.\r\n     */\r\n    @editableInPropertyPage(\"Debug mode\", PropertyTypeForEdition.List, \"DEBUG\", {\r\n        notifiers: { update: true },\r\n        options: [\r\n            { label: \"None\", value: 0 },\r\n            // Geometry\r\n            { label: \"Normalized position\", value: 1 },\r\n            { label: \"Normals\", value: 2 },\r\n            { label: \"Tangents\", value: 3 },\r\n            { label: \"Bitangents\", value: 4 },\r\n            { label: \"Bump Normals\", value: 5 },\r\n            //{ label: \"UV1\", value: 6 },\r\n            //{ label: \"UV2\", value: 7 },\r\n            { label: \"ClearCoat Normals\", value: 8 },\r\n            { label: \"ClearCoat Tangents\", value: 9 },\r\n            { label: \"ClearCoat Bitangents\", value: 10 },\r\n            { label: \"Anisotropic Normals\", value: 11 },\r\n            { label: \"Anisotropic Tangents\", value: 12 },\r\n            { label: \"Anisotropic Bitangents\", value: 13 },\r\n            // Maps\r\n            //{ label: \"Emissive Map\", value: 23 },\r\n            //{ label: \"Light Map\", value: 24 },\r\n            // Env\r\n            { label: \"Env Refraction\", value: 40 },\r\n            { label: \"Env Reflection\", value: 41 },\r\n            { label: \"Env Clear Coat\", value: 42 },\r\n            // Lighting\r\n            { label: \"Direct Diffuse\", value: 50 },\r\n            { label: \"Direct Specular\", value: 51 },\r\n            { label: \"Direct Clear Coat\", value: 52 },\r\n            { label: \"Direct Sheen\", value: 53 },\r\n            { label: \"Env Irradiance\", value: 54 },\r\n            // Lighting Params\r\n            { label: \"Surface Albedo\", value: 60 },\r\n            { label: \"Reflectance 0\", value: 61 },\r\n            { label: \"Metallic\", value: 62 },\r\n            { label: \"Metallic F0\", value: 71 },\r\n            { label: \"Roughness\", value: 63 },\r\n            { label: \"AlphaG\", value: 64 },\r\n            { label: \"NdotV\", value: 65 },\r\n            { label: \"ClearCoat Color\", value: 66 },\r\n            { label: \"ClearCoat Roughness\", value: 67 },\r\n            { label: \"ClearCoat NdotV\", value: 68 },\r\n            { label: \"Transmittance\", value: 69 },\r\n            { label: \"Refraction Transmittance\", value: 70 },\r\n            // Misc\r\n            { label: \"SEO\", value: 80 },\r\n            { label: \"EHO\", value: 81 },\r\n            { label: \"Energy Factor\", value: 82 },\r\n            { label: \"Specular Reflectance\", value: 83 },\r\n            { label: \"Clear Coat Reflectance\", value: 84 },\r\n            { label: \"Sheen Reflectance\", value: 85 },\r\n            { label: \"Luminance Over Alpha\", value: 86 },\r\n            { label: \"Alpha\", value: 87 },\r\n            { label: \"Albedo color\", value: 88 },\r\n            { label: \"Ambient occlusion color\", value: 89 },\r\n        ],\r\n    })\r\n    public debugMode = 0;\r\n\r\n    /**\r\n     * Specify from where on screen the debug mode should start.\r\n     * The value goes from -1 (full screen) to 1 (not visible)\r\n     * It helps with side by side comparison against the final render\r\n     * This defaults to 0\r\n     */\r\n    @editableInPropertyPage(\"Split position\", PropertyTypeForEdition.Float, \"DEBUG\", { min: -1, max: 1, notifiers: { update: true } })\r\n    public debugLimit = 0;\r\n\r\n    /**\r\n     * As the default viewing range might not be enough (if the ambient is really small for instance)\r\n     * You can use the factor to better multiply the final value.\r\n     */\r\n    @editableInPropertyPage(\"Output factor\", PropertyTypeForEdition.Float, \"DEBUG\", { min: 0, max: 5, notifiers: { update: true } })\r\n    public debugFactor = 1;\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        state._excludeVariableName(\"vLightingIntensity\");\r\n\r\n        state._excludeVariableName(\"geometricNormalW\");\r\n        state._excludeVariableName(\"normalW\");\r\n        state._excludeVariableName(\"faceNormal\");\r\n\r\n        state._excludeVariableName(\"albedoOpacityOut\");\r\n        state._excludeVariableName(\"surfaceAlbedo\");\r\n        state._excludeVariableName(\"alpha\");\r\n\r\n        state._excludeVariableName(\"aoOut\");\r\n\r\n        state._excludeVariableName(\"baseColor\");\r\n        state._excludeVariableName(\"reflectivityOut\");\r\n        state._excludeVariableName(\"microSurface\");\r\n        state._excludeVariableName(\"roughness\");\r\n        state._excludeVariableName(\"vReflectivityColor\");\r\n\r\n        state._excludeVariableName(\"NdotVUnclamped\");\r\n        state._excludeVariableName(\"NdotV\");\r\n        state._excludeVariableName(\"alphaG\");\r\n        state._excludeVariableName(\"AARoughnessFactors\");\r\n        state._excludeVariableName(\"environmentBrdf\");\r\n        state._excludeVariableName(\"ambientMonochrome\");\r\n        state._excludeVariableName(\"seo\");\r\n        state._excludeVariableName(\"eho\");\r\n\r\n        state._excludeVariableName(\"environmentRadiance\");\r\n        state._excludeVariableName(\"irradianceVector\");\r\n        state._excludeVariableName(\"environmentIrradiance\");\r\n\r\n        state._excludeVariableName(\"diffuseBase\");\r\n        state._excludeVariableName(\"specularBase\");\r\n        state._excludeVariableName(\"preInfo\");\r\n        state._excludeVariableName(\"info\");\r\n        state._excludeVariableName(\"shadow\");\r\n\r\n        state._excludeVariableName(\"finalDiffuse\");\r\n        state._excludeVariableName(\"finalAmbient\");\r\n        state._excludeVariableName(\"ambientOcclusionForDirectDiffuse\");\r\n\r\n        state._excludeVariableName(\"finalColor\");\r\n\r\n        state._excludeVariableName(\"vClipSpacePosition\");\r\n        state._excludeVariableName(\"vDebugMode\");\r\n        state._excludeVariableName(\"vViewDepth\");\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await Promise.all([import(\"../../../../ShadersWGSL/pbr.vertex\"), import(\"../../../../ShadersWGSL/pbr.fragment\")]);\r\n        } else {\r\n            await Promise.all([import(\"../../../../Shaders/pbr.vertex\"), import(\"../../../../Shaders/pbr.fragment\")]);\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PBRMetallicRoughnessBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the world position input component\r\n     */\r\n    public get worldPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the world normal input component\r\n     */\r\n    public get worldNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the view matrix parameter\r\n     */\r\n    public get view(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the camera position input component\r\n     */\r\n    public get cameraPosition(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the perturbed normal input component\r\n     */\r\n    public get perturbedNormal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the base color input component\r\n     */\r\n    public get baseColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the metallic input component\r\n     */\r\n    public get metallic(): NodeMaterialConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the roughness input component\r\n     */\r\n    public get roughness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the ambient occlusion input component\r\n     */\r\n    public get ambientOcc(): NodeMaterialConnectionPoint {\r\n        return this._inputs[8];\r\n    }\r\n\r\n    /**\r\n     * Gets the opacity input component\r\n     */\r\n    public get opacity(): NodeMaterialConnectionPoint {\r\n        return this._inputs[9];\r\n    }\r\n\r\n    /**\r\n     * Gets the index of refraction input component\r\n     */\r\n    public get indexOfRefraction(): NodeMaterialConnectionPoint {\r\n        return this._inputs[10];\r\n    }\r\n\r\n    /**\r\n     * Gets the ambient color input component\r\n     */\r\n    public get ambientColor(): NodeMaterialConnectionPoint {\r\n        return this._inputs[11];\r\n    }\r\n\r\n    /**\r\n     * Gets the reflection object parameters\r\n     */\r\n    public get reflection(): NodeMaterialConnectionPoint {\r\n        return this._inputs[12];\r\n    }\r\n\r\n    /**\r\n     * Gets the clear coat object parameters\r\n     */\r\n    public get clearcoat(): NodeMaterialConnectionPoint {\r\n        return this._inputs[13];\r\n    }\r\n\r\n    /**\r\n     * Gets the sheen object parameters\r\n     */\r\n    public get sheen(): NodeMaterialConnectionPoint {\r\n        return this._inputs[14];\r\n    }\r\n\r\n    /**\r\n     * Gets the sub surface object parameters\r\n     */\r\n    public get subsurface(): NodeMaterialConnectionPoint {\r\n        return this._inputs[15];\r\n    }\r\n\r\n    /**\r\n     * Gets the anisotropy object parameters\r\n     */\r\n    public get anisotropy(): NodeMaterialConnectionPoint {\r\n        return this._inputs[16];\r\n    }\r\n\r\n    /**\r\n     * Gets the iridescence object parameters\r\n     */\r\n    public get iridescence(): NodeMaterialConnectionPoint {\r\n        return this._inputs[17];\r\n    }\r\n\r\n    /**\r\n     * Gets the ambient output component\r\n     */\r\n    public get ambientClr(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the diffuse output component\r\n     */\r\n    public get diffuseDir(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the specular output component\r\n     */\r\n    public get specularDir(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the clear coat output component\r\n     */\r\n    public get clearcoatDir(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the sheen output component\r\n     */\r\n    public get sheenDir(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the indirect diffuse output component\r\n     */\r\n    public get diffuseInd(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the indirect specular output component\r\n     */\r\n    public get specularInd(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the indirect clear coat output component\r\n     */\r\n    public get clearcoatInd(): NodeMaterialConnectionPoint {\r\n        return this._outputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the indirect sheen output component\r\n     */\r\n    public get sheenInd(): NodeMaterialConnectionPoint {\r\n        return this._outputs[8];\r\n    }\r\n\r\n    /**\r\n     * Gets the refraction output component\r\n     */\r\n    public get refraction(): NodeMaterialConnectionPoint {\r\n        return this._outputs[9];\r\n    }\r\n\r\n    /**\r\n     * Gets the global lighting output component\r\n     */\r\n    public get lighting(): NodeMaterialConnectionPoint {\r\n        return this._outputs[10];\r\n    }\r\n\r\n    /**\r\n     * Gets the shadow output component\r\n     */\r\n    public get shadow(): NodeMaterialConnectionPoint {\r\n        return this._outputs[11];\r\n    }\r\n\r\n    /**\r\n     * Gets the alpha output component\r\n     */\r\n    public get alpha(): NodeMaterialConnectionPoint {\r\n        return this._outputs[12];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.cameraPosition.isConnected) {\r\n            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.CameraPosition && additionalFilteringInfo(b));\r\n\r\n            if (!cameraPositionInput) {\r\n                cameraPositionInput = new InputBlock(\"cameraPosition\");\r\n                cameraPositionInput.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);\r\n            }\r\n            cameraPositionInput.output.connectTo(this.cameraPosition);\r\n        }\r\n\r\n        if (!this.view.isConnected) {\r\n            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View && additionalFilteringInfo(b));\r\n\r\n            if (!viewInput) {\r\n                viewInput = new InputBlock(\"view\");\r\n                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);\r\n            }\r\n            viewInput.output.connectTo(this.view);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Prepare the list of defines\r\n     * @param defines - the list of defines to update\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to prepare defines for\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines, nodeMaterial: NodeMaterial, mesh?: AbstractMesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        // General\r\n        defines.setValue(\"PBR\", true);\r\n        defines.setValue(\"METALLICWORKFLOW\", true);\r\n        defines.setValue(\"DEBUGMODE\", this.debugMode, true);\r\n        defines.setValue(\"DEBUGMODE_FORCERETURN\", true);\r\n        defines.setValue(\"NORMALXYSCALE\", true);\r\n        defines.setValue(\"BUMP\", this.perturbedNormal.isConnected, true);\r\n        defines.setValue(\"LODBASEDMICROSFURACE\", this._scene.getEngine().getCaps().textureLOD);\r\n\r\n        // Albedo & Opacity\r\n        defines.setValue(\"ALBEDO\", false, true);\r\n        defines.setValue(\"OPACITY\", this.opacity.isConnected, true);\r\n\r\n        // Ambient occlusion\r\n        defines.setValue(\"AMBIENT\", true, true);\r\n        defines.setValue(\"AMBIENTINGRAYSCALE\", false, true);\r\n\r\n        // Reflectivity\r\n        defines.setValue(\"REFLECTIVITY\", false, true);\r\n        defines.setValue(\"AOSTOREINMETALMAPRED\", false, true);\r\n        defines.setValue(\"METALLNESSSTOREINMETALMAPBLUE\", false, true);\r\n        defines.setValue(\"ROUGHNESSSTOREINMETALMAPALPHA\", false, true);\r\n        defines.setValue(\"ROUGHNESSSTOREINMETALMAPGREEN\", false, true);\r\n\r\n        // Lighting & colors\r\n        if (this.lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_STANDARD) {\r\n            defines.setValue(\"USEPHYSICALLIGHTFALLOFF\", false);\r\n            defines.setValue(\"USEGLTFLIGHTFALLOFF\", false);\r\n        } else if (this.lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_GLTF) {\r\n            defines.setValue(\"USEPHYSICALLIGHTFALLOFF\", false);\r\n            defines.setValue(\"USEGLTFLIGHTFALLOFF\", true);\r\n        } else {\r\n            defines.setValue(\"USEPHYSICALLIGHTFALLOFF\", true);\r\n            defines.setValue(\"USEGLTFLIGHTFALLOFF\", false);\r\n        }\r\n\r\n        // Transparency\r\n        const alphaTestCutOffString = this.alphaTestCutoff.toString();\r\n\r\n        defines.setValue(\"ALPHABLEND\", this.useAlphaBlending, true);\r\n        defines.setValue(\"ALPHAFROMALBEDO\", false, true);\r\n        defines.setValue(\"ALPHATEST\", this.useAlphaTest, true);\r\n        defines.setValue(\"ALPHATESTVALUE\", alphaTestCutOffString.indexOf(\".\") < 0 ? alphaTestCutOffString + \".\" : alphaTestCutOffString, true);\r\n        defines.setValue(\"OPACITYRGB\", false, true);\r\n\r\n        // Rendering\r\n        defines.setValue(\"RADIANCEOVERALPHA\", this.useRadianceOverAlpha, true);\r\n        defines.setValue(\"SPECULAROVERALPHA\", this.useSpecularOverAlpha, true);\r\n        defines.setValue(\"SPECULARAA\", this._scene.getEngine().getCaps().standardDerivatives && this.enableSpecularAntiAliasing, true);\r\n        defines.setValue(\"REALTIME_FILTERING\", this.realTimeFiltering, true);\r\n\r\n        const scene = mesh.getScene();\r\n        const engine = scene.getEngine();\r\n\r\n        if (engine._features.needTypeSuffixInShaderConstants) {\r\n            defines.setValue(\"NUM_SAMPLES\", this.realTimeFilteringQuality + \"u\", true);\r\n        } else {\r\n            defines.setValue(\"NUM_SAMPLES\", \"\" + this.realTimeFilteringQuality, true);\r\n        }\r\n\r\n        defines.setValue(\"BASE_DIFFUSE_MODEL\", this.baseDiffuseModel, true);\r\n\r\n        // Advanced\r\n        defines.setValue(\"BRDF_V_HEIGHT_CORRELATED\", true);\r\n        defines.setValue(\"LEGACY_SPECULAR_ENERGY_CONSERVATION\", true);\r\n        defines.setValue(\"MS_BRDF_ENERGY_CONSERVATION\", this.useEnergyConservation, true);\r\n        defines.setValue(\"RADIANCEOCCLUSION\", this.useRadianceOcclusion, true);\r\n        defines.setValue(\"HORIZONOCCLUSION\", this.useHorizonOcclusion, true);\r\n        defines.setValue(\"UNLIT\", this.unlit, true);\r\n        defines.setValue(\"FORCENORMALFORWARD\", this.forceNormalForward, true);\r\n\r\n        if (this._environmentBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {\r\n            defines.setValue(\"ENVIRONMENTBRDF\", true);\r\n            defines.setValue(\"ENVIRONMENTBRDF_RGBD\", this._environmentBRDFTexture.isRGBD, true);\r\n        } else {\r\n            defines.setValue(\"ENVIRONMENTBRDF\", false);\r\n            defines.setValue(\"ENVIRONMENTBRDF_RGBD\", false);\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {\r\n            nodeMaterial.imageProcessingConfiguration.prepareDefines(defines);\r\n        }\r\n\r\n        if (!defines._areLightsDirty) {\r\n            return;\r\n        }\r\n\r\n        if (!this.light) {\r\n            // Lights\r\n            PrepareDefinesForLights(scene, mesh, defines, true, nodeMaterial.maxSimultaneousLights);\r\n            defines._needNormals = true;\r\n\r\n            // Multiview\r\n            PrepareDefinesForMultiview(scene, defines);\r\n        } else {\r\n            const state = {\r\n                needNormals: false,\r\n                needRebuild: false,\r\n                lightmapMode: false,\r\n                shadowEnabled: false,\r\n                specularEnabled: false,\r\n            };\r\n\r\n            PrepareDefinesForLight(scene, mesh, this.light, this._lightId, defines, true, state);\r\n\r\n            if (state.needRebuild) {\r\n                defines.rebuild();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the uniforms and samples\r\n     * @param state - the build state\r\n     * @param nodeMaterial - the node material\r\n     * @param defines - the list of defines\r\n     * @param uniformBuffers - the uniform buffers\r\n     */\r\n    public override updateUniformsAndSamples(state: NodeMaterialBuildState, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, uniformBuffers: string[]) {\r\n        for (let lightIndex = 0; lightIndex < nodeMaterial.maxSimultaneousLights; lightIndex++) {\r\n            if (!defines[\"LIGHT\" + lightIndex]) {\r\n                break;\r\n            }\r\n            const onlyUpdateBuffersList = state.uniforms.indexOf(\"vLightData\" + lightIndex) >= 0;\r\n            PrepareUniformsAndSamplersForLight(\r\n                lightIndex,\r\n                state.uniforms,\r\n                state.samplers,\r\n                defines[\"PROJECTEDLIGHTTEXTURE\" + lightIndex],\r\n                uniformBuffers,\r\n                onlyUpdateBuffersList,\r\n                defines[\"IESLIGHTTEXTURE\" + lightIndex],\r\n                defines[\"CLUSTLIGHT\" + lightIndex],\r\n                defines[\"RECTAREALIGHTEMISSIONTEXTURE\" + lightIndex],\r\n                state.shaderLanguage === ShaderLanguage.WGSL\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @param mesh - the mesh to check\r\n     * @param nodeMaterial - the node material\r\n     * @param defines - the list of defines\r\n     * @returns true if ready\r\n     */\r\n    public override isReady(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {\r\n        if (this._environmentBRDFTexture && !this._environmentBRDFTexture.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {\r\n            if (!nodeMaterial.imageProcessingConfiguration.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (this.light && !this.light.areLightTexturesReady()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Bind data to effect\r\n     * @param effect - the effect to bind data to\r\n     * @param nodeMaterial - the node material\r\n     * @param mesh - the mesh to bind data for\r\n     */\r\n    public override bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n\r\n        if (!this.light) {\r\n            BindLights(scene, mesh, effect, true, nodeMaterial.maxSimultaneousLights);\r\n        } else {\r\n            BindLight(this.light, this._lightId, scene, effect, true);\r\n        }\r\n\r\n        effect.setTexture(this._environmentBrdfSamplerName, this._environmentBRDFTexture);\r\n\r\n        effect.setFloat2(\"vDebugMode\", this.debugLimit, this.debugFactor);\r\n\r\n        const ambientScene = this._scene.ambientColor;\r\n\r\n        if (ambientScene) {\r\n            effect.setColor3(\"ambientFromScene\", ambientScene);\r\n        }\r\n\r\n        const invertNormal = scene.useRightHandedSystem === (scene._mirroredCameraPosition != null);\r\n\r\n        effect.setFloat(this._invertNormalName, invertNormal ? -1 : 1);\r\n\r\n        effect.setFloat4(\"vLightingIntensity\", this.directIntensity, 1, this.environmentIntensity * this._scene.environmentIntensity, this.specularIntensity);\r\n\r\n        // reflectivity bindings\r\n        const metallicF90 = this._metallicF0Factor;\r\n\r\n        effect.setColor4(this._vMetallicReflectanceFactorsName, this._metallicReflectanceColor, metallicF90);\r\n\r\n        if (nodeMaterial.imageProcessingConfiguration) {\r\n            nodeMaterial.imageProcessingConfiguration.bind(effect);\r\n        }\r\n    }\r\n\r\n    private _injectVertexCode(state: NodeMaterialBuildState) {\r\n        const worldPos = this.worldPosition;\r\n        const worldNormal = this.worldNormal;\r\n        const comments = `//${this.name}`;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        const scene = state.sharedData.nodeMaterial.getScene();\r\n\r\n        // Declaration\r\n        if (!this.light) {\r\n            // Emit for all lights\r\n            state._emitFunctionFromInclude(state.supportUniformBuffers ? \"lightVxUboDeclaration\" : \"lightVxFragmentDeclaration\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n            });\r\n            this._lightId = 0;\r\n\r\n            state.sharedData.dynamicUniformBlocks.push(this);\r\n        } else {\r\n            this._lightId = (state.counters[\"lightCounter\"] !== undefined ? state.counters[\"lightCounter\"] : -1) + 1;\r\n            state.counters[\"lightCounter\"] = this._lightId;\r\n\r\n            state._emitFunctionFromInclude(\r\n                state.supportUniformBuffers ? \"lightVxUboDeclaration\" : \"lightVxFragmentDeclaration\",\r\n                comments,\r\n                {\r\n                    replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }],\r\n                },\r\n                this._lightId.toString()\r\n            );\r\n        }\r\n\r\n        // Inject code in vertex\r\n        const worldPosVaryingName = \"v_\" + worldPos.associatedVariableName;\r\n        if (state._emitVaryingFromString(worldPosVaryingName, NodeMaterialBlockConnectionPointTypes.Vector4)) {\r\n            state.compilationString += (isWebGPU ? \"vertexOutputs.\" : \"\") + `${worldPosVaryingName} = ${worldPos.associatedVariableName};\\n`;\r\n        }\r\n\r\n        const worldNormalVaryingName = \"v_\" + worldNormal.associatedVariableName;\r\n        if (state._emitVaryingFromString(worldNormalVaryingName, NodeMaterialBlockConnectionPointTypes.Vector4)) {\r\n            state.compilationString += (isWebGPU ? \"vertexOutputs.\" : \"\") + `${worldNormalVaryingName} = ${worldNormal.associatedVariableName};\\n`;\r\n        }\r\n\r\n        const reflectionBlock = this.reflection.isConnected ? (this.reflection.connectedPoint?.ownerBlock as ReflectionBlock) : null;\r\n\r\n        if (reflectionBlock) {\r\n            reflectionBlock.viewConnectionPoint = this.view;\r\n        }\r\n\r\n        state.compilationString += reflectionBlock?.handleVertexSide(state) ?? \"\";\r\n\r\n        if (state._emitVaryingFromString(\"vClipSpacePosition\", NodeMaterialBlockConnectionPointTypes.Vector4, \"defined(IGNORE) || DEBUGMODE > 0\")) {\r\n            state._injectAtEnd += `#if DEBUGMODE > 0\\n`;\r\n            state._injectAtEnd += (isWebGPU ? \"vertexOutputs.\" : \"\") + `vClipSpacePosition = ${isWebGPU ? \"vertexOutputs.position\" : \"gl_Position\"};\\n`;\r\n            state._injectAtEnd += `#endif\\n`;\r\n        }\r\n\r\n        if (this.light) {\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowsVertex\", comments, {\r\n                replaceStrings: [\r\n                    { search: /{X}/g, replace: this._lightId.toString() },\r\n                    { search: /worldPos/g, replace: worldPos.associatedVariableName },\r\n                ],\r\n            });\r\n        } else {\r\n            state.compilationString += `${state._declareLocalVar(\"worldPos\", NodeMaterialBlockConnectionPointTypes.Vector4)} = ${worldPos.associatedVariableName};\\n`;\r\n            if (this.view.isConnected) {\r\n                state.compilationString += `${state._declareLocalVar(\"view\", NodeMaterialBlockConnectionPointTypes.Matrix)} = ${this.view.associatedVariableName};\\n`;\r\n                state._emitVaryingFromString(\"vViewDepth\", NodeMaterialBlockConnectionPointTypes.Float);\r\n                state.compilationString +=\r\n                    (state.shaderLanguage === ShaderLanguage.WGSL ? \"vertexOutputs.\" : \"\") +\r\n                    `vViewDepth = ${scene.useRightHandedSystem ? \"-\" : \"\"}(${this.view.associatedVariableName} * ${worldPos.associatedVariableName}).z;\\n`;\r\n            }\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowsVertex\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n            });\r\n        }\r\n    }\r\n\r\n    private _getAlbedoOpacityCode(state: NodeMaterialBuildState): string {\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        let code = isWebGPU ? \"var albedoOpacityOut: albedoOpacityOutParams;\\n\" : `albedoOpacityOutParams albedoOpacityOut;\\n`;\r\n\r\n        const albedoColor = this.baseColor.isConnected ? this.baseColor.associatedVariableName : \"vec3(1.)\";\r\n        const opacity = this.opacity.isConnected ? this.opacity.associatedVariableName : \"1.\";\r\n\r\n        code += `albedoOpacityOut = albedoOpacityBlock(\r\n                vec4${state.fSuffix}(${albedoColor}, 1.)\r\n            #ifdef ALBEDO\r\n                ,vec4${state.fSuffix}(1.)\r\n                ,vec2${state.fSuffix}(1., 1.)\r\n            #endif\r\n                ,1. /* Base Weight */\r\n            #ifdef OPACITY\r\n                ,vec4${state.fSuffix}(${opacity})\r\n                ,vec2${state.fSuffix}(1., 1.)\r\n            #endif\r\n            );\r\n\r\n            ${state._declareLocalVar(\"surfaceAlbedo\", NodeMaterialBlockConnectionPointTypes.Vector3)} = albedoOpacityOut.surfaceAlbedo;\r\n            ${state._declareLocalVar(\"alpha\", NodeMaterialBlockConnectionPointTypes.Float)} = albedoOpacityOut.alpha;\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    private _getAmbientOcclusionCode(state: NodeMaterialBuildState): string {\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        let code = isWebGPU ? \"var aoOut: ambientOcclusionOutParams;\\n\" : `ambientOcclusionOutParams aoOut;\\n`;\r\n\r\n        const ao = this.ambientOcc.isConnected ? this.ambientOcc.associatedVariableName : \"1.\";\r\n\r\n        code += `aoOut = ambientOcclusionBlock(\r\n            #ifdef AMBIENT\r\n                vec3${state.fSuffix}(${ao}),\r\n                vec4${state.fSuffix}(0., 1.0, 1.0, 0.)\r\n            #endif\r\n            );\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    private _getReflectivityCode(state: NodeMaterialBuildState): string {\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n        let code = isWebGPU ? \"var reflectivityOut: reflectivityOutParams;\\n\" : `reflectivityOutParams reflectivityOut;\\n`;\r\n        const aoIntensity = \"1.\";\r\n\r\n        this._vMetallicReflectanceFactorsName = state._getFreeVariableName(\"vMetallicReflectanceFactors\");\r\n        state._emitUniformFromString(this._vMetallicReflectanceFactorsName, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        this._baseDiffuseRoughnessName = state._getFreeVariableName(\"baseDiffuseRoughness\");\r\n        state._emitUniformFromString(this._baseDiffuseRoughnessName, NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        const outsideIOR = 1; // consider air as clear coat and other layers would remap in the shader.\r\n        const ior = this.indexOfRefraction.connectInputBlock?.value ?? 1.5;\r\n        // Based of the schlick fresnel approximation model\r\n        // for dielectrics.\r\n        const f0 = Math.pow((ior - outsideIOR) / (ior + outsideIOR), 2);\r\n\r\n        code += `${state._declareLocalVar(\"baseColor\", NodeMaterialBlockConnectionPointTypes.Vector3)} = surfaceAlbedo;\r\n            ${isWebGPU ? \"let\" : `vec4${state.fSuffix}`} vReflectivityColor = vec4${state.fSuffix}(${this.metallic.associatedVariableName}, ${this.roughness.associatedVariableName}, ${this.indexOfRefraction.associatedVariableName || \"1.5\"}, ${f0});\r\n            reflectivityOut = reflectivityBlock(\r\n                vReflectivityColor\r\n            #ifdef METALLICWORKFLOW\r\n                , surfaceAlbedo\r\n                , ${(isWebGPU ? \"uniforms.\" : \"\") + this._vMetallicReflectanceFactorsName}\r\n            #endif\r\n                , ${(isWebGPU ? \"uniforms.\" : \"\") + this._baseDiffuseRoughnessName}\r\n            #ifdef BASE_DIFFUSE_ROUGHNESS\r\n                , 0.\r\n                , vec2${state.fSuffix}(0., 0.)\r\n            #endif\r\n            #ifdef REFLECTIVITY\r\n                , vec3${state.fSuffix}(0., 0., ${aoIntensity})\r\n                , vec4${state.fSuffix}(1.)\r\n            #endif\r\n            #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY)  && defined(AOSTOREINMETALMAPRED)\r\n                , aoOut.ambientOcclusionColor\r\n            #endif\r\n            #ifdef MICROSURFACEMAP\r\n                , microSurfaceTexel <== not handled!\r\n            #endif\r\n            );\r\n\r\n            ${state._declareLocalVar(\"microSurface\", NodeMaterialBlockConnectionPointTypes.Float)} = reflectivityOut.microSurface;\r\n            ${state._declareLocalVar(\"roughness\", NodeMaterialBlockConnectionPointTypes.Float)} = reflectivityOut.roughness;\r\n            ${state._declareLocalVar(\"diffuseRoughness\", NodeMaterialBlockConnectionPointTypes.Float)} = reflectivityOut.diffuseRoughness;\r\n\r\n            #ifdef METALLICWORKFLOW\r\n                surfaceAlbedo = reflectivityOut.surfaceAlbedo;\r\n            #endif\r\n            #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)\r\n                aoOut.ambientOcclusionColor = reflectivityOut.ambientOcclusionColor;\r\n            #endif\\n`;\r\n\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this._scene = state.sharedData.scene;\r\n        const isWebGPU = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        if (!this._environmentBRDFTexture) {\r\n            this._environmentBRDFTexture = GetEnvironmentBRDFTexture(this._scene);\r\n        }\r\n\r\n        const reflectionBlock = this.reflection.isConnected ? (this.reflection.connectedPoint?.ownerBlock as ReflectionBlock) : null;\r\n\r\n        if (reflectionBlock) {\r\n            // Need those variables to be setup when calling _injectVertexCode\r\n            reflectionBlock.worldPositionConnectionPoint = this.worldPosition;\r\n            reflectionBlock.cameraPositionConnectionPoint = this.cameraPosition;\r\n            reflectionBlock.worldNormalConnectionPoint = this.worldNormal;\r\n            reflectionBlock.viewConnectionPoint = this.view;\r\n        }\r\n\r\n        if (state.target !== NodeMaterialBlockTargets.Fragment) {\r\n            // Vertex\r\n            this._injectVertexCode(state);\r\n\r\n            return this;\r\n        }\r\n\r\n        // Fragment\r\n        state.sharedData.forcedBindableBlocks.push(this);\r\n        state.sharedData.blocksWithDefines.push(this);\r\n        state.sharedData.blockingBlocks.push(this);\r\n        if (this.generateOnlyFragmentCode) {\r\n            state.sharedData.dynamicUniformBlocks.push(this);\r\n        }\r\n\r\n        const comments = `//${this.name}`;\r\n        const normalShading = this.perturbedNormal;\r\n\r\n        let worldPosVarName = this.worldPosition.associatedVariableName;\r\n        let worldPosVarName4 = this.worldPosition.associatedVariableName;\r\n        let worldNormalVarName = this.worldNormal.associatedVariableName;\r\n        if (this.generateOnlyFragmentCode) {\r\n            worldPosVarName = state._getFreeVariableName(\"globalWorldPos\");\r\n            state._emitFunction(\"pbr_globalworldpos\", `${state._declareLocalVar(worldPosVarName, NodeMaterialBlockConnectionPointTypes.Vector3, false, true)};\\n`, comments);\r\n            state.compilationString += `${worldPosVarName} = ${this.worldPosition.associatedVariableName}.xyz;\\n`;\r\n\r\n            worldPosVarName4 = state._getFreeVariableName(\"globalWorldPos4\");\r\n            state._emitFunction(\"pbr_globalworldpos4\", `${state._declareLocalVar(worldPosVarName4, NodeMaterialBlockConnectionPointTypes.Vector4, false, true)};\\n`, comments);\r\n            state.compilationString += `${worldPosVarName4} = ${this.worldPosition.associatedVariableName};\\n`;\r\n\r\n            worldNormalVarName = state._getFreeVariableName(\"globalWorldNormal\");\r\n            state._emitFunction(\"pbr_globalworldnorm\", `${state._declareLocalVar(worldNormalVarName, NodeMaterialBlockConnectionPointTypes.Vector4, false, true)};\\n`, comments);\r\n            state.compilationString += `${worldNormalVarName} = ${this.worldNormal.associatedVariableName};\\n`;\r\n\r\n            state.compilationString += state._emitCodeFromInclude(\"shadowsVertex\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n                substitutionVars: `worldPos,${this.worldPosition.associatedVariableName}`,\r\n            });\r\n\r\n            state.compilationString += `#if DEBUGMODE > 0\\n`;\r\n            state.compilationString += `${state._declareLocalVar(\"vClipSpacePosition\", NodeMaterialBlockConnectionPointTypes.Vector4)} = vec4${state.fSuffix}((vec2${state.fSuffix}(${isWebGPU ? \"fragmentInputs.position\" : \"gl_FragCoord.xy\"}) / vec2${state.fSuffix}(1.0)) * 2.0 - 1.0, 0.0, 1.0);\\n`;\r\n            state.compilationString += `#endif\\n`;\r\n        } else {\r\n            worldPosVarName = (isWebGPU ? \"input.\" : \"\") + \"v_\" + worldPosVarName;\r\n            worldNormalVarName = (isWebGPU ? \"input.\" : \"\") + \"v_\" + worldNormalVarName;\r\n        }\r\n\r\n        this._environmentBrdfSamplerName = state._getFreeVariableName(\"environmentBrdfSampler\");\r\n\r\n        state._emit2DSampler(this._environmentBrdfSamplerName);\r\n\r\n        state.sharedData.hints.needAlphaBlending = state.sharedData.hints.needAlphaBlending || this.useAlphaBlending;\r\n        state.sharedData.hints.needAlphaTesting = state.sharedData.hints.needAlphaTesting || this.useAlphaTest;\r\n\r\n        state._emitExtension(\"lod\", \"#extension GL_EXT_shader_texture_lod : enable\", \"defined(LODBASEDMICROSFURACE)\");\r\n        state._emitExtension(\"derivatives\", \"#extension GL_OES_standard_derivatives : enable\");\r\n\r\n        state._emitUniformFromString(\"vDebugMode\", NodeMaterialBlockConnectionPointTypes.Vector2, \"defined(IGNORE) || DEBUGMODE > 0\");\r\n        state._emitUniformFromString(\"ambientFromScene\", NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        // Image processing uniforms\r\n        state.uniforms.push(\"whiteBalanceMatrix\");\r\n        state.uniforms.push(\"exposureLinear\");\r\n        state.uniforms.push(\"contrast\");\r\n        state.uniforms.push(\"vInverseScreenSize\");\r\n        state.uniforms.push(\"vignetteSettings1\");\r\n        state.uniforms.push(\"vignetteSettings2\");\r\n        state.uniforms.push(\"vCameraColorCurveNegative\");\r\n        state.uniforms.push(\"vCameraColorCurveNeutral\");\r\n        state.uniforms.push(\"vCameraColorCurvePositive\");\r\n        state.uniforms.push(\"txColorTransform\");\r\n        state.uniforms.push(\"colorTransformSettings\");\r\n        state.uniforms.push(\"ditherIntensity\");\r\n\r\n        //\r\n        // Includes\r\n        //\r\n        if (!this.light) {\r\n            if (this.generateOnlyFragmentCode && this.view.isConnected) {\r\n                state.compilationString += `${state._declareLocalVar(\"vViewDepth\", NodeMaterialBlockConnectionPointTypes.Float)} = (${this.view.associatedVariableName} * ${worldPosVarName4}).z;\\n`;\r\n            }\r\n\r\n            // Emit for all lights\r\n            state._emitFunctionFromInclude(state.supportUniformBuffers ? \"lightUboDeclaration\" : \"lightFragmentDeclaration\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n                substitutionVars: this.generateOnlyFragmentCode ? \"varying,\" : undefined,\r\n            });\r\n        } else {\r\n            state._emitFunctionFromInclude(\r\n                state.supportUniformBuffers ? \"lightUboDeclaration\" : \"lightFragmentDeclaration\",\r\n                comments,\r\n                {\r\n                    replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }],\r\n                },\r\n                this._lightId.toString()\r\n            );\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n        state._emitFunctionFromInclude(\"importanceSampling\", comments);\r\n        state._emitFunctionFromInclude(\"pbrHelperFunctions\", comments);\r\n        state._emitFunctionFromInclude(\"imageProcessingDeclaration\", comments);\r\n        state._emitFunctionFromInclude(\"imageProcessingFunctions\", comments);\r\n\r\n        state._emitFunctionFromInclude(\"shadowsFragmentFunctions\", comments);\r\n\r\n        state._emitFunctionFromInclude(\"pbrDirectLightingSetupFunctions\", comments);\r\n\r\n        state._emitFunctionFromInclude(\"pbrDirectLightingFalloffFunctions\", comments);\r\n        state._emitFunctionFromInclude(\"pbrBRDFFunctions\", comments, {\r\n            replaceStrings: [{ search: /REFLECTIONMAP_SKYBOX/g, replace: reflectionBlock?._defineSkyboxName ?? \"REFLECTIONMAP_SKYBOX\" }],\r\n        });\r\n        state._emitFunctionFromInclude(\"hdrFilteringFunctions\", comments);\r\n\r\n        if (!isWebGPU) {\r\n            state._emitFunctionFromInclude(\"pbrDirectLightingFunctions\", comments);\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"pbrIBLFunctions\", comments);\r\n\r\n        state._emitFunctionFromInclude(\"pbrBlockAlbedoOpacity\", comments);\r\n        state._emitFunctionFromInclude(\"pbrBlockReflectivity\", comments);\r\n        state._emitFunctionFromInclude(\"pbrBlockAmbientOcclusion\", comments);\r\n        state._emitFunctionFromInclude(\"pbrBlockAlphaFresnel\", comments);\r\n        state._emitFunctionFromInclude(\"pbrBlockAnisotropic\", comments);\r\n\r\n        //\r\n        // code\r\n        //\r\n\r\n        state._emitUniformFromString(\"vLightingIntensity\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        if (reflectionBlock?.generateOnlyFragmentCode) {\r\n            state.compilationString += reflectionBlock.handleVertexSide(state);\r\n        }\r\n\r\n        // _____________________________ Geometry Information ____________________________\r\n        this._vNormalWName = state._getFreeVariableName(\"vNormalW\");\r\n\r\n        state.compilationString += `${state._declareLocalVar(this._vNormalWName, NodeMaterialBlockConnectionPointTypes.Vector4)} = normalize(${worldNormalVarName});\\n`;\r\n\r\n        if (state._registerTempVariable(\"viewDirectionW\")) {\r\n            state.compilationString += `${state._declareLocalVar(\"viewDirectionW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = normalize(${this.cameraPosition.associatedVariableName} - ${worldPosVarName}.xyz);\\n`;\r\n        }\r\n\r\n        state.compilationString += `${state._declareLocalVar(\"geometricNormalW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this._vNormalWName}.xyz;\\n`;\r\n\r\n        state.compilationString += `${state._declareLocalVar(\"normalW\", NodeMaterialBlockConnectionPointTypes.Vector3)} = ${normalShading.isConnected ? \"normalize(\" + normalShading.associatedVariableName + \".xyz)\" : \"geometricNormalW\"};\\n`;\r\n\r\n        this._invertNormalName = state._getFreeVariableName(\"invertNormal\");\r\n\r\n        state._emitUniformFromString(this._invertNormalName, NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockNormalFinal\", comments, {\r\n            replaceStrings: [\r\n                { search: /vPositionW/g, replace: worldPosVarName + \".xyz\" },\r\n                { search: /vEyePosition.w/g, replace: this._invertNormalName },\r\n            ],\r\n        });\r\n\r\n        // _____________________________ Albedo & Opacity ______________________________\r\n        state.compilationString += this._getAlbedoOpacityCode(state);\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"depthPrePass\", comments);\r\n\r\n        // _____________________________ AO  _______________________________\r\n        state.compilationString += this._getAmbientOcclusionCode(state);\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockLightmapInit\", comments);\r\n\r\n        // _____________________________ UNLIT  _______________________________\r\n        state.compilationString += `#ifdef UNLIT\r\n                ${state._declareLocalVar(\"diffuseBase\", NodeMaterialBlockConnectionPointTypes.Vector3)} = vec3${state.fSuffix}(1., 1., 1.);\r\n            #else\\n`;\r\n\r\n        // _____________________________ Reflectivity _______________________________\r\n        state.compilationString += this._getReflectivityCode(state);\r\n\r\n        // _____________________________ Geometry info _________________________________\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockGeometryInfo\", comments, {\r\n            replaceStrings: [\r\n                { search: /REFLECTIONMAP_SKYBOX/g, replace: reflectionBlock?._defineSkyboxName ?? \"REFLECTIONMAP_SKYBOX\" },\r\n                { search: /REFLECTIONMAP_3D/g, replace: reflectionBlock?._define3DName ?? \"REFLECTIONMAP_3D\" },\r\n            ],\r\n        });\r\n\r\n        // _____________________________ Anisotropy _______________________________________\r\n        const anisotropyBlock = this.anisotropy.isConnected ? (this.anisotropy.connectedPoint?.ownerBlock as AnisotropyBlock) : null;\r\n\r\n        if (anisotropyBlock) {\r\n            anisotropyBlock.worldPositionConnectionPoint = this.worldPosition;\r\n            anisotropyBlock.worldNormalConnectionPoint = this.worldNormal;\r\n\r\n            state.compilationString += anisotropyBlock.getCode(state, !this.perturbedNormal.isConnected);\r\n        }\r\n\r\n        // _____________________________ Reflection _______________________________________\r\n        if (reflectionBlock && reflectionBlock.hasTexture) {\r\n            state.compilationString += reflectionBlock.getCode(state, anisotropyBlock ? \"anisotropicOut.anisotropicNormal\" : \"normalW\");\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"pbrBlockReflection\", comments, {\r\n            replaceStrings: [\r\n                { search: /computeReflectionCoords/g, replace: \"computeReflectionCoordsPBR\" },\r\n                { search: /REFLECTIONMAP_3D/g, replace: reflectionBlock?._define3DName ?? \"REFLECTIONMAP_3D\" },\r\n                { search: /REFLECTIONMAP_OPPOSITEZ/g, replace: reflectionBlock?._defineOppositeZ ?? \"REFLECTIONMAP_OPPOSITEZ\" },\r\n                { search: /REFLECTIONMAP_PROJECTION/g, replace: reflectionBlock?._defineProjectionName ?? \"REFLECTIONMAP_PROJECTION\" },\r\n                { search: /REFLECTIONMAP_SKYBOX/g, replace: reflectionBlock?._defineSkyboxName ?? \"REFLECTIONMAP_SKYBOX\" },\r\n                { search: /LODINREFLECTIONALPHA/g, replace: reflectionBlock?._defineLODReflectionAlpha ?? \"LODINREFLECTIONALPHA\" },\r\n                { search: /LINEARSPECULARREFLECTION/g, replace: reflectionBlock?._defineLinearSpecularReflection ?? \"LINEARSPECULARREFLECTION\" },\r\n                { search: /vReflectionFilteringInfo/g, replace: reflectionBlock?._vReflectionFilteringInfoName ?? \"vReflectionFilteringInfo\" },\r\n            ],\r\n        });\r\n\r\n        // ___________________ Compute Reflectance aka R0 F0 info _________________________\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockReflectance0\", comments, {\r\n            replaceStrings: [{ search: /metallicReflectanceFactors/g, replace: (isWebGPU ? \"uniforms.\" : \"\") + this._vMetallicReflectanceFactorsName }],\r\n        });\r\n        // ________________________________ Sheen ______________________________\r\n        const sheenBlock = this.sheen.isConnected ? (this.sheen.connectedPoint?.ownerBlock as SheenBlock) : null;\r\n\r\n        if (sheenBlock) {\r\n            state.compilationString += sheenBlock.getCode(reflectionBlock, state);\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"pbrBlockSheen\", comments, {\r\n            replaceStrings: [\r\n                { search: /REFLECTIONMAP_3D/g, replace: reflectionBlock?._define3DName ?? \"REFLECTIONMAP_3D\" },\r\n                { search: /REFLECTIONMAP_SKYBOX/g, replace: reflectionBlock?._defineSkyboxName ?? \"REFLECTIONMAP_SKYBOX\" },\r\n                { search: /LODINREFLECTIONALPHA/g, replace: reflectionBlock?._defineLODReflectionAlpha ?? \"LODINREFLECTIONALPHA\" },\r\n                { search: /LINEARSPECULARREFLECTION/g, replace: reflectionBlock?._defineLinearSpecularReflection ?? \"LINEARSPECULARREFLECTION\" },\r\n            ],\r\n        });\r\n\r\n        // ____________________ Clear Coat Initialization Code _____________________\r\n        const clearcoatBlock = this.clearcoat.isConnected ? (this.clearcoat.connectedPoint?.ownerBlock as ClearCoatBlock) : null;\r\n\r\n        state.compilationString += ClearCoatBlock._GetInitializationCode(state, clearcoatBlock);\r\n\r\n        // _____________________________ Iridescence _______________________________\r\n        const iridescenceBlock = this.iridescence.isConnected ? (this.iridescence.connectedPoint?.ownerBlock as IridescenceBlock) : null;\r\n        state.compilationString += IridescenceBlock.GetCode(iridescenceBlock, state);\r\n\r\n        state._emitFunctionFromInclude(\"pbrBlockIridescence\", comments, {\r\n            replaceStrings: [],\r\n        });\r\n\r\n        // _____________________________ Clear Coat ____________________________\r\n        const generateTBNSpace = !this.perturbedNormal.isConnected && !this.anisotropy.isConnected;\r\n        const isTangentConnectedToPerturbNormal =\r\n            this.perturbedNormal.isConnected && (this.perturbedNormal.connectedPoint?.ownerBlock as PerturbNormalBlock).worldTangent?.isConnected;\r\n        const isTangentConnectedToAnisotropy = this.anisotropy.isConnected && (this.anisotropy.connectedPoint?.ownerBlock as AnisotropyBlock).worldTangent.isConnected;\r\n        let vTBNAvailable = isTangentConnectedToPerturbNormal || (!this.perturbedNormal.isConnected && isTangentConnectedToAnisotropy);\r\n\r\n        state.compilationString += ClearCoatBlock.GetCode(state, clearcoatBlock, reflectionBlock, worldPosVarName, generateTBNSpace, vTBNAvailable, worldNormalVarName);\r\n\r\n        if (generateTBNSpace) {\r\n            vTBNAvailable = clearcoatBlock?.worldTangent.isConnected ?? false;\r\n        }\r\n\r\n        state._emitFunctionFromInclude(\"pbrBlockClearcoat\", comments, {\r\n            replaceStrings: [\r\n                { search: /computeReflectionCoords/g, replace: \"computeReflectionCoordsPBR\" },\r\n                { search: /REFLECTIONMAP_3D/g, replace: reflectionBlock?._define3DName ?? \"REFLECTIONMAP_3D\" },\r\n                { search: /REFLECTIONMAP_OPPOSITEZ/g, replace: reflectionBlock?._defineOppositeZ ?? \"REFLECTIONMAP_OPPOSITEZ\" },\r\n                { search: /REFLECTIONMAP_PROJECTION/g, replace: reflectionBlock?._defineProjectionName ?? \"REFLECTIONMAP_PROJECTION\" },\r\n                { search: /REFLECTIONMAP_SKYBOX/g, replace: reflectionBlock?._defineSkyboxName ?? \"REFLECTIONMAP_SKYBOX\" },\r\n                { search: /LODINREFLECTIONALPHA/g, replace: reflectionBlock?._defineLODReflectionAlpha ?? \"LODINREFLECTIONALPHA\" },\r\n                { search: /LINEARSPECULARREFLECTION/g, replace: reflectionBlock?._defineLinearSpecularReflection ?? \"LINEARSPECULARREFLECTION\" },\r\n                { search: /defined\\(TANGENT\\)/g, replace: vTBNAvailable ? \"defined(TANGENT)\" : \"defined(IGNORE)\" },\r\n            ],\r\n        });\r\n\r\n        // _________________________ Specular Environment Reflectance __________________________\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockReflectance\", comments, {\r\n            replaceStrings: [\r\n                { search: /REFLECTIONMAP_SKYBOX/g, replace: reflectionBlock?._defineSkyboxName ?? \"REFLECTIONMAP_SKYBOX\" },\r\n                { search: /REFLECTIONMAP_3D/g, replace: reflectionBlock?._define3DName ?? \"REFLECTIONMAP_3D\" },\r\n                { search: /uniforms\\.vReflectivityColor/g, replace: \"vReflectivityColor\" },\r\n            ],\r\n        });\r\n\r\n        // ___________________________________ SubSurface ______________________________________\r\n        const subsurfaceBlock = this.subsurface.isConnected ? (this.subsurface.connectedPoint?.ownerBlock as SubSurfaceBlock) : null;\r\n        const refractionBlock = this.subsurface.isConnected\r\n            ? ((this.subsurface.connectedPoint?.ownerBlock as SubSurfaceBlock).refraction.connectedPoint?.ownerBlock as RefractionBlock)\r\n            : null;\r\n\r\n        if (refractionBlock) {\r\n            refractionBlock.viewConnectionPoint = this.view;\r\n            refractionBlock.indexOfRefractionConnectionPoint = this.indexOfRefraction;\r\n        }\r\n\r\n        state.compilationString += SubSurfaceBlock.GetCode(state, subsurfaceBlock, reflectionBlock, worldPosVarName);\r\n\r\n        state._emitFunctionFromInclude(\"pbrBlockSubSurface\", comments, {\r\n            replaceStrings: [\r\n                { search: /REFLECTIONMAP_3D/g, replace: reflectionBlock?._define3DName ?? \"REFLECTIONMAP_3D\" },\r\n                { search: /REFLECTIONMAP_OPPOSITEZ/g, replace: reflectionBlock?._defineOppositeZ ?? \"REFLECTIONMAP_OPPOSITEZ\" },\r\n                { search: /REFLECTIONMAP_PROJECTION/g, replace: reflectionBlock?._defineProjectionName ?? \"REFLECTIONMAP_PROJECTION\" },\r\n                { search: /SS_REFRACTIONMAP_3D/g, replace: refractionBlock?._define3DName ?? \"SS_REFRACTIONMAP_3D\" },\r\n                { search: /SS_LODINREFRACTIONALPHA/g, replace: refractionBlock?._defineLODRefractionAlpha ?? \"SS_LODINREFRACTIONALPHA\" },\r\n                { search: /SS_LINEARSPECULARREFRACTION/g, replace: refractionBlock?._defineLinearSpecularRefraction ?? \"SS_LINEARSPECULARREFRACTION\" },\r\n                { search: /SS_REFRACTIONMAP_OPPOSITEZ/g, replace: refractionBlock?._defineOppositeZ ?? \"SS_REFRACTIONMAP_OPPOSITEZ\" },\r\n            ],\r\n        });\r\n\r\n        if (isWebGPU) {\r\n            state._emitFunctionFromInclude(\"pbrDirectLightingFunctions\", comments);\r\n        }\r\n\r\n        if (!isWebGPU) {\r\n            // WebGL keeps clustered lighting in a separate include.\r\n            // WebGPU nests a per-light specialized include inside pbrDirectLightingFunctions\r\n            // so storage buffers are not passed as ptr function parameters.\r\n            state._emitFunctionFromInclude(\"pbrClusteredLightingFunctions\", comments);\r\n        }\r\n\r\n        // _____________________________ Direct Lighting Info __________________________________\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockDirectLighting\", comments);\r\n\r\n        if (this.light) {\r\n            state.compilationString += state._emitCodeFromInclude(\"lightFragment\", comments, {\r\n                replaceStrings: [\r\n                    { search: /{X}/g, replace: this._lightId.toString() },\r\n                    { search: new RegExp(`${isWebGPU ? \"fragmentInputs.\" : \"\"}vPositionW`, \"g\"), replace: worldPosVarName + \".xyz\" },\r\n                    { search: /uniforms\\.vReflectivityColor/g, replace: \"vReflectivityColor\" },\r\n                ],\r\n            });\r\n        } else {\r\n            let substitutionVars = `vPositionW,${worldPosVarName}.xyz`;\r\n\r\n            if (isWebGPU) {\r\n                substitutionVars = \"fragmentInputs.\" + substitutionVars;\r\n                if (this.generateOnlyFragmentCode) {\r\n                    substitutionVars += `,fragmentInputs.vViewDepth,vViewDepth`;\r\n                }\r\n            }\r\n\r\n            state.compilationString += state._emitCodeFromInclude(\"lightFragment\", comments, {\r\n                repeatKey: \"maxSimultaneousLights\",\r\n                substitutionVars: substitutionVars + \",uniforms.vReflectivityColor,vReflectivityColor\",\r\n            });\r\n        }\r\n\r\n        // _____________________________ Compute Final Lit Components ________________________\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockFinalLitComponents\", comments);\r\n\r\n        // _____________________________ UNLIT (2) ________________________\r\n        state.compilationString += `#endif\\n`; // UNLIT\r\n\r\n        // _____________________________ Compute Final Unlit Components ________________________\r\n        const aoColor = this.ambientColor.isConnected ? this.ambientColor.associatedVariableName : `vec3${state.fSuffix}(0., 0., 0.)`;\r\n\r\n        let aoDirectLightIntensity = PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS.toString();\r\n\r\n        if (aoDirectLightIntensity.indexOf(\".\") === -1) {\r\n            aoDirectLightIntensity += \".\";\r\n        }\r\n\r\n        let replaceStrings = [\r\n            { search: /vec3 finalEmissive[\\s\\S]*?finalEmissive\\*=vLightingIntensity\\.y;/g, replace: \"\" },\r\n            { search: new RegExp(`${isWebGPU ? \"uniforms.\" : \"\"}vAmbientColor`, \"g\"), replace: aoColor + ` * ${isWebGPU ? \"uniforms.\" : \"\"}ambientFromScene` },\r\n            { search: new RegExp(`${isWebGPU ? \"uniforms.\" : \"\"}vAmbientInfos.w`, \"g\"), replace: aoDirectLightIntensity },\r\n        ];\r\n\r\n        if (isWebGPU) {\r\n            replaceStrings[0] = { search: /var finalEmissive[\\s\\S]*?finalEmissive\\*=uniforms.vLightingIntensity\\.y;/g, replace: \"\" };\r\n        }\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockFinalUnlitComponents\", comments, {\r\n            replaceStrings: replaceStrings,\r\n        });\r\n\r\n        // _____________________________ Output Final Color Composition ________________________\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockFinalColorComposition\", comments, {\r\n            replaceStrings: [{ search: /finalEmissive/g, replace: `vec3${state.fSuffix}(0.)` }],\r\n        });\r\n\r\n        // _____________________________ Apply image processing ________________________\r\n        if (isWebGPU) {\r\n            replaceStrings = [{ search: /mesh.visibility/g, replace: \"1.\" }];\r\n        } else {\r\n            replaceStrings = [{ search: /visibility/g, replace: \"1.\" }];\r\n        }\r\n\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrBlockImageProcessing\", comments, {\r\n            replaceStrings: replaceStrings,\r\n        });\r\n\r\n        // _____________________________ Generate debug code ________________________\r\n\r\n        const colorOutput = isWebGPU ? \"fragmentOutputs.color\" : \"gl_FragColor\";\r\n        replaceStrings = [\r\n            { search: new RegExp(`${isWebGPU ? \"fragmentInputs.\" : \"\"}vNormalW`, \"g\"), replace: this._vNormalWName },\r\n            { search: new RegExp(`${isWebGPU ? \"fragmentInputs.\" : \"\"}vPositionW`, \"g\"), replace: worldPosVarName },\r\n            { search: /uniforms\\.vReflectivityColor/g, replace: \"vReflectivityColor\" },\r\n            {\r\n                search: /albedoTexture\\.rgb;/g,\r\n                replace: `vec3${state.fSuffix}(1.);\\n${colorOutput}.rgb = toGammaSpace(${colorOutput}.rgb);\\n`,\r\n            },\r\n        ];\r\n        state.compilationString += state._emitCodeFromInclude(\"pbrDebug\", comments, {\r\n            replaceStrings: replaceStrings,\r\n        });\r\n\r\n        // _____________________________ Generate end points ________________________\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints) {\r\n                const remap = MapOutputToVariable[output.name];\r\n                if (remap) {\r\n                    const [varName, conditions] = remap;\r\n                    if (conditions) {\r\n                        state.compilationString += `#if ${conditions}\\n`;\r\n                    }\r\n                    state.compilationString += `${state._declareOutput(output)} = ${varName};\\n`;\r\n                    if (conditions) {\r\n                        state.compilationString += `#else\\n`;\r\n                        state.compilationString += `${state._declareOutput(output)} = vec3${state.fSuffix}(0.);\\n`;\r\n                        state.compilationString += `#endif\\n`;\r\n                    }\r\n                } else {\r\n                    state.sharedData.raiseBuildError(`There's no remapping for the ${output.name} end point! No code generated`);\r\n                }\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.lightFalloff = ${this.lightFalloff};\\n`;\r\n        codeString += `${this._codeVariableName}.useAlphaTest = ${this.useAlphaTest};\\n`;\r\n        codeString += `${this._codeVariableName}.alphaTestCutoff = ${this.alphaTestCutoff};\\n`;\r\n        codeString += `${this._codeVariableName}.useAlphaBlending = ${this.useAlphaBlending};\\n`;\r\n        codeString += `${this._codeVariableName}.useRadianceOverAlpha = ${this.useRadianceOverAlpha};\\n`;\r\n        codeString += `${this._codeVariableName}.useSpecularOverAlpha = ${this.useSpecularOverAlpha};\\n`;\r\n        codeString += `${this._codeVariableName}.enableSpecularAntiAliasing = ${this.enableSpecularAntiAliasing};\\n`;\r\n        codeString += `${this._codeVariableName}.realTimeFiltering = ${this.realTimeFiltering};\\n`;\r\n        codeString += `${this._codeVariableName}.realTimeFilteringQuality = ${this.realTimeFilteringQuality};\\n`;\r\n        codeString += `${this._codeVariableName}.useEnergyConservation = ${this.useEnergyConservation};\\n`;\r\n        codeString += `${this._codeVariableName}.useRadianceOcclusion = ${this.useRadianceOcclusion};\\n`;\r\n        codeString += `${this._codeVariableName}.useHorizonOcclusion = ${this.useHorizonOcclusion};\\n`;\r\n        codeString += `${this._codeVariableName}.unlit = ${this.unlit};\\n`;\r\n        codeString += `${this._codeVariableName}.forceNormalForward = ${this.forceNormalForward};\\n`;\r\n        codeString += `${this._codeVariableName}.debugMode = ${this.debugMode};\\n`;\r\n        codeString += `${this._codeVariableName}.debugLimit = ${this.debugLimit};\\n`;\r\n        codeString += `${this._codeVariableName}.debugFactor = ${this.debugFactor};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        if (this.light) {\r\n            serializationObject.lightId = this.light.id;\r\n        }\r\n\r\n        serializationObject.lightFalloff = this.lightFalloff;\r\n        serializationObject.useAlphaTest = this.useAlphaTest;\r\n        serializationObject.alphaTestCutoff = this.alphaTestCutoff;\r\n        serializationObject.useAlphaBlending = this.useAlphaBlending;\r\n        serializationObject.useRadianceOverAlpha = this.useRadianceOverAlpha;\r\n        serializationObject.useSpecularOverAlpha = this.useSpecularOverAlpha;\r\n        serializationObject.enableSpecularAntiAliasing = this.enableSpecularAntiAliasing;\r\n        serializationObject.realTimeFiltering = this.realTimeFiltering;\r\n        serializationObject.realTimeFilteringQuality = this.realTimeFilteringQuality;\r\n        serializationObject.useEnergyConservation = this.useEnergyConservation;\r\n        serializationObject.useRadianceOcclusion = this.useRadianceOcclusion;\r\n        serializationObject.useHorizonOcclusion = this.useHorizonOcclusion;\r\n        serializationObject.unlit = this.unlit;\r\n        serializationObject.forceNormalForward = this.forceNormalForward;\r\n        serializationObject.debugMode = this.debugMode;\r\n        serializationObject.debugLimit = this.debugLimit;\r\n        serializationObject.debugFactor = this.debugFactor;\r\n        serializationObject.generateOnlyFragmentCode = this.generateOnlyFragmentCode;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the scene to deserialize in\r\n     * @param rootUrl - the root URL for assets\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        if (serializationObject.lightId) {\r\n            this.light = scene.getLightById(serializationObject.lightId);\r\n        }\r\n\r\n        this.lightFalloff = serializationObject.lightFalloff ?? 0;\r\n        this.useAlphaTest = serializationObject.useAlphaTest;\r\n        this.alphaTestCutoff = serializationObject.alphaTestCutoff;\r\n        this.useAlphaBlending = serializationObject.useAlphaBlending;\r\n        this.useRadianceOverAlpha = serializationObject.useRadianceOverAlpha;\r\n        this.useSpecularOverAlpha = serializationObject.useSpecularOverAlpha;\r\n        this.enableSpecularAntiAliasing = serializationObject.enableSpecularAntiAliasing;\r\n        this.realTimeFiltering = !!serializationObject.realTimeFiltering;\r\n        this.realTimeFilteringQuality = serializationObject.realTimeFilteringQuality ?? Constants.TEXTURE_FILTERING_QUALITY_LOW;\r\n        this.useEnergyConservation = serializationObject.useEnergyConservation;\r\n        this.useRadianceOcclusion = serializationObject.useRadianceOcclusion;\r\n        this.useHorizonOcclusion = serializationObject.useHorizonOcclusion;\r\n        this.unlit = serializationObject.unlit;\r\n        this.forceNormalForward = !!serializationObject.forceNormalForward;\r\n        this.debugMode = serializationObject.debugMode;\r\n        this.debugLimit = serializationObject.debugLimit;\r\n        this.debugFactor = serializationObject.debugFactor;\r\n        this.generateOnlyFragmentCode = !!serializationObject.generateOnlyFragmentCode;\r\n\r\n        this._setTarget();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pbrMetallicRoughnessBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPbrMetallicRoughnessBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PBRMetallicRoughnessBlock\", PBRMetallicRoughnessBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to compute value of one parameter modulo another\r\n */\r\nexport class ModBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ModBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"left\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ModBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.GLSL) {\r\n            state.compilationString += state._declareOutput(output) + ` = mod(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\\n`;\r\n        } else {\r\n            state.compilationString += state._declareOutput(output) + ` = (${this.left.associatedVariableName} % ${this.right.associatedVariableName});\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for modBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterModBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ModBlock\", ModBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to build a matrix from 4 Vector4\r\n */\r\nexport class MatrixBuilderBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MatrixBuilder\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"row0\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"row1\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"row2\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerInput(\"row3\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MatrixBuilder\";\r\n    }\r\n\r\n    /**\r\n     * Gets the row0 vector\r\n     */\r\n    public get row0(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the row1 vector\r\n     */\r\n    public get row1(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the row2 vector\r\n     */\r\n    public get row2(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the row3 vector\r\n     */\r\n    public get row3(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** Auto configure the block based on the material */\r\n    public override autoConfigure() {\r\n        if (!this.row0.isConnected) {\r\n            const row0Input = new InputBlock(\"row0\");\r\n            row0Input.value = new Vector4(1, 0, 0, 0);\r\n            row0Input.output.connectTo(this.row0);\r\n        }\r\n\r\n        if (!this.row1.isConnected) {\r\n            const row1Input = new InputBlock(\"row1\");\r\n            row1Input.value = new Vector4(0, 1, 0, 0);\r\n            row1Input.output.connectTo(this.row1);\r\n        }\r\n\r\n        if (!this.row2.isConnected) {\r\n            const row2Input = new InputBlock(\"row2\");\r\n            row2Input.value = new Vector4(0, 0, 1, 0);\r\n            row2Input.output.connectTo(this.row2);\r\n        }\r\n\r\n        if (!this.row3.isConnected) {\r\n            const row3Input = new InputBlock(\"row3\");\r\n            row3Input.value = new Vector4(0, 0, 0, 1);\r\n            row3Input.output.connectTo(this.row3);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const row0 = this.row0;\r\n        const row1 = this.row1;\r\n        const row2 = this.row2;\r\n        const row3 = this.row3;\r\n\r\n        const mat4 = state.shaderLanguage === ShaderLanguage.WGSL ? \"mat4x4f\" : \"mat4\";\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(output) +\r\n            ` = ${mat4}(${row0.associatedVariableName}, ${row1.associatedVariableName}, ${row2.associatedVariableName}, ${row3.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for matrixBuilderBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMatrixBuilderBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MatrixBuilder\", MatrixBuilderBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { type NodeMaterial } from \"../nodeMaterial.pure\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the ConditionalBlock block\r\n */\r\nexport enum ConditionalBlockConditions {\r\n    /** Equal */\r\n    Equal,\r\n    /** NotEqual */\r\n    NotEqual,\r\n    /** LessThan */\r\n    LessThan,\r\n    /** GreaterThan */\r\n    GreaterThan,\r\n    /** LessOrEqual */\r\n    LessOrEqual,\r\n    /** GreaterOrEqual */\r\n    GreaterOrEqual,\r\n    /** Logical Exclusive OR */\r\n    Xor,\r\n    /** Logical Or */\r\n    Or,\r\n    /** Logical And */\r\n    And,\r\n}\r\n\r\n/**\r\n * Block used to apply conditional operation between floats\r\n * @since 5.0.0\r\n */\r\nexport class ConditionalBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the condition applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Condition\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Equal\", value: ConditionalBlockConditions.Equal },\r\n            { label: \"NotEqual\", value: ConditionalBlockConditions.NotEqual },\r\n            { label: \"LessThan\", value: ConditionalBlockConditions.LessThan },\r\n            { label: \"GreaterThan\", value: ConditionalBlockConditions.GreaterThan },\r\n            { label: \"LessOrEqual\", value: ConditionalBlockConditions.LessOrEqual },\r\n            { label: \"GreaterOrEqual\", value: ConditionalBlockConditions.GreaterOrEqual },\r\n            { label: \"Xor\", value: ConditionalBlockConditions.Xor },\r\n            { label: \"And\", value: ConditionalBlockConditions.And },\r\n            { label: \"Or\", value: ConditionalBlockConditions.Or },\r\n        ],\r\n    })\r\n    public condition = ConditionalBlockConditions.LessThan;\r\n\r\n    /**\r\n     * Creates a new ConditionalBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"a\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"b\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"true\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"false\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._linkConnectionTypes(2, 3);\r\n        this._outputs[0]._typeConnectionSource = this._inputs[2];\r\n        this._outputs[0]._defaultConnectionPointType = NodeMaterialBlockConnectionPointTypes.Float;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ConditionalBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the first operand component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the second operand component\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the value to return if condition is true\r\n     */\r\n    public get true(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the value to return if condition is false\r\n     */\r\n    public get false(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param nodeMaterial - the node material\r\n     */\r\n    public override autoConfigure(nodeMaterial: NodeMaterial) {\r\n        if (!this.true.isConnected) {\r\n            const minInput = (nodeMaterial.getBlockByPredicate((b) => b.isInput && (b as InputBlock).value === 1 && b.name === \"True\") as InputBlock) || new InputBlock(\"True\");\r\n            minInput.value = 1;\r\n            minInput.output.connectTo(this.true);\r\n        }\r\n\r\n        if (!this.false.isConnected) {\r\n            const maxInput = (nodeMaterial.getBlockByPredicate((b) => b.isInput && (b as InputBlock).value === 0 && b.name === \"False\") as InputBlock) || new InputBlock(\"False\");\r\n            maxInput.value = 0;\r\n            maxInput.output.connectTo(this.false);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        const trueStatement = this.true.isConnected ? this.true.associatedVariableName : \"1.0\";\r\n        const falseStatement = this.false.isConnected ? this.false.associatedVariableName : \"0.0\";\r\n\r\n        switch (this.condition) {\r\n            case ConditionalBlockConditions.Equal: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `${this.a.associatedVariableName} == ${this.b.associatedVariableName}`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.NotEqual: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `${this.a.associatedVariableName} != ${this.b.associatedVariableName}`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.LessThan: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `${this.a.associatedVariableName} < ${this.b.associatedVariableName}`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.LessOrEqual: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `${this.a.associatedVariableName} <= ${this.b.associatedVariableName}`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.GreaterThan: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `${this.a.associatedVariableName} > ${this.b.associatedVariableName}`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.GreaterOrEqual: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `${this.a.associatedVariableName} >= ${this.b.associatedVariableName}`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.Xor: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `(((${this.a.associatedVariableName} + ${this.b.associatedVariableName}) % 2.0) > 0.0)`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.Or: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `(min(${this.a.associatedVariableName} + ${this.b.associatedVariableName}, 1.0) > 0.0)`)};\\n`;\r\n                break;\r\n            }\r\n            case ConditionalBlockConditions.And: {\r\n                state.compilationString +=\r\n                    state._declareOutput(output) +\r\n                    ` = ${state._generateTernary(trueStatement, falseStatement, `(${this.a.associatedVariableName} * ${this.b.associatedVariableName} > 0.0)`)};\\n`;\r\n                break;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.condition = this.condition;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.condition = serializationObject.condition;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString =\r\n            super._dumpPropertiesCode() + `${this._codeVariableName}.condition = BABYLON.ConditionalBlockConditions.${ConditionalBlockConditions[this.condition]};\\n`;\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for conditionalBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterConditionalBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ConditionalBlock\", ConditionalBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { ShaderLanguage } from \"../../../Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * block used to Generate Fractal Brownian Motion Clouds\r\n */\r\nexport class CloudBlock extends NodeMaterialBlock {\r\n    /** Gets or sets the number of octaves */\r\n    @editableInPropertyPage(\"Octaves\", PropertyTypeForEdition.Int, undefined, { embedded: true })\r\n    public octaves = 6.0;\r\n\r\n    /**\r\n     * Creates a new CloudBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n        this.registerInput(\"seed\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"chaos\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n        this.registerInput(\"offsetX\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"offsetY\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"offsetZ\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CloudBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the seed input component\r\n     */\r\n    public get seed(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the chaos input component\r\n     */\r\n    public get chaos(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset X input component\r\n     */\r\n    public get offsetX(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset Y input component\r\n     */\r\n    public get offsetY(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset Z input component\r\n     */\r\n    public get offsetZ(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.seed.isConnected) {\r\n            return;\r\n        }\r\n\r\n        if (!this._outputs[0].hasEndpoints) {\r\n            return;\r\n        }\r\n\r\n        let functionString = `\r\n\r\n        float cloudRandom(float p) { \r\n            float temp = fract(p * 0.011); \r\n            temp *= temp + 7.5; \r\n            temp *= temp + temp; \r\n            return fract(temp); \r\n        }\r\n\r\n        // Based on Morgan McGuire @morgan3d\r\n        // https://www.shadertoy.com/view/4dS3Wd\r\n        float cloudNoise2(vec2 x, vec2 chaos) {\r\n            vec2 step = chaos * vec2(75., 120.) + vec2(75., 120.);\r\n\r\n            vec2 i = floor(x);\r\n            vec2 f = fract(x);\r\n\r\n            float n = dot(i, step);\r\n\r\n            vec2 u = f * f * (3.0 - 2.0 * f);\r\n            return mix(\r\n                    mix(cloudRandom(n + dot(step, vec2(0, 0))), cloudRandom(n + dot(step, vec2(1, 0))), u.x),\r\n                    mix(cloudRandom(n + dot(step, vec2(0, 1))), cloudRandom(n + dot(step, vec2(1, 1))), u.x),\r\n                    u.y\r\n                );\r\n        }\r\n\r\n        float cloudNoise3(vec3 x, vec3 chaos) {\r\n            vec3 step = chaos * vec3(60., 120., 75.) + vec3(60., 120., 75.);\r\n\r\n            vec3 i = floor(x);\r\n            vec3 f = fract(x);\r\n\r\n            float n = dot(i, step);\r\n\r\n            vec3 u = f * f * (3.0 - 2.0 * f);\r\n            return mix(mix(mix( cloudRandom(n + dot(step, vec3(0, 0, 0))), cloudRandom(n + dot(step, vec3(1, 0, 0))), u.x),\r\n                           mix( cloudRandom(n + dot(step, vec3(0, 1, 0))), cloudRandom(n + dot(step, vec3(1, 1, 0))), u.x), u.y),\r\n                       mix(mix( cloudRandom(n + dot(step, vec3(0, 0, 1))), cloudRandom(n + dot(step, vec3(1, 0, 1))), u.x),\r\n                           mix( cloudRandom(n + dot(step, vec3(0, 1, 1))), cloudRandom(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z);\r\n        }`;\r\n\r\n        let fractalBrownianString = `\r\n        float fbm2(vec2 st, vec2 chaos) {\r\n            // Initial values\r\n            float value = 0.0;\r\n            float amplitude = .5;\r\n            float frequency = 0.;\r\n\r\n            // Loop of octaves\r\n            vec2 tempST = st;\r\n            for (int i = 0; i < OCTAVES; i++) {\r\n                value += amplitude * cloudNoise2(tempST, chaos);\r\n                tempST *= 2.0;\r\n                amplitude *= 0.5;\r\n            }\r\n            return value;\r\n        }\r\n\r\n        float fbm3(vec3 x, vec3 chaos) {\r\n            // Initial values\r\n            float value = 0.0;\r\n            float amplitude = 0.5;\r\n            vec3 tempX = x;\r\n            for (int i = 0; i < OCTAVES; i++) {\r\n                value += amplitude * cloudNoise3(tempX, chaos);\r\n                tempX = tempX * 2.0;\r\n                amplitude *= 0.5;\r\n            }\r\n            return value;\r\n        }`;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = state._babylonSLtoWGSL(functionString);\r\n            fractalBrownianString = state._babylonSLtoWGSL(fractalBrownianString);\r\n        }\r\n\r\n        const fbmNewName = `fbm${this.octaves}`;\r\n        state._emitFunction(\"CloudBlockCode\", functionString, \"// CloudBlockCode\");\r\n        state._emitFunction(\r\n            \"CloudBlockCodeFBM\" + this.octaves,\r\n            fractalBrownianString.replace(/fbm/gi, fbmNewName).replace(/OCTAVES/gi, (this.octaves | 0).toString()),\r\n            \"// CloudBlockCode FBM\"\r\n        );\r\n\r\n        const localVariable = state._getFreeVariableName(\"st\");\r\n        const seedType = this.seed.connectedPoint?.type || NodeMaterialBlockConnectionPointTypes.Vector3;\r\n\r\n        state.compilationString += `${state._declareLocalVar(localVariable, seedType)} = ${this.seed.associatedVariableName};\\n`;\r\n        if (this.offsetX.isConnected) {\r\n            state.compilationString += `${localVariable}.x += 0.1 * ${this.offsetX.associatedVariableName};\\n`;\r\n        }\r\n        if (this.offsetY.isConnected) {\r\n            state.compilationString += `${localVariable}.y += 0.1 * ${this.offsetY.associatedVariableName};\\n`;\r\n        }\r\n        if (this.offsetZ.isConnected && seedType === NodeMaterialBlockConnectionPointTypes.Vector3) {\r\n            state.compilationString += `${localVariable}.z += 0.1 * ${this.offsetZ.associatedVariableName};\\n`;\r\n        }\r\n\r\n        let chaosValue: string;\r\n        if (this.chaos.isConnected) {\r\n            chaosValue = this.chaos.associatedVariableName;\r\n        } else {\r\n            const addF = state.fSuffix;\r\n            chaosValue = this.seed.connectedPoint?.type === NodeMaterialBlockConnectionPointTypes.Vector2 ? `vec2${addF}(0., 0.)` : `vec3${addF}(0., 0., 0.)`;\r\n        }\r\n\r\n        state.compilationString +=\r\n            state._declareOutput(this._outputs[0]) +\r\n            ` = ${fbmNewName}${this.seed.connectedPoint?.type === NodeMaterialBlockConnectionPointTypes.Vector2 ? \"2\" : \"3\"}(${localVariable}, ${chaosValue});\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.octaves = ${this.octaves};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.octaves = this.octaves;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.octaves = serializationObject.octaves;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cloudBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCloudBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CloudBlock\", CloudBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * block used to Generate a Voronoi Noise Pattern\r\n */\r\nexport class VoronoiNoiseBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new VoronoiNoiseBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n        this.registerInput(\"seed\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"offset\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"density\", NodeMaterialBlockConnectionPointTypes.Float);\r\n\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"cells\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"VoronoiNoiseBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the seed input component\r\n     */\r\n    public get seed(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset input component\r\n     */\r\n    public get offset(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the density input component\r\n     */\r\n    public get density(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get cells(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this.seed.isConnected) {\r\n            return;\r\n        }\r\n        // Adapted from https://www.shadertoy.com/view/MslGD8\r\n        let functionString = `vec2 voronoiRandom(vec2 p){\r\n            p = vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3)));\r\n            return fract(sin(p)*18.5453);\r\n        }\r\n        `;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = state._babylonSLtoWGSL(functionString);\r\n        }\r\n\r\n        state._emitFunction(\"voronoiRandom\", functionString, \"// Voronoi random generator\");\r\n\r\n        functionString = `void voronoi(vec2 seed, float offset, float density, out float outValue, out float cells){\r\n            vec2 n = floor(seed * density);\r\n            vec2 f = fract(seed * density);\r\n            vec3 m = vec3( 8.0 );\r\n            for( int j=-1; j<=1; j++ ){\r\n                for( int i=-1; i<=1; i++ ){\r\n                    vec2  g = vec2( float(i), float(j) );\r\n                    vec2  o = voronoiRandom( n + g);\r\n                    vec2  r = g - f + (0.5+0.5*sin(offset+6.2831*o));\r\n                    float d = dot( r, r );\r\n                    if( d<m.x ){\r\n                        m = vec3( d, o );\r\n                        outValue = m.x;\r\n                        cells = m.y;\r\n                    }\r\n                }\r\n\t\t\t}\r\n        }\r\n        `;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            functionString = state._babylonSLtoWGSL(functionString);\r\n        } else {\r\n            functionString = state._babylonSLtoGLSL(functionString);\r\n        }\r\n\r\n        state._emitFunction(\"voronoi\", functionString, \"// Voronoi\");\r\n\r\n        const tempOutput = state._getFreeVariableName(\"tempOutput\");\r\n        const tempCells = state._getFreeVariableName(\"tempCells\");\r\n        const ref = state.shaderLanguage === ShaderLanguage.WGSL ? \"&\" : \"\";\r\n\r\n        state.compilationString += `${state._declareLocalVar(tempOutput, NodeMaterialBlockConnectionPointTypes.Float)} = 0.0;\\n`;\r\n        state.compilationString += `${state._declareLocalVar(tempCells, NodeMaterialBlockConnectionPointTypes.Float)} = 0.0;\\n`;\r\n        state.compilationString += `voronoi(${this.seed.associatedVariableName}, ${this.offset.associatedVariableName}, ${this.density.associatedVariableName}, ${ref}${tempOutput}, ${ref}${tempCells});\\n`;\r\n\r\n        if (this.output.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.output) + ` = ${tempOutput};\\n`;\r\n        }\r\n\r\n        if (this.cells.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(this.cells) + ` = ${tempCells};\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for voronoiNoiseBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVoronoiNoiseBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.VoronoiNoiseBlock\", VoronoiNoiseBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used as a pass through\r\n */\r\nexport class ElbowBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new ElbowBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ElbowBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the target of the block\r\n     */\r\n    public override get target() {\r\n        const input = this._inputs[0];\r\n        if (input.isConnected) {\r\n            const block = input.connectedPoint!.ownerBlock;\r\n            if (block.target !== NodeMaterialBlockTargets.VertexAndFragment) {\r\n                return block.target;\r\n            }\r\n\r\n            if (input.connectedPoint!.target !== NodeMaterialBlockTargets.VertexAndFragment) {\r\n                return input.connectedPoint!.target;\r\n            }\r\n        }\r\n\r\n        return this._target;\r\n    }\r\n\r\n    public override set target(value: NodeMaterialBlockTargets) {\r\n        if ((this._target & value) !== 0) {\r\n            return;\r\n        }\r\n        this._target = value;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input = this._inputs[0];\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${input.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialsNodeBlocksElbowBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialsNodeBlocksElbowBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ElbowBlock\", ElbowBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\n\r\nimport { NodeMaterial } from \"../nodeMaterial.pure\";\r\nimport { type NodeMaterialDefines } from \"../nodeMaterial\";\r\nimport { type Effect } from \"../../effect.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Texture } from \"../../Textures/texture.pure\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { ImageSourceBlock } from \"./Dual/imageSourceBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../nodeMaterialConnectionPointCustomObject\";\r\nimport { EngineStore } from \"../../../Engines/engineStore\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to read a texture with triplanar mapping (see \"boxmap\" in https://iquilezles.org/articles/biplanar/)\r\n */\r\nexport class TriPlanarBlock extends NodeMaterialBlock {\r\n    private _linearDefineName: string;\r\n    private _gammaDefineName: string;\r\n    protected _tempTextureRead: string;\r\n    private _samplerName: string;\r\n    private _textureInfoName: string;\r\n    private _textureInfoName2: string;\r\n    private _imageSource: Nullable<ImageSourceBlock>;\r\n\r\n    /**\r\n     * Project the texture(s) for a better fit to a cube\r\n     */\r\n    @editableInPropertyPage(\"Project as cube\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { update: true } })\r\n    public projectAsCube: boolean = false;\r\n\r\n    protected _texture: Nullable<Texture>;\r\n    /**\r\n     * Gets or sets the texture associated with the node\r\n     */\r\n    public get texture(): Nullable<Texture> {\r\n        if (this.source.isConnected) {\r\n            return (this.source.connectedPoint?.ownerBlock as ImageSourceBlock).texture;\r\n        }\r\n        return this._texture;\r\n    }\r\n\r\n    public set texture(texture: Nullable<Texture>) {\r\n        if (this._texture === texture) {\r\n            return;\r\n        }\r\n\r\n        const scene = texture?.getScene() ?? EngineStore.LastCreatedScene;\r\n\r\n        if (!texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this._texture!);\r\n            });\r\n        }\r\n\r\n        this._texture = texture;\r\n\r\n        if (texture && scene) {\r\n            scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(texture);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the textureY associated with the node\r\n     */\r\n    public get textureY(): Nullable<Texture> {\r\n        if (this.sourceY.isConnected) {\r\n            return (this.sourceY.connectedPoint?.ownerBlock as ImageSourceBlock).texture;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the textureZ associated with the node\r\n     */\r\n    public get textureZ(): Nullable<Texture> {\r\n        if (this.sourceZ?.isConnected) {\r\n            return (this.sourceZ.connectedPoint?.ownerBlock as ImageSourceBlock).texture;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    protected _getImageSourceBlock(connectionPoint: Nullable<NodeMaterialConnectionPoint>): Nullable<ImageSourceBlock> {\r\n        return connectionPoint?.isConnected ? (connectionPoint.connectedPoint!.ownerBlock as ImageSourceBlock) : null;\r\n    }\r\n\r\n    /**\r\n     * Gets the sampler name associated with this texture\r\n     */\r\n    public get samplerName(): string {\r\n        const imageSourceBlock = this._getImageSourceBlock(this.source);\r\n        if (imageSourceBlock) {\r\n            return imageSourceBlock.samplerName;\r\n        }\r\n        return this._samplerName;\r\n    }\r\n\r\n    /**\r\n     * Gets the samplerY name associated with this texture\r\n     */\r\n    public get samplerYName(): Nullable<string> {\r\n        return this._getImageSourceBlock(this.sourceY)?.samplerName ?? null;\r\n    }\r\n\r\n    /**\r\n     * Gets the samplerZ name associated with this texture\r\n     */\r\n    public get samplerZName(): Nullable<string> {\r\n        return this._getImageSourceBlock(this.sourceZ)?.samplerName ?? null;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block is linked to an ImageSourceBlock\r\n     */\r\n    public get hasImageSource(): boolean {\r\n        return this.source.isConnected;\r\n    }\r\n\r\n    private _convertToGammaSpace = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to gamma space\r\n     */\r\n    public set convertToGammaSpace(value: boolean) {\r\n        if (value === this._convertToGammaSpace) {\r\n            return;\r\n        }\r\n\r\n        this._convertToGammaSpace = value;\r\n        if (this.texture) {\r\n            const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;\r\n            scene?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this.texture!);\r\n            });\r\n        }\r\n    }\r\n    public get convertToGammaSpace(): boolean {\r\n        return this._convertToGammaSpace;\r\n    }\r\n\r\n    private _convertToLinearSpace = false;\r\n    /**\r\n     * Gets or sets a boolean indicating if content needs to be converted to linear space\r\n     */\r\n    public set convertToLinearSpace(value: boolean) {\r\n        if (value === this._convertToLinearSpace) {\r\n            return;\r\n        }\r\n\r\n        this._convertToLinearSpace = value;\r\n        if (this.texture) {\r\n            const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;\r\n            scene?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n                return mat.hasTexture(this.texture!);\r\n            });\r\n        }\r\n    }\r\n    public get convertToLinearSpace(): boolean {\r\n        return this._convertToLinearSpace;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if multiplication of texture with level should be disabled\r\n     */\r\n    public disableLevelMultiplication = false;\r\n\r\n    /**\r\n     * Create a new TriPlanarBlock\r\n     * @param name defines the block name\r\n     * @param hideSourceZ defines a boolean indicating that normal Z should not be used (false by default)\r\n     */\r\n    public constructor(name: string, hideSourceZ = false) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"position\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false);\r\n        this.registerInput(\"normal\", NodeMaterialBlockConnectionPointTypes.AutoDetect, false);\r\n        this.registerInput(\"sharpness\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\r\n            \"source\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"source\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        this.registerInput(\r\n            \"sourceY\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            true,\r\n            NodeMaterialBlockTargets.VertexAndFragment,\r\n            new NodeMaterialConnectionPointCustomObject(\"sourceY\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n        );\r\n        if (!hideSourceZ) {\r\n            this.registerInput(\r\n                \"sourceZ\",\r\n                NodeMaterialBlockConnectionPointTypes.Object,\r\n                true,\r\n                NodeMaterialBlockTargets.VertexAndFragment,\r\n                new NodeMaterialConnectionPointCustomObject(\"sourceZ\", this, NodeMaterialConnectionPointDirection.Input, ImageSourceBlock, \"ImageSourceBlock\")\r\n            );\r\n        }\r\n\r\n        this.registerOutput(\"rgba\", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"r\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"g\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"b\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n        this.registerOutput(\"a\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerOutput(\"level\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n        this._inputs[1].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeMaterialBlockConnectionPointTypes.Color3 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     * @param state defines the state that will be used for the build\r\n     */\r\n    public override initialize(state: NodeMaterialBuildState) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync(state.shaderLanguage);\r\n    }\r\n\r\n    private async _initShaderSourceAsync(shaderLanguage: ShaderLanguage) {\r\n        this._codeIsReady = false;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            await import(\"../../../ShadersWGSL/ShadersInclude/helperFunctions\");\r\n        } else {\r\n            await import(\"../../../Shaders/ShadersInclude/helperFunctions\");\r\n        }\r\n\r\n        this._codeIsReady = true;\r\n        this.onCodeIsReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TriPlanarBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get position(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal input component\r\n     */\r\n    public get normal(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the sharpness input component\r\n     */\r\n    public get sharpness(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the source input component\r\n     */\r\n    public get source(): NodeMaterialConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the sourceY input component\r\n     */\r\n    public get sourceY(): NodeMaterialConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the sourceZ input component\r\n     */\r\n    public get sourceZ(): Nullable<NodeMaterialConnectionPoint> {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba output component\r\n     */\r\n    public get rgba(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb output component\r\n     */\r\n    public get rgb(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the r output component\r\n     */\r\n    public get r(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the g output component\r\n     */\r\n    public get g(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the b output component\r\n     */\r\n    public get b(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the a output component\r\n     */\r\n    public get a(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the level output component\r\n     */\r\n    public get level(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Prepares the defines for the block\r\n     * @param defines - the defines to prepare\r\n     */\r\n    public override prepareDefines(defines: NodeMaterialDefines) {\r\n        if (!defines._areTexturesDirty) {\r\n            return;\r\n        }\r\n\r\n        const toGamma = this.convertToGammaSpace && this.texture && !this.texture.gammaSpace;\r\n        const toLinear = this.convertToLinearSpace && this.texture && this.texture.gammaSpace;\r\n\r\n        // Not a bug... Name defines the texture space not the required conversion\r\n        defines.setValue(this._linearDefineName, toGamma, true);\r\n        defines.setValue(this._gammaDefineName, toLinear, true);\r\n    }\r\n\r\n    /**\r\n     * Checks if the block is ready\r\n     * @returns true if the block is ready\r\n     */\r\n    public override isReady() {\r\n        if (this.texture && !this.texture.isReadyOrNotBlocking()) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Bind the block\r\n     * @param effect - the effect to bind\r\n     */\r\n    public override bind(effect: Effect) {\r\n        if (!this.texture) {\r\n            return;\r\n        }\r\n\r\n        effect.setFloat4(this._textureInfoName, this.texture.level, this.texture.uAng, this.texture.vAng, this.texture.wAng);\r\n        effect.setFloat4(this._textureInfoName2, this.texture.uOffset, this.texture.vOffset, this.texture.uScale, this.texture.vScale);\r\n\r\n        if (!this._imageSource) {\r\n            effect.setTexture(this._samplerName, this.texture);\r\n        }\r\n    }\r\n\r\n    private _samplerFunc(state: NodeMaterialBuildState) {\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return \"textureSample\";\r\n        }\r\n        return \"texture2D\";\r\n    }\r\n\r\n    private _generateTextureSample(textureName: string, uv: string, state: NodeMaterialBuildState) {\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `${this._samplerFunc(state)}(${textureName},${textureName + Constants.AUTOSAMPLERSUFFIX}, ${uv})`;\r\n        }\r\n        return `${this._samplerFunc(state)}(${textureName}, ${uv})`;\r\n    }\r\n\r\n    protected _generateTextureLookup(state: NodeMaterialBuildState): void {\r\n        const samplerName = this.samplerName;\r\n        const samplerYName = this.samplerYName ?? samplerName;\r\n        const samplerZName = this.samplerZName ?? samplerName;\r\n\r\n        const sharpness = this.sharpness.isConnected ? this.sharpness.associatedVariableName : \"1.0\";\r\n\r\n        const x = state._getFreeVariableName(\"x\");\r\n        const y = state._getFreeVariableName(\"y\");\r\n        const z = state._getFreeVariableName(\"z\");\r\n        const w = state._getFreeVariableName(\"w\");\r\n        const n = state._getFreeVariableName(\"n\");\r\n        const uvx = state._getFreeVariableName(\"uvx\");\r\n        const uvy = state._getFreeVariableName(\"uvy\");\r\n        const uvz = state._getFreeVariableName(\"uvz\");\r\n\r\n        state.compilationString += `\r\n            ${state._declareLocalVar(n, NodeMaterialBlockConnectionPointTypes.Vector3)} = ${this.normal.associatedVariableName}.xyz;\r\n\r\n            ${state._declareLocalVar(uvx, NodeMaterialBlockConnectionPointTypes.Vector2)} = ${this.position.associatedVariableName}.yz;\r\n            ${state._declareLocalVar(uvy, NodeMaterialBlockConnectionPointTypes.Vector2)} = ${this.position.associatedVariableName}.zx;\r\n            ${state._declareLocalVar(uvz, NodeMaterialBlockConnectionPointTypes.Vector2)} = ${this.position.associatedVariableName}.xy;\r\n        `;\r\n\r\n        if (this.projectAsCube) {\r\n            state.compilationString += `\r\n                ${uvx}.xy = ${uvx}.yx;\r\n\r\n                if (${n}.x >= 0.0) {\r\n                    ${uvx}.x = -${uvx}.x;\r\n                }\r\n                if (${n}.y < 0.0) {\r\n                    ${uvy}.y = -${uvy}.y;\r\n                }\r\n                if (${n}.z < 0.0) {\r\n                    ${uvz}.x = -${uvz}.x;\r\n                }\r\n            `;\r\n        }\r\n\r\n        const suffix = state.fSuffix;\r\n        const uniformPrefix = state.shaderLanguage === ShaderLanguage.WGSL ? \"uniforms.\" : \"\";\r\n        const mat2 = state.shaderLanguage === ShaderLanguage.WGSL ? \"mat2x2f\" : \"mat2\";\r\n\r\n        state.compilationString += `\r\n            // apply rotation\r\n            {\r\n            ${state._declareLocalVar(\"cosAngle\", NodeMaterialBlockConnectionPointTypes.Float)} = cos(${uniformPrefix}${this._textureInfoName}.y);\r\n            ${state._declareLocalVar(\"sinAngle\", NodeMaterialBlockConnectionPointTypes.Float)} = sin(${uniformPrefix}${this._textureInfoName}.y);\r\n            ${uvx} = ${mat2}(cosAngle, -sinAngle, sinAngle, cosAngle) * ${uvx};\r\n            cosAngle = cos(${uniformPrefix}${this._textureInfoName}.z);\r\n            sinAngle = sin(${uniformPrefix}${this._textureInfoName}.z);\r\n            ${uvy} = ${mat2}(cosAngle, sinAngle, -sinAngle, cosAngle) * ${uvy};\r\n            cosAngle = cos(${uniformPrefix}${this._textureInfoName}.w);\r\n            sinAngle = sin(${uniformPrefix}${this._textureInfoName}.w);\r\n            ${uvz} = ${mat2}(cosAngle, -sinAngle, sinAngle, cosAngle) * ${uvz};\r\n\r\n            // apply scaling\r\n            ${state._declareLocalVar(\"uvScale\", NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2${suffix}(${uniformPrefix}${this._textureInfoName2}.z, ${uniformPrefix}${this._textureInfoName2}.w);\r\n            ${uvx} = ${uvx} * uvScale;\r\n            ${uvy} = ${uvy} * uvScale;\r\n            ${uvz} = ${uvz} * uvScale;\r\n\r\n            // apply offset\r\n            ${state._declareLocalVar(\"offset\", NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2${suffix}(${uniformPrefix}${this._textureInfoName2}.x, ${uniformPrefix}${this._textureInfoName2}.y);\r\n            ${uvx} = ${uvx} + offset;\r\n            ${uvy} = ${uvy} + offset;\r\n            ${uvz} = ${uvz} + offset;\r\n            }\r\n        `;\r\n\r\n        state.compilationString += `\r\n            ${state._declareLocalVar(x, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(samplerName, uvx, state)};\r\n            ${state._declareLocalVar(y, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(samplerYName, uvy, state)};\r\n            ${state._declareLocalVar(z, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(samplerZName, uvz, state)};\r\n           \r\n            // blend weights\r\n            ${state._declareLocalVar(w, NodeMaterialBlockConnectionPointTypes.Vector3)} = pow(abs(${n}), vec3${suffix}(${sharpness}));\r\n\r\n            // blend and return\r\n            ${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = (${x}*${w}.x + ${y}*${w}.y + ${z}*${w}.z) / (${w}.x + ${w}.y + ${w}.z);        \r\n        `;\r\n    }\r\n\r\n    private _generateConversionCode(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string): void {\r\n        let vecSpecifier = \"\";\r\n\r\n        if (\r\n            state.shaderLanguage === ShaderLanguage.WGSL &&\r\n            (output.type === NodeMaterialBlockConnectionPointTypes.Vector3 || output.type === NodeMaterialBlockConnectionPointTypes.Color3)\r\n        ) {\r\n            vecSpecifier = \"Vec3\";\r\n        }\r\n\r\n        if (swizzle !== \"a\") {\r\n            // no conversion if the output is \"a\" (alpha)\r\n            if (!this.texture || !this.texture.gammaSpace) {\r\n                state.compilationString += `#ifdef ${this._linearDefineName}\r\n                    ${output.associatedVariableName} = toGammaSpace${vecSpecifier}(${output.associatedVariableName});\r\n                    #endif\r\n                `;\r\n            }\r\n\r\n            state.compilationString += `#ifdef ${this._gammaDefineName}\r\n                ${output.associatedVariableName} = toLinearSpace${vecSpecifier}(${output.associatedVariableName});\r\n                #endif\r\n            `;\r\n        }\r\n    }\r\n\r\n    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string) {\r\n        let complement = \"\";\r\n\r\n        if (!this.disableLevelMultiplication) {\r\n            complement = ` * ${state.shaderLanguage === ShaderLanguage.WGSL ? \"uniforms.\" : \"\"}${this._textureInfoName}.x`;\r\n        }\r\n\r\n        state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle}${complement};\\n`;\r\n        this._generateConversionCode(state, output, swizzle);\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (this.source.isConnected) {\r\n            this._imageSource = this.source.connectedPoint!.ownerBlock as ImageSourceBlock;\r\n        } else {\r\n            this._imageSource = null;\r\n        }\r\n\r\n        this._textureInfoName = state._getFreeVariableName(\"textureInfoName\");\r\n        this._textureInfoName2 = state._getFreeVariableName(\"textureInfoName2\");\r\n\r\n        this.level.associatedVariableName = (state.shaderLanguage === ShaderLanguage.WGSL ? \"uniforms.\" : \"\") + this._textureInfoName + \".x\";\r\n\r\n        this._tempTextureRead = state._getFreeVariableName(\"tempTextureRead\");\r\n        this._linearDefineName = state._getFreeDefineName(\"ISLINEAR\");\r\n        this._gammaDefineName = state._getFreeDefineName(\"ISGAMMA\");\r\n\r\n        if (!this._imageSource) {\r\n            this._samplerName = state._getFreeVariableName(this.name + \"Texture\");\r\n\r\n            state._emit2DSampler(this._samplerName);\r\n        }\r\n\r\n        // Declarations\r\n        state.sharedData.blockingBlocks.push(this);\r\n        state.sharedData.textureBlocks.push(this);\r\n        state.sharedData.blocksWithDefines.push(this);\r\n        state.sharedData.bindableBlocks.push(this);\r\n\r\n        const comments = `//${this.name}`;\r\n        state._emitFunctionFromInclude(\"helperFunctions\", comments);\r\n\r\n        state._emitUniformFromString(this._textureInfoName, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        state._emitUniformFromString(this._textureInfoName2, NodeMaterialBlockConnectionPointTypes.Vector4);\r\n\r\n        this._generateTextureLookup(state);\r\n\r\n        for (const output of this._outputs) {\r\n            if (output.hasEndpoints && output.name !== \"level\") {\r\n                this._writeOutput(state, output, output.name);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.convertToGammaSpace = ${this.convertToGammaSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.convertToLinearSpace = ${this.convertToLinearSpace};\\n`;\r\n        codeString += `${this._codeVariableName}.disableLevelMultiplication = ${this.disableLevelMultiplication};\\n`;\r\n        codeString += `${this._codeVariableName}.projectAsCube = ${this.projectAsCube};\\n`;\r\n\r\n        if (!this.texture) {\r\n            return codeString;\r\n        }\r\n\r\n        codeString += `${this._codeVariableName}.texture = new BABYLON.Texture(\"${this.texture.name}\", null, ${this.texture.noMipmap}, ${this.texture.invertY}, ${this.texture.samplingMode});\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wrapU = ${this.texture.wrapU};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wrapV = ${this.texture.wrapV};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uAng = ${this.texture.uAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vAng = ${this.texture.vAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.wAng = ${this.texture.wAng};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uOffset = ${this.texture.uOffset};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vOffset = ${this.texture.vOffset};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.uScale = ${this.texture.uScale};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.vScale = ${this.texture.vScale};\\n`;\r\n        codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.convertToGammaSpace = this.convertToGammaSpace;\r\n        serializationObject.convertToLinearSpace = this.convertToLinearSpace;\r\n        serializationObject.disableLevelMultiplication = this.disableLevelMultiplication;\r\n        serializationObject.projectAsCube = this.projectAsCube;\r\n        if (!this.hasImageSource && this.texture && !this.texture.isRenderTarget && this.texture.getClassName() !== \"VideoTexture\") {\r\n            serializationObject.texture = this.texture.serialize();\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.convertToGammaSpace = serializationObject.convertToGammaSpace;\r\n        this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;\r\n        this.disableLevelMultiplication = !!serializationObject.disableLevelMultiplication;\r\n        this.projectAsCube = !!serializationObject.projectAsCube;\r\n\r\n        if (serializationObject.texture && !NodeMaterial.IgnoreTexturesAtLoadTime && serializationObject.texture.url !== undefined) {\r\n            rootUrl = serializationObject.texture.url.indexOf(\"data:\") === 0 ? \"\" : rootUrl;\r\n            this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl) as Texture;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for triPlanarBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTriPlanarBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TriPlanarBlock\", TriPlanarBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { TriPlanarBlock } from \"./triPlanarBlock.pure\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { ShaderLanguage } from \"../../../Materials/shaderLanguage\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to read a texture with triplanar mapping (see https://iquilezles.org/articles/biplanar/)\r\n */\r\nexport class BiPlanarBlock extends TriPlanarBlock {\r\n    /**\r\n     * Create a new BiPlanarBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, true);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BiPlanarBlock\";\r\n    }\r\n\r\n    private _declareLocalVarAsVec3I(name: string, state: NodeMaterialBuildState): string {\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `var ${name}: vec3<i32>`;\r\n        } else {\r\n            return `ivec3 ${name}`;\r\n        }\r\n    }\r\n\r\n    private _getTextureGrad(state: NodeMaterialBuildState, samplerName: string) {\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            return `textureSampleGrad(${samplerName},${samplerName + Constants.AUTOSAMPLERSUFFIX}`;\r\n        }\r\n\r\n        return `textureGrad(${samplerName}`;\r\n    }\r\n\r\n    protected override _generateTextureLookup(state: NodeMaterialBuildState): void {\r\n        const samplerName = this.samplerName;\r\n        const samplerYName = this.samplerYName ?? this.samplerName;\r\n\r\n        const sharpness = this.sharpness.isConnected ? this.sharpness.associatedVariableName : \"1.0\";\r\n\r\n        const dpdx = state._getFreeVariableName(\"dxValue\");\r\n        const dpdy = state._getFreeVariableName(\"dyValue\");\r\n        const n = state._getFreeVariableName(\"n\");\r\n        const ma = state._getFreeVariableName(\"ma\");\r\n        const mi = state._getFreeVariableName(\"mi\");\r\n        const me = state._getFreeVariableName(\"me\");\r\n        const x = state._getFreeVariableName(\"x\");\r\n        const y = state._getFreeVariableName(\"y\");\r\n        const w = state._getFreeVariableName(\"w\");\r\n\r\n        let ivec3 = \"ivec3\";\r\n        let dpdxFunc = \"dFdx\";\r\n        let dpdyFunc = \"dFdy\";\r\n        const suffix = state.fSuffix;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            ivec3 = \"vec3<i32>\";\r\n            dpdxFunc = \"dpdx\";\r\n            dpdyFunc = \"dpdy\";\r\n        }\r\n\r\n        state.compilationString += `\r\n            // grab coord derivatives for texturing\r\n            ${state._declareLocalVar(dpdx, NodeMaterialBlockConnectionPointTypes.Vector3)} = ${dpdxFunc}(${this.position.associatedVariableName}.xyz);\r\n            ${state._declareLocalVar(dpdy, NodeMaterialBlockConnectionPointTypes.Vector3)} = ${dpdyFunc}(${this.position.associatedVariableName}.xyz);\r\n            ${state._declareLocalVar(n, NodeMaterialBlockConnectionPointTypes.Vector3)} = abs(${this.normal.associatedVariableName}.xyz);\r\n        \r\n            // determine major axis (in x; yz are following axis)\r\n            ${this._declareLocalVarAsVec3I(ma, state)} = ${state._generateTernary(\r\n                `${ivec3}(0,1,2)`,\r\n                `${state._generateTernary(`${ivec3}(1,2,0)`, `${ivec3}(2,0,1)`, `(${n}.y>${n}.z)`)}`,\r\n                `(${n}.x>${n}.y && ${n}.x>${n}.z)`\r\n            )};                    \r\n\r\n            // determine minor axis (in x; yz are following axis)\r\n            ${this._declareLocalVarAsVec3I(mi, state)} =  ${state._generateTernary(\r\n                `${ivec3}(0,1,2)`,\r\n                `${state._generateTernary(`${ivec3}(1,2,0)`, `${ivec3}(2,0,1)`, `(${n}.y<${n}.z)`)}`,\r\n                `(${n}.x<${n}.y && ${n}.x<${n}.z)`\r\n            )};  \r\n                              \r\n            // determine median axis (in x;  yz are following axis)\r\n            ${this._declareLocalVarAsVec3I(me, state)} = ${ivec3}(3) - ${mi} - ${ma};\r\n            \r\n            // project+fetch\r\n            ${state._declareLocalVar(x, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._getTextureGrad(state, samplerName)}, vec2${suffix}(${this.position.associatedVariableName}[${ma}.y], ${this.position.associatedVariableName}[${ma}.z]), \r\n                                    vec2${suffix}(${dpdx}[${ma}.y],${dpdx}[${ma}.z]), \r\n                                    vec2${suffix}(${dpdy}[${ma}.y],${dpdy}[${ma}.z]));\r\n            ${state._declareLocalVar(y, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._getTextureGrad(state, samplerYName)}, vec2${suffix}(${this.position.associatedVariableName}[${me}.y], ${this.position.associatedVariableName}[${me}.z]), \r\n                                    vec2${suffix}(${dpdx}[${me}.y],${dpdx}[${me}.z]),\r\n                                    vec2${suffix}(${dpdy}[${me}.y],${dpdy}[${me}.z]));\r\n            \r\n            // blend factors\r\n            ${state._declareLocalVar(w, NodeMaterialBlockConnectionPointTypes.Vector2)} = vec2${suffix}(${n}[${ma}.x],${n}[${me}.x]);\r\n            // make local support\r\n            ${w} = clamp( (${w}-0.5773)/(1.0-0.5773), vec2${suffix}(0.0), vec2${suffix}(1.0) );\r\n            // shape transition\r\n            ${w} = pow( ${w}, vec2${suffix}(${sharpness}/8.0) );\r\n            // blend and return\r\n            ${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = (${x}*${w}.x + ${y}*${w}.y) / (${w}.x + ${w}.y);\r\n        `;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for biPlanarBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBiPlanarBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BiPlanarBlock\", BiPlanarBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to compute the determinant of a matrix\r\n */\r\nexport class MatrixDeterminantBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MatrixDeterminantBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MatrixDeterminantBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input matrix\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this.output;\r\n        const input = this.input;\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = determinant(${input.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for matrixDeterminantBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMatrixDeterminantBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MatrixDeterminantBlock\", MatrixDeterminantBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to transpose a matrix\r\n */\r\nexport class MatrixTransposeBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MatrixTransposeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MatrixTransposeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input matrix\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this.output;\r\n        const input = this.input;\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = transpose(${input.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for matrixTransposeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMatrixTransposeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MatrixTransposeBlock\", MatrixTransposeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { MorphTargetsBlock } from \"./Vertex/morphTargetsBlock.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\nexport const enum MeshAttributeExistsBlockTypes {\r\n    None,\r\n    Normal,\r\n    Tangent,\r\n    VertexColor,\r\n    UV1,\r\n    UV2,\r\n    UV3,\r\n    UV4,\r\n    UV5,\r\n    UV6,\r\n}\r\n\r\n/**\r\n * Block used to check if Mesh attribute of specified type exists\r\n * and provide an alternative fallback input for to use in such case\r\n */\r\nexport class MeshAttributeExistsBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MeshAttributeExistsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"fallback\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        // Try to auto determine attributeType\r\n        this._inputs[0].onConnectionObservable.add((other) => {\r\n            if (this.attributeType) {\r\n                // But only if not already specified\r\n                return;\r\n            }\r\n            const sourceBlock = other.ownerBlock;\r\n            if (sourceBlock instanceof InputBlock && sourceBlock.isAttribute) {\r\n                switch (sourceBlock.name) {\r\n                    case \"color\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.VertexColor;\r\n                        break;\r\n                    case \"normal\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.Normal;\r\n                        break;\r\n                    case \"tangent\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.Tangent;\r\n                        break;\r\n                    case \"uv\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV1;\r\n                        break;\r\n                    case \"uv2\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV2;\r\n                        break;\r\n                    case \"uv3\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV3;\r\n                        break;\r\n                    case \"uv4\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV4;\r\n                        break;\r\n                    case \"uv5\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV5;\r\n                        break;\r\n                    case \"uv6\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV6;\r\n                        break;\r\n                }\r\n            } else if (sourceBlock instanceof MorphTargetsBlock) {\r\n                switch (this.input.connectedPoint?.name) {\r\n                    case \"normalOutput\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.Normal;\r\n                        break;\r\n                    case \"tangentOutput\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.Tangent;\r\n                        break;\r\n                    case \"uvOutput\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV1;\r\n                        break;\r\n                    case \"uv2Output\":\r\n                        this.attributeType = MeshAttributeExistsBlockTypes.UV2;\r\n                        break;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MeshAttributeExistsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Defines which mesh attribute to use\r\n     */\r\n    @editableInPropertyPage(\"Attribute lookup\", PropertyTypeForEdition.List, undefined, {\r\n        notifiers: { update: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"(None)\", value: MeshAttributeExistsBlockTypes.None },\r\n            { label: \"Normal\", value: MeshAttributeExistsBlockTypes.Normal },\r\n            { label: \"Tangent\", value: MeshAttributeExistsBlockTypes.Tangent },\r\n            { label: \"Vertex Color\", value: MeshAttributeExistsBlockTypes.VertexColor },\r\n            { label: \"UV1\", value: MeshAttributeExistsBlockTypes.UV1 },\r\n            { label: \"UV2\", value: MeshAttributeExistsBlockTypes.UV2 },\r\n            { label: \"UV3\", value: MeshAttributeExistsBlockTypes.UV3 },\r\n            { label: \"UV4\", value: MeshAttributeExistsBlockTypes.UV4 },\r\n            { label: \"UV5\", value: MeshAttributeExistsBlockTypes.UV5 },\r\n            { label: \"UV6\", value: MeshAttributeExistsBlockTypes.UV6 },\r\n        ],\r\n    })\r\n    public attributeType = MeshAttributeExistsBlockTypes.None;\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the fallback component when speciefied attribute doesn't exist\r\n     */\r\n    public get fallback(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        let attributeDefine: null | string = null;\r\n        switch (this.attributeType) {\r\n            case MeshAttributeExistsBlockTypes.VertexColor:\r\n                attributeDefine = \"VERTEXCOLOR_NME\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.Normal:\r\n                attributeDefine = \"NORMAL\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.Tangent:\r\n                attributeDefine = \"TANGENT\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.UV1:\r\n                attributeDefine = \"UV1\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.UV2:\r\n                attributeDefine = \"UV2\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.UV3:\r\n                attributeDefine = \"UV3\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.UV4:\r\n                attributeDefine = \"UV4\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.UV5:\r\n                attributeDefine = \"UV5\";\r\n                break;\r\n            case MeshAttributeExistsBlockTypes.UV6:\r\n                attributeDefine = \"UV6\";\r\n                break;\r\n        }\r\n\r\n        const output = state._declareOutput(this.output);\r\n        if (attributeDefine) {\r\n            state.compilationString += `#ifdef ${attributeDefine}\\n`;\r\n        }\r\n\r\n        state.compilationString += `${output} = ${this.input.associatedVariableName};\\n`;\r\n\r\n        if (attributeDefine) {\r\n            state.compilationString += `#else\\n`;\r\n            state.compilationString += `${output} = ${this.fallback.associatedVariableName};\\n`;\r\n            state.compilationString += `#endif\\n`;\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.attributeType = this.attributeType;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a serialization object\r\n     * @param serializationObject - the object to deserialize from\r\n     * @param scene - the current scene\r\n     * @param rootUrl - the root URL for loading\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.attributeType = serializationObject.attributeType ?? MeshAttributeExistsBlockTypes.None;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n\r\n        codeString += `${this._codeVariableName}.attributeType = ${this.attributeType};\\n`;\r\n\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshAttributeExistsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshAttributeExistsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MeshAttributeExistsBlock\", MeshAttributeExistsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Types of curves supported by the Curve block\r\n */\r\nexport enum CurveBlockTypes {\r\n    /** EaseInSine */\r\n    EaseInSine,\r\n    /** EaseOutSine */\r\n    EaseOutSine,\r\n    /** EaseInOutSine */\r\n    EaseInOutSine,\r\n    /** EaseInQuad */\r\n    EaseInQuad,\r\n    /** EaseOutQuad */\r\n    EaseOutQuad,\r\n    /** EaseInOutQuad */\r\n    EaseInOutQuad,\r\n    /** EaseInCubic */\r\n    EaseInCubic,\r\n    /** EaseOutCubic */\r\n    EaseOutCubic,\r\n    /** EaseInOutCubic */\r\n    EaseInOutCubic,\r\n    /** EaseInQuart */\r\n    EaseInQuart,\r\n    /** EaseOutQuart */\r\n    EaseOutQuart,\r\n    /** EaseInOutQuart */\r\n    EaseInOutQuart,\r\n    /** EaseInQuint */\r\n    EaseInQuint,\r\n    /** EaseOutQuint */\r\n    EaseOutQuint,\r\n    /** EaseInOutQuint */\r\n    EaseInOutQuint,\r\n    /** EaseInExpo */\r\n    EaseInExpo,\r\n    /** EaseOutExpo */\r\n    EaseOutExpo,\r\n    /** EaseInOutExpo */\r\n    EaseInOutExpo,\r\n    /** EaseInCirc */\r\n    EaseInCirc,\r\n    /** EaseOutCirc */\r\n    EaseOutCirc,\r\n    /** EaseInOutCirc */\r\n    EaseInOutCirc,\r\n    /** EaseInBack */\r\n    EaseInBack,\r\n    /** EaseOutBack */\r\n    EaseOutBack,\r\n    /** EaseInOutBack */\r\n    EaseInOutBack,\r\n    /** EaseInElastic */\r\n    EaseInElastic,\r\n    /** EaseOutElastic */\r\n    EaseOutElastic,\r\n    /** EaseInOutElastic */\r\n    EaseInOutElastic,\r\n}\r\n\r\n/**\r\n * Block used to apply curve operation\r\n */\r\nexport class CurveBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets the type of the curve applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"EaseInSine\", value: CurveBlockTypes.EaseInSine },\r\n            { label: \"EaseOutSine\", value: CurveBlockTypes.EaseOutSine },\r\n            { label: \"EaseInOutSine\", value: CurveBlockTypes.EaseInOutSine },\r\n            { label: \"EaseInQuad\", value: CurveBlockTypes.EaseInQuad },\r\n            { label: \"EaseOutQuad\", value: CurveBlockTypes.EaseOutQuad },\r\n            { label: \"EaseInOutQuad\", value: CurveBlockTypes.EaseInOutQuad },\r\n            { label: \"EaseInCubic\", value: CurveBlockTypes.EaseInCubic },\r\n            { label: \"EaseOutCubic\", value: CurveBlockTypes.EaseOutCubic },\r\n            { label: \"EaseInOutCubic\", value: CurveBlockTypes.EaseInOutCubic },\r\n            { label: \"EaseInQuart\", value: CurveBlockTypes.EaseInQuart },\r\n            { label: \"EaseOutQuart\", value: CurveBlockTypes.EaseOutQuart },\r\n            { label: \"EaseInOutQuart\", value: CurveBlockTypes.EaseInOutQuart },\r\n            { label: \"EaseInQuint\", value: CurveBlockTypes.EaseInQuint },\r\n            { label: \"EaseOutQuint\", value: CurveBlockTypes.EaseOutQuint },\r\n            { label: \"EaseInOutQuint\", value: CurveBlockTypes.EaseInOutQuint },\r\n            { label: \"EaseInExpo\", value: CurveBlockTypes.EaseInExpo },\r\n            { label: \"EaseOutExpo\", value: CurveBlockTypes.EaseOutExpo },\r\n            { label: \"EaseInOutExpo\", value: CurveBlockTypes.EaseInOutExpo },\r\n            { label: \"EaseInCirc\", value: CurveBlockTypes.EaseInCirc },\r\n            { label: \"EaseOutCirc\", value: CurveBlockTypes.EaseOutCirc },\r\n            { label: \"EaseInOutCirc\", value: CurveBlockTypes.EaseInOutCirc },\r\n            { label: \"EaseInBack\", value: CurveBlockTypes.EaseInBack },\r\n            { label: \"EaseOutBack\", value: CurveBlockTypes.EaseOutBack },\r\n            { label: \"EaseInOutBack\", value: CurveBlockTypes.EaseInOutBack },\r\n            { label: \"EaseInElastic\", value: CurveBlockTypes.EaseInElastic },\r\n            { label: \"EaseOutElastic\", value: CurveBlockTypes.EaseOutElastic },\r\n            { label: \"EaseInOutElastic\", value: CurveBlockTypes.EaseInOutElastic },\r\n        ],\r\n    })\r\n    public type = CurveBlockTypes.EaseInOutSine;\r\n\r\n    /**\r\n     * Creates a new CurveBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Object);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Int);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CurveBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _duplicateEntry(entry: string, component: string) {\r\n        return `ret.${component} = ${entry.replace(/VAL/g, \"v.\" + component)}`;\r\n    }\r\n\r\n    private _duplicateEntryDirect(entry: string) {\r\n        return `return ${entry.replace(/VAL/g, \"v\")}`;\r\n    }\r\n\r\n    private _duplicateVector(entry: string, inputType: string, isWGSL: boolean) {\r\n        if (inputType === \"float\" || inputType === \"f32\") {\r\n            return this._duplicateEntryDirect(entry);\r\n        }\r\n\r\n        const size = parseInt(inputType.replace(\"vec\", \"\"));\r\n        let code = isWGSL\r\n            ? `\r\n            var ret: vec${size}f = vec${size}f(0.0);\r\n        `\r\n            : `\r\n            vec${size} ret = vec${size}(0.0);\r\n        `;\r\n\r\n        for (let i = 1; i <= size; i++) {\r\n            code += this._duplicateEntry(entry, i === 1 ? \"x\" : i === 2 ? \"y\" : i === 3 ? \"z\" : \"w\") + \";\\n\";\r\n        }\r\n\r\n        code += \"return ret;\\n\";\r\n        return code;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        let registeredFunction: string;\r\n\r\n        const inputType = state._getShaderType(this.input.type);\r\n        const isWGSL = state.shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n        const registeredFunctionName = CurveBlockTypes[this.type] + \"_\" + inputType.replace(\"<\", \"\").replace(\">\", \"\");\r\n\r\n        switch (this.type) {\r\n            case CurveBlockTypes.EaseInSine:\r\n                registeredFunction = `return 1.0 - cos((v * 3.1415) / 2.0)`;\r\n                break;\r\n            case CurveBlockTypes.EaseOutSine:\r\n                registeredFunction = `return sin((v * 3.1415) / 2.0)`;\r\n                break;\r\n            case CurveBlockTypes.EaseInOutSine:\r\n                registeredFunction = `return -(cos(v * 3.1415) - 1.0) / 2.0`;\r\n                break;\r\n            case CurveBlockTypes.EaseInQuad:\r\n                registeredFunction = `return v * v`;\r\n                break;\r\n            case CurveBlockTypes.EaseOutQuad:\r\n                registeredFunction = `return (1.0 - v) * (1.0 - v)`;\r\n                break;\r\n            case CurveBlockTypes.EaseInOutQuad: {\r\n                const entry = state._generateTernary(\"2.0 * VAL * VAL\", \"1.0 - pow(-2.0 * VAL + 2.0, 2.0) / 2.0\", \"VAL < 0.5\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInCubic:\r\n                registeredFunction = `return v * v * v`;\r\n                break;\r\n            case CurveBlockTypes.EaseOutCubic: {\r\n                const entry = \"1.0 - pow(1.0 - VAL, 3.0)\";\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutCubic: {\r\n                const entry = state._generateTernary(\"4.0 * VAL * VAL * VAL\", \"1.0 - pow(-2.0 * VAL + 2.0, 3.0) / 2.0\", \"VAL < 0.5\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInQuart:\r\n                registeredFunction = `return v * v * v * v`;\r\n                break;\r\n            case CurveBlockTypes.EaseOutQuart: {\r\n                const entry = \"1.0 - pow(1.0 - VAL, 4.0)\";\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutQuart: {\r\n                const entry = state._generateTernary(\"8.0 * VAL * VAL * VAL * VAL\", \"1.0 - pow(-2.0 * VAL + 2.0, 4.0) / 2.0\", \"VAL < 0.5\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInQuint:\r\n                registeredFunction = `return v * v * v * v * v`;\r\n                break;\r\n            case CurveBlockTypes.EaseOutQuint: {\r\n                const entry = \"1.0 - pow(1.0 - VAL, 5.0)\";\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutQuint: {\r\n                const entry = state._generateTernary(\"16.0 * VAL * VAL * VAL * VAL * VAL\", \"1.0 - pow(-2.0 * VAL + 2.0, 5.0) / 2.0\", \"VAL < 0.5\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInExpo: {\r\n                const entry = state._generateTernary(\"0.0\", \"pow(2.0, 10.0 * VAL - 10.0)\", \"VAL == 0.0\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseOutExpo: {\r\n                const entry = state._generateTernary(\"1.0\", \"1.0 - pow(2.0, -10.0 * VAL)\", \"VAL == 1.0\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutExpo: {\r\n                const entry = state._generateTernary(\r\n                    \"0.0\",\r\n                    state._generateTernary(\r\n                        \"1.0\",\r\n                        state._generateTernary(\"pow(2.0, 20.0 * VAL - 10.0) / 2.0\", \"(2.0 - pow(2.0, -20.0 * VAL + 10.0)) / 2.0\", \"VAL < 0.5\"),\r\n                        \"VAL == 1.0\"\r\n                    ),\r\n                    \"VAL == 0.0\"\r\n                );\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInCirc: {\r\n                const entry = \"1.0 - sqrt(1.0 - pow(VAL, 2.0))\";\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseOutCirc: {\r\n                const entry = \"sqrt(1.0 - pow(VAL - 1.0, 2.0))\";\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutCirc: {\r\n                const entry = state._generateTernary(\"(1.0 - sqrt(1.0 - pow(2.0 * VAL, 2.0))) / 2.0\", \"(sqrt(1.0 - pow(-2.0 * VAL + 2.0, 2.0)) + 1.0) / 2.0\", \"VAL < 0.5\");\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInBack: {\r\n                registeredFunction = \"return 2.70158 * v * v * v - 1.70158 * v * v\";\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseOutBack: {\r\n                const entry = \"2.70158 * pow(VAL - 1.0, 3.0) + 1.70158 * pow(VAL - 1.0, 2.0)\";\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutBack: {\r\n                const entry = state._generateTernary(\r\n                    \"(pow(2.0 * VAL, 2.0) * ((3.5949095) * 2.0 * VAL - 2.5949095)) / 2.0\",\r\n                    \"(pow(2.0 * VAL - 2.0, 2.0) * (3.5949095 * (VAL * 2.0 - 2.0) + 3.5949095) + 2.0) / 2.0\",\r\n                    \"VAL < 0.5\"\r\n                );\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInElastic: {\r\n                const entry = state._generateTernary(\r\n                    \"0.0\",\r\n                    state._generateTernary(\"1.0\", \"-pow(2.0, 10.0 * VAL - 10.0) * sin((VAL * 10.0 - 10.75) * ((2.0 * 3.1415) / 3.0))\", \"VAL == 1.0\"),\r\n                    \"VAL == 0.0\"\r\n                );\r\n\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseOutElastic: {\r\n                const entry = state._generateTernary(\r\n                    \"0.0\",\r\n                    state._generateTernary(\"1.0\", \"pow(2.0, -10.0 * VAL) * sin((VAL * 10.0 - 0.75) * ((2.0 * 3.1415) / 3.0)) + 1.0\", \"VAL == 1.0\"),\r\n                    \"VAL == 0.0\"\r\n                );\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n            case CurveBlockTypes.EaseInOutElastic: {\r\n                const entry = state._generateTernary(\r\n                    \"0.0\",\r\n                    state._generateTernary(\r\n                        \"1.0\",\r\n                        state._generateTernary(\r\n                            \"-(pow(2.0, 20.0 * VAL - 10.0) * sin((20.0 * VAL - 11.125) * ((2.0 * 3.1415) / 4.5))) / 2.0\",\r\n                            \"(pow(2.0, -20.0 * VAL + 10.0) * sin((20.0 * VAL - 11.125) * ((2.0 * 3.1415) / 4.5))) / 2.0 + 1.0\",\r\n                            \"VAL < 0.5\"\r\n                        ),\r\n                        \"VAL == 1.0\"\r\n                    ),\r\n                    \"VAL == 0.0\"\r\n                );\r\n\r\n                registeredFunction = this._duplicateVector(entry, inputType, isWGSL);\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (isWGSL) {\r\n            state._emitFunction(registeredFunctionName, `fn ${registeredFunctionName}(v: ${inputType}) -> ${inputType}  {${registeredFunction};}\\n`, \"\");\r\n        } else {\r\n            state._emitFunction(registeredFunctionName, `${inputType} ${registeredFunctionName}(${inputType} v) {${registeredFunction};}\\n`, \"\");\r\n        }\r\n\r\n        state.compilationString += state._declareOutput(output) + ` = ${registeredFunctionName}(${this.input.associatedVariableName});\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.curveType = this.type;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.type = serializationObject.curveType;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.type = BABYLON.CurveBlockTypes.${CurveBlockTypes[this.type]};\\n`;\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for curveBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCurveBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CurveBlock\", CurveBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to apply rgb/hsl convertions\r\n */\r\nexport class ColorConverterBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Create a new ColorConverterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"rgb \", NodeMaterialBlockConnectionPointTypes.Color3, true);\r\n        this.registerInput(\"hsl \", NodeMaterialBlockConnectionPointTypes.Color3, true);\r\n\r\n        this.registerOutput(\"rgb\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n        this.registerOutput(\"hsl\", NodeMaterialBlockConnectionPointTypes.Color3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ColorConverterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb value (input)\r\n     */\r\n    public get rgbIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the hsl value (input)\r\n     */\r\n    public get hslIn(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb value (output)\r\n     */\r\n    public get rgbOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the hsl value (output)\r\n     */\r\n    public get hslOut(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"rgb \") {\r\n            return \"rgbIn\";\r\n        }\r\n        if (name === \"hsl \") {\r\n            return \"hslIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _outputRename(name: string) {\r\n        if (name === \"rgb\") {\r\n            return \"rgbOut\";\r\n        }\r\n        if (name === \"hsl\") {\r\n            return \"hslOut\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const rgbInput = this.rgbIn;\r\n        const hslInput = this.hslIn;\r\n\r\n        const rbgOutput = this._outputs[0];\r\n        const hslOutput = this._outputs[1];\r\n\r\n        const vec3 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector3);\r\n\r\n        let rgb2hsl = `\r\n            vec3 rgb2hsl(vec3 color) {\r\n                float r = color.r;\r\n                float g = color.g;\r\n                float b = color.b;\r\n\r\n                float maxc = max(r, max(g, b));\r\n                float minc = min(r, min(g, b));\r\n                float h = 0.0;\r\n                float s = 0.0;\r\n                float l = (maxc + minc) / 2.0;\r\n\r\n                if (maxc != minc) {\r\n                    float d = maxc - minc;\r\n                    if (l > 0.5) {\r\n                        s = d / (2.0 - maxc - minc);\r\n                    } else {\r\n                        s = d / (maxc + minc);\r\n                    }\r\n\r\n                    if (maxc == r) {\r\n                        float add = 0.0;\r\n                        if (g < b) {\r\n                            add = 6.0;\r\n                        }\r\n                        h = (g - b) / d + add;\r\n                    } else if (maxc == g) {\r\n                        h = (b - r) / d + 2.0;\r\n                    } else if (maxc == b) {\r\n                        h = (r - g) / d + 4.0;\r\n                    }\r\n                    h /= 6.0;\r\n                }\r\n\r\n                return vec3(h, s, l);\r\n            }`;\r\n\r\n        let hue2rgb = `\r\n            float hue2rgb(float p, float q, float tt) {\r\n                float t = tt;\r\n                if (t < 0.0) {\r\n                    t += 1.0;\r\n                }\r\n                if (t > 1.0) {\r\n                    t -= 1.0;\r\n                }\r\n                if (t < 1.0/6.0) {\r\n                    return p + (q - p) * 6.0 * t;\r\n                }\r\n                if (t < 1.0/2.0) {\r\n                    return q;\r\n                }\r\n                if (t < 2.0/3.0) {\r\n                    return p + (q - p) * (2.0/3.0 - t) * 6.0;\r\n                }\r\n                return p;\r\n            }`;\r\n\r\n        let hsl2rgb = `\r\n            vec3 hsl2rgb(vec3 hsl) {\r\n                float h = hsl.x;\r\n                float s = hsl.y;\r\n                float l = hsl.z;\r\n\r\n                float r;\r\n                float g;\r\n                float b;\r\n\r\n                if (s == 0.0) {\r\n                    // Achromatic (grey)\r\n                    r = l;\r\n                    g = l;\r\n                    b = l; \r\n                } else {\r\n                    float q;\r\n                \r\n                    if (l < 0.5) {\r\n                        q = l * (1.0 + s);\r\n                    } else {\r\n                        q = (l + s - l * s);\r\n                    }\r\n\r\n                    float p = 2.0 * l - q;\r\n\r\n                    r = hue2rgb(p, q, h + 1.0/3.0);\r\n                    g = hue2rgb(p, q, h);\r\n                    b = hue2rgb(p, q, h - 1.0/3.0);\r\n                }\r\n\r\n                return vec3(r, g, b);\r\n            }`;\r\n\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            rgb2hsl = state._babylonSLtoWGSL(rgb2hsl);\r\n            hue2rgb = state._babylonSLtoWGSL(hue2rgb);\r\n            hsl2rgb = state._babylonSLtoWGSL(hsl2rgb);\r\n        }\r\n\r\n        state._emitFunction(\"rgb2hsl\", rgb2hsl, \"\");\r\n        state._emitFunction(\"hue2rgb\", hue2rgb, \"\");\r\n        state._emitFunction(\"hsl2rgb\", hsl2rgb, \"\");\r\n\r\n        if (rgbInput.isConnected) {\r\n            if (rbgOutput.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(rbgOutput) + ` = ${rgbInput.associatedVariableName};\\n`;\r\n            }\r\n\r\n            if (hslOutput.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(hslOutput) + ` = rgb2hsl(${rgbInput.associatedVariableName});\\n`;\r\n            }\r\n        } else if (hslInput.isConnected) {\r\n            if (rbgOutput.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(rbgOutput) + ` = hsl2rgb(${hslInput.associatedVariableName});\\n`;\r\n            }\r\n            if (hslOutput.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(hslOutput) + ` = ${hslInput.associatedVariableName};\\n`;\r\n            }\r\n        } else {\r\n            if (rbgOutput.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(rbgOutput) + ` =  ${vec3}(0.);\\n`;\r\n            }\r\n\r\n            if (hslOutput.hasEndpoints) {\r\n                state.compilationString += state._declareOutput(hslOutput) + ` =  ${vec3}(0.);\\n`;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for colorConverterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterColorConverterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ColorConverterBlock\", ColorConverterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../nodeMaterialConnectionPointCustomObject\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to repeat code\r\n */\r\nexport class LoopBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Gets or sets number of iterations\r\n     * Will be ignored if the iterations input is connected\r\n     */\r\n    @editableInPropertyPage(\"Iterations\", PropertyTypeForEdition.Int, undefined, { embedded: true })\r\n    public iterations = 4;\r\n\r\n    /**\r\n     * Creates a new LoopBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"iterations\", NodeMaterialBlockConnectionPointTypes.Float, true);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.BasedOnInput);\r\n        this.registerOutput(\"index\", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);\r\n        this.registerOutput(\r\n            \"loopID\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            undefined,\r\n            new NodeMaterialConnectionPointCustomObject(\"loopID\", this, NodeMaterialConnectionPointDirection.Output, LoopBlock, \"LoopBlock\")\r\n        );\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._outputs[0]._forPostBuild = true;\r\n\r\n        this._outputs[2]._redirectedSource = this._inputs[0];\r\n\r\n        this._outputs[1]._preventBubbleUp = true;\r\n        this._outputs[2]._preventBubbleUp = true;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"LoopBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the main input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the iterations input component\r\n     */\r\n    public get iterationsInput(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the index component which will be incremented at each iteration\r\n     */\r\n    public get index(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the loop ID component\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get loopID(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const index = this._outputs[1];\r\n\r\n        const indexName = state._getFreeVariableName(\"index\");\r\n\r\n        const decl = state.shaderLanguage === ShaderLanguage.WGSL ? \"var\" : \"int\";\r\n        const castFloat = state.shaderLanguage === ShaderLanguage.WGSL ? \"f32\" : \"float\";\r\n        const castInt = state.shaderLanguage === ShaderLanguage.WGSL ? \"i32\" : \"int\";\r\n\r\n        // Declare storage variable and store initial value\r\n        state.compilationString += state._declareOutput(output) + ` = ${this.input.associatedVariableName};\\n`;\r\n\r\n        // Iterations\r\n        const iterations = this.iterationsInput.isConnected ? `${castInt}(${this.iterationsInput.associatedVariableName})` : this.iterations;\r\n\r\n        // Loop\r\n        state.compilationString += `for (${decl} ${indexName} = 0; ${indexName} < ${iterations}; ${indexName}++){\\n`;\r\n        state.compilationString += `${state._declareOutput(index)} = ${castFloat}(${indexName});\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _postBuildBlock(state: NodeMaterialBuildState) {\r\n        super._postBuildBlock(state);\r\n\r\n        state.compilationString += `}\\n`;\r\n\r\n        return this;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        return super._dumpPropertiesCode() + `${this._codeVariableName}.iterations = ${this.iterations};\\n`;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.iterations = this.iterations;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.iterations = serializationObject.iterations;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for loopBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLoopBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.LoopBlock\", LoopBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { LoopBlock } from \"./loopBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../nodeMaterialConnectionPointCustomObject\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to read from a variable within a loop\r\n */\r\nexport class StorageReadBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new StorageReadBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\r\n            \"loopID\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            false,\r\n            undefined,\r\n            new NodeMaterialConnectionPointCustomObject(\"loopID\", this, NodeMaterialConnectionPointDirection.Input, LoopBlock, \"LoopBlock\")\r\n        );\r\n        this.registerOutput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this._outputs[0]._linkedConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"StorageReadBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the loop link component\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get loopID(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the value component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const value = this.value;\r\n\r\n        if (!this.loopID.isConnected) {\r\n            return this;\r\n        }\r\n\r\n        const loopBlock = this.loopID.connectedPoint!.ownerBlock as LoopBlock;\r\n\r\n        state.compilationString += state._declareOutput(value) + ` = ${loopBlock.output.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for storageReadBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStorageReadBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.StorageReadBlock\", StorageReadBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialConnectionPointDirection, type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { LoopBlock } from \"./loopBlock.pure\";\r\nimport { NodeMaterialConnectionPointCustomObject } from \"../nodeMaterialConnectionPointCustomObject\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to write to a variable within a loop\r\n */\r\nexport class StorageWriteBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new StorageWriteBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\r\n            \"loopID\",\r\n            NodeMaterialBlockConnectionPointTypes.Object,\r\n            false,\r\n            undefined,\r\n            new NodeMaterialConnectionPointCustomObject(\"loopID\", this, NodeMaterialConnectionPointDirection.Input, LoopBlock, \"LoopBlock\")\r\n        );\r\n        this.registerInput(\"value\", NodeMaterialBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"StorageWriteBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the loop link component\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get loopID(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the value component\r\n     */\r\n    public get value(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /** Gets a boolean indicating that this connection will be used in the fragment shader\r\n     * @returns true if connected in fragment shader\r\n     */\r\n    public override isConnectedInFragmentShader() {\r\n        if (!this.loopID.isConnected) {\r\n            return false;\r\n        }\r\n        const loopBlock = this.loopID.connectedPoint!.ownerBlock as LoopBlock;\r\n\r\n        return loopBlock.output.isConnectedInFragmentShader;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const value = this.value;\r\n\r\n        if (!this.loopID.isConnected) {\r\n            return this;\r\n        }\r\n\r\n        const loopBlock = this.loopID.connectedPoint!.ownerBlock as LoopBlock;\r\n\r\n        state.compilationString += `${loopBlock.output.associatedVariableName} = ${value.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for storageWriteBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStorageWriteBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.StorageWriteBlock\", StorageWriteBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to split a matrix into Vector4\r\n */\r\nexport class MatrixSplitterBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new MatrixSplitterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"input\", NodeMaterialBlockConnectionPointTypes.Matrix);\r\n        this.registerOutput(\"row0\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"row1\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"row2\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"row3\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"col0\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"col1\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"col2\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"col3\", NodeMaterialBlockConnectionPointTypes.Vector4);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MatrixSplitterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the row0 output vector\r\n     */\r\n    public get row0(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the row1 output vector\r\n     */\r\n    public get row1(): NodeMaterialConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the row2 output vector\r\n     */\r\n    public get row2(): NodeMaterialConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the row3 output vector\r\n     */\r\n    public get row3(): NodeMaterialConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the col0 output vector\r\n     */\r\n    public get col0(): NodeMaterialConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the col1 output vector\r\n     */\r\n    public get col1(): NodeMaterialConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the col2 output vector\r\n     */\r\n    public get col2(): NodeMaterialConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the col3 output vector\r\n     */\r\n    public get col3(): NodeMaterialConnectionPoint {\r\n        return this._outputs[7];\r\n    }\r\n\r\n    private _exportColumn(state: NodeMaterialBuildState, col: NodeMaterialConnectionPoint, input: string, columnIndex: number) {\r\n        const vec4 = state.shaderLanguage === ShaderLanguage.WGSL ? \"vec4f\" : \"vec4\";\r\n        state.compilationString +=\r\n            state._declareOutput(col) + ` = ${vec4}(${input}[0][${columnIndex}], ${input}[1][${columnIndex}], ${input}[2][${columnIndex}], ${input}[3][${columnIndex}]);\\n`;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const input = this._inputs[0].associatedVariableName;\r\n\r\n        const row0 = this.row0;\r\n        const row1 = this.row1;\r\n        const row2 = this.row2;\r\n        const row3 = this.row3;\r\n        const col0 = this.col0;\r\n        const col1 = this.col1;\r\n        const col2 = this.col2;\r\n        const col3 = this.col3;\r\n\r\n        if (row0.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(row0) + ` = ${input}[0];\\n`;\r\n        }\r\n        if (row1.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(row1) + ` = ${input}[1];\\n`;\r\n        }\r\n        if (row2.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(row2) + ` = ${input}[2];\\n`;\r\n        }\r\n        if (row3.hasEndpoints) {\r\n            state.compilationString += state._declareOutput(row3) + ` = ${input}[3];\\n`;\r\n        }\r\n\r\n        if (col0.hasEndpoints) {\r\n            this._exportColumn(state, col0, input, 0);\r\n        }\r\n        if (col1.hasEndpoints) {\r\n            this._exportColumn(state, col1, input, 1);\r\n        }\r\n        if (col2.hasEndpoints) {\r\n            this._exportColumn(state, col2, input, 2);\r\n        }\r\n        if (col3.hasEndpoints) {\r\n            this._exportColumn(state, col3, input, 3);\r\n        }\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for matrixSplitterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMatrixSplitterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MatrixSplitterBlock\", MatrixSplitterBlock);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"gaussianSplattingVertexDeclaration\";\nconst shader = `attribute position: vec3f;attribute splatIndex0: vec4f;attribute splatIndex1: vec4f;attribute splatIndex2: vec4f;attribute splatIndex3: vec4f;`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingVertexDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"gaussianSplatting\";\nconst shader = `fn getDataUV(index: f32,dataTextureSize: vec2f)->vec2<f32> {let y: f32=floor(index/dataTextureSize.x);let x: f32=index-y*dataTextureSize.x;return vec2f((x+0.5),(y+0.5));}\nstruct Splat {center: vec4f,\ncolor: vec4f,\ncovA: vec4f,\ncovB: vec4f,\n#if SH_DEGREE>0\nsh0: vec4<u32>,\n#endif\n#if SH_DEGREE>1\nsh1: vec4<u32>,\n#endif\n#if SH_DEGREE>2\nsh2: vec4<u32>,\n#endif\n#if SH_DEGREE>3\nsh3: vec4<u32>,\nsh4: vec4<u32>,\n#endif\n#if IS_COMPOUND\npartIndex: u32,\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nrotationA: vec4f,\nrotationB: vec4f,\nrotationScale: vec4f,\n#endif\n#ifdef USE_SOG\nsplatIndex: f32,\n#endif\n};fn getSplatIndex(localIndex: i32,splatIndex0: vec4f,splatIndex1: vec4f,splatIndex2: vec4f,splatIndex3: vec4f)->f32 {var splatIndex: f32;switch (localIndex)\n{case 0:\n{splatIndex=splatIndex0.x;break;}\ncase 1:\n{splatIndex=splatIndex0.y;break;}\ncase 2:\n{splatIndex=splatIndex0.z;break;}\ncase 3:\n{splatIndex=splatIndex0.w;break;}\ncase 4:\n{splatIndex=splatIndex1.x;break;}\ncase 5:\n{splatIndex=splatIndex1.y;break;}\ncase 6:\n{splatIndex=splatIndex1.z;break;}\ncase 7:\n{splatIndex=splatIndex1.w;break;}\ncase 8:\n{splatIndex=splatIndex2.x;break;}\ncase 9:\n{splatIndex=splatIndex2.y;break;}\ncase 10:\n{splatIndex=splatIndex2.z;break;}\ncase 11:\n{splatIndex=splatIndex2.w;break;}\ncase 12:\n{splatIndex=splatIndex3.x;break;}\ncase 13:\n{splatIndex=splatIndex3.y;break;}\ncase 14:\n{splatIndex=splatIndex3.z;break;}\ndefault:\n{splatIndex=splatIndex3.w;break;}}\nreturn splatIndex;}\nfn readSplat(splatIndex: f32,dataTextureSize: vec2f)->Splat {var splat: Splat;let splatUV=getDataUV(splatIndex,dataTextureSize);let splatUVi32=vec2<i32>(i32(splatUV.x),i32(splatUV.y));\n#ifdef USE_SOG\nlet mL=textureLoad(centersTexture,splatUVi32,0);let mU=textureLoad(covariancesATexture,splatUVi32,0);let sRaw=textureLoad(covariancesBTexture,splatUVi32,0);let qRaw=textureLoad(sogQuatsTexture,splatUVi32,0);let c0=textureLoad(colorsTexture,splatUVi32,0);let q16=(mU.xyz*256.0+mL.xyz)*(255.0/65535.0);let nPos=mix(uniforms.sogMeansMin,uniforms.sogMeansMax,q16);let center3=sign(nPos)*(exp(abs(nPos))-vec3f(1.0));splat.center=vec4f(center3,1.0);\n#ifdef USE_SOG_V2\nlet sIdx=floor(sRaw.xyz*255.0+0.5);var splatScale: vec3f;splatScale.x=exp(textureLoad(sogCodebookTexture,vec2<i32>(i32(sIdx.x),0),0).r);splatScale.y=exp(textureLoad(sogCodebookTexture,vec2<i32>(i32(sIdx.y),0),0).r);splatScale.z=exp(textureLoad(sogCodebookTexture,vec2<i32>(i32(sIdx.z),0),0).r);\n#else\nlet splatScale=exp(mix(uniforms.sogScalesMin,uniforms.sogScalesMax,sRaw.xyz));\n#endif\nlet invSqrt2: f32=0.70710678118;let qabc=(qRaw.xyz-vec3f(0.5))*2.0*invSqrt2;let qMode=i32(qRaw.w*255.0+0.5)-252;let qd=sqrt(max(0.0,1.0-dot(qabc,qabc)));var quat: vec4f;if (qMode==0) { quat=vec4f(qd,qabc.x,qabc.y,qabc.z); }\nelse if (qMode==1) { quat=vec4f(qabc.x,qd,qabc.y,qabc.z); }\nelse if (qMode==2) { quat=vec4f(qabc.x,qabc.y,qd,qabc.z); }\nelse { quat=vec4f(qabc.x,qabc.y,qabc.z,qd); }\nlet qw=quat.x; let qx=quat.y; let qy=quat.z; let qz=quat.w;let R=mat3x3<f32>(\n1.0-2.0*(qy*qy+qz*qz),2.0*(qx*qy+qw*qz), 2.0*(qx*qz-qw*qy),\n2.0*(qx*qy-qw*qz), 1.0-2.0*(qx*qx+qz*qz),2.0*(qy*qz+qw*qx),\n2.0*(qx*qz+qw*qy), 2.0*(qy*qz-qw*qx), 1.0-2.0*(qx*qx+qy*qy)\n);let S2=mat3x3<f32>(\n4.0*splatScale.x*splatScale.x,0.0,0.0,\n0.0,4.0*splatScale.y*splatScale.y,0.0,\n0.0,0.0,4.0*splatScale.z*splatScale.z\n);let Sigma=R*S2*transpose(R);splat.covA=vec4f(Sigma[0][0],Sigma[0][1],Sigma[0][2],Sigma[1][1]);splat.covB=vec4f(Sigma[1][2],Sigma[2][2],0.0,0.0);let SH_C0_SOG: f32=0.28209479177387814;\n#ifdef USE_SOG_V2\nvar c3: vec3f;c3.x=textureLoad(sogCodebookTexture,vec2<i32>(256+i32(c0.x*255.0+0.5),0),0).r;c3.y=textureLoad(sogCodebookTexture,vec2<i32>(256+i32(c0.y*255.0+0.5),0),0).r;c3.z=textureLoad(sogCodebookTexture,vec2<i32>(256+i32(c0.z*255.0+0.5),0),0).r;let colRgb=vec3f(0.5)+c3*SH_C0_SOG;let colA=c0.w;\n#else\nlet cLerp=mix(uniforms.sogSh0Min,uniforms.sogSh0Max,c0);let colRgb=vec3f(0.5)+cLerp.xyz*SH_C0_SOG;let colA=1.0/(1.0+exp(-cLerp.w));\n#endif\nsplat.color=vec4f(colRgb,colA);splat.splatIndex=splatIndex;\n#else\nsplat.center=textureLoad(centersTexture,splatUVi32,0);splat.color=textureLoad(colorsTexture,splatUVi32,0);\n#if !defined(IS_FOR_VOXELIZATION)\nsplat.covA=textureLoad(covariancesATexture,splatUVi32,0)*splat.center.w;splat.covB=textureLoad(covariancesBTexture,splatUVi32,0)*splat.center.w;\n#endif\n#endif\n#if SH_DEGREE>0 && !defined(USE_SOG)\nsplat.sh0=textureLoad(shTexture0,splatUVi32,0);\n#endif\n#if SH_DEGREE>1 && !defined(USE_SOG)\nsplat.sh1=textureLoad(shTexture1,splatUVi32,0);\n#endif\n#if SH_DEGREE>2 && !defined(USE_SOG)\nsplat.sh2=textureLoad(shTexture2,splatUVi32,0);\n#endif\n#if SH_DEGREE>3 && !defined(USE_SOG)\nsplat.sh3=textureLoad(shTexture3,splatUVi32,0);splat.sh4=textureLoad(shTexture4,splatUVi32,0);\n#endif\n#if IS_COMPOUND\nsplat.partIndex=u32(textureLoad(partIndicesTexture,splatUVi32,0).r*255.0+0.5);\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nsplat.rotationA=textureLoad(rotationsATexture,splatUVi32,0);splat.rotationB=textureLoad(rotationsBTexture,splatUVi32,0);splat.rotationScale=textureLoad(rotationScaleTexture,splatUVi32,0);\n#endif\nreturn splat;}\nfn computeColorFromSHDegree(dir: vec3f,sh: array<vec3<f32>,25>,_so1: f32,_so2: f32,_so3: f32,_so4: f32)->vec3f\n{let SH_C0: f32=0.28209479;let SH_C1: f32=0.48860251;var SH_C2: array<f32,5>=array<f32,5>(\n1.092548430,\n-1.09254843,\n0.315391565,\n-1.09254843,\n0.546274215\n);var SH_C3: array<f32,7>=array<f32,7>(\n-0.59004358,\n2.890611442,\n-0.45704579,\n0.373176332,\n-0.45704579,\n1.445305721,\n-0.59004358\n);var SH_C4: array<f32,9>=array<f32,9>(\n2.5033429418,\n-1.7701307698,\n0.9461746958,\n-0.6690465436,\n0.1057855469,\n-0.6690465436,\n0.4730873479,\n-1.7701307698,\n0.6258357354\n);var result: vec3f=/*SH_C0**/sh[0];\n#if SH_DEGREE>0\nlet x: f32=dir.x;let y: f32=dir.y;let z: f32=dir.z;result+=_so1*(-SH_C1*y*sh[1]+SH_C1*z*sh[2]-SH_C1*x*sh[3]);\n#if SH_DEGREE>1\nlet xx: f32=x*x;let yy: f32=y*y;let zz: f32=z*z;let xy: f32=x*y;let yz: f32=y*z;let xz: f32=x*z;result+=_so2*(\nSH_C2[0]*xy*sh[4] +\nSH_C2[1]*yz*sh[5] +\nSH_C2[2]*(2.0f*zz-xx-yy)*sh[6] +\nSH_C2[3]*xz*sh[7] +\nSH_C2[4]*(xx-yy)*sh[8]);\n#if SH_DEGREE>2\nresult+=_so3*(\nSH_C3[0]*y*(3.0f*xx-yy)*sh[9] +\nSH_C3[1]*xy*z*sh[10] +\nSH_C3[2]*y*(4.0f*zz-xx-yy)*sh[11] +\nSH_C3[3]*z*(2.0f*zz-3.0f*xx-3.0f*yy)*sh[12] +\nSH_C3[4]*x*(4.0f*zz-xx-yy)*sh[13] +\nSH_C3[5]*z*(xx-yy)*sh[14] +\nSH_C3[6]*x*(xx-3.0f*yy)*sh[15]);\n#if SH_DEGREE>3\nresult+=_so4*(\nSH_C4[0]*x*y*(xx-yy)*sh[16] +\nSH_C4[1]*y*z*(3.0f*xx-yy)*sh[17] +\nSH_C4[2]*x*y*(7.0f*zz-1.0f)*sh[18] +\nSH_C4[3]*y*z*(7.0f*zz-3.0f)*sh[19] +\nSH_C4[4]*(zz*(35.0f*zz-30.0f)+3.0f)*sh[20] +\nSH_C4[5]*x*z*(7.0f*zz-3.0f)*sh[21] +\nSH_C4[6]*(xx-yy)*(7.0f*zz-1.0f)*sh[22] +\nSH_C4[7]*x*z*(xx-3.0f*yy)*sh[23] +\nSH_C4[8]*(xx*(xx-3.0f*yy)-yy*(3.0f*xx-yy))*sh[24]);\n#endif\n#endif\n#endif\n#endif\nreturn result;}\nfn decompose(value: u32)->vec4f\n{let components : vec4f=vec4f(\nf32((value ) & 255u),\nf32((value>>u32( 8)) & 255u),\nf32((value>>u32(16)) & 255u),\nf32((value>>u32(24)) & 255u));return components*vec4f(2./255.)-vec4f(1.);}\n#ifdef USE_SOG\nfn computeSH(splat: Splat,dir: vec3f)->vec3f\n{\n#if SH_DEGREE>0\nvar sh: array<vec3<f32>,25>;sh[0]=vec3f(0.,0.,0.);let labelSize=textureDimensions(sogShNLabelsTexture,0);let idx=i32(splat.splatIndex+0.5);let lw=i32(labelSize.x);let lx=idx-(idx/lw)*lw;let ly=idx/lw;let labelRaw=textureLoad(sogShNLabelsTexture,vec2<i32>(lx,ly),0);let n=i32(labelRaw.r*255.0+0.5)+i32(labelRaw.g*255.0+0.5)*256;let coeffs=i32(uniforms.sogShCoeffCount+0.5);let u=(n-(n/64)*64)*coeffs;let v=n/64;for (var k: i32=0; k<24; k=k+1) {if (k>=coeffs) { break; }\nlet centroidRaw=textureLoad(sogShNCentroidsTexture,vec2<i32>(u+k,v),0);var shCoeff: vec3f;\n#ifdef USE_SOG_V2\nlet rIdx=i32(centroidRaw.r*255.0+0.5);let gIdx=i32(centroidRaw.g*255.0+0.5);let bIdx=i32(centroidRaw.b*255.0+0.5);shCoeff.r=textureLoad(sogCodebookTexture,vec2<i32>(512+rIdx,0),0).r;shCoeff.g=textureLoad(sogCodebookTexture,vec2<i32>(512+gIdx,0),0).r;shCoeff.b=textureLoad(sogCodebookTexture,vec2<i32>(512+bIdx,0),0).r;\n#else\nshCoeff=mix(vec3f(uniforms.sogShnMin),vec3f(uniforms.sogShnMax),centroidRaw.rgb);\n#endif\nsh[k+1]=shCoeff;}\nreturn computeColorFromSHDegree(dir,sh,1.,1.,1.,1.);\n#else\nreturn vec3f(0.,0.,0.);\n#endif\n}\n#else\nfn computeSHWeighted(splat: Splat,dir: vec3f,_so1: f32,_so2: f32,_so3: f32,_so4: f32)->vec3f\n{var sh: array<vec3<f32>,25>;sh[0]=vec3f(0.,0.,0.);\n#if SH_DEGREE>0\nlet sh00: vec4f=decompose(splat.sh0.x);let sh01: vec4f=decompose(splat.sh0.y);let sh02: vec4f=decompose(splat.sh0.z);sh[1]=vec3f(sh00.x,sh00.y,sh00.z);sh[2]=vec3f(sh00.w,sh01.x,sh01.y);sh[3]=vec3f(sh01.z,sh01.w,sh02.x);\n#endif\n#if SH_DEGREE>1\nlet sh03: vec4f=decompose(splat.sh0.w);let sh04: vec4f=decompose(splat.sh1.x);let sh05: vec4f=decompose(splat.sh1.y);sh[4]=vec3f(sh02.y,sh02.z,sh02.w);sh[5]=vec3f(sh03.x,sh03.y,sh03.z);sh[6]=vec3f(sh03.w,sh04.x,sh04.y);sh[7]=vec3f(sh04.z,sh04.w,sh05.x);sh[8]=vec3f(sh05.y,sh05.z,sh05.w);\n#endif\n#if SH_DEGREE>2\nlet sh06: vec4f=decompose(splat.sh1.z);let sh07: vec4f=decompose(splat.sh1.w);let sh08: vec4f=decompose(splat.sh2.x);let sh09: vec4f=decompose(splat.sh2.y);let sh10: vec4f=decompose(splat.sh2.z);let sh11: vec4f=decompose(splat.sh2.w);sh[9]=vec3f(sh06.x,sh06.y,sh06.z);sh[10]=vec3f(sh06.w,sh07.x,sh07.y);sh[11]=vec3f(sh07.z,sh07.w,sh08.x);sh[12]=vec3f(sh08.y,sh08.z,sh08.w);sh[13]=vec3f(sh09.x,sh09.y,sh09.z);sh[14]=vec3f(sh09.w,sh10.x,sh10.y);sh[15]=vec3f(sh10.z,sh10.w,sh11.x);\n#endif\n#if SH_DEGREE>3\nlet sh12: vec4f=decompose(splat.sh3.x);let sh13: vec4f=decompose(splat.sh3.y);let sh14: vec4f=decompose(splat.sh3.z);let sh15: vec4f=decompose(splat.sh3.w);let sh16: vec4f=decompose(splat.sh4.x);let sh17: vec4f=decompose(splat.sh4.y);sh[16]=vec3f(sh11.y,sh11.z,sh11.w);sh[17]=vec3f(sh12.x,sh12.y,sh12.z);sh[18]=vec3f(sh12.w,sh13.x,sh13.y);sh[19]=vec3f(sh13.z,sh13.w,sh14.x);sh[20]=vec3f(sh14.y,sh14.z,sh14.w);sh[21]=vec3f(sh15.x,sh15.y,sh15.z);sh[22]=vec3f(sh15.w,sh16.x,sh16.y);sh[23]=vec3f(sh16.z,sh16.w,sh17.x);sh[24]=vec3f(sh17.y,sh17.z,sh17.w);\n#endif\nreturn computeColorFromSHDegree(dir,sh,_so1,_so2,_so3,_so4);}\nfn computeSH(splat: Splat,dir: vec3f)->vec3f\n{\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER1==1\nlet _w1: f32=1.0;\n#else\nlet _w1: f32=0.0;\n#endif\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER2==1\nlet _w2: f32=1.0;\n#else\nlet _w2: f32=0.0;\n#endif\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER3==1\nlet _w3: f32=1.0;\n#else\nlet _w3: f32=0.0;\n#endif\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER4==1\nlet _w4: f32=1.0;\n#else\nlet _w4: f32=0.0;\n#endif\nreturn computeSHWeighted(splat,dir,_w1,_w2,_w3,_w4);}\n#endif\nfn gaussianSplatting(\nmeshPos: vec2<f32>,\nworldPos: vec3<f32>,\nscale: vec2<f32>,\ncovA: vec3<f32>,\ncovB: vec3<f32>,\nworldMatrix: mat4x4<f32>,\nviewMatrix: mat4x4<f32>,\nprojectionMatrix: mat4x4<f32>,\nfocal: vec2f,\ninvViewport: vec2f,\nkernelSize: f32,\nminPixelSize: f32\n)->vec4f {let modelView=viewMatrix*worldMatrix;let camspace=viewMatrix*vec4f(worldPos,1.0);let pos2d=projectionMatrix*camspace;let bounds=1.2*pos2d.w;if (pos2d.z<0. || pos2d.x<-bounds || pos2d.x>bounds || pos2d.y<-bounds || pos2d.y>bounds) {return vec4f(0.0,0.0,2.0,1.0);}\nlet Vrk=mat3x3<f32>(\ncovA.x,covA.y,covA.z,\ncovA.y,covB.x,covB.y,\ncovA.z,covB.y,covB.z\n);let isOrtho=abs(projectionMatrix[3][3]-1.0)<0.001;var J: mat3x3<f32>;if (isOrtho) {J=mat3x3<f32>(\nfocal.x,0.0,0.0,\n0.0,focal.y,0.0,\n0.0,0.0,0.0\n);} else {J=mat3x3<f32>(\nfocal.x/camspace.z,0.0,-(focal.x*camspace.x)/(camspace.z*camspace.z),\n0.0,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),\n0.0,0.0,0.0\n);}\nlet T=transpose(mat3x3<f32>(\nmodelView[0].xyz,\nmodelView[1].xyz,\nmodelView[2].xyz))*J;var cov2d=transpose(T)*Vrk*T;\n#if COMPENSATION\nlet c00: f32=cov2d[0][0];let c11: f32=cov2d[1][1];let c01: f32=cov2d[0][1];let detOrig: f32=c00*c11-c01*c01;\n#endif\ncov2d[0][0]+=kernelSize;cov2d[1][1]+=kernelSize;\n#if COMPENSATION\nlet c2d: vec3f=vec3f(cov2d[0][0],c01,cov2d[1][1]);let detBlur: f32=c2d.x*c2d.z-c2d.y*c2d.y;let compensation: f32=sqrt(max(0.,detOrig/detBlur));vertexOutputs.vColor.w*=compensation;\n#endif\nlet mid=(cov2d[0][0]+cov2d[1][1])/2.0;let radius=length(vec2<f32>((cov2d[0][0]-cov2d[1][1])/2.0,cov2d[0][1]));let lambda1=mid+radius;let lambda2=mid-radius;if (lambda2<0.0) {return vec4f(0.0,0.0,2.0,1.0);}\nif (minPixelSize>0.0) {let l1=2.0*min(sqrt(2.0*lambda1),1024.0);let l2=2.0*min(sqrt(2.0*lambda2),1024.0);if (max(l1,l2)<minPixelSize) {return vec4f(0.0,0.0,2.0,1.0);}}\nlet diagonalVector=normalize(vec2<f32>(cov2d[0][1],lambda1-cov2d[0][0]));let majorAxis=min(sqrt(2.0*lambda1),1024.0)*diagonalVector;let minorAxis=min(sqrt(2.0*lambda2),1024.0)*vec2<f32>(diagonalVector.y,-diagonalVector.x);let vCenter=vec2<f32>(pos2d.x,pos2d.y);let scaleFactor=select(pos2d.w,1.0,isOrtho);return vec4f(\nvCenter+((meshPos.x*majorAxis+meshPos.y*minorAxis)*invViewport*scaleFactor)*scale,\npos2d.z,\npos2d.w\n);}\n#if IS_COMPOUND\nfn getPartWorld(partIndex: u32)->mat4x4<f32> {return uniforms.partWorld[partIndex];}\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nfn computeVoxelSplatWorldPos(rotationA: vec4f,rotationB: vec4f,rotationScale: vec4f,center: vec3f,splatWorld: mat4x4f,viewMatrix: mat4x4f,invWorldScale: mat4x4f,quadPos: vec2f)->vec4f {let splatRotation=mat3x3f(\nrotationA.xyz,\nvec3f(rotationA.w,rotationB.x,rotationB.y),\nvec3f(rotationB.z,rotationB.w,rotationScale.x)\n);let splatScale=rotationScale.yzw;let view3x3=mat3x3f(viewMatrix[0].xyz,viewMatrix[1].xyz,viewMatrix[2].xyz);let invWorldScale3x3=mat3x3f(invWorldScale[0].xyz,invWorldScale[1].xyz,invWorldScale[2].xyz);let splatWorld3x3=mat3x3f(splatWorld[0].xyz,splatWorld[1].xyz,splatWorld[2].xyz);let rotToView=view3x3*invWorldScale3x3*splatWorld3x3*splatRotation;let axisLengthInViewZ=abs(vec3f(rotToView[0][2],rotToView[1][2],rotToView[2][2]));let gaussianSplatCutoffStddev: f32=0.7071067812; \nvar offsetSplatSpace: vec3f;if (axisLengthInViewZ.x>axisLengthInViewZ.y && axisLengthInViewZ.x>axisLengthInViewZ.z) {offsetSplatSpace=vec3f(0.0,quadPos.x,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else if (axisLengthInViewZ.y>axisLengthInViewZ.z) {offsetSplatSpace=vec3f(quadPos.x,0.0,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else {offsetSplatSpace=vec3f(quadPos.x,quadPos.y,0.0)*splatScale*gaussianSplatCutoffStddev;}\nlet vertexObjectSpace=center+splatRotation*offsetSplatSpace;return splatWorld*vec4f(vertexObjectSpace,1.0);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"gaussianSplattingVertexDeclaration\";\nconst shader = `attribute vec3 position;attribute vec4 splatIndex0;attribute vec4 splatIndex1;attribute vec4 splatIndex2;attribute vec4 splatIndex3;uniform mat4 view;uniform mat4 projection;uniform mat4 world;uniform vec4 vEyePosition;\n#ifdef PREPASS\nuniform mat4 inverseProjection;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"gaussianSplatting\";\nconst shader = `#if !defined(WEBGL2) && !defined(WEBGPU) && !defined(NATIVE)\nmat3 transpose(mat3 matrix) {return mat3(matrix[0][0],matrix[1][0],matrix[2][0],\nmatrix[0][1],matrix[1][1],matrix[2][1],\nmatrix[0][2],matrix[1][2],matrix[2][2]);}\n#endif\nvec2 getDataUV(float index,vec2 textureSize) {float y=floor(index/textureSize.x);float x=index-y*textureSize.x;return vec2((x+0.5)/textureSize.x,(y+0.5)/textureSize.y);}\n#if SH_DEGREE>0 || IS_COMPOUND\nivec2 getDataUVint(float index,vec2 textureSize) {float y=floor(index/textureSize.x);float x=index-y*textureSize.x;return ivec2(uint(x+0.5),uint(y+0.5));}\n#endif\nstruct Splat {vec4 center;vec4 color;vec4 covA;vec4 covB;\n#if SH_DEGREE>0\nuvec4 sh0; \n#endif\n#if SH_DEGREE>1\nuvec4 sh1;\n#endif\n#if SH_DEGREE>2\nuvec4 sh2;\n#endif\n#if SH_DEGREE>3\nuvec4 sh3;uvec4 sh4;\n#endif\n#if IS_COMPOUND\nuint partIndex;\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nvec4 rotationA;vec4 rotationB;vec4 rotationScale;\n#endif\n#ifdef USE_SOG\nfloat splatIndex;\n#endif\n};float getSplatIndex(int localIndex)\n{float splatIndex;switch (localIndex)\n{case 0: splatIndex=splatIndex0.x; break;case 1: splatIndex=splatIndex0.y; break;case 2: splatIndex=splatIndex0.z; break;case 3: splatIndex=splatIndex0.w; break;case 4: splatIndex=splatIndex1.x; break;case 5: splatIndex=splatIndex1.y; break;case 6: splatIndex=splatIndex1.z; break;case 7: splatIndex=splatIndex1.w; break;case 8: splatIndex=splatIndex2.x; break;case 9: splatIndex=splatIndex2.y; break;case 10: splatIndex=splatIndex2.z; break;case 11: splatIndex=splatIndex2.w; break;case 12: splatIndex=splatIndex3.x; break;case 13: splatIndex=splatIndex3.y; break;case 14: splatIndex=splatIndex3.z; break;case 15: splatIndex=splatIndex3.w; break;}\nreturn splatIndex;}\nSplat readSplat(float splatIndex)\n{Splat splat;vec2 splatUV=getDataUV(splatIndex,dataTextureSize);\n#ifdef USE_SOG\nivec2 sogUVi=ivec2(int(splatUV.x*dataTextureSize.x),int(splatUV.y*dataTextureSize.y));vec4 mL=texelFetch(centersTexture,sogUVi,0); \nvec4 mU=texelFetch(covariancesATexture,sogUVi,0); \nvec4 sRaw=texelFetch(covariancesBTexture,sogUVi,0); \nvec4 qRaw=texelFetch(sogQuatsTexture,sogUVi,0); \nvec4 c0=texelFetch(colorsTexture,sogUVi,0); \nvec3 q16=(mU.xyz*256.0+mL.xyz)*(255.0/65535.0);vec3 nPos=mix(sogMeansMin,sogMeansMax,q16);vec3 center=sign(nPos)*(exp(abs(nPos))-vec3(1.0));splat.center=vec4(center,1.0);\n#ifdef USE_SOG_V2\nvec3 sIdx=floor(sRaw.xyz*255.0+0.5);vec3 splatScale;splatScale.x=exp(texelFetch(sogCodebookTexture,ivec2(int(sIdx.x),0),0).r);splatScale.y=exp(texelFetch(sogCodebookTexture,ivec2(int(sIdx.y),0),0).r);splatScale.z=exp(texelFetch(sogCodebookTexture,ivec2(int(sIdx.z),0),0).r);\n#else\nvec3 splatScale=exp(mix(sogScalesMin,sogScalesMax,sRaw.xyz));\n#endif\nconst float invSqrt2=0.70710678118;vec3 qabc=(qRaw.xyz-vec3(0.5))*2.0*invSqrt2;int qMode=int(qRaw.w*255.0+0.5)-252;float qd=sqrt(max(0.0,1.0-dot(qabc,qabc)));vec4 quat;if (qMode==0) quat=vec4(qd,qabc.x,qabc.y,qabc.z);else if (qMode==1) quat=vec4(qabc.x,qd,qabc.y,qabc.z);else if (qMode==2) quat=vec4(qabc.x,qabc.y,qd,qabc.z);else quat=vec4(qabc.x,qabc.y,qabc.z,qd);float qw=quat.x,qx=quat.y,qy=quat.z,qz=quat.w;mat3 R=mat3(\n1.0-2.0*(qy*qy+qz*qz),2.0*(qx*qy+qw*qz), 2.0*(qx*qz-qw*qy),\n2.0*(qx*qy-qw*qz), 1.0-2.0*(qx*qx+qz*qz),2.0*(qy*qz+qw*qx),\n2.0*(qx*qz+qw*qy), 2.0*(qy*qz-qw*qx), 1.0-2.0*(qx*qx+qy*qy)\n);mat3 S2=mat3(4.0*splatScale.x*splatScale.x,0.0,0.0,\n0.0,4.0*splatScale.y*splatScale.y,0.0,\n0.0,0.0,4.0*splatScale.z*splatScale.z);mat3 Sigma=R*S2*transpose(R);splat.covA=vec4(Sigma[0][0],Sigma[0][1],Sigma[0][2],Sigma[1][1]);splat.covB=vec4(Sigma[1][2],Sigma[2][2],0.0,0.0);const float SH_C0=0.28209479177387814;\n#ifdef USE_SOG_V2\nvec3 c3;c3.x=texelFetch(sogCodebookTexture,ivec2(256+int(c0.x*255.0+0.5),0),0).r;c3.y=texelFetch(sogCodebookTexture,ivec2(256+int(c0.y*255.0+0.5),0),0).r;c3.z=texelFetch(sogCodebookTexture,ivec2(256+int(c0.z*255.0+0.5),0),0).r;vec3 colRgb=vec3(0.5)+c3*SH_C0;float colA=c0.w; \n#else\nvec4 cLerp=mix(sogSh0Min,sogSh0Max,c0);vec3 colRgb=vec3(0.5)+cLerp.xyz*SH_C0;float colA=1.0/(1.0+exp(-cLerp.w));\n#endif\nsplat.color=vec4(colRgb,colA);splat.splatIndex=splatIndex;\n#else\nsplat.center=texture2D(centersTexture,splatUV);splat.color=texture2D(colorsTexture,splatUV);\n#if !defined(IS_FOR_VOXELIZATION)\nsplat.covA=texture2D(covariancesATexture,splatUV)*splat.center.w;splat.covB=texture2D(covariancesBTexture,splatUV)*splat.center.w;\n#endif\n#endif\n#if SH_DEGREE>0 || IS_COMPOUND\nivec2 splatUVint=getDataUVint(splatIndex,dataTextureSize);\n#endif\n#if SH_DEGREE>0 && !defined(USE_SOG)\nsplat.sh0=texelFetch(shTexture0,splatUVint,0);\n#endif\n#if SH_DEGREE>1 && !defined(USE_SOG)\nsplat.sh1=texelFetch(shTexture1,splatUVint,0);\n#endif\n#if SH_DEGREE>2 && !defined(USE_SOG)\nsplat.sh2=texelFetch(shTexture2,splatUVint,0);\n#endif\n#if SH_DEGREE>3 && !defined(USE_SOG)\nsplat.sh3=texelFetch(shTexture3,splatUVint,0);splat.sh4=texelFetch(shTexture4,splatUVint,0);\n#endif\n#if IS_COMPOUND\nsplat.partIndex=uint(texture2D(partIndicesTexture,splatUV).r*255.0+0.5);\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nsplat.rotationA=texture2D(rotationsATexture,splatUV);splat.rotationB=texture2D(rotationsBTexture,splatUV);splat.rotationScale=texture2D(rotationScaleTexture,splatUV);\n#endif\nreturn splat;}\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nvec3 computeColorFromSHDegree(vec3 dir,const vec3 sh[25],float _so1,float _so2,float _so3,float _so4)\n{const float SH_C0=0.28209479;const float SH_C1=0.48860251;float SH_C2[5];SH_C2[0]=1.092548430;SH_C2[1]=-1.09254843;SH_C2[2]=0.315391565;SH_C2[3]=-1.09254843;SH_C2[4]=0.546274215;float SH_C3[7];SH_C3[0]=-0.59004358;SH_C3[1]=2.890611442;SH_C3[2]=-0.45704579;SH_C3[3]=0.373176332;SH_C3[4]=-0.45704579;SH_C3[5]=1.445305721;SH_C3[6]=-0.59004358;float SH_C4[9];SH_C4[0]= 2.5033429418;SH_C4[1]=-1.7701307698;SH_C4[2]= 0.9461746958;SH_C4[3]=-0.6690465436;SH_C4[4]= 0.1057855469;SH_C4[5]=-0.6690465436;SH_C4[6]= 0.4730873479;SH_C4[7]=-1.7701307698;SH_C4[8]= 0.6258357354;vec3 result=/*SH_C0**/sh[0];\n#if SH_DEGREE>0\nfloat x=dir.x;float y=dir.y;float z=dir.z;result+=_so1*(- SH_C1*y*sh[1]+SH_C1*z*sh[2]-SH_C1*x*sh[3]);\n#if SH_DEGREE>1\nfloat xx=x*x,yy=y*y,zz=z*z;float xy=x*y,yz=y*z,xz=x*z;result+=_so2*(\nSH_C2[0]*xy*sh[4] +\nSH_C2[1]*yz*sh[5] +\nSH_C2[2]*(2.0*zz-xx-yy)*sh[6] +\nSH_C2[3]*xz*sh[7] +\nSH_C2[4]*(xx-yy)*sh[8]);\n#if SH_DEGREE>2\nresult+=_so3*(\nSH_C3[0]*y*(3.0*xx-yy)*sh[9] +\nSH_C3[1]*xy*z*sh[10] +\nSH_C3[2]*y*(4.0*zz-xx-yy)*sh[11] +\nSH_C3[3]*z*(2.0*zz-3.0*xx-3.0*yy)*sh[12] +\nSH_C3[4]*x*(4.0*zz-xx-yy)*sh[13] +\nSH_C3[5]*z*(xx-yy)*sh[14] +\nSH_C3[6]*x*(xx-3.0*yy)*sh[15]);\n#if SH_DEGREE>3\nresult+=_so4*(\nSH_C4[0]*x*y*(xx-yy)*sh[16] +\nSH_C4[1]*y*z*(3.0*xx-yy)*sh[17] +\nSH_C4[2]*x*y*(7.0*zz-1.0)*sh[18] +\nSH_C4[3]*y*z*(7.0*zz-3.0)*sh[19] +\nSH_C4[4]*(zz*(35.0*zz-30.0)+3.0)*sh[20] +\nSH_C4[5]*x*z*(7.0*zz-3.0)*sh[21] +\nSH_C4[6]*(xx-yy)*(7.0*zz-1.0)*sh[22] +\nSH_C4[7]*x*z*(xx-3.0*yy)*sh[23] +\nSH_C4[8]*(xx*(xx-3.0*yy)-yy*(3.0*xx-yy))*sh[24]);\n#endif\n#endif\n#endif\n#endif\nreturn result;}\nvec4 decompose(uint value)\n{vec4 components=vec4(\nfloat((value ) & 255u),\nfloat((value>>uint( 8)) & 255u),\nfloat((value>>uint(16)) & 255u),\nfloat((value>>uint(24)) & 255u));return components*vec4(2./255.)-vec4(1.);}\n#ifdef USE_SOG\nvec3 computeSH(Splat splat,vec3 dir)\n{\n#if SH_DEGREE>0\nvec3 sh[25];sh[0]=vec3(0.,0.,0.);ivec2 labelSize=textureSize(sogShNLabelsTexture,0);int idx=int(splat.splatIndex+0.5);int lx=idx-(idx/labelSize.x)*labelSize.x;int ly=idx/labelSize.x;vec4 labelRaw=texelFetch(sogShNLabelsTexture,ivec2(lx,ly),0);int n=int(labelRaw.r*255.0+0.5)+int(labelRaw.g*255.0+0.5)*256;int coeffs=int(sogShCoeffCount+0.5);int u=(n-(n/64)*64)*coeffs;int v=n/64;for (int k=0; k<24; k++) {if (k>=coeffs) break;vec4 centroidRaw=texelFetch(sogShNCentroidsTexture,ivec2(u+k,v),0);vec3 shCoeff;\n#ifdef USE_SOG_V2\nint rIdx=int(centroidRaw.r*255.0+0.5);int gIdx=int(centroidRaw.g*255.0+0.5);int bIdx=int(centroidRaw.b*255.0+0.5);shCoeff.r=texelFetch(sogCodebookTexture,ivec2(512+rIdx,0),0).r;shCoeff.g=texelFetch(sogCodebookTexture,ivec2(512+gIdx,0),0).r;shCoeff.b=texelFetch(sogCodebookTexture,ivec2(512+bIdx,0),0).r;\n#else\nshCoeff=mix(vec3(sogShnMin),vec3(sogShnMax),centroidRaw.rgb);\n#endif\nsh[k+1]=shCoeff;}\nreturn computeColorFromSHDegree(dir,sh,1.,1.,1.,1.);\n#else\nreturn vec3(0.,0.,0.);\n#endif\n}\n#else\nvec3 computeSHWeighted(Splat splat,vec3 dir,float _so1,float _so2,float _so3,float _so4)\n{vec3 sh[25];sh[0]=vec3(0.,0.,0.);\n#if SH_DEGREE>0\nvec4 sh00=decompose(splat.sh0.x);vec4 sh01=decompose(splat.sh0.y);vec4 sh02=decompose(splat.sh0.z);sh[1]=vec3(sh00.x,sh00.y,sh00.z);sh[2]=vec3(sh00.w,sh01.x,sh01.y);sh[3]=vec3(sh01.z,sh01.w,sh02.x);\n#endif\n#if SH_DEGREE>1\nvec4 sh03=decompose(splat.sh0.w);vec4 sh04=decompose(splat.sh1.x);vec4 sh05=decompose(splat.sh1.y);sh[4]=vec3(sh02.y,sh02.z,sh02.w);sh[5]=vec3(sh03.x,sh03.y,sh03.z);sh[6]=vec3(sh03.w,sh04.x,sh04.y);sh[7]=vec3(sh04.z,sh04.w,sh05.x);sh[8]=vec3(sh05.y,sh05.z,sh05.w);\n#endif\n#if SH_DEGREE>2\nvec4 sh06=decompose(splat.sh1.z);vec4 sh07=decompose(splat.sh1.w);vec4 sh08=decompose(splat.sh2.x);vec4 sh09=decompose(splat.sh2.y);vec4 sh10=decompose(splat.sh2.z);vec4 sh11=decompose(splat.sh2.w);sh[9]=vec3(sh06.x,sh06.y,sh06.z);sh[10]=vec3(sh06.w,sh07.x,sh07.y);sh[11]=vec3(sh07.z,sh07.w,sh08.x);sh[12]=vec3(sh08.y,sh08.z,sh08.w);sh[13]=vec3(sh09.x,sh09.y,sh09.z);sh[14]=vec3(sh09.w,sh10.x,sh10.y);sh[15]=vec3(sh10.z,sh10.w,sh11.x);\n#endif\n#if SH_DEGREE>3\nvec4 sh12=decompose(splat.sh3.x);vec4 sh13=decompose(splat.sh3.y);vec4 sh14=decompose(splat.sh3.z);vec4 sh15=decompose(splat.sh3.w);vec4 sh16=decompose(splat.sh4.x);vec4 sh17=decompose(splat.sh4.y);sh[16]=vec3(sh11.y,sh11.z,sh11.w);sh[17]=vec3(sh12.x,sh12.y,sh12.z);sh[18]=vec3(sh12.w,sh13.x,sh13.y);sh[19]=vec3(sh13.z,sh13.w,sh14.x);sh[20]=vec3(sh14.y,sh14.z,sh14.w);sh[21]=vec3(sh15.x,sh15.y,sh15.z);sh[22]=vec3(sh15.w,sh16.x,sh16.y);sh[23]=vec3(sh16.z,sh16.w,sh17.x);sh[24]=vec3(sh17.y,sh17.z,sh17.w);\n#endif\nreturn computeColorFromSHDegree(dir,sh,_so1,_so2,_so3,_so4);}\nvec3 computeSH(Splat splat,vec3 dir)\n{\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER1==1\nfloat _w1=1.0;\n#else\nfloat _w1=0.0;\n#endif\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER2==1\nfloat _w2=1.0;\n#else\nfloat _w2=0.0;\n#endif\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER3==1\nfloat _w3=1.0;\n#else\nfloat _w3=0.0;\n#endif\n#if !defined(GS_DBG_ENABLED) || GS_DBG_SH_ORDER4==1\nfloat _w4=1.0;\n#else\nfloat _w4=0.0;\n#endif\nreturn computeSHWeighted(splat,dir,_w1,_w2,_w3,_w4);}\n#endif\n#else\nvec3 computeSH(Splat splat,vec3 dir)\n{return vec3(0.,0.,0.);}\n#endif\n#if !defined(IS_FOR_VOXELIZATION)\nvec4 gaussianSplatting(vec2 meshPos,vec3 worldPos,vec2 scale,vec3 covA,vec3 covB,mat4 worldMatrix,mat4 viewMatrix,mat4 projectionMatrix)\n{mat4 modelView=viewMatrix*worldMatrix;vec4 camspace=viewMatrix*vec4(worldPos,1.);vec4 pos2d=projectionMatrix*camspace;float bounds=1.2*pos2d.w;if (pos2d.z<-pos2d.w || pos2d.x<-bounds || pos2d.x>bounds\n|| pos2d.y<-bounds || pos2d.y>bounds) {return vec4(0.0,0.0,2.0,1.0);}\nmat3 Vrk=mat3(\ncovA.x,covA.y,covA.z,\ncovA.y,covB.x,covB.y,\ncovA.z,covB.y,covB.z\n);bool isOrtho=abs(projectionMatrix[3][3]-1.0)<0.001;mat3 J;if (isOrtho) {J=mat3(\nfocal.x,0.,0.,\n0.,focal.y,0.,\n0.,0.,0.\n);} else {J=mat3(\nfocal.x/camspace.z,0.,-(focal.x*camspace.x)/(camspace.z*camspace.z),\n0.,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),\n0.,0.,0.\n);}\nmat3 T=transpose(mat3(modelView))*J;mat3 cov2d=transpose(T)*Vrk*T;\n#if COMPENSATION\nfloat c00=cov2d[0][0];float c11=cov2d[1][1];float c01=cov2d[0][1];float detOrig=c00*c11-c01*c01;\n#endif\ncov2d[0][0]+=kernelSize;cov2d[1][1]+=kernelSize;\n#if COMPENSATION\nvec3 c2d=vec3(cov2d[0][0],c01,cov2d[1][1]);float detBlur=c2d.x*c2d.z-c2d.y*c2d.y;float compensation=sqrt(max(0.,detOrig/detBlur));vColor.w*=compensation;\n#endif\nfloat mid=(cov2d[0][0]+cov2d[1][1])/2.0;float radius=length(vec2((cov2d[0][0]-cov2d[1][1])/2.0,cov2d[0][1]));float epsilon=0.0001;float lambda1=mid+radius+epsilon,lambda2=mid-radius+epsilon;if (lambda2<0.0)\n{return vec4(0.0,0.0,2.0,1.0);}\nif (minPixelSize>0.0) {float l1=2.0*min(sqrt(2.0*lambda1),1024.0);float l2=2.0*min(sqrt(2.0*lambda2),1024.0);if (max(l1,l2)<minPixelSize) {return vec4(0.0,0.0,2.0,1.0);}}\nvec2 diagonalVector=normalize(vec2(cov2d[0][1],lambda1-cov2d[0][0]));vec2 majorAxis=min(sqrt(2.0*lambda1),1024.0)*diagonalVector;vec2 minorAxis=min(sqrt(2.0*lambda2),1024.0)*vec2(diagonalVector.y,-diagonalVector.x);vec2 vCenter=vec2(pos2d);float scaleFactor=isOrtho ? 1.0 : pos2d.w;return vec4(\nvCenter \n+ ((meshPos.x*majorAxis\n+ meshPos.y*minorAxis)*invViewport*scaleFactor)*scale,pos2d.zw);}\n#endif\n#if IS_COMPOUND\nmat4 getPartWorld(uint partIndex) {return partWorld[partIndex];}\n#endif\n#if defined(IS_FOR_VOXELIZATION)\nvec4 computeVoxelSplatWorldPos(vec4 rotationA,vec4 rotationB,vec4 rotationScale,vec3 center,mat4 splatWorld,mat4 viewMatrix,mat4 invWorldScale,vec2 quadPos) {mat3 splatRotation=mat3(\nvec3(rotationA.x,rotationA.y,rotationA.z),\nvec3(rotationA.w,rotationB.x,rotationB.y),\nvec3(rotationB.z,rotationB.w,rotationScale.x)\n);vec3 splatScale=vec3(rotationScale.y,rotationScale.z,rotationScale.w);mat3 rotToView=mat3(viewMatrix)*mat3(invWorldScale)*mat3(splatWorld)*splatRotation;vec3 axisLengthInViewZ=abs(vec3(rotToView[0][2],rotToView[1][2],rotToView[2][2]));float gaussianSplatCutoffStddev=1.4142135624/2.0; \nvec3 offsetSplatSpace;if (axisLengthInViewZ.x>axisLengthInViewZ.y && axisLengthInViewZ.x>axisLengthInViewZ.z) {offsetSplatSpace=vec3(0.0,quadPos.x,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else if (axisLengthInViewZ.y>axisLengthInViewZ.z) {offsetSplatSpace=vec3(quadPos.x,0.0,quadPos.y)*splatScale*gaussianSplatCutoffStddev;} else {offsetSplatSpace=vec3(quadPos.x,quadPos.y,0.0)*splatScale*gaussianSplatCutoffStddev;}\nvec3 vertexObjectSpace=center+splatRotation*offsetSplatSpace;return splatWorld*vec4(vertexObjectSpace,1.0);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const gaussianSplatting = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./logDepthFragment\";\nimport \"./fogFragment\";\nconst name = \"gaussianSplattingFragmentDeclaration\";\nconst shader = `fn gaussianColor(inColor: vec4f,inPosition: vec2f)->vec4f\n{var A : f32=-dot(inPosition,inPosition);if (A>-4.0)\n{var B: f32=exp(A)*inColor.a;\n#include<logDepthFragment>\nvar color: vec3f=inColor.rgb;\n#ifdef FOG\n#include<fogFragment>\n#endif\nreturn vec4f(color,B);} else {return vec4f(0.0);}}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingFragmentDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./logDepthFragment\";\nimport \"./fogFragment\";\nconst name = \"gaussianSplattingFragmentDeclaration\";\nconst shader = `vec4 gaussianColor(vec4 inColor)\n{float A=-dot(vPosition,vPosition);if (A<-4.0) discard;float B=exp(A)*inColor.a;\n#include<logDepthFragment>\nvec3 color=inColor.rgb;\n#ifdef FOG\n#include<fogFragment>\n#endif\nreturn vec4(color,B);}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingFragmentDeclaration = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to render intermediate debug values\r\n * Please note that the node needs to be active to be generated in the shader\r\n * Only one DebugBlock should be active at a time\r\n */\r\nexport class NodeMaterialDebugBlock extends NodeMaterialBlock {\r\n    private _isActive = false;\r\n\r\n    /** @internal */\r\n    public _forcedActive = false;\r\n\r\n    /** Gets or sets a boolean indicating if we want to render alpha when using a rgba input*/\r\n    @editableInPropertyPage(\"Render Alpha\", PropertyTypeForEdition.Boolean, undefined)\r\n    public renderAlpha = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the block is active\r\n     */\r\n    public get isActive(): boolean {\r\n        return this._isActive && this.debug.isConnected;\r\n    }\r\n\r\n    public set isActive(value: boolean) {\r\n        if (this._isActive === value) {\r\n            return;\r\n        }\r\n\r\n        this._isActive = value;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeMaterialDebugBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Fragment, true, true);\r\n\r\n        this.registerInput(\"debug\", NodeMaterialBlockConnectionPointTypes.AutoDetect, true);\r\n\r\n        this.debug.excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /** @internal */\r\n    public override get _isFinalOutputAndActive() {\r\n        return this.isActive || this._forcedActive;\r\n    }\r\n\r\n    /** @internal */\r\n    public override get _hasPrecedence() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba input component\r\n     */\r\n    public get debug(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NodeMaterialDebugBlock\";\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this._isFinalOutputAndActive) {\r\n            return this;\r\n        }\r\n\r\n        let outputString = \"gl_FragColor\";\r\n        if (state.shaderLanguage === ShaderLanguage.WGSL) {\r\n            outputString = \"fragmentOutputs.color\";\r\n        }\r\n\r\n        const debug = this.debug;\r\n        if (!debug.connectedPoint) {\r\n            return this;\r\n        }\r\n\r\n        if (debug.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Float) {\r\n            state.compilationString += `${outputString}  = vec4${state.fSuffix}(${debug.associatedVariableName}, ${debug.associatedVariableName}, ${debug.associatedVariableName}, 1.0);\\n`;\r\n        } else if (debug.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector2) {\r\n            state.compilationString += `${outputString}  = vec4${state.fSuffix}(${debug.associatedVariableName}, 0., 1.0);\\n`;\r\n        } else if (debug.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Color3 || debug.connectedPoint.type === NodeMaterialBlockConnectionPointTypes.Vector3) {\r\n            state.compilationString += `${outputString}  = vec4${state.fSuffix}(${debug.associatedVariableName}, 1.0);\\n`;\r\n        } else if (this.renderAlpha) {\r\n            state.compilationString += `${outputString}  =${debug.associatedVariableName};\\n`;\r\n        } else {\r\n            state.compilationString += `${outputString}  = vec4${state.fSuffix}(${debug.associatedVariableName}.rgb, 1.0);\\n`;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Serializes the block\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.isActive = this._isActive;\r\n        serializationObject.renderAlpha = this.renderAlpha;\r\n        serializationObject._forcedActive = this._forcedActive;\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block\r\n     * @param serializationObject - the serialization object\r\n     * @param scene - the scene\r\n     * @param rootUrl - the root URL\r\n     */\r\n    public override _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {\r\n        super._deserialize(serializationObject, scene, rootUrl);\r\n\r\n        this.isActive = serializationObject.isActive;\r\n        this.renderAlpha = serializationObject.renderAlpha;\r\n        this._forcedActive = serializationObject._forcedActive;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialsNodeBlocksDebugBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialsNodeBlocksDebugBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NodeMaterialDebugBlock\", NodeMaterialDebugBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\nimport { NodeMaterialBlockConnectionPointTypes } from \"../Enums/nodeMaterialBlockConnectionPointTypes\";\r\nimport { type NodeMaterialBuildState } from \"../nodeMaterialBuildState\";\r\nimport { type NodeMaterialConnectionPoint } from \"../nodeMaterialBlockConnectionPoint\";\r\nimport { NodeMaterialBlockTargets } from \"../Enums/nodeMaterialBlockTargets\";\r\nimport { InputBlock } from \"./Input/inputBlock.pure\";\r\nimport { type NodeMaterial } from \"../nodeMaterial.pure\";\r\nimport { AnimatedInputBlockTypes } from \"./Input/animatedInputBlockTypes\";\r\nimport { NodeMaterialModes } from \"../Enums/nodeMaterialModes\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to pan UV coordinates over time (similar to Unreal's Panner node).\r\n * This block takes UV coordinates, speed values for X and Y axes, and a time input,\r\n * then outputs animated UV coordinates that scroll based on the speed and time.\r\n */\r\nexport class PannerBlock extends NodeMaterialBlock {\r\n    /**\r\n     * Creates a new PannerBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name, NodeMaterialBlockTargets.Neutral);\r\n\r\n        this.registerInput(\"uv\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"speed\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"time\", NodeMaterialBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeMaterialBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PannerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the uv input component\r\n     */\r\n    public get uv(): NodeMaterialConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the speed input component\r\n     */\r\n    public get speed(): NodeMaterialConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the time input component\r\n     */\r\n    public get time(): NodeMaterialConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeMaterialConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Auto configure the block based on the material\r\n     * @param material - the node material\r\n     * @param additionalFilteringInfo - additional filtering info\r\n     */\r\n    public override autoConfigure(material: NodeMaterial, additionalFilteringInfo: (node: NodeMaterialBlock) => boolean = () => true) {\r\n        if (!this.uv.isConnected) {\r\n            if (material.mode !== NodeMaterialModes.PostProcess && material.mode !== NodeMaterialModes.ProceduralTexture) {\r\n                const attributeName = material.mode === NodeMaterialModes.Particle ? \"particle_uv\" : \"uv\";\r\n\r\n                let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === attributeName && additionalFilteringInfo(b));\r\n\r\n                if (!uvInput) {\r\n                    uvInput = new InputBlock(\"uv\");\r\n                    uvInput.setAsAttribute(attributeName);\r\n                }\r\n\r\n                uvInput.output.connectTo(this.uv);\r\n            }\r\n        }\r\n\r\n        if (!this.time.isConnected) {\r\n            let timeInput = material.getInputBlockByPredicate((b) => b.animationType === AnimatedInputBlockTypes.Time && additionalFilteringInfo(b));\r\n\r\n            if (!timeInput) {\r\n                timeInput = new InputBlock(\"time\");\r\n                timeInput.value = 0;\r\n                timeInput.animationType = AnimatedInputBlockTypes.Time;\r\n            }\r\n\r\n            timeInput.output.connectTo(this.time);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeMaterialBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n\r\n        // Output = UV + speed * time\r\n        state.compilationString +=\r\n            state._declareOutput(output) + ` = ${this.uv.associatedVariableName} + ${this.speed.associatedVariableName} * ${this.time.associatedVariableName};\\n`;\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pannerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPannerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PannerBlock\", PannerBlock);\r\n}\r\n","import { type NodeMaterialBlock } from \"../nodeMaterialBlock\";\r\n\r\n/**\r\n * Root class for all node material optimizers\r\n */\r\nexport class NodeMaterialOptimizer {\r\n    /**\r\n     * Function used to optimize a NodeMaterial graph\r\n     * @param _vertexOutputNodes defines the list of output nodes for the vertex shader\r\n     * @param _fragmentOutputNodes defines the list of output nodes for the fragment shader\r\n     */\r\n    public optimize(_vertexOutputNodes: NodeMaterialBlock[], _fragmentOutputNodes: NodeMaterialBlock[]) {\r\n        // Do nothing by default\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"postprocessVertexShader\";\nconst shader = `attribute vec2 position;uniform vec2 scale;varying vec2 vUV;const vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvUV=(position*madd+madd)*scale;gl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const postprocessVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"postprocessVertexShader\";\nconst shader = `attribute position: vec2<f32>;uniform scale: vec2<f32>;varying vUV: vec2<f32>;const madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.vUV=(vertexInputs.position*madd+madd)*uniforms.scale;vertexOutputs.position=vec4(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const postprocessVertexShaderWGSL = { name, shader };\n","import { type ShaderCustomProcessingFunction } from \"../Engines/Processors/shaderProcessingOptions\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\n\r\nimport { type BaseTexture } from \"./Textures/baseTexture\";\r\nimport { type EffectFallbacks } from \"./effectFallbacks\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type SubMesh } from \"../Meshes/subMesh\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { type RenderTargetTexture } from \"./Textures/renderTargetTexture\";\r\n\r\n/** @internal */\r\nexport type MaterialPluginCreated = object;\r\n\r\n/** @internal */\r\nexport type MaterialPluginDisposed = {\r\n    forceDisposeTextures?: boolean;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginHasTexture = {\r\n    hasTexture: boolean;\r\n    texture: BaseTexture;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginIsReadyForSubMesh = {\r\n    isReadyForSubMesh: boolean;\r\n    defines: MaterialDefines;\r\n    subMesh: SubMesh;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginGetDefineNames = {\r\n    defineNames?: { [name: string]: { type: string; default: any } };\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginPrepareEffect = {\r\n    defines: MaterialDefines;\r\n    fallbacks: EffectFallbacks;\r\n    fallbackRank: number;\r\n    customCode?: ShaderCustomProcessingFunction;\r\n    attributes: string[];\r\n    uniforms: string[];\r\n    samplers: string[];\r\n    uniformBuffersNames: string[];\r\n    mesh: AbstractMesh;\r\n    indexParameters: any;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginPrepareDefines = {\r\n    defines: MaterialDefines;\r\n    mesh: AbstractMesh;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginPrepareUniformBuffer = {\r\n    ubo: UniformBuffer;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginBindForSubMesh = {\r\n    subMesh: SubMesh;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginGetAnimatables = {\r\n    animatables: IAnimatable[];\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginGetActiveTextures = {\r\n    activeTextures: BaseTexture[];\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginFillRenderTargetTextures = {\r\n    renderTargets: SmartArray<RenderTargetTexture>;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginHasRenderTargetTextures = {\r\n    hasRenderTargetTextures: boolean;\r\n};\r\n\r\n/** @internal */\r\nexport type MaterialPluginHardBindForSubMesh = {\r\n    subMesh: SubMesh;\r\n};\r\n\r\n/**\r\n * @internal\r\n */\r\nexport const enum MaterialPluginEvent {\r\n    Created = 0x0001,\r\n    Disposed = 0x0002,\r\n    GetDefineNames = 0x0004,\r\n    PrepareUniformBuffer = 0x0008,\r\n    IsReadyForSubMesh = 0x0010,\r\n    PrepareDefines = 0x0020,\r\n    BindForSubMesh = 0x0040,\r\n    PrepareEffect = 0x0080,\r\n    GetAnimatables = 0x0100,\r\n    GetActiveTextures = 0x0200,\r\n    HasTexture = 0x0400,\r\n    FillRenderTargetTextures = 0x0800,\r\n    HasRenderTargetTextures = 0x1000,\r\n    HardBindForSubMesh = 0x2000,\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { InstancedMesh, RegisterInstancedMesh } from \"../Meshes/instancedMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { RegisterThinInstanceMesh } from \"../Meshes/thinInstanceMesh.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { MaterialPluginBase } from \"./materialPluginBase.pure\";\r\nimport { type MaterialDefines } from \"./materialDefines\";\r\nimport { PBRBaseMaterial } from \"./PBR/pbrBaseMaterial.pure\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { StandardMaterial } from \"./standardMaterial.pure\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\n\r\n/**\r\n * The material families supported by {@link DitheredTileFadeMaterialPlugin}.\r\n */\r\nexport type DitheredTileFadeSupportedMaterial = StandardMaterial | PBRBaseMaterial;\r\n\r\n/**\r\n * The mesh types that can store independent dithered tile fade bounds.\r\n */\r\nexport type DitheredTileFadeMesh = Mesh | InstancedMesh;\r\n\r\n/**\r\n * Defines a normalized interval in the 8x8 Bayer threshold domain.\r\n */\r\nexport interface IDitheredTileFadeBounds {\r\n    /**\r\n     * The inclusive lower bound.\r\n     */\r\n    lowerBound: number;\r\n\r\n    /**\r\n     * The exclusive upper bound.\r\n     */\r\n    upperBound: number;\r\n}\r\n\r\nlet GlslShaderLoadPromise: Promise<void> | undefined;\r\nlet WgslShaderLoadPromise: Promise<void> | undefined;\r\nconst DepthPrePassInjectionPoint = \"!#include<depthPrePass>\";\r\n\r\nasync function _LoadGlslShaderIncludeAsync(): Promise<void> {\r\n    await import(\"../Shaders/ShadersInclude/bayerDitherFunctions\");\r\n}\r\n\r\nasync function _LoadWgslShaderIncludeAsync(): Promise<void> {\r\n    await import(\"../ShadersWGSL/ShadersInclude/bayerDitherFunctions\");\r\n}\r\n\r\nasync function _LoadShaderIncludeAsync(shaderLanguage: ShaderLanguage): Promise<void> {\r\n    if (shaderLanguage === ShaderLanguage.WGSL) {\r\n        WgslShaderLoadPromise ??= _LoadWgslShaderIncludeAsync();\r\n        await WgslShaderLoadPromise;\r\n        return;\r\n    }\r\n\r\n    GlslShaderLoadPromise ??= _LoadGlslShaderIncludeAsync();\r\n    await GlslShaderLoadPromise;\r\n}\r\n\r\n/**\r\n * Applies an opaque, screen-space dithered fade for tile LOD meshes that share a Standard or PBR material.\r\n *\r\n * The plugin keeps depth writing and the material's alpha mode unchanged. It affects the material color and integrated\r\n * prepass outputs, but not standalone depth, shadow, picking, outline, or custom passes. Tile renderers using those passes\r\n * must provide equivalent pass-specific coverage or exclude fading tiles from them.\r\n *\r\n * Per-mesh bounds are runtime state. Material cloning and serialization do not copy them; use {@link copyToMaterial} to\r\n * copy the enabled state to a cloned material and then configure bounds for the cloned tile meshes.\r\n * @see https://playground.babylonjs.com/#HI17VI#0\r\n */\r\nexport class DitheredTileFadeMaterialPlugin extends MaterialPluginBase {\r\n    /**\r\n     * The name used to register the plugin on a material.\r\n     */\r\n    public static readonly Name = \"DitheredTileFade\";\r\n\r\n    private _meshBounds = new WeakMap<AbstractMesh, IDitheredTileFadeBounds>();\r\n    private _instancedBufferSources = new WeakSet<Mesh>();\r\n    private _thinInstanceFadeBuffers = new WeakMap<Mesh, Float32Array>();\r\n    private _generation = 1;\r\n    private _isEnabled = true;\r\n    private _shaderIncludeReady = false;\r\n    private _shaderIncludeError: unknown;\r\n\r\n    /**\r\n     * Gets whether configured fades are applied. Disabling the plugin makes every mesh fully visible without discarding its stored bounds.\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    /**\r\n     * Sets whether configured fades are applied. This uniform-only change does not recompile the material.\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        this._isEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Creates and attaches a dithered fade plugin.\r\n     * @param material The Standard or PBR material that the plugin will extend.\r\n     * @throws If the material is unsupported or already has a dithered tile fade plugin. Use {@link GetOrCreate} when reuse is intended.\r\n     */\r\n    public constructor(material: DitheredTileFadeSupportedMaterial) {\r\n        super(material, DitheredTileFadeMaterialPlugin.Name, 190, undefined, DitheredTileFadeMaterialPlugin._ValidateNewPlugin(material), false, true);\r\n\r\n        this.registerForExtraEvents = true;\r\n        this.doNotSerialize = true;\r\n        void this._loadShaderIncludeAsync(material.shaderLanguage);\r\n        this._enable(true);\r\n    }\r\n\r\n    /**\r\n     * Gets the plugin already attached to a material, or creates and attaches one.\r\n     * @param material The Standard or PBR material to extend.\r\n     * @returns The material's dithered fade plugin.\r\n     * @throws If the material is unsupported or another plugin uses the reserved plugin name.\r\n     */\r\n    public static GetOrCreate(material: DitheredTileFadeSupportedMaterial): DitheredTileFadeMaterialPlugin {\r\n        DitheredTileFadeMaterialPlugin._ValidateMaterial(material);\r\n        const existing = material.pluginManager?.getPlugin(DitheredTileFadeMaterialPlugin.Name);\r\n        if (existing) {\r\n            if (!(existing instanceof DitheredTileFadeMaterialPlugin)) {\r\n                throw new Error(`The material \"${material.name}\" already has an incompatible plugin named \"${DitheredTileFadeMaterialPlugin.Name}\".`);\r\n            }\r\n            return existing;\r\n        }\r\n        return new DitheredTileFadeMaterialPlugin(material);\r\n    }\r\n\r\n    /**\r\n     * Checks whether the plugin supports a shader language.\r\n     * @param shaderLanguage The shader language to check.\r\n     * @returns True for GLSL and WGSL.\r\n     */\r\n    public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n        return shaderLanguage === ShaderLanguage.GLSL || shaderLanguage === ShaderLanguage.WGSL;\r\n    }\r\n\r\n    /**\r\n     * Sets both normalized Bayer interval bounds for a mesh.\r\n     * @param mesh The tile mesh or hardware instance whose draw calls use the bounds.\r\n     * @param lowerBound The inclusive lower bound in the range [0, 1].\r\n     * @param upperBound The exclusive upper bound in the range [0, 1].\r\n     * @remarks Bounds are independent. A lower bound greater than or equal to the upper bound intentionally produces an empty interval.\r\n     */\r\n    public setFadeBounds(mesh: DitheredTileFadeMesh, lowerBound: number, upperBound: number): void {\r\n        this._validateMesh(mesh);\r\n        this._validateBound(lowerBound, \"lowerBound\");\r\n        this._validateBound(upperBound, \"upperBound\");\r\n\r\n        const bounds = this._meshBounds.get(mesh);\r\n        if (bounds) {\r\n            bounds.lowerBound = lowerBound;\r\n            bounds.upperBound = upperBound;\r\n        } else {\r\n            this._meshBounds.set(mesh, { lowerBound, upperBound });\r\n        }\r\n\r\n        this._updateInstancedFadeBounds(mesh, lowerBound, upperBound, true);\r\n    }\r\n\r\n    /**\r\n     * Sets the normalized inclusive lower Bayer interval bound for a mesh.\r\n     * @param mesh The tile mesh or hardware instance whose draw calls use the bound.\r\n     * @param lowerBound The inclusive lower bound in the range [0, 1].\r\n     */\r\n    public setFadeLowerBound(mesh: DitheredTileFadeMesh, lowerBound: number): void {\r\n        this.setFadeBounds(mesh, lowerBound, this._meshBounds.get(mesh)?.upperBound ?? 1);\r\n    }\r\n\r\n    /**\r\n     * Sets the normalized exclusive upper Bayer interval bound for a mesh.\r\n     * @param mesh The tile mesh or hardware instance whose draw calls use the bound.\r\n     * @param upperBound The exclusive upper bound in the range [0, 1].\r\n     */\r\n    public setFadeUpperBound(mesh: DitheredTileFadeMesh, upperBound: number): void {\r\n        this.setFadeBounds(mesh, this._meshBounds.get(mesh)?.lowerBound ?? 0, upperBound);\r\n    }\r\n\r\n    /**\r\n     * Copies a mesh's current bounds without allocating.\r\n     * @param mesh The mesh whose bounds are queried.\r\n     * @param result The object that receives the bounds.\r\n     * @returns True when the mesh has explicit bounds. Otherwise false is returned with the source mesh's bounds for a hardware instance, or [0, 1].\r\n     */\r\n    public getFadeBoundsToRef(mesh: DitheredTileFadeMesh, result: IDitheredTileFadeBounds): boolean {\r\n        this._validateMesh(mesh);\r\n        const explicitBounds = this._meshBounds.get(mesh);\r\n        const bounds = explicitBounds ?? (mesh instanceof InstancedMesh ? this._meshBounds.get(mesh.sourceMesh) : undefined);\r\n        result.lowerBound = bounds?.lowerBound ?? 0;\r\n        result.upperBound = bounds?.upperBound ?? 1;\r\n        return explicitBounds !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Removes a mesh's explicit bounds. A hardware instance inherits its source mesh's bounds; a source mesh uses [0, 1].\r\n     * @param mesh The mesh to reset.\r\n     */\r\n    public resetFade(mesh: DitheredTileFadeMesh): void {\r\n        this._validateMesh(mesh);\r\n        this._meshBounds.delete(mesh);\r\n        this._updateInstancedFadeBounds(mesh, 0, 1, false);\r\n    }\r\n\r\n    /**\r\n     * Sets normalized Bayer interval bounds for one thin instance.\r\n     * @param mesh The source mesh containing the thin instance.\r\n     * @param index The thin instance index.\r\n     * @param lowerBound The inclusive lower bound in the range [0, 1].\r\n     * @param upperBound The exclusive upper bound in the range [0, 1].\r\n     * @param refresh Whether to immediately upload the updated attribute buffer.\r\n     */\r\n    public setThinInstanceFadeBounds(mesh: Mesh, index: number, lowerBound: number, upperBound: number, refresh = true): void {\r\n        this._validateBound(lowerBound, \"lowerBound\");\r\n        this._validateBound(upperBound, \"upperBound\");\r\n        this._validateThinInstanceIndex(mesh, index);\r\n        const buffer = this._ensureThinInstanceBuffer(mesh);\r\n        const offset = index * 4;\r\n        buffer[offset] = lowerBound;\r\n        buffer[offset + 1] = upperBound;\r\n        buffer[offset + 2] = 1;\r\n        buffer[offset + 3] = this._generation;\r\n        if (refresh) {\r\n            this.commitThinInstanceFadeBounds(mesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets normalized Bayer interval bounds for all thin instances from packed lower/upper pairs.\r\n     * @param mesh The source mesh containing the thin instances.\r\n     * @param bounds Packed lower/upper pairs, with two values per thin instance.\r\n     */\r\n    public setThinInstanceFadeBoundsBuffer(mesh: Mesh, bounds: Float32Array): void {\r\n        RegisterThinInstanceMesh();\r\n        const instanceCount = mesh.thinInstanceCount;\r\n        if (bounds.length !== instanceCount * 2) {\r\n            throw new RangeError(`bounds must contain exactly ${instanceCount * 2} values.`);\r\n        }\r\n\r\n        for (let index = 0; index < instanceCount; index++) {\r\n            const lowerBound = bounds[index * 2];\r\n            const upperBound = bounds[index * 2 + 1];\r\n            this._validateBound(lowerBound, `bounds[${index * 2}]`);\r\n            this._validateBound(upperBound, `bounds[${index * 2 + 1}]`);\r\n        }\r\n\r\n        const attributeData = this._ensureThinInstanceBuffer(mesh);\r\n        for (let index = 0; index < instanceCount; index++) {\r\n            const attributeOffset = index * 4;\r\n            attributeData[attributeOffset] = bounds[index * 2];\r\n            attributeData[attributeOffset + 1] = bounds[index * 2 + 1];\r\n            attributeData[attributeOffset + 2] = 1;\r\n            attributeData[attributeOffset + 3] = this._generation;\r\n        }\r\n\r\n        this.commitThinInstanceFadeBounds(mesh);\r\n    }\r\n\r\n    /**\r\n     * Uploads thin-instance fade changes after one or more setters used `refresh = false`.\r\n     * @param mesh The source mesh whose fade attribute buffer changed.\r\n     */\r\n    public commitThinInstanceFadeBounds(mesh: Mesh): void {\r\n        if (!this._thinInstanceFadeBuffers.has(mesh)) {\r\n            throw new Error(\"No thin-instance fade buffer has been created for this mesh.\");\r\n        }\r\n        mesh.thinInstanceBufferUpdated(this._getInstanceAttributeName());\r\n    }\r\n\r\n    /**\r\n     * Removes one thin instance's explicit bounds so it inherits the source mesh's bounds.\r\n     * @param mesh The source mesh containing the thin instance.\r\n     * @param index The thin instance index.\r\n     * @param refresh Whether to immediately upload the updated attribute buffer.\r\n     */\r\n    public resetThinInstanceFade(mesh: Mesh, index: number, refresh = true): void {\r\n        this._validateThinInstanceIndex(mesh, index);\r\n        const buffer = this._ensureThinInstanceBuffer(mesh);\r\n        const offset = index * 4;\r\n        buffer[offset] = 0;\r\n        buffer[offset + 1] = 1;\r\n        buffer[offset + 2] = 0;\r\n        buffer[offset + 3] = this._generation;\r\n        if (refresh) {\r\n            this.commitThinInstanceFadeBounds(mesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes all explicit mesh bounds while keeping the plugin enabled.\r\n     */\r\n    public reset(): void {\r\n        this._meshBounds = new WeakMap();\r\n        this._generation++;\r\n    }\r\n\r\n    /**\r\n     * Copies material-level configuration to another supported material.\r\n     *\r\n     * Per-mesh bounds are intentionally not copied because they belong to the source tile meshes.\r\n     * @param material The destination material, including a material clone.\r\n     * @returns The destination material's dithered tile fade plugin.\r\n     */\r\n    public copyToMaterial(material: DitheredTileFadeSupportedMaterial): DitheredTileFadeMaterialPlugin {\r\n        const plugin = DitheredTileFadeMaterialPlugin.GetOrCreate(material);\r\n        plugin.isEnabled = this._isEnabled;\r\n        return plugin;\r\n    }\r\n\r\n    /** @internal */\r\n    public override isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\r\n        if (this._shaderIncludeError) {\r\n            throw this._shaderIncludeError;\r\n        }\r\n        return this._shaderIncludeReady;\r\n    }\r\n\r\n    /**\r\n     * Uploads the current mesh's bounds for every draw, including shared and frozen materials.\r\n     * @param _uniformBuffer The material uniform buffer.\r\n     * @param _scene The scene being rendered.\r\n     * @param _engine The engine being used.\r\n     * @param subMesh The submesh being bound.\r\n     */\r\n    public override hardBindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void {\r\n        const effect = subMesh.effect;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        const mesh = subMesh.getMesh();\r\n        const bounds = this._meshBounds.get(mesh);\r\n        effect.setFloat4(\"ditheredFadeSettings\", bounds?.lowerBound ?? 0, bounds?.upperBound ?? 1, this._isEnabled ? 1 : 0, this._generation);\r\n    }\r\n\r\n    /**\r\n     * Registers the per-instance fade attribute when a mesh is rendered as a hardware or thin instance batch.\r\n     * @param attributes The attributes used to compile the material.\r\n     * @param _scene The scene containing the mesh.\r\n     * @param mesh The mesh being compiled.\r\n     */\r\n    public override getAttributes(attributes: string[], _scene: Scene, mesh: AbstractMesh): void {\r\n        const source = mesh instanceof InstancedMesh ? mesh.sourceMesh : mesh;\r\n        if (!(source instanceof Mesh)) {\r\n            return;\r\n        }\r\n\r\n        if (source.instances.length > 0) {\r\n            this._ensureInstancedBuffer(source);\r\n        }\r\n        if (source.hasThinInstances) {\r\n            this._ensureThinInstanceBuffer(source);\r\n        }\r\n        if (source.instances.length > 0 || source.hasThinInstances) {\r\n            attributes.push(this._getInstanceAttributeName());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the uniforms used by the plugin.\r\n     * @returns The external uniform names.\r\n     */\r\n    public override getUniforms(): { externalUniforms: string[] } {\r\n        return {\r\n            externalUniforms: [\"ditheredFadeSettings\"],\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the shader code injected by the plugin.\r\n     * @param shaderType The shader stage being customized.\r\n     * @param shaderLanguage The material shader language.\r\n     * @returns Fragment customizations, or null for the vertex stage.\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderType !== \"fragment\") {\r\n            const instanceAttributeName = this._getInstanceAttributeName();\r\n            if (shaderType !== \"vertex\") {\r\n                return null;\r\n            }\r\n\r\n            if (shaderLanguage === ShaderLanguage.WGSL) {\r\n                return {\r\n                    CUSTOM_VERTEX_DEFINITIONS: `\r\n#ifdef INSTANCES\r\nattribute ${instanceAttributeName}: vec4f;\r\n#endif\r\nvarying vDitheredTileFade: vec4f;\r\n`,\r\n                    CUSTOM_VERTEX_MAIN_BEGIN: `\r\n#ifdef INSTANCES\r\nvertexOutputs.vDitheredTileFade = input.${instanceAttributeName};\r\n#else\r\nvertexOutputs.vDitheredTileFade = vec4f(0.0);\r\n#endif\r\n`,\r\n                };\r\n            }\r\n\r\n            return {\r\n                CUSTOM_VERTEX_DEFINITIONS: `\r\n#ifdef INSTANCES\r\nattribute vec4 ${instanceAttributeName};\r\n#endif\r\nvarying vec4 vDitheredTileFade;\r\n`,\r\n                CUSTOM_VERTEX_MAIN_BEGIN: `\r\n#ifdef INSTANCES\r\nvDitheredTileFade = ${instanceAttributeName};\r\n#else\r\nvDitheredTileFade = vec4(0.0);\r\n#endif\r\n`,\r\n            };\r\n        }\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return {\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n#include<bayerDitherFunctions>\r\nuniform ditheredFadeSettings: vec4f;\r\nvarying vDitheredTileFade: vec4f;\r\n\r\nfn shouldDiscardDitheredTileFragment(position: vec2f, materialSettings: vec4f, instanceSettings: vec4f) -> bool {\r\n    var bounds = materialSettings.xy;\r\n#ifdef INSTANCES\r\n    if (instanceSettings.z > 0.5 && instanceSettings.w == materialSettings.w) {\r\n        bounds = instanceSettings.xy;\r\n    }\r\n#endif\r\n    let ditheredFadeSample = bayerDither8(floor(position)) / 64.0;\r\n    return materialSettings.z > 0.5 && (ditheredFadeSample < bounds.x || ditheredFadeSample >= bounds.y);\r\n}\r\n`,\r\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\nif (shouldDiscardDitheredTileFragment(fragmentInputs.position.xy, uniforms.ditheredFadeSettings, fragmentInputs.vDitheredTileFade)) {\r\n    discard;\r\n}\r\n`,\r\n                [DepthPrePassInjectionPoint]: `\r\n#ifdef DEPTHPREPASS\r\nif (shouldDiscardDitheredTileFragment(fragmentInputs.position.xy, uniforms.ditheredFadeSettings, fragmentInputs.vDitheredTileFade)) {\r\n    discard;\r\n}\r\n#endif\r\n#include<depthPrePass>\r\n`,\r\n            };\r\n        }\r\n\r\n        return {\r\n            CUSTOM_FRAGMENT_DEFINITIONS: `\r\n#include<bayerDitherFunctions>\r\nuniform vec4 ditheredFadeSettings;\r\nvarying vec4 vDitheredTileFade;\r\n\r\nbool shouldDiscardDitheredTileFragment(vec2 position, vec4 materialSettings, vec4 instanceSettings) {\r\n    vec2 bounds = materialSettings.xy;\r\n#ifdef INSTANCES\r\n    if (instanceSettings.z > 0.5 && instanceSettings.w == materialSettings.w) {\r\n        bounds = instanceSettings.xy;\r\n    }\r\n#endif\r\n    float ditheredFadeSample = bayerDither8(floor(position)) / 64.0;\r\n    return materialSettings.z > 0.5 && (ditheredFadeSample < bounds.x || ditheredFadeSample >= bounds.y);\r\n}\r\n`,\r\n            CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\nif (shouldDiscardDitheredTileFragment(gl_FragCoord.xy, ditheredFadeSettings, vDitheredTileFade)) {\r\n    discard;\r\n}\r\n`,\r\n            [DepthPrePassInjectionPoint]: `\r\n#ifdef DEPTHPREPASS\r\nif (shouldDiscardDitheredTileFragment(gl_FragCoord.xy, ditheredFadeSettings, vDitheredTileFade)) {\r\n    discard;\r\n}\r\n#endif\r\n#include<depthPrePass>\r\n`,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the class name.\r\n     * @returns The class name.\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DitheredTileFadeMaterialPlugin\";\r\n    }\r\n\r\n    /**\r\n     * Releases all weakly held runtime fade state and disables fading.\r\n     *\r\n     * The plugin remains attached to its material and can be reused through {@link GetOrCreate}.\r\n     */\r\n    public override dispose(): void {\r\n        this.reset();\r\n        this._isEnabled = false;\r\n    }\r\n\r\n    private static _ValidateNewPlugin(material: DitheredTileFadeSupportedMaterial): true {\r\n        DitheredTileFadeMaterialPlugin._ValidateMaterial(material);\r\n        if (material.pluginManager?.getPlugin(DitheredTileFadeMaterialPlugin.Name)) {\r\n            throw new Error(`The material \"${material.name}\" already has a plugin named \"${DitheredTileFadeMaterialPlugin.Name}\". Use GetOrCreate to reuse it.`);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private static _ValidateMaterial(material: DitheredTileFadeSupportedMaterial): void {\r\n        if (!(material instanceof StandardMaterial) && !(material instanceof PBRBaseMaterial)) {\r\n            throw new TypeError(\"DitheredTileFadeMaterialPlugin supports only StandardMaterial and PBRBaseMaterial-derived materials.\");\r\n        }\r\n    }\r\n\r\n    private _validateMesh(mesh: AbstractMesh): asserts mesh is DitheredTileFadeMesh {\r\n        if (!(mesh instanceof Mesh) && !(mesh instanceof InstancedMesh)) {\r\n            throw new TypeError(\"DitheredTileFadeMaterialPlugin supports only Mesh and InstancedMesh objects.\");\r\n        }\r\n    }\r\n\r\n    private _validateThinInstanceIndex(mesh: Mesh, index: number): void {\r\n        RegisterThinInstanceMesh();\r\n        if (!Number.isInteger(index) || index < 0 || index >= mesh.thinInstanceCount) {\r\n            throw new RangeError(`index must identify one of the mesh's ${mesh.thinInstanceCount} thin instances.`);\r\n        }\r\n    }\r\n\r\n    private _getInstanceAttributeName(): string {\r\n        return `ditheredTileFade${this._material.uniqueId}`;\r\n    }\r\n\r\n    private _ensureInstancedBuffer(source: Mesh): void {\r\n        if (this._instancedBufferSources.has(source)) {\r\n            return;\r\n        }\r\n\r\n        RegisterInstancedMesh();\r\n        source.registerInstancedBuffer(this._getInstanceAttributeName(), 4);\r\n        this._instancedBufferSources.add(source);\r\n    }\r\n\r\n    private _ensureThinInstanceBuffer(source: Mesh): Float32Array {\r\n        const requiredLength = source.thinInstanceCount * 4;\r\n        const existingBuffer = this._thinInstanceFadeBuffers.get(source);\r\n        if (existingBuffer && existingBuffer.length >= requiredLength) {\r\n            return existingBuffer;\r\n        }\r\n\r\n        RegisterThinInstanceMesh();\r\n        const buffer = new Float32Array(Math.max(requiredLength, 32 * 4));\r\n        if (existingBuffer) {\r\n            buffer.set(existingBuffer);\r\n        }\r\n        source.thinInstanceSetBuffer(this._getInstanceAttributeName(), buffer, 4, false);\r\n        this._thinInstanceFadeBuffers.set(source, buffer);\r\n        return buffer;\r\n    }\r\n\r\n    private _updateInstancedFadeBounds(mesh: DitheredTileFadeMesh, lowerBound: number, upperBound: number, configured: boolean): void {\r\n        const source = mesh instanceof InstancedMesh ? mesh.sourceMesh : mesh;\r\n        if (mesh instanceof InstancedMesh || source.instances.length > 0) {\r\n            this._ensureInstancedBuffer(source);\r\n            const current = mesh.instancedBuffers[this._getInstanceAttributeName()];\r\n            if (current instanceof Vector4) {\r\n                current.set(lowerBound, upperBound, configured ? 1 : 0, this._generation);\r\n            } else {\r\n                mesh.instancedBuffers[this._getInstanceAttributeName()] = new Vector4(lowerBound, upperBound, configured ? 1 : 0, this._generation);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _validateBound(value: number, name: string): void {\r\n        if (!Number.isFinite(value) || value < 0 || value > 1) {\r\n            throw new RangeError(`${name} must be a finite number in the range [0, 1].`);\r\n        }\r\n    }\r\n\r\n    private async _loadShaderIncludeAsync(shaderLanguage: ShaderLanguage): Promise<void> {\r\n        try {\r\n            await _LoadShaderIncludeAsync(shaderLanguage);\r\n            this._shaderIncludeReady = true;\r\n        } catch (error) {\r\n            this._shaderIncludeError = error;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serialize, expandToProperty } from \"../Misc/decorators\";\r\nimport { MaterialDefines } from \"./materialDefines\";\r\nimport { MaterialPluginBase } from \"./materialPluginBase.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { MaterialFlags } from \"./materialFlags\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type Engine } from \"core/Engines/engine.pure\";\r\nimport { type SubMesh } from \"core/Meshes/subMesh.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type PBRBaseMaterial } from \"./PBR/pbrBaseMaterial.pure\";\r\nimport { type StandardMaterial } from \"./standardMaterial.pure\";\r\nimport { BindTextureMatrix, PrepareDefinesForMergedUV } from \"./materialHelper.functions\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class DecalMapDefines extends MaterialDefines {\r\n    DECAL = false;\r\n    DECALDIRECTUV = 0;\r\n    DECAL_SMOOTHALPHA = false;\r\n    GAMMADECAL = false;\r\n}\r\n\r\n/**\r\n * Plugin that implements the decal map component of a material\r\n * @since 5.49.1\r\n */\r\nexport class DecalMapConfiguration extends MaterialPluginBase {\r\n    private _isEnabled = false;\r\n    /**\r\n     * Enables or disables the decal map on this material\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    private _smoothAlpha = false;\r\n\r\n    /**\r\n     * Enables or disables the smooth alpha mode on this material. Default: false.\r\n     * When enabled, the alpha value used to blend the decal map will be the squared value and will produce a smoother result.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor smoothAlpha = false;\r\n\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /** @internal */\r\n    public _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Creates a new DecalMapConfiguration\r\n     * @param material The material to attach the decal map plugin to\r\n     * @param addToPluginList If the plugin should be added to the material plugin list\r\n     */\r\n    constructor(material: PBRBaseMaterial | StandardMaterial, addToPluginList = true) {\r\n        super(material, \"DecalMap\", 150, new DecalMapDefines(), addToPluginList);\r\n\r\n        this.registerForExtraEvents = true; // because we override the hardBindForSubMesh method\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n    }\r\n\r\n    /**\r\n     * Checks if the sub mesh is ready to be used\r\n     * @param defines the list of defines\r\n     * @param scene the current scene\r\n     * @param engine the current engine\r\n     * @param subMesh the sub mesh to check\r\n     * @returns true if the sub mesh is ready\r\n     */\r\n    public override isReadyForSubMesh(defines: DecalMapDefines, scene: Scene, engine: Engine, subMesh: SubMesh): boolean {\r\n        const decalMap = subMesh.getMesh().decalMap;\r\n\r\n        if (!this._isEnabled || !decalMap?.texture || !MaterialFlags.DecalMapEnabled || !scene.texturesEnabled) {\r\n            return true;\r\n        }\r\n\r\n        return decalMap.isReady();\r\n    }\r\n\r\n    /**\r\n     * Prepares the defines before attributes are set\r\n     * @param defines the list of defines\r\n     * @param scene the current scene\r\n     * @param mesh the current mesh\r\n     */\r\n    public override prepareDefinesBeforeAttributes(defines: DecalMapDefines, scene: Scene, mesh: AbstractMesh): void {\r\n        const decalMap = mesh.decalMap;\r\n\r\n        if (!this._isEnabled || !decalMap?.texture || !MaterialFlags.DecalMapEnabled || !scene.texturesEnabled) {\r\n            const isDirty = defines.DECAL;\r\n            if (isDirty) {\r\n                defines.markAsTexturesDirty();\r\n            }\r\n            defines.DECAL = false;\r\n        } else {\r\n            const isDirty = !defines.DECAL || defines.GAMMADECAL !== decalMap.texture.gammaSpace;\r\n            if (isDirty) {\r\n                defines.markAsTexturesDirty();\r\n            }\r\n            defines.DECAL = true;\r\n            defines.GAMMADECAL = decalMap.texture.gammaSpace;\r\n            defines.DECAL_SMOOTHALPHA = this._smoothAlpha;\r\n            PrepareDefinesForMergedUV(decalMap.texture, defines, \"DECAL\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds the material data for a sub mesh\r\n     * @param uniformBuffer the uniform buffer to update\r\n     * @param scene the current scene\r\n     * @param _engine the current engine\r\n     * @param subMesh the sub mesh to bind\r\n     */\r\n    public override hardBindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, _engine: Engine, subMesh: SubMesh): void {\r\n        /**\r\n         * Note that we override hardBindForSubMesh and not bindForSubMesh because the material can be shared by multiple meshes,\r\n         * in which case mustRebind could return false even though the decal map is different for each mesh: that's because the decal map\r\n         * is not part of the material but hosted by the decalMap of the mesh instead.\r\n         */\r\n        const decalMap = subMesh.getMesh().decalMap;\r\n\r\n        if (!this._isEnabled || !decalMap?.texture || !MaterialFlags.DecalMapEnabled || !scene.texturesEnabled) {\r\n            return;\r\n        }\r\n\r\n        const isFrozen = this._material.isFrozen;\r\n        const texture = decalMap.texture;\r\n\r\n        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {\r\n            uniformBuffer.updateFloat4(\"vDecalInfos\", texture.coordinatesIndex, 0, 0, 0);\r\n            BindTextureMatrix(texture, uniformBuffer, \"decal\");\r\n        }\r\n\r\n        uniformBuffer.setTexture(\"decalSampler\", texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the class name of this plugin\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DecalMapConfiguration\";\r\n    }\r\n\r\n    /**\r\n     * Gets the samplers used by the plugin\r\n     * @param samplers the list of samplers to update\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"decalSampler\");\r\n    }\r\n\r\n    public override getUniforms(): { ubo?: Array<{ name: string; size: number; type: string }>; vertex?: string; fragment?: string } {\r\n        return {\r\n            ubo: [\r\n                { name: \"vDecalInfos\", size: 4, type: \"vec4\" },\r\n                { name: \"decalMatrix\", size: 16, type: \"mat4\" },\r\n            ],\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for materialDecalMapConfiguration.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMaterialDecalMapConfiguration(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DecalMapConfiguration\", DecalMapConfiguration);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { DetailMapConfiguration } from \"./material.detailMapConfiguration\";\r\nimport { type MaterialPluginBase } from \"./materialPluginBase\";\r\nimport { PBRAnisotropicConfiguration } from \"./PBR/pbrAnisotropicConfiguration\";\r\nimport { PBRBaseMaterial } from \"./PBR/pbrBaseMaterial.pure\";\r\nimport { PBRBRDFConfiguration } from \"./PBR/pbrBRDFConfiguration\";\r\nimport { PBRClearCoatConfiguration } from \"./PBR/pbrClearCoatConfiguration\";\r\nimport { PBRIridescenceConfiguration } from \"./PBR/pbrIridescenceConfiguration\";\r\nimport { PBRSheenConfiguration } from \"./PBR/pbrSheenConfiguration\";\r\nimport { PBRSubSurfaceConfiguration } from \"./PBR/pbrSubSurfaceConfiguration\";\r\nimport { StandardMaterial } from \"./standardMaterial.pure\";\r\n\r\nimport { type Material } from \"./material\";\r\n\r\n/**\r\n * Creates an instance of the anisotropic plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createPBRAnisotropicPlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial) {\r\n        return new PBRAnisotropicConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n\r\n/**\r\n * Creates an instance of the brdf plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createPBRBRDFPlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial) {\r\n        return new PBRBRDFConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n\r\n/**\r\n * Creates an instance of the clear coat plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createPBRClearCoatPlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial) {\r\n        return new PBRClearCoatConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n\r\n/**\r\n * Creates an instance of the iridescence plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createPBRIridescencePlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial) {\r\n        return new PBRIridescenceConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n\r\n/**\r\n * Creates an instance of the sheen plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createPBRSheenPlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial) {\r\n        return new PBRSheenConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n\r\n/**\r\n * Creates an instance of the sub surface plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createPBRSubSurfacePlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial) {\r\n        return new PBRSubSurfaceConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n\r\n/**\r\n * Creates an instance of the detail map plugin\r\n * @param material parent material the plugin will be created for\r\n * @returns the plugin instance or null if the plugin is incompatible with material\r\n */\r\nexport function createDetailMapPlugin(material: Material): Nullable<MaterialPluginBase> {\r\n    if (material instanceof PBRBaseMaterial || material instanceof StandardMaterial) {\r\n        return new DetailMapConfiguration(material);\r\n    }\r\n    return null;\r\n}\r\n","import { type RawTexture } from \"../Textures/rawTexture\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\n\r\n/**\r\n * Default settings for GreasedLine materials\r\n */\r\nexport class GreasedLineMaterialDefaults {\r\n    /**\r\n     * Default line color for newly created lines\r\n     */\r\n    public static DEFAULT_COLOR = Color3.White();\r\n    /**\r\n     * Default line width when sizeAttenuation is true\r\n     */\r\n    public static DEFAULT_WIDTH_ATTENUATED = 1;\r\n    /**\r\n     * Defaule line width\r\n     */\r\n    public static DEFAULT_WIDTH = 0.1;\r\n    /**\r\n     * Empty colors texture for WebGPU\r\n     */\r\n    public static EmptyColorsTexture: Nullable<RawTexture>;\r\n}\r\n","import { Curve3 } from \"../Maths/math.path\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type IFontData, CreateTextShapePaths } from \"../Meshes/Builders/textBuilder\";\r\nimport { type FloatArray, type IndicesArray } from \"../types\";\r\nimport { type GreasedLinePoints, type GreasedLinePointsOptions } from \"../Meshes/GreasedLine/greasedLineBaseMesh\";\r\nimport { type Color3 } from \"../Maths/math.color\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Engine } from \"../Engines/engine.pure\";\r\nimport { GreasedLineMaterialDefaults } from \"../Materials/GreasedLine/greasedLineMaterialDefaults\";\r\n\r\n/**\r\n * Tool functions for GreasedLine\r\n */\r\nexport class GreasedLineTools {\r\n    /**\r\n     * Converts GreasedLinePoints to number[][]\r\n     * @param points GreasedLinePoints\r\n     * @param options GreasedLineToolsConvertPointsOptions\r\n     * @returns number[][] with x, y, z coordinates of the points, like [[x, y, z, x, y, z, ...], [x, y, z, ...]]\r\n     */\r\n    public static ConvertPoints(points: GreasedLinePoints, options?: GreasedLinePointsOptions): number[][] {\r\n        if (points.length && Array.isArray(points) && typeof points[0] === \"number\") {\r\n            return [<number[]>points];\r\n        } else if (points.length && Array.isArray(points[0]) && typeof points[0][0] === \"number\") {\r\n            return <number[][]>points;\r\n        } else if (points.length && !Array.isArray(points[0]) && points[0] instanceof Vector3) {\r\n            const positions: number[] = [];\r\n            for (let j = 0; j < points.length; j++) {\r\n                const p = points[j] as Vector3;\r\n                positions.push(p.x, p.y, p.z);\r\n            }\r\n            return [positions];\r\n        } else if (points.length > 0 && Array.isArray(points[0]) && points[0].length > 0 && points[0][0] instanceof Vector3) {\r\n            const positions: number[][] = [];\r\n            const vectorPoints = points as Vector3[][];\r\n            for (const p of vectorPoints) {\r\n                positions.push(p.flatMap((p2) => [p2.x, p2.y, p2.z]));\r\n            }\r\n            return positions;\r\n        } else if (points instanceof Float32Array) {\r\n            if (options?.floatArrayStride) {\r\n                const positions: number[][] = [];\r\n                const stride = options.floatArrayStride * 3;\r\n                for (let i = 0; i < points.length; i += stride) {\r\n                    const linePoints = new Array(stride); // Pre-allocate memory for the line\r\n                    for (let j = 0; j < stride; j++) {\r\n                        linePoints[j] = points[i + j];\r\n                    }\r\n                    positions.push(linePoints);\r\n                }\r\n                return positions;\r\n            } else {\r\n                return [Array.from(points)];\r\n            }\r\n        } else if (points.length && points[0] instanceof Float32Array) {\r\n            const positions: number[][] = [];\r\n            for (const p of points) {\r\n                positions.push(Array.from(p as Float32Array));\r\n            }\r\n\r\n            return positions;\r\n        }\r\n\r\n        return [];\r\n    }\r\n\r\n    /**\r\n     * Omit zero length lines predicate for the MeshesToLines function\r\n     * @param p1 point1 position of the face\r\n     * @param p2 point2 position of the face\r\n     * @param p3 point3 position of the face\r\n     * @returns original points or null if any edge length is zero\r\n     */\r\n    public static OmitZeroLengthPredicate(p1: Vector3, p2: Vector3, p3: Vector3) {\r\n        const fileredPoints = [];\r\n        // edge1\r\n        if (p2.subtract(p1).lengthSquared() > 0) {\r\n            fileredPoints.push([p1, p2]);\r\n        }\r\n        // edge2\r\n        if (p3.subtract(p2).lengthSquared() > 0) {\r\n            fileredPoints.push([p2, p3]);\r\n        }\r\n        // edge3\r\n        if (p1.subtract(p3).lengthSquared() > 0) {\r\n            fileredPoints.push([p3, p1]);\r\n        }\r\n        return fileredPoints.length === 0 ? null : fileredPoints;\r\n    }\r\n\r\n    /**\r\n     * Omit duplicate lines predicate for the MeshesToLines function\r\n     * @param p1 point1 position of the face\r\n     * @param p2 point2 position of the face\r\n     * @param p3 point3 position of the face\r\n     * @param points array of points to search in\r\n     * @returns original points or null if any edge length is zero\r\n     */\r\n    public static OmitDuplicatesPredicate(p1: Vector3, p2: Vector3, p3: Vector3, points: Vector3[][]) {\r\n        const fileredPoints = [];\r\n        // edge1\r\n        if (!GreasedLineTools._SearchInPoints(p1, p2, points)) {\r\n            fileredPoints.push([p1, p2]);\r\n        }\r\n        // edge2\r\n        if (!GreasedLineTools._SearchInPoints(p2, p3, points)) {\r\n            fileredPoints.push([p2, p3]);\r\n        }\r\n        // edge3\r\n        if (!GreasedLineTools._SearchInPoints(p3, p1, points)) {\r\n            fileredPoints.push([p3, p1]);\r\n        }\r\n        return fileredPoints.length === 0 ? null : fileredPoints;\r\n    }\r\n\r\n    private static _SearchInPoints(p1: Vector3, p2: Vector3, points: Vector3[][]) {\r\n        for (const ps of points) {\r\n            for (let i = 0; i < ps.length; i++) {\r\n                if (ps[i]?.equals(p1)) {\r\n                    // find the first point\r\n                    // if it has a sibling of p2 the line already exists\r\n                    if (ps[i + 1]?.equals(p2) || ps[i - 1]?.equals(p2)) {\r\n                        return true;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Gets mesh triangles as line positions\r\n     * @param meshes array of meshes\r\n     * @param predicate predicate function which decides whether to include the mesh triangle/face in the ouput\r\n     * @returns array of arrays of points\r\n     */\r\n    public static MeshesToLines(\r\n        meshes: AbstractMesh[],\r\n        predicate?: (\r\n            p1: Vector3,\r\n            p2: Vector3,\r\n            p3: Vector3,\r\n            points: Vector3[][],\r\n            indiceIndex: number,\r\n            vertexIndex: number,\r\n            mesh: AbstractMesh,\r\n            meshIndex: number,\r\n            vertices: FloatArray,\r\n            indices: IndicesArray\r\n        ) => Vector3[][]\r\n    ) {\r\n        const points: Vector3[][] = [];\r\n\r\n        for (let meshIndex = 0; meshIndex < meshes.length; meshIndex++) {\r\n            const mesh = meshes[meshIndex];\r\n            const vertices = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n            const indices = mesh.getIndices();\r\n            if (vertices && indices) {\r\n                for (let i = 0, ii = 0; i < indices.length; i++) {\r\n                    const vi1 = indices[ii++] * 3;\r\n                    const vi2 = indices[ii++] * 3;\r\n                    const vi3 = indices[ii++] * 3;\r\n\r\n                    const p1 = new Vector3(vertices[vi1], vertices[vi1 + 1], vertices[vi1 + 2]);\r\n                    const p2 = new Vector3(vertices[vi2], vertices[vi2 + 1], vertices[vi2 + 2]);\r\n                    const p3 = new Vector3(vertices[vi3], vertices[vi3 + 1], vertices[vi3 + 2]);\r\n\r\n                    if (predicate) {\r\n                        const pointsFromPredicate = predicate(p1, p2, p3, points, i, vi1, mesh, meshIndex, vertices, indices);\r\n                        if (pointsFromPredicate) {\r\n                            for (const p of pointsFromPredicate) {\r\n                                points.push(p);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        points.push([p1, p2], [p2, p3], [p3, p1]);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return points;\r\n    }\r\n\r\n    /**\r\n     * Converts number coordinates to Vector3s\r\n     * @param points number array of x, y, z, x, y z, ... coordinates\r\n     * @returns Vector3 array\r\n     */\r\n    public static ToVector3Array(points: number[] | number[][]) {\r\n        if (Array.isArray(points[0])) {\r\n            const array: Vector3[][] = [];\r\n            const inputArray = points as number[][];\r\n            for (const subInputArray of inputArray) {\r\n                const subArray: Vector3[] = [];\r\n                for (let i = 0; i < subInputArray.length; i += 3) {\r\n                    subArray.push(new Vector3(subInputArray[i], subInputArray[i + 1], subInputArray[i + 2]));\r\n                }\r\n                array.push(subArray);\r\n            }\r\n            return array;\r\n        }\r\n\r\n        const inputArray = points as number[];\r\n        const array: Vector3[] = [];\r\n        for (let i = 0; i < inputArray.length; i += 3) {\r\n            array.push(new Vector3(inputArray[i], inputArray[i + 1], inputArray[i + 2]));\r\n        }\r\n        return array;\r\n    }\r\n\r\n    /**\r\n     * Gets a number array from a Vector3 array.\r\n     * You can you for example to convert your Vector3[] offsets to the required number[] for the offsets option.\r\n     * @param points Vector3 array\r\n     * @returns an array of x, y, z coordinates as numbers [x, y, z, x, y, z, x, y, z, ....]\r\n     */\r\n    public static ToNumberArray(points: Vector3[]) {\r\n        return points.flatMap((v) => [v.x, v.y, v.z]);\r\n    }\r\n\r\n    /**\r\n     * Calculates the sum of points of every line and the number of points in each line.\r\n     * This function is useful when you are drawing multiple lines in one mesh and you want\r\n     * to know the counts. For example for creating an offsets table.\r\n     * @param points point array\r\n     * @returns points count info\r\n     */\r\n    public static GetPointsCountInfo(points: number[][]): { total: number; counts: number[] } {\r\n        const counts = new Array(points.length);\r\n        let total = 0;\r\n        for (let n = points.length; n--;) {\r\n            counts[n] = points[n].length / 3;\r\n            total += counts[n];\r\n        }\r\n        return { total, counts };\r\n    }\r\n\r\n    /**\r\n     * Gets the length of the line counting all it's segments length\r\n     * @param data array of line points\r\n     * @returns length of the line\r\n     */\r\n    public static GetLineLength(data: Vector3[] | number[]): number {\r\n        if (data.length === 0) {\r\n            return 0;\r\n        }\r\n\r\n        let points: Vector3[];\r\n        if (typeof data[0] === \"number\") {\r\n            points = GreasedLineTools.ToVector3Array(<number[]>data) as Vector3[];\r\n        } else {\r\n            points = data as Vector3[];\r\n        }\r\n\r\n        const tmp = TmpVectors.Vector3[0];\r\n        let length = 0;\r\n        for (let index = 0; index < points.length - 1; index++) {\r\n            const point1 = points[index];\r\n            const point2 = points[index + 1];\r\n            length += point2.subtractToRef(point1, tmp).length();\r\n        }\r\n        return length;\r\n    }\r\n\r\n    /**\r\n     * Gets the length from the beginning to each point of the line as array.\r\n     * @param data array of line points\r\n     * @param buf optional pre-allocated buffer to reduce memory pressure, should be at least `data.length * 4 / 3` bytes\r\n     * @returns length array of the line\r\n     */\r\n    public static GetLineLengthArray(data: number[], buf?: ArrayBuffer): Float32Array {\r\n        const out = buf ? new Float32Array(buf, 0, data.length / 3) : new Float32Array(data.length / 3);\r\n        let length = 0;\r\n        for (let index = 0, pointsLength = data.length / 3 - 1; index < pointsLength; index++) {\r\n            let x = data[index * 3 + 0];\r\n            let y = data[index * 3 + 1];\r\n            let z = data[index * 3 + 2];\r\n            x -= data[index * 3 + 3];\r\n            y -= data[index * 3 + 4];\r\n            z -= data[index * 3 + 5];\r\n            const currentLength = Math.sqrt(x * x + y * y + z * z);\r\n            length += currentLength;\r\n            out[index + 1] = length;\r\n        }\r\n        return out;\r\n    }\r\n\r\n    /**\r\n     * Divides a segment into smaller segments.\r\n     * A segment is a part of the line between it's two points.\r\n     * @param point1 first point of the line\r\n     * @param point2 second point of the line\r\n     * @param segmentCount number of segments we want to have in the divided line\r\n     * @returns\r\n     */\r\n    public static SegmentizeSegmentByCount(point1: Vector3, point2: Vector3, segmentCount: number): Vector3[] {\r\n        const dividedLinePoints: Vector3[] = [];\r\n        const diff = point2.subtract(point1);\r\n        const divisor = TmpVectors.Vector3[0];\r\n        divisor.setAll(segmentCount);\r\n        const segmentVector = TmpVectors.Vector3[1];\r\n        diff.divideToRef(divisor, segmentVector);\r\n\r\n        let nextPoint = point1.clone();\r\n        dividedLinePoints.push(nextPoint);\r\n        for (let index = 0; index < segmentCount; index++) {\r\n            nextPoint = nextPoint.clone();\r\n            dividedLinePoints.push(nextPoint.addInPlace(segmentVector));\r\n        }\r\n\r\n        return dividedLinePoints;\r\n    }\r\n\r\n    /**\r\n     * Divides a line into segments.\r\n     * A segment is a part of the line between it's two points.\r\n     * @param what line points\r\n     * @param segmentLength length of each segment of the resulting line (distance between two line points)\r\n     * @returns line point\r\n     */\r\n    public static SegmentizeLineBySegmentLength(what: Vector3[] | number[] | { point1: Vector3; point2: Vector3; length: number }[], segmentLength: number): Vector3[] {\r\n        const subLines =\r\n            what[0] instanceof Vector3\r\n                ? GreasedLineTools.GetLineSegments(what as Vector3[])\r\n                : typeof what[0] === \"number\"\r\n                  ? GreasedLineTools.GetLineSegments(GreasedLineTools.ToVector3Array(what as number[]) as Vector3[])\r\n                  : (what as { point1: Vector3; point2: Vector3; length: number }[]);\r\n        const points: Vector3[] = [];\r\n        for (const s of subLines) {\r\n            if (s.length > segmentLength) {\r\n                const segments = GreasedLineTools.SegmentizeSegmentByCount(s.point1, s.point2, Math.ceil(s.length / segmentLength));\r\n                for (const seg of segments) {\r\n                    points.push(seg);\r\n                }\r\n            } else {\r\n                points.push(s.point1);\r\n                points.push(s.point2);\r\n            }\r\n        }\r\n        return points;\r\n    }\r\n\r\n    /**\r\n     * Divides a line into segments.\r\n     * A segment is a part of the line between it's two points.\r\n     * @param what line points\r\n     * @param segmentCount number of segments\r\n     * @returns line point\r\n     */\r\n    public static SegmentizeLineBySegmentCount(what: Vector3[] | number[], segmentCount: number): Vector3[] {\r\n        const points = <Vector3[]>(typeof what[0] === \"number\" ? GreasedLineTools.ToVector3Array(<number[]>what) : what);\r\n        const segmentLength = GreasedLineTools.GetLineLength(points) / segmentCount;\r\n        return GreasedLineTools.SegmentizeLineBySegmentLength(points, segmentLength);\r\n    }\r\n    /**\r\n     * Gets line segments.\r\n     * A segment is a part of the line between it's two points.\r\n     * @param points line points\r\n     * @returns segments information of the line segment including starting point, ending point and the distance between them\r\n     */\r\n    public static GetLineSegments(points: Vector3[]): { point1: Vector3; point2: Vector3; length: number }[] {\r\n        const segments = [];\r\n        for (let index = 0; index < points.length - 1; index++) {\r\n            const point1 = points[index];\r\n            const point2 = points[index + 1];\r\n            const length = point2.subtract(point1).length();\r\n            segments.push({ point1, point2, length });\r\n        }\r\n\r\n        return segments;\r\n    }\r\n\r\n    /**\r\n     * Gets the minimum and the maximum length of a line segment in the line.\r\n     * A segment is a part of the line between it's two points.\r\n     * @param points line points\r\n     * @returns\r\n     */\r\n    public static GetMinMaxSegmentLength(points: Vector3[]): { min: number; max: number } {\r\n        const subLines = GreasedLineTools.GetLineSegments(points);\r\n        const sorted = subLines.sort((s) => s.length);\r\n        return {\r\n            min: sorted[0].length,\r\n            max: sorted[sorted.length - 1].length,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Finds the last visible position in world space of the line according to the visibility parameter\r\n     * @param lineSegments segments of the line\r\n     * @param lineLength total length of the line\r\n     * @param visbility normalized value of visibility\r\n     * @param localSpace if true the result will be in local space (default is false)\r\n     * @returns world space coordinate of the last visible piece of the line\r\n     */\r\n    public static GetPositionOnLineByVisibility(lineSegments: { point1: Vector3; point2: Vector3; length: number }[], lineLength: number, visbility: number, localSpace = false) {\r\n        const lengthVisibilityRatio = lineLength * visbility;\r\n        let sumSegmentLengths = 0;\r\n        let segmentIndex = 0;\r\n\r\n        const lineSegmentsLength = lineSegments.length;\r\n        for (let i = 0; i < lineSegmentsLength; i++) {\r\n            if (lengthVisibilityRatio <= sumSegmentLengths + lineSegments[i].length) {\r\n                segmentIndex = i;\r\n                break;\r\n            }\r\n            sumSegmentLengths += lineSegments[i].length;\r\n        }\r\n\r\n        const s = (lengthVisibilityRatio - sumSegmentLengths) / lineSegments[segmentIndex].length;\r\n\r\n        lineSegments[segmentIndex].point2.subtractToRef(lineSegments[segmentIndex].point1, TmpVectors.Vector3[0]);\r\n        TmpVectors.Vector3[0].scaleToRef(s, TmpVectors.Vector3[1]);\r\n        if (!localSpace) {\r\n            TmpVectors.Vector3[1].addInPlace(lineSegments[segmentIndex].point1);\r\n        }\r\n\r\n        return TmpVectors.Vector3[1].clone();\r\n    }\r\n\r\n    /**\r\n     * Creates lines in a shape of circle/arc.\r\n     * A segment is a part of the line between it's two points.\r\n     * @param radiusX radiusX of the circle\r\n     * @param segments number of segments in the circle\r\n     * @param z z coordinate of the points. Defaults to 0.\r\n     * @param radiusY radiusY of the circle - you can draw an oval if using different values\r\n     * @param segmentAngle angle offset of the segments. Defaults to Math.PI * 2 / segments. Change this value to draw a part of the circle.\r\n     * @returns line points\r\n     */\r\n    public static GetCircleLinePoints(radiusX: number, segments: number, z = 0, radiusY = radiusX, segmentAngle = (Math.PI * 2) / segments) {\r\n        const points: Vector3[] = [];\r\n        for (let i = 0; i <= segments; i++) {\r\n            points.push(new Vector3(Math.cos(i * segmentAngle) * radiusX, Math.sin(i * segmentAngle) * radiusY, z));\r\n        }\r\n        return points;\r\n    }\r\n\r\n    /**\r\n     * Gets line points in a shape of a bezier curve\r\n     * @param p0 bezier point0\r\n     * @param p1 bezier point1\r\n     * @param p2 bezier point2\r\n     * @param segments number of segments in the curve\r\n     * @returns\r\n     */\r\n    public static GetBezierLinePoints(p0: Vector3, p1: Vector3, p2: Vector3, segments: number) {\r\n        return Curve3.CreateQuadraticBezier(p0, p1, p2, segments)\r\n            .getPoints()\r\n            .flatMap((v) => [v.x, v.y, v.z]);\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @param position position of the arrow cap (mainly you want to create a triangle, set widthUp and widthDown to the same value and omit widthStartUp and widthStartDown)\r\n     * @param direction direction which the arrow points to\r\n     * @param length length (size) of the arrow cap itself\r\n     * @param widthUp the arrow width above the line\r\n     * @param widthDown the arrow width belove the line\r\n     * @param widthStartUp the arrow width at the start of the arrow above the line. In most scenarios this is 0.\r\n     * @param widthStartDown the arrow width at the start of the arrow below the line. In most scenarios this is 0.\r\n     * @returns\r\n     */\r\n    public static GetArrowCap(position: Vector3, direction: Vector3, length: number, widthUp: number, widthDown: number, widthStartUp = 0, widthStartDown = 0) {\r\n        const points = [position.clone(), position.add(direction.multiplyByFloats(length, length, length))];\r\n        const widths = [widthUp, widthDown, widthStartUp, widthStartDown];\r\n\r\n        return {\r\n            points,\r\n            widths,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets 3D positions of points from a text and font\r\n     * @param text Text\r\n     * @param size Size of the font\r\n     * @param resolution Resolution of the font\r\n     * @param fontData defines the font data (can be generated with http://gero3.github.io/facetype.js/)\r\n     * @param z z coordinate\r\n     * @param includeInner include the inner parts of the font in the result. Default true. If false, only the outlines will be returned.\r\n     * @returns number[][] of 3D positions\r\n     */\r\n    public static GetPointsFromText(text: string, size: number, resolution: number, fontData: IFontData, z = 0, includeInner = true) {\r\n        const allPoints = [];\r\n        const shapePaths = CreateTextShapePaths(text, size, resolution, fontData);\r\n\r\n        for (const sp of shapePaths) {\r\n            for (const p of sp.paths) {\r\n                const points = [];\r\n                const points2d = p.getPoints();\r\n                for (const p2d of points2d) {\r\n                    points.push(p2d.x, p2d.y, z);\r\n                }\r\n                allPoints.push(points);\r\n            }\r\n\r\n            if (includeInner) {\r\n                for (const h of sp.holes) {\r\n                    const holes = [];\r\n                    const points2d = h.getPoints();\r\n                    for (const p2d of points2d) {\r\n                        holes.push(p2d.x, p2d.y, z);\r\n                    }\r\n                    allPoints.push(holes);\r\n                }\r\n            }\r\n        }\r\n\r\n        return allPoints;\r\n    }\r\n\r\n    /**\r\n     * Converts an array of Color3 to Uint8Array\r\n     * @param colors Arrray of Color3\r\n     * @returns Uin8Array of colors [r, g, b, a, r, g, b, a, ...]\r\n     */\r\n    public static Color3toRGBAUint8(colors: Color3[]): Uint8Array {\r\n        const colorTable: Uint8Array = new Uint8Array(colors.length * 4);\r\n        for (let i = 0, j = 0; i < colors.length; i++) {\r\n            colorTable[j++] = colors[i].r * 255;\r\n            colorTable[j++] = colors[i].g * 255;\r\n            colorTable[j++] = colors[i].b * 255;\r\n            colorTable[j++] = 255;\r\n        }\r\n\r\n        return colorTable;\r\n    }\r\n\r\n    /**\r\n     * Creates a RawTexture from an RGBA color array and sets it on the plugin material instance.\r\n     * @param name name of the texture\r\n     * @param colors Uint8Array of colors\r\n     * @param colorsSampling sampling mode of the created texture\r\n     * @param scene Scene\r\n     * @returns the colors texture\r\n     */\r\n    public static CreateColorsTexture(name: string, colors: Color3[], colorsSampling: number, scene: Scene) {\r\n        const maxTextureSize = scene.getEngine().getCaps().maxTextureSize ?? 1;\r\n        const width = colors.length > maxTextureSize ? maxTextureSize : colors.length;\r\n        const height = Math.ceil(colors.length / maxTextureSize);\r\n        if (height > 1) {\r\n            colors = [...colors, ...Array(width * height - colors.length).fill(colors[0])];\r\n        }\r\n        const colorsArray = GreasedLineTools.Color3toRGBAUint8(colors);\r\n        const colorsTexture = new RawTexture(colorsArray, width, height, Engine.TEXTUREFORMAT_RGBA, scene, false, true, colorsSampling);\r\n        colorsTexture.name = name;\r\n        return colorsTexture;\r\n    }\r\n\r\n    /**\r\n     * A minimum size texture for the colors sampler2D when there is no colors texture defined yet.\r\n     * For fast switching using the useColors property without the need to use defines.\r\n     * @param scene Scene\r\n     * @returns empty colors texture\r\n     */\r\n    public static PrepareEmptyColorsTexture(scene: Scene) {\r\n        if (!GreasedLineMaterialDefaults.EmptyColorsTexture) {\r\n            const colorsArray = new Uint8Array(4);\r\n            GreasedLineMaterialDefaults.EmptyColorsTexture = new RawTexture(colorsArray, 1, 1, Engine.TEXTUREFORMAT_RGBA, scene, false, false, RawTexture.NEAREST_NEAREST);\r\n            GreasedLineMaterialDefaults.EmptyColorsTexture.name = \"grlEmptyColorsTexture\";\r\n            // Clear the static reference when the texture is disposed (e.g. by scene.dispose())\r\n            // so that PrepareEmptyColorsTexture will create a fresh one for the next scene.\r\n            GreasedLineMaterialDefaults.EmptyColorsTexture.onDisposeObservable.addOnce(() => {\r\n                GreasedLineMaterialDefaults.EmptyColorsTexture = null;\r\n            });\r\n        }\r\n\r\n        return GreasedLineMaterialDefaults.EmptyColorsTexture;\r\n    }\r\n\r\n    /**\r\n     * Diposes the shared empty colors texture\r\n     */\r\n    public static DisposeEmptyColorsTexture() {\r\n        GreasedLineMaterialDefaults.EmptyColorsTexture?.dispose();\r\n        GreasedLineMaterialDefaults.EmptyColorsTexture = null;\r\n    }\r\n\r\n    /**\r\n     * Converts boolean to number.\r\n     * @param bool the bool value\r\n     * @returns 1 if true, 0 if false.\r\n     */\r\n    public static BooleanToNumber(bool?: boolean) {\r\n        return bool ? 1 : 0;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { RawTexture } from \"../Textures/rawTexture\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type UniformBuffer } from \"../uniformBuffer\";\r\nimport { Vector2, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type Color3 } from \"../../Maths/math.color.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Material } from \"../material.pure\";\r\nimport { MaterialDefines } from \"../materialDefines\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type BaseTexture } from \"../Textures/baseTexture.pure\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { GreasedLineMeshColorDistributionType, GreasedLineMeshColorMode, type GreasedLineMaterialOptions, type IGreasedLineMaterial } from \"./greasedLineMaterialInterfaces\";\r\n\r\nimport { GreasedLineMaterialDefaults } from \"./greasedLineMaterialDefaults\";\r\nimport { GreasedLineTools } from \"../../Misc/greasedLineTools\";\r\nimport { GetCustomCode as getCustomCodeGLSL } from \"./greasedLinePluginMaterialShadersGLSL\";\r\nimport { GetCustomCode as getCustomCodeWGSL } from \"./greasedLinePluginMaterialShadersWGSL\";\r\nimport { type GreasedLineBaseMesh } from \"../../Meshes\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class MaterialGreasedLineDefines extends MaterialDefines {\r\n    /**\r\n     * The material has a color option specified\r\n     */\r\n    GREASED_LINE_HAS_COLOR = false;\r\n    /**\r\n     * The material's size attenuation optiom\r\n     */\r\n    GREASED_LINE_SIZE_ATTENUATION = false;\r\n    /**\r\n     * The type of color distribution is set to line this value equals to true.\r\n     */\r\n    GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE = false;\r\n    /**\r\n     * True if scene is in right handed coordinate system.\r\n     */\r\n    GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM = false;\r\n\r\n    /**\r\n     * True if the line is in camera facing mode\r\n     */\r\n    GREASED_LINE_CAMERA_FACING = true;\r\n\r\n    /**\r\n     * True if the line uses offsets\r\n     */\r\n    GREASED_LINE_USE_OFFSETS = false;\r\n}\r\n\r\n/**\r\n * GreasedLinePluginMaterial for GreasedLineMesh/GreasedLineRibbonMesh.\r\n * Use the GreasedLineBuilder.CreateGreasedLineMaterial function to create and instance of this class.\r\n */\r\nexport class GreasedLinePluginMaterial extends MaterialPluginBase implements IGreasedLineMaterial {\r\n    /**\r\n     * Plugin name\r\n     */\r\n    public static readonly GREASED_LINE_MATERIAL_NAME = \"GreasedLinePluginMaterial\";\r\n\r\n    /**\r\n     * Force all the greased lines to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * Whether to use the colors option to colorize the line\r\n     */\r\n    public useColors: boolean;\r\n\r\n    /**\r\n     * Normalized value of how much of the line will be visible\r\n     * 0 - 0% of the line will be visible\r\n     * 1 - 100% of the line will be visible\r\n     */\r\n    public visibility: number;\r\n\r\n    /**\r\n     * Dash offset\r\n     */\r\n    public dashOffset: number;\r\n\r\n    /**\r\n     * Length of the dash. 0 to 1. 0.5 means half empty, half drawn.\r\n     */\r\n    public dashRatio: number;\r\n\r\n    /**\r\n     * Line base width. At each point the line width is calculated by widths[pointIndex] * width\r\n     */\r\n    public width: number;\r\n\r\n    /**\r\n     * The type of sampling of the colors texture. The values are the same when using with textures.\r\n     */\r\n    public colorsSampling: number;\r\n\r\n    /**\r\n     * Turns on/off dash mode\r\n     */\r\n    public useDash: boolean;\r\n\r\n    /**\r\n     * The mixing mode of the color paramater. Default value is GreasedLineMeshColorMode.SET\r\n     * @see GreasedLineMeshColorMode\r\n     */\r\n    public colorMode: GreasedLineMeshColorMode;\r\n\r\n    /**\r\n     * You can provide a colorsTexture to use instead of one generated from the 'colors' option\r\n     */\r\n    public colorsTexture: Nullable<RawTexture> = null;\r\n\r\n    private _scene: Scene;\r\n    private _dashCount: number;\r\n    private _dashArray: number;\r\n    private _color: Nullable<Color3>;\r\n    private _colors: Nullable<Color3[]>;\r\n    private _colorsDistributionType: GreasedLineMeshColorDistributionType;\r\n    private _resolution: Vector2;\r\n    private _aspect: number;\r\n    private _sizeAttenuation: boolean;\r\n\r\n    private _cameraFacing: boolean;\r\n\r\n    private _engine: AbstractEngine;\r\n\r\n    private _forceGLSL = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language\r\n     * @param _shaderLanguage The shader language to use\r\n     * @returns true if the plugin is compatible with the shader language. Return always true since both GLSL and WGSL are supported\r\n     */\r\n    public override isCompatible(_shaderLanguage: ShaderLanguage): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance of the GreasedLinePluginMaterial\r\n     * @param material Base material for the plugin\r\n     * @param scene The scene\r\n     * @param options Plugin options\r\n     */\r\n    constructor(material: Material, scene?: Scene, options?: GreasedLineMaterialOptions) {\r\n        options = options || {\r\n            color: GreasedLineMaterialDefaults.DEFAULT_COLOR,\r\n        };\r\n\r\n        const defines = new MaterialGreasedLineDefines();\r\n        defines.GREASED_LINE_HAS_COLOR = !!options.color && !options.useColors;\r\n        defines.GREASED_LINE_SIZE_ATTENUATION = options.sizeAttenuation ?? false;\r\n        defines.GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE = options.colorDistributionType === GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_LINE;\r\n        defines.GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM = (scene ?? material.getScene()).useRightHandedSystem;\r\n        defines.GREASED_LINE_CAMERA_FACING = options.cameraFacing ?? true;\r\n        super(material, GreasedLinePluginMaterial.GREASED_LINE_MATERIAL_NAME, 200, defines, true, true);\r\n\r\n        this._forceGLSL = options?.forceGLSL || GreasedLinePluginMaterial.ForceGLSL;\r\n\r\n        this._scene = scene ?? material.getScene();\r\n        this._engine = this._scene.getEngine();\r\n\r\n        this._cameraFacing = options.cameraFacing ?? true;\r\n\r\n        this.visibility = options.visibility ?? 1;\r\n        this.useDash = options.useDash ?? false;\r\n        this.dashRatio = options.dashRatio ?? 0.5;\r\n        this.dashOffset = options.dashOffset ?? 0;\r\n        this.width = options.width ? options.width : options.sizeAttenuation ? GreasedLineMaterialDefaults.DEFAULT_WIDTH_ATTENUATED : GreasedLineMaterialDefaults.DEFAULT_WIDTH;\r\n        this._sizeAttenuation = options.sizeAttenuation ?? false;\r\n        this.colorMode = options.colorMode ?? GreasedLineMeshColorMode.COLOR_MODE_SET;\r\n        this._color = options.color ?? null;\r\n        this.useColors = options.useColors ?? false;\r\n        this._colorsDistributionType = options.colorDistributionType ?? GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_SEGMENT;\r\n        this.colorsSampling = options.colorsSampling ?? RawTexture.NEAREST_NEAREST;\r\n        this._colors = options.colors ?? null;\r\n\r\n        this.dashCount = options.dashCount ?? 1; // calculate the _dashArray value, call the setter\r\n        this.resolution = options.resolution ?? new Vector2(this._engine.getRenderWidth(), this._engine.getRenderHeight()); // calculate aspect call the setter\r\n\r\n        if (options.colorsTexture) {\r\n            this.colorsTexture = options.colorsTexture; // colorsTexture from options takes precedence\r\n        } else {\r\n            if (this._colors) {\r\n                this.colorsTexture = GreasedLineTools.CreateColorsTexture(`${material.name}-colors-texture`, this._colors, this.colorsSampling, this._scene);\r\n            } else {\r\n                this._color = this._color ?? GreasedLineMaterialDefaults.DEFAULT_COLOR;\r\n                GreasedLineTools.PrepareEmptyColorsTexture(this._scene);\r\n            }\r\n        }\r\n\r\n        this._engine.onDisposeObservable.add(() => {\r\n            GreasedLineTools.DisposeEmptyColorsTexture();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Get the shader attributes\r\n     * @param attributes array which will be filled with the attributes\r\n     */\r\n    override getAttributes(attributes: string[]) {\r\n        attributes.push(\"grl_offsets\");\r\n        attributes.push(\"grl_widths\");\r\n        attributes.push(\"grl_colorPointers\");\r\n        attributes.push(\"grl_counters\");\r\n        if (this._cameraFacing) {\r\n            attributes.push(\"grl_previousAndSide\");\r\n            attributes.push(\"grl_nextAndCounters\");\r\n        } else {\r\n            attributes.push(\"grl_slopes\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the shader samplers\r\n     * @param samplers\r\n     */\r\n    override getSamplers(samplers: string[]) {\r\n        samplers.push(\"grl_colors\");\r\n    }\r\n\r\n    /**\r\n     * Get the shader textures\r\n     * @param activeTextures array which will be filled with the textures\r\n     */\r\n    public override getActiveTextures(activeTextures: BaseTexture[]): void {\r\n        if (this.colorsTexture) {\r\n            activeTextures.push(this.colorsTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the shader uniforms\r\n     * @param shaderLanguage The shader language to use\r\n     * @returns uniforms\r\n     */\r\n    override getUniforms(shaderLanguage = ShaderLanguage.GLSL) {\r\n        const ubo = [\r\n            { name: \"grl_singleColor\", size: 3, type: \"vec3\" },\r\n            { name: \"grl_textureSize\", size: 2, type: \"vec2\" },\r\n            { name: \"grl_dashOptions\", size: 4, type: \"vec4\" },\r\n            { name: \"grl_colorMode_visibility_colorsWidth_useColors\", size: 4, type: \"vec4\" },\r\n        ];\r\n        if (this._cameraFacing) {\r\n            ubo.push({ name: \"grl_projection\", size: 16, type: \"mat4\" }, { name: \"grl_aspect_resolution_lineWidth\", size: 4, type: \"vec4\" });\r\n        }\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            ubo.push({\r\n                name: \"viewProjection\",\r\n                size: 16,\r\n                type: \"mat4\",\r\n            });\r\n        }\r\n\r\n        return {\r\n            ubo,\r\n            vertex:\r\n                this._cameraFacing && this._isGLSL(shaderLanguage)\r\n                    ? `\r\n                    uniform vec4 grl_aspect_resolution_lineWidth;\r\n                    uniform mat4 grl_projection;\r\n    `\r\n                    : \"\",\r\n            fragment: this._isGLSL(shaderLanguage)\r\n                ? `\r\n                    uniform vec4 grl_dashOptions;\r\n                    uniform vec2 grl_textureSize;\r\n                    uniform vec4 grl_colorMode_visibility_colorsWidth_useColors;\r\n                    uniform vec3 grl_singleColor;\r\n    `\r\n                : \"\",\r\n        };\r\n    }\r\n\r\n    // only getter, it doesn't make sense to use this plugin on a mesh other than GreasedLineMesh\r\n    // and it doesn't make sense to disable it on the mesh\r\n    get isEnabled() {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Bind the uniform buffer\r\n     * @param uniformBuffer\r\n     */\r\n    override bindForSubMesh(uniformBuffer: UniformBuffer) {\r\n        if (this._cameraFacing) {\r\n            uniformBuffer.updateMatrix(\"grl_projection\", this._scene.getProjectionMatrix());\r\n            if (!this._isGLSL(this._material.shaderLanguage)) {\r\n                uniformBuffer.updateMatrix(\"viewProjection\", this._scene.getTransformMatrix());\r\n            }\r\n\r\n            const resolutionLineWidth = TmpVectors.Vector4[0];\r\n            resolutionLineWidth.x = this._aspect;\r\n            resolutionLineWidth.y = this._resolution.x;\r\n            resolutionLineWidth.z = this._resolution.y;\r\n            resolutionLineWidth.w = this.width;\r\n            uniformBuffer.updateVector4(\"grl_aspect_resolution_lineWidth\", resolutionLineWidth);\r\n        }\r\n\r\n        const dashOptions = TmpVectors.Vector4[0];\r\n        dashOptions.x = GreasedLineTools.BooleanToNumber(this.useDash);\r\n        dashOptions.y = this._dashArray;\r\n        dashOptions.z = this.dashOffset;\r\n        dashOptions.w = this.dashRatio;\r\n        uniformBuffer.updateVector4(\"grl_dashOptions\", dashOptions);\r\n\r\n        const colorModeVisibilityColorsWidthUseColors = TmpVectors.Vector4[1];\r\n        colorModeVisibilityColorsWidthUseColors.x = this.colorMode;\r\n        colorModeVisibilityColorsWidthUseColors.y = this.visibility;\r\n        colorModeVisibilityColorsWidthUseColors.z = this.colorsTexture ? this.colorsTexture.getSize().width : 0;\r\n        colorModeVisibilityColorsWidthUseColors.w = GreasedLineTools.BooleanToNumber(this.useColors);\r\n        uniformBuffer.updateVector4(\"grl_colorMode_visibility_colorsWidth_useColors\", colorModeVisibilityColorsWidthUseColors);\r\n\r\n        if (this._color) {\r\n            uniformBuffer.updateColor3(\"grl_singleColor\", this._color);\r\n        }\r\n        const texture = this.colorsTexture ?? GreasedLineMaterialDefaults.EmptyColorsTexture;\r\n        uniformBuffer.setTexture(\"grl_colors\", texture);\r\n        uniformBuffer.updateFloat2(\"grl_textureSize\", texture?.getSize().width ?? 1, texture?.getSize().height ?? 1);\r\n    }\r\n\r\n    /**\r\n     * Prepare the defines\r\n     * @param defines\r\n     * @param _scene\r\n     * @param mesh\r\n     */\r\n    override prepareDefines(defines: MaterialGreasedLineDefines, _scene: Scene, mesh: AbstractMesh) {\r\n        defines.GREASED_LINE_HAS_COLOR = !!this.color && !this.useColors;\r\n        defines.GREASED_LINE_SIZE_ATTENUATION = this._sizeAttenuation;\r\n        defines.GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE = this._colorsDistributionType === GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_LINE;\r\n        defines.GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM = _scene.useRightHandedSystem;\r\n        defines.GREASED_LINE_CAMERA_FACING = this._cameraFacing;\r\n        defines.GREASED_LINE_USE_OFFSETS = !!(mesh as GreasedLineBaseMesh).offsets;\r\n    }\r\n\r\n    /**\r\n     * Get the class name\r\n     * @returns class name\r\n     */\r\n    override getClassName() {\r\n        return GreasedLinePluginMaterial.GREASED_LINE_MATERIAL_NAME;\r\n    }\r\n\r\n    /**\r\n     * Get shader code\r\n     * @param shaderType vertex/fragment\r\n     * @param shaderLanguage GLSL or WGSL\r\n     * @returns shader code\r\n     */\r\n    override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        if (this._isGLSL(shaderLanguage)) {\r\n            return getCustomCodeGLSL(shaderType, this._cameraFacing);\r\n        }\r\n        return getCustomCodeWGSL(shaderType, this._cameraFacing);\r\n    }\r\n\r\n    /**\r\n     * Disposes the plugin material.\r\n     */\r\n    public override dispose(): void {\r\n        this.colorsTexture?.dispose();\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Returns the colors used to colorize the line\r\n     */\r\n    get colors() {\r\n        return this._colors;\r\n    }\r\n\r\n    /**\r\n     * Sets the colors used to colorize the line\r\n     */\r\n    set colors(value: Nullable<Color3[]>) {\r\n        this.setColors(value);\r\n    }\r\n\r\n    /**\r\n     * Creates or updates the colors texture\r\n     * @param colors color table RGBA\r\n     * @param lazy if lazy, the colors are not updated\r\n     * @param forceNewTexture force creation of a new texture\r\n     */\r\n    public setColors(colors: Nullable<Color3[]>, lazy = false, forceNewTexture = false): void {\r\n        const origColorsCount = this._colors?.length ?? 0;\r\n\r\n        this._colors = colors;\r\n\r\n        if (colors === null || colors.length === 0) {\r\n            this.colorsTexture?.dispose();\r\n            return;\r\n        }\r\n\r\n        if (lazy && !forceNewTexture) {\r\n            return;\r\n        }\r\n\r\n        if (this.colorsTexture && origColorsCount === colors.length && !forceNewTexture) {\r\n            const colorArray = GreasedLineTools.Color3toRGBAUint8(colors);\r\n            this.colorsTexture.update(colorArray);\r\n        } else {\r\n            this.colorsTexture?.dispose();\r\n            this.colorsTexture = GreasedLineTools.CreateColorsTexture(`${this._material.name}-colors-texture`, colors, this.colorsSampling, this._scene);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the material. Use when material created in lazy mode.\r\n     */\r\n    public updateLazy() {\r\n        if (this._colors) {\r\n            this.setColors(this._colors, false, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the number of dashes in the line\r\n     */\r\n    get dashCount() {\r\n        return this._dashCount;\r\n    }\r\n    /**\r\n     * Sets the number of dashes in the line\r\n     * @param value dash\r\n     */\r\n    set dashCount(value: number) {\r\n        this._dashCount = value;\r\n        this._dashArray = 1 / value;\r\n    }\r\n\r\n    /**\r\n     * If set to true the line will be rendered always with the same width regardless how far it is located from the camera.\r\n     * Not supported for non camera facing lines.\r\n     */\r\n    get sizeAttenuation() {\r\n        return this._sizeAttenuation;\r\n    }\r\n\r\n    /**\r\n     * Turn on/off size attenuation of the width option and widths array.\r\n     * Not supported for non camera facing lines.\r\n     * @param value If set to true the line will be rendered always with the same width regardless how far it is located from the camera.\r\n     */\r\n    set sizeAttenuation(value: boolean) {\r\n        this._sizeAttenuation = value;\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets the color of the line\r\n     */\r\n    get color() {\r\n        return this._color;\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the line\r\n     * @param value Color3 or null to clear the color. You need to clear the color if you use colors and useColors = true\r\n     */\r\n    set color(value: Nullable<Color3>) {\r\n        this.setColor(value);\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the line. If set the whole line will be mixed with this color according to the colorMode option.\r\n     * @param value color\r\n     * @param doNotMarkDirty if true, the material will not be marked as dirty\r\n     */\r\n    public setColor(value: Nullable<Color3>, doNotMarkDirty = false) {\r\n        if ((this._color === null && value !== null) || (this._color !== null && value === null)) {\r\n            this._color = value;\r\n            if (!doNotMarkDirty) {\r\n                this.markAllDefinesAsDirty();\r\n            }\r\n        } else {\r\n            this._color = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the color distributiopn type\r\n     */\r\n    get colorsDistributionType() {\r\n        return this._colorsDistributionType;\r\n    }\r\n\r\n    /**\r\n     * Sets the color distribution type\r\n     * @see GreasedLineMeshColorDistributionType\r\n     * @param value color distribution type\r\n     */\r\n    set colorsDistributionType(value: GreasedLineMeshColorDistributionType) {\r\n        this._colorsDistributionType = value;\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets the resolution\r\n     */\r\n    get resolution() {\r\n        return this._resolution;\r\n    }\r\n\r\n    /**\r\n     * Sets the resolution\r\n     * @param value resolution of the screen for GreasedLine\r\n     */\r\n    set resolution(value: Vector2) {\r\n        this._aspect = value.x / value.y;\r\n        this._resolution = value;\r\n    }\r\n\r\n    /**\r\n     * Serializes this plugin material\r\n     * @returns serializationObjec\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        const greasedLineMaterialOptions: GreasedLineMaterialOptions = {\r\n            colorDistributionType: this._colorsDistributionType,\r\n            colorsSampling: this.colorsSampling,\r\n            colorMode: this.colorMode,\r\n            dashCount: this._dashCount,\r\n            dashOffset: this.dashOffset,\r\n            dashRatio: this.dashRatio,\r\n            resolution: this._resolution,\r\n            sizeAttenuation: this._sizeAttenuation,\r\n            useColors: this.useColors,\r\n            useDash: this.useDash,\r\n            visibility: this.visibility,\r\n            width: this.width,\r\n        };\r\n\r\n        if (this._colors) {\r\n            greasedLineMaterialOptions.colors = this._colors;\r\n        }\r\n        if (this._color) {\r\n            greasedLineMaterialOptions.color = this._color;\r\n        }\r\n\r\n        serializationObject.greasedLineMaterialOptions = greasedLineMaterialOptions;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized objects\r\n     * @param source serialized object\r\n     * @param scene scene\r\n     * @param rootUrl root url for textures\r\n     */\r\n    public override parse(source: any, scene: Scene, rootUrl: string): void {\r\n        super.parse(source, scene, rootUrl);\r\n        const greasedLineMaterialOptions = <GreasedLineMaterialOptions>source.greasedLineMaterialOptions;\r\n\r\n        this.colorsTexture?.dispose();\r\n\r\n        if (greasedLineMaterialOptions.color) {\r\n            this.setColor(greasedLineMaterialOptions.color, true);\r\n        }\r\n        if (greasedLineMaterialOptions.colorDistributionType) {\r\n            this.colorsDistributionType = greasedLineMaterialOptions.colorDistributionType;\r\n        }\r\n        if (greasedLineMaterialOptions.colors) {\r\n            this.colors = greasedLineMaterialOptions.colors;\r\n        }\r\n        if (greasedLineMaterialOptions.colorsSampling) {\r\n            this.colorsSampling = greasedLineMaterialOptions.colorsSampling;\r\n        }\r\n        if (greasedLineMaterialOptions.colorMode) {\r\n            this.colorMode = greasedLineMaterialOptions.colorMode;\r\n        }\r\n        if (greasedLineMaterialOptions.useColors) {\r\n            this.useColors = greasedLineMaterialOptions.useColors;\r\n        }\r\n        if (greasedLineMaterialOptions.visibility) {\r\n            this.visibility = greasedLineMaterialOptions.visibility;\r\n        }\r\n        if (greasedLineMaterialOptions.useDash) {\r\n            this.useDash = greasedLineMaterialOptions.useDash;\r\n        }\r\n        if (greasedLineMaterialOptions.dashCount) {\r\n            this.dashCount = greasedLineMaterialOptions.dashCount;\r\n        }\r\n        if (greasedLineMaterialOptions.dashRatio) {\r\n            this.dashRatio = greasedLineMaterialOptions.dashRatio;\r\n        }\r\n        if (greasedLineMaterialOptions.dashOffset) {\r\n            this.dashOffset = greasedLineMaterialOptions.dashOffset;\r\n        }\r\n        if (greasedLineMaterialOptions.width) {\r\n            this.width = greasedLineMaterialOptions.width;\r\n        }\r\n        if (greasedLineMaterialOptions.sizeAttenuation) {\r\n            this.sizeAttenuation = greasedLineMaterialOptions.sizeAttenuation;\r\n        }\r\n        if (greasedLineMaterialOptions.resolution) {\r\n            this.resolution = greasedLineMaterialOptions.resolution;\r\n        }\r\n        if (this.colors) {\r\n            this.colorsTexture = GreasedLineTools.CreateColorsTexture(`${this._material.name}-colors-texture`, this.colors, this.colorsSampling, scene);\r\n        } else {\r\n            GreasedLineTools.PrepareEmptyColorsTexture(scene);\r\n        }\r\n\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current configuration into another one.\r\n     * @param plugin define the config where to copy the info\r\n     */\r\n    public override copyTo(plugin: MaterialPluginBase): void {\r\n        const dest = plugin as GreasedLinePluginMaterial;\r\n\r\n        dest.colorsTexture?.dispose();\r\n\r\n        if (this._colors) {\r\n            dest.colorsTexture = GreasedLineTools.CreateColorsTexture(`${dest._material.name}-colors-texture`, this._colors, dest.colorsSampling, this._scene);\r\n        }\r\n\r\n        dest.setColor(this.color, true);\r\n        dest.colorsDistributionType = this.colorsDistributionType;\r\n        dest.colorsSampling = this.colorsSampling;\r\n        dest.colorMode = this.colorMode;\r\n        dest.useColors = this.useColors;\r\n        dest.visibility = this.visibility;\r\n        dest.useDash = this.useDash;\r\n        dest.dashCount = this.dashCount;\r\n        dest.dashRatio = this.dashRatio;\r\n        dest.dashOffset = this.dashOffset;\r\n        dest.width = this.width;\r\n        dest.sizeAttenuation = this.sizeAttenuation;\r\n        dest.resolution = this.resolution;\r\n\r\n        dest.markAllDefinesAsDirty();\r\n    }\r\n\r\n    private _isGLSL(shaderLanguage: ShaderLanguage) {\r\n        return shaderLanguage === ShaderLanguage.GLSL || this._forceGLSL;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for greasedLinePluginMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGreasedLinePluginMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(`BABYLON.${GreasedLinePluginMaterial.GREASED_LINE_MATERIAL_NAME}`, GreasedLinePluginMaterial);\r\n}\r\n","import { type Nullable } from \"../../types\";\nimport { GreasedLineMeshColorMode } from \"./greasedLineMaterialInterfaces\";\n\n/**\n * Returns GLSL custom shader code\n * @param shaderType vertex or fragment\n * @param cameraFacing is in camera facing mode?\n * @returns GLSL custom shader code\n */\n/** @internal */\nexport function GetCustomCode(shaderType: string, cameraFacing: boolean): Nullable<{ [pointName: string]: string }> {\n    if (shaderType === \"vertex\") {\n        const obj: any = {\n            CUSTOM_VERTEX_DEFINITIONS: `\n                attribute float grl_widths;\n                #ifdef GREASED_LINE_USE_OFFSETS\n                    attribute vec3 grl_offsets;\n                #endif\n                attribute float grl_colorPointers;\n                varying float grlCounters;\n                varying float grlColorPointer;\n\n                #ifdef GREASED_LINE_CAMERA_FACING\n                    attribute vec4 grl_previousAndSide;\n                    attribute vec4 grl_nextAndCounters;\n\n                    vec2 grlFix( vec4 i, float aspect ) {\n                        vec2 res = i.xy / i.w;\n                        res.x *= aspect;\n                        return res;\n                    }\n                #else\n                    attribute vec3 grl_slopes;\n                    attribute float grl_counters;\n                #endif\n                `,\n            CUSTOM_VERTEX_UPDATE_POSITION: `\n                #ifdef GREASED_LINE_USE_OFFSETS\n                    vec3 grlPositionOffset = grl_offsets;\n                #else\n                    vec3 grlPositionOffset = vec3(0.);\n                #endif\n\n                #ifdef GREASED_LINE_CAMERA_FACING\n                    positionUpdated += grlPositionOffset;\n                #else\n                    positionUpdated = (positionUpdated + grlPositionOffset) + (grl_slopes * grl_widths);\n                #endif\n                `,\n            CUSTOM_VERTEX_MAIN_END: `\n                grlColorPointer = grl_colorPointers;\n\n                #ifdef GREASED_LINE_CAMERA_FACING\n\n                    float grlAspect = grl_aspect_resolution_lineWidth.x;\n                    float grlBaseWidth = grl_aspect_resolution_lineWidth.w;\n\n                    vec3 grlPrevious = grl_previousAndSide.xyz;\n                    float grlSide = grl_previousAndSide.w;\n\n                    vec3 grlNext = grl_nextAndCounters.xyz;\n                    grlCounters = grl_nextAndCounters.w;\n                    float grlWidth = grlBaseWidth * grl_widths;\n                    \n                    vec3 worldDir = normalize(grlNext - grlPrevious);\n                    vec3 nearPosition = positionUpdated + (worldDir * 0.01);\n                    mat4 grlMatrix = viewProjection * finalWorld;\n                    vec4 grlFinalPosition = grlMatrix * vec4(positionUpdated , 1.0);\n                    vec4 screenNearPos = grlMatrix * vec4(nearPosition, 1.0);\n                    vec2 grlLinePosition = grlFix(grlFinalPosition, grlAspect);\n                    vec2 grlLineNearPosition = grlFix(screenNearPos, grlAspect);\n                    vec2 grlDir = normalize(grlLineNearPosition - grlLinePosition);\n\n                    vec4 grlNormal = vec4(-grlDir.y, grlDir.x, 0., 1.);\n\n                    #ifdef GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM\n                        grlNormal.xy *= -.5 * grlWidth;\n                    #else\n                        grlNormal.xy *= .5 * grlWidth;\n                    #endif\n\n                    grlNormal *= grl_projection;\n\n                    #ifdef GREASED_LINE_SIZE_ATTENUATION\n                        grlNormal.xy *= grlFinalPosition.w;\n                        grlNormal.xy /= (vec4(grl_aspect_resolution_lineWidth.yz, 0., 1.) * grl_projection).xy;\n                    #endif\n\n                    grlFinalPosition.xy += grlNormal.xy * grlSide;\n                    gl_Position = grlFinalPosition;\n\n                    vPositionW = vec3(grlFinalPosition);\n                #else\n                    grlCounters = grl_counters;\n                #endif\n                `,\n        };\n        if (cameraFacing) {\n            obj[\"!gl_Position\\\\=viewProjection\\\\*worldPos;\"] = \"//\"; // not needed for camera facing GRL\n        }\n        return obj;\n    }\n\n    if (shaderType === \"fragment\") {\n        return {\n            CUSTOM_FRAGMENT_DEFINITIONS: `\n                    #ifdef PBR\n                         #define grlFinalColor finalColor\n                    #else\n                         #define grlFinalColor color\n                    #endif\n\n                    varying float grlCounters;\n                    varying float grlColorPointer;\n                    uniform sampler2D grl_colors;\n                `,\n            CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\n                    float grlColorMode = grl_colorMode_visibility_colorsWidth_useColors.x;\n                    float grlVisibility = grl_colorMode_visibility_colorsWidth_useColors.y;\n                    float grlColorsWidth = grl_colorMode_visibility_colorsWidth_useColors.z;\n                    float grlUseColors = grl_colorMode_visibility_colorsWidth_useColors.w;\n\n                    float grlUseDash = grl_dashOptions.x;\n                    float grlDashArray = grl_dashOptions.y;\n                    float grlDashOffset = grl_dashOptions.z;\n                    float grlDashRatio = grl_dashOptions.w;\n\n                    grlFinalColor.a *= step(grlCounters, grlVisibility);\n                    if(grlFinalColor.a == 0.) discard;\n\n                    if(grlUseDash == 1.){\n                        grlFinalColor.a *= ceil(mod(grlCounters + grlDashOffset, grlDashArray) - (grlDashArray * grlDashRatio));\n                        if (grlFinalColor.a == 0.) discard;\n                    }\n\n                    #ifdef GREASED_LINE_HAS_COLOR\n                        if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_SET}.) {\n                            grlFinalColor.rgb = grl_singleColor;\n                        } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_ADD}.) {\n                            grlFinalColor.rgb += grl_singleColor;\n                        } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY}.) {\n                            grlFinalColor.rgb *= grl_singleColor;\n                        }\n                    #else\n                        if (grlUseColors == 1.) {\n                            #ifdef GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE\n                                vec4 grlColor = texture2D(grl_colors, vec2(grlCounters, 0.), 0.);\n                            #else\n                                vec2 lookup = vec2(fract(grlColorPointer / grl_textureSize.x), 1.0 - floor(grlColorPointer / grl_textureSize.x) / max(grl_textureSize.y - 1.0, 1.0));\n                                vec4 grlColor = texture2D(grl_colors, lookup, 0.0);\n                            #endif\n                            if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_SET}.) {\n                                grlFinalColor = grlColor;\n                            } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_ADD}.) {\n                                grlFinalColor += grlColor;\n                            } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY}.) {\n                                grlFinalColor *= grlColor;\n                            }\n                        }\n                    #endif\n                `,\n        };\n    }\n\n    return null;\n}\n","import { type Nullable } from \"../../types\";\nimport { GreasedLineMeshColorMode } from \"./greasedLineMaterialInterfaces\";\n\n/**\n * Returns WGSL custom shader code\n * @param shaderType vertex or fragment\n * @param cameraFacing is in camera facing mode?\n * @returns WGSL custom shader code\n */\n/** @internal */\nexport function GetCustomCode(shaderType: string, cameraFacing: boolean): Nullable<{ [pointName: string]: string }> {\n    if (shaderType === \"vertex\") {\n        const obj: any = {\n            CUSTOM_VERTEX_DEFINITIONS: `\n                attribute grl_widths: f32;\n                attribute grl_colorPointers: f32;\n                varying grlCounters: f32;\n                varying grlColorPointer: f32;\n\n                #ifdef GREASED_LINE_USE_OFFSETS\n                    attribute grl_offsets: vec3f;   \n                #endif\n\n                #ifdef GREASED_LINE_CAMERA_FACING\n                    attribute grl_previousAndSide : vec4f;\n                    attribute grl_nextAndCounters : vec4f;\n\n                    fn grlFix(i: vec4f, aspect: f32) -> vec2f {\n                        var res = i.xy / i.w;\n                        res.x *= aspect;\n                        return res;\n                    }\n                #else\n                    attribute grl_slopes: f32;\n                    attribute grl_counters: f32;\n                #endif\n\n\n                `,\n            CUSTOM_VERTEX_UPDATE_POSITION: `\n                #ifdef GREASED_LINE_USE_OFFSETS\n                    var grlPositionOffset: vec3f = input.grl_offsets;\n                #else\n                    var grlPositionOffset = vec3f(0.);\n                #endif\n\n                #ifdef GREASED_LINE_CAMERA_FACING\n                    positionUpdated += grlPositionOffset;\n                #else\n                    positionUpdated = (positionUpdated + grlPositionOffset) + (input.grl_slopes * input.grl_widths);\n                #endif\n                `,\n            CUSTOM_VERTEX_MAIN_END: `\n                vertexOutputs.grlColorPointer = input.grl_colorPointers;\n\n                #ifdef GREASED_LINE_CAMERA_FACING\n\n                    let grlAspect: f32 = uniforms.grl_aspect_resolution_lineWidth.x;\n                    let grlBaseWidth: f32 = uniforms.grl_aspect_resolution_lineWidth.w;\n\n                    let grlPrevious: vec3f = input.grl_previousAndSide.xyz;\n                    let grlSide: f32 = input.grl_previousAndSide.w;\n\n                    let grlNext: vec3f = input.grl_nextAndCounters.xyz;\n                    vertexOutputs.grlCounters = input.grl_nextAndCounters.w;\n\n                    let grlWidth: f32 = grlBaseWidth * input.grl_widths;\n\n                    let worldDir: vec3f = normalize(grlNext - grlPrevious);\n                    let nearPosition: vec3f = positionUpdated + (worldDir * 0.01);\n                    let grlMatrix: mat4x4f = uniforms.viewProjection * finalWorld;\n                    let grlFinalPosition: vec4f = grlMatrix * vec4f(positionUpdated, 1.0); \n                    let screenNearPos: vec4f = grlMatrix * vec4(nearPosition, 1.0);\n                    let grlLinePosition: vec2f = grlFix(grlFinalPosition, grlAspect);\n                    let grlLineNearPosition: vec2f = grlFix(screenNearPos, grlAspect);\n                    let grlDir: vec2f = normalize(grlLineNearPosition - grlLinePosition);\n\n                    var grlNormal: vec4f = vec4f(-grlDir.y, grlDir.x, 0.0, 1.0);\n\n                    let grlHalfWidth: f32 = 0.5 * grlWidth;\n                    #if defined(GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM)\n                        grlNormal.x *= -grlHalfWidth;\n                        grlNormal.y *= -grlHalfWidth;\n                    #else\n                        grlNormal.x *= grlHalfWidth;\n                        grlNormal.y *= grlHalfWidth;\n                    #endif\n\n                    grlNormal *= uniforms.grl_projection;\n\n                    #if defined(GREASED_LINE_SIZE_ATTENUATION)\n                        grlNormal.x *= grlFinalPosition.w;\n                        grlNormal.y *= grlFinalPosition.w;\n\n                        let pr = vec4f(uniforms.grl_aspect_resolution_lineWidth.yz, 0.0, 1.0) * uniforms.grl_projection;\n                        grlNormal.x /= pr.x;\n                        grlNormal.y /= pr.y;\n                    #endif\n\n                    vertexOutputs.position = vec4f(grlFinalPosition.xy + grlNormal.xy * grlSide, grlFinalPosition.z, grlFinalPosition.w);\n                    vertexOutputs.vPositionW = vertexOutputs.position.xyz;\n                \n                #else\n                    vertexOutputs.grlCounters = input.grl_counters;\n                #endif\n                `,\n        };\n\n        if (cameraFacing) {\n            obj[\"!vertexOutputs\\\\.position\\\\s=\\\\sscene\\\\.viewProjection\\\\s\\\\*\\\\sworldPos;\"] = \"//\"; // not needed for camera facing GRL\n        }\n        return obj;\n    }\n\n    if (shaderType === \"fragment\") {\n        return {\n            CUSTOM_FRAGMENT_DEFINITIONS: `\n                    #ifdef PBR\n                         #define grlFinalColor finalColor\n                    #else\n                         #define grlFinalColor color\n                    #endif\n\n                    varying grlCounters: f32;\n                    varying grlColorPointer: 32;\n\n                    var grl_colors: texture_2d<f32>;\n                    var grl_colorsSampler: sampler;\n                `,\n            CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\n                    let grlColorMode: f32 = uniforms.grl_colorMode_visibility_colorsWidth_useColors.x;\n                    let grlVisibility: f32 = uniforms.grl_colorMode_visibility_colorsWidth_useColors.y;\n                    let grlColorsWidth: f32 = uniforms.grl_colorMode_visibility_colorsWidth_useColors.z;\n                    let grlUseColors: f32 = uniforms.grl_colorMode_visibility_colorsWidth_useColors.w;\n\n                    let grlUseDash: f32 = uniforms.grl_dashOptions.x;\n                    let grlDashArray: f32 = uniforms.grl_dashOptions.y;\n                    let grlDashOffset: f32 = uniforms.grl_dashOptions.z;\n                    let grlDashRatio: f32 = uniforms.grl_dashOptions.w;\n\n                    grlFinalColor.a *= step(fragmentInputs.grlCounters, grlVisibility);\n                    if (grlFinalColor.a == 0.0) {\n                        discard;\n                    }\n\n                    if (grlUseDash == 1.0) {\n                        let dashPosition = (fragmentInputs.grlCounters + grlDashOffset) % grlDashArray;\n                        grlFinalColor.a *= ceil(dashPosition - (grlDashArray * grlDashRatio));\n\n                        if (grlFinalColor.a == 0.0) {\n                            discard;\n                        }\n                    }\n\n                    #ifdef GREASED_LINE_HAS_COLOR\n                        if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_SET}.) {\n                            grlFinalColor = vec4f(uniforms.grl_singleColor, grlFinalColor.a);\n                        } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_ADD}.) {\n                            grlFinalColor += vec4f(uniforms.grl_singleColor, grlFinalColor.a);\n                        } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY}.) {\n                            grlFinalColor *= vec4f(uniforms.grl_singleColor, grlFinalColor.a);\n                        }\n                    #else\n                        if (grlUseColors == 1.) {\n                            #ifdef GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE\n                                let grlColor: vec4f = textureSample(grl_colors, grl_colorsSampler, vec2f(fragmentInputs.grlCounters, 0.));\n                            #else\n                                let lookup: vec2f = vec2(fract(fragmentInputs.grlColorPointer / uniforms.grl_textureSize.x), 1.0 - floor(fragmentInputs.grlColorPointer / uniforms.grl_textureSize.x) / max(uniforms.grl_textureSize.y - 1.0, 1.0));\n                                let grlColor: vec4f = textureSample(grl_colors, grl_colorsSampler, lookup);\n                            #endif\n                            if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_SET}.) {\n                                grlFinalColor = grlColor;\n                            } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_ADD}.) {\n                                grlFinalColor += grlColor;\n                            } else if (grlColorMode == ${GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY}.) {\n                                grlFinalColor *= grlColor;\n                            }\n                        }\n                    #endif\n\n\n                `,\n        };\n    }\n\n    return null;\n}\n","import { type Scene } from \"../../scene\";\r\nimport { RawTexture } from \"../Textures/rawTexture\";\r\nimport { ShaderMaterial } from \"../shaderMaterial.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { Vector2 } from \"../../Maths/math.vector.pure\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { TextureSampler } from \"../Textures/textureSampler\";\r\n\r\nimport { type GreasedLineMaterialOptions, type IGreasedLineMaterial, GreasedLineMeshColorDistributionType, GreasedLineMeshColorMode } from \"./greasedLineMaterialInterfaces\";\r\nimport { GreasedLineTools } from \"../../Misc/greasedLineTools\";\r\nimport { GreasedLineMaterialDefaults } from \"./greasedLineMaterialDefaults\";\r\n\r\nexport const GreasedLineUseOffsetsSimpleMaterialDefine = \"GREASED_LINE_USE_OFFSETS\";\r\n\r\n/**\r\n * GreasedLineSimpleMaterial\r\n */\r\nexport class GreasedLineSimpleMaterial extends ShaderMaterial implements IGreasedLineMaterial {\r\n    /**\r\n     * Force to use GLSL in WebGPU\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    private _visibility: number;\r\n    private _width: number;\r\n    private _useDash: boolean;\r\n    private _dashCount: number;\r\n    private _dashArray: number;\r\n    private _dashRatio: number;\r\n    private _dashOffset: number;\r\n    private _useColors: boolean;\r\n    private _color: Color3 = Color3.White();\r\n    private _colors: Nullable<Color3[]>;\r\n    private _colorsDistributionType: GreasedLineMeshColorDistributionType = GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_SEGMENT;\r\n    private _colorMode: GreasedLineMeshColorMode;\r\n    private _colorsSampling: number;\r\n    private _resolution: Vector2;\r\n    private _sizeAttenuation: boolean;\r\n    private _colorsTexture: Nullable<RawTexture> = null;\r\n    private _cameraFacing: boolean;\r\n\r\n    /**\r\n     * GreasedLineSimple material constructor\r\n     * @param name material name\r\n     * @param scene the scene\r\n     * @param options material options\r\n     */\r\n    constructor(name: string, scene: Scene, options: GreasedLineMaterialOptions) {\r\n        const engine = scene.getEngine();\r\n        const isWGSL = engine.isWebGPU && !(options.forceGLSL || GreasedLineSimpleMaterial.ForceGLSL);\r\n\r\n        const defines = [\r\n            `COLOR_DISTRIBUTION_TYPE_LINE ${GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_LINE}.`,\r\n            `COLOR_DISTRIBUTION_TYPE_SEGMENT ${GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_SEGMENT}.`,\r\n            `COLOR_MODE_SET ${GreasedLineMeshColorMode.COLOR_MODE_SET}.`,\r\n            `COLOR_MODE_ADD ${GreasedLineMeshColorMode.COLOR_MODE_ADD}.`,\r\n            `COLOR_MODE_MULTIPLY ${GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY}.`,\r\n        ];\r\n        if (scene.useRightHandedSystem) {\r\n            defines.push(\"GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM\");\r\n        }\r\n\r\n        const attributes = [\"position\", \"grl_widths\", \"grl_offsets\", \"grl_colorPointers\"];\r\n\r\n        if (options.cameraFacing) {\r\n            defines.push(\"GREASED_LINE_CAMERA_FACING\");\r\n            attributes.push(\"grl_previousAndSide\", \"grl_nextAndCounters\");\r\n        } else {\r\n            attributes.push(\"grl_slopes\");\r\n            attributes.push(\"grl_counters\");\r\n        }\r\n\r\n        const uniforms = [\r\n            \"grlColorsWidth\",\r\n            \"grlUseColors\",\r\n            \"grlWidth\",\r\n            \"grlColor\",\r\n            \"grl_colorModeAndColorDistributionType\",\r\n            \"grlResolution\",\r\n            \"grlAspect\",\r\n            \"grlAizeAttenuation\",\r\n            \"grlDashArray\",\r\n            \"grlDashOffset\",\r\n            \"grlDashRatio\",\r\n            \"grlUseDash\",\r\n            \"grlVisibility\",\r\n            \"grlColors\",\r\n        ];\r\n\r\n        if (!isWGSL) {\r\n            uniforms.push(\"world\", \"viewProjection\", \"view\", \"projection\");\r\n        }\r\n\r\n        super(\r\n            name,\r\n            scene,\r\n            {\r\n                vertex: \"greasedLine\",\r\n                fragment: \"greasedLine\",\r\n            },\r\n            {\r\n                uniformBuffers: isWGSL ? [\"Scene\", \"Mesh\"] : undefined,\r\n                attributes,\r\n                uniforms,\r\n                samplers: isWGSL ? [] : [\"grlColors\"],\r\n                defines,\r\n                extraInitializationsAsync: async () => {\r\n                    if (isWGSL) {\r\n                        await Promise.all([import(\"../../ShadersWGSL/greasedLine.vertex\"), import(\"../../ShadersWGSL/greasedLine.fragment\")]);\r\n                    } else {\r\n                        await Promise.all([import(\"../../Shaders/greasedLine.vertex\"), import(\"../../Shaders/greasedLine.fragment\")]);\r\n                    }\r\n                },\r\n                shaderLanguage: isWGSL ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            }\r\n        );\r\n\r\n        options = options || {\r\n            color: GreasedLineMaterialDefaults.DEFAULT_COLOR,\r\n        };\r\n\r\n        this.visibility = options.visibility ?? 1;\r\n        this.useDash = options.useDash ?? false;\r\n        this.dashRatio = options.dashRatio ?? 0.5;\r\n        this.dashOffset = options.dashOffset ?? 0;\r\n        this.dashCount = options.dashCount ?? 1; // calculate the _dashArray value, call the setter\r\n        this.width = options.width\r\n            ? options.width\r\n            : options.sizeAttenuation && options.cameraFacing\r\n              ? GreasedLineMaterialDefaults.DEFAULT_WIDTH_ATTENUATED\r\n              : GreasedLineMaterialDefaults.DEFAULT_WIDTH;\r\n        this.sizeAttenuation = options.sizeAttenuation ?? false;\r\n        this.color = options.color ?? Color3.White();\r\n        this.useColors = options.useColors ?? false;\r\n        this.colorsDistributionType = options.colorDistributionType ?? GreasedLineMeshColorDistributionType.COLOR_DISTRIBUTION_TYPE_SEGMENT;\r\n        this.colorsSampling = options.colorsSampling ?? RawTexture.NEAREST_NEAREST;\r\n        this.colorMode = options.colorMode ?? GreasedLineMeshColorMode.COLOR_MODE_SET;\r\n        this._colors = options.colors ?? null;\r\n        this._cameraFacing = options.cameraFacing ?? true;\r\n        this.resolution = options.resolution ?? new Vector2(engine.getRenderWidth(), engine.getRenderHeight()); // calculate aspect call the setter\r\n\r\n        if (options.colorsTexture) {\r\n            this.colorsTexture = options.colorsTexture;\r\n        } else {\r\n            if (this._colors) {\r\n                this.colorsTexture = GreasedLineTools.CreateColorsTexture(`${this.name}-colors-texture`, this._colors, this.colorsSampling, scene);\r\n            } else {\r\n                this._color = this._color ?? GreasedLineMaterialDefaults.DEFAULT_COLOR;\r\n                this.colorsTexture = GreasedLineTools.PrepareEmptyColorsTexture(scene);\r\n            }\r\n        }\r\n\r\n        if (isWGSL) {\r\n            const sampler = new TextureSampler();\r\n            sampler.setParameters(); // use the default values\r\n            sampler.samplingMode = this.colorsSampling;\r\n            this.setTextureSampler(\"grlColorsSampler\", sampler);\r\n        }\r\n\r\n        engine.onDisposeObservable.add(() => {\r\n            GreasedLineTools.DisposeEmptyColorsTexture();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Disposes the plugin material.\r\n     */\r\n    public override dispose(): void {\r\n        if (this._colorsTexture && this._colorsTexture !== GreasedLineMaterialDefaults.EmptyColorsTexture) {\r\n            this._colorsTexture.dispose();\r\n        }\r\n        super.dispose();\r\n    }\r\n\r\n    private _setColorModeAndColorDistributionType() {\r\n        this.setVector2(\"grl_colorModeAndColorDistributionType\", new Vector2(this._colorMode, this._colorsDistributionType));\r\n    }\r\n\r\n    /**\r\n     * Updates the material. Use when material created in lazy mode.\r\n     */\r\n    public updateLazy() {\r\n        if (this._colors) {\r\n            this.setColors(this._colors, false, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the colors used to colorize the line\r\n     */\r\n    get colors() {\r\n        return this._colors;\r\n    }\r\n\r\n    /**\r\n     * Sets the colors used to colorize the line\r\n     */\r\n    set colors(value: Nullable<Color3[]>) {\r\n        this.setColors(value);\r\n    }\r\n\r\n    /**\r\n     * Creates or updates the colors texture\r\n     * @param colors color table RGBA\r\n     * @param lazy if lazy, the colors are not updated\r\n     * @param forceNewTexture force creation of a new texture\r\n     */\r\n    public setColors(colors: Nullable<Color3[]>, lazy = false, forceNewTexture = false): void {\r\n        const origColorsCount = this._colors?.length ?? 0;\r\n\r\n        this._colors = colors;\r\n\r\n        if (colors === null || colors.length === 0) {\r\n            if (this._colorsTexture && this._colorsTexture !== GreasedLineMaterialDefaults.EmptyColorsTexture) {\r\n                this._colorsTexture.dispose();\r\n            }\r\n            const scene = this.getScene();\r\n            if (scene) {\r\n                this.colorsTexture = GreasedLineTools.PrepareEmptyColorsTexture(scene);\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (lazy && !forceNewTexture) {\r\n            return;\r\n        }\r\n\r\n        if (this._colorsTexture && origColorsCount === colors.length && !forceNewTexture) {\r\n            const colorArray = GreasedLineTools.Color3toRGBAUint8(colors);\r\n            this._colorsTexture.update(colorArray);\r\n        } else {\r\n            if (this._colorsTexture && this._colorsTexture !== GreasedLineMaterialDefaults.EmptyColorsTexture) {\r\n                this._colorsTexture.dispose();\r\n            }\r\n            this.colorsTexture = GreasedLineTools.CreateColorsTexture(`${this.name}-colors-texture`, colors, this.colorsSampling, this.getScene());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the colors texture\r\n     */\r\n    get colorsTexture() {\r\n        return (this._colorsTexture as RawTexture) ?? null;\r\n    }\r\n\r\n    /**\r\n     * Sets the colorsTexture\r\n     */\r\n    set colorsTexture(value: RawTexture) {\r\n        this._colorsTexture = value;\r\n        this.setFloat(\"grlColorsWidth\", this._colorsTexture.getSize().width);\r\n        this.setTexture(\"grlColors\", this._colorsTexture);\r\n    }\r\n\r\n    /**\r\n     * Line base width. At each point the line width is calculated by widths[pointIndex] * width\r\n     */\r\n    get width() {\r\n        return this._width;\r\n    }\r\n\r\n    /**\r\n     * Line base width. At each point the line width is calculated by widths[pointIndex] * width\r\n     */\r\n    set width(value: number) {\r\n        this._width = value;\r\n        this.setFloat(\"grlWidth\", value);\r\n    }\r\n\r\n    /**\r\n     * Whether to use the colors option to colorize the line\r\n     */\r\n    get useColors() {\r\n        return this._useColors;\r\n    }\r\n\r\n    set useColors(value: boolean) {\r\n        this._useColors = value;\r\n        this.setFloat(\"grlUseColors\", GreasedLineTools.BooleanToNumber(value));\r\n    }\r\n\r\n    /**\r\n     * The type of sampling of the colors texture. The values are the same when using with textures.\r\n     */\r\n    get colorsSampling() {\r\n        return this._colorsSampling;\r\n    }\r\n\r\n    /**\r\n     * The type of sampling of the colors texture. The values are the same when using with textures.\r\n     */\r\n    set colorsSampling(value: number) {\r\n        this._colorsSampling = value;\r\n    }\r\n\r\n    /**\r\n     * Normalized value of how much of the line will be visible\r\n     * 0 - 0% of the line will be visible\r\n     * 1 - 100% of the line will be visible\r\n     */\r\n    get visibility() {\r\n        return this._visibility;\r\n    }\r\n\r\n    set visibility(value: number) {\r\n        this._visibility = value;\r\n        this.setFloat(\"grlVisibility\", value);\r\n    }\r\n\r\n    /**\r\n     * Turns on/off dash mode\r\n     */\r\n    get useDash() {\r\n        return this._useDash;\r\n    }\r\n\r\n    /**\r\n     * Turns on/off dash mode\r\n     */\r\n    set useDash(value: boolean) {\r\n        this._useDash = value;\r\n        this.setFloat(\"grlUseDash\", GreasedLineTools.BooleanToNumber(value));\r\n    }\r\n\r\n    /**\r\n     * Gets the dash offset\r\n     */\r\n    get dashOffset() {\r\n        return this._dashOffset;\r\n    }\r\n\r\n    /**\r\n     * Sets the dash offset\r\n     */\r\n    set dashOffset(value: number) {\r\n        this._dashOffset = value;\r\n        this.setFloat(\"grlDashOffset\", value);\r\n    }\r\n\r\n    /**\r\n     * Length of the dash. 0 to 1. 0.5 means half empty, half drawn.\r\n     */\r\n    get dashRatio() {\r\n        return this._dashRatio;\r\n    }\r\n\r\n    /**\r\n     * Length of the dash. 0 to 1. 0.5 means half empty, half drawn.\r\n     */\r\n    set dashRatio(value: number) {\r\n        this._dashRatio = value;\r\n        this.setFloat(\"grlDashRatio\", value);\r\n    }\r\n\r\n    /**\r\n     * Gets the number of dashes in the line\r\n     */\r\n    get dashCount() {\r\n        return this._dashCount;\r\n    }\r\n    /**\r\n     * Sets the number of dashes in the line\r\n     * @param value dash\r\n     */\r\n    set dashCount(value: number) {\r\n        this._dashCount = value;\r\n        this._dashArray = 1 / value;\r\n        this.setFloat(\"grlDashArray\", this._dashArray);\r\n    }\r\n\r\n    /**\r\n     * False means 1 unit in width = 1 unit on scene, true means 1 unit in width is reduced on the screen to make better looking lines\r\n     */\r\n    get sizeAttenuation() {\r\n        return this._sizeAttenuation;\r\n    }\r\n\r\n    /**\r\n     * Turn on/off attenuation of the width option and widths array.\r\n     * @param value false means 1 unit in width = 1 unit on scene, true means 1 unit in width is reduced on the screen to make better looking lines\r\n     */\r\n    set sizeAttenuation(value: boolean) {\r\n        this._sizeAttenuation = value;\r\n        this.setFloat(\"grlSizeAttenuation\", GreasedLineTools.BooleanToNumber(value));\r\n    }\r\n\r\n    /**\r\n     * Gets the color of the line\r\n     */\r\n    get color() {\r\n        return this._color;\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the line\r\n     * @param value Color3\r\n     */\r\n    set color(value: Color3) {\r\n        this.setColor(value);\r\n    }\r\n\r\n    /**\r\n     * Sets the color of the line. If set the whole line will be mixed with this color according to the colorMode option.\r\n     * The simple material always needs a color to be set. If you set it to null it will set the color to the default color (GreasedLineSimpleMaterial.DEFAULT_COLOR).\r\n     * @param value color\r\n     */\r\n    public setColor(value: Nullable<Color3>) {\r\n        value = value ?? GreasedLineMaterialDefaults.DEFAULT_COLOR;\r\n        this._color = value;\r\n        this.setColor3(\"grlColor\", value);\r\n    }\r\n\r\n    /**\r\n     * Gets the color distributiopn type\r\n     */\r\n    get colorsDistributionType() {\r\n        return this._colorsDistributionType;\r\n    }\r\n\r\n    /**\r\n     * Sets the color distribution type\r\n     * @see GreasedLineMeshColorDistributionType\r\n     * @param value color distribution type\r\n     */\r\n    set colorsDistributionType(value: GreasedLineMeshColorDistributionType) {\r\n        this._colorsDistributionType = value;\r\n        this._setColorModeAndColorDistributionType();\r\n    }\r\n\r\n    /**\r\n     * Gets the mixing mode of the color and colors paramaters. Default value is GreasedLineMeshColorMode.SET.\r\n     * MATERIAL_TYPE_SIMPLE mixes the color and colors of the greased line material.\r\n     * @see GreasedLineMeshColorMode\r\n     */\r\n    get colorMode() {\r\n        return this._colorMode;\r\n    }\r\n\r\n    /**\r\n     * Sets the mixing mode of the color and colors paramaters. Default value is GreasedLineMeshColorMode.SET.\r\n     * MATERIAL_TYPE_SIMPLE mixes the color and colors of the greased line material.\r\n     * @see GreasedLineMeshColorMode\r\n     */\r\n    set colorMode(value: GreasedLineMeshColorMode) {\r\n        this._colorMode = value;\r\n        this._setColorModeAndColorDistributionType();\r\n    }\r\n\r\n    /**\r\n     * Gets the resolution\r\n     */\r\n    get resolution() {\r\n        return this._resolution;\r\n    }\r\n\r\n    /**\r\n     * Sets the resolution\r\n     * @param value resolution of the screen for GreasedLine\r\n     */\r\n    set resolution(value: Vector2) {\r\n        this._resolution = value;\r\n        this.setVector2(\"grlResolution\", value);\r\n        this.setFloat(\"grlAspect\", value.x / value.y);\r\n    }\r\n\r\n    /**\r\n     * Serializes this plugin material\r\n     * @returns serializationObjec\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        const greasedLineMaterialOptions: GreasedLineMaterialOptions = {\r\n            colorDistributionType: this._colorsDistributionType,\r\n            colorsSampling: this._colorsSampling,\r\n            colorMode: this._colorMode,\r\n            color: this._color,\r\n            dashCount: this._dashCount,\r\n            dashOffset: this._dashOffset,\r\n            dashRatio: this._dashRatio,\r\n            resolution: this._resolution,\r\n            sizeAttenuation: this._sizeAttenuation,\r\n            useColors: this._useColors,\r\n            useDash: this._useDash,\r\n            visibility: this._visibility,\r\n            width: this._width,\r\n            cameraFacing: this._cameraFacing,\r\n        };\r\n\r\n        if (this._colors) {\r\n            greasedLineMaterialOptions.colors = this._colors;\r\n        }\r\n\r\n        serializationObject.greasedLineMaterialOptions = greasedLineMaterialOptions;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized objects\r\n     * @param source serialized object\r\n     * @param scene scene\r\n     * @param _rootUrl root url for textures\r\n     */\r\n    public parse(source: any, scene: Scene, _rootUrl: string): void {\r\n        const greasedLineMaterialOptions = <GreasedLineMaterialOptions>source.greasedLineMaterialOptions;\r\n\r\n        this._colorsTexture?.dispose();\r\n\r\n        if (greasedLineMaterialOptions.color) {\r\n            this.color = greasedLineMaterialOptions.color;\r\n        }\r\n        if (greasedLineMaterialOptions.colorDistributionType) {\r\n            this.colorsDistributionType = greasedLineMaterialOptions.colorDistributionType;\r\n        }\r\n        if (greasedLineMaterialOptions.colorsSampling) {\r\n            this.colorsSampling = greasedLineMaterialOptions.colorsSampling;\r\n        }\r\n        if (greasedLineMaterialOptions.colorMode) {\r\n            this.colorMode = greasedLineMaterialOptions.colorMode;\r\n        }\r\n        if (greasedLineMaterialOptions.useColors) {\r\n            this.useColors = greasedLineMaterialOptions.useColors;\r\n        }\r\n        if (greasedLineMaterialOptions.visibility) {\r\n            this.visibility = greasedLineMaterialOptions.visibility;\r\n        }\r\n        if (greasedLineMaterialOptions.useDash) {\r\n            this.useDash = greasedLineMaterialOptions.useDash;\r\n        }\r\n        if (greasedLineMaterialOptions.dashCount) {\r\n            this.dashCount = greasedLineMaterialOptions.dashCount;\r\n        }\r\n        if (greasedLineMaterialOptions.dashRatio) {\r\n            this.dashRatio = greasedLineMaterialOptions.dashRatio;\r\n        }\r\n        if (greasedLineMaterialOptions.dashOffset) {\r\n            this.dashOffset = greasedLineMaterialOptions.dashOffset;\r\n        }\r\n        if (greasedLineMaterialOptions.width) {\r\n            this.width = greasedLineMaterialOptions.width;\r\n        }\r\n        if (greasedLineMaterialOptions.sizeAttenuation) {\r\n            this.sizeAttenuation = greasedLineMaterialOptions.sizeAttenuation;\r\n        }\r\n        if (greasedLineMaterialOptions.resolution) {\r\n            this.resolution = greasedLineMaterialOptions.resolution;\r\n        }\r\n        if (greasedLineMaterialOptions.colors) {\r\n            this.colorsTexture = GreasedLineTools.CreateColorsTexture(`${this.name}-colors-texture`, greasedLineMaterialOptions.colors, this.colorsSampling, this.getScene());\r\n        } else {\r\n            this.colorsTexture = GreasedLineTools.PrepareEmptyColorsTexture(scene);\r\n        }\r\n\r\n        this._cameraFacing = greasedLineMaterialOptions.cameraFacing ?? true;\r\n        this.setDefine(\"GREASED_LINE_CAMERA_FACING\", this._cameraFacing);\r\n    }\r\n}\r\n","import { type RawTexture } from \"../Textures/rawTexture\";\r\nimport { type Vector2 } from \"../../Maths/math.vector\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Color3 } from \"../../Maths/math.color\";\r\n/**\r\n * Interface which defines the available methods for a GreasedLineMaterial\r\n */\r\nexport interface IGreasedLineMaterial {\r\n    /**\r\n     * Normalized value of how much of the line will be visible\r\n     * 0 - 0% of the line will be visible\r\n     * 1 - 100% of the line will be visible\r\n     */\r\n    visibility: number;\r\n\r\n    /**\r\n     * Line base width. At each point the line width is calculated by widths[pointIndex] * width\r\n     */\r\n    width: number;\r\n\r\n    /**\r\n     * Turns on/off dash mode\r\n     */\r\n    useDash: boolean;\r\n\r\n    /**\r\n     * @see GreasedLinePluginMaterial.setDashCount\r\n     * Number of dashes in the line.\r\n     * Defaults to 1.\r\n     */\r\n    dashCount: number;\r\n\r\n    /**\r\n     * Dash offset\r\n     */\r\n    dashOffset: number;\r\n\r\n    /**\r\n     * Length of the dash. 0 to 1. 0.5 means half empty, half drawn.\r\n     */\r\n    dashRatio: number;\r\n\r\n    /**\r\n     * Whether to use the colors option to colorize the line\r\n     */\r\n    useColors: boolean;\r\n\r\n    /**\r\n     * The mixing mode of the color paramater. Default value is GreasedLineMeshColorMode.SET.\r\n     * MATERIAL_TYPE_SIMPLE mixes the color and colors of the greased line material.\r\n     * MATERIAL_TYPE_STANDARD and MATERIAL_TYPE_PBR mixes the color from the base material with the color and/or colors of the greased line material.\r\n     * @see GreasedLineMeshColorMode\r\n     */\r\n    colorMode: GreasedLineMeshColorMode;\r\n\r\n    /**\r\n     * Colors of the line segments.\r\n     * Defaults to empty.\r\n     */\r\n    colors: Nullable<Color3[]>;\r\n\r\n    /**\r\n     * If false then width units = scene units. If true then line will width be reduced.\r\n     * Defaults to false.\r\n     */\r\n    sizeAttenuation: boolean;\r\n\r\n    /**\r\n     * Color of the line. Applies to all line segments.\r\n     * Defaults to White.\r\n     */\r\n    color: Nullable<Color3>;\r\n\r\n    /**\r\n     * The method used to distribute the colors along the line.\r\n     * You can use segment distribution when each segment will use on color from the color table.\r\n     * Or you can use line distribution when the colors are distributed evenly along the line ignoring the segments.\r\n     */\r\n    colorsDistributionType: GreasedLineMeshColorDistributionType;\r\n\r\n    /**\r\n     * Defaults to engine.getRenderWidth() and engine.getRenderHeight()\r\n     * Rendering resolution\r\n     */\r\n    resolution: Vector2;\r\n\r\n    /**\r\n     * You can provide a colorsTexture to use instead of one generated from the 'colors' option\r\n     */\r\n    colorsTexture: Nullable<RawTexture>;\r\n\r\n    /**\r\n     * Allows to change the color without marking the material dirty.\r\n     * MATERIAL_TYPE_STANDARD and MATERIAL_TYPE_PBR material's shaders will get recompiled if there was no color set and you set a color or when there was a color set and you set it to null.\r\n     * @param value the color\r\n     * @param doNotMarkDirty the flag\r\n     */\r\n    setColor(value: Nullable<Color3>, doNotMarkDirty?: boolean): void;\r\n\r\n    /**\r\n     * Set the colors\r\n     * @param colors colors array\r\n     * @param lazy if true the colors texture will not be updated\r\n     * @param forceNewTexture forces to create a new colors texture\r\n     */\r\n    setColors(colors: Nullable<Color3[]>, lazy: boolean, forceNewTexture?: boolean): void;\r\n\r\n    /**\r\n     * Creates and sets the colors texture from the colors array which was created in lazy mode\r\n     */\r\n    updateLazy(): void;\r\n}\r\n\r\n/**\r\n * Material types for GreasedLine\r\n * {@link https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/greased_line#materialtype}\r\n */\r\nexport const enum GreasedLineMeshMaterialType {\r\n    /**\r\n     * StandardMaterial\r\n     */\r\n    MATERIAL_TYPE_STANDARD = 0,\r\n    /**\r\n     * PBR Material\r\n     */\r\n    MATERIAL_TYPE_PBR = 1,\r\n    /**\r\n     * Simple and fast shader material without texture, light, fog, instances, ... support.\r\n     * Just raw colored lines.\r\n     * Dashing and visibility is supported.\r\n     */\r\n    MATERIAL_TYPE_SIMPLE = 2,\r\n}\r\n\r\n/**\r\n * Color blending mode of the @see GreasedLineMaterial and the base material\r\n * {@link https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/greased_line#colormode}\r\n */\r\nexport const enum GreasedLineMeshColorMode {\r\n    /**\r\n     * Color blending mode SET\r\n     */\r\n    COLOR_MODE_SET = 0,\r\n    /**\r\n     * Color blending mode ADD\r\n     */\r\n    COLOR_MODE_ADD = 1,\r\n    /**\r\n     * Color blending mode ADD\r\n     */\r\n    COLOR_MODE_MULTIPLY = 2,\r\n}\r\n\r\n/**\r\n * Color distribution type of the @see colors.\r\n * {@link https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/greased_line#colordistributiontype}\r\n *\r\n */\r\nexport const enum GreasedLineMeshColorDistributionType {\r\n    /**\r\n     * Colors distributed between segments of the line\r\n     */\r\n    COLOR_DISTRIBUTION_TYPE_SEGMENT = 0,\r\n    /**\r\n     * Colors distributed along the line ingoring the segments\r\n     */\r\n    COLOR_DISTRIBUTION_TYPE_LINE = 1,\r\n}\r\n\r\n/**\r\n * Options for GreasedLineMaterial\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GreasedLineMaterialOptions {\r\n    /**\r\n     * Force the greased lines to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    forceGLSL?: boolean;\r\n    /**\r\n     * Line width. If sizeAttenuation os false scene units will be used for width.\r\n     * Defaults to 0.1 if @see sizeAttenuation is false, or to 1 if it's true.\r\n     */\r\n    width?: number;\r\n    /**\r\n     * If false then width units = scene units. If true then line will width be reduced.\r\n     * Defaults to false.\r\n     */\r\n    sizeAttenuation?: boolean;\r\n    /**\r\n     * Type of the material to use to render the line.\r\n     * Defaults to StandardMaterial.\r\n     */\r\n    materialType?: GreasedLineMeshMaterialType;\r\n    /**\r\n     * Color of the line. Applies to all line segments.\r\n     * Defaults to White.\r\n     */\r\n    color?: Color3;\r\n    /**\r\n     * Color mode of the line. Applies to all line segments.\r\n     * The pixel color from the material shader will be modified with the value of @see color using the colorMode.\r\n     * Defaults to @see GreasedLineMeshColorMode.SET\r\n     */\r\n    colorMode?: GreasedLineMeshColorMode;\r\n    /**\r\n     * Colors of the line segments.\r\n     * Defaults to empty.\r\n     */\r\n    colors?: Color3[];\r\n    /**\r\n     * If true, @see colors are used, otherwise they're ignored.\r\n     * Defaults to false.\r\n     */\r\n    useColors?: boolean;\r\n    /**\r\n     * Sampling type of the colors texture\r\n     * Defaults to NEAREST_NEAREST.\r\n     */\r\n    colorsSampling?: number;\r\n    /**\r\n     * The method used to distribute the colors along the line.\r\n     * You can use segment distribution when each segment will use on color from the color table.\r\n     * Or you can use line distribution when the colors are distributed evenly along the line ignoring the segments.\r\n     */\r\n    colorDistributionType?: GreasedLineMeshColorDistributionType;\r\n    /**\r\n     * If true, dashing is used.\r\n     * Defaults to false.\r\n     */\r\n    useDash?: boolean;\r\n    /**\r\n     * @see GreasedLinePluginMaterial.setDashCount\r\n     * Number of dashes in the line.\r\n     * Defaults to 1.\r\n     */\r\n    dashCount?: number;\r\n    /**\r\n     * Offset of the dashes along the line. 0 to 1.\r\n     * Defaults to 0.\r\n     * @see GreasedLinePluginMaterial.setDashOffset\r\n     */\r\n    dashOffset?: number;\r\n    /**\r\n     * Length of the dash. 0 to 1. 0.5 means half empty, half drawn.\r\n     * Defaults to 0.5.\r\n     * @see GreasedLinePluginMaterial.setDashRatio\r\n     */\r\n    dashRatio?: number;\r\n    /**\r\n     * Sets the line length visibility.\r\n     * 0 - 0% of the line will be visible.\r\n     * 1 - 100% of the line will be visible.\r\n     * @see GreasedLinePluginMaterial.setVisibility\r\n     */\r\n    visibility?: number;\r\n    /**\r\n     * Defaults to engine.getRenderWidth() and engine.getRenderHeight()\r\n     * Rendering resolution\r\n     */\r\n    resolution?: Vector2;\r\n    /**\r\n     * Whether to use camera facing for the line.\r\n     * Defaults to true.\r\n     */\r\n    cameraFacing?: boolean;\r\n    /**\r\n     * You can provide a colorsTexture to use instead of one generated from the 'colors' option\r\n     */\r\n    colorsTexture?: RawTexture;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { MaterialPluginBase } from \"./materialPluginBase.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\nimport { type FloatArray, type Nullable } from \"../types\";\r\nimport { MaterialDefines } from \"./materialDefines\";\r\nimport { type PBRBaseMaterial } from \"./PBR/pbrBaseMaterial.pure\";\r\nimport { type StandardMaterial } from \"./standardMaterial.pure\";\r\nimport { Color3 } from \"core/Maths/math\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { expandToProperty, serialize, serializeAsColor3 } from \"core/Misc/decorators\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { ShaderLanguage } from \"./shaderLanguage\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nconst vertexDefinitions = `#if defined(DBG_ENABLED)\r\nattribute float dbg_initialPass;\r\nvarying vec3 dbg_vBarycentric;\r\nflat varying vec3 dbg_vVertexWorldPos;\r\nflat varying float dbg_vPass;\r\n#endif`;\r\n\r\nconst vertexDefinitionsWebGPU = `#if defined(DBG_ENABLED)\r\nattribute dbg_initialPass: f32;\r\nvarying dbg_vBarycentric: vec3f;\r\nflat varying dbg_vVertexWorldPos: vec3f;\r\nflat varying dbg_vPass: f32;\r\n#endif`;\r\n\r\nconst vertexMainEnd = `#if defined(DBG_ENABLED)\r\nfloat dbg_vertexIndex = mod(float(gl_VertexID), 3.);\r\nif (dbg_vertexIndex == 0.0) { \r\n    dbg_vBarycentric = vec3(1.,0.,0.); \r\n}\r\nelse if (dbg_vertexIndex == 1.0) { \r\n    dbg_vBarycentric = vec3(0.,1.,0.); \r\n}\r\nelse { \r\n    dbg_vBarycentric = vec3(0.,0.,1.); \r\n}\r\n\r\ndbg_vVertexWorldPos = vPositionW;\r\ndbg_vPass = dbg_initialPass;\r\n#endif`;\r\n\r\nconst vertexMainEndWebGPU = `#if defined(DBG_ENABLED)\r\nvar dbg_vertexIndex = f32(input.vertexIndex) % 3.;\r\nif (dbg_vertexIndex == 0.0) { \r\n    vertexOutputs.dbg_vBarycentric = vec3f(1.,0.,0.); \r\n}\r\nelse if (dbg_vertexIndex == 1.0) { \r\n    vertexOutputs.dbg_vBarycentric = vec3f(0.,1.,0.); \r\n}\r\nelse { \r\n    vertexOutputs.dbg_vBarycentric = vec3f(0.,0.,1.); \r\n}\r\n\r\nvertexOutputs.dbg_vVertexWorldPos = vertexOutputs.vPositionW;\r\nvertexOutputs.dbg_vPass = input.dbg_initialPass;\r\n#endif`;\r\n\r\nconst fragmentUniforms = `#if defined(DBG_ENABLED)\r\nuniform vec3 dbg_shadedDiffuseColor;\r\nuniform vec4 dbg_shadedSpecularColorPower;\r\nuniform vec3 dbg_thicknessRadiusScale;\r\n\r\n#if DBG_MODE == 2 || DBG_MODE == 3\r\n    uniform vec3 dbg_vertexColor;\r\n#endif\r\n\r\n#if DBG_MODE == 1\r\n    uniform vec3 dbg_wireframeTrianglesColor;\r\n#elif DBG_MODE == 3\r\n    uniform vec3 dbg_wireframeVerticesColor;\r\n#elif DBG_MODE == 4 || DBG_MODE == 5\r\n    uniform vec3 dbg_uvPrimaryColor;\r\n    uniform vec3 dbg_uvSecondaryColor;\r\n#elif DBG_MODE == 7\r\n    uniform vec3 dbg_materialColor;\r\n#endif\r\n#endif`;\r\n\r\nconst fragmentUniformsWebGPU = `#if defined(DBG_ENABLED)\r\nuniform dbg_shadedDiffuseColor: vec3f;\r\nuniform dbg_shadedSpecularColorPower: vec4f;\r\nuniform dbg_thicknessRadiusScale: vec3f;\r\n\r\n#if DBG_MODE == 2 || DBG_MODE == 3\r\n    uniform dbg_vertexColor: vec3f;\r\n#endif\r\n\r\n#if DBG_MODE == 1\r\n    uniform dbg_wireframeTrianglesColor: vec3f;\r\n#elif DBG_MODE == 3\r\n    uniform  dbg_wireframeVerticesColor: vec3f;\r\n#elif DBG_MODE == 4 || DBG_MODE == 5\r\n    uniform dbg_uvPrimaryColor: vec3f;\r\n    uniform dbg_uvSecondaryColor: vec3f;\r\n#elif DBG_MODE == 7\r\n    uniform dbg_materialColor: vec3f;\r\n#endif\r\n#endif`;\r\n\r\nconst fragmentDefinitions = `#if defined(DBG_ENABLED)\r\nvarying vec3 dbg_vBarycentric;\r\nflat varying vec3 dbg_vVertexWorldPos;\r\nflat varying float dbg_vPass;\r\n\r\n#if !defined(DBG_MULTIPLY)\r\n    vec3 dbg_applyShading(vec3 color) {\r\n        vec3 N = vNormalW.xyz;\r\n        vec3 L = normalize(vEyePosition.xyz - vPositionW.xyz);\r\n        vec3 H = normalize(L + L);\r\n        float LdotN = clamp(dot(L,N), 0., 1.);\r\n        float HdotN = clamp(dot(H,N), 0., 1.);\r\n        float specTerm = pow(HdotN, dbg_shadedSpecularColorPower.w);\r\n        color *= (LdotN / PI);\r\n        color += dbg_shadedSpecularColorPower.rgb * (specTerm / PI);\r\n        return color;\r\n    }\r\n#endif\r\n\r\n#if DBG_MODE == 1 || DBG_MODE == 3\r\n    float dbg_edgeFactor() {\r\n        vec3 d = fwidth(dbg_vBarycentric);\r\n        vec3 a3 = smoothstep(vec3(0.), d * dbg_thicknessRadiusScale.x, dbg_vBarycentric);\r\n        return min(min(a3.x, a3.y), a3.z);\r\n    }\r\n#endif\r\n\r\n#if DBG_MODE == 2 || DBG_MODE == 3\r\n    float dbg_cornerFactor() {\r\n        vec3 worldPos = vPositionW;\r\n        float dist = length(worldPos - dbg_vVertexWorldPos);\r\n        float camDist = length(worldPos - vEyePosition.xyz);\r\n        float d = sqrt(camDist) * .001;\r\n        return smoothstep((dbg_thicknessRadiusScale.y * d), ((dbg_thicknessRadiusScale.y * 1.01) * d), dist);\r\n    }\r\n#endif\r\n\r\n#if (DBG_MODE == 4 && defined(UV1)) || (DBG_MODE == 5 && defined(UV2))\r\n    float dbg_checkerboardFactor(vec2 uv) {\r\n        vec2 f = fract(uv * dbg_thicknessRadiusScale.z);\r\n        f -= .5;\r\n        return (f.x * f.y) > 0. ? 1. : 0.;\r\n    }\r\n#endif\r\n#endif`;\r\n\r\nconst fragmentDefinitionsWebGPU = `#if defined(DBG_ENABLED)\r\nvarying dbg_vBarycentric: vec3f;\r\nflat varying dbg_vVertexWorldPos: vec3f;\r\nflat varying dbg_vPass: f32;\r\n\r\n#if !defined(DBG_MULTIPLY)\r\n    fn dbg_applyShading(color: vec3f) -> vec3f {\r\n        var N = fragmentInputs.vNormalW.xyz;\r\n        var L = normalize(scene.vEyePosition.xyz - fragmentInputs.vPositionW.xyz);\r\n        var H = normalize(L + L);\r\n        var LdotN = clamp(dot(L,N), 0., 1.);\r\n        var HdotN = clamp(dot(H,N), 0., 1.);\r\n        var specTerm = pow(HdotN, uniforms.dbg_shadedSpecularColorPower.w);\r\n        var result = color * (LdotN / PI);\r\n        result += uniforms.dbg_shadedSpecularColorPower.rgb * (specTerm / PI);\r\n        return result;\r\n    }\r\n#endif\r\n\r\n#if DBG_MODE == 1 || DBG_MODE == 3\r\n    fn dbg_edgeFactor() -> f32 {\r\n        var d = fwidth(fragmentInputs.dbg_vBarycentric);\r\n        var a3 = smoothstep(vec3f(0.), d * uniforms.dbg_thicknessRadiusScale.x, fragmentInputs.dbg_vBarycentric);\r\n        return min(min(a3.x, a3.y), a3.z);\r\n    }\r\n#endif\r\n\r\n#if DBG_MODE == 2 || DBG_MODE == 3\r\n    fn dbg_cornerFactor() -> f32 {\r\n        let worldPos = fragmentInputs.vPositionW;\r\n        let dist = length(worldPos - fragmentInputs.dbg_vVertexWorldPos);\r\n        let camDist = length(worldPos - scene.vEyePosition.xyz);\r\n        let d = sqrt(camDist) * .001;\r\n        return smoothstep((uniforms.dbg_thicknessRadiusScale.y * d), ((uniforms.dbg_thicknessRadiusScale.y * 1.01) * d), dist);\r\n    }\r\n#endif\r\n\r\n#if (DBG_MODE == 4 && defined(UV1)) || (DBG_MODE == 5 && defined(UV2))\r\n    fn dbg_checkerboardFactor(uv: vec2f) -> f32 {\r\n        var f = fract(uv * uniforms.dbg_thicknessRadiusScale.z);\r\n        f -= .5;\r\n        return select(0.0, 1.0, (f.x * f.y) > 0.0);\r\n    }\r\n#endif\r\n#endif`;\r\n\r\nconst fragmentMainEnd = `#if defined(DBG_ENABLED)\r\nvec3 dbg_color = vec3(1.);\r\n#if DBG_MODE == 1\r\n    dbg_color = mix(dbg_wireframeTrianglesColor, vec3(1.), dbg_edgeFactor());\r\n#elif DBG_MODE == 2 || DBG_MODE == 3\r\n    float dbg_cornerFactor = dbg_cornerFactor();\r\n    if (dbg_vPass == 0. && dbg_cornerFactor == 1.) discard;\r\n    dbg_color = mix(dbg_vertexColor, vec3(1.), dbg_cornerFactor);\r\n    #if DBG_MODE == 3\r\n        dbg_color *= mix(dbg_wireframeVerticesColor, vec3(1.), dbg_edgeFactor());\r\n    #endif\r\n#elif DBG_MODE == 4 && defined(MAINUV1)\r\n    dbg_color = mix(dbg_uvPrimaryColor, dbg_uvSecondaryColor, dbg_checkerboardFactor(vMainUV1));\r\n#elif DBG_MODE == 5 && defined(MAINUV2)\r\n    dbg_color = mix(dbg_uvPrimaryColor, dbg_uvSecondaryColor, dbg_checkerboardFactor(vMainUV2));\r\n#elif DBG_MODE == 6 && defined(VERTEXCOLOR)\r\n    dbg_color = vColor.rgb;\r\n#elif DBG_MODE == 7\r\n    dbg_color = dbg_materialColor;\r\n#endif\r\n\r\n#if defined(DBG_MULTIPLY)\r\n    gl_FragColor *= vec4(dbg_color, 1.);\r\n#else\r\n    #if DBG_MODE != 6\r\n        gl_FragColor = vec4(dbg_applyShading(dbg_shadedDiffuseColor) * dbg_color, 1.);\r\n    #else\r\n        gl_FragColor = vec4(dbg_color, 1.);\r\n    #endif\r\n#endif\r\n#endif`;\r\n\r\nconst fragmentMainEndWebGPU = `#if defined(DBG_ENABLED)\r\nvar dbg_color = vec3f(1.);\r\n#if DBG_MODE == 1\r\n    dbg_color = mix(uniforms.dbg_wireframeTrianglesColor, vec3f(1.), dbg_edgeFactor());\r\n#elif DBG_MODE == 2 || DBG_MODE == 3\r\n    let dbg_cornerFactor = dbg_cornerFactor();\r\n    if (fragmentInputs.dbg_vPass == 0.0 && dbg_cornerFactor == 1.0) {\r\n        discard;\r\n    }\r\n    dbg_color = mix(uniforms.dbg_vertexColor, vec3f(1.), dbg_cornerFactor);\r\n    #if DBG_MODE == 3\r\n        dbg_color *= mix(uniforms.dbg_wireframeVerticesColor, vec3f(1.), dbg_edgeFactor());\r\n    #endif\r\n#elif DBG_MODE == 4 && defined(MAINUV1)\r\n    dbg_color = mix(uniforms.dbg_uvPrimaryColor, uniforms.dbg_uvSecondaryColor, dbg_checkerboardFactor(fragmentInputs.vMainUV1));\r\n#elif DBG_MODE == 5 && defined(MAINUV2)\r\n    dbg_color = mix(uniforms.dbg_uvPrimaryColor, uniforms.dbg_uvSecondaryColor, dbg_checkerboardFactor(fragmentInputs.vMainUV2));\r\n#elif DBG_MODE == 6 && defined(VERTEXCOLOR)\r\n    dbg_color = fragmentInputs.vColor.rgb;\r\n#elif DBG_MODE == 7\r\n    dbg_color = uniforms.dbg_materialColor;\r\n#endif\r\n\r\n#if defined(DBG_MULTIPLY)\r\n    fragmentOutputs.color *= vec4f(dbg_color, 1.);\r\n#else\r\n    #if DBG_MODE != 6\r\n        fragmentOutputs.color = vec4f(dbg_applyShading(uniforms.dbg_shadedDiffuseColor) * dbg_color, 1.);\r\n    #else\r\n        fragmentOutputs.color = vec4f(dbg_color, 1.);\r\n    #endif\r\n#endif\r\n#endif`;\r\n\r\nconst defaultMaterialColors = [\r\n    new Color3(0.98, 0.26, 0.38),\r\n    new Color3(0.47, 0.75, 0.3),\r\n    new Color3(0, 0.26, 0.77),\r\n    new Color3(0.97, 0.6, 0.76),\r\n    new Color3(0.19, 0.63, 0.78),\r\n    new Color3(0.98, 0.8, 0.6),\r\n    new Color3(0.65, 0.43, 0.15),\r\n    new Color3(0.15, 0.47, 0.22),\r\n    new Color3(0.67, 0.71, 0.86),\r\n    new Color3(0.09, 0.46, 0.56),\r\n    new Color3(0.8, 0.98, 0.02),\r\n    new Color3(0.39, 0.29, 0.13),\r\n    new Color3(0.53, 0.63, 0.06),\r\n    new Color3(0.95, 0.96, 0.41),\r\n    new Color3(1, 0.72, 0.94),\r\n    new Color3(0.63, 0.08, 0.31),\r\n    new Color3(0.66, 0.96, 0.95),\r\n    new Color3(0.22, 0.14, 0.19),\r\n    new Color3(0.14, 0.65, 0.59),\r\n    new Color3(0.93, 1, 0.68),\r\n    new Color3(0.93, 0.14, 0.44),\r\n    new Color3(0.47, 0.86, 0.67),\r\n    new Color3(0.85, 0.07, 0.78),\r\n    new Color3(0.53, 0.64, 0.98),\r\n    new Color3(0.43, 0.37, 0.56),\r\n    new Color3(0.71, 0.65, 0.25),\r\n    new Color3(0.66, 0.19, 0.01),\r\n    new Color3(0.94, 0.53, 0.12),\r\n    new Color3(0.41, 0.44, 0.44),\r\n    new Color3(0.24, 0.71, 0.96),\r\n    new Color3(0.57, 0.28, 0.56),\r\n    new Color3(0.44, 0.98, 0.42),\r\n];\r\n\r\n/**\r\n * Supported visualizations of MeshDebugPluginMaterial\r\n */\r\nexport const enum MeshDebugMode {\r\n    /**\r\n     * Material without any mesh debug visualization\r\n     */\r\n    NONE = 0,\r\n    /**\r\n     * A wireframe of the mesh\r\n     * NOTE: For this mode to work correctly, convertToUnIndexedMesh() or MeshDebugPluginMaterial.PrepareMeshForTrianglesAndVerticesMode() must first be called on mesh.\r\n     */\r\n    TRIANGLES = 1,\r\n    /**\r\n     * Points drawn over vertices of mesh\r\n     * NOTE: For this mode to work correctly, MeshDebugPluginMaterial.PrepareMeshForTrianglesAndVerticesMode() must first be called on mesh.\r\n     */\r\n    VERTICES = 2,\r\n    /**\r\n     * A wireframe of the mesh, with points drawn over vertices\r\n     * NOTE: For this mode to work correctly, MeshDebugPluginMaterial.PrepareMeshForTrianglesAndVerticesMode() must first be called on mesh.\r\n     */\r\n    TRIANGLES_VERTICES = 3,\r\n    /**\r\n     * A checkerboard grid of the mesh's UV set 0\r\n     */\r\n    UV0 = 4,\r\n    /**\r\n     * A checkerboard grid of the mesh's UV set 1\r\n     */\r\n    UV1 = 5,\r\n    /**\r\n     * The mesh's vertex colors displayed as the primary texture\r\n     */\r\n    VERTEXCOLORS = 6,\r\n    /**\r\n     * An arbitrary, distinguishable color to identify the material\r\n     */\r\n    MATERIALIDS = 7,\r\n}\r\n\r\n/**\r\n * Options for MeshDebugPluginMaterial visualizations\r\n */\r\nexport interface MeshDebugOptions {\r\n    /**\r\n     * The mesh debug visualization.\r\n     * Defaults to NONE.\r\n     */\r\n    mode?: MeshDebugMode;\r\n    /**\r\n     * Whether the mesh debug visualization should multiply with color underneath.\r\n     * Defaults to true.\r\n     */\r\n    multiply?: boolean;\r\n    /**\r\n     * Diffuse color used to shade the mesh.\r\n     * Defaults to (1.0, 1.0, 1.0).\r\n     */\r\n    shadedDiffuseColor?: Color3;\r\n    /**\r\n     * Specular color used to shade the mesh.\r\n     * Defaults to (0.8, 0.8, 0.8).\r\n     */\r\n    shadedSpecularColor?: Color3;\r\n    /**\r\n     * Specular power used to shade the mesh.\r\n     * Defaults to 10.\r\n     */\r\n    shadedSpecularPower?: number;\r\n    /**\r\n     * Width of edge lines in TRIANGLES and TRIANGLE_VERTICES modes.\r\n     * Defaults to 0.7.\r\n     */\r\n    wireframeThickness?: number;\r\n    /**\r\n     * Color of edge lines in TRIANGLES mode.\r\n     * Defaults to (0.0, 0.0, 0.0).\r\n     */\r\n    wireframeTrianglesColor?: Color3;\r\n    /**\r\n     * Color of edge lines in TRIANGLES_VERTICES modes.\r\n     * Defaults to (0.8, 0.8, 0.8).\r\n     */\r\n    wireframeVerticesColor?: Color3;\r\n    /**\r\n     * Color of vertices in TRIANGLES_VERTICES and VERTICES mode.\r\n     * Defaults to (0.0, 0.0, 0.0).\r\n     */\r\n    vertexColor?: Color3;\r\n    /**\r\n     * Radius of dots drawn over vertices in TRIANGLE_VERTICES and VERTICES mode.\r\n     * Defaults to 1.2.\r\n     */\r\n    vertexRadius?: number;\r\n    /**\r\n     * Size of tiles in UV1 or UV2 modes.\r\n     * Defaults to 20.\r\n     */\r\n    uvScale?: number;\r\n    /**\r\n     * 1st color of checkerboard grid in UV1 or UV2 modes.\r\n     * Defaults to (1.0, 1.0, 1.0).\r\n     */\r\n    uvPrimaryColor?: Color3;\r\n    /**\r\n     * 2nd color of checkerboard grid in UV1 or UV2 modes.\r\n     * Defaults to (0.5, 0.5, 0.5).\r\n     */\r\n    uvSecondaryColor?: Color3;\r\n}\r\n\r\n/** @internal */\r\nclass MeshDebugDefines extends MaterialDefines {\r\n    /**\r\n     * Current mesh debug visualization.\r\n     * Defaults to NONE.\r\n     */\r\n    DBG_MODE: MeshDebugMode = MeshDebugMode.NONE;\r\n    /**\r\n     * Whether the mesh debug visualization multiplies with colors underneath.\r\n     * Defaults to true.\r\n     */\r\n    DBG_MULTIPLY: boolean = true;\r\n    /**\r\n     * Whether the mesh debug plugin is enabled in the material.\r\n     * Defaults to true.\r\n     */\r\n    DBG_ENABLED: boolean = true;\r\n}\r\n\r\n/**\r\n * Plugin that implements various mesh debug visualizations,\r\n * List of available visualizations can be found in MeshDebugMode enum.\r\n */\r\nexport class MeshDebugPluginMaterial extends MaterialPluginBase {\r\n    /**\r\n     * Total number of instances of the plugin.\r\n     * Starts at 0.\r\n     */\r\n    private static _PluginCount: number = 0;\r\n\r\n    /**\r\n     * Color palette used for MATERIALIDS mode.\r\n     * Defaults to `defaultMaterialColors`\r\n     */\r\n    public static MaterialColors: Color3[] = defaultMaterialColors;\r\n\r\n    /**\r\n     * Material ID color of this plugin instance.\r\n     * Taken from index `_PluginCount` of `MaterialColors` at time of instantiation.\r\n     */\r\n    @serializeAsColor3()\r\n    private _materialColor: Color3;\r\n\r\n    /**\r\n     * Whether the mesh debug plugin is enabled in the material.\r\n     * Defaults to true in constructor.\r\n     */\r\n    @serialize()\r\n    private _isEnabled: boolean;\r\n\r\n    private _mode: MeshDebugMode;\r\n    /**\r\n     * The mesh debug visualization.\r\n     * Defaults to NONE.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllDefinesAsDirty\")\r\n    public accessor mode: MeshDebugMode;\r\n\r\n    private _multiply: boolean;\r\n    /**\r\n     * Whether the mesh debug visualization should multiply with color underneath.\r\n     * Defaults to true.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllDefinesAsDirty\")\r\n    public accessor multiply: boolean;\r\n\r\n    /**\r\n     * Diffuse color used to shade the mesh.\r\n     * Defaults to (1.0, 1.0, 1.0).\r\n     */\r\n    @serializeAsColor3()\r\n    public shadedDiffuseColor: Color3;\r\n\r\n    /**\r\n     * Specular color used to shade the mesh.\r\n     * Defaults to (0.8, 0.8, 0.8).\r\n     */\r\n    @serializeAsColor3()\r\n    public shadedSpecularColor: Color3;\r\n\r\n    /**\r\n     * Specular power used to shade the mesh.\r\n     * Defaults to 10.\r\n     */\r\n    @serialize()\r\n    public shadedSpecularPower: number;\r\n\r\n    /**\r\n     * Width of edge lines in TRIANGLES and TRIANGLE_VERTICES modes.\r\n     * Defaults to 0.7.\r\n     */\r\n    @serialize()\r\n    public wireframeThickness: number;\r\n\r\n    /**\r\n     * Color of edge lines in TRIANGLES mode.\r\n     * Defaults to (0.0, 0.0, 0.0).\r\n     */\r\n    @serializeAsColor3()\r\n    public wireframeTrianglesColor: Color3;\r\n\r\n    /**\r\n     * Color of edge lines in TRIANGLES_VERTICES modes.\r\n     * Defaults to (0.8, 0.8, 0.8).\r\n     */\r\n    @serializeAsColor3()\r\n    public wireframeVerticesColor: Color3;\r\n\r\n    /**\r\n     * Color of vertices in TRIANGLES_VERTICES and VERTICES mode.\r\n     * Defaults to (0.0, 0.0, 0.0).\r\n     */\r\n    @serializeAsColor3()\r\n    public vertexColor: Color3;\r\n\r\n    /**\r\n     * Radius of dots drawn over vertices in TRIANGLE_VERTICES and VERTICES mode.\r\n     * Defaults to 1.2.\r\n     */\r\n    @serialize()\r\n    public vertexRadius: number;\r\n\r\n    /**\r\n     * Size of tiles in UV1 or UV2 modes.\r\n     * Defaults to 20.\r\n     */\r\n    @serialize()\r\n    public uvScale: number;\r\n\r\n    /**\r\n     * 1st color of checkerboard grid in UV1 or UV2 modes.\r\n     * Defaults to (1.0, 1.0, 1.0).\r\n     */\r\n    @serializeAsColor3()\r\n    public uvPrimaryColor: Color3;\r\n\r\n    /**\r\n     * 2nd color of checkerboard grid in UV1 or UV2 modes.\r\n     * Defaults to (0.5, 0.5, 0.5).\r\n     */\r\n    @serializeAsColor3()\r\n    public uvSecondaryColor: Color3;\r\n\r\n    /** @internal */\r\n    protected _markAllDefinesAsDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n        switch (shaderLanguage) {\r\n            case ShaderLanguage.GLSL:\r\n            case ShaderLanguage.WGSL:\r\n                return true;\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new MeshDebugPluginMaterial\r\n     * @param material Material to attach the mesh debug plugin to\r\n     * @param options Options for the mesh debug plugin\r\n     */\r\n    constructor(material: PBRBaseMaterial | StandardMaterial, options: MeshDebugOptions = {}) {\r\n        const defines = new MeshDebugDefines();\r\n        defines.DBG_MODE = options.mode ?? defines.DBG_MODE;\r\n        defines.DBG_MULTIPLY = options.multiply ?? defines.DBG_MULTIPLY;\r\n        super(material, \"MeshDebug\", 200, defines, true, true);\r\n\r\n        this._mode = defines.DBG_MODE;\r\n        this._multiply = defines.DBG_MULTIPLY;\r\n        this.shadedDiffuseColor = options.shadedDiffuseColor ?? new Color3(1, 1, 1);\r\n        this.shadedSpecularColor = options.shadedSpecularColor ?? new Color3(0.8, 0.8, 0.8);\r\n        this.shadedSpecularPower = options.shadedSpecularPower ?? 10;\r\n        this.wireframeThickness = options.wireframeThickness ?? 0.7;\r\n        this.wireframeTrianglesColor = options.wireframeTrianglesColor ?? new Color3(0, 0, 0);\r\n        this.wireframeVerticesColor = options.wireframeVerticesColor ?? new Color3(0.8, 0.8, 0.8);\r\n        this.vertexColor = options.vertexColor ?? new Color3(0, 0, 0);\r\n        this.vertexRadius = options.vertexRadius ?? 1.2;\r\n        this.uvScale = options.uvScale ?? 20;\r\n        this.uvPrimaryColor = options.uvPrimaryColor ?? new Color3(1, 1, 1);\r\n        this.uvSecondaryColor = options.uvSecondaryColor ?? new Color3(0.5, 0.5, 0.5);\r\n\r\n        this._materialColor = MeshDebugPluginMaterial.MaterialColors[MeshDebugPluginMaterial._PluginCount++ % MeshDebugPluginMaterial.MaterialColors.length];\r\n        this.isEnabled = true;\r\n    }\r\n\r\n    /**\r\n     * Get the class name\r\n     * @returns Class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MeshDebugPluginMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Gets whether the mesh debug plugin is enabled in the material.\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the mesh debug plugin is enabled in the material.\r\n     * @param value enabled\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        if (this._isEnabled === value) {\r\n            return;\r\n        }\r\n        if (!this._material.getScene().getEngine().isWebGPU && this._material.getScene().getEngine().version == 1) {\r\n            Logger.Error(\"MeshDebugPluginMaterial is not supported on WebGL 1.0.\");\r\n            this._isEnabled = false;\r\n            return;\r\n        }\r\n        this._isEnabled = value;\r\n        this._markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Prepare the defines\r\n     * @param defines Mesh debug defines\r\n     * @param scene Scene\r\n     * @param mesh Mesh associated with material\r\n     */\r\n    public override prepareDefines(defines: MeshDebugDefines, scene: Scene, mesh: AbstractMesh) {\r\n        if (\r\n            (this._mode == MeshDebugMode.VERTICES || this._mode == MeshDebugMode.TRIANGLES || this._mode == MeshDebugMode.TRIANGLES_VERTICES) &&\r\n            !mesh.isVerticesDataPresent(\"dbg_initialPass\")\r\n        ) {\r\n            Logger.Warn(\r\n                \"For best results with TRIANGLES, TRIANGLES_VERTICES, or VERTICES modes, please use MeshDebugPluginMaterial.PrepareMeshForTrianglesAndVerticesMode() on mesh.\",\r\n                1\r\n            );\r\n        }\r\n\r\n        defines.DBG_MODE = this._mode;\r\n        defines.DBG_MULTIPLY = this._multiply;\r\n        defines.DBG_ENABLED = this._isEnabled;\r\n    }\r\n\r\n    /**\r\n     * Get the shader attributes\r\n     * @param attributes Array of attributes\r\n     */\r\n    public override getAttributes(attributes: string[]) {\r\n        attributes.push(\"dbg_initialPass\");\r\n    }\r\n\r\n    /**\r\n     * Get the shader uniforms\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns Uniforms\r\n     */\r\n    public override getUniforms(shaderLanguage = ShaderLanguage.GLSL) {\r\n        return {\r\n            ubo: [\r\n                { name: \"dbg_shadedDiffuseColor\", size: 3, type: \"vec3\" },\r\n                { name: \"dbg_shadedSpecularColorPower\", size: 4, type: \"vec4\" }, // shadedSpecularColor, shadedSpecularPower\r\n                { name: \"dbg_thicknessRadiusScale\", size: 3, type: \"vec3\" }, // wireframeThickness, vertexRadius, uvScale\r\n                { name: \"dbg_wireframeTrianglesColor\", size: 3, type: \"vec3\" },\r\n                { name: \"dbg_wireframeVerticesColor\", size: 3, type: \"vec3\" },\r\n                { name: \"dbg_vertexColor\", size: 3, type: \"vec3\" },\r\n                { name: \"dbg_uvPrimaryColor\", size: 3, type: \"vec3\" },\r\n                { name: \"dbg_uvSecondaryColor\", size: 3, type: \"vec3\" },\r\n                { name: \"dbg_materialColor\", size: 3, type: \"vec3\" },\r\n            ],\r\n            fragment: shaderLanguage === ShaderLanguage.GLSL ? fragmentUniforms : fragmentUniformsWebGPU,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Bind the uniform buffer\r\n     * @param uniformBuffer Uniform buffer\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer): void {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n        uniformBuffer.updateFloat3(\"dbg_shadedDiffuseColor\", this.shadedDiffuseColor.r, this.shadedDiffuseColor.g, this.shadedDiffuseColor.b);\r\n        uniformBuffer.updateFloat4(\"dbg_shadedSpecularColorPower\", this.shadedSpecularColor.r, this.shadedSpecularColor.g, this.shadedSpecularColor.b, this.shadedSpecularPower);\r\n        uniformBuffer.updateFloat3(\"dbg_thicknessRadiusScale\", this.wireframeThickness, this.vertexRadius, this.uvScale);\r\n        uniformBuffer.updateColor3(\"dbg_wireframeTrianglesColor\", this.wireframeTrianglesColor);\r\n        uniformBuffer.updateColor3(\"dbg_wireframeVerticesColor\", this.wireframeVerticesColor);\r\n        uniformBuffer.updateColor3(\"dbg_vertexColor\", this.vertexColor);\r\n        uniformBuffer.updateColor3(\"dbg_uvPrimaryColor\", this.uvPrimaryColor);\r\n        uniformBuffer.updateColor3(\"dbg_uvSecondaryColor\", this.uvSecondaryColor);\r\n        uniformBuffer.updateColor3(\"dbg_materialColor\", this._materialColor);\r\n    }\r\n\r\n    /**\r\n     * Get shader code\r\n     * @param shaderType \"vertex\" or \"fragment\"\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns Shader code\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return shaderType === \"vertex\"\r\n                ? {\r\n                      CUSTOM_VERTEX_DEFINITIONS: vertexDefinitionsWebGPU,\r\n                      CUSTOM_VERTEX_MAIN_END: vertexMainEndWebGPU,\r\n                  }\r\n                : {\r\n                      CUSTOM_FRAGMENT_DEFINITIONS: fragmentDefinitionsWebGPU,\r\n                      CUSTOM_FRAGMENT_MAIN_END: fragmentMainEndWebGPU,\r\n                  };\r\n        }\r\n\r\n        return shaderType === \"vertex\"\r\n            ? {\r\n                  CUSTOM_VERTEX_DEFINITIONS: vertexDefinitions,\r\n                  CUSTOM_VERTEX_MAIN_END: vertexMainEnd,\r\n              }\r\n            : {\r\n                  CUSTOM_FRAGMENT_DEFINITIONS: fragmentDefinitions,\r\n                  CUSTOM_FRAGMENT_MAIN_END: fragmentMainEnd,\r\n              };\r\n    }\r\n\r\n    /**\r\n     * Resets static variables of the plugin to their original state\r\n     */\r\n    public static Reset(): void {\r\n        this._PluginCount = 0;\r\n        this.MaterialColors = defaultMaterialColors;\r\n    }\r\n\r\n    /**\r\n     * Renders triangles in a mesh 3 times by tripling the indices in the index buffer.\r\n     * Used to prepare a mesh to be rendered in `TRIANGLES`, `VERTICES`, or `TRIANGLES_VERTICES` modes.\r\n     * NOTE: This is a destructive operation. The mesh's index buffer and vertex buffers are modified, and a new vertex buffer is allocated.\r\n     * If you'd like the ability to revert these changes, toggle the optional `returnRollback` flag.\r\n     * @param mesh the mesh to target\r\n     * @param returnRollback whether or not to return a function that reverts mesh to its initial state. Default: false.\r\n     * @returns a rollback function if `returnRollback` is true, otherwise an empty function.\r\n     */\r\n    public static PrepareMeshForTrianglesAndVerticesMode(mesh: Mesh, returnRollback: boolean = false): () => void {\r\n        let rollback = () => {};\r\n\r\n        if (mesh.getTotalIndices() == 0) {\r\n            return rollback;\r\n        }\r\n\r\n        if (returnRollback) {\r\n            const kinds = mesh.getVerticesDataKinds();\r\n            const indices = mesh.getIndices()!;\r\n            const data: { [kind: string]: FloatArray } = {};\r\n            for (const kind of kinds) {\r\n                data[kind] = mesh.getVerticesData(kind)!;\r\n            }\r\n\r\n            rollback = function () {\r\n                mesh.setIndices(indices);\r\n                for (const kind of kinds) {\r\n                    const stride = mesh.getVertexBuffer(kind)!.getStrideSize();\r\n                    mesh.setVerticesData(kind, data[kind], undefined, stride);\r\n                }\r\n                mesh.removeVerticesData(\"dbg_initialPass\");\r\n            };\r\n        }\r\n\r\n        let indices = Array.from(mesh.getIndices()!);\r\n        const newIndices1 = [];\r\n        for (let i = 0; i < indices.length; i += 3) {\r\n            newIndices1.push(indices[i + 1], indices[i + 2], indices[i + 0]);\r\n        }\r\n        mesh.setIndices(indices.concat(newIndices1));\r\n\r\n        mesh.convertToUnIndexedMesh();\r\n\r\n        mesh.isUnIndexed = false;\r\n\r\n        indices = Array.from(mesh.getIndices()!);\r\n        const newIndices2 = [];\r\n        for (let i = indices.length / 2; i < indices.length; i += 3) {\r\n            newIndices2.push(indices[i + 1], indices[i + 2], indices[i + 0]);\r\n        }\r\n        mesh.setIndices(indices.concat(newIndices2));\r\n\r\n        const num = mesh.getTotalVertices();\r\n        const mid = num / 2;\r\n        const pass = new Array(num).fill(1, 0, mid).fill(0, mid, num);\r\n        mesh.setVerticesData(\"dbg_initialPass\", pass, false, 1);\r\n\r\n        return rollback;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshDebugPluginMaterial.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshDebugPluginMaterial(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MeshDebugPluginMaterial\", MeshDebugPluginMaterial);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gaussianSplattingDepthPixelShader\";\nconst shader = `precision highp float;varying vec2 vPosition;varying vec4 vColor;\n#ifdef DEPTH_RENDER\nvarying float vDepthMetric;\n#endif\nvoid main(void) {float A=-dot(vPosition,vPosition);\n#if (defined(SM_SOFTTRANSPARENTSHADOW) && SM_SOFTTRANSPARENTSHADOW==1) || \\\n(defined(DEPTH_RENDER) && defined(ALPHA_BLENDED_DEPTH))\nfloat alpha=exp(A)*vColor.a;if (A<-4.)\ndiscard;\n#else\nif (A<-vColor.a)\ndiscard;\n#endif\n#ifdef DEPTH_RENDER\nfloat opacity=1.0;\n#ifdef ALPHA_BLENDED_DEPTH\nopacity=alpha;\n#endif\ngl_FragColor=vec4(vDepthMetric,0.0,0.0,opacity);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const gaussianSplattingDepthPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"gaussianSplattingUboDeclaration\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute vec3 position;attribute vec4 splatIndex0;attribute vec4 splatIndex1;attribute vec4 splatIndex2;attribute vec4 splatIndex3;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const gaussianSplattingUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { gaussianSplattingVertexDeclaration } from \"./ShadersInclude/gaussianSplattingVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { gaussianSplattingUboDeclaration } from \"./ShadersInclude/gaussianSplattingUboDeclaration\";\nimport { gaussianSplatting } from \"./ShadersInclude/gaussianSplatting\";\n\nconst name = \"gaussianSplattingDepthVertexShader\";\nconst shader = `#include<__decl__gaussianSplattingVertex>\nuniform vec2 invViewport;uniform vec2 dataTextureSize;uniform vec2 focal;uniform float kernelSize;uniform float minPixelSize;uniform float alpha;uniform sampler2D covariancesATexture;uniform sampler2D covariancesBTexture;uniform sampler2D centersTexture;uniform sampler2D colorsTexture;\n#if IS_COMPOUND\nuniform mat4 partWorld[MAX_PART_COUNT];uniform float partVisibility[MAX_PART_COUNT];uniform sampler2D partIndicesTexture;\n#endif\nvarying vec2 vPosition;varying vec4 vColor;\n#include<gaussianSplatting>\n#ifdef DEPTH_RENDER\nuniform vec2 depthValues;varying float vDepthMetric;\n#endif\nvoid main(void) {float splatIndex=getSplatIndex(int(position.z+0.5));Splat splat=readSplat(splatIndex);vec3 covA=splat.covA.xyz;vec3 covB=vec3(splat.covA.w,splat.covB.xy);\n#if IS_COMPOUND\nmat4 splatWorld=getPartWorld(splat.partIndex);\n#else\nmat4 splatWorld=world;\n#endif\nvec4 worldPosGS=splatWorld*vec4(splat.center.xyz,1.0);vPosition=position.xy;vColor=splat.color;vColor.w*=alpha;\n#if IS_COMPOUND\nvColor.w*=partVisibility[splat.partIndex];\n#endif\ngl_Position=gaussianSplatting(position.xy,worldPosGS.xyz,vec2(1.,1.),covA,covB,splatWorld,view,projection);\n#ifdef DEPTH_RENDER\n#ifdef USE_REVERSE_DEPTHBUFFER\nvDepthMetric=((-gl_Position.z+depthValues.x)/(depthValues.y));\n#else\nvDepthMetric=((gl_Position.z+depthValues.x)/(depthValues.y));\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [gaussianSplattingVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, gaussianSplattingUboDeclaration, gaussianSplatting];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingDepthVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { gaussianSplattingFragmentDeclarationWGSL } from \"./ShadersInclude/gaussianSplattingFragmentDeclaration\";\n\nconst name = \"gaussianSplattingDepthPixelShader\";\nconst shader = `#include<gaussianSplattingFragmentDeclaration>\nvarying vPosition: vec2f;varying vColor: vec4f;\n#ifdef DEPTH_RENDER\nvarying vDepthMetric: f32;\n#endif\nfn checkDiscard(inPosition: vec2f,inColor: vec4f)->vec4f {var A : f32=-dot(inPosition,inPosition);var alpha : f32=exp(A)*inColor.a;\n#if (defined(SM_SOFTTRANSPARENTSHADOW) && SM_SOFTTRANSPARENTSHADOW==1) || \\\n(defined(DEPTH_RENDER) && defined(ALPHA_BLENDED_DEPTH))\nif (A<-4.) {discard;}\n#else\nif (A<-inColor.a) {discard;}\n#endif\n#ifdef DEPTH_RENDER\nvar opacity : f32=1.0;\n#ifdef ALPHA_BLENDED_DEPTH\nopacity=alpha;\n#endif\nreturn vec4f(fragmentInputs.vDepthMetric,0.0,0.0,opacity);\n#else\nreturn vec4f(inColor.rgb,alpha);\n#endif\n}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=checkDiscard(fragmentInputs.vPosition,fragmentInputs.vColor);\n#if (defined(SM_SOFTTRANSPARENTSHADOW) && SM_SOFTTRANSPARENTSHADOW==1) || \\\n(defined(DEPTH_RENDER) && defined(ALPHA_BLENDED_DEPTH))\nvar alpha : f32=fragmentOutputs.color.a;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [logDepthFragmentWGSL, fogFragmentWGSL, gaussianSplattingFragmentDeclarationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingDepthPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { gaussianSplattingWGSL } from \"./ShadersInclude/gaussianSplatting\";\n\nconst name = \"gaussianSplattingDepthVertexShader\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute splatIndex0: vec4f;attribute splatIndex1: vec4f;attribute splatIndex2: vec4f;attribute splatIndex3: vec4f;attribute position: vec3f;uniform invViewport: vec2f;uniform dataTextureSize: vec2f;uniform focal: vec2f;uniform kernelSize: f32;uniform minPixelSize: f32;uniform alpha: f32;var covariancesATexture: texture_2d<f32>;var covariancesBTexture: texture_2d<f32>;var centersTexture: texture_2d<f32>;var colorsTexture: texture_2d<f32>;\n#if IS_COMPOUND\nuniform partWorld: array<mat4x4<f32>,MAX_PART_COUNT>;uniform partVisibility: array<f32,MAX_PART_COUNT>;var partIndicesTexture: texture_2d<f32>;\n#endif\nvarying vPosition: vec2f;varying vColor: vec4f;\n#ifdef DEPTH_RENDER\nuniform depthValues: vec2f;varying vDepthMetric: f32;\n#endif\n#include<gaussianSplatting>\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {let splatIndex: f32=getSplatIndex(i32(vertexInputs.position.z+0.5),vertexInputs.splatIndex0,vertexInputs.splatIndex1,vertexInputs.splatIndex2,vertexInputs.splatIndex3);var splat: Splat=readSplat(splatIndex,uniforms.dataTextureSize);var covA: vec3f=splat.covA.xyz;var covB: vec3f=vec3f(splat.covA.w,splat.covB.xy);\n#if IS_COMPOUND\nlet splatWorld: mat4x4f=getPartWorld(splat.partIndex);\n#else\nlet splatWorld: mat4x4f=mesh.world;\n#endif\nlet worldPos: vec4f=splatWorld*vec4f(splat.center.xyz,1.0);vertexOutputs.vPosition=vertexInputs.position.xy;vertexOutputs.vColor=splat.color;vertexOutputs.vColor.w*=uniforms.alpha;\n#if IS_COMPOUND\nvertexOutputs.vColor.w*=uniforms.partVisibility[splat.partIndex];\n#endif\nvertexOutputs.position=gaussianSplatting(vertexInputs.position.xy,worldPos.xyz,vec2f(1.0,1.0),covA,covB,splatWorld,scene.view,scene.projection,uniforms.focal,uniforms.invViewport,uniforms.kernelSize,uniforms.minPixelSize);\n#ifdef DEPTH_RENDER\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric=((-vertexOutputs.position.z+uniforms.depthValues.x)/(uniforms.depthValues.y));\n#else\nvertexOutputs.vDepthMetric=((vertexOutputs.position.z+uniforms.depthValues.x)/(uniforms.depthValues.y));\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, gaussianSplattingWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingDepthVertexShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh.pure\";\r\nimport { type UniformBuffer } from \"../uniformBuffer\";\r\nimport { type MaterialDefines } from \"../materialDefines\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Color3 } from \"../../Maths/math.color.pure\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { GetGaussianSplattingMaxPartCount, GetPartIndexVaryingDeclaration, type GaussianSplattingMaterial } from \"./gaussianSplattingMaterial.pure\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\n\r\n/**\r\n * Plugin for GaussianSplattingMaterial that replaces per-splat colors with a\r\n * solid color per compound-mesh part. Each part index maps to a single Color3\r\n * value, which is looked up in a uniform array in the fragment shader.\r\n */\r\nexport class GaussianSplattingSolidColorMaterialPlugin extends MaterialPluginBase {\r\n    private _partColors: Color3[];\r\n    private _maxPartCount: number;\r\n    private _isEnabled = true;\r\n    private readonly _partColorArray: number[] = [];\r\n    /**\r\n     * Whether the solid-color override is active. When false, splats\r\n     * render with their original per-splat colors.\r\n     * Toggled via a shader uniform so no recompilation is required.\r\n     */\r\n    @serialize()\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n\r\n    public set isEnabled(value: boolean) {\r\n        if (this._isEnabled === value) {\r\n            return;\r\n        }\r\n        this._isEnabled = value;\r\n        this._onIsEnabledChanged();\r\n    }\r\n\r\n    /** @internal */\r\n    public _onIsEnabledChanged(): void {\r\n        // Intentional no-op: isEnabled is applied via a uniform in\r\n        // bindForSubMesh, so no dirty-marking or recompilation is needed.\r\n    }\r\n\r\n    /**\r\n     * Creates a new GaussianSplatSolidColorPlugin.\r\n     * @param material The GaussianSplattingMaterial to attach the plugin to.\r\n     * @param partColors A map from part index to the solid Color3 for that part.\r\n     * @param maxPartCount The maximum number of parts supported. This determines the size of the uniform array.\r\n     */\r\n    constructor(material: GaussianSplattingMaterial, partColors: Color3[], maxPartCount?: number) {\r\n        super(material, \"GaussianSplatSolidColor\", 200);\r\n\r\n        this._partColors = partColors;\r\n        this._maxPartCount = maxPartCount ?? GetGaussianSplattingMaxPartCount(material.getScene().getEngine());\r\n        this._enable(true);\r\n    }\r\n\r\n    /**\r\n     * Updates the part colors dynamically.\r\n     * @param partColors A map from part index to the solid Color3 for that part.\r\n     */\r\n    public updatePartColors(partColors: Color3[]): void {\r\n        this._partColors = partColors;\r\n    }\r\n\r\n    // --- Plugin overrides ---\r\n\r\n    /**\r\n     * @returns the class name\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GaussianSplattingSolidColorMaterialPlugin\";\r\n    }\r\n\r\n    /**\r\n     * Indicates this plugin supports both GLSL and WGSL.\r\n     * @param shaderLanguage the shader language to check\r\n     * @returns true for GLSL and WGSL\r\n     */\r\n    public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n        switch (shaderLanguage) {\r\n            case ShaderLanguage.GLSL:\r\n            case ShaderLanguage.WGSL:\r\n                return true;\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Always ready — no textures or async resources to wait on.\r\n     * @param _defines the defines\r\n     * @param _scene the scene\r\n     * @param _engine the engine\r\n     * @param _subMesh the submesh\r\n     * @returns true\r\n     */\r\n    public override isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns custom shader code fragments to inject solid-color rendering.\r\n     *\r\n     * @param shaderType \"vertex\" or \"fragment\"\r\n     * @param shaderLanguage the shader language to use (default: GLSL)\r\n     * @returns null or a map of injection point names to code strings\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        const maxPartCount = this._maxPartCount;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return this._getCustomCodeWGSL(shaderType, maxPartCount);\r\n        }\r\n        return this._getCustomCodeGLSL(shaderType, maxPartCount);\r\n    }\r\n\r\n    private _getCustomCodeGLSL(shaderType: string, maxPartCount: number): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderType === \"vertex\") {\r\n            return {\r\n                CUSTOM_VERTEX_DEFINITIONS: GetPartIndexVaryingDeclaration(ShaderLanguage.GLSL),\r\n                CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n    vPartIndex = float(splat.partIndex);\r\n#else\r\n    vPartIndex = 0.0;\r\n#endif\r\n                `,\r\n            };\r\n        } else if (shaderType === \"fragment\") {\r\n            return {\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n${GetPartIndexVaryingDeclaration(ShaderLanguage.GLSL)}\r\nuniform float solidColorEnabled;\r\nuniform vec3 partColors[${maxPartCount}];\r\n                `,\r\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\nif (solidColorEnabled > 0.5) {\r\n    int partIdx = int(vPartIndex + 0.5);\r\n    finalColor = vec4(partColors[partIdx], finalColor.w);\r\n}\r\n                `,\r\n            };\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private _getCustomCodeWGSL(shaderType: string, maxPartCount: number): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderType === \"vertex\") {\r\n            return {\r\n                CUSTOM_VERTEX_DEFINITIONS: GetPartIndexVaryingDeclaration(ShaderLanguage.WGSL),\r\n                CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n    vertexOutputs.vPartIndex = f32(splat.partIndex);\r\n#else\r\n    vertexOutputs.vPartIndex = 0.0;\r\n#endif\r\n                `,\r\n            };\r\n        } else if (shaderType === \"fragment\") {\r\n            return {\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n${GetPartIndexVaryingDeclaration(ShaderLanguage.WGSL)}\r\nuniform solidColorEnabled: f32;\r\nuniform partColors: array<vec3f, ${maxPartCount}>;\r\n                `,\r\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\nif (uniforms.solidColorEnabled > 0.5) {\r\n    var partIdx: i32 = i32(fragmentInputs.vPartIndex + 0.5);\r\n    finalColor = vec4f(uniforms.partColors[partIdx], finalColor.w);\r\n}\r\n                `,\r\n            };\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Registers the plugin uniforms with the engine so that\r\n     * the Effect can resolve their locations.\r\n     * @returns uniform descriptions\r\n     */\r\n    public override getUniforms(): {\r\n        ubo?: Array<{ name: string; size?: number; type?: string; arraySize?: number }>;\r\n        vertex?: string;\r\n        fragment?: string;\r\n        externalUniforms?: string[];\r\n    } {\r\n        return {\r\n            externalUniforms: [\"partColors\", \"solidColorEnabled\"],\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Binds the plugin uniforms each frame.\r\n     * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect)\r\n     * @param _scene the current scene\r\n     * @param _engine the current engine\r\n     * @param subMesh the submesh being rendered\r\n     */\r\n    public override bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void {\r\n        const effect = subMesh.effect;\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        effect.setFloat(\"solidColorEnabled\", this._isEnabled ? 1.0 : 0.0);\r\n\r\n        const colorArray = this._partColorArray;\r\n        colorArray.length = 0;\r\n        for (let i = 0; i < this._maxPartCount; i++) {\r\n            const color = this._partColors[i];\r\n            if (color) {\r\n                colorArray.push(color.r, color.g, color.b);\r\n            } else {\r\n                colorArray.push(0, 0, 0);\r\n            }\r\n        }\r\n\r\n        effect.setArray3(\"partColors\", colorArray);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingSolidColorMaterialPlugin.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingSolidColorMaterialPlugin(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GaussianSplattingSolidColorMaterialPlugin\", GaussianSplattingSolidColorMaterialPlugin);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../../types\";\nimport { type Scene } from \"../../scene\";\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\nimport { type SubMesh } from \"../../Meshes/subMesh\";\nimport { type UniformBuffer } from \"../uniformBuffer\";\nimport { MaterialDefines } from \"../materialDefines\";\nimport { MaterialPluginBase } from \"../materialPluginBase.pure\";\nimport { ShaderLanguage } from \"../shaderLanguage\";\nimport { RegisterClass } from \"../../Misc/typeStore\";\nimport { type Vector3 } from \"../../Maths/math.vector\";\nimport { Logger } from \"../../Misc/logger\";\nimport { type GaussianSplattingMaterial, GetGaussianSplattingMaxPartCount, GetPartIndexVaryingDeclaration } from \"./gaussianSplattingMaterial.pure\";\nimport { RawTexture } from \"../Textures/rawTexture\";\nimport { Constants } from \"../../Engines/constants\";\n\n/** @internal */\nclass GaussianSplattingDebugDefines extends MaterialDefines {\n    /** Defines whether any debug feature is active */\n    GS_DBG_ENABLED: boolean = false;\n    /** Defines whether world-space clipping box is enabled (0: off, 1: on) */\n    GS_DBG_CLIP: number = 0;\n    /** Defines whether opacity culling is enabled (0: off, 1: on) */\n    GS_DBG_CULL_OPACITY: number = 0;\n    /** Defines whether size culling is enabled (0: off, 1: on) */\n    GS_DBG_CULL_SIZE: number = 0;\n    /** Defines whether per-splat opacity scaling is enabled (0: off, 1: on) */\n    GS_DBG_OPACITY_SCALE: number = 0;\n    /** Defines whether opacity saturation (flat disk) is enabled (0: off, 1: on) */\n    GS_DBG_OPACITY_SATURATE: number = 0;\n    /** Defines whether the DC (base) SH color is included (0: off, 1: on) */\n    GS_DBG_SH_DC: number = 1;\n    /** Defines whether SH band 1 contribution is included (0: off, 1: on) */\n    GS_DBG_SH_ORDER1: number = 1;\n    /** Defines whether SH band 2 contribution is included (0: off, 1: on) */\n    GS_DBG_SH_ORDER2: number = 1;\n    /** Defines whether SH band 3 contribution is included (0: off, 1: on) */\n    GS_DBG_SH_ORDER3: number = 1;\n    /** Defines whether SH band 4 contribution is included (0: off, 1: on) */\n    GS_DBG_SH_ORDER4: number = 1;\n}\n\n/**\n * Per-part debug options for compound Gaussian splat meshes.\n * Each field is optional; unset fields fall back to the global setting on the plugin,\n * and if that is also unset, a neutral value is used (no culling, full SH, etc.).\n */\nexport interface IGaussianSplattingDebugOptions {\n    /** World-space axis-aligned clipping box, or null to disable. */\n    clippingBox: Nullable<{ min: Vector3; max: Vector3 }>;\n    /** Opacity culling range [0..1], or null to disable. */\n    opacityCulling: Nullable<{ min: number; max: number }>;\n    /** Size culling range, or null to disable. */\n    sizeCulling: Nullable<{ min: number; max: number }>;\n    /** Scalar opacity multiplier. 1.0 = no change. */\n    opacityScale: number;\n    /** When true, replaces Gaussian falloff with flat disk opacity. */\n    opacitySaturate: boolean;\n    /** Include the DC (base) SH color. */\n    shDc: boolean;\n    /** Include SH band 1 contribution. */\n    shOrder1: boolean;\n    /** Include SH band 2 contribution. */\n    shOrder2: boolean;\n    /** Include SH band 3 contribution. */\n    shOrder3: boolean;\n    /** Include SH band 4 contribution. */\n    shOrder4: boolean;\n}\n\n/**\n * Debug plugin for GaussianSplattingMaterial.\n * Provides runtime controls for clipping, opacity/size culling, opacity scaling,\n * opacity saturation, and per-SH-order toggling. All features are gated behind\n * the GS_DBG_ENABLED shader define — when every option is at its default value\n * the define is absent and the shader compiles to identical code as without the plugin.\n *\n * In compound mode (partCount \\> 0), per-part overrides can be set via setPartOptions().\n * Global settings act as defaults; per-part settings override them for that part index.\n */\nexport class GaussianSplattingDebugMaterialPlugin extends MaterialPluginBase {\n    private _clippingBox: Nullable<{ min: Vector3; max: Vector3 }> = null;\n    private _opacityCulling: Nullable<{ min: number; max: number }> = null;\n    private _sizeCulling: Nullable<{ min: number; max: number }> = null;\n    private _opacityScale: number = 1.0;\n    private _opacitySaturate: boolean = false;\n    private _shDc: boolean = true;\n    private _shOrder1: boolean = true;\n    private _shOrder2: boolean = true;\n    private _shOrder3: boolean = true;\n    private _shOrder4: boolean = true;\n\n    // Per-part state (only populated when partCount > 0)\n    private _partCount: number = 0;\n    private _partClippingBoxes: Array<Nullable<{ min: Vector3; max: Vector3 }>> = [];\n    private _partOpacityCullings: Array<Nullable<{ min: number; max: number }>> = [];\n    private _partSizeCullings: Array<Nullable<{ min: number; max: number }>> = [];\n    private _partOpacityScales: Array<Nullable<number>> = [];\n    private _partOpacitySaturates: Array<Nullable<boolean>> = [];\n    private _partShDcs: Array<Nullable<boolean>> = [];\n    private _partShOrder1s: Array<Nullable<boolean>> = [];\n    private _partShOrder2s: Array<Nullable<boolean>> = [];\n    private _partShOrder3s: Array<Nullable<boolean>> = [];\n    private _partShOrder4s: Array<Nullable<boolean>> = [];\n    // Single registry of every _part* array — shiftPartOptions iterates this instead of\n    // listing each array by name, so adding a new per-part field only requires adding it here.\n    private readonly _partArrays: Array<Array<unknown>>;\n\n    // Per-part debug LUT: MAX_PART_COUNT × 5 RGBA float texture (dbgPartData)\n    private _dbgPartDataTexture: Nullable<RawTexture> = null;\n    private _textureDirty: boolean = false;\n    private _maxPartCount: number = 0;\n\n    /**\n     * Creates a new GaussianSplattingDebugMaterialPlugin.\n     * @param material The GaussianSplattingMaterial to attach the plugin to.\n     */\n    constructor(material: GaussianSplattingMaterial) {\n        super(material, \"GaussianSplattingDebug\", 200, new GaussianSplattingDebugDefines(), true, true);\n        this._partArrays = [\n            this._partClippingBoxes,\n            this._partOpacityCullings,\n            this._partSizeCullings,\n            this._partOpacityScales,\n            this._partOpacitySaturates,\n            this._partShDcs,\n            this._partShOrder1s,\n            this._partShOrder2s,\n            this._partShOrder3s,\n            this._partShOrder4s,\n        ];\n    }\n\n    private _isAnyFeatureActive(): boolean {\n        return (\n            this._clippingBox !== null ||\n            this._opacityCulling !== null ||\n            this._sizeCulling !== null ||\n            this._opacityScale !== 1.0 ||\n            this._opacitySaturate ||\n            !this._shDc ||\n            !this._shOrder1 ||\n            !this._shOrder2 ||\n            !this._shOrder3 ||\n            !this._shOrder4 ||\n            this._partClippingBoxes.some((b) => b !== null) ||\n            this._partOpacityCullings.some((b) => b !== null) ||\n            this._partSizeCullings.some((b) => b !== null) ||\n            this._partOpacityScales.some((s) => s !== null) ||\n            this._partOpacitySaturates.some((s) => s !== null) ||\n            this._partShDcs.some((s) => s !== null) ||\n            this._partShOrder1s.some((s) => s !== null) ||\n            this._partShOrder2s.some((s) => s !== null) ||\n            this._partShOrder3s.some((s) => s !== null) ||\n            this._partShOrder4s.some((s) => s !== null)\n        );\n    }\n\n    private _markDirty(): void {\n        this.markAllDefinesAsDirty();\n        this._textureDirty = true;\n    }\n\n    // ----- Public API -----\n\n    /**\n     * Number of parts in compound mode. Set automatically by GaussianSplattingDebugger.addMesh().\n     * When 0 (non-compound), setPartOptions() logs an error.\n     * @returns the part count\n     */\n    public get partCount(): number {\n        return this._partCount;\n    }\n    public set partCount(count: number) {\n        if (this._partCount !== count) {\n            this._partCount = count;\n            this._markDirty();\n        }\n    }\n\n    /**\n     * Sets per-part debug overrides for the given part index.\n     * Only valid on compound meshes (partCount \\> 0); logs an error otherwise.\n     * @param partIndex The zero-based part index.\n     * @param options Partial set of debug options to override for this part.\n     */\n    public setPartOptions(partIndex: number, options: Partial<IGaussianSplattingDebugOptions>): void {\n        if (this._partCount === 0) {\n            Logger.Error(\"GaussianSplattingDebugMaterialPlugin.setPartOptions: called on a non-compound mesh. partCount is 0.\");\n            return;\n        }\n        if (options.clippingBox !== undefined) {\n            this._partClippingBoxes[partIndex] = options.clippingBox;\n        }\n        if (options.opacityCulling !== undefined) {\n            this._partOpacityCullings[partIndex] = options.opacityCulling;\n        }\n        if (options.sizeCulling !== undefined) {\n            this._partSizeCullings[partIndex] = options.sizeCulling;\n        }\n        if (options.opacityScale !== undefined) {\n            this._partOpacityScales[partIndex] = options.opacityScale;\n        }\n        if (options.opacitySaturate !== undefined) {\n            this._partOpacitySaturates[partIndex] = options.opacitySaturate;\n        }\n        if (options.shDc !== undefined) {\n            this._partShDcs[partIndex] = options.shDc;\n        }\n        if (options.shOrder1 !== undefined) {\n            this._partShOrder1s[partIndex] = options.shOrder1;\n        }\n        if (options.shOrder2 !== undefined) {\n            this._partShOrder2s[partIndex] = options.shOrder2;\n        }\n        if (options.shOrder3 !== undefined) {\n            this._partShOrder3s[partIndex] = options.shOrder3;\n        }\n        if (options.shOrder4 !== undefined) {\n            this._partShOrder4s[partIndex] = options.shOrder4;\n        }\n        this._markDirty();\n    }\n\n    /**\n     * Clears all per-part debug overrides for the given part index,\n     * falling back to global settings.\n     * @param partIndex The zero-based part index.\n     */\n    public clearPartOptions(partIndex: number): void {\n        this._partClippingBoxes[partIndex] = null;\n        this._partOpacityCullings[partIndex] = null;\n        this._partSizeCullings[partIndex] = null;\n        this._partOpacityScales[partIndex] = null;\n        this._partOpacitySaturates[partIndex] = null;\n        this._partShDcs[partIndex] = null;\n        this._partShOrder1s[partIndex] = null;\n        this._partShOrder2s[partIndex] = null;\n        this._partShOrder3s[partIndex] = null;\n        this._partShOrder4s[partIndex] = null;\n        this._markDirty();\n    }\n\n    /**\n     * Removes the per-part override slot at `removedIndex` and shifts all higher-indexed\n     * slots down by one, keeping the arrays aligned with the compound mesh's new part layout.\n     * @param removedIndex The original (pre-removal) part index.\n     * @internal\n     */\n    public shiftPartOptions(removedIndex: number): void {\n        for (const arr of this._partArrays) {\n            if (removedIndex < arr.length) {\n                arr.splice(removedIndex, 1);\n            }\n        }\n        this._markDirty();\n    }\n\n    /**\n     * World-space axis-aligned clipping box. Splats outside are not rendered.\n     * Set to null to disable clipping.\n     * Example: `{ min: new Vector3(-2,-2,-2), max: new Vector3(2,2,2) }`\n     */\n    public get clippingBox(): Nullable<{ min: Vector3; max: Vector3 }> {\n        return this._clippingBox;\n    }\n    public set clippingBox(value: Nullable<{ min: Vector3; max: Vector3 }>) {\n        this._clippingBox = value;\n        this._markDirty();\n    }\n\n    /**\n     * Opacity culling range [0..1]. Splats whose stored opacity falls outside this\n     * range are not rendered. Set to null to disable.\n     */\n    public get opacityCulling(): Nullable<{ min: number; max: number }> {\n        return this._opacityCulling;\n    }\n    public set opacityCulling(value: Nullable<{ min: number; max: number }>) {\n        this._opacityCulling = value;\n        this._markDirty();\n    }\n\n    /**\n     * Size culling range. Size is pow(|det(Σ)|, 1/6) of the 3D covariance matrix,\n     * equal to the geometric mean of the principal radii. Use GaussianSplattingMeshBase.splatSizeRange\n     * to find the asset's range. Set to null to disable.\n     */\n    public get sizeCulling(): Nullable<{ min: number; max: number }> {\n        return this._sizeCulling;\n    }\n    public set sizeCulling(value: Nullable<{ min: number; max: number }>) {\n        this._sizeCulling = value;\n        this._markDirty();\n    }\n\n    /**\n     * Scalar multiplier applied to every splat's opacity after all other modifiers.\n     * 1.0 (default) = no change.\n     */\n    public get opacityScale(): number {\n        return this._opacityScale;\n    }\n    public set opacityScale(value: number) {\n        this._opacityScale = value;\n        this._markDirty();\n    }\n\n    /**\n     * When true, replaces the Gaussian spatial falloff with a flat uniform opacity,\n     * making each splat appear as a solid disk with its raw alpha value.\n     */\n    public get opacitySaturate(): boolean {\n        return this._opacitySaturate;\n    }\n    public set opacitySaturate(value: boolean) {\n        this._opacitySaturate = value;\n        this._markDirty();\n    }\n\n    /** Include the DC (base) color from colorsTexture. Default: true. */\n    public get shDc(): boolean {\n        return this._shDc;\n    }\n    public set shDc(value: boolean) {\n        this._shDc = value;\n        this._markDirty();\n    }\n\n    /** Include SH band 1 contribution. Default: true. */\n    public get shOrder1(): boolean {\n        return this._shOrder1;\n    }\n    public set shOrder1(value: boolean) {\n        this._shOrder1 = value;\n        this._markDirty();\n    }\n\n    /** Include SH band 2 contribution. Default: true. */\n    public get shOrder2(): boolean {\n        return this._shOrder2;\n    }\n    public set shOrder2(value: boolean) {\n        this._shOrder2 = value;\n        this._markDirty();\n    }\n\n    /** Include SH band 3 contribution. Default: true. */\n    public get shOrder3(): boolean {\n        return this._shOrder3;\n    }\n    public set shOrder3(value: boolean) {\n        this._shOrder3 = value;\n        this._markDirty();\n    }\n\n    /** Include SH band 4 contribution. Default: true. */\n    public get shOrder4(): boolean {\n        return this._shOrder4;\n    }\n    public set shOrder4(value: boolean) {\n        this._shOrder4 = value;\n        this._markDirty();\n    }\n\n    // ----- Plugin overrides -----\n\n    /**\n     * Adds the per-part debug data texture name to the sampler list so the effect can bind it.\n     * @param samplers the sampler list to populate\n     */\n    public override getSamplers(samplers: string[]): void {\n        samplers.push(\"dbgPartData\");\n    }\n\n    /** @returns the class name of this plugin */\n    public override getClassName(): string {\n        return \"GaussianSplattingDebugMaterialPlugin\";\n    }\n\n    /**\n     * @param shaderLanguage the shader language to check\n     * @returns true for GLSL and WGSL\n     */\n    public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\n        switch (shaderLanguage) {\n            case ShaderLanguage.GLSL:\n            case ShaderLanguage.WGSL:\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    /**\n     * Always ready — no async resources.\n     * @param _defines unused\n     * @param _scene unused\n     * @param _engine unused\n     * @param _subMesh unused\n     * @returns true\n     */\n    public override isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\n        return true;\n    }\n\n    /**\n     * Sets shader defines from current property state. GS_DBG_ENABLED is set to true\n     * only when at least one feature is non-default, ensuring zero overhead otherwise.\n     * Sub-flags also check per-part arrays so compound-only overrides activate the correct\n     * code paths even when the global setting is at its default.\n     * @param defines the defines object\n     */\n    public override prepareDefines(defines: GaussianSplattingDebugDefines): void {\n        defines.GS_DBG_ENABLED = this._isAnyFeatureActive();\n        defines.GS_DBG_CLIP = this._clippingBox !== null || this._partClippingBoxes.some((b) => b !== null) ? 1 : 0;\n        defines.GS_DBG_CULL_OPACITY = this._opacityCulling !== null || this._partOpacityCullings.some((b) => b !== null) ? 1 : 0;\n        defines.GS_DBG_CULL_SIZE = this._sizeCulling !== null || this._partSizeCullings.some((b) => b !== null) ? 1 : 0;\n        defines.GS_DBG_OPACITY_SCALE = this._opacityScale !== 1.0 || this._partOpacityScales.some((s) => s !== null) ? 1 : 0;\n        defines.GS_DBG_OPACITY_SATURATE = this._opacitySaturate || this._partOpacitySaturates.some((s) => s !== null) ? 1 : 0;\n        defines.GS_DBG_SH_DC = !this._shDc || this._partShDcs.some((s) => s !== null) ? 0 : 1;\n        defines.GS_DBG_SH_ORDER1 = !this._shOrder1 || this._partShOrder1s.some((s) => s !== null) ? 0 : 1;\n        defines.GS_DBG_SH_ORDER2 = !this._shOrder2 || this._partShOrder2s.some((s) => s !== null) ? 0 : 1;\n        defines.GS_DBG_SH_ORDER3 = !this._shOrder3 || this._partShOrder3s.some((s) => s !== null) ? 0 : 1;\n        defines.GS_DBG_SH_ORDER4 = !this._shOrder4 || this._partShOrder4s.some((s) => s !== null) ? 0 : 1;\n    }\n\n    /**\n     * Returns shader code injections for the debug features.\n     * @param shaderType \"vertex\" or \"fragment\"\n     * @param shaderLanguage GLSL or WGSL\n     * @returns map of injection-point name to injected code, or null\n     */\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\n        if (shaderLanguage === ShaderLanguage.WGSL) {\n            return this._getCustomCodeWGSL(shaderType);\n        }\n        return this._getCustomCodeGLSL(shaderType);\n    }\n\n    private _getCustomCodeGLSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\n        if (shaderType === \"vertex\") {\n            return {\n                CUSTOM_VERTEX_DEFINITIONS: `\n#if defined(GS_DBG_ENABLED) && GS_DBG_CLIP == 1 && !defined(IS_COMPOUND)\nuniform vec3 dbgClipMin;\nuniform vec3 dbgClipMax;\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_OPACITY == 1 && !defined(IS_COMPOUND)\nuniform float dbgMinOpacity;\nuniform float dbgMaxOpacity;\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_SIZE == 1 && !defined(IS_COMPOUND)\nuniform float dbgMinSize;\nuniform float dbgMaxSize;\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_OPACITY_SCALE == 1 && !defined(IS_COMPOUND)\nuniform float dbgOpacityScale;\n#endif\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\nuniform sampler2D dbgPartData;\n${GetPartIndexVaryingDeclaration(ShaderLanguage.GLSL)}\n#endif\n`,\n                CUSTOM_VERTEX_UPDATE: `\n#if defined(GS_DBG_ENABLED) && GS_DBG_CLIP == 1 && !defined(IS_COMPOUND)\n    if (worldPos.x < dbgClipMin.x || worldPos.x > dbgClipMax.x ||\n        worldPos.y < dbgClipMin.y || worldPos.y > dbgClipMax.y ||\n        worldPos.z < dbgClipMin.z || worldPos.z > dbgClipMax.z) {\n        scale = vec2(0.0);\n    }\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_OPACITY == 1 && !defined(IS_COMPOUND)\n    if (splat.color.w < dbgMinOpacity || splat.color.w > dbgMaxOpacity) {\n        scale = vec2(0.0);\n    }\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_SIZE == 1 && !defined(IS_COMPOUND)\n    {\n        float _d0 = splat.covA.x; float _d1 = splat.covA.y; float _d2 = splat.covA.z;\n        float _d3 = splat.covA.w; float _d4 = splat.covB.x; float _d5 = splat.covB.y;\n        float _det = _d0*(_d3*_d5 - _d4*_d4) - _d1*(_d1*_d5 - _d4*_d2) + _d2*(_d1*_d4 - _d3*_d2);\n        float _sz = pow(abs(_det), 1.0/6.0);\n        if (_sz < dbgMinSize || _sz > dbgMaxSize) {\n            scale = vec2(0.0);\n        }\n    }\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_OPACITY_SCALE == 1 && !defined(IS_COMPOUND)\n    vColor.w *= dbgOpacityScale;\n#endif\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n    {\n        int _pIdx = int(splat.partIndex);\n        vPartIndex = float(splat.partIndex);\n        vec4 _row0 = texelFetch(dbgPartData, ivec2(_pIdx, 0), 0);\n        vec4 _row1 = texelFetch(dbgPartData, ivec2(_pIdx, 1), 0);\n        vec4 _row2 = texelFetch(dbgPartData, ivec2(_pIdx, 2), 0);\n        vec3 _clipMin = _row0.xyz;\n        vec3 _clipMax = vec3(_row0.w, _row1.xy);\n        float _minOp = _row1.z;\n        float _maxOp = _row1.w;\n        float _minSz = _row2.x;\n        float _maxSz = _row2.y;\n        float _opSc  = _row2.z;\n        #if GS_DBG_CLIP == 1\n        if (worldPos.x < _clipMin.x || worldPos.x > _clipMax.x ||\n            worldPos.y < _clipMin.y || worldPos.y > _clipMax.y ||\n            worldPos.z < _clipMin.z || worldPos.z > _clipMax.z) {\n            scale = vec2(0.0);\n        }\n        #endif\n        #if GS_DBG_CULL_OPACITY == 1\n        if (splat.color.w < _minOp || splat.color.w > _maxOp) {\n            scale = vec2(0.0);\n        }\n        #endif\n        #if GS_DBG_CULL_SIZE == 1\n        {\n            float _d0 = splat.covA.x; float _d1 = splat.covA.y; float _d2 = splat.covA.z;\n            float _d3 = splat.covA.w; float _d4 = splat.covB.x; float _d5 = splat.covB.y;\n            float _det = _d0*(_d3*_d5 - _d4*_d4) - _d1*(_d1*_d5 - _d4*_d2) + _d2*(_d1*_d4 - _d3*_d2);\n            float _sz = pow(abs(_det), 1.0/6.0);\n            if (_sz < _minSz || _sz > _maxSz) {\n                scale = vec2(0.0);\n            }\n        }\n        #endif\n        #if GS_DBG_OPACITY_SCALE == 1\n        vColor.w *= _opSc;\n        #endif\n    }\n#endif\n`,\n            };\n        } else if (shaderType === \"fragment\") {\n            return {\n                CUSTOM_FRAGMENT_DEFINITIONS: `\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\nuniform sampler2D dbgPartData;\n${GetPartIndexVaryingDeclaration(ShaderLanguage.GLSL)}\n#endif\n`,\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n    if (texelFetch(dbgPartData, ivec2(int(vPartIndex + 0.5), 2), 0).w > 0.5) { finalColor.a = vColor.a; }\n#elif defined(GS_DBG_ENABLED) && GS_DBG_OPACITY_SATURATE == 1\n    finalColor.a = vColor.a;\n#endif\n`,\n            };\n        }\n        return null;\n    }\n\n    private _getCustomCodeWGSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\n        if (shaderType === \"vertex\") {\n            return {\n                CUSTOM_VERTEX_DEFINITIONS: `\n#if defined(GS_DBG_ENABLED) && GS_DBG_CLIP == 1 && !defined(IS_COMPOUND)\nuniform dbgClipMin: vec3f;\nuniform dbgClipMax: vec3f;\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_OPACITY == 1 && !defined(IS_COMPOUND)\nuniform dbgMinOpacity: f32;\nuniform dbgMaxOpacity: f32;\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_SIZE == 1 && !defined(IS_COMPOUND)\nuniform dbgMinSize: f32;\nuniform dbgMaxSize: f32;\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_OPACITY_SCALE == 1 && !defined(IS_COMPOUND)\nuniform dbgOpacityScale: f32;\n#endif\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\nvar dbgPartData: texture_2d<f32>;\n${GetPartIndexVaryingDeclaration(ShaderLanguage.WGSL)}\n#endif\n`,\n                CUSTOM_VERTEX_UPDATE: `\n#if defined(GS_DBG_ENABLED) && GS_DBG_CLIP == 1 && !defined(IS_COMPOUND)\n    if (worldPos.x < uniforms.dbgClipMin.x || worldPos.x > uniforms.dbgClipMax.x ||\n        worldPos.y < uniforms.dbgClipMin.y || worldPos.y > uniforms.dbgClipMax.y ||\n        worldPos.z < uniforms.dbgClipMin.z || worldPos.z > uniforms.dbgClipMax.z) {\n        scale = vec2f(0.0);\n    }\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_OPACITY == 1 && !defined(IS_COMPOUND)\n    if (splat.color.w < uniforms.dbgMinOpacity || splat.color.w > uniforms.dbgMaxOpacity) {\n        scale = vec2f(0.0);\n    }\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_CULL_SIZE == 1 && !defined(IS_COMPOUND)\n    {\n        let _d0 = splat.covA.x; let _d1 = splat.covA.y; let _d2 = splat.covA.z;\n        let _d3 = splat.covA.w; let _d4 = splat.covB.x; let _d5 = splat.covB.y;\n        let _det = _d0*(_d3*_d5 - _d4*_d4) - _d1*(_d1*_d5 - _d4*_d2) + _d2*(_d1*_d4 - _d3*_d2);\n        let _sz = pow(abs(_det), 1.0/6.0);\n        if (_sz < uniforms.dbgMinSize || _sz > uniforms.dbgMaxSize) {\n            scale = vec2f(0.0);\n        }\n    }\n#endif\n#if defined(GS_DBG_ENABLED) && GS_DBG_OPACITY_SCALE == 1 && !defined(IS_COMPOUND)\n    vertexOutputs.vColor.w *= uniforms.dbgOpacityScale;\n#endif\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n    {\n        let _pIdx = i32(splat.partIndex);\n        vertexOutputs.vPartIndex = f32(splat.partIndex);\n        let _row0 = textureLoad(dbgPartData, vec2i(_pIdx, 0), 0);\n        let _row1 = textureLoad(dbgPartData, vec2i(_pIdx, 1), 0);\n        let _row2 = textureLoad(dbgPartData, vec2i(_pIdx, 2), 0);\n        let _clipMin = _row0.xyz;\n        let _clipMax = vec3f(_row0.w, _row1.xy);\n        let _minOp = _row1.z;\n        let _maxOp = _row1.w;\n        let _minSz = _row2.x;\n        let _maxSz = _row2.y;\n        let _opSc  = _row2.z;\n        #if GS_DBG_CLIP == 1\n        if (worldPos.x < _clipMin.x || worldPos.x > _clipMax.x ||\n            worldPos.y < _clipMin.y || worldPos.y > _clipMax.y ||\n            worldPos.z < _clipMin.z || worldPos.z > _clipMax.z) {\n            scale = vec2f(0.0);\n        }\n        #endif\n        #if GS_DBG_CULL_OPACITY == 1\n        if (splat.color.w < _minOp || splat.color.w > _maxOp) {\n            scale = vec2f(0.0);\n        }\n        #endif\n        #if GS_DBG_CULL_SIZE == 1\n        {\n            let _d0 = splat.covA.x; let _d1 = splat.covA.y; let _d2 = splat.covA.z;\n            let _d3 = splat.covA.w; let _d4 = splat.covB.x; let _d5 = splat.covB.y;\n            let _det = _d0*(_d3*_d5 - _d4*_d4) - _d1*(_d1*_d5 - _d4*_d2) + _d2*(_d1*_d4 - _d3*_d2);\n            let _sz = pow(abs(_det), 1.0/6.0);\n            if (_sz < _minSz || _sz > _maxSz) {\n                scale = vec2f(0.0);\n            }\n        }\n        #endif\n        #if GS_DBG_OPACITY_SCALE == 1\n        vertexOutputs.vColor.w *= _opSc;\n        #endif\n    }\n#endif\n`,\n            };\n        } else if (shaderType === \"fragment\") {\n            return {\n                CUSTOM_FRAGMENT_DEFINITIONS: `\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\nvar dbgPartData: texture_2d<f32>;\n${GetPartIndexVaryingDeclaration(ShaderLanguage.WGSL)}\n#endif\n`,\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n    if (textureLoad(dbgPartData, vec2i(i32(fragmentInputs.vPartIndex + 0.5), 2), 0).w > 0.5) {\n        let _gsdbgA: f32 = -dot(fragmentInputs.vPosition, fragmentInputs.vPosition);\n        if (_gsdbgA > -4.0) { finalColor.a = fragmentInputs.vColor.a; }\n    }\n#elif defined(GS_DBG_ENABLED) && GS_DBG_OPACITY_SATURATE == 1\n    {\n        let _gsdbgA: f32 = -dot(fragmentInputs.vPosition, fragmentInputs.vPosition);\n        if (_gsdbgA > -4.0) {\n            finalColor.a = fragmentInputs.vColor.a;\n        }\n    }\n#endif\n`,\n            };\n        }\n        return null;\n    }\n\n    /**\n     * Declares the non-compound scalar debug uniform names as external so the Effect can\n     * resolve their locations. WGSL uniforms are declared inline in getCustomCode() injections.\n     * @returns uniform descriptor with externalUniforms list\n     */\n    public override getUniforms(): {\n        ubo?: Array<{ name: string; size?: number; type?: string; arraySize?: number }>;\n        vertex?: string;\n        fragment?: string;\n        externalUniforms?: string[];\n    } {\n        return {\n            externalUniforms: [\"dbgClipMin\", \"dbgClipMax\", \"dbgMinOpacity\", \"dbgMaxOpacity\", \"dbgMinSize\", \"dbgMaxSize\", \"dbgOpacityScale\"],\n        };\n    }\n\n    private _buildTextureData(partCount: number): Float32Array {\n        const maxPartCount = this._maxPartCount;\n        const data = new Float32Array(maxPartCount * 5 * 4);\n        for (let i = 0; i < maxPartCount; i++) {\n            const r0 = i * 4;\n            const r1 = (maxPartCount + i) * 4;\n            const r2 = (maxPartCount * 2 + i) * 4;\n            const r3 = (maxPartCount * 3 + i) * 4;\n            const r4 = (maxPartCount * 4 + i) * 4;\n\n            // Row 0: clipMin.xyz, clipMax.x  — Row 1: clipMax.yz, minOpacity, maxOpacity\n            const box = i < partCount ? (this._partClippingBoxes[i] ?? this._clippingBox) : this._clippingBox;\n            if (box) {\n                data[r0] = box.min.x;\n                data[r0 + 1] = box.min.y;\n                data[r0 + 2] = box.min.z;\n                data[r0 + 3] = box.max.x;\n                data[r1] = box.max.y;\n                data[r1 + 1] = box.max.z;\n            } else {\n                data[r0] = -1e9;\n                data[r0 + 1] = -1e9;\n                data[r0 + 2] = -1e9;\n                data[r0 + 3] = 1e9;\n                data[r1] = 1e9;\n                data[r1 + 1] = 1e9;\n            }\n            const opCull = i < partCount ? (this._partOpacityCullings[i] ?? this._opacityCulling) : this._opacityCulling;\n            data[r1 + 2] = opCull ? opCull.min : 0.0;\n            data[r1 + 3] = opCull ? opCull.max : 1.0;\n\n            // Row 2: minSize, maxSize, opacityScale, opacitySaturate\n            const szCull = i < partCount ? (this._partSizeCullings[i] ?? this._sizeCulling) : this._sizeCulling;\n            data[r2] = szCull ? szCull.min : 0.0;\n            data[r2 + 1] = szCull ? szCull.max : 1e9;\n            data[r2 + 2] = i < partCount ? (this._partOpacityScales[i] ?? this._opacityScale) : this._opacityScale;\n            const sat = i < partCount ? (this._partOpacitySaturates[i] ?? this._opacitySaturate) : this._opacitySaturate;\n            data[r2 + 3] = sat ? 1.0 : 0.0;\n\n            // Row 3: shDc, shOrder1, shOrder2, shOrder3\n            data[r3] = (i < partCount ? (this._partShDcs[i] ?? this._shDc) : this._shDc) ? 1.0 : 0.0;\n            data[r3 + 1] = (i < partCount ? (this._partShOrder1s[i] ?? this._shOrder1) : this._shOrder1) ? 1.0 : 0.0;\n            data[r3 + 2] = (i < partCount ? (this._partShOrder2s[i] ?? this._shOrder2) : this._shOrder2) ? 1.0 : 0.0;\n            data[r3 + 3] = (i < partCount ? (this._partShOrder3s[i] ?? this._shOrder3) : this._shOrder3) ? 1.0 : 0.0;\n\n            // Row 4: shOrder4, padding\n            data[r4] = (i < partCount ? (this._partShOrder4s[i] ?? this._shOrder4) : this._shOrder4) ? 1.0 : 0.0;\n        }\n        return data;\n    }\n\n    private _updateOrCreateTexture(scene: Scene): void {\n        if (!this._maxPartCount) {\n            this._maxPartCount = GetGaussianSplattingMaxPartCount(scene.getEngine());\n        }\n        const data = this._buildTextureData(this._partCount);\n        if (!this._dbgPartDataTexture) {\n            this._dbgPartDataTexture = RawTexture.CreateRGBATexture(\n                data,\n                this._maxPartCount,\n                5,\n                scene,\n                false,\n                false,\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n                Constants.TEXTURETYPE_FLOAT\n            );\n        } else {\n            this._dbgPartDataTexture.update(data);\n        }\n        this._textureDirty = false;\n    }\n\n    /**\n     * Binds uniform values each frame. Scalar uniforms are uploaded for non-compound mode;\n     * the per-part data texture is updated and bound for compound mode.\n     * @param _uniformBuffer unused\n     * @param _scene the current scene\n     * @param _engine unused\n     * @param subMesh the submesh being rendered\n     */\n    public override bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void {\n        const effect = subMesh.effect;\n        if (!effect) {\n            return;\n        }\n\n        if (this._partCount > 0 && this._isAnyFeatureActive()) {\n            // Compound mode: pack per-part data into a texture (only when the debug path is active)\n            if (this._textureDirty || !this._dbgPartDataTexture) {\n                this._updateOrCreateTexture(_scene);\n            }\n            if (this._dbgPartDataTexture) {\n                effect.setTexture(\"dbgPartData\", this._dbgPartDataTexture);\n            }\n        } else if (this._partCount === 0) {\n            // Non-compound: upload scalar uniforms\n            if (this._clippingBox) {\n                effect.setVector3(\"dbgClipMin\", this._clippingBox.min);\n                effect.setVector3(\"dbgClipMax\", this._clippingBox.max);\n            }\n            if (this._opacityCulling) {\n                effect.setFloat(\"dbgMinOpacity\", this._opacityCulling.min);\n                effect.setFloat(\"dbgMaxOpacity\", this._opacityCulling.max);\n            }\n            if (this._sizeCulling) {\n                effect.setFloat(\"dbgMinSize\", this._sizeCulling.min);\n                effect.setFloat(\"dbgMaxSize\", this._sizeCulling.max);\n            }\n            if (this._opacityScale !== 1.0) {\n                effect.setFloat(\"dbgOpacityScale\", this._opacityScale);\n            }\n        }\n    }\n\n    /**\n     * Disposes the per-part data texture.\n     * @param _forceDisposeTextures unused; the LUT texture is always disposed as it is owned by this plugin\n     */\n    public override dispose(_forceDisposeTextures?: boolean): void {\n        this._dbgPartDataTexture?.dispose();\n        this._dbgPartDataTexture = null;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for GaussianSplattingDebugMaterialPlugin.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterGaussianSplattingDebugMaterialPlugin(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(\"BABYLON.GaussianSplattingDebugMaterialPlugin\", GaussianSplattingDebugMaterialPlugin);\n}\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./decalFragmentDeclaration\";\nconst name = \"defaultFragmentDeclaration\";\nconst shader = `uniform vec4 vEyePosition;uniform vec4 vDiffuseColor;uniform vec4 vSpecularColor;uniform vec3 vEmissiveColor;uniform vec3 vAmbientColor;uniform float visibility;\n#ifdef DIFFUSE\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform vec2 vAmbientInfos;\n#endif\n#ifdef OPACITY \nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;uniform vec2 vTangentSpaceParams;\n#endif\n#ifdef ALPHATEST\nuniform float alphaCutOff;\n#endif\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(REFRACTION) || defined(PREPASS)\nuniform mat4 view;\n#endif\n#ifdef REFRACTION\nuniform vec4 vRefractionInfos;\n#ifndef REFRACTIONMAP_3D\nuniform mat4 refractionMatrix;\n#endif\n#ifdef REFRACTIONFRESNEL\nuniform vec4 refractionLeftColor;uniform vec4 refractionRightColor;\n#endif\n#if defined(USE_LOCAL_REFRACTIONMAP_CUBIC) && defined(REFRACTIONMAP_3D)\nuniform vec3 vRefractionPosition;uniform vec3 vRefractionSize; \n#endif\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;\n#endif\n#ifdef DIFFUSEFRESNEL\nuniform vec4 diffuseLeftColor;uniform vec4 diffuseRightColor;\n#endif\n#ifdef OPACITYFRESNEL\nuniform vec4 opacityParts;\n#endif\n#ifdef EMISSIVEFRESNEL\nuniform vec4 emissiveLeftColor;uniform vec4 emissiveRightColor;\n#endif\n#if defined(REFLECTION) || (defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED))\nuniform vec2 vReflectionInfos;\n#if defined(REFLECTIONMAP_PLANAR) || defined(REFLECTIONMAP_CUBIC) || defined(REFLECTIONMAP_PROJECTION) || defined(REFLECTIONMAP_EQUIRECTANGULAR) || defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_SKYBOX)\nuniform mat4 reflectionMatrix;\n#endif\n#ifndef REFLECTIONMAP_SKYBOX\n#if defined(USE_LOCAL_REFLECTIONMAP_CUBIC) && defined(REFLECTIONMAP_CUBIC)\nuniform vec3 vReflectionPosition;uniform vec3 vReflectionSize; \n#endif\n#endif\n#ifdef REFLECTIONFRESNEL\nuniform vec4 reflectionLeftColor;uniform vec4 reflectionRightColor;\n#endif\n#endif\n#ifdef DETAIL\nuniform vec4 vDetailInfos;\n#endif\n#include<decalFragmentDeclaration>\n#if TEXTURE_REPETITION_MODE>0\nuniform vec4 vTextureRepetitionHexTilingParams;\n#endif\n#define ADDITIONAL_FRAGMENT_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const defaultFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"defaultUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;uniform Material\n{vec4 diffuseLeftColor;vec4 diffuseRightColor;vec4 opacityParts;vec4 reflectionLeftColor;vec4 reflectionRightColor;vec4 refractionLeftColor;vec4 refractionRightColor;vec4 emissiveLeftColor;vec4 emissiveRightColor;vec2 vDiffuseInfos;vec2 vAmbientInfos;vec2 vOpacityInfos;vec2 vEmissiveInfos;vec2 vLightmapInfos;vec2 vSpecularInfos;vec3 vBumpInfos;mat4 diffuseMatrix;mat4 ambientMatrix;mat4 opacityMatrix;mat4 emissiveMatrix;mat4 lightmapMatrix;mat4 specularMatrix;mat4 bumpMatrix;vec2 vTangentSpaceParams;float pointSize;float alphaCutOff;mat4 refractionMatrix;vec4 vRefractionInfos;vec3 vRefractionPosition;vec3 vRefractionSize;vec4 vSpecularColor;vec3 vEmissiveColor;vec4 vDiffuseColor;vec3 vAmbientColor;vec4 cameraInfo;vec4 vTextureRepetitionHexTilingParams;vec2 vReflectionInfos;mat4 reflectionMatrix;vec3 vReflectionPosition;vec3 vReflectionSize;\n#define ADDITIONAL_UBO_DECLARATION\n};\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const defaultUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fresnelFunction\";\nconst shader = `#ifdef FRESNEL\nfloat computeFresnelTerm(vec3 viewDirection,vec3 worldNormal,float bias,float power)\n{float fresnelTerm=pow(bias+abs(dot(viewDirection,worldNormal)),power);return clamp(fresnelTerm,0.,1.);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const fresnelFunction = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"defaultFragmentAlpha\";\nconst shader = `#ifdef OPACITY\nvec4 opacityMap=TEXRD(opacitySampler,vOpacityUV+uvOffset);\n#ifdef OPACITYRGB\nopacityMap.rgb=opacityMap.rgb*vec3(0.3,0.59,0.11);alpha*=(opacityMap.x+opacityMap.y+opacityMap.z)* vOpacityInfos.y;\n#else\nalpha*=opacityMap.a*vOpacityInfos.y;\n#endif\n#endif\n#if defined(VERTEXALPHA) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nalpha*=vColor.a;\n#endif\n#ifdef OPACITYFRESNEL\nfloat opacityFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,opacityParts.z,opacityParts.w);alpha+=opacityParts.x*(1.0-opacityFresnelTerm)+opacityFresnelTerm*opacityParts.y;\n#endif\n#ifdef ALPHATEST\n#ifdef ALPHATEST_AFTERALLALPHACOMPUTATIONS\nif (alpha<alphaCutOff)\ndiscard;\n#endif\n#ifndef ALPHABLEND\nalpha=1.0;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const defaultFragmentAlpha = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { decalFragmentDeclaration } from \"./ShadersInclude/decalFragmentDeclaration\";\nimport { defaultFragmentDeclaration } from \"./ShadersInclude/defaultFragmentDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { defaultUboDeclaration } from \"./ShadersInclude/defaultUboDeclaration\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { oitDeclaration } from \"./ShadersInclude/oitDeclaration\";\nimport { mainUVVaryingDeclaration } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { lightFragmentDeclaration } from \"./ShadersInclude/lightFragmentDeclaration\";\nimport { lightUboDeclaration } from \"./ShadersInclude/lightUboDeclaration\";\nimport { ltcHelperFunctions } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { clusteredLightingFunctions } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { lightsFragmentFunctions } from \"./ShadersInclude/lightsFragmentFunctions\";\nimport { shadowsFragmentFunctions } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { samplerFragmentDeclaration } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { fresnelFunction } from \"./ShadersInclude/fresnelFunction\";\nimport { reflectionFunction } from \"./ShadersInclude/reflectionFunction\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { textureRepetitionFunctions } from \"./ShadersInclude/textureRepetitionFunctions\";\nimport { bumpFragmentMainFunctions } from \"./ShadersInclude/bumpFragmentMainFunctions\";\nimport { bumpFragmentFunctions } from \"./ShadersInclude/bumpFragmentFunctions\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { bumpFragment } from \"./ShadersInclude/bumpFragment\";\nimport { decalFragment } from \"./ShadersInclude/decalFragment\";\nimport { defaultFragmentAlpha } from \"./ShadersInclude/defaultFragmentAlpha\";\nimport { depthPrePass } from \"./ShadersInclude/depthPrePass\";\nimport { lightFragment } from \"./ShadersInclude/lightFragment\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { oitFragment } from \"./ShadersInclude/oitFragment\";\n\nconst name = \"defaultPixelShader\";\nconst shader = `#define CUSTOM_FRAGMENT_EXTENSION\n#include<__decl__defaultFragment>\n#if defined(BUMP) || !defined(NORMAL)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<oitDeclaration>\n#define CUSTOM_FRAGMENT_BEGIN\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vec4 vColor;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying float vViewDepth;\n#endif\n#include<mainUVVaryingDeclaration>[1..7]\n#include<helperFunctions>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DIFFUSE,_VARYINGNAME_,Diffuse,_SAMPLERNAME_,diffuse)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_SAMPLERNAME_,ambient)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_SAMPLERNAME_,opacity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_SAMPLERNAME_,emissive)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_SAMPLERNAME_,lightmap)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_SAMPLERNAME_,decal)\n#ifdef REFRACTION\n#ifdef REFRACTIONMAP_3D\nuniform samplerCube refractionCubeSampler;\n#else\nuniform sampler2D refraction2DSampler;\n#endif\n#endif\n#if defined(SPECULARTERM)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR,_VARYINGNAME_,Specular,_SAMPLERNAME_,specular)\n#endif\n#include<fresnelFunction>\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nuniform samplerCube reflectionCubeSampler;\n#else\nuniform sampler2D reflection2DSampler;\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n#include<imageProcessingDeclaration>\n#include<imageProcessingFunctions>\n#include<textureRepetitionFunctions>\n#include<bumpFragmentMainFunctions>\n#include<bumpFragmentFunctions>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);vec4 baseColor=vec4(1.,1.,1.,1.);vec3 diffuseColor=vDiffuseColor.rgb;float alpha=vDiffuseColor.a;\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=normalize(cross(dFdx(vPositionW),dFdy(vPositionW)))*vEyePosition.w;\n#endif\n#include<bumpFragment>\n#ifdef TWOSIDEDLIGHTING\nnormalW=gl_FrontFacing ? normalW : -normalW;\n#endif\n#ifdef DIFFUSE\nbaseColor=TEXRD(diffuseSampler,vDiffuseUV+uvOffset);\n#if defined(ALPHATEST) && !defined(ALPHATEST_AFTERALLALPHACOMPUTATIONS)\nif (baseColor.a<alphaCutOff)\ndiscard;\n#endif\n#ifdef ALPHAFROMDIFFUSE\nalpha*=baseColor.a;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\nbaseColor.rgb*=vDiffuseInfos.y;\n#endif\n#if defined(DECAL) && !defined(DECAL_AFTER_DETAIL)\nvec4 decalColor=texture2D(decalSampler,vDecalUV+uvOffset);\n#include<decalFragment>(surfaceAlbedo,baseColor,GAMMADECAL,_GAMMADECAL_NOTUSED_)\n#endif\n#ifdef DEPTHPREPASS\n#include<defaultFragmentAlpha>\n#endif\n#include<depthPrePass>\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nbaseColor.rgb*=vColor.rgb;\n#endif\n#ifdef DETAIL\nbaseColor.rgb=baseColor.rgb*2.0*mix(0.5,detailColor.r,vDetailInfos.y);\n#endif\n#if defined(DECAL) && defined(DECAL_AFTER_DETAIL)\nvec4 decalColor=texture2D(decalSampler,vDecalUV+uvOffset);\n#include<decalFragment>(surfaceAlbedo,baseColor,GAMMADECAL,_GAMMADECAL_NOTUSED_)\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE\nvec3 baseAmbientColor=vec3(1.,1.,1.);\n#ifdef AMBIENT\nbaseAmbientColor=TEXRD(ambientSampler,vAmbientUV+uvOffset).rgb*vAmbientInfos.y;\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\nfloat glossiness=vSpecularColor.a;vec3 specularColor=vSpecularColor.rgb;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\nvec4 specularMapColor=TEXRD(specularSampler,vSpecularUV+uvOffset);specularColor=specularMapColor.rgb;\n#ifdef GLOSSINESS\nglossiness=glossiness*specularMapColor.a;\n#endif\n#endif\n#endif\nvec3 diffuseBase=vec3(0.,0.,0.);lightingInfo info;\n#ifdef SPECULARTERM\nvec3 specularBase=vec3(0.,0.,0.);\n#endif\nfloat shadow=1.;float aggShadow=0.;float numLights=0.;\n#ifdef LIGHTMAP\nvec4 lightmapColor=TEXRD(lightmapSampler,vLightmapUV+uvOffset);\n#ifdef RGBDLIGHTMAP\nlightmapColor.rgb=fromRGBD(lightmapColor);\n#endif\nlightmapColor.rgb*=vLightmapInfos.y;\n#endif\n#include<lightFragment>[0..maxSimultaneousLights]\naggShadow=aggShadow/numLights;vec4 refractionColor=vec4(0.,0.,0.,1.);\n#ifdef REFRACTION\nvec3 refractionVector=normalize(refract(-viewDirectionW,normalW,vRefractionInfos.y));\n#ifdef REFRACTIONMAP_3D\n#ifdef USE_LOCAL_REFRACTIONMAP_CUBIC\nrefractionVector=parallaxCorrectNormal(vPositionW,refractionVector,vRefractionSize,vRefractionPosition);\n#endif\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;vec4 refractionLookup=textureCube(refractionCubeSampler,refractionVector);if (dot(refractionVector,viewDirectionW)<1.0) {refractionColor=refractionLookup;}\n#else\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*vRefractionInfos.z,1.0)));vec2 refractionCoords=vRefractionUVW.xy/vRefractionUVW.z;refractionCoords.y=1.0-refractionCoords.y;refractionColor=texture2D(refraction2DSampler,refractionCoords);\n#endif\n#ifdef RGBDREFRACTION\nrefractionColor.rgb=fromRGBD(refractionColor);\n#endif\n#ifdef IS_REFRACTION_LINEAR\nrefractionColor.rgb=toGammaSpace(refractionColor.rgb);\n#endif\nrefractionColor.rgb*=vRefractionInfos.x;\n#endif\nvec4 reflectionColor=vec4(0.,0.,0.,1.);\n#ifdef REFLECTION\nvec3 vReflectionUVW=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nvReflectionUVW.z*=-1.0;\n#endif\n#ifdef REFLECTIONMAP_3D\n#ifdef ROUGHNESS\nfloat bias=vReflectionInfos.y;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\n#ifdef GLOSSINESS\nbias*=(1.0-specularMapColor.a);\n#endif\n#endif\n#endif\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW,bias);\n#else\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW);\n#endif\n#else\nvec2 coords=vReflectionUVW.xy;\n#ifdef REFLECTIONMAP_PROJECTION\ncoords/=vReflectionUVW.z;\n#endif\ncoords.y=1.0-coords.y;reflectionColor=texture2D(reflection2DSampler,coords);\n#endif\n#ifdef RGBDREFLECTION\nreflectionColor.rgb=fromRGBD(reflectionColor);\n#endif\n#ifdef IS_REFLECTION_LINEAR\nreflectionColor.rgb=toGammaSpace(reflectionColor.rgb);\n#endif\nreflectionColor.rgb*=vReflectionInfos.x;\n#ifdef REFLECTIONFRESNEL\nfloat reflectionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,reflectionRightColor.a,reflectionLeftColor.a);\n#ifdef REFLECTIONFRESNELFROMSPECULAR\n#ifdef SPECULARTERM\nreflectionColor.rgb*=specularColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#else\nreflectionColor.rgb*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#else\nreflectionColor.rgb*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#endif\n#endif\n#ifdef REFRACTIONFRESNEL\nfloat refractionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,refractionRightColor.a,refractionLeftColor.a);refractionColor.rgb*=refractionLeftColor.rgb*(1.0-refractionFresnelTerm)+refractionFresnelTerm*refractionRightColor.rgb;\n#endif\n#ifndef DEPTHPREPASS\n#include<defaultFragmentAlpha>\n#endif\nvec3 emissiveColor=vEmissiveColor;\n#ifdef EMISSIVE\nemissiveColor+=TEXRD(emissiveSampler,vEmissiveUV+uvOffset).rgb*vEmissiveInfos.y;\n#endif\n#ifdef EMISSIVEFRESNEL\nfloat emissiveFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,emissiveRightColor.a,emissiveLeftColor.a);emissiveColor*=emissiveLeftColor.rgb*(1.0-emissiveFresnelTerm)+emissiveFresnelTerm*emissiveRightColor.rgb;\n#endif\n#ifdef DIFFUSEFRESNEL\nfloat diffuseFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,diffuseRightColor.a,diffuseLeftColor.a);diffuseBase*=diffuseLeftColor.rgb*(1.0-diffuseFresnelTerm)+diffuseFresnelTerm*diffuseRightColor.rgb;\n#endif\n#ifdef EMISSIVEASILLUMINATION\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\n#ifdef LINKEMISSIVEWITHDIFFUSE\nvec3 finalDiffuse=clamp((diffuseBase+emissiveColor)*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#endif\n#endif\n#ifdef SPECULARTERM\nvec3 finalSpecular=specularBase*specularColor;\n#ifdef SPECULAROVERALPHA\nalpha=clamp(alpha+dot(finalSpecular,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n#else\nvec3 finalSpecular=vec3(0.0);\n#endif\n#ifdef REFLECTIONOVERALPHA\nalpha=clamp(alpha+dot(reflectionColor.rgb,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n#ifdef EMISSIVEASILLUMINATION\nvec4 color=vec4(clamp(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+emissiveColor+refractionColor.rgb,0.0,1.0),alpha);\n#else\nvec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+refractionColor.rgb,alpha);\n#endif\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\ncolor.rgb*=lightmapColor.rgb;\n#else\ncolor.rgb+=lightmapColor.rgb;\n#endif\n#endif\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FOG\ncolor.rgb=max(color.rgb,0.);\n#include<logDepthFragment>\n#include<fogFragment>\n#ifdef IMAGEPROCESSINGPOSTPROCESS\ncolor.rgb=toLinearSpace(color.rgb);\n#else\n#ifdef IMAGEPROCESSING\ncolor.rgb=toLinearSpace(color.rgb);color=applyImageProcessing(color);\n#endif\n#endif\ncolor.a*=visibility;\n#ifdef PREMULTIPLYALPHA\ncolor.rgb*=color.a;\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\n#if SCENE_MRT_COUNT>0\n#ifdef ALPHATEST\nfloat writeGeometryInfo=1.0;\n#else\nfloat writeGeometryInfo=color.a>0.4 ? 1.0 : 0.0;\n#endif\n#ifdef PREPASS_COLOR\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_COLOR_INDEX,color); \n#endif\n#ifdef PREPASS_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_POSITION_INDEX,vec4(vPositionW,writeGeometryInfo));\n#endif\n#ifdef PREPASS_OBJECT_ID\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_OBJECT_ID_INDEX,encodeObjectId(objectId)*writeGeometryInfo);\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nmeshBlendTagOutput=writeGeometryInfo>0.0 ? uvec4(uint(meshBlendTag),0u,0u,0u) : uvec4(0u);\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_LOCAL_POSITION_INDEX,vec4(vPosition,writeGeometryInfo));\n#endif\n#if defined(PREPASS_VELOCITY)\nvec2 a=(vCurrentPosition.xy/vCurrentPosition.w)*0.5+0.5;vec2 b=(vPreviousPosition.xy/vPreviousPosition.w)*0.5+0.5;vec2 velocity=abs(a-b);velocity=vec2(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;WRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_INDEX,vec4(velocity,0.0,writeGeometryInfo));\n#elif defined(PREPASS_VELOCITY_LINEAR)\nvec2 velocity=vec2(0.5)*((vPreviousPosition.xy/vPreviousPosition.w)-(vCurrentPosition.xy/vCurrentPosition.w));WRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_LINEAR_INDEX,vec4(velocity,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_IRRADIANCE\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_IRRADIANCE_INDEX,vec4(0.0,0.0,0.0,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_DEPTH_INDEX,vec4(vViewPos.z,0.0,0.0,writeGeometryInfo)); \n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_SCREENSPACE_DEPTH_INDEX,vec4(gl_FragCoord.z,0.0,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMALIZED_VIEW_DEPTH_INDEX,vec4(vNormViewDepth,0.0,0.0,writeGeometryInfo));\n#endif\n#ifdef PREPASS_NORMAL\n#ifdef PREPASS_NORMAL_WORLDSPACE\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(normalW,writeGeometryInfo));\n#else\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(normalize((view*vec4(normalW,0.0)).rgb),writeGeometryInfo));\n#endif\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_WORLD_NORMAL_INDEX,vec4(normalW*0.5+0.5,writeGeometryInfo));\n#endif\n#ifdef PREPASS_ALBEDO\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_INDEX,vec4(baseColor.rgb,writeGeometryInfo));\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_SQRT_INDEX,vec4(sqrt(baseColor.rgb),writeGeometryInfo));\n#endif\n#ifdef PREPASS_REFLECTIVITY\n#if defined(SPECULAR)\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4(toLinearSpace(specularMapColor))*writeGeometryInfo); \n#else\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4(toLinearSpace(specularColor),1.0)*writeGeometryInfo);\n#endif\n#endif\n#endif\n#endif\n#if !defined(PREPASS) || defined(WEBGL2)\ngl_FragColor=color;\n#endif\n#include<oitFragment>\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {frontColor.rgb+=color.rgb*color.a*alphaMultiplier;frontColor.a=1.0-alphaMultiplier*(1.0-color.a);} else {backColor+=color;}\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [decalFragmentDeclaration, defaultFragmentDeclaration, sceneUboDeclaration, meshUboDeclaration, defaultUboDeclaration, objectIdFunctions, prePassDeclaration, oitDeclaration, mainUVVaryingDeclaration, helperFunctions, lightFragmentDeclaration, lightUboDeclaration, ltcHelperFunctions, clusteredLightingFunctions, lightsFragmentFunctions, shadowsFragmentFunctions, samplerFragmentDeclaration, fresnelFunction, reflectionFunction, imageProcessingDeclaration, imageProcessingFunctions, textureRepetitionFunctions, bumpFragmentMainFunctions, bumpFragmentFunctions, clipPlaneFragmentDeclaration, logDepthDeclaration, fogFragmentDeclaration, clipPlaneFragment, bumpFragment, decalFragment, defaultFragmentAlpha, depthPrePass, lightFragment, logDepthFragment, fogFragment, oitFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const defaultPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./decalVertexDeclaration\";\nconst name = \"defaultVertexDeclaration\";\nconst shader = `uniform mat4 viewProjection;\n#ifdef MULTIVIEW\nmat4 viewProjectionR;\n#endif \nuniform mat4 view;\n#ifdef DIFFUSE\nuniform mat4 diffuseMatrix;uniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform mat4 ambientMatrix;uniform vec2 vAmbientInfos;\n#endif\n#ifdef OPACITY\nuniform mat4 opacityMatrix;uniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;uniform mat4 emissiveMatrix;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;uniform mat4 lightmapMatrix;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;uniform mat4 specularMatrix;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;uniform mat4 bumpMatrix;\n#endif\n#ifdef REFLECTION\nuniform mat4 reflectionMatrix;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n#ifdef DETAIL\nuniform vec4 vDetailInfos;uniform mat4 detailMatrix;\n#endif\nuniform vec4 cameraInfo;uniform vec4 vTextureRepetitionHexTilingParams;\n#include<decalVertexDeclaration>\n#define ADDITIONAL_VERTEX_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const defaultVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pointCloudVertex\";\nconst shader = `#if defined(POINTSIZE) && !defined(WEBGPU)\ngl_PointSize=pointSize;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pointCloudVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { decalVertexDeclaration } from \"./ShadersInclude/decalVertexDeclaration\";\nimport { defaultVertexDeclaration } from \"./ShadersInclude/defaultVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { defaultUboDeclaration } from \"./ShadersInclude/defaultUboDeclaration\";\nimport { uvAttributeDeclaration } from \"./ShadersInclude/uvAttributeDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { prePassVertexDeclaration } from \"./ShadersInclude/prePassVertexDeclaration\";\nimport { mainUVVaryingDeclaration } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { samplerVertexDeclaration } from \"./ShadersInclude/samplerVertexDeclaration\";\nimport { bumpVertexDeclaration } from \"./ShadersInclude/bumpVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxFragmentDeclaration } from \"./ShadersInclude/lightVxFragmentDeclaration\";\nimport { lightVxUboDeclaration } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { prePassVertex } from \"./ShadersInclude/prePassVertex\";\nimport { uvVariableDeclaration } from \"./ShadersInclude/uvVariableDeclaration\";\nimport { samplerVertexImplementation } from \"./ShadersInclude/samplerVertexImplementation\";\nimport { bumpVertex } from \"./ShadersInclude/bumpVertex\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertex } from \"./ShadersInclude/shadowsVertex\";\nimport { vertexColorMixing } from \"./ShadersInclude/vertexColorMixing\";\nimport { pointCloudVertex } from \"./ShadersInclude/pointCloudVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"defaultVertexShader\";\nconst shader = `#define CUSTOM_VERTEX_EXTENSION\n#include<__decl__defaultVertex>\n#define CUSTOM_VERTEX_BEGIN\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#include<uvAttributeDeclaration>[2..7]\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<helperFunctions>\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<prePassVertexDeclaration>\n#include<mainUVVaryingDeclaration>[1..7]\n#include<samplerVertexDeclaration>(_DEFINENAME_,DIFFUSE,_VARYINGNAME_,Diffuse)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail)\n#include<samplerVertexDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient)\n#include<samplerVertexDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive)\n#include<samplerVertexDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap)\n#if defined(SPECULARTERM)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR,_VARYINGNAME_,Specular)\n#endif\n#include<samplerVertexDeclaration>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal)\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vec4 vColor;\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightVxFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying float vViewDepth;\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#ifdef NORMAL\nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#ifdef VERTEXCOLOR\nvec4 colorUpdated=color;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvPositionUVW=positionUpdated;\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#if defined(PREPASS) && ((defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);vPreviousPosition=previousViewProjection*finalPreviousWorld*vec4(positionUpdated,1.0);\n#endif\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvNormalW=normalUpdated/vec3(dot(normalWorld[0],normalWorld[0]),dot(normalWorld[1],normalWorld[1]),dot(normalWorld[2],normalWorld[2]));vNormalW=normalize(normalWorld*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_WORLDPOS\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {gl_Position=viewProjection*worldPos;} else {gl_Position=viewProjectionR*worldPos;}\n#else\ngl_Position=viewProjection*worldPos;\n#endif\nvPositionW=vec3(worldPos);\n#ifdef PREPASS\n#include<prePassVertex>\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#ifdef RIGHT_HANDED\nvViewDepth=-(view*worldPos).z;\n#else\nvViewDepth=(view*worldPos).z;\n#endif\n#endif\n#ifndef UV1\nvec2 uvUpdated=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2Updated=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uvUpdated;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2Updated;\n#endif\n#include<uvVariableDeclaration>[3..7]\n#include<samplerVertexImplementation>(_DEFINENAME_,DIFFUSE,_VARYINGNAME_,Diffuse,_MATRIXNAME_,diffuse,_INFONAME_,DiffuseInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_MATRIXNAME_,detail,_INFONAME_,DetailInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_MATRIXNAME_,ambient,_INFONAME_,AmbientInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_MATRIXNAME_,opacity,_INFONAME_,OpacityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_MATRIXNAME_,emissive,_INFONAME_,EmissiveInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_MATRIXNAME_,lightmap,_INFONAME_,LightmapInfos.x)\n#if defined(SPECULARTERM)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR,_VARYINGNAME_,Specular,_MATRIXNAME_,specular,_INFONAME_,SpecularInfos.x)\n#endif\n#include<samplerVertexImplementation>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_MATRIXNAME_,bump,_INFONAME_,BumpInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_MATRIXNAME_,decal,_INFONAME_,DecalInfos.x)\n#include<bumpVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#include<vertexColorMixing>\n#include<pointCloudVertex>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [decalVertexDeclaration, defaultVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, defaultUboDeclaration, uvAttributeDeclaration, helperFunctions, bonesDeclaration, bakedVertexAnimationDeclaration, instancesDeclaration, prePassVertexDeclaration, mainUVVaryingDeclaration, samplerVertexDeclaration, bumpVertexDeclaration, clipPlaneVertexDeclaration, fogVertexDeclaration, lightVxFragmentDeclaration, lightVxUboDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, logDepthDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, prePassVertex, uvVariableDeclaration, samplerVertexImplementation, bumpVertex, clipPlaneVertex, fogVertex, shadowsVertex, vertexColorMixing, pointCloudVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const defaultVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"defaultUboDeclaration\";\nconst shader = `uniform diffuseLeftColor: vec4f;uniform diffuseRightColor: vec4f;uniform opacityParts: vec4f;uniform reflectionLeftColor: vec4f;uniform reflectionRightColor: vec4f;uniform refractionLeftColor: vec4f;uniform refractionRightColor: vec4f;uniform emissiveLeftColor: vec4f;uniform emissiveRightColor: vec4f;uniform vDiffuseInfos: vec2f;uniform vAmbientInfos: vec2f;uniform vOpacityInfos: vec2f;uniform vEmissiveInfos: vec2f;uniform vLightmapInfos: vec2f;uniform vSpecularInfos: vec2f;uniform vBumpInfos: vec3f;uniform diffuseMatrix: mat4x4f;uniform ambientMatrix: mat4x4f;uniform opacityMatrix: mat4x4f;uniform emissiveMatrix: mat4x4f;uniform lightmapMatrix: mat4x4f;uniform specularMatrix: mat4x4f;uniform bumpMatrix: mat4x4f;uniform vTangentSpaceParams: vec2f;uniform pointSize: f32;uniform alphaCutOff: f32;uniform refractionMatrix: mat4x4f;uniform vRefractionInfos: vec4f;uniform vRefractionPosition: vec3f;uniform vRefractionSize: vec3f;uniform vSpecularColor: vec4f;uniform vEmissiveColor: vec3f;uniform vDiffuseColor: vec4f;uniform vAmbientColor: vec3f;uniform cameraInfo: vec4f;uniform vTextureRepetitionHexTilingParams: vec4f;uniform vReflectionInfos: vec2f;uniform reflectionMatrix: mat4x4f;uniform vReflectionPosition: vec3f;uniform vReflectionSize: vec3f;\n#define ADDITIONAL_UBO_DECLARATION\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const defaultUboDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"defaultFragmentAlpha\";\nconst shader = `#ifdef OPACITY\nvar opacityMap: vec4f=TEXRD(opacitySampler,opacitySamplerSampler,fragmentInputs.vOpacityUV+uvOffset);\n#ifdef OPACITYRGB\nopacityMap=vec4f(opacityMap.rgb* vec3f(0.3,0.59,0.11),opacityMap.a);alpha*=(opacityMap.x+opacityMap.y+opacityMap.z)* uniforms.vOpacityInfos.y;\n#else\nalpha*=opacityMap.a*uniforms.vOpacityInfos.y;\n#endif\n#endif\n#if defined(VERTEXALPHA) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nalpha*=fragmentInputs.vColor.a;\n#endif\n#ifdef OPACITYFRESNEL\nvar opacityFresnelTerm: f32=computeFresnelTerm(viewDirectionW,normalW,uniforms.opacityParts.z,uniforms.opacityParts.w);alpha+=uniforms.opacityParts.x*(1.0-opacityFresnelTerm)+opacityFresnelTerm*uniforms.opacityParts.y;\n#endif\n#ifdef ALPHATEST\n#ifdef ALPHATEST_AFTERALLALPHACOMPUTATIONS\nif (alpha<uniforms.alphaCutOff) {discard;}\n#endif\n#ifndef ALPHABLEND\nalpha=1.0;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const defaultFragmentAlphaWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { defaultUboDeclarationWGSL } from \"./ShadersInclude/defaultUboDeclaration\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { oitDeclarationWGSL } from \"./ShadersInclude/oitDeclaration\";\nimport { mainUVVaryingDeclarationWGSL } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { lightUboDeclarationWGSL } from \"./ShadersInclude/lightUboDeclaration\";\nimport { ltcHelperFunctionsWGSL } from \"./ShadersInclude/ltcHelperFunctions\";\nimport { clusteredLightingFunctionsWGSL } from \"./ShadersInclude/clusteredLightingFunctions\";\nimport { clusteredLightingComputeWGSL } from \"./ShadersInclude/clusteredLightingCompute\";\nimport { lightsFragmentFunctionsWGSL } from \"./ShadersInclude/lightsFragmentFunctions\";\nimport { shadowsFragmentFunctionsWGSL } from \"./ShadersInclude/shadowsFragmentFunctions\";\nimport { samplerFragmentDeclarationWGSL } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { fresnelFunctionWGSL } from \"./ShadersInclude/fresnelFunction\";\nimport { reflectionFunctionWGSL } from \"./ShadersInclude/reflectionFunction\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { textureRepetitionFunctionsWGSL } from \"./ShadersInclude/textureRepetitionFunctions\";\nimport { bumpFragmentMainFunctionsWGSL } from \"./ShadersInclude/bumpFragmentMainFunctions\";\nimport { bumpFragmentFunctionsWGSL } from \"./ShadersInclude/bumpFragmentFunctions\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { bumpFragmentWGSL } from \"./ShadersInclude/bumpFragment\";\nimport { decalFragmentWGSL } from \"./ShadersInclude/decalFragment\";\nimport { defaultFragmentAlphaWGSL } from \"./ShadersInclude/defaultFragmentAlpha\";\nimport { depthPrePassWGSL } from \"./ShadersInclude/depthPrePass\";\nimport { lightFragmentWGSL } from \"./ShadersInclude/lightFragment\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { oitFragmentWGSL } from \"./ShadersInclude/oitFragment\";\n\nconst name = \"defaultPixelShader\";\nconst shader = `#include<defaultUboDeclaration>\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<oitDeclaration>\n#define CUSTOM_FRAGMENT_BEGIN\nvarying vPositionW: vec3f;\n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vColor: vec4f;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying vViewDepth: f32;\n#endif\n#include<mainUVVaryingDeclaration>[1..7]\n#include<helperFunctions>\n#include<lightUboDeclaration>[0..maxSimultaneousLights]\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DIFFUSE,_VARYINGNAME_,Diffuse,_SAMPLERNAME_,diffuse)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_SAMPLERNAME_,ambient)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_SAMPLERNAME_,opacity)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_SAMPLERNAME_,emissive)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_SAMPLERNAME_,lightmap)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_SAMPLERNAME_,decal)\n#ifdef REFRACTION\n#ifdef REFRACTIONMAP_3D\nvar refractionCubeSamplerSampler: sampler;var refractionCubeSampler: texture_cube<f32>;\n#else\nvar refraction2DSamplerSampler: sampler;var refraction2DSampler: texture_2d<f32>;\n#endif\n#endif\n#if defined(SPECULARTERM)\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SPECULAR,_VARYINGNAME_,Specular,_SAMPLERNAME_,specular)\n#endif\n#include<fresnelFunction>\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nvar reflectionCubeSamplerSampler: sampler;var reflectionCubeSampler: texture_cube<f32>;\n#else\nvar reflection2DSamplerSampler: sampler;var reflection2DSampler: texture_2d<f32>;\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n#include<imageProcessingDeclaration>\n#include<imageProcessingFunctions>\n#include<textureRepetitionFunctions>\n#include<bumpFragmentMainFunctions>\n#include<bumpFragmentFunctions>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvar viewDirectionW: vec3f=normalize(scene.vEyePosition.xyz-fragmentInputs.vPositionW);var baseColor: vec4f= vec4f(1.,1.,1.,1.);var diffuseColor: vec3f=uniforms.vDiffuseColor.rgb;var alpha: f32=uniforms.vDiffuseColor.a;\n#ifdef NORMAL\nvar normalW: vec3f=normalize(fragmentInputs.vNormalW);\n#else\nvar normalW: vec3f=normalize(cross(dpdx(fragmentInputs.vPositionW),dpdy(fragmentInputs.vPositionW)))* scene.vEyePosition.w;\n#endif\n#include<bumpFragment>\n#ifdef TWOSIDEDLIGHTING\nnormalW=select(-normalW,normalW,fragmentInputs.frontFacing);\n#endif\n#ifdef DIFFUSE\nbaseColor=TEXRD(diffuseSampler,diffuseSamplerSampler,fragmentInputs.vDiffuseUV+uvOffset);\n#if defined(ALPHATEST) && !defined(ALPHATEST_AFTERALLALPHACOMPUTATIONS)\nif (baseColor.a<uniforms.alphaCutOff) {discard;}\n#endif\n#ifdef ALPHAFROMDIFFUSE\nalpha*=baseColor.a;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\nbaseColor=vec4f(baseColor.rgb*uniforms.vDiffuseInfos.y,baseColor.a);\n#endif\n#if defined(DECAL) && !defined(DECAL_AFTER_DETAIL)\nvar decalColor: vec4f=textureSample(decalSampler,decalSamplerSampler,fragmentInputs.vDecalUV+uvOffset);\n#include<decalFragment>(surfaceAlbedo,baseColor,GAMMADECAL,_GAMMADECAL_NOTUSED_)\n#endif\n#ifdef DEPTHPREPASS\n#include<defaultFragmentAlpha>\n#endif\n#define DEPTHPREPASS_SKIP_EARLY_RETURN\n#include<depthPrePass>\n#ifndef DEPTHPREPASS\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nbaseColor=vec4f(baseColor.rgb*fragmentInputs.vColor.rgb,baseColor.a);\n#endif\n#ifdef DETAIL\nbaseColor=vec4f(baseColor.rgb*2.0*mix(0.5,detailColor.r,uniforms.vDetailInfos.y),baseColor.a);\n#endif\n#if defined(DECAL) && defined(DECAL_AFTER_DETAIL)\nvar decalColor: vec4f=textureSample(decalSampler,decalSamplerSampler,fragmentInputs.vDecalUV+uvOffset);\n#include<decalFragment>(surfaceAlbedo,baseColor,GAMMADECAL,_GAMMADECAL_NOTUSED_)\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE\nvar baseAmbientColor: vec3f= vec3f(1.,1.,1.);\n#ifdef AMBIENT\nbaseAmbientColor=TEXRD(ambientSampler,ambientSamplerSampler,fragmentInputs.vAmbientUV+uvOffset).rgb*uniforms.vAmbientInfos.y;\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\nvar glossiness: f32=uniforms.vSpecularColor.a;var specularColor: vec3f=uniforms.vSpecularColor.rgb;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\nvar specularMapColor: vec4f=TEXRD(specularSampler,specularSamplerSampler,fragmentInputs.vSpecularUV+uvOffset);specularColor=specularMapColor.rgb;\n#ifdef GLOSSINESS\nglossiness=glossiness*specularMapColor.a;\n#endif\n#endif\n#endif\nvar diffuseBase: vec3f= vec3f(0.,0.,0.);var info: lightingInfo;\n#ifdef SPECULARTERM\nvar specularBase: vec3f= vec3f(0.,0.,0.);\n#endif\nvar shadow: f32=1.;var aggShadow: f32=0.;var numLights: f32=0.;\n#ifdef LIGHTMAP\nvar lightmapColor: vec4f=TEXRD(lightmapSampler,lightmapSamplerSampler,fragmentInputs.vLightmapUV+uvOffset);\n#ifdef RGBDLIGHTMAP\nlightmapColor=vec4f(fromRGBD(lightmapColor),lightmapColor.a);\n#endif\nlightmapColor=vec4f(lightmapColor.rgb*uniforms.vLightmapInfos.y,lightmapColor.a);\n#endif\n#include<lightFragment>[0..maxSimultaneousLights]\naggShadow=aggShadow/numLights;var refractionColor: vec4f= vec4f(0.,0.,0.,1.);\n#ifdef REFRACTION\nvar refractionVector: vec3f=normalize(refract(-viewDirectionW,normalW,uniforms.vRefractionInfos.y));\n#ifdef REFRACTIONMAP_3D\n#ifdef USE_LOCAL_REFRACTIONMAP_CUBIC\nrefractionVector=parallaxCorrectNormal(fragmentInputs.vPositionW,refractionVector,uniforms.vRefractionSize,uniforms.vRefractionPosition);\n#endif\nrefractionVector.y=refractionVector.y*uniforms.vRefractionInfos.w;var refractionLookup: vec4f=textureSample(refractionCubeSampler,refractionCubeSamplerSampler,refractionVector);if (dot(refractionVector,viewDirectionW)<1.0) {refractionColor=refractionLookup;}\n#else\nvar vRefractionUVW: vec3f= (uniforms.refractionMatrix*(scene.view* vec4f(fragmentInputs.vPositionW+refractionVector*uniforms.vRefractionInfos.z,1.0))).xyz;var refractionCoords: vec2f=vRefractionUVW.xy/vRefractionUVW.z;refractionCoords.y=1.0-refractionCoords.y;refractionColor=textureSample(refraction2DSampler,refraction2DSamplerSampler,refractionCoords);\n#endif\n#ifdef RGBDREFRACTION\nrefractionColor=vec4f(fromRGBD(refractionColor),refractionColor.a);\n#endif\n#ifdef IS_REFRACTION_LINEAR\nrefractionColor=vec4f(toGammaSpaceVec3(refractionColor.rgb),refractionColor.a);\n#endif\nrefractionColor=vec4f(refractionColor.rgb*uniforms.vRefractionInfos.x,refractionColor.a);\n#endif\nvar reflectionColor: vec4f= vec4f(0.,0.,0.,1.);\n#ifdef REFLECTION\nvar vReflectionUVW: vec3f=computeReflectionCoords( vec4f(fragmentInputs.vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nvReflectionUVW=vec3f(vReflectionUVW.x,vReflectionUVW.y,vReflectionUVW.z*-1.0);\n#endif\n#ifdef REFLECTIONMAP_3D\n#ifdef ROUGHNESS\nvar bias: f32=uniforms.vReflectionInfos.y;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\n#ifdef GLOSSINESS\nbias*=(1.0-specularMapColor.a);\n#endif\n#endif\n#endif\nreflectionColor=textureSampleLevel(reflectionCubeSampler,reflectionCubeSamplerSampler,vReflectionUVW,bias);\n#else\nreflectionColor=textureSample(reflectionCubeSampler,reflectionCubeSamplerSampler,vReflectionUVW);\n#endif\n#else\nvar coords: vec2f=vReflectionUVW.xy;\n#ifdef REFLECTIONMAP_PROJECTION\ncoords/=vReflectionUVW.z;\n#endif\ncoords.y=1.0-coords.y;reflectionColor=textureSample(reflection2DSampler,reflection2DSamplerSampler,coords);\n#endif\n#ifdef RGBDREFLECTION\nreflectionColor=vec4f(fromRGBD(reflectionColor),reflectionColor.a);\n#endif\n#ifdef IS_REFLECTION_LINEAR\nreflectionColor=vec4f(toGammaSpaceVec3(reflectionColor.rgb),reflectionColor.a);\n#endif\nreflectionColor=vec4f(reflectionColor.rgb*uniforms.vReflectionInfos.x,reflectionColor.a);\n#ifdef REFLECTIONFRESNEL\nvar reflectionFresnelTerm: f32=computeFresnelTerm(viewDirectionW,normalW,uniforms.reflectionRightColor.a,uniforms.reflectionLeftColor.a);\n#ifdef REFLECTIONFRESNELFROMSPECULAR\n#ifdef SPECULARTERM\nreflectionColor=vec4f(reflectionColor.rgb*specularColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*uniforms.reflectionRightColor.rgb,reflectionColor.a);\n#else\nreflectionColor=vec4f(reflectionColor.rgb*uniforms.reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*uniforms.reflectionRightColor.rgb,reflectionColor.a);\n#endif\n#else\nreflectionColor=vec4f(reflectionColor.rgb*uniforms.reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*uniforms.reflectionRightColor.rgb,reflectionColor.a);\n#endif\n#endif\n#endif\n#ifdef REFRACTIONFRESNEL\nvar refractionFresnelTerm: f32=computeFresnelTerm(viewDirectionW,normalW,uniforms.refractionRightColor.a,uniforms.refractionLeftColor.a);refractionColor=vec4f(refractionColor.rgb*uniforms.refractionLeftColor.rgb*(1.0-refractionFresnelTerm)+refractionFresnelTerm*uniforms.refractionRightColor.rgb,refractionColor.a);\n#endif\n#include<defaultFragmentAlpha>\nvar emissiveColor: vec3f=uniforms.vEmissiveColor;\n#ifdef EMISSIVE\nemissiveColor+=TEXRD(emissiveSampler,emissiveSamplerSampler,fragmentInputs.vEmissiveUV+uvOffset).rgb*uniforms.vEmissiveInfos.y;\n#endif\n#ifdef EMISSIVEFRESNEL\nvar emissiveFresnelTerm: f32=computeFresnelTerm(viewDirectionW,normalW,uniforms.emissiveRightColor.a,uniforms.emissiveLeftColor.a);emissiveColor*=uniforms.emissiveLeftColor.rgb*(1.0-emissiveFresnelTerm)+emissiveFresnelTerm*uniforms.emissiveRightColor.rgb;\n#endif\n#ifdef DIFFUSEFRESNEL\nvar diffuseFresnelTerm: f32=computeFresnelTerm(viewDirectionW,normalW,uniforms.diffuseRightColor.a,uniforms.diffuseLeftColor.a);diffuseBase*=uniforms.diffuseLeftColor.rgb*(1.0-diffuseFresnelTerm)+diffuseFresnelTerm*uniforms.diffuseRightColor.rgb;\n#endif\n#ifdef EMISSIVEASILLUMINATION\nvar finalDiffuse: vec3f=clamp(diffuseBase*diffuseColor+uniforms.vAmbientColor,vec3f(0.0),vec3f(1.0))*baseColor.rgb;\n#else\n#ifdef LINKEMISSIVEWITHDIFFUSE\nvar finalDiffuse: vec3f=clamp((diffuseBase+emissiveColor)*diffuseColor+uniforms.vAmbientColor,vec3f(0.0),vec3f(1.0))*baseColor.rgb;\n#else\nvar finalDiffuse: vec3f=clamp(diffuseBase*diffuseColor+emissiveColor+uniforms.vAmbientColor,vec3f(0.0),vec3f(1.0))*baseColor.rgb;\n#endif\n#endif\n#ifdef SPECULARTERM\nvar finalSpecular: vec3f=specularBase*specularColor;\n#ifdef SPECULAROVERALPHA\nalpha=clamp(alpha+dot(finalSpecular, vec3f(0.3,0.59,0.11)),0.0,1.0);\n#endif\n#else\nvar finalSpecular: vec3f= vec3f(0.0);\n#endif\n#ifdef REFLECTIONOVERALPHA\nalpha=clamp(alpha+dot(reflectionColor.rgb, vec3f(0.3,0.59,0.11)),0.0,1.0);\n#endif\n#ifdef EMISSIVEASILLUMINATION\nvar color: vec4f= vec4f(clamp(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+emissiveColor+refractionColor.rgb,vec3f(0.0),vec3f(1.0)),alpha);\n#else\nvar color: vec4f= vec4f(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+refractionColor.rgb,alpha);\n#endif\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\ncolor=vec4f(color.rgb*lightmapColor.rgb,color.a);\n#else\ncolor=vec4f(color.rgb+lightmapColor.rgb,color.a);\n#endif\n#endif\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FOG\ncolor=vec4f(max(color.rgb,vec3f(0.)),color.a);\n#include<logDepthFragment>\n#include<fogFragment>\n#ifdef IMAGEPROCESSINGPOSTPROCESS\ncolor=vec4f(toLinearSpaceVec3(color.rgb),color.a);\n#else\n#ifdef IMAGEPROCESSING\ncolor=vec4f(toLinearSpaceVec3(color.rgb),color.a);color=applyImageProcessing(color);\n#endif\n#endif\ncolor=vec4f(color.rgb,color.a*mesh.visibility);\n#ifdef PREMULTIPLYALPHA\ncolor=vec4f(color.rgb*color.a, color.a);\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\n#if SCENE_MRT_COUNT>0\n#ifdef ALPHATEST\nvar writeGeometryInfo: f32=1.0;\n#else\nvar writeGeometryInfo: f32=select(0.0,1.0,color.a>0.4);\n#endif\nvar fragData: array<vec4<f32>,SCENE_MRT_COUNT>;\n#ifdef PREPASS_MESH_BLEND_TAG\nvar meshBlendTagOutput: vec4<u32>=vec4u(0u);if (writeGeometryInfo>0.0) {meshBlendTagOutput=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);}\n#endif\n#ifdef PREPASS_COLOR\nfragData[PREPASS_COLOR_INDEX]=color; \n#endif\n#ifdef PREPASS_POSITION\nfragData[PREPASS_POSITION_INDEX]=vec4f(fragmentInputs.vPositionW,writeGeometryInfo);\n#endif\n#ifdef PREPASS_OBJECT_ID\nfragData[PREPASS_OBJECT_ID_INDEX]=encodeObjectId(uniforms.objectId)*writeGeometryInfo;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nfragData[PREPASS_LOCAL_POSITION_INDEX]=vec4f(fragmentInputs.vPosition,writeGeometryInfo);\n#endif\n#ifdef PREPASS_VELOCITY\nvar a: vec2f=(fragmentInputs.vCurrentPosition.xy/fragmentInputs.vCurrentPosition.w)*0.5+0.5;var b: vec2f=(fragmentInputs.vPreviousPosition.xy/fragmentInputs.vPreviousPosition.w)*0.5+0.5;var velocity: vec2f=abs(a-b);velocity= vec2f(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;fragData[PREPASS_VELOCITY_INDEX]= vec4f(velocity,0.0,writeGeometryInfo);\n#elif defined(PREPASS_VELOCITY_LINEAR)\nvar velocity : vec2f=vec2f(0.5)*((fragmentInputs.vPreviousPosition.xy/fragmentInputs.vPreviousPosition.w) -\n(fragmentInputs.vCurrentPosition.xy/fragmentInputs.vCurrentPosition.w));fragData[PREPASS_VELOCITY_LINEAR_INDEX]=vec4f(velocity,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_IRRADIANCE\nfragData[PREPASS_IRRADIANCE_INDEX]=vec4f(0.0,0.0,0.0,writeGeometryInfo); \n#endif\n#ifdef PREPASS_DEPTH\nfragData[PREPASS_DEPTH_INDEX]=vec4f(fragmentInputs.vViewPos.z,0.0,0.0,writeGeometryInfo); \n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nfragData[PREPASS_SCREENSPACE_DEPTH_INDEX]=vec4f(fragmentInputs.position.z,0.0,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfragData[PREPASS_NORMALIZED_VIEW_DEPTH_INDEX]=vec4f(fragmentInputs.vNormViewDepth,0.0,0.0,writeGeometryInfo);\n#endif\n#ifdef PREPASS_NORMAL\n#ifdef PREPASS_NORMAL_WORLDSPACE\nfragData[PREPASS_NORMAL_INDEX]=vec4f(normalW,writeGeometryInfo);\n#else\nfragData[PREPASS_NORMAL_INDEX]=vec4f(normalize((scene.view*vec4f(normalW,0.0)).rgb),writeGeometryInfo);\n#endif\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nfragData[PREPASS_WORLD_NORMAL_INDEX]=vec4f(normalW*0.5+0.5,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO\nfragData[PREPASS_ALBEDO_INDEX]=vec4f(baseColor.rgb,writeGeometryInfo);\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nfragData[PREPASS_ALBEDO_SQRT_INDEX]=vec4f(sqrt(baseColor.rgb),writeGeometryInfo);\n#endif\n#ifdef PREPASS_REFLECTIVITY\n#if defined(SPECULAR)\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(toLinearSpaceVec4(specularMapColor))*writeGeometryInfo; \n#else\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(toLinearSpaceVec3(specularColor),1.0)*writeGeometryInfo;\n#endif\n#endif\n#include<meshBlendTagFragmentOutput>[0..8]\n#endif\n#endif\n#if !defined(PREPASS) && !defined(ORDER_INDEPENDENT_TRANSPARENCY)\nfragmentOutputs.color=color;\n#endif\n#include<oitFragment>\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {fragmentOutputs.frontColor=vec4f(fragmentOutputs.frontColor.rgb+color.rgb*color.a*alphaMultiplier,1.0-alphaMultiplier*(1.0-color.a));} else {fragmentOutputs.backColor+=color;}\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, defaultUboDeclarationWGSL, objectIdFunctionsWGSL, prePassDeclarationWGSL, oitDeclarationWGSL, mainUVVaryingDeclarationWGSL, helperFunctionsWGSL, lightUboDeclarationWGSL, ltcHelperFunctionsWGSL, clusteredLightingFunctionsWGSL, clusteredLightingComputeWGSL, lightsFragmentFunctionsWGSL, shadowsFragmentFunctionsWGSL, samplerFragmentDeclarationWGSL, fresnelFunctionWGSL, reflectionFunctionWGSL, imageProcessingDeclarationWGSL, imageProcessingFunctionsWGSL, textureRepetitionFunctionsWGSL, bumpFragmentMainFunctionsWGSL, bumpFragmentFunctionsWGSL, clipPlaneFragmentDeclarationWGSL, logDepthDeclarationWGSL, fogFragmentDeclarationWGSL, clipPlaneFragmentWGSL, bumpFragmentWGSL, decalFragmentWGSL, defaultFragmentAlphaWGSL, depthPrePassWGSL, lightFragmentWGSL, logDepthFragmentWGSL, fogFragmentWGSL, meshBlendTagFragmentOutputWGSL, oitFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const defaultPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lightVxFragmentDeclaration\";\nconst shader = `#ifdef LIGHT{X}\nuniform vLightData{X}: vec4f;uniform vLightDiffuse{X}: vec4f;\n#ifdef SPECULARTERM\nuniform vLightSpecular{X}: vec4f;\n#else\nvar vLightSpecular{X}: vec4f= vec4f(0.);\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCSM{X}\nuniform lightMatrix{X}: mat4x4f[SHADOWCSMNUM_CASCADES{X}];varying var vPositionFromLight{X}: vec4f[SHADOWCSMNUM_CASCADES{X}];varying var vDepthMetric{X}: f32[SHADOWCSMNUM_CASCADES{X}];varying var vPositionFromCamera{X}: vec4f;\n#elif defined(SHADOWCUBE{X})\n#else\nvarying var vPositionFromLight{X}: vec4f;varying var vDepthMetric{X}: f32;uniform lightMatrix{X}: mat4x4f;\n#endif\nuniform shadowsInfo{X}: vec4f;uniform depthValues{X}: vec2f;\n#endif\n#ifdef SPOTLIGHT{X}\nuniform vLightDirection{X}: vec4f;uniform vLightFalloff{X}: vec4f;\n#elif defined(POINTLIGHT{X})\nuniform vLightFalloff{X}: vec4f;\n#elif defined(HEMILIGHT{X})\nuniform vLightGround{X}: vec3f;\n#endif\n#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)\nuniform vLightWidth{X}: vec4f;uniform vLightHeight{X}: vec4f;\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const lightVxFragmentDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { defaultUboDeclarationWGSL } from \"./ShadersInclude/defaultUboDeclaration\";\nimport { uvAttributeDeclarationWGSL } from \"./ShadersInclude/uvAttributeDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { prePassVertexDeclarationWGSL } from \"./ShadersInclude/prePassVertexDeclaration\";\nimport { mainUVVaryingDeclarationWGSL } from \"./ShadersInclude/mainUVVaryingDeclaration\";\nimport { samplerVertexDeclarationWGSL } from \"./ShadersInclude/samplerVertexDeclaration\";\nimport { bumpVertexDeclarationWGSL } from \"./ShadersInclude/bumpVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { lightVxFragmentDeclarationWGSL } from \"./ShadersInclude/lightVxFragmentDeclaration\";\nimport { lightVxUboDeclarationWGSL } from \"./ShadersInclude/lightVxUboDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { vertexPullingDeclarationWGSL } from \"./ShadersInclude/vertexPullingDeclaration\";\nimport { vertexPullingVertexWGSL } from \"./ShadersInclude/vertexPullingVertex\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { prePassVertexWGSL } from \"./ShadersInclude/prePassVertex\";\nimport { uvVariableDeclarationWGSL } from \"./ShadersInclude/uvVariableDeclaration\";\nimport { samplerVertexImplementationWGSL } from \"./ShadersInclude/samplerVertexImplementation\";\nimport { bumpVertexWGSL } from \"./ShadersInclude/bumpVertex\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { shadowsVertexWGSL } from \"./ShadersInclude/shadowsVertex\";\nimport { vertexColorMixingWGSL } from \"./ShadersInclude/vertexColorMixing\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"defaultVertexShader\";\nconst shader = `#include<defaultUboDeclaration>\n#define CUSTOM_VERTEX_BEGIN\n#ifndef USE_VERTEX_PULLING\nattribute position: vec3f;\n#ifdef NORMAL\nattribute normal: vec3f;\n#endif\n#ifdef TANGENT\nattribute tangent: vec4f;\n#endif\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#include<uvAttributeDeclaration>[2..7]\n#ifdef VERTEXCOLOR\nattribute color: vec4f;\n#endif\n#endif\n#include<helperFunctions>\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<prePassVertexDeclaration>\n#include<mainUVVaryingDeclaration>[1..7]\n#include<samplerVertexDeclaration>(_DEFINENAME_,DIFFUSE,_VARYINGNAME_,Diffuse)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail)\n#include<samplerVertexDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient)\n#include<samplerVertexDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity)\n#include<samplerVertexDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive)\n#include<samplerVertexDeclaration>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap)\n#if defined(SPECULARTERM)\n#include<samplerVertexDeclaration>(_DEFINENAME_,SPECULAR,_VARYINGNAME_,Specular)\n#endif\n#include<samplerVertexDeclaration>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump)\n#include<samplerVertexDeclaration>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal)\nvarying vPositionW: vec3f;\n#ifdef NORMAL\nvarying vNormalW: vec3f;\n#endif\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vColor: vec4f;\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightVxFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vPositionUVW: vec3f;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vDirectionW: vec3f;\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\nvarying vViewDepth: f32;\n#endif\n#include<logDepthDeclaration>\n#include<vertexPullingDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef USE_VERTEX_PULLING\nvar positionUpdated: vec3f=vec3f(0.0);\n#ifdef NORMAL\nvar normalUpdated: vec3f=vec3f(0.0);\n#endif\n#ifdef TANGENT\nvar tangentUpdated: vec4f=vec4f(0.0);\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vec2f(0.0);\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vec2f(0.0);\n#endif\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vec4f(0.0);\n#endif\n#else\nvar positionUpdated: vec3f=vertexInputs.position;\n#ifdef NORMAL\nvar normalUpdated: vec3f=vertexInputs.normal;\n#endif\n#ifdef TANGENT\nvar tangentUpdated: vec4f=vertexInputs.tangent;\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vertexInputs.color;\n#endif\n#endif\n#include<vertexPullingVertex>\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvertexOutputs.vPositionUVW=positionUpdated;\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#if defined(PREPASS) && ((defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvertexOutputs.vCurrentPosition=scene.viewProjection*finalWorld*vec4f(positionUpdated,1.0);vertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld*vec4f(positionUpdated,1.0);\n#endif\n#ifdef USE_VERTEX_PULLING\n#include<bonesVertex>(vertexInputs.matricesIndices,vp_matricesIndices,vertexInputs.matricesWeights,vp_matricesWeights,vertexInputs.matricesIndicesExtra,vp_matricesIndicesExtra,vertexInputs.matricesWeightsExtra,vp_matricesWeightsExtra)\n#include<bakedVertexAnimation>(vertexInputs.matricesIndices,vp_matricesIndices,vertexInputs.matricesWeights,vp_matricesWeights,vertexInputs.matricesIndicesExtra,vp_matricesIndicesExtra,vertexInputs.matricesWeightsExtra,vp_matricesWeightsExtra)\n#else\n#include<bonesVertex>\n#include<bakedVertexAnimation>\n#endif\nvar worldPos: vec4f=finalWorld*vec4f(positionUpdated,1.0);\n#ifdef NORMAL\nvar normalWorld: mat3x3f= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvertexOutputs.vNormalW=normalUpdated/ vec3f(dot(normalWorld[0],normalWorld[0]),dot(normalWorld[1],normalWorld[1]),dot(normalWorld[2],normalWorld[2]));vertexOutputs.vNormalW=normalize(normalWorld*vertexOutputs.vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvertexOutputs.vNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_WORLDPOS\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {vertexOutputs.position=scene.viewProjection*worldPos;} else {vertexOutputs.position=scene.viewProjectionR*worldPos;}\n#else\nvertexOutputs.position=scene.viewProjection*worldPos;\n#endif\nvertexOutputs.vPositionW= worldPos.xyz;\n#ifdef PREPASS\n#include<prePassVertex>\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvertexOutputs.vDirectionW=normalize((finalWorld* vec4f(positionUpdated,0.0)).xyz);\n#endif\n#if defined(CLUSTLIGHT_BATCH) && CLUSTLIGHT_BATCH>0\n#ifdef RIGHT_HANDED\nvertexOutputs.vViewDepth=-(scene.view*worldPos).z;\n#else\nvertexOutputs.vViewDepth=(scene.view*worldPos).z;\n#endif\n#endif\n#ifndef UV1\nvar uvUpdated: vec2f=vec2f(0.,0.);\n#endif\n#ifdef MAINUV1\nvertexOutputs.vMainUV1=uvUpdated;\n#endif\n#ifndef UV2\nvar uv2Updated: vec2f=vec2f(0.,0.);\n#endif\n#ifdef MAINUV2\nvertexOutputs.vMainUV2=uv2Updated;\n#endif\n#include<uvVariableDeclaration>[3..7]\n#include<samplerVertexImplementation>(_DEFINENAME_,DIFFUSE,_VARYINGNAME_,Diffuse,_MATRIXNAME_,diffuse,_INFONAME_,DiffuseInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DETAIL,_VARYINGNAME_,Detail,_MATRIXNAME_,detail,_INFONAME_,DetailInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_MATRIXNAME_,ambient,_INFONAME_,AmbientInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_MATRIXNAME_,opacity,_INFONAME_,OpacityInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_MATRIXNAME_,emissive,_INFONAME_,EmissiveInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,LIGHTMAP,_VARYINGNAME_,Lightmap,_MATRIXNAME_,lightmap,_INFONAME_,LightmapInfos.x)\n#if defined(SPECULARTERM)\n#include<samplerVertexImplementation>(_DEFINENAME_,SPECULAR,_VARYINGNAME_,Specular,_MATRIXNAME_,specular,_INFONAME_,SpecularInfos.x)\n#endif\n#include<samplerVertexImplementation>(_DEFINENAME_,BUMP,_VARYINGNAME_,Bump,_MATRIXNAME_,bump,_INFONAME_,BumpInfos.x)\n#include<samplerVertexImplementation>(_DEFINENAME_,DECAL,_VARYINGNAME_,Decal,_MATRIXNAME_,decal,_INFONAME_,DecalInfos.x)\n#include<bumpVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#include<vertexColorMixing>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, defaultUboDeclarationWGSL, uvAttributeDeclarationWGSL, helperFunctionsWGSL, bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, instancesDeclarationWGSL, prePassVertexDeclarationWGSL, mainUVVaryingDeclarationWGSL, samplerVertexDeclarationWGSL, bumpVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, lightVxFragmentDeclarationWGSL, lightVxUboDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, logDepthDeclarationWGSL, vertexPullingDeclarationWGSL, vertexPullingVertexWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, prePassVertexWGSL, uvVariableDeclarationWGSL, samplerVertexImplementationWGSL, bumpVertexWGSL, clipPlaneVertexWGSL, fogVertexWGSL, shadowsVertexWGSL, vertexColorMixingWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const defaultVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"greasedLinePixelShader\";\nconst shader = `precision highp float;uniform sampler2D grlColors;uniform float grlUseColors;uniform float grlUseDash;uniform float grlDashArray;uniform float grlDashOffset;uniform float grlDashRatio;uniform float grlVisibility;uniform float grlColorsWidth;uniform vec2 grl_colorModeAndColorDistributionType;uniform vec3 grlColor;varying float grlCounters;varying float grlColorPointer;void main() {float grlColorMode=grl_colorModeAndColorDistributionType.x;float grlColorDistributionType=grl_colorModeAndColorDistributionType.y;gl_FragColor=vec4(grlColor,1.);gl_FragColor.a=step(grlCounters,grlVisibility);if (gl_FragColor.a==0.) discard;if( grlUseDash==1. ){gl_FragColor.a=ceil(mod(grlCounters+grlDashOffset,grlDashArray)-(grlDashArray*grlDashRatio));if (gl_FragColor.a==0.) discard;}\nif (grlUseColors==1.) {vec4 textureColor;if (grlColorDistributionType==COLOR_DISTRIBUTION_TYPE_LINE) { \ntextureColor=texture2D(grlColors,vec2(grlCounters,0.),0.);} else {textureColor=texture2D(grlColors,vec2(grlColorPointer/grlColorsWidth,0.),0.);}\nif (grlColorMode==COLOR_MODE_SET) {gl_FragColor=textureColor;} else if (grlColorMode==COLOR_MODE_ADD) {gl_FragColor+=textureColor;} else if (grlColorMode==COLOR_MODE_MULTIPLY) {gl_FragColor*=textureColor;}}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const greasedLinePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\n\nconst name = \"greasedLineVertexShader\";\nconst shader = `precision highp float;\n#include<instancesDeclaration>\nattribute float grl_widths;\n#ifdef GREASED_LINE_USE_OFFSETS\nattribute vec3 grl_offsets;\n#endif\nattribute float grl_colorPointers;attribute vec3 position;uniform mat4 viewProjection;uniform mat4 projection;varying float grlCounters;varying float grlColorPointer;\n#ifdef GREASED_LINE_CAMERA_FACING\nattribute vec4 grl_nextAndCounters;attribute vec4 grl_previousAndSide;uniform vec2 grlResolution;uniform float grlAspect;uniform float grlWidth;uniform float grlSizeAttenuation;vec2 grlFix( vec4 i,float aspect ) {vec2 res=i.xy/i.w;res.x*=aspect;return res;}\n#else\nattribute vec3 grl_slopes;attribute float grl_counters;\n#endif\nvoid main() {\n#include<instancesVertex>\ngrlColorPointer=grl_colorPointers;mat4 grlMatrix=viewProjection*finalWorld ;\n#ifdef GREASED_LINE_CAMERA_FACING\nfloat grlBaseWidth=grlWidth;vec3 grlPrevious=grl_previousAndSide.xyz;float grlSide=grl_previousAndSide.w;vec3 grlNext=grl_nextAndCounters.xyz;grlCounters=grl_nextAndCounters.w;float grlWidth=grlBaseWidth*grl_widths;\n#ifdef GREASED_LINE_USE_OFFSETS\nvec3 grlPositionOffset=grl_offsets;\n#else\nvec3 grlPositionOffset=vec3(0.);\n#endif\nvec3 positionUpdated=position+grlPositionOffset;vec3 worldDir=normalize(grlNext-grlPrevious);vec3 nearPosition=positionUpdated+(worldDir*0.01);vec4 grlFinalPosition=grlMatrix*vec4( positionUpdated ,1.0);vec4 screenNearPos=grlMatrix*vec4(nearPosition,1.0);vec2 grlLinePosition=grlFix(grlFinalPosition,grlAspect);vec2 grlLineNearPosition=grlFix(screenNearPos,grlAspect);vec2 grlDir=normalize(grlLineNearPosition-grlLinePosition);vec4 grlNormal=vec4( -grlDir.y,grlDir.x,0.,1. );\n#ifdef GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM\ngrlNormal.xy*=-.5*grlWidth;\n#else\ngrlNormal.xy*=.5*grlWidth;\n#endif\ngrlNormal*=projection;if (grlSizeAttenuation==1.) {grlNormal.xy*=grlFinalPosition.w;grlNormal.xy/=( vec4( grlResolution,0.,1. )*projection ).xy;}\ngrlFinalPosition.xy+=grlNormal.xy*grlSide;gl_Position=grlFinalPosition;\n#else\ngrlCounters=grl_counters;\n#ifdef GREASED_LINE_USE_OFFSETS\nvec3 grlPositionOffset=grl_offsets;\n#else\nvec3 grlPositionOffset=vec3(0.);\n#endif\nvec4 grlFinalPosition=grlMatrix*vec4( (position+grlPositionOffset)+grl_slopes*grl_widths ,1.0 ) ;gl_Position=grlFinalPosition;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [instancesDeclaration, instancesVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const greasedLineVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"greasedLinePixelShader\";\nconst shader = `var grlColors: texture_2d<f32>;var grlColorsSampler: sampler;uniform grlUseColors: f32;uniform grlUseDash: f32;uniform grlDashArray: f32;uniform grlDashOffset: f32;uniform grlDashRatio: f32;uniform grlVisibility: f32;uniform grlColorsWidth: f32;uniform grl_colorModeAndColorDistributionType: vec2f;uniform grlColor: vec3f;varying grlCounters: f32;varying grlColorPointer: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nlet grlColorMode: f32=uniforms.grl_colorModeAndColorDistributionType.x;let grlColorDistributionType: f32=uniforms.grl_colorModeAndColorDistributionType.y;var outColor=vec4(uniforms.grlColor,1.);outColor.a=step(fragmentInputs.grlCounters,uniforms.grlVisibility);if (outColor.a==0.0) {discard;}\nif (uniforms.grlUseDash==1.0) {let dashPosition=(fragmentInputs.grlCounters+uniforms.grlDashOffset) % uniforms.grlDashArray;outColor.a*=ceil(dashPosition-(uniforms.grlDashArray*uniforms.grlDashRatio));if (outColor.a==0.0) {discard;}}\nif (uniforms.grlUseColors==1.) {\n#ifdef GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE\nlet grlColor: vec4f=textureSample(grlColors,grlColorsSampler,vec2f(fragmentInputs.grlCounters,0.));\n#else\nlet lookup: vec2f=vec2(fract(fragmentInputs.grlColorPointer/uniforms.grlColorsWidth),1.0-floor(fragmentInputs.grlColorPointer/uniforms.grlColorsWidth));let grlColor: vec4f=textureSample(grlColors,grlColorsSampler,lookup);\n#endif\nif (grlColorMode==COLOR_MODE_SET) {outColor=grlColor;} else if (grlColorMode==COLOR_MODE_ADD) {outColor+=grlColor;} else if (grlColorMode==COLOR_MODE_MULTIPLY) {outColor*=grlColor;}}\n#if !defined(PREPASS) && !defined(ORDER_INDEPENDENT_TRANSPARENCY)\nfragmentOutputs.color=outColor;\n#endif\n#if ORDER_INDEPENDENT_TRANSPARENCY\nif (fragDepth==nearestDepth) {fragmentOutputs.frontColor=vec4f(fragmentOutputs.frontColor.rgb+outColor.rgb*outColor.a*alphaMultiplier,1.0-alphaMultiplier*(1.0-outColor.a));} else {fragmentOutputs.backColor+=outColor;}\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const greasedLinePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\n\nconst name = \"greasedLineVertexShader\";\nconst shader = `#include<instancesDeclaration>\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute grl_widths: f32;\n#ifdef GREASED_LINE_USE_OFFSETS\nattribute grl_offsets: vec3f; \n#endif\nattribute grl_colorPointers: f32;attribute position: vec3f;varying grlCounters: f32;varying grlColorPointer: f32;\n#ifdef GREASED_LINE_CAMERA_FACING\nattribute grl_nextAndCounters: vec4f;attribute grl_previousAndSide: vec4f;uniform grlResolution: vec2f;uniform grlAspect: f32;uniform grlWidth: f32;uniform grlSizeAttenuation: f32;fn grlFix(i: vec4f,aspect: f32)->vec2f {var res=i.xy/i.w;res.x*=aspect;return res;}\n#else\nattribute grl_slopes: vec3f;attribute grl_counters: f32;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#include<instancesVertex>\nvertexOutputs.grlColorPointer=vertexInputs.grl_colorPointers;let grlMatrix: mat4x4f=scene.viewProjection*mesh.world ;\n#ifdef GREASED_LINE_CAMERA_FACING\nlet grlBaseWidth: f32=uniforms.grlWidth;let grlPrevious: vec3f=vertexInputs.grl_previousAndSide.xyz;let grlSide: f32=vertexInputs.grl_previousAndSide.w;let grlNext: vec3f=vertexInputs.grl_nextAndCounters.xyz;vertexOutputs.grlCounters=vertexInputs.grl_nextAndCounters.w;let grlWidth:f32=grlBaseWidth*vertexInputs.grl_widths;\n#ifdef GREASED_LINE_USE_OFFSETS\nvar grlPositionOffset: vec3f=vertexInputs.grl_offsets;\n#else\nvar grlPositionOffset=vec3f(0.);\n#endif\nlet positionUpdated: vec3f=vertexInputs.position+grlPositionOffset;let worldDir: vec3f=normalize(grlNext-grlPrevious);let nearPosition: vec3f=positionUpdated+(worldDir*0.001);let grlFinalPosition: vec4f=grlMatrix*vec4f(positionUpdated,1.0);let screenNearPos: vec4f=grlMatrix*vec4(nearPosition,1.0);let grlLinePosition: vec2f=grlFix(grlFinalPosition,uniforms.grlAspect);let grlLineNearPosition: vec2f=grlFix(screenNearPos,uniforms.grlAspect);let grlDir: vec2f=normalize(grlLineNearPosition-grlLinePosition);var grlNormal: vec4f=vec4f(-grlDir.y,grlDir.x,0.0,1.0);let grlHalfWidth: f32=0.5*grlWidth;\n#if defined(GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM)\ngrlNormal.x*=-grlHalfWidth;grlNormal.y*=-grlHalfWidth;\n#else\ngrlNormal.x*=grlHalfWidth;grlNormal.y*=grlHalfWidth;\n#endif\ngrlNormal*=scene.projection;if (uniforms.grlSizeAttenuation==1.) {grlNormal.x*=grlFinalPosition.w;grlNormal.y*=grlFinalPosition.w;let pr=vec4f(uniforms.grlResolution,0.0,1.0)*scene.projection;grlNormal.x/=pr.x;grlNormal.y/=pr.y;}\nvertexOutputs.position=vec4f(grlFinalPosition.xy+grlNormal.xy*grlSide,grlFinalPosition.z,grlFinalPosition.w);\n#else\nvertexOutputs.grlCounters=vertexInputs.grl_counters;\n#ifdef GREASED_LINE_USE_OFFSETS\nlet grlPositionOffset: vec3f=vertexInputs.grl_offsets;\n#else\nlet grlPositionOffset: vec3f=vec3f(0.0);\n#endif\nvertexOutputs.position=grlMatrix*vec4f(vertexInputs.position+grlPositionOffset+vertexInputs.grl_slopes*vertexInputs.grl_widths,1.0);\n#endif\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [instancesDeclarationWGSL, sceneUboDeclarationWGSL, meshUboDeclarationWGSL, instancesVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const greasedLineVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"imageProcessingCompatibility\";\nconst shader = `#ifdef IMAGEPROCESSINGPOSTPROCESS\ngl_FragColor.rgb=pow(gl_FragColor.rgb,vec3(2.2));\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const imageProcessingCompatibility = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"imageProcessingCompatibility\";\nconst shader = `#ifdef IMAGEPROCESSINGPOSTPROCESS\nfragmentOutputs.color=vec4f(pow(fragmentOutputs.color.rgb, vec3f(2.2)),fragmentOutputs.color.a);\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const imageProcessingCompatibilityWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { DecalMapConfiguration } from \"./material.decalMapConfiguration.pure\";\r\nimport { StandardMaterial } from \"./standardMaterial.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for standardMaterialDecalMap.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterStandardMaterialDecalMap(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(StandardMaterial.prototype, \"decalMap\", {\r\n        get: function (this: StandardMaterial) {\r\n            if (!this._decalMap) {\r\n                this._decalMap = new DecalMapConfiguration(this);\r\n            }\r\n            return this._decalMap;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { DecalMapConfiguration } from \"../material.decalMapConfiguration.pure\";\r\nimport { PBRBaseMaterial } from \"./pbrBaseMaterial.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pbrMaterialDecalMap.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPbrMaterialDecalMap(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(PBRBaseMaterial.prototype, \"decalMap\", {\r\n        get: function (this: PBRBaseMaterial) {\r\n            if (!this._decalMap) {\r\n                this._decalMap = new DecalMapConfiguration(this);\r\n            }\r\n            return this._decalMap;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type MeshUVSpaceRenderer } from \"./meshUVSpaceRenderer.pure\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractMeshDecalMap.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractMeshDecalMap(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"decalMap\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._decalMap;\r\n        },\r\n        set: function (this: AbstractMesh, decalMap: Nullable<MeshUVSpaceRenderer>) {\r\n            this._decalMap = decalMap;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport * as functions from \"./math.scalar.functions\";\r\n\r\nconst HCF: (a: number, b: number) => number = functions.HighestCommonFactor;\r\n\r\n/**\r\n * Scalar computation library\r\n */\r\nexport const Scalar = {\r\n    ...functions,\r\n\r\n    /**\r\n     * Two pi constants convenient for computation.\r\n     */\r\n    TwoPi: Math.PI * 2,\r\n\r\n    /**\r\n     * Returns -1 if value is negative and +1 is value is positive.\r\n     * @param value the value\r\n     * @returns the value itself if it's equal to zero.\r\n     */\r\n    Sign: Math.sign,\r\n\r\n    /**\r\n     * the log2 of value.\r\n     * @param value the value to compute log2 of\r\n     * @returns the log2 of value.\r\n     */\r\n    Log2: Math.log2,\r\n\r\n    /**\r\n     * Returns the highest common factor of two integers.\r\n     * @param a first parameter\r\n     * @param b second parameter\r\n     * @returns HCF of a and b\r\n     */\r\n    HCF,\r\n};\r\n/* eslint-enable @typescript-eslint/naming-convention */\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type DeepImmutable } from \"../types\";\r\nimport { Vector2, Vector3 } from \"./math.vector.pure\";\r\n\r\n/**\r\n * Class used to store (r, theta) vector representation\r\n */\r\nexport class Polar {\r\n    /**\r\n     * Creates a new Polar object\r\n     * @param radius the radius of the vector\r\n     * @param theta the angle of the vector\r\n     */\r\n    constructor(\r\n        public radius: number,\r\n        public theta: number\r\n    ) {\r\n        this.radius = radius;\r\n        this.theta = theta;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name\r\n     * @returns the string \"Polar\"\r\n     */\r\n    public getClassName() {\r\n        return \"Polar\";\r\n    }\r\n\r\n    /**\r\n     * Converts the current polar to a string\r\n     * @returns the current polar as a string\r\n     */\r\n    public toString() {\r\n        return JSON.stringify(this);\r\n    }\r\n\r\n    /**\r\n     * Converts the current polar to an array\r\n     * @returns the current polar as an array\r\n     */\r\n    public asArray() {\r\n        return [this.radius, this.theta];\r\n    }\r\n\r\n    /**\r\n     * Adds the current Polar and the given Polar and stores the result\r\n     * @param polar the polar to add\r\n     * @param ref the polar to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public addToRef(polar: Polar, ref: Polar) {\r\n        ref.radius = this.radius + polar.radius;\r\n        ref.theta = this.theta + polar.theta;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Adds the current Polar and the given Polar\r\n     * @param polar the polar to add\r\n     * @returns the sum polar\r\n     */\r\n    public add(polar: Polar) {\r\n        const ref = new Polar(0, 0);\r\n        this.addToRef(polar, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Adds the given polar to the current polar\r\n     * @param polar the polar to add\r\n     * @returns the current polar\r\n     */\r\n    public addInPlace(polar: Polar) {\r\n        this.addToRef(polar, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the provided values to the current polar\r\n     * @param radius the amount to add to the radius\r\n     * @param theta the amount to add to the theta\r\n     * @returns the current polar\r\n     */\r\n    public addInPlaceFromFloats(radius: number, theta: number) {\r\n        this.radius += radius;\r\n        this.theta += theta;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given Polar from the current Polar and stores the result\r\n     * @param polar the polar to subtract\r\n     * @param ref the polar to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public subtractToRef(polar: Polar, ref: Polar) {\r\n        ref.radius = this.radius - polar.radius;\r\n        ref.theta = this.theta - polar.theta;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given Polar from the current Polar\r\n     * @param polar the polar to subtract\r\n     * @returns the difference polar\r\n     */\r\n    public subtract(polar: Polar) {\r\n        const ref = new Polar(0, 0);\r\n        this.subtractToRef(polar, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given Polar from the current Polar\r\n     * @param polar the polar to subtract\r\n     * @returns the current polar\r\n     */\r\n    public subtractInPlace(polar: Polar) {\r\n        this.subtractToRef(polar, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current polar\r\n     * @param radius the amount to subtract from the radius\r\n     * @param theta the amount to subtract from the theta\r\n     * @param ref the polar to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public subtractFromFloatsToRef(radius: number, theta: number, ref: Polar) {\r\n        ref.radius = this.radius - radius;\r\n        ref.theta = this.theta - theta;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current polar\r\n     * @param radius the amount to subtract from the radius\r\n     * @param theta the amount to subtract from the theta\r\n     * @returns the difference polar\r\n     */\r\n    public subtractFromFloats(radius: number, theta: number) {\r\n        const ref = new Polar(0, 0);\r\n        this.subtractFromFloatsToRef(radius, theta, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the given Polar with the current Polar and stores the result\r\n     * @param polar the polar to multiply\r\n     * @param ref the polar to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public multiplyToRef(polar: Polar, ref: Polar) {\r\n        ref.radius = this.radius * polar.radius;\r\n        ref.theta = this.theta * polar.theta;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the given Polar with the current Polar\r\n     * @param polar the polar to multiply\r\n     * @returns the product polar\r\n     */\r\n    public multiply(polar: Polar) {\r\n        const ref = new Polar(0, 0);\r\n        this.multiplyToRef(polar, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the given Polar with the current Polar\r\n     * @param polar the polar to multiply\r\n     * @returns the current polar\r\n     */\r\n    public multiplyInPlace(polar: Polar) {\r\n        this.multiplyToRef(polar, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Polar by the given Polar and stores the result\r\n     * @param polar the polar to divide\r\n     * @param ref the polar to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public divideToRef(polar: Polar, ref: Polar) {\r\n        ref.radius = this.radius / polar.radius;\r\n        ref.theta = this.theta / polar.theta;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Polar by the given Polar\r\n     * @param polar the polar to divide\r\n     * @returns the quotient polar\r\n     */\r\n    public divide(polar: Polar) {\r\n        const ref = new Polar(0, 0);\r\n        this.divideToRef(polar, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Polar by the given Polar\r\n     * @param polar the polar to divide\r\n     * @returns the current polar\r\n     */\r\n    public divideInPlace(polar: Polar) {\r\n        this.divideToRef(polar, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Clones the current polar\r\n     * @returns a clone of the current polar\r\n     */\r\n    public clone() {\r\n        return new Polar(this.radius, this.theta);\r\n    }\r\n\r\n    /**\r\n     * Copies the source polar into the current polar\r\n     * @param source the polar to copy from\r\n     * @returns the current polar\r\n     */\r\n    public copyFrom(source: Polar) {\r\n        this.radius = source.radius;\r\n        this.theta = source.theta;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copies the given values into the current polar\r\n     * @param radius the radius to use\r\n     * @param theta the theta to use\r\n     * @returns the current polar\r\n     */\r\n    public copyFromFloats(radius: number, theta: number) {\r\n        this.radius = radius;\r\n        this.theta = theta;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Scales the current polar and stores the result\r\n     * @param scale defines the multiplication factor\r\n     * @param ref where to store the result\r\n     * @returns the updated ref\r\n     */\r\n    public scaleToRef(scale: number, ref: Polar) {\r\n        ref.radius = this.radius * scale;\r\n        ref.theta = this.theta * scale;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Scales the current polar and returns a new polar with the scaled coordinates\r\n     * @param scale defines the multiplication factor\r\n     * @returns the scaled polar\r\n     */\r\n    public scale(scale: number) {\r\n        const ref = new Polar(0, 0);\r\n        this.scaleToRef(scale, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Scales the current polar\r\n     * @param scale defines the multiplication factor\r\n     * @returns the current polar\r\n     */\r\n    public scaleInPlace(scale: number) {\r\n        this.scaleToRef(scale, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the values of the current polar\r\n     * @param radius the new radius\r\n     * @param theta the new theta\r\n     * @returns the current polar\r\n     */\r\n    public set(radius: number, theta: number) {\r\n        this.radius = radius;\r\n        this.theta = theta;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the values of the current polar\r\n     * @param value the new values\r\n     * @returns the current polar\r\n     */\r\n    public setAll(value: number) {\r\n        this.set(value, value);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Gets the rectangular coordinates of the current Polar\r\n     * @param ref the reference to assign the result\r\n     * @returns the updated reference\r\n     */\r\n    public toVector2ToRef(ref: Vector2): Vector2 {\r\n        const x = this.radius * Math.cos(this.theta);\r\n        const y = this.radius * Math.sin(this.theta);\r\n        ref.set(x, y);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Gets the rectangular coordinates of the current Polar\r\n     * @returns the rectangular coordinates\r\n     */\r\n    public toVector2(): Vector2 {\r\n        const ref = new Vector2(0, 0);\r\n        return this.toVector2ToRef(ref);\r\n    }\r\n\r\n    /**\r\n     * Converts a given Vector2 to its polar coordinates\r\n     * @param v the Vector2 to convert\r\n     * @param ref the reference to assign the result\r\n     * @returns the updated reference\r\n     */\r\n    public static FromVector2ToRef(v: Vector2, ref: Polar): Polar {\r\n        const theta = Math.atan2(v.y, v.x);\r\n        ref.radius = v.length();\r\n        ref.theta = theta;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Converts a given Vector2 to its polar coordinates\r\n     * @param v the Vector2 to convert\r\n     * @returns a Polar\r\n     */\r\n    public static FromVector2(v: Vector2): Polar {\r\n        const polar = new Polar(0, 0);\r\n        Polar.FromVector2ToRef(v, polar);\r\n        return polar;\r\n    }\r\n\r\n    /**\r\n     * Converts an array of floats to a polar\r\n     * @param array the array to convert\r\n     * @returns the converted polar\r\n     */\r\n    public static FromArray(array: number[]) {\r\n        return new Polar(array[0], array[1]);\r\n    }\r\n}\r\n\r\n/**\r\n * Class used for (radius, theta, phi) vector representation.\r\n */\r\nexport class Spherical {\r\n    /**\r\n     * Creates a new Spherical object from the given spherical coordinates\r\n     * @param radius spherical radius\r\n     * @param theta angle from positive y axis to radial line from 0 to PI (vertical)\r\n     * @param phi angle from positive x axis measured anticlockwise from -PI to PI (horizontal)\r\n     */\r\n    constructor(\r\n        public radius: number,\r\n        public theta: number,\r\n        public phi: number\r\n    ) {\r\n        this.radius = radius;\r\n        this.theta = theta;\r\n        this.phi = phi;\r\n    }\r\n\r\n    /**\r\n     * Gets the class name\r\n     * @returns the string \"Spherical\"\r\n     */\r\n    public getClassName() {\r\n        return \"Spherical\";\r\n    }\r\n\r\n    /**\r\n     * Converts the current spherical to a string\r\n     * @returns the current spherical as a string\r\n     */\r\n    public toString() {\r\n        return JSON.stringify(this);\r\n    }\r\n\r\n    /**\r\n     * Converts the current spherical to an array\r\n     * @returns the current spherical as an array\r\n     */\r\n    public asArray() {\r\n        return [this.radius, this.theta, this.phi];\r\n    }\r\n\r\n    /**\r\n     * Adds the current Spherical and the given Spherical and stores the result\r\n     * @param spherical the spherical to add\r\n     * @param ref the spherical to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public addToRef(spherical: Spherical, ref: Spherical) {\r\n        ref.radius = this.radius + spherical.radius;\r\n        ref.theta = this.theta + spherical.theta;\r\n        ref.phi = this.phi + spherical.phi;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Adds the current Spherical and the given Spherical\r\n     * @param spherical the spherical to add\r\n     * @returns the sum spherical\r\n     */\r\n    public add(spherical: Spherical) {\r\n        const ref = new Spherical(0, 0, 0);\r\n        this.addToRef(spherical, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Adds the given spherical to the current spherical\r\n     * @param spherical the spherical to add\r\n     * @returns the current spherical\r\n     */\r\n    public addInPlace(spherical: Spherical) {\r\n        this.addToRef(spherical, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds the provided values to the current spherical\r\n     * @param radius the amount to add to the radius\r\n     * @param theta the amount to add to the theta\r\n     * @param phi the amount to add to the phi\r\n     * @returns the current spherical\r\n     */\r\n    public addInPlaceFromFloats(radius: number, theta: number, phi: number) {\r\n        this.radius += radius;\r\n        this.theta += theta;\r\n        this.phi += phi;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given Spherical from the current Spherical and stores the result\r\n     * @param spherical the spherical to subtract\r\n     * @param ref the spherical to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public subtractToRef(spherical: Spherical, ref: Spherical) {\r\n        ref.radius = this.radius - spherical.radius;\r\n        ref.theta = this.theta - spherical.theta;\r\n        ref.phi = this.phi - spherical.phi;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given Spherical from the current Spherical\r\n     * @param spherical the spherical to subtract\r\n     * @returns the difference spherical\r\n     */\r\n    public subtract(spherical: Spherical) {\r\n        const ref = new Spherical(0, 0, 0);\r\n        this.subtractToRef(spherical, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given Spherical from the current Spherical\r\n     * @param spherical the spherical to subtract\r\n     * @returns the current spherical\r\n     */\r\n    public subtractInPlace(spherical: Spherical) {\r\n        this.subtractToRef(spherical, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current spherical\r\n     * @param radius the amount to subtract from the radius\r\n     * @param theta the amount to subtract from the theta\r\n     * @param phi the amount to subtract from the phi\r\n     * @param ref the spherical to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public subtractFromFloatsToRef(radius: number, theta: number, phi: number, ref: Spherical) {\r\n        ref.radius = this.radius - radius;\r\n        ref.theta = this.theta - theta;\r\n        ref.phi = this.phi - phi;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Subtracts the given floats from the current spherical\r\n     * @param radius the amount to subtract from the radius\r\n     * @param theta the amount to subtract from the theta\r\n     * @param phi the amount to subtract from the phi\r\n     * @returns the difference spherical\r\n     */\r\n    public subtractFromFloats(radius: number, theta: number, phi: number) {\r\n        const ref = new Spherical(0, 0, 0);\r\n        this.subtractFromFloatsToRef(radius, theta, phi, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the given Spherical with the current Spherical and stores the result\r\n     * @param spherical the spherical to multiply\r\n     * @param ref the spherical to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public multiplyToRef(spherical: Spherical, ref: Spherical) {\r\n        ref.radius = this.radius * spherical.radius;\r\n        ref.theta = this.theta * spherical.theta;\r\n        ref.phi = this.phi * spherical.phi;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the given Spherical with the current Spherical\r\n     * @param spherical the spherical to multiply\r\n     * @returns the product spherical\r\n     */\r\n    public multiply(spherical: Spherical) {\r\n        const ref = new Spherical(0, 0, 0);\r\n        this.multiplyToRef(spherical, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Multiplies the given Spherical with the current Spherical\r\n     * @param spherical the spherical to multiply\r\n     * @returns the current spherical\r\n     */\r\n    public multiplyInPlace(spherical: Spherical) {\r\n        this.multiplyToRef(spherical, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Spherical by the given Spherical and stores the result\r\n     * @param spherical the spherical to divide\r\n     * @param ref the spherical to store the result in\r\n     * @returns the updated ref\r\n     */\r\n    public divideToRef(spherical: Spherical, ref: Spherical) {\r\n        ref.radius = this.radius / spherical.radius;\r\n        ref.theta = this.theta / spherical.theta;\r\n        ref.phi = this.phi / spherical.phi;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Spherical by the given Spherical\r\n     * @param spherical the spherical to divide\r\n     * @returns the quotient spherical\r\n     */\r\n    public divide(spherical: Spherical) {\r\n        const ref = new Spherical(0, 0, 0);\r\n        this.divideToRef(spherical, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Divides the current Spherical by the given Spherical\r\n     * @param spherical the spherical to divide\r\n     * @returns the current spherical\r\n     */\r\n    public divideInPlace(spherical: Spherical) {\r\n        this.divideToRef(spherical, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Clones the current spherical\r\n     * @returns a clone of the current spherical\r\n     */\r\n    public clone() {\r\n        return new Spherical(this.radius, this.theta, this.phi);\r\n    }\r\n\r\n    /**\r\n     * Copies the source spherical into the current spherical\r\n     * @param source the spherical to copy from\r\n     * @returns the current spherical\r\n     */\r\n    public copyFrom(source: Spherical) {\r\n        this.radius = source.radius;\r\n        this.theta = source.theta;\r\n        this.phi = source.phi;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Copies the given values into the current spherical\r\n     * @param radius the radius to use\r\n     * @param theta the theta to use\r\n     * @param phi the phi to use\r\n     * @returns the current spherical\r\n     */\r\n    public copyFromFloats(radius: number, theta: number, phi: number) {\r\n        this.radius = radius;\r\n        this.theta = theta;\r\n        this.phi = phi;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Scales the current spherical and stores the result\r\n     * @param scale defines the multiplication factor\r\n     * @param ref where to store the result\r\n     * @returns the updated ref\r\n     */\r\n    public scaleToRef(scale: number, ref: Spherical) {\r\n        ref.radius = this.radius * scale;\r\n        ref.theta = this.theta * scale;\r\n        ref.phi = this.phi * scale;\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Scales the current spherical and returns a new spherical with the scaled coordinates\r\n     * @param scale defines the multiplication factor\r\n     * @returns the scaled spherical\r\n     */\r\n    public scale(scale: number) {\r\n        const ref = new Spherical(0, 0, 0);\r\n        this.scaleToRef(scale, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Scales the current spherical\r\n     * @param scale defines the multiplication factor\r\n     * @returns the current spherical\r\n     */\r\n    public scaleInPlace(scale: number) {\r\n        this.scaleToRef(scale, this);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the values of the current spherical\r\n     * @param radius the new radius\r\n     * @param theta the new theta\r\n     * @param phi the new phi\r\n     * @returns the current spherical\r\n     */\r\n    public set(radius: number, theta: number, phi: number) {\r\n        this.radius = radius;\r\n        this.theta = theta;\r\n        this.phi = phi;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Sets the values of the current spherical\r\n     * @param value the new values\r\n     * @returns the current spherical\r\n     */\r\n    public setAll(value: number) {\r\n        this.set(value, value, value);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Assigns the rectangular coordinates of the current Spherical to a Vector3\r\n     * @param ref the Vector3 to update\r\n     * @returns the updated Vector3\r\n     */\r\n    public toVector3ToRef(ref: Vector3): Vector3 {\r\n        const x = this.radius * Math.sin(this.theta) * Math.cos(this.phi);\r\n        const y = this.radius * Math.cos(this.theta);\r\n        const z = this.radius * Math.sin(this.theta) * Math.sin(this.phi);\r\n        ref.set(x, y, z);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Gets a Vector3 from the current spherical coordinates\r\n     * @returns the (x, y,z) form of the current Spherical\r\n     */\r\n    public toVector3(): Vector3 {\r\n        const ref = new Vector3(0, 0, 0);\r\n        return this.toVector3ToRef(ref);\r\n    }\r\n\r\n    /**\r\n     * Assigns the spherical coordinates from a Vector3\r\n     * @param vector the vector to convert\r\n     * @param ref the Spherical to update\r\n     * @returns the updated ref\r\n     */\r\n    public static FromVector3ToRef(vector: DeepImmutable<Vector3>, ref: Spherical): Spherical {\r\n        ref.radius = vector.length();\r\n        ref.theta = Math.acos(vector.y / ref.radius);\r\n        ref.phi = Math.atan2(vector.z, vector.x);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Gets a Spherical from a Vector3\r\n     * @param vector defines the vector in (x, y, z) coordinate space\r\n     * @returns a new Spherical\r\n     */\r\n    public static FromVector3(vector: DeepImmutable<Vector3>): Spherical {\r\n        const spherical = new Spherical(0, 0, 0);\r\n        Spherical.FromVector3ToRef(vector, spherical);\r\n        return spherical;\r\n    }\r\n\r\n    /**\r\n     * Converts an array of floats to a spherical\r\n     * @param array the array to convert\r\n     * @returns the converted spherical\r\n     */\r\n    public static FromArray(array: number[]) {\r\n        return new Spherical(array[0], array[1], array[2]);\r\n    }\r\n}\r\n","import { type Tuple } from \"core/types\";\r\nimport { type IMatrixLike } from \"../math.like\";\r\n\r\n/**\r\n * A thin matrix class that is used for size reasons.\r\n * The class is identity by default\r\n */\r\nexport class ThinMatrix implements IMatrixLike {\r\n    private readonly _m: Tuple<number, 16> = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0];\r\n\r\n    /**\r\n     * Returns the matrix as a Array<number>\r\n     * @returns the matrix underlying array.\r\n     */\r\n    public asArray(): Tuple<number, 16> {\r\n        return this._m;\r\n    }\r\n\r\n    /**\r\n     * Gets the update flag of the matrix which is an unique number for the matrix.\r\n     * It will be incremented every time the matrix data change.\r\n     * You can use it to speed the comparison between two versions of the same matrix.\r\n     */\r\n    public updateFlag: number = 0;\r\n}\r\n","import { Clamp } from \"./math.scalar.functions\";\r\nimport { type DeepImmutable } from \"../types\";\r\nimport { type IEllipsoidLike, type ILatLonAltLike, type ILatLonLike } from \"./math.geospatial\";\r\nimport { type IVector3Like } from \"./math.like\";\r\nimport { Vector3FromFloatsToRef } from \"./math.vector.functions\";\r\n\r\nconst HalfPi = Math.PI / 2;\r\nconst DegreesToRadians = Math.PI / 180;\r\n\r\nconst EllipsoidFromSemiMajorAxisAndInverseFlattening = (semiMajorAxis: number, inverseFlattening: number): IEllipsoidLike => {\r\n    const flattening = 1 / inverseFlattening;\r\n    const semiMinorAxis = semiMajorAxis * (1 - flattening);\r\n    const firstEccentricitySquared = 2 * flattening - flattening * flattening;\r\n    const secondEccentricitySquared = firstEccentricitySquared / (1 - firstEccentricitySquared);\r\n    return { semiMajorAxis, semiMinorAxis, flattening, firstEccentricitySquared, secondEccentricitySquared };\r\n};\r\n\r\n/**\r\n * The WGS84 reference ellipsoid used for Earth-related geospatial functions.\r\n * Derived from the semi-major axis (meters) and the inverse flattening.\r\n */\r\nexport const Wgs84Ellipsoid: DeepImmutable<IEllipsoidLike> = Object.freeze(EllipsoidFromSemiMajorAxisAndInverseFlattening(6378137.0, 298.257223563));\r\n\r\n/**\r\n * Converts the latitude and longitude specified in degrees to an {@link ILatLonLike} in radians.\r\n * @param lat - The latitude in degrees\r\n * @param lon - The longitude in degrees\r\n * @param result - The resulting {@link ILatLonLike} in radians\r\n * @returns The resulting {@link ILatLonLike} in radians\r\n */\r\nexport function LatLonFromDegreesToRef<T extends ILatLonLike>(lat: number, lon: number, result: T): T {\r\n    result.lat = lat * DegreesToRadians;\r\n    result.lon = lon * DegreesToRadians;\r\n    return result;\r\n}\r\n\r\n/**\r\n * Computes the normal (up direction) in ECEF (Earth-Centered, Earth-Fixed) coordinates from the specified latitude and longitude in radians.\r\n * For the calculation, latitude is clamped to -PI/2 to PI/2.\r\n * @param latLon - The latitude and longitude in radians\r\n * @param result - The resulting normal\r\n * @returns The resulting normal\r\n */\r\nexport function LatLonToNormalToRef<T extends IVector3Like>(latLon: DeepImmutable<ILatLonLike>, result: T): T {\r\n    const lat = Clamp(latLon.lat, -HalfPi, HalfPi);\r\n    const cosLat = Math.cos(lat);\r\n    return Vector3FromFloatsToRef(cosLat * Math.cos(latLon.lon), cosLat * Math.sin(latLon.lon), Math.sin(lat), result);\r\n}\r\n\r\n/**\r\n * Converts latitude, longitude, and altitude to an ECEF (Earth-Centered, Earth-Fixed) position using the specified ellipsoid.\r\n * For the calculation, latitude is clamped to -PI/2 to PI/2.\r\n * @param latLonAlt - The latitude and longitude in radians, and the altitude relative to the reference ellipsoid's surface.\r\n * @param ellipsoid - Parameters for a reference ellipsoid (e.g., the {@link Wgs84Ellipsoid}).\r\n * @param result - The resulting ECEF position\r\n * @returns The resulting ECEF position\r\n */\r\nexport function EcefFromLatLonAltToRef<T extends IVector3Like>(\r\n    latLonAlt: DeepImmutable<ILatLonAltLike>,\r\n    ellipsoid: DeepImmutable<Pick<IEllipsoidLike, \"semiMajorAxis\" | \"firstEccentricitySquared\">>,\r\n    result: T\r\n): T {\r\n    const lat = Clamp(latLonAlt.lat, -HalfPi, HalfPi);\r\n    const { lon, alt } = latLonAlt;\r\n    const { semiMajorAxis, firstEccentricitySquared } = ellipsoid;\r\n    const sinLat = Math.sin(lat);\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const N = semiMajorAxis / Math.sqrt(1 - firstEccentricitySquared * sinLat * sinLat);\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    const NPlusAltTimesCosLat = (N + alt) * Math.cos(lat);\r\n    return Vector3FromFloatsToRef(NPlusAltTimesCosLat * Math.cos(lon), NPlusAltTimesCosLat * Math.sin(lon), (N * (1 - firstEccentricitySquared) + alt) * sinLat, result);\r\n}\r\n","import { type AbstractMesh, type PickingInfo } from \"core/index\";\r\nimport { Vector3, TmpVectors, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EnumerateFloatValues } from \"core/Buffers/bufferUtils\";\r\n\r\n/**\r\n * Data for mesh hotspot computation\r\n */\r\nexport type HotSpotQuery = {\r\n    /**\r\n     * 3 point indices\r\n     */\r\n    pointIndex: [number, number, number];\r\n    /**\r\n     * 3 barycentric coordinates\r\n     */\r\n    barycentric: [number, number, number];\r\n};\r\n\r\n/**\r\n * Create a HotSpotQuery from a picking info\r\n * @remarks If there is no pickedMesh or the pickedMesh has no indices, the faceId is used as the base index\r\n * @param pickingInfo picking info to use\r\n * @returns the created HotSpotQuery\r\n */\r\nexport function CreateHotSpotQueryForPickingInfo(pickingInfo: PickingInfo): HotSpotQuery {\r\n    const indices = pickingInfo.pickedMesh?.getIndices();\r\n    const base = pickingInfo.faceId * 3;\r\n\r\n    return {\r\n        pointIndex: indices ? [indices[base], indices[base + 1], indices[base + 2]] : [base, base + 1, base + 2],\r\n        barycentric: [pickingInfo.bu, pickingInfo.bv, 1 - pickingInfo.bu - pickingInfo.bv],\r\n    };\r\n}\r\n\r\nfunction GetVertexElementData(mesh: AbstractMesh, index: number, kind: string) {\r\n    const vertexBuffer = mesh.getVertexBuffer(kind);\r\n    if (!vertexBuffer) {\r\n        return null;\r\n    }\r\n\r\n    const bufferData = vertexBuffer.getData();\r\n    if (!bufferData) {\r\n        return null;\r\n    }\r\n\r\n    // EnumerateFloatValues synchronously calls the callback, hence the non-null assertion.\r\n    let values!: number[];\r\n    EnumerateFloatValues(\r\n        bufferData,\r\n        vertexBuffer.byteStride * index,\r\n        vertexBuffer.byteStride,\r\n        vertexBuffer.getSize(),\r\n        vertexBuffer.type,\r\n        1, // Request only a single element.\r\n        vertexBuffer.normalized,\r\n        (v) => (values = v)\r\n    );\r\n\r\n    return values;\r\n}\r\n\r\n/**\r\n * Return a transformed local position from a mesh and vertex index\r\n * @param mesh mesh used to get vertex array from\r\n * @param index vertex index\r\n * @param res resulting local position\r\n * @returns false if it was not possible to compute the position for that vertex\r\n */\r\nexport function GetTransformedPosition(mesh: AbstractMesh, index: number, res: Vector3): boolean {\r\n    const positions = GetVertexElementData(mesh, index, VertexBuffer.PositionKind);\r\n    if (!positions) {\r\n        return false;\r\n    }\r\n\r\n    if (positions.some((value) => isNaN(value ?? Number.NaN))) {\r\n        return false;\r\n    }\r\n\r\n    if (mesh.morphTargetManager) {\r\n        const base = index * 3;\r\n        for (let i = 0; i < positions.length; i++) {\r\n            let value = positions[i];\r\n            for (let targetCount = 0; targetCount < mesh.morphTargetManager.numTargets; targetCount++) {\r\n                const target = mesh.morphTargetManager.getTarget(targetCount);\r\n                const influence = target.influence;\r\n                if (influence !== 0) {\r\n                    const targetData = target.getPositions();\r\n                    if (targetData) {\r\n                        value += (targetData[base + i] - positions[i]) * influence;\r\n                    }\r\n                }\r\n            }\r\n            positions[i] = value;\r\n        }\r\n    }\r\n\r\n    res.fromArray(positions);\r\n\r\n    if (mesh.skeleton) {\r\n        const matricesIndicesData = GetVertexElementData(mesh, index, VertexBuffer.MatricesIndicesKind);\r\n        const matricesWeightsData = GetVertexElementData(mesh, index, VertexBuffer.MatricesWeightsKind);\r\n        if (matricesIndicesData && matricesWeightsData) {\r\n            const needExtras = mesh.numBoneInfluencers > 4;\r\n            const matricesIndicesExtraData = needExtras ? GetVertexElementData(mesh, index, VertexBuffer.MatricesIndicesExtraKind) : null;\r\n            const matricesWeightsExtraData = needExtras ? GetVertexElementData(mesh, index, VertexBuffer.MatricesWeightsExtraKind) : null;\r\n            const skeletonMatrices = mesh.skeleton.getTransformMatrices(mesh);\r\n\r\n            const finalMatrix = TmpVectors.Matrix[0];\r\n            const tempMatrix = TmpVectors.Matrix[1];\r\n\r\n            finalMatrix.reset();\r\n\r\n            for (let i = 0; i < matricesWeightsData.length; i++) {\r\n                const weight = matricesWeightsData[i];\r\n                if (weight > 0) {\r\n                    Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[i] * 16), weight, tempMatrix);\r\n                    finalMatrix.addToSelf(tempMatrix);\r\n                }\r\n            }\r\n            if (matricesIndicesExtraData && matricesWeightsExtraData) {\r\n                for (let i = 0; i < matricesWeightsExtraData.length; i++) {\r\n                    const weight = matricesWeightsExtraData[i];\r\n                    if (weight > 0) {\r\n                        Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[i] * 16), weight, tempMatrix);\r\n                        finalMatrix.addToSelf(tempMatrix);\r\n                    }\r\n                }\r\n            }\r\n\r\n            Vector3.TransformCoordinatesFromFloatsToRef(positions[0], positions[1], positions[2], finalMatrix, res);\r\n        }\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\n/**\r\n * Compute a world space hotspot position\r\n * TmpVectors.Vector3[0..4] are modified by this function. Do not use them as result output.\r\n * @param mesh mesh used to get hotspot from\r\n * @param hotSpotQuery point indices and barycentric\r\n * @param resPosition output world position\r\n * @param resNormal optional output world normal\r\n * @returns false if it was not possible to compute the hotspot position\r\n */\r\nexport function GetHotSpotToRef(mesh: AbstractMesh, hotSpotQuery: HotSpotQuery, resPosition: Vector3, resNormal?: Vector3): boolean {\r\n    resPosition.set(0, 0, 0);\r\n    for (let i = 0; i < 3; i++) {\r\n        const index = hotSpotQuery.pointIndex[i];\r\n        if (!GetTransformedPosition(mesh, index, TmpVectors.Vector3[i])) {\r\n            return false;\r\n        }\r\n        TmpVectors.Vector3[i].scaleAndAddToRef(hotSpotQuery.barycentric[i], resPosition);\r\n    }\r\n\r\n    // Convert the result to world space\r\n    Vector3.TransformCoordinatesToRef(resPosition, mesh.getWorldMatrix(), resPosition);\r\n\r\n    // compute normal in world space\r\n    if (resNormal) {\r\n        const pointA = TmpVectors.Vector3[0];\r\n        const pointB = TmpVectors.Vector3[1];\r\n        const pointC = TmpVectors.Vector3[2];\r\n        const segmentA = TmpVectors.Vector3[3];\r\n        const segmentB = TmpVectors.Vector3[4];\r\n        segmentA.copyFrom(pointB);\r\n        segmentA.subtractInPlace(pointA);\r\n        segmentB.copyFrom(pointC);\r\n        segmentB.subtractInPlace(pointA);\r\n        segmentA.normalize();\r\n        segmentB.normalize();\r\n        Vector3.CrossToRef(segmentA, segmentB, resNormal);\r\n\r\n        // flip normal when face culling is changed\r\n        const flipNormal =\r\n            mesh.material &&\r\n            mesh.material.sideOrientation ===\r\n                (mesh.getScene().useRightHandedSystem ? Constants.MATERIAL_ClockWiseSideOrientation : Constants.MATERIAL_CounterClockWiseSideOrientation);\r\n\r\n        if (flipNormal) {\r\n            resNormal.scaleInPlace(-1);\r\n        }\r\n\r\n        // Convert the result to world space\r\n        Vector3.TransformNormalToRef(resNormal, mesh.getWorldMatrix(), resNormal);\r\n        resNormal.normalize();\r\n    }\r\n\r\n    return true;\r\n}\r\n","import { type Nullable, type TypedArray, type TypedArrayConstructor } from \"core/types\";\r\nimport { type EncoderMessage, type IDracoAttributeData, type IDracoEncodedMeshData, type IDracoEncoderOptions } from \"./dracoEncoder.types\";\r\nimport { type DecoderMessage } from \"./dracoDecoder.types\";\r\nimport {\r\n    type DecoderBuffer,\r\n    type Decoder,\r\n    type Mesh,\r\n    type PointCloud,\r\n    type Status,\r\n    type DecoderModule,\r\n    type EncoderModule,\r\n    type MeshBuilder,\r\n    type Encoder,\r\n    type DracoInt8Array,\r\n    DracoDecoderModule,\r\n} from \"draco3dgltf\";\r\nimport { type VertexDataTypedArray } from \"core/Buffers/bufferUtils\";\r\n\r\ndeclare let DracoDecoderModule: DracoDecoderModule;\r\ndeclare let DracoEncoderModule: (props: { wasmBinary?: ArrayBuffer }) => Promise<EncoderModule>;\r\n\r\ninterface IInitDoneMessage {\r\n    id: \"initDone\";\r\n}\r\n\r\n// WorkerGlobalScope\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare function importScripts(...urls: string[]): void;\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare function postMessage(message: IInitDoneMessage | DecoderMessage | EncoderMessage, transfer?: ArrayBufferLike[]): void;\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function EncodeMesh(\r\n    module: unknown /** EncoderModule */,\r\n    attributes: Array<IDracoAttributeData>,\r\n    indices: Nullable<Uint16Array | Uint32Array>,\r\n    options: IDracoEncoderOptions\r\n): IDracoEncodedMeshData {\r\n    const encoderModule = module as EncoderModule;\r\n    let encoder: Nullable<Encoder> = null;\r\n    let meshBuilder: Nullable<MeshBuilder> = null;\r\n    let mesh: Nullable<Mesh> = null;\r\n    let encodedNativeBuffer: Nullable<DracoInt8Array> = null;\r\n    const attributeIDs: Record<string, number> = {}; // Babylon kind -> Draco unique id\r\n\r\n    // Double-check that at least a position attribute is provided\r\n    const positionAttribute = attributes.find((a) => a.dracoName === \"POSITION\");\r\n    if (!positionAttribute) {\r\n        throw new Error(\"Draco: Missing position attribute for encoding.\");\r\n    }\r\n\r\n    // If no indices are provided, assume mesh is unindexed. Let's generate them, since Draco meshes require them.\r\n    // TODO: This may be the POINT_CLOUD case, but need to investigate. Should work for now-- just less efficient.\r\n    if (!indices) {\r\n        // Assume position attribute is the largest attribute.\r\n        const positionVerticesCount = positionAttribute.data.length / positionAttribute.size;\r\n        indices = new (positionVerticesCount > 65535 ? Uint32Array : Uint16Array)(positionVerticesCount);\r\n        for (let i = 0; i < positionVerticesCount; i++) {\r\n            indices[i] = i;\r\n        }\r\n    }\r\n\r\n    try {\r\n        encoder = new encoderModule.Encoder();\r\n        meshBuilder = new encoderModule.MeshBuilder();\r\n        mesh = new encoderModule.Mesh();\r\n\r\n        // Add the faces\r\n        meshBuilder.AddFacesToMesh(mesh, indices.length / 3, indices);\r\n\r\n        const addAttributeMap = new Map<\r\n            Function,\r\n            (builder: MeshBuilder, mesh: Mesh, attr: any, count: number, size: number, data: Exclude<VertexDataTypedArray, Uint8ClampedArray>) => number\r\n        >([\r\n            [Float32Array, (mb, m, a, c, s, d) => mb.AddFloatAttribute(m, a, c, s, d)],\r\n            [Uint32Array, (mb, m, a, c, s, d) => mb.AddUInt32Attribute(m, a, c, s, d)],\r\n            [Uint16Array, (mb, m, a, c, s, d) => mb.AddUInt16Attribute(m, a, c, s, d)],\r\n            [Uint8Array, (mb, m, a, c, s, d) => mb.AddUInt8Attribute(m, a, c, s, d)],\r\n            [Int32Array, (mb, m, a, c, s, d) => mb.AddInt32Attribute(m, a, c, s, d)],\r\n            [Int16Array, (mb, m, a, c, s, d) => mb.AddInt16Attribute(m, a, c, s, d)],\r\n            [Int8Array, (mb, m, a, c, s, d) => mb.AddInt8Attribute(m, a, c, s, d)],\r\n        ]);\r\n\r\n        // Add the attributes\r\n        for (const attribute of attributes) {\r\n            if (attribute.data instanceof Uint8ClampedArray) {\r\n                attribute.data = new Uint8Array(attribute.data); // Draco does not support Uint8ClampedArray\r\n            }\r\n            const addAttribute = addAttributeMap.get(attribute.data.constructor)!;\r\n            const verticesCount = attribute.data.length / attribute.size;\r\n            attributeIDs[attribute.kind] = addAttribute(meshBuilder, mesh, encoderModule[attribute.dracoName], verticesCount, attribute.size, attribute.data);\r\n            if (options.quantizationBits && options.quantizationBits[attribute.dracoName]) {\r\n                encoder.SetAttributeQuantization(encoderModule[attribute.dracoName], options.quantizationBits[attribute.dracoName]);\r\n            }\r\n        }\r\n\r\n        // Set the options\r\n        if (options.method) {\r\n            encoder.SetEncodingMethod(encoderModule[options.method]);\r\n        }\r\n        if (options.encodeSpeed !== undefined && options.decodeSpeed !== undefined) {\r\n            encoder.SetSpeedOptions(options.encodeSpeed, options.decodeSpeed);\r\n        }\r\n\r\n        // Encode to native buffer\r\n        encodedNativeBuffer = new encoderModule.DracoInt8Array();\r\n        const encodedLength = encoder.EncodeMeshToDracoBuffer(mesh, encodedNativeBuffer);\r\n        if (encodedLength <= 0) {\r\n            throw new Error(\"Draco: Failed to encode.\");\r\n        }\r\n\r\n        // Copy the native buffer data to worker heap\r\n        const encodedData = new Int8Array(encodedLength);\r\n        for (let i = 0; i < encodedLength; i++) {\r\n            encodedData[i] = encodedNativeBuffer.GetValue(i);\r\n        }\r\n\r\n        return { data: encodedData, attributeIds: attributeIDs };\r\n    } finally {\r\n        if (mesh) {\r\n            encoderModule.destroy(mesh);\r\n        }\r\n        if (meshBuilder) {\r\n            encoderModule.destroy(meshBuilder);\r\n        }\r\n        if (encoder) {\r\n            encoderModule.destroy(encoder);\r\n        }\r\n        if (encodedNativeBuffer) {\r\n            encoderModule.destroy(encodedNativeBuffer);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * The worker function that gets converted to a blob url to pass into a worker.\r\n * To be used if a developer wants to create their own worker instance and inject it instead of using the default worker.\r\n */\r\nexport function EncoderWorkerFunction(): void {\r\n    let encoderPromise: Promise<EncoderModule> | undefined;\r\n\r\n    onmessage = (event) => {\r\n        const message = event.data;\r\n        switch (message.id) {\r\n            case \"init\": {\r\n                // if URL is provided then load the script. Otherwise expect the script to be loaded already\r\n                if (message.url) {\r\n                    importScripts(message.url);\r\n                }\r\n                const initEncoderObject = message.wasmBinary ? { wasmBinary: message.wasmBinary } : {};\r\n                encoderPromise = DracoEncoderModule(initEncoderObject);\r\n                postMessage({ id: \"initDone\" });\r\n                break;\r\n            }\r\n            case \"encodeMesh\": {\r\n                if (!encoderPromise) {\r\n                    throw new Error(\"Draco: Encoder module is not available.\");\r\n                }\r\n                encoderPromise\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((encoder) => {\r\n                        const result = EncodeMesh(encoder, message.attributes, message.indices, message.options);\r\n                        postMessage({ id: \"encodeMeshSuccess\", encodedMeshData: result }, result ? [result.data.buffer] : undefined);\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch((error) => {\r\n                        postMessage({ id: \"encodeMeshError\", errorMessage: error.message });\r\n                    });\r\n                break;\r\n            }\r\n        }\r\n    };\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function DecodeMesh(\r\n    module: unknown /** DecoderModule */,\r\n    data: Int8Array,\r\n    attributeIDs: Record<string, number> | undefined,\r\n    onIndicesData: (indices: Uint16Array | Uint32Array) => void,\r\n    onAttributeData: (kind: string, data: ArrayBufferView, size: number, offset: number, stride: number, normalized: boolean) => void\r\n): number {\r\n    const decoderModule = module as DecoderModule;\r\n    let decoder: Nullable<Decoder> = null;\r\n    let buffer: Nullable<DecoderBuffer> = null;\r\n    let geometry: Nullable<Mesh | PointCloud> = null;\r\n\r\n    try {\r\n        decoder = new decoderModule.Decoder();\r\n\r\n        buffer = new decoderModule.DecoderBuffer();\r\n        buffer.Init(data, data.byteLength);\r\n\r\n        let status: Status;\r\n        const type = decoder.GetEncodedGeometryType(buffer);\r\n        switch (type) {\r\n            case decoderModule.TRIANGULAR_MESH: {\r\n                const mesh = new decoderModule.Mesh();\r\n                status = decoder.DecodeBufferToMesh(buffer, mesh);\r\n                if (!status.ok() || mesh.ptr === 0) {\r\n                    throw new Error(status.error_msg());\r\n                }\r\n\r\n                const numFaces = mesh.num_faces();\r\n                const numIndices = numFaces * 3;\r\n                const byteLength = numIndices * 4;\r\n\r\n                const ptr = decoderModule._malloc(byteLength);\r\n                try {\r\n                    decoder.GetTrianglesUInt32Array(mesh, byteLength, ptr);\r\n                    const indices = new Uint32Array(numIndices);\r\n                    indices.set(new Uint32Array(decoderModule.HEAPF32.buffer, ptr, numIndices));\r\n                    onIndicesData(indices);\r\n                } finally {\r\n                    decoderModule._free(ptr);\r\n                }\r\n\r\n                geometry = mesh;\r\n                break;\r\n            }\r\n            case decoderModule.POINT_CLOUD: {\r\n                const pointCloud = new decoderModule.PointCloud();\r\n                status = decoder.DecodeBufferToPointCloud(buffer, pointCloud);\r\n                if (!status.ok() || !pointCloud.ptr) {\r\n                    throw new Error(status.error_msg());\r\n                }\r\n\r\n                geometry = pointCloud;\r\n                break;\r\n            }\r\n            default: {\r\n                throw new Error(`Draco: Cannot decode invalid geometry type ${type}`);\r\n            }\r\n        }\r\n\r\n        const numPoints = geometry.num_points();\r\n\r\n        const processAttribute = (decoder: Decoder, geometry: Mesh | PointCloud, kind: string, attribute: any /** Attribute */) => {\r\n            const dataType = attribute.data_type();\r\n            const numComponents = attribute.num_components();\r\n            const normalized = attribute.normalized();\r\n            const byteStride = attribute.byte_stride();\r\n            const byteOffset = attribute.byte_offset();\r\n\r\n            const dataTypeInfo: Record<number, { typedArrayConstructor: TypedArrayConstructor; heap: TypedArray }> = {\r\n                [decoderModule.DT_FLOAT32]: { typedArrayConstructor: Float32Array, heap: decoderModule.HEAPF32 },\r\n                [decoderModule.DT_INT8]: { typedArrayConstructor: Int8Array, heap: decoderModule.HEAP8 },\r\n                [decoderModule.DT_INT16]: { typedArrayConstructor: Int16Array, heap: decoderModule.HEAP16 },\r\n                [decoderModule.DT_INT32]: { typedArrayConstructor: Int32Array, heap: decoderModule.HEAP32 },\r\n                [decoderModule.DT_UINT8]: { typedArrayConstructor: Uint8Array, heap: decoderModule.HEAPU8 },\r\n                [decoderModule.DT_UINT16]: { typedArrayConstructor: Uint16Array, heap: decoderModule.HEAPU16 },\r\n                [decoderModule.DT_UINT32]: { typedArrayConstructor: Uint32Array, heap: decoderModule.HEAPU32 },\r\n            };\r\n\r\n            const info = dataTypeInfo[dataType];\r\n            if (!info) {\r\n                throw new Error(`Draco: Cannot decode invalid data type ${dataType}`);\r\n            }\r\n\r\n            const numValues = numPoints * numComponents;\r\n            const byteLength = numValues * info.typedArrayConstructor.BYTES_PER_ELEMENT;\r\n\r\n            const ptr = decoderModule._malloc(byteLength);\r\n            try {\r\n                decoder.GetAttributeDataArrayForAllPoints(geometry, attribute, dataType, byteLength, ptr);\r\n                const data = new info.typedArrayConstructor(info.heap.buffer, ptr, numValues);\r\n                onAttributeData(kind, data.slice(), numComponents, byteOffset, byteStride, normalized);\r\n            } finally {\r\n                decoderModule._free(ptr);\r\n            }\r\n        };\r\n\r\n        if (attributeIDs) {\r\n            for (const kind in attributeIDs) {\r\n                const id = attributeIDs[kind];\r\n                const attribute = decoder.GetAttributeByUniqueId(geometry, id);\r\n                processAttribute(decoder, geometry, kind, attribute);\r\n            }\r\n        } else {\r\n            const dracoAttributeTypes: Record<string, number> = {\r\n                position: decoderModule.POSITION,\r\n                normal: decoderModule.NORMAL,\r\n                color: decoderModule.COLOR,\r\n                uv: decoderModule.TEX_COORD,\r\n            };\r\n\r\n            for (const kind in dracoAttributeTypes) {\r\n                const id = decoder.GetAttributeId(geometry, dracoAttributeTypes[kind]);\r\n                if (id !== -1) {\r\n                    const attribute = decoder.GetAttribute(geometry, id);\r\n                    processAttribute(decoder, geometry, kind, attribute);\r\n                }\r\n            }\r\n        }\r\n\r\n        return numPoints;\r\n    } finally {\r\n        if (geometry) {\r\n            decoderModule.destroy(geometry);\r\n        }\r\n\r\n        if (buffer) {\r\n            decoderModule.destroy(buffer);\r\n        }\r\n\r\n        if (decoder) {\r\n            decoderModule.destroy(decoder);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * The worker function that gets converted to a blob url to pass into a worker.\r\n * To be used if a developer wants to create their own worker instance and inject it instead of using the default worker.\r\n */\r\nexport function DecoderWorkerFunction(): void {\r\n    let decoderPromise: PromiseLike<DecoderModule> | undefined;\r\n\r\n    onmessage = (event) => {\r\n        const message = event.data;\r\n        switch (message.id) {\r\n            case \"init\": {\r\n                // if URL is provided then load the script. Otherwise expect the script to be loaded already\r\n                if (message.url) {\r\n                    importScripts(message.url);\r\n                }\r\n                const initDecoderObject = message.wasmBinary ? { wasmBinary: message.wasmBinary } : {};\r\n                decoderPromise = DracoDecoderModule(initDecoderObject);\r\n                postMessage({ id: \"initDone\" });\r\n                break;\r\n            }\r\n            case \"decodeMesh\": {\r\n                if (!decoderPromise) {\r\n                    throw new Error(\"Draco: Decoder module is not available\");\r\n                }\r\n                // eslint-disable-next-line github/no-then\r\n                decoderPromise.then((decoder) => {\r\n                    const numPoints = DecodeMesh(\r\n                        decoder,\r\n                        message.dataView,\r\n                        message.attributes,\r\n                        (indices) => {\r\n                            postMessage({ id: \"indices\", data: indices }, [indices.buffer]);\r\n                        },\r\n                        (kind, data, size, offset, stride, normalized) => {\r\n                            postMessage({ id: \"attribute\", kind, data, size, byteOffset: offset, byteStride: stride, normalized }, [data.buffer]);\r\n                        }\r\n                    );\r\n                    postMessage({ id: \"decodeMeshDone\", totalVertices: numPoints });\r\n                });\r\n                break;\r\n            }\r\n        }\r\n    };\r\n}\r\n\r\n// For backwards compatibility\r\nexport { DecoderWorkerFunction as workerFunction };\r\n\r\n/**\r\n * Initializes a worker that was created for the draco agent pool\r\n * @param worker  The worker to initialize\r\n * @param wasmBinary The wasm binary to load into the worker\r\n * @param moduleUrl The url to the draco decoder module (optional)\r\n * @returns A promise that resolves when the worker is initialized\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport async function initializeWebWorker(worker: Worker, wasmBinary?: ArrayBuffer, moduleUrl?: string): Promise<Worker> {\r\n    return await new Promise<Worker>((resolve, reject) => {\r\n        const onError = (error: ErrorEvent) => {\r\n            worker.removeEventListener(\"error\", onError);\r\n            worker.removeEventListener(\"message\", onMessage);\r\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n            reject(error);\r\n        };\r\n\r\n        const onMessage = (event: MessageEvent<IInitDoneMessage>) => {\r\n            if (event.data.id === \"initDone\") {\r\n                worker.removeEventListener(\"error\", onError);\r\n                worker.removeEventListener(\"message\", onMessage);\r\n                resolve(worker);\r\n            }\r\n        };\r\n\r\n        worker.addEventListener(\"error\", onError);\r\n        worker.addEventListener(\"message\", onMessage);\r\n\r\n        // Load with either JS-only or WASM version\r\n        if (!wasmBinary) {\r\n            worker.postMessage({\r\n                id: \"init\",\r\n                url: moduleUrl,\r\n            });\r\n        } else {\r\n            // clone the array buffer to make it transferable\r\n            const clone = wasmBinary.slice(0);\r\n            worker.postMessage(\r\n                {\r\n                    id: \"init\",\r\n                    url: moduleUrl,\r\n                    wasmBinary: clone,\r\n                },\r\n                [clone]\r\n            );\r\n        }\r\n        // note: no transfer list as the ArrayBuffer is shared across main thread and pool workers\r\n    });\r\n}\r\n","import { Tools } from \"../../Misc/tools.pure\";\r\nimport { AutoReleaseWorkerPool, type WorkerPool } from \"../../Misc/workerPool\";\r\nimport { type IDisposable } from \"../../scene\";\r\nimport { initializeWebWorker } from \"./dracoCompressionWorker\";\r\n\r\n/**\r\n * Configuration for using a Draco codec.\r\n */\r\nexport interface IDracoCodecConfiguration {\r\n    /**\r\n     * The url to the WebAssembly module.\r\n     */\r\n    wasmUrl?: string;\r\n\r\n    /**\r\n     * The url to the WebAssembly binary.\r\n     */\r\n    wasmBinaryUrl?: string;\r\n\r\n    /**\r\n     * The url to the fallback JavaScript module.\r\n     */\r\n    fallbackUrl?: string;\r\n\r\n    /**\r\n     * The number of workers for async operations. Specify `0` to disable web workers and run synchronously in the current context.\r\n     */\r\n    numWorkers?: number;\r\n\r\n    /**\r\n     * Optional worker pool to use for async encoding/decoding.\r\n     * If provided, the worker pool will be used as is: no Draco scripts will be loaded, and numWorkers will be ignored.\r\n     */\r\n    workerPool?: WorkerPool;\r\n\r\n    /**\r\n     * Optional ArrayBuffer of the WebAssembly binary.\r\n     * If provided it will be used instead of loading the binary from wasmBinaryUrl.\r\n     */\r\n    wasmBinary?: ArrayBuffer;\r\n\r\n    /**\r\n     * The codec module if already available.\r\n     */\r\n    jsModule?: unknown /* DracoDecoderModule | DracoEncoderModule */;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _GetDefaultNumWorkers(): number {\r\n    if (typeof navigator !== \"object\" || !navigator.hardwareConcurrency) {\r\n        return 1;\r\n    }\r\n\r\n    // Use 50% of the available logical processors but capped at 4.\r\n    return Math.min(Math.floor(navigator.hardwareConcurrency * 0.5), 4);\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function _IsConfigurationAvailable(config: IDracoCodecConfiguration): boolean {\r\n    return !!((config.wasmUrl && (config.wasmBinary || config.wasmBinaryUrl) && typeof WebAssembly === \"object\") || config.fallbackUrl);\r\n    // TODO: Account for jsModule\r\n}\r\n\r\n/**\r\n * Base class for a Draco codec.\r\n * @internal\r\n */\r\nexport abstract class DracoCodec implements IDisposable {\r\n    protected _workerPoolPromise?: Promise<WorkerPool>;\r\n    protected _modulePromise?: Promise<{ module: unknown /** DecoderModule | EncoderModule */ }>;\r\n\r\n    /**\r\n     * Checks if the default codec JS module is in scope.\r\n     */\r\n    protected abstract _isModuleAvailable(): boolean;\r\n\r\n    /**\r\n     * Creates the JS Module for the corresponding wasm.\r\n     */\r\n    protected abstract _createModuleAsync(\r\n        wasmBinary?: ArrayBuffer,\r\n        jsModule?: unknown /** DracoDecoderModule | DracoEncoderModule */\r\n    ): Promise<{ module: unknown /** DecoderModule | EncoderModule */ }>;\r\n\r\n    /**\r\n     * Returns the worker content.\r\n     */\r\n    protected abstract _getWorkerContent(): string;\r\n\r\n    /**\r\n     * Constructor\r\n     * @param configuration The configuration for the DracoCodec instance.\r\n     */\r\n    constructor(configuration: IDracoCodecConfiguration) {\r\n        // check if the codec binary and worker pool was injected\r\n        // Note - it is expected that the developer checked if WebWorker, WebAssembly and the URL object are available\r\n        if (configuration.workerPool) {\r\n            // Set the promise accordingly\r\n            this._workerPoolPromise = Promise.resolve(configuration.workerPool);\r\n            return;\r\n        }\r\n\r\n        // to avoid making big changes to the code here, if wasmBinary is provided use it in the wasmBinaryPromise\r\n        const wasmBinaryProvided = configuration.wasmBinary;\r\n        const numberOfWorkers = configuration.numWorkers ?? _GetDefaultNumWorkers();\r\n        const useWorkers = numberOfWorkers && typeof Worker === \"function\" && typeof URL === \"function\";\r\n        const urlNeeded = useWorkers || !configuration.jsModule;\r\n        // code maintained here for back-compat with no changes\r\n\r\n        const codecInfo: { url: string | undefined; wasmBinaryPromise: Promise<ArrayBuffer | undefined> } =\r\n            configuration.wasmUrl && configuration.wasmBinaryUrl && typeof WebAssembly === \"object\"\r\n                ? {\r\n                      url: urlNeeded ? Tools.GetBabylonScriptURL(configuration.wasmUrl, true) : \"\",\r\n                      wasmBinaryPromise: wasmBinaryProvided\r\n                          ? Promise.resolve(wasmBinaryProvided)\r\n                          : Tools.LoadFileAsync(Tools.GetBabylonScriptURL(configuration.wasmBinaryUrl, true)),\r\n                  }\r\n                : {\r\n                      url: urlNeeded ? Tools.GetBabylonScriptURL(configuration.fallbackUrl!) : \"\",\r\n                      wasmBinaryPromise: Promise.resolve(undefined),\r\n                  };\r\n        // If using workers, initialize a worker pool with either the wasm or url?\r\n        if (useWorkers) {\r\n            // eslint-disable-next-line github/no-then\r\n            this._workerPoolPromise = codecInfo.wasmBinaryPromise.then((wasmBinary) => {\r\n                const workerContent = this._getWorkerContent();\r\n                const workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: \"application/javascript\" }));\r\n\r\n                // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n                return new AutoReleaseWorkerPool(numberOfWorkers, () => {\r\n                    const worker = new Worker(workerBlobUrl);\r\n                    return initializeWebWorker(worker, wasmBinary, codecInfo.url);\r\n                });\r\n            });\r\n        } else {\r\n            // eslint-disable-next-line github/no-then\r\n            this._modulePromise = codecInfo.wasmBinaryPromise.then(async (wasmBinary) => {\r\n                if (!this._isModuleAvailable()) {\r\n                    if (!configuration.jsModule) {\r\n                        if (!codecInfo.url) {\r\n                            throw new Error(\"Draco codec module is not available\");\r\n                        }\r\n                        await Tools.LoadBabylonScriptAsync(codecInfo.url);\r\n                    }\r\n                }\r\n                return await this._createModuleAsync(wasmBinary as ArrayBuffer, configuration.jsModule);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves when ready. Call this manually to ensure the draco codec is ready before use.\r\n     * @returns a promise that resolves when ready\r\n     */\r\n    public async whenReadyAsync(): Promise<void> {\r\n        if (this._workerPoolPromise) {\r\n            await this._workerPoolPromise;\r\n            return;\r\n        }\r\n\r\n        if (this._modulePromise) {\r\n            await this._modulePromise;\r\n            return;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stop all async operations and release resources.\r\n     */\r\n    public dispose(): void {\r\n        if (this._workerPoolPromise) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            this._workerPoolPromise.then((workerPool) => {\r\n                workerPool.dispose();\r\n            });\r\n        }\r\n\r\n        delete this._workerPoolPromise;\r\n        delete this._modulePromise;\r\n    }\r\n}\r\n","import { DracoDecoderModule } from \"draco3dgltf\";\r\nimport { _IsConfigurationAvailable, DracoCodec, type IDracoCodecConfiguration } from \"./dracoCodec\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { Geometry } from \"../geometry\";\r\nimport { VertexBuffer } from \"../buffer\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { DecodeMesh, DecoderWorkerFunction } from \"./dracoCompressionWorker\";\r\nimport { type IAttributeData, type MeshData, type DecoderMessage } from \"./dracoDecoder.types\";\r\n\r\ndeclare let DracoDecoderModule: DracoDecoderModule;\r\n\r\n/**\r\n * @experimental This class is an experimental version of `DracoCompression` and is subject to change.\r\n *\r\n * Draco Decoder (https://google.github.io/draco/)\r\n *\r\n * This class wraps the Draco decoder module.\r\n *\r\n * By default, the configuration points to a copy of the Draco decoder files for glTF from the Babylon.js cdn https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js.\r\n *\r\n * To update the configuration, use the following code:\r\n * ```javascript\r\n *     DracoDecoder.DefaultConfiguration = {\r\n *          wasmUrl: \"<url to the WebAssembly library>\",\r\n *          wasmBinaryUrl: \"<url to the WebAssembly binary>\",\r\n *          fallbackUrl: \"<url to the fallback JavaScript library>\",\r\n *     };\r\n * ```\r\n *\r\n * Draco has two versions, one for WebAssembly and one for JavaScript. The decoder configuration can be set to only support WebAssembly or only support the JavaScript version.\r\n * Decoding will automatically fallback to the JavaScript version if WebAssembly version is not configured or if WebAssembly is not supported by the browser.\r\n * Use `DracoDecoder.DefaultAvailable` to determine if the decoder configuration is available for the current context.\r\n *\r\n * To decode Draco compressed data, get the default DracoDecoder object and call decodeMeshToGeometryAsync:\r\n * ```javascript\r\n *     var geometry = await DracoDecoder.Default.decodeMeshToGeometryAsync(data);\r\n * ```\r\n */\r\nexport class DracoDecoder extends DracoCodec {\r\n    /**\r\n     * Default configuration for the DracoDecoder. Defaults to the following:\r\n     * - numWorkers: 50% of the available logical processors, capped to 4. If no logical processors are available, defaults to 1.\r\n     * - wasmUrl: `\"https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js\"`\r\n     * - wasmBinaryUrl: `\"https://cdn.babylonjs.com/draco_decoder_gltf.wasm\"`\r\n     * - fallbackUrl: `\"https://cdn.babylonjs.com/draco_decoder_gltf.js\"`\r\n     */\r\n    public static DefaultConfiguration: IDracoCodecConfiguration = {\r\n        wasmUrl: `${Tools._DefaultCdnUrl}/draco_wasm_wrapper_gltf.js`,\r\n        wasmBinaryUrl: `${Tools._DefaultCdnUrl}/draco_decoder_gltf.wasm`,\r\n        fallbackUrl: `${Tools._DefaultCdnUrl}/draco_decoder_gltf.js`,\r\n    };\r\n\r\n    /**\r\n     * Returns true if the decoder's `DefaultConfiguration` is available.\r\n     */\r\n    public static get DefaultAvailable(): boolean {\r\n        return _IsConfigurationAvailable(DracoDecoder.DefaultConfiguration);\r\n    }\r\n\r\n    protected static _Default: Nullable<DracoDecoder> = null;\r\n    /**\r\n     * Default instance for the DracoDecoder.\r\n     */\r\n    public static get Default(): DracoDecoder {\r\n        DracoDecoder._Default ??= new DracoDecoder();\r\n        return DracoDecoder._Default;\r\n    }\r\n\r\n    /**\r\n     * Reset the default DracoDecoder object to null and disposing the removed default instance.\r\n     * Note that if the workerPool is a member of the static DefaultConfiguration object it is recommended not to run dispose,\r\n     * unless the static worker pool is no longer needed.\r\n     * @param skipDispose set to true to not dispose the removed default instance\r\n     */\r\n    public static ResetDefault(skipDispose?: boolean): void {\r\n        if (DracoDecoder._Default) {\r\n            if (!skipDispose) {\r\n                DracoDecoder._Default.dispose();\r\n            }\r\n            DracoDecoder._Default = null;\r\n        }\r\n    }\r\n\r\n    protected override _isModuleAvailable(): boolean {\r\n        return typeof DracoDecoderModule !== \"undefined\";\r\n    }\r\n\r\n    protected override async _createModuleAsync(wasmBinary?: ArrayBuffer, jsModule?: unknown /** DracoDecoderModule */): Promise<{ module: unknown /** DecoderModule */ }> {\r\n        const module = await ((jsModule as DracoDecoderModule) || DracoDecoderModule)({ wasmBinary });\r\n        return { module };\r\n    }\r\n\r\n    protected override _getWorkerContent(): string {\r\n        return `${DecodeMesh}(${DecoderWorkerFunction})()`;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Draco decoder.\r\n     * @param configuration Optional override of the configuration for the DracoDecoder. If not provided, defaults to {@link DracoDecoder.DefaultConfiguration}.\r\n     */\r\n    constructor(configuration: IDracoCodecConfiguration = DracoDecoder.DefaultConfiguration) {\r\n        super(configuration);\r\n    }\r\n\r\n    /**\r\n     * Decode Draco compressed mesh data to mesh data.\r\n     * @param data The ArrayBuffer or ArrayBufferView of the compressed Draco data\r\n     * @param attributes A map of attributes from vertex buffer kinds to Draco unique ids\r\n     * @param gltfNormalizedOverride A map of attributes from vertex buffer kinds to normalized flags to override the Draco normalization\r\n     * @returns A promise that resolves with the decoded mesh data\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public decodeMeshToMeshDataAsync(\r\n        data: ArrayBuffer | ArrayBufferView,\r\n        attributes?: { [kind: string]: number },\r\n        gltfNormalizedOverride?: { [kind: string]: boolean }\r\n    ): Promise<MeshData> {\r\n        const dataView = data instanceof ArrayBuffer ? new Int8Array(data) : new Int8Array(data.buffer, data.byteOffset, data.byteLength);\r\n\r\n        const applyGltfNormalizedOverride = (kind: string, normalized: boolean): boolean => {\r\n            if (gltfNormalizedOverride && gltfNormalizedOverride[kind] !== undefined) {\r\n                if (normalized !== gltfNormalizedOverride[kind]) {\r\n                    Logger.Warn(\r\n                        `Normalized flag from Draco data (${normalized}) does not match normalized flag from glTF accessor (${gltfNormalizedOverride[kind]}). Using flag from glTF accessor.`\r\n                    );\r\n                }\r\n\r\n                return gltfNormalizedOverride[kind];\r\n            } else {\r\n                return normalized;\r\n            }\r\n        };\r\n\r\n        if (this._workerPoolPromise) {\r\n            // eslint-disable-next-line github/no-then\r\n            return this._workerPoolPromise.then(async (workerPool) => {\r\n                return await new Promise<MeshData>((resolve, reject) => {\r\n                    workerPool.push((worker, onComplete) => {\r\n                        let resultIndices: Nullable<Uint16Array | Uint32Array> = null;\r\n                        const resultAttributes: Array<IAttributeData> = [];\r\n\r\n                        const onError = (error: ErrorEvent) => {\r\n                            worker.removeEventListener(\"error\", onError);\r\n                            worker.removeEventListener(\"message\", onMessage);\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            reject(error);\r\n                            onComplete();\r\n                        };\r\n\r\n                        const onMessage = (event: MessageEvent<DecoderMessage>) => {\r\n                            const message = event.data;\r\n                            switch (message.id) {\r\n                                case \"indices\": {\r\n                                    resultIndices = message.data;\r\n                                    break;\r\n                                }\r\n                                case \"attribute\": {\r\n                                    resultAttributes.push({\r\n                                        kind: message.kind,\r\n                                        data: message.data,\r\n                                        size: message.size,\r\n                                        byteOffset: message.byteOffset,\r\n                                        byteStride: message.byteStride,\r\n                                        normalized: applyGltfNormalizedOverride(message.kind, message.normalized),\r\n                                    });\r\n                                    break;\r\n                                }\r\n                                case \"decodeMeshDone\": {\r\n                                    worker.removeEventListener(\"error\", onError);\r\n                                    worker.removeEventListener(\"message\", onMessage);\r\n                                    resolve({ indices: resultIndices!, attributes: resultAttributes, totalVertices: message.totalVertices });\r\n                                    onComplete();\r\n                                    break;\r\n                                }\r\n                            }\r\n                        };\r\n\r\n                        worker.addEventListener(\"error\", onError);\r\n                        worker.addEventListener(\"message\", onMessage);\r\n\r\n                        const dataViewCopy = dataView.slice();\r\n                        worker.postMessage({ id: \"decodeMesh\", dataView: dataViewCopy, attributes: attributes }, [dataViewCopy.buffer]);\r\n                    });\r\n                });\r\n            });\r\n        }\r\n\r\n        if (this._modulePromise) {\r\n            // eslint-disable-next-line github/no-then\r\n            return this._modulePromise.then((decoder) => {\r\n                let resultIndices: Nullable<Uint16Array | Uint32Array> = null;\r\n                const resultAttributes: Array<IAttributeData> = [];\r\n\r\n                const numPoints = DecodeMesh(\r\n                    decoder.module,\r\n                    dataView,\r\n                    attributes,\r\n                    (indices) => {\r\n                        resultIndices = indices;\r\n                    },\r\n                    (kind, data, size, byteOffset, byteStride, normalized) => {\r\n                        resultAttributes.push({\r\n                            kind,\r\n                            data,\r\n                            size,\r\n                            byteOffset,\r\n                            byteStride,\r\n                            normalized,\r\n                        });\r\n                    }\r\n                );\r\n\r\n                return { indices: resultIndices!, attributes: resultAttributes, totalVertices: numPoints };\r\n            });\r\n        }\r\n\r\n        throw new Error(\"Draco: Decoder module is not available\");\r\n    }\r\n\r\n    /**\r\n     * Decode Draco compressed mesh data to Babylon geometry.\r\n     * @param name The name to use when creating the geometry\r\n     * @param scene The scene to use when creating the geometry\r\n     * @param data The ArrayBuffer or ArrayBufferView of the Draco compressed data\r\n     * @param attributes A map of attributes from vertex buffer kinds to Draco unique ids\r\n     * @returns A promise that resolves with the decoded geometry\r\n     */\r\n    public async decodeMeshToGeometryAsync(name: string, scene: Scene, data: ArrayBuffer | ArrayBufferView, attributes?: { [kind: string]: number }): Promise<Geometry> {\r\n        const meshData = await this.decodeMeshToMeshDataAsync(data, attributes);\r\n        const geometry = new Geometry(name, scene);\r\n        if (meshData.indices) {\r\n            geometry.setIndices(meshData.indices);\r\n        }\r\n        for (const attribute of meshData.attributes) {\r\n            geometry.setVerticesBuffer(\r\n                new VertexBuffer(\r\n                    scene.getEngine(),\r\n                    attribute.data,\r\n                    attribute.kind,\r\n                    false,\r\n                    undefined,\r\n                    attribute.byteStride,\r\n                    undefined,\r\n                    attribute.byteOffset,\r\n                    attribute.size,\r\n                    undefined,\r\n                    attribute.normalized,\r\n                    true\r\n                ),\r\n                meshData.totalVertices\r\n            );\r\n        }\r\n        return geometry;\r\n    }\r\n\r\n    /** @internal */\r\n    public async _decodeMeshToGeometryForGltfAsync(\r\n        name: string,\r\n        scene: Scene,\r\n        data: ArrayBuffer | ArrayBufferView,\r\n        attributes: { [kind: string]: number },\r\n        gltfNormalizedOverride: { [kind: string]: boolean },\r\n        boundingInfo: Nullable<BoundingInfo>\r\n    ): Promise<Geometry> {\r\n        const meshData = await this.decodeMeshToMeshDataAsync(data, attributes, gltfNormalizedOverride);\r\n        const geometry = new Geometry(name, scene);\r\n        if (boundingInfo) {\r\n            geometry._boundingInfo = boundingInfo;\r\n            geometry.useBoundingInfoFromGeometry = true;\r\n        }\r\n        if (meshData.indices) {\r\n            geometry.setIndices(meshData.indices);\r\n        }\r\n        for (const attribute of meshData.attributes) {\r\n            geometry.setVerticesBuffer(\r\n                new VertexBuffer(\r\n                    scene.getEngine(),\r\n                    attribute.data,\r\n                    attribute.kind,\r\n                    false,\r\n                    undefined,\r\n                    attribute.byteStride,\r\n                    undefined,\r\n                    attribute.byteOffset,\r\n                    attribute.size,\r\n                    undefined,\r\n                    attribute.normalized,\r\n                    true\r\n                ),\r\n                meshData.totalVertices\r\n            );\r\n        }\r\n        return geometry;\r\n    }\r\n}\r\n","import { _GetDefaultNumWorkers, _IsConfigurationAvailable, type IDracoCodecConfiguration } from \"./dracoCodec\";\r\nimport { DracoDecoder } from \"./dracoDecoder\";\r\nimport { type MeshData } from \"./dracoDecoder.types\";\r\nimport { VertexBufferGetDataType, VertexBufferGetFloatData } from \"../../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Geometry } from \"../geometry\";\r\nimport { type BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type Scene } from \"../../scene\";\r\n\r\n/**\r\n * Configuration for Draco compression\r\n */\r\nexport interface IDracoCompressionConfiguration {\r\n    /**\r\n     * Configuration for the decoder.\r\n     */\r\n    decoder: IDracoCodecConfiguration;\r\n}\r\n\r\n/**\r\n * Options for Draco compression\r\n */\r\nexport interface IDracoCompressionOptions extends Pick<IDracoCodecConfiguration, \"numWorkers\" | \"wasmBinary\" | \"workerPool\"> {}\r\n\r\n/**\r\n * Draco compression (https://google.github.io/draco/)\r\n *\r\n * This class wraps the Draco module.\r\n *\r\n * **Encoder**\r\n *\r\n * The encoder is not currently implemented.\r\n *\r\n * **Decoder**\r\n *\r\n * By default, the configuration points to a copy of the Draco decoder files for glTF from the babylon.js cdn https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js.\r\n * The configuration is shared with the DracoDecoder class.\r\n *\r\n * To update the configuration, use the following code:\r\n * ```javascript\r\n *     DracoCompression.Configuration = {\r\n *         decoder: {\r\n *             wasmUrl: \"<url to the WebAssembly library>\",\r\n *             wasmBinaryUrl: \"<url to the WebAssembly binary>\",\r\n *             fallbackUrl: \"<url to the fallback JavaScript library>\",\r\n *         }\r\n *     };\r\n * ```\r\n *\r\n * Draco has two versions, one for WebAssembly and one for JavaScript. The decoder configuration can be set to only support WebAssembly or only support the JavaScript version.\r\n * Decoding will automatically fallback to the JavaScript version if WebAssembly version is not configured or if WebAssembly is not supported by the browser.\r\n * Use `DracoCompression.DecoderAvailable` to determine if the decoder configuration is available for the current context.\r\n *\r\n * To decode Draco compressed data, get the default DracoCompression object and call decodeMeshToGeometryAsync:\r\n * ```javascript\r\n *     var geometry = await DracoCompression.Default.decodeMeshToGeometryAsync(data);\r\n * ```\r\n *\r\n * @see https://playground.babylonjs.com/#DMZIBD#0\r\n */\r\nexport class DracoCompression {\r\n    private _decoder: DracoDecoder;\r\n\r\n    /**\r\n     * The configuration. Defaults to the following urls:\r\n     * - wasmUrl: \"https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js\"\r\n     * - wasmBinaryUrl: \"https://cdn.babylonjs.com/draco_decoder_gltf.wasm\"\r\n     * - fallbackUrl: \"https://cdn.babylonjs.com/draco_decoder_gltf.js\"\r\n     */\r\n    public static get Configuration(): IDracoCompressionConfiguration {\r\n        return {\r\n            get decoder() {\r\n                return DracoDecoder.DefaultConfiguration;\r\n            },\r\n            set decoder(value: IDracoCodecConfiguration) {\r\n                DracoDecoder.DefaultConfiguration = value;\r\n            },\r\n        };\r\n    }\r\n    public static set Configuration(value: IDracoCompressionConfiguration) {\r\n        DracoDecoder.DefaultConfiguration = value.decoder;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the decoder configuration is available.\r\n     */\r\n    public static get DecoderAvailable(): boolean {\r\n        return _IsConfigurationAvailable(DracoDecoder.DefaultConfiguration);\r\n    }\r\n\r\n    /**\r\n     * Default number of workers to create when creating the draco compression object.\r\n     */\r\n    public static DefaultNumWorkers = _GetDefaultNumWorkers();\r\n\r\n    protected static _Default: Nullable<DracoCompression> = null;\r\n    /**\r\n     * Default instance for the DracoCompression.\r\n     */\r\n    public static get Default(): DracoCompression {\r\n        DracoCompression._Default ??= new DracoCompression();\r\n        return DracoCompression._Default;\r\n    }\r\n\r\n    /**\r\n     * Reset the default draco compression object to null and disposing the removed default instance.\r\n     * Note that if the workerPool is a member of the static Configuration object it is recommended not to run dispose,\r\n     * unless the static worker pool is no longer needed.\r\n     * @param skipDispose set to true to not dispose the removed default instance\r\n     */\r\n    public static ResetDefault(skipDispose?: boolean): void {\r\n        if (DracoCompression._Default) {\r\n            if (!skipDispose) {\r\n                DracoCompression._Default.dispose();\r\n            }\r\n            DracoCompression._Default = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new DracoCompression object.\r\n     * @param numWorkersOrOptions Overrides for the Configuration. Either:\r\n     * - The number of workers for async operations or a config object. Specify `0` to disable web workers and run synchronously in the current context.\r\n     * - An options object\r\n     */\r\n    constructor(numWorkersOrOptions: number | IDracoCompressionOptions = DracoCompression.DefaultNumWorkers) {\r\n        const configuration =\r\n            typeof numWorkersOrOptions === \"number\"\r\n                ? { ...DracoDecoder.DefaultConfiguration, numWorkers: numWorkersOrOptions }\r\n                : { ...DracoDecoder.DefaultConfiguration, ...numWorkersOrOptions };\r\n        this._decoder = new DracoDecoder(configuration);\r\n    }\r\n\r\n    /**\r\n     * Stop all async operations and release resources.\r\n     */\r\n    public dispose(): void {\r\n        this._decoder.dispose();\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves when ready. Call this manually to ensure draco compression is ready before use.\r\n     * @returns a promise that resolves when ready\r\n     */\r\n    public async whenReadyAsync(): Promise<void> {\r\n        return await this._decoder.whenReadyAsync();\r\n    }\r\n\r\n    /**\r\n     * Decode Draco compressed mesh data to mesh data.\r\n     * @param data The ArrayBuffer or ArrayBufferView for the Draco compression data\r\n     * @param attributes A map of attributes from vertex buffer kinds to Draco unique ids\r\n     * @param gltfNormalizedOverride A map of attributes from vertex buffer kinds to normalized flags to override the Draco normalization\r\n     * @returns A promise that resolves with the decoded mesh data\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public decodeMeshToMeshDataAsync(\r\n        data: ArrayBuffer | ArrayBufferView,\r\n        attributes?: { [kind: string]: number },\r\n        gltfNormalizedOverride?: { [kind: string]: boolean }\r\n    ): Promise<MeshData> {\r\n        return this._decoder.decodeMeshToMeshDataAsync(data, attributes, gltfNormalizedOverride);\r\n    }\r\n\r\n    /**\r\n     * Decode Draco compressed mesh data to Babylon geometry.\r\n     * @param name The name to use when creating the geometry\r\n     * @param scene The scene to use when creating the geometry\r\n     * @param data The ArrayBuffer or ArrayBufferView for the Draco compression data\r\n     * @param attributes A map of attributes from vertex buffer kinds to Draco unique ids\r\n     * @returns A promise that resolves with the decoded geometry\r\n     */\r\n    public async decodeMeshToGeometryAsync(name: string, scene: Scene, data: ArrayBuffer | ArrayBufferView, attributes?: { [kind: string]: number }): Promise<Geometry> {\r\n        return await this._decoder.decodeMeshToGeometryAsync(name, scene, data, attributes);\r\n    }\r\n\r\n    /** @internal */\r\n    public async _decodeMeshToGeometryForGltfAsync(\r\n        name: string,\r\n        scene: Scene,\r\n        data: ArrayBuffer | ArrayBufferView,\r\n        attributes: { [kind: string]: number },\r\n        gltfNormalizedOverride: { [kind: string]: boolean },\r\n        boundingInfo: Nullable<BoundingInfo>\r\n    ): Promise<Geometry> {\r\n        return await this._decoder._decodeMeshToGeometryForGltfAsync(name, scene, data, attributes, gltfNormalizedOverride, boundingInfo);\r\n    }\r\n\r\n    /**\r\n     * Decode Draco compressed mesh data to Babylon vertex data.\r\n     * @param data The ArrayBuffer or ArrayBufferView for the Draco compression data\r\n     * @param attributes A map of attributes from vertex buffer kinds to Draco unique ids\r\n     * @returns A promise that resolves with the decoded vertex data\r\n     * @deprecated Use {@link decodeMeshToGeometryAsync} for better performance in some cases\r\n     */\r\n    public async decodeMeshAsync(data: ArrayBuffer | ArrayBufferView, attributes?: { [kind: string]: number }): Promise<VertexData> {\r\n        const meshData = await this._decoder.decodeMeshToMeshDataAsync(data, attributes);\r\n        const vertexData = new VertexData();\r\n        if (meshData.indices) {\r\n            vertexData.indices = meshData.indices;\r\n        }\r\n        for (const attribute of meshData.attributes) {\r\n            const floatData = VertexBufferGetFloatData(\r\n                attribute.data,\r\n                attribute.size,\r\n                VertexBufferGetDataType(attribute.data),\r\n                attribute.byteOffset,\r\n                attribute.byteStride,\r\n                attribute.normalized,\r\n                meshData.totalVertices\r\n            );\r\n\r\n            vertexData.set(floatData, attribute.kind);\r\n        }\r\n        return vertexData;\r\n    }\r\n}\r\n","import { Tools } from \"../../Misc/tools.pure\";\r\nimport { type IDisposable } from \"../../scene\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\ndeclare let MeshoptDecoder: any;\r\n\r\nlet NumberOfWorkers = 0;\r\nlet WorkerTimeout: Nullable<ReturnType<typeof setTimeout>> = null;\r\n\r\n/**\r\n * Configuration for meshoptimizer compression\r\n */\r\nexport interface IMeshoptCompressionConfiguration {\r\n    /**\r\n     * Configuration for the decoder.\r\n     */\r\n    decoder: {\r\n        /**\r\n         * The url to the meshopt decoder library.\r\n         */\r\n        url: string;\r\n    };\r\n}\r\n\r\n/**\r\n * Meshopt compression (https://github.com/zeux/meshoptimizer)\r\n *\r\n * This class wraps the meshopt library from https://github.com/zeux/meshoptimizer/tree/master/js.\r\n *\r\n * **Encoder**\r\n *\r\n * The encoder is not currently implemented.\r\n *\r\n * **Decoder**\r\n *\r\n * By default, the configuration points to a copy of the meshopt files on the Babylon.js preview CDN (e.g. https://preview.babylonjs.com/meshopt_decoder.js).\r\n *\r\n * To update the configuration, use the following code:\r\n * ```javascript\r\n *     MeshoptCompression.Configuration = {\r\n *         decoder: {\r\n *             url: \"<url to the meshopt decoder library>\"\r\n *         }\r\n *     };\r\n * ```\r\n */\r\nexport class MeshoptCompression implements IDisposable {\r\n    private _decoderModulePromise?: Promise<any>;\r\n\r\n    /**\r\n     * The configuration. Defaults to the following:\r\n     * ```javascript\r\n     * decoder: {\r\n     *   url: \"https://cdn.babylonjs.com/meshopt_decoder.js\"\r\n     * }\r\n     * ```\r\n     */\r\n    public static Configuration: IMeshoptCompressionConfiguration = {\r\n        decoder: {\r\n            url: `${Tools._DefaultCdnUrl}/meshopt_decoder.js`,\r\n        },\r\n    };\r\n\r\n    private static _Default: Nullable<MeshoptCompression> = null;\r\n\r\n    /**\r\n     * Default instance for the meshoptimizer object.\r\n     */\r\n    public static get Default(): MeshoptCompression {\r\n        if (!MeshoptCompression._Default) {\r\n            MeshoptCompression._Default = new MeshoptCompression();\r\n        }\r\n\r\n        return MeshoptCompression._Default;\r\n    }\r\n\r\n    /**\r\n     * Constructor\r\n     */\r\n    constructor() {\r\n        const decoder = MeshoptCompression.Configuration.decoder;\r\n\r\n        // eslint-disable-next-line github/no-then\r\n        this._decoderModulePromise = Tools.LoadBabylonScriptAsync(decoder.url).then(() => {\r\n            // Wait for WebAssembly compilation before resolving promise\r\n            return MeshoptDecoder.ready;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Stop all async operations and release resources.\r\n     */\r\n    public dispose(): void {\r\n        delete this._decoderModulePromise;\r\n    }\r\n\r\n    /**\r\n     * Decode meshopt data.\r\n     * @see https://github.com/zeux/meshoptimizer/tree/master/js#decoder\r\n     * @param source The input data.\r\n     * @param count The number of elements.\r\n     * @param stride The stride in bytes.\r\n     * @param mode The compression mode.\r\n     * @param filter The compression filter.\r\n     * @returns a Promise<Uint8Array> that resolves to the decoded data\r\n     */\r\n    public async decodeGltfBufferAsync(source: Uint8Array, count: number, stride: number, mode: \"ATTRIBUTES\" | \"TRIANGLES\" | \"INDICES\", filter?: string): Promise<Uint8Array> {\r\n        await this._decoderModulePromise!;\r\n        if (NumberOfWorkers === 0) {\r\n            MeshoptDecoder.useWorkers(1);\r\n            NumberOfWorkers = 1;\r\n        }\r\n        const result = await MeshoptDecoder.decodeGltfBufferAsync(count, stride, source, mode, filter);\r\n        // a simple debounce to avoid switching back and forth between workers and no workers while decoding\r\n        if (WorkerTimeout !== null) {\r\n            clearTimeout(WorkerTimeout);\r\n        }\r\n        WorkerTimeout = setTimeout(() => {\r\n            MeshoptDecoder.useWorkers(0);\r\n            NumberOfWorkers = 0;\r\n            WorkerTimeout = null;\r\n        }, 1000);\r\n        return result;\r\n    }\r\n}\r\n","// https://stackoverflow.com/a/48218209\r\n/**\r\n * Merges a series of objects into a single object, deeply.\r\n * @param objects The objects to merge (objects later in the list take precedence).\r\n * @returns The merged object.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function deepMerge<T extends object>(...objects: T[]): T {\r\n    const isRecord = (obj: unknown): obj is Record<string, unknown> => !!obj && typeof obj === \"object\";\r\n\r\n    return objects.reduce<Record<string, unknown>>((prev, obj) => {\r\n        const keys = Object.keys(obj);\r\n        for (const key of keys) {\r\n            const pVal = prev[key];\r\n            const oVal = (obj as Record<string, unknown>)[key];\r\n\r\n            if (Array.isArray(pVal) && Array.isArray(oVal)) {\r\n                prev[key] = pVal.concat(oVal);\r\n            } else if (isRecord(pVal) && isRecord(oVal)) {\r\n                prev[key] = deepMerge(pVal, oVal);\r\n            } else {\r\n                prev[key] = oVal;\r\n            }\r\n        }\r\n\r\n        return prev;\r\n    }, {}) as T;\r\n}\r\n","import { _IsConfigurationAvailable, DracoCodec, type IDracoCodecConfiguration } from \"./dracoCodec\";\r\nimport { type EncoderMessage, type IDracoAttributeData, type IDracoEncodedMeshData, type IDracoEncoderOptions, type DracoAttributeName } from \"./dracoEncoder.types\";\r\nimport { EncodeMesh, EncoderWorkerFunction } from \"./dracoCompressionWorker\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { VertexBuffer } from \"../buffer\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { type Geometry } from \"../geometry\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { deepMerge } from \"../../Misc/deepMerger\";\r\nimport { type EncoderModule } from \"draco3d\";\r\nimport { AreIndices32Bits, GetTypedArrayData } from \"core/Buffers/bufferUtils\";\r\n\r\n// Missing type from types/draco3d. Do not use in public scope; UMD tests will fail because of EncoderModule.\r\ntype DracoEncoderModule = (props: { wasmBinary?: ArrayBuffer }) => Promise<EncoderModule>;\r\n\r\ndeclare let DracoEncoderModule: DracoEncoderModule;\r\n\r\n/**\r\n * Map the Babylon.js attribute kind to the Draco attribute kind, defined by the `GeometryAttributeType` enum.\r\n * @internal\r\n */\r\nfunction GetDracoAttributeName(kind: string): DracoAttributeName {\r\n    if (kind === VertexBuffer.PositionKind) {\r\n        return \"POSITION\";\r\n    } else if (kind === VertexBuffer.NormalKind) {\r\n        return \"NORMAL\";\r\n    } else if (kind === VertexBuffer.ColorKind) {\r\n        return \"COLOR\";\r\n    } else if (kind.startsWith(VertexBuffer.UVKind)) {\r\n        return \"TEX_COORD\";\r\n    }\r\n    return \"GENERIC\";\r\n}\r\n\r\n/**\r\n * Get the indices for the geometry, if present. Eventually used as\r\n * `AddFacesToMesh(mesh: Mesh, numFaces: number, faces: Uint16Array | Uint32Array)`;\r\n * where `numFaces = indices.length / 3` and `faces = indices`.\r\n * @internal\r\n */\r\nfunction PrepareIndicesForDraco(input: Mesh | Geometry): Nullable<Uint32Array | Uint16Array> {\r\n    let indices = input.getIndices(undefined, true);\r\n\r\n    // Convert number[] and Int32Array types, if needed\r\n    if (indices && !(indices instanceof Uint32Array) && !(indices instanceof Uint16Array)) {\r\n        indices = (AreIndices32Bits(indices, indices.length) ? Uint32Array : Uint16Array).from(indices);\r\n    }\r\n\r\n    return indices;\r\n}\r\n\r\n/**\r\n * Get relevant information about the geometry's vertex attributes for Draco encoding. Eventually used for each attribute as\r\n * `AddFloatAttribute(mesh: Mesh, attribute: number, count: number, itemSize: number, array: TypedArray)`\r\n * where `attribute = EncoderModule[<dracoAttribute>]`, `itemSize = <size>`, `array = <data>`, and count is the number of position vertices.\r\n * @internal\r\n */\r\nfunction PrepareAttributesForDraco(input: Mesh | Geometry, excludedAttributes?: string[]): Array<IDracoAttributeData> {\r\n    const attributes: Array<IDracoAttributeData> = [];\r\n\r\n    for (const kind of input.getVerticesDataKinds()) {\r\n        if (excludedAttributes?.includes(kind)) {\r\n            if (kind === VertexBuffer.PositionKind) {\r\n                throw new Error(\"Draco: Cannot exclude position attribute from encoding.\");\r\n            }\r\n            continue;\r\n        }\r\n\r\n        // Convert number[] to typed array, if needed.\r\n        const vertexBuffer = input.getVertexBuffer(kind)!;\r\n        const size = vertexBuffer.getSize();\r\n        const data = GetTypedArrayData(vertexBuffer.getData()!, size, vertexBuffer.type, vertexBuffer.byteOffset, vertexBuffer.byteStride, input.getTotalVertices(), true);\r\n        attributes.push({ kind: kind, dracoName: GetDracoAttributeName(kind), size: size, data: data });\r\n    }\r\n\r\n    return attributes;\r\n}\r\n\r\nconst DefaultEncoderOptions: IDracoEncoderOptions = {\r\n    decodeSpeed: 5,\r\n    encodeSpeed: 5,\r\n    method: \"MESH_EDGEBREAKER_ENCODING\",\r\n    quantizationBits: {\r\n        POSITION: 14,\r\n        NORMAL: 10,\r\n        COLOR: 8,\r\n        TEX_COORD: 12,\r\n        GENERIC: 12,\r\n    },\r\n};\r\n\r\n/**\r\n * @experimental This class is subject to change.\r\n *\r\n * Draco Encoder (https://google.github.io/draco/)\r\n *\r\n * This class wraps the Draco encoder module.\r\n *\r\n * By default, the configuration points to a copy of the Draco encoder files from the Babylon.js cdn https://cdn.babylonjs.com/draco_encoder_wasm_wrapper.js.\r\n *\r\n * To update the configuration, use the following code:\r\n * ```javascript\r\n *     DracoEncoder.DefaultConfiguration = {\r\n *          wasmUrl: \"<url to the WebAssembly library>\",\r\n *          wasmBinaryUrl: \"<url to the WebAssembly binary>\",\r\n *          fallbackUrl: \"<url to the fallback JavaScript library>\",\r\n *     };\r\n * ```\r\n *\r\n * Draco has two versions, one for WebAssembly and one for JavaScript. The encoder configuration can be set to only support WebAssembly or only support the JavaScript version.\r\n * Decoding will automatically fallback to the JavaScript version if WebAssembly version is not configured or if WebAssembly is not supported by the browser.\r\n * Use `DracoEncoder.DefaultAvailable` to determine if the encoder configuration is available for the current context.\r\n *\r\n * To encode Draco compressed data, get the default DracoEncoder object and call encodeMeshAsync:\r\n * ```javascript\r\n *     var dracoData = await DracoEncoder.Default.encodeMeshAsync(mesh);\r\n * ```\r\n *\r\n * Currently, DracoEncoder only encodes to meshes. Encoding to point clouds is not yet supported.\r\n *\r\n * Only position, normal, color, and UV attributes are supported natively by the encoder. All other attributes are treated as generic. This means that,\r\n * when decoding these generic attributes later, additional information about their original Babylon types will be needed to interpret the data correctly.\r\n * You can use the return value of `encodeMeshAsync` to source this information, specifically the `attributes` field. E.g.,\r\n * ```javascript\r\n *    var dracoData = await DracoEncoder.Default.encodeMeshAsync(mesh);\r\n *    var meshData = await DracoDecoder.Default.decodeMeshToMeshDataAsync(dracoData.data, dracoData.attributes);\r\n * ```\r\n *\r\n * By default, DracoEncoder will encode all available attributes of the mesh. To exclude specific attributes, use the following code:\r\n * ```javascript\r\n *    var options = { excludedAttributes: [VertexBuffer.MatricesIndicesKind, VertexBuffer.MatricesWeightsKind] };\r\n *    var dracoData = await DracoDecoder.Default.encodeMeshAsync(mesh, options);\r\n * ```\r\n */\r\nexport class DracoEncoder extends DracoCodec {\r\n    /**\r\n     * Default configuration for the DracoEncoder. Defaults to the following:\r\n     * - numWorkers: 50% of the available logical processors, capped to 4. If no logical processors are available, defaults to 1.\r\n     * - wasmUrl: `\"https://cdn.babylonjs.com/draco_encoder_wasm_wrapper.js\"`\r\n     * - wasmBinaryUrl: `\"https://cdn.babylonjs.com/draco_encoder.wasm\"`\r\n     * - fallbackUrl: `\"https://cdn.babylonjs.com/draco_encoder.js\"`\r\n     */\r\n    public static DefaultConfiguration: IDracoCodecConfiguration = {\r\n        wasmUrl: `${Tools._DefaultCdnUrl}/draco_encoder_wasm_wrapper.js`,\r\n        wasmBinaryUrl: `${Tools._DefaultCdnUrl}/draco_encoder.wasm`,\r\n        fallbackUrl: `${Tools._DefaultCdnUrl}/draco_encoder.js`,\r\n    };\r\n\r\n    /**\r\n     * Returns true if the encoder's `DefaultConfiguration` is available.\r\n     */\r\n    public static get DefaultAvailable(): boolean {\r\n        return _IsConfigurationAvailable(DracoEncoder.DefaultConfiguration);\r\n    }\r\n\r\n    protected static _Default: Nullable<DracoEncoder> = null;\r\n    /**\r\n     * Default instance for the DracoEncoder.\r\n     */\r\n    public static get Default(): DracoEncoder {\r\n        DracoEncoder._Default ??= new DracoEncoder();\r\n        return DracoEncoder._Default;\r\n    }\r\n\r\n    /**\r\n     * Reset the default DracoEncoder object to null and disposing the removed default instance.\r\n     * Note that if the workerPool is a member of the static DefaultConfiguration object it is recommended not to run dispose,\r\n     * unless the static worker pool is no longer needed.\r\n     * @param skipDispose set to true to not dispose the removed default instance\r\n     */\r\n    public static ResetDefault(skipDispose?: boolean): void {\r\n        if (DracoEncoder._Default) {\r\n            if (!skipDispose) {\r\n                DracoEncoder._Default.dispose();\r\n            }\r\n            DracoEncoder._Default = null;\r\n        }\r\n    }\r\n\r\n    protected override _isModuleAvailable(): boolean {\r\n        return typeof DracoEncoderModule !== \"undefined\";\r\n    }\r\n\r\n    protected override async _createModuleAsync(wasmBinary?: ArrayBuffer, jsModule?: unknown /** DracoEncoderModule */): Promise<{ module: unknown /** EncoderModule */ }> {\r\n        const module = await ((jsModule as DracoEncoderModule) || DracoEncoderModule)({ wasmBinary });\r\n        return { module };\r\n    }\r\n\r\n    protected override _getWorkerContent(): string {\r\n        return `${EncodeMesh}(${EncoderWorkerFunction})()`;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Draco encoder.\r\n     * @param configuration Optional override of the configuration for the DracoEncoder. If not provided, defaults to {@link DracoEncoder.DefaultConfiguration}.\r\n     */\r\n    constructor(configuration: IDracoCodecConfiguration = DracoEncoder.DefaultConfiguration) {\r\n        super(configuration);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public async _encodeAsync(\r\n        attributes: Array<IDracoAttributeData>,\r\n        indices: Nullable<Uint16Array | Uint32Array>,\r\n        options?: IDracoEncoderOptions\r\n    ): Promise<IDracoEncodedMeshData> {\r\n        const mergedOptions = options ? deepMerge(DefaultEncoderOptions, options) : DefaultEncoderOptions;\r\n\r\n        if (this._workerPoolPromise) {\r\n            const workerPool = await this._workerPoolPromise;\r\n            return await new Promise<IDracoEncodedMeshData>((resolve, reject) => {\r\n                workerPool.push((worker, onComplete) => {\r\n                    const onError = (error: ErrorEvent) => {\r\n                        worker.removeEventListener(\"error\", onError);\r\n                        worker.removeEventListener(\"message\", onMessage);\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(error);\r\n                        onComplete();\r\n                    };\r\n\r\n                    const onMessage = (message: MessageEvent<EncoderMessage>) => {\r\n                        if (message.data.id === \"encodeMeshSuccess\") {\r\n                            worker.removeEventListener(\"error\", onError);\r\n                            worker.removeEventListener(\"message\", onMessage);\r\n                            resolve(message.data.encodedMeshData);\r\n                            onComplete();\r\n                        } else if (message.data.id === \"encodeMeshError\") {\r\n                            worker.removeEventListener(\"error\", onError);\r\n                            worker.removeEventListener(\"message\", onMessage);\r\n                            reject(new Error(message.data.errorMessage));\r\n                            onComplete();\r\n                        }\r\n                    };\r\n\r\n                    worker.addEventListener(\"error\", onError);\r\n                    worker.addEventListener(\"message\", onMessage);\r\n\r\n                    // Build the transfer list. No need to copy, as the data was copied in previous steps.\r\n                    const transferList = [];\r\n                    for (const attribute of attributes) {\r\n                        transferList.push(attribute.data.buffer);\r\n                    }\r\n                    if (indices) {\r\n                        transferList.push(indices.buffer);\r\n                    }\r\n\r\n                    worker.postMessage({ id: \"encodeMesh\", attributes: attributes, indices: indices, options: mergedOptions }, transferList);\r\n                });\r\n            });\r\n        }\r\n\r\n        if (this._modulePromise) {\r\n            const encoder = await this._modulePromise;\r\n            return EncodeMesh(encoder.module, attributes, indices, mergedOptions);\r\n        }\r\n\r\n        throw new Error(\"Draco: Encoder module is not available\");\r\n    }\r\n\r\n    /**\r\n     * Encodes a mesh or geometry into a Draco-encoded mesh data.\r\n     * @param input the mesh or geometry to encode\r\n     * @param options options for the encoding\r\n     * @returns a promise that resolves to the newly-encoded data\r\n     */\r\n    public async encodeMeshAsync(input: Mesh | Geometry, options?: IDracoEncoderOptions): Promise<IDracoEncodedMeshData> {\r\n        const verticesCount = input.getTotalVertices();\r\n        if (verticesCount == 0) {\r\n            throw new Error(\"Draco: Cannot encode geometry with no vertices.\");\r\n        }\r\n\r\n        // Prepare parameters for encoding\r\n        if (input instanceof Mesh && input.morphTargetManager && options?.method === \"MESH_EDGEBREAKER_ENCODING\") {\r\n            Logger.Warn(\"Draco: Cannot use EDGEBREAKER encoding method with morph targets. Falling back to SEQUENTIAL method.\");\r\n            options.method = \"MESH_SEQUENTIAL_ENCODING\";\r\n        }\r\n\r\n        const indices = PrepareIndicesForDraco(input);\r\n        const attributes = PrepareAttributesForDraco(input, options?.excludedAttributes);\r\n\r\n        return await this._encodeAsync(attributes, indices, options);\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Quaternion, Matrix, Vector3, Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { SubMesh } from \"../Meshes/subMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Material } from \"../Materials/material\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { VertexData } from \"./mesh.vertexData\";\r\n/**\r\n * Unique ID when we import meshes from Babylon to CSG\r\n */\r\nlet CurrentCSGMeshId = 0;\r\n\r\n/**\r\n * Represents a vertex of a polygon. Use your own vertex class instead of this\r\n * one to provide additional features like texture coordinates and vertex\r\n * colors. Custom vertex classes need to provide a `pos` property and `clone()`,\r\n * `flip()`, and `interpolate()` methods that behave analogous to the ones\r\n * defined by `BABYLON.CSG.Vertex`. This class provides `normal` so convenience\r\n * functions like `BABYLON.CSG.sphere()` can return a smooth vertex normal, but `normal`\r\n * is not used anywhere else.\r\n * Same goes for uv, it allows to keep the original vertex uv coordinates of the 2 meshes\r\n */\r\nclass Vertex {\r\n    /**\r\n     * Initializes the vertex\r\n     * @param pos The position of the vertex\r\n     * @param normal The normal of the vertex\r\n     * @param uv The texture coordinate of the vertex\r\n     * @param vertColor The RGBA color of the vertex\r\n     */\r\n    constructor(\r\n        /**\r\n         * The position of the vertex\r\n         */\r\n        public pos: Vector3,\r\n        /**\r\n         * The normal of the vertex\r\n         */\r\n        public normal: Vector3,\r\n        /**\r\n         * The texture coordinate of the vertex\r\n         */\r\n        public uv?: Vector2,\r\n        /**\r\n         * The texture coordinate of the vertex\r\n         */\r\n        public vertColor?: Color4\r\n    ) {}\r\n\r\n    /**\r\n     * Make a clone, or deep copy, of the vertex\r\n     * @returns A new Vertex\r\n     */\r\n    public clone(): Vertex {\r\n        return new Vertex(this.pos.clone(), this.normal.clone(), this.uv?.clone(), this.vertColor?.clone());\r\n    }\r\n\r\n    /**\r\n     * Invert all orientation-specific data (e.g. vertex normal). Called when the\r\n     * orientation of a polygon is flipped.\r\n     */\r\n    public flip(): void {\r\n        this.normal = this.normal.scale(-1);\r\n    }\r\n\r\n    /**\r\n     * Create a new vertex between this vertex and `other` by linearly\r\n     * interpolating all properties using a parameter of `t`. Subclasses should\r\n     * override this to interpolate additional properties.\r\n     * @param other the vertex to interpolate against\r\n     * @param t The factor used to linearly interpolate between the vertices\r\n     * @returns The new interpolated vertex\r\n     */\r\n    public interpolate(other: Vertex, t: number): Vertex {\r\n        return new Vertex(\r\n            Vector3.Lerp(this.pos, other.pos, t),\r\n            Vector3.Lerp(this.normal, other.normal, t),\r\n            this.uv && other.uv ? Vector2.Lerp(this.uv, other.uv, t) : undefined,\r\n            this.vertColor && other.vertColor ? Color4.Lerp(this.vertColor, other.vertColor, t) : undefined\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a plane in 3D space.\r\n */\r\nclass CSGPlane {\r\n    /**\r\n     * Initializes the plane\r\n     * @param normal The normal for the plane\r\n     * @param w\r\n     */\r\n    constructor(\r\n        public normal: Vector3,\r\n        public w: number\r\n    ) {}\r\n\r\n    /**\r\n     * `CSG.Plane.EPSILON` is the tolerance used by `splitPolygon()` to decide if a\r\n     * point is on the plane\r\n     */\r\n    static EPSILON = 1e-5;\r\n\r\n    /**\r\n     * Construct a plane from three points\r\n     * @param a Point a\r\n     * @param b Point b\r\n     * @param c Point c\r\n     * @returns A new plane\r\n     */\r\n    public static FromPoints(a: Vector3, b: Vector3, c: Vector3): Nullable<CSGPlane> {\r\n        const v0 = c.subtract(a);\r\n        const v1 = b.subtract(a);\r\n\r\n        if (v0.lengthSquared() === 0 || v1.lengthSquared() === 0) {\r\n            return null;\r\n        }\r\n\r\n        const n = Vector3.Normalize(Vector3.Cross(v0, v1));\r\n        return new CSGPlane(n, Vector3.Dot(n, a));\r\n    }\r\n\r\n    /**\r\n     * Clone, or make a deep copy of the plane\r\n     * @returns a new Plane\r\n     */\r\n    public clone(): CSGPlane {\r\n        return new CSGPlane(this.normal.clone(), this.w);\r\n    }\r\n\r\n    /**\r\n     * Flip the face of the plane\r\n     */\r\n    public flip() {\r\n        this.normal.scaleInPlace(-1);\r\n        this.w = -this.w;\r\n    }\r\n\r\n    /**\r\n     * Split `polygon` by this plane if needed, then put the polygon or polygon\r\n     * fragments in the appropriate lists. Coplanar polygons go into either\r\n    `* coplanarFront` or `coplanarBack` depending on their orientation with\r\n     * respect to this plane. Polygons in front or in back of this plane go into\r\n     * either `front` or `back`\r\n     * @param polygon The polygon to be split\r\n     * @param coplanarFront Will contain polygons coplanar with the plane that are oriented to the front of the plane\r\n     * @param coplanarBack Will contain polygons coplanar with the plane that are oriented to the back of the plane\r\n     * @param front Will contain the polygons in front of the plane\r\n     * @param back Will contain the polygons begind the plane\r\n     */\r\n    public splitPolygon(polygon: CSGPolygon, coplanarFront: CSGPolygon[], coplanarBack: CSGPolygon[], front: CSGPolygon[], back: CSGPolygon[]): void {\r\n        const coplanarConst = 0;\r\n        const frontConst = 1;\r\n        const backConst = 2;\r\n        const spanningConst = 3;\r\n\r\n        // Classify each point as well as the entire polygon into one of the above\r\n        // four classes.\r\n        let polygonType = 0;\r\n        const types = [];\r\n        let i: number;\r\n        let t: number;\r\n        for (i = 0; i < polygon.vertices.length; i++) {\r\n            t = Vector3.Dot(this.normal, polygon.vertices[i].pos) - this.w;\r\n            const type = t < -CSGPlane.EPSILON ? backConst : t > CSGPlane.EPSILON ? frontConst : coplanarConst;\r\n            polygonType |= type;\r\n            types.push(type);\r\n        }\r\n\r\n        // Put the polygon in the correct list, splitting it when necessary\r\n        switch (polygonType) {\r\n            case coplanarConst:\r\n                (Vector3.Dot(this.normal, polygon.plane.normal) > 0 ? coplanarFront : coplanarBack).push(polygon);\r\n                break;\r\n            case frontConst:\r\n                front.push(polygon);\r\n                break;\r\n            case backConst:\r\n                back.push(polygon);\r\n                break;\r\n            case spanningConst: {\r\n                const f = [],\r\n                    b = [];\r\n                for (i = 0; i < polygon.vertices.length; i++) {\r\n                    const j = (i + 1) % polygon.vertices.length;\r\n                    const ti = types[i],\r\n                        tj = types[j];\r\n                    const vi = polygon.vertices[i],\r\n                        vj = polygon.vertices[j];\r\n                    if (ti !== backConst) {\r\n                        f.push(vi);\r\n                    }\r\n                    if (ti !== frontConst) {\r\n                        b.push(ti !== backConst ? vi.clone() : vi);\r\n                    }\r\n                    if ((ti | tj) === spanningConst) {\r\n                        t = (this.w - Vector3.Dot(this.normal, vi.pos)) / Vector3.Dot(this.normal, vj.pos.subtract(vi.pos));\r\n                        const v = vi.interpolate(vj, t);\r\n                        f.push(v);\r\n                        b.push(v.clone());\r\n                    }\r\n                }\r\n                let poly: CSGPolygon;\r\n                if (f.length >= 3) {\r\n                    poly = new CSGPolygon(f, polygon.shared);\r\n                    if (poly.plane) {\r\n                        front.push(poly);\r\n                    }\r\n                }\r\n\r\n                if (b.length >= 3) {\r\n                    poly = new CSGPolygon(b, polygon.shared);\r\n\r\n                    if (poly.plane) {\r\n                        back.push(poly);\r\n                    }\r\n                }\r\n\r\n                break;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a convex polygon. The vertices used to initialize a polygon must\r\n * be coplanar and form a convex loop.\r\n *\r\n * Each convex polygon has a `shared` property, which is shared between all\r\n * polygons that are clones of each other or were split from the same polygon.\r\n * This can be used to define per-polygon properties (such as surface color)\r\n */\r\nclass CSGPolygon {\r\n    /**\r\n     * Vertices of the polygon\r\n     */\r\n    public vertices: Vertex[];\r\n    /**\r\n     * Properties that are shared across all polygons\r\n     */\r\n    public shared: any;\r\n    /**\r\n     * A plane formed from the vertices of the polygon\r\n     */\r\n    public plane: CSGPlane;\r\n\r\n    /**\r\n     * Initializes the polygon\r\n     * @param vertices The vertices of the polygon\r\n     * @param shared The properties shared across all polygons\r\n     */\r\n    constructor(vertices: Vertex[], shared: any) {\r\n        this.vertices = vertices;\r\n        this.shared = shared;\r\n        this.plane = <CSGPlane>CSGPlane.FromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos);\r\n    }\r\n\r\n    /**\r\n     * Clones, or makes a deep copy, or the polygon\r\n     * @returns A new CSGPolygon\r\n     */\r\n    public clone(): CSGPolygon {\r\n        const vertices = this.vertices.map((v) => v.clone());\r\n        return new CSGPolygon(vertices, this.shared);\r\n    }\r\n\r\n    /**\r\n     * Flips the faces of the polygon\r\n     */\r\n    public flip() {\r\n        this.vertices.reverse().map((v) => {\r\n            v.flip();\r\n        });\r\n        this.plane.flip();\r\n    }\r\n}\r\n\r\n/**\r\n * Holds a node in a BSP tree. A BSP tree is built from a collection of polygons\r\n * by picking a polygon to split along. That polygon (and all other coplanar\r\n * polygons) are added directly to that node and the other polygons are added to\r\n * the front and/or back subtrees. This is not a leafy BSP tree since there is\r\n * no distinction between internal and leaf nodes\r\n */\r\nclass Node {\r\n    private _plane: Nullable<CSGPlane> = null;\r\n    private _front: Nullable<Node> = null;\r\n    private _back: Nullable<Node> = null;\r\n    private _polygons = new Array<CSGPolygon>();\r\n\r\n    /**\r\n     * Initializes the node\r\n     * @param polygons A collection of polygons held in the node\r\n     */\r\n    constructor(polygons?: Array<CSGPolygon>) {\r\n        if (polygons) {\r\n            this.build(polygons);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clones, or makes a deep copy, of the node\r\n     * @returns The cloned node\r\n     */\r\n    public clone(): Node {\r\n        const node = new Node();\r\n        node._plane = this._plane && this._plane.clone();\r\n        node._front = this._front && this._front.clone();\r\n        node._back = this._back && this._back.clone();\r\n        node._polygons = this._polygons.map((p) => p.clone());\r\n        return node;\r\n    }\r\n\r\n    /**\r\n     * Convert solid space to empty space and empty space to solid space\r\n     */\r\n    public invert(): void {\r\n        for (let i = 0; i < this._polygons.length; i++) {\r\n            this._polygons[i].flip();\r\n        }\r\n        if (this._plane) {\r\n            this._plane.flip();\r\n        }\r\n        if (this._front) {\r\n            this._front.invert();\r\n        }\r\n        if (this._back) {\r\n            this._back.invert();\r\n        }\r\n        const temp = this._front;\r\n        this._front = this._back;\r\n        this._back = temp;\r\n    }\r\n\r\n    /**\r\n     * Recursively remove all polygons in `polygons` that are inside this BSP\r\n     * tree.\r\n     * @param polygons Polygons to remove from the BSP\r\n     * @returns Polygons clipped from the BSP\r\n     */\r\n    clipPolygons(polygons: CSGPolygon[]): CSGPolygon[] {\r\n        if (!this._plane) {\r\n            return polygons.slice();\r\n        }\r\n        let front: CSGPolygon[] = [],\r\n            back = [] as CSGPolygon[];\r\n        for (let i = 0; i < polygons.length; i++) {\r\n            this._plane.splitPolygon(polygons[i], front, back, front, back);\r\n        }\r\n        if (this._front) {\r\n            front = this._front.clipPolygons(front);\r\n        }\r\n        if (this._back) {\r\n            back = this._back.clipPolygons(back);\r\n        } else {\r\n            back = [];\r\n        }\r\n        return front.concat(back);\r\n    }\r\n\r\n    /**\r\n     * Remove all polygons in this BSP tree that are inside the other BSP tree\r\n     * `bsp`.\r\n     * @param bsp BSP containing polygons to remove from this BSP\r\n     */\r\n    clipTo(bsp: Node): void {\r\n        this._polygons = bsp.clipPolygons(this._polygons);\r\n        if (this._front) {\r\n            this._front.clipTo(bsp);\r\n        }\r\n        if (this._back) {\r\n            this._back.clipTo(bsp);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Return a list of all polygons in this BSP tree\r\n     * @returns List of all polygons in this BSP tree\r\n     */\r\n    allPolygons(): CSGPolygon[] {\r\n        let polygons = this._polygons.slice();\r\n        if (this._front) {\r\n            polygons = polygons.concat(this._front.allPolygons());\r\n        }\r\n        if (this._back) {\r\n            polygons = polygons.concat(this._back.allPolygons());\r\n        }\r\n        return polygons;\r\n    }\r\n\r\n    /**\r\n     * Build a BSP tree out of `polygons`. When called on an existing tree, the\r\n     * new polygons are filtered down to the bottom of the tree and become new\r\n     * nodes there. Each set of polygons is partitioned using the first polygon\r\n     * (no heuristic is used to pick a good split)\r\n     * @param polygons Polygons used to construct the BSP tree\r\n     */\r\n    build(polygons: CSGPolygon[]): void {\r\n        if (!polygons.length) {\r\n            return;\r\n        }\r\n        if (!this._plane) {\r\n            this._plane = polygons[0].plane.clone();\r\n        }\r\n        const front: CSGPolygon[] = [],\r\n            back = [] as CSGPolygon[];\r\n        for (let i = 0; i < polygons.length; i++) {\r\n            this._plane.splitPolygon(polygons[i], this._polygons, this._polygons, front, back);\r\n        }\r\n        if (front.length) {\r\n            if (!this._front) {\r\n                this._front = new Node();\r\n            }\r\n            this._front.build(front);\r\n        }\r\n        if (back.length) {\r\n            if (!this._back) {\r\n                this._back = new Node();\r\n            }\r\n            this._back.build(back);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Class for building Constructive Solid Geometry\r\n * @deprecated Please use CSG2 instead\r\n */\r\nexport class CSG {\r\n    private _polygons = new Array<CSGPolygon>();\r\n    /**\r\n     * The world matrix\r\n     */\r\n    public matrix: Matrix;\r\n    /**\r\n     * Stores the position\r\n     */\r\n    public position: Vector3;\r\n    /**\r\n     * Stores the rotation\r\n     */\r\n    public rotation: Vector3;\r\n    /**\r\n     * Stores the rotation quaternion\r\n     */\r\n    public rotationQuaternion: Nullable<Quaternion>;\r\n    /**\r\n     * Stores the scaling vector\r\n     */\r\n    public scaling: Vector3;\r\n\r\n    /**\r\n     * Convert a VertexData to CSG\r\n     * @param data defines the VertexData to convert to CSG\r\n     * @returns the new CSG\r\n     */\r\n    public static FromVertexData(data: VertexData): CSG {\r\n        let vertex: Vertex, polygon: CSGPolygon, vertices: Vertex[];\r\n        const polygons: CSGPolygon[] = [];\r\n\r\n        const indices = data.indices;\r\n        const positions = data.positions;\r\n        const normals = data.normals;\r\n        const uvs = data.uvs;\r\n        const vertColors = data.colors;\r\n\r\n        if (!indices || !positions) {\r\n            throw \"BABYLON.CSG: VertexData must at least contain positions and indices\";\r\n        }\r\n\r\n        for (let i = 0; i < indices.length; i += 3) {\r\n            vertices = [];\r\n            for (let j = 0; j < 3; j++) {\r\n                const indexIndices = i + j;\r\n                const offset = indices[indexIndices];\r\n\r\n                const normal = normals ? Vector3.FromArray(normals, offset * 3) : Vector3.Zero();\r\n                const uv = uvs ? Vector2.FromArray(uvs, offset * 2) : undefined;\r\n                const vertColor = vertColors ? Color4.FromArray(vertColors, offset * 4) : undefined;\r\n\r\n                const position = Vector3.FromArray(positions, offset * 3);\r\n\r\n                vertex = new Vertex(position, normal, uv, vertColor);\r\n                vertices.push(vertex);\r\n            }\r\n\r\n            polygon = new CSGPolygon(vertices, { subMeshId: 0, meshId: CurrentCSGMeshId, materialIndex: 0 });\r\n\r\n            // To handle the case of degenerated triangle\r\n            // polygon.plane == null <=> the polygon does not represent 1 single plane <=> the triangle is degenerated\r\n            if (polygon.plane) {\r\n                polygons.push(polygon);\r\n            }\r\n        }\r\n\r\n        const csg = CSG._FromPolygons(polygons);\r\n        csg.matrix = Matrix.Identity();\r\n        csg.position = Vector3.Zero();\r\n        csg.rotation = Vector3.Zero();\r\n        csg.scaling = Vector3.One();\r\n        csg.rotationQuaternion = Quaternion.Identity();\r\n        CurrentCSGMeshId++;\r\n\r\n        return csg;\r\n    }\r\n\r\n    /**\r\n     * Convert the Mesh to CSG\r\n     * @param mesh The Mesh to convert to CSG\r\n     * @param absolute If true, the final (local) matrix transformation is set to the identity and not to that of `mesh`. It can help when dealing with right-handed meshes (default: false)\r\n     * @returns A new CSG from the Mesh\r\n     */\r\n    public static FromMesh(mesh: Mesh, absolute = false): CSG {\r\n        let vertex: Vertex,\r\n            normal: Vector3,\r\n            uv: Vector2 | undefined = undefined,\r\n            position: Vector3,\r\n            vertColor: Color4 | undefined = undefined,\r\n            polygon: CSGPolygon,\r\n            vertices: Vertex[];\r\n        const polygons: CSGPolygon[] = [];\r\n        let matrix: Matrix,\r\n            meshPosition: Vector3,\r\n            meshRotation: Vector3,\r\n            meshRotationQuaternion: Nullable<Quaternion> = null,\r\n            meshScaling: Vector3;\r\n\r\n        let invertWinding = false;\r\n        if (mesh instanceof Mesh) {\r\n            mesh.computeWorldMatrix(true);\r\n            matrix = mesh.getWorldMatrix();\r\n            meshPosition = mesh.position.clone();\r\n            meshRotation = mesh.rotation.clone();\r\n            if (mesh.rotationQuaternion) {\r\n                meshRotationQuaternion = mesh.rotationQuaternion.clone();\r\n            }\r\n            meshScaling = mesh.scaling.clone();\r\n            if (mesh.material && absolute) {\r\n                invertWinding = mesh.material.sideOrientation === Constants.MATERIAL_ClockWiseSideOrientation;\r\n            }\r\n        } else {\r\n            throw \"BABYLON.CSG: Wrong Mesh type, must be BABYLON.Mesh\";\r\n        }\r\n\r\n        const indices = mesh.getIndices(),\r\n            positions = mesh.getVerticesData(VertexBuffer.PositionKind),\r\n            normals = mesh.getVerticesData(VertexBuffer.NormalKind),\r\n            uvs = mesh.getVerticesData(VertexBuffer.UVKind),\r\n            vertColors = mesh.getVerticesData(VertexBuffer.ColorKind);\r\n\r\n        if (indices === null) {\r\n            throw \"BABYLON.CSG: Mesh has no indices\";\r\n        }\r\n        if (positions === null) {\r\n            throw \"BABYLON.CSG: Mesh has no positions\";\r\n        }\r\n        if (normals === null) {\r\n            throw \"BABYLON.CSG: Mesh has no normals\";\r\n        }\r\n\r\n        const subMeshes = mesh.subMeshes;\r\n        if (!subMeshes) {\r\n            throw \"BABYLON.CSG: Mesh has no submeshes\";\r\n        }\r\n\r\n        for (let sm = 0, sml = subMeshes.length; sm < sml; sm++) {\r\n            for (let i = subMeshes[sm].indexStart, il = subMeshes[sm].indexCount + subMeshes[sm].indexStart; i < il; i += 3) {\r\n                vertices = [];\r\n                for (let j = 0; j < 3; j++) {\r\n                    const indexIndices = j === 0 ? i + j : invertWinding ? i + 3 - j : i + j;\r\n                    const sourceNormal = new Vector3(normals[indices[indexIndices] * 3], normals[indices[indexIndices] * 3 + 1], normals[indices[indexIndices] * 3 + 2]);\r\n                    if (uvs) {\r\n                        uv = new Vector2(uvs[indices[indexIndices] * 2], uvs[indices[indexIndices] * 2 + 1]);\r\n                    }\r\n                    if (vertColors) {\r\n                        vertColor = new Color4(\r\n                            vertColors[indices[indexIndices] * 4],\r\n                            vertColors[indices[indexIndices] * 4 + 1],\r\n                            vertColors[indices[indexIndices] * 4 + 2],\r\n                            vertColors[indices[indexIndices] * 4 + 3]\r\n                        );\r\n                    }\r\n                    const sourcePosition = new Vector3(positions[indices[indexIndices] * 3], positions[indices[indexIndices] * 3 + 1], positions[indices[indexIndices] * 3 + 2]);\r\n                    position = Vector3.TransformCoordinates(sourcePosition, matrix);\r\n                    normal = Vector3.TransformNormal(sourceNormal, matrix);\r\n\r\n                    vertex = new Vertex(position, normal, uv, vertColor);\r\n                    vertices.push(vertex);\r\n                }\r\n\r\n                polygon = new CSGPolygon(vertices, { subMeshId: sm, meshId: CurrentCSGMeshId, materialIndex: subMeshes[sm].materialIndex });\r\n\r\n                // To handle the case of degenerated triangle\r\n                // polygon.plane == null <=> the polygon does not represent 1 single plane <=> the triangle is degenerated\r\n                if (polygon.plane) {\r\n                    polygons.push(polygon);\r\n                }\r\n            }\r\n        }\r\n\r\n        const csg = CSG._FromPolygons(polygons);\r\n        csg.matrix = absolute ? Matrix.Identity() : matrix;\r\n        csg.position = absolute ? Vector3.Zero() : meshPosition;\r\n        csg.rotation = absolute ? Vector3.Zero() : meshRotation;\r\n        csg.scaling = absolute ? Vector3.One() : meshScaling;\r\n        csg.rotationQuaternion = absolute && meshRotationQuaternion ? Quaternion.Identity() : meshRotationQuaternion;\r\n        CurrentCSGMeshId++;\r\n\r\n        return csg;\r\n    }\r\n\r\n    /**\r\n     * Construct a CSG solid from a list of `CSG.Polygon` instances.\r\n     * @param polygons Polygons used to construct a CSG solid\r\n     * @returns A new CSG solid\r\n     */\r\n    private static _FromPolygons(polygons: CSGPolygon[]): CSG {\r\n        const csg = new CSG();\r\n        csg._polygons = polygons;\r\n        return csg;\r\n    }\r\n\r\n    /**\r\n     * Clones, or makes a deep copy, of the CSG\r\n     * @returns A new CSG\r\n     */\r\n    public clone(): CSG {\r\n        const csg = new CSG();\r\n        csg._polygons = this._polygons.map((p) => p.clone());\r\n        csg.copyTransformAttributes(this);\r\n        return csg;\r\n    }\r\n\r\n    /**\r\n     * Unions this CSG with another CSG\r\n     * @param csg The CSG to union against this CSG\r\n     * @returns The unioned CSG\r\n     */\r\n    public union(csg: CSG): CSG {\r\n        const a = new Node(this.clone()._polygons);\r\n        const b = new Node(csg.clone()._polygons);\r\n        a.clipTo(b);\r\n        b.clipTo(a);\r\n        b.invert();\r\n        b.clipTo(a);\r\n        b.invert();\r\n        a.build(b.allPolygons());\r\n        return CSG._FromPolygons(a.allPolygons()).copyTransformAttributes(this);\r\n    }\r\n\r\n    /**\r\n     * Unions this CSG with another CSG in place\r\n     * @param csg The CSG to union against this CSG\r\n     */\r\n    public unionInPlace(csg: CSG): void {\r\n        const a = new Node(this._polygons);\r\n        const b = new Node(csg._polygons);\r\n\r\n        a.clipTo(b);\r\n        b.clipTo(a);\r\n        b.invert();\r\n        b.clipTo(a);\r\n        b.invert();\r\n        a.build(b.allPolygons());\r\n\r\n        this._polygons = a.allPolygons();\r\n    }\r\n\r\n    /**\r\n     * Subtracts this CSG with another CSG\r\n     * @param csg The CSG to subtract against this CSG\r\n     * @returns A new CSG\r\n     */\r\n    public subtract(csg: CSG): CSG {\r\n        const a = new Node(this.clone()._polygons);\r\n        const b = new Node(csg.clone()._polygons);\r\n        a.invert();\r\n        a.clipTo(b);\r\n        b.clipTo(a);\r\n        b.invert();\r\n        b.clipTo(a);\r\n        b.invert();\r\n        a.build(b.allPolygons());\r\n        a.invert();\r\n        return CSG._FromPolygons(a.allPolygons()).copyTransformAttributes(this);\r\n    }\r\n\r\n    /**\r\n     * Subtracts this CSG with another CSG in place\r\n     * @param csg The CSG to subtract against this CSG\r\n     */\r\n    public subtractInPlace(csg: CSG): void {\r\n        const a = new Node(this._polygons);\r\n        const b = new Node(csg._polygons);\r\n\r\n        a.invert();\r\n        a.clipTo(b);\r\n        b.clipTo(a);\r\n        b.invert();\r\n        b.clipTo(a);\r\n        b.invert();\r\n        a.build(b.allPolygons());\r\n        a.invert();\r\n\r\n        this._polygons = a.allPolygons();\r\n    }\r\n\r\n    /**\r\n     * Intersect this CSG with another CSG\r\n     * @param csg The CSG to intersect against this CSG\r\n     * @returns A new CSG\r\n     */\r\n    public intersect(csg: CSG): CSG {\r\n        const a = new Node(this.clone()._polygons);\r\n        const b = new Node(csg.clone()._polygons);\r\n        a.invert();\r\n        b.clipTo(a);\r\n        b.invert();\r\n        a.clipTo(b);\r\n        b.clipTo(a);\r\n        a.build(b.allPolygons());\r\n        a.invert();\r\n        return CSG._FromPolygons(a.allPolygons()).copyTransformAttributes(this);\r\n    }\r\n\r\n    /**\r\n     * Intersects this CSG with another CSG in place\r\n     * @param csg The CSG to intersect against this CSG\r\n     */\r\n    public intersectInPlace(csg: CSG): void {\r\n        const a = new Node(this._polygons);\r\n        const b = new Node(csg._polygons);\r\n\r\n        a.invert();\r\n        b.clipTo(a);\r\n        b.invert();\r\n        a.clipTo(b);\r\n        b.clipTo(a);\r\n        a.build(b.allPolygons());\r\n        a.invert();\r\n\r\n        this._polygons = a.allPolygons();\r\n    }\r\n\r\n    /**\r\n     * Return a new CSG solid with solid and empty space switched. This solid is\r\n     * not modified.\r\n     * @returns A new CSG solid with solid and empty space switched\r\n     */\r\n    public inverse(): CSG {\r\n        const csg = this.clone();\r\n        csg.inverseInPlace();\r\n        return csg;\r\n    }\r\n\r\n    /**\r\n     * Inverses the CSG in place\r\n     */\r\n    public inverseInPlace(): void {\r\n        this._polygons.map((p) => {\r\n            p.flip();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * This is used to keep meshes transformations so they can be restored\r\n     * when we build back a Babylon Mesh\r\n     * NB : All CSG operations are performed in world coordinates\r\n     * @param csg The CSG to copy the transform attributes from\r\n     * @returns This CSG\r\n     */\r\n    public copyTransformAttributes(csg: CSG): CSG {\r\n        this.matrix = csg.matrix;\r\n        this.position = csg.position;\r\n        this.rotation = csg.rotation;\r\n        this.scaling = csg.scaling;\r\n        this.rotationQuaternion = csg.rotationQuaternion;\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Build vertex data from CSG\r\n     * Coordinates here are in world space\r\n     * @param onBeforePolygonProcessing called before each polygon is being processed\r\n     * @param onAfterPolygonProcessing called after each polygon has been processed\r\n     * @returns the final vertex data\r\n     */\r\n    public toVertexData(onBeforePolygonProcessing: Nullable<(polygon: CSGPolygon) => void> = null, onAfterPolygonProcessing: Nullable<() => void> = null): VertexData {\r\n        const matrix = this.matrix.clone();\r\n        matrix.invert();\r\n\r\n        const polygons = this._polygons;\r\n        const vertices = [];\r\n        const indices = [];\r\n        const normals = [];\r\n        let uvs: Nullable<number[]> = null;\r\n        let vertColors: Nullable<number[]> = null;\r\n        const vertex = Vector3.Zero();\r\n        const normal = Vector3.Zero();\r\n        const uv = Vector2.Zero();\r\n        const vertColor = new Color4(0, 0, 0, 0);\r\n        const polygonIndices = [0, 0, 0];\r\n        const verticeDict = {};\r\n        let vertexIdx;\r\n\r\n        for (let i = 0, il = polygons.length; i < il; i++) {\r\n            const polygon = polygons[i];\r\n\r\n            if (onBeforePolygonProcessing) {\r\n                onBeforePolygonProcessing(polygon);\r\n            }\r\n\r\n            for (let j = 2, jl = polygon.vertices.length; j < jl; j++) {\r\n                polygonIndices[0] = 0;\r\n                polygonIndices[1] = j - 1;\r\n                polygonIndices[2] = j;\r\n\r\n                for (let k = 0; k < 3; k++) {\r\n                    vertex.copyFrom(polygon.vertices[polygonIndices[k]].pos);\r\n                    normal.copyFrom(polygon.vertices[polygonIndices[k]].normal);\r\n                    if (polygon.vertices[polygonIndices[k]].uv) {\r\n                        if (!uvs) {\r\n                            uvs = [];\r\n                        }\r\n                        uv.copyFrom(polygon.vertices[polygonIndices[k]].uv!);\r\n                    }\r\n\r\n                    if (polygon.vertices[polygonIndices[k]].vertColor) {\r\n                        if (!vertColors) {\r\n                            vertColors = [];\r\n                        }\r\n                        vertColor.copyFrom(polygon.vertices[polygonIndices[k]].vertColor!);\r\n                    }\r\n                    const localVertex = Vector3.TransformCoordinates(vertex, matrix);\r\n                    const localNormal = Vector3.TransformNormal(normal, matrix);\r\n\r\n                    vertexIdx = (<any>verticeDict)[localVertex.x + \",\" + localVertex.y + \",\" + localVertex.z];\r\n\r\n                    let areUvsDifferent = false;\r\n\r\n                    if (uvs && !(uvs[vertexIdx * 2] === uv.x && uvs[vertexIdx * 2 + 1] === uv.y)) {\r\n                        areUvsDifferent = true;\r\n                    }\r\n\r\n                    let areColorsDifferent = false;\r\n\r\n                    if (\r\n                        vertColors &&\r\n                        !(\r\n                            vertColors[vertexIdx * 4] === vertColor.r &&\r\n                            vertColors[vertexIdx * 4 + 1] === vertColor.g &&\r\n                            vertColors[vertexIdx * 4 + 2] === vertColor.b &&\r\n                            vertColors[vertexIdx * 4 + 3] === vertColor.a\r\n                        )\r\n                    ) {\r\n                        areColorsDifferent = true;\r\n                    }\r\n\r\n                    // Check if 2 points can be merged\r\n                    if (\r\n                        !(\r\n                            typeof vertexIdx !== \"undefined\" &&\r\n                            normals[vertexIdx * 3] === localNormal.x &&\r\n                            normals[vertexIdx * 3 + 1] === localNormal.y &&\r\n                            normals[vertexIdx * 3 + 2] === localNormal.z\r\n                        ) ||\r\n                        areUvsDifferent ||\r\n                        areColorsDifferent\r\n                    ) {\r\n                        vertices.push(localVertex.x, localVertex.y, localVertex.z);\r\n                        if (uvs) {\r\n                            uvs.push(uv.x, uv.y);\r\n                        }\r\n                        normals.push(localNormal.x, localNormal.y, localNormal.z);\r\n                        if (vertColors) {\r\n                            vertColors.push(vertColor.r, vertColor.g, vertColor.b, vertColor.a);\r\n                        }\r\n                        vertexIdx = (<any>verticeDict)[localVertex.x + \",\" + localVertex.y + \",\" + localVertex.z] = vertices.length / 3 - 1;\r\n                    }\r\n\r\n                    indices.push(vertexIdx);\r\n\r\n                    if (onAfterPolygonProcessing) {\r\n                        onAfterPolygonProcessing();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        const result = new VertexData();\r\n        result.positions = vertices;\r\n        result.normals = normals;\r\n        if (uvs) {\r\n            result.uvs = uvs;\r\n        }\r\n        if (vertColors) {\r\n            result.colors = vertColors;\r\n        }\r\n        result.indices = indices;\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Build Raw mesh from CSG\r\n     * Coordinates here are in world space\r\n     * @param name The name of the mesh geometry\r\n     * @param scene The Scene\r\n     * @param keepSubMeshes Specifies if the submeshes should be kept\r\n     * @returns A new Mesh\r\n     */\r\n    public buildMeshGeometry(name: string, scene?: Scene, keepSubMeshes?: boolean): Mesh {\r\n        const mesh = new Mesh(name, scene);\r\n        const polygons = this._polygons;\r\n        let currentIndex = 0;\r\n        const subMeshDict = {};\r\n        let subMeshObj: {\r\n            materialIndex: number;\r\n            indexStart: number;\r\n            indexEnd: number;\r\n        };\r\n\r\n        if (keepSubMeshes) {\r\n            // Sort Polygons, since subMeshes are indices range\r\n            polygons.sort((a, b) => {\r\n                if (a.shared.meshId === b.shared.meshId) {\r\n                    return a.shared.subMeshId - b.shared.subMeshId;\r\n                } else {\r\n                    return a.shared.meshId - b.shared.meshId;\r\n                }\r\n            });\r\n        }\r\n\r\n        const vertexData = this.toVertexData(\r\n            (polygon) => {\r\n                // Building SubMeshes\r\n                if (!(<any>subMeshDict)[polygon.shared.meshId]) {\r\n                    (<any>subMeshDict)[polygon.shared.meshId] = {};\r\n                }\r\n                if (!(<any>subMeshDict)[polygon.shared.meshId][polygon.shared.subMeshId]) {\r\n                    (<any>subMeshDict)[polygon.shared.meshId][polygon.shared.subMeshId] = {\r\n                        indexStart: +Infinity,\r\n                        indexEnd: -Infinity,\r\n                        materialIndex: polygon.shared.materialIndex,\r\n                    };\r\n                }\r\n                subMeshObj = (<any>subMeshDict)[polygon.shared.meshId][polygon.shared.subMeshId];\r\n            },\r\n            () => {\r\n                subMeshObj.indexStart = Math.min(currentIndex, subMeshObj.indexStart);\r\n                subMeshObj.indexEnd = Math.max(currentIndex, subMeshObj.indexEnd);\r\n                currentIndex++;\r\n            }\r\n        );\r\n\r\n        vertexData.applyToMesh(mesh);\r\n\r\n        if (keepSubMeshes) {\r\n            // We offset the materialIndex by the previous number of materials in the CSG mixed meshes\r\n            let materialIndexOffset = 0,\r\n                materialMaxIndex;\r\n\r\n            mesh.subMeshes = [] as SubMesh[];\r\n\r\n            for (const m in subMeshDict) {\r\n                materialMaxIndex = -1;\r\n                for (const sm in (<any>subMeshDict)[m]) {\r\n                    subMeshObj = (<any>subMeshDict)[m][sm];\r\n                    SubMesh.CreateFromIndices(\r\n                        subMeshObj.materialIndex + materialIndexOffset,\r\n                        subMeshObj.indexStart,\r\n                        subMeshObj.indexEnd - subMeshObj.indexStart + 1,\r\n                        <AbstractMesh>mesh\r\n                    );\r\n                    materialMaxIndex = Math.max(subMeshObj.materialIndex, materialMaxIndex);\r\n                }\r\n                materialIndexOffset += materialMaxIndex + 1;\r\n            }\r\n        }\r\n\r\n        return mesh;\r\n    }\r\n\r\n    /**\r\n     * Build Mesh from CSG taking material and transforms into account\r\n     * @param name The name of the Mesh\r\n     * @param material The material of the Mesh\r\n     * @param scene The Scene\r\n     * @param keepSubMeshes Specifies if submeshes should be kept\r\n     * @returns The new Mesh\r\n     */\r\n    public toMesh(name: string, material: Nullable<Material> = null, scene?: Scene, keepSubMeshes?: boolean): Mesh {\r\n        const mesh = this.buildMeshGeometry(name, scene, keepSubMeshes);\r\n\r\n        mesh.material = material;\r\n\r\n        mesh.position.copyFrom(this.position);\r\n        mesh.rotation.copyFrom(this.rotation);\r\n        if (this.rotationQuaternion) {\r\n            mesh.rotationQuaternion = this.rotationQuaternion.clone();\r\n        }\r\n        mesh.scaling.copyFrom(this.scaling);\r\n        mesh.computeWorldMatrix(true);\r\n\r\n        return mesh;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { type Vector3, Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type AbstractMesh } from \"./abstractMesh.pure\";\r\nimport { type ThinTexture } from \"core/Materials/Textures/thinTexture\";\r\nimport { type BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial.pure\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture.pure\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { PostProcess } from \"core/PostProcesses/postProcess.pure\";\r\n\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Options for the MeshUVSpaceRenderer\r\n * @since 5.49.1\r\n */\r\nexport interface IMeshUVSpaceRendererOptions {\r\n    /**\r\n     * Width of the texture. Default: 1024\r\n     */\r\n    width?: number;\r\n    /**\r\n     * Height of the texture. Default: 1024\r\n     */\r\n    height?: number;\r\n    /**\r\n     * Type of the texture. Default: Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n     */\r\n    textureType?: number;\r\n    /**\r\n     * Generate mip maps. Default: true\r\n     */\r\n    generateMipMaps?: boolean;\r\n    /**\r\n     * Optimize UV allocation. Default: true\r\n     * If you plan to use the texture as a decal map and rotate / offset the texture, you should set this to false\r\n     */\r\n    optimizeUVAllocation?: boolean;\r\n    /**\r\n     * If true, a post processing effect will be applied to the texture to fix seams. Default: false\r\n     */\r\n    uvEdgeBlending?: boolean;\r\n}\r\n\r\n/**\r\n * Class used to render in the mesh UV space\r\n * @since 5.49.1\r\n */\r\nexport class MeshUVSpaceRenderer {\r\n    private _mesh: AbstractMesh;\r\n    private _scene: Scene;\r\n    private _options: Required<IMeshUVSpaceRendererOptions>;\r\n    private _textureCreatedInternally = false;\r\n    private _configureUserCreatedTexture = true;\r\n    private _maskTexture: Nullable<RenderTargetTexture> = null;\r\n    private _finalPostProcess: Nullable<PostProcess> = null;\r\n    private _shadersLoaded = false;\r\n    private _isDisposed = false;\r\n\r\n    private static _GetShader(scene: Scene, shaderLanguage: ShaderLanguage): ShaderMaterial {\r\n        if (!scene._meshUVSpaceRendererShader) {\r\n            const shader = new ShaderMaterial(\r\n                \"meshUVSpaceRendererShader\",\r\n                scene,\r\n                {\r\n                    vertex: \"meshUVSpaceRenderer\",\r\n                    fragment: \"meshUVSpaceRenderer\",\r\n                },\r\n                {\r\n                    attributes: [\"position\", \"normal\", \"uv\"],\r\n                    uniforms: [\"world\", \"projMatrix\"],\r\n                    samplers: [\"textureSampler\"],\r\n                    needAlphaBlending: true,\r\n                    shaderLanguage: shaderLanguage,\r\n                }\r\n            );\r\n            shader.backFaceCulling = false;\r\n            shader.alphaMode = Constants.ALPHA_COMBINE;\r\n\r\n            scene.onDisposeObservable.add(() => {\r\n                scene._meshUVSpaceRendererShader?.dispose();\r\n                scene._meshUVSpaceRendererShader = null;\r\n            });\r\n\r\n            scene._meshUVSpaceRendererShader = shader;\r\n        }\r\n\r\n        return scene._meshUVSpaceRendererShader;\r\n    }\r\n\r\n    private static _GetMaskShader(scene: Scene, shaderLanguage: ShaderLanguage): ShaderMaterial {\r\n        if (!scene._meshUVSpaceRendererMaskShader) {\r\n            const shader = new ShaderMaterial(\r\n                \"meshUVSpaceRendererMaskShader\",\r\n                scene,\r\n                {\r\n                    vertex: \"meshUVSpaceRendererMasker\",\r\n                    fragment: \"meshUVSpaceRendererMasker\",\r\n                },\r\n                {\r\n                    attributes: [\"position\", \"uv\"],\r\n                    uniforms: [\"worldViewProjection\"],\r\n                    shaderLanguage: shaderLanguage,\r\n                }\r\n            );\r\n            shader.backFaceCulling = false;\r\n            shader.alphaMode = Constants.ALPHA_COMBINE;\r\n\r\n            scene.onDisposeObservable.add(() => {\r\n                scene._meshUVSpaceRendererMaskShader?.dispose();\r\n                scene._meshUVSpaceRendererMaskShader = null;\r\n            });\r\n\r\n            scene._meshUVSpaceRendererMaskShader = shader;\r\n        }\r\n        return scene._meshUVSpaceRendererMaskShader;\r\n    }\r\n\r\n    private static _IsRenderTargetTexture(texture: ThinTexture | RenderTargetTexture): texture is RenderTargetTexture {\r\n        return (texture as RenderTargetTexture).renderList !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Clear color of the texture\r\n     */\r\n    public clearColor = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * Target texture used for rendering\r\n     * If you don't set the property, a RenderTargetTexture will be created internally given the options provided to the constructor.\r\n     * If you provide a RenderTargetTexture, it will be used directly.\r\n     */\r\n    public texture: Nullable<Texture> = null;\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Creates a new MeshUVSpaceRenderer\r\n     * @param mesh The mesh used for the source UV space\r\n     * @param scene The scene the mesh belongs to\r\n     * @param options The options to use when creating the texture\r\n     */\r\n    constructor(mesh: AbstractMesh, scene: Scene, options?: IMeshUVSpaceRendererOptions) {\r\n        this._mesh = mesh;\r\n        this._scene = scene;\r\n        this._options = {\r\n            width: 1024,\r\n            height: 1024,\r\n            textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            generateMipMaps: true,\r\n            optimizeUVAllocation: true,\r\n            uvEdgeBlending: false,\r\n            ...options,\r\n        };\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n    }\r\n\r\n    private async _initShaderSourceAsync() {\r\n        const engine = this._scene.getEngine();\r\n\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n            await Promise.all([\r\n                import(\"../ShadersWGSL/meshUVSpaceRenderer.vertex\"),\r\n                import(\"../ShadersWGSL/meshUVSpaceRenderer.fragment\"),\r\n                import(\"../ShadersWGSL/meshUVSpaceRendererMasker.vertex\"),\r\n                import(\"../ShadersWGSL/meshUVSpaceRendererMasker.fragment\"),\r\n                import(\"../ShadersWGSL/meshUVSpaceRendererFinaliser.vertex\"),\r\n                import(\"../ShadersWGSL/meshUVSpaceRendererFinaliser.fragment\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../Shaders/meshUVSpaceRenderer.vertex\"),\r\n                import(\"../Shaders/meshUVSpaceRenderer.fragment\"),\r\n                import(\"../Shaders/meshUVSpaceRendererMasker.vertex\"),\r\n                import(\"../Shaders/meshUVSpaceRendererMasker.fragment\"),\r\n                import(\"../Shaders/meshUVSpaceRendererFinaliser.vertex\"),\r\n                import(\"../Shaders/meshUVSpaceRendererFinaliser.fragment\"),\r\n            ]);\r\n        }\r\n\r\n        if (this._isDisposed) {\r\n            return;\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n    }\r\n\r\n    /**\r\n     * Checks if the texture is ready to be used\r\n     * @returns true if the texture is ready to be used\r\n     */\r\n    public isReady(): boolean {\r\n        if (!this._shadersLoaded) {\r\n            return false;\r\n        }\r\n\r\n        if (!this.texture) {\r\n            this._createDiffuseRTT();\r\n        } else if (this._configureUserCreatedTexture) {\r\n            this._configureUserCreatedRTT();\r\n        }\r\n\r\n        // this.texture is guaranteed to be non-null here as it is created in _createDiffuseRTT above\r\n        const textureIsReady = MeshUVSpaceRenderer._IsRenderTargetTexture(this.texture!) ? this.texture.isReadyForRendering() : this.texture!.isReady();\r\n        const maskIsReady = this._maskTexture?.isReadyForRendering() ?? true;\r\n        const postProcessIsReady = this._finalPostProcess?.isReady() ?? true;\r\n\r\n        return textureIsReady && maskIsReady && postProcessIsReady;\r\n    }\r\n\r\n    /**\r\n     * Projects and renders a texture in the mesh UV space\r\n     * @param texture The texture\r\n     * @param position The position of the center of projection (world space coordinates)\r\n     * @param normal The direction of the projection (world space coordinates)\r\n     * @param size The size of the projection\r\n     * @param angle The rotation angle around the direction of the projection (default: 0)\r\n     * @param checkIsReady If true, it will check if the texture is ready before rendering (default: true). If the texture is not ready, a new attempt will be scheduled in 16ms\r\n     */\r\n    public renderTexture(texture: BaseTexture, position: Vector3, normal: Vector3, size: Vector3, angle = 0, checkIsReady = true): void {\r\n        if (checkIsReady && !this.isReady()) {\r\n            setTimeout(() => {\r\n                this.renderTexture(texture, position, normal, size, angle, checkIsReady);\r\n            }, 16);\r\n            return;\r\n        }\r\n\r\n        if (!this.texture) {\r\n            this._createDiffuseRTT();\r\n        } else if (this._configureUserCreatedTexture) {\r\n            this._configureUserCreatedRTT();\r\n        }\r\n\r\n        // this.texture is guaranteed to be non-null here as it is created in _createDiffuseRTT above\r\n        if (MeshUVSpaceRenderer._IsRenderTargetTexture(this.texture!)) {\r\n            const matrix = this._createProjectionMatrix(position, normal, size, angle);\r\n            const shader = MeshUVSpaceRenderer._GetShader(this._scene, this._shaderLanguage);\r\n\r\n            shader.setTexture(\"textureSampler\", texture);\r\n            shader.setMatrix(\"projMatrix\", matrix);\r\n\r\n            this.texture.render();\r\n\r\n            // We needed the texture only once for the render() call above, so we can remove it from the shader.\r\n            // It's important to do that, because this texture could be disposed by the user, meaning that shader.isReady() would return false as part of the this.texture.isReadyForRendering() call of isReady()\r\n            shader.removeTexture(\"textureSampler\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clears the texture map\r\n     */\r\n    public clear(): void {\r\n        if (this.texture && MeshUVSpaceRenderer._IsRenderTargetTexture(this.texture) && this.texture.renderTarget) {\r\n            const engine = this._scene.getEngine();\r\n\r\n            engine.bindFramebuffer(this.texture.renderTarget);\r\n            engine.clear(this.clearColor, true, true, true);\r\n            engine.unBindFramebuffer(this.texture.renderTarget);\r\n        }\r\n        if (this._finalPostProcess?.inputTexture) {\r\n            const engine = this._scene.getEngine();\r\n\r\n            engine.bindFramebuffer(this._finalPostProcess?.inputTexture);\r\n            engine.clear(this.clearColor, true, true, true);\r\n            engine.unBindFramebuffer(this._finalPostProcess?.inputTexture);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the resources\r\n     */\r\n    public dispose() {\r\n        if (this._textureCreatedInternally) {\r\n            this.texture?.dispose();\r\n            this._textureCreatedInternally = false;\r\n        }\r\n        this._configureUserCreatedTexture = true;\r\n        this._maskTexture?.dispose();\r\n        this._maskTexture = null;\r\n        this._finalPostProcess?.dispose();\r\n        this._finalPostProcess = null;\r\n        this._isDisposed = true;\r\n    }\r\n\r\n    private _configureUserCreatedRTT(): void {\r\n        this._configureUserCreatedTexture = false;\r\n        if (this.texture && MeshUVSpaceRenderer._IsRenderTargetTexture(this.texture)) {\r\n            this.texture.setMaterialForRendering(this._mesh, MeshUVSpaceRenderer._GetShader(this._scene, this._shaderLanguage));\r\n            this.texture.onClearObservable.add(() => {});\r\n            this.texture.renderList = [this._mesh];\r\n            if (this._options.uvEdgeBlending) {\r\n                this._createMaskTexture();\r\n                this._createPostProcess();\r\n                this.texture.addPostProcess(this._finalPostProcess!);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _createDiffuseRTT(): void {\r\n        this._textureCreatedInternally = true;\r\n\r\n        const texture = this._createRenderTargetTexture(this._options.width, this._options.height);\r\n\r\n        texture.setMaterialForRendering(this._mesh, MeshUVSpaceRenderer._GetShader(this._scene, this._shaderLanguage));\r\n\r\n        this.texture = texture;\r\n        this._configureUserCreatedTexture = false;\r\n        if (this._options.uvEdgeBlending) {\r\n            this._createMaskTexture();\r\n            this._createPostProcess();\r\n            texture.addPostProcess(this._finalPostProcess!);\r\n        }\r\n    }\r\n\r\n    private _createMaskTexture(): void {\r\n        if (this._maskTexture) {\r\n            return;\r\n        }\r\n\r\n        this._maskTexture = new RenderTargetTexture(\r\n            this._mesh.name + \"_maskTexture\",\r\n            { width: this._options.width, height: this._options.height },\r\n            this._scene,\r\n            false, // No mipmaps for the mask texture\r\n            true,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            false,\r\n            Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            Constants.TEXTUREFORMAT_R\r\n        );\r\n\r\n        this._maskTexture.clearColor = new Color4(0, 0, 0, 0);\r\n\r\n        // Render the mesh with the mask material to the mask texture\r\n        this._maskTexture.renderList!.push(this._mesh);\r\n        this._maskTexture.setMaterialForRendering(this._mesh, MeshUVSpaceRenderer._GetMaskShader(this._scene, this._shaderLanguage));\r\n\r\n        // Ensure the mask texture is updated\r\n        this._maskTexture.refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;\r\n        this._scene.customRenderTargets.push(this._maskTexture);\r\n    }\r\n\r\n    private _createPostProcess(): void {\r\n        if (this._finalPostProcess) {\r\n            return;\r\n        }\r\n\r\n        this._finalPostProcess = new PostProcess(\r\n            this._mesh.name + \"_fixSeamsPostProcess\",\r\n            \"meshUVSpaceRendererFinaliser\",\r\n            [\"textureSize\"],\r\n            [\"textureSampler\", \"maskTextureSampler\"],\r\n            1.0,\r\n            null,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false,\r\n            null,\r\n            this._options.textureType,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            this._shaderLanguage\r\n        );\r\n\r\n        this._finalPostProcess.onApplyObservable.add((effect) => {\r\n            effect.setTexture(\"maskTextureSampler\", this._maskTexture);\r\n            effect.setFloat2(\"textureSize\", this._options.width, this._options.height);\r\n        });\r\n    }\r\n\r\n    private _createRenderTargetTexture(width: number, height: number): RenderTargetTexture {\r\n        const rtt = new RenderTargetTexture(\r\n            this._mesh.name + \"_uvspaceTexture\",\r\n            { width, height },\r\n            this._scene,\r\n            this._options.generateMipMaps,\r\n            true,\r\n            this._options.textureType,\r\n            false,\r\n            this._options.generateMipMaps ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n            false,\r\n            false,\r\n            false,\r\n            Constants.TEXTUREFORMAT_RGBA\r\n        );\r\n\r\n        rtt.renderParticles = false;\r\n        rtt.optimizeUVAllocation = !!this._options.optimizeUVAllocation;\r\n\r\n        rtt.onClearObservable.addOnce(() => {\r\n            this._scene.getEngine().clear(this.clearColor, true, true, true);\r\n            rtt.onClearObservable.add(() => {}); // this disables clearing the texture for the next frames\r\n        });\r\n\r\n        rtt.renderList = [this._mesh];\r\n\r\n        return rtt;\r\n    }\r\n\r\n    private _createProjectionMatrix(position: Vector3, normal: Vector3, size: Vector3, angle = 0): Matrix {\r\n        const yaw = -Math.atan2(normal.z, normal.x) - Math.PI / 2;\r\n        const len = Math.sqrt(normal.x * normal.x + normal.z * normal.z);\r\n        const pitch = Math.atan2(normal.y, len);\r\n\r\n        const p = position.add(normal.scale(size.z * 0.5));\r\n\r\n        const projWorldMatrix = Matrix.RotationYawPitchRoll(yaw, pitch, angle).multiply(Matrix.Translation(p.x, p.y, p.z));\r\n        const inverseProjWorldMatrix = Matrix.Invert(projWorldMatrix);\r\n\r\n        const projMatrix = Matrix.FromArray([2 / size.x, 0, 0, 0, 0, 2 / size.y, 0, 0, 0, 0, 1 / size.z, 0, 0, 0, 0, 1]);\r\n\r\n        const screenMatrix = Matrix.FromArray([0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, 0.5, 0.5, 0.0, 1]);\r\n\r\n        return inverseProjWorldMatrix.multiply(projMatrix).multiply(screenMatrix);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { Lerp } from \"../Maths/math.scalar.functions\";\r\nimport { type TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\n\r\n/**\r\n * Options to be used when creating a trail mesh\r\n */\r\nexport interface ITrailMeshOptions {\r\n    /**\r\n     * diameter of trailing mesh (default: 1)\r\n     */\r\n    diameter?: number;\r\n    /**\r\n     * length of trailing mesh (default: 60)\r\n     */\r\n    length?: number;\r\n    /**\r\n     * segments of trailing mesh (default: length)\r\n     */\r\n    segments?: number;\r\n    /**\r\n     * sections of trailing mesh (default: 4)\r\n     */\r\n    sections?: number;\r\n    /**\r\n     * tapers the trailing mesh (default: false)\r\n     */\r\n    doNotTaper?: boolean;\r\n    /**\r\n     * automatically start trailing mesh. (default: true)\r\n     */\r\n    autoStart?: boolean;\r\n}\r\n\r\n/**\r\n * Class used to create a trail following a mesh\r\n */\r\nexport class TrailMesh extends Mesh {\r\n    /**\r\n     * The diameter of the trail, i.e. the width of the ribbon.\r\n     */\r\n    public diameter: number;\r\n\r\n    private _generator: TransformNode;\r\n    private _autoStart: boolean;\r\n    private _running: boolean;\r\n    private _doNotTaper: boolean;\r\n    private _length: number;\r\n    private _segments: number;\r\n    private _sectionPolygonPointsCount: number = 4;\r\n    private _sectionVectors: Array<Vector3>;\r\n    private _sectionNormalVectors: Array<Vector3>;\r\n    private _beforeRenderObserver: Nullable<Observer<Scene>>;\r\n\r\n    /**\r\n     * Constructor\r\n     * @param name The value used by scene.getMeshByName() to do a lookup.\r\n     * @param generator The mesh or transform node to generate a trail.\r\n     * @param scene The scene to add this mesh to.\r\n     * @param diameter Diameter of trailing mesh. Default is 1.\r\n     * @param length Length of trailing mesh. Default is 60.\r\n     * @param autoStart Automatically start trailing mesh. Default true.\r\n     */\r\n    constructor(name: string, generator: TransformNode, scene?: Scene, diameter?: number, length?: number, autoStart?: boolean);\r\n\r\n    /**\r\n     * Constructor\r\n     * @param name The value used by scene.getMeshByName() to do a lookup.\r\n     * @param generator The mesh or transform node to generate a trail.\r\n     * @param scene The scene to add this mesh to.\r\n     * @param options defines the options used to create the mesh.\r\n     */\r\n    constructor(name: string, generator: TransformNode, scene?: Scene, options?: ITrailMeshOptions);\r\n\r\n    /** @internal */\r\n    constructor(name: string, generator: TransformNode, scene?: Scene, diameterOrOptions?: number | ITrailMeshOptions, length: number = 60, autoStart: boolean = true) {\r\n        super(name, scene);\r\n\r\n        this._running = false;\r\n        this._generator = generator;\r\n\r\n        if (typeof diameterOrOptions === \"object\" && diameterOrOptions !== null) {\r\n            this.diameter = diameterOrOptions.diameter || 1;\r\n            this._length = diameterOrOptions.length || 60;\r\n            this._segments = diameterOrOptions.segments ? (diameterOrOptions.segments > this._length ? this._length : diameterOrOptions.segments) : this._length;\r\n            this._sectionPolygonPointsCount = diameterOrOptions.sections || 4;\r\n            this._doNotTaper = diameterOrOptions.doNotTaper ?? false;\r\n            this._autoStart = diameterOrOptions.autoStart ?? true;\r\n        } else {\r\n            this.diameter = diameterOrOptions || 1;\r\n            this._length = length;\r\n            this._segments = this._length;\r\n            this._doNotTaper = false;\r\n            this._autoStart = autoStart;\r\n        }\r\n\r\n        this._sectionVectors = [];\r\n        this._sectionNormalVectors = [];\r\n        for (let i: number = 0; i <= this._sectionPolygonPointsCount; i++) {\r\n            this._sectionVectors[i] = Vector3.Zero();\r\n            this._sectionNormalVectors[i] = Vector3.Zero();\r\n        }\r\n        this._createMesh();\r\n    }\r\n\r\n    /**\r\n     * \"TrailMesh\"\r\n     * @returns \"TrailMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"TrailMesh\";\r\n    }\r\n\r\n    private _createMesh(): void {\r\n        const data: VertexData = new VertexData();\r\n        const positions: Array<number> = [];\r\n        const normals: Array<number> = [];\r\n        const indices: Array<number> = [];\r\n        const uvs: Array<number> = [];\r\n        let meshCenter: Vector3;\r\n        if (this._generator instanceof AbstractMesh && this._generator.hasBoundingInfo) {\r\n            meshCenter = this._generator.getBoundingInfo().boundingBox.centerWorld;\r\n        } else {\r\n            meshCenter = this._generator.absolutePosition;\r\n        }\r\n        const alpha: number = (2 * Math.PI) / this._sectionPolygonPointsCount;\r\n        for (let i: number = 0; i <= this._sectionPolygonPointsCount; i++) {\r\n            const angle = i !== this._sectionPolygonPointsCount ? i * alpha : 0;\r\n            positions.push(meshCenter.x + Math.cos(angle) * this.diameter, meshCenter.y + Math.sin(angle) * this.diameter, meshCenter.z);\r\n            uvs.push(i / this._sectionPolygonPointsCount, 0);\r\n        }\r\n        for (let i: number = 1; i <= this._segments; i++) {\r\n            for (let j: number = 0; j <= this._sectionPolygonPointsCount; j++) {\r\n                const angle = j !== this._sectionPolygonPointsCount ? j * alpha : 0;\r\n                positions.push(meshCenter.x + Math.cos(angle) * this.diameter, meshCenter.y + Math.sin(angle) * this.diameter, meshCenter.z);\r\n                uvs.push(j / this._sectionPolygonPointsCount, i / this._segments);\r\n            }\r\n            const l: number = positions.length / 3 - 2 * (this._sectionPolygonPointsCount + 1);\r\n            for (let j: number = 0; j <= this._sectionPolygonPointsCount; j++) {\r\n                indices.push(l + j, l + j + this._sectionPolygonPointsCount, l + j + this._sectionPolygonPointsCount + 1);\r\n                indices.push(l + j, l + j + this._sectionPolygonPointsCount + 1, l + j + 1);\r\n            }\r\n        }\r\n        VertexData.ComputeNormals(positions, indices, normals);\r\n        data.positions = positions;\r\n        data.normals = normals;\r\n        data.indices = indices;\r\n        data.uvs = uvs;\r\n        data.applyToMesh(this, true);\r\n        if (this._autoStart) {\r\n            this.start();\r\n        }\r\n    }\r\n\r\n    private _updateSectionVectors(): void {\r\n        const wm = this._generator.getWorldMatrix();\r\n        const alpha: number = (2 * Math.PI) / this._sectionPolygonPointsCount;\r\n        for (let i: number = 0; i <= this._sectionPolygonPointsCount; i++) {\r\n            const angle = i !== this._sectionPolygonPointsCount ? i * alpha : 0;\r\n            this._sectionVectors[i].copyFromFloats(Math.cos(angle) * this.diameter, Math.sin(angle) * this.diameter, 0);\r\n            this._sectionNormalVectors[i].copyFromFloats(Math.cos(angle), Math.sin(angle), 0);\r\n            Vector3.TransformCoordinatesToRef(this._sectionVectors[i], wm, this._sectionVectors[i]);\r\n            Vector3.TransformNormalToRef(this._sectionNormalVectors[i], wm, this._sectionNormalVectors[i]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Start trailing mesh.\r\n     */\r\n    public start(): void {\r\n        if (!this._running) {\r\n            this._running = true;\r\n            this._beforeRenderObserver = this.getScene().onBeforeRenderObservable.add(() => {\r\n                this.update();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stop trailing mesh.\r\n     */\r\n    public stop(): void {\r\n        if (this._beforeRenderObserver && this._running) {\r\n            this._running = false;\r\n            this.getScene().onBeforeRenderObservable.remove(this._beforeRenderObserver);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update trailing mesh geometry.\r\n     */\r\n    public update(): void {\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n        const normals = this.getVerticesData(VertexBuffer.NormalKind);\r\n        const index = 3 * (this._sectionPolygonPointsCount + 1);\r\n        if (positions && normals) {\r\n            if (this._doNotTaper) {\r\n                for (let i: number = index; i < positions.length; i++) {\r\n                    positions[i - index] = Lerp(positions[i - index], positions[i], this._segments / this._length);\r\n                }\r\n            } else {\r\n                for (let i: number = index; i < positions.length; i++) {\r\n                    positions[i - index] = Lerp(positions[i - index], positions[i], this._segments / this._length) - (normals[i] / this._length) * this.diameter;\r\n                }\r\n            }\r\n            for (let i: number = index; i < normals.length; i++) {\r\n                normals[i - index] = Lerp(normals[i - index], normals[i], this._segments / this._length);\r\n            }\r\n            this._updateSectionVectors();\r\n            const l: number = positions.length - 3 * (this._sectionPolygonPointsCount + 1);\r\n            for (let i: number = 0; i <= this._sectionPolygonPointsCount; i++) {\r\n                positions[l + 3 * i] = this._sectionVectors[i].x;\r\n                positions[l + 3 * i + 1] = this._sectionVectors[i].y;\r\n                positions[l + 3 * i + 2] = this._sectionVectors[i].z;\r\n                normals[l + 3 * i] = this._sectionNormalVectors[i].x;\r\n                normals[l + 3 * i + 1] = this._sectionNormalVectors[i].y;\r\n                normals[l + 3 * i + 2] = this._sectionNormalVectors[i].z;\r\n            }\r\n            this.updateVerticesData(VertexBuffer.PositionKind, positions, true, false);\r\n            this.updateVerticesData(VertexBuffer.NormalKind, normals, true, false);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reset trailing mesh geometry.\r\n     */\r\n    public reset(): void {\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n        const normals = this.getVerticesData(VertexBuffer.NormalKind);\r\n        if (positions && normals) {\r\n            this._updateSectionVectors();\r\n            for (let i: number = 0; i <= this._segments; i++) {\r\n                const l: number = 3 * i * (this._sectionPolygonPointsCount + 1);\r\n                for (let j: number = 0; j <= this._sectionPolygonPointsCount; j++) {\r\n                    positions[l + 3 * j] = this._sectionVectors[j].x;\r\n                    positions[l + 3 * j + 1] = this._sectionVectors[j].y;\r\n                    positions[l + 3 * j + 2] = this._sectionVectors[j].z;\r\n                    normals[l + 3 * j] = this._sectionNormalVectors[j].x;\r\n                    normals[l + 3 * j + 1] = this._sectionNormalVectors[j].y;\r\n                    normals[l + 3 * j + 2] = this._sectionNormalVectors[j].z;\r\n                }\r\n            }\r\n            this.updateVerticesData(VertexBuffer.PositionKind, positions, true, false);\r\n            this.updateVerticesData(VertexBuffer.NormalKind, normals, true, false);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a new TrailMesh object.\r\n     * @param name is a string, the name given to the new mesh\r\n     * @param newGenerator use new generator object for cloned trail mesh\r\n     * @returns a new mesh\r\n     */\r\n    public override clone(name: string = \"\", newGenerator: TransformNode): TrailMesh {\r\n        const options = {\r\n            diameter: this.diameter,\r\n            length: this._length,\r\n            segments: this._segments,\r\n            sections: this._sectionPolygonPointsCount,\r\n            doNotTaper: this._doNotTaper,\r\n            autoStart: this._autoStart,\r\n        };\r\n        return new TrailMesh(name, newGenerator ?? this._generator, this.getScene(), options);\r\n    }\r\n\r\n    /**\r\n     * Serializes this trail mesh\r\n     * @param serializationObject object to write serialization to\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n\r\n        serializationObject.generatorId = this._generator.id;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized trail mesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the trail mesh in\r\n     * @returns the created trail mesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): TrailMesh {\r\n        const generator = scene.getLastMeshById(parsedMesh.generatorId) ?? scene.getLastTransformNodeById(parsedMesh.generatorId);\r\n\r\n        if (!generator) {\r\n            throw new Error(\"TrailMesh: generator not found with ID \" + parsedMesh.generatorId);\r\n        }\r\n\r\n        const options = {\r\n            diameter: parsedMesh.diameter ?? parsedMesh._diameter,\r\n            length: parsedMesh._length,\r\n            segments: parsedMesh._segments,\r\n            sections: parsedMesh._sectionPolygonPointsCount,\r\n            doNotTaper: parsedMesh._doNotTaper,\r\n            autoStart: parsedMesh._autoStart,\r\n        };\r\n        return new TrailMesh(parsedMesh.name, generator, scene, options);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for trailMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTrailMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._TrailMeshParser = (parsedMesh: any, scene: Scene) => {\r\n        return TrailMesh.Parse(parsedMesh, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\n\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { Mesh } from \"./mesh.pure\";\r\nimport { type SimplificationQueue } from \"./meshSimplification\";\r\nimport { type ISimplificationSettings, SimplificationType } from \"./meshSimplification.common\";\r\n\r\n/**\r\n * Defines the simplification queue scene component responsible to help scheduling the various simplification task\r\n * created in a scene\r\n */\r\nexport class SimplicationQueueSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpfull to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_SIMPLIFICATIONQUEUE;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._beforeCameraUpdateStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE, this, this._beforeCameraUpdate);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    private _beforeCameraUpdate(): void {\r\n        if (this.scene._simplificationQueue && !this.scene._simplificationQueue.running) {\r\n            this.scene._simplificationQueue.executeNext();\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshSimplificationSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param simplificationQueueClass The SimplificationQueue class to use for lazy instantiation\r\n */\r\nexport function RegisterMeshSimplificationSceneComponent(simplificationQueueClass: typeof SimplificationQueue): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"simplificationQueue\", {\r\n        get: function (this: Scene) {\r\n            if (!this._simplificationQueue) {\r\n                this._simplificationQueue = new simplificationQueueClass();\r\n                let component = this._getComponent(SceneComponentConstants.NAME_SIMPLIFICATIONQUEUE) as SimplicationQueueSceneComponent;\r\n                if (!component) {\r\n                    component = new SimplicationQueueSceneComponent(this);\r\n                    this._addComponent(component);\r\n                }\r\n            }\r\n            return this._simplificationQueue;\r\n        },\r\n        set: function (this: Scene, value: SimplificationQueue) {\r\n            this._simplificationQueue = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Mesh.prototype.simplify = function (\r\n        settings: Array<ISimplificationSettings>,\r\n        parallelProcessing: boolean = true,\r\n        simplificationType: SimplificationType = SimplificationType.QUADRATIC,\r\n        successCallback?: (mesh?: Mesh, submeshIndex?: number) => void\r\n    ): Mesh {\r\n        this.getScene().simplificationQueue.addTask({\r\n            settings: settings,\r\n            parallelProcessing: parallelProcessing,\r\n            mesh: this,\r\n            simplificationType: simplificationType,\r\n            successCallback: successCallback,\r\n        });\r\n        return this;\r\n    };\r\n}\r\n","/**\n * Expected simplification settings.\n * Quality should be between 0 and 1 (1 being 100%, 0 being 0%)\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/simplifyingMeshes\n */\nexport interface ISimplificationSettings {\n    /**\n     * Gets or sets the expected quality\n     */\n    quality: number;\n    /**\n     * Gets or sets the distance when this optimized version should be used\n     */\n    distance: number;\n    /**\n     * Gets an already optimized mesh\n     */\n    optimizeMesh?: boolean | undefined;\n}\n\n/**\n * Class used to specify simplification options\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/simplifyingMeshes\n */\nexport class SimplificationSettings implements ISimplificationSettings {\n    /**\n     * Creates a SimplificationSettings\n     * @param quality expected quality\n     * @param distance distance when this optimized version should be used\n     * @param optimizeMesh already optimized mesh\n     */\n    constructor(\n        /** expected quality */\n        public quality: number,\n        /** distance when this optimized version should be used */\n        public distance: number,\n        /** already optimized mesh  */\n        public optimizeMesh?: boolean\n    ) {}\n}\n\n/**\n * The implemented types of simplification\n * At the moment only Quadratic Error Decimation is implemented\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/simplifyingMeshes\n */\nexport const enum SimplificationType {\n    /** Quadratic error decimation */\n    QUADRATIC,\n}\n","import { type IndicesArray } from \"../types\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { SubMesh } from \"../Meshes/subMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { AsyncLoop } from \"../Misc/tools.pure\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { RegisterMeshSimplificationSceneComponent } from \"./meshSimplificationSceneComponent.pure\";\r\nimport { type ISimplificationSettings, SimplificationType } from \"./meshSimplification.common\";\r\n\r\nexport { SimplificationSettings, SimplificationType } from \"./meshSimplification.common\";\r\nexport { type ISimplificationSettings } from \"./meshSimplification.common\";\r\n\r\n/**\r\n * A simplifier interface for future simplification implementations\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/simplifyingMeshes\r\n */\r\nexport interface ISimplifier {\r\n    /**\r\n     * Simplification of a given mesh according to the given settings.\r\n     * Since this requires computation, it is assumed that the function runs async.\r\n     * @param settings The settings of the simplification, including quality and distance\r\n     * @param successCallback A callback that will be called after the mesh was simplified.\r\n     * @param errorCallback in case of an error, this callback will be called. optional.\r\n     */\r\n    simplify(settings: ISimplificationSettings, successCallback: (simplifiedMeshes: Mesh) => void, errorCallback?: () => void): void;\r\n}\r\n\r\n/**\r\n * Interface used to define a simplification task\r\n */\r\nexport interface ISimplificationTask {\r\n    /**\r\n     * Array of settings\r\n     */\r\n    settings: Array<ISimplificationSettings>;\r\n    /**\r\n     * Simplification type\r\n     */\r\n    simplificationType: SimplificationType;\r\n    /**\r\n     * Mesh to simplify\r\n     */\r\n    mesh: Mesh;\r\n    /**\r\n     * Callback called on success\r\n     */\r\n    successCallback?: () => void;\r\n    /**\r\n     * Defines if parallel processing can be used\r\n     */\r\n    parallelProcessing: boolean;\r\n}\r\n\r\n/**\r\n * Queue used to order the simplification tasks\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/simplifyingMeshes\r\n */\r\nexport class SimplificationQueue {\r\n    private _simplificationArray: Array<ISimplificationTask>;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the process is still running\r\n     */\r\n    public running: boolean;\r\n\r\n    /**\r\n     * Creates a new queue\r\n     */\r\n    constructor() {\r\n        RegisterMeshSimplificationSceneComponent(SimplificationQueue);\r\n        this.running = false;\r\n        this._simplificationArray = [];\r\n    }\r\n\r\n    /**\r\n     * Adds a new simplification task\r\n     * @param task defines a task to add\r\n     */\r\n    public addTask(task: ISimplificationTask) {\r\n        this._simplificationArray.push(task);\r\n    }\r\n\r\n    /**\r\n     * Execute next task\r\n     */\r\n    public executeNext() {\r\n        const task = this._simplificationArray.pop();\r\n        if (task) {\r\n            this.running = true;\r\n            this.runSimplification(task);\r\n        } else {\r\n            this.running = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Execute a simplification task\r\n     * @param task defines the task to run\r\n     */\r\n    public runSimplification(task: ISimplificationTask) {\r\n        if (task.parallelProcessing) {\r\n            //parallel simplifier\r\n            for (const setting of task.settings) {\r\n                const simplifier = this._getSimplifier(task);\r\n                simplifier.simplify(setting, (newMesh) => {\r\n                    if (setting.distance !== undefined) {\r\n                        task.mesh.addLODLevel(setting.distance, newMesh);\r\n                    }\r\n                    newMesh.isVisible = true;\r\n                    //check if it is the last\r\n                    if (setting.quality === task.settings[task.settings.length - 1].quality && task.successCallback) {\r\n                        //all done, run the success callback.\r\n                        task.successCallback();\r\n                    }\r\n                    this.executeNext();\r\n                });\r\n            }\r\n        } else {\r\n            //single simplifier.\r\n            const simplifier = this._getSimplifier(task);\r\n\r\n            const runDecimation = (setting: ISimplificationSettings, callback: () => void) => {\r\n                simplifier.simplify(setting, (newMesh) => {\r\n                    if (setting.distance !== undefined) {\r\n                        task.mesh.addLODLevel(setting.distance, newMesh);\r\n                    }\r\n                    newMesh.isVisible = true;\r\n                    //run the next quality level\r\n                    callback();\r\n                });\r\n            };\r\n\r\n            AsyncLoop.Run(\r\n                task.settings.length,\r\n                (loop: AsyncLoop) => {\r\n                    runDecimation(task.settings[loop.index], () => {\r\n                        loop.executeNext();\r\n                    });\r\n                },\r\n                () => {\r\n                    //execution ended, run the success callback.\r\n                    if (task.successCallback) {\r\n                        task.successCallback();\r\n                    }\r\n                    this.executeNext();\r\n                }\r\n            );\r\n        }\r\n    }\r\n\r\n    private _getSimplifier(task: ISimplificationTask): ISimplifier {\r\n        switch (task.simplificationType) {\r\n            case SimplificationType.QUADRATIC:\r\n            default:\r\n                return new QuadraticErrorSimplification(task.mesh);\r\n        }\r\n    }\r\n}\r\n\r\nclass DecimationTriangle {\r\n    /** @internal */\r\n    public normal: Vector3;\r\n    /** @internal */\r\n    public error: Array<number>;\r\n    /** @internal */\r\n    public deleted: boolean;\r\n    /** @internal */\r\n    public isDirty: boolean;\r\n    /** @internal */\r\n    public borderFactor: number;\r\n    /** @internal */\r\n    public deletePending: boolean;\r\n\r\n    /** @internal */\r\n    public originalOffset: number;\r\n\r\n    constructor(public _vertices: Array<DecimationVertex>) {\r\n        this.error = new Array<number>(4);\r\n        this.deleted = false;\r\n        this.isDirty = false;\r\n        this.deletePending = false;\r\n        this.borderFactor = 0;\r\n    }\r\n}\r\n\r\nclass DecimationVertex {\r\n    /** @internal */\r\n    public q: QuadraticMatrix;\r\n    /** @internal */\r\n    public isBorder: boolean;\r\n\r\n    /** @internal */\r\n    public triangleStart: number;\r\n    /** @internal */\r\n    public triangleCount: number;\r\n\r\n    /** @internal */\r\n    public originalOffsets: Array<number>;\r\n\r\n    constructor(\r\n        public position: Vector3,\r\n        public id: number\r\n    ) {\r\n        this.isBorder = true;\r\n        this.q = new QuadraticMatrix();\r\n        this.triangleCount = 0;\r\n        this.triangleStart = 0;\r\n        this.originalOffsets = [];\r\n    }\r\n\r\n    /** @internal */\r\n    public updatePosition(newPosition: Vector3) {\r\n        this.position.copyFrom(newPosition);\r\n    }\r\n}\r\n\r\nclass QuadraticMatrix {\r\n    /** @internal */\r\n    public data: Array<number>;\r\n\r\n    constructor(data?: Array<number>) {\r\n        this.data = new Array(10);\r\n        for (let i = 0; i < 10; ++i) {\r\n            if (data && data[i]) {\r\n                this.data[i] = data[i];\r\n            } else {\r\n                this.data[i] = 0;\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public det(a11: number, a12: number, a13: number, a21: number, a22: number, a23: number, a31: number, a32: number, a33: number): number {\r\n        const det =\r\n            this.data[a11] * this.data[a22] * this.data[a33] +\r\n            this.data[a13] * this.data[a21] * this.data[a32] +\r\n            this.data[a12] * this.data[a23] * this.data[a31] -\r\n            this.data[a13] * this.data[a22] * this.data[a31] -\r\n            this.data[a11] * this.data[a23] * this.data[a32] -\r\n            this.data[a12] * this.data[a21] * this.data[a33];\r\n        return det;\r\n    }\r\n\r\n    /** @internal */\r\n    public addInPlace(matrix: QuadraticMatrix) {\r\n        for (let i = 0; i < 10; ++i) {\r\n            this.data[i] += matrix.data[i];\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public addArrayInPlace(data: Array<number>) {\r\n        for (let i = 0; i < 10; ++i) {\r\n            this.data[i] += data[i];\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public add(matrix: QuadraticMatrix): QuadraticMatrix {\r\n        const m = new QuadraticMatrix();\r\n        for (let i = 0; i < 10; ++i) {\r\n            m.data[i] = this.data[i] + matrix.data[i];\r\n        }\r\n        return m;\r\n    }\r\n\r\n    /** @internal */\r\n    public static FromData(a: number, b: number, c: number, d: number): QuadraticMatrix {\r\n        return new QuadraticMatrix(QuadraticMatrix.DataFromNumbers(a, b, c, d));\r\n    }\r\n\r\n    //returning an array to avoid garbage collection\r\n    public static DataFromNumbers(a: number, b: number, c: number, d: number) {\r\n        return [a * a, a * b, a * c, a * d, b * b, b * c, b * d, c * c, c * d, d * d];\r\n    }\r\n}\r\n\r\nclass Reference {\r\n    constructor(\r\n        public vertexId: number,\r\n        public triangleId: number\r\n    ) {}\r\n}\r\n\r\n/**\r\n * An implementation of the Quadratic Error simplification algorithm.\r\n * Original paper : http://www1.cs.columbia.edu/~cs4162/html05s/garland97.pdf\r\n * Ported mostly from QSlim and http://voxels.blogspot.de/2014/05/quadric-mesh-simplification-with-source.html to babylon JS\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/simplifyingMeshes\r\n */\r\nexport class QuadraticErrorSimplification implements ISimplifier {\r\n    private _triangles: Array<DecimationTriangle>;\r\n    private _vertices: Array<DecimationVertex>;\r\n    private _references: Array<Reference>;\r\n\r\n    private _reconstructedMesh: Mesh;\r\n\r\n    /** Gets or sets the number pf sync iterations */\r\n    public syncIterations = 5000;\r\n\r\n    /** Gets or sets the aggressiveness of the simplifier */\r\n    public aggressiveness: number;\r\n\r\n    /** Gets or sets the number of allowed iterations for decimation */\r\n    public decimationIterations: number;\r\n\r\n    /** Gets or sets the espilon to use for bounding box computation */\r\n    public boundingBoxEpsilon: number;\r\n\r\n    /**\r\n     * Creates a new QuadraticErrorSimplification\r\n     * @param _mesh defines the target mesh\r\n     */\r\n    constructor(private _mesh: Mesh) {\r\n        this.aggressiveness = 7;\r\n        this.decimationIterations = 100;\r\n        this.boundingBoxEpsilon = Epsilon;\r\n    }\r\n\r\n    /**\r\n     * Simplification of a given mesh according to the given settings.\r\n     * Since this requires computation, it is assumed that the function runs async.\r\n     * @param settings The settings of the simplification, including quality and distance\r\n     * @param successCallback A callback that will be called after the mesh was simplified.\r\n     */\r\n    public simplify(settings: ISimplificationSettings, successCallback: (simplifiedMesh: Mesh) => void) {\r\n        this._initDecimatedMesh();\r\n        //iterating through the submeshes array, one after the other.\r\n        AsyncLoop.Run(\r\n            this._mesh.subMeshes.length,\r\n            (loop: AsyncLoop) => {\r\n                this._initWithMesh(\r\n                    loop.index,\r\n                    () => {\r\n                        this._runDecimation(settings, loop.index, () => {\r\n                            loop.executeNext();\r\n                        });\r\n                    },\r\n                    settings.optimizeMesh\r\n                );\r\n            },\r\n            () => {\r\n                setTimeout(() => {\r\n                    successCallback(this._reconstructedMesh);\r\n                }, 0);\r\n            }\r\n        );\r\n    }\r\n\r\n    private _runDecimation(settings: ISimplificationSettings, submeshIndex: number, successCallback: () => void) {\r\n        const targetCount = ~~(this._triangles.length * settings.quality);\r\n        let deletedTriangles = 0;\r\n\r\n        const triangleCount = this._triangles.length;\r\n\r\n        const iterationFunction = (iteration: number, callback: () => void) => {\r\n            setTimeout(() => {\r\n                if (iteration % 5 === 0) {\r\n                    this._updateMesh(iteration === 0);\r\n                }\r\n\r\n                for (let i = 0; i < this._triangles.length; ++i) {\r\n                    this._triangles[i].isDirty = false;\r\n                }\r\n\r\n                const threshold = 0.000000001 * Math.pow(iteration + 3, this.aggressiveness);\r\n\r\n                const trianglesIterator = (i: number) => {\r\n                    const tIdx = ~~((this._triangles.length / 2 + i) % this._triangles.length);\r\n                    const t = this._triangles[tIdx];\r\n                    if (!t) {\r\n                        return;\r\n                    }\r\n                    if (t.error[3] > threshold || t.deleted || t.isDirty) {\r\n                        return;\r\n                    }\r\n                    for (let j = 0; j < 3; ++j) {\r\n                        if (t.error[j] < threshold) {\r\n                            const deleted0: Array<boolean> = [];\r\n                            const deleted1: Array<boolean> = [];\r\n\r\n                            const v0 = t._vertices[j];\r\n                            const v1 = t._vertices[(j + 1) % 3];\r\n\r\n                            if (v0.isBorder || v1.isBorder) {\r\n                                continue;\r\n                            }\r\n\r\n                            const p = Vector3.Zero();\r\n                            // var n = Vector3.Zero();\r\n                            // var uv = Vector2.Zero();\r\n                            // var color = new Color4(0, 0, 0, 1);\r\n\r\n                            this._calculateError(v0, v1, p);\r\n\r\n                            const delTr: DecimationTriangle[] = [];\r\n\r\n                            if (this._isFlipped(v0, v1, p, deleted0, delTr)) {\r\n                                continue;\r\n                            }\r\n                            if (this._isFlipped(v1, v0, p, deleted1, delTr)) {\r\n                                continue;\r\n                            }\r\n\r\n                            if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0) {\r\n                                continue;\r\n                            }\r\n\r\n                            const uniqueArray: DecimationTriangle[] = [];\r\n                            for (const deletedT of delTr) {\r\n                                if (uniqueArray.indexOf(deletedT) === -1) {\r\n                                    deletedT.deletePending = true;\r\n                                    uniqueArray.push(deletedT);\r\n                                }\r\n                            }\r\n\r\n                            if (uniqueArray.length % 2 !== 0) {\r\n                                continue;\r\n                            }\r\n\r\n                            v0.q = v1.q.add(v0.q);\r\n\r\n                            v0.updatePosition(p);\r\n\r\n                            const tStart = this._references.length;\r\n\r\n                            deletedTriangles = this._updateTriangles(v0, v0, deleted0, deletedTriangles);\r\n                            deletedTriangles = this._updateTriangles(v0, v1, deleted1, deletedTriangles);\r\n\r\n                            const tCount = this._references.length - tStart;\r\n\r\n                            if (tCount <= v0.triangleCount) {\r\n                                if (tCount) {\r\n                                    for (let c = 0; c < tCount; c++) {\r\n                                        this._references[v0.triangleStart + c] = this._references[tStart + c];\r\n                                    }\r\n                                }\r\n                            } else {\r\n                                v0.triangleStart = tStart;\r\n                            }\r\n\r\n                            v0.triangleCount = tCount;\r\n                            break;\r\n                        }\r\n                    }\r\n                };\r\n                AsyncLoop.SyncAsyncForLoop(this._triangles.length, this.syncIterations, trianglesIterator, callback, () => {\r\n                    return triangleCount - deletedTriangles <= targetCount;\r\n                });\r\n            }, 0);\r\n        };\r\n\r\n        AsyncLoop.Run(\r\n            this.decimationIterations,\r\n            (loop: AsyncLoop) => {\r\n                if (triangleCount - deletedTriangles <= targetCount) {\r\n                    loop.breakLoop();\r\n                } else {\r\n                    iterationFunction(loop.index, () => {\r\n                        loop.executeNext();\r\n                    });\r\n                }\r\n            },\r\n            () => {\r\n                setTimeout(() => {\r\n                    //reconstruct this part of the mesh\r\n                    this._reconstructMesh(submeshIndex);\r\n                    successCallback();\r\n                }, 0);\r\n            }\r\n        );\r\n    }\r\n\r\n    private _initWithMesh(submeshIndex: number, callback: Function, optimizeMesh?: boolean) {\r\n        this._vertices = [];\r\n        this._triangles = [];\r\n\r\n        const positionData = this._mesh.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        const indices = this._mesh.getIndices();\r\n        const submesh = this._mesh.subMeshes[submeshIndex];\r\n\r\n        const findInVertices = (positionToSearch: Vector3) => {\r\n            if (optimizeMesh) {\r\n                for (let ii = 0; ii < this._vertices.length; ++ii) {\r\n                    if (this._vertices[ii].position.equalsWithEpsilon(positionToSearch, 0.0001)) {\r\n                        return this._vertices[ii];\r\n                    }\r\n                }\r\n            }\r\n            return null;\r\n        };\r\n\r\n        const vertexReferences: Array<number> = [];\r\n\r\n        const vertexInit = (i: number) => {\r\n            if (!positionData) {\r\n                return;\r\n            }\r\n\r\n            const offset = i + submesh.verticesStart;\r\n            const position = Vector3.FromArray(positionData, offset * 3);\r\n\r\n            const vertex = findInVertices(position) || new DecimationVertex(position, this._vertices.length);\r\n            vertex.originalOffsets.push(offset);\r\n            if (vertex.id === this._vertices.length) {\r\n                this._vertices.push(vertex);\r\n            }\r\n            vertexReferences.push(vertex.id);\r\n        };\r\n        //var totalVertices = mesh.getTotalVertices();\r\n        const totalVertices = submesh.verticesCount;\r\n        AsyncLoop.SyncAsyncForLoop(totalVertices, (this.syncIterations / 4) >> 0, vertexInit, () => {\r\n            const indicesInit = (i: number) => {\r\n                if (!indices) {\r\n                    return;\r\n                }\r\n\r\n                const offset = submesh.indexStart / 3 + i;\r\n                const pos = offset * 3;\r\n                const i0 = indices[pos + 0];\r\n                const i1 = indices[pos + 1];\r\n                const i2 = indices[pos + 2];\r\n                const v0: DecimationVertex = this._vertices[vertexReferences[i0 - submesh.verticesStart]];\r\n                const v1: DecimationVertex = this._vertices[vertexReferences[i1 - submesh.verticesStart]];\r\n                const v2: DecimationVertex = this._vertices[vertexReferences[i2 - submesh.verticesStart]];\r\n                const triangle = new DecimationTriangle([v0, v1, v2]);\r\n                triangle.originalOffset = pos;\r\n                this._triangles.push(triangle);\r\n            };\r\n            AsyncLoop.SyncAsyncForLoop(submesh.indexCount / 3, this.syncIterations, indicesInit, () => {\r\n                this._init(callback);\r\n            });\r\n        });\r\n    }\r\n\r\n    private _init(callback: Function) {\r\n        const triangleInit1 = (i: number) => {\r\n            const t = this._triangles[i];\r\n            t.normal = Vector3.Cross(t._vertices[1].position.subtract(t._vertices[0].position), t._vertices[2].position.subtract(t._vertices[0].position)).normalize();\r\n            for (let j = 0; j < 3; j++) {\r\n                t._vertices[j].q.addArrayInPlace(QuadraticMatrix.DataFromNumbers(t.normal.x, t.normal.y, t.normal.z, -Vector3.Dot(t.normal, t._vertices[0].position)));\r\n            }\r\n        };\r\n        AsyncLoop.SyncAsyncForLoop(this._triangles.length, this.syncIterations, triangleInit1, () => {\r\n            const triangleInit2 = (i: number) => {\r\n                const t = this._triangles[i];\r\n                for (let j = 0; j < 3; ++j) {\r\n                    t.error[j] = this._calculateError(t._vertices[j], t._vertices[(j + 1) % 3]);\r\n                }\r\n                t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);\r\n            };\r\n            AsyncLoop.SyncAsyncForLoop(this._triangles.length, this.syncIterations, triangleInit2, () => {\r\n                callback();\r\n            });\r\n        });\r\n    }\r\n\r\n    private _reconstructMesh(submeshIndex: number) {\r\n        const newTriangles: Array<DecimationTriangle> = [];\r\n        let i: number;\r\n        for (i = 0; i < this._vertices.length; ++i) {\r\n            this._vertices[i].triangleCount = 0;\r\n        }\r\n        let t: DecimationTriangle;\r\n        let j: number;\r\n        for (i = 0; i < this._triangles.length; ++i) {\r\n            if (!this._triangles[i].deleted) {\r\n                t = this._triangles[i];\r\n                for (j = 0; j < 3; ++j) {\r\n                    t._vertices[j].triangleCount = 1;\r\n                }\r\n                newTriangles.push(t);\r\n            }\r\n        }\r\n\r\n        const newPositionData = <number[]>(this._reconstructedMesh.getVerticesData(VertexBuffer.PositionKind) || []);\r\n        const newNormalData = <number[]>(this._reconstructedMesh.getVerticesData(VertexBuffer.NormalKind) || []);\r\n        const newUVsData = <number[]>(this._reconstructedMesh.getVerticesData(VertexBuffer.UVKind) || []);\r\n        const newColorsData = <number[]>(this._reconstructedMesh.getVerticesData(VertexBuffer.ColorKind) || []);\r\n\r\n        const normalData = this._mesh.getVerticesData(VertexBuffer.NormalKind);\r\n        const uvs = this._mesh.getVerticesData(VertexBuffer.UVKind);\r\n        const colorsData = this._mesh.getVerticesData(VertexBuffer.ColorKind);\r\n\r\n        let vertexCount = 0;\r\n        for (i = 0; i < this._vertices.length; ++i) {\r\n            const vertex = this._vertices[i];\r\n            vertex.id = vertexCount;\r\n            if (vertex.triangleCount) {\r\n                for (const originalOffset of vertex.originalOffsets) {\r\n                    newPositionData.push(vertex.position.x);\r\n                    newPositionData.push(vertex.position.y);\r\n                    newPositionData.push(vertex.position.z);\r\n\r\n                    if (normalData && normalData.length) {\r\n                        newNormalData.push(normalData[originalOffset * 3]);\r\n                        newNormalData.push(normalData[originalOffset * 3 + 1]);\r\n                        newNormalData.push(normalData[originalOffset * 3 + 2]);\r\n                    }\r\n                    if (uvs && uvs.length) {\r\n                        newUVsData.push(uvs[originalOffset * 2]);\r\n                        newUVsData.push(uvs[originalOffset * 2 + 1]);\r\n                    }\r\n                    if (colorsData && colorsData.length) {\r\n                        newColorsData.push(colorsData[originalOffset * 4]);\r\n                        newColorsData.push(colorsData[originalOffset * 4 + 1]);\r\n                        newColorsData.push(colorsData[originalOffset * 4 + 2]);\r\n                        newColorsData.push(colorsData[originalOffset * 4 + 3]);\r\n                    }\r\n                    ++vertexCount;\r\n                }\r\n            }\r\n        }\r\n\r\n        const startingIndex = this._reconstructedMesh.getTotalIndices();\r\n        const startingVertex = this._reconstructedMesh.getTotalVertices();\r\n\r\n        const submeshesArray = this._reconstructedMesh.subMeshes;\r\n        this._reconstructedMesh.subMeshes = [];\r\n\r\n        const newIndicesArray: number[] = <number[]>this._reconstructedMesh.getIndices(); //[];\r\n        const originalIndices = <IndicesArray>this._mesh.getIndices();\r\n        for (i = 0; i < newTriangles.length; ++i) {\r\n            t = newTriangles[i]; //now get the new referencing point for each vertex\r\n            for (let idx = 0; idx < 3; ++idx) {\r\n                const id = originalIndices[t.originalOffset + idx];\r\n                let offset = t._vertices[idx].originalOffsets.indexOf(id);\r\n                if (offset < 0) {\r\n                    offset = 0;\r\n                }\r\n                newIndicesArray.push(t._vertices[idx].id + offset + startingVertex);\r\n            }\r\n        }\r\n\r\n        //overwriting the old vertex buffers and indices.\r\n\r\n        this._reconstructedMesh.setIndices(newIndicesArray);\r\n        this._reconstructedMesh.setVerticesData(VertexBuffer.PositionKind, newPositionData);\r\n        if (newNormalData.length > 0) {\r\n            this._reconstructedMesh.setVerticesData(VertexBuffer.NormalKind, newNormalData);\r\n        }\r\n        if (newUVsData.length > 0) {\r\n            this._reconstructedMesh.setVerticesData(VertexBuffer.UVKind, newUVsData);\r\n        }\r\n        if (newColorsData.length > 0) {\r\n            this._reconstructedMesh.setVerticesData(VertexBuffer.ColorKind, newColorsData);\r\n        }\r\n\r\n        //create submesh\r\n        const originalSubmesh = this._mesh.subMeshes[submeshIndex];\r\n        if (submeshIndex > 0) {\r\n            this._reconstructedMesh.subMeshes = [];\r\n            for (const submesh of submeshesArray) {\r\n                SubMesh.AddToMesh(\r\n                    submesh.materialIndex,\r\n                    submesh.verticesStart,\r\n                    submesh.verticesCount,\r\n                    /* 0, newPositionData.length/3, */ submesh.indexStart,\r\n                    submesh.indexCount,\r\n                    submesh.getMesh()\r\n                );\r\n            }\r\n            SubMesh.AddToMesh(\r\n                originalSubmesh.materialIndex,\r\n                startingVertex,\r\n                vertexCount,\r\n                /* 0, newPositionData.length / 3, */ startingIndex,\r\n                newTriangles.length * 3,\r\n                this._reconstructedMesh\r\n            );\r\n        }\r\n    }\r\n\r\n    private _initDecimatedMesh() {\r\n        this._reconstructedMesh = new Mesh(this._mesh.name + \"Decimated\", this._mesh.getScene());\r\n        this._reconstructedMesh.material = this._mesh.material;\r\n        this._reconstructedMesh.parent = this._mesh.parent;\r\n        this._reconstructedMesh.isVisible = false;\r\n        this._reconstructedMesh.renderingGroupId = this._mesh.renderingGroupId;\r\n    }\r\n\r\n    private _isFlipped(vertex1: DecimationVertex, vertex2: DecimationVertex, point: Vector3, deletedArray: Array<boolean>, delTr: Array<DecimationTriangle>): boolean {\r\n        for (let i = 0; i < vertex1.triangleCount; ++i) {\r\n            const t = this._triangles[this._references[vertex1.triangleStart + i].triangleId];\r\n            if (t.deleted) {\r\n                continue;\r\n            }\r\n\r\n            const s = this._references[vertex1.triangleStart + i].vertexId;\r\n\r\n            const v1 = t._vertices[(s + 1) % 3];\r\n            const v2 = t._vertices[(s + 2) % 3];\r\n\r\n            if (v1 === vertex2 || v2 === vertex2) {\r\n                deletedArray[i] = true;\r\n                delTr.push(t);\r\n                continue;\r\n            }\r\n\r\n            let d1 = v1.position.subtract(point);\r\n            d1 = d1.normalize();\r\n            let d2 = v2.position.subtract(point);\r\n            d2 = d2.normalize();\r\n            if (Math.abs(Vector3.Dot(d1, d2)) > 0.999) {\r\n                return true;\r\n            }\r\n            const normal = Vector3.Cross(d1, d2).normalize();\r\n            deletedArray[i] = false;\r\n            if (Vector3.Dot(normal, t.normal) < 0.2) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    private _updateTriangles(origVertex: DecimationVertex, vertex: DecimationVertex, deletedArray: Array<boolean>, deletedTriangles: number): number {\r\n        let newDeleted = deletedTriangles;\r\n        for (let i = 0; i < vertex.triangleCount; ++i) {\r\n            const ref = this._references[vertex.triangleStart + i];\r\n            const t = this._triangles[ref.triangleId];\r\n            if (t.deleted) {\r\n                continue;\r\n            }\r\n            if (deletedArray[i] && t.deletePending) {\r\n                t.deleted = true;\r\n                newDeleted++;\r\n                continue;\r\n            }\r\n            t._vertices[ref.vertexId] = origVertex;\r\n            t.isDirty = true;\r\n            t.error[0] = this._calculateError(t._vertices[0], t._vertices[1]) + t.borderFactor / 2;\r\n            t.error[1] = this._calculateError(t._vertices[1], t._vertices[2]) + t.borderFactor / 2;\r\n            t.error[2] = this._calculateError(t._vertices[2], t._vertices[0]) + t.borderFactor / 2;\r\n            t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);\r\n            this._references.push(ref);\r\n        }\r\n        return newDeleted;\r\n    }\r\n\r\n    private _identifyBorder() {\r\n        for (let i = 0; i < this._vertices.length; ++i) {\r\n            const vCount: Array<number> = [];\r\n            const vId: Array<number> = [];\r\n            const v = this._vertices[i];\r\n            let j: number;\r\n            for (j = 0; j < v.triangleCount; ++j) {\r\n                const triangle = this._triangles[this._references[v.triangleStart + j].triangleId];\r\n                for (let ii = 0; ii < 3; ii++) {\r\n                    let ofs = 0;\r\n                    const vv = triangle._vertices[ii];\r\n                    while (ofs < vCount.length) {\r\n                        if (vId[ofs] === vv.id) {\r\n                            break;\r\n                        }\r\n                        ++ofs;\r\n                    }\r\n                    if (ofs === vCount.length) {\r\n                        vCount.push(1);\r\n                        vId.push(vv.id);\r\n                    } else {\r\n                        vCount[ofs]++;\r\n                    }\r\n                }\r\n            }\r\n\r\n            for (j = 0; j < vCount.length; ++j) {\r\n                if (vCount[j] === 1) {\r\n                    this._vertices[vId[j]].isBorder = true;\r\n                } else {\r\n                    this._vertices[vId[j]].isBorder = false;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateMesh(identifyBorders: boolean = false) {\r\n        let i: number;\r\n        if (!identifyBorders) {\r\n            const newTrianglesVector: Array<DecimationTriangle> = [];\r\n            for (i = 0; i < this._triangles.length; ++i) {\r\n                if (!this._triangles[i].deleted) {\r\n                    newTrianglesVector.push(this._triangles[i]);\r\n                }\r\n            }\r\n            this._triangles = newTrianglesVector;\r\n        }\r\n\r\n        for (i = 0; i < this._vertices.length; ++i) {\r\n            this._vertices[i].triangleCount = 0;\r\n            this._vertices[i].triangleStart = 0;\r\n        }\r\n        let t: DecimationTriangle;\r\n        let j: number;\r\n        let v: DecimationVertex;\r\n        for (i = 0; i < this._triangles.length; ++i) {\r\n            t = this._triangles[i];\r\n            for (j = 0; j < 3; ++j) {\r\n                v = t._vertices[j];\r\n                v.triangleCount++;\r\n            }\r\n        }\r\n\r\n        let tStart = 0;\r\n\r\n        for (i = 0; i < this._vertices.length; ++i) {\r\n            this._vertices[i].triangleStart = tStart;\r\n            tStart += this._vertices[i].triangleCount;\r\n            this._vertices[i].triangleCount = 0;\r\n        }\r\n\r\n        const newReferences: Array<Reference> = new Array(this._triangles.length * 3);\r\n        for (i = 0; i < this._triangles.length; ++i) {\r\n            t = this._triangles[i];\r\n            for (j = 0; j < 3; ++j) {\r\n                v = t._vertices[j];\r\n                newReferences[v.triangleStart + v.triangleCount] = new Reference(j, i);\r\n                v.triangleCount++;\r\n            }\r\n        }\r\n        this._references = newReferences;\r\n\r\n        if (identifyBorders) {\r\n            this._identifyBorder();\r\n        }\r\n    }\r\n\r\n    private _vertexError(q: QuadraticMatrix, point: Vector3): number {\r\n        const x = point.x;\r\n        const y = point.y;\r\n        const z = point.z;\r\n        return (\r\n            q.data[0] * x * x +\r\n            2 * q.data[1] * x * y +\r\n            2 * q.data[2] * x * z +\r\n            2 * q.data[3] * x +\r\n            q.data[4] * y * y +\r\n            2 * q.data[5] * y * z +\r\n            2 * q.data[6] * y +\r\n            q.data[7] * z * z +\r\n            2 * q.data[8] * z +\r\n            q.data[9]\r\n        );\r\n    }\r\n\r\n    private _calculateError(vertex1: DecimationVertex, vertex2: DecimationVertex, pointResult?: Vector3): number {\r\n        const q = vertex1.q.add(vertex2.q);\r\n        const border = vertex1.isBorder && vertex2.isBorder;\r\n        let error: number;\r\n        const qDet = q.det(0, 1, 2, 1, 4, 5, 2, 5, 7);\r\n\r\n        if (qDet !== 0 && !border) {\r\n            if (!pointResult) {\r\n                pointResult = Vector3.Zero();\r\n            }\r\n            pointResult.x = (-1 / qDet) * q.det(1, 2, 3, 4, 5, 6, 5, 7, 8);\r\n            pointResult.y = (1 / qDet) * q.det(0, 2, 3, 1, 5, 6, 2, 7, 8);\r\n            pointResult.z = (-1 / qDet) * q.det(0, 1, 3, 1, 4, 6, 2, 5, 8);\r\n            error = this._vertexError(q, pointResult);\r\n        } else {\r\n            const p3 = vertex1.position.add(vertex2.position).divide(new Vector3(2, 2, 2));\r\n            //var norm3 = (vertex1.normal.add(vertex2.normal)).divide(new Vector3(2, 2, 2)).normalize();\r\n            const error1 = this._vertexError(q, vertex1.position);\r\n            const error2 = this._vertexError(q, vertex2.position);\r\n            const error3 = this._vertexError(q, p3);\r\n            error = Math.min(error1, error2, error3);\r\n            if (error === error1) {\r\n                if (pointResult) {\r\n                    pointResult.copyFrom(vertex1.position);\r\n                }\r\n            } else if (error === error2) {\r\n                if (pointResult) {\r\n                    pointResult.copyFrom(vertex2.position);\r\n                }\r\n            } else {\r\n                if (pointResult) {\r\n                    pointResult.copyFrom(p3);\r\n                }\r\n            }\r\n        }\r\n        return error;\r\n    }\r\n}\r\n","import { type AnimationGroup } from \"../Animations/animationGroup\";\r\nimport { type FloatArray, type Nullable } from \"../types\";\r\nimport { type AbstractMesh } from \"./abstractMesh\";\r\nimport { type Mesh } from \"./mesh\";\r\n\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\n\r\nfunction GetExtentCorners(extent: { minimum: Vector3; maximum: Vector3 }): Array<Vector3> {\r\n    const minX = extent.minimum.x;\r\n    const minY = extent.minimum.y;\r\n    const minZ = extent.minimum.z;\r\n    const maxX = extent.maximum.x;\r\n    const maxY = extent.maximum.y;\r\n    const maxZ = extent.maximum.z;\r\n    return [\r\n        new Vector3(minX, minY, minZ),\r\n        new Vector3(maxX, maxY, maxZ),\r\n        new Vector3(maxX, minY, minZ),\r\n        new Vector3(minX, maxY, minZ),\r\n        new Vector3(minX, minY, maxZ),\r\n        new Vector3(maxX, maxY, minZ),\r\n        new Vector3(minX, maxY, maxZ),\r\n        new Vector3(maxX, minY, maxZ),\r\n    ];\r\n}\r\n\r\n/**\r\n * Computes the maximum extents of the given meshes considering animation, skeleton, and morph targets.\r\n * @param meshes The array of meshes to compute\r\n * @param animationGroup An optional animation group to animate (must be started to take effect)\r\n * @param animationStep An optional value indicating the number of seconds to step while looping through the given animation group\r\n * @returns An array of world space extents corresponding to the given meshes\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function computeMaxExtents(\r\n    meshes: Array<AbstractMesh>,\r\n    animationGroup: Nullable<AnimationGroup> = null,\r\n    animationStep = 1 / 6\r\n): Array<{ minimum: Vector3; maximum: Vector3 }> {\r\n    // Local vector to avoid allocations.\r\n    const position = TmpVectors.Vector3[0];\r\n\r\n    const meshExtents = new Map<number, { minimum: Vector3; maximum: Vector3 }>();\r\n    const skinnedMeshExtents = new Map<number, Map<number, { minimum: Vector3; maximum: Vector3 }>>();\r\n\r\n    // Compute the non-skinned and skinned mesh extents.\r\n    const maxLength = meshes.reduce((previous, current) => Math.max(previous, current.getTotalVertices()), 0);\r\n    const minPositions = Array.from({ length: maxLength }, () => new Vector3());\r\n    const maxPositions = Array.from({ length: maxLength }, () => new Vector3());\r\n    for (const mesh of meshes) {\r\n        const positions = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        if (!positions) {\r\n            continue;\r\n        }\r\n\r\n        // Initialize min/max positions with the original positions.\r\n        const numVertices = mesh.getTotalVertices();\r\n        minPositions.length = Math.max(minPositions.length, numVertices);\r\n        maxPositions.length = Math.max(minPositions.length, numVertices);\r\n        for (let i = 0, j = 0; i < numVertices; i++, j += 3) {\r\n            position.set(positions[j], positions[j + 1], positions[j + 2]);\r\n            minPositions[i].copyFrom(position);\r\n            maxPositions[i].copyFrom(position);\r\n        }\r\n\r\n        // Apply morph targets to the min/max positions.\r\n        const morphTargetManager = mesh.morphTargetManager;\r\n        if (morphTargetManager) {\r\n            for (let targetIndex = 0; targetIndex < morphTargetManager.numTargets; ++targetIndex) {\r\n                const target = morphTargetManager.getTarget(targetIndex);\r\n                const positions = target.getPositions();\r\n                if (positions) {\r\n                    for (let i = 0, j = 0; i < numVertices; i++, j += 3) {\r\n                        position.set(positions[j], positions[j + 1], positions[j + 2]);\r\n                        minPositions[i].minimizeInPlace(position);\r\n                        maxPositions[i].maximizeInPlace(position);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Compute extent per mesh.\r\n        const skeleton = mesh.skeleton;\r\n        const weights = skeleton ? mesh.getVerticesData(VertexBuffer.MatricesWeightsKind) : null;\r\n        const indices = skeleton ? mesh.getVerticesData(VertexBuffer.MatricesIndicesKind) : null;\r\n        if (weights && indices) {\r\n            // Compute extent per bone for skinned meshes.\r\n            const needsExtra = mesh.numBoneInfluencers > 4;\r\n            const weightsExtra = needsExtra ? mesh.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;\r\n            const indicesExtra = needsExtra ? mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;\r\n\r\n            const perBoneExtents = skinnedMeshExtents.get(mesh.uniqueId) || new Map<number, { minimum: Vector3; maximum: Vector3 }>();\r\n            skinnedMeshExtents.set(mesh.uniqueId, perBoneExtents);\r\n\r\n            const updateExtents = (i: number, j: number, weights: FloatArray, indices: FloatArray): void => {\r\n                for (let k = j; k < j + 4; k++) {\r\n                    if (weights[k] > 0) {\r\n                        const boneIndex = indices[k];\r\n\r\n                        const extent = perBoneExtents.get(boneIndex);\r\n                        if (extent) {\r\n                            extent.minimum.minimizeInPlace(minPositions[i]);\r\n                            extent.maximum.maximizeInPlace(maxPositions[i]);\r\n                        } else {\r\n                            perBoneExtents.set(boneIndex, {\r\n                                minimum: minPositions[i].clone(),\r\n                                maximum: maxPositions[i].clone(),\r\n                            });\r\n                        }\r\n                    }\r\n                }\r\n            };\r\n\r\n            for (let i = 0, j = 0; i < numVertices; i++, j += 4) {\r\n                updateExtents(i, j, weights, indices);\r\n\r\n                if (weightsExtra && indicesExtra) {\r\n                    updateExtents(i, j, weightsExtra, indicesExtra);\r\n                }\r\n            }\r\n        } else {\r\n            // Compute extent for the whole mesh for non-skinned meshes.\r\n            const extent = meshExtents.get(mesh.uniqueId) || {\r\n                minimum: new Vector3().setAll(Number.POSITIVE_INFINITY),\r\n                maximum: new Vector3().setAll(Number.NEGATIVE_INFINITY),\r\n            };\r\n            meshExtents.set(mesh.uniqueId, extent);\r\n\r\n            for (let i = 0; i < numVertices; i++) {\r\n                extent.minimum.minimizeInPlace(minPositions[i]);\r\n                extent.maximum.maximizeInPlace(maxPositions[i]);\r\n            }\r\n        }\r\n    }\r\n\r\n    // Create the 8 corners of each non-skinned and skinned extent.\r\n    const meshCorners = new Map<number, Array<Vector3>>();\r\n    const skinnedMeshCorners = new Map<number, Map<number, Array<Vector3>>>();\r\n    for (const mesh of meshes) {\r\n        const extent = meshExtents.get(mesh.uniqueId);\r\n        if (extent) {\r\n            meshCorners.set(mesh.uniqueId, GetExtentCorners(extent));\r\n        } else {\r\n            const perBoneExtents = skinnedMeshExtents.get(mesh.uniqueId);\r\n            if (perBoneExtents) {\r\n                const bones = mesh.skeleton!.bones;\r\n\r\n                const perBoneCorners = new Map<number, Array<Vector3>>();\r\n                skinnedMeshCorners.set(mesh.uniqueId, perBoneCorners);\r\n\r\n                perBoneExtents.forEach((extent, boneIndex) => {\r\n                    const corners = GetExtentCorners(extent);\r\n\r\n                    // Transform the coordinates of the corners for skinned meshes to bone space.\r\n                    const inverseBindMatrix = bones[boneIndex].getAbsoluteInverseBindMatrix();\r\n                    for (const corner of corners) {\r\n                        Vector3.TransformCoordinatesToRef(corner, inverseBindMatrix, corner);\r\n                    }\r\n\r\n                    perBoneCorners.set(boneIndex, corners);\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    const maxExtents = Array.from({ length: meshes.length }, () => ({\r\n        minimum: new Vector3().setAll(Number.POSITIVE_INFINITY),\r\n        maximum: new Vector3().setAll(Number.NEGATIVE_INFINITY),\r\n    }));\r\n\r\n    const updateMaxExtents = (): void => {\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const mesh = meshes[i];\r\n            const positions = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n            if (!positions) {\r\n                continue;\r\n            }\r\n\r\n            const worldMatrix = mesh.computeWorldMatrix(true);\r\n\r\n            const skeleton = mesh.skeleton;\r\n            if (skeleton) {\r\n                skeleton.prepare(true);\r\n\r\n                const bones = skeleton.bones;\r\n                const perBoneCorners = skinnedMeshCorners.get(mesh.uniqueId)!;\r\n                perBoneCorners.forEach((corners, boneIndex) => {\r\n                    // Transform the per-bone corners into world space and update the max extent for each corner.\r\n                    for (const corner of corners) {\r\n                        const matrix = bones[boneIndex].getFinalMatrix().multiplyToRef(worldMatrix, TmpVectors.Matrix[0]);\r\n                        Vector3.TransformCoordinatesToRef(corner, matrix, position);\r\n                        maxExtents[i].minimum.minimizeInPlace(position);\r\n                        maxExtents[i].maximum.maximizeInPlace(position);\r\n                    }\r\n                });\r\n            } else {\r\n                // Transform the corners into world space and update the max extent for each corner.\r\n                for (const corner of meshCorners.get(mesh.uniqueId)!) {\r\n                    Vector3.TransformCoordinatesToRef(corner, worldMatrix, position);\r\n                    maxExtents[i].minimum.minimizeInPlace(position);\r\n                    maxExtents[i].maximum.maximizeInPlace(position);\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    if (animationGroup && animationGroup.isStarted) {\r\n        const currentFrame = animationGroup.getCurrentFrame();\r\n        const step = animationStep / animationGroup.getLength(0, 1);\r\n        for (let frame = animationGroup.from; frame <= animationGroup.to; frame += step) {\r\n            animationGroup.goToFrame(frame);\r\n            updateMaxExtents();\r\n        }\r\n        animationGroup.goToFrame(currentFrame);\r\n    } else {\r\n        updateMaxExtents();\r\n    }\r\n\r\n    return maxExtents;\r\n}\r\n\r\n/**\r\n * @experimental\r\n * Removes unreferenced vertex data from the given meshes.\r\n * This is useful for cleaning up unused vertex data, such as UV sets, to reduce memory usage and stay under graphics device limits.\r\n * @remarks\r\n * This function currently only removes unreferenced UV sets (UV2, UV3, etc.) from the meshes.\r\n * @param meshes The array of meshes to clean up.\r\n */\r\nexport function RemoveUnreferencedVerticesData(meshes: readonly Mesh[]) {\r\n    const uvIndexToKind = [VertexBuffer.UVKind, VertexBuffer.UV2Kind, VertexBuffer.UV3Kind, VertexBuffer.UV4Kind, VertexBuffer.UV5Kind, VertexBuffer.UV6Kind] as const;\r\n    for (const mesh of meshes) {\r\n        const unreferencedUVSets = new Set(uvIndexToKind);\r\n        const textures = mesh.material?.getActiveTextures();\r\n        if (textures) {\r\n            for (const texture of textures) {\r\n                unreferencedUVSets.delete(uvIndexToKind[texture.coordinatesIndex]);\r\n            }\r\n        }\r\n\r\n        unreferencedUVSets.forEach((unreferencedUVSet) => {\r\n            if (mesh.isVerticesDataPresent(unreferencedUVSet)) {\r\n                mesh.removeVerticesData(unreferencedUVSet);\r\n            }\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type IndicesArray } from \"../types\";\r\nimport { SubMesh } from \"./subMesh.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for subMeshProject.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSubMeshProject(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    SubMesh.prototype._projectOnTrianglesToRef = function (\r\n        vector: Vector3,\r\n        positions: Vector3[],\r\n        indices: IndicesArray,\r\n        step: number,\r\n        checkStopper: boolean,\r\n        ref: Vector3\r\n    ): number {\r\n        // Triangles test\r\n        const proj = TmpVectors.Vector3[0];\r\n        const tmp = TmpVectors.Vector3[1];\r\n        let distance = +Infinity;\r\n\r\n        for (let index = this.indexStart; index < this.indexStart + this.indexCount - (3 - step); index += step) {\r\n            const indexA = indices[index];\r\n            const indexB = indices[index + 1];\r\n            const indexC = indices[index + 2];\r\n\r\n            if (checkStopper && indexC === 0xffffffff) {\r\n                index += 2;\r\n                continue;\r\n            }\r\n\r\n            const p0 = positions[indexA];\r\n            const p1 = positions[indexB];\r\n            const p2 = positions[indexC];\r\n\r\n            // stay defensive and don't check against undefined positions.\r\n            if (!p0 || !p1 || !p2) {\r\n                continue;\r\n            }\r\n\r\n            const tmpDist = Vector3.ProjectOnTriangleToRef(vector, p0, p1, p2, tmp);\r\n            if (tmpDist < distance) {\r\n                proj.copyFrom(tmp);\r\n                distance = tmpDist;\r\n            }\r\n        }\r\n\r\n        ref.copyFrom(proj);\r\n\r\n        return distance;\r\n    };\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    SubMesh.prototype._projectOnUnIndexedTrianglesToRef = function (vector: Vector3, positions: Vector3[], indices: IndicesArray, ref: Vector3): number {\r\n        // Triangles test\r\n        const proj = TmpVectors.Vector3[0];\r\n        const tmp = TmpVectors.Vector3[1];\r\n        let distance = +Infinity;\r\n\r\n        for (let index = this.verticesStart; index < this.verticesStart + this.verticesCount; index += 3) {\r\n            const p0 = positions[index];\r\n            const p1 = positions[index + 1];\r\n            const p2 = positions[index + 2];\r\n\r\n            const tmpDist = Vector3.ProjectOnTriangleToRef(vector, p0, p1, p2, tmp);\r\n            if (tmpDist < distance) {\r\n                proj.copyFrom(tmp);\r\n                distance = tmpDist;\r\n            }\r\n        }\r\n\r\n        ref.copyFrom(proj);\r\n\r\n        return distance;\r\n    };\r\n\r\n    SubMesh.prototype.projectToRef = function (vector: Vector3, positions: Vector3[], indices: IndicesArray, ref: Vector3): number {\r\n        const material = this.getMaterial();\r\n        if (!material) {\r\n            return -1;\r\n        }\r\n        let step = 3;\r\n        let checkStopper = false;\r\n\r\n        switch (material.fillMode) {\r\n            case Constants.MATERIAL_PointListDrawMode:\r\n            case Constants.MATERIAL_LineLoopDrawMode:\r\n            case Constants.MATERIAL_LineStripDrawMode:\r\n            case Constants.MATERIAL_TriangleFanDrawMode:\r\n                return -1;\r\n            case Constants.MATERIAL_TriangleStripDrawMode:\r\n                step = 1;\r\n                checkStopper = true;\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n\r\n        // LineMesh first as it's also a Mesh...\r\n        if (material.fillMode === Constants.MATERIAL_LineListDrawMode) {\r\n            return -1;\r\n        } else {\r\n            // Check if mesh is unindexed\r\n            if (!indices.length && (this as any)._mesh._unIndexed) {\r\n                return this._projectOnUnIndexedTrianglesToRef(vector, positions, indices, ref);\r\n            }\r\n\r\n            return this._projectOnTrianglesToRef(vector, positions, indices, step, checkStopper, ref);\r\n        }\r\n    };\r\n}\r\n","import { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Mesh } from \"./mesh\";\r\nimport { type FloatArray } from \"core/types\";\r\nimport { VertexBuffer } from \"./buffer\";\r\nimport { Clamp, OutsideRange } from \"core/Maths/math.scalar.functions\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\n/**\r\n * Interface used to define options for creating a lattice\r\n */\r\nexport interface ILatticeOptions {\r\n    /** resolution on x axis */\r\n    resolutionX: number;\r\n    /** resolution on y axis */\r\n    resolutionY: number;\r\n    /** resolution on z axis */\r\n    resolutionZ: number;\r\n    /** the lattice position in object space */\r\n    position: Vector3;\r\n    /** size of the lattice along each axis in object space */\r\n    size: Vector3;\r\n    /** Optional mesh to adapt the size to */\r\n    autoAdaptToMesh?: Mesh;\r\n}\r\n\r\n/**\r\n * Class used to represent a lattice\r\n * @see [Moving lattice bounds](https://playground.babylonjs.com/#MDVD75#18)\r\n * @see [Twist](https://playground.babylonjs.com/#MDVD75#23)\r\n */\r\nexport class Lattice {\r\n    private _resolutionX: number;\r\n    private _resolutionY: number;\r\n    private _resolutionZ: number;\r\n    private _position: Vector3;\r\n    private _size: Vector3;\r\n    private _cellSize = new Vector3();\r\n\r\n    private _data: Vector3[][][];\r\n\r\n    // Cache\r\n    private _min = new Vector3(-0.5, -0.5, -0.5);\r\n    private _max = new Vector3(0.5, 0.5, 0.5);\r\n    private _localPos = new Vector3();\r\n    private _tmpVector = new Vector3();\r\n    private _lerpVector0 = new Vector3();\r\n    private _lerpVector1 = new Vector3();\r\n    private _lerpVector2 = new Vector3();\r\n    private _lerpVector3 = new Vector3();\r\n    private _lerpVector4 = new Vector3();\r\n    private _lerpVector5 = new Vector3();\r\n\r\n    /**\r\n     * @returns the string \"Lattice\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"Lattice\";\r\n    }\r\n\r\n    /**\r\n     * Gets the resolution on x axis\r\n     */\r\n    public get resolutionX(): number {\r\n        return this._resolutionX;\r\n    }\r\n\r\n    /**\r\n     * Gets the resolution on y axis\r\n     */\r\n    public get resolutionY(): number {\r\n        return this._resolutionY;\r\n    }\r\n\r\n    /**\r\n     * Gets the resolution on z axis\r\n     */\r\n    public get resolutionZ(): number {\r\n        return this._resolutionZ;\r\n    }\r\n\r\n    /**\r\n     * Gets the size of the lattice along each axis in object space\r\n     * Updating the size requires you to call update afterwards\r\n     */\r\n    public get size(): Vector3 {\r\n        return this._size;\r\n    }\r\n\r\n    /**\r\n     * Gets the lattice position in object space\r\n     */\r\n    public get position(): Vector3 {\r\n        return this._position;\r\n    }\r\n\r\n    /**\r\n     * Gets the data of the lattice\r\n     */\r\n    public get data(): Vector3[][][] {\r\n        return this._data;\r\n    }\r\n\r\n    /**\r\n     * Gets the size of each cell in the lattice\r\n     */\r\n    public get cellSize(): Vector3 {\r\n        return this._cellSize;\r\n    }\r\n\r\n    /**\r\n     * Gets the min bounds of the lattice\r\n     */\r\n    public get min(): Vector3 {\r\n        return this._min;\r\n    }\r\n\r\n    /**\r\n     * Gets the max bounds of the lattice\r\n     */\r\n    public get max(): Vector3 {\r\n        return this._max;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Lattice\r\n     * @param options options for creating\r\n     */\r\n    public constructor(options?: Partial<ILatticeOptions>) {\r\n        const localOptions: ILatticeOptions = {\r\n            resolutionX: 3,\r\n            resolutionY: 3,\r\n            resolutionZ: 3,\r\n            position: Vector3.Zero(),\r\n            size: Vector3.One(),\r\n            ...options,\r\n        };\r\n\r\n        this._resolutionX = localOptions.resolutionX;\r\n        this._resolutionY = localOptions.resolutionY;\r\n        this._resolutionZ = localOptions.resolutionZ;\r\n        this._position = localOptions.position;\r\n        this._size = localOptions.autoAdaptToMesh ? localOptions.autoAdaptToMesh.getBoundingInfo().boundingBox.extendSize.scale(2) : localOptions.size;\r\n\r\n        // Allocate data\r\n        this._allocateData();\r\n        this.update();\r\n    }\r\n\r\n    private _allocateData() {\r\n        this._data = new Array<Array<Array<Vector3>>>(this.resolutionX);\r\n        for (let i = 0; i < this.resolutionX; i++) {\r\n            this._data[i] = new Array<Array<Vector3>>(this.resolutionY);\r\n            for (let j = 0; j < this.resolutionY; j++) {\r\n                this._data[i][j] = new Array<Vector3>(this.resolutionZ);\r\n                for (let k = 0; k < this.resolutionZ; k++) {\r\n                    this._data[i][j][k] = Vector3.Zero();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update of the lattice data\r\n     */\r\n    public update() {\r\n        for (let i = 0; i < this.resolutionX; i++) {\r\n            for (let j = 0; j < this.resolutionY; j++) {\r\n                for (let k = 0; k < this.resolutionZ; k++) {\r\n                    const x = -this.size.x / 2 + this.size.x * (i / (this.resolutionX - 1));\r\n                    const y = -this.size.y / 2 + this.size.y * (j / (this.resolutionY - 1));\r\n                    const z = -this.size.z / 2 + this.size.z * (k / (this.resolutionZ - 1));\r\n\r\n                    this._data[i][j][k].set(x, y, z);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Apply the lattice to a mesh\r\n     * @param mesh mesh to deform\r\n     */\r\n    public deformMesh(mesh: Mesh) {\r\n        const positions = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n        if (!positions) {\r\n            return;\r\n        }\r\n\r\n        // Apply the lattice\r\n        this.deform(positions);\r\n\r\n        // Update back the mesh\r\n        mesh.setVerticesData(VertexBuffer.PositionKind, positions, true);\r\n    }\r\n\r\n    /**\r\n     * Update the lattice internals (like min, max and cell size)\r\n     */\r\n    public updateInternals() {\r\n        const nx = this._resolutionX;\r\n        const ny = this._resolutionY;\r\n        const nz = this._resolutionZ;\r\n\r\n        // Calculate the size of each cell in the lattice\r\n        this._cellSize.set(this.size.x / (nx - 1), this.size.y / (ny - 1), this.size.z / (nz - 1));\r\n\r\n        // Calculate the lattice bounds\r\n        this._min.set(this.position.x - this.size.x / 2, this.position.y - this.size.y / 2, this.position.z - this.size.z / 2);\r\n        this._min.addToRef(this._size, this._max);\r\n    }\r\n\r\n    /**\r\n     * Apply the lattice to a set of points\r\n     * @param positions vertex data to deform\r\n     * @param target optional target array to store the result (operation will be done in place in not defined)\r\n     */\r\n    public deform(positions: FloatArray, target?: FloatArray) {\r\n        const nx = this._resolutionX;\r\n        const ny = this._resolutionY;\r\n        const nz = this._resolutionZ;\r\n\r\n        this.updateInternals();\r\n\r\n        const min = this._min;\r\n        const max = this._max;\r\n\r\n        // Loop over each vertex\r\n        for (let i = 0; i < positions.length; i += 3) {\r\n            const vertex = this._tmpVector.fromArray(positions, i);\r\n\r\n            // Check we are inside\r\n            if (OutsideRange(vertex.x, min.x, max.x, Epsilon) || OutsideRange(vertex.y, min.y, max.y, Epsilon) || OutsideRange(vertex.z, min.z, max.z, Epsilon)) {\r\n                if (target) {\r\n                    vertex.toArray(target, i);\r\n                }\r\n                continue;\r\n            }\r\n\r\n            // Map vertex position to lattice local coordinates\r\n            const localPos = this._localPos.set((vertex.x - min.x) / this._cellSize.x, (vertex.y - min.y) / this._cellSize.y, (vertex.z - min.z) / this._cellSize.z);\r\n\r\n            // Get integer lattice indices\r\n            const i0 = Math.floor(localPos.x);\r\n            const j0 = Math.floor(localPos.y);\r\n            const k0 = Math.floor(localPos.z);\r\n\r\n            const i1 = Math.min(i0 + 1, nx - 1);\r\n            const j1 = Math.min(j0 + 1, ny - 1);\r\n            const k1 = Math.min(k0 + 1, nz - 1);\r\n\r\n            // Compute interpolation weights\r\n            const tx = localPos.x - i0;\r\n            const ty = localPos.y - j0;\r\n            const tz = localPos.z - k0;\r\n\r\n            // Ensure indices are within bounds\r\n            const ii0 = Clamp(i0, 0, nx - 1);\r\n            const jj0 = Clamp(j0, 0, ny - 1);\r\n            const kk0 = Clamp(k0, 0, nz - 1);\r\n            const ii1 = Clamp(i1, 0, nx - 1);\r\n            const jj1 = Clamp(j1, 0, ny - 1);\r\n            const kk1 = Clamp(k1, 0, nz - 1);\r\n\r\n            // Get lattice control points\r\n            const p000 = this._data[ii0][jj0][kk0];\r\n            const p100 = this._data[ii1][jj0][kk0];\r\n            const p010 = this._data[ii0][jj1][kk0];\r\n            const p110 = this._data[ii1][jj1][kk0];\r\n            const p001 = this._data[ii0][jj0][kk1];\r\n            const p101 = this._data[ii1][jj0][kk1];\r\n            const p011 = this._data[ii0][jj1][kk1];\r\n            const p111 = this._data[ii1][jj1][kk1];\r\n\r\n            // Trilinear interpolation\r\n            const p00 = Vector3.LerpToRef(p000, p100, tx, this._lerpVector0);\r\n            const p01 = Vector3.LerpToRef(p001, p101, tx, this._lerpVector1);\r\n            const p10 = Vector3.LerpToRef(p010, p110, tx, this._lerpVector2);\r\n            const p11 = Vector3.LerpToRef(p011, p111, tx, this._lerpVector3);\r\n\r\n            const p0 = Vector3.LerpToRef(p00, p10, ty, this._lerpVector4);\r\n            const p1 = Vector3.LerpToRef(p01, p11, ty, this._lerpVector5);\r\n\r\n            const deformedPos = Vector3.LerpToRef(p0, p1, tz, this._lerpVector0);\r\n            deformedPos.addInPlace(this.position);\r\n\r\n            // Apply deformation to the vertex\r\n            deformedPos.toArray(target || positions, i);\r\n        }\r\n    }\r\n}\r\n","import { RawTexture3D } from \"core/Materials/Textures/rawTexture3D\";\r\nimport { type Material } from \"core/Materials/material\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase.pure\";\r\nimport { type Lattice } from \"./lattice\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\n\r\n/**\r\n * Material plugin to add hardware accelerated lattice support\r\n * @see [webgl2](https://playground.babylonjs.com/#HBZD72#5)\r\n * @see [webgpu](https://playground.babylonjs.com/#HBZD72#6)\r\n */\r\nexport class LatticePluginMaterial extends MaterialPluginBase {\r\n    private _lattice: Lattice;\r\n    private _latticeDataTexture: Nullable<RawTexture3D>;\r\n    private _latticeData: Float32Array;\r\n    private _code: string;\r\n\r\n    /**\r\n     * Create a new LatticePluginMaterial\r\n     * @param lattice defines the lattice this plugin is associated with\r\n     * @param material defines the material this plugin is associated with\r\n     */\r\n    constructor(lattice: Lattice, material: Material) {\r\n        super(material, \"Lattice\", 200);\r\n\r\n        this._lattice = lattice;\r\n\r\n        this.refreshData();\r\n\r\n        // let's enable it by default\r\n        this._enable(true);\r\n    }\r\n\r\n    /**\r\n     * Get the class name of the plugin\r\n     * @returns the string \"LatticePluginMaterial\"\r\n     */\r\n    public override getClassName() {\r\n        return \"LatticePluginMaterial\";\r\n    }\r\n\r\n    /**\r\n     * Defines if the plugin supports the specified shader language\r\n     * @param shaderLanguage defines the shader language to check\r\n     * @returns true if supported, false otherwise\r\n     */\r\n    public override isCompatible(shaderLanguage: ShaderLanguage) {\r\n        switch (shaderLanguage) {\r\n            case ShaderLanguage.GLSL:\r\n            case ShaderLanguage.WGSL:\r\n                return true;\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Must be called when the lattice data was updated\r\n     */\r\n    public refreshData() {\r\n        const length = this._lattice.resolutionX * this._lattice.resolutionY * this._lattice.resolutionZ * 4;\r\n        if (!this._latticeData || this._latticeData.length !== length) {\r\n            this._latticeData = new Float32Array(length);\r\n        }\r\n\r\n        for (let i = 0; i < this._lattice.resolutionX; i++) {\r\n            for (let j = 0; j < this._lattice.resolutionY; j++) {\r\n                for (let k = 0; k < this._lattice.resolutionZ; k++) {\r\n                    const control = this._lattice.data[i][j][k];\r\n                    const index = i + this._lattice.resolutionX * (j + this._lattice.resolutionY * k);\r\n                    control.toArray(this._latticeData, index * 4);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (\r\n            !this._latticeDataTexture ||\r\n            this._latticeDataTexture.width !== this._lattice.resolutionX ||\r\n            this._latticeDataTexture.height !== this._lattice.resolutionY ||\r\n            this._latticeDataTexture.depth !== this._lattice.resolutionZ\r\n        ) {\r\n            if (this._latticeDataTexture) {\r\n                this._latticeDataTexture.dispose();\r\n            }\r\n\r\n            this._latticeDataTexture = new RawTexture3D(\r\n                this._latticeData,\r\n                this._lattice.resolutionX,\r\n                this._lattice.resolutionY,\r\n                this._lattice.resolutionZ,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                this._material.getScene(),\r\n                false,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                Constants.TEXTURETYPE_FLOAT\r\n            );\r\n        } else {\r\n            this._latticeDataTexture.update(this._latticeData);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the description of the uniforms to add to the ubo (if engine supports ubos) or to inject directly in the vertex/fragment shaders (if engine does not support ubos)\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns the description of the uniforms\r\n     */\r\n    public override getUniforms(shaderLanguage: ShaderLanguage = ShaderLanguage.GLSL): {\r\n        ubo: { name: string; size: number; type: string; arraySize?: number }[];\r\n        vertex?: string;\r\n        fragment?: string;\r\n    } {\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            // For webgpu we only define the UBO with the correct type and size.\r\n            return {\r\n                ubo: [\r\n                    { name: \"lattice_cellSize\", size: 3, type: \"vec3\" },\r\n                    { name: \"lattice_min\", size: 3, type: \"vec3\" },\r\n                    { name: \"lattice_max\", size: 3, type: \"vec3\" },\r\n                    { name: \"lattice_resolution\", size: 3, type: \"vec3\" },\r\n                    { name: \"lattice_position\", size: 3, type: \"vec3\" },\r\n                ],\r\n            };\r\n        }\r\n        return {\r\n            // first, define the UBO with the correct type and size.\r\n            ubo: [\r\n                { name: \"lattice_cellSize\", size: 3, type: \"vec3\" },\r\n                { name: \"lattice_min\", size: 3, type: \"vec3\" },\r\n                { name: \"lattice_max\", size: 3, type: \"vec3\" },\r\n                { name: \"lattice_resolution\", size: 3, type: \"vec3\" },\r\n                { name: \"lattice_position\", size: 3, type: \"vec3\" },\r\n            ],\r\n            // now, on the vertex shader, add the uniform itself in case uniform buffers are not supported by the engine\r\n            vertex: `\r\n                    uniform vec3 lattice_cellSize;\r\n                    uniform vec3 lattice_min;\r\n                    uniform vec3 lattice_max;\r\n                    uniform vec3 lattice_resolution;\r\n                    uniform vec3 lattice_position;\r\n                    `,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Binds the material data.\r\n     * @param uniformBuffer defines the Uniform buffer to fill in.\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer) {\r\n        this._lattice.updateInternals();\r\n\r\n        uniformBuffer.updateVector3(\"lattice_cellSize\", this._lattice.cellSize);\r\n        uniformBuffer.updateVector3(\"lattice_min\", this._lattice.min);\r\n        uniformBuffer.updateVector3(\"lattice_max\", this._lattice.max);\r\n        uniformBuffer.updateFloat3(\"lattice_resolution\", this._lattice.resolutionX, this._lattice.resolutionY, this._lattice.resolutionZ);\r\n        uniformBuffer.updateVector3(\"lattice_position\", this._lattice.position);\r\n\r\n        uniformBuffer.setTexture(\"latticeData\", this._latticeDataTexture);\r\n    }\r\n\r\n    /**\r\n     * Gets the samplers used by the plugin.\r\n     * @param samplers list that the sampler names should be added to.\r\n     */\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"latticeData\");\r\n    }\r\n\r\n    private _prepareCode(shaderLanguage = ShaderLanguage.GLSL) {\r\n        if (this._code) {\r\n            return this._code;\r\n        }\r\n\r\n        let code = `\r\n            if (positionUpdated.x >= lattice_min.x && positionUpdated.x <= lattice_max.x &&\r\n                positionUpdated.y >= lattice_min.y && positionUpdated.y <= lattice_max.y &&\r\n                positionUpdated.z >= lattice_min.z && positionUpdated.z <= lattice_max.z) {\r\n\r\n                // Map vertex position to lattice local coordinates\r\n                vec3d localPos = vec3c((positionUpdated.x - lattice_min.x) / lattice_cellSize.x, (positionUpdated.y - lattice_min.y) / lattice_cellSize.y, (positionUpdated.z - lattice_min.z) / lattice_cellSize.z);\r\n\r\n                // Get integer lattice indices\r\n                intd i0 = intc(floor(localPos.x));\r\n                intd j0 = intc(floor(localPos.y));\r\n                intd k0 = intc(floor(localPos.z));\r\n\r\n                intd resX = intc(lattice_resolution.x) - 1;\r\n                intd resY = intc(lattice_resolution.y) - 1;\r\n                intd resZ = intc(lattice_resolution.z) - 1;\r\n\r\n                intd i1 = min(i0 + 1, resX);\r\n                intd j1 = min(j0 + 1, resY);\r\n                intd k1 = min(k0 + 1, resZ);\r\n\r\n                // Compute interpolation weights\r\n                floatd tx = localPos.x - floatc(i0);\r\n                floatd ty = localPos.y - floatc(j0);\r\n                floatd tz = localPos.z - floatc(k0);\r\n\r\n                // Ensure indices are within bounds\r\n                intd ii0 = clamp(i0, 0, resX);\r\n                intd jj0 = clamp(j0, 0, resY);\r\n                intd kk0 = clamp(k0, 0, resZ);\r\n                intd ii1 = clamp(i1, 0, resX);\r\n                intd jj1 = clamp(j1, 0, resY);\r\n                intd kk1 = clamp(k1, 0, resZ);\r\n\r\n                // Get lattice control points\r\n                vec3d p000 = texelFetch(latticeData, ivec3c(ii0, jj0, kk0), 0).rgb;\r\n                vec3d p100 = texelFetch(latticeData, ivec3c(ii1, jj0, kk0), 0).rgb;\r\n                vec3d p010 = texelFetch(latticeData, ivec3c(ii0, jj1, kk0), 0).rgb;\r\n                vec3d p110 = texelFetch(latticeData, ivec3c(ii1, jj1, kk0), 0).rgb;\r\n                vec3d p001 = texelFetch(latticeData, ivec3c(ii0, jj0, kk1), 0).rgb;\r\n                vec3d p101 = texelFetch(latticeData, ivec3c(ii1, jj0, kk1), 0).rgb;\r\n                vec3d p011 = texelFetch(latticeData, ivec3c(ii0, jj1, kk1), 0).rgb;\r\n                vec3d p111 = texelFetch(latticeData, ivec3c(ii1, jj1, kk1), 0).rgb;\r\n\r\n                // Trilinear interpolation\r\n                vec3d p00 = mix(p000, p100, tx);\r\n                vec3d p01 = mix(p001, p101, tx);\r\n                vec3d p10 = mix(p010, p110, tx);\r\n                vec3d p11 = mix(p011, p111, tx);\r\n\r\n                vec3d p0 = mix(p00, p10, ty);\r\n                vec3d p1 = mix(p01, p11, ty);\r\n\r\n                vec3d deformedPos = mix(p0, p1, tz);\r\n                positionUpdated = deformedPos + lattice_position;\r\n            };\r\n        `;\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            code =\r\n                `\r\n                let lattice_min = uniforms.lattice_min;\r\n                let lattice_max = uniforms.lattice_max;\r\n                let lattice_resolution = uniforms.lattice_resolution;\r\n                let lattice_position = uniforms.lattice_position;\r\n                let lattice_cellSize = uniforms.lattice_cellSize;\r\n            ` + code;\r\n\r\n            code = code.replace(/ivec3c/g, \"vec3i\");\r\n            code = code.replace(/vec3d/g, \"var\");\r\n            code = code.replace(/vec3c/g, \"vec3f\");\r\n            code = code.replace(/intd/g, \"var\");\r\n            code = code.replace(/intc/g, \"i32\");\r\n            code = code.replace(/floatd/g, \"var\");\r\n            code = code.replace(/floatc/g, \"f32\");\r\n            code = code.replace(/texelFetch/g, \"textureLoad\");\r\n        } else {\r\n            code = code.replace(/ivec3c/g, \"ivec3\");\r\n            code = code.replace(/vec3d/g, \"vec3\");\r\n            code = code.replace(/vec3c/g, \"vec3\");\r\n            code = code.replace(/intd/g, \"int\");\r\n            code = code.replace(/intc/g, \"int\");\r\n            code = code.replace(/floatd/g, \"float\");\r\n            code = code.replace(/floatc/g, \"float\");\r\n        }\r\n        this._code = code;\r\n\r\n        return this._code;\r\n    }\r\n\r\n    /**\r\n     * Returns a list of custom shader code fragments to customize the shader.\r\n     * @param shaderType \"vertex\" or \"fragment\"\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns null if no code to be added, or a list of pointName =\\> code.\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL) {\r\n        if (shaderType === \"vertex\") {\r\n            // we're adding this specific code at the end of the main() function\r\n            if (shaderLanguage === ShaderLanguage.WGSL) {\r\n                return {\r\n                    CUSTOM_VERTEX_DEFINITIONS: `\r\n                        var latticeData: texture_3d<f32>;\r\n                    `,\r\n                    CUSTOM_VERTEX_UPDATE_POSITION: this._prepareCode(shaderLanguage),\r\n                };\r\n            }\r\n\r\n            return {\r\n                CUSTOM_VERTEX_DEFINITIONS: `\r\n                    precision highp sampler3D;\r\n                    uniform sampler3D latticeData;\r\n                `,\r\n                CUSTOM_VERTEX_UPDATE_POSITION: this._prepareCode(shaderLanguage),\r\n            };\r\n        }\r\n        // for other shader types we're not doing anything, return null\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources of the material.\r\n     */\r\n    public override dispose(): void {\r\n        if (this._latticeDataTexture) {\r\n            this._latticeDataTexture.dispose();\r\n            this._latticeDataTexture = null;\r\n        }\r\n    }\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { type IGreasedLineMaterial } from \"../../Materials/GreasedLine/greasedLineMaterialInterfaces\";\r\nimport { GreasedLinePluginMaterial } from \"../../Materials/GreasedLine/greasedLinePluginMaterial.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { Buffer } from \"../../Buffers/buffer.pure\";\r\nimport { type Vector3 } from \"../../Maths/math.vector\";\r\nimport { VertexData } from \"../mesh.vertexData\";\r\nimport { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { GreasedLineSimpleMaterial, GreasedLineUseOffsetsSimpleMaterialDefine } from \"../../Materials/GreasedLine/greasedLineSimpleMaterial\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type FloatArray, type IndicesArray } from \"../../types\";\r\nimport { GreasedLineTools } from \"../../Misc/greasedLineTools\";\r\n\r\n/**\r\n * In POINTS_MODE_POINTS every array of points will become the center (backbone) of the ribbon. The ribbon will be expanded by `width / 2` to `+direction` and `-direction` as well.\r\n * In POINTS_MODE_PATHS every array of points specifies an edge. These will be used to build one ribbon.\r\n */\r\nexport const enum GreasedLineRibbonPointsMode {\r\n    POINTS_MODE_POINTS = 0,\r\n    POINTS_MODE_PATHS = 1,\r\n}\r\n\r\n/**\r\n * FACES_MODE_SINGLE_SIDED single sided with back face culling. Default value.\r\n * FACES_MODE_SINGLE_SIDED_NO_BACKFACE_CULLING single sided without back face culling. Sets backFaceCulling = false on the material so it affects all line ribbons added to the line ribbon instance.\r\n * FACES_MODE_DOUBLE_SIDED extra back faces are created. This doubles the amount of faces of the mesh.\r\n */\r\nexport const enum GreasedLineRibbonFacesMode {\r\n    FACES_MODE_SINGLE_SIDED = 0,\r\n    FACES_MODE_SINGLE_SIDED_NO_BACKFACE_CULLING = 1,\r\n    FACES_MODE_DOUBLE_SIDED = 2,\r\n}\r\n\r\n/**\r\n * Only with POINTS_MODE_PATHS.\r\n * AUTO_DIRECTIONS_FROM_FIRST_SEGMENT sets the direction (slope) of the ribbon from the direction of the first line segment. Recommended.\r\n * AUTO_DIRECTIONS_FROM_ALL_SEGMENTS in this mode the direction (slope) will be calculated for each line segment according to the direction vector between each point of the line segments. Slow method.\r\n * AUTO_DIRECTIONS_ENHANCED in this mode the direction (slope) will be calculated for each line segment according to the direction vector between each point of the line segments using a more sophisitcaed algorithm. Slowest method.\r\n * AUTO_DIRECTIONS_FACE_TO in this mode the direction (slope) will be calculated for each line segment according to the direction vector between each point of the line segments and a direction (face-to) vector specified in direction. The resulting line will face to the direction of this face-to vector.\r\n * AUTO_DIRECTIONS_NONE you have to set the direction (slope) manually. Recommended.\r\n */\r\nexport const enum GreasedLineRibbonAutoDirectionMode {\r\n    AUTO_DIRECTIONS_FROM_FIRST_SEGMENT = 0,\r\n    AUTO_DIRECTIONS_FROM_ALL_SEGMENTS = 1,\r\n    AUTO_DIRECTIONS_ENHANCED = 2,\r\n    AUTO_DIRECTIONS_FACE_TO = 3,\r\n    AUTO_DIRECTIONS_NONE = 99,\r\n}\r\n\r\nexport type GreasedLineRibbonOptions = {\r\n    /**\r\n     * Defines how the points are processed.\r\n     * In GreasedLineRibbonPointsMode.POINTS_MODE_POINTS every array of points will become the center of the ribbon. The ribbon will be expanded by width/2 to +direction and -direction as well.\r\n     * In GreasedLineRibbonPointsMode.POINTS_MODE_PATHS every array of points is one path. These will be used to buuid one ribbon.\r\n     */\r\n    pointsMode?: GreasedLineRibbonPointsMode;\r\n    /**\r\n     * Normalized directions of the slopes of the non camera facing lines.\r\n     */\r\n    directions?: Vector3[] | Vector3;\r\n    /**\r\n     * Defines the calculation mode of the directions which the line will be thickened to.\r\n     */\r\n    directionsAutoMode?: GreasedLineRibbonAutoDirectionMode;\r\n    /**\r\n     * Width of the ribbon.\r\n     */\r\n    width?: number;\r\n    /**\r\n     * Controls how the faces are created.\r\n     * GreasedLineRibbonFacesMode.FACES_MODE_SINGLE_SIDED = single sided with back face culling. Default value.\r\n     * GreasedLineRibbonFacesMode.FACES_MODE_SINGLE_SIDED_NO_BACKFACE_CULLING = single sided without back face culling\r\n     * GreasedLineRibbonFacesMode.FACES_MODE_DOUBLE_SIDED = extra back faces are created. This doubles the amount of faces of the mesh.\r\n     */\r\n    facesMode?: GreasedLineRibbonFacesMode;\r\n    /**\r\n     * If true, the path will be closed.\r\n     */\r\n    closePath?: boolean;\r\n    /**\r\n     * If true, normals will be computed when creating the vertex buffers.\r\n     * This results to smooth shading of the mesh.\r\n     */\r\n    smoothShading?: boolean;\r\n};\r\n\r\nexport type GreasedLinePoints = Vector3[] | Vector3[][] | Float32Array | Float32Array[] | number[][] | number[];\r\n\r\n/**\r\n * Options for converting the points to the internal number[][] format used by GreasedLine\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GreasedLinePointsOptions {\r\n    /**\r\n     * If defined and a Float32Array is used for the points parameter,\r\n     * it will create multiple disconnected lines.\r\n     * This parameter defines how many entries from the array to use for one line.\r\n     * One entry = 3 float values.\r\n     */\r\n    floatArrayStride?: number;\r\n}\r\n\r\n/**\r\n * Options for creating a GreasedLineMesh\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GreasedLineMeshOptions {\r\n    /**\r\n     * Points of the line.\r\n     */\r\n    points: GreasedLinePoints;\r\n    /**\r\n     * Each line segment (from point to point) can have it's width multiplier. Final width = widths[segmentIdx] * width.\r\n     * Defaults to empty array.\r\n     */\r\n    widths?: number[];\r\n    /**\r\n     * If instance is specified, lines are added to the specified instance.\r\n     * Defaults to undefined.\r\n     */\r\n    instance?: GreasedLineBaseMesh;\r\n    /**\r\n     * You can manually set the color pointers so you can control which segment/part\r\n     * will use which color from the colors material option\r\n     */\r\n    colorPointers?: number[];\r\n    /**\r\n     * UVs for the mesh\r\n     */\r\n    uvs?: FloatArray;\r\n    /**\r\n     * If true, offsets and widths are updatable.\r\n     * Defaults to false.\r\n     */\r\n    updatable?: boolean;\r\n    /**\r\n     * Use when @see instance is specified.\r\n     * If true, the line will be rendered only after calling instance.updateLazy(). If false, line will be rerendered after every call to @see CreateGreasedLine\r\n     * Defaults to false.\r\n     */\r\n    lazy?: boolean;\r\n    /**\r\n     * The options for the ribbon which will be used as a line.\r\n     * If this option is set the line switches automatically to a non camera facing mode.\r\n     */\r\n    ribbonOptions?: GreasedLineRibbonOptions;\r\n    /**\r\n     * Options for converting the points.\r\n     */\r\n    pointsOptions?: GreasedLinePointsOptions;\r\n}\r\n\r\n/**\r\n * GreasedLineBaseMesh\r\n */\r\nexport abstract class GreasedLineBaseMesh extends Mesh {\r\n    protected _vertexPositions: FloatArray;\r\n    protected _indices: IndicesArray;\r\n    protected _uvs: FloatArray;\r\n    protected _points: number[][];\r\n    protected _offsets: number[];\r\n    protected _colorPointers: number[];\r\n    protected _widths: number[];\r\n\r\n    protected _offsetsBuffer?: Buffer;\r\n    protected _widthsBuffer?: Buffer;\r\n    protected _colorPointersBuffer?: Buffer;\r\n\r\n    protected _lazy = false;\r\n    protected _updatable = false;\r\n\r\n    protected _engine: AbstractEngine;\r\n\r\n    constructor(\r\n        public override readonly name: string,\r\n        scene: Scene,\r\n        protected _options: GreasedLineMeshOptions\r\n    ) {\r\n        super(name, scene, null, null, false, false);\r\n\r\n        this._engine = scene.getEngine();\r\n\r\n        this._lazy = _options.lazy ?? false;\r\n        this._updatable = _options.updatable ?? false;\r\n\r\n        this._vertexPositions = [];\r\n        this._indices = [];\r\n        this._uvs = [];\r\n        this._points = [];\r\n        this._colorPointers = _options.colorPointers ?? [];\r\n        this._widths = _options.widths ?? new Array(_options.points.length).fill(1);\r\n    }\r\n\r\n    /**\r\n     * \"GreasedLineMesh\"\r\n     * @returns \"GreasedLineMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GreasedLineMesh\";\r\n    }\r\n\r\n    protected abstract _setPoints(points: number[][], options?: GreasedLineMeshOptions): void;\r\n    protected abstract _updateColorPointers(): void;\r\n    protected abstract _updateWidths(): void;\r\n\r\n    protected _updateWidthsWithValue(defaulValue: number) {\r\n        let pointCount = 0;\r\n        for (const points of this._points) {\r\n            pointCount += points.length;\r\n        }\r\n        const countDiff = (pointCount / 3) * 2 - this._widths.length;\r\n        for (let i = 0; i < countDiff; i++) {\r\n            this._widths.push(defaulValue);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updated a lazy line. Rerenders the line and updates boundinfo as well.\r\n     */\r\n    public updateLazy() {\r\n        this._setPoints(this._points);\r\n        if (!this._options.colorPointers) {\r\n            this._updateColorPointers();\r\n        }\r\n        this._createVertexBuffers(this._options.ribbonOptions?.smoothShading);\r\n        !this.doNotSyncBoundingInfo && this.refreshBoundingInfo();\r\n\r\n        this.greasedLineMaterial?.updateLazy();\r\n    }\r\n\r\n    /**\r\n     * Adds new points to the line. It doesn't rerenders the line if in lazy mode.\r\n     * @param points points table\r\n     * @param options optional options\r\n     */\r\n    public addPoints(points: number[][], options?: GreasedLineMeshOptions) {\r\n        for (const p of points) {\r\n            this._points.push(p);\r\n        }\r\n\r\n        if (!this._lazy) {\r\n            this.setPoints(this._points, options);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the line and it's resources\r\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\r\n     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)\r\n     */\r\n    public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures = false) {\r\n        super.dispose(doNotRecurse, disposeMaterialAndTextures);\r\n    }\r\n\r\n    /**\r\n     * @returns true if the mesh was created in lazy mode\r\n     */\r\n    public isLazy(): boolean {\r\n        return this._lazy;\r\n    }\r\n\r\n    /**\r\n     * Returns the UVs\r\n     */\r\n    get uvs() {\r\n        return this._uvs;\r\n    }\r\n\r\n    /**\r\n     * Sets the UVs\r\n     * @param uvs the UVs\r\n     */\r\n    set uvs(uvs: FloatArray) {\r\n        this._uvs = uvs instanceof Float32Array ? uvs : new Float32Array(uvs);\r\n        this._createVertexBuffers();\r\n    }\r\n\r\n    /**\r\n     * Returns the points offsets\r\n     * Return the points offsets\r\n     */\r\n    get offsets() {\r\n        return this._offsets;\r\n    }\r\n\r\n    /**\r\n     * Sets point offests\r\n     * @param offsets offset table [x,y,z, x,y,z, ....]\r\n     */\r\n    set offsets(offsets: number[]) {\r\n        if (this.material instanceof GreasedLineSimpleMaterial) {\r\n            this.material.setDefine(GreasedLineUseOffsetsSimpleMaterialDefine, offsets?.length > 0);\r\n        }\r\n        this._offsets = offsets;\r\n        if (!this._offsetsBuffer) {\r\n            this._createOffsetsBuffer(offsets);\r\n        } else {\r\n            this._offsetsBuffer.update(offsets);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets widths at each line point like [widthLower, widthUpper, widthLower, widthUpper, ...]\r\n     */\r\n    get widths() {\r\n        return this._widths;\r\n    }\r\n\r\n    /**\r\n     * Sets widths at each line point\r\n     * @param widths width table [widthLower, widthUpper, widthLower, widthUpper ...]\r\n     */\r\n    set widths(widths: number[]) {\r\n        this._widths = widths;\r\n        if (!this._lazy) {\r\n            this._widthsBuffer && this._widthsBuffer.update(widths);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the color pointer. Each vertex need a color pointer. These color pointers points to the colors in the color table @see colors\r\n     */\r\n    get colorPointers() {\r\n        return this._colorPointers;\r\n    }\r\n\r\n    /**\r\n     * Sets the color pointer\r\n     * @param colorPointers array of color pointer in the colors array. One pointer for every vertex is needed.\r\n     */\r\n    set colorPointers(colorPointers: number[]) {\r\n        this._colorPointers = colorPointers;\r\n        if (!this._lazy) {\r\n            this._colorPointersBuffer && this._colorPointersBuffer.update(colorPointers);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the pluginMaterial associated with line\r\n     */\r\n    get greasedLineMaterial(): IGreasedLineMaterial | undefined {\r\n        if (this.material && this.material instanceof GreasedLineSimpleMaterial) {\r\n            return this.material;\r\n        }\r\n        const materialPlugin = this.material?.pluginManager?.getPlugin(GreasedLinePluginMaterial.GREASED_LINE_MATERIAL_NAME);\r\n        if (materialPlugin) {\r\n            return <GreasedLinePluginMaterial>materialPlugin;\r\n        }\r\n        return;\r\n    }\r\n\r\n    /**\r\n     * Return copy the points.\r\n     */\r\n    get points() {\r\n        const pointsCopy: number[][] = [];\r\n        DeepCopier.DeepCopy(this._points, pointsCopy);\r\n        return pointsCopy;\r\n    }\r\n\r\n    /**\r\n     * Sets line points and rerenders the line.\r\n     * @param points points table\r\n     * @param options optional options\r\n     */\r\n    public setPoints(points: GreasedLinePoints, options?: GreasedLineMeshOptions) {\r\n        this._points = GreasedLineTools.ConvertPoints(points, options?.pointsOptions ?? this._options.pointsOptions);\r\n        this._updateWidths();\r\n        if (!options?.colorPointers) {\r\n            this._updateColorPointers();\r\n        }\r\n        this._setPoints(this._points, options);\r\n    }\r\n\r\n    protected _initGreasedLine() {\r\n        this._vertexPositions = [];\r\n        this._indices = [];\r\n        this._uvs = [];\r\n    }\r\n\r\n    protected _createLineOptions() {\r\n        const lineOptions: GreasedLineMeshOptions = {\r\n            points: this._points,\r\n            colorPointers: this._colorPointers,\r\n            lazy: this._lazy,\r\n            updatable: this._updatable,\r\n            uvs: this._uvs,\r\n            widths: this._widths,\r\n            ribbonOptions: this._options.ribbonOptions,\r\n        };\r\n        return lineOptions;\r\n    }\r\n\r\n    /**\r\n     * Serializes this GreasedLineMesh\r\n     * @param serializationObject object to write serialization to\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.type = this.getClassName();\r\n\r\n        serializationObject.lineOptions = this._createLineOptions();\r\n    }\r\n\r\n    protected _createVertexBuffers(computeNormals = false) {\r\n        const vertexData = new VertexData();\r\n        vertexData.positions = this._vertexPositions;\r\n        vertexData.indices = this._indices;\r\n        vertexData.uvs = this._uvs;\r\n        if (computeNormals) {\r\n            vertexData.normals = [];\r\n            VertexData.ComputeNormals(this._vertexPositions, this._indices, vertexData.normals);\r\n        }\r\n        vertexData.applyToMesh(this, this._options.updatable);\r\n        return vertexData;\r\n    }\r\n\r\n    protected _createOffsetsBuffer(offsets: number[]) {\r\n        const engine = this._scene.getEngine();\r\n\r\n        const offsetBuffer = new Buffer(engine, offsets, this._updatable, 3);\r\n        this.setVerticesBuffer(offsetBuffer.createVertexBuffer(\"grl_offsets\", 0, 3));\r\n        this._offsetsBuffer = offsetBuffer;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Matrix } from \"../../Maths/math.vector\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { type Ray, type TrianglePickingPredicate } from \"../../Culling/ray.pure\";\r\nimport { Buffer, VertexBuffer } from \"../../Buffers/buffer.pure\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { type Nullable, type FloatArray } from \"../../types\";\r\nimport { type Node } from \"../../node\";\r\nimport { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { GreasedLineTools } from \"../../Misc/greasedLineTools\";\r\nimport { GreasedLineBaseMesh, type GreasedLineMeshOptions } from \"./greasedLineBaseMesh\";\r\n\r\nimport { type VertexData } from \"../mesh.vertexData\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * GreasedLineMesh\r\n * Use the GreasedLineBuilder.CreateGreasedLine function to create an instance of this class.\r\n */\r\nexport class GreasedLineMesh extends GreasedLineBaseMesh {\r\n    private _previousAndSide: FloatArray;\r\n    private _nextAndCounters: FloatArray;\r\n\r\n    private static _V_START = /*#__PURE__*/ new Vector3();\r\n    private static _V_END = /*#__PURE__*/ new Vector3();\r\n    private static _V_OFFSET_START = /*#__PURE__*/ new Vector3();\r\n    private static _V_OFFSET_END = /*#__PURE__*/ new Vector3();\r\n\r\n    /**\r\n     * Treshold used to pick the mesh\r\n     */\r\n    public intersectionThreshold = 0.1;\r\n\r\n    /**\r\n     * GreasedLineMesh\r\n     * @param name name of the mesh\r\n     * @param scene the scene\r\n     * @param _options mesh options\r\n     */\r\n    constructor(\r\n        public override readonly name: string,\r\n        scene: Scene,\r\n        _options: GreasedLineMeshOptions\r\n    ) {\r\n        super(name, scene, _options);\r\n\r\n        this._previousAndSide = [];\r\n        this._nextAndCounters = [];\r\n\r\n        if (_options.points) {\r\n            this.addPoints(GreasedLineTools.ConvertPoints(_options.points));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * \"GreasedLineMesh\"\r\n     * @returns \"GreasedLineMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GreasedLineMesh\";\r\n    }\r\n\r\n    protected _updateColorPointers() {\r\n        if (this._options.colorPointers) {\r\n            return;\r\n        }\r\n\r\n        let colorPointer = 0;\r\n        this._colorPointers = [];\r\n        for (const p of this._points) {\r\n            for (let jj = 0; jj < p.length; jj += 3) {\r\n                this._colorPointers.push(colorPointer);\r\n                this._colorPointers.push(colorPointer++);\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _updateWidths(): void {\r\n        // intentionally left blank\r\n    }\r\n\r\n    protected _setPoints(points: number[][]) {\r\n        this._points = points;\r\n        this._options.points = points;\r\n\r\n        this._initGreasedLine();\r\n\r\n        let indiceOffset = 0;\r\n        let vertexPositionsLen = 0,\r\n            indicesLength = 0,\r\n            uvLength = 0,\r\n            previousAndSideLength = 0,\r\n            maxLineLength = 0;\r\n        for (const p of points) {\r\n            maxLineLength = Math.max(p.length, maxLineLength);\r\n            vertexPositionsLen += p.length * 2;\r\n            indicesLength += (p.length - 3) * 2;\r\n            uvLength += (p.length * 4) / 3;\r\n            previousAndSideLength += (p.length * 8) / 3;\r\n        }\r\n        const buffer = new ArrayBuffer(vertexPositionsLen * 4 + indicesLength * (vertexPositionsLen > 65535 ? 4 : 2) + uvLength * 4 + previousAndSideLength * 4 * 2);\r\n        const tempBuffer = new ArrayBuffer((maxLineLength / 3 + maxLineLength * 4) * 4);\r\n        let byteOffset = 0;\r\n        const vertexPositionsArr = new Float32Array(buffer, byteOffset, vertexPositionsLen);\r\n        byteOffset += vertexPositionsArr.byteLength;\r\n        const indicesArr = vertexPositionsLen > 65535 ? new Uint32Array(buffer, byteOffset, indicesLength) : new Uint16Array(buffer, byteOffset, indicesLength);\r\n        byteOffset += indicesArr.byteLength;\r\n        const uvArr = new Float32Array(buffer, byteOffset, uvLength);\r\n        byteOffset += uvArr.byteLength;\r\n        const previousAndSide = new Float32Array(buffer, byteOffset, previousAndSideLength);\r\n        byteOffset += previousAndSide.byteLength;\r\n        // it's the same length here\r\n        const nextAndCounters = new Float32Array(buffer, byteOffset, previousAndSideLength);\r\n        let vertexPositionsOffset = 0,\r\n            indicesOffset = 0,\r\n            uvOffset = 0,\r\n            previousAndSideOffset = 0,\r\n            nextAndCountersOffset = 0;\r\n\r\n        for (const p of points) {\r\n            const lengthArray = GreasedLineTools.GetLineLengthArray(p, tempBuffer);\r\n            const totalLength = lengthArray[lengthArray.length - 1];\r\n            for (let j = 0, jj = 0; jj < p.length; j++, jj += 3) {\r\n                const baseOffset = vertexPositionsOffset + jj * 2;\r\n                vertexPositionsArr[baseOffset + 0] = p[jj + 0];\r\n                vertexPositionsArr[baseOffset + 1] = p[jj + 1];\r\n                vertexPositionsArr[baseOffset + 2] = p[jj + 2];\r\n                vertexPositionsArr[baseOffset + 3] = p[jj + 0];\r\n                vertexPositionsArr[baseOffset + 4] = p[jj + 1];\r\n                vertexPositionsArr[baseOffset + 5] = p[jj + 2];\r\n\r\n                if (jj < p.length - 3) {\r\n                    const n = j * 2 + indiceOffset;\r\n                    const baseIndicesOffset = indicesOffset + jj * 2;\r\n                    indicesArr[baseIndicesOffset + 0] = n;\r\n                    indicesArr[baseIndicesOffset + 1] = n + 1;\r\n                    indicesArr[baseIndicesOffset + 2] = n + 2;\r\n                    indicesArr[baseIndicesOffset + 3] = n + 2;\r\n                    indicesArr[baseIndicesOffset + 4] = n + 1;\r\n                    indicesArr[baseIndicesOffset + 5] = n + 3;\r\n                }\r\n            }\r\n\r\n            indiceOffset += (p.length / 3) * 2;\r\n            const currVertexPositionsOffsetLength = p.length * 2;\r\n            const positions = vertexPositionsArr.subarray(vertexPositionsOffset, vertexPositionsOffset + currVertexPositionsOffsetLength);\r\n            vertexPositionsOffset += currVertexPositionsOffsetLength;\r\n            indicesOffset += (p.length - 3) * 2;\r\n\r\n            let byteOffset = lengthArray.byteLength;\r\n            const previous = new Float32Array(tempBuffer, byteOffset, positions.length);\r\n            byteOffset += previous.byteLength;\r\n            const next = new Float32Array(tempBuffer, byteOffset, positions.length);\r\n            const l = positions.length / 6;\r\n            let v;\r\n            if (GreasedLineMesh._CompareV3(0, l - 1, positions)) {\r\n                v = positions.subarray((l - 2) * 6, (l - 1) * 6);\r\n            } else {\r\n                v = positions.subarray(0, 6);\r\n            }\r\n            previous.set(v);\r\n            previous.set(positions.subarray(0, positions.length - 6), 6);\r\n            next.set(positions.subarray(6));\r\n            if (GreasedLineMesh._CompareV3(l - 1, 0, positions)) {\r\n                v = positions.subarray(6, 12);\r\n            } else {\r\n                v = positions.subarray((l - 1) * 6, l * 6);\r\n            }\r\n            next.set(v, next.length - 6);\r\n\r\n            for (let i = 0, sidesLength = positions.length / 3; i < sidesLength; i++) {\r\n                previousAndSide[previousAndSideOffset++] = previous[i * 3];\r\n                previousAndSide[previousAndSideOffset++] = previous[i * 3 + 1];\r\n                previousAndSide[previousAndSideOffset++] = previous[i * 3 + 2];\r\n                // side[i] = i % 2 ? -1 : 1;\r\n                // side[i] = 1 - ((i & 1) << 1);\r\n                previousAndSide[previousAndSideOffset++] = 1 - ((i & 1) << 1);\r\n                nextAndCounters[nextAndCountersOffset++] = next[i * 3];\r\n                nextAndCounters[nextAndCountersOffset++] = next[i * 3 + 1];\r\n                nextAndCounters[nextAndCountersOffset++] = next[i * 3 + 2];\r\n                // counters[i] = lengthArray[i >> 1] / totalLength;\r\n                nextAndCounters[nextAndCountersOffset++] = lengthArray[i >> 1] / totalLength;\r\n            }\r\n            if (this._options.uvs) {\r\n                for (let i = 0; i < this._options.uvs.length; i++) {\r\n                    uvArr[uvOffset++] = this._options.uvs[i];\r\n                }\r\n            } else {\r\n                for (let j = 0; j < l; j++) {\r\n                    // uvs\r\n                    const lengthRatio = lengthArray[j] / totalLength;\r\n                    const uvOffsetBase = uvOffset + j * 4;\r\n                    uvArr[uvOffsetBase + 0] = lengthRatio;\r\n                    uvArr[uvOffsetBase + 1] = 0;\r\n                    uvArr[uvOffsetBase + 2] = lengthRatio;\r\n                    uvArr[uvOffsetBase + 3] = 1;\r\n                }\r\n            }\r\n        }\r\n        this._vertexPositions = vertexPositionsArr;\r\n        this._indices = indicesArr;\r\n        this._uvs = uvArr;\r\n        this._previousAndSide = previousAndSide;\r\n        this._nextAndCounters = nextAndCounters;\r\n\r\n        if (!this._lazy) {\r\n            if (!this._options.colorPointers) {\r\n                this._updateColorPointers();\r\n            }\r\n            this._createVertexBuffers();\r\n            !this.doNotSyncBoundingInfo && this.refreshBoundingInfo();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clones the GreasedLineMesh.\r\n     * @param name new line name\r\n     * @param newParent new parent node\r\n     * @returns cloned line\r\n     */\r\n    public override clone(name: string = `${this.name}-cloned`, newParent?: Nullable<Node>) {\r\n        const lineOptions = this._createLineOptions();\r\n        const deepCopiedLineOptions = {};\r\n        DeepCopier.DeepCopy(lineOptions, deepCopiedLineOptions, [\"instance\"], undefined, true);\r\n\r\n        const cloned = new GreasedLineMesh(name, this._scene, <GreasedLineMeshOptions>deepCopiedLineOptions);\r\n        if (newParent) {\r\n            cloned.parent = newParent;\r\n        }\r\n\r\n        cloned.material = this.material;\r\n\r\n        return cloned;\r\n    }\r\n\r\n    /**\r\n     * Serializes this GreasedLineMesh\r\n     * @param serializationObject object to write serialization to\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.type = this.getClassName();\r\n\r\n        serializationObject.lineOptions = this._createLineOptions();\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized GreasedLineMesh\r\n     * @param parsedMesh the serialized GreasedLineMesh\r\n     * @param scene the scene to create the GreasedLineMesh in\r\n     * @returns the created GreasedLineMesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): Mesh {\r\n        const lineOptions = <GreasedLineMeshOptions>parsedMesh.lineOptions;\r\n        const name = <string>parsedMesh.name;\r\n        const result = new GreasedLineMesh(name, scene, lineOptions);\r\n        return result;\r\n    }\r\n\r\n    protected override _initGreasedLine() {\r\n        super._initGreasedLine();\r\n\r\n        this._previousAndSide = [];\r\n        this._nextAndCounters = [];\r\n    }\r\n    /**\r\n     * Checks whether a ray is intersecting this GreasedLineMesh\r\n     * @param ray ray to check the intersection of this mesh with\r\n     * @param fastCheck not supported\r\n     * @param trianglePredicate not supported\r\n     * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)\r\n     * @param worldToUse not supported\r\n     * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n     * @returns the picking info\r\n     */\r\n    public override intersects(\r\n        ray: Ray,\r\n        fastCheck?: boolean,\r\n        trianglePredicate?: TrianglePickingPredicate,\r\n        onlyBoundingInfo = false,\r\n        worldToUse?: Matrix,\r\n        skipBoundingInfo = false\r\n    ): PickingInfo {\r\n        const pickingInfo = new PickingInfo();\r\n        const intersections = this.findAllIntersections(ray, fastCheck, trianglePredicate, onlyBoundingInfo, worldToUse, skipBoundingInfo, true);\r\n        if (intersections?.length === 1) {\r\n            const intersection = intersections[0];\r\n            pickingInfo.hit = true;\r\n            pickingInfo.distance = intersection.distance;\r\n            pickingInfo.ray = ray;\r\n            pickingInfo.pickedMesh = this;\r\n            pickingInfo.pickedPoint = intersection.point;\r\n        }\r\n        return pickingInfo;\r\n    }\r\n\r\n    /**\r\n     * Gets all intersections of a ray and the line\r\n     * @param ray Ray to check the intersection of this mesh with\r\n     * @param _fastCheck not supported\r\n     * @param _trianglePredicate not supported\r\n     * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)\r\n     * @param _worldToUse not supported\r\n     * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n     * @param firstOnly If true, the first and only intersection is immediatelly returned if found\r\n     * @returns intersection(s)\r\n     */\r\n    public findAllIntersections(\r\n        ray: Ray,\r\n        _fastCheck?: boolean,\r\n        _trianglePredicate?: TrianglePickingPredicate,\r\n        onlyBoundingInfo = false,\r\n        _worldToUse?: Matrix,\r\n        skipBoundingInfo = false,\r\n        firstOnly = false\r\n    ): { distance: number; point: Vector3 }[] | undefined {\r\n        if (onlyBoundingInfo && !skipBoundingInfo && ray.intersectsSphere(this._boundingSphere, this.intersectionThreshold) === false) {\r\n            return;\r\n        }\r\n\r\n        const indices = this.getIndices();\r\n        const positions = this.getVerticesData(VertexBuffer.PositionKind);\r\n        const widths = this._widths;\r\n\r\n        const lineWidth = this.greasedLineMaterial?.width ?? 1;\r\n\r\n        const intersects = [];\r\n        if (indices && positions && widths) {\r\n            let i: number, l: number;\r\n            for (i = 0, l = indices.length - 1; i < l; i += 3) {\r\n                const a = indices[i];\r\n                const b = indices[i + 1];\r\n\r\n                GreasedLineMesh._V_START.fromArray(positions, a * 3);\r\n                GreasedLineMesh._V_END.fromArray(positions, b * 3);\r\n\r\n                if (this._offsets) {\r\n                    GreasedLineMesh._V_OFFSET_START.fromArray(this._offsets, a * 3);\r\n                    GreasedLineMesh._V_OFFSET_END.fromArray(this._offsets, b * 3);\r\n                    GreasedLineMesh._V_START.addInPlace(GreasedLineMesh._V_OFFSET_START);\r\n                    GreasedLineMesh._V_END.addInPlace(GreasedLineMesh._V_OFFSET_END);\r\n                }\r\n\r\n                const iFloored = Math.floor(i / 3);\r\n                const width = widths[iFloored] !== undefined ? widths[iFloored] : 1;\r\n                const precision = (this.intersectionThreshold * (lineWidth * width)) / 2;\r\n\r\n                const distance = ray.intersectionSegment(GreasedLineMesh._V_START, GreasedLineMesh._V_END, precision);\r\n                if (distance !== -1) {\r\n                    intersects.push({\r\n                        distance: distance,\r\n                        point: ray.direction.normalize().multiplyByFloats(distance, distance, distance).add(ray.origin),\r\n                    });\r\n                    if (firstOnly) {\r\n                        return intersects;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return intersects;\r\n    }\r\n\r\n    private get _boundingSphere() {\r\n        return this.getBoundingInfo().boundingSphere;\r\n    }\r\n\r\n    private static _CompareV3(positionIdx1: number, positionIdx2: number, positions: FloatArray) {\r\n        const arrayIdx1 = positionIdx1 * 6;\r\n        const arrayIdx2 = positionIdx2 * 6;\r\n        return positions[arrayIdx1] === positions[arrayIdx2] && positions[arrayIdx1 + 1] === positions[arrayIdx2 + 1] && positions[arrayIdx1 + 2] === positions[arrayIdx2 + 2];\r\n    }\r\n\r\n    protected override _createVertexBuffers() {\r\n        const vertexData: VertexData = super._createVertexBuffers();\r\n\r\n        const engine = this._scene.getEngine();\r\n\r\n        const previousAndSideBuffer = new Buffer(engine, this._previousAndSide, false, 4);\r\n        this.setVerticesBuffer(previousAndSideBuffer.createVertexBuffer(\"grl_previousAndSide\", 0, 4));\r\n\r\n        const nextAndCountersBuffer = new Buffer(engine, this._nextAndCounters, false, 4);\r\n        this.setVerticesBuffer(nextAndCountersBuffer.createVertexBuffer(\"grl_nextAndCounters\", 0, 4));\r\n\r\n        const widthBuffer = new Buffer(engine, this._widths, this._updatable, 1);\r\n        this.setVerticesBuffer(widthBuffer.createVertexBuffer(\"grl_widths\", 0, 1));\r\n        this._widthsBuffer = widthBuffer;\r\n\r\n        const colorPointersBuffer = new Buffer(engine, this._colorPointers, this._updatable, 1);\r\n        this.setVerticesBuffer(colorPointersBuffer.createVertexBuffer(\"grl_colorPointers\", 0, 1));\r\n        this._colorPointersBuffer = colorPointersBuffer;\r\n\r\n        return vertexData;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for greasedLineMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGreasedLineMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GreasedLineMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        return GreasedLineMesh.Parse(parsedMesh, scene);\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Quaternion, TmpVectors, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { Buffer } from \"../../Buffers/buffer.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Node } from \"../../node\";\r\nimport { DeepCopier } from \"../../Misc/deepCopier\";\r\nimport { GreasedLineTools } from \"../../Misc/greasedLineTools\";\r\nimport {\r\n    GreasedLineBaseMesh,\r\n    GreasedLineRibbonAutoDirectionMode,\r\n    GreasedLineRibbonFacesMode,\r\n    GreasedLineRibbonPointsMode,\r\n    type GreasedLineMeshOptions,\r\n    type GreasedLineRibbonOptions,\r\n} from \"./greasedLineBaseMesh\";\r\n\r\nimport { type VertexData } from \"../mesh.vertexData\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/**\r\n * GreasedLineRibbonMesh\r\n * Use the GreasedLineBuilder.CreateGreasedLine function to create an instance of this class.\r\n */\r\nexport class GreasedLineRibbonMesh extends GreasedLineBaseMesh {\r\n    /**\r\n     * Default line width\r\n     */\r\n    public static DEFAULT_WIDTH = 0.1;\r\n\r\n    private static _RightHandedForwardReadOnlyQuaternion = /*#__PURE__*/ Quaternion.RotationAxis(Vector3.RightHandedForwardReadOnly, Math.PI / 2);\r\n    private static _LeftHandedForwardReadOnlyQuaternion = /*#__PURE__*/ Quaternion.RotationAxis(Vector3.LeftHandedForwardReadOnly, Math.PI / 2);\r\n    private static _LeftReadOnlyQuaternion = /*#__PURE__*/ Quaternion.RotationAxis(Vector3.LeftReadOnly, Math.PI / 2);\r\n\r\n    /**\r\n     * Direction which the line segment will be thickened if drawn on the XY plane\r\n     */\r\n    public static DIRECTION_XY = Vector3.LeftHandedForwardReadOnly; // doesn't matter in which handed system the scene operates\r\n    /**\r\n     * Direction which the line segment will be thickened if drawn on the XZ plane\r\n     */\r\n    public static DIRECTION_XZ = Vector3.UpReadOnly;\r\n    /**\r\n     * Direction which the line segment will be thickened if drawn on the YZ plane\r\n     */\r\n    public static DIRECTION_YZ = Vector3.LeftReadOnly;\r\n\r\n    private _paths: Vector3[][];\r\n    private _pathsOptions: { options: GreasedLineMeshOptions; pathCount: number }[];\r\n    private _vSegmentLengths: number[][];\r\n    private _uSegmentLengths: number[][];\r\n    private _vTotalLengths: number[];\r\n    private _uTotalLengths: number[];\r\n\r\n    private _counters: number[];\r\n    private _slopes: number[];\r\n    private _ribbonWidths: number[];\r\n\r\n    /**\r\n     * GreasedLineRibbonMesh\r\n     * @param name name of the mesh\r\n     * @param scene the scene\r\n     * @param _options mesh options\r\n     * @param _pathOptions used internaly when parsing a serialized GreasedLineRibbonMesh\r\n     */\r\n    constructor(\r\n        public override readonly name: string,\r\n        scene: Scene,\r\n        _options: GreasedLineMeshOptions,\r\n        _pathOptions?: { options: GreasedLineMeshOptions; pathCount: number }[]\r\n    ) {\r\n        super(name, scene, _options);\r\n\r\n        if (!_options.ribbonOptions) {\r\n            throw \"'GreasedLineMeshOptions.ribbonOptions' is not set.\";\r\n        }\r\n\r\n        this._paths = [];\r\n        this._counters = [];\r\n        this._slopes = [];\r\n        this._widths = _options.widths ?? [];\r\n        this._ribbonWidths = [];\r\n        this._pathsOptions = _pathOptions ?? [];\r\n\r\n        if (_options.points) {\r\n            this.addPoints(GreasedLineTools.ConvertPoints(_options.points), _options, !!_pathOptions);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds new points to the line. It doesn't rerenders the line if in lazy mode.\r\n     * @param points points table\r\n     * @param options mesh options\r\n     * @param hasPathOptions defaults to false\r\n     */\r\n    public override addPoints(points: number[][], options: GreasedLineMeshOptions, hasPathOptions = false) {\r\n        if (!options.ribbonOptions) {\r\n            throw \"addPoints() on GreasedLineRibbonMesh instance requires 'GreasedLineMeshOptions.ribbonOptions'.\";\r\n        }\r\n\r\n        if (!hasPathOptions) {\r\n            this._pathsOptions.push({ options, pathCount: points.length });\r\n        }\r\n\r\n        super.addPoints(points, options);\r\n    }\r\n\r\n    /**\r\n     * \"GreasedLineRibbonMesh\"\r\n     * @returns \"GreasedLineRibbonMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GreasedLineRibbonMesh\";\r\n    }\r\n\r\n    /**\r\n     * Return true if the line was created from two edge paths or one points path.\r\n     * In this case the line is always flat.\r\n     */\r\n    public get isFlatLine() {\r\n        return this._paths.length < 3;\r\n    }\r\n\r\n    /**\r\n     * Returns the slopes of the line at each point relative to the center of the line\r\n     */\r\n    get slopes() {\r\n        return this._slopes;\r\n    }\r\n\r\n    /**\r\n     * Set the slopes of the line at each point relative to the center of the line\r\n     */\r\n    set slopes(slopes: number[]) {\r\n        this._slopes = slopes;\r\n    }\r\n\r\n    protected _updateColorPointers() {\r\n        if (this._options.colorPointers) {\r\n            return;\r\n        }\r\n\r\n        let colorPointer = 0;\r\n        this._colorPointers = [];\r\n        for (let i = 0; i < this._pathsOptions.length; i++) {\r\n            const { options: pathOptions, pathCount } = this._pathsOptions[i];\r\n            const points = this._points[i];\r\n\r\n            if (pathOptions.ribbonOptions!.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_POINTS) {\r\n                for (let k = 0; k < pathCount; k++) {\r\n                    for (let j = 0; j < points.length; j += 3) {\r\n                        this._colorPointers.push(colorPointer);\r\n                        this._colorPointers.push(colorPointer++);\r\n                    }\r\n                }\r\n            } else {\r\n                for (let j = 0; j < points.length; j += 3) {\r\n                    for (let k = 0; k < pathCount; k++) {\r\n                        this._colorPointers.push(colorPointer);\r\n                    }\r\n                    colorPointer++;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _updateWidths(): void {\r\n        super._updateWidthsWithValue(1);\r\n    }\r\n\r\n    protected _setPoints(points: number[][], _options: GreasedLineMeshOptions) {\r\n        if (!this._options.ribbonOptions) {\r\n            throw \"No 'GreasedLineMeshOptions.ribbonOptions' provided.\";\r\n        }\r\n        this._points = points;\r\n        this._options.points = points;\r\n\r\n        this._initGreasedLine();\r\n\r\n        let indiceOffset = 0;\r\n        let directionPlanes: Vector3[] | undefined = undefined;\r\n        for (let i = 0, c = 0; i < this._pathsOptions.length; i++) {\r\n            const { options: pathOptions, pathCount } = this._pathsOptions[i];\r\n            const subPoints = points.slice(c, c + pathCount);\r\n            c += pathCount;\r\n            if (pathOptions.ribbonOptions?.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_PATHS) {\r\n                indiceOffset = this._preprocess(GreasedLineTools.ToVector3Array(subPoints) as Vector3[][], indiceOffset, pathOptions);\r\n            } else {\r\n                if (pathOptions.ribbonOptions?.directionsAutoMode === GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_NONE) {\r\n                    if (!pathOptions.ribbonOptions.directions) {\r\n                        throw \"In GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_NONE 'GreasedLineMeshOptions.ribbonOptions.directions' must be defined.\";\r\n                    }\r\n                    directionPlanes = GreasedLineRibbonMesh._GetDirectionPlanesFromDirectionsOption(subPoints.length, pathOptions.ribbonOptions.directions);\r\n                }\r\n                for (let idx = 0; idx < subPoints.length; idx++) {\r\n                    const p = subPoints[idx];\r\n\r\n                    const pathArray = GreasedLineRibbonMesh._ConvertToRibbonPath(\r\n                        p,\r\n                        pathOptions.ribbonOptions!,\r\n                        this._scene.useRightHandedSystem,\r\n                        directionPlanes ? directionPlanes[idx] : directionPlanes\r\n                    );\r\n                    indiceOffset = this._preprocess(pathArray, indiceOffset, pathOptions);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!this._lazy) {\r\n            this._createVertexBuffers();\r\n            !this.doNotSyncBoundingInfo && this.refreshBoundingInfo();\r\n        }\r\n    }\r\n\r\n    private static _GetDirectionPlanesFromDirectionsOption(count: number, directions: Vector3 | Vector3[]) {\r\n        if (Array.isArray(directions)) {\r\n            return directions;\r\n        }\r\n\r\n        return new Array(count).fill(directions) as Vector3[];\r\n    }\r\n\r\n    private static _CreateRibbonVertexData(pathArray: Vector3[][], options: GreasedLineMeshOptions) {\r\n        const numOfPaths = pathArray.length;\r\n        if (numOfPaths < 2) {\r\n            throw \"Minimum of two paths are required to create a GreasedLineRibbonMesh.\";\r\n        }\r\n\r\n        const positions = [];\r\n        const indices = [];\r\n\r\n        const path = pathArray[0];\r\n        for (let i = 0; i < path.length; i++) {\r\n            for (let pi = 0; pi < pathArray.length; pi++) {\r\n                const v = pathArray[pi][i];\r\n                positions.push(v.x, v.y, v.z);\r\n            }\r\n        }\r\n\r\n        const v: number[] = [1, 0, numOfPaths];\r\n        const doubleSided = options.ribbonOptions?.facesMode === GreasedLineRibbonFacesMode.FACES_MODE_DOUBLE_SIDED;\r\n\r\n        const closePath = options.ribbonOptions?.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_PATHS && options.ribbonOptions.closePath;\r\n        if (numOfPaths > 2) {\r\n            for (let i = 0; i < path.length - 1; i++) {\r\n                v[0] = 1 + numOfPaths * i;\r\n                v[1] = numOfPaths * i;\r\n                v[2] = (i + 1) * numOfPaths;\r\n                for (let pi = 0; pi < (numOfPaths - 1) * 2; pi++) {\r\n                    if (pi % 2 !== 0) {\r\n                        v[2] += 1;\r\n                    }\r\n                    if (pi % 2 === 0 && pi > 0) {\r\n                        v[0] += 1;\r\n                        v[1] += 1;\r\n                    }\r\n                    indices.push(v[1] + (pi % 2 !== 0 ? numOfPaths : 0), v[0], v[2]);\r\n                    if (doubleSided) {\r\n                        indices.push(v[0], v[1] + (pi % 2 !== 0 ? numOfPaths : 0), v[2]);\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            for (let i = 0; i < positions.length / 3 - 3; i += 2) {\r\n                indices.push(i, i + 1, i + 2);\r\n                indices.push(i + 2, i + 1, i + 3);\r\n                if (doubleSided) {\r\n                    indices.push(i + 1, i, i + 2);\r\n                    indices.push(i + 1, i + 2, i + 3);\r\n                }\r\n            }\r\n        }\r\n        if (closePath) {\r\n            let lastIndice = numOfPaths * (path.length - 1);\r\n            for (let pi = 0; pi < numOfPaths - 1; pi++) {\r\n                indices.push(lastIndice, pi + 1, pi);\r\n                indices.push(lastIndice + 1, pi + 1, lastIndice);\r\n                if (doubleSided) {\r\n                    indices.push(pi, pi + 1, lastIndice);\r\n                    indices.push(lastIndice, pi + 1, lastIndice + 1);\r\n                }\r\n                lastIndice++;\r\n            }\r\n        }\r\n\r\n        return {\r\n            positions,\r\n            indices,\r\n        };\r\n    }\r\n\r\n    private _preprocess(pathArray: Vector3[][], indiceOffset: number, options: GreasedLineMeshOptions) {\r\n        this._paths = pathArray;\r\n\r\n        const ribbonVertexData = GreasedLineRibbonMesh._CreateRibbonVertexData(pathArray, options);\r\n\r\n        const positions = ribbonVertexData.positions;\r\n\r\n        if (!this._options.widths) {\r\n            throw \"No 'GreasedLineMeshOptions.widths' table is specified.\";\r\n        }\r\n\r\n        const vertexPositions = Array.isArray(this._vertexPositions) ? this._vertexPositions : Array.from(this._vertexPositions);\r\n        this._vertexPositions = vertexPositions;\r\n        const uvs = Array.isArray(this._uvs) ? this._uvs : Array.from(this._uvs);\r\n        this._uvs = uvs;\r\n        const indices = Array.isArray(this._indices) ? this._indices : Array.from(this._indices);\r\n        this._indices = indices;\r\n\r\n        for (const p of positions) {\r\n            vertexPositions.push(p);\r\n        }\r\n\r\n        let pathArrayCopy = pathArray;\r\n        if (options.ribbonOptions?.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_PATHS && options.ribbonOptions.closePath) {\r\n            pathArrayCopy = [];\r\n            for (let i = 0; i < pathArray.length; i++) {\r\n                const pathCopy = pathArray[i].slice();\r\n                pathCopy.push(pathArray[i][0].clone());\r\n                pathArrayCopy.push(pathCopy);\r\n            }\r\n        }\r\n\r\n        this._calculateSegmentLengths(pathArrayCopy);\r\n\r\n        const pathArrayLength = pathArrayCopy.length;\r\n        const previousCounters = new Array(pathArrayLength).fill(0);\r\n        for (let i = 0; i < pathArrayCopy[0].length; i++) {\r\n            let v = 0;\r\n            for (let pi = 0; pi < pathArrayLength; pi++) {\r\n                const counter = previousCounters[pi] + this._vSegmentLengths[pi][i] / this._vTotalLengths[pi];\r\n                this._counters.push(counter);\r\n                uvs.push(counter, v);\r\n\r\n                previousCounters[pi] = counter;\r\n                v += this._uSegmentLengths[i][pi] / this._uTotalLengths[i];\r\n            }\r\n        }\r\n\r\n        for (let i = 0, c = 0; i < pathArrayCopy[0].length; i++) {\r\n            const widthLower = this._uSegmentLengths[i][0] / 2;\r\n            const widthUpper = this._uSegmentLengths[i][pathArrayLength - 2] / 2;\r\n            this._ribbonWidths.push(((this._widths[c++] ?? 1) - 1) * widthLower);\r\n            for (let pi = 0; pi < pathArrayLength - 2; pi++) {\r\n                this._ribbonWidths.push(0);\r\n            }\r\n            this._ribbonWidths.push(((this._widths[c++] ?? 1) - 1) * widthUpper);\r\n        }\r\n\r\n        const slopes =\r\n            options.ribbonOptions?.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_PATHS\r\n                ? new Array(pathArrayCopy[0].length * pathArrayCopy.length * 6).fill(0)\r\n                : GreasedLineRibbonMesh._CalculateSlopes(pathArrayCopy);\r\n        for (const s of slopes) {\r\n            this._slopes.push(s);\r\n        }\r\n\r\n        if (ribbonVertexData.indices) {\r\n            for (let i = 0; i < ribbonVertexData.indices.length; i++) {\r\n                indices.push(ribbonVertexData.indices[i] + indiceOffset);\r\n            }\r\n        }\r\n        indiceOffset += positions.length / 3;\r\n\r\n        return indiceOffset;\r\n    }\r\n\r\n    private static _ConvertToRibbonPath(points: number[], ribbonInfo: GreasedLineRibbonOptions, rightHandedSystem: boolean, directionPlane?: Vector3) {\r\n        if (ribbonInfo.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_POINTS && !ribbonInfo.width) {\r\n            throw \"'GreasedLineMeshOptions.ribbonOptiosn.width' must be specified in GreasedLineRibbonPointsMode.POINTS_MODE_POINTS.\";\r\n        }\r\n        const path1 = [];\r\n        const path2 = [];\r\n        if (ribbonInfo.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_POINTS) {\r\n            const width = ribbonInfo.width! / 2;\r\n            const pointVectors = GreasedLineTools.ToVector3Array(points) as Vector3[];\r\n            let direction: Nullable<Vector3> = null;\r\n            let fatDirection: Nullable<Vector3> = null;\r\n\r\n            if (ribbonInfo.directionsAutoMode === GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FROM_FIRST_SEGMENT) {\r\n                // set the direction plane from the first line segment for the whole line\r\n                directionPlane = GreasedLineRibbonMesh._GetDirectionFromPoints(pointVectors[0], pointVectors[1], null);\r\n            }\r\n\r\n            if (ribbonInfo.directionsAutoMode === GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FACE_TO && !(ribbonInfo.directions instanceof Vector3)) {\r\n                throw \"In GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FACE_TO 'GreasedLineMeshOptions.ribbonOptions.directions' must be a Vector3.\";\r\n            }\r\n\r\n            // Copy into the scratch vector instead of rebinding the slot. Assigning would make\r\n            // TmpVectors.Vector3[1] alias either the caller's vector or one of the DIRECTION_*\r\n            // constants (which are themselves Vector3.UpReadOnly / LeftReadOnly / ...), so the next\r\n            // write to that shared scratch slot anywhere in the engine would silently corrupt them.\r\n            TmpVectors.Vector3[1].copyFrom(ribbonInfo.directions instanceof Vector3 ? ribbonInfo.directions : GreasedLineRibbonMesh.DIRECTION_XZ);\r\n            for (let i = 0; i < pointVectors.length - (directionPlane ? 0 : 1); i++) {\r\n                const p1 = pointVectors[i];\r\n                const p2 = pointVectors[i + 1];\r\n\r\n                if (directionPlane) {\r\n                    direction = directionPlane;\r\n                } else if (ribbonInfo.directionsAutoMode === GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FACE_TO) {\r\n                    p2.subtractToRef(p1, TmpVectors.Vector3[0]);\r\n                    direction = Vector3.CrossToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2]).normalize();\r\n                } else if (ribbonInfo.directionsAutoMode === GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FROM_ALL_SEGMENTS) {\r\n                    direction = GreasedLineRibbonMesh._GetDirectionFromPoints(p1, p2, direction);\r\n                } else {\r\n                    // GreasedLineRibbonAutoDirectionMode.DIRECTION_ENHANCED\r\n                    const directionTemp = p2.subtract(p1);\r\n                    directionTemp.applyRotationQuaternionInPlace(\r\n                        directionTemp.x > directionTemp.y && directionTemp.x > directionTemp.z\r\n                            ? rightHandedSystem\r\n                                ? GreasedLineRibbonMesh._RightHandedForwardReadOnlyQuaternion\r\n                                : GreasedLineRibbonMesh._LeftHandedForwardReadOnlyQuaternion\r\n                            : GreasedLineRibbonMesh._LeftReadOnlyQuaternion\r\n                    );\r\n                    direction = directionTemp.normalize();\r\n                }\r\n\r\n                fatDirection = direction.multiplyByFloats(width, width, width);\r\n                path1.push(p1.add(fatDirection));\r\n                path2.push(p1.subtract(fatDirection));\r\n            }\r\n            if (!directionPlane) {\r\n                path1.push(pointVectors[pointVectors.length - 1].add(fatDirection!));\r\n                path2.push(pointVectors[pointVectors.length - 1].subtract(fatDirection!));\r\n            }\r\n        }\r\n        return [path1, path2];\r\n    }\r\n\r\n    private static _GetDirectionFromPoints(p1: Vector3, p2: Vector3, previousDirection: Nullable<Vector3>) {\r\n        // handle straight lines\r\n        if (p1.x === p2.x && (!previousDirection || previousDirection?.x === 1)) {\r\n            return GreasedLineRibbonMesh.DIRECTION_YZ;\r\n        }\r\n\r\n        if (p1.y === p2.y) {\r\n            return GreasedLineRibbonMesh.DIRECTION_XZ;\r\n        }\r\n\r\n        if (p1.z === p2.z) {\r\n            return GreasedLineRibbonMesh.DIRECTION_XY;\r\n        }\r\n\r\n        return GreasedLineRibbonMesh.DIRECTION_XZ;\r\n    }\r\n\r\n    /**\r\n     * Clones the GreasedLineRibbonMesh.\r\n     * @param name new line name\r\n     * @param newParent new parent node\r\n     * @returns cloned line\r\n     */\r\n    public override clone(name: string = `${this.name}-cloned`, newParent?: Nullable<Node>) {\r\n        const lineOptions = this._createLineOptions();\r\n        const deepCopiedLineOptions: any = {};\r\n        const pathOptionsCloned: any = [];\r\n        DeepCopier.DeepCopy(this._pathsOptions, pathOptionsCloned, undefined, undefined, true);\r\n        DeepCopier.DeepCopy(lineOptions, deepCopiedLineOptions, [\"instance\"], undefined, true);\r\n\r\n        const cloned = new GreasedLineRibbonMesh(name, this._scene, <GreasedLineMeshOptions>deepCopiedLineOptions, pathOptionsCloned);\r\n        if (newParent) {\r\n            cloned.parent = newParent;\r\n        }\r\n\r\n        cloned.material = this.material;\r\n\r\n        return cloned;\r\n    }\r\n\r\n    /**\r\n     * Serializes this GreasedLineRibbonMesh\r\n     * @param serializationObject object to write serialization to\r\n     */\r\n    public override serialize(serializationObject: any): void {\r\n        super.serialize(serializationObject);\r\n        serializationObject.type = this.getClassName();\r\n\r\n        serializationObject.lineOptions = this._createLineOptions();\r\n        serializationObject.pathsOptions = this._pathsOptions;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized GreasedLineRibbonMesh\r\n     * @param parsedMesh the serialized GreasedLineRibbonMesh\r\n     * @param scene the scene to create the GreasedLineRibbonMesh in\r\n     * @returns the created GreasedLineRibbonMesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): Mesh {\r\n        const lineOptions = <GreasedLineMeshOptions>parsedMesh.lineOptions;\r\n        const name = <string>parsedMesh.name;\r\n        const pathOptions = parsedMesh.pathOptions;\r\n        const result = new GreasedLineRibbonMesh(name, scene, lineOptions, pathOptions);\r\n        return result;\r\n    }\r\n\r\n    protected override _initGreasedLine() {\r\n        super._initGreasedLine();\r\n\r\n        this._paths = [];\r\n        this._counters = [];\r\n        this._slopes = [];\r\n        this._ribbonWidths = [];\r\n    }\r\n\r\n    private _calculateSegmentLengths(pathArray: Vector3[][]) {\r\n        const pathArrayLength = pathArray.length;\r\n        this._vSegmentLengths = new Array(pathArrayLength);\r\n        this._vTotalLengths = new Array(pathArrayLength);\r\n        let length: number;\r\n        for (let pi = 0; pi < pathArrayLength; pi++) {\r\n            const points = pathArray[pi];\r\n            this._vSegmentLengths[pi] = [0]; // first point has 0 distance\r\n            length = 0;\r\n            for (let i = 0; i < points.length - 1; i++) {\r\n                const l = Math.abs(points[i].subtract(points[i + 1]).lengthSquared()); // it's ok to have lengthSquared() here\r\n                length += l;\r\n                this._vSegmentLengths[pi].push(l);\r\n            }\r\n            this._vTotalLengths[pi] = length;\r\n        }\r\n\r\n        const positionsLength = pathArray[0].length;\r\n        this._uSegmentLengths = Array.from({ length: positionsLength }, () => []);\r\n        this._uTotalLengths = new Array(positionsLength);\r\n        const uLength = new Vector3();\r\n        for (let i = 0; i < positionsLength; i++) {\r\n            length = 0;\r\n            for (let pi = 1; pi < pathArrayLength; pi++) {\r\n                pathArray[pi][i].subtractToRef(pathArray[pi - 1][i], uLength);\r\n                const l = uLength.length(); // must be length()\r\n                length += l;\r\n                this._uSegmentLengths[i].push(l);\r\n            }\r\n            this._uTotalLengths[i] = length;\r\n        }\r\n    }\r\n\r\n    private static _CalculateSlopes(paths: Vector3[][]) {\r\n        const points1 = paths[0];\r\n        const points2 = paths.length === 2 ? paths[1] : paths[paths.length - 1];\r\n        const slopes: number[] = [];\r\n\r\n        const slope = new Vector3();\r\n        for (let i = 0; i < points1.length; i++) {\r\n            for (let pi = 0; pi < paths.length; pi++) {\r\n                if (pi === 0 || pi === paths.length - 1) {\r\n                    points1[i].subtract(points2[i]).normalizeToRef(slope);\r\n                    slopes.push(slope.x, slope.y, slope.z);\r\n                    slopes.push(-slope.x, -slope.y, -slope.z);\r\n                } else {\r\n                    slopes.push(0, 0, 0, 0, 0, 0);\r\n                }\r\n            }\r\n        }\r\n\r\n        return slopes;\r\n    }\r\n\r\n    protected override _createVertexBuffers(): VertexData {\r\n        this._uvs = this._options.uvs ?? this._uvs;\r\n        const vertexData = super._createVertexBuffers(this._options.ribbonOptions?.smoothShading);\r\n\r\n        const countersBuffer = new Buffer(this._engine, this._counters, this._updatable, 1);\r\n        this.setVerticesBuffer(countersBuffer.createVertexBuffer(\"grl_counters\", 0, 1));\r\n\r\n        const colorPointersBuffer = new Buffer(this._engine, this._colorPointers, this._updatable, 1);\r\n        this.setVerticesBuffer(colorPointersBuffer.createVertexBuffer(\"grl_colorPointers\", 0, 1));\r\n\r\n        const slopesBuffer = new Buffer(this._engine, this._slopes, this._updatable, 3);\r\n        this.setVerticesBuffer(slopesBuffer.createVertexBuffer(\"grl_slopes\", 0, 3));\r\n\r\n        const widthsBuffer = new Buffer(this._engine, this._ribbonWidths, this._updatable, 1);\r\n        this.setVerticesBuffer(widthsBuffer.createVertexBuffer(\"grl_widths\", 0, 1));\r\n        this._widthsBuffer = widthsBuffer;\r\n\r\n        return vertexData;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for greasedLineRibbonMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGreasedLineRibbonMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GreasedLineRibbonMeshParser = (parsedMesh: any, scene: Scene): Mesh => {\r\n        return GreasedLineRibbonMesh.Parse(parsedMesh, scene);\r\n    };\r\n}\r\n","import { StandardMaterial } from \"./../../Materials/standardMaterial.pure\";\r\nimport { PBRMaterial } from \"../../Materials/PBR/pbrMaterial.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { GreasedLineMesh } from \"../GreasedLine/greasedLineMesh.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { type Color3 } from \"../../Maths/math.color\";\r\nimport { GreasedLineSimpleMaterial } from \"../../Materials/GreasedLine/greasedLineSimpleMaterial\";\r\nimport { GreasedLineTools } from \"../../Misc/greasedLineTools\";\r\nimport { type GreasedLineMeshOptions, GreasedLineRibbonAutoDirectionMode, GreasedLineRibbonFacesMode, GreasedLineRibbonPointsMode } from \"../GreasedLine/greasedLineBaseMesh\";\r\nimport { GreasedLineRibbonMesh } from \"../GreasedLine/greasedLineRibbonMesh.pure\";\r\nimport { type GreasedLineMaterialOptions, GreasedLineMeshMaterialType } from \"../../Materials/GreasedLine/greasedLineMaterialInterfaces\";\r\nimport { GreasedLinePluginMaterial } from \"../../Materials/GreasedLine/greasedLinePluginMaterial.pure\";\r\nimport { GreasedLineMaterialDefaults } from \"../../Materials/GreasedLine/greasedLineMaterialDefaults\";\r\n\r\n/**\r\n * How are the colors distributed along the color table\r\n * {@link https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/greased_line#colors-and-colordistribution}\r\n */\r\nexport const enum GreasedLineMeshColorDistribution {\r\n    /**\r\n     * Do no modify the color table\r\n     */\r\n    COLOR_DISTRIBUTION_NONE = 0,\r\n    /**\r\n     * Repeat the colors until the color table is full\r\n     */\r\n    COLOR_DISTRIBUTION_REPEAT = 1,\r\n    /**\r\n     * Distribute the colors evenly through the color table\r\n     */\r\n    COLOR_DISTRIBUTION_EVEN = 2,\r\n    /**\r\n     * Put the colors to start of the color table a fill the rest with the default color\r\n     */\r\n    COLOR_DISTRIBUTION_START = 3,\r\n    /**\r\n     * Put the colors to the end of the color table and fill the rest with the default color\r\n     */\r\n    COLOR_DISTRIBUTION_END = 4,\r\n    /**\r\n     * Put the colors to start and to the end of the color table and fill the gap between with the default color\r\n     */\r\n    COLOR_DISTRIBUTION_START_END = 5,\r\n}\r\n\r\n/**\r\n * How are the widths distributed along the width table\r\n * {@link https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/param/greased_line#widths-and-widthdistribution}\r\n */\r\nexport const enum GreasedLineMeshWidthDistribution {\r\n    /**\r\n     * Do no modify the width table\r\n     */\r\n    WIDTH_DISTRIBUTION_NONE = 0,\r\n    /**\r\n     * Repeat the widths until the width table is full\r\n     */\r\n    WIDTH_DISTRIBUTION_REPEAT = 1,\r\n    /**\r\n     * Distribute the widths evenly through the width table\r\n     */\r\n    WIDTH_DISTRIBUTION_EVEN = 2,\r\n    /**\r\n     * Put the widths to start of the width table a fill the rest with the default width\r\n     */\r\n    WIDTH_DISTRIBUTION_START = 3,\r\n    /**\r\n     * Put the widths to the end of the width table and fill the rest with the default width\r\n     */\r\n    WIDTH_DISTRIBUTION_END = 4,\r\n    /**\r\n     * Put the widths to start and to the end of the width table and fill the gap between with the default width\r\n     */\r\n    WIDTH_DISTRIBUTION_START_END = 5,\r\n}\r\n\r\n/**\r\n * Material options for GreasedLineBuilder\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GreasedLineMaterialBuilderOptions extends GreasedLineMaterialOptions {\r\n    /**\r\n     * If set to true a new material will be created and a new material plugin will be attached\r\n     * to the material. The material will be set on the mesh. If the instance option is specified in the mesh options,\r\n     * no material will be created/assigned. Defaults to true.\r\n     */\r\n    createAndAssignMaterial?: boolean;\r\n    /**\r\n     * Distribution of the colors if the color table contains fewer entries than needed. Defaults to GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_START\r\n     * @see CompleteGreasedLineColorTable\r\n     */\r\n    colorDistribution?: GreasedLineMeshColorDistribution;\r\n}\r\n\r\n/**\r\n * Line mesh options for GreasedLineBuilder\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface GreasedLineMeshBuilderOptions extends GreasedLineMeshOptions {\r\n    /**\r\n     * Distribution of the widths if the width table contains fewer entries than needed. Defaults to GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_START\r\n     * @see CompleteGreasedLineWidthTable\r\n     */\r\n    widthDistribution?: GreasedLineMeshWidthDistribution;\r\n}\r\n\r\n/**\r\n * Builder functions for creating GreasedLineMeshes\r\n */\r\n\r\n/**\r\n * Creates a new @see GreasedLinePluginMaterial\r\n * @param name name of the material\r\n * @param options material options @see GreasedLineMaterialOptions\r\n * @param scene scene or null to use the last scene\r\n * @returns StandardMaterial or PBRMaterial with the @see GreasedLinePluginMaterial attached to it\r\n */\r\nexport function CreateGreasedLineMaterial(name: string, options: GreasedLineMaterialOptions, scene: Nullable<Scene>) {\r\n    scene = <Scene>(scene ?? EngineStore.LastCreatedScene);\r\n\r\n    let material;\r\n    switch (options.materialType) {\r\n        case GreasedLineMeshMaterialType.MATERIAL_TYPE_PBR:\r\n            material = new PBRMaterial(name, scene, options.forceGLSL);\r\n            new GreasedLinePluginMaterial(material, scene, options);\r\n            break;\r\n        case GreasedLineMeshMaterialType.MATERIAL_TYPE_SIMPLE:\r\n            material = new GreasedLineSimpleMaterial(name, scene, options);\r\n            break;\r\n        default:\r\n            material = new StandardMaterial(name, scene, options.forceGLSL);\r\n            new GreasedLinePluginMaterial(material, scene, options);\r\n            break;\r\n    }\r\n\r\n    return material;\r\n}\r\n\r\n/**\r\n * Creates a GreasedLine mesh\r\n * @param name name of the mesh\r\n * @param options options for the mesh\r\n * @param materialOptions material options for the mesh\r\n * @param scene scene where the mesh will be created\r\n * @returns instance of GreasedLineMesh\r\n */\r\nexport function CreateGreasedLine(name: string, options: GreasedLineMeshBuilderOptions, materialOptions?: Nullable<GreasedLineMaterialBuilderOptions>, scene?: Nullable<Scene>) {\r\n    scene = <Scene>(scene ?? EngineStore.LastCreatedScene);\r\n\r\n    let instance;\r\n    const allPoints = GreasedLineTools.ConvertPoints(options.points, options.pointsOptions);\r\n\r\n    options.widthDistribution = options.widthDistribution ?? GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_START;\r\n    if (options.ribbonOptions) {\r\n        options.ribbonOptions.facesMode = options.ribbonOptions.facesMode ?? GreasedLineRibbonFacesMode.FACES_MODE_SINGLE_SIDED_NO_BACKFACE_CULLING;\r\n        options.ribbonOptions.pointsMode = options.ribbonOptions.pointsMode ?? GreasedLineRibbonPointsMode.POINTS_MODE_POINTS;\r\n        options.ribbonOptions.directionsAutoMode =\r\n            options.ribbonOptions.directionsAutoMode ??\r\n            (options.ribbonOptions.directions ? GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_NONE : GreasedLineRibbonAutoDirectionMode.AUTO_DIRECTIONS_FROM_FIRST_SEGMENT);\r\n    }\r\n\r\n    materialOptions = materialOptions ?? {\r\n        color: GreasedLineMaterialDefaults.DEFAULT_COLOR,\r\n    };\r\n    materialOptions.createAndAssignMaterial = materialOptions.createAndAssignMaterial ?? true;\r\n    materialOptions.colorDistribution = materialOptions?.colorDistribution ?? GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_START;\r\n    materialOptions.materialType = materialOptions.materialType ?? GreasedLineMeshMaterialType.MATERIAL_TYPE_STANDARD;\r\n\r\n    const pointsCount = GetPointsCount(allPoints);\r\n    const widths = CompleteGreasedLineWidthTable(pointsCount, options.widths ?? [], options.widthDistribution);\r\n\r\n    const colors = materialOptions?.colors\r\n        ? CompleteGreasedLineColorTable(pointsCount, materialOptions.colors, materialOptions.colorDistribution, materialOptions.color ?? GreasedLineMaterialDefaults.DEFAULT_COLOR)\r\n        : undefined;\r\n\r\n    // create new mesh if instance is not defined\r\n    const initialGreasedLineOptions: GreasedLineMeshOptions = {\r\n        points: allPoints,\r\n        updatable: options.updatable,\r\n        widths,\r\n        lazy: options.lazy,\r\n        ribbonOptions: options.ribbonOptions,\r\n        uvs: options.uvs,\r\n        colorPointers: options.colorPointers,\r\n    };\r\n\r\n    if (initialGreasedLineOptions.ribbonOptions) {\r\n        if (initialGreasedLineOptions.ribbonOptions.pointsMode === GreasedLineRibbonPointsMode.POINTS_MODE_POINTS) {\r\n            initialGreasedLineOptions.ribbonOptions.width = materialOptions.width ?? initialGreasedLineOptions.ribbonOptions.width ?? GreasedLineMaterialDefaults.DEFAULT_WIDTH;\r\n        }\r\n    }\r\n\r\n    if (!options.instance) {\r\n        instance = initialGreasedLineOptions.ribbonOptions\r\n            ? new GreasedLineRibbonMesh(name, scene, initialGreasedLineOptions)\r\n            : new GreasedLineMesh(name, scene, initialGreasedLineOptions);\r\n\r\n        if (materialOptions) {\r\n            const initialMaterialOptions: GreasedLineMaterialOptions = {\r\n                materialType: materialOptions.materialType,\r\n                dashCount: materialOptions.dashCount,\r\n                dashOffset: materialOptions.dashOffset,\r\n                dashRatio: materialOptions.dashRatio,\r\n                resolution: materialOptions.resolution,\r\n                sizeAttenuation: materialOptions.sizeAttenuation,\r\n                useColors: materialOptions.useColors,\r\n                useDash: materialOptions.useDash,\r\n                visibility: materialOptions.visibility,\r\n                width: materialOptions.width,\r\n                color: materialOptions.color,\r\n                colorMode: materialOptions.colorMode,\r\n                colorsSampling: materialOptions.colorsSampling,\r\n                colorDistributionType: materialOptions.colorDistributionType,\r\n                colors,\r\n                cameraFacing: !options.ribbonOptions,\r\n                colorsTexture: materialOptions.colorsTexture,\r\n            };\r\n\r\n            if (materialOptions.createAndAssignMaterial) {\r\n                const material = CreateGreasedLineMaterial(name, initialMaterialOptions, scene);\r\n                instance.material = material;\r\n\r\n                if (options.ribbonOptions?.facesMode === GreasedLineRibbonFacesMode.FACES_MODE_SINGLE_SIDED_NO_BACKFACE_CULLING) {\r\n                    material.backFaceCulling = false;\r\n                }\r\n            }\r\n        }\r\n    } else {\r\n        // update the data on the mesh instance\r\n        instance = options.instance;\r\n        if (instance instanceof GreasedLineRibbonMesh) {\r\n            instance.addPoints(allPoints, initialGreasedLineOptions);\r\n        } else {\r\n            // add widths\r\n            const currentWidths = instance.widths;\r\n            if (currentWidths) {\r\n                const newWidths = currentWidths.slice();\r\n                for (const w of widths) {\r\n                    newWidths.push(w);\r\n                }\r\n                instance.widths = newWidths;\r\n            } else {\r\n                instance.widths = widths;\r\n            }\r\n\r\n            instance.addPoints(allPoints);\r\n\r\n            // add UVs\r\n            if (options.uvs) {\r\n                const currentUVs = instance.uvs;\r\n                if (currentUVs) {\r\n                    const newUVs = new Float32Array(currentUVs.length + options.uvs.length);\r\n                    newUVs.set(currentUVs, 0);\r\n                    newUVs.set(options.uvs, currentUVs.length);\r\n                    instance.uvs = newUVs;\r\n                } else {\r\n                    instance.uvs = options.uvs;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // add colors\r\n    // it will merge if any colors already on the instance\r\n    if (colors && options.instance) {\r\n        if (options.instance.greasedLineMaterial) {\r\n            const currentColors = options.instance.greasedLineMaterial.colors;\r\n            if (currentColors) {\r\n                const newColors = currentColors.concat(colors);\r\n                options.instance.greasedLineMaterial.setColors(newColors, instance.isLazy());\r\n            }\r\n        }\r\n    }\r\n\r\n    return instance;\r\n}\r\n\r\n/**\r\n * Counts the number of points\r\n * @param allPoints Array of points [[x, y, z], [x, y, z], ...] or Array of points [x, y, z, x, y, z, ...]\r\n * @returns total number of points\r\n */\r\nexport function GetPointsCount(allPoints: number[][]) {\r\n    let pointCount = 0;\r\n    for (const points of allPoints) {\r\n        pointCount += points.length / 3;\r\n    }\r\n    return pointCount;\r\n}\r\n\r\n/**\r\n * Completes the width table/fills the missing entries. It means it creates a width entry for every point of the line mesh.\r\n * You can provide more points the widths when creating the mesh. This function will fill the empty entries.\r\n * The algorithm used to fill the empty entries can be\r\n * GreasedLineMeshWidthDistribution.REPEAT - the width table will be repeatedly copied to the empty values [wL, wU] = [wL, wU, wL, wU, wL, wU, wL, wU, ...]\r\n * GreasedLineMeshWidthDistribution.EVEN - the width table will be evenly copied to the empty values [wL, wU] = [wL, wL, wL, wL, wU, wU, wU, wU]\r\n * GreasedLineMeshWidthDistribution.START - the width table will be copied at the start of the empty values\r\n * and rest will be filled width the default width upper and default width lower values [wU, wL] = [wL, wU, dwL, dwU, dwL, dwU, dwL, dwU]\r\n * GreasedLineMeshWidthDistribution.END - the width table will be copied at the end of the empty values\r\n * and rest will be filled width the default values [wL, wU] = [wL, wU, dwL, dwU, dwL, dwU, wL, wU]\r\n * @param pointCount number of points of the line mesh\r\n * @param widths array of widths [widhtLower, widthUpper, widthLower, widthUpper ...]. Two widths (lower/upper) per point.\r\n * @param widthsDistribution how to distribute widths if the widths array has fewer entries than pointCount\r\n * @param defaultWidthUpper the default value which will be used to fill empty width entries - upper width\r\n * @param defaultWidthLower the default value which will be used to fill empty width entries - lower width\r\n * @returns completed width table.\r\n */\r\nexport function CompleteGreasedLineWidthTable(\r\n    pointCount: number,\r\n    widths: number[],\r\n    widthsDistribution: GreasedLineMeshWidthDistribution,\r\n    defaultWidthUpper = 1,\r\n    defaultWidthLower = 1\r\n): number[] {\r\n    const missingCount = pointCount - widths.length / 2;\r\n\r\n    const widthsData: number[] = [];\r\n    if (missingCount < 0) {\r\n        return widths.slice(0, pointCount * 2);\r\n    }\r\n\r\n    // is the width table shorter than the point table?\r\n    if (missingCount > 0) {\r\n        if (widths.length % 2 != 0) {\r\n            widths.push(defaultWidthUpper);\r\n        }\r\n        // it is, fill in the missing elements\r\n        if (widthsDistribution === GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_START_END) {\r\n            const halfCount = Math.floor(widths.length / 2);\r\n\r\n            // start sector\r\n            for (let i = 0, j = 0; i < halfCount - 1; i++) {\r\n                widthsData.push(widths[j++]);\r\n                widthsData.push(widths[j++]);\r\n            }\r\n\r\n            // middle sector\r\n            const widthL = widths[halfCount / 2];\r\n            const widthU = widths[halfCount / 2 + 1];\r\n            for (let i = 0; i < missingCount; i++) {\r\n                widthsData.push(widthU);\r\n                widthsData.push(widthL);\r\n            }\r\n\r\n            // end sector\r\n            for (let i = halfCount; i < widths.length; i += 2) {\r\n                widthsData.push(widths[i]);\r\n                widthsData.push(widths[i + 1]);\r\n            }\r\n        } else if (widthsDistribution === GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_START) {\r\n            // start sector\r\n            for (let i = 0; i < widths.length; i += 2) {\r\n                widthsData.push(widths[i]);\r\n                widthsData.push(widths[i + 1]);\r\n            }\r\n\r\n            // end sector\r\n            for (let i = 0; i < missingCount; i++) {\r\n                widthsData.push(defaultWidthUpper);\r\n                widthsData.push(defaultWidthLower);\r\n            }\r\n        } else if (widthsDistribution === GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_END) {\r\n            // start sector\r\n            for (let i = 0; i < missingCount; i++) {\r\n                widthsData.push(defaultWidthUpper);\r\n                widthsData.push(defaultWidthLower);\r\n            }\r\n\r\n            // end sector\r\n            for (let i = 0; i < widths.length; i += 2) {\r\n                widthsData.push(widths[i]);\r\n                widthsData.push(widths[i + 1]);\r\n            }\r\n        } else if (widthsDistribution === GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_REPEAT) {\r\n            let i = 0;\r\n            for (let x = 0; x < pointCount; x++) {\r\n                widthsData.push(widths[i++]);\r\n                widthsData.push(widths[i++]);\r\n\r\n                if (i === widths.length) {\r\n                    i = 0;\r\n                }\r\n            }\r\n        } else if (widthsDistribution === GreasedLineMeshWidthDistribution.WIDTH_DISTRIBUTION_EVEN) {\r\n            let j = 0;\r\n            const widthsectorLength = widths.length / ((pointCount - 1) * 2);\r\n            for (let x = 0; x < pointCount; x++) {\r\n                const i = Math.floor(j);\r\n\r\n                widthsData.push(widths[i]);\r\n                widthsData.push(widths[i + 1]);\r\n\r\n                j += widthsectorLength;\r\n            }\r\n        }\r\n    } else {\r\n        for (let i = 0; i < widths.length; i++) {\r\n            widthsData.push(widths[i]);\r\n        }\r\n    }\r\n\r\n    return widthsData;\r\n}\r\n\r\n/**\r\n * Completes the color table/fill the missing color entries. It means it creates a color entry for every point of the line mesh.\r\n * You can provide more points the colors when creating the mesh. This function will fill the empty entries.\r\n * The algorithm used to fill the empty entries can be\r\n * GreasedLineMesColorhDistribution.REPEAT - the color table will be repeatedly copied to the empty values [c1, c2] = [c1, c2, c1, c2, c1, c2, c1, c2]\r\n * GreasedLineMesColorhDistribution.EVEN - the color table will be evenly copied to the empty values [c1, c2] = [c1, c1, c1, c1, c2, c2, c2, c2]\r\n * GreasedLineMesColorhDistribution.START - the color table will be copied at the start of the empty values\r\n * and rest will be filled color the default color value [c1, c2] = [c1, c2, dc, dc, dc, dc, dc, dc]\r\n * GreasedLineMesColorhDistribution.START_END - the color table will be copied at the start and the end of the empty values\r\n * and rest will be filled color the default color value [c1, c2] = [c1, c2, dc, dc, dc, dc, c1, c2]\r\n * @param pointCount number of points of the line mesh\r\n * @param colors array of Color3 for the color table\r\n * @param colorDistribution how to distribute colors if the colors array has fewer entries than pointCount\r\n * @param defaultColor default color to be used to fill empty entries in the color table\r\n * @returns completed array of Color3s\r\n */\r\nexport function CompleteGreasedLineColorTable(pointCount: number, colors: Color3[], colorDistribution: GreasedLineMeshColorDistribution, defaultColor: Color3): Color3[] {\r\n    pointCount = Math.max(colors.length, pointCount);\r\n    const missingCount = pointCount - colors.length;\r\n    if (missingCount < 0) {\r\n        return colors.slice(0, pointCount);\r\n    }\r\n\r\n    const colorsData: Color3[] = [];\r\n    // is the color table shorter than the point table?\r\n    if (missingCount > 0) {\r\n        // it is, fill in the missing elements\r\n        if (colorDistribution === GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_START_END) {\r\n            const halfCount = Math.floor(colors.length / 2);\r\n\r\n            // start sector\r\n            for (let i = 0; i < halfCount; i++) {\r\n                colorsData.push(colors[i]);\r\n            }\r\n\r\n            // middle sector\r\n            for (let i = 0; i < missingCount - 1; i++) {\r\n                colorsData.push(defaultColor);\r\n            }\r\n\r\n            // end sector\r\n            for (let i = halfCount; i < colors.length; i++) {\r\n                colorsData.push(colors[i]);\r\n            }\r\n        } else if (colorDistribution === GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_START) {\r\n            // start sector\r\n            for (let i = 0; i < colors.length; i++) {\r\n                colorsData.push(colors[i]);\r\n            }\r\n\r\n            // end sector\r\n            for (let i = 0; i < missingCount; i++) {\r\n                colorsData.push(defaultColor);\r\n            }\r\n        } else if (colorDistribution === GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_END) {\r\n            // start sector\r\n            for (let i = 0; i < missingCount - 1; i++) {\r\n                colorsData.push(defaultColor);\r\n            }\r\n\r\n            // end sector\r\n            for (let i = 0; i < colors.length; i++) {\r\n                colorsData.push(colors[i]);\r\n            }\r\n        } else if (colorDistribution === GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_REPEAT) {\r\n            let i = 0;\r\n            for (let x = 0; x < pointCount; x++) {\r\n                colorsData.push(colors[i]);\r\n\r\n                i++;\r\n\r\n                if (i === colors.length) {\r\n                    i = 0;\r\n                }\r\n            }\r\n        } else if (colorDistribution === GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_EVEN) {\r\n            let j = 0;\r\n            const colorSectorLength = colors.length / (pointCount - 1);\r\n            for (let x = 0; x < pointCount - 1; x++) {\r\n                const i = Math.floor(j);\r\n\r\n                colorsData.push(colors[i]);\r\n\r\n                j += colorSectorLength;\r\n            }\r\n        } else if (colorDistribution === GreasedLineMeshColorDistribution.COLOR_DISTRIBUTION_NONE) {\r\n            for (let i = 0; i < colors.length; i++) {\r\n                colorsData.push(colors[i]);\r\n            }\r\n        }\r\n    } else {\r\n        for (let i = 0; i < pointCount; i++) {\r\n            colorsData.push(colors[i]);\r\n        }\r\n    }\r\n\r\n    return colorsData;\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/**\r\n * This file is only for internal use only and should not be used in your code\r\n */\r\n\r\nimport { IsWindowObjectExist } from \"./domManagement\";\r\nimport { Tools } from \"./tools.pure\";\r\n\r\nlet UniqueResolveID = 0;\r\n\r\n/**\r\n * Load an asynchronous script (identified by an url) in a module way. When the url returns, the\r\n * content of this file is added into a new script element, attached to the DOM (body element)\r\n * @param scriptUrl defines the url of the script to load\r\n * @param scriptId defines the id of the script element\r\n * @returns a promise request object\r\n * It is up to the caller to provide a script that will do the import and prepare a \"returnedValue\" variable\r\n * @internal DO NOT USE outside of Babylon.js core\r\n */\r\nexport async function _LoadScriptModuleAsync(scriptUrl: string, scriptId?: string): Promise<any> {\r\n    return await new Promise((resolve, reject) => {\r\n        // Need a relay\r\n        let windowAsAny: any;\r\n        let windowString: string;\r\n\r\n        if (IsWindowObjectExist()) {\r\n            windowAsAny = window;\r\n            windowString = \"window\";\r\n        } else if (typeof self !== \"undefined\") {\r\n            windowAsAny = self;\r\n            windowString = \"self\";\r\n        } else {\r\n            reject(new Error(\"Cannot load script module outside of a window or a worker\"));\r\n            return;\r\n        }\r\n\r\n        if (!windowAsAny._LoadScriptModuleResolve) {\r\n            windowAsAny._LoadScriptModuleResolve = {};\r\n        }\r\n        windowAsAny._LoadScriptModuleResolve[UniqueResolveID] = resolve;\r\n\r\n        scriptUrl += `\r\n            ${windowString}._LoadScriptModuleResolve[${UniqueResolveID}](returnedValue);\r\n            ${windowString}._LoadScriptModuleResolve[${UniqueResolveID}] = undefined;\r\n        `;\r\n        UniqueResolveID++;\r\n\r\n        Tools.LoadScript(\r\n            scriptUrl,\r\n            undefined,\r\n            (message, exception) => {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                reject(exception || new Error(message));\r\n            },\r\n            scriptId,\r\n            true\r\n        );\r\n    });\r\n}\r\n","import { Mesh } from \"./mesh.pure\";\r\nimport { type IDisposable, type Scene } from \"core/scene\";\r\nimport { type IVertexDataLike, VertexData } from \"./mesh.vertexData\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { MultiMaterial } from \"core/Materials/multiMaterial.pure\";\r\nimport { SubMesh } from \"./subMesh\";\r\nimport { type Material } from \"core/Materials/material\";\r\nimport { _LoadScriptModuleAsync } from \"core/Misc/tools.internals\";\r\nimport { type FloatArray, type Nullable } from \"core/types\";\r\nimport { type Matrix, Vector3 } from \"core/Maths/math.vector.pure\";\r\n\r\n/**\r\n * Main manifold library\r\n */\r\nlet Manifold: any;\r\n\r\n/**\r\n * Promise to wait for the manifold library to be ready\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nlet ManifoldPromise: Promise<{ Manifold: any; Mesh: any }>;\r\n\r\n/**\r\n * Manifold mesh\r\n */\r\nlet ManifoldMesh: any;\r\n\r\n/**\r\n * First ID to use for materials indexing\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nlet FirstID: number;\r\n\r\n/**\r\n * Interface to customize the Manifold library import\r\n */\r\nexport interface ICSG2Options {\r\n    /**\r\n     * Custom manifold URL\r\n     */\r\n    manifoldUrl?: string;\r\n    /**\r\n     * Custom manifold instance\r\n     */\r\n    manifoldInstance: any;\r\n    /**\r\n     * Custom manifold mesh instance\r\n     */\r\n    manifoldMeshInstance: any;\r\n}\r\n\r\n/**\r\n * Interface to customize the mesh rebuild options\r\n */\r\nexport interface IMeshRebuildOptions {\r\n    /**\r\n     * Rebuild normals\r\n     */\r\n    rebuildNormals?: boolean;\r\n    /**\r\n     * True to center the mesh on 0,0,0\r\n     */\r\n    centerMesh?: boolean;\r\n    /**\r\n     * Defines a material to use for that mesh. When not defined the system will either reuse the one from the source or create a multimaterial if several materials were involved\r\n     */\r\n    materialToUse?: Material;\r\n}\r\n\r\n/**\r\n * Interface to customize the vertex data rebuild options\r\n */\r\nexport interface IVertexDataRebuildOptions {\r\n    /**\r\n     * Rebuild normals\r\n     */\r\n    rebuildNormals?: boolean;\r\n}\r\n\r\ninterface IManifoldMesh {\r\n    numProp: number;\r\n    vertProperties: Float32Array;\r\n    triVerts: Uint32Array;\r\n    runIndex: Uint32Array;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    runOriginalID: Uint32Array;\r\n    numRun: number;\r\n}\r\n\r\ninterface IManifoldVertexComponent {\r\n    stride: number;\r\n    kind: string;\r\n    data?: FloatArray;\r\n}\r\n\r\n/**\r\n * Wrapper around the Manifold library\r\n * https://manifoldcad.org/\r\n * Use this class to perform fast boolean operations on meshes\r\n * @see [basic operations](https://playground.babylonjs.com/#IW43EB#15)\r\n * @see [skull vs box](https://playground.babylonjs.com/#JUKXQD#6218)\r\n * @see [skull vs vertex data](https://playground.babylonjs.com/#JUKXQD#6219)\r\n */\r\nexport class CSG2 implements IDisposable {\r\n    private _manifold: any;\r\n    private _numProp: number;\r\n    private _vertexStructure: IManifoldVertexComponent[];\r\n\r\n    /**\r\n     * Return the size of a vertex (at least 3 for the position)\r\n     */\r\n    public get numProp() {\r\n        return this._numProp;\r\n    }\r\n\r\n    private constructor(manifold: any, numProp: number, vertexStructure: IManifoldVertexComponent[]) {\r\n        this._manifold = manifold;\r\n        this._numProp = numProp;\r\n        this._vertexStructure = vertexStructure;\r\n    }\r\n\r\n    private _process(operation: \"difference\" | \"intersection\" | \"union\", csg: CSG2) {\r\n        if (this.numProp !== csg.numProp) {\r\n            throw new Error(\"CSG must be used with geometries having the same number of properties\");\r\n        }\r\n        return new CSG2(Manifold[operation](this._manifold, csg._manifold), this.numProp, this._vertexStructure);\r\n    }\r\n\r\n    /**\r\n     * Run a difference operation between two CSG\r\n     * @param csg defines the CSG to use to create the difference\r\n     * @returns a new csg\r\n     */\r\n    public subtract(csg: CSG2) {\r\n        return this._process(\"difference\", csg);\r\n    }\r\n\r\n    /**\r\n     * Run an intersection operation between two CSG\r\n     * @param csg defines the CSG to use to create the intersection\r\n     * @returns a new csg\r\n     */\r\n    public intersect(csg: CSG2) {\r\n        return this._process(\"intersection\", csg);\r\n    }\r\n\r\n    /**\r\n     * Run an union operation between two CSG\r\n     * @param csg defines the CSG to use to create the union\r\n     * @returns a new csg\r\n     */\r\n    public add(csg: CSG2) {\r\n        return this._process(\"union\", csg);\r\n    }\r\n\r\n    /**\r\n     * Print debug information about the CSG\r\n     */\r\n    public printDebug() {\r\n        Logger.Log(\"Genus:\" + this._manifold.genus());\r\n        Logger.Log(\"Volume:\" + this._manifold.volume());\r\n        Logger.Log(\"surface area:\" + this._manifold.surfaceArea());\r\n    }\r\n\r\n    /**\r\n     * Generate a vertex data from the CSG\r\n     * @param options defines the options to use to rebuild the vertex data\r\n     * @returns a new vertex data\r\n     */\r\n    public toVertexData(options?: Partial<IVertexDataRebuildOptions>): VertexData {\r\n        const localOptions = {\r\n            rebuildNormals: false,\r\n            ...options,\r\n        };\r\n        const vertexData = new VertexData();\r\n        const normalComponent = this._vertexStructure.find((c) => c.kind === VertexBuffer.NormalKind);\r\n        const manifoldMesh: IManifoldMesh = this._manifold.getMesh(localOptions.rebuildNormals && normalComponent ? [3, 4, 5] : undefined);\r\n\r\n        vertexData.indices = manifoldMesh.triVerts.length > 65535 ? new Uint32Array(manifoldMesh.triVerts) : new Uint16Array(manifoldMesh.triVerts);\r\n\r\n        for (let i = 0; i < manifoldMesh.triVerts.length; i += 3) {\r\n            vertexData.indices[i] = manifoldMesh.triVerts[i + 2];\r\n            vertexData.indices[i + 1] = manifoldMesh.triVerts[i + 1];\r\n            vertexData.indices[i + 2] = manifoldMesh.triVerts[i];\r\n        }\r\n\r\n        const vertexCount = manifoldMesh.vertProperties.length / manifoldMesh.numProp;\r\n\r\n        // Attributes\r\n        let offset = 0;\r\n        for (let componentIndex = 0; componentIndex < this._vertexStructure.length; componentIndex++) {\r\n            const component = this._vertexStructure[componentIndex];\r\n\r\n            const data = new Float32Array(vertexCount * component.stride);\r\n            for (let i = 0; i < vertexCount; i++) {\r\n                for (let strideIndex = 0; strideIndex < component.stride; strideIndex++) {\r\n                    data[i * component.stride + strideIndex] = manifoldMesh.vertProperties[i * manifoldMesh.numProp + offset + strideIndex];\r\n                }\r\n            }\r\n            vertexData.set(data, component.kind);\r\n            offset += component.stride;\r\n        }\r\n\r\n        // Rebuild mesh from vertex data\r\n        return vertexData;\r\n    }\r\n\r\n    /**\r\n     * Generate a mesh from the CSG\r\n     * @param name defines the name of the mesh\r\n     * @param scene defines the scene to use to create the mesh\r\n     * @param options defines the options to use to rebuild the mesh\r\n     * @returns a new Mesh\r\n     */\r\n    public toMesh(name: string, scene?: Scene, options?: Partial<IMeshRebuildOptions>): Mesh {\r\n        const localOptions = {\r\n            rebuildNormals: false,\r\n            centerMesh: true,\r\n            ...options,\r\n        };\r\n        const vertexData = this.toVertexData({ rebuildNormals: localOptions.rebuildNormals });\r\n        const normalComponent = this._vertexStructure.find((c) => c.kind === VertexBuffer.NormalKind);\r\n        const manifoldMesh: IManifoldMesh = this._manifold.getMesh(localOptions.rebuildNormals && normalComponent ? [3, 4, 5] : undefined);\r\n        const vertexCount = manifoldMesh.vertProperties.length / manifoldMesh.numProp;\r\n\r\n        // Rebuild mesh from vertex data\r\n        const output = new Mesh(name, scene);\r\n        vertexData.applyToMesh(output);\r\n\r\n        if (!vertexCount) {\r\n            throw new Error(\"Unable to build a mesh. Manifold has 0 vertex\");\r\n        }\r\n\r\n        // Center mesh\r\n        if (localOptions.centerMesh) {\r\n            const extents = output.getBoundingInfo().boundingSphere.center;\r\n            output.position.set(-extents.x, -extents.y, -extents.z);\r\n            output.bakeCurrentTransformIntoVertices();\r\n        }\r\n\r\n        // Submeshes\r\n        let id = manifoldMesh.runOriginalID[0];\r\n        let start = manifoldMesh.runIndex[0];\r\n        let materialIndex = 0;\r\n        const materials: Material[] = [];\r\n        scene = output.getScene();\r\n        for (let run = 0; run < manifoldMesh.numRun; ++run) {\r\n            const nextID = manifoldMesh.runOriginalID[run + 1];\r\n            if (nextID !== id) {\r\n                const end = manifoldMesh.runIndex[run + 1];\r\n                new SubMesh(materialIndex, 0, vertexCount, start, end - start, output);\r\n                materials.push(scene.getMaterialByUniqueID(id - FirstID) || scene.defaultMaterial);\r\n                id = nextID;\r\n                start = end;\r\n                materialIndex++;\r\n            }\r\n        }\r\n\r\n        if (localOptions.materialToUse) {\r\n            output.material = localOptions.materialToUse;\r\n        } else {\r\n            if (materials.length > 1) {\r\n                const multiMaterial = new MultiMaterial(name, scene);\r\n                multiMaterial.subMaterials = materials;\r\n                output.material = multiMaterial;\r\n            } else {\r\n                if (output.subMeshes.length > 1) {\r\n                    // Remove the submeshes as they are not needed\r\n                    output._createGlobalSubMesh(true);\r\n                }\r\n                output.material = materials[0];\r\n            }\r\n        }\r\n\r\n        return output;\r\n    }\r\n\r\n    /**\r\n     * Dispose the CSG resources\r\n     */\r\n    public dispose() {\r\n        if (this._manifold) {\r\n            this._manifold.delete();\r\n            this._manifold = null;\r\n        }\r\n    }\r\n\r\n    private static _ProcessData(\r\n        vertexCount: number,\r\n        triVerts: Uint32Array,\r\n        structure: IManifoldVertexComponent[],\r\n        numProp: number,\r\n        runIndex?: Uint32Array,\r\n        runOriginalID?: Uint32Array\r\n    ) {\r\n        const vertProperties = new Float32Array(vertexCount * structure.reduce((acc, cur) => acc + cur.stride, 0));\r\n\r\n        for (let i = 0; i < vertexCount; i++) {\r\n            let offset = 0;\r\n            for (let idx = 0; idx < structure.length; idx++) {\r\n                const component = structure[idx];\r\n\r\n                for (let strideIndex = 0; strideIndex < component.stride; strideIndex++) {\r\n                    vertProperties[i * numProp + offset + strideIndex] = component.data![i * component.stride + strideIndex];\r\n                }\r\n                offset += component.stride;\r\n            }\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        const manifoldMesh = new ManifoldMesh({ numProp: numProp, vertProperties, triVerts, runIndex, runOriginalID });\r\n        manifoldMesh.merge();\r\n\r\n        let returnValue: CSG2;\r\n        try {\r\n            returnValue = new CSG2(new Manifold(manifoldMesh), numProp, structure);\r\n        } catch (e) {\r\n            throw new Error(\"Error while creating the CSG: \" + e.message, { cause: e });\r\n        }\r\n\r\n        return returnValue;\r\n    }\r\n\r\n    private static _Construct(data: IVertexDataLike, worldMatrix: Nullable<Matrix>, runIndex?: Uint32Array, runOriginalID?: Uint32Array, invertWinding = false) {\r\n        // Create the MeshGL for I/O with Manifold library.\r\n        const triVerts = new Uint32Array(data.indices!.length);\r\n\r\n        if (invertWinding) {\r\n            // The mesh winding is reflected relative to Babylon's default winding for the\r\n            // current handedness (e.g. a glTF mesh in a right-handed scene). Keep the\r\n            // original order so Manifold always receives consistently outward-wound input.\r\n            triVerts.set(data.indices!);\r\n        } else {\r\n            // Revert order to match Manifold's expected winding for Babylon-default meshes\r\n            for (let i = 0; i < data.indices!.length; i += 3) {\r\n                triVerts[i] = data.indices![i + 2];\r\n                triVerts[i + 1] = data.indices![i + 1];\r\n                triVerts[i + 2] = data.indices![i];\r\n            }\r\n        }\r\n\r\n        const tempVector3 = new Vector3();\r\n        let numProp = 3;\r\n        const structure: IManifoldVertexComponent[] = [{ stride: 3, kind: VertexBuffer.PositionKind }];\r\n\r\n        if (!worldMatrix) {\r\n            structure[0].data = data.positions!;\r\n        } else {\r\n            const positions = new Float32Array(data.positions!.length);\r\n            for (let i = 0; i < data.positions!.length; i += 3) {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(data.positions![i], data.positions![i + 1], data.positions![i + 2], worldMatrix, tempVector3);\r\n                tempVector3.toArray(positions, i);\r\n            }\r\n            structure[0].data = positions;\r\n        }\r\n\r\n        // Normals\r\n        const sourceNormals = data.normals!;\r\n        if (sourceNormals) {\r\n            numProp += 3;\r\n            structure.push({ stride: 3, kind: VertexBuffer.NormalKind });\r\n            if (!worldMatrix) {\r\n                structure[1].data = sourceNormals;\r\n            } else {\r\n                const normals = new Float32Array(sourceNormals.length);\r\n                for (let i = 0; i < sourceNormals.length; i += 3) {\r\n                    Vector3.TransformNormalFromFloatsToRef(sourceNormals[i], sourceNormals[i + 1], sourceNormals[i + 2], worldMatrix, tempVector3);\r\n                    tempVector3.toArray(normals, i);\r\n                }\r\n                structure[1].data = normals;\r\n            }\r\n        }\r\n\r\n        // UVs\r\n        const uvKindToPropertyName: { [key: string]: string } = {\r\n            [VertexBuffer.UVKind]: \"uvs\",\r\n            [VertexBuffer.UV2Kind]: \"uvs2\",\r\n            [VertexBuffer.UV3Kind]: \"uvs3\",\r\n            [VertexBuffer.UV4Kind]: \"uvs4\",\r\n            [VertexBuffer.UV5Kind]: \"uvs5\",\r\n            [VertexBuffer.UV6Kind]: \"uvs6\",\r\n        };\r\n        for (const kind of [VertexBuffer.UVKind, VertexBuffer.UV2Kind, VertexBuffer.UV3Kind, VertexBuffer.UV4Kind, VertexBuffer.UV5Kind, VertexBuffer.UV6Kind]) {\r\n            const sourceUV = (data as any)[uvKindToPropertyName[kind]];\r\n            if (sourceUV) {\r\n                numProp += 2;\r\n                structure.push({ stride: 2, kind: kind, data: sourceUV });\r\n            }\r\n        }\r\n\r\n        // Colors\r\n        const sourceColors = data.colors;\r\n        if (sourceColors) {\r\n            numProp += 4;\r\n            structure.push({ stride: 4, kind: VertexBuffer.ColorKind, data: sourceColors });\r\n        }\r\n\r\n        return this._ProcessData(data.positions!.length / 3, triVerts, structure, numProp, runIndex, runOriginalID);\r\n    }\r\n\r\n    /**\r\n     * Create a new Constructive Solid Geometry from a vertexData\r\n     * @param vertexData defines the vertexData to use to create the CSG\r\n     * @returns a new CSG2 class\r\n     */\r\n    public static FromVertexData(vertexData: VertexData): CSG2 {\r\n        const sourceVertices = vertexData.positions;\r\n        const sourceIndices = vertexData.indices;\r\n\r\n        if (!sourceVertices || !sourceIndices) {\r\n            throw new Error(\"The vertexData must at least have positions and indices\");\r\n        }\r\n\r\n        return this._Construct(vertexData, null);\r\n    }\r\n\r\n    /**\r\n     * Create a new Constructive Solid Geometry from a mesh\r\n     * @param mesh defines the mesh to use to create the CSG\r\n     * @param ignoreWorldMatrix defines if the world matrix should be ignored\r\n     * @returns a new CSG2 class\r\n     */\r\n    public static FromMesh(mesh: Mesh, ignoreWorldMatrix = false): CSG2 {\r\n        const sourceVertices = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const sourceIndices = mesh.getIndices();\r\n        const worldMatrix = mesh.computeWorldMatrix(true);\r\n\r\n        if (!sourceVertices || !sourceIndices) {\r\n            throw new Error(\"The mesh must at least have positions and indices\");\r\n        }\r\n\r\n        // Create a triangle run for each submesh (material)\r\n        const starts = [...Array(mesh.subMeshes.length)].map((_, idx) => mesh.subMeshes[idx].indexStart);\r\n\r\n        // Map the materials to ID.\r\n        const sourceMaterial = mesh.material || mesh.getScene().defaultMaterial;\r\n        const isMultiMaterial = sourceMaterial.getClassName() === \"MultiMaterial\";\r\n        const originalIDs = [...Array(mesh.subMeshes.length)].map((_, idx) => {\r\n            if (isMultiMaterial) {\r\n                return FirstID + (sourceMaterial as MultiMaterial).subMaterials[mesh.subMeshes[idx].materialIndex]!.uniqueId;\r\n            }\r\n\r\n            return FirstID + sourceMaterial.uniqueId;\r\n        });\r\n\r\n        // List the runs in sequence.\r\n        const indices = Array.from(starts.keys());\r\n        indices.sort((a, b) => starts[a] - starts[b]);\r\n        const runIndex = new Uint32Array(indices.map((i) => starts[i]));\r\n        const runOriginalID = new Uint32Array(indices.map((i) => originalIDs[i]));\r\n\r\n        // Process\r\n        const data = {\r\n            positions: sourceVertices,\r\n            indices: sourceIndices,\r\n            normals: mesh.getVerticesData(VertexBuffer.NormalKind),\r\n            colors: mesh.getVerticesData(VertexBuffer.ColorKind),\r\n            uvs: mesh.getVerticesData(VertexBuffer.UVKind),\r\n            uvs2: mesh.getVerticesData(VertexBuffer.UV2Kind),\r\n            uvs3: mesh.getVerticesData(VertexBuffer.UV3Kind),\r\n            uvs4: mesh.getVerticesData(VertexBuffer.UV4Kind),\r\n            uvs5: mesh.getVerticesData(VertexBuffer.UV5Kind),\r\n            uvs6: mesh.getVerticesData(VertexBuffer.UV6Kind),\r\n        };\r\n        // Manifold requires consistently outward-wound (positive volume) input. Babylon\r\n        // meshes can be wound either way depending on their source: a default mesh uses the\r\n        // engine's winding for the current handedness, while an imported mesh (e.g. glTF)\r\n        // keeps its own winding and compensates through sideOrientation. Detect when the\r\n        // effective world-space winding is reflected relative to the default so Manifold's\r\n        // input orientation stays consistent across all sources. This fixes CSG operations\r\n        // in right-handed scenes and with negative-determinant (mirrored) world matrices.\r\n        // Use the same effective material the renderer binds (mesh.material falling back to\r\n        // the scene default) so an explicit sideOrientation override is honored, and reuse\r\n        // the cached world-matrix determinant.\r\n        let effectiveOrientation = sourceMaterial.sideOrientation !== null ? sourceMaterial.sideOrientation : mesh.sideOrientation;\r\n        if (!ignoreWorldMatrix && mesh._getWorldMatrixDeterminant() < 0) {\r\n            effectiveOrientation =\r\n                effectiveOrientation === Constants.MATERIAL_ClockWiseSideOrientation\r\n                    ? Constants.MATERIAL_CounterClockWiseSideOrientation\r\n                    : Constants.MATERIAL_ClockWiseSideOrientation;\r\n        }\r\n        const invertWinding = (effectiveOrientation === Constants.MATERIAL_CounterClockWiseSideOrientation) === mesh.getScene().useRightHandedSystem;\r\n\r\n        return this._Construct(data, ignoreWorldMatrix ? null : worldMatrix, runIndex, runOriginalID, invertWinding);\r\n    }\r\n}\r\n\r\n/**\r\n * Checks if the Manifold library is ready\r\n * @returns true if the Manifold library is ready\r\n */\r\nexport function IsCSG2Ready() {\r\n    return Manifold !== undefined;\r\n}\r\n\r\n/**\r\n * Initialize the Manifold library\r\n * @param options defines the options to use to initialize the library\r\n */\r\nexport async function InitializeCSG2Async(options?: Partial<ICSG2Options>) {\r\n    const localOptions = {\r\n        manifoldUrl: \"https://unpkg.com/manifold-3d@3.4.0\",\r\n        ...options,\r\n    };\r\n\r\n    if (Manifold) {\r\n        return; // Already initialized\r\n    }\r\n\r\n    if (ManifoldPromise) {\r\n        await ManifoldPromise;\r\n        return;\r\n    }\r\n\r\n    if (localOptions.manifoldInstance) {\r\n        Manifold = localOptions.manifoldInstance;\r\n        ManifoldMesh = localOptions.manifoldMeshInstance;\r\n    } else {\r\n        ManifoldPromise = _LoadScriptModuleAsync(\r\n            `\r\n            import Module from '${localOptions.manifoldUrl}/manifold.js';\r\n            const wasm = await Module();\r\n            wasm.setup();\r\n            const {Manifold, Mesh} = wasm;\r\n            const returnedValue =  {Manifold, Mesh};\r\n        `\r\n        );\r\n\r\n        const result = await ManifoldPromise;\r\n        // eslint-disable-next-line require-atomic-updates\r\n        Manifold = result.Manifold;\r\n        ManifoldMesh = result.Mesh;\r\n    }\r\n\r\n    // Reserve IDs for materials (we consider that there will be no more than 65536 materials)\r\n    FirstID = Manifold.reserveIDs(65536);\r\n}\r\n","function GetByteIndex(bitIndex: number): number {\r\n    return Math.floor(bitIndex / 8);\r\n}\r\n\r\nfunction GetBitMask(bitIndex: number): number {\r\n    return 1 << (bitIndex % 8);\r\n}\r\n\r\n/**\r\n * An fixed size array that effectively stores boolean values where each value is a single bit of backing data.\r\n * @remarks\r\n * All bits are initialized to false.\r\n */\r\nexport class BitArray {\r\n    private readonly _byteArray: Uint8Array;\r\n\r\n    /**\r\n     * Creates a new bit array with a fixed size.\r\n     * @param size The number of bits to store.\r\n     */\r\n    public constructor(public readonly size: number) {\r\n        this._byteArray = new Uint8Array(Math.ceil(this.size / 8));\r\n    }\r\n\r\n    /**\r\n     * Gets the current value at the specified index.\r\n     * @param bitIndex The index to get the value from.\r\n     * @returns The value at the specified index.\r\n     */\r\n    public get(bitIndex: number): boolean {\r\n        if (bitIndex >= this.size) {\r\n            throw new RangeError(\"Bit index out of range\");\r\n        }\r\n        const byteIndex = GetByteIndex(bitIndex);\r\n        const bitMask = GetBitMask(bitIndex);\r\n        return (this._byteArray[byteIndex] & bitMask) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the value at the specified index.\r\n     * @param bitIndex The index to set the value at.\r\n     * @param value The value to set.\r\n     */\r\n    public set(bitIndex: number, value: boolean): void {\r\n        if (bitIndex >= this.size) {\r\n            throw new RangeError(\"Bit index out of range\");\r\n        }\r\n        const byteIndex = GetByteIndex(bitIndex);\r\n        const bitMask = GetBitMask(bitIndex);\r\n        if (value) {\r\n            this._byteArray[byteIndex] |= bitMask;\r\n        } else {\r\n            this._byteArray[byteIndex] &= ~bitMask;\r\n        }\r\n    }\r\n}\r\n","import { type IndicesArray } from \"core/types\";\r\nimport { BitArray } from \"core/Misc/bitArray\";\r\n\r\n/**\r\n * Sort (in place) the index array so that faces with common indices are close\r\n * @param indices the array of indices to sort\r\n */\r\nexport function OptimizeIndices(indices: IndicesArray) {\r\n    const faces: Array<Array<number>> = [];\r\n    const faceCount = indices.length / 3;\r\n\r\n    // Step 1: Break the indices array into faces\r\n    for (let i = 0; i < faceCount; i++) {\r\n        faces.push([indices[i * 3], indices[i * 3 + 1], indices[i * 3 + 2]]);\r\n    }\r\n\r\n    // Step 2: Build a graph connecting faces sharing a vertex\r\n    const vertexToFaceMap = new Map<number, number[]>();\r\n    for (let faceIndex = 0; faceIndex < faces.length; faceIndex++) {\r\n        const face = faces[faceIndex];\r\n        for (const vertex of face) {\r\n            let face = vertexToFaceMap.get(vertex);\r\n            if (!face) {\r\n                vertexToFaceMap.set(vertex, (face = []));\r\n            }\r\n            face.push(faceIndex);\r\n        }\r\n    }\r\n\r\n    // Step 3: Traverse faces using DFS to ensure connected faces are close\r\n    const visited = new BitArray(faceCount);\r\n    const sortedFaces: Array<number[]> = [];\r\n\r\n    // Using a stack and not a recursive version to avoid call stack overflow\r\n    const deepFirstSearchStack = (startFaceIndex: number) => {\r\n        const stack: Array<number> = [startFaceIndex];\r\n\r\n        while (stack.length > 0) {\r\n            const currentFaceIndex = stack.pop()!;\r\n\r\n            if (visited.get(currentFaceIndex)) {\r\n                continue;\r\n            }\r\n            visited.set(currentFaceIndex, true);\r\n            sortedFaces.push(faces[currentFaceIndex]);\r\n\r\n            // Push unvisited neighbors (faces sharing a vertex) onto the stack\r\n            for (const vertex of faces[currentFaceIndex]) {\r\n                const neighbors = vertexToFaceMap.get(vertex);\r\n\r\n                if (!neighbors) {\r\n                    return;\r\n                }\r\n\r\n                for (const neighborFaceIndex of neighbors) {\r\n                    if (!visited.get(neighborFaceIndex)) {\r\n                        stack.push(neighborFaceIndex);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    // Start DFS from the first face\r\n    for (let i = 0; i < faceCount; i++) {\r\n        if (!visited.get(i)) {\r\n            deepFirstSearchStack(i);\r\n        }\r\n    }\r\n\r\n    // Step 4: Flatten the sorted faces back into an array\r\n    let index = 0;\r\n    for (const face of sortedFaces) {\r\n        indices[index++] = face[0];\r\n        indices[index++] = face[1];\r\n        indices[index++] = face[2];\r\n    }\r\n}\r\n","import { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { VertexData } from \"./mesh.vertexData\";\r\nimport { Scalar } from \"core/Maths/math.scalar\";\r\nimport { type FloatArray } from \"core/types\";\r\n\r\n/**\r\n * Inspired by https://github.com/stevinz/three-subdivide\r\n * Thanks a lot to https://github.com/stevinz\r\n */\r\n\r\n/**\r\n * Interface used to configure the subdivision process\r\n */\r\nexport interface ISubdivideOptions {\r\n    /** Apply only flat subdivision - false by default */\r\n    flatOnly?: boolean;\r\n    /** Split all triangles at edges shared by coplanar triangles - true by default*/\r\n    split?: boolean;\r\n    /**  Should UV values be averaged during subdivision - false by default */\r\n    uvSmooth?: boolean;\r\n    /** Should edges / breaks in geometry be ignored during subdivision? - false by default */\r\n    preserveEdges?: boolean;\r\n    /** How much to weigh favoring heavy corners vs favoring Loop's formula - 1 by default*/\r\n    weight?: number;\r\n}\r\n\r\nconst PositionShift = Math.pow(10, 4);\r\n\r\n/**\r\n * Rounds a number (simulate integer rounding)\r\n * @internal\r\n */\r\nfunction Round(x: number): number {\r\n    return (x + (x > 0 ? 0.5 : -0.5)) << 0;\r\n}\r\n\r\n/**\r\n * Generates a hash string from a number\r\n * @internal\r\n */\r\nfunction HashFromNumber(num: number, shift = PositionShift): string {\r\n    let roundedNumber = Round(num * shift);\r\n    if (roundedNumber === 0) {\r\n        roundedNumber = 0; // prevent -0\r\n    }\r\n    return `${roundedNumber}`;\r\n}\r\n\r\n/**\r\n * Generates a hash string from a Vector3\r\n * @internal\r\n */\r\nfunction HashFromVector(v: Vector3, shift = PositionShift): string {\r\n    return `${HashFromNumber(v.x, shift)},${HashFromNumber(v.y, shift)},${HashFromNumber(v.z, shift)}`;\r\n}\r\n\r\n/**\r\n * Gathers attribute names from a VertexData object\r\n * @internal\r\n */\r\nfunction GatherAttributes(vertexData: VertexData): string[] {\r\n    const desired = [\"positions\", \"normals\", \"uvs\"];\r\n    const available = Object.keys(vertexData).filter((k) => Array.isArray((vertexData as any)[k]));\r\n    return Array.from(new Set([...desired, ...available]));\r\n}\r\n\r\n/**\r\n * Sets triangle data into an attribute array\r\n * @internal\r\n */\r\nfunction SetTriangle(arr: number[], index: number, itemSize: number, vec0: number[], vec1: number[], vec2: number[]): void {\r\n    for (let i = 0; i < itemSize; i++) {\r\n        arr[index + i] = vec0[i];\r\n        arr[index + itemSize + i] = vec1[i];\r\n        arr[index + 2 * itemSize + i] = vec2[i];\r\n    }\r\n}\r\n\r\n/**\r\n * Converts indexed VertexData to a non-indexed form\r\n * @internal\r\n */\r\nfunction ToNonIndexed(vertexData: VertexData): VertexData {\r\n    if (!vertexData.indices || vertexData.indices.length === 0) {\r\n        return vertexData; // already non-indexed\r\n    }\r\n    const newPositions: number[] = [];\r\n    const newNormals: number[] = [];\r\n    const newUVs: number[] = [];\r\n    const indices = vertexData.indices;\r\n    const pos = vertexData.positions!;\r\n    const norm = vertexData.normals;\r\n    const uv = vertexData.uvs;\r\n\r\n    for (let i = 0; i < indices.length; i++) {\r\n        const idx = indices[i];\r\n        newPositions.push(pos[3 * idx], pos[3 * idx + 1], pos[3 * idx + 2]);\r\n        if (norm) {\r\n            newNormals.push(norm[3 * idx], norm[3 * idx + 1], norm[3 * idx + 2]);\r\n        }\r\n        if (uv) {\r\n            newUVs.push(uv[2 * idx], uv[2 * idx + 1]);\r\n        }\r\n    }\r\n\r\n    const newVertexData = new VertexData();\r\n    newVertexData.positions = newPositions;\r\n    if (newNormals.length) {\r\n        newVertexData.normals = newNormals;\r\n    }\r\n    if (newUVs.length) {\r\n        newVertexData.uvs = newUVs;\r\n    }\r\n    return newVertexData;\r\n}\r\n\r\n/** Helper to read a Vector3 from an attribute array\r\n * @internal\r\n */\r\nfunction ReadVector(destination: Vector3, attribute: FloatArray, index: number, itemSize: number) {\r\n    if (itemSize === 3) {\r\n        destination.fromArray(attribute, index * 3);\r\n        return;\r\n    }\r\n    // For uvs (itemSize 2), return a Vector3 with z = 0.\r\n    destination.set(attribute[index * 2], attribute[index * 2 + 1], 0);\r\n}\r\n\r\nfunction ProcessFlatAttribute(source: FloatArray, vertexCount: number, output: number[]) {\r\n    const v0 = new Vector3();\r\n    const v1 = new Vector3();\r\n    const v2 = new Vector3();\r\n    const m01 = new Vector3();\r\n    const m12 = new Vector3();\r\n    const m20 = new Vector3();\r\n\r\n    for (let i = 0; i < vertexCount; i += 3) {\r\n        const j = i * 3;\r\n        v0.set(source[j], source[j + 1], source[j + 2]);\r\n        v1.set(source[j + 3], source[j + 4], source[j + 5]);\r\n        v2.set(source[j + 6], source[j + 7], source[j + 8]);\r\n        v0.addToRef(v1, m01);\r\n        m01.scaleInPlace(0.5);\r\n        v1.addToRef(v2, m12);\r\n        m12.scaleInPlace(0.5);\r\n        v2.addToRef(v0, m20);\r\n        m20.scaleInPlace(0.5);\r\n\r\n        // Positions\r\n        output.push(v0.x, v0.y, v0.z, m01.x, m01.y, m01.z, m20.x, m20.y, m20.z);\r\n        output.push(v1.x, v1.y, v1.z, m12.x, m12.y, m12.z, m01.x, m01.y, m01.z);\r\n        output.push(v2.x, v2.y, v2.z, m20.x, m20.y, m20.z, m12.x, m12.y, m12.z);\r\n        output.push(m01.x, m01.y, m01.z, m12.x, m12.y, m12.z, m20.x, m20.y, m20.z);\r\n    }\r\n}\r\n\r\n/**\r\n * Applies one iteration of flat subdivision (each triangle becomes 4).\r\n * @internal\r\n */\r\nfunction Flat(vertexData: VertexData): VertexData {\r\n    const data = ToNonIndexed(vertexData);\r\n    const positions = data.positions!;\r\n    const normals = data.normals;\r\n    const uvs = data.uvs;\r\n    const vertexCount = positions.length / 3;\r\n\r\n    const newPositions: number[] = [];\r\n    const newNormals: number[] = [];\r\n    const newUVs: number[] = [];\r\n    ProcessFlatAttribute(positions, vertexCount, newPositions);\r\n\r\n    if (normals && normals.length) {\r\n        ProcessFlatAttribute(normals, vertexCount, newNormals);\r\n    }\r\n\r\n    if (uvs && uvs.length) {\r\n        for (let i = 0; i < vertexCount; i += 3) {\r\n            const j = i * 2;\r\n            const uv0 = [uvs[j], uvs[j + 1]];\r\n            const uv1 = [uvs[j + 2], uvs[j + 3]];\r\n            const uv2 = [uvs[j + 4], uvs[j + 5]];\r\n\r\n            const uv01 = [(uv0[0] + uv1[0]) / 2, (uv0[1] + uv1[1]) / 2];\r\n            const uv12 = [(uv1[0] + uv2[0]) / 2, (uv1[1] + uv2[1]) / 2];\r\n            const uv20 = [(uv2[0] + uv0[0]) / 2, (uv2[1] + uv0[1]) / 2];\r\n\r\n            newUVs.push(...uv0, ...uv01, ...uv20);\r\n            newUVs.push(...uv1, ...uv12, ...uv01);\r\n            newUVs.push(...uv2, ...uv20, ...uv12);\r\n            newUVs.push(...uv01, ...uv12, ...uv20);\r\n        }\r\n    }\r\n\r\n    const newVertexCount = newPositions.length / 3;\r\n    const newIndices: number[] = [];\r\n    for (let i = 0; i < newVertexCount; i++) {\r\n        newIndices.push(i);\r\n    }\r\n\r\n    const newVertexData = new VertexData();\r\n    newVertexData.positions = newPositions;\r\n    if (newNormals.length) {\r\n        newVertexData.normals = newNormals;\r\n    }\r\n    if (newUVs.length) {\r\n        newVertexData.uvs = newUVs;\r\n    }\r\n    newVertexData.indices = newIndices;\r\n    return newVertexData;\r\n}\r\n\r\n/**\r\n * Applies one iteration of smooth subdivision with vertex averaging.\r\n * This function uses the subdivideAttribute routine to adjust vertex data.\r\n * @internal\r\n */\r\nfunction Smooth(vertexData: VertexData, options: ISubdivideOptions): VertexData {\r\n    // Convert to non-indexed and apply flat subdivision first.\r\n    const sourceData = ToNonIndexed(vertexData);\r\n    const flatData = Flat(sourceData);\r\n\r\n    const attributeList = GatherAttributes(sourceData);\r\n    const origPositions = sourceData.positions!;\r\n    const flatPositions = flatData.positions!;\r\n    const vertexCount = origPositions.length / 3;\r\n\r\n    // Build connectivity maps from the original geometry.\r\n    const hashToIndex: { [hash: string]: number[] } = {};\r\n    const existingNeighbors: { [hash: string]: { [neighborHash: string]: number[] } } = {};\r\n    const flatOpposites: { [hash: string]: number[] } = {};\r\n    const existingEdges: { [hash: string]: Set<string> } = {};\r\n\r\n    function addNeighbor(posHash: string, neighborHash: string, index: number): void {\r\n        if (!existingNeighbors[posHash]) {\r\n            existingNeighbors[posHash] = {};\r\n        }\r\n        if (!existingNeighbors[posHash][neighborHash]) {\r\n            existingNeighbors[posHash][neighborHash] = [];\r\n        }\r\n        existingNeighbors[posHash][neighborHash].push(index);\r\n    }\r\n    function addOpposite(posHash: string, index: number): void {\r\n        if (!flatOpposites[posHash]) {\r\n            flatOpposites[posHash] = [];\r\n        }\r\n        flatOpposites[posHash].push(index);\r\n    }\r\n    function addEdgePoint(posHash: string, edgeHash: string): void {\r\n        if (!existingEdges[posHash]) {\r\n            existingEdges[posHash] = new Set<string>();\r\n        }\r\n        existingEdges[posHash].add(edgeHash);\r\n    }\r\n\r\n    const temp = new Vector3();\r\n    const v0 = new Vector3();\r\n    const v1 = new Vector3();\r\n    const v2 = new Vector3();\r\n    const m01 = new Vector3();\r\n    const m12 = new Vector3();\r\n    const m20 = new Vector3();\r\n\r\n    // Process original positions\r\n    for (let i = 0; i < vertexCount; i += 3) {\r\n        ReadVector(v0, origPositions, i, 3);\r\n        ReadVector(v1, origPositions, i + 1, 3);\r\n        ReadVector(v2, origPositions, i + 2, 3);\r\n        const h0 = HashFromVector(v0);\r\n        const h1 = HashFromVector(v1);\r\n        const h2 = HashFromVector(v2);\r\n        addNeighbor(h0, h1, i + 1);\r\n        addNeighbor(h0, h2, i + 2);\r\n        addNeighbor(h1, h0, i);\r\n        addNeighbor(h1, h2, i + 2);\r\n        addNeighbor(h2, h0, i);\r\n        addNeighbor(h2, h1, i + 1);\r\n\r\n        // Opposites from flat subdivision: calculate midpoints.\r\n        v0.addToRef(v1, m01);\r\n        m01.scaleInPlace(0.5);\r\n        v1.addToRef(v2, m12);\r\n        m12.scaleInPlace(0.5);\r\n        v2.addToRef(v0, m20);\r\n        m20.scaleInPlace(0.5);\r\n\r\n        addOpposite(HashFromVector(m01), i + 2);\r\n        addOpposite(HashFromVector(m12), i);\r\n        addOpposite(HashFromVector(m20), i + 1);\r\n\r\n        // Track edges for preserveEdges.\r\n        addEdgePoint(h0, HashFromVector(m01));\r\n        addEdgePoint(h0, HashFromVector(m20));\r\n        addEdgePoint(h1, HashFromVector(m01));\r\n        addEdgePoint(h1, HashFromVector(m12));\r\n        addEdgePoint(h2, HashFromVector(m12));\r\n        addEdgePoint(h2, HashFromVector(m20));\r\n    }\r\n\r\n    // Build map from flat positions to indices.\r\n    for (let i = 0; i < flatPositions.length / 3; i++) {\r\n        ReadVector(temp, flatPositions, i, 3);\r\n        const h = HashFromVector(temp);\r\n        if (!hashToIndex[h]) {\r\n            hashToIndex[h] = [];\r\n        }\r\n        hashToIndex[h].push(i);\r\n    }\r\n\r\n    // Prepare temporary vectors for subdivideAttribute.\r\n    const _vertex: Vector3[] = [new Vector3(), new Vector3(), new Vector3()];\r\n    const _position: Vector3[] = [new Vector3(), new Vector3(), new Vector3()];\r\n    const _average = new Vector3();\r\n    const _temp = new Vector3();\r\n\r\n    // subdivideAttribute: adjusts vertex attributes using Loop’s averaging rules.\r\n    function subdivideAttribute(attributeName: string, existingAttribute: number[], flattenedAttribute: number[]): number[] {\r\n        const itemSize = attributeName === \"uvs\" ? 2 : 3;\r\n        const flatVertexCount = flatPositions.length / 3;\r\n        const floatArray = new Array(flatVertexCount * itemSize);\r\n        let index = 0;\r\n        for (let i = 0; i < flatVertexCount; i += 3) {\r\n            for (let v = 0; v < 3; v++) {\r\n                if (attributeName === \"uvs\" && !options.uvSmooth) {\r\n                    // Simply copy UVs.\r\n                    ReadVector(_vertex[v], flattenedAttribute, i + v, 2);\r\n                } else if (attributeName === \"normals\") {\r\n                    ReadVector(_position[v], flatPositions, i + v, 3);\r\n                    const positionHash = HashFromVector(_position[v]);\r\n                    const positionsArr = hashToIndex[positionHash] || [];\r\n                    const k = positionsArr.length;\r\n                    const beta = 0.75 / k;\r\n                    const startWeight = 1.0 - beta * k;\r\n                    ReadVector(_vertex[v], flattenedAttribute, i + v, 3);\r\n                    _vertex[v].scaleInPlace(startWeight);\r\n                    for (const positionIndex of positionsArr) {\r\n                        ReadVector(_average, flattenedAttribute, positionIndex, 3);\r\n                        _average.scaleInPlace(beta);\r\n                        _vertex[v].addInPlace(_average);\r\n                    }\r\n                } else {\r\n                    // 'positions', 'colors', etc.\r\n                    ReadVector(_vertex[v], flattenedAttribute, i + v, itemSize);\r\n                    ReadVector(_position[v], flatPositions, i + v, 3);\r\n                    const positionHash = HashFromVector(_position[v]);\r\n                    const neighbors = existingNeighbors[positionHash];\r\n                    const opposites = flatOpposites[positionHash];\r\n                    if (neighbors) {\r\n                        if (options.preserveEdges) {\r\n                            const edgeSet = existingEdges[positionHash];\r\n                            let hasPair = true;\r\n                            edgeSet.forEach((edgeHash) => {\r\n                                if (flatOpposites[edgeHash] && flatOpposites[edgeHash].length % 2 !== 0) {\r\n                                    hasPair = false;\r\n                                }\r\n                            });\r\n                            if (!hasPair) {\r\n                                // If edges aren't paired, skip adjustment.\r\n                                continue;\r\n                            }\r\n                        }\r\n                        const neighborKeys = Object.keys(neighbors);\r\n                        const k = neighborKeys.length;\r\n                        const beta = (1 / k) * (5 / 8 - Math.pow(3 / 8 + (1 / 4) * Math.cos((2 * Math.PI) / k), 2));\r\n                        const heavy = 1 / k / k;\r\n                        const weight = Scalar.Lerp(heavy, beta, options.weight!);\r\n                        const startWeight = 1.0 - weight * k;\r\n                        _vertex[v].scaleInPlace(startWeight);\r\n                        for (const neighborHash in neighbors) {\r\n                            const neighborIndices = neighbors[neighborHash];\r\n                            _average.set(0, 0, 0);\r\n                            for (const neighborIndex of neighborIndices) {\r\n                                ReadVector(_temp, existingAttribute, neighborIndex, itemSize);\r\n                                _average.addInPlace(_temp);\r\n                            }\r\n                            _average.scaleInPlace(1 / neighborIndices.length);\r\n                            _average.scaleInPlace(weight);\r\n                            _vertex[v].addInPlace(_average);\r\n                        }\r\n                    } else if (opposites && opposites.length === 2) {\r\n                        const k = opposites.length;\r\n                        const beta = 0.125; // 1/8\r\n                        const startWeight = 1.0 - beta * k;\r\n                        _vertex[v].scaleInPlace(startWeight);\r\n                        for (const oppositeIndex of opposites) {\r\n                            ReadVector(_average, existingAttribute, oppositeIndex, itemSize);\r\n                            _average.scaleInPlace(beta);\r\n                            _vertex[v].addInPlace(_average);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            // Write out new triangle vertices.\r\n            SetTriangle(floatArray, index, itemSize, _vertex[0].asArray(), _vertex[1].asArray(), _vertex[2].asArray());\r\n            index += itemSize * 3;\r\n        }\r\n        return floatArray;\r\n    }\r\n\r\n    // Build new attributes for the smoothed geometry.\r\n    const smoothData = new VertexData();\r\n    for (const attributeName of attributeList) {\r\n        if (attributeName === \"indices\") {\r\n            continue;\r\n        }\r\n        const existingAttribute = (sourceData as any)[attributeName] as number[];\r\n        const flattenedAttribute = (flatData as any)[attributeName] as number[];\r\n        if (!existingAttribute || !flattenedAttribute) {\r\n            continue;\r\n        }\r\n        const newArray = subdivideAttribute(attributeName, existingAttribute, flattenedAttribute);\r\n        (smoothData as any)[attributeName] = newArray;\r\n    }\r\n\r\n    // Rebuild indices sequentially.\r\n    const newPositions = smoothData.positions!;\r\n    const newIndices: number[] = [];\r\n    for (let i = 0; i < newPositions.length / 3; i++) {\r\n        newIndices.push(i);\r\n    }\r\n    smoothData.indices = newIndices;\r\n    return smoothData;\r\n}\r\n\r\n/**\r\n * Subdivide a vertexData using Loop algorithm\r\n * @param vertexData The vertexData to subdivide\r\n * @param level The number of times to subdivide\r\n * @param options The options to use when subdividing\r\n * @returns The subdivided vertexData\r\n */\r\nexport function Subdivide(vertexData: VertexData, level: number, options?: Partial<ISubdivideOptions>): VertexData {\r\n    options = {\r\n        flatOnly: false,\r\n        uvSmooth: false,\r\n        preserveEdges: false,\r\n        weight: 1,\r\n        ...options,\r\n    };\r\n\r\n    if (!vertexData.positions || vertexData.positions.length === 0 || level <= 0) {\r\n        return vertexData;\r\n    }\r\n\r\n    // Clone the input\r\n    let modified = vertexData.clone();\r\n\r\n    for (let i = 0; i < level; i++) {\r\n        if (options.flatOnly) {\r\n            modified = Flat(modified);\r\n        } else {\r\n            modified = Smooth(modified, options);\r\n        }\r\n    }\r\n\r\n    return modified;\r\n}\r\n","/**\r\n * Defines the kind of connection point for node geometry\r\n */\r\nexport enum NodeGeometryBlockConnectionPointTypes {\r\n    /** Int */\r\n    Int = 0x0001,\r\n    /** Float */\r\n    Float = 0x0002,\r\n    /** Vector2 */\r\n    Vector2 = 0x0004,\r\n    /** Vector3 */\r\n    Vector3 = 0x0008,\r\n    /** Vector4 */\r\n    Vector4 = 0x0010,\r\n    /** Matrix */\r\n    Matrix = 0x0020,\r\n    /** Geometry */\r\n    Geometry = 0x0040,\r\n    /** Texture */\r\n    Texture = 0x0080,\r\n    /** Detect type based on connection */\r\n    AutoDetect = 0x0400,\r\n    /** Output type that will be defined by input type */\r\n    BasedOnInput = 0x0800,\r\n    /** Undefined */\r\n    Undefined = 0x1000,\r\n    /** Bitmask of all types */\r\n    All = 0x0fff,\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type NodeGeometryBlock } from \"./nodeGeometryBlock\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"./Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type GeometryInputBlock } from \"./Blocks/geometryInputBlock\";\r\nimport { type NodeGeometryBuildState } from \"./nodeGeometryBuildState\";\r\n\r\n/**\r\n * Enum used to define the compatibility state between two connection points\r\n */\r\nexport const enum NodeGeometryConnectionPointCompatibilityStates {\r\n    /** Points are compatibles */\r\n    Compatible,\r\n    /** Points are incompatible because of their types */\r\n    TypeIncompatible,\r\n    /** Points are incompatible because they are in the same hierarchy **/\r\n    HierarchyIssue,\r\n}\r\n\r\n/**\r\n * Defines the direction of a connection point\r\n */\r\nexport const enum NodeGeometryConnectionPointDirection {\r\n    /** Input */\r\n    Input,\r\n    /** Output */\r\n    Output,\r\n}\r\n\r\n/**\r\n * Defines a connection point for a block\r\n */\r\nexport class NodeGeometryConnectionPoint {\r\n    /** @internal */\r\n    public _ownerBlock: NodeGeometryBlock;\r\n    /** @internal */\r\n    public _connectedPoint: Nullable<NodeGeometryConnectionPoint> = null;\r\n    /** @internal */\r\n    public _storedValue: any = null;\r\n    /** @internal */\r\n    public _storedFunction: Nullable<(state: NodeGeometryBuildState) => any> = null;\r\n\r\n    /** @internal */\r\n    public _acceptedConnectionPointType: Nullable<NodeGeometryConnectionPoint> = null;\r\n\r\n    private _endpoints = new Array<NodeGeometryConnectionPoint>();\r\n    private _direction: NodeGeometryConnectionPointDirection;\r\n    private _type = NodeGeometryBlockConnectionPointTypes.Geometry;\r\n\r\n    /** @internal */\r\n    public _linkedConnectionSource: Nullable<NodeGeometryConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _typeConnectionSource: Nullable<NodeGeometryConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _defaultConnectionPointType: Nullable<NodeGeometryBlockConnectionPointTypes> = null;\r\n\r\n    /** @internal */\r\n    public _isMainLinkSource = false;\r\n\r\n    /** Gets the direction of the point */\r\n    public get direction() {\r\n        return this._direction;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the additional types supported by this connection point\r\n     */\r\n    public acceptedConnectionPointTypes: NodeGeometryBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Gets or sets the additional types excluded by this connection point\r\n     */\r\n    public excludedConnectionPointTypes: NodeGeometryBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Observable triggered when this point is connected\r\n     */\r\n    public onConnectionObservable = new Observable<NodeGeometryConnectionPoint>();\r\n\r\n    /**\r\n     * Observable triggered when this point is disconnected\r\n     */\r\n    public onDisconnectionObservable = new Observable<NodeGeometryConnectionPoint>();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is exposed on a frame\r\n     */\r\n    public isExposedOnFrame: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets number indicating the position that the port is exposed to on a frame\r\n     */\r\n    public exposedPortPosition: number = -1;\r\n\r\n    /**\r\n     * Gets the default value used for this point at creation time\r\n     */\r\n    public defaultValue: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the default value used for this point if nothing is connected\r\n     */\r\n    public value: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the min value accepted for this point if nothing is connected\r\n     */\r\n    public valueMin: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the max value accepted for this point if nothing is connected\r\n     */\r\n    public valueMax: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is float)\r\n     */\r\n    public get type(): NodeGeometryBlockConnectionPointTypes {\r\n        if (this._type === NodeGeometryBlockConnectionPointTypes.AutoDetect) {\r\n            if (this._ownerBlock.isInput) {\r\n                return (this._ownerBlock as GeometryInputBlock).type;\r\n            }\r\n\r\n            if (this._connectedPoint) {\r\n                return this._connectedPoint.type;\r\n            }\r\n\r\n            if (this._linkedConnectionSource) {\r\n                if (this._linkedConnectionSource.isConnected) {\r\n                    return this._linkedConnectionSource.type;\r\n                }\r\n                if (this._linkedConnectionSource._defaultConnectionPointType) {\r\n                    return this._linkedConnectionSource._defaultConnectionPointType;\r\n                }\r\n            }\r\n\r\n            if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        if (this._type === NodeGeometryBlockConnectionPointTypes.BasedOnInput) {\r\n            if (this._typeConnectionSource) {\r\n                if (!this._typeConnectionSource.isConnected && this._defaultConnectionPointType) {\r\n                    return this._defaultConnectionPointType;\r\n                }\r\n                return this._typeConnectionSource.type;\r\n            } else if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    public set type(value: NodeGeometryBlockConnectionPointTypes) {\r\n        this._type = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the connection point name\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * Gets or sets the connection point display name\r\n     */\r\n    public displayName: string;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point can be omitted\r\n     */\r\n    public isOptional: boolean;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current point is connected to another NodeMaterialBlock\r\n     */\r\n    public get isConnected(): boolean {\r\n        return this.connectedPoint !== null || this.hasEndpoints;\r\n    }\r\n\r\n    /** Get the other side of the connection (if any) */\r\n    public get connectedPoint(): Nullable<NodeGeometryConnectionPoint> {\r\n        return this._connectedPoint;\r\n    }\r\n\r\n    /** Get the block that owns this connection point */\r\n    public get ownerBlock(): NodeGeometryBlock {\r\n        return this._ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the other side of this connection (if any) */\r\n    public get sourceBlock(): Nullable<NodeGeometryBlock> {\r\n        if (!this._connectedPoint) {\r\n            return null;\r\n        }\r\n\r\n        return this._connectedPoint.ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the endpoints of this connection (if any) */\r\n    public get connectedBlocks(): Array<NodeGeometryBlock> {\r\n        if (this._endpoints.length === 0) {\r\n            return [];\r\n        }\r\n\r\n        return this._endpoints.map((e) => e.ownerBlock);\r\n    }\r\n\r\n    /** Gets the list of connected endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /** Gets a boolean indicating if that output point is connected to at least one input */\r\n    public get hasEndpoints(): boolean {\r\n        return this._endpoints && this._endpoints.length > 0;\r\n    }\r\n\r\n    /** Get the inner type (ie AutoDetect for instance instead of the inferred one) */\r\n    public get innerType() {\r\n        if (this._linkedConnectionSource && !this._isMainLinkSource && this._linkedConnectionSource.isConnected) {\r\n            return this.type;\r\n        }\r\n        return this._type;\r\n    }\r\n\r\n    /** @internal */\r\n    public _callCount = 0;\r\n\r\n    /** @internal */\r\n    public _executionCount = 0;\r\n\r\n    /** @internal */\r\n    public _resetCounters() {\r\n        this._callCount = 0;\r\n        this._executionCount = 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of times this point was called\r\n     */\r\n    public get callCount() {\r\n        return this._callCount;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of times this point was executed\r\n     */\r\n    public get executionCount() {\r\n        return this._executionCount;\r\n    }\r\n\r\n    /**\r\n     * Gets the value represented by this connection point\r\n     * @param state current evaluation state\r\n     * @returns the connected value or the value if nothing is connected\r\n     */\r\n    public getConnectedValue(state: NodeGeometryBuildState) {\r\n        if (this.isConnected) {\r\n            if (this._connectedPoint?._storedFunction) {\r\n                this._connectedPoint._callCount++;\r\n                this._connectedPoint._executionCount++;\r\n                return this._connectedPoint._storedFunction(state);\r\n            }\r\n            this._connectedPoint!._callCount++;\r\n            this._connectedPoint!._executionCount = 1;\r\n            return this._connectedPoint!._storedValue;\r\n        }\r\n        this._callCount++;\r\n        this._executionCount = 1;\r\n        return this.value;\r\n    }\r\n\r\n    /**\r\n     * Creates a new connection point\r\n     * @param name defines the connection point name\r\n     * @param ownerBlock defines the block hosting this connection point\r\n     * @param direction defines the direction of the connection point\r\n     */\r\n    public constructor(name: string, ownerBlock: NodeGeometryBlock, direction: NodeGeometryConnectionPointDirection) {\r\n        this._ownerBlock = ownerBlock;\r\n        this.name = name;\r\n        this._direction = direction;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeMaterialConnectionPoint\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeGeometryConnectionPoint\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a boolean\r\n     */\r\n    public canConnectTo(connectionPoint: NodeGeometryConnectionPoint) {\r\n        return this.checkCompatibilityState(connectionPoint) === NodeGeometryConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Gets a number indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a number defining the compatibility state\r\n     */\r\n    public checkCompatibilityState(connectionPoint: NodeGeometryConnectionPoint): NodeGeometryConnectionPointCompatibilityStates {\r\n        const ownerBlock = this._ownerBlock;\r\n        const otherBlock = connectionPoint.ownerBlock;\r\n\r\n        if (this.type !== connectionPoint.type && connectionPoint.innerType !== NodeGeometryBlockConnectionPointTypes.AutoDetect) {\r\n            // Accepted types\r\n            if (connectionPoint.acceptedConnectionPointTypes && connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n                return NodeGeometryConnectionPointCompatibilityStates.Compatible;\r\n            } else {\r\n                return NodeGeometryConnectionPointCompatibilityStates.TypeIncompatible;\r\n            }\r\n        }\r\n\r\n        // Excluded\r\n        if (connectionPoint.excludedConnectionPointTypes && connectionPoint.excludedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n            return NodeGeometryConnectionPointCompatibilityStates.TypeIncompatible;\r\n        }\r\n\r\n        // Check hierarchy\r\n        let targetBlock = otherBlock;\r\n        let sourceBlock = ownerBlock;\r\n        if (this.direction === NodeGeometryConnectionPointDirection.Input) {\r\n            targetBlock = ownerBlock;\r\n            sourceBlock = otherBlock;\r\n        }\r\n\r\n        if (targetBlock.isAnAncestorOf(sourceBlock)) {\r\n            return NodeGeometryConnectionPointCompatibilityStates.HierarchyIssue;\r\n        }\r\n\r\n        return NodeGeometryConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Connect this point to another connection point\r\n     * @param connectionPoint defines the other connection point\r\n     * @param ignoreConstraints defines if the system will ignore connection type constraints (default is false)\r\n     * @returns the current connection point\r\n     */\r\n    public connectTo(connectionPoint: NodeGeometryConnectionPoint, ignoreConstraints = false): NodeGeometryConnectionPoint {\r\n        if (!ignoreConstraints && !this.canConnectTo(connectionPoint)) {\r\n            throw `Cannot connect these two connectors. source: \"${this.ownerBlock.name}\".${this.name}, target: \"${connectionPoint.ownerBlock.name}\".${connectionPoint.name}`;\r\n        }\r\n\r\n        this._endpoints.push(connectionPoint);\r\n        connectionPoint._connectedPoint = this;\r\n\r\n        this.onConnectionObservable.notifyObservers(connectionPoint);\r\n        connectionPoint.onConnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disconnect this point from one of his endpoint\r\n     * @param endpoint defines the other connection point\r\n     * @returns the current connection point\r\n     */\r\n    public disconnectFrom(endpoint: NodeGeometryConnectionPoint): NodeGeometryConnectionPoint {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index === -1) {\r\n            return this;\r\n        }\r\n\r\n        this._endpoints.splice(index, 1);\r\n        endpoint._connectedPoint = null;\r\n\r\n        this.onDisconnectionObservable.notifyObservers(endpoint);\r\n        endpoint.onDisconnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Fill the list of excluded connection point types with all types other than those passed in the parameter\r\n     * @param mask Types (ORed values of NodeMaterialBlockConnectionPointTypes) that are allowed, and thus will not be pushed to the excluded list\r\n     */\r\n    public addExcludedConnectionPointFromAllowedTypes(mask: number): void {\r\n        let bitmask = 1;\r\n        while (bitmask < NodeGeometryBlockConnectionPointTypes.All) {\r\n            if (!(mask & bitmask)) {\r\n                this.excludedConnectionPointTypes.push(bitmask);\r\n            }\r\n            bitmask = bitmask << 1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this point in a JSON representation\r\n     * @param isInput defines if the connection point is an input (default is true)\r\n     * @returns the serialized point object\r\n     */\r\n    public serialize(isInput = true): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.displayName = this.displayName;\r\n        if (this.value !== undefined && this.value !== null) {\r\n            if (this.value.asArray) {\r\n                serializationObject.valueType = \"BABYLON.\" + this.value.getClassName();\r\n                serializationObject.value = this.value.asArray();\r\n            } else {\r\n                serializationObject.valueType = \"number\";\r\n                serializationObject.value = this.value;\r\n            }\r\n        }\r\n\r\n        if (isInput && this.connectedPoint) {\r\n            serializationObject.inputName = this.name;\r\n            serializationObject.targetBlockId = this.connectedPoint.ownerBlock.uniqueId;\r\n            serializationObject.targetConnectionName = this.connectedPoint.name;\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        if (this.isExposedOnFrame || this.exposedPortPosition >= 0) {\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        this.onConnectionObservable.clear();\r\n        this.onDisconnectionObservable.clear();\r\n    }\r\n}\r\n","import { GetClass } from \"../../Misc/typeStore\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { UniqueIdGenerator } from \"../../Misc/uniqueIdGenerator\";\r\nimport { type NodeGeometryBlockConnectionPointTypes } from \"./Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryConnectionPoint, NodeGeometryConnectionPointDirection } from \"./nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"./nodeGeometryBuildState\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { PrecisionDate } from \"../../Misc/precisionDate\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type GeometryInputBlock } from \"./Blocks/geometryInputBlock\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { type NodeGeometry } from \"./nodeGeometry\";\r\n\r\n/**\r\n * Defines a block that can be used inside a node based geometry\r\n */\r\nexport class NodeGeometryBlock {\r\n    private _name = \"\";\r\n    private _buildId: number;\r\n    protected _isInput = false;\r\n    protected _isTeleportOut = false;\r\n    protected _isTeleportIn = false;\r\n    protected _isDebug = false;\r\n    protected _isUnique = false;\r\n    private _buildExecutionTime: number = 0;\r\n\r\n    /**\r\n     * Gets an observable raised when the block is built\r\n     */\r\n    public onBuildObservable = new Observable<NodeGeometryBlock>();\r\n\r\n    /** @internal */\r\n    public _inputs = new Array<NodeGeometryConnectionPoint>();\r\n    /** @internal */\r\n    public _outputs = new Array<NodeGeometryConnectionPoint>();\r\n    /** @internal */\r\n    public _preparationId: number;\r\n    /** @internal */\r\n    public _codeVariableName = \"\";\r\n\r\n    /**\r\n     * Gets the time spent to build this block (in ms)\r\n     */\r\n    public get buildExecutionTime() {\r\n        return this._buildExecutionTime;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of input points\r\n     */\r\n    public get inputs(): NodeGeometryConnectionPoint[] {\r\n        return this._inputs;\r\n    }\r\n\r\n    /** Gets the list of output points */\r\n    public get outputs(): NodeGeometryConnectionPoint[] {\r\n        return this._outputs;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the unique id of the node\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /**\r\n     * Gets or set the name of the block\r\n     */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is an input\r\n     */\r\n    public get isInput(): boolean {\r\n        return this._isInput;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport out\r\n     */\r\n    public get isTeleportOut(): boolean {\r\n        return this._isTeleportOut;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport in\r\n     */\r\n    public get isTeleportIn(): boolean {\r\n        return this._isTeleportIn;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a debug block\r\n     */\r\n    public get isDebug(): boolean {\r\n        return this._isDebug;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block can only be used once per NodeGeometry\r\n     */\r\n    public get isUnique() {\r\n        return this._isUnique;\r\n    }\r\n\r\n    /**\r\n     * A free comment about the block\r\n     */\r\n    @serialize(\"comment\")\r\n    public comments: string;\r\n\r\n    /** Gets or sets a boolean indicating that this input can be edited from a collapsed frame */\r\n    public visibleOnFrame = false;\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeGeometryBlock\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName() {\r\n        return \"NodeGeometryBlock\";\r\n    }\r\n\r\n    protected _inputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    protected _outputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOf(block: NodeGeometryBlock): boolean {\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock === block) {\r\n                    return true;\r\n                }\r\n                if (endpoint.ownerBlock.isAnAncestorOf(block)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given type\r\n     * @param type defines the potential type to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOfType(type: string): boolean {\r\n        if (this.getClassName() === type) {\r\n            return true;\r\n        }\r\n\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock.isAnAncestorOfType(type)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Get the first descendant using a predicate\r\n     * @param predicate defines the predicate to check\r\n     * @returns descendant or null if none found\r\n     */\r\n    public getDescendantOfPredicate(predicate: (block: NodeGeometryBlock) => boolean): Nullable<NodeGeometryBlock> {\r\n        if (predicate(this)) {\r\n            return this;\r\n        }\r\n\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const descendant = endpoint.ownerBlock.getDescendantOfPredicate(predicate);\r\n\r\n                if (descendant) {\r\n                    return descendant;\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public get _isReadyState(): Nullable<Promise<void>> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeGeometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        this._name = name;\r\n        this.uniqueId = UniqueIdGenerator.UniqueId;\r\n    }\r\n\r\n    /**\r\n     * Register a new input. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param isOptional defines a boolean indicating that this input can be omitted\r\n     * @param value value to return if there is no connection\r\n     * @param valueMin min value accepted for value\r\n     * @param valueMax max value accepted for value\r\n     * @returns the current block\r\n     */\r\n    public registerInput(name: string, type: NodeGeometryBlockConnectionPointTypes, isOptional: boolean = false, value?: any, valueMin?: any, valueMax?: any) {\r\n        const point = new NodeGeometryConnectionPoint(name, this, NodeGeometryConnectionPointDirection.Input);\r\n        point.type = type;\r\n        point.isOptional = isOptional;\r\n        point.defaultValue = value;\r\n        point.value = value;\r\n        point.valueMin = valueMin;\r\n        point.valueMax = valueMax;\r\n\r\n        this._inputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Register a new output. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param point an already created connection point. If not provided, create a new one\r\n     * @returns the current block\r\n     */\r\n    public registerOutput(name: string, type: NodeGeometryBlockConnectionPointTypes, point?: NodeGeometryConnectionPoint) {\r\n        point = point ?? new NodeGeometryConnectionPoint(name, this, NodeGeometryConnectionPointDirection.Output);\r\n        point.type = type;\r\n\r\n        this._outputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _buildBlock(state: NodeGeometryBuildState) {\r\n        // Empty. Must be defined by child nodes\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    protected _customBuildStep(state: NodeGeometryBuildState): void {\r\n        // Must be implemented by children\r\n    }\r\n\r\n    /**\r\n     * Build the current node and generate the vertex data\r\n     * @param state defines the current generation state\r\n     * @returns true if already built\r\n     */\r\n    public build(state: NodeGeometryBuildState): boolean {\r\n        if (this._buildId === state.buildId) {\r\n            return true;\r\n        }\r\n\r\n        if (this._outputs.length > 0) {\r\n            if (!this._outputs.some((o) => o.hasEndpoints) && !this.isDebug) {\r\n                return false;\r\n            }\r\n\r\n            for (const o of this.outputs) {\r\n                o._resetCounters();\r\n            }\r\n        }\r\n\r\n        this._buildId = state.buildId;\r\n\r\n        // Check if \"parent\" blocks are compiled\r\n        for (const input of this._inputs) {\r\n            if (!input.connectedPoint) {\r\n                if (!input.isOptional) {\r\n                    // Emit a warning\r\n                    state.notConnectedNonOptionalInputs.push(input);\r\n                }\r\n                continue;\r\n            }\r\n\r\n            const block = input.connectedPoint.ownerBlock;\r\n            if (block && block !== this) {\r\n                block.build(state);\r\n            }\r\n        }\r\n\r\n        this._customBuildStep(state);\r\n\r\n        // Logs\r\n        if (state.verbose) {\r\n            Logger.Log(`Building ${this.name} [${this.getClassName()}]`);\r\n        }\r\n\r\n        const now = PrecisionDate.Now;\r\n        this._buildBlock(state);\r\n        this._buildExecutionTime = PrecisionDate.Now - now;\r\n\r\n        this.onBuildObservable.notifyObservers(this);\r\n\r\n        return false;\r\n    }\r\n\r\n    protected _linkConnectionTypes(inputIndex0: number, inputIndex1: number, looseCoupling = false) {\r\n        if (looseCoupling) {\r\n            this._inputs[inputIndex1]._acceptedConnectionPointType = this._inputs[inputIndex0];\r\n        } else {\r\n            this._inputs[inputIndex0]._linkedConnectionSource = this._inputs[inputIndex1];\r\n            this._inputs[inputIndex0]._isMainLinkSource = true;\r\n        }\r\n        this._inputs[inputIndex1]._linkedConnectionSource = this._inputs[inputIndex0];\r\n    }\r\n\r\n    /**\r\n     * Initialize the block and prepare the context for build\r\n     */\r\n    public initialize() {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Lets the block try to connect some inputs automatically\r\n     * @param _nodeGeometry defines the node geometry to use for auto connection\r\n     */\r\n    public autoConfigure(_nodeGeometry: NodeGeometry) {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Find an input by its name\r\n     * @param name defines the name of the input to look for\r\n     * @returns the input or null if not found\r\n     */\r\n    public getInputByName(name: string) {\r\n        const filter = this._inputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Find an output by its name\r\n     * @param name defines the name of the output to look for\r\n     * @returns the output or null if not found\r\n     */\r\n    public getOutputByName(name: string) {\r\n        const filter = this._outputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.customType = \"BABYLON.\" + this.getClassName();\r\n        serializationObject.id = this.uniqueId;\r\n        serializationObject.name = this.name;\r\n        serializationObject.visibleOnFrame = this.visibleOnFrame;\r\n        serializationObject.comments = this.comments;\r\n\r\n        serializationObject.inputs = [];\r\n        serializationObject.outputs = [];\r\n\r\n        for (const input of this.inputs) {\r\n            serializationObject.inputs.push(input.serialize());\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            serializationObject.outputs.push(output.serialize(false));\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _deserialize(serializationObject: any) {\r\n        this._name = serializationObject.name;\r\n        this.comments = serializationObject.comments;\r\n        this.visibleOnFrame = !!serializationObject.visibleOnFrame;\r\n        this._deserializePortDisplayNamesAndExposedOnFrame(serializationObject);\r\n    }\r\n\r\n    private _deserializePortDisplayNamesAndExposedOnFrame(serializationObject: any) {\r\n        const serializedInputs = serializationObject.inputs;\r\n        const serializedOutputs = serializationObject.outputs;\r\n        if (serializedInputs) {\r\n            for (const port of serializedInputs) {\r\n                const input = this.inputs.find((i) => i.name === port.name);\r\n\r\n                if (!input) {\r\n                    return;\r\n                }\r\n\r\n                if (port.displayName) {\r\n                    input.displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    input.isExposedOnFrame = port.isExposedOnFrame;\r\n                    input.exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n                if (port.value !== undefined && port.value !== null) {\r\n                    if (port.valueType === \"number\") {\r\n                        input.value = port.value;\r\n                    } else {\r\n                        const valueType = GetClass(port.valueType);\r\n\r\n                        if (valueType) {\r\n                            input.value = valueType.FromArray(port.value);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        if (serializedOutputs) {\r\n            for (let i = 0; i < serializedOutputs.length; i++) {\r\n                const port = serializedOutputs[i];\r\n                if (port.displayName) {\r\n                    this.outputs[i].displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    this.outputs[i].isExposedOnFrame = port.isExposedOnFrame;\r\n                    this.outputs[i].exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _dumpPropertiesCode() {\r\n        const variableName = this._codeVariableName;\r\n        return `${variableName}.visibleOnFrame = ${this.visibleOnFrame};\\n`;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _dumpCodeForOutputConnections(alreadyDumped: NodeGeometryBlock[]) {\r\n        let codeString = \"\";\r\n\r\n        if (alreadyDumped.indexOf(this) !== -1) {\r\n            return codeString;\r\n        }\r\n\r\n        alreadyDumped.push(this);\r\n\r\n        for (const input of this.inputs) {\r\n            if (!input.isConnected) {\r\n                continue;\r\n            }\r\n\r\n            const connectedOutput = input.connectedPoint!;\r\n            const connectedBlock = connectedOutput.ownerBlock;\r\n\r\n            codeString += connectedBlock._dumpCodeForOutputConnections(alreadyDumped);\r\n            codeString += `${connectedBlock._codeVariableName}.${connectedBlock._outputRename(connectedOutput.name)}.connectTo(${this._codeVariableName}.${this._inputRename(\r\n                input.name\r\n            )});\\n`;\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _dumpCode(uniqueNames: string[], alreadyDumped: NodeGeometryBlock[]) {\r\n        alreadyDumped.push(this);\r\n\r\n        // Get unique name\r\n        const nameAsVariableName = this.name.replace(/[^A-Za-z_]+/g, \"\");\r\n        this._codeVariableName = nameAsVariableName || `${this.getClassName()}_${this.uniqueId}`;\r\n\r\n        if (uniqueNames.indexOf(this._codeVariableName) !== -1) {\r\n            let index = 0;\r\n            do {\r\n                index++;\r\n                this._codeVariableName = nameAsVariableName + index;\r\n            } while (uniqueNames.indexOf(this._codeVariableName) !== -1);\r\n        }\r\n\r\n        uniqueNames.push(this._codeVariableName);\r\n\r\n        // Declaration\r\n        let codeString = `\\n// ${this.getClassName()}\\n`;\r\n        if (this.comments) {\r\n            codeString += `// ${this.comments}\\n`;\r\n        }\r\n        const className = this.getClassName();\r\n        if (className === \"GeometryInputBlock\") {\r\n            const block = this as unknown as GeometryInputBlock;\r\n            const blockType = block.type;\r\n            codeString += `var ${this._codeVariableName} = new BABYLON.GeometryInputBlock(\"${this.name}\", ${blockType});\\n`;\r\n        } else {\r\n            codeString += `var ${this._codeVariableName} = new BABYLON.${className}(\"${this.name}\");\\n`;\r\n        }\r\n\r\n        // Properties\r\n        codeString += this._dumpPropertiesCode();\r\n\r\n        // Inputs\r\n        for (const input of this.inputs) {\r\n            if (!input.isConnected) {\r\n                continue;\r\n            }\r\n\r\n            const connectedOutput = input.connectedPoint!;\r\n            const connectedBlock = connectedOutput.ownerBlock;\r\n\r\n            if (alreadyDumped.indexOf(connectedBlock) === -1) {\r\n                codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        // Outputs\r\n        for (const output of this.outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                const connectedBlock = endpoint.ownerBlock;\r\n                if (connectedBlock && alreadyDumped.indexOf(connectedBlock) === -1) {\r\n                    codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);\r\n                }\r\n            }\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @returns a copy of the current block\r\n     */\r\n    public clone() {\r\n        const serializationObject = this.serialize();\r\n\r\n        const blockType = GetClass(serializationObject.customType);\r\n        if (blockType) {\r\n            const block: NodeGeometryBlock = new blockType();\r\n            block._deserialize(serializationObject);\r\n\r\n            return block;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        for (const input of this.inputs) {\r\n            input.dispose();\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            output.dispose();\r\n        }\r\n\r\n        this.onBuildObservable.clear();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { type VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to generate the final geometry\r\n */\r\nexport class GeometryOutputBlock extends NodeGeometryBlock {\r\n    private _vertexData: Nullable<VertexData> = null;\r\n\r\n    /**\r\n     * Gets the current vertex data if the graph was successfully built\r\n     */\r\n    public get currentVertexData() {\r\n        return this._vertexData;\r\n    }\r\n\r\n    /**\r\n     * Create a new GeometryOutputBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isUnique = true;\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryOutputBlock\";\r\n    }\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        state.vertexData = this.geometry.getConnectedValue(state);\r\n        this._vertexData = state.vertexData;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryOutputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryOutputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryOutputBlock\", GeometryOutputBlock);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/**\r\n * Defines the kind of contextual sources for node geometry\r\n */\r\nexport enum NodeGeometryContextualSources {\r\n    /** None */\r\n    None = 0x0000,\r\n    /** Positions */\r\n    Positions = 0x0001,\r\n    /** Normals */\r\n    Normals = 0x0002,\r\n    /** Tangents */\r\n    Tangents = 0x0003,\r\n    /** UV */\r\n    UV = 0x0004,\r\n    /** UV2 */\r\n    UV2 = 0x0005,\r\n    /** UV3 */\r\n    UV3 = 0x0006,\r\n    /** UV4 */\r\n    UV4 = 0x0007,\r\n    /** UV5 */\r\n    UV5 = 0x0008,\r\n    /** UV6 */\r\n    UV6 = 0x0009,\r\n    /** Colors */\r\n    Colors = 0x000a,\r\n    /** VertexID */\r\n    VertexID = 0x000b,\r\n    /** FaceID */\r\n    FaceID = 0x000c,\r\n    /** GeometryID */\r\n    GeometryID = 0x000d,\r\n    /** CollectionID */\r\n    CollectionID = 0x000e,\r\n    /** LoopID */\r\n    LoopID = 0x000f,\r\n    /** InstanceID */\r\n    InstanceID = 0x0010,\r\n    /** LatticeID */\r\n    LatticeID = 0x0011,\r\n    /** LatticeControl */\r\n    LatticeControl = 0x0012,\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { type VertexData } from \"../mesh.vertexData\";\r\nimport { type NodeGeometryConnectionPoint } from \"./nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryContextualSources } from \"./Enums/nodeGeometryContextualSources\";\r\nimport { Matrix, Vector2, Vector3, Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { type INodeGeometryExecutionContext } from \"./Interfaces/nodeGeometryExecutionContext\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"./Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type INodeGeometryInstancingContext } from \"./Interfaces/nodeGeometryInstancingContext\";\r\n\r\n/**\r\n * Class used to store node based geometry build state\r\n */\r\nexport class NodeGeometryBuildState {\r\n    private _rotationMatrix = new Matrix();\r\n    private _scalingMatrix = new Matrix();\r\n    private _positionMatrix = new Matrix();\r\n    private _scalingRotationMatrix = new Matrix();\r\n    private _transformMatrix = new Matrix();\r\n    private _tempVector3 = new Vector3();\r\n\r\n    /** Gets or sets the list of non connected mandatory inputs */\r\n    public notConnectedNonOptionalInputs: NodeGeometryConnectionPoint[] = [];\r\n    /** Gets or sets the list of non contextual inputs having no contextudal data */\r\n    public noContextualData: NodeGeometryContextualSources[] = [];\r\n    /** Gets or sets the build identifier */\r\n    public buildId: number;\r\n    /** Gets or sets a boolean indicating that verbose mode is on */\r\n    public verbose: boolean;\r\n    /** Gets or sets the vertex data */\r\n    public vertexData: Nullable<VertexData> = null;\r\n\r\n    private _geometryContext: Nullable<VertexData> = null;\r\n    private _executionContext: Nullable<INodeGeometryExecutionContext> = null;\r\n    private _instancingContext: Nullable<INodeGeometryInstancingContext> = null;\r\n\r\n    private _geometryContextStack: Array<Nullable<VertexData>> = [];\r\n    private _executionContextStack: Array<Nullable<INodeGeometryExecutionContext>> = [];\r\n    private _instancingContextStack: Array<Nullable<INodeGeometryInstancingContext>> = [];\r\n\r\n    /** Gets or sets the geometry context */\r\n    public get geometryContext() {\r\n        return this._geometryContext;\r\n    }\r\n\r\n    /** Gets or sets the execution context */\r\n    public get executionContext() {\r\n        return this._executionContext;\r\n    }\r\n\r\n    /** Gets or sets the instancing context */\r\n    public get instancingContext() {\r\n        return this._instancingContext;\r\n    }\r\n\r\n    /**\r\n     * Push the new active geometry context\r\n     * @param geometryContext defines the geometry context\r\n     */\r\n    public pushGeometryContext(geometryContext: VertexData) {\r\n        this._geometryContext = geometryContext;\r\n        this._geometryContextStack.push(this._geometryContext);\r\n    }\r\n\r\n    /**\r\n     * Push the new active execution context\r\n     * @param executionContext defines the execution context\r\n     */\r\n    public pushExecutionContext(executionContext: INodeGeometryExecutionContext) {\r\n        this._executionContext = executionContext;\r\n        this._executionContextStack.push(this._executionContext);\r\n    }\r\n\r\n    /**\r\n     * Push the new active instancing context\r\n     * @param instancingContext defines the instancing context\r\n     */\r\n    public pushInstancingContext(instancingContext: INodeGeometryInstancingContext) {\r\n        this._instancingContext = instancingContext;\r\n        this._instancingContextStack.push(this._instancingContext);\r\n    }\r\n\r\n    /**\r\n     * Remove current geometry context and restore the previous one\r\n     */\r\n    public restoreGeometryContext() {\r\n        this._geometryContextStack.pop();\r\n        this._geometryContext = this._geometryContextStack.length > 0 ? this._geometryContextStack[this._geometryContextStack.length - 1] : null;\r\n    }\r\n\r\n    /**\r\n     * Remove current execution context and restore the previous one\r\n     */\r\n    public restoreExecutionContext() {\r\n        this._executionContextStack.pop();\r\n        this._executionContext = this._executionContextStack.length > 0 ? this._executionContextStack[this._executionContextStack.length - 1] : null;\r\n    }\r\n\r\n    /**\r\n     * Remove current isntancing context and restore the previous one\r\n     */\r\n    public restoreInstancingContext() {\r\n        this._instancingContextStack.pop();\r\n        this._instancingContext = this._instancingContextStack.length > 0 ? this._instancingContextStack[this._instancingContextStack.length - 1] : null;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual source\r\n     * @param source Source of the contextual value\r\n     * @param skipWarning Do not store the warning for reporting if true\r\n     * @returns the value associated with the source\r\n     */\r\n    public getContextualValue(source: NodeGeometryContextualSources, skipWarning = false) {\r\n        if (!this.executionContext) {\r\n            if (!skipWarning) {\r\n                this.noContextualData.push(source);\r\n            }\r\n            return null;\r\n        }\r\n\r\n        const index = this.executionContext.getExecutionIndex();\r\n\r\n        switch (source) {\r\n            case NodeGeometryContextualSources.Positions:\r\n                if (this.executionContext.getOverridePositionsContextualValue) {\r\n                    return this.executionContext.getOverridePositionsContextualValue();\r\n                }\r\n                if (!this.geometryContext || !this.geometryContext.positions) {\r\n                    return Vector3.Zero();\r\n                }\r\n                return Vector3.FromArray(this.geometryContext.positions as ArrayLike<number>, index * 3);\r\n            case NodeGeometryContextualSources.Normals:\r\n                if (this.executionContext.getOverrideNormalsContextualValue) {\r\n                    return this.executionContext.getOverrideNormalsContextualValue();\r\n                }\r\n                if (!this.geometryContext || !this.geometryContext.normals) {\r\n                    return Vector3.Zero();\r\n                }\r\n                return Vector3.FromArray(this.geometryContext.normals as ArrayLike<number>, index * 3);\r\n            case NodeGeometryContextualSources.Colors:\r\n                if (!this.geometryContext || !this.geometryContext.colors) {\r\n                    return Vector4.Zero();\r\n                }\r\n                return Vector4.FromArray(this.geometryContext.colors as ArrayLike<number>, index * 4);\r\n            case NodeGeometryContextualSources.Tangents:\r\n                if (!this.geometryContext || !this.geometryContext.tangents) {\r\n                    return Vector4.Zero();\r\n                }\r\n                return Vector4.FromArray(this.geometryContext.tangents as ArrayLike<number>, index * 4);\r\n            case NodeGeometryContextualSources.UV:\r\n                if (this.executionContext.getOverrideUVs1ContextualValue) {\r\n                    return this.executionContext.getOverrideUVs1ContextualValue();\r\n                }\r\n                if (!this.geometryContext || !this.geometryContext.uvs) {\r\n                    return Vector2.Zero();\r\n                }\r\n                return Vector2.FromArray(this.geometryContext.uvs as ArrayLike<number>, index * 2);\r\n            case NodeGeometryContextualSources.UV2:\r\n                if (!this.geometryContext || !this.geometryContext.uvs2) {\r\n                    return Vector2.Zero();\r\n                }\r\n                return Vector2.FromArray(this.geometryContext.uvs2 as ArrayLike<number>, index * 2);\r\n            case NodeGeometryContextualSources.UV3:\r\n                if (!this.geometryContext || !this.geometryContext.uvs3) {\r\n                    return Vector2.Zero();\r\n                }\r\n                return Vector2.FromArray(this.geometryContext.uvs3 as ArrayLike<number>, index * 2);\r\n            case NodeGeometryContextualSources.UV4:\r\n                if (!this.geometryContext || !this.geometryContext.uvs4) {\r\n                    return Vector2.Zero();\r\n                }\r\n                return Vector2.FromArray(this.geometryContext.uvs4 as ArrayLike<number>, index * 2);\r\n            case NodeGeometryContextualSources.UV5:\r\n                if (!this.geometryContext || !this.geometryContext.uvs5) {\r\n                    return Vector2.Zero();\r\n                }\r\n                return Vector2.FromArray(this.geometryContext.uvs5 as ArrayLike<number>, index * 2);\r\n            case NodeGeometryContextualSources.UV6:\r\n                if (!this.geometryContext || !this.geometryContext.uvs6) {\r\n                    return Vector2.Zero();\r\n                }\r\n                return Vector2.FromArray(this.geometryContext.uvs6 as ArrayLike<number>, index * 2);\r\n            case NodeGeometryContextualSources.VertexID:\r\n                return index;\r\n            case NodeGeometryContextualSources.FaceID:\r\n                return this.executionContext.getExecutionFaceIndex();\r\n            case NodeGeometryContextualSources.LoopID:\r\n                return this.executionContext.getExecutionLoopIndex();\r\n            case NodeGeometryContextualSources.InstanceID:\r\n                return this.instancingContext ? this.instancingContext.getInstanceIndex() : 0;\r\n            case NodeGeometryContextualSources.GeometryID:\r\n                return !this.geometryContext ? 0 : this.geometryContext.uniqueId;\r\n            case NodeGeometryContextualSources.CollectionID: {\r\n                if (!this.geometryContext || !this.geometryContext.metadata) {\r\n                    return 0;\r\n                }\r\n                return this.geometryContext.metadata.collectionId || 0;\r\n            }\r\n            case NodeGeometryContextualSources.LatticeID: {\r\n                if (this.executionContext.getOverridePositionsContextualValue) {\r\n                    return this.executionContext.getOverridePositionsContextualValue();\r\n                }\r\n                return Vector3.Zero();\r\n            }\r\n            case NodeGeometryContextualSources.LatticeControl: {\r\n                if (this.executionContext.getOverrideNormalsContextualValue) {\r\n                    return this.executionContext.getOverrideNormalsContextualValue();\r\n                }\r\n                return Vector3.Zero();\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Adapt a value to a target type\r\n     * @param source defines the value to adapt\r\n     * @param targetType defines the target type\r\n     * @returns the adapted value\r\n     */\r\n    adapt(source: NodeGeometryConnectionPoint, targetType: NodeGeometryBlockConnectionPointTypes) {\r\n        const value = source.getConnectedValue(this) || 0;\r\n\r\n        if (source.type === targetType) {\r\n            return value;\r\n        }\r\n\r\n        switch (targetType) {\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                return new Vector2(value, value);\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                return new Vector3(value, value, value);\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                return new Vector4(value, value, value, value);\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Adapt an input value to a target type\r\n     * @param source defines the value to adapt\r\n     * @param targetType defines the target type\r\n     * @param defaultValue defines the default value to use if not connected\r\n     * @returns the adapted value\r\n     */\r\n    adaptInput(source: NodeGeometryConnectionPoint, targetType: NodeGeometryBlockConnectionPointTypes, defaultValue: any) {\r\n        if (!source.isConnected) {\r\n            return source.value || defaultValue;\r\n        }\r\n\r\n        const value = source.getConnectedValue(this);\r\n\r\n        if (source._connectedPoint?.type === targetType) {\r\n            return value;\r\n        }\r\n\r\n        switch (targetType) {\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                return new Vector2(value, value);\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                return new Vector3(value, value, value);\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                return new Vector4(value, value, value, value);\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Emits console errors and exceptions if there is a failing check\r\n     */\r\n    public emitErrors() {\r\n        let errorMessage = \"\";\r\n\r\n        for (const notConnectedInput of this.notConnectedNonOptionalInputs) {\r\n            errorMessage += `input ${notConnectedInput.name} from block ${\r\n                notConnectedInput.ownerBlock.name\r\n            }[${notConnectedInput.ownerBlock.getClassName()}] is not connected and is not optional.\\n`;\r\n        }\r\n\r\n        for (const source of this.noContextualData) {\r\n            errorMessage += `Contextual input ${NodeGeometryContextualSources[source]} has no context to pull data from (must be connected to a setXXX block or a instantiateXXX block).\\n`;\r\n        }\r\n\r\n        if (errorMessage) {\r\n            throw \"Build of NodeGeometry failed:\\n\" + errorMessage;\r\n        }\r\n    }\r\n\r\n    /** @internal  */\r\n    public _instantiate(clone: VertexData, currentPosition: Vector3, rotation: Vector3, scaling: Vector3, additionalVertexData: VertexData[]) {\r\n        // Transform\r\n        Matrix.ScalingToRef(scaling.x, scaling.y, scaling.z, this._scalingMatrix);\r\n        Matrix.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, this._rotationMatrix);\r\n        Matrix.TranslationToRef(currentPosition.x, currentPosition.y, currentPosition.z, this._positionMatrix);\r\n\r\n        this._scalingMatrix.multiplyToRef(this._rotationMatrix, this._scalingRotationMatrix);\r\n        this._scalingRotationMatrix.multiplyToRef(this._positionMatrix, this._transformMatrix);\r\n        for (let clonePositionIndex = 0; clonePositionIndex < clone.positions!.length; clonePositionIndex += 3) {\r\n            this._tempVector3.fromArray(clone.positions!, clonePositionIndex);\r\n            Vector3.TransformCoordinatesToRef(this._tempVector3, this._transformMatrix, this._tempVector3);\r\n            this._tempVector3.toArray(clone.positions!, clonePositionIndex);\r\n\r\n            if (clone.normals) {\r\n                this._tempVector3.fromArray(clone.normals, clonePositionIndex);\r\n                Vector3.TransformNormalToRef(this._tempVector3, this._scalingRotationMatrix, this._tempVector3);\r\n                this._tempVector3.toArray(clone.normals, clonePositionIndex);\r\n            }\r\n        }\r\n\r\n        additionalVertexData.push(clone);\r\n    }\r\n\r\n    /** @internal  */\r\n    public _instantiateWithMatrix(clone: VertexData, transform: Matrix, additionalVertexData: VertexData[]) {\r\n        for (let clonePositionIndex = 0; clonePositionIndex < clone.positions!.length; clonePositionIndex += 3) {\r\n            this._tempVector3.fromArray(clone.positions!, clonePositionIndex);\r\n            Vector3.TransformCoordinatesToRef(this._tempVector3, transform, this._tempVector3);\r\n            this._tempVector3.toArray(clone.positions!, clonePositionIndex);\r\n\r\n            if (clone.normals) {\r\n                this._tempVector3.fromArray(clone.normals, clonePositionIndex);\r\n                Vector3.TransformNormalToRef(this._tempVector3, transform, this._tempVector3);\r\n                this._tempVector3.toArray(clone.normals, clonePositionIndex);\r\n            }\r\n        }\r\n\r\n        additionalVertexData.push(clone);\r\n    }\r\n\r\n    /** @internal  */\r\n    public _instantiateWithPositionAndMatrix(clone: VertexData, currentPosition: Vector3, transform: Matrix, additionalVertexData: VertexData[]) {\r\n        Matrix.TranslationToRef(currentPosition.x, currentPosition.y, currentPosition.z, this._positionMatrix);\r\n        transform.multiplyToRef(this._positionMatrix, this._transformMatrix);\r\n\r\n        for (let clonePositionIndex = 0; clonePositionIndex < clone.positions!.length; clonePositionIndex += 3) {\r\n            this._tempVector3.fromArray(clone.positions!, clonePositionIndex);\r\n            Vector3.TransformCoordinatesToRef(this._tempVector3, this._transformMatrix, this._tempVector3);\r\n            this._tempVector3.toArray(clone.positions!, clonePositionIndex);\r\n\r\n            if (clone.normals) {\r\n                this._tempVector3.fromArray(clone.normals, clonePositionIndex);\r\n                Vector3.TransformNormalToRef(this._tempVector3, this._transformMatrix, this._tempVector3);\r\n                this._tempVector3.toArray(clone.normals, clonePositionIndex);\r\n            }\r\n        }\r\n\r\n        additionalVertexData.push(clone);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../../../Misc/observable.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { GetClass, RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { Matrix, Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { NodeGeometryContextualSources } from \"../Enums/nodeGeometryContextualSources\";\r\n\r\n/**\r\n * Block used to expose an input value\r\n */\r\nexport class GeometryInputBlock extends NodeGeometryBlock {\r\n    private _storedValue: any;\r\n    private _valueCallback: () => any;\r\n    private _type: NodeGeometryBlockConnectionPointTypes = NodeGeometryBlockConnectionPointTypes.Undefined;\r\n    private _contextualSource = NodeGeometryContextualSources.None;\r\n\r\n    /** Gets or set a value used to limit the range of float values */\r\n    public min: number = 0;\r\n\r\n    /** Gets or set a value used to limit the range of float values */\r\n    public max: number = 0;\r\n\r\n    /** Gets or sets the group to use to display this block in the Inspector */\r\n    public groupInInspector = \"\";\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this input is displayed in the Inspector\r\n     */\r\n    public displayInInspector = true;\r\n\r\n    /** Gets an observable raised when the value is changed */\r\n    public onValueChangedObservable = new Observable<GeometryInputBlock>();\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is float)\r\n     */\r\n    public get type(): NodeGeometryBlockConnectionPointTypes {\r\n        if (this._type === NodeGeometryBlockConnectionPointTypes.AutoDetect) {\r\n            if (this.value != null) {\r\n                if (!isNaN(this.value)) {\r\n                    this._type = NodeGeometryBlockConnectionPointTypes.Float;\r\n                    return this._type;\r\n                }\r\n\r\n                switch (this.value.getClassName()) {\r\n                    case \"Vector2\":\r\n                        this._type = NodeGeometryBlockConnectionPointTypes.Vector2;\r\n                        return this._type;\r\n                    case \"Vector3\":\r\n                        this._type = NodeGeometryBlockConnectionPointTypes.Vector3;\r\n                        return this._type;\r\n                    case \"Vector4\":\r\n                        this._type = NodeGeometryBlockConnectionPointTypes.Vector4;\r\n                        return this._type;\r\n                    case \"Matrix\":\r\n                        this._type = NodeGeometryBlockConnectionPointTypes.Matrix;\r\n                        return this._type;\r\n                }\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current connection point is a contextual value\r\n     */\r\n    public get isContextual(): boolean {\r\n        return this._contextualSource !== NodeGeometryContextualSources.None;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current contextual value\r\n     */\r\n    public get contextualValue(): NodeGeometryContextualSources {\r\n        return this._contextualSource;\r\n    }\r\n\r\n    public set contextualValue(value: NodeGeometryContextualSources) {\r\n        this._contextualSource = value;\r\n\r\n        switch (value) {\r\n            case NodeGeometryContextualSources.Positions:\r\n            case NodeGeometryContextualSources.Normals:\r\n            case NodeGeometryContextualSources.LatticeID:\r\n            case NodeGeometryContextualSources.LatticeControl:\r\n                this._type = NodeGeometryBlockConnectionPointTypes.Vector3;\r\n                break;\r\n            case NodeGeometryContextualSources.Colors:\r\n            case NodeGeometryContextualSources.Tangents:\r\n                this._type = NodeGeometryBlockConnectionPointTypes.Vector4;\r\n                break;\r\n            case NodeGeometryContextualSources.UV:\r\n            case NodeGeometryContextualSources.UV2:\r\n            case NodeGeometryContextualSources.UV3:\r\n            case NodeGeometryContextualSources.UV4:\r\n            case NodeGeometryContextualSources.UV5:\r\n            case NodeGeometryContextualSources.UV6:\r\n                this._type = NodeGeometryBlockConnectionPointTypes.Vector2;\r\n                break;\r\n            case NodeGeometryContextualSources.VertexID:\r\n            case NodeGeometryContextualSources.GeometryID:\r\n            case NodeGeometryContextualSources.CollectionID:\r\n            case NodeGeometryContextualSources.FaceID:\r\n            case NodeGeometryContextualSources.LoopID:\r\n            case NodeGeometryContextualSources.InstanceID:\r\n                this._type = NodeGeometryBlockConnectionPointTypes.Int;\r\n                break;\r\n        }\r\n\r\n        if (this.output) {\r\n            this.output.type = this._type;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new InputBlock\r\n     * @param name defines the block name\r\n     * @param type defines the type of the input (can be set to NodeGeometryBlockConnectionPointTypes.AutoDetect)\r\n     */\r\n    public constructor(name: string, type: NodeGeometryBlockConnectionPointTypes = NodeGeometryBlockConnectionPointTypes.AutoDetect) {\r\n        super(name);\r\n\r\n        this._type = type;\r\n        this._isInput = true;\r\n\r\n        this.setDefaultValue();\r\n\r\n        this.registerOutput(\"output\", type);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the value of that point.\r\n     * Please note that this value will be ignored if valueCallback is defined\r\n     */\r\n    public get value(): any {\r\n        return this._storedValue;\r\n    }\r\n\r\n    public set value(value: any) {\r\n        if (this.type === NodeGeometryBlockConnectionPointTypes.Float) {\r\n            if (this.min !== this.max) {\r\n                value = Math.max(this.min, value);\r\n                value = Math.min(this.max, value);\r\n            }\r\n        }\r\n\r\n        this._storedValue = value;\r\n\r\n        this.onValueChangedObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a callback used to get the value of that point.\r\n     * Please note that setting this value will force the connection point to ignore the value property\r\n     */\r\n    public get valueCallback(): () => any {\r\n        return this._valueCallback;\r\n    }\r\n\r\n    public set valueCallback(value: () => any) {\r\n        this._valueCallback = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryInputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Set the input block to its default value (based on its type)\r\n     */\r\n    public setDefaultValue() {\r\n        this.contextualValue = NodeGeometryContextualSources.None;\r\n        switch (this.type) {\r\n            case NodeGeometryBlockConnectionPointTypes.Int:\r\n            case NodeGeometryBlockConnectionPointTypes.Float:\r\n                this.value = 0;\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                this.value = Vector2.Zero();\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                this.value = Vector3.Zero();\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                this.value = Vector4.Zero();\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Matrix:\r\n                this.value = Matrix.Identity();\r\n                break;\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (this.isContextual) {\r\n            this.output._storedValue = null;\r\n            this.output._storedFunction = (state) => {\r\n                return state.getContextualValue(this._contextualSource);\r\n            };\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = this.value;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override dispose() {\r\n        this.onValueChangedObservable.clear();\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const variableName = this._codeVariableName;\r\n\r\n        if (this.isContextual) {\r\n            return (\r\n                super._dumpPropertiesCode() + `${variableName}.contextualValue = BABYLON.NodeGeometryContextualSources.${NodeGeometryContextualSources[this._contextualSource]};\\n`\r\n            );\r\n        }\r\n        const codes: string[] = [];\r\n\r\n        let valueString = \"\";\r\n\r\n        switch (this.type) {\r\n            case NodeGeometryBlockConnectionPointTypes.Float:\r\n            case NodeGeometryBlockConnectionPointTypes.Int:\r\n                valueString = `${this.value}`;\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                valueString = `new BABYLON.Vector2(${this.value.x}, ${this.value.y})`;\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                valueString = `new BABYLON.Vector3(${this.value.x}, ${this.value.y}, ${this.value.z})`;\r\n                break;\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                valueString = `new BABYLON.Vector4(${this.value.x}, ${this.value.y}, ${this.value.z}, ${this.value.w})`;\r\n                break;\r\n        }\r\n\r\n        // Common Property \"Value\"\r\n        codes.push(`${variableName}.value = ${valueString}`);\r\n\r\n        // Float-Value-Specific Properties\r\n        if (this.type === NodeGeometryBlockConnectionPointTypes.Float || this.type === NodeGeometryBlockConnectionPointTypes.Int) {\r\n            codes.push(`${variableName}.min = ${this.min}`, `${variableName}.max = ${this.max}`);\r\n        }\r\n\r\n        codes.push(\"\");\r\n\r\n        return super._dumpPropertiesCode() + codes.join(\";\\n\");\r\n    }\r\n\r\n    /** @internal */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.type = this.type;\r\n        serializationObject.contextualValue = this.contextualValue;\r\n        serializationObject.min = this.min;\r\n        serializationObject.max = this.max;\r\n        serializationObject.groupInInspector = this.groupInInspector;\r\n        serializationObject.displayInInspector = this.displayInInspector;\r\n\r\n        if (this._storedValue !== null && !this.isContextual) {\r\n            if (this._storedValue.asArray) {\r\n                serializationObject.valueType = \"BABYLON.\" + this._storedValue.getClassName();\r\n                serializationObject.value = this._storedValue.asArray();\r\n            } else {\r\n                serializationObject.valueType = \"number\";\r\n                serializationObject.value = this._storedValue;\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this._type = serializationObject.type;\r\n\r\n        this.contextualValue = serializationObject.contextualValue;\r\n        this.min = serializationObject.min || 0;\r\n        this.max = serializationObject.max || 0;\r\n        this.groupInInspector = serializationObject.groupInInspector || \"\";\r\n        if (serializationObject.displayInInspector !== undefined) {\r\n            this.displayInInspector = serializationObject.displayInInspector;\r\n        }\r\n\r\n        if (!serializationObject.valueType) {\r\n            return;\r\n        }\r\n\r\n        if (serializationObject.valueType === \"number\") {\r\n            this._storedValue = serializationObject.value;\r\n        } else {\r\n            const valueType = GetClass(serializationObject.valueType);\r\n\r\n            if (valueType) {\r\n                this._storedValue = valueType.FromArray(serializationObject.value);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryInputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryInputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryInputBlock\", GeometryInputBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { CreateSegmentedBoxVertexData } from \"core/Meshes/Builders/boxBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate box geometry data\r\n */\r\nexport class BoxBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new BoxBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"size\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"width\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"height\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"depth\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"subdivisions\", NodeGeometryBlockConnectionPointTypes.Int, true, 1, 0);\r\n        this.registerInput(\"subdivisionsX\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n        this.registerInput(\"subdivisionsY\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n        this.registerInput(\"subdivisionsZ\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BoxBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the size input component\r\n     */\r\n    public get size(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the width input component\r\n     */\r\n    public get width(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the height input component\r\n     */\r\n    public get height(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth input component\r\n     */\r\n    public get depth(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisions input component\r\n     */\r\n    public get subdivisions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsX input component\r\n     */\r\n    public get subdivisionsX(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsY input component\r\n     */\r\n    public get subdivisionsY(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsZ input component\r\n     */\r\n    public get subdivisionsZ(): NodeGeometryConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (this.size.isConnected) {\r\n            return;\r\n        }\r\n\r\n        if (!this.width.isConnected && !this.height.isConnected && !this.depth.isConnected) {\r\n            const sizeInput = new GeometryInputBlock(\"Size\");\r\n            sizeInput.value = 1;\r\n            sizeInput.output.connectTo(this.size);\r\n            return;\r\n        }\r\n\r\n        if (!this.width.isConnected) {\r\n            const widthInput = new GeometryInputBlock(\"Width\");\r\n            widthInput.value = 1;\r\n            widthInput.output.connectTo(this.width);\r\n        }\r\n\r\n        if (!this.height.isConnected) {\r\n            const heightInput = new GeometryInputBlock(\"Height\");\r\n            heightInput.value = 1;\r\n            heightInput.output.connectTo(this.height);\r\n        }\r\n\r\n        if (!this.depth.isConnected) {\r\n            const depthInput = new GeometryInputBlock(\"Depth\");\r\n            depthInput.value = 1;\r\n            depthInput.output.connectTo(this.depth);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            size?: number;\r\n            width?: number;\r\n            height?: number;\r\n            depth?: number;\r\n            segments?: number;\r\n            widthSegments?: number;\r\n            heightSegments?: number;\r\n            depthSegments?: number;\r\n        } = {};\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.size = this.size.getConnectedValue(state);\r\n            options.width = this.width.getConnectedValue(state);\r\n            options.height = this.height.getConnectedValue(state);\r\n            options.depth = this.depth.getConnectedValue(state);\r\n\r\n            const subdivisions = this.subdivisions.getConnectedValue(state);\r\n            const subdivisionsX = this.subdivisionsX.getConnectedValue(state);\r\n            const subdivisionsY = this.subdivisionsY.getConnectedValue(state);\r\n            const subdivisionsZ = this.subdivisionsZ.getConnectedValue(state);\r\n\r\n            if (subdivisions) {\r\n                options.segments = subdivisions;\r\n            }\r\n\r\n            if (subdivisionsX) {\r\n                options.widthSegments = subdivisionsX;\r\n            }\r\n\r\n            if (subdivisionsY) {\r\n                options.heightSegments = subdivisionsY;\r\n            }\r\n\r\n            if (subdivisionsZ) {\r\n                options.depthSegments = subdivisionsZ;\r\n            }\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateSegmentedBoxVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for boxBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBoxBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BoxBlock\", BoxBlock);\r\n}\r\n","import { Observable } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { type VertexData } from \"../mesh.vertexData\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { GeometryOutputBlock } from \"./Blocks/geometryOutputBlock.pure\";\r\nimport { type NodeGeometryBlock } from \"./nodeGeometryBlock\";\r\nimport { NodeGeometryBuildState } from \"./nodeGeometryBuildState\";\r\nimport { GetClass } from \"../../Misc/typeStore\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { WebRequest } from \"../../Misc/webRequest\";\r\nimport { BoxBlock } from \"./Blocks/Sources/boxBlock.pure\";\r\nimport { type GeometryInputBlock } from \"./Blocks/geometryInputBlock\";\r\nimport { PrecisionDate } from \"../../Misc/precisionDate\";\r\nimport { type TeleportOutBlock } from \"./Blocks/Teleport/teleportOutBlock\";\r\nimport { type TeleportInBlock } from \"./Blocks/Teleport/teleportInBlock\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type Color4 } from \"../../Maths/math.color\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n// declare NODEGEOMETRYEDITOR namespace for compilation issue\r\ndeclare let NODEGEOMETRYEDITOR: any;\r\ndeclare let BABYLON: any;\r\n\r\n/**\r\n * Interface used to configure the node geometry editor\r\n */\r\nexport interface INodeGeometryEditorOptions {\r\n    /** Define the URL to load node editor script from */\r\n    editorURL?: string;\r\n    /** Additional configuration for the NGE */\r\n    nodeGeometryEditorConfig?: {\r\n        backgroundColor?: Color4;\r\n        hostScene?: Scene;\r\n        hostMesh?: Mesh;\r\n    };\r\n}\r\n\r\n/**\r\n * Defines a node based geometry\r\n * @see demo at https://playground.babylonjs.com#PYY6XE#69\r\n */\r\nexport class NodeGeometry {\r\n    private static _BuildIdGenerator: number = 0;\r\n    private _buildId: number = NodeGeometry._BuildIdGenerator++;\r\n    private _buildWasSuccessful = false;\r\n    private _vertexData: Nullable<VertexData> = null;\r\n    private _buildExecutionTime: number = 0;\r\n\r\n    /** Define the Url to load node editor script */\r\n    public static EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/nodeGeometryEditor/babylon.nodeGeometryEditor.js`;\r\n\r\n    /** Define the Url to load snippets */\r\n    public static SnippetUrl = Constants.SnippetUrl;\r\n\r\n    private BJSNODEGEOMETRYEDITOR = this._getGlobalNodeGeometryEditor();\r\n\r\n    /** @returns the inspector from bundle or global */\r\n    private _getGlobalNodeGeometryEditor(): any {\r\n        // UMD global name detection from bundle metadata.\r\n        // Note: rollup-built UMD bundles do not expose the editor class\r\n        // directly on the namespace - it lives on `.default.NodeGeometryEditor` -\r\n        // so we unwrap that case before falling back to the BABYLON global.\r\n        if (typeof NODEGEOMETRYEDITOR !== \"undefined\") {\r\n            if ((NODEGEOMETRYEDITOR as any).NodeGeometryEditor) {\r\n                return NODEGEOMETRYEDITOR;\r\n            }\r\n            if ((NODEGEOMETRYEDITOR as any).default?.NodeGeometryEditor) {\r\n                return (NODEGEOMETRYEDITOR as any).default;\r\n            }\r\n        }\r\n\r\n        // In case of module let's check the global emitted from the editor entry point.\r\n        if (typeof BABYLON !== \"undefined\" && typeof BABYLON.NodeGeometryEditor !== \"undefined\") {\r\n            return BABYLON;\r\n        }\r\n\r\n        return undefined;\r\n    }\r\n\r\n    /**\r\n     * Gets the time spent to build this block (in ms)\r\n     */\r\n    public get buildExecutionTime() {\r\n        return this._buildExecutionTime;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets data used by visual editor\r\n     * @see https://nge.babylonjs.com\r\n     */\r\n    public editorData: any = null;\r\n\r\n    /**\r\n     * Gets an array of blocks that needs to be serialized even if they are not yet connected\r\n     */\r\n    public attachedBlocks: NodeGeometryBlock[] = [];\r\n\r\n    /**\r\n     * Observable raised when the geometry is built\r\n     */\r\n    public onBuildObservable = new Observable<NodeGeometry>();\r\n\r\n    /** Gets or sets the GeometryOutputBlock used to gather the final geometry data */\r\n    public outputBlock: Nullable<GeometryOutputBlock> = null;\r\n\r\n    /**\r\n     * Snippet ID if the material was created from the snippet server\r\n     */\r\n    public snippetId: string;\r\n\r\n    /**\r\n     * The name of the geometry\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * A free comment about the geometry\r\n     */\r\n    @serialize(\"comment\")\r\n    public comment: string;\r\n\r\n    /**\r\n     * Creates a new geometry\r\n     * @param name defines the name of the geometry\r\n     */\r\n    public constructor(name: string) {\r\n        this.name = name;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name of the geometry e.g. \"NodeGeometry\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeGeometry\";\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex data. This needs to be done after build() was called.\r\n     * This is used to access vertexData when creating a mesh is not required.\r\n     */\r\n    public get vertexData() {\r\n        return this._vertexData;\r\n    }\r\n\r\n    /**\r\n     * Get a block by its name\r\n     * @param name defines the name of the block to retrieve\r\n     * @returns the required block or null if not found\r\n     */\r\n    public getBlockByName(name: string) {\r\n        let result = null;\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.name === name) {\r\n                if (!result) {\r\n                    result = block;\r\n                } else {\r\n                    Tools.Warn(\"More than one block was found with the name `\" + name + \"`\");\r\n                    return result;\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Get a block using a predicate\r\n     * @param predicate defines the predicate used to find the good candidate\r\n     * @returns the required block or null if not found\r\n     */\r\n    public getBlockByPredicate(predicate: (block: NodeGeometryBlock) => boolean) {\r\n        for (const block of this.attachedBlocks) {\r\n            if (predicate(block)) {\r\n                return block;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of input blocks attached to this material\r\n     * @returns an array of InputBlocks\r\n     */\r\n    public getInputBlocks() {\r\n        const blocks: GeometryInputBlock[] = [];\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isInput) {\r\n                blocks.push(block as GeometryInputBlock);\r\n            }\r\n        }\r\n\r\n        return blocks;\r\n    }\r\n\r\n    /**\r\n     * Launch the node geometry editor\r\n     * @param config Define the configuration of the editor\r\n     * @returns a promise fulfilled when the node editor is visible\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async edit(config?: INodeGeometryEditorOptions): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            this.BJSNODEGEOMETRYEDITOR = this.BJSNODEGEOMETRYEDITOR || this._getGlobalNodeGeometryEditor();\r\n            if (typeof this.BJSNODEGEOMETRYEDITOR == \"undefined\") {\r\n                const editorUrl = config && config.editorURL ? config.editorURL : NodeGeometry.EditorURL;\r\n\r\n                // Load editor and add it to the DOM\r\n                Tools.LoadBabylonScript(editorUrl, () => {\r\n                    this.BJSNODEGEOMETRYEDITOR = this.BJSNODEGEOMETRYEDITOR || this._getGlobalNodeGeometryEditor();\r\n                    this._createNodeEditor(config?.nodeGeometryEditorConfig);\r\n                    resolve();\r\n                });\r\n            } else {\r\n                // Otherwise creates the editor\r\n                this._createNodeEditor(config?.nodeGeometryEditorConfig);\r\n                resolve();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates the node editor window.\r\n     * @param additionalConfig Additional configuration for the NGE\r\n     */\r\n    private _createNodeEditor(additionalConfig?: any) {\r\n        const nodeEditorConfig: any = {\r\n            nodeGeometry: this,\r\n            ...additionalConfig,\r\n        };\r\n        this.BJSNODEGEOMETRYEDITOR.NodeGeometryEditor.Show(nodeEditorConfig);\r\n    }\r\n\r\n    /**\r\n     * Build the final geometry. Please note that the geometry MAY not be ready until the onBuildObservable is raised.\r\n     * @param verbose defines if the build should log activity\r\n     * @param updateBuildId defines if the internal build Id should be updated (default is true)\r\n     * @param autoConfigure defines if the autoConfigure method should be called when initializing blocks (default is false)\r\n     */\r\n    public build(verbose: boolean = false, updateBuildId = true, autoConfigure = false) {\r\n        this._buildWasSuccessful = false;\r\n\r\n        if (!this.outputBlock) {\r\n            throw \"You must define the outputBlock property before building the geometry\";\r\n        }\r\n        const now = PrecisionDate.Now;\r\n        // Initialize blocks\r\n        this._initializeBlock(this.outputBlock, autoConfigure);\r\n\r\n        // Check async states\r\n        const promises: Promise<void>[] = [];\r\n        for (const block of this.attachedBlocks) {\r\n            if (block._isReadyState) {\r\n                promises.push(block._isReadyState);\r\n            }\r\n        }\r\n\r\n        if (promises.length) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            Promise.all(promises).then(() => {\r\n                this.build(verbose, updateBuildId, autoConfigure);\r\n            });\r\n            return;\r\n        }\r\n\r\n        // Build\r\n        const state = new NodeGeometryBuildState();\r\n\r\n        state.buildId = this._buildId;\r\n        state.verbose = verbose;\r\n\r\n        try {\r\n            this.outputBlock.build(state);\r\n        } finally {\r\n            if (updateBuildId) {\r\n                this._buildId = NodeGeometry._BuildIdGenerator++;\r\n            }\r\n        }\r\n\r\n        this._buildExecutionTime = PrecisionDate.Now - now;\r\n\r\n        // Errors\r\n        state.emitErrors();\r\n\r\n        this._buildWasSuccessful = true;\r\n        this._vertexData = state.vertexData;\r\n        this.onBuildObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Creates a mesh from the geometry blocks\r\n     * @param name defines the name of the mesh\r\n     * @param scene The scene the mesh is scoped to\r\n     * @returns The new mesh\r\n     */\r\n    public createMesh(name: string, scene: Nullable<Scene> = null): Nullable<Mesh> {\r\n        if (!this._buildWasSuccessful) {\r\n            this.build();\r\n        }\r\n\r\n        if (!this._vertexData) {\r\n            return null;\r\n        }\r\n\r\n        const mesh = new Mesh(name, scene);\r\n        this._vertexData.applyToMesh(mesh);\r\n\r\n        mesh._internalMetadata = mesh._internalMetadata || {};\r\n        mesh._internalMetadata.nodeGeometry = this;\r\n\r\n        return mesh;\r\n    }\r\n\r\n    /**\r\n     * Creates a mesh from the geometry blocks\r\n     * @param mesh the mesh to update\r\n     * @returns True if successfully updated\r\n     */\r\n    public updateMesh(mesh: Mesh) {\r\n        if (!this._buildWasSuccessful) {\r\n            this.build();\r\n        }\r\n\r\n        if (!this._vertexData) {\r\n            return false;\r\n        }\r\n\r\n        this._vertexData.applyToMesh(mesh);\r\n\r\n        mesh._internalMetadata = mesh._internalMetadata || {};\r\n        mesh._internalMetadata.nodeGeometry = this;\r\n\r\n        return mesh;\r\n    }\r\n\r\n    private _initializeBlock(node: NodeGeometryBlock, autoConfigure = true) {\r\n        node.initialize();\r\n        if (autoConfigure) {\r\n            node.autoConfigure(this);\r\n        }\r\n        node._preparationId = this._buildId;\r\n\r\n        if (this.attachedBlocks.indexOf(node) === -1) {\r\n            this.attachedBlocks.push(node);\r\n        }\r\n\r\n        for (const input of node.inputs) {\r\n            const connectedPoint = input.connectedPoint;\r\n            if (connectedPoint) {\r\n                const block = connectedPoint.ownerBlock;\r\n                if (block !== node) {\r\n                    this._initializeBlock(block, autoConfigure);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current geometry\r\n     */\r\n    public clear() {\r\n        this.outputBlock = null;\r\n        this.attachedBlocks.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Remove a block from the current geometry\r\n     * @param block defines the block to remove\r\n     */\r\n    public removeBlock(block: NodeGeometryBlock) {\r\n        const attachedBlockIndex = this.attachedBlocks.indexOf(block);\r\n        if (attachedBlockIndex > -1) {\r\n            this.attachedBlocks.splice(attachedBlockIndex, 1);\r\n        }\r\n\r\n        if (block === this.outputBlock) {\r\n            this.outputBlock = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current graph and load a new one from a serialization object\r\n     * @param source defines the JSON representation of the geometry\r\n     * @param merge defines whether or not the source must be merged or replace the current content\r\n     */\r\n    public parseSerializedObject(source: any, merge = false) {\r\n        if (!merge) {\r\n            this.clear();\r\n        }\r\n\r\n        const map: { [key: number]: NodeGeometryBlock } = {};\r\n\r\n        // Create blocks\r\n        for (const parsedBlock of source.blocks) {\r\n            const blockType = GetClass(parsedBlock.customType);\r\n            if (blockType) {\r\n                const block: NodeGeometryBlock = new blockType();\r\n                block._deserialize(parsedBlock);\r\n                map[parsedBlock.id] = block;\r\n\r\n                this.attachedBlocks.push(block);\r\n            }\r\n        }\r\n\r\n        // Reconnect teleportation\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isTeleportOut) {\r\n                const teleportOut = block as TeleportOutBlock;\r\n                const id = teleportOut._tempEntryPointUniqueId;\r\n                if (id) {\r\n                    const source = map[id] as TeleportInBlock;\r\n                    if (source) {\r\n                        source.attachToEndpoint(teleportOut);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Connections - Starts with input blocks only (except if in \"merge\" mode where we scan all blocks)\r\n        for (let blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {\r\n            const parsedBlock = source.blocks[blockIndex];\r\n            const block = map[parsedBlock.id];\r\n\r\n            if (!block) {\r\n                continue;\r\n            }\r\n\r\n            if (block.inputs.length && parsedBlock.inputs.some((i: any) => i.targetConnectionName) && !merge) {\r\n                continue;\r\n            }\r\n            this._restoreConnections(block, source, map);\r\n        }\r\n\r\n        // Outputs\r\n        if (source.outputNodeId) {\r\n            this.outputBlock = map[source.outputNodeId] as GeometryOutputBlock;\r\n        }\r\n\r\n        // UI related info\r\n        if (source.locations || (source.editorData && source.editorData.locations)) {\r\n            const locations: {\r\n                blockId: number;\r\n                x: number;\r\n                y: number;\r\n                isCollapsed: boolean;\r\n            }[] = source.locations || source.editorData.locations;\r\n\r\n            for (const location of locations) {\r\n                if (map[location.blockId]) {\r\n                    location.blockId = map[location.blockId].uniqueId;\r\n                }\r\n            }\r\n\r\n            if (merge && this.editorData && this.editorData.locations) {\r\n                locations.concat(this.editorData.locations);\r\n            }\r\n\r\n            if (source.locations) {\r\n                this.editorData = {\r\n                    locations: locations,\r\n                };\r\n            } else {\r\n                this.editorData = source.editorData;\r\n                this.editorData.locations = locations;\r\n            }\r\n\r\n            const blockMap: { [key: number]: number } = {};\r\n\r\n            for (const key in map) {\r\n                blockMap[key] = map[key].uniqueId;\r\n            }\r\n\r\n            this.editorData.map = blockMap;\r\n        }\r\n\r\n        this.comment = source.comment;\r\n    }\r\n\r\n    private _restoreConnections(block: NodeGeometryBlock, source: any, map: { [key: number]: NodeGeometryBlock }) {\r\n        for (const outputPoint of block.outputs) {\r\n            for (const candidate of source.blocks) {\r\n                const target = map[candidate.id];\r\n\r\n                if (!target) {\r\n                    continue;\r\n                }\r\n\r\n                for (const input of candidate.inputs) {\r\n                    if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {\r\n                        const inputPoint = target.getInputByName(input.inputName);\r\n                        if (!inputPoint || inputPoint.isConnected) {\r\n                            continue;\r\n                        }\r\n\r\n                        outputPoint.connectTo(inputPoint, true);\r\n                        this._restoreConnections(target, source, map);\r\n                        continue;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Generate a string containing the code declaration required to create an equivalent of this geometry\r\n     * @returns a string\r\n     */\r\n    public generateCode() {\r\n        let alreadyDumped: NodeGeometryBlock[] = [];\r\n        const blocks: NodeGeometryBlock[] = [];\r\n        const uniqueNames: string[] = [\"const\", \"var\", \"let\"];\r\n        // Gets active blocks\r\n        if (this.outputBlock) {\r\n            this._gatherBlocks(this.outputBlock, blocks);\r\n        }\r\n\r\n        // Generate\r\n        let codeString = `let nodeGeometry = new BABYLON.NodeGeometry(\"${this.name || \"node geometry\"}\");\\n`;\r\n        for (const node of blocks) {\r\n            if (node.isInput && alreadyDumped.indexOf(node) === -1) {\r\n                codeString += node._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        if (this.outputBlock) {\r\n            // Connections\r\n            alreadyDumped = [];\r\n            codeString += \"// Connections\\n\";\r\n            codeString += this.outputBlock._dumpCodeForOutputConnections(alreadyDumped);\r\n\r\n            // Output nodes\r\n            codeString += \"// Output nodes\\n\";\r\n            codeString += `nodeGeometry.outputBlock = ${this.outputBlock._codeVariableName};\\n`;\r\n            codeString += `nodeGeometry.build();\\n`;\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    private _gatherBlocks(rootNode: NodeGeometryBlock, list: NodeGeometryBlock[]) {\r\n        if (list.indexOf(rootNode) !== -1) {\r\n            return;\r\n        }\r\n        list.push(rootNode);\r\n\r\n        for (const input of rootNode.inputs) {\r\n            const connectedPoint = input.connectedPoint;\r\n            if (connectedPoint) {\r\n                const block = connectedPoint.ownerBlock;\r\n                if (block !== rootNode) {\r\n                    this._gatherBlocks(block, list);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Teleportation\r\n        if (rootNode.isTeleportOut) {\r\n            const block = rootNode as TeleportOutBlock;\r\n            if (block.entryPoint) {\r\n                this._gatherBlocks(block.entryPoint, list);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current geometry and set it to a default state\r\n     */\r\n    public setToDefault() {\r\n        this.clear();\r\n\r\n        this.editorData = null;\r\n\r\n        // Source\r\n        const dataBlock = new BoxBlock(\"Box\");\r\n        dataBlock.autoConfigure();\r\n\r\n        // Final output\r\n        const output = new GeometryOutputBlock(\"Geometry Output\");\r\n        dataBlock.geometry.connectTo(output.geometry);\r\n\r\n        this.outputBlock = output;\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current geometry.\r\n     * @param name defines the name to use for the new geometry\r\n     * @returns the new geometry\r\n     */\r\n    public clone(name: string): NodeGeometry {\r\n        const serializationObject = this.serialize();\r\n\r\n        const clone = SerializationHelper.Clone(() => new NodeGeometry(name), this);\r\n        clone.name = name;\r\n\r\n        clone.parseSerializedObject(serializationObject);\r\n        clone._buildId = this._buildId;\r\n        clone.build(false);\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serializes this geometry in a JSON representation\r\n     * @param selectedBlocks defines the list of blocks to save (if null the whole geometry will be saved)\r\n     * @returns the serialized geometry object\r\n     */\r\n    public serialize(selectedBlocks?: NodeGeometryBlock[]): any {\r\n        const serializationObject = selectedBlocks ? {} : SerializationHelper.Serialize(this);\r\n        serializationObject.editorData = JSON.parse(JSON.stringify(this.editorData)); // Copy\r\n\r\n        let blocks: NodeGeometryBlock[] = [];\r\n\r\n        if (selectedBlocks) {\r\n            blocks = selectedBlocks;\r\n        } else {\r\n            serializationObject.customType = \"BABYLON.NodeGeometry\";\r\n            if (this.outputBlock) {\r\n                serializationObject.outputNodeId = this.outputBlock.uniqueId;\r\n            }\r\n        }\r\n\r\n        // Blocks\r\n        serializationObject.blocks = [];\r\n\r\n        for (const block of blocks) {\r\n            serializationObject.blocks.push(block.serialize());\r\n        }\r\n\r\n        if (!selectedBlocks) {\r\n            for (const block of this.attachedBlocks) {\r\n                if (blocks.indexOf(block) !== -1) {\r\n                    continue;\r\n                }\r\n                serializationObject.blocks.push(block.serialize());\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources\r\n     */\r\n    public dispose(): void {\r\n        for (const block of this.attachedBlocks) {\r\n            block.dispose();\r\n        }\r\n\r\n        this.attachedBlocks.length = 0;\r\n        this.onBuildObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Creates a new node geometry set to default basic configuration\r\n     * @param name defines the name of the geometry\r\n     * @returns a new NodeGeometry\r\n     */\r\n    public static CreateDefault(name: string) {\r\n        const nodeGeometry = new NodeGeometry(name);\r\n\r\n        nodeGeometry.setToDefault();\r\n        nodeGeometry.build();\r\n\r\n        return nodeGeometry;\r\n    }\r\n\r\n    /**\r\n     * Creates a node geometry from parsed geometry data\r\n     * @param source defines the JSON representation of the geometry\r\n     * @returns a new node geometry\r\n     */\r\n    public static Parse(source: any): NodeGeometry {\r\n        const nodeGeometry = SerializationHelper.Parse(() => new NodeGeometry(source.name), source, null);\r\n\r\n        nodeGeometry.parseSerializedObject(source);\r\n        nodeGeometry.build();\r\n\r\n        return nodeGeometry;\r\n    }\r\n\r\n    /**\r\n     * Creates a node geometry from a snippet saved by the node geometry editor\r\n     * @param snippetId defines the snippet to load\r\n     * @param nodeGeometry defines a node geometry to update (instead of creating a new one)\r\n     * @param skipBuild defines whether to build the node geometry\r\n     * @returns a promise that will resolve to the new node geometry\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromSnippetAsync(snippetId: string, nodeGeometry?: NodeGeometry, skipBuild: boolean = false): Promise<NodeGeometry> {\r\n        if (snippetId === \"_BLANK\") {\r\n            return Promise.resolve(NodeGeometry.CreateDefault(\"blank\"));\r\n        }\r\n\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n                        const serializationObject = JSON.parse(snippet.nodeGeometry);\r\n\r\n                        if (!nodeGeometry) {\r\n                            nodeGeometry = SerializationHelper.Parse(() => new NodeGeometry(snippetId), serializationObject, null);\r\n                        }\r\n\r\n                        nodeGeometry.parseSerializedObject(serializationObject);\r\n                        nodeGeometry.snippetId = snippetId;\r\n\r\n                        try {\r\n                            if (!skipBuild) {\r\n                                nodeGeometry.build();\r\n                            }\r\n                            resolve(nodeGeometry);\r\n                        } catch (err) {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            reject(err);\r\n                        }\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the snippet \" + snippetId);\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", this.SnippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\r\n            request.send();\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { type FloatArray } from \"../../../types\";\r\nimport { VertexData } from \"../../../Meshes/mesh.vertexData\";\r\nimport { WithinEpsilon } from \"../../../Maths/math.scalar.functions\";\r\nimport { Epsilon } from \"../../../Maths/math.constants\";\r\nimport { type INodeGeometryExecutionContext } from \"../Interfaces/nodeGeometryExecutionContext\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to extract unique positions from a geometry\r\n */\r\nexport class GeometryOptimizeBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _currentIndex: number;\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Define the epsilon used to compare similar positions\r\n     */\r\n    @editableInPropertyPage(\"Epsilon\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public epsilon = Epsilon;\r\n\r\n    /**\r\n     * Optimize faces (by removing duplicates)\r\n     */\r\n    @editableInPropertyPage(\"Optimize faces\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public optimizeFaces = false;\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Creates a new GeometryOptimizeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"selector\", NodeGeometryBlockConnectionPointTypes.Int, true);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryOptimizeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the selector component\r\n     */\r\n    public get selector(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            if (!this.geometry.isConnected) {\r\n                return null;\r\n            }\r\n            const vertexData = this.geometry.getConnectedValue(state);\r\n            const newPositions: FloatArray = [];\r\n            const newIndicesMap: { [key: number]: number } = {};\r\n            const newUVs: FloatArray = [];\r\n            state.pushExecutionContext(this);\r\n            state.pushGeometryContext(vertexData);\r\n\r\n            // Optimize positions\r\n            for (let index = 0; index < vertexData.positions.length; index += 3) {\r\n                this._currentIndex = index / 3;\r\n\r\n                if (this.selector.isConnected) {\r\n                    const selector = this.selector.getConnectedValue(state);\r\n                    if (!selector) {\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                const x = vertexData.positions[index];\r\n                const y = vertexData.positions[index + 1];\r\n                const z = vertexData.positions[index + 2];\r\n\r\n                const uvIndex = (index / 3) * 2;\r\n                const u = vertexData.uvs ? vertexData.uvs[uvIndex] : 0;\r\n                const v = vertexData.uvs ? vertexData.uvs[uvIndex + 1] : 0;\r\n\r\n                // check if we already have it\r\n                let found = false;\r\n                for (let checkIndex = 0; checkIndex < newPositions.length; checkIndex += 3) {\r\n                    if (\r\n                        WithinEpsilon(x, newPositions[checkIndex], this.epsilon) &&\r\n                        WithinEpsilon(y, newPositions[checkIndex + 1], this.epsilon) &&\r\n                        WithinEpsilon(z, newPositions[checkIndex + 2], this.epsilon)\r\n                    ) {\r\n                        newIndicesMap[index / 3] = checkIndex / 3;\r\n                        found = true;\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                if (!found) {\r\n                    newIndicesMap[index / 3] = newPositions.length / 3;\r\n                    newPositions.push(x, y, z);\r\n                    newUVs.push(u, v);\r\n                }\r\n            }\r\n            const newVertexData = new VertexData();\r\n            newVertexData.positions = newPositions;\r\n            if (vertexData.uvs) {\r\n                newVertexData.uvs = newUVs;\r\n            }\r\n            const indices: number[] = vertexData.indices.map((index: number) => newIndicesMap[index]);\r\n            const newIndices: number[] = [];\r\n\r\n            if (this.optimizeFaces) {\r\n                // Optimize indices\r\n                for (let index = 0; index < indices.length; index += 3) {\r\n                    const a = indices[index];\r\n                    const b = indices[index + 1];\r\n                    const c = indices[index + 2];\r\n\r\n                    if (a === b || b == c || c === a) {\r\n                        continue;\r\n                    }\r\n\r\n                    // check if we already have it\r\n                    let found = false;\r\n                    for (let checkIndex = 0; checkIndex < newIndices.length; checkIndex += 3) {\r\n                        if (a === newIndices[checkIndex] && b === newIndices[checkIndex + 1] && c === newIndices[checkIndex + 2]) {\r\n                            found = true;\r\n                            continue;\r\n                        }\r\n\r\n                        if (a === newIndices[checkIndex + 1] && b === newIndices[checkIndex + 2] && c === newIndices[checkIndex]) {\r\n                            found = true;\r\n                            continue;\r\n                        }\r\n\r\n                        if (a === newIndices[checkIndex + 2] && b === newIndices[checkIndex] && c === newIndices[checkIndex + 1]) {\r\n                            found = true;\r\n                            continue;\r\n                        }\r\n                    }\r\n\r\n                    if (!found) {\r\n                        newIndices.push(a, b, c);\r\n                    }\r\n                }\r\n\r\n                newVertexData.indices = newIndices;\r\n            } else {\r\n                newVertexData.indices = indices;\r\n            }\r\n\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n\r\n            return newVertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.epsilon = ${this.epsilon};\\n`;\r\n        codeString += `${this._codeVariableName}.optimizeFaces = ${this.optimizeFaces ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.epsilon = this.epsilon;\r\n        serializationObject.optimizeFaces = this.optimizeFaces;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n        this.epsilon = serializationObject.epsilon;\r\n        this.optimizeFaces = serializationObject.optimizeFaces;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryOptimizeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryOptimizeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryOptimizeBlock\", GeometryOptimizeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { Matrix } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { CreateGroundVertexData } from \"core/Meshes/Builders/groundBuilder.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate plane geometry data\r\n */\r\nexport class PlaneBlock extends NodeGeometryBlock {\r\n    private _rotationMatrix = new Matrix();\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new PlaneBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"size\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"width\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"height\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"subdivisions\", NodeGeometryBlockConnectionPointTypes.Int, true, 1, 0);\r\n        this.registerInput(\"subdivisionsX\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n        this.registerInput(\"subdivisionsY\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PlaneBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the size input component\r\n     */\r\n    public get size(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the width input component\r\n     */\r\n    public get width(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the height input component\r\n     */\r\n    public get height(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisions input component\r\n     */\r\n    public get subdivisions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsX input component\r\n     */\r\n    public get subdivisionsX(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsY input component\r\n     */\r\n    public get subdivisionsY(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (this.size.isConnected) {\r\n            return;\r\n        }\r\n\r\n        if (!this.width.isConnected && !this.height.isConnected) {\r\n            const sizeInput = new GeometryInputBlock(\"Size\");\r\n            sizeInput.value = 1;\r\n            sizeInput.output.connectTo(this.size);\r\n            return;\r\n        }\r\n\r\n        if (!this.width.isConnected) {\r\n            const widthInput = new GeometryInputBlock(\"Width\");\r\n            widthInput.value = 1;\r\n            widthInput.output.connectTo(this.width);\r\n        }\r\n\r\n        if (!this.height.isConnected) {\r\n            const heightInput = new GeometryInputBlock(\"Height\");\r\n            heightInput.value = 1;\r\n            heightInput.output.connectTo(this.height);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: { size?: number; width?: number; height?: number; subdivisions?: number; subdivisionsX?: number; subdivisionsY?: number } = {};\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.size = this.size.getConnectedValue(state);\r\n            options.width = this.width.getConnectedValue(state);\r\n            options.height = this.height.getConnectedValue(state);\r\n\r\n            const subdivisions = this.subdivisions.getConnectedValue(state);\r\n            const subdivisionsX = this.subdivisionsX.getConnectedValue(state);\r\n            const subdivisionsY = this.subdivisionsY.getConnectedValue(state);\r\n\r\n            if (subdivisions) {\r\n                options.subdivisions = subdivisions;\r\n            }\r\n\r\n            if (subdivisionsX) {\r\n                options.subdivisionsX = subdivisionsX;\r\n            }\r\n\r\n            if (subdivisionsY) {\r\n                options.subdivisionsY = subdivisionsY;\r\n            }\r\n\r\n            // Append vertex data from the ground builder (to get access to subdivisions)\r\n            const vertexData = CreateGroundVertexData(options);\r\n\r\n            Matrix.RotationYawPitchRollToRef(-Math.PI / 2, 0, Math.PI / 2, this._rotationMatrix);\r\n\r\n            vertexData.transform(this._rotationMatrix);\r\n\r\n            return vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for planeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPlaneBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PlaneBlock\", PlaneBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type Mesh } from \"../../../../Meshes/mesh.pure\";\r\nimport { VertexData } from \"../../../../Meshes/mesh.vertexData\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate a user defined mesh geometry data\r\n */\r\nexport class MeshBlock extends NodeGeometryBlock {\r\n    private _mesh: Nullable<Mesh>;\r\n    private _cachedVertexData: Nullable<VertexData> = null;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that winding order needs to be reserved\r\n     */\r\n    public reverseWindingOrder = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block should serialize its cached data\r\n     */\r\n    @editableInPropertyPage(\"Serialize cached data\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public serializedCachedData = false;\r\n\r\n    /**\r\n     * Gets or sets the mesh to use to get vertex data\r\n     */\r\n    public get mesh() {\r\n        return this._mesh;\r\n    }\r\n\r\n    public set mesh(value: Nullable<Mesh>) {\r\n        this._mesh = value;\r\n    }\r\n\r\n    /**\r\n     * Create a new MeshBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MeshBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the block is using cached data\r\n     */\r\n    public get isUsingCachedData() {\r\n        return !this.mesh && !!this._cachedVertexData;\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Remove stored data\r\n     */\r\n    public cleanData() {\r\n        this._mesh = null;\r\n        this._cachedVertexData = null;\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this._mesh) {\r\n            if (this._cachedVertexData) {\r\n                this.geometry._storedValue = this._cachedVertexData.clone();\r\n            } else {\r\n                this.geometry._storedValue = null;\r\n            }\r\n            return;\r\n        }\r\n\r\n        const vertexData = VertexData.ExtractFromMesh(this._mesh, false, true);\r\n        this._cachedVertexData = null;\r\n\r\n        if (this.reverseWindingOrder && vertexData.indices) {\r\n            for (let index = 0; index < vertexData.indices.length; index += 3) {\r\n                const tmp = vertexData.indices[index];\r\n                vertexData.indices[index] = vertexData.indices[index + 2];\r\n                vertexData.indices[index + 2] = tmp;\r\n            }\r\n        }\r\n\r\n        this.geometry._storedFunction = () => {\r\n            return vertexData.clone();\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.serializedCachedData = this.serializedCachedData;\r\n\r\n        if (this.serializedCachedData) {\r\n            if (this._mesh) {\r\n                serializationObject.cachedVertexData = VertexData.ExtractFromMesh(this._mesh, false, true).serialize();\r\n            } else if (this._cachedVertexData) {\r\n                serializationObject.cachedVertexData = this._cachedVertexData.serialize();\r\n            }\r\n        }\r\n\r\n        serializationObject.reverseWindingOrder = this.reverseWindingOrder;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.cachedVertexData) {\r\n            this._cachedVertexData = VertexData.Parse(serializationObject.cachedVertexData);\r\n        }\r\n\r\n        this.serializedCachedData = !!serializationObject.serializedCachedData;\r\n        this.reverseWindingOrder = serializationObject.reverseWindingOrder;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MeshBlock\", MeshBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { CreateIcoSphereVertexData } from \"core/Meshes/Builders/icoSphereBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate icosphere geometry data\r\n */\r\nexport class IcoSphereBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new IcoSphereBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"radius\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"radiusX\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"radiusY\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"radiusZ\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"subdivisions\", NodeGeometryBlockConnectionPointTypes.Int, true, 4);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"IcoSphereBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the radius input component\r\n     */\r\n    public get radius(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the radiusX input component\r\n     */\r\n    public get radiusX(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the radiusY input component\r\n     */\r\n    public get radiusY(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the radiusZ input component\r\n     */\r\n    public get radiusZ(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisions input component\r\n     */\r\n    public get subdivisions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.radius.isConnected) {\r\n            const radiusInput = new GeometryInputBlock(\"Radius\");\r\n            radiusInput.value = 0.2;\r\n            radiusInput.output.connectTo(this.radius);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            radius?: number;\r\n            radiusX?: number;\r\n            radiusY?: number;\r\n            radiusZ?: number;\r\n            flat?: boolean;\r\n            subdivisions?: number;\r\n            sideOrientation?: number;\r\n            frontUVs?: Vector4;\r\n            backUVs?: Vector4;\r\n        } = {};\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.radius = this.radius.getConnectedValue(state);\r\n            options.subdivisions = this.subdivisions.getConnectedValue(state);\r\n            options.radiusX = this.radiusX.getConnectedValue(state);\r\n            options.radiusY = this.radiusY.getConnectedValue(state);\r\n            options.radiusZ = this.radiusZ.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateIcoSphereVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for icoSphereBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterIcoSphereBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.IcoSphereBlock\", IcoSphereBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { CreateSphereVertexData } from \"core/Meshes/Builders/sphereBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate sphere geometry data\r\n */\r\nexport class SphereBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new SphereBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"segments\", NodeGeometryBlockConnectionPointTypes.Int, true, 32);\r\n        this.registerInput(\"diameter\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"diameterX\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"diameterY\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"diameterZ\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"arc\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"slice\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SphereBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the segments input component\r\n     */\r\n    public get segments(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameter input component\r\n     */\r\n    public get diameter(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameterX input component\r\n     */\r\n    public get diameterX(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameterY input component\r\n     */\r\n    public get diameterY(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameterZ input component\r\n     */\r\n    public get diameterZ(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the arc input component\r\n     */\r\n    public get arc(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the slice input component\r\n     */\r\n    public get slice(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.diameter.isConnected) {\r\n            const diameterInput = new GeometryInputBlock(\"Diameter\");\r\n            diameterInput.value = 1;\r\n            diameterInput.output.connectTo(this.diameter);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            segments?: number;\r\n            diameter?: number;\r\n            diameterX?: number;\r\n            diameterY?: number;\r\n            diameterZ?: number;\r\n            arc?: number;\r\n            slice?: number;\r\n            sideOrientation?: number;\r\n            frontUVs?: Vector4;\r\n            backUVs?: Vector4;\r\n            dedupTopBottomIndices?: boolean;\r\n        } = {};\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.segments = this.segments.getConnectedValue(state);\r\n            options.diameter = this.diameter.getConnectedValue(state);\r\n            options.diameterX = this.diameterX.getConnectedValue(state);\r\n            options.diameterY = this.diameterY.getConnectedValue(state);\r\n            options.diameterZ = this.diameterZ.getConnectedValue(state);\r\n            options.arc = this.arc.getConnectedValue(state);\r\n            options.slice = this.slice.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateSphereVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sphereBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSphereBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SphereBlock\", SphereBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { CreateGroundVertexData } from \"../../../Builders/groundBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate grid geometry data\r\n */\r\nexport class GridBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new GridBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"width\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"height\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"subdivisions\", NodeGeometryBlockConnectionPointTypes.Int, true, 1, 0);\r\n        this.registerInput(\"subdivisionsX\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n        this.registerInput(\"subdivisionsY\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GridBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the width input component\r\n     */\r\n    public get width(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the height input component\r\n     */\r\n    public get height(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisions input component\r\n     */\r\n    public get subdivisions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsX input component\r\n     */\r\n    public get subdivisionsX(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisionsY input component\r\n     */\r\n    public get subdivisionsY(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.width.isConnected) {\r\n            const widthInput = new GeometryInputBlock(\"Width\");\r\n            widthInput.value = 1;\r\n            widthInput.output.connectTo(this.width);\r\n        }\r\n\r\n        if (!this.height.isConnected) {\r\n            const heightInput = new GeometryInputBlock(\"Height\");\r\n            heightInput.value = 1;\r\n            heightInput.output.connectTo(this.height);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: { width?: number; height?: number; subdivisions?: number; subdivisionsX?: number; subdivisionsY?: number } = {};\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.width = this.width.getConnectedValue(state);\r\n            options.height = this.height.getConnectedValue(state);\r\n            options.subdivisions = this.subdivisions.getConnectedValue(state);\r\n            options.subdivisionsX = this.subdivisionsX.getConnectedValue(state);\r\n            options.subdivisionsY = this.subdivisionsY.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateGroundVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gridBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGridBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GridBlock\", GridBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { CreateTorusVertexData } from \"core/Meshes/Builders/torusBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate torus geometry data\r\n */\r\nexport class TorusBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new TorusBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"diameter\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"thickness\", NodeGeometryBlockConnectionPointTypes.Float, true, 0.5);\r\n        this.registerInput(\"tessellation\", NodeGeometryBlockConnectionPointTypes.Int, true, 16);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TorusBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the diameter input component\r\n     */\r\n    public get diameter(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the thickness input component\r\n     */\r\n    public get thickness(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the tessellation input component\r\n     */\r\n    public get tessellation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.diameter.isConnected) {\r\n            const diameterInput = new GeometryInputBlock(\"Diameter\");\r\n            diameterInput.value = 1;\r\n            diameterInput.output.connectTo(this.diameter);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            diameter?: number;\r\n            thickness?: number;\r\n            tessellation?: number;\r\n            sideOrientation?: number;\r\n            frontUVs?: Vector4;\r\n            backUVs?: Vector4;\r\n        } = {};\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.thickness = this.thickness.getConnectedValue(state);\r\n            options.diameter = this.diameter.getConnectedValue(state);\r\n            options.tessellation = this.tessellation.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateTorusVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for torusBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTorusBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TorusBlock\", TorusBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { CreateCylinderVertexData } from \"core/Meshes/Builders/cylinderBuilder.pure\";\r\nimport { type Color4 } from \"../../../../Maths/math.color.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate cylinder geometry data\r\n */\r\nexport class CylinderBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new SphereBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"height\", NodeGeometryBlockConnectionPointTypes.Float, true, 25);\r\n        this.registerInput(\"diameter\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"diameterTop\", NodeGeometryBlockConnectionPointTypes.Float, true, -1);\r\n        this.registerInput(\"diameterBottom\", NodeGeometryBlockConnectionPointTypes.Float, true, -1);\r\n        this.registerInput(\"subdivisions\", NodeGeometryBlockConnectionPointTypes.Int, true, 1);\r\n        this.registerInput(\"tessellation\", NodeGeometryBlockConnectionPointTypes.Int, true, 24);\r\n        this.registerInput(\"arc\", NodeGeometryBlockConnectionPointTypes.Float, true, 1.0);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CylinderBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the height input component\r\n     */\r\n    public get height(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameter input component\r\n     */\r\n    public get diameter(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameterTop input component\r\n     */\r\n    public get diameterTop(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the diameterBottom input component\r\n     */\r\n    public get diameterBottom(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisions input component\r\n     */\r\n    public get subdivisions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the tessellation input component\r\n     */\r\n    public get tessellation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the arc input component\r\n     */\r\n    public get arc(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.diameter.isConnected) {\r\n            const diameterInput = new GeometryInputBlock(\"Diameter\");\r\n            diameterInput.value = 1;\r\n            diameterInput.output.connectTo(this.diameter);\r\n        }\r\n\r\n        if (!this.height.isConnected) {\r\n            const heightInput = new GeometryInputBlock(\"Height\");\r\n            heightInput.value = 1;\r\n            heightInput.output.connectTo(this.height);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            height?: number;\r\n            diameterTop?: number;\r\n            diameterBottom?: number;\r\n            diameter?: number;\r\n            tessellation?: number;\r\n            subdivisions?: number;\r\n            arc?: number;\r\n            faceColors?: Color4[];\r\n            faceUV?: Vector4[];\r\n            hasRings?: boolean;\r\n            enclose?: boolean;\r\n            cap?: number;\r\n            sideOrientation?: number;\r\n            frontUVs?: Vector4;\r\n            backUVs?: Vector4;\r\n        } = {};\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.height = this.height.getConnectedValue(state);\r\n            options.diameter = this.diameter.getConnectedValue(state);\r\n            options.diameterTop = this.diameterTop.getConnectedValue(state);\r\n            options.diameterBottom = this.diameterBottom.getConnectedValue(state);\r\n\r\n            if (options.diameterTop === -1) {\r\n                options.diameterTop = options.diameter;\r\n            }\r\n\r\n            if (options.diameterBottom === -1) {\r\n                options.diameterBottom = options.diameter;\r\n            }\r\n\r\n            options.tessellation = this.tessellation.getConnectedValue(state);\r\n            options.subdivisions = this.subdivisions.getConnectedValue(state);\r\n            options.arc = this.arc.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateCylinderVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cylinderBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCylinderBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CylinderBlock\", CylinderBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { CreateCapsuleVertexData } from \"core/Meshes/Builders/capsuleBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate capsule geometry data\r\n */\r\nexport class CapsuleBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new CapsuleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"height\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"radius\", NodeGeometryBlockConnectionPointTypes.Float, true, 0.25);\r\n        this.registerInput(\"tessellation\", NodeGeometryBlockConnectionPointTypes.Int, true, 16);\r\n        this.registerInput(\"subdivisions\", NodeGeometryBlockConnectionPointTypes.Int, true, 2);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CapsuleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the height input component\r\n     */\r\n    public get height(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the radius input component\r\n     */\r\n    public get radius(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the tessellation input component\r\n     */\r\n    public get tessellation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the subdivisions input component\r\n     */\r\n    public get subdivisions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.height.isConnected) {\r\n            const heightInput = new GeometryInputBlock(\"Height\");\r\n            heightInput.value = 1;\r\n            heightInput.output.connectTo(this.height);\r\n        }\r\n        if (!this.radius.isConnected) {\r\n            const radiusInput = new GeometryInputBlock(\"Radius\");\r\n            radiusInput.value = 0.2;\r\n            radiusInput.output.connectTo(this.radius);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            orientation?: Vector3;\r\n            subdivisions?: number;\r\n            tessellation?: number;\r\n            height?: number;\r\n            radius?: number;\r\n            capSubdivisions?: number;\r\n            radiusTop?: number;\r\n            radiusBottom?: number;\r\n            topCapSubdivisions?: number;\r\n            bottomCapSubdivisions?: number;\r\n            updatable?: boolean;\r\n        } = {};\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.height = this.height.getConnectedValue(state);\r\n            options.radius = this.radius.getConnectedValue(state);\r\n            options.tessellation = this.tessellation.getConnectedValue(state);\r\n            options.subdivisions = this.subdivisions.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateCapsuleVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for capsuleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCapsuleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CapsuleBlock\", CapsuleBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { CreateDiscVertexData } from \"core/Meshes/Builders/discBuilder.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate disc geometry data\r\n */\r\nexport class DiscBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new DiscBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"radius\", NodeGeometryBlockConnectionPointTypes.Float, true, 0.5);\r\n        this.registerInput(\"tessellation\", NodeGeometryBlockConnectionPointTypes.Int, true, 64);\r\n        this.registerInput(\"arc\", NodeGeometryBlockConnectionPointTypes.Float, true, 1.0);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DiscBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the radius input component\r\n     */\r\n    public get radius(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the tessellation input component\r\n     */\r\n    public get tessellation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the arc input component\r\n     */\r\n    public get arc(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.radius.isConnected) {\r\n            const radiusInput = new GeometryInputBlock(\"Radius\");\r\n            radiusInput.value = 0.2;\r\n            radiusInput.output.connectTo(this.radius);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const options: {\r\n            radius?: number;\r\n            tessellation?: number;\r\n            arc?: number;\r\n            sideOrientation?: number;\r\n            frontUVs?: Vector4;\r\n            backUVs?: Vector4;\r\n        } = {};\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            options.radius = this.radius.getConnectedValue(state);\r\n            options.tessellation = this.tessellation.getConnectedValue(state);\r\n            options.arc = this.arc.getConnectedValue(state);\r\n\r\n            // Append vertex data from the plane builder\r\n            return CreateDiscVertexData(options);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.geometry._storedFunction = func;\r\n        } else {\r\n            const value = func(state);\r\n            this.geometry._storedFunction = () => {\r\n                this.geometry._executionCount = 1;\r\n                return value.clone();\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for discBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDiscBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DiscBlock\", DiscBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate a null geometry data\r\n */\r\nexport class NullBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new NullBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerOutput(\"vector\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NullBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the vector output component\r\n     */\r\n    public get vector(): NodeGeometryConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.geometry._storedValue = null;\r\n        this.vector._storedValue = null;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for nullBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNullBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NullBlock\", NullBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate a geometry data from a list of points\r\n */\r\nexport class PointListBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a list of points used to generate the geometry\r\n     */\r\n    public points: Vector3[] = [];\r\n\r\n    /**\r\n     * Create a new PointListBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerOutput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PointListBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(_state: NodeGeometryBuildState) {\r\n        this.geometry._storedFunction = () => {\r\n            this.geometry._executionCount = 1;\r\n\r\n            if (this.points.length === 0) {\r\n                return null;\r\n            }\r\n\r\n            const vertexData = new VertexData();\r\n            vertexData.positions = this.points.reduce((acc, point) => {\r\n                acc.push(point.x, point.y, point.z);\r\n                return acc;\r\n            }, [] as number[]);\r\n\r\n            return vertexData;\r\n        };\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.points = [];\\n`;\r\n\r\n        for (let i = 0; i < this.points.length; i++) {\r\n            const point = this.points[i];\r\n            codeString += `${this._codeVariableName}.points.push(new BABYLON.Vector3(${point.x}, ${point.y}, ${point.z}));\\n`;\r\n        }\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.points = this.points.map((point) => {\r\n            return point.asArray();\r\n        });\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.points = serializationObject.points.map((point: number[]) => {\r\n            return Vector3.FromArray(point);\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pointListBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPointListBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PointListBlock\", PointListBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../../Meshes/mesh.vertexData\";\r\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { type FloatArray } from \"core/types\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to set positions for a geometry\r\n */\r\nexport class SetPositionsBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new SetPositionsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"positions\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetPositionsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the positions input component\r\n     */\r\n    public get positions(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _remapVector3Data(source: FloatArray, remap: { [key: number]: number }): FloatArray {\r\n        const newData: FloatArray = [];\r\n        for (let index = 0; index < source.length; index += 3) {\r\n            const remappedIndex = remap[index / 3];\r\n\r\n            if (remappedIndex !== undefined) {\r\n                newData.push(source[index], source[index + 1], source[index + 2]);\r\n            }\r\n        }\r\n        return newData;\r\n    }\r\n\r\n    private _remapVector4Data(source: FloatArray, remap: { [key: number]: number }): FloatArray {\r\n        const newData: FloatArray = [];\r\n        for (let index = 0; index < source.length; index += 4) {\r\n            const remappedIndex = remap[index / 4];\r\n\r\n            if (remappedIndex !== undefined) {\r\n                newData.push(source[index], source[index + 1], source[index + 2], source[index + 3]);\r\n            }\r\n        }\r\n        return newData;\r\n    }\r\n\r\n    private _remapVector2Data(source: FloatArray, remap: { [key: number]: number }): FloatArray {\r\n        const newData: FloatArray = [];\r\n        for (let index = 0; index < source.length; index += 2) {\r\n            const remappedIndex = remap[index / 2];\r\n\r\n            if (remappedIndex !== undefined) {\r\n                newData.push(source[index], source[index + 1]);\r\n            }\r\n        }\r\n        return newData;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            if (this._vertexData) {\r\n                this._vertexData = this._vertexData.clone(); // Preserve source data\r\n            }\r\n\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions || !this.positions.isConnected) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            // Processing\r\n            const remap: { [key: number]: number } = {};\r\n            const vertexCount = this._vertexData.positions.length / 3;\r\n            const newPositions: FloatArray = [];\r\n            let activeIndex = 0;\r\n            let resize = false;\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                const tempVector3 = this.positions.getConnectedValue(state) as Vector3;\r\n                if (tempVector3) {\r\n                    tempVector3.toArray(newPositions, activeIndex * 3);\r\n                    remap[this._currentIndex] = activeIndex;\r\n                    activeIndex++;\r\n                } else {\r\n                    resize = true;\r\n                }\r\n            }\r\n\r\n            if (resize) {\r\n                // Indices remap\r\n                if (this._vertexData.indices) {\r\n                    const newIndices: number[] = [];\r\n                    for (let index = 0; index < this._vertexData.indices.length; index += 3) {\r\n                        const a = this._vertexData.indices[index];\r\n                        const b = this._vertexData.indices[index + 1];\r\n                        const c = this._vertexData.indices[index + 2];\r\n                        const remappedA = remap[a];\r\n                        const remappedB = remap[b];\r\n                        const remappedC = remap[c];\r\n\r\n                        if (remappedA !== undefined && remappedB !== undefined && remappedC !== undefined) {\r\n                            newIndices.push(remappedA);\r\n                            newIndices.push(remappedB);\r\n                            newIndices.push(remappedC);\r\n                        }\r\n                    }\r\n\r\n                    this._vertexData.indices = newIndices;\r\n                }\r\n\r\n                // Normals remap\r\n                if (this._vertexData.normals) {\r\n                    this._vertexData.normals = this._remapVector3Data(this._vertexData.normals, remap);\r\n                }\r\n\r\n                // Tangents remap\r\n                if (this._vertexData.tangents) {\r\n                    this._vertexData.tangents = this._remapVector4Data(this._vertexData.tangents, remap);\r\n                }\r\n\r\n                // Colors remap\r\n                if (this._vertexData.colors) {\r\n                    this._vertexData.colors = this._remapVector4Data(this._vertexData.colors, remap);\r\n                }\r\n\r\n                // UVs remap\r\n                if (this._vertexData.uvs) {\r\n                    this._vertexData.uvs = this._remapVector2Data(this._vertexData.uvs, remap);\r\n                }\r\n                if (this._vertexData.uvs2) {\r\n                    this._vertexData.uvs2 = this._remapVector2Data(this._vertexData.uvs2, remap);\r\n                }\r\n                if (this._vertexData.uvs3) {\r\n                    this._vertexData.uvs3 = this._remapVector2Data(this._vertexData.uvs3, remap);\r\n                }\r\n                if (this._vertexData.uvs4) {\r\n                    this._vertexData.uvs4 = this._remapVector2Data(this._vertexData.uvs4, remap);\r\n                }\r\n                if (this._vertexData.uvs5) {\r\n                    this._vertexData.uvs5 = this._remapVector2Data(this._vertexData.uvs5, remap);\r\n                }\r\n                if (this._vertexData.uvs6) {\r\n                    this._vertexData.uvs6 = this._remapVector2Data(this._vertexData.uvs6, remap);\r\n                }\r\n            }\r\n\r\n            // Update positions\r\n            this._vertexData.positions = newPositions;\r\n\r\n            // Storage\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setPositionsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetPositionsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetPositionsBlock\", SetPositionsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { type Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to set normals for a geometry\r\n */\r\nexport class SetNormalsBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new SetNormalsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"normals\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetNormalsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normals input component\r\n     */\r\n    public get normals(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            if (this._vertexData) {\r\n                this._vertexData = this._vertexData.clone(); // Preserve source data\r\n            }\r\n\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            if (!this.normals.isConnected) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = this._vertexData;\r\n                return;\r\n            }\r\n\r\n            if (!this._vertexData.normals) {\r\n                this._vertexData.normals = [];\r\n            }\r\n\r\n            // Processing\r\n            const vertexCount = this._vertexData.positions.length / 3;\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                const tempVector3 = this.normals.getConnectedValue(state) as Vector3;\r\n                if (tempVector3) {\r\n                    tempVector3.toArray(this._vertexData.normals, this._currentIndex * 3);\r\n                }\r\n            }\r\n\r\n            // Storage\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setNormalsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetNormalsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetNormalsBlock\", SetNormalsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { type Vector2 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to set texture coordinates for a geometry\r\n */\r\nexport class SetUVsBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Gets or sets a value indicating which UV to set\r\n     */\r\n    @editableInPropertyPage(\"Texture coordinates index\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { update: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"UV1\", value: 0 },\r\n            { label: \"UV2\", value: 1 },\r\n            { label: \"UV3\", value: 2 },\r\n            { label: \"UV4\", value: 3 },\r\n            { label: \"UV5\", value: 4 },\r\n            { label: \"UV6\", value: 5 },\r\n        ],\r\n    })\r\n    public textureCoordinateIndex = 0;\r\n\r\n    /**\r\n     * Create a new SetUVsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"uvs\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetUVsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the uvs input component\r\n     */\r\n    public get uvs(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            if (this._vertexData) {\r\n                this._vertexData = this._vertexData.clone(); // Preserve source data\r\n            }\r\n\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            if (!this.uvs.isConnected) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = this._vertexData;\r\n                return;\r\n            }\r\n\r\n            const uvs: number[] = [];\r\n\r\n            // Processing\r\n            const vertexCount = this._vertexData.positions.length / 3;\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                const tempVector2 = this.uvs.getConnectedValue(state) as Vector2;\r\n                if (tempVector2) {\r\n                    tempVector2.toArray(uvs, this._currentIndex * 2);\r\n                }\r\n            }\r\n\r\n            switch (this.textureCoordinateIndex) {\r\n                case 0:\r\n                    this._vertexData.uvs = uvs;\r\n                    break;\r\n                case 1:\r\n                    this._vertexData.uvs2 = uvs;\r\n                    break;\r\n                case 2:\r\n                    this._vertexData.uvs3 = uvs;\r\n                    break;\r\n                case 3:\r\n                    this._vertexData.uvs4 = uvs;\r\n                    break;\r\n                case 4:\r\n                    this._vertexData.uvs5 = uvs;\r\n                    break;\r\n                case 5:\r\n                    this._vertexData.uvs6 = uvs;\r\n                    break;\r\n            }\r\n\r\n            // Storage\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.textureCoordinateIndex};\\n`;\r\n        codeString += `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.textureCoordinateIndex = this.textureCoordinateIndex;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.textureCoordinateIndex = serializationObject.textureCoordinateIndex;\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setUVsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetUVsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetUVsBlock\", SetUVsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { type Vector3, type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to set colors for a geometry\r\n */\r\nexport class SetColorsBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new SetColorsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"colors\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetColorsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the colors input component\r\n     */\r\n    public get colors(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            if (this._vertexData) {\r\n                this._vertexData = this._vertexData.clone(); // Preserve source data\r\n            }\r\n\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            if (!this.colors.isConnected) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = this._vertexData;\r\n                return;\r\n            }\r\n\r\n            if (!this._vertexData.colors) {\r\n                this._vertexData.colors = [];\r\n            }\r\n\r\n            // Processing\r\n            const vertexCount = this._vertexData.positions.length / 3;\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                if (this.colors.connectedPoint?.type === NodeGeometryBlockConnectionPointTypes.Vector3) {\r\n                    const tempVector3 = this.colors.getConnectedValue(state) as Vector3;\r\n                    if (tempVector3) {\r\n                        tempVector3.toArray(this._vertexData.colors, this._currentIndex * 4);\r\n                        this._vertexData.colors[this._currentIndex * 4 + 3] = 1; // Alpha\r\n                        this._vertexData.hasVertexAlpha = false;\r\n                    }\r\n                } else {\r\n                    const tempVector4 = this.colors.getConnectedValue(state) as Vector4;\r\n                    if (tempVector4) {\r\n                        tempVector4.toArray(this._vertexData.colors, this._currentIndex * 4);\r\n                        this._vertexData.hasVertexAlpha = true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Storage\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setColorsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetColorsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetColorsBlock\", SetColorsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { type Vector4 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to set tangents for a geometry\r\n */\r\nexport class SetTangentsBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new SetTangentsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"tangents\", NodeGeometryBlockConnectionPointTypes.Vector4);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetTangentsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the tangents input component\r\n     */\r\n    public get tangents(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            if (this._vertexData) {\r\n                this._vertexData = this._vertexData.clone(); // Preserve source data\r\n            }\r\n\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            if (!this.tangents.isConnected) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = this._vertexData;\r\n                return;\r\n            }\r\n\r\n            if (!this._vertexData.tangents) {\r\n                this._vertexData.tangents = [];\r\n            }\r\n\r\n            // Processing\r\n            const vertexCount = this._vertexData.positions.length / 3;\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                const tempVector4 = this.tangents.getConnectedValue(state) as Vector4;\r\n                if (tempVector4) {\r\n                    tempVector4.toArray(this._vertexData.tangents, this._currentIndex * 4);\r\n                }\r\n            }\r\n\r\n            // Storage\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setTangentsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetTangentsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetTangentsBlock\", SetTangentsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Math block\r\n */\r\nexport enum MathBlockOperations {\r\n    /** Add */\r\n    Add,\r\n    /** Subtract */\r\n    Subtract,\r\n    /** Multiply */\r\n    Multiply,\r\n    /** Divide */\r\n    Divide,\r\n    /** Max */\r\n    Max,\r\n    /** Min */\r\n    Min,\r\n}\r\n\r\n/**\r\n * Block used to apply math functions\r\n */\r\nexport class MathBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Add\", value: MathBlockOperations.Add },\r\n            { label: \"Subtract\", value: MathBlockOperations.Subtract },\r\n            { label: \"Multiply\", value: MathBlockOperations.Multiply },\r\n            { label: \"Divide\", value: MathBlockOperations.Divide },\r\n            { label: \"Max\", value: MathBlockOperations.Max },\r\n            { label: \"Min\", value: MathBlockOperations.Min },\r\n        ],\r\n    })\r\n    public operation = MathBlockOperations.Add;\r\n\r\n    private readonly _connectionObservers: Observer<NodeGeometryConnectionPoint>[];\r\n\r\n    /**\r\n     * Create a new MathBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        const excludedConnectionPointTypes = [\r\n            NodeGeometryBlockConnectionPointTypes.Matrix,\r\n            NodeGeometryBlockConnectionPointTypes.Geometry,\r\n            NodeGeometryBlockConnectionPointTypes.Texture,\r\n        ] as const;\r\n\r\n        this.left.excludedConnectionPointTypes.push(...excludedConnectionPointTypes);\r\n        this.right.excludedConnectionPointTypes.push(...excludedConnectionPointTypes);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._connectionObservers = [\r\n            this.left.onConnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.left.onDisconnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onConnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onDisconnectionObservable.add(() => this._updateInputOutputTypes()),\r\n        ];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MathBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        let func: (state: NodeGeometryBuildState) => any;\r\n        const left = this.left;\r\n        const right = this.right;\r\n\r\n        if (!left.isConnected || !right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const leftIsScalar = left.type === NodeGeometryBlockConnectionPointTypes.Float || left.type === NodeGeometryBlockConnectionPointTypes.Int;\r\n        const rightIsScalar = right.type === NodeGeometryBlockConnectionPointTypes.Float || right.type === NodeGeometryBlockConnectionPointTypes.Int;\r\n\r\n        // If both input types are scalars, then this is a scalar operation.\r\n        const isScalar = leftIsScalar && rightIsScalar;\r\n\r\n        switch (this.operation) {\r\n            case MathBlockOperations.Add: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) + right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).add(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).add(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case MathBlockOperations.Subtract: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) - right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).subtract(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).subtract(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case MathBlockOperations.Multiply: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) * right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).multiply(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).multiply(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case MathBlockOperations.Divide: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) / right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).divide(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).divide(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case MathBlockOperations.Min: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return Math.min(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    const [vector, scalar] = leftIsScalar ? [right, left] : [left, right];\r\n\r\n                    switch (vector.type) {\r\n                        case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                            func = (state) => {\r\n                                return Vector2.Minimize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                            func = (state) => {\r\n                                return Vector3.Minimize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                            func = (state) => {\r\n                                return Vector4.Minimize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n            case MathBlockOperations.Max: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return Math.max(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    const [vector, scalar] = leftIsScalar ? [right, left] : [left, right];\r\n\r\n                    switch (vector.type) {\r\n                        case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                            func = (state) => {\r\n                                return Vector2.Maximize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                            func = (state) => {\r\n                                return Vector3.Maximize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                            func = (state) => {\r\n                                return Vector4.Maximize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            if (left.type === NodeGeometryBlockConnectionPointTypes.Int) {\r\n                return func(state) | 0;\r\n            }\r\n            return func(state);\r\n        };\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.operation = BABYLON.MathBlockOperations.${MathBlockOperations[this.operation]};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    private _updateInputOutputTypes() {\r\n        // First update the output type with the initial assumption that we'll base it on the left input.\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        if (this.left.isConnected && this.right.isConnected) {\r\n            // Both inputs are connected, so we need to determine the output type based on the input types.\r\n            if (\r\n                this.left.type === NodeGeometryBlockConnectionPointTypes.Int ||\r\n                (this.left.type === NodeGeometryBlockConnectionPointTypes.Float && this.right.type !== NodeGeometryBlockConnectionPointTypes.Int)\r\n            ) {\r\n                this.output._typeConnectionSource = this.right;\r\n            }\r\n        } else if (this.left.isConnected !== this.right.isConnected) {\r\n            // Only one input is connected, so we need to determine the output type based on the connected input.\r\n            this.output._typeConnectionSource = this.left.isConnected ? this.left : this.right;\r\n        }\r\n\r\n        // Next update the accepted connection point types for the inputs based on the current input connection state.\r\n        if (this.left.isConnected || this.right.isConnected) {\r\n            for (const [first, second] of [\r\n                [this.left, this.right],\r\n                [this.right, this.left],\r\n            ]) {\r\n                // Always allow Ints and Floats.\r\n                first.acceptedConnectionPointTypes = [NodeGeometryBlockConnectionPointTypes.Int, NodeGeometryBlockConnectionPointTypes.Float];\r\n\r\n                if (second.isConnected) {\r\n                    // The same types as the connected input are always allowed.\r\n                    first.acceptedConnectionPointTypes.push(second.type);\r\n\r\n                    // If the other input is a scalar, then we also allow Vector types.\r\n                    if (second.type === NodeGeometryBlockConnectionPointTypes.Int || second.type === NodeGeometryBlockConnectionPointTypes.Float) {\r\n                        first.acceptedConnectionPointTypes.push(\r\n                            NodeGeometryBlockConnectionPointTypes.Vector2,\r\n                            NodeGeometryBlockConnectionPointTypes.Vector3,\r\n                            NodeGeometryBlockConnectionPointTypes.Vector4\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        for (const observer of this._connectionObservers) {\r\n            observer.remove();\r\n        }\r\n        this._connectionObservers.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mathBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMathBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MathBlock\", MathBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to move a value from a range to another\r\n */\r\nexport class MapRangeBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new MapRangeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"fromMin\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"fromMax\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"toMin\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"toMax\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Vector4);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MapRangeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the fromMin input component\r\n     */\r\n    public get fromMin(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the fromMax input component\r\n     */\r\n    public get fromMax(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the toMin input component\r\n     */\r\n    public get toMin(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the toMax input component\r\n     */\r\n    public get toMax(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const value = this.value.getConnectedValue(state);\r\n            const fromMin = this.fromMin.getConnectedValue(state);\r\n            const fromMax = this.fromMax.getConnectedValue(state);\r\n            const toMin = this.toMin.getConnectedValue(state);\r\n            const toMax = this.toMax.getConnectedValue(state);\r\n\r\n            const result = ((value - fromMin) / (fromMax - fromMin)) * (toMax - toMin) + toMin;\r\n\r\n            if (this.output.type === NodeGeometryBlockConnectionPointTypes.Int) {\r\n                return Math.floor(result);\r\n            }\r\n\r\n            return result;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mapRangeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMapRangeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MapRangeBlock\", MapRangeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { WithinEpsilon } from \"../../../Maths/math.scalar.functions\";\r\nimport { GeometryInputBlock } from \"./geometryInputBlock.pure\";\r\nimport { type NodeGeometry } from \"../nodeGeometry\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Conditions supported by the condition block\r\n */\r\nexport enum ConditionBlockTests {\r\n    /** Equal */\r\n    Equal,\r\n    /** NotEqual */\r\n    NotEqual,\r\n    /** LessThan */\r\n    LessThan,\r\n    /** GreaterThan */\r\n    GreaterThan,\r\n    /** LessOrEqual */\r\n    LessOrEqual,\r\n    /** GreaterOrEqual */\r\n    GreaterOrEqual,\r\n    /** Logical Exclusive OR */\r\n    Xor,\r\n    /** Logical Or */\r\n    Or,\r\n    /** Logical And */\r\n    And,\r\n}\r\n\r\n/**\r\n * Block used to evaluate a condition and return a true or false value\r\n */\r\nexport class ConditionBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets the test used by the block\r\n     */\r\n    @editableInPropertyPage(\"Test\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Equal\", value: ConditionBlockTests.Equal },\r\n            { label: \"NotEqual\", value: ConditionBlockTests.NotEqual },\r\n            { label: \"LessThan\", value: ConditionBlockTests.LessThan },\r\n            { label: \"GreaterThan\", value: ConditionBlockTests.GreaterThan },\r\n            { label: \"LessOrEqual\", value: ConditionBlockTests.LessOrEqual },\r\n            { label: \"GreaterOrEqual\", value: ConditionBlockTests.GreaterOrEqual },\r\n            { label: \"Xor\", value: ConditionBlockTests.Xor },\r\n            { label: \"Or\", value: ConditionBlockTests.Or },\r\n            { label: \"And\", value: ConditionBlockTests.And },\r\n        ],\r\n    })\r\n    public test = ConditionBlockTests.Equal;\r\n\r\n    /**\r\n     * Gets or sets the epsilon value used for comparison\r\n     */\r\n    @editableInPropertyPage(\"Epsilon\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public epsilon = 0;\r\n\r\n    /**\r\n     * Create a new ConditionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"ifTrue\", NodeGeometryBlockConnectionPointTypes.AutoDetect, true, 1);\r\n        this.registerInput(\"ifFalse\", NodeGeometryBlockConnectionPointTypes.AutoDetect, true, 0);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[2];\r\n        this._outputs[0]._defaultConnectionPointType = NodeGeometryBlockConnectionPointTypes.Float;\r\n        this._inputs[0].acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[1].acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._linkConnectionTypes(2, 3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ConditionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the ifTrue input component\r\n     */\r\n    public get ifTrue(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the ifFalse input component\r\n     */\r\n    public get ifFalse(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure(nodeGeometry: NodeGeometry) {\r\n        if (!this.ifTrue.isConnected) {\r\n            const minInput =\r\n                (nodeGeometry.getBlockByPredicate((b) => b.isInput && (b as GeometryInputBlock).value === 1 && b.name === \"True\") as GeometryInputBlock) ||\r\n                new GeometryInputBlock(\"True\");\r\n            minInput.value = 1;\r\n            minInput.output.connectTo(this.ifTrue);\r\n        }\r\n\r\n        if (!this.ifFalse.isConnected) {\r\n            const maxInput =\r\n                (nodeGeometry.getBlockByPredicate((b) => b.isInput && (b as GeometryInputBlock).value === 0 && b.name === \"False\") as GeometryInputBlock) ||\r\n                new GeometryInputBlock(\"False\");\r\n            maxInput.value = 0;\r\n            maxInput.output.connectTo(this.ifFalse);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const left = this.left.getConnectedValue(state) as number;\r\n            const right = this.right.getConnectedValue(state) as number;\r\n            let condition = false;\r\n\r\n            switch (this.test) {\r\n                case ConditionBlockTests.Equal:\r\n                    condition = WithinEpsilon(left, right, this.epsilon);\r\n                    break;\r\n                case ConditionBlockTests.NotEqual:\r\n                    condition = !WithinEpsilon(left, right, this.epsilon);\r\n                    break;\r\n                case ConditionBlockTests.LessThan:\r\n                    condition = left < right + this.epsilon;\r\n                    break;\r\n                case ConditionBlockTests.GreaterThan:\r\n                    condition = left > right - this.epsilon;\r\n                    break;\r\n                case ConditionBlockTests.LessOrEqual:\r\n                    condition = left <= right + this.epsilon;\r\n                    break;\r\n                case ConditionBlockTests.GreaterOrEqual:\r\n                    condition = left >= right - this.epsilon;\r\n                    break;\r\n                case ConditionBlockTests.Xor:\r\n                    condition = (!!left && !right) || (!left && !!right);\r\n                    break;\r\n                case ConditionBlockTests.Or:\r\n                    condition = !!left || !!right;\r\n                    break;\r\n                case ConditionBlockTests.And:\r\n                    condition = !!left && !!right;\r\n                    break;\r\n            }\r\n            return condition;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            if (func(state)) {\r\n                return this.ifTrue.getConnectedValue(state);\r\n            }\r\n\r\n            return this.ifFalse.getConnectedValue(state);\r\n        };\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.test = BABYLON.ConditionBlockTests.${ConditionBlockTests[this.test]};\\n`;\r\n        codeString += `${this._codeVariableName}.epsilon = ${this.epsilon};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.test = this.test;\r\n        serializationObject.epsilon = this.epsilon;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.test = serializationObject.test;\r\n        if (serializationObject.epsilon !== undefined) {\r\n            this.epsilon = serializationObject.epsilon;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for conditionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterConditionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ConditionBlock\", ConditionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"./geometryInputBlock.pure\";\r\nimport { Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../../../types\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { NodeGeometryContextualSources } from \"../Enums/nodeGeometryContextualSources\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Locks supported by the random block\r\n */\r\nexport enum RandomBlockLocks {\r\n    /** None */\r\n    None,\r\n    /** LoopID */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    LoopID,\r\n    /** InstanceID */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    InstanceID,\r\n    /** Once */\r\n    Once,\r\n}\r\n\r\n/**\r\n * Block used to get a random number\r\n */\r\nexport class RandomBlock extends NodeGeometryBlock {\r\n    private _currentLockId = -1;\r\n    /**\r\n     * Gets or sets a value indicating if that block will lock its value for a specific duration\r\n     */\r\n    @editableInPropertyPage(\"LockMode\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"None\", value: RandomBlockLocks.None },\r\n            { label: \"LoopID\", value: RandomBlockLocks.LoopID },\r\n            { label: \"InstanceID\", value: RandomBlockLocks.InstanceID },\r\n            { label: \"Once\", value: RandomBlockLocks.Once },\r\n        ],\r\n    })\r\n    public lockMode = RandomBlockLocks.None;\r\n\r\n    /**\r\n     * Create a new RandomBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"min\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"max\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RandomBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the min input component\r\n     */\r\n    public get min(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the max input component\r\n     */\r\n    public get max(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.min.isConnected) {\r\n            const minInput = new GeometryInputBlock(\"Min\");\r\n            minInput.value = 0;\r\n            minInput.output.connectTo(this.min);\r\n        }\r\n\r\n        if (!this.max.isConnected) {\r\n            const maxInput = new GeometryInputBlock(\"Max\");\r\n            maxInput.value = 1;\r\n            maxInput.output.connectTo(this.max);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        let func: Nullable<(state: NodeGeometryBuildState) => any> = null;\r\n        this._currentLockId = -1;\r\n\r\n        switch (this.min.type) {\r\n            case NodeGeometryBlockConnectionPointTypes.Int:\r\n            case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? 0;\r\n                    const max = this.max.getConnectedValue(state) ?? 0;\r\n                    return min + Math.random() * (max - min);\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? Vector2.Zero();\r\n                    const max = this.max.getConnectedValue(state) ?? Vector2.Zero();\r\n                    return new Vector2(min.x + Math.random() * (max.x - min.x), min.y + Math.random() * (max.y - min.y));\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? Vector3.Zero();\r\n                    const max = this.max.getConnectedValue(state) ?? Vector3.Zero();\r\n                    return new Vector3(min.x + Math.random() * (max.x - min.x), min.y + Math.random() * (max.y - min.y), min.z + Math.random() * (max.z - min.z));\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? Vector4.Zero();\r\n                    const max = this.max.getConnectedValue(state) ?? Vector4.Zero();\r\n                    return new Vector4(\r\n                        min.x + Math.random() * (max.x - min.x),\r\n                        min.y + Math.random() * (max.y - min.y),\r\n                        min.z + Math.random() * (max.z - min.z),\r\n                        min.w + Math.random() * (max.w - min.w)\r\n                    );\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (this.lockMode === RandomBlockLocks.None || !func) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = (state) => {\r\n                let lockId = 0;\r\n\r\n                switch (this.lockMode) {\r\n                    case RandomBlockLocks.InstanceID:\r\n                        lockId = state.getContextualValue(NodeGeometryContextualSources.InstanceID, true) ?? 0;\r\n                        break;\r\n                    case RandomBlockLocks.LoopID:\r\n                        lockId = state.getContextualValue(NodeGeometryContextualSources.LoopID, true) ?? 0;\r\n                        break;\r\n                    case RandomBlockLocks.Once:\r\n                        lockId = state.buildId ?? 0;\r\n                        break;\r\n                }\r\n\r\n                if (this._currentLockId !== lockId || this.lockMode === RandomBlockLocks.None) {\r\n                    this._currentLockId = lockId;\r\n                    this.output._storedValue = func(state);\r\n                }\r\n                return this.output._storedValue;\r\n            };\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.lockMode = BABYLON.RandomBlockLocks.${RandomBlockLocks[this.lockMode]};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.lockMode = this.lockMode;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.lockMode = serializationObject.lockMode;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for randomBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRandomBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RandomBlock\", RandomBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { Clamp } from \"../../../Maths/math.scalar.functions\";\r\nimport { NodeGeometryContextualSources } from \"../Enums/nodeGeometryContextualSources\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a noise value\r\n */\r\nexport class NoiseBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new NoiseBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"offset\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"scale\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n\r\n        this.registerInput(\"octaves\", NodeGeometryBlockConnectionPointTypes.Float, true, 2, 0, 16);\r\n        this.registerInput(\"roughness\", NodeGeometryBlockConnectionPointTypes.Float, true, 0.5, 0, 1);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NoiseBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the offset input component\r\n     */\r\n    public get offset(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the scale input component\r\n     */\r\n    public get scale(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the octaves input component\r\n     */\r\n    public get octaves(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the roughtness input component\r\n     */\r\n    public get roughness(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _negateIf(value: number, condition: number) {\r\n        return condition !== 0 ? -value : value;\r\n    }\r\n\r\n    private _noiseGrad(hash: number, x: number, y: number, z: number) {\r\n        const h = hash & 15;\r\n        const u = h < 8 ? x : y;\r\n        const vt = h === 12 || h == 14 ? x : z;\r\n        const v = h < 4 ? y : vt;\r\n        return this._negateIf(u, h & u) + this._negateIf(v, h & 2);\r\n    }\r\n\r\n    private _fade(t: number) {\r\n        return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\r\n    }\r\n\r\n    private _hashBitRotate(x: number, k: number) {\r\n        return (x << k) | (x >> (32 - k));\r\n    }\r\n\r\n    private _hash(kx: number, ky: number, kz: number) {\r\n        let a: number, b: number, c: number;\r\n        a = b = c = 0xdeadbeef + (3 << 2) + 13;\r\n\r\n        c += kz;\r\n        b += ky;\r\n        a += kx;\r\n\r\n        c ^= b;\r\n        c -= this._hashBitRotate(b, 14);\r\n        a ^= c;\r\n        a -= this._hashBitRotate(c, 11);\r\n        b ^= a;\r\n        b -= this._hashBitRotate(a, 25);\r\n        c ^= b;\r\n        c -= this._hashBitRotate(b, 16);\r\n        a ^= c;\r\n        a -= this._hashBitRotate(c, 4);\r\n        b ^= a;\r\n        b -= this._hashBitRotate(a, 14);\r\n        c ^= b;\r\n        c -= this._hashBitRotate(b, 24);\r\n\r\n        return c;\r\n    }\r\n\r\n    private _mix(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, x: number, y: number, z: number) {\r\n        const x1 = 1.0 - x;\r\n        const y1 = 1.0 - y;\r\n        const z1 = 1.0 - z;\r\n        return z1 * (y1 * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x)) + z * (y1 * (v4 * x1 + v5 * x) + y * (v6 * x1 + v7 * x));\r\n    }\r\n\r\n    private _perlinNoise(position: Vector3) {\r\n        const x = (position.x | 0) - (position.x < 0 ? 1 : 0);\r\n        const y = (position.y | 0) - (position.y < 0 ? 1 : 0);\r\n        const z = (position.z | 0) - (position.z < 0 ? 1 : 0);\r\n\r\n        const fx = position.x - x;\r\n        const fy = position.y - y;\r\n        const fz = position.z - z;\r\n\r\n        const u = this._fade(fx);\r\n        const v = this._fade(fy);\r\n        const w = this._fade(fz);\r\n\r\n        return this._mix(\r\n            this._noiseGrad(this._hash(x, y, z), fx, fy, fz),\r\n            this._noiseGrad(this._hash(x + 1, y, z), fx - 1, fy, fz),\r\n            this._noiseGrad(this._hash(x, y + 1, z), fx, fy - 1, fz),\r\n            this._noiseGrad(this._hash(x + 1, y + 1, z), fx - 1, fy - 1, fz),\r\n            this._noiseGrad(this._hash(x, y, z + 1), fx, fy, fz - 1),\r\n            this._noiseGrad(this._hash(x + 1, y, z + 1), fx - 1, fy, fz - 1),\r\n            this._noiseGrad(this._hash(x, y + 1, z + 1), fx, fy - 1, fz - 1),\r\n            this._noiseGrad(this._hash(x + 1, y + 1, z + 1), fx - 1, fy - 1, fz - 1),\r\n            u,\r\n            v,\r\n            w\r\n        );\r\n    }\r\n\r\n    private _perlinSigned(position: Vector3) {\r\n        return this._perlinNoise(position) * 0.982;\r\n    }\r\n\r\n    private _perlin(position: Vector3) {\r\n        return this._perlinSigned(position) / 2.0 + 0.5;\r\n    }\r\n\r\n    /**\r\n     * Gets a perlin noise value\r\n     * @param octaves number of octaves\r\n     * @param roughness roughness\r\n     * @param _position position vector\r\n     * @param offset offset vector\r\n     * @param scale scale value\r\n     * @returns a value between 0 and 1\r\n     * @see Based on https://github.com/blender/blender/blob/main/source/blender/blenlib/intern/noise.cc#L533\r\n     */\r\n    public noise(octaves: number, roughness: number, _position: Vector3, offset: Vector3, scale: number) {\r\n        const position = new Vector3(_position.x * scale + offset.x, _position.y * scale + offset.y, _position.z * scale + offset.z);\r\n\r\n        let fscale = 1.0;\r\n        let amp = 1.0;\r\n        let maxamp = 0.0;\r\n        let sum = 0.0;\r\n        octaves = Clamp(octaves, 0, 15.0);\r\n        const step = octaves | 0;\r\n\r\n        for (let i = 0; i <= step; i++) {\r\n            const t = this._perlin(position.scale(fscale));\r\n            sum += t * amp;\r\n            maxamp += amp;\r\n            amp *= Clamp(roughness, 0.0, 1.0);\r\n            fscale *= 2.0;\r\n        }\r\n\r\n        const rmd = octaves - Math.floor(octaves);\r\n        if (rmd == 0.0) {\r\n            return sum / maxamp;\r\n        }\r\n\r\n        const t = this._perlin(position.scale(fscale));\r\n        let sum2 = sum + t * amp;\r\n        sum /= maxamp;\r\n        sum2 /= maxamp + amp;\r\n        return (1.0 - rmd) * sum + rmd * sum2;\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.output._storedFunction = (state) => {\r\n            const position = state.getContextualValue(NodeGeometryContextualSources.Positions) as Vector3;\r\n            const octaves = this.octaves.getConnectedValue(state);\r\n            const roughness = this.roughness.getConnectedValue(state);\r\n\r\n            const offset = this.offset.getConnectedValue(state) as Vector3;\r\n            const scale = this.scale.getConnectedValue(state);\r\n\r\n            return this.noise(octaves, roughness, position, offset, scale);\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for noiseBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNoiseBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NoiseBlock\", NoiseBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type VertexData } from \"../../../Meshes/mesh.vertexData\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to merge several geometries\r\n */\r\nexport class MergeGeometryBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Create a new MergeGeometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry0\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"geometry1\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry2\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry3\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry4\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MergeGeometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry0 input component\r\n     */\r\n    public get geometry0(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry1 input component\r\n     */\r\n    public get geometry1(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry2 input component\r\n     */\r\n    public get geometry2(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry3 input component\r\n     */\r\n    public get geometry3(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry4 input component\r\n     */\r\n    public get geometry4(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const vertexDataSource: VertexData[] = [];\r\n\r\n            if (this.geometry0.isConnected) {\r\n                const data = this.geometry0.getConnectedValue(state);\r\n                if (data) {\r\n                    vertexDataSource.push(data);\r\n                }\r\n            }\r\n            if (this.geometry1.isConnected) {\r\n                const data = this.geometry1.getConnectedValue(state);\r\n                if (data) {\r\n                    vertexDataSource.push(data);\r\n                }\r\n            }\r\n            if (this.geometry2.isConnected) {\r\n                const data = this.geometry2.getConnectedValue(state);\r\n                if (data) {\r\n                    vertexDataSource.push(data);\r\n                }\r\n            }\r\n            if (this.geometry3.isConnected) {\r\n                const data = this.geometry3.getConnectedValue(state);\r\n                if (data) {\r\n                    vertexDataSource.push(data);\r\n                }\r\n            }\r\n            if (this.geometry4.isConnected) {\r\n                const data = this.geometry4.getConnectedValue(state);\r\n                if (data) {\r\n                    vertexDataSource.push(data);\r\n                }\r\n            }\r\n\r\n            if (vertexDataSource.length === 0) {\r\n                return null;\r\n            }\r\n\r\n            let vertexData = vertexDataSource[0].clone(); // Preserve source data\r\n            const additionalVertexData: VertexData[] = vertexDataSource.slice(1);\r\n\r\n            if (additionalVertexData.length && vertexData) {\r\n                vertexData = vertexData.merge(additionalVertexData, true, false, true, true);\r\n            }\r\n            return vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mergeGeometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMergeGeometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MergeGeometryBlock\", MergeGeometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type VertexData } from \"../../mesh.vertexData\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to randomly pick a geometry from a collection\r\n */\r\nexport class GeometryCollectionBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new GeometryCollectionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry0\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry1\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry2\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry3\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry4\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry5\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry6\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry7\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry8\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"geometry9\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryCollectionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry0 input component\r\n     */\r\n    public get geometry0(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry1 input component\r\n     */\r\n    public get geometry1(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry2 input component\r\n     */\r\n    public get geometry2(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry3 input component\r\n     */\r\n    public get geometry3(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry4 input component\r\n     */\r\n    public get geometry4(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry5 input component\r\n     */\r\n    public get geometry5(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry6 input component\r\n     */\r\n    public get geometry6(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry7 input component\r\n     */\r\n    public get geometry7(): NodeGeometryConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry8 input component\r\n     */\r\n    public get geometry8(): NodeGeometryConnectionPoint {\r\n        return this._inputs[8];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry9 input component\r\n     */\r\n    public get geometry9(): NodeGeometryConnectionPoint {\r\n        return this._inputs[9];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _storeGeometry(input: NodeGeometryConnectionPoint, state: NodeGeometryBuildState, index: number, availables: VertexData[]) {\r\n        if (input.isConnected) {\r\n            const vertexData = input.getConnectedValue(state) as VertexData;\r\n            if (!vertexData) {\r\n                return;\r\n            }\r\n            vertexData.metadata = vertexData.metadata || {};\r\n            vertexData.metadata.collectionId = index;\r\n            availables.push(vertexData);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const availables: VertexData[] = [];\r\n\r\n            this._storeGeometry(this.geometry0, state, 0, availables);\r\n            this._storeGeometry(this.geometry1, state, 1, availables);\r\n            this._storeGeometry(this.geometry2, state, 2, availables);\r\n            this._storeGeometry(this.geometry3, state, 3, availables);\r\n            this._storeGeometry(this.geometry4, state, 4, availables);\r\n            this._storeGeometry(this.geometry5, state, 5, availables);\r\n            this._storeGeometry(this.geometry6, state, 6, availables);\r\n            this._storeGeometry(this.geometry7, state, 7, availables);\r\n            this._storeGeometry(this.geometry8, state, 8, availables);\r\n            this._storeGeometry(this.geometry9, state, 9, availables);\r\n\r\n            if (!availables.length) {\r\n                return null;\r\n            }\r\n            return availables[Math.round(Math.random() * (availables.length - 1))];\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryCollectionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryCollectionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryCollectionBlock\", GeometryCollectionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { type VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { FixFlippedFaces } from \"core/Maths/math.functions\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clean a geometry\r\n */\r\nexport class CleanGeometryBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Creates a new CleanGeometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CleanGeometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            if (!this.geometry.isConnected) {\r\n                return null;\r\n            }\r\n\r\n            const vertexData = (this.geometry.getConnectedValue(state) as VertexData).clone();\r\n\r\n            if (!vertexData.positions || !vertexData.indices || !vertexData.normals) {\r\n                return vertexData;\r\n            }\r\n\r\n            const indices = vertexData.indices;\r\n            const positions = vertexData.positions;\r\n\r\n            FixFlippedFaces(positions, indices);\r\n\r\n            return vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        return super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cleanGeometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCleanGeometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CleanGeometryBlock\", CleanGeometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used as a pass through\r\n */\r\nexport class GeometryElbowBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryElbowBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the time spent to build this block (in ms)\r\n     */\r\n    public override get buildExecutionTime() {\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryElbowBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input = this._inputs[0];\r\n\r\n        output._storedFunction = (state) => {\r\n            return input.getConnectedValue(state);\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryElbowBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryElbowBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryElbowBlock\", GeometryElbowBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to recompute normals for a geometry\r\n */\r\nexport class ComputeNormalsBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new ComputeNormalsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ComputeNormalsBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.output._storedFunction = (state) => {\r\n            if (!this.geometry.isConnected) {\r\n                return null;\r\n            }\r\n\r\n            const vertexData = this.geometry.getConnectedValue(state);\r\n            if (!vertexData) {\r\n                return null;\r\n            }\r\n\r\n            if (!vertexData.normals) {\r\n                vertexData.normals = [];\r\n            }\r\n\r\n            VertexData.ComputeNormals(vertexData.positions, vertexData.indices, vertexData.normals);\r\n\r\n            return vertexData;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for computeNormalsBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterComputeNormalsBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ComputeNormalsBlock\", ComputeNormalsBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to create a Vector2/3/4 out of individual or partial inputs\r\n */\r\nexport class VectorConverterBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new VectorConverterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"xyzw \", NodeGeometryBlockConnectionPointTypes.Vector4, true);\r\n        this.registerInput(\"xyz \", NodeGeometryBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"xy \", NodeGeometryBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"zw \", NodeGeometryBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"x \", NodeGeometryBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"y \", NodeGeometryBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"z \", NodeGeometryBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"w \", NodeGeometryBlockConnectionPointTypes.Float, true);\r\n\r\n        this.registerOutput(\"xyzw\", NodeGeometryBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"xyz\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"xy\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"zw\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"x\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"y\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"z\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"w\", NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"VectorConverterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component (input)\r\n     */\r\n    public get xyzwIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (input)\r\n     */\r\n    public get xyzIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (input)\r\n     */\r\n    public get xyIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (input)\r\n     */\r\n    public get zwIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component (input)\r\n     */\r\n    public get xIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component (input)\r\n     */\r\n    public get yIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component (input)\r\n     */\r\n    public get zIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component (input)\r\n     */\r\n    public get wIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component (output)\r\n     */\r\n    public get xyzwOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (output)\r\n     */\r\n    public get xyzOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (output)\r\n     */\r\n    public get xyOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (output)\r\n     */\r\n    public get zwOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component (output)\r\n     */\r\n    public get xOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component (output)\r\n     */\r\n    public get yOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component (output)\r\n     */\r\n    public get zOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component (output)\r\n     */\r\n    public get wOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[7];\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"xyzw \") {\r\n            return \"xyzwIn\";\r\n        }\r\n        if (name === \"xyz \") {\r\n            return \"xyzIn\";\r\n        }\r\n        if (name === \"xy \") {\r\n            return \"xyIn\";\r\n        }\r\n        if (name === \"zw \") {\r\n            return \"zwIn\";\r\n        }\r\n        if (name === \"x \") {\r\n            return \"xIn\";\r\n        }\r\n        if (name === \"y \") {\r\n            return \"yIn\";\r\n        }\r\n        if (name === \"z \") {\r\n            return \"zIn\";\r\n        }\r\n        if (name === \"w \") {\r\n            return \"wIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _outputRename(name: string) {\r\n        switch (name) {\r\n            case \"x\":\r\n                return \"xOut\";\r\n            case \"y\":\r\n                return \"yOut\";\r\n            case \"z\":\r\n                return \"zOut\";\r\n            case \"w\":\r\n                return \"wOut\";\r\n            case \"xy\":\r\n                return \"xyOut\";\r\n            case \"zw\":\r\n                return \"zwOut\";\r\n            case \"xyz\":\r\n                return \"xyzOut\";\r\n            case \"xyzw\":\r\n                return \"xyzwOut\";\r\n            default:\r\n                return name;\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const xInput = this.xIn;\r\n        const yInput = this.yIn;\r\n        const zInput = this.zIn;\r\n        const wInput = this.wIn;\r\n        const xyInput = this.xyIn;\r\n        const zwInput = this.zwIn;\r\n        const xyzInput = this.xyzIn;\r\n        const xyzwInput = this.xyzwIn;\r\n\r\n        const xyzwOutput = this.xyzwOut;\r\n        const xyzOutput = this.xyzOut;\r\n        const xyOutput = this.xyOut;\r\n        const zwOutput = this.zwOut;\r\n        const xOutput = this.xOut;\r\n        const yOutput = this.yOut;\r\n        const zOutput = this.zOut;\r\n        const wOutput = this.wOut;\r\n\r\n        const getData = (state: NodeGeometryBuildState): Vector4 => {\r\n            if (xyzwInput.isConnected) {\r\n                return xyzwInput.getConnectedValue(state);\r\n            }\r\n\r\n            let x: number = 0;\r\n            let y: number = 0;\r\n            let z: number = 0;\r\n            let w: number = 0;\r\n\r\n            if (xInput.isConnected) {\r\n                x = xInput.getConnectedValue(state);\r\n            }\r\n            if (yInput.isConnected) {\r\n                y = yInput.getConnectedValue(state);\r\n            }\r\n            if (zInput.isConnected) {\r\n                z = zInput.getConnectedValue(state);\r\n            }\r\n            if (wInput.isConnected) {\r\n                w = wInput.getConnectedValue(state);\r\n            }\r\n\r\n            if (xyInput.isConnected) {\r\n                const temp = xyInput.getConnectedValue(state);\r\n                if (temp) {\r\n                    x = temp.x;\r\n                    y = temp.y;\r\n                }\r\n            }\r\n            if (zwInput.isConnected) {\r\n                const temp = zwInput.getConnectedValue(state);\r\n                if (temp) {\r\n                    z = temp.x;\r\n                    w = temp.y;\r\n                }\r\n            }\r\n            if (xyzInput.isConnected) {\r\n                const temp = xyzInput.getConnectedValue(state);\r\n                if (temp) {\r\n                    x = temp.x;\r\n                    y = temp.y;\r\n                    z = temp.z;\r\n                }\r\n            }\r\n\r\n            return new Vector4(x, y, z, w);\r\n        };\r\n\r\n        xyzwOutput._storedFunction = (state) => getData(state);\r\n        xyzOutput._storedFunction = (state) => {\r\n            const data = getData(state);\r\n            return new Vector3(data.x, data.y, data.z);\r\n        };\r\n        xyOutput._storedFunction = (state) => {\r\n            const data = getData(state);\r\n            return new Vector2(data.x, data.y);\r\n        };\r\n        zwOutput._storedFunction = (state) => {\r\n            const data = getData(state);\r\n            return new Vector2(data.z, data.w);\r\n        };\r\n        xOutput._storedFunction = (state) => getData(state).x;\r\n        yOutput._storedFunction = (state) => getData(state).y;\r\n        zOutput._storedFunction = (state) => getData(state).z;\r\n        wOutput._storedFunction = (state) => getData(state).w;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for vectorConverterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVectorConverterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.VectorConverterBlock\", VectorConverterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to normalize vectors\r\n */\r\nexport class NormalizeVectorBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new NormalizeVectorBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"NormalizeVectorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n        this.output._storedFunction = null;\r\n\r\n        if (!this.input.isConnected) {\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => this.input.getConnectedValue(state).normalize();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for normalizeVectorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNormalizeVectorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.NormalizeVectorBlock\", NormalizeVectorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { VertexDataMaterialInfo, type VertexData } from \"../../../../Meshes/mesh.vertexData\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to affect a material ID to a geometry\r\n */\r\nexport class SetMaterialIDBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new SetMaterialIDBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"id\", NodeGeometryBlockConnectionPointTypes.Int, true, 0);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.id.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetMaterialIDBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the id input component\r\n     */\r\n    public get id(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        if (!this.geometry.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const vertexData = this.geometry.getConnectedValue(state) as VertexData;\r\n            if (!vertexData || !vertexData.indices || !vertexData.positions) {\r\n                return vertexData;\r\n            }\r\n\r\n            const materialInfo = new VertexDataMaterialInfo();\r\n            materialInfo.materialIndex = this.id.getConnectedValue(state) | 0;\r\n            materialInfo.indexStart = 0;\r\n            materialInfo.indexCount = vertexData.indices.length;\r\n            materialInfo.verticesStart = 0;\r\n            materialInfo.verticesCount = vertexData.positions.length / 3;\r\n\r\n            vertexData.materialInfos = [materialInfo];\r\n\r\n            return vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setMaterialIDBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetMaterialIDBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetMaterialIDBlock\", SetMaterialIDBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { Lattice } from \"core/Meshes/lattice\";\r\nimport { extractMinAndMax } from \"core/Maths/math.functions\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to apply Lattice on geometry\r\n */\r\nexport class LatticeBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndexX: number;\r\n    private _currentIndexY: number;\r\n    private _currentIndexZ: number;\r\n    private _lattice: Lattice;\r\n    private _indexVector3 = new Vector3();\r\n    private _currentControl = new Vector3();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Resolution on x axis\r\n     */\r\n    @editableInPropertyPage(\"resolutionX\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 1, max: 10 })\r\n    public resolutionX = 3;\r\n\r\n    /**\r\n     * Resolution on y axis\r\n     */\r\n    @editableInPropertyPage(\"resolutionY\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 1, max: 10 })\r\n    public resolutionY = 3;\r\n\r\n    /**\r\n     * Resolution on z axis\r\n     */\r\n    @editableInPropertyPage(\"resolutionZ\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 1, max: 10 })\r\n    public resolutionZ = 3;\r\n\r\n    /**\r\n     * Create a new LatticeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"controls\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndexX + this.resolutionX * (this._currentIndexY + this.resolutionY * this._currentIndexZ);\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this.getExecutionIndex();\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"LatticeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the controls input component\r\n     */\r\n    public get controls(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual positions\r\n     * In this case it will be the current position in the lattice\r\n     * @returns the current position in the lattice\r\n     */\r\n    public getOverridePositionsContextualValue() {\r\n        return this._indexVector3;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual normals\r\n     * In this case it will be the current control point being processed\r\n     * @returns the current control point being processed\r\n     */\r\n    public getOverrideNormalsContextualValue() {\r\n        return this._currentControl;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            if (this._vertexData) {\r\n                this._vertexData = this._vertexData.clone(); // Preserve source data\r\n            }\r\n\r\n            if (!this._vertexData || !this._vertexData.positions) {\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n            const positions = this._vertexData.positions;\r\n            const boundingInfo = extractMinAndMax(positions, 0, positions.length / 3);\r\n\r\n            // Building the lattice\r\n            const size = boundingInfo.maximum.subtract(boundingInfo.minimum);\r\n            this._lattice = new Lattice({\r\n                resolutionX: this.resolutionX,\r\n                resolutionY: this.resolutionY,\r\n                resolutionZ: this.resolutionZ,\r\n                size: size,\r\n                position: boundingInfo.minimum.add(size.scale(0.5)),\r\n            });\r\n\r\n            for (this._currentIndexX = 0; this._currentIndexX < this.resolutionX; this._currentIndexX++) {\r\n                for (this._currentIndexY = 0; this._currentIndexY < this.resolutionY; this._currentIndexY++) {\r\n                    for (this._currentIndexZ = 0; this._currentIndexZ < this.resolutionZ; this._currentIndexZ++) {\r\n                        this._indexVector3.set(this._currentIndexX, this._currentIndexY, this._currentIndexZ);\r\n                        const latticeControl = this._lattice.data[this._currentIndexX][this._currentIndexY][this._currentIndexZ];\r\n                        this._currentControl.copyFrom(latticeControl);\r\n                        const tempVector3 = this.controls.getConnectedValue(state) as Vector3;\r\n\r\n                        if (tempVector3) {\r\n                            latticeControl.set(tempVector3.x, tempVector3.y, tempVector3.z);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Apply lattice\r\n            this._lattice.deform(positions);\r\n\r\n            // Storage\r\n            state.restoreExecutionContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n\r\n        codeString += `${this._codeVariableName}.resolutionX = ${this.resolutionX};\\n`;\r\n        codeString += `${this._codeVariableName}.resolutionY = ${this.resolutionY};\\n`;\r\n        codeString += `${this._codeVariableName}.resolutionZ = ${this.resolutionZ};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.resolutionX = this.resolutionX;\r\n        serializationObject.resolutionY = this.resolutionY;\r\n        serializationObject.resolutionZ = this.resolutionZ;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n            this.resolutionX = serializationObject.resolutionX;\r\n            this.resolutionY = serializationObject.resolutionY;\r\n            this.resolutionZ = serializationObject.resolutionZ;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for latticeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterLatticeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.LatticeBlock\", LatticeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../types\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Trigonometry block\r\n */\r\nexport enum GeometryTrigonometryBlockOperations {\r\n    /** Cos */\r\n    Cos,\r\n    /** Sin */\r\n    Sin,\r\n    /** Abs */\r\n    Abs,\r\n    /** Exp */\r\n    Exp,\r\n    /** Round */\r\n    Round,\r\n    /** Floor */\r\n    Floor,\r\n    /** Ceiling */\r\n    Ceiling,\r\n    /** Square root */\r\n    Sqrt,\r\n    /** Log */\r\n    Log,\r\n    /** Tangent */\r\n    Tan,\r\n    /** Arc tangent */\r\n    ArcTan,\r\n    /** Arc cosinus */\r\n    ArcCos,\r\n    /** Arc sinus */\r\n    ArcSin,\r\n    /** Sign */\r\n    Sign,\r\n    /** Negate */\r\n    Negate,\r\n    /** OneMinus */\r\n    OneMinus,\r\n    /** Reciprocal */\r\n    Reciprocal,\r\n    /** ToDegrees */\r\n    ToDegrees,\r\n    /** ToRadians */\r\n    ToRadians,\r\n    /** Fract */\r\n    Fract,\r\n    /** Exp2 */\r\n    Exp2,\r\n}\r\n\r\n/**\r\n * Block used to apply trigonometry operation to floats\r\n */\r\nexport class GeometryTrigonometryBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        embedded: true,\r\n        notifiers: { rebuild: true },\r\n        options: [\r\n            { label: \"Cos\", value: GeometryTrigonometryBlockOperations.Cos },\r\n            { label: \"Sin\", value: GeometryTrigonometryBlockOperations.Sin },\r\n            { label: \"Abs\", value: GeometryTrigonometryBlockOperations.Abs },\r\n            { label: \"Exp\", value: GeometryTrigonometryBlockOperations.Exp },\r\n            { label: \"Exp2\", value: GeometryTrigonometryBlockOperations.Exp2 },\r\n            { label: \"Round\", value: GeometryTrigonometryBlockOperations.Round },\r\n            { label: \"Floor\", value: GeometryTrigonometryBlockOperations.Floor },\r\n            { label: \"Ceiling\", value: GeometryTrigonometryBlockOperations.Ceiling },\r\n            { label: \"Sqrt\", value: GeometryTrigonometryBlockOperations.Sqrt },\r\n            { label: \"Log\", value: GeometryTrigonometryBlockOperations.Log },\r\n            { label: \"Tan\", value: GeometryTrigonometryBlockOperations.Tan },\r\n            { label: \"ArcTan\", value: GeometryTrigonometryBlockOperations.ArcTan },\r\n            { label: \"ArcCos\", value: GeometryTrigonometryBlockOperations.ArcCos },\r\n            { label: \"ArcSin\", value: GeometryTrigonometryBlockOperations.ArcSin },\r\n            { label: \"Sign\", value: GeometryTrigonometryBlockOperations.Sign },\r\n            { label: \"Negate\", value: GeometryTrigonometryBlockOperations.Negate },\r\n            { label: \"OneMinus\", value: GeometryTrigonometryBlockOperations.OneMinus },\r\n            { label: \"Reciprocal\", value: GeometryTrigonometryBlockOperations.Reciprocal },\r\n            { label: \"ToDegrees\", value: GeometryTrigonometryBlockOperations.ToDegrees },\r\n            { label: \"ToRadians\", value: GeometryTrigonometryBlockOperations.ToRadians },\r\n            { label: \"Fract\", value: GeometryTrigonometryBlockOperations.Fract },\r\n        ],\r\n    })\r\n    public operation = GeometryTrigonometryBlockOperations.Cos;\r\n\r\n    /**\r\n     * Creates a new GeometryTrigonometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryTrigonometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n        let func: Nullable<(value: number) => number> = null;\r\n\r\n        switch (this.operation) {\r\n            case GeometryTrigonometryBlockOperations.Cos: {\r\n                func = (value: number) => Math.cos(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Sin: {\r\n                func = (value: number) => Math.sin(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Abs: {\r\n                func = (value: number) => Math.abs(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Exp: {\r\n                func = (value: number) => Math.exp(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Exp2: {\r\n                func = (value: number) => Math.pow(2, value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Round: {\r\n                func = (value: number) => Math.round(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Floor: {\r\n                func = (value: number) => Math.floor(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Ceiling: {\r\n                func = (value: number) => Math.ceil(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Sqrt: {\r\n                func = (value: number) => Math.sqrt(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Log: {\r\n                func = (value: number) => Math.log(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Tan: {\r\n                func = (value: number) => Math.tan(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.ArcTan: {\r\n                func = (value: number) => Math.atan(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.ArcCos: {\r\n                func = (value: number) => Math.acos(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.ArcSin: {\r\n                func = (value: number) => Math.asin(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Sign: {\r\n                func = (value: number) => Math.sign(value);\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Negate: {\r\n                func = (value: number) => -value;\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.OneMinus: {\r\n                func = (value: number) => 1 - value;\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Reciprocal: {\r\n                func = (value: number) => 1 / value;\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.ToRadians: {\r\n                func = (value: number) => (value * Math.PI) / 180;\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.ToDegrees: {\r\n                func = (value: number) => (value * 180) / Math.PI;\r\n                break;\r\n            }\r\n            case GeometryTrigonometryBlockOperations.Fract: {\r\n                func = (value: number) => {\r\n                    if (value >= 0) {\r\n                        return value - Math.floor(value);\r\n                    } else {\r\n                        return value - Math.ceil(value);\r\n                    }\r\n                };\r\n                break;\r\n            }\r\n        }\r\n        if (!func) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        switch (this.input.type) {\r\n            case NodeGeometryBlockConnectionPointTypes.Int:\r\n            case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return func(source);\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector2(func(source.x), func(source.y));\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector3(func(source.x), func(source.y), func(source.z));\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector4(func(source.x), func(source.y), func(source.z), func(source.w));\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString =\r\n            super._dumpPropertiesCode() +\r\n            `${this._codeVariableName}.operation = BABYLON.GeometryTrigonometryBlockOperations.${GeometryTrigonometryBlockOperations[this.operation]};\\n`;\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryTrigonometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryTrigonometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryTrigonometryBlock\", GeometryTrigonometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { Matrix, Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { type VertexData } from \"../../../Meshes/mesh.vertexData\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to apply a transform to a vector / geometry\r\n */\r\nexport class GeometryTransformBlock extends NodeGeometryBlock {\r\n    private _rotationMatrix = new Matrix();\r\n    private _scalingMatrix = new Matrix();\r\n    private _translationMatrix = new Matrix();\r\n    private _scalingRotationMatrix = new Matrix();\r\n    private _pivotMatrix = new Matrix();\r\n    private _backPivotMatrix = new Matrix();\r\n    private _transformMatrix = new Matrix();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new GeometryTransformBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix, true);\r\n        this.registerInput(\"translation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.One());\r\n        this.registerInput(\"pivot\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryTransformBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix input component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the translation input component\r\n     */\r\n    public get translation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the pivot input component\r\n     */\r\n    public get pivot(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const value = this.value.getConnectedValue(state);\r\n\r\n            if (!value) {\r\n                return null;\r\n            }\r\n\r\n            let matrix: Matrix;\r\n\r\n            if (this.matrix.isConnected) {\r\n                matrix = this.matrix.getConnectedValue(state);\r\n            } else {\r\n                const scaling = this.scaling.getConnectedValue(state) || Vector3.OneReadOnly;\r\n                const rotation = this.rotation.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n                const translation = this.translation.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n                const pivot = this.pivot.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n\r\n                // Transform\r\n                Matrix.TranslationToRef(-pivot.x, -pivot.y, -pivot.z, this._pivotMatrix);\r\n                Matrix.ScalingToRef(scaling.x, scaling.y, scaling.z, this._scalingMatrix);\r\n                Matrix.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, this._rotationMatrix);\r\n                Matrix.TranslationToRef(translation.x + pivot.x, translation.y + pivot.y, translation.z + pivot.z, this._translationMatrix);\r\n\r\n                this._pivotMatrix.multiplyToRef(this._scalingMatrix, this._backPivotMatrix);\r\n                this._backPivotMatrix.multiplyToRef(this._rotationMatrix, this._scalingRotationMatrix);\r\n                this._scalingRotationMatrix.multiplyToRef(this._translationMatrix, this._transformMatrix);\r\n                matrix = this._transformMatrix;\r\n            }\r\n\r\n            switch (this.value.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Geometry: {\r\n                    const geometry = (value as VertexData).clone();\r\n                    geometry.transform(matrix);\r\n                    return geometry;\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                    return Vector2.Transform(value, matrix);\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                    return Vector3.TransformCoordinates(value, matrix);\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                    return Vector4.TransformCoordinates(value, matrix);\r\n            }\r\n\r\n            return null;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryTransformBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryTransformBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryTransformBlock\", GeometryTransformBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { Matrix } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a rotation matrix on X Axis\r\n */\r\nexport class RotationXBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new RotationXBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"angle\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RotationXBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the angle input component\r\n     */\r\n    public get angle(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix output component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.matrix._storedFunction = (state) => {\r\n            return Matrix.RotationX(this.angle.getConnectedValue(state));\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for rotationXBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRotationXBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RotationXBlock\", RotationXBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { Matrix } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a rotation matrix on Y Axis\r\n */\r\nexport class RotationYBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new RotationYBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"angle\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RotationYBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the angle input component\r\n     */\r\n    public get angle(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix output component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.matrix._storedFunction = (state) => {\r\n            return Matrix.RotationY(this.angle.getConnectedValue(state));\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for rotationYBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRotationYBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RotationYBlock\", RotationYBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { Matrix } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a rotation matrix on Z Axis\r\n */\r\nexport class RotationZBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new RotationZBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"angle\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"RotationZBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the angle input component\r\n     */\r\n    public get angle(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix output component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.matrix._storedFunction = (state) => {\r\n            return Matrix.RotationZ(this.angle.getConnectedValue(state));\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for rotationZBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRotationZBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RotationZBlock\", RotationZBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { Matrix, Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a scaling matrix\r\n */\r\nexport class ScalingBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new ScalingBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"scale\", NodeGeometryBlockConnectionPointTypes.Vector3, false, Vector3.One());\r\n        this.registerOutput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ScalingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the scale input component\r\n     */\r\n    public get scale(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix output component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.scale.isConnected) {\r\n            const scaleInput = new GeometryInputBlock(\"Scale\");\r\n            scaleInput.value = new Vector3(1, 1, 1);\r\n            scaleInput.output.connectTo(this.scale);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.matrix._storedFunction = (state) => {\r\n            const value = this.scale.getConnectedValue(state) as Vector3;\r\n            return Matrix.Scaling(value.x, value.y, value.z);\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for scalingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScalingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ScalingBlock\", ScalingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { Matrix, Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a align matrix\r\n */\r\nexport class AlignBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new AlignBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"source\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Up());\r\n        this.registerInput(\"target\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Left());\r\n        this.registerOutput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"AlignBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the source input component\r\n     */\r\n    public get source(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the target input component\r\n     */\r\n    public get target(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix output component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.matrix._storedFunction = (state) => {\r\n            const source = (this.source.getConnectedValue(state) as Vector3).clone();\r\n            const target = (this.target.getConnectedValue(state) as Vector3).clone();\r\n            const result = new Matrix();\r\n\r\n            source.normalize();\r\n            target.normalize();\r\n\r\n            Matrix.RotationAlignToRef(source, target, result, true);\r\n\r\n            return result;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for alignBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAlignBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AlignBlock\", AlignBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { GeometryInputBlock } from \"../geometryInputBlock.pure\";\r\nimport { Matrix, Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get a translation matrix\r\n */\r\nexport class TranslationBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new TranslationBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"translation\", NodeGeometryBlockConnectionPointTypes.Vector3, false, Vector3.Zero());\r\n        this.registerOutput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TranslationBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the translation input component\r\n     */\r\n    public get translation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix output component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override autoConfigure() {\r\n        if (!this.translation.isConnected) {\r\n            const translationInput = new GeometryInputBlock(\"Translation\");\r\n            translationInput.value = new Vector3(0, 0, 0);\r\n            translationInput.output.connectTo(this.translation);\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        this.matrix._storedFunction = (state) => {\r\n            const value = this.translation.getConnectedValue(state) as Vector3;\r\n            return Matrix.Translation(value.x, value.y, value.z);\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for translationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTranslationBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TranslationBlock\", TranslationBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { Epsilon } from \"../../../../Maths/math.constants\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type INodeGeometryInstancingContext } from \"../../Interfaces/nodeGeometryInstancingContext\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to instance geometry on every vertex of a geometry\r\n */\r\nexport class InstantiateOnVerticesBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext, INodeGeometryInstancingContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n    private _currentLoopIndex: number;\r\n    private _indexTranslation: Nullable<{ [key: number]: number }> = null;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the block should remove duplicated positions\r\n     */\r\n    @editableInPropertyPage(\"Remove duplicated positions\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { update: true } })\r\n    public removeDuplicatedPositions = true;\r\n\r\n    /**\r\n     * Create a new InstantiateOnVerticesBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"instance\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"density\", NodeGeometryBlockConnectionPointTypes.Float, true, 1, 0, 1);\r\n        this.registerInput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix, true);\r\n        this.registerInput(\"offset\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.One());\r\n\r\n        this.scaling.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getInstanceIndex(): number {\r\n        return this._currentLoopIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._indexTranslation ? this._indexTranslation[this._currentIndex] : this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentLoopIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateOnVerticesBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the instance input component\r\n     */\r\n    public get instance(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the density input component\r\n     */\r\n    public get density(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix input component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset input component\r\n     */\r\n    public get offset(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n            state.pushInstancingContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions || !this.instance.isConnected) {\r\n                state.restoreExecutionContext();\r\n                state.restoreInstancingContext();\r\n                state.restoreGeometryContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            // Processing\r\n            let vertexCount = this._vertexData.positions.length / 3;\r\n            const additionalVertexData: VertexData[] = [];\r\n            const currentPosition = new Vector3();\r\n            const alreadyDone: number[] = [];\r\n            let vertices = this._vertexData.positions;\r\n            this._currentLoopIndex = 0;\r\n\r\n            if (this.removeDuplicatedPositions) {\r\n                this._indexTranslation = {};\r\n                for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                    const x = vertices[this._currentIndex * 3];\r\n                    const y = vertices[this._currentIndex * 3 + 1];\r\n                    const z = vertices[this._currentIndex * 3 + 2];\r\n                    let found = false;\r\n                    for (let index = 0; index < alreadyDone.length; index += 3) {\r\n                        if (Math.abs(alreadyDone[index] - x) < Epsilon && Math.abs(alreadyDone[index + 1] - y) < Epsilon && Math.abs(alreadyDone[index + 2] - z) < Epsilon) {\r\n                            found = true;\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (found) {\r\n                        continue;\r\n                    }\r\n                    this._indexTranslation[alreadyDone.length / 3] = this._currentIndex;\r\n                    alreadyDone.push(x, y, z);\r\n                }\r\n\r\n                vertices = alreadyDone;\r\n                vertexCount = vertices.length / 3;\r\n            } else {\r\n                this._indexTranslation = null;\r\n            }\r\n\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                const instanceGeometry = this.instance.getConnectedValue(state) as VertexData;\r\n\r\n                if (!instanceGeometry || !instanceGeometry.positions || instanceGeometry.positions.length === 0) {\r\n                    continue;\r\n                }\r\n\r\n                const density = this.density.getConnectedValue(state);\r\n\r\n                if (density < 1) {\r\n                    if (Math.random() > density) {\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                currentPosition.fromArray(vertices, this._currentIndex * 3);\r\n\r\n                // Clone the instance\r\n                const clone = instanceGeometry.clone();\r\n\r\n                // Transform\r\n                if (this.matrix.isConnected) {\r\n                    const transform = this.matrix.getConnectedValue(state);\r\n                    state._instantiateWithPositionAndMatrix(clone, currentPosition, transform, additionalVertexData);\r\n                } else {\r\n                    const offset = state.adaptInput(this.offset, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.ZeroReadOnly);\r\n                    const scaling = state.adaptInput(this.scaling, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.OneReadOnly);\r\n                    const rotation = this.rotation.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n\r\n                    currentPosition.addInPlace(offset);\r\n\r\n                    state._instantiate(clone, currentPosition, rotation, scaling, additionalVertexData);\r\n                }\r\n                this._currentLoopIndex++;\r\n            }\r\n\r\n            // Restore\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            state.restoreInstancingContext();\r\n\r\n            // Merge\r\n            if (additionalVertexData.length) {\r\n                if (additionalVertexData.length === 1) {\r\n                    this._vertexData = additionalVertexData[0];\r\n                } else {\r\n                    // We do not merge the main one as user can use a merge node if wanted\r\n                    const main = additionalVertexData.splice(0, 1)[0];\r\n                    this._vertexData = main.merge(additionalVertexData, true, false, true, true);\r\n                }\r\n            } else {\r\n                return null;\r\n            }\r\n\r\n            return this._vertexData;\r\n        };\r\n\r\n        // Storage\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.removeDuplicatedPositions = ${this.removeDuplicatedPositions ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.removeDuplicatedPositions = this.removeDuplicatedPositions;\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.removeDuplicatedPositions = serializationObject.removeDuplicatedPositions;\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instantiateOnVerticesBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstantiateOnVerticesBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstantiateOnVerticesBlock\", InstantiateOnVerticesBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { Vector2, Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { type INodeGeometryInstancingContext } from \"../../Interfaces/nodeGeometryInstancingContext\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to instance geometry on every face of a geometry\r\n */\r\nexport class InstantiateOnFacesBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext, INodeGeometryInstancingContext {\r\n    private _vertexData: VertexData;\r\n    private _currentFaceIndex: number;\r\n    private _currentLoopIndex: number;\r\n    private _currentPosition = new Vector3();\r\n    private _currentUV = new Vector2();\r\n    private _vertex0 = new Vector3();\r\n    private _vertex1 = new Vector3();\r\n    private _vertex2 = new Vector3();\r\n    private _tempVector0 = new Vector3();\r\n    private _tempVector1 = new Vector3();\r\n    private _uv0 = new Vector2();\r\n    private _uv1 = new Vector2();\r\n    private _uv2 = new Vector2();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new InstantiateOnFacesBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"instance\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"count\", NodeGeometryBlockConnectionPointTypes.Int, true, 256);\r\n        this.registerInput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix, true);\r\n        this.registerInput(\"offset\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.One());\r\n\r\n        this.scaling.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getInstanceIndex(): number {\r\n        return this._currentLoopIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return this._currentFaceIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentLoopIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual positions\r\n     * @returns the value associated with the source\r\n     */\r\n    public getOverridePositionsContextualValue() {\r\n        return this._currentPosition;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual normals\r\n     * @returns the value associated with the source\r\n     */\r\n    public getOverrideNormalsContextualValue() {\r\n        this._vertex1.subtractToRef(this._vertex0, this._tempVector0);\r\n        this._vertex2.subtractToRef(this._vertex1, this._tempVector1);\r\n        this._tempVector0.normalize();\r\n        this._tempVector1.normalize();\r\n        return Vector3.Cross(this._tempVector1, this._tempVector0);\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual UV1 se\r\n     * @returns the value associated with the source\r\n     */\r\n    public getOverrideUVs1ContextualValue() {\r\n        return this._currentUV;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateOnFacesBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the instance input component\r\n     */\r\n    public get instance(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the count input component\r\n     */\r\n    public get count(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix input component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset input component\r\n     */\r\n    public get offset(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n            state.pushInstancingContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions || !this._vertexData.indices || !this.instance.isConnected) {\r\n                state.restoreExecutionContext();\r\n                state.restoreInstancingContext();\r\n                state.restoreGeometryContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            // Processing\r\n            let instanceGeometry: Nullable<VertexData>;\r\n            const instanceCount = this.count.getConnectedValue(state);\r\n            const faceCount = this._vertexData.indices.length / 3;\r\n            const instancePerFace = instanceCount / faceCount;\r\n            let accumulatedCount = 0;\r\n            const additionalVertexData: VertexData[] = [];\r\n            let totalDone = 0;\r\n            this._currentLoopIndex = 0;\r\n\r\n            for (this._currentFaceIndex = 0; this._currentFaceIndex < faceCount; this._currentFaceIndex++) {\r\n                accumulatedCount += instancePerFace;\r\n                const countPerFace = (accumulatedCount | 0) - totalDone;\r\n\r\n                if (countPerFace < 1) {\r\n                    continue;\r\n                }\r\n\r\n                const faceID0 = this._vertexData.indices[this._currentFaceIndex * 3];\r\n                const faceID1 = this._vertexData.indices[this._currentFaceIndex * 3 + 1];\r\n                const faceID2 = this._vertexData.indices[this._currentFaceIndex * 3 + 2];\r\n\r\n                // Extract face vertices\r\n                this._vertex0.fromArray(this._vertexData.positions, faceID0 * 3);\r\n                this._vertex1.fromArray(this._vertexData.positions, faceID1 * 3);\r\n                this._vertex2.fromArray(this._vertexData.positions, faceID2 * 3);\r\n\r\n                if (this._vertexData.uvs) {\r\n                    this._uv0.fromArray(this._vertexData.uvs, faceID0 * 2);\r\n                    this._uv1.fromArray(this._vertexData.uvs, faceID1 * 2);\r\n                    this._uv2.fromArray(this._vertexData.uvs, faceID2 * 2);\r\n                }\r\n\r\n                for (let faceDispatchCount = 0; faceDispatchCount < countPerFace; faceDispatchCount++) {\r\n                    if (totalDone >= instanceCount) {\r\n                        break;\r\n                    }\r\n\r\n                    // Get random point on face\r\n                    let x = Math.random();\r\n                    let y = Math.random();\r\n\r\n                    if (x > y) {\r\n                        const temp = x;\r\n                        x = y;\r\n                        y = temp;\r\n                    }\r\n                    const s = x;\r\n                    const t = y - x;\r\n                    const u = 1 - s - t;\r\n\r\n                    this._currentPosition.set(\r\n                        s * this._vertex0.x + t * this._vertex1.x + u * this._vertex2.x,\r\n                        s * this._vertex0.y + t * this._vertex1.y + u * this._vertex2.y,\r\n                        s * this._vertex0.z + t * this._vertex1.z + u * this._vertex2.z\r\n                    );\r\n\r\n                    if (this._vertexData.uvs) {\r\n                        this._currentUV.set(s * this._uv0.x + t * this._uv1.x + u * this._uv2.x, s * this._uv0.y + t * this._uv1.y + u * this._uv2.y);\r\n                    }\r\n\r\n                    // Clone the instance\r\n                    instanceGeometry = this.instance.getConnectedValue(state) as VertexData;\r\n\r\n                    if (!instanceGeometry || !instanceGeometry.positions || instanceGeometry.positions.length === 0) {\r\n                        accumulatedCount -= instancePerFace;\r\n                        continue;\r\n                    }\r\n                    const clone = instanceGeometry.clone();\r\n\r\n                    if (this.matrix.isConnected) {\r\n                        const transform = this.matrix.getConnectedValue(state);\r\n                        state._instantiateWithPositionAndMatrix(clone, this._currentPosition, transform, additionalVertexData);\r\n                    } else {\r\n                        const offset = state.adaptInput(this.offset, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.ZeroReadOnly);\r\n                        const scaling = state.adaptInput(this.scaling, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.OneReadOnly);\r\n                        const rotation = this.rotation.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n\r\n                        this._currentPosition.addInPlace(offset);\r\n                        state._instantiate(clone, this._currentPosition, rotation, scaling, additionalVertexData);\r\n                    }\r\n                    totalDone++;\r\n                    this._currentLoopIndex++;\r\n                }\r\n            }\r\n\r\n            // Merge\r\n            if (additionalVertexData.length) {\r\n                if (additionalVertexData.length === 1) {\r\n                    this._vertexData = additionalVertexData[0];\r\n                } else {\r\n                    // We do not merge the main one as user can use a merge node if wanted\r\n                    const main = additionalVertexData.splice(0, 1)[0];\r\n                    this._vertexData = main.merge(additionalVertexData, true, false, true, true);\r\n                }\r\n            }\r\n            state.restoreExecutionContext();\r\n            state.restoreInstancingContext();\r\n            state.restoreGeometryContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        // Storage\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instantiateOnFacesBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstantiateOnFacesBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstantiateOnFacesBlock\", InstantiateOnFacesBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../../Decorators/nodeDecorator\";\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { Ray } from \"../../../../Culling/ray.pure\";\r\nimport { extractMinAndMax } from \"../../../../Maths/math.functions\";\r\nimport { type INodeGeometryInstancingContext } from \"../../Interfaces/nodeGeometryInstancingContext\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to instance geometry inside a geometry\r\n */\r\nexport class InstantiateOnVolumeBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext, INodeGeometryInstancingContext {\r\n    private _vertexData: VertexData;\r\n    private _currentLoopIndex: number;\r\n    private _currentPosition = new Vector3();\r\n    private _vertex0 = new Vector3();\r\n    private _vertex1 = new Vector3();\r\n    private _vertex2 = new Vector3();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that a grid pattern should be used\r\n     */\r\n    @editableInPropertyPage(\"Grid mode\", PropertyTypeForEdition.Boolean, \"MODES\", { notifiers: { rebuild: true } })\r\n    public gridMode = false;\r\n\r\n    /**\r\n     * Create a new InstantiateOnVolumeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"instance\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"count\", NodeGeometryBlockConnectionPointTypes.Int, true, 256);\r\n        this.registerInput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix, true);\r\n        this.registerInput(\"offset\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.One());\r\n        this.registerInput(\"gridSize\", NodeGeometryBlockConnectionPointTypes.Int, true, 10);\r\n\r\n        this.scaling.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getInstanceIndex(): number {\r\n        return this._currentLoopIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentLoopIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual positions\r\n     * @returns the value associated with the source\r\n     */\r\n    public getOverridePositionsContextualValue() {\r\n        return this._currentPosition;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateOnVolumeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the instance input component\r\n     */\r\n    public get instance(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the count input component\r\n     */\r\n    public get count(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix input component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the offset input component\r\n     */\r\n    public get offset(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the grid size input component\r\n     */\r\n    public get gridSize(): NodeGeometryConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _getValueOnGrid(step: number, size: number, min: number, max: number): number {\r\n        const cellSize = (max - min) / size;\r\n        return min + cellSize / 2 + step * cellSize;\r\n    }\r\n\r\n    private _getIndexinGrid(x: number, y: number, z: number, size: number) {\r\n        return x + y * size + z * size * size;\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n            state.pushInstancingContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions || !this._vertexData.indices || !this.instance.isConnected) {\r\n                state.restoreExecutionContext();\r\n                state.restoreInstancingContext();\r\n                state.restoreGeometryContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            // Processing\r\n            let instanceGeometry: Nullable<VertexData>;\r\n            const instanceCount = this.count.getConnectedValue(state);\r\n            const additionalVertexData: VertexData[] = [];\r\n            const boundingInfo = extractMinAndMax(this._vertexData.positions, 0, this._vertexData.positions.length / 3);\r\n            const min = boundingInfo.minimum;\r\n            const max = boundingInfo.maximum;\r\n            const direction = new Vector3(0.5, 0.8, 0.2);\r\n            const faceCount = this._vertexData.indices.length / 3;\r\n            const gridSize = this.gridSize.getConnectedValue(state);\r\n            this._currentLoopIndex = 0;\r\n\r\n            let candidatesCells: Array<boolean>;\r\n            if (this.gridMode) {\r\n                candidatesCells = [];\r\n                // Generates the list of candidates cells\r\n                for (let index = 0; index < gridSize * gridSize * gridSize; index++) {\r\n                    candidatesCells[index] = false;\r\n                }\r\n            }\r\n\r\n            for (let index = 0; index < instanceCount; index++) {\r\n                if (this.gridMode) {\r\n                    // Get a random cell\r\n                    let cellX = Math.floor(Math.random() * gridSize);\r\n                    let cellY = Math.floor(Math.random() * gridSize);\r\n                    let cellZ = Math.floor(Math.random() * gridSize);\r\n                    let cellIndex = this._getIndexinGrid(cellX, cellY, cellZ, gridSize);\r\n\r\n                    if (candidatesCells![cellIndex]) {\r\n                        // Find the first one that is free\r\n                        let found = false;\r\n                        for (let candidateIndex = 0; candidateIndex < gridSize * gridSize * gridSize; candidateIndex++) {\r\n                            if (!candidatesCells![candidateIndex]) {\r\n                                cellZ = Math.floor(candidateIndex / (gridSize * gridSize));\r\n                                cellY = Math.floor((candidateIndex - cellZ * gridSize * gridSize) / gridSize);\r\n                                cellX = candidateIndex - cellZ * gridSize * gridSize - cellY * gridSize;\r\n                                cellIndex = this._getIndexinGrid(cellX, cellY, cellZ, gridSize);\r\n                                found = true;\r\n                                break;\r\n                            }\r\n                        }\r\n                        if (!found) {\r\n                            // No more free cells\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (!candidatesCells![cellIndex]) {\r\n                        // Cell is free\r\n                        const x = this._getValueOnGrid(cellX, gridSize, min.x, max.x);\r\n                        const y = this._getValueOnGrid(cellY, gridSize, min.y, max.y);\r\n                        const z = this._getValueOnGrid(cellZ, gridSize, min.z, max.z);\r\n                        this._currentPosition.set(x, y, z);\r\n                        candidatesCells![cellIndex] = true;\r\n                    }\r\n                } else {\r\n                    this._currentPosition.set(Math.random() * (max.x - min.x) + min.x, Math.random() * (max.y - min.y) + min.y, Math.random() * (max.z - min.z) + min.z);\r\n                }\r\n\r\n                // Cast a ray from the random point in an arbitrary direction\r\n                const ray = new Ray(this._currentPosition, direction);\r\n\r\n                let intersectionCount = 0;\r\n                for (let currentFaceIndex = 0; currentFaceIndex < faceCount; currentFaceIndex++) {\r\n                    // Extract face vertices\r\n                    this._vertex0.fromArray(this._vertexData.positions, this._vertexData.indices[currentFaceIndex * 3] * 3);\r\n                    this._vertex1.fromArray(this._vertexData.positions, this._vertexData.indices[currentFaceIndex * 3 + 1] * 3);\r\n                    this._vertex2.fromArray(this._vertexData.positions, this._vertexData.indices[currentFaceIndex * 3 + 2] * 3);\r\n\r\n                    const currentIntersectInfo = ray.intersectsTriangle(this._vertex0, this._vertex1, this._vertex2);\r\n\r\n                    if (currentIntersectInfo && currentIntersectInfo.distance > 0) {\r\n                        intersectionCount++;\r\n                    }\r\n                }\r\n\r\n                if (intersectionCount % 2 === 0) {\r\n                    // We are outside, try again\r\n                    index--;\r\n                    continue;\r\n                }\r\n\r\n                // Clone the instance\r\n                instanceGeometry = this.instance.getConnectedValue(state) as VertexData;\r\n\r\n                if (!instanceGeometry || !instanceGeometry.positions || instanceGeometry.positions.length === 0) {\r\n                    continue;\r\n                }\r\n                const clone = instanceGeometry.clone();\r\n\r\n                if (this.matrix.isConnected) {\r\n                    const transform = this.matrix.getConnectedValue(state);\r\n                    state._instantiateWithPositionAndMatrix(clone, this._currentPosition, transform, additionalVertexData);\r\n                } else {\r\n                    const offset = state.adaptInput(this.offset, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.ZeroReadOnly);\r\n                    const scaling = state.adaptInput(this.scaling, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.OneReadOnly);\r\n                    const rotation = this.rotation.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n\r\n                    this._currentPosition.addInPlace(offset);\r\n\r\n                    state._instantiate(clone, this._currentPosition, rotation, scaling, additionalVertexData);\r\n                }\r\n                this._currentLoopIndex++;\r\n            }\r\n\r\n            // Merge\r\n            if (additionalVertexData.length) {\r\n                if (additionalVertexData.length === 1) {\r\n                    this._vertexData = additionalVertexData[0];\r\n                } else {\r\n                    // We do not merge the main one as user can use a merge node if wanted\r\n                    const main = additionalVertexData.splice(0, 1)[0];\r\n                    this._vertexData = main.merge(additionalVertexData, true, false, true, true);\r\n                }\r\n            }\r\n\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            state.restoreInstancingContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        // Storage\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.gridMode = ${this.gridMode ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.gridMode = this.gridMode;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n\r\n        if (serializationObject.gridMode !== undefined) {\r\n            this.gridMode = serializationObject.gridMode;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instantiateOnVolumeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstantiateOnVolumeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstantiateOnVolumeBlock\", InstantiateOnVolumeBlock);\r\n}\r\n","import { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { type INodeGeometryInstancingContext } from \"../../Interfaces/nodeGeometryInstancingContext\";\r\n\r\n/**\r\n * Block used as a base for InstantiateXXX blocks\r\n */\r\nexport abstract class InstantiateBaseBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext, INodeGeometryInstancingContext {\r\n    protected _vertexData: VertexData;\r\n    protected _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new InstantiateBaseBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"instance\", NodeGeometryBlockConnectionPointTypes.Geometry, true);\r\n        this.registerInput(\"count\", NodeGeometryBlockConnectionPointTypes.Int, true, 1);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getInstanceIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateBaseBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the instance input component\r\n     */\r\n    public get instance(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the count input component\r\n     */\r\n    public get count(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type VertexData } from \"../../../mesh.vertexData\";\r\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { InstantiateBaseBlock } from \"./instantiateBaseBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to instantiate a geometry inside a loop\r\n */\r\nexport class InstantiateBlock extends InstantiateBaseBlock {\r\n    protected override _vertexData: VertexData;\r\n    protected override _currentIndex: number;\r\n\r\n    /**\r\n     * Create a new InstantiateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"matrix\", NodeGeometryBlockConnectionPointTypes.Matrix, true);\r\n        this.registerInput(\"position\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.One());\r\n\r\n        this.scaling.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current instance index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public override getInstanceIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public override getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public override getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public override getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix input component\r\n     */\r\n    public get matrix(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get position(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n            state.pushInstancingContext(this);\r\n\r\n            // Processing\r\n            const iterationCount = this.count.getConnectedValue(state);\r\n            const additionalVertexData: VertexData[] = [];\r\n\r\n            for (this._currentIndex = 0; this._currentIndex < iterationCount; this._currentIndex++) {\r\n                const instanceGeometry = this.instance.getConnectedValue(state) as VertexData;\r\n\r\n                if (!instanceGeometry || !instanceGeometry.positions || instanceGeometry.positions.length === 0) {\r\n                    continue;\r\n                }\r\n\r\n                // Clone the instance\r\n                const clone = instanceGeometry.clone();\r\n\r\n                // Transform\r\n                if (this.matrix.isConnected) {\r\n                    const transform = this.matrix.getConnectedValue(state);\r\n                    state._instantiateWithMatrix(clone, transform, additionalVertexData);\r\n                } else {\r\n                    const position = this.position.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n                    const scaling = state.adaptInput(this.scaling, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.OneReadOnly);\r\n                    const rotation = this.rotation.getConnectedValue(state) || Vector3.ZeroReadOnly;\r\n                    state._instantiate(clone, position, rotation, scaling, additionalVertexData);\r\n                }\r\n            }\r\n\r\n            // Merge\r\n            if (additionalVertexData.length) {\r\n                if (additionalVertexData.length === 1) {\r\n                    this._vertexData = additionalVertexData[0];\r\n                } else {\r\n                    // We do not merge the main one as user can use a merge node if wanted\r\n                    const main = additionalVertexData.splice(0, 1)[0];\r\n                    this._vertexData = main.merge(additionalVertexData, true, false, true, true);\r\n                }\r\n            }\r\n\r\n            state.restoreExecutionContext();\r\n            state.restoreInstancingContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        // Storage\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instantiateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstantiateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstantiateBlock\", InstantiateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { Matrix, Quaternion, Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { InstantiateBaseBlock } from \"./instantiateBaseBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clone geometry along a line\r\n */\r\nexport class InstantiateLinearBlock extends InstantiateBaseBlock {\r\n    /**\r\n     * Create a new Instantiate Linear Block\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n        // Direction is magnitude per step\r\n        this.registerInput(\"direction\", NodeGeometryBlockConnectionPointTypes.Vector3, true, new Vector3(1, 0, 0));\r\n\r\n        // Rotation is magnitude per step\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, new Vector3(0, 0, 0));\r\n\r\n        // Scaling is magnitude per step\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, new Vector3(0, 0, 0));\r\n        this.scaling.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateLinearBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the direction input component\r\n     */\r\n    public get direction(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n            state.pushInstancingContext(this);\r\n\r\n            const iterationCount = this.count.getConnectedValue(state) as number;\r\n\r\n            const additionalVertexData: VertexData[] = [];\r\n\r\n            const transformMatrix = Matrix.Identity();\r\n            const transformOffset = Vector3.Zero();\r\n            const rotationOffset = Vector3.Zero();\r\n            const scaleOffset = Vector3.Zero();\r\n\r\n            for (this._currentIndex = 0; this._currentIndex < iterationCount; this._currentIndex++) {\r\n                const instanceGeometry = this.instance.getConnectedValue(state) as VertexData;\r\n\r\n                if (!instanceGeometry || !instanceGeometry.positions || instanceGeometry.positions.length === 0) {\r\n                    continue;\r\n                }\r\n                // Clone the instance\r\n                const clone = instanceGeometry.clone();\r\n\r\n                const direction = this.direction.getConnectedValue(state) as Vector3;\r\n                const rotation = this.rotation.getConnectedValue(state) as Vector3;\r\n                const scale = state.adaptInput(this.scaling, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.OneReadOnly);\r\n\r\n                transformOffset.copyFrom(direction.clone().scale(this._currentIndex));\r\n                rotationOffset.copyFrom(rotation.clone().scale(this._currentIndex));\r\n                scaleOffset.copyFrom(scale.clone().scale(this._currentIndex));\r\n                scaleOffset.addInPlaceFromFloats(1, 1, 1);\r\n\r\n                Matrix.ComposeToRef(scaleOffset, Quaternion.FromEulerAngles(rotationOffset.x, rotationOffset.y, rotationOffset.z), transformOffset, transformMatrix);\r\n\r\n                state._instantiateWithMatrix(clone, transformMatrix, additionalVertexData);\r\n            }\r\n\r\n            // Merge\r\n            if (additionalVertexData.length) {\r\n                if (additionalVertexData.length === 1) {\r\n                    this._vertexData = additionalVertexData[0];\r\n                } else {\r\n                    // We do not merge the main one as user can use a merge node if wanted\r\n                    const main = additionalVertexData.splice(0, 1)[0];\r\n                    this._vertexData = main.merge(additionalVertexData, true, false, true, true);\r\n                }\r\n            }\r\n\r\n            state.restoreExecutionContext();\r\n            state.restoreInstancingContext();\r\n            // Storage\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instantiateLinearBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstantiateLinearBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstantiateLinearBlock\", InstantiateLinearBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { Matrix, Quaternion, Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { InstantiateBaseBlock } from \"./instantiateBaseBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clone geometry in a radial shape\r\n */\r\nexport class InstantiateRadialBlock extends InstantiateBaseBlock {\r\n    /**\r\n     * Create a new InstantiateRadialBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n        this.registerInput(\"radius\", NodeGeometryBlockConnectionPointTypes.Int, true, 0, 0);\r\n\r\n        // Angle start and end\r\n        this.registerInput(\"angleStart\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"angleEnd\", NodeGeometryBlockConnectionPointTypes.Float, true, Math.PI * 2);\r\n\r\n        // Transform offset\r\n        this.registerInput(\"transform\", NodeGeometryBlockConnectionPointTypes.Vector3, true, new Vector3(0, 0, 0));\r\n\r\n        // Rotation is magnitude per step\r\n        this.registerInput(\"rotation\", NodeGeometryBlockConnectionPointTypes.Vector3, true, new Vector3(0, 0, 0));\r\n\r\n        // Scale is magnitude per step\r\n        this.registerInput(\"scaling\", NodeGeometryBlockConnectionPointTypes.Vector3, true, new Vector3(0, 0, 0));\r\n        this.scaling.acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"InstantiateRadialBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the direction input component\r\n     */\r\n    public get radius(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction input component\r\n     */\r\n    public get angleStart(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction input component\r\n     */\r\n    public get angleEnd(): NodeGeometryConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the transform input component\r\n     */\r\n    public get transform(): NodeGeometryConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the rotation input component\r\n     */\r\n    public get rotation(): NodeGeometryConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the scaling input component\r\n     */\r\n    public get scaling(): NodeGeometryConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n            state.pushInstancingContext(this);\r\n\r\n            const iterationCount = this.count.getConnectedValue(state) as number;\r\n\r\n            const additionalVertexData: VertexData[] = [];\r\n\r\n            const rotMatrix = Matrix.Identity();\r\n            const radiusMatrix = Matrix.Identity();\r\n            const transformMatrix = Matrix.Identity();\r\n            const transformOffset = Vector3.Zero();\r\n            const rotationOffset = Vector3.Zero();\r\n            const scaleOffset = Vector3.Zero();\r\n\r\n            for (this._currentIndex = 0; this._currentIndex < iterationCount; this._currentIndex++) {\r\n                const instanceGeometry = this.instance.getConnectedValue(state) as VertexData;\r\n\r\n                if (!instanceGeometry || !instanceGeometry.positions || instanceGeometry.positions.length === 0) {\r\n                    continue;\r\n                }\r\n                // Clone the instance\r\n                const clone = instanceGeometry.clone();\r\n\r\n                const radius = this.radius.getConnectedValue(state) as number;\r\n                const angleStart: number = this.angleStart.getConnectedValue(state) as number;\r\n                const angleEnd = this.angleEnd.getConnectedValue(state) as number;\r\n\r\n                const transform = this.transform.getConnectedValue(state) as Vector3;\r\n\r\n                const rotation = this.rotation.getConnectedValue(state) as Vector3;\r\n\r\n                const scale = state.adaptInput(this.scaling, NodeGeometryBlockConnectionPointTypes.Vector3, Vector3.OneReadOnly);\r\n\r\n                // Define arc size\r\n                const pieSlice = angleEnd - angleStart;\r\n                const rStep = pieSlice / iterationCount;\r\n\r\n                const angle = angleStart + rStep * this._currentIndex;\r\n                const angleQuat = Quaternion.FromEulerAngles(0, angle, 0);\r\n\r\n                // Get local transforms\r\n                transformOffset.copyFrom(transform.clone().scale(this._currentIndex));\r\n                rotationOffset.copyFrom(rotation.clone().scale(this._currentIndex));\r\n                scaleOffset.copyFrom(scale.clone().scale(this._currentIndex));\r\n                scaleOffset.addInPlaceFromFloats(1, 1, 1);\r\n\r\n                // Compose (rotMatrix x radius x scale x angle x user transform)\r\n                Matrix.RotationYawPitchRollToRef(rotationOffset.y, rotationOffset.x, rotationOffset.z, rotMatrix);\r\n                radiusMatrix.setTranslationFromFloats(0, 0, radius);\r\n                Matrix.ComposeToRef(scaleOffset, angleQuat, transformOffset, transformMatrix);\r\n\r\n                rotMatrix.multiplyToRef(radiusMatrix, radiusMatrix);\r\n                radiusMatrix.multiplyToRef(transformMatrix, transformMatrix);\r\n\r\n                state._instantiateWithMatrix(clone, transformMatrix, additionalVertexData);\r\n            }\r\n\r\n            // Merge\r\n            if (additionalVertexData.length) {\r\n                if (additionalVertexData.length === 1) {\r\n                    this._vertexData = additionalVertexData[0];\r\n                } else {\r\n                    // We do not merge the main one as user can use a merge node if wanted\r\n                    const main = additionalVertexData.splice(0, 1)[0];\r\n                    this._vertexData = main.merge(additionalVertexData, true, false, true, true);\r\n                }\r\n            }\r\n\r\n            // Storage\r\n            state.restoreExecutionContext();\r\n            state.restoreInstancingContext();\r\n            return this._vertexData;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for instantiateRadialBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterInstantiateRadialBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.InstantiateRadialBlock\", InstantiateRadialBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to convert from int to float\r\n */\r\nexport class IntFloatConverterBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new IntFloatConverterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"float \", NodeGeometryBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"int \", NodeGeometryBlockConnectionPointTypes.Int, true);\r\n\r\n        this.registerOutput(\"float\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"int\", NodeGeometryBlockConnectionPointTypes.Int);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"IntFloatConverterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the float input component\r\n     */\r\n    public get floatIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the int input component\r\n     */\r\n    public get intIn(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the float output component\r\n     */\r\n    public get floatOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the int output component\r\n     */\r\n    public get intOut(): NodeGeometryConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"float \") {\r\n            return \"floatIn\";\r\n        }\r\n        if (name === \"int \") {\r\n            return \"intIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.floatOut._storedFunction = (state) => {\r\n            if (this.floatIn.isConnected) {\r\n                return this.floatIn.getConnectedValue(state);\r\n            }\r\n            if (this.intIn.isConnected) {\r\n                return this.intIn.getConnectedValue(state);\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        this.intOut._storedFunction = (state) => {\r\n            if (this.floatIn.isConnected) {\r\n                return Math.floor(this.floatIn.getConnectedValue(state));\r\n            }\r\n            if (this.intIn.isConnected) {\r\n                return Math.floor(this.intIn.getConnectedValue(state));\r\n            }\r\n\r\n            return 0;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for intFloatConverterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterIntFloatConverterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.IntFloatConverterBlock\", IntFloatConverterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2ToFixed, Vector3ToFixed, Vector4ToFixed } from \"../../../Maths/math.vector.functions\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to debug values going through it\r\n */\r\nexport class DebugBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets the log entries\r\n     */\r\n    public log: string[][] = [];\r\n\r\n    /**\r\n     * Create a new DebugBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isDebug = true;\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the time spent to build this block (in ms)\r\n     */\r\n    public override get buildExecutionTime() {\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"DebugBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        if (!this.input.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.log = [];\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const input = this.input.getConnectedValue(state);\r\n\r\n            if (input === null || input === undefined) {\r\n                this.log.push([\"null\", \"\"]);\r\n                return input;\r\n            }\r\n\r\n            switch (this.input.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                    this.log.push([Vector2ToFixed(input, 4), input.toString()]);\r\n                    break;\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                    this.log.push([Vector3ToFixed(input, 4), input.toString()]);\r\n                    break;\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                    this.log.push([Vector4ToFixed(input, 4), input.toString()]);\r\n                    break;\r\n                default:\r\n                    this.log.push([input.toString(), input.toString()]);\r\n                    break;\r\n            }\r\n\r\n            return input;\r\n        };\r\n\r\n        if (this.output.isConnected) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshesNodeBlocksDebugBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshesNodeBlocksDebugBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DebugBlock\", DebugBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type VertexData } from \"../../mesh.vertexData\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get information about a geometry\r\n */\r\nexport class GeometryInfoBlock extends NodeGeometryBlock {\r\n    private _currentVertexData: VertexData;\r\n    /**\r\n     * Create a new GeometryInfoBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerOutput(\"id\", NodeGeometryBlockConnectionPointTypes.Int);\r\n        this.registerOutput(\"collectionId\", NodeGeometryBlockConnectionPointTypes.Int);\r\n        this.registerOutput(\"verticesCount\", NodeGeometryBlockConnectionPointTypes.Int);\r\n        this.registerOutput(\"facesCount\", NodeGeometryBlockConnectionPointTypes.Int);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryInfoBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the id output component\r\n     */\r\n    public get id(): NodeGeometryConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the collectionId output component\r\n     */\r\n    public get collectionId(): NodeGeometryConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the verticesCount output component\r\n     */\r\n    public get verticesCount(): NodeGeometryConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the facesCount output component\r\n     */\r\n    public get facesCount(): NodeGeometryConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.geometry.isConnected) {\r\n            this.id._storedValue = 0;\r\n            this.collectionId._storedValue = 0;\r\n            this.verticesCount._storedValue = 0;\r\n            this.facesCount._storedValue = 0;\r\n            this.output._storedValue = 0;\r\n            this.id._storedFunction = null;\r\n            this.collectionId._storedFunction = null;\r\n            this.verticesCount._storedFunction = null;\r\n            this.facesCount._storedFunction = null;\r\n            this.output._storedFunction = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state: NodeGeometryBuildState) => {\r\n            this._currentVertexData = this.geometry.getConnectedValue(state) as VertexData;\r\n            return this._currentVertexData;\r\n        };\r\n        this.id._storedFunction = (state: NodeGeometryBuildState) => {\r\n            this._currentVertexData = this._currentVertexData || (this.geometry.getConnectedValue(state) as VertexData);\r\n            return this._currentVertexData.uniqueId;\r\n        };\r\n        this.collectionId._storedFunction = (state: NodeGeometryBuildState) => {\r\n            this._currentVertexData = this._currentVertexData || (this.geometry.getConnectedValue(state) as VertexData);\r\n            return this._currentVertexData.metadata ? this._currentVertexData.metadata.collectionId : 0;\r\n        };\r\n        this.verticesCount._storedFunction = (state: NodeGeometryBuildState) => {\r\n            this._currentVertexData = this._currentVertexData || (this.geometry.getConnectedValue(state) as VertexData);\r\n            return this._currentVertexData.positions ? this._currentVertexData.positions.length / 3 : 0;\r\n        };\r\n        this.facesCount._storedFunction = (state: NodeGeometryBuildState) => {\r\n            this._currentVertexData = this._currentVertexData || (this.geometry.getConnectedValue(state) as VertexData);\r\n            return this._currentVertexData.indices ? this._currentVertexData.indices.length / 3 : 0;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryInfoBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryInfoBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryInfoBlock\", GeometryInfoBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { Vector2, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Type of mappings supported by the mapping block\r\n */\r\nexport enum MappingTypes {\r\n    /** Spherical */\r\n    Spherical,\r\n    /** Cylindrical */\r\n    Cylindrical,\r\n    /** Cubic */\r\n    Cubic,\r\n}\r\n\r\n/**\r\n * Block used to generate UV coordinates\r\n */\r\nexport class MappingBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets the mapping type used by the block\r\n     */\r\n    @editableInPropertyPage(\"Mapping\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Spherical\", value: MappingTypes.Spherical },\r\n            { label: \"Cylindrical\", value: MappingTypes.Cylindrical },\r\n            { label: \"Cubic\", value: MappingTypes.Cubic },\r\n        ],\r\n    })\r\n    public mapping = MappingTypes.Spherical;\r\n\r\n    /**\r\n     * Create a new MappingBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"position\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"normal\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"center\", NodeGeometryBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerOutput(\"uv\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MappingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get position(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal input component\r\n     */\r\n    public get normal(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the center input component\r\n     */\r\n    public get center(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get uv(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.position.isConnected) {\r\n            this.uv._storedFunction = null;\r\n            this.uv._storedValue = null;\r\n            return;\r\n        }\r\n        const tempDirection = Vector3.Zero();\r\n\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const position = (this.position.getConnectedValue(state) as Vector3) || Vector3.Zero();\r\n            const normal = (this.normal.getConnectedValue(state) as Vector3) || Vector3.Zero();\r\n            const center = this.center.getConnectedValue(state) as Vector3;\r\n            const uv = Vector2.Zero();\r\n\r\n            switch (this.mapping) {\r\n                case MappingTypes.Spherical: {\r\n                    position.subtractToRef(center, tempDirection);\r\n                    const len = tempDirection.length();\r\n                    if (len > 0) {\r\n                        uv.y = Math.acos(tempDirection.y / len) / Math.PI;\r\n                        if (tempDirection.x !== 0 || tempDirection.z !== 0) {\r\n                            uv.x = Math.atan2(tempDirection.x, tempDirection.z) / (Math.PI * 2);\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n                case MappingTypes.Cylindrical: {\r\n                    position.subtractToRef(center, tempDirection);\r\n                    const len = tempDirection.length();\r\n                    if (len > 0) {\r\n                        uv.x = Math.atan2(tempDirection.x / len, tempDirection.z / len) / (Math.PI * 2);\r\n                        uv.y = (tempDirection.y + 1.0) / 2.0;\r\n                    }\r\n                    break;\r\n                }\r\n                case MappingTypes.Cubic: {\r\n                    // Find the largest component of the normal vector\r\n                    const absX = Math.abs(normal.x);\r\n                    const absY = Math.abs(normal.y);\r\n                    const absZ = Math.abs(normal.z);\r\n                    const maxDim = Math.max(Math.abs(position.x), Math.abs(position.y), Math.abs(position.z));\r\n\r\n                    let u: number, v: number;\r\n\r\n                    if (absX >= absY && absX >= absZ) {\r\n                        u = position.y / maxDim - center.y;\r\n                        v = position.z / maxDim - center.z;\r\n                    } else if (absY >= absX && absY >= absZ) {\r\n                        u = position.x / maxDim - center.x;\r\n                        v = position.z / maxDim - center.z;\r\n                    } else {\r\n                        u = position.x / maxDim - center.x;\r\n                        v = position.y / maxDim - center.y;\r\n                    }\r\n\r\n                    uv.x = (u + 1) / 2;\r\n                    uv.y = (v + 1) / 2;\r\n                }\r\n            }\r\n            return uv;\r\n        };\r\n\r\n        this.uv._storedFunction = (state) => {\r\n            return func(state);\r\n        };\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.mapping = BABYLON.MappingTypes.${MappingTypes[this.mapping]};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.mapping = this.mapping;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.mapping = serializationObject.mapping;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for mappingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMappingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MappingBlock\", MappingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { type Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to compose two matrices\r\n */\r\nexport class MatrixComposeBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new MatrixComposeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"matrix0\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this.registerInput(\"matrix1\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MatrixComposeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix0 input component\r\n     */\r\n    public get matrix0(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the matrix1 input component\r\n     */\r\n    public get matrix1(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.output._storedFunction = (state: NodeGeometryBuildState) => {\r\n            if (!this.matrix0.isConnected || !this.matrix1.isConnected) {\r\n                return null;\r\n            }\r\n\r\n            const matrix0 = this.matrix0.getConnectedValue(state) as Matrix;\r\n            const matrix1 = this.matrix1.getConnectedValue(state) as Matrix;\r\n\r\n            if (!matrix0 || !matrix1) {\r\n                return null;\r\n            }\r\n            return matrix0.multiply(matrix1);\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for matrixComposeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMatrixComposeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MatrixComposeBlock\", MatrixComposeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type TeleportOutBlock } from \"./teleportOutBlock.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to teleport a value to an endpoint\r\n */\r\nexport class TeleportInBlock extends NodeGeometryBlock {\r\n    private _endpoints: TeleportOutBlock[] = [];\r\n\r\n    /** Gets the list of attached endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /**\r\n     * Create a new TeleportInBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n        this._isTeleportIn = true;\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TeleportInBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /** @internal */\r\n    public override _dumpCode(uniqueNames: string[], alreadyDumped: NodeGeometryBlock[]) {\r\n        let codeString = super._dumpCode(uniqueNames, alreadyDumped);\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            if (alreadyDumped.indexOf(endpoint) === -1) {\r\n                codeString += endpoint._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given type\r\n     * @param type defines the potential type to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOfType(type: string): boolean {\r\n        if (this.getClassName() === type) {\r\n            return true;\r\n        }\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint.isAnAncestorOfType(type)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOf(block: NodeGeometryBlock): boolean {\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint === block) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.isAnAncestorOf(block)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Get the first descendant using a predicate\r\n     * @param predicate defines the predicate to check\r\n     * @returns descendant or null if none found\r\n     */\r\n    public override getDescendantOfPredicate(predicate: (block: NodeGeometryBlock) => boolean): Nullable<NodeGeometryBlock> {\r\n        if (predicate(this)) {\r\n            return this;\r\n        }\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            const descendant = endpoint.getDescendantOfPredicate(predicate);\r\n\r\n            if (descendant) {\r\n                return descendant;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Add an enpoint to this block\r\n     * @param endpoint define the endpoint to attach to\r\n     */\r\n    public attachToEndpoint(endpoint: TeleportOutBlock) {\r\n        endpoint.detach();\r\n\r\n        this._endpoints.push(endpoint);\r\n        endpoint._entryPoint = this;\r\n        endpoint._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        endpoint._tempEntryPointUniqueId = null;\r\n        endpoint.name = \"> \" + this.name;\r\n    }\r\n\r\n    /**\r\n     * Remove enpoint from this block\r\n     * @param endpoint define the endpoint to remove\r\n     */\r\n    public detachFromEndpoint(endpoint: TeleportOutBlock) {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index !== -1) {\r\n            this._endpoints.splice(index, 1);\r\n            endpoint._outputs[0]._typeConnectionSource = null;\r\n            endpoint._entryPoint = null;\r\n        }\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        for (const endpoint of this._endpoints) {\r\n            endpoint.output._storedFunction = (state) => {\r\n                return this.input.getConnectedValue(state);\r\n            };\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshesNodeBlocksTeleportTeleportInBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshesNodeBlocksTeleportTeleportInBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TeleportInBlock\", TeleportInBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type TeleportInBlock } from \"./teleportInBlock.pure\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to receive a value from a teleport entry point\r\n */\r\nexport class TeleportOutBlock extends NodeGeometryBlock {\r\n    /** @internal */\r\n    public _entryPoint: Nullable<TeleportInBlock> = null;\r\n    /** @internal */\r\n    public _tempEntryPointUniqueId: Nullable<number> = null;\r\n\r\n    /**\r\n     * Create a new TeleportOutBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isTeleportOut = true;\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n    }\r\n\r\n    /**\r\n     * Gets the entry point\r\n     */\r\n    public get entryPoint() {\r\n        return this._entryPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"TeleportOutBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** Detach from entry point */\r\n    public detach() {\r\n        if (!this._entryPoint) {\r\n            return;\r\n        }\r\n        this._entryPoint.detachFromEndpoint(this);\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        // Do nothing\r\n        // All work done by the emitter\r\n    }\r\n\r\n    protected override _customBuildStep(state: NodeGeometryBuildState): void {\r\n        if (this.entryPoint) {\r\n            this.entryPoint.build(state);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _dumpCode(uniqueNames: string[], alreadyDumped: NodeGeometryBlock[]) {\r\n        let codeString: string = \"\";\r\n        if (this.entryPoint) {\r\n            if (alreadyDumped.indexOf(this.entryPoint) === -1) {\r\n                codeString += this.entryPoint._dumpCode(uniqueNames, alreadyDumped);\r\n            }\r\n        }\r\n\r\n        return codeString + super._dumpCode(uniqueNames, alreadyDumped);\r\n    }\r\n\r\n    /** @internal */\r\n    public override _dumpCodeForOutputConnections(alreadyDumped: NodeGeometryBlock[]) {\r\n        let codeString = super._dumpCodeForOutputConnections(alreadyDumped);\r\n\r\n        if (this.entryPoint) {\r\n            codeString += this.entryPoint._dumpCodeForOutputConnections(alreadyDumped);\r\n        }\r\n\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @returns a copy of the current block\r\n     */\r\n    public override clone() {\r\n        const clone = super.clone();\r\n\r\n        if (this.entryPoint) {\r\n            this.entryPoint.attachToEndpoint(clone as TeleportOutBlock);\r\n        }\r\n\r\n        return clone;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode();\r\n        if (this.entryPoint) {\r\n            codeString += `${this.entryPoint._codeVariableName}.attachToEndpoint(${this._codeVariableName});\\n`;\r\n        }\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.entryPoint = this.entryPoint?.uniqueId ?? \"\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this._tempEntryPointUniqueId = serializationObject.entryPoint;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshesNodeBlocksTeleportTeleportOutBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshesNodeBlocksTeleportTeleportOutBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TeleportOutBlock\", TeleportOutBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type INodeGeometryTextureData } from \"../../Interfaces/nodeGeometryTextureData\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { type Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { TextureTools } from \"core/Misc/textureTools\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used to load texture data\r\n */\r\nexport class GeometryTextureBlock extends NodeGeometryBlock {\r\n    private _data: Nullable<Float32Array> = null;\r\n    private _width: number;\r\n    private _height: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block should serialize its cached data\r\n     */\r\n    public serializedCachedData = false;\r\n\r\n    /**\r\n     * Gets the texture data\r\n     */\r\n    public get textureData(): Nullable<Float32Array> {\r\n        return this._data;\r\n    }\r\n\r\n    /**\r\n     * Gets the texture width\r\n     */\r\n    public get textureWidth() {\r\n        return this._width;\r\n    }\r\n\r\n    /**\r\n     * Gets the texture height\r\n     */\r\n    public get textureHeight() {\r\n        return this._height;\r\n    }\r\n\r\n    /**\r\n     * Creates a new GeometryTextureBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerOutput(\"texture\", NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryTextureBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the texture component\r\n     */\r\n    public get texture(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private async _prepareImgToLoadAsync(url: string) {\r\n        return await new Promise<void>((resolve, reject) => {\r\n            const img = new Image();\r\n            const canvas = document.createElement(\"canvas\");\r\n            const ctx = canvas.getContext(\"2d\");\r\n\r\n            img.onload = () => {\r\n                canvas.width = img.width;\r\n                canvas.height = img.height;\r\n\r\n                ctx!.drawImage(img, 0, 0);\r\n\r\n                const imageData = ctx!.getImageData(0, 0, img.width, img.height);\r\n                const pixels = imageData.data;\r\n                const floatArray = new Float32Array(pixels.length);\r\n\r\n                for (let i = 0; i < pixels.length; i++) {\r\n                    floatArray[i] = pixels[i] / 255.0;\r\n                }\r\n\r\n                this._data = floatArray;\r\n                this._width = img.width;\r\n                this._height = img.height;\r\n                resolve();\r\n            };\r\n\r\n            img.onerror = () => {\r\n                this._data = null;\r\n                reject(new Error(\"Failed to load image\"));\r\n            };\r\n\r\n            img.src = url;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Remove stored data\r\n     */\r\n    public cleanData() {\r\n        this._data = null;\r\n    }\r\n\r\n    /**\r\n     * Load the texture data from a Float32Array\r\n     * @param data defines the data to load\r\n     * @param width defines the width of the texture\r\n     * @param height defines the height of the texture\r\n     */\r\n    public loadTextureFromData(data: Float32Array, width: number, height: number) {\r\n        this._data = data;\r\n        this._width = width;\r\n        this._height = height;\r\n    }\r\n\r\n    /**\r\n     * Load the texture data\r\n     * @param imageFile defines the file to load data from\r\n     * @returns a promise fulfilled when image data is loaded\r\n     */\r\n    public async loadTextureFromFileAsync(imageFile: File) {\r\n        return await this._prepareImgToLoadAsync(URL.createObjectURL(imageFile));\r\n    }\r\n\r\n    /**\r\n     * Load the texture data\r\n     * @param url defines the url to load data from\r\n     * @returns a promise fulfilled when image data is loaded\r\n     */\r\n    public async loadTextureFromUrlAsync(url: string) {\r\n        return await this._prepareImgToLoadAsync(url);\r\n    }\r\n\r\n    /**\r\n     * Load the texture data\r\n     * @param texture defines the source texture\r\n     * @returns a promise fulfilled when image data is loaded\r\n     */\r\n    public async extractFromTextureAsync(texture: Texture) {\r\n        return await new Promise<void>((resolve, reject) => {\r\n            if (!texture.isReady()) {\r\n                texture.onLoadObservable.addOnce(async () => {\r\n                    try {\r\n                        await this.extractFromTextureAsync(texture);\r\n                        resolve();\r\n                    } catch (e) {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(e);\r\n                    }\r\n                });\r\n                return;\r\n            }\r\n            const size = texture.getSize();\r\n            TextureTools.GetTextureDataAsync(texture, size.width, size.height)\r\n                // eslint-disable-next-line github/no-then\r\n                .then((data) => {\r\n                    const floatArray = new Float32Array(data.length);\r\n\r\n                    for (let i = 0; i < data.length; i++) {\r\n                        floatArray[i] = data[i] / 255.0;\r\n                    }\r\n                    this._data = floatArray;\r\n                    this._width = size.width;\r\n                    this._height = size.height;\r\n                    resolve();\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .catch(reject);\r\n        });\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this._data) {\r\n            this.texture._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const textureData: INodeGeometryTextureData = {\r\n            data: this._data,\r\n            width: this._width,\r\n            height: this._height,\r\n        };\r\n\r\n        this.texture._storedValue = textureData;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.width = this._width;\r\n        serializationObject.height = this._height;\r\n        serializationObject.serializedCachedData = this.serializedCachedData;\r\n        if (this._data && this.serializedCachedData) {\r\n            serializationObject.data = Array.from(this._data);\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this._width = serializationObject.width;\r\n        this._height = serializationObject.height;\r\n        if (serializationObject.data) {\r\n            this._data = new Float32Array(serializationObject.data);\r\n            this.serializedCachedData = true;\r\n        } else {\r\n            this.serializedCachedData = !!serializationObject.serializedCachedData;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryTextureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryTextureBlock\", GeometryTextureBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector4, type Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type INodeGeometryTextureData } from \"../../Interfaces/nodeGeometryTextureData\";\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to fetch a color from texture data\r\n */\r\nexport class GeometryTextureFetchBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating if coordinates should be clamped between 0 and 1\r\n     */\r\n    @editableInPropertyPage(\"Clamp Coordinates\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public clampCoordinates = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if coordinates should be clamped between 0 and 1\r\n     */\r\n    @editableInPropertyPage(\"Interpolation\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public interpolation = true;\r\n\r\n    /**\r\n     * Creates a new GeometryTextureFetchBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"texture\", NodeGeometryBlockConnectionPointTypes.Texture);\r\n        this.registerInput(\"coordinates\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"rgba\", NodeGeometryBlockConnectionPointTypes.Vector4);\r\n        this.registerOutput(\"rgb\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"r\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"g\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"b\", NodeGeometryBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"a\", NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryTextureFetchBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the texture component\r\n     */\r\n    public get texture(): NodeGeometryConnectionPoint {\r\n        return this.inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the coordinates component\r\n     */\r\n    public get coordinates(): NodeGeometryConnectionPoint {\r\n        return this.inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgba component\r\n     */\r\n    public get rgba(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the rgb component\r\n     */\r\n    public get rgb(): NodeGeometryConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the r component\r\n     */\r\n    public get r(): NodeGeometryConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the g component\r\n     */\r\n    public get g(): NodeGeometryConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the b component\r\n     */\r\n    public get b(): NodeGeometryConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the a component\r\n     */\r\n    public get a(): NodeGeometryConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    private _repeatClamp(num: number) {\r\n        if (num >= 0) {\r\n            return num % 1;\r\n        } else {\r\n            return 1 - (Math.abs(num) % 1);\r\n        }\r\n    }\r\n\r\n    private _lerp(a: Vector4, b: Vector4, t: number) {\r\n        return new Vector4(a.x * (1 - t) + b.x * t, a.y * (1 - t) + b.y * t, a.z * (1 - t) + b.z * t, a.w * (1 - t) + b.w * t);\r\n    }\r\n\r\n    private _getPixel(ix: number, iy: number, data: Float32Array, width: number): Vector4 {\r\n        const i = (iy * width + ix) * 4;\r\n        return new Vector4(data[i], data[i + 1], data[i + 2], data[i + 3]);\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const textureData = this.texture.getConnectedValue(state) as INodeGeometryTextureData;\r\n            if (!textureData || !textureData.data) {\r\n                return null;\r\n            }\r\n\r\n            const uv = this.coordinates.getConnectedValue(state) as Vector2;\r\n\r\n            if (!uv) {\r\n                return null;\r\n            }\r\n\r\n            const u = this.clampCoordinates ? Math.max(0, Math.min(uv.x, 1.0)) : this._repeatClamp(uv.x);\r\n            const v = this.clampCoordinates ? Math.max(0, Math.min(uv.y, 1.0)) : this._repeatClamp(uv.y);\r\n            const width = textureData.width;\r\n            const height = textureData.height;\r\n            const data = textureData.data;\r\n\r\n            // Convert UV to texel space\r\n            const x = u * (width - 1);\r\n            const y = v * (height - 1);\r\n\r\n            if (this.interpolation) {\r\n                const x0 = Math.floor(x);\r\n                const y0 = Math.floor(y);\r\n                const x1 = Math.min(x0 + 1, width - 1);\r\n                const y1 = Math.min(y0 + 1, height - 1);\r\n\r\n                const dx = x - x0;\r\n                const dy = y - y0;\r\n\r\n                const c00 = this._getPixel(x0, y0, data, width);\r\n                const c10 = this._getPixel(x1, y0, data, width);\r\n                const c01 = this._getPixel(x0, y1, data, width);\r\n                const c11 = this._getPixel(x1, y1, data, width);\r\n\r\n                // Interpolate horizontally\r\n                const top = this._lerp(c00, c10, dx);\r\n                const bottom = this._lerp(c01, c11, dx);\r\n\r\n                // Interpolate vertically\r\n                return this._lerp(top, bottom, dy);\r\n            }\r\n\r\n            return this._getPixel(Math.floor(x), Math.floor(y), data, width);\r\n        };\r\n\r\n        this.rgba._storedFunction = (state) => {\r\n            return func(state);\r\n        };\r\n\r\n        this.rgb._storedFunction = (state) => {\r\n            const color = func(state) as Vector4;\r\n            return color ? color.toVector3() : null;\r\n        };\r\n\r\n        this.r._storedFunction = (state) => {\r\n            const color = func(state) as Vector4;\r\n            return color ? color.x : null;\r\n        };\r\n\r\n        this.g._storedFunction = (state) => {\r\n            const color = func(state) as Vector4;\r\n            return color ? color.y : null;\r\n        };\r\n\r\n        this.b._storedFunction = (state) => {\r\n            const color = func(state) as Vector4;\r\n            return color ? color.z : null;\r\n        };\r\n\r\n        this.a._storedFunction = (state) => {\r\n            const color = func(state) as Vector4;\r\n            return color ? color.w : null;\r\n        };\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.clampCoordinates = ${this.clampCoordinates};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.clampCoordinates = this.clampCoordinates;\r\n        serializationObject.interpolation = this.interpolation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.clampCoordinates = serializationObject.clampCoordinates;\r\n        if (serializationObject.clampCoordinates === undefined) {\r\n            this.interpolation = serializationObject.interpolation;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryTextureFetchBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryTextureFetchBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryTextureFetchBlock\", GeometryTextureFetchBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { extractMinAndMax } from \"../../../Maths/math.functions\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get the bounding info of a geometry\r\n */\r\nexport class BoundingBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Create a new BoundingBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n\r\n        this.registerOutput(\"min\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"max\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BoundingBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the min output component\r\n     */\r\n    public get min(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the max output component\r\n     */\r\n    public get max(): NodeGeometryConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.min._storedFunction = (state) => {\r\n            const geometry = this.geometry.getConnectedValue(state);\r\n\r\n            if (!geometry) {\r\n                return null;\r\n            }\r\n\r\n            const boundingInfo = extractMinAndMax(geometry.positions, 0, geometry.positions!.length / 3);\r\n            return boundingInfo.minimum;\r\n        };\r\n\r\n        this.max._storedFunction = (state) => {\r\n            const geometry = this.geometry.getConnectedValue(state);\r\n\r\n            if (!geometry) {\r\n                return null;\r\n            }\r\n\r\n            const boundingInfo = extractMinAndMax(geometry.positions, 0, geometry.positions!.length / 3);\r\n            return boundingInfo.maximum;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for boundingBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBoundingBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BoundingBlock\", BoundingBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type VertexData } from \"../../mesh.vertexData\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { CSG2, InitializeCSG2Async, IsCSG2Ready } from \"core/Meshes/csg2\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { CSG } from \"core/Meshes/csg\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the boolean block\r\n */\r\nexport enum BooleanGeometryOperations {\r\n    /** Intersect */\r\n    Intersect,\r\n    /** Subtract */\r\n    Subtract,\r\n    /** Union */\r\n    Union,\r\n}\r\n\r\n/**\r\n * Block used to apply a boolean operation between 2 geometries\r\n */\r\nexport class BooleanGeometryBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Intersect\", value: BooleanGeometryOperations.Intersect },\r\n            { label: \"Subtract\", value: BooleanGeometryOperations.Subtract },\r\n            { label: \"Union\", value: BooleanGeometryOperations.Union },\r\n        ],\r\n    })\r\n    public operation = BooleanGeometryOperations.Intersect;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Use old CSG engine\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public useOldCSGEngine = false;\r\n\r\n    private _csg2LoadingPromise: Promise<void>;\r\n    /**\r\n     * @internal\r\n     */\r\n    public override get _isReadyState(): Nullable<Promise<void>> {\r\n        if (IsCSG2Ready()) {\r\n            return null;\r\n        }\r\n\r\n        if (!this._csg2LoadingPromise) {\r\n            this._csg2LoadingPromise = InitializeCSG2Async();\r\n        }\r\n\r\n        return this._csg2LoadingPromise;\r\n    }\r\n\r\n    /**\r\n     * Create a new BooleanGeometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry0\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"geometry1\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BooleanGeometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry0 input component\r\n     */\r\n    public get geometry0(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry1 input component\r\n     */\r\n    public get geometry1(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const vertexData0 = this.geometry0.getConnectedValue(state) as VertexData;\r\n            const vertexData1 = this.geometry1.getConnectedValue(state) as VertexData;\r\n\r\n            if (!vertexData0 || !vertexData1) {\r\n                return null;\r\n            }\r\n\r\n            const vertexCount = vertexData0.positions!.length / 3;\r\n            // Ensure that all the fields are filled to avoid problems later on in the graph\r\n            if (!vertexData0.normals && vertexData1.normals) {\r\n                vertexData0.normals = new Array<number>(vertexData0.positions!.length);\r\n            }\r\n            if (!vertexData1.normals && vertexData0.normals) {\r\n                vertexData1.normals = new Array<number>(vertexData1.positions!.length);\r\n            }\r\n            if (!vertexData0.uvs && vertexData1.uvs) {\r\n                vertexData0.uvs = new Array<number>(vertexCount * 2);\r\n            }\r\n            if (!vertexData1.uvs && vertexData0.uvs) {\r\n                vertexData1.uvs = new Array<number>(vertexCount * 2);\r\n            }\r\n            if (!vertexData0.colors && vertexData1.colors) {\r\n                vertexData0.colors = new Array<number>(vertexCount * 4);\r\n            }\r\n            if (!vertexData1.colors && vertexData0.colors) {\r\n                vertexData1.colors = new Array<number>(vertexCount * 4);\r\n            }\r\n\r\n            let boolCSG: CSG | CSG2;\r\n\r\n            if (this.useOldCSGEngine) {\r\n                const csg0 = CSG.FromVertexData(vertexData0);\r\n                const csg1 = CSG.FromVertexData(vertexData1);\r\n                switch (this.operation) {\r\n                    case BooleanGeometryOperations.Intersect:\r\n                        boolCSG = csg0.intersect(csg1);\r\n                        break;\r\n                    case BooleanGeometryOperations.Subtract:\r\n                        boolCSG = csg0.subtract(csg1);\r\n                        break;\r\n                    case BooleanGeometryOperations.Union:\r\n                        boolCSG = csg0.union(csg1);\r\n                        break;\r\n                }\r\n            } else {\r\n                const csg0 = CSG2.FromVertexData(vertexData0);\r\n                const csg1 = CSG2.FromVertexData(vertexData1);\r\n                switch (this.operation) {\r\n                    case BooleanGeometryOperations.Intersect:\r\n                        boolCSG = csg0.intersect(csg1);\r\n                        break;\r\n                    case BooleanGeometryOperations.Subtract:\r\n                        boolCSG = csg0.subtract(csg1);\r\n                        break;\r\n                    case BooleanGeometryOperations.Union:\r\n                        boolCSG = csg0.add(csg1);\r\n                        break;\r\n                }\r\n            }\r\n\r\n            return boolCSG.toVertexData();\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.operation = BABYLON.BooleanGeometryOperations.${BooleanGeometryOperations[this.operation]};\\n`;\r\n        codeString += `${this._codeVariableName}.useOldCSGEngine = ${this.useOldCSGEngine ? \"true\" : \"false\"};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.operation = this.operation;\r\n        serializationObject.useOldCSGEngine = this.useOldCSGEngine;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.evaluateContext = serializationObject.evaluateContext;\r\n        if (serializationObject.operation) {\r\n            this.operation = serializationObject.operation;\r\n        }\r\n\r\n        this.useOldCSGEngine = !!serializationObject.useOldCSGEngine;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for booleanGeometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBooleanGeometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BooleanGeometryBlock\", BooleanGeometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to compute arc tangent of 2 values\r\n */\r\nexport class GeometryArcTan2Block extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryArcTan2Block\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"x\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"y\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryArcTan2Block\";\r\n    }\r\n\r\n    /**\r\n     * Gets the x operand input component\r\n     */\r\n    public get x(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the y operand input component\r\n     */\r\n    public get y(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.x.isConnected || !this.y.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (x: number, y: number) => {\r\n            return Math.atan2(x, y);\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const x = this.x.getConnectedValue(state);\r\n            const y = this.y.getConnectedValue(state);\r\n\r\n            switch (this.x.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(x, y);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(x.x, y.x), func(x.y, y.y));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(x.x, y.x), func(x.y, y.y), func(x.z, y.z));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(x.x, y.x), func(x.y, y.y), func(x.z, y.z), func(x.w, y.w));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryArcTan2Block.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryArcTan2Block(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryArcTan2Block\", GeometryArcTan2Block);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to lerp between 2 values\r\n */\r\nexport class GeometryLerpBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryLerpBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"gradient\", NodeGeometryBlockConnectionPointTypes.Float, true, 0, 0, 1);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryLerpBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (gradient: number, left: number, right: number) => {\r\n            return (1 - gradient) * left + gradient * right;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n            const gradient = this.gradient.getConnectedValue(state);\r\n            switch (this.left.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(gradient, left, right);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(gradient, left.x, right.x), func(gradient, left.y, right.y));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(gradient, left.x, right.x), func(gradient, left.y, right.y), func(gradient, left.z, right.z));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(gradient, left.x, right.x), func(gradient, left.y, right.y), func(gradient, left.z, right.z), func(gradient, left.w, right.w));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryLerpBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryLerpBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryLerpBlock\", GeometryLerpBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to normalize lerp between 2 values\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class GeometryNLerpBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryNLerpBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"gradient\", NodeGeometryBlockConnectionPointTypes.Float, true, 0, 0, 1);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryNLerpBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (gradient: number, left: number, right: number) => {\r\n            return (1 - gradient) * left + gradient * right;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n            const gradient = this.gradient.getConnectedValue(state);\r\n            switch (this.left.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(gradient, left, right); // NLerp is really lerp in that case\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    const result = new Vector2(func(gradient, left.x, right.x), func(gradient, left.y, right.y));\r\n                    result.normalize();\r\n\r\n                    return result;\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    const result = new Vector3(func(gradient, left.x, right.x), func(gradient, left.y, right.y), func(gradient, left.z, right.z));\r\n                    result.normalize();\r\n\r\n                    return result;\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    const result = new Vector4(func(gradient, left.x, right.x), func(gradient, left.y, right.y), func(gradient, left.z, right.z), func(gradient, left.w, right.w));\r\n                    result.normalize();\r\n\r\n                    return result;\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryNLerpBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RegisterGeometryNLerpBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryNLerpBlock\", GeometryNLerpBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to step a value\r\n */\r\nexport class GeometryStepBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryStepBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"edge\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryStepBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the edge operand input component\r\n     */\r\n    public get edge(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n        const func = (value: number, edge: number) => {\r\n            if (value < edge) {\r\n                return 0;\r\n            }\r\n\r\n            return 1;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const source = this.value.getConnectedValue(state);\r\n            const edge = this.edge.getConnectedValue(state);\r\n            switch (this.value.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(source, edge);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(source.x, edge), func(source.y, edge));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(source.x, edge), func(source.y, edge), func(source.z, edge));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(source.x, edge), func(source.y, edge), func(source.z, edge), func(source.w, edge));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryStepBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryStepBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryStepBlock\", GeometryStepBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to smooth step a value\r\n */\r\nexport class GeometrySmoothStepBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometrySmoothStepBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"edge0\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"edge1\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometrySmoothStepBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the first edge operand input component\r\n     */\r\n    public get edge0(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the second edge operand input component\r\n     */\r\n    public get edge1(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (value: number, edge0: number, edge1: number) => {\r\n            const x = Math.max(0, Math.min((value - edge0) / (edge1 - edge0), 1));\r\n\r\n            // Smoothstep formula: 3x^2 - 2x^3\r\n            return x * x * (3 - 2 * x);\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const source = this.value.getConnectedValue(state);\r\n            const edge0 = this.edge0.getConnectedValue(state);\r\n            const edge1 = this.edge1.getConnectedValue(state);\r\n            switch (this.value.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(source, edge0, edge1);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(source.x, edge0, edge1), func(source.y, edge0, edge1));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(source.x, edge0, edge1), func(source.y, edge0, edge1), func(source.z, edge0, edge1));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(source.x, edge0, edge1), func(source.y, edge0, edge1), func(source.z, edge0, edge1), func(source.w, edge0, edge1));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometrySmoothStepBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometrySmoothStepBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometrySmoothStepBlock\", GeometrySmoothStepBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to compute value of one parameter modulo another\r\n */\r\nexport class GeometryModBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryModBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryModBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (left: number, right: number) => {\r\n            return left - Math.floor(left / right) * right;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n            switch (this.left.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(left, right);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(left.x, right.x), func(left.y, right.y));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(left.x, right.x), func(left.y, right.y), func(left.z, right.z));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(left.x, right.x), func(left.y, right.y), func(left.z, right.z), func(left.w, right.w));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryModBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryModBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryModBlock\", GeometryModBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the value of the first parameter raised to the power of the second\r\n */\r\nexport class GeometryPowBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryPowBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"power\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryPowBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the power operand input component\r\n     */\r\n    public get power(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected || !this.power.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n        const func = (value: number, power: number) => {\r\n            return Math.pow(value, power);\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const source = this.value.getConnectedValue(state);\r\n            const power = this.power.getConnectedValue(state);\r\n            switch (this.value.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(source, power);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(source.x, power), func(source.y, power));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(source.x, power), func(source.y, power), func(source.z, power));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(source.x, power), func(source.y, power), func(source.z, power), func(source.w, power));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryPowBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryPowBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryPowBlock\", GeometryPowBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clamp a float\r\n */\r\nexport class GeometryClampBlock extends NodeGeometryBlock {\r\n    /** Gets or sets the minimum range */\r\n    public get minimum() {\r\n        return this.min.value;\r\n    }\r\n\r\n    public set minimum(value: number) {\r\n        this.min.value = value;\r\n    }\r\n\r\n    /** Gets or sets the maximum range */\r\n    public get maximum() {\r\n        return this.max.value;\r\n    }\r\n\r\n    public set maximum(value: number) {\r\n        this.max.value = value;\r\n    }\r\n\r\n    /**\r\n     * Creates a new GeometryClampBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"min\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"max\", NodeGeometryBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryClampBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the min input component\r\n     */\r\n    public get min(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the max input component\r\n     */\r\n    public get max(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (value: number, min: number, max: number) => {\r\n            return Math.max(min, Math.min(value, max));\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const value = this.value.getConnectedValue(state);\r\n            const min = this.min.isConnected ? this.min.getConnectedValue(state) : this.minimum;\r\n            const max = this.max.isConnected ? this.max.getConnectedValue(state) : this.maximum;\r\n\r\n            switch (this.value.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(value, min, max);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(value.x, min, max), func(value.y, min, max));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(value.x, min, max), func(value.y, min, max), func(value.z, min, max));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(value.x, min, max), func(value.y, min, max), func(value.z, min, max), func(value.w, min, max));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.minimum = serializationObject.minimum;\r\n        this.maximum = serializationObject.maximum;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryClampBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryClampBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryClampBlock\", GeometryClampBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to apply a cross product between 2 vectors\r\n */\r\nexport class GeometryCrossBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryCrossBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryCrossBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n\r\n            switch (this.left.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return Vector3.Cross(left, right);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return Vector3.Cross(left.toVector3(), right.toVector3());\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryCrossBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryCrossBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryCrossBlock\", GeometryCrossBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type float } from \"core/types\";\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Types of curves supported by the Curve block\r\n */\r\nexport enum GeometryCurveBlockTypes {\r\n    /** EaseInSine */\r\n    EaseInSine,\r\n    /** EaseOutSine */\r\n    EaseOutSine,\r\n    /** EaseInOutSine */\r\n    EaseInOutSine,\r\n    /** EaseInQuad */\r\n    EaseInQuad,\r\n    /** EaseOutQuad */\r\n    EaseOutQuad,\r\n    /** EaseInOutQuad */\r\n    EaseInOutQuad,\r\n    /** EaseInCubic */\r\n    EaseInCubic,\r\n    /** EaseOutCubic */\r\n    EaseOutCubic,\r\n    /** EaseInOutCubic */\r\n    EaseInOutCubic,\r\n    /** EaseInQuart */\r\n    EaseInQuart,\r\n    /** EaseOutQuart */\r\n    EaseOutQuart,\r\n    /** EaseInOutQuart */\r\n    EaseInOutQuart,\r\n    /** EaseInQuint */\r\n    EaseInQuint,\r\n    /** EaseOutQuint */\r\n    EaseOutQuint,\r\n    /** EaseInOutQuint */\r\n    EaseInOutQuint,\r\n    /** EaseInExpo */\r\n    EaseInExpo,\r\n    /** EaseOutExpo */\r\n    EaseOutExpo,\r\n    /** EaseInOutExpo */\r\n    EaseInOutExpo,\r\n    /** EaseInCirc */\r\n    EaseInCirc,\r\n    /** EaseOutCirc */\r\n    EaseOutCirc,\r\n    /** EaseInOutCirc */\r\n    EaseInOutCirc,\r\n    /** EaseInBack */\r\n    EaseInBack,\r\n    /** EaseOutBack */\r\n    EaseOutBack,\r\n    /** EaseInOutBack */\r\n    EaseInOutBack,\r\n    /** EaseInElastic */\r\n    EaseInElastic,\r\n    /** EaseOutElastic */\r\n    EaseOutElastic,\r\n    /** EaseInOutElastic */\r\n    EaseInOutElastic,\r\n}\r\n\r\n/**\r\n * Block used to apply curve operation\r\n */\r\nexport class GeometryCurveBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets the type of the curve applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"EaseInSine\", value: GeometryCurveBlockTypes.EaseInSine },\r\n            { label: \"EaseOutSine\", value: GeometryCurveBlockTypes.EaseOutSine },\r\n            { label: \"EaseInOutSine\", value: GeometryCurveBlockTypes.EaseInOutSine },\r\n            { label: \"EaseInQuad\", value: GeometryCurveBlockTypes.EaseInQuad },\r\n            { label: \"EaseOutQuad\", value: GeometryCurveBlockTypes.EaseOutQuad },\r\n            { label: \"EaseInOutQuad\", value: GeometryCurveBlockTypes.EaseInOutQuad },\r\n            { label: \"EaseInCubic\", value: GeometryCurveBlockTypes.EaseInCubic },\r\n            { label: \"EaseOutCubic\", value: GeometryCurveBlockTypes.EaseOutCubic },\r\n            { label: \"EaseInOutCubic\", value: GeometryCurveBlockTypes.EaseInOutCubic },\r\n            { label: \"EaseInQuart\", value: GeometryCurveBlockTypes.EaseInQuart },\r\n            { label: \"EaseOutQuart\", value: GeometryCurveBlockTypes.EaseOutQuart },\r\n            { label: \"EaseInOutQuart\", value: GeometryCurveBlockTypes.EaseInOutQuart },\r\n            { label: \"EaseInQuint\", value: GeometryCurveBlockTypes.EaseInQuint },\r\n            { label: \"EaseOutQuint\", value: GeometryCurveBlockTypes.EaseOutQuint },\r\n            { label: \"EaseInOutQuint\", value: GeometryCurveBlockTypes.EaseInOutQuint },\r\n            { label: \"EaseInExpo\", value: GeometryCurveBlockTypes.EaseInExpo },\r\n            { label: \"EaseOutExpo\", value: GeometryCurveBlockTypes.EaseOutExpo },\r\n            { label: \"EaseInOutExpo\", value: GeometryCurveBlockTypes.EaseInOutExpo },\r\n            { label: \"EaseInCirc\", value: GeometryCurveBlockTypes.EaseInCirc },\r\n            { label: \"EaseOutCirc\", value: GeometryCurveBlockTypes.EaseOutCirc },\r\n            { label: \"EaseInOutCirc\", value: GeometryCurveBlockTypes.EaseInOutCirc },\r\n            { label: \"EaseInBack\", value: GeometryCurveBlockTypes.EaseInBack },\r\n            { label: \"EaseOutBack\", value: GeometryCurveBlockTypes.EaseOutBack },\r\n            { label: \"EaseInOutBack\", value: GeometryCurveBlockTypes.EaseInOutBack },\r\n            { label: \"EaseInElastic\", value: GeometryCurveBlockTypes.EaseInElastic },\r\n            { label: \"EaseOutElastic\", value: GeometryCurveBlockTypes.EaseOutElastic },\r\n            { label: \"EaseInOutElastic\", value: GeometryCurveBlockTypes.EaseInOutElastic },\r\n        ],\r\n    })\r\n    public type = GeometryCurveBlockTypes.EaseInOutSine;\r\n\r\n    /**\r\n     * Creates a new CurveBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryCurveBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.input.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        let func: (v: float) => any;\r\n\r\n        switch (this.type) {\r\n            case GeometryCurveBlockTypes.EaseInSine:\r\n                func = (v: float) => 1.0 - Math.cos((v * 3.1415) / 2.0);\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseOutSine:\r\n                func = (v: float) => Math.sin((v * 3.1415) / 2.0);\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseInOutSine:\r\n                func = (v: float) => -(Math.cos(v * 3.1415) - 1.0) / 2.0;\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseInQuad:\r\n                func = (v: float) => v * v;\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseOutQuad:\r\n                func = (v: float) => (1.0 - v) * (1.0 - v);\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseInOutQuad: {\r\n                func = (v: float) => (v < 0.5 ? 2.0 * v * v : 1.0 - Math.pow(-2.0 * v + 2.0, 2.0) / 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInCubic:\r\n                func = (v: float) => v * v * v;\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseOutCubic: {\r\n                func = (v: float) => 1.0 - Math.pow(1.0 - v, 3.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutCubic: {\r\n                func = (v: float) => (v < 0.5 ? 4.0 * v * v * v : 1.0 - Math.pow(-2.0 * v + 2.0, 3.0) / 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInQuart:\r\n                func = (v: float) => v * v * v * v;\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseOutQuart: {\r\n                func = (v: float) => 1.0 - Math.pow(1.0 - v, 4.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutQuart: {\r\n                func = (v: float) => (v < 0.5 ? 8.0 * v * v * v * v : 1.0 - Math.pow(-2.0 * v + 2.0, 4.0) / 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInQuint:\r\n                func = (v: float) => v * v * v * v * v;\r\n                break;\r\n            case GeometryCurveBlockTypes.EaseOutQuint: {\r\n                func = (v: float) => 1.0 - Math.pow(1.0 - v, 5.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutQuint: {\r\n                func = (v: float) => (v < 0.5 ? 16.0 * v * v * v * v * v : 1.0 - Math.pow(-2.0 * v + 2.0, 5.0) / 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInExpo: {\r\n                func = (v: float) => (v === 0.0 ? 0.0 : Math.pow(2.0, 10.0 * v - 10.0));\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseOutExpo: {\r\n                func = (v: float) => (v === 1.0 ? 1.0 : 1.0 - Math.pow(2.0, -10.0 * v));\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutExpo: {\r\n                func = (v: float) => (v === 0.0 ? 0.0 : v === 1.0 ? 1.0 : v < 0.5 ? Math.pow(2.0, 20.0 * v - 10.0) / 2.0 : (2.0 - Math.pow(2.0, -20.0 * v + 10.0)) / 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInCirc: {\r\n                func = (v: float) => 1.0 - Math.sqrt(1.0 - Math.pow(v, 2.0));\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseOutCirc: {\r\n                func = (v: float) => Math.sqrt(1.0 - Math.pow(v - 1.0, 2.0));\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutCirc: {\r\n                func = (v: float) => (v < 0.5 ? (1.0 - Math.sqrt(1.0 - Math.pow(2.0 * v, 2.0))) / 2.0 : (Math.sqrt(1.0 - Math.pow(-2.0 * v + 2.0, 2.0)) + 1.0) / 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInBack: {\r\n                func = (v: float) => 2.70158 * v * v * v - 1.70158 * v * v;\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseOutBack: {\r\n                func = (v: float) => 2.70158 * Math.pow(v - 1.0, 3.0) + 1.70158 * Math.pow(v - 1.0, 2.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutBack: {\r\n                func = (v: float) =>\r\n                    v < 0.5\r\n                        ? (Math.pow(2.0 * v, 2.0) * (3.5949095 * 2.0 * v - 2.5949095)) / 2.0\r\n                        : (Math.pow(2.0 * v - 2.0, 2.0) * (3.5949095 * (v * 2.0 - 2.0) + 3.5949095) + 2.0) / 2.0;\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInElastic: {\r\n                func = (v: float) => (v === 0.0 ? 0.0 : v === 1.0 ? 1.0 : -Math.pow(2.0, 10.0 * v - 10.0) * Math.sin((v * 10.0 - 10.75) * ((2.0 * 3.1415) / 3.0)));\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseOutElastic: {\r\n                func = (v: float) => (v === 0.0 ? 0.0 : v === 1.0 ? 1.0 : Math.pow(2.0, -10.0 * v) * Math.sin((v * 10.0 - 0.75) * ((2.0 * 3.1415) / 3.0)) + 1.0);\r\n                break;\r\n            }\r\n            case GeometryCurveBlockTypes.EaseInOutElastic: {\r\n                func = (v: float) =>\r\n                    v === 0.0\r\n                        ? 0.0\r\n                        : v == 1.0\r\n                          ? 1.0\r\n                          : v < 0.5\r\n                            ? -(Math.pow(2.0, 20.0 * v - 10.0) * Math.sin((20.0 * v - 11.125) * ((2.0 * 3.1415) / 4.5))) / 2.0\r\n                            : (Math.pow(2.0, -20.0 * v + 10.0) * Math.sin((20.0 * v - 11.125) * ((2.0 * 3.1415) / 4.5))) / 2.0 + 1.0;\r\n                break;\r\n            }\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const input = this.input.getConnectedValue(state);\r\n\r\n            switch (this.input.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    return func(input);\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(input.x), func(input.y));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(input.x), func(input.y), func(input.z));\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    return new Vector4(func(input.x), func(input.y), func(input.z), func(input.w));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.curveType = this.type;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.type = serializationObject.curveType;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.type = BABYLON.GeometryCurveBlockTypes.${GeometryCurveBlockTypes[this.type]};\\n`;\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryCurveBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryCurveBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryCurveBlock\", GeometryCurveBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to desaturate a color\r\n */\r\nexport class GeometryDesaturateBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryDesaturateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"color\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"level\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Vector3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryDesaturateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color operand input component\r\n     */\r\n    public get color(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the level operand input component\r\n     */\r\n    public get level(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.color.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const color = this.color.getConnectedValue(state);\r\n            const level = this.level.getConnectedValue(state);\r\n\r\n            const tempMin = Math.min(color.x, color.y, color.z);\r\n            const tempMax = Math.max(color.x, color.y, color.z);\r\n            const tempMerge = 0.5 * (tempMin + tempMax);\r\n\r\n            return new Vector3(color.x * (1 - level) + tempMerge * level, color.y * (1 - level) + tempMerge * level, color.z * (1 - level) + tempMerge * level);\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryDesaturateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryDesaturateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryDesaturateBlock\", GeometryDesaturateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to posterize a value\r\n * @see https://en.wikipedia.org/wiki/Posterization\r\n */\r\nexport class GeometryPosterizeBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryPosterizeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"steps\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].acceptedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryPosterizeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the steps input component\r\n     */\r\n    public get steps(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected || !this.steps.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const source = this.value.getConnectedValue(state);\r\n            const steps = this.steps.getConnectedValue(state);\r\n            let stepVector = steps;\r\n\r\n            if (this.steps.type === NodeGeometryBlockConnectionPointTypes.Float) {\r\n                switch (this.value.type) {\r\n                    case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                        stepVector = new Vector2(steps, steps);\r\n                        break;\r\n                    case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                        stepVector = new Vector3(steps, steps, steps);\r\n                        break;\r\n                    case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                        stepVector = new Vector4(steps, steps, steps, steps);\r\n                        break;\r\n                }\r\n            }\r\n\r\n            switch (this.value.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2:\r\n                    return new Vector2((source.x / (1.0 / stepVector.x)) * (1.0 / stepVector.x), (source.y / (1.0 / stepVector.y)) * (1.0 / stepVector.y));\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3:\r\n                    return new Vector3(\r\n                        (source.x / (1.0 / stepVector.x)) * (1.0 / stepVector.x),\r\n                        (source.y / (1.0 / stepVector.y)) * (1.0 / stepVector.y),\r\n                        (source.z / (1.0 / stepVector.z)) * (1.0 / stepVector.z)\r\n                    );\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4:\r\n                    return new Vector4(\r\n                        (source.x / (1.0 / stepVector.x)) * (1.0 / stepVector.x),\r\n                        (source.y / (1.0 / stepVector.y)) * (1.0 / stepVector.y),\r\n                        (source.z / (1.0 / stepVector.z)) * (1.0 / stepVector.z),\r\n                        (source.w / (1.0 / stepVector.w)) * (1.0 / stepVector.w)\r\n                    );\r\n                default:\r\n                    return Math.floor((source / (1.0 / steps)) * (1.0 / steps));\r\n            }\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryPosterizeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryPosterizeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryPosterizeBlock\", GeometryPosterizeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to replace a color by another one\r\n */\r\nexport class GeometryReplaceColorBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryReplaceColorBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"reference\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"distance\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"replacement\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n        this._linkConnectionTypes(0, 3);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[3].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[3].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryReplaceColorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the reference input component\r\n     */\r\n    public get reference(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the distance input component\r\n     */\r\n    public get distance(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the replacement input component\r\n     */\r\n    public get replacement(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected || !this.reference.isConnected || !this.replacement.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const value = this.value.getConnectedValue(state);\r\n            const reference = this.reference.getConnectedValue(state);\r\n            const distance = this.distance.getConnectedValue(state);\r\n            const replacement = this.replacement.getConnectedValue(state);\r\n\r\n            if (value.subtract(reference).length() < distance) {\r\n                return replacement;\r\n            } else {\r\n                return value;\r\n            }\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryReplaceColorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryReplaceColorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryReplaceColorBlock\", GeometryReplaceColorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to get the distance between 2 values\r\n */\r\nexport class GeometryDistanceBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryDistanceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Float);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryDistanceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n\r\n            return left.subtract(right).length();\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryDistanceBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryDistanceBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryDistanceBlock\", GeometryDistanceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to apply a dot product between 2 vectors\r\n */\r\nexport class GeometryDotBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryDotBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Float);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[1].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryDotBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n\r\n            return left.dot(right);\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryDotBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryDotBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryDotBlock\", GeometryDotBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to get the length of a vector\r\n */\r\nexport class GeometryLengthBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryLengthBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Float);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Int);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Float);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryLengthBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const value = this.value.getConnectedValue(state);\r\n            return value.length();\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryLengthBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryLengthBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryLengthBlock\", GeometryLengthBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to rotate a 2d vector by a given angle\r\n */\r\nexport class GeometryRotate2dBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Creates a new GeometryRotate2dBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n        this.registerInput(\"angle\", NodeGeometryBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Vector2);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryRotate2dBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input vector\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the input angle\r\n     */\r\n    public get angle(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        if (!this.input.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const input = this.input.getConnectedValue(state) as Vector2;\r\n            const angle = this.angle.getConnectedValue(state);\r\n            return new Vector2(Math.cos(angle) * input.x - Math.sin(angle) * input.y, Math.sin(angle) * input.x + Math.cos(angle) * input.y);\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryRotate2dBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryRotate2dBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryRotate2dBlock\", GeometryRotate2dBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"core/Misc/observable.pure\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to trigger an observable when traversed\r\n * It can also be used to execute a function when traversed\r\n */\r\nexport class GeometryInterceptorBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Observable triggered when the block is traversed\r\n     */\r\n    public onInterceptionObservable = new Observable<any>(undefined, true);\r\n\r\n    /**\r\n     * Custom function to execute when traversed\r\n     */\r\n    public customFunction?: (value: any, state: NodeGeometryBuildState) => any;\r\n\r\n    /**\r\n     * Creates a new GeometryInterceptorBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the time spent to build this block (in ms)\r\n     */\r\n    public override get buildExecutionTime() {\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryInterceptorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input = this._inputs[0];\r\n\r\n        output._storedFunction = (state) => {\r\n            let value = input.getConnectedValue(state);\r\n\r\n            if (this.customFunction) {\r\n                value = this.customFunction(value, state);\r\n            }\r\n\r\n            this.onInterceptionObservable.notifyObservers(value);\r\n\r\n            return value;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryInterceptorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryInterceptorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryInterceptorBlock\", GeometryInterceptorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { Vector2, Vector3, Vector4 } from \"../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type EasingFunction, BackEase, CircleEase, CubicEase, ElasticEase, ExponentialEase, QuadraticEase, QuarticEase, QuinticEase, SineEase } from \"core/Animations/easing\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Types of easing function supported by the Ease block\r\n */\r\nexport enum GeometryEaseBlockTypes {\r\n    /** EaseInSine */\r\n    EaseInSine,\r\n    /** EaseOutSine */\r\n    EaseOutSine,\r\n    /** EaseInOutSine */\r\n    EaseInOutSine,\r\n    /** EaseInQuad */\r\n    EaseInQuad,\r\n    /** EaseOutQuad */\r\n    EaseOutQuad,\r\n    /** EaseInOutQuad */\r\n    EaseInOutQuad,\r\n    /** EaseInCubic */\r\n    EaseInCubic,\r\n    /** EaseOutCubic */\r\n    EaseOutCubic,\r\n    /** EaseInOutCubic */\r\n    EaseInOutCubic,\r\n    /** EaseInQuart */\r\n    EaseInQuart,\r\n    /** EaseOutQuart */\r\n    EaseOutQuart,\r\n    /** EaseInOutQuart */\r\n    EaseInOutQuart,\r\n    /** EaseInQuint */\r\n    EaseInQuint,\r\n    /** EaseOutQuint */\r\n    EaseOutQuint,\r\n    /** EaseInOutQuint */\r\n    EaseInOutQuint,\r\n    /** EaseInExpo */\r\n    EaseInExpo,\r\n    /** EaseOutExpo */\r\n    EaseOutExpo,\r\n    /** EaseInOutExpo */\r\n    EaseInOutExpo,\r\n    /** EaseInCirc */\r\n    EaseInCirc,\r\n    /** EaseOutCirc */\r\n    EaseOutCirc,\r\n    /** EaseInOutCirc */\r\n    EaseInOutCirc,\r\n    /** EaseInBack */\r\n    EaseInBack,\r\n    /** EaseOutBack */\r\n    EaseOutBack,\r\n    /** EaseInOutBack */\r\n    EaseInOutBack,\r\n    /** EaseInElastic */\r\n    EaseInElastic,\r\n    /** EaseOutElastic */\r\n    EaseOutElastic,\r\n    /** EaseInOutElastic */\r\n    EaseInOutElastic,\r\n}\r\n\r\n/**\r\n * Block used to apply an easing function to floats\r\n */\r\nexport class GeometryEaseBlock extends NodeGeometryBlock {\r\n    private _easingFunction: EasingFunction = new SineEase();\r\n    private _type = GeometryEaseBlockTypes.EaseInOutSine;\r\n    /**\r\n     * Gets or sets the type of the easing functions applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Type\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"EaseInSine\", value: GeometryEaseBlockTypes.EaseInSine },\r\n            { label: \"EaseOutSine\", value: GeometryEaseBlockTypes.EaseOutSine },\r\n            { label: \"EaseInOutSine\", value: GeometryEaseBlockTypes.EaseInOutSine },\r\n            { label: \"EaseInQuad\", value: GeometryEaseBlockTypes.EaseInQuad },\r\n            { label: \"EaseOutQuad\", value: GeometryEaseBlockTypes.EaseOutQuad },\r\n            { label: \"EaseInOutQuad\", value: GeometryEaseBlockTypes.EaseInOutQuad },\r\n            { label: \"EaseInCubic\", value: GeometryEaseBlockTypes.EaseInCubic },\r\n            { label: \"EaseOutCubic\", value: GeometryEaseBlockTypes.EaseOutCubic },\r\n            { label: \"EaseInOutCubic\", value: GeometryEaseBlockTypes.EaseInOutCubic },\r\n            { label: \"EaseInQuart\", value: GeometryEaseBlockTypes.EaseInQuart },\r\n            { label: \"EaseOutQuart\", value: GeometryEaseBlockTypes.EaseOutQuart },\r\n            { label: \"EaseInOutQuart\", value: GeometryEaseBlockTypes.EaseInOutQuart },\r\n            { label: \"EaseInQuint\", value: GeometryEaseBlockTypes.EaseInQuint },\r\n            { label: \"EaseOutQuint\", value: GeometryEaseBlockTypes.EaseOutQuint },\r\n            { label: \"EaseInOutQuint\", value: GeometryEaseBlockTypes.EaseInOutQuint },\r\n            { label: \"EaseInExpo\", value: GeometryEaseBlockTypes.EaseInExpo },\r\n            { label: \"EaseOutExpo\", value: GeometryEaseBlockTypes.EaseOutExpo },\r\n            { label: \"EaseInOutExpo\", value: GeometryEaseBlockTypes.EaseInOutExpo },\r\n            { label: \"EaseInCirc\", value: GeometryEaseBlockTypes.EaseInCirc },\r\n            { label: \"EaseOutCirc\", value: GeometryEaseBlockTypes.EaseOutCirc },\r\n            { label: \"EaseInOutCirc\", value: GeometryEaseBlockTypes.EaseInOutCirc },\r\n            { label: \"EaseInBack\", value: GeometryEaseBlockTypes.EaseInBack },\r\n            { label: \"EaseOutBack\", value: GeometryEaseBlockTypes.EaseOutBack },\r\n            { label: \"EaseInOutBack\", value: GeometryEaseBlockTypes.EaseInOutBack },\r\n            { label: \"EaseInElastic\", value: GeometryEaseBlockTypes.EaseInElastic },\r\n            { label: \"EaseOutElastic\", value: GeometryEaseBlockTypes.EaseOutElastic },\r\n            { label: \"EaseInOutElastic\", value: GeometryEaseBlockTypes.EaseInOutElastic },\r\n        ],\r\n    })\r\n    public get type() {\r\n        return this._type;\r\n    }\r\n\r\n    public set type(value: GeometryEaseBlockTypes) {\r\n        if (this._type === value) {\r\n            return;\r\n        }\r\n        this._type = value;\r\n\r\n        switch (this._type) {\r\n            case GeometryEaseBlockTypes.EaseInSine:\r\n                this._easingFunction = new SineEase();\r\n                this._easingFunction.setEasingMode(SineEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutSine:\r\n                this._easingFunction = new SineEase();\r\n                this._easingFunction.setEasingMode(SineEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutSine:\r\n                this._easingFunction = new SineEase();\r\n                this._easingFunction.setEasingMode(SineEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInQuad:\r\n                this._easingFunction = new QuadraticEase();\r\n                this._easingFunction.setEasingMode(QuadraticEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutQuad:\r\n                this._easingFunction = new QuadraticEase();\r\n                this._easingFunction.setEasingMode(QuadraticEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutQuad:\r\n                this._easingFunction = new QuadraticEase();\r\n                this._easingFunction.setEasingMode(QuadraticEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInCubic:\r\n                this._easingFunction = new CubicEase();\r\n                this._easingFunction.setEasingMode(CubicEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutCubic:\r\n                this._easingFunction = new CubicEase();\r\n                this._easingFunction.setEasingMode(CubicEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutCubic:\r\n                this._easingFunction = new CubicEase();\r\n                this._easingFunction.setEasingMode(CubicEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInQuart:\r\n                this._easingFunction = new QuarticEase();\r\n                this._easingFunction.setEasingMode(QuarticEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutQuart:\r\n                this._easingFunction = new QuarticEase();\r\n                this._easingFunction.setEasingMode(QuarticEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutQuart:\r\n                this._easingFunction = new QuarticEase();\r\n                this._easingFunction.setEasingMode(QuarticEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInQuint:\r\n                this._easingFunction = new QuinticEase();\r\n                this._easingFunction.setEasingMode(QuinticEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutQuint:\r\n                this._easingFunction = new QuinticEase();\r\n                this._easingFunction.setEasingMode(QuinticEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutQuint:\r\n                this._easingFunction = new QuinticEase();\r\n                this._easingFunction.setEasingMode(QuinticEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInExpo:\r\n                this._easingFunction = new ExponentialEase();\r\n                this._easingFunction.setEasingMode(ExponentialEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutExpo:\r\n                this._easingFunction = new ExponentialEase();\r\n                this._easingFunction.setEasingMode(ExponentialEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutExpo:\r\n                this._easingFunction = new ExponentialEase();\r\n                this._easingFunction.setEasingMode(ExponentialEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInCirc:\r\n                this._easingFunction = new CircleEase();\r\n                this._easingFunction.setEasingMode(CircleEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutCirc:\r\n                this._easingFunction = new CircleEase();\r\n                this._easingFunction.setEasingMode(CircleEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutCirc:\r\n                this._easingFunction = new CircleEase();\r\n                this._easingFunction.setEasingMode(CircleEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInBack:\r\n                this._easingFunction = new BackEase();\r\n                this._easingFunction.setEasingMode(BackEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutBack:\r\n                this._easingFunction = new BackEase();\r\n                this._easingFunction.setEasingMode(BackEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutBack:\r\n                this._easingFunction = new BackEase();\r\n                this._easingFunction.setEasingMode(BackEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInElastic:\r\n                this._easingFunction = new ElasticEase();\r\n                this._easingFunction.setEasingMode(ElasticEase.EASINGMODE_EASEIN);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseOutElastic:\r\n                this._easingFunction = new ElasticEase();\r\n                this._easingFunction.setEasingMode(ElasticEase.EASINGMODE_EASEOUT);\r\n                break;\r\n            case GeometryEaseBlockTypes.EaseInOutElastic:\r\n                this._easingFunction = new ElasticEase();\r\n                this._easingFunction.setEasingMode(ElasticEase.EASINGMODE_EASEINOUT);\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new GeometryEaseBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeGeometryBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"GeometryEaseBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        super._buildBlock(state);\r\n\r\n        if (!this._easingFunction) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        switch (this.input.type) {\r\n            case NodeGeometryBlockConnectionPointTypes.Int:\r\n            case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return this._easingFunction.ease(source);\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector2(this._easingFunction.ease(source.x), this._easingFunction.ease(source.y));\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector3(this._easingFunction.ease(source.x), this._easingFunction.ease(source.y), this._easingFunction.ease(source.z));\r\n                };\r\n                break;\r\n            }\r\n            case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector4(\r\n                        this._easingFunction.ease(source.x),\r\n                        this._easingFunction.ease(source.y),\r\n                        this._easingFunction.ease(source.z),\r\n                        this._easingFunction.ease(source.w)\r\n                    );\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /** @internal */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.type = this.type;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.type = serializationObject.type;\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        const codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.type = BABYLON.GeometryEaseBlockTypes.${GeometryEaseBlockTypes[this.type]};\\n`;\r\n        return codeString;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for geometryEaseBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGeometryEaseBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GeometryEaseBlock\", GeometryEaseBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../../nodeGeometryBuildState\";\r\nimport { type INodeGeometryExecutionContext } from \"../../Interfaces/nodeGeometryExecutionContext\";\r\nimport { type VertexData } from \"../../../../Meshes/mesh.vertexData\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { Vector2, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Conditions supported by the condition block\r\n */\r\nexport enum Aggregations {\r\n    /** Max */\r\n    Max,\r\n    /** Min */\r\n    Min,\r\n    /** Sum */\r\n    Sum,\r\n}\r\n\r\n/**\r\n * Block used to extract a valuefrom a geometry\r\n */\r\nexport class AggregatorBlock extends NodeGeometryBlock implements INodeGeometryExecutionContext {\r\n    private _vertexData: VertexData;\r\n    private _currentIndex: number;\r\n\r\n    /**\r\n     * Gets or sets the test used by the block\r\n     */\r\n    @editableInPropertyPage(\"Aggregation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Max\", value: Aggregations.Max },\r\n            { label: \"Min\", value: Aggregations.Min },\r\n            { label: \"Sum\", value: Aggregations.Sum },\r\n        ],\r\n    })\r\n    public aggregation = Aggregations.Sum;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { notifiers: { rebuild: true } })\r\n    public evaluateContext = true;\r\n\r\n    /**\r\n     * Create a new SetPositionsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"source\", NodeGeometryBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.BasedOnInput);\r\n        this._outputs[0]._typeConnectionSource = this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the current index in the current flow\r\n     * @returns the current index\r\n     */\r\n    public getExecutionIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current loop index in the current flow\r\n     * @returns the current loop index\r\n     */\r\n    public getExecutionLoopIndex(): number {\r\n        return this._currentIndex;\r\n    }\r\n\r\n    /**\r\n     * Gets the current face index in the current flow\r\n     * @returns the current face index\r\n     */\r\n    public getExecutionFaceIndex(): number {\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"AggregatorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the source input component\r\n     */\r\n    public get source(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            state.pushExecutionContext(this);\r\n\r\n            this._vertexData = this.geometry.getConnectedValue(state);\r\n\r\n            state.pushGeometryContext(this._vertexData);\r\n\r\n            if (!this._vertexData || !this._vertexData.positions || !this.source.isConnected) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            // Processing\r\n            const vertexCount = this._vertexData.positions.length / 3;\r\n            const context: any[] = [];\r\n            for (this._currentIndex = 0; this._currentIndex < vertexCount; this._currentIndex++) {\r\n                context.push(this.source.getConnectedValue(state));\r\n            }\r\n\r\n            // Aggregation\r\n            let func: Nullable<(a: number, b: number) => number> = null;\r\n\r\n            switch (this.aggregation) {\r\n                case Aggregations.Max: {\r\n                    func = (a: number, b: number) => Math.max(a, b);\r\n                    break;\r\n                }\r\n                case Aggregations.Min: {\r\n                    func = (a: number, b: number) => Math.min(a, b);\r\n                    break;\r\n                }\r\n                case Aggregations.Sum: {\r\n                    func = (a: number, b: number) => a + b;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (!func) {\r\n                state.restoreGeometryContext();\r\n                state.restoreExecutionContext();\r\n                this.output._storedFunction = null;\r\n                this.output._storedValue = null;\r\n                return;\r\n            }\r\n\r\n            let returnValue: any;\r\n\r\n            switch (this.source.type) {\r\n                case NodeGeometryBlockConnectionPointTypes.Int:\r\n                case NodeGeometryBlockConnectionPointTypes.Float: {\r\n                    returnValue = (context as number[]).reduce(func);\r\n                    break;\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector2: {\r\n                    const x = (context as Vector2[]).map((v) => v.x).reduce(func);\r\n                    const y = (context as Vector2[]).map((v) => v.y).reduce(func);\r\n                    returnValue = new Vector2(x, y);\r\n                    break;\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector3: {\r\n                    const x = (context as Vector3[]).map((v) => v.x).reduce(func);\r\n                    const y = (context as Vector3[]).map((v) => v.y).reduce(func);\r\n                    const z = (context as Vector3[]).map((v) => v.z).reduce(func);\r\n                    returnValue = new Vector3(x, y, z);\r\n                    break;\r\n                }\r\n                case NodeGeometryBlockConnectionPointTypes.Vector4: {\r\n                    const x = (context as Vector4[]).map((v) => v.x).reduce(func);\r\n                    const y = (context as Vector4[]).map((v) => v.y).reduce(func);\r\n                    const z = (context as Vector4[]).map((v) => v.z).reduce(func);\r\n                    const w = (context as Vector4[]).map((v) => v.w).reduce(func);\r\n                    returnValue = new Vector4(x, y, z, w);\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // Storage\r\n            state.restoreGeometryContext();\r\n            state.restoreExecutionContext();\r\n            return returnValue;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.aggregation = BABYLON.Aggregations.${Aggregations[this.aggregation]};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.aggregation = this.aggregation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n        if (serializationObject.aggregation !== undefined) {\r\n            this.aggregation = serializationObject.aggregation;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for aggregatorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAggregatorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AggregatorBlock\", AggregatorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Subdivide } from \"core/Meshes/mesh.vertexData.subdivide\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to subdivide for a geometry using Catmull-Clark algorithm\r\n */\r\nexport class SubdivideBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     */\r\n    @editableInPropertyPage(\"Flat Only\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public flatOnly = false;\r\n\r\n    /**\r\n     * Gets or sets a float defining the loop weight. i.e how much to weigh favoring heavy corners vs favoring Loop's formula\r\n     */\r\n    @editableInPropertyPage(\"Loop weight\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, min: 0, max: 1, notifiers: { rebuild: true } })\r\n    public loopWeight = 1.0;\r\n\r\n    /**\r\n     * Creates a new ComputeNormalsBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"level\", NodeGeometryBlockConnectionPointTypes.Int, true, 1, 0, 8);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SubdivideBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the level component\r\n     */\r\n    public get level(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock() {\r\n        this.output._storedFunction = (state) => {\r\n            if (!this.geometry.isConnected) {\r\n                return null;\r\n            }\r\n\r\n            const vertexData = this.geometry.getConnectedValue(state);\r\n            if (!vertexData) {\r\n                return null;\r\n            }\r\n\r\n            const level = this.level.getConnectedValue(state);\r\n\r\n            return Subdivide(vertexData, level, {\r\n                flatOnly: this.flatOnly,\r\n                weight: this.loopWeight,\r\n            });\r\n        };\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.flatOnly = ${this.flatOnly ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.loopWeight = ${this.loopWeight};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.flatOnly = this.flatOnly;\r\n        serializationObject.loopWeight = this.loopWeight;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.flatOnly = serializationObject.flatOnly;\r\n        this.loopWeight = serializationObject.loopWeight;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for subdivideBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSubdivideBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SubdivideBlock\", SubdivideBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { VertexData } from \"../../mesh.vertexData\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Cap mode for the extrusion\r\n */\r\nexport enum ExtrudeGeometryCap {\r\n    /** No caps — only the extruded side walls are generated */\r\n    NoCap = 0,\r\n    /** Cap the bottom face (the original input geometry face) */\r\n    CapStart = 1,\r\n    /** Cap the top face (the offset/extruded geometry face) */\r\n    CapEnd = 2,\r\n    /** Cap both the bottom and top faces (default). Creates a solid */\r\n    CapAll = 3,\r\n}\r\n\r\n/**\r\n * Block used to extrude a geometry along its face normals\r\n */\r\nexport class ExtrudeGeometryBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Gets or sets the cap mode for the extrusion\r\n     */\r\n    @editableInPropertyPage(\"Cap\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"No Cap\", value: ExtrudeGeometryCap.NoCap },\r\n            { label: \"Cap Start\", value: ExtrudeGeometryCap.CapStart },\r\n            { label: \"Cap End\", value: ExtrudeGeometryCap.CapEnd },\r\n            { label: \"Cap All\", value: ExtrudeGeometryCap.CapAll },\r\n        ],\r\n    })\r\n    public cap = ExtrudeGeometryCap.CapAll;\r\n\r\n    /**\r\n     * Create a new ExtrudeGeometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"depth\", NodeGeometryBlockConnectionPointTypes.Float, true, 1.0);\r\n\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ExtrudeGeometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the depth input component\r\n     */\r\n    public get depth(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const inputGeometry = this.geometry.getConnectedValue(state) as VertexData;\r\n\r\n            if (!inputGeometry || !inputGeometry.positions || !inputGeometry.indices) {\r\n                return null;\r\n            }\r\n\r\n            const vertexData = inputGeometry.clone();\r\n            const positions = vertexData.positions!;\r\n            const indices = vertexData.indices!;\r\n            const depthValue: number = this.depth.getConnectedValue(state) ?? 1.0;\r\n\r\n            if (depthValue === 0) {\r\n                return vertexData;\r\n            }\r\n\r\n            // Step 2: Compute average face normal\r\n            const normal = new Vector3(0, 0, 0);\r\n            const v0 = new Vector3();\r\n            const v1 = new Vector3();\r\n            const v2 = new Vector3();\r\n            const edge1 = new Vector3();\r\n            const edge2 = new Vector3();\r\n            const faceNormal = new Vector3();\r\n\r\n            for (let i = 0; i < indices.length; i += 3) {\r\n                const i0 = indices[i];\r\n                const i1 = indices[i + 1];\r\n                const i2 = indices[i + 2];\r\n\r\n                v0.set(positions[i0 * 3], positions[i0 * 3 + 1], positions[i0 * 3 + 2]);\r\n                v1.set(positions[i1 * 3], positions[i1 * 3 + 1], positions[i1 * 3 + 2]);\r\n                v2.set(positions[i2 * 3], positions[i2 * 3 + 1], positions[i2 * 3 + 2]);\r\n\r\n                v1.subtractToRef(v0, edge1);\r\n                v2.subtractToRef(v0, edge2);\r\n                Vector3.CrossToRef(edge1, edge2, faceNormal);\r\n\r\n                normal.addInPlace(faceNormal);\r\n            }\r\n\r\n            if (normal.lengthSquared() < 1e-10) {\r\n                normal.set(0, 1, 0);\r\n            } else {\r\n                normal.normalize();\r\n            }\r\n\r\n            // Step 3: Create offset positions\r\n            const offset = normal.scale(depthValue);\r\n            const vertexCount = positions.length / 3;\r\n            const bottomPositions = new Float32Array(positions);\r\n            const topPositions = new Float32Array(vertexCount * 3);\r\n\r\n            for (let i = 0; i < vertexCount; i++) {\r\n                topPositions[i * 3] = positions[i * 3] + offset.x;\r\n                topPositions[i * 3 + 1] = positions[i * 3 + 1] + offset.y;\r\n                topPositions[i * 3 + 2] = positions[i * 3 + 2] + offset.z;\r\n            }\r\n\r\n            // Step 4: Detect boundary edges\r\n            const edgeCount = new Map<string, { count: number; triIndex: number }>();\r\n            for (let i = 0; i < indices.length; i += 3) {\r\n                const triIdx = i;\r\n                const triVerts = [indices[i], indices[i + 1], indices[i + 2]];\r\n\r\n                for (let e = 0; e < 3; e++) {\r\n                    const a = triVerts[e];\r\n                    const b = triVerts[(e + 1) % 3];\r\n                    const key = Math.min(a, b) + \"_\" + Math.max(a, b);\r\n\r\n                    const existing = edgeCount.get(key);\r\n                    if (existing) {\r\n                        existing.count++;\r\n                    } else {\r\n                        edgeCount.set(key, { count: 1, triIndex: triIdx });\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Collect boundary edges with winding info\r\n            const boundaryEdges: { a: number; b: number; orderedAb: boolean }[] = [];\r\n            for (const [key, value] of Array.from(edgeCount)) {\r\n                if (value.count === 1) {\r\n                    const parts = key.split(\"_\");\r\n                    const minV = parseInt(parts[0]);\r\n                    const maxV = parseInt(parts[1]);\r\n\r\n                    // Check original winding order in the triangle\r\n                    const ti = value.triIndex;\r\n                    const t0 = indices[ti];\r\n                    const t1 = indices[ti + 1];\r\n                    const t2 = indices[ti + 2];\r\n\r\n                    // Determine if edge (minV, maxV) appears in order or reversed in the triangle\r\n                    let inOrder = false;\r\n                    if ((t0 === minV && t1 === maxV) || (t1 === minV && t2 === maxV) || (t2 === minV && t0 === maxV)) {\r\n                        inOrder = true;\r\n                    }\r\n\r\n                    boundaryEdges.push({ a: minV, b: maxV, orderedAb: inOrder });\r\n                }\r\n            }\r\n\r\n            // Step 5: Generate side wall faces\r\n            const sideIndices: number[] = [];\r\n            for (const edge of boundaryEdges) {\r\n                const a = edge.a;\r\n                const b = edge.b;\r\n                const aTop = a + vertexCount;\r\n                const bTop = b + vertexCount;\r\n\r\n                if (edge.orderedAb) {\r\n                    // Edge appears as (a, b) in triangle — outward normals\r\n                    sideIndices.push(a, b, bTop);\r\n                    sideIndices.push(a, bTop, aTop);\r\n                } else {\r\n                    // Edge appears as (b, a) in triangle — reverse winding\r\n                    sideIndices.push(b, a, aTop);\r\n                    sideIndices.push(b, aTop, bTop);\r\n                }\r\n            }\r\n\r\n            // Step 6: Assemble final VertexData\r\n            const capStart = (this.cap & ExtrudeGeometryCap.CapStart) !== 0;\r\n            const capEnd = (this.cap & ExtrudeGeometryCap.CapEnd) !== 0;\r\n\r\n            // Build indices\r\n            const finalIndices: number[] = [];\r\n\r\n            // Bottom cap: original indices\r\n            if (capStart) {\r\n                for (let i = 0; i < indices.length; i++) {\r\n                    finalIndices.push(indices[i]);\r\n                }\r\n            }\r\n\r\n            // Top cap: original indices offset by vertexCount, reversed winding\r\n            if (capEnd) {\r\n                for (let i = 0; i < indices.length; i += 3) {\r\n                    finalIndices.push(indices[i] + vertexCount);\r\n                    finalIndices.push(indices[i + 2] + vertexCount);\r\n                    finalIndices.push(indices[i + 1] + vertexCount);\r\n                }\r\n            }\r\n\r\n            // Side walls\r\n            for (let i = 0; i < sideIndices.length; i++) {\r\n                finalIndices.push(sideIndices[i]);\r\n            }\r\n\r\n            // Build positions: [bottom, top]\r\n            const finalPositions = new Float32Array(vertexCount * 2 * 3);\r\n            finalPositions.set(bottomPositions, 0);\r\n            finalPositions.set(topPositions, vertexCount * 3);\r\n\r\n            // Build the result VertexData\r\n            const result = new VertexData();\r\n            result.positions = Array.from(finalPositions);\r\n            result.indices = finalIndices;\r\n\r\n            // Duplicate UVs if present\r\n            if (vertexData.uvs) {\r\n                const uvs = vertexData.uvs;\r\n                const finalUVs = new Float32Array(vertexCount * 2 * 2);\r\n                finalUVs.set(new Float32Array(uvs), 0);\r\n                finalUVs.set(new Float32Array(uvs), vertexCount * 2);\r\n                result.uvs = Array.from(finalUVs);\r\n            }\r\n\r\n            // Duplicate colors if present\r\n            if (vertexData.colors) {\r\n                const colors = vertexData.colors;\r\n                const finalColors = new Float32Array(vertexCount * 2 * 4);\r\n                finalColors.set(new Float32Array(colors), 0);\r\n                finalColors.set(new Float32Array(colors), vertexCount * 4);\r\n                result.colors = Array.from(finalColors);\r\n            }\r\n\r\n            // Duplicate tangents if present\r\n            if (vertexData.tangents) {\r\n                const tangents = vertexData.tangents;\r\n                const finalTangents = new Float32Array(vertexCount * 2 * 4);\r\n                finalTangents.set(new Float32Array(tangents), 0);\r\n                finalTangents.set(new Float32Array(tangents), vertexCount * 4);\r\n                result.tangents = Array.from(finalTangents);\r\n            }\r\n\r\n            // Duplicate UV2-UV6 if present\r\n            const uvSets = [\"uvs2\", \"uvs3\", \"uvs4\", \"uvs5\", \"uvs6\"] as const;\r\n            for (const uvSet of uvSets) {\r\n                const uvData = (vertexData as any)[uvSet];\r\n                if (uvData) {\r\n                    const finalUV = new Float32Array(vertexCount * 2 * 2);\r\n                    finalUV.set(new Float32Array(uvData), 0);\r\n                    finalUV.set(new Float32Array(uvData), vertexCount * 2);\r\n                    (result as any)[uvSet] = Array.from(finalUV);\r\n                }\r\n            }\r\n\r\n            // Compute normals using the simplified approach\r\n            const normals: number[] = [];\r\n            VertexData.ComputeNormals(result.positions, result.indices, normals);\r\n            result.normals = normals;\r\n\r\n            return result;\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        let codeString = super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n        codeString += `${this._codeVariableName}.cap = BABYLON.ExtrudeGeometryCap.${ExtrudeGeometryCap[this.cap]};\\n`;\r\n        return codeString;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n        serializationObject.cap = this.cap;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n        if (serializationObject.cap !== undefined) {\r\n            this.cap = serializationObject.cap;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for extrudeGeometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterExtrudeGeometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ExtrudeGeometryBlock\", ExtrudeGeometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../Decorators/nodeDecorator\";\r\nimport { Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { VertexData, VertexDataMaterialInfo } from \"../../mesh.vertexData\";\r\nimport { NodeGeometryBlockConnectionPointTypes } from \"../Enums/nodeGeometryConnectionPointTypes\";\r\nimport { type NodeGeometryBuildState } from \"../nodeGeometryBuildState\";\r\nimport { NodeGeometryBlock } from \"../nodeGeometryBlock\";\r\nimport { type NodeGeometryConnectionPoint } from \"../nodeGeometryBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\nconst PositionEpsilon = 1e-5;\r\nconst OutputPositionEpsilon = 1e-4;\r\nconst NormalEpsilon = 1e-8;\r\nconst AngleEpsilon = 1e-7;\r\nconst TriangleAreaEpsilon = PositionEpsilon * PositionEpsilon * PositionEpsilon * PositionEpsilon;\r\n\r\ntype BevelFaceEdgeSegment = {\r\n    edgeKey: string;\r\n    faceIndex: number;\r\n    inward: Vector3;\r\n    tMin: number;\r\n    tMax: number;\r\n    minPoint: Vector3;\r\n    maxPoint: Vector3;\r\n    minNormal: Vector3;\r\n    maxNormal: Vector3;\r\n    minAttributes: number[];\r\n    maxAttributes: number[];\r\n    materialIndex: number;\r\n};\r\n\r\ntype BevelPolygonPoint = {\r\n    position: Vector3;\r\n    normal: Vector3;\r\n    attributes: number[];\r\n    materialIndex: number;\r\n};\r\n\r\ntype BevelCapPoint = Vector3 | BevelPolygonPoint;\r\n\r\ntype BevelPreparedFace = {\r\n    faceIndex: number;\r\n    polygon: BevelPolygonPoint[];\r\n    selectedFaceEdges: BevelFaceClipEdge[];\r\n    isFlat: boolean;\r\n};\r\n\r\ntype BevelEdgeInterval = {\r\n    tStart: number;\r\n    tEnd: number;\r\n};\r\n\r\ntype BevelFaceClipEdge = {\r\n    key: string;\r\n    start: number;\r\n    end: number;\r\n    inward: Vector3;\r\n};\r\n\r\ntype BevelFace = {\r\n    indices: [number, number, number];\r\n    originalIndices: [number, number, number];\r\n    normal: Vector3;\r\n    cornerNormals: [Vector3, Vector3, Vector3];\r\n    materialIndex: number;\r\n};\r\n\r\ntype BevelEdgeFace = {\r\n    faceIndex: number;\r\n};\r\n\r\ntype BevelEdge = {\r\n    key: string;\r\n    v0: number;\r\n    v1: number;\r\n    faces: BevelEdgeFace[];\r\n};\r\n\r\ntype BevelTopology = {\r\n    positions: Vector3[];\r\n    faces: BevelFace[];\r\n    edges: Map<string, BevelEdge>;\r\n    vertexFaces: Map<number, number[]>;\r\n};\r\n\r\ntype BevelAttributeName =\r\n    \"tangents\" | \"uvs\" | \"uvs2\" | \"uvs3\" | \"uvs4\" | \"uvs5\" | \"uvs6\" | \"colors\" | \"matricesIndices\" | \"matricesWeights\" | \"matricesIndicesExtra\" | \"matricesWeightsExtra\";\r\n\r\ntype BevelAttributeDescriptor = {\r\n    name: BevelAttributeName;\r\n    source: ArrayLike<number>;\r\n    stride: number;\r\n    offset: number;\r\n    output: number[];\r\n};\r\n\r\nfunction _Quantize(value: number) {\r\n    const quantized = Math.round(value / PositionEpsilon);\r\n    return quantized === 0 ? 0 : quantized;\r\n}\r\n\r\nfunction _PositionKey(x: number, y: number, z: number) {\r\n    return `${_Quantize(x)}:${_Quantize(y)}:${_Quantize(z)}`;\r\n}\r\n\r\nfunction _VectorKey(position: Vector3) {\r\n    return _PositionKey(position.x, position.y, position.z);\r\n}\r\n\r\nfunction _OutputQuantize(value: number) {\r\n    const quantized = Math.round(value / OutputPositionEpsilon);\r\n    return quantized === 0 ? 0 : quantized;\r\n}\r\n\r\nfunction _OutputPositionKey(x: number, y: number, z: number) {\r\n    return `${x}:${y}:${z}`;\r\n}\r\n\r\nfunction _EdgeKey(v0: number, v1: number) {\r\n    return v0 < v1 ? `${v0}:${v1}` : `${v1}:${v0}`;\r\n}\r\n\r\nfunction _CloneVertexData(vertexData: VertexData) {\r\n    const clone = vertexData.clone();\r\n    if (!clone.normals && clone.positions && clone.indices) {\r\n        const normals: number[] = [];\r\n        VertexData.ComputeNormals(clone.positions, clone.indices, normals);\r\n        clone.normals = normals;\r\n    }\r\n\r\n    return clone;\r\n}\r\n\r\nfunction _NormalizeNormalOrFallback(normal: Vector3, fallback: Vector3) {\r\n    return normal.lengthSquared() > NormalEpsilon ? normal.normalizeToNew() : fallback.normalizeToNew();\r\n}\r\n\r\nfunction _BuildAttributeDescriptors(vertexData: VertexData, vertexCount: number) {\r\n    const descriptors: BevelAttributeDescriptor[] = [];\r\n    const addDescriptor = (name: BevelAttributeName, stride: number) => {\r\n        const source = vertexData[name];\r\n\r\n        if (!source || source.length < vertexCount * stride) {\r\n            return;\r\n        }\r\n\r\n        descriptors.push({\r\n            name,\r\n            source,\r\n            stride,\r\n            offset: descriptors.reduce((sum, descriptor) => sum + descriptor.stride, 0),\r\n            output: [],\r\n        });\r\n    };\r\n\r\n    addDescriptor(\"tangents\", 4);\r\n    addDescriptor(\"uvs\", 2);\r\n    addDescriptor(\"uvs2\", 2);\r\n    addDescriptor(\"uvs3\", 2);\r\n    addDescriptor(\"uvs4\", 2);\r\n    addDescriptor(\"uvs5\", 2);\r\n    addDescriptor(\"uvs6\", 2);\r\n    if (vertexData.colors) {\r\n        addDescriptor(\"colors\", vertexData.colors.length === vertexData.positions!.length ? 3 : 4);\r\n    }\r\n    addDescriptor(\"matricesIndices\", 4);\r\n    addDescriptor(\"matricesWeights\", 4);\r\n    addDescriptor(\"matricesIndicesExtra\", 4);\r\n    addDescriptor(\"matricesWeightsExtra\", 4);\r\n\r\n    return descriptors;\r\n}\r\n\r\nfunction _GetAttributeLength(descriptors: BevelAttributeDescriptor[]) {\r\n    return descriptors.reduce((sum, descriptor) => sum + descriptor.stride, 0);\r\n}\r\n\r\nfunction _GetVertexAttributes(descriptors: BevelAttributeDescriptor[], vertexIndex: number) {\r\n    const attributes: number[] = [];\r\n\r\n    for (const descriptor of descriptors) {\r\n        const sourceOffset = vertexIndex * descriptor.stride;\r\n        for (let index = 0; index < descriptor.stride; index++) {\r\n            attributes.push(descriptor.source[sourceOffset + index]);\r\n        }\r\n    }\r\n\r\n    return attributes;\r\n}\r\n\r\nfunction _InterpolateAttributes(start: number[], end: number[], amount: number) {\r\n    if (!start.length) {\r\n        return start;\r\n    }\r\n\r\n    return start.map((value, index) => value + (end[index] - value) * amount);\r\n}\r\n\r\nfunction _AverageAttributes(attributes: number[][], length: number) {\r\n    if (!length || !attributes.length) {\r\n        return [];\r\n    }\r\n\r\n    const result = new Array<number>(length).fill(0);\r\n\r\n    for (const attribute of attributes) {\r\n        for (let index = 0; index < length; index++) {\r\n            result[index] += attribute[index] ?? 0;\r\n        }\r\n    }\r\n\r\n    for (let index = 0; index < length; index++) {\r\n        result[index] /= attributes.length;\r\n    }\r\n\r\n    return result;\r\n}\r\n\r\nfunction _AttributesMatch(left: number[], right: number[]) {\r\n    if (left.length !== right.length) {\r\n        return false;\r\n    }\r\n\r\n    for (let index = 0; index < left.length; index++) {\r\n        if (Math.abs(left[index] - right[index]) > OutputPositionEpsilon) {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nfunction _AssignAttributeOutputs(result: VertexData, descriptors: BevelAttributeDescriptor[], vertexAttributes: number[][]) {\r\n    for (const descriptor of descriptors) {\r\n        descriptor.output.length = 0;\r\n\r\n        for (const attributes of vertexAttributes) {\r\n            for (let index = 0; index < descriptor.stride; index++) {\r\n                descriptor.output.push(attributes[descriptor.offset + index] ?? 0);\r\n            }\r\n        }\r\n\r\n        switch (descriptor.name) {\r\n            case \"tangents\":\r\n                result.tangents = descriptor.output;\r\n                break;\r\n            case \"uvs\":\r\n                result.uvs = descriptor.output;\r\n                break;\r\n            case \"uvs2\":\r\n                result.uvs2 = descriptor.output;\r\n                break;\r\n            case \"uvs3\":\r\n                result.uvs3 = descriptor.output;\r\n                break;\r\n            case \"uvs4\":\r\n                result.uvs4 = descriptor.output;\r\n                break;\r\n            case \"uvs5\":\r\n                result.uvs5 = descriptor.output;\r\n                break;\r\n            case \"uvs6\":\r\n                result.uvs6 = descriptor.output;\r\n                break;\r\n            case \"colors\":\r\n                result.colors = descriptor.output;\r\n                break;\r\n            case \"matricesIndices\":\r\n                result.matricesIndices = descriptor.output;\r\n                break;\r\n            case \"matricesWeights\":\r\n                result.matricesWeights = descriptor.output;\r\n                break;\r\n            case \"matricesIndicesExtra\":\r\n                result.matricesIndicesExtra = descriptor.output;\r\n                break;\r\n            case \"matricesWeightsExtra\":\r\n                result.matricesWeightsExtra = descriptor.output;\r\n                break;\r\n        }\r\n    }\r\n}\r\n\r\nfunction _GetMaterialIndex(vertexData: VertexData, indexStart: number) {\r\n    if (!vertexData.materialInfos) {\r\n        return 0;\r\n    }\r\n\r\n    for (const materialInfo of vertexData.materialInfos) {\r\n        if (indexStart >= materialInfo.indexStart && indexStart < materialInfo.indexStart + materialInfo.indexCount) {\r\n            return materialInfo.materialIndex;\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}\r\n\r\nfunction _BuildMaterialInfoResult(vertexData: VertexData, indices: number[], materialIndices: number[], vertexCount: number) {\r\n    if (!vertexData.materialInfos?.length) {\r\n        return { indices, materialInfos: null };\r\n    }\r\n\r\n    const materialOrder = vertexData.materialInfos.map((materialInfo) => materialInfo.materialIndex);\r\n    const groups = new Map<number, number[]>();\r\n\r\n    for (let triangleIndex = 0; triangleIndex < materialIndices.length; triangleIndex++) {\r\n        const materialIndex = materialIndices[triangleIndex];\r\n        let group = groups.get(materialIndex);\r\n\r\n        if (!group) {\r\n            group = [];\r\n            groups.set(materialIndex, group);\r\n            if (!materialOrder.includes(materialIndex)) {\r\n                materialOrder.push(materialIndex);\r\n            }\r\n        }\r\n\r\n        const indexOffset = triangleIndex * 3;\r\n        group.push(indices[indexOffset], indices[indexOffset + 1], indices[indexOffset + 2]);\r\n    }\r\n\r\n    const groupedIndices: number[] = [];\r\n    const materialInfos: VertexDataMaterialInfo[] = [];\r\n\r\n    for (const materialIndex of materialOrder) {\r\n        const group = groups.get(materialIndex);\r\n\r\n        if (!group?.length) {\r\n            continue;\r\n        }\r\n\r\n        const materialInfo = new VertexDataMaterialInfo();\r\n        materialInfo.materialIndex = materialIndex;\r\n        materialInfo.indexStart = groupedIndices.length;\r\n        materialInfo.indexCount = group.length;\r\n        materialInfo.verticesStart = 0;\r\n        materialInfo.verticesCount = vertexCount;\r\n        groupedIndices.push(...group);\r\n        materialInfos.push(materialInfo);\r\n    }\r\n\r\n    return { indices: groupedIndices, materialInfos };\r\n}\r\n\r\nfunction _IsFlatFace(face: BevelFace) {\r\n    return face.cornerNormals.every((normal) => Vector3.Dot(normal, face.normal) > 1 - PositionEpsilon);\r\n}\r\n\r\nfunction _IsBevelPolygonPoint(point: BevelCapPoint): point is BevelPolygonPoint {\r\n    return (point as BevelPolygonPoint).position !== undefined;\r\n}\r\n\r\nfunction _GetCapPointPosition(point: BevelCapPoint) {\r\n    return _IsBevelPolygonPoint(point) ? point.position : point;\r\n}\r\n\r\nfunction _GetCapPointNormal(point: BevelCapPoint, fallback: Vector3) {\r\n    return _IsBevelPolygonPoint(point) ? point.normal : fallback;\r\n}\r\n\r\nfunction _GetCapPointAttributes(point: BevelCapPoint) {\r\n    return _IsBevelPolygonPoint(point) ? point.attributes : [];\r\n}\r\n\r\nfunction _GetCapPointMaterialIndex(point: BevelCapPoint) {\r\n    return _IsBevelPolygonPoint(point) ? point.materialIndex : 0;\r\n}\r\n\r\nfunction _BuildTopology(vertexData: VertexData): BevelTopology | null {\r\n    const positions = vertexData.positions;\r\n    const normals = vertexData.normals;\r\n\r\n    if (!positions || positions.length < 9) {\r\n        return null;\r\n    }\r\n\r\n    const vertexCount = positions.length / 3;\r\n    const indices = vertexData.indices && vertexData.indices.length ? Array.from(vertexData.indices) : Array.from({ length: vertexCount }, (_, index) => index);\r\n    const weldedPositionMap = new Map<string, number>();\r\n    const originalToWelded: number[] = [];\r\n    const weldedPositions: Vector3[] = [];\r\n\r\n    for (let index = 0; index < vertexCount; index++) {\r\n        const x = positions[index * 3];\r\n        const y = positions[index * 3 + 1];\r\n        const z = positions[index * 3 + 2];\r\n        const key = _PositionKey(x, y, z);\r\n        let weldedIndex = weldedPositionMap.get(key);\r\n\r\n        if (weldedIndex === undefined) {\r\n            weldedIndex = weldedPositions.length;\r\n            weldedPositionMap.set(key, weldedIndex);\r\n            weldedPositions.push(new Vector3(x, y, z));\r\n        }\r\n\r\n        originalToWelded[index] = weldedIndex;\r\n    }\r\n\r\n    const faces: BevelFace[] = [];\r\n    const edges = new Map<string, BevelEdge>();\r\n    const vertexFaces = new Map<number, number[]>();\r\n    const edge0 = new Vector3();\r\n    const edge1 = new Vector3();\r\n    const normal = new Vector3();\r\n\r\n    for (let index = 0; index < indices.length; index += 3) {\r\n        let originalIndices: [number, number, number] = [indices[index], indices[index + 1], indices[index + 2]];\r\n        const i0 = originalToWelded[originalIndices[0]];\r\n        const i1 = originalToWelded[originalIndices[1]];\r\n        const i2 = originalToWelded[originalIndices[2]];\r\n\r\n        if (i0 === i1 || i1 === i2 || i2 === i0) {\r\n            continue;\r\n        }\r\n\r\n        let faceIndices: [number, number, number] = [i0, i1, i2];\r\n        const p0 = weldedPositions[faceIndices[0]];\r\n        const p1 = weldedPositions[faceIndices[1]];\r\n        const p2 = weldedPositions[faceIndices[2]];\r\n\r\n        p1.subtractToRef(p0, edge0);\r\n        p2.subtractToRef(p0, edge1);\r\n        Vector3.CrossToRef(edge0, edge1, normal);\r\n\r\n        if (normal.lengthSquared() < NormalEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        let cornerNormals: [Vector3, Vector3, Vector3] = normals\r\n            ? [\r\n                  _NormalizeNormalOrFallback(Vector3.FromArray(normals, originalIndices[0] * 3), normal),\r\n                  _NormalizeNormalOrFallback(Vector3.FromArray(normals, originalIndices[1] * 3), normal),\r\n                  _NormalizeNormalOrFallback(Vector3.FromArray(normals, originalIndices[2] * 3), normal),\r\n              ]\r\n            : [normal.normalizeToNew(), normal.normalizeToNew(), normal.normalizeToNew()];\r\n\r\n        const averageCornerNormal = _NormalizeNormalOrFallback(cornerNormals[0].add(cornerNormals[1]).addInPlace(cornerNormals[2]), normal);\r\n\r\n        if (normals && Vector3.Dot(normal, averageCornerNormal) < 0) {\r\n            faceIndices = [i0, i2, i1];\r\n            originalIndices = [originalIndices[0], originalIndices[2], originalIndices[1]];\r\n            cornerNormals = [cornerNormals[0], cornerNormals[2], cornerNormals[1]];\r\n            normal.scaleInPlace(-1);\r\n        }\r\n\r\n        const faceNormal = normal.normalizeToNew();\r\n\r\n        if (!normals) {\r\n            cornerNormals = [faceNormal.clone(), faceNormal.clone(), faceNormal.clone()];\r\n        }\r\n\r\n        const faceIndex = faces.length;\r\n        faces.push({\r\n            indices: faceIndices,\r\n            originalIndices,\r\n            normal: faceNormal,\r\n            cornerNormals,\r\n            materialIndex: _GetMaterialIndex(vertexData, index),\r\n        });\r\n\r\n        for (const vertexIndex of faceIndices) {\r\n            let faceList = vertexFaces.get(vertexIndex);\r\n            if (!faceList) {\r\n                faceList = [];\r\n                vertexFaces.set(vertexIndex, faceList);\r\n            }\r\n            faceList.push(faceIndex);\r\n        }\r\n\r\n        for (let edgeIndex = 0; edgeIndex < 3; edgeIndex++) {\r\n            const v0 = faceIndices[edgeIndex];\r\n            const v1 = faceIndices[(edgeIndex + 1) % 3];\r\n            const key = _EdgeKey(v0, v1);\r\n            let edge = edges.get(key);\r\n\r\n            if (!edge) {\r\n                edge = {\r\n                    key,\r\n                    v0: Math.min(v0, v1),\r\n                    v1: Math.max(v0, v1),\r\n                    faces: [],\r\n                };\r\n                edges.set(key, edge);\r\n            }\r\n\r\n            edge.faces.push({ faceIndex });\r\n        }\r\n    }\r\n\r\n    if (!faces.length) {\r\n        return null;\r\n    }\r\n\r\n    return {\r\n        positions: weldedPositions,\r\n        faces,\r\n        edges,\r\n        vertexFaces,\r\n    };\r\n}\r\n\r\nfunction _ClonePolygonPoint(point: BevelPolygonPoint): BevelPolygonPoint {\r\n    return {\r\n        position: point.position.clone(),\r\n        normal: point.normal.clone(),\r\n        attributes: point.attributes.slice(),\r\n        materialIndex: point.materialIndex,\r\n    };\r\n}\r\n\r\nfunction _InterpolatePolygonPoint(start: BevelPolygonPoint, end: BevelPolygonPoint, amount: number): BevelPolygonPoint {\r\n    return {\r\n        position: Vector3.Lerp(start.position, end.position, amount),\r\n        normal: _NormalizeNormalOrFallback(Vector3.Lerp(start.normal, end.normal, amount), start.normal),\r\n        attributes: _InterpolateAttributes(start.attributes, end.attributes, amount),\r\n        materialIndex: start.materialIndex,\r\n    };\r\n}\r\n\r\nfunction _InterpolateSegmentNormal(segment: BevelFaceEdgeSegment, t: number) {\r\n    const denominator = segment.tMax - segment.tMin;\r\n\r\n    if (denominator <= PositionEpsilon) {\r\n        return segment.minNormal.clone();\r\n    }\r\n\r\n    const amount = Math.min(1, Math.max(0, (t - segment.tMin) / denominator));\r\n    return _NormalizeNormalOrFallback(Vector3.Lerp(segment.minNormal, segment.maxNormal, amount), segment.minNormal);\r\n}\r\n\r\nfunction _InterpolateSegmentPoint(segment: BevelFaceEdgeSegment, t: number) {\r\n    if (t <= segment.tMin + PositionEpsilon) {\r\n        return segment.minPoint;\r\n    }\r\n\r\n    if (t >= segment.tMax - PositionEpsilon) {\r\n        return segment.maxPoint;\r\n    }\r\n\r\n    return Vector3.Lerp(segment.minPoint, segment.maxPoint, (t - segment.tMin) / (segment.tMax - segment.tMin));\r\n}\r\n\r\nfunction _InterpolateSegmentAttributes(segment: BevelFaceEdgeSegment, t: number) {\r\n    if (t <= segment.tMin + PositionEpsilon) {\r\n        return segment.minAttributes;\r\n    }\r\n\r\n    if (t >= segment.tMax - PositionEpsilon) {\r\n        return segment.maxAttributes;\r\n    }\r\n\r\n    return _InterpolateAttributes(segment.minAttributes, segment.maxAttributes, (t - segment.tMin) / (segment.tMax - segment.tMin));\r\n}\r\n\r\nfunction _ClipPolygonAgainstEdge(polygon: BevelPolygonPoint[], edgeStart: Vector3, inward: Vector3, amount: number) {\r\n    if (!polygon.length) {\r\n        return polygon;\r\n    }\r\n\r\n    const output: BevelPolygonPoint[] = [];\r\n    let previous = polygon[polygon.length - 1];\r\n    let previousDistance = Vector3.Dot(previous.position.subtract(edgeStart), inward) - amount;\r\n    let previousInside = previousDistance >= -PositionEpsilon;\r\n\r\n    for (const current of polygon) {\r\n        const currentDistance = Vector3.Dot(current.position.subtract(edgeStart), inward) - amount;\r\n        const currentInside = currentDistance >= -PositionEpsilon;\r\n\r\n        if (currentInside !== previousInside) {\r\n            const denominator = previousDistance - currentDistance;\r\n            if (Math.abs(denominator) > NormalEpsilon) {\r\n                const t = previousDistance / denominator;\r\n                output.push(_InterpolatePolygonPoint(previous, current, t));\r\n            }\r\n        }\r\n\r\n        if (currentInside) {\r\n            output.push(_ClonePolygonPoint(current));\r\n        }\r\n\r\n        previous = current;\r\n        previousDistance = currentDistance;\r\n        previousInside = currentInside;\r\n    }\r\n\r\n    return output;\r\n}\r\n\r\nfunction _SlerpDirections(start: Vector3, end: Vector3, amount: number) {\r\n    const dot = Math.min(1, Math.max(-1, Vector3.Dot(start, end)));\r\n\r\n    if (dot > 1 - PositionEpsilon) {\r\n        return Vector3.Lerp(start, end, amount).normalize();\r\n    }\r\n\r\n    const theta = Math.acos(dot);\r\n    const sinTheta = Math.sin(theta);\r\n\r\n    if (Math.abs(sinTheta) < NormalEpsilon) {\r\n        return Vector3.Lerp(start, end, amount).normalize();\r\n    }\r\n\r\n    const startScale = Math.sin((1 - amount) * theta) / sinTheta;\r\n    const endScale = Math.sin(amount * theta) / sinTheta;\r\n    const result = start.scale(startScale).addInPlace(end.scale(endScale));\r\n\r\n    if (result.lengthSquared() < NormalEpsilon) {\r\n        return Vector3.Lerp(start, end, amount).normalize();\r\n    }\r\n\r\n    return result.normalize();\r\n}\r\n\r\nfunction _AddUniquePoint(points: BevelCapPoint[], point: Vector3, normal: Vector3, attributes: number[], materialIndex: number) {\r\n    const key = _VectorKey(point);\r\n    const normalizedNormal = _NormalizeNormalOrFallback(normal, normal);\r\n\r\n    for (const existing of points) {\r\n        if (_VectorKey(_GetCapPointPosition(existing)) === key) {\r\n            if (_IsBevelPolygonPoint(existing)) {\r\n                existing.normal.addInPlace(normalizedNormal).normalize();\r\n                existing.attributes = _AverageAttributes([existing.attributes, attributes], attributes.length);\r\n            }\r\n            return;\r\n        }\r\n    }\r\n\r\n    points.push({\r\n        position: point.clone(),\r\n        normal: normalizedNormal,\r\n        attributes: attributes.slice(),\r\n        materialIndex,\r\n    });\r\n}\r\n\r\nfunction _AddUniqueNormal(normals: Vector3[], normal: Vector3) {\r\n    for (const existing of normals) {\r\n        if (Vector3.Dot(existing, normal) > 1 - PositionEpsilon) {\r\n            return;\r\n        }\r\n    }\r\n\r\n    normals.push(normal.clone());\r\n}\r\n\r\nfunction _SolveThreePlaneIntersection(normals: Vector3[], distances: number[]) {\r\n    const cross12 = Vector3.Cross(normals[1], normals[2]);\r\n    const denominator = Vector3.Dot(normals[0], cross12);\r\n\r\n    if (Math.abs(denominator) < NormalEpsilon) {\r\n        return null;\r\n    }\r\n\r\n    const result = cross12.scale(distances[0]);\r\n    result.addInPlace(Vector3.Cross(normals[2], normals[0]).scale(distances[1]));\r\n    result.addInPlace(Vector3.Cross(normals[0], normals[1]).scale(distances[2]));\r\n    result.scaleInPlace(1 / denominator);\r\n\r\n    return result;\r\n}\r\n\r\nfunction _BuildCoplanarFaceClipEdges(topology: BevelTopology, selectedEdges: Set<string>) {\r\n    const result = new Map<number, BevelFaceClipEdge[]>();\r\n    const visitedFaces = new Set<number>();\r\n\r\n    for (let startFaceIndex = 0; startFaceIndex < topology.faces.length; startFaceIndex++) {\r\n        if (visitedFaces.has(startFaceIndex)) {\r\n            continue;\r\n        }\r\n\r\n        const group: number[] = [];\r\n        const stack = [startFaceIndex];\r\n        const groupNormal = topology.faces[startFaceIndex].normal;\r\n        visitedFaces.add(startFaceIndex);\r\n\r\n        while (stack.length) {\r\n            const faceIndex = stack.pop()!;\r\n            const face = topology.faces[faceIndex];\r\n            group.push(faceIndex);\r\n\r\n            for (let edgeIndex = 0; edgeIndex < 3; edgeIndex++) {\r\n                const key = _EdgeKey(face.indices[edgeIndex], face.indices[(edgeIndex + 1) % 3]);\r\n                const edge = topology.edges.get(key);\r\n\r\n                if (!edge) {\r\n                    continue;\r\n                }\r\n\r\n                for (const edgeFace of edge.faces) {\r\n                    if (visitedFaces.has(edgeFace.faceIndex)) {\r\n                        continue;\r\n                    }\r\n\r\n                    if (Vector3.Dot(groupNormal, topology.faces[edgeFace.faceIndex].normal) < 1 - PositionEpsilon) {\r\n                        continue;\r\n                    }\r\n\r\n                    visitedFaces.add(edgeFace.faceIndex);\r\n                    stack.push(edgeFace.faceIndex);\r\n                }\r\n            }\r\n        }\r\n\r\n        const clipEdges: BevelFaceClipEdge[] = [];\r\n        const addedClipEdges = new Set<string>();\r\n\r\n        for (const faceIndex of group) {\r\n            const face = topology.faces[faceIndex];\r\n\r\n            for (let edgeIndex = 0; edgeIndex < 3; edgeIndex++) {\r\n                const start = face.indices[edgeIndex];\r\n                const end = face.indices[(edgeIndex + 1) % 3];\r\n                const key = _EdgeKey(start, end);\r\n\r\n                if (!selectedEdges.has(key) || addedClipEdges.has(key)) {\r\n                    continue;\r\n                }\r\n\r\n                const edgeStart = topology.positions[start];\r\n                const edgeEnd = topology.positions[end];\r\n                const edgeDirection = edgeEnd.subtract(edgeStart).normalize();\r\n                const inward = Vector3.Cross(face.normal, edgeDirection).normalize();\r\n                clipEdges.push({ key, start, end, inward });\r\n                addedClipEdges.add(key);\r\n            }\r\n        }\r\n\r\n        for (const faceIndex of group) {\r\n            result.set(faceIndex, clipEdges);\r\n        }\r\n    }\r\n\r\n    return result;\r\n}\r\n\r\nfunction _InsertPointOnPolygonBoundary(polygon: BevelPolygonPoint[], point: Vector3) {\r\n    for (const existing of polygon) {\r\n        if (existing.position.subtract(point).lengthSquared() <= PositionEpsilon * PositionEpsilon) {\r\n            return;\r\n        }\r\n    }\r\n\r\n    let bestEdgeIndex = -1;\r\n    let bestDistanceSquared = Number.MAX_VALUE;\r\n    let bestProjection = 0;\r\n\r\n    for (let index = 0; index < polygon.length; index++) {\r\n        const start = polygon[index].position;\r\n        const end = polygon[(index + 1) % polygon.length].position;\r\n        const edge = end.subtract(start);\r\n        const edgeLengthSquared = edge.lengthSquared();\r\n\r\n        if (edgeLengthSquared < PositionEpsilon * PositionEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        const projection = Vector3.Dot(point.subtract(start), edge) / edgeLengthSquared;\r\n\r\n        if (projection < -PositionEpsilon || projection > 1 + PositionEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        const closest = start.add(edge.scale(projection));\r\n        const distanceSquared = closest.subtract(point).lengthSquared();\r\n\r\n        if (distanceSquared < bestDistanceSquared) {\r\n            bestDistanceSquared = distanceSquared;\r\n            bestEdgeIndex = index;\r\n            bestProjection = projection;\r\n        }\r\n    }\r\n\r\n    if (bestEdgeIndex !== -1 && bestDistanceSquared <= OutputPositionEpsilon * OutputPositionEpsilon) {\r\n        const insertedPoint = _InterpolatePolygonPoint(polygon[bestEdgeIndex], polygon[(bestEdgeIndex + 1) % polygon.length], bestProjection);\r\n        insertedPoint.position = point.clone();\r\n        polygon.splice(bestEdgeIndex + 1, 0, insertedPoint);\r\n    }\r\n}\r\n\r\nfunction _BuildMergedBoundaryPolygon(polygons: BevelPolygonPoint[][]) {\r\n    const points = new Map<string, BevelPolygonPoint>();\r\n    const edgeUseCounts = new Map<string, { count: number; key0: string; key1: string }>();\r\n\r\n    for (const polygon of polygons) {\r\n        for (const point of polygon) {\r\n            const key = _VectorKey(point.position);\r\n            const existing = points.get(key);\r\n\r\n            if (existing) {\r\n                existing.normal.addInPlace(point.normal).normalize();\r\n            } else {\r\n                points.set(key, _ClonePolygonPoint(point));\r\n            }\r\n        }\r\n\r\n        for (let index = 0; index < polygon.length; index++) {\r\n            const key0 = _VectorKey(polygon[index].position);\r\n            const key1 = _VectorKey(polygon[(index + 1) % polygon.length].position);\r\n\r\n            if (key0 === key1) {\r\n                continue;\r\n            }\r\n\r\n            const edgeKey = key0 < key1 ? `${key0}|${key1}` : `${key1}|${key0}`;\r\n            const edgeUseCount = edgeUseCounts.get(edgeKey);\r\n\r\n            if (edgeUseCount) {\r\n                edgeUseCount.count++;\r\n            } else {\r\n                edgeUseCounts.set(edgeKey, { count: 1, key0, key1 });\r\n            }\r\n        }\r\n    }\r\n\r\n    const adjacency = new Map<string, string[]>();\r\n    for (const edge of Array.from(edgeUseCounts.values())) {\r\n        if (edge.count !== 1) {\r\n            continue;\r\n        }\r\n\r\n        let adjacency0 = adjacency.get(edge.key0);\r\n        if (!adjacency0) {\r\n            adjacency0 = [];\r\n            adjacency.set(edge.key0, adjacency0);\r\n        }\r\n        adjacency0.push(edge.key1);\r\n\r\n        let adjacency1 = adjacency.get(edge.key1);\r\n        if (!adjacency1) {\r\n            adjacency1 = [];\r\n            adjacency.set(edge.key1, adjacency1);\r\n        }\r\n        adjacency1.push(edge.key0);\r\n    }\r\n\r\n    if (!adjacency.size || Array.from(adjacency.values()).some((neighbors) => neighbors.length !== 2)) {\r\n        return null;\r\n    }\r\n\r\n    const startKey = Array.from(adjacency.keys()).sort()[0];\r\n    const orderedKeys: string[] = [];\r\n    let previousKey = \"\";\r\n    let currentKey = startKey;\r\n\r\n    do {\r\n        orderedKeys.push(currentKey);\r\n        const neighbors = adjacency.get(currentKey)!;\r\n        const nextKey = neighbors[0] === previousKey ? neighbors[1] : neighbors[0];\r\n        previousKey = currentKey;\r\n        currentKey = nextKey;\r\n\r\n        if (orderedKeys.length > adjacency.size) {\r\n            return null;\r\n        }\r\n    } while (currentKey !== startKey);\r\n\r\n    if (orderedKeys.length !== adjacency.size) {\r\n        return null;\r\n    }\r\n\r\n    return orderedKeys.map((key) => points.get(key)!);\r\n}\r\n\r\nfunction _BevelVertexData(vertexData: VertexData, amount: number, segments: number, angle: number) {\r\n    const topology = _BuildTopology(vertexData);\r\n\r\n    if (!topology || amount <= PositionEpsilon || segments <= 0) {\r\n        return _CloneVertexData(vertexData);\r\n    }\r\n\r\n    const selectedEdges = new Set<string>();\r\n    const selectedVertices = new Set<number>();\r\n    const selectedEdgeCountPerVertex = new Map<number, number>();\r\n    const threshold = Math.cos(angle + AngleEpsilon);\r\n    let shortestSelectedEdgeLength = Number.MAX_VALUE;\r\n\r\n    for (const edge of Array.from(topology.edges.values())) {\r\n        if (edge.faces.length !== 2) {\r\n            continue;\r\n        }\r\n\r\n        const face0 = topology.faces[edge.faces[0].faceIndex];\r\n        const face1 = topology.faces[edge.faces[1].faceIndex];\r\n\r\n        if (Vector3.Dot(face0.normal, face1.normal) < threshold) {\r\n            selectedEdges.add(edge.key);\r\n            selectedVertices.add(edge.v0);\r\n            selectedVertices.add(edge.v1);\r\n            selectedEdgeCountPerVertex.set(edge.v0, (selectedEdgeCountPerVertex.get(edge.v0) ?? 0) + 1);\r\n            selectedEdgeCountPerVertex.set(edge.v1, (selectedEdgeCountPerVertex.get(edge.v1) ?? 0) + 1);\r\n            shortestSelectedEdgeLength = Math.min(shortestSelectedEdgeLength, Vector3.Distance(topology.positions[edge.v0], topology.positions[edge.v1]));\r\n        }\r\n    }\r\n\r\n    if (!selectedEdges.size) {\r\n        return _CloneVertexData(vertexData);\r\n    }\r\n\r\n    const bevelAmount = Math.min(amount, shortestSelectedEdgeLength * 0.5);\r\n\r\n    if (bevelAmount <= PositionEpsilon) {\r\n        return _CloneVertexData(vertexData);\r\n    }\r\n\r\n    const faceClipEdges = _BuildCoplanarFaceClipEdges(topology, selectedEdges);\r\n    const attributeDescriptors = _BuildAttributeDescriptors(vertexData, vertexData.positions!.length / 3);\r\n    const attributeLength = _GetAttributeLength(attributeDescriptors);\r\n    const outputPositions: number[] = [];\r\n    const outputNormals: Vector3[] = [];\r\n    const outputNormalContributions: Vector3[][] = [];\r\n    const outputVertexAttributes: number[][] = [];\r\n    const outputIndices: number[] = [];\r\n    const outputTriangleMaterialIndices: number[] = [];\r\n    const outputVertexBuckets = new Map<string, number[]>();\r\n    const outputVertexGroups: string[] = [];\r\n    const faceEdgeSegments = new Map<string, BevelFaceEdgeSegment>();\r\n    const capPoints = new Map<number, BevelCapPoint[]>();\r\n    const preparedFaces: BevelPreparedFace[] = [];\r\n    const edgeIntervals = new Map<string, BevelEdgeInterval>();\r\n\r\n    const getOrCreateVertex = (position: Vector3, normal: Vector3, smoothingGroup: string, attributes: number[]) => {\r\n        const normalizedNormal = normal.normalizeToNew();\r\n        const vertexAttributes = attributeLength ? (attributes.length === attributeLength ? attributes : new Array<number>(attributeLength).fill(0)) : [];\r\n        const qx = _OutputQuantize(position.x);\r\n        const qy = _OutputQuantize(position.y);\r\n        const qz = _OutputQuantize(position.z);\r\n        let canonicalIndex = -1;\r\n\r\n        for (let dz = -1; dz <= 1; dz++) {\r\n            for (let dy = -1; dy <= 1; dy++) {\r\n                for (let dx = -1; dx <= 1; dx++) {\r\n                    const bucket = outputVertexBuckets.get(_OutputPositionKey(qx + dx, qy + dy, qz + dz));\r\n\r\n                    if (!bucket) {\r\n                        continue;\r\n                    }\r\n\r\n                    for (const index of bucket) {\r\n                        const outputIndex = index * 3;\r\n                        const deltaX = outputPositions[outputIndex] - position.x;\r\n                        const deltaY = outputPositions[outputIndex + 1] - position.y;\r\n                        const deltaZ = outputPositions[outputIndex + 2] - position.z;\r\n\r\n                        if (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ <= OutputPositionEpsilon * OutputPositionEpsilon) {\r\n                            if (canonicalIndex === -1) {\r\n                                canonicalIndex = index;\r\n                            }\r\n\r\n                            if (outputVertexGroups[index] !== smoothingGroup) {\r\n                                continue;\r\n                            }\r\n\r\n                            if (!_AttributesMatch(outputVertexAttributes[index], vertexAttributes)) {\r\n                                continue;\r\n                            }\r\n\r\n                            const normalContributions = outputNormalContributions[index];\r\n                            if (!normalContributions.some((normal) => Vector3.Dot(normal, normalizedNormal) > 1 - PositionEpsilon)) {\r\n                                normalContributions.push(normalizedNormal);\r\n                                outputNormals[index].addInPlace(normalizedNormal);\r\n                            }\r\n                            return index;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        const index = outputPositions.length / 3;\r\n        const outputX = canonicalIndex === -1 ? position.x : outputPositions[canonicalIndex * 3];\r\n        const outputY = canonicalIndex === -1 ? position.y : outputPositions[canonicalIndex * 3 + 1];\r\n        const outputZ = canonicalIndex === -1 ? position.z : outputPositions[canonicalIndex * 3 + 2];\r\n        const key = _OutputPositionKey(_OutputQuantize(outputX), _OutputQuantize(outputY), _OutputQuantize(outputZ));\r\n        let bucket = outputVertexBuckets.get(key);\r\n\r\n        if (!bucket) {\r\n            bucket = [];\r\n            outputVertexBuckets.set(key, bucket);\r\n        }\r\n\r\n        bucket.push(index);\r\n        outputPositions.push(outputX, outputY, outputZ);\r\n        outputNormals.push(normalizedNormal);\r\n        outputNormalContributions.push([normalizedNormal.clone()]);\r\n        outputVertexAttributes.push(vertexAttributes.slice());\r\n        outputVertexGroups.push(smoothingGroup);\r\n\r\n        return index;\r\n    };\r\n\r\n    const addCapPoint = (vertexIndex: number, point: Vector3, normal: Vector3, attributes: number[], materialIndex: number) => {\r\n        let points = capPoints.get(vertexIndex);\r\n        if (!points) {\r\n            points = [];\r\n            capPoints.set(vertexIndex, points);\r\n        }\r\n        _AddUniquePoint(points, point, normal, attributes, materialIndex);\r\n    };\r\n\r\n    const addTriangle = (\r\n        p0: Vector3,\r\n        p1: Vector3,\r\n        p2: Vector3,\r\n        targetNormal: Vector3,\r\n        n0 = targetNormal,\r\n        n1 = targetNormal,\r\n        n2 = targetNormal,\r\n        smoothingGroup = \"smooth\",\r\n        p0Attributes: number[] = [],\r\n        p1Attributes: number[] = [],\r\n        p2Attributes: number[] = [],\r\n        materialIndex = 0\r\n    ) => {\r\n        const edge0 = p1.subtract(p0);\r\n        const edge1 = p2.subtract(p0);\r\n        const normal = Vector3.Cross(edge0, edge1);\r\n\r\n        if (normal.lengthSquared() < TriangleAreaEpsilon) {\r\n            return;\r\n        }\r\n\r\n        let v1 = p1;\r\n        let v2 = p2;\r\n        let vn1 = n1;\r\n        let vn2 = n2;\r\n        let va1 = p1Attributes;\r\n        let va2 = p2Attributes;\r\n\r\n        if (Vector3.Dot(normal, targetNormal) > 0) {\r\n            v1 = p2;\r\n            v2 = p1;\r\n            vn1 = n2;\r\n            vn2 = n1;\r\n            va1 = p2Attributes;\r\n            va2 = p1Attributes;\r\n        }\r\n\r\n        const i0 = getOrCreateVertex(p0, n0, smoothingGroup, p0Attributes);\r\n        const i1 = getOrCreateVertex(v1, vn1, smoothingGroup, va1);\r\n        const i2 = getOrCreateVertex(v2, vn2, smoothingGroup, va2);\r\n\r\n        if (i0 === i1 || i1 === i2 || i2 === i0) {\r\n            return;\r\n        }\r\n\r\n        outputIndices.push(i0, i1, i2);\r\n        outputTriangleMaterialIndices.push(materialIndex);\r\n    };\r\n\r\n    const addFacePolygon = (polygon: BevelPolygonPoint[], normal: Vector3, smoothingGroup: string, useFlatNormals: boolean) => {\r\n        const center = new Vector3();\r\n        const centerAttributes = _AverageAttributes(\r\n            polygon.map((point) => point.attributes),\r\n            attributeLength\r\n        );\r\n        const materialIndex = polygon[0]?.materialIndex ?? 0;\r\n        const centerNormal = useFlatNormals\r\n            ? normal\r\n            : _NormalizeNormalOrFallback(\r\n                  polygon.reduce((accumulator, point) => accumulator.addInPlace(point.normal), new Vector3()),\r\n                  normal\r\n              );\r\n\r\n        for (const point of polygon) {\r\n            center.addInPlace(point.position);\r\n        }\r\n        center.scaleInPlace(1 / polygon.length);\r\n\r\n        for (let index = 0; index < polygon.length; index++) {\r\n            const nextIndex = (index + 1) % polygon.length;\r\n            addTriangle(\r\n                center,\r\n                polygon[index].position,\r\n                polygon[nextIndex].position,\r\n                normal,\r\n                centerNormal,\r\n                useFlatNormals ? normal : polygon[index].normal,\r\n                useFlatNormals ? normal : polygon[nextIndex].normal,\r\n                smoothingGroup,\r\n                centerAttributes,\r\n                polygon[index].attributes,\r\n                polygon[nextIndex].attributes,\r\n                materialIndex\r\n            );\r\n        }\r\n    };\r\n\r\n    for (let faceIndex = 0; faceIndex < topology.faces.length; faceIndex++) {\r\n        const face = topology.faces[faceIndex];\r\n        const isFlat = _IsFlatFace(face);\r\n        let polygon = face.indices.map((index, cornerIndex) => ({\r\n            position: topology.positions[index].clone(),\r\n            normal: face.cornerNormals[cornerIndex].clone(),\r\n            attributes: _GetVertexAttributes(attributeDescriptors, face.originalIndices[cornerIndex]),\r\n            materialIndex: face.materialIndex,\r\n        }));\r\n        const selectedFaceEdges: BevelFaceClipEdge[] = [];\r\n\r\n        for (let edgeIndex = 0; edgeIndex < 3; edgeIndex++) {\r\n            const start = face.indices[edgeIndex];\r\n            const end = face.indices[(edgeIndex + 1) % 3];\r\n            const key = _EdgeKey(start, end);\r\n\r\n            if (!selectedEdges.has(key)) {\r\n                continue;\r\n            }\r\n\r\n            const edgeStart = topology.positions[start];\r\n            const edgeEnd = topology.positions[end];\r\n            const edgeDirection = edgeEnd.subtract(edgeStart).normalize();\r\n            const inward = Vector3.Cross(face.normal, edgeDirection).normalize();\r\n            selectedFaceEdges.push({ key, start, end, inward });\r\n        }\r\n\r\n        const clipEdges = faceClipEdges.get(faceIndex) ?? selectedFaceEdges;\r\n\r\n        for (const clipEdge of clipEdges) {\r\n            polygon = _ClipPolygonAgainstEdge(polygon, topology.positions[clipEdge.start], clipEdge.inward, bevelAmount);\r\n        }\r\n\r\n        if (isFlat) {\r\n            for (const point of polygon) {\r\n                point.normal = face.normal.clone();\r\n            }\r\n        }\r\n\r\n        preparedFaces.push({ faceIndex, polygon, selectedFaceEdges, isFlat });\r\n\r\n        for (const selectedFaceEdge of selectedFaceEdges) {\r\n            const edge = topology.edges.get(selectedFaceEdge.key)!;\r\n            const edgeStart = topology.positions[edge.v0];\r\n            const edgeEnd = topology.positions[edge.v1];\r\n            const axis = edgeEnd.subtract(edgeStart);\r\n            const edgeLength = axis.length();\r\n\r\n            if (edgeLength < PositionEpsilon) {\r\n                continue;\r\n            }\r\n\r\n            axis.normalize();\r\n\r\n            const pointsOnLine: Array<{ point: BevelPolygonPoint; t: number }> = [];\r\n            const orientedEdgeStart = topology.positions[selectedFaceEdge.start];\r\n\r\n            for (const point of polygon) {\r\n                const distance = Vector3.Dot(point.position.subtract(orientedEdgeStart), selectedFaceEdge.inward);\r\n\r\n                if (Math.abs(distance - bevelAmount) < PositionEpsilon * 10) {\r\n                    const t = Vector3.Dot(point.position.subtract(edgeStart), axis);\r\n                    if (t >= -PositionEpsilon && t <= edgeLength + PositionEpsilon) {\r\n                        pointsOnLine.push({ point, t: Math.min(edgeLength, Math.max(0, t)) });\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (pointsOnLine.length < 2) {\r\n                continue;\r\n            }\r\n\r\n            pointsOnLine.sort((a, b) => a.t - b.t);\r\n\r\n            const minPoint = pointsOnLine[0].point.position;\r\n            const maxPoint = pointsOnLine[pointsOnLine.length - 1].point.position;\r\n            const minNormal = pointsOnLine[0].point.normal;\r\n            const maxNormal = pointsOnLine[pointsOnLine.length - 1].point.normal;\r\n            const minAttributes = pointsOnLine[0].point.attributes;\r\n            const maxAttributes = pointsOnLine[pointsOnLine.length - 1].point.attributes;\r\n            const segment: BevelFaceEdgeSegment = {\r\n                edgeKey: selectedFaceEdge.key,\r\n                faceIndex,\r\n                inward: selectedFaceEdge.inward,\r\n                tMin: pointsOnLine[0].t,\r\n                tMax: pointsOnLine[pointsOnLine.length - 1].t,\r\n                minPoint,\r\n                maxPoint,\r\n                minNormal,\r\n                maxNormal,\r\n                minAttributes,\r\n                maxAttributes,\r\n                materialIndex: face.materialIndex,\r\n            };\r\n\r\n            faceEdgeSegments.set(`${faceIndex}|${selectedFaceEdge.key}`, segment);\r\n            addCapPoint(edge.v0, minPoint, pointsOnLine[0].point.normal, minAttributes, face.materialIndex);\r\n            addCapPoint(edge.v1, maxPoint, pointsOnLine[pointsOnLine.length - 1].point.normal, maxAttributes, face.materialIndex);\r\n        }\r\n    }\r\n\r\n    for (const edgeKey of Array.from(selectedEdges)) {\r\n        const edge = topology.edges.get(edgeKey)!;\r\n        const face0 = edge.faces[0].faceIndex;\r\n        const face1 = edge.faces[1].faceIndex;\r\n        const segment0 = faceEdgeSegments.get(`${face0}|${edgeKey}`);\r\n        const segment1 = faceEdgeSegments.get(`${face1}|${edgeKey}`);\r\n\r\n        if (!segment0 || !segment1) {\r\n            continue;\r\n        }\r\n\r\n        const edgeStart = topology.positions[edge.v0];\r\n        const edgeEnd = topology.positions[edge.v1];\r\n        const axis = edgeEnd.subtract(edgeStart);\r\n        const edgeLength = axis.length();\r\n\r\n        if (edgeLength < PositionEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        axis.normalize();\r\n\r\n        const tStart = Math.max(segment0.tMin, segment1.tMin);\r\n        const tEnd = Math.min(segment0.tMax, segment1.tMax);\r\n\r\n        if (tEnd - tStart <= PositionEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        edgeIntervals.set(edgeKey, { tStart, tEnd });\r\n    }\r\n\r\n    for (const preparedFace of preparedFaces) {\r\n        for (const selectedFaceEdge of preparedFace.selectedFaceEdges) {\r\n            const edge = topology.edges.get(selectedFaceEdge.key)!;\r\n            const interval = edgeIntervals.get(selectedFaceEdge.key);\r\n            const segment = faceEdgeSegments.get(`${preparedFace.faceIndex}|${selectedFaceEdge.key}`);\r\n\r\n            if (!interval || !segment) {\r\n                continue;\r\n            }\r\n\r\n            const edgeStart = topology.positions[edge.v0];\r\n            const edgeEnd = topology.positions[edge.v1];\r\n            const axis = edgeEnd.subtract(edgeStart);\r\n            const edgeLength = axis.length();\r\n\r\n            if (edgeLength < PositionEpsilon) {\r\n                continue;\r\n            }\r\n\r\n            axis.normalize();\r\n\r\n            for (const t of [interval.tStart, interval.tEnd]) {\r\n                if (t <= segment.tMin + PositionEpsilon || t >= segment.tMax - PositionEpsilon) {\r\n                    continue;\r\n                }\r\n\r\n                _InsertPointOnPolygonBoundary(preparedFace.polygon, edgeStart.add(axis.scale(t)).addInPlace(segment.inward.scale(bevelAmount)));\r\n            }\r\n        }\r\n    }\r\n\r\n    const emittedMergedFaces = new Set<number>();\r\n    const preparedFacesByPlane = new Map<string, BevelPreparedFace[]>();\r\n\r\n    for (const preparedFace of preparedFaces) {\r\n        if (!preparedFace.selectedFaceEdges.length || !preparedFace.isFlat) {\r\n            continue;\r\n        }\r\n\r\n        const face = topology.faces[preparedFace.faceIndex];\r\n        const distance = Vector3.Dot(topology.positions[face.indices[0]], face.normal);\r\n        const planeKey = `${_PositionKey(face.normal.x, face.normal.y, face.normal.z)}:${_Quantize(distance)}`;\r\n        let group = preparedFacesByPlane.get(planeKey);\r\n\r\n        if (!group) {\r\n            group = [];\r\n            preparedFacesByPlane.set(planeKey, group);\r\n        }\r\n\r\n        group.push(preparedFace);\r\n    }\r\n\r\n    for (const group of Array.from(preparedFacesByPlane.values())) {\r\n        if (group.length < 2) {\r\n            continue;\r\n        }\r\n\r\n        const mergedPolygon = _BuildMergedBoundaryPolygon(group.map((preparedFace) => preparedFace.polygon));\r\n\r\n        if (!mergedPolygon || mergedPolygon.length < 3) {\r\n            continue;\r\n        }\r\n\r\n        const face = topology.faces[group[0].faceIndex];\r\n        addFacePolygon(mergedPolygon, face.normal, `face-flat:${_PositionKey(face.normal.x, face.normal.y, face.normal.z)}`, true);\r\n\r\n        for (const preparedFace of group) {\r\n            emittedMergedFaces.add(preparedFace.faceIndex);\r\n        }\r\n    }\r\n\r\n    for (const preparedFace of preparedFaces) {\r\n        if (emittedMergedFaces.has(preparedFace.faceIndex)) {\r\n            continue;\r\n        }\r\n\r\n        const face = topology.faces[preparedFace.faceIndex];\r\n        const smoothingGroup = preparedFace.selectedFaceEdges.length && !preparedFace.isFlat ? \"smooth\" : `face-flat:${_PositionKey(face.normal.x, face.normal.y, face.normal.z)}`;\r\n\r\n        if (preparedFace.polygon.length >= 3) {\r\n            if (smoothingGroup === \"smooth\") {\r\n                addFacePolygon(preparedFace.polygon, face.normal, smoothingGroup, false);\r\n            } else {\r\n                for (let index = 1; index < preparedFace.polygon.length - 1; index++) {\r\n                    addTriangle(\r\n                        preparedFace.polygon[0].position,\r\n                        preparedFace.polygon[index].position,\r\n                        preparedFace.polygon[index + 1].position,\r\n                        face.normal,\r\n                        face.normal,\r\n                        face.normal,\r\n                        face.normal,\r\n                        smoothingGroup,\r\n                        preparedFace.polygon[0].attributes,\r\n                        preparedFace.polygon[index].attributes,\r\n                        preparedFace.polygon[index + 1].attributes,\r\n                        face.materialIndex\r\n                    );\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    for (const edgeKey of Array.from(selectedEdges)) {\r\n        const edge = topology.edges.get(edgeKey)!;\r\n        const face0 = edge.faces[0].faceIndex;\r\n        const face1 = edge.faces[1].faceIndex;\r\n        const segment0 = faceEdgeSegments.get(`${face0}|${edgeKey}`);\r\n        const segment1 = faceEdgeSegments.get(`${face1}|${edgeKey}`);\r\n        const interval = edgeIntervals.get(edgeKey);\r\n\r\n        if (!segment0 || !segment1 || !interval) {\r\n            continue;\r\n        }\r\n\r\n        const edgeStart = topology.positions[edge.v0];\r\n        const edgeEnd = topology.positions[edge.v1];\r\n        const axis = edgeEnd.subtract(edgeStart);\r\n        const edgeLength = axis.length();\r\n\r\n        if (edgeLength < PositionEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        axis.normalize();\r\n\r\n        const { tStart, tEnd } = interval;\r\n        const faceNormal0 = topology.faces[segment0.faceIndex].normal;\r\n        const faceNormal1 = topology.faces[segment1.faceIndex].normal;\r\n        const segment0Start = _InterpolateSegmentPoint(segment0, tStart);\r\n        const segment1Start = _InterpolateSegmentPoint(segment1, tStart);\r\n        const segment0End = _InterpolateSegmentPoint(segment0, tEnd);\r\n        const segment1End = _InterpolateSegmentPoint(segment1, tEnd);\r\n        const segment0StartNormal = _InterpolateSegmentNormal(segment0, tStart);\r\n        const segment1StartNormal = _InterpolateSegmentNormal(segment1, tStart);\r\n        const segment0EndNormal = _InterpolateSegmentNormal(segment0, tEnd);\r\n        const segment1EndNormal = _InterpolateSegmentNormal(segment1, tEnd);\r\n        const segment0StartAttributes = _InterpolateSegmentAttributes(segment0, tStart);\r\n        const segment1StartAttributes = _InterpolateSegmentAttributes(segment1, tStart);\r\n        const segment0EndAttributes = _InterpolateSegmentAttributes(segment0, tEnd);\r\n        const segment1EndAttributes = _InterpolateSegmentAttributes(segment1, tEnd);\r\n        const centerStart = segment0Start\r\n            .subtract(faceNormal0.scale(bevelAmount))\r\n            .addInPlace(segment1Start.subtract(faceNormal1.scale(bevelAmount)))\r\n            .scaleInPlace(0.5);\r\n        const centerEnd = segment0End\r\n            .subtract(faceNormal0.scale(bevelAmount))\r\n            .addInPlace(segment1End.subtract(faceNormal1.scale(bevelAmount)))\r\n            .scaleInPlace(0.5);\r\n        const startProfilePoints: Vector3[] = [];\r\n        const endProfilePoints: Vector3[] = [];\r\n        const startProfileNormals: Vector3[] = [];\r\n        const endProfileNormals: Vector3[] = [];\r\n        const startProfileAttributes: number[][] = [];\r\n        const endProfileAttributes: number[][] = [];\r\n\r\n        for (let segmentIndex = 0; segmentIndex <= segments; segmentIndex++) {\r\n            const profileAmount = segmentIndex / segments;\r\n            const profileNormal = _SlerpDirections(faceNormal0, faceNormal1, profileAmount);\r\n            const startNormal = _SlerpDirections(segment0StartNormal, segment1StartNormal, profileAmount);\r\n            const endNormal = _SlerpDirections(segment0EndNormal, segment1EndNormal, profileAmount);\r\n            const startAttributes = _InterpolateAttributes(segment0StartAttributes, segment1StartAttributes, profileAmount);\r\n            const endAttributes = _InterpolateAttributes(segment0EndAttributes, segment1EndAttributes, profileAmount);\r\n            let startPoint = centerStart.add(profileNormal.scale(bevelAmount));\r\n            let endPoint = centerEnd.add(profileNormal.scale(bevelAmount));\r\n\r\n            if (segmentIndex === 0) {\r\n                startPoint = segment0Start;\r\n                endPoint = segment0End;\r\n            } else if (segmentIndex === segments) {\r\n                startPoint = segment1Start;\r\n                endPoint = segment1End;\r\n            }\r\n\r\n            startProfilePoints.push(startPoint);\r\n            endProfilePoints.push(endPoint);\r\n            startProfileNormals.push(startNormal);\r\n            endProfileNormals.push(endNormal);\r\n            startProfileAttributes.push(startAttributes);\r\n            endProfileAttributes.push(endAttributes);\r\n            addCapPoint(edge.v0, startPoint, startNormal, startAttributes, segment0.materialIndex);\r\n            addCapPoint(edge.v1, endPoint, endNormal, endAttributes, segment0.materialIndex);\r\n        }\r\n\r\n        for (let segmentIndex = 0; segmentIndex < segments; segmentIndex++) {\r\n            const normalTarget = _SlerpDirections(faceNormal0, faceNormal1, (segmentIndex + 0.5) / segments);\r\n\r\n            addTriangle(\r\n                startProfilePoints[segmentIndex],\r\n                endProfilePoints[segmentIndex],\r\n                endProfilePoints[segmentIndex + 1],\r\n                normalTarget,\r\n                startProfileNormals[segmentIndex],\r\n                endProfileNormals[segmentIndex],\r\n                endProfileNormals[segmentIndex + 1],\r\n                \"smooth\",\r\n                startProfileAttributes[segmentIndex],\r\n                endProfileAttributes[segmentIndex],\r\n                endProfileAttributes[segmentIndex + 1],\r\n                segment0.materialIndex\r\n            );\r\n            addTriangle(\r\n                startProfilePoints[segmentIndex],\r\n                endProfilePoints[segmentIndex + 1],\r\n                startProfilePoints[segmentIndex + 1],\r\n                normalTarget,\r\n                startProfileNormals[segmentIndex],\r\n                endProfileNormals[segmentIndex + 1],\r\n                startProfileNormals[segmentIndex + 1],\r\n                \"smooth\",\r\n                startProfileAttributes[segmentIndex],\r\n                endProfileAttributes[segmentIndex + 1],\r\n                startProfileAttributes[segmentIndex + 1],\r\n                segment0.materialIndex\r\n            );\r\n        }\r\n    }\r\n\r\n    const addSphericalCornerPatch = (vertexIndex: number) => {\r\n        if ((selectedEdgeCountPerVertex.get(vertexIndex) ?? 0) < 3) {\r\n            return false;\r\n        }\r\n\r\n        const incidentNormals: Vector3[] = [];\r\n        const vertexPosition = topology.positions[vertexIndex];\r\n        const cornerCapPoints = capPoints.get(vertexIndex) ?? [];\r\n        const cornerAttributes = _AverageAttributes(\r\n            cornerCapPoints.map((point) => _GetCapPointAttributes(point)),\r\n            attributeLength\r\n        );\r\n        const materialIndex = cornerCapPoints.length ? _GetCapPointMaterialIndex(cornerCapPoints[0]) : 0;\r\n\r\n        for (const edgeKey of Array.from(selectedEdges)) {\r\n            const edge = topology.edges.get(edgeKey)!;\r\n\r\n            if (edge.v0 !== vertexIndex && edge.v1 !== vertexIndex) {\r\n                continue;\r\n            }\r\n\r\n            for (const edgeFace of edge.faces) {\r\n                _AddUniqueNormal(incidentNormals, topology.faces[edgeFace.faceIndex].normal);\r\n            }\r\n        }\r\n\r\n        if (incidentNormals.length !== 3) {\r\n            return false;\r\n        }\r\n\r\n        const averageNormal = incidentNormals[0].add(incidentNormals[1]).addInPlace(incidentNormals[2]).normalize();\r\n        const tangent = incidentNormals[0].subtract(averageNormal.scale(Vector3.Dot(incidentNormals[0], averageNormal))).normalize();\r\n        const bitangent = Vector3.Cross(averageNormal, tangent).normalize();\r\n        incidentNormals.sort((a, b) => Math.atan2(Vector3.Dot(a, bitangent), Vector3.Dot(a, tangent)) - Math.atan2(Vector3.Dot(b, bitangent), Vector3.Dot(b, tangent)));\r\n\r\n        const distances = incidentNormals.map((normal) => Vector3.Dot(vertexPosition, normal) - bevelAmount);\r\n        const center = _SolveThreePlaneIntersection(incidentNormals, distances);\r\n\r\n        if (!center) {\r\n            return false;\r\n        }\r\n\r\n        const rows: BevelPolygonPoint[][] = [];\r\n        for (let rowIndex = 0; rowIndex <= segments; rowIndex++) {\r\n            const rowAmount = rowIndex / segments;\r\n            const left = _SlerpDirections(incidentNormals[0], incidentNormals[1], rowAmount);\r\n            const right = _SlerpDirections(incidentNormals[0], incidentNormals[2], rowAmount);\r\n            const row: BevelPolygonPoint[] = [];\r\n\r\n            for (let columnIndex = 0; columnIndex <= rowIndex; columnIndex++) {\r\n                const columnAmount = rowIndex === 0 ? 0 : columnIndex / rowIndex;\r\n                const direction = rowIndex === 0 ? incidentNormals[0].clone() : _SlerpDirections(left, right, columnAmount);\r\n                row.push({\r\n                    position: center.add(direction.scale(bevelAmount)),\r\n                    normal: direction,\r\n                    attributes: cornerAttributes,\r\n                    materialIndex,\r\n                });\r\n            }\r\n\r\n            rows.push(row);\r\n        }\r\n\r\n        for (let rowIndex = 0; rowIndex < segments; rowIndex++) {\r\n            const row = rows[rowIndex];\r\n            const nextRow = rows[rowIndex + 1];\r\n\r\n            for (let columnIndex = 0; columnIndex < row.length; columnIndex++) {\r\n                const targetNormal0 = row[columnIndex].position.subtract(center).normalize();\r\n                const targetNormal1 = nextRow[columnIndex].position.subtract(center).normalize();\r\n                const targetNormal2 = nextRow[columnIndex + 1].position.subtract(center).normalize();\r\n                const targetNormal = targetNormal0.addInPlace(targetNormal1).addInPlace(targetNormal2).normalize();\r\n\r\n                addTriangle(\r\n                    row[columnIndex].position,\r\n                    nextRow[columnIndex].position,\r\n                    nextRow[columnIndex + 1].position,\r\n                    targetNormal,\r\n                    targetNormal0,\r\n                    targetNormal1,\r\n                    targetNormal2,\r\n                    \"smooth\",\r\n                    row[columnIndex].attributes,\r\n                    nextRow[columnIndex].attributes,\r\n                    nextRow[columnIndex + 1].attributes,\r\n                    materialIndex\r\n                );\r\n\r\n                if (columnIndex < row.length - 1) {\r\n                    const secondTargetNormal0 = row[columnIndex].position.subtract(center).normalize();\r\n                    const secondTargetNormal1 = nextRow[columnIndex + 1].position.subtract(center).normalize();\r\n                    const secondTargetNormal2 = row[columnIndex + 1].position.subtract(center).normalize();\r\n                    const secondTargetNormal = secondTargetNormal0.add(secondTargetNormal1).addInPlace(secondTargetNormal2).normalize();\r\n\r\n                    addTriangle(\r\n                        row[columnIndex].position,\r\n                        nextRow[columnIndex + 1].position,\r\n                        row[columnIndex + 1].position,\r\n                        secondTargetNormal,\r\n                        secondTargetNormal0,\r\n                        secondTargetNormal1,\r\n                        secondTargetNormal2,\r\n                        \"smooth\",\r\n                        row[columnIndex].attributes,\r\n                        nextRow[columnIndex + 1].attributes,\r\n                        row[columnIndex + 1].attributes,\r\n                        materialIndex\r\n                    );\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    };\r\n\r\n    const verticesWithSphericalPatch = new Set<number>();\r\n    for (const vertexIndex of Array.from(selectedVertices)) {\r\n        if (addSphericalCornerPatch(vertexIndex)) {\r\n            verticesWithSphericalPatch.add(vertexIndex);\r\n        }\r\n    }\r\n\r\n    for (const [vertexIndex, points] of Array.from(capPoints)) {\r\n        if (points.length < 3) {\r\n            continue;\r\n        }\r\n\r\n        if (verticesWithSphericalPatch.has(vertexIndex)) {\r\n            continue;\r\n        }\r\n\r\n        const center = new Vector3();\r\n        for (const point of points) {\r\n            center.addInPlace(_GetCapPointPosition(point));\r\n        }\r\n        center.scaleInPlace(1 / points.length);\r\n\r\n        let normal = new Vector3();\r\n        const incidentFaces = topology.vertexFaces.get(vertexIndex) || [];\r\n        for (const faceIndex of incidentFaces) {\r\n            normal.addInPlace(topology.faces[faceIndex].normal);\r\n        }\r\n\r\n        if (normal.lengthSquared() < NormalEpsilon) {\r\n            normal = topology.positions[vertexIndex].subtract(center);\r\n        }\r\n\r\n        if (normal.lengthSquared() < NormalEpsilon) {\r\n            continue;\r\n        }\r\n\r\n        normal.normalize();\r\n\r\n        const reference = Math.abs(normal.y) < 0.9 ? Vector3.Up() : Vector3.Right();\r\n        const tangent = Vector3.Cross(reference, normal).normalize();\r\n        const bitangent = Vector3.Cross(normal, tangent).normalize();\r\n        const sortedPoints = points.slice().sort((a, b) => {\r\n            const da = _GetCapPointPosition(a).subtract(center);\r\n            const db = _GetCapPointPosition(b).subtract(center);\r\n            const angleA = Math.atan2(Vector3.Dot(da, bitangent), Vector3.Dot(da, tangent));\r\n            const angleB = Math.atan2(Vector3.Dot(db, bitangent), Vector3.Dot(db, tangent));\r\n            return angleA - angleB;\r\n        });\r\n\r\n        if ((selectedEdgeCountPerVertex.get(vertexIndex) ?? 0) === 2) {\r\n            const polygonPoints = sortedPoints.map((point) => ({\r\n                position: _GetCapPointPosition(point),\r\n                normal: _GetCapPointNormal(point, normal),\r\n                attributes: _GetCapPointAttributes(point),\r\n                materialIndex: _GetCapPointMaterialIndex(point),\r\n            }));\r\n            const addPatchTriangle = (point0: BevelPolygonPoint, point1: BevelPolygonPoint, point2: BevelPolygonPoint) => {\r\n                const targetNormal = _NormalizeNormalOrFallback(point0.normal.add(point1.normal).addInPlace(point2.normal), normal);\r\n                addTriangle(\r\n                    point0.position,\r\n                    point1.position,\r\n                    point2.position,\r\n                    targetNormal,\r\n                    point0.normal,\r\n                    point1.normal,\r\n                    point2.normal,\r\n                    \"smooth\",\r\n                    point0.attributes,\r\n                    point1.attributes,\r\n                    point2.attributes,\r\n                    point0.materialIndex\r\n                );\r\n            };\r\n\r\n            while (polygonPoints.length > 3) {\r\n                let bestIndex = -1;\r\n                let bestScore = Number.MAX_VALUE;\r\n\r\n                for (let index = 0; index < polygonPoints.length; index++) {\r\n                    const previous = polygonPoints[(index + polygonPoints.length - 1) % polygonPoints.length];\r\n                    const current = polygonPoints[index];\r\n                    const next = polygonPoints[(index + 1) % polygonPoints.length];\r\n                    const edge0 = current.position.subtract(previous.position);\r\n                    const edge1 = next.position.subtract(previous.position);\r\n                    const triangleNormal = Vector3.Cross(edge0, edge1);\r\n\r\n                    if (triangleNormal.lengthSquared() < TriangleAreaEpsilon) {\r\n                        continue;\r\n                    }\r\n\r\n                    const score = previous.position.subtract(next.position).lengthSquared();\r\n                    if (score < bestScore) {\r\n                        bestScore = score;\r\n                        bestIndex = index;\r\n                    }\r\n                }\r\n\r\n                if (bestIndex === -1) {\r\n                    break;\r\n                }\r\n\r\n                addPatchTriangle(\r\n                    polygonPoints[(bestIndex + polygonPoints.length - 1) % polygonPoints.length],\r\n                    polygonPoints[bestIndex],\r\n                    polygonPoints[(bestIndex + 1) % polygonPoints.length]\r\n                );\r\n                polygonPoints.splice(bestIndex, 1);\r\n            }\r\n\r\n            if (polygonPoints.length === 3) {\r\n                addPatchTriangle(polygonPoints[0], polygonPoints[1], polygonPoints[2]);\r\n            }\r\n\r\n            continue;\r\n        }\r\n\r\n        const centerAttributes = _AverageAttributes(\r\n            sortedPoints.map((point) => _GetCapPointAttributes(point)),\r\n            attributeLength\r\n        );\r\n        const centerMaterialIndex = sortedPoints.length ? _GetCapPointMaterialIndex(sortedPoints[0]) : 0;\r\n        for (let index = 0; index < sortedPoints.length; index++) {\r\n            const point0 = sortedPoints[index];\r\n            const point1 = sortedPoints[(index + 1) % sortedPoints.length];\r\n            const point0Position = _GetCapPointPosition(point0);\r\n            const point1Position = _GetCapPointPosition(point1);\r\n\r\n            addTriangle(\r\n                center,\r\n                point0Position,\r\n                point1Position,\r\n                normal,\r\n                normal,\r\n                _GetCapPointNormal(point0, normal),\r\n                _GetCapPointNormal(point1, normal),\r\n                \"smooth\",\r\n                centerAttributes,\r\n                _GetCapPointAttributes(point0),\r\n                _GetCapPointAttributes(point1),\r\n                centerMaterialIndex\r\n            );\r\n        }\r\n    }\r\n\r\n    if (!outputPositions.length || !outputIndices.length) {\r\n        return _CloneVertexData(vertexData);\r\n    }\r\n\r\n    const result = new VertexData();\r\n    result.positions = outputPositions;\r\n    result.normals = [];\r\n\r\n    for (let index = 0; index < outputNormals.length; index++) {\r\n        const normal = outputNormals[index];\r\n        normal.normalize();\r\n\r\n        result.normals.push(normal.x, normal.y, normal.z);\r\n    }\r\n\r\n    _AssignAttributeOutputs(result, attributeDescriptors, outputVertexAttributes);\r\n\r\n    const materialResult = _BuildMaterialInfoResult(vertexData, outputIndices, outputTriangleMaterialIndices, outputPositions.length / 3);\r\n    result.indices = materialResult.indices;\r\n    result.materialInfos = materialResult.materialInfos;\r\n\r\n    return result;\r\n}\r\n\r\n/**\r\n * Block used to bevel sharp edges in a geometry.\r\n */\r\nexport class BevelBlock extends NodeGeometryBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating that this block can evaluate context.\r\n     * Build performance is improved when this value is set to false as the system will cache values instead of reevaluating everything per context change.\r\n     */\r\n    @editableInPropertyPage(\"Evaluate context\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public evaluateContext = false;\r\n\r\n    /**\r\n     * Creates a new BevelBlock.\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"geometry\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n        this.registerInput(\"amount\", NodeGeometryBlockConnectionPointTypes.Float, true, 0.1, 0, 1);\r\n        this.registerInput(\"segments\", NodeGeometryBlockConnectionPointTypes.Int, true, 1, 1, 64);\r\n        this.registerInput(\"angle\", NodeGeometryBlockConnectionPointTypes.Float, true, 30, 0, 180);\r\n        this.registerOutput(\"output\", NodeGeometryBlockConnectionPointTypes.Geometry);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name.\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BevelBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry input component.\r\n     */\r\n    public get geometry(): NodeGeometryConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the bevel amount input component.\r\n     */\r\n    public get amount(): NodeGeometryConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the bevel segment count input component.\r\n     */\r\n    public get segments(): NodeGeometryConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the angle threshold input component in degrees.\r\n     */\r\n    public get angle(): NodeGeometryConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component.\r\n     */\r\n    public get output(): NodeGeometryConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    protected override _buildBlock(state: NodeGeometryBuildState) {\r\n        const func = (state: NodeGeometryBuildState) => {\r\n            const source = this.geometry.getConnectedValue(state) as VertexData;\r\n\r\n            if (!source || !source.positions) {\r\n                return null;\r\n            }\r\n\r\n            const amount = Math.min(1, Math.max(0, this.amount.getConnectedValue(state) ?? 0.1));\r\n            const segments = Math.min(64, Math.max(1, Math.floor(this.segments.getConnectedValue(state) ?? 1)));\r\n            const angleDegrees = Math.max(0, Math.min(180, this.angle.getConnectedValue(state) ?? 30));\r\n            const angle = (angleDegrees * Math.PI) / 180;\r\n\r\n            return _BevelVertexData(source, amount, segments, angle);\r\n        };\r\n\r\n        if (this.evaluateContext) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    protected override _dumpPropertiesCode() {\r\n        return super._dumpPropertiesCode() + `${this._codeVariableName}.evaluateContext = ${this.evaluateContext ? \"true\" : \"false\"};\\n`;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation.\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.evaluateContext = this.evaluateContext;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.evaluateContext !== undefined) {\r\n            this.evaluateContext = serializationObject.evaluateContext;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for bevelBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBevelBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BevelBlock\", BevelBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * Message commands exchanged with the Gaussian Splatting depth-sort worker. Every message carries a\r\n * `command` field naming the intended work, instead of inferring it from which payload is present.\r\n */\r\nexport const GaussianSplattingSortWorkerCommand = {\r\n    /** Main -> worker: set the source splat centers (stride 4: xyz + 1). */\r\n    POSITIONS: \"positions\",\r\n    /** Main -> worker: patch a contiguous sub-range of the existing source splat centers in place. */\r\n    POSITIONS_UPDATE: \"positionsUpdate\",\r\n    /** Main -> worker: set the compound-mesh rig node matrices. */\r\n    PART_MATRICES: \"partMatrices\",\r\n    /** Main -> worker: set the compound-mesh per-splat rig node indices. */\r\n    PART_INDICES: \"partIndices\",\r\n    /** Main -> worker: set the active source-splat ranges (flat [start0, count0, ...]). */\r\n    INTERVALS: \"intervals\",\r\n    /** Main -> worker: sort the active splats for a camera view. */\r\n    SORT: \"sort\",\r\n    /** Worker -> main: a completed sort result. */\r\n    SORTED: \"sorted\",\r\n} as const;\r\n\r\n/**\r\n * Depth-sort web worker body for Gaussian Splatting meshes.\r\n *\r\n * The function is self-contained: it is serialized with `Function.prototype.toString()` and run\r\n * inside a `Blob`-backed `Worker`, so it must not reference anything from its enclosing module\r\n * (including {@link GaussianSplattingSortWorkerCommand} — the command literals are duplicated here).\r\n *\r\n * The intended work for each message is selected explicitly via its `command` field:\r\n * - `positions`    set source splat centers (stride 4: xyz + 1).\r\n * - `partMatrices` set compound-mesh rig node matrices.\r\n * - `partIndices`  set compound-mesh per-splat rig node indices.\r\n * - `intervals`    set active source-splat ranges (flat [start0, count0, ...]); persisted across sorts.\r\n * - `sort`         sort the active splats for `{ worldMatrix, cameraForward, cameraPosition, depthMix,\r\n *                  cameraId, sortRequestId, rightHanded }` and post back a `sorted` result.\r\n *\r\n * @param self - the worker global scope\r\n */\r\nexport const GaussianSplattingSortWorker = function (self: Worker) {\r\n    let positions: Float32Array;\r\n    // Real (unpadded) splat count backing `positions` — see emptySplatIndex below for why this matters.\r\n    let vertexCount = 0;\r\n    let depthMix: BigInt64Array;\r\n    let partIndices: Uint8Array;\r\n    let partMatrices: Float32Array[];\r\n    // Active source-splat intervals as flat [start0, count0, start1, count1, ...]. Persisted between\r\n    // sort requests and refreshed by the main thread via the `intervals` message.\r\n    let intervals: Nullable<Uint32Array> = null;\r\n    // Reusable counting-sort scratch buffers (grown on demand, never per-sort allocations).\r\n    let sortSourceIndices: Uint32Array; // active source splat index for each compact slot\r\n    let sortDepths: Float32Array; // view-space depth for each compact slot\r\n    let sortKeys: Uint32Array; // depth-derived integer bucket key for each compact slot\r\n    let sortCounts: Uint32Array; // counting-sort histogram (one entry per bucket)\r\n\r\n    self.onmessage = (e: any) => {\r\n        // The intended work is selected explicitly via the message `command` field. These string\r\n        // literals must match GaussianSplattingSortWorkerCommand above (this body is serialized in\r\n        // isolation and cannot reference the shared constant).\r\n        const command = e.data.command;\r\n        if (command === \"positions\") {\r\n            positions = e.data.positions;\r\n            vertexCount = e.data.vertexCount;\r\n        } else if (command === \"positionsUpdate\") {\r\n            // Patch only the changed sub-range in place, avoiding a full re-copy/transfer of the entire\r\n            // (potentially hundreds-of-MB) position buffer on every streamed LOD decode.\r\n            if (positions && e.data.data) {\r\n                positions.set(e.data.data, e.data.offset);\r\n            }\r\n        } else if (command === \"partMatrices\") {\r\n            partMatrices = e.data.partMatrices;\r\n        } else if (command === \"partIndices\") {\r\n            partIndices = e.data.partIndices;\r\n        } else if (command === \"intervals\") {\r\n            intervals = e.data.intervals;\r\n        } else if (command === \"sort\") {\r\n            const cameraId = e.data.cameraId;\r\n            const sortRequestId = e.data.sortRequestId;\r\n            const rangeVersion = e.data.rangeVersion;\r\n            const globalWorldMatrix = e.data.worldMatrix;\r\n            const cameraForward = e.data.cameraForward;\r\n            const cameraPosition = e.data.cameraPosition;\r\n\r\n            depthMix = e.data.depthMix;\r\n\r\n            if (!positions || !cameraForward) {\r\n                // Sort request arrived before positions were initialized — return the buffer unchanged so the main thread can unlock _canPostToWorker.\r\n                self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n                return;\r\n            }\r\n\r\n            // Feature flags are forwarded by the main thread on each sort request (the worker body is\r\n            // serialized in isolation and cannot read shared statics directly). useCountingSort defaults to\r\n            // true; set it false to fall back to the legacy comparison sort.\r\n            const useCountingSort = e.data.useCountingSort !== false;\r\n            const logSortPerformance = !!e.data.logSortPerformance;\r\n\r\n            // `cameraForward` is the view matrix's third row [m[2], m[6], m[10]], which points into the scene\r\n            // in a left-handed scene but back toward the viewer in a right-handed one. As a result the signed\r\n            // `depth = dot(cameraForward, worldPos - cameraPos)` increases with distance in left-handed scenes\r\n            // but decreases with distance in right-handed ones. The counting sort below relies on \"larger depth\r\n            // = farther\", so negate the depth in right-handed scenes to keep that invariant and preserve correct\r\n            // back-to-front ordering. (The legacy comparison sort handles either sign naturally and is untouched.)\r\n            const depthSign = e.data.rightHanded ? -1 : 1;\r\n\r\n            // Resolve the active interval set. The main thread always sends an `intervals` message,\r\n            // but fall back to \"all source splats\" if a sort somehow arrives before it.\r\n            const activeIntervals = intervals;\r\n            const totalSplats = positions.length / 4;\r\n            // Index to use when 16-aligning the sorted output needs extra filler entries. Real data never\r\n            // lives at or past `vertexCount` — with or without range filtering — and `_getTextureSize`\r\n            // (gaussianSplattingMeshBase.pure.ts) always reserves at least one empty slot there, even when\r\n            // `vertexCount` would otherwise exactly fill every texture row.\r\n            const emptySplatIndex = vertexCount;\r\n            let renderSplatCount = totalSplats;\r\n            if (activeIntervals) {\r\n                renderSplatCount = 0;\r\n                for (let rangeIndex = 1; rangeIndex < activeIntervals.length; rangeIndex += 2) {\r\n                    renderSplatCount += activeIntervals[rangeIndex];\r\n                }\r\n            }\r\n            const vertexCountPadded = Math.max((renderSplatCount + 15) & ~0xf, 16);\r\n\r\n            // depth = dot(cameraForward, worldPos - cameraPos)\r\n            const camDot = cameraForward[0] * cameraPosition[0] + cameraForward[1] * cameraPosition[1] + cameraForward[2] * cameraPosition[2];\r\n\r\n            const computeDepthCoeffs = (m: Float32Array): number[] => {\r\n                return [\r\n                    cameraForward[0] * m[0] + cameraForward[1] * m[1] + cameraForward[2] * m[2],\r\n                    cameraForward[0] * m[4] + cameraForward[1] * m[5] + cameraForward[2] * m[6],\r\n                    cameraForward[0] * m[8] + cameraForward[1] * m[9] + cameraForward[2] * m[10],\r\n                    cameraForward[0] * m[12] + cameraForward[1] * m[13] + cameraForward[2] * m[14] - camDot,\r\n                ];\r\n            };\r\n\r\n            // Optional, flag-gated sort timing (a simple wall-clock delta logged to the worker console).\r\n            const perf = (globalThis as { performance?: { now(): number } }).performance;\r\n            const sortStart = logSortPerformance && perf ? perf.now() : 0;\r\n\r\n            try {\r\n                if (useCountingSort) {\r\n                    // ===== Fast O(n) counting (radix) sort =====\r\n                    // Output view: the even 32-bit words of the depthMix buffer hold the sorted source indices\r\n                    // (the main thread reads indexMix[2*j]); the odd words are left unused.\r\n                    const outIndices = new Uint32Array(depthMix.buffer);\r\n\r\n                    // Grow the reusable scratch buffers when the active count increases (kept across sorts).\r\n                    if (!sortSourceIndices || sortSourceIndices.length < renderSplatCount) {\r\n                        const capacity = Math.max(renderSplatCount, 16);\r\n                        sortSourceIndices = new Uint32Array(capacity);\r\n                        sortDepths = new Float32Array(capacity);\r\n                        sortKeys = new Uint32Array(capacity);\r\n                    }\r\n\r\n                    // Compound (rig) meshes give each splat its own world transform via its part: depth uses the\r\n                    // splat's part coefficients. Single meshes use the one global world matrix. Both produce\r\n                    // depths in the same camera-forward space, so all active splats sort together correctly.\r\n                    // Require a non-empty partIndices: an empty one (length 0) would make partLen-1 index -1 below.\r\n                    const compound = !!(partMatrices && partMatrices.length > 0 && partIndices && partIndices.length > 0);\r\n                    let depthCoeffs: number[][] = [];\r\n                    let partLen = 0;\r\n                    let a = 0;\r\n                    let b = 0;\r\n                    let c = 0;\r\n                    let d = 0;\r\n                    if (compound) {\r\n                        depthCoeffs = partMatrices.map((m) => {\r\n                            const co = computeDepthCoeffs(m);\r\n                            co[0] *= depthSign;\r\n                            co[1] *= depthSign;\r\n                            co[2] *= depthSign;\r\n                            co[3] *= depthSign;\r\n                            return co;\r\n                        });\r\n                        partLen = partIndices.length;\r\n                    } else {\r\n                        const coeff = computeDepthCoeffs(globalWorldMatrix);\r\n                        a = coeff[0] * depthSign;\r\n                        b = coeff[1] * depthSign;\r\n                        c = coeff[2] * depthSign;\r\n                        d = coeff[3] * depthSign;\r\n                    }\r\n\r\n                    // Pass 1: gather the active source indices, compute each splat's view-space depth (signed\r\n                    // distance from the camera along the forward axis), and track the depth range. The compound\r\n                    // branch is hoisted out of the inner loop so the hot path stays straight-line.\r\n                    let writeIndex = 0;\r\n                    let minDepth = Infinity;\r\n                    let maxDepth = -Infinity;\r\n                    // A partIndices entry >= partCount means partIndices and partMatrices disagree — an inconsistent\r\n                    // snapshot posted mid-rebuild.\r\n                    const partCount = depthCoeffs.length;\r\n                    let inconsistentSnapshot = false;\r\n                    const rangeWords = activeIntervals ? activeIntervals.length : 2;\r\n                    gather: for (let r = 0; r < rangeWords; r += 2) {\r\n                        const start = activeIntervals ? activeIntervals[r] : 0;\r\n                        const end = start + (activeIntervals ? activeIntervals[r + 1] : totalSplats);\r\n                        if (compound) {\r\n                            for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {\r\n                                const o = 4 * sourceIndex;\r\n                                const rawPart = partIndices[sourceIndex < partLen ? sourceIndex : partLen - 1];\r\n                                if (rawPart >= partCount) {\r\n                                    // Reject rather than sort with the wrong transform: the output buffer is untouched\r\n                                    // until the scatter pass below, so returning it as-is keeps the last good order and\r\n                                    // the next frame retries once the snapshot is consistent.\r\n                                    inconsistentSnapshot = true;\r\n                                    break gather;\r\n                                }\r\n                                const coeff = depthCoeffs[rawPart];\r\n                                const depth = coeff[0] * positions[o] + coeff[1] * positions[o + 1] + coeff[2] * positions[o + 2] + coeff[3];\r\n                                sortSourceIndices[writeIndex] = sourceIndex;\r\n                                sortDepths[writeIndex] = depth;\r\n                                writeIndex++;\r\n                                if (depth < minDepth) {\r\n                                    minDepth = depth;\r\n                                }\r\n                                if (depth > maxDepth) {\r\n                                    maxDepth = depth;\r\n                                }\r\n                            }\r\n                        } else {\r\n                            for (let sourceIndex = start; sourceIndex < end; sourceIndex++) {\r\n                                const o = 4 * sourceIndex;\r\n                                const depth = a * positions[o] + b * positions[o + 1] + c * positions[o + 2] + d;\r\n                                sortSourceIndices[writeIndex] = sourceIndex;\r\n                                sortDepths[writeIndex] = depth;\r\n                                writeIndex++;\r\n                                if (depth < minDepth) {\r\n                                    minDepth = depth;\r\n                                }\r\n                                if (depth > maxDepth) {\r\n                                    maxDepth = depth;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (inconsistentSnapshot) {\r\n                        self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n                        return;\r\n                    }\r\n\r\n                    // Counting (radix) sort by a depth-derived integer key — O(n) vs the legacy comparison sort.\r\n                    // Bucket bit depth follows PlayCanvas: round(log2(n/4)) clamped to [10, 20]. The farthest splat\r\n                    // gets key 0 so the ascending counting sort yields back-to-front order for alpha blending.\r\n                    const compareBits = Math.max(10, Math.min(20, Math.round(Math.log2(Math.max(1, renderSplatCount) / 4))));\r\n                    const bucketCount = 2 ** compareBits + 1;\r\n                    if (!sortCounts || sortCounts.length !== bucketCount) {\r\n                        sortCounts = new Uint32Array(bucketCount);\r\n                    } else {\r\n                        sortCounts.fill(0);\r\n                    }\r\n\r\n                    const range = maxDepth - minDepth;\r\n                    if (!(range > 1e-12)) {\r\n                        // All active splats share a depth (or none are active): identity order, single bucket.\r\n                        for (let k = 0; k < renderSplatCount; k++) {\r\n                            sortKeys[k] = 0;\r\n                        }\r\n                        sortCounts[0] = renderSplatCount;\r\n                    } else {\r\n                        const scale = (bucketCount - 1) / range;\r\n                        const maxKey = bucketCount - 1;\r\n                        for (let k = 0; k < renderSplatCount; k++) {\r\n                            // maxDepth -> 0 (rendered first), minDepth -> bucketCount-1 (rendered last). Clamp\r\n                            // against float rounding (a tiny `range` makes `scale` huge), which could otherwise\r\n                            // produce key >= bucketCount and corrupt the histogram with out-of-bounds writes.\r\n                            let key = ((maxDepth - sortDepths[k]) * scale) >>> 0;\r\n                            if (key > maxKey) {\r\n                                key = maxKey;\r\n                            }\r\n                            sortKeys[k] = key;\r\n                            sortCounts[key]++;\r\n                        }\r\n                    }\r\n\r\n                    // Prefix-sum the histogram into bucket end offsets, then scatter source indices into place.\r\n                    for (let i = 1; i < bucketCount; i++) {\r\n                        sortCounts[i] += sortCounts[i - 1];\r\n                    }\r\n                    for (let k = 0; k < renderSplatCount; k++) {\r\n                        const dest = --sortCounts[sortKeys[k]];\r\n                        outIndices[2 * dest] = sortSourceIndices[k];\r\n                    }\r\n\r\n                    // Pad the remainder up to the 16-multiple with a guaranteed-empty index (see\r\n                    // emptySplatIndex above) — NOT splat index 0, which is just the first real splat of\r\n                    // whatever source data was loaded. Padding with a real, opaque splat draws it an extra\r\n                    // 15 times at the very end of the (back-to-front) draw order — i.e. always on top,\r\n                    // regardless of camera.\r\n                    for (let dest = renderSplatCount; dest < vertexCountPadded; dest++) {\r\n                        outIndices[2 * dest] = emptySplatIndex;\r\n                    }\r\n                } else {\r\n                    // ===== Legacy comparison sort: pack (index, ~depthBits) into each 64-bit lane and sort it =====\r\n                    const indices = new Uint32Array(depthMix.buffer);\r\n                    const floatMix = new Float32Array(depthMix.buffer);\r\n\r\n                    // Build the compact list of source-splat indices to sort.\r\n                    if (activeIntervals) {\r\n                        let writeIndex = 0;\r\n                        for (let rangeIndex = 0; rangeIndex < activeIntervals.length; rangeIndex += 2) {\r\n                            const start = activeIntervals[rangeIndex];\r\n                            const count = activeIntervals[rangeIndex + 1];\r\n                            for (let sourceIndex = start; sourceIndex < start + count; sourceIndex++) {\r\n                                indices[2 * writeIndex++] = sourceIndex;\r\n                            }\r\n                        }\r\n                        // Pad up to a multiple of 16. Splat index 0 isn't guaranteed invisible (see the\r\n                        // counting-sort branch above) — use the same guaranteed-empty index instead.\r\n                        for (; writeIndex < vertexCountPadded; writeIndex++) {\r\n                            indices[2 * writeIndex] = emptySplatIndex;\r\n                        }\r\n                    } else {\r\n                        for (let j = 0; j < vertexCountPadded; j++) {\r\n                            indices[2 * j] = j;\r\n                        }\r\n                    }\r\n\r\n                    let inconsistentSnapshot = false;\r\n                    if (partMatrices && partMatrices.length > 0 && partIndices && partIndices.length > 0) {\r\n                        // Precompute depth coefficients for each rig node.\r\n                        const depthCoeffs = partMatrices.map((m) => computeDepthCoeffs(m));\r\n                        const length = partIndices.length;\r\n                        for (let j = 0; j < vertexCountPadded; j++) {\r\n                            const sourceIndex = indices[2 * j];\r\n                            // NB: We need this 'min' because the vertex array is padded, not partIndices.\r\n                            const partIndex = partIndices[Math.min(sourceIndex, length - 1)];\r\n                            if (partIndex >= depthCoeffs.length) {\r\n                                // Inconsistent snapshot (see the counting-sort branch): skip the sort rather than depth\r\n                                // splats with the wrong transform; the unsorted indices render for one frame, then retry.\r\n                                inconsistentSnapshot = true;\r\n                                break;\r\n                            }\r\n                            const coeff = depthCoeffs[partIndex];\r\n                            floatMix[2 * j + 1] =\r\n                                coeff[0] * positions[4 * sourceIndex + 0] + coeff[1] * positions[4 * sourceIndex + 1] + coeff[2] * positions[4 * sourceIndex + 2] + coeff[3];\r\n                            // Invert the depth bits (bitwise not) so the ascending sort renders back to front.\r\n                            indices[2 * j + 1] = ~indices[2 * j + 1];\r\n                        }\r\n                    } else {\r\n                        const [a, b, c, d] = computeDepthCoeffs(globalWorldMatrix);\r\n                        for (let j = 0; j < vertexCountPadded; j++) {\r\n                            const sourceIndex = indices[2 * j];\r\n                            floatMix[2 * j + 1] = a * positions[4 * sourceIndex + 0] + b * positions[4 * sourceIndex + 1] + c * positions[4 * sourceIndex + 2] + d;\r\n                            indices[2 * j + 1] = ~indices[2 * j + 1];\r\n                        }\r\n                    }\r\n\r\n                    if (!inconsistentSnapshot) {\r\n                        depthMix.sort();\r\n                    }\r\n                }\r\n            } catch (sortError) {\r\n                // Transient data inconsistency (e.g. partIndices/partMatrices mismatch during addPart/removePart rebuild).\r\n                // Return the buffer unsorted so the main thread can unlock _canPostToWorker and retry next frame.\r\n                // Logger is unavailable inside the worker — console is the only option.\r\n                // eslint-disable-next-line no-console\r\n                console.error(\"Gaussian splat sort worker encountered an error (will retry next frame):\", sortError);\r\n            }\r\n\r\n            if (logSortPerformance && perf) {\r\n                // eslint-disable-next-line no-console\r\n                console.log(`[GaussianSplatting] ${useCountingSort ? \"counting\" : \"legacy\"} sort: ${renderSplatCount} splats in ${(perf.now() - sortStart).toFixed(2)}ms`);\r\n            }\r\n\r\n            self.postMessage({ command: \"sorted\", depthMix, cameraId, sortRequestId, rangeVersion }, [depthMix.buffer]);\r\n        }\r\n    };\r\n};\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Scene } from \"core/scene.pure\";\nimport { type DeepImmutable, type Nullable } from \"core/types\";\nimport { type BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\nimport { SubMesh } from \"../subMesh.pure\";\nimport { type AbstractMesh } from \"../abstractMesh.pure\";\nimport { Mesh } from \"../mesh.pure\";\nimport { VertexData } from \"../mesh.vertexData\";\nimport { Matrix, TmpVectors, Vector2, Vector3, type Quaternion } from \"core/Maths/math.vector.pure\";\n\nimport { Logger } from \"core/Misc/logger\";\nimport { Observable } from \"core/Misc/observable\";\nimport { GaussianSplattingMaterial } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\nimport { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget.pure\";\nimport { Color4 } from \"core/Maths/math.color.pure\";\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\nimport { Constants } from \"core/Engines/constants\";\nimport { FromHalfFloat, ToHalfFloat } from \"core/Misc/textureTools\";\nimport { type Material } from \"core/Materials/material.pure\";\nimport { type Effect } from \"core/Materials/effect.pure\";\nimport { Scalar } from \"core/Maths/math.scalar\";\nimport { runCoroutineSync, runCoroutineAsync, createYieldingScheduler, type Coroutine } from \"core/Misc/coroutine\";\nimport { EngineStore } from \"core/Engines/engineStore\";\nimport { type Camera } from \"core/Cameras/camera.pure\";\nimport { ImportMeshAsync } from \"core/Loading/sceneLoader\";\nimport { type INative } from \"core/Engines/Native/nativeInterfaces\";\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\nimport { type ICustomAnimationFrameRequester } from \"core/Misc/customAnimationFrameRequester\";\nimport { GaussianSplattingSortWorker, GaussianSplattingSortWorkerCommand } from \"./gaussianSplattingSortWorker\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\ndeclare const _native: INative;\n\n/** Internal mirror of ISogTexturePack (defined in loaders) — avoids a circular import. */\ninterface ISogPackInternal {\n    version: 1 | 2;\n    splatCount: number;\n    shDegree: number;\n    meansTextureL: BaseTexture;\n    meansTextureU: BaseTexture;\n    scalesTexture: BaseTexture;\n    quatsTexture: BaseTexture;\n    sh0Texture: BaseTexture;\n    shCentroidsTexture?: BaseTexture;\n    shLabelsTexture?: BaseTexture;\n    codebookTexture?: BaseTexture;\n    meansMin: [number, number, number];\n    meansMax: [number, number, number];\n    scalesMin?: [number, number, number];\n    scalesMax?: [number, number, number];\n    sh0Min?: [number, number, number, number];\n    sh0Max?: [number, number, number, number];\n    shnMin?: number;\n    shnMax?: number;\n    shCoeffCount: number;\n    positions: Float32Array;\n}\n\n/**\n * Safe-orbit camera limits embedded in a Gaussian Splatting file's metadata (Adobe safe-orbit\n * extension). Exposed on the loaded mesh via {@link GaussianSplattingMeshBase.safeOrbitCameraLimits}\n * so consumers can read/apply the limits independently of the scene's active camera — the loader's\n * automatic application only affects an active ArcRotateCamera at load time.\n */\nexport interface ISafeOrbitCameraLimits {\n    /** Minimum safe orbit radius (distance from the camera to its target), if the file specifies one. */\n    radiusMin?: number;\n    /** Safe elevation range as `[minElevation, maxElevation]` in radians, if the file specifies one. */\n    elevationMinMax?: [number, number];\n}\n\nconst IsNative = typeof _native !== \"undefined\";\nconst Native = IsNative ? _native : null;\ninterface IDelayedTextureUpdate {\n    covA: Uint16Array;\n    covB: Uint16Array;\n    colors: Uint8Array;\n    centers: Float32Array;\n    sh?: Uint8Array[];\n}\ninterface IUpdateOptions {\n    flipY?: boolean;\n    /** @internal When set, skips reprocessing splats [0, previousVertexCount) and copies from cached arrays instead. */\n    previousVertexCount?: number;\n}\n\n/**\n * Defines a contiguous source-splat range to render from a GaussianSplattingMesh.\n */\nexport interface IGaussianSplattingSplatRange {\n    /**\n     * First source splat index to render.\n     */\n    offset: number;\n    /**\n     * Number of source splats to render.\n     */\n    count: number;\n}\n\ninterface ITextureDataUpdateCapableEngine {\n    updateTextureData(\n        texture: InternalTexture,\n        imageData: ArrayBufferView,\n        xOffset: number,\n        yOffset: number,\n        width: number,\n        height: number,\n        faceIndex?: number,\n        lod?: number,\n        generateMipMaps?: boolean\n    ): void;\n    updateRawTexture(\n        texture: Nullable<InternalTexture>,\n        data: Nullable<ArrayBufferView>,\n        format: number,\n        invertY: boolean,\n        compression?: Nullable<string>,\n        type?: number,\n        useSRGBBuffer?: boolean\n    ): void;\n    _gl?: unknown;\n    isWebGPU?: boolean;\n}\n\n// @internal\nconst UnpackUnorm = (value: number, bits: number) => {\n    const t = (1 << bits) - 1;\n    return (value & t) / t;\n};\n\n// @internal\nconst Unpack111011 = (value: number, result: Vector3) => {\n    result.x = UnpackUnorm(value >>> 21, 11);\n    result.y = UnpackUnorm(value >>> 11, 10);\n    result.z = UnpackUnorm(value, 11);\n};\n\n// @internal\nconst Unpack8888 = (value: number, result: Uint8ClampedArray) => {\n    result[0] = UnpackUnorm(value >>> 24, 8) * 255;\n    result[1] = UnpackUnorm(value >>> 16, 8) * 255;\n    result[2] = UnpackUnorm(value >>> 8, 8) * 255;\n    result[3] = UnpackUnorm(value, 8) * 255;\n};\n\n// @internal\n// unpack quaternion with 2,10,10,10 format (largest element, 3x10bit element)\nconst UnpackRot = (value: number, result: Quaternion) => {\n    const norm = 1.0 / (Math.sqrt(2) * 0.5);\n    const a = (UnpackUnorm(value >>> 20, 10) - 0.5) * norm;\n    const b = (UnpackUnorm(value >>> 10, 10) - 0.5) * norm;\n    const c = (UnpackUnorm(value, 10) - 0.5) * norm;\n    const m = Math.sqrt(1.0 - (a * a + b * b + c * c));\n\n    switch (value >>> 30) {\n        case 0:\n            result.set(m, a, b, c);\n            break;\n        case 1:\n            result.set(a, m, b, c);\n            break;\n        case 2:\n            result.set(a, b, m, c);\n            break;\n        case 3:\n            result.set(a, b, c, m);\n            break;\n    }\n};\n\ninterface ICompressedPLYChunk {\n    min: Vector3;\n    max: Vector3;\n    minScale: Vector3;\n    maxScale: Vector3;\n    minColor: Vector3;\n    maxColor: Vector3;\n}\n\n/**\n * To support multiple camera rendering, rendered mesh is separated from the GaussianSplattingMesh itself.\n * The GS mesh serves as a proxy and a different mesh is rendered for each camera. This hot switch is done\n * in the render() function. Each camera has a corresponding ICameraViewInfo object. The key is the camera unique id.\n * ICameraViewInfo and the rendered mesh are created in method `_postToWorker`\n * Mesh are disabled to not let the scene render them directly.\n * ICameraViewInfo are sorted per last frame id update to prioritize the less recently updated ones.\n * There is 1 web worker per GaussianSplattingMesh to avoid too many copies between main thread and workers.\n * So, only one sort is being done at a time per GaussianSplattingMeshBase. If multiple cameras need an update,\n * they will be processed one by one in subsequent frames.\n */\ninterface ICameraViewInfo {\n    camera: Camera;\n    cameraDirection: Vector3;\n    sortWorldMatrix: Matrix;\n    sortCameraForward: Vector3;\n    sortCameraPosition: Vector3;\n    sortRequestId: number;\n    sortAppliedId: number;\n    mesh: Mesh;\n    frameIdLastUpdate: number;\n    splatIndexBufferSet: boolean;\n}\n/**\n * Representation of the types\n */\nconst enum PLYType {\n    FLOAT,\n    INT,\n    UINT,\n    DOUBLE,\n    UCHAR,\n    USHORT,\n    UNDEFINED,\n}\n\n/**\n * Usage types of the PLY values\n */\nconst enum PLYValue {\n    MIN_X,\n    MIN_Y,\n    MIN_Z,\n    MAX_X,\n    MAX_Y,\n    MAX_Z,\n\n    MIN_SCALE_X,\n    MIN_SCALE_Y,\n    MIN_SCALE_Z,\n\n    MAX_SCALE_X,\n    MAX_SCALE_Y,\n    MAX_SCALE_Z,\n\n    PACKED_POSITION,\n    PACKED_ROTATION,\n    PACKED_SCALE,\n    PACKED_COLOR,\n    X,\n    Y,\n    Z,\n    SCALE_0,\n    SCALE_1,\n    SCALE_2,\n\n    DIFFUSE_RED,\n    DIFFUSE_GREEN,\n    DIFFUSE_BLUE,\n    OPACITY,\n\n    F_DC_0,\n    F_DC_1,\n    F_DC_2,\n    F_DC_3,\n\n    ROT_0,\n    ROT_1,\n    ROT_2,\n    ROT_3,\n\n    MIN_COLOR_R,\n    MIN_COLOR_G,\n    MIN_COLOR_B,\n\n    MAX_COLOR_R,\n    MAX_COLOR_G,\n    MAX_COLOR_B,\n\n    SH_0,\n    SH_1,\n    SH_2,\n    SH_3,\n    SH_4,\n    SH_5,\n    SH_6,\n    SH_7,\n    SH_8,\n    SH_9,\n    SH_10,\n    SH_11,\n    SH_12,\n    SH_13,\n    SH_14,\n    SH_15,\n    SH_16,\n    SH_17,\n    SH_18,\n    SH_19,\n    SH_20,\n    SH_21,\n    SH_22,\n    SH_23,\n    SH_24,\n    SH_25,\n    SH_26,\n    SH_27,\n    SH_28,\n    SH_29,\n    SH_30,\n    SH_31,\n    SH_32,\n    SH_33,\n    SH_34,\n    SH_35,\n    SH_36,\n    SH_37,\n    SH_38,\n    SH_39,\n    SH_40,\n    SH_41,\n    SH_42,\n    SH_43,\n    SH_44,\n    SH_45,\n    SH_46,\n    SH_47,\n    SH_48,\n    SH_49,\n    SH_50,\n    SH_51,\n    SH_52,\n    SH_53,\n    SH_54,\n    SH_55,\n    SH_56,\n    SH_57,\n    SH_58,\n    SH_59,\n    SH_60,\n    SH_61,\n    SH_62,\n    SH_63,\n    SH_64,\n    SH_65,\n    SH_66,\n    SH_67,\n    SH_68,\n    SH_69,\n    SH_70,\n    SH_71,\n\n    UNDEFINED,\n}\n\n/**\n * Property field found in PLY header\n */\nexport type PlyProperty = {\n    /**\n     * Value usage\n     */\n    value: PLYValue;\n    /**\n     * Value type\n     */\n    type: PLYType;\n    /**\n     * offset in byte from te beginning of the splat\n     */\n    offset: number;\n};\n\n/**\n * meta info on Splat file\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport interface PLYHeader {\n    /**\n     * number of splats\n     */\n    vertexCount: number;\n    /**\n     * number of spatial chunks for compressed ply\n     */\n    chunkCount: number;\n    /**\n     * length in bytes of the vertex info\n     */\n    rowVertexLength: number;\n    /**\n     * length in bytes of the chunk\n     */\n    rowChunkLength: number;\n    /**\n     * array listing properties per vertex\n     */\n    vertexProperties: PlyProperty[];\n    /**\n     * array listing properties per chunk\n     */\n    chunkProperties: PlyProperty[];\n    /**\n     * data view for parsing chunks and vertices\n     */\n    dataView: DataView;\n    /**\n     * buffer for the data view\n     */\n    buffer: ArrayBuffer;\n    /**\n     * degree of SH coefficients\n     */\n    shDegree: number;\n    /**\n     * number of coefficient per splat\n     */\n    shCoefficientCount: number;\n    /**\n     * buffer for SH coefficients\n     */\n    shBuffer: ArrayBuffer | null;\n}\n\n// Inter-frame task-queue yield\n// Depth-sort results arrive via worker postMessage, which is a regular-priority\n// task. At high refresh rates the rAF loop can leave almost no time for the\n// regular task queue, starving sort results for hundreds of milliseconds.\n// Installing a customAnimationFrameRequester that inserts a setTimeout(0) before\n// each rAF forces the event loop to drain regular tasks between frames.\n// The wrapper is ref-counted so it is installed when the first GSplat mesh is\n// created and removed when the last one is disposed.\n\ninterface IGsInterFrameYieldRequester extends ICustomAnimationFrameRequester {\n    _gsInterFrameYield: true;\n    _refCount: number;\n}\n\nfunction _AcquireGsInterFrameYield(engine: AbstractEngine): void {\n    // Browser-only optimization: wraps the global requestAnimationFrame, which\n    // doesn't exist on Babylon Native. Skip it there so the engine uses its\n    // default frame scheduling.\n    if (IsNative) {\n        return;\n    }\n    const existing = engine.customAnimationFrameRequester as IGsInterFrameYieldRequester | null;\n    if (existing?._gsInterFrameYield) {\n        existing._refCount++;\n        return;\n    }\n    if (existing) {\n        // Slot is owned by another requester. Don't interfere.\n        return;\n    }\n    let _timeoutId = 0;\n    let _innerRafId = 0;\n    const wrapper: IGsInterFrameYieldRequester = {\n        _gsInterFrameYield: true,\n        _refCount: 1,\n        requestAnimationFrame: (callback: Function): number => {\n            // Insert a setTimeout(0) to yield to the regular task queue (worker\n            // postMessage results, input events) before scheduling the next animation\n            // frame. Without this, a continuous rAF loop at high refresh rates leaves\n            // almost no time for regular tasks, starving worker messages for hundreds of ms.\n            _timeoutId = setTimeout(() => {\n                _innerRafId = requestAnimationFrame(callback as FrameRequestCallback);\n            }, 0) as unknown as number;\n            return _timeoutId;\n        },\n        cancelAnimationFrame: (_id: number) => {\n            clearTimeout(_timeoutId);\n            if (_innerRafId > 0) {\n                cancelAnimationFrame(_innerRafId);\n            }\n            _timeoutId = 0;\n            _innerRafId = 0;\n        },\n    };\n    engine.customAnimationFrameRequester = wrapper;\n}\n\n// Counterpart to _AcquireGsInterFrameYield. Call once per mesh on dispose.\nfunction _ReleaseGsInterFrameYield(engine: AbstractEngine): void {\n    const existing = engine.customAnimationFrameRequester as IGsInterFrameYieldRequester | null;\n    if (!existing?._gsInterFrameYield) {\n        return;\n    }\n    existing._refCount--;\n    if (existing._refCount === 0) {\n        engine.customAnimationFrameRequester = null;\n    }\n}\n\n/**\n * Base class for Gaussian Splatting meshes. Contains all single-cloud rendering logic.\n * @internal Use GaussianSplattingMesh instead; this class is an internal implementation detail.\n */\nexport class GaussianSplattingMeshBase extends Mesh {\n    /**\n     * When true (default), the depth-sort worker uses the fast O(n) counting (radix) sort. Set to false to\n     * fall back to the legacy comparison sort (useful for A/B comparison or as a safety fallback). The change\n     * takes effect on the next sort.\n     */\n    public static UseCountingSort = true;\n\n    /**\n     * When true, the depth-sort worker logs each sort's duration (ms) and active splat count to the console.\n     * Off by default; intended for performance investigation only.\n     */\n    public static LogSortPerformance = false;\n\n    /**\n     * Safe-orbit camera limits parsed from the source file's metadata, or `null` when the file\n     * carries none. The loader also auto-applies these to an active ArcRotateCamera at load time\n     * (unless `disableAutoCameraLimits` is set); this field exposes the raw values so they can be\n     * applied or tracked regardless of the active camera type. See {@link ISafeOrbitCameraLimits}.\n     */\n    public safeOrbitCameraLimits: Nullable<ISafeOrbitCameraLimits> = null;\n\n    /** @internal */\n    public _vertexCount = 0;\n    protected _worker: Nullable<Worker> = null;\n    private _modelViewProjectionMatrix = Matrix.Identity();\n    private _depthMix: BigInt64Array;\n    protected _canPostToWorker = true;\n    private _readyToDisplay = false;\n    private _sortRequestId = 0;\n    // Incremented on every active-range change. A worker sort result is only applied when it was computed\n    // for the current range version (and size), so a sort for stale ranges is never rendered.\n    private _activeRangeVersion = 0;\n    private _hasRenderedOnce = false;\n    protected _covariancesATexture: Nullable<BaseTexture> = null;\n    protected _covariancesBTexture: Nullable<BaseTexture> = null;\n    protected _centersTexture: Nullable<BaseTexture> = null;\n    protected _colorsTexture: Nullable<BaseTexture> = null;\n    // When a streaming part is reserved, the four core data textures (centers, covA, covB, colors) are backed\n    // by this MRT's attachments instead of standalone RawTextures, so a streaming engine can GPU-decode into\n    // the reserved region while static parts still CPU-upload into it. Null in the normal\n    // (non-streaming) path, which keeps using RawTextures unchanged.\n    protected _mrtAtlas: Nullable<MultiRenderTarget> = null;\n    protected _useMrtAtlas = false;\n    // Higher-order SH atlas. When a streaming part needs baked SH, `_shTextures` become the single\n    // attachments of these render-targetable integer MRTs (one per packed-u32 SH texture) so the streaming engine\n    // GPU-decodes SH into the reserved region while static SH parts still CPU-upload into them. Null in the normal\n    // path (SH stays plain RawTextures). One MRT per attachment keeps within WebGPU's per-sample byte budget.\n    protected _shMrtAtlas: Nullable<MultiRenderTarget[]> = null;\n    protected _useShMrtAtlas = false;\n    protected _shMrtAtlasTextureCount = 0;\n    protected _rotationsATexture: Nullable<BaseTexture> = null;\n    protected _rotationsBTexture: Nullable<BaseTexture> = null;\n    protected _rotationScaleTexture: Nullable<BaseTexture> = null;\n    // Rotation/scale atlas. When a streaming part needs voxel-IBL rotation/scale, the three rotation\n    // textures become the attachments of this render-targetable half-float MRT so the streaming engine GPU-decodes\n    // rotation/scale into the reserved region while static parts still CPU-upload into it. Null in the normal path\n    // (rotation stays plain RawTextures created per-splat by `_makeSplat`).\n    protected _rotMrtAtlas: Nullable<MultiRenderTarget> = null;\n    protected _useRotMrtAtlas = false;\n    private _rotationDataA: Nullable<Uint16Array> = null;\n    private _rotationDataB: Nullable<Uint16Array> = null;\n    private _rotationScaleData: Nullable<Uint16Array> = null;\n    protected _needsRotationScaleTextures: boolean = false;\n    protected _splatPositions: Nullable<Float32Array> = null;\n    private _splatIndex: Nullable<Float32Array> = null;\n    protected _shTextures: Nullable<BaseTexture[]> = null;\n    /** @internal */\n    public _splatsData: Nullable<ArrayBuffer> = null;\n    /** @internal */\n    public _shData: Nullable<Uint8Array[]> = null;\n    private _textureSize: Vector2 = new Vector2(0, 0);\n    protected readonly _keepInRam: boolean = false;\n    protected _alwaysRetainSplatsData: boolean = false;\n    protected _flipY = false;\n\n    private _delayedTextureUpdate: Nullable<IDelayedTextureUpdate> = null;\n    protected _useRGBACovariants = false;\n    protected _useSog = false;\n    protected _sogParams: Nullable<ISogPackInternal> = null;\n    private _material: Nullable<Material> = null;\n\n    private _tmpCovariances = [0, 0, 0, 0, 0, 0];\n    private _splatSizeMin: number = Infinity;\n    private _splatSizeMax: number = -Infinity;\n    private _sortIsDirty = false;\n    private _activeSplatRanges: Nullable<Uint32Array> = null;\n    private _activeSplatRangeKey = \"\";\n    private _activeSplatRenderCount = 0;\n\n    // Cached bounding box for incremental addPart updates (O(1) vs O(N) scan of positions)\n    protected _cachedBoundingMin: Nullable<Vector3> = null;\n    protected _cachedBoundingMax: Nullable<Vector3> = null;\n\n    private static _RowOutputLength = 3 * 4 + 3 * 4 + 4 + 4; // Vector3 position, Vector3 scale, 1 u8 quaternion, 1 color with alpha\n    private static _SH_C0 = 0.28209479177387814;\n    // batch size between 2 yield calls. This value is a tradeoff between updates overhead and framerate hiccups\n    // This step is faster the PLY conversion. So batch size can be bigger\n    private static _SplatBatchSize = 327680;\n    // batch size between 2 yield calls during the PLY to splat conversion.\n    private static _PlyConversionBatchSize = 32768;\n    /** @internal */\n    public _shDegree = 0;\n    protected _maxShDegree = 0;\n\n    private static readonly _BatchSize = 16; // 16 splats per instance\n    private _cameraViewInfos = new Map<number, ICameraViewInfo>();\n\n    protected static readonly _DefaultViewUpdateThreshold = 1e-4;\n\n    /** Fired after parts are added or the mesh is rebuilt following a removal. Payload is the new part count. */\n    public readonly onPartCountChangedObservable = new Observable<number>();\n\n    /** Fired after part-removal validation passes but before the mesh is rebuilt.\n     *  Payload is the original (pre-removal) part index. */\n    public readonly onPartRemovedObservable = new Observable<number>();\n\n    /**\n     * Fired just before an existing MRT-backed atlas is recreated to grow it (e.g. adding a part while a streaming\n     * part exists). Payload is the OLD atlas. Streaming parts subscribe to back up their GPU-only region before it\n     * is disposed. Only fires when growing an existing MRT atlas (not on first creation).\n     * @internal\n     */\n    public readonly _onBeforeAtlasRebuildObservable = new Observable<MultiRenderTarget>();\n\n    /**\n     * Fired after the new (grown) MRT-backed atlas has been created and its CPU data uploaded. Payload is the NEW\n     * atlas. Streaming parts subscribe to rebind to it and restore their backed-up region.\n     * @internal\n     */\n    public readonly _onAfterAtlasRebuildObservable = new Observable<MultiRenderTarget>();\n\n    /**\n     * Returns a byte-accurate view for retained splat data, preserving any non-zero byte offset.\n     * @param data The retained splat source bytes.\n     * @returns A Uint8Array covering the exact source byte range.\n     * @internal\n     */\n    protected static _GetSplatDataBytes(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n        return ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);\n    }\n\n    /**\n     * Returns a Float32 reinterpretation for retained splat data, copying only when alignment requires it.\n     * @param data The retained splat source bytes.\n     * @returns A Float32Array over the exact source byte range.\n     * @internal\n     */\n    protected static _GetSplatDataFloats(data: ArrayBuffer | ArrayBufferView): Float32Array {\n        const bytes = GaussianSplattingMeshBase._GetSplatDataBytes(data);\n        const floatSize = Float32Array.BYTES_PER_ELEMENT;\n\n        if (bytes.byteLength % floatSize !== 0) {\n            throw new Error(`Gaussian splat data byte length (${bytes.byteLength}) is not divisible by ${floatSize} and cannot be reinterpreted as Float32 data.`);\n        }\n\n        if (bytes.byteOffset % floatSize !== 0) {\n            const copy = new Uint8Array(bytes.byteLength);\n            copy.set(bytes);\n            return new Float32Array(copy.buffer, 0, bytes.byteLength / floatSize);\n        }\n\n        return new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / floatSize);\n    }\n\n    private static _BuildSplatRangeData(\n        ranges: Nullable<readonly IGaussianSplattingSplatRange[]>,\n        vertexCount: number\n    ): { ranges: Nullable<Uint32Array>; count: number; key: string } {\n        if (ranges === null) {\n            return { ranges: null, count: vertexCount, key: \"\" };\n        }\n\n        const rangePairs: number[] = [];\n        let totalCount = 0;\n        let key = \"\";\n        for (const range of ranges) {\n            const start = Math.max(0, Math.floor(range.offset));\n            const count = Math.max(0, Math.floor(range.count));\n            const end = Math.min(vertexCount, start + count);\n            const rangeCount = Math.max(0, end - start);\n            if (rangeCount === 0) {\n                continue;\n            }\n\n            rangePairs.push(start, rangeCount);\n            totalCount += rangeCount;\n            key += `${start}:${rangeCount};`;\n        }\n\n        return { ranges: new Uint32Array(rangePairs), count: totalCount, key };\n    }\n\n    /**\n     * Cosine value of the angle threshold to update view dependent splat sorting. Default is 0.0001.\n     */\n    public viewUpdateThreshold: number = GaussianSplattingMeshBase._DefaultViewUpdateThreshold;\n\n    protected _disableDepthSort = false;\n    /**\n     * If true, disables depth sorting of the splats (default: false)\n     */\n    public get disableDepthSort() {\n        return this._disableDepthSort;\n    }\n    public set disableDepthSort(value: boolean) {\n        if (!this._disableDepthSort && value) {\n            this._worker?.terminate();\n            this._worker = null;\n            this._disableDepthSort = true;\n        } else if (this._disableDepthSort && !value) {\n            this._disableDepthSort = false;\n            this._sortIsDirty = true;\n            this._instantiateWorker();\n        }\n    }\n\n    /**\n     * View direction factor used to compute the SH view direction in the shader.\n     * @deprecated Not used anymore for SH rendering\n     */\n    public get viewDirectionFactor() {\n        return Vector3.OneReadOnly;\n    }\n\n    /**\n     * SH degree. 0 = no sh (default). 1 = 3 parameters. 2 = 8 parameters. 3 = 15 parameters.\n     * Value is clamped between 0 and the maximum degree available from loaded data.\n     */\n    public get shDegree() {\n        return this._shDegree;\n    }\n\n    public set shDegree(value: number) {\n        const maxDegree = this._maxShDegree;\n        const clamped = Math.max(0, Math.min(Math.round(value), maxDegree));\n        if (this._shDegree === clamped) {\n            return;\n        }\n        this._shDegree = clamped;\n        this.material?.resetDrawCache();\n    }\n\n    /**\n     * Maximum SH degree available from the loaded data.\n     */\n    public get maxShDegree() {\n        return this._maxShDegree;\n    }\n\n    /**\n     * Number of splats in the mesh\n     */\n    public get splatCount() {\n        return this._splatIndex?.length;\n    }\n\n    /**\n     * Number of source splats currently selected for rendering.\n     * When no range filter is active, this is the mesh's full source splat count.\n     */\n    public get renderedSplatCount(): number {\n        return this._activeSplatRanges ? this._activeSplatRenderCount : this._vertexCount;\n    }\n\n    /**\n     * Restricts rendering to the provided source splat ranges.\n     * Passing `null` clears the range filter and renders the full source splat set.\n     * @param ranges contiguous source ranges to render, or null to render all splats\n     */\n    public setSplatIndexRanges(ranges: Nullable<readonly IGaussianSplattingSplatRange[]>): void {\n        this._setSplatIndexRanges(ranges);\n    }\n\n    private _setSplatIndexRanges(ranges: Nullable<readonly IGaussianSplattingSplatRange[]>): void {\n        const rangeData = GaussianSplattingMeshBase._BuildSplatRangeData(ranges, this._vertexCount);\n        const isSameRangeSet = this._activeSplatRanges === null ? rangeData.ranges === null : rangeData.ranges !== null && this._activeSplatRangeKey === rangeData.key;\n        if (isSameRangeSet) {\n            return;\n        }\n\n        this._activeSplatRanges = rangeData.ranges;\n        this._activeSplatRangeKey = rangeData.key;\n        this._activeSplatRenderCount = rangeData.count;\n        this._activeRangeVersion++;\n        this._postIntervalsToWorker();\n        if (this._worker) {\n            // Defer swapping the rendered index buffer until the worker returns a depth sort computed for\n            // this exact range set (see the worker `onmessage` handler). Until then we keep rendering the\n            // previous fully-sorted state, so a range/LOD change never shows an unsorted flash nor a stale\n            // index buffer (rendering indices that belong to a different active set, which caused the\n            // disappear/reappear flicker). Only the worker's depth buffer is resized here so the next sort\n            // produces the right number of entries.\n            this._ensureDepthMixSize(Math.max((this._activeSplatRenderCount + 15) & ~0xf, 16));\n            this._sortIsDirty = true;\n            this._postToWorker(true);\n        } else {\n            // Synchronous sort paths (disabled depth sort / Native): swap the index buffer immediately.\n            this._updateSplatIndexBuffer(this._vertexCount);\n            this._postToWorker(true);\n        }\n    }\n\n    /**\n     * Whether the depth sort is settled: a sort computed for the current active ranges and camera has been\n     * applied to the rendered index buffer, and no further sort is pending or in flight. For a static camera\n     * and a fixed active set this becomes true once the final sort completes. Used by streaming subclasses to\n     * detect when rendering is fully up to date (e.g. for deterministic screenshots) and by IBL shadows to\n     * avoid voxelizing against an index buffer the worker has not finished (re)building yet.\n     * @internal\n     */\n    public get _isDepthSortSettled(): boolean {\n        return this._readyToDisplay && !this._sortIsDirty && this._canPostToWorker;\n    }\n\n    // (Re)allocates the worker depth buffer to the given padded size. A fresh array is allocated when the\n    // size differs or the current buffer is detached (in-flight in the worker), so a queued sort can be\n    // re-posted with a correctly-sized buffer without disturbing the in-flight one.\n    private _ensureDepthMixSize(paddedCount: number): void {\n        if (IsNative) {\n            return;\n        }\n        if (!this._depthMix || this._depthMix.length !== paddedCount || this._depthMix.buffer.byteLength === 0) {\n            this._depthMix = new BigInt64Array(paddedCount);\n        }\n    }\n\n    /**\n     * Sends the active source-splat intervals to the sort worker. When no range filter is active,\n     * a single interval covering all source splats is sent so the worker never assumes the full set.\n     */\n    private _postIntervalsToWorker(): void {\n        if (!this._worker) {\n            return;\n        }\n        const intervals = this._activeSplatRanges ? new Uint32Array(this._activeSplatRanges) : new Uint32Array([0, this._vertexCount]);\n        this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.INTERVALS, intervals }, [intervals.buffer]);\n    }\n\n    /**\n     * Initializes this mesh to render from an externally-provided, GPU-decoded work buffer, bypassing the\n     * CPU `updateData` path. The four textures must hold the standard decoded GS layout addressed by linear\n     * splat index over a square texture: centers (x,y,z,1), covariance A (Sigma00,01,02,11) and B\n     * (Sigma12,22,*,*) as full covariance (so `center.w` is 1), and RGBA color. `splatPositions` are the\n     * stride-4 CPU centers consumed by the depth-sort worker.\n     * @param centers centers texture\n     * @param covariancesA covariance A texture\n     * @param covariancesB covariance B texture\n     * @param colors color texture\n     * @param splatPositions stride-4 CPU centers for depth sorting (length vertexCount*4)\n     * @param vertexCount number of splats addressable in the work buffer\n     * @param shTextures optional baked higher-order SH textures (packed-u32) produced by the work buffer's SH decode.\n     *   When provided, the draw path lights the decoded splats with view-dependent SH (the non-SOG `shTexture0..N`\n     *   path). `shDegree` sets both the max and active SH degree.\n     * @param shDegree SH degree of the baked SH textures (0 = none). Ignored when `shTextures` is empty/omitted.\n     * @param rotationTextures optional decoded rotation/scale textures ([rotA, rotB, rotScale]) produced by the work\n     *   buffer's rotation decode. When provided, they drive the voxel-IBL rotation/scale samplers so the streamed\n     *   splats participate in voxel-based IBL shadowing.\n     */\n    protected _setExternalWorkBuffer(\n        centers: BaseTexture,\n        covariancesA: BaseTexture,\n        covariancesB: BaseTexture,\n        colors: BaseTexture,\n        splatPositions: Float32Array,\n        vertexCount: number,\n        shTextures?: Nullable<BaseTexture[]>,\n        shDegree: number = 0,\n        rotationTextures?: Nullable<BaseTexture[]>\n    ): void {\n        this._covariancesATexture = covariancesA;\n        this._covariancesBTexture = covariancesB;\n        this._centersTexture = centers;\n        this._colorsTexture = colors;\n        this._splatPositions = splatPositions;\n        this._vertexCount = vertexCount;\n        if (shTextures && shTextures.length) {\n            this._shTextures = shTextures;\n            this._maxShDegree = shDegree;\n            this._shDegree = shDegree;\n        }\n        // Point the voxel-IBL rotation/scale samplers at the work buffer's decoded rotation textures ([rotA, rotB,\n        // rotScale]) so a standalone stream can cast/receive voxel-IBL shadows.\n        if (rotationTextures && rotationTextures.length >= 3) {\n            this._rotationsATexture = rotationTextures[0];\n            this._rotationsBTexture = rotationTextures[1];\n            this._rotationScaleTexture = rotationTextures[2];\n            this._needsRotationScaleTextures = true;\n        }\n        this._activeSplatRanges = null;\n        this._activeSplatRangeKey = \"\";\n        this._activeSplatRenderCount = 0;\n        this._readyToDisplay = false;\n        // Sizes _splatIndex/_depthMix, starts the sort worker, and posts positions + intervals.\n        this._instantiateWorker();\n        // updateData (bypassed here) normally enables the mesh; do it explicitly for the work-buffer path.\n        this.setEnabled(true);\n    }\n\n    /**\n     * returns the splats data array buffer that contains in order : postions (3 floats), size (3 floats), color (4 bytes), orientation quaternion (4 bytes)\n     * Only available if the mesh was created with keepInRam: true\n     */\n    public get splatsData() {\n        return this._keepInRam ? this._splatsData : null;\n    }\n\n    /**\n     * returns the SH data arrays\n     * Only available if the mesh was created with keepInRam: true\n     */\n    public get shData() {\n        return this._keepInRam ? this._shData : null;\n    }\n\n    /**\n     * Returns the min/max size range of splats in this mesh, where size is pow(|det(Σ)|, 1/6)\n     * of the 3D covariance matrix — equivalent to the geometric mean of the principal radii.\n     * Computed automatically during updateData(). Returns null before any data has been loaded.\n     */\n    public get splatSizeRange(): Nullable<{ min: number; max: number }> {\n        if (!isFinite(this._splatSizeMin) || !isFinite(this._splatSizeMax)) {\n            return null;\n        }\n        return { min: this._splatSizeMin, max: this._splatSizeMax };\n    }\n\n    /**\n     * Set the number of batch (a batch is 16384 splats) after which a display update is performed\n     * A value of 0 (default) means display update will not happens before splat is ready.\n     */\n    public static ProgressiveUpdateAmount = 0;\n\n    /**\n     * Gets the covariancesA texture\n     */\n    public get covariancesATexture() {\n        return this._covariancesATexture;\n    }\n\n    /**\n     * Gets the covariancesB texture\n     */\n    public get covariancesBTexture() {\n        return this._covariancesBTexture;\n    }\n\n    /**\n     * Gets the centers texture\n     */\n    public get centersTexture() {\n        return this._centersTexture;\n    }\n\n    /**\n     * Gets the colors texture\n     */\n    public get colorsTexture() {\n        return this._colorsTexture;\n    }\n\n    /**\n     * Gets the rotation matrix A texture (rotation elements m[0],m[1],m[2],m[4])\n     */\n    public get rotationsATexture() {\n        return this._rotationsATexture;\n    }\n\n    /**\n     * Gets the rotation matrix B texture (rotation elements m[5],m[6],m[8],m[9])\n     */\n    public get rotationsBTexture() {\n        return this._rotationsBTexture;\n    }\n\n    /**\n     * Gets the rotation scale texture (rotation element m[10] followed by scale diagonal sx,sy,sz)\n     */\n    public get rotationScaleTexture() {\n        return this._rotationScaleTexture;\n    }\n\n    /**\n     * Enables or disables generation of rotation and scale matrix textures, required for voxel-based IBL shadows.\n     */\n    public get needsRotationScaleTextures() {\n        return this._needsRotationScaleTextures;\n    }\n\n    public set needsRotationScaleTextures(value: boolean) {\n        if (this._needsRotationScaleTextures === value) {\n            return;\n        }\n        this._needsRotationScaleTextures = value;\n        if (value && this._covariancesATexture) {\n            if (this._splatsData) {\n                this.updateData(this._splatsData, this._shData ?? undefined, { flipY: false }, undefined, this._shDegree);\n            } else {\n                Logger.Error(\n                    \"GaussianSplattingMeshBase: needsRotationScaleTextures was enabled after the mesh was already loaded, but the splat data is not kept in RAM. \" +\n                        \"The rotation and scale matrix textures cannot be initialized. Please reload the mesh data via updateData() or construct with keepInRam=true.\"\n                );\n            }\n        }\n    }\n\n    /**\n     * Gets the SH textures\n     */\n    public get shTextures() {\n        return this._shTextures;\n    }\n\n    /**\n     * True when this mesh holds raw SOG webp textures (dequantized in-shader) rather than the\n     * pre-decoded covariance/center/color textures produced by the standard splat loader.\n     */\n    public get useSog(): boolean {\n        return this._useSog;\n    }\n\n    /**\n     * SOG dequantization parameters paired with the raw textures.\n     * Set by the splat loader when `useSogTextures: true`. Null otherwise.\n     */\n    public get sogParams(): Nullable<ISogPackInternal> {\n        return this._sogParams;\n    }\n\n    /**\n     * Install a set of raw SOG webp textures and bind the mesh to the in-shader dequantization path.\n     * @param pack SOG texture pack produced by ParseSogMetaAsTextures.\n     * @internal\n     */\n    public setSogTextureData(pack: ISogPackInternal): void {\n        this._useSog = true;\n        this._sogParams?.codebookTexture?.dispose();\n        this._sogParams = pack;\n        this._vertexCount = pack.splatCount;\n        this._shDegree = pack.shDegree ?? 0;\n        this._maxShDegree = this._shDegree;\n\n        // Stride-4 (xyz + 1) — required by the depth-sort worker and the centers texture path.\n        this._splatPositions = pack.positions;\n\n        // Reuse existing texture slots for SOG textures (the shader, under USE_SOG, samples them as RGBA8).\n        this._covariancesATexture?.dispose();\n        this._covariancesBTexture?.dispose();\n        this._centersTexture?.dispose();\n        this._colorsTexture?.dispose();\n        this._rotationsATexture?.dispose();\n        if (this._shTextures) {\n            for (const t of this._shTextures) {\n                t.dispose();\n            }\n        }\n\n        this._centersTexture = pack.meansTextureL;\n        this._covariancesATexture = pack.meansTextureU;\n        this._covariancesBTexture = pack.scalesTexture;\n        this._rotationsATexture = pack.quatsTexture;\n        this._colorsTexture = pack.sh0Texture;\n\n        const shTextures: BaseTexture[] = [];\n        if (pack.shCentroidsTexture) {\n            shTextures.push(pack.shCentroidsTexture);\n        }\n        if (pack.shLabelsTexture) {\n            shTextures.push(pack.shLabelsTexture);\n        }\n        this._shTextures = shTextures.length ? shTextures : null;\n\n        // Force pipeline rebuild so the USE_SOG define and extra samplers are picked up.\n        this._material?.resetDrawCache();\n\n        const size = pack.meansTextureL.getSize();\n        this._textureSize.x = size.width;\n        this._textureSize.y = size.height;\n\n        this._updateSplatIndexBuffer(this._vertexCount);\n        this._instantiateWorker();\n\n        // Compute bounds from the CPU-decoded positions (stride-4) so the mesh is not frustum-culled.\n        const positions = pack.positions as Float32Array;\n        const minimum = new Vector3(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);\n        const maximum = new Vector3(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY);\n        for (let i = 0; i < this._vertexCount; i++) {\n            const x = positions[i * 4 + 0];\n            const y = positions[i * 4 + 1];\n            const z = positions[i * 4 + 2];\n            if (x < minimum.x) {\n                minimum.x = x;\n            }\n            if (y < minimum.y) {\n                minimum.y = y;\n            }\n            if (z < minimum.z) {\n                minimum.z = z;\n            }\n            if (x > maximum.x) {\n                maximum.x = x;\n            }\n            if (y > maximum.y) {\n                maximum.y = y;\n            }\n            if (z > maximum.z) {\n                maximum.z = z;\n            }\n        }\n        this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());\n        this.setEnabled(true);\n        this._sortIsDirty = true;\n    }\n\n    /**\n     * Gets the kernel size\n     * Documentation and mathematical explanations here:\n     * https://github.com/graphdeco-inria/gaussian-splatting/issues/294#issuecomment-1772688093\n     * https://github.com/autonomousvision/mip-splatting/issues/18#issuecomment-1929388931\n     */\n    public get kernelSize() {\n        return this._material instanceof GaussianSplattingMaterial ? this._material.kernelSize : 0;\n    }\n\n    /**\n     * Get the compensation state\n     */\n    public get compensation() {\n        return this._material instanceof GaussianSplattingMaterial ? this._material.compensation : false;\n    }\n\n    /**\n     * Minimum projected splat size, in pixels, below which a splat is discarded (0 = disabled).\n     * Applied in real time; no rebuild required.\n     */\n    public get minPixelSize(): number {\n        return this._material instanceof GaussianSplattingMaterial ? this._material.minPixelSize : 0;\n    }\n\n    public set minPixelSize(value: number) {\n        if (this._material instanceof GaussianSplattingMaterial) {\n            this._material.minPixelSize = Math.max(0, value);\n        }\n    }\n\n    private _loadingPromise: Promise<void> | null = null;\n\n    /**\n     * set rendering material\n     */\n    public override set material(value: Material) {\n        this._material = value;\n        this._material.backFaceCulling = false;\n        this._material.cullBackFaces = false;\n        value.resetDrawCache();\n        this._cameraViewInfos?.forEach((cameraViewInfo) => {\n            cameraViewInfo.mesh.material = value;\n        });\n    }\n\n    /**\n     * get rendering material\n     */\n    public override get material(): Nullable<Material> {\n        return this._material;\n    }\n\n    private static _MakeSplatGeometryForMesh(mesh: Mesh): void {\n        const vertexData = new VertexData();\n        const originPositions = [-2, -2, 0, 2, -2, 0, 2, 2, 0, -2, 2, 0];\n        const originIndices = [0, 1, 2, 0, 2, 3];\n        const positions = [];\n        const indices = [];\n        for (let i = 0; i < GaussianSplattingMeshBase._BatchSize; i++) {\n            for (let j = 0; j < 12; j++) {\n                if (j == 2 || j == 5 || j == 8 || j == 11) {\n                    positions.push(i); // local splat index\n                } else {\n                    positions.push(originPositions[j]);\n                }\n            }\n            indices.push(originIndices.map((v) => v + i * 4));\n        }\n\n        vertexData.positions = positions;\n        vertexData.indices = indices.flat();\n\n        vertexData.applyToMesh(mesh);\n    }\n\n    /**\n     * Creates a new gaussian splatting mesh\n     * @param name defines the name of the mesh\n     * @param url defines the url to load from (optional)\n     * @param scene defines the hosting scene (optional)\n     * @param keepInRam keep datas in ram for editing purpose\n     */\n    constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false) {\n        super(name, scene);\n\n        this.subMeshes = [];\n        new SubMesh(0, 0, 4 * GaussianSplattingMeshBase._BatchSize, 0, 6 * GaussianSplattingMeshBase._BatchSize, this);\n\n        this.setEnabled(false);\n        // webGL2 and webGPU support for RG texture with float16 is fine. not webGL1\n        this._useRGBACovariants = !this.getEngine().isWebGPU && this.getEngine().version === 1.0;\n        _AcquireGsInterFrameYield(this.getEngine());\n\n        this._keepInRam = keepInRam;\n        if (url) {\n            this._loadingPromise = this.loadFileAsync(url);\n        }\n        const gaussianSplattingMaterial = new GaussianSplattingMaterial(this.name + \"_material\", this._scene);\n        // Cast is safe: GaussianSplattingMeshBase is @internal; all concrete instances are GaussianSplattingMesh.\n        gaussianSplattingMaterial.setSourceMesh(this as any);\n        gaussianSplattingMaterial.doNotSerialize = true;\n        this._material = gaussianSplattingMaterial;\n\n        // delete meshes created for cameras on camera removal\n        this._scene.onCameraRemovedObservable.add((camera: Camera) => {\n            const cameraId = camera.uniqueId;\n            // delete mesh for this camera\n            const cameraViewInfos = this._cameraViewInfos.get(cameraId);\n            if (cameraViewInfos) {\n                // If the cached shadow-caster geometry came from the mesh we're disposing, drop it\n                // so isReady()/render() re-cache it from a surviving camera (see isReady()).\n                // Must run before dispose(), which nulls the inner mesh's geometry.\n                if (this._geometry === cameraViewInfos.mesh.geometry) {\n                    this._geometry = null;\n                }\n                cameraViewInfos.mesh.dispose();\n                this._cameraViewInfos.delete(cameraId);\n            }\n        });\n    }\n\n    /**\n     * Get the loading promise when loading the mesh from a URL in the constructor\n     * @returns constructor loading promise or null if no URL was provided\n     */\n    public getLoadingPromise(): Promise<void> | null {\n        return this._loadingPromise;\n    }\n\n    /** @internal */\n    public override get _isGaussianSplatting(): boolean {\n        return true;\n    }\n\n    /**\n     * Returns the class name\n     * @returns \"GaussianSplattingMeshBase\"\n     */\n    public override getClassName(): string {\n        return \"GaussianSplattingMeshBase\";\n    }\n\n    /**\n     * Returns the total number of vertices (splats) within the mesh\n     * @returns the total number of vertices\n     */\n    public override getTotalVertices(): number {\n        return this._vertexCount;\n    }\n\n    /**\n     * Is this node ready to be used/rendered\n     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\n     * @returns true when ready\n     */\n    public override isReady(completeCheck = false): boolean {\n        if (!super.isReady(completeCheck, true)) {\n            return false;\n        }\n\n        if (!this._readyToDisplay) {\n            // mesh is ready when worker has done at least 1 sorting\n            this._postToWorker(true);\n            return false;\n        }\n\n        // Before the first successful render, require an applied index buffer. A pending refresh can\n        // use the latest completed buffer, otherwise a transform changed every frame would starve the\n        // first render. Once rendered, the render loop continuously re-sorts as the camera/world changes.\n        if (!this._hasRenderedOnce && !this._disableDepthSort) {\n            const cameras = this._scene.activeCameras?.length ? this._scene.activeCameras : [this._scene.activeCamera!];\n            const canRenderWithPendingRefresh = this._scene._isInRenderingMeshEvaluation() && cameras.filter((camera) => camera !== null).length === 1;\n            const worldMatrix = this.computeWorldMatrix(true);\n            let sortBufferMissing = false;\n            let sortRefreshPending = false;\n            let worldMatrixDirty = false;\n            for (const camera of cameras) {\n                if (!camera) {\n                    continue;\n                }\n\n                const cameraViewInfo = this._cameraViewInfos.get(camera.uniqueId);\n                if (!cameraViewInfo || !cameraViewInfo.splatIndexBufferSet || cameraViewInfo.sortAppliedId === 0) {\n                    sortBufferMissing = true;\n                    continue;\n                }\n\n                if (cameraViewInfo.sortAppliedId !== cameraViewInfo.sortRequestId) {\n                    sortRefreshPending = true;\n                    continue;\n                }\n\n                // If world matrix drifted (user applied transforms after load), request an updated sort.\n                // Camera drift is intentionally excluded here: checking camera movement would cause isReady()\n                // to return false indefinitely while the camera is moving. The render loop handles camera\n                // re-sorting continuously via _postToWorker() in render().\n                if (this._isSortStateDirty(cameraViewInfo, worldMatrix, camera, true)) {\n                    worldMatrixDirty = true;\n                }\n            }\n\n            if (sortBufferMissing || sortRefreshPending || worldMatrixDirty) {\n                // Try to post any pending sort so subsequent polling iterations make progress.\n                this._postToWorker(true);\n                // A single-camera scene may use its latest completed sort while a transform refresh is\n                // pending, which prevents continuously changing transforms from starving the first render.\n                // Multi-camera scenes must wait because each viewport needs its own refreshed ordering.\n                if (sortBufferMissing || !canRenderWithPendingRefresh) {\n                    return false;\n                }\n            }\n        }\n\n        // Attach the splat geometry to the GS top mesh so that the shadow generator (which renders\n        // shadow casters via the top mesh's subMeshes, NOT through this mesh's render() override)\n        // has valid geometry on the very first shadow pass. Without this, the first shadow render\n        // happens before render() is called and the GS produces no shadow caster output.\n        if (!this._geometry && this._cameraViewInfos.size) {\n            this._geometry = this._cameraViewInfos.values().next().value!.mesh.geometry;\n        }\n\n        // If the material declares a shadow depth wrapper, make sure its effect is compiled for\n        // each subMesh against the scene's shadow generators. Otherwise the first shadow pass\n        // would be skipped (ShadowGenerator.isReady would return false) and we'd miss the shadow\n        // on a renderCount=1 capture.\n        // The shadow generator's depth wrapper is standalone (it wraps a ShaderMaterial), so its\n        // isReadyForSubMesh path stamps an effect on subMesh._drawWrappers[engine.currentRenderPassId].\n        // If we leave currentRenderPassId set to the main pass while doing this, we'd overwrite the\n        // GS material's defines on the main draw wrapper, causing the GS material to recreate its\n        // defines on the next call and lose any plugin-driven define state (e.g. defines toggled\n        // by a MaterialPluginBase.isReadyForSubMesh override). Temporarily switch to each shadow\n        // generator's render pass id while preparing it (matches the pattern used in Mesh.isReady).\n        if (this.material && this.material.shadowDepthWrapper) {\n            const engine = this._scene.getEngine();\n            const previousRenderPassId = engine.currentRenderPassId;\n            try {\n                for (const light of this._scene.lights) {\n                    const shadowGenerator = light.getShadowGenerator();\n                    if (!shadowGenerator) {\n                        continue;\n                    }\n                    const shadowMap = shadowGenerator.getShadowMap();\n                    const renderPassIds = shadowMap?.renderPassIds;\n                    if (!renderPassIds || renderPassIds.length === 0) {\n                        continue;\n                    }\n                    for (let p = 0; p < renderPassIds.length; ++p) {\n                        engine.currentRenderPassId = renderPassIds[p];\n                        for (const subMesh of this.subMeshes) {\n                            if (!shadowGenerator.isReady(subMesh, true, false)) {\n                                return false;\n                            }\n                        }\n                    }\n                }\n            } finally {\n                engine.currentRenderPassId = previousRenderPassId;\n            }\n        }\n\n        return true;\n    }\n\n    public _getCameraDirection(camera: Camera): Vector3 {\n        const cameraViewMatrix = camera.getViewMatrix();\n        const cameraProjectionMatrix = camera.getProjectionMatrix();\n        const cameraViewProjectionMatrix = TmpVectors.Matrix[0];\n        cameraViewMatrix.multiplyToRef(cameraProjectionMatrix, cameraViewProjectionMatrix);\n\n        const modelMatrix = this.computeWorldMatrix(true);\n        const modelViewMatrix = TmpVectors.Matrix[1];\n        modelMatrix.multiplyToRef(cameraViewMatrix, modelViewMatrix);\n        modelMatrix.multiplyToRef(cameraViewProjectionMatrix, this._modelViewProjectionMatrix);\n\n        // return vector used to compute distance to camera\n        const localDirection = TmpVectors.Vector3[1];\n        localDirection.set(modelViewMatrix.m[2], modelViewMatrix.m[6], modelViewMatrix.m[10]);\n        localDirection.normalize();\n\n        return localDirection;\n    }\n\n    private _isSortStateDirty(cameraViewInfo: ICameraViewInfo, worldMatrix: Matrix, camera: Camera, worldMatrixOnly = false): boolean {\n        const world = worldMatrix.m;\n        const previousWorld = cameraViewInfo.sortWorldMatrix.m;\n        for (let i = 0; i < previousWorld.length; i++) {\n            if (!Scalar.WithinEpsilon(previousWorld[i], world[i], this.viewUpdateThreshold)) {\n                return true;\n            }\n        }\n\n        if (worldMatrixOnly) {\n            return false;\n        }\n\n        const cameraViewMatrix = camera.getViewMatrix();\n        if (\n            !Scalar.WithinEpsilon(cameraViewInfo.sortCameraForward.x, cameraViewMatrix.m[2], this.viewUpdateThreshold) ||\n            !Scalar.WithinEpsilon(cameraViewInfo.sortCameraForward.y, cameraViewMatrix.m[6], this.viewUpdateThreshold) ||\n            !Scalar.WithinEpsilon(cameraViewInfo.sortCameraForward.z, cameraViewMatrix.m[10], this.viewUpdateThreshold)\n        ) {\n            return true;\n        }\n\n        const cameraPosition = camera.globalPosition;\n        return (\n            !Scalar.WithinEpsilon(cameraViewInfo.sortCameraPosition.x, cameraPosition.x, this.viewUpdateThreshold) ||\n            !Scalar.WithinEpsilon(cameraViewInfo.sortCameraPosition.y, cameraPosition.y, this.viewUpdateThreshold) ||\n            !Scalar.WithinEpsilon(cameraViewInfo.sortCameraPosition.z, cameraPosition.z, this.viewUpdateThreshold)\n        );\n    }\n\n    /** @internal */\n    public _postToWorker(forced = false): void {\n        const scene = this._scene;\n        const frameId = scene.getFrameId();\n        // force update or at least frame update for camera is outdated\n        let outdated = false;\n        this._cameraViewInfos.forEach((cameraViewInfos) => {\n            if (cameraViewInfos.frameIdLastUpdate !== frameId) {\n                outdated = true;\n            }\n        });\n\n        // array of cameras used for rendering\n        const cameras = this._scene.activeCameras?.length ? this._scene.activeCameras : [this._scene.activeCamera!];\n        // list view infos for active cameras\n        const activeViewInfos: ICameraViewInfo[] = [];\n        cameras.forEach((camera) => {\n            if (!camera) {\n                return;\n            }\n            const cameraId = camera.uniqueId;\n\n            const cameraViewInfos = this._cameraViewInfos.get(cameraId);\n            if (cameraViewInfos) {\n                activeViewInfos.push(cameraViewInfos);\n            } else {\n                // mesh doesn't exist yet for this camera\n                const cameraMesh = new Mesh(this.name + \"_cameraMesh_\" + cameraId, this._scene);\n                cameraMesh.doNotSerialize = true;\n                // not visible with inspector or the scene graph\n                cameraMesh.reservedDataStore = { hidden: true, _gaussianSplattingSourceMesh: this };\n                cameraMesh.setEnabled(false);\n                cameraMesh.material = this.material;\n                if (cameraMesh.material && cameraMesh.material instanceof GaussianSplattingMaterial) {\n                    const gsMaterial = cameraMesh.material as GaussianSplattingMaterial;\n                    // GaussianSplattingMaterial source mesh may not have been set yet.\n                    // This happens for cloned resources from asset containers for instance,\n                    // where material is cloned before mesh.\n                    if (!gsMaterial.getSourceMesh()) {\n                        // Cast is safe: see constructor comment above.\n                        gsMaterial.setSourceMesh(this as any);\n                    }\n                }\n                GaussianSplattingMeshBase._MakeSplatGeometryForMesh(cameraMesh);\n\n                const newViewInfos: ICameraViewInfo = {\n                    camera: camera,\n                    cameraDirection: new Vector3(0, 0, 0),\n                    sortWorldMatrix: Matrix.Identity(),\n                    sortCameraForward: new Vector3(0, 0, 0),\n                    sortCameraPosition: new Vector3(0, 0, 0),\n                    sortRequestId: 0,\n                    sortAppliedId: 0,\n                    mesh: cameraMesh,\n                    frameIdLastUpdate: frameId,\n                    splatIndexBufferSet: false,\n                };\n                activeViewInfos.push(newViewInfos);\n                this._cameraViewInfos.set(cameraId, newViewInfos);\n            }\n        });\n        // Sort view infos: cameras without a completed initial sort come first so they don't get starved\n        // by a `forced` re-sort of an already-initialized camera (which would consume `_canPostToWorker`).\n        // A camera can already have the shared index buffer bound when another camera's first sort resizes it,\n        // so splatIndexBufferSet alone does not mean this camera has received its own sorted result.\n        // Among initialized cameras, the least recently updated comes first.\n        activeViewInfos.sort((a, b) => {\n            if ((a.sortAppliedId === 0) !== (b.sortAppliedId === 0)) {\n                return a.sortAppliedId === 0 ? -1 : 1;\n            }\n            if (a.splatIndexBufferSet !== b.splatIndexBufferSet) {\n                return a.splatIndexBufferSet ? 1 : -1;\n            }\n            return a.frameIdLastUpdate - b.frameIdLastUpdate;\n        });\n\n        // The native sort writes into _splatPositions/_splatIndex: both must be allocated (they still are\n        // null before any splat data has been committed) or the native binding throws on the conversion.\n        const hasNativeSort = !!Native?.sortSplats && !!this._splatPositions && !!this._splatIndex;\n        // When depth sort is disabled, no sort function must run: fall through to the no-sort path below.\n        const hasSortFunction = !this._disableDepthSort && (this._worker || hasNativeSort);\n        if ((forced || outdated) && hasSortFunction && (this._scene.activeCameras?.length || this._scene.activeCamera) && this._canPostToWorker) {\n            const worldMatrix = this.computeWorldMatrix(true);\n            // view infos sorted by least recent updated frame id\n            activeViewInfos.forEach((cameraViewInfos) => {\n                const camera = cameraViewInfos.camera;\n                const cameraDirection = this._getCameraDirection(camera);\n                if ((forced || this._isSortStateDirty(cameraViewInfos, worldMatrix, camera)) && this._canPostToWorker) {\n                    const cameraViewMatrix = camera.getViewMatrix();\n                    cameraViewInfos.cameraDirection.copyFrom(cameraDirection);\n                    cameraViewInfos.sortWorldMatrix.copyFrom(worldMatrix);\n                    cameraViewInfos.sortCameraForward.set(cameraViewMatrix.m[2], cameraViewMatrix.m[6], cameraViewMatrix.m[10]);\n                    cameraViewInfos.sortCameraPosition.copyFrom(camera.globalPosition);\n                    cameraViewInfos.sortRequestId = ++this._sortRequestId;\n                    cameraViewInfos.frameIdLastUpdate = frameId;\n                    this._canPostToWorker = false;\n                    if (this._worker) {\n                        this._worker.postMessage(\n                            {\n                                command: GaussianSplattingSortWorkerCommand.SORT,\n                                worldMatrix: worldMatrix.m,\n                                cameraForward: [cameraViewMatrix.m[2], cameraViewMatrix.m[6], cameraViewMatrix.m[10]],\n                                cameraPosition: [camera.globalPosition.x, camera.globalPosition.y, camera.globalPosition.z],\n                                depthMix: this._depthMix,\n                                cameraId: camera.uniqueId,\n                                sortRequestId: cameraViewInfos.sortRequestId,\n                                rangeVersion: this._activeRangeVersion,\n                                useCountingSort: GaussianSplattingMeshBase.UseCountingSort,\n                                rightHanded: this._scene.useRightHandedSystem,\n                                logSortPerformance: GaussianSplattingMeshBase.LogSortPerformance,\n                            },\n                            [this._depthMix.buffer]\n                        );\n                    } else if (Native?.sortSplats) {\n                        if (this._activeSplatRanges) {\n                            // Native sort can't filter ranges: fall back to the (already range-filtered) identity index buffer.\n                            this._updateSplatIndexBuffer(this._vertexCount);\n                        } else {\n                            Native.sortSplats(this._modelViewProjectionMatrix, this._splatPositions!, this._splatIndex!, this._scene.useRightHandedSystem);\n                        }\n                        if (cameraViewInfos.splatIndexBufferSet) {\n                            cameraViewInfos.mesh.thinInstanceBufferUpdated(\"splatIndex\");\n                        } else {\n                            cameraViewInfos.mesh.thinInstanceSetBuffer(\"splatIndex\", this._splatIndex, 16, false);\n                            cameraViewInfos.splatIndexBufferSet = true;\n                        }\n                        cameraViewInfos.sortAppliedId = cameraViewInfos.sortRequestId;\n                        this._canPostToWorker = true;\n                        this._readyToDisplay = true;\n                    }\n                }\n            });\n        } else if (this._disableDepthSort) {\n            if (this._splatIndex) {\n                activeViewInfos.forEach((cameraViewInfos) => {\n                    if (!cameraViewInfos.splatIndexBufferSet) {\n                        cameraViewInfos.mesh.thinInstanceSetBuffer(\"splatIndex\", this._splatIndex, 16, false);\n                        cameraViewInfos.splatIndexBufferSet = true;\n                    }\n                });\n                this._readyToDisplay = true;\n            }\n            this._canPostToWorker = true;\n        }\n    }\n    /**\n     * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager\n     * @param subMesh defines the subMesh to render\n     * @param enableAlphaMode defines if alpha mode can be changed\n     * @param effectiveMeshReplacement defines an optional mesh used to provide info for the rendering\n     * @returns the current mesh\n     */\n    public override render(subMesh: SubMesh, enableAlphaMode: boolean, effectiveMeshReplacement?: AbstractMesh): Mesh {\n        this._postToWorker();\n\n        // geometry used for shadows, bind the first found in the camera view infos\n        if (!this._geometry && this._cameraViewInfos.size) {\n            this._geometry = this._cameraViewInfos.values().next().value!.mesh.geometry;\n        }\n\n        const cameraId = this._scene.activeCamera!.uniqueId;\n        const cameraViewInfos = this._cameraViewInfos.get(cameraId);\n        if (!cameraViewInfos || !cameraViewInfos.splatIndexBufferSet) {\n            return this;\n        }\n\n        if (this.onBeforeRenderObservable) {\n            this.onBeforeRenderObservable.notifyObservers(this);\n        }\n        const mesh = cameraViewInfos.mesh;\n        mesh.getWorldMatrix().copyFrom(this.getWorldMatrix());\n\n        // Propagate render pass material overrides (e.g., GPU picking) to the inner camera mesh.\n        // When this mesh is rendered into a RenderTargetTexture with a material override (via setMaterialForRendering),\n        // the override is set on this proxy mesh but needs to be applied to the actual camera mesh that does the rendering.\n        const engine = this._scene.getEngine();\n        const renderPassId = engine.currentRenderPassId;\n        const renderPassMaterial = this.getMaterialForRenderPass(renderPassId);\n        if (renderPassMaterial) {\n            mesh.setMaterialForRenderPass(renderPassId, renderPassMaterial);\n        }\n\n        const ret = mesh.render(subMesh, enableAlphaMode, effectiveMeshReplacement);\n\n        this._hasRenderedOnce = true;\n\n        // Clean up the temporary override to avoid affecting other render passes\n        if (renderPassMaterial) {\n            mesh.setMaterialForRenderPass(renderPassId, undefined);\n        }\n\n        if (this.onAfterRenderObservable) {\n            this.onAfterRenderObservable.notifyObservers(this);\n        }\n        return ret;\n    }\n\n    private static _TypeNameToEnum(name: string): PLYType {\n        switch (name) {\n            case \"float\":\n                return PLYType.FLOAT;\n            case \"int\":\n                return PLYType.INT;\n            case \"uint\":\n                return PLYType.UINT;\n            case \"double\":\n                return PLYType.DOUBLE;\n            case \"uchar\":\n                return PLYType.UCHAR;\n            case \"ushort\":\n            case \"uint16\":\n                return PLYType.USHORT;\n        }\n        return PLYType.UNDEFINED;\n    }\n\n    private static _ValueNameToEnum(name: string): PLYValue {\n        switch (name) {\n            case \"min_x\":\n                return PLYValue.MIN_X;\n            case \"min_y\":\n                return PLYValue.MIN_Y;\n            case \"min_z\":\n                return PLYValue.MIN_Z;\n            case \"max_x\":\n                return PLYValue.MAX_X;\n            case \"max_y\":\n                return PLYValue.MAX_Y;\n            case \"max_z\":\n                return PLYValue.MAX_Z;\n            case \"min_scale_x\":\n                return PLYValue.MIN_SCALE_X;\n            case \"min_scale_y\":\n                return PLYValue.MIN_SCALE_Y;\n            case \"min_scale_z\":\n                return PLYValue.MIN_SCALE_Z;\n            case \"max_scale_x\":\n                return PLYValue.MAX_SCALE_X;\n            case \"max_scale_y\":\n                return PLYValue.MAX_SCALE_Y;\n            case \"max_scale_z\":\n                return PLYValue.MAX_SCALE_Z;\n            case \"packed_position\":\n                return PLYValue.PACKED_POSITION;\n            case \"packed_rotation\":\n                return PLYValue.PACKED_ROTATION;\n            case \"packed_scale\":\n                return PLYValue.PACKED_SCALE;\n            case \"packed_color\":\n                return PLYValue.PACKED_COLOR;\n            case \"x\":\n                return PLYValue.X;\n            case \"y\":\n                return PLYValue.Y;\n            case \"z\":\n                return PLYValue.Z;\n            case \"scale_0\":\n                return PLYValue.SCALE_0;\n            case \"scale_1\":\n                return PLYValue.SCALE_1;\n            case \"scale_2\":\n                return PLYValue.SCALE_2;\n            case \"diffuse_red\":\n            case \"red\":\n                return PLYValue.DIFFUSE_RED;\n            case \"diffuse_green\":\n            case \"green\":\n                return PLYValue.DIFFUSE_GREEN;\n            case \"diffuse_blue\":\n            case \"blue\":\n                return PLYValue.DIFFUSE_BLUE;\n            case \"f_dc_0\":\n                return PLYValue.F_DC_0;\n            case \"f_dc_1\":\n                return PLYValue.F_DC_1;\n            case \"f_dc_2\":\n                return PLYValue.F_DC_2;\n            case \"f_dc_3\":\n                return PLYValue.F_DC_3;\n            case \"opacity\":\n                return PLYValue.OPACITY;\n            case \"rot_0\":\n                return PLYValue.ROT_0;\n            case \"rot_1\":\n                return PLYValue.ROT_1;\n            case \"rot_2\":\n                return PLYValue.ROT_2;\n            case \"rot_3\":\n                return PLYValue.ROT_3;\n            case \"min_r\":\n                return PLYValue.MIN_COLOR_R;\n            case \"min_g\":\n                return PLYValue.MIN_COLOR_G;\n            case \"min_b\":\n                return PLYValue.MIN_COLOR_B;\n            case \"max_r\":\n                return PLYValue.MAX_COLOR_R;\n            case \"max_g\":\n                return PLYValue.MAX_COLOR_G;\n            case \"max_b\":\n                return PLYValue.MAX_COLOR_B;\n            case \"f_rest_0\":\n                return PLYValue.SH_0;\n            case \"f_rest_1\":\n                return PLYValue.SH_1;\n            case \"f_rest_2\":\n                return PLYValue.SH_2;\n            case \"f_rest_3\":\n                return PLYValue.SH_3;\n            case \"f_rest_4\":\n                return PLYValue.SH_4;\n            case \"f_rest_5\":\n                return PLYValue.SH_5;\n            case \"f_rest_6\":\n                return PLYValue.SH_6;\n            case \"f_rest_7\":\n                return PLYValue.SH_7;\n            case \"f_rest_8\":\n                return PLYValue.SH_8;\n            case \"f_rest_9\":\n                return PLYValue.SH_9;\n            case \"f_rest_10\":\n                return PLYValue.SH_10;\n            case \"f_rest_11\":\n                return PLYValue.SH_11;\n            case \"f_rest_12\":\n                return PLYValue.SH_12;\n            case \"f_rest_13\":\n                return PLYValue.SH_13;\n            case \"f_rest_14\":\n                return PLYValue.SH_14;\n            case \"f_rest_15\":\n                return PLYValue.SH_15;\n            case \"f_rest_16\":\n                return PLYValue.SH_16;\n            case \"f_rest_17\":\n                return PLYValue.SH_17;\n            case \"f_rest_18\":\n                return PLYValue.SH_18;\n            case \"f_rest_19\":\n                return PLYValue.SH_19;\n            case \"f_rest_20\":\n                return PLYValue.SH_20;\n            case \"f_rest_21\":\n                return PLYValue.SH_21;\n            case \"f_rest_22\":\n                return PLYValue.SH_22;\n            case \"f_rest_23\":\n                return PLYValue.SH_23;\n            case \"f_rest_24\":\n                return PLYValue.SH_24;\n            case \"f_rest_25\":\n                return PLYValue.SH_25;\n            case \"f_rest_26\":\n                return PLYValue.SH_26;\n            case \"f_rest_27\":\n                return PLYValue.SH_27;\n            case \"f_rest_28\":\n                return PLYValue.SH_28;\n            case \"f_rest_29\":\n                return PLYValue.SH_29;\n            case \"f_rest_30\":\n                return PLYValue.SH_30;\n            case \"f_rest_31\":\n                return PLYValue.SH_31;\n            case \"f_rest_32\":\n                return PLYValue.SH_32;\n            case \"f_rest_33\":\n                return PLYValue.SH_33;\n            case \"f_rest_34\":\n                return PLYValue.SH_34;\n            case \"f_rest_35\":\n                return PLYValue.SH_35;\n            case \"f_rest_36\":\n                return PLYValue.SH_36;\n            case \"f_rest_37\":\n                return PLYValue.SH_37;\n            case \"f_rest_38\":\n                return PLYValue.SH_38;\n            case \"f_rest_39\":\n                return PLYValue.SH_39;\n            case \"f_rest_40\":\n                return PLYValue.SH_40;\n            case \"f_rest_41\":\n                return PLYValue.SH_41;\n            case \"f_rest_42\":\n                return PLYValue.SH_42;\n            case \"f_rest_43\":\n                return PLYValue.SH_43;\n            case \"f_rest_44\":\n                return PLYValue.SH_44;\n            case \"f_rest_45\":\n                return PLYValue.SH_45;\n            case \"f_rest_46\":\n                return PLYValue.SH_46;\n            case \"f_rest_47\":\n                return PLYValue.SH_47;\n            case \"f_rest_48\":\n                return PLYValue.SH_48;\n            case \"f_rest_49\":\n                return PLYValue.SH_49;\n            case \"f_rest_50\":\n                return PLYValue.SH_50;\n            case \"f_rest_51\":\n                return PLYValue.SH_51;\n            case \"f_rest_52\":\n                return PLYValue.SH_52;\n            case \"f_rest_53\":\n                return PLYValue.SH_53;\n            case \"f_rest_54\":\n                return PLYValue.SH_54;\n            case \"f_rest_55\":\n                return PLYValue.SH_55;\n            case \"f_rest_56\":\n                return PLYValue.SH_56;\n            case \"f_rest_57\":\n                return PLYValue.SH_57;\n            case \"f_rest_58\":\n                return PLYValue.SH_58;\n            case \"f_rest_59\":\n                return PLYValue.SH_59;\n            case \"f_rest_60\":\n                return PLYValue.SH_60;\n            case \"f_rest_61\":\n                return PLYValue.SH_61;\n            case \"f_rest_62\":\n                return PLYValue.SH_62;\n            case \"f_rest_63\":\n                return PLYValue.SH_63;\n            case \"f_rest_64\":\n                return PLYValue.SH_64;\n            case \"f_rest_65\":\n                return PLYValue.SH_65;\n            case \"f_rest_66\":\n                return PLYValue.SH_66;\n            case \"f_rest_67\":\n                return PLYValue.SH_67;\n            case \"f_rest_68\":\n                return PLYValue.SH_68;\n            case \"f_rest_69\":\n                return PLYValue.SH_69;\n            case \"f_rest_70\":\n                return PLYValue.SH_70;\n            case \"f_rest_71\":\n                return PLYValue.SH_71;\n        }\n\n        return PLYValue.UNDEFINED;\n    }\n    /**\n     * Parse a PLY file header and returns metas infos on splats and chunks\n     * @param data the loaded buffer\n     * @returns a PLYHeader\n     */\n    static ParseHeader(data: ArrayBuffer): PLYHeader | null {\n        const ubuf = new Uint8Array(data);\n        const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));\n        const headerEnd = \"end_header\\n\";\n        const headerEndIndex = header.indexOf(headerEnd);\n        if (headerEndIndex < 0 || !header) {\n            // standard splat\n            return null;\n        }\n        const vertexCount = parseInt(/element vertex (\\d+)\\n/.exec(header)![1]);\n        const chunkElement = /element chunk (\\d+)\\n/.exec(header);\n        let chunkCount = 0;\n        if (chunkElement) {\n            chunkCount = parseInt(chunkElement[1]);\n        }\n        let rowVertexOffset = 0;\n        let rowChunkOffset = 0;\n        const offsets: Record<string, number> = {\n            double: 8,\n            int: 4,\n            uint: 4,\n            float: 4,\n            short: 2,\n            ushort: 2,\n            uint16: 2,\n            uchar: 1,\n            list: 0,\n        };\n\n        const enum ElementMode {\n            Vertex = 0,\n            Chunk = 1,\n            SH = 2,\n            Unused = 3,\n        }\n        let chunkMode = ElementMode.Chunk;\n        const vertexProperties: PlyProperty[] = [];\n        const chunkProperties: PlyProperty[] = [];\n        const filtered = header.slice(0, headerEndIndex).split(\"\\n\");\n        let shDegree = 0;\n        for (const prop of filtered) {\n            if (prop.startsWith(\"property \")) {\n                const [, typeName, name] = prop.split(\" \");\n\n                const value = GaussianSplattingMeshBase._ValueNameToEnum(name);\n                if (value != PLYValue.UNDEFINED) {\n                    // SH degree 1,2,3 or 4 for 9, 24, 45 or 72 values\n                    if (value >= PLYValue.SH_71) {\n                        shDegree = 4;\n                    } else if (value >= PLYValue.SH_44) {\n                        shDegree = Math.max(shDegree, 3);\n                    } else if (value >= PLYValue.SH_23) {\n                        shDegree = Math.max(shDegree, 2);\n                    } else if (value >= PLYValue.SH_8) {\n                        shDegree = Math.max(shDegree, 1);\n                    }\n                }\n                const type = GaussianSplattingMeshBase._TypeNameToEnum(typeName);\n                if (chunkMode == ElementMode.Chunk) {\n                    chunkProperties.push({ value, type, offset: rowChunkOffset });\n                    rowChunkOffset += offsets[typeName];\n                } else if (chunkMode == ElementMode.Vertex) {\n                    vertexProperties.push({ value, type, offset: rowVertexOffset });\n                    rowVertexOffset += offsets[typeName];\n                } else if (chunkMode == ElementMode.SH) {\n                    // SH doesn't count for vertex row size but its properties are used to retrieve SH\n                    vertexProperties.push({ value, type, offset: rowVertexOffset });\n                }\n\n                if (!offsets[typeName]) {\n                    Logger.Warn(`Unsupported property type: ${typeName}.`);\n                }\n            } else if (prop.startsWith(\"element \")) {\n                const [, type] = prop.split(\" \");\n                if (type == \"chunk\") {\n                    chunkMode = ElementMode.Chunk;\n                } else if (type == \"vertex\") {\n                    chunkMode = ElementMode.Vertex;\n                } else if (type == \"sh\") {\n                    chunkMode = ElementMode.SH;\n                } else {\n                    chunkMode = ElementMode.Unused;\n                }\n            }\n        }\n\n        const dataView = new DataView(data, headerEndIndex + headerEnd.length);\n        const buffer = new ArrayBuffer(GaussianSplattingMeshBase._RowOutputLength * vertexCount);\n\n        let shBuffer = null;\n        let shCoefficientCount = 0;\n        if (shDegree) {\n            const shVectorCount = (shDegree + 1) * (shDegree + 1) - 1;\n            shCoefficientCount = shVectorCount * 3;\n            shBuffer = new ArrayBuffer(shCoefficientCount * vertexCount);\n        }\n\n        return {\n            vertexCount: vertexCount,\n            chunkCount: chunkCount,\n            rowVertexLength: rowVertexOffset,\n            rowChunkLength: rowChunkOffset,\n            vertexProperties: vertexProperties,\n            chunkProperties: chunkProperties,\n            dataView: dataView,\n            buffer: buffer,\n            shDegree: shDegree,\n            shCoefficientCount: shCoefficientCount,\n            shBuffer: shBuffer,\n        };\n    }\n    private static _GetCompressedChunks(header: PLYHeader, offset: { value: number }): Array<ICompressedPLYChunk> | null {\n        if (!header.chunkCount) {\n            return null;\n        }\n        const dataView = header.dataView;\n        const compressedChunks = new Array<ICompressedPLYChunk>(header.chunkCount);\n        for (let i = 0; i < header.chunkCount; i++) {\n            const currentChunk = {\n                min: new Vector3(),\n                max: new Vector3(),\n                minScale: new Vector3(),\n                maxScale: new Vector3(),\n                minColor: new Vector3(0, 0, 0),\n                maxColor: new Vector3(1, 1, 1),\n            };\n            compressedChunks[i] = currentChunk;\n            for (let propertyIndex = 0; propertyIndex < header.chunkProperties.length; propertyIndex++) {\n                const property = header.chunkProperties[propertyIndex];\n                let value;\n                switch (property.type) {\n                    case PLYType.FLOAT:\n                        value = dataView.getFloat32(property.offset + offset.value, true);\n                        break;\n                    default:\n                        continue;\n                }\n\n                switch (property.value) {\n                    case PLYValue.MIN_X:\n                        currentChunk.min.x = value;\n                        break;\n                    case PLYValue.MIN_Y:\n                        currentChunk.min.y = value;\n                        break;\n                    case PLYValue.MIN_Z:\n                        currentChunk.min.z = value;\n                        break;\n                    case PLYValue.MAX_X:\n                        currentChunk.max.x = value;\n                        break;\n                    case PLYValue.MAX_Y:\n                        currentChunk.max.y = value;\n                        break;\n                    case PLYValue.MAX_Z:\n                        currentChunk.max.z = value;\n                        break;\n                    case PLYValue.MIN_SCALE_X:\n                        currentChunk.minScale.x = value;\n                        break;\n                    case PLYValue.MIN_SCALE_Y:\n                        currentChunk.minScale.y = value;\n                        break;\n                    case PLYValue.MIN_SCALE_Z:\n                        currentChunk.minScale.z = value;\n                        break;\n                    case PLYValue.MAX_SCALE_X:\n                        currentChunk.maxScale.x = value;\n                        break;\n                    case PLYValue.MAX_SCALE_Y:\n                        currentChunk.maxScale.y = value;\n                        break;\n                    case PLYValue.MAX_SCALE_Z:\n                        currentChunk.maxScale.z = value;\n                        break;\n                    case PLYValue.MIN_COLOR_R:\n                        currentChunk.minColor.x = value;\n                        break;\n                    case PLYValue.MIN_COLOR_G:\n                        currentChunk.minColor.y = value;\n                        break;\n                    case PLYValue.MIN_COLOR_B:\n                        currentChunk.minColor.z = value;\n                        break;\n                    case PLYValue.MAX_COLOR_R:\n                        currentChunk.maxColor.x = value;\n                        break;\n                    case PLYValue.MAX_COLOR_G:\n                        currentChunk.maxColor.y = value;\n                        break;\n                    case PLYValue.MAX_COLOR_B:\n                        currentChunk.maxColor.z = value;\n                        break;\n                }\n            }\n            offset.value += header.rowChunkLength;\n        }\n        return compressedChunks;\n    }\n\n    private static _GetSplat(header: PLYHeader, index: number, compressedChunks: Array<ICompressedPLYChunk> | null, offset: { value: number }): void {\n        const q = TmpVectors.Quaternion[0];\n        const temp3 = TmpVectors.Vector3[0];\n\n        const rowOutputLength = GaussianSplattingMeshBase._RowOutputLength;\n        const buffer = header.buffer;\n        const dataView = header.dataView;\n        const position = new Float32Array(buffer, index * rowOutputLength, 3);\n        const scale = new Float32Array(buffer, index * rowOutputLength + 12, 3);\n        const rgba = new Uint8ClampedArray(buffer, index * rowOutputLength + 24, 4);\n        const rot = new Uint8ClampedArray(buffer, index * rowOutputLength + 28, 4);\n        let sh = null;\n        if (header.shBuffer) {\n            sh = new Uint8ClampedArray(header.shBuffer, index * header.shCoefficientCount, header.shCoefficientCount);\n        }\n        const chunkIndex = index >> 8;\n        let r0: number = 255;\n        let r1: number = 0;\n        let r2: number = 0;\n        let r3: number = 0;\n\n        const plySH = [];\n\n        for (let propertyIndex = 0; propertyIndex < header.vertexProperties.length; propertyIndex++) {\n            const property = header.vertexProperties[propertyIndex];\n            let value;\n            switch (property.type) {\n                case PLYType.FLOAT:\n                    value = dataView.getFloat32(offset.value + property.offset, true);\n                    break;\n                case PLYType.INT:\n                    value = dataView.getInt32(offset.value + property.offset, true);\n                    break;\n                case PLYType.UINT:\n                    value = dataView.getUint32(offset.value + property.offset, true);\n                    break;\n                case PLYType.DOUBLE:\n                    value = dataView.getFloat64(offset.value + property.offset, true);\n                    break;\n                case PLYType.UCHAR:\n                    value = dataView.getUint8(offset.value + property.offset);\n                    break;\n                case PLYType.USHORT:\n                    value = FromHalfFloat(dataView.getUint16(offset.value + property.offset, true));\n                    break;\n                default:\n                    continue;\n            }\n\n            switch (property.value) {\n                case PLYValue.PACKED_POSITION:\n                    {\n                        const compressedChunk = compressedChunks![chunkIndex];\n                        Unpack111011(value, temp3);\n                        position[0] = Scalar.Lerp(compressedChunk.min.x, compressedChunk.max.x, temp3.x);\n                        position[1] = Scalar.Lerp(compressedChunk.min.y, compressedChunk.max.y, temp3.y);\n                        position[2] = Scalar.Lerp(compressedChunk.min.z, compressedChunk.max.z, temp3.z);\n                    }\n                    break;\n                case PLYValue.PACKED_ROTATION:\n                    {\n                        UnpackRot(value, q);\n\n                        r0 = q.x;\n                        r1 = q.y;\n                        r2 = q.z;\n                        r3 = q.w;\n                    }\n                    break;\n                case PLYValue.PACKED_SCALE:\n                    {\n                        const compressedChunk = compressedChunks![chunkIndex];\n                        Unpack111011(value, temp3);\n                        scale[0] = Math.exp(Scalar.Lerp(compressedChunk.minScale.x, compressedChunk.maxScale.x, temp3.x));\n                        scale[1] = Math.exp(Scalar.Lerp(compressedChunk.minScale.y, compressedChunk.maxScale.y, temp3.y));\n                        scale[2] = Math.exp(Scalar.Lerp(compressedChunk.minScale.z, compressedChunk.maxScale.z, temp3.z));\n                    }\n                    break;\n                case PLYValue.PACKED_COLOR:\n                    {\n                        const compressedChunk = compressedChunks![chunkIndex];\n                        Unpack8888(value, rgba);\n                        rgba[0] = Scalar.Lerp(compressedChunk.minColor.x, compressedChunk.maxColor.x, rgba[0] / 255) * 255;\n                        rgba[1] = Scalar.Lerp(compressedChunk.minColor.y, compressedChunk.maxColor.y, rgba[1] / 255) * 255;\n                        rgba[2] = Scalar.Lerp(compressedChunk.minColor.z, compressedChunk.maxColor.z, rgba[2] / 255) * 255;\n                    }\n                    break;\n                case PLYValue.X:\n                    position[0] = value;\n                    break;\n                case PLYValue.Y:\n                    position[1] = value;\n                    break;\n                case PLYValue.Z:\n                    position[2] = value;\n                    break;\n                case PLYValue.SCALE_0:\n                    scale[0] = Math.exp(value);\n                    break;\n                case PLYValue.SCALE_1:\n                    scale[1] = Math.exp(value);\n                    break;\n                case PLYValue.SCALE_2:\n                    scale[2] = Math.exp(value);\n                    break;\n                case PLYValue.DIFFUSE_RED:\n                    rgba[0] = value;\n                    break;\n                case PLYValue.DIFFUSE_GREEN:\n                    rgba[1] = value;\n                    break;\n                case PLYValue.DIFFUSE_BLUE:\n                    rgba[2] = value;\n                    break;\n                case PLYValue.F_DC_0:\n                    rgba[0] = (0.5 + GaussianSplattingMeshBase._SH_C0 * value) * 255;\n                    break;\n                case PLYValue.F_DC_1:\n                    rgba[1] = (0.5 + GaussianSplattingMeshBase._SH_C0 * value) * 255;\n                    break;\n                case PLYValue.F_DC_2:\n                    rgba[2] = (0.5 + GaussianSplattingMeshBase._SH_C0 * value) * 255;\n                    break;\n                case PLYValue.F_DC_3:\n                    rgba[3] = (0.5 + GaussianSplattingMeshBase._SH_C0 * value) * 255;\n                    break;\n                case PLYValue.OPACITY:\n                    rgba[3] = (1 / (1 + Math.exp(-value))) * 255;\n                    break;\n                case PLYValue.ROT_0:\n                    r0 = value;\n                    break;\n                case PLYValue.ROT_1:\n                    r1 = value;\n                    break;\n                case PLYValue.ROT_2:\n                    r2 = value;\n                    break;\n                case PLYValue.ROT_3:\n                    r3 = value;\n                    break;\n            }\n            if (sh && property.value >= PLYValue.SH_0 && property.value <= PLYValue.SH_71) {\n                const shIndex = property.value - PLYValue.SH_0;\n                if (property.type == PLYType.UCHAR && header.chunkCount) {\n                    // compressed ply. dataView points to beginning of vertex\n                    // could be improved with a direct copy instead of a per SH index computation + copy\n                    const compressedValue = dataView.getUint8(\n                        header.rowChunkLength * header.chunkCount + header.vertexCount * header.rowVertexLength + index * header.shCoefficientCount + shIndex\n                    );\n                    // compressed .ply SH import : https://github.com/playcanvas/engine/blob/fda3f0368b45d7381f0b5a1722bd2056128eaebe/src/scene/gsplat/gsplat-compressed-data.js#L88C81-L88C98\n                    plySH[shIndex] = (compressedValue * (8 / 255) - 4) * 127.5 + 127.5;\n                } else {\n                    const clampedValue = Scalar.Clamp(value * 127.5 + 127.5, 0, 255);\n                    plySH[shIndex] = clampedValue;\n                }\n            }\n        }\n\n        if (sh) {\n            const shDim = header.shDegree == 1 ? 3 : header.shDegree == 2 ? 8 : header.shDegree == 3 ? 15 : 24;\n            for (let j = 0; j < shDim; j++) {\n                sh[j * 3 + 0] = plySH[j];\n                sh[j * 3 + 1] = plySH[j + shDim];\n                sh[j * 3 + 2] = plySH[j + shDim * 2];\n            }\n        }\n\n        q.set(r1, r2, r3, r0);\n        q.normalize();\n        rot[0] = q.w * 127.5 + 127.5;\n        rot[1] = q.x * 127.5 + 127.5;\n        rot[2] = q.y * 127.5 + 127.5;\n        rot[3] = q.z * 127.5 + 127.5;\n        offset.value += header.rowVertexLength;\n    }\n\n    /**\n     * Converts a .ply data with SH coefficients splat\n     * if data array buffer is not ply, returns the original buffer\n     * @param data the .ply data to load\n     * @param useCoroutine use coroutine and yield\n     * @returns the loaded splat buffer and optional array of sh coefficients\n     */\n    public static *ConvertPLYWithSHToSplat(data: ArrayBuffer, useCoroutine = false) {\n        const header = GaussianSplattingMeshBase.ParseHeader(data);\n        if (!header) {\n            return { buffer: data };\n        }\n\n        const offset = { value: 0 };\n        const compressedChunks = GaussianSplattingMeshBase._GetCompressedChunks(header, offset);\n\n        for (let i = 0; i < header.vertexCount; i++) {\n            GaussianSplattingMeshBase._GetSplat(header, i, compressedChunks, offset);\n            if (i % GaussianSplattingMeshBase._PlyConversionBatchSize === 0 && useCoroutine) {\n                yield;\n            }\n        }\n\n        let sh = null;\n        // make SH texture buffers\n        if (header.shDegree && header.shBuffer) {\n            const textureCount = Math.ceil(header.shCoefficientCount / 16); // 4 components can be stored per texture, 4 sh per component\n            let shIndexRead = 0;\n            const ubuf = new Uint8Array(header.shBuffer);\n\n            // sh is an array of uint8array that will be used to create sh textures\n            sh = [];\n\n            const splatCount = header.vertexCount;\n            const engine = EngineStore.LastCreatedEngine;\n            if (engine) {\n                const width = engine.getCaps().maxTextureSize;\n                const height = Math.ceil(splatCount / width);\n                // create array for the number of textures needed.\n                sh = AllocateShBuffers(textureCount, height * width * 4 * 4);\n\n                for (let i = 0; i < splatCount; i++) {\n                    for (let shIndexWrite = 0; shIndexWrite < header.shCoefficientCount; shIndexWrite++) {\n                        const shValue = ubuf[shIndexRead++];\n\n                        const textureIndex = Math.floor(shIndexWrite / 16);\n                        const shArray = sh[textureIndex];\n\n                        const byteIndexInTexture = shIndexWrite % 16; // [0..15]\n                        const offsetPerSplat = i * 16; // 16 sh values per texture per splat.\n                        shArray[byteIndexInTexture + offsetPerSplat] = shValue;\n                    }\n                }\n            }\n        }\n\n        return { buffer: header.buffer, sh: sh, shDegree: header.shDegree };\n    }\n\n    /**\n     * Converts a .ply data array buffer to splat\n     * if data array buffer is not ply, returns the original buffer\n     * @param data the .ply data to load\n     * @param useCoroutine use coroutine and yield\n     * @returns the loaded splat buffer without SH coefficient, whether ply contains or not SH.\n     */\n    public static *ConvertPLYToSplat(data: ArrayBuffer, useCoroutine = false) {\n        const header = GaussianSplattingMeshBase.ParseHeader(data);\n        if (!header) {\n            return data;\n        }\n\n        const offset = { value: 0 };\n        const compressedChunks = GaussianSplattingMeshBase._GetCompressedChunks(header, offset);\n\n        for (let i = 0; i < header.vertexCount; i++) {\n            GaussianSplattingMeshBase._GetSplat(header, i, compressedChunks, offset);\n            if (i % GaussianSplattingMeshBase._PlyConversionBatchSize === 0 && useCoroutine) {\n                yield;\n            }\n        }\n\n        return header.buffer;\n    }\n\n    /**\n     * Converts a .ply data array buffer to splat\n     * if data array buffer is not ply, returns the original buffer\n     * @param data the .ply data to load\n     * @returns the loaded splat buffer\n     */\n    public static async ConvertPLYToSplatAsync(data: ArrayBuffer) {\n        return await runCoroutineAsync(GaussianSplattingMeshBase.ConvertPLYToSplat(data, true), createYieldingScheduler());\n    }\n\n    /**\n     * Converts a .ply with SH data array buffer to splat\n     * if data array buffer is not ply, returns the original buffer\n     * @param data the .ply data to load\n     * @returns the loaded splat buffer with SH\n     */\n    public static async ConvertPLYWithSHToSplatAsync(data: ArrayBuffer) {\n        return await runCoroutineAsync(GaussianSplattingMeshBase.ConvertPLYWithSHToSplat(data, true), createYieldingScheduler());\n    }\n    /**\n     * Loads a .splat Gaussian Splatting array buffer asynchronously\n     * @param data arraybuffer containing splat file\n     * @returns a promise that resolves when the operation is complete\n     */\n\n    public async loadDataAsync(data: ArrayBuffer): Promise<void> {\n        return await this.updateDataAsync(data);\n    }\n\n    /**\n     * Loads a Gaussian or Splatting file asynchronously\n     * @param url path to the splat file to load\n     * @param scene optional scene it belongs to\n     * @returns a promise that resolves when the operation is complete\n     * @deprecated Please use SceneLoader.ImportMeshAsync instead\n     */\n    public async loadFileAsync(url: string, scene?: Scene): Promise<void> {\n        await ImportMeshAsync(url, (scene || EngineStore.LastCreatedScene)!, { pluginOptions: { splat: { gaussianSplattingMesh: this } } });\n    }\n\n    /**\n     * Releases resources associated with this mesh.\n     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)\n     */\n    public override dispose(doNotRecurse?: boolean): void {\n        if (this._mrtAtlas) {\n            // The four data textures are attachments of this MRT — dispose the MRT, not each attachment.\n            this._mrtAtlas.dispose();\n            this._mrtAtlas = null;\n            this._covariancesATexture = this._covariancesBTexture = this._centersTexture = this._colorsTexture = null;\n        } else {\n            this._covariancesATexture?.dispose();\n            this._covariancesBTexture?.dispose();\n            this._centersTexture?.dispose();\n            this._colorsTexture?.dispose();\n        }\n        if (this._shMrtAtlas) {\n            // SH attachments belong to these MRTs — dispose the MRTs, not each attachment (which is _shTextures[k]\n            // for k < _shMrtAtlas.length).\n            for (const mrt of this._shMrtAtlas) {\n                mrt.dispose();\n            }\n            // Defence in depth: free any _shTextures entries beyond the MRT-backed set (not MRT-owned, so the loop\n            // above misses them). The reuse guard keeps the atlas sized correctly, so this is normally a no-op.\n            if (this._shTextures) {\n                for (let k = this._shMrtAtlas.length; k < this._shTextures.length; k++) {\n                    this._shTextures[k].dispose();\n                }\n            }\n            this._shMrtAtlas = null;\n        } else if (this._shTextures) {\n            for (const shTexture of this._shTextures) {\n                shTexture.dispose();\n            }\n        }\n        this._shTextures = null;\n\n        if (this._rotMrtAtlas) {\n            // The three rotation textures are attachments of this MRT — dispose the MRT, not each attachment.\n            this._rotMrtAtlas.dispose();\n            this._rotMrtAtlas = null;\n        } else {\n            this._rotationsATexture?.dispose();\n            this._rotationsBTexture?.dispose();\n            this._rotationScaleTexture?.dispose();\n        }\n        this._sogParams?.codebookTexture?.dispose();\n        this._rotationsATexture = null;\n        this._rotationsBTexture = null;\n        this._rotationScaleTexture = null;\n        this._rotationDataA = null;\n        this._rotationDataB = null;\n        this._rotationScaleData = null;\n        this._covariancesATexture = null;\n        this._covariancesBTexture = null;\n        this._centersTexture = null;\n        this._colorsTexture = null;\n        this._shTextures = null;\n        this._cachedBoundingMin = null;\n        this._cachedBoundingMax = null;\n        // Note: _splatsData and _shData are intentionally kept alive after dispose.\n        // They can still be used as runtime source buffers by a compound mesh that retained\n        // this mesh's data before disposal.\n\n        _ReleaseGsInterFrameYield(this.getEngine());\n        this._worker?.terminate();\n        this._worker = null;\n\n        this.onPartCountChangedObservable.clear();\n        this.onPartRemovedObservable.clear();\n\n        // delete meshes created for each camera\n        this._cameraViewInfos.forEach((cameraViewInfo) => {\n            cameraViewInfo.mesh.dispose();\n        });\n\n        super.dispose(doNotRecurse, true);\n    }\n\n    protected _copyTextures(source: GaussianSplattingMeshBase): void {\n        this._covariancesATexture = source.covariancesATexture?.clone()!;\n        this._covariancesBTexture = source.covariancesBTexture?.clone()!;\n        this._centersTexture = source.centersTexture?.clone()!;\n        this._colorsTexture = source.colorsTexture?.clone()!;\n        if (source._shTextures) {\n            this._shTextures = [];\n            for (const shTexture of source._shTextures) {\n                this._shTextures?.push(shTexture.clone()!);\n            }\n        }\n        if (source._rotationsATexture) {\n            this._rotationsATexture = source._rotationsATexture.clone()!;\n            this._rotationsBTexture = source._rotationsBTexture?.clone()!;\n            this._rotationScaleTexture = source._rotationScaleTexture?.clone()!;\n        }\n    }\n\n    /**\n     * Returns a new Mesh object generated from the current mesh properties.\n     * @param name is a string, the name given to the new mesh\n     * @returns a new Gaussian Splatting Mesh\n     */\n    public override clone(name: string = \"\"): GaussianSplattingMeshBase {\n        const newGS = new GaussianSplattingMeshBase(name, undefined, this.getScene());\n        newGS._copySource(this);\n        newGS.makeGeometryUnique();\n        newGS._vertexCount = this._vertexCount;\n        newGS._copyTextures(this);\n        newGS._modelViewProjectionMatrix = Matrix.Identity();\n        newGS._splatPositions = this._splatPositions;\n        newGS._readyToDisplay = false;\n        newGS._hasRenderedOnce = false;\n        newGS._disableDepthSort = this._disableDepthSort;\n        newGS._instantiateWorker();\n\n        const binfo = this.getBoundingInfo();\n        newGS.getBoundingInfo().reConstruct(binfo.minimum, binfo.maximum, this.getWorldMatrix());\n\n        newGS.forcedInstanceCount = this.forcedInstanceCount;\n        newGS.setEnabled(true);\n        return newGS;\n    }\n\n    protected _makeEmptySplat(index: number, covA: Uint16Array, covB: Uint16Array, colorArray: Uint8Array): void {\n        const covBSItemSize = this._useRGBACovariants ? 4 : 2;\n        this._splatPositions![4 * index + 0] = 0;\n        this._splatPositions![4 * index + 1] = 0;\n        this._splatPositions![4 * index + 2] = 0;\n\n        covA[index * 4 + 0] = ToHalfFloat(0);\n        covA[index * 4 + 1] = ToHalfFloat(0);\n        covA[index * 4 + 2] = ToHalfFloat(0);\n        covA[index * 4 + 3] = ToHalfFloat(0);\n        covB[index * covBSItemSize + 0] = ToHalfFloat(0);\n        covB[index * covBSItemSize + 1] = ToHalfFloat(0);\n        colorArray[index * 4 + 3] = 0;\n    }\n\n    /**\n     * Processes a single splat from the source buffer (at srcIndex) and writes the result into\n     * the destination texture arrays at dstIndex. This decoupling allows addPart to feed multiple\n     * independent source buffers into a single set of destination arrays without merging them first.\n     * @param dstIndex - destination splat index (into _splatPositions, covA, covB, colorArray)\n     * @param fBuffer - float32 view of the source .splat buffer\n     * @param uBuffer - uint8 view of the source .splat buffer\n     * @param covA - destination covariancesA array\n     * @param covB - destination covariancesB array\n     * @param colorArray - destination color array\n     * @param minimum - accumulated bounding minimum (updated in-place)\n     * @param maximum - accumulated bounding maximum (updated in-place)\n     * @param flipY - whether to negate the Y position\n     * @param srcIndex - source splat index (defaults to dstIndex when omitted)\n     * @param dstArrayIndex - index into the covA/covB/colorArray transients (defaults to dstIndex). Lets a streaming\n     * write pass count-sized transients indexed from 0 while dstIndex still addresses the atlas-sized _splatPositions.\n     */\n    protected _makeSplat(\n        dstIndex: number,\n        fBuffer: Float32Array,\n        uBuffer: Uint8Array,\n        covA: Uint16Array,\n        covB: Uint16Array,\n        colorArray: Uint8Array,\n        minimum: Vector3,\n        maximum: Vector3,\n        flipY: boolean,\n        srcIndex: number = dstIndex,\n        dstArrayIndex: number = dstIndex\n    ): void {\n        const matrixRotation = TmpVectors.Matrix[0];\n        const matrixScale = TmpVectors.Matrix[1];\n        const quaternion = TmpVectors.Quaternion[0];\n        const covBSItemSize = this._useRGBACovariants ? 4 : 2;\n\n        const x = fBuffer[8 * srcIndex + 0];\n        const y = fBuffer[8 * srcIndex + 1] * (flipY ? -1 : 1);\n        const z = fBuffer[8 * srcIndex + 2];\n\n        this._splatPositions![4 * dstIndex + 0] = x;\n        this._splatPositions![4 * dstIndex + 1] = y;\n        this._splatPositions![4 * dstIndex + 2] = z;\n\n        minimum.minimizeInPlaceFromFloats(x, y, z);\n        maximum.maximizeInPlaceFromFloats(x, y, z);\n\n        quaternion.set(\n            (uBuffer[32 * srcIndex + 28 + 1] - 127.5) / 127.5,\n            (uBuffer[32 * srcIndex + 28 + 2] - 127.5) / 127.5,\n            (uBuffer[32 * srcIndex + 28 + 3] - 127.5) / 127.5,\n            -(uBuffer[32 * srcIndex + 28 + 0] - 127.5) / 127.5\n        );\n        quaternion.normalize();\n        quaternion.toRotationMatrix(matrixRotation);\n\n        Matrix.ScalingToRef(fBuffer[8 * srcIndex + 3 + 0] * 2, fBuffer[8 * srcIndex + 3 + 1] * 2, fBuffer[8 * srcIndex + 3 + 2] * 2, matrixScale);\n\n        if (this._needsRotationScaleTextures) {\n            // Sized to the atlas (_splatPositions), not covA: these persistent arrays are indexed by the global\n            // dstIndex, so a count-sized covA transient must not shrink them.\n            const rotLength = this._splatPositions!.length;\n            if (!this._rotationDataA || this._rotationDataA.length < rotLength) {\n                this._rotationDataA = new Uint16Array(rotLength);\n                this._rotationDataB = new Uint16Array(rotLength);\n                this._rotationScaleData = new Uint16Array(rotLength);\n            }\n            const rotDataA = this._rotationDataA;\n            const rotDataB = this._rotationDataB!;\n            const rotScaleData = this._rotationScaleData!;\n            const rm = matrixRotation.m;\n            const sm = matrixScale.m;\n            rotDataA[dstIndex * 4 + 0] = ToHalfFloat(rm[0]);\n            rotDataA[dstIndex * 4 + 1] = ToHalfFloat(rm[1]);\n            rotDataA[dstIndex * 4 + 2] = ToHalfFloat(rm[2]);\n            rotDataA[dstIndex * 4 + 3] = ToHalfFloat(rm[4]);\n            rotDataB[dstIndex * 4 + 0] = ToHalfFloat(rm[5]);\n            rotDataB[dstIndex * 4 + 1] = ToHalfFloat(rm[6]);\n            rotDataB[dstIndex * 4 + 2] = ToHalfFloat(rm[8]);\n            rotDataB[dstIndex * 4 + 3] = ToHalfFloat(rm[9]);\n            rotScaleData[dstIndex * 4 + 0] = ToHalfFloat(rm[10]);\n            rotScaleData[dstIndex * 4 + 1] = ToHalfFloat(sm[0]);\n            rotScaleData[dstIndex * 4 + 2] = ToHalfFloat(sm[5]);\n            rotScaleData[dstIndex * 4 + 3] = ToHalfFloat(sm[10]);\n        }\n\n        const m = matrixRotation.multiplyToRef(matrixScale, TmpVectors.Matrix[0]).m;\n\n        const covariances = this._tmpCovariances;\n        covariances[0] = m[0] * m[0] + m[1] * m[1] + m[2] * m[2];\n        covariances[1] = m[0] * m[4] + m[1] * m[5] + m[2] * m[6];\n        covariances[2] = m[0] * m[8] + m[1] * m[9] + m[2] * m[10];\n        covariances[3] = m[4] * m[4] + m[5] * m[5] + m[6] * m[6];\n        covariances[4] = m[4] * m[8] + m[5] * m[9] + m[6] * m[10];\n        covariances[5] = m[8] * m[8] + m[9] * m[9] + m[10] * m[10];\n\n        // normalize covA, covB\n        let factor = -10000;\n        for (let covIndex = 0; covIndex < 6; covIndex++) {\n            factor = Math.max(factor, Math.abs(covariances[covIndex]));\n        }\n\n        this._splatPositions![4 * dstIndex + 3] = factor;\n        const transform = factor;\n\n        covA[dstArrayIndex * 4 + 0] = ToHalfFloat(covariances[0] / transform);\n        covA[dstArrayIndex * 4 + 1] = ToHalfFloat(covariances[1] / transform);\n        covA[dstArrayIndex * 4 + 2] = ToHalfFloat(covariances[2] / transform);\n        covA[dstArrayIndex * 4 + 3] = ToHalfFloat(covariances[3] / transform);\n        covB[dstArrayIndex * covBSItemSize + 0] = ToHalfFloat(covariances[4] / transform);\n        covB[dstArrayIndex * covBSItemSize + 1] = ToHalfFloat(covariances[5] / transform);\n\n        const c0 = covariances[0];\n        const c1 = covariances[1];\n        const c2 = covariances[2];\n        const c3 = covariances[3];\n        const c4 = covariances[4];\n        const c5 = covariances[5];\n        const det3d = c0 * (c3 * c5 - c4 * c4) - c1 * (c1 * c5 - c4 * c2) + c2 * (c1 * c4 - c3 * c2);\n        const splatSize = Math.pow(Math.abs(det3d), 1.0 / 6.0);\n        if (splatSize < this._splatSizeMin) {\n            this._splatSizeMin = splatSize;\n        }\n        if (splatSize > this._splatSizeMax) {\n            this._splatSizeMax = splatSize;\n        }\n\n        // colors\n        colorArray[dstArrayIndex * 4 + 0] = uBuffer[32 * srcIndex + 24 + 0];\n        colorArray[dstArrayIndex * 4 + 1] = uBuffer[32 * srcIndex + 24 + 1];\n        colorArray[dstArrayIndex * 4 + 2] = uBuffer[32 * srcIndex + 24 + 2];\n        colorArray[dstArrayIndex * 4 + 3] = uBuffer[32 * srcIndex + 24 + 3];\n    }\n\n    protected _onUpdateTextures(_textureSize: Vector2) {}\n\n    /**\n     * Called when part index data is received during a data load. Override to store and manage\n     * part index state (e.g. allocating the padded Uint8Array).\n     * No-op in the base class.\n     * @param _partIndices - the raw part indices passed in by the caller\n     * @param _textureLength - the padded texture length (width × height) to allocate into\n     */\n    protected _onIndexDataReceived(_partIndices: Uint8Array, _textureLength: number): void {}\n\n    /**\n     * Called at the start of an incremental texture update, before any splats are processed.\n     * Override to perform incremental-specific setup, such as ensuring the part-index GPU texture\n     * exists before the sub-texture upload begins.\n     * No-op in the base class.\n     * @param _textureSize - current texture dimensions\n     */\n    protected _onIncrementalUpdateStart(_textureSize: Vector2): void {}\n\n    /**\n     * Whether this mesh is in compound mode (has at least one part added via addPart).\n     * Returns `false` in the base class; overridden to return `true` in the compound subclass.\n     * Consumed by the material and depth renderer to toggle compound-specific shader paths.\n     * @internal\n     */\n    public get isCompound(): boolean {\n        return false;\n    }\n\n    protected _setDelayedTextureUpdate(covA: Uint16Array, covB: Uint16Array, colorArray: Uint8Array, sh?: Uint8Array[]): void {\n        this._delayedTextureUpdate = { covA, covB, colors: colorArray, centers: this._splatPositions!, sh };\n    }\n\n    /**\n     * Creates (or recreates) the MRT-backed data atlas at the given size and points the four core data\n     * textures at its attachments. The attachments use the same decoded GS layout as {@link GaussianSplattingWorkBuffer}\n     * — [centers F32, covA HALF_FLOAT, covB HALF_FLOAT, colors U8], all RGBA — so a streaming engine can render\n     * (decode/relayout) directly into the same textures the GS material samples, while static parts CPU-upload\n     * into them via {@link _updateSubTextures}. Covariance B is RGBA here (its extra channels unused), so the\n     * atlas forces {@link _useRGBACovariants}.\n     * @param textureSize atlas dimensions (width, height)\n     */\n    protected _createMrtAtlas(textureSize: Vector2): void {\n        // covB carries only Sigma12/Sigma22 but MRT attachments are RGBA, so switch to the RGBA covariant layout.\n        this._useRGBACovariants = true;\n        const engine = this.getEngine();\n        // No real GPU (NullEngine): skip MRT allocation. The reservation's part/index/range logic still runs;\n        // texture population requires a real (WebGL2/WebGPU) backend.\n        const updateEngine = this._getTextureDataUpdateEngine();\n        if (!updateEngine._gl && !updateEngine.isWebGPU) {\n            return;\n        }\n        const covType = engine.getCaps().textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_FLOAT;\n        const mrt = new MultiRenderTarget(\n            this.name + \"_gsAtlas\",\n            { width: textureSize.x, height: textureSize.y },\n            4,\n            this._scene,\n            {\n                types: [Constants.TEXTURETYPE_FLOAT, covType, covType, Constants.TEXTURETYPE_UNSIGNED_BYTE],\n                formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\n                samplingModes: [\n                    Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n                    Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n                    Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n                    Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n                ],\n                generateDepthBuffer: false,\n                generateDepthTexture: false,\n                generateMipMaps: false,\n            },\n            [this.name + \"_gsCenters\", this.name + \"_gsCovA\", this.name + \"_gsCovB\", this.name + \"_gsColors\"]\n        );\n        mrt.clearColor = new Color4(0, 0, 0, 0);\n        mrt.renderList = [];\n        // Suppress clearing so a streaming engine's decode passes ACCUMULATE into the atlas (each decode writes\n        // only its region and must not wipe static parts or previously-decoded splats). All texels are defined by\n        // the initial full CPU sub-upload below (the reserved region's arrays are zero => invisible padding).\n        mrt.onClearObservable.add(() => {});\n        // Render once so the attachment textures are really allocated on the GPU before the CPU sub-uploads\n        // below (on WebGPU, writeTexture requires the destination texture to already exist).\n        mrt.render();\n        this._mrtAtlas = mrt;\n        this._centersTexture = mrt.textures[0];\n        this._covariancesATexture = mrt.textures[1];\n        this._covariancesBTexture = mrt.textures[2];\n        this._colorsTexture = mrt.textures[3];\n    }\n\n    /**\n     * Creates the shared higher-order SH atlas: `_shMrtAtlasTextureCount` single-attachment integer render targets\n     * (RGBA_INTEGER / UNSIGNED_INTEGER, packed-u32), sized to the whole atlas, so a streaming engine can GPU-decode\n     * baked SH into the reserved region and static SH parts CPU-upload into the same attachments. `_shTextures` (the\n     * draw path's `shTexture0..N` samplers) are the attachments. One MRT per attachment keeps within WebGPU's\n     * per-sample color-attachment byte budget. No-op without a real GPU backend (mirrors {@link _createMrtAtlas}).\n     * @param textureSize atlas dimensions (width, height)\n     */\n    protected _createShMrtAtlas(textureSize: Vector2): void {\n        const updateEngine = this._getTextureDataUpdateEngine();\n        if (!updateEngine._gl && !updateEngine.isWebGPU) {\n            return;\n        }\n        const count = this._shMrtAtlasTextureCount;\n        if (count <= 0) {\n            return;\n        }\n        const mrts: MultiRenderTarget[] = [];\n        const shTextures: BaseTexture[] = [];\n        for (let k = 0; k < count; k++) {\n            const name = `${this.name}_gsShAtlas${k}`;\n            const mrt = new MultiRenderTarget(\n                name,\n                { width: textureSize.x, height: textureSize.y },\n                1,\n                this._scene,\n                {\n                    types: [Constants.TEXTURETYPE_UNSIGNED_INTEGER],\n                    formats: [Constants.TEXTUREFORMAT_RGBA_INTEGER],\n                    samplingModes: [Constants.TEXTURE_NEAREST_SAMPLINGMODE],\n                    generateDepthBuffer: false,\n                    generateDepthTexture: false,\n                    generateMipMaps: false,\n                },\n                [name]\n            );\n            mrt.clearColor = new Color4(0, 0, 0, 0);\n            mrt.renderList = [];\n            // Accumulate: each SH decode writes only its region; the rest stays whatever was there (neutral for a\n            // fresh atlas — 128 == 0 lighting is guaranteed by decoding every splat's region, incl. no-SH files).\n            mrt.onClearObservable.add(() => {});\n            const attachment = mrt.textures[0];\n            attachment.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n            attachment.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n            // Allocate on the GPU before any CPU sub-upload (WebGPU writeTexture needs the resource to exist).\n            mrt.render();\n            mrts.push(mrt);\n            shTextures.push(attachment);\n        }\n        this._shMrtAtlas = mrts;\n        this._shTextures = shTextures;\n    }\n\n    /**\n     * Creates the shared rotation/scale atlas: one 3-attachment half-float render target ([rotA, rotB, rotScale])\n     * sized to the whole atlas, so a streaming engine can GPU-decode rotation/scale into the reserved region and\n     * static parts CPU-upload into the same attachments. `_rotationsATexture`/`_rotationsBTexture`/\n     * `_rotationScaleTexture` (the voxel-IBL samplers) become the three attachments. No-op without a real GPU\n     * backend (mirrors {@link _createMrtAtlas}).\n     * @param textureSize atlas dimensions (width, height)\n     */\n    protected _createRotMrtAtlas(textureSize: Vector2): void {\n        const updateEngine = this._getTextureDataUpdateEngine();\n        if (!updateEngine._gl && !updateEngine.isWebGPU) {\n            return;\n        }\n        const rotType = this.getEngine().getCaps().textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_FLOAT;\n        const name = this.name + \"_gsRotAtlas\";\n        const mrt = new MultiRenderTarget(\n            name,\n            { width: textureSize.x, height: textureSize.y },\n            3,\n            this._scene,\n            {\n                types: [rotType, rotType, rotType],\n                formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA],\n                samplingModes: [Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURE_NEAREST_SAMPLINGMODE],\n                generateDepthBuffer: false,\n                generateDepthTexture: false,\n                generateMipMaps: false,\n            },\n            [name + \"A\", name + \"B\", name + \"Scale\"]\n        );\n        mrt.clearColor = new Color4(0, 0, 0, 0);\n        mrt.renderList = [];\n        // Accumulate: each rotation decode writes only its region; the rest stays whatever was there.\n        mrt.onClearObservable.add(() => {});\n        for (const attachment of mrt.textures) {\n            attachment.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n            attachment.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n        }\n        // Allocate on the GPU before any CPU sub-upload (WebGPU writeTexture needs the resource to exist).\n        mrt.render();\n        this._rotMrtAtlas = mrt;\n        this._rotationsATexture = mrt.textures[0];\n        this._rotationsBTexture = mrt.textures[1];\n        this._rotationScaleTexture = mrt.textures[2];\n    }\n\n    // NB: partIndices is assumed to be padded to a round texture size\n    protected _updateTextures(covA: Uint16Array, covB: Uint16Array, colorArray: Uint8Array, sh?: Uint8Array[]): void {\n        const textureSize = this._getTextureSize(this._vertexCount);\n        // Update the textures\n        const createTextureFromData = (data: Float32Array, width: number, height: number, format: number) => {\n            return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_FLOAT);\n        };\n\n        const createTextureFromDataU8 = (data: Uint8Array, width: number, height: number, format: number) => {\n            return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);\n        };\n\n        const createEmptyTextureU32 = (width: number, height: number, format: number) => {\n            return new RawTexture(null, width, height, format, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_INTEGER);\n        };\n\n        const createTextureFromDataF16 = (data: Uint16Array, width: number, height: number, format: number) => {\n            return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_HALF_FLOAT);\n        };\n\n        const firstTime = this._covariancesATexture === null;\n        const textureSizeChanged = this._textureSize.y != textureSize.y;\n        // The render-backed SH atlas must have one attachment per SH texture the material samples, i.e. sized to the\n        // compound's MERGED SH degree (`sh` spans static + streaming), not just the streaming parts' requested count —\n        // otherwise a lower-degree stream mixed with a higher-degree static part (or a later higher-degree stream)\n        // leaves the atlas undersized. `sh` is always present when a streaming SH part is live (its degree makes it so).\n        if (this._useShMrtAtlas && sh) {\n            this._shMrtAtlasTextureCount = sh.length;\n        }\n        // First streaming-part reservation must convert the existing RawTexture atlas to the MRT-backed atlas,\n        // which requires the full (re)build branch even when the texture height is unchanged. Same for the SH atlas:\n        // a streaming SH part must convert the SH textures to render-targetable integer MRTs (and recreate them when\n        // the required attachment count changes).\n        const needsMrtConversion =\n            (this._useMrtAtlas && !this._mrtAtlas) ||\n            (this._useShMrtAtlas && (!this._shMrtAtlas || this._shMrtAtlas.length !== this._shMrtAtlasTextureCount)) ||\n            (this._useRotMrtAtlas && !this._rotMrtAtlas);\n\n        if (!firstTime && !textureSizeChanged && !needsMrtConversion) {\n            this._setDelayedTextureUpdate(covA, covB, colorArray, sh);\n            const positions = Float32Array.from(this._splatPositions!);\n            const vertexCount = this._vertexCount;\n            if (this._worker) {\n                this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.POSITIONS, positions, vertexCount }, [positions.buffer]);\n                // Re-sync the active interval set in case the source splat count changed.\n                this._postIntervalsToWorker();\n            }\n\n            // Handle SH textures in update path - create if they don't exist. Skip when the SH atlas is\n            // render-backed (_useShMrtAtlas): those targets are created/managed by _createShMrtAtlas, not here.\n            if (sh && !this._shTextures && !this._useShMrtAtlas) {\n                this._shTextures = [];\n                for (let textureIndex = 0; textureIndex < sh.length; textureIndex++) {\n                    const shTexture = createEmptyTextureU32(textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA_INTEGER);\n                    shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    this._shTextures!.push(shTexture);\n                    this._updateShTextureData(shTexture, sh[textureIndex], textureSize.x, 0, textureSize.y);\n                }\n            }\n\n            if (this._needsRotationScaleTextures && this._rotationDataA) {\n                if (this._rotationsATexture) {\n                    this._updateTextureFromData(this._rotationsATexture, this._rotationDataA, textureSize.x, 0, textureSize.y);\n                    this._updateTextureFromData(this._rotationsBTexture!, this._rotationDataB!, textureSize.x, 0, textureSize.y);\n                    this._updateTextureFromData(this._rotationScaleTexture!, this._rotationScaleData!, textureSize.x, 0, textureSize.y);\n                } else {\n                    // Rotation textures not yet created (needsRotationScaleTextures was enabled after initial load).\n                    this._rotationsATexture = createTextureFromDataF16(this._rotationDataA, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                    this._rotationsBTexture = createTextureFromDataF16(this._rotationDataB!, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                    this._rotationScaleTexture = createTextureFromDataF16(this._rotationScaleData!, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                    this._rotationsATexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    this._rotationsATexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    this._rotationsBTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    this._rotationsBTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    this._rotationScaleTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                    this._rotationScaleTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                }\n            }\n\n            this._onUpdateTextures(textureSize);\n\n            this._postToWorker(true);\n        } else {\n            // Full rebuild: the texture size changed (or this is a size-changing reload), so the existing\n            // GPU textures cannot be reused. Dispose them before recreating to avoid leaking the old ones.\n            // Growing an EXISTING MRT atlas: let streaming parts back up their GPU-only region from the old atlas\n            // before it is disposed (they restore it into the new atlas via _onAfterAtlasRebuildObservable).\n            const growingMrtAtlas = this._useMrtAtlas && !!this._mrtAtlas;\n            if (growingMrtAtlas) {\n                this._onBeforeAtlasRebuildObservable.notifyObservers(this._mrtAtlas!);\n            }\n            if (this._mrtAtlas) {\n                // The four data textures are attachments of this MRT — dispose the MRT, not each attachment.\n                this._mrtAtlas.dispose();\n                this._mrtAtlas = null;\n                this._covariancesATexture = this._covariancesBTexture = this._centersTexture = this._colorsTexture = null;\n            } else {\n                this._covariancesATexture?.dispose();\n                this._covariancesBTexture?.dispose();\n                this._centersTexture?.dispose();\n                this._colorsTexture?.dispose();\n            }\n            // Dispose+null the rotation/scale textures before the MRT-branch _updateSubTextures below: that helper\n            // also writes the rotation textures, so leaving them at the old (smaller) height would upload the taller\n            // region out of bounds. Nulling them makes it skip rotation; the block further down recreates them.\n            if (this._rotMrtAtlas) {\n                // The three rotation textures are attachments of this MRT — dispose the MRT, not each attachment.\n                this._rotMrtAtlas.dispose();\n                this._rotMrtAtlas = null;\n                this._rotationsATexture = null;\n                this._rotationsBTexture = null;\n                this._rotationScaleTexture = null;\n            } else if (this._rotationsATexture) {\n                this._rotationsATexture.dispose();\n                this._rotationsBTexture?.dispose();\n                this._rotationScaleTexture?.dispose();\n                this._rotationsATexture = null;\n                this._rotationsBTexture = null;\n                this._rotationScaleTexture = null;\n            }\n            if (this._shTextures) {\n                // SH attachments belong to _shMrtAtlas MRTs (dispose the MRT, not each attachment) when render-backed.\n                if (this._shMrtAtlas) {\n                    for (const mrt of this._shMrtAtlas) {\n                        mrt.dispose();\n                    }\n                    // Defence in depth: free any _shTextures entries beyond the MRT-backed set (see dispose()).\n                    for (let k = this._shMrtAtlas.length; k < this._shTextures.length; k++) {\n                        this._shTextures[k].dispose();\n                    }\n                    this._shMrtAtlas = null;\n                } else {\n                    for (const shTexture of this._shTextures) {\n                        shTexture.dispose();\n                    }\n                }\n                this._shTextures = null;\n            }\n\n            this._textureSize = textureSize;\n            if (this._useMrtAtlas) {\n                // Back the four data textures with a render-targetable MRT so a streaming engine can decode\n                // into the reserved region; static splats are CPU-uploaded into the same attachments below.\n                this._createMrtAtlas(textureSize);\n                // Same for the higher-order SH atlas (integer render targets), when a streaming part needs baked SH.\n                if (this._useShMrtAtlas) {\n                    this._createShMrtAtlas(textureSize);\n                }\n                // Same for the rotation/scale atlas (half-float), created before the _updateSubTextures below so\n                // static parts' CPU rotation data lands in the shared attachments (streamed rows are decoded after).\n                if (this._useRotMrtAtlas) {\n                    this._createRotMrtAtlas(textureSize);\n                }\n                if (this._mrtAtlas) {\n                    this._updateSubTextures(this._splatPositions!, covA, covB, colorArray, 0, textureSize.y);\n                    // Render-backed SH: CPU-upload the static parts' SH into the shared SH atlas HERE — before the\n                    // streaming restore below — so a streamed region's restored SH wins over the bulk (neutral) fill,\n                    // exactly like the core atlas's _updateSubTextures-then-restore ordering. (`sh` covers the whole\n                    // atlas; streamed rows are neutral in it and get overwritten by the restore.)\n                    if (this._useShMrtAtlas && sh) {\n                        const shTex = this._shTextures as Nullable<BaseTexture[]>;\n                        if (shTex) {\n                            for (let textureIndex = 0; textureIndex < sh.length && textureIndex < shTex.length; textureIndex++) {\n                                this._updateShTextureData(shTex[textureIndex], sh[textureIndex], textureSize.x, 0, textureSize.y);\n                            }\n                        }\n                    }\n                    // New atlas is populated (streamed regions currently zeroed); let streaming parts rebind and\n                    // restore their backed-up region into it, overwriting those zeros with the preserved data.\n                    if (growingMrtAtlas) {\n                        this._onAfterAtlasRebuildObservable.notifyObservers(this._mrtAtlas);\n                    }\n                }\n            } else {\n                this._covariancesATexture = createTextureFromDataF16(covA, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                this._covariancesBTexture = createTextureFromDataF16(\n                    covB,\n                    textureSize.x,\n                    textureSize.y,\n                    this._useRGBACovariants ? Constants.TEXTUREFORMAT_RGBA : Constants.TEXTUREFORMAT_RG\n                );\n                this._centersTexture = createTextureFromData(this._splatPositions!, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                this._colorsTexture = createTextureFromDataU8(colorArray, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n            }\n\n            // Render-backed SH (_useShMrtAtlas) was already CPU-uploaded above (before the streaming restore); only\n            // the plain RawTexture SH path is handled here.\n            if (sh && !this._useShMrtAtlas) {\n                {\n                    this._shTextures = [];\n                    for (let textureIndex = 0; textureIndex < sh.length; textureIndex++) {\n                        const shTexture = createEmptyTextureU32(textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA_INTEGER);\n                        shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                        shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                        this._shTextures!.push(shTexture);\n                    }\n                    for (let textureIndex = 0; textureIndex < sh.length; textureIndex++) {\n                        this._updateShTextureData(this._shTextures[textureIndex], sh[textureIndex], textureSize.x, 0, textureSize.y);\n                    }\n                }\n            }\n\n            // Render-backed rotation (_useRotMrtAtlas) was already created + CPU-uploaded above (via _updateSubTextures,\n            // before the streaming restore); only the plain RawTexture rotation path is handled here.\n            if (this._needsRotationScaleTextures && !this._useRotMrtAtlas) {\n                const rotDataA = this._rotationDataA ?? new Uint16Array(covA.length);\n                const rotDataB = this._rotationDataB ?? new Uint16Array(covA.length);\n                const rotScaleData = this._rotationScaleData ?? new Uint16Array(covA.length);\n                // Already disposed+nulled in the rebuild's disposal block above; just (re)create at the new size.\n                this._rotationsATexture = createTextureFromDataF16(rotDataA, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                this._rotationsBTexture = createTextureFromDataF16(rotDataB, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                this._rotationScaleTexture = createTextureFromDataF16(rotScaleData, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);\n                this._rotationsATexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                this._rotationsATexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                this._rotationsBTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                this._rotationsBTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                this._rotationScaleTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n                this._rotationScaleTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\n            }\n\n            this._onUpdateTextures(textureSize);\n\n            if (firstTime) {\n                this._instantiateWorker();\n            } else {\n                if (this._worker) {\n                    const positions = Float32Array.from(this._splatPositions!);\n                    const vertexCount = this._vertexCount;\n                    this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.POSITIONS, positions, vertexCount }, [positions.buffer]);\n                    // Re-sync the active interval set in case the source splat count changed.\n                    this._postIntervalsToWorker();\n                }\n                this._postToWorker(true);\n            }\n        }\n    }\n\n    /**\n     * Checks whether the GPU textures can be incrementally updated for a new addPart operation,\n     * avoiding a full texture re-upload for existing splats.\n     * Requires that the GPU textures already exist and the texture height won't change.\n     * @param previousVertexCount - The number of splats previously committed to GPU\n     * @param vertexCount - The new total number of splats\n     * @param requiredShTextureCount - SH texture count this update requires (the merged `sh.length`), 0 when no SH\n     * @returns true when only the new splat region needs to be uploaded\n     */\n    protected _canReuseCachedData(previousVertexCount: number, vertexCount: number, requiredShTextureCount: number = 0): boolean {\n        if (previousVertexCount <= 0 || previousVertexCount > vertexCount) {\n            return false;\n        }\n        if (this._splatPositions === null || this._cachedBoundingMin === null || this._cachedBoundingMax === null) {\n            return false;\n        }\n        if (this._covariancesATexture === null) {\n            return false;\n        }\n        // Switching to (or resizing) a render-backed atlas requires a full rebuild so the affected textures are\n        // recreated as MRT attachments — the incremental sub-upload path cannot convert them. These must mirror the\n        // `needsMrtConversion` checks in _updateTextures: if they disagree, an incremental data prep (which fills only\n        // the new splats) would be paired with a full-rebuild upload (which uploads the whole array), zeroing the\n        // existing parts. Covers the first streaming reservation, a later part that introduces/grows SH, and rotation.\n        if (this._useMrtAtlas && !this._mrtAtlas) {\n            return false;\n        }\n        // Compare against the count this update requires, not `_shMrtAtlasTextureCount` — that field is refreshed\n        // only in _updateTextures (skipped on the incremental path), so a higher-degree addPart would pass the guard\n        // on a stale count and never grow the SH atlas.\n        if (this._useShMrtAtlas && (!this._shMrtAtlas || this._shMrtAtlas.length !== requiredShTextureCount)) {\n            return false;\n        }\n        if (this._useRotMrtAtlas && !this._rotMrtAtlas) {\n            return false;\n        }\n        // Can only do an incremental GPU update if texture height doesn't need to grow\n        const newTextureSize = this._getTextureSize(vertexCount);\n        return newTextureSize.y === this._textureSize.y;\n    }\n\n    /**\n     * Posts updated positions to the sort worker and marks the sort as dirty.\n     * Called after processing new splats so the worker can re-sort with the complete position set.\n     * Subclasses (e.g. compound) may override to additionally post part-index data.\n     */\n    protected _notifyWorkerNewData(): void {\n        if (this._worker) {\n            const positions = Float32Array.from(this._splatPositions!);\n            const vertexCount = this._vertexCount;\n            this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.POSITIONS, positions, vertexCount }, [positions.buffer]);\n            // The source splat count may have changed (e.g. addPart): re-sync the worker's active\n            // interval set so it covers the current splats instead of a stale (smaller) range.\n            this._postIntervalsToWorker();\n        }\n        this._sortIsDirty = true;\n    }\n\n    /**\n     * Patches only a contiguous range of source-splat centers in the sort worker, instead of re-copying and\n     * transferring the entire position buffer (which is hundreds of MB for large streamed datasets and caused\n     * a multi-frame freeze on every LOD decode). The worker must already hold a full-size position buffer (from\n     * the initial {@link GaussianSplattingSortWorkerCommand.POSITIONS} message at worker creation). Marks the\n     * sort dirty so the new splats are sorted in; the caller is responsible for any interval/range refresh.\n     * @param splatOffset first splat index of the updated range\n     * @param splatCount number of splats in the updated range\n     */\n    protected _postWorkerPositionsRange(splatOffset: number, splatCount: number): void {\n        if (!this._worker || !this._splatPositions || splatCount <= 0) {\n            return;\n        }\n        const floatOffset = splatOffset * 4;\n        // Copy just the changed region (stride 4) so the main thread keeps its own _splatPositions intact.\n        const data = this._splatPositions.slice(floatOffset, floatOffset + splatCount * 4);\n        this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.POSITIONS_UPDATE, offset: floatOffset, data }, [data.buffer]);\n        this._sortIsDirty = true;\n    }\n\n    /**\n     * Decodes raw `.splat` bytes (32 bytes/splat) into a contiguous sub-range of the already-allocated atlas,\n     * uploading only the affected texels (never touching neighboring parts' texels) and patching just that\n     * range of positions in the sort worker. Used to populate a region reserved by\n     * {@link GaussianSplattingMesh.reserveStreamingPart} — the CPU path a streaming engine uses when GPU\n     * decode/readback is unavailable, and the seam that verifies reservation + interleaving before the\n     * streaming engine exists.\n     *\n     * The atlas textures and `_splatPositions` must already be sized to cover `[globalOffset, globalOffset+count)`\n     * (guaranteed after `reserveStreamingPart`). Bounds of the written centers are accumulated into `min`/`max`\n     * when provided (so the caller can grow the owning part's bounding info).\n     * @param globalOffset first atlas splat index to write\n     * @param count number of splats to write\n     * @param splatsData raw `.splat` bytes for `count` splats (stride 32)\n     * @param min optional running min accumulator for the written centers\n     * @param max optional running max accumulator for the written centers\n     */\n    protected _writeStreamingSplats(globalOffset: number, count: number, splatsData: ArrayBuffer | ArrayBufferView, min?: Vector3, max?: Vector3): void {\n        if (!this._splatPositions) {\n            return;\n        }\n        // Validate the range against the atlas and the input length (independent of GPU state): an out-of-range\n        // offset/count would write over another part's texels or allocate a huge transient (the CPU arrays are\n        // atlas-indexed up to `end`); a short input would read past its end.\n        const capacity = this._splatPositions.length / 4;\n        const uBuffer = GaussianSplattingMeshBase._GetSplatDataBytes(splatsData);\n        if (!Number.isInteger(globalOffset) || !Number.isInteger(count) || globalOffset < 0 || count < 0 || globalOffset + count > capacity) {\n            throw new Error(`_writeStreamingSplats: range [${globalOffset}, ${globalOffset + count}) is outside the atlas bounds [0, ${capacity})`);\n        }\n        if (uBuffer.length < count * 32) {\n            throw new Error(`_writeStreamingSplats: splatsData has ${uBuffer.length} bytes, need ${count * 32} for ${count} splats (stride 32)`);\n        }\n        if (count === 0 || !this._covariancesATexture) {\n            return;\n        }\n        const textureSize = this._getTextureSize(this._vertexCount);\n        const width = textureSize.x;\n        const covBSItemSize = this._useRGBACovariants ? 4 : 2;\n        const end = globalOffset + count;\n\n        const fBuffer = GaussianSplattingMeshBase._GetSplatDataFloats(splatsData);\n\n        // Transients are sized to `count`, not `end` (globalOffset + count): sizing by atlas position would allocate\n        // tens of MB for a small write near a large atlas's tail. dstIndex still addresses the atlas _splatPositions.\n        const covA = new Uint16Array(count * 4);\n        const covB = new Uint16Array(count * covBSItemSize);\n        const colorArray = new Uint8Array(count * 4);\n        const localMin = min ?? new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\n        const localMax = max ?? new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n        for (let i = 0; i < count; i++) {\n            this._makeSplat(globalOffset + i, fBuffer, uBuffer, covA, covB, colorArray, localMin, localMax, this._flipY, i, i);\n        }\n\n        // Retain the written bytes so future full rebuilds / picking see the region's real data.\n        if (this._splatsData) {\n            const dst = new Uint8Array(GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData).buffer);\n            dst.set(uBuffer.subarray(0, count * 32), globalOffset * 32);\n        }\n\n        // Upload only the written texels, one contiguous per-row run at a time (rectangular sub-uploads never\n        // clobber texels outside [globalOffset, end), so neighboring parts on a shared boundary row are safe).\n        const positions = this._splatPositions;\n        let gi = globalOffset;\n        while (gi < end) {\n            const row = Math.floor(gi / width);\n            const runEnd = Math.min(end, (row + 1) * width);\n            const col = gi - row * width;\n            const runLen = runEnd - gi;\n            // covA/covB/colorArray are count-sized (0-based), so rebase by globalOffset; positions stays global.\n            const li = gi - globalOffset;\n            this._updateTextureFromDataRect(this._covariancesATexture!, new Uint16Array(covA.buffer, li * 4 * 2, runLen * 4), col, row, runLen, 1);\n            this._updateTextureFromDataRect(this._covariancesBTexture!, new Uint16Array(covB.buffer, li * covBSItemSize * 2, runLen * covBSItemSize), col, row, runLen, 1);\n            this._updateTextureFromDataRect(this._centersTexture!, new Float32Array(positions.buffer, gi * 4 * 4, runLen * 4), col, row, runLen, 1);\n            this._updateTextureFromDataRect(this._colorsTexture!, new Uint8Array(colorArray.buffer, li * 4, runLen * 4), col, row, runLen, 1);\n            gi = runEnd;\n        }\n\n        this._postWorkerPositionsRange(globalOffset, count);\n    }\n\n    private *_updateData(\n        data: ArrayBuffer,\n        isAsync: boolean,\n        sh?: Uint8Array[],\n        partIndices?: Uint8Array,\n        { flipY = false, previousVertexCount = 0 }: IUpdateOptions = {},\n        shDegree?: number\n    ): Coroutine<void> {\n        if (!this._covariancesATexture) {\n            this._readyToDisplay = false;\n        }\n        this._flipY = flipY;\n\n        const uBuffer = new Uint8Array(data);\n        const fBuffer = new Float32Array(uBuffer.buffer);\n\n        // Optionally store the raw splat buffer as an ArrayBuffer. This is the source reference\n        // used by _addPartsInternal when a full texture rebuild is needed. Use uBuffer.buffer as\n        // the canonical backing store — it is always a tightly packed ArrayBuffer containing\n        // exactly the bytes we processed, avoiding issues with ArrayBufferView.byteOffset.\n        if (this._keepInRam || this._alwaysRetainSplatsData) {\n            this._splatsData = uBuffer.buffer;\n            this._shData = sh ? sh.map((arr) => new Uint8Array(arr)) : null;\n        } else {\n            this._splatsData = null;\n            this._shData = null;\n        }\n\n        const vertexCount = uBuffer.length / GaussianSplattingMeshBase._RowOutputLength;\n        if (vertexCount != this._vertexCount) {\n            // The source set changed: drop any active range filter so the buffers resize to the full\n            // set. Callers (e.g. streaming LOD) re-apply their ranges after the data is committed.\n            this._activeSplatRanges = null;\n            this._activeSplatRangeKey = \"\";\n            this._activeSplatRenderCount = 0;\n            this._updateSplatIndexBuffer(vertexCount);\n        }\n        this._vertexCount = vertexCount;\n        this._maxShDegree = sh ? (shDegree ?? 0) : 0;\n        this._shDegree = this._maxShDegree;\n\n        const textureSize = this._getTextureSize(vertexCount);\n        const textureLength = textureSize.x * textureSize.y;\n        const lineCountUpdate = GaussianSplattingMeshBase.ProgressiveUpdateAmount ?? textureSize.y;\n\n        // Delegate part index storage to subclasses (e.g. GaussianSplattingMesh compound mode).\n        if (partIndices) {\n            this._onIndexDataReceived(partIndices, textureLength);\n        }\n\n        const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\n        const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\n\n        const covBSItemSize = this._useRGBACovariants ? 4 : 2;\n        const covA = new Uint16Array(textureLength * 4);\n        const covB = new Uint16Array(covBSItemSize * textureLength);\n        const colorArray = new Uint8Array(textureLength * 4);\n\n        // Incremental path: only upload the rows that contain new splats, leaving the already-committed\n        // GPU region untouched. Falls through to the full-rebuild path when textures don't exist yet\n        // or the texture height needs to grow.\n        const incremental = this._canReuseCachedData(previousVertexCount, vertexCount, sh?.length ?? 0);\n\n        if (!incremental) {\n            this._splatSizeMin = Infinity;\n            this._splatSizeMax = -Infinity;\n        }\n\n        // The first texture line/texel that must be (re-)processed and uploaded.\n        // For a full rebuild this is 0. For an incremental update it is the row boundary just before\n        // previousVertexCount so that any partial old row is re-processed as a complete row.\n        const firstNewLine = incremental ? Math.floor(previousVertexCount / textureSize.x) : 0;\n        const firstNewTexel = firstNewLine * textureSize.x;\n\n        // Preserve old positions before replacing the array (incremental only)\n        const oldPositions = this._splatPositions;\n        this._splatPositions = new Float32Array(4 * textureLength);\n\n        if (incremental) {\n            this._splatPositions.set(oldPositions!.subarray(0, previousVertexCount * 4));\n            minimum.copyFrom(this._cachedBoundingMin!);\n            maximum.copyFrom(this._cachedBoundingMax!);\n            // Let subclasses handle any incremental-specific setup (e.g. ensuring part-index textures)\n            this._onIncrementalUpdateStart(textureSize);\n        }\n\n        if (GaussianSplattingMeshBase.ProgressiveUpdateAmount) {\n            // Full rebuild: create GPU textures upfront with empty data; the loop fills them in batches via _updateSubTextures\n            if (!incremental) {\n                this._updateTextures(covA, covB, colorArray, sh);\n            }\n            this.setEnabled(true);\n\n            const partCount = Math.ceil(textureSize.y / lineCountUpdate);\n            for (let partIndex = 0; partIndex < partCount; partIndex++) {\n                const updateLine = partIndex * lineCountUpdate;\n                const batchEndLine = Math.min(updateLine + lineCountUpdate, textureSize.y);\n\n                // Skip batches that lie entirely within the already-committed GPU region\n                if (batchEndLine <= firstNewLine) {\n                    continue;\n                }\n\n                // Clip upload start to firstNewLine to avoid overwriting committed data with zeros\n                const uploadStartLine = Math.max(updateLine, firstNewLine);\n                const uploadStartTexel = uploadStartLine * textureSize.x;\n                const batchEndTexel = batchEndLine * textureSize.x;\n\n                for (let splatIdx = uploadStartTexel; splatIdx < batchEndTexel; splatIdx++) {\n                    if (splatIdx < vertexCount) {\n                        this._makeSplat(splatIdx, fBuffer, uBuffer, covA, covB, colorArray, minimum, maximum, flipY);\n                    } else {\n                        this._makeEmptySplat(splatIdx, covA, covB, colorArray);\n                    }\n                }\n\n                this._updateSubTextures(this._splatPositions, covA, covB, colorArray, uploadStartLine, batchEndLine - uploadStartLine, sh);\n                this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());\n                if (isAsync) {\n                    yield;\n                }\n            }\n\n            this._notifyWorkerNewData();\n        } else {\n            // Process splats from firstNewTexel: re-processes the partial old row (incremental) or processes everything from 0 (full rebuild)\n            for (let i = firstNewTexel; i < vertexCount; i++) {\n                this._makeSplat(i, fBuffer, uBuffer, covA, covB, colorArray, minimum, maximum, flipY);\n                if (isAsync && i % GaussianSplattingMeshBase._SplatBatchSize === 0) {\n                    yield;\n                }\n            }\n\n            // Incremental pads the full texture; full rebuild pads only to the next 16-splat boundary\n            const paddedEnd = incremental ? textureLength : (vertexCount + 15) & ~0xf;\n            for (let i = vertexCount; i < paddedEnd; i++) {\n                this._makeEmptySplat(i, covA, covB, colorArray);\n            }\n\n            if (incremental) {\n                // Partial upload: only rows from firstNewLine onwards; existing rows stay on GPU\n                this._updateSubTextures(this._splatPositions, covA, covB, colorArray, firstNewLine, textureSize.y - firstNewLine, sh);\n                this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());\n                this.setEnabled(true);\n                this._notifyWorkerNewData();\n            } else {\n                // Full upload: create or replace all GPU textures\n                this._updateTextures(covA, covB, colorArray, sh);\n                this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());\n                this.setEnabled(true);\n                this._sortIsDirty = true;\n            }\n        }\n\n        // Cache bounding box for the next incremental addPart call\n        this._cachedBoundingMin = minimum.clone();\n        this._cachedBoundingMax = maximum.clone();\n\n        this._postToWorker(true);\n    }\n\n    /**\n     * Update asynchronously the buffer\n     * @param data array buffer containing center, color, orientation and scale of splats\n     * @param sh optional array of uint8 array for SH data\n     * @param partIndices optional array of uint8 for rig node indices\n     * @param shDegree optional SH degree of the data\n     * @returns a promise\n     */\n    public async updateDataAsync(data: ArrayBuffer, sh?: Uint8Array[], partIndices?: Uint8Array, shDegree?: number): Promise<void> {\n        return await runCoroutineAsync(this._updateData(data, true, sh, partIndices, undefined, shDegree), createYieldingScheduler());\n    }\n\n    /**\n     * @experimental\n     * Update data from GS (position, orientation, color, scaling)\n     * @param data array that contain all the datas\n     * @param sh optional array of uint8 array for SH data\n     * @param options optional informations on how to treat data (needs to be 3rd for backward compatibility)\n     * @param partIndices optional array of uint8 for rig node indices\n     * @param shDegree optional SH degree of the data\n     */\n    public updateData(data: ArrayBuffer, sh?: Uint8Array[], options: IUpdateOptions = { flipY: true }, partIndices?: Uint8Array, shDegree?: number): void {\n        runCoroutineSync(this._updateData(data, false, sh, partIndices, options, shDegree));\n    }\n\n    /**\n     * Refreshes the bounding info, taking into account all the thin instances defined\n     * @returns the current Gaussian Splatting\n     */\n    public override refreshBoundingInfo(): Mesh {\n        this.thinInstanceRefreshBoundingInfo(false);\n        return this;\n    }\n\n    // in case size is different\n    protected _updateSplatIndexBuffer(vertexCount: number): void {\n        const renderedSplatCount = this._activeSplatRanges ? this._activeSplatRenderCount : vertexCount;\n        const paddedVertexCount = Math.max((renderedSplatCount + 15) & ~0xf, 16);\n\n        const previousIndex = this._splatIndex;\n\n        if (!previousIndex || paddedVertexCount !== previousIndex.length) {\n            this._splatIndex = new Float32Array(paddedVertexCount);\n\n            // update meshes for knowns cameras\n            this._cameraViewInfos.forEach((cameraViewInfos) => {\n                cameraViewInfos.mesh.thinInstanceSetBuffer(\"splatIndex\", this._splatIndex, 16, false);\n            });\n        }\n\n        const splatIndex = this._splatIndex!;\n\n        // Populate the buffer with the current active source indices (identity when unfiltered) so every\n        // rendered slot points at a valid splat. This is the synchronous (no async sort worker) path; the\n        // worker path instead defers the index-buffer swap until a matching sort lands (see _onWorkerCreated).\n        if (this._activeSplatRanges) {\n            let index = 0;\n            for (let rangeIndex = 0; rangeIndex < this._activeSplatRanges.length; rangeIndex += 2) {\n                const start = this._activeSplatRanges[rangeIndex];\n                const count = this._activeSplatRanges[rangeIndex + 1];\n                for (let sourceIndex = start; sourceIndex < start + count; sourceIndex++) {\n                    splatIndex[index++] = sourceIndex;\n                }\n            }\n            // Pad with `vertexCount` itself, not 0: splat 0 is real data, not a reserved empty slot, and\n            // range filtering can leave it fully visible — see gaussianSplattingSortWorker.ts.\n            for (; index < paddedVertexCount; index++) {\n                splatIndex[index] = vertexCount;\n            }\n        } else {\n            for (let i = 0; i < paddedVertexCount; i++) {\n                splatIndex[i] = i;\n            }\n        }\n\n        // Update depthMix\n        if ((!this._depthMix || paddedVertexCount !== this._depthMix.length) && !IsNative) {\n            this._depthMix = new BigInt64Array(paddedVertexCount);\n        }\n\n        this.forcedInstanceCount = Math.max(paddedVertexCount >> 4, 1);\n    }\n\n    protected _updateTextureFromData = (texture: BaseTexture, data: ArrayBufferView, width: number, lineStart: number, lineCount: number) => {\n        const engine = this._getTextureDataUpdateEngine();\n        engine.updateTextureData(texture.getInternalTexture()!, data, 0, lineStart, width, lineCount, 0, 0, false);\n    };\n\n    protected _updateTextureFromDataRect = (texture: BaseTexture, data: ArrayBufferView, xOffset: number, yOffset: number, width: number, height: number) => {\n        const engine = this._getTextureDataUpdateEngine();\n        engine.updateTextureData(texture.getInternalTexture()!, data, xOffset, yOffset, width, height, 0, 0, false);\n    };\n\n    protected _getTextureDataUpdateEngine(): ITextureDataUpdateCapableEngine {\n        return this.getEngine() as unknown as ITextureDataUpdateCapableEngine;\n    }\n\n    protected _updateShTextureData(texture: BaseTexture, shData: Uint8Array, textureWidth: number, lineStart: number, lineCount: number): void {\n        const engine = this._getTextureDataUpdateEngine();\n\n        // NativeEngine/NullEngine, updateTextureData unsupported\n        if (!engine._gl && !engine.isWebGPU) {\n            const internalTexture = texture.getInternalTexture()!;\n            const expectedByteLength = textureWidth * internalTexture.height * 16;\n            let uploadData: Uint32Array;\n            if (shData.byteLength === expectedByteLength && shData.byteOffset % Uint32Array.BYTES_PER_ELEMENT === 0) {\n                uploadData = new Uint32Array(shData.buffer, shData.byteOffset, shData.byteLength / Uint32Array.BYTES_PER_ELEMENT);\n            } else {\n                const padded = new Uint8Array(expectedByteLength);\n                padded.set(shData.subarray(0, Math.min(shData.byteLength, expectedByteLength)));\n                uploadData = new Uint32Array(padded.buffer);\n            }\n            engine.updateRawTexture(internalTexture, uploadData, internalTexture.format, internalTexture.invertY, null, internalTexture.type, internalTexture._useSRGBBuffer);\n            return;\n        }\n\n        const bytesPerTexel = 16;\n        const componentsPerTexel = 4;\n        const startTexel = lineStart * textureWidth;\n        const availableTexelCount = Math.floor(shData.byteLength / bytesPerTexel);\n\n        if (startTexel >= availableTexelCount) {\n            return;\n        }\n\n        let texelCount = Math.min(lineCount * textureWidth, availableTexelCount - startTexel);\n        if (texelCount <= 0) {\n            return;\n        }\n\n        const createView = (byteOffset: number, viewTexelCount: number) => {\n            return new Uint32Array(shData.buffer, shData.byteOffset + byteOffset, viewTexelCount * componentsPerTexel);\n        };\n\n        const fullRowCount = Math.floor(texelCount / textureWidth);\n        if (fullRowCount > 0) {\n            const fullRowTexelCount = fullRowCount * textureWidth;\n            this._updateTextureFromData(texture, createView(startTexel * bytesPerTexel, fullRowTexelCount), textureWidth, lineStart, fullRowCount);\n            texelCount -= fullRowTexelCount;\n        }\n\n        if (texelCount > 0) {\n            const partialRowOffset = (startTexel + fullRowCount * textureWidth) * bytesPerTexel;\n            this._updateTextureFromDataRect(texture, createView(partialRowOffset, texelCount), 0, lineStart + fullRowCount, texelCount, 1);\n        }\n    }\n\n    protected _updateSubTextures(centers: Float32Array, covA: Uint16Array, covB: Uint16Array, colors: Uint8Array, lineStart: number, lineCount: number, sh?: Uint8Array[]): void {\n        const textureSize = this._getTextureSize(this._vertexCount);\n        const covBSItemSize = this._useRGBACovariants ? 4 : 2;\n        const texelStart = lineStart * textureSize.x;\n        const texelCount = lineCount * textureSize.x;\n        const covAView = new Uint16Array(covA.buffer, texelStart * 4 * Uint16Array.BYTES_PER_ELEMENT, texelCount * 4);\n        const covBView = new Uint16Array(covB.buffer, texelStart * covBSItemSize * Uint16Array.BYTES_PER_ELEMENT, texelCount * covBSItemSize);\n        const colorsView = new Uint8Array(colors.buffer, texelStart * 4, texelCount * 4);\n        const centersView = new Float32Array(centers.buffer, texelStart * 4 * Float32Array.BYTES_PER_ELEMENT, texelCount * 4);\n        this._updateTextureFromData(this._covariancesATexture!, covAView, textureSize.x, lineStart, lineCount);\n        this._updateTextureFromData(this._covariancesBTexture!, covBView, textureSize.x, lineStart, lineCount);\n        this._updateTextureFromData(this._centersTexture!, centersView, textureSize.x, lineStart, lineCount);\n        this._updateTextureFromData(this._colorsTexture!, colorsView, textureSize.x, lineStart, lineCount);\n        if (this._rotationsATexture && this._rotationDataA) {\n            const rotAView = new Uint16Array(this._rotationDataA.buffer, texelStart * 4 * Uint16Array.BYTES_PER_ELEMENT, texelCount * 4);\n            const rotBView = new Uint16Array(this._rotationDataB!.buffer, texelStart * 4 * Uint16Array.BYTES_PER_ELEMENT, texelCount * 4);\n            const rotScaleView = new Uint16Array(this._rotationScaleData!.buffer, texelStart * 4 * Uint16Array.BYTES_PER_ELEMENT, texelCount * 4);\n            this._updateTextureFromData(this._rotationsATexture, rotAView, textureSize.x, lineStart, lineCount);\n            this._updateTextureFromData(this._rotationsBTexture!, rotBView, textureSize.x, lineStart, lineCount);\n            this._updateTextureFromData(this._rotationScaleTexture!, rotScaleView, textureSize.x, lineStart, lineCount);\n        }\n        if (sh) {\n            for (let i = 0; i < sh.length; i++) {\n                this._updateShTextureData(this._shTextures![i], sh[i], textureSize.x, lineStart, lineCount);\n            }\n        }\n    }\n\n    protected _instantiateWorker(): void {\n        if (!this._vertexCount) {\n            return;\n        }\n        // The identity index buffer must exist even when no sort worker is needed: every render path\n        // (including the Native one) reads it, and a null buffer breaks the Native bindings.\n        this._updateSplatIndexBuffer(this._vertexCount);\n        if (this._disableDepthSort) {\n            return;\n        }\n\n        // no worker in native\n        if (IsNative) {\n            return;\n        }\n\n        // Start the worker thread\n        this._worker?.terminate();\n        // Reset the posting gate so the new worker can immediately receive sort requests.\n        // If the previous worker was terminated mid-sort it would never have set _canPostToWorker\n        // back to true, leaving the sort permanently frozen on the new worker.\n        this._canPostToWorker = true;\n        this._worker = new Worker(\n            URL.createObjectURL(\n                new Blob([\"(\", GaussianSplattingSortWorker.toString(), \")(self)\"], {\n                    type: \"application/javascript\",\n                })\n            )\n        );\n\n        const positions = Float32Array.from(this._splatPositions!);\n        const vertexCount = this._vertexCount;\n\n        this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.POSITIONS, positions, vertexCount }, [positions.buffer]);\n        // The main thread owns the active interval set: send it explicitly (covering all indices when\n        // no LOD filter is active) rather than letting the worker assume the full source set.\n        this._postIntervalsToWorker();\n        this._onWorkerCreated(this._worker!);\n\n        this._worker.onerror = () => {\n            // If the worker throws an unhandled error, unlock the posting gate so the next frame can retry the sort.\n            this._canPostToWorker = true;\n        };\n\n        this._worker.onmessage = (e) => {\n            // Size the result against the active (rendered) splat count, which may be a subset of the\n            // full source set when an interval/LOD filter is active.\n            const renderedPadded = Math.max((this.renderedSplatCount + 15) & ~0xf, 16);\n\n            // Discard the result and trigger a fresh sort if it no longer matches the current active set:\n            // either the active count changed since it was posted, or it was computed for a stale range\n            // version (the active ranges changed while it was in flight). Applying it would render indices\n            // that belong to a different active set.\n            if (e.data.depthMix.length != renderedPadded || e.data.rangeVersion !== this._activeRangeVersion) {\n                // Only re-enable posting and trigger a re-sort if the buffer is available.\n                // If byteLength === 0 the buffer is already in-flight for a newer sort;\n                // that sort's onmessage will handle things when it returns.\n                if (this._depthMix.buffer.byteLength > 0) {\n                    this._canPostToWorker = true;\n                    this._postToWorker(true);\n                    this._sortIsDirty = false;\n                }\n                return;\n            }\n\n            this._depthMix = e.data.depthMix;\n            const cameraId = e.data.cameraId;\n            const sortRequestId = e.data.sortRequestId;\n\n            // The index buffer swap is deferred to here so the previous fully-sorted state stays on screen\n            // until this matching sort lands. Resize it now (the active count may have grown/shrunk since the\n            // last applied sort) and rebind it for every known camera.\n            if (!this._splatIndex || this._splatIndex.length !== renderedPadded) {\n                this._splatIndex = new Float32Array(renderedPadded);\n                this._cameraViewInfos.forEach((info) => {\n                    info.mesh.thinInstanceSetBuffer(\"splatIndex\", this._splatIndex, 16, false);\n                    info.splatIndexBufferSet = true;\n                });\n            }\n\n            const indexMix = new Uint32Array(e.data.depthMix.buffer);\n            if (this._splatIndex) {\n                for (let j = 0; j < renderedPadded; j++) {\n                    this._splatIndex[j] = indexMix[2 * j];\n                }\n            }\n            this.forcedInstanceCount = Math.max(renderedPadded >> 4, 1);\n            if (this._delayedTextureUpdate) {\n                const vertexCountPadded = (this._vertexCount + 15) & ~0xf;\n                const textureSize = this._getTextureSize(vertexCountPadded);\n                this._updateSubTextures(\n                    this._delayedTextureUpdate.centers,\n                    this._delayedTextureUpdate.covA,\n                    this._delayedTextureUpdate.covB,\n                    this._delayedTextureUpdate.colors,\n                    0,\n                    textureSize.y,\n                    this._delayedTextureUpdate.sh\n                );\n                this._delayedTextureUpdate = null;\n            }\n\n            // get mesh for camera and update its instance buffer\n            const cameraViewInfos = this._cameraViewInfos.get(cameraId);\n            if (cameraViewInfos) {\n                if (cameraViewInfos.splatIndexBufferSet) {\n                    cameraViewInfos.mesh.thinInstanceBufferUpdated(\"splatIndex\");\n                } else {\n                    cameraViewInfos.mesh.thinInstanceSetBuffer(\"splatIndex\", this._splatIndex, 16, false);\n                    cameraViewInfos.splatIndexBufferSet = true;\n                }\n                cameraViewInfos.sortAppliedId = sortRequestId;\n            }\n            this._canPostToWorker = true;\n            this._readyToDisplay = true;\n            // sort is dirty when GS is visible for progressive update with a this message arriving but positions were partially filled\n            // another update needs to be kicked. The kick can't happen just when the position buffer is ready because _canPostToWorker might be false.\n            if (this._sortIsDirty) {\n                this._postToWorker(true);\n                this._sortIsDirty = false;\n            }\n        };\n    }\n\n    protected _getTextureSize(length: number): Vector2 {\n        const engine = this._scene.getEngine();\n        const width = engine.getCaps().maxTextureSize;\n\n        let height = 1;\n\n        if (engine.version === 1 && !engine.isWebGPU) {\n            while (width * height < length) {\n                height *= 2;\n            }\n            // See the WebGL2/WebGPU branch below for why this guarantees an extra row when `length`\n            // exactly fills every row. A power-of-2 height has to double to add any slack at all.\n            // Usually this is a no-op since it is rare that the asset exactly contains a power-of-2\n            // number of splats.\n            if (length > 0 && width * height === length) {\n                height *= 2;\n            }\n        } else {\n            height = Math.ceil(length / width);\n            // When `length` exactly fills every row, force one extra (fully zeroed) row so the atlas\n            // always has at least one genuinely-empty splat slot past the real data, at index `length`.\n            // The sort worker (gaussianSplattingSortWorker.ts) relies on that slot always existing to\n            // safely pad the 16-aligned draw order — without it, the only \"spare\" index would be the\n            // last real splat, which range-filtering (setSplatIndexRanges/opacity/size culling) can\n            // leave fully visible and opaque, reproducing the same \"stuck in front\" bug on that splat.\n            if (length > 0 && height * width === length) {\n                height += 1;\n            }\n        }\n\n        if (height > width) {\n            Logger.Error(\"GaussianSplatting texture size: (\" + width + \", \" + height + \"), maxTextureSize: \" + width);\n            height = width;\n        }\n\n        return new Vector2(width, height);\n    }\n\n    /**\n     * Called after the sort worker has been created and the initial positions message has been sent.\n     * Override in subclasses to post any additional setup messages the worker needs (e.g. group\n     * indices, per-part matrices, etc.).\n     * @param _worker the newly created worker\n     */\n    protected _onWorkerCreated(_worker: Worker): void {}\n\n    /**\n     * Called by the material to bind any extra shader uniforms that are specific to this mesh type.\n     * The base implementation is a no-op; override in subclasses to bind additional data.\n     * @param _effect the shader effect that is being bound\n     * @internal\n     */\n    public bindExtraEffectUniforms(_effect: Effect): void {}\n\n    /**\n     * Processes all splats from a source GaussianSplattingMesh directly into the destination\n     * texture arrays starting at dstOffset. This is the core of the texture-direct compound API:\n     * no merged CPU buffer is ever created; each source mesh is written straight into its region.\n     *\n     * @param source - The source mesh whose splats are appended\n     * @param dstOffset - The destination splat index at which writing starts\n     * @param covA - Destination covA array (full texture size)\n     * @param covB - Destination covB array (full texture size)\n     * @param colorArray - Destination color array (full texture size)\n     * @param sh - Destination SH arrays (full texture size), or undefined\n     * @param minimum - Accumulated bounding min (updated in-place)\n     * @param maximum - Accumulated bounding max (updated in-place)\n     * @internal Use GaussianSplattingMesh.addPart instead\n     */\n    protected _appendSourceToArrays(\n        source: GaussianSplattingMeshBase,\n        dstOffset: number,\n        covA: Uint16Array,\n        covB: Uint16Array,\n        colorArray: Uint8Array,\n        sh: Uint8Array[] | undefined,\n        minimum: Vector3,\n        maximum: Vector3\n    ): void {\n        const srcCount = source._vertexCount;\n        const bytesPerTexel = 16;\n        const srcRaw = source._splatsData;\n        if (!srcRaw || srcCount === 0) {\n            return;\n        }\n        const uBuffer = GaussianSplattingMeshBase._GetSplatDataBytes(srcRaw);\n        const fBuffer = GaussianSplattingMeshBase._GetSplatDataFloats(srcRaw);\n\n        for (let i = 0; i < srcCount; i++) {\n            this._makeSplat(dstOffset + i, fBuffer, uBuffer, covA, covB, colorArray, minimum, maximum, false, i);\n        }\n\n        // Copy SH data if both source and destination have it\n        if (sh && source._shData) {\n            for (let texIdx = 0; texIdx < sh.length; texIdx++) {\n                if (texIdx < source._shData.length) {\n                    sh[texIdx].set(source._shData[texIdx].subarray(0, srcCount * bytesPerTexel), dstOffset * bytesPerTexel);\n                }\n            }\n        }\n    }\n\n    /**\n     * Modifies the splats according to the passed transformation matrix.\n     * @param transform defines the transform matrix to use\n     * @returns the current mesh\n     */\n    public override bakeTransformIntoVertices(transform: DeepImmutable<Matrix>): Mesh {\n        const arrayBuffer = this.splatsData;\n        if (!arrayBuffer) {\n            Logger.Error(\"Cannot bake transform into vertices if splatsData is not kept in RAM\");\n            return this;\n        }\n\n        // Check for uniform scaling\n        const m = transform.m;\n        const scaleX = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);\n        const scaleY = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);\n        const scaleZ = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);\n        const epsilon = 0.001;\n        if (Math.abs(scaleX - scaleY) > epsilon || Math.abs(scaleX - scaleZ) > epsilon) {\n            Logger.Error(\"Gaussian Splatting bakeTransformIntoVertices does not support non-uniform scaling\");\n            return this;\n        }\n\n        const uBuffer = new Uint8Array(arrayBuffer);\n        const fBuffer = new Float32Array(arrayBuffer);\n\n        const temp = TmpVectors.Vector3[0];\n        let index: number;\n        const quaternion = TmpVectors.Quaternion[0];\n        const transformedQuaternion = TmpVectors.Quaternion[1];\n        transform.decompose(temp, transformedQuaternion, temp);\n        for (index = 0; index < this._vertexCount; index++) {\n            const floatIndex = index * 8; // 8 floats per splat (center.x, center.y, center.z, scale.x, scale.y, scale.z, ...)\n            Vector3.TransformCoordinatesFromFloatsToRef(fBuffer[floatIndex], fBuffer[floatIndex + 1], fBuffer[floatIndex + 2], transform, temp);\n            fBuffer[floatIndex] = temp.x;\n            fBuffer[floatIndex + 1] = temp.y;\n            fBuffer[floatIndex + 2] = temp.z;\n\n            // Apply uniform scaling to splat scales\n            fBuffer[floatIndex + 3] *= scaleX;\n            fBuffer[floatIndex + 4] *= scaleX;\n            fBuffer[floatIndex + 5] *= scaleX;\n\n            // Unpack quaternion from uint8array (matching _GetSplat packing convention)\n            quaternion.set(\n                (uBuffer[32 * index + 28 + 1] - 127.5) / 127.5,\n                (uBuffer[32 * index + 28 + 2] - 127.5) / 127.5,\n                (uBuffer[32 * index + 28 + 3] - 127.5) / 127.5,\n                (uBuffer[32 * index + 28 + 0] - 127.5) / 127.5\n            );\n            quaternion.normalize();\n\n            // If there is a negative scaling, we need to flip the quaternion to keep the correct handedness\n            if (this.scaling.x < 0) {\n                quaternion.x = -quaternion.x;\n                quaternion.w = -quaternion.w;\n            }\n            if (this.scaling.y < 0) {\n                quaternion.y = -quaternion.y;\n                quaternion.w = -quaternion.w;\n            }\n            if (this.scaling.z < 0) {\n                quaternion.z = -quaternion.z;\n                quaternion.w = -quaternion.w;\n            }\n\n            // Transform the quaternion\n            transformedQuaternion.multiplyToRef(quaternion, quaternion);\n            quaternion.normalize();\n\n            // Pack quaternion back to uint8array (matching _GetSplat packing convention)\n            uBuffer[32 * index + 28 + 0] = Math.round(quaternion.w * 127.5 + 127.5);\n            uBuffer[32 * index + 28 + 1] = Math.round(quaternion.x * 127.5 + 127.5);\n            uBuffer[32 * index + 28 + 2] = Math.round(quaternion.y * 127.5 + 127.5);\n            uBuffer[32 * index + 28 + 3] = Math.round(quaternion.z * 127.5 + 127.5);\n        }\n\n        this.updateData(arrayBuffer, this.shData ?? undefined, { flipY: false });\n\n        return this;\n    }\n}\n\n/**\n * Allocates SH texture buffers pre-filled with 128 (the neutral encoding of ~0.0 in the\n * shader's decompose() function). Padding bytes beyond the actual coefficients in the last\n * texture are read as higher-order SH bands when the mesh is added to a compound with a\n * higher degree; zero would decode to -1.0 instead, producing wrong colors.\n * @param textureCount number of SH textures to allocate\n * @param bytesEach byte size of each texture buffer\n * @returns array of initialized Uint8Array buffers\n */\nexport function AllocateShBuffers(textureCount: number, bytesEach: number): Uint8Array[] {\n    const result: Uint8Array[] = [];\n    for (let i = 0; i < textureCount; i++) {\n        const arr = new Uint8Array(bytesEach);\n        arr.fill(128);\n        result.push(arr);\n    }\n    return result;\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type AbstractMesh } from \"../abstractMesh.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type GaussianSplattingMesh } from \"./gaussianSplattingMesh.pure\";\r\nimport { type Ray } from \"../../Culling/ray.core\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Class used as a proxy mesh for a part of a compound Gaussian Splatting mesh\r\n */\r\nexport class GaussianSplattingPartProxyMesh extends Mesh {\r\n    /**\r\n     * Local-space bounds for this part, stored directly on the proxy so it does not\r\n     * need to retain a reference to the original source mesh.\r\n     */\r\n    private _minimum: Vector3;\r\n    private _maximum: Vector3;\r\n\r\n    private _disabledVisibility: Nullable<number> = null;\r\n\r\n    /**\r\n     * The index of the part in the compound mesh (internal storage)\r\n     */\r\n    private _partIndex: number;\r\n\r\n    /**\r\n     * Number of splats owned by this part.\r\n     * @internal\r\n     */\r\n    public _vertexCount: number;\r\n\r\n    /**\r\n     * Offset of this part in the compound splat ordering.\r\n     * @internal\r\n     */\r\n    public _splatsDataOffset: number;\r\n\r\n    /**\r\n     * Texel offset of this part inside the compound SH textures.\r\n     * This matches the splat offset because SH data is stored one texel per splat.\r\n     * @internal\r\n     */\r\n    public _shDataOffset: number;\r\n\r\n    /**\r\n     * Gets the index of the part in the compound mesh\r\n     */\r\n    public get partIndex(): number {\r\n        return this._partIndex;\r\n    }\r\n\r\n    /**\r\n     * The compound mesh that owns this part proxy\r\n     */\r\n    public readonly compoundSplatMesh: GaussianSplattingMesh;\r\n\r\n    /**\r\n     * Backward-compatible alias for the owning compound mesh.\r\n     * @deprecated Use `compoundSplatMesh` instead.\r\n     */\r\n    public get proxiedMesh(): GaussianSplattingMesh {\r\n        return this.compoundSplatMesh;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Gaussian Splatting part proxy mesh\r\n     * @param name The name of the proxy mesh\r\n     * @param scene The scene the proxy mesh belongs to\r\n     * @param compoundSplatMesh The compound mesh that owns this part proxy\r\n     * @param partIndex The index of the part in the compound mesh\r\n     * @param boundingInfo Local-space bounds of the part inside the compound mesh\r\n     * @param vertexCount Number of splats owned by the part\r\n     * @param splatsDataOffset Offset of the part in the compound splat ordering\r\n     * @param shDataOffset Offset of the part in the compound SH textures\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Nullable<Scene>,\r\n        compoundSplatMesh: GaussianSplattingMesh,\r\n        partIndex: number,\r\n        boundingInfo: BoundingInfo,\r\n        vertexCount: number,\r\n        splatsDataOffset: number,\r\n        shDataOffset: number = splatsDataOffset\r\n    ) {\r\n        super(name, scene);\r\n        this._partIndex = partIndex;\r\n        this._vertexCount = vertexCount;\r\n        this._splatsDataOffset = splatsDataOffset;\r\n        this._shDataOffset = shDataOffset;\r\n        this._minimum = boundingInfo.minimum.clone();\r\n        this._maximum = boundingInfo.maximum.clone();\r\n        this.compoundSplatMesh = compoundSplatMesh;\r\n\r\n        this._applyBoundingInfo();\r\n        this.compoundSplatMesh.setWorldMatrixForPart(this.partIndex, this.getWorldMatrix());\r\n\r\n        // Update the compound mesh's part matrix when this proxy's world matrix changes.\r\n        this.onAfterWorldMatrixUpdateObservable.add(() => {\r\n            this.compoundSplatMesh.setWorldMatrixForPart(this.partIndex, this.getWorldMatrix());\r\n        });\r\n        this.onEffectiveEnabledStateChangedObservable.add((isEnabled) => {\r\n            if (isEnabled) {\r\n                this.compoundSplatMesh.setPartVisibility(this.partIndex, this._disabledVisibility ?? this.compoundSplatMesh.getPartVisibility(this.partIndex));\r\n                this._disabledVisibility = null;\r\n            } else {\r\n                this._disabledVisibility = this.compoundSplatMesh.getPartVisibility(this.partIndex);\r\n                this.compoundSplatMesh.setPartVisibility(this.partIndex, 0);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Updates the bounding info of this proxy mesh from its stored part metadata.\r\n     */\r\n    public updateBoundingInfoFromPartData(): void {\r\n        this._applyBoundingInfo();\r\n    }\r\n\r\n    /**\r\n     * Backward-compatible alias retained while callers move away from source-mesh based semantics.\r\n     */\r\n    public updateBoundingInfoFromProxiedMesh(): void {\r\n        this.updateBoundingInfoFromPartData();\r\n    }\r\n\r\n    private _applyBoundingInfo(): void {\r\n        this.setBoundingInfo(new BoundingInfo(this._minimum.clone(), this._maximum.clone()));\r\n    }\r\n\r\n    /**\r\n     * Returns the class name\r\n     * @returns \"GaussianSplattingPartProxyMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GaussianSplattingPartProxyMesh\";\r\n    }\r\n\r\n    /**\r\n     * Returns the world-space bounding vectors spanning this part (and any descendants).\r\n     *\r\n     * A part proxy carries real bounds (set via {@link setBoundingInfo}) but owns NO geometry — the compound\r\n     * holds the splats. The base {@link Node.getHierarchyBoundingVectors} only folds in a mesh's own bounds\r\n     * when it has a `subMeshes` array (a geometry-less mesh's is `undefined`) and skips zero-vertex descendants,\r\n     * so for a bare proxy it returns a degenerate ±MAX_VALUE box. Callers that treat the proxy as a normal mesh\r\n     * (camera framing, grounding, picking) would then derive NaN / astronomically large offsets. This override\r\n     * folds the proxy's own world-space box into whatever the base returns for descendants.\r\n     * @param includeDescendants include bounding vectors from descendant meshes\r\n     * @param predicate optional filter applied to each descendant mesh\r\n     * @returns the world-space min/max spanning this part (and any descendants)\r\n     */\r\n    public override getHierarchyBoundingVectors(\r\n        includeDescendants: boolean = true,\r\n        predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n    ): { min: Vector3; max: Vector3 } {\r\n        // Base recomputes this proxy's world matrix but skips its (geometry-less) own bounds.\r\n        const result = super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n        // Refresh the world-space corners against the just-computed world matrix, then extend the result:\r\n        // CheckExtends turns the base's ±MAX_VALUE sentinel seed into this part's real box.\r\n        const info = this.getBoundingInfo();\r\n        info.update(this.getWorldMatrix());\r\n        Vector3.CheckExtends(info.boundingBox.minimumWorld, result.min, result.max);\r\n        Vector3.CheckExtends(info.boundingBox.maximumWorld, result.min, result.max);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Updates the part index for this proxy mesh.\r\n     * This should only be called internally when parts are removed from the compound mesh.\r\n     * @param newPartIndex the new part index\r\n     * @internal\r\n     */\r\n    public updatePartIndex(newPartIndex: number): void {\r\n        this._partIndex = newPartIndex;\r\n    }\r\n\r\n    /**\r\n     * Updates the per-part metadata for this proxy mesh.\r\n     * This is used internally when compound parts are rebuilt and re-indexed.\r\n     * @param vertexCount the number of splats owned by the part\r\n     * @param splatsDataOffset the new splat offset in the compound\r\n     * @param shDataOffset the new SH texel offset in the compound\r\n     * @internal\r\n     */\r\n    public updatePartMetadata(vertexCount: number, splatsDataOffset: number, shDataOffset: number = splatsDataOffset): void {\r\n        this._vertexCount = vertexCount;\r\n        this._splatsDataOffset = splatsDataOffset;\r\n        this._shDataOffset = shDataOffset;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the part should be visible when this proxy is enabled\r\n     */\r\n    public override get isVisible(): boolean {\r\n        return this.visibility > 0;\r\n    }\r\n\r\n    /**\r\n     * Sets whether the part should be visible when this proxy is enabled\r\n     */\r\n    public override set isVisible(value: boolean) {\r\n        this.visibility = value ? 1.0 : 0.0;\r\n    }\r\n\r\n    /**\r\n     * Gets the visibility applied to the part while this proxy is enabled (0.0 to 1.0)\r\n     */\r\n    public override get visibility(): number {\r\n        return this._disabledVisibility ?? this.compoundSplatMesh.getPartVisibility(this.partIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the visibility to apply to the part while this proxy is enabled (0.0 to 1.0)\r\n     */\r\n    public override set visibility(value: number) {\r\n        const visibility = Math.max(0.0, Math.min(1.0, value));\r\n        if (this.isEnabled()) {\r\n            this.compoundSplatMesh.setPartVisibility(this.partIndex, visibility);\r\n        } else {\r\n            this._disabledVisibility = visibility;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks if a ray intersects with this proxy mesh using only bounding info\r\n     * @param ray defines the ray to test\r\n     * @returns the picking info with this mesh set as pickedMesh if hit\r\n     */\r\n    public override intersects(ray: Ray): PickingInfo {\r\n        const pickingInfo = new PickingInfo();\r\n        const boundingInfo = this.getBoundingInfo();\r\n\r\n        if (!boundingInfo) {\r\n            return pickingInfo;\r\n        }\r\n\r\n        // Always check against bounding info for proxy meshes\r\n        if (!ray.intersectsSphere(boundingInfo.boundingSphere) || !ray.intersectsBox(boundingInfo.boundingBox)) {\r\n            return pickingInfo;\r\n        }\r\n\r\n        // If we hit the bounding volume, report this mesh as picked\r\n        pickingInfo.hit = true;\r\n        pickingInfo.pickedMesh = this;\r\n        pickingInfo.distance = Vector3.Distance(ray.origin, boundingInfo.boundingSphere.center);\r\n        pickingInfo.subMeshId = 0;\r\n\r\n        return pickingInfo;\r\n    }\r\n\r\n    /**\r\n     * Serialize current GaussianSplattingPartProxyMesh\r\n     * @param serializationObject defines the object which will receive the serialization data\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(serializationObject: any = {}): any {\r\n        serializationObject = super.serialize(serializationObject);\r\n        // GaussianSplattingPartProxyMesh needs no SubMesh, Geometry, or Material\r\n        serializationObject.subMeshes = [];\r\n        serializationObject.geometryUniqueId = undefined;\r\n        serializationObject.geometryId = undefined;\r\n        serializationObject.materialUniqueId = undefined;\r\n        serializationObject.materialId = undefined;\r\n        serializationObject.instances = [];\r\n        serializationObject.actions = undefined;\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.compoundSplatMeshId = this.compoundSplatMesh.id;\r\n        // Part metadata is needed to reconnect the proxy to the correct compound segment.\r\n        serializationObject.partIndex = this._partIndex;\r\n        serializationObject.vertexCount = this._vertexCount;\r\n        serializationObject.splatsDataOffset = this._splatsDataOffset;\r\n        serializationObject.shDataOffset = this._shDataOffset;\r\n        const boundingInfo = this.getBoundingInfo();\r\n        serializationObject.boundingInfo = {\r\n            minimum: boundingInfo.minimum.asArray(),\r\n            maximum: boundingInfo.maximum.asArray(),\r\n        };\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized GaussianSplattingPartProxyMesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the GaussianSplattingPartProxyMesh in\r\n     * @returns the created GaussianSplattingPartProxyMesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingPartProxyMesh {\r\n        const partIndex = parsedMesh.partIndex;\r\n        const compoundSplatMesh =\r\n            (parsedMesh.compoundSplatMesh as GaussianSplattingMesh | undefined) ?? (scene.getLastMeshById(parsedMesh.compoundSplatMeshId) as GaussianSplattingMesh | null);\r\n        if (!compoundSplatMesh) {\r\n            throw new Error(`GaussianSplattingPartProxyMesh: compound mesh not found with ID ${parsedMesh.compoundSplatMeshId}`);\r\n        }\r\n        const minimum = Vector3.FromArray(parsedMesh.boundingInfo.minimum);\r\n        const maximum = Vector3.FromArray(parsedMesh.boundingInfo.maximum);\r\n        const boundingInfo = new BoundingInfo(minimum, maximum);\r\n        const vertexCount = parsedMesh.vertexCount ?? 0;\r\n        const splatsDataOffset = parsedMesh.splatsDataOffset ?? 0;\r\n        const shDataOffset = parsedMesh.shDataOffset ?? splatsDataOffset;\r\n        return new GaussianSplattingPartProxyMesh(parsedMesh.name, scene, compoundSplatMesh, partIndex, boundingInfo, vertexCount, splatsDataOffset, shDataOffset);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingPartProxyMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingPartProxyMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GaussianSplattingPartProxyMeshParser = GaussianSplattingPartProxyMesh.Parse;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Vector2 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { GaussianSplattingMeshBase, AllocateShBuffers, type IGaussianSplattingSplatRange } from \"./gaussianSplattingMeshBase.pure\";\r\nimport { GaussianSplattingSortWorkerCommand } from \"./gaussianSplattingSortWorker\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { type MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DecodeBase64ToBinary, EncodeArrayBufferToBase64 } from \"core/Misc/stringTools\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\n\r\nexport { IsGaussianSplattingClassName } from \"./gaussianSplatting.functions\";\r\n\r\nconst _GaussianSplattingBytesPerSplat = 32;\r\nconst _GaussianSplattingBytesPerShTexel = 16;\r\n\r\ninterface IGaussianSplattingPartSource {\r\n    name: string;\r\n    _vertexCount: number;\r\n    _splatsData: Nullable<ArrayBuffer | ArrayBufferView>;\r\n    _shData: Nullable<Uint8Array[]>;\r\n    _shDegree: number;\r\n    isCompound: boolean;\r\n    getWorldMatrix(): Matrix;\r\n    getBoundingInfo(): BoundingInfo;\r\n    dispose(): void;\r\n    /**\r\n     * When true this is a placeholder that reserves `_vertexCount` empty (invisible) splats in the\r\n     * atlas instead of copying real data. Used by {@link GaussianSplattingMesh.reserveStreamingPart}\r\n     * so a streaming engine can later GPU-decode into the reserved region. Sources flagged this way\r\n     * are allowed to have a null `_splatsData`; their atlas region is left zeroed (invisible padding).\r\n     */\r\n    _isReservedEmpty?: boolean;\r\n}\r\n\r\n/**\r\n * Run-Length Encoding (RLE) compression for serialization\r\n * Compressed Uint32Array can be parsed using {@link ParsePartIndices}\r\n * Some notes for devs: We do not expect Uint8Array larger than 4GB,\r\n * so it should be safe to use Uint32Array.\r\n * @param partIndices A view of partIndices from GaussianSplattingMesh\r\n * @returns A compressed Uint32Array of [count, value, ...]\r\n */\r\nfunction CompressPartIndices(partIndices: Uint8Array): Uint32Array {\r\n    const runs: number[] = [];\r\n    const length = partIndices.length;\r\n    let i = 0;\r\n    while (i < length) {\r\n        const value = partIndices[i];\r\n        let count = 1;\r\n        while (i + count < length && partIndices[i + count] === value) {\r\n            count++;\r\n        }\r\n        runs.push(count, value);\r\n        i += count;\r\n    }\r\n    return new Uint32Array(runs);\r\n}\r\n\r\n/**\r\n * Parse partIndices compressed by {@link CompressPartIndices} to runtime array\r\n * @param compressed The compressed partIndices of [count, value, ...]\r\n * @returns runtime Uint8Array for GaussianSplattingMesh\r\n */\r\nfunction ParsePartIndices(compressed: Uint32Array | number[]): Uint8Array {\r\n    let totalCount = 0;\r\n    const length = compressed.length;\r\n    for (let i = 0; i < length; i += 2) {\r\n        totalCount += compressed[i];\r\n    }\r\n\r\n    const partIndices = new Uint8Array(totalCount);\r\n    let offset = 0;\r\n    for (let i = 0; i < length; i += 2) {\r\n        const count = compressed[i];\r\n        const value = compressed[i + 1];\r\n        partIndices.fill(value, offset, offset + count);\r\n        offset += count;\r\n    }\r\n\r\n    return partIndices;\r\n}\r\n\r\n/**\r\n * A LOD engine (e.g. a streamed part) that participates in a compound's shared splat budget. The compound\r\n * apportions {@link GaussianSplattingMesh.splatBudget} (net of static parts) across all registered participants\r\n * by demand and pushes each its allocation. Defined here (core) so the compound never depends on the loader's\r\n * streaming engine; the engine implements this and registers via\r\n * {@link GaussianSplattingMesh.registerLodBudgetParticipant}.\r\n * @experimental\r\n */\r\nexport interface IGaussianSplattingLodBudgetParticipant {\r\n    /** The number of splats this participant would render at full (distance-optimal) detail — its budget demand. */\r\n    getBudgetDemand(): number;\r\n    /**\r\n     * Sets the participant's apportioned share of the compound budget (in splats). `null` clears coordination so\r\n     * the participant reverts to its own budget; `0` keeps it coordinated at the coarsest level.\r\n     * @param splats the apportioned splat allocation, or null to release coordination\r\n     */\r\n    setBudgetAllocation(splats: Nullable<number>): void;\r\n}\r\n\r\n/**\r\n * Handle to a region of a compound Gaussian Splatting mesh reserved for dynamic (streamed) content by\r\n * {@link GaussianSplattingMesh.reserveStreamingPart}. It lets a streaming engine populate the region's\r\n * splats over time and drive which of them are sorted/rendered, while the compound keeps depth-sorting\r\n * and drawing every part (static + streamed) together in one pass.\r\n *\r\n * Ranges/offsets passed to this handle are LOCAL to the part (0-based within `[0, capacity)`); the handle\r\n * translates them to the compound's global atlas coordinates.\r\n */\r\nexport interface IGaussianSplattingStreamingPart {\r\n    /** The proxy mesh controlling this part's world transform and visibility. */\r\n    readonly proxy: GaussianSplattingPartProxyMesh;\r\n    /** The part index assigned to this streaming region in the compound. */\r\n    readonly partIndex: number;\r\n    /** First atlas splat index of the reserved region. */\r\n    readonly base: number;\r\n    /** Number of splats reserved for the region. */\r\n    readonly capacity: number;\r\n    /** The compound's shared centers texture (the region occupies `[base, base+capacity)` within it). */\r\n    readonly centersTexture: Nullable<BaseTexture>;\r\n    /** The compound's shared covariance A texture. */\r\n    readonly covariancesATexture: Nullable<BaseTexture>;\r\n    /** The compound's shared covariance B texture. */\r\n    readonly covariancesBTexture: Nullable<BaseTexture>;\r\n    /** The compound's shared colors texture. */\r\n    readonly colorsTexture: Nullable<BaseTexture>;\r\n    /** The compound's shared CPU centers buffer consumed by the sort worker. */\r\n    readonly splatPositions: Nullable<Float32Array>;\r\n    /** The compound's shared render-target atlas a streaming engine decodes into, or null on a non-GPU backend. */\r\n    readonly mrtAtlas: Nullable<MultiRenderTarget>;\r\n    /**\r\n     * The compound's shared higher-order SH render-target atlas (one single-attachment integer MRT per packed-u32\r\n     * SH texture) a streaming engine bakes SH into, or null when SH decode was not requested for this part.\r\n     */\r\n    readonly shMrtAtlas: Nullable<MultiRenderTarget[]>;\r\n    /**\r\n     * The compound's shared rotation/scale render-target atlas (one 3-attachment half-float MRT) a streaming engine\r\n     * decodes rotation/scale into for voxel-IBL shadows, or null when rotation decode was not requested for this part.\r\n     */\r\n    readonly rotMrtAtlas: Nullable<MultiRenderTarget>;\r\n    /** Width (in texels) of the atlas, used to address decode/readback over the wide layout. */\r\n    readonly atlasWidth: number;\r\n    /** Whether the compound's shared depth sort is settled (a streaming engine polls this to detect readiness). */\r\n    readonly isDepthSortSettled: boolean;\r\n    /**\r\n     * Restricts which of this part's splats are sorted/rendered, in LOCAL coordinates. `null` renders the\r\n     * whole reserved region. The compound merges this with every other part's ranges into the single sort.\r\n     * @param localRanges active local ranges, or `null` for the full region\r\n     */\r\n    setActiveRanges(localRanges: Nullable<readonly IGaussianSplattingSplatRange[]>): void;\r\n    /**\r\n     * CPU-decodes raw `.splat` bytes into the region at `localOffset`, uploading only those texels and\r\n     * patching the sort worker. Grows the part's bounding info to include the written centers. This is the\r\n     * CPU population path (used to seed the region or as a fallback when GPU decode is unavailable).\r\n     * @param localOffset first local splat index to write\r\n     * @param count number of splats to write\r\n     * @param splatsData raw `.splat` bytes for `count` splats (stride 32)\r\n     */\r\n    writeSplats(localOffset: number, count: number, splatsData: ArrayBuffer | ArrayBufferView): void;\r\n    /**\r\n     * Patches only `[localOffset, localOffset+count)` of the worker's position buffer (for the GPU path,\r\n     * where texel data is written directly to the atlas and only the CPU centers are pushed to the worker).\r\n     * @param localOffset first local splat index\r\n     * @param count number of splats\r\n     */\r\n    postPositionsRange(localOffset: number, count: number): void;\r\n    /**\r\n     * Grows the part's (and compound's) bounding info to include the given local-space centers extent.\r\n     * @param min minimum corner\r\n     * @param max maximum corner\r\n     */\r\n    expandBounds(min: Vector3, max: Vector3): void;\r\n    /**\r\n     * Re-posts the full merged position + part-index set to the compound's sort worker. Only needed after a\r\n     * relayout moved the region's data wholesale; per-decode updates use {@link postPositionsRange} instead.\r\n     */\r\n    notifyDataChanged(): void;\r\n    /**\r\n     * Subscribes to the \"about to recreate the shared atlas to grow it\" event (e.g. another part is being added).\r\n     * The callback receives the OLD atlas and should back up this region's GPU-only data before it is disposed.\r\n     * @param callback invoked with the old atlas MRT\r\n     * @returns an unsubscribe function (call it on dispose)\r\n     */\r\n    onBeforeAtlasRebuild(callback: (oldAtlas: MultiRenderTarget) => void): () => void;\r\n    /**\r\n     * Subscribes to the \"shared atlas has been recreated\" event. The callback receives the NEW atlas and should\r\n     * rebind to it and restore this region's backed-up data.\r\n     * @param callback invoked with the new atlas MRT\r\n     * @returns an unsubscribe function (call it on dispose)\r\n     */\r\n    onAfterAtlasRebuild(callback: (newAtlas: MultiRenderTarget) => void): () => void;\r\n}\r\n\r\n/**\r\n * Internal mutable bookkeeping for one reserved streaming region. The handle's `base`/`partIndex` getters and\r\n * the compaction re-post read from this object, so {@link GaussianSplattingMesh.compactAtlas} can RELOCATE a\r\n * region (assign it a new base/partIndex) in place without invalidating the streaming engine's handle.\r\n */\r\ninterface IStreamingPartState {\r\n    /** The proxy mesh for this region (stable identity across a relocation). */\r\n    proxy: GaussianSplattingPartProxyMesh;\r\n    /** First usable atlas splat index of the region (row-aligned). Updated when the region is relocated. */\r\n    base: number;\r\n    /** The region's current part index. Updated when parts before it are removed. */\r\n    partIndex: number;\r\n    /** Usable capacity (row-aligned), fixed for the region's lifetime. */\r\n    capacity: number;\r\n    /** Running local-space bounds of the region's written centers (shared with the handle's closures). */\r\n    boundsMin: Vector3;\r\n    boundsMax: Vector3;\r\n    /** The region's last active LOD ranges in LOCAL coordinates, so a relocation can re-post them at the new base. */\r\n    localRanges: Nullable<readonly IGaussianSplattingSplatRange[]>;\r\n    /** Number of packed-u32 SH textures this streaming part bakes into the shared SH atlas (0 = no SH). Used to\r\n     * recompute the compound's SH-atlas state from the SURVIVING parts when a part is removed (so removing the last\r\n     * SH part turns the SH atlas off instead of leaving stale render-target degree/count behind). */\r\n    shTextureCount: number;\r\n    /** SH degree of this streaming part's baked SH (0 = no SH). Feeds the compound's max-degree recompute. */\r\n    shDegree: number;\r\n    /** Whether this streaming part decodes rotation/scale into the shared rotation atlas (for voxel-IBL shadows).\r\n     * Used to recompute the compound's rotation-atlas state from the SURVIVING parts when a part is removed. */\r\n    needsRotationScale: boolean;\r\n    /** Set once the part is removed (tombstoned). The handle returned by {@link GaussianSplattingMesh.reserveStreamingPart}\r\n     * checks this so a caller that retained a removed handle can't mutate a surviving part that later inherited this\r\n     * region's part index/base. */\r\n    removed: boolean;\r\n}\r\n\r\n/**\r\n * Class used to render a Gaussian Splatting mesh. Supports both single-cloud and compound\r\n * (multi-part) rendering. In compound mode, multiple Gaussian Splatting source meshes are\r\n * merged into one draw call while retaining per-part world-matrix control via\r\n * addPart/addParts and removePart.\r\n */\r\nexport class GaussianSplattingMesh extends GaussianSplattingMeshBase {\r\n    /**\r\n     * Proxy meshes indexed by part index. Maintained in sync with _partMatrices.\r\n     */\r\n    private _partProxies: GaussianSplattingPartProxyMesh[] = [];\r\n\r\n    /** Part 0 local-space AABB when owned directly (not proxied). Set on first addPart, cleared on dispose/reset. */\r\n    private _part0LocalMin: Nullable<Vector3> = null;\r\n    private _part0LocalMax: Nullable<Vector3> = null;\r\n\r\n    /**\r\n     * World matrices for each part, indexed by part index.\r\n     */\r\n    protected _partMatrices: Matrix[] = [];\r\n\r\n    /** When true, suppresses the sort trigger inside setWorldMatrixForPart during batch rebuilds. */\r\n    private _rebuilding: boolean = false;\r\n\r\n    /**\r\n     * Visibility values for each part (0.0 to 1.0), indexed by part index.\r\n     */\r\n    protected _partVisibility: number[] = [];\r\n\r\n    /**\r\n     * Per-part active source-splat range overrides, indexed by part index, in GLOBAL source-splat\r\n     * coordinates (offsets into the merged atlas). A part with no entry (undefined) renders its full\r\n     * range; a part with an entry renders only those ranges. Used by streaming parts to render just\r\n     * their currently-active LOD splats while static parts render fully. No overrides at all means no\r\n     * filter (the base renders every splat, preserving the non-streaming fast path).\r\n     */\r\n    private _partSplatRanges: Nullable<IGaussianSplattingSplatRange[]>[] = [];\r\n\r\n    /**\r\n     * True once a streaming part has been reserved. A streamed region's data lives only on the GPU (no retained CPU\r\n     * source), so atlas rebuilds and part add/remove take the streaming-aware paths that back up and restore each\r\n     * region rather than regenerating it from a CPU source.\r\n     * @internal\r\n     */\r\n    protected _hasStreamingPart = false;\r\n\r\n    /** Mutable bookkeeping for each reserved streaming region, so {@link compactAtlas} can relocate them. */\r\n    private _streamingStates: IStreamingPartState[] = [];\r\n\r\n    /**\r\n     * Shared LOD splat budget for the whole compound (0 = disabled). When set, {@link _apportionBudget} divides it\r\n     * (net of static parts) across the registered {@link IGaussianSplattingLodBudgetParticipant}s each frame, so\r\n     * all hosted streams together stay within one cap. See {@link splatBudget}.\r\n     * Protected so {@link GaussianSplattingStream} can reuse it as its own per-stream budget.\r\n     */\r\n    protected _splatBudget = 0;\r\n    /** LOD engines sharing {@link _splatBudget} (e.g. hosted streamed parts). */\r\n    private _lodBudgetParticipants: IGaussianSplattingLodBudgetParticipant[] = [];\r\n    /** Per-frame budget apportionment observer, installed only while a budget and participants are both present. */\r\n    private _budgetObserver: Nullable<Observer<Scene>> = null;\r\n    // Reused per-participant scratch for the per-frame water-fill (avoids allocating three arrays every frame).\r\n    private readonly _budgetDemands: number[] = [];\r\n    private readonly _budgetAlloc: number[] = [];\r\n    private readonly _budgetSettled: boolean[] = [];\r\n\r\n    /**\r\n     * Max SH degree contributed by the live (non-tombstoned) streaming parts. Recomputed by\r\n     * {@link _refreshStreamingShState} whenever parts change, so removing the last SH stream turns the shared SH\r\n     * atlas off instead of leaving SH_DEGREE high over texels nothing refills.\r\n     */\r\n    private _streamingShDegree = 0;\r\n\r\n    /** Part indices tombstoned by {@link removePart} while streaming — excluded from render, reclaimed by {@link compactAtlas}. */\r\n    private _tombstonedPartIndices = new Set<number>();\r\n\r\n    private _partIndicesTexture: Nullable<BaseTexture> = null;\r\n    private _partIndices: Nullable<Uint8Array> = null;\r\n    private _partWorldData = new Float32Array(0);\r\n    private readonly _partVisibilityData: number[] = [];\r\n\r\n    /** Gets the part indices texture used for compound rendering */\r\n    public get partIndicesTexture() {\r\n        return this._partIndicesTexture;\r\n    }\r\n\r\n    /**\r\n     * Creates a new GaussianSplattingMesh\r\n     * @param name the name of the mesh\r\n     * @param url optional URL to load a Gaussian Splatting file from\r\n     * @param scene the hosting scene\r\n     * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU\r\n     * @param needsRotationScaleTextures generate rotation and scale matrix textures required for voxel-based IBL shadows\r\n     */\r\n    constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false, needsRotationScaleTextures: boolean = false) {\r\n        super(name, url, scene, keepInRam);\r\n        // Ensure _splatsData is retained once compound mode is entered — addPart/addParts need\r\n        // the source data for full-texture rebuilds. Set after super() so it is visible to\r\n        // _updateData when the async load completes.\r\n        this._alwaysRetainSplatsData = true;\r\n        this._needsRotationScaleTextures = needsRotationScaleTextures;\r\n    }\r\n\r\n    /**\r\n     * Returns the class name\r\n     * @returns \"GaussianSplattingMesh\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GaussianSplattingMesh\";\r\n    }\r\n\r\n    /**\r\n     * Is this node ready to be used/rendered.\r\n     * Force-syncs every part proxy's world matrix into `_partMatrices` BEFORE delegating to\r\n     * the base readiness check. This guarantees that any pending proxy transform changes\r\n     * (for example a user-set `proxy.position`) are reflected in the next sort post, so the\r\n     * base `isReady` will only return true once `sortAppliedId === sortRequestId` for that\r\n     * up-to-date state. Without this, the proxy's `onAfterWorldMatrixUpdateObservable` would\r\n     * fire during the first render and queue a fresh sort AFTER readiness was reported,\r\n     * leaving the rendered frame with stale splat order on `renderCount=1` runs.\r\n     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n     * @returns true when ready\r\n     */\r\n    public override isReady(completeCheck = false): boolean {\r\n        for (const proxy of this._partProxies) {\r\n            if (proxy) {\r\n                proxy.computeWorldMatrix(true);\r\n            }\r\n        }\r\n        return super.isReady(completeCheck);\r\n    }\r\n\r\n    /**\r\n     * Recomputes compound local-space bounds from part 0's stored AABB (if unproxied) plus all\r\n     * proxy world AABBs inverse-transformed to compound-local space. All 8 corners of each proxy\r\n     * AABB are transformed so the result is correct under non-identity compound rotation/scale.\r\n     */\r\n    private _updateBoundingInfoFromProxies(): void {\r\n        const compoundWorld = this.getWorldMatrix();\r\n        const invCompoundWorld = Matrix.Invert(compoundWorld);\r\n\r\n        const localMin = this._part0LocalMin ? this._part0LocalMin.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const localMax = this._part0LocalMax ? this._part0LocalMax.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n        const corner = new Vector3();\r\n        for (const proxy of this._partProxies) {\r\n            // Skip removed parts: a tombstoned proxy is kept (for compaction) but renders nothing, so it must not\r\n            // inflate the compound's bounds (and thus its frustum culling) until its rows are actually reclaimed.\r\n            if (!proxy || this._tombstonedPartIndices.has(proxy.partIndex)) {\r\n                continue;\r\n            }\r\n            // Proxies have no geometry — getHierarchyBoundingVectors returns sentinels. Use boundingBox directly.\r\n            proxy.computeWorldMatrix(false);\r\n            const bb = proxy.getBoundingInfo().boundingBox;\r\n            const wMin = bb.minimumWorld;\r\n            const wMax = bb.maximumWorld;\r\n            for (let b = 0; b < 8; b++) {\r\n                corner.set(b & 1 ? wMax.x : wMin.x, b & 2 ? wMax.y : wMin.y, b & 4 ? wMax.z : wMin.z);\r\n                Vector3.TransformCoordinatesToRef(corner, invCompoundWorld, corner);\r\n                localMin.minimizeInPlace(corner);\r\n                localMax.maximizeInPlace(corner);\r\n            }\r\n        }\r\n\r\n        if (localMin.x <= localMax.x) {\r\n            // Direct access avoids getBoundingInfo() → _updateBoundingInfo() recursion.\r\n            if (this._boundingInfo) {\r\n                this._boundingInfo.reConstruct(localMin, localMax, compoundWorld);\r\n            } else {\r\n                this._boundingInfo = new BoundingInfo(localMin, localMax, compoundWorld);\r\n            }\r\n            this._cachedBoundingMin = localMin.clone();\r\n            this._cachedBoundingMax = localMax.clone();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Override for compound meshes: recomputes bounds from proxy world extents instead of\r\n     * local bounds × world matrix, which is wrong for proxied parts with independent transforms.\r\n     * @returns this mesh\r\n     */\r\n    public override _updateBoundingInfo(): AbstractMesh {\r\n        if (this.isCompound) {\r\n            this._updateBoundingInfoFromProxies();\r\n            this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n            return this;\r\n        }\r\n        return super._updateBoundingInfo();\r\n    }\r\n\r\n    /**\r\n     * Replaces the base hierarchy bounds computation for compound meshes: computes world bounds\r\n     * from scratch by iterating part 0's local AABB and all proxy meshes, rather than delegating\r\n     * to the base _children traversal which never reaches proxies (they are not parented to the\r\n     * compound). Visibility per-part is respected; invisible parts are excluded.\r\n     * @param includeDescendants when true, includes descendants (default: true)\r\n     * @param predicate optional filter predicate\r\n     * @returns world-space min/max of the hierarchy bounding box\r\n     */\r\n    public override getHierarchyBoundingVectors(\r\n        includeDescendants: boolean = true,\r\n        predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n    ): { min: Vector3; max: Vector3 } {\r\n        if (!this.isCompound) {\r\n            return super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n        }\r\n        // For compound meshes, compute visible-only world bounds from scratch so that\r\n        // invisible parts don't inflate the result (e.g. for voxelization scene bounds).\r\n        const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n        // Unproxied part 0: the compound mesh owns this geometry directly (no proxy node).\r\n        // Transform its local AABB to world space if visible.\r\n        if (this._part0LocalMin && (this._partVisibility[0] ?? 1.0) > 0) {\r\n            const wm = this.getWorldMatrix();\r\n            const lMin = this._part0LocalMin;\r\n            const lMax = this._part0LocalMax!;\r\n            const corner = new Vector3();\r\n            for (let b = 0; b < 8; b++) {\r\n                corner.set(b & 1 ? lMax.x : lMin.x, b & 2 ? lMax.y : lMin.y, b & 4 ? lMax.z : lMin.z);\r\n                Vector3.TransformCoordinatesToRef(corner, wm, corner);\r\n                min.minimizeInPlace(corner);\r\n                max.maximizeInPlace(corner);\r\n            }\r\n        }\r\n        for (let i = 0; i < this._partProxies.length; i++) {\r\n            const proxy = this._partProxies[i];\r\n            if (!proxy || (this._partVisibility[i] ?? 1.0) === 0) {\r\n                continue;\r\n            }\r\n            proxy.computeWorldMatrix(false);\r\n            const bb = proxy.getBoundingInfo().boundingBox;\r\n            min.minimizeInPlace(bb.minimumWorld);\r\n            max.maximizeInPlace(bb.maximumWorld);\r\n        }\r\n        return { min, max };\r\n    }\r\n\r\n    /**\r\n     * Disposes proxy meshes and clears part data in addition to the base class GPU resources.\r\n     * @param doNotRecurse Set to true to not recurse into each children\r\n     */\r\n    public override dispose(doNotRecurse?: boolean): void {\r\n        if (this._budgetObserver) {\r\n            this.getScene().onBeforeRenderObservable.remove(this._budgetObserver);\r\n            this._budgetObserver = null;\r\n        }\r\n        this._lodBudgetParticipants = [];\r\n        for (const proxy of this._partProxies) {\r\n            proxy.dispose();\r\n        }\r\n        this._partIndicesTexture?.dispose();\r\n        this._partProxies = [];\r\n        this._partMatrices = [];\r\n        this._partVisibility = [];\r\n        this._partIndicesTexture = null;\r\n        this._part0LocalMin = null;\r\n        this._part0LocalMax = null;\r\n        super.dispose(doNotRecurse);\r\n    }\r\n\r\n    // ---------------------------------------------------------------------------\r\n    // Worker and material hooks\r\n    // ---------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Posts the initial per-part data to the sort worker after it has been created.\r\n     * Sends the current part matrices and group index array so the worker can correctly\r\n     * weight depth values per part.\r\n     * @param worker the newly created sort worker\r\n     */\r\n    protected override _onWorkerCreated(worker: Worker): void {\r\n        worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_MATRICES, partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n        worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: this._partIndices ? new Uint8Array(this._partIndices) : null });\r\n    }\r\n\r\n    /**\r\n     * Stores the raw part index array, padded to texture length, so the worker and GPU texture\r\n     * creation step have access to it.\r\n     * @param partIndices - the raw part indices array received during a data load\r\n     * @param textureLength - the padded texture length to allocate into\r\n     */\r\n    protected override _onIndexDataReceived(partIndices: Uint8Array, textureLength: number): void {\r\n        this._partIndices = new Uint8Array(textureLength);\r\n        this._partIndices.set(partIndices);\r\n    }\r\n\r\n    /**\r\n     * Returns `true` when at least one part has been added to this compound mesh.\r\n     * Returns `false` before any parts are added, so the mesh renders in normal\r\n     * (non-compound) mode until the first addPart/addParts call. This matches the\r\n     * old base-class behavior of `this._partMatrices.length > 0` and avoids\r\n     * binding unset partWorld uniforms (which would cause division-by-zero in the\r\n     * Gaussian projection Jacobian and produce huge distorted splats).\r\n     * @internal\r\n     */\r\n    public override get isCompound(): boolean {\r\n        return this._partMatrices.length > 0;\r\n    }\r\n\r\n    /**\r\n     * During a removePart rebuild, keep the existing sort worker alive rather than\r\n     * tearing it down and spinning up a new one. This avoids startup latency and the\r\n     * transient state window where a stale sort could fire against an incomplete\r\n     * partMatrices array.\r\n     * Outside of a rebuild the base-class behaviour is used unchanged.\r\n     */\r\n    protected override _instantiateWorker(): void {\r\n        if (this._rebuilding && this._worker) {\r\n            // Worker already exists and is kept alive; just resize the splat-index buffer.\r\n            this._updateSplatIndexBuffer(this._vertexCount);\r\n            return;\r\n        }\r\n        super._instantiateWorker();\r\n    }\r\n\r\n    /**\r\n     * Ensures the part-index GPU texture exists at the start of an incremental update.\r\n     * Called before the sub-texture upload so the correct texture is available for the first batch.\r\n     * @param textureSize - current texture dimensions\r\n     */\r\n    protected override _onIncrementalUpdateStart(textureSize: Vector2): void {\r\n        this._ensurePartIndicesTexture(textureSize, this._partIndices ?? undefined);\r\n    }\r\n\r\n    /**\r\n     * Posts positions (via super) and then additionally posts the current part-index array\r\n     * to the sort worker so it can associate each splat with its part.\r\n     */\r\n    protected override _notifyWorkerNewData(): void {\r\n        super._notifyWorkerNewData();\r\n        if (this._worker) {\r\n            this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: this._partIndices ?? null });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Binds all compound-specific shader uniforms: the group index texture, per-part world\r\n     * matrices, and per-part visibility values.\r\n     * @param effect the shader effect that is being bound\r\n     * @internal\r\n     */\r\n    public override bindExtraEffectUniforms(effect: Effect): void {\r\n        if (!this._partIndicesTexture) {\r\n            return;\r\n        }\r\n        effect.setTexture(\"partIndicesTexture\", this._partIndicesTexture);\r\n        const partWorldDataLength = this.partCount * 16;\r\n        if (this._partWorldData.length !== partWorldDataLength) {\r\n            this._partWorldData = new Float32Array(partWorldDataLength);\r\n        }\r\n        const partWorldData = this._partWorldData;\r\n        for (let i = 0; i < this.partCount; i++) {\r\n            this._partMatrices[i].toArray(partWorldData, i * 16);\r\n        }\r\n        effect.setMatrices(\"partWorld\", partWorldData);\r\n        const partVisibilityData = this._partVisibilityData;\r\n        partVisibilityData.length = this.partCount;\r\n        for (let i = 0; i < this.partCount; i++) {\r\n            partVisibilityData[i] = this._partVisibility[i] ?? 1.0;\r\n        }\r\n        effect.setArray(\"partVisibility\", partVisibilityData);\r\n    }\r\n\r\n    // ---------------------------------------------------------------------------\r\n    // Part matrix / visibility management\r\n    // ---------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Gets the number of parts in the compound.\r\n     */\r\n    public get partCount(): number {\r\n        return this._partMatrices.length;\r\n    }\r\n\r\n    /**\r\n     * Shared LOD splat budget for the whole compound: a cap on the total splats its budget-participating LOD\r\n     * engines (hosted streamed parts) render together, net of static parts. `0`/undefined disables it (each stream\r\n     * uses its own budget, or none). Setting it apportions the cap across all registered participants by demand and\r\n     * takes effect on the next frame. See {@link IGaussianSplattingLodBudgetParticipant}.\r\n     * @experimental\r\n     */\r\n    public get splatBudget(): number {\r\n        return this._splatBudget;\r\n    }\r\n\r\n    public set splatBudget(value: number) {\r\n        const budget = value > 0 ? Math.floor(value) : 0;\r\n        if (budget === this._splatBudget) {\r\n            return;\r\n        }\r\n        this._splatBudget = budget;\r\n        this._updateBudgetCoordination();\r\n    }\r\n\r\n    /**\r\n     * Registers a LOD engine to share this compound's {@link splatBudget}. The compound apportions the budget\r\n     * across all registered participants each frame. No-op if already registered.\r\n     * @param participant the LOD engine (e.g. a hosted streamed part)\r\n     * @experimental\r\n     */\r\n    public registerLodBudgetParticipant(participant: IGaussianSplattingLodBudgetParticipant): void {\r\n        if (this._lodBudgetParticipants.indexOf(participant) === -1) {\r\n            this._lodBudgetParticipants.push(participant);\r\n            this._updateBudgetCoordination();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes a previously registered budget participant and releases its coordinated allocation (it reverts to its\r\n     * own budget).\r\n     * @param participant the LOD engine to remove\r\n     * @experimental\r\n     */\r\n    public unregisterLodBudgetParticipant(participant: IGaussianSplattingLodBudgetParticipant): void {\r\n        const i = this._lodBudgetParticipants.indexOf(participant);\r\n        if (i !== -1) {\r\n            this._lodBudgetParticipants.splice(i, 1);\r\n            participant.setBudgetAllocation(null);\r\n            this._updateBudgetCoordination();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Total splats contributed by static (non-streaming) parts — the fixed floor subtracted from the budget before\r\n     * the streamable remainder is apportioned. Streaming regions are excluded (their rendered count is LOD-driven).\r\n     * @returns the static parts' splat count\r\n     */\r\n    private _staticSplatCount(): number {\r\n        let proxied = 0;\r\n        let sum = 0;\r\n        for (const proxy of this._partProxies) {\r\n            if (!proxy) {\r\n                continue;\r\n            }\r\n            proxied += proxy._vertexCount; // all proxies feed the legacy part-0 derivation below\r\n            // Count only static (non-streaming), non-tombstoned parts: streaming regions are LOD-driven, and a\r\n            // tombstoned part renders nothing (empty active range) until compaction reclaims its rows.\r\n            if (!this._streamingStates.some((s) => s.proxy === proxy) && !this._tombstonedPartIndices.has(proxy.partIndex)) {\r\n                sum += proxy._vertexCount;\r\n            }\r\n        }\r\n        // Legacy layout: the compound's own splat data is an implicit, unproxied part 0 (always static). Its count\r\n        // is the atlas total minus every proxied part — the same derivation used in _addPartsInternal. Excluded when\r\n        // part 0 has been tombstoned.\r\n        if (!this._partProxies[0] && !this._tombstonedPartIndices.has(0)) {\r\n            sum += Math.max(0, this._vertexCount - proxied);\r\n        }\r\n        return sum;\r\n    }\r\n\r\n    /**\r\n     * Installs or removes the per-frame apportionment observer so it runs only while a budget and at least one\r\n     * participant are both present. When coordination turns off, participants are released to their own budgets.\r\n     */\r\n    private _updateBudgetCoordination(): void {\r\n        const active = this._splatBudget > 0 && this._lodBudgetParticipants.length > 0;\r\n        if (active && !this._budgetObserver) {\r\n            // Runs before the streams' own onBeforeRender LOD frames (the compound is created before its streams),\r\n            // so each stream reads a fresh allocation the same frame; a one-frame lag is harmless regardless.\r\n            this._budgetObserver = this.getScene().onBeforeRenderObservable.add(() => this._apportionBudget());\r\n        } else if (!active && this._budgetObserver) {\r\n            this.getScene().onBeforeRenderObservable.remove(this._budgetObserver);\r\n            this._budgetObserver = null;\r\n            for (const participant of this._lodBudgetParticipants) {\r\n                participant.setBudgetAllocation(null);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Apportions {@link splatBudget} (net of {@link _staticSplatCount}) across the registered participants by demand\r\n     * via water-filling: each gets `min(demand, fairShare)` and any leftover is redistributed to the still-unmet\r\n     * ones. Pushes each participant its allocation.\r\n     */\r\n    private _apportionBudget(): void {\r\n        const participants = this._lodBudgetParticipants;\r\n        if (this._splatBudget <= 0 || participants.length === 0) {\r\n            return;\r\n        }\r\n        const streamable = Math.max(0, this._splatBudget - this._staticSplatCount());\r\n        // Reuse the scratch arrays (resized in place) so this per-frame path allocates nothing for a stable participant set.\r\n        const n = participants.length;\r\n        const demands = this._budgetDemands;\r\n        const alloc = this._budgetAlloc;\r\n        const settled = this._budgetSettled;\r\n        demands.length = n;\r\n        alloc.length = n;\r\n        settled.length = n;\r\n        for (let i = 0; i < n; i++) {\r\n            demands[i] = Math.max(0, participants[i].getBudgetDemand());\r\n            alloc[i] = 0;\r\n            settled[i] = false;\r\n        }\r\n        let remaining = streamable;\r\n        let activeCount = participants.length;\r\n        // Water-fill: repeatedly satisfy every participant whose demand is at or below the equal share, then split\r\n        // the remainder among the rest. Terminates in ≤ participants.length passes.\r\n        for (let pass = 0; pass < participants.length && activeCount > 0 && remaining > 0; pass++) {\r\n            const share = remaining / activeCount;\r\n            let progressed = false;\r\n            for (let i = 0; i < participants.length; i++) {\r\n                if (!settled[i] && demands[i] <= share) {\r\n                    alloc[i] = demands[i];\r\n                    remaining -= demands[i];\r\n                    settled[i] = true;\r\n                    activeCount--;\r\n                    progressed = true;\r\n                }\r\n            }\r\n            if (!progressed) {\r\n                for (let i = 0; i < participants.length; i++) {\r\n                    if (!settled[i]) {\r\n                        alloc[i] = share;\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n        for (let i = 0; i < participants.length; i++) {\r\n            participants[i].setBudgetAllocation(Math.floor(alloc[i]));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the part visibility array.\r\n     */\r\n    public get partVisibility(): number[] {\r\n        return this._partVisibility;\r\n    }\r\n\r\n    /**\r\n     * Sets the world matrix for a specific part of the compound.\r\n     * This will trigger a re-sort of the mesh.\r\n     * The `_partMatrices` array is automatically extended when `partIndex >= partCount`.\r\n     * @param partIndex index of the part\r\n     * @param worldMatrix the world matrix to set\r\n     */\r\n    public setWorldMatrixForPart(partIndex: number, worldMatrix: Matrix): void {\r\n        if (this._partMatrices.length <= partIndex) {\r\n            this.computeWorldMatrix(true);\r\n            const defaultMatrix = this.getWorldMatrix();\r\n            while (this._partMatrices.length <= partIndex) {\r\n                this._partMatrices.push(defaultMatrix.clone());\r\n                this._partVisibility.push(1.0);\r\n            }\r\n        }\r\n        // Skip the post / sort if the matrix is unchanged. Babylon recomputes the proxy mesh's world matrix every frame\r\n        // and fires onAfterWorldMatrixUpdateObservable, so without this guard a stable scene would queue a forced sort\r\n        // every frame and `isReady()` would never settle (sortRequestId would keep advancing past sortAppliedId).\r\n        if (this._partMatrices[partIndex].equals(worldMatrix)) {\r\n            return;\r\n        }\r\n        this._partMatrices[partIndex].copyFrom(worldMatrix);\r\n        // During a batch rebuild suppress intermediate posts — the final correct set is posted\r\n        // once the full rebuild completes (at the end of removePart).\r\n        if (!this._rebuilding) {\r\n            if (this._worker) {\r\n                this._worker.postMessage({\r\n                    command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n                    partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n                });\r\n            }\r\n            this._postToWorker(true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the world matrix for a specific part of the compound.\r\n     * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n     * @returns the world matrix for the part, or the current world matrix of the mesh if the part is not found\r\n     */\r\n    public getWorldMatrixForPart(partIndex: number): Matrix {\r\n        return this._partMatrices[partIndex] ?? this.getWorldMatrix();\r\n    }\r\n\r\n    /**\r\n     * Gets the visibility for a specific part of the compound.\r\n     * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n     * @returns the visibility value (0.0 to 1.0) for the part\r\n     */\r\n    public getPartVisibility(partIndex: number): number {\r\n        return this._partVisibility[partIndex] ?? 1.0;\r\n    }\r\n\r\n    /**\r\n     * Sets the visibility for a specific part of the compound.\r\n     * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n     * @param value the visibility value (0.0 to 1.0) to set\r\n     */\r\n    public setPartVisibility(partIndex: number, value: number): void {\r\n        this._partVisibility[partIndex] = Math.max(0.0, Math.min(1.0, value));\r\n    }\r\n\r\n    /**\r\n     * Restricts which source splats of a single part are sorted and rendered, in GLOBAL source-splat\r\n     * coordinates (offsets into the merged atlas). Static parts render fully by default; a streaming\r\n     * part uses this to render only its currently-active LOD splats. The compound recomputes the union\r\n     * of every part's active ranges and drives the single shared depth sort / draw with it, so all\r\n     * parts still sort together in one pass.\r\n     *\r\n     * Passing `null` clears the override for that part (it reverts to rendering its full range). When no\r\n     * part has an override, the compound clears the range filter entirely (renders every splat), which\r\n     * preserves the non-streaming fast path.\r\n     * @param partIndex index of the part to constrain\r\n     * @param ranges active global source-splat ranges for the part, or `null` to render the whole part\r\n     */\r\n    public setPartSplatRanges(partIndex: number, ranges: Nullable<readonly IGaussianSplattingSplatRange[]>): void {\r\n        if (partIndex < 0) {\r\n            return;\r\n        }\r\n        this._partSplatRanges[partIndex] = ranges ? ranges.map((r) => ({ offset: r.offset, count: r.count })) : null;\r\n        this._refreshPartRangeUnion();\r\n    }\r\n\r\n    /**\r\n     * Recomputes the global active-range union across all parts and pushes it to the shared sort/draw\r\n     * via the base {@link setSplatIndexRanges}. When no part carries an override the filter is cleared\r\n     * (render everything). A part without an override contributes its full `[offset, count)` derived\r\n     * from its proxy; a part with an override contributes exactly those ranges.\r\n     */\r\n    private _refreshPartRangeUnion(): void {\r\n        let hasOverride = false;\r\n        for (let i = 0; i < this._partSplatRanges.length; i++) {\r\n            if (this._partSplatRanges[i]) {\r\n                hasOverride = true;\r\n                break;\r\n            }\r\n        }\r\n        if (!hasOverride) {\r\n            // No part constrains its splats: render the whole atlas (base fast path).\r\n            this.setSplatIndexRanges(null);\r\n            return;\r\n        }\r\n\r\n        const collected: IGaussianSplattingSplatRange[] = [];\r\n        const partCount = this.partCount;\r\n        for (let partIndex = 0; partIndex < partCount; partIndex++) {\r\n            const override = this._partSplatRanges[partIndex];\r\n            if (override) {\r\n                for (const range of override) {\r\n                    if (range.count > 0) {\r\n                        collected.push({ offset: range.offset, count: range.count });\r\n                    }\r\n                }\r\n                continue;\r\n            }\r\n            // No override: render the part's full extent, derived from its proxy.\r\n            const proxy = this._partProxies[partIndex];\r\n            if (proxy && proxy._vertexCount > 0) {\r\n                collected.push({ offset: proxy._splatsDataOffset, count: proxy._vertexCount });\r\n            }\r\n        }\r\n\r\n        this.setSplatIndexRanges(GaussianSplattingMesh._CoalesceSplatRanges(collected));\r\n    }\r\n\r\n    /**\r\n     * Sorts and merges adjacent/overlapping source-splat ranges so the interval list handed to the sort\r\n     * worker stays compact (parts occupy disjoint regions, so this mainly coalesces contiguous parts).\r\n     * @param ranges raw ranges\r\n     * @returns coalesced ranges sorted by offset\r\n     */\r\n    private static _CoalesceSplatRanges(ranges: IGaussianSplattingSplatRange[]): IGaussianSplattingSplatRange[] {\r\n        if (ranges.length <= 1) {\r\n            return ranges;\r\n        }\r\n        const sorted = ranges.slice().sort((a, b) => a.offset - b.offset);\r\n        const merged: IGaussianSplattingSplatRange[] = [{ offset: sorted[0].offset, count: sorted[0].count }];\r\n        for (let i = 1; i < sorted.length; i++) {\r\n            const last = merged[merged.length - 1];\r\n            const range = sorted[i];\r\n            const lastEnd = last.offset + last.count;\r\n            if (range.offset <= lastEnd) {\r\n                const end = Math.max(lastEnd, range.offset + range.count);\r\n                last.count = end - last.offset;\r\n            } else {\r\n                merged.push({ offset: range.offset, count: range.count });\r\n            }\r\n        }\r\n        return merged;\r\n    }\r\n\r\n    protected override _copyTextures(source: GaussianSplattingMeshBase): void {\r\n        super._copyTextures(source);\r\n        this._partIndicesTexture = (source as GaussianSplattingMesh)._partIndicesTexture?.clone()!;\r\n    }\r\n\r\n    protected override _onUpdateTextures(textureSize: Vector2) {\r\n        const createTextureFromDataU8 = (data: Uint8Array, width: number, height: number, format: number) => {\r\n            return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n        };\r\n\r\n        // Keep the part indices texture in sync with _partIndices whenever textures are rebuilt.\r\n        // The old \"only create if absent\" logic left the texture stale after a second addPart/addParts\r\n        // call that doesn't change the texture dimensions: all new splats kept reading partIndex=0\r\n        // (the first part), causing wrong positions, broken GPU picking, and shared movement.\r\n        if (this._partIndices) {\r\n            const buffer = new Uint8Array(this._partIndices);\r\n            if (!this._partIndicesTexture) {\r\n                this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n                this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n            } else {\r\n                const existingSize = this._partIndicesTexture.getSize();\r\n                if (existingSize.width !== textureSize.x || existingSize.height !== textureSize.y) {\r\n                    // Dimensions changed — dispose and recreate at the new size.\r\n                    this._partIndicesTexture.dispose();\r\n                    this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n                    this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                    this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                } else {\r\n                    // Same size — update data in-place (e.g. second addParts fitting in existing dims).\r\n                    this._updateTextureFromData(this._partIndicesTexture, buffer, textureSize.x, 0, textureSize.y);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override _updateSubTextures(\r\n        splatPositions: Float32Array,\r\n        covA: Uint16Array,\r\n        covB: Uint16Array,\r\n        colorArray: Uint8Array,\r\n        lineStart: number,\r\n        lineCount: number,\r\n        sh?: Uint8Array[],\r\n        partIndices?: Uint8Array\r\n    ): void {\r\n        super._updateSubTextures(splatPositions, covA, covB, colorArray, lineStart, lineCount, sh);\r\n        if (partIndices && this._partIndicesTexture) {\r\n            const textureSize = this._getTextureSize(this._vertexCount);\r\n            const texelStart = lineStart * textureSize.x;\r\n            const texelCount = lineCount * textureSize.x;\r\n            const partIndicesView = new Uint8Array(partIndices.buffer, texelStart, texelCount);\r\n            this._updateTextureFromData(this._partIndicesTexture, partIndicesView, textureSize.x, lineStart, lineCount);\r\n\r\n            if (this._worker) {\r\n                this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: partIndices });\r\n            }\r\n        }\r\n    }\r\n\r\n    // ---------------------------------------------------------------------------\r\n    // Private helpers\r\n    // ---------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Creates the part indices GPU texture the first time an incremental addPart introduces\r\n     * compound data. Has no effect if the texture already exists or no partIndices are provided.\r\n     * @param textureSize - Current texture dimensions\r\n     * @param partIndices - Part index data; if undefined the method is a no-op\r\n     */\r\n    protected _ensurePartIndicesTexture(textureSize: Vector2, partIndices: Uint8Array | undefined): void {\r\n        if (!partIndices || this._partIndicesTexture) {\r\n            return;\r\n        }\r\n        const buffer = new Uint8Array(this._partIndices!);\r\n        this._partIndicesTexture = new RawTexture(\r\n            buffer,\r\n            textureSize.x,\r\n            textureSize.y,\r\n            Constants.TEXTUREFORMAT_RED,\r\n            this._scene,\r\n            false,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        );\r\n        this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        if (this._worker) {\r\n            this._worker.postMessage({ command: GaussianSplattingSortWorkerCommand.PART_INDICES, partIndices: partIndices ?? null });\r\n        }\r\n    }\r\n\r\n    private _appendPartSourceToArrays(\r\n        source: IGaussianSplattingPartSource,\r\n        dstOffset: number,\r\n        covA: Uint16Array,\r\n        covB: Uint16Array,\r\n        colorArray: Uint8Array,\r\n        sh: Uint8Array[] | undefined,\r\n        minimum: Vector3,\r\n        maximum: Vector3\r\n    ): void {\r\n        this._appendSourceToArrays(source as unknown as GaussianSplattingMeshBase, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n    }\r\n\r\n    private _createRetainedPartSource(proxy: GaussianSplattingPartProxyMesh): Nullable<IGaussianSplattingPartSource> {\r\n        if (!this._splatsData || (this._shDegree > 0 && !this._shData)) {\r\n            return null;\r\n        }\r\n\r\n        const splatByteOffset = proxy._splatsDataOffset * _GaussianSplattingBytesPerSplat;\r\n        const splatByteLength = proxy._vertexCount * _GaussianSplattingBytesPerSplat;\r\n        const shByteOffset = proxy._shDataOffset * _GaussianSplattingBytesPerShTexel;\r\n        const shByteLength = proxy._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n        const splatBytes = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n\r\n        return {\r\n            name: proxy.name,\r\n            _vertexCount: proxy._vertexCount,\r\n            _splatsData: splatBytes.subarray(splatByteOffset, splatByteOffset + splatByteLength),\r\n            _shData: this._shData?.map((texture) => texture.subarray(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n            _shDegree: this._shData ? this._shDegree : 0,\r\n            isCompound: false,\r\n            getWorldMatrix: () => proxy.getWorldMatrix(),\r\n            getBoundingInfo: () => proxy.getBoundingInfo(),\r\n            dispose: () => {},\r\n        };\r\n    }\r\n\r\n    private _retainMergedPartData(existingVertexCount: number, totalCount: number, others: IGaussianSplattingPartSource[], shDegree: number): void {\r\n        if (!this._keepInRam && !this._alwaysRetainSplatsData) {\r\n            this._splatsData = null;\r\n            this._shData = null;\r\n            return;\r\n        }\r\n\r\n        const mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n        let splatByteOffset = 0;\r\n\r\n        if (this._splatsData && existingVertexCount > 0) {\r\n            mergedSplatsData.set(\r\n                GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData).subarray(0, existingVertexCount * _GaussianSplattingBytesPerSplat),\r\n                splatByteOffset\r\n            );\r\n            splatByteOffset += existingVertexCount * _GaussianSplattingBytesPerSplat;\r\n        }\r\n\r\n        for (const other of others) {\r\n            // A reserved-empty streaming source carries no CPU data but still owns its slot in the atlas (its\r\n            // GPU rows are decoded later). Advance past that slot regardless of data so a real source appended\r\n            // after it lands at the offset its proxy's _splatsDataOffset points to — matching the unconditional\r\n            // GPU dstOffset advance in _addPartsInternal (and the SH loop below).\r\n            const splatByteLength = other._vertexCount * _GaussianSplattingBytesPerSplat;\r\n            if (other._splatsData) {\r\n                mergedSplatsData.set(GaussianSplattingMeshBase._GetSplatDataBytes(other._splatsData).subarray(0, splatByteLength), splatByteOffset);\r\n            }\r\n            splatByteOffset += splatByteLength;\r\n        }\r\n\r\n        this._splatsData = mergedSplatsData.buffer;\r\n\r\n        if (shDegree <= 0) {\r\n            this._shData = null;\r\n            return;\r\n        }\r\n\r\n        // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n        // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n        // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n        const shTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n        const mergedShData = AllocateShBuffers(shTextureCount, totalCount * _GaussianSplattingBytesPerShTexel);\r\n\r\n        let shByteOffset = 0;\r\n        if (this._shData && existingVertexCount > 0) {\r\n            const existingShByteLength = existingVertexCount * _GaussianSplattingBytesPerShTexel;\r\n            for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n                if (textureIndex < this._shData.length) {\r\n                    mergedShData[textureIndex].set(this._shData[textureIndex].subarray(0, existingShByteLength), shByteOffset);\r\n                }\r\n            }\r\n            shByteOffset += existingShByteLength;\r\n        }\r\n\r\n        for (const other of others) {\r\n            const otherShByteLength = other._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n            if (other._shData) {\r\n                for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n                    if (textureIndex < other._shData.length) {\r\n                        mergedShData[textureIndex].set(other._shData[textureIndex].subarray(0, otherShByteLength), shByteOffset);\r\n                    }\r\n                }\r\n            }\r\n            shByteOffset += otherShByteLength;\r\n        }\r\n\r\n        this._shData = mergedShData;\r\n    }\r\n\r\n    /**\r\n     * Core implementation for adding one or more source parts as new\r\n     * parts. Writes directly into texture-sized CPU arrays, updates the retained merged source\r\n     * buffers, and uploads in one pass.\r\n     *\r\n     * @param others - Source meshes to append (must each be non-compound and fully loaded)\r\n     * @param disposeOthers - Dispose source meshes after appending\r\n     * @returns Proxy meshes and their assigned part indices\r\n     */\r\n    protected _addPartsInternal(others: IGaussianSplattingPartSource[], disposeOthers: boolean): { proxyMeshes: GaussianSplattingPartProxyMesh[]; assignedPartIndices: number[] } {\r\n        if (others.length === 0) {\r\n            return { proxyMeshes: [], assignedPartIndices: [] };\r\n        }\r\n\r\n        // Validate\r\n        for (const other of others) {\r\n            // Reserved-empty placeholders (reserveStreamingPart) intentionally carry no splat data —\r\n            // their atlas region is left zeroed (invisible) for a streaming engine to decode into later.\r\n            if (!other._splatsData && !other._isReservedEmpty) {\r\n                throw new Error(`To call addPart()/addParts(), each source mesh must be fully loaded`);\r\n            }\r\n            if (other.isCompound) {\r\n                throw new Error(`To call addPart()/addParts(), each source mesh must not be a compound`);\r\n            }\r\n        }\r\n\r\n        const splatCountA = this._vertexCount;\r\n        const totalOtherCount = others.reduce((s, o) => s + o._vertexCount, 0);\r\n        const totalCount = splatCountA + totalOtherCount;\r\n\r\n        const textureSize = this._getTextureSize(totalCount);\r\n        const textureLength = textureSize.x * textureSize.y;\r\n        const covBSItemSize = this._useRGBACovariants ? 4 : 2;\r\n\r\n        // Allocate destination arrays for the full new texture\r\n        const covA = new Uint16Array(textureLength * 4);\r\n        const covB = new Uint16Array(covBSItemSize * textureLength);\r\n        const colorArray = new Uint8Array(textureLength * 4);\r\n\r\n        // Merged SH degree. The compound carries SH if any existing or new part has it, or a hosted stream bakes it.\r\n        // Parts without SH get neutral (128) fill. `_streamingShDegree` is the degree of the live SH streams (recomputed\r\n        // from surviving parts, so it shrinks when one is removed); folding it in keeps `_shDegree` correct across a\r\n        // rebuild (which resets it) and drops it to 0 when no SH stream survives.\r\n        const streamingShDegree = this._streamingShDegree;\r\n        const staticHasSH = this._shDegree > 0 || others.some((o) => o._shData !== null);\r\n        const hasSH = staticHasSH || streamingShDegree > 0;\r\n        const shDegreeNew = hasSH ? Math.max(this._shDegree, streamingShDegree, ...others.map((o) => o._shDegree)) : 0;\r\n        let sh: Uint8Array[] | undefined = undefined;\r\n        // Allocate the neutral (128 == 0 after decode) CPU SH base whenever the atlas carries SH, and upload it over\r\n        // the whole atlas before any SH stream restores its region, so non-SH regions read neutral instead of raw 0\r\n        // (which decodes to -1).\r\n        if (hasSH && shDegreeNew > 0) {\r\n            // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n            // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n            // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n            const shTextureCount = Math.ceil((((shDegreeNew + 1) * (shDegreeNew + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n            sh = AllocateShBuffers(shTextureCount, textureLength * _GaussianSplattingBytesPerShTexel);\r\n        }\r\n\r\n        // --- Incremental path: can we reuse the already-committed GPU region? ---\r\n        const incremental = this._canReuseCachedData(splatCountA, totalCount, sh?.length ?? 0);\r\n        const firstNewLine = incremental ? Math.floor(splatCountA / textureSize.x) : 0;\r\n\r\n        const minimum = incremental ? this._cachedBoundingMin!.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const maximum = incremental ? this._cachedBoundingMax!.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n        // Preserve existing processed positions in the new array\r\n        const oldPositions = this._splatPositions;\r\n        this._splatPositions = new Float32Array(4 * textureLength);\r\n        if (incremental && oldPositions) {\r\n            this._splatPositions.set(oldPositions.subarray(0, splatCountA * 4));\r\n        }\r\n\r\n        // --- Build part indices ---\r\n        let nextPartIndex = this.partCount;\r\n        let partIndicesA = this._partIndices;\r\n        if (!partIndicesA) {\r\n            // First addPart on a plain mesh: assign its splats to part 0\r\n            partIndicesA = new Uint8Array(splatCountA);\r\n            nextPartIndex = splatCountA > 0 ? 1 : 0;\r\n        }\r\n\r\n        this._partIndices = new Uint8Array(textureLength);\r\n        this._partIndices.set(partIndicesA.subarray(0, splatCountA));\r\n\r\n        const assignedPartIndices: number[] = [];\r\n        const assignedSplatsDataOffsets: number[] = [];\r\n        let dstOffset = splatCountA;\r\n        const maxPartCount = GetGaussianSplattingMaxPartCount(this._scene.getEngine());\r\n        for (const other of others) {\r\n            if (nextPartIndex >= maxPartCount) {\r\n                throw new Error(`Cannot add part, as the maximum part count (${maxPartCount}) has been reached`);\r\n            }\r\n            const newPartIndex = nextPartIndex++;\r\n            assignedPartIndices.push(newPartIndex);\r\n            assignedSplatsDataOffsets.push(dstOffset);\r\n            this._partIndices.fill(newPartIndex, dstOffset, dstOffset + other._vertexCount);\r\n            dstOffset += other._vertexCount;\r\n        }\r\n\r\n        // --- Process source data ---\r\n        if (!incremental) {\r\n            // Full rebuild path — only reached when the GPU texture must be reallocated\r\n            // (either the texture height needs to grow to fit the new total, or this is\r\n            // the very first addPart onto a mesh with no GPU textures yet). In the common\r\n            // case where the texture height is unchanged, `incremental` is true and this\r\n            // entire block is skipped. The `splatCountA > 0` guard avoids redundant work\r\n            // on the first-ever addPart when the compound mesh starts empty.\r\n            if (splatCountA > 0) {\r\n                if (this._partProxies.length > 0) {\r\n                    // Already compound: rebuild every existing part from its stored source data.\r\n                    //\r\n                    // DESIGN NOTE: The intended use of GaussianSplattingMesh / GaussianSplattingCompoundMesh\r\n                    // in compound mode is to start EMPTY and compose parts exclusively via addPart/addParts.\r\n                    // In a future major version this will be the only supported path and the \"own data\"\r\n                    // legacy branch below will be removed.\r\n                    //\r\n                    // Until then, two layouts are possible:\r\n                    //   A) LEGACY — compound loaded its own splat data (via URL or updateData) before\r\n                    //      any addPart call. _partProxies[0] is undefined; the mesh's own splat data\r\n                    //      is treated as an implicit \"part 0\" in this._splatsData. Proxied parts occupy\r\n                    //      indices 1+. This layout will be deprecated in the next major version.\r\n                    //   B) PREFERRED — compound started empty; first addPart assigned partIndex=0.\r\n                    //      _partProxies[0] is set; this._splatsData is null; all parts are proxied.\r\n                    let rebuildOffset = 0;\r\n\r\n                    // Rebuild the compound's legacy \"own\" data at part 0 (scenario A only).\r\n                    // Skipped in the preferred empty-composer path (scenario B).\r\n                    if (!this._partProxies[0] && this._splatsData) {\r\n                        const proxyVertexCount = this._partProxies.reduce((sum, proxy) => sum + (proxy ? proxy._vertexCount : 0), 0);\r\n                        const part0Count = splatCountA - proxyVertexCount;\r\n                        if (part0Count > 0) {\r\n                            const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n                            const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n                            for (let i = 0; i < part0Count; i++) {\r\n                                this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n                            }\r\n                            if (sh && this._shData) {\r\n                                for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n                                    if (texIdx < this._shData.length) {\r\n                                        sh[texIdx].set(this._shData[texIdx].subarray(0, part0Count * _GaussianSplattingBytesPerShTexel), 0);\r\n                                    }\r\n                                }\r\n                            }\r\n                            rebuildOffset += part0Count;\r\n                        }\r\n                    }\r\n\r\n                    // Rebuild all proxied parts. Loop from index 0 because in the preferred\r\n                    // scenario B, part 0 is itself a proxied part with no implicit \"own\" data.\r\n                    for (let partIndex = 0; partIndex < this._partProxies.length; partIndex++) {\r\n                        const proxy = this._partProxies[partIndex];\r\n                        if (!proxy) {\r\n                            continue;\r\n                        }\r\n                        // Streaming parts have no retained CPU source — their atlas rows (core + SH) are\r\n                        // GPU-authoritative and preserved across the rebuild by the backup/restore hooks. Leave their\r\n                        // rows at the fresh-array defaults (zero core, neutral SH) for the restore to overwrite; just\r\n                        // advance the offset. (With a static part present _splatsData is non-null and these would\r\n                        // otherwise reconstruct as a harmless zeros-slice; with only streaming parts it is null and\r\n                        // _createRetainedPartSource returns null — so this skip is required, not just an optimization.)\r\n                        if (this._streamingStates.some((s) => s.proxy === proxy)) {\r\n                            rebuildOffset += proxy._vertexCount;\r\n                            continue;\r\n                        }\r\n                        const source = this._createRetainedPartSource(proxy);\r\n                        if (!source) {\r\n                            throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n                        }\r\n                        this._appendPartSourceToArrays(source, rebuildOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n                        rebuildOffset += source._vertexCount;\r\n                    }\r\n                } else {\r\n                    // No proxies yet: this is the very first addPart call on a mesh that loaded\r\n                    // its own splat data (scenario A legacy path). Re-process that own data so\r\n                    // it occupies the start of the new texture before the incoming part is appended.\r\n                    // In the preferred scenario B (empty composer) splatCountA is 0 and this\r\n                    // entire branch is skipped by the outer `if (splatCountA > 0)` guard.\r\n                    if (this._splatsData) {\r\n                        const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n                        const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n                        for (let i = 0; i < splatCountA; i++) {\r\n                            this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n                        }\r\n                        if (sh && this._shData) {\r\n                            for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n                                if (texIdx < this._shData.length) {\r\n                                    sh[texIdx].set(this._shData[texIdx].subarray(0, splatCountA * _GaussianSplattingBytesPerShTexel), 0);\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Incremental path: rebuild the partial first row (indices firstNewTexel to splatCountA-1)\r\n        // so _updateSubTextures does not upload stale zeros over those already-committed texels.\r\n        // The base-class _updateData always re-processes from firstNewTexel for the same reason;\r\n        // the compound path must do the same.\r\n        // Boundary-row SH is restored after _retainMergedPartData (see below), where _shData is ready.\r\n        if (incremental) {\r\n            const firstNewTexel = firstNewLine * textureSize.x;\r\n            if (firstNewTexel < splatCountA) {\r\n                if (this._partProxies.length === 0) {\r\n                    // No proxies: the mesh loaded its own splat data and this is the first\r\n                    // addPart call (scenario A legacy path). Re-process the partial boundary\r\n                    // row so it is not clobbered by stale zeros during the sub-texture upload.\r\n                    if (this._splatsData) {\r\n                        const uBufA = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n                        const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n                        for (let i = firstNewTexel; i < splatCountA; i++) {\r\n                            this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false, i);\r\n                        }\r\n                    }\r\n                } else {\r\n                    // Already compound: build a per-partIndex source lookup so each splat in the\r\n                    // partial boundary row can be re-processed from its original source buffer.\r\n                    //\r\n                    // Handles both layouts (see full-rebuild comment above):\r\n                    //   A) LEGACY: _partProxies[0] absent → seed lookup[0] with this._splatsData\r\n                    //   B) PREFERRED: _partProxies[0] present → all entries filled from proxies\r\n                    const proxyTotal = this._partProxies.reduce((s, p) => s + (p ? p._vertexCount : 0), 0);\r\n                    const part0Count = splatCountA - proxyTotal; // > 0 only in legacy scenario A\r\n                    const srcUBufs: (Uint8Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n                    const srcFBufs: (Float32Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n                    const partStarts: number[] = new Array(this._partProxies.length).fill(0);\r\n                    // Legacy scenario A: part 0 is the mesh's own loaded data.\r\n                    if (!this._partProxies[0] && this._splatsData && part0Count > 0) {\r\n                        srcUBufs[0] = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n                        srcFBufs[0] = GaussianSplattingMeshBase._GetSplatDataFloats(this._splatsData);\r\n                        partStarts[0] = 0;\r\n                    }\r\n                    // All proxied parts — start from pi=0 to cover preferred scenario B.\r\n                    let cumOffset = part0Count;\r\n                    for (let pi = 0; pi < this._partProxies.length; pi++) {\r\n                        const proxy = this._partProxies[pi];\r\n                        if (!proxy) {\r\n                            continue;\r\n                        }\r\n                        // Streaming parts are GPU-authoritative (no CPU source) — skip reconstruction (their rows are\r\n                        // restored via the atlas hooks). Row-aligned regions mean a streamed part's splats never fall\r\n                        // in the partial boundary row anyway; leave its source buffers null and just track the offset.\r\n                        if (this._streamingStates.some((s) => s.proxy === proxy)) {\r\n                            partStarts[pi] = cumOffset;\r\n                            cumOffset += proxy._vertexCount;\r\n                            continue;\r\n                        }\r\n                        const source = this._createRetainedPartSource(proxy);\r\n                        if (!source || !source._splatsData) {\r\n                            throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n                        }\r\n                        srcUBufs[pi] = GaussianSplattingMeshBase._GetSplatDataBytes(source._splatsData);\r\n                        srcFBufs[pi] = GaussianSplattingMeshBase._GetSplatDataFloats(source._splatsData);\r\n                        partStarts[pi] = cumOffset;\r\n                        cumOffset += source._vertexCount;\r\n                    }\r\n                    for (let splatIdx = firstNewTexel; splatIdx < splatCountA; splatIdx++) {\r\n                        const partIdx = this._partIndices ? this._partIndices[splatIdx] : 0;\r\n                        const uBuf = partIdx < srcUBufs.length ? srcUBufs[partIdx] : null;\r\n                        const fBuf = partIdx < srcFBufs.length ? srcFBufs[partIdx] : null;\r\n                        if (uBuf && fBuf) {\r\n                            this._makeSplat(splatIdx, fBuf, uBuf, covA, covB, colorArray, minimum, maximum, false, splatIdx - (partStarts[partIdx] ?? 0));\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Append each new source\r\n        dstOffset = splatCountA;\r\n        for (const other of others) {\r\n            this._appendPartSourceToArrays(other, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n            dstOffset += other._vertexCount;\r\n        }\r\n\r\n        // Pad empty splats to texture boundary\r\n        const paddedEnd = (totalCount + 15) & ~0xf;\r\n        for (let i = totalCount; i < paddedEnd; i++) {\r\n            this._makeEmptySplat(i, covA, covB, colorArray);\r\n        }\r\n\r\n        // --- Update vertex count / index buffer ---\r\n        if (totalCount !== this._vertexCount) {\r\n            this._updateSplatIndexBuffer(totalCount);\r\n        }\r\n        // Retain CPU SH only for the STATIC contribution — a stream-only SH atlas has no CPU SH to reconstruct on a\r\n        // later compaction (the stream re-decodes/backup-restores its own region), so don't retain neutral buffers.\r\n        this._retainMergedPartData(splatCountA, totalCount, others, staticHasSH ? shDegreeNew : 0);\r\n        this._vertexCount = totalCount;\r\n        this._shDegree = shDegreeNew;\r\n        // Keep the max in sync so the public `shDegree` setter's clamp tracks the current data (and shrinks when a\r\n        // higher-degree part is removed). The compound's SH degree is fully described by the live parts.\r\n        this._maxShDegree = shDegreeNew;\r\n\r\n        // Gate the sort worker for the duration of this operation. _updateTextures (below) may create the worker and fire an\r\n        // immediate sort via _postToWorker. At that point partMatrices has not yet been updated for the incoming parts, so the\r\n        // worker would compute depthCoeffs for fewer parts than partIndices references — crashing with\r\n        // \"Cannot read properties of undefined (reading '0')\".\r\n        // When called from removePart, _rebuilding is already true and _canPostToWorker is already false, so the gate is a\r\n        // no-op — removePart handles the final post+sort.\r\n        const needsWorkerGate = !this._rebuilding;\r\n        if (needsWorkerGate) {\r\n            this._canPostToWorker = false;\r\n            this._rebuilding = true;\r\n        }\r\n\r\n        try {\r\n            // --- Upload to GPU ---\r\n            if (incremental) {\r\n                // Create missing SH GPU textures: either the compound just gained SH for the first\r\n                // time (_shTextures===null) or the degree increased (sh.length > _shTextures.length).\r\n                // Use _shData when available (contains correct merged values for all rows);\r\n                // fall back to sh[idx] (pre-filled with 128) when _shData is absent (keepInRam=false).\r\n                // _updateSubTextures will re-upload from firstNewLine, which is redundant but harmless.\r\n                if (sh && (!this._shTextures || sh.length > this._shTextures.length)) {\r\n                    if (!this._shTextures) {\r\n                        this._shTextures = [];\r\n                    }\r\n                    while (this._shTextures.length < sh.length) {\r\n                        const idx = this._shTextures.length;\r\n                        const shTexture = new RawTexture(\r\n                            null,\r\n                            textureSize.x,\r\n                            textureSize.y,\r\n                            Constants.TEXTUREFORMAT_RGBA_INTEGER,\r\n                            this._scene,\r\n                            false,\r\n                            false,\r\n                            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                            Constants.TEXTURETYPE_UNSIGNED_INTEGER\r\n                        );\r\n                        shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                        shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n                        this._shTextures.push(shTexture);\r\n                        const src = this._shData && idx < this._shData.length ? this._shData[idx] : sh[idx];\r\n                        this._updateShTextureData(shTexture, src, textureSize.x, 0, textureSize.y);\r\n                    }\r\n                }\r\n\r\n                // Restore boundary-row SH: sh is freshly filled with 128, and _updateSubTextures\r\n                // starts at firstNewLine — existing splats on that row need their values from _shData.\r\n                if (sh && this._shData) {\r\n                    const firstNewTexel = firstNewLine * textureSize.x;\r\n                    if (firstNewTexel < splatCountA) {\r\n                        const byteStart = firstNewTexel * _GaussianSplattingBytesPerShTexel;\r\n                        const byteEnd = splatCountA * _GaussianSplattingBytesPerShTexel;\r\n                        for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n                            if (texIdx < this._shData.length) {\r\n                                sh[texIdx].set(this._shData[texIdx].subarray(byteStart, byteEnd), byteStart);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Update the part-indices texture (handles both create and update-in-place).\r\n                // _ensurePartIndicesTexture is a no-op when the texture already exists, so on the\r\n                // second+ addPart the partIndices would be stale without this call.\r\n                this._onUpdateTextures(textureSize);\r\n                this._updateSubTextures(this._splatPositions, covA, covB, colorArray, firstNewLine, textureSize.y - firstNewLine, sh);\r\n            } else {\r\n                this._updateTextures(covA, covB, colorArray, sh);\r\n            }\r\n\r\n            this.setEnabled(true);\r\n            this._notifyWorkerNewData();\r\n\r\n            // Bounding info is updated via _updateBoundingInfoFromProxies (called below, after proxy\r\n            // world matrices are known), which needs part 0's local-space AABB as an input:\r\n            //   • For unproxied part 0 (legacy layout A: compound loaded its own splat data before\r\n            //     any addPart call, so no _partProxies[0]), capture the local-space AABB from the\r\n            //     compound mesh's existing _boundingInfo — set when the mesh loaded its own data via\r\n            //     URL/updateData — so _updateBoundingInfoFromProxies can include part 0's geometry.\r\n            //   • For proxied part 0, skip — its bounds are already on the proxy's getBoundingInfo()\r\n            //     and _updateBoundingInfoFromProxies picks it up there.\r\n            // Guard splatCountA > 0 avoids reading a stale bounding box on a fresh empty mesh.\r\n            // Guard !this._part0LocalMin ensures we only store once; subsequent addPart calls must\r\n            // not overwrite it, because by then _boundingInfo reflects the full merged dataset.\r\n            if (!this._partProxies[0] && splatCountA > 0 && !this._part0LocalMin) {\r\n                this._part0LocalMin = this.getBoundingInfo().minimum.clone();\r\n                this._part0LocalMax = this.getBoundingInfo().maximum.clone();\r\n            }\r\n\r\n            // --- Create proxy meshes ---\r\n            const proxyMeshes: GaussianSplattingPartProxyMesh[] = [];\r\n            for (let i = 0; i < others.length; i++) {\r\n                const other = others[i];\r\n                const newPartIndex = assignedPartIndices[i];\r\n\r\n                const partWorldMatrix = other.getWorldMatrix();\r\n                this.setWorldMatrixForPart(newPartIndex, partWorldMatrix);\r\n\r\n                const proxyMesh = new GaussianSplattingPartProxyMesh(\r\n                    other.name,\r\n                    this.getScene(),\r\n                    this,\r\n                    newPartIndex,\r\n                    other.getBoundingInfo(),\r\n                    other._vertexCount,\r\n                    assignedSplatsDataOffsets[i],\r\n                    assignedSplatsDataOffsets[i]\r\n                );\r\n\r\n                if (disposeOthers) {\r\n                    other.dispose();\r\n                }\r\n\r\n                const quaternion = new Quaternion();\r\n                partWorldMatrix.decompose(proxyMesh.scaling, quaternion, proxyMesh.position);\r\n                proxyMesh.rotationQuaternion = quaternion;\r\n                proxyMesh.computeWorldMatrix(true);\r\n\r\n                this._partProxies[newPartIndex] = proxyMesh;\r\n                proxyMeshes.push(proxyMesh);\r\n            }\r\n\r\n            // Update compound bounds now that all proxy world matrices are known.\r\n            this._updateBoundingInfoFromProxies();\r\n\r\n            // Restore the rebuild gate and post the now-complete partMatrices in one message, then trigger a single sort pass.\r\n            // This ensures the worker sees a consistent partMatrices array that matches the partIndices for every splat.\r\n            if (needsWorkerGate) {\r\n                this._rebuilding = false;\r\n                if (this._worker) {\r\n                    this._worker.postMessage({\r\n                        command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n                        partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n                    });\r\n                }\r\n                this._canPostToWorker = true;\r\n                // A streaming compound renders the active-range UNION (a part carries an override), so a newly\r\n                // added static part must be folded into that union now — otherwise it stays out of the sorted\r\n                // set and isn't drawn until the stream's next LOD re-evaluation happens to refresh the union.\r\n                // (No-op for non-streaming compounds: with no override the union clears to the render-all path.)\r\n                if (this._hasStreamingPart) {\r\n                    this._refreshPartRangeUnion();\r\n                }\r\n                this._postToWorker(true);\r\n            }\r\n\r\n            this.onPartCountChangedObservable.notifyObservers(this.partCount);\r\n            return { proxyMeshes, assignedPartIndices };\r\n        } catch (e) {\r\n            // Ensure the gates are always restored so sorting is not permanently frozen.\r\n            if (needsWorkerGate) {\r\n                this._rebuilding = false;\r\n                this._canPostToWorker = true;\r\n            }\r\n            throw e;\r\n        }\r\n    }\r\n\r\n    // ---------------------------------------------------------------------------\r\n    // Public compound API\r\n    // ---------------------------------------------------------------------------\r\n\r\n    /**\r\n     * Add another mesh to this mesh, as a new part. This makes the current mesh a compound, if not already.\r\n     * The source mesh's splat data is read directly and copied into the compound's retained source buffers.\r\n     * @param other - The other mesh to add. Must be fully loaded before calling this method.\r\n     * @param disposeOther - Whether to dispose the other mesh after adding it to the current mesh.\r\n     * @returns a placeholder mesh that can be used to manipulate the part transform\r\n     * @deprecated Use {@link GaussianSplattingCompoundMesh.addPart} instead.\r\n     */\r\n    public addPart(other: GaussianSplattingMesh, disposeOther: boolean = true): GaussianSplattingPartProxyMesh {\r\n        // Adding parts while a streaming part exists is supported: the grow rebuild preserves streamed regions\r\n        // (their GPU data is backed up/restored around the atlas recreation). Only removal is still restricted,\r\n        // because it shifts existing part offsets (which streamed regions' work buffers depend on).\r\n        const { proxyMeshes } = this._addPartsInternal([other], disposeOther);\r\n        return proxyMeshes[0];\r\n    }\r\n\r\n    /**\r\n     * Recomputes the shared SH-atlas state ({@link _useShMrtAtlas}, {@link _shMrtAtlasTextureCount},\r\n     * {@link _streamingShDegree}) from the currently-live (non-tombstoned) streaming parts. Call before an atlas\r\n     * rebuild that follows a removal so a stale SH degree/count from a removed part can't keep the SH atlas active\r\n     * (and SH_DEGREE high) with nothing refilling the SH texels.\r\n     */\r\n    private _refreshStreamingShState(): void {\r\n        let count = 0;\r\n        let degree = 0;\r\n        let needsRot = false;\r\n        for (const state of this._streamingStates) {\r\n            if (this._tombstonedPartIndices.has(state.partIndex)) {\r\n                continue;\r\n            }\r\n            if (state.shTextureCount > count) {\r\n                count = state.shTextureCount;\r\n            }\r\n            if (state.shDegree > degree) {\r\n                degree = state.shDegree;\r\n            }\r\n            if (state.needsRotationScale) {\r\n                needsRot = true;\r\n            }\r\n        }\r\n        this._shMrtAtlasTextureCount = count;\r\n        this._useShMrtAtlas = count > 0;\r\n        this._streamingShDegree = degree;\r\n        // Render-backed rotation atlas is active iff a live streaming part decodes rotation/scale. (`_needsRotationScaleTextures`\r\n        // is left as-is — removing a stream doesn't disable IBL for surviving static parts, which keep CPU RawTextures.)\r\n        this._useRotMrtAtlas = needsRot;\r\n    }\r\n\r\n    /**\r\n     * Tombstones a part of a streaming compound: excludes it from the render union permanently and hides its\r\n     * proxy, leaving its atlas rows idle. Used instead of the compacting {@link removePart} rebuild whenever a\r\n     * streaming part is reserved — a streamed region has no retained CPU source and decodes at a FIXED base\r\n     * offset, so the rebuild can neither reconstruct it nor shift any part without desynchronizing the streaming\r\n     * engine. Every other part keeps its exact offset (no shift), so resident streams keep decoding at their base.\r\n     * The empty `[]` override survives future add-driven rebuilds, so the region stays invisible even though its\r\n     * texels get rebuilt; memory is only reclaimed by disposing/recreating the whole compound.\r\n     * @param index the part index to tombstone\r\n     */\r\n    private _tombstonePart(index: number): void {\r\n        // Fire before mutation so the stream driving this part (which subscribes to this observable at reservation)\r\n        // can dispose itself: stop its LOD loop, free its work buffer, and drop its atlas-rebuild hooks.\r\n        this.onPartRemovedObservable.notifyObservers(index);\r\n        const proxy = this._partProxies[index];\r\n        if (proxy) {\r\n            proxy.setEnabled(false);\r\n            proxy.visibility = 0;\r\n        }\r\n        this._partVisibility[index] = 0;\r\n        // Invalidate this region's streaming handle so a caller that retained it can't later mutate a surviving part\r\n        // that inherits this index/base after compaction.\r\n        const removedState = this._streamingStates.find((s) => s.partIndex === index);\r\n        if (removedState) {\r\n            removedState.removed = true;\r\n        }\r\n        // Empty (non-null) override = \"this part contributes no splats\"; keeps the union filter engaged so the\r\n        // idle region is never rendered, even after another part's addition rebuilds the atlas.\r\n        this._partSplatRanges[index] = [];\r\n        // Record the tombstone so compactAtlas() can drop this part's atlas rows and reclaim the memory.\r\n        this._tombstonedPartIndices.add(index);\r\n        this._refreshPartRangeUnion();\r\n        this._updateBoundingInfoFromProxies();\r\n    }\r\n\r\n    /**\r\n     * Tears the compound down to an empty state so a subsequent {@link _addPartsInternal} recreates fresh GPU\r\n     * textures. Shared by {@link removePart} (compacting rebuild) and {@link compactAtlas}. Does NOT dispose the\r\n     * part proxies — callers dispose only the proxies being removed and reuse the survivors' proxy objects.\r\n     * @internal\r\n     */\r\n    protected _resetForRebuild(): void {\r\n        // Terminate the sort worker before zeroing _vertexCount. The worker's onmessage handler compares\r\n        // depthMix.length against (_vertexCount + 15) & ~0xf; with _vertexCount = 0 that becomes 16, forcing a\r\n        // re-sort loop on stale data and resetting _canPostToWorker to true, defeating the rebuild gate. The\r\n        // worker is re-instantiated after the rebuild via the first _postToWorker call.\r\n        if (this._worker) {\r\n            this._worker.terminate();\r\n            this._worker = null;\r\n        }\r\n        // Dispose GPU textures and null them so _updateTextures sees firstTime=true and allocates fresh ones.\r\n        // For a streaming atlas the four data textures are attachments of _mrtAtlas — dispose the MRT, not each.\r\n        if (this._mrtAtlas) {\r\n            this._mrtAtlas.dispose();\r\n            this._mrtAtlas = null;\r\n            this._covariancesATexture = this._covariancesBTexture = this._centersTexture = this._colorsTexture = null;\r\n        } else {\r\n            this._covariancesATexture?.dispose();\r\n            this._covariancesBTexture?.dispose();\r\n            this._centersTexture?.dispose();\r\n            this._colorsTexture?.dispose();\r\n            this._covariancesATexture = null;\r\n            this._covariancesBTexture = null;\r\n            this._centersTexture = null;\r\n            this._colorsTexture = null;\r\n        }\r\n        if (this._rotMrtAtlas) {\r\n            // The three rotation textures are attachments of this MRT — dispose the MRT, not each attachment.\r\n            this._rotMrtAtlas.dispose();\r\n            this._rotMrtAtlas = null;\r\n        } else {\r\n            this._rotationsATexture?.dispose();\r\n            this._rotationsBTexture?.dispose();\r\n            this._rotationScaleTexture?.dispose();\r\n        }\r\n        this._rotationsATexture = null;\r\n        this._rotationsBTexture = null;\r\n        this._rotationScaleTexture = null;\r\n        if (this._shMrtAtlas) {\r\n            // SH attachments belong to these MRTs — dispose the MRTs, not each attachment (mirrors _mrtAtlas).\r\n            for (const mrt of this._shMrtAtlas) {\r\n                mrt.dispose();\r\n            }\r\n            this._shMrtAtlas = null;\r\n            this._shTextures = null;\r\n        } else if (this._shTextures) {\r\n            for (const t of this._shTextures) {\r\n                t.dispose();\r\n            }\r\n            this._shTextures = null;\r\n        }\r\n        if (this._partIndicesTexture) {\r\n            this._partIndicesTexture.dispose();\r\n            this._partIndicesTexture = null;\r\n        }\r\n        this._vertexCount = 0;\r\n        this._splatPositions = null;\r\n        this._partIndices = null;\r\n        this._partMatrices = [];\r\n        this._partVisibility = [];\r\n        this._cachedBoundingMin = null;\r\n        this._cachedBoundingMax = null;\r\n        this._part0LocalMin = null;\r\n        this._part0LocalMax = null;\r\n        this._splatsData = null;\r\n        this._shData = null;\r\n        this._shDegree = 0;\r\n        this._partProxies = [];\r\n        // Drop per-part range overrides too: a rebuild reassigns part indices from 0, so a leftover entry at a\r\n        // now-unused high index would otherwise be inherited by a later-added part (rendering it wrong/nothing).\r\n        // The rebuild re-sets the surviving parts' entries.\r\n        this._partSplatRanges = [];\r\n    }\r\n\r\n    /**\r\n     * Reclaims the atlas rows of parts removed (tombstoned) while a streaming part was resident. `removePart`\r\n     * on a streaming compound only tombstones — it excludes the part from the render union and hides its proxy,\r\n     * but leaves its rows allocated, since compacting them would relocate the still-resident streaming regions.\r\n     * This method performs that compaction: it rebuilds the shared atlas from the LIVE parts at new, contiguous\r\n     * (row-aligned for streaming) offsets, physically relocating each surviving streaming region's GPU texels,\r\n     * CPU sort positions, and decode/render base offset, and drops the tombstoned rows — shrinking the atlas.\r\n     *\r\n     * Call it after removing one or more models to actually free the GPU/CPU memory (e.g. on idle, or once a\r\n     * batch of removals settles). No-op when nothing is tombstoned. Safe while streams are actively decoding:\r\n     * each surviving region is backed up before the old atlas is disposed and restored at its new base after.\r\n     */\r\n    public compactAtlas(): void {\r\n        if (this._tombstonedPartIndices.size === 0) {\r\n            return;\r\n        }\r\n\r\n        const atlasWidth = this._getTextureSize(1).x;\r\n\r\n        // Build the compacted layout of the LIVE parts (skip tombstoned ones), in current part-index order.\r\n        // Static parts pack tightly from their retained CPU source; streaming regions are re-reserved as\r\n        // row-aligned empty sources (front-padded to the next row) and relocated via the atlas-rebuild hooks.\r\n        type LivePartSpec = {\r\n            oldProxy: GaussianSplattingPartProxyMesh;\r\n            source: IGaussianSplattingPartSource;\r\n            worldMatrix: Matrix;\r\n            visibility: number;\r\n            state: Nullable<IStreamingPartState>;\r\n            newBase: number; // streaming only: the region's usable base after compaction\r\n            frontPad: number; // streaming only\r\n        };\r\n        const specs: LivePartSpec[] = [];\r\n        let cumOffset = 0;\r\n        for (let i = 0; i < this._partProxies.length; i++) {\r\n            const proxy = this._partProxies[i];\r\n            if (!proxy || this._tombstonedPartIndices.has(i)) {\r\n                continue;\r\n            }\r\n            const state = this._streamingStates.find((s) => s.proxy === proxy) ?? null;\r\n            const worldMatrix = proxy.getWorldMatrix().clone();\r\n            const visibility = this._partVisibility[i] ?? 1.0;\r\n            if (state) {\r\n                // Streaming: reserve an empty, row-aligned region (front pad + capacity) at the compacted offset.\r\n                const alignedBase = Math.ceil(cumOffset / atlasWidth) * atlasWidth;\r\n                const frontPad = alignedBase - cumOffset;\r\n                const regionSplats = frontPad + state.capacity;\r\n                const source: IGaussianSplattingPartSource = {\r\n                    name: proxy.name,\r\n                    _vertexCount: regionSplats,\r\n                    _splatsData: null,\r\n                    _shData: null,\r\n                    _shDegree: 0,\r\n                    isCompound: false,\r\n                    getWorldMatrix: () => worldMatrix,\r\n                    getBoundingInfo: () => new BoundingInfo(Vector3.ZeroReadOnly, Vector3.ZeroReadOnly),\r\n                    dispose: () => {},\r\n                    _isReservedEmpty: true,\r\n                };\r\n                specs.push({ oldProxy: proxy, source, worldMatrix, visibility, state, newBase: alignedBase, frontPad });\r\n                cumOffset += regionSplats;\r\n            } else {\r\n                const source = this._createRetainedPartSource(proxy);\r\n                if (!source || !source._splatsData) {\r\n                    throw new Error(`compactAtlas: the retained source data for static part \"${proxy.name}\" is not available.`);\r\n                }\r\n                specs.push({ oldProxy: proxy, source, worldMatrix, visibility, state: null, newBase: 0, frontPad: 0 });\r\n                cumOffset += source._vertexCount;\r\n            }\r\n        }\r\n\r\n        // Back up every surviving streaming region's GPU texels + CPU positions before the atlas is torn down.\r\n        if (this._mrtAtlas) {\r\n            this._onBeforeAtlasRebuildObservable.notifyObservers(this._mrtAtlas);\r\n        }\r\n\r\n        // Dispose the tombstoned parts' proxies (their streams were already disposed when tombstoned).\r\n        for (const i of this._tombstonedPartIndices) {\r\n            this._partProxies[i]?.dispose();\r\n        }\r\n\r\n        // Tear the compound down to empty so _addPartsInternal recreates fresh (smaller) GPU textures.\r\n        this._resetForRebuild();\r\n\r\n        if (specs.length === 0) {\r\n            // Everything was tombstoned — nothing to rebuild. Clear the streaming/atlas capability flags so that\r\n            // reusing this now-empty compound for plain (non-streaming) content doesn't recreate render-target\r\n            // atlases or restore a stale SH/rotation configuration. _refreshStreamingShState turns off SH/rotation\r\n            // from the (empty) live states; the render-backed core atlas + RGBA covariants reset here.\r\n            this._streamingStates.length = 0;\r\n            this._hasStreamingPart = false;\r\n            this._tombstonedPartIndices.clear();\r\n            this._refreshStreamingShState();\r\n            this._useMrtAtlas = false;\r\n            // Restore the engine-derived default rather than a hardcoded `false`: WebGL 1 (no WebGPU) cannot render\r\n            // the RG half-float covariance-B path and requires RGBA, so a reused compound must keep that default.\r\n            this._useRGBACovariants = !this.getEngine().isWebGPU && this.getEngine().version === 1.0;\r\n            this.setEnabled(false);\r\n            this.onPartCountChangedObservable.notifyObservers(0);\r\n            return;\r\n        }\r\n\r\n        // Recompute the SH-atlas state from the SURVIVING streaming parts BEFORE the rebuild: if the removed part\r\n        // was the only SH stream, this turns the SH atlas off (degree 0) so the rebuild neither recreates a stale\r\n        // SH atlas nor keeps SH_DEGREE high over now-unfilled (raw-0) texels; a lower surviving degree shrinks too.\r\n        this._refreshStreamingShState();\r\n\r\n        this._rebuilding = true;\r\n        this._canPostToWorker = false;\r\n        try {\r\n            const { proxyMeshes: newProxies } = this._addPartsInternal(\r\n                specs.map((s) => s.source),\r\n                false\r\n            );\r\n\r\n            // Re-map the surviving proxies onto their new indices/offsets and relocate streaming state.\r\n            for (let i = 0; i < specs.length; i++) {\r\n                const spec = specs[i];\r\n                const newProxy = newProxies[i];\r\n                const newPartIndex = newProxy.partIndex;\r\n\r\n                this.setWorldMatrixForPart(newPartIndex, spec.worldMatrix);\r\n                this.setPartVisibility(newPartIndex, spec.visibility);\r\n                const quaternion = new Quaternion();\r\n                spec.worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n                newProxy.rotationQuaternion = quaternion;\r\n                newProxy.computeWorldMatrix(true);\r\n\r\n                spec.oldProxy.updatePartIndex(newPartIndex);\r\n                spec.oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n                this._partProxies[newPartIndex] = spec.oldProxy;\r\n                newProxy.dispose();\r\n\r\n                if (spec.state) {\r\n                    // Relocate: the usable base is the (aligned) source start + front pad. Update BEFORE the\r\n                    // onAfter hook fires so the stream reads the new base from the handle.\r\n                    spec.state.partIndex = newPartIndex;\r\n                    spec.state.base = newProxy._splatsDataOffset + spec.frontPad;\r\n                    // Re-post the region's active ranges at the new base so the union stays correct with no flicker.\r\n                    this._partSplatRanges[newPartIndex] = spec.state.localRanges\r\n                        ? spec.state.localRanges.map((r) => ({ offset: spec.state!.base + r.offset, count: r.count }))\r\n                        : null;\r\n                } else {\r\n                    this._partSplatRanges[newPartIndex] = null; // static parts render fully\r\n                }\r\n            }\r\n\r\n            // Rebind + restore every surviving streaming region into the new (smaller) atlas at its new base.\r\n            if (this._mrtAtlas) {\r\n                this._onAfterAtlasRebuildObservable.notifyObservers(this._mrtAtlas);\r\n            }\r\n\r\n            // Drop the states of tombstoned streaming parts; keep only surviving ones.\r\n            this._streamingStates = specs.filter((s) => s.state).map((s) => s.state!);\r\n            this._hasStreamingPart = this._streamingStates.length > 0;\r\n            this._tombstonedPartIndices.clear();\r\n\r\n            // Recompute bounds from the restored proxies (_addPartsInternal above used the zero-box placeholders),\r\n            // else a static-transform compound keeps stale bounds and isInFrustum can cull it. Must run after the\r\n            // tombstone set is cleared so a survivor reusing a tombstoned index isn't skipped by the filter.\r\n            this._updateBoundingInfoFromProxies();\r\n\r\n            this._rebuilding = false;\r\n            this._canPostToWorker = true;\r\n            // The streaming regions' CPU positions were restored into _splatPositions by the onAfter hook (after\r\n            // _addPartsInternal had already posted the rebuild's zeros), so re-post the full merged set: positions\r\n            // + part indices via _notifyWorkerNewData, then the per-part matrices (suppressed during _rebuilding),\r\n            // refresh the union, and fire one sort — so the worker's positions/partIndices/partMatrices all agree.\r\n            this._refreshPartRangeUnion();\r\n            this._notifyWorkerNewData();\r\n            const workerAfterRebuild = this._worker as Worker | null;\r\n            workerAfterRebuild?.postMessage({\r\n                command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n                partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n            });\r\n            this._postToWorker(true);\r\n            this.onPartCountChangedObservable.notifyObservers(this.partCount);\r\n        } catch (e) {\r\n            this._rebuilding = false;\r\n            this._canPostToWorker = true;\r\n            throw e;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a part from this compound mesh.\r\n     * The remaining parts are rebuilt directly from the compound mesh's retained source buffers.\r\n     * The current mesh is reset to a plain (single-part) state and then each remaining source is\r\n     * re-added via addParts.\r\n     * When a streaming part is reserved the part is tombstoned instead of compacted (see {@link _tombstonePart}).\r\n     * @param index - The index of the part to remove\r\n     * @deprecated Use {@link GaussianSplattingCompoundMesh.removePart} instead.\r\n     */\r\n    public removePart(index: number): void {\r\n        if (index < 0 || index >= this.partCount) {\r\n            throw new Error(`Part index ${index} is out of range [0, ${this.partCount})`);\r\n        }\r\n\r\n        // Streaming compounds can't compact (a reserved region has no CPU source and a fixed base offset).\r\n        if (this._hasStreamingPart) {\r\n            this._tombstonePart(index);\r\n            return;\r\n        }\r\n\r\n        // Collect surviving proxy objects (sorted by current part index so part 0 is added first)\r\n        const survivors: Array<{ proxyMesh: GaussianSplattingPartProxyMesh; source: IGaussianSplattingPartSource; oldIndex: number; worldMatrix: Matrix; visibility: number }> = [];\r\n        for (let proxyIndex = 0; proxyIndex < this._partProxies.length; proxyIndex++) {\r\n            const proxy = this._partProxies[proxyIndex];\r\n            if (!proxy || proxyIndex === index) {\r\n                continue;\r\n            }\r\n            const source = this._createRetainedPartSource(proxy);\r\n            if (!source) {\r\n                throw new Error(`Cannot remove part: the retained compound source data is not available for part \"${proxy.name}\".`);\r\n            }\r\n            survivors.push({ proxyMesh: proxy, source, oldIndex: proxyIndex, worldMatrix: proxy.getWorldMatrix().clone(), visibility: this._partVisibility[proxyIndex] ?? 1.0 });\r\n        }\r\n        survivors.sort((a, b) => a.oldIndex - b.oldIndex);\r\n\r\n        // Validate every survivor still has its source data. If even one is missing we cannot rebuild.\r\n        for (const { proxyMesh, source } of survivors) {\r\n            if (!source._splatsData) {\r\n                throw new Error(`Cannot remove part: the source data for part \"${proxyMesh.name}\" is not available.`);\r\n            }\r\n            if (source._shDegree > 0 && !source._shData) {\r\n                throw new Error(`Cannot remove part: the SH data for part \"${proxyMesh.name}\" is not available.`);\r\n            }\r\n        }\r\n\r\n        // Notify listeners before mutation so they can record state keyed on the original index.\r\n        this.onPartRemovedObservable.notifyObservers(index);\r\n\r\n        // Dispose the removed part's proxy, then reset to an empty state (survivors' proxy objects are held in\r\n        // `survivors` and reused after the rebuild).\r\n        this._partProxies[index]?.dispose();\r\n        this._resetForRebuild();\r\n\r\n        // Rebuild from surviving sources. _addPartsInternal assigns part indices in order 0, 1, 2, …\r\n        // so the new index for each survivor is simply its position in the survivors array.\r\n        if (survivors.length === 0) {\r\n            // Nothing left — leave the mesh empty.\r\n            this.setEnabled(false);\r\n            this.onPartCountChangedObservable.notifyObservers(0);\r\n            return;\r\n        }\r\n\r\n        // Gate the sort worker: suppress any sort request until the full rebuild is committed.\r\n        this._rebuilding = true;\r\n        this._canPostToWorker = false;\r\n        try {\r\n            const sources = survivors.map((s) => s.source);\r\n            const { proxyMeshes: newProxies } = this._addPartsInternal(sources, false);\r\n\r\n            // Restore world matrices and re-map proxies\r\n            for (let i = 0; i < survivors.length; i++) {\r\n                const oldProxy = survivors[i].proxyMesh;\r\n                const newProxy = newProxies[i];\r\n                const newPartIndex = newProxy.partIndex;\r\n\r\n                // Restore the world matrix and visibility the user had set on the old proxy\r\n                this.setWorldMatrixForPart(newPartIndex, survivors[i].worldMatrix);\r\n                this.setPartVisibility(newPartIndex, survivors[i].visibility);\r\n                const quaternion = new Quaternion();\r\n                survivors[i].worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n                newProxy.rotationQuaternion = quaternion;\r\n                newProxy.computeWorldMatrix(true);\r\n\r\n                // Update the old proxy's index and metadata so existing user references still work.\r\n                oldProxy.updatePartIndex(newPartIndex);\r\n                oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n                this._partProxies[newPartIndex] = oldProxy;\r\n\r\n                // newProxy is redundant — it was created inside _addPartsInternal; dispose it\r\n                newProxy.dispose();\r\n            }\r\n\r\n            // Rebuild is complete: all partMatrices are now set correctly.\r\n            // Post the final complete set and fire one sort.\r\n            this._rebuilding = false;\r\n            // Break TypeScript's flow narrowing — _addPartsInternal may have reinstantiated _worker.\r\n            const workerAfterRebuild = this._worker as Worker | null;\r\n            workerAfterRebuild?.postMessage({\r\n                command: GaussianSplattingSortWorkerCommand.PART_MATRICES,\r\n                partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)),\r\n            });\r\n            this._canPostToWorker = true;\r\n            this._postToWorker(true);\r\n        } catch (e) {\r\n            // Ensure the gates are always restored so sorting is not permanently frozen.\r\n            this._rebuilding = false;\r\n            this._canPostToWorker = true;\r\n            throw e;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reserves a contiguous region of `capacity` splats in the compound as a new part for dynamic (streamed)\r\n     * content. Unlike {@link addPart}, no source data is copied: the region is created as invisible padding\r\n     * (zeroed) for a streaming engine to populate over time via the returned handle. The reserved part\r\n     * participates in the compound's single shared depth sort and draw exactly like a static part — it has a\r\n     * `partIndex`, a per-part world matrix (via its proxy), and a per-part visibility — so streamed splats are\r\n     * sorted and rendered together in one pass with the static parts.\r\n     *\r\n     * Add the streaming part LAST (after all static parts). The returned handle drives which of the region's\r\n     * splats render (LOD) and writes their data.\r\n     * @param capacity number of splats to reserve\r\n     * @param worldMatrix initial world matrix for the region's proxy (e.g. carrying a source's up-axis\r\n     *   convention); defaults to identity\r\n     * @param name name for the region's proxy mesh\r\n     * @param shTextureCount number of packed-u32 higher-order SH textures to allocate as a shared render-target SH\r\n     *   atlas the streaming engine bakes into (`ceil(coeffs*3/16)` for the stream's max SH degree); 0 = no SH\r\n     * @param shDegree SH degree of the streamed content (drives the compound's `SH_DEGREE`); ignored when\r\n     *   `shTextureCount` is 0. The compound keeps the MAX SH degree across its parts.\r\n     * @param needsRotationScale when true, converts the compound's rotation/scale textures to a shared render-target\r\n     *   half-float atlas the streaming engine decodes into, so the streamed splats participate in voxel-IBL shadows.\r\n     * @returns a handle used to populate and control the reserved region\r\n     */\r\n    public reserveStreamingPart(\r\n        capacity: number,\r\n        worldMatrix: Matrix = Matrix.Identity(),\r\n        name: string = this.name + \"_streamingPart\",\r\n        shTextureCount: number = 0,\r\n        shDegree: number = 0,\r\n        needsRotationScale: boolean = false\r\n    ): IGaussianSplattingStreamingPart {\r\n        // Require a positive integer (reject e.g. 0.5, which would floor to a 0-capacity region), and cap at the\r\n        // largest atlas the backend can allocate (a square texture at the max width) so an absurd value can't drive\r\n        // an out-of-memory typed-array / MRT allocation.\r\n        if (!Number.isSafeInteger(capacity) || capacity < 1) {\r\n            throw new Error(\"reserveStreamingPart: capacity must be a positive integer\");\r\n        }\r\n\r\n        // Validate the SH sizing parameters — they drive the SH_DEGREE define and the SH texture allocation, so a\r\n        // fractional/negative/huge value would give an invalid layout or an unbounded allocation. The draw path\r\n        // supports degree 0..4 (shTexture0..4); SH is all-or-nothing; the texture count must match the degree.\r\n        const maxSupportedShDegree = 4;\r\n        if (!Number.isSafeInteger(shDegree) || shDegree < 0 || shDegree > maxSupportedShDegree) {\r\n            throw new Error(`reserveStreamingPart: shDegree must be an integer in [0, ${maxSupportedShDegree}]`);\r\n        }\r\n        if (!Number.isSafeInteger(shTextureCount) || shTextureCount < 0) {\r\n            throw new Error(\"reserveStreamingPart: shTextureCount must be a non-negative integer\");\r\n        }\r\n        if (shDegree > 0 !== shTextureCount > 0) {\r\n            throw new Error(\"reserveStreamingPart: shDegree and shTextureCount must both be positive (SH) or both zero (no SH)\");\r\n        }\r\n        if (shDegree > 0) {\r\n            const expectedShTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n            if (shTextureCount !== expectedShTextureCount) {\r\n                throw new Error(`reserveStreamingPart: shTextureCount ${shTextureCount} does not match shDegree ${shDegree} (expected ${expectedShTextureCount})`);\r\n            }\r\n        }\r\n\r\n        const maxTextureSize = this._scene.getEngine().getCaps().maxTextureSize;\r\n        const maxCapacity = maxTextureSize * maxTextureSize;\r\n\r\n        // Row-align the region so a later GPU relayout (defrag under a memory budget) can be scoped to whole\r\n        // atlas rows via scissor without ever touching a preceding part that shares a row.\r\n        //   - Front alignment: start the usable region on the next row boundary. This only consumes the\r\n        //     preceding parts' already-allocated last-row tail padding, so it costs no extra memory.\r\n        //   - Capacity alignment: pad the region up to a whole number of rows so its end is a row boundary too\r\n        //     (needed when another part follows, e.g. multiple streaming parts).\r\n        const atlasWidth = this._getTextureSize(1).x;\r\n        const startOffset = this._vertexCount; // first atlas index the reserved part occupies\r\n        const alignedBase = Math.ceil(startOffset / atlasWidth) * atlasWidth;\r\n        const frontPad = alignedBase - startOffset; // invisible padding that fills the preceding row\r\n        const alignedCapacity = Math.ceil(capacity / atlasWidth) * atlasWidth;\r\n        const regionSplats = frontPad + alignedCapacity;\r\n\r\n        // Validate the RESULTING atlas, not just `capacity`: existing splats, row-alignment padding, and the trailing\r\n        // empty sentinel slot (`+ 1`, see _getTextureSize) all count against the device's square-texture limit.\r\n        // _getTextureSize would silently clamp and drop the sentinel past the limit, so reject here — before any\r\n        // state is mutated below, so a rejected reservation leaves the compound intact.\r\n        const projectedSplats = startOffset + regionSplats;\r\n        if (projectedSplats + 1 > maxCapacity) {\r\n            throw new Error(\r\n                `reserveStreamingPart: capacity ${capacity} would grow the atlas to ${projectedSplats} splats (plus a sentinel), exceeding the maximum atlas capacity ${maxCapacity}`\r\n            );\r\n        }\r\n\r\n        // Back the atlas with a render-targetable MRT so a streaming engine can GPU-decode into the reserved\r\n        // region. Must be set before _addPartsInternal so the (forced) full rebuild builds MRT attachments and\r\n        // allocates covariance B as RGBA. Harmless/no-op if a streaming part was already reserved.\r\n        this._useMrtAtlas = true;\r\n        this._useRGBACovariants = true;\r\n\r\n        // Higher-order SH: convert the SH textures to render-targetable integer MRTs so the stream can bake SH into\r\n        // its region, and set the compound's SH degree so the draw path lights the decoded splats. Sized for the\r\n        // MAX SH texture count across parts (a later higher-degree part grows it; lower-degree parts neutral-fill).\r\n        if (shTextureCount > 0 && shDegree > 0) {\r\n            this._useShMrtAtlas = true;\r\n            this._shMrtAtlasTextureCount = Math.max(this._shMrtAtlasTextureCount, shTextureCount);\r\n            // Streaming SH degree is tracked separately from _maxShDegree (which folds in static parts too) and is\r\n            // recomputed from the surviving states on removal — so it shrinks correctly. The _addPartsInternal\r\n            // rebuild below folds it into _shDegree/_maxShDegree.\r\n            this._streamingShDegree = Math.max(this._streamingShDegree, shDegree);\r\n        }\r\n\r\n        // Rotation/scale: convert the rotation textures to a render-targetable half-float atlas so the stream can\r\n        // decode rotation/scale into its region for voxel-IBL shadows. `_needsRotationScaleTextures` makes _makeSplat\r\n        // fill static parts' rotation data (CPU-uploaded into the shared atlas by the rebuild) too.\r\n        if (needsRotationScale) {\r\n            this._useRotMrtAtlas = true;\r\n            this._needsRotationScaleTextures = true;\r\n        }\r\n\r\n        // Running local-space bounds of the region's written centers; grown as splats are populated.\r\n        const boundsMin = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n        const boundsMax = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n        // Synthetic placeholder source: no data, so _addPartsInternal leaves the region zeroed (invisible)\r\n        // while still assigning a part index, filling _partIndices, growing the atlas + _splatPositions,\r\n        // creating the proxy, and posting the (larger) position/interval set to the sort worker.\r\n        const reservedSource: IGaussianSplattingPartSource = {\r\n            name,\r\n            _vertexCount: regionSplats,\r\n            _splatsData: null,\r\n            _shData: null,\r\n            _shDegree: 0,\r\n            isCompound: false,\r\n            getWorldMatrix: () => worldMatrix,\r\n            getBoundingInfo: () => new BoundingInfo(Vector3.ZeroReadOnly, Vector3.ZeroReadOnly),\r\n            dispose: () => {},\r\n            _isReservedEmpty: true,\r\n        };\r\n\r\n        const { proxyMeshes, assignedPartIndices } = this._addPartsInternal([reservedSource], false);\r\n        const proxy = proxyMeshes[0];\r\n        // Usable region starts at the row-aligned base (past the front padding) and spans the aligned capacity.\r\n        // (proxy._splatsDataOffset === startOffset; the usable base is startOffset + frontPad === alignedBase.)\r\n        // `base`/`partIndex` live in mutable state so compactAtlas can RELOCATE this region (new base/index) in\r\n        // place; the handle's getters and closures read the state, so the streaming engine's handle stays valid.\r\n        const state: IStreamingPartState = {\r\n            proxy,\r\n            base: alignedBase,\r\n            partIndex: assignedPartIndices[0],\r\n            capacity: alignedCapacity,\r\n            boundsMin,\r\n            boundsMax,\r\n            localRanges: null,\r\n            shTextureCount: shTextureCount > 0 && shDegree > 0 ? shTextureCount : 0,\r\n            shDegree: shTextureCount > 0 && shDegree > 0 ? shDegree : 0,\r\n            needsRotationScale,\r\n            removed: false,\r\n        };\r\n        this._streamingStates.push(state);\r\n        capacity = alignedCapacity;\r\n\r\n        // The handle's live getters need a stable reference to this compound (its atlas textures can be\r\n        // recreated on a later rebuild), so alias it for the closures below.\r\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n        const compound = this;\r\n        const applyBounds = () => {\r\n            if (boundsMin.x <= boundsMax.x) {\r\n                proxy.setBoundingInfo(new BoundingInfo(boundsMin.clone(), boundsMax.clone()));\r\n                compound._updateBoundingInfoFromProxies();\r\n            }\r\n        };\r\n        // Rejects any mutating call after the part was removed, so a retained stale handle can't touch a surviving\r\n        // part that inherited this region's (now-reused) part index/base.\r\n        const assertLive = (method: string) => {\r\n            if (state.removed) {\r\n                throw new Error(`${method}: this streaming part has been removed`);\r\n            }\r\n        };\r\n        // Enforces the documented local part boundary [0, capacity) so a handle call can never address another\r\n        // part's atlas region (the region base is added to these local coordinates before use).\r\n        const assertLocalRange = (method: string, offset: number, count: number) => {\r\n            if (!Number.isInteger(offset) || !Number.isInteger(count) || offset < 0 || count < 0 || offset + count > state.capacity) {\r\n                throw new Error(`${method}: local range [${offset}, ${offset + count}) is outside the reserved region [0, ${state.capacity})`);\r\n            }\r\n        };\r\n\r\n        const handle: IGaussianSplattingStreamingPart = {\r\n            proxy,\r\n            capacity,\r\n            get partIndex() {\r\n                return state.partIndex;\r\n            },\r\n            get base() {\r\n                return state.base;\r\n            },\r\n            get centersTexture() {\r\n                return compound.centersTexture;\r\n            },\r\n            get covariancesATexture() {\r\n                return compound.covariancesATexture;\r\n            },\r\n            get covariancesBTexture() {\r\n                return compound.covariancesBTexture;\r\n            },\r\n            get colorsTexture() {\r\n                return compound.colorsTexture;\r\n            },\r\n            get splatPositions() {\r\n                return compound._splatPositions;\r\n            },\r\n            get mrtAtlas() {\r\n                return compound._mrtAtlas;\r\n            },\r\n            get shMrtAtlas() {\r\n                return compound._shMrtAtlas;\r\n            },\r\n            get rotMrtAtlas() {\r\n                return compound._rotMrtAtlas;\r\n            },\r\n            get atlasWidth() {\r\n                return compound._getTextureSize(compound._vertexCount).x;\r\n            },\r\n            get isDepthSortSettled() {\r\n                return compound._isDepthSortSettled;\r\n            },\r\n            setActiveRanges: (localRanges) => {\r\n                assertLive(\"setActiveRanges\");\r\n                // Keep every range inside this part's region so it can never activate another part's splats.\r\n                if (localRanges) {\r\n                    for (const r of localRanges) {\r\n                        assertLocalRange(\"setActiveRanges\", r.offset, r.count);\r\n                    }\r\n                }\r\n                // Remember the LOCAL ranges so compactAtlas can re-post them at the region's new base.\r\n                state.localRanges = localRanges ? localRanges.map((r) => ({ offset: r.offset, count: r.count })) : null;\r\n                const globalRanges = localRanges ? localRanges.map((r) => ({ offset: state.base + r.offset, count: r.count })) : null;\r\n                compound.setPartSplatRanges(state.partIndex, globalRanges);\r\n            },\r\n            writeSplats: (localOffset, count, splatsData) => {\r\n                assertLive(\"writeSplats\");\r\n                // Keep the write inside this part's region so it can never touch another part's atlas texels.\r\n                assertLocalRange(\"writeSplats\", localOffset, count);\r\n                compound._writeStreamingSplats(state.base + localOffset, count, splatsData, boundsMin, boundsMax);\r\n                applyBounds();\r\n            },\r\n            postPositionsRange: (localOffset, count) => {\r\n                assertLive(\"postPositionsRange\");\r\n                assertLocalRange(\"postPositionsRange\", localOffset, count);\r\n                compound._postWorkerPositionsRange(state.base + localOffset, count);\r\n            },\r\n            expandBounds: (min, max) => {\r\n                assertLive(\"expandBounds\");\r\n                boundsMin.minimizeInPlace(min);\r\n                boundsMax.maximizeInPlace(max);\r\n                applyBounds();\r\n            },\r\n            notifyDataChanged: () => {\r\n                assertLive(\"notifyDataChanged\");\r\n                compound._notifyWorkerNewData();\r\n            },\r\n            onBeforeAtlasRebuild: (callback) => {\r\n                const observer = compound._onBeforeAtlasRebuildObservable.add(callback);\r\n                return () => compound._onBeforeAtlasRebuildObservable.remove(observer);\r\n            },\r\n            onAfterAtlasRebuild: (callback) => {\r\n                const observer = compound._onAfterAtlasRebuildObservable.add(callback);\r\n                return () => compound._onAfterAtlasRebuildObservable.remove(observer);\r\n            },\r\n        };\r\n        // Mark AFTER the successful internal _addPartsInternal so its own call isn't blocked by the guard.\r\n        this._hasStreamingPart = true;\r\n        return handle;\r\n    }\r\n\r\n    /**\r\n     * Serialize current GaussianSplattingMesh\r\n     * @param serializationObject defines the object which will receive the serialization data\r\n     * @param encoding the encoding of binary data, defaults to base64 for json serialize,\r\n     * kept for future internal use like cloning where base64 encoding wastes cycles and memory\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(serializationObject: any = {}, encoding: string = \"base64\"): any {\r\n        serializationObject = super.serialize(serializationObject);\r\n        serializationObject.subMeshes = [];\r\n        serializationObject.geometryUniqueId = undefined;\r\n        serializationObject.geometryId = undefined;\r\n        serializationObject.materialUniqueId = undefined;\r\n        serializationObject.materialId = undefined;\r\n        serializationObject.instances = [];\r\n        serializationObject.actions = undefined;\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.keepInRam = this._keepInRam;\r\n        serializationObject.disableDepthSort = this._disableDepthSort;\r\n        serializationObject.viewUpdateThreshold = this.viewUpdateThreshold;\r\n        serializationObject._flipY = this._flipY;\r\n\r\n        if (this._splatsData) {\r\n            serializationObject.splatsData = encoding === \"base64\" ? EncodeArrayBufferToBase64(this._splatsData) : this._splatsData;\r\n        }\r\n        if (this._shData) {\r\n            serializationObject.shData = encoding === \"base64\" ? this._shData.map(EncodeArrayBufferToBase64) : this._shData;\r\n            serializationObject.shDegree = this._shDegree;\r\n        }\r\n        if (this._partIndices) {\r\n            const compressedIndices = CompressPartIndices(this._partIndices.subarray(0, this._vertexCount));\r\n            serializationObject.partIndices = encoding === \"base64\" ? EncodeArrayBufferToBase64(compressedIndices) : compressedIndices;\r\n        }\r\n        if (this._partProxies.length) {\r\n            serializationObject.partProxies = this._partProxies.filter((proxy) => !!proxy).map((proxy) => proxy.serialize());\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Internal helper to parses a serialized GaussianSplattingMesh or GaussianSplattingCompoundMesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the GaussianSplattingMesh or GaussianSplattingCompoundMesh in\r\n     * @param ctor the constructor of the mesh to create\r\n     * @returns the created GaussianSplattingMesh\r\n     * @internal\r\n     */\r\n    public static _ParseInternal<T extends GaussianSplattingMesh>(\r\n        parsedMesh: any,\r\n        scene: Scene,\r\n        ctor: new (name: string, url: Nullable<string>, scene: Nullable<Scene>, keepInRam: boolean) => T\r\n    ): T {\r\n        const mesh = new ctor(parsedMesh.name, null, scene, parsedMesh.keepInRam);\r\n\r\n        mesh.disableDepthSort = parsedMesh.disableDepthSort ?? false;\r\n        mesh.viewUpdateThreshold = parsedMesh.viewUpdateThreshold ?? GaussianSplattingMeshBase._DefaultViewUpdateThreshold;\r\n\r\n        let splatsData: ArrayBuffer | string | undefined = parsedMesh.splatsData;\r\n        if (typeof splatsData === \"string\") {\r\n            splatsData = DecodeBase64ToBinary(splatsData);\r\n        }\r\n\r\n        const shData: string[] | Uint8Array[] | undefined = parsedMesh.shData;\r\n        let parsedShData: Uint8Array[] | undefined;\r\n        if (Array.isArray(shData) && shData.length) {\r\n            const newData: Uint8Array[] = [];\r\n            for (let i = 0, length = shData.length; i < length; i++) {\r\n                const data = shData[i];\r\n                if (typeof data === \"string\") {\r\n                    newData[i] = new Uint8Array(DecodeBase64ToBinary(data));\r\n                } else {\r\n                    newData[i] = data;\r\n                }\r\n            }\r\n            parsedShData = newData;\r\n        }\r\n\r\n        let partIndices: string | Uint32Array | number[] | undefined = parsedMesh.partIndices;\r\n        let parsedPartIndices: Uint8Array | undefined;\r\n        if (typeof partIndices === \"string\") {\r\n            partIndices = new Uint32Array(DecodeBase64ToBinary(partIndices));\r\n        }\r\n        if (partIndices) {\r\n            parsedPartIndices = ParsePartIndices(partIndices);\r\n        }\r\n\r\n        if (splatsData) {\r\n            const flipY = parsedMesh._flipY ?? false;\r\n            mesh.updateData(splatsData, parsedShData, { flipY }, parsedPartIndices, parsedMesh.shDegree);\r\n        }\r\n\r\n        if (parsedMesh.partProxies) {\r\n            for (const serializedPart of parsedMesh.partProxies) {\r\n                const part = Object.assign({}, serializedPart);\r\n                part.compoundSplatMesh = mesh;\r\n                const proxyMesh = Mesh.Parse(part, scene, \"\") as GaussianSplattingPartProxyMesh;\r\n                const newPartIndex = proxyMesh.partIndex;\r\n                mesh._partProxies[newPartIndex] = proxyMesh;\r\n                mesh.setWorldMatrixForPart(newPartIndex, proxyMesh.getWorldMatrix());\r\n                mesh.setPartVisibility(newPartIndex, proxyMesh.isEnabled() ? proxyMesh.visibility : 0);\r\n            }\r\n        }\r\n\r\n        return mesh;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized GaussianSplattingMesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the GaussianSplattingMesh in\r\n     * @returns the created GaussianSplattingMesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingMesh {\r\n        return GaussianSplattingMesh._ParseInternal(parsedMesh, scene, GaussianSplattingMesh);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { GaussianSplattingMesh } from \"./gaussianSplattingMesh.pure\";\r\nimport { type GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh.pure\";\r\nimport { Mesh } from \"../mesh.pure\";\r\n\r\n/**\r\n * Class used to compose multiple Gaussian Splatting meshes into a single draw call,\r\n * with per-part world-matrix and visibility control via addPart/addParts/removePart.\r\n *\r\n * This is the recommended class for multi-part Gaussian Splatting use cases.\r\n *\r\n * Next major version: the compound mesh API (addPart/addParts/removePart) will\r\n * move exclusively to this class and will be removed from GaussianSplattingMesh.\r\n */\r\nexport class GaussianSplattingCompoundMesh extends GaussianSplattingMesh {\r\n    /**\r\n     * Creates a new GaussianSplattingCompoundMesh\r\n     * @param name the name of the mesh\r\n     * @param url optional URL to load a Gaussian Splatting file from\r\n     * @param scene the hosting scene\r\n     * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU\r\n     * @param needsRotationScaleTextures generate rotation and scale matrix textures required for voxel-based IBL shadows\r\n     */\r\n    constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false, needsRotationScaleTextures: boolean = false) {\r\n        super(name, url, scene, keepInRam, needsRotationScaleTextures);\r\n    }\r\n\r\n    /**\r\n     * Add another mesh to this compound mesh as a new part.\r\n     * The source mesh's splat data is read directly and copied into the compound's retained source buffers.\r\n     * @param other - The other mesh to add. Must be fully loaded before calling this method.\r\n     * @param disposeOther - Whether to dispose the other mesh after adding it.\r\n     * @returns a placeholder mesh that can be used to manipulate the part transform\r\n     */\r\n    public override addPart(other: GaussianSplattingMesh, disposeOther: boolean = true): GaussianSplattingPartProxyMesh {\r\n        return super.addPart(other, disposeOther);\r\n    }\r\n\r\n    /**\r\n     * Add multiple meshes to this compound mesh as new parts in a single operation.\r\n     * Splat data is written into texture arrays while the compound refreshes its retained merged source buffers.\r\n     * @param others - The meshes to add. Each must be fully loaded and must not be a compound.\r\n     * @param disposeOthers - Whether to dispose the other meshes after adding them.\r\n     * @returns an array of placeholder meshes that can be used to manipulate the part transforms\r\n     */\r\n    public addParts(others: GaussianSplattingMesh[], disposeOthers: boolean = true): GaussianSplattingPartProxyMesh[] {\r\n        if (others.length === 0) {\r\n            return [];\r\n        }\r\n        const { proxyMeshes } = this._addPartsInternal(others, disposeOthers);\r\n        return proxyMeshes;\r\n    }\r\n\r\n    /**\r\n     * Remove a part from this compound mesh.\r\n     * The remaining parts are rebuilt directly from the compound mesh's retained source buffers.\r\n     * @param index - The index of the part to remove\r\n     */\r\n    public override removePart(index: number): void {\r\n        super.removePart(index);\r\n    }\r\n\r\n    /**\r\n     * Serialize current GaussianSplattingMesh\r\n     * @param serializationObject defines the object which will receive the serialization data\r\n     * @param encoding the encoding of binary data, defaults to base64 for json serialize,\r\n     * kept for future internal use like cloning where base64 encoding wastes cycles and memory\r\n     * @returns the serialized object\r\n     */\r\n    public override serialize(serializationObject: any = {}, encoding: string = \"base64\"): any {\r\n        serializationObject = super.serialize(serializationObject, encoding);\r\n        // Note here, the getClassName() is not overridden,\r\n        // as a lot of code currently depend on `getClassName() === \"GaussianSplattingMesh\"` check,\r\n        // to not break those code, serialization uses `_isCompound` to mark the type\r\n        serializationObject._isCompound = true;\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a serialized GaussianSplattingCompoundMesh\r\n     * @param parsedMesh the serialized mesh\r\n     * @param scene the scene to create the GaussianSplattingCompoundMesh in\r\n     * @returns the created GaussianSplattingCompoundMesh\r\n     */\r\n    public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingCompoundMesh {\r\n        return GaussianSplattingMesh._ParseInternal(parsedMesh, scene, GaussianSplattingCompoundMesh);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingCompoundMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingCompoundMesh(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Mesh._GaussianSplattingCompoundMeshParser = GaussianSplattingCompoundMesh.Parse;\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../../types\";\nimport { type Observer } from \"../../Misc/observable\";\nimport { type Node } from \"../../node\";\nimport { type Vector3 } from \"../../Maths/math.vector\";\nimport { GaussianSplattingMaterial } from \"../../Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\nimport { GaussianSplattingDebugMaterialPlugin, type IGaussianSplattingDebugOptions } from \"../../Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure\";\nimport { type GaussianSplattingMeshBase } from \"./gaussianSplattingMeshBase.pure\";\n\n/**\n * Manages debug rendering options across a set of Gaussian splat meshes.\n * Create one instance, add meshes via addMesh(), then set options to apply\n * them to every registered mesh simultaneously.\n *\n * All options default to their \"off\" states so there is no rendering cost\n * until a feature is explicitly enabled.\n *\n * @example\n * ```ts\n * // Global options — applied to every registered mesh\n * const gsDebugger = new GaussianSplattingDebugger();\n * gsDebugger.addMesh(mesh1);\n * gsDebugger.addMesh(compoundMesh); // compound mesh with multiple parts\n * gsDebugger.clippingBox = { min: new Vector3(-2, -2, -2), max: new Vector3(2, 2, 2) };\n * gsDebugger.shOrder1 = false;\n *\n * // Per-part override — saturate opacity on part 0 of the compound mesh only,\n * // leaving all other parts (and mesh1) unaffected\n * gsDebugger.setPartOptions(compoundMesh, 0, { opacitySaturate: true });\n * // Later, restore part 0 to the global setting\n * gsDebugger.clearPartOptions(compoundMesh, 0);\n * ```\n */\nexport class GaussianSplattingDebugger {\n    private _plugins: GaussianSplattingDebugMaterialPlugin[] = [];\n    private _meshes: GaussianSplattingMeshBase[] = [];\n    private _disposeObservers: Observer<Node>[] = [];\n    // observable.add() returns Nullable<Observer<T>>; Observable.remove() accepts null safely.\n    private _partCountObservers: Nullable<Observer<number>>[] = [];\n    private _partRemovedObservers: Nullable<Observer<number>>[] = [];\n\n    // Cached option state so newly added meshes inherit current settings\n    private _clippingBox: Nullable<{ min: Vector3; max: Vector3 }> = null;\n    private _opacityCulling: Nullable<{ min: number; max: number }> = null;\n    private _sizeCulling: Nullable<{ min: number; max: number }> = null;\n    private _opacityScale: number = 1.0;\n    private _opacitySaturate: boolean = false;\n    private _shDc: boolean = true;\n    private _shOrder1: boolean = true;\n    private _shOrder2: boolean = true;\n    private _shOrder3: boolean = true;\n    private _shOrder4: boolean = true;\n\n    /**\n     * Adds a mesh to the debugger, attaching a debug plugin to its material.\n     * The mesh must already have a GaussianSplattingMaterial assigned (i.e., data\n     * must have been loaded at least once). Current option values are applied immediately.\n     * The mesh is automatically unregistered if it is disposed.\n     * @param mesh The mesh to register.\n     */\n    public addMesh(mesh: GaussianSplattingMeshBase): void {\n        if (this._meshes.indexOf(mesh) !== -1) {\n            return;\n        }\n        const mat = mesh.material;\n        if (!(mat instanceof GaussianSplattingMaterial)) {\n            throw new Error(\"GaussianSplattingDebugger.addMesh: mesh must have a GaussianSplattingMaterial.\");\n        }\n        const plugin = new GaussianSplattingDebugMaterialPlugin(mat);\n        plugin.partCount = (mesh as unknown as { partCount?: number }).partCount ?? 0;\n        this._applyAllTo(plugin);\n        this._meshes.push(mesh);\n        this._plugins.push(plugin);\n        this._disposeObservers.push(mesh.onDisposeObservable.add(() => this.removeMesh(mesh))!);\n        this._partCountObservers.push(\n            mesh.onPartCountChangedObservable.add((count) => {\n                plugin.partCount = count;\n            })\n        );\n        this._partRemovedObservers.push(\n            mesh.onPartRemovedObservable.add((removedIndex) => {\n                plugin.shiftPartOptions(removedIndex);\n            })\n        );\n    }\n\n    /**\n     * Removes a mesh and disposes its debug plugin.\n     * @param mesh The mesh to unregister.\n     */\n    public removeMesh(mesh: GaussianSplattingMeshBase): void {\n        const idx = this._meshes.indexOf(mesh);\n        if (idx === -1) {\n            return;\n        }\n        mesh.onDisposeObservable.remove(this._disposeObservers[idx]);\n        mesh.onPartCountChangedObservable.remove(this._partCountObservers[idx]);\n        mesh.onPartRemovedObservable.remove(this._partRemovedObservers[idx]);\n        this._plugins[idx].dispose();\n        this._meshes.splice(idx, 1);\n        this._plugins.splice(idx, 1);\n        this._disposeObservers.splice(idx, 1);\n        this._partCountObservers.splice(idx, 1);\n        this._partRemovedObservers.splice(idx, 1);\n    }\n\n    /** Disposes all debug plugins and clears the mesh list. */\n    public dispose(): void {\n        for (let i = 0; i < this._meshes.length; i++) {\n            this._meshes[i].onDisposeObservable.remove(this._disposeObservers[i]);\n            this._meshes[i].onPartCountChangedObservable.remove(this._partCountObservers[i]);\n            this._meshes[i].onPartRemovedObservable.remove(this._partRemovedObservers[i]);\n            this._plugins[i].dispose();\n        }\n        this._meshes.length = 0;\n        this._plugins.length = 0;\n        this._disposeObservers.length = 0;\n        this._partCountObservers.length = 0;\n        this._partRemovedObservers.length = 0;\n    }\n\n    /**\n     * Returns the min/max size range of splats in a mesh.\n     * Convenience wrapper for GaussianSplattingMeshBase.splatSizeRange.\n     * @param mesh The mesh to query.\n     * @returns the splat size range, or null if not yet computed.\n     */\n    public static GetSplatSizeRange(mesh: GaussianSplattingMeshBase): Nullable<{ min: number; max: number }> {\n        return mesh.splatSizeRange;\n    }\n\n    // ----- Option setters (broadcast to all plugins) -----\n\n    private _applyAllTo(plugin: GaussianSplattingDebugMaterialPlugin): void {\n        plugin.clippingBox = this._clippingBox;\n        plugin.opacityCulling = this._opacityCulling;\n        plugin.sizeCulling = this._sizeCulling;\n        plugin.opacityScale = this._opacityScale;\n        plugin.opacitySaturate = this._opacitySaturate;\n        plugin.shDc = this._shDc;\n        plugin.shOrder1 = this._shOrder1;\n        plugin.shOrder2 = this._shOrder2;\n        plugin.shOrder3 = this._shOrder3;\n        plugin.shOrder4 = this._shOrder4;\n    }\n\n    /**\n     * World-space axis-aligned clipping box. Splats outside are not rendered.\n     * Set to null to disable.\n     */\n    public get clippingBox(): Nullable<{ min: Vector3; max: Vector3 }> {\n        return this._clippingBox;\n    }\n    public set clippingBox(value: Nullable<{ min: Vector3; max: Vector3 }>) {\n        this._clippingBox = value;\n        for (const p of this._plugins) {\n            p.clippingBox = value;\n        }\n    }\n\n    /**\n     * Opacity culling range [0..1]. Splats outside this range are not rendered.\n     * Set to null to disable.\n     */\n    public get opacityCulling(): Nullable<{ min: number; max: number }> {\n        return this._opacityCulling;\n    }\n    public set opacityCulling(value: Nullable<{ min: number; max: number }>) {\n        this._opacityCulling = value;\n        for (const p of this._plugins) {\n            p.opacityCulling = value;\n        }\n    }\n\n    /**\n     * Size culling range. Size is pow(|det(Σ)|, 1/6) of the 3D covariance matrix,\n     * equal to the geometric mean of the principal radii. Splats outside this range are not rendered.\n     * Use GaussianSplattingDebugger.GetSplatSizeRange(mesh) to find an asset's range.\n     * Set to null to disable.\n     */\n    public get sizeCulling(): Nullable<{ min: number; max: number }> {\n        return this._sizeCulling;\n    }\n    public set sizeCulling(value: Nullable<{ min: number; max: number }>) {\n        this._sizeCulling = value;\n        for (const p of this._plugins) {\n            p.sizeCulling = value;\n        }\n    }\n\n    /** Scalar multiplier applied to every splat's opacity. 1.0 = no change. */\n    public get opacityScale(): number {\n        return this._opacityScale;\n    }\n    public set opacityScale(value: number) {\n        this._opacityScale = value;\n        for (const p of this._plugins) {\n            p.opacityScale = value;\n        }\n    }\n\n    /**\n     * When true, replaces the Gaussian spatial falloff with a flat uniform opacity,\n     * showing each splat as a solid disk.\n     */\n    public get opacitySaturate(): boolean {\n        return this._opacitySaturate;\n    }\n    public set opacitySaturate(value: boolean) {\n        this._opacitySaturate = value;\n        for (const p of this._plugins) {\n            p.opacitySaturate = value;\n        }\n    }\n\n    /** Include the DC (base) color from colorsTexture. Default: true. */\n    public get shDc(): boolean {\n        return this._shDc;\n    }\n    public set shDc(value: boolean) {\n        this._shDc = value;\n        for (const p of this._plugins) {\n            p.shDc = value;\n        }\n    }\n\n    /** Include SH band 1 contribution. Default: true. */\n    public get shOrder1(): boolean {\n        return this._shOrder1;\n    }\n    public set shOrder1(value: boolean) {\n        this._shOrder1 = value;\n        for (const p of this._plugins) {\n            p.shOrder1 = value;\n        }\n    }\n\n    /** Include SH band 2 contribution. Default: true. */\n    public get shOrder2(): boolean {\n        return this._shOrder2;\n    }\n    public set shOrder2(value: boolean) {\n        this._shOrder2 = value;\n        for (const p of this._plugins) {\n            p.shOrder2 = value;\n        }\n    }\n\n    /** Include SH band 3 contribution. Default: true. */\n    public get shOrder3(): boolean {\n        return this._shOrder3;\n    }\n    public set shOrder3(value: boolean) {\n        this._shOrder3 = value;\n        for (const p of this._plugins) {\n            p.shOrder3 = value;\n        }\n    }\n\n    /** Include SH band 4 contribution. Default: true. */\n    public get shOrder4(): boolean {\n        return this._shOrder4;\n    }\n    public set shOrder4(value: boolean) {\n        this._shOrder4 = value;\n        for (const p of this._plugins) {\n            p.shOrder4 = value;\n        }\n    }\n\n    // ----- Per-part API (compound meshes only) -----\n\n    /**\n     * Sets per-part debug overrides for a specific part of a compound mesh.\n     * The mesh must already be registered via addMesh(). Logs an error if the mesh\n     * is not compound (partCount is 0).\n     * @param mesh The compound mesh.\n     * @param partIndex The zero-based part index.\n     * @param options Partial set of debug options to override for this part.\n     */\n    public setPartOptions(mesh: GaussianSplattingMeshBase, partIndex: number, options: Partial<IGaussianSplattingDebugOptions>): void {\n        const idx = this._meshes.indexOf(mesh);\n        if (idx < 0) {\n            return;\n        }\n        this._plugins[idx].setPartOptions(partIndex, options);\n    }\n\n    /**\n     * Clears all per-part debug overrides for a specific part, falling back to global settings.\n     * @param mesh The compound mesh.\n     * @param partIndex The zero-based part index.\n     */\n    public clearPartOptions(mesh: GaussianSplattingMeshBase, partIndex: number): void {\n        const idx = this._meshes.indexOf(mesh);\n        if (idx < 0) {\n            return;\n        }\n        this._plugins[idx].clearPartOptions(partIndex);\n    }\n}\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\n\nconst name = \"colorPixelShader\";\nconst shader = `#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\n#define VERTEXCOLOR\nvarying vColor: vec4f;\n#else\nuniform color: vec4f;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nfragmentOutputs.color=input.vColor;\n#else\nfragmentOutputs.color=uniforms.color;\n#endif\n#include<fogFragment>(color,fragmentOutputs.color)\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclarationWGSL, fogFragmentDeclarationWGSL, clipPlaneFragmentWGSL, fogFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const colorPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { vertexColorMixingWGSL } from \"./ShadersInclude/vertexColorMixing\";\n\nconst name = \"colorVertexShader\";\nconst shader = `attribute position: vec3f;\n#ifdef VERTEXCOLOR\nattribute color: vec4f;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#ifdef FOG\nuniform view: mat4x4f;\n#endif\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;\n#if defined(VERTEXCOLOR) || defined(INSTANCESCOLOR) && defined(INSTANCES)\nvarying vColor: vec4f;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef VERTEXCOLOR\nvar colorUpdated: vec4f=vertexInputs.color;\n#endif\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld* vec4f(vertexInputs.position,1.0);vertexOutputs.position=uniforms.viewProjection*worldPos;\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<vertexColorMixing>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, instancesDeclarationWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL, fogVertexWGSL, vertexColorMixingWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const colorVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"meshUVSpaceRendererVertexShader\";\nconst shader = `precision highp float;attribute vec3 position;attribute vec3 normal;attribute vec2 uv;uniform mat4 projMatrix;varying vec2 vDecalTC;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\nvoid main(void) {vec3 positionUpdated=position;vec3 normalUpdated=normal;\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);mat3 normWorldSM=mat3(finalWorld);vec3 vNormalW;\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvNormalW=normalUpdated/vec3(dot(normWorldSM[0],normWorldSM[0]),dot(normWorldSM[1],normWorldSM[1]),dot(normWorldSM[2],normWorldSM[2]));vNormalW=normalize(normWorldSM*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormWorldSM=transposeMat3(inverseMat3(normWorldSM));\n#endif\nvNormalW=normalize(normWorldSM*normalUpdated);\n#endif\nvec3 normalView=normalize((projMatrix*vec4(vNormalW,0.0)).xyz);vec3 decalTC=(projMatrix*worldPos).xyz;vDecalTC=decalTC.xy;gl_Position=vec4(uv*2.0-1.0,normalView.z>0.0 ? 2. : decalTC.z,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, instancesDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const meshUVSpaceRendererVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererPixelShader\";\nconst shader = `precision highp float;varying vec2 vDecalTC;uniform sampler2D textureSampler;void main(void) {if (vDecalTC.x<0. || vDecalTC.x>1. || vDecalTC.y<0. || vDecalTC.y>1.) {discard;}\ngl_FragColor=texture2D(textureSampler,vDecalTC);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererMaskerVertexShader\";\nconst shader = `attribute vec2 uv;varying vec2 vUV;void main(void) {gl_Position=vec4(vec2(uv.x,uv.y)*2.0-1.0,0.,1.0);vUV=uv;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererMaskerVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererMaskerPixelShader\";\nconst shader = `varying vec2 vUV;void main(void) {gl_FragColor=vec4(1.0,1.0,1.0,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererMaskerPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererFinaliserPixelShader\";\nconst shader = `precision highp float;varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D maskTextureSampler;uniform vec2 textureSize;void main() {vec4 mask=texture2D(maskTextureSampler,vUV).rgba;if (mask.r>0.5) {gl_FragColor=texture2D(textureSampler,vUV);} else {vec2 texelSize=4.0/textureSize;vec2 uv_p01=vUV+vec2(-1.0,0.0)*texelSize;vec2 uv_p21=vUV+vec2(1.0,0.0)*texelSize;vec2 uv_p10=vUV+vec2(0.0,-1.0)*texelSize;vec2 uv_p12=vUV+vec2(0.0,1.0)*texelSize;float mask_p01=texture2D(maskTextureSampler,uv_p01).r;float mask_p21=texture2D(maskTextureSampler,uv_p21).r;float mask_p10=texture2D(maskTextureSampler,uv_p10).r;float mask_p12=texture2D(maskTextureSampler,uv_p12).r;vec4 col=vec4(0.0,0.0,0.0,0.0);float total_weight=0.0;if (mask_p01>0.5) {col+=texture2D(textureSampler,uv_p01);total_weight+=1.0;}\nif (mask_p21>0.5) {col+=texture2D(textureSampler,uv_p21);total_weight+=1.0;}\nif (mask_p10>0.5) {col+=texture2D(textureSampler,uv_p10);total_weight+=1.0;}\nif (mask_p12>0.5) {col+=texture2D(textureSampler,uv_p12);total_weight+=1.0;}\nif (total_weight>0.0) {gl_FragColor=col/total_weight;} else {gl_FragColor=col;}}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererFinaliserPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererFinaliserVertexShader\";\nconst shader = `precision highp float;attribute vec3 position;attribute vec2 uv;uniform mat4 worldViewProjection;varying vec2 vUV;void main() {gl_Position=worldViewProjection*vec4(position,1.0);vUV=uv;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererFinaliserVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"meshUVSpaceRendererVertexShader\";\nconst shader = `attribute position: vec3f;attribute normal: vec3f;attribute uv: vec2f;uniform projMatrix: mat4x4f;varying vDecalTC: vec2f;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;var normalUpdated: vec3f=vertexInputs.normal;\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld* vec4f(positionUpdated,1.0);var normWorldSM: mat3x3f= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);var vNormalW: vec3f;\n#if defined(INSTANCES) && defined(THIN_INSTANCES)\nvNormalW=normalUpdated/ vec3f(dot(normWorldSM[0],normWorldSM[0]),dot(normWorldSM[1],normWorldSM[1]),dot(normWorldSM[2],normWorldSM[2]));vNormalW=normalize(normWorldSM*vNormalW);\n#else\n#ifdef NONUNIFORMSCALING\nnormWorldSM=transposeMat3(inverseMat3(normWorldSM));\n#endif\nvNormalW=normalize(normWorldSM*normalUpdated);\n#endif\nvar normalView: vec3f=normalize((uniforms.projMatrix* vec4f(vNormalW,0.0)).xyz);var decalTC: vec3f=(uniforms.projMatrix*worldPos).xyz;vertexOutputs.vDecalTC=decalTC.xy;vertexOutputs.position=vec4f(vertexInputs.uv*2.0-1.0,select(decalTC.z,2.,normalView.z>0.0),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, instancesDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const meshUVSpaceRendererVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererPixelShader\";\nconst shader = `varying vDecalTC: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {if (input.vDecalTC.x<0. || input.vDecalTC.x>1. || input.vDecalTC.y<0. || input.vDecalTC.y>1.) {discard;}\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vDecalTC);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererMaskerVertexShader\";\nconst shader = `attribute uv: vec2f;varying vUV: vec2f;@vertex\nfn main(input : VertexInputs)->FragmentInputs {vertexOutputs.position= vec4f( vec2f(vertexInputs.uv.x,vertexInputs.uv.y)*2.0-1.0,0.,1.0);vertexOutputs.vUV=vertexInputs.uv;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererMaskerVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererMaskerPixelShader\";\nconst shader = `varying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color= vec4f(1.0,1.0,1.0,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererMaskerPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererFinaliserPixelShader\";\nconst shader = `#define DISABLE_UNIFORMITY_ANALYSIS\nvarying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var maskTextureSamplerSampler: sampler;var maskTextureSampler: texture_2d<f32>;uniform textureSize: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var mask: vec4f=textureSample(maskTextureSampler,maskTextureSamplerSampler,input.vUV).rgba;if (mask.r>0.5) {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);} else {var texelSize: vec2f=4.0/uniforms.textureSize;var uv_p01: vec2f=input.vUV+ vec2f(-1.0,0.0)*texelSize;var uv_p21: vec2f=input.vUV+ vec2f(1.0,0.0)*texelSize;var uv_p10: vec2f=input.vUV+ vec2f(0.0,-1.0)*texelSize;var uv_p12: vec2f=input.vUV+ vec2f(0.0,1.0)*texelSize;var mask_p01: f32=textureSample(maskTextureSampler,maskTextureSamplerSampler,uv_p01).r;var mask_p21: f32=textureSample(maskTextureSampler,maskTextureSamplerSampler,uv_p21).r;var mask_p10: f32=textureSample(maskTextureSampler,maskTextureSamplerSampler,uv_p10).r;var mask_p12: f32=textureSample(maskTextureSampler,maskTextureSamplerSampler,uv_p12).r;var col: vec4f= vec4f(0.0,0.0,0.0,0.0);var total_weight: f32=0.0;if (mask_p01>0.5) {col+=textureSample(textureSampler,textureSamplerSampler,uv_p01);total_weight+=1.0;}\nif (mask_p21>0.5) {col+=textureSample(textureSampler,textureSamplerSampler,uv_p21);total_weight+=1.0;}\nif (mask_p10>0.5) {col+=textureSample(textureSampler,textureSamplerSampler,uv_p10);total_weight+=1.0;}\nif (mask_p12>0.5) {col+=textureSample(textureSampler,textureSamplerSampler,uv_p12);total_weight+=1.0;}\nif (total_weight>0.0) {fragmentOutputs.color=col/total_weight;} else {fragmentOutputs.color=col;}}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererFinaliserPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshUVSpaceRendererFinaliserVertexShader\";\nconst shader = `attribute position: vec3f;attribute uv: vec2f;uniform worldViewProjection: mat4x4f;varying vUV: vec2f;@vertex\nfn main(input : VertexInputs)->FragmentInputs {vertexOutputs.position=uniforms.worldViewProjection* vec4f(vertexInputs.position,1.0);vertexOutputs.positionvUV=vertexInputs.uv;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const meshUVSpaceRendererFinaliserVertexShaderWGSL = { name, shader };\n","import { type Scene } from \"../scene\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport { type Skeleton } from \"../Bones/skeleton\";\r\nimport { type PluginOptions, SceneLoader, SceneLoaderAnimationGroupLoadingMode } from \"../Loading/sceneLoader\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { Observable } from \"./observable\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { type ITextureCreationOptions, Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type ICubeTextureCreationOptions, CubeTexture } from \"../Materials/Textures/cubeTexture.pure\";\r\nimport { HDRCubeTexture } from \"../Materials/Textures/hdrCubeTexture.pure\";\r\nimport { EquiRectangularCubeTexture } from \"../Materials/Textures/equiRectangularCubeTexture.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Animatable } from \"../Animations/animatable.core\";\r\nimport { type AnimationGroup } from \"../Animations/animationGroup\";\r\nimport { type AssetContainer } from \"../assetContainer\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Nullable } from \"../types\";\r\n\r\n/**\r\n * Defines the list of states available for a task inside a AssetsManager\r\n */\r\nexport const enum AssetTaskState {\r\n    /**\r\n     * Initialization\r\n     */\r\n    INIT,\r\n    /**\r\n     * Running\r\n     */\r\n    RUNNING,\r\n    /**\r\n     * Done\r\n     */\r\n    DONE,\r\n    /**\r\n     * Error\r\n     */\r\n    ERROR,\r\n}\r\n\r\n/**\r\n * Define an abstract asset task used with a AssetsManager class to load assets into a scene\r\n */\r\nexport abstract class AbstractAssetTask {\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public onSuccess: (task: any) => void;\r\n\r\n    /**\r\n     * Callback called when the task is not successful\r\n     */\r\n    public onError: (task: any, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new AssetsManager\r\n     * @param name defines the name of the task\r\n     */\r\n    constructor(\r\n        /**\r\n         * Task name\r\n         */ public name: string\r\n    ) {}\r\n\r\n    private _isCompleted = false;\r\n    private _taskState = AssetTaskState.INIT;\r\n    private _errorObject: { message?: string; exception?: any };\r\n\r\n    /**\r\n     * Get if the task is completed\r\n     */\r\n    public get isCompleted(): boolean {\r\n        return this._isCompleted;\r\n    }\r\n\r\n    /**\r\n     * Gets the current state of the task\r\n     */\r\n    public get taskState(): AssetTaskState {\r\n        return this._taskState;\r\n    }\r\n\r\n    /**\r\n     * Gets the current error object (if task is in error)\r\n     */\r\n    public get errorObject(): { message?: string; exception?: any } {\r\n        return this._errorObject;\r\n    }\r\n\r\n    /**\r\n     * Internal only\r\n     * @internal\r\n     */\r\n    public _setErrorObject(message?: string, exception?: any) {\r\n        if (this._errorObject) {\r\n            return;\r\n        }\r\n\r\n        this._errorObject = {\r\n            message: message,\r\n            exception: exception,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        this._taskState = AssetTaskState.RUNNING;\r\n        this.runTask(\r\n            scene,\r\n            () => {\r\n                this._onDoneCallback(onSuccess, onError);\r\n            },\r\n            (msg, exception) => {\r\n                this._onErrorCallback(onError, msg, exception);\r\n            }\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        throw new Error(\"runTask is not implemented\");\r\n    }\r\n\r\n    /**\r\n     * Reset will set the task state back to INIT, so the next load call of the assets manager will execute this task again.\r\n     * This can be used with failed tasks that have the reason for failure fixed.\r\n     */\r\n    public reset() {\r\n        this._taskState = AssetTaskState.INIT;\r\n    }\r\n\r\n    private _onErrorCallback(onError: (message?: string, exception?: any) => void, message?: string, exception?: any) {\r\n        this._taskState = AssetTaskState.ERROR;\r\n\r\n        this._errorObject = {\r\n            message: message,\r\n            exception: exception,\r\n        };\r\n\r\n        if (this.onError) {\r\n            this.onError(this, message, exception);\r\n        }\r\n\r\n        onError();\r\n    }\r\n\r\n    private _onDoneCallback(onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        try {\r\n            this._taskState = AssetTaskState.DONE;\r\n            this._isCompleted = true;\r\n\r\n            if (this.onSuccess) {\r\n                this.onSuccess(this);\r\n            }\r\n\r\n            onSuccess();\r\n        } catch (e) {\r\n            this._onErrorCallback(onError, \"Task is done, error executing success callback(s)\", e);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Define the interface used by progress events raised during assets loading\r\n */\r\nexport interface IAssetsProgressEvent {\r\n    /**\r\n     * Defines the number of remaining tasks to process\r\n     */\r\n    remainingCount: number;\r\n    /**\r\n     * Defines the total number of tasks\r\n     */\r\n    totalCount: number;\r\n    /**\r\n     * Defines the task that was just processed\r\n     */\r\n    task: AbstractAssetTask;\r\n}\r\n\r\n/**\r\n * Class used to share progress information about assets loading\r\n */\r\nexport class AssetsProgressEvent implements IAssetsProgressEvent {\r\n    /**\r\n     * Defines the number of remaining tasks to process\r\n     */\r\n    public remainingCount: number;\r\n    /**\r\n     * Defines the total number of tasks\r\n     */\r\n    public totalCount: number;\r\n    /**\r\n     * Defines the task that was just processed\r\n     */\r\n    public task: AbstractAssetTask;\r\n\r\n    /**\r\n     * Creates a AssetsProgressEvent\r\n     * @param remainingCount defines the number of remaining tasks to process\r\n     * @param totalCount defines the total number of tasks\r\n     * @param task defines the task that was just processed\r\n     */\r\n    constructor(remainingCount: number, totalCount: number, task: AbstractAssetTask) {\r\n        this.remainingCount = remainingCount;\r\n        this.totalCount = totalCount;\r\n        this.task = task;\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load assets into a container\r\n */\r\nexport class ContainerAssetTask extends AbstractAssetTask {\r\n    /**\r\n     * Get the loaded asset container\r\n     */\r\n    public loadedContainer: AssetContainer;\r\n    /**\r\n     * Gets the list of loaded transforms\r\n     */\r\n    public loadedTransformNodes: Array<TransformNode>;\r\n    /**\r\n     * Gets the list of loaded meshes\r\n     */\r\n    public loadedMeshes: Array<AbstractMesh>;\r\n    /**\r\n     * Gets the list of loaded particle systems\r\n     */\r\n    public loadedParticleSystems: Array<IParticleSystem>;\r\n    /**\r\n     * Gets the list of loaded skeletons\r\n     */\r\n    public loadedSkeletons: Array<Skeleton>;\r\n    /**\r\n     * Gets the list of loaded animation groups\r\n     */\r\n    public loadedAnimationGroups: Array<AnimationGroup>;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: ContainerAssetTask) => void;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: ContainerAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new ContainerAssetTask\r\n     * @param name defines the name of the task\r\n     * @param meshesNames defines the list of mesh's names you want to load\r\n     * @param rootUrl defines the root url to use as a base to load your meshes and associated resources\r\n     * @param sceneFilename defines the filename or File of the scene to load from\r\n     * @param extension defines the extension to use to load the scene (if not defined, \".babylon\" will be used)\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the list of mesh's names you want to load\r\n         */\r\n        public meshesNames: any,\r\n        /**\r\n         * Defines the root url to use as a base to load your meshes and associated resources\r\n         */\r\n        public rootUrl: string,\r\n        /**\r\n         * Defines the filename or File of the scene to load from\r\n         */\r\n        public sceneFilename: string | File,\r\n        /**\r\n         * Defines the extension to use to load the scene (if not defined, \".babylon\" will be used)\r\n         */\r\n        public extension?: string\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        SceneLoader.LoadAssetContainer(\r\n            this.rootUrl,\r\n            this.sceneFilename,\r\n            scene,\r\n            (container: AssetContainer) => {\r\n                this.loadedContainer = container;\r\n                this.loadedMeshes = container.meshes;\r\n                this.loadedTransformNodes = container.transformNodes;\r\n                this.loadedParticleSystems = container.particleSystems;\r\n                this.loadedSkeletons = container.skeletons;\r\n                this.loadedAnimationGroups = container.animationGroups;\r\n                onSuccess();\r\n            },\r\n            null,\r\n            (scene, message, exception) => {\r\n                onError(message, exception);\r\n            },\r\n            this.extension\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load meshes\r\n */\r\nexport class MeshAssetTask extends AbstractAssetTask {\r\n    /**\r\n     * Gets the list of loaded transforms\r\n     */\r\n    public loadedTransformNodes: Array<TransformNode>;\r\n    /**\r\n     * Gets the list of loaded meshes\r\n     */\r\n    public loadedMeshes: Array<AbstractMesh>;\r\n    /**\r\n     * Gets the list of loaded particle systems\r\n     */\r\n    public loadedParticleSystems: Array<IParticleSystem>;\r\n    /**\r\n     * Gets the list of loaded skeletons\r\n     */\r\n    public loadedSkeletons: Array<Skeleton>;\r\n    /**\r\n     * Gets the list of loaded animation groups\r\n     */\r\n    public loadedAnimationGroups: Array<AnimationGroup>;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: MeshAssetTask) => void;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: MeshAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new MeshAssetTask\r\n     * @param name defines the name of the task\r\n     * @param meshesNames defines the list of mesh's names you want to load\r\n     * @param rootUrl defines the root url to use as a base to load your meshes and associated resources\r\n     * @param sceneFilename defines the filename or File of the scene to load from\r\n     * @param extension defines the extension to use to load the scene (if not defined, \".babylon\" will be used)\r\n     * @param fileName defines the name of the file, if the data is binary\r\n     * @param pluginOptions defines the options to use with the plugin\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the list of mesh's names you want to load\r\n         */\r\n        public meshesNames: any,\r\n        /**\r\n         * Defines the root url to use as a base to load your meshes and associated resources\r\n         */\r\n        public rootUrl: string,\r\n        /**\r\n         * Defines the filename or File of the scene to load from\r\n         */\r\n        public sceneFilename: string | File,\r\n        /**\r\n         * Defines the extension to use to load the scene (if not defined, \".babylon\" will be used)\r\n         */\r\n        public extension?: string,\r\n        /**\r\n         * defines the name of the file, if the data is binary\r\n         */\r\n        public fileName?: string,\r\n        /**\r\n         * defines the options to use with the plugin\r\n         */\r\n        public pluginOptions?: PluginOptions\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        SceneLoader.ImportMesh(\r\n            this.meshesNames,\r\n            this.rootUrl,\r\n            this.sceneFilename,\r\n            scene,\r\n            (meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[], transformNodes: TransformNode[]) => {\r\n                this.loadedMeshes = meshes;\r\n                this.loadedTransformNodes = transformNodes;\r\n                this.loadedParticleSystems = particleSystems;\r\n                this.loadedSkeletons = skeletons;\r\n                this.loadedAnimationGroups = animationGroups;\r\n                onSuccess();\r\n            },\r\n            null,\r\n            (scene, message, exception) => {\r\n                onError(message, exception);\r\n            },\r\n            this.extension,\r\n            this.fileName,\r\n            this.pluginOptions\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load animations\r\n */\r\nexport class AnimationAssetTask extends AbstractAssetTask {\r\n    /**\r\n     * Gets the list of loaded animation groups\r\n     */\r\n    public loadedAnimationGroups: Array<AnimationGroup>;\r\n    /**\r\n     * Gets the list of loaded animatables\r\n     */\r\n    public loadedAnimatables: Array<Animatable>;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: AnimationAssetTask) => void;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: AnimationAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new AnimationAssetTask\r\n     * @param name defines the name of the task\r\n     * @param rootUrl defines the root url to use as a base to load your meshes and associated resources\r\n     * @param filename defines the filename or File of the scene to load from\r\n     * @param targetConverter defines a function used to convert animation targets from loaded scene to current scene (default: search node by name)\r\n     * @param extension defines the extension to use to load the scene (if not defined, \".babylon\" will be used)\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the root url to use as a base to load your meshes and associated resources\r\n         */\r\n        public rootUrl: string,\r\n        /**\r\n         * Defines the filename to load from\r\n         */\r\n        public filename: string | File,\r\n        /**\r\n         * Defines a function used to convert animation targets from loaded scene to current scene (default: search node by name)\r\n         */\r\n        public targetConverter?: Nullable<(target: any) => any>,\r\n        /**\r\n         * Defines the extension to use to load the scene (if not defined, \".babylon\" will be used)\r\n         */\r\n        public extension?: string\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        const startingIndexForNewAnimatables = scene.animatables.length;\r\n        const startingIndexForNewAnimationGroups = scene.animationGroups.length;\r\n        this.loadedAnimatables = [];\r\n        this.loadedAnimationGroups = [];\r\n        SceneLoader.ImportAnimations(\r\n            this.rootUrl,\r\n            this.filename,\r\n            scene,\r\n            false,\r\n            SceneLoaderAnimationGroupLoadingMode.NoSync,\r\n            this.targetConverter,\r\n            () => {\r\n                this.loadedAnimatables = scene.animatables.slice(startingIndexForNewAnimatables);\r\n                this.loadedAnimationGroups = scene.animationGroups.slice(startingIndexForNewAnimationGroups);\r\n\r\n                onSuccess();\r\n            },\r\n            null,\r\n            (scene, message, exception) => {\r\n                onError(message, exception);\r\n            },\r\n            this.extension\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load text content\r\n */\r\nexport class TextFileAssetTask extends AbstractAssetTask {\r\n    /**\r\n     * Gets the loaded text string\r\n     */\r\n    public text: string;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: TextFileAssetTask) => void;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: TextFileAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new TextFileAssetTask object\r\n     * @param name defines the name of the task\r\n     * @param url defines the location of the file to load\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the file to load\r\n         */\r\n        public url: string\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        scene._loadFile(\r\n            this.url,\r\n            (data) => {\r\n                this.text = data as string;\r\n                onSuccess();\r\n            },\r\n            undefined,\r\n            false,\r\n            false,\r\n            (request, exception) => {\r\n                if (request) {\r\n                    onError(request.status + \" \" + request.statusText, exception);\r\n                }\r\n            }\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load binary data\r\n */\r\nexport class BinaryFileAssetTask extends AbstractAssetTask {\r\n    /**\r\n     * Gets the loaded data (as an array buffer)\r\n     */\r\n    public data: ArrayBuffer;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: BinaryFileAssetTask) => void;\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: BinaryFileAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new BinaryFileAssetTask object\r\n     * @param name defines the name of the new task\r\n     * @param url defines the location of the file to load\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the file to load\r\n         */\r\n        public url: string\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        scene._loadFile(\r\n            this.url,\r\n            (data) => {\r\n                this.data = data as ArrayBuffer;\r\n                onSuccess();\r\n            },\r\n            undefined,\r\n            true,\r\n            true,\r\n            (request, exception) => {\r\n                if (request) {\r\n                    onError(request.status + \" \" + request.statusText, exception);\r\n                }\r\n            }\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load images\r\n */\r\nexport class ImageAssetTask extends AbstractAssetTask {\r\n    /**\r\n     * Gets the loaded images\r\n     */\r\n    public image: HTMLImageElement;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: ImageAssetTask) => void;\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: ImageAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new ImageAssetTask\r\n     * @param name defines the name of the task\r\n     * @param url defines the location of the image to load\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the image to load\r\n         */\r\n        public url: string\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        const img = new Image();\r\n\r\n        Tools.SetCorsBehavior(this.url, img);\r\n\r\n        img.onload = () => {\r\n            this.image = img;\r\n            onSuccess();\r\n        };\r\n\r\n        img.onerror = (err: string | Event): any => {\r\n            onError(\"Error loading image\", err);\r\n        };\r\n\r\n        img.src = this.url;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines the interface used by texture loading tasks\r\n */\r\nexport interface ITextureAssetTask<Tex extends BaseTexture> {\r\n    /**\r\n     * Gets the loaded texture\r\n     */\r\n    texture: Tex;\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load 2D textures\r\n */\r\nexport class TextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<Texture> {\r\n    /**\r\n     * Gets the loaded texture\r\n     */\r\n    public texture: Texture;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: TextureAssetTask) => void;\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: TextureAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new TextureAssetTask object\r\n     * @param name defines the name of the task\r\n     * @param url defines the location of the file to load\r\n     * @param noMipmapOrOptions defines if mipmap should not be generated (default is false) or the creation options to use\r\n     * @param invertY defines if texture must be inverted on Y axis (default is true)\r\n     * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the file to load\r\n         */\r\n        public url: string,\r\n        /**\r\n         * Defines if mipmap should not be generated (default is false) or the creation options to use\r\n         */\r\n        public noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n        /**\r\n         * [true] Defines if texture must be inverted on Y axis (default is true)\r\n         */\r\n        public invertY: boolean = true,\r\n        /**\r\n         * [3] Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)\r\n         */\r\n        public samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        const onload = () => {\r\n            onSuccess();\r\n        };\r\n\r\n        const onerror = (message?: string, exception?: any) => {\r\n            onError(message, exception);\r\n        };\r\n\r\n        this.texture = new Texture(this.url, scene, this.noMipmapOrOptions, this.invertY, this.samplingMode, onload, onerror);\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load cube textures\r\n */\r\nexport class CubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<CubeTexture> {\r\n    /**\r\n     * Gets the loaded texture\r\n     */\r\n    public texture: CubeTexture;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: CubeTextureAssetTask) => void;\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: CubeTextureAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new CubeTextureAssetTask\r\n     * @param name defines the name of the task\r\n     * @param url defines the location of the files to load (You have to specify the folder where the files are + filename with no extension)\r\n     * @param extensionsOrOptions defines the suffixes add to the picture name in case six images are in use like _px.jpg or set of all options to create the cube texture\r\n     * @param noMipmap defines if mipmaps should not be generated (default is false)\r\n     * @param files defines the explicit list of files (undefined by default)\r\n     * @param prefiltered\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the files to load (You have to specify the folder where the files are + filename with no extension)\r\n         */\r\n        public url: string,\r\n        /**\r\n         * Defines the suffixes add to the picture name in case six images are in use like _px.jpg or set of all options to create the cube texture\r\n         */\r\n        public extensionsOrOptions: Nullable<string[] | ICubeTextureCreationOptions> = null,\r\n        /**\r\n         * Defines if mipmaps should not be generated (default is false)\r\n         */\r\n        public noMipmap?: boolean,\r\n        /**\r\n         * Defines the explicit list of files (undefined by default)\r\n         */\r\n        public files?: string[],\r\n        /**\r\n         * Defines the prefiltered texture option (default is false)\r\n         */\r\n        public prefiltered?: boolean\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        const onload = () => {\r\n            onSuccess();\r\n        };\r\n\r\n        const onerror = (message?: string, exception?: any) => {\r\n            onError(message, exception);\r\n        };\r\n\r\n        this.texture = new CubeTexture(this.url, scene, this.extensionsOrOptions, this.noMipmap, this.files, onload, onerror, undefined, this.prefiltered);\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load HDR cube textures\r\n */\r\nexport class HDRCubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<HDRCubeTexture> {\r\n    /**\r\n     * Gets the loaded texture\r\n     */\r\n    public texture: HDRCubeTexture;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: HDRCubeTextureAssetTask) => void;\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: HDRCubeTextureAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new HDRCubeTextureAssetTask object\r\n     * @param name defines the name of the task\r\n     * @param url defines the location of the file to load\r\n     * @param size defines the desired size (the more it increases the longer the generation will be) If the size is omitted this implies you are using a preprocessed cubemap.\r\n     * @param noMipmap defines if mipmaps should not be generated (default is false)\r\n     * @param generateHarmonics specifies whether you want to extract the polynomial harmonics during the generation process (default is true)\r\n     * @param gammaSpace specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)\r\n     * @param prefilterOnLoad specifies if the texture should be prefiltered on load (default is false)\r\n     * @param supersample specifies if the texture will be generated with super sampling (default is false)\r\n     * @param prefilterIrradianceOnLoad specifies if the irradiance should be prefiltered on load (default is false)\r\n     * @param prefilterUsingCdf specifies if the texture should be prefiltered using CDF (default is false)\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the file to load\r\n         */\r\n        public url: string,\r\n        /**\r\n         * Defines the desired size (the more it increases the longer the generation will be)\r\n         */\r\n        public size: number,\r\n        /**\r\n         * [false] Defines if mipmaps should not be generated (default is false)\r\n         */\r\n        public noMipmap = false,\r\n        /**\r\n         * [true] Specifies whether you want to extract the polynomial harmonics during the generation process (default is true)\r\n         */\r\n        public generateHarmonics = true,\r\n        /**\r\n         * [false] Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)\r\n         */\r\n        public gammaSpace = false,\r\n        /**\r\n         * [false] Specifies if the texture should be prefiltered on load (default is false)\r\n         */\r\n        public prefilterOnLoad = false,\r\n        /**\r\n         * [false] Specifies if the texture will be generated with super sampling (default is false)\r\n         */\r\n        public supersample = false,\r\n        /**\r\n         * [false] Specifies if the irradiance should be prefiltered on load (default is false)\r\n         */\r\n        public prefilterIrradianceOnLoad = false,\r\n        /**\r\n         * [false] Specifies if the texture should be prefiltered using CDF (default is false)\r\n         */\r\n        public prefilterUsingCdf = false\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {\r\n        const onload = () => {\r\n            onSuccess();\r\n        };\r\n\r\n        const onerror = (message?: string, exception?: any) => {\r\n            onError(message, exception);\r\n        };\r\n\r\n        this.texture = new HDRCubeTexture(\r\n            this.url,\r\n            scene,\r\n            this.size,\r\n            this.noMipmap,\r\n            this.generateHarmonics,\r\n            this.gammaSpace,\r\n            this.prefilterOnLoad,\r\n            onload,\r\n            onerror,\r\n            this.supersample,\r\n            this.prefilterIrradianceOnLoad,\r\n            this.prefilterUsingCdf\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Define a task used by AssetsManager to load Equirectangular cube textures\r\n */\r\nexport class EquiRectangularCubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<EquiRectangularCubeTexture> {\r\n    /**\r\n     * Gets the loaded texture\r\n     */\r\n    public texture: EquiRectangularCubeTexture;\r\n\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onSuccess: (task: EquiRectangularCubeTextureAssetTask) => void;\r\n    /**\r\n     * Callback called when the task is successful\r\n     */\r\n    public override onError: (task: EquiRectangularCubeTextureAssetTask, message?: string, exception?: any) => void;\r\n\r\n    /**\r\n     * Creates a new EquiRectangularCubeTextureAssetTask object\r\n     * @param name defines the name of the task\r\n     * @param url defines the location of the file to load\r\n     * @param size defines the desired size (the more it increases the longer the generation will be)\r\n     * If the size is omitted this implies you are using a preprocessed cubemap.\r\n     * @param noMipmap defines if mipmaps should not be generated (default is false)\r\n     * @param gammaSpace specifies if the texture will be used in gamma or linear space\r\n     * @param superSample specifies if the texture will be generated with super sampling (default is false)\r\n     * (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)\r\n     * (default is true)\r\n     */\r\n    constructor(\r\n        /**\r\n         * Defines the name of the task\r\n         */\r\n        public override name: string,\r\n        /**\r\n         * Defines the location of the file to load\r\n         */\r\n        public url: string,\r\n        /**\r\n         * Defines the desired size (the more it increases the longer the generation will be)\r\n         */\r\n        public size: number,\r\n        /**\r\n         * [false] Defines if mipmaps should not be generated (default is false)\r\n         */\r\n        public noMipmap: boolean = false,\r\n        /**\r\n         * [true] Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space,\r\n         * but the standard material would require them in Gamma space) (default is true)\r\n         */\r\n        public gammaSpace: boolean = true,\r\n\r\n        public superSample: boolean = false\r\n    ) {\r\n        super(name);\r\n    }\r\n\r\n    /**\r\n     * Execute the current task\r\n     * @param scene defines the scene where you want your assets to be loaded\r\n     * @param onSuccess is a callback called when the task is successfully executed\r\n     * @param onError is a callback called if an error occurs\r\n     */\r\n    public override runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void): void {\r\n        const onload = () => {\r\n            onSuccess();\r\n        };\r\n\r\n        const onerror = (message?: string, exception?: any) => {\r\n            onError(message, exception);\r\n        };\r\n\r\n        this.texture = new EquiRectangularCubeTexture(this.url, scene, this.size, this.noMipmap, this.gammaSpace, onload, onerror, this.superSample);\r\n    }\r\n}\r\n\r\n/**\r\n * This class can be used to easily import assets into a scene\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/assetManager\r\n */\r\nexport class AssetsManager {\r\n    private _scene: Scene;\r\n    private _isLoading = false;\r\n\r\n    protected _tasks = new Array<AbstractAssetTask>();\r\n    protected _waitingTasksCount = 0;\r\n    protected _totalTasksCount = 0;\r\n\r\n    /**\r\n     * Callback called when all tasks are processed\r\n     */\r\n    public onFinish: (tasks: AbstractAssetTask[]) => void;\r\n\r\n    /**\r\n     * Callback called when a task is successful\r\n     */\r\n    public onTaskSuccess: (task: AbstractAssetTask) => void;\r\n\r\n    /**\r\n     * Callback called when a task had an error\r\n     */\r\n    public onTaskError: (task: AbstractAssetTask) => void;\r\n\r\n    /**\r\n     * Callback called when a task is done (whatever the result is)\r\n     */\r\n    public onProgress: (remainingCount: number, totalCount: number, task: AbstractAssetTask) => void;\r\n\r\n    /**\r\n     * Observable called when all tasks are processed\r\n     */\r\n    public onTaskSuccessObservable = new Observable<AbstractAssetTask>();\r\n\r\n    /**\r\n     * Observable called when a task had an error\r\n     */\r\n    public onTaskErrorObservable = new Observable<AbstractAssetTask>();\r\n\r\n    /**\r\n     * Observable called when all tasks were executed\r\n     */\r\n    public onTasksDoneObservable = new Observable<AbstractAssetTask[]>();\r\n\r\n    /**\r\n     * Observable called when a task is done (whatever the result is)\r\n     */\r\n    public onProgressObservable = new Observable<IAssetsProgressEvent>();\r\n\r\n    /**\r\n     * Gets or sets a boolean defining if the AssetsManager should use the default loading screen\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n     */\r\n    public useDefaultLoadingScreen = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean defining if the AssetsManager should automatically hide the loading screen\r\n     * when all assets have been downloaded.\r\n     * If set to false, you need to manually call in hideLoadingUI() once your scene is ready.\r\n     */\r\n    public autoHideLoadingUI = true;\r\n\r\n    /**\r\n     * Creates a new AssetsManager\r\n     * @param scene defines the scene to work on\r\n     */\r\n    constructor(scene?: Scene) {\r\n        this._scene = scene || <Scene>EngineStore.LastCreatedScene;\r\n    }\r\n\r\n    /**\r\n     * Add a ContainerAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param meshesNames defines the name of meshes to load\r\n     * @param rootUrl defines the root url to use to locate files\r\n     * @param sceneFilename defines the filename of the scene file or the File itself\r\n     * @param extension defines the extension to use to load the file\r\n     * @returns a new ContainerAssetTask object\r\n     */\r\n    public addContainerTask(taskName: string, meshesNames: any, rootUrl: string, sceneFilename: string | File, extension?: string): ContainerAssetTask {\r\n        const task = new ContainerAssetTask(taskName, meshesNames, rootUrl, sceneFilename, extension);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Add a MeshAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param meshesNames defines the name of meshes to load\r\n     * @param rootUrl defines the root url to use to locate files\r\n     * @param sceneFilename defines the filename of the scene file or the File itself\r\n     * @param extension defines the extension to use to load the file\r\n     * @param filename defines the name of the file, if the data is binary\r\n     * @param pluginOptions defines the options to use with the plugin\r\n     * @returns a new MeshAssetTask object\r\n     */\r\n    public addMeshTask(\r\n        taskName: string,\r\n        meshesNames: any,\r\n        rootUrl: string,\r\n        sceneFilename: string | File,\r\n        extension?: string,\r\n        filename?: string,\r\n        pluginOptions?: PluginOptions\r\n    ): MeshAssetTask {\r\n        const task = new MeshAssetTask(taskName, meshesNames, rootUrl, sceneFilename, extension, filename, pluginOptions);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Add a TextFileAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @returns a new TextFileAssetTask object\r\n     */\r\n    public addTextFileTask(taskName: string, url: string): TextFileAssetTask {\r\n        const task = new TextFileAssetTask(taskName, url);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Add a BinaryFileAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @returns a new BinaryFileAssetTask object\r\n     */\r\n    public addBinaryFileTask(taskName: string, url: string): BinaryFileAssetTask {\r\n        const task = new BinaryFileAssetTask(taskName, url);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Add a ImageAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @returns a new ImageAssetTask object\r\n     */\r\n    public addImageTask(taskName: string, url: string): ImageAssetTask {\r\n        const task = new ImageAssetTask(taskName, url);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Add a TextureAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @param noMipmapOrOptions defines if mipmap should not be generated (default is false) or the creation options to use\r\n     * @param invertY defines if you want to invert Y axis of the loaded texture (true by default)\r\n     * @param samplingMode defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default)\r\n     * @returns a new TextureAssetTask object\r\n     */\r\n    public addTextureTask(\r\n        taskName: string,\r\n        url: string,\r\n        noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n        invertY?: boolean,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE\r\n    ): TextureAssetTask {\r\n        const task = new TextureAssetTask(taskName, url, noMipmapOrOptions, invertY, samplingMode);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Add a CubeTextureAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @param extensionsOrOptions defines the extension to use to load the cube map (can be null) or the options to use for the cube texture\r\n     * @param noMipmap defines if the texture must not receive mipmaps (false by default)\r\n     * @param files defines the list of files to load (can be null)\r\n     * @param prefiltered defines the prefiltered texture option (default is false)\r\n     * @returns a new CubeTextureAssetTask object\r\n     */\r\n    public addCubeTextureTask(\r\n        taskName: string,\r\n        url: string,\r\n        extensionsOrOptions?: string[] | ICubeTextureCreationOptions,\r\n        noMipmap?: boolean,\r\n        files?: string[],\r\n        prefiltered?: boolean\r\n    ): CubeTextureAssetTask {\r\n        const task = new CubeTextureAssetTask(taskName, url, extensionsOrOptions, noMipmap, files, prefiltered);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     *\r\n     * Add a HDRCubeTextureAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @param size defines the size you want for the cubemap (can be null)\r\n     * @param noMipmap defines if the texture must not receive mipmaps (false by default)\r\n     * @param generateHarmonics defines if you want to automatically generate (true by default)\r\n     * @param gammaSpace specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)\r\n     * @param prefilterOnLoad specifies if the texture should be prefiltered on load (default is false)\r\n     * @param supersample specifies if the texture will be generated with super sampling (default is false)\r\n     * @param prefilterIrradianceOnLoad specifies if the irradiance should be prefiltered on load (default is false)\r\n     * @param prefilterUsingCdf specifies if the texture should be prefiltered using CDF (default is false)\r\n     * @returns a new HDRCubeTextureAssetTask object\r\n     */\r\n    public addHDRCubeTextureTask(\r\n        taskName: string,\r\n        url: string,\r\n        size: number,\r\n        noMipmap = false,\r\n        generateHarmonics = true,\r\n        gammaSpace = false,\r\n        prefilterOnLoad = false,\r\n        supersample = false,\r\n        prefilterIrradianceOnLoad = false,\r\n        prefilterUsingCdf = false\r\n    ): HDRCubeTextureAssetTask {\r\n        const task = new HDRCubeTextureAssetTask(\r\n            taskName,\r\n            url,\r\n            size,\r\n            noMipmap,\r\n            generateHarmonics,\r\n            gammaSpace,\r\n            prefilterOnLoad,\r\n            supersample,\r\n            prefilterIrradianceOnLoad,\r\n            prefilterUsingCdf\r\n        );\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     *\r\n     * Add a EquiRectangularCubeTextureAssetTask to the list of active tasks\r\n     * @param taskName defines the name of the new task\r\n     * @param url defines the url of the file to load\r\n     * @param size defines the size you want for the cubemap (can be null)\r\n     * @param noMipmap defines if the texture must not receive mipmaps (false by default)\r\n     * @param gammaSpace Specifies if the texture will be used in gamma or linear space\r\n     * @param superSample specifies if the texture will be generated with super sampling (default is false)\r\n     * (the PBR material requires those textures in linear space, but the standard material would require them in Gamma space)\r\n     * @returns a new EquiRectangularCubeTextureAssetTask object\r\n     */\r\n    public addEquiRectangularCubeTextureAssetTask(\r\n        taskName: string,\r\n        url: string,\r\n        size: number,\r\n        noMipmap = false,\r\n        gammaSpace = true,\r\n        superSample = false\r\n    ): EquiRectangularCubeTextureAssetTask {\r\n        const task = new EquiRectangularCubeTextureAssetTask(taskName, url, size, noMipmap, gammaSpace, superSample);\r\n        this._tasks.push(task);\r\n\r\n        return task;\r\n    }\r\n\r\n    /**\r\n     * Remove a task from the assets manager.\r\n     * @param task the task to remove\r\n     */\r\n    public removeTask(task: AbstractAssetTask) {\r\n        const index = this._tasks.indexOf(task);\r\n\r\n        if (index > -1) {\r\n            this._tasks.splice(index, 1);\r\n        }\r\n    }\r\n\r\n    private _decreaseWaitingTasksCount(task: AbstractAssetTask): void {\r\n        this._waitingTasksCount--;\r\n\r\n        try {\r\n            if (this.onProgress) {\r\n                this.onProgress(this._waitingTasksCount, this._totalTasksCount, task);\r\n            }\r\n\r\n            this.onProgressObservable.notifyObservers(new AssetsProgressEvent(this._waitingTasksCount, this._totalTasksCount, task));\r\n        } catch (e) {\r\n            Logger.Error(\"Error running progress callbacks.\");\r\n            Logger.Log(e);\r\n        }\r\n\r\n        if (this._waitingTasksCount === 0) {\r\n            try {\r\n                const currentTasks = this._tasks.slice();\r\n\r\n                if (this.onFinish) {\r\n                    // Calling onFinish with immutable array of tasks\r\n                    this.onFinish(currentTasks);\r\n                }\r\n\r\n                // Let's remove successful tasks\r\n                for (const task of currentTasks) {\r\n                    if (task.taskState === AssetTaskState.DONE) {\r\n                        const index = this._tasks.indexOf(task);\r\n\r\n                        if (index > -1) {\r\n                            this._tasks.splice(index, 1);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                this.onTasksDoneObservable.notifyObservers(this._tasks);\r\n            } catch (e) {\r\n                Logger.Error(\"Error running tasks-done callbacks.\");\r\n                Logger.Log(e);\r\n            }\r\n            this._isLoading = false;\r\n            if (this.autoHideLoadingUI) {\r\n                this._scene.getEngine().hideLoadingUI();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _runTask(task: AbstractAssetTask): void {\r\n        const done = () => {\r\n            try {\r\n                if (this.onTaskSuccess) {\r\n                    this.onTaskSuccess(task);\r\n                }\r\n                this.onTaskSuccessObservable.notifyObservers(task);\r\n                this._decreaseWaitingTasksCount(task);\r\n            } catch (e) {\r\n                error(\"Error executing task success callbacks\", e);\r\n            }\r\n        };\r\n\r\n        const error = (message?: string, exception?: any) => {\r\n            task._setErrorObject(message, exception);\r\n\r\n            if (this.onTaskError) {\r\n                this.onTaskError(task);\r\n            } else if (!task.onError) {\r\n                Logger.Error(this._formatTaskErrorMessage(task));\r\n            }\r\n            this.onTaskErrorObservable.notifyObservers(task);\r\n            this._decreaseWaitingTasksCount(task);\r\n        };\r\n\r\n        task.run(this._scene, done, error);\r\n    }\r\n\r\n    private _formatTaskErrorMessage(task: AbstractAssetTask) {\r\n        let errorMessage = \"Unable to complete task \" + task.name;\r\n\r\n        if (task.errorObject.message) {\r\n            errorMessage += `: ${task.errorObject.message}`;\r\n        }\r\n        if (task.errorObject.exception) {\r\n            errorMessage += `: ${task.errorObject.exception}`;\r\n        }\r\n\r\n        return errorMessage;\r\n    }\r\n\r\n    /**\r\n     * Reset the AssetsManager and remove all tasks\r\n     * @returns the current instance of the AssetsManager\r\n     */\r\n    public reset(): AssetsManager {\r\n        this._isLoading = false;\r\n        this._tasks = new Array<AbstractAssetTask>();\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Start the loading process\r\n     * @returns the current instance of the AssetsManager\r\n     */\r\n    public load(): AssetsManager {\r\n        if (this._isLoading) {\r\n            return this;\r\n        }\r\n        this._isLoading = true;\r\n        this._waitingTasksCount = this._tasks.length;\r\n        this._totalTasksCount = this._tasks.length;\r\n\r\n        if (this._waitingTasksCount === 0) {\r\n            this._isLoading = false;\r\n            if (this.onFinish) {\r\n                this.onFinish(this._tasks);\r\n            }\r\n            this.onTasksDoneObservable.notifyObservers(this._tasks);\r\n            return this;\r\n        }\r\n\r\n        if (this.useDefaultLoadingScreen) {\r\n            this._scene.getEngine().displayLoadingUI();\r\n        }\r\n\r\n        for (let index = 0; index < this._tasks.length; index++) {\r\n            const task = this._tasks[index];\r\n            if (task.taskState === AssetTaskState.INIT) {\r\n                this._runTask(task);\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Start the loading process as an async operation\r\n     * @returns a promise returning the list of failed tasks\r\n     */\r\n    public async loadAsync(): Promise<void> {\r\n        return await new Promise((resolve, reject) => {\r\n            if (this._isLoading) {\r\n                resolve();\r\n                return;\r\n            }\r\n            this.onTasksDoneObservable.addOnce((remainingTasks) => {\r\n                if (remainingTasks && remainingTasks.length) {\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(remainingTasks);\r\n                } else {\r\n                    resolve();\r\n                }\r\n            });\r\n\r\n            this.load();\r\n        });\r\n    }\r\n}\r\n","/**\r\n * Wrapper class for promise with external resolve and reject.\r\n */\r\nexport class Deferred<T> {\r\n    /**\r\n     * The promise associated with this deferred object.\r\n     */\r\n    public readonly promise: Promise<T>;\r\n\r\n    private _resolve: (value: T | PromiseLike<T>) => void;\r\n    private _reject: (reason?: any) => void;\r\n\r\n    /**\r\n     * The resolve method of the promise associated with this deferred object.\r\n     */\r\n    public get resolve() {\r\n        return this._resolve;\r\n    }\r\n\r\n    /**\r\n     * The reject method of the promise associated with this deferred object.\r\n     */\r\n    public get reject() {\r\n        return this._reject;\r\n    }\r\n\r\n    /**\r\n     * Constructor for this deferred object.\r\n     */\r\n    constructor() {\r\n        this.promise = new Promise((resolve: (value: T | PromiseLike<T>) => void, reject) => {\r\n            this._resolve = resolve;\r\n            this._reject = reject;\r\n        });\r\n    }\r\n}\r\n","import { type Mesh } from \"../Meshes/mesh\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Class used to explode meshes (ie. to have a center and move them away from that center to better see the overall organization)\r\n */\r\nexport class MeshExploder {\r\n    private _centerMesh: Mesh;\r\n    private _meshes: Array<Mesh>;\r\n    private _meshesOrigins: Array<Vector3> = [];\r\n    private _toCenterVectors: Array<Vector3> = [];\r\n    private _scaledDirection = new Vector3(1, 1, 1);\r\n    private _newPosition = Vector3.Zero();\r\n    private _centerPosition = Vector3.Zero();\r\n\r\n    /**\r\n     * Explodes meshes from a center mesh.\r\n     * @param meshes The meshes to explode.\r\n     * @param centerMesh The mesh to be center of explosion.\r\n     */\r\n    constructor(meshes: Array<Mesh>, centerMesh?: Mesh) {\r\n        this._meshes = meshes.slice();\r\n\r\n        if (centerMesh) {\r\n            this._centerMesh = centerMesh;\r\n        } else {\r\n            this._setCenterMesh();\r\n        }\r\n        this._centerMesh.computeWorldMatrix(true);\r\n\r\n        const centerMeshIndex = this._meshes.indexOf(this._centerMesh);\r\n        if (centerMeshIndex >= 0) {\r\n            this._meshes.splice(centerMeshIndex, 1);\r\n        }\r\n        this._centerPosition = this._centerMesh.getAbsolutePosition().clone();\r\n        for (let index = 0; index < this._meshes.length; index++) {\r\n            if (this._meshes[index]) {\r\n                const mesh = this._meshes[index];\r\n                this._meshesOrigins[index] = mesh.getAbsolutePosition().clone();\r\n                this._toCenterVectors[index] = Vector3.Zero();\r\n                if (mesh.hasBoundingInfo && this._centerMesh.hasBoundingInfo) {\r\n                    mesh.computeWorldMatrix(true);\r\n                    mesh.getBoundingInfo().boundingBox.centerWorld.subtractToRef(this._centerMesh.getBoundingInfo().boundingBox.centerWorld, this._toCenterVectors[index]);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _setCenterMesh(): void {\r\n        const totalCenters = Vector3.Zero();\r\n        let shortestToCenter = Number.MAX_VALUE;\r\n        for (let index = 0; index < this._meshes.length; index++) {\r\n            if (this._meshes[index]) {\r\n                const mesh = this._meshes[index];\r\n                const boundingInfo = mesh.getBoundingInfo();\r\n                if (boundingInfo) {\r\n                    totalCenters.addInPlace(boundingInfo.boundingBox.centerWorld);\r\n                }\r\n            }\r\n        }\r\n        const averageCenter = totalCenters.scale(1 / this._meshes.length);\r\n        for (let index = 0; index < this._meshes.length; index++) {\r\n            if (this._meshes[index]) {\r\n                const mesh = this._meshes[index];\r\n                const boundingInfo = mesh.getBoundingInfo();\r\n                if (boundingInfo) {\r\n                    const distanceToCenter = boundingInfo.boundingBox.centerWorld.subtract(averageCenter).lengthSquared();\r\n                    if (distanceToCenter < shortestToCenter) {\r\n                        this._centerMesh = mesh;\r\n                        shortestToCenter = distanceToCenter;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get class name\r\n     * @returns \"MeshExploder\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"MeshExploder\";\r\n    }\r\n\r\n    /**\r\n     * \"Exploded meshes\"\r\n     * @returns Array of meshes with the centerMesh at index 0.\r\n     */\r\n    public getMeshes(): Array<Mesh> {\r\n        const meshArray = this._meshes.slice();\r\n        meshArray.unshift(this._centerMesh);\r\n        return meshArray;\r\n    }\r\n\r\n    /**\r\n     * Explodes meshes giving a specific direction\r\n     * @param direction Number to multiply distance of each mesh's origin from center. Use a negative number to implode, or zero to reset.\r\n     */\r\n    public explode(direction: number = 1.0): void {\r\n        for (let index = 0; index < this._meshes.length; index++) {\r\n            if (this._meshes[index] && this._meshesOrigins[index] && this._toCenterVectors[index]) {\r\n                this._toCenterVectors[index].scaleToRef(direction, this._scaledDirection);\r\n                this._meshesOrigins[index].addToRef(this._scaledDirection, this._newPosition);\r\n                this._meshes[index].setAbsolutePosition(this._newPosition);\r\n            }\r\n        }\r\n        this._centerMesh.setAbsolutePosition(this._centerPosition);\r\n    }\r\n}\r\n","import { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type ISceneLoaderProgressEvent, SceneLoader } from \"../Loading/sceneLoader\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { FilesInputStore } from \"./filesInputStore\";\r\nimport { type Nullable } from \"../types\";\r\nimport { SceneLoaderFlags } from \"core/Loading/sceneLoaderFlags\";\r\n\r\n/**\r\n * Class used to help managing file picking and drag-n-drop\r\n */\r\nexport class FilesInput {\r\n    /**\r\n     * List of files ready to be loaded\r\n     */\r\n    public static get FilesToLoad() {\r\n        return FilesInputStore.FilesToLoad;\r\n    }\r\n\r\n    /**\r\n     * Callback called when a file is processed\r\n     * @returns false to abort the process\r\n     */\r\n    public onProcessFileCallback: (file: File, name: string, extension: string, setSceneFileToLoad: (sceneFile: File) => void) => boolean = () => {\r\n        return true;\r\n    };\r\n\r\n    /**\r\n     * Callback called when an accepted file selection does not contain a loadable scene.\r\n     */\r\n    public onProcessFilesErrorCallback: (files: File[]) => void = () => {};\r\n\r\n    /**\r\n     * If a loading UI should be displayed while loading a file\r\n     */\r\n    public displayLoadingUI: boolean = true;\r\n\r\n    /**\r\n     * Function used when loading the scene file\r\n     * @param sceneFile defines the file to load\r\n     * @param onProgress onProgress callback called while loading the file\r\n     * @returns a promise completing when the load is complete\r\n     */\r\n    public loadAsync: (sceneFile: File, onProgress: Nullable<(event: ISceneLoaderProgressEvent) => void>) => Promise<Scene> = async (sceneFile, onProgress) =>\r\n        this.useAppend\r\n            ? await SceneLoader.AppendAsync(\"file:\", sceneFile, this._currentScene, onProgress)\r\n            : await SceneLoader.LoadAsync(\"file:\", sceneFile, this._engine, onProgress);\r\n\r\n    private _engine: AbstractEngine;\r\n    private _currentScene: Nullable<Scene>;\r\n    private _sceneLoadedCallback: Nullable<(sceneFile: File, scene: Scene) => void>;\r\n    private _progressCallback: Nullable<(progress: ISceneLoaderProgressEvent) => void>;\r\n    private _additionalRenderLoopLogicCallback: Nullable<() => void>;\r\n    private _textureLoadingCallback: Nullable<(remaining: number) => void>;\r\n    private _startingProcessingFilesCallback: Nullable<(files?: File[]) => void>;\r\n    private _onReloadCallback: Nullable<(sceneFile: File) => void>;\r\n    private _errorCallback: Nullable<(sceneFile: File, scene: Nullable<Scene>, message: string) => void>;\r\n    private _elementToMonitor: HTMLElement;\r\n\r\n    private _sceneFileToLoad: Nullable<File> = null;\r\n    private _filesToLoad: File[] = [];\r\n    private _fileSelectionGeneration = 0;\r\n    private _reloadGeneration = 0;\r\n    private _isLoading = false;\r\n    private readonly _renderLoop = () => {\r\n        this._renderFunction();\r\n    };\r\n\r\n    /**\r\n     * Creates a new FilesInput\r\n     * @param engine defines the rendering engine\r\n     * @param scene defines the hosting scene\r\n     * @param sceneLoadedCallback callback called when scene (files provided) is loaded\r\n     * @param progressCallback callback called to track progress\r\n     * @param additionalRenderLoopLogicCallback callback called to add user logic to the rendering loop\r\n     * @param textureLoadingCallback callback called when a texture is loading\r\n     * @param startingProcessingFilesCallback callback called when the system is about to process all files\r\n     * @param onReloadCallback callback called when a reload is requested\r\n     * @param errorCallback callback call if an error occurs\r\n     * @param useAppend defines if the file loaded must be appended (true) or have the scene replaced (false, default behavior)\r\n     * @param dontInjectRenderLoop defines if the render loop mustn't be injected into engine (default is false). Used only if useAppend is false.\r\n     */\r\n    constructor(\r\n        engine: AbstractEngine,\r\n        scene: Nullable<Scene>,\r\n        sceneLoadedCallback: Nullable<(sceneFile: File, scene: Scene) => void>,\r\n        progressCallback: Nullable<(progress: ISceneLoaderProgressEvent) => void>,\r\n        additionalRenderLoopLogicCallback: Nullable<() => void>,\r\n        textureLoadingCallback: Nullable<(remaining: number) => void>,\r\n        startingProcessingFilesCallback: Nullable<(files?: File[]) => void>,\r\n        onReloadCallback: Nullable<(sceneFile: File) => void>,\r\n        errorCallback: Nullable<(sceneFile: File, scene: Nullable<Scene>, message: string) => void>,\r\n        public readonly useAppend = false,\r\n        public readonly dontInjectRenderLoop = false\r\n    ) {\r\n        this._engine = engine;\r\n        this._currentScene = scene;\r\n\r\n        this._sceneLoadedCallback = sceneLoadedCallback;\r\n        this._progressCallback = progressCallback;\r\n        this._additionalRenderLoopLogicCallback = additionalRenderLoopLogicCallback;\r\n        this._textureLoadingCallback = textureLoadingCallback;\r\n        this._startingProcessingFilesCallback = startingProcessingFilesCallback;\r\n        this._onReloadCallback = onReloadCallback;\r\n        this._errorCallback = errorCallback;\r\n    }\r\n\r\n    private _dragEnterHandler: (e: any) => void;\r\n    private _dragOverHandler: (e: any) => void;\r\n    private _dropHandler: (e: any) => void;\r\n\r\n    /**\r\n     * Calls this function to listen to drag'n'drop events on a specific DOM element\r\n     * @param elementToMonitor defines the DOM element to track\r\n     */\r\n    // should probably be DragAndDrop\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public monitorElementForDragNDrop(elementToMonitor: HTMLElement): void {\r\n        if (elementToMonitor) {\r\n            this._elementToMonitor = elementToMonitor;\r\n\r\n            this._dragEnterHandler = (e) => {\r\n                this._drag(e);\r\n            };\r\n            this._dragOverHandler = (e) => {\r\n                this._drag(e);\r\n            };\r\n            this._dropHandler = (e) => {\r\n                this._drop(e);\r\n            };\r\n\r\n            this._elementToMonitor.addEventListener(\"dragenter\", this._dragEnterHandler, false);\r\n            this._elementToMonitor.addEventListener(\"dragover\", this._dragOverHandler, false);\r\n            this._elementToMonitor.addEventListener(\"drop\", this._dropHandler, false);\r\n        }\r\n    }\r\n\r\n    /** Gets the current list of files to load */\r\n    public get filesToLoad() {\r\n        return this._filesToLoad;\r\n    }\r\n\r\n    /**\r\n     * Clears the files and scene selection associated with the current load.\r\n     * @param cancelActiveLoad whether an in-progress replacement load should be canceled, restoring FilesInput-managed loading UI and rendering\r\n     */\r\n    public clearFileSelection(cancelActiveLoad = true): void {\r\n        this._fileSelectionGeneration++;\r\n        if (cancelActiveLoad) {\r\n            this._reloadGeneration++;\r\n        }\r\n        this._sceneFileToLoad = null;\r\n        this._filesToLoad = [];\r\n        if (cancelActiveLoad && this._isLoading) {\r\n            this._restoreCurrentScene();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources\r\n     */\r\n    public dispose() {\r\n        if (!this._elementToMonitor) {\r\n            return;\r\n        }\r\n\r\n        this._elementToMonitor.removeEventListener(\"dragenter\", this._dragEnterHandler);\r\n        this._elementToMonitor.removeEventListener(\"dragover\", this._dragOverHandler);\r\n        this._elementToMonitor.removeEventListener(\"drop\", this._dropHandler);\r\n    }\r\n\r\n    private _renderFunction(): void {\r\n        if (this._additionalRenderLoopLogicCallback) {\r\n            this._additionalRenderLoopLogicCallback();\r\n        }\r\n\r\n        if (this._currentScene) {\r\n            if (this._textureLoadingCallback) {\r\n                const remaining = this._currentScene.getWaitingItemsCount();\r\n\r\n                if (remaining > 0) {\r\n                    this._textureLoadingCallback(remaining);\r\n                }\r\n            }\r\n            this._currentScene.render();\r\n        }\r\n    }\r\n\r\n    private _restoreCurrentScene(): void {\r\n        this._isLoading = false;\r\n        if (this.displayLoadingUI) {\r\n            this._engine.hideLoadingUI();\r\n        }\r\n        if (!this.useAppend && !this.dontInjectRenderLoop && this._currentScene) {\r\n            this._engine.runRenderLoop(this._renderLoop);\r\n        }\r\n    }\r\n\r\n    private _drag(e: DragEvent): void {\r\n        e.stopPropagation();\r\n        e.preventDefault();\r\n    }\r\n\r\n    private _drop(eventDrop: DragEvent): void {\r\n        eventDrop.stopPropagation();\r\n        eventDrop.preventDefault();\r\n\r\n        this.loadFiles(eventDrop);\r\n    }\r\n\r\n    private _traverseFolder(folder: any, files: Array<any>, remaining: { count: number }, callback: () => void) {\r\n        const reader = folder.createReader();\r\n        const relativePath = folder.fullPath.replace(/^\\//, \"\").replace(/(.+?)\\/?$/, \"$1/\");\r\n\r\n        const completeEntry = () => {\r\n            if (--remaining.count === 0) {\r\n                callback();\r\n            }\r\n        };\r\n        const readNextBatch = () => {\r\n            reader.readEntries(\r\n                (entries: any[]) => {\r\n                    if (entries.length === 0) {\r\n                        completeEntry();\r\n                        return;\r\n                    }\r\n\r\n                    remaining.count += entries.length;\r\n                    for (const entry of entries) {\r\n                        if (entry.isFile) {\r\n                            entry.file(\r\n                                (file: any) => {\r\n                                    file.correctName = relativePath + file.name;\r\n                                    files.push(file);\r\n                                    completeEntry();\r\n                                },\r\n                                (error: DOMException) => {\r\n                                    Logger.Error(`Unable to read dropped file '${entry.fullPath}': ${error.message}`);\r\n                                    completeEntry();\r\n                                }\r\n                            );\r\n                        } else if (entry.isDirectory) {\r\n                            this._traverseFolder(entry, files, remaining, callback);\r\n                        } else {\r\n                            completeEntry();\r\n                        }\r\n                    }\r\n\r\n                    // DirectoryReader may return large folders in several batches.\r\n                    readNextBatch();\r\n                },\r\n                (error: DOMException) => {\r\n                    Logger.Error(`Unable to read dropped folder '${folder.fullPath}': ${error.message}`);\r\n                    completeEntry();\r\n                }\r\n            );\r\n        };\r\n\r\n        readNextBatch();\r\n    }\r\n\r\n    private _processFiles(files: Array<any>): void {\r\n        for (let i = 0; i < files.length; i++) {\r\n            const name = (files[i].correctName || files[i].webkitRelativePath || files[i].name).replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\").toLowerCase();\r\n            const extension = name.split(\".\").pop();\r\n\r\n            if (!this.onProcessFileCallback(files[i], name, extension, (sceneFile) => (this._sceneFileToLoad = sceneFile))) {\r\n                continue;\r\n            }\r\n\r\n            if (SceneLoader.IsPluginForExtensionAvailable(\".\" + extension)) {\r\n                this._sceneFileToLoad = files[i];\r\n            }\r\n\r\n            FilesInput.FilesToLoad[name] = files[i];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Load files from a drop event\r\n     * @param event defines the drop event to use as source\r\n     */\r\n    public loadFiles(event: any): void {\r\n        const dataTransferItems = event?.dataTransfer?.items;\r\n        let filesToLoad: File[] = [];\r\n\r\n        // Handling data transfer via drag'n'drop\r\n        if (event && event.dataTransfer && event.dataTransfer.files) {\r\n            filesToLoad = Array.from(event.dataTransfer.files);\r\n        }\r\n\r\n        // Handling files from input files\r\n        if (event && event.target && event.target.files) {\r\n            filesToLoad = Array.from(event.target.files);\r\n        }\r\n\r\n        if (filesToLoad.length === 0 && (!dataTransferItems || dataTransferItems.length === 0)) {\r\n            return;\r\n        }\r\n\r\n        const files: File[] = [];\r\n        const folders = [];\r\n        if (dataTransferItems?.length) {\r\n            for (let index = 0; index < dataTransferItems.length; index++) {\r\n                const item = dataTransferItems[index];\r\n                if (item.kind && item.kind !== \"file\") {\r\n                    continue;\r\n                }\r\n                const entry = item.getAsEntry?.() ?? item.webkitGetAsEntry?.();\r\n                if (entry?.isDirectory) {\r\n                    folders.push(entry);\r\n                    continue;\r\n                }\r\n                const file = item.getAsFile?.();\r\n                if (file) {\r\n                    const fileWithPath = file as File & { correctName?: string };\r\n                    fileWithPath.correctName = (entry?.fullPath || file.webkitRelativePath || file.name).replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\r\n                    files.push(file);\r\n                }\r\n            }\r\n        }\r\n        if (files.length === 0 && folders.length === 0) {\r\n            for (let i = 0; i < filesToLoad.length; i++) {\r\n                const fileToLoad = filesToLoad[i] as File & { correctName?: string };\r\n                const relativePath = fileToLoad.correctName || fileToLoad.webkitRelativePath || fileToLoad.name;\r\n                fileToLoad.correctName = relativePath.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\r\n                files.push(fileToLoad);\r\n            }\r\n        }\r\n        if (files.length === 0 && folders.length === 0) {\r\n            return;\r\n        }\r\n\r\n        const fileSelectionGeneration = ++this._fileSelectionGeneration;\r\n        if (!this.useAppend) {\r\n            this._reloadGeneration++;\r\n        }\r\n        this._sceneFileToLoad = null;\r\n\r\n        if (folders.length === 0) {\r\n            this._processLoadedFiles(files, fileSelectionGeneration);\r\n        } else {\r\n            const remaining = { count: folders.length };\r\n            for (const folder of folders) {\r\n                this._traverseFolder(folder, files, remaining, () => {\r\n                    if (remaining.count === 0) {\r\n                        this._processLoadedFiles(files, fileSelectionGeneration);\r\n                    }\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    private _processLoadedFiles(files: File[], fileSelectionGeneration: number): void {\r\n        if (fileSelectionGeneration !== this._fileSelectionGeneration) {\r\n            return;\r\n        }\r\n        if (files.length === 0) {\r\n            this._restoreCurrentScene();\r\n            this.onProcessFilesErrorCallback(files);\r\n            return;\r\n        }\r\n        this._sceneFileToLoad = null;\r\n        this._filesToLoad = files;\r\n        this._startingProcessingFilesCallback?.(files);\r\n        this._processFiles(files);\r\n        if (!this._sceneFileToLoad) {\r\n            this._restoreCurrentScene();\r\n            this.onProcessFilesErrorCallback(files);\r\n        }\r\n        this._processReload();\r\n    }\r\n\r\n    private _processReload() {\r\n        if (this._onReloadCallback && this._sceneFileToLoad) {\r\n            this._onReloadCallback(this._sceneFileToLoad);\r\n        } else {\r\n            this.reload();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reload the current scene from the loaded files\r\n     */\r\n    public reload() {\r\n        // If a scene file has been provided\r\n        if (this._sceneFileToLoad) {\r\n            const sceneFileToLoad = this._sceneFileToLoad;\r\n            const reloadGeneration = ++this._reloadGeneration;\r\n            if (!this.useAppend) {\r\n                this._isLoading = true;\r\n                if (this._currentScene) {\r\n                    if (Logger.errorsCount > 0) {\r\n                        Logger.ClearLogCache();\r\n                    }\r\n                    this._engine.stopRenderLoop();\r\n                }\r\n            }\r\n\r\n            SceneLoaderFlags.ShowLoadingScreen = false;\r\n            if (this.displayLoadingUI) {\r\n                this._engine.displayLoadingUI();\r\n            }\r\n\r\n            this.loadAsync(sceneFileToLoad, this._progressCallback)\r\n                // eslint-disable-next-line github/no-then\r\n                .then((scene) => {\r\n                    if (!this.useAppend && reloadGeneration !== this._reloadGeneration) {\r\n                        scene.dispose();\r\n                        return;\r\n                    }\r\n\r\n                    // if appending do nothing\r\n                    if (!this.useAppend) {\r\n                        if (this._currentScene) {\r\n                            this._currentScene.dispose();\r\n                        }\r\n\r\n                        this._currentScene = scene;\r\n\r\n                        // Wait for textures and shaders to be ready\r\n                        this._currentScene.executeWhenReady(() => {\r\n                            if (reloadGeneration === this._reloadGeneration) {\r\n                                this._restoreCurrentScene();\r\n                            }\r\n                        });\r\n                    } else {\r\n                        if (this.displayLoadingUI) {\r\n                            this._engine.hideLoadingUI();\r\n                        }\r\n                    }\r\n                    if (this._sceneLoadedCallback && this._currentScene) {\r\n                        this._sceneLoadedCallback(sceneFileToLoad, this._currentScene);\r\n                    }\r\n                })\r\n                // eslint-disable-next-line github/no-then\r\n                .catch((error) => {\r\n                    if (!this.useAppend && reloadGeneration !== this._reloadGeneration) {\r\n                        return;\r\n                    }\r\n                    this._isLoading = false;\r\n                    if (this.displayLoadingUI) {\r\n                        this._engine.hideLoadingUI();\r\n                    }\r\n                    if (this._errorCallback) {\r\n                        this._errorCallback(sceneFileToLoad, this._currentScene, error.message);\r\n                    }\r\n                });\r\n        } else {\r\n            if (this._filesToLoad.length === 1) {\r\n                const name = this._filesToLoad[0].name.toLowerCase();\r\n                const extension = name.split(\".\").pop();\r\n                if (extension) {\r\n                    switch (extension.toLowerCase()) {\r\n                        case \"dds\":\r\n                        case \"env\":\r\n                        case \"hdr\": {\r\n                            return; // Ignore error in that case\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            Logger.Error(\"Please provide a valid .babylon file.\");\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Observable } from \"./observable.pure\";\r\nimport { type Observer, type EventState } from \"./observable\";\r\n\r\n/**\r\n * Represent a list of observers registered to multiple Observables object.\r\n */\r\nexport class MultiObserver<T> {\r\n    private _observers: Nullable<Observer<T>[]>;\r\n    private _observables: Nullable<Observable<T>[]>;\r\n\r\n    /**\r\n     * Release associated resources\r\n     */\r\n    public dispose(): void {\r\n        if (this._observers && this._observables) {\r\n            for (let index = 0; index < this._observers.length; index++) {\r\n                this._observables[index].remove(this._observers[index]);\r\n            }\r\n        }\r\n\r\n        this._observers = null;\r\n        this._observables = null;\r\n    }\r\n\r\n    /**\r\n     * Raise a callback when one of the observable will notify\r\n     * @param observables defines a list of observables to watch\r\n     * @param callback defines the callback to call on notification\r\n     * @param mask defines the mask used to filter notifications\r\n     * @param scope defines the current scope used to restore the JS context\r\n     * @returns the new MultiObserver\r\n     */\r\n    public static Watch<T>(observables: Observable<T>[], callback: (eventData: T, eventState: EventState) => void, mask: number = -1, scope: any = null): MultiObserver<T> {\r\n        const result = new MultiObserver<T>();\r\n\r\n        result._observers = new Array<Observer<T>>();\r\n        result._observables = observables;\r\n\r\n        for (const observable of observables) {\r\n            const observer = observable.add(callback, mask, false, scope);\r\n            if (observer) {\r\n                result._observers.push(observer);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for observableExtensions.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterObservableExtensions(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Observable.prototype.notifyObserversWithPromise = async function <T>(eventData: T, mask: number = -1, target?: any, currentTarget?: any, userInfo?: any): Promise<T> {\r\n        // create an empty promise\r\n        let p: Promise<any> = Promise.resolve(eventData);\r\n\r\n        // no observers? return this promise.\r\n        if (!this.observers.length) {\r\n            return await p;\r\n        }\r\n\r\n        const state = this._eventState;\r\n        state.mask = mask;\r\n        state.target = target;\r\n        state.currentTarget = currentTarget;\r\n        state.skipNextObservers = false;\r\n        state.userInfo = userInfo;\r\n\r\n        // execute one callback after another (not using Promise.all, the order is important)\r\n        for (const obs of this.observers) {\r\n            if (state.skipNextObservers) {\r\n                continue;\r\n            }\r\n            if (obs._willBeUnregistered) {\r\n                continue;\r\n            }\r\n            if (obs.mask & mask) {\r\n                if (obs.scope) {\r\n                    // eslint-disable-next-line github/no-then\r\n                    p = p.then((lastReturnedValue) => {\r\n                        state.lastReturnValue = lastReturnedValue;\r\n                        return obs.callback.apply(obs.scope, [eventData, state]);\r\n                    });\r\n                } else {\r\n                    // eslint-disable-next-line github/no-then\r\n                    p = p.then((lastReturnedValue) => {\r\n                        state.lastReturnValue = lastReturnedValue;\r\n                        return obs.callback(eventData, state);\r\n                    });\r\n                }\r\n                if (obs.unregisterOnNextCall) {\r\n                    this._deferUnregister(obs);\r\n                }\r\n            }\r\n        }\r\n\r\n        // return the eventData\r\n        await p;\r\n        return eventData;\r\n    };\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Observer, Observable } from \"./observable\";\r\nimport { _IsSideEffectImplemented } from \"./devTools\";\r\n\r\n/**\r\n * Defines the root class used to create scene optimization to use with SceneOptimizer\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public getDescription(): string {\r\n        return \"\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Creates the SceneOptimization object\r\n     * @param priority defines the priority of this optimization (0 by default which means first in the list)\r\n     */\r\n    constructor(\r\n        /**\r\n         * [0] Defines the priority of this optimization (0 by default which means first in the list)\r\n         */\r\n        public priority: number = 0\r\n    ) {}\r\n}\r\n\r\n/**\r\n * Defines an optimization used to reduce the size of render target textures\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class TextureOptimization extends SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Reducing render target texture size to \" + this.maximumSize;\r\n    }\r\n\r\n    /**\r\n     * Creates the TextureOptimization object\r\n     * @param priority defines the priority of this optimization (0 by default which means first in the list)\r\n     * @param maximumSize defines the maximum sized allowed for textures (1024 is the default value). If a texture is bigger, it will be scaled down using a factor defined by the step parameter\r\n     * @param step defines the factor (0.5 by default) used to scale down textures bigger than maximum sized allowed.\r\n     */\r\n    constructor(\r\n        /**\r\n         * [0] Defines the priority of this optimization (0 by default which means first in the list)\r\n         */\r\n        public override priority: number = 0,\r\n        /**\r\n         * [1024] Defines the maximum sized allowed for textures (1024 is the default value). If a texture is bigger, it will be scaled down using a factor defined by the step parameter\r\n         */\r\n        public maximumSize: number = 1024,\r\n        /**\r\n         * [0.5] Defines the factor (0.5 by default) used to scale down textures bigger than maximum sized allowed.\r\n         */\r\n        public step = 0.5\r\n    ) {\r\n        super(priority);\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        let allDone = true;\r\n        for (let index = 0; index < scene.textures.length; index++) {\r\n            const texture = scene.textures[index];\r\n\r\n            if (!texture.canRescale || (<any>texture).getContext) {\r\n                continue;\r\n            }\r\n\r\n            const currentSize = texture.getSize();\r\n            const maxDimension = Math.max(currentSize.width, currentSize.height);\r\n\r\n            if (maxDimension > this.maximumSize) {\r\n                texture.scale(this.step);\r\n                allDone = false;\r\n            }\r\n        }\r\n\r\n        return allDone;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to increase or decrease the rendering resolution\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class HardwareScalingOptimization extends SceneOptimization {\r\n    private _currentScale = -1;\r\n    private _directionOffset = 1;\r\n\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Setting hardware scaling level to \" + this._currentScale;\r\n    }\r\n\r\n    /**\r\n     * Creates the HardwareScalingOptimization object\r\n     * @param priority defines the priority of this optimization (0 by default which means first in the list)\r\n     * @param maximumScale defines the maximum scale to use (2 by default)\r\n     * @param step defines the step to use between two passes (0.5 by default)\r\n     */\r\n    constructor(\r\n        /**\r\n         * [0] Defines the priority of this optimization (0 by default which means first in the list)\r\n         */\r\n        public override priority: number = 0,\r\n        /**\r\n         * [2] Defines the maximum scale to use (2 by default)\r\n         */\r\n        public maximumScale: number = 2,\r\n        /**\r\n         * [0.25] Defines the step to use between two passes (0.5 by default)\r\n         */\r\n        public step: number = 0.25\r\n    ) {\r\n        super(priority);\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        if (this._currentScale === -1) {\r\n            this._currentScale = scene.getEngine().getHardwareScalingLevel();\r\n            if (this._currentScale > this.maximumScale) {\r\n                this._directionOffset = -1;\r\n            }\r\n        }\r\n\r\n        this._currentScale += this._directionOffset * this.step;\r\n        this._currentScale = Math.min(this.maximumScale, this._currentScale);\r\n\r\n        scene.getEngine().setHardwareScalingLevel(this._currentScale);\r\n\r\n        return this._directionOffset === 1 ? this._currentScale >= this.maximumScale : this._currentScale <= this.maximumScale;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to remove shadows\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class ShadowsOptimization extends SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Turning shadows on/off\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        scene.shadowsEnabled = optimizer.isInImprovementMode;\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to turn post-processes off\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class PostProcessesOptimization extends SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Turning post-processes on/off\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        scene.postProcessesEnabled = optimizer.isInImprovementMode;\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to turn lens flares off\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class LensFlaresOptimization extends SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Turning lens flares on/off\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        scene.lensFlaresEnabled = optimizer.isInImprovementMode;\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization based on user defined callback.\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class CustomOptimization extends SceneOptimization {\r\n    /**\r\n     * Callback called to apply the custom optimization.\r\n     */\r\n    public onApply: (scene: Scene, optimizer: SceneOptimizer) => boolean;\r\n\r\n    /**\r\n     * Callback called to get custom description\r\n     */\r\n    public onGetDescription: () => string;\r\n\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        if (this.onGetDescription) {\r\n            return this.onGetDescription();\r\n        }\r\n\r\n        return \"Running user defined callback\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        if (this.onApply) {\r\n            return this.onApply(scene, optimizer);\r\n        }\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to turn particles off\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class ParticlesOptimization extends SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Turning particles on/off\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        scene.particlesEnabled = optimizer.isInImprovementMode;\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to turn render targets off\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class RenderTargetsOptimization extends SceneOptimization {\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Turning render targets off\";\r\n    }\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer): boolean {\r\n        scene.renderTargetsEnabled = optimizer.isInImprovementMode;\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines an optimization used to merge meshes with compatible materials\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class MergeMeshesOptimization extends SceneOptimization {\r\n    private static _UpdateSelectionTree = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean which defines if optimization octree has to be updated\r\n     */\r\n    public static get UpdateSelectionTree(): boolean {\r\n        return MergeMeshesOptimization._UpdateSelectionTree;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean which defines if optimization octree has to be updated\r\n     */\r\n    public static set UpdateSelectionTree(value: boolean) {\r\n        MergeMeshesOptimization._UpdateSelectionTree = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string describing the action executed by the current optimization\r\n     * @returns description string\r\n     */\r\n    public override getDescription(): string {\r\n        return \"Merging similar meshes together\";\r\n    }\r\n\r\n    private _canBeMerged = (abstractMesh: AbstractMesh): boolean => {\r\n        if (!(abstractMesh instanceof Mesh)) {\r\n            return false;\r\n        }\r\n\r\n        const mesh = abstractMesh;\r\n\r\n        if (mesh.isDisposed()) {\r\n            return false;\r\n        }\r\n\r\n        if (!mesh.isVisible || !mesh.isEnabled()) {\r\n            return false;\r\n        }\r\n\r\n        if (mesh.instances.length > 0) {\r\n            return false;\r\n        }\r\n\r\n        if (mesh.skeleton || mesh.hasLODLevels) {\r\n            return false;\r\n        }\r\n\r\n        if (mesh.getTotalVertices() === 0) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    };\r\n\r\n    /**\r\n     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization\r\n     * @param scene defines the current scene where to apply this optimization\r\n     * @param optimizer defines the current optimizer\r\n     * @param updateSelectionTree defines that the selection octree has to be updated (false by default)\r\n     * @returns true if everything that can be done was applied\r\n     */\r\n    public override apply(scene: Scene, optimizer: SceneOptimizer, updateSelectionTree?: boolean): boolean {\r\n        const globalPool = scene.meshes.slice(0);\r\n        let globalLength = globalPool.length;\r\n\r\n        for (let index = 0; index < globalLength; index++) {\r\n            const currentPool: Mesh[] = [];\r\n            const current = globalPool[index];\r\n\r\n            // Checks\r\n            if (!this._canBeMerged(current)) {\r\n                continue;\r\n            }\r\n\r\n            currentPool.push(<Mesh>current);\r\n\r\n            // Find compatible meshes\r\n            for (let subIndex = index + 1; subIndex < globalLength; subIndex++) {\r\n                const otherMesh = globalPool[subIndex];\r\n\r\n                if (!this._canBeMerged(otherMesh)) {\r\n                    continue;\r\n                }\r\n\r\n                if (otherMesh.material !== current.material) {\r\n                    continue;\r\n                }\r\n\r\n                if (otherMesh.checkCollisions !== current.checkCollisions) {\r\n                    continue;\r\n                }\r\n\r\n                currentPool.push(<Mesh>otherMesh);\r\n                globalLength--;\r\n\r\n                globalPool.splice(subIndex, 1);\r\n\r\n                subIndex--;\r\n            }\r\n\r\n            if (currentPool.length < 2) {\r\n                continue;\r\n            }\r\n\r\n            // Merge meshes\r\n            Mesh.MergeMeshes(currentPool, undefined, true);\r\n        }\r\n\r\n        // Call the octree system optimization if it is defined.\r\n        const sceneAsAny = scene as any;\r\n        if (_IsSideEffectImplemented(sceneAsAny.createOrUpdateSelectionOctree)) {\r\n            if (updateSelectionTree != undefined) {\r\n                if (updateSelectionTree) {\r\n                    sceneAsAny.createOrUpdateSelectionOctree();\r\n                }\r\n            } else if (MergeMeshesOptimization.UpdateSelectionTree) {\r\n                sceneAsAny.createOrUpdateSelectionOctree();\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n}\r\n\r\n/**\r\n * Defines a list of options used by SceneOptimizer\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class SceneOptimizerOptions {\r\n    /**\r\n     * Gets the list of optimizations to apply\r\n     */\r\n    public optimizations: SceneOptimization[] = [];\r\n\r\n    /**\r\n     * Creates a new list of options used by SceneOptimizer\r\n     * @param targetFrameRate defines the target frame rate to reach (60 by default)\r\n     * @param trackerDuration defines the interval between two checks (2000ms by default)\r\n     */\r\n    constructor(\r\n        /**\r\n         * [60] Defines the target frame rate to reach (60 by default)\r\n         */\r\n        public targetFrameRate: number = 60,\r\n        /**\r\n         * [2000] Defines the interval between two checks (2000ms by default)\r\n         */\r\n        public trackerDuration: number = 2000\r\n    ) {}\r\n\r\n    /**\r\n     * Add a new optimization\r\n     * @param optimization defines the SceneOptimization to add to the list of active optimizations\r\n     * @returns the current SceneOptimizerOptions\r\n     */\r\n    public addOptimization(optimization: SceneOptimization): SceneOptimizerOptions {\r\n        this.optimizations.push(optimization);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Add a new custom optimization\r\n     * @param onApply defines the callback called to apply the custom optimization (true if everything that can be done was applied)\r\n     * @param onGetDescription defines the callback called to get the description attached with the optimization.\r\n     * @param priority defines the priority of this optimization (0 by default which means first in the list)\r\n     * @returns the current SceneOptimizerOptions\r\n     */\r\n    public addCustomOptimization(onApply: (scene: Scene, optimizer: SceneOptimizer) => boolean, onGetDescription: () => string, priority: number = 0): SceneOptimizerOptions {\r\n        const optimization = new CustomOptimization(priority);\r\n        optimization.onApply = onApply;\r\n        optimization.onGetDescription = onGetDescription;\r\n\r\n        this.optimizations.push(optimization);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates a list of pre-defined optimizations aimed to reduce the visual impact on the scene\r\n     * @param targetFrameRate defines the target frame rate (60 by default)\r\n     * @returns a SceneOptimizerOptions object\r\n     */\r\n    public static LowDegradationAllowed(targetFrameRate?: number): SceneOptimizerOptions {\r\n        const result = new SceneOptimizerOptions(targetFrameRate);\r\n\r\n        let priority = 0;\r\n        result.addOptimization(new MergeMeshesOptimization(priority));\r\n        result.addOptimization(new ShadowsOptimization(priority));\r\n        result.addOptimization(new LensFlaresOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new PostProcessesOptimization(priority));\r\n        result.addOptimization(new ParticlesOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new TextureOptimization(priority, 1024));\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a list of pre-defined optimizations aimed to have a moderate impact on the scene visual\r\n     * @param targetFrameRate defines the target frame rate (60 by default)\r\n     * @returns a SceneOptimizerOptions object\r\n     */\r\n    public static ModerateDegradationAllowed(targetFrameRate?: number): SceneOptimizerOptions {\r\n        const result = new SceneOptimizerOptions(targetFrameRate);\r\n\r\n        let priority = 0;\r\n        result.addOptimization(new MergeMeshesOptimization(priority));\r\n        result.addOptimization(new ShadowsOptimization(priority));\r\n        result.addOptimization(new LensFlaresOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new PostProcessesOptimization(priority));\r\n        result.addOptimization(new ParticlesOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new TextureOptimization(priority, 512));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new RenderTargetsOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new HardwareScalingOptimization(priority, 2));\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a list of pre-defined optimizations aimed to have a big impact on the scene visual\r\n     * @param targetFrameRate defines the target frame rate (60 by default)\r\n     * @returns a SceneOptimizerOptions object\r\n     */\r\n    public static HighDegradationAllowed(targetFrameRate?: number): SceneOptimizerOptions {\r\n        const result = new SceneOptimizerOptions(targetFrameRate);\r\n\r\n        let priority = 0;\r\n        result.addOptimization(new MergeMeshesOptimization(priority));\r\n        result.addOptimization(new ShadowsOptimization(priority));\r\n        result.addOptimization(new LensFlaresOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new PostProcessesOptimization(priority));\r\n        result.addOptimization(new ParticlesOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new TextureOptimization(priority, 256));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new RenderTargetsOptimization(priority));\r\n\r\n        // Next priority\r\n        priority++;\r\n        result.addOptimization(new HardwareScalingOptimization(priority, 4));\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\n/**\r\n * Class used to run optimizations in order to reach a target frame rate\r\n * @description More details at https://doc.babylonjs.com/features/featuresDeepDive/scene/sceneOptimizer\r\n */\r\nexport class SceneOptimizer implements IDisposable {\r\n    private _isRunning = false;\r\n    private _options: SceneOptimizerOptions;\r\n    private _scene: Scene;\r\n    private _currentPriorityLevel = 0;\r\n    private _targetFrameRate = 60;\r\n    private _trackerDuration = 2000;\r\n    private _currentFrameRate = 0;\r\n    private _sceneDisposeObserver: Nullable<Observer<Scene>>;\r\n    private _improvementMode = false;\r\n\r\n    /**\r\n     * Defines an observable called when the optimizer reaches the target frame rate\r\n     */\r\n    public onSuccessObservable = new Observable<SceneOptimizer>();\r\n    /**\r\n     * Defines an observable called when the optimizer enables an optimization\r\n     */\r\n    public onNewOptimizationAppliedObservable = new Observable<SceneOptimization>();\r\n    /**\r\n     * Defines an observable called when the optimizer is not able to reach the target frame rate\r\n     */\r\n    public onFailureObservable = new Observable<SceneOptimizer>();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the optimizer is in improvement mode\r\n     */\r\n    public get isInImprovementMode(): boolean {\r\n        return this._improvementMode;\r\n    }\r\n\r\n    public set isInImprovementMode(value: boolean) {\r\n        this._improvementMode = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current priority level (0 at start)\r\n     */\r\n    public get currentPriorityLevel(): number {\r\n        return this._currentPriorityLevel;\r\n    }\r\n\r\n    /**\r\n     * Gets the current frame rate checked by the SceneOptimizer\r\n     */\r\n    public get currentFrameRate(): number {\r\n        return this._currentFrameRate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current target frame rate (60 by default)\r\n     */\r\n    public get targetFrameRate(): number {\r\n        return this._targetFrameRate;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current target frame rate (60 by default)\r\n     */\r\n    public set targetFrameRate(value: number) {\r\n        this._targetFrameRate = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current interval between two checks (every 2000ms by default)\r\n     */\r\n    public get trackerDuration(): number {\r\n        return this._trackerDuration;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current interval between two checks (every 2000ms by default)\r\n     */\r\n    public set trackerDuration(value: number) {\r\n        this._trackerDuration = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of active optimizations\r\n     */\r\n    public get optimizations(): SceneOptimization[] {\r\n        return this._options.optimizations;\r\n    }\r\n\r\n    /**\r\n     * Creates a new SceneOptimizer\r\n     * @param scene defines the scene to work on\r\n     * @param options defines the options to use with the SceneOptimizer\r\n     * @param autoGeneratePriorities defines if priorities must be generated and not read from SceneOptimization property (true by default)\r\n     * @param improvementMode defines if the scene optimizer must run the maximum optimization while staying over a target frame instead of trying to reach the target framerate (false by default)\r\n     */\r\n    public constructor(scene: Scene, options?: SceneOptimizerOptions, autoGeneratePriorities = true, improvementMode = false) {\r\n        if (!options) {\r\n            this._options = new SceneOptimizerOptions();\r\n        } else {\r\n            this._options = options;\r\n        }\r\n\r\n        if (this._options.targetFrameRate) {\r\n            this._targetFrameRate = this._options.targetFrameRate;\r\n        }\r\n\r\n        if (this._options.trackerDuration) {\r\n            this._trackerDuration = this._options.trackerDuration;\r\n        }\r\n\r\n        if (autoGeneratePriorities) {\r\n            let priority = 0;\r\n            for (const optim of this._options.optimizations) {\r\n                optim.priority = priority++;\r\n            }\r\n        }\r\n\r\n        this._improvementMode = improvementMode;\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        this._sceneDisposeObserver = this._scene.onDisposeObservable.add(() => {\r\n            this._sceneDisposeObserver = null;\r\n            this.dispose();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Stops the current optimizer\r\n     */\r\n    public stop() {\r\n        this._isRunning = false;\r\n    }\r\n\r\n    /**\r\n     * Reset the optimizer to initial step (current priority level = 0)\r\n     */\r\n    public reset() {\r\n        this._currentPriorityLevel = 0;\r\n    }\r\n\r\n    /**\r\n     * Start the optimizer. By default it will try to reach a specific framerate\r\n     * but if the optimizer is set with improvementMode === true then it will run all optimization while frame rate is above the target frame rate\r\n     */\r\n    public start() {\r\n        if (this._isRunning) {\r\n            return;\r\n        }\r\n\r\n        this._isRunning = true;\r\n\r\n        // Let's wait for the scene to be ready before running our check\r\n        this._scene.executeWhenReady(() => {\r\n            setTimeout(() => {\r\n                this._checkCurrentState();\r\n            }, this._trackerDuration);\r\n        });\r\n    }\r\n\r\n    private _checkCurrentState() {\r\n        if (!this._isRunning) {\r\n            return;\r\n        }\r\n\r\n        const scene = this._scene;\r\n        const options = this._options;\r\n\r\n        this._currentFrameRate = Math.round(scene.getEngine().getFps());\r\n\r\n        if ((this._improvementMode && this._currentFrameRate <= this._targetFrameRate) || (!this._improvementMode && this._currentFrameRate >= this._targetFrameRate)) {\r\n            this._isRunning = false;\r\n            this.onSuccessObservable.notifyObservers(this);\r\n            return;\r\n        }\r\n\r\n        // Apply current level of optimizations\r\n        let allDone = true;\r\n        let noOptimizationApplied = true;\r\n        for (let index = 0; index < options.optimizations.length; index++) {\r\n            const optimization = options.optimizations[index];\r\n\r\n            if (optimization.priority === this._currentPriorityLevel) {\r\n                noOptimizationApplied = false;\r\n                allDone = allDone && optimization.apply(scene, this);\r\n                this.onNewOptimizationAppliedObservable.notifyObservers(optimization);\r\n            }\r\n        }\r\n\r\n        // If no optimization was applied, this is a failure :(\r\n        if (noOptimizationApplied) {\r\n            this._isRunning = false;\r\n            this.onFailureObservable.notifyObservers(this);\r\n\r\n            return;\r\n        }\r\n\r\n        // If all optimizations were done, move to next level\r\n        if (allDone) {\r\n            this._currentPriorityLevel++;\r\n        }\r\n\r\n        // Let's the system running for a specific amount of time before checking FPS\r\n        scene.executeWhenReady(() => {\r\n            setTimeout(() => {\r\n                this._checkCurrentState();\r\n            }, this._trackerDuration);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Release all resources\r\n     */\r\n    public dispose(): void {\r\n        this.stop();\r\n        this.onSuccessObservable.clear();\r\n        this.onFailureObservable.clear();\r\n        this.onNewOptimizationAppliedObservable.clear();\r\n        if (this._sceneDisposeObserver) {\r\n            this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Helper function to create a SceneOptimizer with one single line of code\r\n     * @param scene defines the scene to work on\r\n     * @param options defines the options to use with the SceneOptimizer\r\n     * @param onSuccess defines a callback to call on success\r\n     * @param onFailure defines a callback to call on failure\r\n     * @returns the new SceneOptimizer object\r\n     */\r\n    // This function i s not technically Async\r\n    // eslint-disable-next-line no-restricted-syntax\r\n    public static OptimizeAsync(scene: Scene, options?: SceneOptimizerOptions, onSuccess?: () => void, onFailure?: () => void): SceneOptimizer {\r\n        const optimizer = new SceneOptimizer(scene, options || SceneOptimizerOptions.ModerateDegradationAllowed(), false);\r\n\r\n        if (onSuccess) {\r\n            optimizer.onSuccessObservable.add(() => {\r\n                onSuccess();\r\n            });\r\n        }\r\n\r\n        if (onFailure) {\r\n            optimizer.onFailureObservable.add(() => {\r\n                onFailure();\r\n            });\r\n        }\r\n\r\n        optimizer.start();\r\n\r\n        return optimizer;\r\n    }\r\n}\r\n","import { type Geometry } from \"../Meshes/geometry\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { MultiMaterial } from \"../Materials/multiMaterial.pure\";\r\nimport { type Material } from \"../Materials/material\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type Light } from \"../Lights/light\";\r\nimport { SerializationHelper } from \"./decorators.serialization\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type CubeTexture } from \"../Materials/Textures/cubeTexture\";\r\nimport { type Node } from \"../node\";\r\nimport { type TransformNode } from \"../Meshes/transformNode\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { _IsSideEffectImplemented } from \"./devTools\";\r\n\r\nlet SerializedGeometries: Geometry[] = [];\r\nconst SerializeGeometry = (geometry: Geometry, serializationGeometries: any): any => {\r\n    if (geometry.doNotSerialize) {\r\n        return;\r\n    }\r\n\r\n    serializationGeometries.vertexData.push(geometry.serializeVerticeData());\r\n\r\n    (<any>SerializedGeometries)[geometry.id] = true;\r\n};\r\n\r\nconst SerializeMesh = (mesh: Mesh, serializationScene: any): any => {\r\n    const serializationObject: any = {};\r\n\r\n    // Geometry\r\n    const geometry = mesh._geometry;\r\n    if (geometry) {\r\n        if (!mesh.getScene().getGeometryById(geometry.id)) {\r\n            // Geometry was in the memory but not added to the scene, nevertheless it's better to serialize to be able to reload the mesh with its geometry\r\n            SerializeGeometry(geometry, serializationScene.geometries);\r\n        }\r\n    }\r\n\r\n    // Custom\r\n    if (mesh.serialize) {\r\n        mesh.serialize(serializationObject);\r\n    }\r\n\r\n    return serializationObject;\r\n};\r\n\r\nconst FinalizeSingleNode = (node: Node, serializationObject: any) => {\r\n    if ((node as Mesh)._isMesh) {\r\n        const mesh = node as Mesh;\r\n        //only works if the mesh is already loaded\r\n        if (mesh.delayLoadState === Constants.DELAYLOADSTATE_LOADED || mesh.delayLoadState === Constants.DELAYLOADSTATE_NONE) {\r\n            const serializeMaterial = (material: Material) => {\r\n                serializationObject.materials = serializationObject.materials || [];\r\n                if (mesh.material && !serializationObject.materials.some((mat: Material) => mat.id === (<Material>mesh.material).id)) {\r\n                    serializationObject.materials.push(material.serialize());\r\n                }\r\n            };\r\n\r\n            //serialize material\r\n            if (mesh.material && !mesh.material.doNotSerialize) {\r\n                if (mesh.material instanceof MultiMaterial) {\r\n                    serializationObject.multiMaterials = serializationObject.multiMaterials || [];\r\n                    if (!serializationObject.multiMaterials.some((mat: Material) => mat.id === (<Material>mesh.material).id)) {\r\n                        serializationObject.multiMaterials.push(mesh.material.serialize());\r\n                        for (const submaterial of mesh.material.subMaterials) {\r\n                            if (submaterial) {\r\n                                serializeMaterial(submaterial);\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    serializeMaterial(mesh.material);\r\n                }\r\n            } else if (!mesh.material) {\r\n                serializeMaterial(mesh.getScene().defaultMaterial);\r\n            }\r\n\r\n            //serialize geometry\r\n            const geometry = mesh._geometry;\r\n            if (geometry) {\r\n                if (!serializationObject.geometries) {\r\n                    serializationObject.geometries = {};\r\n\r\n                    serializationObject.geometries.boxes = [];\r\n                    serializationObject.geometries.spheres = [];\r\n                    serializationObject.geometries.cylinders = [];\r\n                    serializationObject.geometries.toruses = [];\r\n                    serializationObject.geometries.grounds = [];\r\n                    serializationObject.geometries.planes = [];\r\n                    serializationObject.geometries.torusKnots = [];\r\n                    serializationObject.geometries.vertexData = [];\r\n                }\r\n\r\n                SerializeGeometry(geometry, serializationObject.geometries);\r\n            }\r\n            // Skeletons\r\n            if (mesh.skeleton && !mesh.skeleton.doNotSerialize) {\r\n                serializationObject.skeletons = serializationObject.skeletons || [];\r\n                serializationObject.skeletons.push(mesh.skeleton.serialize());\r\n            }\r\n\r\n            //serialize the actual mesh\r\n            serializationObject.meshes = serializationObject.meshes || [];\r\n            serializationObject.meshes.push(SerializeMesh(mesh, serializationObject));\r\n        }\r\n    } else if (node.getClassName() === \"TransformNode\") {\r\n        const transformNode = node as TransformNode;\r\n        serializationObject.transformNodes.push(transformNode.serialize());\r\n    } else if (node.getClassName().indexOf(\"Camera\") !== -1) {\r\n        const camera = node as Camera;\r\n        serializationObject.cameras.push(camera.serialize());\r\n    } else if (node.getClassName().indexOf(\"Light\") !== -1) {\r\n        const light = node as Light;\r\n        serializationObject.lights.push(light.serialize());\r\n    }\r\n};\r\n\r\n/**\r\n * Class used to serialize a scene into a string\r\n */\r\nexport class SceneSerializer {\r\n    /**\r\n     * Clear cache used by a previous serialization\r\n     */\r\n    public static ClearCache(): void {\r\n        SerializedGeometries = [];\r\n    }\r\n\r\n    /**\r\n     * Serialize a scene into a JSON compatible object\r\n     * Note that if the current engine does not support synchronous texture reading (like WebGPU), you should use SerializeAsync instead\r\n     * as else you may not retrieve the proper base64 encoded texture data (when using the Texture.ForceSerializeBuffers flag)\r\n     * @param scene defines the scene to serialize\r\n     * @returns a JSON compatible object\r\n     */\r\n    public static Serialize(scene: Scene): any {\r\n        return SceneSerializer._Serialize(scene);\r\n    }\r\n\r\n    private static _Serialize(scene: Scene, checkSyncReadSupported = true): any {\r\n        const serializationObject: any = {};\r\n\r\n        if (checkSyncReadSupported && !scene.getEngine()._features.supportSyncTextureRead && Texture.ForceSerializeBuffers) {\r\n            Logger.Warn(\"The serialization object may not contain the proper base64 encoded texture data! You should use the SerializeAsync method instead.\");\r\n        }\r\n\r\n        SceneSerializer.ClearCache();\r\n\r\n        // Scene\r\n        serializationObject.useDelayedTextureLoading = scene.useDelayedTextureLoading;\r\n        serializationObject.autoClear = scene.autoClear;\r\n        serializationObject.clearColor = scene.clearColor.asArray();\r\n        serializationObject.ambientColor = scene.ambientColor.asArray();\r\n        serializationObject.gravity = scene.gravity.asArray();\r\n        serializationObject.collisionsEnabled = scene.collisionsEnabled;\r\n        serializationObject.useRightHandedSystem = scene.useRightHandedSystem;\r\n\r\n        // Fog\r\n        if (scene.fogMode !== undefined && scene.fogMode !== null) {\r\n            serializationObject.fogMode = scene.fogMode;\r\n        }\r\n        if (scene.fogColor !== undefined && scene.fogColor !== null) {\r\n            serializationObject.fogColor = scene.fogColor.asArray();\r\n        }\r\n        if (scene.fogStart !== undefined && scene.fogStart !== null) {\r\n            serializationObject.fogStart = scene.fogStart;\r\n        }\r\n        if (scene.fogEnd !== undefined && scene.fogEnd !== null) {\r\n            serializationObject.fogEnd = scene.fogEnd;\r\n        }\r\n        if (scene.fogDensity !== undefined && scene.fogDensity !== null) {\r\n            serializationObject.fogDensity = scene.fogDensity;\r\n        }\r\n\r\n        //Physics\r\n        if (_IsSideEffectImplemented(scene.isPhysicsEnabled) && scene.isPhysicsEnabled()) {\r\n            const physicEngine = scene.getPhysicsEngine();\r\n\r\n            if (physicEngine) {\r\n                serializationObject.physicsEnabled = true;\r\n                serializationObject.physicsGravity = physicEngine.gravity.asArray();\r\n                serializationObject.physicsEngine = physicEngine.getPhysicsPluginName();\r\n            }\r\n        }\r\n\r\n        // Metadata\r\n        if (scene.metadata) {\r\n            serializationObject.metadata = scene.metadata;\r\n        }\r\n\r\n        // Morph targets\r\n        serializationObject.morphTargetManagers = [];\r\n        for (const abstractMesh of scene.meshes) {\r\n            const manager = (<Mesh>abstractMesh).morphTargetManager;\r\n\r\n            if (manager) {\r\n                serializationObject.morphTargetManagers.push(manager.serialize());\r\n            }\r\n        }\r\n\r\n        // Lights\r\n        serializationObject.lights = [];\r\n        let index: number;\r\n        let light: Light;\r\n        for (index = 0; index < scene.lights.length; index++) {\r\n            light = scene.lights[index];\r\n\r\n            if (!light.doNotSerialize) {\r\n                serializationObject.lights.push(light.serialize());\r\n            }\r\n        }\r\n\r\n        // Cameras\r\n        serializationObject.cameras = [];\r\n        for (index = 0; index < scene.cameras.length; index++) {\r\n            const camera = scene.cameras[index];\r\n\r\n            if (!camera.doNotSerialize) {\r\n                serializationObject.cameras.push(camera.serialize());\r\n            }\r\n        }\r\n\r\n        if (scene.activeCamera) {\r\n            serializationObject.activeCameraID = scene.activeCamera.id;\r\n        }\r\n\r\n        // Animations\r\n        SerializationHelper.AppendSerializedAnimations(scene, serializationObject);\r\n\r\n        // Animation Groups\r\n        if (scene.animationGroups && scene.animationGroups.length > 0) {\r\n            serializationObject.animationGroups = [];\r\n            for (let animationGroupIndex = 0; animationGroupIndex < scene.animationGroups.length; animationGroupIndex++) {\r\n                const animationGroup = scene.animationGroups[animationGroupIndex];\r\n\r\n                serializationObject.animationGroups.push(animationGroup.serialize());\r\n            }\r\n        }\r\n\r\n        // Reflection probes\r\n        if (scene.reflectionProbes && scene.reflectionProbes.length > 0) {\r\n            serializationObject.reflectionProbes = [];\r\n\r\n            for (index = 0; index < scene.reflectionProbes.length; index++) {\r\n                const reflectionProbe = scene.reflectionProbes[index];\r\n                serializationObject.reflectionProbes.push(reflectionProbe.serialize());\r\n            }\r\n        }\r\n\r\n        // Materials\r\n        serializationObject.materials = [];\r\n        serializationObject.multiMaterials = [];\r\n        let material: Material;\r\n        for (index = 0; index < scene.materials.length; index++) {\r\n            material = scene.materials[index];\r\n            if (!material.doNotSerialize) {\r\n                serializationObject.materials.push(material.serialize());\r\n            }\r\n        }\r\n\r\n        // MultiMaterials\r\n        serializationObject.multiMaterials = [];\r\n        for (index = 0; index < scene.multiMaterials.length; index++) {\r\n            const multiMaterial = scene.multiMaterials[index];\r\n            serializationObject.multiMaterials.push(multiMaterial.serialize());\r\n        }\r\n\r\n        // Environment texture\r\n        if (scene.environmentTexture) {\r\n            if ((scene.environmentTexture as CubeTexture)._files) {\r\n                serializationObject.environmentTexture = scene.environmentTexture.serialize();\r\n            } else {\r\n                serializationObject.environmentTexture = scene.environmentTexture.name;\r\n                serializationObject.environmentTextureRotationY = (scene.environmentTexture as CubeTexture).rotationY;\r\n            }\r\n        }\r\n\r\n        // Environment Intensity\r\n        serializationObject.environmentIntensity = scene.environmentIntensity;\r\n\r\n        // IBL Intensity\r\n        serializationObject.iblIntensity = scene.iblIntensity;\r\n\r\n        // Skeletons\r\n        serializationObject.skeletons = [];\r\n        for (index = 0; index < scene.skeletons.length; index++) {\r\n            const skeleton = scene.skeletons[index];\r\n            if (!skeleton.doNotSerialize) {\r\n                serializationObject.skeletons.push(skeleton.serialize());\r\n            }\r\n        }\r\n\r\n        // Transform nodes\r\n        serializationObject.transformNodes = [];\r\n        for (index = 0; index < scene.transformNodes.length; index++) {\r\n            if (!scene.transformNodes[index].doNotSerialize) {\r\n                serializationObject.transformNodes.push(scene.transformNodes[index].serialize());\r\n            }\r\n        }\r\n\r\n        // Geometries\r\n        serializationObject.geometries = {};\r\n\r\n        serializationObject.geometries.boxes = [];\r\n        serializationObject.geometries.spheres = [];\r\n        serializationObject.geometries.cylinders = [];\r\n        serializationObject.geometries.toruses = [];\r\n        serializationObject.geometries.grounds = [];\r\n        serializationObject.geometries.planes = [];\r\n        serializationObject.geometries.torusKnots = [];\r\n        serializationObject.geometries.vertexData = [];\r\n\r\n        SerializedGeometries = [];\r\n        const geometries = scene.getGeometries();\r\n        for (index = 0; index < geometries.length; index++) {\r\n            const geometry = geometries[index];\r\n\r\n            if (geometry.isReady()) {\r\n                SerializeGeometry(geometry, serializationObject.geometries);\r\n            }\r\n        }\r\n\r\n        // Meshes\r\n        serializationObject.meshes = [];\r\n        for (index = 0; index < scene.meshes.length; index++) {\r\n            const abstractMesh = scene.meshes[index];\r\n\r\n            // GaussianSplattingPartProxyMesh would be serialized with the GaussianSplattingMesh holding it\r\n            if (abstractMesh instanceof Mesh && abstractMesh.getClassName() !== \"GaussianSplattingPartProxyMesh\") {\r\n                const mesh = abstractMesh;\r\n                if (!mesh.doNotSerialize) {\r\n                    if (mesh.delayLoadState === Constants.DELAYLOADSTATE_LOADED || mesh.delayLoadState === Constants.DELAYLOADSTATE_NONE) {\r\n                        serializationObject.meshes.push(SerializeMesh(mesh, serializationObject));\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Particles Systems\r\n        serializationObject.particleSystems = [];\r\n        for (index = 0; index < scene.particleSystems.length; index++) {\r\n            const particleSystem = scene.particleSystems[index];\r\n            if (!particleSystem.doNotSerialize) {\r\n                serializationObject.particleSystems.push(particleSystem.serialize(false));\r\n            }\r\n        }\r\n\r\n        // Post processes\r\n        serializationObject.postProcesses = [];\r\n        for (index = 0; index < scene.postProcesses.length; index++) {\r\n            const postProcess = scene.postProcesses[index];\r\n            if (!postProcess.doNotSerialize) {\r\n                serializationObject.postProcesses.push(postProcess.serialize());\r\n            }\r\n        }\r\n\r\n        // Action Manager\r\n        if (scene.actionManager) {\r\n            serializationObject.actions = scene.actionManager.serialize(\"scene\");\r\n        }\r\n\r\n        // Components\r\n        for (const component of scene._serializableComponents) {\r\n            component.serialize(serializationObject);\r\n        }\r\n\r\n        // Sprites\r\n        if (scene.spriteManagers) {\r\n            serializationObject.spriteManagers = [];\r\n            for (index = 0; index < scene.spriteManagers.length; index++) {\r\n                const spriteManager = scene.spriteManagers[index];\r\n                if (!spriteManager.doNotSerialize) {\r\n                    serializationObject.spriteManagers.push(spriteManager.serialize(true));\r\n                }\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Serialize a scene into a JSON compatible object\r\n     * @param scene defines the scene to serialize\r\n     * @returns a JSON promise compatible object\r\n     */\r\n    public static async SerializeAsync(scene: Scene): Promise<any> {\r\n        const serializationObject = SceneSerializer._Serialize(scene, false);\r\n\r\n        const promises: Array<Promise<any>> = [];\r\n\r\n        this._CollectPromises(serializationObject, promises);\r\n\r\n        await Promise.all(promises);\r\n        return serializationObject;\r\n    }\r\n\r\n    private static _CollectPromises(obj: any, promises: Array<Promise<any>>): void {\r\n        if (Array.isArray(obj)) {\r\n            for (let i = 0; i < obj.length; ++i) {\r\n                const o = obj[i];\r\n                if (o instanceof Promise) {\r\n                    // eslint-disable-next-line @typescript-eslint/no-unsafe-return, github/no-then\r\n                    promises.push(o.then((res: any) => (obj[i] = res)));\r\n                } else if (o instanceof Object || Array.isArray(o)) {\r\n                    this._CollectPromises(o, promises);\r\n                }\r\n            }\r\n        } else if (obj instanceof Object) {\r\n            for (const name in obj) {\r\n                if (Object.prototype.hasOwnProperty.call(obj, name)) {\r\n                    const o = obj[name];\r\n                    if (o instanceof Promise) {\r\n                        // eslint-disable-next-line @typescript-eslint/no-unsafe-return, github/no-then\r\n                        promises.push(o.then((res: any) => (obj[name] = res)));\r\n                    } else if (o instanceof Object || Array.isArray(o)) {\r\n                        this._CollectPromises(o, promises);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serialize a mesh into a JSON compatible object\r\n     * @param toSerialize defines the mesh to serialize\r\n     * @param withParents defines if parents must be serialized as well\r\n     * @param withChildren defines if children must be serialized as well\r\n     * @returns a JSON compatible object\r\n     */\r\n    public static SerializeMesh(toSerialize: any /* Mesh || Mesh[] */, withParents: boolean = false, withChildren: boolean = false): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.meshes = [];\r\n        serializationObject.transformNodes = [];\r\n        serializationObject.cameras = [];\r\n        serializationObject.lights = [];\r\n\r\n        SceneSerializer.ClearCache();\r\n\r\n        toSerialize = toSerialize instanceof Array ? toSerialize : [toSerialize];\r\n\r\n        if (withParents || withChildren) {\r\n            //deliberate for loop! not for each, appended should be processed as well.\r\n            for (let i = 0; i < toSerialize.length; ++i) {\r\n                if (withChildren) {\r\n                    const descendants = toSerialize[i].getDescendants();\r\n                    for (const node of descendants) {\r\n                        if (toSerialize.indexOf(node) < 0 && !node.doNotSerialize) {\r\n                            toSerialize.push(node);\r\n                        }\r\n                    }\r\n                }\r\n                //make sure the array doesn't contain the object already\r\n                if (withParents && toSerialize[i].parent && toSerialize.indexOf(toSerialize[i].parent) < 0 && !toSerialize[i].parent.doNotSerialize) {\r\n                    toSerialize.push(toSerialize[i].parent);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const mesh of toSerialize) {\r\n            FinalizeSingleNode(mesh, serializationObject);\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lodCubePixelShader\";\nconst shader = `precision highp float;const float GammaEncodePowerApprox=1.0/2.2;varying vec2 vUV;uniform samplerCube textureSampler;uniform float lod;uniform int gamma;void main(void)\n{vec2 uv=vUV*2.0-1.0;\n#ifdef POSITIVEX\ngl_FragColor=textureCube(textureSampler,vec3(1.001,uv.y,uv.x),lod);\n#endif\n#ifdef NEGATIVEX\ngl_FragColor=textureCube(textureSampler,vec3(-1.001,uv.y,uv.x),lod);\n#endif\n#ifdef POSITIVEY\ngl_FragColor=textureCube(textureSampler,vec3(uv.y,1.001,uv.x),lod);\n#endif\n#ifdef NEGATIVEY\ngl_FragColor=textureCube(textureSampler,vec3(uv.y,-1.001,uv.x),lod);\n#endif\n#ifdef POSITIVEZ\ngl_FragColor=textureCube(textureSampler,vec3(uv,1.001),lod);\n#endif\n#ifdef NEGATIVEZ\ngl_FragColor=textureCube(textureSampler,vec3(uv,-1.001),lod);\n#endif\nif (gamma==0) {gl_FragColor.rgb=pow(gl_FragColor.rgb,vec3(GammaEncodePowerApprox));}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lodCubePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lodPixelShader\";\nconst shader = `precision highp float;const float GammaEncodePowerApprox=1.0/2.2;varying vec2 vUV;uniform sampler2D textureSampler;uniform float lod;uniform vec2 texSize;uniform int gamma;void main(void)\n{ivec2 textureDimensions=textureSize(textureSampler,0);gl_FragColor=texelFetch(textureSampler,ivec2(vUV*vec2(textureDimensions)),int(lod));if (gamma==0) {gl_FragColor.rgb=pow(gl_FragColor.rgb,vec3(GammaEncodePowerApprox));}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lodPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lodCubePixelShader\";\nconst shader = `const GammaEncodePowerApprox=1.0/2.2;varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_cube<f32>;uniform lod: f32;uniform gamma: i32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let uv=fragmentInputs.vUV*2.0-1.0;\n#ifdef POSITIVEX\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,vec3f(1.001,uv.y,uv.x),uniforms.lod);\n#endif\n#ifdef NEGATIVEX\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,vec3f(-1.001,uv.y,uv.x),uniforms.lod);\n#endif\n#ifdef POSITIVEY\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,vec3f(uv.y,1.001,uv.x),uniforms.lod);\n#endif\n#ifdef NEGATIVEY\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,vec3f(uv.y,-1.001,uv.x),uniforms.lod);\n#endif\n#ifdef POSITIVEZ\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,vec3f(uv,1.001),uniforms.lod);\n#endif\n#ifdef NEGATIVEZ\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,vec3f(uv,-1.001),uniforms.lod);\n#endif\nif (uniforms.gamma==0) {fragmentOutputs.color=vec4f(pow(fragmentOutputs.color.rgb,vec3f(GammaEncodePowerApprox)),fragmentOutputs.color.a);}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lodCubePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lodPixelShader\";\nconst shader = `const GammaEncodePowerApprox=1.0/2.2;varying vUV: vec2f;var textureSampler: texture_2d<f32>;uniform lod: f32;uniform gamma: i32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let textureSize=textureDimensions(textureSampler);fragmentOutputs.color=textureLoad(textureSampler,vec2u(fragmentInputs.vUV*vec2f(textureSize)),u32(uniforms.lod));if (uniforms.gamma==0) {fragmentOutputs.color=vec4f(pow(fragmentOutputs.color.rgb,vec3f(GammaEncodePowerApprox)),fragmentOutputs.color.a);}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lodPixelShaderWGSL = { name, shader };\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable no-var */\r\nimport { type Nullable } from \"../types\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\ninterface MediaRecorder {\r\n    /** Starts recording */\r\n    start(timeSlice: number): void;\r\n    /** Stops recording */\r\n    stop(): void;\r\n\r\n    /** Event raised when an error arised. */\r\n    onerror: (event: ErrorEvent) => void;\r\n    /** Event raised when the recording stops. */\r\n    onstop: (event: Event) => void;\r\n    /** Event raised when a new chunk of data is available and should be tracked. */\r\n    ondataavailable: (event: Event) => void;\r\n}\r\n\r\ninterface MediaRecorderOptions {\r\n    /** The mime type you want to use as the recording container for the new MediaRecorder. */\r\n    mimeType?: string;\r\n    /** The chosen bitrate for the audio component of the media. */\r\n    audioBitsPerSecond?: number;\r\n    /** The chosen bitrate for the video component of the media. */\r\n    videoBitsPerSecond?: number;\r\n    /** The chosen bitrate for the audio and video components of the media. This can be specified instead of the above two properties.\r\n     * If this is specified along with one or the other of the above properties, this will be used for the one that isn't specified. */\r\n    bitsPerSecond?: number;\r\n}\r\n\r\ninterface MediaRecorderConstructor {\r\n    /**\r\n     * A reference to the prototype.\r\n     */\r\n    readonly prototype: MediaRecorder;\r\n\r\n    /**\r\n     * Creates a new MediaRecorder.\r\n     * @param stream Defines the stream to record.\r\n     * @param options Defines the options for the recorder available in the type MediaRecorderOptions.\r\n     */\r\n    new (stream: MediaStream, options?: MediaRecorderOptions): MediaRecorder;\r\n}\r\n\r\n/**\r\n * MediaRecorder object available in some browsers.\r\n */\r\ndeclare var MediaRecorder: MediaRecorderConstructor;\r\n\r\n/**\r\n * This represents the different options available for the video capture.\r\n */\r\nexport interface VideoRecorderOptions {\r\n    /** The canvas you want to record */\r\n    canvas?: HTMLCanvasElement;\r\n    /** Defines the mime type of the video. */\r\n    mimeType: string;\r\n    /** Defines the FPS the video should be recorded at. */\r\n    fps: number;\r\n    /** Defines the chunk size for the recording data. */\r\n    recordChunckSize: number;\r\n    /** The audio tracks to attach to the recording. */\r\n    audioTracks?: MediaStreamTrack[];\r\n}\r\n\r\n/**\r\n * This can help with recording videos from BabylonJS.\r\n * This is based on the available WebRTC functionalities of the browser.\r\n *\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToVideo\r\n */\r\nexport class VideoRecorder {\r\n    private static readonly _DefaultOptions = {\r\n        mimeType: \"video/webm\",\r\n        fps: 25,\r\n        recordChunckSize: 3000,\r\n    };\r\n\r\n    /**\r\n     * Returns whether or not the VideoRecorder is available in your browser.\r\n     * @param engine Defines the Babylon Engine.\r\n     * @param canvas Defines the canvas to record. If not provided, the engine canvas will be used.\r\n     * @returns true if supported otherwise false.\r\n     */\r\n    public static IsSupported(engine: AbstractEngine, canvas?: HTMLCanvasElement): boolean {\r\n        const targetCanvas = canvas ?? engine.getRenderingCanvas();\r\n        return !!targetCanvas && typeof (<any>targetCanvas).captureStream === \"function\";\r\n    }\r\n\r\n    private readonly _options: VideoRecorderOptions;\r\n    private _canvas: Nullable<HTMLCanvasElement>;\r\n    private _mediaRecorder: Nullable<MediaRecorder>;\r\n\r\n    private _recordedChunks: any[];\r\n    private _fileName: Nullable<string>;\r\n    private _resolve: Nullable<(blob: Blob) => void>;\r\n    private _reject: Nullable<(error: any) => void>;\r\n\r\n    private _isRecording: boolean;\r\n\r\n    /**\r\n     * True when a recording is already in progress.\r\n     */\r\n    public get isRecording(): boolean {\r\n        return !!this._canvas && this._isRecording;\r\n    }\r\n\r\n    /**\r\n     * Create a new VideoCapture object which can help converting what you see in Babylon to a video file.\r\n     * @param engine Defines the BabylonJS Engine you wish to record.\r\n     * @param options Defines options that can be used to customize the capture.\r\n     */\r\n    constructor(engine: AbstractEngine, options: Partial<VideoRecorderOptions> = {}) {\r\n        if (!VideoRecorder.IsSupported(engine, options.canvas)) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Your browser does not support recording so far.\";\r\n        }\r\n\r\n        const canvas = options.canvas ?? engine.getRenderingCanvas();\r\n        if (!canvas) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"The babylon engine must have a canvas to be recorded\";\r\n        }\r\n\r\n        this._canvas = canvas;\r\n        this._isRecording = false;\r\n\r\n        this._options = {\r\n            ...VideoRecorder._DefaultOptions,\r\n            ...options,\r\n        };\r\n\r\n        const stream = this._canvas.captureStream(this._options.fps);\r\n        if (this._options.audioTracks) {\r\n            for (const track of this._options.audioTracks) {\r\n                stream.addTrack(track);\r\n            }\r\n        }\r\n\r\n        this._mediaRecorder = new MediaRecorder(stream, { mimeType: this._options.mimeType });\r\n        this._mediaRecorder.ondataavailable = (evt: Event) => this._handleDataAvailable(evt);\r\n        this._mediaRecorder.onerror = (evt: ErrorEvent) => this._handleError(evt);\r\n        this._mediaRecorder.onstop = () => this._handleStop();\r\n    }\r\n\r\n    /**\r\n     * Stops the current recording before the default capture timeout passed in the startRecording function.\r\n     */\r\n    public stopRecording(): void {\r\n        if (!this._canvas || !this._mediaRecorder) {\r\n            return;\r\n        }\r\n\r\n        if (!this.isRecording) {\r\n            return;\r\n        }\r\n\r\n        this._isRecording = false;\r\n        this._mediaRecorder.stop();\r\n    }\r\n\r\n    /**\r\n     * Starts recording the canvas for a max duration specified in parameters.\r\n     * @param fileName Defines the name of the file to be downloaded when the recording stop.\r\n     * If null no automatic download will start and you can rely on the promise to get the data back.\r\n     * @param maxDuration Defines the maximum recording time in seconds.\r\n     * It defaults to 7 seconds. A value of zero will not stop automatically, you would need to call stopRecording manually.\r\n     * @returns A promise callback at the end of the recording with the video data in Blob.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    public startRecording(fileName: Nullable<string> = \"babylonjs.webm\", maxDuration = 7): Promise<Blob> {\r\n        if (!this._canvas || !this._mediaRecorder) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Recorder has already been disposed\";\r\n        }\r\n\r\n        if (this.isRecording) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Recording already in progress\";\r\n        }\r\n\r\n        if (maxDuration > 0) {\r\n            setTimeout(() => {\r\n                this.stopRecording();\r\n            }, maxDuration * 1000);\r\n        }\r\n\r\n        this._fileName = fileName;\r\n        this._recordedChunks = [];\r\n        this._resolve = null;\r\n        this._reject = null;\r\n\r\n        this._isRecording = true;\r\n        this._mediaRecorder.start(this._options.recordChunckSize);\r\n\r\n        return new Promise<Blob>((resolve, reject) => {\r\n            this._resolve = resolve;\r\n            this._reject = reject;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Releases internal resources used during the recording.\r\n     */\r\n    public dispose() {\r\n        this._canvas = null;\r\n        this._mediaRecorder = null;\r\n\r\n        this._recordedChunks = [];\r\n        this._fileName = null;\r\n        this._resolve = null;\r\n        this._reject = null;\r\n    }\r\n\r\n    private _handleDataAvailable(event: any): void {\r\n        if (event.data.size > 0) {\r\n            this._recordedChunks.push(event.data);\r\n        }\r\n    }\r\n\r\n    private _handleError(event: ErrorEvent): void {\r\n        this.stopRecording();\r\n\r\n        if (this._reject) {\r\n            this._reject(event.error);\r\n        } else {\r\n            throw new event.error();\r\n        }\r\n    }\r\n\r\n    private _handleStop(): void {\r\n        this.stopRecording();\r\n\r\n        const superBuffer = new Blob(this._recordedChunks);\r\n        if (this._resolve) {\r\n            this._resolve(superBuffer);\r\n        }\r\n\r\n        window.URL.createObjectURL(superBuffer);\r\n\r\n        if (this._fileName) {\r\n            Tools.Download(superBuffer, this._fileName);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { ThinFXAAPostProcess } from \"./thinFXAAPostProcess\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n/**\r\n * Fxaa post process\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#fxaa\r\n */\r\nexport class FxaaPostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"FxaaPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FxaaPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinFXAAPostProcess;\r\n\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinFXAAPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode: samplingMode || Texture.BILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinFXAAPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinFXAAPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.onApplyObservable.add((_effect: Effect) => {\r\n            this._effectWrapper.texelSize = this.texelSize;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new FxaaPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fxaaPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFxaaPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FxaaPostProcess\", FxaaPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { FxaaPostProcess } from \"../PostProcesses/fxaaPostProcess.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"./logger\";\r\nimport { Tools } from \"./tools.pure\";\r\nimport { type IScreenshotSize } from \"./interfaces/screenshotSize\";\r\nimport { DumpData } from \"./dumpTools.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { ApplyPostProcess } from \"./textureTools\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { _RetryWithInterval } from \"./timingTools\";\r\nimport { type FrameGraph } from \"../FrameGraph/frameGraph\";\r\nimport { backbufferColorTextureHandle } from \"../FrameGraph/frameGraphTypes\";\r\nimport { FrameGraphFXAATask } from \"../FrameGraph/Tasks/PostProcesses/fxaaTask\";\r\nimport { FrameGraphPassTask } from \"../FrameGraph/Tasks/PostProcesses/passTask\";\r\nimport { FrameGraphUtils } from \"../FrameGraph/frameGraphUtils\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\nlet screenshotCanvas: Nullable<HTMLCanvasElement> = null;\r\n\r\n/**\r\n * Captures a screenshot of the current rendering\r\n * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n * @param engine defines the rendering engine\r\n * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored\r\n * @param size This parameter can be set to a single number or to an object with the\r\n * following (optional) properties: precision, width, height. If a single number is passed,\r\n * it will be used for both width and height. If an object is passed, the screenshot size\r\n * will be derived from the parameters. The precision property is a multiplier allowing\r\n * rendering at a higher or lower resolution\r\n * @param successCallback defines the callback receives a single parameter which contains the\r\n * screenshot as a string of base64-encoded characters. This string can be assigned to the\r\n * src parameter of an <img> to display it\r\n * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n * Check your browser for supported MIME types\r\n * @param forceDownload force the system to download the image even if a successCallback is provided\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.\r\n * @param clearWithSceneColor If true, the screenshot canvas will be cleared with the scene clear color before copying the render.\r\n */\r\nexport function CreateScreenshot(\r\n    engine: AbstractEngine,\r\n    camera: Camera,\r\n    size: IScreenshotSize | number,\r\n    successCallback?: (data: string) => void,\r\n    mimeType = \"image/png\",\r\n    forceDownload = false,\r\n    quality?: number,\r\n    useFill = false,\r\n    clearWithSceneColor = false\r\n): void {\r\n    const { height, width } = GetScreenshotSize(engine, camera, size);\r\n\r\n    if (!(height && width)) {\r\n        Logger.Error(\"Invalid 'size' parameter !\");\r\n        return;\r\n    }\r\n\r\n    const scene = camera.getScene();\r\n\r\n    let useRenderTarget = scene.activeCamera !== camera;\r\n    if (scene.frameGraph) {\r\n        const mainObjectRendererTask = FrameGraphUtils.FindMainObjectRenderer(scene.frameGraph);\r\n        if (mainObjectRendererTask) {\r\n            useRenderTarget = mainObjectRendererTask.camera !== camera;\r\n        }\r\n    }\r\n\r\n    if (useRenderTarget) {\r\n        CreateScreenshotUsingRenderTarget(\r\n            engine,\r\n            camera,\r\n            size,\r\n            (data) => {\r\n                if (forceDownload) {\r\n                    const blob = new Blob([data]);\r\n                    Tools.DownloadBlob(blob);\r\n                    if (successCallback) {\r\n                        successCallback(\"\");\r\n                    }\r\n                } else if (successCallback) {\r\n                    successCallback(data);\r\n                }\r\n            },\r\n            mimeType,\r\n            1.0,\r\n            engine.getCreationOptions().antialias,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            quality\r\n        );\r\n        return;\r\n    }\r\n\r\n    engine.onEndFrameObservable.addOnce(() => {\r\n        if (!screenshotCanvas) {\r\n            screenshotCanvas = document.createElement(\"canvas\");\r\n        }\r\n        screenshotCanvas.width = width;\r\n        screenshotCanvas.height = height;\r\n\r\n        const renderContext = screenshotCanvas.getContext(\"2d\");\r\n        const renderingCanvas = engine.getRenderingCanvas();\r\n        if (!renderContext || !renderingCanvas) {\r\n            Logger.Error(\"Failed to create screenshot. Rendering context or rendering canvas is not available.\");\r\n            return;\r\n        }\r\n\r\n        const srcWidth = renderingCanvas.width;\r\n        const srcHeight = renderingCanvas.height;\r\n        const destWidth = screenshotCanvas.width;\r\n        const destHeight = screenshotCanvas.height;\r\n\r\n        // Calculate scale factors for width and height.\r\n        const scaleX = destWidth / srcWidth;\r\n        const scaleY = destHeight / srcHeight;\r\n        // Use the larger of the two scales to fill the screenshot dimensions, else use the smaller to fit.\r\n        const scale = useFill ? Math.max(scaleX, scaleY) : Math.min(scaleX, scaleY);\r\n        const newWidth = srcWidth * scale;\r\n        const newHeight = srcHeight * scale;\r\n\r\n        // Center the image in the screenshot canvas\r\n        const offsetX = (destWidth - newWidth) / 2;\r\n        const offsetY = (destHeight - newHeight) / 2;\r\n\r\n        renderContext.save();\r\n        renderContext.fillStyle = clearWithSceneColor ? scene.clearColor.toHexString() : \"rgba(0, 0, 0, 0)\";\r\n        renderContext.fillRect(0, 0, width, height);\r\n        renderContext.restore();\r\n\r\n        renderContext.drawImage(renderingCanvas, 0, 0, srcWidth, srcHeight, offsetX, offsetY, newWidth, newHeight);\r\n\r\n        if (forceDownload) {\r\n            Tools.EncodeScreenshotCanvasData(screenshotCanvas, undefined, mimeType, undefined, quality);\r\n            if (successCallback) {\r\n                successCallback(\"\");\r\n            }\r\n        } else {\r\n            Tools.EncodeScreenshotCanvasData(screenshotCanvas, successCallback, mimeType, undefined, quality);\r\n        }\r\n    });\r\n}\r\n\r\n/**\r\n * Captures a screenshot of the current rendering\r\n * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n * @param engine defines the rendering engine\r\n * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored\r\n * @param size This parameter can be set to a single number or to an object with the\r\n * following (optional) properties: precision, width, height. If a single number is passed,\r\n * it will be used for both width and height. If an object is passed, the screenshot size\r\n * will be derived from the parameters. The precision property is a multiplier allowing\r\n * rendering at a higher or lower resolution\r\n * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n * Check your browser for supported MIME types\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.\r\n * @param clearWithSceneColor If true, the screenshot canvas will be cleared with the scene clear color before copying the render.\r\n * @param forceDownload force the system to download the image\r\n * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n * to the src parameter of an <img> to display it\r\n */\r\nexport async function CreateScreenshotAsync(\r\n    engine: AbstractEngine,\r\n    camera: Camera,\r\n    size: IScreenshotSize | number,\r\n    mimeType = \"image/png\",\r\n    quality?: number,\r\n    useFill = false,\r\n    clearWithSceneColor = false,\r\n    forceDownload = false\r\n): Promise<string> {\r\n    return await new Promise((resolve, reject) => {\r\n        CreateScreenshot(\r\n            engine,\r\n            camera,\r\n            size,\r\n            (data) => {\r\n                if (typeof data !== \"undefined\") {\r\n                    resolve(data);\r\n                } else {\r\n                    reject(new Error(\"Data is undefined\"));\r\n                }\r\n            },\r\n            mimeType,\r\n            forceDownload,\r\n            quality,\r\n            useFill,\r\n            clearWithSceneColor\r\n        );\r\n    });\r\n}\r\n\r\n/**\r\n * Captures and automatically downloads a screenshot of the current rendering for a specific size. This will render the entire canvas but will generate a blink (due to canvas resize)\r\n * If screenshot image data is needed, use {@link CreateScreenshotAsync} instead.\r\n * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n * @param engine defines the rendering engine\r\n * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored\r\n * @param width defines the expected width\r\n * @param height defines the expected height\r\n * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n * Check your browser for supported MIME types\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.\r\n * @returns promise that resolves once the screenshot is taken\r\n */\r\nexport async function CreateScreenshotWithResizeAsync(\r\n    engine: AbstractEngine,\r\n    camera: Camera,\r\n    width: number,\r\n    height: number,\r\n    mimeType = \"image/png\",\r\n    quality?: number,\r\n    useFill = false\r\n): Promise<void> {\r\n    return await new Promise((resolve) => {\r\n        CreateScreenshot(\r\n            engine,\r\n            camera,\r\n            { width: width, height: height },\r\n            () => {\r\n                resolve();\r\n            },\r\n            mimeType,\r\n            true,\r\n            quality,\r\n            useFill\r\n        );\r\n    });\r\n}\r\n\r\n/**\r\n * Generates an image screenshot from the specified camera.\r\n * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n * @param engine The engine to use for rendering\r\n * @param camera The camera to use for rendering\r\n * @param size This parameter can be set to a single number or to an object with the\r\n * following (optional) properties: precision, width, height, finalWidth, finalHeight. If a single number is passed,\r\n * it will be used for both width and height, as well as finalWidth, finalHeight. If an object is passed, the screenshot size\r\n * will be derived from the parameters. The precision property is a multiplier allowing\r\n * rendering at a higher or lower resolution\r\n * @param successCallback The callback receives a single parameter which contains the\r\n * screenshot as a string of base64-encoded characters. This string can be assigned to the\r\n * src parameter of an <img> to display it\r\n * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n * Check your browser for supported MIME types\r\n * @param samples Texture samples (default: 1)\r\n * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n * @param fileName A name for for the downloaded file.\r\n * @param renderSprites Whether the sprites should be rendered or not (default: false)\r\n * @param enableStencilBuffer Whether the stencil buffer should be enabled or not (default: false)\r\n * @param useLayerMask if the camera's layer mask should be used to filter what should be rendered (default: true)\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @param customizeTexture An optional callback that can be used to modify the render target texture before taking the screenshot. This can be used, for instance, to enable camera post-processes before taking the screenshot.\r\n * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.\r\n * @param timeoutInMilliseconds The maximum time to wait for the screenshot to be ready before calling the timeoutErrorCallback (default: 30000 ms)\r\n * @param timeoutErrorCallback The callback that will be called if the screenshot could not be taken before the timeoutInMilliseconds\r\n */\r\nexport function CreateScreenshotUsingRenderTarget(\r\n    engine: AbstractEngine,\r\n    camera: Camera,\r\n    size: IScreenshotSize | number,\r\n    successCallback?: (data: string) => void,\r\n    mimeType = \"image/png\",\r\n    samples = 1,\r\n    antialiasing = false,\r\n    fileName?: string,\r\n    renderSprites = false,\r\n    enableStencilBuffer = false,\r\n    useLayerMask = true,\r\n    quality?: number,\r\n    customizeTexture?: (texture: RenderTargetTexture) => void,\r\n    customDumpData?: (\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        successCallback?: (data: string | ArrayBuffer) => void,\r\n        mimeType?: string,\r\n        fileName?: string,\r\n        invertY?: boolean,\r\n        toArrayBuffer?: boolean,\r\n        quality?: number\r\n    ) => void,\r\n    timeoutInMilliseconds = 30000,\r\n    timeoutErrorCallback?: () => void\r\n): void {\r\n    const scene = camera.getScene();\r\n\r\n    if (scene.frameGraph) {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        CreateScreenshotForFrameGraphAsync(scene.frameGraph, camera, size, mimeType, samples, antialiasing, fileName, quality, customDumpData, !successCallback).then((data) => {\r\n            if (successCallback) {\r\n                (successCallback as (data: string | ArrayBuffer) => void)(data!);\r\n            }\r\n        });\r\n        return;\r\n    }\r\n\r\n    const { height, width, finalWidth, finalHeight } = GetScreenshotSize(engine, camera, size);\r\n    const targetTextureSize = { width, height };\r\n\r\n    if (!(height && width)) {\r\n        Logger.Error(\"Invalid 'size' parameter !\");\r\n        return;\r\n    }\r\n\r\n    // Prevent engine to render on screen while we do the screenshot\r\n    engine.skipFrameRender = true;\r\n\r\n    const originalGetRenderWidth = engine.getRenderWidth;\r\n    const originalGetRenderHeight = engine.getRenderHeight;\r\n\r\n    // Override getRenderWidth and getRenderHeight to return the desired size of the render\r\n    // A few internal methods are relying on the canvas size to compute the render size\r\n    // so we need to override these methods to ensure the correct size is used during the preparation of the render\r\n    // as well as the screenshot\r\n    engine.getRenderWidth = (useScreen = false) => {\r\n        if (!useScreen && engine._currentRenderTarget) {\r\n            return engine._currentRenderTarget.width;\r\n        }\r\n\r\n        return width;\r\n    };\r\n    engine.getRenderHeight = (useScreen = false) => {\r\n        if (!useScreen && engine._currentRenderTarget) {\r\n            return engine._currentRenderTarget.height;\r\n        }\r\n\r\n        return height;\r\n    };\r\n\r\n    // Trigger a resize event to ensure the intermediate renders have the correct size\r\n    if (engine.onResizeObservable.hasObservers()) {\r\n        engine.onResizeObservable.notifyObservers(engine);\r\n    }\r\n\r\n    // At this point size can be a number, or an object (according to engine.prototype.createRenderTargetTexture method)\r\n    const texture = new RenderTargetTexture(\r\n        \"screenShot\",\r\n        targetTextureSize,\r\n        scene,\r\n        false,\r\n        false,\r\n        Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        false,\r\n        Texture.BILINEAR_SAMPLINGMODE,\r\n        undefined,\r\n        enableStencilBuffer,\r\n        undefined,\r\n        undefined,\r\n        undefined,\r\n        samples\r\n    );\r\n    texture.renderList = scene.meshes.slice();\r\n    texture.samples = samples;\r\n    texture.renderSprites = renderSprites;\r\n    texture.activeCamera = camera;\r\n    texture.forceLayerMaskCheck = useLayerMask;\r\n    customizeTexture?.(texture);\r\n\r\n    const dumpDataFunc = customDumpData || DumpData;\r\n\r\n    const renderWhenReady = () => {\r\n        _RetryWithInterval(\r\n            () => texture.isReadyForRendering() && camera.isReady(true),\r\n            () => {\r\n                engine.onEndFrameObservable.addOnce(() => {\r\n                    if (finalWidth === width && finalHeight === height) {\r\n                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                        texture.readPixels(undefined, undefined, undefined, false)!.then((data) => {\r\n                            dumpDataFunc(width, height, data, successCallback as (data: string | ArrayBuffer) => void, mimeType, fileName, true, undefined, quality);\r\n                            texture.dispose();\r\n                        });\r\n                    } else {\r\n                        const importPromise = engine.isWebGPU ? import(\"../ShadersWGSL/pass.fragment\") : import(\"../Shaders/pass.fragment\");\r\n                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                        importPromise.then(\r\n                            async () =>\r\n                                // eslint-disable-next-line github/no-then\r\n                                await ApplyPostProcess(\"pass\", texture.getInternalTexture()!, scene, undefined, undefined, undefined, finalWidth, finalHeight).then((texture) => {\r\n                                    // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                                    engine._readTexturePixels(texture, finalWidth, finalHeight, -1, 0, null, true, false, 0, 0).then((data) => {\r\n                                        dumpDataFunc(\r\n                                            finalWidth,\r\n                                            finalHeight,\r\n                                            data,\r\n                                            successCallback as (data: string | ArrayBuffer) => void,\r\n                                            mimeType,\r\n                                            fileName,\r\n                                            true,\r\n                                            undefined,\r\n                                            quality\r\n                                        );\r\n                                        texture.dispose();\r\n                                    });\r\n                                })\r\n                        );\r\n                    }\r\n                });\r\n                scene.incrementRenderId();\r\n                scene.resetCachedMaterial();\r\n\r\n                // Record the original scene setup\r\n                const originalCamera = scene.activeCamera;\r\n                const originalCameras = scene.activeCameras;\r\n                const originalOutputRenderTarget = camera.outputRenderTarget;\r\n                const originalSpritesEnabled = scene.spritesEnabled;\r\n\r\n                // Swap with the requested one\r\n                scene.activeCamera = camera;\r\n                scene.activeCameras = null;\r\n                camera.outputRenderTarget = texture;\r\n                scene.spritesEnabled = renderSprites;\r\n\r\n                const currentMeshList = scene.meshes;\r\n                scene.meshes = texture.renderList || scene.meshes;\r\n\r\n                // render the scene on the RTT\r\n                try {\r\n                    scene.render();\r\n                } finally {\r\n                    // Restore the original scene camera setup\r\n                    scene.activeCamera = originalCamera;\r\n                    scene.activeCameras = originalCameras;\r\n                    camera.outputRenderTarget = originalOutputRenderTarget;\r\n                    scene.spritesEnabled = originalSpritesEnabled;\r\n                    scene.meshes = currentMeshList;\r\n\r\n                    engine.getRenderWidth = originalGetRenderWidth;\r\n                    engine.getRenderHeight = originalGetRenderHeight;\r\n\r\n                    // Trigger a resize event to ensure the intermediate renders have the correct size\r\n                    if (engine.onResizeObservable.hasObservers()) {\r\n                        engine.onResizeObservable.notifyObservers(engine);\r\n                    }\r\n\r\n                    camera.getProjectionMatrix(true); // Force cache refresh;\r\n\r\n                    engine.skipFrameRender = false;\r\n                }\r\n            },\r\n            () => {\r\n                // Restore engine frame rendering on error\r\n                engine.skipFrameRender = false;\r\n                engine.getRenderWidth = originalGetRenderWidth;\r\n                engine.getRenderHeight = originalGetRenderHeight;\r\n                timeoutErrorCallback?.();\r\n            },\r\n            undefined,\r\n            timeoutInMilliseconds\r\n        );\r\n    };\r\n\r\n    const renderToTexture = () => {\r\n        // render the RTT\r\n        scene.incrementRenderId();\r\n        scene.resetCachedMaterial();\r\n\r\n        renderWhenReady();\r\n    };\r\n\r\n    if (antialiasing) {\r\n        const fxaaPostProcess = new FxaaPostProcess(\"antialiasing\", 1.0, scene.activeCamera);\r\n        texture.addPostProcess(fxaaPostProcess);\r\n        // Ensures the correct background color is used\r\n        fxaaPostProcess.autoClear = true;\r\n\r\n        // Async Shader Compilation can lead to none ready effects in synchronous code\r\n        fxaaPostProcess.onEffectCreatedObservable.addOnce((e) => {\r\n            if (!e.isReady()) {\r\n                e.onCompiled = () => {\r\n                    renderToTexture();\r\n                };\r\n            }\r\n            // The effect is ready we can render\r\n            else {\r\n                renderToTexture();\r\n            }\r\n        });\r\n    } else {\r\n        // No need to wait for extra resources to be ready\r\n        renderToTexture();\r\n    }\r\n}\r\n\r\n/**\r\n * Generates an image screenshot from the specified camera.\r\n * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n * @param engine The engine to use for rendering\r\n * @param camera The camera to use for rendering\r\n * @param size This parameter can be set to a single number or to an object with the\r\n * following (optional) properties: precision, width, height. If a single number is passed,\r\n * it will be used for both width and height. If an object is passed, the screenshot size\r\n * will be derived from the parameters. The precision property is a multiplier allowing\r\n * rendering at a higher or lower resolution\r\n * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n * Check your browser for supported MIME types\r\n * @param samples Texture samples (default: 1)\r\n * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n * @param fileName A name for for the downloaded file.\r\n * @param renderSprites Whether the sprites should be rendered or not (default: false)\r\n * @param enableStencilBuffer Whether the stencil buffer should be enabled or not (default: false)\r\n * @param useLayerMask if the camera's layer mask should be used to filter what should be rendered (default: true)\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @param customizeTexture An optional callback that can be used to modify the render target texture before taking the screenshot. This can be used, for instance, to enable camera post-processes before taking the screenshot.\r\n * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.\r\n * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n * to the src parameter of an <img> to display it\r\n */\r\nexport async function CreateScreenshotUsingRenderTargetAsync(\r\n    engine: AbstractEngine,\r\n    camera: Camera,\r\n    size: IScreenshotSize | number,\r\n    mimeType = \"image/png\",\r\n    samples = 1,\r\n    antialiasing = false,\r\n    fileName?: string,\r\n    renderSprites = false,\r\n    enableStencilBuffer = false,\r\n    useLayerMask = true,\r\n    quality?: number,\r\n    customizeTexture?: (texture: RenderTargetTexture) => void,\r\n    customDumpData?: (\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        successCallback?: (data: string | ArrayBuffer) => void,\r\n        mimeType?: string,\r\n        fileName?: string,\r\n        invertY?: boolean,\r\n        toArrayBuffer?: boolean,\r\n        quality?: number\r\n    ) => void\r\n): Promise<string> {\r\n    return await new Promise((resolve, reject) => {\r\n        CreateScreenshotUsingRenderTarget(\r\n            engine,\r\n            camera,\r\n            size,\r\n            (data) => {\r\n                if (typeof data !== \"undefined\") {\r\n                    resolve(data);\r\n                } else {\r\n                    reject(new Error(\"Data is undefined\"));\r\n                }\r\n            },\r\n            mimeType,\r\n            samples,\r\n            antialiasing,\r\n            fileName,\r\n            renderSprites,\r\n            enableStencilBuffer,\r\n            useLayerMask,\r\n            quality,\r\n            customizeTexture,\r\n            customDumpData\r\n        );\r\n    });\r\n}\r\n\r\n/**\r\n * Generates an image screenshot from the specified frame graph and camera\r\n * Please note:\r\n *  - that the frame graph must write to the back buffer color for this to work! This is because the back buffer color is replaced by the texture of the screenshot during the operation.\r\n *  - the camera is set as the camera for the main object renderer of the frame graph during the operation, and restored afterwards.\r\n *    This will only work if the frame graph has a main object renderer (isMainObjectRenderer is true for one of its object renderers)\r\n *  - that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n * @param frameGraph The frame graph to use for rendering\r\n * @param camera The camera to use for rendering\r\n * @param size This parameter can be set to a single number or to an object with the\r\n * following (optional) properties: precision, width, height. If a single number is passed,\r\n * it will be used for both width and height. If an object is passed, the screenshot size\r\n * will be derived from the parameters. The precision property is a multiplier allowing\r\n * rendering at a higher or lower resolution\r\n * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n * Check your browser for supported MIME types\r\n * @param samples Texture samples (default: 1)\r\n * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n * @param fileName A name for for the downloaded file.\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.\r\n * @param automaticDownload If true, the screenshot will be automatically downloaded as a file instead of being returned as a string: in this case, null is returned.\r\n * @param numberOfFramesToRender If provided, the number of frames to render before taking the screenshot.\r\n * If not provided, the screenshot will be taken after the next frame, or after 32 frames if the frame graph has at least one history texture.\r\n * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n * to the src parameter of an <img> to display it. If automaticDownload is true, null is returned instead\r\n */\r\nexport async function CreateScreenshotForFrameGraphAsync(\r\n    frameGraph: FrameGraph,\r\n    camera: Camera,\r\n    size: IScreenshotSize | number,\r\n    mimeType = \"image/png\",\r\n    samples = 1,\r\n    antialiasing = false,\r\n    fileName?: string,\r\n    quality?: number,\r\n    customDumpData?: (\r\n        width: number,\r\n        height: number,\r\n        data: ArrayBufferView,\r\n        successCallback?: (data: string | ArrayBuffer) => void,\r\n        mimeType?: string,\r\n        fileName?: string,\r\n        invertY?: boolean,\r\n        toArrayBuffer?: boolean,\r\n        quality?: number\r\n    ) => void,\r\n    automaticDownload = false,\r\n    numberOfFramesToRender?: number\r\n): Promise<string | ArrayBuffer | null> {\r\n    const engine = frameGraph.engine;\r\n    const textureManager = frameGraph.textureManager;\r\n\r\n    const { height, width, finalWidth, finalHeight } = GetScreenshotSize(engine, camera, size);\r\n    const targetTextureSize = { width, height };\r\n    const dumpDataFunc = customDumpData || DumpData;\r\n    const tasks = frameGraph.tasks;\r\n    const currentTaskListLength = tasks.length;\r\n    const pausedExecution = frameGraph.pausedExecution;\r\n    const currentParallelShaderCompile = engine.getCaps().parallelShaderCompile;\r\n\r\n    textureManager.setBackBufferTextures(\r\n        0,\r\n        0,\r\n        {\r\n            size: targetTextureSize,\r\n            options: {\r\n                createMipMaps: false,\r\n                samples,\r\n                types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                useSRGBBuffers: [false],\r\n                creationFlags: [0],\r\n                labels: [\"screenshot color\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n        },\r\n        {\r\n            size: targetTextureSize,\r\n            options: {\r\n                createMipMaps: false,\r\n                samples,\r\n                types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                formats: [engine.isStencilEnable ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT],\r\n                useSRGBBuffers: [false],\r\n                creationFlags: [0],\r\n                labels: [\"screenshot depth\"],\r\n            },\r\n            sizeIsPercentage: false,\r\n        }\r\n    );\r\n\r\n    let outputTextureHandle = backbufferColorTextureHandle;\r\n\r\n    if (antialiasing) {\r\n        const task = new FrameGraphFXAATask(\"fxaa\", frameGraph);\r\n\r\n        task.sourceTexture = outputTextureHandle;\r\n\r\n        outputTextureHandle = task.outputTexture;\r\n\r\n        frameGraph.addTask(task);\r\n    }\r\n\r\n    if (finalWidth !== width || finalHeight !== height) {\r\n        const task = new FrameGraphPassTask(\"pass\", frameGraph);\r\n\r\n        task.sourceTexture = outputTextureHandle;\r\n        task.targetTexture = frameGraph.textureManager.createRenderTargetTexture(\"pass_output\", {\r\n            size: { width: finalWidth, height: finalHeight },\r\n            options: {\r\n                createMipMaps: false,\r\n                types: [Constants.TEXTURETYPE_UNSIGNED_BYTE],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA],\r\n                samples: 1,\r\n                labels: [\"screenshot_final_texture\"],\r\n                useSRGBBuffers: [false],\r\n            },\r\n            sizeIsPercentage: false,\r\n        });\r\n\r\n        outputTextureHandle = task.outputTexture;\r\n\r\n        frameGraph.addTask(task);\r\n    }\r\n\r\n    const mainObjectRendererTask = FrameGraphUtils.FindMainObjectRenderer(frameGraph);\r\n\r\n    let currentCamera: Nullable<Camera> = null;\r\n    if (mainObjectRendererTask) {\r\n        currentCamera = mainObjectRendererTask.camera;\r\n        mainObjectRendererTask.camera = camera;\r\n    }\r\n\r\n    /**\r\n     * We need to disable parallel shader compile before running frameGraph.whenReadyAsync because of WebGL.\r\n     * In some cases, when whenReadyAsync is not ready the first time readiness is checked, the execute call will\r\n     * not render correctly. Disabling parallel shader compile fixes the problem. This does not happen with WebGPU.\r\n     *\r\n     * That's what happens in this PG: http://playground.babylonjs.com/#GAGVQO#16\r\n     *\r\n     * The FXAA task is injected in the frame graph (because antialiasing==true), and whenReadyAsync checks the readiness\r\n     * of the FXAA task for the first time, it returns false because the shader is not yet imported/compiled.\r\n     * If you uncomment line 2 in the PG, the FXAA shader will be preloaded/compiled before the screenshot is taken and\r\n     * whenReadyAsync won't have to check readiness twice. In that case, disabling parallel shader compile won't be necessary to have a correct screenshot.\r\n     *\r\n     * Same problem in: http://playground.babylonjs.com/#Z6C5EF#3\r\n     *\r\n     * TODO: find a better solution for this problem?\r\n     */\r\n    engine.getCaps().parallelShaderCompile = undefined;\r\n\r\n    await frameGraph.buildAsync();\r\n\r\n    const numberOfFrames = numberOfFramesToRender ?? (textureManager.hasHistoryTextures ? 32 : 1);\r\n\r\n    for (let i = 0; i < numberOfFrames; ++i) {\r\n        frameGraph.execute();\r\n    }\r\n\r\n    // eslint-disable-next-line require-atomic-updates\r\n    frameGraph.pausedExecution = true;\r\n\r\n    engine.getCaps().parallelShaderCompile = currentParallelShaderCompile;\r\n\r\n    for (let i = currentTaskListLength; i < tasks.length; ++i) {\r\n        frameGraph.tasks[i].dispose();\r\n    }\r\n\r\n    // eslint-disable-next-line require-atomic-updates\r\n    frameGraph.tasks.length = currentTaskListLength;\r\n\r\n    if (mainObjectRendererTask && currentCamera) {\r\n        mainObjectRendererTask.camera = currentCamera;\r\n    }\r\n\r\n    const texture = frameGraph.textureManager.getTextureFromHandle(outputTextureHandle)!;\r\n\r\n    texture.incrementReferences();\r\n\r\n    textureManager.resetBackBufferTextures();\r\n\r\n    await frameGraph.buildAsync();\r\n\r\n    // eslint-disable-next-line require-atomic-updates\r\n    frameGraph.pausedExecution = pausedExecution;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/return-await\r\n    return new Promise((resolve) => {\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        engine._readTexturePixels(texture, finalWidth, finalHeight, -1, 0, null, true, false, 0, 0).then(async (data) => {\r\n            texture.dispose();\r\n\r\n            dumpDataFunc(\r\n                finalWidth,\r\n                finalHeight,\r\n                data,\r\n                automaticDownload ? undefined : (data: string | ArrayBuffer) => resolve(data),\r\n                mimeType,\r\n                fileName,\r\n                true,\r\n                undefined,\r\n                quality\r\n            );\r\n\r\n            if (automaticDownload) {\r\n                resolve(null);\r\n            }\r\n        });\r\n    });\r\n}\r\n\r\n/**\r\n * Gets height and width for screenshot size\r\n * @param engine The engine to use for rendering\r\n * @param camera The camera to use for rendering\r\n * @param size This size of the screenshot. can be a number or an object implementing IScreenshotSize\r\n * @returns height and width for screenshot size\r\n */\r\nfunction GetScreenshotSize(engine: AbstractEngine, camera: Camera, size: IScreenshotSize | number): { height: number; width: number; finalWidth: number; finalHeight: number } {\r\n    let height = 0;\r\n    let width = 0;\r\n    let finalWidth = 0;\r\n    let finalHeight = 0;\r\n\r\n    //If a size value defined as object\r\n    if (typeof size === \"object\") {\r\n        const precision = size.precision\r\n            ? Math.abs(size.precision) // prevent GL_INVALID_VALUE : glViewport: negative width/height\r\n            : 1;\r\n\r\n        //If a width and height values is specified\r\n        if (size.width && size.height) {\r\n            height = size.height * precision;\r\n            width = size.width * precision;\r\n        }\r\n        //If passing only width, computing height to keep display canvas ratio.\r\n        else if (size.width && !size.height) {\r\n            width = size.width * precision;\r\n            height = Math.round(width / engine.getAspectRatio(camera));\r\n        }\r\n        //If passing only height, computing width to keep display canvas ratio.\r\n        else if (size.height && !size.width) {\r\n            height = size.height * precision;\r\n            width = Math.round(height * engine.getAspectRatio(camera));\r\n        } else {\r\n            width = Math.round(engine.getRenderWidth() * precision);\r\n            height = Math.round(width / engine.getAspectRatio(camera));\r\n        }\r\n\r\n        //If a finalWidth and finalHeight values is specified\r\n        if (size.finalWidth && size.finalHeight) {\r\n            finalHeight = size.finalHeight;\r\n            finalWidth = size.finalWidth;\r\n        }\r\n        //If passing only finalWidth, computing finalHeight to keep display canvas ratio.\r\n        else if (size.finalWidth && !size.finalHeight) {\r\n            finalWidth = size.finalWidth;\r\n            finalHeight = Math.round(finalWidth / engine.getAspectRatio(camera));\r\n        }\r\n        //If passing only finalHeight, computing finalWidth to keep display canvas ratio.\r\n        else if (size.finalHeight && !size.finalWidth) {\r\n            finalHeight = size.finalHeight;\r\n            finalWidth = Math.round(finalHeight * engine.getAspectRatio(camera));\r\n        } else {\r\n            finalWidth = width;\r\n            finalHeight = height;\r\n        }\r\n    }\r\n    //Assuming here that \"size\" parameter is a number\r\n    else if (!isNaN(size)) {\r\n        height = size;\r\n        width = size;\r\n        finalWidth = size;\r\n        finalHeight = size;\r\n    }\r\n\r\n    // When creating the image data from the CanvasRenderingContext2D, the width and height is clamped to the size of the _gl context\r\n    // On certain GPUs, it seems as if the _gl context truncates to an integer automatically. Therefore, if a user tries to pass the width of their canvas element\r\n    // and it happens to be a float (1000.5 x 600.5 px), the engine.readPixels will return a different size array than context.createImageData\r\n    // to resolve this, we truncate the floats here to ensure the same size\r\n    if (width) {\r\n        width = Math.floor(width);\r\n    }\r\n    if (height) {\r\n        height = Math.floor(height);\r\n    }\r\n    if (finalWidth) {\r\n        finalWidth = Math.floor(finalWidth);\r\n    }\r\n    if (finalHeight) {\r\n        finalHeight = Math.floor(finalHeight);\r\n    }\r\n\r\n    return { height: height | 0, width: width | 0, finalWidth: finalWidth | 0, finalHeight: finalHeight | 0 };\r\n}\r\n\r\n/**\r\n * Class containing a set of static utilities functions for screenshots\r\n */\r\nexport const ScreenshotTools = {\r\n    /**\r\n     * Captures a screenshot of the current rendering\r\n     * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine defines the rendering engine\r\n     * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param successCallback defines the callback receives a single parameter which contains the\r\n     * screenshot as a string of base64-encoded characters. This string can be assigned to the\r\n     * src parameter of an <img> to display it\r\n     * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param forceDownload force the system to download the image even if a successCallback is provided\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.\r\n     */\r\n    CreateScreenshot,\r\n\r\n    /**\r\n     * Captures a screenshot of the current rendering\r\n     * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine defines the rendering engine\r\n     * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.\r\n     * @param forceDownload force the system to download the image\r\n     * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n     * to the src parameter of an <img> to display it\r\n     */\r\n    CreateScreenshotAsync,\r\n\r\n    /**\r\n     * Captures and automatically downloads a screenshot of the current rendering for a specific size. This will render the entire canvas but will generate a blink (due to canvas resize)\r\n     * If screenshot image data is needed, use {@link CreateScreenshotAsync} instead.\r\n     * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine defines the rendering engine\r\n     * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored\r\n     * @param width defines the expected width\r\n     * @param height defines the expected height\r\n     * @param mimeType defines the MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.\r\n     * @returns promise that resolves once the screenshot is taken\r\n     */\r\n    CreateScreenshotWithResizeAsync,\r\n\r\n    /**\r\n     * Generates an image screenshot from the specified camera.\r\n     * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine The engine to use for rendering\r\n     * @param camera The camera to use for rendering\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param successCallback The callback receives a single parameter which contains the\r\n     * screenshot as a string of base64-encoded characters. This string can be assigned to the\r\n     * src parameter of an <img> to display it\r\n     * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param samples Texture samples (default: 1)\r\n     * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n     * @param fileName A name for for the downloaded file.\r\n     * @param renderSprites Whether the sprites should be rendered or not (default: false)\r\n     * @param enableStencilBuffer Whether the stencil buffer should be enabled or not (default: false)\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     */\r\n    CreateScreenshotUsingRenderTarget,\r\n\r\n    /**\r\n     * Generates an image screenshot from the specified camera.\r\n     * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG\r\n     * @param engine The engine to use for rendering\r\n     * @param camera The camera to use for rendering\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param samples Texture samples (default: 1)\r\n     * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n     * @param fileName A name for for the downloaded file.\r\n     * @param renderSprites Whether the sprites should be rendered or not (default: false)\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n     * to the src parameter of an <img> to display it\r\n     */\r\n    CreateScreenshotUsingRenderTargetAsync,\r\n\r\n    /**\r\n     * Generates an image screenshot from the specified frame graph and camera\r\n     * Please note:\r\n     *  - that the frame graph must write to the back buffer color for this to work! This is because the back buffer color is replaced by the texture of the screenshot during the operation.\r\n     *  - the camera is set as the camera for the main object renderer of the frame graph during the operation, and restored afterwards.\r\n     *    This will only work if the frame graph has a main object renderer (isMainObjectRenderer is true for one of its object renderers)\r\n     *  - that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.\r\n     * @param frameGraph The frame graph to use for rendering\r\n     * @param camera The camera to use for rendering\r\n     * @param size This parameter can be set to a single number or to an object with the\r\n     * following (optional) properties: precision, width, height. If a single number is passed,\r\n     * it will be used for both width and height. If an object is passed, the screenshot size\r\n     * will be derived from the parameters. The precision property is a multiplier allowing\r\n     * rendering at a higher or lower resolution\r\n     * @param mimeType The MIME type of the screenshot image (default: image/png).\r\n     * Check your browser for supported MIME types\r\n     * @param samples Texture samples (default: 1)\r\n     * @param antialiasing Whether antialiasing should be turned on or not (default: false)\r\n     * @param fileName A name for for the downloaded file.\r\n     * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n     * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.\r\n     * @param automaticDownload If true, the screenshot will be automatically downloaded as a file instead of being returned as a string: in this case, null is returned.\r\n     * @returns screenshot as a string of base64-encoded characters. This string can be assigned\r\n     * to the src parameter of an <img> to display it. If automaticDownload is true, null is returned instead\r\n     */\r\n    CreateScreenshotForFrameGraphAsync,\r\n};\r\n\r\n/**\r\n * This will be executed automatically for UMD and es5.\r\n * If esm dev wants the side effects to execute they will have to run it manually\r\n * Once we build native modules those need to be exported.\r\n * @internal\r\n */\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for screenshotTools.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScreenshotTools(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    const initSideEffects = () => {\r\n        // References the dependencies.\r\n        Tools.CreateScreenshot = CreateScreenshot;\r\n        Tools.CreateScreenshotAsync = CreateScreenshotAsync;\r\n        Tools.CreateScreenshotUsingRenderTarget = CreateScreenshotUsingRenderTarget;\r\n        Tools.CreateScreenshotUsingRenderTargetAsync = CreateScreenshotUsingRenderTargetAsync;\r\n    };\r\n\r\n    initSideEffects();\r\n}\r\n","/**\r\n * Enum that determines the text-wrapping mode to use.\r\n */\r\nexport const enum InspectableType {\r\n    /**\r\n     * Checkbox for booleans\r\n     */\r\n    Checkbox = 0,\r\n    /**\r\n     * Sliders for numbers\r\n     */\r\n    Slider = 1,\r\n    /**\r\n     * Vector3\r\n     */\r\n    Vector3 = 2,\r\n    /**\r\n     * Quaternions\r\n     */\r\n    Quaternion = 3,\r\n    /**\r\n     * Color3\r\n     */\r\n    Color3 = 4,\r\n    /**\r\n     * String\r\n     */\r\n    String = 5,\r\n    /**\r\n     * Button\r\n     */\r\n    Button = 6,\r\n    /**\r\n     * Options\r\n     */\r\n    Options = 7,\r\n    /**\r\n     * Tab\r\n     */\r\n    Tab = 8,\r\n    /**\r\n     * File button\r\n     */\r\n    FileButton = 9,\r\n    /**\r\n     * Vector2\r\n     */\r\n    Vector2 = 10,\r\n}\r\n\r\n/**\r\n * Interface used to define custom inspectable options in \"Options\" mode.\r\n * This interface is used by the inspector to display the list of options\r\n */\r\nexport interface IInspectableOptions {\r\n    /**\r\n     * Defines the visible part of the option\r\n     */\r\n    label: string;\r\n    /**\r\n     * Defines the value part of the option (returned through the callback)\r\n     */\r\n    value: number | string;\r\n    /**\r\n     * Defines if the option should be selected or not\r\n     */\r\n    selected?: boolean;\r\n}\r\n\r\n/**\r\n * Interface used to define custom inspectable properties.\r\n * This interface is used by the inspector to display custom property grids\r\n * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n */\r\nexport interface IInspectable {\r\n    /**\r\n     * Gets the label to display\r\n     */\r\n    label: string;\r\n    /**\r\n     * Gets the name of the property to edit\r\n     */\r\n    propertyName: string;\r\n    /**\r\n     * Gets the type of the editor to use\r\n     */\r\n    type: InspectableType;\r\n    /**\r\n     * Gets the minimum value of the property when using in \"slider\" mode\r\n     */\r\n    min?: number;\r\n    /**\r\n     * Gets the maximum value of the property when using in \"slider\" mode\r\n     */\r\n    max?: number;\r\n    /**\r\n     * Gets the setp to use when using in \"slider\" mode\r\n     */\r\n    step?: number;\r\n    /**\r\n     * Gets the callback function when using \"Button\" mode\r\n     */\r\n    callback?: () => void;\r\n    /**\r\n     * Gets the callback function when using \"FileButton\" mode\r\n     */\r\n    fileCallback?: (file: File) => void;\r\n    /**\r\n     * Gets the list of options when using \"Option\" mode\r\n     */\r\n    options?: IInspectableOptions[];\r\n    /**\r\n     * Gets the extensions to accept when using \"FileButton\" mode.\r\n     * The value should be a comma separated string with the list of extensions to accept e.g., \".jpg, .png, .tga, .dds, .env\".\r\n     */\r\n    accept?: string;\r\n}\r\n","import { Decode } from \"./stringTools\";\r\n\r\n/**\r\n * Interface for a data buffer\r\n */\r\nexport interface IDataBuffer {\r\n    /**\r\n     * Reads bytes from the data buffer.\r\n     * @param byteOffset The byte offset to read\r\n     * @param byteLength The byte length to read\r\n     * @returns A promise that resolves when the bytes are read\r\n     */\r\n    readAsync(byteOffset: number, byteLength: number): Promise<ArrayBufferView>;\r\n\r\n    /**\r\n     * The byte length of the buffer.\r\n     */\r\n    readonly byteLength: number;\r\n}\r\n\r\n/**\r\n * Utility class for reading from a data buffer\r\n */\r\nexport class DataReader {\r\n    /**\r\n     * The data buffer associated with this data reader.\r\n     */\r\n    public readonly buffer: IDataBuffer;\r\n\r\n    /**\r\n     * The current byte offset from the beginning of the data buffer.\r\n     */\r\n    public byteOffset = 0;\r\n\r\n    private _dataView: DataView;\r\n    private _dataByteOffset: number;\r\n\r\n    /**\r\n     * Constructor\r\n     * @param buffer The buffer to read\r\n     */\r\n    constructor(buffer: IDataBuffer) {\r\n        this.buffer = buffer;\r\n    }\r\n\r\n    /**\r\n     * Loads the given byte length.\r\n     * @param byteLength The byte length to load\r\n     * @returns A promise that resolves when the load is complete\r\n     */\r\n    public async loadAsync(byteLength: number): Promise<void> {\r\n        const data = await this.buffer.readAsync(this.byteOffset, byteLength);\r\n        this._dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\r\n        this._dataByteOffset = 0;\r\n    }\r\n\r\n    /**\r\n     * Read a unsigned 32-bit integer from the currently loaded data range.\r\n     * @returns The 32-bit integer read\r\n     */\r\n    public readUint32(): number {\r\n        const value = this._dataView.getUint32(this._dataByteOffset, true);\r\n        this._dataByteOffset += 4;\r\n        this.byteOffset += 4;\r\n        return value;\r\n    }\r\n\r\n    /**\r\n     * Read a byte array from the currently loaded data range.\r\n     * @param byteLength The byte length to read\r\n     * @returns The byte array read\r\n     */\r\n    public readUint8Array(byteLength: number): Uint8Array {\r\n        const value = new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + this._dataByteOffset, byteLength);\r\n        this._dataByteOffset += byteLength;\r\n        this.byteOffset += byteLength;\r\n        return value;\r\n    }\r\n\r\n    /**\r\n     * Read a string from the currently loaded data range.\r\n     * @param byteLength The byte length to read\r\n     * @returns The string read\r\n     */\r\n    public readString(byteLength: number): string {\r\n        return Decode(this.readUint8Array(byteLength));\r\n    }\r\n\r\n    /**\r\n     * Skips the given byte length the currently loaded data range.\r\n     * @param byteLength The byte length to skip\r\n     */\r\n    public skipBytes(byteLength: number): void {\r\n        this._dataByteOffset += byteLength;\r\n        this.byteOffset += byteLength;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"minmaxReduxPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;\n#if defined(INITIAL)\nuniform vec2 texSize;void main(void)\n{ivec2 coord=ivec2(vUV*(texSize-1.0));float f1=texelFetch(textureSampler,coord,0).r;float f2=texelFetch(textureSampler,coord+ivec2(1,0),0).r;float f3=texelFetch(textureSampler,coord+ivec2(1,1),0).r;float f4=texelFetch(textureSampler,coord+ivec2(0,1),0).r;\n#ifdef DEPTH_REDUX\n#ifdef VIEW_DEPTH\nfloat minz=3.4e38;if (f1 != 0.0) { minz=f1; }\nif (f2 != 0.0) { minz=min(minz,f2); }\nif (f3 != 0.0) { minz=min(minz,f3); }\nif (f4 != 0.0) { minz=min(minz,f4); }\nfloat maxz=max(max(max(f1,f2),f3),f4);\n#else\nfloat minz=min(min(min(f1,f2),f3),f4);float maxz=max(max(max(sign(1.0-f1)*f1,sign(1.0-f2)*f2),sign(1.0-f3)*f3),sign(1.0-f4)*f4);\n#endif\n#else\nfloat minz=min(min(min(f1,f2),f3),f4);float maxz=max(max(max(f1,f2),f3),f4);\n#endif\nglFragColor=vec4(minz,maxz,0.,0.);}\n#elif defined(MAIN)\nuniform vec2 texSize;void main(void)\n{ivec2 coord=ivec2(vUV*(texSize-1.0));vec2 f1=texelFetch(textureSampler,coord,0).rg;vec2 f2=texelFetch(textureSampler,coord+ivec2(1,0),0).rg;vec2 f3=texelFetch(textureSampler,coord+ivec2(1,1),0).rg;vec2 f4=texelFetch(textureSampler,coord+ivec2(0,1),0).rg;float minz=min(min(min(f1.x,f2.x),f3.x),f4.x);float maxz=max(max(max(f1.y,f2.y),f3.y),f4.y);glFragColor=vec4(minz,maxz,0.,0.);}\n#elif defined(ONEBEFORELAST)\nuniform ivec2 texSize;void main(void)\n{ivec2 coord=ivec2(vUV*vec2(texSize-1));vec2 f1=texelFetch(textureSampler,coord % texSize,0).rg;vec2 f2=texelFetch(textureSampler,(coord+ivec2(1,0)) % texSize,0).rg;vec2 f3=texelFetch(textureSampler,(coord+ivec2(1,1)) % texSize,0).rg;vec2 f4=texelFetch(textureSampler,(coord+ivec2(0,1)) % texSize,0).rg;float minz=min(min(min(f1.x,f2.x),f3.x),f4.x);float maxz=max(max(max(f1.y,f2.y),f3.y),f4.y);glFragColor=vec4(minz,maxz,0.,0.);}\n#elif defined(LAST)\nvoid main(void)\n{glFragColor=vec4(0.);if (true) { \ndiscard;}}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const minmaxReduxPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"minmaxReduxPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSampler: texture_2d<f32>;\n#if defined(INITIAL)\nuniform texSize: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let coord=vec2i(fragmentInputs.vUV*(uniforms.texSize-1.0));let f1=textureLoad(textureSampler,coord,0).r;let f2=textureLoad(textureSampler,coord+vec2i(1,0),0).r;let f3=textureLoad(textureSampler,coord+vec2i(1,1),0).r;let f4=textureLoad(textureSampler,coord+vec2i(0,1),0).r;\n#ifdef DEPTH_REDUX\n#ifdef VIEW_DEPTH\nvar minz=3.4e38;if (f1 != 0.0) { minz=f1; }\nif (f2 != 0.0) { minz=min(minz,f2); }\nif (f3 != 0.0) { minz=min(minz,f3); }\nif (f4 != 0.0) { minz=min(minz,f4); }\nlet maxz=max(max(max(f1,f2),f3),f4);\n#else\nlet minz=min(min(min(f1,f2),f3),f4);let maxz=max(max(max(sign(1.0-f1)*f1,sign(1.0-f2)*f2),sign(1.0-f3)*f3),sign(1.0-f4)*f4);\n#endif\n#else\nlet minz=min(min(min(f1,f2),f3),f4);let maxz=max(max(max(f1,f2),f3),f4);\n#endif\nfragmentOutputs.color=vec4f(minz,maxz,0.,0.);}\n#elif defined(MAIN)\nuniform texSize: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let coord=vec2i(fragmentInputs.vUV*(uniforms.texSize-1.0));let f1=textureLoad(textureSampler,coord,0).rg;let f2=textureLoad(textureSampler,coord+vec2i(1,0),0).rg;let f3=textureLoad(textureSampler,coord+vec2i(1,1),0).rg;let f4=textureLoad(textureSampler,coord+vec2i(0,1),0).rg;let minz=min(min(min(f1.x,f2.x),f3.x),f4.x);let maxz=max(max(max(f1.y,f2.y),f3.y),f4.y);fragmentOutputs.color=vec4(minz,maxz,0.,0.);}\n#elif defined(ONEBEFORELAST)\nuniform texSize: vec2i;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let coord=vec2i(fragmentInputs.vUV*vec2f(uniforms.texSize-1));let f1=textureLoad(textureSampler,coord % uniforms.texSize,0).rg;let f2=textureLoad(textureSampler,(coord+vec2i(1,0)) % uniforms.texSize,0).rg;let f3=textureLoad(textureSampler,(coord+vec2i(1,1)) % uniforms.texSize,0).rg;let f4=textureLoad(textureSampler,(coord+vec2i(0,1)) % uniforms.texSize,0).rg;let minz=min(min(min(f1.x,f2.x),f3.x),f4.x);let maxz=max(max(max(f1.y,f2.y),f3.y),f4.y);fragmentOutputs.color=vec4(minz,maxz,0.,0.);}\n#elif defined(LAST)\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=vec4f(0.);if (true) { \ndiscard;}}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const minmaxReduxPixelShaderWGSL = { name, shader };\n","import { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { GetClass } from \"../Misc/typeStore\";\r\n\r\nimport { type Scene } from \"../scene\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type ParticleSystem } from \"../Particles/particleSystem\";\r\n\r\n/**\r\n * Type of sub emitter\r\n */\r\nexport const enum SubEmitterType {\r\n    /**\r\n     * Attached to the particle over it's lifetime\r\n     */\r\n    ATTACHED,\r\n    /**\r\n     * Created when the particle dies\r\n     */\r\n    END,\r\n}\r\n\r\n/**\r\n * Sub emitter class used to emit particles from an existing particle\r\n */\r\nexport class SubEmitter {\r\n    /**\r\n     * Type of the submitter (Default: END)\r\n     */\r\n    public type = SubEmitterType.END;\r\n    /**\r\n     * If the particle should inherit the direction from the particle it's attached to. (+Y will face the direction the particle is moving) (Default: false)\r\n     * Note: This only is supported when using an emitter of type Mesh\r\n     */\r\n    public inheritDirection = false;\r\n    /**\r\n     * How much of the attached particles speed should be added to the sub emitted particle (default: 0)\r\n     */\r\n    public inheritedVelocityAmount = 0;\r\n\r\n    /**\r\n     * Creates a sub emitter\r\n     * @param particleSystem the particle system to be used by the sub emitter\r\n     */\r\n    constructor(\r\n        /**\r\n         * the particle system to be used by the sub emitter\r\n         */\r\n        public particleSystem: ParticleSystem\r\n    ) {\r\n        // Create mesh as emitter to support rotation\r\n        if (!particleSystem.emitter || !(<AbstractMesh>particleSystem.emitter).dispose) {\r\n            const internalClass = GetClass(\"BABYLON.AbstractMesh\");\r\n            particleSystem.emitter = new internalClass(\"SubemitterSystemEmitter\", particleSystem.getScene());\r\n            particleSystem._disposeEmitterOnDispose = true;\r\n        }\r\n    }\r\n    /**\r\n     * Clones the sub emitter\r\n     * @returns the cloned sub emitter\r\n     */\r\n    public clone(): SubEmitter {\r\n        // Clone particle system\r\n        let emitter = this.particleSystem.emitter;\r\n        if (!emitter) {\r\n            emitter = new Vector3();\r\n        } else if (emitter instanceof Vector3) {\r\n            emitter = emitter.clone();\r\n        } else if (emitter.getClassName().indexOf(\"Mesh\") !== -1) {\r\n            const internalClass = GetClass(\"BABYLON.Mesh\");\r\n            emitter = new internalClass(\"\", emitter.getScene());\r\n            (emitter! as any).isVisible = false;\r\n        }\r\n        const clone = new SubEmitter(this.particleSystem.clone(this.particleSystem.name, emitter));\r\n\r\n        // Clone properties\r\n        clone.particleSystem.name += \"Clone\";\r\n        clone.type = this.type;\r\n        clone.inheritDirection = this.inheritDirection;\r\n        clone.inheritedVelocityAmount = this.inheritedVelocityAmount;\r\n\r\n        clone.particleSystem._disposeEmitterOnDispose = true;\r\n        clone.particleSystem.disposeOnStop = true;\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serialize current object to a JSON object\r\n     * @param serializeTexture defines if the texture must be serialized as well\r\n     * @returns the serialized object\r\n     */\r\n    public serialize(serializeTexture: boolean = false): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.type = this.type;\r\n        serializationObject.inheritDirection = this.inheritDirection;\r\n        serializationObject.inheritedVelocityAmount = this.inheritedVelocityAmount;\r\n        serializationObject.particleSystem = this.particleSystem.serialize(serializeTexture);\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public static _ParseParticleSystem(system: any, sceneOrEngine: Scene | AbstractEngine, rootUrl: string, doNotStart = false): ParticleSystem {\r\n        throw _WarnImport(\"ParseParticle\");\r\n    }\r\n\r\n    /**\r\n     * Creates a new SubEmitter from a serialized JSON version\r\n     * @param serializationObject defines the JSON object to read from\r\n     * @param sceneOrEngine defines the hosting scene or the hosting engine\r\n     * @param rootUrl defines the rootUrl for data loading\r\n     * @returns a new SubEmitter\r\n     */\r\n    public static Parse(serializationObject: any, sceneOrEngine: Scene | AbstractEngine, rootUrl: string): SubEmitter {\r\n        const system = serializationObject.particleSystem;\r\n        const subEmitter = new SubEmitter(SubEmitter._ParseParticleSystem(system, sceneOrEngine, rootUrl, true));\r\n        subEmitter.type = serializationObject.type;\r\n        subEmitter.inheritDirection = serializationObject.inheritDirection;\r\n        subEmitter.inheritedVelocityAmount = serializationObject.inheritedVelocityAmount;\r\n        subEmitter.particleSystem._isSubEmitter = true;\r\n\r\n        return subEmitter;\r\n    }\r\n\r\n    /** Release associated resources */\r\n    public dispose() {\r\n        this.particleSystem.dispose();\r\n    }\r\n}\r\n","import { Logger } from \"./logger\";\r\n\r\ninterface IStorage {\r\n    getItem: (key: string) => string | null;\r\n    setItem: (key: string, value: string) => void;\r\n}\r\n\r\n/**\r\n * Class for storing data to local storage if available or in-memory storage otherwise\r\n */\r\nexport class DataStorage {\r\n    private static _Storage: IStorage = DataStorage._GetStorage();\r\n\r\n    private static _GetStorage(): IStorage {\r\n        try {\r\n            localStorage.setItem(\"test\", \"\");\r\n            localStorage.removeItem(\"test\");\r\n            return localStorage;\r\n        } catch {\r\n            const inMemoryStorage: { [key: string]: string } = {};\r\n            return {\r\n                getItem: (key) => {\r\n                    const value = inMemoryStorage[key];\r\n                    return value === undefined ? null : value;\r\n                },\r\n                setItem: (key, value) => {\r\n                    inMemoryStorage[key] = value;\r\n                },\r\n            };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reads a string from the data storage\r\n     * @param key The key to read\r\n     * @param defaultValue The value if the key doesn't exist\r\n     * @returns The string value\r\n     */\r\n    public static ReadString(key: string, defaultValue: string): string {\r\n        const value = this._Storage.getItem(key);\r\n        return value !== null ? value : defaultValue;\r\n    }\r\n\r\n    /**\r\n     * Writes a string to the data storage\r\n     * @param key The key to write\r\n     * @param value The value to write\r\n     */\r\n    public static WriteString(key: string, value: string): void {\r\n        this._Storage.setItem(key, value);\r\n    }\r\n\r\n    /**\r\n     * Reads a boolean from the data storage\r\n     * @param key The key to read\r\n     * @param defaultValue The value if the key doesn't exist\r\n     * @returns The boolean value\r\n     */\r\n    public static ReadBoolean(key: string, defaultValue: boolean): boolean {\r\n        const value = this._Storage.getItem(key);\r\n        return value !== null ? value === \"true\" : defaultValue;\r\n    }\r\n\r\n    /**\r\n     * Writes a boolean to the data storage\r\n     * @param key The key to write\r\n     * @param value The value to write\r\n     */\r\n    public static WriteBoolean(key: string, value: boolean) {\r\n        this._Storage.setItem(key, value ? \"true\" : \"false\");\r\n    }\r\n\r\n    /**\r\n     * Reads a number from the data storage\r\n     * @param key The key to read\r\n     * @param defaultValue The value if the key doesn't exist\r\n     * @returns The number value\r\n     */\r\n    public static ReadNumber(key: string, defaultValue: number): number {\r\n        const value = this._Storage.getItem(key);\r\n        return value !== null ? parseFloat(value) : defaultValue;\r\n    }\r\n\r\n    /**\r\n     * Writes a number to the data storage\r\n     * @param key The key to write\r\n     * @param value The value to write\r\n     */\r\n    public static WriteNumber(key: string, value: number) {\r\n        this._Storage.setItem(key, value.toString());\r\n    }\r\n\r\n    /**\r\n     * Reads a JSON value from the data storage\r\n     * @param key The key to read\r\n     * @param defaultValue The value if the key doesn't exist\r\n     * @returns The JSON value\r\n     */\r\n    public static ReadJson<T>(key: string, defaultValue: T): T {\r\n        const value = this._Storage.getItem(key);\r\n        try {\r\n            return value !== null ? JSON.parse(value) : defaultValue;\r\n        } catch (e) {\r\n            Logger.Warn(`Failed to parse JSON from storage for key \"${key}\". Returning default value.`, e);\r\n            return defaultValue;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Writes a JSON value to the data storage\r\n     * @param key The key to write\r\n     * @param value The JSON value to write\r\n     */\r\n    public static WriteJson<T>(key: string, value: T) {\r\n        this._Storage.setItem(key, JSON.stringify(value));\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Vector2, Vector3, TmpVectors, Vector4 } from \"../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type SubEmitter } from \"./subEmitter\";\r\nimport { type ColorGradient, type FactorGradient } from \"../Misc/gradients\";\r\n\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type ThinParticleSystem } from \"./thinParticleSystem\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\n\r\n/**\r\n * @internal\r\n * Holds all internal properties of a Particle, grouped into a single sub-object\r\n * to keep the Particle's own property count low (V8 in-object property limit).\r\n */\r\nclass ParticleInternalProperties {\r\n    /** @internal */\r\n    public randomCellOffset?: number;\r\n\r\n    /** @internal */\r\n    public initialDirection: Nullable<Vector3>;\r\n\r\n    /** @internal */\r\n    public attachedSubEmitters: Nullable<Array<SubEmitter>> = null;\r\n\r\n    /** @internal */\r\n    public initialStartSpriteCellId: number;\r\n    /** @internal */\r\n    public initialEndSpriteCellId: number;\r\n    /** @internal */\r\n    public initialSpriteCellLoop: boolean;\r\n\r\n    /** @internal */\r\n    public currentColorGradient: Nullable<ColorGradient>;\r\n    /** @internal */\r\n    public currentColor1 = new Color4(0, 0, 0, 0);\r\n    /** @internal */\r\n    public currentColor2 = new Color4(0, 0, 0, 0);\r\n\r\n    /** @internal */\r\n    public currentSizeGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public currentSize1 = 0;\r\n    /** @internal */\r\n    public currentSize2 = 0;\r\n\r\n    /** @internal */\r\n    public currentAngularSpeedGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public currentAngularSpeed1 = 0;\r\n    /** @internal */\r\n    public currentAngularSpeed2 = 0;\r\n\r\n    /** @internal */\r\n    public currentVelocityGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public currentVelocity1 = 0;\r\n    /** @internal */\r\n    public currentVelocity2 = 0;\r\n\r\n    /** @internal */\r\n    public directionScale: number;\r\n    /** @internal */\r\n    public scaledDirection = Vector3.Zero();\r\n\r\n    /** @internal */\r\n    public currentLimitVelocityGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public currentLimitVelocity1 = 0;\r\n    /** @internal */\r\n    public currentLimitVelocity2 = 0;\r\n\r\n    /** @internal */\r\n    public currentDragGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public currentDrag1 = 0;\r\n    /** @internal */\r\n    public currentDrag2 = 0;\r\n\r\n    /** @internal */\r\n    public randomNoiseCoordinates1: Nullable<Vector3>;\r\n    /** @internal */\r\n    public randomNoiseCoordinates2: Nullable<Vector3>;\r\n\r\n    /** @internal */\r\n    public localPosition?: Vector3;\r\n\r\n    /**\r\n     * Callback triggered when the particle is reset\r\n     */\r\n    public onReset: Nullable<() => void>;\r\n\r\n    /** @internal */\r\n    public reset(): void {\r\n        this.currentColorGradient = null;\r\n        this.currentSizeGradient = null;\r\n        this.currentAngularSpeedGradient = null;\r\n        this.currentVelocityGradient = null;\r\n        this.currentLimitVelocityGradient = null;\r\n        this.currentDragGradient = null;\r\n        this.randomCellOffset = undefined;\r\n        this.randomNoiseCoordinates1 = null;\r\n        this.randomNoiseCoordinates2 = null;\r\n    }\r\n}\r\n\r\n/**\r\n * A particle represents one of the element emitted by a particle system.\r\n * This is mainly define by its coordinates, direction, velocity and age.\r\n */\r\nexport class Particle {\r\n    private static _Count = 0;\r\n    /**\r\n     * Unique ID of the particle\r\n     */\r\n    public id: number;\r\n    /**\r\n     * The world position of the particle in the scene.\r\n     */\r\n    public position = Vector3.Zero();\r\n\r\n    /**\r\n     * The world direction of the particle in the scene.\r\n     */\r\n    public direction = Vector3.Zero();\r\n\r\n    /**\r\n     * The color of the particle.\r\n     */\r\n    public color = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * The color change of the particle per step.\r\n     */\r\n    public colorStep = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * The creation color of the particle.\r\n     */\r\n    public initialColor = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * The color used when the end of life of the particle.\r\n     */\r\n    public colorDead = new Color4(0, 0, 0, 0);\r\n\r\n    /**\r\n     * Defines how long will the life of the particle be.\r\n     */\r\n    public lifeTime = 1.0;\r\n\r\n    /**\r\n     * The current age of the particle.\r\n     */\r\n    public age = 0;\r\n\r\n    /**\r\n     * The current size of the particle.\r\n     */\r\n    public size = 0;\r\n\r\n    /**\r\n     * The current scale of the particle.\r\n     */\r\n    public scale = new Vector2(1, 1);\r\n\r\n    /**\r\n     * The current angle of the particle.\r\n     */\r\n    public angle = 0;\r\n\r\n    /**\r\n     * Defines how fast is the angle changing.\r\n     */\r\n    public angularSpeed = 0;\r\n\r\n    /**\r\n     * Defines the cell index used by the particle to be rendered from a sprite.\r\n     */\r\n    public cellIndex: number = 0;\r\n\r\n    /**\r\n     * The information required to support color remapping\r\n     */\r\n    public remapData: Vector4;\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the particle\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /** @internal */\r\n    public _properties = new ParticleInternalProperties();\r\n\r\n    /**\r\n     * Creates a new instance Particle\r\n     * @param particleSystem the particle system the particle belongs to\r\n     */\r\n    constructor(\r\n        /**\r\n         * The particle system the particle belongs to.\r\n         */\r\n        public particleSystem: ThinParticleSystem\r\n    ) {\r\n        this.id = Particle._Count++;\r\n        if (!this.particleSystem.isAnimationSheetEnabled) {\r\n            return;\r\n        }\r\n\r\n        this._updateCellInfoFromSystem();\r\n    }\r\n\r\n    private _updateCellInfoFromSystem(): void {\r\n        this.cellIndex = this.particleSystem.startSpriteCellID;\r\n    }\r\n\r\n    /**\r\n     * Defines how the sprite cell index is updated for the particle\r\n     */\r\n    public updateCellIndex(): void {\r\n        let offsetAge = this.age;\r\n        let changeSpeed = this.particleSystem.spriteCellChangeSpeed;\r\n\r\n        if (this.particleSystem.spriteRandomStartCell) {\r\n            if (this._properties.randomCellOffset === undefined) {\r\n                this._properties.randomCellOffset = Math.random() * this.lifeTime;\r\n            }\r\n\r\n            if (changeSpeed === 0) {\r\n                // Special case when speed = 0 meaning we want to stay on initial cell\r\n                changeSpeed = 1;\r\n                offsetAge = this._properties.randomCellOffset;\r\n            } else {\r\n                offsetAge += this._properties.randomCellOffset;\r\n            }\r\n        }\r\n\r\n        const dist = this._properties.initialEndSpriteCellId - this._properties.initialStartSpriteCellId + 1;\r\n        let ratio: number;\r\n        if (this._properties.initialSpriteCellLoop) {\r\n            ratio = Clamp(((offsetAge * changeSpeed) % this.lifeTime) / this.lifeTime);\r\n        } else {\r\n            ratio = Clamp((offsetAge * changeSpeed) / this.lifeTime);\r\n        }\r\n        this.cellIndex = (this._properties.initialStartSpriteCellId + ratio * dist) | 0;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _inheritParticleInfoToSubEmitter(subEmitter: SubEmitter) {\r\n        if ((<AbstractMesh>subEmitter.particleSystem.emitter).position) {\r\n            const emitterMesh = <AbstractMesh>subEmitter.particleSystem.emitter;\r\n            emitterMesh.position.copyFrom(this.position);\r\n            if (subEmitter.inheritDirection) {\r\n                const temp = TmpVectors.Vector3[0];\r\n                this.direction.normalizeToRef(temp);\r\n                emitterMesh.setDirection(temp, 0, Math.PI / 2);\r\n            }\r\n        } else {\r\n            const emitterPosition = <Vector3>subEmitter.particleSystem.emitter;\r\n            emitterPosition.copyFrom(this.position);\r\n        }\r\n        // Set inheritedVelocityOffset to be used when new particles are created\r\n        this.direction.scaleToRef(subEmitter.inheritedVelocityAmount / 2, TmpVectors.Vector3[0]);\r\n        subEmitter.particleSystem._inheritedVelocityOffset.copyFrom(TmpVectors.Vector3[0]);\r\n    }\r\n\r\n    /** @internal */\r\n    public _inheritParticleInfoToSubEmitters() {\r\n        if (this._properties.attachedSubEmitters && this._properties.attachedSubEmitters.length > 0) {\r\n            for (const subEmitter of this._properties.attachedSubEmitters) {\r\n                this._inheritParticleInfoToSubEmitter(subEmitter);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _reset() {\r\n        if (this._properties.onReset) {\r\n            this._properties.onReset();\r\n        }\r\n        this.age = 0;\r\n        this.id = Particle._Count++;\r\n        this._properties.reset();\r\n        this.metadata = null;\r\n        this.cellIndex = this.particleSystem.startSpriteCellID;\r\n    }\r\n\r\n    /**\r\n     * Copy the properties of particle to another one.\r\n     * @param other the particle to copy the information to.\r\n     */\r\n    public copyTo(other: Particle) {\r\n        other.position.copyFrom(this.position);\r\n        if (this._properties.initialDirection) {\r\n            if (other._properties.initialDirection) {\r\n                other._properties.initialDirection.copyFrom(this._properties.initialDirection);\r\n            } else {\r\n                other._properties.initialDirection = this._properties.initialDirection.clone();\r\n            }\r\n        } else {\r\n            other._properties.initialDirection = null;\r\n        }\r\n        other.direction.copyFrom(this.direction);\r\n        if (this._properties.localPosition) {\r\n            if (other._properties.localPosition) {\r\n                other._properties.localPosition.copyFrom(this._properties.localPosition);\r\n            } else {\r\n                other._properties.localPosition = this._properties.localPosition.clone();\r\n            }\r\n        }\r\n        other.color.copyFrom(this.color);\r\n        other.colorStep.copyFrom(this.colorStep);\r\n        other.initialColor.copyFrom(this.initialColor);\r\n        other.colorDead.copyFrom(this.colorDead);\r\n        other.lifeTime = this.lifeTime;\r\n        other.age = this.age;\r\n        other._properties.randomCellOffset = this._properties.randomCellOffset;\r\n        other.size = this.size;\r\n        other.scale.copyFrom(this.scale);\r\n        other.angle = this.angle;\r\n        other.angularSpeed = this.angularSpeed;\r\n        other.particleSystem = this.particleSystem;\r\n        other.cellIndex = this.cellIndex;\r\n        other.id = this.id;\r\n        other._properties.attachedSubEmitters = this._properties.attachedSubEmitters;\r\n        if (this._properties.currentColorGradient) {\r\n            other._properties.currentColorGradient = this._properties.currentColorGradient;\r\n            other._properties.currentColor1.copyFrom(this._properties.currentColor1);\r\n            other._properties.currentColor2.copyFrom(this._properties.currentColor2);\r\n        }\r\n        if (this._properties.currentSizeGradient) {\r\n            other._properties.currentSizeGradient = this._properties.currentSizeGradient;\r\n            other._properties.currentSize1 = this._properties.currentSize1;\r\n            other._properties.currentSize2 = this._properties.currentSize2;\r\n        }\r\n        if (this._properties.currentAngularSpeedGradient) {\r\n            other._properties.currentAngularSpeedGradient = this._properties.currentAngularSpeedGradient;\r\n            other._properties.currentAngularSpeed1 = this._properties.currentAngularSpeed1;\r\n            other._properties.currentAngularSpeed2 = this._properties.currentAngularSpeed2;\r\n        }\r\n        if (this._properties.currentVelocityGradient) {\r\n            other._properties.currentVelocityGradient = this._properties.currentVelocityGradient;\r\n            other._properties.currentVelocity1 = this._properties.currentVelocity1;\r\n            other._properties.currentVelocity2 = this._properties.currentVelocity2;\r\n        }\r\n        if (this._properties.currentLimitVelocityGradient) {\r\n            other._properties.currentLimitVelocityGradient = this._properties.currentLimitVelocityGradient;\r\n            other._properties.currentLimitVelocity1 = this._properties.currentLimitVelocity1;\r\n            other._properties.currentLimitVelocity2 = this._properties.currentLimitVelocity2;\r\n        }\r\n        if (this._properties.currentDragGradient) {\r\n            other._properties.currentDragGradient = this._properties.currentDragGradient;\r\n            other._properties.currentDrag1 = this._properties.currentDrag1;\r\n            other._properties.currentDrag2 = this._properties.currentDrag2;\r\n        }\r\n        if (this.particleSystem.isAnimationSheetEnabled) {\r\n            other._properties.initialStartSpriteCellId = this._properties.initialStartSpriteCellId;\r\n            other._properties.initialEndSpriteCellId = this._properties.initialEndSpriteCellId;\r\n            other._properties.initialSpriteCellLoop = this._properties.initialSpriteCellLoop;\r\n        }\r\n        if (this.particleSystem.useRampGradients) {\r\n            if (other.remapData && this.remapData) {\r\n                other.remapData.copyFrom(this.remapData);\r\n            } else {\r\n                other.remapData = new Vector4(0, 0, 0, 0);\r\n            }\r\n        }\r\n        if (this._properties.randomNoiseCoordinates1 && this._properties.randomNoiseCoordinates2) {\r\n            if (other._properties.randomNoiseCoordinates1 && other._properties.randomNoiseCoordinates2) {\r\n                other._properties.randomNoiseCoordinates1.copyFrom(this._properties.randomNoiseCoordinates1);\r\n                other._properties.randomNoiseCoordinates2.copyFrom(this._properties.randomNoiseCoordinates2);\r\n            } else {\r\n                other._properties.randomNoiseCoordinates1 = this._properties.randomNoiseCoordinates1.clone();\r\n                other._properties.randomNoiseCoordinates2 = this._properties.randomNoiseCoordinates2.clone();\r\n            }\r\n        }\r\n        other.metadata = this.metadata;\r\n    }\r\n}\r\n","import { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { type ColorGradient, type FactorGradient, GradientHelper } from \"core/Misc/gradients\";\r\nimport { type Particle } from \"./particle\";\r\nimport { type ThinParticleSystem } from \"./thinParticleSystem\";\r\nimport { Clamp, Lerp, RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { TmpVectors, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\n\r\n/** Color */\r\n\r\n/** @internal */\r\nexport function _CreateColorData(particle: Particle, system: ThinParticleSystem) {\r\n    const step = RandomRange(0, 1.0);\r\n\r\n    Color4.LerpToRef(system.color1, system.color2, step, particle.color);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateColorDeadData(particle: Particle, system: ThinParticleSystem) {\r\n    system.colorDead.subtractToRef(particle.color, system._colorDiff);\r\n    system._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateColorGradientsData(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.currentColorGradient = system._colorGradients![0];\r\n    particle._properties.currentColorGradient.getColorToRef(particle.color);\r\n    particle._properties.currentColor1.copyFrom(particle.color);\r\n\r\n    if (system._colorGradients!.length > 1) {\r\n        system._colorGradients![1].getColorToRef(particle._properties.currentColor2);\r\n    } else {\r\n        particle._properties.currentColor2.copyFrom(particle.color);\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessColorGradients(particle: Particle, system: ThinParticleSystem) {\r\n    const colorGradients = system._colorGradients;\r\n    GradientHelper.GetCurrentGradient(system._ratio, colorGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== particle._properties.currentColorGradient) {\r\n            particle._properties.currentColor1.copyFrom(particle._properties.currentColor2);\r\n            (<ColorGradient>nextGradient).getColorToRef(particle._properties.currentColor2);\r\n            particle._properties.currentColorGradient = <ColorGradient>currentGradient;\r\n        }\r\n        Color4.LerpToRef(particle._properties.currentColor1, particle._properties.currentColor2, scale, particle.color);\r\n\r\n        if (particle.color.a < 0) {\r\n            particle.color.a = 0;\r\n        }\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessColor(particle: Particle, system: ThinParticleSystem) {\r\n    particle.colorStep.scaleToRef(system._scaledUpdateSpeed, system._scaledColorStep);\r\n    particle.color.addInPlace(system._scaledColorStep);\r\n\r\n    if (particle.color.a < 0) {\r\n        particle.color.a = 0;\r\n    }\r\n}\r\n\r\n/** Angular speed */\r\n\r\n/** @internal */\r\nexport function _ProcessAngularSpeedGradients(particle: Particle, system: ThinParticleSystem) {\r\n    GradientHelper.GetCurrentGradient(system._ratio, system._angularSpeedGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== particle._properties.currentAngularSpeedGradient) {\r\n            particle._properties.currentAngularSpeed1 = particle._properties.currentAngularSpeed2;\r\n            particle._properties.currentAngularSpeed2 = (<FactorGradient>nextGradient).getFactor();\r\n            particle._properties.currentAngularSpeedGradient = <FactorGradient>currentGradient;\r\n        }\r\n        particle.angularSpeed = Lerp(particle._properties.currentAngularSpeed1, particle._properties.currentAngularSpeed2, scale);\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessAngularSpeed(particle: Particle, system: ThinParticleSystem) {\r\n    particle.angle += particle.angularSpeed * system._scaledUpdateSpeed;\r\n}\r\n\r\n/** Velocity & direction */\r\n\r\n/** @internal */\r\nexport function _CreateDirectionData(particle: Particle, system: ThinParticleSystem) {\r\n    system.particleEmitterType.startDirectionFunction(system._emitterWorldMatrix, particle.direction, particle, system.isLocal, system._emitterInverseWorldMatrix);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateCustomDirectionData(particle: Particle, system: ThinParticleSystem) {\r\n    system.startDirectionFunction!(system._emitterWorldMatrix, particle.direction, particle, system.isLocal);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateVelocityGradients(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.currentVelocityGradient = system._velocityGradients![0];\r\n    particle._properties.currentVelocity1 = particle._properties.currentVelocityGradient.getFactor();\r\n\r\n    if (system._velocityGradients!.length > 1) {\r\n        particle._properties.currentVelocity2 = system._velocityGradients![1].getFactor();\r\n    } else {\r\n        particle._properties.currentVelocity2 = particle._properties.currentVelocity1;\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateLimitVelocityGradients(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.currentLimitVelocityGradient = system._limitVelocityGradients![0];\r\n    particle._properties.currentLimitVelocity1 = particle._properties.currentLimitVelocityGradient.getFactor();\r\n\r\n    if (system._limitVelocityGradients!.length > 1) {\r\n        particle._properties.currentLimitVelocity2 = system._limitVelocityGradients![1].getFactor();\r\n    } else {\r\n        particle._properties.currentLimitVelocity2 = particle._properties.currentLimitVelocity1;\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessVelocityGradients(particle: Particle, system: ThinParticleSystem) {\r\n    GradientHelper.GetCurrentGradient(system._ratio, system._velocityGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== particle._properties.currentVelocityGradient) {\r\n            particle._properties.currentVelocity1 = particle._properties.currentVelocity2;\r\n            particle._properties.currentVelocity2 = (<FactorGradient>nextGradient).getFactor();\r\n            particle._properties.currentVelocityGradient = <FactorGradient>currentGradient;\r\n        }\r\n        particle._properties.directionScale *= Lerp(particle._properties.currentVelocity1, particle._properties.currentVelocity2, scale);\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessLimitVelocityGradients(particle: Particle, system: ThinParticleSystem) {\r\n    GradientHelper.GetCurrentGradient(system._ratio, system._limitVelocityGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== particle._properties.currentLimitVelocityGradient) {\r\n            particle._properties.currentLimitVelocity1 = particle._properties.currentLimitVelocity2;\r\n            particle._properties.currentLimitVelocity2 = (<FactorGradient>nextGradient).getFactor();\r\n            particle._properties.currentLimitVelocityGradient = <FactorGradient>currentGradient;\r\n        }\r\n\r\n        const limitVelocity = Lerp(particle._properties.currentLimitVelocity1, particle._properties.currentLimitVelocity2, scale);\r\n        const currentVelocity = particle.direction.length();\r\n\r\n        if (currentVelocity > limitVelocity) {\r\n            particle.direction.scaleInPlace(system.limitVelocityDamping);\r\n        }\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessDirection(particle: Particle) {\r\n    particle.direction.scaleToRef(particle._properties.directionScale, particle._properties.scaledDirection);\r\n}\r\n\r\n/** Position */\r\n\r\n/** @internal */\r\nexport function _CreatePositionData(particle: Particle, system: ThinParticleSystem) {\r\n    system.particleEmitterType.startPositionFunction(system._emitterWorldMatrix, particle.position, particle, system.isLocal);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateCustomPositionData(particle: Particle, system: ThinParticleSystem) {\r\n    system.startPositionFunction!(system._emitterWorldMatrix, particle.position, particle, system.isLocal);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateIsLocalData(particle: Particle, system: ThinParticleSystem) {\r\n    if (!particle._properties.localPosition) {\r\n        particle._properties.localPosition = particle.position.clone();\r\n    } else {\r\n        particle._properties.localPosition.copyFrom(particle.position);\r\n    }\r\n    Vector3.TransformCoordinatesToRef(particle._properties.localPosition, system._emitterWorldMatrix, particle.position);\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessPosition(particle: Particle, system: ThinParticleSystem) {\r\n    if (system.isLocal && particle._properties.localPosition) {\r\n        particle._properties.localPosition!.addInPlace(particle._properties.scaledDirection);\r\n        Vector3.TransformCoordinatesToRef(particle._properties.localPosition!, system._emitterWorldMatrix, particle.position);\r\n    } else {\r\n        particle.position.addInPlace(particle._properties.scaledDirection);\r\n    }\r\n}\r\n\r\n/** Drag */\r\n\r\n/** @internal */\r\nexport function _CreateDragData(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.currentDragGradient = system._dragGradients![0];\r\n    particle._properties.currentDrag1 = particle._properties.currentDragGradient.getFactor();\r\n\r\n    if (system._dragGradients!.length > 1) {\r\n        particle._properties.currentDrag2 = system._dragGradients![1].getFactor();\r\n    } else {\r\n        particle._properties.currentDrag2 = particle._properties.currentDrag1;\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessDragGradients(particle: Particle, system: ThinParticleSystem) {\r\n    GradientHelper.GetCurrentGradient(system._ratio, system._dragGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== particle._properties.currentDragGradient) {\r\n            particle._properties.currentDrag1 = particle._properties.currentDrag2;\r\n            particle._properties.currentDrag2 = (<FactorGradient>nextGradient).getFactor();\r\n            particle._properties.currentDragGradient = <FactorGradient>currentGradient;\r\n        }\r\n\r\n        const drag = Lerp(particle._properties.currentDrag1, particle._properties.currentDrag2, scale);\r\n\r\n        particle._properties.scaledDirection.scaleInPlace(1.0 - drag);\r\n    });\r\n}\r\n\r\n/** Noise */\r\n\r\n/** @internal */\r\nexport function _CreateNoiseData(particle: Particle, _system: ThinParticleSystem) {\r\n    if (particle._properties.randomNoiseCoordinates1 && particle._properties.randomNoiseCoordinates2) {\r\n        particle._properties.randomNoiseCoordinates1.copyFromFloats(Math.random(), Math.random(), Math.random());\r\n        particle._properties.randomNoiseCoordinates2.copyFromFloats(Math.random(), Math.random(), Math.random());\r\n    } else {\r\n        particle._properties.randomNoiseCoordinates1 = new Vector3(Math.random(), Math.random(), Math.random());\r\n        particle._properties.randomNoiseCoordinates2 = new Vector3(Math.random(), Math.random(), Math.random());\r\n    }\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessNoise(particle: Particle, system: ThinParticleSystem) {\r\n    const noiseTextureData = system._noiseTextureData;\r\n    const noiseTextureSize = system._noiseTextureSize;\r\n\r\n    if (noiseTextureData && noiseTextureSize && particle._properties.randomNoiseCoordinates1 && particle._properties.randomNoiseCoordinates2) {\r\n        const fetchedColorR = system._fetchR(\r\n            particle._properties.randomNoiseCoordinates1.x,\r\n            particle._properties.randomNoiseCoordinates1.y,\r\n            noiseTextureSize.width,\r\n            noiseTextureSize.height,\r\n            noiseTextureData\r\n        );\r\n        const fetchedColorG = system._fetchR(\r\n            particle._properties.randomNoiseCoordinates1.z,\r\n            particle._properties.randomNoiseCoordinates2.x,\r\n            noiseTextureSize.width,\r\n            noiseTextureSize.height,\r\n            noiseTextureData\r\n        );\r\n        const fetchedColorB = system._fetchR(\r\n            particle._properties.randomNoiseCoordinates2.y,\r\n            particle._properties.randomNoiseCoordinates2.z,\r\n            noiseTextureSize.width,\r\n            noiseTextureSize.height,\r\n            noiseTextureData\r\n        );\r\n\r\n        const force = TmpVectors.Vector3[0];\r\n        const scaledForce = TmpVectors.Vector3[1];\r\n\r\n        force.copyFromFloats((2 * fetchedColorR - 1) * system.noiseStrength.x, (2 * fetchedColorG - 1) * system.noiseStrength.y, (2 * fetchedColorB - 1) * system.noiseStrength.z);\r\n\r\n        force.scaleToRef(system._tempScaledUpdateSpeed, scaledForce);\r\n        particle.direction.addInPlace(scaledForce);\r\n    }\r\n}\r\n\r\n/** Gravity */\r\n\r\n/** @internal */\r\nexport function _ProcessGravity(particle: Particle, system: ThinParticleSystem) {\r\n    system.gravity.scaleToRef(system._tempScaledUpdateSpeed, system._scaledGravity);\r\n    particle.direction.addInPlace(system._scaledGravity);\r\n}\r\n\r\n/** Size */\r\n\r\n/** @internal */\r\nexport function _CreateSizeData(particle: Particle, system: ThinParticleSystem) {\r\n    particle.size = RandomRange(system.minSize, system.maxSize);\r\n    particle.scale.copyFromFloats(RandomRange(system.minScaleX, system.maxScaleX), RandomRange(system.minScaleY, system.maxScaleY));\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateSizeGradientsData(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.currentSizeGradient = system._sizeGradients![0];\r\n    particle._properties.currentSize1 = particle._properties.currentSizeGradient.getFactor();\r\n    particle.size = particle._properties.currentSize1;\r\n\r\n    if (system._sizeGradients!.length > 1) {\r\n        particle._properties.currentSize2 = system._sizeGradients![1].getFactor();\r\n    } else {\r\n        particle._properties.currentSize2 = particle._properties.currentSize1;\r\n    }\r\n\r\n    particle.scale.copyFromFloats(RandomRange(system.minScaleX, system.maxScaleX), RandomRange(system.minScaleY, system.maxScaleY));\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateStartSizeGradientsData(particle: Particle, system: ThinParticleSystem) {\r\n    const ratio = system._actualFrame / system.targetStopDuration;\r\n    GradientHelper.GetCurrentGradient(ratio, system._startSizeGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== system._currentStartSizeGradient) {\r\n            system._currentStartSize1 = system._currentStartSize2;\r\n            system._currentStartSize2 = (<FactorGradient>nextGradient).getFactor();\r\n            system._currentStartSizeGradient = <FactorGradient>currentGradient;\r\n        }\r\n\r\n        const value = Lerp(system._currentStartSize1, system._currentStartSize2, scale);\r\n        particle.scale.scaleInPlace(value);\r\n    });\r\n}\r\n\r\n/** @internal */\r\nexport function _ProcessSizeGradients(particle: Particle, system: ThinParticleSystem) {\r\n    GradientHelper.GetCurrentGradient(system._ratio, system._sizeGradients!, (currentGradient, nextGradient, scale) => {\r\n        if (currentGradient !== particle._properties.currentSizeGradient) {\r\n            particle._properties.currentSize1 = particle._properties.currentSize2;\r\n            particle._properties.currentSize2 = (<FactorGradient>nextGradient).getFactor();\r\n            particle._properties.currentSizeGradient = <FactorGradient>currentGradient;\r\n        }\r\n        particle.size = Lerp(particle._properties.currentSize1, particle._properties.currentSize2, scale);\r\n    });\r\n}\r\n\r\n/** Ramp */\r\n\r\n/** @internal */\r\nexport function _CreateRampData(particle: Particle, _system: ThinParticleSystem) {\r\n    particle.remapData = new Vector4(0, 1, 0, 1);\r\n}\r\n\r\n/** Remap */\r\n\r\n/** @internal */\r\nexport function _ProcessRemapGradients(particle: Particle, system: ThinParticleSystem) {\r\n    if (system._colorRemapGradients && system._colorRemapGradients.length > 0) {\r\n        GradientHelper.GetCurrentGradient(system._ratio, system._colorRemapGradients, (currentGradient, nextGradient, scale) => {\r\n            const min = Lerp((<FactorGradient>currentGradient).factor1, (<FactorGradient>nextGradient).factor1, scale);\r\n            const max = Lerp((<FactorGradient>currentGradient).factor2!, (<FactorGradient>nextGradient).factor2!, scale);\r\n\r\n            particle.remapData.x = min;\r\n            particle.remapData.y = max - min;\r\n        });\r\n    }\r\n\r\n    if (system._alphaRemapGradients && system._alphaRemapGradients.length > 0) {\r\n        GradientHelper.GetCurrentGradient(system._ratio, system._alphaRemapGradients, (currentGradient, nextGradient, scale) => {\r\n            const min = Lerp((<FactorGradient>currentGradient).factor1, (<FactorGradient>nextGradient).factor1, scale);\r\n            const max = Lerp((<FactorGradient>currentGradient).factor2!, (<FactorGradient>nextGradient).factor2!, scale);\r\n\r\n            particle.remapData.z = min;\r\n            particle.remapData.w = max - min;\r\n        });\r\n    }\r\n}\r\n\r\n/** Life */\r\n\r\n/** @internal */\r\nexport function _CreateLifeGradientsData(particle: Particle, system: ThinParticleSystem) {\r\n    const ratio = Clamp(system._actualFrame / system.targetStopDuration);\r\n    GradientHelper.GetCurrentGradient(ratio, system._lifeTimeGradients!, (currentGradient, nextGradient) => {\r\n        const factorGradient1 = <FactorGradient>currentGradient;\r\n        const factorGradient2 = <FactorGradient>nextGradient;\r\n        const lifeTime1 = factorGradient1.getFactor();\r\n        const lifeTime2 = factorGradient2.getFactor();\r\n        const gradient = (ratio - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);\r\n        particle.lifeTime = Lerp(lifeTime1, lifeTime2, gradient);\r\n    });\r\n    system._emitPower = RandomRange(system.minEmitPower, system.maxEmitPower);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateLifetimeData(particle: Particle, system: ThinParticleSystem) {\r\n    particle.lifeTime = RandomRange(system.minLifeTime, system.maxLifeTime);\r\n    system._emitPower = RandomRange(system.minEmitPower, system.maxEmitPower);\r\n}\r\n\r\n/** Emit power */\r\n\r\n/** @internal */\r\nexport function _CreateEmitPowerData(particle: Particle, system: ThinParticleSystem) {\r\n    if (system._emitPower === 0) {\r\n        if (!particle._properties.initialDirection) {\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        } else {\r\n            particle._properties.initialDirection.copyFrom(particle.direction);\r\n        }\r\n        particle.direction.set(0, 0, 0);\r\n    } else {\r\n        particle._properties.initialDirection = null;\r\n        particle.direction.scaleInPlace(system._emitPower);\r\n    }\r\n\r\n    // Inherited Velocity\r\n    particle.direction.addInPlace(system._inheritedVelocityOffset);\r\n}\r\n\r\n/** Angle */\r\n\r\n/** @internal */\r\nexport function _CreateAngleData(particle: Particle, system: ThinParticleSystem) {\r\n    particle.angularSpeed = RandomRange(system.minAngularSpeed, system.maxAngularSpeed);\r\n    particle.angle = RandomRange(system.minInitialRotation, system.maxInitialRotation);\r\n}\r\n\r\n/** @internal */\r\nexport function _CreateAngleGradientsData(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.currentAngularSpeedGradient = system._angularSpeedGradients![0];\r\n    particle.angularSpeed = particle._properties.currentAngularSpeedGradient.getFactor();\r\n    particle._properties.currentAngularSpeed1 = particle.angularSpeed;\r\n\r\n    if (system._angularSpeedGradients!.length > 1) {\r\n        particle._properties.currentAngularSpeed2 = system._angularSpeedGradients![1].getFactor();\r\n    } else {\r\n        particle._properties.currentAngularSpeed2 = particle._properties.currentAngularSpeed1;\r\n    }\r\n    particle.angle = RandomRange(system.minInitialRotation, system.maxInitialRotation);\r\n}\r\n\r\n/** Sheet */\r\n\r\n/** @internal */\r\nexport function _CreateSheetData(particle: Particle, system: ThinParticleSystem) {\r\n    particle._properties.initialStartSpriteCellId = system.startSpriteCellID;\r\n    particle._properties.initialEndSpriteCellId = system.endSpriteCellID;\r\n    particle._properties.initialSpriteCellLoop = system.spriteCellLoop;\r\n}\r\n","import { type Nullable } from \"core/types\";\r\nimport { type Particle } from \"../particle\";\r\nimport { type ThinParticleSystem } from \"../thinParticleSystem\";\r\n\r\n/** @internal */\r\nexport interface _IExecutionQueueItem {\r\n    /** @internal */\r\n    process: (particle: Particle, system: ThinParticleSystem) => void;\r\n    /** @internal */\r\n    previousItem: Nullable<_IExecutionQueueItem>;\r\n    /** @internal */\r\n    nextItem: Nullable<_IExecutionQueueItem>;\r\n}\r\n\r\n/** @internal */\r\nexport function _ConnectBefore(newOne: _IExecutionQueueItem, activeOne: _IExecutionQueueItem) {\r\n    newOne.previousItem = activeOne.previousItem;\r\n    newOne.nextItem = activeOne;\r\n    if (activeOne.previousItem) {\r\n        activeOne.previousItem.nextItem = newOne;\r\n    }\r\n    activeOne.previousItem = newOne;\r\n}\r\n\r\n/** @internal */\r\nexport function _ConnectAfter(newOne: _IExecutionQueueItem, activeOne: _IExecutionQueueItem) {\r\n    newOne.previousItem = activeOne;\r\n    newOne.nextItem = activeOne.nextItem;\r\n    if (activeOne.nextItem) {\r\n        activeOne.nextItem.previousItem = newOne;\r\n    }\r\n    activeOne.nextItem = newOne;\r\n}\r\n\r\n/** @internal */\r\nexport function _ConnectAtTheEnd(newOne: _IExecutionQueueItem, root: _IExecutionQueueItem) {\r\n    let activeOne = root;\r\n    while (activeOne.nextItem) {\r\n        activeOne = activeOne.nextItem;\r\n    }\r\n    newOne.previousItem = activeOne;\r\n    newOne.nextItem = activeOne.nextItem;\r\n    activeOne.nextItem = newOne;\r\n}\r\n\r\n/** @internal */\r\nexport function _RemoveFromQueue(item: _IExecutionQueueItem) {\r\n    if (item.previousItem) {\r\n        item.previousItem.nextItem = item.nextItem;\r\n    }\r\n    if (item.nextItem) {\r\n        item.nextItem.previousItem = item.previousItem;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Immutable, type Nullable } from \"../types\";\r\nimport { type FactorGradient, ColorGradient, Color3Gradient, GradientHelper } from \"../Misc/gradients\";\r\nimport { type Observer, Observable } from \"../Misc/observable.pure\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer, Buffer } from \"../Buffers/buffer.pure\";\r\n\r\nimport { type Effect, type IEffectCreationOptions } from \"../Materials/effect.pure\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IDisposable, type Scene } from \"../scene.pure\";\r\n\r\nimport { type IParticleSystem } from \"./IParticleSystem\";\r\nimport { BaseParticleSystem } from \"./baseParticleSystem.pure\";\r\nimport { Particle } from \"./particle\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { RegisterAnimatable } from \"../Animations/animatable.pure\";\r\nimport { RegisterEnginesExtensionsEngineAlpha } from \"../Engines/Extensions/engine.alpha.pure\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\n\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { Color4, Color3, TmpColors } from \"../Maths/math.color.pure\";\r\nimport { type ISize } from \"../Maths/math.size\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\n\r\nimport { AddClipPlaneUniforms, PrepareStringDefinesForClipPlanes, BindClipPlane } from \"../Materials/clipPlaneMaterialHelper\";\r\n\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type ProceduralTexture } from \"../Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { BindFogParameters, BindLogDepth } from \"../Materials/materialHelper.functions\";\r\nimport { BoxParticleEmitter } from \"./EmitterTypes/boxParticleEmitter\";\r\nimport { Lerp } from \"../Maths/math.scalar.functions\";\r\nimport { PrepareSamplersForImageProcessing, PrepareUniformsForImageProcessing } from \"../Materials/imageProcessingConfiguration.functions\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport {\r\n    _CreateAngleData,\r\n    _CreateAngleGradientsData,\r\n    _CreateColorData,\r\n    _CreateColorDeadData,\r\n    _CreateColorGradientsData,\r\n    _CreateCustomDirectionData,\r\n    _CreateCustomPositionData,\r\n    _CreateDirectionData,\r\n    _CreateDragData,\r\n    _CreateEmitPowerData,\r\n    _CreateIsLocalData,\r\n    _CreateLifeGradientsData,\r\n    _CreateLifetimeData,\r\n    _CreateLimitVelocityGradients,\r\n    _CreateNoiseData,\r\n    _CreatePositionData,\r\n    _CreateRampData,\r\n    _CreateSheetData,\r\n    _CreateSizeData,\r\n    _CreateSizeGradientsData,\r\n    _CreateStartSizeGradientsData,\r\n    _CreateVelocityGradients,\r\n    _ProcessAngularSpeed,\r\n    _ProcessAngularSpeedGradients,\r\n    _ProcessColor,\r\n    _ProcessColorGradients,\r\n    _ProcessDirection,\r\n    _ProcessDragGradients,\r\n    _ProcessGravity,\r\n    _ProcessLimitVelocityGradients,\r\n    _ProcessNoise,\r\n    _ProcessPosition,\r\n    _ProcessRemapGradients,\r\n    _ProcessSizeGradients,\r\n    _ProcessVelocityGradients,\r\n} from \"./thinParticleSystem.function\";\r\nimport { type _IExecutionQueueItem, _ConnectAfter, _ConnectBefore, _RemoveFromQueue } from \"./Queue/executionQueue\";\r\nimport { MaterialHelperGeometryRendering } from \"../Materials/materialHelper.geometryrendering\";\r\n\r\n/**\r\n * This represents a thin particle system in Babylon.\r\n * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.\r\n * Particles can take different shapes while emitted like box, sphere, cone or you can write your custom function.\r\n * This thin version contains a limited subset of the total features in order to provide users with a way to get particles but with a smaller footprint\r\n * @example https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro\r\n */\r\nexport class ThinParticleSystem extends BaseParticleSystem implements IDisposable, IAnimatable, IParticleSystem {\r\n    /**\r\n     * Force all the particle systems to compile to glsl even on WebGPU engines.\r\n     * False by default. This is mostly meant for backward compatibility.\r\n     */\r\n    public static ForceGLSL = false;\r\n\r\n    /**\r\n     * This function can be defined to provide custom update for active particles.\r\n     * This function will be called instead of regular update (age, position, color, etc.).\r\n     * Do not forget that this function will be called on every frame so try to keep it simple and fast :)\r\n     */\r\n    public updateFunction: (particles: Particle[]) => void;\r\n\r\n    /** @internal */\r\n    public _emitterWorldMatrix: Matrix;\r\n    /** @internal */\r\n    public _emitterInverseWorldMatrix: Matrix = Matrix.Identity();\r\n\r\n    private _startDirectionFunction: Nullable<(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean) => void> = null;\r\n\r\n    /**\r\n     * This function can be defined to specify initial direction for every new particle.\r\n     * It by default use the emitterType defined function\r\n     */\r\n    public get startDirectionFunction(): Nullable<(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean) => void> {\r\n        return this._startDirectionFunction;\r\n    }\r\n\r\n    public set startDirectionFunction(value: Nullable<(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean) => void>) {\r\n        if (this._startDirectionFunction === value) {\r\n            return;\r\n        }\r\n        this._startDirectionFunction = value;\r\n\r\n        if (value) {\r\n            this._directionCreation.process = _CreateCustomDirectionData;\r\n        } else {\r\n            this._directionCreation.process = _CreateDirectionData;\r\n        }\r\n    }\r\n\r\n    private _startPositionFunction: Nullable<(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean) => void> = null;\r\n\r\n    /**\r\n     * This function can be defined to specify initial position for every new particle.\r\n     * It by default use the emitterType defined function\r\n     */\r\n    public get startPositionFunction(): Nullable<(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean) => void> {\r\n        return this._startPositionFunction;\r\n    }\r\n\r\n    public set startPositionFunction(value: Nullable<(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean) => void>) {\r\n        if (this._startPositionFunction === value) {\r\n            return;\r\n        }\r\n        this._startPositionFunction = value;\r\n\r\n        if (value) {\r\n            this._positionCreation.process = _CreateCustomPositionData;\r\n        } else {\r\n            this._positionCreation.process = _CreatePositionData;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _inheritedVelocityOffset = new Vector3();\r\n    /**\r\n     * An event triggered when the system is disposed\r\n     */\r\n    public onDisposeObservable = new Observable<IParticleSystem>();\r\n    /**\r\n     * An event triggered when the system is stopped\r\n     */\r\n    public onStoppedObservable = new Observable<IParticleSystem>();\r\n    /**\r\n     * An event triggered when the system is started\r\n     */\r\n    public onStartedObservable = new Observable<IParticleSystem>();\r\n\r\n    private _onDisposeObserver: Nullable<Observer<IParticleSystem>>;\r\n    /**\r\n     * Sets a callback that will be triggered when the system is disposed\r\n     */\r\n    public set onDispose(callback: () => void) {\r\n        if (this._onDisposeObserver) {\r\n            this.onDisposeObservable.remove(this._onDisposeObserver);\r\n        }\r\n        this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n    }\r\n\r\n    /** @internal */\r\n    public _noiseTextureSize: Nullable<ISize> = null;\r\n    /** @internal */\r\n    public _noiseTextureData: Nullable<Uint8Array> = null;\r\n    private _particles = new Array<Particle>();\r\n    private _epsilon: number;\r\n    private _capacity: number;\r\n    private _stockParticles = new Array<Particle>();\r\n    private _newPartsExcess = 0;\r\n    private _vertexData: Float32Array;\r\n    private _vertexBuffer: Nullable<Buffer>;\r\n    private _vertexBuffers: { [key: string]: VertexBuffer } = {};\r\n    private _spriteBuffer: Nullable<Buffer>;\r\n    private _indexBuffer: Nullable<DataBuffer>;\r\n    private _linesIndexBuffer: Nullable<DataBuffer>;\r\n    private _linesIndexBufferUseInstancing: Nullable<DataBuffer>;\r\n    private _drawWrappers: DrawWrapper[][]; // first index is render pass id, second index is blend mode\r\n    private _renderPassObserver: Nullable<Observer<number>> = null;\r\n    /** @internal */\r\n    public _customWrappers: { [blendMode: number]: Nullable<DrawWrapper> };\r\n    /** @internal */\r\n    public _scaledColorStep = new Color4(0, 0, 0, 0);\r\n    /** @internal */\r\n    public _colorDiff = new Color4(0, 0, 0, 0);\r\n    /** @internal */\r\n    public _scaledGravity = Vector3.Zero();\r\n    private _currentRenderId = -1;\r\n    private _alive: boolean;\r\n    private _useInstancing = false;\r\n    private _vertexArrayObject: Nullable<WebGLVertexArrayObject>;\r\n    /** @internal */\r\n    public _useFixedCapacityForSnapshot = false;\r\n    private _fixedCapacityHighWaterMark = 0;\r\n\r\n    private _isDisposed = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the particle system was disposed\r\n     */\r\n    public get isDisposed(): boolean {\r\n        return this._isDisposed;\r\n    }\r\n\r\n    private _started = false;\r\n    private _stopped = false;\r\n    /** @internal */\r\n    public _actualFrame = 0;\r\n    /** @internal */\r\n    public _scaledUpdateSpeed: number;\r\n    private _vertexBufferSize: number;\r\n\r\n    /** @internal */\r\n    public _currentEmitRateGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public _currentEmitRate1 = 0;\r\n    /** @internal */\r\n    public _currentEmitRate2 = 0;\r\n\r\n    /** @internal */\r\n    public _currentStartSizeGradient: Nullable<FactorGradient>;\r\n    /** @internal */\r\n    public _currentStartSize1 = 0;\r\n    /** @internal */\r\n    public _currentStartSize2 = 0;\r\n\r\n    /** Indicates that the update of particles is done in the animate function */\r\n    public readonly updateInAnimate = true;\r\n\r\n    private readonly _rawTextureWidth = 256;\r\n    private _rampGradientsTexture: Nullable<RawTexture>;\r\n    private _useRampGradients = false;\r\n\r\n    /** @internal */\r\n    public _updateQueueStart: Nullable<_IExecutionQueueItem> = null;\r\n    protected _colorProcessing: _IExecutionQueueItem;\r\n    protected _angularSpeedGradientProcessing: _IExecutionQueueItem;\r\n    protected _angularSpeedProcessing: _IExecutionQueueItem;\r\n    protected _velocityGradientProcessing: _IExecutionQueueItem;\r\n    protected _directionProcessing: _IExecutionQueueItem;\r\n    protected _limitVelocityGradientProcessing: _IExecutionQueueItem;\r\n    protected _positionProcessing: _IExecutionQueueItem;\r\n    protected _dragGradientProcessing: _IExecutionQueueItem;\r\n    protected _noiseProcessing: _IExecutionQueueItem;\r\n    protected _gravityProcessing: _IExecutionQueueItem;\r\n    protected _sizeGradientProcessing: _IExecutionQueueItem;\r\n    protected _remapGradientProcessing: _IExecutionQueueItem;\r\n\r\n    /** @internal */\r\n    public _lifeTimeCreation: _IExecutionQueueItem;\r\n    /** @internal */\r\n    public _positionCreation: _IExecutionQueueItem;\r\n    private _isLocalCreation: _IExecutionQueueItem;\r\n    /** @internal */\r\n    public _directionCreation: _IExecutionQueueItem;\r\n    private _emitPowerCreation: _IExecutionQueueItem;\r\n    /** @internal */\r\n    public _sizeCreation: _IExecutionQueueItem;\r\n    private _startSizeCreation: Nullable<_IExecutionQueueItem> = null;\r\n    /** @internal */\r\n    public _angleCreation: _IExecutionQueueItem;\r\n    private _velocityCreation: _IExecutionQueueItem;\r\n    private _limitVelocityCreation: _IExecutionQueueItem;\r\n    private _dragCreation: _IExecutionQueueItem;\r\n    /** @internal */\r\n    public _colorCreation: _IExecutionQueueItem;\r\n    /** @internal */\r\n    public _colorDeadCreation: _IExecutionQueueItem;\r\n    private _sheetCreation: _IExecutionQueueItem;\r\n    private _rampCreation: _IExecutionQueueItem;\r\n    private _noiseCreation: _IExecutionQueueItem;\r\n    private _createQueueStart: Nullable<_IExecutionQueueItem> = null;\r\n\r\n    /** @internal */\r\n    public _tempScaledUpdateSpeed: number;\r\n    /** @internal */\r\n    public _ratio: number;\r\n    /** @internal */\r\n    public _emitPower: number;\r\n\r\n    /** Gets or sets a matrix to use to compute projection */\r\n    public defaultProjectionMatrix: Matrix;\r\n\r\n    /** Gets or sets a matrix to use to compute view */\r\n    public defaultViewMatrix: Matrix;\r\n\r\n    /** Gets or sets a boolean indicating that ramp gradients must be used\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro#ramp-gradients\r\n     */\r\n    public get useRampGradients(): boolean {\r\n        return this._useRampGradients;\r\n    }\r\n\r\n    public set useRampGradients(value: boolean) {\r\n        if (this._useRampGradients === value) {\r\n            return;\r\n        }\r\n\r\n        this._useRampGradients = value;\r\n\r\n        this._resetEffect();\r\n\r\n        if (value) {\r\n            this._rampCreation = {\r\n                process: _CreateRampData,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._rampCreation, this._colorDeadCreation);\r\n\r\n            // NPE based particles system do not have an update queue as that's represented by update blocks\r\n            // So even if there is ramp/remap, do not try to add it to the queue unless it exists already (if it exists, gravityProcessing will be defined)\r\n            if (this._gravityProcessing) {\r\n                this._remapGradientProcessing = {\r\n                    process: _ProcessRemapGradients,\r\n                    previousItem: null,\r\n                    nextItem: null,\r\n                };\r\n                _ConnectAfter(this._remapGradientProcessing, this._gravityProcessing);\r\n            }\r\n        } else {\r\n            _RemoveFromQueue(this._rampCreation);\r\n            _RemoveFromQueue(this._remapGradientProcessing);\r\n        }\r\n    }\r\n\r\n    private _isLocal = false;\r\n\r\n    /**\r\n     * Specifies if the particles are updated in emitter local space or world space\r\n     */\r\n    public get isLocal() {\r\n        return this._isLocal;\r\n    }\r\n\r\n    public set isLocal(value: boolean) {\r\n        if (this._isLocal === value) {\r\n            return;\r\n        }\r\n\r\n        this._isLocal = value;\r\n\r\n        if (value) {\r\n            this._isLocalCreation = {\r\n                process: _CreateIsLocalData,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n\r\n            _ConnectAfter(this._isLocalCreation, this._positionCreation);\r\n        } else {\r\n            _RemoveFromQueue(this._isLocalCreation);\r\n        }\r\n    }\r\n\r\n    /** Indicates that the particle system is CPU based */\r\n    public readonly isGPU = false;\r\n\r\n    /**\r\n     * Gets the current list of active particles\r\n     */\r\n    public get particles(): Particle[] {\r\n        return this._particles;\r\n    }\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this material.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /** @internal */\r\n    public override get _isAnimationSheetEnabled() {\r\n        return this._animationSheetEnabled;\r\n    }\r\n\r\n    public override set _isAnimationSheetEnabled(value: boolean) {\r\n        if (this._animationSheetEnabled === value) {\r\n            return;\r\n        }\r\n\r\n        this._animationSheetEnabled = value;\r\n\r\n        if (value) {\r\n            this._sheetCreation = {\r\n                process: _CreateSheetData,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n\r\n            _ConnectAfter(this._sheetCreation, this._colorDeadCreation);\r\n        } else {\r\n            _RemoveFromQueue(this._sheetCreation);\r\n        }\r\n\r\n        this._reset();\r\n    }\r\n\r\n    /**\r\n     * Gets the number of particles active at the same time.\r\n     * @returns The number of active particles.\r\n     */\r\n    public getActiveCount() {\r\n        return this._particles.length;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"ParticleSystem\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"ParticleSystem\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the system is stopping\r\n     * @returns true if the system is currently stopping\r\n     */\r\n    public isStopping() {\r\n        return this._stopped && this.isAlive();\r\n    }\r\n\r\n    /**\r\n     * Gets the custom effect used to render the particles\r\n     * @param blendMode Blend mode for which the effect should be retrieved\r\n     * @returns The effect\r\n     */\r\n    public getCustomEffect(blendMode: number = 0): Nullable<Effect> {\r\n        return this._customWrappers[blendMode]?.effect ?? this._customWrappers[0]!.effect;\r\n    }\r\n\r\n    private _getCustomDrawWrapper(blendMode: number = 0): Nullable<DrawWrapper> {\r\n        return this._customWrappers[blendMode] ?? this._customWrappers[0];\r\n    }\r\n\r\n    /**\r\n     * Sets the custom effect used to render the particles\r\n     * @param effect The effect to set\r\n     * @param blendMode Blend mode for which the effect should be set\r\n     */\r\n    public setCustomEffect(effect: Nullable<Effect>, blendMode: number = 0) {\r\n        this._customWrappers[blendMode] = new DrawWrapper(this._engine);\r\n        this._customWrappers[blendMode].effect = effect;\r\n        if (this._customWrappers[blendMode].drawContext) {\r\n            this._customWrappers[blendMode].drawContext.useInstancing = this._useInstancing;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    private _onBeforeDrawParticlesObservable: Nullable<Observable<Nullable<Effect>>> = null;\r\n\r\n    /**\r\n     * Observable that will be called just before the particles are drawn\r\n     */\r\n    public get onBeforeDrawParticlesObservable(): Observable<Nullable<Effect>> {\r\n        if (!this._onBeforeDrawParticlesObservable) {\r\n            this._onBeforeDrawParticlesObservable = new Observable<Nullable<Effect>>();\r\n        }\r\n\r\n        return this._onBeforeDrawParticlesObservable;\r\n    }\r\n\r\n    /**\r\n     * Gets the name of the particle vertex shader\r\n     */\r\n    public get vertexShaderName(): string {\r\n        return \"particles\";\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex buffers used by the particle system\r\n     */\r\n    public get vertexBuffers(): Immutable<{ [key: string]: VertexBuffer }> {\r\n        return this._vertexBuffers;\r\n    }\r\n\r\n    /**\r\n     * Gets the index buffer used by the particle system (or null if no index buffer is used (if _useInstancing=true))\r\n     */\r\n    public get indexBuffer(): Nullable<DataBuffer> {\r\n        return this._indexBuffer;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a texture used to add random noise to particle positions\r\n     */\r\n    public override get noiseTexture() {\r\n        return this._noiseTexture;\r\n    }\r\n\r\n    public override set noiseTexture(value: Nullable<ProceduralTexture>) {\r\n        if (this.noiseTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._noiseTexture = value;\r\n\r\n        if (!value) {\r\n            _RemoveFromQueue(this._noiseCreation);\r\n            _RemoveFromQueue(this._noiseProcessing);\r\n            return;\r\n        }\r\n\r\n        this._noiseCreation = {\r\n            process: _CreateNoiseData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._noiseCreation, this._colorDeadCreation);\r\n\r\n        this._noiseProcessing = {\r\n            process: _ProcessNoise,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._noiseProcessing, this._positionProcessing);\r\n    }\r\n\r\n    /**\r\n     * Instantiates a particle system.\r\n     * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.\r\n     * @param name The name of the particle system\r\n     * @param capacity The max number of particles alive at the same time\r\n     * @param sceneOrEngine The scene the particle system belongs to or the engine to use if no scene\r\n     * @param customEffect a custom effect used to change the way particles are rendered by default\r\n     * @param isAnimationSheetEnabled Must be true if using a spritesheet to animate the particles texture\r\n     * @param epsilon Offset used to render the particles\r\n     * @param noUpdateQueue If true, the particle system will start with an empty update queue\r\n     */\r\n    constructor(\r\n        name: string,\r\n        capacity: number,\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        customEffect: Nullable<Effect> = null,\r\n        isAnimationSheetEnabled: boolean = false,\r\n        epsilon: number = 0.01,\r\n        noUpdateQueue: boolean = false\r\n    ) {\r\n        RegisterAnimatable();\r\n        RegisterEnginesExtensionsEngineAlpha();\r\n        super(name);\r\n\r\n        this._capacity = capacity;\r\n\r\n        this._epsilon = epsilon;\r\n\r\n        if (!sceneOrEngine || sceneOrEngine.getClassName() === \"Scene\") {\r\n            this._scene = (sceneOrEngine as Scene) || EngineStore.LastCreatedScene;\r\n            this._engine = this._scene.getEngine();\r\n            this.uniqueId = this._scene.getUniqueId();\r\n            this.layerMask = this._scene.defaultRenderableLayerMask;\r\n            this._scene.particleSystems.push(this);\r\n        } else {\r\n            this._engine = sceneOrEngine as AbstractEngine;\r\n            this.defaultProjectionMatrix = Matrix.PerspectiveFovLH(0.8, 1, 0.1, 100, this._engine.isNDCHalfZRange);\r\n        }\r\n\r\n        if (this._engine.getCaps().vertexArrayObject) {\r\n            this._vertexArrayObject = null;\r\n        }\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n\r\n        // Creation queue\r\n        this._lifeTimeCreation = {\r\n            process: _CreateLifetimeData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        this._positionCreation = {\r\n            process: _CreatePositionData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._positionCreation, this._lifeTimeCreation);\r\n\r\n        this._directionCreation = {\r\n            process: _CreateDirectionData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._directionCreation, this._positionCreation);\r\n\r\n        this._emitPowerCreation = {\r\n            process: _CreateEmitPowerData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._emitPowerCreation, this._directionCreation);\r\n\r\n        this._sizeCreation = {\r\n            process: _CreateSizeData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._sizeCreation, this._emitPowerCreation);\r\n\r\n        this._angleCreation = {\r\n            process: _CreateAngleData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._angleCreation, this._sizeCreation);\r\n\r\n        this._colorCreation = {\r\n            process: _CreateColorData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._colorCreation, this._angleCreation);\r\n\r\n        this._colorDeadCreation = {\r\n            process: _CreateColorDeadData,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n        _ConnectAfter(this._colorDeadCreation, this._colorCreation);\r\n\r\n        this._createQueueStart = this._lifeTimeCreation;\r\n\r\n        // Processing queue\r\n        if (!noUpdateQueue) {\r\n            this._colorProcessing = {\r\n                process: _ProcessColor,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n\r\n            this._angularSpeedProcessing = {\r\n                process: _ProcessAngularSpeed,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._angularSpeedProcessing, this._colorProcessing);\r\n\r\n            this._directionProcessing = {\r\n                process: _ProcessDirection,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._directionProcessing, this._angularSpeedProcessing);\r\n\r\n            this._positionProcessing = {\r\n                process: _ProcessPosition,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._positionProcessing, this._directionProcessing);\r\n\r\n            this._gravityProcessing = {\r\n                process: _ProcessGravity,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n\r\n            _ConnectAfter(this._gravityProcessing, this._positionProcessing);\r\n\r\n            this._updateQueueStart = this._colorProcessing;\r\n        }\r\n\r\n        this._isAnimationSheetEnabled = isAnimationSheetEnabled;\r\n\r\n        // Setup the default processing configuration to the scene.\r\n        this._attachImageProcessingConfiguration(null);\r\n\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        this._customWrappers = { 0: new DrawWrapper(this._engine) };\r\n        this._customWrappers[0]!.effect = customEffect;\r\n\r\n        this._drawWrappers = [];\r\n        this._useInstancing = this._engine.getCaps().instancedArrays;\r\n\r\n        this._createIndexBuffer();\r\n        this._createVertexBuffers();\r\n\r\n        // Default emitter type\r\n        this.particleEmitterType = new BoxParticleEmitter();\r\n\r\n        // Update\r\n        this.updateFunction = (particles: Particle[]): void => {\r\n            if (this.noiseTexture) {\r\n                // We need to get texture data back to CPU\r\n                this._noiseTextureSize = this.noiseTexture.getSize();\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                this.noiseTexture.getContent()?.then((data) => {\r\n                    this._noiseTextureData = data as Uint8Array;\r\n                });\r\n            }\r\n\r\n            const sameParticleArray = particles === this._particles;\r\n\r\n            for (let index = 0; index < particles.length; index++) {\r\n                const particle = particles[index];\r\n\r\n                this._tempScaledUpdateSpeed = this._scaledUpdateSpeed;\r\n                const previousAge = particle.age;\r\n                particle.age += this._tempScaledUpdateSpeed;\r\n\r\n                // Evaluate step to death\r\n                if (particle.age > particle.lifeTime) {\r\n                    const diff = particle.age - previousAge;\r\n                    const oldDiff = particle.lifeTime - previousAge;\r\n\r\n                    this._tempScaledUpdateSpeed = (oldDiff * this._tempScaledUpdateSpeed) / diff;\r\n\r\n                    particle.age = particle.lifeTime;\r\n                }\r\n\r\n                this._ratio = particle.age / particle.lifeTime;\r\n                particle._properties.directionScale = this._tempScaledUpdateSpeed;\r\n\r\n                // Processing queue\r\n                let currentQueueItem = this._updateQueueStart;\r\n\r\n                while (currentQueueItem) {\r\n                    currentQueueItem.process(particle, this);\r\n                    currentQueueItem = currentQueueItem.nextItem;\r\n                }\r\n\r\n                if (this._isAnimationSheetEnabled && !noUpdateQueue) {\r\n                    particle.updateCellIndex();\r\n                }\r\n\r\n                // Update the position of the attached sub-emitters to match their attached particle\r\n                particle._inheritParticleInfoToSubEmitters();\r\n\r\n                if (particle.age >= particle.lifeTime) {\r\n                    // Recycle by swapping with last particle\r\n                    this._emitFromParticle(particle);\r\n                    if (particle._properties.attachedSubEmitters) {\r\n                        for (const subEmitter of particle._properties.attachedSubEmitters) {\r\n                            subEmitter.particleSystem.disposeOnStop = true;\r\n                            subEmitter.particleSystem.stop();\r\n                        }\r\n                        particle._properties.attachedSubEmitters = null;\r\n                    }\r\n                    this.recycleParticle(particle);\r\n                    if (sameParticleArray) {\r\n                        index--;\r\n                    }\r\n                    continue;\r\n                }\r\n            }\r\n        };\r\n    }\r\n\r\n    /** @internal */\r\n    public _emitFromParticle: (particle: Particle) => void = (_particle) => {\r\n        // Do nothing\r\n    };\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @param _serializeTexture Whether to serialize the texture information\r\n     */\r\n    serialize(_serializeTexture: boolean) {\r\n        throw new Error(\"Method not implemented.\");\r\n    }\r\n\r\n    /**\r\n     * Clones the particle system.\r\n     * @param name The name of the cloned object\r\n     * @param newEmitter The new emitter to use\r\n     * @param _cloneTexture Also clone the textures if true\r\n     */\r\n    public clone(name: string, newEmitter: any, _cloneTexture = false): ThinParticleSystem {\r\n        throw new Error(\"Method not implemented.\");\r\n    }\r\n\r\n    private _syncLifeTimeCreation() {\r\n        if (this.targetStopDuration && this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {\r\n            this._lifeTimeCreation.process = _CreateLifeGradientsData;\r\n            return;\r\n        }\r\n\r\n        this._lifeTimeCreation.process = _CreateLifetimeData;\r\n    }\r\n\r\n    private _syncStartSizeCreation() {\r\n        if (this._startSizeGradients && this._startSizeGradients[0] && this.targetStopDuration) {\r\n            if (!this._startSizeCreation) {\r\n                this._startSizeCreation = {\r\n                    process: _CreateStartSizeGradientsData,\r\n                    previousItem: null,\r\n                    nextItem: null,\r\n                };\r\n                _ConnectAfter(this._startSizeCreation, this._sizeCreation);\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (this._startSizeCreation) {\r\n            _RemoveFromQueue(this._startSizeCreation);\r\n            this._startSizeCreation = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The amount of time the particle system is running (depends of the overall update speed).\r\n     */\r\n    public override get targetStopDuration(): number {\r\n        return this._targetStopDuration;\r\n    }\r\n\r\n    public override set targetStopDuration(value: number) {\r\n        if (this.targetStopDuration === value) {\r\n            return;\r\n        }\r\n\r\n        this._targetStopDuration = value;\r\n\r\n        this._syncLifeTimeCreation();\r\n        this._syncStartSizeCreation();\r\n    }\r\n\r\n    /**\r\n     * Adds a new life time gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the life time factor to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addLifeTimeGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._lifeTimeGradients) {\r\n            this._lifeTimeGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);\r\n\r\n        this._syncLifeTimeCreation();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific life time gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeLifeTimeGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._lifeTimeGradients, gradient);\r\n\r\n        this._syncLifeTimeCreation();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new size gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the size factor to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addSizeGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._sizeGradients) {\r\n            this._sizeGradients = [];\r\n        }\r\n\r\n        if (this._sizeGradients.length === 0) {\r\n            this._sizeCreation.process = _CreateSizeGradientsData;\r\n\r\n            this._sizeGradientProcessing = {\r\n                process: _ProcessSizeGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectBefore(this._sizeGradientProcessing, this._gravityProcessing);\r\n        }\r\n\r\n        this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific size gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeSizeGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._sizeGradients, gradient);\r\n\r\n        if (this._sizeGradients?.length === 0) {\r\n            _RemoveFromQueue(this._sizeGradientProcessing);\r\n            this._sizeCreation.process = _CreateSizeData;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new color remap gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param min defines the color remap minimal range\r\n     * @param max defines the color remap maximal range\r\n     * @returns the current particle system\r\n     */\r\n    public addColorRemapGradient(gradient: number, min: number, max: number): IParticleSystem {\r\n        if (!this._colorRemapGradients) {\r\n            this._colorRemapGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._colorRemapGradients, gradient, min, max);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific color remap gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeColorRemapGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._colorRemapGradients, gradient);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new alpha remap gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param min defines the alpha remap minimal range\r\n     * @param max defines the alpha remap maximal range\r\n     * @returns the current particle system\r\n     */\r\n    public addAlphaRemapGradient(gradient: number, min: number, max: number): IParticleSystem {\r\n        if (!this._alphaRemapGradients) {\r\n            this._alphaRemapGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._alphaRemapGradients, gradient, min, max);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific alpha remap gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeAlphaRemapGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._alphaRemapGradients, gradient);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new angular speed gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the angular speed  to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addAngularSpeedGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._angularSpeedGradients) {\r\n            this._angularSpeedGradients = [];\r\n        }\r\n\r\n        if (this._angularSpeedGradients.length === 0) {\r\n            this._angleCreation.process = _CreateAngleGradientsData;\r\n\r\n            this._angularSpeedGradientProcessing = {\r\n                process: _ProcessAngularSpeedGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n\r\n            _ConnectBefore(this._angularSpeedGradientProcessing, this._angularSpeedProcessing);\r\n        }\r\n\r\n        this._addFactorGradient(this._angularSpeedGradients, gradient, factor, factor2);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific angular speed gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeAngularSpeedGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._angularSpeedGradients, gradient);\r\n\r\n        if (this._angularSpeedGradients?.length === 0) {\r\n            this._angleCreation.process = _CreateAngleData;\r\n            _RemoveFromQueue(this._angularSpeedGradientProcessing);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new velocity gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the velocity to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addVelocityGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._velocityGradients) {\r\n            this._velocityGradients = [];\r\n        }\r\n\r\n        if (this._velocityGradients.length === 0) {\r\n            this._velocityCreation = {\r\n                process: _CreateVelocityGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._velocityCreation, this._angleCreation);\r\n\r\n            this._velocityGradientProcessing = {\r\n                process: _ProcessVelocityGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectBefore(this._velocityGradientProcessing, this._directionProcessing);\r\n        }\r\n\r\n        this._addFactorGradient(this._velocityGradients, gradient, factor, factor2);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific velocity gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeVelocityGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._velocityGradients, gradient);\r\n\r\n        if (this._velocityGradients?.length === 0) {\r\n            _RemoveFromQueue(this._velocityCreation);\r\n            _RemoveFromQueue(this._velocityGradientProcessing);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new limit velocity gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the limit velocity value to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addLimitVelocityGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._limitVelocityGradients) {\r\n            this._limitVelocityGradients = [];\r\n        }\r\n\r\n        if (this._limitVelocityGradients.length === 0) {\r\n            this._limitVelocityCreation = {\r\n                process: _CreateLimitVelocityGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._limitVelocityCreation, this._angleCreation);\r\n\r\n            this._limitVelocityGradientProcessing = {\r\n                process: _ProcessLimitVelocityGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._limitVelocityGradientProcessing, this._directionProcessing);\r\n        }\r\n\r\n        this._addFactorGradient(this._limitVelocityGradients, gradient, factor, factor2);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific limit velocity gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeLimitVelocityGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._limitVelocityGradients, gradient);\r\n\r\n        if (this._limitVelocityGradients?.length === 0) {\r\n            _RemoveFromQueue(this._limitVelocityCreation);\r\n            _RemoveFromQueue(this._limitVelocityGradientProcessing);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new drag gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the drag value to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addDragGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._dragGradients) {\r\n            this._dragGradients = [];\r\n        }\r\n\r\n        if (this._dragGradients.length === 0) {\r\n            this._dragCreation = {\r\n                process: _CreateDragData,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectBefore(this._dragCreation, this._colorDeadCreation);\r\n\r\n            this._dragGradientProcessing = {\r\n                process: _ProcessDragGradients,\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectBefore(this._dragGradientProcessing, this._positionProcessing);\r\n        }\r\n\r\n        this._addFactorGradient(this._dragGradients, gradient, factor, factor2);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific drag gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeDragGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._dragGradients, gradient);\r\n\r\n        if (this._dragGradients?.length === 0) {\r\n            _RemoveFromQueue(this._dragCreation);\r\n            _RemoveFromQueue(this._dragGradientProcessing);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new start size gradient (please note that this will only work if you set the targetStopDuration property)\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the start size value to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addStartSizeGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._startSizeGradients) {\r\n            this._startSizeGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);\r\n\r\n        this._syncStartSizeCreation();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific start size gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeStartSizeGradient(gradient: number): IParticleSystem {\r\n        this._removeFactorGradient(this._startSizeGradients, gradient);\r\n\r\n        this._syncStartSizeCreation();\r\n\r\n        return this;\r\n    }\r\n\r\n    private _createRampGradientTexture() {\r\n        if (!this._rampGradients || !this._rampGradients.length || this._rampGradientsTexture || !this._scene) {\r\n            return;\r\n        }\r\n\r\n        const data = new Uint8Array(this._rawTextureWidth * 4);\r\n        const tmpColor = TmpColors.Color3[0];\r\n\r\n        for (let x = 0; x < this._rawTextureWidth; x++) {\r\n            const ratio = x / this._rawTextureWidth;\r\n\r\n            GradientHelper.GetCurrentGradient(ratio, this._rampGradients, (currentGradient, nextGradient, scale) => {\r\n                Color3.LerpToRef((<Color3Gradient>currentGradient).color, (<Color3Gradient>nextGradient).color, scale, tmpColor);\r\n                data[x * 4] = tmpColor.r * 255;\r\n                data[x * 4 + 1] = tmpColor.g * 255;\r\n                data[x * 4 + 2] = tmpColor.b * 255;\r\n                data[x * 4 + 3] = 255;\r\n            });\r\n        }\r\n\r\n        this._rampGradientsTexture = RawTexture.CreateRGBATexture(data, this._rawTextureWidth, 1, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n    }\r\n\r\n    /**\r\n     * Gets the current list of ramp gradients.\r\n     * You must use addRampGradient and removeRampGradient to update this list\r\n     * @returns the list of ramp gradients\r\n     */\r\n    public getRampGradients(): Nullable<Array<Color3Gradient>> {\r\n        return this._rampGradients;\r\n    }\r\n\r\n    /** Force the system to rebuild all gradients that need to be resync */\r\n    public forceRefreshGradients() {\r\n        this._syncRampGradientTexture();\r\n    }\r\n\r\n    private _syncRampGradientTexture() {\r\n        if (!this._rampGradients) {\r\n            return;\r\n        }\r\n\r\n        this._rampGradients.sort((a, b) => {\r\n            if (a.gradient < b.gradient) {\r\n                return -1;\r\n            } else if (a.gradient > b.gradient) {\r\n                return 1;\r\n            }\r\n\r\n            return 0;\r\n        });\r\n\r\n        if (this._rampGradientsTexture) {\r\n            this._rampGradientsTexture.dispose();\r\n            this._rampGradientsTexture = null;\r\n        }\r\n\r\n        this._createRampGradientTexture();\r\n    }\r\n\r\n    /**\r\n     * Adds a new ramp gradient used to remap particle colors\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param color defines the color to affect to the specified gradient\r\n     * @returns the current particle system\r\n     */\r\n    public addRampGradient(gradient: number, color: Color3): ThinParticleSystem {\r\n        if (!this._rampGradients) {\r\n            this._rampGradients = [];\r\n        }\r\n\r\n        const rampGradient = new Color3Gradient(gradient, color);\r\n        this._rampGradients.push(rampGradient);\r\n\r\n        this._syncRampGradientTexture();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific ramp gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeRampGradient(gradient: number): ThinParticleSystem {\r\n        this._removeGradientAndTexture(gradient, this._rampGradients, this._rampGradientsTexture);\r\n        this._rampGradientsTexture = null;\r\n\r\n        if (this._rampGradients && this._rampGradients.length > 0) {\r\n            this._createRampGradientTexture();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new color gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param color1 defines the color to affect to the specified gradient\r\n     * @param color2 defines an additional color used to define a range ([color, color2]) with main color to pick the final color from\r\n     * @returns this particle system\r\n     */\r\n    public addColorGradient(gradient: number, color1: Color4, color2?: Color4): IParticleSystem {\r\n        if (!this._colorGradients) {\r\n            this._colorGradients = [];\r\n        }\r\n\r\n        if (this._colorGradients.length === 0) {\r\n            this._colorCreation.process = _CreateColorGradientsData;\r\n            this._colorProcessing.process = _ProcessColorGradients;\r\n        }\r\n\r\n        const colorGradient = new ColorGradient(gradient, color1, color2);\r\n        this._colorGradients.push(colorGradient);\r\n\r\n        this._colorGradients.sort((a, b) => {\r\n            if (a.gradient < b.gradient) {\r\n                return -1;\r\n            } else if (a.gradient > b.gradient) {\r\n                return 1;\r\n            }\r\n\r\n            return 0;\r\n        });\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific color gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns this particle system\r\n     */\r\n    public removeColorGradient(gradient: number): IParticleSystem {\r\n        if (!this._colorGradients) {\r\n            return this;\r\n        }\r\n\r\n        let index = 0;\r\n        for (const colorGradient of this._colorGradients) {\r\n            if (colorGradient.gradient === gradient) {\r\n                this._colorGradients.splice(index, 1);\r\n                break;\r\n            }\r\n            index++;\r\n        }\r\n\r\n        if (this._colorGradients.length === 0) {\r\n            this._colorCreation.process = _CreateColorData;\r\n            this._colorProcessing.process = _ProcessColor;\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Resets the draw wrappers cache\r\n     */\r\n    public resetDrawCache(): void {\r\n        if (!this._drawWrappers) {\r\n            return;\r\n        }\r\n        for (const drawWrappers of this._drawWrappers) {\r\n            if (drawWrappers) {\r\n                for (const drawWrapper of drawWrappers) {\r\n                    drawWrapper?.dispose();\r\n                }\r\n            }\r\n        }\r\n\r\n        this._drawWrappers = [];\r\n    }\r\n\r\n    /** @internal */\r\n    public _fetchR(u: number, v: number, width: number, height: number, pixels: Uint8Array | Uint8ClampedArray): number {\r\n        u = Math.abs(u) * 0.5 + 0.5;\r\n        v = Math.abs(v) * 0.5 + 0.5;\r\n\r\n        const wrappedU = ((u * width) % width) | 0;\r\n        const wrappedV = ((v * height) % height) | 0;\r\n\r\n        const position = (wrappedU + wrappedV * width) * 4;\r\n        return pixels[position] / 255;\r\n    }\r\n\r\n    protected override _reset() {\r\n        this._resetEffect();\r\n    }\r\n\r\n    private _resetEffect() {\r\n        if (this._vertexBuffer) {\r\n            this._vertexBuffer.dispose();\r\n            this._vertexBuffer = null;\r\n        }\r\n\r\n        if (this._spriteBuffer) {\r\n            this._spriteBuffer.dispose();\r\n            this._spriteBuffer = null;\r\n        }\r\n\r\n        if (this._vertexArrayObject) {\r\n            (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObject);\r\n            this._vertexArrayObject = null;\r\n        }\r\n\r\n        this._createVertexBuffers();\r\n    }\r\n\r\n    private _createVertexBuffers() {\r\n        this._vertexBufferSize = this._useInstancing ? 10 : 12;\r\n        if (this._isAnimationSheetEnabled) {\r\n            this._vertexBufferSize += 1;\r\n        }\r\n\r\n        if (\r\n            !this._isBillboardBased ||\r\n            this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED ||\r\n            this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL\r\n        ) {\r\n            this._vertexBufferSize += 3;\r\n        }\r\n\r\n        if (this._useRampGradients) {\r\n            this._vertexBufferSize += 4;\r\n        }\r\n\r\n        const engine = this._engine;\r\n        const vertexSize = this._vertexBufferSize * (this._useInstancing ? 1 : 4);\r\n        this._vertexData = new Float32Array(this._capacity * vertexSize);\r\n        this._vertexBuffer = new Buffer(engine, this._vertexData, true, vertexSize);\r\n\r\n        let dataOffset = 0;\r\n        const positions = this._vertexBuffer.createVertexBuffer(VertexBuffer.PositionKind, dataOffset, 3, this._vertexBufferSize, this._useInstancing);\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = positions;\r\n        dataOffset += 3;\r\n\r\n        const colors = this._vertexBuffer.createVertexBuffer(VertexBuffer.ColorKind, dataOffset, 4, this._vertexBufferSize, this._useInstancing);\r\n        this._vertexBuffers[VertexBuffer.ColorKind] = colors;\r\n        dataOffset += 4;\r\n\r\n        const options = this._vertexBuffer.createVertexBuffer(\"angle\", dataOffset, 1, this._vertexBufferSize, this._useInstancing);\r\n        this._vertexBuffers[\"angle\"] = options;\r\n        dataOffset += 1;\r\n\r\n        const size = this._vertexBuffer.createVertexBuffer(\"size\", dataOffset, 2, this._vertexBufferSize, this._useInstancing);\r\n        this._vertexBuffers[\"size\"] = size;\r\n        dataOffset += 2;\r\n\r\n        if (this._isAnimationSheetEnabled) {\r\n            const cellIndexBuffer = this._vertexBuffer.createVertexBuffer(\"cellIndex\", dataOffset, 1, this._vertexBufferSize, this._useInstancing);\r\n            this._vertexBuffers[\"cellIndex\"] = cellIndexBuffer;\r\n            dataOffset += 1;\r\n        }\r\n\r\n        if (\r\n            !this._isBillboardBased ||\r\n            this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED ||\r\n            this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL\r\n        ) {\r\n            const directionBuffer = this._vertexBuffer.createVertexBuffer(\"direction\", dataOffset, 3, this._vertexBufferSize, this._useInstancing);\r\n            this._vertexBuffers[\"direction\"] = directionBuffer;\r\n            dataOffset += 3;\r\n        }\r\n\r\n        if (this._useRampGradients) {\r\n            const rampDataBuffer = this._vertexBuffer.createVertexBuffer(\"remapData\", dataOffset, 4, this._vertexBufferSize, this._useInstancing);\r\n            this._vertexBuffers[\"remapData\"] = rampDataBuffer;\r\n            dataOffset += 4;\r\n        }\r\n\r\n        let offsets: VertexBuffer;\r\n        if (this._useInstancing) {\r\n            const spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\r\n            this._spriteBuffer = new Buffer(engine, spriteData, false, 2);\r\n            offsets = this._spriteBuffer.createVertexBuffer(\"offset\", 0, 2);\r\n        } else {\r\n            offsets = this._vertexBuffer.createVertexBuffer(\"offset\", dataOffset, 2, this._vertexBufferSize, this._useInstancing);\r\n        }\r\n        this._vertexBuffers[\"offset\"] = offsets;\r\n\r\n        this.resetDrawCache();\r\n    }\r\n\r\n    private _createIndexBuffer() {\r\n        if (this._useInstancing) {\r\n            this._linesIndexBufferUseInstancing = this._engine.createIndexBuffer(new Uint32Array([0, 1, 1, 3, 3, 2, 2, 0, 0, 3]));\r\n            return;\r\n        }\r\n        const indices = [];\r\n        const indicesWireframe = [];\r\n        let index = 0;\r\n        for (let count = 0; count < this._capacity; count++) {\r\n            indices.push(index);\r\n            indices.push(index + 1);\r\n            indices.push(index + 2);\r\n            indices.push(index);\r\n            indices.push(index + 2);\r\n            indices.push(index + 3);\r\n            indicesWireframe.push(index, index + 1, index + 1, index + 2, index + 2, index + 3, index + 3, index, index, index + 3);\r\n            index += 4;\r\n        }\r\n\r\n        this._indexBuffer = this._engine.createIndexBuffer(indices);\r\n        this._linesIndexBuffer = this._engine.createIndexBuffer(indicesWireframe);\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum number of particles active at the same time.\r\n     * @returns The max number of active particles.\r\n     */\r\n    public getCapacity(): number {\r\n        return this._capacity;\r\n    }\r\n\r\n    /**\r\n     * Gets whether there are still active particles in the system.\r\n     * @returns True if it is alive, otherwise false.\r\n     */\r\n    public isAlive(): boolean {\r\n        return this._alive;\r\n    }\r\n\r\n    /**\r\n     * Gets if the system has been started. (Note: this will still be true after stop is called)\r\n     * @returns True if it has been started, otherwise false.\r\n     */\r\n    public isStarted(): boolean {\r\n        return this._started;\r\n    }\r\n\r\n    /** @internal */\r\n    public _preStart() {\r\n        // Do nothing\r\n    }\r\n\r\n    /**\r\n     * Starts the particle system and begins to emit\r\n     * @param delay defines the delay in milliseconds before starting the system (this.startDelay by default)\r\n     */\r\n    public start(delay = this.startDelay): void {\r\n        if (!this.targetStopDuration && this._hasTargetStopDurationDependantGradient()) {\r\n            throw \"Particle system started with a targetStopDuration dependant gradient (eg. startSizeGradients) but no targetStopDuration set\";\r\n        }\r\n        if (delay) {\r\n            this.startDelay = delay;\r\n            setTimeout(() => {\r\n                this.start(0);\r\n            }, delay);\r\n            return;\r\n        }\r\n        this._started = true;\r\n        this._stopped = false;\r\n        this._actualFrame = 0;\r\n\r\n        this._preStart();\r\n\r\n        // Reset emit gradient so it acts the same on every start\r\n        if (this._emitRateGradients) {\r\n            if (this._emitRateGradients.length > 0) {\r\n                this._currentEmitRateGradient = this._emitRateGradients[0];\r\n                this._currentEmitRate1 = this._currentEmitRateGradient.getFactor();\r\n                this._currentEmitRate2 = this._currentEmitRate1;\r\n            }\r\n            if (this._emitRateGradients.length > 1) {\r\n                this._currentEmitRate2 = this._emitRateGradients[1].getFactor();\r\n            }\r\n        }\r\n        // Reset start size gradient so it acts the same on every start\r\n        if (this._startSizeGradients) {\r\n            if (this._startSizeGradients.length > 0) {\r\n                this._currentStartSizeGradient = this._startSizeGradients[0];\r\n                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();\r\n                this._currentStartSize2 = this._currentStartSize1;\r\n            }\r\n            if (this._startSizeGradients.length > 1) {\r\n                this._currentStartSize2 = this._startSizeGradients[1].getFactor();\r\n            }\r\n        }\r\n\r\n        if (this.preWarmCycles) {\r\n            if (this.emitter?.getClassName().indexOf(\"Mesh\") !== -1) {\r\n                (this.emitter as any).computeWorldMatrix(true);\r\n            }\r\n\r\n            // Ensure the scene transform matrix is up-to-date so matrix-dependent\r\n            // update steps (notably flow map sampling, which projects world positions\r\n            // into screen space) produce correct results during pre-warm, before any\r\n            // render has had a chance to populate the matrix.\r\n            this._scene?.updateTransformMatrix();\r\n\r\n            const noiseTextureAsProcedural = this.noiseTexture as ProceduralTexture;\r\n\r\n            if (noiseTextureAsProcedural && noiseTextureAsProcedural.onGeneratedObservable) {\r\n                noiseTextureAsProcedural.onGeneratedObservable.addOnce(() => {\r\n                    setTimeout(() => {\r\n                        for (let index = 0; index < this.preWarmCycles; index++) {\r\n                            this.animate(true);\r\n                            noiseTextureAsProcedural.render();\r\n                        }\r\n                    });\r\n                });\r\n            } else {\r\n                for (let index = 0; index < this.preWarmCycles; index++) {\r\n                    this.animate(true);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Animations\r\n        if (this.beginAnimationOnStart && this.animations && this.animations.length > 0 && this._scene) {\r\n            this._scene.beginAnimation(this, this.beginAnimationFrom, this.beginAnimationTo, this.beginAnimationLoop);\r\n        }\r\n\r\n        this.onStartedObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Stops the particle system.\r\n     * @param stopSubEmitters if true it will stop the current system and all created sub-Systems if false it will stop the current root system only, this param is used by the root particle system only. The default value is true.\r\n     */\r\n    public stop(stopSubEmitters = true): void {\r\n        if (this._stopped) {\r\n            return;\r\n        }\r\n\r\n        this.onStoppedObservable.notifyObservers(this);\r\n\r\n        this._stopped = true;\r\n\r\n        this._postStop(stopSubEmitters);\r\n    }\r\n\r\n    /** @internal */\r\n    public _postStop(_stopSubEmitters: boolean) {\r\n        // Do nothing\r\n    }\r\n\r\n    // Animation sheet\r\n\r\n    /**\r\n     * Remove all active particles\r\n     */\r\n    public reset(): void {\r\n        this._stockParticles.length = 0;\r\n        this._particles.length = 0;\r\n    }\r\n\r\n    /**\r\n     * @internal (for internal use only)\r\n     */\r\n    public _appendParticleVertex(index: number, particle: Particle, offsetX: number, offsetY: number): void {\r\n        let offset = index * this._vertexBufferSize;\r\n\r\n        const floatingOriginOffset = TmpVectors.Vector3[0].copyFrom(this._scene?.floatingOriginOffset || Vector3.ZeroReadOnly);\r\n        this._vertexData[offset++] = particle.position.x + this.worldOffset.x - floatingOriginOffset.x;\r\n        this._vertexData[offset++] = particle.position.y + this.worldOffset.y - floatingOriginOffset.y;\r\n        this._vertexData[offset++] = particle.position.z + this.worldOffset.z - floatingOriginOffset.z;\r\n        this._vertexData[offset++] = particle.color.r;\r\n        this._vertexData[offset++] = particle.color.g;\r\n        this._vertexData[offset++] = particle.color.b;\r\n        this._vertexData[offset++] = particle.color.a;\r\n        this._vertexData[offset++] = particle.angle;\r\n\r\n        this._vertexData[offset++] = particle.scale.x * particle.size;\r\n        this._vertexData[offset++] = particle.scale.y * particle.size;\r\n\r\n        if (this._isAnimationSheetEnabled) {\r\n            this._vertexData[offset++] = particle.cellIndex;\r\n        }\r\n\r\n        if (!this._isBillboardBased) {\r\n            if (particle._properties.initialDirection) {\r\n                let initialDirection = particle._properties.initialDirection;\r\n                if (this.isLocal) {\r\n                    Vector3.TransformNormalToRef(initialDirection, this._emitterWorldMatrix, TmpVectors.Vector3[0]);\r\n                    initialDirection = TmpVectors.Vector3[0];\r\n                }\r\n                if (initialDirection.x === 0 && initialDirection.z === 0) {\r\n                    initialDirection.x = 0.001;\r\n                }\r\n\r\n                this._vertexData[offset++] = initialDirection.x;\r\n                this._vertexData[offset++] = initialDirection.y;\r\n                this._vertexData[offset++] = initialDirection.z;\r\n            } else {\r\n                let direction = particle.direction;\r\n                if (this.isLocal) {\r\n                    Vector3.TransformNormalToRef(direction, this._emitterWorldMatrix, TmpVectors.Vector3[0]);\r\n                    direction = TmpVectors.Vector3[0];\r\n                }\r\n\r\n                if (direction.x === 0 && direction.z === 0) {\r\n                    direction.x = 0.001;\r\n                }\r\n                this._vertexData[offset++] = direction.x;\r\n                this._vertexData[offset++] = direction.y;\r\n                this._vertexData[offset++] = direction.z;\r\n            }\r\n        } else if (this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED || this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL) {\r\n            this._vertexData[offset++] = particle.direction.x;\r\n            this._vertexData[offset++] = particle.direction.y;\r\n            this._vertexData[offset++] = particle.direction.z;\r\n        }\r\n\r\n        if (this._useRampGradients && particle.remapData) {\r\n            this._vertexData[offset++] = particle.remapData.x;\r\n            this._vertexData[offset++] = particle.remapData.y;\r\n            this._vertexData[offset++] = particle.remapData.z;\r\n            this._vertexData[offset++] = particle.remapData.w;\r\n        }\r\n\r\n        if (!this._useInstancing) {\r\n            if (this._isAnimationSheetEnabled) {\r\n                if (offsetX === 0) {\r\n                    offsetX = this._epsilon;\r\n                } else if (offsetX === 1) {\r\n                    offsetX = 1 - this._epsilon;\r\n                }\r\n\r\n                if (offsetY === 0) {\r\n                    offsetY = this._epsilon;\r\n                } else if (offsetY === 1) {\r\n                    offsetY = 1 - this._epsilon;\r\n                }\r\n            }\r\n\r\n            this._vertexData[offset++] = offsetX;\r\n            this._vertexData[offset] = offsetY;\r\n        }\r\n    }\r\n\r\n    // start of sub system methods\r\n\r\n    /**\r\n     * \"Recycles\" one of the particle by copying it back to the \"stock\" of particles and removing it from the active list.\r\n     * Its lifetime will start back at 0.\r\n     * @param particle\r\n     */\r\n    public recycleParticle: (particle: Particle) => void = (particle) => {\r\n        // move particle from activeParticle list to stock particles\r\n        const lastParticle = <Particle>this._particles.pop();\r\n        if (lastParticle !== particle) {\r\n            lastParticle.copyTo(particle);\r\n        }\r\n        lastParticle.metadata = null;\r\n        this._stockParticles.push(lastParticle);\r\n    };\r\n\r\n    private _createParticle: () => Particle = () => {\r\n        let particle: Particle;\r\n        if (this._stockParticles.length !== 0) {\r\n            particle = <Particle>this._stockParticles.pop();\r\n            particle._reset();\r\n        } else {\r\n            particle = new Particle(this);\r\n        }\r\n\r\n        this._prepareParticle(particle);\r\n        return particle;\r\n    };\r\n\r\n    /** @internal */\r\n    public _prepareParticle(_particle: Particle) {\r\n        //Do nothing\r\n    }\r\n\r\n    private _createNewOnes(newParticles: number) {\r\n        // Add new ones\r\n        let particle: Particle;\r\n        for (let index = 0; index < newParticles; index++) {\r\n            if (this._particles.length === this._capacity) {\r\n                break;\r\n            }\r\n\r\n            particle = this._createParticle();\r\n\r\n            this._particles.push(particle);\r\n\r\n            // Creation queue\r\n            let currentQueueItem = this._createQueueStart;\r\n\r\n            while (currentQueueItem) {\r\n                currentQueueItem.process(particle, this);\r\n                currentQueueItem = currentQueueItem.nextItem;\r\n            }\r\n\r\n            // Update the position of the attached sub-emitters to match their attached particle\r\n            particle._inheritParticleInfoToSubEmitters();\r\n        }\r\n    }\r\n\r\n    private _update(newParticles: number): void {\r\n        // Update current\r\n        this._alive = this._particles.length > 0;\r\n\r\n        if ((<AbstractMesh>this.emitter).position) {\r\n            const emitterMesh = <AbstractMesh>this.emitter;\r\n            this._emitterWorldMatrix = emitterMesh.getWorldMatrix();\r\n        } else {\r\n            const emitterPosition = <Vector3>this.emitter;\r\n            this._emitterWorldMatrix = Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);\r\n        }\r\n\r\n        this._emitterWorldMatrix.invertToRef(this._emitterInverseWorldMatrix);\r\n        this.updateFunction(this._particles);\r\n\r\n        this._createNewOnes(newParticles);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _GetAttributeNamesOrOptions(isAnimationSheetEnabled = false, isBillboardBased = false, useRampGradients = false): string[] {\r\n        const attributeNamesOrOptions = [VertexBuffer.PositionKind, VertexBuffer.ColorKind, \"angle\", \"offset\", \"size\"];\r\n\r\n        if (isAnimationSheetEnabled) {\r\n            attributeNamesOrOptions.push(\"cellIndex\");\r\n        }\r\n\r\n        if (!isBillboardBased) {\r\n            attributeNamesOrOptions.push(\"direction\");\r\n        }\r\n\r\n        if (useRampGradients) {\r\n            attributeNamesOrOptions.push(\"remapData\");\r\n        }\r\n\r\n        return attributeNamesOrOptions;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _GetEffectCreationOptions(isAnimationSheetEnabled = false, useLogarithmicDepth = false, applyFog = false): string[] {\r\n        const effectCreationOption = [\"invView\", \"view\", \"projection\", \"textureMask\", \"translationPivot\", \"eyePosition\"];\r\n\r\n        AddClipPlaneUniforms(effectCreationOption);\r\n\r\n        if (isAnimationSheetEnabled) {\r\n            effectCreationOption.push(\"particlesInfos\");\r\n        }\r\n        if (useLogarithmicDepth) {\r\n            effectCreationOption.push(\"logarithmicDepthConstant\");\r\n        }\r\n\r\n        if (applyFog) {\r\n            effectCreationOption.push(\"vFogInfos\");\r\n            effectCreationOption.push(\"vFogColor\");\r\n        }\r\n\r\n        return effectCreationOption;\r\n    }\r\n\r\n    /**\r\n     * Fill the defines array according to the current settings of the particle system\r\n     * @param defines Array to be updated\r\n     * @param blendMode blend mode to take into account when updating the array\r\n     * @param fillImageProcessing fills the image processing defines\r\n     */\r\n    public fillDefines(defines: Array<string>, blendMode: number, fillImageProcessing: boolean = true): void {\r\n        if (this._scene) {\r\n            PrepareStringDefinesForClipPlanes(this, this._scene, defines);\r\n            if (this.applyFog && this._scene.fogEnabled && this._scene.fogMode !== Constants.FOGMODE_NONE) {\r\n                defines.push(\"#define FOG\");\r\n            }\r\n        }\r\n\r\n        if (this._isAnimationSheetEnabled) {\r\n            defines.push(\"#define ANIMATESHEET\");\r\n        }\r\n\r\n        if (this.useLogarithmicDepth) {\r\n            defines.push(\"#define LOGARITHMICDEPTH\");\r\n        }\r\n\r\n        if (blendMode === BaseParticleSystem.BLENDMODE_MULTIPLY) {\r\n            defines.push(\"#define BLENDMULTIPLYMODE\");\r\n        }\r\n\r\n        if (this.isLocal) {\r\n            defines.push(\"#define LOCAL\");\r\n        }\r\n\r\n        if (this._useRampGradients) {\r\n            defines.push(\"#define RAMPGRADIENT\");\r\n        }\r\n\r\n        if (this._isBillboardBased) {\r\n            defines.push(\"#define BILLBOARD\");\r\n\r\n            switch (this.billboardMode) {\r\n                case Constants.PARTICLES_BILLBOARDMODE_Y:\r\n                    defines.push(\"#define BILLBOARDY\");\r\n                    break;\r\n                case Constants.PARTICLES_BILLBOARDMODE_STRETCHED:\r\n                case Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL:\r\n                    defines.push(\"#define BILLBOARDSTRETCHED\");\r\n                    if (this.billboardMode === Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL) {\r\n                        defines.push(\"#define BILLBOARDSTRETCHED_LOCAL\");\r\n                    }\r\n                    break;\r\n                case Constants.PARTICLES_BILLBOARDMODE_ALL:\r\n                    defines.push(\"#define BILLBOARDMODE_ALL\");\r\n                    break;\r\n                default:\r\n                    break;\r\n            }\r\n        }\r\n\r\n        if (fillImageProcessing && this._imageProcessingConfiguration) {\r\n            this._imageProcessingConfiguration.prepareDefines(this._imageProcessingConfigurationDefines);\r\n            defines.push(this._imageProcessingConfigurationDefines.toString());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Fill the uniforms, attributes and samplers arrays according to the current settings of the particle system\r\n     * @param uniforms Uniforms array to fill\r\n     * @param attributes Attributes array to fill\r\n     * @param samplers Samplers array to fill\r\n     */\r\n    public fillUniformsAttributesAndSamplerNames(uniforms: Array<string>, attributes: Array<string>, samplers: Array<string>) {\r\n        attributes.push(\r\n            ...ThinParticleSystem._GetAttributeNamesOrOptions(\r\n                this._isAnimationSheetEnabled,\r\n                this._isBillboardBased &&\r\n                    this.billboardMode !== Constants.PARTICLES_BILLBOARDMODE_STRETCHED &&\r\n                    this.billboardMode !== Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL,\r\n                this._useRampGradients\r\n            )\r\n        );\r\n\r\n        uniforms.push(...ThinParticleSystem._GetEffectCreationOptions(this._isAnimationSheetEnabled, this.useLogarithmicDepth, this.applyFog));\r\n\r\n        samplers.push(\"diffuseSampler\", \"rampSampler\");\r\n\r\n        if (this._imageProcessingConfiguration) {\r\n            PrepareUniformsForImageProcessing(uniforms, this._imageProcessingConfigurationDefines);\r\n            PrepareSamplersForImageProcessing(samplers, this._imageProcessingConfigurationDefines);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    private _getWrapper(blendMode: number): DrawWrapper {\r\n        const customWrapper = this._getCustomDrawWrapper(blendMode);\r\n\r\n        if (customWrapper?.effect) {\r\n            return customWrapper;\r\n        }\r\n\r\n        const defines: Array<string> = [];\r\n\r\n        this.fillDefines(defines, blendMode);\r\n\r\n        // Effect\r\n        const currentRenderPassId = this._engine._features.supportRenderPasses ? this._engine.currentRenderPassId : Constants.RENDERPASS_MAIN;\r\n        const geometryRendering = MaterialHelperGeometryRendering._PrepareStringDefines(currentRenderPassId, defines);\r\n        const geometryRenderingConfiguration = geometryRendering ? MaterialHelperGeometryRendering.GetConfiguration(currentRenderPassId) : undefined;\r\n        let drawWrappers = this._drawWrappers[currentRenderPassId];\r\n        if (!drawWrappers) {\r\n            drawWrappers = this._drawWrappers[currentRenderPassId] = [];\r\n            if (currentRenderPassId !== Constants.RENDERPASS_MAIN && !this._renderPassObserver) {\r\n                this._renderPassObserver = (this._engine._onReleaseRenderPassObservable ??= new Observable<number>()).add((id) => {\r\n                    const releasedWrappers = this._drawWrappers[id];\r\n                    if (releasedWrappers) {\r\n                        for (const wrapper of releasedWrappers) {\r\n                            wrapper?.dispose();\r\n                        }\r\n                        delete this._drawWrappers[id];\r\n                    }\r\n                });\r\n            }\r\n        }\r\n        let drawWrapper = drawWrappers[blendMode];\r\n        if (!drawWrapper) {\r\n            drawWrapper = new DrawWrapper(this._engine);\r\n            if (drawWrapper.drawContext) {\r\n                drawWrapper.drawContext.useInstancing = this._useInstancing;\r\n            }\r\n            drawWrappers[blendMode] = drawWrapper;\r\n        }\r\n\r\n        const join = defines.join(\"\\n\");\r\n        if (drawWrapper.defines !== join) {\r\n            const attributesNamesOrOptions: Array<string> = [];\r\n            const effectCreationOption: Array<string> = [];\r\n            const samplers: Array<string> = [];\r\n\r\n            this.fillUniformsAttributesAndSamplerNames(effectCreationOption, attributesNamesOrOptions, samplers);\r\n            if (geometryRendering) {\r\n                effectCreationOption.push(\"cameraInfo\", \"objectId\", \"meshBlendTag\", \"geometryZeroAlphaDiscard\");\r\n                if (this.isLocal && geometryRenderingConfiguration?.defines.PREPASS_LOCAL_POSITION_INDEX !== undefined) {\r\n                    effectCreationOption.push(\"inverseEmitterWM\", \"geometryWorldOffset\");\r\n                }\r\n            }\r\n\r\n            drawWrapper.setEffect(\r\n                this._engine.createEffect(\r\n                    \"particles\",\r\n                    <IEffectCreationOptions>{\r\n                        attributes: attributesNamesOrOptions,\r\n                        uniformsNames: effectCreationOption,\r\n                        samplers,\r\n                        defines: join,\r\n                        shaderLanguage: this._shaderLanguage,\r\n                        multiTarget: geometryRendering,\r\n                        indexParameters: geometryRendering ? { buffersCount: geometryRenderingConfiguration?._mrtCount ?? 0 } : undefined,\r\n                    },\r\n                    this._engine\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        return drawWrapper;\r\n    }\r\n\r\n    private _bindGeometryRendering(effect: Effect): void {\r\n        const renderPassId = this._engine._features.supportRenderPasses ? this._engine.currentRenderPassId : Constants.RENDERPASS_MAIN;\r\n        const configuration = MaterialHelperGeometryRendering.GetConfiguration(renderPassId);\r\n        if (!configuration?._defines) {\r\n            return;\r\n        }\r\n\r\n        effect.setFloat(\"objectId\", 0);\r\n        effect.setInt(\"meshBlendTag\", 0);\r\n\r\n        const camera = this._scene?.activeCamera;\r\n        effect.setFloat2(\"cameraInfo\", camera?.minZ ?? 0, camera?.maxZ ?? 1);\r\n        if (this.isLocal && configuration.defines.PREPASS_LOCAL_POSITION_INDEX !== undefined) {\r\n            effect.setMatrix(\"inverseEmitterWM\", this._emitterInverseWorldMatrix);\r\n            const renderOffset = this.worldOffset.subtractToRef(this._scene?.floatingOriginOffset || Vector3.ZeroReadOnly, TmpVectors.Vector3[0]);\r\n            effect.setVector3(\"geometryWorldOffset\", renderOffset);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the particle system is paused (no animation will be done).\r\n     */\r\n    public paused = false;\r\n\r\n    /**\r\n     * Animates the particle system for the current frame by emitting new particles and or animating the living ones.\r\n     * @param preWarmOnly will prevent the system from updating the vertex buffer (default is false)\r\n     */\r\n    public animate(preWarmOnly = false): void {\r\n        if (!this._started || this.paused) {\r\n            return;\r\n        }\r\n\r\n        if (!preWarmOnly && this._scene) {\r\n            // Check\r\n            if (!this.isReady()) {\r\n                return;\r\n            }\r\n\r\n            if (this._currentRenderId === this._scene.getFrameId()) {\r\n                return;\r\n            }\r\n            this._currentRenderId = this._scene.getFrameId();\r\n        }\r\n\r\n        this._scaledUpdateSpeed = this.updateSpeed * (preWarmOnly ? this.preWarmStepOffset : this._scene?.getAnimationRatio() || 1);\r\n\r\n        // Determine the number of particles we need to create\r\n        let newParticles;\r\n\r\n        if (this.manualEmitCount > -1) {\r\n            newParticles = this.manualEmitCount;\r\n            this._newPartsExcess = 0;\r\n            this.manualEmitCount = 0;\r\n        } else {\r\n            const rate = this._calculateEmitRate();\r\n            newParticles = (rate * this._scaledUpdateSpeed) >> 0;\r\n            this._newPartsExcess += rate * this._scaledUpdateSpeed - newParticles;\r\n        }\r\n\r\n        if (this._newPartsExcess > 1.0) {\r\n            newParticles += this._newPartsExcess >> 0;\r\n            this._newPartsExcess -= this._newPartsExcess >> 0;\r\n        }\r\n\r\n        this._alive = false;\r\n\r\n        if (!this._stopped) {\r\n            this._actualFrame += this._scaledUpdateSpeed;\r\n\r\n            if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration) {\r\n                this.stop();\r\n            }\r\n        } else {\r\n            newParticles = 0;\r\n        }\r\n        this._update(newParticles);\r\n\r\n        // Stopped?\r\n        if (this._stopped) {\r\n            if (!this._alive) {\r\n                this._started = false;\r\n                if (this.onAnimationEnd) {\r\n                    this.onAnimationEnd();\r\n                }\r\n                if (this.disposeOnStop && this._scene) {\r\n                    this._scene._toBeDisposed.push(this);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!preWarmOnly) {\r\n            // Update VBO\r\n            let offset = 0;\r\n            for (let index = 0; index < this._particles.length; index++) {\r\n                const particle = this._particles[index];\r\n                this._appendParticleVertices(offset, particle);\r\n                offset += this._useInstancing ? 1 : 4;\r\n            }\r\n\r\n            if (this._vertexBuffer) {\r\n                if (this._useFixedCapacityForSnapshot) {\r\n                    // The vertex buffer is uploaded at full capacity so the FAST-snapshot bundle's draw call stays valid.\r\n                    // Inactive slots must be zeroed so they collapse to degenerate (size=0) quads that emit no fragments.\r\n                    const stride = this._vertexBufferSize * (this._useInstancing ? 1 : 4);\r\n                    const currentCount = this._particles.length;\r\n                    if (currentCount < this._fixedCapacityHighWaterMark) {\r\n                        this._vertexData.fill(0, currentCount * stride, this._fixedCapacityHighWaterMark * stride);\r\n                    }\r\n                    this._fixedCapacityHighWaterMark = currentCount;\r\n                    this._vertexBuffer.updateDirectly(this._vertexData, 0, this._capacity);\r\n                } else {\r\n                    this._vertexBuffer.updateDirectly(this._vertexData, 0, this._particles.length);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this.manualEmitCount === 0 && this.disposeOnStop) {\r\n            this.stop();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _initFixedCapacitySnapshotData(): boolean {\r\n        if (this._useFixedCapacityForSnapshot) {\r\n            return false;\r\n        }\r\n\r\n        this._useFixedCapacityForSnapshot = true;\r\n        this._vertexData.fill(0);\r\n        this._fixedCapacityHighWaterMark = 0;\r\n        this._vertexBuffer?.updateDirectly(this._vertexData, 0, this._capacity);\r\n\r\n        return true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _clearFixedCapacitySnapshotData(): void {\r\n        if (!this._useFixedCapacityForSnapshot || !this._vertexBuffer || this._fixedCapacityHighWaterMark === 0) {\r\n            return;\r\n        }\r\n\r\n        const stride = this._vertexBufferSize * (this._useInstancing ? 1 : 4);\r\n        this._vertexData.fill(0, 0, this._fixedCapacityHighWaterMark * stride);\r\n        this._fixedCapacityHighWaterMark = 0;\r\n        this._vertexBuffer.updateDirectly(this._vertexData, 0, this._capacity);\r\n    }\r\n\r\n    /**\r\n     * Internal only. Calculates the current emit rate based on the gradients if any.\r\n     * @returns The emit rate\r\n     * @internal\r\n     */\r\n    public _calculateEmitRate(): number {\r\n        let rate = this.emitRate;\r\n\r\n        if (this._emitRateGradients && this._emitRateGradients.length > 0 && this.targetStopDuration) {\r\n            const ratio = this._actualFrame / this.targetStopDuration;\r\n            GradientHelper.GetCurrentGradient(ratio, this._emitRateGradients, (currentGradient, nextGradient, scale) => {\r\n                if (currentGradient !== this._currentEmitRateGradient) {\r\n                    this._currentEmitRate1 = this._currentEmitRate2;\r\n                    this._currentEmitRate2 = (<FactorGradient>nextGradient).getFactor();\r\n                    this._currentEmitRateGradient = <FactorGradient>currentGradient;\r\n                }\r\n\r\n                rate = Lerp(this._currentEmitRate1, this._currentEmitRate2, scale);\r\n            });\r\n        }\r\n\r\n        return rate;\r\n    }\r\n\r\n    private _appendParticleVertices(offset: number, particle: Particle) {\r\n        this._appendParticleVertex(offset++, particle, 0, 0);\r\n        if (!this._useInstancing) {\r\n            this._appendParticleVertex(offset++, particle, 1, 0);\r\n            this._appendParticleVertex(offset++, particle, 1, 1);\r\n            this._appendParticleVertex(offset, particle, 0, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the particle system.\r\n     */\r\n    public rebuild(): void {\r\n        if (this._engine.getCaps().vertexArrayObject) {\r\n            this._vertexArrayObject = null;\r\n        }\r\n\r\n        this._createIndexBuffer();\r\n\r\n        this._spriteBuffer?._rebuild();\r\n\r\n        this._createVertexBuffers();\r\n\r\n        this.resetDrawCache();\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n    private async _initShaderSourceAsync() {\r\n        const engine = this._engine;\r\n\r\n        if (engine.isWebGPU && !ThinParticleSystem.ForceGLSL) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([import(\"../ShadersWGSL/particles.vertex\"), import(\"../ShadersWGSL/particles.fragment\")]);\r\n        } else {\r\n            await Promise.all([import(\"../Shaders/particles.vertex\"), import(\"../Shaders/particles.fragment\")]);\r\n        }\r\n\r\n        this._shadersLoaded = true;\r\n    }\r\n\r\n    /**\r\n     * Is this system ready to be used/rendered\r\n     * @returns true if the system is ready\r\n     */\r\n    public isReady(): boolean {\r\n        if (!this._shadersLoaded) {\r\n            return false;\r\n        }\r\n        if (!this.emitter || (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.isReady()) || !this.particleTexture || !this.particleTexture.isReady()) {\r\n            return false;\r\n        }\r\n\r\n        if (this.blendMode !== BaseParticleSystem.BLENDMODE_MULTIPLYADD) {\r\n            if (!this._getWrapper(this.blendMode).effect!.isReady()) {\r\n                return false;\r\n            }\r\n        } else {\r\n            if (!this._getWrapper(BaseParticleSystem.BLENDMODE_MULTIPLY).effect!.isReady()) {\r\n                return false;\r\n            }\r\n            if (!this._getWrapper(BaseParticleSystem.BLENDMODE_ADD).effect!.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _render(blendMode: number) {\r\n        const drawWrapper = this._getWrapper(blendMode);\r\n        const effect = drawWrapper.effect!;\r\n\r\n        const engine = this._engine;\r\n\r\n        // Render\r\n        engine.enableEffect(drawWrapper);\r\n\r\n        const viewMatrix = this.defaultViewMatrix ?? this._scene!.getViewMatrix();\r\n        effect.setTexture(\"diffuseSampler\", this.particleTexture);\r\n        effect.setMatrix(\"view\", viewMatrix);\r\n        const projectionMatrix = this.defaultProjectionMatrix ?? this._scene!.getProjectionMatrix();\r\n        effect.setMatrix(\"projection\", projectionMatrix);\r\n\r\n        if (this._isAnimationSheetEnabled && this.particleTexture) {\r\n            const baseSize = this.particleTexture.getBaseSize();\r\n            effect.setFloat3(\"particlesInfos\", this.spriteCellWidth / baseSize.width, this.spriteCellHeight / baseSize.height, this.spriteCellWidth / baseSize.width);\r\n        }\r\n\r\n        effect.setVector2(\"translationPivot\", this.translationPivot);\r\n        effect.setFloat4(\"textureMask\", this.textureMask.r, this.textureMask.g, this.textureMask.b, this.textureMask.a);\r\n\r\n        if (this._isBillboardBased && this._scene) {\r\n            const camera = this._scene.activeCamera!;\r\n            effect.setVector3(\"eyePosition\", camera.globalPosition);\r\n        }\r\n\r\n        if (this._rampGradientsTexture) {\r\n            if (!this._rampGradients || !this._rampGradients.length) {\r\n                this._rampGradientsTexture.dispose();\r\n                this._rampGradientsTexture = null;\r\n            }\r\n            effect.setTexture(\"rampSampler\", this._rampGradientsTexture);\r\n        }\r\n\r\n        const defines = effect.defines;\r\n\r\n        if (this._scene) {\r\n            BindClipPlane(effect, this, this._scene);\r\n\r\n            if (this.applyFog) {\r\n                BindFogParameters(this._scene, undefined, effect);\r\n            }\r\n        }\r\n\r\n        if (defines.indexOf(\"#define BILLBOARDMODE_ALL\") >= 0) {\r\n            viewMatrix.invertToRef(TmpVectors.Matrix[0]);\r\n            effect.setMatrix(\"invView\", TmpVectors.Matrix[0]);\r\n        }\r\n\r\n        if (effect._multiTarget) {\r\n            this._bindGeometryRendering(effect);\r\n        }\r\n\r\n        if (this._vertexArrayObject !== undefined) {\r\n            if (this._scene?.forceWireframe) {\r\n                engine.bindBuffers(this._vertexBuffers, this._linesIndexBufferUseInstancing, effect);\r\n            } else {\r\n                if (!this._vertexArrayObject) {\r\n                    this._vertexArrayObject = (this._engine as ThinEngine).recordVertexArrayObject(this._vertexBuffers, this._indexBuffer, effect);\r\n                }\r\n\r\n                (this._engine as ThinEngine).bindVertexArrayObject(this._vertexArrayObject, this._indexBuffer);\r\n            }\r\n        } else {\r\n            if (!this._indexBuffer) {\r\n                // Use instancing mode\r\n                engine.bindBuffers(this._vertexBuffers, this._scene?.forceWireframe ? this._linesIndexBufferUseInstancing : null, effect);\r\n            } else {\r\n                engine.bindBuffers(this._vertexBuffers, this._scene?.forceWireframe ? this._linesIndexBuffer : this._indexBuffer, effect);\r\n            }\r\n        }\r\n\r\n        // Log. depth\r\n        if (this.useLogarithmicDepth && this._scene) {\r\n            BindLogDepth(defines, effect, this._scene);\r\n        }\r\n\r\n        // image processing\r\n        if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {\r\n            this._imageProcessingConfiguration.bind(effect);\r\n        }\r\n\r\n        // Draw order\r\n        this._setEngineBasedOnBlendMode(blendMode);\r\n\r\n        if (effect._multiTarget) {\r\n            MaterialHelperGeometryRendering._BindZeroAlphaDiscard(engine, effect);\r\n        }\r\n        let rendered = false;\r\n        try {\r\n            if (MaterialHelperGeometryRendering._BindAttachmentsForEffect(engine, effect)) {\r\n                if (this._onBeforeDrawParticlesObservable) {\r\n                    this._onBeforeDrawParticlesObservable.notifyObservers(effect);\r\n                }\r\n\r\n                if (this._useInstancing) {\r\n                    if (this._scene?.forceWireframe) {\r\n                        engine.drawElementsType(Constants.MATERIAL_LineStripDrawMode, 0, 10, this._useFixedCapacityForSnapshot ? this._capacity : this._particles.length);\r\n                    } else {\r\n                        engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, this._useFixedCapacityForSnapshot ? this._capacity : this._particles.length);\r\n                    }\r\n                } else if (this._scene?.forceWireframe) {\r\n                    engine.drawElementsType(Constants.MATERIAL_WireFrameFillMode, 0, (this._useFixedCapacityForSnapshot ? this._capacity : this._particles.length) * 10);\r\n                } else {\r\n                    engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, (this._useFixedCapacityForSnapshot ? this._capacity : this._particles.length) * 6);\r\n                }\r\n                rendered = true;\r\n            }\r\n        } finally {\r\n            MaterialHelperGeometryRendering._RestoreAttachments(engine);\r\n        }\r\n\r\n        return rendered ? this._particles.length : 0;\r\n    }\r\n\r\n    /**\r\n     * Renders the particle system in its current state.\r\n     * @returns the current number of particles\r\n     */\r\n    public render(): number {\r\n        // Check\r\n        if (!this.isReady() || (!this._particles.length && !this._useFixedCapacityForSnapshot)) {\r\n            return 0;\r\n        }\r\n\r\n        const engine = this._engine as any;\r\n        if (engine.setState) {\r\n            engine.setState(false);\r\n\r\n            if (this.forceDepthWrite) {\r\n                engine.setDepthWrite(true);\r\n            }\r\n        }\r\n\r\n        let outparticles: number;\r\n\r\n        if (this.blendMode === BaseParticleSystem.BLENDMODE_MULTIPLYADD) {\r\n            outparticles = this._render(BaseParticleSystem.BLENDMODE_MULTIPLY) + this._render(BaseParticleSystem.BLENDMODE_ADD);\r\n        } else {\r\n            outparticles = this._render(this.blendMode);\r\n        }\r\n\r\n        this._engine.unbindInstanceAttributes();\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n        return outparticles;\r\n    }\r\n\r\n    /** @internal */\r\n    public _onDispose(_disposeAttachedSubEmitters = false, _disposeEndSubEmitters = false) {\r\n        // Do Nothing\r\n    }\r\n\r\n    /**\r\n     * Disposes the particle system and free the associated resources\r\n     * @param disposeTexture defines if the particle texture must be disposed as well (true by default)\r\n     * @param disposeAttachedSubEmitters defines if the attached sub-emitters must be disposed as well (false by default)\r\n     * @param disposeEndSubEmitters defines if the end type sub-emitters must be disposed as well (false by default)\r\n     */\r\n    public dispose(disposeTexture = true, disposeAttachedSubEmitters = false, disposeEndSubEmitters = false): void {\r\n        this._engine._onReleaseRenderPassObservable?.remove(this._renderPassObserver);\r\n        this._renderPassObserver = null;\r\n        this.resetDrawCache();\r\n\r\n        if (this._vertexBuffer) {\r\n            this._vertexBuffer.dispose();\r\n            this._vertexBuffer = null;\r\n        }\r\n\r\n        if (this._spriteBuffer) {\r\n            this._spriteBuffer.dispose();\r\n            this._spriteBuffer = null;\r\n        }\r\n\r\n        if (this._indexBuffer) {\r\n            this._engine._releaseBuffer(this._indexBuffer);\r\n            this._indexBuffer = null;\r\n        }\r\n\r\n        if (this._linesIndexBuffer) {\r\n            this._engine._releaseBuffer(this._linesIndexBuffer);\r\n            this._linesIndexBuffer = null;\r\n        }\r\n\r\n        if (this._linesIndexBufferUseInstancing) {\r\n            this._engine._releaseBuffer(this._linesIndexBufferUseInstancing);\r\n            this._linesIndexBufferUseInstancing = null;\r\n        }\r\n\r\n        if (this._vertexArrayObject) {\r\n            (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObject);\r\n            this._vertexArrayObject = null;\r\n        }\r\n\r\n        if (disposeTexture && this.particleTexture) {\r\n            this.particleTexture.dispose();\r\n            this.particleTexture = null;\r\n        }\r\n\r\n        if (disposeTexture && this.noiseTexture) {\r\n            this.noiseTexture.dispose();\r\n            this.noiseTexture = null;\r\n        }\r\n\r\n        if (this._rampGradientsTexture) {\r\n            this._rampGradientsTexture.dispose();\r\n            this._rampGradientsTexture = null;\r\n        }\r\n\r\n        this._onDispose(disposeAttachedSubEmitters, disposeEndSubEmitters);\r\n\r\n        if (this._onBeforeDrawParticlesObservable) {\r\n            this._onBeforeDrawParticlesObservable.clear();\r\n        }\r\n\r\n        // Remove from scene\r\n        if (this._scene) {\r\n            const index = this._scene.particleSystems.indexOf(this);\r\n            if (index > -1) {\r\n                this._scene.particleSystems.splice(index, 1);\r\n            }\r\n\r\n            this._scene._activeParticleSystems.dispose();\r\n        }\r\n\r\n        // Callback\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n        this.onStoppedObservable.clear();\r\n        this.onStartedObservable.clear();\r\n\r\n        this.reset();\r\n\r\n        this._isDisposed = true;\r\n    }\r\n}\r\n","import { type Nullable } from \"core/types\";\r\nimport { type Matrix, Vector3, TmpVectors } from \"core/Maths/math.vector.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"core/Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { type IParticleEmitterType } from \"./IParticleEmitterType\";\r\n\r\nimport { DeepCopier } from \"core/Misc/deepCopier\";\r\n\r\n/** Represents and empty generator function */\r\nexport const EmptyGeneratorFunc = () => {};\r\n\r\n/**\r\n * Particle emitter emitting particles from a custom list of positions.\r\n */\r\nexport class CustomParticleEmitter implements IParticleEmitterType {\r\n    /**\r\n     * Gets or sets the position generator that will create the initial position of each particle.\r\n     * Index will be provided when used with GPU particle. Particle will be provided when used with CPU particles\r\n     */\r\n    public particlePositionGenerator: (index: number, particle: Nullable<Particle>, outPosition: Vector3) => void = EmptyGeneratorFunc;\r\n\r\n    /**\r\n     * Gets or sets the destination generator that will create the final destination of each particle.\r\n     *  * Index will be provided when used with GPU particle. Particle will be provided when used with CPU particles\r\n     */\r\n    public particleDestinationGenerator: (index: number, particle: Nullable<Particle>, outDestination: Vector3) => void = EmptyGeneratorFunc;\r\n\r\n    /**\r\n     * Gets or sets the direction generator that will create the initial direction of each particle.\r\n     *  * Index will be provided when used with GPU particle. Particle will be provided when used with CPU particles\r\n     */\r\n    public particleDirectionGenerator: (index: number, particle: Nullable<Particle>, outDestination: Vector3) => void = EmptyGeneratorFunc;\r\n\r\n    /**\r\n     * Creates a new instance CustomParticleEmitter\r\n     */\r\n    constructor() {}\r\n\r\n    /**\r\n     * Called by the particle System when the direction is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param directionToUpdate is the direction vector to update with the result\r\n     * @param particle is the particle we are computed the direction for\r\n     * @param isLocal defines if the direction should be set in local space\r\n     */\r\n    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const tmpVector = TmpVectors.Vector3[0];\r\n\r\n        if (this.particleDirectionGenerator && this.particleDirectionGenerator !== EmptyGeneratorFunc) {\r\n            this.particleDirectionGenerator(-1, particle, tmpVector);\r\n        } else if (this.particleDestinationGenerator && this.particleDestinationGenerator !== EmptyGeneratorFunc) {\r\n            this.particleDestinationGenerator(-1, particle, tmpVector);\r\n\r\n            // Get direction\r\n            const diffVector = TmpVectors.Vector3[1];\r\n            tmpVector.subtractToRef(particle.position, diffVector);\r\n\r\n            diffVector.scaleToRef(1 / particle.lifeTime, tmpVector);\r\n        } else {\r\n            tmpVector.set(0, 0, 0);\r\n        }\r\n\r\n        if (isLocal) {\r\n            directionToUpdate.copyFrom(tmpVector);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformNormalToRef(tmpVector, worldMatrix, directionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Called by the particle System when the position is computed for the created particle.\r\n     * @param worldMatrix is the world matrix of the particle system\r\n     * @param positionToUpdate is the position vector to update with the result\r\n     * @param particle is the particle we are computed the position for\r\n     * @param isLocal defines if the position should be set in local space\r\n     */\r\n    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {\r\n        const tmpVector = TmpVectors.Vector3[0];\r\n\r\n        if (this.particlePositionGenerator && this.particlePositionGenerator !== EmptyGeneratorFunc) {\r\n            this.particlePositionGenerator(-1, particle, tmpVector);\r\n        } else {\r\n            tmpVector.set(0, 0, 0);\r\n        }\r\n\r\n        if (isLocal) {\r\n            positionToUpdate.copyFrom(tmpVector);\r\n            return;\r\n        }\r\n\r\n        Vector3.TransformCoordinatesToRef(tmpVector, worldMatrix, positionToUpdate);\r\n    }\r\n\r\n    /**\r\n     * Clones the current emitter and returns a copy of it\r\n     * @returns the new emitter\r\n     */\r\n    public clone(): CustomParticleEmitter {\r\n        const newOne = new CustomParticleEmitter();\r\n\r\n        DeepCopier.DeepCopy(this, newOne);\r\n\r\n        return newOne;\r\n    }\r\n\r\n    /**\r\n     * Called by the GPUParticleSystem to setup the update shader\r\n     * @param uboOrEffect defines the update shader\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public applyToShader(uboOrEffect: UniformBufferEffectCommonAccessor): void {}\r\n\r\n    /**\r\n     * Creates the structure of the ubo for this particle emitter\r\n     * @param ubo ubo to create the structure for\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public buildUniformLayout(ubo: UniformBuffer): void {}\r\n\r\n    /**\r\n     * Returns a string to use to update the GPU particles update shader\r\n     * @returns a string containing the defines string\r\n     */\r\n    public getEffectDefines(): string {\r\n        return \"#define CUSTOMEMITTER\";\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"PointParticleEmitter\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"CustomParticleEmitter\";\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object.\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.type = this.getClassName();\r\n        serializationObject.particlePositionGenerator = this.particlePositionGenerator;\r\n        serializationObject.particleDestinationGenerator = this.particleDestinationGenerator;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parse properties from a JSON object\r\n     * @param serializationObject defines the JSON object\r\n     */\r\n    public parse(serializationObject: any): void {\r\n        if (serializationObject.particlePositionGenerator) {\r\n            this.particlePositionGenerator = serializationObject.particlePositionGenerator;\r\n        }\r\n\r\n        if (serializationObject.particleDestinationGenerator) {\r\n            this.particleDestinationGenerator = serializationObject.particleDestinationGenerator;\r\n        }\r\n    }\r\n}\r\n","import { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Particle } from \"./particle\";\r\nimport { type ThinParticleSystem } from \"./thinParticleSystem\";\r\n\r\nconst ToAttractor: Vector3 = Vector3.Zero();\r\nconst Force: Vector3 = Vector3.Zero();\r\nconst ScaledForce: Vector3 = Vector3.Zero();\r\n\r\n/**\r\n * Class representing an attractor in a particle system.\r\n * #DEZ79M#40\r\n */\r\nexport class Attractor {\r\n    /**\r\n     * Gets or sets the strength of the attractor.\r\n     * A positive value attracts particles, while a negative value repels them.\r\n     */\r\n    public strength = 0.0;\r\n\r\n    /**\r\n     * Gets or sets the position of the attractor in 3D space.\r\n     */\r\n    public position = Vector3.Zero();\r\n\r\n    /** @internal */\r\n    public _processParticle(particle: Particle, system: ThinParticleSystem) {\r\n        this.position.subtractToRef(particle.position, ToAttractor);\r\n        const distanceSquared = ToAttractor.lengthSquared() + 1; // Avoid going under 1.0\r\n        ToAttractor.normalize().scaleToRef(this.strength / distanceSquared, Force);\r\n\r\n        Force.scaleToRef(system._tempScaledUpdateSpeed, ScaledForce);\r\n\r\n        particle.direction.addInPlace(ScaledForce); // Update particle velocity\r\n    }\r\n\r\n    /**\r\n     * Serializes the attractor to a JSON object.\r\n     * @returns The serialized JSON object.\r\n     */\r\n    public serialize(): any {\r\n        return {\r\n            position: this.position.asArray(),\r\n            strength: this.strength,\r\n        };\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { ThinParticleSystem } from \"./thinParticleSystem.pure\";\r\nimport { type IParticleEmitterType } from \"./EmitterTypes/IParticleEmitterType\";\r\nimport { SubEmitter, SubEmitterType } from \"./subEmitter\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type IParticleSystem } from \"./IParticleSystem\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { GetClass } from \"../Misc/typeStore\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Particle } from \"./particle\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { MeshParticleEmitter } from \"./EmitterTypes/meshParticleEmitter\";\r\nimport { CustomParticleEmitter } from \"./EmitterTypes/customParticleEmitter\";\r\nimport { BoxParticleEmitter } from \"./EmitterTypes/boxParticleEmitter\";\r\nimport { PointParticleEmitter } from \"./EmitterTypes/pointParticleEmitter\";\r\nimport { HemisphericParticleEmitter } from \"./EmitterTypes/hemisphericParticleEmitter\";\r\nimport { SphereDirectedParticleEmitter, SphereParticleEmitter } from \"./EmitterTypes/sphereParticleEmitter\";\r\nimport { CylinderDirectedParticleEmitter, CylinderParticleEmitter } from \"./EmitterTypes/cylinderParticleEmitter\";\r\nimport { ConeDirectedParticleEmitter, ConeParticleEmitter } from \"./EmitterTypes/coneParticleEmitter\";\r\nimport { Attractor } from \"./attractor\";\r\nimport { _ConnectAfter, _RemoveFromQueue, type _IExecutionQueueItem } from \"./Queue/executionQueue\";\r\nimport { _IsSideEffectImplemented } from \"../Misc/devTools\";\r\n\r\nimport { type FlowMap } from \"./flowMap\";\r\nimport { type NodeParticleSystemSet } from \"./Node/nodeParticleSystemSet\";\r\n\r\n// Names of the particle texture display settings persisted alongside `textureName` when the texture\r\n// pixels are serialized by reference (serializeTexture === false), so a serialize/parse round-trip\r\n// keeps the same appearance. `samplingMode` is handled separately (passed to the Texture constructor).\r\nconst ParticleTextureSettingKeys = [\r\n    \"level\",\r\n    \"hasAlpha\",\r\n    \"getAlphaFromRGB\",\r\n    \"gammaSpace\",\r\n    \"coordinatesIndex\",\r\n    \"coordinatesMode\",\r\n    \"wrapU\",\r\n    \"wrapV\",\r\n    \"wrapR\",\r\n    \"anisotropicFilteringLevel\",\r\n    \"uOffset\",\r\n    \"vOffset\",\r\n    \"uScale\",\r\n    \"vScale\",\r\n    \"uAng\",\r\n    \"vAng\",\r\n    \"wAng\",\r\n    \"uRotationCenter\",\r\n    \"vRotationCenter\",\r\n    \"wRotationCenter\",\r\n] as const;\r\n\r\n/**\r\n * This represents a particle system in Babylon.\r\n * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.\r\n * Particles can take different shapes while emitted like box, sphere, cone or you can write your custom function.\r\n * @example https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro\r\n */\r\nexport class ParticleSystem extends ThinParticleSystem {\r\n    /**\r\n     * Billboard mode will only apply to Y axis\r\n     */\r\n    public static readonly BILLBOARDMODE_Y = Constants.PARTICLES_BILLBOARDMODE_Y;\r\n    /**\r\n     * Billboard mode will apply to all axes\r\n     */\r\n    public static readonly BILLBOARDMODE_ALL = Constants.PARTICLES_BILLBOARDMODE_ALL;\r\n    /**\r\n     * Special billboard mode where the particle will be biilboard to the camera but rotated to align with direction\r\n     */\r\n    public static readonly BILLBOARDMODE_STRETCHED = Constants.PARTICLES_BILLBOARDMODE_STRETCHED;\r\n    /**\r\n     * Special billboard mode where the particle will be billboard to the camera but only around the axis of the direction of particle emission\r\n     */\r\n    public static readonly BILLBOARDMODE_STRETCHED_LOCAL = Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL;\r\n\r\n    // Sub-emitters\r\n    private _rootParticleSystem: Nullable<ParticleSystem>;\r\n\r\n    /**\r\n     * The Sub-emitters templates that will be used to generate the sub particle system to be associated with the system, this property is used by the root particle system only.\r\n     * When a particle is spawned, an array will be chosen at random and all the emitters in that array will be attached to the particle.  (Default: [])\r\n     */\r\n    public subEmitters: Array<ParticleSystem | SubEmitter | Array<SubEmitter>>;\r\n    // the subEmitters field above converted to a constant type\r\n    private _subEmitters: Array<Array<SubEmitter>>;\r\n\r\n    /**\r\n     * @internal\r\n     * If the particle systems emitter should be disposed when the particle system is disposed\r\n     */\r\n    public _disposeEmitterOnDispose = false;\r\n    /**\r\n     * The current active Sub-systems, this property is used by the root particle system only.\r\n     */\r\n    public activeSubSystems: Array<ParticleSystem>;\r\n\r\n    /**\r\n     * Specifies if the particle system should be serialized\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    /**\r\n     * Gets or sets a function indicating if the particle system can start.\r\n     * @returns true if the particle system can start, false otherwise.\r\n     */\r\n    public canStart = () => {\r\n        return true;\r\n    };\r\n\r\n    /** Flow map */\r\n    private _flowMap: Nullable<FlowMap> = null;\r\n    private _flowMapUpdate: Nullable<_IExecutionQueueItem> = null;\r\n\r\n    /** @internal */\r\n    public _source: Nullable<NodeParticleSystemSet> = null;\r\n\r\n    /** @internal */\r\n    public _blockReference: number = 0;\r\n\r\n    /**\r\n     * Gets the NodeParticleSystemSet that this particle system belongs to.\r\n     */\r\n    public get source(): Nullable<NodeParticleSystemSet> {\r\n        return this._source;\r\n    }\r\n\r\n    /**\r\n     * Returns true if the particle system was generated by a node particle system set\r\n     */\r\n    public override get isNodeGenerated(): boolean {\r\n        return this._source !== null;\r\n    }\r\n    /**\r\n     * The strength of the flow map\r\n     */\r\n    public flowMapStrength = 1.0;\r\n\r\n    /** Gets or sets the current flow map */\r\n    public get flowMap(): Nullable<FlowMap> {\r\n        return this._flowMap;\r\n    }\r\n\r\n    public set flowMap(value: Nullable<FlowMap>) {\r\n        if (this._flowMap === value) {\r\n            return;\r\n        }\r\n\r\n        this._flowMap = value;\r\n\r\n        if (this._flowMapUpdate) {\r\n            _RemoveFromQueue(this._flowMapUpdate);\r\n            this._flowMapUpdate = null;\r\n        }\r\n        if (value) {\r\n            this._flowMapUpdate = {\r\n                process: (particle: Particle) => {\r\n                    const matrix = this.getScene()?.getTransformMatrix();\r\n                    this._flowMap!._processParticle(particle, this.flowMapStrength * this._tempScaledUpdateSpeed, matrix);\r\n                },\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._flowMapUpdate, this._directionProcessing!);\r\n        }\r\n    }\r\n\r\n    /** Attractors */\r\n    private _attractorUpdate: Nullable<_IExecutionQueueItem> = null;\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the particle system\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /**\r\n     * Add an attractor to the particle system. Attractors are used to change the direction of the particles in the system.\r\n     * @param attractor The attractor to add to the particle system\r\n     */\r\n    public override addAttractor(attractor: Attractor): void {\r\n        super.addAttractor(attractor);\r\n\r\n        if (this._attractors.length === 1) {\r\n            this._attractorUpdate = {\r\n                process: (particle: Particle) => {\r\n                    for (const attractor of this._attractors) {\r\n                        attractor._processParticle(particle, this);\r\n                    }\r\n                },\r\n                previousItem: null,\r\n                nextItem: null,\r\n            };\r\n            _ConnectAfter(this._attractorUpdate, this._directionProcessing!);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes an attractor from the particle system. Attractors are used to change the direction of the particles in the system.\r\n     * @param attractor The attractor to remove from the particle system\r\n     */\r\n    public override removeAttractor(attractor: Attractor): void {\r\n        super.removeAttractor(attractor);\r\n\r\n        if (this._attractors.length === 0 && this._attractorUpdate) {\r\n            _RemoveFromQueue(this._attractorUpdate);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Starts the particle system and begins to emit\r\n     * @param delay defines the delay in milliseconds before starting the system (this.startDelay by default)\r\n     */\r\n    public override start(delay = this.startDelay): void {\r\n        if (!this.canStart()) {\r\n            return;\r\n        }\r\n        super.start(delay);\r\n    }\r\n\r\n    private _prepareSubEmitterInternalArray() {\r\n        this._subEmitters = new Array<Array<SubEmitter>>();\r\n        if (this.subEmitters) {\r\n            for (const subEmitter of this.subEmitters) {\r\n                if (subEmitter instanceof ParticleSystem) {\r\n                    this._subEmitters.push([new SubEmitter(subEmitter)]);\r\n                } else if (subEmitter instanceof SubEmitter) {\r\n                    this._subEmitters.push([subEmitter]);\r\n                } else if (subEmitter instanceof Array) {\r\n                    this._subEmitters.push(subEmitter);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _stopSubEmitters(): void {\r\n        if (!this.activeSubSystems) {\r\n            return;\r\n        }\r\n        for (const subSystem of this.activeSubSystems) {\r\n            subSystem.stop(true);\r\n        }\r\n        this.activeSubSystems = [] as ParticleSystem[];\r\n    }\r\n\r\n    private _removeFromRoot(): void {\r\n        if (!this._rootParticleSystem) {\r\n            return;\r\n        }\r\n\r\n        const index = this._rootParticleSystem.activeSubSystems.indexOf(this);\r\n        if (index !== -1) {\r\n            this._rootParticleSystem.activeSubSystems.splice(index, 1);\r\n        }\r\n\r\n        this._rootParticleSystem = null;\r\n    }\r\n\r\n    /** @internal */\r\n    public override _emitFromParticle: (particle: Particle) => void = (particle) => {\r\n        if (!this._subEmitters || this._subEmitters.length === 0) {\r\n            return;\r\n        }\r\n        const templateIndex = Math.floor(Math.random() * this._subEmitters.length);\r\n\r\n        for (const subEmitter of this._subEmitters[templateIndex]) {\r\n            if (subEmitter.type === SubEmitterType.END) {\r\n                const subSystem = subEmitter.clone();\r\n                particle._inheritParticleInfoToSubEmitter(subSystem);\r\n                subSystem.particleSystem._rootParticleSystem = this;\r\n                this.activeSubSystems.push(subSystem.particleSystem);\r\n                subSystem.particleSystem.start();\r\n            }\r\n        }\r\n    };\r\n\r\n    /** @internal */\r\n    public override _preStart() {\r\n        // Convert the subEmitters field to the constant type field _subEmitters\r\n        this._prepareSubEmitterInternalArray();\r\n\r\n        if (this._subEmitters && this._subEmitters.length != 0) {\r\n            this.activeSubSystems = [] as ParticleSystem[];\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _postStop(stopSubEmitters: boolean) {\r\n        if (stopSubEmitters) {\r\n            this._stopSubEmitters();\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _prepareParticle(particle: Particle): void {\r\n        // Attach emitters\r\n        if (this._subEmitters && this._subEmitters.length > 0) {\r\n            const subEmitters = this._subEmitters[Math.floor(Math.random() * this._subEmitters.length)];\r\n            particle._properties.attachedSubEmitters = [];\r\n            for (const subEmitter of subEmitters) {\r\n                if (subEmitter.type === SubEmitterType.ATTACHED) {\r\n                    const newEmitter = subEmitter.clone();\r\n                    particle._properties.attachedSubEmitters.push(newEmitter);\r\n                    newEmitter.particleSystem.start();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public override _onDispose(disposeAttachedSubEmitters = false, disposeEndSubEmitters = false) {\r\n        this._removeFromRoot();\r\n\r\n        if (this.subEmitters && !this._subEmitters) {\r\n            this._prepareSubEmitterInternalArray();\r\n        }\r\n\r\n        if (disposeAttachedSubEmitters) {\r\n            if (this.particles) {\r\n                for (const particle of this.particles) {\r\n                    if (particle._properties.attachedSubEmitters) {\r\n                        for (let i = particle._properties.attachedSubEmitters.length - 1; i >= 0; i -= 1) {\r\n                            particle._properties.attachedSubEmitters[i].dispose();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (disposeEndSubEmitters) {\r\n            if (this.activeSubSystems) {\r\n                for (let i = this.activeSubSystems.length - 1; i >= 0; i -= 1) {\r\n                    this.activeSubSystems[i].dispose();\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._subEmitters && this._subEmitters.length) {\r\n            for (let index = 0; index < this._subEmitters.length; index++) {\r\n                for (const subEmitter of this._subEmitters[index]) {\r\n                    subEmitter.dispose();\r\n                }\r\n            }\r\n\r\n            this._subEmitters = [];\r\n            this.subEmitters = [];\r\n        }\r\n\r\n        if (this._disposeEmitterOnDispose && this.emitter && (this.emitter as AbstractMesh).dispose) {\r\n            (<AbstractMesh>this.emitter).dispose(true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _Parse(parsedParticleSystem: any, particleSystem: IParticleSystem, sceneOrEngine: Scene | AbstractEngine, rootUrl: string) {\r\n        let scene: Nullable<Scene>;\r\n\r\n        if (sceneOrEngine instanceof AbstractEngine) {\r\n            scene = null;\r\n        } else {\r\n            scene = sceneOrEngine;\r\n        }\r\n\r\n        const internalClass = GetClass(\"BABYLON.Texture\");\r\n        if (internalClass && scene) {\r\n            // Texture\r\n            if (parsedParticleSystem.texture) {\r\n                particleSystem.particleTexture = internalClass.Parse(parsedParticleSystem.texture, scene, rootUrl) as BaseTexture;\r\n            } else if (parsedParticleSystem.textureName) {\r\n                const textureSettings = parsedParticleSystem.textureSettings;\r\n                particleSystem.particleTexture = new internalClass(\r\n                    rootUrl + parsedParticleSystem.textureName,\r\n                    scene,\r\n                    false,\r\n                    parsedParticleSystem.invertY !== undefined ? parsedParticleSystem.invertY : true,\r\n                    textureSettings ? textureSettings.samplingMode : undefined\r\n                );\r\n                particleSystem.particleTexture!.name = parsedParticleSystem.textureName;\r\n\r\n                if (textureSettings) {\r\n                    const texture = particleSystem.particleTexture as any;\r\n                    for (const key of ParticleTextureSettingKeys) {\r\n                        if (textureSettings[key] !== undefined) {\r\n                            texture[key] = textureSettings[key];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Emitter\r\n        if (!parsedParticleSystem.emitterId && parsedParticleSystem.emitterId !== 0 && parsedParticleSystem.emitter === undefined) {\r\n            particleSystem.emitter = Vector3.Zero();\r\n        } else if ((parsedParticleSystem.emitterId || parsedParticleSystem.emitterId === 0) && scene) {\r\n            particleSystem.emitter = scene.getLastMeshById(parsedParticleSystem.emitterId);\r\n            if (!particleSystem.emitter) {\r\n                particleSystem.emitter = Vector3.Zero();\r\n            }\r\n        } else {\r\n            particleSystem.emitter = Vector3.FromArray(parsedParticleSystem.emitter);\r\n        }\r\n\r\n        particleSystem.isLocal = !!parsedParticleSystem.isLocal;\r\n\r\n        // Misc.\r\n        if (parsedParticleSystem.renderingGroupId !== undefined) {\r\n            particleSystem.renderingGroupId = parsedParticleSystem.renderingGroupId;\r\n        }\r\n\r\n        if (parsedParticleSystem.isBillboardBased !== undefined) {\r\n            particleSystem.isBillboardBased = parsedParticleSystem.isBillboardBased;\r\n        }\r\n\r\n        if (parsedParticleSystem.billboardMode !== undefined) {\r\n            particleSystem.billboardMode = parsedParticleSystem.billboardMode;\r\n        }\r\n\r\n        if (parsedParticleSystem.useLogarithmicDepth !== undefined) {\r\n            particleSystem.useLogarithmicDepth = parsedParticleSystem.useLogarithmicDepth;\r\n        }\r\n\r\n        // Animations\r\n        if (parsedParticleSystem.animations) {\r\n            for (let animationIndex = 0; animationIndex < parsedParticleSystem.animations.length; animationIndex++) {\r\n                const parsedAnimation = parsedParticleSystem.animations[animationIndex];\r\n                const internalClass = GetClass(\"BABYLON.Animation\");\r\n                if (internalClass) {\r\n                    particleSystem.animations.push(internalClass.Parse(parsedAnimation));\r\n                }\r\n            }\r\n            particleSystem.beginAnimationOnStart = parsedParticleSystem.beginAnimationOnStart;\r\n            particleSystem.beginAnimationFrom = parsedParticleSystem.beginAnimationFrom;\r\n            particleSystem.beginAnimationTo = parsedParticleSystem.beginAnimationTo;\r\n            particleSystem.beginAnimationLoop = parsedParticleSystem.beginAnimationLoop;\r\n        }\r\n\r\n        if (parsedParticleSystem.autoAnimate && scene) {\r\n            scene.beginAnimation(\r\n                particleSystem,\r\n                parsedParticleSystem.autoAnimateFrom,\r\n                parsedParticleSystem.autoAnimateTo,\r\n                parsedParticleSystem.autoAnimateLoop,\r\n                parsedParticleSystem.autoAnimateSpeed || 1.0\r\n            );\r\n        }\r\n\r\n        // Particle system\r\n        particleSystem.startDelay = parsedParticleSystem.startDelay | 0;\r\n        particleSystem.minAngularSpeed = parsedParticleSystem.minAngularSpeed;\r\n        particleSystem.maxAngularSpeed = parsedParticleSystem.maxAngularSpeed;\r\n        particleSystem.minSize = parsedParticleSystem.minSize;\r\n        particleSystem.maxSize = parsedParticleSystem.maxSize;\r\n\r\n        if (parsedParticleSystem.minScaleX) {\r\n            particleSystem.minScaleX = parsedParticleSystem.minScaleX;\r\n            particleSystem.maxScaleX = parsedParticleSystem.maxScaleX;\r\n            particleSystem.minScaleY = parsedParticleSystem.minScaleY;\r\n            particleSystem.maxScaleY = parsedParticleSystem.maxScaleY;\r\n        }\r\n\r\n        if (parsedParticleSystem.preWarmCycles !== undefined) {\r\n            particleSystem.preWarmCycles = parsedParticleSystem.preWarmCycles;\r\n            particleSystem.preWarmStepOffset = parsedParticleSystem.preWarmStepOffset;\r\n        }\r\n\r\n        if (parsedParticleSystem.minInitialRotation !== undefined) {\r\n            particleSystem.minInitialRotation = parsedParticleSystem.minInitialRotation;\r\n            particleSystem.maxInitialRotation = parsedParticleSystem.maxInitialRotation;\r\n        }\r\n\r\n        particleSystem.minLifeTime = parsedParticleSystem.minLifeTime;\r\n        particleSystem.maxLifeTime = parsedParticleSystem.maxLifeTime;\r\n        particleSystem.minEmitPower = parsedParticleSystem.minEmitPower;\r\n        particleSystem.maxEmitPower = parsedParticleSystem.maxEmitPower;\r\n        particleSystem.emitRate = parsedParticleSystem.emitRate;\r\n        particleSystem.gravity = Vector3.FromArray(parsedParticleSystem.gravity);\r\n        if (parsedParticleSystem.noiseStrength) {\r\n            particleSystem.noiseStrength = Vector3.FromArray(parsedParticleSystem.noiseStrength);\r\n        }\r\n        particleSystem.color1 = Color4.FromArray(parsedParticleSystem.color1);\r\n        particleSystem.color2 = Color4.FromArray(parsedParticleSystem.color2);\r\n        particleSystem.colorDead = Color4.FromArray(parsedParticleSystem.colorDead);\r\n        particleSystem.updateSpeed = parsedParticleSystem.updateSpeed;\r\n        particleSystem.targetStopDuration = parsedParticleSystem.targetStopDuration;\r\n        particleSystem.blendMode = parsedParticleSystem.blendMode;\r\n\r\n        if (parsedParticleSystem.colorGradients) {\r\n            for (const colorGradient of parsedParticleSystem.colorGradients) {\r\n                particleSystem.addColorGradient(\r\n                    colorGradient.gradient,\r\n                    Color4.FromArray(colorGradient.color1),\r\n                    colorGradient.color2 ? Color4.FromArray(colorGradient.color2) : undefined\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.rampGradients) {\r\n            for (const rampGradient of parsedParticleSystem.rampGradients) {\r\n                particleSystem.addRampGradient(rampGradient.gradient, Color3.FromArray(rampGradient.color));\r\n            }\r\n            particleSystem.useRampGradients = parsedParticleSystem.useRampGradients;\r\n        }\r\n\r\n        if (parsedParticleSystem.colorRemapGradients) {\r\n            for (const colorRemapGradient of parsedParticleSystem.colorRemapGradients) {\r\n                particleSystem.addColorRemapGradient(\r\n                    colorRemapGradient.gradient,\r\n                    colorRemapGradient.factor1 !== undefined ? colorRemapGradient.factor1 : colorRemapGradient.factor,\r\n                    colorRemapGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.alphaRemapGradients) {\r\n            for (const alphaRemapGradient of parsedParticleSystem.alphaRemapGradients) {\r\n                particleSystem.addAlphaRemapGradient(\r\n                    alphaRemapGradient.gradient,\r\n                    alphaRemapGradient.factor1 !== undefined ? alphaRemapGradient.factor1 : alphaRemapGradient.factor,\r\n                    alphaRemapGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.sizeGradients) {\r\n            for (const sizeGradient of parsedParticleSystem.sizeGradients) {\r\n                particleSystem.addSizeGradient(sizeGradient.gradient, sizeGradient.factor1 !== undefined ? sizeGradient.factor1 : sizeGradient.factor, sizeGradient.factor2);\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.angularSpeedGradients) {\r\n            for (const angularSpeedGradient of parsedParticleSystem.angularSpeedGradients) {\r\n                particleSystem.addAngularSpeedGradient(\r\n                    angularSpeedGradient.gradient,\r\n                    angularSpeedGradient.factor1 !== undefined ? angularSpeedGradient.factor1 : angularSpeedGradient.factor,\r\n                    angularSpeedGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.velocityGradients) {\r\n            for (const velocityGradient of parsedParticleSystem.velocityGradients) {\r\n                particleSystem.addVelocityGradient(\r\n                    velocityGradient.gradient,\r\n                    velocityGradient.factor1 !== undefined ? velocityGradient.factor1 : velocityGradient.factor,\r\n                    velocityGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.dragGradients) {\r\n            for (const dragGradient of parsedParticleSystem.dragGradients) {\r\n                particleSystem.addDragGradient(dragGradient.gradient, dragGradient.factor1 !== undefined ? dragGradient.factor1 : dragGradient.factor, dragGradient.factor2);\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.emitRateGradients) {\r\n            for (const emitRateGradient of parsedParticleSystem.emitRateGradients) {\r\n                particleSystem.addEmitRateGradient(\r\n                    emitRateGradient.gradient,\r\n                    emitRateGradient.factor1 !== undefined ? emitRateGradient.factor1 : emitRateGradient.factor,\r\n                    emitRateGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.startSizeGradients) {\r\n            for (const startSizeGradient of parsedParticleSystem.startSizeGradients) {\r\n                particleSystem.addStartSizeGradient(\r\n                    startSizeGradient.gradient,\r\n                    startSizeGradient.factor1 !== undefined ? startSizeGradient.factor1 : startSizeGradient.factor,\r\n                    startSizeGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.lifeTimeGradients) {\r\n            for (const lifeTimeGradient of parsedParticleSystem.lifeTimeGradients) {\r\n                particleSystem.addLifeTimeGradient(\r\n                    lifeTimeGradient.gradient,\r\n                    lifeTimeGradient.factor1 !== undefined ? lifeTimeGradient.factor1 : lifeTimeGradient.factor,\r\n                    lifeTimeGradient.factor2\r\n                );\r\n            }\r\n        }\r\n\r\n        if (parsedParticleSystem.limitVelocityGradients) {\r\n            for (const limitVelocityGradient of parsedParticleSystem.limitVelocityGradients) {\r\n                particleSystem.addLimitVelocityGradient(\r\n                    limitVelocityGradient.gradient,\r\n                    limitVelocityGradient.factor1 !== undefined ? limitVelocityGradient.factor1 : limitVelocityGradient.factor,\r\n                    limitVelocityGradient.factor2\r\n                );\r\n            }\r\n            particleSystem.limitVelocityDamping = parsedParticleSystem.limitVelocityDamping;\r\n        }\r\n\r\n        if (parsedParticleSystem.noiseTexture && scene) {\r\n            const internalClass = GetClass(\"BABYLON.ProceduralTexture\");\r\n            particleSystem.noiseTexture = internalClass.Parse(parsedParticleSystem.noiseTexture, scene, rootUrl);\r\n        }\r\n\r\n        // Emitter\r\n        let emitterType: IParticleEmitterType;\r\n        if (parsedParticleSystem.particleEmitterType) {\r\n            switch (parsedParticleSystem.particleEmitterType.type) {\r\n                case \"SphereParticleEmitter\":\r\n                    emitterType = new SphereParticleEmitter();\r\n                    break;\r\n                case \"SphereDirectedParticleEmitter\":\r\n                    emitterType = new SphereDirectedParticleEmitter();\r\n                    break;\r\n                case \"ConeEmitter\":\r\n                case \"ConeParticleEmitter\":\r\n                    emitterType = new ConeParticleEmitter();\r\n                    break;\r\n                case \"ConeDirectedParticleEmitter\":\r\n                    emitterType = new ConeDirectedParticleEmitter();\r\n                    break;\r\n                case \"CylinderParticleEmitter\":\r\n                    emitterType = new CylinderParticleEmitter();\r\n                    break;\r\n                case \"CylinderDirectedParticleEmitter\":\r\n                    emitterType = new CylinderDirectedParticleEmitter();\r\n                    break;\r\n                case \"HemisphericParticleEmitter\":\r\n                    emitterType = new HemisphericParticleEmitter();\r\n                    break;\r\n                case \"PointParticleEmitter\":\r\n                    emitterType = new PointParticleEmitter();\r\n                    break;\r\n                case \"MeshParticleEmitter\":\r\n                    emitterType = new MeshParticleEmitter();\r\n                    break;\r\n                case \"CustomParticleEmitter\":\r\n                    emitterType = new CustomParticleEmitter();\r\n                    break;\r\n                case \"BoxEmitter\":\r\n                case \"BoxParticleEmitter\":\r\n                default:\r\n                    emitterType = new BoxParticleEmitter();\r\n                    break;\r\n            }\r\n\r\n            emitterType.parse(parsedParticleSystem.particleEmitterType, scene);\r\n        } else {\r\n            emitterType = new BoxParticleEmitter();\r\n            emitterType.parse(parsedParticleSystem, scene);\r\n        }\r\n        particleSystem.particleEmitterType = emitterType;\r\n\r\n        // Animation sheet\r\n        particleSystem.startSpriteCellID = parsedParticleSystem.startSpriteCellID;\r\n        particleSystem.endSpriteCellID = parsedParticleSystem.endSpriteCellID;\r\n        particleSystem.spriteCellLoop = parsedParticleSystem.spriteCellLoop ?? true;\r\n        particleSystem.spriteCellWidth = parsedParticleSystem.spriteCellWidth;\r\n        particleSystem.spriteCellHeight = parsedParticleSystem.spriteCellHeight;\r\n        particleSystem.spriteCellChangeSpeed = parsedParticleSystem.spriteCellChangeSpeed;\r\n        particleSystem.spriteRandomStartCell = parsedParticleSystem.spriteRandomStartCell;\r\n\r\n        particleSystem.disposeOnStop = parsedParticleSystem.disposeOnStop ?? false;\r\n        particleSystem.manualEmitCount = parsedParticleSystem.manualEmitCount ?? -1;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON object to create a particle system.\r\n     * @param parsedParticleSystem The JSON object to parse\r\n     * @param sceneOrEngine The scene or the engine to create the particle system in\r\n     * @param rootUrl The root url to use to load external dependencies like texture\r\n     * @param doNotStart Ignore the preventAutoStart attribute and does not start\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns the Parsed particle system\r\n     */\r\n    public static Parse(parsedParticleSystem: any, sceneOrEngine: Scene | AbstractEngine, rootUrl: string, doNotStart = false, capacity?: number): ParticleSystem {\r\n        const name = parsedParticleSystem.name;\r\n        let custom: Nullable<Effect> = null;\r\n        let program: any = null;\r\n        let engine: AbstractEngine;\r\n        let scene: Nullable<Scene>;\r\n\r\n        if (sceneOrEngine instanceof AbstractEngine) {\r\n            engine = sceneOrEngine;\r\n        } else {\r\n            scene = sceneOrEngine;\r\n            engine = scene.getEngine();\r\n        }\r\n\r\n        if (parsedParticleSystem.customShader && _IsSideEffectImplemented((engine as any).createEffectForParticles)) {\r\n            program = parsedParticleSystem.customShader;\r\n            const defines: string = program.shaderOptions.defines.length > 0 ? program.shaderOptions.defines.join(\"\\n\") : \"\";\r\n            custom = (engine as any).createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);\r\n        }\r\n        const particleSystem = new ParticleSystem(name, capacity || parsedParticleSystem.capacity, sceneOrEngine, custom, parsedParticleSystem.isAnimationSheetEnabled);\r\n        particleSystem.customShader = program;\r\n        particleSystem._rootUrl = rootUrl;\r\n\r\n        if (parsedParticleSystem.id) {\r\n            particleSystem.id = parsedParticleSystem.id;\r\n        }\r\n\r\n        // SubEmitters\r\n        if (parsedParticleSystem.subEmitters) {\r\n            particleSystem.subEmitters = [];\r\n            for (const cell of parsedParticleSystem.subEmitters) {\r\n                const cellArray = [];\r\n                for (const sub of cell) {\r\n                    cellArray.push(SubEmitter.Parse(sub, sceneOrEngine, rootUrl));\r\n                }\r\n\r\n                particleSystem.subEmitters.push(cellArray);\r\n            }\r\n        }\r\n\r\n        // Attractors\r\n        if (parsedParticleSystem.attractors) {\r\n            for (const attractor of parsedParticleSystem.attractors) {\r\n                const newAttractor = new Attractor();\r\n                newAttractor.position = Vector3.FromArray(attractor.position);\r\n                newAttractor.strength = attractor.strength;\r\n                particleSystem.addAttractor(newAttractor);\r\n            }\r\n        }\r\n\r\n        ParticleSystem._Parse(parsedParticleSystem, particleSystem, sceneOrEngine, rootUrl);\r\n\r\n        if (parsedParticleSystem.textureMask) {\r\n            particleSystem.textureMask = Color4.FromArray(parsedParticleSystem.textureMask);\r\n        }\r\n\r\n        if (parsedParticleSystem.worldOffset) {\r\n            particleSystem.worldOffset = Vector3.FromArray(parsedParticleSystem.worldOffset);\r\n        }\r\n\r\n        // Auto start\r\n        if (parsedParticleSystem.preventAutoStart) {\r\n            particleSystem.preventAutoStart = parsedParticleSystem.preventAutoStart;\r\n        }\r\n\r\n        if (parsedParticleSystem.metadata) {\r\n            particleSystem.metadata = parsedParticleSystem.metadata;\r\n        }\r\n\r\n        if (!doNotStart && !particleSystem.preventAutoStart) {\r\n            particleSystem.start();\r\n        }\r\n\r\n        return particleSystem;\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object\r\n     * @param serializeTexture defines if the texture must be serialized as well\r\n     * @returns the JSON object\r\n     */\r\n    public override serialize(serializeTexture = false): any {\r\n        const serializationObject: any = {};\r\n\r\n        ParticleSystem._Serialize(serializationObject, this, serializeTexture);\r\n\r\n        serializationObject.textureMask = this.textureMask.asArray();\r\n        serializationObject.customShader = this.customShader;\r\n        serializationObject.preventAutoStart = this.preventAutoStart;\r\n        serializationObject.worldOffset = this.worldOffset.asArray();\r\n\r\n        if (this.metadata) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n\r\n        // SubEmitters\r\n        if (this.subEmitters) {\r\n            serializationObject.subEmitters = [];\r\n\r\n            if (!this._subEmitters) {\r\n                this._prepareSubEmitterInternalArray();\r\n            }\r\n\r\n            for (const subs of this._subEmitters) {\r\n                const cell = [];\r\n                for (const sub of subs) {\r\n                    if (!sub.particleSystem.doNotSerialize) {\r\n                        cell.push(sub.serialize(serializeTexture));\r\n                    }\r\n                }\r\n\r\n                serializationObject.subEmitters.push(cell);\r\n            }\r\n        }\r\n\r\n        // Attractors\r\n        if (this._attractors && this._attractors.length) {\r\n            serializationObject.attractors = [];\r\n            for (const attractor of this._attractors) {\r\n                serializationObject.attractors.push(attractor.serialize());\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _Serialize(serializationObject: any, particleSystem: IParticleSystem, serializeTexture: boolean) {\r\n        serializationObject.name = particleSystem.name;\r\n        serializationObject.id = particleSystem.id;\r\n\r\n        serializationObject.capacity = particleSystem.getCapacity();\r\n\r\n        serializationObject.disposeOnStop = particleSystem.disposeOnStop;\r\n        serializationObject.manualEmitCount = particleSystem.manualEmitCount;\r\n\r\n        // Emitter\r\n        if ((<AbstractMesh>particleSystem.emitter).position) {\r\n            const emitterMesh = <AbstractMesh>particleSystem.emitter;\r\n            serializationObject.emitterId = emitterMesh.id;\r\n        } else {\r\n            const emitterPosition = <Vector3>particleSystem.emitter;\r\n            serializationObject.emitter = emitterPosition.asArray();\r\n        }\r\n\r\n        // Emitter\r\n        if (particleSystem.particleEmitterType) {\r\n            serializationObject.particleEmitterType = particleSystem.particleEmitterType.serialize();\r\n        }\r\n\r\n        if (particleSystem.particleTexture) {\r\n            if (serializeTexture) {\r\n                serializationObject.texture = particleSystem.particleTexture.serialize();\r\n            } else {\r\n                const particleTexture = particleSystem.particleTexture as any;\r\n                serializationObject.textureName = particleSystem.particleTexture.name;\r\n                serializationObject.invertY = !!particleTexture._invertY;\r\n                // The texture pixels are referenced by name only, but its display settings would\r\n                // otherwise be lost on reload. Persist them so a serialize/parse round-trip keeps the\r\n                // same appearance.\r\n                const textureSettings: any = {};\r\n                for (const key of ParticleTextureSettingKeys) {\r\n                    textureSettings[key] = particleTexture[key];\r\n                }\r\n                textureSettings.samplingMode = particleTexture.samplingMode;\r\n                serializationObject.textureSettings = textureSettings;\r\n            }\r\n        }\r\n\r\n        serializationObject.isLocal = particleSystem.isLocal;\r\n\r\n        // Animations\r\n        SerializationHelper.AppendSerializedAnimations(particleSystem, serializationObject);\r\n        serializationObject.beginAnimationOnStart = particleSystem.beginAnimationOnStart;\r\n        serializationObject.beginAnimationFrom = particleSystem.beginAnimationFrom;\r\n        serializationObject.beginAnimationTo = particleSystem.beginAnimationTo;\r\n        serializationObject.beginAnimationLoop = particleSystem.beginAnimationLoop;\r\n\r\n        // Particle system\r\n        serializationObject.startDelay = particleSystem.startDelay;\r\n        serializationObject.renderingGroupId = particleSystem.renderingGroupId;\r\n        serializationObject.isBillboardBased = particleSystem.isBillboardBased;\r\n        serializationObject.billboardMode = particleSystem.billboardMode;\r\n        serializationObject.minAngularSpeed = particleSystem.minAngularSpeed;\r\n        serializationObject.maxAngularSpeed = particleSystem.maxAngularSpeed;\r\n        serializationObject.minSize = particleSystem.minSize;\r\n        serializationObject.maxSize = particleSystem.maxSize;\r\n        serializationObject.minScaleX = particleSystem.minScaleX;\r\n        serializationObject.maxScaleX = particleSystem.maxScaleX;\r\n        serializationObject.minScaleY = particleSystem.minScaleY;\r\n        serializationObject.maxScaleY = particleSystem.maxScaleY;\r\n        serializationObject.minEmitPower = particleSystem.minEmitPower;\r\n        serializationObject.maxEmitPower = particleSystem.maxEmitPower;\r\n        serializationObject.minLifeTime = particleSystem.minLifeTime;\r\n        serializationObject.maxLifeTime = particleSystem.maxLifeTime;\r\n        serializationObject.emitRate = particleSystem.emitRate;\r\n        serializationObject.gravity = particleSystem.gravity.asArray();\r\n        serializationObject.noiseStrength = particleSystem.noiseStrength.asArray();\r\n        serializationObject.color1 = particleSystem.color1.asArray();\r\n        serializationObject.color2 = particleSystem.color2.asArray();\r\n        serializationObject.colorDead = particleSystem.colorDead.asArray();\r\n        serializationObject.updateSpeed = particleSystem.updateSpeed;\r\n        serializationObject.targetStopDuration = particleSystem.targetStopDuration;\r\n        serializationObject.blendMode = particleSystem.blendMode;\r\n        serializationObject.preWarmCycles = particleSystem.preWarmCycles;\r\n        serializationObject.preWarmStepOffset = particleSystem.preWarmStepOffset;\r\n        serializationObject.minInitialRotation = particleSystem.minInitialRotation;\r\n        serializationObject.maxInitialRotation = particleSystem.maxInitialRotation;\r\n        serializationObject.startSpriteCellID = particleSystem.startSpriteCellID;\r\n        serializationObject.spriteCellLoop = particleSystem.spriteCellLoop;\r\n        serializationObject.endSpriteCellID = particleSystem.endSpriteCellID;\r\n        serializationObject.spriteCellChangeSpeed = particleSystem.spriteCellChangeSpeed;\r\n        serializationObject.spriteCellWidth = particleSystem.spriteCellWidth;\r\n        serializationObject.spriteCellHeight = particleSystem.spriteCellHeight;\r\n        serializationObject.spriteRandomStartCell = particleSystem.spriteRandomStartCell;\r\n        serializationObject.isAnimationSheetEnabled = particleSystem.isAnimationSheetEnabled;\r\n        serializationObject.useLogarithmicDepth = particleSystem.useLogarithmicDepth;\r\n\r\n        const colorGradients = particleSystem.getColorGradients();\r\n        if (colorGradients) {\r\n            serializationObject.colorGradients = [];\r\n            for (const colorGradient of colorGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: colorGradient.gradient,\r\n                    color1: colorGradient.color1.asArray(),\r\n                };\r\n\r\n                if (colorGradient.color2) {\r\n                    serializedGradient.color2 = colorGradient.color2.asArray();\r\n                } else {\r\n                    serializedGradient.color2 = colorGradient.color1.asArray();\r\n                }\r\n\r\n                serializationObject.colorGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const rampGradients = particleSystem.getRampGradients();\r\n        if (rampGradients) {\r\n            serializationObject.rampGradients = [];\r\n            for (const rampGradient of rampGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: rampGradient.gradient,\r\n                    color: rampGradient.color.asArray(),\r\n                };\r\n\r\n                serializationObject.rampGradients.push(serializedGradient);\r\n            }\r\n            serializationObject.useRampGradients = particleSystem.useRampGradients;\r\n        }\r\n\r\n        const colorRemapGradients = particleSystem.getColorRemapGradients();\r\n        if (colorRemapGradients) {\r\n            serializationObject.colorRemapGradients = [];\r\n            for (const colorRemapGradient of colorRemapGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: colorRemapGradient.gradient,\r\n                    factor1: colorRemapGradient.factor1,\r\n                };\r\n\r\n                if (colorRemapGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = colorRemapGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = colorRemapGradient.factor1;\r\n                }\r\n\r\n                serializationObject.colorRemapGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const alphaRemapGradients = particleSystem.getAlphaRemapGradients();\r\n        if (alphaRemapGradients) {\r\n            serializationObject.alphaRemapGradients = [];\r\n            for (const alphaRemapGradient of alphaRemapGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: alphaRemapGradient.gradient,\r\n                    factor1: alphaRemapGradient.factor1,\r\n                };\r\n\r\n                if (alphaRemapGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = alphaRemapGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = alphaRemapGradient.factor1;\r\n                }\r\n\r\n                serializationObject.alphaRemapGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const sizeGradients = particleSystem.getSizeGradients();\r\n        if (sizeGradients) {\r\n            serializationObject.sizeGradients = [];\r\n            for (const sizeGradient of sizeGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: sizeGradient.gradient,\r\n                    factor1: sizeGradient.factor1,\r\n                };\r\n\r\n                if (sizeGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = sizeGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = sizeGradient.factor1;\r\n                }\r\n\r\n                serializationObject.sizeGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const angularSpeedGradients = particleSystem.getAngularSpeedGradients();\r\n        if (angularSpeedGradients) {\r\n            serializationObject.angularSpeedGradients = [];\r\n            for (const angularSpeedGradient of angularSpeedGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: angularSpeedGradient.gradient,\r\n                    factor1: angularSpeedGradient.factor1,\r\n                };\r\n\r\n                if (angularSpeedGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = angularSpeedGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = angularSpeedGradient.factor1;\r\n                }\r\n\r\n                serializationObject.angularSpeedGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const velocityGradients = particleSystem.getVelocityGradients();\r\n        if (velocityGradients) {\r\n            serializationObject.velocityGradients = [];\r\n            for (const velocityGradient of velocityGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: velocityGradient.gradient,\r\n                    factor1: velocityGradient.factor1,\r\n                };\r\n\r\n                if (velocityGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = velocityGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = velocityGradient.factor1;\r\n                }\r\n\r\n                serializationObject.velocityGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const dragGradients = particleSystem.getDragGradients();\r\n        if (dragGradients) {\r\n            serializationObject.dragGradients = [];\r\n            for (const dragGradient of dragGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: dragGradient.gradient,\r\n                    factor1: dragGradient.factor1,\r\n                };\r\n\r\n                if (dragGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = dragGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = dragGradient.factor1;\r\n                }\r\n\r\n                serializationObject.dragGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const emitRateGradients = particleSystem.getEmitRateGradients();\r\n        if (emitRateGradients) {\r\n            serializationObject.emitRateGradients = [];\r\n            for (const emitRateGradient of emitRateGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: emitRateGradient.gradient,\r\n                    factor1: emitRateGradient.factor1,\r\n                };\r\n\r\n                if (emitRateGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = emitRateGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = emitRateGradient.factor1;\r\n                }\r\n\r\n                serializationObject.emitRateGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const startSizeGradients = particleSystem.getStartSizeGradients();\r\n        if (startSizeGradients) {\r\n            serializationObject.startSizeGradients = [];\r\n            for (const startSizeGradient of startSizeGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: startSizeGradient.gradient,\r\n                    factor1: startSizeGradient.factor1,\r\n                };\r\n\r\n                if (startSizeGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = startSizeGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = startSizeGradient.factor1;\r\n                }\r\n\r\n                serializationObject.startSizeGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const lifeTimeGradients = particleSystem.getLifeTimeGradients();\r\n        if (lifeTimeGradients) {\r\n            serializationObject.lifeTimeGradients = [];\r\n            for (const lifeTimeGradient of lifeTimeGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: lifeTimeGradient.gradient,\r\n                    factor1: lifeTimeGradient.factor1,\r\n                };\r\n\r\n                if (lifeTimeGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = lifeTimeGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = lifeTimeGradient.factor1;\r\n                }\r\n\r\n                serializationObject.lifeTimeGradients.push(serializedGradient);\r\n            }\r\n        }\r\n\r\n        const limitVelocityGradients = particleSystem.getLimitVelocityGradients();\r\n        if (limitVelocityGradients) {\r\n            serializationObject.limitVelocityGradients = [];\r\n            for (const limitVelocityGradient of limitVelocityGradients) {\r\n                const serializedGradient: any = {\r\n                    gradient: limitVelocityGradient.gradient,\r\n                    factor1: limitVelocityGradient.factor1,\r\n                };\r\n\r\n                if (limitVelocityGradient.factor2 !== undefined) {\r\n                    serializedGradient.factor2 = limitVelocityGradient.factor2;\r\n                } else {\r\n                    serializedGradient.factor2 = limitVelocityGradient.factor1;\r\n                }\r\n\r\n                serializationObject.limitVelocityGradients.push(serializedGradient);\r\n            }\r\n\r\n            serializationObject.limitVelocityDamping = particleSystem.limitVelocityDamping;\r\n        }\r\n\r\n        if (particleSystem.noiseTexture) {\r\n            serializationObject.noiseTexture = particleSystem.noiseTexture.serialize();\r\n        }\r\n    }\r\n\r\n    // Clone\r\n    /**\r\n     * Clones the particle system.\r\n     * @param name The name of the cloned object\r\n     * @param newEmitter The new emitter to use\r\n     * @param cloneTexture Also clone the textures if true\r\n     * @returns the cloned particle system\r\n     */\r\n    public override clone(name: string, newEmitter: any, cloneTexture = false): ParticleSystem {\r\n        const custom = { ...this._customWrappers };\r\n        let program: any = null;\r\n        const engine = this._engine;\r\n        if (_IsSideEffectImplemented(engine.createEffectForParticles)) {\r\n            if (this.customShader != null) {\r\n                program = this.customShader;\r\n                const defines: string = program.shaderOptions.defines.length > 0 ? program.shaderOptions.defines.join(\"\\n\") : \"\";\r\n                const effect = engine.createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);\r\n                if (!custom[0]) {\r\n                    this.setCustomEffect(effect, 0);\r\n                } else {\r\n                    custom[0].effect = effect;\r\n                }\r\n            }\r\n        }\r\n\r\n        const serialization = this.serialize(cloneTexture);\r\n        // When the texture is not serialized it is stored by name only, and Parse would reload it from\r\n        // that name (which can resolve to a different image and reset texture settings like level).\r\n        // Prefer a faithful copy of the source texture, and only skip the name-based reload when that\r\n        // copy is available (clone() can legally return null for textures that do not implement it).\r\n        const clonedTexture = cloneTexture === false && this.particleTexture ? this.particleTexture.clone() : null;\r\n        if (clonedTexture) {\r\n            serialization.textureName = undefined;\r\n        }\r\n        const result = ParticleSystem.Parse(serialization, this._scene || this._engine, this._rootUrl);\r\n        result.name = name;\r\n        result.customShader = program;\r\n        result._customWrappers = custom;\r\n\r\n        if (clonedTexture) {\r\n            result.particleTexture = clonedTexture;\r\n        }\r\n\r\n        if (newEmitter === undefined) {\r\n            newEmitter = this.emitter;\r\n        }\r\n\r\n        if (this.noiseTexture) {\r\n            result.noiseTexture = this.noiseTexture.clone();\r\n        }\r\n\r\n        result.emitter = newEmitter;\r\n        if (!this.preventAutoStart) {\r\n            result.start();\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleSystem.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleSystem(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    SubEmitter._ParseParticleSystem = ParticleSystem.Parse;\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type IDisposable, type Scene } from \"../scene\";\r\nimport { type Nullable } from \"../types\";\r\nimport { SceneSerializer } from \"./sceneSerializer\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { Light } from \"../Lights/light\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { Skeleton } from \"../Bones/skeleton\";\r\nimport { Material } from \"../Materials/material\";\r\nimport { MultiMaterial } from \"../Materials/multiMaterial.pure\";\r\nimport { TransformNode } from \"../Meshes/transformNode.pure\";\r\nimport { ParticleSystem } from \"../Particles/particleSystem.pure\";\r\nimport { MorphTargetManager } from \"../Morph/morphTargetManager\";\r\nimport { ShadowGenerator } from \"../Lights/Shadows/shadowGenerator\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { SerializationHelper } from \"./decorators.serialization\";\r\n\r\n/**\r\n * Class used to record delta files between 2 scene states\r\n */\r\nexport class SceneRecorder implements IDisposable {\r\n    private _trackedScene: Nullable<Scene> = null;\r\n    private _savedJSON: any;\r\n\r\n    /**\r\n     * Track a given scene. This means the current scene state will be considered the original state\r\n     * @param scene defines the scene to track\r\n     */\r\n    public track(scene: Scene) {\r\n        this._trackedScene = scene;\r\n\r\n        SerializationHelper.AllowLoadingUniqueId = true;\r\n        this._savedJSON = SceneSerializer.Serialize(scene);\r\n        SerializationHelper.AllowLoadingUniqueId = false;\r\n    }\r\n\r\n    /**\r\n     * Get the delta between current state and original state\r\n     * @returns a any containing the delta\r\n     */\r\n    public getDelta(): any {\r\n        if (!this._trackedScene) {\r\n            return null;\r\n        }\r\n\r\n        const currentForceSerializeBuffers = Texture.ForceSerializeBuffers;\r\n        Texture.ForceSerializeBuffers = false;\r\n\r\n        SerializationHelper.AllowLoadingUniqueId = true;\r\n        const newJSON = SceneSerializer.Serialize(this._trackedScene);\r\n        SerializationHelper.AllowLoadingUniqueId = false;\r\n        const deltaJSON: any = {};\r\n\r\n        for (const node in newJSON) {\r\n            this._compareCollections(node, this._savedJSON[node], newJSON[node], deltaJSON);\r\n        }\r\n\r\n        Texture.ForceSerializeBuffers = currentForceSerializeBuffers;\r\n\r\n        return deltaJSON;\r\n    }\r\n\r\n    private _compareArray(key: string, original: any[], current: any[], deltaJSON: any) {\r\n        if (original.length === 0 && current.length === 0) {\r\n            return true;\r\n        }\r\n\r\n        // Numbers?\r\n        if ((original.length && !isNaN(original[0])) || (current.length && !isNaN(current[0]))) {\r\n            if (original.length !== current.length) {\r\n                return false;\r\n            }\r\n\r\n            if (original.length === 0) {\r\n                return true;\r\n            }\r\n            for (let index = 0; index < original.length; index++) {\r\n                if (original[index] !== current[index]) {\r\n                    deltaJSON[key] = current;\r\n                    return false;\r\n                }\r\n            }\r\n            return true;\r\n        }\r\n\r\n        // let's use uniqueId to find similar objects\r\n        const originalUniqueIds: number[] = [];\r\n        for (let index = 0; index < original.length; index++) {\r\n            const originalObject = original[index];\r\n            const originalUniqueId = originalObject.uniqueId;\r\n\r\n            originalUniqueIds.push(originalUniqueId);\r\n            // Look for that object in current state\r\n            const currentObjects = current.filter((c) => c.uniqueId === originalUniqueId);\r\n            if (currentObjects.length) {\r\n                // We have a candidate\r\n                const currentObject = currentObjects[0];\r\n\r\n                const newObject: any = {};\r\n                if (!this._compareObjects(originalObject, currentObject, newObject)) {\r\n                    if (!deltaJSON[key]) {\r\n                        deltaJSON[key] = [];\r\n                    }\r\n                    newObject.__state = {\r\n                        id: currentObject.id || currentObject.name,\r\n                    };\r\n                    deltaJSON[key].push(newObject);\r\n                }\r\n            } else {\r\n                // We need to delete\r\n                const newObject: any = {\r\n                    __state: {\r\n                        deleteId: originalObject.id || originalObject.name,\r\n                    },\r\n                };\r\n                if (!deltaJSON[key]) {\r\n                    deltaJSON[key] = [];\r\n                }\r\n                deltaJSON[key].push(newObject);\r\n            }\r\n        }\r\n\r\n        // Checking for new objects\r\n        for (let index = 0; index < current.length; index++) {\r\n            const currentObject = current[index];\r\n            const currentUniqueId = currentObject.uniqueId;\r\n\r\n            // Object was added\r\n            if (originalUniqueIds.indexOf(currentUniqueId) === -1) {\r\n                if (!deltaJSON[key]) {\r\n                    deltaJSON[key] = [];\r\n                }\r\n\r\n                deltaJSON[key].push(currentObject);\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _compareObjects(originalObjet: any, currentObject: any, deltaJSON: any) {\r\n        let aDifferenceWasFound = false;\r\n\r\n        for (const prop in originalObjet) {\r\n            if (!Object.prototype.hasOwnProperty.call(originalObjet, prop)) {\r\n                continue;\r\n            }\r\n            const originalValue = originalObjet[prop];\r\n            const currentValue = currentObject[prop];\r\n            let diffFound = false;\r\n\r\n            if (Array.isArray(originalValue)) {\r\n                diffFound = JSON.stringify(originalValue) !== JSON.stringify(currentValue);\r\n            } else if (!isNaN(originalValue) || Object.prototype.toString.call(originalValue) == \"[object String]\") {\r\n                diffFound = originalValue !== currentValue;\r\n            } else if (typeof originalValue === \"object\" && typeof currentValue === \"object\") {\r\n                const newObject = {};\r\n                if (!this._compareObjects(originalValue, currentValue, newObject)) {\r\n                    deltaJSON[prop] = newObject;\r\n                    aDifferenceWasFound = true;\r\n                }\r\n            }\r\n\r\n            if (diffFound) {\r\n                aDifferenceWasFound = true;\r\n                deltaJSON[prop] = currentValue;\r\n            }\r\n        }\r\n\r\n        return !aDifferenceWasFound;\r\n    }\r\n\r\n    private _compareCollections(key: string, original: any[], current: any[], deltaJSON: any) {\r\n        // Same ?\r\n        if (original === current) {\r\n            return;\r\n        }\r\n\r\n        if (original && current) {\r\n            // Array?\r\n            if (Array.isArray(original) && Array.isArray(current)) {\r\n                if (this._compareArray(key, original, current, deltaJSON)) {\r\n                    return;\r\n                }\r\n            } else if (typeof original === \"object\" && typeof current === \"object\") {\r\n                // Object\r\n                const newObject = {};\r\n                if (!this._compareObjects(original, current, newObject)) {\r\n                    deltaJSON[key] = newObject;\r\n                }\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the recorder.\r\n     */\r\n    public dispose() {\r\n        this._trackedScene = null;\r\n        this._savedJSON = null;\r\n    }\r\n\r\n    private static GetShadowGeneratorById(scene: Scene, id: string) {\r\n        const allGenerators = scene.lights.map((l) => l.getShadowGenerators());\r\n\r\n        for (const generators of allGenerators) {\r\n            if (generators) {\r\n                const iterator = generators.values();\r\n                for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n                    const generator = key.value;\r\n                    if (generator && generator.id === id) {\r\n                        return generator;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Apply a given delta to a given scene\r\n     * @param deltaJSON defines the JSON containing the delta\r\n     * @param scene defines the scene to apply the delta to\r\n     */\r\n    public static ApplyDelta(deltaJSON: any | string, scene: Scene) {\r\n        if (typeof deltaJSON === \"string\") {\r\n            deltaJSON = JSON.parse(deltaJSON);\r\n        }\r\n\r\n        // Scene\r\n        const anyScene = scene as any;\r\n        for (const prop in deltaJSON) {\r\n            const source = deltaJSON[prop];\r\n            const property = anyScene[prop];\r\n\r\n            if (Array.isArray(property) || prop === \"shadowGenerators\") {\r\n                // Restore array\r\n                switch (prop) {\r\n                    case \"cameras\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getCameraById.bind(scene), (data) => Camera.Parse(data, scene));\r\n                        break;\r\n                    case \"lights\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getLightById.bind(scene), (data) => Light.Parse(data, scene));\r\n                        break;\r\n                    case \"shadowGenerators\":\r\n                        this._ApplyDeltaForEntity(\r\n                            source,\r\n                            scene,\r\n                            (id) => this.GetShadowGeneratorById(scene, id),\r\n                            (data) => ShadowGenerator.Parse(data, scene)\r\n                        );\r\n                        break;\r\n                    case \"meshes\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getMeshById.bind(scene), (data) => Mesh.Parse(data, scene, \"\"));\r\n                        break;\r\n                    case \"skeletons\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getSkeletonById.bind(scene), (data) => Skeleton.Parse(data, scene));\r\n                        break;\r\n                    case \"materials\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getMaterialById.bind(scene), (data) => Material.Parse(data, scene, \"\"));\r\n                        break;\r\n                    case \"multiMaterials\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getMaterialById.bind(scene), (data) => MultiMaterial.Parse(data, scene, \"\"));\r\n                        break;\r\n                    case \"transformNodes\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getTransformNodeById.bind(scene), (data) => TransformNode.Parse(data, scene, \"\"));\r\n                        break;\r\n                    case \"particleSystems\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getParticleSystemById.bind(scene), (data) => ParticleSystem.Parse(data, scene, \"\"));\r\n                        break;\r\n                    case \"morphTargetManagers\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getMorphTargetById.bind(scene), (data) => MorphTargetManager.Parse(data, scene));\r\n                        break;\r\n                    case \"postProcesses\":\r\n                        this._ApplyDeltaForEntity(source, scene, scene.getPostProcessByName.bind(scene), (data) => PostProcess.Parse(data, scene, \"\"));\r\n                        break;\r\n                }\r\n            } else if (!isNaN(property)) {\r\n                anyScene[prop] = source;\r\n            } else if (property.fromArray) {\r\n                property.fromArray(source);\r\n            }\r\n        }\r\n    }\r\n\r\n    private static _ApplyPropertiesToEntity(deltaJSON: any, entity: any) {\r\n        for (const prop in deltaJSON) {\r\n            const source = deltaJSON[prop];\r\n            const property = entity[prop];\r\n\r\n            if (property === undefined) {\r\n                continue;\r\n            }\r\n\r\n            if (!isNaN(property) || Array.isArray(property)) {\r\n                entity[prop] = source;\r\n            } else if (property.fromArray) {\r\n                property.fromArray(source);\r\n            } else if (typeof property === \"object\" && property !== null) {\r\n                this._ApplyPropertiesToEntity(source, property);\r\n            }\r\n        }\r\n    }\r\n\r\n    private static _ApplyDeltaForEntity(sources: any[], scene: Scene, finder: (id: string) => any, addNew: (data: any) => void) {\r\n        for (const source of sources) {\r\n            // Update\r\n            if (source.__state && source.__state.id !== undefined) {\r\n                const targetEntity = finder(source.__state.id);\r\n\r\n                if (targetEntity) {\r\n                    // This first pass applies properties that aren't on the serialization list\r\n                    this._ApplyPropertiesToEntity(source, targetEntity);\r\n                    // The second pass applies the serializable properties\r\n                    SerializationHelper.ParseProperties(source, targetEntity, scene, null);\r\n                }\r\n            } else if (source.__state && source.__state.deleteId !== undefined) {\r\n                const target = finder(source.__state.deleteId);\r\n                target?.dispose();\r\n            } else {\r\n                // New\r\n                addNew(source);\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type DeepImmutable, type Nullable } from \"../types\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\n\r\n// This implementation was based on the original MIT-licensed TRACE repository\r\n// from https://github.com/septagon/TRACE.\r\n\r\n/**\r\n * Generic implementation of Levenshtein distance.\r\n */\r\nnamespace Levenshtein {\r\n    /**\r\n     * Alphabet from which to construct sequences to be compared using Levenshtein\r\n     * distance.\r\n     */\r\n    export class Alphabet<T> {\r\n        private _characterToIdx: Map<T, number>;\r\n        private _insertionCosts: number[];\r\n        private _deletionCosts: number[];\r\n        private _substitutionCosts: number[][];\r\n\r\n        /**\r\n         * Serialize the Alphabet to JSON string.\r\n         * @returns JSON serialization\r\n         */\r\n        public serialize(): string {\r\n            const jsonObject: any = {};\r\n\r\n            const characters = new Array<T>(this._characterToIdx.size);\r\n            this._characterToIdx.forEach((v, k) => {\r\n                characters[v] = k;\r\n            });\r\n            jsonObject[\"characters\"] = characters;\r\n\r\n            jsonObject[\"insertionCosts\"] = this._insertionCosts;\r\n            jsonObject[\"deletionCosts\"] = this._deletionCosts;\r\n            jsonObject[\"substitutionCosts\"] = this._substitutionCosts;\r\n\r\n            return JSON.stringify(jsonObject);\r\n        }\r\n\r\n        /**\r\n         * Parse an Alphabet from a JSON serialization.\r\n         * @param json JSON string to deserialize\r\n         * @returns deserialized Alphabet\r\n         */\r\n        public static Deserialize<T>(json: string): Alphabet<T> {\r\n            const jsonObject = JSON.parse(json);\r\n            const alphabet = new Alphabet(jsonObject[\"characters\"] as T[]);\r\n            alphabet._insertionCosts = jsonObject[\"insertionCosts\"];\r\n            alphabet._deletionCosts = jsonObject[\"deletionCosts\"];\r\n            alphabet._substitutionCosts = jsonObject[\"substitutionCosts\"];\r\n            return alphabet;\r\n        }\r\n\r\n        /**\r\n         * Create a new Alphabet.\r\n         * @param characters characters of the alphabet\r\n         * @param charToInsertionCost function mapping characters to insertion costs\r\n         * @param charToDeletionCost function mapping characters to deletion costs\r\n         * @param charsToSubstitutionCost function mapping character pairs to substitution costs\r\n         */\r\n        public constructor(\r\n            characters: Array<T>,\r\n            charToInsertionCost: Nullable<(char: T) => number> = null,\r\n            charToDeletionCost: Nullable<(char: T) => number> = null,\r\n            charsToSubstitutionCost: Nullable<(outChar: T, inChar: T) => number> = null\r\n        ) {\r\n            charToInsertionCost = charToInsertionCost ?? (() => 1);\r\n            charToDeletionCost = charToDeletionCost ?? (() => 1);\r\n            charsToSubstitutionCost = charsToSubstitutionCost ?? ((a: T, b: T) => (a === b ? 0 : 1));\r\n\r\n            this._characterToIdx = new Map<T, number>();\r\n            this._insertionCosts = new Array<number>(characters.length);\r\n            this._deletionCosts = new Array<number>(characters.length);\r\n            this._substitutionCosts = new Array<Array<number>>(characters.length);\r\n\r\n            let c: T;\r\n            for (let outerIdx = 0; outerIdx < characters.length; ++outerIdx) {\r\n                c = characters[outerIdx];\r\n                this._characterToIdx.set(c, outerIdx);\r\n                this._insertionCosts[outerIdx] = charToInsertionCost(c);\r\n                this._deletionCosts[outerIdx] = charToDeletionCost(c);\r\n\r\n                this._substitutionCosts[outerIdx] = new Array<number>(characters.length);\r\n                for (let innerIdx = outerIdx; innerIdx < characters.length; ++innerIdx) {\r\n                    this._substitutionCosts[outerIdx][innerIdx] = charsToSubstitutionCost(c, characters[innerIdx]);\r\n                }\r\n            }\r\n        }\r\n\r\n        /**\r\n         * Get the index (internally-assigned number) for a character.\r\n         * @param char character\r\n         * @returns index\r\n         */\r\n        public getCharacterIdx(char: T): number {\r\n            return this._characterToIdx.get(char)!;\r\n        }\r\n\r\n        /**\r\n         * Get the insertion cost of a character from its index.\r\n         * @param idx character index\r\n         * @returns insertion cost\r\n         */\r\n        public getInsertionCost(idx: number): number {\r\n            return this._insertionCosts[idx];\r\n        }\r\n\r\n        /**\r\n         * Get the deletion cost of a character from its index.\r\n         * @param idx character index\r\n         * @returns deletion cost\r\n         */\r\n        public getDeletionCost(idx: number): number {\r\n            return this._deletionCosts[idx];\r\n        }\r\n\r\n        /**\r\n         * Gets the cost to substitute two characters. NOTE: this cost is\r\n         * required to be bi-directional, meaning it cannot matter which of\r\n         * the provided characters is being removed and which is being inserted.\r\n         * @param idx1 the first character index\r\n         * @param idx2 the second character index\r\n         * @returns substitution cost\r\n         */\r\n        public getSubstitutionCost(idx1: number, idx2: number): number {\r\n            const min = Math.min(idx1, idx2);\r\n            const max = Math.max(idx1, idx2);\r\n\r\n            return this._substitutionCosts[min][max];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Character sequence intended to be compared against other Sequences created\r\n     * with the same Alphabet in order to compute Levenshtein distance.\r\n     */\r\n    export class Sequence<T> {\r\n        private _alphabet: Alphabet<T>;\r\n        private _characters: number[];\r\n\r\n        // Scratch values\r\n        private static readonly _MAX_SEQUENCE_LENGTH = 256;\r\n        private static _CostMatrix = [...Array(Sequence._MAX_SEQUENCE_LENGTH + 1)].map(() => new Array<number>(Sequence._MAX_SEQUENCE_LENGTH + 1));\r\n        private static _InsertionCost: number;\r\n        private static _DeletionCost: number;\r\n        private static _SubstitutionCost: number;\r\n\r\n        /**\r\n         * Serialize to JSON string. JSON representation does NOT include the Alphabet\r\n         * from which this Sequence was created; Alphabet must be independently\r\n         * serialized.\r\n         * @returns JSON string\r\n         */\r\n        public serialize(): string {\r\n            return JSON.stringify(this._characters);\r\n        }\r\n\r\n        /**\r\n         * Deserialize from JSON string and Alphabet. This should be the same Alphabet\r\n         * from which the Sequence was originally created, which must be serialized and\r\n         * deserialized independently so that it can be passed in here.\r\n         * @param json JSON string representation of Sequence\r\n         * @param alphabet Alphabet from which Sequence was originally created\r\n         * @returns Sequence\r\n         */\r\n        public static Deserialize<T>(json: string, alphabet: Alphabet<T>): Sequence<T> {\r\n            const sequence = new Sequence([], alphabet);\r\n            sequence._characters = JSON.parse(json);\r\n            return sequence;\r\n        }\r\n\r\n        /**\r\n         * Create a new Sequence.\r\n         * @param characters characters in the new Sequence\r\n         * @param alphabet Alphabet, which must include all used characters\r\n         */\r\n        public constructor(characters: T[], alphabet: Alphabet<T>) {\r\n            if (characters.length > Sequence._MAX_SEQUENCE_LENGTH) {\r\n                throw new Error(\"Sequences longer than \" + Sequence._MAX_SEQUENCE_LENGTH + \" not supported.\");\r\n            }\r\n            this._alphabet = alphabet;\r\n            this._characters = characters.map((c) => this._alphabet.getCharacterIdx(c));\r\n        }\r\n\r\n        /**\r\n         * Get the distance between this Sequence and another.\r\n         * @param other sequence to compare to\r\n         * @returns Levenshtein distance\r\n         */\r\n        public distance(other: Sequence<T>): number {\r\n            return Sequence._Distance<T>(this, other);\r\n        }\r\n\r\n        /**\r\n         * Compute the Levenshtein distance between two Sequences.\r\n         * @param a first Sequence\r\n         * @param b second Sequence\r\n         * @returns Levenshtein distance\r\n         */\r\n        private static _Distance<T>(a: Sequence<T>, b: Sequence<T>): number {\r\n            const alphabet = a._alphabet;\r\n            if (alphabet !== b._alphabet) {\r\n                throw new Error(\"Cannot Levenshtein compare Sequences built from different alphabets.\");\r\n            }\r\n            const aChars = a._characters;\r\n            const bChars = b._characters;\r\n            const aLength = aChars.length;\r\n            const bLength = bChars.length;\r\n\r\n            const costMatrix = Sequence._CostMatrix;\r\n            costMatrix[0][0] = 0;\r\n            for (let idx = 0; idx < aLength; ++idx) {\r\n                costMatrix[idx + 1][0] = costMatrix[idx][0] + alphabet.getInsertionCost(aChars[idx]);\r\n            }\r\n            for (let idx = 0; idx < bLength; ++idx) {\r\n                costMatrix[0][idx + 1] = costMatrix[0][idx] + alphabet.getInsertionCost(bChars[idx]);\r\n            }\r\n\r\n            for (let aIdx = 0; aIdx < aLength; ++aIdx) {\r\n                for (let bIdx = 0; bIdx < bLength; ++bIdx) {\r\n                    Sequence._InsertionCost = costMatrix[aIdx + 1][bIdx] + alphabet.getInsertionCost(bChars[bIdx]);\r\n                    Sequence._DeletionCost = costMatrix[aIdx][bIdx + 1] + alphabet.getDeletionCost(aChars[aIdx]);\r\n                    Sequence._SubstitutionCost = costMatrix[aIdx][bIdx] + alphabet.getSubstitutionCost(aChars[aIdx], bChars[bIdx]);\r\n\r\n                    costMatrix[aIdx + 1][bIdx + 1] = Math.min(Sequence._InsertionCost, Sequence._DeletionCost, Sequence._SubstitutionCost);\r\n                }\r\n            }\r\n\r\n            return costMatrix[aLength][bLength];\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * A 3D trajectory consisting of an order list of vectors describing a\r\n * path of motion through 3D space.\r\n */\r\nexport class Trajectory {\r\n    private _points: Vector3[];\r\n    private readonly _segmentLength: number;\r\n\r\n    /**\r\n     * Serialize to JSON.\r\n     * @returns serialized JSON string\r\n     */\r\n    public serialize(): string {\r\n        return JSON.stringify(this);\r\n    }\r\n\r\n    /**\r\n     * Deserialize from JSON.\r\n     * @param json serialized JSON string\r\n     * @returns deserialized Trajectory\r\n     */\r\n    public static Deserialize(json: string): Trajectory {\r\n        const jsonObject = JSON.parse(json);\r\n        const trajectory = new Trajectory(jsonObject[\"_segmentLength\"]);\r\n        trajectory._points = jsonObject[\"_points\"].map((pt: any) => {\r\n            return new Vector3(pt[\"_x\"], pt[\"_y\"], pt[\"_z\"]);\r\n        });\r\n        return trajectory;\r\n    }\r\n\r\n    /**\r\n     * Create a new empty Trajectory.\r\n     * @param segmentLength radius of discretization for Trajectory points\r\n     */\r\n    public constructor(segmentLength: number = 0.01) {\r\n        this._points = [];\r\n        this._segmentLength = segmentLength;\r\n    }\r\n\r\n    /**\r\n     * Get the length of the Trajectory.\r\n     * @returns length of the Trajectory\r\n     */\r\n    public getLength(): number {\r\n        return this._points.length * this._segmentLength;\r\n    }\r\n\r\n    /**\r\n     * Append a new point to the Trajectory.\r\n     * NOTE: This implementation has many allocations.\r\n     * @param point point to append to the Trajectory\r\n     */\r\n    public add(point: DeepImmutable<Vector3>): void {\r\n        let numPoints = this._points.length;\r\n        if (numPoints === 0) {\r\n            this._points.push(point.clone());\r\n        } else {\r\n            const getT = () => this._segmentLength / Vector3.Distance(this._points[numPoints - 1], point);\r\n            for (let t = getT(); t <= 1.0; t = getT()) {\r\n                const newPoint = this._points[numPoints - 1].scale(1.0 - t);\r\n                point.scaleAndAddToRef(t, newPoint);\r\n                this._points.push(newPoint);\r\n                ++numPoints;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a new Trajectory with a segment length chosen to make it\r\n     * probable that the new Trajectory will have a specified number of\r\n     * segments. This operation is imprecise.\r\n     * @param targetResolution number of segments desired\r\n     * @returns new Trajectory with approximately the requested number of segments\r\n     */\r\n    public resampleAtTargetResolution(targetResolution: number): Trajectory {\r\n        const resampled = new Trajectory(this.getLength() / targetResolution);\r\n        for (const pt of this._points) {\r\n            resampled.add(pt);\r\n        }\r\n        return resampled;\r\n    }\r\n\r\n    /**\r\n     * Convert Trajectory segments into tokenized representation. This\r\n     * representation is an array of numbers where each nth number is the\r\n     * index of the token which is most similar to the nth segment of the\r\n     * Trajectory.\r\n     * @param tokens list of vectors which serve as discrete tokens\r\n     * @returns list of indices of most similar token per segment\r\n     */\r\n    public tokenize(tokens: DeepImmutable<Vector3[]>): number[] {\r\n        const tokenization: number[] = [];\r\n\r\n        const segmentDir = new Vector3();\r\n        for (let idx = 2; idx < this._points.length; ++idx) {\r\n            if (Trajectory._TransformSegmentDirToRef(this._points[idx - 2], this._points[idx - 1], this._points[idx], segmentDir)) {\r\n                tokenization.push(Trajectory._TokenizeSegment(segmentDir, tokens));\r\n            }\r\n        }\r\n\r\n        return tokenization;\r\n    }\r\n\r\n    private static _ForwardDir = new Vector3();\r\n    private static _InverseFromVec = new Vector3();\r\n    private static _UpDir = new Vector3();\r\n    private static _FromToVec = new Vector3();\r\n    private static _LookMatrix = new Matrix();\r\n\r\n    /**\r\n     * Transform the rotation (i.e., direction) of a segment to isolate\r\n     * the relative transformation represented by the segment. This operation\r\n     * may or may not succeed due to singularities in the equations that define\r\n     * motion relativity in this context.\r\n     * @param priorVec the origin of the prior segment\r\n     * @param fromVec the origin of the current segment\r\n     * @param toVec the destination of the current segment\r\n     * @param result reference to output variable\r\n     * @returns whether or not transformation was successful\r\n     */\r\n    private static _TransformSegmentDirToRef(priorVec: DeepImmutable<Vector3>, fromVec: DeepImmutable<Vector3>, toVec: DeepImmutable<Vector3>, result: Vector3): boolean {\r\n        const dotProductSampleRejectionThreshold = 0.98;\r\n\r\n        fromVec.subtractToRef(priorVec, Trajectory._ForwardDir);\r\n        Trajectory._ForwardDir.normalize();\r\n        fromVec.scaleToRef(-1, Trajectory._InverseFromVec);\r\n        Trajectory._InverseFromVec.normalize();\r\n\r\n        if (Math.abs(Vector3.Dot(Trajectory._ForwardDir, Trajectory._InverseFromVec)) > dotProductSampleRejectionThreshold) {\r\n            return false;\r\n        }\r\n\r\n        Vector3.CrossToRef(Trajectory._ForwardDir, Trajectory._InverseFromVec, Trajectory._UpDir);\r\n        Trajectory._UpDir.normalize();\r\n        Matrix.LookAtLHToRef(priorVec, fromVec, Trajectory._UpDir, Trajectory._LookMatrix);\r\n        toVec.subtractToRef(fromVec, Trajectory._FromToVec);\r\n        Trajectory._FromToVec.normalize();\r\n        Vector3.TransformNormalToRef(Trajectory._FromToVec, Trajectory._LookMatrix, result);\r\n        return true;\r\n    }\r\n\r\n    private static _BestMatch: number;\r\n    private static _Score: number;\r\n    private static _BestScore: number;\r\n\r\n    /**\r\n     * Determine which token vector is most similar to the\r\n     * segment vector.\r\n     * @param segment segment vector\r\n     * @param tokens token vector list\r\n     * @returns index of the most similar token to the segment\r\n     */\r\n    private static _TokenizeSegment(segment: DeepImmutable<Vector3>, tokens: DeepImmutable<Vector3[]>): number {\r\n        Trajectory._BestMatch = 0;\r\n        Trajectory._Score = Vector3.Dot(segment, tokens[0]);\r\n        Trajectory._BestScore = Trajectory._Score;\r\n        for (let idx = 1; idx < tokens.length; ++idx) {\r\n            Trajectory._Score = Vector3.Dot(segment, tokens[idx]);\r\n            if (Trajectory._Score > Trajectory._BestScore) {\r\n                Trajectory._BestMatch = idx;\r\n                Trajectory._BestScore = Trajectory._Score;\r\n            }\r\n        }\r\n\r\n        return Trajectory._BestMatch;\r\n    }\r\n}\r\n\r\n/**\r\n * Collection of vectors intended to be used as the basis of Trajectory\r\n * tokenization for Levenshtein distance comparison. Canonically, a\r\n * Vector3Alphabet will resemble a \"spikeball\" of vectors distributed\r\n * roughly evenly over the surface of the unit sphere.\r\n */\r\nclass Vector3Alphabet {\r\n    /**\r\n     * Characters in the alphabet.\r\n     * NOTE: There is no reason for this property to exist and this class should just extend\r\n     * Array<Vector3>, except that doing so produces bizarre build-time errors indicating that\r\n     * the ES5 library itself fails its own TypeDoc validation.\r\n     */\r\n    public chars: Vector3[];\r\n\r\n    /**\r\n     * Helper method to create new \"spikeball\" Vector3Alphabets. Uses a naive\r\n     * optimize-from-random strategy to space points around the unit sphere\r\n     * surface as a simple alternative to really doing the math to tile the\r\n     * sphere.\r\n     * @param alphabetSize size of the desired alphabet\r\n     * @param iterations number of iterations over which to optimize the \"spikeball\"\r\n     * @param startingStepSize distance factor to move points in early optimization iterations\r\n     * @param endingStepSize distance factor to move points in late optimization iterations\r\n     * @param fixedValues alphabet \"characters\" that are required and cannot be moved by optimization\r\n     * @returns a new randomly generated and optimized Vector3Alphabet of the specified size\r\n     */\r\n    public static Generate(\r\n        alphabetSize: number = 64,\r\n        iterations: number = 256,\r\n        startingStepSize: number = 0.1,\r\n        endingStepSize: number = 0.001,\r\n        fixedValues: DeepImmutable<Vector3[]> = []\r\n    ): Vector3Alphabet {\r\n        const epsilon = 0.001;\r\n        const epsilonSquared = epsilon * epsilon;\r\n\r\n        const alphabet = new Vector3Alphabet(alphabetSize);\r\n        for (let idx = 0; idx < alphabetSize; ++idx) {\r\n            alphabet.chars[idx] = new Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);\r\n            alphabet.chars[idx].normalize();\r\n        }\r\n\r\n        for (let idx = 0; idx < fixedValues.length; ++idx) {\r\n            alphabet.chars[idx].copyFrom(fixedValues[idx]);\r\n        }\r\n\r\n        let stepSize: number;\r\n        let distSq: number;\r\n        const force = new Vector3();\r\n        const scratch = new Vector3();\r\n        const lerp = (l: number, r: number, t: number) => (1.0 - t) * l + t * r;\r\n        for (let iteration = 0; iteration < iterations; ++iteration) {\r\n            stepSize = lerp(startingStepSize, endingStepSize, iteration / (iterations - 1));\r\n            for (let idx = fixedValues.length; idx < alphabet.chars.length; ++idx) {\r\n                force.copyFromFloats(0, 0, 0);\r\n                for (const pt of alphabet.chars) {\r\n                    alphabet.chars[idx].subtractToRef(pt, scratch);\r\n                    distSq = scratch.lengthSquared();\r\n                    if (distSq > epsilonSquared) {\r\n                        scratch.scaleAndAddToRef(1 / (scratch.lengthSquared() * distSq), force);\r\n                    }\r\n                }\r\n                force.scaleInPlace(stepSize);\r\n                alphabet.chars[idx].addInPlace(force);\r\n                alphabet.chars[idx].normalize();\r\n            }\r\n        }\r\n\r\n        return alphabet;\r\n    }\r\n\r\n    /**\r\n     * Serialize to JSON.\r\n     * @returns JSON serialization\r\n     */\r\n    public serialize(): string {\r\n        return JSON.stringify(this.chars);\r\n    }\r\n\r\n    /**\r\n     * Deserialize from JSON.\r\n     * @param json JSON serialization\r\n     * @returns deserialized Vector3Alphabet\r\n     */\r\n    public static Deserialize(json: string): Vector3Alphabet {\r\n        const jsonObject = JSON.parse(json);\r\n        const alphabet = new Vector3Alphabet(jsonObject.length);\r\n        for (let idx = 0; idx < jsonObject.length; ++idx) {\r\n            alphabet.chars[idx] = new Vector3(jsonObject[idx][\"_x\"], jsonObject[idx][\"_y\"], jsonObject[idx][\"_z\"]);\r\n        }\r\n        return alphabet;\r\n    }\r\n\r\n    private constructor(size: number) {\r\n        this.chars = new Array(size);\r\n    }\r\n}\r\n\r\n/**\r\n * Class which formalizes the manner in which a Vector3Alphabet is used to tokenize and\r\n * describe a Trajectory. This class houses the functionality which determines what\r\n * attributes of Trajectories are and are not considered important, such as scale.\r\n */\r\nclass TrajectoryDescriptor {\r\n    private static readonly _FINEST_DESCRIPTOR_RESOLUTION = 32;\r\n\r\n    private _sequences: Levenshtein.Sequence<number>[];\r\n\r\n    /**\r\n     * Serialize to JSON.\r\n     * @returns JSON serialization\r\n     */\r\n    public serialize(): string {\r\n        return JSON.stringify(this._sequences.map((sequence) => sequence.serialize()));\r\n    }\r\n\r\n    /**\r\n     * Deserialize from JSON string and Alphabet. This should be the same Alphabet\r\n     * from which the descriptor was originally created, which must be serialized and\r\n     * deserialized independently so that it can be passed in here.\r\n     * @param json JSON serialization\r\n     * @param alphabet Alphabet from which descriptor was originally created\r\n     * @returns deserialized TrajectoryDescriptor\r\n     */\r\n    public static Deserialize(json: string, alphabet: Levenshtein.Alphabet<number>): TrajectoryDescriptor {\r\n        const descriptor = new TrajectoryDescriptor();\r\n        descriptor._sequences = (JSON.parse(json) as string[]).map((s) => Levenshtein.Sequence.Deserialize(s, alphabet));\r\n        return descriptor;\r\n    }\r\n\r\n    /**\r\n     * Create a new TrajectoryDescriptor to describe a provided Trajectory according\r\n     * to the provided alphabets.\r\n     * @param trajectory Trajectory to be described\r\n     * @param vector3Alphabet Vector3Alphabet to be used to tokenize the Trajectory\r\n     * @param levenshteinAlphabet Levenshtein.Alphabet to be used as basis for comparison with other descriptors\r\n     * @returns TrajectoryDescriptor describing provided Trajectory\r\n     */\r\n    public static CreateFromTrajectory(trajectory: Trajectory, vector3Alphabet: Vector3Alphabet, levenshteinAlphabet: Levenshtein.Alphabet<number>): TrajectoryDescriptor {\r\n        return TrajectoryDescriptor.CreateFromTokenizationPyramid(TrajectoryDescriptor._GetTokenizationPyramid(trajectory, vector3Alphabet), levenshteinAlphabet);\r\n    }\r\n\r\n    /**\r\n     * Create a new TrajectoryDescriptor from a pre-existing pyramid of tokens.\r\n     * NOTE: This function exists to support an outdated serialization mechanism and should\r\n     * be deleted if it is no longer useful.\r\n     * @param pyramid tokenization pyramid\r\n     * @param levenshteinAlphabet Levenshtein.Alphabet to be uses as basis for comparison with other descriptors\r\n     * @returns TrajectoryDescriptor describing the Trajectory from which the pyramid was built\r\n     */\r\n    public static CreateFromTokenizationPyramid(pyramid: number[][], levenshteinAlphabet: Levenshtein.Alphabet<number>): TrajectoryDescriptor {\r\n        const descriptor = new TrajectoryDescriptor();\r\n        descriptor._sequences = pyramid.map((tokens) => new Levenshtein.Sequence<number>(tokens, levenshteinAlphabet));\r\n        return descriptor;\r\n    }\r\n\r\n    private constructor() {\r\n        this._sequences = [];\r\n    }\r\n\r\n    /**\r\n     * Create the tokenization pyramid for the provided Trajectory according to the given\r\n     * Vector3Alphabet.\r\n     * @param trajectory Trajectory to be tokenized\r\n     * @param alphabet Vector3Alphabet containing tokens\r\n     * @param targetResolution finest resolution of descriptor\r\n     * @returns tokenization pyramid for Trajectory\r\n     */\r\n    private static _GetTokenizationPyramid(\r\n        trajectory: Trajectory,\r\n        alphabet: Vector3Alphabet,\r\n        targetResolution: number = TrajectoryDescriptor._FINEST_DESCRIPTOR_RESOLUTION\r\n    ): number[][] {\r\n        const pyramid: number[][] = [];\r\n        for (let res = targetResolution; res > 4; res = Math.floor(res / 2)) {\r\n            pyramid.push(trajectory.resampleAtTargetResolution(res).tokenize(alphabet.chars));\r\n        }\r\n        return pyramid;\r\n    }\r\n\r\n    /**\r\n     * Calculate a distance metric between this TrajectoryDescriptor and another. This is\r\n     * essentially a similarity score and does not directly represent Euclidean distance,\r\n     * edit distance, or any other formal distance metric.\r\n     * @param other TrajectoryDescriptor from which to determine distance\r\n     * @returns distance, a nonnegative similarity score where larger values indicate dissimilarity\r\n     */\r\n    public distance(other: TrajectoryDescriptor): number {\r\n        let totalDistance = 0;\r\n        let weight: number;\r\n        for (let idx = 0; idx < this._sequences.length; ++idx) {\r\n            weight = Math.pow(2, idx);\r\n            totalDistance += weight * this._sequences[idx].distance(other._sequences[idx]);\r\n        }\r\n        return totalDistance;\r\n    }\r\n}\r\n\r\n/**\r\n * A set of TrajectoryDescriptors defined to be \"the same.\" This is essentially a helper\r\n * class to facilitate methods of Trajectory clustering.\r\n */\r\nclass TrajectoryClass {\r\n    private static readonly _MIN_AVERAGE_DISTANCE = 1;\r\n\r\n    private _descriptors: TrajectoryDescriptor[];\r\n    private _centroidIdx: number;\r\n    private _averageDistance: number;\r\n\r\n    /**\r\n     * Serialize to JSON.\r\n     * @returns JSON serialization\r\n     */\r\n    public serialize(): string {\r\n        const jsonObject: any = {};\r\n        jsonObject.descriptors = this._descriptors.map((desc) => desc.serialize());\r\n        jsonObject.centroidIdx = this._centroidIdx;\r\n        jsonObject.averageDistance = this._averageDistance;\r\n        return JSON.stringify(jsonObject);\r\n    }\r\n\r\n    /**\r\n     * Deserialize from JSON string and Alphabet. This should be the same Alphabet\r\n     * from which the descriptors were originally created, which must be serialized and\r\n     * deserialized independently so that it can be passed in here.\r\n     * @param json JSON string representation\r\n     * @param alphabet Alphabet from which TrajectoryDescriptors were originally created\r\n     * @returns deserialized TrajectoryDescriptor\r\n     */\r\n    public static Deserialize(json: string, alphabet: Levenshtein.Alphabet<number>): TrajectoryClass {\r\n        const jsonObject = JSON.parse(json);\r\n        const described = new TrajectoryClass();\r\n        described._descriptors = jsonObject.descriptors.map((s: string) => TrajectoryDescriptor.Deserialize(s, alphabet));\r\n        described._centroidIdx = jsonObject.centroidIdx;\r\n        described._averageDistance = jsonObject.averageDistance;\r\n        return described;\r\n    }\r\n\r\n    /**\r\n     * Create a new DescribedTrajectory.\r\n     * @param descriptors currently-known TrajectoryDescriptors, if any\r\n     */\r\n    public constructor(descriptors: TrajectoryDescriptor[] = []) {\r\n        this._descriptors = descriptors;\r\n        this._centroidIdx = -1;\r\n        this._averageDistance = 0;\r\n\r\n        this._refreshDescription();\r\n    }\r\n\r\n    /**\r\n     * Add a new TrajectoryDescriptor to the list of descriptors known to describe\r\n     * this same DescribedTrajectory.\r\n     * @param descriptor descriptor to be added\r\n     */\r\n    public add(descriptor: TrajectoryDescriptor): void {\r\n        this._descriptors.push(descriptor);\r\n        this._refreshDescription();\r\n    }\r\n\r\n    /**\r\n     * Compute the cost, which is inversely related to the likelihood that the provided\r\n     * TrajectoryDescriptor describes a Trajectory that is considered to be the same as\r\n     * the class represented by this DescribedTrajectory.\r\n     * @param descriptor the descriptor to be costed\r\n     * @returns cost of the match, which is a nonnegative similarity metric where larger values indicate dissimilarity\r\n     */\r\n    public getMatchCost(descriptor: TrajectoryDescriptor): number {\r\n        return descriptor.distance(this._descriptors[this._centroidIdx]) / this._averageDistance;\r\n    }\r\n\r\n    /**\r\n     * Compute the minimum distance between the queried TrajectoryDescriptor and a\r\n     * descriptor which is a member of this collection. This is an alternative way of\r\n     * conceptualizing match cost from getMatchCost(), and it serves a different function.\r\n     * @param descriptor the descriptor to find the minimum distance to\r\n     * @returns minimum descriptor distance to a member descriptor of this DescribedTrajectory\r\n     */\r\n    public getMatchMinimumDistance(descriptor: TrajectoryDescriptor): number {\r\n        return Math.min(...this._descriptors.map((desc) => desc.distance(descriptor)));\r\n    }\r\n\r\n    /**\r\n     * Refreshes the internal representation of this DescribedTrajectory.\r\n     */\r\n    private _refreshDescription(): void {\r\n        this._centroidIdx = -1;\r\n        let sum: number;\r\n        const distances = this._descriptors.map((a) => {\r\n            sum = 0;\r\n            for (const b of this._descriptors) {\r\n                sum += a.distance(b);\r\n            }\r\n            return sum;\r\n        });\r\n        for (let idx = 0; idx < distances.length; ++idx) {\r\n            if (this._centroidIdx < 0 || distances[idx] < distances[this._centroidIdx]) {\r\n                this._centroidIdx = idx;\r\n            }\r\n        }\r\n\r\n        this._averageDistance = 0;\r\n        for (const desc of this._descriptors) {\r\n            this._averageDistance += desc.distance(this._descriptors[this._centroidIdx]);\r\n        }\r\n        if (this._descriptors.length > 0) {\r\n            this._averageDistance = Math.max(this._averageDistance / this._descriptors.length, TrajectoryClass._MIN_AVERAGE_DISTANCE);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Class representing a set of known, named trajectories to which Trajectories can be\r\n * added and using which Trajectories can be recognized.\r\n */\r\nexport class TrajectoryClassifier {\r\n    private _maximumAllowableMatchCost: number = 4;\r\n    private _vector3Alphabet: Vector3Alphabet;\r\n    private _levenshteinAlphabet: Levenshtein.Alphabet<number>;\r\n    private _nameToDescribedTrajectory: Map<string, TrajectoryClass>;\r\n\r\n    /**\r\n     * Serialize to JSON.\r\n     * @returns JSON serialization\r\n     */\r\n    public serialize(): string {\r\n        const jsonObject: any = {};\r\n        jsonObject.maximumAllowableMatchCost = this._maximumAllowableMatchCost;\r\n        jsonObject.vector3Alphabet = this._vector3Alphabet.serialize();\r\n        jsonObject.levenshteinAlphabet = this._levenshteinAlphabet.serialize();\r\n        jsonObject.nameToDescribedTrajectory = [];\r\n        this._nameToDescribedTrajectory.forEach((described, name) => {\r\n            jsonObject.nameToDescribedTrajectory.push(name);\r\n            jsonObject.nameToDescribedTrajectory.push(described.serialize());\r\n        });\r\n        return JSON.stringify(jsonObject);\r\n    }\r\n\r\n    /**\r\n     * Deserialize from JSON.\r\n     * @param json JSON serialization\r\n     * @returns deserialized TrajectorySet\r\n     */\r\n    public static Deserialize(json: string): TrajectoryClassifier {\r\n        const jsonObject = JSON.parse(json);\r\n        const classifier = new TrajectoryClassifier();\r\n        classifier._maximumAllowableMatchCost = jsonObject.maximumAllowableMatchCost;\r\n        classifier._vector3Alphabet = Vector3Alphabet.Deserialize(jsonObject.vector3Alphabet);\r\n        classifier._levenshteinAlphabet = Levenshtein.Alphabet.Deserialize<number>(jsonObject.levenshteinAlphabet);\r\n        for (let idx = 0; idx < jsonObject.nameToDescribedTrajectory.length; idx += 2) {\r\n            classifier._nameToDescribedTrajectory.set(\r\n                jsonObject.nameToDescribedTrajectory[idx],\r\n                TrajectoryClass.Deserialize(jsonObject.nameToDescribedTrajectory[idx + 1], classifier._levenshteinAlphabet)\r\n            );\r\n        }\r\n        return classifier;\r\n    }\r\n\r\n    /**\r\n     * Initialize a new empty TrajectorySet with auto-generated Alphabets.\r\n     * VERY naive, need to be generating these things from known\r\n     * sets. Better version later, probably eliminating this one.\r\n     * @returns auto-generated TrajectorySet\r\n     */\r\n    public static Generate(): TrajectoryClassifier {\r\n        const vecs = Vector3Alphabet.Generate(64, 256, 0.1, 0.001, [Vector3.Forward()]);\r\n\r\n        const charIdxs = new Array(vecs.chars.length);\r\n        for (let idx = 0; idx < charIdxs.length; ++idx) {\r\n            charIdxs[idx] = idx;\r\n        }\r\n\r\n        const alphabet = new Levenshtein.Alphabet<number>(\r\n            charIdxs,\r\n            (idx) => (idx === 0 ? 0 : 1),\r\n            (idx) => (idx === 0 ? 0 : 1),\r\n            (a, b) => Math.min(1 - Vector3.Dot(vecs.chars[a], vecs.chars[b]), 1)\r\n        );\r\n\r\n        const trajectorySet = new TrajectoryClassifier();\r\n        trajectorySet._vector3Alphabet = vecs;\r\n        trajectorySet._levenshteinAlphabet = alphabet;\r\n        return trajectorySet;\r\n    }\r\n\r\n    private constructor() {\r\n        this._nameToDescribedTrajectory = new Map<string, TrajectoryClass>();\r\n    }\r\n\r\n    /**\r\n     * Add a new Trajectory to the set with a given name.\r\n     * @param trajectory new Trajectory to be added\r\n     * @param classification name to which to add the Trajectory\r\n     */\r\n    public addTrajectoryToClassification(trajectory: Trajectory, classification: string): void {\r\n        if (!this._nameToDescribedTrajectory.has(classification)) {\r\n            this._nameToDescribedTrajectory.set(classification, new TrajectoryClass());\r\n        }\r\n\r\n        this._nameToDescribedTrajectory.get(classification)!.add(TrajectoryDescriptor.CreateFromTrajectory(trajectory, this._vector3Alphabet, this._levenshteinAlphabet));\r\n    }\r\n\r\n    /**\r\n     * Remove a known named trajectory and all Trajectories associated with it.\r\n     * @param classification name to remove\r\n     * @returns whether anything was removed\r\n     */\r\n    public deleteClassification(classification: string): boolean {\r\n        return this._nameToDescribedTrajectory.delete(classification);\r\n    }\r\n\r\n    /**\r\n     * Attempt to recognize a Trajectory from among all the classifications\r\n     * already known to the classifier.\r\n     * @param trajectory Trajectory to be recognized\r\n     * @returns classification of Trajectory if recognized, null otherwise\r\n     */\r\n    public classifyTrajectory(trajectory: Trajectory): Nullable<string> {\r\n        const descriptor = TrajectoryDescriptor.CreateFromTrajectory(trajectory, this._vector3Alphabet, this._levenshteinAlphabet);\r\n\r\n        const allowableMatches: string[] = [];\r\n        this._nameToDescribedTrajectory.forEach((trajectoryClass, classification) => {\r\n            if (trajectoryClass.getMatchCost(descriptor) < this._maximumAllowableMatchCost) {\r\n                allowableMatches.push(classification);\r\n            }\r\n        });\r\n\r\n        if (allowableMatches.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        let bestIdx = 0;\r\n        let bestMatch = this._nameToDescribedTrajectory.get(allowableMatches[bestIdx])!.getMatchMinimumDistance(descriptor);\r\n        let match: number;\r\n        for (let idx = 0; idx < allowableMatches.length; ++idx) {\r\n            match = this._nameToDescribedTrajectory.get(allowableMatches[idx])!.getMatchMinimumDistance(descriptor);\r\n            if (match < bestMatch) {\r\n                bestMatch = match;\r\n                bestIdx = idx;\r\n            }\r\n        }\r\n        return allowableMatches[bestIdx];\r\n    }\r\n}\r\n","import { type Scene } from \"../scene\";\r\nimport { Logger } from \"./logger\";\r\nimport { SceneSerializer } from \"./sceneSerializer\";\r\n\r\n/**\r\n * Class used to connect with the reflector zone of the sandbox via the reflector bridge\r\n * @since 5.0.0\r\n */\r\nexport class Reflector {\r\n    private static readonly _SERVER_PREFIX = \"$$\";\r\n\r\n    private _scene: Scene;\r\n    private _webSocket: WebSocket;\r\n\r\n    /**\r\n     * Constructs a reflector object.\r\n     * @param scene The scene to use\r\n     * @param hostname The hostname of the reflector bridge\r\n     * @param port The port of the reflector bridge\r\n     */\r\n    public constructor(scene: Scene, hostname: string, port: number) {\r\n        this._scene = scene;\r\n\r\n        Logger.Log(`[Reflector] Connecting to ws://${hostname}:${port}`);\r\n        this._webSocket = new WebSocket(`ws://${hostname}:${port}`);\r\n\r\n        this._webSocket.onmessage = (event) => {\r\n            const message: string = event.data;\r\n            if (message.startsWith(Reflector._SERVER_PREFIX)) {\r\n                const serverMessage = message.substring(Reflector._SERVER_PREFIX.length);\r\n                Logger.Log(`[Reflector] Received server message: ${serverMessage.substring(0, 64)}`);\r\n                this._handleServerMessage(serverMessage);\r\n                return;\r\n            } else {\r\n                Logger.Log(`[Reflector] Received client message: ${message.substring(0, 64)}`);\r\n                this._handleClientMessage();\r\n            }\r\n        };\r\n\r\n        this._webSocket.onclose = (event) => {\r\n            Logger.Log(`[Reflector] Disconnected ${event.code} ${event.reason}`);\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Closes the reflector connection\r\n     */\r\n    public close(): void {\r\n        this._webSocket.close();\r\n    }\r\n\r\n    private _handleServerMessage(message: string): void {\r\n        switch (message) {\r\n            case \"connected\": {\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                SceneSerializer.SerializeAsync(this._scene).then((serialized) => {\r\n                    this._webSocket.send(`load|${JSON.stringify(serialized)}`);\r\n                });\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _handleClientMessage(): void {\r\n        // do nothing\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Observable } from \"./observable\";\r\n\r\n/**\r\n * A wrapper for the experimental pressure api which allows a callback to be called whenever certain thresholds are met.\r\n */\r\nexport class PressureObserverWrapper {\r\n    private _observer: Nullable<PressureObserver> = null;\r\n    private _currentState: PressureRecord[] = [];\r\n\r\n    /**\r\n     * An event triggered when the cpu usage/speed meets certain thresholds.\r\n     * Note: pressure is an experimental API.\r\n     */\r\n    public onPressureChanged = new Observable<PressureRecord[]>();\r\n\r\n    /**\r\n     * A pressure observer will call this callback, whenever these thresholds are met.\r\n     * @param options An object containing the thresholds used to decide what value to to return for each update property (average of start and end of a threshold boundary).\r\n     */\r\n    constructor(options?: PressureObserverOptions) {\r\n        if (PressureObserverWrapper.IsAvailable) {\r\n            this._observer = new PressureObserver((update) => {\r\n                this._currentState = update;\r\n                this.onPressureChanged.notifyObservers(update);\r\n            }, options);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns true if PressureObserver is available for use, false otherwise.\r\n     */\r\n    public static get IsAvailable() {\r\n        return typeof PressureObserver !== \"undefined\" && PressureObserver.knownSources && PressureObserver.knownSources.includes(\"cpu\");\r\n    }\r\n\r\n    /**\r\n     * Method that must be called to begin observing changes, and triggering callbacks.\r\n     * @param source defines the source to observe\r\n     */\r\n    observe(source: PressureSource): void {\r\n        try {\r\n            // eslint-disable-next-line github/no-then\r\n            this._observer?.observe(source).catch(() => {\r\n                // Ignore any error\r\n            });\r\n            this.onPressureChanged.notifyObservers(this._currentState);\r\n        } catch {\r\n            // Ignore error\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Method that must be called to stop observing changes and triggering callbacks (cleanup function).\r\n     * @param source defines the source to unobserve\r\n     */\r\n    unobserve(source: PressureSource): void {\r\n        try {\r\n            this._observer?.unobserve(source);\r\n        } catch {\r\n            // Ignore error\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release the associated resources.\r\n     */\r\n    dispose() {\r\n        this._observer?.disconnect();\r\n        this._observer = null;\r\n        this.onPressureChanged.clear();\r\n    }\r\n}\r\n","const GrowthFactor = 1.5;\r\n\r\n/**\r\n * A class acting as a dynamic float32array used in the performance viewer\r\n */\r\nexport class DynamicFloat32Array {\r\n    private _view: Float32Array;\r\n    private _itemLength: number;\r\n\r\n    /**\r\n     * Creates a new DynamicFloat32Array with the desired item capacity.\r\n     * @param itemCapacity The initial item capacity you would like to set for the array.\r\n     */\r\n    constructor(itemCapacity: number) {\r\n        this._view = new Float32Array(itemCapacity);\r\n        this._itemLength = 0;\r\n    }\r\n\r\n    /**\r\n     * The number of items currently in the array.\r\n     */\r\n    public get itemLength(): number {\r\n        return this._itemLength;\r\n    }\r\n\r\n    /**\r\n     * Gets value at index, NaN if no such index exists.\r\n     * @param index the index to get the value at.\r\n     * @returns the value at the index provided.\r\n     */\r\n    public at(index: number): number {\r\n        if (index < 0 || index >= this._itemLength) {\r\n            return NaN;\r\n        }\r\n\r\n        return this._view[index];\r\n    }\r\n\r\n    /**\r\n     * Gets a view of the original array from start to end (exclusive of end).\r\n     * @param start starting index.\r\n     * @param end ending index.\r\n     * @returns a subarray of the original array.\r\n     */\r\n    public subarray(start: number, end: number): Float32Array {\r\n        if (start >= end || start < 0) {\r\n            return new Float32Array(0);\r\n        }\r\n\r\n        if (end > this._itemLength) {\r\n            end = this._itemLength;\r\n        }\r\n\r\n        return this._view.subarray(start, end);\r\n    }\r\n\r\n    /**\r\n     * Pushes items to the end of the array.\r\n     * @param item The item to push into the array.\r\n     */\r\n    public push(item: number) {\r\n        this._view[this._itemLength] = item;\r\n        this._itemLength++;\r\n        if (this._itemLength >= this._view.length) {\r\n            this._growArray();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Grows the array by the growth factor when necessary.\r\n     */\r\n    private _growArray() {\r\n        const newCapacity = Math.floor(this._view.length * GrowthFactor);\r\n        const view = new Float32Array(newCapacity);\r\n        view.set(this._view);\r\n        this._view = view;\r\n    }\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { type IPerfCustomEvent, type IPerfDatasets, type IPerfMetadata } from \"../interfaces/iPerfViewer\";\r\nimport { EventState, Observable } from \"../observable\";\r\nimport { PrecisionDate } from \"../precisionDate\";\r\nimport { Tools } from \"../tools.pure\";\r\nimport { DynamicFloat32Array } from \"./dynamicFloat32Array\";\r\nimport { type IPerfViewerCollectionStrategy, type PerfStrategyInitialization } from \"./performanceViewerCollectionStrategies\";\r\n\r\n// the initial size of our array, should be a multiple of two!\r\nconst InitialArraySize = 1800;\r\n\r\n// three octets in a hexcode. #[AA][BB][CC], i.e. 24 bits of data.\r\nconst NumberOfBitsInHexcode = 24;\r\n\r\n// Allows single numeral hex numbers to be appended by a 0.\r\nconst HexPadding = \"0\";\r\n\r\n// header for the timestamp column\r\nconst TimestampColHeader = \"timestamp\";\r\n\r\n// header for the numPoints column\r\nconst NumPointsColHeader = \"numPoints\";\r\n\r\n// regex to capture all carriage returns in the string.\r\nconst CarriageReturnRegex = /\\r/g;\r\n\r\n// string to use as separator when exporting extra information along with the dataset id\r\nconst ExportedDataSeparator = \"@\";\r\n\r\n/**\r\n * Callback strategy and optional category for data collection\r\n */\r\ninterface IPerformanceViewerStrategyParameter {\r\n    /**\r\n     * The strategy for collecting data. Available strategies are located on the PerfCollectionStrategy class\r\n     */\r\n    strategyCallback: PerfStrategyInitialization;\r\n    /**\r\n     * Category for displaying this strategy on the viewer. Can be undefined or an empty string, in which case the strategy will be displayed on top\r\n     */\r\n    category?: string;\r\n    /**\r\n     * Starts hidden\r\n     */\r\n    hidden?: boolean;\r\n}\r\n\r\n/**\r\n * The collector class handles the collection and storage of data into the appropriate array.\r\n * The collector also handles notifying any observers of any updates.\r\n */\r\nexport class PerformanceViewerCollector {\r\n    private _datasetMeta: Map<string, IPerfMetadata>;\r\n    private _strategies: Map<string, IPerfViewerCollectionStrategy>;\r\n    private _startingTimestamp: number;\r\n    private _hasLoadedData: boolean;\r\n    private _isStarted: boolean;\r\n    private readonly _customEventObservable: Observable<IPerfCustomEvent>;\r\n    private readonly _eventRestoreSet: Set<string>;\r\n\r\n    /**\r\n     * Datastructure containing the collected datasets. Warning: you should not modify the values in here, data will be of the form [timestamp, numberOfPoints, value1, value2..., timestamp, etc...]\r\n     */\r\n    public readonly datasets: IPerfDatasets;\r\n    /**\r\n     * An observable you can attach to get deltas in the dataset. Subscribing to this will increase memory consumption slightly, and may hurt performance due to increased garbage collection needed.\r\n     * Updates of slices will be of the form [timestamp, numberOfPoints, value1, value2...].\r\n     */\r\n    public readonly datasetObservable: Observable<number[]>;\r\n    /**\r\n     * An observable you can attach to get the most updated map of metadatas.\r\n     */\r\n    public readonly metadataObservable: Observable<Map<string, IPerfMetadata>>;\r\n\r\n    /**\r\n     * The offset for when actual data values start appearing inside a slice.\r\n     */\r\n    public static get SliceDataOffset() {\r\n        return 2;\r\n    }\r\n\r\n    /**\r\n     * The offset for the value of the number of points inside a slice.\r\n     */\r\n    public static get NumberOfPointsOffset() {\r\n        return 1;\r\n    }\r\n\r\n    /**\r\n     * Handles the creation of a performance viewer collector.\r\n     * @param _scene the scene to collect on.\r\n     * @param _enabledStrategyCallbacks the list of data to collect with callbacks for initialization purposes.\r\n     */\r\n    constructor(\r\n        private _scene: Scene,\r\n        _enabledStrategyCallbacks?: IPerformanceViewerStrategyParameter[]\r\n    ) {\r\n        this.datasets = {\r\n            ids: [],\r\n            data: new DynamicFloat32Array(InitialArraySize),\r\n            startingIndices: new DynamicFloat32Array(InitialArraySize),\r\n        };\r\n        this._strategies = new Map<string, IPerfViewerCollectionStrategy>();\r\n        this._datasetMeta = new Map<string, IPerfMetadata>();\r\n        this._eventRestoreSet = new Set();\r\n        this._customEventObservable = new Observable();\r\n        this.datasetObservable = new Observable();\r\n        this.metadataObservable = new Observable((observer) => observer.callback(this._datasetMeta, new EventState(0)));\r\n        if (_enabledStrategyCallbacks) {\r\n            this.addCollectionStrategies(..._enabledStrategyCallbacks);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Registers a custom string event which will be callable via sendEvent. This method returns an event object which will contain the id of the event.\r\n     * The user can set a value optionally, which will be used in the sendEvent method. If the value is set, we will record this value at the end of each frame,\r\n     * if not we will increment our counter and record the value of the counter at the end of each frame. The value recorded is 0 if no sendEvent method is called, within a frame.\r\n     * @param name The name of the event to register\r\n     * @param forceUpdate if the code should force add an event, and replace the last one.\r\n     * @param category the category for that event\r\n     * @returns The event registered, used in sendEvent\r\n     */\r\n    public registerEvent(name: string, forceUpdate?: boolean, category?: string): IPerfCustomEvent | undefined {\r\n        if (this._strategies.has(name) && !forceUpdate) {\r\n            return;\r\n        }\r\n\r\n        if (this._strategies.has(name) && forceUpdate) {\r\n            this._strategies.get(name)?.dispose();\r\n            this._strategies.delete(name);\r\n        }\r\n\r\n        const strategy: PerfStrategyInitialization = (scene) => {\r\n            let counter: number = 0;\r\n            let value: number = 0;\r\n\r\n            const afterRenderObserver = scene.onAfterRenderObservable.add(() => {\r\n                value = counter;\r\n                counter = 0;\r\n            });\r\n\r\n            const stringObserver = this._customEventObservable.add((eventVal) => {\r\n                if (name !== eventVal.name) {\r\n                    return;\r\n                }\r\n\r\n                if (eventVal.value !== undefined) {\r\n                    counter = eventVal.value;\r\n                } else {\r\n                    counter++;\r\n                }\r\n            });\r\n\r\n            return {\r\n                id: name,\r\n                getData: () => value,\r\n                dispose: () => {\r\n                    scene.onAfterRenderObservable.remove(afterRenderObserver);\r\n                    this._customEventObservable.remove(stringObserver);\r\n                },\r\n            };\r\n        };\r\n        const event: IPerfCustomEvent = {\r\n            name,\r\n        };\r\n\r\n        this._eventRestoreSet.add(name);\r\n        this.addCollectionStrategies({ strategyCallback: strategy, category });\r\n\r\n        return event;\r\n    }\r\n\r\n    /**\r\n     * Lets the perf collector handle an event, occurences or event value depending on if the event.value params is set.\r\n     * @param event the event to handle an occurence for\r\n     */\r\n    public sendEvent(event: IPerfCustomEvent) {\r\n        this._customEventObservable.notifyObservers(event);\r\n    }\r\n\r\n    /**\r\n     * This event restores all custom string events if necessary.\r\n     */\r\n    private _restoreStringEvents() {\r\n        if (this._eventRestoreSet.size !== this._customEventObservable.observers.length) {\r\n            this._eventRestoreSet.forEach((event) => {\r\n                this.registerEvent(event, true);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This method adds additional collection strategies for data collection purposes.\r\n     * @param strategyCallbacks the list of data to collect with callbacks.\r\n     */\r\n    public addCollectionStrategies(...strategyCallbacks: IPerformanceViewerStrategyParameter[]) {\r\n        // eslint-disable-next-line prefer-const\r\n        for (let { strategyCallback, category, hidden } of strategyCallbacks) {\r\n            const strategy = strategyCallback(this._scene);\r\n            if (this._strategies.has(strategy.id)) {\r\n                strategy.dispose();\r\n                continue;\r\n            }\r\n\r\n            this.datasets.ids.push(strategy.id);\r\n\r\n            if (category) {\r\n                category = category.replace(new RegExp(ExportedDataSeparator, \"g\"), \"\");\r\n            }\r\n\r\n            this._datasetMeta.set(strategy.id, {\r\n                color: this._getHexColorFromId(strategy.id),\r\n                category,\r\n                hidden,\r\n            });\r\n\r\n            this._strategies.set(strategy.id, strategy);\r\n        }\r\n\r\n        this.metadataObservable.notifyObservers(this._datasetMeta);\r\n    }\r\n\r\n    /**\r\n     * Gets a 6 character hexcode representing the colour from a passed in string.\r\n     * @param id the string to get a hex code for.\r\n     * @returns a hexcode hashed from the id.\r\n     */\r\n    private _getHexColorFromId(id: string) {\r\n        // this first bit is just a known way of hashing a string.\r\n        let hash = 0;\r\n        for (let i = 0; i < id.length; i++) {\r\n            // (hash << 5) - hash is the same as hash * 31\r\n            hash = id.charCodeAt(i) + ((hash << 5) - hash);\r\n        }\r\n\r\n        // then we build the string octet by octet.\r\n        let hex = \"#\";\r\n        for (let i = 0; i < NumberOfBitsInHexcode; i += 8) {\r\n            const octet = (hash >> i) & 0xff;\r\n            const toStr = HexPadding + octet.toString(16);\r\n            hex += toStr.substring(toStr.length - 2);\r\n        }\r\n\r\n        return hex;\r\n    }\r\n\r\n    /**\r\n     * Collects data for every dataset by using the appropriate strategy. This is called every frame.\r\n     * This method will then notify all observers with the latest slice.\r\n     */\r\n    private _collectDataAtFrame = () => {\r\n        const timestamp = PrecisionDate.Now - this._startingTimestamp;\r\n        const numPoints = this.datasets.ids.length;\r\n\r\n        // add the starting index for the slice\r\n        const numberOfIndices = this.datasets.startingIndices.itemLength;\r\n        let startingIndex = 0;\r\n\r\n        if (numberOfIndices > 0) {\r\n            const previousStartingIndex = this.datasets.startingIndices.at(numberOfIndices - 1);\r\n            startingIndex =\r\n                previousStartingIndex + this.datasets.data.at(previousStartingIndex + PerformanceViewerCollector.NumberOfPointsOffset) + PerformanceViewerCollector.SliceDataOffset;\r\n        }\r\n\r\n        this.datasets.startingIndices.push(startingIndex);\r\n\r\n        // add the first 2 items in our slice.\r\n        this.datasets.data.push(timestamp);\r\n        this.datasets.data.push(numPoints);\r\n\r\n        // add the values inside the slice.\r\n        for (const id of this.datasets.ids) {\r\n            const strategy = this._strategies.get(id);\r\n\r\n            if (!strategy) {\r\n                return;\r\n            }\r\n\r\n            this.datasets.data.push(strategy.getData());\r\n        }\r\n\r\n        if (this.datasetObservable.hasObservers()) {\r\n            const slice: number[] = [timestamp, numPoints];\r\n\r\n            for (let i = 0; i < numPoints; i++) {\r\n                slice.push(this.datasets.data.at(startingIndex + PerformanceViewerCollector.SliceDataOffset + i));\r\n            }\r\n\r\n            this.datasetObservable.notifyObservers(slice);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Collects and then sends the latest slice to any observers by using the appropriate strategy when the user wants.\r\n     * The slice will be of the form [timestamp, numberOfPoints, value1, value2...]\r\n     * This method does not add onto the collected data accessible via the datasets variable.\r\n     */\r\n    public getCurrentSlice() {\r\n        const timestamp = PrecisionDate.Now - this._startingTimestamp;\r\n        const numPoints = this.datasets.ids.length;\r\n        const slice: number[] = [timestamp, numPoints];\r\n\r\n        // add the values inside the slice.\r\n        for (const id of this.datasets.ids) {\r\n            const strategy = this._strategies.get(id);\r\n\r\n            if (!strategy) {\r\n                return;\r\n            }\r\n\r\n            if (this.datasetObservable.hasObservers()) {\r\n                slice.push(strategy.getData());\r\n            }\r\n        }\r\n\r\n        if (this.datasetObservable.hasObservers()) {\r\n            this.datasetObservable.notifyObservers(slice);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates a property for a dataset's metadata with the value provided.\r\n     * @param id the id of the dataset which needs its metadata updated.\r\n     * @param prop the property to update.\r\n     * @param value the value to update the property with.\r\n     */\r\n    public updateMetadata<T extends keyof IPerfMetadata>(id: string, prop: T, value: IPerfMetadata[T]) {\r\n        const meta = this._datasetMeta.get(id);\r\n\r\n        if (!meta) {\r\n            return;\r\n        }\r\n\r\n        meta[prop] = value;\r\n\r\n        this.metadataObservable.notifyObservers(this._datasetMeta);\r\n    }\r\n\r\n    /**\r\n     * Completely clear, data, ids, and strategies saved to this performance collector.\r\n     * @param preserveStringEventsRestore if it should preserve the string events, by default will clear string events registered when called.\r\n     */\r\n    public clear(preserveStringEventsRestore?: boolean) {\r\n        this.datasets.data = new DynamicFloat32Array(InitialArraySize);\r\n        this.datasets.ids.length = 0;\r\n        this.datasets.startingIndices = new DynamicFloat32Array(InitialArraySize);\r\n        this._datasetMeta.clear();\r\n        this._strategies.forEach((strategy) => strategy.dispose());\r\n        this._strategies.clear();\r\n\r\n        if (!preserveStringEventsRestore) {\r\n            this._eventRestoreSet.clear();\r\n        }\r\n        this._hasLoadedData = false;\r\n    }\r\n\r\n    /**\r\n     * Accessor which lets the caller know if the performance collector has data loaded from a file or not!\r\n     * Call clear() to reset this value.\r\n     * @returns true if the data is loaded from a file, false otherwise.\r\n     */\r\n    public get hasLoadedData(): boolean {\r\n        return this._hasLoadedData;\r\n    }\r\n\r\n    /**\r\n     * Given a string containing file data, this function parses the file data into the datasets object.\r\n     * It returns a boolean to indicate if this object was successfully loaded with the data.\r\n     * @param data string content representing the file data.\r\n     * @param keepDatasetMeta if it should use reuse the existing dataset metadata\r\n     * @returns true if the data was successfully loaded, false otherwise.\r\n     */\r\n    public loadFromFileData(data: string, keepDatasetMeta?: boolean): boolean {\r\n        const lines = data\r\n            .replace(CarriageReturnRegex, \"\")\r\n            .split(\"\\n\")\r\n            .map((line) => line.split(\",\").filter((s) => s.length > 0))\r\n            .filter((line) => line.length > 0);\r\n        const timestampIndex = 0;\r\n        const numPointsIndex = PerformanceViewerCollector.NumberOfPointsOffset;\r\n        if (lines.length < 2) {\r\n            return false;\r\n        }\r\n\r\n        const parsedDatasets: IPerfDatasets = {\r\n            ids: [],\r\n            data: new DynamicFloat32Array(InitialArraySize),\r\n            startingIndices: new DynamicFloat32Array(InitialArraySize),\r\n        };\r\n\r\n        // parse first line separately to populate ids!\r\n        const [firstLine, ...dataLines] = lines;\r\n        // make sure we have the correct beginning headers\r\n        if (firstLine.length < 2 || firstLine[timestampIndex] !== TimestampColHeader || firstLine[numPointsIndex] !== NumPointsColHeader) {\r\n            return false;\r\n        }\r\n\r\n        const idCategoryMap: Map<string, string> = new Map<string, string>();\r\n\r\n        // populate the ids.\r\n        for (let i = PerformanceViewerCollector.SliceDataOffset; i < firstLine.length; i++) {\r\n            const [id, category] = firstLine[i].split(ExportedDataSeparator);\r\n            parsedDatasets.ids.push(id);\r\n            idCategoryMap.set(id, category);\r\n        }\r\n\r\n        let startingIndex = 0;\r\n        for (const line of dataLines) {\r\n            if (line.length < 2) {\r\n                return false;\r\n            }\r\n\r\n            const timestamp = parseFloat(line[timestampIndex]);\r\n            const numPoints = parseInt(line[numPointsIndex]);\r\n\r\n            if (isNaN(numPoints) || isNaN(timestamp)) {\r\n                return false;\r\n            }\r\n\r\n            parsedDatasets.data.push(timestamp);\r\n            parsedDatasets.data.push(numPoints);\r\n\r\n            if (numPoints + PerformanceViewerCollector.SliceDataOffset !== line.length) {\r\n                return false;\r\n            }\r\n\r\n            for (let i = PerformanceViewerCollector.SliceDataOffset; i < line.length; i++) {\r\n                const val = parseFloat(line[i]);\r\n                if (isNaN(val)) {\r\n                    return false;\r\n                }\r\n                parsedDatasets.data.push(val);\r\n            }\r\n\r\n            parsedDatasets.startingIndices.push(startingIndex);\r\n            startingIndex += line.length;\r\n        }\r\n\r\n        this.datasets.ids = parsedDatasets.ids;\r\n        this.datasets.data = parsedDatasets.data;\r\n        this.datasets.startingIndices = parsedDatasets.startingIndices;\r\n        if (!keepDatasetMeta) {\r\n            this._datasetMeta.clear();\r\n        }\r\n        this._strategies.forEach((strategy) => strategy.dispose());\r\n        this._strategies.clear();\r\n\r\n        // populate metadata.\r\n        if (!keepDatasetMeta) {\r\n            for (const id of this.datasets.ids) {\r\n                const category = idCategoryMap.get(id);\r\n\r\n                this._datasetMeta.set(id, { category, color: this._getHexColorFromId(id) });\r\n            }\r\n        }\r\n        this.metadataObservable.notifyObservers(this._datasetMeta);\r\n        this._hasLoadedData = true;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Exports the datasets inside of the collector to a csv.\r\n     */\r\n    public exportDataToCsv() {\r\n        let csvContent = \"\";\r\n        // create the header line.\r\n        csvContent += `${TimestampColHeader},${NumPointsColHeader}`;\r\n        for (let i = 0; i < this.datasets.ids.length; i++) {\r\n            csvContent += `,${this.datasets.ids[i]}`;\r\n            if (this._datasetMeta) {\r\n                const meta = this._datasetMeta.get(this.datasets.ids[i]);\r\n                if (meta?.category) {\r\n                    csvContent += `${ExportedDataSeparator}${meta.category}`;\r\n                }\r\n            }\r\n        }\r\n        csvContent += \"\\n\";\r\n        // create the data lines\r\n        for (let i = 0; i < this.datasets.startingIndices.itemLength; i++) {\r\n            const startingIndex = this.datasets.startingIndices.at(i);\r\n            const timestamp = this.datasets.data.at(startingIndex);\r\n            const numPoints = this.datasets.data.at(startingIndex + PerformanceViewerCollector.NumberOfPointsOffset);\r\n\r\n            csvContent += `${timestamp},${numPoints}`;\r\n\r\n            for (let offset = 0; offset < numPoints; offset++) {\r\n                csvContent += `,${this.datasets.data.at(startingIndex + PerformanceViewerCollector.SliceDataOffset + offset)}`;\r\n            }\r\n\r\n            // add extra commas.\r\n            for (let diff = 0; diff < this.datasets.ids.length - numPoints; diff++) {\r\n                csvContent += \",\";\r\n            }\r\n\r\n            csvContent += \"\\n\";\r\n        }\r\n\r\n        const fileName = `${new Date().toISOString()}-perfdata.csv`;\r\n        Tools.Download(new Blob([csvContent], { type: \"text/csv\" }), fileName);\r\n    }\r\n    /**\r\n     * Starts the realtime collection of data.\r\n     * @param shouldPreserve optional boolean param, if set will preserve the dataset between calls of start.\r\n     */\r\n    public start(shouldPreserve?: boolean) {\r\n        if (!shouldPreserve) {\r\n            this.datasets.data = new DynamicFloat32Array(InitialArraySize);\r\n            this.datasets.startingIndices = new DynamicFloat32Array(InitialArraySize);\r\n            this._startingTimestamp = PrecisionDate.Now;\r\n        } else if (this._startingTimestamp === undefined) {\r\n            this._startingTimestamp = PrecisionDate.Now;\r\n        }\r\n        this._scene.onAfterRenderObservable.add(this._collectDataAtFrame);\r\n        this._restoreStringEvents();\r\n        this._isStarted = true;\r\n    }\r\n\r\n    /**\r\n     * Stops the collection of data.\r\n     */\r\n    public stop() {\r\n        this._scene.onAfterRenderObservable.removeCallback(this._collectDataAtFrame);\r\n        this._isStarted = false;\r\n    }\r\n\r\n    /**\r\n     * Returns if the perf collector has been started or not.\r\n     */\r\n    public get isStarted(): boolean {\r\n        return this._isStarted;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the object\r\n     */\r\n    public dispose() {\r\n        this._scene.onAfterRenderObservable.removeCallback(this._collectDataAtFrame);\r\n        this._datasetMeta.clear();\r\n        this._strategies.forEach((strategy) => {\r\n            strategy.dispose();\r\n        });\r\n        this.datasetObservable.clear();\r\n        this.metadataObservable.clear();\r\n        this._isStarted = false;\r\n        (<any>this.datasets) = null;\r\n    }\r\n}\r\n","import { EngineInstrumentation } from \"../../Instrumentation/engineInstrumentation\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { PrecisionDate } from \"../precisionDate\";\r\nimport { SceneInstrumentation } from \"../../Instrumentation/sceneInstrumentation\";\r\nimport { PressureObserverWrapper } from \"../pressureObserverWrapper\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Defines the general structure of what is necessary for a collection strategy.\r\n */\r\nexport interface IPerfViewerCollectionStrategy {\r\n    /**\r\n     * The id of the strategy.\r\n     */\r\n    id: string;\r\n    /**\r\n     * Function which gets the data for the strategy.\r\n     */\r\n    getData: () => number;\r\n    /**\r\n     * Function which does any necessary cleanup. Called when performanceViewerCollector.dispose() is called.\r\n     */\r\n    dispose: () => void;\r\n}\r\n// Dispose which does nothing.\r\nconst DefaultDisposeImpl = () => {};\r\n\r\n/**\r\n * Initializer callback for a strategy\r\n */\r\nexport type PerfStrategyInitialization = (scene: Scene) => IPerfViewerCollectionStrategy;\r\n/**\r\n * Defines the predefined strategies used in the performance viewer.\r\n */\r\nexport class PerfCollectionStrategy {\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of fps metrics\r\n     * @returns the initializer for the fps strategy\r\n     */\r\n    public static FpsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            const engine = scene.getEngine();\r\n            return {\r\n                id: \"FPS\",\r\n                getData: () => engine.getFps(),\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of thermal utilization metrics.\r\n     * Needs the experimental pressure API.\r\n     * @returns the initializer for the thermal utilization strategy\r\n     */\r\n    public static ThermalStrategy(): PerfStrategyInitialization {\r\n        return this._PressureStrategy(\"Thermal utilization\", \"thermal\");\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of power supply utilization metrics.\r\n     * Needs the experimental pressure API.\r\n     * @returns the initializer for the power supply utilization strategy\r\n     */\r\n    public static PowerSupplyStrategy(): PerfStrategyInitialization {\r\n        return this._PressureStrategy(\"Power supply utilization\", \"power-supply\");\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of pressure metrics.\r\n     * Needs the experimental pressure API.\r\n     * @returns the initializer for the pressure strategy\r\n     */\r\n    public static PressureStrategy(): PerfStrategyInitialization {\r\n        return this._PressureStrategy(\"Pressure\");\r\n    }\r\n\r\n    private static _PressureStrategy(name: string, factor: Nullable<PressureFactor> = null): PerfStrategyInitialization {\r\n        return () => {\r\n            let value = 0;\r\n\r\n            const wrapper = new PressureObserverWrapper();\r\n            wrapper.observe(\"cpu\");\r\n\r\n            wrapper.onPressureChanged.add((update) => {\r\n                for (const record of update) {\r\n                    if ((factor && record.factors.includes(factor)) || (!factor && (record.factors?.length ?? 0) === 0)) {\r\n                        // Let s consider each step being 25% of the total pressure.\r\n                        switch (record.state) {\r\n                            case \"nominal\":\r\n                                value = 0;\r\n                                break;\r\n                            case \"fair\":\r\n                                value = 0.25;\r\n                                break;\r\n                            case \"serious\":\r\n                                value = 0.5;\r\n                                break;\r\n                            case \"critical\":\r\n                                value = 1;\r\n                                break;\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n            return {\r\n                id: name,\r\n                getData: () => value,\r\n                dispose: () => wrapper.dispose(),\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of total meshes metrics.\r\n     * @returns the initializer for the total meshes strategy\r\n     */\r\n    public static TotalMeshesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Total meshes\",\r\n                getData: () => scene.meshes.length,\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of active meshes metrics.\r\n     * @returns the initializer for the active meshes strategy\r\n     */\r\n    public static ActiveMeshesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Active meshes\",\r\n                getData: () => scene.getActiveMeshes().length,\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of active indices metrics.\r\n     * @returns the initializer for the active indices strategy\r\n     */\r\n    public static ActiveIndicesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Active indices\",\r\n                getData: () => scene.getActiveIndices(),\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of active faces metrics.\r\n     * @returns the initializer for the active faces strategy\r\n     */\r\n    public static ActiveFacesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Active faces\",\r\n                getData: () => scene.getActiveIndices() / 3,\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of active bones metrics.\r\n     * @returns the initializer for the active bones strategy\r\n     */\r\n    public static ActiveBonesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Active bones\",\r\n                getData: () => scene.getActiveBones(),\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of active particles metrics.\r\n     * @returns the initializer for the active particles strategy\r\n     */\r\n    public static ActiveParticlesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Active particles\",\r\n                getData: () => scene.getActiveParticles(),\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of draw calls metrics.\r\n     * @returns the initializer for the draw calls strategy\r\n     */\r\n    public static DrawCallsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let drawCalls = 0;\r\n            const onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\r\n                scene.getEngine()._drawCalls.fetchNewFrame();\r\n            });\r\n\r\n            const onAfterRenderObserver = scene.onAfterRenderObservable.add(() => {\r\n                drawCalls = scene.getEngine()._drawCalls.current;\r\n            });\r\n\r\n            return {\r\n                id: \"Draw calls\",\r\n                getData: () => drawCalls,\r\n                dispose: () => {\r\n                    scene.onBeforeAnimationsObservable.remove(onBeforeAnimationsObserver);\r\n                    scene.onAfterRenderObservable.remove(onAfterRenderObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of total lights metrics.\r\n     * @returns the initializer for the total lights strategy\r\n     */\r\n    public static TotalLightsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Total lights\",\r\n                getData: () => scene.lights.length,\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of total vertices metrics.\r\n     * @returns the initializer for the total vertices strategy\r\n     */\r\n    public static TotalVerticesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Total vertices\",\r\n                getData: () => scene.getTotalVertices(),\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of total materials metrics.\r\n     * @returns the initializer for the total materials strategy\r\n     */\r\n    public static TotalMaterialsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Total materials\",\r\n                getData: () => scene.materials.length,\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of total textures metrics.\r\n     * @returns the initializer for the total textures strategy\r\n     */\r\n    public static TotalTexturesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            return {\r\n                id: \"Total textures\",\r\n                getData: () => scene.textures.length,\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of absolute fps metrics.\r\n     * @returns the initializer for the absolute fps strategy\r\n     */\r\n    public static AbsoluteFpsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            const sceneInstrumentation = new SceneInstrumentation(scene);\r\n            sceneInstrumentation.captureFrameTime = true;\r\n\r\n            return {\r\n                id: \"Absolute FPS\",\r\n                getData: () => {\r\n                    return 1000.0 / sceneInstrumentation.frameTimeCounter.lastSecAverage;\r\n                },\r\n                dispose: DefaultDisposeImpl,\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of meshes selection time metrics.\r\n     * @returns the initializer for the meshes selection time strategy\r\n     */\r\n    public static MeshesSelectionStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeActiveMeshesObserver = scene.onBeforeActiveMeshesEvaluationObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterActiveMeshesObserver = scene.onAfterActiveMeshesEvaluationObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Meshes Selection\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeActiveMeshesEvaluationObservable.remove(onBeforeActiveMeshesObserver);\r\n                    scene.onAfterActiveMeshesEvaluationObservable.remove(onAfterActiveMeshesObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of render targets time metrics.\r\n     * @returns the initializer for the render targets time strategy\r\n     */\r\n    public static RenderTargetsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeRenderTargetsObserver = scene.onBeforeRenderTargetsRenderObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterRenderTargetsObserver = scene.onAfterRenderTargetsRenderObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Render Targets\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeRenderTargetsRenderObservable.remove(onBeforeRenderTargetsObserver);\r\n                    scene.onAfterRenderTargetsRenderObservable.remove(onAfterRenderTargetsObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of particles time metrics.\r\n     * @returns the initializer for the particles time strategy\r\n     */\r\n    public static ParticlesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeParticlesObserver = scene.onBeforeParticlesRenderingObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterParticlesObserver = scene.onAfterParticlesRenderingObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Particles\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeParticlesRenderingObservable.remove(onBeforeParticlesObserver);\r\n                    scene.onAfterParticlesRenderingObservable.remove(onAfterParticlesObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of sprites time metrics.\r\n     * @returns the initializer for the sprites time strategy\r\n     */\r\n    public static SpritesStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeSpritesObserver = scene.onBeforeSpritesRenderingObservable?.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterSpritesObserver = scene.onAfterSpritesRenderingObservable?.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Sprites\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeSpritesRenderingObservable?.remove(onBeforeSpritesObserver);\r\n                    scene.onAfterSpritesRenderingObservable?.remove(onAfterSpritesObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of animations time metrics.\r\n     * @returns the initializer for the animations time strategy\r\n     */\r\n    public static AnimationsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterAnimationsObserver = scene.onAfterAnimationsObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Animations\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeAnimationsObservable.remove(onBeforeAnimationsObserver);\r\n                    scene.onAfterAnimationsObservable.remove(onAfterAnimationsObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of physics time metrics.\r\n     * @returns the initializer for the physics time strategy\r\n     */\r\n    public static PhysicsStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforePhysicsObserver = scene.onBeforePhysicsObservable?.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterPhysicsObserver = scene.onAfterPhysicsObservable?.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Physics\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforePhysicsObservable?.remove(onBeforePhysicsObserver);\r\n                    scene.onAfterPhysicsObservable?.remove(onAfterPhysicsObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of render time metrics.\r\n     * @returns the initializer for the render time strategy\r\n     */\r\n    public static RenderStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeDrawPhaseObserver = scene.onBeforeDrawPhaseObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterDrawPhaseObserver = scene.onAfterDrawPhaseObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Render\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeDrawPhaseObservable.remove(onBeforeDrawPhaseObserver);\r\n                    scene.onAfterDrawPhaseObservable.remove(onAfterDrawPhaseObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of total frame time metrics.\r\n     * @returns the initializer for the total frame time strategy\r\n     */\r\n    public static FrameTotalStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n            const onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            const onAfterRenderObserver = scene.onAfterRenderObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            return {\r\n                id: \"Frame Total\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeAnimationsObservable.remove(onBeforeAnimationsObserver);\r\n                    scene.onAfterRenderObservable.remove(onAfterRenderObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of inter-frame time metrics.\r\n     * @returns the initializer for the inter-frame time strategy\r\n     */\r\n    public static InterFrameStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            let startTime = PrecisionDate.Now;\r\n            let timeTaken = 0;\r\n\r\n            const onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\r\n                timeTaken = PrecisionDate.Now - startTime;\r\n            });\r\n\r\n            const onAfterRenderObserver = scene.onAfterRenderObservable.add(() => {\r\n                startTime = PrecisionDate.Now;\r\n            });\r\n\r\n            return {\r\n                id: \"Inter-frame\",\r\n                getData: () => timeTaken,\r\n                dispose: () => {\r\n                    scene.onBeforeAnimationsObservable.remove(onBeforeAnimationsObserver);\r\n                    scene.onAfterRenderObservable.remove(onAfterRenderObserver);\r\n                },\r\n            };\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the initializer for the strategy used for collection of gpu frame time metrics.\r\n     * @returns the initializer for the gpu frame time strategy\r\n     */\r\n    public static GpuFrameTimeStrategy(): PerfStrategyInitialization {\r\n        return (scene) => {\r\n            const engineInstrumentation = new EngineInstrumentation(scene.getEngine());\r\n            engineInstrumentation.captureGPUFrameTime = true;\r\n            return {\r\n                id: \"GPU frame time\",\r\n                getData: () => Math.max(engineInstrumentation.gpuFrameTimeCounter!.current * 0.000001, 0),\r\n                dispose: () => {\r\n                    engineInstrumentation.dispose();\r\n                },\r\n            };\r\n        };\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { PerformanceViewerCollector } from \"./performanceViewerCollector\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register the getPerfCollector method on Scene.\r\n * @internal\r\n */\r\nexport function RegisterPerformanceViewerSceneExtension(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Scene.prototype.getPerfCollector = function (this: Scene): PerformanceViewerCollector {\r\n        if (!this._perfCollector) {\r\n            this._perfCollector = new PerformanceViewerCollector(this);\r\n        }\r\n\r\n        return this._perfCollector;\r\n    };\r\n}\r\n","import { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { type EffectLayer } from \"core/Layers/effectLayer\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\nimport { type Scene, ScenePerformancePriority } from \"core/scene.pure\";\r\nimport { type WebGPUDrawContext } from \"core/Engines/WebGPU/webgpuDrawContext\";\r\nimport { type WebGPUShaderProcessor } from \"core/Engines/WebGPU/webgpuShaderProcessor\";\r\nimport { type WebGPUPipelineContext } from \"core/Engines/WebGPU/webgpuPipelineContext\";\r\nimport { type GaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplattingMesh.pure\";\r\nimport { _IsGaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplatting.functions\";\r\nimport { type DrawWrapper } from \"core/Materials/drawWrapper\";\r\nimport { type Camera } from \"core/Cameras/camera.pure\";\r\nimport { type SpriteManager } from \"core/Sprites/spriteManager\";\r\nimport { type IParticleSystem } from \"core/Particles/IParticleSystem\";\r\nimport { type ParticleSystem } from \"core/Particles/particleSystem.pure\";\r\n\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { BindMorphTargetParameters } from \"core/Materials/materialHelper.functions\";\r\nimport { TmpVectors, type Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FrameGraphBaseLayerTask } from \"../FrameGraph/Tasks/Layers/baseLayerTask\";\r\nimport { FrameGraphUtils } from \"../FrameGraph/frameGraphUtils\";\r\n\r\n/**\r\n * Options for the snapshot rendering helper\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface SnapshotRenderingHelpersOptions {\r\n    /**\r\n     * Maximum number of influences for morph target managers\r\n     * In FAST snapshot mode, the number of influences must be fixed and cannot change from one frame to the next.\r\n     * morphTargetsNumMaxInfluences is the maximum number of non-zero influences allowed in a morph target manager.\r\n     * The final value defined for a morph target manager is: Math.min(morphTargetManager.numTargets, morphTargetsNumMaxInfluences)\r\n     * Default: 20\r\n     */\r\n    morphTargetsNumMaxInfluences?: number;\r\n}\r\n\r\n/**\r\n * A helper class to simplify work with FAST snapshot mode (WebGPU only - can be used in WebGL too, but won't do anything).\r\n */\r\nexport class SnapshotRenderingHelper {\r\n    private readonly _engine: AbstractEngine;\r\n    private readonly _scene: Scene;\r\n    private readonly _options: SnapshotRenderingHelpersOptions;\r\n    private readonly _onBeforeRenderObserver: Nullable<Observer<Scene>>;\r\n    private _onBeforeRenderObserverUpdateLayer: Nullable<Observer<Scene>>;\r\n    private readonly _onResizeObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _disableRenderingRefCount = 0;\r\n    private _currentPerformancePriorityMode = ScenePerformancePriority.BackwardCompatible;\r\n    private _pendingCurrentPerformancePriorityMode?: ScenePerformancePriority;\r\n    private _isEnabling = false;\r\n    private _enableCancelFunctions: Map<() => void, () => void> = new Map(); // first function is the callback, second function is the cancel function\r\n    private _disableCancelFunctions: Map<() => void, () => void> = new Map(); // same as above\r\n\r\n    /**\r\n     * Indicates if debug logs should be displayed\r\n     */\r\n    public showDebugLogs = false;\r\n\r\n    /**\r\n     * Creates a new snapshot rendering helper\r\n     * Note that creating an instance of the helper will set the snapshot rendering mode to SNAPSHOTRENDERING_FAST but will not enable snapshot rendering (engine.snapshotRendering is not updated).\r\n     * Note also that fixMeshes() is called as part of the construction\r\n     * @param scene The scene to use the helper in\r\n     * @param options The options for the helper\r\n     */\r\n    constructor(scene: Scene, options?: SnapshotRenderingHelpersOptions) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        this._options = {\r\n            morphTargetsNumMaxInfluences: 20,\r\n            ...options,\r\n        };\r\n\r\n        this._engine.snapshotRenderingMode = Constants.SNAPSHOTRENDERING_FAST;\r\n\r\n        this.fixMeshes();\r\n\r\n        this._onResizeObserver = this._engine.onResizeObservable.add(() => {\r\n            this._log(\"onResize\", \"start\");\r\n\r\n            // enableSnapshotRendering() will delay the actual enabling of snapshot rendering by at least a frame, so these two lines are not redundant!\r\n            if (this._fastSnapshotRenderingEnabled) {\r\n                this.disableSnapshotRendering();\r\n                this.enableSnapshotRendering();\r\n            } else if (this._isEnabling) {\r\n                // We are in the process of enabling snapshot rendering, but the engine got resized before we could actually enable it:\r\n                // * cancel all \"enable\" pending callbacks\r\n                // * increase the ref count to balance the decrease that enableSnapshotRendering() will do\r\n                // * call enableSnapshotRendering() again to restart the enabling process\r\n                this._enableCancelFunctions.forEach((cancel) => cancel());\r\n                this._enableCancelFunctions.clear();\r\n                this._disableRenderingRefCount++;\r\n                this.enableSnapshotRendering();\r\n            }\r\n\r\n            this._log(\"onResize\", \"end\");\r\n        });\r\n\r\n        this._onBeforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n            if (!this._fastSnapshotRenderingEnabled) {\r\n                return;\r\n            }\r\n\r\n            // Animates skeletons\r\n            for (const skeleton of scene.skeletons) {\r\n                skeleton.prepare(true);\r\n            }\r\n\r\n            // Handles meshes\r\n            for (const mesh of scene.meshes) {\r\n                if (mesh.infiniteDistance) {\r\n                    mesh.transferToEffect(mesh.computeWorldMatrix(true));\r\n                }\r\n\r\n                if (mesh.skeleton) {\r\n                    mesh.transferToEffect(mesh.computeWorldMatrix(true));\r\n                }\r\n\r\n                if (_IsGaussianSplattingMesh(mesh)) {\r\n                    (mesh as GaussianSplattingMesh)._postToWorker();\r\n                }\r\n\r\n                if (mesh.morphTargetManager && mesh.subMeshes) {\r\n                    // Make sure morph target animations work\r\n                    for (const subMesh of mesh.subMeshes) {\r\n                        const dw = subMesh._drawWrapper;\r\n                        const effect = dw.effect;\r\n                        if (effect) {\r\n                            const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n                            const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n                            if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n                                mesh.morphTargetManager._bind(effect);\r\n                                BindMorphTargetParameters(mesh, effect);\r\n                                ubLeftOver.update();\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Handles sprite renderers\r\n            let camera = scene.activeCamera;\r\n            if (scene.frameGraph) {\r\n                camera = FrameGraphUtils.FindMainCamera(scene.frameGraph) || camera;\r\n            }\r\n            if (scene.spriteManagers && camera) {\r\n                for (const imanager of scene.spriteManagers) {\r\n                    const manager = imanager as SpriteManager;\r\n                    const renderer = manager.spriteRenderer;\r\n\r\n                    this._spriteRendererUpdateEffects(renderer._drawWrapperBase, renderer._drawWrapperDepth, camera);\r\n                }\r\n            }\r\n\r\n            // Handles fixed-capacity particle systems\r\n            if (scene.particleSystems && camera) {\r\n                for (const ps of scene.particleSystems) {\r\n                    const particleSystem = ps as ParticleSystem;\r\n                    if (particleSystem._useFixedCapacityForSnapshot) {\r\n                        this._updateFixedCapacityParticleSystem(particleSystem, camera);\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets a value indicating if the helper is in a steady state (not in the process of enabling snapshot rendering).\r\n     */\r\n    public get isReady() {\r\n        return !this._isEnabling;\r\n    }\r\n\r\n    /**\r\n     * Enable snapshot rendering\r\n     * Use this method instead of engine.snapshotRendering=true, to make sure everything is ready before enabling snapshot rendering.\r\n     * Note that this method is ref-counted and works in pair with disableSnapshotRendering(): you should call enableSnapshotRendering() as many times as you call disableSnapshotRendering().\r\n     * @param debugMessage An optional message to display in debug logs to help identify the context of the call to enableSnapshotRendering\r\n     */\r\n    public enableSnapshotRendering(debugMessage?: string) {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        this._log(\"enableSnapshotRendering\", `called (refCount: ${this._disableRenderingRefCount - 1})${debugMessage ? ` - ${debugMessage}` : \"\"}`);\r\n\r\n        if (--this._disableRenderingRefCount > 0) {\r\n            return;\r\n        }\r\n\r\n        this._log(\"enableSnapshotRendering\", `execute`);\r\n\r\n        if (this._disableCancelFunctions.size > 0) {\r\n            this._log(\"enableSnapshotRendering\", `cancelling ${this._disableCancelFunctions.size} \"disable\" callbacks`);\r\n        }\r\n\r\n        this._disableCancelFunctions.forEach((cancel) => cancel());\r\n        this._disableCancelFunctions.clear();\r\n\r\n        this._isEnabling = true;\r\n        this._disableRenderingRefCount = 0;\r\n\r\n        this._currentPerformancePriorityMode = this._pendingCurrentPerformancePriorityMode ?? this._scene.performancePriority;\r\n        this._pendingCurrentPerformancePriorityMode = undefined;\r\n        this._scene.performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n\r\n        const callbackWhenSceneReady = () => {\r\n            this._enableCancelFunctions.delete(callbackWhenSceneReady);\r\n\r\n            // Make sure a full frame is rendered before enabling snapshot rendering, so use \"+2\" instead of \"+1\"\r\n            const targetFrameId = this._engine.frameId + 2;\r\n\r\n            this._log(\"enableSnapshotRendering\", `scene ready, add callbacks for frames ${targetFrameId} and ${targetFrameId + 1}`);\r\n\r\n            this._executeAtFrame(targetFrameId, () => {\r\n                this._log(\"enableSnapshotRendering\", `callback #1, enable snapshot rendering at the engine level`);\r\n                this._engine.snapshotRendering = true;\r\n            });\r\n\r\n            // Render one frame with snapshot rendering enabled to make sure everything is ready\r\n            this._executeAtFrame(targetFrameId + 1, () => {\r\n                this._log(\"enableSnapshotRendering\", `callback #2, signals that snapshot rendering helper is ready`);\r\n                this._isEnabling = false;\r\n            });\r\n        };\r\n\r\n        this._enableCancelFunctions.set(callbackWhenSceneReady, () => this._scene.onReadyObservable.removeCallback(callbackWhenSceneReady));\r\n\r\n        this._scene.executeWhenReady(callbackWhenSceneReady);\r\n    }\r\n\r\n    /**\r\n     * Disable snapshot rendering\r\n     * Note that this method is ref-counted and works in pair with enableSnapshotRendering(): you should call enableSnapshotRendering() as many times as you call disableSnapshotRendering().\r\n     * @param debugMessage An optional message to display in debug logs to help identify the context of the call to disableSnapshotRendering\r\n     */\r\n    public disableSnapshotRendering(debugMessage?: string) {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        this._log(\r\n            \"disableSnapshotRendering\",\r\n            `called (refCount: ${this._disableRenderingRefCount === 0 ? 0 : this._disableRenderingRefCount + 1})${debugMessage ? ` - ${debugMessage}` : \"\"}`\r\n        );\r\n\r\n        if (this._disableRenderingRefCount === 0) {\r\n            this._log(\"disableSnapshotRendering\", `execute (refCount set to 1 after execution)`);\r\n\r\n            if (this._enableCancelFunctions.size > 0) {\r\n                this._log(\"disableSnapshotRendering\", `cancelling ${this._enableCancelFunctions.size} \"enable\" callbacks`);\r\n            }\r\n\r\n            this._enableCancelFunctions.forEach((cancel) => cancel());\r\n            this._enableCancelFunctions.clear();\r\n\r\n            this._isEnabling = false;\r\n\r\n            // Snapshot rendering switches from enabled to disabled\r\n            // We reset the performance priority mode to that which it was before enabling snapshot rendering, but first set it to “BackwardCompatible” to allow the system to regenerate resources that may have been optimized for snapshot rendering.\r\n            // We'll then restore the original mode at the next frame.\r\n            this._scene.performancePriority = ScenePerformancePriority.BackwardCompatible;\r\n            if (this._currentPerformancePriorityMode !== ScenePerformancePriority.BackwardCompatible) {\r\n                this._log(\r\n                    \"disableSnapshotRendering\",\r\n                    `makes sure that the scene is rendered once in BackwardCompatible mode (code: ${ScenePerformancePriority.BackwardCompatible}) before switching to mode ${this._currentPerformancePriorityMode}`\r\n                );\r\n\r\n                this._pendingCurrentPerformancePriorityMode = this._currentPerformancePriorityMode;\r\n\r\n                const callbackWhenSceneReady = () => {\r\n                    this._log(\"disableSnapshotRendering\", `scene ready, add callback for frame ${this._engine.frameId + 2}`);\r\n\r\n                    this._executeAtFrame(\r\n                        this._engine.frameId + 2,\r\n                        () => {\r\n                            this._log(\"disableSnapshotRendering\", `switching to performance priority mode ${this._pendingCurrentPerformancePriorityMode}`);\r\n                            this._scene.performancePriority = this._pendingCurrentPerformancePriorityMode!;\r\n                            this._pendingCurrentPerformancePriorityMode = undefined;\r\n                        },\r\n                        \"whenDisabled\"\r\n                    );\r\n                };\r\n\r\n                this._disableCancelFunctions.set(callbackWhenSceneReady, () => this._scene.onReadyObservable.removeCallback(callbackWhenSceneReady));\r\n\r\n                this._scene.executeWhenReady(callbackWhenSceneReady);\r\n            }\r\n        }\r\n\r\n        this._engine.snapshotRendering = false;\r\n        this._disableRenderingRefCount++;\r\n    }\r\n\r\n    /**\r\n     * Fix meshes for snapshot rendering.\r\n     * This method will make sure that some features are disabled or fixed to make sure snapshot rendering works correctly.\r\n     * @param meshes List of meshes to fix. If not provided, all meshes in the scene will be fixed.\r\n     */\r\n    public fixMeshes(meshes?: AbstractMesh[]) {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        meshes = meshes || this._scene.meshes;\r\n\r\n        for (const mesh of meshes) {\r\n            (mesh as Mesh).ignoreCameraMaxZ = false;\r\n            if (mesh.morphTargetManager) {\r\n                mesh.morphTargetManager.numMaxInfluencers = Math.min(mesh.morphTargetManager.numTargets, this._options.morphTargetsNumMaxInfluences!);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Call this method to update a mesh on the GPU after some properties have changed (position, rotation, scaling).\r\n     * Note: in FAST snapshot mode the GPU bundle is recorded once and replayed every frame, so draw calls\r\n     * (including instance counts) are baked in. This method updates per-mesh GPU data such as transforms and\r\n     * `mesh.visibility`, but it cannot change whether a recorded draw call is emitted. To apply changes such as\r\n     * `mesh.isVisible`, `setEnabled(false)`, or per-instance visibility/state changes that affect instance counts,\r\n     * wrap the change in a disableSnapshotRendering() / enableSnapshotRendering() pair so the snapshot is\r\n     * re-recorded.\r\n     * @param mesh The mesh to update. Can be a single mesh or an array of meshes to update.\r\n     * @param updateInstancedMeshes If true, the method will also update instanced meshes. Default is true. If you know instanced meshes won't move (or you don't have instanced meshes), you can set this to false to save some CPU time.\r\n     */\r\n    public updateMesh(mesh: AbstractMesh | AbstractMesh[], updateInstancedMeshes = true) {\r\n        if (!this._fastSnapshotRenderingEnabled) {\r\n            return;\r\n        }\r\n\r\n        if (Array.isArray(mesh)) {\r\n            for (const m of mesh) {\r\n                if (!updateInstancedMeshes || !this._updateInstancedMesh(m)) {\r\n                    m.transferToEffect(m.computeWorldMatrix());\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (!updateInstancedMeshes || !this._updateInstancedMesh(mesh)) {\r\n            mesh.transferToEffect(mesh.computeWorldMatrix());\r\n        }\r\n    }\r\n\r\n    private _updateInstancedMesh(mesh: AbstractMesh) {\r\n        if (mesh.hasInstances) {\r\n            if (mesh.subMeshes) {\r\n                const sourceMesh = mesh as Mesh;\r\n                for (const subMesh of sourceMesh.subMeshes) {\r\n                    const batch = sourceMesh._getInstancesRenderList(subMesh._id);\r\n                    sourceMesh._updateInstancedBuffers(subMesh, batch, batch.parent.instancesBufferSize, this._engine);\r\n                }\r\n            }\r\n            return true;\r\n        } else if (mesh.isAnInstance) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Update the meshes used in an effect layer to ensure that snapshot rendering works correctly for these meshes in this layer.\r\n     * @param layer The effect layer or frame graph layer\r\n     * @param autoUpdate If true, the helper will automatically update the meshes of the layer with each frame. If false, you'll need to call this method manually when the camera or layer meshes move or rotate.\r\n     */\r\n    public updateMeshesForEffectLayer(layer: EffectLayer | FrameGraphBaseLayerTask, autoUpdate = true) {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        const renderPassId = layer instanceof FrameGraphBaseLayerTask ? layer.objectRendererForLayer.objectRenderer.renderPassId : layer.mainTexture.renderPassId;\r\n\r\n        if (autoUpdate) {\r\n            this._onBeforeRenderObserverUpdateLayer = this._scene.onBeforeRenderObservable.add(() => {\r\n                this._updateMeshMatricesForRenderPassId(renderPassId);\r\n            });\r\n        } else {\r\n            this._updateMeshMatricesForRenderPassId(renderPassId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose the helper\r\n     */\r\n    public dispose() {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n        this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserverUpdateLayer);\r\n        this._engine.onResizeObservable.remove(this._onResizeObserver);\r\n    }\r\n\r\n    private get _fastSnapshotRenderingEnabled() {\r\n        return this._engine.snapshotRendering && this._engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n    }\r\n\r\n    private _updateMeshMatricesForRenderPassId(renderPassId: number) {\r\n        if (!this._fastSnapshotRenderingEnabled) {\r\n            return;\r\n        }\r\n\r\n        const sceneTransformationMatrix =\r\n            this._scene.objectRenderers.find((renderer) => renderer.renderPassId === renderPassId)?.activeCamera?.getTransformationMatrix() ?? this._scene.getTransformMatrix();\r\n\r\n        for (let i = 0; i < this._scene.meshes.length; ++i) {\r\n            const mesh = this._scene.meshes[i];\r\n            if (!mesh.subMeshes) {\r\n                continue;\r\n            }\r\n\r\n            for (let j = 0; j < mesh.subMeshes.length; ++j) {\r\n                const dw = mesh.subMeshes[j]._getDrawWrapper(renderPassId);\r\n                const effect = dw?.effect;\r\n                if (effect) {\r\n                    const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n                    const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n                    if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n                        effect.setMatrix(\"viewProjection\", sceneTransformationMatrix);\r\n                        effect.setMatrix(\"world\", mesh.computeWorldMatrix());\r\n                        ubLeftOver.update();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _spriteRendererDirectMatrixUpdate(dw: DrawWrapper, camera: Camera) {\r\n        const effect = dw?.effect;\r\n        if (effect) {\r\n            const dataBuffer = (dw.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n            const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n            if (dataBuffer && ubLeftOver && ubLeftOver.setDataBuffer(dataBuffer)) {\r\n                effect.setMatrix(\"view\", camera.getViewMatrix());\r\n                effect.setMatrix(\"projection\", camera.getProjectionMatrix());\r\n                ubLeftOver.update();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _spriteRendererUpdateEffects(drawWrapperBase: DrawWrapper, drawWrapperDepth: DrawWrapper, camera: Camera) {\r\n        this._spriteRendererDirectMatrixUpdate(drawWrapperBase, camera);\r\n        this._spriteRendererDirectMatrixUpdate(drawWrapperDepth, camera);\r\n    }\r\n\r\n    /**\r\n     * Make a CPU particle system compatible with FAST snapshot rendering.\r\n     * The particle system will always render at full capacity (`getCapacity()` quads), with inactive slots collapsed\r\n     * to degenerate triangles via zero-fill. This keeps the recorded GPU bundle's draw call valid every frame, while\r\n     * the live particle data is uploaded to the bundle-referenced vertex buffer through the normal `animate()` path.\r\n     *\r\n     * The helper additionally advances the particle simulation and updates view/projection (and `eyePosition`/`invView`\r\n     * for billboard modes) into the particle system's draw wrappers each frame, because FAST snapshot replay skips the\r\n     * normal scene particle evaluation path after the bundle is recorded.\r\n     *\r\n     * Notes:\r\n     * - Call this BEFORE `enableSnapshotRendering()` so the recording sees the correct draw count.\r\n     * - GPU particle systems (`GPUParticleSystem`) are not supported by this method.\r\n     * - Vertex shader cost scales with `getCapacity()` rather than the live particle count, so size capacity realistically.\r\n     * - Per-frame uniforms other than camera matrices (e.g. `textureMask`, `translationPivot`, clip planes, fog) are\r\n     *   baked at recording time and will not update during snapshot replay.\r\n     * @param particleSystem The particle system to fix\r\n     */\r\n    public fixParticleSystem(particleSystem: IParticleSystem): void {\r\n        if (!this._engine.isWebGPU) {\r\n            return;\r\n        }\r\n\r\n        if (particleSystem.getClassName() !== \"ParticleSystem\") {\r\n            this._log(\"fixParticleSystem\", `skipping ${particleSystem.name}: only CPU ParticleSystem is supported (got ${particleSystem.getClassName()})`);\r\n            return;\r\n        }\r\n\r\n        const ps = particleSystem as ParticleSystem;\r\n        const fixedCapacityInitialized = ps._initFixedCapacitySnapshotData();\r\n\r\n        // The recorded bundle bakes in the draw-call vertex/instance count. If snapshot rendering is already active\r\n        // (or in the process of being enabled) when we flip the flag, the bundle was recorded with the live particle\r\n        // count and is now stale. Cycle disable/enable so the next recording picks up the fixed-capacity draw count.\r\n        if (fixedCapacityInitialized && (this._fastSnapshotRenderingEnabled || this._isEnabling)) {\r\n            Logger.Warn(\r\n                `SnapshotRenderingHelper.fixParticleSystem(\"${particleSystem.name}\") was called after snapshot rendering was enabled. ` +\r\n                    `Forcing a re-record so the bundle uses the fixed-capacity draw count. Call fixParticleSystem before enableSnapshotRendering to avoid this.`\r\n            );\r\n            this.disableSnapshotRendering(\"fixParticleSystem auto-recover\");\r\n            this.enableSnapshotRendering(\"fixParticleSystem auto-recover\");\r\n        }\r\n    }\r\n\r\n    private _updateFixedCapacityParticleSystem(ps: ParticleSystem, camera: Camera): void {\r\n        if (!this._scene.particlesEnabled || !ps.isStarted() || !ps.emitter) {\r\n            ps._clearFixedCapacitySnapshotData();\r\n            return;\r\n        }\r\n\r\n        const emitter = ps.emitter as { position?: unknown; isEnabled?: () => boolean };\r\n        if (!emitter.position || emitter.isEnabled?.()) {\r\n            ps.animate();\r\n            this._particleSystemUpdateEffects(ps, camera);\r\n        } else {\r\n            ps._clearFixedCapacitySnapshotData();\r\n        }\r\n    }\r\n\r\n    private _particleSystemUpdateEffects(ps: ParticleSystem, camera: Camera) {\r\n        const drawWrappers = (ps as unknown as { _drawWrappers: DrawWrapper[][] })._drawWrappers;\r\n        if (!drawWrappers) {\r\n            return;\r\n        }\r\n\r\n        const viewMatrix = ps.defaultViewMatrix ?? camera.getViewMatrix();\r\n        const projectionMatrix = ps.defaultProjectionMatrix ?? camera.getProjectionMatrix();\r\n        // Compute invView lazily once per system per frame, only if any draw wrapper actually needs it.\r\n        let invViewMatrix: Nullable<Matrix> = null;\r\n\r\n        for (const perPass of drawWrappers) {\r\n            if (!perPass) {\r\n                continue;\r\n            }\r\n            for (const dw of perPass) {\r\n                invViewMatrix = this._particleSystemDirectMatrixUpdate(dw, viewMatrix, projectionMatrix, camera, invViewMatrix);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _particleSystemBillboardFlags = new WeakMap<object, { billboard: boolean; billboardAll: boolean }>();\r\n\r\n    private _particleSystemDirectMatrixUpdate(\r\n        dw: Nullable<DrawWrapper>,\r\n        viewMatrix: Matrix,\r\n        projectionMatrix: Matrix,\r\n        camera: Camera,\r\n        invViewMatrix: Nullable<Matrix>\r\n    ): Nullable<Matrix> {\r\n        const effect = dw?.effect;\r\n        if (!effect) {\r\n            return invViewMatrix;\r\n        }\r\n        const dataBuffer = (dw!.drawContext as WebGPUDrawContext).buffers[\"LeftOver\" satisfies (typeof WebGPUShaderProcessor)[\"LeftOvertUBOName\"]];\r\n        const ubLeftOver = (effect._pipelineContext as WebGPUPipelineContext)?.uniformBuffer;\r\n        if (!dataBuffer || !ubLeftOver || !ubLeftOver.setDataBuffer(dataBuffer)) {\r\n            return invViewMatrix;\r\n        }\r\n        effect.setMatrix(\"view\", viewMatrix);\r\n        effect.setMatrix(\"projection\", projectionMatrix);\r\n        let flags = this._particleSystemBillboardFlags.get(effect);\r\n        if (!flags) {\r\n            const defines = effect.defines ?? \"\";\r\n            flags = { billboard: defines.indexOf(\"#define BILLBOARD\") >= 0, billboardAll: defines.indexOf(\"#define BILLBOARDMODE_ALL\") >= 0 };\r\n            this._particleSystemBillboardFlags.set(effect, flags);\r\n        }\r\n        if (flags.billboard) {\r\n            effect.setVector3(\"eyePosition\", camera.globalPosition);\r\n        }\r\n        if (flags.billboardAll) {\r\n            if (!invViewMatrix) {\r\n                invViewMatrix = TmpVectors.Matrix[0];\r\n                viewMatrix.invertToRef(invViewMatrix);\r\n            }\r\n            effect.setMatrix(\"invView\", invViewMatrix);\r\n        }\r\n        ubLeftOver.update();\r\n\r\n        return invViewMatrix;\r\n    }\r\n\r\n    private _executeAtFrame(frameId: number, func: () => void, mode: \"whenEnabled\" | \"whenDisabled\" = \"whenEnabled\") {\r\n        const callback = () => {\r\n            if (this._engine.frameId >= frameId) {\r\n                this._engine.onEndFrameObservable.remove(obs);\r\n                if (mode === \"whenEnabled\") {\r\n                    this._enableCancelFunctions.delete(callback);\r\n                } else {\r\n                    this._disableCancelFunctions.delete(callback);\r\n                }\r\n                func();\r\n            }\r\n        };\r\n\r\n        const obs = this._engine.onEndFrameObservable.add(callback);\r\n        if (mode === \"whenEnabled\") {\r\n            this._enableCancelFunctions.set(callback, () => this._engine.onEndFrameObservable.remove(obs));\r\n        } else {\r\n            this._disableCancelFunctions.set(callback, () => this._engine.onEndFrameObservable.remove(obs));\r\n        }\r\n    }\r\n\r\n    private _log(funcName: string, message: string) {\r\n        if (this.showDebugLogs) {\r\n            Logger.Log(`[Frame: ${this._engine.frameId}] SnapshotRenderingHelper:${funcName} - ${message}`);\r\n        }\r\n    }\r\n}\r\n","import { type CoroutineStep, inlineScheduler, type AsyncCoroutine, type CoroutineScheduler, runCoroutineAsync } from \"./coroutine\";\r\nimport { Observable } from \"./observable.pure\";\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for observableCoroutine.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterObservableCoroutine(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    function CreateObservableScheduler<T>(observable: Observable<any>): { scheduler: CoroutineScheduler<T>; dispose: () => void } {\r\n        const coroutines = new Array<AsyncCoroutine<T>>();\r\n        const onSteps = new Array<(stepResult: CoroutineStep<T>) => void>();\r\n        const onErrors = new Array<(stepError: any) => void>();\r\n\r\n        const observer = observable.add(() => {\r\n            const count = coroutines.length;\r\n            for (let i = 0; i < count; i++) {\r\n                inlineScheduler(coroutines.shift()!, onSteps.shift()!, onErrors.shift()!);\r\n            }\r\n        });\r\n\r\n        const scheduler = (coroutine: AsyncCoroutine<T>, onStep: (stepResult: CoroutineStep<T>) => void, onError: (stepError: any) => void) => {\r\n            coroutines.push(coroutine);\r\n            onSteps.push(onStep);\r\n            onErrors.push(onError);\r\n        };\r\n\r\n        return {\r\n            scheduler: scheduler,\r\n            dispose: () => {\r\n                observable.remove(observer);\r\n            },\r\n        };\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n    Observable.prototype.runCoroutineAsync = function (coroutine: AsyncCoroutine<void>) {\r\n        if (!this._coroutineScheduler) {\r\n            const schedulerAndDispose = CreateObservableScheduler<void>(this);\r\n            this._coroutineScheduler = schedulerAndDispose.scheduler;\r\n            this._coroutineSchedulerDispose = schedulerAndDispose.dispose;\r\n        }\r\n\r\n        return runCoroutineAsync(coroutine, this._coroutineScheduler);\r\n    };\r\n\r\n    Observable.prototype.cancelAllCoroutines = function () {\r\n        if (this._coroutineSchedulerDispose) {\r\n            this._coroutineSchedulerDispose();\r\n        }\r\n        this._coroutineScheduler = undefined;\r\n        this._coroutineSchedulerDispose = undefined;\r\n    };\r\n}\r\n","import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { type ThinTexture } from \"core/Materials/Textures/thinTexture\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { WhenTextureReadyAsync } from \"core/Misc/textureTools\";\r\nimport { BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\ntype KernelData = {\r\n    kernel: Float32Array;\r\n    kernelSize: number;\r\n    kernelHalfSize: number;\r\n};\r\n\r\n/**\r\n * Class used for fast copy from one texture to another\r\n */\r\nexport class AreaLightTextureTools {\r\n    private _engine: AbstractEngine;\r\n    private _renderer: EffectRenderer;\r\n    private _effectWrapper: EffectWrapper;\r\n    private _source: BaseTexture;\r\n    private _scalingRange: Vector2;\r\n    private _kernelLibrary: KernelData[] = [];\r\n    private readonly _blurSize = 5;\r\n    private readonly _alphaFactor = 0.5;\r\n\r\n    /** Shader language used */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    private _textureIsInternal(texture: InternalTexture | ThinTexture): texture is InternalTexture {\r\n        return (texture as ThinTexture)?.getInternalTexture === undefined;\r\n    }\r\n\r\n    /**\r\n     * Constructs a new instance of the class\r\n     * @param engine The engine to use for the copy\r\n     */\r\n    constructor(engine: AbstractEngine) {\r\n        this._engine = engine;\r\n        this._renderer = new EffectRenderer(this._engine);\r\n        this._scalingRange = new Vector2();\r\n\r\n        for (let i = 0; i < 512; i++) {\r\n            const kernelSize = this._blurSize + (i + 1) * 2;\r\n            const alpha = (kernelSize / 2.0) * this._alphaFactor;\r\n            this._kernelLibrary.push(this._generateGaussianKernel(kernelSize, alpha));\r\n        }\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n    private _createEffect(): EffectWrapper {\r\n        const engine = this._engine;\r\n        let isWebGPU = false;\r\n\r\n        if (engine?.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n            isWebGPU = true;\r\n        }\r\n\r\n        const effectWrapper = new EffectWrapper({\r\n            engine: engine,\r\n            name: \"AreaLightTextureProcessing\",\r\n            fragmentShader: \"areaLightTextureProcessing\",\r\n            useShaderStore: true,\r\n            uniformNames: [\"scalingRange\"],\r\n            samplerNames: [\"textureSampler\"],\r\n            defines: [],\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await import(\"../ShadersWGSL/areaLightTextureProcessing.fragment\");\r\n                } else {\r\n                    await import(\"../Shaders/areaLightTextureProcessing.fragment\");\r\n                }\r\n            },\r\n        });\r\n\r\n        effectWrapper.onApplyObservable.add(() => {\r\n            engine.depthCullingState.depthMask = false;\r\n            if (this._textureIsInternal(this._source)) {\r\n                effectWrapper.effect._bindTexture(\"textureSampler\", this._source);\r\n            } else {\r\n                effectWrapper.effect.setTexture(\"textureSampler\", this._source);\r\n            }\r\n            effectWrapper.effect.setVector2(\"scalingRange\", this._scalingRange);\r\n        });\r\n\r\n        return effectWrapper;\r\n    }\r\n\r\n    /**\r\n     * Indicates if the effect is ready to be used for the copy\r\n     * @returns true if \"copy\" can be called without delay, else false\r\n     */\r\n    public isReady(): boolean {\r\n        return this._shadersLoaded && !!this._effectWrapper?.effect?.isReady();\r\n    }\r\n\r\n    /**\r\n     * Pre-processes the texture to be used with RectAreaLight emissionTexture.\r\n     * @param source The texture to pre-process\r\n     * @returns A promise that resolves with the pre-processed texture\r\n     */\r\n    public async processAsync(source: BaseTexture): Promise<Nullable<BaseTexture>> {\r\n        if (!this._shadersLoaded) {\r\n            this._effectWrapper = this._createEffect();\r\n            await this._effectWrapper.effect.whenCompiledAsync();\r\n            this._shadersLoaded = true;\r\n        }\r\n\r\n        if (!source.isReady()) {\r\n            await WhenTextureReadyAsync(source);\r\n        }\r\n\r\n        this._scalingRange.x = 0.125;\r\n        this._scalingRange.y = 0.875;\r\n\r\n        this._source = source;\r\n        const oldWrapU = this._source.wrapU;\r\n        const oldWrapV = this._source.wrapV;\r\n\r\n        this._source.wrapU = Constants.TEXTURE_MIRROR_ADDRESSMODE;\r\n        this._source.wrapV = Constants.TEXTURE_MIRROR_ADDRESSMODE;\r\n\r\n        const result = await this._scaleImageDownAsync(source);\r\n        await this._applyProgressiveBlurAsync(result);\r\n\r\n        result.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n        result.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n\r\n        this._source.wrapU = oldWrapU;\r\n        this._source.wrapV = oldWrapV;\r\n\r\n        return result;\r\n    }\r\n\r\n    private async _scaleImageDownAsync(source: BaseTexture): Promise<BaseTexture> {\r\n        const renderTarget = this._engine.createRenderTargetTexture(\r\n            { width: 1024, height: 1024 },\r\n            {\r\n                generateDepthBuffer: false,\r\n                generateMipMaps: true,\r\n                generateStencilBuffer: false,\r\n                samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n                type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                format: Constants.TEXTUREFORMAT_RGBA,\r\n            }\r\n        );\r\n\r\n        this._source = source;\r\n        const engineDepthMask = this._engine.getDepthWrite(); // for some reasons, depthWrite is not restored by EffectRenderer.restoreStates\r\n        this._renderer.render(this._effectWrapper, renderTarget);\r\n        this._engine.setDepthWrite(engineDepthMask);\r\n        return new BaseTexture(this._engine, renderTarget.texture);\r\n    }\r\n\r\n    private _generateGaussianKernel(size: number, sigma: number): KernelData {\r\n        if (size % 2 === 0) {\r\n            throw new Error(\"Kernel size must be odd.\");\r\n        }\r\n\r\n        const kernel = new Float32Array(size);\r\n        let sum = 0.0;\r\n        const halfSize = Math.floor(size / 2);\r\n\r\n        for (let i = -halfSize; i <= halfSize; ++i) {\r\n            const value = Math.exp(-(i * i) / (2.0 * sigma * sigma));\r\n            const index = i + halfSize;\r\n            kernel[index] = value;\r\n            sum += value;\r\n        }\r\n\r\n        for (let i = 0; i < kernel.length; i++) {\r\n            kernel[i] /= sum;\r\n        }\r\n\r\n        return { kernel, kernelSize: size, kernelHalfSize: halfSize };\r\n    }\r\n\r\n    private _mirrorIndex(x: number, width: number): number {\r\n        if (x < 0) {\r\n            x = -x;\r\n        }\r\n        if (x >= width) {\r\n            x = 2 * width - 2 - x;\r\n        }\r\n        return x;\r\n    }\r\n\r\n    private _applyGaussianBlurRange(input: Uint8Array, output: Uint8Array, width: number, height: number, channels: number, kernelLibrary: KernelData[]) {\r\n        const marginStart = Math.floor(width * 0.125);\r\n        const marginEnd = Math.floor(width * 0.875);\r\n\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                let targetKernel = 0;\r\n\r\n                if (x <= marginStart) {\r\n                    targetKernel = Math.max(targetKernel, Math.abs(x - marginStart));\r\n                }\r\n                if (y <= marginStart) {\r\n                    targetKernel = Math.max(targetKernel, Math.abs(y - marginStart));\r\n                }\r\n                if (x >= marginEnd) {\r\n                    targetKernel = Math.max(targetKernel, Math.abs(x - marginEnd));\r\n                }\r\n                if (y >= marginEnd) {\r\n                    targetKernel = Math.max(targetKernel, Math.abs(y - marginEnd));\r\n                }\r\n\r\n                const kernelData = kernelLibrary[targetKernel];\r\n                const { kernel, kernelHalfSize } = kernelData;\r\n\r\n                for (let c = 0; c < channels - 1; c++) {\r\n                    let sum = 0.0;\r\n                    for (let kx = -kernelHalfSize; kx <= kernelHalfSize; kx++) {\r\n                        const px = this._mirrorIndex(x + kx, width);\r\n                        const weight = kernel[kx + kernelHalfSize];\r\n                        const pixelData = input[(y * width + px) * channels + c];\r\n                        sum += pixelData * weight;\r\n                    }\r\n                    output[(y * width + x) * channels + c] = Math.max(0, Math.min(255, Math.round(sum)));\r\n                }\r\n                // copy alpha if present\r\n                if (channels > 3) {\r\n                    output[(y * width + x) * channels + (channels - 1)] = input[(y * width + x) * channels + (channels - 1)];\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _transposeImage(input: Uint8Array, width: number, height: number, channels: number, output: Uint8Array): void {\r\n        for (let y = 0; y < height; y++) {\r\n            for (let x = 0; x < width; x++) {\r\n                const srcBase = (y * width + x) * channels;\r\n                const dstBase = (x * height + y) * channels;\r\n                for (let c = 0; c < channels; c++) {\r\n                    output[dstBase + c] = input[srcBase + c];\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private async _applyProgressiveBlurAsync(source: BaseTexture): Promise<void> {\r\n        const pixelData = await source.readPixels();\r\n\r\n        if (!pixelData) {\r\n            return;\r\n        }\r\n\r\n        const internalTexture = source.getInternalTexture();\r\n\r\n        if (!internalTexture) {\r\n            return;\r\n        }\r\n\r\n        const rourcePixel = new Uint8Array(pixelData.buffer);\r\n        const result = new Uint8Array(rourcePixel.length);\r\n\r\n        this._applyGaussianBlurRange(rourcePixel, result, internalTexture.width, internalTexture.height, 4, this._kernelLibrary);\r\n        this._transposeImage(result, internalTexture.width, internalTexture.height, 4, rourcePixel);\r\n        this._applyGaussianBlurRange(rourcePixel, result, internalTexture.width, internalTexture.height, 4, this._kernelLibrary);\r\n        this._transposeImage(result, internalTexture.width, internalTexture.height, 4, rourcePixel);\r\n        this._engine.updateRawTexture(internalTexture, rourcePixel, internalTexture.format, false);\r\n    }\r\n\r\n    /**\r\n     * Releases all the resources used by the class\r\n     */\r\n    public dispose(): void {\r\n        this._effectWrapper?.dispose();\r\n        this._renderer.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ReflectionProbe } from \"../Probes/reflectionProbe.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { CustomProceduralTexture } from \"../Materials/Textures/Procedurals/customProceduralTexture\";\r\nimport { DumpData } from \"./dumpTools.pure\";\r\nimport { type Vector3 } from \"../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Interface containing options related to equirectangular capture of the current scene\r\n */\r\n// Should have \"I\" prefix but we are keeping it as is for backward compatibility\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface EquiRectangularCaptureOptions {\r\n    /**\r\n     * This option relates to smallest dimension of the given equirectangular capture\r\n     * Giving a 512px size would result in an image that 512 x 1024px\r\n     */\r\n    size: number;\r\n    /**\r\n     * Optional function to map which meshes should get rendered on the equirectangular map\r\n     * This is specifically helpful when you have certain meshes that you want to skip, especially ground\r\n     */\r\n    meshesFilter?: (mesh: AbstractMesh) => boolean;\r\n    /**\r\n     * Optional argument to specify filename, passing this would auto download the given file\r\n     */\r\n    filename?: string;\r\n\r\n    /**\r\n     * Optional argument to specify position in 3D Space from where the equirectangular capture should be taken, if not specified, it would take the position of the scene's active camera or else origin\r\n     */\r\n    position?: Vector3;\r\n\r\n    /**\r\n     * Optional argument to specify probe with which the equirectangular image is generated\r\n     * When passing this, size and position arguments are ignored\r\n     */\r\n    probe?: ReflectionProbe;\r\n}\r\n\r\n/**\r\n * @param scene This refers to the scene which would be rendered in the given equirectangular capture\r\n * @param options This refers to the options for a given equirectangular capture\r\n * @returns the requested capture's pixel-data or auto downloads the file if options.filename is specified\r\n */\r\n// Should end with \"Async\" and start with \"C\" but we are keeping it as is for backward compatibility\r\n// eslint-disable-next-line no-restricted-syntax, @typescript-eslint/naming-convention\r\nexport async function captureEquirectangularFromScene(scene: Scene, options: EquiRectangularCaptureOptions): Promise<ArrayBufferView | null> {\r\n    const probe: ReflectionProbe = options.probe ?? new ReflectionProbe(\"tempProbe\", options.size, scene);\r\n    const wasProbeProvided = !!options.probe;\r\n    if (!wasProbeProvided) {\r\n        if (options.position) {\r\n            probe.position = options.position.clone();\r\n        } else if (scene.activeCamera) {\r\n            probe.position = scene.activeCamera.position.clone();\r\n        }\r\n    }\r\n    const meshesToConsider = options.meshesFilter ? scene.meshes.filter(options.meshesFilter) : scene.meshes;\r\n    probe.renderList?.push(...meshesToConsider);\r\n    probe.refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;\r\n    probe.cubeTexture.render();\r\n    const dumpTexture = new CustomProceduralTexture(\"tempProceduralTexture\", \"equirectangularPanorama\", { width: options.size * 2, height: options.size }, scene);\r\n    dumpTexture.setTexture(\"cubeMap\", probe.cubeTexture);\r\n    return await new Promise((resolve, reject) => {\r\n        dumpTexture.onGeneratedObservable.addOnce(() => {\r\n            const pixelDataPromise = dumpTexture.readPixels();\r\n            if (!pixelDataPromise) {\r\n                reject(new Error(\"No Pixel Data found on procedural texture\"));\r\n                dumpTexture.dispose();\r\n                if (!wasProbeProvided) {\r\n                    probe.dispose();\r\n                }\r\n                return;\r\n            }\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n            pixelDataPromise.then((pixelData) => {\r\n                dumpTexture.dispose();\r\n                if (!wasProbeProvided) {\r\n                    probe.dispose();\r\n                }\r\n                if (options.filename) {\r\n                    DumpData(options.size * 2, options.size, pixelData, undefined, \"image/png\", options.filename);\r\n                    resolve(null);\r\n                } else {\r\n                    resolve(pixelData);\r\n                }\r\n            });\r\n        });\r\n    });\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"equirectangularPanoramaPixelShader\";\nconst shader = `#ifdef GL_ES\nprecision highp float;\n#endif\n#define M_PI 3.1415926535897932384626433832795\nvarying vec2 vUV;uniform samplerCube cubeMap;void main(void) {vec2 uv=vUV;float longitude=uv.x*2.*M_PI-M_PI+M_PI/2.;float latitude=(1.-uv.y)*M_PI;vec3 dir=vec3(\n- sin( longitude )*sin( latitude ),\ncos( latitude ),\n- cos( longitude )*sin( latitude )\n);normalize( dir );gl_FragColor=textureCube( cubeMap,dir );}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const equirectangularPanoramaPixelShader = { name, shader };\n","import { Deferred } from \"./deferred\";\r\n\r\n/**\r\n * Provides a simple way of creating the rough equivalent of an async critical section.\r\n *\r\n * @example\r\n * ```typescript\r\n * const myLock = new AsyncLock();\r\n *\r\n * private async MyFuncAsync(): Promise<void> {\r\n *   await myLock.lockAsync(async () => {\r\n *     await operation1Async();\r\n *     await operation2Async();\r\n *   });\r\n * }\r\n * ```\r\n */\r\nexport class AsyncLock {\r\n    private _currentOperation: Promise<void> = Promise.resolve();\r\n\r\n    /**\r\n     * Executes the provided function when the lock is acquired (e.g. when the previous operation finishes).\r\n     * @param func The function to execute.\r\n     * @param signal An optional signal that can be used to abort the operation.\r\n     * @returns A promise that resolves when the func finishes executing.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public lockAsync<T>(func: () => T | Promise<T>, signal?: AbortSignal): Promise<T> {\r\n        signal?.throwIfAborted();\r\n\r\n        const wrappedFunc = signal\r\n            ? // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n              () => {\r\n                  signal.throwIfAborted();\r\n                  return func();\r\n              }\r\n            : func;\r\n\r\n        // eslint-disable-next-line github/no-then\r\n        const newOperation = this._currentOperation.then(wrappedFunc);\r\n        // NOTE: It would be simpler to just hold a Promise<unknown>, but this class should not prevent an object held by the returned promise from being garbage collected.\r\n        this._currentOperation = new Promise<void>((resolve) => {\r\n            // eslint-disable-next-line github/no-then\r\n            newOperation.then(() => resolve(), resolve);\r\n        });\r\n        return newOperation;\r\n    }\r\n\r\n    /**\r\n     * Executes the provided function when all the specified locks are acquired.\r\n     * @param func The function to execute.\r\n     * @param locks The locks to acquire.\r\n     * @param signal An optional signal that can be used to abort the operation.\r\n     * @returns A promise that resolves when the func finishes executing.\r\n     */\r\n    public static async LockAsync<T>(func: () => T | Promise<T>, locks: AsyncLock[], signal?: AbortSignal): Promise<T> {\r\n        signal?.throwIfAborted();\r\n\r\n        if (locks.length === 0) {\r\n            return await func();\r\n        }\r\n\r\n        const deferred = new Deferred<T>();\r\n        let acquiredLocks = 0;\r\n\r\n        for (const lock of locks) {\r\n            lock.lockAsync(async () => {\r\n                acquiredLocks++;\r\n                if (acquiredLocks === locks.length) {\r\n                    deferred.resolve(await func());\r\n                }\r\n                return await deferred.promise;\r\n                // eslint-disable-next-line github/no-then\r\n            }, signal).catch((e) => deferred.reject(e));\r\n        }\r\n\r\n        return await deferred.promise;\r\n    }\r\n}\r\n","/**\r\n * A class that lazily initializes a value given a factory function.\r\n */\r\nexport class Lazy<T> {\r\n    private _factory: (() => T) | undefined;\r\n    private _value: T | undefined;\r\n\r\n    /**\r\n     * Creates a new instance of the Lazy class.\r\n     * @param factory A function that creates the value.\r\n     */\r\n    constructor(factory: () => T) {\r\n        this._factory = factory;\r\n    }\r\n\r\n    /**\r\n     * Gets the lazily initialized value.\r\n     */\r\n    public get value(): T {\r\n        // If the factory function is still defined, it means we haven't called it yet.\r\n        if (this._factory) {\r\n            this._value = this._factory();\r\n            // Set the factory function to undefined to allow it to be garbage collected.\r\n            this._factory = undefined;\r\n        }\r\n        return this._value as T;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"rgbdDecodePixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{gl_FragColor=vec4(fromRGBD(texture2D(textureSampler,vUV)),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const rgbdDecodePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"rgbdEncodePixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{gl_FragColor=toRGBD(texture2D(textureSampler,vUV).rgb);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const rgbdEncodePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"rgbdDecodePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=vec4f(fromRGBD(textureSample(textureSampler,textureSamplerSampler,input.vUV)),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const rgbdDecodePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"rgbdEncodePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=toRGBD(textureSample(textureSampler,textureSamplerSampler,input.vUV).rgb);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const rgbdEncodePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"copyTextureToTexturePixelShader\";\nconst shader = `uniform float conversion;uniform sampler2D textureSampler;uniform float lodLevel;varying vec2 vUV;\n#include<helperFunctions>\nvoid main(void) \n{\n#ifdef NO_SAMPLER\nvec4 color=texelFetch(textureSampler,ivec2(gl_FragCoord.xy),0);\n#else\nvec4 color=textureLod(textureSampler,vUV,lodLevel);\n#endif\n#ifdef DEPTH_TEXTURE\ngl_FragDepth=color.r;\n#else\nif (conversion==1.) {color=toLinearSpace(color);} else if (conversion==2.) {color=toGammaSpace(color);}\ngl_FragColor=color;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const copyTextureToTexturePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"copyTextureToTexturePixelShader\";\nconst shader = `uniform conversion: f32;\n#ifndef NO_SAMPLER\nvar textureSamplerSampler: sampler;\n#endif\nvar textureSampler: texture_2d<f32>;uniform lodLevel : f32;varying vUV: vec2f;\n#include<helperFunctions>\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#ifdef NO_SAMPLER\nvar color: vec4f=textureLoad(textureSampler,vec2u(fragmentInputs.position.xy),u32(uniforms.lodLevel));\n#else\nvar color: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,uniforms.lodLevel);\n#endif\n#ifdef DEPTH_TEXTURE\nfragmentOutputs.fragDepth=color.r;\n#else\nif (uniforms.conversion==1.) {color=toLinearSpaceVec4(color);} else if (uniforms.conversion==2.) {color=toGammaSpace(color);}\nfragmentOutputs.color=color;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const copyTextureToTexturePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"areaLightTextureProcessingPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform vec2 scalingRange;varying vec2 vUV;void main(void)\n{float x=(vUV.x-scalingRange.x)/(scalingRange.y-scalingRange.x);float y=(vUV.y-scalingRange.x)/(scalingRange.y-scalingRange.x);vec2 scaledUV=vec2(x,y);gl_FragColor=texture2D(textureSampler,scaledUV);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const areaLightTextureProcessingPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"areaLightTextureProcessingPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform scalingRange: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let x: f32=(input.vUV.x-uniforms.scalingRange.x)/(uniforms.scalingRange.y-uniforms.scalingRange.x);let y: f32=(input.vUV.y-uniforms.scalingRange.x)/(uniforms.scalingRange.y-uniforms.scalingRange.x);let scaledUV: vec2f=vec2f(x,y);fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,scaledUV);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const areaLightTextureProcessingPixelShaderWGSL = { name, shader };\n","import { type INavigationEnginePlugin, type ICrowd, type IAgentParameters, type INavMeshParameters, type IObstacle } from \"../../Navigation/INavigationEngine\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { VertexData } from \"../../Meshes/mesh.vertexData\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Epsilon, Vector3, Matrix } from \"../../Maths/math\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { type Observer, Observable } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { VertexBuffer } from \"../../Buffers/buffer.pure\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ndeclare let Recast: any;\r\n\r\n/**\r\n * RecastJS navigation plugin\r\n */\r\nexport class RecastJSPlugin implements INavigationEnginePlugin {\r\n    /**\r\n     * Reference to the Recast library\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public bjsRECAST: any = {};\r\n\r\n    /**\r\n     * plugin name\r\n     */\r\n    public name: string = \"RecastJSPlugin\";\r\n\r\n    /**\r\n     * the first navmesh created. We might extend this to support multiple navmeshes\r\n     */\r\n    public navMesh: any;\r\n\r\n    private _maximumSubStepCount: number = 10;\r\n    private _timeStep: number = 1 / 60;\r\n    private _timeFactor: number = 1;\r\n\r\n    private _tempVec1: any;\r\n    private _tempVec2: any;\r\n\r\n    private _worker: Nullable<Worker> = null;\r\n\r\n    /**\r\n     * Initializes the recastJS plugin\r\n     * @param recastInjection can be used to inject your own recast reference\r\n     */\r\n    public constructor(recastInjection: any = Recast) {\r\n        if (typeof recastInjection === \"function\") {\r\n            Logger.Error(\"RecastJS is not ready. Please make sure you await Recast() before using the plugin.\");\r\n        } else {\r\n            this.bjsRECAST = recastInjection;\r\n        }\r\n\r\n        if (!this.isSupported()) {\r\n            Logger.Error(\"RecastJS is not available. Please make sure you included the js file.\");\r\n            return;\r\n        }\r\n        this.setTimeStep();\r\n\r\n        this._tempVec1 = new this.bjsRECAST.Vec3();\r\n        this._tempVec2 = new this.bjsRECAST.Vec3();\r\n    }\r\n\r\n    /**\r\n     * Set worker URL to be used when generating a new navmesh\r\n     * @param workerURL url string\r\n     * @returns boolean indicating if worker is created\r\n     */\r\n    public setWorkerURL(workerURL: string | URL): boolean {\r\n        if (window && window.Worker) {\r\n            this._worker = new Worker(workerURL);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Set the time step of the navigation tick update.\r\n     * Default is 1/60.\r\n     * A value of 0 will disable fixed time update\r\n     * @param newTimeStep the new timestep to apply to this world.\r\n     */\r\n    setTimeStep(newTimeStep: number = 1 / 60): void {\r\n        this._timeStep = newTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Get the time step of the navigation tick update.\r\n     * @returns the current time step\r\n     */\r\n    getTimeStep(): number {\r\n        return this._timeStep;\r\n    }\r\n\r\n    /**\r\n     * If delta time in navigation tick update is greater than the time step\r\n     * a number of sub iterations are done. If more iterations are needed to reach deltatime\r\n     * they will be discarded.\r\n     * A value of 0 will set to no maximum and update will use as many substeps as needed\r\n     * @param newStepCount the maximum number of iterations\r\n     */\r\n    setMaximumSubStepCount(newStepCount: number = 10): void {\r\n        this._maximumSubStepCount = newStepCount;\r\n    }\r\n\r\n    /**\r\n     * Get the maximum number of iterations per navigation tick update\r\n     * @returns the maximum number of iterations\r\n     */\r\n    getMaximumSubStepCount(): number {\r\n        return this._maximumSubStepCount;\r\n    }\r\n\r\n    /**\r\n     * Time factor applied when updating crowd agents (default 1). A value of 0 will pause crowd updates.\r\n     * @param value the time factor applied at update\r\n     */\r\n    public set timeFactor(value: number) {\r\n        this._timeFactor = Math.max(value, 0);\r\n    }\r\n\r\n    /**\r\n     * Get the time factor used for crowd agent update\r\n     * @returns the time factor\r\n     */\r\n    public get timeFactor(): number {\r\n        return this._timeFactor;\r\n    }\r\n\r\n    /**\r\n     * Creates a navigation mesh\r\n     * @param meshes array of all the geometry used to compute the navigation mesh\r\n     * @param parameters bunch of parameters used to filter geometry\r\n     * @param completion callback when data is available from the worker. Not used without a worker\r\n     */\r\n    createNavMesh(meshes: Array<Mesh>, parameters: INavMeshParameters, completion?: (navmeshData: Uint8Array) => void): void {\r\n        if (this._worker && !completion) {\r\n            Logger.Warn(\"A worker is available but no completion callback. Defaulting to blocking navmesh creation\");\r\n        } else if (!this._worker && completion) {\r\n            Logger.Warn(\"A completion callback is available but no worker. Defaulting to blocking navmesh creation\");\r\n        }\r\n\r\n        this.navMesh = new this.bjsRECAST.NavMesh();\r\n\r\n        let index: number;\r\n        let tri: number;\r\n        let pt: number;\r\n\r\n        const indices = [];\r\n        const positions = [];\r\n        let offset = 0;\r\n        for (index = 0; index < meshes.length; index++) {\r\n            if (meshes[index]) {\r\n                const mesh = meshes[index];\r\n\r\n                const meshIndices = mesh.getIndices();\r\n                if (!meshIndices) {\r\n                    continue;\r\n                }\r\n                const meshPositions = mesh.getVerticesData(VertexBuffer.PositionKind, false, false);\r\n                if (!meshPositions) {\r\n                    continue;\r\n                }\r\n\r\n                const worldMatrices = [];\r\n                const worldMatrix = mesh.computeWorldMatrix(true);\r\n\r\n                if (mesh.hasThinInstances) {\r\n                    const thinMatrices = mesh.thinInstanceGetWorldMatrices();\r\n                    for (let instanceIndex = 0; instanceIndex < thinMatrices.length; instanceIndex++) {\r\n                        const tmpMatrix = new Matrix();\r\n                        const thinMatrix = thinMatrices[instanceIndex];\r\n                        thinMatrix.multiplyToRef(worldMatrix, tmpMatrix);\r\n                        worldMatrices.push(tmpMatrix);\r\n                    }\r\n                } else {\r\n                    worldMatrices.push(worldMatrix);\r\n                }\r\n\r\n                for (let matrixIndex = 0; matrixIndex < worldMatrices.length; matrixIndex++) {\r\n                    const wm = worldMatrices[matrixIndex];\r\n                    for (tri = 0; tri < meshIndices.length; tri++) {\r\n                        indices.push(meshIndices[tri] + offset);\r\n                    }\r\n\r\n                    const transformed = Vector3.Zero();\r\n                    const position = Vector3.Zero();\r\n                    for (pt = 0; pt < meshPositions.length; pt += 3) {\r\n                        Vector3.FromArrayToRef(meshPositions, pt, position);\r\n                        Vector3.TransformCoordinatesToRef(position, wm, transformed);\r\n                        positions.push(transformed.x, transformed.y, transformed.z);\r\n                    }\r\n\r\n                    offset += meshPositions.length / 3;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._worker && completion) {\r\n            // spawn worker and send message\r\n            this._worker.postMessage([positions, offset, indices, indices.length, parameters]);\r\n            this._worker.onmessage = function (e) {\r\n                completion(e.data);\r\n            };\r\n        } else {\r\n            // blocking calls\r\n            const rc = new this.bjsRECAST.rcConfig();\r\n            rc.cs = parameters.cs;\r\n            rc.ch = parameters.ch;\r\n            rc.borderSize = parameters.borderSize ? parameters.borderSize : 0;\r\n            rc.tileSize = parameters.tileSize ? parameters.tileSize : 0;\r\n            rc.walkableSlopeAngle = parameters.walkableSlopeAngle;\r\n            rc.walkableHeight = parameters.walkableHeight;\r\n            rc.walkableClimb = parameters.walkableClimb;\r\n            rc.walkableRadius = parameters.walkableRadius;\r\n            rc.maxEdgeLen = parameters.maxEdgeLen;\r\n            rc.maxSimplificationError = parameters.maxSimplificationError;\r\n            rc.minRegionArea = parameters.minRegionArea;\r\n            rc.mergeRegionArea = parameters.mergeRegionArea;\r\n            rc.maxVertsPerPoly = parameters.maxVertsPerPoly;\r\n            rc.detailSampleDist = parameters.detailSampleDist;\r\n            rc.detailSampleMaxError = parameters.detailSampleMaxError;\r\n\r\n            this.navMesh.build(positions, offset, indices, indices.length, rc);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Create a navigation mesh debug mesh\r\n     * @param scene is where the mesh will be added\r\n     * @returns debug display mesh\r\n     */\r\n    createDebugNavMesh(scene: Scene): Mesh {\r\n        let tri: number;\r\n        let pt: number;\r\n        const debugNavMesh = this.navMesh.getDebugNavMesh();\r\n        const triangleCount = debugNavMesh.getTriangleCount();\r\n\r\n        const indices = [];\r\n        const positions = [];\r\n        for (tri = 0; tri < triangleCount * 3; tri++) {\r\n            indices.push(tri);\r\n        }\r\n        for (tri = 0; tri < triangleCount; tri++) {\r\n            for (pt = 0; pt < 3; pt++) {\r\n                const point = debugNavMesh.getTriangle(tri).getPoint(pt);\r\n                positions.push(point.x, point.y, point.z);\r\n            }\r\n        }\r\n\r\n        const mesh = new Mesh(\"NavMeshDebug\", scene);\r\n        const vertexData = new VertexData();\r\n\r\n        vertexData.indices = indices;\r\n        vertexData.positions = positions;\r\n        vertexData.applyToMesh(mesh, false);\r\n        return mesh;\r\n    }\r\n\r\n    /**\r\n     * Get a navigation mesh constrained position, closest to the parameter position\r\n     * @param position world position\r\n     * @returns the closest point to position constrained by the navigation mesh\r\n     */\r\n    getClosestPoint(position: Vector3): Vector3 {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        const ret = this.navMesh.getClosestPoint(this._tempVec1);\r\n        const pr = new Vector3(ret.x, ret.y, ret.z);\r\n        return pr;\r\n    }\r\n\r\n    /**\r\n     * Get a navigation mesh constrained position, closest to the parameter position\r\n     * @param position world position\r\n     * @param result output the closest point to position constrained by the navigation mesh\r\n     */\r\n    getClosestPointToRef(position: Vector3, result: Vector3): void {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        const ret = this.navMesh.getClosestPoint(this._tempVec1);\r\n        result.set(ret.x, ret.y, ret.z);\r\n    }\r\n\r\n    /**\r\n     * Get a navigation mesh constrained position, within a particular radius\r\n     * @param position world position\r\n     * @param maxRadius the maximum distance to the constrained world position\r\n     * @returns the closest point to position constrained by the navigation mesh\r\n     */\r\n    getRandomPointAround(position: Vector3, maxRadius: number): Vector3 {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        const ret = this.navMesh.getRandomPointAround(this._tempVec1, maxRadius);\r\n        const pr = new Vector3(ret.x, ret.y, ret.z);\r\n        return pr;\r\n    }\r\n\r\n    /**\r\n     * Get a navigation mesh constrained position, within a particular radius\r\n     * @param position world position\r\n     * @param maxRadius the maximum distance to the constrained world position\r\n     * @param result output the closest point to position constrained by the navigation mesh\r\n     */\r\n    getRandomPointAroundToRef(position: Vector3, maxRadius: number, result: Vector3): void {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        const ret = this.navMesh.getRandomPointAround(this._tempVec1, maxRadius);\r\n        result.set(ret.x, ret.y, ret.z);\r\n    }\r\n\r\n    /**\r\n     * Compute the final position from a segment made of destination-position\r\n     * @param position world position\r\n     * @param destination world position\r\n     * @returns the resulting point along the navmesh\r\n     */\r\n    moveAlong(position: Vector3, destination: Vector3): Vector3 {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        this._tempVec2.x = destination.x;\r\n        this._tempVec2.y = destination.y;\r\n        this._tempVec2.z = destination.z;\r\n        const ret = this.navMesh.moveAlong(this._tempVec1, this._tempVec2);\r\n        const pr = new Vector3(ret.x, ret.y, ret.z);\r\n        return pr;\r\n    }\r\n\r\n    /**\r\n     * Compute the final position from a segment made of destination-position\r\n     * @param position world position\r\n     * @param destination world position\r\n     * @param result output the resulting point along the navmesh\r\n     */\r\n    moveAlongToRef(position: Vector3, destination: Vector3, result: Vector3): void {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        this._tempVec2.x = destination.x;\r\n        this._tempVec2.y = destination.y;\r\n        this._tempVec2.z = destination.z;\r\n        const ret = this.navMesh.moveAlong(this._tempVec1, this._tempVec2);\r\n        result.set(ret.x, ret.y, ret.z);\r\n    }\r\n\r\n    private _convertNavPathPoints(navPath: any): Vector3[] {\r\n        let pt: number;\r\n        const pointCount = navPath.getPointCount();\r\n        const positions = [];\r\n        for (pt = 0; pt < pointCount; pt++) {\r\n            const p = navPath.getPoint(pt);\r\n            positions.push(new Vector3(p.x, p.y, p.z));\r\n        }\r\n        return positions;\r\n    }\r\n\r\n    /**\r\n     * Compute a navigation path from start to end. Returns an empty array if no path can be computed\r\n     * Path is straight.\r\n     * @param start world position\r\n     * @param end world position\r\n     * @returns array containing world position composing the path\r\n     */\r\n    computePath(start: Vector3, end: Vector3): Vector3[] {\r\n        this._tempVec1.x = start.x;\r\n        this._tempVec1.y = start.y;\r\n        this._tempVec1.z = start.z;\r\n        this._tempVec2.x = end.x;\r\n        this._tempVec2.y = end.y;\r\n        this._tempVec2.z = end.z;\r\n        const navPath = this.navMesh.computePath(this._tempVec1, this._tempVec2);\r\n        return this._convertNavPathPoints(navPath);\r\n    }\r\n\r\n    /**\r\n     * Compute a navigation path from start to end. Returns an empty array if no path can be computed.\r\n     * Path follows navigation mesh geometry.\r\n     * @param start world position\r\n     * @param end world position\r\n     * @returns array containing world position composing the path\r\n     */\r\n    computePathSmooth(start: Vector3, end: Vector3): Vector3[] {\r\n        this._tempVec1.x = start.x;\r\n        this._tempVec1.y = start.y;\r\n        this._tempVec1.z = start.z;\r\n        this._tempVec2.x = end.x;\r\n        this._tempVec2.y = end.y;\r\n        this._tempVec2.z = end.z;\r\n        const navPath = this.navMesh.computePathSmooth(this._tempVec1, this._tempVec2);\r\n        return this._convertNavPathPoints(navPath);\r\n    }\r\n    /**\r\n     * Create a new Crowd so you can add agents\r\n     * @param maxAgents the maximum agent count in the crowd\r\n     * @param maxAgentRadius the maximum radius an agent can have\r\n     * @param scene to attach the crowd to\r\n     * @returns the crowd you can add agents to\r\n     */\r\n    createCrowd(maxAgents: number, maxAgentRadius: number, scene: Scene): ICrowd {\r\n        const crowd = new RecastJSCrowd(this, maxAgents, maxAgentRadius, scene);\r\n        return crowd;\r\n    }\r\n\r\n    /**\r\n     * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)\r\n     * The queries will try to find a solution within those bounds\r\n     * default is (1,1,1)\r\n     * @param extent x,y,z value that define the extent around the queries point of reference\r\n     */\r\n    setDefaultQueryExtent(extent: Vector3): void {\r\n        this._tempVec1.x = extent.x;\r\n        this._tempVec1.y = extent.y;\r\n        this._tempVec1.z = extent.z;\r\n        this.navMesh.setDefaultQueryExtent(this._tempVec1);\r\n    }\r\n\r\n    /**\r\n     * Get the Bounding box extent specified by setDefaultQueryExtent\r\n     * @returns the box extent values\r\n     */\r\n    getDefaultQueryExtent(): Vector3 {\r\n        const p = this.navMesh.getDefaultQueryExtent();\r\n        return new Vector3(p.x, p.y, p.z);\r\n    }\r\n\r\n    /**\r\n     * build the navmesh from a previously saved state using getNavmeshData\r\n     * @param data the Uint8Array returned by getNavmeshData\r\n     */\r\n    buildFromNavmeshData(data: Uint8Array): void {\r\n        const nDataBytes = data.length * data.BYTES_PER_ELEMENT;\r\n        const dataPtr = this.bjsRECAST._malloc(nDataBytes);\r\n\r\n        const dataHeap = new Uint8Array(this.bjsRECAST.HEAPU8.buffer, dataPtr, nDataBytes);\r\n        dataHeap.set(data);\r\n\r\n        const buf = new this.bjsRECAST.NavmeshData();\r\n        buf.dataPointer = dataHeap.byteOffset;\r\n        buf.size = data.length;\r\n        this.navMesh = new this.bjsRECAST.NavMesh();\r\n        this.navMesh.buildFromNavmeshData(buf);\r\n\r\n        // Free memory\r\n        this.bjsRECAST._free(dataHeap.byteOffset);\r\n    }\r\n\r\n    /**\r\n     * returns the navmesh data that can be used later. The navmesh must be built before retrieving the data\r\n     * @returns data the Uint8Array that can be saved and reused\r\n     */\r\n    getNavmeshData(): Uint8Array {\r\n        const navmeshData = this.navMesh.getNavmeshData();\r\n        const arrView = new Uint8Array(this.bjsRECAST.HEAPU8.buffer, navmeshData.dataPointer, navmeshData.size);\r\n        const ret = new Uint8Array(navmeshData.size);\r\n        ret.set(arrView);\r\n        this.navMesh.freeNavmeshData(navmeshData);\r\n        return ret;\r\n    }\r\n\r\n    /**\r\n     * Get the Bounding box extent result specified by setDefaultQueryExtent\r\n     * @param result output the box extent values\r\n     */\r\n    getDefaultQueryExtentToRef(result: Vector3): void {\r\n        const p = this.navMesh.getDefaultQueryExtent();\r\n        result.set(p.x, p.y, p.z);\r\n    }\r\n\r\n    /**\r\n     * Disposes of the plugin resources\r\n     */\r\n    public dispose() {\r\n        if (this._worker) {\r\n            // Clear handlers and terminate the worker to avoid leaks\r\n            this._worker.onmessage = null;\r\n            // Clear other handlers if they were used\r\n            (this._worker as any).onerror = null;\r\n            this._worker.terminate();\r\n        }\r\n        this._worker = null;\r\n    }\r\n\r\n    /**\r\n     * Creates a cylinder obstacle and add it to the navigation\r\n     * @param position world position\r\n     * @param radius cylinder radius\r\n     * @param height cylinder height\r\n     * @returns the obstacle freshly created\r\n     */\r\n    addCylinderObstacle(position: Vector3, radius: number, height: number): Nullable<IObstacle> {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        return this.navMesh.addCylinderObstacle(this._tempVec1, radius, height);\r\n    }\r\n\r\n    /**\r\n     * Creates an oriented box obstacle and add it to the navigation\r\n     * @param position world position\r\n     * @param extent box size\r\n     * @param angle angle in radians of the box orientation on Y axis\r\n     * @returns the obstacle freshly created\r\n     */\r\n    addBoxObstacle(position: Vector3, extent: Vector3, angle: number): Nullable<IObstacle> {\r\n        this._tempVec1.x = position.x;\r\n        this._tempVec1.y = position.y;\r\n        this._tempVec1.z = position.z;\r\n        this._tempVec2.x = extent.x;\r\n        this._tempVec2.y = extent.y;\r\n        this._tempVec2.z = extent.z;\r\n        return this.navMesh.addBoxObstacle(this._tempVec1, this._tempVec2, angle);\r\n    }\r\n\r\n    /**\r\n     * Removes an obstacle created by addCylinderObstacle or addBoxObstacle\r\n     * @param obstacle obstacle to remove from the navigation\r\n     */\r\n    removeObstacle(obstacle: IObstacle): void {\r\n        this.navMesh.removeObstacle(obstacle);\r\n    }\r\n\r\n    /**\r\n     * If this plugin is supported\r\n     * @returns true if plugin is supported\r\n     */\r\n    public isSupported(): boolean {\r\n        return this.bjsRECAST !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Returns the seed used for randomized functions like `getRandomPointAround`\r\n     * @returns seed number\r\n     */\r\n    public getRandomSeed(): number {\r\n        return this.bjsRECAST._getRandomSeed();\r\n    }\r\n\r\n    /**\r\n     * Set the seed used for randomized functions like `getRandomPointAround`\r\n     * @param seed number used as seed for random functions\r\n     */\r\n    public setRandomSeed(seed: number): void {\r\n        this.bjsRECAST._setRandomSeed(seed);\r\n    }\r\n}\r\n\r\n/**\r\n * Recast detour crowd implementation\r\n */\r\nexport class RecastJSCrowd implements ICrowd {\r\n    /**\r\n     * Recast/detour plugin\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public bjsRECASTPlugin: RecastJSPlugin;\r\n    /**\r\n     * Link to the detour crowd\r\n     */\r\n    public recastCrowd: any = {};\r\n    /**\r\n     * One transform per agent\r\n     */\r\n    public transforms: TransformNode[] = new Array<TransformNode>();\r\n    /**\r\n     * All agents created\r\n     */\r\n    public agents: number[] = new Array<number>();\r\n    /**\r\n     * agents reach radius\r\n     */\r\n    public reachRadii: number[] = new Array<number>();\r\n    /**\r\n     * true when a destination is active for an agent and notifier hasn't been notified of reach\r\n     */\r\n    private _agentDestinationArmed: boolean[] = new Array<boolean>();\r\n    /**\r\n     * agent current target\r\n     */\r\n    private _agentDestination: Vector3[] = new Array<Vector3>();\r\n    /**\r\n     * Link to the scene is kept to unregister the crowd from the scene\r\n     */\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Observer for crowd updates\r\n     */\r\n    private _onBeforeAnimationsObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    /**\r\n     * Fires each time an agent is in reach radius of its destination\r\n     */\r\n    public onReachTargetObservable = new Observable<{ agentIndex: number; destination: Vector3 }>();\r\n\r\n    /**\r\n     * Constructor\r\n     * @param plugin recastJS plugin\r\n     * @param maxAgents the maximum agent count in the crowd\r\n     * @param maxAgentRadius the maximum radius an agent can have\r\n     * @param scene to attach the crowd to\r\n     * @returns the crowd you can add agents to\r\n     */\r\n    public constructor(plugin: RecastJSPlugin, maxAgents: number, maxAgentRadius: number, scene: Scene) {\r\n        this.bjsRECASTPlugin = plugin;\r\n        this.recastCrowd = new this.bjsRECASTPlugin.bjsRECAST.Crowd(maxAgents, maxAgentRadius, this.bjsRECASTPlugin.navMesh.getNavMesh());\r\n        this._scene = scene;\r\n\r\n        this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {\r\n            this.update(scene.getEngine().getDeltaTime() * 0.001 * plugin.timeFactor);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Add a new agent to the crowd with the specified parameter a corresponding transformNode.\r\n     * You can attach anything to that node. The node position is updated in the scene update tick.\r\n     * @param pos world position that will be constrained by the navigation mesh\r\n     * @param parameters agent parameters\r\n     * @param transform hooked to the agent that will be update by the scene\r\n     * @returns agent index\r\n     */\r\n    addAgent(pos: Vector3, parameters: IAgentParameters, transform: TransformNode): number {\r\n        const agentParams = new this.bjsRECASTPlugin.bjsRECAST.dtCrowdAgentParams();\r\n        agentParams.radius = parameters.radius;\r\n        agentParams.height = parameters.height;\r\n        agentParams.maxAcceleration = parameters.maxAcceleration;\r\n        agentParams.maxSpeed = parameters.maxSpeed;\r\n        agentParams.collisionQueryRange = parameters.collisionQueryRange;\r\n        agentParams.pathOptimizationRange = parameters.pathOptimizationRange;\r\n        agentParams.separationWeight = parameters.separationWeight;\r\n        agentParams.updateFlags = 7;\r\n        agentParams.obstacleAvoidanceType = 0;\r\n        agentParams.queryFilterType = 0;\r\n        agentParams.userData = 0;\r\n\r\n        const agentIndex = this.recastCrowd.addAgent(new this.bjsRECASTPlugin.bjsRECAST.Vec3(pos.x, pos.y, pos.z), agentParams);\r\n        this.transforms.push(transform);\r\n        this.agents.push(agentIndex);\r\n        this.reachRadii.push(parameters.reachRadius ? parameters.reachRadius : parameters.radius);\r\n        this._agentDestinationArmed.push(false);\r\n        this._agentDestination.push(new Vector3(0, 0, 0));\r\n        return agentIndex;\r\n    }\r\n\r\n    /**\r\n     * Returns the agent position in world space\r\n     * @param index agent index returned by addAgent\r\n     * @returns world space position\r\n     */\r\n    getAgentPosition(index: number): Vector3 {\r\n        const agentPos = this.recastCrowd.getAgentPosition(index);\r\n        return new Vector3(agentPos.x, agentPos.y, agentPos.z);\r\n    }\r\n\r\n    /**\r\n     * Returns the agent position result in world space\r\n     * @param index agent index returned by addAgent\r\n     * @param result output world space position\r\n     */\r\n    getAgentPositionToRef(index: number, result: Vector3): void {\r\n        const agentPos = this.recastCrowd.getAgentPosition(index);\r\n        result.set(agentPos.x, agentPos.y, agentPos.z);\r\n    }\r\n\r\n    /**\r\n     * Returns the agent velocity in world space\r\n     * @param index agent index returned by addAgent\r\n     * @returns world space velocity\r\n     */\r\n    getAgentVelocity(index: number): Vector3 {\r\n        const agentVel = this.recastCrowd.getAgentVelocity(index);\r\n        return new Vector3(agentVel.x, agentVel.y, agentVel.z);\r\n    }\r\n\r\n    /**\r\n     * Returns the agent velocity result in world space\r\n     * @param index agent index returned by addAgent\r\n     * @param result output world space velocity\r\n     */\r\n    getAgentVelocityToRef(index: number, result: Vector3): void {\r\n        const agentVel = this.recastCrowd.getAgentVelocity(index);\r\n        result.set(agentVel.x, agentVel.y, agentVel.z);\r\n    }\r\n\r\n    /**\r\n     * Returns the agent next target point on the path\r\n     * @param index agent index returned by addAgent\r\n     * @returns world space position\r\n     */\r\n    getAgentNextTargetPath(index: number): Vector3 {\r\n        const pathTargetPos = this.recastCrowd.getAgentNextTargetPath(index);\r\n        return new Vector3(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);\r\n    }\r\n\r\n    /**\r\n     * Returns the agent next target point on the path\r\n     * @param index agent index returned by addAgent\r\n     * @param result output world space position\r\n     */\r\n    getAgentNextTargetPathToRef(index: number, result: Vector3): void {\r\n        const pathTargetPos = this.recastCrowd.getAgentNextTargetPath(index);\r\n        result.set(pathTargetPos.x, pathTargetPos.y, pathTargetPos.z);\r\n    }\r\n\r\n    /**\r\n     * Gets the agent state\r\n     * @param index agent index returned by addAgent\r\n     * @returns agent state\r\n     */\r\n    getAgentState(index: number): number {\r\n        return this.recastCrowd.getAgentState(index);\r\n    }\r\n\r\n    /**\r\n     * returns true if the agent in over an off mesh link connection\r\n     * @param index agent index returned by addAgent\r\n     * @returns true if over an off mesh link connection\r\n     */\r\n    overOffmeshConnection(index: number): boolean {\r\n        return this.recastCrowd.overOffmeshConnection(index);\r\n    }\r\n\r\n    /**\r\n     * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh\r\n     * @param index agent index returned by addAgent\r\n     * @param destination targeted world position\r\n     */\r\n    agentGoto(index: number, destination: Vector3): void {\r\n        this.recastCrowd.agentGoto(index, new this.bjsRECASTPlugin.bjsRECAST.Vec3(destination.x, destination.y, destination.z));\r\n\r\n        // arm observer\r\n        const item = this.agents.indexOf(index);\r\n        if (item > -1) {\r\n            this._agentDestinationArmed[item] = true;\r\n            this._agentDestination[item].set(destination.x, destination.y, destination.z);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Teleport the agent to a new position\r\n     * @param index agent index returned by addAgent\r\n     * @param destination targeted world position\r\n     */\r\n    agentTeleport(index: number, destination: Vector3): void {\r\n        this.recastCrowd.agentTeleport(index, new this.bjsRECASTPlugin.bjsRECAST.Vec3(destination.x, destination.y, destination.z));\r\n    }\r\n\r\n    /**\r\n     * Update agent parameters\r\n     * @param index agent index returned by addAgent\r\n     * @param parameters agent parameters\r\n     */\r\n    updateAgentParameters(index: number, parameters: IAgentParameters): void {\r\n        const agentParams = this.recastCrowd.getAgentParameters(index);\r\n\r\n        if (parameters.radius !== undefined) {\r\n            agentParams.radius = parameters.radius;\r\n        }\r\n        if (parameters.height !== undefined) {\r\n            agentParams.height = parameters.height;\r\n        }\r\n        if (parameters.maxAcceleration !== undefined) {\r\n            agentParams.maxAcceleration = parameters.maxAcceleration;\r\n        }\r\n        if (parameters.maxSpeed !== undefined) {\r\n            agentParams.maxSpeed = parameters.maxSpeed;\r\n        }\r\n        if (parameters.collisionQueryRange !== undefined) {\r\n            agentParams.collisionQueryRange = parameters.collisionQueryRange;\r\n        }\r\n        if (parameters.pathOptimizationRange !== undefined) {\r\n            agentParams.pathOptimizationRange = parameters.pathOptimizationRange;\r\n        }\r\n        if (parameters.separationWeight !== undefined) {\r\n            agentParams.separationWeight = parameters.separationWeight;\r\n        }\r\n\r\n        this.recastCrowd.setAgentParameters(index, agentParams);\r\n    }\r\n\r\n    /**\r\n     * remove a particular agent previously created\r\n     * @param index agent index returned by addAgent\r\n     */\r\n    removeAgent(index: number): void {\r\n        this.recastCrowd.removeAgent(index);\r\n\r\n        const item = this.agents.indexOf(index);\r\n        if (item > -1) {\r\n            this.agents.splice(item, 1);\r\n            this.transforms.splice(item, 1);\r\n            this.reachRadii.splice(item, 1);\r\n            this._agentDestinationArmed.splice(item, 1);\r\n            this._agentDestination.splice(item, 1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * get the list of all agents attached to this crowd\r\n     * @returns list of agent indices\r\n     */\r\n    getAgents(): number[] {\r\n        return this.agents;\r\n    }\r\n\r\n    /**\r\n     * Tick update done by the Scene. Agent position/velocity/acceleration is updated by this function\r\n     * @param deltaTime in seconds\r\n     */\r\n    update(deltaTime: number): void {\r\n        // update obstacles\r\n        this.bjsRECASTPlugin.navMesh.update();\r\n\r\n        if (deltaTime <= Epsilon) {\r\n            return;\r\n        }\r\n        // update crowd\r\n        const timeStep = this.bjsRECASTPlugin.getTimeStep();\r\n        const maxStepCount = this.bjsRECASTPlugin.getMaximumSubStepCount();\r\n        if (timeStep <= Epsilon) {\r\n            this.recastCrowd.update(deltaTime);\r\n        } else {\r\n            let iterationCount = Math.floor(deltaTime / timeStep);\r\n            if (maxStepCount && iterationCount > maxStepCount) {\r\n                iterationCount = maxStepCount;\r\n            }\r\n            if (iterationCount < 1) {\r\n                iterationCount = 1;\r\n            }\r\n\r\n            const step = deltaTime / iterationCount;\r\n            for (let i = 0; i < iterationCount; i++) {\r\n                this.recastCrowd.update(step);\r\n            }\r\n        }\r\n\r\n        // update transforms\r\n        for (let index = 0; index < this.agents.length; index++) {\r\n            // update transform position\r\n            const agentIndex = this.agents[index];\r\n            const agentPosition = this.getAgentPosition(agentIndex);\r\n            this.transforms[index].position = agentPosition;\r\n            // check agent reach destination\r\n            if (this._agentDestinationArmed[index]) {\r\n                const dx = agentPosition.x - this._agentDestination[index].x;\r\n                const dz = agentPosition.z - this._agentDestination[index].z;\r\n                const radius = this.reachRadii[index];\r\n                const groundY = this._agentDestination[index].y - this.reachRadii[index];\r\n                const ceilingY = this._agentDestination[index].y + this.reachRadii[index];\r\n                const distanceXZSquared = dx * dx + dz * dz;\r\n                if (agentPosition.y > groundY && agentPosition.y < ceilingY && distanceXZSquared < radius * radius) {\r\n                    this._agentDestinationArmed[index] = false;\r\n                    this.onReachTargetObservable.notifyObservers({ agentIndex: agentIndex, destination: this._agentDestination[index] });\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)\r\n     * The queries will try to find a solution within those bounds\r\n     * default is (1,1,1)\r\n     * @param extent x,y,z value that define the extent around the queries point of reference\r\n     */\r\n    setDefaultQueryExtent(extent: Vector3): void {\r\n        const ext = new this.bjsRECASTPlugin.bjsRECAST.Vec3(extent.x, extent.y, extent.z);\r\n        this.recastCrowd.setDefaultQueryExtent(ext);\r\n    }\r\n\r\n    /**\r\n     * Get the Bounding box extent specified by setDefaultQueryExtent\r\n     * @returns the box extent values\r\n     */\r\n    getDefaultQueryExtent(): Vector3 {\r\n        const p = this.recastCrowd.getDefaultQueryExtent();\r\n        return new Vector3(p.x, p.y, p.z);\r\n    }\r\n\r\n    /**\r\n     * Get the Bounding box extent result specified by setDefaultQueryExtent\r\n     * @param result output the box extent values\r\n     */\r\n    getDefaultQueryExtentToRef(result: Vector3): void {\r\n        const p = this.recastCrowd.getDefaultQueryExtent();\r\n        result.set(p.x, p.y, p.z);\r\n    }\r\n\r\n    /**\r\n     * Get the next corner points composing the path (max 4 points)\r\n     * @param index agent index returned by addAgent\r\n     * @returns array containing world position composing the path\r\n     */\r\n    getCorners(index: number): Vector3[] {\r\n        let pt: number;\r\n        const navPath = this.recastCrowd.getCorners(index);\r\n        const pointCount = navPath.getPointCount();\r\n        const positions = [];\r\n        for (pt = 0; pt < pointCount; pt++) {\r\n            const p = navPath.getPoint(pt);\r\n            positions.push(new Vector3(p.x, p.y, p.z));\r\n        }\r\n        return positions;\r\n    }\r\n\r\n    /**\r\n     * Release all resources\r\n     */\r\n    dispose(): void {\r\n        this.recastCrowd.destroy();\r\n        this._scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);\r\n        this._onBeforeAnimationsObserver = null;\r\n        this.onReachTargetObservable.clear();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { TimingTools } from \"../Misc/timingTools\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { GetTGAHeader } from \"../Misc/tga\";\r\nimport { type IOfflineProvider } from \"./IOfflineProvider\";\r\nimport { WebRequest } from \"../Misc/webRequest\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\n\r\n/**\r\n * Class used to enable access to IndexedDB\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimizeCached\r\n */\r\nexport class Database implements IOfflineProvider {\r\n    private _currentSceneUrl: string;\r\n    private _db: Nullable<IDBDatabase>;\r\n    private _enableSceneOffline: boolean;\r\n    private _enableTexturesOffline: boolean;\r\n    private _manifestVersionFound: number;\r\n    private _mustUpdateResources: boolean;\r\n    private _hasReachedQuota: boolean;\r\n    private _isSupported: boolean;\r\n\r\n    // Handling various flavors of prefixed version of IndexedDB\r\n    private _idbFactory = <IDBFactory>(typeof indexedDB !== \"undefined\" ? indexedDB : undefined);\r\n\r\n    /** Gets a boolean indicating if the user agent supports blob storage (this value will be updated after creating the first Database object) */\r\n    private static _IsUaSupportingBlobStorage = true;\r\n\r\n    /**\r\n     * Gets a boolean indicating if Database storage is enabled (off by default)\r\n     */\r\n    static IDBStorageEnabled = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating if scene must be saved in the database\r\n     */\r\n    public get enableSceneOffline(): boolean {\r\n        return this._enableSceneOffline;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if textures must be saved in the database\r\n     */\r\n    public get enableTexturesOffline(): boolean {\r\n        return this._enableTexturesOffline;\r\n    }\r\n\r\n    /**\r\n     * Creates a new Database\r\n     * @param urlToScene defines the url to load the scene\r\n     * @param callbackManifestChecked defines the callback to use when manifest is checked\r\n     * @param disableManifestCheck defines a boolean indicating that we want to skip the manifest validation (it will be considered validated and up to date)\r\n     */\r\n    constructor(urlToScene: string, callbackManifestChecked: (checked: boolean) => any, disableManifestCheck = false) {\r\n        this._currentSceneUrl = Database._ReturnFullUrlLocation(urlToScene);\r\n        this._db = null;\r\n        this._enableSceneOffline = false;\r\n        this._enableTexturesOffline = false;\r\n        this._manifestVersionFound = 0;\r\n        this._mustUpdateResources = false;\r\n        this._hasReachedQuota = false;\r\n\r\n        if (!Database.IDBStorageEnabled) {\r\n            callbackManifestChecked(true);\r\n        } else {\r\n            if (disableManifestCheck) {\r\n                this._enableSceneOffline = true;\r\n                this._enableTexturesOffline = true;\r\n                this._manifestVersionFound = 1;\r\n                TimingTools.SetImmediate(() => {\r\n                    callbackManifestChecked(true);\r\n                });\r\n            } else {\r\n                this._checkManifestFile(callbackManifestChecked);\r\n            }\r\n        }\r\n    }\r\n\r\n    private static _ParseURL = (url: string) => {\r\n        const a = document.createElement(\"a\");\r\n        a.href = url;\r\n        const urlWithoutHash = url.substring(0, url.lastIndexOf(\"#\"));\r\n        const fileName = url.substring(urlWithoutHash.lastIndexOf(\"/\") + 1, url.length);\r\n        const absLocation = url.substring(0, url.indexOf(fileName, 0));\r\n        return absLocation;\r\n    };\r\n\r\n    private static _ReturnFullUrlLocation = (url: string): string => {\r\n        if (url.indexOf(\"http:/\") === -1 && url.indexOf(\"https:/\") === -1 && typeof window !== \"undefined\") {\r\n            return Database._ParseURL(window.location.href) + url;\r\n        } else {\r\n            return url;\r\n        }\r\n    };\r\n\r\n    private _checkManifestFile(callbackManifestChecked: (checked: boolean) => any) {\r\n        const noManifestFile = () => {\r\n            this._enableSceneOffline = false;\r\n            this._enableTexturesOffline = false;\r\n            callbackManifestChecked(false);\r\n        };\r\n\r\n        const createManifestURL = (): string => {\r\n            try {\r\n                // make sure we have a valid URL.\r\n                if (typeof URL === \"function\" && this._currentSceneUrl.indexOf(\"http\") === 0) {\r\n                    // we don't have the base url, so the URL string must have a protocol\r\n                    const url = new URL(this._currentSceneUrl);\r\n                    url.pathname += \".manifest\";\r\n                    return url.toString();\r\n                }\r\n            } catch (e) {\r\n                // defensive - if this fails for any reason, fall back to the older method\r\n            }\r\n\r\n            return `${this._currentSceneUrl}.manifest`;\r\n        };\r\n\r\n        let timeStampUsed = false;\r\n        let manifestURL = createManifestURL();\r\n\r\n        const xhr = new WebRequest();\r\n\r\n        if (navigator.onLine) {\r\n            // Adding a timestamp to by-pass browsers' cache\r\n            timeStampUsed = true;\r\n            manifestURL = manifestURL + (manifestURL.match(/\\?/) == null ? \"?\" : \"&\") + Date.now();\r\n        }\r\n        xhr.open(\"GET\", manifestURL);\r\n\r\n        xhr.addEventListener(\r\n            \"load\",\r\n            () => {\r\n                if (xhr.status === 200 || Database._ValidateXHRData(xhr, 1)) {\r\n                    try {\r\n                        const manifestFile = JSON.parse(xhr.response);\r\n                        this._enableSceneOffline = manifestFile.enableSceneOffline;\r\n                        this._enableTexturesOffline = manifestFile.enableTexturesOffline && Database._IsUaSupportingBlobStorage;\r\n                        if (manifestFile.version && !isNaN(parseInt(manifestFile.version))) {\r\n                            this._manifestVersionFound = manifestFile.version;\r\n                        }\r\n                        callbackManifestChecked(true);\r\n                    } catch (ex) {\r\n                        noManifestFile();\r\n                    }\r\n                } else {\r\n                    noManifestFile();\r\n                }\r\n            },\r\n            false\r\n        );\r\n\r\n        xhr.addEventListener(\r\n            \"error\",\r\n            () => {\r\n                if (timeStampUsed) {\r\n                    timeStampUsed = false;\r\n                    // Let's retry without the timeStamp\r\n                    // It could fail when coupled with HTML5 Offline API\r\n                    const retryManifestURL = createManifestURL();\r\n                    xhr.open(\"GET\", retryManifestURL);\r\n                    xhr.send();\r\n                } else {\r\n                    noManifestFile();\r\n                }\r\n            },\r\n            false\r\n        );\r\n\r\n        try {\r\n            xhr.send();\r\n        } catch (ex) {\r\n            Logger.Error(\"Error on XHR send request.\");\r\n            callbackManifestChecked(false);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Open the database and make it available\r\n     * @param successCallback defines the callback to call on success\r\n     * @param errorCallback defines the callback to call on error\r\n     */\r\n    public open(successCallback: () => void, errorCallback: () => void): void {\r\n        const handleError = () => {\r\n            this._isSupported = false;\r\n            if (errorCallback) {\r\n                errorCallback();\r\n            }\r\n        };\r\n\r\n        if (!this._idbFactory || !(this._enableSceneOffline || this._enableTexturesOffline)) {\r\n            // Your browser doesn't support IndexedDB\r\n            this._isSupported = false;\r\n            if (errorCallback) {\r\n                errorCallback();\r\n            }\r\n        } else {\r\n            // If the DB hasn't been opened or created yet\r\n            if (!this._db) {\r\n                this._hasReachedQuota = false;\r\n                this._isSupported = true;\r\n\r\n                const request: IDBOpenDBRequest = this._idbFactory.open(\"babylonjs\", 1);\r\n\r\n                // Could occur if user is blocking the quota for the DB and/or doesn't grant access to IndexedDB\r\n                request.onerror = () => {\r\n                    handleError();\r\n                };\r\n\r\n                // executes when a version change transaction cannot complete due to other active transactions\r\n                request.onblocked = () => {\r\n                    Logger.Error(\"IDB request blocked. Please reload the page.\");\r\n                    handleError();\r\n                };\r\n\r\n                // DB has been opened successfully\r\n                request.onsuccess = () => {\r\n                    this._db = request.result;\r\n                    successCallback();\r\n                };\r\n\r\n                // Initialization of the DB. Creating Scenes & Textures stores\r\n                request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\r\n                    this._db = (<any>event.target).result;\r\n                    if (this._db) {\r\n                        try {\r\n                            this._db.createObjectStore(\"scenes\", { keyPath: \"sceneUrl\" });\r\n                            this._db.createObjectStore(\"versions\", { keyPath: \"sceneUrl\" });\r\n                            this._db.createObjectStore(\"textures\", { keyPath: \"textureUrl\" });\r\n                        } catch (ex) {\r\n                            Logger.Error(\"Error while creating object stores. Exception: \" + ex.message);\r\n                            handleError();\r\n                        }\r\n                    }\r\n                };\r\n            }\r\n            // DB has already been created and opened\r\n            else {\r\n                if (successCallback) {\r\n                    successCallback();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Loads an image from the database\r\n     * @param url defines the url to load from\r\n     * @param image defines the target DOM image\r\n     */\r\n    public loadImage(url: string, image: HTMLImageElement) {\r\n        const completeURL = Database._ReturnFullUrlLocation(url);\r\n\r\n        const saveAndLoadImage = () => {\r\n            if (!this._hasReachedQuota && this._db !== null) {\r\n                // the texture is not yet in the DB, let's try to save it\r\n                this._saveImageIntoDB(completeURL, image);\r\n            }\r\n            // If the texture is not in the DB and we've reached the DB quota limit\r\n            // let's load it directly from the web\r\n            else {\r\n                image.src = url;\r\n            }\r\n        };\r\n\r\n        if (!this._mustUpdateResources) {\r\n            this._loadImageFromDB(completeURL, image, saveAndLoadImage);\r\n        }\r\n        // First time we're download the images or update requested in the manifest file by a version change\r\n        else {\r\n            saveAndLoadImage();\r\n        }\r\n    }\r\n\r\n    private _loadImageFromDB(url: string, image: HTMLImageElement, notInDBCallback: () => any) {\r\n        if (this._isSupported && this._db !== null) {\r\n            let texture: any;\r\n            const transaction: IDBTransaction = this._db.transaction([\"textures\"]);\r\n\r\n            transaction.onabort = () => {\r\n                image.src = url;\r\n            };\r\n\r\n            transaction.oncomplete = () => {\r\n                let blobTextureURL: string;\r\n                if (texture && typeof URL === \"function\") {\r\n                    // check if data is an array buffer and create a Blob if it is\r\n                    let data = texture.data;\r\n                    if (texture.data instanceof ArrayBuffer) {\r\n                        const blob = new Blob([texture.data], { type: \"image/png\" });\r\n                        data = blob;\r\n                    }\r\n                    blobTextureURL = URL.createObjectURL(data);\r\n                    image.onerror = () => {\r\n                        Logger.Error(\"Error loading image from blob URL: \" + blobTextureURL + \" switching back to web url: \" + url);\r\n                        image.src = url;\r\n                    };\r\n                    image.src = blobTextureURL;\r\n                } else {\r\n                    notInDBCallback();\r\n                }\r\n            };\r\n\r\n            const getRequest: IDBRequest = transaction.objectStore(\"textures\").get(url);\r\n\r\n            getRequest.onsuccess = (event) => {\r\n                texture = (<any>event.target).result;\r\n            };\r\n            getRequest.onerror = () => {\r\n                Logger.Error(\"Error loading texture \" + url + \" from DB.\");\r\n                image.src = url;\r\n            };\r\n        } else {\r\n            Logger.Error(\"Error: IndexedDB not supported by your browser or BabylonJS Database is not open.\");\r\n            image.src = url;\r\n        }\r\n    }\r\n\r\n    private _saveImageIntoDB(url: string, image: HTMLImageElement) {\r\n        let blob: Blob;\r\n\r\n        if (this._isSupported) {\r\n            // In case of error (type not supported or quota exceeded), we're at least sending back XHR data to allow texture loading later on\r\n            const generateBlobUrl = () => {\r\n                let blobTextureURL;\r\n\r\n                if (blob && typeof URL === \"function\") {\r\n                    try {\r\n                        blobTextureURL = URL.createObjectURL(blob);\r\n                    } catch (ex) {\r\n                        // Chrome is raising a type error if we're setting the oneTimeOnly parameter\r\n                        blobTextureURL = URL.createObjectURL(blob);\r\n                    }\r\n                }\r\n\r\n                if (blobTextureURL) {\r\n                    image.src = blobTextureURL;\r\n                }\r\n            };\r\n\r\n            if (Database._IsUaSupportingBlobStorage) {\r\n                // Create XHR\r\n                const xhr = new WebRequest();\r\n\r\n                xhr.open(\"GET\", url);\r\n                xhr.responseType = \"blob\";\r\n\r\n                xhr.addEventListener(\r\n                    \"load\",\r\n                    () => {\r\n                        if (xhr.status === 200 && this._db) {\r\n                            // Blob as response\r\n                            blob = xhr.response;\r\n\r\n                            const transaction = this._db.transaction([\"textures\"], \"readwrite\");\r\n\r\n                            // the transaction could abort because of a QuotaExceededError error\r\n                            transaction.onabort = (event) => {\r\n                                try {\r\n                                    //backwards compatibility with ts 1.0, srcElement doesn't have an \"error\" according to ts 1.3\r\n                                    const srcElement = <any>event.target;\r\n                                    const error = srcElement.error;\r\n                                    if (error && error.name === \"QuotaExceededError\") {\r\n                                        this._hasReachedQuota = true;\r\n                                    }\r\n                                } catch (ex) {}\r\n                                generateBlobUrl();\r\n                            };\r\n\r\n                            transaction.oncomplete = () => {\r\n                                generateBlobUrl();\r\n                            };\r\n\r\n                            const newTexture = { textureUrl: url, data: blob };\r\n\r\n                            try {\r\n                                // Put the blob into the dabase\r\n                                const addRequest = transaction.objectStore(\"textures\").put(newTexture);\r\n                                addRequest.onsuccess = () => {};\r\n                                addRequest.onerror = () => {\r\n                                    generateBlobUrl();\r\n                                };\r\n                            } catch (ex) {\r\n                                // \"DataCloneError\" generated by Chrome when you try to inject blob into IndexedDB\r\n                                if (ex.code === 25) {\r\n                                    Database._IsUaSupportingBlobStorage = false;\r\n                                    this._enableTexturesOffline = false;\r\n                                }\r\n                                image.src = url;\r\n                            }\r\n                        } else {\r\n                            image.src = url;\r\n                        }\r\n                    },\r\n                    false\r\n                );\r\n\r\n                xhr.addEventListener(\r\n                    \"error\",\r\n                    () => {\r\n                        Logger.Error(\"Error in XHR request in BABYLON.Database.\");\r\n                        image.src = url;\r\n                    },\r\n                    false\r\n                );\r\n\r\n                xhr.send();\r\n            } else {\r\n                image.src = url;\r\n            }\r\n        } else {\r\n            Logger.Error(\"Error: IndexedDB not supported by your browser or Babylon.js database is not open.\");\r\n            image.src = url;\r\n        }\r\n    }\r\n\r\n    private _checkVersionFromDB(url: string, versionLoaded: (version: number) => void) {\r\n        const updateVersion = () => {\r\n            // the version is not yet in the DB or we need to update it\r\n            this._saveVersionIntoDB(url, versionLoaded);\r\n        };\r\n        this._loadVersionFromDB(url, versionLoaded, updateVersion);\r\n    }\r\n\r\n    private _loadVersionFromDB(url: string, callback: (version: number) => void, updateInDBCallback: () => void) {\r\n        if (this._isSupported && this._db) {\r\n            let version: any;\r\n            try {\r\n                const transaction = this._db.transaction([\"versions\"]);\r\n\r\n                transaction.oncomplete = () => {\r\n                    if (version) {\r\n                        // If the version in the JSON file is different from the version in DB\r\n                        if (this._manifestVersionFound !== version.data) {\r\n                            this._mustUpdateResources = true;\r\n                            updateInDBCallback();\r\n                        } else {\r\n                            callback(version.data);\r\n                        }\r\n                    }\r\n                    // version was not found in DB\r\n                    else {\r\n                        this._mustUpdateResources = true;\r\n                        updateInDBCallback();\r\n                    }\r\n                };\r\n\r\n                transaction.onabort = () => {\r\n                    callback(-1);\r\n                };\r\n\r\n                const getRequest = transaction.objectStore(\"versions\").get(url);\r\n\r\n                getRequest.onsuccess = (event) => {\r\n                    version = (<any>event.target).result;\r\n                };\r\n                getRequest.onerror = () => {\r\n                    Logger.Error(\"Error loading version for scene \" + url + \" from DB.\");\r\n                    callback(-1);\r\n                };\r\n            } catch (ex) {\r\n                Logger.Error(\"Error while accessing 'versions' object store (READ OP). Exception: \" + ex.message);\r\n                callback(-1);\r\n            }\r\n        } else {\r\n            Logger.Error(\"Error: IndexedDB not supported by your browser or Babylon.js database is not open.\");\r\n            callback(-1);\r\n        }\r\n    }\r\n\r\n    private _saveVersionIntoDB(url: string, callback: (version: number) => void) {\r\n        if (this._isSupported && !this._hasReachedQuota && this._db) {\r\n            try {\r\n                // Open a transaction to the database\r\n                const transaction = this._db.transaction([\"versions\"], \"readwrite\");\r\n\r\n                // the transaction could abort because of a QuotaExceededError error\r\n                transaction.onabort = (event) => {\r\n                    try {\r\n                        //backwards compatibility with ts 1.0, srcElement doesn't have an \"error\" according to ts 1.3\r\n                        const error = (<any>event.target)[\"error\"];\r\n                        if (error && error.name === \"QuotaExceededError\") {\r\n                            this._hasReachedQuota = true;\r\n                        }\r\n                    } catch (ex) {}\r\n                    callback(-1);\r\n                };\r\n\r\n                transaction.oncomplete = () => {\r\n                    callback(this._manifestVersionFound);\r\n                };\r\n\r\n                const newVersion = { sceneUrl: url, data: this._manifestVersionFound };\r\n\r\n                // Put the scene into the database\r\n                const addRequest = transaction.objectStore(\"versions\").put(newVersion);\r\n                addRequest.onsuccess = () => {};\r\n                addRequest.onerror = () => {\r\n                    Logger.Error(\"Error in DB add version request in BABYLON.Database.\");\r\n                };\r\n            } catch (ex) {\r\n                Logger.Error(\"Error while accessing 'versions' object store (WRITE OP). Exception: \" + ex.message);\r\n                callback(-1);\r\n            }\r\n        } else {\r\n            callback(-1);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Loads a file from database\r\n     * @param url defines the URL to load from\r\n     * @param sceneLoaded defines a callback to call on success\r\n     * @param progressCallBack defines a callback to call when progress changed\r\n     * @param errorCallback defines a callback to call on error\r\n     * @param useArrayBuffer defines a boolean to use array buffer instead of text string\r\n     */\r\n    public loadFile(url: string, sceneLoaded: (data: any) => void, progressCallBack?: (data: any) => void, errorCallback?: () => void, useArrayBuffer?: boolean): void {\r\n        const completeUrl = Database._ReturnFullUrlLocation(url);\r\n\r\n        const saveAndLoadFile = () => {\r\n            // the scene is not yet in the DB, let's try to save it\r\n            this._saveFile(completeUrl, sceneLoaded, progressCallBack, useArrayBuffer, errorCallback);\r\n        };\r\n\r\n        this._checkVersionFromDB(completeUrl, (version) => {\r\n            if (version !== -1) {\r\n                if (!this._mustUpdateResources) {\r\n                    this._loadFile(completeUrl, sceneLoaded, saveAndLoadFile, progressCallBack);\r\n                } else {\r\n                    this._saveFile(completeUrl, sceneLoaded, progressCallBack, useArrayBuffer, errorCallback);\r\n                }\r\n            } else {\r\n                if (errorCallback) {\r\n                    errorCallback();\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    private _loadFile(url: string, callback: (data?: any) => void, notInDBCallback: () => void, progressCallBack?: (data: any) => void) {\r\n        if (this._isSupported && this._db) {\r\n            let targetStore: string;\r\n            if (url.split(\"?\")[0].endsWith(\".babylon\")) {\r\n                targetStore = \"scenes\";\r\n            } else {\r\n                targetStore = \"textures\";\r\n            }\r\n\r\n            let file: any;\r\n            const transaction = this._db.transaction([targetStore]);\r\n\r\n            transaction.oncomplete = () => {\r\n                function loadArrayBuffer(arrayBuffer: ArrayBuffer) {\r\n                    if (progressCallBack) {\r\n                        const numberToLoad = arrayBuffer.byteLength || 0;\r\n                        progressCallBack({\r\n                            total: numberToLoad,\r\n                            loaded: numberToLoad,\r\n                            lengthComputable: true,\r\n                        });\r\n                    }\r\n                    callback(arrayBuffer);\r\n                }\r\n                if (file) {\r\n                    // check if data is a Blob, and get the array Data from the blob if it is\r\n                    if (file.data instanceof Blob) {\r\n                        const reader = new FileReader();\r\n                        reader.onload = (ev) => {\r\n                            loadArrayBuffer(ev.target?.result as ArrayBuffer);\r\n                        };\r\n                        reader.readAsArrayBuffer(file.data);\r\n                    } else {\r\n                        loadArrayBuffer(file.data);\r\n                    }\r\n                }\r\n                // file was not found in DB\r\n                else {\r\n                    notInDBCallback();\r\n                }\r\n            };\r\n\r\n            transaction.onabort = () => {\r\n                notInDBCallback();\r\n            };\r\n\r\n            const getRequest = transaction.objectStore(targetStore).get(url);\r\n\r\n            getRequest.onsuccess = (event) => {\r\n                file = (<any>event.target).result;\r\n            };\r\n            getRequest.onerror = () => {\r\n                Logger.Error(\"Error loading file \" + url + \" from DB.\");\r\n                notInDBCallback();\r\n            };\r\n        } else {\r\n            Logger.Error(\"Error: IndexedDB not supported by your browser or BabylonJS Database is not open.\");\r\n            callback();\r\n        }\r\n    }\r\n\r\n    private _saveFile(\r\n        url: string,\r\n        callback: (data?: any) => void,\r\n        progressCallback?: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any,\r\n        useArrayBuffer?: boolean,\r\n        errorCallback?: (data?: any) => void\r\n    ) {\r\n        if (this._isSupported) {\r\n            let targetStore: string;\r\n            if (url.split(\"?\")[0].endsWith(\".babylon\")) {\r\n                targetStore = \"scenes\";\r\n            } else {\r\n                targetStore = \"textures\";\r\n            }\r\n\r\n            // Create XHR\r\n            const xhr = new WebRequest();\r\n            let fileData: any;\r\n            xhr.open(\"GET\", url + (url.match(/\\?/) == null ? \"?\" : \"&\") + Date.now());\r\n\r\n            if (useArrayBuffer) {\r\n                xhr.responseType = \"arraybuffer\";\r\n            }\r\n\r\n            if (progressCallback) {\r\n                xhr.onprogress = progressCallback;\r\n            }\r\n\r\n            xhr.addEventListener(\r\n                \"load\",\r\n                () => {\r\n                    if (xhr.status === 200 || (xhr.status < 400 && Database._ValidateXHRData(xhr, !useArrayBuffer ? 1 : 6))) {\r\n                        // Blob as response\r\n                        fileData = !useArrayBuffer ? xhr.responseText : xhr.response;\r\n\r\n                        if (!this._hasReachedQuota && this._db) {\r\n                            // Open a transaction to the database\r\n                            const transaction = this._db.transaction([targetStore], \"readwrite\");\r\n\r\n                            // the transaction could abort because of a QuotaExceededError error\r\n                            transaction.onabort = (event) => {\r\n                                try {\r\n                                    //backwards compatibility with ts 1.0, srcElement doesn't have an \"error\" according to ts 1.3\r\n                                    const error = (<any>event.target)[\"error\"];\r\n                                    if (error && error.name === \"QuotaExceededError\") {\r\n                                        this._hasReachedQuota = true;\r\n                                    }\r\n                                } catch (ex) {}\r\n                                callback(fileData);\r\n                            };\r\n\r\n                            transaction.oncomplete = () => {\r\n                                callback(fileData);\r\n                            };\r\n\r\n                            let newFile;\r\n                            if (targetStore === \"scenes\") {\r\n                                newFile = { sceneUrl: url, data: fileData, version: this._manifestVersionFound };\r\n                            } else {\r\n                                newFile = { textureUrl: url, data: fileData };\r\n                            }\r\n\r\n                            try {\r\n                                // Put the scene into the database\r\n                                const addRequest = transaction.objectStore(targetStore).put(newFile);\r\n                                addRequest.onsuccess = () => {};\r\n                                addRequest.onerror = () => {\r\n                                    Logger.Error(\"Error in DB add file request in BABYLON.Database.\");\r\n                                };\r\n                            } catch (ex) {\r\n                                callback(fileData);\r\n                            }\r\n                        } else {\r\n                            callback(fileData);\r\n                        }\r\n                    } else {\r\n                        if (xhr.status >= 400 && errorCallback) {\r\n                            errorCallback(xhr);\r\n                        } else {\r\n                            callback();\r\n                        }\r\n                    }\r\n                },\r\n                false\r\n            );\r\n\r\n            xhr.addEventListener(\r\n                \"error\",\r\n                () => {\r\n                    Logger.Error(\"error on XHR request.\");\r\n                    errorCallback && errorCallback();\r\n                },\r\n                false\r\n            );\r\n\r\n            xhr.send();\r\n        } else {\r\n            Logger.Error(\"Error: IndexedDB not supported by your browser or Babylon.js database is not open.\");\r\n            errorCallback && errorCallback();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Validates if xhr data is correct\r\n     * @param xhr defines the request to validate\r\n     * @param dataType defines the expected data type\r\n     * @returns true if data is correct\r\n     */\r\n    private static _ValidateXHRData(xhr: WebRequest, dataType = 7): boolean {\r\n        // 1 for text (.babylon, manifest and shaders), 2 for TGA, 4 for DDS, 7 for all\r\n\r\n        try {\r\n            if (dataType & 1) {\r\n                if (xhr.responseText && xhr.responseText.length > 0) {\r\n                    return true;\r\n                } else if (dataType === 1) {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            if (dataType & 2) {\r\n                // Check header width and height since there is no \"TGA\" magic number\r\n                const tgaHeader = GetTGAHeader(xhr.response);\r\n\r\n                if (tgaHeader.width && tgaHeader.height && tgaHeader.width > 0 && tgaHeader.height > 0) {\r\n                    return true;\r\n                } else if (dataType === 2) {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            if (dataType & 4) {\r\n                // Check for the \"DDS\" magic number\r\n                const ddsHeader = new Uint8Array(xhr.response, 0, 3);\r\n\r\n                if (ddsHeader[0] === 68 && ddsHeader[1] === 68 && ddsHeader[2] === 83) {\r\n                    return true;\r\n                } else {\r\n                    return false;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            // Global protection\r\n        }\r\n\r\n        return false;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for database.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDatabase(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Sets the default offline provider to Babylon.js\r\n    AbstractEngine.OfflineProviderFactory = (urlToScene: string, callbackManifestChecked: (checked: boolean) => any, disableManifestCheck = false) => {\r\n        return new Database(urlToScene, callbackManifestChecked, disableManifestCheck);\r\n    };\r\n}\r\n","import { type IColor3Like, type IColor4Like, type IMatrixLike, type IVector3Like, type IVector4Like } from \"../Maths/math.like\";\r\nimport { type Effect } from \"./effect\";\r\nimport { type UniformBuffer } from \"./uniformBuffer\";\r\n\r\n/** @internal */\r\nexport class UniformBufferEffectCommonAccessor {\r\n    public setMatrix3x3: (name: string, matrix: Float32Array) => void;\r\n\r\n    public setMatrix2x2: (name: string, matrix: Float32Array) => void;\r\n\r\n    public setFloat: (name: string, x: number) => void;\r\n\r\n    public setFloat2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n    public setFloat3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n    public setFloat4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n    public setFloatArray: (name: string, array: Float32Array) => void;\r\n\r\n    public setArray: (name: string, array: number[]) => void;\r\n\r\n    public setIntArray: (name: string, array: Int32Array) => void;\r\n\r\n    public setMatrix: (name: string, mat: IMatrixLike) => void;\r\n\r\n    public setMatrices: (name: string, mat: Float32Array) => void;\r\n\r\n    public setVector3: (name: string, vector: IVector3Like) => void;\r\n\r\n    public setVector4: (name: string, vector: IVector4Like) => void;\r\n\r\n    public setColor3: (name: string, color: IColor3Like, suffix?: string) => void;\r\n\r\n    public setColor4: (name: string, color: IColor3Like, alpha: number, suffix?: string) => void;\r\n\r\n    public setDirectColor4: (name: string, color: IColor4Like) => void;\r\n\r\n    public setInt: (name: string, x: number, suffix?: string) => void;\r\n\r\n    public setInt2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n    public setInt3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n    public setInt4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n    private _isUbo(uboOrEffect: UniformBuffer | Effect): uboOrEffect is UniformBuffer {\r\n        return (uboOrEffect as UniformBuffer).addUniform !== undefined;\r\n    }\r\n\r\n    constructor(uboOrEffect: UniformBuffer | Effect) {\r\n        if (this._isUbo(uboOrEffect)) {\r\n            this.setMatrix3x3 = uboOrEffect.updateMatrix3x3.bind(uboOrEffect);\r\n            this.setMatrix2x2 = uboOrEffect.updateMatrix2x2.bind(uboOrEffect);\r\n            this.setFloat = uboOrEffect.updateFloat.bind(uboOrEffect);\r\n            this.setFloat2 = uboOrEffect.updateFloat2.bind(uboOrEffect);\r\n            this.setFloat3 = uboOrEffect.updateFloat3.bind(uboOrEffect);\r\n            this.setFloat4 = uboOrEffect.updateFloat4.bind(uboOrEffect);\r\n            this.setFloatArray = uboOrEffect.updateFloatArray.bind(uboOrEffect);\r\n            this.setArray = uboOrEffect.updateArray.bind(uboOrEffect);\r\n            this.setIntArray = uboOrEffect.updateIntArray.bind(uboOrEffect);\r\n            this.setMatrix = uboOrEffect.updateMatrix.bind(uboOrEffect);\r\n            this.setMatrices = uboOrEffect.updateMatrices.bind(uboOrEffect);\r\n            this.setVector3 = uboOrEffect.updateVector3.bind(uboOrEffect);\r\n            this.setVector4 = uboOrEffect.updateVector4.bind(uboOrEffect);\r\n            this.setColor3 = uboOrEffect.updateColor3.bind(uboOrEffect);\r\n            this.setColor4 = uboOrEffect.updateColor4.bind(uboOrEffect);\r\n            this.setDirectColor4 = uboOrEffect.updateDirectColor4.bind(uboOrEffect);\r\n            this.setInt = uboOrEffect.updateInt.bind(uboOrEffect);\r\n            this.setInt2 = uboOrEffect.updateInt2.bind(uboOrEffect);\r\n            this.setInt3 = uboOrEffect.updateInt3.bind(uboOrEffect);\r\n            this.setInt4 = uboOrEffect.updateInt4.bind(uboOrEffect);\r\n        } else {\r\n            this.setMatrix3x3 = uboOrEffect.setMatrix3x3.bind(uboOrEffect);\r\n            this.setMatrix2x2 = uboOrEffect.setMatrix2x2.bind(uboOrEffect);\r\n            this.setFloat = uboOrEffect.setFloat.bind(uboOrEffect);\r\n            this.setFloat2 = uboOrEffect.setFloat2.bind(uboOrEffect);\r\n            this.setFloat3 = uboOrEffect.setFloat3.bind(uboOrEffect);\r\n            this.setFloat4 = uboOrEffect.setFloat4.bind(uboOrEffect);\r\n            this.setFloatArray = uboOrEffect.setFloatArray.bind(uboOrEffect);\r\n            this.setArray = uboOrEffect.setArray.bind(uboOrEffect);\r\n            this.setIntArray = uboOrEffect.setIntArray.bind(uboOrEffect);\r\n            this.setMatrix = uboOrEffect.setMatrix.bind(uboOrEffect);\r\n            this.setMatrices = uboOrEffect.setMatrices.bind(uboOrEffect);\r\n            this.setVector3 = uboOrEffect.setVector3.bind(uboOrEffect);\r\n            this.setVector4 = uboOrEffect.setVector4.bind(uboOrEffect);\r\n            this.setColor3 = uboOrEffect.setColor3.bind(uboOrEffect);\r\n            this.setColor4 = uboOrEffect.setColor4.bind(uboOrEffect);\r\n            this.setDirectColor4 = uboOrEffect.setDirectColor4.bind(uboOrEffect);\r\n            this.setInt = uboOrEffect.setInt.bind(uboOrEffect);\r\n            this.setInt2 = uboOrEffect.setInt2.bind(uboOrEffect);\r\n            this.setInt3 = uboOrEffect.setInt3.bind(uboOrEffect);\r\n            this.setInt4 = uboOrEffect.setInt4.bind(uboOrEffect);\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type VertexBuffer, type Buffer } from \"../Buffers/buffer.pure\";\r\nimport { type ThinEngine } from \"../Engines/thinEngine.pure\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../Materials/effect.pure\";\r\nimport { type IGPUParticleSystemPlatform } from \"./IGPUParticleSystemPlatform\";\r\nimport { CustomParticleEmitter } from \"./EmitterTypes/customParticleEmitter\";\r\nimport { type GPUParticleSystem } from \"./gpuParticleSystem.pure\";\r\nimport { type DataArray, type Nullable } from \"../types\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { UniformBufferEffectCommonAccessor } from \"../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Engine } from \"../Engines/engine.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport { RegisterEngineTransformFeedback } from \"../Engines/Extensions/engine.transformFeedback.pure\";\r\n\r\n/** @internal */\r\nexport class WebGL2ParticleSystem implements IGPUParticleSystemPlatform {\r\n    private _parent: GPUParticleSystem;\r\n    private _engine: ThinEngine;\r\n    private _updateEffect: Effect;\r\n    private _updateEffectOptions: IEffectCreationOptions;\r\n    private _renderVAO: WebGLVertexArrayObject[] = [];\r\n    private _renderVAOEffects: Effect[] = [];\r\n    private _updateVAO: WebGLVertexArrayObject[] = [];\r\n    private _renderVertexBuffers: Array<{ [key: string]: VertexBuffer }> = [];\r\n    private _baseUniformsNamesLength: number;\r\n\r\n    /** @internal */\r\n    public readonly alignDataInBuffer = false;\r\n\r\n    /** @internal */\r\n    constructor(parent: GPUParticleSystem, engine: ThinEngine) {\r\n        RegisterEngineTransformFeedback();\r\n\r\n        this._parent = parent;\r\n        this._engine = engine;\r\n\r\n        this._updateEffectOptions = {\r\n            attributes: [\r\n                \"position\",\r\n                \"initialPosition\",\r\n                \"age\",\r\n                \"life\",\r\n                \"seed\",\r\n                \"size\",\r\n                \"color\",\r\n                \"direction\",\r\n                \"initialDirection\",\r\n                \"angle\",\r\n                \"cellIndex\",\r\n                \"cellStartOffset\",\r\n                \"noiseCoordinates1\",\r\n                \"noiseCoordinates2\",\r\n            ],\r\n            uniformsNames: [\r\n                \"currentCount\",\r\n                \"timeDelta\",\r\n                \"emitterWM\",\r\n                \"lifeTime\",\r\n                \"color1\",\r\n                \"color2\",\r\n                \"sizeRange\",\r\n                \"scaleRange\",\r\n                \"gravity\",\r\n                \"emitPower\",\r\n                \"direction1\",\r\n                \"direction2\",\r\n                \"minEmitBox\",\r\n                \"maxEmitBox\",\r\n                \"radius\",\r\n                \"directionRandomizer\",\r\n                \"height\",\r\n                \"coneAngle\",\r\n                \"stopFactor\",\r\n                \"emitIndex\",\r\n                \"emitCount\",\r\n                \"angleRange\",\r\n                \"radiusRange\",\r\n                \"cellInfos\",\r\n                \"noiseStrength\",\r\n                \"limitVelocityDamping\",\r\n                \"flowMapProjection\",\r\n                \"flowMapStrength\",\r\n            ],\r\n            uniformBuffersNames: [],\r\n            samplers: [\r\n                \"randomSampler\",\r\n                \"randomSampler2\",\r\n                \"sizeGradientSampler\",\r\n                \"angularSpeedGradientSampler\",\r\n                \"velocityGradientSampler\",\r\n                \"limitVelocityGradientSampler\",\r\n                \"noiseSampler\",\r\n                \"dragGradientSampler\",\r\n                \"flowMapSampler\",\r\n                \"meshPositionSampler\",\r\n                \"meshNormalSampler\",\r\n            ],\r\n            defines: \"\",\r\n            fallbacks: null,\r\n            onCompiled: null,\r\n            onError: null,\r\n            indexParameters: null,\r\n            maxSimultaneousLights: 0,\r\n            transformFeedbackVaryings: [],\r\n        };\r\n        this._baseUniformsNamesLength = this._updateEffectOptions.uniformsNames.length;\r\n    }\r\n\r\n    /** @internal */\r\n    public contextLost(): void {\r\n        this._updateEffect = undefined as any;\r\n        this._renderVAO.length = 0;\r\n        this._renderVAOEffects.length = 0;\r\n        this._updateVAO.length = 0;\r\n        this._renderVertexBuffers.length = 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public isUpdateBufferCreated(): boolean {\r\n        return !!this._updateEffect;\r\n    }\r\n\r\n    /** @internal */\r\n    public isUpdateBufferReady(): boolean {\r\n        return this._updateEffect?.isReady() ?? false;\r\n    }\r\n\r\n    /** @internal */\r\n    public createUpdateBuffer(defines: string): UniformBufferEffectCommonAccessor {\r\n        // Reset dynamic uniforms to avoid accumulating duplicates on rebuild\r\n        this._updateEffectOptions.uniformsNames.length = this._baseUniformsNamesLength;\r\n\r\n        this._updateEffectOptions.transformFeedbackVaryings = [\"outPosition\"];\r\n        this._updateEffectOptions.transformFeedbackVaryings.push(\"outAge\");\r\n        this._updateEffectOptions.transformFeedbackVaryings.push(\"outSize\");\r\n        this._updateEffectOptions.transformFeedbackVaryings.push(\"outLife\");\r\n        this._updateEffectOptions.transformFeedbackVaryings.push(\"outSeed\");\r\n        this._updateEffectOptions.transformFeedbackVaryings.push(\"outDirection\");\r\n\r\n        if (this._parent.particleEmitterType instanceof CustomParticleEmitter) {\r\n            this._updateEffectOptions.transformFeedbackVaryings.push(\"outInitialPosition\");\r\n        }\r\n\r\n        if (!this._parent._colorGradientsTexture) {\r\n            this._updateEffectOptions.transformFeedbackVaryings.push(\"outColor\");\r\n        }\r\n\r\n        if (this._parent._needsInitialDirection) {\r\n            this._updateEffectOptions.transformFeedbackVaryings.push(\"outInitialDirection\");\r\n        }\r\n\r\n        if (this._parent.noiseTexture) {\r\n            this._updateEffectOptions.transformFeedbackVaryings.push(\"outNoiseCoordinates1\");\r\n            this._updateEffectOptions.transformFeedbackVaryings.push(\"outNoiseCoordinates2\");\r\n        }\r\n\r\n        this._updateEffectOptions.transformFeedbackVaryings.push(\"outAngle\");\r\n\r\n        if (this._parent.isAnimationSheetEnabled) {\r\n            this._updateEffectOptions.transformFeedbackVaryings.push(\"outCellIndex\");\r\n            if (this._parent.spriteRandomStartCell) {\r\n                this._updateEffectOptions.transformFeedbackVaryings.push(\"outCellStartOffset\");\r\n            }\r\n        }\r\n\r\n        this._updateEffectOptions.defines = defines;\r\n\r\n        // Add attractor uniform names dynamically based on maxAttractors\r\n        if (defines.indexOf(\"ATTRACTORS\") !== -1) {\r\n            this._updateEffectOptions.uniformsNames.push(\"attractorCount\");\r\n            for (let i = 0; i < this._parent.maxAttractors; i++) {\r\n                this._updateEffectOptions.uniformsNames.push(\"attractorPositionAndStrength[\" + i + \"]\");\r\n            }\r\n        }\r\n\r\n        if (defines.indexOf(\"STARTSIZEGRADIENTS\") !== -1) {\r\n            this._updateEffectOptions.uniformsNames.push(\"startSizeGradientFactor\");\r\n        }\r\n\r\n        if (defines.indexOf(\"LIFETIMEGRADIENTS\") !== -1) {\r\n            this._updateEffectOptions.uniformsNames.push(\"lifeTimeGradientRange\");\r\n        }\r\n\r\n        if (defines.indexOf(\"MESHEMITTER\") !== -1) {\r\n            this._updateEffectOptions.uniformsNames.push(\"meshTriangleCount\");\r\n            this._updateEffectOptions.uniformsNames.push(\"meshTextureWidth\");\r\n        }\r\n\r\n        this._updateEffect = this._engine.createEffect(\"gpuUpdateParticles\", this._updateEffectOptions, this._engine);\r\n\r\n        return new UniformBufferEffectCommonAccessor(this._updateEffect);\r\n    }\r\n\r\n    /** @internal */\r\n    public createVertexBuffers(updateBuffer: Buffer, renderVertexBuffers: { [key: string]: VertexBuffer }): void {\r\n        this._updateVAO.push(this._createUpdateVAO(updateBuffer));\r\n\r\n        const renderEffect = this._parent._getWrapper(this._parent.blendMode).effect!;\r\n        this._renderVAO.push(this._engine.recordVertexArrayObject(renderVertexBuffers, null, renderEffect));\r\n        this._renderVAOEffects.push(renderEffect);\r\n        this._engine.bindArrayBuffer(null);\r\n\r\n        this._renderVertexBuffers.push(renderVertexBuffers);\r\n    }\r\n\r\n    /** @internal */\r\n    public createParticleBuffer(data: number[]): DataArray | DataBuffer {\r\n        return data;\r\n    }\r\n\r\n    /** @internal */\r\n    public bindDrawBuffers(index: number, effect: Effect, indexBuffer: Nullable<DataBuffer>): void {\r\n        if (indexBuffer || this._renderVAOEffects[index] !== effect) {\r\n            this._engine.bindBuffers(this._renderVertexBuffers[index], indexBuffer, effect);\r\n        } else {\r\n            this._engine.bindVertexArrayObject(this._renderVAO[index], null);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public preUpdateParticleBuffer(): void {\r\n        const engine = this._engine as Engine;\r\n\r\n        this._engine.enableEffect(this._updateEffect);\r\n\r\n        if (!engine.setState) {\r\n            throw new Error(\"GPU particles cannot work without a full Engine. ThinEngine is not supported\");\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public updateParticleBuffer(index: number, targetBuffer: Buffer, currentActiveCount: number): void {\r\n        this._updateEffect.setTexture(\"randomSampler\", this._parent._randomTexture);\r\n        this._updateEffect.setTexture(\"randomSampler2\", this._parent._randomTexture2);\r\n\r\n        if (this._parent._flowMap) {\r\n            this._updateEffect.setTexture(\"flowMapSampler\", this._parent._flowMap);\r\n        }\r\n\r\n        if (this._parent._sizeGradientsTexture) {\r\n            this._updateEffect.setTexture(\"sizeGradientSampler\", this._parent._sizeGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._angularSpeedGradientsTexture) {\r\n            this._updateEffect.setTexture(\"angularSpeedGradientSampler\", this._parent._angularSpeedGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._velocityGradientsTexture) {\r\n            this._updateEffect.setTexture(\"velocityGradientSampler\", this._parent._velocityGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._limitVelocityGradientsTexture) {\r\n            this._updateEffect.setTexture(\"limitVelocityGradientSampler\", this._parent._limitVelocityGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._dragGradientsTexture) {\r\n            this._updateEffect.setTexture(\"dragGradientSampler\", this._parent._dragGradientsTexture);\r\n        }\r\n\r\n        if (this._parent.noiseTexture) {\r\n            this._updateEffect.setTexture(\"noiseSampler\", this._parent.noiseTexture);\r\n        }\r\n\r\n        if (this._parent._meshPositionTexture) {\r\n            this._updateEffect.setTexture(\"meshPositionSampler\", this._parent._meshPositionTexture);\r\n        }\r\n\r\n        if (this._parent._meshNormalTexture) {\r\n            this._updateEffect.setTexture(\"meshNormalSampler\", this._parent._meshNormalTexture);\r\n        }\r\n\r\n        // Bind source VAO\r\n        this._engine.bindVertexArrayObject(this._updateVAO[index], null);\r\n\r\n        // Update\r\n        const engine = this._engine as Engine;\r\n\r\n        engine.bindTransformFeedbackBuffer(targetBuffer.getBuffer());\r\n        engine.setRasterizerState(false);\r\n        engine.beginTransformFeedback(true);\r\n        engine.drawArraysType(Constants.MATERIAL_PointListDrawMode, 0, currentActiveCount);\r\n        engine.endTransformFeedback();\r\n        engine.setRasterizerState(true);\r\n        engine.bindTransformFeedbackBuffer(null);\r\n    }\r\n\r\n    /** @internal */\r\n    public releaseBuffers(): void {}\r\n\r\n    /** @internal */\r\n    public releaseVertexBuffers(): void {\r\n        for (let index = 0; index < this._updateVAO.length; index++) {\r\n            this._engine.releaseVertexArrayObject(this._updateVAO[index]);\r\n        }\r\n        this._updateVAO.length = 0;\r\n\r\n        for (let index = 0; index < this._renderVAO.length; index++) {\r\n            this._engine.releaseVertexArrayObject(this._renderVAO[index]);\r\n        }\r\n        this._renderVAO.length = 0;\r\n        this._renderVAOEffects.length = 0;\r\n        this._renderVertexBuffers.length = 0;\r\n    }\r\n\r\n    private _createUpdateVAO(source: Buffer): WebGLVertexArrayObject {\r\n        const updateVertexBuffers: { [key: string]: VertexBuffer } = {};\r\n        updateVertexBuffers[\"position\"] = source.createVertexBuffer(\"position\", 0, 3);\r\n\r\n        let offset = 3;\r\n        updateVertexBuffers[\"age\"] = source.createVertexBuffer(\"age\", offset, 1);\r\n        offset += 1;\r\n        updateVertexBuffers[\"size\"] = source.createVertexBuffer(\"size\", offset, 3);\r\n        offset += 3;\r\n        updateVertexBuffers[\"life\"] = source.createVertexBuffer(\"life\", offset, 1);\r\n        offset += 1;\r\n        updateVertexBuffers[\"seed\"] = source.createVertexBuffer(\"seed\", offset, 4);\r\n        offset += 4;\r\n        updateVertexBuffers[\"direction\"] = source.createVertexBuffer(\"direction\", offset, 3);\r\n        offset += 3;\r\n\r\n        if (this._parent.particleEmitterType instanceof CustomParticleEmitter) {\r\n            updateVertexBuffers[\"initialPosition\"] = source.createVertexBuffer(\"initialPosition\", offset, 3);\r\n            offset += 3;\r\n        }\r\n\r\n        if (!this._parent._colorGradientsTexture) {\r\n            updateVertexBuffers[\"color\"] = source.createVertexBuffer(\"color\", offset, 4);\r\n            offset += 4;\r\n        }\r\n\r\n        if (this._parent._needsInitialDirection) {\r\n            updateVertexBuffers[\"initialDirection\"] = source.createVertexBuffer(\"initialDirection\", offset, 3);\r\n            offset += 3;\r\n        }\r\n\r\n        if (this._parent.noiseTexture) {\r\n            updateVertexBuffers[\"noiseCoordinates1\"] = source.createVertexBuffer(\"noiseCoordinates1\", offset, 3);\r\n            offset += 3;\r\n            updateVertexBuffers[\"noiseCoordinates2\"] = source.createVertexBuffer(\"noiseCoordinates2\", offset, 3);\r\n            offset += 3;\r\n        }\r\n\r\n        if (this._parent._angularSpeedGradientsTexture) {\r\n            updateVertexBuffers[\"angle\"] = source.createVertexBuffer(\"angle\", offset, 1);\r\n            offset += 1;\r\n        } else {\r\n            updateVertexBuffers[\"angle\"] = source.createVertexBuffer(\"angle\", offset, 2);\r\n            offset += 2;\r\n        }\r\n\r\n        if (this._parent._isAnimationSheetEnabled) {\r\n            updateVertexBuffers[\"cellIndex\"] = source.createVertexBuffer(\"cellIndex\", offset, 1);\r\n            offset += 1;\r\n            if (this._parent.spriteRandomStartCell) {\r\n                updateVertexBuffers[\"cellStartOffset\"] = source.createVertexBuffer(\"cellStartOffset\", offset, 1);\r\n            }\r\n        }\r\n\r\n        const vao = this._engine.recordVertexArrayObject(updateVertexBuffers, null, this._updateEffect);\r\n        this._engine.bindArrayBuffer(null);\r\n\r\n        return vao;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webgl2ParticleSystem.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebgl2ParticleSystem(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.WebGL2ParticleSystem\", WebGL2ParticleSystem);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesPixelShader\";\nconst shader = `#version 300 es\nvoid main() {discard;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const gpuUpdateParticlesPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesVertexShader\";\nconst shader = `#version 300 es\n#define PI 3.14159\nuniform float currentCount;uniform float timeDelta;uniform float stopFactor;uniform float emitIndex;uniform float emitCount;\n#ifndef LOCAL\nuniform mat4 emitterWM;\n#endif\nuniform vec2 lifeTime;uniform vec2 emitPower;uniform vec2 sizeRange;uniform vec4 scaleRange;\n#ifdef FLOWMAP\nuniform mat4 flowMapProjection;uniform float flowMapStrength;uniform sampler2D flowMapSampler;\n#endif\n#ifndef COLORGRADIENTS\nuniform vec4 color1;uniform vec4 color2;\n#endif\nuniform vec3 gravity;uniform sampler2D randomSampler;uniform sampler2D randomSampler2;uniform vec4 angleRange;\n#ifdef BOXEMITTER\nuniform vec3 direction1;uniform vec3 direction2;uniform vec3 minEmitBox;uniform vec3 maxEmitBox;\n#endif\n#ifdef POINTEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#endif\n#ifdef HEMISPHERICEMITTER\nuniform float radius;uniform float radiusRange;uniform float directionRandomizer;\n#endif\n#ifdef SPHEREEMITTER\nuniform float radius;uniform float radiusRange;\n#ifdef DIRECTEDSPHEREEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nuniform float radius;uniform float height;uniform float radiusRange;\n#ifdef DIRECTEDCYLINDEREMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CONEEMITTER\nuniform vec2 radius;uniform float coneAngle;uniform vec2 height;\n#ifdef DIRECTEDCONEEMITTER\nuniform vec3 direction1;uniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\nin vec3 position;\n#ifdef CUSTOMEMITTER\nin vec3 initialPosition;\n#endif\nin float age;in float life;in vec4 seed;in vec3 size;\n#ifndef COLORGRADIENTS\nin vec4 color;\n#endif\nin vec3 direction;\n#ifndef BILLBOARD\nin vec3 initialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nin float angle;\n#else\nin vec2 angle;\n#endif\n#ifdef ANIMATESHEET\nin float cellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nin float cellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nin vec3 noiseCoordinates1;in vec3 noiseCoordinates2;\n#endif\nout vec3 outPosition;\n#ifdef CUSTOMEMITTER\nout vec3 outInitialPosition;\n#endif\nout float outAge;out float outLife;out vec4 outSeed;out vec3 outSize;\n#ifndef COLORGRADIENTS\nout vec4 outColor;\n#endif\nout vec3 outDirection;\n#ifndef BILLBOARD\nout vec3 outInitialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nout float outAngle;\n#else\nout vec2 outAngle;\n#endif\n#ifdef ANIMATESHEET\nout float outCellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nout float outCellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nout vec3 outNoiseCoordinates1;out vec3 outNoiseCoordinates2;\n#endif\n#ifdef SIZEGRADIENTS\nuniform sampler2D sizeGradientSampler;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nuniform sampler2D angularSpeedGradientSampler;\n#endif \n#ifdef VELOCITYGRADIENTS\nuniform sampler2D velocityGradientSampler;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nuniform sampler2D limitVelocityGradientSampler;uniform float limitVelocityDamping;\n#endif\n#ifdef DRAGGRADIENTS\nuniform sampler2D dragGradientSampler;\n#endif\n#ifdef NOISE\nuniform vec3 noiseStrength;uniform sampler2D noiseSampler;\n#endif\n#ifdef ANIMATESHEET\nuniform vec4 cellInfos;\n#endif\n#ifdef ATTRACTORS\nuniform int attractorCount;uniform vec4 attractorPositionAndStrength[MAX_ATTRACTORS];\n#endif\n#ifdef STARTSIZEGRADIENTS\nuniform float startSizeGradientFactor;\n#endif\n#ifdef LIFETIMEGRADIENTS\nuniform vec2 lifeTimeGradientRange;\n#endif\n#ifdef MESHEMITTER\nuniform sampler2D meshPositionSampler;uniform int meshTriangleCount;uniform int meshTextureWidth;uniform vec3 direction1;uniform vec3 direction2;\n#ifdef MESHNORMALS\nuniform sampler2D meshNormalSampler;\n#endif\n#endif\nvec3 getRandomVec3(float offset) {return texture(randomSampler2,vec2(float(gl_VertexID)*offset/currentCount,0)).rgb;}\nvec4 getRandomVec4(float offset) {return texture(randomSampler,vec2(float(gl_VertexID)*offset/currentCount,0));}\nvoid main() {float newAge=age+timeDelta;\n#ifdef EMITRATECTRL\nfloat particleIndex=float(gl_VertexID);float offsetFromEmitIndex=particleIndex-emitIndex;if (offsetFromEmitIndex<0.0) {offsetFromEmitIndex+=currentCount; }\nbool shouldEmit=offsetFromEmitIndex<emitCount && stopFactor != 0.;\n#else\nbool shouldEmit=newAge>=life && stopFactor != 0.;\n#endif\nif (shouldEmit) {vec3 newPosition;vec3 newDirection;vec4 randoms=getRandomVec4(seed.x);outLife=lifeTime.x+(lifeTime.y-lifeTime.x)*randoms.r;\n#ifdef LIFETIMEGRADIENTS\noutLife=lifeTimeGradientRange.x+(lifeTimeGradientRange.y-lifeTimeGradientRange.x)*randoms.r;\n#endif\n#ifdef EMITRATECTRL\noutAge=0.0;\n#else\noutAge=newAge-life;\n#endif\noutSeed=seed;\n#ifdef SIZEGRADIENTS \nvec2 sizeGradientRange=texture(sizeGradientSampler,vec2(0,0)).rg;outSize.x=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;\n#else\noutSize.x=sizeRange.x+(sizeRange.y-sizeRange.x)*randoms.g;\n#endif\noutSize.y=scaleRange.x+(scaleRange.y-scaleRange.x)*randoms.b;outSize.z=scaleRange.z+(scaleRange.w-scaleRange.z)*randoms.a; \n#ifdef STARTSIZEGRADIENTS\noutSize.x*=startSizeGradientFactor;\n#endif\n#ifndef COLORGRADIENTS\noutColor=color1+(color2-color1)*randoms.b;\n#endif\n#ifndef ANGULARSPEEDGRADIENTS \noutAngle.y=angleRange.x+(angleRange.y-angleRange.x)*randoms.a;outAngle.x=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#else\noutAngle=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#endif \n#ifdef POINTEMITTER\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);newPosition=vec3(0,0,0);newDirection=direction1+(direction2-direction1)*randoms3;\n#elif defined(BOXEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);newPosition=minEmitBox+(maxEmitBox-minEmitBox)*randoms2;newDirection=direction1+(direction2-direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float phi=2.0*PI*randoms2.x;float theta=acos(2.0*randoms2.y-1.0);float randX=cos(phi)*sin(theta);float randY=cos(theta);float randZ=sin(phi)*sin(theta);newPosition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,abs(randY),randZ);newDirection=newPosition+directionRandomizer*randoms3; \n#elif defined(SPHEREEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float phi=2.0*PI*randoms2.x;float theta=acos(2.0*randoms2.y-1.0);float randX=cos(phi)*sin(theta);float randY=cos(theta);float randZ=sin(phi)*sin(theta);newPosition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nnewDirection=normalize(newPosition+directionRandomizer*randoms3);\n#endif\n#elif defined(CYLINDEREMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);float yPos=(randoms2.x-0.5)*height;float angle=randoms2.y*PI*2.;float inverseRadiusRangeSquared=((1.-radiusRange)*(1.-radiusRange));float positionRadius=radius*sqrt(inverseRadiusRangeSquared+(randoms2.z*(1.-inverseRadiusRangeSquared)));float xPos=positionRadius*cos(angle);float zPos=positionRadius*sin(angle);newPosition=vec3(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nangle=angle+((randoms3.x-0.5)*PI)*directionRandomizer;newDirection=vec3(cos(angle),(randoms3.y-0.5)*directionRandomizer,sin(angle));newDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);float s=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nfloat h=0.0001;\n#else\nfloat h=randoms2.y*height.y;h=1.-h*h; \n#endif\nfloat lRadius=radius.x-radius.x*randoms2.z*radius.y;lRadius=lRadius*h;float randX=lRadius*sin(s);float randZ=lRadius*cos(s);float randY=h *height.x;newPosition=vec3(randX,randY,randZ); \nvec3 randoms3=getRandomVec3(seed.z);\n#ifdef DIRECTEDCONEEMITTER\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#else\nif (abs(cos(coneAngle))==1.0) {newDirection=vec3(0.,1.0,0.);} else {newDirection=normalize(newPosition+directionRandomizer*randoms3); }\n#endif\n#elif defined(MESHEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);vec3 randoms3=getRandomVec3(seed.z);int triIdx=int(floor(randoms2.x*float(meshTriangleCount)));triIdx=min(triIdx,meshTriangleCount-1);int baseTexel=triIdx*3;int t0=baseTexel;int t1=baseTexel+1;int t2=baseTexel+2;vec3 v0=texelFetch(meshPositionSampler,ivec2(t0 % meshTextureWidth,t0/meshTextureWidth),0).xyz;vec3 v1=texelFetch(meshPositionSampler,ivec2(t1 % meshTextureWidth,t1/meshTextureWidth),0).xyz;vec3 v2=texelFetch(meshPositionSampler,ivec2(t2 % meshTextureWidth,t2/meshTextureWidth),0).xyz;float bu=randoms2.y;float bv=randoms2.z*(1.0-bu);float bw=1.0-bu-bv;newPosition=bu*v0+bv*v1+bw*v2;\n#ifdef MESHNORMALS\nvec3 n0=texelFetch(meshNormalSampler,ivec2(t0 % meshTextureWidth,t0/meshTextureWidth),0).xyz;vec3 n1=texelFetch(meshNormalSampler,ivec2(t1 % meshTextureWidth,t1/meshTextureWidth),0).xyz;vec3 n2=texelFetch(meshNormalSampler,ivec2(t2 % meshTextureWidth,t2/meshTextureWidth),0).xyz;newDirection=normalize(bu*n0+bv*n1+bw*n2);\n#else\nnewDirection=direction1+(direction2-direction1)*randoms3;\n#endif\n#elif defined(CUSTOMEMITTER)\nnewPosition=initialPosition;outInitialPosition=initialPosition;\n#else \nnewPosition=vec3(0.,0.,0.);newDirection=2.0*(getRandomVec3(seed.w)-vec3(0.5,0.5,0.5));\n#endif\nfloat power=emitPower.x+(emitPower.y-emitPower.x)*randoms.a;\n#ifdef LOCAL\noutPosition=newPosition;\n#else\noutPosition=(emitterWM*vec4(newPosition,1.)).xyz;\n#endif\n#ifdef CUSTOMEMITTER\noutDirection=direction;\n#ifndef BILLBOARD \noutInitialDirection=direction;\n#endif\n#else\n#ifdef LOCAL\nvec3 initial=newDirection;\n#else \nvec3 initial=(emitterWM*vec4(newDirection,0.)).xyz;\n#endif\noutDirection=initial*power;\n#ifndef BILLBOARD \noutInitialDirection=initial;\n#endif\n#endif\n#ifdef ANIMATESHEET \noutCellIndex=cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=randoms.a*outLife;\n#endif \n#endif\n#ifdef NOISE\noutNoiseCoordinates1=noiseCoordinates1;outNoiseCoordinates2=noiseCoordinates2;\n#endif\n} else {float directionScale=timeDelta;outAge=newAge;float ageGradient=newAge/life;\n#ifdef VELOCITYGRADIENTS\nvec2 velocityGradientRange=texture(velocityGradientSampler,vec2(ageGradient,0)).rg;directionScale*=velocityGradientRange.x+(velocityGradientRange.y-velocityGradientRange.x)*seed.w;\n#endif\n#ifdef DRAGGRADIENTS\nvec2 dragGradientRange=texture(dragGradientSampler,vec2(ageGradient,0)).rg;directionScale*=1.0-(dragGradientRange.x+(dragGradientRange.y-dragGradientRange.x)*seed.x);\n#endif\n#if defined(CUSTOMEMITTER)\noutPosition=position+(direction-position)*ageGradient; \noutInitialPosition=initialPosition;\n#else\noutPosition=position+direction*directionScale;\n#endif\noutLife=life;outSeed=seed;\n#ifndef COLORGRADIENTS \noutColor=color;\n#endif\n#ifdef SIZEGRADIENTS\nvec2 sizeGradientRange=texture(sizeGradientSampler,vec2(ageGradient,0)).rg;outSize.x=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;outSize.yz=size.yz;\n#else\noutSize=size;\n#endif \n#ifndef BILLBOARD \noutInitialDirection=initialDirection;\n#endif\n#ifdef CUSTOMEMITTER\noutDirection=direction;\n#else\nvec3 updatedDirection=direction+gravity*timeDelta;\n#ifdef FLOWMAP\nvec4 clipSpace=(flowMapProjection*vec4(position,1.));vec3 ndcSpace=clipSpace.xyz/clipSpace.w;vec2 flowMapUV=ndcSpace.xy*0.5+0.5;vec4 flowMapValue=texture(flowMapSampler,flowMapUV);vec3 flowMapDirection=(flowMapValue.xyz*2.0-1.0)*flowMapValue.w;updatedDirection+=flowMapDirection*timeDelta*flowMapStrength;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nvec2 limitVelocityRange=texture(limitVelocityGradientSampler,vec2(ageGradient,0)).rg;float limitVelocity=limitVelocityRange.x+(limitVelocityRange.y-limitVelocityRange.x)*seed.y;float currentVelocity=length(updatedDirection);if (currentVelocity>limitVelocity) {updatedDirection=updatedDirection*limitVelocityDamping;}\n#endif\n#ifdef ATTRACTORS\n{for (int i=0; i<attractorCount; i++) {vec3 toAttractor=attractorPositionAndStrength[i].xyz-outPosition;float distSq=dot(toAttractor,toAttractor)+1.0;updatedDirection+=(attractorPositionAndStrength[i].w/distSq)*normalize(toAttractor)*timeDelta;}}\n#endif\noutDirection=updatedDirection;\n#ifdef NOISE\nfloat fetchedR=texture(noiseSampler,vec2(noiseCoordinates1.x,noiseCoordinates1.y)*vec2(0.5)+vec2(0.5)).r;float fetchedG=texture(noiseSampler,vec2(noiseCoordinates1.z,noiseCoordinates2.x)*vec2(0.5)+vec2(0.5)).r;float fetchedB=texture(noiseSampler,vec2(noiseCoordinates2.y,noiseCoordinates2.z)*vec2(0.5)+vec2(0.5)).r;vec3 force=vec3(2.*fetchedR-1.,2.*fetchedG-1.,2.*fetchedB-1.)*noiseStrength;outDirection=outDirection+force*timeDelta;outNoiseCoordinates1=noiseCoordinates1;outNoiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nvec2 angularSpeedRange=texture(angularSpeedGradientSampler,vec2(ageGradient,0)).rg;float angularSpeed=angularSpeedRange.x+(angularSpeedRange.y-angularSpeedRange.x)*seed.z;outAngle=angle+angularSpeed*timeDelta;\n#else\noutAngle=vec2(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nfloat offsetAge=outAge;float dist=cellInfos.y-cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=cellStartOffset;offsetAge+=cellStartOffset;\n#else\nfloat cellStartOffset=0.;\n#endif \nfloat ratio=0.;if (cellInfos.w==1.0) {ratio=clamp(mod(cellStartOffset+cellInfos.z*offsetAge,life)/life,0.,1.0);}\nelse {ratio=clamp(cellStartOffset+cellInfos.z*offsetAge/life,0.,1.0);}\noutCellIndex=float(int(cellInfos.x+ratio*dist));\n#endif\n}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const gpuUpdateParticlesVertexShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type WebGPUEngine } from \"../Engines/webgpuEngine.pure\";\r\nimport { StorageBuffer } from \"../Buffers/storageBuffer\";\r\nimport { ComputeShader } from \"../Compute/computeShader.pure\";\r\nimport { UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { type IGPUParticleSystemPlatform } from \"./IGPUParticleSystemPlatform\";\r\nimport { type Buffer, type VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type GPUParticleSystem } from \"./gpuParticleSystem.pure\";\r\nimport { type DataArray, type Nullable } from \"../types\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { UniformBufferEffectCommonAccessor } from \"../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type ComputeBindingMapping } from \"../Engines/Extensions/engine.computeShader.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/** @internal */\r\nexport class ComputeShaderParticleSystem implements IGPUParticleSystemPlatform {\r\n    private _parent: GPUParticleSystem;\r\n    private _engine: WebGPUEngine;\r\n    private _updateComputeShader: ComputeShader;\r\n    private _simParamsComputeShader: UniformBuffer;\r\n    private _bufferComputeShader: StorageBuffer[] = [];\r\n    private _renderVertexBuffers: Array<{ [key: string]: VertexBuffer }> = [];\r\n\r\n    /** @internal */\r\n    public readonly alignDataInBuffer = true;\r\n\r\n    /** @internal */\r\n    constructor(parent: GPUParticleSystem, engine: WebGPUEngine) {\r\n        this._parent = parent;\r\n        this._engine = engine;\r\n    }\r\n\r\n    /** @internal */\r\n    public contextLost(): void {\r\n        this._updateComputeShader = undefined as any;\r\n        this._bufferComputeShader.length = 0;\r\n        this._renderVertexBuffers.length = 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public isUpdateBufferCreated(): boolean {\r\n        return !!this._updateComputeShader;\r\n    }\r\n\r\n    /** @internal */\r\n    public isUpdateBufferReady(): boolean {\r\n        return this._updateComputeShader?.isReady() ?? false;\r\n    }\r\n\r\n    /** @internal */\r\n    public createUpdateBuffer(defines: string): UniformBufferEffectCommonAccessor {\r\n        const bindingsMapping: ComputeBindingMapping = {\r\n            params: { group: 0, binding: 0 },\r\n            particlesIn: { group: 0, binding: 1 },\r\n            particlesOut: { group: 0, binding: 2 },\r\n            randomTexture: { group: 0, binding: 3 },\r\n            randomTexture2: { group: 0, binding: 4 },\r\n        };\r\n        if (this._parent._sizeGradientsTexture) {\r\n            bindingsMapping[\"sizeGradientTexture\"] = { group: 1, binding: 1 };\r\n        }\r\n        if (this._parent._angularSpeedGradientsTexture) {\r\n            bindingsMapping[\"angularSpeedGradientTexture\"] = { group: 1, binding: 3 };\r\n        }\r\n        if (this._parent._velocityGradientsTexture) {\r\n            bindingsMapping[\"velocityGradientTexture\"] = { group: 1, binding: 5 };\r\n        }\r\n        if (this._parent._limitVelocityGradientsTexture) {\r\n            bindingsMapping[\"limitVelocityGradientTexture\"] = { group: 1, binding: 7 };\r\n        }\r\n        if (this._parent._dragGradientsTexture) {\r\n            bindingsMapping[\"dragGradientTexture\"] = { group: 1, binding: 9 };\r\n        }\r\n        if (this._parent.noiseTexture) {\r\n            bindingsMapping[\"noiseTexture\"] = { group: 1, binding: 11 };\r\n        }\r\n        if (this._parent.flowMap) {\r\n            bindingsMapping[\"flowMapTexture\"] = { group: 1, binding: 13 };\r\n        }\r\n        if (this._parent._meshPositionTexture) {\r\n            bindingsMapping[\"meshPositionTexture\"] = { group: 1, binding: 14 };\r\n        }\r\n        if (this._parent._meshNormalTexture) {\r\n            bindingsMapping[\"meshNormalTexture\"] = { group: 1, binding: 15 };\r\n        }\r\n\r\n        this._updateComputeShader = new ComputeShader(\"updateParticles\", this._engine, \"gpuUpdateParticles\", {\r\n            bindingsMapping,\r\n            defines: defines.split(\"\\n\"),\r\n            useExplicitComputePipelineLayout: true,\r\n        });\r\n\r\n        this._simParamsComputeShader?.dispose();\r\n        this._simParamsComputeShader = new UniformBuffer(this._engine, undefined, undefined, \"ComputeShaderParticleSystemUBO\");\r\n\r\n        this._simParamsComputeShader.addUniform(\"currentCount\", 1);\r\n        this._simParamsComputeShader.addUniform(\"timeDelta\", 1);\r\n        this._simParamsComputeShader.addUniform(\"stopFactor\", 1);\r\n        this._simParamsComputeShader.addUniform(\"randomTextureSize\", 1);\r\n        this._simParamsComputeShader.addUniform(\"lifeTime\", 2);\r\n        this._simParamsComputeShader.addUniform(\"emitPower\", 2);\r\n        this._simParamsComputeShader.addUniform(\"emitIndex\", 1);\r\n        this._simParamsComputeShader.addUniform(\"emitCount\", 1);\r\n        if (!this._parent._colorGradientsTexture) {\r\n            this._simParamsComputeShader.addUniform(\"color1\", 4);\r\n            this._simParamsComputeShader.addUniform(\"color2\", 4);\r\n        }\r\n        this._simParamsComputeShader.addUniform(\"sizeRange\", 2);\r\n        this._simParamsComputeShader.addUniform(\"scaleRange\", 4);\r\n        this._simParamsComputeShader.addUniform(\"angleRange\", 4);\r\n        this._simParamsComputeShader.addUniform(\"gravity\", 3);\r\n        if (this._parent._limitVelocityGradientsTexture) {\r\n            this._simParamsComputeShader.addUniform(\"limitVelocityDamping\", 1);\r\n        }\r\n        if (this._parent.isAnimationSheetEnabled) {\r\n            this._simParamsComputeShader.addUniform(\"cellInfos\", 4);\r\n        }\r\n        if (this._parent.noiseTexture) {\r\n            this._simParamsComputeShader.addUniform(\"noiseStrength\", 3);\r\n        }\r\n        if (this._parent.flowMap) {\r\n            this._simParamsComputeShader.addUniform(\"flowMapProjection\", 16);\r\n            this._simParamsComputeShader.addUniform(\"flowMapStrength\", 1);\r\n        }\r\n        if (!this._parent.isLocal) {\r\n            this._simParamsComputeShader.addUniform(\"emitterWM\", 16);\r\n        }\r\n        if (this._parent.attractors.length > 0) {\r\n            this._simParamsComputeShader.addUniform(\"attractorCount\", 1);\r\n            for (let i = 0; i < this._parent.maxAttractors; i++) {\r\n                this._simParamsComputeShader.addUniform(\"attractorPositionAndStrength[\" + i + \"]\", 4);\r\n            }\r\n        }\r\n        if (this._parent._startSizeGradients && this._parent._startSizeGradients.length > 0) {\r\n            this._simParamsComputeShader.addUniform(\"startSizeGradientFactor\", 1);\r\n        }\r\n        if (this._parent._lifeTimeGradients && this._parent._lifeTimeGradients.length > 0) {\r\n            this._simParamsComputeShader.addUniform(\"lifeTimeGradientRange\", 2);\r\n        }\r\n        if (this._parent._meshPositionTexture) {\r\n            this._simParamsComputeShader.addUniform(\"meshTriangleCount\", 1);\r\n            this._simParamsComputeShader.addUniform(\"meshTextureWidth\", 1);\r\n        }\r\n        if (this._parent.particleEmitterType) {\r\n            this._parent.particleEmitterType.buildUniformLayout(this._simParamsComputeShader);\r\n        }\r\n\r\n        this._updateComputeShader.setUniformBuffer(\"params\", this._simParamsComputeShader);\r\n\r\n        return new UniformBufferEffectCommonAccessor(this._simParamsComputeShader);\r\n    }\r\n\r\n    /** @internal */\r\n    public createVertexBuffers(updateBuffer: Buffer, renderVertexBuffers: { [key: string]: VertexBuffer }): void {\r\n        this._renderVertexBuffers.push(renderVertexBuffers);\r\n    }\r\n\r\n    /** @internal */\r\n    public createParticleBuffer(data: number[]): DataArray | DataBuffer {\r\n        const buffer = new StorageBuffer(\r\n            this._engine,\r\n            data.length * 4,\r\n            Constants.BUFFER_CREATIONFLAG_READWRITE | Constants.BUFFER_CREATIONFLAG_VERTEX,\r\n            \"ComputeShaderParticleSystemBuffer\"\r\n        );\r\n\r\n        buffer.update(data);\r\n        this._bufferComputeShader.push(buffer);\r\n\r\n        return buffer.getBuffer();\r\n    }\r\n\r\n    /** @internal */\r\n    public bindDrawBuffers(index: number, effect: Effect, indexBuffer: Nullable<DataBuffer>): void {\r\n        this._engine.bindBuffers(this._renderVertexBuffers[index], indexBuffer, effect);\r\n    }\r\n\r\n    /** @internal */\r\n    public preUpdateParticleBuffer(): void {}\r\n\r\n    /** @internal */\r\n    public updateParticleBuffer(index: number, targetBuffer: Buffer, currentActiveCount: number): void {\r\n        this._simParamsComputeShader.update();\r\n\r\n        this._updateComputeShader.setTexture(\"randomTexture\", this._parent._randomTexture, false);\r\n        this._updateComputeShader.setTexture(\"randomTexture2\", this._parent._randomTexture2, false);\r\n        if (this._parent._sizeGradientsTexture) {\r\n            this._updateComputeShader.setTexture(\"sizeGradientTexture\", this._parent._sizeGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._angularSpeedGradientsTexture) {\r\n            this._updateComputeShader.setTexture(\"angularSpeedGradientTexture\", this._parent._angularSpeedGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._velocityGradientsTexture) {\r\n            this._updateComputeShader.setTexture(\"velocityGradientTexture\", this._parent._velocityGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._limitVelocityGradientsTexture) {\r\n            this._updateComputeShader.setTexture(\"limitVelocityGradientTexture\", this._parent._limitVelocityGradientsTexture);\r\n        }\r\n\r\n        if (this._parent._dragGradientsTexture) {\r\n            this._updateComputeShader.setTexture(\"dragGradientTexture\", this._parent._dragGradientsTexture);\r\n        }\r\n\r\n        if (this._parent.noiseTexture) {\r\n            this._updateComputeShader.setTexture(\"noiseTexture\", this._parent.noiseTexture);\r\n        }\r\n\r\n        if (this._parent.flowMap) {\r\n            this._updateComputeShader.setTexture(\"flowMapTexture\", this._parent.flowMap);\r\n        }\r\n\r\n        if (this._parent._meshPositionTexture) {\r\n            this._updateComputeShader.setTexture(\"meshPositionTexture\", this._parent._meshPositionTexture, false);\r\n        }\r\n\r\n        if (this._parent._meshNormalTexture) {\r\n            this._updateComputeShader.setTexture(\"meshNormalTexture\", this._parent._meshNormalTexture, false);\r\n        }\r\n\r\n        this._updateComputeShader.setStorageBuffer(\"particlesIn\", this._bufferComputeShader[index]);\r\n        this._updateComputeShader.setStorageBuffer(\"particlesOut\", this._bufferComputeShader[index ^ 1]);\r\n\r\n        this._updateComputeShader.dispatch(Math.ceil(currentActiveCount / 64));\r\n    }\r\n\r\n    /** @internal */\r\n    public releaseBuffers(): void {\r\n        for (let i = 0; i < this._bufferComputeShader.length; ++i) {\r\n            this._bufferComputeShader[i].dispose();\r\n        }\r\n\r\n        this._bufferComputeShader.length = 0;\r\n\r\n        this._simParamsComputeShader?.dispose();\r\n        (<any>this._simParamsComputeShader) = null;\r\n\r\n        (<any>this._updateComputeShader) = null;\r\n    }\r\n\r\n    /** @internal */\r\n    public releaseVertexBuffers(): void {\r\n        this._renderVertexBuffers.length = 0;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for computeShaderParticleSystem.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterComputeShaderParticleSystem(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ComputeShaderParticleSystem\", ComputeShaderParticleSystem);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gpuUpdateParticlesComputeShader\";\nconst shader = `struct Particle {position : vec3<f32>,\nage : f32,\nsize : vec3<f32>,\nlife : f32,\nseed : vec4<f32>,\ndirection : vec3<f32>,\ndummy0: f32,\n#ifdef CUSTOMEMITTER\ninitialPosition : vec3<f32>,\ndummy1: f32,\n#endif\n#ifndef COLORGRADIENTS\ncolor : vec4<f32>,\n#endif\n#ifndef BILLBOARD\ninitialDirection : vec3<f32>,\ndummy2: f32,\n#endif\n#ifdef NOISE\nnoiseCoordinates1 : vec3<f32>,\ndummy3: f32,\nnoiseCoordinates2 : vec3<f32>,\ndummy4: f32,\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nangle : f32,\n#else\nangle : vec2<f32>,\n#endif\n#ifdef ANIMATESHEET\ncellIndex : f32,\n#ifdef ANIMATESHEETRANDOMSTART\ncellStartOffset : f32,\n#endif\n#endif\n};struct Particles {particles : array<Particle>,};struct SimParams {currentCount : f32,\ntimeDelta : f32,\nstopFactor : f32,\nrandomTextureSize: i32,\nlifeTime : vec2<f32>,\nemitPower : vec2<f32>,\nemitIndex : f32,\nemitCount : f32,\n#ifndef COLORGRADIENTS\ncolor1 : vec4<f32>,\ncolor2 : vec4<f32>,\n#endif\nsizeRange : vec2<f32>,\nscaleRange : vec4<f32>,\nangleRange : vec4<f32>,\ngravity : vec3<f32>,\n#ifdef LIMITVELOCITYGRADIENTS\nlimitVelocityDamping : f32,\n#endif\n#ifdef ANIMATESHEET\ncellInfos : vec4<f32>,\n#endif\n#ifdef NOISE\nnoiseStrength : vec3<f32>,\n#endif\n#ifdef FLOWMAP\nflowMapProjection : mat4x4<f32>,\nflowMapStrength : f32,\n#endif\n#ifndef LOCAL\nemitterWM : mat4x4<f32>,\n#endif\n#ifdef ATTRACTORS\nattractorCount : i32,\nattractorPositionAndStrength : array<vec4<f32>,MAX_ATTRACTORS>,\n#endif\n#ifdef STARTSIZEGRADIENTS\nstartSizeGradientFactor : f32,\n#endif\n#ifdef LIFETIMEGRADIENTS\nlifeTimeGradientRange : vec2<f32>,\n#endif\n#ifdef MESHEMITTER\nmeshTriangleCount : i32,\nmeshTextureWidth : i32,\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#endif\n#ifdef BOXEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\nminEmitBox : vec3<f32>,\nmaxEmitBox : vec3<f32>,\n#endif\n#ifdef CONEEMITTER\nradius : vec2<f32>,\nconeAngle : f32,\nheight : vec2<f32>,\n#ifdef DIRECTEDCONEEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nradius : f32,\nheight : f32,\nradiusRange : f32,\n#ifdef DIRECTEDCYLINDEREMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n#ifdef HEMISPHERICEMITTER\nradius : f32,\nradiusRange : f32,\ndirectionRandomizer : f32,\n#endif\n#ifdef POINTEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#endif\n#ifdef SPHEREEMITTER\nradius : f32,\nradiusRange : f32,\n#ifdef DIRECTEDSPHEREEMITTER\ndirection1 : vec3<f32>,\ndirection2 : vec3<f32>,\n#else\ndirectionRandomizer : f32,\n#endif\n#endif\n};@binding(0) @group(0) var<uniform> params : SimParams;@binding(1) @group(0) var<storage,read> particlesIn : Particles;@binding(2) @group(0) var<storage,read_write> particlesOut : Particles;@binding(3) @group(0) var randomTexture : texture_2d<f32>;@binding(4) @group(0) var randomTexture2 : texture_2d<f32>;\n#ifdef SIZEGRADIENTS\n@binding(0) @group(1) var sizeGradientSampler : sampler;@binding(1) @group(1) var sizeGradientTexture : texture_2d<f32>;\n#endif \n#ifdef ANGULARSPEEDGRADIENTS\n@binding(2) @group(1) var angularSpeedGradientSampler : sampler;@binding(3) @group(1) var angularSpeedGradientTexture : texture_2d<f32>;\n#endif \n#ifdef VELOCITYGRADIENTS\n@binding(4) @group(1) var velocityGradientSampler : sampler;@binding(5) @group(1) var velocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\n@binding(6) @group(1) var limitVelocityGradientSampler : sampler;@binding(7) @group(1) var limitVelocityGradientTexture : texture_2d<f32>;\n#endif\n#ifdef DRAGGRADIENTS\n@binding(8) @group(1) var dragGradientSampler : sampler;@binding(9) @group(1) var dragGradientTexture : texture_2d<f32>;\n#endif\n#ifdef NOISE\n@binding(10) @group(1) var noiseSampler : sampler;@binding(11) @group(1) var noiseTexture : texture_2d<f32>;\n#endif\n#ifdef FLOWMAP\n@binding(12) @group(1) var flowMapSampler : sampler;@binding(13) @group(1) var flowMapTexture : texture_2d<f32>;\n#endif\n#ifdef MESHEMITTER\n@binding(14) @group(1) var meshPositionTexture : texture_2d<f32>;\n#ifdef MESHNORMALS\n@binding(15) @group(1) var meshNormalTexture : texture_2d<f32>;\n#endif\n#endif\nfn getRandomVec3(offset : f32,vertexID : f32)->vec3<f32> {return textureLoad(randomTexture2,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0).rgb;}\nfn getRandomVec4(offset : f32,vertexID : f32)->vec4<f32> {return textureLoad(randomTexture,vec2<i32>(i32(vertexID*offset/params.currentCount*f32(params.randomTextureSize)) % params.randomTextureSize,0),0);}\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {let index : u32=GlobalInvocationID.x;let vertexID : f32=f32(index);if (index>=u32(params.currentCount)) {return;}\nlet PI : f32=3.14159;let timeDelta : f32=params.timeDelta;let newAge : f32=particlesIn.particles[index].age+timeDelta;let life : f32=particlesIn.particles[index].life;let seed : vec4<f32>=particlesIn.particles[index].seed;let direction : vec3<f32>=particlesIn.particles[index].direction;\n#ifdef EMITRATECTRL\nvar offsetFromEmitIndex : f32=vertexID-params.emitIndex;if (offsetFromEmitIndex<0.0) {offsetFromEmitIndex+=params.currentCount; }\nlet shouldEmit : bool=offsetFromEmitIndex<params.emitCount && params.stopFactor != 0.;\n#else\nlet shouldEmit : bool=newAge>=life && params.stopFactor != 0.;\n#endif\nif (shouldEmit) {var newPosition : vec3<f32>;var newDirection : vec3<f32>;let randoms : vec4<f32>=getRandomVec4(seed.x,vertexID);let outLife : f32=params.lifeTime.x+(params.lifeTime.y-params.lifeTime.x)*randoms.r;\n#ifdef LIFETIMEGRADIENTS\nparticlesOut.particles[index].life=params.lifeTimeGradientRange.x+(params.lifeTimeGradientRange.y-params.lifeTimeGradientRange.x)*randoms.r;\n#else\nparticlesOut.particles[index].life=outLife;\n#endif\n#ifdef EMITRATECTRL\nparticlesOut.particles[index].age=0.0;\n#else\nparticlesOut.particles[index].age=newAge-life;\n#endif\nparticlesOut.particles[index].seed=seed;var sizex : f32;\n#ifdef SIZEGRADIENTS \nlet sizeGradientRange=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(0.,0.),0.).rg;sizex=sizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y;\n#else\nsizex=params.sizeRange.x+(params.sizeRange.y-params.sizeRange.x)*randoms.g;\n#endif\n#ifdef STARTSIZEGRADIENTS\nsizex*=params.startSizeGradientFactor;\n#endif\nparticlesOut.particles[index].size=vec3<f32>(\nsizex,\nparams.scaleRange.x+(params.scaleRange.y-params.scaleRange.x)*randoms.b,\nparams.scaleRange.z+(params.scaleRange.w-params.scaleRange.z)*randoms.a);\n#ifndef COLORGRADIENTS\nparticlesOut.particles[index].color=params.color1+(params.color2-params.color1)*randoms.b;\n#endif\n#ifndef ANGULARSPEEDGRADIENTS \nparticlesOut.particles[index].angle=vec2<f32>(\nparams.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r,\nparams.angleRange.x+(params.angleRange.y-params.angleRange.x)*randoms.a);\n#else\nparticlesOut.particles[index].angle=params.angleRange.z+(params.angleRange.w-params.angleRange.z)*randoms.r;\n#endif \n#if defined(POINTEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);newPosition=vec3<f32>(0.,0.,0.);newDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#elif defined(BOXEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);newPosition=params.minEmitBox+(params.maxEmitBox-params.minEmitBox)*randoms2;newDirection=params.direction1+(params.direction2-params.direction1)*randoms3; \n#elif defined(HEMISPHERICEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let phi : f32=2.0*PI*randoms2.x;let theta : f32=acos(-1.0+2.0*randoms2.y);let randX : f32=cos(phi)*sin(theta);let randY : f32=cos(theta);let randZ : f32=sin(phi)*sin(theta);newPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,abs(randY),randZ);newDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#elif defined(SPHEREEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let phi : f32=2.0*PI*randoms2.x;let theta : f32=acos(-1.0+2.0*randoms2.y);let randX : f32=cos(phi)*sin(theta);let randY : f32=cos(theta);let randZ : f32=sin(phi)*sin(theta);newPosition=(params.radius-(params.radius*params.radiusRange*randoms2.z))*vec3<f32>(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nnewDirection=normalize(newPosition+params.directionRandomizer*randoms3);\n#endif\n#elif defined(CYLINDEREMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);let yPos : f32=(-0.5+randoms2.x)*params.height;var angle : f32=randoms2.y*PI*2.;let inverseRadiusRangeSquared : f32=(1.-params.radiusRange)*(1.-params.radiusRange);let positionRadius : f32=params.radius*sqrt(inverseRadiusRangeSquared+randoms2.z*(1.-inverseRadiusRangeSquared));let xPos : f32=positionRadius*cos(angle);let zPos : f32=positionRadius*sin(angle);newPosition=vec3<f32>(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nangle=angle+(-0.5+randoms3.x)*PI*params.directionRandomizer;newDirection=vec3<f32>(cos(angle),(-0.5+randoms3.y)*params.directionRandomizer,sin(angle));newDirection=normalize(newDirection);\n#endif\n#elif defined(CONEEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let s : f32=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nlet h : f32=0.0001;\n#else\nvar h : f32=randoms2.y*params.height.y;h=1.-h*h; \n#endif\nvar lRadius : f32=params.radius.x-params.radius.x*randoms2.z*params.radius.y;lRadius=lRadius*h;let randX : f32=lRadius*sin(s);let randZ : f32=lRadius*cos(s);let randY : f32=h *params.height.x;newPosition=vec3<f32>(randX,randY,randZ); \nlet randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);\n#ifdef DIRECTEDCONEEMITTER\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#else\nif (abs(cos(params.coneAngle))==1.0) {newDirection=vec3<f32>(0.,1.0,0.);} else {newDirection=normalize(newPosition+params.directionRandomizer*randoms3); }\n#endif\n#elif defined(MESHEMITTER)\nlet randoms2 : vec3<f32>=getRandomVec3(seed.y,vertexID);let randoms3 : vec3<f32>=getRandomVec3(seed.z,vertexID);var triIdx : i32=i32(floor(randoms2.x*f32(params.meshTriangleCount)));triIdx=min(triIdx,params.meshTriangleCount-1);let baseTexel : i32=triIdx*3;let t0 : i32=baseTexel;let t1 : i32=baseTexel+1;let t2 : i32=baseTexel+2;let v0 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t0 % params.meshTextureWidth,t0/params.meshTextureWidth),0).xyz;let v1 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t1 % params.meshTextureWidth,t1/params.meshTextureWidth),0).xyz;let v2 : vec3<f32>=textureLoad(meshPositionTexture,vec2<i32>(t2 % params.meshTextureWidth,t2/params.meshTextureWidth),0).xyz;let bu : f32=randoms2.y;let bv : f32=randoms2.z*(1.0-bu);let bw : f32=1.0-bu-bv;newPosition=bu*v0+bv*v1+bw*v2;\n#ifdef MESHNORMALS\nlet n0 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t0 % params.meshTextureWidth,t0/params.meshTextureWidth),0).xyz;let n1 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t1 % params.meshTextureWidth,t1/params.meshTextureWidth),0).xyz;let n2 : vec3<f32>=textureLoad(meshNormalTexture,vec2<i32>(t2 % params.meshTextureWidth,t2/params.meshTextureWidth),0).xyz;newDirection=normalize(bu*n0+bv*n1+bw*n2);\n#else\nnewDirection=params.direction1+(params.direction2-params.direction1)*randoms3;\n#endif\n#elif defined(CUSTOMEMITTER)\nnewPosition=particlesIn.particles[index].initialPosition;particlesOut.particles[index].initialPosition=newPosition;\n#else \nnewPosition=vec3<f32>(0.,0.,0.);newDirection=2.0*(getRandomVec3(seed.w,vertexID)-vec3<f32>(0.5,0.5,0.5));\n#endif\nlet power : f32=params.emitPower.x+(params.emitPower.y-params.emitPower.x)*randoms.a;\n#ifdef LOCAL\nparticlesOut.particles[index].position=newPosition;\n#else\nparticlesOut.particles[index].position=(params.emitterWM*vec4<f32>(newPosition,1.)).xyz;\n#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=direction;\n#endif\n#else\n#ifdef LOCAL\nlet initial : vec3<f32>=newDirection;\n#else \nlet initial : vec3<f32>=(params.emitterWM*vec4<f32>(newDirection,0.)).xyz;\n#endif\nparticlesOut.particles[index].direction=initial*power;\n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=initial;\n#endif\n#endif\n#ifdef ANIMATESHEET \nparticlesOut.particles[index].cellIndex=params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nparticlesOut.particles[index].cellStartOffset=randoms.a*outLife;\n#endif \n#endif\n#ifdef NOISE\nparticlesOut.particles[index].noiseCoordinates1=particlesIn.particles[index].noiseCoordinates1;particlesOut.particles[index].noiseCoordinates2=particlesIn.particles[index].noiseCoordinates2;\n#endif\n} else {var directionScale : f32=timeDelta;particlesOut.particles[index].age=newAge;let ageGradient : f32=newAge/life;\n#ifdef VELOCITYGRADIENTS\nlet velocityGradientRange=textureSampleLevel(velocityGradientTexture,velocityGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;directionScale=directionScale*(velocityGradientRange.x+(velocityGradientRange.y-velocityGradientRange.x)*seed.w);\n#endif\n#ifdef DRAGGRADIENTS\nlet dragGradientRange=textureSampleLevel(dragGradientTexture,dragGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;directionScale=directionScale*(1.0-(dragGradientRange.x+(dragGradientRange.y-dragGradientRange.x)*seed.x));\n#endif\nlet position : vec3<f32>=particlesIn.particles[index].position;\n#if defined(CUSTOMEMITTER)\nparticlesOut.particles[index].position=position+(direction-position)*ageGradient; \nparticlesOut.particles[index].initialPosition=particlesIn.particles[index].initialPosition;\n#else\nparticlesOut.particles[index].position=position+direction*directionScale;\n#endif\nparticlesOut.particles[index].life=life;particlesOut.particles[index].seed=seed;\n#ifndef COLORGRADIENTS \nparticlesOut.particles[index].color=particlesIn.particles[index].color;\n#endif\n#ifdef SIZEGRADIENTS\nlet sizeGradientRange=textureSampleLevel(sizeGradientTexture,sizeGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;particlesOut.particles[index].size=vec3<f32>(\nsizeGradientRange.x+(sizeGradientRange.y-sizeGradientRange.x)*seed.y,\nparticlesIn.particles[index].size.yz);\n#else\nparticlesOut.particles[index].size=particlesIn.particles[index].size;\n#endif \n#ifndef BILLBOARD \nparticlesOut.particles[index].initialDirection=particlesIn.particles[index].initialDirection;\n#endif\n#ifdef CUSTOMEMITTER\nparticlesOut.particles[index].direction=direction;\n#else\nvar updatedDirection : vec3<f32>=direction+params.gravity*timeDelta;\n#ifdef FLOWMAP\nvar clipSpace=(params.flowMapProjection*vec4f(position,1.));var ndcSpace=clipSpace.xyz/clipSpace.w;var flowMapUV=ndcSpace.xy*0.5+0.5;var flowMapValue=textureSampleLevel(flowMapTexture,flowMapSampler,flowMapUV,0.);var flowMapDirection=(flowMapValue.xyz*2.0-1.0)*flowMapValue.w;updatedDirection+=flowMapDirection*timeDelta*params.flowMapStrength;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nlet limitVelocityRange=textureSampleLevel(limitVelocityGradientTexture,limitVelocityGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;let limitVelocity : f32=limitVelocityRange.x+(limitVelocityRange.y-limitVelocityRange.x)*seed.y;let currentVelocity : f32=length(updatedDirection);if (currentVelocity>limitVelocity) {updatedDirection=updatedDirection*params.limitVelocityDamping;}\n#endif\n#ifdef ATTRACTORS\n{for (var i : i32=0; i<params.attractorCount; i=i+1) {let toAttractor : vec3<f32>=params.attractorPositionAndStrength[i].xyz-position;let distSq : f32=dot(toAttractor,toAttractor)+1.0;updatedDirection=updatedDirection+(params.attractorPositionAndStrength[i].w/distSq)*normalize(toAttractor)*timeDelta;}}\n#endif\nparticlesOut.particles[index].direction=updatedDirection;\n#ifdef NOISE\nlet noiseCoordinates1 : vec3<f32>=particlesIn.particles[index].noiseCoordinates1;let noiseCoordinates2 : vec3<f32>=particlesIn.particles[index].noiseCoordinates2;let fetchedR : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates1.x,noiseCoordinates1.y)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let fetchedG : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates1.z,noiseCoordinates2.x)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let fetchedB : f32=textureSampleLevel(noiseTexture,noiseSampler,vec2<f32>(noiseCoordinates2.y,noiseCoordinates2.z)*vec2<f32>(0.5,0.5)+vec2<f32>(0.5,0.5),0.).r;let force : vec3<f32>=vec3<f32>(-1.+2.*fetchedR,-1.+2.*fetchedG,-1.+2.*fetchedB)*params.noiseStrength;particlesOut.particles[index].direction=particlesOut.particles[index].direction+force*timeDelta;particlesOut.particles[index].noiseCoordinates1=noiseCoordinates1;particlesOut.particles[index].noiseCoordinates2=noiseCoordinates2;\n#endif \n#endif \n#ifdef ANGULARSPEEDGRADIENTS\nlet angularSpeedRange=textureSampleLevel(angularSpeedGradientTexture,angularSpeedGradientSampler,vec2<f32>(ageGradient,0.),0.).rg;let angularSpeed : f32=angularSpeedRange.x+(angularSpeedRange.y-angularSpeedRange.x)*seed.z;particlesOut.particles[index].angle=particlesIn.particles[index].angle+angularSpeed*timeDelta;\n#else\nlet angle : vec2<f32>=particlesIn.particles[index].angle;particlesOut.particles[index].angle=vec2<f32>(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET \nvar offsetAge : f32=particlesOut.particles[index].age;let dist : f32=params.cellInfos.y-params.cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\nlet cellStartOffset : f32=particlesIn.particles[index].cellStartOffset;particlesOut.particles[index].cellStartOffset=cellStartOffset;offsetAge=offsetAge+cellStartOffset;\n#else\nlet cellStartOffset : f32=0.;\n#endif \nvar ratio : f32;if (params.cellInfos.w==1.0) {ratio=clamp(((cellStartOffset+params.cellInfos.z*offsetAge) % life)/life,0.,1.0);}\nelse {ratio=clamp((cellStartOffset+params.cellInfos.z*offsetAge)/life,0.,1.0);}\nparticlesOut.particles[index].cellIndex=f32(i32(params.cellInfos.x+ratio*dist));\n#endif\n}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const gpuUpdateParticlesComputeShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Immutable, type Nullable, type float, type DataArray } from \"../types\";\r\nimport { type Color3Gradient, type IValueGradient, type FactorGradient, ColorGradient, GradientHelper } from \"../Misc/gradients\";\r\nimport { Observable, type Observer } from \"../Misc/observable.pure\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { Color4, TmpColors } from \"../Maths/math.color.pure\";\r\nimport { Lerp } from \"../Maths/math.scalar.functions\";\r\nimport { VertexBuffer, Buffer } from \"../Buffers/buffer.pure\";\r\n\r\nimport { type IParticleSystem } from \"./IParticleSystem\";\r\nimport { BaseParticleSystem } from \"./baseParticleSystem.pure\";\r\nimport { ParticleSystem } from \"./particleSystem.pure\";\r\nimport { Attractor } from \"./attractor\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { BoxParticleEmitter } from \"../Particles/EmitterTypes/boxParticleEmitter\";\r\nimport { type IDisposable, Scene } from \"../scene.pure\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../Materials/effect.pure\";\r\nimport { ImageProcessingConfiguration } from \"../Materials/imageProcessingConfiguration.pure\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { RegisterAnimatable } from \"../Animations/animatable.pure\";\r\nimport { CustomParticleEmitter } from \"./EmitterTypes/customParticleEmitter\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\nimport { type UniformBufferEffectCommonAccessor } from \"../Materials/uniformBufferEffectCommonAccessor\";\r\nimport { type IGPUParticleSystemPlatform } from \"./IGPUParticleSystemPlatform\";\r\nimport { GetClass } from \"../Misc/typeStore\";\r\nimport { _IsSideEffectImplemented } from \"../Misc/devTools\";\r\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"../Materials/clipPlaneMaterialHelper\";\r\n\r\nimport { type Engine } from \"../Engines/engine.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\n\r\nimport { BindFogParameters, BindLogDepth } from \"../Materials/materialHelper.functions\";\r\nimport { MeshParticleEmitter } from \"./EmitterTypes/meshParticleEmitter\";\r\nimport { type Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { MaterialHelperGeometryRendering } from \"../Materials/materialHelper.geometryrendering\";\r\n\r\n/**\r\n * This represents a GPU particle system in Babylon\r\n * This is the fastest particle system in Babylon as it uses the GPU to update the individual particle data\r\n * @see https://www.babylonjs-playground.com/#PU4WYI#4\r\n */\r\nexport class GPUParticleSystem extends BaseParticleSystem implements IDisposable, IParticleSystem, IAnimatable {\r\n    /**\r\n     * The layer mask we are rendering the particles through.\r\n     */\r\n    public override layerMask: number = 0x0fffffff;\r\n\r\n    private _capacity: number;\r\n    private _maxActiveParticleCount: number;\r\n    private _currentActiveCount: number;\r\n    private _accumulatedCount = 0;\r\n    private _writePointer = 0;\r\n    private _emitIndex = 0;\r\n    private _emitCount = 0;\r\n    private _updateBuffer: UniformBufferEffectCommonAccessor;\r\n\r\n    private _buffer0: Buffer;\r\n    private _buffer1: Buffer;\r\n    private _spriteBuffer: Buffer;\r\n    private _renderVertexBuffers: Array<{ [key: string]: VertexBuffer }> = [];\r\n    private _linesIndexBufferUseInstancing: Nullable<DataBuffer>;\r\n\r\n    private _targetIndex = 0;\r\n    private _sourceBuffer: Buffer;\r\n    private _targetBuffer: Buffer;\r\n\r\n    /** Set to true when any entry in `_colorGradients` has a `color2` (per-particle random color range). */\r\n    private _hasColorGradientColor2 = false;\r\n\r\n    private _currentRenderId = -1;\r\n    private _currentRenderingCameraUniqueId = -1;\r\n    private _started = false;\r\n    private _stopped = false;\r\n\r\n    private _timeDelta = 0;\r\n\r\n    /** @internal */\r\n    public _randomTexture: RawTexture;\r\n    /** @internal */\r\n    public _randomTexture2: RawTexture;\r\n\r\n    /** Indicates that the update of particles is done in the animate function (and not in render). Default: false */\r\n    public updateInAnimate = false;\r\n\r\n    private _attributesStrideSize: number;\r\n    private _cachedUpdateDefines: string;\r\n\r\n    private _randomTextureSize: number;\r\n    private _actualFrame = 0;\r\n    private _drawWrappers: DrawWrapper[][]; // first index is render pass id, second index is blend mode\r\n    private _renderPassObserver: Nullable<Observer<number>> = null;\r\n    private _customWrappers: { [blendMode: number]: Nullable<DrawWrapper> };\r\n    private _renderShadersLoaded = false;\r\n\r\n    private readonly _rawTextureWidth = 256;\r\n\r\n    private _platform: IGPUParticleSystemPlatform;\r\n    private _rebuildingAfterContextLost = false;\r\n\r\n    /**\r\n     * Whether the particle buffer needs to store the initial emission direction.\r\n     * True when particles are not billboarded (they orient by direction) or when\r\n     * using stretched-local billboard mode (stretches along initial direction).\r\n     * @internal\r\n     */\r\n    public get _needsInitialDirection(): boolean {\r\n        return !this._isBillboardBased || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL;\r\n    }\r\n\r\n    // Emit rate gradient caching (mirrors ThinParticleSystem)\r\n    private _currentEmitRateGradient: Nullable<FactorGradient> = null;\r\n    private _currentEmitRate1: number = 0;\r\n    private _currentEmitRate2: number = 0;\r\n\r\n    // Start size gradient caching (mirrors ThinParticleSystem)\r\n    private _currentStartSizeGradient: Nullable<FactorGradient> = null;\r\n    private _currentStartSize1: number = 0;\r\n    private _currentStartSize2: number = 0;\r\n    private _startSizeGradientFactor: number = 1.0;\r\n\r\n    // Life time gradient factor range for per-particle randomization in shader\r\n    private _lifeTimeGradientMin: number = 1.0;\r\n    private _lifeTimeGradientMax: number = 1.0;\r\n\r\n    /**\r\n     * Specifies if the particle system should be serialized\r\n     */\r\n    public doNotSerialize = false;\r\n\r\n    /**\r\n     * Gets a boolean indicating if the GPU particles can be rendered on current browser\r\n     */\r\n    public static get IsSupported(): boolean {\r\n        if (!EngineStore.LastCreatedEngine) {\r\n            return false;\r\n        }\r\n        const caps = EngineStore.LastCreatedEngine.getCaps();\r\n\r\n        return caps.supportTransformFeedbacks || caps.supportComputeShaders;\r\n    }\r\n\r\n    /**\r\n     * An event triggered when the system is disposed.\r\n     */\r\n    public onDisposeObservable = new Observable<IParticleSystem>();\r\n    /**\r\n     * An event triggered when the system is stopped\r\n     */\r\n    public onStoppedObservable = new Observable<IParticleSystem>();\r\n\r\n    /**\r\n     * An event triggered when the system is started\r\n     */\r\n    public onStartedObservable = new Observable<IParticleSystem>();\r\n\r\n    private _createIndexBuffer() {\r\n        this._linesIndexBufferUseInstancing = this._engine.createIndexBuffer(new Uint32Array([0, 1, 1, 3, 3, 2, 2, 0, 0, 3]), undefined, \"GPUParticleSystemLinesIndexBuffer\");\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum number of particles active at the same time.\r\n     * @returns The max number of active particles.\r\n     */\r\n    public getCapacity(): number {\r\n        return this._capacity;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets whether emit rate control is enabled.\r\n     * When true, the GPU particle system limits the number of active particles\r\n     * to approximately emitRate * maxLifeTime (matching CPU particle behavior)\r\n     * and uses a circular buffer to recycle particle slots.\r\n     * When false (default), all dead particles are recycled immediately,\r\n     * which is the legacy GPU particle behavior.\r\n     * Changing the value takes effect on the next frame (the update and render effects are rebuilt\r\n     * automatically when their shader defines change; buffer allocation does not depend on it).\r\n     */\r\n    public emitRateControl = false;\r\n\r\n    /**\r\n     * Forces the particle to write their depth information to the depth buffer. This can help preventing other draw calls\r\n     * to override the particles.\r\n     */\r\n    public override forceDepthWrite = false;\r\n\r\n    /**\r\n     * Gets or set the number of active particles\r\n     * The value cannot be greater than \"capacity\" (if it is, it will be limited to \"capacity\").\r\n     */\r\n    public get maxActiveParticleCount(): number {\r\n        return this._maxActiveParticleCount;\r\n    }\r\n\r\n    public set maxActiveParticleCount(value: number) {\r\n        this._maxActiveParticleCount = Math.min(value, this._capacity);\r\n    }\r\n\r\n    /**\r\n     * Gets or set the number of active particles\r\n     * @deprecated Please use maxActiveParticleCount instead.\r\n     */\r\n    public get activeParticleCount(): number {\r\n        return this.maxActiveParticleCount;\r\n    }\r\n\r\n    public set activeParticleCount(value: number) {\r\n        this.maxActiveParticleCount = value;\r\n    }\r\n\r\n    private _preWarmDone = false;\r\n\r\n    /**\r\n     * Specifies if the particles are updated in emitter local space or world space.\r\n     */\r\n    public isLocal = false;\r\n\r\n    /** Indicates that the particle system is GPU based */\r\n    public readonly isGPU = true;\r\n\r\n    /** Attractors */\r\n    /**\r\n     * Maximum number of attractors for this GPU particle system instance.\r\n     * Determined at construction time via the `maxAttractors` option (default 8).\r\n     * Limited by the fixed-size uniform arrays in the update shaders.\r\n     */\r\n    public readonly maxAttractors: number;\r\n\r\n    /**\r\n     * Add an attractor to the particle system. Attractors are used to change the direction of the particles in the system.\r\n     * @param attractor - The attractor to add to the particle system\r\n     */\r\n    public override addAttractor(attractor: Attractor): void {\r\n        if (this._attractors.length >= this.maxAttractors) {\r\n            Logger.Warn(`GPU particle system supports a maximum of ${this.maxAttractors} attractors. Ignoring additional attractor.`);\r\n            return;\r\n        }\r\n        super.addAttractor(attractor);\r\n    }\r\n\r\n    /** Gets or sets a matrix to use to compute projection */\r\n    public defaultProjectionMatrix: Matrix;\r\n\r\n    /**\r\n     * Gets or sets an object used to store user defined information for the particle system\r\n     */\r\n    public metadata: any = null;\r\n\r\n    /** Flow map */\r\n\r\n    /** @internal */\r\n    public _flowMap: Nullable<Texture> = null;\r\n\r\n    /**\r\n     * The strength of the flow map\r\n     */\r\n    public flowMapStrength = 1.0;\r\n\r\n    /** Gets or sets the current flow map */\r\n    public get flowMap(): Nullable<Texture> {\r\n        return this._flowMap;\r\n    }\r\n\r\n    public set flowMap(value: Nullable<Texture>) {\r\n        if (this._flowMap === value) {\r\n            return;\r\n        }\r\n\r\n        this._flowMap = value;\r\n    }\r\n\r\n    /** Mesh emitter textures */\r\n\r\n    /** @internal */\r\n    public _meshPositionTexture: Nullable<RawTexture> = null;\r\n\r\n    /** @internal */\r\n    public _meshNormalTexture: Nullable<RawTexture> = null;\r\n\r\n    /** @internal */\r\n    public _meshTriangleCount: number = 0;\r\n\r\n    /** @internal */\r\n    public _meshTextureWidth: number = 0;\r\n\r\n    // Track mesh emitter inputs for invalidation\r\n    private _meshEmitterMeshId: number = -1;\r\n    private _meshEmitterUsedNormals: boolean = false;\r\n\r\n    /**\r\n     * Is this system ready to be used/rendered\r\n     * @returns true if the system is ready\r\n     */\r\n    public isReady(): boolean {\r\n        if (\r\n            !this.emitter ||\r\n            (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.isReady()) ||\r\n            (this._flowMap && !this._flowMap.isReady()) ||\r\n            !this.particleTexture ||\r\n            !this.particleTexture.isReady() ||\r\n            this._rebuildingAfterContextLost\r\n        ) {\r\n            return false;\r\n        }\r\n\r\n        if (this.blendMode !== ParticleSystem.BLENDMODE_MULTIPLYADD) {\r\n            if (!this._getWrapper(this.blendMode).effect!.isReady()) {\r\n                return false;\r\n            }\r\n        } else {\r\n            if (!this._getWrapper(ParticleSystem.BLENDMODE_MULTIPLY).effect!.isReady()) {\r\n                return false;\r\n            }\r\n            if (!this._getWrapper(ParticleSystem.BLENDMODE_ADD).effect!.isReady()) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (!this._platform.isUpdateBufferCreated()) {\r\n            this._recreateUpdateEffect();\r\n            return false;\r\n        }\r\n\r\n        return this._platform.isUpdateBufferReady();\r\n    }\r\n\r\n    /**\r\n     * Gets if the system has been started. (Note: this will still be true after stop is called)\r\n     * @returns True if it has been started, otherwise false.\r\n     */\r\n    public isStarted(): boolean {\r\n        return this._started;\r\n    }\r\n\r\n    /**\r\n     * Gets if the system has been stopped. (Note: rendering is still happening but the system is frozen)\r\n     * @returns True if it has been stopped, otherwise false.\r\n     */\r\n    public isStopped(): boolean {\r\n        return this._stopped;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the system is stopping\r\n     * @returns true if the system is currently stopping\r\n     */\r\n    public isStopping() {\r\n        return false; // Stop is immediate on GPU\r\n    }\r\n\r\n    /**\r\n     * Gets the number of particles active at the same time.\r\n     * @returns The number of active particles.\r\n     */\r\n    public getActiveCount() {\r\n        return this._currentActiveCount;\r\n    }\r\n\r\n    /**\r\n     * Starts the particle system and begins to emit\r\n     * @param delay defines the delay in milliseconds before starting the system (this.startDelay by default)\r\n     */\r\n    public start(delay = this.startDelay): void {\r\n        if (!this.targetStopDuration && this._hasTargetStopDurationDependantGradient()) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Particle system started with a targetStopDuration dependant gradient (eg. startSizeGradients) but no targetStopDuration set\";\r\n        }\r\n        if (delay) {\r\n            setTimeout(() => {\r\n                this.start(0);\r\n            }, delay);\r\n            return;\r\n        }\r\n        this._started = true;\r\n        this._stopped = false;\r\n        this._actualFrame = 0;\r\n        this._preWarmDone = false;\r\n\r\n        // Reset emit gradient so it acts the same on every start\r\n        if (this._emitRateGradients) {\r\n            if (this._emitRateGradients.length > 0) {\r\n                this._currentEmitRateGradient = this._emitRateGradients[0];\r\n                this._currentEmitRate1 = this._currentEmitRateGradient.getFactor();\r\n                this._currentEmitRate2 = this._currentEmitRate1;\r\n            }\r\n            if (this._emitRateGradients.length > 1) {\r\n                this._currentEmitRate2 = this._emitRateGradients[1].getFactor();\r\n            }\r\n        }\r\n        // Reset start size gradient so it acts the same on every start\r\n        if (this._startSizeGradients) {\r\n            if (this._startSizeGradients.length > 0) {\r\n                this._currentStartSizeGradient = this._startSizeGradients[0];\r\n                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();\r\n                this._currentStartSize2 = this._currentStartSize1;\r\n            }\r\n            if (this._startSizeGradients.length > 1) {\r\n                this._currentStartSize2 = this._startSizeGradients[1].getFactor();\r\n            }\r\n        }\r\n\r\n        // Animations\r\n        if (this.beginAnimationOnStart && this.animations && this.animations.length > 0 && this._scene) {\r\n            this._scene.beginAnimation(this, this.beginAnimationFrom, this.beginAnimationTo, this.beginAnimationLoop);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stops the particle system.\r\n     */\r\n    public stop(): void {\r\n        if (this._stopped) {\r\n            return;\r\n        }\r\n\r\n        this.onStoppedObservable.notifyObservers(this);\r\n\r\n        this._stopped = true;\r\n    }\r\n\r\n    /**\r\n     * Remove all active particles\r\n     */\r\n    public reset(): void {\r\n        this._releaseBuffers();\r\n        this._platform.releaseVertexBuffers();\r\n        this._currentActiveCount = 0;\r\n        this._targetIndex = 0;\r\n        this._writePointer = 0;\r\n        this._emitIndex = 0;\r\n        this._emitCount = 0;\r\n        this._accumulatedCount = 0;\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"GPUParticleSystem\"\r\n     * @returns a string containing the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"GPUParticleSystem\";\r\n    }\r\n\r\n    /**\r\n     * Gets the custom effect used to render the particles\r\n     * @param blendMode Blend mode for which the effect should be retrieved\r\n     * @returns The effect\r\n     */\r\n    public getCustomEffect(blendMode: number = 0): Nullable<Effect> {\r\n        return this._customWrappers[blendMode]?.effect ?? this._customWrappers[0]!.effect;\r\n    }\r\n\r\n    private _getCustomDrawWrapper(blendMode: number = 0): Nullable<DrawWrapper> {\r\n        return this._customWrappers[blendMode] ?? this._customWrappers[0];\r\n    }\r\n\r\n    /**\r\n     * Sets the custom effect used to render the particles\r\n     * @param effect The effect to set\r\n     * @param blendMode Blend mode for which the effect should be set\r\n     */\r\n    public setCustomEffect(effect: Nullable<Effect>, blendMode: number = 0) {\r\n        this._customWrappers[blendMode] = new DrawWrapper(this._engine);\r\n        this._customWrappers[blendMode].effect = effect;\r\n    }\r\n\r\n    /** @internal */\r\n    protected _onBeforeDrawParticlesObservable: Nullable<Observable<Nullable<Effect>>> = null;\r\n\r\n    /**\r\n     * Observable that will be called just before the particles are drawn\r\n     */\r\n    public get onBeforeDrawParticlesObservable(): Observable<Nullable<Effect>> {\r\n        if (!this._onBeforeDrawParticlesObservable) {\r\n            this._onBeforeDrawParticlesObservable = new Observable<Nullable<Effect>>();\r\n        }\r\n\r\n        return this._onBeforeDrawParticlesObservable;\r\n    }\r\n\r\n    /**\r\n     * Gets the name of the particle vertex shader\r\n     */\r\n    public get vertexShaderName(): string {\r\n        return \"gpuRenderParticles\";\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex buffers used by the particle system\r\n     * Should be called after render() has been called for the current frame so that the buffers returned are the ones that have been updated\r\n     * in the current frame (there's a ping-pong between two sets of buffers - for a given frame, one set is used as the source and the other as the destination)\r\n     */\r\n    public get vertexBuffers(): Immutable<{ [key: string]: VertexBuffer }> {\r\n        // We return the other buffers than those corresponding to this._targetIndex because it is assumed vertexBuffers will be called in the current frame\r\n        // after render() has been called, meaning that the buffers have already been swapped and this._targetIndex points to the buffers that will be updated\r\n        // in the next frame (and which are the sources in this frame) and (this._targetIndex ^ 1) points to the buffers that have been updated this frame\r\n        // (and that will be the source buffers in the next frame)\r\n        return this._renderVertexBuffers[this._targetIndex ^ 1];\r\n    }\r\n\r\n    /**\r\n     * Gets the index buffer used by the particle system (null for GPU particle systems)\r\n     */\r\n    public get indexBuffer(): Nullable<DataBuffer> {\r\n        return null;\r\n    }\r\n\r\n    /** @internal */\r\n    public _colorGradientsTexture: RawTexture;\r\n\r\n    protected override _removeGradientAndTexture(gradient: number, gradients: Nullable<IValueGradient[]>, texture: RawTexture): BaseParticleSystem {\r\n        super._removeGradientAndTexture(gradient, gradients, texture);\r\n        this._releaseBuffers();\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new color gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param color1 defines the color to affect to the specified gradient\r\n     * @param color2 defines an optional second color to be used to produce a random color per particle at the gradient (lerped with color1 using a per-particle random value)\r\n     * @returns the current particle system\r\n     */\r\n    public addColorGradient(gradient: number, color1: Color4, color2?: Color4): GPUParticleSystem {\r\n        if (!this._colorGradients) {\r\n            this._colorGradients = [];\r\n        }\r\n\r\n        const colorGradient = new ColorGradient(gradient, color1, color2);\r\n        this._colorGradients.push(colorGradient);\r\n\r\n        if (!this._refreshColorGradient(true)) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Resyncs the color gradient state after a change.\r\n     * @param reorder true to re-sort the gradient list by position\r\n     * @returns true when the existing lookup texture was re-baked in place (value-only change — nothing to\r\n     * release, the live particle pool survives), false when the change is structural (family emptied, color2 row\r\n     * layout flipped, or no texture yet) and the caller must release the buffers; in that case the outdated\r\n     * texture is disposed for lazy recreation.\r\n     */\r\n    private _refreshColorGradient(reorder = false): boolean {\r\n        if (this._colorGradients) {\r\n            if (reorder) {\r\n                this._colorGradients.sort((a, b) => {\r\n                    if (a.gradient < b.gradient) {\r\n                        return -1;\r\n                    } else if (a.gradient > b.gradient) {\r\n                        return 1;\r\n                    }\r\n\r\n                    return 0;\r\n                });\r\n            }\r\n\r\n            // Recompute whether any stop uses a color2 range. Done here (not inside _createColorGradientTexture)\r\n            // so the flag is available to both define generation (fillDefines) and render vertex buffer layout\r\n            // (_createVertexBuffers), which can run before the texture is recreated.\r\n            this._hasColorGradientColor2 = false;\r\n            for (const g of this._colorGradients) {\r\n                if (g.color2) {\r\n                    this._hasColorGradientColor2 = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // When the texture layout is unchanged, re-bake the existing texture's pixels in place: identity is\r\n            // preserved, so retained bindings (e.g. the WebGPU update compute shader's) stay valid and no buffer\r\n            // release is needed.\r\n            if (this._rebakeColorGradientTexture()) {\r\n                return true;\r\n            }\r\n\r\n            if (this._colorGradientsTexture) {\r\n                this._colorGradientsTexture.dispose();\r\n                (<any>this._colorGradientsTexture) = null;\r\n            }\r\n        } else {\r\n            this._hasColorGradientColor2 = false;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Force the system to rebuild all gradients that need to be resync.\r\n     *\r\n     * This is the live-edit entry point both Inspectors call from their gradient onChange handlers, so a\r\n     * value-only edit must preserve the running simulation: every family whose lookup texture can be re-baked\r\n     * in place is updated without touching the particle buffers. Only a STRUCTURAL change — a family that has\r\n     * no texture to re-bake yet, one that was emptied, or a color2 row-layout flip — rebuilds the pool.\r\n     *\r\n     * An ABSENT family is not a structural change: it has nothing to resync, and counting it as one would\r\n     * reset the pool on every call (the destruction this method exists to avoid). Absence has two spellings —\r\n     * see _gradientFamilyNeedsResync.\r\n     */\r\n    public forceRefreshGradients() {\r\n        let structural = false;\r\n\r\n        if (this._gradientFamilyNeedsResync(this._colorGradients, \"_colorGradientsTexture\") && !this._refreshColorGradient()) {\r\n            structural = true;\r\n        }\r\n        if (this._gradientFamilyNeedsResync(this._sizeGradients, \"_sizeGradientsTexture\") && !this._refreshFactorGradient(this._sizeGradients, \"_sizeGradientsTexture\")) {\r\n            structural = true;\r\n        }\r\n        if (\r\n            this._gradientFamilyNeedsResync(this._angularSpeedGradients, \"_angularSpeedGradientsTexture\") &&\r\n            !this._refreshFactorGradient(this._angularSpeedGradients, \"_angularSpeedGradientsTexture\")\r\n        ) {\r\n            structural = true;\r\n        }\r\n        if (\r\n            this._gradientFamilyNeedsResync(this._velocityGradients, \"_velocityGradientsTexture\") &&\r\n            !this._refreshFactorGradient(this._velocityGradients, \"_velocityGradientsTexture\")\r\n        ) {\r\n            structural = true;\r\n        }\r\n        if (\r\n            this._gradientFamilyNeedsResync(this._limitVelocityGradients, \"_limitVelocityGradientsTexture\") &&\r\n            !this._refreshFactorGradient(this._limitVelocityGradients, \"_limitVelocityGradientsTexture\")\r\n        ) {\r\n            structural = true;\r\n        }\r\n        if (this._gradientFamilyNeedsResync(this._dragGradients, \"_dragGradientsTexture\") && !this._refreshFactorGradient(this._dragGradients, \"_dragGradientsTexture\")) {\r\n            structural = true;\r\n        }\r\n\r\n        if (structural) {\r\n            this.reset();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Whether a gradient family still has anything for a resync pass to do.\r\n     *\r\n     * Absence has TWO spellings: a family that was never initialized is `null`, but one that has been emptied\r\n     * stays `[]`. Only the first is falsy, so a bare truthiness test reads an emptied family as unfinished\r\n     * business on every later call — its refresh finds nothing to re-bake, reports \"structural\", and\r\n     * forceRefreshGradients resets the live pool forever after, which is precisely the destruction it exists\r\n     * to prevent.\r\n     *\r\n     * Entries always mean work (re-bake in place, or build when there is no texture yet). An EMPTY family is\r\n     * work only while it still owns a texture: that is the just-emptied transition, whose stale texture must\r\n     * be disposed. `[]` with no texture is settled absence — nothing left to resync.\r\n     * @param gradients the gradient family to test, or null when it was never initialized\r\n     * @param textureName the name of the lookup texture property backing that family\r\n     * @returns true when the family still has work for a resync pass, false when its absence is settled\r\n     */\r\n    private _gradientFamilyNeedsResync(gradients: Nullable<IValueGradient[]>, textureName: string): boolean {\r\n        if (!gradients) {\r\n            return false;\r\n        }\r\n\r\n        return gradients.length > 0 || !!(<any>this)[textureName];\r\n    }\r\n\r\n    /**\r\n     * Remove a specific color gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeColorGradient(gradient: number): GPUParticleSystem {\r\n        super._removeGradientAndTexture(gradient, this._colorGradients, null);\r\n\r\n        // The set of remaining gradients may no longer contain a color2; _refreshColorGradient recomputes the flag\r\n        // and either re-bakes the texture in place (value-only change) or signals a structural change.\r\n        if (!this._refreshColorGradient()) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Resets the draw wrappers cache\r\n     */\r\n    public resetDrawCache(): void {\r\n        for (const drawWrappers of this._drawWrappers) {\r\n            if (!drawWrappers) {\r\n                continue;\r\n            }\r\n            for (const drawWrapper of drawWrappers) {\r\n                drawWrapper?.drawContext?.reset();\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _angularSpeedGradientsTexture: RawTexture;\r\n    /** @internal */\r\n    public _sizeGradientsTexture: RawTexture;\r\n    /** @internal */\r\n    public _velocityGradientsTexture: RawTexture;\r\n    /** @internal */\r\n    public _limitVelocityGradientsTexture: RawTexture;\r\n    /** @internal */\r\n    public _dragGradientsTexture: RawTexture;\r\n\r\n    /**\r\n     * Adds a new size gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the size factor to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addSizeGradient(gradient: number, factor: number, factor2?: number): GPUParticleSystem {\r\n        if (!this._sizeGradients) {\r\n            this._sizeGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);\r\n\r\n        if (!this._refreshFactorGradient(this._sizeGradients, \"_sizeGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific size gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeSizeGradient(gradient: number): GPUParticleSystem {\r\n        this._removeFactorGradient(this._sizeGradients, gradient);\r\n\r\n        if (!this._refreshFactorGradient(this._sizeGradients, \"_sizeGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Resyncs a factor gradient family's lookup texture after a change.\r\n     * @param factorGradients defines the gradient family that changed\r\n     * @param textureName defines the name of the property holding the family's lookup texture\r\n     * @returns true when the existing texture was re-baked in place (value-only change — nothing to release, the\r\n     * live particle pool survives), false when the caller must release the buffers (no texture to re-bake, or the\r\n     * family was emptied); in that case the outdated texture is disposed for lazy recreation.\r\n     */\r\n    private _refreshFactorGradient(factorGradients: Nullable<FactorGradient[]>, textureName: string): boolean {\r\n        if (!factorGradients) {\r\n            return false;\r\n        }\r\n\r\n        if (this._rebakeFactorGradientTexture(factorGradients, textureName)) {\r\n            return true;\r\n        }\r\n\r\n        const that = this as any;\r\n        if (that[textureName]) {\r\n            that[textureName].dispose();\r\n            that[textureName] = null;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds a new angular speed gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the angular speed to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addAngularSpeedGradient(gradient: number, factor: number, factor2?: number): GPUParticleSystem {\r\n        if (!this._angularSpeedGradients) {\r\n            this._angularSpeedGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._angularSpeedGradients, gradient, factor, factor2);\r\n\r\n        if (!this._refreshFactorGradient(this._angularSpeedGradients, \"_angularSpeedGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific angular speed gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeAngularSpeedGradient(gradient: number): GPUParticleSystem {\r\n        this._removeFactorGradient(this._angularSpeedGradients, gradient);\r\n\r\n        if (!this._refreshFactorGradient(this._angularSpeedGradients, \"_angularSpeedGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new velocity gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the velocity to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addVelocityGradient(gradient: number, factor: number, factor2?: number): GPUParticleSystem {\r\n        if (!this._velocityGradients) {\r\n            this._velocityGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._velocityGradients, gradient, factor, factor2);\r\n\r\n        if (!this._refreshFactorGradient(this._velocityGradients, \"_velocityGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific velocity gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeVelocityGradient(gradient: number): GPUParticleSystem {\r\n        this._removeFactorGradient(this._velocityGradients, gradient);\r\n\r\n        if (!this._refreshFactorGradient(this._velocityGradients, \"_velocityGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new limit velocity gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the limit velocity value to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addLimitVelocityGradient(gradient: number, factor: number, factor2?: number): GPUParticleSystem {\r\n        if (!this._limitVelocityGradients) {\r\n            this._limitVelocityGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._limitVelocityGradients, gradient, factor, factor2);\r\n\r\n        if (!this._refreshFactorGradient(this._limitVelocityGradients, \"_limitVelocityGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific limit velocity gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeLimitVelocityGradient(gradient: number): GPUParticleSystem {\r\n        this._removeFactorGradient(this._limitVelocityGradients, gradient);\r\n\r\n        if (!this._refreshFactorGradient(this._limitVelocityGradients, \"_limitVelocityGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new drag gradient\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the drag value to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addDragGradient(gradient: number, factor: number, factor2?: number): GPUParticleSystem {\r\n        if (!this._dragGradients) {\r\n            this._dragGradients = [];\r\n        }\r\n\r\n        this._addFactorGradient(this._dragGradients, gradient, factor, factor2);\r\n\r\n        if (!this._refreshFactorGradient(this._dragGradients, \"_dragGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific drag gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeDragGradient(gradient: number): GPUParticleSystem {\r\n        this._removeFactorGradient(this._dragGradients, gradient);\r\n\r\n        if (!this._refreshFactorGradient(this._dragGradients, \"_dragGradientsTexture\")) {\r\n            this._releaseBuffers();\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Adds a new start size gradient (please note that this will only work if you set the targetStopDuration property)\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the start size factor to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addStartSizeGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._startSizeGradients) {\r\n            this._startSizeGradients = [];\r\n        }\r\n\r\n        const hadGradients = this._startSizeGradients.length > 0;\r\n        this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);\r\n        if (!hadGradients) {\r\n            this._resetEffect();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific start size gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeStartSizeGradient(gradient: number): IParticleSystem {\r\n        const hadGradients = this._startSizeGradients && this._startSizeGradients.length > 0;\r\n        this._removeFactorGradient(this._startSizeGradients, gradient);\r\n        if (hadGradients && (!this._startSizeGradients || this._startSizeGradients.length === 0)) {\r\n            this._resetEffect();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the current particle system\r\n     */\r\n    public addColorRemapGradient(): IParticleSystem {\r\n        // Do nothing as start size is not supported by GPUParticleSystem\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the current particle system\r\n     */\r\n    public removeColorRemapGradient(): IParticleSystem {\r\n        // Do nothing as start size is not supported by GPUParticleSystem\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the current particle system\r\n     */\r\n    public addAlphaRemapGradient(): IParticleSystem {\r\n        // Do nothing as start size is not supported by GPUParticleSystem\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the current particle system\r\n     */\r\n    public removeAlphaRemapGradient(): IParticleSystem {\r\n        // Do nothing as start size is not supported by GPUParticleSystem\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the current particle system\r\n     */\r\n    public addRampGradient(): IParticleSystem {\r\n        //Not supported by GPUParticleSystem\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the current particle system\r\n     */\r\n    public removeRampGradient(): IParticleSystem {\r\n        //Not supported by GPUParticleSystem\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * @returns the list of ramp gradients\r\n     */\r\n    public getRampGradients(): Nullable<Array<Color3Gradient>> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Not supported by GPUParticleSystem\r\n     * Gets or sets a boolean indicating that ramp gradients must be used\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro#ramp-gradients\r\n     */\r\n    public get useRampGradients(): boolean {\r\n        //Not supported by GPUParticleSystem\r\n        return false;\r\n    }\r\n\r\n    public set useRampGradients(value: boolean) {\r\n        //Not supported by GPUParticleSystem\r\n    }\r\n\r\n    /**\r\n     * Adds a new life time gradient (please note that this will only work if you set the targetStopDuration property)\r\n     * @param gradient defines the gradient to use (between 0 and 1)\r\n     * @param factor defines the life time factor to affect to the specified gradient\r\n     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from\r\n     * @returns the current particle system\r\n     */\r\n    public addLifeTimeGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {\r\n        if (!this._lifeTimeGradients) {\r\n            this._lifeTimeGradients = [];\r\n        }\r\n\r\n        const hadGradients = this._lifeTimeGradients.length > 0;\r\n        this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);\r\n        if (!hadGradients) {\r\n            this._resetEffect();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Remove a specific life time gradient\r\n     * @param gradient defines the gradient to remove\r\n     * @returns the current particle system\r\n     */\r\n    public removeLifeTimeGradient(gradient: number): IParticleSystem {\r\n        const hadGradients = this._lifeTimeGradients && this._lifeTimeGradients.length > 0;\r\n        this._removeFactorGradient(this._lifeTimeGradients, gradient);\r\n        if (hadGradients && (!this._lifeTimeGradients || this._lifeTimeGradients.length === 0)) {\r\n            this._resetEffect();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a GPU particle system.\r\n     * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.\r\n     * @param name The name of the particle system\r\n     * @param options The options used to create the system\r\n     * @param sceneOrEngine The scene the particle system belongs to or the engine to use if no scene\r\n     * @param customEffect a custom effect used to change the way particles are rendered by default\r\n     * @param isAnimationSheetEnabled Must be true if using a spritesheet to animate the particles texture\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: Partial<{\r\n            capacity: number;\r\n            randomTextureSize: number;\r\n            emitRateControl: boolean;\r\n            maxAttractors: number;\r\n        }>,\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        customEffect: Nullable<Effect> = null,\r\n        isAnimationSheetEnabled: boolean = false\r\n    ) {\r\n        RegisterAnimatable();\r\n        super(name);\r\n\r\n        if (!sceneOrEngine || sceneOrEngine.getClassName() === \"Scene\") {\r\n            this._scene = (sceneOrEngine as Scene) || EngineStore.LastCreatedScene;\r\n            this._engine = this._scene.getEngine();\r\n            this.uniqueId = this._scene.getUniqueId();\r\n            this.layerMask = this._scene.defaultRenderableLayerMask;\r\n            this._scene.particleSystems.push(this);\r\n        } else {\r\n            this._engine = sceneOrEngine as AbstractEngine;\r\n            this.defaultProjectionMatrix = Matrix.PerspectiveFovLH(0.8, 1, 0.1, 100, this._engine.isNDCHalfZRange);\r\n        }\r\n\r\n        if (this._engine.getCaps().supportComputeShaders) {\r\n            if (!GetClass(\"BABYLON.ComputeShaderParticleSystem\")) {\r\n                throw new Error(\"The ComputeShaderParticleSystem class is not available! Make sure you have imported it.\");\r\n            }\r\n            this._platform = new (GetClass(\"BABYLON.ComputeShaderParticleSystem\"))(this, this._engine);\r\n        } else {\r\n            if (!GetClass(\"BABYLON.WebGL2ParticleSystem\")) {\r\n                throw new Error(\"The WebGL2ParticleSystem class is not available! Make sure you have imported it.\");\r\n            }\r\n            this._platform = new (GetClass(\"BABYLON.WebGL2ParticleSystem\"))(this, this._engine);\r\n        }\r\n\r\n        this._customWrappers = { 0: new DrawWrapper(this._engine) };\r\n        this._customWrappers[0]!.effect = customEffect;\r\n\r\n        this._drawWrappers = [];\r\n\r\n        this._createIndexBuffer();\r\n\r\n        // Setup the default processing configuration to the scene.\r\n        this._attachImageProcessingConfiguration(null);\r\n\r\n        options = options ?? {};\r\n\r\n        if (!options.randomTextureSize) {\r\n            delete options.randomTextureSize;\r\n        }\r\n\r\n        const fullOptions = {\r\n            capacity: 50000,\r\n            randomTextureSize: this._engine.getCaps().maxTextureSize,\r\n            ...options,\r\n        };\r\n\r\n        const optionsAsNumber = <number>options;\r\n        if (isFinite(optionsAsNumber)) {\r\n            fullOptions.capacity = optionsAsNumber;\r\n        }\r\n\r\n        this._capacity = fullOptions.capacity;\r\n        this._maxActiveParticleCount = fullOptions.capacity;\r\n        this._currentActiveCount = 0;\r\n        this._isAnimationSheetEnabled = isAnimationSheetEnabled;\r\n        this.emitRateControl = !!options.emitRateControl;\r\n        this.maxAttractors = options.maxAttractors ?? 8;\r\n\r\n        this.particleEmitterType = new BoxParticleEmitter();\r\n\r\n        // Random data\r\n        const maxTextureSize = Math.min(this._engine.getCaps().maxTextureSize, fullOptions.randomTextureSize);\r\n        let d = [];\r\n        for (let i = 0; i < maxTextureSize; ++i) {\r\n            d.push(Math.random());\r\n            d.push(Math.random());\r\n            d.push(Math.random());\r\n            d.push(Math.random());\r\n        }\r\n        this._randomTexture = new RawTexture(\r\n            new Float32Array(d),\r\n            maxTextureSize,\r\n            1,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            sceneOrEngine,\r\n            false,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            Constants.TEXTURETYPE_FLOAT\r\n        );\r\n        this._randomTexture.name = \"GPUParticleSystem_random1\";\r\n        this._randomTexture.wrapU = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n        this._randomTexture.wrapV = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n\r\n        d = [];\r\n        for (let i = 0; i < maxTextureSize; ++i) {\r\n            d.push(Math.random());\r\n            d.push(Math.random());\r\n            d.push(Math.random());\r\n            d.push(Math.random());\r\n        }\r\n        this._randomTexture2 = new RawTexture(\r\n            new Float32Array(d),\r\n            maxTextureSize,\r\n            1,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            sceneOrEngine,\r\n            false,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            Constants.TEXTURETYPE_FLOAT\r\n        );\r\n        this._randomTexture2.name = \"GPUParticleSystem_random2\";\r\n        this._randomTexture2.wrapU = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n        this._randomTexture2.wrapV = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n\r\n        this._randomTextureSize = maxTextureSize;\r\n    }\r\n\r\n    protected override _reset() {\r\n        this._releaseBuffers();\r\n    }\r\n\r\n    private _createVertexBuffers(updateBuffer: Buffer, renderBuffer: Buffer, spriteSource: Buffer): void {\r\n        const renderVertexBuffers: { [key: string]: VertexBuffer } = {};\r\n        renderVertexBuffers[\"position\"] = renderBuffer.createVertexBuffer(\"position\", 0, 3, this._attributesStrideSize, true);\r\n        let offset = 3;\r\n        renderVertexBuffers[\"age\"] = renderBuffer.createVertexBuffer(\"age\", offset, 1, this._attributesStrideSize, true);\r\n        offset += 1;\r\n        renderVertexBuffers[\"size\"] = renderBuffer.createVertexBuffer(\"size\", offset, 3, this._attributesStrideSize, true);\r\n        offset += 3;\r\n        renderVertexBuffers[\"life\"] = renderBuffer.createVertexBuffer(\"life\", offset, 1, this._attributesStrideSize, true);\r\n        offset += 1;\r\n        if (this._hasColorGradientColor2) {\r\n            // Expose `seed` to the render shader so it can pick a stable per-particle mix factor between\r\n            // the color1 and color2 rows of the color gradient texture.\r\n            renderVertexBuffers[\"seed\"] = renderBuffer.createVertexBuffer(\"seed\", offset, 4, this._attributesStrideSize, true);\r\n        }\r\n        offset += 4; // seed\r\n        if (this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL) {\r\n            renderVertexBuffers[\"direction\"] = renderBuffer.createVertexBuffer(\"direction\", offset, 3, this._attributesStrideSize, true);\r\n        }\r\n        offset += 3; // direction\r\n        if (this._platform.alignDataInBuffer) {\r\n            offset += 1;\r\n        }\r\n\r\n        if (this.particleEmitterType instanceof CustomParticleEmitter) {\r\n            offset += 3;\r\n            if (this._platform.alignDataInBuffer) {\r\n                offset += 1;\r\n            }\r\n        }\r\n\r\n        if (!this._colorGradientsTexture) {\r\n            renderVertexBuffers[\"color\"] = renderBuffer.createVertexBuffer(\"color\", offset, 4, this._attributesStrideSize, true);\r\n            offset += 4;\r\n        }\r\n\r\n        if (this._needsInitialDirection) {\r\n            renderVertexBuffers[\"initialDirection\"] = renderBuffer.createVertexBuffer(\"initialDirection\", offset, 3, this._attributesStrideSize, true);\r\n            offset += 3;\r\n            if (this._platform.alignDataInBuffer) {\r\n                offset += 1;\r\n            }\r\n        }\r\n\r\n        if (this.noiseTexture) {\r\n            renderVertexBuffers[\"noiseCoordinates1\"] = renderBuffer.createVertexBuffer(\"noiseCoordinates1\", offset, 3, this._attributesStrideSize, true);\r\n            offset += 3;\r\n            if (this._platform.alignDataInBuffer) {\r\n                offset += 1;\r\n            }\r\n            renderVertexBuffers[\"noiseCoordinates2\"] = renderBuffer.createVertexBuffer(\"noiseCoordinates2\", offset, 3, this._attributesStrideSize, true);\r\n            offset += 3;\r\n            if (this._platform.alignDataInBuffer) {\r\n                offset += 1;\r\n            }\r\n        }\r\n\r\n        renderVertexBuffers[\"angle\"] = renderBuffer.createVertexBuffer(\"angle\", offset, 1, this._attributesStrideSize, true);\r\n        if (this._angularSpeedGradientsTexture) {\r\n            offset++;\r\n        } else {\r\n            offset += 2;\r\n        }\r\n\r\n        if (this._isAnimationSheetEnabled) {\r\n            renderVertexBuffers[\"cellIndex\"] = renderBuffer.createVertexBuffer(\"cellIndex\", offset, 1, this._attributesStrideSize, true);\r\n            offset += 1;\r\n            if (this.spriteRandomStartCell) {\r\n                renderVertexBuffers[\"cellStartOffset\"] = renderBuffer.createVertexBuffer(\"cellStartOffset\", offset, 1, this._attributesStrideSize, true);\r\n            }\r\n        }\r\n\r\n        renderVertexBuffers[\"offset\"] = spriteSource.createVertexBuffer(\"offset\", 0, 2);\r\n        renderVertexBuffers[\"uv\"] = spriteSource.createVertexBuffer(\"uv\", 2, 2);\r\n\r\n        this._renderVertexBuffers.push(renderVertexBuffers);\r\n\r\n        this._platform.createVertexBuffers(updateBuffer, renderVertexBuffers);\r\n\r\n        this.resetDrawCache();\r\n    }\r\n\r\n    private _initialize(force = false): void {\r\n        if (this._buffer0 && !force) {\r\n            return;\r\n        }\r\n\r\n        const engine = this._engine;\r\n        const data: float[] = [];\r\n\r\n        this._attributesStrideSize = 21;\r\n        this._targetIndex = 0;\r\n\r\n        if (this._platform.alignDataInBuffer) {\r\n            this._attributesStrideSize += 1;\r\n        }\r\n\r\n        if (this.particleEmitterType instanceof CustomParticleEmitter) {\r\n            this._attributesStrideSize += 3;\r\n            if (this._platform.alignDataInBuffer) {\r\n                this._attributesStrideSize += 1;\r\n            }\r\n        }\r\n\r\n        if (this._needsInitialDirection) {\r\n            this._attributesStrideSize += 3;\r\n            if (this._platform.alignDataInBuffer) {\r\n                this._attributesStrideSize += 1;\r\n            }\r\n        }\r\n\r\n        if (this._colorGradientsTexture) {\r\n            this._attributesStrideSize -= 4;\r\n        }\r\n\r\n        if (this._angularSpeedGradientsTexture) {\r\n            this._attributesStrideSize -= 1;\r\n        }\r\n\r\n        if (this._isAnimationSheetEnabled) {\r\n            this._attributesStrideSize += 1;\r\n            if (this.spriteRandomStartCell) {\r\n                this._attributesStrideSize += 1;\r\n            }\r\n        }\r\n\r\n        if (this.noiseTexture) {\r\n            this._attributesStrideSize += 6;\r\n            if (this._platform.alignDataInBuffer) {\r\n                this._attributesStrideSize += 2;\r\n            }\r\n        }\r\n\r\n        if (this._platform.alignDataInBuffer) {\r\n            this._attributesStrideSize += 3 - ((this._attributesStrideSize + 3) & 3); // round to multiple of 4\r\n        }\r\n\r\n        const usingCustomEmitter = this.particleEmitterType instanceof CustomParticleEmitter;\r\n        const tmpVector = TmpVectors.Vector3[0];\r\n\r\n        let offset = 0;\r\n        for (let particleIndex = 0; particleIndex < this._capacity; particleIndex++) {\r\n            // position\r\n            data.push(0.0);\r\n            data.push(0.0);\r\n            data.push(0.0);\r\n\r\n            // Age\r\n            data.push(0.0); // create the particle as a dead one to create a new one at start\r\n\r\n            // Size\r\n            data.push(0.0);\r\n            data.push(0.0);\r\n            data.push(0.0);\r\n\r\n            // life\r\n            data.push(0.0);\r\n\r\n            // Seed\r\n            data.push(Math.random());\r\n            data.push(Math.random());\r\n            data.push(Math.random());\r\n            data.push(Math.random());\r\n\r\n            // direction\r\n            if (usingCustomEmitter) {\r\n                (this.particleEmitterType as CustomParticleEmitter).particleDestinationGenerator(particleIndex, null, tmpVector);\r\n                data.push(tmpVector.x);\r\n                data.push(tmpVector.y);\r\n                data.push(tmpVector.z);\r\n            } else {\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n            }\r\n\r\n            if (this._platform.alignDataInBuffer) {\r\n                data.push(0.0); // dummy0\r\n            }\r\n\r\n            offset += 16; // position, age, size, life, seed, direction, dummy0\r\n\r\n            if (usingCustomEmitter) {\r\n                (this.particleEmitterType as CustomParticleEmitter).particlePositionGenerator(particleIndex, null, tmpVector);\r\n                data.push(tmpVector.x);\r\n                data.push(tmpVector.y);\r\n                data.push(tmpVector.z);\r\n                if (this._platform.alignDataInBuffer) {\r\n                    data.push(0.0); // dummy1\r\n                }\r\n                offset += 4;\r\n            }\r\n\r\n            if (!this._colorGradientsTexture) {\r\n                // color\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n                offset += 4;\r\n            }\r\n\r\n            if (this._needsInitialDirection) {\r\n                // initialDirection\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n                data.push(0.0);\r\n                if (this._platform.alignDataInBuffer) {\r\n                    data.push(0.0); // dummy2\r\n                }\r\n                offset += 4;\r\n            }\r\n\r\n            if (this.noiseTexture) {\r\n                // Random coordinates for reading into noise texture\r\n                data.push(Math.random());\r\n                data.push(Math.random());\r\n                data.push(Math.random());\r\n                if (this._platform.alignDataInBuffer) {\r\n                    data.push(0.0); // dummy3\r\n                }\r\n                data.push(Math.random());\r\n                data.push(Math.random());\r\n                data.push(Math.random());\r\n                if (this._platform.alignDataInBuffer) {\r\n                    data.push(0.0); // dummy4\r\n                }\r\n                offset += 8;\r\n            }\r\n\r\n            // angle\r\n            data.push(0.0);\r\n            offset += 1;\r\n\r\n            if (!this._angularSpeedGradientsTexture) {\r\n                data.push(0.0);\r\n                offset += 1;\r\n            }\r\n\r\n            if (this._isAnimationSheetEnabled) {\r\n                data.push(0.0);\r\n                offset += 1;\r\n                if (this.spriteRandomStartCell) {\r\n                    data.push(0.0);\r\n                    offset += 1;\r\n                }\r\n            }\r\n\r\n            if (this._platform.alignDataInBuffer) {\r\n                let numDummies = 3 - ((offset + 3) & 3);\r\n                offset += numDummies;\r\n                while (numDummies-- > 0) {\r\n                    data.push(0.0);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Sprite data\r\n        const spriteData = new Float32Array([0.5, 0.5, 1, 1, -0.5, 0.5, 0, 1, 0.5, -0.5, 1, 0, -0.5, -0.5, 0, 0]);\r\n\r\n        const bufferData1: DataArray | DataBuffer = this._platform.createParticleBuffer(data);\r\n        const bufferData2: DataArray | DataBuffer = this._platform.createParticleBuffer(data);\r\n\r\n        // Buffers\r\n        this._buffer0 = new Buffer(engine, bufferData1, false, this._attributesStrideSize);\r\n        this._buffer1 = new Buffer(engine, bufferData2, false, this._attributesStrideSize);\r\n        this._spriteBuffer = new Buffer(engine, spriteData, false, 4);\r\n\r\n        // Update & Render vertex buffers\r\n        this._renderVertexBuffers = [];\r\n        this._createVertexBuffers(this._buffer0, this._buffer1, this._spriteBuffer);\r\n        this._createVertexBuffers(this._buffer1, this._buffer0, this._spriteBuffer);\r\n\r\n        // Links\r\n        this._sourceBuffer = this._buffer0;\r\n        this._targetBuffer = this._buffer1;\r\n    }\r\n\r\n    /**\r\n     * Forces the update effect to be recreated on the next render.\r\n     */\r\n    private _resetEffect() {\r\n        this._cachedUpdateDefines = \"\";\r\n    }\r\n\r\n    /** @internal */\r\n    public _recreateUpdateEffect() {\r\n        this._createColorGradientTexture();\r\n        this._createSizeGradientTexture();\r\n        this._createAngularSpeedGradientTexture();\r\n        this._createVelocityGradientTexture();\r\n        this._createLimitVelocityGradientTexture();\r\n        this._createDragGradientTexture();\r\n        this._createMeshEmitterTextures();\r\n\r\n        let defines = this.particleEmitterType ? this.particleEmitterType.getEffectDefines() : \"\";\r\n\r\n        if (this._isBillboardBased) {\r\n            // Stretched local needs initialDirection in the buffer, which requires !BILLBOARD in the update shader.\r\n            // The render shader still uses BILLBOARD — that's handled separately in fillDefines().\r\n            if (this.billboardMode !== ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL) {\r\n                defines += \"\\n#define BILLBOARD\";\r\n            }\r\n        }\r\n\r\n        if (this._colorGradientsTexture) {\r\n            defines += \"\\n#define COLORGRADIENTS\";\r\n        }\r\n\r\n        if (this._sizeGradientsTexture) {\r\n            defines += \"\\n#define SIZEGRADIENTS\";\r\n        }\r\n\r\n        if (this._angularSpeedGradientsTexture) {\r\n            defines += \"\\n#define ANGULARSPEEDGRADIENTS\";\r\n        }\r\n\r\n        if (this._velocityGradientsTexture) {\r\n            defines += \"\\n#define VELOCITYGRADIENTS\";\r\n        }\r\n\r\n        if (this._limitVelocityGradientsTexture) {\r\n            defines += \"\\n#define LIMITVELOCITYGRADIENTS\";\r\n        }\r\n\r\n        if (this._dragGradientsTexture) {\r\n            defines += \"\\n#define DRAGGRADIENTS\";\r\n        }\r\n\r\n        if (this._flowMap) {\r\n            defines += \"\\n#define FLOWMAP\";\r\n        }\r\n\r\n        if (this.isAnimationSheetEnabled) {\r\n            defines += \"\\n#define ANIMATESHEET\";\r\n            if (this.spriteRandomStartCell) {\r\n                defines += \"\\n#define ANIMATESHEETRANDOMSTART\";\r\n            }\r\n        }\r\n\r\n        if (this.noiseTexture) {\r\n            defines += \"\\n#define NOISE\";\r\n        }\r\n\r\n        if (this.isLocal) {\r\n            defines += \"\\n#define LOCAL\";\r\n        }\r\n\r\n        if (this._attractors.length > 0) {\r\n            defines += \"\\n#define ATTRACTORS\";\r\n            defines += \"\\n#define MAX_ATTRACTORS \" + this.maxAttractors;\r\n        }\r\n\r\n        if (this.emitRateControl) {\r\n            defines += \"\\n#define EMITRATECTRL\";\r\n        }\r\n\r\n        if (this._startSizeGradients && this._startSizeGradients.length > 0) {\r\n            defines += \"\\n#define STARTSIZEGRADIENTS\";\r\n        }\r\n\r\n        if (this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {\r\n            defines += \"\\n#define LIFETIMEGRADIENTS\";\r\n        }\r\n\r\n        if (this.particleEmitterType instanceof MeshParticleEmitter && this._meshPositionTexture) {\r\n            defines += \"\\n#define MESHEMITTER\";\r\n            if (this._meshNormalTexture) {\r\n                defines += \"\\n#define MESHNORMALS\";\r\n            }\r\n        }\r\n\r\n        if (this._platform.isUpdateBufferCreated() && this._cachedUpdateDefines === defines) {\r\n            return this._platform.isUpdateBufferReady();\r\n        }\r\n\r\n        this._cachedUpdateDefines = defines;\r\n        this._updateBuffer = this._platform.createUpdateBuffer(defines);\r\n\r\n        return this._platform.isUpdateBufferReady();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _getWrapper(blendMode: number): DrawWrapper {\r\n        const customWrapper = this._getCustomDrawWrapper(blendMode);\r\n\r\n        if (customWrapper?.effect) {\r\n            return customWrapper;\r\n        }\r\n\r\n        const defines: Array<string> = [];\r\n\r\n        this.fillDefines(defines, blendMode);\r\n\r\n        // Effect\r\n        const currentRenderPassId = this._engine._features.supportRenderPasses ? this._engine.currentRenderPassId : Constants.RENDERPASS_MAIN;\r\n        const geometryRendering = MaterialHelperGeometryRendering._PrepareStringDefines(currentRenderPassId, defines);\r\n        const geometryRenderingConfiguration = geometryRendering ? MaterialHelperGeometryRendering.GetConfiguration(currentRenderPassId) : undefined;\r\n\r\n        let drawWrappers = this._drawWrappers[currentRenderPassId];\r\n        if (!drawWrappers) {\r\n            drawWrappers = this._drawWrappers[currentRenderPassId] = [];\r\n            if (currentRenderPassId !== Constants.RENDERPASS_MAIN && !this._renderPassObserver) {\r\n                this._renderPassObserver = (this._engine._onReleaseRenderPassObservable ??= new Observable<number>()).add((id) => {\r\n                    const releasedWrappers = this._drawWrappers[id];\r\n                    if (releasedWrappers) {\r\n                        for (const wrapper of releasedWrappers) {\r\n                            wrapper?.dispose();\r\n                        }\r\n                        delete this._drawWrappers[id];\r\n                    }\r\n                });\r\n            }\r\n        }\r\n        let drawWrapper = drawWrappers[blendMode];\r\n        if (!drawWrapper) {\r\n            drawWrapper = new DrawWrapper(this._engine);\r\n            if (drawWrapper.drawContext) {\r\n                drawWrapper.drawContext.useInstancing = true;\r\n            }\r\n            drawWrappers[blendMode] = drawWrapper;\r\n        }\r\n\r\n        const join = defines.join(\"\\n\");\r\n        if (drawWrapper.defines !== join) {\r\n            const attributes: Array<string> = [];\r\n            const uniforms: Array<string> = [];\r\n            const samplers: Array<string> = [];\r\n\r\n            this.fillUniformsAttributesAndSamplerNames(uniforms, attributes, samplers);\r\n            if (geometryRendering) {\r\n                uniforms.push(\"cameraInfo\", \"inverseEmitterWM\", \"objectId\", \"meshBlendTag\", \"geometryZeroAlphaDiscard\");\r\n            }\r\n\r\n            const shaderLanguage = this._engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n            drawWrapper.setEffect(\r\n                this._engine.createEffect(\r\n                    \"gpuRenderParticles\",\r\n                    <IEffectCreationOptions>{\r\n                        attributes,\r\n                        uniformsNames: uniforms,\r\n                        samplers,\r\n                        defines: join,\r\n                        shaderLanguage,\r\n                        multiTarget: geometryRendering,\r\n                        indexParameters: geometryRendering ? { buffersCount: geometryRenderingConfiguration?._mrtCount ?? 0 } : undefined,\r\n                        extraInitializationsAsync: this._renderShadersLoaded\r\n                            ? undefined\r\n                            : async () => {\r\n                                  if (shaderLanguage === ShaderLanguage.WGSL) {\r\n                                      await Promise.all([import(\"../ShadersWGSL/gpuRenderParticles.vertex\"), import(\"../ShadersWGSL/gpuRenderParticles.fragment\")]);\r\n                                  }\r\n\r\n                                  this._renderShadersLoaded = true;\r\n                              },\r\n                    },\r\n                    this._engine\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        return drawWrapper;\r\n    }\r\n\r\n    private _bindGeometryRendering(effect: Effect, emitterWM: Matrix): void {\r\n        const renderPassId = this._engine._features.supportRenderPasses ? this._engine.currentRenderPassId : Constants.RENDERPASS_MAIN;\r\n        const configuration = MaterialHelperGeometryRendering.GetConfiguration(renderPassId);\r\n        if (!configuration?._defines) {\r\n            return;\r\n        }\r\n\r\n        effect.setFloat(\"objectId\", 0);\r\n        effect.setInt(\"meshBlendTag\", 0);\r\n\r\n        const camera = this._scene?.activeCamera;\r\n        effect.setFloat2(\"cameraInfo\", camera?.minZ ?? 0, camera?.maxZ ?? 1);\r\n        if (this.isLocal) {\r\n            emitterWM.invertToRef(TmpVectors.Matrix[2]);\r\n            effect.setMatrix(\"inverseEmitterWM\", TmpVectors.Matrix[2]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _GetAttributeNamesOrOptions(\r\n        hasColorGradients = false,\r\n        isAnimationSheetEnabled = false,\r\n        isBillboardBased = false,\r\n        isBillboardStretched = false,\r\n        isBillboardStretchedLocal = false,\r\n        hasColorGradientColor2 = false\r\n    ): string[] {\r\n        const attributeNamesOrOptions = [VertexBuffer.PositionKind, \"age\", \"life\", \"size\", \"angle\"];\r\n\r\n        if (!hasColorGradients) {\r\n            attributeNamesOrOptions.push(VertexBuffer.ColorKind);\r\n        } else if (hasColorGradientColor2) {\r\n            // When packing a color1/color2 range into the gradient texture, the render shader needs the\r\n            // particle's persistent random seed to pick a stable per-particle mix factor.\r\n            attributeNamesOrOptions.push(\"seed\");\r\n        }\r\n\r\n        if (isAnimationSheetEnabled) {\r\n            attributeNamesOrOptions.push(\"cellIndex\");\r\n        }\r\n\r\n        if (!isBillboardBased || isBillboardStretchedLocal) {\r\n            attributeNamesOrOptions.push(\"initialDirection\");\r\n        }\r\n\r\n        if (isBillboardStretched) {\r\n            attributeNamesOrOptions.push(\"direction\");\r\n        }\r\n\r\n        attributeNamesOrOptions.push(\"offset\", VertexBuffer.UVKind);\r\n\r\n        return attributeNamesOrOptions;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _GetEffectCreationOptions(isAnimationSheetEnabled = false, useLogarithmicDepth = false, applyFog = false): string[] {\r\n        const effectCreationOption = [\"emitterWM\", \"worldOffset\", \"view\", \"projection\", \"colorDead\", \"invView\", \"translationPivot\", \"eyePosition\"];\r\n        AddClipPlaneUniforms(effectCreationOption);\r\n\r\n        if (isAnimationSheetEnabled) {\r\n            effectCreationOption.push(\"sheetInfos\");\r\n        }\r\n        if (useLogarithmicDepth) {\r\n            effectCreationOption.push(\"logarithmicDepthConstant\");\r\n        }\r\n\r\n        if (applyFog) {\r\n            effectCreationOption.push(\"vFogInfos\");\r\n            effectCreationOption.push(\"vFogColor\");\r\n        }\r\n\r\n        return effectCreationOption;\r\n    }\r\n\r\n    /**\r\n     * Fill the defines array according to the current settings of the particle system\r\n     * @param defines Array to be updated\r\n     * @param blendMode blend mode to take into account when updating the array\r\n     * @param fillImageProcessing fills the image processing defines\r\n     */\r\n    public fillDefines(defines: Array<string>, blendMode: number = 0, fillImageProcessing: boolean = true): void {\r\n        if (this._scene) {\r\n            PrepareStringDefinesForClipPlanes(this, this._scene, defines);\r\n            if (this.applyFog && this._scene.fogEnabled && this._scene.fogMode !== Scene.FOGMODE_NONE) {\r\n                defines.push(\"#define FOG\");\r\n            }\r\n        }\r\n\r\n        if (blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {\r\n            defines.push(\"#define BLENDMULTIPLYMODE\");\r\n        }\r\n\r\n        if (this.isLocal) {\r\n            defines.push(\"#define LOCAL\");\r\n        }\r\n\r\n        if (this.useLogarithmicDepth) {\r\n            defines.push(\"#define LOGARITHMICDEPTH\");\r\n        }\r\n\r\n        if (this._isBillboardBased) {\r\n            defines.push(\"#define BILLBOARD\");\r\n\r\n            switch (this.billboardMode) {\r\n                case ParticleSystem.BILLBOARDMODE_Y:\r\n                    defines.push(\"#define BILLBOARDY\");\r\n                    break;\r\n                case ParticleSystem.BILLBOARDMODE_STRETCHED:\r\n                    defines.push(\"#define BILLBOARDSTRETCHED\");\r\n                    break;\r\n                case ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL:\r\n                    defines.push(\"#define BILLBOARDSTRETCHED\");\r\n                    defines.push(\"#define BILLBOARDSTRETCHED_LOCAL\");\r\n                    break;\r\n                case ParticleSystem.BILLBOARDMODE_ALL:\r\n                    defines.push(\"#define BILLBOARDMODE_ALL\");\r\n                    break;\r\n                default:\r\n                    break;\r\n            }\r\n        }\r\n\r\n        if (this._colorGradientsTexture) {\r\n            defines.push(\"#define COLORGRADIENTS\");\r\n            if (this._hasColorGradientColor2) {\r\n                defines.push(\"#define COLORGRADIENTS_COLOR2\");\r\n            }\r\n        }\r\n\r\n        if (this.isAnimationSheetEnabled) {\r\n            defines.push(\"#define ANIMATESHEET\");\r\n        }\r\n\r\n        if (this.emitRateControl) {\r\n            defines.push(\"#define EMITRATECTRL\");\r\n        }\r\n\r\n        if (fillImageProcessing && this._imageProcessingConfiguration) {\r\n            this._imageProcessingConfiguration.prepareDefines(this._imageProcessingConfigurationDefines);\r\n            defines.push(\"\" + this._imageProcessingConfigurationDefines.toString());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Fill the uniforms, attributes and samplers arrays according to the current settings of the particle system\r\n     * @param uniforms Uniforms array to fill\r\n     * @param attributes Attributes array to fill\r\n     * @param samplers Samplers array to fill\r\n     */\r\n    public fillUniformsAttributesAndSamplerNames(uniforms: Array<string>, attributes: Array<string>, samplers: Array<string>) {\r\n        attributes.push(\r\n            ...GPUParticleSystem._GetAttributeNamesOrOptions(\r\n                !!this._colorGradientsTexture,\r\n                this._isAnimationSheetEnabled,\r\n                this._isBillboardBased,\r\n                this._isBillboardBased && (this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL),\r\n                this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED_LOCAL,\r\n                this._hasColorGradientColor2\r\n            )\r\n        );\r\n\r\n        uniforms.push(...GPUParticleSystem._GetEffectCreationOptions(this._isAnimationSheetEnabled, this.useLogarithmicDepth, this.applyFog));\r\n\r\n        samplers.push(\"diffuseSampler\", \"colorGradientSampler\");\r\n\r\n        if (this._imageProcessingConfiguration) {\r\n            ImageProcessingConfiguration.PrepareUniforms(uniforms, this._imageProcessingConfigurationDefines);\r\n            ImageProcessingConfiguration.PrepareSamplers(samplers, this._imageProcessingConfigurationDefines);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Animates the particle system for the current frame by emitting new particles and or animating the living ones.\r\n     * @param preWarm defines if we are in the pre-warmimg phase\r\n     */\r\n    public animate(preWarm = false): void {\r\n        this._timeDelta = this.updateSpeed * (preWarm ? this.preWarmStepOffset : this._scene?.getAnimationRatio() || 1);\r\n        this._actualFrame += this._timeDelta;\r\n\r\n        if (!this._stopped) {\r\n            if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration) {\r\n                this.stop();\r\n            }\r\n        }\r\n\r\n        if (this.updateInAnimate) {\r\n            this._update();\r\n        }\r\n    }\r\n\r\n    private _bakeFactorGradientData(factorGradients: IValueGradient[]): Float32Array {\r\n        const data = new Float32Array(this._rawTextureWidth * 2);\r\n\r\n        for (let x = 0; x < this._rawTextureWidth; x++) {\r\n            const ratio = x / this._rawTextureWidth;\r\n\r\n            GradientHelper.GetCurrentGradient(ratio, factorGradients, (currentGradient, nextGradient, scale) => {\r\n                const cg = currentGradient as FactorGradient;\r\n                const ng = nextGradient as FactorGradient;\r\n                data[x * 2] = Lerp(cg.factor1, ng.factor1, scale);\r\n                data[x * 2 + 1] = Lerp(cg.factor2 ?? cg.factor1, ng.factor2 ?? ng.factor1, scale);\r\n            });\r\n        }\r\n\r\n        return data;\r\n    }\r\n\r\n    /**\r\n     * Re-bakes an active factor gradient family's lookup texture pixels in place. The texture identity is\r\n     * preserved, so retained bindings (e.g. the WebGPU update compute shader's) stay valid and no buffer\r\n     * release is needed — the live particle pool survives the edit. The texture layout is independent of the\r\n     * number of stops (fixed _rawTextureWidth x 1), so any change within an active family can be re-baked.\r\n     * @param factorGradients defines the gradient family to bake\r\n     * @param textureName defines the name of the property holding the family's lookup texture\r\n     * @returns false when there is nothing to re-bake (no texture yet, or the family was emptied) — callers\r\n     * fall back to the dispose + release path.\r\n     */\r\n    private _rebakeFactorGradientTexture(factorGradients: Nullable<FactorGradient[]>, textureName: string): boolean {\r\n        const texture: Nullable<RawTexture> = (<any>this)[textureName];\r\n\r\n        if (!texture || !factorGradients || !factorGradients.length) {\r\n            return false;\r\n        }\r\n\r\n        texture.update(this._bakeFactorGradientData(factorGradients));\r\n\r\n        return true;\r\n    }\r\n\r\n    private _createFactorGradientTexture(factorGradients: Nullable<IValueGradient[]>, textureName: string) {\r\n        const texture: RawTexture = (<any>this)[textureName];\r\n\r\n        if (!factorGradients || !factorGradients.length || texture) {\r\n            return;\r\n        }\r\n\r\n        const data = this._bakeFactorGradientData(factorGradients);\r\n\r\n        (<any>this)[textureName] = new RawTexture(\r\n            data,\r\n            this._rawTextureWidth,\r\n            1,\r\n            Constants.TEXTUREFORMAT_RG,\r\n            this._scene || this._engine,\r\n            false,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            Constants.TEXTURETYPE_FLOAT\r\n        );\r\n        (<any>this)[textureName].name = textureName.substring(1);\r\n    }\r\n\r\n    private _createSizeGradientTexture() {\r\n        this._createFactorGradientTexture(this._sizeGradients, \"_sizeGradientsTexture\");\r\n    }\r\n\r\n    private _createAngularSpeedGradientTexture() {\r\n        this._createFactorGradientTexture(this._angularSpeedGradients, \"_angularSpeedGradientsTexture\");\r\n    }\r\n\r\n    private _createVelocityGradientTexture() {\r\n        this._createFactorGradientTexture(this._velocityGradients, \"_velocityGradientsTexture\");\r\n    }\r\n\r\n    private _createLimitVelocityGradientTexture() {\r\n        this._createFactorGradientTexture(this._limitVelocityGradients, \"_limitVelocityGradientsTexture\");\r\n    }\r\n\r\n    private _createDragGradientTexture() {\r\n        this._createFactorGradientTexture(this._dragGradients, \"_dragGradientsTexture\");\r\n    }\r\n\r\n    private _disposeMeshEmitterTextures() {\r\n        if (this._meshPositionTexture) {\r\n            this._meshPositionTexture.dispose();\r\n            this._meshPositionTexture = null;\r\n        }\r\n        if (this._meshNormalTexture) {\r\n            this._meshNormalTexture.dispose();\r\n            this._meshNormalTexture = null;\r\n        }\r\n        this._meshTriangleCount = 0;\r\n        this._meshTextureWidth = 0;\r\n        this._meshEmitterMeshId = -1;\r\n        this._meshEmitterUsedNormals = false;\r\n    }\r\n\r\n    private _createMeshEmitterTextures() {\r\n        if (!(this.particleEmitterType instanceof MeshParticleEmitter)) {\r\n            // Emitter type changed away from mesh — dispose stale textures\r\n            if (this._meshPositionTexture) {\r\n                this._disposeMeshEmitterTextures();\r\n            }\r\n            return;\r\n        }\r\n\r\n        const meshEmitter = this.particleEmitterType;\r\n        const mesh = meshEmitter.mesh;\r\n        if (!mesh) {\r\n            // Mesh removed — dispose stale textures\r\n            if (this._meshPositionTexture) {\r\n                this._disposeMeshEmitterTextures();\r\n            }\r\n            return;\r\n        }\r\n\r\n        const useNormals = meshEmitter.useMeshNormalsForDirection;\r\n\r\n        // Invalidate if the source mesh or normals usage changed\r\n        if (this._meshPositionTexture && (mesh.uniqueId !== this._meshEmitterMeshId || useNormals !== this._meshEmitterUsedNormals)) {\r\n            this._disposeMeshEmitterTextures();\r\n        }\r\n\r\n        // Already created and still valid\r\n        if (this._meshPositionTexture) {\r\n            return;\r\n        }\r\n\r\n        const positions = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const normals = mesh.getVerticesData(VertexBuffer.NormalKind);\r\n        const indices = mesh.getIndices();\r\n\r\n        if (!positions || !indices) {\r\n            return;\r\n        }\r\n\r\n        const triangleCount = indices.length / 3;\r\n        this._meshTriangleCount = triangleCount;\r\n\r\n        // Use a 2D texture layout so large meshes don't exceed maxTextureSize\r\n        const totalTexels = triangleCount * 3;\r\n        const maxTexSize = this._engine.getCaps().maxTextureSize;\r\n        const texWidth = Math.min(totalTexels, maxTexSize);\r\n        const texHeight = Math.ceil(totalTexels / texWidth);\r\n        this._meshTextureWidth = texWidth;\r\n\r\n        // Pack vertex positions: one texel per vertex, 3 vertices per triangle, RGBA float (xyz + padding)\r\n        const posData = new Float32Array(texWidth * texHeight * 4);\r\n        for (let t = 0; t < triangleCount; t++) {\r\n            const i0 = indices[t * 3];\r\n            const i1 = indices[t * 3 + 1];\r\n            const i2 = indices[t * 3 + 2];\r\n            const baseOffset = t * 3 * 4;\r\n            posData[baseOffset] = positions[i0 * 3];\r\n            posData[baseOffset + 1] = positions[i0 * 3 + 1];\r\n            posData[baseOffset + 2] = positions[i0 * 3 + 2];\r\n            posData[baseOffset + 3] = 0;\r\n            posData[baseOffset + 4] = positions[i1 * 3];\r\n            posData[baseOffset + 5] = positions[i1 * 3 + 1];\r\n            posData[baseOffset + 6] = positions[i1 * 3 + 2];\r\n            posData[baseOffset + 7] = 0;\r\n            posData[baseOffset + 8] = positions[i2 * 3];\r\n            posData[baseOffset + 9] = positions[i2 * 3 + 1];\r\n            posData[baseOffset + 10] = positions[i2 * 3 + 2];\r\n            posData[baseOffset + 11] = 0;\r\n        }\r\n\r\n        this._meshPositionTexture = new RawTexture(\r\n            posData,\r\n            texWidth,\r\n            texHeight,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            this._scene || this._engine,\r\n            false,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            Constants.TEXTURETYPE_FLOAT\r\n        );\r\n        this._meshPositionTexture.name = \"meshPositionTexture\";\r\n\r\n        // Pack normals the same way if available\r\n        if (normals && useNormals) {\r\n            const normData = new Float32Array(texWidth * texHeight * 4);\r\n            for (let t = 0; t < triangleCount; t++) {\r\n                const i0 = indices[t * 3];\r\n                const i1 = indices[t * 3 + 1];\r\n                const i2 = indices[t * 3 + 2];\r\n                const baseOffset = t * 3 * 4;\r\n                normData[baseOffset] = normals[i0 * 3];\r\n                normData[baseOffset + 1] = normals[i0 * 3 + 1];\r\n                normData[baseOffset + 2] = normals[i0 * 3 + 2];\r\n                normData[baseOffset + 3] = 0;\r\n                normData[baseOffset + 4] = normals[i1 * 3];\r\n                normData[baseOffset + 5] = normals[i1 * 3 + 1];\r\n                normData[baseOffset + 6] = normals[i1 * 3 + 2];\r\n                normData[baseOffset + 7] = 0;\r\n                normData[baseOffset + 8] = normals[i2 * 3];\r\n                normData[baseOffset + 9] = normals[i2 * 3 + 1];\r\n                normData[baseOffset + 10] = normals[i2 * 3 + 2];\r\n                normData[baseOffset + 11] = 0;\r\n            }\r\n\r\n            this._meshNormalTexture = new RawTexture(\r\n                normData,\r\n                texWidth,\r\n                texHeight,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                this._scene || this._engine,\r\n                false,\r\n                false,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                Constants.TEXTURETYPE_FLOAT\r\n            );\r\n            this._meshNormalTexture.name = \"meshNormalTexture\";\r\n        }\r\n\r\n        this._meshEmitterMeshId = mesh.uniqueId;\r\n        this._meshEmitterUsedNormals = useNormals;\r\n    }\r\n\r\n    private _bakeColorGradientData(height: number): Uint8Array {\r\n        const data = new Uint8Array(this._rawTextureWidth * 4 * height);\r\n        const tmpColor = TmpColors.Color4[0];\r\n\r\n        for (let x = 0; x < this._rawTextureWidth; x++) {\r\n            const ratio = x / this._rawTextureWidth;\r\n\r\n            GradientHelper.GetCurrentGradient(ratio, this._colorGradients!, (currentGradient, nextGradient, scale) => {\r\n                Color4.LerpToRef((<ColorGradient>currentGradient).color1, (<ColorGradient>nextGradient).color1, scale, tmpColor);\r\n                data[x * 4] = tmpColor.r * 255;\r\n                data[x * 4 + 1] = tmpColor.g * 255;\r\n                data[x * 4 + 2] = tmpColor.b * 255;\r\n                data[x * 4 + 3] = tmpColor.a * 255;\r\n            });\r\n        }\r\n\r\n        if (height === 2) {\r\n            const rowOffset = this._rawTextureWidth * 4;\r\n            for (let x = 0; x < this._rawTextureWidth; x++) {\r\n                const ratio = x / this._rawTextureWidth;\r\n\r\n                GradientHelper.GetCurrentGradient(ratio, this._colorGradients!, (currentGradient, nextGradient, scale) => {\r\n                    const cg = currentGradient as ColorGradient;\r\n                    const ng = nextGradient as ColorGradient;\r\n                    // Fall back to color1 for stops without a color2 so the row stays continuous.\r\n                    Color4.LerpToRef(cg.color2 ?? cg.color1, ng.color2 ?? ng.color1, scale, tmpColor);\r\n                    data[rowOffset + x * 4] = tmpColor.r * 255;\r\n                    data[rowOffset + x * 4 + 1] = tmpColor.g * 255;\r\n                    data[rowOffset + x * 4 + 2] = tmpColor.b * 255;\r\n                    data[rowOffset + x * 4 + 3] = tmpColor.a * 255;\r\n                });\r\n            }\r\n        }\r\n\r\n        return data;\r\n    }\r\n\r\n    /**\r\n     * Re-bakes the color gradient lookup texture pixels in place (same texture identity, so retained bindings —\r\n     * e.g. the WebGPU update compute shader's — stay valid and the live particle pool survives the edit). Only\r\n     * valid while the row layout is unchanged: a color2 range appearing or disappearing changes the texture\r\n     * height and the render vertex buffer layout, which must go through the structural dispose + release path.\r\n     * @returns false when the re-bake cannot handle the change (no texture yet, family emptied, or row layout flip)\r\n     */\r\n    private _rebakeColorGradientTexture(): boolean {\r\n        const texture = this._colorGradientsTexture;\r\n\r\n        if (!texture || !this._colorGradients || !this._colorGradients.length) {\r\n            return false;\r\n        }\r\n\r\n        const height = this._hasColorGradientColor2 ? 2 : 1;\r\n        if (texture.getSize().height !== height) {\r\n            return false;\r\n        }\r\n\r\n        texture.update(this._bakeColorGradientData(height));\r\n\r\n        return true;\r\n    }\r\n\r\n    private _createColorGradientTexture() {\r\n        if (!this._colorGradients || !this._colorGradients.length || this._colorGradientsTexture) {\r\n            return;\r\n        }\r\n\r\n        // When any stop has a color2, pack color1 into row 0 and color2 into row 1. The render shader\r\n        // samples both rows and lerps using the particle's persistent seed.x for per-particle randomness.\r\n        const height = this._hasColorGradientColor2 ? 2 : 1;\r\n        const data = this._bakeColorGradientData(height);\r\n\r\n        this._colorGradientsTexture = RawTexture.CreateRGBATexture(data, this._rawTextureWidth, height, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n        this._colorGradientsTexture.name = \"colorGradients\";\r\n    }\r\n\r\n    private _render(blendMode: number, emitterWM: Matrix): number {\r\n        // Enable render effect\r\n        const drawWrapper = this._getWrapper(blendMode);\r\n        const effect = drawWrapper.effect!;\r\n\r\n        this._engine.enableEffect(drawWrapper);\r\n        const viewMatrix = this._scene?.getViewMatrix() || Matrix.IdentityReadOnly;\r\n        effect.setMatrix(\"view\", viewMatrix);\r\n        const projectionMatrix = this.defaultProjectionMatrix ?? this._scene!.getProjectionMatrix();\r\n        effect.setMatrix(\"projection\", projectionMatrix);\r\n        effect.setTexture(\"diffuseSampler\", this.particleTexture);\r\n        effect.setVector2(\"translationPivot\", this.translationPivot);\r\n        const worldOffset = this.worldOffset.subtractToRef(this._scene?.floatingOriginOffset || Vector3.ZeroReadOnly, TmpVectors.Vector3[0]);\r\n        effect.setVector3(\"worldOffset\", worldOffset);\r\n        if (this.isLocal) {\r\n            effect.setMatrix(\"emitterWM\", emitterWM);\r\n        }\r\n        if (this._colorGradientsTexture) {\r\n            effect.setTexture(\"colorGradientSampler\", this._colorGradientsTexture);\r\n        } else {\r\n            effect.setDirectColor4(\"colorDead\", this.colorDead);\r\n        }\r\n\r\n        if (this._isAnimationSheetEnabled && this.particleTexture) {\r\n            const baseSize = this.particleTexture.getBaseSize();\r\n            effect.setFloat3(\"sheetInfos\", this.spriteCellWidth / baseSize.width, this.spriteCellHeight / baseSize.height, baseSize.width / this.spriteCellWidth);\r\n        }\r\n\r\n        if (this._isBillboardBased && this._scene) {\r\n            const camera = this._scene.activeCamera!;\r\n            effect.setVector3(\"eyePosition\", camera.globalPosition);\r\n        }\r\n\r\n        const defines = effect.defines;\r\n\r\n        if (this._scene) {\r\n            BindClipPlane(effect, this, this._scene);\r\n\r\n            if (this.applyFog) {\r\n                BindFogParameters(this._scene, undefined, effect);\r\n            }\r\n        }\r\n\r\n        if (defines.indexOf(\"#define BILLBOARDMODE_ALL\") >= 0) {\r\n            viewMatrix.invertToRef(TmpVectors.Matrix[1]);\r\n            effect.setMatrix(\"invView\", TmpVectors.Matrix[1]);\r\n        }\r\n\r\n        if (effect._multiTarget) {\r\n            this._bindGeometryRendering(effect, emitterWM);\r\n        }\r\n\r\n        // Log. depth\r\n        if (this.useLogarithmicDepth && this._scene) {\r\n            BindLogDepth(defines, effect, this._scene);\r\n        }\r\n\r\n        // image processing\r\n        if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {\r\n            this._imageProcessingConfiguration.bind(effect);\r\n        }\r\n\r\n        // Draw order\r\n        this._setEngineBasedOnBlendMode(blendMode);\r\n\r\n        if (effect._multiTarget) {\r\n            MaterialHelperGeometryRendering._BindZeroAlphaDiscard(this._engine, effect);\r\n        }\r\n        let rendered = false;\r\n        try {\r\n            if (MaterialHelperGeometryRendering._BindAttachmentsForEffect(this._engine, effect)) {\r\n                this._platform.bindDrawBuffers(this._targetIndex, effect, this._scene?.forceWireframe ? this._linesIndexBufferUseInstancing : null);\r\n\r\n                if (this._onBeforeDrawParticlesObservable) {\r\n                    this._onBeforeDrawParticlesObservable.notifyObservers(effect);\r\n                }\r\n\r\n                if (this._scene?.forceWireframe) {\r\n                    this._engine.drawElementsType(Constants.MATERIAL_LineStripDrawMode, 0, 10, this._currentActiveCount);\r\n                } else {\r\n                    this._engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, this._currentActiveCount);\r\n                }\r\n                rendered = true;\r\n            }\r\n        } finally {\r\n            MaterialHelperGeometryRendering._RestoreAttachments(this._engine);\r\n        }\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n        if (this._scene?.forceWireframe) {\r\n            this._engine.unbindInstanceAttributes();\r\n        }\r\n\r\n        return rendered ? this._currentActiveCount : 0;\r\n    }\r\n\r\n    /** @internal */\r\n    public _update(emitterWM?: Matrix): void {\r\n        if (!this.emitter || !this._targetBuffer) {\r\n            return;\r\n        }\r\n\r\n        if (!this._recreateUpdateEffect() || this._rebuildingAfterContextLost) {\r\n            return;\r\n        }\r\n\r\n        if (!emitterWM) {\r\n            if ((<AbstractMesh>this.emitter).position) {\r\n                const emitterMesh = <AbstractMesh>this.emitter;\r\n                emitterWM = emitterMesh.getWorldMatrix();\r\n            } else {\r\n                const emitterPosition = <Vector3>this.emitter;\r\n                emitterWM = TmpVectors.Matrix[0];\r\n                Matrix.TranslationToRef(emitterPosition.x, emitterPosition.y, emitterPosition.z, emitterWM);\r\n            }\r\n        }\r\n\r\n        const engine = this._engine as Engine;\r\n        const depthWriteState = engine.getDepthWrite();\r\n        engine.setDepthWrite(false);\r\n\r\n        this._platform.preUpdateParticleBuffer();\r\n\r\n        this._updateBuffer.setFloat(\"currentCount\", this._currentActiveCount);\r\n        this._updateBuffer.setFloat(\"timeDelta\", this._timeDelta);\r\n        this._updateBuffer.setFloat(\"stopFactor\", this._stopped ? 0 : 1);\r\n        this._updateBuffer.setFloat(\"emitIndex\", this._emitIndex);\r\n        this._updateBuffer.setFloat(\"emitCount\", this._emitCount);\r\n        this._updateBuffer.setInt(\"randomTextureSize\", this._randomTextureSize);\r\n        this._updateBuffer.setFloat2(\"lifeTime\", this.minLifeTime, this.maxLifeTime);\r\n        this._updateBuffer.setFloat2(\"emitPower\", this.minEmitPower, this.maxEmitPower);\r\n        if (!this._colorGradientsTexture) {\r\n            this._updateBuffer.setDirectColor4(\"color1\", this.color1);\r\n            this._updateBuffer.setDirectColor4(\"color2\", this.color2);\r\n        }\r\n        this._updateBuffer.setFloat2(\"sizeRange\", this.minSize, this.maxSize);\r\n        this._updateBuffer.setFloat4(\"scaleRange\", this.minScaleX, this.maxScaleX, this.minScaleY, this.maxScaleY);\r\n        this._updateBuffer.setFloat4(\"angleRange\", this.minAngularSpeed, this.maxAngularSpeed, this.minInitialRotation, this.maxInitialRotation);\r\n        this._updateBuffer.setVector3(\"gravity\", this.gravity);\r\n        if (this._limitVelocityGradientsTexture) {\r\n            this._updateBuffer.setFloat(\"limitVelocityDamping\", this.limitVelocityDamping);\r\n        }\r\n        if (this.particleEmitterType) {\r\n            this.particleEmitterType.applyToShader(this._updateBuffer);\r\n        }\r\n        if (this._isAnimationSheetEnabled) {\r\n            this._updateBuffer.setFloat4(\"cellInfos\", this.startSpriteCellID, this.endSpriteCellID, this.spriteCellChangeSpeed, this.spriteCellLoop ? 1 : 0);\r\n        }\r\n        if (this.noiseTexture) {\r\n            this._updateBuffer.setVector3(\"noiseStrength\", this.noiseStrength);\r\n        }\r\n        if (this._flowMap) {\r\n            const scene = this.getScene()!;\r\n            this._updateBuffer.setFloat(\"flowMapStrength\", this.flowMapStrength);\r\n            this._updateBuffer.setMatrix(\"flowMapProjection\", scene.getTransformMatrix());\r\n        }\r\n\r\n        if (!this.isLocal) {\r\n            this._updateBuffer.setMatrix(\"emitterWM\", emitterWM);\r\n        }\r\n\r\n        if (this._attractors.length > 0) {\r\n            this._updateBuffer.setInt(\"attractorCount\", this._attractors.length);\r\n\r\n            // Compute inverse world matrix once for all attractors when in local space\r\n            let invWorld: Matrix | undefined;\r\n            if (this.isLocal) {\r\n                invWorld = TmpVectors.Matrix[1];\r\n                emitterWM!.invertToRef(invWorld);\r\n            }\r\n\r\n            for (let i = 0; i < this._attractors.length; i++) {\r\n                const attractor = this._attractors[i];\r\n                const name = \"attractorPositionAndStrength[\" + i + \"]\";\r\n                if (invWorld) {\r\n                    const localPos = TmpVectors.Vector3[0];\r\n                    Vector3.TransformCoordinatesToRef(attractor.position, invWorld, localPos);\r\n                    this._updateBuffer.setFloat4(name, localPos.x, localPos.y, localPos.z, attractor.strength);\r\n                } else {\r\n                    this._updateBuffer.setFloat4(name, attractor.position.x, attractor.position.y, attractor.position.z, attractor.strength);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._startSizeGradients && this._startSizeGradients.length > 0) {\r\n            this._updateBuffer.setFloat(\"startSizeGradientFactor\", this._startSizeGradientFactor);\r\n        }\r\n\r\n        if (this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {\r\n            this._updateBuffer.setFloat2(\"lifeTimeGradientRange\", this._lifeTimeGradientMin, this._lifeTimeGradientMax);\r\n        }\r\n\r\n        if (this._meshPositionTexture) {\r\n            this._updateBuffer.setInt(\"meshTriangleCount\", this._meshTriangleCount);\r\n            this._updateBuffer.setInt(\"meshTextureWidth\", this._meshTextureWidth);\r\n        }\r\n\r\n        this._platform.updateParticleBuffer(this._targetIndex, this._targetBuffer, this._currentActiveCount);\r\n\r\n        // Switch VAOs\r\n        this._targetIndex++;\r\n        if (this._targetIndex === 2) {\r\n            this._targetIndex = 0;\r\n        }\r\n\r\n        // Switch buffers\r\n        const tmpBuffer = this._sourceBuffer;\r\n        this._sourceBuffer = this._targetBuffer;\r\n        this._targetBuffer = tmpBuffer;\r\n\r\n        engine.setDepthWrite(depthWriteState);\r\n    }\r\n\r\n    /**\r\n     * Renders the particle system in its current state\r\n     * @param preWarm defines if the system should only update the particles but not render them\r\n     * @param forceUpdateOnly if true, force to only update the particles and never display them (meaning, even if preWarm=false, when forceUpdateOnly=true the particles won't be displayed)\r\n     * @returns the current number of particles\r\n     */\r\n    public render(preWarm = false, forceUpdateOnly = false): number {\r\n        if (!this._started) {\r\n            return 0;\r\n        }\r\n\r\n        if (!this.isReady()) {\r\n            return 0;\r\n        }\r\n\r\n        if (!preWarm && this._scene) {\r\n            if (!this._preWarmDone && this.preWarmCycles) {\r\n                for (let index = 0; index < this.preWarmCycles; index++) {\r\n                    this.animate(true);\r\n                    this.render(true, true);\r\n                }\r\n\r\n                this._preWarmDone = true;\r\n            }\r\n\r\n            if (\r\n                this._currentRenderId === this._scene.getRenderId() &&\r\n                (!this._scene.activeCamera || (this._scene.activeCamera && this._currentRenderingCameraUniqueId === this._scene.activeCamera.uniqueId))\r\n            ) {\r\n                return 0;\r\n            }\r\n\r\n            this._currentRenderId = this._scene.getRenderId();\r\n            if (this._scene.activeCamera) {\r\n                this._currentRenderingCameraUniqueId = this._scene.activeCamera.uniqueId;\r\n            }\r\n        }\r\n\r\n        // Get everything ready to render\r\n        this._initialize();\r\n\r\n        // Compute effective emit rate, applying emit rate gradients if set\r\n        let effectiveEmitRate = this.emitRate;\r\n        if (this._emitRateGradients && this._emitRateGradients.length > 0 && this.targetStopDuration) {\r\n            const ratio = this._actualFrame / this.targetStopDuration;\r\n            GradientHelper.GetCurrentGradient(ratio, this._emitRateGradients, (currentGradient, nextGradient, scale) => {\r\n                if (currentGradient !== this._currentEmitRateGradient) {\r\n                    this._currentEmitRate1 = this._currentEmitRate2;\r\n                    this._currentEmitRate2 = (<FactorGradient>nextGradient).getFactor();\r\n                    this._currentEmitRateGradient = <FactorGradient>currentGradient;\r\n                }\r\n                effectiveEmitRate = Lerp(this._currentEmitRate1, this._currentEmitRate2, scale);\r\n            });\r\n        }\r\n\r\n        // Compute start size and life time gradient factors for shader uniforms\r\n        if (this.targetStopDuration) {\r\n            const ratio = this._actualFrame / this.targetStopDuration;\r\n\r\n            if (this._startSizeGradients && this._startSizeGradients.length > 0) {\r\n                GradientHelper.GetCurrentGradient(ratio, this._startSizeGradients, (currentGradient, nextGradient, scale) => {\r\n                    if (currentGradient !== this._currentStartSizeGradient) {\r\n                        this._currentStartSize1 = this._currentStartSize2;\r\n                        this._currentStartSize2 = (<FactorGradient>nextGradient).getFactor();\r\n                        this._currentStartSizeGradient = <FactorGradient>currentGradient;\r\n                    }\r\n                    this._startSizeGradientFactor = Lerp(this._currentStartSize1, this._currentStartSize2, scale);\r\n                });\r\n            } else {\r\n                this._startSizeGradientFactor = 1.0;\r\n            }\r\n\r\n            if (this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {\r\n                GradientHelper.GetCurrentGradient(ratio, this._lifeTimeGradients, (currentGradient, nextGradient, scale) => {\r\n                    const current = <FactorGradient>currentGradient;\r\n                    const next = <FactorGradient>nextGradient;\r\n                    this._lifeTimeGradientMin = Lerp(current.factor1, next.factor1, scale);\r\n                    this._lifeTimeGradientMax = Lerp(current.factor2 ?? current.factor1, next.factor2 ?? next.factor1, scale);\r\n                });\r\n            } else {\r\n                this._lifeTimeGradientMin = 1.0;\r\n                this._lifeTimeGradientMax = 1.0;\r\n            }\r\n        }\r\n\r\n        if (this.emitRateControl) {\r\n            // Emit-rate-controlled mode: limits active particles to ~emitRate * maxLifeTime,\r\n            // matching CPU particle behavior with circular buffer recycling.\r\n\r\n            // Accumulate fractional particles over time. Manual emit bypasses the rate.\r\n            if (this.manualEmitCount > -1) {\r\n                this._accumulatedCount += this.manualEmitCount;\r\n                this.manualEmitCount = 0;\r\n            } else if (!this._stopped) {\r\n                this._accumulatedCount += effectiveEmitRate * this._timeDelta;\r\n            }\r\n\r\n            // Convert accumulated fractional count into whole particles to emit this frame.\r\n            // The fractional remainder carries over to the next frame.\r\n            let newParticles = 0;\r\n            if (this._accumulatedCount >= 1) {\r\n                newParticles = this._accumulatedCount | 0;\r\n                this._accumulatedCount -= newParticles;\r\n            }\r\n\r\n            // The maximum number of particles that can be alive at once is bounded by\r\n            // emitRate * maxLifeTime (e.g. 1000 emit/s * 0.3s = 300 particles).\r\n            // This matches CPU particle system behavior and avoids filling the entire capacity.\r\n            // When emitRate is 0 but manualEmitCount is used, the rate-based steady state\r\n            // would be 0, blocking buffer growth. Use newParticles as a floor so manual\r\n            // emissions can always allocate slots.\r\n            const steadyStateCount = Math.min(Math.max(Math.ceil(effectiveEmitRate * this.maxLifeTime), newParticles), this._maxActiveParticleCount);\r\n\r\n            // During ramp-up, grow the active buffer size by adding new slots.\r\n            // Once _currentActiveCount reaches steadyStateCount, no new slots are added —\r\n            // existing slots are recycled instead (handled by _emitIndex below).\r\n            if (this._currentActiveCount < steadyStateCount && newParticles > 0) {\r\n                const growth = Math.min(newParticles, steadyStateCount - this._currentActiveCount);\r\n                this._currentActiveCount += growth;\r\n            }\r\n\r\n            // Tell the update shader which particle slots to (re)initialize this frame.\r\n            // _emitIndex is where the circular write pointer starts in the buffer,\r\n            // _emitCount is how many consecutive slots to reinitialize (with wrapping).\r\n            // The shader checks each particle's index against this range to decide\r\n            // whether to recycle it (emit branch) or advance its simulation (update branch).\r\n            if (this._currentActiveCount > 0 && newParticles > 0) {\r\n                this._emitCount = Math.min(newParticles, this._currentActiveCount);\r\n                this._emitIndex = this._writePointer % this._currentActiveCount;\r\n                this._writePointer += this._emitCount;\r\n            } else {\r\n                this._emitCount = 0;\r\n            }\r\n        } else {\r\n            // Legacy mode: dead particles recycle immediately, filling up to capacity.\r\n            if (this.manualEmitCount > -1) {\r\n                this._accumulatedCount += this.manualEmitCount;\r\n                this.manualEmitCount = 0;\r\n            } else {\r\n                this._accumulatedCount += effectiveEmitRate * this._timeDelta;\r\n            }\r\n            if (this._accumulatedCount >= 1) {\r\n                const intPart = this._accumulatedCount | 0;\r\n                this._accumulatedCount -= intPart;\r\n                this._currentActiveCount += intPart;\r\n            }\r\n\r\n            this._currentActiveCount = Math.min(this._maxActiveParticleCount, this._currentActiveCount);\r\n            this._emitIndex = 0;\r\n            this._emitCount = 0;\r\n        }\r\n\r\n        if (!this._currentActiveCount) {\r\n            return 0;\r\n        }\r\n\r\n        // Enable update effect\r\n        let emitterWM: Matrix;\r\n        if ((<AbstractMesh>this.emitter).position) {\r\n            const emitterMesh = <AbstractMesh>this.emitter;\r\n            emitterWM = emitterMesh.getWorldMatrix();\r\n        } else {\r\n            const emitterPosition = <Vector3>this.emitter;\r\n            emitterWM = TmpVectors.Matrix[0];\r\n            Matrix.TranslationToRef(emitterPosition.x, emitterPosition.y, emitterPosition.z, emitterWM);\r\n        }\r\n\r\n        const engine = this._engine as Engine;\r\n\r\n        if (!this.updateInAnimate) {\r\n            this._update(emitterWM);\r\n        }\r\n\r\n        let outparticles = 0;\r\n        if (!preWarm && !forceUpdateOnly) {\r\n            engine.setState(false);\r\n\r\n            if (this.forceDepthWrite) {\r\n                engine.setDepthWrite(true);\r\n            }\r\n\r\n            if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLYADD) {\r\n                outparticles = this._render(ParticleSystem.BLENDMODE_MULTIPLY, emitterWM) + this._render(ParticleSystem.BLENDMODE_ADD, emitterWM);\r\n            } else {\r\n                outparticles = this._render(this.blendMode, emitterWM);\r\n            }\r\n\r\n            this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        }\r\n\r\n        return outparticles;\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the particle system\r\n     */\r\n    public rebuild(): void {\r\n        const checkUpdateEffect = () => {\r\n            if (!this._recreateUpdateEffect() || !this._platform.isUpdateBufferReady()) {\r\n                setTimeout(checkUpdateEffect, 10);\r\n            } else {\r\n                this._initialize(true);\r\n                this._rebuildingAfterContextLost = false;\r\n            }\r\n        };\r\n\r\n        this._createIndexBuffer();\r\n\r\n        this._cachedUpdateDefines = \"\";\r\n\r\n        // Re-upload mesh emitter data if the mesh geometry changed\r\n        this._disposeMeshEmitterTextures();\r\n\r\n        this._platform.contextLost();\r\n        this._rebuildingAfterContextLost = true;\r\n\r\n        checkUpdateEffect();\r\n    }\r\n\r\n    private _releaseBuffers() {\r\n        if (this._buffer0) {\r\n            this._buffer0.dispose();\r\n            (<any>this._buffer0) = null;\r\n        }\r\n        if (this._buffer1) {\r\n            this._buffer1.dispose();\r\n            (<any>this._buffer1) = null;\r\n        }\r\n        if (this._spriteBuffer) {\r\n            this._spriteBuffer.dispose();\r\n            (<any>this._spriteBuffer) = null;\r\n        }\r\n        this._platform.releaseBuffers();\r\n    }\r\n\r\n    /**\r\n     * Disposes the particle system and free the associated resources\r\n     * @param disposeTexture defines if the particule texture must be disposed as well (true by default)\r\n     */\r\n    public dispose(disposeTexture = true): void {\r\n        this._engine._onReleaseRenderPassObservable?.remove(this._renderPassObserver);\r\n        this._renderPassObserver = null;\r\n        for (const drawWrappers of this._drawWrappers) {\r\n            if (!drawWrappers) {\r\n                continue;\r\n            }\r\n            for (const drawWrapper of drawWrappers) {\r\n                drawWrapper?.dispose();\r\n            }\r\n        }\r\n\r\n        this._drawWrappers = [];\r\n\r\n        if (this._scene) {\r\n            const index = this._scene.particleSystems.indexOf(this);\r\n            if (index > -1) {\r\n                this._scene.particleSystems.splice(index, 1);\r\n            }\r\n        }\r\n\r\n        this._releaseBuffers();\r\n        this._platform.releaseVertexBuffers();\r\n\r\n        for (let i = 0; i < this._renderVertexBuffers.length; ++i) {\r\n            const rvb = this._renderVertexBuffers[i];\r\n            for (const key in rvb) {\r\n                rvb[key].dispose();\r\n            }\r\n        }\r\n\r\n        this._renderVertexBuffers = [];\r\n\r\n        if (this._colorGradientsTexture) {\r\n            this._colorGradientsTexture.dispose();\r\n            (<any>this._colorGradientsTexture) = null;\r\n        }\r\n\r\n        if (this._sizeGradientsTexture) {\r\n            this._sizeGradientsTexture.dispose();\r\n            (<any>this._sizeGradientsTexture) = null;\r\n        }\r\n\r\n        if (this._angularSpeedGradientsTexture) {\r\n            this._angularSpeedGradientsTexture.dispose();\r\n            (<any>this._angularSpeedGradientsTexture) = null;\r\n        }\r\n\r\n        if (this._velocityGradientsTexture) {\r\n            this._velocityGradientsTexture.dispose();\r\n            (<any>this._velocityGradientsTexture) = null;\r\n        }\r\n\r\n        if (this._limitVelocityGradientsTexture) {\r\n            this._limitVelocityGradientsTexture.dispose();\r\n            (<any>this._limitVelocityGradientsTexture) = null;\r\n        }\r\n\r\n        if (this._dragGradientsTexture) {\r\n            this._dragGradientsTexture.dispose();\r\n            (<any>this._dragGradientsTexture) = null;\r\n        }\r\n\r\n        this._disposeMeshEmitterTextures();\r\n\r\n        if (this._randomTexture) {\r\n            this._randomTexture.dispose();\r\n            (<any>this._randomTexture) = null;\r\n        }\r\n\r\n        if (this._randomTexture2) {\r\n            this._randomTexture2.dispose();\r\n            (<any>this._randomTexture2) = null;\r\n        }\r\n\r\n        if (disposeTexture && this.particleTexture) {\r\n            this.particleTexture.dispose();\r\n            this.particleTexture = null;\r\n        }\r\n\r\n        if (disposeTexture && this.noiseTexture) {\r\n            this.noiseTexture.dispose();\r\n            this.noiseTexture = null;\r\n        }\r\n\r\n        if (disposeTexture && this._flowMap) {\r\n            this._flowMap.dispose();\r\n            this._flowMap = null;\r\n        }\r\n\r\n        // Callback\r\n        this.onStoppedObservable.clear();\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n    }\r\n    /**\r\n     * Clones the particle system.\r\n     * @param name The name of the cloned object\r\n     * @param newEmitter The new emitter to use\r\n     * @param cloneTexture Also clone the textures if true\r\n     * @returns the cloned particle system\r\n     */\r\n    public clone(name: string, newEmitter: any, cloneTexture = false): GPUParticleSystem {\r\n        const custom = { ...this._customWrappers };\r\n        let program: any = null;\r\n        const engine = this._engine as any;\r\n        if (_IsSideEffectImplemented(engine.createEffectForParticles)) {\r\n            if (this.customShader != null) {\r\n                program = this.customShader;\r\n                const defines: string = program.shaderOptions.defines.length > 0 ? program.shaderOptions.defines.join(\"\\n\") : \"\";\r\n                custom[0] = engine.createEffectForParticles(\r\n                    program.shaderPath.fragmentElement,\r\n                    program.shaderOptions.uniforms,\r\n                    program.shaderOptions.samplers,\r\n                    defines,\r\n                    undefined,\r\n                    undefined,\r\n                    undefined,\r\n                    this\r\n                );\r\n            }\r\n        }\r\n\r\n        const serialization = this.serialize(cloneTexture);\r\n        // When the texture is not serialized it is stored by name only, and Parse would reload it from\r\n        // that name (which can resolve to a different image and reset texture settings like level).\r\n        // Prefer a faithful copy of the source texture, and only skip the name-based reload when that\r\n        // copy is available (clone() can legally return null for textures that do not implement it).\r\n        const clonedTexture = cloneTexture === false && this.particleTexture ? this.particleTexture.clone() : null;\r\n        if (clonedTexture) {\r\n            serialization.textureName = undefined;\r\n        }\r\n        const result = GPUParticleSystem.Parse(serialization, this._scene || this._engine, this._rootUrl);\r\n        result.name = name;\r\n        result.customShader = program;\r\n        result._customWrappers = custom;\r\n\r\n        if (clonedTexture) {\r\n            result.particleTexture = clonedTexture;\r\n        }\r\n\r\n        if (newEmitter === undefined) {\r\n            newEmitter = this.emitter;\r\n        }\r\n\r\n        if (this.noiseTexture) {\r\n            result.noiseTexture = this.noiseTexture.clone();\r\n        }\r\n\r\n        result.emitter = newEmitter;\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Creates a new GPUParticleSystem from an existing CPU ParticleSystem, copying all shared properties.\r\n     * Features that are not supported on the GPU (sub-emitters, custom `startDirectionFunction` /\r\n     * `startPositionFunction`, `customShader`, ramp/remap gradients) are logged as warnings and skipped.\r\n     * Flow maps are converted: the CPU `FlowMap` image data is uploaded to a new `RawTexture` which is\r\n     * assigned to the result.\r\n     *\r\n     * Note: a custom `updateFunction` on the source cannot be detected (the property is always assigned\r\n     * to a default) and has no equivalent on the GPU path, so any custom per-frame update logic will be\r\n     * silently dropped.\r\n     *\r\n     * Textures (particleTexture, noiseTexture) are shared by reference between the source and the result.\r\n     * All other mutable state (colors, vectors, emitter type, gradients, attractors) is cloned so that\r\n     * the two systems can be modified independently after the call.\r\n     *\r\n     * Note: unlike the GPUParticleSystem constructor, `emitRateControl` defaults to `true` here so that\r\n     * changes to `emitRate` on the converted system behave the same as on the CPU source. Pass\r\n     * `{ emitRateControl: false }` explicitly to opt out.\r\n     * @param source The CPU ParticleSystem to convert\r\n     * @param sceneOrEngine The scene or engine the new GPU particle system belongs to\r\n     * @param options Optional options forwarded to the new GPU particle system (capacity, randomTextureSize, emitRateControl, maxAttractors). `capacity` defaults to the source capacity and `emitRateControl` defaults to `true`.\r\n     * @returns A new GPUParticleSystem with shared properties copied from the source\r\n     */\r\n    public static fromParticleSystem(\r\n        source: ParticleSystem,\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        options?: Partial<{\r\n            capacity: number;\r\n            randomTextureSize: number;\r\n            emitRateControl: boolean;\r\n            maxAttractors: number;\r\n        }>\r\n    ): GPUParticleSystem {\r\n        // Warn on features that cannot be represented on a GPU particle system.\r\n        if (source.subEmitters && source.subEmitters.length > 0) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'subEmitters' is not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n        if (source.startDirectionFunction) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'startDirectionFunction' is not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n        if (source.startPositionFunction) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'startPositionFunction' is not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n        if (source.customShader) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'customShader' is not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n        const sourceRampGradients = source.getRampGradients();\r\n        if (sourceRampGradients && sourceRampGradients.length > 0) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'rampGradients' are not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n        const sourceColorRemapGradients = source.getColorRemapGradients();\r\n        if (sourceColorRemapGradients && sourceColorRemapGradients.length > 0) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'colorRemapGradients' are not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n        const sourceAlphaRemapGradients = source.getAlphaRemapGradients();\r\n        if (sourceAlphaRemapGradients && sourceAlphaRemapGradients.length > 0) {\r\n            Logger.Warn(\"GPUParticleSystem.fromParticleSystem: 'alphaRemapGradients' are not supported on GPUParticleSystem and will be skipped.\");\r\n        }\r\n\r\n        const capacity = options?.capacity ?? source.getCapacity();\r\n        const gpuOptions: Partial<{ capacity: number; randomTextureSize: number; emitRateControl: boolean; maxAttractors: number }> = { capacity };\r\n        if (options?.randomTextureSize !== undefined) {\r\n            gpuOptions.randomTextureSize = options.randomTextureSize;\r\n        }\r\n        // Default emitRateControl to true here: on a freshly constructed GPUParticleSystem the default is\r\n        // false for backwards compatibility, but when converting an existing CPU system users expect\r\n        // changes to emitRate to take effect — matching CPU behavior.\r\n        gpuOptions.emitRateControl = options?.emitRateControl ?? true;\r\n        if (options?.maxAttractors !== undefined) {\r\n            gpuOptions.maxAttractors = options.maxAttractors;\r\n        }\r\n\r\n        const gpu = new GPUParticleSystem(source.name + \" (GPU)\", gpuOptions, sceneOrEngine, null, source.isAnimationSheetEnabled);\r\n\r\n        gpu.id = source.id;\r\n\r\n        // Emitter (shared by reference: mesh or Vector3 — users expect both systems to follow the same source).\r\n        gpu.emitter = source.emitter;\r\n\r\n        // Emitter type — cloned for independence.\r\n        if (source.particleEmitterType) {\r\n            gpu.particleEmitterType = source.particleEmitterType.clone();\r\n        }\r\n\r\n        // Textures — shared by reference.\r\n        gpu.particleTexture = source.particleTexture;\r\n        if (source.noiseTexture) {\r\n            gpu.noiseTexture = source.noiseTexture;\r\n        }\r\n\r\n        // Colors.\r\n        gpu.color1 = source.color1.clone();\r\n        gpu.color2 = source.color2.clone();\r\n        gpu.colorDead = source.colorDead.clone();\r\n        gpu.textureMask = source.textureMask.clone();\r\n\r\n        // Sizes.\r\n        gpu.minSize = source.minSize;\r\n        gpu.maxSize = source.maxSize;\r\n        gpu.minScaleX = source.minScaleX;\r\n        gpu.maxScaleX = source.maxScaleX;\r\n        gpu.minScaleY = source.minScaleY;\r\n        gpu.maxScaleY = source.maxScaleY;\r\n\r\n        // Speeds / rotation.\r\n        gpu.minEmitPower = source.minEmitPower;\r\n        gpu.maxEmitPower = source.maxEmitPower;\r\n        gpu.minAngularSpeed = source.minAngularSpeed;\r\n        gpu.maxAngularSpeed = source.maxAngularSpeed;\r\n        gpu.minInitialRotation = source.minInitialRotation;\r\n        gpu.maxInitialRotation = source.maxInitialRotation;\r\n\r\n        // Lifetime.\r\n        gpu.minLifeTime = source.minLifeTime;\r\n        gpu.maxLifeTime = source.maxLifeTime;\r\n\r\n        // Emission.\r\n        gpu.emitRate = source.emitRate;\r\n        gpu.manualEmitCount = source.manualEmitCount;\r\n\r\n        // Physics.\r\n        gpu.gravity = source.gravity.clone();\r\n        gpu.limitVelocityDamping = source.limitVelocityDamping;\r\n\r\n        // Rendering.\r\n        gpu.blendMode = source.blendMode;\r\n        gpu.billboardMode = source.billboardMode;\r\n        gpu.isBillboardBased = source.isBillboardBased;\r\n        gpu.forceDepthWrite = source.forceDepthWrite;\r\n        gpu.useLogarithmicDepth = source.useLogarithmicDepth;\r\n        gpu.renderingGroupId = source.renderingGroupId;\r\n        gpu.layerMask = source.layerMask;\r\n\r\n        // Animation sheet.\r\n        gpu.startSpriteCellID = source.startSpriteCellID;\r\n        gpu.endSpriteCellID = source.endSpriteCellID;\r\n        gpu.spriteCellWidth = source.spriteCellWidth;\r\n        gpu.spriteCellHeight = source.spriteCellHeight;\r\n        gpu.spriteCellChangeSpeed = source.spriteCellChangeSpeed;\r\n        gpu.spriteCellLoop = source.spriteCellLoop;\r\n        gpu.spriteRandomStartCell = source.spriteRandomStartCell;\r\n\r\n        // Space.\r\n        gpu.isLocal = source.isLocal;\r\n        gpu.worldOffset = source.worldOffset.clone();\r\n        gpu.translationPivot = source.translationPivot.clone();\r\n\r\n        // Lifecycle.\r\n        gpu.targetStopDuration = source.targetStopDuration;\r\n        gpu.disposeOnStop = source.disposeOnStop;\r\n        gpu.startDelay = source.startDelay;\r\n        gpu.preWarmCycles = source.preWarmCycles;\r\n        gpu.preWarmStepOffset = source.preWarmStepOffset;\r\n        gpu.updateSpeed = source.updateSpeed;\r\n        gpu.preventAutoStart = source.preventAutoStart;\r\n\r\n        // Animations (shared by reference, matching the rest of the scene-graph convention).\r\n        gpu.animations = source.animations;\r\n        gpu.beginAnimationOnStart = source.beginAnimationOnStart;\r\n        gpu.beginAnimationFrom = source.beginAnimationFrom;\r\n        gpu.beginAnimationTo = source.beginAnimationTo;\r\n        gpu.beginAnimationLoop = source.beginAnimationLoop;\r\n\r\n        // Noise.\r\n        gpu.noiseStrength = source.noiseStrength.clone();\r\n\r\n        // Flow map — convert the CPU FlowMap (JS-side image data) into a RawTexture for GPU sampling.\r\n        // The CPU FlowMap stores image data top-left origin and flips V in its sampler; to get the\r\n        // same orientation under the GPU shader's non-flipped sampling, the uploaded texture needs invertY=true.\r\n        if (source.flowMap) {\r\n            const sourceFlowMap = source.flowMap;\r\n            const flowTexture = new RawTexture(\r\n                new Uint8Array(sourceFlowMap.data.buffer, sourceFlowMap.data.byteOffset, sourceFlowMap.data.byteLength),\r\n                sourceFlowMap.width,\r\n                sourceFlowMap.height,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                sceneOrEngine,\r\n                false,\r\n                true,\r\n                Constants.TEXTURE_BILINEAR_SAMPLINGMODE\r\n            );\r\n            gpu.flowMap = flowTexture;\r\n            gpu.flowMapStrength = source.flowMapStrength;\r\n        }\r\n\r\n        // Gradients.\r\n        const colorGradients = source.getColorGradients();\r\n        if (colorGradients) {\r\n            for (const g of colorGradients) {\r\n                gpu.addColorGradient(g.gradient, g.color1.clone(), g.color2?.clone());\r\n            }\r\n        }\r\n\r\n        const sizeGradients = source.getSizeGradients();\r\n        if (sizeGradients) {\r\n            for (const g of sizeGradients) {\r\n                gpu.addSizeGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const angularSpeedGradients = source.getAngularSpeedGradients();\r\n        if (angularSpeedGradients) {\r\n            for (const g of angularSpeedGradients) {\r\n                gpu.addAngularSpeedGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const velocityGradients = source.getVelocityGradients();\r\n        if (velocityGradients) {\r\n            for (const g of velocityGradients) {\r\n                gpu.addVelocityGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const limitVelocityGradients = source.getLimitVelocityGradients();\r\n        if (limitVelocityGradients) {\r\n            for (const g of limitVelocityGradients) {\r\n                gpu.addLimitVelocityGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const dragGradients = source.getDragGradients();\r\n        if (dragGradients) {\r\n            for (const g of dragGradients) {\r\n                gpu.addDragGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const emitRateGradients = source.getEmitRateGradients();\r\n        if (emitRateGradients) {\r\n            for (const g of emitRateGradients) {\r\n                gpu.addEmitRateGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const startSizeGradients = source.getStartSizeGradients();\r\n        if (startSizeGradients) {\r\n            for (const g of startSizeGradients) {\r\n                gpu.addStartSizeGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        const lifeTimeGradients = source.getLifeTimeGradients();\r\n        if (lifeTimeGradients) {\r\n            for (const g of lifeTimeGradients) {\r\n                gpu.addLifeTimeGradient(g.gradient, g.factor1, g.factor2);\r\n            }\r\n        }\r\n\r\n        // Attractors — cloned.\r\n        for (const attractor of source.attractors) {\r\n            const newAttractor = new Attractor();\r\n            newAttractor.position = attractor.position.clone();\r\n            newAttractor.strength = attractor.strength;\r\n            gpu.addAttractor(newAttractor);\r\n        }\r\n\r\n        return gpu;\r\n    }\r\n\r\n    /**\r\n     * Serializes the particle system to a JSON object\r\n     * @param serializeTexture defines if the texture must be serialized as well\r\n     * @returns the JSON object\r\n     */\r\n    public serialize(serializeTexture = false): any {\r\n        const serializationObject: any = {};\r\n\r\n        ParticleSystem._Serialize(serializationObject, this, serializeTexture);\r\n\r\n        serializationObject.activeParticleCount = this.activeParticleCount;\r\n        serializationObject.randomTextureSize = this._randomTextureSize;\r\n        serializationObject.emitRateControl = this.emitRateControl;\r\n        serializationObject.maxAttractors = this.maxAttractors;\r\n        serializationObject.customShader = this.customShader;\r\n\r\n        serializationObject.preventAutoStart = this.preventAutoStart;\r\n        serializationObject.worldOffset = this.worldOffset.asArray();\r\n\r\n        if (this.metadata) {\r\n            serializationObject.metadata = this.metadata;\r\n        }\r\n\r\n        // Attractors\r\n        if (this._attractors.length > 0) {\r\n            serializationObject.attractors = [];\r\n            for (const attractor of this._attractors) {\r\n                serializationObject.attractors.push(attractor.serialize());\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Parses a JSON object to create a GPU particle system.\r\n     * @param parsedParticleSystem The JSON object to parse\r\n     * @param sceneOrEngine The scene or the engine to create the particle system in\r\n     * @param rootUrl The root url to use to load external dependencies like texture\r\n     * @param doNotStart Ignore the preventAutoStart attribute and does not start\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns the parsed GPU particle system\r\n     */\r\n    public static Parse(parsedParticleSystem: any, sceneOrEngine: Scene | AbstractEngine, rootUrl: string, doNotStart = false, capacity?: number): GPUParticleSystem {\r\n        const name = parsedParticleSystem.name;\r\n        let engine: AbstractEngine;\r\n        let scene: Nullable<Scene>;\r\n\r\n        if (sceneOrEngine instanceof AbstractEngine) {\r\n            engine = sceneOrEngine;\r\n        } else {\r\n            scene = sceneOrEngine;\r\n            engine = scene.getEngine();\r\n        }\r\n\r\n        const particleSystem = new GPUParticleSystem(\r\n            name,\r\n            {\r\n                capacity: capacity || parsedParticleSystem.capacity,\r\n                randomTextureSize: parsedParticleSystem.randomTextureSize,\r\n                emitRateControl: parsedParticleSystem.emitRateControl,\r\n                maxAttractors: parsedParticleSystem.maxAttractors,\r\n            },\r\n            sceneOrEngine,\r\n            null,\r\n            parsedParticleSystem.isAnimationSheetEnabled\r\n        );\r\n        particleSystem._rootUrl = rootUrl;\r\n\r\n        if (parsedParticleSystem.customShader && _IsSideEffectImplemented((engine as any).createEffectForParticles)) {\r\n            const program = parsedParticleSystem.customShader;\r\n            const defines: string = program.shaderOptions.defines.length > 0 ? program.shaderOptions.defines.join(\"\\n\") : \"\";\r\n            const custom: Nullable<Effect> = (engine as any).createEffectForParticles(\r\n                program.shaderPath.fragmentElement,\r\n                program.shaderOptions.uniforms,\r\n                program.shaderOptions.samplers,\r\n                defines,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                particleSystem\r\n            );\r\n            particleSystem.setCustomEffect(custom, 0);\r\n            particleSystem.customShader = program;\r\n        }\r\n\r\n        if (parsedParticleSystem.id) {\r\n            particleSystem.id = parsedParticleSystem.id;\r\n        }\r\n\r\n        if (parsedParticleSystem.activeParticleCount) {\r\n            particleSystem.activeParticleCount = parsedParticleSystem.activeParticleCount;\r\n        }\r\n\r\n        ParticleSystem._Parse(parsedParticleSystem, particleSystem, sceneOrEngine, rootUrl);\r\n\r\n        if (parsedParticleSystem.worldOffset) {\r\n            particleSystem.worldOffset = Vector3.FromArray(parsedParticleSystem.worldOffset);\r\n        }\r\n\r\n        // Auto start\r\n        if (parsedParticleSystem.preventAutoStart) {\r\n            particleSystem.preventAutoStart = parsedParticleSystem.preventAutoStart;\r\n        }\r\n\r\n        if (parsedParticleSystem.metadata) {\r\n            particleSystem.metadata = parsedParticleSystem.metadata;\r\n        }\r\n\r\n        // Attractors\r\n        if (parsedParticleSystem.attractors) {\r\n            for (const attractorData of parsedParticleSystem.attractors) {\r\n                const attractor = new Attractor();\r\n                attractor.position = Vector3.FromArray(attractorData.position);\r\n                attractor.strength = attractorData.strength;\r\n                particleSystem.addAttractor(attractor);\r\n            }\r\n        }\r\n\r\n        if (!doNotStart && !particleSystem.preventAutoStart) {\r\n            particleSystem.start();\r\n        }\r\n\r\n        return particleSystem;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneFragmentDeclaration2\";\nconst shader = `#ifdef CLIPPLANE\nin float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nin float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nin float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nin float fClipDistance4;\n#endif\n#ifdef CLIPPLANE5\nin float fClipDistance5;\n#endif\n#ifdef CLIPPLANE6\nin float fClipDistance6;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clipPlaneFragmentDeclaration2 = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"geometryRenderingFragment\";\nconst shader = `#ifdef PREPASS\n#if SCENE_MRT_COUNT>0\nfloat geometryCoverage=geometryColor.a>0.4 ? 1.0 : 0.0;\n#ifdef PREPASS_COLOR\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_COLOR_INDEX,geometryColor);\n#endif\n#ifdef PREPASS_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_POSITION_INDEX,vec4(geometryPositionW,geometryCoverage));\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_LOCAL_POSITION_INDEX,vec4(geometryPositionL,geometryCoverage));\n#endif\n#ifdef PREPASS_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_DEPTH_INDEX,vec4(geometryViewDepth,0.0,0.0,geometryCoverage));\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMALIZED_VIEW_DEPTH_INDEX,vec4(geometryNormalizedViewDepth,0.0,0.0,geometryCoverage));\n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_SCREENSPACE_DEPTH_INDEX,vec4(gl_FragCoord.z,0.0,0.0,geometryCoverage));\n#endif\n#ifdef PREPASS_NORMAL\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_NORMAL_INDEX,vec4(geometryNormalV,geometryCoverage));\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_WORLD_NORMAL_INDEX,vec4(geometryNormalW*0.5+0.5,geometryCoverage));\n#endif\n#ifdef PREPASS_ALBEDO\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_INDEX,vec4(geometryAlbedo,geometryCoverage));\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_ALBEDO_SQRT_INDEX,vec4(sqrt(max(geometryAlbedo,vec3(0.0))),geometryCoverage));\n#endif\n#ifdef PREPASS_REFLECTIVITY\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_REFLECTIVITY_INDEX,vec4(0.0,0.0,0.0,geometryCoverage));\n#endif\n#ifdef PREPASS_IRRADIANCE\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_IRRADIANCE_INDEX,vec4(0.0,0.0,0.0,geometryCoverage));\n#endif\n#ifdef PREPASS_IRRADIANCE_LEGACY\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_IRRADIANCE_LEGACY_INDEX,vec4(0.0));\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\n#ifdef PREPASS_VELOCITY_ZERO\nvec2 geometryMotion=vec2(0.0);\n#else\nvec2 geometryMotion=0.5*(geometryCurrentPosition.xy/geometryCurrentPosition.w-geometryPreviousPosition.xy/geometryPreviousPosition.w);\n#endif\n#ifdef PREPASS_VELOCITY\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_INDEX,vec4(pow(abs(geometryMotion),vec2(1.0/3.0))*sign(geometryMotion)*0.5+0.5,0.0,geometryCoverage));\n#endif\n#ifdef PREPASS_VELOCITY_LINEAR\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_VELOCITY_LINEAR_INDEX,vec4(-geometryMotion,0.0,geometryCoverage));\n#endif\n#endif\n#ifdef PREPASS_OBJECT_ID\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(PREPASS_OBJECT_ID_INDEX,encodeObjectId(objectId)*geometryCoverage);\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nmeshBlendTagOutput=geometryCoverage>0.0 ? uvec4(uint(meshBlendTag),0u,0u,0u) : uvec4(0u);\n#endif\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const geometryRenderingFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { clipPlaneFragmentDeclaration2 } from \"./ShadersInclude/clipPlaneFragmentDeclaration2\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { geometryRenderingFragment } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"gpuRenderParticlesPixelShader\";\nconst shader = `precision highp float;\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\nuniform sampler2D diffuseSampler;varying vec2 vUV;varying vec4 vColor;\n#ifdef PREPASS\nuniform float geometryZeroAlphaDiscard;\n#ifdef PREPASS_POSITION\nvarying vec3 vGeometryPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vGeometryNormalW;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vGeometryNormalV;\n#endif\n#endif\n#define PREPASS_VELOCITY_ZERO\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<clipPlaneFragmentDeclaration2> \n#include<imageProcessingDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#include<fogFragmentDeclaration>\nvoid main() {\n#include<clipPlaneFragment> \nvec4 textureColor=texture2D(diffuseSampler,vUV);gl_FragColor=textureColor*vColor;\n#ifdef PREPASS\nvec3 geometryAlbedo=toLinearSpace(gl_FragColor.rgb);\n#endif\n#ifdef BLENDMULTIPLYMODE\nfloat alpha=vColor.a*textureColor.a;gl_FragColor.rgb=gl_FragColor.rgb*alpha+vec3(1.0)*(1.0-alpha);\n#endif \n#include<logDepthFragment>\n#include<fogFragment>(color,gl_FragColor)\n#ifdef IMAGEPROCESSINGPOSTPROCESS\ngl_FragColor.rgb=toLinearSpace(gl_FragColor.rgb);\n#else\n#ifdef IMAGEPROCESSING\ngl_FragColor.rgb=toLinearSpace(gl_FragColor.rgb);gl_FragColor=applyImageProcessing(gl_FragColor);\n#endif\n#endif\n#ifdef PREPASS\nvec4 geometryColor=gl_FragColor;if (geometryColor.a<=0.0 && geometryZeroAlphaDiscard>0.0) {discard;}\n#ifdef PREPASS_POSITION\nvec3 geometryPositionW=vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvec3 geometryPositionL=vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nfloat geometryViewDepth=vViewPos.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfloat geometryNormalizedViewDepth=vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvec3 geometryNormalV=normalize(vGeometryNormalV);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvec3 geometryNormalW=normalize(vGeometryNormalW);\n#endif\n#include<geometryRenderingFragment>\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [objectIdFunctions, prePassDeclaration, clipPlaneFragmentDeclaration2, imageProcessingDeclaration, logDepthDeclaration, helperFunctions, imageProcessingFunctions, fogFragmentDeclaration, clipPlaneFragment, logDepthFragment, fogFragment, geometryRenderingFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gpuRenderParticlesPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"clipPlaneVertexDeclaration2\";\nconst shader = `#ifdef CLIPPLANE\nuniform vec4 vClipPlane;out float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nuniform vec4 vClipPlane2;out float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nuniform vec4 vClipPlane3;out float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nuniform vec4 vClipPlane4;out float fClipDistance4;\n#endif\n#ifdef CLIPPLANE5\nuniform vec4 vClipPlane5;out float fClipDistance5;\n#endif\n#ifdef CLIPPLANE6\nuniform vec4 vClipPlane6;out float fClipDistance6;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const clipPlaneVertexDeclaration2 = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneVertexDeclaration2 } from \"./ShadersInclude/clipPlaneVertexDeclaration2\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"gpuRenderParticlesVertexShader\";\nconst shader = `precision highp float;uniform mat4 view;uniform mat4 projection;uniform vec2 translationPivot;uniform vec3 worldOffset;\n#ifdef LOCAL\nuniform mat4 emitterWM;\n#endif\n#ifdef PREPASS\nuniform vec2 cameraInfo;\n#ifdef LOCAL\nuniform mat4 inverseEmitterWM;\n#endif\n#ifdef PREPASS_POSITION\nvarying vec3 vGeometryPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vGeometryNormalW;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vGeometryNormalV;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vec3 vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vec3 vViewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying float vNormViewDepth;\n#endif\n#endif\nattribute vec3 position;attribute float age;attribute float life;attribute vec3 size;\n#if !defined(BILLBOARD) || defined(BILLBOARDSTRETCHED_LOCAL)\nattribute vec3 initialDirection;\n#endif\n#ifdef BILLBOARDSTRETCHED\nattribute vec3 direction;\n#endif\nattribute float angle;\n#ifdef ANIMATESHEET\nattribute float cellIndex;\n#endif\nattribute vec2 offset;attribute vec2 uv;varying vec2 vUV;varying vec4 vColor;varying vec3 vPositionW;\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\nuniform mat4 invView;\n#endif\n#include<clipPlaneVertexDeclaration2>\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#ifdef COLORGRADIENTS\nuniform sampler2D colorGradientSampler;\n#ifdef COLORGRADIENTS_COLOR2\nattribute vec4 seed;\n#endif\n#else\nuniform vec4 colorDead;attribute vec4 color;\n#endif\n#ifdef ANIMATESHEET\nuniform vec3 sheetInfos;\n#endif\n#ifdef BILLBOARD\nuniform vec3 eyePosition;\n#endif\nvec3 particleBasePosition() {\n#ifdef LOCAL\nreturn (emitterWM*vec4(position,1.0)).xyz+worldOffset;\n#else\nreturn position+worldOffset;\n#endif\n}\nvec3 rotate(vec3 yaxis,vec3 rotatedCorner) {vec3 xaxis=normalize(cross(vec3(0.,1.0,0.),yaxis));vec3 zaxis=normalize(cross(yaxis,xaxis));vec3 row0=vec3(xaxis.x,xaxis.y,xaxis.z);vec3 row1=vec3(yaxis.x,yaxis.y,yaxis.z);vec3 row2=vec3(zaxis.x,zaxis.y,zaxis.z);mat3 rotMatrix= mat3(row0,row1,row2);vec3 alignedCorner=rotMatrix*rotatedCorner;return particleBasePosition()+alignedCorner;}\n#ifdef BILLBOARDSTRETCHED\nvec3 rotateAlign(vec3 toCamera,vec3 rotatedCorner) {\n#ifdef BILLBOARDSTRETCHED_LOCAL\nvec3 stretchDirection=initialDirection;\n#else\nvec3 stretchDirection=direction;\n#endif\nvec3 normalizedToCamera=normalize(toCamera);vec3 normalizedCrossDirToCamera=normalize(cross(normalize(stretchDirection),normalizedToCamera));vec3 row0=vec3(normalizedCrossDirToCamera.x,normalizedCrossDirToCamera.y,normalizedCrossDirToCamera.z);vec3 row2=vec3(normalizedToCamera.x,normalizedToCamera.y,normalizedToCamera.z);\n#ifdef BILLBOARDSTRETCHED_LOCAL\nvec3 row1=normalize(stretchDirection);\n#else\nvec3 crossProduct=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));vec3 row1=vec3(crossProduct.x,crossProduct.y,crossProduct.z);\n#endif\nmat3 rotMatrix= mat3(row0,row1,row2);vec3 alignedCorner=rotMatrix*rotatedCorner;return particleBasePosition()+alignedCorner;}\nvec3 stretchedNormal(vec3 toCamera,vec3 stretchDirection) {vec3 normalizedToCamera=normalize(toCamera);vec3 normalizedCrossDirToCamera=normalize(cross(normalize(stretchDirection),normalizedToCamera));\n#ifdef BILLBOARDSTRETCHED_LOCAL\nvec3 row1=normalize(stretchDirection);\n#else\nvec3 row1=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\n#endif\nreturn normalize(cross(normalizedCrossDirToCamera,row1));}\n#endif\nvoid main() {\n#ifdef PREPASS\nvec3 geometryNormalW;\n#endif\n#ifdef EMITRATECTRL\nif (life>0.0 && age>=life) {gl_Position=vec4(0.0,0.0,2.0,1.0);vColor=vec4(0.0); \nvUV=vec2(0.0);vPositionW=vec3(0.0);return;}\n#endif\n#ifdef ANIMATESHEET\nfloat rowOffset=floor(cellIndex/sheetInfos.z);float columnOffset=cellIndex-rowOffset*sheetInfos.z;vec2 uvScale=sheetInfos.xy;vec2 uvOffset=vec2(uv.x ,1.0-uv.y);vUV=(uvOffset+vec2(columnOffset,rowOffset))*uvScale;\n#else\nvUV=uv;\n#endif\nfloat ratio=min(1.0,age/life);\n#ifdef COLORGRADIENTS\n#ifdef COLORGRADIENTS_COLOR2\nvec4 vColor1=texture2D(colorGradientSampler,vec2(ratio,0.25));vec4 vColor2=texture2D(colorGradientSampler,vec2(ratio,0.75));vColor=mix(vColor1,vColor2,seed.x);\n#else\nvColor=texture2D(colorGradientSampler,vec2(ratio,0));\n#endif\n#else\nvColor=color*vec4(1.0-ratio)+colorDead*vec4(ratio);\n#endif\nvec2 cornerPos=(offset-translationPivot)*size.yz*size.x;\n#ifdef BILLBOARD\nvec4 rotatedCorner;rotatedCorner.w=0.;\n#ifdef BILLBOARDY\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.y=0.;rotatedCorner.xz+=translationPivot;vec3 yaxis=(position+worldOffset)-eyePosition;yaxis.y=0.;vPositionW=rotate(normalize(yaxis),rotatedCorner.xyz);\n#ifdef PREPASS\ngeometryNormalW=normalize(yaxis);\n#endif\nvec4 viewPosition=(view*vec4(vPositionW,1.0));\n#elif defined(BILLBOARDSTRETCHED)\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.z=0.;rotatedCorner.xy+=translationPivot;vec3 toCamera=(position+worldOffset)-eyePosition;vPositionW=rotateAlign(toCamera,rotatedCorner.xyz);\n#ifdef PREPASS\n#ifdef BILLBOARDSTRETCHED_LOCAL\ngeometryNormalW=stretchedNormal(toCamera,initialDirection);\n#else\ngeometryNormalW=stretchedNormal(toCamera,direction);\n#endif\n#endif\nvec4 viewPosition=(view*vec4(vPositionW,1.0));\n#else\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.z=0.;rotatedCorner.xy+=translationPivot;\n#ifdef LOCAL\nvec4 viewPosition=view*vec4(((emitterWM*vec4(position,1.0)).xyz+worldOffset),1.0)+rotatedCorner;\n#else\nvec4 viewPosition=view*vec4((position+worldOffset),1.0)+rotatedCorner;\n#endif\nvPositionW=(invView*viewPosition).xyz;\n#ifdef PREPASS\ngeometryNormalW=normalize((invView*vec4(0.0,0.0,1.0,0.0)).xyz);\n#endif\n#endif\n#else\nvec3 rotatedCorner;rotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=0.;rotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.xz+=translationPivot;vec3 yaxis=normalize(initialDirection);vPositionW=rotate(yaxis,rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=yaxis;\n#endif\nvec4 viewPosition=view*vec4(vPositionW,1.0);\n#endif\ngl_Position=projection*viewPosition;\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6) || defined(FOG)\nvec4 worldPos=vec4(vPositionW,1.0);\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<logDepthVertex>\n#ifdef PREPASS\nvec4 geometryViewPosition=view*vec4(vPositionW,1.0);\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nvec3 geometryNormalV=normalize((view*vec4(geometryNormalW,0.0)).xyz);vec3 geometryViewDirection=projection[3][3]==0.0 ? geometryViewPosition.xyz : vec3(0.0,0.0,geometryViewPosition.z);if (dot(geometryNormalV,geometryViewDirection)>0.0) {geometryNormalV=-geometryNormalV;geometryNormalW=-geometryNormalW;}\n#endif\n#ifdef PREPASS_POSITION\nvGeometryPositionW=vPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvGeometryNormalW=normalize(geometryNormalW);\n#endif\n#ifdef PREPASS_NORMAL\nvGeometryNormalV=geometryNormalV;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\n#ifdef LOCAL\nvec3 geometryRenderPosition=vPositionW;\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\ngeometryRenderPosition=particleBasePosition()+(invView*vec4(rotatedCorner.xyz,0.0)).xyz;\n#endif\nvPosition=(inverseEmitterWM*vec4(geometryRenderPosition-worldOffset,1.0)).xyz;\n#else\nvPosition=vPositionW;\n#endif\n#endif\n#ifdef PREPASS_DEPTH\nvViewPos=geometryViewPosition.xyz;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvNormViewDepth=(geometryViewPosition.z-cameraInfo.x)/(cameraInfo.y-cameraInfo.x);\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneVertexDeclaration2, fogVertexDeclaration, logDepthDeclaration, clipPlaneVertex, fogVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gpuRenderParticlesVertexShader = { name, shader };\n","import { type Nullable } from \"../types\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { type IParticleSystem } from \"./IParticleSystem\";\r\nimport { GPUParticleSystem } from \"./gpuParticleSystem.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { ParticleSystem } from \"../Particles/particleSystem.pure\";\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { type Vector3 } from \"../Maths/math.vector\";\r\n\r\n/** Internal class used to store shapes for emitters */\r\nclass ParticleSystemSetEmitterCreationOptions {\r\n    public kind: string;\r\n    public options: any;\r\n    public renderingGroupId: number;\r\n}\r\n\r\n/**\r\n * Represents a set of particle systems working together to create a specific effect\r\n */\r\nexport class ParticleSystemSet implements IDisposable {\r\n    /**\r\n     * Gets or sets base Assets URL\r\n     * Only used when parsing particle systems from JSON, not part of the core assets\r\n     */\r\n    public static BaseAssetsUrl = \"https://assets.babylonjs.com/particles\";\r\n\r\n    private _emitterCreationOptions: ParticleSystemSetEmitterCreationOptions;\r\n    private _emitterNode: Nullable<AbstractMesh | Vector3>;\r\n    private _emitterNodeIsOwned = true;\r\n\r\n    /**\r\n     * Gets the particle system list\r\n     */\r\n    public systems: IParticleSystem[] = [];\r\n\r\n    /**\r\n     * Gets or sets the emitter node used with this set\r\n     */\r\n    public get emitterNode(): Nullable<AbstractMesh | Vector3> {\r\n        return this._emitterNode;\r\n    }\r\n\r\n    public set emitterNode(value: Nullable<AbstractMesh | Vector3>) {\r\n        if (this._emitterNodeIsOwned && this._emitterNode) {\r\n            if ((this._emitterNode as AbstractMesh).dispose) {\r\n                (this._emitterNode as AbstractMesh).dispose();\r\n            }\r\n            this._emitterNodeIsOwned = false;\r\n        }\r\n\r\n        for (const system of this.systems) {\r\n            system.emitter = value;\r\n        }\r\n\r\n        this._emitterNode = value;\r\n    }\r\n\r\n    /**\r\n     * Creates a new emitter mesh as a sphere\r\n     * @param options defines the options used to create the sphere\r\n     * @param options.diameter\r\n     * @param options.segments\r\n     * @param options.color\r\n     * @param renderingGroupId defines the renderingGroupId to use for the sphere\r\n     * @param scene defines the hosting scene\r\n     */\r\n    public setEmitterAsSphere(options: { diameter: number; segments: number; color: Color3 }, renderingGroupId: number, scene: Scene) {\r\n        if (this._emitterNodeIsOwned && this._emitterNode) {\r\n            if ((this._emitterNode as AbstractMesh).dispose) {\r\n                (this._emitterNode as AbstractMesh).dispose();\r\n            }\r\n        }\r\n\r\n        this._emitterNodeIsOwned = true;\r\n\r\n        this._emitterCreationOptions = {\r\n            kind: \"Sphere\",\r\n            options: options,\r\n            renderingGroupId: renderingGroupId,\r\n        };\r\n\r\n        const emitterMesh = CreateSphere(\"emitterSphere\", { diameter: options.diameter, segments: options.segments }, scene);\r\n        emitterMesh.renderingGroupId = renderingGroupId;\r\n\r\n        const material = new StandardMaterial(\"emitterSphereMaterial\", scene);\r\n        material.emissiveColor = options.color;\r\n        emitterMesh.material = material;\r\n\r\n        for (const system of this.systems) {\r\n            system.emitter = emitterMesh;\r\n        }\r\n\r\n        this._emitterNode = emitterMesh;\r\n    }\r\n\r\n    /**\r\n     * Starts all particle systems of the set\r\n     * @param emitter defines an optional mesh to use as emitter for the particle systems\r\n     */\r\n    public start(emitter?: AbstractMesh): void {\r\n        for (const system of this.systems) {\r\n            if (emitter) {\r\n                system.emitter = emitter;\r\n            }\r\n            system.start();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release all associated resources\r\n     */\r\n    public dispose(): void {\r\n        for (const system of this.systems) {\r\n            system.dispose();\r\n        }\r\n\r\n        this.systems.length = 0;\r\n\r\n        if (this._emitterNode) {\r\n            if ((this._emitterNode as AbstractMesh).dispose) {\r\n                (this._emitterNode as AbstractMesh).dispose();\r\n            }\r\n            this._emitterNode = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serialize the set into a JSON compatible object\r\n     * @param serializeTexture defines if the texture must be serialized as well\r\n     * @returns a JSON compatible representation of the set\r\n     */\r\n    public serialize(serializeTexture = false): any {\r\n        const result: any = {};\r\n\r\n        result.systems = [];\r\n        for (const system of this.systems) {\r\n            if (!system.doNotSerialize) {\r\n                result.systems.push(system.serialize(serializeTexture));\r\n            }\r\n        }\r\n\r\n        if (this._emitterNode) {\r\n            result.emitter = this._emitterCreationOptions;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Parse a new ParticleSystemSet from a serialized source\r\n     * @param data defines a JSON compatible representation of the set\r\n     * @param scene defines the hosting scene\r\n     * @param gpu defines if we want GPU particles or CPU particles\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns a new ParticleSystemSet\r\n     */\r\n    public static Parse(data: any, scene: Scene, gpu = false, capacity?: number): ParticleSystemSet {\r\n        const result = new ParticleSystemSet();\r\n        const rootUrl = this.BaseAssetsUrl + \"/textures/\";\r\n\r\n        scene = scene || EngineStore.LastCreatedScene;\r\n\r\n        for (const system of data.systems) {\r\n            result.systems.push(gpu ? GPUParticleSystem.Parse(system, scene, rootUrl, true, capacity) : ParticleSystem.Parse(system, scene, rootUrl, true, capacity));\r\n        }\r\n\r\n        if (data.emitter) {\r\n            const options = data.emitter.options;\r\n            switch (data.emitter.kind) {\r\n                case \"Sphere\":\r\n                    result.setEmitterAsSphere(\r\n                        {\r\n                            diameter: options.diameter,\r\n                            segments: options.segments,\r\n                            color: Color3.FromArray(options.color),\r\n                        },\r\n                        data.emitter.renderingGroupId,\r\n                        scene\r\n                    );\r\n                    break;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { type Vector3 } from \"../Maths/math.vector\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type IParticleSystem } from \"./IParticleSystem\";\r\nimport { GPUParticleSystem } from \"./gpuParticleSystem.pure\";\r\nimport { ParticleSystemSet } from \"./particleSystemSet\";\r\nimport { ParticleSystem } from \"./particleSystem.pure\";\r\nimport { WebRequest } from \"../Misc/webRequest\";\r\nimport { Constants } from \"../Engines/constants\";\r\n/**\r\n * This class is made for on one-liner static method to help creating particle system set.\r\n */\r\nexport class ParticleHelper {\r\n    /**\r\n     * Gets or sets base Assets URL\r\n     */\r\n    public static BaseAssetsUrl = ParticleSystemSet.BaseAssetsUrl;\r\n\r\n    /** Define the Url to load snippets */\r\n    public static SnippetUrl = Constants.SnippetUrl;\r\n\r\n    /**\r\n     * Create a default particle system that you can tweak\r\n     * @param emitter defines the emitter to use\r\n     * @param capacity defines the system capacity (default is 500 particles)\r\n     * @param scene defines the hosting scene\r\n     * @param useGPU defines if a GPUParticleSystem must be created (default is false)\r\n     * @returns the new Particle system\r\n     */\r\n    public static CreateDefault(emitter: Nullable<AbstractMesh | Vector3>, capacity = 500, scene?: Scene, useGPU = false): IParticleSystem {\r\n        let system: IParticleSystem;\r\n\r\n        if (useGPU) {\r\n            system = new GPUParticleSystem(\"default system\", { capacity: capacity }, scene!);\r\n        } else {\r\n            system = new ParticleSystem(\"default system\", capacity, scene!);\r\n        }\r\n\r\n        system.emitter = emitter;\r\n        const textureUrl = Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/textures/flare.png\");\r\n        system.particleTexture = new Texture(textureUrl, system.getScene());\r\n        system.createConeEmitter(0.1, Math.PI / 4);\r\n\r\n        // Particle color\r\n        system.color1 = new Color4(1.0, 1.0, 1.0, 1.0);\r\n        system.color2 = new Color4(1.0, 1.0, 1.0, 1.0);\r\n        system.colorDead = new Color4(1.0, 1.0, 1.0, 0.0);\r\n\r\n        // Particle Size\r\n        system.minSize = 0.1;\r\n        system.maxSize = 0.1;\r\n\r\n        // Emission speed\r\n        system.minEmitPower = 2;\r\n        system.maxEmitPower = 2;\r\n\r\n        // Update speed\r\n        system.updateSpeed = 1 / 60;\r\n\r\n        system.emitRate = 30;\r\n\r\n        return system;\r\n    }\r\n\r\n    /**\r\n     * This is the main static method (one-liner) of this helper to create different particle systems\r\n     * @param type This string represents the type to the particle system to create\r\n     * @param scene The scene where the particle system should live\r\n     * @param gpu If the system will use gpu\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns the ParticleSystemSet created\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static CreateAsync(type: string, scene: Nullable<Scene>, gpu: boolean = false, capacity?: number): Promise<ParticleSystemSet> {\r\n        if (!scene) {\r\n            scene = EngineStore.LastCreatedScene;\r\n        }\r\n\r\n        const token = {};\r\n\r\n        scene!.addPendingData(token);\r\n\r\n        return new Promise((resolve, reject) => {\r\n            if (gpu && !GPUParticleSystem.IsSupported) {\r\n                scene!.removePendingData(token);\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                return reject(\"Particle system with GPU is not supported.\");\r\n            }\r\n\r\n            Tools.LoadFile(\r\n                `${ParticleHelper.BaseAssetsUrl}/systems/${type}.json`,\r\n                (data) => {\r\n                    scene!.removePendingData(token);\r\n                    const newData = JSON.parse(data.toString());\r\n                    return resolve(ParticleSystemSet.Parse(newData, scene!, gpu, capacity));\r\n                },\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                () => {\r\n                    scene!.removePendingData(token);\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    return reject(`An error occurred with the creation of your particle system. Check if your type '${type}' exists.`);\r\n                }\r\n            );\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Static function used to export a particle system to a ParticleSystemSet variable.\r\n     * Please note that the emitter shape is not exported\r\n     * @param systems defines the particle systems to export\r\n     * @returns the created particle system set\r\n     */\r\n    public static ExportSet(systems: IParticleSystem[]): ParticleSystemSet {\r\n        const set = new ParticleSystemSet();\r\n\r\n        for (const system of systems) {\r\n            set.systems.push(system);\r\n        }\r\n\r\n        return set;\r\n    }\r\n\r\n    /**\r\n     * Creates a particle system from a snippet saved in a remote file\r\n     * @param name defines the name of the particle system to create (can be null or empty to use the one from the json data)\r\n     * @param url defines the url to load from\r\n     * @param scene defines the hosting scene\r\n     * @param gpu If the system will use gpu\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns a promise that will resolve to the new particle system\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromFileAsync(name: Nullable<string>, url: string, scene: Scene, gpu: boolean = false, rootUrl: string = \"\", capacity?: number): Promise<IParticleSystem> {\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const serializationObject = JSON.parse(request.responseText);\r\n                        let output: IParticleSystem;\r\n\r\n                        if (gpu) {\r\n                            output = GPUParticleSystem.Parse(serializationObject, scene, rootUrl, false, capacity);\r\n                        } else {\r\n                            output = ParticleSystem.Parse(serializationObject, scene, rootUrl, false, capacity);\r\n                        }\r\n\r\n                        if (name) {\r\n                            output.name = name;\r\n                        }\r\n\r\n                        resolve(output);\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the particle system\");\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", url);\r\n            request.send();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a particle system from a snippet saved by the particle system editor\r\n     * @param snippetId defines the snippet to load (can be set to _BLANK to create a default one)\r\n     * @param scene defines the hosting scene\r\n     * @param gpu If the system will use gpu\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns a promise that will resolve to the new particle system\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromSnippetAsync(snippetId: string, scene: Scene, gpu: boolean = false, rootUrl: string = \"\", capacity?: number): Promise<IParticleSystem> {\r\n        if (snippetId === \"_BLANK\") {\r\n            const system = this.CreateDefault(null);\r\n            system.start();\r\n            return Promise.resolve(system);\r\n        }\r\n\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n                        const serializationObject = JSON.parse(snippet.particleSystem);\r\n                        let output: IParticleSystem;\r\n\r\n                        if (gpu) {\r\n                            output = GPUParticleSystem.Parse(serializationObject, scene, rootUrl, false, capacity);\r\n                        } else {\r\n                            output = ParticleSystem.Parse(serializationObject, scene, rootUrl, false, capacity);\r\n                        }\r\n                        output.snippetId = snippetId;\r\n\r\n                        resolve(output);\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the snippet \" + snippetId);\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", this.SnippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\r\n            request.send();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a particle system from a snippet saved by the particle system editor\r\n     * @deprecated Please use ParseFromSnippetAsync instead\r\n     * @param snippetId defines the snippet to load (can be set to _BLANK to create a default one)\r\n     * @param scene defines the hosting scene\r\n     * @param gpu If the system will use gpu\r\n     * @param rootUrl defines the root URL to use to load textures and relative dependencies\r\n     * @param capacity defines the system capacity (if null or undefined the sotred capacity will be used)\r\n     * @returns a promise that will resolve to the new particle system\r\n     */\r\n    public static CreateFromSnippetAsync = ParticleHelper.ParseFromSnippetAsync;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IParticleSystem } from \"./IParticleSystem\";\r\nimport { GPUParticleSystem } from \"./gpuParticleSystem.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { ParticleSystem } from \"./particleSystem.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants } from \"../sceneComponent\";\r\nimport { type AssetContainer } from \"../assetContainer\";\r\nimport { type EffectFallbacks } from \"../Materials/effectFallbacks\";\r\nimport { AddParser, AddIndividualParser, GetIndividualParser } from \"core/Loading/Plugins/babylonFileParser.function\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleSystemComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleSystemComponent(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Adds the parsers to the scene parsers.\r\n    AddParser(SceneComponentConstants.NAME_PARTICLESYSTEM, (parsedData: any, scene: Scene, container: AssetContainer, rootUrl: string) => {\r\n        const individualParser = GetIndividualParser(SceneComponentConstants.NAME_PARTICLESYSTEM);\r\n\r\n        if (!individualParser) {\r\n            return;\r\n        }\r\n\r\n        // Particles Systems\r\n        if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {\r\n            for (let index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {\r\n                const parsedParticleSystem = parsedData.particleSystems[index];\r\n                container.particleSystems.push(individualParser(parsedParticleSystem, scene, rootUrl));\r\n            }\r\n        }\r\n    });\r\n\r\n    AddIndividualParser(SceneComponentConstants.NAME_PARTICLESYSTEM, (parsedParticleSystem: any, scene: Scene, rootUrl: string) => {\r\n        if (parsedParticleSystem.activeParticleCount) {\r\n            const ps = GPUParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);\r\n            return ps;\r\n        } else {\r\n            const ps = ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);\r\n            return ps;\r\n        }\r\n    });\r\n\r\n    AbstractEngine.prototype.createEffectForParticles = function (\r\n        fragmentName: string,\r\n        uniformsNames: string[] = [],\r\n        samplers: string[] = [],\r\n        defines = \"\",\r\n        fallbacks?: EffectFallbacks,\r\n        onCompiled?: (effect: Effect) => void,\r\n        onError?: (effect: Effect, errors: string) => void,\r\n        particleSystem?: IParticleSystem,\r\n        shaderLanguage = ShaderLanguage.GLSL,\r\n        vertexName?: string\r\n    ): Effect {\r\n        let attributesNamesOrOptions: Array<string> = [];\r\n        let effectCreationOption: Array<string> = [];\r\n        const allSamplers: Array<string> = [];\r\n\r\n        if (particleSystem) {\r\n            particleSystem.fillUniformsAttributesAndSamplerNames(effectCreationOption, attributesNamesOrOptions, allSamplers);\r\n        } else {\r\n            attributesNamesOrOptions = ParticleSystem._GetAttributeNamesOrOptions();\r\n            effectCreationOption = ParticleSystem._GetEffectCreationOptions();\r\n        }\r\n\r\n        if (defines.indexOf(\" BILLBOARD\") === -1) {\r\n            defines += \"\\n#define BILLBOARD\\n\";\r\n        }\r\n\r\n        if (particleSystem?.isAnimationSheetEnabled) {\r\n            if (defines.indexOf(\" ANIMATESHEET\") === -1) {\r\n                defines += \"\\n#define ANIMATESHEET\\n\";\r\n            }\r\n        }\r\n\r\n        if (samplers.indexOf(\"diffuseSampler\") === -1) {\r\n            samplers.push(\"diffuseSampler\");\r\n        }\r\n\r\n        return this.createEffect(\r\n            {\r\n                vertex: vertexName ?? particleSystem?.vertexShaderName ?? \"particles\",\r\n                fragmentElement: fragmentName,\r\n            },\r\n            attributesNamesOrOptions,\r\n            effectCreationOption.concat(uniformsNames),\r\n            allSamplers.concat(samplers),\r\n            defines,\r\n            fallbacks,\r\n            onCompiled,\r\n            onError,\r\n            undefined,\r\n            shaderLanguage,\r\n            async () => {\r\n                if (shaderLanguage === ShaderLanguage.GLSL) {\r\n                    await import(\"../Shaders/particles.vertex\");\r\n                } else {\r\n                    await import(\"../ShadersWGSL/particles.vertex\");\r\n                }\r\n            }\r\n        );\r\n    };\r\n\r\n    Mesh.prototype.getEmittedParticleSystems = function (): IParticleSystem[] {\r\n        const results: IParticleSystem[] = [];\r\n        for (let index = 0; index < this.getScene().particleSystems.length; index++) {\r\n            const particleSystem = this.getScene().particleSystems[index];\r\n            if (particleSystem.emitter === this) {\r\n                results.push(particleSystem);\r\n            }\r\n        }\r\n        return results;\r\n    };\r\n\r\n    Mesh.prototype.getHierarchyEmittedParticleSystems = function (): IParticleSystem[] {\r\n        const results: IParticleSystem[] = [];\r\n        const descendants = this.getDescendants();\r\n        descendants.push(this);\r\n\r\n        for (let index = 0; index < this.getScene().particleSystems.length; index++) {\r\n            const particleSystem = this.getScene().particleSystems[index];\r\n            const emitter: any = particleSystem.emitter;\r\n\r\n            if (emitter.position && descendants.indexOf(emitter) !== -1) {\r\n                results.push(particleSystem);\r\n            }\r\n        }\r\n\r\n        return results;\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Matrix, Vector3, TmpVectors, Quaternion, Vector4, Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { BoundingInfo } from \"../Culling/boundingInfo\";\r\nimport { BoundingSphere } from \"../Culling/boundingSphere\";\r\nimport { type SolidParticleSystem } from \"./solidParticleSystem\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Plane } from \"../Maths/math.plane\";\r\nimport { type Material } from \"../Materials/material\";\r\n/**\r\n * Represents one particle of a solid particle system.\r\n */\r\nexport class SolidParticle {\r\n    /**\r\n     * particle global index\r\n     */\r\n    public idx: number = 0;\r\n    /**\r\n     * particle identifier\r\n     */\r\n    public id: number = 0;\r\n    /**\r\n     * The color of the particle\r\n     */\r\n    public color: Nullable<Color4> = new Color4(1.0, 1.0, 1.0, 1.0);\r\n    /**\r\n     * The world space position of the particle.\r\n     */\r\n    public position: Vector3 = Vector3.Zero();\r\n    /**\r\n     * The world space rotation of the particle. (Not use if rotationQuaternion is set)\r\n     */\r\n    public rotation: Vector3 = Vector3.Zero();\r\n    /**\r\n     * The world space rotation quaternion of the particle.\r\n     */\r\n    public rotationQuaternion: Nullable<Quaternion>;\r\n    /**\r\n     * The scaling of the particle.\r\n     */\r\n    public scaling: Vector3 = Vector3.One();\r\n    /**\r\n     * The uvs of the particle.\r\n     */\r\n    public uvs: Vector4 = new Vector4(0.0, 0.0, 1.0, 1.0);\r\n    /**\r\n     * The current speed of the particle.\r\n     */\r\n    public velocity: Vector3 = Vector3.Zero();\r\n    /**\r\n     * The pivot point in the particle local space.\r\n     */\r\n    public pivot: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Must the particle be translated from its pivot point in its local space ?\r\n     * In this case, the pivot point is set at the origin of the particle local space and the particle is translated.\r\n     * Default : false\r\n     */\r\n    public translateFromPivot: boolean = false;\r\n    /**\r\n     * Is the particle active or not ?\r\n     */\r\n    public alive: boolean = true;\r\n    /**\r\n     * Is the particle visible or not ?\r\n     */\r\n    public isVisible: boolean = true;\r\n    /**\r\n     * Defines how long will the life of the particle be.\r\n     * Set to Infinity for particles that should never die (default behavior for SolidParticleSystem).\r\n     */\r\n    public lifeTime = Infinity;\r\n    /**\r\n     * The current age of the particle.\r\n     */\r\n    public age = 0;\r\n    /**\r\n     * Index of this particle in the global \"positions\" array (Internal use)\r\n     * @internal\r\n     */\r\n    public _pos: number = 0;\r\n    /**\r\n     * @internal Index of this particle in the global \"indices\" array (Internal use)\r\n     */\r\n    public _ind: number = 0;\r\n    /**\r\n     * @internal ModelShape of this particle (Internal use)\r\n     */\r\n    public _model: ModelShape;\r\n    /**\r\n     * ModelShape id of this particle\r\n     */\r\n    public shapeId: number = 0;\r\n    /**\r\n     * Index of the particle in its shape id\r\n     */\r\n    public idxInShape: number = 0;\r\n    /**\r\n     * @internal Reference to the shape model BoundingInfo object (Internal use)\r\n     */\r\n    public _modelBoundingInfo: BoundingInfo;\r\n    private _boundingInfo: BoundingInfo;\r\n    /**\r\n     * @internal Reference to the SPS what the particle belongs to (Internal use)\r\n     */\r\n    public _sps: SolidParticleSystem;\r\n    /**\r\n     * @internal Still set as invisible in order to skip useless computations (Internal use)\r\n     */\r\n    public _stillInvisible: boolean = false;\r\n    /**\r\n     * @internal Last computed particle rotation matrix\r\n     */\r\n    public _rotationMatrix: number[] = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];\r\n    /**\r\n     * Parent particle Id, if any.\r\n     * Default null.\r\n     */\r\n    public parentId: Nullable<number> = null;\r\n    /**\r\n     * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.\r\n     */\r\n    public materialIndex: Nullable<number> = null;\r\n    /**\r\n     * Custom object or properties.\r\n     */\r\n    public props: Nullable<any> = null;\r\n    /**\r\n     * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().\r\n     * The possible values are :\r\n     * - AbstractMesh.CULLINGSTRATEGY_STANDARD\r\n     * - AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY\r\n     * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION\r\n     * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY\r\n     * The default value for solid particles is AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY\r\n     * Please read each static variable documentation in the class AbstractMesh to get details about the culling process.\r\n     * */\r\n    public cullingStrategy = AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;\r\n\r\n    /**\r\n     * @internal Internal global position in the SPS.\r\n     */\r\n    public _globalPosition: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Particle BoundingInfo object\r\n     * @returns a BoundingInfo\r\n     */\r\n    public getBoundingInfo(): BoundingInfo {\r\n        return this._boundingInfo;\r\n    }\r\n\r\n    /**\r\n     * Returns true if there is already a bounding info\r\n     */\r\n    public get hasBoundingInfo(): boolean {\r\n        return this._boundingInfo !== null;\r\n    }\r\n\r\n    /**\r\n     * Creates a Solid Particle object.\r\n     * Don't create particles manually, use instead the Solid Particle System internal tools like _addParticle()\r\n     * @param particleIndex (integer) is the particle index in the Solid Particle System pool.\r\n     * @param particleId (integer) is the particle identifier. Unless some particles are removed from the SPS, it's the same value than the particle idx.\r\n     * @param positionIndex (integer) is the starting index of the particle vertices in the SPS \"positions\" array.\r\n     * @param indiceIndex (integer) is the starting index of the particle indices in the SPS \"indices\" array.\r\n     * @param model (ModelShape) is a reference to the model shape on what the particle is designed.\r\n     * @param shapeId (integer) is the model shape identifier in the SPS.\r\n     * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))\r\n     * @param sps defines the sps it is associated to\r\n     * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.\r\n     * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.\r\n     */\r\n    constructor(\r\n        particleIndex: number,\r\n        particleId: number,\r\n        positionIndex: number,\r\n        indiceIndex: number,\r\n        model: Nullable<ModelShape>,\r\n        shapeId: number,\r\n        idxInShape: number,\r\n        sps: SolidParticleSystem,\r\n        modelBoundingInfo: Nullable<BoundingInfo> = null,\r\n        materialIndex: Nullable<number> = null\r\n    ) {\r\n        this.idx = particleIndex;\r\n        this.id = particleId;\r\n        this._pos = positionIndex;\r\n        this._ind = indiceIndex;\r\n        this._model = <ModelShape>model;\r\n        this.shapeId = shapeId;\r\n        this.idxInShape = idxInShape;\r\n        this._sps = sps;\r\n        if (modelBoundingInfo) {\r\n            this._modelBoundingInfo = modelBoundingInfo;\r\n            this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum);\r\n        }\r\n        if (materialIndex !== null) {\r\n            this.materialIndex = materialIndex;\r\n        }\r\n    }\r\n    /**\r\n     * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive\r\n     * @param target the particle target\r\n     * @returns the current particle\r\n     */\r\n    public copyToRef(target: SolidParticle): SolidParticle {\r\n        target.position.copyFrom(this.position);\r\n        target.rotation.copyFrom(this.rotation);\r\n        if (this.rotationQuaternion) {\r\n            if (target.rotationQuaternion) {\r\n                target.rotationQuaternion.copyFrom(this.rotationQuaternion);\r\n            } else {\r\n                target.rotationQuaternion = this.rotationQuaternion.clone();\r\n            }\r\n        }\r\n        target.scaling.copyFrom(this.scaling);\r\n        if (this.color) {\r\n            if (target.color) {\r\n                target.color.copyFrom(this.color);\r\n            } else {\r\n                target.color = this.color.clone();\r\n            }\r\n        }\r\n        target.uvs.copyFrom(this.uvs);\r\n        target.velocity.copyFrom(this.velocity);\r\n        target.pivot.copyFrom(this.pivot);\r\n        target.translateFromPivot = this.translateFromPivot;\r\n        target.alive = this.alive;\r\n        target.isVisible = this.isVisible;\r\n        target.parentId = this.parentId;\r\n        target.cullingStrategy = this.cullingStrategy;\r\n        target.lifeTime = this.lifeTime;\r\n        target.age = this.age;\r\n        if (this.materialIndex !== null) {\r\n            target.materialIndex = this.materialIndex;\r\n        }\r\n        return this;\r\n    }\r\n    /**\r\n     * Legacy support, changed scale to scaling\r\n     */\r\n    public get scale(): Vector3 {\r\n        return this.scaling;\r\n    }\r\n\r\n    /**\r\n     * Legacy support, changed scale to scaling\r\n     */\r\n    public set scale(scale: Vector3) {\r\n        this.scaling = scale;\r\n    }\r\n\r\n    /**\r\n     * Legacy support, changed quaternion to rotationQuaternion\r\n     */\r\n    public get quaternion(): Nullable<Quaternion> {\r\n        return this.rotationQuaternion;\r\n    }\r\n\r\n    /**\r\n     * Legacy support, changed quaternion to rotationQuaternion\r\n     */\r\n    public set quaternion(q: Nullable<Quaternion>) {\r\n        this.rotationQuaternion = q;\r\n    }\r\n\r\n    /**\r\n     * Returns a boolean. True if the particle intersects another particle or another mesh, else false.\r\n     * The intersection is computed on the particle bounding sphere and Axis Aligned Bounding Box (AABB)\r\n     * @param target is the object (solid particle or mesh) what the intersection is computed against.\r\n     * @returns true if it intersects\r\n     */\r\n    public intersectsMesh(target: Mesh | SolidParticle): boolean {\r\n        if (!this._boundingInfo || !target.hasBoundingInfo) {\r\n            return false;\r\n        }\r\n        if (this._sps._bSphereOnly) {\r\n            return BoundingSphere.Intersects(this._boundingInfo.boundingSphere, target.getBoundingInfo().boundingSphere);\r\n        }\r\n        return this._boundingInfo.intersects(target.getBoundingInfo(), false);\r\n    }\r\n\r\n    /**\r\n     * Returns `true` if the solid particle is within the frustum defined by the passed array of planes.\r\n     * A particle is in the frustum if its bounding box intersects the frustum\r\n     * @param frustumPlanes defines the frustum to test\r\n     * @returns true if the particle is in the frustum planes\r\n     */\r\n    public isInFrustum(frustumPlanes: Plane[]): boolean {\r\n        return this._boundingInfo !== null && this._boundingInfo.isInFrustum(frustumPlanes, this.cullingStrategy);\r\n    }\r\n\r\n    /**\r\n     * get the rotation matrix of the particle\r\n     * @internal\r\n     */\r\n    public getRotationMatrix(m: Matrix) {\r\n        let quaternion: Quaternion;\r\n        if (this.rotationQuaternion) {\r\n            quaternion = this.rotationQuaternion;\r\n        } else {\r\n            quaternion = TmpVectors.Quaternion[0];\r\n            const rotation = this.rotation;\r\n            Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);\r\n        }\r\n\r\n        quaternion.toRotationMatrix(m);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents the shape of the model used by one particle of a solid particle system.\r\n * SPS internal tool, don't use it manually.\r\n */\r\nexport class ModelShape {\r\n    /**\r\n     * Get or set the shapeId\r\n     * @deprecated Please use shapeId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get shapeID(): number {\r\n        return this.shapeId;\r\n    }\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set shapeID(shapeID: number) {\r\n        this.shapeId = shapeID;\r\n    }\r\n    /**\r\n     * The shape id\r\n     * @internal\r\n     */\r\n    public shapeId: number;\r\n    /**\r\n     * flat array of model positions (internal use)\r\n     * @internal\r\n     */\r\n    public _shape: Vector3[];\r\n    /**\r\n     * flat array of model UVs (internal use)\r\n     * @internal\r\n     */\r\n    public _shapeUV: number[];\r\n    /**\r\n     * color array of the model\r\n     * @internal\r\n     */\r\n    public _shapeColors: number[];\r\n    /**\r\n     * indices array of the model\r\n     * @internal\r\n     */\r\n    public _indices: number[];\r\n    /**\r\n     * normals array of the model\r\n     * @internal\r\n     */\r\n    public _normals: number[];\r\n    /**\r\n     * length of the shape in the model indices array (internal use)\r\n     * @internal\r\n     */\r\n    public _indicesLength: number = 0;\r\n    /**\r\n     * Custom position function (internal use)\r\n     * @internal\r\n     */\r\n    public _positionFunction: Nullable<(particle: SolidParticle, i: number, s: number) => void>;\r\n    /**\r\n     * Custom vertex function (internal use)\r\n     * @internal\r\n     */\r\n    public _vertexFunction: Nullable<(particle: SolidParticle, vertex: Vector3, i: number) => void>;\r\n    /**\r\n     * Model material (internal use)\r\n     * @internal\r\n     */\r\n    public _material: Nullable<Material>;\r\n\r\n    /**\r\n     * Creates a ModelShape object. This is an internal simplified reference to a mesh used as for a model to replicate particles from by the SPS.\r\n     * SPS internal tool, don't use it manually.\r\n     * @internal\r\n     */\r\n    constructor(\r\n        id: number,\r\n        shape: Vector3[],\r\n        indices: number[],\r\n        normals: number[],\r\n        colors: number[],\r\n        shapeUV: number[],\r\n        posFunction: Nullable<(particle: SolidParticle, i: number, s: number) => void>,\r\n        vtxFunction: Nullable<(particle: SolidParticle, vertex: Vector3, i: number) => void>,\r\n        material: Nullable<Material>\r\n    ) {\r\n        this.shapeId = id;\r\n        this._shape = shape;\r\n        this._indices = indices;\r\n        this._indicesLength = indices.length;\r\n        this._shapeUV = shapeUV;\r\n        this._shapeColors = colors;\r\n        this._normals = normals;\r\n        this._positionFunction = posFunction;\r\n        this._vertexFunction = vtxFunction;\r\n        this._material = material;\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a Depth Sorted Particle in the solid particle system.\r\n * @internal\r\n */\r\nexport class DepthSortedParticle {\r\n    /**\r\n     * Particle index\r\n     */\r\n    public idx: number = 0;\r\n    /**\r\n     * Index of the particle in the \"indices\" array\r\n     */\r\n    public ind: number = 0;\r\n    /**\r\n     * Length of the particle shape in the \"indices\" array\r\n     */\r\n    public indicesLength: number = 0;\r\n    /**\r\n     * Squared distance from the particle to the camera\r\n     */\r\n    public sqDistance: number = 0.0;\r\n    /**\r\n     * Material index when used with MultiMaterials\r\n     */\r\n    public materialIndex: number = 0;\r\n\r\n    /**\r\n     * Creates a new sorted particle\r\n     * @param idx\r\n     * @param ind\r\n     * @param indLength\r\n     * @param materialIndex\r\n     */\r\n    constructor(idx: number, ind: number, indLength: number, materialIndex: number) {\r\n        this.idx = idx;\r\n        this.ind = ind;\r\n        this.indicesLength = indLength;\r\n        this.materialIndex = materialIndex;\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a solid particle vertex\r\n */\r\nexport class SolidParticleVertex {\r\n    /**\r\n     * Vertex position\r\n     */\r\n    public position: Vector3;\r\n    /**\r\n     * Vertex color\r\n     */\r\n    public color: Color4;\r\n    /**\r\n     * Vertex UV\r\n     */\r\n    public uv: Vector2;\r\n    /**\r\n     * Creates a new solid particle vertex\r\n     */\r\n    constructor() {\r\n        this.position = Vector3.Zero();\r\n        this.color = new Color4(1.0, 1.0, 1.0, 1.0);\r\n        this.uv = Vector2.Zero();\r\n    }\r\n    // Getters and Setters for back-compatibility\r\n    /** Vertex x coordinate */\r\n    public get x(): number {\r\n        return this.position.x;\r\n    }\r\n    public set x(val: number) {\r\n        this.position.x = val;\r\n    }\r\n    /** Vertex y coordinate */\r\n    public get y(): number {\r\n        return this.position.y;\r\n    }\r\n    public set y(val: number) {\r\n        this.position.y = val;\r\n    }\r\n    /** Vertex z coordinate */\r\n    public get z(): number {\r\n        return this.position.z;\r\n    }\r\n    public set z(val: number) {\r\n        this.position.z = val;\r\n    }\r\n}\r\n","import { type Nullable, type IndicesArray, type FloatArray } from \"../types\";\r\nimport { Vector3, Matrix, TmpVectors, Quaternion } from \"../Maths/math.vector.pure\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { CreateDisc } from \"../Meshes/Builders/discBuilder.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { type Observer } from \"../Misc/observable\";\r\nimport { DepthSortedParticle, SolidParticle, ModelShape, SolidParticleVertex } from \"./solidParticle\";\r\nimport { type TargetCamera } from \"../Cameras/targetCamera\";\r\nimport { BoundingInfo } from \"../Culling/boundingInfo\";\r\nimport { Axis } from \"../Maths/math.axis\";\r\nimport { SubMesh } from \"../Meshes/subMesh\";\r\nimport { type Material } from \"../Materials/material\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { MultiMaterial } from \"../Materials/multiMaterial.pure\";\r\nimport { type PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type PBRMaterial } from \"../Materials/PBR/pbrMaterial\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * The SPS is a single updatable mesh. The solid particles are simply separate parts or faces of this big mesh.\r\n *As it is just a mesh, the SPS has all the same properties than any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.\r\n\r\n * The SPS is also a particle system. It provides some methods to manage the particles.\r\n * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.\r\n *\r\n * Full documentation here : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_intro\r\n */\r\nexport class SolidParticleSystem implements IDisposable {\r\n    /**\r\n     *  The SPS array of Solid Particle objects. Just access each particle as with any classic array.\r\n     *  Example : var p = SPS.particles[i];\r\n     */\r\n    public particles: SolidParticle[] = new Array<SolidParticle>();\r\n    /**\r\n     * The SPS total number of particles. Read only. Use SPS.counter instead if you need to set your own value.\r\n     */\r\n    public nbParticles: number = 0;\r\n    /**\r\n     * If the particles must ever face the camera (default false). Useful for planar particles.\r\n     */\r\n    public billboard: boolean = false;\r\n    /**\r\n     * Recompute normals when adding a shape\r\n     */\r\n    public recomputeNormals: boolean = false;\r\n    /**\r\n     * This a counter ofr your own usage. It's not set by any SPS functions.\r\n     */\r\n    public counter: number = 0;\r\n    /**\r\n     * The SPS name. This name is also given to the underlying mesh.\r\n     */\r\n    public name: string;\r\n    /**\r\n     * The SPS mesh. It's a standard BJS Mesh, so all the methods from the Mesh class are available.\r\n     */\r\n    public mesh: Mesh;\r\n    /**\r\n     * This empty object is intended to store some SPS specific or temporary values in order to lower the Garbage Collector activity.\r\n     * Please read : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/optimize_sps#limit-garbage-collection\r\n     */\r\n    public vars: any = {};\r\n    /**\r\n     * This array is populated when the SPS is set as 'pickable'.\r\n     * Each key of this array is a `faceId` value that you can get from a pickResult object.\r\n     * Each element of this array is an object `{idx: int, faceId: int}`.\r\n     * `idx` is the picked particle index in the `SPS.particles` array\r\n     * `faceId` is the picked face index counted within this particle.\r\n     * This array is the first element of the pickedBySubMesh array : sps.pickBySubMesh[0].\r\n     * It's not pertinent to use it when using a SPS with the support for MultiMaterial enabled.\r\n     * Use the method SPS.pickedParticle(pickingInfo) instead.\r\n     * Please read : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/picking_sps\r\n     */\r\n    public pickedParticles: { idx: number; faceId: number }[];\r\n    /**\r\n     * This array is populated when the SPS is set as 'pickable'\r\n     * Each key of this array is a submesh index.\r\n     * Each element of this array is a second array defined like this :\r\n     * Each key of this second array is a `faceId` value that you can get from a pickResult object.\r\n     * Each element of this second array is an object `{idx: int, faceId: int}`.\r\n     * `idx` is the picked particle index in the `SPS.particles` array\r\n     * `faceId` is the picked face index counted within this particle.\r\n     * It's better to use the method SPS.pickedParticle(pickingInfo) rather than using directly this array.\r\n     * Please read : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/picking_sps\r\n     */\r\n    public pickedBySubMesh: { idx: number; faceId: number }[][];\r\n    /**\r\n     * This array is populated when `enableDepthSort` is set to true.\r\n     * Each element of this array is an instance of the class DepthSortedParticle.\r\n     */\r\n    public depthSortedParticles: DepthSortedParticle[];\r\n\r\n    /**\r\n     * If the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster). (Internal use only)\r\n     * @internal\r\n     */\r\n    public _bSphereOnly: boolean = false;\r\n    /**\r\n     * A number to multiply the bounding sphere radius by in order to reduce it for instance. (Internal use only)\r\n     * @internal\r\n     */\r\n    public _bSphereRadiusFactor: number = 1.0;\r\n\r\n    protected _scene: Scene;\r\n    protected _positions: number[] = new Array<number>();\r\n    protected _indices: number[] = new Array<number>();\r\n    protected _normals: number[] = new Array<number>();\r\n    protected _colors: number[] = new Array<number>();\r\n    protected _uvs: number[] = new Array<number>();\r\n    protected _indices32: IndicesArray; // used as depth sorted array if depth sort enabled, else used as typed indices\r\n    protected _positions32: Float32Array; // updated positions for the VBO\r\n    protected _normals32: Float32Array; // updated normals for the VBO\r\n    protected _fixedNormal32: Float32Array; // initial normal references\r\n    protected _colors32: Float32Array;\r\n    protected _uvs32: Float32Array;\r\n    protected _index: number = 0; // indices index\r\n    protected _updatable: boolean = true;\r\n    protected _pickable: boolean = false;\r\n    protected _isVisibilityBoxLocked = false;\r\n    protected _alwaysVisible: boolean = false;\r\n    protected _depthSort: boolean = false;\r\n    protected _expandable: boolean = false;\r\n    protected _shapeCounter: number = 0;\r\n    protected _copy: SolidParticle = new SolidParticle(0, 0, 0, 0, null, 0, 0, this);\r\n    protected _color: Color4 = new Color4(0, 0, 0, 0);\r\n    protected _computeParticleColor: boolean = true;\r\n    protected _computeParticleTexture: boolean = true;\r\n    protected _computeParticleRotation: boolean = true;\r\n    protected _computeParticleVertex: boolean = false;\r\n    protected _computeBoundingBox: boolean = false;\r\n    protected _autoFixFaceOrientation: boolean = false;\r\n    protected _depthSortParticles: boolean = true;\r\n    protected _camera: TargetCamera;\r\n    protected _mustUnrotateFixedNormals = false;\r\n    protected _particlesIntersect: boolean = false;\r\n    protected _needs32Bits: boolean = false;\r\n    protected _isNotBuilt: boolean = true;\r\n    protected _lastParticleId: number = 0;\r\n    protected _idxOfId: number[] = []; // array : key = particle.id / value = particle.idx\r\n    protected _multimaterialEnabled: boolean = false;\r\n    protected _useModelMaterial: boolean = false;\r\n    protected _indicesByMaterial: number[];\r\n    protected _materialIndexes: number[];\r\n    protected _depthSortFunction = (p1: DepthSortedParticle, p2: DepthSortedParticle) => p2.sqDistance - p1.sqDistance;\r\n    protected _materialSortFunction = (p1: DepthSortedParticle, p2: DepthSortedParticle) => p1.materialIndex - p2.materialIndex;\r\n    protected _materials: Material[];\r\n    protected _multimaterial: MultiMaterial;\r\n    protected _materialIndexesById: any;\r\n    protected _defaultMaterial: Material;\r\n    protected _autoUpdateSubMeshes: boolean = false;\r\n    protected _tmpVertex: SolidParticleVertex;\r\n    protected _recomputeInvisibles: boolean = false;\r\n    protected _started: boolean = false;\r\n    protected _stopped: boolean = false;\r\n    protected _onBeforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n    /**\r\n     * The overall motion speed (0.01 is default update speed, faster updates = faster animation)\r\n     */\r\n    public updateSpeed = 0.01;\r\n    /** @internal */\r\n    protected _scaledUpdateSpeed: number;\r\n\r\n    /**\r\n     * Creates a SPS (Solid Particle System) object.\r\n     * @param name (String) is the SPS name, this will be the underlying mesh name.\r\n     * @param scene (Scene) is the scene in which the SPS is added.\r\n     * @param options defines the options of the sps e.g.\r\n     * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.\r\n     * * isPickable (optional boolean, default false) : if the solid particles must be pickable.\r\n     * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.\r\n     * * useModelMaterial (optional boolean, default false) : if the model materials must be used to create the SPS multimaterial. This enables the multimaterial supports of the SPS.\r\n     * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.\r\n     * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.\r\n     * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.\r\n     * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).\r\n     * * bSphereRadiusFactor (optional float, default 1.0) : a number to multiply the bounding sphere radius by in order to reduce it for instance.\r\n     * * computeBoundingBox (optional boolean, default false): if the bounding box of the entire SPS will be computed (for occlusion detection, for example). If it is false, the bounding box will be the bounding box of the first particle.\r\n     * * autoFixFaceOrientation (optional boolean, default false): if the particle face orientations will be flipped for transformations that change orientation (scale (-1, 1, 1), for example)\r\n     * * camera (optional Camera) : the camera to use with the particule system. If not provided, use the scene active camera.\r\n     * @param options.updatable\r\n     * @param options.isPickable\r\n     * @param options.enableDepthSort\r\n     * @param options.particleIntersection\r\n     * @param options.boundingSphereOnly\r\n     * @param options.bSphereRadiusFactor\r\n     * @param options.expandable\r\n     * @param options.useModelMaterial\r\n     * @param options.enableMultiMaterial\r\n     * @param options.computeBoundingBox\r\n     * @param options.autoFixFaceOrientation\r\n     * @param options.camera\r\n     * @example bSphereRadiusFactor = 1.0 / Math.sqrt(3.0) => the bounding sphere exactly matches a spherical mesh.\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        options?: {\r\n            updatable?: boolean;\r\n            isPickable?: boolean;\r\n            enableDepthSort?: boolean;\r\n            particleIntersection?: boolean;\r\n            boundingSphereOnly?: boolean;\r\n            bSphereRadiusFactor?: number;\r\n            expandable?: boolean;\r\n            useModelMaterial?: boolean;\r\n            enableMultiMaterial?: boolean;\r\n            computeBoundingBox?: boolean;\r\n            autoFixFaceOrientation?: boolean;\r\n            camera?: TargetCamera;\r\n        }\r\n    ) {\r\n        this.name = name;\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        this._camera = options && options.camera ? options.camera : <TargetCamera>scene.activeCamera;\r\n        this._pickable = options ? <boolean>options.isPickable : false;\r\n        this._depthSort = options ? <boolean>options.enableDepthSort : false;\r\n        this._multimaterialEnabled = options ? <boolean>options.enableMultiMaterial : false;\r\n        this._useModelMaterial = options ? <boolean>options.useModelMaterial : false;\r\n        this._multimaterialEnabled = this._useModelMaterial ? true : this._multimaterialEnabled;\r\n        this._expandable = options ? <boolean>options.expandable : false;\r\n        this._particlesIntersect = options ? <boolean>options.particleIntersection : false;\r\n        this._bSphereOnly = options ? <boolean>options.boundingSphereOnly : false;\r\n        this._bSphereRadiusFactor = options && options.bSphereRadiusFactor ? options.bSphereRadiusFactor : 1.0;\r\n        this._computeBoundingBox = options?.computeBoundingBox ? options.computeBoundingBox : false;\r\n        this._autoFixFaceOrientation = options?.autoFixFaceOrientation ? options.autoFixFaceOrientation : false;\r\n        if (options && options.updatable !== undefined) {\r\n            this._updatable = options.updatable;\r\n        } else {\r\n            this._updatable = true;\r\n        }\r\n        if (this._pickable) {\r\n            this.pickedBySubMesh = [[]];\r\n            this.pickedParticles = this.pickedBySubMesh[0];\r\n        }\r\n        if (this._depthSort || this._multimaterialEnabled) {\r\n            this.depthSortedParticles = [];\r\n        }\r\n        if (this._multimaterialEnabled) {\r\n            this._multimaterial = new MultiMaterial(this.name + \"MultiMaterial\", this._scene);\r\n            this._materials = [];\r\n            this._materialIndexesById = {};\r\n        }\r\n        this._tmpVertex = new SolidParticleVertex();\r\n    }\r\n\r\n    /**\r\n     * Builds the SPS underlying mesh. Returns a standard Mesh.\r\n     * If no model shape was added to the SPS, the returned mesh is just a single triangular plane.\r\n     * @returns the created mesh\r\n     */\r\n    public buildMesh(): Mesh {\r\n        if (!this._isNotBuilt && this.mesh) {\r\n            return this.mesh;\r\n        }\r\n        if (this.nbParticles === 0 && !this.mesh) {\r\n            const triangle = CreateDisc(\"\", { radius: 1, tessellation: 3 }, this._scene);\r\n            this.addShape(triangle, 1);\r\n            triangle.dispose();\r\n        }\r\n        this._indices32 = this._needs32Bits ? new Uint32Array(this._indices) : new Uint16Array(this._indices);\r\n        this._positions32 = new Float32Array(this._positions);\r\n        this._uvs32 = new Float32Array(this._uvs);\r\n        this._colors32 = new Float32Array(this._colors);\r\n\r\n        if (!this.mesh) {\r\n            // in case it's already expanded\r\n            const mesh = new Mesh(this.name, this._scene);\r\n            this.mesh = mesh;\r\n        }\r\n        if (!this._updatable && this._multimaterialEnabled) {\r\n            this._sortParticlesByMaterial(); // this may reorder the indices32\r\n        }\r\n        if (this.recomputeNormals) {\r\n            VertexData.ComputeNormals(this._positions32, this._indices32, this._normals);\r\n        }\r\n\r\n        this._normals32 = new Float32Array(this._normals);\r\n        this._fixedNormal32 = new Float32Array(this._normals);\r\n        if (this._mustUnrotateFixedNormals) {\r\n            // the particles could be created already rotated in the mesh with a positionFunction\r\n            this._unrotateFixedNormals();\r\n        }\r\n        const vertexData = new VertexData();\r\n        vertexData.indices = this._depthSort ? this._indices : this._indices32;\r\n        vertexData.set(this._positions32, VertexBuffer.PositionKind);\r\n        vertexData.set(this._normals32, VertexBuffer.NormalKind);\r\n\r\n        if (this._uvs32.length > 0) {\r\n            vertexData.set(this._uvs32, VertexBuffer.UVKind);\r\n        }\r\n        if (this._colors32.length > 0) {\r\n            vertexData.set(this._colors32, VertexBuffer.ColorKind);\r\n        }\r\n\r\n        vertexData.applyToMesh(this.mesh, this._updatable);\r\n        this.mesh.isPickable = this._pickable;\r\n\r\n        if (this._pickable) {\r\n            let faceId = 0;\r\n            for (let p = 0; p < this.nbParticles; p++) {\r\n                const part = this.particles[p];\r\n                const lind = part._model._indicesLength;\r\n                for (let i = 0; i < lind; i++) {\r\n                    const f = i % 3;\r\n                    if (f == 0) {\r\n                        const pickedData = { idx: part.idx, faceId: faceId };\r\n                        this.pickedParticles[faceId] = pickedData;\r\n                        faceId++;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._multimaterialEnabled) {\r\n            this.setMultiMaterial(this._materials);\r\n        }\r\n\r\n        if (!this._expandable) {\r\n            // free memory\r\n            if (!this._depthSort && !this._multimaterialEnabled && !this._autoFixFaceOrientation) {\r\n                (<any>this._indices) = null;\r\n            }\r\n            (<any>this._positions) = null;\r\n            (<any>this._normals) = null;\r\n            (<any>this._uvs) = null;\r\n            (<any>this._colors) = null;\r\n\r\n            if (!this._updatable) {\r\n                this.particles.length = 0;\r\n            }\r\n        }\r\n        this._isNotBuilt = false;\r\n        this.recomputeNormals = false;\r\n        this._recomputeInvisibles = true;\r\n        return this.mesh;\r\n    }\r\n\r\n    private _getUVKind(mesh: Mesh, uvKind: number) {\r\n        if (uvKind === -1) {\r\n            if ((mesh.material as StandardMaterial)?.diffuseTexture) {\r\n                uvKind = (mesh.material as StandardMaterial).diffuseTexture!.coordinatesIndex;\r\n            } else if ((mesh.material as PBRMaterial)?.albedoTexture) {\r\n                uvKind = (mesh.material as PBRMaterial).albedoTexture!.coordinatesIndex;\r\n            }\r\n        }\r\n\r\n        return \"uv\" + (uvKind ? uvKind + 1 : \"\");\r\n    }\r\n\r\n    /**\r\n     * Digests the mesh and generates as many solid particles in the system as wanted. Returns the SPS.\r\n     * These particles will have the same geometry than the mesh parts and will be positioned at the same localisation than the mesh original places.\r\n     * Thus the particles generated from `digest()` have their property `position` set yet.\r\n     * @param mesh ( Mesh ) is the mesh to be digested\r\n     * @param options {facetNb} (optional integer, default 1) is the number of mesh facets per particle, this parameter is overridden by the parameter `number` if any\r\n     * {delta} (optional integer, default 0) is the random extra number of facets per particle , each particle will have between `facetNb` and `facetNb + delta` facets\r\n     * {number} (optional positive integer) is the wanted number of particles : each particle is built with `mesh_total_facets / number` facets\r\n     * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.\r\n     * {uvKind} (optional positive integer, default 0) is the kind of UV to read from. Use -1 to deduce it from the diffuse/albedo texture (if any) of the mesh material\r\n     * @param options.facetNb\r\n     * @param options.number\r\n     * @param options.delta\r\n     * @param options.storage\r\n     * @param options.uvKind\r\n     * @returns the current SPS\r\n     */\r\n    public digest(mesh: Mesh, options?: { facetNb?: number; number?: number; delta?: number; storage?: []; uvKind?: number }): SolidParticleSystem {\r\n        let size: number = (options && options.facetNb) || 1;\r\n        let number: number = (options && options.number) || 0;\r\n        let delta: number = (options && options.delta) || 0;\r\n        const meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const meshInd = <IndicesArray>mesh.getIndices();\r\n        const meshUV = <FloatArray>mesh.getVerticesData(this._getUVKind(mesh, options?.uvKind ?? 0));\r\n        let meshCol = <FloatArray>mesh.getVerticesData(VertexBuffer.ColorKind);\r\n        const meshNor = <FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind);\r\n        const storage = options && options.storage ? options.storage : null;\r\n        // Normalize vertex colors to RGBA (4 components) since the code below always reads 4 components per color.\r\n        // Source meshes (e.g. from glTF) may provide RGB (3 components) vertex colors.\r\n        meshCol = this._normalizeMeshVertexColors(mesh, meshPos, meshCol)!;\r\n\r\n        let f: number = 0; // facet counter\r\n        const totalFacets: number = meshInd.length / 3; // a facet is a triangle, so 3 indices\r\n        // compute size from number\r\n        if (number) {\r\n            number = number > totalFacets ? totalFacets : number;\r\n            size = Math.round(totalFacets / number);\r\n            delta = 0;\r\n        } else {\r\n            size = size > totalFacets ? totalFacets : size;\r\n        }\r\n\r\n        const facetPos: number[] = []; // submesh positions\r\n        const facetNor: number[] = [];\r\n        const facetInd: number[] = []; // submesh indices\r\n        const facetUV: number[] = []; // submesh UV\r\n        const facetCol: number[] = []; // submesh colors\r\n        const barycenter: Vector3 = Vector3.Zero();\r\n        const sizeO: number = size;\r\n\r\n        while (f < totalFacets) {\r\n            size = sizeO + Math.floor((1 + delta) * Math.random());\r\n            if (f > totalFacets - size) {\r\n                size = totalFacets - f;\r\n            }\r\n            // reset temp arrays\r\n            facetPos.length = 0;\r\n            facetNor.length = 0;\r\n            facetInd.length = 0;\r\n            facetUV.length = 0;\r\n            facetCol.length = 0;\r\n\r\n            // iterate over \"size\" facets\r\n            let fi: number = 0;\r\n            for (let j = f * 3; j < (f + size) * 3; j++) {\r\n                facetInd.push(fi);\r\n                const i: number = meshInd[j];\r\n                const i3: number = i * 3;\r\n                facetPos.push(meshPos[i3], meshPos[i3 + 1], meshPos[i3 + 2]);\r\n                facetNor.push(meshNor[i3], meshNor[i3 + 1], meshNor[i3 + 2]);\r\n                if (meshUV) {\r\n                    const i2: number = i * 2;\r\n                    facetUV.push(meshUV[i2], meshUV[i2 + 1]);\r\n                }\r\n                if (meshCol) {\r\n                    const i4: number = i * 4;\r\n                    facetCol.push(meshCol[i4], meshCol[i4 + 1], meshCol[i4 + 2], meshCol[i4 + 3]);\r\n                }\r\n                fi++;\r\n            }\r\n\r\n            // create a model shape for each single particle\r\n            const idx: number = this.nbParticles;\r\n            const shape: Vector3[] = this._posToShape(facetPos);\r\n            const shapeUV: number[] = this._uvsToShapeUV(facetUV);\r\n            const shapeInd = facetInd.slice();\r\n            const shapeCol = facetCol.slice();\r\n            const shapeNor = facetNor.slice();\r\n\r\n            // compute the barycenter of the shape\r\n            barycenter.copyFromFloats(0, 0, 0);\r\n            let v: number;\r\n            for (v = 0; v < shape.length; v++) {\r\n                barycenter.addInPlace(shape[v]);\r\n            }\r\n            barycenter.scaleInPlace(1 / shape.length);\r\n\r\n            // shift the shape from its barycenter to the origin\r\n            // and compute the BBox required for intersection.\r\n            const minimum: Vector3 = new Vector3(Infinity, Infinity, Infinity);\r\n            const maximum: Vector3 = new Vector3(-Infinity, -Infinity, -Infinity);\r\n            for (v = 0; v < shape.length; v++) {\r\n                shape[v].subtractInPlace(barycenter);\r\n                minimum.minimizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);\r\n                maximum.maximizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);\r\n            }\r\n            let bInfo;\r\n            if (this._particlesIntersect) {\r\n                bInfo = new BoundingInfo(minimum, maximum);\r\n            }\r\n            let material = null;\r\n            if (this._useModelMaterial) {\r\n                material = mesh.material ? mesh.material : this._setDefaultMaterial();\r\n            }\r\n            const modelShape = new ModelShape(this._shapeCounter, shape, shapeInd, shapeNor, shapeCol, shapeUV, null, null, material);\r\n\r\n            // add the particle in the SPS\r\n            const currentPos = this._positions.length;\r\n            const currentInd = this._indices.length;\r\n            this._meshBuilder(\r\n                this._index,\r\n                currentInd,\r\n                shape,\r\n                this._positions,\r\n                shapeInd,\r\n                this._indices,\r\n                facetUV,\r\n                this._uvs,\r\n                shapeCol,\r\n                this._colors,\r\n                shapeNor,\r\n                this._normals,\r\n                idx,\r\n                0,\r\n                null,\r\n                modelShape\r\n            );\r\n            this._addParticle(idx, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, 0, bInfo, storage);\r\n            // initialize the particle position\r\n            this.particles[this.nbParticles].position.addInPlace(barycenter);\r\n\r\n            if (!storage) {\r\n                this._index += shape.length;\r\n                this.nbParticles++;\r\n                this._lastParticleId++;\r\n            }\r\n            this._shapeCounter++;\r\n            f += size;\r\n        }\r\n        this._isNotBuilt = true; // buildMesh() is now expected for setParticles() to work\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()\r\n     * @internal\r\n     */\r\n    protected _unrotateFixedNormals() {\r\n        let index = 0;\r\n        let idx = 0;\r\n        const tmpNormal = TmpVectors.Vector3[0];\r\n        const quaternion = TmpVectors.Quaternion[0];\r\n        const invertedRotMatrix = TmpVectors.Matrix[0];\r\n        for (let p = 0; p < this.particles.length; p++) {\r\n            const particle = this.particles[p];\r\n            const shape = particle._model._shape;\r\n\r\n            // computing the inverse of the rotation matrix from the quaternion\r\n            // is equivalent to computing the matrix of the inverse quaternion, i.e of the conjugate quaternion\r\n            if (particle.rotationQuaternion) {\r\n                particle.rotationQuaternion.conjugateToRef(quaternion);\r\n            } else {\r\n                const rotation = particle.rotation;\r\n                Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);\r\n                quaternion.conjugateInPlace();\r\n            }\r\n            quaternion.toRotationMatrix(invertedRotMatrix);\r\n\r\n            for (let pt = 0; pt < shape.length; pt++) {\r\n                idx = index + pt * 3;\r\n                Vector3.TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], invertedRotMatrix, tmpNormal);\r\n                tmpNormal.toArray(this._fixedNormal32, idx);\r\n            }\r\n            index = idx + 3;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Resets the temporary working copy particle\r\n     * @internal\r\n     */\r\n    protected _resetCopy() {\r\n        const copy = this._copy;\r\n        copy.position.setAll(0);\r\n        copy.rotation.setAll(0);\r\n        copy.rotationQuaternion = null;\r\n        copy.scaling.setAll(1);\r\n        copy.uvs.copyFromFloats(0.0, 0.0, 1.0, 1.0);\r\n        copy.color = null;\r\n        copy.translateFromPivot = false;\r\n        copy.shapeId = 0;\r\n        copy.materialIndex = null;\r\n    }\r\n\r\n    /**\r\n     * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays\r\n     * @param p the current index in the positions array to be updated\r\n     * @param ind the current index in the indices array\r\n     * @param shape a Vector3 array, the shape geometry\r\n     * @param positions the positions array to be updated\r\n     * @param meshInd the shape indices array\r\n     * @param indices the indices array to be updated\r\n     * @param meshUV the shape uv array\r\n     * @param uvs the uv array to be updated\r\n     * @param meshCol the shape color array\r\n     * @param colors the color array to be updated\r\n     * @param meshNor the shape normals array\r\n     * @param normals the normals array to be updated\r\n     * @param idx the particle index\r\n     * @param idxInShape the particle index in its shape\r\n     * @param options the addShape() method  passed options\r\n     * @param model\r\n     * @model the particle model\r\n     * @internal\r\n     */\r\n    protected _meshBuilder(\r\n        p: number,\r\n        ind: number,\r\n        shape: Vector3[],\r\n        positions: number[],\r\n        meshInd: IndicesArray,\r\n        indices: number[],\r\n        meshUV: FloatArray,\r\n        uvs: number[],\r\n        meshCol: FloatArray,\r\n        colors: number[],\r\n        meshNor: FloatArray,\r\n        normals: number[],\r\n        idx: number,\r\n        idxInShape: number,\r\n        options: any,\r\n        model: ModelShape\r\n    ): SolidParticle {\r\n        let i;\r\n        let u = 0;\r\n        let c = 0;\r\n        let n = 0;\r\n\r\n        this._resetCopy();\r\n        const copy = this._copy;\r\n        const storeApart = options && options.storage ? true : false;\r\n        copy.idx = idx;\r\n        copy.idxInShape = idxInShape;\r\n        copy.shapeId = model.shapeId;\r\n        if (this._useModelMaterial) {\r\n            const materialId = model._material!.uniqueId;\r\n            const materialIndexesById = this._materialIndexesById;\r\n            if (!Object.prototype.hasOwnProperty.call(materialIndexesById, materialId)) {\r\n                materialIndexesById[materialId] = this._materials.length;\r\n                this._materials.push(model._material!);\r\n            }\r\n            const matIdx = materialIndexesById[materialId];\r\n            copy.materialIndex = matIdx;\r\n        }\r\n\r\n        if (options && options.positionFunction) {\r\n            // call to custom positionFunction\r\n            options.positionFunction(copy, idx, idxInShape);\r\n            this._mustUnrotateFixedNormals = true;\r\n        }\r\n\r\n        // in case the particle geometry must NOT be inserted in the SPS mesh geometry\r\n        if (storeApart) {\r\n            return copy;\r\n        }\r\n\r\n        const rotMatrix = TmpVectors.Matrix[0];\r\n        const tmpVertex = this._tmpVertex;\r\n        const tmpVector = tmpVertex.position;\r\n        const tmpColor = tmpVertex.color;\r\n        const tmpUV = tmpVertex.uv;\r\n        const tmpRotated = TmpVectors.Vector3[1];\r\n        const pivotBackTranslation = TmpVectors.Vector3[2];\r\n        const scaledPivot = TmpVectors.Vector3[3];\r\n        Matrix.IdentityToRef(rotMatrix);\r\n        copy.getRotationMatrix(rotMatrix);\r\n\r\n        copy.pivot.multiplyToRef(copy.scaling, scaledPivot);\r\n\r\n        if (copy.translateFromPivot) {\r\n            pivotBackTranslation.setAll(0.0);\r\n        } else {\r\n            pivotBackTranslation.copyFrom(scaledPivot);\r\n        }\r\n\r\n        const someVertexFunction = options && options.vertexFunction;\r\n        for (i = 0; i < shape.length; i++) {\r\n            tmpVector.copyFrom(shape[i]);\r\n            if (copy.color) {\r\n                tmpColor.copyFrom(copy.color);\r\n            }\r\n            if (meshUV) {\r\n                tmpUV.copyFromFloats(meshUV[u], meshUV[u + 1]);\r\n            }\r\n            if (someVertexFunction) {\r\n                options.vertexFunction(copy, tmpVertex, i);\r\n            }\r\n\r\n            tmpVector.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);\r\n            Vector3.TransformCoordinatesToRef(tmpVector, rotMatrix, tmpRotated);\r\n            tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position);\r\n            positions.push(tmpRotated.x, tmpRotated.y, tmpRotated.z);\r\n\r\n            if (meshUV) {\r\n                const copyUvs = copy.uvs;\r\n                uvs.push((copyUvs.z - copyUvs.x) * tmpUV.x + copyUvs.x, (copyUvs.w - copyUvs.y) * tmpUV.y + copyUvs.y);\r\n                u += 2;\r\n            }\r\n\r\n            if (copy.color) {\r\n                this._color.copyFrom(tmpColor);\r\n            } else {\r\n                const color = this._color;\r\n                if (meshCol && meshCol[c] !== undefined) {\r\n                    color.r = meshCol[c];\r\n                    color.g = meshCol[c + 1];\r\n                    color.b = meshCol[c + 2];\r\n                    color.a = meshCol[c + 3];\r\n                } else {\r\n                    color.r = 1.0;\r\n                    color.g = 1.0;\r\n                    color.b = 1.0;\r\n                    color.a = 1.0;\r\n                }\r\n            }\r\n            colors.push(this._color.r, this._color.g, this._color.b, this._color.a);\r\n            c += 4;\r\n\r\n            if (!this.recomputeNormals && meshNor) {\r\n                Vector3.TransformNormalFromFloatsToRef(meshNor[n], meshNor[n + 1], meshNor[n + 2], rotMatrix, tmpVector);\r\n                normals.push(tmpVector.x, tmpVector.y, tmpVector.z);\r\n                n += 3;\r\n            }\r\n        }\r\n\r\n        for (i = 0; i < meshInd.length; i++) {\r\n            const currentInd = p + meshInd[i];\r\n            indices.push(currentInd);\r\n            if (currentInd > 65535) {\r\n                this._needs32Bits = true;\r\n            }\r\n        }\r\n\r\n        if (this._depthSort || this._multimaterialEnabled) {\r\n            const matIndex = copy.materialIndex !== null ? copy.materialIndex : 0;\r\n            this.depthSortedParticles.push(new DepthSortedParticle(idx, ind, meshInd.length, matIndex));\r\n        }\r\n\r\n        return copy;\r\n    }\r\n\r\n    /**\r\n     * Returns a shape Vector3 array from positions float array\r\n     * @param positions float array\r\n     * @returns a vector3 array\r\n     * @internal\r\n     */\r\n    protected _posToShape(positions: FloatArray): Vector3[] {\r\n        const shape = [];\r\n        for (let i = 0; i < positions.length; i += 3) {\r\n            shape.push(Vector3.FromArray(positions, i));\r\n        }\r\n        return shape;\r\n    }\r\n\r\n    /**\r\n     * Returns a shapeUV array from a float uvs (array deep copy)\r\n     * @param uvs as a float array\r\n     * @returns a shapeUV array\r\n     * @internal\r\n     */\r\n    protected _uvsToShapeUV(uvs: FloatArray): number[] {\r\n        const shapeUV = [];\r\n        if (uvs) {\r\n            for (let i = 0; i < uvs.length; i++) {\r\n                shapeUV.push(uvs[i]);\r\n            }\r\n        }\r\n        return shapeUV;\r\n    }\r\n\r\n    /**\r\n     * Adds a new particle object in the particles array\r\n     * @param idx particle index in particles array\r\n     * @param id particle id\r\n     * @param idxpos positionIndex : the starting index of the particle vertices in the SPS \"positions\" array\r\n     * @param idxind indiceIndex : he starting index of the particle indices in the SPS \"indices\" array\r\n     * @param model particle ModelShape object\r\n     * @param shapeId model shape identifier\r\n     * @param idxInShape index of the particle in the current model\r\n     * @param bInfo model bounding info object\r\n     * @param storage target storage array, if any\r\n     * @internal\r\n     */\r\n    protected _addParticle(\r\n        idx: number,\r\n        id: number,\r\n        idxpos: number,\r\n        idxind: number,\r\n        model: ModelShape,\r\n        shapeId: number,\r\n        idxInShape: number,\r\n        bInfo: Nullable<BoundingInfo> = null,\r\n        storage: Nullable<[]> = null\r\n    ): SolidParticle {\r\n        const sp = new SolidParticle(idx, id, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);\r\n        const target = storage ? storage : this.particles;\r\n        target.push(sp);\r\n        return sp;\r\n    }\r\n\r\n    private _normalizeMeshVertexColors(mesh: AbstractMesh, meshPos: FloatArray, meshCol: Nullable<FloatArray>): Nullable<FloatArray> {\r\n        if (!meshCol) {\r\n            return meshCol;\r\n        }\r\n        const vertexCount = meshPos.length / 3;\r\n        if (!vertexCount) {\r\n            return meshCol;\r\n        }\r\n        const colorBuffer = mesh.getVertexBuffer(VertexBuffer.ColorKind);\r\n        const colorStride = colorBuffer ? colorBuffer.getSize() : Math.round(meshCol.length / vertexCount);\r\n        if (colorStride !== 3 || meshCol.length !== vertexCount * 3) {\r\n            return meshCol;\r\n        }\r\n        const rgba = new Float32Array(vertexCount * 4);\r\n        for (let i = 0; i < vertexCount; i++) {\r\n            const rgbIndex = i * 3;\r\n            const rgbaIndex = i * 4;\r\n            rgba[rgbaIndex] = meshCol[rgbIndex];\r\n            rgba[rgbaIndex + 1] = meshCol[rgbIndex + 1];\r\n            rgba[rgbaIndex + 2] = meshCol[rgbIndex + 2];\r\n            rgba[rgbaIndex + 3] = 1;\r\n        }\r\n        return rgba;\r\n    }\r\n\r\n    /**\r\n     * Adds some particles to the SPS from the model shape. Returns the shape id.\r\n     * Please read the doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/immutable_sps\r\n     * @param mesh is any Mesh object that will be used as a model for the solid particles. If the mesh does not have vertex normals, it will turn on the recomputeNormals attribute.\r\n     * @param nb (positive integer) the number of particles to be created from this model\r\n     * @param options {positionFunction} is an optional javascript function to called for each particle on SPS creation.\r\n     * {vertexFunction} is an optional javascript function to called for each vertex of each particle on SPS creation\r\n     * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.\r\n     * @param options.positionFunction\r\n     * @param options.vertexFunction\r\n     * @param options.storage\r\n     * @returns the number of shapes in the system\r\n     */\r\n    public addShape(mesh: AbstractMesh, nb: number, options?: { positionFunction?: any; vertexFunction?: any; storage?: [] }): number {\r\n        const meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const meshInd = <IndicesArray>mesh.getIndices();\r\n        const meshUV = <FloatArray>mesh.getVerticesData(VertexBuffer.UVKind);\r\n        let meshCol = <FloatArray>mesh.getVerticesData(VertexBuffer.ColorKind);\r\n        const meshNor = <FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind);\r\n        this.recomputeNormals = meshNor ? false : true;\r\n        // Normalize vertex colors to RGBA (4 components) since _meshBuilder always reads 4 components per color.\r\n        // Source meshes (e.g. from glTF) may provide RGB (3 components) vertex colors.\r\n        meshCol = this._normalizeMeshVertexColors(mesh, meshPos, meshCol)!;\r\n        const indices = Array.from(meshInd);\r\n        const shapeNormals = meshNor ? Array.from(meshNor) : [];\r\n        const shapeColors = meshCol ? Array.from(meshCol) : [];\r\n        const storage = options && options.storage ? options.storage : null;\r\n        let bbInfo: Nullable<BoundingInfo> = null;\r\n        if (this._particlesIntersect) {\r\n            bbInfo = mesh.getBoundingInfo();\r\n        }\r\n\r\n        const shape = this._posToShape(meshPos);\r\n        const shapeUV = this._uvsToShapeUV(meshUV);\r\n\r\n        const posfunc = options ? options.positionFunction : null;\r\n        const vtxfunc = options ? options.vertexFunction : null;\r\n        let material = null;\r\n        if (this._useModelMaterial) {\r\n            material = mesh.material ? mesh.material : this._setDefaultMaterial();\r\n        }\r\n        const modelShape = new ModelShape(this._shapeCounter, shape, indices, shapeNormals, shapeColors, shapeUV, posfunc, vtxfunc, material);\r\n\r\n        // particles\r\n        for (let i = 0; i < nb; i++) {\r\n            this._insertNewParticle(this.nbParticles, i, modelShape, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, storage, options);\r\n        }\r\n        this._shapeCounter++;\r\n        this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\r\n        return this._shapeCounter - 1;\r\n    }\r\n\r\n    /**\r\n     * Rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices\r\n     * @internal\r\n     */\r\n    protected _rebuildParticle(particle: SolidParticle, reset: boolean = false): void {\r\n        this._resetCopy();\r\n        const copy = this._copy;\r\n        if (particle._model._positionFunction) {\r\n            // recall to stored custom positionFunction\r\n            particle._model._positionFunction(copy, particle.idx, particle.idxInShape);\r\n        }\r\n\r\n        const rotMatrix = TmpVectors.Matrix[0];\r\n        const tmpVertex = TmpVectors.Vector3[0];\r\n        const tmpRotated = TmpVectors.Vector3[1];\r\n        const pivotBackTranslation = TmpVectors.Vector3[2];\r\n        const scaledPivot = TmpVectors.Vector3[3];\r\n\r\n        copy.getRotationMatrix(rotMatrix);\r\n\r\n        particle.pivot.multiplyToRef(particle.scaling, scaledPivot);\r\n\r\n        if (copy.translateFromPivot) {\r\n            pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);\r\n        } else {\r\n            pivotBackTranslation.copyFrom(scaledPivot);\r\n        }\r\n\r\n        const shape = particle._model._shape;\r\n\r\n        for (let pt = 0; pt < shape.length; pt++) {\r\n            tmpVertex.copyFrom(shape[pt]);\r\n            if (particle._model._vertexFunction) {\r\n                particle._model._vertexFunction(copy, tmpVertex, pt); // recall to stored vertexFunction\r\n            }\r\n\r\n            tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);\r\n            Vector3.TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);\r\n            tmpRotated\r\n                .addInPlace(pivotBackTranslation)\r\n                .addInPlace(copy.position)\r\n                .toArray(this._positions32, particle._pos + pt * 3);\r\n        }\r\n        if (reset) {\r\n            particle.position.setAll(0.0);\r\n            particle.rotation.setAll(0.0);\r\n            particle.rotationQuaternion = null;\r\n            particle.scaling.setAll(1.0);\r\n            particle.uvs.setAll(0.0);\r\n            particle.pivot.setAll(0.0);\r\n            particle.translateFromPivot = false;\r\n            particle.parentId = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the whole mesh and updates the VBO : custom positions and vertices are recomputed if needed.\r\n     * @param reset boolean, default false : if the particles must be reset at position and rotation zero, scaling 1, color white, initial UVs and not parented.\r\n     * @returns the SPS.\r\n     */\r\n    public rebuildMesh(reset: boolean = false): SolidParticleSystem {\r\n        for (let p = 0; p < this.particles.length; p++) {\r\n            this._rebuildParticle(this.particles[p], reset);\r\n        }\r\n        this.mesh.updateVerticesData(VertexBuffer.PositionKind, this._positions32, false, false);\r\n        return this;\r\n    }\r\n\r\n    /** Removes the particles from the start-th to the end-th included from an expandable SPS (required).\r\n     *  Returns an array with the removed particles.\r\n     *  If the number of particles to remove is lower than zero or greater than the global remaining particle number, then an empty array is returned.\r\n     *  The SPS can't be empty so at least one particle needs to remain in place.\r\n     *  Under the hood, the VertexData array, so the VBO buffer, is recreated each call.\r\n     * @param start index of the first particle to remove\r\n     * @param end index of the last particle to remove (included)\r\n     * @returns an array populated with the removed particles\r\n     */\r\n    public removeParticles(start: number, end: number): SolidParticle[] {\r\n        const nb = end - start + 1;\r\n        if (!this._expandable || nb <= 0 || nb >= this.nbParticles || !this._updatable) {\r\n            return [];\r\n        }\r\n        const particles = this.particles;\r\n        const currentNb = this.nbParticles;\r\n        if (end < currentNb - 1) {\r\n            // update the particle indexes in the positions array in case they're remaining particles after the last removed\r\n            const firstRemaining = end + 1;\r\n            const shiftPos = particles[firstRemaining]._pos - particles[start]._pos;\r\n            const shifInd = particles[firstRemaining]._ind - particles[start]._ind;\r\n            for (let i = firstRemaining; i < currentNb; i++) {\r\n                const part = particles[i];\r\n                part._pos -= shiftPos;\r\n                part._ind -= shifInd;\r\n            }\r\n        }\r\n        const removed = particles.splice(start, nb);\r\n        this._positions.length = 0;\r\n        this._indices.length = 0;\r\n        this._colors.length = 0;\r\n        this._uvs.length = 0;\r\n        this._normals.length = 0;\r\n        this._index = 0;\r\n        this._idxOfId.length = 0;\r\n        if (this._depthSort || this._multimaterialEnabled) {\r\n            this.depthSortedParticles = [];\r\n        }\r\n        let ind = 0;\r\n        const particlesLength = particles.length;\r\n        for (let p = 0; p < particlesLength; p++) {\r\n            const particle = particles[p];\r\n            const model = particle._model;\r\n            const shape = model._shape;\r\n            const modelIndices = model._indices;\r\n            const modelNormals = model._normals;\r\n            const modelColors = model._shapeColors;\r\n            const modelUVs = model._shapeUV;\r\n            particle.idx = p;\r\n            this._idxOfId[particle.id] = p;\r\n            this._meshBuilder(\r\n                this._index,\r\n                ind,\r\n                shape,\r\n                this._positions,\r\n                modelIndices,\r\n                this._indices,\r\n                modelUVs,\r\n                this._uvs,\r\n                modelColors,\r\n                this._colors,\r\n                modelNormals,\r\n                this._normals,\r\n                particle.idx,\r\n                particle.idxInShape,\r\n                null,\r\n                model\r\n            );\r\n            this._index += shape.length;\r\n            ind += modelIndices.length;\r\n        }\r\n        this.nbParticles -= nb;\r\n        this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\r\n        return removed;\r\n    }\r\n\r\n    /**\r\n     * Inserts some pre-created particles in the solid particle system so that they can be managed by setParticles().\r\n     * @param solidParticleArray an array populated with Solid Particles objects\r\n     * @returns the SPS\r\n     */\r\n    public insertParticlesFromArray(solidParticleArray: SolidParticle[]): SolidParticleSystem {\r\n        if (!this._expandable) {\r\n            return this;\r\n        }\r\n        let idxInShape = 0;\r\n        let currentShapeId = solidParticleArray[0].shapeId;\r\n        const nb = solidParticleArray.length;\r\n        for (let i = 0; i < nb; i++) {\r\n            const sp = solidParticleArray[i];\r\n            const model = sp._model;\r\n            const shape = model._shape;\r\n            const meshInd = model._indices;\r\n            const meshUV = model._shapeUV;\r\n            const meshCol = model._shapeColors;\r\n            const meshNor = model._normals;\r\n            const noNor = meshNor ? false : true;\r\n            this.recomputeNormals = noNor || this.recomputeNormals;\r\n            const bbInfo = sp.getBoundingInfo();\r\n            const newPart = this._insertNewParticle(this.nbParticles, idxInShape, model, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, null, null);\r\n            sp.copyToRef(newPart!);\r\n            idxInShape++;\r\n            if (currentShapeId != sp.shapeId) {\r\n                currentShapeId = sp.shapeId;\r\n                idxInShape = 0;\r\n            }\r\n        }\r\n        this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Creates a new particle and modifies the SPS mesh geometry :\r\n     * - calls _meshBuilder() to increase the SPS mesh geometry step by step\r\n     * - calls _addParticle() to populate the particle array\r\n     * factorized code from addShape() and insertParticlesFromArray()\r\n     * @param idx particle index in the particles array\r\n     * @param i particle index in its shape\r\n     * @param modelShape particle ModelShape object\r\n     * @param shape shape vertex array\r\n     * @param meshInd shape indices array\r\n     * @param meshUV shape uv array\r\n     * @param meshCol shape color array\r\n     * @param meshNor shape normals array\r\n     * @param bbInfo shape bounding info\r\n     * @param storage target particle storage\r\n     * @param options\r\n     * @options addShape() passed options\r\n     * @internal\r\n     */\r\n    protected _insertNewParticle(\r\n        idx: number,\r\n        i: number,\r\n        modelShape: ModelShape,\r\n        shape: Vector3[],\r\n        meshInd: IndicesArray,\r\n        meshUV: FloatArray,\r\n        meshCol: FloatArray,\r\n        meshNor: FloatArray,\r\n        bbInfo: Nullable<BoundingInfo>,\r\n        storage: Nullable<[]>,\r\n        options: any\r\n    ): Nullable<SolidParticle> {\r\n        const currentPos = this._positions.length;\r\n        const currentInd = this._indices.length;\r\n        const currentCopy = this._meshBuilder(\r\n            this._index,\r\n            currentInd,\r\n            shape,\r\n            this._positions,\r\n            meshInd,\r\n            this._indices,\r\n            meshUV,\r\n            this._uvs,\r\n            meshCol,\r\n            this._colors,\r\n            meshNor,\r\n            this._normals,\r\n            idx,\r\n            i,\r\n            options,\r\n            modelShape\r\n        );\r\n        let sp: Nullable<SolidParticle> = null;\r\n        if (this._updatable) {\r\n            sp = this._addParticle(this.nbParticles, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo, storage);\r\n            sp.position.copyFrom(currentCopy.position);\r\n            sp.rotation.copyFrom(currentCopy.rotation);\r\n            if (currentCopy.rotationQuaternion) {\r\n                if (sp.rotationQuaternion) {\r\n                    sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);\r\n                } else {\r\n                    sp.rotationQuaternion = currentCopy.rotationQuaternion.clone();\r\n                }\r\n            }\r\n            if (currentCopy.color) {\r\n                if (sp.color) {\r\n                    sp.color.copyFrom(currentCopy.color);\r\n                } else {\r\n                    sp.color = currentCopy.color.clone();\r\n                }\r\n            }\r\n            sp.scaling.copyFrom(currentCopy.scaling);\r\n            sp.uvs.copyFrom(currentCopy.uvs);\r\n            if (currentCopy.materialIndex !== null) {\r\n                sp.materialIndex = currentCopy.materialIndex;\r\n            }\r\n            if (this.expandable) {\r\n                this._idxOfId[sp.id] = sp.idx;\r\n            }\r\n        }\r\n        if (!storage) {\r\n            this._index += shape.length;\r\n            this.nbParticles++;\r\n            this._lastParticleId++;\r\n        }\r\n        return sp;\r\n    }\r\n\r\n    /**\r\n     *  Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.\r\n     *  This method calls `updateParticle()` for each particle of the SPS.\r\n     *  For an animated SPS, it is usually called within the render loop.\r\n     * This methods does nothing if called on a non updatable or not yet built SPS. Example : buildMesh() not called after having added or removed particles from an expandable SPS.\r\n     * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_\r\n     * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_\r\n     * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_\r\n     * @returns the SPS.\r\n     */\r\n    public setParticles(start: number = 0, end: number = this.nbParticles - 1, update: boolean = true): SolidParticleSystem {\r\n        if (!this._updatable || this._isNotBuilt) {\r\n            return this;\r\n        }\r\n\r\n        // custom beforeUpdate\r\n        this.beforeUpdateParticles(start, end, update);\r\n\r\n        const rotMatrix = TmpVectors.Matrix[0];\r\n        const invertedMatrix = TmpVectors.Matrix[1];\r\n        const mesh = this.mesh;\r\n        const colors32 = this._colors32;\r\n        const positions32 = this._positions32;\r\n        const normals32 = this._normals32;\r\n        const uvs32 = this._uvs32;\r\n        const indices32 = this._indices32;\r\n        const indices = this._indices;\r\n        const fixedNormal32 = this._fixedNormal32;\r\n        const depthSortParticles = this._depthSort && this._depthSortParticles;\r\n\r\n        const tempVectors = TmpVectors.Vector3;\r\n        const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);\r\n        const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);\r\n        const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);\r\n        const minimum = tempVectors[8].setAll(Number.MAX_VALUE);\r\n        const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);\r\n        const camInvertedPosition = tempVectors[10].setAll(0);\r\n\r\n        const tmpVertex = this._tmpVertex;\r\n        const tmpVector = tmpVertex.position;\r\n        const tmpColor = tmpVertex.color;\r\n        const tmpUV = tmpVertex.uv;\r\n\r\n        // cases when the World Matrix is to be computed first\r\n        if (this.billboard || this._depthSort) {\r\n            this.mesh.computeWorldMatrix(true);\r\n            this.mesh._worldMatrix.invertToRef(invertedMatrix);\r\n        }\r\n        const camera = this._camera ? this._camera : this._scene.activeCamera ? this._scene.activeCamera : this._scene.cameras[0];\r\n        // if the particles will always face the camera\r\n        if (this.billboard) {\r\n            // compute the camera position and un-rotate it by the current mesh rotation\r\n            const tmpVector0 = tempVectors[0];\r\n            camera.getDirectionToRef(Axis.Z, tmpVector0);\r\n            Vector3.TransformNormalToRef(tmpVector0, invertedMatrix, camAxisZ);\r\n            camAxisZ.normalize();\r\n            // same for camera up vector extracted from the cam view matrix\r\n            const view = camera.getViewMatrix(true);\r\n            Vector3.TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], invertedMatrix, camAxisY);\r\n            Vector3.CrossToRef(camAxisY, camAxisZ, camAxisX);\r\n            camAxisY.normalize();\r\n            camAxisX.normalize();\r\n        }\r\n\r\n        // if depthSort, compute the camera global position in the mesh local system\r\n        if (this._depthSort) {\r\n            Vector3.TransformCoordinatesToRef(camera.globalPosition, invertedMatrix, camInvertedPosition); // then un-rotate the camera\r\n        }\r\n\r\n        Matrix.IdentityToRef(rotMatrix);\r\n        let idx = 0; // current position index in the global array positions32\r\n        let index: number; // position start index in the global array positions32 of the current particle\r\n        let colidx: number = 0; // current color index in the global array colors32\r\n        let colorIndex: number; // color start index in the global array colors32 of the current particle\r\n        let uvidx: number = 0; // current uv index in the global array uvs32\r\n        let uvIndex: number; // uv start index in the global array uvs32 of the current particle\r\n        let pt: number; // current index in the particle model shape\r\n\r\n        if (this.mesh.isFacetDataEnabled) {\r\n            this._computeBoundingBox = true;\r\n        }\r\n\r\n        end = end >= this.nbParticles ? this.nbParticles - 1 : end;\r\n        if (this._computeBoundingBox) {\r\n            if (start != 0 || end != this.nbParticles - 1) {\r\n                // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.\r\n                const boundingInfo = this.mesh.getBoundingInfo();\r\n                if (boundingInfo) {\r\n                    minimum.copyFrom(boundingInfo.minimum);\r\n                    maximum.copyFrom(boundingInfo.maximum);\r\n                }\r\n            }\r\n        }\r\n\r\n        // particle loop\r\n        index = this.particles[start]._pos;\r\n        const vpos = (index / 3) | 0;\r\n        colorIndex = vpos * 4;\r\n        uvIndex = vpos * 2;\r\n\r\n        // Calculate scaled update speed based on animation ratio (for FPS independence)\r\n        if (this._started && !this._stopped) {\r\n            this._scaledUpdateSpeed = this.updateSpeed * (this._scene?.getAnimationRatio() || 1);\r\n        }\r\n\r\n        for (let p = start; p <= end; p++) {\r\n            const particle = this.particles[p];\r\n\r\n            // Update particle age and check lifetime\r\n            if (this._started && !this._stopped) {\r\n                particle.age += this._scaledUpdateSpeed;\r\n                // Only check lifetime if it's finite (Infinity means particle never dies)\r\n                if (isFinite(particle.lifeTime) && particle.age >= particle.lifeTime) {\r\n                    particle.alive = false;\r\n                }\r\n            }\r\n\r\n            // call to custom user function to update the particle properties\r\n            this.updateParticle(particle);\r\n\r\n            const shape = particle._model._shape;\r\n            const shapeUV = particle._model._shapeUV;\r\n            const particleRotationMatrix = particle._rotationMatrix;\r\n            const particlePosition = particle.position;\r\n            const particleRotation = particle.rotation;\r\n            const particleScaling = particle.scaling;\r\n            const particleGlobalPosition = particle._globalPosition;\r\n\r\n            // camera-particle distance for depth sorting\r\n            if (depthSortParticles) {\r\n                const dsp = this.depthSortedParticles[p];\r\n                dsp.idx = particle.idx;\r\n                dsp.ind = particle._ind;\r\n                dsp.indicesLength = particle._model._indicesLength;\r\n                dsp.sqDistance = Vector3.DistanceSquared(particle.position, camInvertedPosition);\r\n            }\r\n\r\n            // skip the computations for inactive or already invisible particles\r\n            if (!particle.alive || (particle._stillInvisible && !particle.isVisible && !this._recomputeInvisibles)) {\r\n                // increment indexes for the next particle\r\n                pt = shape.length;\r\n                index += pt * 3;\r\n                colorIndex += pt * 4;\r\n                uvIndex += pt * 2;\r\n                continue;\r\n            }\r\n\r\n            if (particle.isVisible) {\r\n                particle._stillInvisible = false; // un-mark permanent invisibility\r\n\r\n                const scaledPivot = tempVectors[12];\r\n                particle.pivot.multiplyToRef(particleScaling, scaledPivot);\r\n\r\n                // particle rotation matrix\r\n                if (this.billboard) {\r\n                    particleRotation.x = 0.0;\r\n                    particleRotation.y = 0.0;\r\n                }\r\n                if (this._computeParticleRotation || this.billboard) {\r\n                    particle.getRotationMatrix(rotMatrix);\r\n                }\r\n\r\n                const particleHasParent = particle.parentId !== null;\r\n                if (particleHasParent) {\r\n                    const parent = this.getParticleById(particle.parentId!);\r\n                    if (parent) {\r\n                        const parentRotationMatrix = parent._rotationMatrix;\r\n                        const parentGlobalPosition = parent._globalPosition;\r\n\r\n                        const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];\r\n                        const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];\r\n                        const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];\r\n\r\n                        particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;\r\n                        particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;\r\n                        particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;\r\n\r\n                        if (this._computeParticleRotation || this.billboard) {\r\n                            const rotMatrixValues = rotMatrix.m;\r\n                            particleRotationMatrix[0] =\r\n                                rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];\r\n                            particleRotationMatrix[1] =\r\n                                rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];\r\n                            particleRotationMatrix[2] =\r\n                                rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];\r\n                            particleRotationMatrix[3] =\r\n                                rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];\r\n                            particleRotationMatrix[4] =\r\n                                rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];\r\n                            particleRotationMatrix[5] =\r\n                                rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];\r\n                            particleRotationMatrix[6] =\r\n                                rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];\r\n                            particleRotationMatrix[7] =\r\n                                rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];\r\n                            particleRotationMatrix[8] =\r\n                                rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];\r\n                        }\r\n                    } else {\r\n                        // in case the parent were removed at some moment\r\n                        particle.parentId = null;\r\n                    }\r\n                } else {\r\n                    particleGlobalPosition.x = particlePosition.x;\r\n                    particleGlobalPosition.y = particlePosition.y;\r\n                    particleGlobalPosition.z = particlePosition.z;\r\n\r\n                    if (this._computeParticleRotation || this.billboard) {\r\n                        const rotMatrixValues = rotMatrix.m;\r\n                        particleRotationMatrix[0] = rotMatrixValues[0];\r\n                        particleRotationMatrix[1] = rotMatrixValues[1];\r\n                        particleRotationMatrix[2] = rotMatrixValues[2];\r\n                        particleRotationMatrix[3] = rotMatrixValues[4];\r\n                        particleRotationMatrix[4] = rotMatrixValues[5];\r\n                        particleRotationMatrix[5] = rotMatrixValues[6];\r\n                        particleRotationMatrix[6] = rotMatrixValues[8];\r\n                        particleRotationMatrix[7] = rotMatrixValues[9];\r\n                        particleRotationMatrix[8] = rotMatrixValues[10];\r\n                    }\r\n                }\r\n\r\n                const pivotBackTranslation = tempVectors[11];\r\n                if (particle.translateFromPivot) {\r\n                    pivotBackTranslation.setAll(0.0);\r\n                } else {\r\n                    pivotBackTranslation.copyFrom(scaledPivot);\r\n                }\r\n\r\n                // particle vertex loop\r\n                for (pt = 0; pt < shape.length; pt++) {\r\n                    idx = index + pt * 3;\r\n                    colidx = colorIndex + pt * 4;\r\n                    uvidx = uvIndex + pt * 2;\r\n                    const iu = 2 * pt;\r\n                    const iv = iu + 1;\r\n\r\n                    tmpVector.copyFrom(shape[pt]);\r\n                    if (this._computeParticleColor && particle.color) {\r\n                        tmpColor.copyFrom(particle.color);\r\n                    }\r\n                    if (this._computeParticleTexture) {\r\n                        tmpUV.copyFromFloats(shapeUV[iu], shapeUV[iv]);\r\n                    }\r\n                    if (this._computeParticleVertex) {\r\n                        this.updateParticleVertex(particle, tmpVertex, pt);\r\n                    }\r\n\r\n                    // positions\r\n                    const vertexX = tmpVector.x * particleScaling.x - scaledPivot.x;\r\n                    const vertexY = tmpVector.y * particleScaling.y - scaledPivot.y;\r\n                    const vertexZ = tmpVector.z * particleScaling.z - scaledPivot.z;\r\n\r\n                    let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];\r\n                    let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];\r\n                    let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];\r\n\r\n                    rotatedX += pivotBackTranslation.x;\r\n                    rotatedY += pivotBackTranslation.y;\r\n                    rotatedZ += pivotBackTranslation.z;\r\n\r\n                    const px = (positions32[idx] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ);\r\n                    const py = (positions32[idx + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ);\r\n                    const pz = (positions32[idx + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ);\r\n\r\n                    if (this._computeBoundingBox) {\r\n                        minimum.minimizeInPlaceFromFloats(px, py, pz);\r\n                        maximum.maximizeInPlaceFromFloats(px, py, pz);\r\n                    }\r\n\r\n                    // normals : if the particles can't be morphed then just rotate the normals, what is much more faster than ComputeNormals()\r\n                    if (!this._computeParticleVertex) {\r\n                        const normalx = fixedNormal32[idx];\r\n                        const normaly = fixedNormal32[idx + 1];\r\n                        const normalz = fixedNormal32[idx + 2];\r\n\r\n                        const rotatedx = normalx * particleRotationMatrix[0] + normaly * particleRotationMatrix[3] + normalz * particleRotationMatrix[6];\r\n                        const rotatedy = normalx * particleRotationMatrix[1] + normaly * particleRotationMatrix[4] + normalz * particleRotationMatrix[7];\r\n                        const rotatedz = normalx * particleRotationMatrix[2] + normaly * particleRotationMatrix[5] + normalz * particleRotationMatrix[8];\r\n\r\n                        normals32[idx] = camAxisX.x * rotatedx + camAxisY.x * rotatedy + camAxisZ.x * rotatedz;\r\n                        normals32[idx + 1] = camAxisX.y * rotatedx + camAxisY.y * rotatedy + camAxisZ.y * rotatedz;\r\n                        normals32[idx + 2] = camAxisX.z * rotatedx + camAxisY.z * rotatedy + camAxisZ.z * rotatedz;\r\n                    }\r\n\r\n                    if (this._computeParticleColor && particle.color) {\r\n                        const colors32 = this._colors32;\r\n                        colors32[colidx] = tmpColor.r;\r\n                        colors32[colidx + 1] = tmpColor.g;\r\n                        colors32[colidx + 2] = tmpColor.b;\r\n                        colors32[colidx + 3] = tmpColor.a;\r\n                    }\r\n\r\n                    if (this._computeParticleTexture) {\r\n                        const uvs = particle.uvs;\r\n                        uvs32[uvidx] = tmpUV.x * (uvs.z - uvs.x) + uvs.x;\r\n                        uvs32[uvidx + 1] = tmpUV.y * (uvs.w - uvs.y) + uvs.y;\r\n                    }\r\n                }\r\n            }\r\n            // particle just set invisible : scaled to zero and positioned at the origin\r\n            else {\r\n                particle._stillInvisible = true; // mark the particle as invisible\r\n                for (pt = 0; pt < shape.length; pt++) {\r\n                    idx = index + pt * 3;\r\n                    colidx = colorIndex + pt * 4;\r\n                    uvidx = uvIndex + pt * 2;\r\n\r\n                    positions32[idx] = positions32[idx + 1] = positions32[idx + 2] = 0;\r\n                    normals32[idx] = normals32[idx + 1] = normals32[idx + 2] = 0;\r\n                    if (this._computeParticleColor && particle.color) {\r\n                        const color = particle.color;\r\n                        colors32[colidx] = color.r;\r\n                        colors32[colidx + 1] = color.g;\r\n                        colors32[colidx + 2] = color.b;\r\n                        colors32[colidx + 3] = color.a;\r\n                    }\r\n                    if (this._computeParticleTexture) {\r\n                        const uvs = particle.uvs;\r\n                        uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;\r\n                        uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // if the particle intersections must be computed : update the bbInfo\r\n            if (this._particlesIntersect) {\r\n                const bInfo = particle.getBoundingInfo();\r\n                const bBox = bInfo.boundingBox;\r\n                const bSphere = bInfo.boundingSphere;\r\n                const modelBoundingInfo = particle._modelBoundingInfo;\r\n                if (!this._bSphereOnly) {\r\n                    // place, scale and rotate the particle bbox within the SPS local system, then update it\r\n                    const modelBoundingInfoVectors = modelBoundingInfo.boundingBox.vectors;\r\n\r\n                    const tempMin = tempVectors[1];\r\n                    const tempMax = tempVectors[2];\r\n                    tempMin.setAll(Number.MAX_VALUE);\r\n                    tempMax.setAll(-Number.MAX_VALUE);\r\n                    for (let b = 0; b < 8; b++) {\r\n                        const scaledX = modelBoundingInfoVectors[b].x * particleScaling.x;\r\n                        const scaledY = modelBoundingInfoVectors[b].y * particleScaling.y;\r\n                        const scaledZ = modelBoundingInfoVectors[b].z * particleScaling.z;\r\n                        const rotatedX = scaledX * particleRotationMatrix[0] + scaledY * particleRotationMatrix[3] + scaledZ * particleRotationMatrix[6];\r\n                        const rotatedY = scaledX * particleRotationMatrix[1] + scaledY * particleRotationMatrix[4] + scaledZ * particleRotationMatrix[7];\r\n                        const rotatedZ = scaledX * particleRotationMatrix[2] + scaledY * particleRotationMatrix[5] + scaledZ * particleRotationMatrix[8];\r\n                        const x = particlePosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;\r\n                        const y = particlePosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;\r\n                        const z = particlePosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;\r\n                        tempMin.minimizeInPlaceFromFloats(x, y, z);\r\n                        tempMax.maximizeInPlaceFromFloats(x, y, z);\r\n                    }\r\n\r\n                    bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix);\r\n                }\r\n\r\n                // place and scale the particle bouding sphere in the SPS local system, then update it\r\n                const minBbox = modelBoundingInfo.minimum.multiplyToRef(particleScaling, tempVectors[1]);\r\n                const maxBbox = modelBoundingInfo.maximum.multiplyToRef(particleScaling, tempVectors[2]);\r\n\r\n                const bSphereCenter = maxBbox.addToRef(minBbox, tempVectors[3]).scaleInPlace(0.5).addInPlace(particleGlobalPosition);\r\n                const halfDiag = maxBbox.subtractToRef(minBbox, tempVectors[4]).scaleInPlace(0.5 * this._bSphereRadiusFactor);\r\n                const bSphereMinBbox = bSphereCenter.subtractToRef(halfDiag, tempVectors[1]);\r\n                const bSphereMaxBbox = bSphereCenter.addToRef(halfDiag, tempVectors[2]);\r\n                bSphere.reConstruct(bSphereMinBbox, bSphereMaxBbox, mesh._worldMatrix);\r\n            }\r\n\r\n            // increment indexes for the next particle\r\n            index = idx + 3;\r\n            colorIndex = colidx + 4;\r\n            uvIndex = uvidx + 2;\r\n        }\r\n\r\n        // if the VBO must be updated\r\n        if (update) {\r\n            if (this._computeParticleColor) {\r\n                const vb = mesh.getVertexBuffer(VertexBuffer.ColorKind);\r\n                if (vb && !mesh.isPickable) {\r\n                    vb.updateDirectly(colors32, 0);\r\n                } else {\r\n                    mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);\r\n                }\r\n            }\r\n            if (this._computeParticleTexture) {\r\n                const vb = mesh.getVertexBuffer(VertexBuffer.UVKind);\r\n                if (vb && !mesh.isPickable) {\r\n                    vb.updateDirectly(uvs32, 0);\r\n                } else {\r\n                    mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);\r\n                }\r\n            }\r\n            const vbp = mesh.getVertexBuffer(VertexBuffer.PositionKind);\r\n            if (vbp && !mesh.isPickable) {\r\n                vbp.updateDirectly(positions32, 0);\r\n            } else {\r\n                mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);\r\n            }\r\n            if (!mesh.areNormalsFrozen || mesh.isFacetDataEnabled) {\r\n                if (this._computeParticleVertex || mesh.isFacetDataEnabled) {\r\n                    // recompute the normals only if the particles can be morphed, update then also the normal reference array _fixedNormal32[]\r\n                    const params = mesh.isFacetDataEnabled ? mesh.getFacetDataParameters() : null;\r\n                    VertexData.ComputeNormals(positions32, indices32, normals32, params);\r\n                    for (let i = 0; i < normals32.length; i++) {\r\n                        fixedNormal32[i] = normals32[i];\r\n                    }\r\n                }\r\n                if (!mesh.areNormalsFrozen) {\r\n                    const vb = mesh.getVertexBuffer(VertexBuffer.NormalKind);\r\n                    if (vb && !mesh.isPickable) {\r\n                        vb.updateDirectly(normals32, 0);\r\n                    } else {\r\n                        mesh.updateVerticesData(VertexBuffer.NormalKind, normals32, false, false);\r\n                    }\r\n                }\r\n            }\r\n            if (depthSortParticles) {\r\n                const depthSortedParticles = this.depthSortedParticles;\r\n                depthSortedParticles.sort(this._depthSortFunction);\r\n                const dspl = depthSortedParticles.length;\r\n                let sid = 0;\r\n                let faceId = 0;\r\n                for (let sorted = 0; sorted < dspl; sorted++) {\r\n                    const sortedParticle = depthSortedParticles[sorted];\r\n                    const lind = sortedParticle.indicesLength;\r\n                    const sind = sortedParticle.ind;\r\n                    for (let i = 0; i < lind; i++) {\r\n                        indices32[sid] = indices[sind + i];\r\n                        sid++;\r\n                        if (this._pickable) {\r\n                            const f = i % 3;\r\n                            if (f == 0) {\r\n                                const pickedData = this.pickedParticles[faceId];\r\n                                pickedData.idx = sortedParticle.idx;\r\n                                pickedData.faceId = faceId;\r\n                                faceId++;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            if (this._autoFixFaceOrientation) {\r\n                let particleInd = 0;\r\n\r\n                for (let particleIdx = 0; particleIdx < this.particles.length; particleIdx++) {\r\n                    const particle = depthSortParticles ? this.particles[this.depthSortedParticles[particleIdx].idx] : this.particles[particleIdx];\r\n                    const flipFaces = particle.scale.x * particle.scale.y * particle.scale.z < 0;\r\n\r\n                    if (flipFaces) {\r\n                        for (let faceInd = 0; faceInd < particle._model._indicesLength; faceInd += 3) {\r\n                            const tmp = indices[particle._ind + faceInd];\r\n                            indices32[particleInd + faceInd] = indices[particle._ind + faceInd + 1];\r\n                            indices32[particleInd + faceInd + 1] = tmp;\r\n                        }\r\n                    }\r\n\r\n                    particleInd += particle._model._indicesLength;\r\n                }\r\n            }\r\n\r\n            if (depthSortParticles || this._autoFixFaceOrientation) {\r\n                mesh.updateIndices(indices32);\r\n            }\r\n        }\r\n        if (this._computeBoundingBox) {\r\n            if (mesh.hasBoundingInfo) {\r\n                mesh.getBoundingInfo().reConstruct(minimum, maximum, mesh._worldMatrix);\r\n            } else {\r\n                mesh.buildBoundingInfo(minimum, maximum, mesh._worldMatrix);\r\n            }\r\n        }\r\n        if (this._autoUpdateSubMeshes) {\r\n            this.computeSubMeshes();\r\n        }\r\n        this._recomputeInvisibles = false;\r\n        this.afterUpdateParticles(start, end, update);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disposes the SPS.\r\n     */\r\n    public dispose(): void {\r\n        this.stop();\r\n        this.mesh.dispose();\r\n        this.vars = null;\r\n        // drop references to internal big arrays for the GC\r\n        (<any>this._positions) = null;\r\n        (<any>this._indices) = null;\r\n        (<any>this._normals) = null;\r\n        (<any>this._uvs) = null;\r\n        (<any>this._colors) = null;\r\n        (<any>this._indices32) = null;\r\n        (<any>this._positions32) = null;\r\n        (<any>this._normals32) = null;\r\n        (<any>this._fixedNormal32) = null;\r\n        (<any>this._uvs32) = null;\r\n        (<any>this._colors32) = null;\r\n        (<any>this.pickedParticles) = null;\r\n        (<any>this.pickedBySubMesh) = null;\r\n        (<any>this._materials) = null;\r\n        (<any>this._materialIndexes) = null;\r\n        (<any>this._indicesByMaterial) = null;\r\n        (<any>this._idxOfId) = null;\r\n    }\r\n    /** Returns an object {idx: number faceId: number} for the picked particle from the passed pickingInfo object.\r\n     * idx is the particle index in the SPS\r\n     * faceId is the picked face index counted within this particle.\r\n     * Returns null if the pickInfo can't identify a picked particle.\r\n     * @param pickingInfo (PickingInfo object)\r\n     * @returns {idx: number, faceId: number} or null\r\n     */\r\n    public pickedParticle(pickingInfo: PickingInfo): Nullable<{ idx: number; faceId: number }> {\r\n        if (pickingInfo.hit) {\r\n            const subMesh = pickingInfo.subMeshId;\r\n            const faceId = pickingInfo.faceId - this.mesh.subMeshes[subMesh].indexStart / 3;\r\n            const picked = this.pickedBySubMesh;\r\n            if (picked[subMesh] && picked[subMesh][faceId]) {\r\n                return picked[subMesh][faceId];\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Returns a SolidParticle object from its identifier : particle.id\r\n     * @param id (integer) the particle Id\r\n     * @returns the searched particle or null if not found in the SPS.\r\n     */\r\n    public getParticleById(id: number): Nullable<SolidParticle> {\r\n        const p = this.particles[id];\r\n        if (p && p.id == id) {\r\n            return p;\r\n        }\r\n        const particles = this.particles;\r\n        const idx = this._idxOfId[id];\r\n        if (idx !== undefined) {\r\n            return particles[idx];\r\n        }\r\n        let i = 0;\r\n        const nb = this.nbParticles;\r\n        while (i < nb) {\r\n            const particle = particles[i];\r\n            if (particle.id == id) {\r\n                return particle;\r\n            }\r\n            i++;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Returns a new array populated with the particles having the passed shapeId.\r\n     * @param shapeId (integer) the shape identifier\r\n     * @returns a new solid particle array\r\n     */\r\n    public getParticlesByShapeId(shapeId: number): SolidParticle[] {\r\n        const ref: SolidParticle[] = [];\r\n        this.getParticlesByShapeIdToRef(shapeId, ref);\r\n        return ref;\r\n    }\r\n\r\n    /**\r\n     * Populates the passed array \"ref\" with the particles having the passed shapeId.\r\n     * @param shapeId the shape identifier\r\n     * @param ref array to populate\r\n     * @returns the SPS\r\n     */\r\n    public getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem {\r\n        ref.length = 0;\r\n        for (let i = 0; i < this.nbParticles; i++) {\r\n            const p = this.particles[i];\r\n            if (p.shapeId == shapeId) {\r\n                ref.push(p);\r\n            }\r\n        }\r\n        return this;\r\n    }\r\n    /**\r\n     * Computes the required SubMeshes according the materials assigned to the particles.\r\n     * @returns the solid particle system.\r\n     * Does nothing if called before the SPS mesh is built.\r\n     */\r\n    public computeSubMeshes(): SolidParticleSystem {\r\n        if (!this.mesh || !this._multimaterialEnabled) {\r\n            return this;\r\n        }\r\n        const depthSortedParticles = this.depthSortedParticles;\r\n        if (this.particles.length > 0) {\r\n            for (let p = 0; p < this.particles.length; p++) {\r\n                const part = this.particles[p];\r\n                if (!part.materialIndex) {\r\n                    part.materialIndex = 0;\r\n                }\r\n                const sortedPart = depthSortedParticles[p];\r\n                sortedPart.materialIndex = part.materialIndex;\r\n                sortedPart.ind = part._ind;\r\n                sortedPart.indicesLength = part._model._indicesLength;\r\n                sortedPart.idx = part.idx;\r\n            }\r\n        }\r\n        this._sortParticlesByMaterial();\r\n        const indicesByMaterial = this._indicesByMaterial;\r\n        const materialIndexes = this._materialIndexes;\r\n        const mesh = this.mesh;\r\n        mesh.subMeshes = [];\r\n        const vcount = mesh.getTotalVertices();\r\n        for (let m = 0; m < materialIndexes.length; m++) {\r\n            const start = indicesByMaterial[m];\r\n            const count = indicesByMaterial[m + 1] - start;\r\n            const matIndex = materialIndexes[m];\r\n            new SubMesh(matIndex, 0, vcount, start, count, mesh);\r\n        }\r\n        return this;\r\n    }\r\n    /**\r\n     * Sorts the solid particles by material when MultiMaterial is enabled.\r\n     * Updates the indices32 array.\r\n     * Updates the indicesByMaterial array.\r\n     * Updates the mesh indices array.\r\n     * @returns the SPS\r\n     * @internal\r\n     */\r\n    protected _sortParticlesByMaterial(): SolidParticleSystem {\r\n        const indicesByMaterial = [0];\r\n        this._indicesByMaterial = indicesByMaterial;\r\n        const materialIndexes: number[] = [];\r\n        this._materialIndexes = materialIndexes;\r\n        const depthSortedParticles = this.depthSortedParticles;\r\n        depthSortedParticles.sort(this._materialSortFunction);\r\n        const length = depthSortedParticles.length;\r\n        const indices32 = this._indices32;\r\n        const indices = this._indices;\r\n\r\n        let subMeshIndex = 0;\r\n        let subMeshFaceId = 0;\r\n        let sid = 0;\r\n        let lastMatIndex = depthSortedParticles[0].materialIndex;\r\n        materialIndexes.push(lastMatIndex);\r\n        if (this._pickable) {\r\n            this.pickedBySubMesh = [[]];\r\n            this.pickedParticles = this.pickedBySubMesh[0];\r\n        }\r\n        for (let sorted = 0; sorted < length; sorted++) {\r\n            const sortedPart = depthSortedParticles[sorted];\r\n            const lind = sortedPart.indicesLength;\r\n            const sind = sortedPart.ind;\r\n            if (sortedPart.materialIndex !== lastMatIndex) {\r\n                lastMatIndex = sortedPart.materialIndex;\r\n                indicesByMaterial.push(sid);\r\n                materialIndexes.push(lastMatIndex);\r\n                if (this._pickable) {\r\n                    subMeshIndex++;\r\n                    this.pickedBySubMesh[subMeshIndex] = [];\r\n                    subMeshFaceId = 0;\r\n                }\r\n            }\r\n            let faceId = 0;\r\n            for (let i = 0; i < lind; i++) {\r\n                indices32[sid] = indices[sind + i];\r\n                if (this._pickable) {\r\n                    const f = i % 3;\r\n                    if (f == 0) {\r\n                        const pickedData = this.pickedBySubMesh[subMeshIndex][subMeshFaceId];\r\n                        if (pickedData) {\r\n                            pickedData.idx = sortedPart.idx;\r\n                            pickedData.faceId = faceId;\r\n                        } else {\r\n                            this.pickedBySubMesh[subMeshIndex][subMeshFaceId] = { idx: sortedPart.idx, faceId: faceId };\r\n                        }\r\n                        subMeshFaceId++;\r\n                        faceId++;\r\n                    }\r\n                }\r\n                sid++;\r\n            }\r\n        }\r\n\r\n        indicesByMaterial.push(indices32.length); // add the last number to ease the indices start/count values for subMeshes creation\r\n        if (this._updatable) {\r\n            this.mesh.updateIndices(indices32);\r\n        }\r\n        return this;\r\n    }\r\n    /**\r\n     * Sets the material indexes by id materialIndexesById[id] = materialIndex\r\n     * @internal\r\n     */\r\n    protected _setMaterialIndexesById() {\r\n        this._materialIndexesById = {};\r\n        for (let i = 0; i < this._materials.length; i++) {\r\n            const id = this._materials[i].uniqueId;\r\n            this._materialIndexesById[id] = i;\r\n        }\r\n    }\r\n    /**\r\n     * Returns an array with unique values of Materials from the passed array\r\n     * @param array the material array to be checked and filtered\r\n     * @internal\r\n     */\r\n    protected _filterUniqueMaterialId(array: Material[]): Material[] {\r\n        const filtered = array.filter(function (value, index, self) {\r\n            return self.indexOf(value) === index;\r\n        });\r\n        return filtered;\r\n    }\r\n    /**\r\n     * Sets a new Standard Material as _defaultMaterial if not already set.\r\n     * @internal\r\n     */\r\n    protected _setDefaultMaterial(): Material {\r\n        if (!this._defaultMaterial) {\r\n            this._defaultMaterial = new StandardMaterial(this.name + \"DefaultMaterial\", this._scene);\r\n        }\r\n        return this._defaultMaterial;\r\n    }\r\n    /**\r\n     * Visibility helper : Recomputes the visible size according to the mesh bounding box\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\r\n     * @returns the SPS.\r\n     */\r\n    public refreshVisibleSize(): SolidParticleSystem {\r\n        if (!this._isVisibilityBoxLocked) {\r\n            this.mesh.refreshBoundingInfo();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.\r\n     * @param size the size (float) of the visibility box\r\n     * note : this doesn't lock the SPS mesh bounding box.\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\r\n     */\r\n    public setVisibilityBox(size: number): void {\r\n        const vis = size / 2;\r\n        this.mesh.buildBoundingInfo(new Vector3(-vis, -vis, -vis), new Vector3(vis, vis, vis));\r\n    }\r\n\r\n    /**\r\n     * Gets whether the SPS as always visible or not\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\r\n     */\r\n    public get isAlwaysVisible(): boolean {\r\n        return this._alwaysVisible;\r\n    }\r\n\r\n    /**\r\n     * Sets the SPS as always visible or not\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\r\n     */\r\n    public set isAlwaysVisible(val: boolean) {\r\n        this._alwaysVisible = val;\r\n        this.mesh.alwaysSelectAsActiveMesh = val;\r\n    }\r\n\r\n    /**\r\n     * Sets the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\r\n     */\r\n    public set isVisibilityBoxLocked(val: boolean) {\r\n        this._isVisibilityBoxLocked = val;\r\n\r\n        const boundingInfo = this.mesh.getBoundingInfo();\r\n\r\n        boundingInfo.isLocked = val;\r\n    }\r\n\r\n    /**\r\n     * Gets if the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\r\n     */\r\n    public get isVisibilityBoxLocked(): boolean {\r\n        return this._isVisibilityBoxLocked;\r\n    }\r\n\r\n    /**\r\n     * Tells to `setParticles()` to compute the particle rotations or not.\r\n     * Default value : true. The SPS is faster when it's set to false.\r\n     * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.\r\n     */\r\n    public set computeParticleRotation(val: boolean) {\r\n        this._computeParticleRotation = val;\r\n    }\r\n\r\n    /**\r\n     * Tells to `setParticles()` to compute the particle colors or not.\r\n     * Default value : true. The SPS is faster when it's set to false.\r\n     * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\r\n     */\r\n    public set computeParticleColor(val: boolean) {\r\n        this._computeParticleColor = val;\r\n    }\r\n\r\n    public set computeParticleTexture(val: boolean) {\r\n        this._computeParticleTexture = val;\r\n    }\r\n    /**\r\n     * Tells to `setParticles()` to call the vertex function for each vertex of each particle, or not.\r\n     * Default value : false. The SPS is faster when it's set to false.\r\n     * Note : the particle custom vertex positions aren't stored values.\r\n     */\r\n    public set computeParticleVertex(val: boolean) {\r\n        this._computeParticleVertex = val;\r\n    }\r\n    /**\r\n     * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.\r\n     */\r\n    public set computeBoundingBox(val: boolean) {\r\n        this._computeBoundingBox = val;\r\n    }\r\n    /**\r\n     * Tells to `setParticles()` to sort or not the distance between each particle and the camera.\r\n     * Skipped when `enableDepthSort` is set to `false` (default) at construction time.\r\n     * Default : `true`\r\n     */\r\n    public set depthSortParticles(val: boolean) {\r\n        this._depthSortParticles = val;\r\n    }\r\n\r\n    /**\r\n     * Gets if `setParticles()` computes the particle rotations or not.\r\n     * Default value : true. The SPS is faster when it's set to false.\r\n     * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.\r\n     */\r\n    public get computeParticleRotation(): boolean {\r\n        return this._computeParticleRotation;\r\n    }\r\n\r\n    /**\r\n     * Gets if `setParticles()` computes the particle colors or not.\r\n     * Default value : true. The SPS is faster when it's set to false.\r\n     * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\r\n     */\r\n    public get computeParticleColor(): boolean {\r\n        return this._computeParticleColor;\r\n    }\r\n\r\n    /**\r\n     * Gets if `setParticles()` computes the particle textures or not.\r\n     * Default value : true. The SPS is faster when it's set to false.\r\n     * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.\r\n     */\r\n    public get computeParticleTexture(): boolean {\r\n        return this._computeParticleTexture;\r\n    }\r\n\r\n    /**\r\n     * Gets if `setParticles()` calls the vertex function for each vertex of each particle, or not.\r\n     * Default value : false. The SPS is faster when it's set to false.\r\n     * Note : the particle custom vertex positions aren't stored values.\r\n     */\r\n    public get computeParticleVertex(): boolean {\r\n        return this._computeParticleVertex;\r\n    }\r\n\r\n    /**\r\n     * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.\r\n     */\r\n    public get computeBoundingBox(): boolean {\r\n        return this._computeBoundingBox;\r\n    }\r\n\r\n    /**\r\n     * Gets if `setParticles()` sorts or not the distance between each particle and the camera.\r\n     * Skipped when `enableDepthSort` is set to `false` (default) at construction time.\r\n     * Default : `true`\r\n     */\r\n    public get depthSortParticles(): boolean {\r\n        return this._depthSortParticles;\r\n    }\r\n\r\n    /**\r\n     * Gets if the SPS is created as expandable at construction time.\r\n     * Default : `false`\r\n     */\r\n    public get expandable(): boolean {\r\n        return this._expandable;\r\n    }\r\n    /**\r\n     * Gets if the SPS supports the Multi Materials\r\n     */\r\n    public get multimaterialEnabled(): boolean {\r\n        return this._multimaterialEnabled;\r\n    }\r\n    /**\r\n     * Gets if the SPS uses the model materials for its own multimaterial.\r\n     */\r\n    public get useModelMaterial(): boolean {\r\n        return this._useModelMaterial;\r\n    }\r\n    /**\r\n     * The SPS used material array.\r\n     */\r\n    public get materials(): Material[] {\r\n        return this._materials;\r\n    }\r\n    /**\r\n     * Sets the SPS MultiMaterial from the passed materials.\r\n     * Note : the passed array is internally copied and not used then by reference.\r\n     * @param materials an array of material objects. This array indexes are the materialIndex values of the particles.\r\n     */\r\n    public setMultiMaterial(materials: Material[]) {\r\n        this._materials = this._filterUniqueMaterialId(materials);\r\n        this._setMaterialIndexesById();\r\n        if (this._multimaterial) {\r\n            this._multimaterial.dispose();\r\n        }\r\n        this._multimaterial = new MultiMaterial(this.name + \"MultiMaterial\", this._scene);\r\n        for (let m = 0; m < this._materials.length; m++) {\r\n            this._multimaterial.subMaterials.push(this._materials[m]);\r\n        }\r\n        this.computeSubMeshes();\r\n        this.mesh.material = this._multimaterial;\r\n    }\r\n    /**\r\n     * The SPS computed multimaterial object\r\n     */\r\n    public get multimaterial(): MultiMaterial {\r\n        return this._multimaterial;\r\n    }\r\n    public set multimaterial(mm) {\r\n        this._multimaterial = mm;\r\n    }\r\n    /**\r\n     * If the subMeshes must be updated on the next call to setParticles()\r\n     */\r\n    public get autoUpdateSubMeshes(): boolean {\r\n        return this._autoUpdateSubMeshes;\r\n    }\r\n    public set autoUpdateSubMeshes(val: boolean) {\r\n        this._autoUpdateSubMeshes = val;\r\n    }\r\n    // =======================================================================\r\n    // Particle behavior logic\r\n    // these following methods may be overwritten by the user to fit his needs\r\n\r\n    /**\r\n     * This function does nothing. It may be overwritten to set all the particle first values.\r\n     * The SPS doesn't call this function, you may have to call it by your own.\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\r\n     */\r\n    public initParticles(): void {}\r\n\r\n    /**\r\n     * This function does nothing. It may be overwritten to recycle a particle.\r\n     * The SPS doesn't call this function, you may have to call it by your own.\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\r\n     * @param particle The particle to recycle\r\n     * @returns the recycled particle\r\n     */\r\n    public recycleParticle(particle: SolidParticle): SolidParticle {\r\n        return particle;\r\n    }\r\n\r\n    /**\r\n     * Updates a particle : this function should  be overwritten by the user.\r\n     * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\r\n     * @example : just set a particle position or velocity and recycle conditions\r\n     * @param particle The particle to update\r\n     * @returns the updated particle\r\n     */\r\n    public updateParticle(particle: SolidParticle): SolidParticle {\r\n        return particle;\r\n    }\r\n\r\n    /**\r\n     * Updates a vertex of a particle : it can be overwritten by the user.\r\n     * This will be called on each vertex particle by `setParticles()` if `computeParticleVertex` is set to true only.\r\n     * @param particle the current particle\r\n     * @param vertex the current vertex of the current particle : a SolidParticleVertex object\r\n     * @param pt the index of the current vertex in the particle shape\r\n     * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_vertices\r\n     * @example : just set a vertex particle position or color\r\n     * @returns the sps\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public updateParticleVertex(particle: SolidParticle, vertex: SolidParticleVertex, pt: number): SolidParticleSystem {\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * This will be called before any other treatment by `setParticles()` and will be passed three parameters.\r\n     * This does nothing and may be overwritten by the user.\r\n     * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\r\n     * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\r\n     * @param update the boolean update value actually passed to setParticles()\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public beforeUpdateParticles(start?: number, stop?: number, update?: boolean): void {}\r\n    /**\r\n     * This will be called  by `setParticles()` after all the other treatments and just before the actual mesh update.\r\n     * This will be passed three parameters.\r\n     * This does nothing and may be overwritten by the user.\r\n     * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\r\n     * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\r\n     * @param update the boolean update value actually passed to setParticles()\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public afterUpdateParticles(start?: number, stop?: number, update?: boolean): void {}\r\n\r\n    /**\r\n     * Starts the particle system and begins to emit.\r\n     * This will call buildMesh(), initParticles(), setParticles() and register the update loop.\r\n     * @param delay defines the delay in milliseconds before starting the system (0 by default)\r\n     */\r\n    public start(delay = 0): void {\r\n        if (this._started) {\r\n            return;\r\n        }\r\n\r\n        if (delay > 0) {\r\n            setTimeout(() => {\r\n                this.start(0);\r\n            }, delay);\r\n            return;\r\n        }\r\n\r\n        this.buildMesh();\r\n        this.initParticles();\r\n        this.setParticles();\r\n\r\n        this._started = true;\r\n        this._stopped = false;\r\n\r\n        // Register update loop\r\n        if (this._scene) {\r\n            this._onBeforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n                if (this._started && !this._stopped) {\r\n                    this.setParticles();\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Stops the particle system.\r\n     */\r\n    public stop(): void {\r\n        if (this._stopped) {\r\n            return;\r\n        }\r\n\r\n        this._stopped = true;\r\n\r\n        // Unregister update loop\r\n        if (this._onBeforeRenderObserver && this._scene) {\r\n            this._scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n            this._onBeforeRenderObserver = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets if the particle system is started\r\n     */\r\n    public get started(): boolean {\r\n        return this._started;\r\n    }\r\n\r\n    /**\r\n     * Gets if the particle system is stopped\r\n     */\r\n    public get stopped(): boolean {\r\n        return this._stopped;\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Matrix, Color4, Vector2, Vector3, TmpVectors, Quaternion } from \"../Maths/math\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { type BoundingInfo } from \"../Culling/boundingInfo\";\r\nimport { type PointsCloudSystem } from \"./pointsCloudSystem\";\r\n/**\r\n * Represents one particle of a points cloud system.\r\n */\r\nexport class CloudPoint {\r\n    /**\r\n     * particle global index\r\n     */\r\n    public idx: number = 0;\r\n    /**\r\n     * The color of the particle\r\n     */\r\n    public color: Nullable<Color4> = new Color4(1.0, 1.0, 1.0, 1.0);\r\n    /**\r\n     * The world space position of the particle.\r\n     */\r\n    public position: Vector3 = Vector3.Zero();\r\n    /**\r\n     * The world space rotation of the particle. (Not use if rotationQuaternion is set)\r\n     */\r\n    public rotation: Vector3 = Vector3.Zero();\r\n    /**\r\n     * The world space rotation quaternion of the particle.\r\n     */\r\n    public rotationQuaternion: Nullable<Quaternion>;\r\n    /**\r\n     * The uv of the particle.\r\n     */\r\n    public uv: Nullable<Vector2> = new Vector2(0.0, 0.0);\r\n    /**\r\n     * The current speed of the particle.\r\n     */\r\n    public velocity: Vector3 = Vector3.Zero();\r\n    /**\r\n     * The pivot point in the particle local space.\r\n     */\r\n    public pivot: Vector3 = Vector3.Zero();\r\n    /**\r\n     * Must the particle be translated from its pivot point in its local space ?\r\n     * In this case, the pivot point is set at the origin of the particle local space and the particle is translated.\r\n     * Default : false\r\n     */\r\n    public translateFromPivot: boolean = false;\r\n    /**\r\n     * Index of this particle in the global \"positions\" array (Internal use)\r\n     * @internal\r\n     */\r\n    public _pos: number = 0;\r\n    /**\r\n     * @internal Index of this particle in the global \"indices\" array (Internal use)\r\n     */\r\n    public _ind: number = 0;\r\n    /**\r\n     * Group this particle belongs to\r\n     */\r\n    public _group: PointsGroup;\r\n    /**\r\n     * Group id of this particle\r\n     */\r\n    public groupId: number = 0;\r\n    /**\r\n     * Index of the particle in its group id (Internal use)\r\n     */\r\n    public idxInGroup: number = 0;\r\n    /**\r\n     * @internal Particle BoundingInfo object (Internal use)\r\n     */\r\n    public _boundingInfo: BoundingInfo;\r\n    /**\r\n     * @internal Reference to the PCS that the particle belongs to (Internal use)\r\n     */\r\n    public _pcs: PointsCloudSystem;\r\n    /**\r\n     * @internal Still set as invisible in order to skip useless computations (Internal use)\r\n     */\r\n    public _stillInvisible: boolean = false;\r\n    /**\r\n     * @internal Last computed particle rotation matrix\r\n     */\r\n    public _rotationMatrix: number[] = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];\r\n    /**\r\n     * Parent particle Id, if any.\r\n     * Default null.\r\n     */\r\n    public parentId: Nullable<number> = null;\r\n    /**\r\n     * @internal Internal global position in the PCS.\r\n     */\r\n    public _globalPosition: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Creates a Point Cloud object.\r\n     * Don't create particles manually, use instead the PCS internal tools like _addParticle()\r\n     * @param particleIndex (integer) is the particle index in the PCS pool. It's also the particle identifier.\r\n     * @param group (PointsGroup) is the group the particle belongs to\r\n     * @param groupId (integer) is the group identifier in the PCS.\r\n     * @param idxInGroup (integer) is the index of the particle in the current point group (ex: the 10th point of addPoints(30))\r\n     * @param pcs defines the PCS it is associated to\r\n     */\r\n    constructor(particleIndex: number, group: PointsGroup, groupId: number, idxInGroup: number, pcs: PointsCloudSystem) {\r\n        this.idx = particleIndex;\r\n        this._group = group;\r\n        this.groupId = groupId;\r\n        this.idxInGroup = idxInGroup;\r\n        this._pcs = pcs;\r\n    }\r\n\r\n    /**\r\n     * get point size\r\n     */\r\n    public get size(): Vector3 {\r\n        return this.size;\r\n    }\r\n\r\n    /**\r\n     * Set point size\r\n     */\r\n    public set size(scale: Vector3) {\r\n        this.size = scale;\r\n    }\r\n\r\n    /**\r\n     * Legacy support, changed quaternion to rotationQuaternion\r\n     */\r\n    public get quaternion(): Nullable<Quaternion> {\r\n        return this.rotationQuaternion;\r\n    }\r\n\r\n    /**\r\n     * Legacy support, changed quaternion to rotationQuaternion\r\n     */\r\n    public set quaternion(q: Nullable<Quaternion>) {\r\n        this.rotationQuaternion = q;\r\n    }\r\n\r\n    /**\r\n     * Returns a boolean. True if the particle intersects a mesh, else false\r\n     * The intersection is computed on the particle position and Axis Aligned Bounding Box (AABB) or Sphere\r\n     * @param target is the object (point or mesh) what the intersection is computed against\r\n     * @param isSphere is boolean flag when false (default) bounding box of mesh is used, when true the bounding sphere is used\r\n     * @returns true if it intersects\r\n     */\r\n    public intersectsMesh(target: Mesh, isSphere: boolean): boolean {\r\n        if (!target.hasBoundingInfo) {\r\n            return false;\r\n        }\r\n\r\n        if (!this._pcs.mesh) {\r\n            throw new Error(\"Point Cloud System doesnt contain the Mesh\");\r\n        }\r\n\r\n        if (isSphere) {\r\n            return target.getBoundingInfo().boundingSphere.intersectsPoint(this.position.add(this._pcs.mesh.position));\r\n        }\r\n\r\n        const bbox = target.getBoundingInfo().boundingBox;\r\n\r\n        const maxX = bbox.maximumWorld.x;\r\n        const minX = bbox.minimumWorld.x;\r\n        const maxY = bbox.maximumWorld.y;\r\n        const minY = bbox.minimumWorld.y;\r\n        const maxZ = bbox.maximumWorld.z;\r\n        const minZ = bbox.minimumWorld.z;\r\n\r\n        const x = this.position.x + this._pcs.mesh.position.x;\r\n        const y = this.position.y + this._pcs.mesh.position.y;\r\n        const z = this.position.z + this._pcs.mesh.position.z;\r\n\r\n        return minX <= x && x <= maxX && minY <= y && y <= maxY && minZ <= z && z <= maxZ;\r\n    }\r\n\r\n    /**\r\n     * get the rotation matrix of the particle\r\n     * @internal\r\n     */\r\n    public getRotationMatrix(m: Matrix) {\r\n        let quaternion: Quaternion;\r\n        if (this.rotationQuaternion) {\r\n            quaternion = this.rotationQuaternion;\r\n        } else {\r\n            quaternion = TmpVectors.Quaternion[0];\r\n            const rotation = this.rotation;\r\n            Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);\r\n        }\r\n\r\n        quaternion.toRotationMatrix(m);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a group of points in a points cloud system\r\n *  * PCS internal tool, don't use it manually.\r\n */\r\nexport class PointsGroup {\r\n    /**\r\n     * Get or set the groupId\r\n     * @deprecated Please use groupId instead\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public get groupID(): number {\r\n        return this.groupId;\r\n    }\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public set groupID(groupID: number) {\r\n        this.groupId = groupID;\r\n    }\r\n    /**\r\n     * The group id\r\n     * @internal\r\n     */\r\n    public groupId: number;\r\n    /**\r\n     * image data for group (internal use)\r\n     * @internal\r\n     */\r\n    public _groupImageData: Nullable<ArrayBufferView>;\r\n    /**\r\n     * Image Width (internal use)\r\n     * @internal\r\n     */\r\n    public _groupImgWidth: number;\r\n    /**\r\n     * Image Height (internal use)\r\n     * @internal\r\n     */\r\n    public _groupImgHeight: number;\r\n    /**\r\n     * Custom position function (internal use)\r\n     * @internal\r\n     */\r\n    public _positionFunction: Nullable<(particle: CloudPoint, i?: number, s?: number) => void>;\r\n    /**\r\n     * density per facet for surface points\r\n     * @internal\r\n     */\r\n    public _groupDensity: number[];\r\n    /**\r\n     * Only when points are colored by texture carries pointer to texture list array\r\n     * @internal\r\n     */\r\n    public _textureNb: number;\r\n\r\n    /**\r\n     * Creates a points group object. This is an internal reference to produce particles for the PCS.\r\n     * PCS internal tool, don't use it manually.\r\n     * @internal\r\n     */\r\n    constructor(id: number, posFunction: Nullable<(particle: CloudPoint, i?: number, s?: number) => void>) {\r\n        this.groupId = id;\r\n        this._positionFunction = posFunction;\r\n    }\r\n}\r\n","import { type IndicesArray, type FloatArray } from \"../types\";\r\nimport { Color4, Color3 } from \"../Maths/math\";\r\nimport { Vector2, Vector3, Vector4, TmpVectors, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { VertexData } from \"../Meshes/mesh.vertexData\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { type Scene, type IDisposable } from \"../scene\";\r\nimport { CloudPoint, PointsGroup } from \"./cloudPoint\";\r\nimport { Ray } from \"../Culling/ray.pure\";\r\nimport { type PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { BaseTexture } from \"./../Materials/Textures/baseTexture.pure\";\r\nimport { RandomRange } from \"../Maths/math.scalar.functions\";\r\nimport { type Material } from \"../Materials/material\";\r\n\r\n/** Defines the 4 color options */\r\nexport const enum PointColor {\r\n    /** color value */\r\n    Color = 2,\r\n    /** uv value */\r\n    UV = 1,\r\n    /** random value */\r\n    Random = 0,\r\n    /** stated value */\r\n    Stated = 3,\r\n}\r\n\r\n/**\r\n * The PointCloudSystem (PCS) is a single updatable mesh. The points corresponding to the vertices of this big mesh.\r\n * As it is just a mesh, the PointCloudSystem has all the same properties as any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.\r\n\r\n * The PointCloudSystem is also a particle system, with each point being a particle. It provides some methods to manage the particles.\r\n * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.\r\n *\r\n * Full documentation here : TO BE ENTERED\r\n */\r\nexport class PointsCloudSystem implements IDisposable {\r\n    /**\r\n     *  The PCS array of cloud point objects. Just access each particle as with any classic array.\r\n     *  Example : var p = SPS.particles[i];\r\n     */\r\n    public particles: CloudPoint[] = new Array<CloudPoint>();\r\n    /**\r\n     * The PCS total number of particles. Read only. Use PCS.counter instead if you need to set your own value.\r\n     */\r\n    public nbParticles: number = 0;\r\n    /**\r\n     * This a counter for your own usage. It's not set by any SPS functions.\r\n     */\r\n    public counter: number = 0;\r\n    /**\r\n     * The PCS name. This name is also given to the underlying mesh.\r\n     */\r\n    public name: string;\r\n    /**\r\n     * The PCS mesh. It's a standard BJS Mesh, so all the methods from the Mesh class are available.\r\n     */\r\n    public mesh?: Mesh;\r\n    /**\r\n     * This empty object is intended to store some PCS specific or temporary values in order to lower the Garbage Collector activity.\r\n     * Please read :\r\n     */\r\n    public vars: any = {};\r\n    /**\r\n     * @internal\r\n     */\r\n    public _size: number; //size of each point particle\r\n\r\n    private _scene: Scene;\r\n    private _promises: Array<Promise<any>> = [];\r\n    private _positions: number[] = new Array<number>();\r\n    private _indices: number[] = new Array<number>();\r\n    private _normals: number[] = new Array<number>();\r\n    private _colors: number[] = new Array<number>();\r\n    private _uvs: number[] = new Array<number>();\r\n    private _indices32: IndicesArray; // used as depth sorted array if depth sort enabled, else used as typed indices\r\n    private _positions32: Float32Array; // updated positions for the VBO\r\n    private _colors32: Float32Array;\r\n    private _uvs32: Float32Array;\r\n    private _updatable: boolean = true;\r\n    private _isVisibilityBoxLocked = false;\r\n    private _alwaysVisible: boolean = false;\r\n    private _groups: number[] = new Array<number>(); //start indices for each group of particles\r\n    private _groupCounter: number = 0;\r\n    private _computeParticleColor: boolean = true;\r\n    private _computeParticleTexture: boolean = true;\r\n    private _computeParticleRotation: boolean = true;\r\n    private _computeBoundingBox: boolean = false;\r\n    private _isReady: boolean = false;\r\n\r\n    /**\r\n     * Gets the particle positions computed by the Point Cloud System\r\n     */\r\n    public get positions(): Float32Array {\r\n        return this._positions32;\r\n    }\r\n\r\n    /**\r\n     * Gets the particle colors computed by the Point Cloud System\r\n     */\r\n    public get colors(): Float32Array {\r\n        return this._colors32;\r\n    }\r\n\r\n    /**\r\n     * Gets the particle uvs computed by the Point Cloud System\r\n     */\r\n    public get uvs(): Float32Array {\r\n        return this._uvs32;\r\n    }\r\n\r\n    /**\r\n     * Creates a PCS (Points Cloud System) object\r\n     * @param name (String) is the PCS name, this will be the underlying mesh name\r\n     * @param pointSize (number) is the size for each point. Has no effect on a WebGPU engine.\r\n     * @param scene (Scene) is the scene in which the PCS is added\r\n     * @param options defines the options of the PCS e.g.\r\n     * * updatable (optional boolean, default true) : if the PCS must be updatable or immutable\r\n     */\r\n    constructor(name: string, pointSize: number, scene: Scene, options?: { updatable?: boolean }) {\r\n        this.name = name;\r\n        this._size = pointSize;\r\n        this._scene = scene || EngineStore.LastCreatedScene;\r\n        if (options && options.updatable !== undefined) {\r\n            this._updatable = options.updatable;\r\n        } else {\r\n            this._updatable = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Builds the PCS underlying mesh. Returns a standard Mesh.\r\n     * If no points were added to the PCS, the returned mesh is just a single point.\r\n     * @param material The material to use to render the mesh. If not provided, will create a default one\r\n     * @returns a promise for the created mesh\r\n     */\r\n    public async buildMeshAsync(material?: Material): Promise<Mesh> {\r\n        await Promise.all(this._promises);\r\n        this._isReady = true;\r\n        return await this._buildMeshAsync(material);\r\n    }\r\n\r\n    private async _buildMeshAsync(material?: Material): Promise<Mesh> {\r\n        if (this.nbParticles === 0) {\r\n            this.addPoints(1);\r\n        }\r\n\r\n        this._positions32 = new Float32Array(this._positions);\r\n        this._uvs32 = new Float32Array(this._uvs);\r\n        this._colors32 = new Float32Array(this._colors);\r\n\r\n        const vertexData = new VertexData();\r\n        vertexData.set(this._positions32, VertexBuffer.PositionKind);\r\n\r\n        if (this._uvs32.length > 0) {\r\n            vertexData.set(this._uvs32, VertexBuffer.UVKind);\r\n        }\r\n        let ec = 0; //emissive color value 0 for UVs, 1 for color\r\n        if (this._colors32.length > 0) {\r\n            ec = 1;\r\n            vertexData.set(this._colors32, VertexBuffer.ColorKind);\r\n        }\r\n        const mesh = new Mesh(this.name, this._scene);\r\n        vertexData.applyToMesh(mesh, this._updatable);\r\n        this.mesh = mesh;\r\n\r\n        // free memory\r\n        (<any>this._positions) = null;\r\n        (<any>this._uvs) = null;\r\n        (<any>this._colors) = null;\r\n\r\n        if (!this._updatable) {\r\n            this.particles.length = 0;\r\n        }\r\n\r\n        let mat = material;\r\n\r\n        if (!mat) {\r\n            mat = new StandardMaterial(\"point cloud material\", this._scene);\r\n            (<StandardMaterial>mat).emissiveColor = new Color3(ec, ec, ec);\r\n            (<StandardMaterial>mat).disableLighting = true;\r\n            (<StandardMaterial>mat).pointsCloud = true;\r\n            (<StandardMaterial>mat).pointSize = this._size;\r\n        }\r\n        mesh.material = mat;\r\n\r\n        return mesh;\r\n    }\r\n\r\n    // adds a new particle object in the particles array\r\n    private _addParticle(idx: number, group: PointsGroup, groupId: number, idxInGroup: number): CloudPoint {\r\n        const cp = new CloudPoint(idx, group, groupId, idxInGroup, this);\r\n        this.particles.push(cp);\r\n        return cp;\r\n    }\r\n\r\n    private _randomUnitVector(particle: CloudPoint): void {\r\n        particle.position = new Vector3(Math.random(), Math.random(), Math.random());\r\n        particle.color = new Color4(1, 1, 1, 1);\r\n    }\r\n\r\n    private _getColorIndicesForCoord(pointsGroup: PointsGroup, x: number, y: number, width: number): Color4 {\r\n        const imageData = <Uint8Array>pointsGroup._groupImageData;\r\n        const color = y * (width * 4) + x * 4;\r\n        const colorIndices = [color, color + 1, color + 2, color + 3];\r\n        const redIndex = colorIndices[0];\r\n        const greenIndex = colorIndices[1];\r\n        const blueIndex = colorIndices[2];\r\n        const alphaIndex = colorIndices[3];\r\n        const redForCoord = imageData[redIndex];\r\n        const greenForCoord = imageData[greenIndex];\r\n        const blueForCoord = imageData[blueIndex];\r\n        const alphaForCoord = imageData[alphaIndex];\r\n        return new Color4(redForCoord / 255, greenForCoord / 255, blueForCoord / 255, alphaForCoord);\r\n    }\r\n\r\n    private _setPointsColorOrUV(\r\n        mesh: Mesh,\r\n        pointsGroup: PointsGroup,\r\n        isVolume: boolean,\r\n        colorFromTexture?: boolean,\r\n        hasTexture?: boolean,\r\n        color?: Color4,\r\n        range?: number,\r\n        uvSetIndex?: number\r\n    ): void {\r\n        uvSetIndex = uvSetIndex ?? 0;\r\n\r\n        if (isVolume) {\r\n            mesh.updateFacetData();\r\n        }\r\n\r\n        const boundInfo = mesh.getBoundingInfo();\r\n        const diameter = 2 * boundInfo.boundingSphere.radius;\r\n\r\n        let meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const meshInd = <IndicesArray>mesh.getIndices();\r\n        const meshUV = <FloatArray>mesh.getVerticesData(VertexBuffer.UVKind + (uvSetIndex ? uvSetIndex + 1 : \"\"));\r\n        const meshCol = <FloatArray>mesh.getVerticesData(VertexBuffer.ColorKind);\r\n\r\n        const place = Vector3.Zero();\r\n        mesh.computeWorldMatrix();\r\n        const meshMatrix: Matrix = mesh.getWorldMatrix();\r\n        if (!meshMatrix.isIdentity()) {\r\n            meshPos = meshPos.slice(0);\r\n            for (let p = 0; p < meshPos.length / 3; p++) {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(meshPos[3 * p], meshPos[3 * p + 1], meshPos[3 * p + 2], meshMatrix, place);\r\n                meshPos[3 * p] = place.x;\r\n                meshPos[3 * p + 1] = place.y;\r\n                meshPos[3 * p + 2] = place.z;\r\n            }\r\n        }\r\n\r\n        let idxPoints: number;\r\n\r\n        let id0: number;\r\n        let id1: number;\r\n        let id2: number;\r\n        let v0X: number;\r\n        let v0Y: number;\r\n        let v0Z: number;\r\n        let v1X: number;\r\n        let v1Y: number;\r\n        let v1Z: number;\r\n        let v2X: number;\r\n        let v2Y: number;\r\n        let v2Z: number;\r\n        const vertex0 = Vector3.Zero();\r\n        const vertex1 = Vector3.Zero();\r\n        const vertex2 = Vector3.Zero();\r\n        const vec0 = Vector3.Zero();\r\n        const vec1 = Vector3.Zero();\r\n\r\n        let uv0X: number;\r\n        let uv0Y: number;\r\n        let uv1X: number;\r\n        let uv1Y: number;\r\n        let uv2X: number;\r\n        let uv2Y: number;\r\n        const uv0 = Vector2.Zero();\r\n        const uv1 = Vector2.Zero();\r\n        const uv2 = Vector2.Zero();\r\n        const uvec0 = Vector2.Zero();\r\n        const uvec1 = Vector2.Zero();\r\n\r\n        let col0X: number;\r\n        let col0Y: number;\r\n        let col0Z: number;\r\n        let col0A: number;\r\n        let col1X: number;\r\n        let col1Y: number;\r\n        let col1Z: number;\r\n        let col1A: number;\r\n        let col2X: number;\r\n        let col2Y: number;\r\n        let col2Z: number;\r\n        let col2A: number;\r\n        const col0 = Vector4.Zero();\r\n        const col1 = Vector4.Zero();\r\n        const col2 = Vector4.Zero();\r\n        const colvec0 = Vector4.Zero();\r\n        const colvec1 = Vector4.Zero();\r\n\r\n        let lamda: number;\r\n        let mu: number;\r\n        range = range ? range : 0;\r\n\r\n        let facetPoint: Vector3;\r\n        let uvPoint: Vector2;\r\n        let colPoint: Vector4 = new Vector4(0, 0, 0, 1);\r\n\r\n        let norm: Vector3;\r\n        let tang: Vector3;\r\n        let biNorm: Vector3;\r\n        let angle: number;\r\n        let facetPlaneVec: Vector3;\r\n\r\n        let gap: number;\r\n        let distance: number;\r\n        const ray = new Ray(Vector3.Zero(), new Vector3(1, 0, 0));\r\n        let pickInfo: PickingInfo;\r\n        let direction: Vector3;\r\n\r\n        for (let index = 0; index < meshInd.length / 3; index++) {\r\n            id0 = meshInd[3 * index];\r\n            id1 = meshInd[3 * index + 1];\r\n            id2 = meshInd[3 * index + 2];\r\n            v0X = meshPos[3 * id0];\r\n            v0Y = meshPos[3 * id0 + 1];\r\n            v0Z = meshPos[3 * id0 + 2];\r\n            v1X = meshPos[3 * id1];\r\n            v1Y = meshPos[3 * id1 + 1];\r\n            v1Z = meshPos[3 * id1 + 2];\r\n            v2X = meshPos[3 * id2];\r\n            v2Y = meshPos[3 * id2 + 1];\r\n            v2Z = meshPos[3 * id2 + 2];\r\n            vertex0.set(v0X, v0Y, v0Z);\r\n            vertex1.set(v1X, v1Y, v1Z);\r\n            vertex2.set(v2X, v2Y, v2Z);\r\n            vertex1.subtractToRef(vertex0, vec0);\r\n            vertex2.subtractToRef(vertex1, vec1);\r\n\r\n            if (meshUV) {\r\n                uv0X = meshUV[2 * id0];\r\n                uv0Y = meshUV[2 * id0 + 1];\r\n                uv1X = meshUV[2 * id1];\r\n                uv1Y = meshUV[2 * id1 + 1];\r\n                uv2X = meshUV[2 * id2];\r\n                uv2Y = meshUV[2 * id2 + 1];\r\n                uv0.set(uv0X, uv0Y);\r\n                uv1.set(uv1X, uv1Y);\r\n                uv2.set(uv2X, uv2Y);\r\n                uv1.subtractToRef(uv0, uvec0);\r\n                uv2.subtractToRef(uv1, uvec1);\r\n            }\r\n\r\n            if (meshCol && colorFromTexture) {\r\n                col0X = meshCol[4 * id0];\r\n                col0Y = meshCol[4 * id0 + 1];\r\n                col0Z = meshCol[4 * id0 + 2];\r\n                col0A = meshCol[4 * id0 + 3];\r\n                col1X = meshCol[4 * id1];\r\n                col1Y = meshCol[4 * id1 + 1];\r\n                col1Z = meshCol[4 * id1 + 2];\r\n                col1A = meshCol[4 * id1 + 3];\r\n                col2X = meshCol[4 * id2];\r\n                col2Y = meshCol[4 * id2 + 1];\r\n                col2Z = meshCol[4 * id2 + 2];\r\n                col2A = meshCol[4 * id2 + 3];\r\n                col0.set(col0X, col0Y, col0Z, col0A);\r\n                col1.set(col1X, col1Y, col1Z, col1A);\r\n                col2.set(col2X, col2Y, col2Z, col2A);\r\n                col1.subtractToRef(col0, colvec0);\r\n                col2.subtractToRef(col1, colvec1);\r\n            }\r\n\r\n            let width: number;\r\n            let height: number;\r\n            let deltaS: number;\r\n            let deltaV: number;\r\n            let h: number;\r\n            let s: number;\r\n            let v: number;\r\n            let hsvCol: Color3;\r\n            const statedColor: Color3 = new Color3(0, 0, 0);\r\n            const colPoint3: Color3 = new Color3(0, 0, 0);\r\n            let pointColors: Color4;\r\n            let particle: CloudPoint;\r\n\r\n            for (let i = 0; i < pointsGroup._groupDensity[index]; i++) {\r\n                idxPoints = this.particles.length;\r\n                this._addParticle(idxPoints, pointsGroup, this._groupCounter, index + i);\r\n                particle = this.particles[idxPoints];\r\n                //form a point inside the facet v0, v1, v2;\r\n                lamda = Math.sqrt(RandomRange(0, 1));\r\n                mu = RandomRange(0, 1);\r\n                facetPoint = vertex0.add(vec0.scale(lamda)).add(vec1.scale(lamda * mu));\r\n                if (isVolume) {\r\n                    norm = mesh.getFacetNormal(index).normalize().scale(-1);\r\n                    tang = vec0.clone().normalize();\r\n                    biNorm = Vector3.Cross(norm, tang);\r\n                    angle = RandomRange(0, 2 * Math.PI);\r\n                    facetPlaneVec = tang.scale(Math.cos(angle)).add(biNorm.scale(Math.sin(angle)));\r\n                    angle = RandomRange(0.1, Math.PI / 2);\r\n                    direction = facetPlaneVec.scale(Math.cos(angle)).add(norm.scale(Math.sin(angle)));\r\n\r\n                    ray.origin = facetPoint.add(direction.scale(0.00001));\r\n                    ray.direction = direction;\r\n                    ray.length = diameter;\r\n                    pickInfo = ray.intersectsMesh(mesh);\r\n                    if (pickInfo.hit) {\r\n                        distance = pickInfo.pickedPoint!.subtract(facetPoint).length();\r\n                        gap = RandomRange(0, 1) * distance;\r\n                        facetPoint.addInPlace(direction.scale(gap));\r\n                    }\r\n                }\r\n                particle.position = facetPoint.clone();\r\n                this._positions.push(particle.position.x, particle.position.y, particle.position.z);\r\n                if (colorFromTexture !== undefined) {\r\n                    if (meshUV) {\r\n                        uvPoint = uv0.add(uvec0.scale(lamda)).add(uvec1.scale(lamda * mu));\r\n                        if (colorFromTexture) {\r\n                            //Set particle color to texture color\r\n                            if (hasTexture && pointsGroup._groupImageData !== null) {\r\n                                width = pointsGroup._groupImgWidth;\r\n                                height = pointsGroup._groupImgHeight;\r\n                                pointColors = this._getColorIndicesForCoord(pointsGroup, Math.round(uvPoint.x * width), Math.round(uvPoint.y * height), width);\r\n                                particle.color = pointColors;\r\n                                this._colors.push(pointColors.r, pointColors.g, pointColors.b, pointColors.a);\r\n                            } else {\r\n                                if (meshCol) {\r\n                                    //failure in texture and colors available\r\n                                    colPoint = col0.add(colvec0.scale(lamda)).add(colvec1.scale(lamda * mu));\r\n                                    particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);\r\n                                    this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);\r\n                                } else {\r\n                                    colPoint = col0.set(Math.random(), Math.random(), Math.random(), 1);\r\n                                    particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);\r\n                                    this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);\r\n                                }\r\n                            }\r\n                        } else {\r\n                            //Set particle uv based on a mesh uv\r\n                            particle.uv = uvPoint.clone();\r\n                            this._uvs.push(particle.uv.x, particle.uv.y);\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (color) {\r\n                        statedColor.set(color.r, color.g, color.b);\r\n                        deltaS = RandomRange(-range, range);\r\n                        deltaV = RandomRange(-range, range);\r\n                        hsvCol = statedColor.toHSV();\r\n                        h = hsvCol.r;\r\n                        s = hsvCol.g + deltaS;\r\n                        v = hsvCol.b + deltaV;\r\n                        if (s < 0) {\r\n                            s = 0;\r\n                        }\r\n                        if (s > 1) {\r\n                            s = 1;\r\n                        }\r\n                        if (v < 0) {\r\n                            v = 0;\r\n                        }\r\n                        if (v > 1) {\r\n                            v = 1;\r\n                        }\r\n                        Color3.HSVtoRGBToRef(h, s, v, colPoint3);\r\n                        colPoint.set(colPoint3.r, colPoint3.g, colPoint3.b, 1);\r\n                    } else {\r\n                        colPoint = col0.set(Math.random(), Math.random(), Math.random(), 1);\r\n                    }\r\n                    particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);\r\n                    this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // stores mesh texture in dynamic texture for color pixel retrieval\r\n    // when pointColor type is color for surface points\r\n    private _colorFromTexture(mesh: Mesh, pointsGroup: PointsGroup, isVolume: boolean): void {\r\n        if (mesh.material === null) {\r\n            Logger.Warn(mesh.name + \"has no material.\");\r\n            pointsGroup._groupImageData = null;\r\n            this._setPointsColorOrUV(mesh, pointsGroup, isVolume, true, false);\r\n            return;\r\n        }\r\n\r\n        const mat = mesh.material;\r\n        const textureList: BaseTexture[] = mat.getActiveTextures();\r\n        if (textureList.length === 0) {\r\n            Logger.Warn(mesh.name + \"has no usable texture.\");\r\n            pointsGroup._groupImageData = null;\r\n            this._setPointsColorOrUV(mesh, pointsGroup, isVolume, true, false);\r\n            return;\r\n        }\r\n\r\n        const clone = mesh.clone();\r\n        clone.setEnabled(false);\r\n        this._promises.push(\r\n            new Promise((resolve: (_: void) => void) => {\r\n                BaseTexture.WhenAllReady(textureList, () => {\r\n                    let n = pointsGroup._textureNb;\r\n                    if (n < 0) {\r\n                        n = 0;\r\n                    }\r\n                    if (n > textureList.length - 1) {\r\n                        n = textureList.length - 1;\r\n                    }\r\n                    const finalize = () => {\r\n                        pointsGroup._groupImgWidth = textureList[n].getSize().width;\r\n                        pointsGroup._groupImgHeight = textureList[n].getSize().height;\r\n                        this._setPointsColorOrUV(clone, pointsGroup, isVolume, true, true, undefined, undefined, textureList[n].coordinatesIndex);\r\n                        clone.dispose();\r\n                        resolve();\r\n                    };\r\n                    pointsGroup._groupImageData = null;\r\n                    const dataPromise = textureList[n].readPixels();\r\n                    if (!dataPromise) {\r\n                        finalize();\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                        dataPromise.then((data) => {\r\n                            pointsGroup._groupImageData = data;\r\n                            finalize();\r\n                        });\r\n                    }\r\n                });\r\n            })\r\n        );\r\n    }\r\n\r\n    // calculates the point density per facet of a mesh for surface points\r\n    private _calculateDensity(nbPoints: number, positions: FloatArray, indices: IndicesArray): number[] {\r\n        let id0: number;\r\n        let id1: number;\r\n        let id2: number;\r\n        let v0X: number;\r\n        let v0Y: number;\r\n        let v0Z: number;\r\n        let v1X: number;\r\n        let v1Y: number;\r\n        let v1Z: number;\r\n        let v2X: number;\r\n        let v2Y: number;\r\n        let v2Z: number;\r\n        const vertex0 = Vector3.Zero();\r\n        const vertex1 = Vector3.Zero();\r\n        const vertex2 = Vector3.Zero();\r\n        const vec0 = Vector3.Zero();\r\n        const vec1 = Vector3.Zero();\r\n        const normal = Vector3.Zero();\r\n\r\n        let area: number;\r\n        const cumulativeAreas: number[] = [];\r\n        let surfaceArea: number = 0;\r\n\r\n        const nbFacets = indices.length / 3;\r\n\r\n        //surface area\r\n        for (let index = 0; index < nbFacets; index++) {\r\n            id0 = indices[3 * index];\r\n            id1 = indices[3 * index + 1];\r\n            id2 = indices[3 * index + 2];\r\n            v0X = positions[3 * id0];\r\n            v0Y = positions[3 * id0 + 1];\r\n            v0Z = positions[3 * id0 + 2];\r\n            v1X = positions[3 * id1];\r\n            v1Y = positions[3 * id1 + 1];\r\n            v1Z = positions[3 * id1 + 2];\r\n            v2X = positions[3 * id2];\r\n            v2Y = positions[3 * id2 + 1];\r\n            v2Z = positions[3 * id2 + 2];\r\n            vertex0.set(v0X, v0Y, v0Z);\r\n            vertex1.set(v1X, v1Y, v1Z);\r\n            vertex2.set(v2X, v2Y, v2Z);\r\n            vertex1.subtractToRef(vertex0, vec0);\r\n            vertex2.subtractToRef(vertex1, vec1);\r\n            Vector3.CrossToRef(vec0, vec1, normal);\r\n            area = 0.5 * normal.length();\r\n            surfaceArea += area;\r\n            cumulativeAreas[index] = surfaceArea;\r\n        }\r\n\r\n        const density: number[] = new Array<number>(nbFacets);\r\n        let remainingPoints = nbPoints;\r\n        for (let index = nbFacets - 1; index > 0; index--) {\r\n            const cumulativeArea = cumulativeAreas[index];\r\n            if (cumulativeArea === 0) {\r\n                // avoiding division by 0 upon degenerate triangles\r\n                density[index] = 0;\r\n            } else {\r\n                const area = cumulativeArea - cumulativeAreas[index - 1];\r\n                const facetPointsWithFraction = (area / cumulativeArea) * remainingPoints;\r\n                const floored = Math.floor(facetPointsWithFraction);\r\n                const fraction = facetPointsWithFraction - floored;\r\n                const extraPoint = Number(Math.random() < fraction);\r\n                const facetPoints = floored + extraPoint;\r\n                density[index] = facetPoints;\r\n                remainingPoints -= facetPoints;\r\n            }\r\n        }\r\n        density[0] = remainingPoints;\r\n\r\n        return density;\r\n    }\r\n\r\n    /**\r\n     * Adds points to the PCS in random positions within a unit sphere\r\n     * @param nb (positive integer) the number of particles to be created from this model\r\n     * @param pointFunction is an optional javascript function to be called for each particle on PCS creation\r\n     * @returns the number of groups in the system\r\n     */\r\n    public addPoints(nb: number, pointFunction: any = this._randomUnitVector): number {\r\n        const pointsGroup = new PointsGroup(this._groupCounter, pointFunction);\r\n        let cp: CloudPoint;\r\n\r\n        // particles\r\n        let idx = this.nbParticles;\r\n        for (let i = 0; i < nb; i++) {\r\n            cp = this._addParticle(idx, pointsGroup, this._groupCounter, i);\r\n            if (pointsGroup && pointsGroup._positionFunction) {\r\n                pointsGroup._positionFunction(cp, idx, i);\r\n            }\r\n            this._positions.push(cp.position.x, cp.position.y, cp.position.z);\r\n            if (cp.color) {\r\n                this._colors.push(cp.color.r, cp.color.g, cp.color.b, cp.color.a);\r\n            }\r\n            if (cp.uv) {\r\n                this._uvs.push(cp.uv.x, cp.uv.y);\r\n            }\r\n            idx++;\r\n        }\r\n        this.nbParticles += nb;\r\n        this._groupCounter++;\r\n        return this._groupCounter;\r\n    }\r\n\r\n    /**\r\n     * Adds points to the PCS from the surface of the model shape\r\n     * @param mesh is any Mesh object that will be used as a surface model for the points\r\n     * @param nb (positive integer) the number of particles to be created from this model\r\n     * @param colorWith determines whether a point is colored using color (default), uv, random, stated or none (invisible)\r\n     * @param color (color4) to be used when colorWith is stated or color (number) when used to specify texture position\r\n     * @param range (number from 0 to 1) to determine the variation in shape and tone for a stated color\r\n     * @returns the number of groups in the system\r\n     */\r\n    public addSurfacePoints(mesh: Mesh, nb: number, colorWith?: number, color?: Color4 | number, range?: number): number {\r\n        let colored = colorWith ? colorWith : PointColor.Random;\r\n        if (isNaN(colored) || colored < 0 || colored > 3) {\r\n            colored = PointColor.Random;\r\n        }\r\n\r\n        const meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const meshInd = <IndicesArray>mesh.getIndices();\r\n\r\n        this._groups.push(this._groupCounter);\r\n        const pointsGroup = new PointsGroup(this._groupCounter, null);\r\n\r\n        pointsGroup._groupDensity = this._calculateDensity(nb, meshPos, meshInd);\r\n        if (colored === PointColor.Color) {\r\n            pointsGroup._textureNb = <number>color ? <number>color : 0;\r\n        } else {\r\n            color = <Color4>color ? <Color4>color : new Color4(1, 1, 1, 1);\r\n        }\r\n        switch (colored) {\r\n            case PointColor.Color:\r\n                this._colorFromTexture(mesh, pointsGroup, false);\r\n                break;\r\n            case PointColor.UV:\r\n                this._setPointsColorOrUV(mesh, pointsGroup, false, false, false);\r\n                break;\r\n            case PointColor.Random:\r\n                this._setPointsColorOrUV(mesh, pointsGroup, false);\r\n                break;\r\n            case PointColor.Stated:\r\n                this._setPointsColorOrUV(mesh, pointsGroup, false, undefined, undefined, <Color4>color, range);\r\n                break;\r\n        }\r\n        this.nbParticles += nb;\r\n        this._groupCounter++;\r\n        return this._groupCounter - 1;\r\n    }\r\n\r\n    /**\r\n     * Adds points to the PCS inside the model shape\r\n     * @param mesh is any Mesh object that will be used as a surface model for the points\r\n     * @param nb (positive integer) the number of particles to be created from this model\r\n     * @param colorWith determines whether a point is colored using color (default), uv, random, stated or none (invisible)\r\n     * @param color (color4) to be used when colorWith is stated or color (number) when used to specify texture position\r\n     * @param range (number from 0 to 1) to determine the variation in shape and tone for a stated color\r\n     * @returns the number of groups in the system\r\n     */\r\n    public addVolumePoints(mesh: Mesh, nb: number, colorWith?: number, color?: Color4 | number, range?: number): number {\r\n        let colored = colorWith ? colorWith : PointColor.Random;\r\n        if (isNaN(colored) || colored < 0 || colored > 3) {\r\n            colored = PointColor.Random;\r\n        }\r\n\r\n        const meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const meshInd = <IndicesArray>mesh.getIndices();\r\n\r\n        this._groups.push(this._groupCounter);\r\n        const pointsGroup = new PointsGroup(this._groupCounter, null);\r\n\r\n        pointsGroup._groupDensity = this._calculateDensity(nb, meshPos, meshInd);\r\n        if (colored === PointColor.Color) {\r\n            pointsGroup._textureNb = <number>color ? <number>color : 0;\r\n        } else {\r\n            color = <Color4>color ? <Color4>color : new Color4(1, 1, 1, 1);\r\n        }\r\n        switch (colored) {\r\n            case PointColor.Color:\r\n                this._colorFromTexture(mesh, pointsGroup, true);\r\n                break;\r\n            case PointColor.UV:\r\n                this._setPointsColorOrUV(mesh, pointsGroup, true, false, false);\r\n                break;\r\n            case PointColor.Random:\r\n                this._setPointsColorOrUV(mesh, pointsGroup, true);\r\n                break;\r\n            case PointColor.Stated:\r\n                this._setPointsColorOrUV(mesh, pointsGroup, true, undefined, undefined, <Color4>color, range);\r\n                break;\r\n        }\r\n        this.nbParticles += nb;\r\n        this._groupCounter++;\r\n        return this._groupCounter - 1;\r\n    }\r\n\r\n    /**\r\n     *  Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.\r\n     *  This method calls `updateParticle()` for each particle of the SPS.\r\n     *  For an animated SPS, it is usually called within the render loop.\r\n     * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_\r\n     * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_\r\n     * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_\r\n     * @returns the PCS.\r\n     */\r\n    public setParticles(start: number = 0, end: number = this.nbParticles - 1, update: boolean = true): PointsCloudSystem {\r\n        if (!this._updatable || !this._isReady) {\r\n            return this;\r\n        }\r\n\r\n        // custom beforeUpdate\r\n        this.beforeUpdateParticles(start, end, update);\r\n\r\n        const rotMatrix = TmpVectors.Matrix[0];\r\n        const mesh = this.mesh;\r\n        const colors32 = this._colors32;\r\n        const positions32 = this._positions32;\r\n        const uvs32 = this._uvs32;\r\n\r\n        const tempVectors = TmpVectors.Vector3;\r\n        const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);\r\n        const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);\r\n        const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);\r\n        const minimum = tempVectors[8].setAll(Number.MAX_VALUE);\r\n        const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);\r\n\r\n        Matrix.IdentityToRef(rotMatrix);\r\n        let idx: number; // current index of the particle\r\n\r\n        if (this.mesh?.isFacetDataEnabled) {\r\n            this._computeBoundingBox = true;\r\n        }\r\n\r\n        end = end >= this.nbParticles ? this.nbParticles - 1 : end;\r\n        if (this._computeBoundingBox) {\r\n            if (start != 0 || end != this.nbParticles - 1) {\r\n                // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.\r\n                const boundingInfo = this.mesh?.getBoundingInfo();\r\n                if (boundingInfo) {\r\n                    minimum.copyFrom(boundingInfo.minimum);\r\n                    maximum.copyFrom(boundingInfo.maximum);\r\n                }\r\n            }\r\n        }\r\n\r\n        let pindex: number; //index in positions array\r\n        let cindex: number; //index in color array\r\n        let uindex: number; //index in uv array\r\n\r\n        // particle loop\r\n        for (let p = start; p <= end; p++) {\r\n            const particle = this.particles[p];\r\n            idx = particle.idx;\r\n            pindex = 3 * idx;\r\n            cindex = 4 * idx;\r\n            uindex = 2 * idx;\r\n\r\n            // call to custom user function to update the particle properties\r\n            this.updateParticle(particle);\r\n\r\n            const particleRotationMatrix = particle._rotationMatrix;\r\n            const particlePosition = particle.position;\r\n            const particleGlobalPosition = particle._globalPosition;\r\n\r\n            if (this._computeParticleRotation) {\r\n                particle.getRotationMatrix(rotMatrix);\r\n            }\r\n\r\n            const particleHasParent = particle.parentId !== null;\r\n            if (particleHasParent) {\r\n                const parent = this.particles[particle.parentId!];\r\n                const parentRotationMatrix = parent._rotationMatrix;\r\n                const parentGlobalPosition = parent._globalPosition;\r\n\r\n                const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];\r\n                const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];\r\n                const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];\r\n\r\n                particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;\r\n                particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;\r\n                particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;\r\n\r\n                if (this._computeParticleRotation) {\r\n                    const rotMatrixValues = rotMatrix.m;\r\n                    particleRotationMatrix[0] =\r\n                        rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];\r\n                    particleRotationMatrix[1] =\r\n                        rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];\r\n                    particleRotationMatrix[2] =\r\n                        rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];\r\n                    particleRotationMatrix[3] =\r\n                        rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];\r\n                    particleRotationMatrix[4] =\r\n                        rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];\r\n                    particleRotationMatrix[5] =\r\n                        rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];\r\n                    particleRotationMatrix[6] =\r\n                        rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];\r\n                    particleRotationMatrix[7] =\r\n                        rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];\r\n                    particleRotationMatrix[8] =\r\n                        rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];\r\n                }\r\n            } else {\r\n                particleGlobalPosition.x = 0;\r\n                particleGlobalPosition.y = 0;\r\n                particleGlobalPosition.z = 0;\r\n\r\n                if (this._computeParticleRotation) {\r\n                    const rotMatrixValues = rotMatrix.m;\r\n                    particleRotationMatrix[0] = rotMatrixValues[0];\r\n                    particleRotationMatrix[1] = rotMatrixValues[1];\r\n                    particleRotationMatrix[2] = rotMatrixValues[2];\r\n                    particleRotationMatrix[3] = rotMatrixValues[4];\r\n                    particleRotationMatrix[4] = rotMatrixValues[5];\r\n                    particleRotationMatrix[5] = rotMatrixValues[6];\r\n                    particleRotationMatrix[6] = rotMatrixValues[8];\r\n                    particleRotationMatrix[7] = rotMatrixValues[9];\r\n                    particleRotationMatrix[8] = rotMatrixValues[10];\r\n                }\r\n            }\r\n\r\n            const pivotBackTranslation = tempVectors[11];\r\n            if (particle.translateFromPivot) {\r\n                pivotBackTranslation.setAll(0.0);\r\n            } else {\r\n                pivotBackTranslation.copyFrom(particle.pivot);\r\n            }\r\n\r\n            // positions\r\n            const tmpVertex = tempVectors[0];\r\n            tmpVertex.copyFrom(particle.position);\r\n            const vertexX = tmpVertex.x - particle.pivot.x;\r\n            const vertexY = tmpVertex.y - particle.pivot.y;\r\n            const vertexZ = tmpVertex.z - particle.pivot.z;\r\n\r\n            let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];\r\n            let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];\r\n            let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];\r\n\r\n            rotatedX += pivotBackTranslation.x;\r\n            rotatedY += pivotBackTranslation.y;\r\n            rotatedZ += pivotBackTranslation.z;\r\n\r\n            const px = (positions32[pindex] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ);\r\n            const py = (positions32[pindex + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ);\r\n            const pz = (positions32[pindex + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ);\r\n\r\n            if (this._computeBoundingBox) {\r\n                minimum.minimizeInPlaceFromFloats(px, py, pz);\r\n                maximum.maximizeInPlaceFromFloats(px, py, pz);\r\n            }\r\n\r\n            if (this._computeParticleColor && particle.color) {\r\n                const color = particle.color;\r\n                const colors32 = this._colors32;\r\n                colors32[cindex] = color.r;\r\n                colors32[cindex + 1] = color.g;\r\n                colors32[cindex + 2] = color.b;\r\n                colors32[cindex + 3] = color.a;\r\n            }\r\n            if (this._computeParticleTexture && particle.uv) {\r\n                const uv = particle.uv;\r\n                const uvs32 = this._uvs32;\r\n                uvs32[uindex] = uv.x;\r\n                uvs32[uindex + 1] = uv.y;\r\n            }\r\n        }\r\n\r\n        // if the VBO must be updated\r\n        if (mesh) {\r\n            if (update) {\r\n                if (this._computeParticleColor) {\r\n                    mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);\r\n                }\r\n                if (this._computeParticleTexture) {\r\n                    mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);\r\n                }\r\n                mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);\r\n            }\r\n\r\n            if (this._computeBoundingBox) {\r\n                if (mesh.hasBoundingInfo) {\r\n                    mesh.getBoundingInfo().reConstruct(minimum, maximum, mesh._worldMatrix);\r\n                } else {\r\n                    mesh.buildBoundingInfo(minimum, maximum, mesh._worldMatrix);\r\n                }\r\n            }\r\n        }\r\n        this.afterUpdateParticles(start, end, update);\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disposes the PCS.\r\n     */\r\n    public dispose(): void {\r\n        this.mesh?.dispose();\r\n        this.vars = null;\r\n        // drop references to internal big arrays for the GC\r\n        (<any>this._positions) = null;\r\n        (<any>this._indices) = null;\r\n        (<any>this._normals) = null;\r\n        (<any>this._uvs) = null;\r\n        (<any>this._colors) = null;\r\n        (<any>this._indices32) = null;\r\n        (<any>this._positions32) = null;\r\n        (<any>this._uvs32) = null;\r\n        (<any>this._colors32) = null;\r\n    }\r\n\r\n    /**\r\n     * Visibility helper : Recomputes the visible size according to the mesh bounding box\r\n     * doc :\r\n     * @returns the PCS.\r\n     */\r\n    public refreshVisibleSize(): PointsCloudSystem {\r\n        if (!this._isVisibilityBoxLocked) {\r\n            this.mesh?.refreshBoundingInfo();\r\n        }\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.\r\n     * @param size the size (float) of the visibility box\r\n     * note : this doesn't lock the PCS mesh bounding box.\r\n     * doc :\r\n     */\r\n    public setVisibilityBox(size: number): void {\r\n        if (!this.mesh) {\r\n            return;\r\n        }\r\n\r\n        const vis = size / 2;\r\n        this.mesh.buildBoundingInfo(new Vector3(-vis, -vis, -vis), new Vector3(vis, vis, vis));\r\n    }\r\n\r\n    /**\r\n     * Gets whether the PCS is always visible or not\r\n     * doc :\r\n     */\r\n    public get isAlwaysVisible(): boolean {\r\n        return this._alwaysVisible;\r\n    }\r\n\r\n    /**\r\n     * Sets the PCS as always visible or not\r\n     * doc :\r\n     */\r\n    public set isAlwaysVisible(val: boolean) {\r\n        if (!this.mesh) {\r\n            return;\r\n        }\r\n\r\n        this._alwaysVisible = val;\r\n        this.mesh.alwaysSelectAsActiveMesh = val;\r\n    }\r\n\r\n    /**\r\n     * Tells to `setParticles()` to compute the particle rotations or not\r\n     * Default value : false. The PCS is faster when it's set to false\r\n     * Note : particle rotations are only applied to parent particles\r\n     * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate\r\n     */\r\n    public set computeParticleRotation(val: boolean) {\r\n        this._computeParticleRotation = val;\r\n    }\r\n\r\n    /**\r\n     * Tells to `setParticles()` to compute the particle colors or not.\r\n     * Default value : true. The PCS is faster when it's set to false.\r\n     * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\r\n     */\r\n    public set computeParticleColor(val: boolean) {\r\n        this._computeParticleColor = val;\r\n    }\r\n\r\n    public set computeParticleTexture(val: boolean) {\r\n        this._computeParticleTexture = val;\r\n    }\r\n    /**\r\n     * Gets if `setParticles()` computes the particle colors or not.\r\n     * Default value : false. The PCS is faster when it's set to false.\r\n     * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\r\n     */\r\n    public get computeParticleColor(): boolean {\r\n        return this._computeParticleColor;\r\n    }\r\n    /**\r\n     * Gets if `setParticles()` computes the particle textures or not.\r\n     * Default value : false. The PCS is faster when it's set to false.\r\n     * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.\r\n     */\r\n    public get computeParticleTexture(): boolean {\r\n        return this._computeParticleTexture;\r\n    }\r\n    /**\r\n     * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.\r\n     */\r\n    public set computeBoundingBox(val: boolean) {\r\n        this._computeBoundingBox = val;\r\n    }\r\n    /**\r\n     * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.\r\n     */\r\n    public get computeBoundingBox(): boolean {\r\n        return this._computeBoundingBox;\r\n    }\r\n\r\n    // =======================================================================\r\n    // Particle behavior logic\r\n    // these following methods may be overwritten by users to fit their needs\r\n\r\n    /**\r\n     * This function does nothing. It may be overwritten to set all the particle first values.\r\n     * The PCS doesn't call this function, you may have to call it by your own.\r\n     * doc :\r\n     */\r\n    public initParticles(): void {}\r\n\r\n    /**\r\n     * This function does nothing. It may be overwritten to recycle a particle\r\n     * The PCS doesn't call this function, you can to call it\r\n     * doc :\r\n     * @param particle The particle to recycle\r\n     * @returns the recycled particle\r\n     */\r\n    public recycleParticle(particle: CloudPoint): CloudPoint {\r\n        return particle;\r\n    }\r\n\r\n    /**\r\n     * Updates a particle : this function should  be overwritten by the user.\r\n     * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.\r\n     * doc :\r\n     * @example : just set a particle position or velocity and recycle conditions\r\n     * @param particle The particle to update\r\n     * @returns the updated particle\r\n     */\r\n    public updateParticle(particle: CloudPoint): CloudPoint {\r\n        return particle;\r\n    }\r\n\r\n    /**\r\n     * This will be called before any other treatment by `setParticles()` and will be passed three parameters.\r\n     * This does nothing and may be overwritten by the user.\r\n     * @param start the particle index in the particle array where to start to iterate, same than the value passed to setParticle()\r\n     * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\r\n     * @param update the boolean update value actually passed to setParticles()\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public beforeUpdateParticles(start?: number, stop?: number, update?: boolean): void {}\r\n    /**\r\n     * This will be called  by `setParticles()` after all the other treatments and just before the actual mesh update.\r\n     * This will be passed three parameters.\r\n     * This does nothing and may be overwritten by the user.\r\n     * @param start the particle index in the particle array where to start to iterate, same than the value passed to setParticle()\r\n     * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\r\n     * @param update the boolean update value actually passed to setParticles()\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public afterUpdateParticles(start?: number, stop?: number, update?: boolean): void {}\r\n}\r\n","import { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type Particle } from \"../Particles/particle\";\r\nimport { type IVector3Like } from \"../Maths/math.like\";\r\nimport { type Texture } from \"core/Materials/Textures/texture\";\r\nimport { TextureTools } from \"core/Misc/textureTools\";\r\n\r\nconst FlowVector = new Vector3(0, 0, 0);\r\nconst ScaledFlowVector = new Vector3(0, 0, 0);\r\nconst ScreenPos = new Vector3(0, 0, 0);\r\n\r\n/**\r\n * Represents an object that can move or be influenced by FlowMap\r\n */\r\nexport interface IFlowable {\r\n    /**\r\n     * The direction vector indicating the flow or movement direction of the object.\r\n     */\r\n    direction: Vector3;\r\n\r\n    /**\r\n     * The current position of the object in 3D space.\r\n     */\r\n    position: Vector3;\r\n}\r\n\r\n/**\r\n * Class used to represent a particle flow map.\r\n * #5DM02T#7\r\n * GPUParts: #5DM02T#12 (webgl2)\r\n * GPUParts: #5DM02T#13 (webgpu)\r\n */\r\nexport class FlowMap {\r\n    /**\r\n     * Create a new flow map.\r\n     * @param width defines the width of the flow map\r\n     * @param height defines the height of the flow map\r\n     * @param data defines the data of the flow map\r\n     */\r\n    constructor(\r\n        public readonly width: number,\r\n        public readonly height: number,\r\n        public readonly data: Uint8ClampedArray\r\n    ) {}\r\n\r\n    /**\r\n     * Applies the flow map to a flowable object.\r\n     * @param flowable defines the object to update\r\n     * @param strength defines the strength of the flow map influence\r\n     * @param flowMapSamplePosOrTransformationMatrix defines the flow map sample position or transformation matrix\r\n     */\r\n    public processFlowable(flowable: IFlowable, strength = 1, flowMapSamplePosOrTransformationMatrix?: IVector3Like | Matrix): void {\r\n        if (!flowMapSamplePosOrTransformationMatrix) {\r\n            return;\r\n        }\r\n\r\n        // Convert world pos to screen pos\r\n        if (flowMapSamplePosOrTransformationMatrix instanceof Matrix) {\r\n            Vector3.TransformCoordinatesToRef(flowable.position, flowMapSamplePosOrTransformationMatrix, ScreenPos);\r\n        } else {\r\n            ScreenPos.x = flowMapSamplePosOrTransformationMatrix.x;\r\n            ScreenPos.y = flowMapSamplePosOrTransformationMatrix.y;\r\n            ScreenPos.z = flowMapSamplePosOrTransformationMatrix.z;\r\n        }\r\n\r\n        const u = ScreenPos.x * 0.5 + 0.5;\r\n        const v = 1.0 - (ScreenPos.y * 0.5 + 0.5);\r\n\r\n        const x = Math.floor(u * this.width);\r\n        const y = Math.floor(v * this.height);\r\n\r\n        // Clamp\r\n        if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\r\n            return;\r\n        }\r\n\r\n        const index = (y * this.width + x) * 4;\r\n        const r = this.data[index];\r\n        const g = this.data[index + 1];\r\n        const b = this.data[index + 2];\r\n        const a = this.data[index + 3];\r\n\r\n        const fx = (r / 255.0) * 2.0 - 1.0;\r\n        const fy = (g / 255.0) * 2.0 - 1.0;\r\n        const fz = (b / 255.0) * 2.0 - 1.0;\r\n        const localStrength = a / 255.0;\r\n\r\n        FlowVector.set(fx, fy, fz);\r\n        FlowVector.scaleToRef(strength * localStrength, ScaledFlowVector);\r\n\r\n        flowable.direction.addInPlace(ScaledFlowVector); // Update IFlowable velocity\r\n    }\r\n\r\n    /** @internal */\r\n    public _processParticle(particle: Particle, strength = 1, matrix?: Matrix) {\r\n        this.processFlowable(particle, strength, matrix);\r\n    }\r\n\r\n    /**\r\n     * Creates a FlowMap from a url.\r\n     * @param url The url of the image to load\r\n     * @returns a promise that resolves to a FlowMap object\r\n     */\r\n    public static async FromUrlAsync(url: string): Promise<FlowMap> {\r\n        return await new Promise((resolve, reject) => {\r\n            const flowCanvas = document.createElement(\"canvas\");\r\n            const flowCtx = flowCanvas.getContext(\"2d\")!;\r\n            let flowImageData = null;\r\n\r\n            const flowMapImage = new Image();\r\n            flowMapImage.crossOrigin = \"anonymous\"; // If loading from another domain\r\n            flowMapImage.src = url;\r\n\r\n            flowMapImage.onerror = (e) => {\r\n                reject(new Error(`Failed to load image: ${url} : ${e}`));\r\n            };\r\n\r\n            flowMapImage.onload = () => {\r\n                flowCanvas.width = flowMapImage.width;\r\n                flowCanvas.height = flowMapImage.height;\r\n                flowCtx.drawImage(flowMapImage, 0, 0);\r\n                flowImageData = flowCtx.getImageData(0, 0, flowCanvas.width, flowCanvas.height);\r\n\r\n                resolve(new FlowMap(flowCanvas.width, flowCanvas.height, flowImageData.data));\r\n            };\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Load from a texture\r\n     * @param texture defines the source texture\r\n     * @returns a promise fulfilled when image data is loaded\r\n     */\r\n    public static async ExtractFromTextureAsync(texture: Texture) {\r\n        const data = await TextureTools.GetTextureDataAsync(texture);\r\n        const { width, height } = texture.getSize();\r\n        return new FlowMap(width, height, new Uint8ClampedArray(data));\r\n    }\r\n}\r\n","/**\r\n * Defines the kind of connection point for node geometry\r\n */\r\nexport enum NodeParticleBlockConnectionPointTypes {\r\n    /** Int */\r\n    Int = 0x0001,\r\n    /** Float */\r\n    Float = 0x0002,\r\n    /** Vector2 */\r\n    Vector2 = 0x0004,\r\n    /** Vector3 */\r\n    Vector3 = 0x0008,\r\n    /** Matrix */\r\n    Matrix = 0x0010,\r\n    /** Particle */\r\n    Particle = 0x0020,\r\n    /** Texture */\r\n    Texture = 0x0040,\r\n    /** Color4 */\r\n    Color4 = 0x0080,\r\n    /** FloatGradient */\r\n    FloatGradient = 0x0100,\r\n    /** Vector2Gradient */\r\n    Vector2Gradient = 0x0200,\r\n    /** Vector3Gradient */\r\n    Vector3Gradient = 0x0400,\r\n    /** Color4Gradient */\r\n    Color4Gradient = 0x0800,\r\n    /** System */\r\n    System = 0x1000,\r\n    /** Detect type based on connection */\r\n    AutoDetect = 0x2000,\r\n    /** Output type that will be defined by input type */\r\n    BasedOnInput = 0x4000,\r\n    /** Undefined */\r\n    Undefined = 0x8000,\r\n    /** Bitmask of all types */\r\n    All = 0xffff,\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { type NodeParticleBlock } from \"./nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"./Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleBuildState } from \"./nodeParticleBuildState\";\r\nimport { type ParticleInputBlock } from \"./Blocks/particleInputBlock\";\r\n\r\n/**\r\n * Enum used to define the compatibility state between two connection points\r\n */\r\nexport const enum NodeParticleConnectionPointCompatibilityStates {\r\n    /** Points are compatibles */\r\n    Compatible,\r\n    /** Points are incompatible because of their types */\r\n    TypeIncompatible,\r\n    /** Points are incompatible because they are in the same hierarchy **/\r\n    HierarchyIssue,\r\n}\r\n\r\n/**\r\n * Defines the direction of a connection point\r\n */\r\nexport const enum NodeParticleConnectionPointDirection {\r\n    /** Input */\r\n    Input,\r\n    /** Output */\r\n    Output,\r\n}\r\n\r\n/**\r\n * Defines a connection point for a block\r\n */\r\nexport class NodeParticleConnectionPoint {\r\n    /** @internal */\r\n    public _ownerBlock: NodeParticleBlock;\r\n    /** @internal */\r\n    public _connectedPoint: Nullable<NodeParticleConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _storedValue: any = null;\r\n    /** @internal */\r\n    public _storedFunction: Nullable<(state: NodeParticleBuildState) => any> = null;\r\n\r\n    /** @internal */\r\n    public _acceptedConnectionPointType: Nullable<NodeParticleConnectionPoint> = null;\r\n\r\n    private _endpoints = new Array<NodeParticleConnectionPoint>();\r\n    private _direction: NodeParticleConnectionPointDirection;\r\n    private _type = NodeParticleBlockConnectionPointTypes.Particle;\r\n\r\n    /** @internal */\r\n    public _linkedConnectionSource: Nullable<NodeParticleConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _typeConnectionSource: Nullable<NodeParticleConnectionPoint> = null;\r\n\r\n    /** @internal */\r\n    public _typeConnectionSourceTranslation: Nullable<(source: NodeParticleBlockConnectionPointTypes) => NodeParticleBlockConnectionPointTypes> = null;\r\n\r\n    /** @internal */\r\n    public _defaultConnectionPointType: Nullable<NodeParticleBlockConnectionPointTypes> = null;\r\n\r\n    /** @internal */\r\n    public _isMainLinkSource = false;\r\n\r\n    /** Gets the direction of the point */\r\n    public get direction() {\r\n        return this._direction;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the additional types supported by this connection point\r\n     */\r\n    public acceptedConnectionPointTypes: NodeParticleBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Gets or sets the additional types excluded by this connection point\r\n     */\r\n    public excludedConnectionPointTypes: NodeParticleBlockConnectionPointTypes[] = [];\r\n\r\n    /**\r\n     * Observable triggered when this point is connected\r\n     */\r\n    public onConnectionObservable = new Observable<NodeParticleConnectionPoint>();\r\n\r\n    /**\r\n     * Observable triggered when this point is disconnected\r\n     */\r\n    public onDisconnectionObservable = new Observable<NodeParticleConnectionPoint>();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point is exposed on a frame\r\n     */\r\n    public isExposedOnFrame: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets number indicating the position that the port is exposed to on a frame\r\n     */\r\n    public exposedPortPosition: number = -1;\r\n\r\n    /**\r\n     * Gets the default value used for this point at creation time\r\n     */\r\n    public defaultValue: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the default value used for this point if nothing is connected\r\n     */\r\n    public value: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the min value accepted for this point if nothing is connected\r\n     */\r\n    public valueMin: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the max value accepted for this point if nothing is connected\r\n     */\r\n    public valueMax: Nullable<any> = null;\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is float)\r\n     */\r\n    public get type(): NodeParticleBlockConnectionPointTypes {\r\n        if (this._type === NodeParticleBlockConnectionPointTypes.AutoDetect) {\r\n            if (this._ownerBlock.isInput) {\r\n                return (this._ownerBlock as ParticleInputBlock).type;\r\n            }\r\n\r\n            if (this._connectedPoint) {\r\n                return this._connectedPoint.type;\r\n            }\r\n\r\n            if (this._linkedConnectionSource) {\r\n                if (this._linkedConnectionSource.isConnected) {\r\n                    return this._linkedConnectionSource.type;\r\n                }\r\n                if (this._linkedConnectionSource._defaultConnectionPointType) {\r\n                    return this._linkedConnectionSource._defaultConnectionPointType;\r\n                }\r\n            }\r\n\r\n            if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        if (this._type === NodeParticleBlockConnectionPointTypes.BasedOnInput) {\r\n            if (this._typeConnectionSource) {\r\n                if (!this._typeConnectionSource.isConnected && this._defaultConnectionPointType) {\r\n                    return this._defaultConnectionPointType;\r\n                }\r\n                if (this._typeConnectionSourceTranslation) {\r\n                    return this._typeConnectionSourceTranslation(this._typeConnectionSource.type);\r\n                }\r\n                return this._typeConnectionSource.type;\r\n            } else if (this._defaultConnectionPointType) {\r\n                return this._defaultConnectionPointType;\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    public set type(value: NodeParticleBlockConnectionPointTypes) {\r\n        this._type = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the connection point name\r\n     */\r\n    public name: string;\r\n\r\n    /**\r\n     * Gets or sets the connection point display name\r\n     */\r\n    public displayName: string;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this connection point can be omitted\r\n     */\r\n    public isOptional: boolean;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current point is connected to another NodeMaterialBlock\r\n     */\r\n    public get isConnected(): boolean {\r\n        return this.connectedPoint !== null || this.hasEndpoints;\r\n    }\r\n\r\n    /** Get the other side of the connection (if any) */\r\n    public get connectedPoint(): Nullable<NodeParticleConnectionPoint> {\r\n        return this._connectedPoint;\r\n    }\r\n\r\n    /** Get the block that owns this connection point */\r\n    public get ownerBlock(): NodeParticleBlock {\r\n        return this._ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the other side of this connection (if any) */\r\n    public get sourceBlock(): Nullable<NodeParticleBlock> {\r\n        if (!this._connectedPoint) {\r\n            return null;\r\n        }\r\n\r\n        return this._connectedPoint.ownerBlock;\r\n    }\r\n\r\n    /** Get the block connected on the endpoints of this connection (if any) */\r\n    public get connectedBlocks(): Array<NodeParticleBlock> {\r\n        if (this._endpoints.length === 0) {\r\n            return [];\r\n        }\r\n\r\n        return this._endpoints.map((e) => e.ownerBlock);\r\n    }\r\n\r\n    /** Gets the list of connected endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /** Gets a boolean indicating if that output point is connected to at least one input */\r\n    public get hasEndpoints(): boolean {\r\n        return this._endpoints && this._endpoints.length > 0;\r\n    }\r\n\r\n    /** Get the inner type (ie AutoDetect for instance instead of the inferred one) */\r\n    public get innerType() {\r\n        if (this._linkedConnectionSource && !this._isMainLinkSource && this._linkedConnectionSource.isConnected) {\r\n            return this.type;\r\n        }\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Creates a new connection point\r\n     * @param name defines the connection point name\r\n     * @param ownerBlock defines the block hosting this connection point\r\n     * @param direction defines the direction of the connection point\r\n     */\r\n    public constructor(name: string, ownerBlock: NodeParticleBlock, direction: NodeParticleConnectionPointDirection) {\r\n        this._ownerBlock = ownerBlock;\r\n        this.name = name;\r\n        this._direction = direction;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeMaterialConnectionPoint\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeParticleConnectionPoint\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value represented by this connection point\r\n     * @param state current evaluation state\r\n     * @returns the connected value or the value if nothing is connected\r\n     */\r\n    public getConnectedValue(state: NodeParticleBuildState) {\r\n        if (this.isConnected) {\r\n            if (this._connectedPoint?._storedFunction) {\r\n                return this._connectedPoint._storedFunction(state);\r\n            }\r\n            return this._connectedPoint!._storedValue;\r\n        }\r\n        return this.value;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a boolean\r\n     */\r\n    public canConnectTo(connectionPoint: NodeParticleConnectionPoint) {\r\n        return this.checkCompatibilityState(connectionPoint) === NodeParticleConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Gets a number indicating if the current point can be connected to another point\r\n     * @param connectionPoint defines the other connection point\r\n     * @returns a number defining the compatibility state\r\n     */\r\n    public checkCompatibilityState(connectionPoint: NodeParticleConnectionPoint): NodeParticleConnectionPointCompatibilityStates {\r\n        const ownerBlock = this._ownerBlock;\r\n        const otherBlock = connectionPoint.ownerBlock;\r\n\r\n        if (this.type !== connectionPoint.type && connectionPoint.innerType !== NodeParticleBlockConnectionPointTypes.AutoDetect) {\r\n            // Accepted types\r\n            if (connectionPoint.acceptedConnectionPointTypes && connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n                return NodeParticleConnectionPointCompatibilityStates.Compatible;\r\n            } else {\r\n                return NodeParticleConnectionPointCompatibilityStates.TypeIncompatible;\r\n            }\r\n        }\r\n\r\n        // Excluded\r\n        if (connectionPoint.excludedConnectionPointTypes && connectionPoint.excludedConnectionPointTypes.indexOf(this.type) !== -1) {\r\n            return NodeParticleConnectionPointCompatibilityStates.TypeIncompatible;\r\n        }\r\n\r\n        // Check hierarchy\r\n        let targetBlock = otherBlock;\r\n        let sourceBlock = ownerBlock;\r\n        if (this.direction === NodeParticleConnectionPointDirection.Input) {\r\n            targetBlock = ownerBlock;\r\n            sourceBlock = otherBlock;\r\n        }\r\n\r\n        if (targetBlock.isAnAncestorOf(sourceBlock)) {\r\n            return NodeParticleConnectionPointCompatibilityStates.HierarchyIssue;\r\n        }\r\n\r\n        return NodeParticleConnectionPointCompatibilityStates.Compatible;\r\n    }\r\n\r\n    /**\r\n     * Connect this point to another connection point\r\n     * @param connectionPoint defines the other connection point\r\n     * @param ignoreConstraints defines if the system will ignore connection type constraints (default is false)\r\n     * @returns the current connection point\r\n     */\r\n    public connectTo(connectionPoint: NodeParticleConnectionPoint, ignoreConstraints = false): NodeParticleConnectionPoint {\r\n        if (!ignoreConstraints && !this.canConnectTo(connectionPoint)) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw `Cannot connect these two connectors. source: \"${this.ownerBlock.name}\".${this.name}, target: \"${connectionPoint.ownerBlock.name}\".${connectionPoint.name}`;\r\n        }\r\n\r\n        this._endpoints.push(connectionPoint);\r\n        connectionPoint._connectedPoint = this;\r\n\r\n        this.onConnectionObservable.notifyObservers(connectionPoint);\r\n        connectionPoint.onConnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Disconnect this point from one of his endpoint\r\n     * @param endpoint defines the other connection point\r\n     * @returns the current connection point\r\n     */\r\n    public disconnectFrom(endpoint: NodeParticleConnectionPoint): NodeParticleConnectionPoint {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index === -1) {\r\n            return this;\r\n        }\r\n\r\n        this._endpoints.splice(index, 1);\r\n        endpoint._connectedPoint = null;\r\n\r\n        this.onDisconnectionObservable.notifyObservers(endpoint);\r\n        endpoint.onDisconnectionObservable.notifyObservers(this);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Fill the list of excluded connection point types with all types other than those passed in the parameter\r\n     * @param mask Types (ORed values of NodeMaterialBlockConnectionPointTypes) that are allowed, and thus will not be pushed to the excluded list\r\n     */\r\n    public addExcludedConnectionPointFromAllowedTypes(mask: number): void {\r\n        let bitmask = 1;\r\n        while (bitmask < NodeParticleBlockConnectionPointTypes.All) {\r\n            if (!(mask & bitmask)) {\r\n                this.excludedConnectionPointTypes.push(bitmask);\r\n            }\r\n            bitmask = bitmask << 1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this point in a JSON representation\r\n     * @param isInput defines if the connection point is an input (default is true)\r\n     * @returns the serialized point object\r\n     */\r\n    public serialize(isInput = true): any {\r\n        const serializationObject: any = {};\r\n\r\n        serializationObject.name = this.name;\r\n        serializationObject.displayName = this.displayName;\r\n        if (this.value !== undefined && this.value !== null) {\r\n            if (this.value.asArray) {\r\n                serializationObject.valueType = \"BABYLON.\" + this.value.getClassName();\r\n                serializationObject.value = this.value.asArray();\r\n            } else {\r\n                serializationObject.valueType = \"number\";\r\n                serializationObject.value = this.value;\r\n            }\r\n        }\r\n\r\n        if (isInput && this.connectedPoint) {\r\n            serializationObject.inputName = this.name;\r\n            serializationObject.targetBlockId = this.connectedPoint.ownerBlock.uniqueId;\r\n            serializationObject.targetConnectionName = this.connectedPoint.name;\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        if (this.isExposedOnFrame || this.exposedPortPosition >= 0) {\r\n            serializationObject.isExposedOnFrame = true;\r\n            serializationObject.exposedPortPosition = this.exposedPortPosition;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        this.onConnectionObservable.clear();\r\n        this.onDisconnectionObservable.clear();\r\n    }\r\n}\r\n","import { serialize } from \"core/Misc/decorators\";\r\nimport { UniqueIdGenerator } from \"core/Misc/uniqueIdGenerator\";\r\nimport { NodeParticleConnectionPoint, NodeParticleConnectionPointDirection } from \"./nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBlockConnectionPointTypes } from \"./Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleBuildState } from \"./nodeParticleBuildState\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { GetClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block that can be used inside a node based particle system\r\n */\r\nexport class NodeParticleBlock {\r\n    private _name = \"\";\r\n    protected _buildId: number;\r\n    protected _isInput = false;\r\n    protected _isSystem = false;\r\n    protected _isDebug = false;\r\n    protected _isTeleportOut = false;\r\n    protected _isTeleportIn = false;\r\n\r\n    /**\r\n     * Gets or sets the unique id of the node\r\n     */\r\n    public uniqueId: number;\r\n\r\n    /** @internal */\r\n    public _inputs = new Array<NodeParticleConnectionPoint>();\r\n    /** @internal */\r\n    public _outputs = new Array<NodeParticleConnectionPoint>();\r\n\r\n    /**\r\n     * Gets an observable raised when the block is built\r\n     */\r\n    public onBuildObservable = new Observable<NodeParticleBlock>();\r\n\r\n    /**\r\n     * Gets an observable raised when the block is disposed\r\n     */\r\n    public onDisposeObservable = new Observable<NodeParticleBlock>();\r\n\r\n    /**\r\n     * Gets an observable raised when the inputs of the block change\r\n     */\r\n    public onInputChangedObservable = new Observable<NodeParticleConnectionPoint>();\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport out\r\n     */\r\n    public get isTeleportOut(): boolean {\r\n        return this._isTeleportOut;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a teleport in\r\n     */\r\n    public get isTeleportIn(): boolean {\r\n        return this._isTeleportIn;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block is a system block\r\n     */\r\n    public get isSystem(): boolean {\r\n        return this._isSystem;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that this block is an input block\r\n     */\r\n    public get isInput(): boolean {\r\n        return this._isInput;\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if this block is a debug block\r\n     */\r\n    public get isDebug(): boolean {\r\n        return this._isDebug;\r\n    }\r\n\r\n    /**\r\n     * A free comment about the block\r\n     */\r\n    @serialize(\"comment\")\r\n    public comments: string;\r\n\r\n    /** Gets or sets a boolean indicating that this input can be edited from a collapsed frame */\r\n    public visibleOnFrame = false;\r\n\r\n    /**\r\n     * Gets or set the name of the block\r\n     */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    public set name(value: string) {\r\n        this._name = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name e.g. \"NodeParticleBlock\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName() {\r\n        return \"NodeParticleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the list of input points\r\n     */\r\n    public get inputs(): NodeParticleConnectionPoint[] {\r\n        return this._inputs;\r\n    }\r\n\r\n    /** Gets the list of output points */\r\n    public get outputs(): NodeParticleConnectionPoint[] {\r\n        return this._outputs;\r\n    }\r\n\r\n    /**\r\n     * Creates a new NodeParticleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        this._name = name;\r\n        this.uniqueId = UniqueIdGenerator.UniqueId;\r\n    }\r\n\r\n    protected _inputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    protected _outputRename(name: string) {\r\n        return name;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOf(block: NodeParticleBlock): boolean {\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock === block) {\r\n                    return true;\r\n                }\r\n                if (endpoint.ownerBlock.isAnAncestorOf(block)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given type\r\n     * @param type defines the potential type to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public isAnAncestorOfType(type: string): boolean {\r\n        if (this.getClassName() === type) {\r\n            return true;\r\n        }\r\n\r\n        for (const output of this._outputs) {\r\n            if (!output.hasEndpoints) {\r\n                continue;\r\n            }\r\n\r\n            for (const endpoint of output.endpoints) {\r\n                if (endpoint.ownerBlock.isAnAncestorOfType(type)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Find an input by its name\r\n     * @param name defines the name of the input to look for\r\n     * @returns the input or null if not found\r\n     */\r\n    public getInputByName(name: string) {\r\n        const filter = this._inputs.filter((e) => e.name === name);\r\n\r\n        if (filter.length) {\r\n            return filter[0];\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    protected _linkConnectionTypes(inputIndex0: number, inputIndex1: number, looseCoupling = false) {\r\n        if (looseCoupling) {\r\n            this._inputs[inputIndex1]._acceptedConnectionPointType = this._inputs[inputIndex0];\r\n        } else {\r\n            this._inputs[inputIndex0]._linkedConnectionSource = this._inputs[inputIndex1];\r\n            this._inputs[inputIndex0]._isMainLinkSource = true;\r\n        }\r\n        this._inputs[inputIndex1]._linkedConnectionSource = this._inputs[inputIndex0];\r\n    }\r\n\r\n    /**\r\n     * Register a new input. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param isOptional defines a boolean indicating that this input can be omitted\r\n     * @param value value to return if there is no connection\r\n     * @param valueMin min value accepted for value\r\n     * @param valueMax max value accepted for value\r\n     * @returns the current block\r\n     */\r\n    public registerInput(name: string, type: NodeParticleBlockConnectionPointTypes, isOptional: boolean = false, value?: any, valueMin?: any, valueMax?: any) {\r\n        const point = new NodeParticleConnectionPoint(name, this, NodeParticleConnectionPointDirection.Input);\r\n        point.type = type;\r\n        point.isOptional = isOptional;\r\n        point.defaultValue = value;\r\n        point.value = value;\r\n        point.valueMin = valueMin;\r\n        point.valueMax = valueMax;\r\n\r\n        this._inputs.push(point);\r\n\r\n        this.onInputChangedObservable.notifyObservers(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Register a new output. Must be called inside a block constructor\r\n     * @param name defines the connection point name\r\n     * @param type defines the connection point type\r\n     * @param point an already created connection point. If not provided, create a new one\r\n     * @returns the current block\r\n     */\r\n    public registerOutput(name: string, type: NodeParticleBlockConnectionPointTypes, point?: NodeParticleConnectionPoint) {\r\n        point = point ?? new NodeParticleConnectionPoint(name, this, NodeParticleConnectionPointDirection.Output);\r\n        point.type = type;\r\n\r\n        this._outputs.push(point);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Builds the block. Must be implemented by derived classes.\r\n     * @param _state defines the current build state\r\n     */\r\n    public _build(_state: NodeParticleBuildState) {}\r\n\r\n    protected _customBuildStep(_state: NodeParticleBuildState): void {\r\n        // Must be implemented by children\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     * @returns the built block\r\n     */\r\n    public build(state: NodeParticleBuildState) {\r\n        if (this._buildId === state.buildId) {\r\n            return true;\r\n        }\r\n\r\n        if (this._outputs.length > 0) {\r\n            if (!this._outputs.some((o) => o.hasEndpoints) && !this.isDebug && !this.isSystem) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        this._buildId = state.buildId;\r\n\r\n        // Check if \"parent\" blocks are compiled\r\n        for (const input of this._inputs) {\r\n            if (!input.connectedPoint) {\r\n                if (!input.isOptional) {\r\n                    // Emit a warning\r\n                    state.notConnectedNonOptionalInputs.push(input);\r\n                }\r\n                continue;\r\n            }\r\n\r\n            const block = input.connectedPoint.ownerBlock;\r\n            if (block && block !== this && !block.isSystem) {\r\n                block.build(state);\r\n            }\r\n        }\r\n\r\n        this._customBuildStep(state);\r\n\r\n        // Logs\r\n        if (state.verbose) {\r\n            Logger.Log(`Building ${this.name} [${this.getClassName()}]`);\r\n        }\r\n\r\n        this._build(state);\r\n\r\n        this.onBuildObservable.notifyObservers(this);\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public serialize(): any {\r\n        const serializationObject: any = {};\r\n        serializationObject.customType = \"BABYLON.\" + this.getClassName();\r\n        serializationObject.id = this.uniqueId;\r\n        serializationObject.name = this.name;\r\n        serializationObject.visibleOnFrame = this.visibleOnFrame;\r\n        serializationObject.comments = this.comments;\r\n\r\n        serializationObject.inputs = [];\r\n        serializationObject.outputs = [];\r\n\r\n        for (const input of this.inputs) {\r\n            serializationObject.inputs.push(input.serialize());\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            serializationObject.outputs.push(output.serialize(false));\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _deserialize(serializationObject: any) {\r\n        this._name = serializationObject.name;\r\n        this.comments = serializationObject.comments;\r\n        this.visibleOnFrame = !!serializationObject.visibleOnFrame;\r\n        this._deserializePortDisplayNamesAndExposedOnFrame(serializationObject);\r\n    }\r\n\r\n    private _deserializePortDisplayNamesAndExposedOnFrame(serializationObject: any) {\r\n        const serializedInputs = serializationObject.inputs;\r\n        const serializedOutputs = serializationObject.outputs;\r\n        if (serializedInputs) {\r\n            for (const port of serializedInputs) {\r\n                const input = this.inputs.find((i) => i.name === port.name);\r\n\r\n                if (!input) {\r\n                    return;\r\n                }\r\n\r\n                if (port.displayName) {\r\n                    input.displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    input.isExposedOnFrame = port.isExposedOnFrame;\r\n                    input.exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n                if (port.value !== undefined && port.value !== null) {\r\n                    if (port.valueType === \"number\") {\r\n                        input.value = port.value;\r\n                    } else {\r\n                        const valueType = GetClass(port.valueType);\r\n\r\n                        if (valueType) {\r\n                            input.value = valueType.FromArray(port.value);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        if (serializedOutputs) {\r\n            for (let i = 0; i < serializedOutputs.length; i++) {\r\n                const port = serializedOutputs[i];\r\n                if (port.displayName) {\r\n                    this.outputs[i].displayName = port.displayName;\r\n                }\r\n                if (port.isExposedOnFrame) {\r\n                    this.outputs[i].isExposedOnFrame = port.isExposedOnFrame;\r\n                    this.outputs[i].exposedPortPosition = port.exposedPortPosition;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @returns a copy of the current block\r\n     */\r\n    public clone() {\r\n        const serializationObject = this.serialize();\r\n\r\n        const blockType = GetClass(serializationObject.customType);\r\n        if (blockType) {\r\n            const block: NodeParticleBlock = new blockType();\r\n            block._deserialize(serializationObject);\r\n\r\n            return block;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public dispose() {\r\n        this.onDisposeObservable.notifyObservers(this);\r\n        this.onDisposeObservable.clear();\r\n\r\n        for (const input of this.inputs) {\r\n            input.dispose();\r\n        }\r\n\r\n        for (const output of this.outputs) {\r\n            output.dispose();\r\n        }\r\n\r\n        this.onBuildObservable.clear();\r\n        this.onInputChangedObservable.clear();\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/**\r\n * Defines the kind of contextual sources for node particles\r\n */\r\nexport enum NodeParticleContextualSources {\r\n    /** None */\r\n    None = 0x0000,\r\n    /** Position */\r\n    Position = 0x0001,\r\n    /** Direction */\r\n    Direction = 0x0002,\r\n    /** Age */\r\n    Age = 0x0003,\r\n    /** Lifetime */\r\n    Lifetime = 0x0004,\r\n    /** Color */\r\n    Color = 0x0005,\r\n    /** ScaledDirection */\r\n    ScaledDirection = 0x0006,\r\n    /** Scale */\r\n    Scale = 0x0007,\r\n    /** AgeGradient */\r\n    AgeGradient = 0x0008,\r\n    /** Angle */\r\n    Angle = 0x0009,\r\n    /** SpriteCellIndex */\r\n    SpriteCellIndex = 0x0010,\r\n    /** SpriteCellStart */\r\n    SpriteCellStart = 0x0011,\r\n    /** SpriteCellEnd */\r\n    SpriteCellEnd = 0x0012,\r\n    /** Initial Color */\r\n    InitialColor = 0x0013,\r\n    /** Color Dead*/\r\n    ColorDead = 0x0014,\r\n    /** Initial Direction */\r\n    InitialDirection = 0x0015,\r\n    /** Color Step */\r\n    ColorStep = 0x0016,\r\n    /** Scaled Color Step */\r\n    ScaledColorStep = 0x0017,\r\n    /** Local Position Updated */\r\n    LocalPositionUpdated = 0x0018,\r\n    /** Size */\r\n    Size = 0x0019,\r\n    /** Direction Scale */\r\n    DirectionScale = 0x0020,\r\n}\r\n","/**\r\n * Enum used to define system values e.g. values automatically provided by the system\r\n */\r\nexport enum NodeParticleSystemSources {\r\n    /** None */\r\n    None = 0,\r\n    /** Time */\r\n    Time = 1,\r\n    /** Delta time */\r\n    Delta = 2,\r\n    /** Emitter */\r\n    Emitter = 3,\r\n    /** Camera position */\r\n    CameraPosition = 4,\r\n}\r\n","import { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\n\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleContextualSources } from \"core/Particles/Node/Enums/nodeParticleContextualSources\";\r\nimport { NodeParticleSystemSources } from \"core/Particles/Node/Enums/nodeParticleSystemSources\";\r\n\r\n/**\r\n * Class used to store node based geometry build state\r\n */\r\nexport class NodeParticleBuildState {\r\n    private _buildPromises = new Array<Promise<void>>();\r\n\r\n    /**\r\n     * Gets the capactity of the particle system to build\r\n     */\r\n    public capacity: number;\r\n\r\n    /**\r\n     * Gets the scene where the particle system is built\r\n     */\r\n    public scene: Scene;\r\n\r\n    /** Gets or sets the build identifier */\r\n    public buildId: number;\r\n\r\n    /** Gets or sets the list of non connected mandatory inputs */\r\n    public notConnectedNonOptionalInputs: NodeParticleConnectionPoint[] = [];\r\n\r\n    /** Gets or sets a boolean indicating that verbose mode is on */\r\n    public verbose: boolean;\r\n\r\n    /**\r\n     * Gets or sets the particle context for contextual data\r\n     */\r\n    public particleContext: Nullable<Particle> = null;\r\n\r\n    /**\r\n     * Gets or sets the system context for contextual data\r\n     */\r\n    public systemContext: Nullable<ThinParticleSystem> = null;\r\n\r\n    /**\r\n     * Gets or sets the index of the gradient to use\r\n     */\r\n    public gradientIndex: number = 0;\r\n    /**\r\n     * Gets or sets next gradient in line\r\n     */\r\n    public nextGradientIndex: number = 0;\r\n    /**\r\n     * Gets or sets the next gradient value\r\n     */\r\n    public nextGradientValue: any;\r\n\r\n    /**\r\n     * Emits errors if any\r\n     */\r\n    public emitErrors() {\r\n        let errorMessage = \"\";\r\n\r\n        for (const notConnectedInput of this.notConnectedNonOptionalInputs) {\r\n            errorMessage += `input ${notConnectedInput.name} from block ${\r\n                notConnectedInput.ownerBlock.name\r\n            }[${notConnectedInput.ownerBlock.getClassName()}] is not connected and is not optional.\\n`;\r\n        }\r\n\r\n        if (errorMessage) {\r\n            // eslint-disable-next-line no-throw-literal\r\n            throw \"Build of Node Particle System Set failed:\\n\" + errorMessage;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Registers an asynchronous operation that must complete before the node particle system is ready.\r\n     * @param promise defines the promise to wait for\r\n     */\r\n    public registerBuildPromise(promise: Promise<void>) {\r\n        this._buildPromises.push(promise);\r\n    }\r\n\r\n    /**\r\n     * Waits for all asynchronous build operations to complete.\r\n     * @returns a promise that resolves when all registered build operations are complete\r\n     */\r\n    public async waitForBuildPromisesAsync(): Promise<void> {\r\n        await Promise.all(this._buildPromises);\r\n    }\r\n\r\n    /**\r\n     * Adapt a value to a target type\r\n     * @param source defines the value to adapt\r\n     * @param targetType defines the target type\r\n     * @returns the adapted value\r\n     */\r\n    adapt(source: NodeParticleConnectionPoint, targetType: NodeParticleBlockConnectionPointTypes) {\r\n        const value = source.getConnectedValue(this) || 0;\r\n\r\n        if (source.type === targetType) {\r\n            return value;\r\n        }\r\n\r\n        switch (targetType) {\r\n            case NodeParticleBlockConnectionPointTypes.Vector2:\r\n                return new Vector2(value, value);\r\n            case NodeParticleBlockConnectionPointTypes.Vector3:\r\n                return new Vector3(value, value, value);\r\n            case NodeParticleBlockConnectionPointTypes.Color4:\r\n                return new Color4(value, value, value, value);\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a contextual source\r\n     * @param source Source of the contextual value\r\n     * @returns the value associated with the source\r\n     */\r\n    public getContextualValue(source: NodeParticleContextualSources) {\r\n        if (!this.particleContext || !this.systemContext) {\r\n            return null;\r\n        }\r\n\r\n        switch (source) {\r\n            case NodeParticleContextualSources.Position:\r\n                return this.particleContext.position;\r\n            case NodeParticleContextualSources.Direction:\r\n                return this.particleContext.direction;\r\n            case NodeParticleContextualSources.DirectionScale:\r\n                return this.particleContext._properties.directionScale;\r\n            case NodeParticleContextualSources.ScaledDirection:\r\n                this.particleContext.direction.scaleToRef(this.particleContext._properties.directionScale, this.particleContext._properties.scaledDirection);\r\n                return this.particleContext._properties.scaledDirection;\r\n            case NodeParticleContextualSources.Color:\r\n                return this.particleContext.color;\r\n            case NodeParticleContextualSources.InitialColor:\r\n                return this.particleContext.initialColor;\r\n            case NodeParticleContextualSources.ColorDead:\r\n                return this.particleContext.colorDead;\r\n            case NodeParticleContextualSources.Age:\r\n                return this.particleContext.age;\r\n            case NodeParticleContextualSources.Lifetime:\r\n                return this.particleContext.lifeTime;\r\n            case NodeParticleContextualSources.Angle:\r\n                return this.particleContext.angle;\r\n            case NodeParticleContextualSources.Scale:\r\n                return this.particleContext.scale;\r\n            case NodeParticleContextualSources.Size:\r\n                return this.particleContext.size;\r\n            case NodeParticleContextualSources.AgeGradient:\r\n                return this.particleContext.age / this.particleContext.lifeTime;\r\n            case NodeParticleContextualSources.SpriteCellEnd:\r\n                return this.systemContext.endSpriteCellID;\r\n            case NodeParticleContextualSources.SpriteCellIndex:\r\n                return this.particleContext.cellIndex;\r\n            case NodeParticleContextualSources.SpriteCellStart:\r\n                return this.systemContext.startSpriteCellID;\r\n            case NodeParticleContextualSources.InitialDirection:\r\n                return this.particleContext._properties.initialDirection;\r\n            case NodeParticleContextualSources.ColorStep:\r\n                return this.particleContext.colorStep;\r\n            case NodeParticleContextualSources.ScaledColorStep:\r\n                this.particleContext.colorStep.scaleToRef(this.systemContext._scaledUpdateSpeed, this.systemContext._scaledColorStep);\r\n                return this.systemContext._scaledColorStep;\r\n            case NodeParticleContextualSources.LocalPositionUpdated:\r\n                this.particleContext.direction.scaleToRef(this.particleContext._properties.directionScale, this.particleContext._properties.scaledDirection);\r\n                this.particleContext._properties.localPosition!.addInPlace(this.particleContext._properties.scaledDirection);\r\n                Vector3.TransformCoordinatesToRef(this.particleContext._properties.localPosition!, this.systemContext._emitterWorldMatrix, this.particleContext.position);\r\n                return this.particleContext.position;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the emitter world matrix\r\n     */\r\n    public get emitterWorldMatrix() {\r\n        if (!this.systemContext) {\r\n            return null;\r\n        }\r\n        return this.systemContext._emitterWorldMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the emitter inverse world matrix\r\n     */\r\n    public get emitterInverseWorldMatrix() {\r\n        if (!this.systemContext) {\r\n            return null;\r\n        }\r\n        return this.systemContext._emitterInverseWorldMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the emitter position\r\n     */\r\n    public get emitterPosition(): Nullable<Vector3> {\r\n        if (!this.systemContext) {\r\n            return null;\r\n        }\r\n\r\n        if (!this.systemContext.emitter) {\r\n            return null;\r\n        }\r\n\r\n        if (this.systemContext.emitter instanceof Vector3) {\r\n            return this.systemContext.emitter;\r\n        }\r\n\r\n        return (<AbstractMesh>this.systemContext.emitter).absolutePosition;\r\n    }\r\n\r\n    /**\r\n     * Gets the value associated with a system source\r\n     * @param source Source of the system value\r\n     * @returns the value associated with the source\r\n     */\r\n    public getSystemValue(source: NodeParticleSystemSources) {\r\n        if (!this.systemContext) {\r\n            return null;\r\n        }\r\n\r\n        switch (source) {\r\n            case NodeParticleSystemSources.Time:\r\n                return this.systemContext._actualFrame;\r\n            case NodeParticleSystemSources.Delta:\r\n                return this.systemContext._scaledUpdateSpeed;\r\n            case NodeParticleSystemSources.Emitter:\r\n                return this.emitterPosition;\r\n            case NodeParticleSystemSources.CameraPosition:\r\n                return this.scene.activeCamera?.globalPosition || Vector3.Zero();\r\n        }\r\n\r\n        return null;\r\n    }\r\n}\r\n","import { type Scene } from \"core/scene\";\r\nimport { type Vector3 } from \"core/Maths/math.vector\";\r\nimport { type SystemBlock } from \"../systemBlock\";\r\nimport { NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ParticleSystem } from \"core/Particles/particleSystem\";\r\n\r\n/**\r\n * @internal\r\n * Tools for managing particle triggers and sub-emitter systems.\r\n */\r\nexport function _TriggerSubEmitter(template: SystemBlock, scene: Scene, location: Vector3): ParticleSystem {\r\n    const newState = new NodeParticleBuildState();\r\n    newState.scene = scene;\r\n    const clone = template.createSystem(newState);\r\n    clone.canStart = () => true; // Allow the cloned system to start\r\n    clone.emitter = location.clone(); // Set the emitter to the particle's position\r\n    clone.disposeOnStop = true; // Clean up the system when it stops\r\n    clone.start();\r\n\r\n    return clone;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { type ParticleSystem } from \"core/Particles/particleSystem.pure\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\n\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { _IsSideEffectImplemented } from \"../../../Misc/devTools\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { BaseParticleSystem } from \"core/Particles/baseParticleSystem.pure\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { _TriggerSubEmitter } from \"core/Particles/Node/Blocks/Triggers/triggerTools\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\ntype CustomShader = {\r\n    shaderPath: { fragmentElement: string };\r\n    shaderOptions: { uniforms: string[]; samplers: string[]; defines: string[] };\r\n};\r\n\r\n/**\r\n * Block used to get a system of particles\r\n */\r\nexport class SystemBlock extends NodeParticleBlock {\r\n    private static _IdCounter = 0;\r\n\r\n    /**\r\n     * Gets or sets the blend mode for the particle system\r\n     */\r\n    @editableInPropertyPage(\"Blend mode\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Blend Mode OneOne\", value: BaseParticleSystem.BLENDMODE_ONEONE },\r\n            { label: \"Blend Mode Standard\", value: BaseParticleSystem.BLENDMODE_STANDARD },\r\n            { label: \"Blend Mode Add\", value: BaseParticleSystem.BLENDMODE_ADD },\r\n            { label: \"Blend Mode Multiply\", value: BaseParticleSystem.BLENDMODE_MULTIPLY },\r\n            { label: \"Blend Mode MultiplyAdd\", value: BaseParticleSystem.BLENDMODE_MULTIPLYADD },\r\n        ],\r\n    })\r\n    public blendMode = BaseParticleSystem.BLENDMODE_ONEONE;\r\n\r\n    /**\r\n     * Gets or sets the epsilon value used for comparison\r\n     */\r\n    @editableInPropertyPage(\"Capacity\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0, max: 10000 })\r\n    public capacity = 1000;\r\n\r\n    /**\r\n     * Gets or sets the manual emit count\r\n     */\r\n    @editableInPropertyPage(\"Manual emit count\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: -1 })\r\n    public manualEmitCount = -1;\r\n\r\n    /**\r\n     * Gets or sets the target stop duration for the particle system\r\n     */\r\n    @editableInPropertyPage(\"Delay start(ms)\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public startDelay = 0;\r\n\r\n    /**\r\n     * Gets or sets the target stop duration for the particle system\r\n     */\r\n    @editableInPropertyPage(\"updateSpeed\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0, max: 0.1 })\r\n    public updateSpeed = 0.0167;\r\n\r\n    /**\r\n     * Gets or sets the number of pre-warm cycles before rendering the particle system\r\n     */\r\n    @editableInPropertyPage(\"Pre-warm cycles\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public preWarmCycles = 0;\r\n\r\n    /**\r\n     * Gets or sets the time step multiplier used for pre-warm\r\n     */\r\n    @editableInPropertyPage(\"Pre-warm step multiplier\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public preWarmStepOffset = 0;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the system is billboard based\r\n     */\r\n    @editableInPropertyPage(\"Is billboard based\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public isBillboardBased = true;\r\n\r\n    /**\r\n     * Gets or sets the billboard mode for the particle system\r\n     */\r\n    @editableInPropertyPage(\"Billboard mode\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Billboard Mode All\", value: Constants.PARTICLES_BILLBOARDMODE_ALL },\r\n            { label: \"Billboard Mode Y\", value: Constants.PARTICLES_BILLBOARDMODE_Y },\r\n            { label: \"Billboard Mode Stretched\", value: Constants.PARTICLES_BILLBOARDMODE_STRETCHED },\r\n            { label: \"Billboard Mode Stretched Local\", value: Constants.PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL },\r\n        ],\r\n    })\r\n    public billBoardMode = Constants.PARTICLES_BILLBOARDMODE_ALL;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the system coordinate space is local or global\r\n     */\r\n    @editableInPropertyPage(\"Is local\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public isLocal = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the system should be disposed when stopped\r\n     */\r\n    @editableInPropertyPage(\"Dispose on stop\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public disposeOnStop = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the system should not start automatically\r\n     */\r\n    @editableInPropertyPage(\"Do no start\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public doNoStart = false;\r\n\r\n    /**\r\n     * Gets or sets the rendering group id for the particle system (0 by default)\r\n     */\r\n    @editableInPropertyPage(\"Rendering group id\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public renderingGroupId = 0;\r\n\r\n    /** @internal */\r\n    public _internalId = SystemBlock._IdCounter++;\r\n\r\n    /**\r\n     * Gets or sets the custom shader configuration used to render the particles.\r\n     * This can be used to set your own shader to render the particle system.\r\n     */\r\n    public customShader: Nullable<CustomShader> = null;\r\n\r\n    /**\r\n     * Gets or sets the emitter for the particle system.\r\n     */\r\n    public emitter: Nullable<AbstractMesh | Vector3> = Vector3.Zero();\r\n\r\n    /**\r\n     * Create a new SystemBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isSystem = true;\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"emitRate\", NodeParticleBlockConnectionPointTypes.Int, true, 10, 0);\r\n        this.registerInput(\"texture\", NodeParticleBlockConnectionPointTypes.Texture);\r\n        this.registerInput(\"translationPivot\", NodeParticleBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"textureMask\", NodeParticleBlockConnectionPointTypes.Color4, true);\r\n        this.registerInput(\"targetStopDuration\", NodeParticleBlockConnectionPointTypes.Float, true, 0, 0);\r\n        this.registerInput(\"onStart\", NodeParticleBlockConnectionPointTypes.System, true);\r\n        this.registerInput(\"onEnd\", NodeParticleBlockConnectionPointTypes.System, true);\r\n        this.registerOutput(\"system\", NodeParticleBlockConnectionPointTypes.System);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SystemBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle input component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the emitRate input component\r\n     */\r\n    public get emitRate(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the texture input component\r\n     */\r\n    public get texture(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the translationPivot input component\r\n     */\r\n    public get translationPivot(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the textureMask input component\r\n     */\r\n    public get textureMask(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the targetStopDuration input component\r\n     */\r\n    public get targetStopDuration(): NodeParticleConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the onStart input component\r\n     */\r\n    public get onStart(): NodeParticleConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the onEnd input component\r\n     */\r\n    public get onEnd(): NodeParticleConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the system output component\r\n     */\r\n    public get system(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block and return a functional particle system\r\n     * @param state defines the building state\r\n     * @returns the built particle system\r\n     */\r\n    public createSystem(state: NodeParticleBuildState): ParticleSystem {\r\n        state.capacity = this.capacity;\r\n        state.buildId = this._buildId++;\r\n\r\n        this.build(state);\r\n\r\n        const particleSystem = this.particle.getConnectedValue(state) as ParticleSystem;\r\n        particleSystem.particleTexture = this.texture.getConnectedValue(state);\r\n        particleSystem.emitRate = this.emitRate.getConnectedValue(state) as number;\r\n        particleSystem.manualEmitCount = this.manualEmitCount;\r\n        particleSystem.updateSpeed = this.updateSpeed;\r\n        particleSystem.preWarmCycles = this.preWarmCycles;\r\n        particleSystem.preWarmStepOffset = this.preWarmStepOffset;\r\n        particleSystem.blendMode = this.blendMode;\r\n        particleSystem.name = this.name;\r\n        particleSystem._targetStopDuration = (this.targetStopDuration.getConnectedValue(state) as number) ?? 0;\r\n        particleSystem.startDelay = this.startDelay;\r\n        particleSystem.isBillboardBased = this.isBillboardBased;\r\n        particleSystem.billboardMode = this.billBoardMode;\r\n        particleSystem.translationPivot = (this.translationPivot.getConnectedValue(state) as Vector2) || Vector2.Zero();\r\n        particleSystem.textureMask = this.textureMask.getConnectedValue(state) ?? new Color4(1, 1, 1, 1);\r\n        particleSystem.isLocal = this.isLocal;\r\n        particleSystem.disposeOnStop = this.disposeOnStop;\r\n        particleSystem.renderingGroupId = this.renderingGroupId;\r\n        if (this.emitter) {\r\n            particleSystem.emitter = this.emitter;\r\n        }\r\n\r\n        // Apply custom shader if defined\r\n        if (this.customShader) {\r\n            const engine = particleSystem.getScene()?.getEngine();\r\n            if (engine && _IsSideEffectImplemented(engine.createEffectForParticles)) {\r\n                const defines: string = this.customShader.shaderOptions.defines.length > 0 ? this.customShader.shaderOptions.defines.join(\"\\n\") : \"\";\r\n                const effect = engine.createEffectForParticles(\r\n                    this.customShader.shaderPath.fragmentElement,\r\n                    this.customShader.shaderOptions.uniforms,\r\n                    this.customShader.shaderOptions.samplers,\r\n                    defines\r\n                );\r\n                particleSystem.setCustomEffect(effect, 0);\r\n                particleSystem.customShader = this.customShader;\r\n            }\r\n        }\r\n\r\n        // The emit rate can vary if it is connected to another block like a gradient\r\n        particleSystem._calculateEmitRate = () => {\r\n            state.systemContext = particleSystem;\r\n            return this.emitRate.getConnectedValue(state) as number;\r\n        };\r\n\r\n        this.system._storedValue = this;\r\n\r\n        particleSystem.canStart = () => {\r\n            return !this.doNoStart;\r\n        };\r\n\r\n        particleSystem.onStartedObservable.add((system) => {\r\n            // Triggers\r\n            const onStartSystem = this.onStart.getConnectedValue(state);\r\n            if (onStartSystem) {\r\n                system.onStartedObservable.addOnce(() => {\r\n                    state.systemContext = particleSystem;\r\n                    const clone = _TriggerSubEmitter(onStartSystem, state.scene, state.emitterPosition!);\r\n\r\n                    this.onDisposeObservable.addOnce(() => {\r\n                        // Clean up the cloned system when the original system is disposed\r\n                        clone.dispose();\r\n                    });\r\n                });\r\n            }\r\n\r\n            const onEndSystem = this.onEnd.getConnectedValue(state);\r\n            if (onEndSystem) {\r\n                system.onStoppedObservable.addOnce(() => {\r\n                    state.systemContext = particleSystem;\r\n                    const clone = _TriggerSubEmitter(onEndSystem, state.scene, state.emitterPosition!);\r\n\r\n                    this.onDisposeObservable.addOnce(() => {\r\n                        // Clean up the cloned system when the original system is disposed\r\n                        clone.dispose();\r\n                    });\r\n                });\r\n            }\r\n        });\r\n\r\n        this.onDisposeObservable.addOnce(() => {\r\n            particleSystem.dispose();\r\n        });\r\n\r\n        // Return\r\n        return particleSystem;\r\n    }\r\n\r\n    /**\r\n     * Serializes the system block\r\n     * @returns The serialized object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.capacity = this.capacity;\r\n        serializationObject.manualEmitCount = this.manualEmitCount;\r\n        serializationObject.blendMode = this.blendMode;\r\n        serializationObject.updateSpeed = this.updateSpeed;\r\n        serializationObject.preWarmCycles = this.preWarmCycles;\r\n        serializationObject.preWarmStepOffset = this.preWarmStepOffset;\r\n        serializationObject.isBillboardBased = this.isBillboardBased;\r\n        serializationObject.billBoardMode = this.billBoardMode;\r\n        serializationObject.isLocal = this.isLocal;\r\n        serializationObject.disposeOnStop = this.disposeOnStop;\r\n        serializationObject.doNoStart = this.doNoStart;\r\n        serializationObject.renderingGroupId = this.renderingGroupId;\r\n        serializationObject.startDelay = this.startDelay;\r\n        serializationObject.customShader = this.customShader;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the system block\r\n     * @param serializationObject The serialized system\r\n     */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.capacity = serializationObject.capacity;\r\n        this.manualEmitCount = serializationObject.manualEmitCount ?? -1;\r\n        this.updateSpeed = serializationObject.updateSpeed ?? 0.0167;\r\n        this.preWarmCycles = serializationObject.preWarmCycles ?? 0;\r\n        this.preWarmStepOffset = serializationObject.preWarmStepOffset ?? 0;\r\n        this.isBillboardBased = serializationObject.isBillboardBased ?? true;\r\n        this.billBoardMode = serializationObject.billBoardMode ?? Constants.PARTICLES_BILLBOARDMODE_ALL;\r\n        this.isLocal = serializationObject.isLocal ?? false;\r\n        this.disposeOnStop = serializationObject.disposeOnStop ?? false;\r\n        this.doNoStart = !!serializationObject.doNoStart;\r\n        this.renderingGroupId = serializationObject.renderingGroupId ?? 0;\r\n\r\n        if (serializationObject.emitRate !== undefined) {\r\n            this.emitRate.value = serializationObject.emitRate;\r\n        }\r\n\r\n        if (serializationObject.blendMode !== undefined) {\r\n            this.blendMode = serializationObject.blendMode;\r\n        }\r\n\r\n        if (serializationObject.startDelay !== undefined) {\r\n            this.startDelay = serializationObject.startDelay;\r\n        }\r\n\r\n        if (serializationObject.customShader !== undefined) {\r\n            this.customShader = serializationObject.customShader;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for systemBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSystemBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SystemBlock\", SystemBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Observable } from \"../../../Misc/observable.pure\";\r\nimport { GetClass, RegisterClass } from \"../../../Misc/typeStore\";\r\nimport { Matrix, Vector2, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { NodeParticleContextualSources } from \"../Enums/nodeParticleContextualSources\";\r\nimport { NodeParticleSystemSources } from \"../Enums/nodeParticleSystemSources\";\r\n\r\n/**\r\n * Block used to expose an input value\r\n */\r\nexport class ParticleInputBlock extends NodeParticleBlock {\r\n    private _storedValue: any;\r\n    private _valueCallback: () => any;\r\n    private _type: NodeParticleBlockConnectionPointTypes = NodeParticleBlockConnectionPointTypes.Undefined;\r\n\r\n    /** Gets or set a value used to limit the range of float values */\r\n    public min: number = 0;\r\n\r\n    /** Gets or set a value used to limit the range of float values */\r\n    public max: number = 0;\r\n\r\n    /** Gets or sets the group to use to display this block in the Inspector */\r\n    public groupInInspector = \"\";\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this input is displayed in the Inspector\r\n     */\r\n    public displayInInspector = true;\r\n\r\n    /** Gets an observable raised when the value is changed */\r\n    public onValueChangedObservable = new Observable<ParticleInputBlock>();\r\n\r\n    /**\r\n     * Gets or sets the connection point type (default is float)\r\n     */\r\n    public get type(): NodeParticleBlockConnectionPointTypes {\r\n        if (this._type === NodeParticleBlockConnectionPointTypes.AutoDetect) {\r\n            if (this.value != null) {\r\n                if (!isNaN(this.value)) {\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Float;\r\n                    return this._type;\r\n                }\r\n\r\n                switch (this.value.getClassName()) {\r\n                    case \"Vector2\":\r\n                        this._type = NodeParticleBlockConnectionPointTypes.Vector2;\r\n                        return this._type;\r\n                    case \"Vector3\":\r\n                        this._type = NodeParticleBlockConnectionPointTypes.Vector3;\r\n                        return this._type;\r\n                    case \"Color4\":\r\n                        this._type = NodeParticleBlockConnectionPointTypes.Color4;\r\n                        return this._type;\r\n                    case \"Matrix\":\r\n                        this._type = NodeParticleBlockConnectionPointTypes.Matrix;\r\n                        return this._type;\r\n                }\r\n            }\r\n        }\r\n\r\n        return this._type;\r\n    }\r\n\r\n    /** @internal */\r\n    private _systemSource: NodeParticleSystemSources = NodeParticleSystemSources.None;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the current connection point is a system source\r\n     */\r\n    public get isSystemSource(): boolean {\r\n        return this._contextualSource === NodeParticleContextualSources.None && this._systemSource !== NodeParticleSystemSources.None;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the system source used by this input block\r\n     */\r\n    public get systemSource(): NodeParticleSystemSources {\r\n        return this._systemSource;\r\n    }\r\n\r\n    public set systemSource(value: NodeParticleSystemSources) {\r\n        this._systemSource = value;\r\n\r\n        if (value !== NodeParticleSystemSources.None) {\r\n            this._contextualSource = NodeParticleContextualSources.None;\r\n            this._type = NodeParticleBlockConnectionPointTypes.Float;\r\n\r\n            switch (value) {\r\n                case NodeParticleSystemSources.Time:\r\n                case NodeParticleSystemSources.Delta:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Float;\r\n                    break;\r\n                case NodeParticleSystemSources.Emitter:\r\n                case NodeParticleSystemSources.CameraPosition:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Vector3;\r\n                    break;\r\n            }\r\n\r\n            if (this.output) {\r\n                this.output.type = this._type;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _contextualSource = NodeParticleContextualSources.None;\r\n    /**\r\n     * Gets a boolean indicating that the current connection point is a contextual value\r\n     */\r\n    public get isContextual(): boolean {\r\n        return this._contextualSource !== NodeParticleContextualSources.None;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the current contextual value\r\n     */\r\n    public get contextualValue(): NodeParticleContextualSources {\r\n        return this._contextualSource;\r\n    }\r\n\r\n    public set contextualValue(value: NodeParticleContextualSources) {\r\n        this._contextualSource = value;\r\n\r\n        if (value !== NodeParticleContextualSources.None) {\r\n            this._systemSource = NodeParticleSystemSources.None;\r\n\r\n            switch (value) {\r\n                case NodeParticleContextualSources.Scale:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Vector2;\r\n                    break;\r\n                case NodeParticleContextualSources.Position:\r\n                case NodeParticleContextualSources.Direction:\r\n                case NodeParticleContextualSources.ScaledDirection:\r\n                case NodeParticleContextualSources.InitialDirection:\r\n                case NodeParticleContextualSources.LocalPositionUpdated:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Vector3;\r\n                    break;\r\n                case NodeParticleContextualSources.Color:\r\n                case NodeParticleContextualSources.InitialColor:\r\n                case NodeParticleContextualSources.ColorDead:\r\n                case NodeParticleContextualSources.ColorStep:\r\n                case NodeParticleContextualSources.ScaledColorStep:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Color4;\r\n                    break;\r\n                case NodeParticleContextualSources.Age:\r\n                case NodeParticleContextualSources.Lifetime:\r\n                case NodeParticleContextualSources.Angle:\r\n                case NodeParticleContextualSources.AgeGradient:\r\n                case NodeParticleContextualSources.Size:\r\n                case NodeParticleContextualSources.DirectionScale:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Float;\r\n                    break;\r\n                case NodeParticleContextualSources.SpriteCellEnd:\r\n                case NodeParticleContextualSources.SpriteCellStart:\r\n                case NodeParticleContextualSources.SpriteCellIndex:\r\n                    this._type = NodeParticleBlockConnectionPointTypes.Int;\r\n                    break;\r\n            }\r\n\r\n            if (this.output) {\r\n                this.output.type = this._type;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Creates a new InputBlock\r\n     * @param name defines the block name\r\n     * @param type defines the type of the input (can be set to NodeParticleBlockConnectionPointTypes.AutoDetect)\r\n     */\r\n    public constructor(name: string, type: NodeParticleBlockConnectionPointTypes = NodeParticleBlockConnectionPointTypes.AutoDetect) {\r\n        super(name);\r\n\r\n        this._type = type;\r\n        this._isInput = true;\r\n        this._storedValue = null;\r\n\r\n        this.setDefaultValue();\r\n\r\n        this.registerOutput(\"output\", type);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the value of that point.\r\n     * Please note that this value will be ignored if valueCallback is defined\r\n     */\r\n    public get value(): any {\r\n        return this._storedValue;\r\n    }\r\n\r\n    public set value(value: any) {\r\n        if (this.type === NodeParticleBlockConnectionPointTypes.Float) {\r\n            if (this.min !== this.max) {\r\n                value = Math.max(this.min, value);\r\n                value = Math.min(this.max, value);\r\n            }\r\n        }\r\n\r\n        this._storedValue = value;\r\n\r\n        this.onValueChangedObservable.notifyObservers(this);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a callback used to get the value of that point.\r\n     * Please note that setting this value will force the connection point to ignore the value property\r\n     */\r\n    public get valueCallback(): () => any {\r\n        return this._valueCallback;\r\n    }\r\n\r\n    public set valueCallback(value: () => any) {\r\n        this._valueCallback = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleInputBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Set the input block to its default value (based on its type)\r\n     */\r\n    public setDefaultValue() {\r\n        switch (this.type) {\r\n            case NodeParticleBlockConnectionPointTypes.Int:\r\n            case NodeParticleBlockConnectionPointTypes.Float:\r\n                this.value = 0;\r\n                break;\r\n            case NodeParticleBlockConnectionPointTypes.Vector2:\r\n                this.value = Vector2.Zero();\r\n                break;\r\n            case NodeParticleBlockConnectionPointTypes.Vector3:\r\n                this.value = Vector3.Zero();\r\n                break;\r\n            case NodeParticleBlockConnectionPointTypes.Color4:\r\n                this.value = new Color4(1, 1, 1, 1);\r\n                break;\r\n            case NodeParticleBlockConnectionPointTypes.Matrix:\r\n                this.value = Matrix.Identity();\r\n                break;\r\n        }\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        super._build(state);\r\n\r\n        if (this.isSystemSource) {\r\n            this.output._storedValue = null;\r\n            this.output._storedFunction = (state) => {\r\n                return state.getSystemValue(this._systemSource);\r\n            };\r\n        } else if (this.isContextual) {\r\n            this.output._storedValue = null;\r\n            this.output._storedFunction = (state) => {\r\n                return state.getContextualValue(this._contextualSource);\r\n            };\r\n        } else {\r\n            this.output._storedValue = this.value;\r\n            // As a function to let the user dynamically change the value at runtime\r\n            this.output._storedFunction = () => {\r\n                return this.value;\r\n            };\r\n        }\r\n    }\r\n\r\n    public override dispose() {\r\n        this.onValueChangedObservable.clear();\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.type = this.type;\r\n        serializationObject.contextualValue = this.contextualValue;\r\n        serializationObject.systemSource = this.systemSource;\r\n        serializationObject.min = this.min;\r\n        serializationObject.max = this.max;\r\n        serializationObject.groupInInspector = this.groupInInspector;\r\n        serializationObject.displayInInspector = this.displayInInspector;\r\n\r\n        if (this._storedValue !== null && !this.isContextual && !this.isSystemSource) {\r\n            if (this._storedValue.asArray) {\r\n                serializationObject.valueType = \"BABYLON.\" + this._storedValue.getClassName();\r\n                serializationObject.value = this._storedValue.asArray();\r\n            } else {\r\n                serializationObject.valueType = \"number\";\r\n                serializationObject.value = this._storedValue;\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this._type = serializationObject.type;\r\n        this.contextualValue = serializationObject.contextualValue;\r\n        this.systemSource = serializationObject.systemSource || NodeParticleSystemSources.None;\r\n\r\n        this.min = serializationObject.min || 0;\r\n        this.max = serializationObject.max || 0;\r\n        this.groupInInspector = serializationObject.groupInInspector || \"\";\r\n        if (serializationObject.displayInInspector !== undefined) {\r\n            this.displayInInspector = serializationObject.displayInInspector;\r\n        }\r\n\r\n        if (!serializationObject.valueType) {\r\n            return;\r\n        }\r\n\r\n        if (serializationObject.valueType === \"number\") {\r\n            this._storedValue = serializationObject.value;\r\n        } else {\r\n            const valueType = GetClass(serializationObject.valueType);\r\n\r\n            if (valueType) {\r\n                this._storedValue = valueType.FromArray(serializationObject.value);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleInputBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleInputBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleInputBlock\", ParticleInputBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type BaseTexture } from \"../../../Materials/Textures/baseTexture.pure\";\r\nimport { type ProceduralTexture } from \"../../../Materials/Textures/Procedurals/proceduralTexture.pure\";\r\n\r\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { TextureTools } from \"core/Misc/textureTools\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Interface used to define texture data\r\n */\r\nexport interface INodeParticleTextureData {\r\n    /** Width of the texture in pixels */\r\n    width: number;\r\n    /** Height of the texture in pixels */\r\n    height: number;\r\n    /** RGBA pixel data */\r\n    data: Uint8ClampedArray;\r\n}\r\n\r\n/**\r\n * Block used to provide a texture for particles in a particle system\r\n */\r\nexport class ParticleTextureSourceBlock extends NodeParticleBlock {\r\n    private _url: string = \"\";\r\n    private _textureDataUrl: string = \"\";\r\n    private _sourceTexture: Nullable<BaseTexture> = null;\r\n    private _cachedData: Nullable<INodeParticleTextureData> = null;\r\n    private _clonedTextures: BaseTexture[] = [];\r\n\r\n    /**\r\n     * Gets or sets the strenght of the flow map effect\r\n     */\r\n    public invertY = true;\r\n\r\n    /**\r\n     * Indicates if the texture data should be serialized as a base64 string.\r\n     */\r\n    public serializedCachedData: boolean = false;\r\n\r\n    /**\r\n     * Gets or sets the URL of the texture to be used by this block.\r\n     */\r\n    public get url(): string {\r\n        return this._url;\r\n    }\r\n\r\n    public set url(value: string) {\r\n        if (this._url === value) {\r\n            return;\r\n        }\r\n        this._cachedData = null;\r\n        this._url = value;\r\n        this._textureDataUrl = \"\";\r\n        this._sourceTexture = null;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the data URL of the texture to be used by this block.\r\n     * This is a base64 encoded string representing the texture data.\r\n     */\r\n    public get textureDataUrl(): string {\r\n        return this._textureDataUrl;\r\n    }\r\n\r\n    public set textureDataUrl(value: string) {\r\n        if (this._textureDataUrl === value) {\r\n            return;\r\n        }\r\n\r\n        this._cachedData = null;\r\n        this._textureDataUrl = value;\r\n        this._url = \"\";\r\n        this._sourceTexture = null;\r\n    }\r\n\r\n    /**\r\n     * Gets the texture directly set on this block.\r\n     * This value will not be serialized.\r\n     */\r\n    public get sourceTexture(): Nullable<BaseTexture> {\r\n        return this._sourceTexture;\r\n    }\r\n\r\n    /**\r\n     * Directly sets the texture to be used by this block.\r\n     * This value will not be serialized.\r\n     */\r\n    public set sourceTexture(value: Nullable<BaseTexture>) {\r\n        if (this._sourceTexture === value) {\r\n            return;\r\n        }\r\n        this._cachedData = null;\r\n        this._sourceTexture = value;\r\n        this._url = (value as Texture).url || \"\";\r\n        this._textureDataUrl = \"\";\r\n    }\r\n\r\n    /**\r\n     * Gets the texture set on this block.\r\n     * This value will not be serialized.\r\n     */\r\n    public get texture(): Nullable<BaseTexture> {\r\n        return this.sourceTexture;\r\n    }\r\n\r\n    /**\r\n     * Sets the texture to be used by this block.\r\n     * This value will not be serialized.\r\n     */\r\n    public set texture(value: Nullable<BaseTexture>) {\r\n        this.sourceTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Create a new ParticleTextureSourceBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerOutput(\"texture\", NodeParticleBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleTextureSourceBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the texture output component\r\n     */\r\n    public get textureOutput(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the texture content as a promise\r\n     * @returns a promise that resolves to the texture content, including width, height, and pixel data\r\n     */\r\n    async extractTextureContentAsync() {\r\n        if (!this.textureOutput._storedValue && !this._sourceTexture) {\r\n            return null;\r\n        }\r\n\r\n        if (this._cachedData) {\r\n            return this._cachedData;\r\n        }\r\n\r\n        const texture = this.textureOutput._storedValue || this._sourceTexture;\r\n        return await new Promise<\r\n            Nullable<{\r\n                width: number;\r\n                height: number;\r\n                data: Uint8ClampedArray;\r\n            }>\r\n        >((resolve, reject) => {\r\n            const extractProceduralTextureContentAsync = async (proceduralTexture: ProceduralTexture) => {\r\n                if (!proceduralTexture.isReady()) {\r\n                    const effect = proceduralTexture.getEffect();\r\n                    await new Promise<boolean>((resolveReady) => {\r\n                        let settled = false;\r\n                        let errorObserver: Nullable<{ remove: () => void }> = null;\r\n                        const settle = (ready: boolean) => {\r\n                            if (settled) {\r\n                                return;\r\n                            }\r\n                            settled = true;\r\n                            errorObserver?.remove();\r\n                            resolveReady(ready);\r\n                        };\r\n                        errorObserver = effect.onErrorObservable.add(() => {\r\n                            settle(false);\r\n                        });\r\n                        effect.executeWhenCompiled(() => {\r\n                            settle(true);\r\n                        });\r\n                    });\r\n                }\r\n\r\n                if (!proceduralTexture.isReady()) {\r\n                    return null;\r\n                }\r\n\r\n                proceduralTexture.render();\r\n                const data = await proceduralTexture.getContent();\r\n                if (!data) {\r\n                    return null;\r\n                }\r\n\r\n                const size = proceduralTexture.getSize();\r\n                return {\r\n                    width: size.width,\r\n                    height: size.height,\r\n                    data: new Uint8ClampedArray(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)),\r\n                };\r\n            };\r\n\r\n            if (!texture.isReady()) {\r\n                if (texture.getContent) {\r\n                    void (async () => {\r\n                        try {\r\n                            this._cachedData = await extractProceduralTextureContentAsync(texture as ProceduralTexture);\r\n                            resolve(this._cachedData);\r\n                        } catch (e) {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            reject(e);\r\n                        }\r\n                    })();\r\n                    return;\r\n                }\r\n\r\n                let settled = false;\r\n                let loadObserver: Nullable<{ remove: () => void }> = null;\r\n                let internalErrorObserver: Nullable<{ remove: () => void }> = null;\r\n                let textureErrorObserver: Nullable<{ remove: () => void }> = null;\r\n\r\n                const cleanup = () => {\r\n                    loadObserver?.remove();\r\n                    internalErrorObserver?.remove();\r\n                    textureErrorObserver?.remove();\r\n                };\r\n\r\n                const settle = (textureContent: Nullable<INodeParticleTextureData>) => {\r\n                    if (settled) {\r\n                        return;\r\n                    }\r\n                    settled = true;\r\n                    cleanup();\r\n                    resolve(textureContent);\r\n                };\r\n\r\n                const fail = (error: any) => {\r\n                    if (settled) {\r\n                        return;\r\n                    }\r\n                    settled = true;\r\n                    cleanup();\r\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                    reject(error);\r\n                };\r\n\r\n                if (texture.loadingError) {\r\n                    settle(null);\r\n                    return;\r\n                }\r\n\r\n                const loadObservable = texture.onLoadObservable;\r\n                if (!loadObservable) {\r\n                    settle(null);\r\n                    return;\r\n                }\r\n\r\n                loadObserver = loadObservable.addOnce(async () => {\r\n                    try {\r\n                        this._cachedData = await this.extractTextureContentAsync();\r\n                        settle(this._cachedData);\r\n                    } catch (e) {\r\n                        fail(e);\r\n                    }\r\n                });\r\n\r\n                internalErrorObserver =\r\n                    texture.getInternalTexture()?.onErrorObservable.addOnce(() => {\r\n                        settle(null);\r\n                    }) ?? null;\r\n\r\n                textureErrorObserver = Texture.OnTextureLoadErrorObservable.add((erroredTexture) => {\r\n                    if (erroredTexture === texture) {\r\n                        settle(null);\r\n                    }\r\n                });\r\n\r\n                if (texture.loadingError) {\r\n                    settle(null);\r\n                    return;\r\n                }\r\n\r\n                if (texture.isReady()) {\r\n                    void (async () => {\r\n                        try {\r\n                            this._cachedData = await this.extractTextureContentAsync();\r\n                            settle(this._cachedData);\r\n                        } catch (e) {\r\n                            fail(e);\r\n                        }\r\n                    })();\r\n                }\r\n                return;\r\n            }\r\n            const size = texture.getSize();\r\n            if (texture.getContent) {\r\n                extractProceduralTextureContentAsync(texture as ProceduralTexture)\r\n                    // eslint-disable-next-line github/no-then\r\n                    ?.then((data) => {\r\n                        this._cachedData = data;\r\n                        resolve(this._cachedData);\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch(reject);\r\n            } else {\r\n                TextureTools.GetTextureDataAsync(texture, size.width, size.height)\r\n                    // eslint-disable-next-line github/no-then\r\n                    .then((data) => {\r\n                        this._cachedData = {\r\n                            width: size.width,\r\n                            height: size.height,\r\n                            data: new Uint8ClampedArray(data),\r\n                        };\r\n                        texture.dispose();\r\n                        resolve(this._cachedData);\r\n                    })\r\n                    // eslint-disable-next-line github/no-then\r\n                    .catch(reject);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        if (this._sourceTexture) {\r\n            // The same NodeParticleSystemSet can be built into multiple scenes/engines\r\n            // (original system scene, editor preview scene).\r\n            // Textures are engine-specific, so we need to handle cross-engine cases.\r\n            const sourceScene = this._sourceTexture.getScene?.();\r\n            const sourceEngine = sourceScene?.getEngine?.();\r\n            const targetEngine = state.scene.getEngine();\r\n\r\n            if (sourceEngine && sourceEngine !== targetEngine) {\r\n                // Cross-engine: recreate texture from URL if available, preserving invertY\r\n                const url = (this._sourceTexture as Texture).url || this._url;\r\n                if (url) {\r\n                    const invertY = (this._sourceTexture as Texture).invertY ?? this.invertY;\r\n                    const tex = new Texture(url, state.scene, undefined, invertY);\r\n                    this._copyTextureProperties(this._sourceTexture, tex);\r\n                    this._clonedTextures.push(tex);\r\n                    this.textureOutput._storedValue = tex;\r\n                    return;\r\n                }\r\n                // No URL available - use the source texture directly as fallback\r\n                // This may not render correctly but avoids breaking completely\r\n                this.textureOutput._storedValue = this._sourceTexture;\r\n                return;\r\n            }\r\n\r\n            // Same engine: clone works correctly and preserves all properties\r\n            const cloned = this._sourceTexture.clone();\r\n            if (cloned) {\r\n                this._clonedTextures.push(cloned);\r\n                this.textureOutput._storedValue = cloned;\r\n            } else {\r\n                this.textureOutput._storedValue = this._sourceTexture;\r\n            }\r\n            return;\r\n        }\r\n\r\n        if (!this._textureDataUrl && !this._url) {\r\n            this.textureOutput._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        if (this._textureDataUrl) {\r\n            const tex = new Texture(this._textureDataUrl, state.scene, undefined, this.invertY);\r\n            this._clonedTextures.push(tex);\r\n            this.textureOutput._storedValue = tex;\r\n            return;\r\n        }\r\n\r\n        const tex = new Texture(this._url, state.scene, undefined, this.invertY);\r\n        this._clonedTextures.push(tex);\r\n        this.textureOutput._storedValue = tex;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block\r\n     * @returns the serialization object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.url = this.url;\r\n        serializationObject.serializedCachedData = this.serializedCachedData;\r\n        serializationObject.invertY = this.invertY;\r\n\r\n        if (this.serializedCachedData) {\r\n            serializationObject.textureDataUrl = this.textureDataUrl;\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes this block from a serialization object\r\n     * @param serializationObject the serialization object\r\n     */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.url = serializationObject.url;\r\n        this.serializedCachedData = !!serializationObject.serializedCachedData;\r\n        this.invertY = !!serializationObject.invertY;\r\n\r\n        if (serializationObject.textureDataUrl) {\r\n            this.textureDataUrl = serializationObject.textureDataUrl;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the block and its associated resources\r\n     */\r\n    public override dispose(): void {\r\n        // Dispose all cloned textures we created\r\n        for (const tex of this._clonedTextures) {\r\n            tex.dispose();\r\n        }\r\n        this._clonedTextures = [];\r\n        this.textureOutput._storedValue = null;\r\n        // Never dispose _sourceTexture - it's owned by the caller\r\n        super.dispose();\r\n    }\r\n\r\n    /**\r\n     * Copies texture properties from source to target texture\r\n     * @param source - The source texture to copy properties from\r\n     * @param target - The target texture to copy properties to\r\n     */\r\n    private _copyTextureProperties(source: BaseTexture, target: BaseTexture): void {\r\n        // BaseTexture properties\r\n        target.hasAlpha = source.hasAlpha;\r\n        target.level = source.level;\r\n        target.coordinatesIndex = source.coordinatesIndex;\r\n        target.coordinatesMode = source.coordinatesMode;\r\n        target.wrapU = source.wrapU;\r\n        target.wrapV = source.wrapV;\r\n        target.wrapR = source.wrapR;\r\n        target.anisotropicFilteringLevel = source.anisotropicFilteringLevel;\r\n\r\n        // Texture-specific properties (if both are Texture instances)\r\n        const sourceTexture = source as Texture;\r\n        const targetTexture = target as Texture;\r\n        if (sourceTexture.uOffset !== undefined && targetTexture.uOffset !== undefined) {\r\n            targetTexture.uOffset = sourceTexture.uOffset;\r\n            targetTexture.vOffset = sourceTexture.vOffset;\r\n            targetTexture.uScale = sourceTexture.uScale;\r\n            targetTexture.vScale = sourceTexture.vScale;\r\n            targetTexture.uAng = sourceTexture.uAng;\r\n            targetTexture.vAng = sourceTexture.vAng;\r\n            targetTexture.wAng = sourceTexture.wAng;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleSourceTextureBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleSourceTextureBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleTextureSourceBlock\", ParticleTextureSourceBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { type Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the position of a particle\r\n */\r\nexport class UpdatePositionBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateDirectionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"position\", NodeParticleBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the position input component\r\n     */\r\n    public get position(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdatePositionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.position.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processPosition = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.position.copyFrom(this.position.getConnectedValue(state) as Vector3);\r\n        };\r\n\r\n        const positionProcessing = {\r\n            process: processPosition,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(positionProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = positionProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updatePositionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdatePositionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdatePositionBlock\", UpdatePositionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Math block\r\n */\r\nexport enum ParticleMathBlockOperations {\r\n    /** Add */\r\n    Add,\r\n    /** Subtract */\r\n    Subtract,\r\n    /** Multiply */\r\n    Multiply,\r\n    /** Divide */\r\n    Divide,\r\n    /** Max */\r\n    Max,\r\n    /** Min */\r\n    Min,\r\n}\r\n\r\n/**\r\n * Block used to apply math functions\r\n */\r\nexport class ParticleMathBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Add\", value: ParticleMathBlockOperations.Add },\r\n            { label: \"Subtract\", value: ParticleMathBlockOperations.Subtract },\r\n            { label: \"Multiply\", value: ParticleMathBlockOperations.Multiply },\r\n            { label: \"Divide\", value: ParticleMathBlockOperations.Divide },\r\n            { label: \"Max\", value: ParticleMathBlockOperations.Max },\r\n            { label: \"Min\", value: ParticleMathBlockOperations.Min },\r\n        ],\r\n    })\r\n    public operation = ParticleMathBlockOperations.Add;\r\n\r\n    private readonly _connectionObservers: Observer<NodeParticleConnectionPoint>[];\r\n\r\n    /**\r\n     * Create a new ParticleMathBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        const excludedConnectionPointTypes = [\r\n            NodeParticleBlockConnectionPointTypes.Matrix,\r\n            NodeParticleBlockConnectionPointTypes.Particle,\r\n            NodeParticleBlockConnectionPointTypes.Texture,\r\n            NodeParticleBlockConnectionPointTypes.System,\r\n            NodeParticleBlockConnectionPointTypes.FloatGradient,\r\n            NodeParticleBlockConnectionPointTypes.Color4Gradient,\r\n            NodeParticleBlockConnectionPointTypes.Vector2Gradient,\r\n            NodeParticleBlockConnectionPointTypes.Vector3Gradient,\r\n        ] as const;\r\n\r\n        this.left.excludedConnectionPointTypes.push(...excludedConnectionPointTypes);\r\n        this.right.excludedConnectionPointTypes.push(...excludedConnectionPointTypes);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._connectionObservers = [\r\n            this.left.onConnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.left.onDisconnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onConnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onDisconnectionObservable.add(() => this._updateInputOutputTypes()),\r\n        ];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleMathBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left input component\r\n     */\r\n    public get left(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right input component\r\n     */\r\n    public get right(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        let func: (state: NodeParticleBuildState) => any;\r\n        const left = this.left;\r\n        const right = this.right;\r\n\r\n        if (!left.isConnected || !right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const leftIsScalar = left.type === NodeParticleBlockConnectionPointTypes.Float || left.type === NodeParticleBlockConnectionPointTypes.Int;\r\n        const rightIsScalar = right.type === NodeParticleBlockConnectionPointTypes.Float || right.type === NodeParticleBlockConnectionPointTypes.Int;\r\n\r\n        // If both input types are scalars, then this is a scalar operation.\r\n        const isScalar = leftIsScalar && rightIsScalar;\r\n\r\n        switch (this.operation) {\r\n            case ParticleMathBlockOperations.Add: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) + right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).add(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).add(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case ParticleMathBlockOperations.Subtract: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) - right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).subtract(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).subtract(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case ParticleMathBlockOperations.Multiply: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) * right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).multiply(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).multiply(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case ParticleMathBlockOperations.Divide: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state) / right.getConnectedValue(state);\r\n                    };\r\n                } else if (leftIsScalar) {\r\n                    func = (state) => {\r\n                        return state.adapt(left, right.type).divide(right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    func = (state) => {\r\n                        return left.getConnectedValue(state).divide(state.adapt(right, left.type));\r\n                    };\r\n                }\r\n                break;\r\n            }\r\n            case ParticleMathBlockOperations.Min: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return Math.min(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    const [vector, scalar] = leftIsScalar ? [right, left] : [left, right];\r\n\r\n                    switch (vector.type) {\r\n                        case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                            func = (state) => {\r\n                                return Vector2.Minimize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                            func = (state) => {\r\n                                return Vector3.Minimize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                            func = (state) => {\r\n                                const other = vector.getConnectedValue(state);\r\n                                const { r, g, b, a } = state.adapt(scalar, vector.type);\r\n\r\n                                return new Color4(Math.min(other.r, r), Math.min(other.g, g), Math.min(other.b, b), Math.min(other.a, a));\r\n                            };\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n            case ParticleMathBlockOperations.Max: {\r\n                if (isScalar) {\r\n                    func = (state) => {\r\n                        return Math.max(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                    };\r\n                } else {\r\n                    const [vector, scalar] = leftIsScalar ? [right, left] : [left, right];\r\n\r\n                    switch (vector.type) {\r\n                        case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                            func = (state) => {\r\n                                return Vector2.Maximize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                            func = (state) => {\r\n                                return Vector3.Maximize(vector.getConnectedValue(state), state.adapt(scalar, vector.type));\r\n                            };\r\n                            break;\r\n                        }\r\n                        case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                            func = (state) => {\r\n                                const other = vector.getConnectedValue(state);\r\n                                const { r, g, b, a } = state.adapt(scalar, vector.type);\r\n\r\n                                return new Color4(Math.max(other.r, r), Math.max(other.g, g), Math.max(other.b, b), Math.max(other.a, a));\r\n                            };\r\n                            break;\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            if (left.type === NodeParticleBlockConnectionPointTypes.Int) {\r\n                return func(state) | 0;\r\n            }\r\n            return func(state);\r\n        };\r\n    }\r\n\r\n    private _updateInputOutputTypes() {\r\n        // First update the output type with the initial assumption that we'll base it on the left input.\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        if (this.left.isConnected && this.right.isConnected) {\r\n            // Both inputs are connected, so we need to determine the output type based on the input types.\r\n            if (\r\n                this.left.type === NodeParticleBlockConnectionPointTypes.Int ||\r\n                (this.left.type === NodeParticleBlockConnectionPointTypes.Float && this.right.type !== NodeParticleBlockConnectionPointTypes.Int)\r\n            ) {\r\n                this.output._typeConnectionSource = this.right;\r\n            }\r\n        } else if (this.left.isConnected !== this.right.isConnected) {\r\n            // Only one input is connected, so we need to determine the output type based on the connected input.\r\n            this.output._typeConnectionSource = this.left.isConnected ? this.left : this.right;\r\n        }\r\n\r\n        // Next update the accepted connection point types for the inputs based on the current input connection state.\r\n        if (this.left.isConnected || this.right.isConnected) {\r\n            for (const [first, second] of [\r\n                [this.left, this.right],\r\n                [this.right, this.left],\r\n            ]) {\r\n                // Always allow Ints and Floats.\r\n                first.acceptedConnectionPointTypes = [NodeParticleBlockConnectionPointTypes.Int, NodeParticleBlockConnectionPointTypes.Float];\r\n\r\n                if (second.isConnected) {\r\n                    // The same types as the connected input are always allowed.\r\n                    first.acceptedConnectionPointTypes.push(second.type);\r\n\r\n                    // If the other input is a scalar, then we also allow Vector types.\r\n                    if (second.type === NodeParticleBlockConnectionPointTypes.Int || second.type === NodeParticleBlockConnectionPointTypes.Float) {\r\n                        first.acceptedConnectionPointTypes.push(\r\n                            NodeParticleBlockConnectionPointTypes.Vector2,\r\n                            NodeParticleBlockConnectionPointTypes.Vector3,\r\n                            NodeParticleBlockConnectionPointTypes.Color4\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        for (const observer of this._connectionObservers) {\r\n            observer.remove();\r\n        }\r\n        this._connectionObservers.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a JSON object\r\n     * @param serializationObject the JSON object to deserialize from\r\n     */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleMathBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleMathBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleMathBlock\", ParticleMathBlock);\r\n}\r\n","import { type Particle } from \"core/Particles/particle\";\r\n\r\n/**\r\n * Creates the local position data for the particle\r\n * @param particle The particle to update\r\n */\r\nexport function _CreateLocalPositionData(particle: Particle): void {\r\n    if (!particle._properties.localPosition) {\r\n        particle._properties.localPosition = particle.position.clone();\r\n    } else {\r\n        particle._properties.localPosition.copyFrom(particle.position);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide a flow of particles emitted from a box shape.\r\n */\r\nexport class BoxShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    /**\r\n     * Create a new BoxShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"direction1\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0, 1.0, 0));\r\n        this.registerInput(\"direction2\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0, 1.0, 0));\r\n        this.registerInput(\"minEmitBox\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(-0.5, -0.5, -0.5));\r\n        this.registerInput(\"maxEmitBox\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0.5, 0.5, 0.5));\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BoxShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle input component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction1 input component\r\n     */\r\n    public get direction1(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction2 input component\r\n     */\r\n    public get direction2(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the minEmitBox input component\r\n     */\r\n    public get minEmitBox(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the maxEmitBox input component\r\n     */\r\n    public get maxEmitBox(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const direction1 = this.direction1.getConnectedValue(state) as Vector3;\r\n            const direction2 = this.direction2.getConnectedValue(state) as Vector3;\r\n\r\n            const randX = RandomRange(direction1.x, direction2.x);\r\n            const randY = RandomRange(direction1.y, direction2.y);\r\n            const randZ = RandomRange(direction1.z, direction2.z);\r\n\r\n            if (system.isLocal) {\r\n                particle.direction.copyFromFloats(randX, randY, randZ);\r\n            } else {\r\n                Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.direction);\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const minEmitBox = this.minEmitBox.getConnectedValue(state) as Vector3;\r\n            const maxEmitBox = this.maxEmitBox.getConnectedValue(state) as Vector3;\r\n\r\n            const randX = RandomRange(minEmitBox.x, maxEmitBox.x);\r\n            const randY = RandomRange(minEmitBox.y, maxEmitBox.y);\r\n            const randZ = RandomRange(minEmitBox.z, maxEmitBox.z);\r\n\r\n            if (system.isLocal) {\r\n                particle.position.copyFromFloats(randX, randY, randZ);\r\n            } else {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for boxShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBoxShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BoxShapeBlock\", BoxShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { ParticleSystem } from \"core/Particles/particleSystem.pure\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { type _IExecutionQueueItem, _RemoveFromQueue } from \"core/Particles/Queue/executionQueue\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { PointParticleEmitter } from \"core/Particles/EmitterTypes/pointParticleEmitter\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\nconst ColorDiff = /*#__PURE__*/ new Color4();\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class CreateParticleBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new CreateParticleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"emitPower\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"lifeTime\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"color\", NodeParticleBlockConnectionPointTypes.Color4, true, new Color4(1, 1, 1, 1));\r\n        this.registerInput(\"colorDead\", NodeParticleBlockConnectionPointTypes.Color4, true, new Color4(0, 0, 0, 0));\r\n        this.registerInput(\"scale\", NodeParticleBlockConnectionPointTypes.Vector2, true, new Vector2(1, 1));\r\n        this.registerInput(\"angle\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"size\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n\r\n        this.scale.acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CreateParticleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the emitPower input component\r\n     */\r\n    public get emitPower(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the lifeTime input component\r\n     */\r\n    public get lifeTime(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the color dead input component\r\n     */\r\n    public get colorDead(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the scale input component\r\n     */\r\n    public get scale(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the angle input component\r\n     */\r\n    public get angle(): NodeParticleConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the size component\r\n     */\r\n    public get size(): NodeParticleConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the particle output component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = new ParticleSystem(this.name, state.capacity, state.scene, null, false, undefined, true);\r\n        system.particleEmitterType = new PointParticleEmitter();\r\n\r\n        // Creation\r\n        system._lifeTimeCreation.process = (particle: Particle, system: ThinParticleSystem) => {\r\n            state.particleContext = particle;\r\n            particle.lifeTime = this.lifeTime.getConnectedValue(state);\r\n            system._emitPower = this.emitPower.getConnectedValue(state);\r\n        };\r\n\r\n        system._colorCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n\r\n            const color = this.color.getConnectedValue(state);\r\n            if (color !== undefined) {\r\n                particle.color.copyFrom(color);\r\n            }\r\n        };\r\n\r\n        system._colorDeadCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n\r\n            particle.colorDead.copyFrom(this.colorDead.getConnectedValue(state));\r\n            particle.initialColor.copyFrom(particle.color);\r\n            particle.colorDead.subtractToRef(particle.initialColor, ColorDiff);\r\n            ColorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);\r\n        };\r\n\r\n        system._sizeCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n\r\n            const size = this.size.getConnectedValue(state);\r\n            if (size !== undefined) {\r\n                particle.size = size;\r\n            } else {\r\n                particle.size = 1.0;\r\n            }\r\n\r\n            const scale = this.scale.getConnectedValue(state);\r\n            if (scale.x !== undefined) {\r\n                particle.scale.x = scale.x;\r\n                particle.scale.y = scale.y;\r\n            } else {\r\n                particle.scale.x = scale;\r\n                particle.scale.y = scale;\r\n            }\r\n        };\r\n\r\n        system._angleCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n\r\n            particle.angle = this.angle.getConnectedValue(state);\r\n        };\r\n\r\n        this.particle._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for createParticleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCreateParticleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CreateParticleBlock\", CreateParticleBlock);\r\n}\r\n","import { serialize } from \"core/Misc/decorators\";\r\nimport { ParticleSystemSet } from \"../particleSystemSet\";\r\nimport { SystemBlock } from \"./Blocks/systemBlock.pure\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { NodeParticleBuildState } from \"./nodeParticleBuildState\";\r\nimport { type NodeParticleBlock } from \"./nodeParticleBlock\";\r\nimport { SerializationHelper } from \"core/Misc/decorators.serialization\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { GetClass } from \"core/Misc/typeStore\";\r\nimport { WebRequest } from \"core/Misc/webRequest\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Tools } from \"core/Misc/tools.pure\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { ParticleInputBlock } from \"./Blocks/particleInputBlock.pure\";\r\nimport { ParticleTextureSourceBlock } from \"./Blocks/particleSourceTextureBlock.pure\";\r\nimport { NodeParticleContextualSources } from \"./Enums/nodeParticleContextualSources\";\r\nimport { UpdatePositionBlock } from \"./Blocks/Update/updatePositionBlock.pure\";\r\nimport { ParticleMathBlock, ParticleMathBlockOperations } from \"./Blocks/particleMathBlock.pure\";\r\nimport { type ParticleTeleportOutBlock } from \"./Blocks/Teleport/particleTeleportOutBlock\";\r\nimport { type ParticleTeleportInBlock } from \"./Blocks/Teleport/particleTeleportInBlock\";\r\nimport { BoxShapeBlock } from \"./Blocks/Emitters/boxShapeBlock.pure\";\r\nimport { CreateParticleBlock } from \"./Blocks/Emitters/createParticleBlock.pure\";\r\nimport { type Color4 } from \"core/Maths/math.color\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n// declare NODEPARTICLEEDITOR namespace for compilation issue\r\ndeclare let NODEPARTICLEEDITOR: any;\r\ndeclare let BABYLON: any;\r\n\r\n/**\r\n * Interface used to configure the node particle editor\r\n */\r\nexport interface INodeParticleEditorOptions {\r\n    /** Define the URL to load node editor script from */\r\n    editorURL?: string;\r\n    /** Additional configuration for the NPE */\r\n    nodeEditorConfig?: {\r\n        backgroundColor?: Color4;\r\n        /** If true, the node particle system set will be disposed when the editor is closed (default: true) */\r\n        disposeOnClose?: boolean;\r\n    };\r\n}\r\n\r\n/**\r\n * Defines a set of particle systems defined as a node graph.\r\n * NPE: #K6F1ZB#1\r\n * PG: #ZT509U#1\r\n */\r\nexport class NodeParticleSystemSet {\r\n    private _systemBlocks: SystemBlock[] = [];\r\n    private _buildId: number = 0;\r\n\r\n    /** Define the Url to load node editor script */\r\n    public static EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/nodeParticleEditor/babylon.nodeParticleEditor.js`;\r\n\r\n    /** Define the Url to load snippets */\r\n    public static SnippetUrl = Constants.SnippetUrl;\r\n\r\n    /**\r\n     * Snippet ID if the material was created from the snippet server\r\n     */\r\n    public snippetId: string;\r\n\r\n    /**\r\n     * Gets an array of blocks that needs to be serialized even if they are not yet connected\r\n     */\r\n    public attachedBlocks: NodeParticleBlock[] = [];\r\n\r\n    /**\r\n     * Gets or sets data used by visual editor\r\n     * @see https://npe.babylonjs.com\r\n     */\r\n    public editorData: any = null;\r\n\r\n    /**\r\n     * Observable raised when the particle set is built\r\n     */\r\n    public onBuildObservable = new Observable<NodeParticleSystemSet>();\r\n\r\n    /**\r\n     * The name of the set\r\n     */\r\n    @serialize()\r\n    public name: string;\r\n\r\n    /**\r\n     * A free comment about the set\r\n     */\r\n    @serialize(\"comment\")\r\n    public comment: string;\r\n\r\n    /**\r\n     * Gets the system blocks\r\n     */\r\n    public get systemBlocks(): SystemBlock[] {\r\n        return this._systemBlocks;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of input blocks attached to this material\r\n     * @returns an array of InputBlocks\r\n     */\r\n    public get inputBlocks() {\r\n        const blocks: ParticleInputBlock[] = [];\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isInput) {\r\n                blocks.push(block as ParticleInputBlock);\r\n            }\r\n        }\r\n\r\n        return blocks;\r\n    }\r\n\r\n    /**\r\n     * Get a block by its name\r\n     * @param name defines the name of the block to retrieve\r\n     * @returns the required block or null if not found\r\n     */\r\n    public getBlockByName(name: string) {\r\n        let result = null;\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.name === name) {\r\n                if (!result) {\r\n                    result = block;\r\n                } else {\r\n                    Tools.Warn(\"More than one block was found with the name `\" + name + \"`\");\r\n                    return result;\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Get a block using a predicate\r\n     * @param predicate defines the predicate used to find the good candidate\r\n     * @returns the required block or null if not found\r\n     */\r\n    public getBlockByPredicate(predicate: (block: NodeParticleBlock) => boolean) {\r\n        for (const block of this.attachedBlocks) {\r\n            if (predicate(block)) {\r\n                return block;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Get an input block using a predicate\r\n     * @param predicate defines the predicate used to find the good candidate\r\n     * @returns the required input block or null if not found\r\n     */\r\n    public getInputBlockByPredicate(predicate: (block: ParticleInputBlock) => boolean): Nullable<ParticleInputBlock> {\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isInput && predicate(block as ParticleInputBlock)) {\r\n                return block as ParticleInputBlock;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n    /**\r\n     * Creates a new set\r\n     * @param name defines the name of the set\r\n     */\r\n    public constructor(name: string) {\r\n        this.name = name;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name of the node particle set e.g. \"NodeParticleSystemSet\"\r\n     * @returns the class name\r\n     */\r\n    public getClassName(): string {\r\n        return \"NodeParticleSystemSet\";\r\n    }\r\n\r\n    private _initializeBlock(node: NodeParticleBlock, autoConfigure = true) {\r\n        if (this.attachedBlocks.indexOf(node) === -1) {\r\n            this.attachedBlocks.push(node);\r\n        }\r\n\r\n        for (const input of node.inputs) {\r\n            const connectedPoint = input.connectedPoint;\r\n            if (connectedPoint) {\r\n                const block = connectedPoint.ownerBlock;\r\n                if (block !== node) {\r\n                    this._initializeBlock(block, autoConfigure);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private BJSNODEPARTICLEEDITOR = this._getGlobalNodeParticleEditor();\r\n\r\n    /** Get the editor from bundle or global\r\n     * @returns the global NPE\r\n     */\r\n    private _getGlobalNodeParticleEditor(): any {\r\n        // UMD global name detection from bundle metadata.\r\n        // Note: rollup-built UMD bundles do not expose the editor class\r\n        // directly on the namespace - it lives on `.default.NodeParticleEditor` -\r\n        // so we unwrap that case before falling back to the BABYLON global.\r\n        if (typeof NODEPARTICLEEDITOR !== \"undefined\") {\r\n            if ((NODEPARTICLEEDITOR as any).NodeParticleEditor) {\r\n                return NODEPARTICLEEDITOR;\r\n            }\r\n            if ((NODEPARTICLEEDITOR as any).default?.NodeParticleEditor) {\r\n                return (NODEPARTICLEEDITOR as any).default;\r\n            }\r\n        }\r\n\r\n        // In case of module let's check the global emitted from the editor entry point.\r\n        if (typeof BABYLON !== \"undefined\" && typeof BABYLON.NodeParticleEditor !== \"undefined\") {\r\n            return BABYLON;\r\n        }\r\n\r\n        return undefined;\r\n    }\r\n\r\n    /** Creates the node editor window.\r\n     * @param additionalConfig Define the configuration of the editor\r\n     */\r\n    private _createNodeParticleEditor(additionalConfig?: any) {\r\n        const nodeEditorConfig: any = {\r\n            nodeParticleSet: this,\r\n            ...additionalConfig,\r\n        };\r\n        this.BJSNODEPARTICLEEDITOR.NodeParticleEditor.Show(nodeEditorConfig);\r\n    }\r\n\r\n    /**\r\n     * Launch the node particle editor\r\n     * @param config Define the configuration of the editor\r\n     * @returns a promise fulfilled when the node editor is visible\r\n     */\r\n    public async editAsync(config?: INodeParticleEditorOptions): Promise<void> {\r\n        return await new Promise((resolve) => {\r\n            this.BJSNODEPARTICLEEDITOR = this.BJSNODEPARTICLEEDITOR || this._getGlobalNodeParticleEditor();\r\n            if (typeof this.BJSNODEPARTICLEEDITOR == \"undefined\") {\r\n                const editorUrl = config && config.editorURL ? config.editorURL : NodeParticleSystemSet.EditorURL;\r\n\r\n                // Load editor and add it to the DOM\r\n                Tools.LoadBabylonScript(editorUrl, () => {\r\n                    this.BJSNODEPARTICLEEDITOR = this.BJSNODEPARTICLEEDITOR || this._getGlobalNodeParticleEditor();\r\n                    this._createNodeParticleEditor(config?.nodeEditorConfig);\r\n                    resolve();\r\n                });\r\n            } else {\r\n                // Otherwise creates the editor\r\n                this._createNodeParticleEditor(config?.nodeEditorConfig);\r\n                resolve();\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Builds the particle system set from the defined blocks.\r\n     * @param scene defines the hosting scene\r\n     * @param verbose defines whether to log detailed information during the build process (false by default)\r\n     * @returns a promise that resolves to the built particle system set\r\n     */\r\n    public async buildAsync(scene: Scene, verbose = false): Promise<ParticleSystemSet> {\r\n        const output = new ParticleSystemSet();\r\n\r\n        // Initialize all blocks\r\n        for (const block of this._systemBlocks) {\r\n            this._initializeBlock(block);\r\n        }\r\n\r\n        // Build the blocks\r\n        const buildPromises = new Array<Promise<void>>();\r\n        for (const block of this.systemBlocks) {\r\n            const state = new NodeParticleBuildState();\r\n            state.buildId = this._buildId++;\r\n            state.scene = scene;\r\n            state.verbose = verbose;\r\n\r\n            const system = block.createSystem(state);\r\n            system._source = this;\r\n            system._blockReference = block._internalId;\r\n\r\n            // Errors\r\n            state.emitErrors();\r\n\r\n            buildPromises.push(state.waitForBuildPromisesAsync());\r\n\r\n            output.systems.push(system);\r\n        }\r\n\r\n        await Promise.all(buildPromises);\r\n\r\n        this.onBuildObservable.notifyObservers(this);\r\n\r\n        return output;\r\n    }\r\n\r\n    /**\r\n     * Clear the current node particle set\r\n     */\r\n    public clear() {\r\n        this.attachedBlocks.length = 0;\r\n        this._systemBlocks.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Clear the current set and restore it to a default state\r\n     */\r\n    public setToDefault() {\r\n        this.clear();\r\n\r\n        this.editorData = null;\r\n\r\n        // Main system\r\n        const system = new SystemBlock(\"Particle system\");\r\n\r\n        // Update position\r\n        const updatePositionBlock = new UpdatePositionBlock(\"Update position\");\r\n        updatePositionBlock.output.connectTo(system.particle);\r\n\r\n        // Contextual inputs\r\n        const positionBlock = new ParticleInputBlock(\"Position\");\r\n        positionBlock.contextualValue = NodeParticleContextualSources.Position;\r\n        const directionBlock = new ParticleInputBlock(\"Scaled direction\");\r\n        directionBlock.contextualValue = NodeParticleContextualSources.ScaledDirection;\r\n\r\n        // Add\r\n        const addBlock = new ParticleMathBlock(\"Add\");\r\n        addBlock.operation = ParticleMathBlockOperations.Add;\r\n        positionBlock.output.connectTo(addBlock.left);\r\n        directionBlock.output.connectTo(addBlock.right);\r\n        addBlock.output.connectTo(updatePositionBlock.position);\r\n\r\n        // Create particle\r\n        const createParticleBlock = new CreateParticleBlock(\"Create particle\");\r\n\r\n        // Shape\r\n        const emitterShape = new BoxShapeBlock(\"Box shape\");\r\n        createParticleBlock.particle.connectTo(emitterShape.particle);\r\n        emitterShape.output.connectTo(updatePositionBlock.particle);\r\n\r\n        // Texture\r\n        const textureBlock = new ParticleTextureSourceBlock(\"Texture\");\r\n        textureBlock.textureOutput.connectTo(system.texture);\r\n        textureBlock.url = Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/textures/flare.png\");\r\n\r\n        this._systemBlocks.push(system);\r\n    }\r\n\r\n    /**\r\n     * Remove a block from the current system set\r\n     * @param block defines the block to remove\r\n     */\r\n    public removeBlock(block: NodeParticleBlock) {\r\n        const attachedBlockIndex = this.attachedBlocks.indexOf(block);\r\n        if (attachedBlockIndex > -1) {\r\n            this.attachedBlocks.splice(attachedBlockIndex, 1);\r\n        }\r\n\r\n        if (block.isSystem) {\r\n            const index = this._systemBlocks.indexOf(block as SystemBlock);\r\n            if (index > -1) {\r\n                this._systemBlocks.splice(index, 1);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the current graph and load a new one from a serialization object\r\n     * @param source defines the JSON representation of the particle set\r\n     * @param merge defines whether or not the source must be merged or replace the current content\r\n     */\r\n    public parseSerializedObject(source: any, merge = false) {\r\n        if (!merge) {\r\n            this.clear();\r\n        }\r\n\r\n        const map: { [key: number]: NodeParticleBlock } = {};\r\n\r\n        // Create blocks\r\n        for (const parsedBlock of source.blocks) {\r\n            const blockType = GetClass(parsedBlock.customType);\r\n            if (blockType) {\r\n                const block: NodeParticleBlock = new blockType();\r\n                block._deserialize(parsedBlock);\r\n                map[parsedBlock.id] = block;\r\n\r\n                this.attachedBlocks.push(block);\r\n\r\n                if (block.isSystem) {\r\n                    this._systemBlocks.push(block as SystemBlock);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Reconnect teleportation\r\n        for (const block of this.attachedBlocks) {\r\n            if (block.isTeleportOut) {\r\n                const teleportOut = block as ParticleTeleportOutBlock;\r\n                const id = teleportOut._tempEntryPointUniqueId;\r\n                if (id) {\r\n                    const source = map[id] as ParticleTeleportInBlock;\r\n                    if (source) {\r\n                        source.attachToEndpoint(teleportOut);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Connections - Starts with input blocks only (except if in \"merge\" mode where we scan all blocks)\r\n        for (let blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {\r\n            const parsedBlock = source.blocks[blockIndex];\r\n            const block = map[parsedBlock.id];\r\n\r\n            if (!block) {\r\n                continue;\r\n            }\r\n\r\n            if (block.inputs.length && parsedBlock.inputs.some((i: any) => i.targetConnectionName) && !merge) {\r\n                continue;\r\n            }\r\n            this._restoreConnections(block, source, map);\r\n        }\r\n\r\n        // UI related info\r\n        if (source.locations || (source.editorData && source.editorData.locations)) {\r\n            const locations: {\r\n                blockId: number;\r\n                x: number;\r\n                y: number;\r\n                isCollapsed: boolean;\r\n            }[] = source.locations || source.editorData.locations;\r\n\r\n            for (const location of locations) {\r\n                if (map[location.blockId]) {\r\n                    location.blockId = map[location.blockId].uniqueId;\r\n                }\r\n            }\r\n\r\n            if (merge && this.editorData && this.editorData.locations) {\r\n                locations.concat(this.editorData.locations);\r\n            }\r\n\r\n            if (source.locations) {\r\n                this.editorData = {\r\n                    locations: locations,\r\n                };\r\n            } else {\r\n                this.editorData = source.editorData;\r\n                this.editorData.locations = locations;\r\n            }\r\n\r\n            const blockMap: { [key: number]: number } = {};\r\n\r\n            for (const key in map) {\r\n                blockMap[key] = map[key].uniqueId;\r\n            }\r\n\r\n            this.editorData.map = blockMap;\r\n        }\r\n\r\n        this.comment = source.comment;\r\n    }\r\n\r\n    private _restoreConnections(block: NodeParticleBlock, source: any, map: { [key: number]: NodeParticleBlock }) {\r\n        for (const outputPoint of block.outputs) {\r\n            for (const candidate of source.blocks) {\r\n                const target = map[candidate.id];\r\n\r\n                if (!target) {\r\n                    continue;\r\n                }\r\n\r\n                for (const input of candidate.inputs) {\r\n                    if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {\r\n                        const inputPoint = target.getInputByName(input.inputName);\r\n                        if (!inputPoint || inputPoint.isConnected) {\r\n                            continue;\r\n                        }\r\n\r\n                        outputPoint.connectTo(inputPoint, true);\r\n                        this._restoreConnections(target, source, map);\r\n                        continue;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Serializes this node particle set in a JSON representation\r\n     * @param selectedBlocks defines the list of blocks to save (if null the whole node particle set will be saved)\r\n     * @returns the serialized particle system set object\r\n     */\r\n    public serialize(selectedBlocks?: NodeParticleBlock[]): any {\r\n        const serializationObject = selectedBlocks ? {} : SerializationHelper.Serialize(this);\r\n        serializationObject.editorData = JSON.parse(JSON.stringify(this.editorData)); // Copy\r\n\r\n        let blocks: NodeParticleBlock[] = [];\r\n\r\n        if (selectedBlocks) {\r\n            blocks = selectedBlocks;\r\n        } else {\r\n            serializationObject.customType = \"BABYLON.NodeParticleSystemSet\";\r\n        }\r\n\r\n        // Blocks\r\n        serializationObject.blocks = [];\r\n\r\n        for (const block of blocks) {\r\n            serializationObject.blocks.push(block.serialize());\r\n        }\r\n\r\n        if (!selectedBlocks) {\r\n            for (const block of this.attachedBlocks) {\r\n                if (blocks.indexOf(block) !== -1) {\r\n                    continue;\r\n                }\r\n                serializationObject.blocks.push(block.serialize());\r\n            }\r\n        }\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Makes a duplicate of the current particle system set.\r\n     * @param name defines the name to use for the new particle system set\r\n     * @returns the cloned particle system set\r\n     */\r\n    public clone(name: string): NodeParticleSystemSet {\r\n        const serializationObject = this.serialize();\r\n\r\n        const clone = SerializationHelper.Clone(() => new NodeParticleSystemSet(name), this);\r\n        clone.name = name;\r\n        clone.snippetId = this.snippetId;\r\n\r\n        clone.parseSerializedObject(serializationObject);\r\n        clone._buildId = this._buildId;\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Disposes the resources\r\n     */\r\n    public dispose(): void {\r\n        for (const block of this.attachedBlocks) {\r\n            block.dispose();\r\n        }\r\n\r\n        this.attachedBlocks.length = 0;\r\n        this.onBuildObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Creates a new node particle set set to default basic configuration\r\n     * @param name defines the name of the particle set\r\n     * @returns a new NodeParticleSystemSet\r\n     */\r\n    public static CreateDefault(name: string) {\r\n        const nodeParticleSet = new NodeParticleSystemSet(name);\r\n\r\n        nodeParticleSet.setToDefault();\r\n\r\n        return nodeParticleSet;\r\n    }\r\n\r\n    /**\r\n     * Creates a node particle set from parsed data\r\n     * @param source defines the JSON representation of the particle set\r\n     * @returns a new node particle set\r\n     */\r\n    public static Parse(source: any): NodeParticleSystemSet {\r\n        const nodeParticleSet = SerializationHelper.Parse(() => new NodeParticleSystemSet(source.name), source, null);\r\n\r\n        nodeParticleSet.parseSerializedObject(source);\r\n\r\n        return nodeParticleSet;\r\n    }\r\n\r\n    /**\r\n     * Creates a node particle set from a snippet saved in a remote file\r\n     * @param name defines the name of the node particle set to create\r\n     * @param url defines the url to load from\r\n     * @param nodeParticleSet defines a node particle set to update (instead of creating a new one)\r\n     * @returns a promise that will resolve to the new node particle set\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromFileAsync(name: string, url: string, nodeParticleSet?: NodeParticleSystemSet): Promise<NodeParticleSystemSet> {\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const serializationObject = JSON.parse(request.responseText);\r\n                        if (!nodeParticleSet) {\r\n                            nodeParticleSet = SerializationHelper.Parse(() => new NodeParticleSystemSet(name), serializationObject, null);\r\n                        }\r\n\r\n                        nodeParticleSet.parseSerializedObject(serializationObject);\r\n\r\n                        resolve(nodeParticleSet);\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the node particle system set\");\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", url);\r\n            request.send();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Creates a node particle set from a snippet saved by the node particle editor\r\n     * @param snippetId defines the snippet to load\r\n     * @param nodeParticleSet defines a node particle set to update (instead of creating a new one)\r\n     * @returns a promise that will resolve to the new node particle set\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\r\n    public static ParseFromSnippetAsync(snippetId: string, nodeParticleSet?: NodeParticleSystemSet): Promise<NodeParticleSystemSet> {\r\n        if (snippetId === \"_BLANK\") {\r\n            return Promise.resolve(NodeParticleSystemSet.CreateDefault(\"blank\"));\r\n        }\r\n\r\n        return new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        const snippet = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n                        const serializationObject = JSON.parse(snippet.nodeParticle);\r\n\r\n                        if (!nodeParticleSet) {\r\n                            nodeParticleSet = SerializationHelper.Parse(() => new NodeParticleSystemSet(snippetId), serializationObject, null);\r\n                        }\r\n\r\n                        nodeParticleSet.parseSerializedObject(serializationObject);\r\n                        nodeParticleSet.snippetId = snippetId;\r\n\r\n                        try {\r\n                            resolve(nodeParticleSet);\r\n                        } catch (err) {\r\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                            reject(err);\r\n                        }\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                        reject(\"Unable to load the snippet \" + snippetId);\r\n                    }\r\n                }\r\n            });\r\n\r\n            request.open(\"GET\", this.SnippetUrl + \"/\" + snippetId.replace(/#/g, \"/\"));\r\n            request.send();\r\n        });\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Vector2, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to create a Vector2/3 and Color4 out of individual or partial inputs\r\n */\r\nexport class ParticleConverterBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new ParticleConverterBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"color \", NodeParticleBlockConnectionPointTypes.Color4, true);\r\n        this.registerInput(\"xyz \", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"xy \", NodeParticleBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"zw \", NodeParticleBlockConnectionPointTypes.Vector2, true);\r\n        this.registerInput(\"x \", NodeParticleBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"y \", NodeParticleBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"z \", NodeParticleBlockConnectionPointTypes.Float, true);\r\n        this.registerInput(\"w \", NodeParticleBlockConnectionPointTypes.Float, true);\r\n\r\n        this.registerOutput(\"color\", NodeParticleBlockConnectionPointTypes.Color4);\r\n        this.registerOutput(\"xyz\", NodeParticleBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"xy\", NodeParticleBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"zw\", NodeParticleBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"x\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"y\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"z\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"w\", NodeParticleBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleConverterBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the color component (input)\r\n     */\r\n    public get colorIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (input)\r\n     */\r\n    public get xyzIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (input)\r\n     */\r\n    public get xyIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (input)\r\n     */\r\n    public get zwIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component (input)\r\n     */\r\n    public get xIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component (input)\r\n     */\r\n    public get yIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component (input)\r\n     */\r\n    public get zIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component (input)\r\n     */\r\n    public get wIn(): NodeParticleConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyzw component (output)\r\n     */\r\n    public get colorOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the xyz component (output)\r\n     */\r\n    public get xyzOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the xy component (output)\r\n     */\r\n    public get xyOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the zw component (output)\r\n     */\r\n    public get zwOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the x component (output)\r\n     */\r\n    public get xOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the y component (output)\r\n     */\r\n    public get yOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the z component (output)\r\n     */\r\n    public get zOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the w component (output)\r\n     */\r\n    public get wOut(): NodeParticleConnectionPoint {\r\n        return this._outputs[7];\r\n    }\r\n\r\n    protected override _inputRename(name: string) {\r\n        if (name === \"color \") {\r\n            return \"colorIn\";\r\n        }\r\n        if (name === \"xyz \") {\r\n            return \"xyzIn\";\r\n        }\r\n        if (name === \"xy \") {\r\n            return \"xyIn\";\r\n        }\r\n        if (name === \"zw \") {\r\n            return \"zwIn\";\r\n        }\r\n        if (name === \"x \") {\r\n            return \"xIn\";\r\n        }\r\n        if (name === \"y \") {\r\n            return \"yIn\";\r\n        }\r\n        if (name === \"z \") {\r\n            return \"zIn\";\r\n        }\r\n        if (name === \"w \") {\r\n            return \"wIn\";\r\n        }\r\n        return name;\r\n    }\r\n\r\n    protected override _outputRename(name: string) {\r\n        switch (name) {\r\n            case \"x\":\r\n                return \"xOut\";\r\n            case \"y\":\r\n                return \"yOut\";\r\n            case \"z\":\r\n                return \"zOut\";\r\n            case \"w\":\r\n                return \"wOut\";\r\n            case \"xy\":\r\n                return \"xyOut\";\r\n            case \"zw\":\r\n                return \"zwOut\";\r\n            case \"xyz\":\r\n                return \"xyzOut\";\r\n            case \"color\":\r\n                return \"colorOut\";\r\n            default:\r\n                return name;\r\n        }\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        super._build(state);\r\n\r\n        const xInput = this.xIn;\r\n        const yInput = this.yIn;\r\n        const zInput = this.zIn;\r\n        const wInput = this.wIn;\r\n        const xyInput = this.xyIn;\r\n        const zwInput = this.zwIn;\r\n        const xyzInput = this.xyzIn;\r\n        const colorInput = this.colorIn;\r\n\r\n        const colorOutput = this.colorOut;\r\n        const xyzOutput = this.xyzOut;\r\n        const xyOutput = this.xyOut;\r\n        const zwOutput = this.zwOut;\r\n        const xOutput = this.xOut;\r\n        const yOutput = this.yOut;\r\n        const zOutput = this.zOut;\r\n        const wOutput = this.wOut;\r\n\r\n        const getData = (state: NodeParticleBuildState): Color4 => {\r\n            if (colorInput.isConnected) {\r\n                return colorInput.getConnectedValue(state);\r\n            }\r\n\r\n            let x: number = 0;\r\n            let y: number = 0;\r\n            let z: number = 0;\r\n            let w: number = 0;\r\n\r\n            if (xInput.isConnected) {\r\n                x = xInput.getConnectedValue(state);\r\n            }\r\n            if (yInput.isConnected) {\r\n                y = yInput.getConnectedValue(state);\r\n            }\r\n            if (zInput.isConnected) {\r\n                z = zInput.getConnectedValue(state);\r\n            }\r\n            if (wInput.isConnected) {\r\n                w = wInput.getConnectedValue(state);\r\n            }\r\n\r\n            if (xyInput.isConnected) {\r\n                const temp = xyInput.getConnectedValue(state);\r\n                if (temp) {\r\n                    x = temp.x;\r\n                    y = temp.y;\r\n                }\r\n            }\r\n            if (zwInput.isConnected) {\r\n                const temp = zwInput.getConnectedValue(state);\r\n                if (temp) {\r\n                    z = temp.x;\r\n                    w = temp.y;\r\n                }\r\n            }\r\n            if (xyzInput.isConnected) {\r\n                const temp = xyzInput.getConnectedValue(state);\r\n                if (temp) {\r\n                    x = temp.x;\r\n                    y = temp.y;\r\n                    z = temp.z;\r\n                }\r\n            }\r\n\r\n            return new Color4(x, y, z, w);\r\n        };\r\n\r\n        colorOutput._storedFunction = (state) => getData(state);\r\n        xyzOutput._storedFunction = (state) => {\r\n            const data = getData(state);\r\n            return new Vector3(data.r, data.g, data.b);\r\n        };\r\n        xyOutput._storedFunction = (state) => {\r\n            const data = getData(state);\r\n            return new Vector2(data.r, data.g);\r\n        };\r\n        zwOutput._storedFunction = (state) => {\r\n            const data = getData(state);\r\n            return new Vector2(data.b, data.a);\r\n        };\r\n        xOutput._storedFunction = (state) => getData(state).r;\r\n        yOutput._storedFunction = (state) => getData(state).g;\r\n        zOutput._storedFunction = (state) => getData(state).b;\r\n        wOutput._storedFunction = (state) => getData(state).a;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleConverterBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleConverterBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleConverterBlock\", ParticleConverterBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\n\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the FloatToInt block\r\n */\r\nexport enum ParticleFloatToIntBlockOperations {\r\n    /** Round */\r\n    Round,\r\n    /** Ceil */\r\n    Ceil,\r\n    /** Floor */\r\n    Floor,\r\n    /** Truncate */\r\n    Truncate,\r\n}\r\n\r\n/**\r\n * Block used to transform a float to an int\r\n */\r\nexport class ParticleFloatToIntBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Round\", value: ParticleFloatToIntBlockOperations.Round },\r\n            { label: \"Ceil\", value: ParticleFloatToIntBlockOperations.Ceil },\r\n            { label: \"Floor\", value: ParticleFloatToIntBlockOperations.Floor },\r\n            { label: \"Truncate\", value: ParticleFloatToIntBlockOperations.Truncate },\r\n        ],\r\n    })\r\n    public operation = ParticleFloatToIntBlockOperations.Round;\r\n\r\n    /**\r\n     * Creates a new ParticleFloatToIntBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Int);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(NodeParticleBlockConnectionPointTypes.Float | NodeParticleBlockConnectionPointTypes.Int);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleFloatToIntBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        super._build(state);\r\n        let func: Nullable<(value: NodeParticleBuildState) => number> = null;\r\n        const input = this.input;\r\n\r\n        switch (this.operation) {\r\n            case ParticleFloatToIntBlockOperations.Round: {\r\n                func = (state) => {\r\n                    return Math.round(input.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n            case ParticleFloatToIntBlockOperations.Ceil: {\r\n                func = (state) => {\r\n                    return Math.ceil(input.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n            case ParticleFloatToIntBlockOperations.Floor: {\r\n                func = (state) => {\r\n                    return Math.floor(input.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n            case ParticleFloatToIntBlockOperations.Truncate: {\r\n                func = (state) => {\r\n                    return Math.trunc(input.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (!func) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            return func(state);\r\n        };\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleFloatToIntBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleFloatToIntBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleFloatToIntBlock\", ParticleFloatToIntBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type ParticleGradientValueBlock } from \"./particleGradientValueBlock.pure\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Lerp } from \"core/Maths/math.scalar.functions\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to define a list of gradient entries\r\n */\r\nexport class ParticleGradientBlock extends NodeParticleBlock {\r\n    private _entryCount = 1;\r\n    /**\r\n     * Creates a new ParticleGradientBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"gradient\", NodeParticleBlockConnectionPointTypes.Float, true, 1, 0, 1);\r\n        this.registerInput(\"value0\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[1];\r\n        this._outputs[0]._typeConnectionSourceTranslation = (type) => {\r\n            switch (type) {\r\n                case NodeParticleBlockConnectionPointTypes.FloatGradient:\r\n                    return NodeParticleBlockConnectionPointTypes.Float;\r\n                case NodeParticleBlockConnectionPointTypes.Vector2Gradient:\r\n                    return NodeParticleBlockConnectionPointTypes.Vector2;\r\n                case NodeParticleBlockConnectionPointTypes.Vector3Gradient:\r\n                    return NodeParticleBlockConnectionPointTypes.Vector3;\r\n                case NodeParticleBlockConnectionPointTypes.Color4Gradient:\r\n                    return NodeParticleBlockConnectionPointTypes.Color4;\r\n            }\r\n            return type;\r\n        };\r\n\r\n        this._inputs[1].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeParticleBlockConnectionPointTypes.FloatGradient |\r\n                NodeParticleBlockConnectionPointTypes.Vector2Gradient |\r\n                NodeParticleBlockConnectionPointTypes.Vector3Gradient |\r\n                NodeParticleBlockConnectionPointTypes.Color4Gradient\r\n        );\r\n\r\n        this._manageExtendedInputs(1);\r\n    }\r\n\r\n    private _extend() {\r\n        this._entryCount++;\r\n        this.registerInput(\"value\" + (this._entryCount - 1), NodeParticleBlockConnectionPointTypes.AutoDetect, true);\r\n        this._linkConnectionTypes(1, this._entryCount);\r\n\r\n        this._manageExtendedInputs(this._entryCount);\r\n    }\r\n\r\n    private _reduce() {\r\n        // Remove the last input if it's not connected and we have more than one entry\r\n        for (let i = this._inputs.length - 2; i >= 1; i--) {\r\n            if (this._inputs[i].isConnected) {\r\n                break;\r\n            }\r\n            const inputToRemove = this._inputs[i];\r\n            inputToRemove.dispose();\r\n            this._inputs.splice(i, 1);\r\n            this._entryCount--;\r\n            this.onInputChangedObservable.notifyObservers(inputToRemove);\r\n        }\r\n\r\n        // Rename inputs\r\n        for (let i = 1; i < this._inputs.length; i++) {\r\n            this._inputs[i].name = \"value\" + (i - 1);\r\n        }\r\n    }\r\n\r\n    private _manageExtendedInputs(index: number) {\r\n        this._inputs[index].onConnectionObservable.add(() => {\r\n            if (this._entryCount > index) {\r\n                return;\r\n            }\r\n\r\n            // Need to add a new input\r\n            this._extend();\r\n        });\r\n\r\n        this._inputs[index].onDisconnectionObservable.add(() => {\r\n            this._reduce();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleGradientBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        // Building the list of entries in order\r\n        const entries: ParticleGradientValueBlock[] = [];\r\n        for (let i = 1; i < this._inputs.length; i++) {\r\n            if (this._inputs[i].isConnected) {\r\n                entries.push(this._inputs[i].connectedPoint?.ownerBlock as ParticleGradientValueBlock);\r\n            }\r\n        }\r\n\r\n        entries.sort((a, b) => {\r\n            return a.reference - b.reference;\r\n        });\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const gradient = this.gradient.getConnectedValue(state);\r\n\r\n            if (entries.length === 1) {\r\n                return entries[0].value.getConnectedValue(state);\r\n            }\r\n\r\n            // Go down the entries list in reverse order\r\n            let nextEntry: Nullable<ParticleGradientValueBlock> = null;\r\n            for (let i = entries.length - 1; i >= 0; i--) {\r\n                const entry = entries[i];\r\n                if (entry.reference <= gradient) {\r\n                    const currentValue = entry.value.getConnectedValue(state);\r\n                    if (nextEntry) {\r\n                        const nextValue = nextEntry.value.getConnectedValue(state);\r\n                        const nextReference = nextEntry.reference;\r\n                        const currentReference = entry.reference;\r\n                        const scale = Math.max(0, Math.min(1, (gradient - currentReference) / (nextReference - currentReference)));\r\n\r\n                        switch (this.output.type) {\r\n                            case NodeParticleBlockConnectionPointTypes.Float:\r\n                                return Lerp(currentValue, nextValue, scale);\r\n                            case NodeParticleBlockConnectionPointTypes.Vector2:\r\n                                return Vector2.Lerp(currentValue, nextValue, scale);\r\n                            case NodeParticleBlockConnectionPointTypes.Vector3:\r\n                                return Vector3.Lerp(currentValue, nextValue, scale);\r\n                            case NodeParticleBlockConnectionPointTypes.Color4:\r\n                                return Color4.Lerp(currentValue, nextValue, scale);\r\n                        }\r\n                    }\r\n                    return currentValue;\r\n                }\r\n\r\n                nextEntry = entry;\r\n            }\r\n\r\n            return 0;\r\n        };\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject._entryCount = this._entryCount;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject._entryCount && serializationObject._entryCount > 1) {\r\n            for (let i = 1; i < serializationObject._entryCount; i++) {\r\n                this._extend();\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleGradientBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleGradientBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleGradientBlock\", ParticleGradientBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to define a gradient entry for a gradient block\r\n */\r\nexport class ParticleGradientValueBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the epsilon value used for comparison\r\n     */\r\n    @editableInPropertyPage(\"Reference\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0, max: 1 })\r\n    public reference = 0;\r\n\r\n    /**\r\n     * Creates a new ParticleGradientEntryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._outputs[0]._typeConnectionSourceTranslation = (type) => {\r\n            switch (type) {\r\n                case NodeParticleBlockConnectionPointTypes.Float:\r\n                    return NodeParticleBlockConnectionPointTypes.FloatGradient;\r\n                case NodeParticleBlockConnectionPointTypes.Vector2:\r\n                    return NodeParticleBlockConnectionPointTypes.Vector2Gradient;\r\n                case NodeParticleBlockConnectionPointTypes.Vector3:\r\n                    return NodeParticleBlockConnectionPointTypes.Vector3Gradient;\r\n                case NodeParticleBlockConnectionPointTypes.Color4:\r\n                    return NodeParticleBlockConnectionPointTypes.Color4Gradient;\r\n            }\r\n            return type;\r\n        };\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeParticleBlockConnectionPointTypes.Float |\r\n                NodeParticleBlockConnectionPointTypes.Vector2 |\r\n                NodeParticleBlockConnectionPointTypes.Vector3 |\r\n                NodeParticleBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleGradientValueBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        this.output._storedFunction = (state) => {\r\n            return null;\r\n        };\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.reference = this.reference;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.reference = serializationObject.reference;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleGradientValueBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleGradientValueBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleGradientValueBlock\", ParticleGradientValueBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\n\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Locks supported by the random block\r\n */\r\nexport enum ParticleRandomBlockLocks {\r\n    /** None */\r\n    None = 0,\r\n    /** PerParticle */\r\n    PerParticle = 1,\r\n    /** PerSystem */\r\n    PerSystem = 2,\r\n    /** OncePerParticle */\r\n    OncePerParticle = 3,\r\n}\r\n\r\n/**\r\n * Block used to get a random number\r\n */\r\nexport class ParticleRandomBlock extends NodeParticleBlock {\r\n    private _currentLockId = -2;\r\n    private _oncePerParticleMap: Map<number, any> = new Map();\r\n\r\n    /**\r\n     * Gets or sets a value indicating if that block will lock its value for a specific event\r\n     */\r\n    @editableInPropertyPage(\"LockMode\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"None\", value: ParticleRandomBlockLocks.None },\r\n            { label: \"Per particle\", value: ParticleRandomBlockLocks.PerParticle },\r\n            { label: \"Per system\", value: ParticleRandomBlockLocks.PerSystem },\r\n            { label: \"Once per particle\", value: ParticleRandomBlockLocks.OncePerParticle },\r\n        ],\r\n    })\r\n    public lockMode = ParticleRandomBlockLocks.PerParticle;\r\n\r\n    /**\r\n     * Create a new ParticleRandomBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"min\", NodeParticleBlockConnectionPointTypes.AutoDetect, true, 0);\r\n        this.registerInput(\"max\", NodeParticleBlockConnectionPointTypes.AutoDetect, true, 1);\r\n\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeParticleBlockConnectionPointTypes.Float |\r\n                NodeParticleBlockConnectionPointTypes.Int |\r\n                NodeParticleBlockConnectionPointTypes.Vector2 |\r\n                NodeParticleBlockConnectionPointTypes.Vector3 |\r\n                NodeParticleBlockConnectionPointTypes.Color4\r\n        );\r\n        this._inputs[1].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeParticleBlockConnectionPointTypes.Float |\r\n                NodeParticleBlockConnectionPointTypes.Int |\r\n                NodeParticleBlockConnectionPointTypes.Vector2 |\r\n                NodeParticleBlockConnectionPointTypes.Vector3 |\r\n                NodeParticleBlockConnectionPointTypes.Color4\r\n        );\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._outputs[0]._defaultConnectionPointType = NodeParticleBlockConnectionPointTypes.Float;\r\n        this._linkConnectionTypes(0, 1);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleRandomBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the min input component\r\n     */\r\n    public get min(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the max input component\r\n     */\r\n    public get max(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        let func: Nullable<(state: NodeParticleBuildState) => any> = null;\r\n        this._currentLockId = -2;\r\n        this._oncePerParticleMap.clear();\r\n\r\n        switch (this.min.type) {\r\n            case NodeParticleBlockConnectionPointTypes.AutoDetect:\r\n            case NodeParticleBlockConnectionPointTypes.Int:\r\n            case NodeParticleBlockConnectionPointTypes.Float: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? 0;\r\n                    const max = this.max.getConnectedValue(state) ?? 1;\r\n                    return min + Math.random() * (max - min);\r\n                };\r\n                break;\r\n            }\r\n            case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? Vector2.Zero();\r\n                    const max = this.max.getConnectedValue(state) ?? Vector2.One();\r\n                    return new Vector2(min.x + Math.random() * (max.x - min.x), min.y + Math.random() * (max.y - min.y));\r\n                };\r\n                break;\r\n            }\r\n            case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? Vector3.Zero();\r\n                    const max = this.max.getConnectedValue(state) ?? Vector3.One();\r\n                    return new Vector3(min.x + Math.random() * (max.x - min.x), min.y + Math.random() * (max.y - min.y), min.z + Math.random() * (max.z - min.z));\r\n                };\r\n                break;\r\n            }\r\n            case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                func = (state) => {\r\n                    const min = this.min.getConnectedValue(state) ?? new Color4(0, 0, 0, 0);\r\n                    const max = this.max.getConnectedValue(state) ?? new Color4(1, 1, 1, 1);\r\n                    return new Color4(\r\n                        min.r + Math.random() * (max.r - min.r),\r\n                        min.g + Math.random() * (max.g - min.g),\r\n                        min.b + Math.random() * (max.b - min.b),\r\n                        min.a + Math.random() * (max.a - min.a)\r\n                    );\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            if (this.lockMode === ParticleRandomBlockLocks.OncePerParticle) {\r\n                const particleId = state.particleContext?.id ?? -1;\r\n                let cachedValue = this._oncePerParticleMap.get(particleId);\r\n\r\n                if (!cachedValue) {\r\n                    cachedValue = func!(state);\r\n                    this._oncePerParticleMap.set(particleId, cachedValue);\r\n                }\r\n\r\n                this.output._storedValue = cachedValue;\r\n            } else {\r\n                let lockId = -2;\r\n\r\n                switch (this.lockMode) {\r\n                    case ParticleRandomBlockLocks.PerParticle:\r\n                        lockId = state.particleContext?.id ?? -1;\r\n                        break;\r\n                    case ParticleRandomBlockLocks.PerSystem:\r\n                        lockId = state.buildId ?? 0;\r\n                        break;\r\n                    default:\r\n                        break;\r\n                }\r\n\r\n                if (this.lockMode === ParticleRandomBlockLocks.None || this._currentLockId !== lockId) {\r\n                    if (this.lockMode !== ParticleRandomBlockLocks.None) {\r\n                        this._currentLockId = lockId;\r\n                    }\r\n\r\n                    this.output._storedValue = func!(state);\r\n                }\r\n            }\r\n\r\n            return this.output._storedValue;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.lockMode = this.lockMode;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.lockMode = serializationObject.lockMode;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleRandomBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleRandomBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleRandomBlock\", ParticleRandomBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used to lerp between 2 values\r\n */\r\nexport class ParticleLerpBlock extends NodeParticleBlock {\r\n    /**\r\n     * Creates a new ParticleLerpBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"gradient\", NodeParticleBlockConnectionPointTypes.Float, true, 0, 0, 1);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeParticleBlockConnectionPointTypes.Float |\r\n                NodeParticleBlockConnectionPointTypes.Int |\r\n                NodeParticleBlockConnectionPointTypes.Vector2 |\r\n                NodeParticleBlockConnectionPointTypes.Vector3 |\r\n                NodeParticleBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleLerpBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (gradient: number, left: number, right: number) => {\r\n            return (1 - gradient) * left + gradient * right;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n            const gradient = this.gradient.getConnectedValue(state);\r\n            switch (this.left.type) {\r\n                case NodeParticleBlockConnectionPointTypes.Int:\r\n                case NodeParticleBlockConnectionPointTypes.Float: {\r\n                    return func(gradient, left, right);\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(gradient, left.x, right.x), func(gradient, left.y, right.y));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(gradient, left.x, right.x), func(gradient, left.y, right.y), func(gradient, left.z, right.z));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                    return new Color4(func(gradient, left.r, right.r), func(gradient, left.g, right.g), func(gradient, left.b, right.b), func(gradient, left.a, right.a));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleLerpBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleLerpBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleLerpBlock\", ParticleLerpBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to compute vector length\r\n */\r\nexport class ParticleVectorLengthBlock extends NodeParticleBlock {\r\n    /**\r\n     * Creates a new ParticleVectorLengthBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Float);\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(NodeParticleBlockConnectionPointTypes.Vector2 | NodeParticleBlockConnectionPointTypes.Vector3);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleVectorLengthBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input operand input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        if (!this.input.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const input = this.input.getConnectedValue(state);\r\n            return input.length();\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleVectorLengthBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleVectorLengthBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleVectorLengthBlock\", ParticleVectorLengthBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WithinEpsilon } from \"../../../../Maths/math.scalar.functions\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Conditions supported by the condition block\r\n */\r\nexport enum ParticleConditionBlockTests {\r\n    /** Equal */\r\n    Equal,\r\n    /** NotEqual */\r\n    NotEqual,\r\n    /** LessThan */\r\n    LessThan,\r\n    /** GreaterThan */\r\n    GreaterThan,\r\n    /** LessOrEqual */\r\n    LessOrEqual,\r\n    /** GreaterOrEqual */\r\n    GreaterOrEqual,\r\n    /** Logical Exclusive OR */\r\n    Xor,\r\n    /** Logical Or */\r\n    Or,\r\n    /** Logical And */\r\n    And,\r\n}\r\n\r\n/**\r\n * Block used to evaluate a condition and return a true or false value as a float (1 or 0).\r\n */\r\nexport class ParticleConditionBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the test used by the block\r\n     */\r\n    @editableInPropertyPage(\"Test\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Equal\", value: ParticleConditionBlockTests.Equal },\r\n            { label: \"NotEqual\", value: ParticleConditionBlockTests.NotEqual },\r\n            { label: \"LessThan\", value: ParticleConditionBlockTests.LessThan },\r\n            { label: \"GreaterThan\", value: ParticleConditionBlockTests.GreaterThan },\r\n            { label: \"LessOrEqual\", value: ParticleConditionBlockTests.LessOrEqual },\r\n            { label: \"GreaterOrEqual\", value: ParticleConditionBlockTests.GreaterOrEqual },\r\n            { label: \"Xor\", value: ParticleConditionBlockTests.Xor },\r\n            { label: \"Or\", value: ParticleConditionBlockTests.Or },\r\n            { label: \"And\", value: ParticleConditionBlockTests.And },\r\n        ],\r\n    })\r\n    public test = ParticleConditionBlockTests.Equal;\r\n\r\n    /**\r\n     * Gets or sets the epsilon value used for comparison\r\n     */\r\n    @editableInPropertyPage(\"Epsilon\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public epsilon = 0;\r\n\r\n    /**\r\n     * Create a new ParticleConditionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerInput(\"right\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"ifTrue\", NodeParticleBlockConnectionPointTypes.AutoDetect, true, 1);\r\n        this.registerInput(\"ifFalse\", NodeParticleBlockConnectionPointTypes.AutoDetect, true, 0);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = this._inputs[2];\r\n        this.output._defaultConnectionPointType = NodeParticleBlockConnectionPointTypes.Float;\r\n        this._inputs[0].acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Int);\r\n        this._inputs[1].acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Int);\r\n        this._linkConnectionTypes(2, 3);\r\n\r\n        this._inputs[2].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[3].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleConditionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left input component\r\n     */\r\n    public get left(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right input component\r\n     */\r\n    public get right(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the ifTrue input component\r\n     */\r\n    public get ifTrue(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the ifFalse input component\r\n     */\r\n    public get ifFalse(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        const func = (state: NodeParticleBuildState) => {\r\n            const left = this.left.getConnectedValue(state) as number;\r\n            const right = this.right.getConnectedValue(state) as number;\r\n            let condition = false;\r\n\r\n            switch (this.test) {\r\n                case ParticleConditionBlockTests.Equal:\r\n                    condition = WithinEpsilon(left, right, this.epsilon);\r\n                    break;\r\n                case ParticleConditionBlockTests.NotEqual:\r\n                    condition = !WithinEpsilon(left, right, this.epsilon);\r\n                    break;\r\n                case ParticleConditionBlockTests.LessThan:\r\n                    condition = left < right + this.epsilon;\r\n                    break;\r\n                case ParticleConditionBlockTests.GreaterThan:\r\n                    condition = left > right - this.epsilon;\r\n                    break;\r\n                case ParticleConditionBlockTests.LessOrEqual:\r\n                    condition = left <= right + this.epsilon;\r\n                    break;\r\n                case ParticleConditionBlockTests.GreaterOrEqual:\r\n                    condition = left >= right - this.epsilon;\r\n                    break;\r\n                case ParticleConditionBlockTests.Xor:\r\n                    condition = (!!left && !right) || (!left && !!right);\r\n                    break;\r\n                case ParticleConditionBlockTests.Or:\r\n                    condition = !!left || !!right;\r\n                    break;\r\n                case ParticleConditionBlockTests.And:\r\n                    condition = !!left && !!right;\r\n                    break;\r\n            }\r\n            return condition;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            if (func(state)) {\r\n                return this.ifTrue.getConnectedValue(state);\r\n            }\r\n\r\n            return this.ifFalse.getConnectedValue(state);\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.test = this.test;\r\n        serializationObject.epsilon = this.epsilon;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.test = serializationObject.test;\r\n        if (serializationObject.epsilon !== undefined) {\r\n            this.epsilon = serializationObject.epsilon;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleConditionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleConditionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleConditionBlock\", ParticleConditionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide a flow of particles emitted from a cone shape.\r\n */\r\nexport class ConeShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating if the system should emit only from the spawn point\r\n     * DirectionRandomizer will be used for the particles initial direction unless both direction1 and direction2 are connected.\r\n     */\r\n    @editableInPropertyPage(\"Emit from spawn point only\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public emitFromSpawnPointOnly = false;\r\n\r\n    /**\r\n     * Create a new ConeShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"radius\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"angle\", NodeParticleBlockConnectionPointTypes.Float, true, Math.PI);\r\n        this.registerInput(\"radiusRange\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"heightRange\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"directionRandomizer\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"direction1\", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"direction2\", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ConeShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle input component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the radius input component\r\n     */\r\n    public get radius(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the angle input component\r\n     */\r\n    public get angle(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the radiusRange input component\r\n     */\r\n    public get radiusRange(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the heightRange input component\r\n     */\r\n    public get heightRange(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the directionRandomizer input component\r\n     */\r\n    public get directionRandomizer(): NodeParticleConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction1 input component\r\n     */\r\n    public get direction1(): NodeParticleConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction2 input component\r\n     */\r\n    public get direction2(): NodeParticleConnectionPoint {\r\n        return this._inputs[7];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            // We always use directionRandomizer unless both directions are connected\r\n            if (this.direction1.isConnected === false || this.direction2.isConnected === false) {\r\n                const directionRandomizer = this.directionRandomizer.getConnectedValue(state) as number;\r\n\r\n                const direction = particle.position.subtract(state.emitterPosition!).normalize();\r\n                const randX = RandomRange(0, directionRandomizer);\r\n                const randY = RandomRange(0, directionRandomizer);\r\n                const randZ = RandomRange(0, directionRandomizer);\r\n                direction.x += randX;\r\n                direction.y += randY;\r\n                direction.z += randZ;\r\n                direction.normalize();\r\n\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFromFloats(direction.x, direction.y, direction.z);\r\n                } else {\r\n                    Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n            } else {\r\n                const direction1 = this.direction1.getConnectedValue(state) as Vector3;\r\n                const direction2 = this.direction2.getConnectedValue(state) as Vector3;\r\n\r\n                const randX = RandomRange(direction1.x, direction2.x);\r\n                const randY = RandomRange(direction1.y, direction2.y);\r\n                const randZ = RandomRange(direction1.z, direction2.z);\r\n\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFromFloats(randX, randY, randZ);\r\n                } else {\r\n                    Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            // Connected values\r\n            const radius = this.radius.getConnectedValue(state) as number;\r\n            const angle = this.angle.getConnectedValue(state) as number;\r\n            const radiusRange = this.radiusRange.getConnectedValue(state) as number;\r\n            const heightRange = this.heightRange.getConnectedValue(state) as number;\r\n\r\n            // Calculate position creation logic\r\n            let h: number;\r\n            if (!this.emitFromSpawnPointOnly) {\r\n                h = RandomRange(0, heightRange);\r\n                // Better distribution in a cone at normal angles.\r\n                h = 1 - h * h;\r\n            } else {\r\n                h = 0.0001;\r\n            }\r\n\r\n            let newRadius = radius - RandomRange(0, radius * radiusRange);\r\n            newRadius = newRadius * h;\r\n            const s = RandomRange(0, Math.PI * 2);\r\n\r\n            const randX = newRadius * Math.sin(s);\r\n            const randZ = newRadius * Math.cos(s);\r\n            const randY = h * this._calculateHeight(angle, radius);\r\n\r\n            if (system.isLocal) {\r\n                particle.position.copyFromFloats(randX, randY, randZ);\r\n            } else {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n\r\n    private _calculateHeight(angle: number, radius: number): number {\r\n        if (angle !== 0) {\r\n            return radius / Math.tan(angle / 2);\r\n        } else {\r\n            return 1;\r\n        }\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.emitFromSpawnPointOnly = this.emitFromSpawnPointOnly;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.emitFromSpawnPointOnly = serializationObject.emitFromSpawnPointOnly;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for coneShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterConeShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ConeShapeBlock\", ConeShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\n\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide a flow of particles emitted from a cylinder shape.\r\n * DirectionRandomizer will be used for the particles initial direction unless both direction1 and direction2 are connected.\r\n */\r\nexport class CylinderShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    private _tempVector = Vector3.Zero();\r\n    /**\r\n     * Create a new CylinderShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"radius\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"height\", NodeParticleBlockConnectionPointTypes.Float, true, 1, 0);\r\n        this.registerInput(\"radiusRange\", NodeParticleBlockConnectionPointTypes.Float, true, 1, 0, 1);\r\n        this.registerInput(\"directionRandomizer\", NodeParticleBlockConnectionPointTypes.Float, true, 0, 0, 1);\r\n        this.registerInput(\"direction1\", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"direction2\", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CylinderShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the radius input component\r\n     */\r\n    public get radius(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the height input component\r\n     */\r\n    public get height(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the radiusRange input component\r\n     */\r\n    public get radiusRange(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the directionRandomizer input component\r\n     */\r\n    public get directionRandomizer(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction1 input component\r\n     */\r\n    public get direction1(): NodeParticleConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction2 input component\r\n     */\r\n    public get direction2(): NodeParticleConnectionPoint {\r\n        return this._inputs[6];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            // We always use directionRandomizer unless both directions are connected\r\n            if (this.direction1.isConnected === false || this.direction2.isConnected === false) {\r\n                const directionRandomizer = this.directionRandomizer.getConnectedValue(state) as number;\r\n\r\n                particle.position.subtractToRef(state.emitterPosition!, this._tempVector);\r\n                this._tempVector.normalize();\r\n\r\n                if (state.emitterInverseWorldMatrix) {\r\n                    Vector3.TransformNormalToRef(this._tempVector, state.emitterInverseWorldMatrix, this._tempVector);\r\n                }\r\n\r\n                const randY = RandomRange(-directionRandomizer / 2, directionRandomizer / 2);\r\n\r\n                let angle = Math.atan2(this._tempVector.x, this._tempVector.z);\r\n                angle += RandomRange(-Math.PI / 2, Math.PI / 2) * directionRandomizer;\r\n\r\n                this._tempVector.y = randY; // set direction y to rand y to mirror normal of cylinder surface\r\n                this._tempVector.x = Math.sin(angle);\r\n                this._tempVector.z = Math.cos(angle);\r\n                this._tempVector.normalize();\r\n\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFrom(this._tempVector);\r\n                } else {\r\n                    Vector3.TransformNormalFromFloatsToRef(this._tempVector.x, this._tempVector.y, this._tempVector.z, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n            } else {\r\n                const direction1 = this.direction1.getConnectedValue(state) as Vector3;\r\n                const direction2 = this.direction2.getConnectedValue(state) as Vector3;\r\n\r\n                const randX = RandomRange(direction1.x, direction2.x);\r\n                const randY = RandomRange(direction1.y, direction2.y);\r\n                const randZ = RandomRange(direction1.z, direction2.z);\r\n\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFromFloats(randX, randY, randZ);\r\n                } else {\r\n                    Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const height = this.height.getConnectedValue(state) as number;\r\n            const radiusRange = this.radiusRange.getConnectedValue(state) as number;\r\n            const radius = this.radius.getConnectedValue(state) as number;\r\n\r\n            const yPos = RandomRange(-height / 2, height / 2);\r\n            const angle = RandomRange(0, 2 * Math.PI);\r\n\r\n            // Pick a properly distributed point within the circle https://programming.guide/random-point-within-circle.html\r\n            const radiusDistribution = RandomRange((1 - radiusRange) * (1 - radiusRange), 1);\r\n            const positionRadius = Math.sqrt(radiusDistribution) * radius;\r\n            const xPos = positionRadius * Math.cos(angle);\r\n            const zPos = positionRadius * Math.sin(angle);\r\n\r\n            if (system.isLocal) {\r\n                particle.position.copyFromFloats(xPos, yPos, zPos);\r\n            } else {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(xPos, yPos, zPos, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for cylinderShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCylinderShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CylinderShapeBlock\", CylinderShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\n\r\nimport { TmpVectors, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { EmptyGeneratorFunc } from \"core/Particles/EmitterTypes/customParticleEmitter\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/** Function that generates particle position/direction data */\r\ntype ParticleGeneratorFunction = (index: number, particle: Nullable<Particle>, outPosition: Vector3) => void;\r\n\r\n/**\r\n * Block used to provide a flow of particles emitted from a custom position.\r\n */\r\nexport class CustomShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    /** The particle position generator function */\r\n    public particlePositionGenerator: ParticleGeneratorFunction = EmptyGeneratorFunc;\r\n    /** The particle destination generator function */\r\n    public particleDestinationGenerator: ParticleGeneratorFunction = EmptyGeneratorFunc;\r\n    /** The particle direction generator function */\r\n    public particleDirectionGenerator: ParticleGeneratorFunction = EmptyGeneratorFunc;\r\n\r\n    /**\r\n     * Create a new CustomShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"CustomShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const tmpVector = TmpVectors.Vector3[0];\r\n\r\n            if (this.particleDirectionGenerator && this.particleDirectionGenerator !== EmptyGeneratorFunc) {\r\n                this.particleDirectionGenerator(-1, particle, tmpVector);\r\n            } else if (this.particleDestinationGenerator && this.particleDestinationGenerator !== EmptyGeneratorFunc) {\r\n                this.particleDestinationGenerator(-1, particle, tmpVector);\r\n\r\n                // Get direction\r\n                const diffVector = TmpVectors.Vector3[1];\r\n                tmpVector.subtractToRef(particle.position, diffVector);\r\n\r\n                diffVector.scaleToRef(1 / particle.lifeTime, tmpVector);\r\n            } else {\r\n                tmpVector.set(0, 0, 0);\r\n            }\r\n\r\n            if (system.isLocal) {\r\n                particle.direction.copyFrom(tmpVector);\r\n            } else {\r\n                Vector3.TransformNormalToRef(tmpVector, state.emitterWorldMatrix!, particle.direction);\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const tmpVector = TmpVectors.Vector3[0];\r\n\r\n            if (this.particlePositionGenerator && this.particlePositionGenerator !== EmptyGeneratorFunc) {\r\n                this.particlePositionGenerator(-1, particle, tmpVector);\r\n            } else {\r\n                tmpVector.set(0, 0, 0);\r\n            }\r\n\r\n            if (system.isLocal) {\r\n                particle.position.copyFrom(tmpVector);\r\n            } else {\r\n                Vector3.TransformCoordinatesToRef(tmpVector, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for customShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCustomShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CustomShapeBlock\", CustomShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FloatArray, type IndicesArray, type Nullable } from \"core/types\";\r\nimport { type Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\n\r\nimport { VertexData } from \"core/Meshes/mesh.vertexData\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"core/Decorators/nodeDecorator\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { TmpVectors, Vector3, Vector4 } from \"core/Maths/math.vector.pure\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to generate particle shape from mesh geometry data\r\n */\r\nexport class MeshShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    private _mesh: Nullable<Mesh>;\r\n    private _cachedVertexData: Nullable<VertexData> = null;\r\n    private _indices: Nullable<IndicesArray> = null;\r\n    private _positions: Nullable<FloatArray> = null;\r\n    private _normals: Nullable<FloatArray> = null;\r\n    private _colors: Nullable<FloatArray> = null;\r\n    private _storedNormal = Vector3.Zero();\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that this block should serialize its cached data\r\n     */\r\n    @editableInPropertyPage(\"Serialize cached data\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public serializedCachedData = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mesh normals should be used for particle direction\r\n     */\r\n    @editableInPropertyPage(\"Use normals for direction\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public useMeshNormalsForDirection = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the mesh colors should be used for particle color\r\n     */\r\n    @editableInPropertyPage(\"Use vertex color for color\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public useMeshColorForColor = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the coordinates should be in world space (local space by default)\r\n     */\r\n    @editableInPropertyPage(\"World space\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public worldSpace = false;\r\n\r\n    /**\r\n     * Gets or sets the mesh to use to get vertex data\r\n     */\r\n    public get mesh() {\r\n        return this._mesh;\r\n    }\r\n\r\n    public set mesh(value: Nullable<Mesh>) {\r\n        this._mesh = value;\r\n    }\r\n\r\n    /**\r\n     * Create a new MeshShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"direction1\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0, 1.0, 0));\r\n        this.registerInput(\"direction2\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0, 1.0, 0));\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"MeshShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating if the block is using cached data\r\n     */\r\n    public get isUsingCachedData() {\r\n        return !this.mesh && !!this._cachedVertexData;\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction1 input component\r\n     */\r\n    public get direction1(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction2 input component\r\n     */\r\n    public get direction2(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Remove stored data\r\n     */\r\n    public cleanData() {\r\n        this._mesh = null;\r\n        this._cachedVertexData = null;\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        if (!this._mesh && !this._cachedVertexData) {\r\n            this.output._storedValue = system;\r\n            return;\r\n        }\r\n\r\n        if (this._mesh) {\r\n            this._cachedVertexData = VertexData.ExtractFromMesh(this._mesh, false, true);\r\n        }\r\n\r\n        if (!this._cachedVertexData) {\r\n            this.output._storedValue = system;\r\n            return;\r\n        }\r\n\r\n        this._indices = this._cachedVertexData.indices;\r\n        this._positions = this._cachedVertexData.positions;\r\n        this._normals = this._cachedVertexData.normals;\r\n        this._colors = this._cachedVertexData.colors;\r\n\r\n        if (this.useMeshColorForColor && this._colors) {\r\n            system._colorCreation.process = () => {};\r\n        }\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            if (this.useMeshNormalsForDirection && this._normals) {\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFrom(this._storedNormal);\r\n                } else {\r\n                    Vector3.TransformNormalToRef(this._storedNormal, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n                return;\r\n            }\r\n\r\n            const direction1 = this.direction1.getConnectedValue(state) as Vector3;\r\n            const direction2 = this.direction2.getConnectedValue(state) as Vector3;\r\n\r\n            const randX = RandomRange(direction1.x, direction2.x);\r\n            const randY = RandomRange(direction1.y, direction2.y);\r\n            const randZ = RandomRange(direction1.z, direction2.z);\r\n\r\n            if (system.isLocal) {\r\n                particle.direction.copyFromFloats(randX, randY, randZ);\r\n            } else {\r\n                Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.direction);\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            if (!this._indices || !this._positions) {\r\n                return;\r\n            }\r\n\r\n            const randomFaceIndex = 3 * ((Math.random() * (this._indices.length / 3)) | 0);\r\n            const bu = Math.random();\r\n            const bv = Math.random() * (1.0 - bu);\r\n            const bw = 1.0 - bu - bv;\r\n\r\n            const faceIndexA = this._indices[randomFaceIndex];\r\n            const faceIndexB = this._indices[randomFaceIndex + 1];\r\n            const faceIndexC = this._indices[randomFaceIndex + 2];\r\n            const vertexA = TmpVectors.Vector3[0];\r\n            const vertexB = TmpVectors.Vector3[1];\r\n            const vertexC = TmpVectors.Vector3[2];\r\n            const randomVertex = TmpVectors.Vector3[3];\r\n\r\n            Vector3.FromArrayToRef(this._positions, faceIndexA * 3, vertexA);\r\n            Vector3.FromArrayToRef(this._positions, faceIndexB * 3, vertexB);\r\n            Vector3.FromArrayToRef(this._positions, faceIndexC * 3, vertexC);\r\n\r\n            randomVertex.x = bu * vertexA.x + bv * vertexB.x + bw * vertexC.x;\r\n            randomVertex.y = bu * vertexA.y + bv * vertexB.y + bw * vertexC.y;\r\n            randomVertex.z = bu * vertexA.z + bv * vertexB.z + bw * vertexC.z;\r\n\r\n            if (this.worldSpace && this.mesh) {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, this.mesh.getWorldMatrix(), randomVertex);\r\n            }\r\n\r\n            if (system.isLocal) {\r\n                particle.position.copyFromFloats(randomVertex.x, randomVertex.y, randomVertex.z);\r\n            } else {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n\r\n            if (this.useMeshNormalsForDirection && this._normals) {\r\n                Vector3.FromArrayToRef(this._normals, faceIndexA * 3, vertexA);\r\n                Vector3.FromArrayToRef(this._normals, faceIndexB * 3, vertexB);\r\n                Vector3.FromArrayToRef(this._normals, faceIndexC * 3, vertexC);\r\n\r\n                this._storedNormal.x = bu * vertexA.x + bv * vertexB.x + bw * vertexC.x;\r\n                this._storedNormal.y = bu * vertexA.y + bv * vertexB.y + bw * vertexC.y;\r\n                this._storedNormal.z = bu * vertexA.z + bv * vertexB.z + bw * vertexC.z;\r\n            }\r\n\r\n            if (this.useMeshColorForColor && this._colors) {\r\n                Vector4.FromArrayToRef(this._colors, faceIndexA * 4, TmpVectors.Vector4[0]);\r\n                Vector4.FromArrayToRef(this._colors, faceIndexB * 4, TmpVectors.Vector4[1]);\r\n                Vector4.FromArrayToRef(this._colors, faceIndexC * 4, TmpVectors.Vector4[2]);\r\n\r\n                particle.color.copyFromFloats(\r\n                    bu * TmpVectors.Vector4[0].x + bv * TmpVectors.Vector4[1].x + bw * TmpVectors.Vector4[2].x,\r\n                    bu * TmpVectors.Vector4[0].y + bv * TmpVectors.Vector4[1].y + bw * TmpVectors.Vector4[2].y,\r\n                    bu * TmpVectors.Vector4[0].z + bv * TmpVectors.Vector4[1].z + bw * TmpVectors.Vector4[2].z,\r\n                    bu * TmpVectors.Vector4[0].w + bv * TmpVectors.Vector4[1].w + bw * TmpVectors.Vector4[2].w\r\n                );\r\n            }\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n        serializationObject.serializedCachedData = this.serializedCachedData;\r\n\r\n        if (this.serializedCachedData) {\r\n            if (this._mesh) {\r\n                serializationObject.cachedVertexData = VertexData.ExtractFromMesh(this._mesh, false, true).serialize();\r\n            } else if (this._cachedVertexData) {\r\n                serializationObject.cachedVertexData = this._cachedVertexData.serialize();\r\n            }\r\n        }\r\n\r\n        serializationObject.useMeshNormalsForDirection = this.useMeshNormalsForDirection;\r\n        serializationObject.useMeshColorForColor = this.useMeshColorForColor;\r\n        serializationObject.worldSpace = this.worldSpace;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.cachedVertexData) {\r\n            this._cachedVertexData = VertexData.Parse(serializationObject.cachedVertexData);\r\n        }\r\n\r\n        this.serializedCachedData = !!serializationObject.serializedCachedData;\r\n        this.useMeshNormalsForDirection = !!serializationObject.useMeshNormalsForDirection;\r\n        this.useMeshColorForColor = !!serializationObject.useMeshColorForColor;\r\n        this.worldSpace = !!serializationObject.worldSpace;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for meshShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMeshShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MeshShapeBlock\", MeshShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide a flow of particles emitted from a point.\r\n */\r\nexport class PointShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    /**\r\n     * Create a new PointShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"direction1\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0, 1.0, 0));\r\n        this.registerInput(\"direction2\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(0, 1.0, 0));\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"PointShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction1 input component\r\n     */\r\n    public get direction1(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction2 input component\r\n     */\r\n    public get direction2(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const direction1 = this.direction1.getConnectedValue(state) as Vector3;\r\n            const direction2 = this.direction2.getConnectedValue(state) as Vector3;\r\n\r\n            const randX = RandomRange(direction1.x, direction2.x);\r\n            const randY = RandomRange(direction1.y, direction2.y);\r\n            const randZ = RandomRange(direction1.z, direction2.z);\r\n\r\n            if (system.isLocal) {\r\n                particle.direction.copyFromFloats(randX, randY, randZ);\r\n            } else {\r\n                Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.direction);\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.systemContext = system;\r\n            if (system.isLocal) {\r\n                particle.position.copyFromFloats(0, 0, 0);\r\n            } else {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(0, 0, 0, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for pointShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPointShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.PointShapeBlock\", PointShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ParticleSystem } from \"core/Particles\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * Block used as configure the sprite sheet for particles\r\n */\r\nexport class SetupSpriteSheetBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the start cell of the sprite sheet\r\n     */\r\n    @editableInPropertyPage(\"Start\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public start = 0;\r\n\r\n    /**\r\n     * Gets or sets the end cell of the sprite sheet\r\n     */\r\n    @editableInPropertyPage(\"End\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public end = 8;\r\n\r\n    /**\r\n     * Gets or sets the width of the sprite sheet\r\n     */\r\n    @editableInPropertyPage(\"Width\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public width = 64;\r\n\r\n    /**\r\n     * Gets or sets the height of the sprite sheet\r\n     */\r\n    @editableInPropertyPage(\"Height\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public height = 64;\r\n\r\n    /**\r\n     * Gets or sets the speed of the cell change\r\n     */\r\n    @editableInPropertyPage(\"Sprite Cell Change Speed\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public spriteCellChangeSpeed = 1;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the sprite sheet should loop\r\n     */\r\n    @editableInPropertyPage(\"Loop\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public loop = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the sprite sheet should start at a random cell\r\n     */\r\n    @editableInPropertyPage(\"Random start cell\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public randomStartCell = false;\r\n\r\n    /**\r\n     * Creates a new SetupSpriteSheetBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SetupSpriteSheetBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        super._build(state);\r\n\r\n        const system = this.particle.getConnectedValue(state) as ParticleSystem;\r\n\r\n        system._isAnimationSheetEnabled = true;\r\n        system.spriteCellWidth = this.width;\r\n        system.spriteCellHeight = this.height;\r\n        system.startSpriteCellID = this.start;\r\n        system.endSpriteCellID = this.end;\r\n        system.spriteCellLoop = this.loop;\r\n        system.spriteRandomStartCell = this.randomStartCell;\r\n        system.spriteCellChangeSpeed = this.spriteCellChangeSpeed;\r\n        this.output._storedValue = system;\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.width = this.width;\r\n        serializationObject.height = this.height;\r\n        serializationObject.start = this.start;\r\n        serializationObject.end = this.end;\r\n        serializationObject.spriteCellChangeSpeed = this.spriteCellChangeSpeed;\r\n        serializationObject.loop = this.loop;\r\n        serializationObject.randomStartCell = this.randomStartCell;\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.width = serializationObject.width;\r\n        this.height = serializationObject.height;\r\n        this.start = serializationObject.start;\r\n        this.end = serializationObject.end;\r\n        this.spriteCellChangeSpeed = serializationObject.spriteCellChangeSpeed;\r\n        this.loop = serializationObject.loop;\r\n        this.randomStartCell = serializationObject.randomStartCell;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for setupSpriteSheetBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSetupSpriteSheetBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SetupSpriteSheetBlock\", SetupSpriteSheetBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type IShapeBlock } from \"./IShapeBlock\";\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { RandomRange } from \"core/Maths/math.scalar.functions\";\r\nimport { _CreateLocalPositionData } from \"./emitters.functions\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide a flow of particles emitted from a sphere shape.\r\n * DirectionRandomizer will be used for the particles initial direction unless both direction1 and direction2 are connected.\r\n */\r\nexport class SphereShapeBlock extends NodeParticleBlock implements IShapeBlock {\r\n    /**\r\n     * Gets or sets a boolean indicating whether to emit in a hemispheric mode (top half of the sphere) or not\r\n     */\r\n    @editableInPropertyPage(\"Is hemispheric\", PropertyTypeForEdition.Boolean, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true } })\r\n    public isHemispheric = false;\r\n\r\n    /**\r\n     * Create a new SphereShapeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"radius\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerInput(\"radiusRange\", NodeParticleBlockConnectionPointTypes.Float, true, 1, 0, 1);\r\n        this.registerInput(\"directionRandomizer\", NodeParticleBlockConnectionPointTypes.Float, true, 0, 0, 1);\r\n        this.registerInput(\"direction1\", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerInput(\"direction2\", NodeParticleBlockConnectionPointTypes.Vector3, true);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"SphereShapeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the radius input component\r\n     */\r\n    public get radius(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the radiusRange input component\r\n     */\r\n    public get radiusRange(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the directionRandomizer input component\r\n     */\r\n    public get directionRandomizer(): NodeParticleConnectionPoint {\r\n        return this._inputs[3];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction1 input component\r\n     */\r\n    public get direction1(): NodeParticleConnectionPoint {\r\n        return this._inputs[4];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction2 input component\r\n     */\r\n    public get direction2(): NodeParticleConnectionPoint {\r\n        return this._inputs[5];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state);\r\n\r\n        system._directionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            // We always use directionRandomizer unless both directions are connected\r\n            if (this.direction1.isConnected === false || this.direction2.isConnected === false) {\r\n                const directionRandomizer = this.directionRandomizer.getConnectedValue(state) as number;\r\n\r\n                const direction = particle.position.subtract(state.emitterPosition!).normalize();\r\n                const randX = RandomRange(0, directionRandomizer);\r\n                const randY = RandomRange(0, directionRandomizer);\r\n                const randZ = RandomRange(0, directionRandomizer);\r\n                direction.x += randX;\r\n                direction.y += randY;\r\n                direction.z += randZ;\r\n                direction.normalize();\r\n\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFromFloats(direction.x, direction.y, direction.z);\r\n                } else {\r\n                    Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n            } else {\r\n                const direction1 = this.direction1.getConnectedValue(state) as Vector3;\r\n                const direction2 = this.direction2.getConnectedValue(state) as Vector3;\r\n\r\n                const randX = RandomRange(direction1.x, direction2.x);\r\n                const randY = RandomRange(direction1.y, direction2.y);\r\n                const randZ = RandomRange(direction1.z, direction2.z);\r\n\r\n                if (system.isLocal) {\r\n                    particle.direction.copyFromFloats(randX, randY, randZ);\r\n                } else {\r\n                    Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.direction);\r\n                }\r\n            }\r\n\r\n            particle._properties.initialDirection = particle.direction.clone();\r\n        };\r\n\r\n        system._positionCreation.process = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            const radius = this.radius.getConnectedValue(state) as number;\r\n            const radiusRange = this.radiusRange.getConnectedValue(state) as number;\r\n\r\n            const randRadius = radius - RandomRange(0, radius * radiusRange);\r\n            const v = RandomRange(0, 1.0);\r\n            const phi = RandomRange(0, 2 * Math.PI);\r\n            const theta = Math.acos(2 * v - 1);\r\n            const randX = randRadius * Math.cos(phi) * Math.sin(theta);\r\n            let randY = randRadius * Math.cos(theta);\r\n            const randZ = randRadius * Math.sin(phi) * Math.sin(theta);\r\n\r\n            if (this.isHemispheric) {\r\n                randY = Math.abs(randY);\r\n            }\r\n\r\n            if (system.isLocal) {\r\n                particle.position.copyFromFloats(randX, randY, randZ);\r\n            } else {\r\n                Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, state.emitterWorldMatrix!, particle.position);\r\n            }\r\n\r\n            _CreateLocalPositionData(particle);\r\n        };\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.isHemispheric = this.isHemispheric;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.isHemispheric = serializationObject.isHemispheric;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sphereShapeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSphereShapeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SphereShapeBlock\", SphereShapeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the angle of a particle\r\n */\r\nexport class UpdateAngleBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateAngleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"angle\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the angle input component\r\n     */\r\n    public get angle(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateAngleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.angle.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processAngle = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.angle = this.angle.getConnectedValue(state);\r\n        };\r\n\r\n        const angleProcessing = {\r\n            process: processAngle,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(angleProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = angleProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateAngleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateAngleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateAngleBlock\", UpdateAngleBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide the basic update functionality for particle sprite index.\r\n */\r\nexport class BasicSpriteUpdateBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new BasicSpriteUpdateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BasicSpriteUpdateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        const processSprite = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.updateCellIndex();\r\n        };\r\n\r\n        const spriteProcessing = {\r\n            process: processSprite,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(spriteProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = spriteProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for basicSpriteUpdateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBasicSpriteUpdateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BasicSpriteUpdateBlock\", BasicSpriteUpdateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\nconst ToAttractor: Vector3 = /*#__PURE__*/ Vector3.Zero();\r\nconst Force: Vector3 = /*#__PURE__*/ Vector3.Zero();\r\nconst ScaledForce: Vector3 = /*#__PURE__*/ Vector3.Zero();\r\n\r\n/**\r\n * Block used to update particle position based on an attractor\r\n */\r\nexport class UpdateAttractorBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateAttractorBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"attractor\", NodeParticleBlockConnectionPointTypes.Vector3, true, Vector3.Zero());\r\n        this.registerInput(\"strength\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the attractor input component\r\n     */\r\n    public get attractor(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the strength input component\r\n     */\r\n    public get strength(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateAttractorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        const processAttractor = (particle: Particle) => {\r\n            const attractorPosition = this.attractor.getConnectedValue(state) as Vector3;\r\n            const strength = this.strength.getConnectedValue(state) as number;\r\n            attractorPosition.subtractToRef(particle.position, ToAttractor);\r\n            const distanceSquared = ToAttractor.lengthSquared() + 1; // Avoid going under 1.0\r\n            ToAttractor.normalize().scaleToRef(strength / distanceSquared, Force);\r\n\r\n            Force.scaleToRef(system._tempScaledUpdateSpeed, ScaledForce);\r\n\r\n            particle.direction.addInPlace(ScaledForce); // Update particle velocity\r\n        };\r\n\r\n        const attractorProcessing = {\r\n            process: processAttractor,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(attractorProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = attractorProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateAttractorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateAttractorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateAttractorBlock\", UpdateAttractorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { type Color4 } from \"core/Maths\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the color of a particle\r\n */\r\nexport class UpdateColorBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateColorBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"color\", NodeParticleBlockConnectionPointTypes.Color4);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the color input component\r\n     */\r\n    public get color(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateColorBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.color.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processColor = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.color.copyFrom(this.color.getConnectedValue(state) as Color4);\r\n        };\r\n\r\n        const colorProcessing = {\r\n            process: processColor,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(colorProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = colorProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateColorBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateColorBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateColorBlock\", UpdateColorBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the direction of a particle\r\n */\r\nexport class UpdateDirectionBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateDirectionBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"direction\", NodeParticleBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the direction input component\r\n     */\r\n    public get direction(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateDirectionBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.direction.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processDirection = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.direction.copyFrom(this.direction.getConnectedValue(state) as Vector3);\r\n        };\r\n\r\n        const directionProcessing = {\r\n            process: processDirection,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(directionProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = directionProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateDirectionBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateDirectionBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateDirectionBlock\", UpdateDirectionBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type INodeParticleTextureData, type ParticleTextureSourceBlock } from \"../particleSourceTextureBlock.pure\";\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { FlowMap } from \"core/Particles/flowMap\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update particle position based on a flow map\r\n */\r\nexport class UpdateFlowMapBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateFlowMapBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"flowMap\", NodeParticleBlockConnectionPointTypes.Texture);\r\n        this.registerInput(\"strength\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the flowMap input component\r\n     */\r\n    public get flowMap(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the strength input component\r\n     */\r\n    public get strength(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateFlowMapBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n        const scene = state.scene;\r\n\r\n        const flowMapTexture = this.flowMap.connectedPoint?.ownerBlock as Nullable<ParticleTextureSourceBlock>;\r\n        let flowMap: Nullable<FlowMap> = null;\r\n\r\n        if (flowMapTexture) {\r\n            state.registerBuildPromise(\r\n                (async () => {\r\n                    let textureContent: Nullable<INodeParticleTextureData>;\r\n                    try {\r\n                        textureContent = await flowMapTexture.extractTextureContentAsync();\r\n                    } catch {\r\n                        return;\r\n                    }\r\n                    if (!textureContent) {\r\n                        return;\r\n                    }\r\n                    flowMap = new FlowMap(textureContent.width, textureContent.height, textureContent.data as Uint8ClampedArray);\r\n                })()\r\n            );\r\n        }\r\n\r\n        const processFlowMap = (particle: Particle) => {\r\n            if (!flowMap) {\r\n                return;\r\n            }\r\n            const matrix = scene.getTransformMatrix();\r\n            const strength = this.strength.getConnectedValue(state) as number;\r\n            flowMap._processParticle(particle, strength * system._tempScaledUpdateSpeed, matrix);\r\n        };\r\n\r\n        const flowMapProcessing = {\r\n            process: processFlowMap,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(flowMapProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = flowMapProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateFlowMapBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateFlowMapBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateFlowMapBlock\", UpdateFlowMapBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type ISize } from \"core/Maths/math.size\";\r\nimport { type ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\nimport { type ParticleTextureSourceBlock } from \"core/Particles/Node/Blocks/particleSourceTextureBlock.pure\";\r\n\r\nimport { TmpVectors, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update particle position based on a noise texture\r\n */\r\nexport class UpdateNoiseBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateNoiseBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"noiseTexture\", NodeParticleBlockConnectionPointTypes.Texture);\r\n        this.registerInput(\"strength\", NodeParticleBlockConnectionPointTypes.Vector3, true, new Vector3(100, 100, 100));\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the noiseTexture input component\r\n     */\r\n    public get noiseTexture(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the strength input component\r\n     */\r\n    public get strength(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateNoiseBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        const strength = this.strength.getConnectedValue(state) as Vector3;\r\n        if (!strength) {\r\n            return;\r\n        }\r\n\r\n        const noiseTextureBlock = this.noiseTexture.connectedPoint?.ownerBlock as ParticleTextureSourceBlock;\r\n        if (!noiseTextureBlock) {\r\n            return;\r\n        }\r\n\r\n        // These will be updated each frame for procedural textures\r\n        let noiseTextureData: Nullable<Uint8Array | Uint8ClampedArray> = null;\r\n        let noiseTextureSize: Nullable<ISize> = null;\r\n        let lastFrameId = -1;\r\n\r\n        state.registerBuildPromise(\r\n            (async () => {\r\n                try {\r\n                    const textureContent = await noiseTextureBlock.extractTextureContentAsync();\r\n                    if (!textureContent) {\r\n                        return;\r\n                    }\r\n                    noiseTextureData = textureContent.data;\r\n                    noiseTextureSize = { width: textureContent.width, height: textureContent.height };\r\n                    lastFrameId = (noiseTextureBlock.textureOutput._storedValue as ProceduralTexture)?.getScene?.()?.getFrameId() ?? -1;\r\n                } catch {\r\n                    return;\r\n                }\r\n            })()\r\n        );\r\n\r\n        const processNoise = (particle: Particle) => {\r\n            // Get the texture directly from the block's stored value to support procedural textures\r\n            // (as the block caches the texture data)\r\n            const texture = noiseTextureBlock.textureOutput._storedValue as ProceduralTexture;\r\n            if (!texture || !texture.isReady()) {\r\n                return;\r\n            }\r\n\r\n            // Fetch fresh texture data once per frame (like in thinParticleSystem)\r\n            const currentFrameId = texture.getScene()?.getFrameId() ?? -1;\r\n            if (currentFrameId !== lastFrameId) {\r\n                lastFrameId = currentFrameId;\r\n\r\n                // Texture size only needs to be fetched once\r\n                if (!noiseTextureSize) {\r\n                    noiseTextureSize = texture.getSize();\r\n                }\r\n\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                texture.getContent()?.then((data) => {\r\n                    noiseTextureData = data as Uint8Array;\r\n                });\r\n            }\r\n\r\n            // Skip if we don't have texture data yet\r\n            if (!noiseTextureData || !noiseTextureSize) {\r\n                return;\r\n            }\r\n\r\n            if (!particle._properties.randomNoiseCoordinates1) {\r\n                particle._properties.randomNoiseCoordinates1 = new Vector3(Math.random(), Math.random(), Math.random());\r\n            }\r\n\r\n            if (!particle._properties.randomNoiseCoordinates2) {\r\n                particle._properties.randomNoiseCoordinates2 = new Vector3(Math.random(), Math.random(), Math.random());\r\n            }\r\n\r\n            const fetchedColorR = system._fetchR(\r\n                particle._properties.randomNoiseCoordinates1.x,\r\n                particle._properties.randomNoiseCoordinates1.y,\r\n                noiseTextureSize.width,\r\n                noiseTextureSize.height,\r\n                noiseTextureData\r\n            );\r\n            const fetchedColorG = system._fetchR(\r\n                particle._properties.randomNoiseCoordinates1.z,\r\n                particle._properties.randomNoiseCoordinates2.x,\r\n                noiseTextureSize.width,\r\n                noiseTextureSize.height,\r\n                noiseTextureData\r\n            );\r\n            const fetchedColorB = system._fetchR(\r\n                particle._properties.randomNoiseCoordinates2.y,\r\n                particle._properties.randomNoiseCoordinates2.z,\r\n                noiseTextureSize.width,\r\n                noiseTextureSize.height,\r\n                noiseTextureData\r\n            );\r\n\r\n            const force = TmpVectors.Vector3[0];\r\n            const scaledForce = TmpVectors.Vector3[1];\r\n\r\n            force.copyFromFloats((2 * fetchedColorR - 1) * strength.x, (2 * fetchedColorG - 1) * strength.y, (2 * fetchedColorB - 1) * strength.z);\r\n\r\n            force.scaleToRef(system._tempScaledUpdateSpeed, scaledForce);\r\n            particle.direction.addInPlace(scaledForce);\r\n        };\r\n\r\n        const noiseProcessing = {\r\n            process: processNoise,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(noiseProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = noiseProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateNoiseBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateNoiseBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateNoiseBlock\", UpdateNoiseBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"core/Particles/Node/nodeParticleBuildState\";\r\n\r\nimport { NodeParticleBlock } from \"core/Particles/Node/nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the size of a particle\r\n */\r\nexport class UpdateSizeBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateSizeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"size\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the size input component\r\n     */\r\n    public get size(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateSizeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.size.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processSize = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.size = this.size.getConnectedValue(state) as number;\r\n        };\r\n\r\n        const sizeProcessing = {\r\n            process: processSize,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(sizeProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = sizeProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateSizeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateSizeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateSizeBlock\", UpdateSizeBlock);\r\n}\r\n","import { type Attractor } from \"../attractor\";\r\nimport { type FlowMap } from \"../flowMap\";\r\nimport { type Color4 } from \"core/Maths/math.color\";\r\nimport { type ColorGradient } from \"core/Misc\";\r\nimport { type FactorGradient } from \"core/Misc/gradients\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { type ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\nimport { type Mesh } from \"core/Meshes/mesh\";\r\nimport { type ParticleSystem } from \"core/Particles/particleSystem\";\r\nimport { type IParticleSystem } from \"core/Particles/IParticleSystem\";\r\nimport { type BoxParticleEmitter } from \"core/Particles/EmitterTypes/boxParticleEmitter\";\r\nimport { type ConeDirectedParticleEmitter, type ConeParticleEmitter } from \"core/Particles/EmitterTypes/coneParticleEmitter\";\r\nimport { type CustomParticleEmitter } from \"core/Particles/EmitterTypes/customParticleEmitter\";\r\nimport { type CylinderDirectedParticleEmitter, type CylinderParticleEmitter } from \"core/Particles/EmitterTypes/cylinderParticleEmitter\";\r\nimport { type HemisphericParticleEmitter } from \"core/Particles/EmitterTypes/hemisphericParticleEmitter\";\r\nimport { type MeshParticleEmitter } from \"core/Particles/EmitterTypes/meshParticleEmitter\";\r\nimport { type PointParticleEmitter } from \"core/Particles/EmitterTypes/pointParticleEmitter\";\r\nimport { type SphereDirectedParticleEmitter, type SphereParticleEmitter } from \"core/Particles/EmitterTypes/sphereParticleEmitter\";\r\nimport { type NodeParticleConnectionPoint } from \"core/Particles/Node/nodeParticleBlockConnectionPoint\";\r\nimport { type IShapeBlock } from \"core/Particles/Node/Blocks/Emitters/IShapeBlock\";\r\nimport { type NodeParticleBlockConnectionPointTypes } from \"core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes\";\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleSystemSet } from \"./nodeParticleSystemSet\";\r\nimport { NodeParticleContextualSources } from \"./Enums/nodeParticleContextualSources\";\r\nimport { NodeParticleSystemSources } from \"./Enums/nodeParticleSystemSources\";\r\nimport { ParticleConverterBlock } from \"./Blocks/particleConverterBlock.pure\";\r\nimport { ParticleFloatToIntBlock, ParticleFloatToIntBlockOperations } from \"./Blocks/particleFloatToIntBlock.pure\";\r\nimport { ParticleGradientBlock } from \"./Blocks/particleGradientBlock.pure\";\r\nimport { ParticleGradientValueBlock } from \"./Blocks/particleGradientValueBlock.pure\";\r\nimport { ParticleInputBlock } from \"./Blocks/particleInputBlock.pure\";\r\nimport { ParticleMathBlock, ParticleMathBlockOperations } from \"./Blocks/particleMathBlock.pure\";\r\nimport { ParticleRandomBlock, ParticleRandomBlockLocks } from \"./Blocks/particleRandomBlock.pure\";\r\nimport { ParticleLerpBlock } from \"./Blocks/particleLerpBlock.pure\";\r\nimport { ParticleTextureSourceBlock } from \"./Blocks/particleSourceTextureBlock.pure\";\r\nimport { ParticleVectorLengthBlock } from \"./Blocks/particleVectorLengthBlock.pure\";\r\nimport { SystemBlock } from \"./Blocks/systemBlock.pure\";\r\nimport { ParticleConditionBlock, ParticleConditionBlockTests } from \"./Blocks/Conditions/particleConditionBlock.pure\";\r\nimport { CreateParticleBlock } from \"./Blocks/Emitters/createParticleBlock.pure\";\r\nimport { BoxShapeBlock } from \"./Blocks/Emitters/boxShapeBlock.pure\";\r\nimport { ConeShapeBlock } from \"./Blocks/Emitters/coneShapeBlock.pure\";\r\nimport { CylinderShapeBlock } from \"./Blocks/Emitters/cylinderShapeBlock.pure\";\r\nimport { CustomShapeBlock } from \"./Blocks/Emitters/customShapeBlock.pure\";\r\nimport { MeshShapeBlock } from \"./Blocks/Emitters/meshShapeBlock.pure\";\r\nimport { PointShapeBlock } from \"./Blocks/Emitters/pointShapeBlock.pure\";\r\nimport { SetupSpriteSheetBlock } from \"./Blocks/Emitters/setupSpriteSheetBlock.pure\";\r\nimport { SphereShapeBlock } from \"./Blocks/Emitters/sphereShapeBlock.pure\";\r\nimport { UpdateAngleBlock } from \"./Blocks/Update/updateAngleBlock.pure\";\r\nimport { BasicSpriteUpdateBlock } from \"./Blocks/Update/basicSpriteUpdateBlock.pure\";\r\nimport { UpdateAttractorBlock } from \"./Blocks/Update/updateAttractorBlock.pure\";\r\nimport { UpdateColorBlock } from \"./Blocks/Update/updateColorBlock.pure\";\r\nimport { UpdateDirectionBlock } from \"./Blocks/Update/updateDirectionBlock.pure\";\r\nimport { UpdateFlowMapBlock } from \"./Blocks/Update/updateFlowMapBlock.pure\";\r\nimport { UpdateNoiseBlock } from \"./Blocks/Update/updateNoiseBlock.pure\";\r\nimport { UpdatePositionBlock } from \"./Blocks/Update/updatePositionBlock.pure\";\r\nimport { UpdateSizeBlock } from \"./Blocks/Update/updateSizeBlock.pure\";\r\nimport { GenerateBase64StringFromPixelData } from \"core/Misc/copyTools\";\r\n\r\n/** Represents blocks or groups of blocks that can be used in multiple places in the graph, so they are stored in this context to be reused */\r\ntype ConversionContext = {\r\n    targetStopDurationBlockOutput: NodeParticleConnectionPoint;\r\n    // Connections that represent calculated ratios values\r\n    timeToStopTimeRatioBlockGroupOutput: NodeParticleConnectionPoint;\r\n    ageToLifeTimeRatioBlockGroupOutput: NodeParticleConnectionPoint;\r\n    // Connections for the start value of a gradient. These are stored so they can be reused for the Creation phase and the Update phase of the particle\r\n    sizeGradientValue0Output: NodeParticleConnectionPoint;\r\n    colorGradientValue0Output: NodeParticleConnectionPoint;\r\n    // Updated scaled direction direction based on velocity and drag\r\n    scaledDirection: NodeParticleConnectionPoint;\r\n};\r\n\r\ntype RuntimeConversionContext = Partial<ConversionContext>;\r\n\r\n/**\r\n * Converts a ParticleSystem to a NodeParticleSystemSet.\r\n * @param name The name of the node particle system set.\r\n * @param particleSystemsList The particle systems to convert.\r\n * @returns The converted node particle system set or null if conversion failed.\r\n */\r\nexport async function ConvertToNodeParticleSystemSetAsync(name: string, particleSystemsList: ParticleSystem[]): Promise<Nullable<NodeParticleSystemSet>> {\r\n    if (!particleSystemsList || !particleSystemsList.length) {\r\n        return null;\r\n    }\r\n\r\n    const nodeParticleSystemSet = new NodeParticleSystemSet(name);\r\n    const promises: Promise<void>[] = [];\r\n\r\n    for (const particleSystem of particleSystemsList) {\r\n        promises.push(_ExtractDatafromParticleSystemAsync(nodeParticleSystemSet, particleSystem, {}));\r\n    }\r\n\r\n    await Promise.all(promises);\r\n    return nodeParticleSystemSet;\r\n}\r\n\r\nasync function _ExtractDatafromParticleSystemAsync(newSet: NodeParticleSystemSet, oldSystem: ParticleSystem, context: RuntimeConversionContext): Promise<void> {\r\n    // CreateParticle block group\r\n    const createParticleOutput = _CreateParticleBlockGroup(oldSystem, context);\r\n\r\n    // UpdateParticle block group\r\n    const updateParticleOutput = _UpdateParticleBlockGroup(createParticleOutput, oldSystem, context);\r\n\r\n    // System block\r\n    const newSystem = _SystemBlockGroup(updateParticleOutput, oldSystem, context);\r\n\r\n    // Register\r\n    newSet.systemBlocks.push(newSystem);\r\n}\r\n\r\n// ------------- CREATE PARTICLE FUNCTIONS -------------\r\n\r\n// The creation of the different properties follows the order they are added to the CreationQueue in ThinParticleSystem:\r\n// Lifetime, Emit Power, Size, Scale/StartSize, Angle, Color, Noise, ColorDead, Sheet\r\nfunction _CreateParticleBlockGroup(oldSystem: ParticleSystem, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    // Create particle block\r\n    const createParticleBlock = new CreateParticleBlock(\"Create Particle\");\r\n    let createdParticle = createParticleBlock.particle;\r\n\r\n    _CreateParticleLifetimeBlockGroup(oldSystem, context).connectTo(createParticleBlock.lifeTime);\r\n    _CreateParticleEmitPowerBlockGroup(oldSystem).connectTo(createParticleBlock.emitPower);\r\n    _CreateParticleSizeBlockGroup(oldSystem, context).connectTo(createParticleBlock.size);\r\n    _CreateParticleScaleBlockGroup(oldSystem, context).connectTo(createParticleBlock.scale);\r\n    _CreateParticleAngleBlockGroup(oldSystem).connectTo(createParticleBlock.angle);\r\n    _CreateParticleColorBlockGroup(oldSystem, context).connectTo(createParticleBlock.color);\r\n\r\n    // Dead color\r\n    _CreateAndConnectInput(\"Dead Color\", oldSystem.colorDead.clone(), createParticleBlock.colorDead);\r\n\r\n    // Emitter shape\r\n    createdParticle = _EmitterShapeBlock(createdParticle, oldSystem);\r\n\r\n    // Sprite sheet setup\r\n    if (oldSystem.isAnimationSheetEnabled) {\r\n        createdParticle = _SpriteSheetBlock(createdParticle, oldSystem);\r\n    }\r\n\r\n    return createdParticle;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle lifetime\r\n * @param oldSystem The old particle system to convert\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle lifetime\r\n */\r\nfunction _CreateParticleLifetimeBlockGroup(oldSystem: ParticleSystem, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    if (oldSystem.targetStopDuration && oldSystem._lifeTimeGradients && oldSystem._lifeTimeGradients.length > 0) {\r\n        context.timeToStopTimeRatioBlockGroupOutput = _CreateTimeToStopTimeRatioBlockGroup(oldSystem.targetStopDuration, context);\r\n        const gradientBlockGroupOutput = _CreateGradientBlockGroup(\r\n            context.timeToStopTimeRatioBlockGroupOutput,\r\n            oldSystem._lifeTimeGradients,\r\n            ParticleRandomBlockLocks.PerParticle,\r\n            \"Lifetime\"\r\n        );\r\n        return gradientBlockGroupOutput;\r\n    } else {\r\n        const randomLifetimeBlock = new ParticleRandomBlock(\"Random Lifetime\");\r\n        _CreateAndConnectInput(\"Min Lifetime\", oldSystem.minLifeTime, randomLifetimeBlock.min);\r\n        _CreateAndConnectInput(\"Max Lifetime\", oldSystem.maxLifeTime, randomLifetimeBlock.max);\r\n        return randomLifetimeBlock.output;\r\n    }\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle emit power\r\n * @param oldSystem The old particle system to convert\r\n * @returns The output of the group of blocks that represent the particle emit power\r\n */\r\nfunction _CreateParticleEmitPowerBlockGroup(oldSystem: ParticleSystem): NodeParticleConnectionPoint {\r\n    const randomEmitPowerBlock = new ParticleRandomBlock(\"Random Emit Power\");\r\n    _CreateAndConnectInput(\"Min Emit Power\", oldSystem.minEmitPower, randomEmitPowerBlock.min);\r\n    _CreateAndConnectInput(\"Max Emit Power\", oldSystem.maxEmitPower, randomEmitPowerBlock.max);\r\n    return randomEmitPowerBlock.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle size\r\n * @param oldSystem The old particle system to convert\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle size\r\n */\r\nfunction _CreateParticleSizeBlockGroup(oldSystem: ParticleSystem, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    if (oldSystem._sizeGradients && oldSystem._sizeGradients.length > 0) {\r\n        context.sizeGradientValue0Output = _CreateParticleInitialValueFromGradient(oldSystem._sizeGradients);\r\n        return context.sizeGradientValue0Output;\r\n    } else {\r\n        const randomSizeBlock = new ParticleRandomBlock(\"Random size\");\r\n        _CreateAndConnectInput(\"Min size\", oldSystem.minSize, randomSizeBlock.min);\r\n        _CreateAndConnectInput(\"Max size\", oldSystem.maxSize, randomSizeBlock.max);\r\n        return randomSizeBlock.output;\r\n    }\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle scale\r\n * @param oldSystem The old particle system to convert\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle scale\r\n */\r\nfunction _CreateParticleScaleBlockGroup(oldSystem: ParticleSystem, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    // Create the random scale\r\n    const randomScaleBlock = new ParticleRandomBlock(\"Random Scale\");\r\n    _CreateAndConnectInput(\"Min Scale\", new Vector2(oldSystem.minScaleX, oldSystem.minScaleY), randomScaleBlock.min);\r\n    _CreateAndConnectInput(\"Max Scale\", new Vector2(oldSystem.maxScaleX, oldSystem.maxScaleY), randomScaleBlock.max);\r\n\r\n    if (oldSystem.targetStopDuration && oldSystem._startSizeGradients && oldSystem._startSizeGradients.length > 0) {\r\n        // Create the start size gradient\r\n        context.timeToStopTimeRatioBlockGroupOutput = _CreateTimeToStopTimeRatioBlockGroup(oldSystem.targetStopDuration, context);\r\n        const gradientBlockGroupOutput = _CreateGradientBlockGroup(\r\n            context.timeToStopTimeRatioBlockGroupOutput,\r\n            oldSystem._startSizeGradients,\r\n            ParticleRandomBlockLocks.PerParticle,\r\n            \"Start Size\"\r\n        );\r\n\r\n        // Multiply the initial random scale by the start size gradient\r\n        const multiplyScaleBlock = new ParticleMathBlock(\"Multiply Scale by Start Size Gradient\");\r\n        multiplyScaleBlock.operation = ParticleMathBlockOperations.Multiply;\r\n        randomScaleBlock.output.connectTo(multiplyScaleBlock.left);\r\n        gradientBlockGroupOutput.connectTo(multiplyScaleBlock.right);\r\n\r\n        return multiplyScaleBlock.output;\r\n    } else {\r\n        return randomScaleBlock.output;\r\n    }\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle angle (rotation)\r\n * @param oldSystem The old particle system to convert\r\n * @returns The output of the group of blocks that represent the particle angle (rotation)\r\n */\r\nfunction _CreateParticleAngleBlockGroup(oldSystem: ParticleSystem): NodeParticleConnectionPoint {\r\n    const randomRotationBlock = new ParticleRandomBlock(\"Random Rotation\");\r\n    _CreateAndConnectInput(\"Min Rotation\", oldSystem.minInitialRotation, randomRotationBlock.min);\r\n    _CreateAndConnectInput(\"Max Rotation\", oldSystem.maxInitialRotation, randomRotationBlock.max);\r\n    return randomRotationBlock.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle color\r\n * @param oldSystem The old particle system to convert\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle color\r\n */\r\nfunction _CreateParticleColorBlockGroup(oldSystem: ParticleSystem, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    if (oldSystem._colorGradients && oldSystem._colorGradients.length > 0) {\r\n        context.colorGradientValue0Output = _CreateParticleInitialValueFromGradient(oldSystem._colorGradients);\r\n        return context.colorGradientValue0Output;\r\n    } else {\r\n        const randomStepBlock = new ParticleRandomBlock(\"Random color step\");\r\n        _CreateAndConnectInput(\"Min\", 0, randomStepBlock.min);\r\n        _CreateAndConnectInput(\"Max\", 1, randomStepBlock.max);\r\n\r\n        const lerpColorBlock = new ParticleLerpBlock(\"Lerp color\");\r\n        _CreateAndConnectInput(\"Color 1\", oldSystem.color1.clone(), lerpColorBlock.left);\r\n        _CreateAndConnectInput(\"Color 2\", oldSystem.color2.clone(), lerpColorBlock.right);\r\n        randomStepBlock.output.connectTo(lerpColorBlock.gradient);\r\n        return lerpColorBlock.output;\r\n    }\r\n}\r\n\r\nfunction _CreateParticleInitialValueFromGradient(gradients: Array<FactorGradient> | Array<ColorGradient>): NodeParticleConnectionPoint {\r\n    if (gradients.length === 0) {\r\n        throw new Error(\"No gradients provided.\");\r\n    }\r\n\r\n    const gradientStep = gradients[0];\r\n    const value1 = (gradientStep as any).factor1 ?? (gradientStep as any).color1;\r\n    const value2 = (gradientStep as any).factor2 ?? (gradientStep as any).color2;\r\n\r\n    if (value2 !== undefined) {\r\n        // Create a random between value1 and value2\r\n        const randomBlock = new ParticleRandomBlock(\"Random Value 0\");\r\n        randomBlock.lockMode = ParticleRandomBlockLocks.OncePerParticle;\r\n        _CreateAndConnectInput(\"Value 1\", value1, randomBlock.min);\r\n        _CreateAndConnectInput(\"Value 2\", value2, randomBlock.max);\r\n        return randomBlock.output;\r\n    } else {\r\n        // Single value\r\n        const sizeBlock = new ParticleInputBlock(\"Value\");\r\n        sizeBlock.value = value1;\r\n        return sizeBlock.output;\r\n    }\r\n}\r\n\r\nfunction _EmitterShapeBlock(particle: NodeParticleConnectionPoint, oldSystem: IParticleSystem): NodeParticleConnectionPoint {\r\n    const emitter = oldSystem.particleEmitterType;\r\n    if (!emitter) {\r\n        throw new Error(\"Particle system has no emitter type.\");\r\n    }\r\n\r\n    let shapeBlock: Nullable<IShapeBlock> = null;\r\n    switch (emitter.getClassName()) {\r\n        case \"BoxParticleEmitter\": {\r\n            const source = emitter as BoxParticleEmitter;\r\n            shapeBlock = new BoxShapeBlock(\"Box Shape\");\r\n\r\n            const target = shapeBlock as BoxShapeBlock;\r\n            _CreateAndConnectInput(\"Direction 1\", source.direction1.clone(), target.direction1);\r\n            _CreateAndConnectInput(\"Direction 2\", source.direction2.clone(), target.direction2);\r\n            _CreateAndConnectInput(\"Min Emit Box\", source.minEmitBox.clone(), target.minEmitBox);\r\n            _CreateAndConnectInput(\"Max Emit Box\", source.maxEmitBox.clone(), target.maxEmitBox);\r\n            break;\r\n        }\r\n        case \"ConeParticleEmitter\": {\r\n            const source = emitter as ConeParticleEmitter;\r\n            shapeBlock = new ConeShapeBlock(\"Cone Shape\");\r\n\r\n            const target = shapeBlock as ConeShapeBlock;\r\n            target.emitFromSpawnPointOnly = source.emitFromSpawnPointOnly;\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Angle\", source.angle, target.angle);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Height Range\", source.heightRange, target.heightRange);\r\n            _CreateAndConnectInput(\"Direction Randomizer\", source.directionRandomizer, target.directionRandomizer);\r\n            break;\r\n        }\r\n        case \"ConeDirectedParticleEmitter\": {\r\n            const source = emitter as ConeDirectedParticleEmitter;\r\n            shapeBlock = new ConeShapeBlock(\"Cone Shape\");\r\n\r\n            const target = shapeBlock as ConeShapeBlock;\r\n            target.emitFromSpawnPointOnly = source.emitFromSpawnPointOnly;\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Angle\", source.angle, target.angle);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Height Range\", source.heightRange, target.heightRange);\r\n            _CreateAndConnectInput(\"Direction 1\", source.direction1.clone(), target.direction1);\r\n            _CreateAndConnectInput(\"Direction 2\", source.direction2.clone(), target.direction2);\r\n            break;\r\n        }\r\n        case \"CustomParticleEmitter\": {\r\n            const source = emitter as CustomParticleEmitter;\r\n            shapeBlock = new CustomShapeBlock(\"Custom Shape\");\r\n\r\n            const target = shapeBlock as CustomShapeBlock;\r\n            target.particlePositionGenerator = source.particlePositionGenerator;\r\n            target.particleDestinationGenerator = source.particleDestinationGenerator;\r\n            target.particleDirectionGenerator = source.particleDirectionGenerator;\r\n            break;\r\n        }\r\n        case \"CylinderParticleEmitter\": {\r\n            const source = emitter as CylinderParticleEmitter;\r\n            shapeBlock = new CylinderShapeBlock(\"Cylinder Shape\");\r\n\r\n            const target = shapeBlock as CylinderShapeBlock;\r\n            _CreateAndConnectInput(\"Height\", source.height, target.height);\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Direction Randomizer\", source.directionRandomizer, target.directionRandomizer);\r\n            break;\r\n        }\r\n        case \"CylinderDirectedParticleEmitter\": {\r\n            const source = emitter as CylinderDirectedParticleEmitter;\r\n            shapeBlock = new CylinderShapeBlock(\"Cylinder Shape\");\r\n\r\n            const target = shapeBlock as CylinderShapeBlock;\r\n            _CreateAndConnectInput(\"Height\", source.height, target.height);\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Direction 1\", source.direction1.clone(), target.direction1);\r\n            _CreateAndConnectInput(\"Direction 2\", source.direction2.clone(), target.direction2);\r\n            break;\r\n        }\r\n        case \"HemisphericParticleEmitter\": {\r\n            const source = emitter as HemisphericParticleEmitter;\r\n            shapeBlock = new SphereShapeBlock(\"Sphere Shape\");\r\n\r\n            const target = shapeBlock as SphereShapeBlock;\r\n            target.isHemispheric = true;\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Direction Randomizer\", source.directionRandomizer, target.directionRandomizer);\r\n            break;\r\n        }\r\n        case \"MeshParticleEmitter\": {\r\n            const source = emitter as MeshParticleEmitter;\r\n            shapeBlock = new MeshShapeBlock(\"Mesh Shape\");\r\n\r\n            const target = shapeBlock as MeshShapeBlock;\r\n            target.useMeshNormalsForDirection = source.useMeshNormalsForDirection;\r\n            _CreateAndConnectInput(\"Direction 1\", source.direction1.clone(), target.direction1);\r\n            _CreateAndConnectInput(\"Direction 2\", source.direction2.clone(), target.direction2);\r\n\r\n            target.mesh = source.mesh as Mesh;\r\n            break;\r\n        }\r\n        case \"PointParticleEmitter\": {\r\n            const source = emitter as PointParticleEmitter;\r\n            shapeBlock = new PointShapeBlock(\"Point Shape\");\r\n\r\n            const target = shapeBlock as PointShapeBlock;\r\n            _CreateAndConnectInput(\"Direction 1\", source.direction1.clone(), target.direction1);\r\n            _CreateAndConnectInput(\"Direction 2\", source.direction2.clone(), target.direction2);\r\n            break;\r\n        }\r\n        case \"SphereParticleEmitter\": {\r\n            const source = emitter as SphereParticleEmitter;\r\n            shapeBlock = new SphereShapeBlock(\"Sphere Shape\");\r\n\r\n            const target = shapeBlock as SphereShapeBlock;\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Direction Randomizer\", source.directionRandomizer, target.directionRandomizer);\r\n            break;\r\n        }\r\n        case \"SphereDirectedParticleEmitter\": {\r\n            const source = emitter as SphereDirectedParticleEmitter;\r\n            shapeBlock = new SphereShapeBlock(\"Sphere Shape\");\r\n\r\n            const target = shapeBlock as SphereShapeBlock;\r\n            _CreateAndConnectInput(\"Radius\", source.radius, target.radius);\r\n            _CreateAndConnectInput(\"Radius Range\", source.radiusRange, target.radiusRange);\r\n            _CreateAndConnectInput(\"Direction1\", source.direction1.clone(), target.direction1);\r\n            _CreateAndConnectInput(\"Direction2\", source.direction2.clone(), target.direction2);\r\n            break;\r\n        }\r\n    }\r\n\r\n    if (!shapeBlock) {\r\n        throw new Error(`Unsupported particle emitter type: ${emitter.getClassName()}`);\r\n    }\r\n\r\n    particle.connectTo(shapeBlock.particle);\r\n    return shapeBlock.output;\r\n}\r\n\r\nfunction _SpriteSheetBlock(particle: NodeParticleConnectionPoint, oldSystem: ParticleSystem): NodeParticleConnectionPoint {\r\n    const spriteSheetBlock = new SetupSpriteSheetBlock(\"Sprite Sheet Setup\");\r\n    particle.connectTo(spriteSheetBlock.particle);\r\n\r\n    spriteSheetBlock.start = oldSystem.startSpriteCellID;\r\n    spriteSheetBlock.end = oldSystem.endSpriteCellID;\r\n    spriteSheetBlock.width = oldSystem.spriteCellWidth;\r\n    spriteSheetBlock.height = oldSystem.spriteCellHeight;\r\n    spriteSheetBlock.spriteCellChangeSpeed = oldSystem.spriteCellChangeSpeed;\r\n    spriteSheetBlock.loop = oldSystem.spriteCellLoop;\r\n    spriteSheetBlock.randomStartCell = oldSystem.spriteRandomStartCell;\r\n\r\n    return spriteSheetBlock.output;\r\n}\r\n\r\n// ------------- UPDATE PARTICLE FUNCTIONS -------------\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle system update\r\n * The creation of the different properties follows the order they are added to the ProcessQueue in ThinParticleSystem:\r\n * Color, AngularSpeedGradients, AngularSpeed, VelocityGradients, Direction, LimitVelocityGradients, DragGradients, Position, Noise, SizeGradients, Gravity\r\n * @param inputParticle The particle input connection point\r\n * @param oldSystem The old particle system to convert\r\n * @param context The runtime conversion context\r\n * @returns The output connection point after all updates have been applied\r\n */\r\nfunction _UpdateParticleBlockGroup(inputParticle: NodeParticleConnectionPoint, oldSystem: ParticleSystem, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    let updatedParticle: NodeParticleConnectionPoint = inputParticle;\r\n\r\n    updatedParticle = _UpdateParticleColorBlockGroup(updatedParticle, oldSystem._colorGradients, context);\r\n    updatedParticle = _UpdateParticleAngleBlockGroup(updatedParticle, oldSystem._angularSpeedGradients, oldSystem.minAngularSpeed, oldSystem.maxAngularSpeed, context);\r\n\r\n    if (oldSystem._velocityGradients && oldSystem._velocityGradients.length > 0) {\r\n        context.scaledDirection = _UpdateParticleVelocityGradientBlockGroup(oldSystem._velocityGradients, context);\r\n    }\r\n\r\n    if (oldSystem._dragGradients && oldSystem._dragGradients.length > 0) {\r\n        context.scaledDirection = _UpdateParticleDragGradientBlockGroup(oldSystem._dragGradients, context);\r\n    }\r\n\r\n    updatedParticle = _UpdateParticlePositionBlockGroup(updatedParticle, oldSystem.isLocal, context);\r\n\r\n    if (oldSystem.attractors && oldSystem.attractors.length > 0) {\r\n        updatedParticle = _UpdateParticleAttractorBlockGroup(updatedParticle, oldSystem.attractors);\r\n    }\r\n\r\n    if (oldSystem.flowMap) {\r\n        updatedParticle = _UpdateParticleFlowMapBlockGroup(updatedParticle, oldSystem.flowMap, oldSystem.flowMapStrength);\r\n    }\r\n\r\n    if (oldSystem._limitVelocityGradients && oldSystem._limitVelocityGradients.length > 0 && oldSystem.limitVelocityDamping !== 0) {\r\n        updatedParticle = _UpdateParticleVelocityLimitGradientBlockGroup(updatedParticle, oldSystem._limitVelocityGradients, oldSystem.limitVelocityDamping, context);\r\n    }\r\n\r\n    if (oldSystem.noiseTexture && oldSystem.noiseStrength) {\r\n        updatedParticle = _UpdateParticleNoiseBlockGroup(updatedParticle, oldSystem.noiseTexture.clone(), oldSystem.noiseStrength.clone());\r\n    }\r\n\r\n    if (oldSystem._sizeGradients && oldSystem._sizeGradients.length > 0) {\r\n        updatedParticle = _UpdateParticleSizeGradientBlockGroup(updatedParticle, oldSystem._sizeGradients, context);\r\n    }\r\n\r\n    if (oldSystem.gravity.equalsToFloats(0, 0, 0) === false) {\r\n        updatedParticle = _UpdateParticleGravityBlockGroup(updatedParticle, oldSystem.gravity);\r\n    }\r\n\r\n    if (oldSystem.isAnimationSheetEnabled) {\r\n        updatedParticle = _UpdateParticleSpriteCellBlockGroup(updatedParticle);\r\n    }\r\n\r\n    return updatedParticle;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle color update\r\n * @param inputParticle The input particle to update\r\n * @param colorGradients The color gradients (if any)\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle color update\r\n */\r\nfunction _UpdateParticleColorBlockGroup(\r\n    inputParticle: NodeParticleConnectionPoint,\r\n    colorGradients: Nullable<Array<ColorGradient>>,\r\n    context: RuntimeConversionContext\r\n): NodeParticleConnectionPoint {\r\n    let colorCalculation: NodeParticleConnectionPoint | undefined;\r\n    if (colorGradients && colorGradients.length > 0) {\r\n        if (context.colorGradientValue0Output === undefined) {\r\n            throw new Error(\"Initial color gradient values not found in context.\");\r\n        }\r\n\r\n        context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);\r\n        colorCalculation = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, colorGradients, ParticleRandomBlockLocks.OncePerParticle, \"Color\", [\r\n            context.colorGradientValue0Output,\r\n        ]);\r\n    } else {\r\n        colorCalculation = _BasicColorUpdateBlockGroup();\r\n    }\r\n\r\n    // Create the color update block clamping alpha >= 0\r\n    const colorUpdateBlock = new UpdateColorBlock(\"Color update\");\r\n    inputParticle.connectTo(colorUpdateBlock.particle);\r\n    _ClampUpdateColorAlpha(colorCalculation).connectTo(colorUpdateBlock.color);\r\n\r\n    return colorUpdateBlock.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle angle update\r\n * @param inputParticle The input particle to update\r\n * @param angularSpeedGradients The angular speed gradients (if any)\r\n * @param minAngularSpeed The minimum angular speed\r\n * @param maxAngularSpeed The maximum angular speed\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle color update\r\n */\r\nfunction _UpdateParticleAngleBlockGroup(\r\n    inputParticle: NodeParticleConnectionPoint,\r\n    angularSpeedGradients: Nullable<Array<FactorGradient>>,\r\n    minAngularSpeed: number,\r\n    maxAngularSpeed: number,\r\n    context: RuntimeConversionContext\r\n): NodeParticleConnectionPoint {\r\n    // We will try to use gradients if they exist\r\n    // If not, we will try to use min/max angular speed\r\n    let angularSpeedCalculation = null;\r\n    if (angularSpeedGradients && angularSpeedGradients.length > 0) {\r\n        angularSpeedCalculation = _UpdateParticleAngularSpeedGradientBlockGroup(angularSpeedGradients, context);\r\n    } else if (minAngularSpeed !== 0 || maxAngularSpeed !== 0) {\r\n        angularSpeedCalculation = _UpdateParticleAngularSpeedBlockGroup(minAngularSpeed, maxAngularSpeed);\r\n    }\r\n\r\n    // If we have an angular speed calculation, then update the angle\r\n    if (angularSpeedCalculation) {\r\n        // Create the angular speed delta\r\n        const angleSpeedDeltaOutput = _CreateDeltaModifiedInput(\"Angular Speed\", angularSpeedCalculation);\r\n\r\n        // Add it to the angle\r\n        const addAngle = new ParticleMathBlock(\"Add Angular Speed to Angle\");\r\n        addAngle.operation = ParticleMathBlockOperations.Add;\r\n        _CreateAndConnectContextualSource(\"Angle\", NodeParticleContextualSources.Angle, addAngle.left);\r\n        angleSpeedDeltaOutput.connectTo(addAngle.right);\r\n\r\n        // Update the particle angle\r\n        const updateAngle = new UpdateAngleBlock(\"Angle Update with Angular Speed\");\r\n        inputParticle.connectTo(updateAngle.particle);\r\n        addAngle.output.connectTo(updateAngle.angle);\r\n\r\n        return updateAngle.output;\r\n    } else {\r\n        return inputParticle;\r\n    }\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle velocity update\r\n * @param velocityGradients The velocity gradients\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle velocity update\r\n */\r\nfunction _UpdateParticleVelocityGradientBlockGroup(velocityGradients: Array<FactorGradient>, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);\r\n\r\n    // Generate the gradient\r\n    const velocityValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, velocityGradients, ParticleRandomBlockLocks.OncePerParticle, \"Velocity\");\r\n\r\n    // Update the direction scale based on the velocity\r\n    const multiplyScaleByVelocity = new ParticleMathBlock(\"Multiply Direction Scale by Velocity\");\r\n    multiplyScaleByVelocity.operation = ParticleMathBlockOperations.Multiply;\r\n    velocityValueOutput.connectTo(multiplyScaleByVelocity.left);\r\n    _CreateAndConnectContextualSource(\"Direction Scale\", NodeParticleContextualSources.DirectionScale, multiplyScaleByVelocity.right);\r\n\r\n    // Update the particle direction scale\r\n    const multiplyDirection = new ParticleMathBlock(\"Scaled Direction\");\r\n    multiplyDirection.operation = ParticleMathBlockOperations.Multiply;\r\n    multiplyScaleByVelocity.output.connectTo(multiplyDirection.left);\r\n    _CreateAndConnectContextualSource(\"Direction\", NodeParticleContextualSources.Direction, multiplyDirection.right);\r\n\r\n    // Store the new calculation of the scaled direction in the context\r\n    context.scaledDirection = multiplyDirection.output;\r\n    return multiplyDirection.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle velocity limit update\r\n * @param inputParticle The input particle to update\r\n * @param velocityLimitGradients The velocity limit gradients\r\n * @param limitVelocityDamping The limit velocity damping factor\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle velocity limit update\r\n */\r\nfunction _UpdateParticleVelocityLimitGradientBlockGroup(\r\n    inputParticle: NodeParticleConnectionPoint,\r\n    velocityLimitGradients: Array<FactorGradient>,\r\n    limitVelocityDamping: number,\r\n    context: RuntimeConversionContext\r\n): NodeParticleConnectionPoint {\r\n    context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);\r\n\r\n    // Calculate the current speed\r\n    const currentSpeedBlock = new ParticleVectorLengthBlock(\"Current Speed\");\r\n    _CreateAndConnectContextualSource(\"Direction\", NodeParticleContextualSources.Direction, currentSpeedBlock.input);\r\n\r\n    // Calculate the velocity limit from the gradient\r\n    const velocityLimitValueOutput = _CreateGradientBlockGroup(\r\n        context.ageToLifeTimeRatioBlockGroupOutput,\r\n        velocityLimitGradients,\r\n        ParticleRandomBlockLocks.OncePerParticle,\r\n        \"Velocity Limit\"\r\n    );\r\n\r\n    // Blocks that will calculate the new velocity if over the limit\r\n    const damped = new ParticleMathBlock(\"Damped Speed\");\r\n    damped.operation = ParticleMathBlockOperations.Multiply;\r\n    _CreateAndConnectContextualSource(\"Direction\", NodeParticleContextualSources.Direction, damped.left);\r\n    _CreateAndConnectInput(\"Limit Velocity Damping\", limitVelocityDamping, damped.right);\r\n\r\n    // Compare current speed and limit\r\n    const compareSpeed = new ParticleConditionBlock(\"Compare Speed to Limit\");\r\n    compareSpeed.test = ParticleConditionBlockTests.GreaterThan;\r\n    currentSpeedBlock.output.connectTo(compareSpeed.left);\r\n    velocityLimitValueOutput.connectTo(compareSpeed.right);\r\n    damped.output.connectTo(compareSpeed.ifTrue);\r\n    _CreateAndConnectContextualSource(\"Direction\", NodeParticleContextualSources.Direction, compareSpeed.ifFalse);\r\n\r\n    // Update the direction based on the calculted value\r\n    const updateDirection = new UpdateDirectionBlock(\"Direction Update\");\r\n    inputParticle.connectTo(updateDirection.particle);\r\n    compareSpeed.output.connectTo(updateDirection.direction);\r\n\r\n    return updateDirection.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle noise update\r\n * @param inputParticle The particle to update\r\n * @param noiseTexture The noise texture\r\n * @param noiseStrength The strength of the noise\r\n * @returns The output of the group of blocks that represent the particle noise update\r\n */\r\nfunction _UpdateParticleNoiseBlockGroup(inputParticle: NodeParticleConnectionPoint, noiseTexture: ProceduralTexture, noiseStrength: Vector3): NodeParticleConnectionPoint {\r\n    const noiseUpdate = new UpdateNoiseBlock(\"Noise Update\");\r\n    inputParticle.connectTo(noiseUpdate.particle);\r\n    _CreateTextureBlock(noiseTexture).connectTo(noiseUpdate.noiseTexture);\r\n    _CreateAndConnectInput(\"Noise Strength\", noiseStrength, noiseUpdate.strength);\r\n    return noiseUpdate.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle drag update\r\n * @param dragGradients The drag gradients\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle drag update\r\n */\r\nfunction _UpdateParticleDragGradientBlockGroup(dragGradients: Array<FactorGradient>, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);\r\n\r\n    // Generate the gradient\r\n    const dragValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, dragGradients, ParticleRandomBlockLocks.OncePerParticle, \"Drag\");\r\n\r\n    // Calculate drag factor\r\n    const oneMinusDragBlock = new ParticleMathBlock(\"1 - Drag\");\r\n    oneMinusDragBlock.operation = ParticleMathBlockOperations.Subtract;\r\n    _CreateAndConnectInput(\"One\", 1, oneMinusDragBlock.left);\r\n    dragValueOutput.connectTo(oneMinusDragBlock.right);\r\n\r\n    // Multiply the scaled direction by drag factor\r\n    const multiplyDirection = new ParticleMathBlock(\"Scaled Direction with Drag\");\r\n    multiplyDirection.operation = ParticleMathBlockOperations.Multiply;\r\n    oneMinusDragBlock.output.connectTo(multiplyDirection.left);\r\n    if (context.scaledDirection === undefined) {\r\n        _CreateAndConnectContextualSource(\"Scaled Direction\", NodeParticleContextualSources.ScaledDirection, multiplyDirection.right);\r\n    } else {\r\n        context.scaledDirection.connectTo(multiplyDirection.right);\r\n    }\r\n\r\n    // Store the new calculation of the scaled direction in the context\r\n    context.scaledDirection = multiplyDirection.output;\r\n    return multiplyDirection.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle position update\r\n * @param inputParticle The input particle to update\r\n * @param isLocal Whether the particle coordinate system is local or not\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle position update\r\n */\r\nfunction _UpdateParticlePositionBlockGroup(inputParticle: NodeParticleConnectionPoint, isLocal: boolean, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    // Update the particle position\r\n    const updatePosition = new UpdatePositionBlock(\"Position Update\");\r\n    inputParticle.connectTo(updatePosition.particle);\r\n\r\n    if (isLocal) {\r\n        _CreateAndConnectContextualSource(\"Local Position Updated\", NodeParticleContextualSources.LocalPositionUpdated, updatePosition.position);\r\n    } else {\r\n        // Calculate the new position\r\n        const addPositionBlock = new ParticleMathBlock(\"Add Position\");\r\n        addPositionBlock.operation = ParticleMathBlockOperations.Add;\r\n        _CreateAndConnectContextualSource(\"Position\", NodeParticleContextualSources.Position, addPositionBlock.left);\r\n        if (context.scaledDirection === undefined) {\r\n            _CreateAndConnectContextualSource(\"Scaled Direction\", NodeParticleContextualSources.ScaledDirection, addPositionBlock.right);\r\n        } else {\r\n            context.scaledDirection.connectTo(addPositionBlock.right);\r\n        }\r\n\r\n        addPositionBlock.output.connectTo(updatePosition.position);\r\n    }\r\n\r\n    return updatePosition.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle attractor update\r\n * @param inputParticle The input particle to update\r\n * @param attractors The attractors (if any)\r\n * @returns The output of the group of blocks that represent the particle attractor update\r\n */\r\nfunction _UpdateParticleAttractorBlockGroup(inputParticle: NodeParticleConnectionPoint, attractors: Attractor[]): NodeParticleConnectionPoint {\r\n    let outputParticle = inputParticle;\r\n\r\n    // Chain update attractor blocks for each attractor\r\n    for (let i = 0; i < attractors.length; i++) {\r\n        const attractor = attractors[i];\r\n        const attractorBlock = new UpdateAttractorBlock(`Attractor Block ${i}`);\r\n        outputParticle.connectTo(attractorBlock.particle);\r\n        _CreateAndConnectInput(\"Attractor Position\", attractor.position.clone(), attractorBlock.attractor);\r\n        _CreateAndConnectInput(\"Attractor Strength\", attractor.strength, attractorBlock.strength);\r\n        outputParticle = attractorBlock.output;\r\n    }\r\n\r\n    return outputParticle;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle flow map update\r\n * @param inputParticle The input particle to update\r\n * @param flowMap The flow map data\r\n * @param flowMapStrength The strength of the flow map\r\n * @returns The output of the group of blocks that represent the particle flow map update\r\n */\r\nfunction _UpdateParticleFlowMapBlockGroup(inputParticle: NodeParticleConnectionPoint, flowMap: FlowMap, flowMapStrength: number): NodeParticleConnectionPoint {\r\n    // Create the flow map update block\r\n    const updateFlowMapBlock = new UpdateFlowMapBlock(\"Flow Map Update\");\r\n    inputParticle.connectTo(updateFlowMapBlock.particle);\r\n\r\n    // Create a texture block from the flow map data\r\n    // The FlowMap only stores raw pixel data, so we need to convert it to a base64 data URL\r\n    // Y has to be flipped as the texture data is flipped between CPU (canvas, Y=0 at top) and GPU (texture, Y=0 at bottom)\r\n    const flowMapTextureBlock = new ParticleTextureSourceBlock(\"Flow Map Texture\");\r\n    flowMapTextureBlock.serializedCachedData = true;\r\n    flowMapTextureBlock.textureDataUrl = GenerateBase64StringFromPixelData(flowMap.data, { width: flowMap.width, height: flowMap.height }, true) ?? \"\";\r\n    flowMapTextureBlock.textureOutput.connectTo(updateFlowMapBlock.flowMap);\r\n\r\n    _CreateAndConnectInput(\"Flow Map Strength\", flowMapStrength, updateFlowMapBlock.strength);\r\n\r\n    return updateFlowMapBlock.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle size update\r\n * @param inputParticle The input particle to update\r\n * @param sizeGradients The size gradients (if any)\r\n * @param context The context of the current conversion\r\n * @returns The output of the group of blocks that represent the particle size update\r\n */\r\nfunction _UpdateParticleSizeGradientBlockGroup(\r\n    inputParticle: NodeParticleConnectionPoint,\r\n    sizeGradients: Array<FactorGradient>,\r\n    context: RuntimeConversionContext\r\n): NodeParticleConnectionPoint {\r\n    if (context.sizeGradientValue0Output === undefined) {\r\n        throw new Error(\"Initial size gradient values not found in context.\");\r\n    }\r\n\r\n    context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);\r\n\r\n    // Generate the gradient\r\n    const sizeValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, sizeGradients, ParticleRandomBlockLocks.OncePerParticle, \"Size\", [\r\n        context.sizeGradientValue0Output,\r\n    ]);\r\n\r\n    // Create the update size\r\n    const updateSizeBlock = new UpdateSizeBlock(\"Size Update\");\r\n    inputParticle.connectTo(updateSizeBlock.particle);\r\n    sizeValueOutput.connectTo(updateSizeBlock.size);\r\n\r\n    return updateSizeBlock.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle gravity update\r\n * @param inputParticle The input particle to update\r\n * @param gravity The gravity vector to apply\r\n * @returns The output of the group of blocks that represent the particle gravity update\r\n */\r\nfunction _UpdateParticleGravityBlockGroup(inputParticle: NodeParticleConnectionPoint, gravity: Vector3): NodeParticleConnectionPoint {\r\n    // Create the gravity delta\r\n    const gravityDeltaOutput = _CreateDeltaModifiedInput(\"Gravity\", gravity);\r\n\r\n    // Add it to the direction\r\n    const addDirectionBlock = new ParticleMathBlock(\"Add Gravity to Direction\");\r\n    addDirectionBlock.operation = ParticleMathBlockOperations.Add;\r\n    _CreateAndConnectContextualSource(\"Direction\", NodeParticleContextualSources.Direction, addDirectionBlock.left);\r\n    gravityDeltaOutput.connectTo(addDirectionBlock.right);\r\n\r\n    // Update the particle direction\r\n    const updateDirection = new UpdateDirectionBlock(\"Direction Update with Gravity\");\r\n    inputParticle.connectTo(updateDirection.particle);\r\n    addDirectionBlock.output.connectTo(updateDirection.direction);\r\n\r\n    return updateDirection.output;\r\n}\r\n\r\n/**\r\n * Creates the group of blocks that represent the particle sprite cell update\r\n * @param inputParticle The input particle to update\r\n * @returns The output of the group of blocks that represent the particle sprite cell update #2MI0A1#3\r\n */\r\nfunction _UpdateParticleSpriteCellBlockGroup(inputParticle: NodeParticleConnectionPoint): NodeParticleConnectionPoint {\r\n    const updateSpriteCell = new BasicSpriteUpdateBlock(\"Sprite Cell Update\");\r\n    inputParticle.connectTo(updateSpriteCell.particle);\r\n    return updateSpriteCell.output;\r\n}\r\n\r\nfunction _UpdateParticleAngularSpeedGradientBlockGroup(angularSpeedGradients: Array<FactorGradient>, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);\r\n\r\n    // Generate the gradient\r\n    const angularSpeedValueOutput = _CreateGradientBlockGroup(\r\n        context.ageToLifeTimeRatioBlockGroupOutput,\r\n        angularSpeedGradients,\r\n        ParticleRandomBlockLocks.OncePerParticle,\r\n        \"Angular Speed\"\r\n    );\r\n    return angularSpeedValueOutput;\r\n}\r\n\r\nfunction _UpdateParticleAngularSpeedBlockGroup(minAngularSpeed: number, maxAngularSpeed: number): NodeParticleConnectionPoint {\r\n    // Random value between for the angular speed of the particle\r\n    const randomAngularSpeedBlock = new ParticleRandomBlock(\"Random Angular Speed\");\r\n    randomAngularSpeedBlock.lockMode = ParticleRandomBlockLocks.OncePerParticle;\r\n    _CreateAndConnectInput(\"Min Angular Speed\", minAngularSpeed, randomAngularSpeedBlock.min);\r\n    _CreateAndConnectInput(\"Max Angular Speed\", maxAngularSpeed, randomAngularSpeedBlock.max);\r\n    return randomAngularSpeedBlock.output;\r\n}\r\n\r\nfunction _BasicColorUpdateBlockGroup(): NodeParticleConnectionPoint {\r\n    const addColorBlock = new ParticleMathBlock(\"Add Color\");\r\n    addColorBlock.operation = ParticleMathBlockOperations.Add;\r\n    _CreateAndConnectContextualSource(\"Color\", NodeParticleContextualSources.Color, addColorBlock.left);\r\n    _CreateAndConnectContextualSource(\"Scaled Color Step\", NodeParticleContextualSources.ScaledColorStep, addColorBlock.right);\r\n    return addColorBlock.output;\r\n}\r\n\r\nfunction _ClampUpdateColorAlpha(colorCalculationOutput: NodeParticleConnectionPoint): NodeParticleConnectionPoint {\r\n    // Decompose color to clamp alpha\r\n    const decomposeColorBlock = new ParticleConverterBlock(\"Decompose Color\");\r\n    colorCalculationOutput.connectTo(decomposeColorBlock.colorIn);\r\n\r\n    // Clamp alpha to be >= 0\r\n    const maxAlphaBlock = new ParticleMathBlock(\"Alpha >= 0\");\r\n    maxAlphaBlock.operation = ParticleMathBlockOperations.Max;\r\n    decomposeColorBlock.wOut.connectTo(maxAlphaBlock.left);\r\n    _CreateAndConnectInput(\"Zero\", 0, maxAlphaBlock.right);\r\n\r\n    // Recompose color\r\n    const composeColorBlock = new ParticleConverterBlock(\"Compose Color\");\r\n    decomposeColorBlock.xyzOut.connectTo(composeColorBlock.xyzIn);\r\n    maxAlphaBlock.output.connectTo(composeColorBlock.wIn);\r\n\r\n    return composeColorBlock.colorOut;\r\n}\r\n\r\n// ------------- SYSTEM FUNCTIONS -------------\r\n\r\nfunction _SystemBlockGroup(updateParticleOutput: NodeParticleConnectionPoint, oldSystem: ParticleSystem, context: RuntimeConversionContext): SystemBlock {\r\n    const newSystem = new SystemBlock(oldSystem.name);\r\n\r\n    newSystem.translationPivot.value = oldSystem.translationPivot.clone();\r\n    newSystem.textureMask.value = oldSystem.textureMask.clone();\r\n    newSystem.manualEmitCount = oldSystem.manualEmitCount;\r\n    newSystem.blendMode = oldSystem.blendMode;\r\n    newSystem.capacity = oldSystem.getCapacity();\r\n    newSystem.startDelay = oldSystem.startDelay;\r\n    newSystem.updateSpeed = oldSystem.updateSpeed;\r\n    newSystem.preWarmCycles = oldSystem.preWarmCycles;\r\n    newSystem.preWarmStepOffset = oldSystem.preWarmStepOffset;\r\n    newSystem.isBillboardBased = oldSystem.isBillboardBased;\r\n    newSystem.billBoardMode = oldSystem.billboardMode;\r\n    newSystem.isLocal = oldSystem.isLocal;\r\n    newSystem.disposeOnStop = oldSystem.disposeOnStop;\r\n    newSystem.renderingGroupId = oldSystem.renderingGroupId;\r\n    const emitter = oldSystem.emitter;\r\n    if (emitter instanceof Vector3) {\r\n        newSystem.emitter = emitter.clone();\r\n    } else {\r\n        newSystem.emitter = emitter;\r\n    }\r\n\r\n    _SystemCustomShader(oldSystem, newSystem);\r\n    _SystemEmitRateValue(oldSystem.getEmitRateGradients(), oldSystem.targetStopDuration, oldSystem.emitRate, newSystem, context);\r\n    _SystemTargetStopDuration(oldSystem.targetStopDuration, newSystem, context);\r\n\r\n    const texture = oldSystem.particleTexture;\r\n    if (texture) {\r\n        _CreateTextureBlock(texture).connectTo(newSystem.texture);\r\n    }\r\n\r\n    updateParticleOutput.connectTo(newSystem.particle);\r\n\r\n    return newSystem;\r\n}\r\n\r\nfunction _SystemCustomShader(oldSystem: ParticleSystem, newSystem: SystemBlock) {\r\n    if (oldSystem.customShader) {\r\n        // Copy the custom shader configuration so it can be recreated when building the system\r\n        newSystem.customShader = {\r\n            shaderPath: {\r\n                fragmentElement: oldSystem.customShader.shaderPath.fragmentElement,\r\n            },\r\n            shaderOptions: {\r\n                uniforms: oldSystem.customShader.shaderOptions.uniforms.slice(),\r\n                samplers: oldSystem.customShader.shaderOptions.samplers.slice(),\r\n                defines: oldSystem.customShader.shaderOptions.defines.slice(),\r\n            },\r\n        };\r\n    } else {\r\n        // Check if there's a custom effect set directly without customShader metadata\r\n        // This happens when using the ThinParticleSystem constructor with a customEffect parameter or when calling setCustomEffect directly\r\n        const customEffect = oldSystem.getCustomEffect(0);\r\n        if (customEffect) {\r\n            const effectName = customEffect.name;\r\n            const fragmentElement =\r\n                typeof effectName === \"string\"\r\n                    ? effectName\r\n                    : ((effectName as { fragmentElement?: string; fragment?: string }).fragmentElement ?? (effectName as { fragment?: string }).fragment);\r\n\r\n            newSystem.customShader = {\r\n                shaderPath: {\r\n                    fragmentElement: fragmentElement ?? \"\",\r\n                },\r\n                shaderOptions: {\r\n                    uniforms: (customEffect as any)._uniformsNames.slice(),\r\n                    samplers: (customEffect as any)._samplerList.slice(),\r\n                    defines: customEffect.defines ? customEffect.defines.split(\"\\n\").filter((d) => d.length > 0) : [],\r\n                },\r\n            };\r\n        }\r\n    }\r\n}\r\n\r\nfunction _SystemEmitRateValue(\r\n    emitGradients: Nullable<Array<FactorGradient>>,\r\n    targetStopDuration: number,\r\n    emitRate: number,\r\n    newSystem: SystemBlock,\r\n    context: RuntimeConversionContext\r\n): void {\r\n    if (emitGradients && emitGradients.length > 0 && targetStopDuration > 0) {\r\n        // Create the emit gradients\r\n        context.timeToStopTimeRatioBlockGroupOutput = _CreateTimeToStopTimeRatioBlockGroup(targetStopDuration, context);\r\n        const gradientValue = _CreateGradientBlockGroup(context.timeToStopTimeRatioBlockGroupOutput, emitGradients, ParticleRandomBlockLocks.PerSystem, \"Emit Rate\");\r\n\r\n        // Round the value to an int\r\n        const roundBlock = new ParticleFloatToIntBlock(\"Round to Int\");\r\n        roundBlock.operation = ParticleFloatToIntBlockOperations.Round;\r\n        gradientValue.connectTo(roundBlock.input);\r\n        roundBlock.output.connectTo(newSystem.emitRate);\r\n    } else {\r\n        newSystem.emitRate.value = emitRate;\r\n    }\r\n}\r\n\r\nfunction _SystemTargetStopDuration(targetStopDuration: number, newSystem: SystemBlock, context: RuntimeConversionContext): void {\r\n    // If something else uses the target stop duration (like a gradient),\r\n    // then the block is already created and stored in the context\r\n    if (context.targetStopDurationBlockOutput) {\r\n        context.targetStopDurationBlockOutput.connectTo(newSystem.targetStopDuration);\r\n    } else {\r\n        // If no one used it, do not create a block just set the value\r\n        newSystem.targetStopDuration.value = targetStopDuration;\r\n    }\r\n}\r\n\r\n// ------------- UTILITY FUNCTIONS -------------\r\n\r\nfunction _CreateDeltaModifiedInput(name: string, value: Vector3 | NodeParticleConnectionPoint): NodeParticleConnectionPoint {\r\n    const multiplyBlock = new ParticleMathBlock(\"Multiply by Delta\");\r\n    multiplyBlock.operation = ParticleMathBlockOperations.Multiply;\r\n    if (value instanceof Vector3) {\r\n        _CreateAndConnectInput(name, value, multiplyBlock.left);\r\n    } else {\r\n        value.connectTo(multiplyBlock.left);\r\n    }\r\n    _CreateAndConnectSystemSource(\"Delta\", NodeParticleSystemSources.Delta, multiplyBlock.right);\r\n\r\n    return multiplyBlock.output;\r\n}\r\n\r\nfunction _CreateAndConnectInput(\r\n    inputBlockName: string,\r\n    value: number | Vector2 | Vector3 | Color4,\r\n    targetToConnectTo: NodeParticleConnectionPoint,\r\n    inputType?: NodeParticleBlockConnectionPointTypes\r\n): void {\r\n    const input = new ParticleInputBlock(inputBlockName, inputType);\r\n    input.value = value;\r\n    input.output.connectTo(targetToConnectTo);\r\n}\r\n\r\nfunction _CreateAndConnectContextualSource(contextualBlockName: string, contextSource: NodeParticleContextualSources, targetToConnectTo: NodeParticleConnectionPoint): void {\r\n    const input = new ParticleInputBlock(contextualBlockName);\r\n    input.contextualValue = contextSource;\r\n    input.output.connectTo(targetToConnectTo);\r\n}\r\n\r\nfunction _CreateAndConnectSystemSource(systemBlockName: string, systemSource: NodeParticleSystemSources, targetToConnectTo: NodeParticleConnectionPoint): void {\r\n    const input = new ParticleInputBlock(systemBlockName);\r\n    input.systemSource = systemSource;\r\n    input.output.connectTo(targetToConnectTo);\r\n}\r\n\r\n/**\r\n * Creates the target stop duration input block, as it can be shared in multiple places\r\n * This block is stored in the context so the same block is shared in the graph\r\n * @param targetStopDuration The target stop duration value\r\n * @param context The context of the current conversion\r\n * @returns\r\n */\r\nfunction _CreateTargetStopDurationInputBlock(targetStopDuration: number, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    // If we have already created the target stop duration input block, return it\r\n    if (context.targetStopDurationBlockOutput) {\r\n        return context.targetStopDurationBlockOutput;\r\n    }\r\n\r\n    // Create the target stop duration input block if not already created\r\n    const targetStopDurationInputBlock = new ParticleInputBlock(\"Target Stop Duration\");\r\n    targetStopDurationInputBlock.value = targetStopDuration;\r\n\r\n    // Save the output in our context to avoid regenerating it again\r\n    context.targetStopDurationBlockOutput = targetStopDurationInputBlock.output;\r\n    return context.targetStopDurationBlockOutput;\r\n}\r\n\r\n/**\r\n * Create a group of blocks that calculates the ratio between the actual frame and the target stop duration, clamped between 0 and 1.\r\n * This is used to simulate the behavior of the old particle system where several particle gradient values are affected by the target stop duration.\r\n * This block group is stored in the context so the same group is shared in the graph\r\n * @param targetStopDuration The target stop duration value\r\n * @param context The context of the current conversion\r\n * @returns The ratio block output connection point\r\n */\r\nfunction _CreateTimeToStopTimeRatioBlockGroup(targetStopDuration: number, context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    // If we have already generated this group, return it\r\n    if (context.timeToStopTimeRatioBlockGroupOutput) {\r\n        return context.timeToStopTimeRatioBlockGroupOutput;\r\n    }\r\n\r\n    context.targetStopDurationBlockOutput = _CreateTargetStopDurationInputBlock(targetStopDuration, context);\r\n\r\n    // Find the ratio between the actual frame and the target stop duration\r\n    const ratio = new ParticleMathBlock(\"Frame/Stop Ratio\");\r\n    ratio.operation = ParticleMathBlockOperations.Divide;\r\n    _CreateAndConnectSystemSource(\"Actual Frame\", NodeParticleSystemSources.Time, ratio.left);\r\n    context.targetStopDurationBlockOutput.connectTo(ratio.right);\r\n\r\n    // Make sure values is >=0\r\n    const clampMin = new ParticleMathBlock(\"Clamp Min 0\");\r\n    clampMin.operation = ParticleMathBlockOperations.Max;\r\n    _CreateAndConnectInput(\"Zero\", 0, clampMin.left);\r\n    ratio.output.connectTo(clampMin.right);\r\n\r\n    // Make sure values is <=1\r\n    const clampMax = new ParticleMathBlock(\"Clamp Max 1\");\r\n    clampMax.operation = ParticleMathBlockOperations.Min;\r\n    _CreateAndConnectInput(\"One\", 1, clampMax.left);\r\n    clampMin.output.connectTo(clampMax.right);\r\n\r\n    // Save the group output in our context to avoid regenerating it again\r\n    context.timeToStopTimeRatioBlockGroupOutput = clampMax.output;\r\n    return context.timeToStopTimeRatioBlockGroupOutput;\r\n}\r\n\r\nfunction _CreateAgeToLifeTimeRatioBlockGroup(context: RuntimeConversionContext): NodeParticleConnectionPoint {\r\n    // If we have already generated this group, return it\r\n    if (context.ageToLifeTimeRatioBlockGroupOutput) {\r\n        return context.ageToLifeTimeRatioBlockGroupOutput;\r\n    }\r\n\r\n    // Find the ratio between the age and the lifetime\r\n    const ratio = new ParticleMathBlock(\"Age/LifeTime Ratio\");\r\n    ratio.operation = ParticleMathBlockOperations.Divide;\r\n    _CreateAndConnectContextualSource(\"Age\", NodeParticleContextualSources.Age, ratio.left);\r\n    _CreateAndConnectContextualSource(\"LifeTime\", NodeParticleContextualSources.Lifetime, ratio.right);\r\n\r\n    // Save the group output in our context to avoid regenerating it again\r\n    context.ageToLifeTimeRatioBlockGroupOutput = ratio.output;\r\n    return ratio.output;\r\n}\r\n\r\n/**\r\n * Creates the blocks that represent a gradient\r\n * @param gradientSelector The value that determines which gradient to use\r\n * @param gradientValues The list of gradient values\r\n * @param randomLockMode The type of random to use for the gradient values\r\n * @param prefix The prefix to use for naming the blocks\r\n * @param initialValues Optional initial values to connect to the gradient inputs that were calculated during other steps of the conversion\r\n * @returns The output connection point of the gradient block\r\n */\r\nfunction _CreateGradientBlockGroup(\r\n    gradientSelector: NodeParticleConnectionPoint,\r\n    gradientValues: Array<FactorGradient> | Array<ColorGradient>,\r\n    randomLockMode: ParticleRandomBlockLocks,\r\n    prefix: string,\r\n    initialValues: NodeParticleConnectionPoint[] = []\r\n): NodeParticleConnectionPoint {\r\n    // Create the gradient block and connect the value that controls the gradient selection\r\n    const gradientBlock = new ParticleGradientBlock(prefix + \" Gradient Block\");\r\n    gradientSelector.connectTo(gradientBlock.gradient);\r\n\r\n    // If initial values are provided, we use them instead of the values in the gradientValues array\r\n    // These means this values were already transformed into blocks on a previous step of the conversion and we must reuse them\r\n    for (let i = 0; i < initialValues.length; i++) {\r\n        const reference = i < gradientValues.length ? gradientValues[i].gradient : 1;\r\n        const gradientValueBlock = new ParticleGradientValueBlock(prefix + \" Gradient Value \" + i);\r\n        gradientValueBlock.reference = reference;\r\n        initialValues[i].connectTo(gradientValueBlock.value);\r\n        gradientValueBlock.output.connectTo(gradientBlock.inputs[i + 1]);\r\n    }\r\n\r\n    // Create the gradient values\r\n    for (let i = 0 + initialValues.length; i < gradientValues.length; i++) {\r\n        const gradientValueBlockGroupOutput = _CreateGradientValueBlockGroup(gradientValues[i], randomLockMode, prefix, i);\r\n        gradientValueBlockGroupOutput.connectTo(gradientBlock.inputs[i + 1]);\r\n    }\r\n\r\n    return gradientBlock.output;\r\n}\r\n\r\n/**\r\n * Creates the blocks that represent a gradient value\r\n * This can be either a single value or a random between two values\r\n * @param gradientStep The gradient step data\r\n * @param randomLockMode The lock mode to use for random values\r\n * @param prefix The prefix to use for naming the blocks\r\n * @param index The index of the gradient step\r\n * @returns The output connection point of the gradient value block\r\n */\r\nfunction _CreateGradientValueBlockGroup(\r\n    gradientStep: FactorGradient | ColorGradient,\r\n    randomLockMode: ParticleRandomBlockLocks,\r\n    prefix: string,\r\n    index: number\r\n): NodeParticleConnectionPoint {\r\n    const gradientValueBlock = new ParticleGradientValueBlock(prefix + \" Gradient Value \" + index);\r\n    gradientValueBlock.reference = gradientStep.gradient;\r\n\r\n    const value1 = (gradientStep as any).factor1 ?? (gradientStep as any).color1.clone();\r\n    const value2 = (gradientStep as any).factor2 ?? (gradientStep as any).color2?.clone();\r\n\r\n    if (value2 !== undefined) {\r\n        // Create a random between value1 and value2\r\n        const randomBlock = new ParticleRandomBlock(\"Random Value \" + index);\r\n        randomBlock.lockMode = randomLockMode;\r\n        _CreateAndConnectInput(\"Value 1\", value1, randomBlock.min);\r\n        _CreateAndConnectInput(\"Value 2\", value2, randomBlock.max);\r\n        randomBlock.output.connectTo(gradientValueBlock.value);\r\n    } else {\r\n        // Single value\r\n        _CreateAndConnectInput(\"Value\", value1, gradientValueBlock.value);\r\n    }\r\n\r\n    return gradientValueBlock.output;\r\n}\r\n\r\nfunction _CreateTextureBlock(texture: Nullable<BaseTexture>): NodeParticleConnectionPoint {\r\n    // Texture - always use sourceTexture to preserve all texture options\r\n    const textureBlock = new ParticleTextureSourceBlock(\"Texture\");\r\n    textureBlock.sourceTexture = texture;\r\n    return textureBlock.textureOutput;\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { type Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the scale of a particle\r\n */\r\nexport class UpdateScaleBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateScaleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"scale\", NodeParticleBlockConnectionPointTypes.Vector2);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the scale input component\r\n     */\r\n    public get scale(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateScaleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.scale.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processScale = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.scale.copyFrom(this.scale.getConnectedValue(state) as Vector2);\r\n        };\r\n\r\n        const scaleProcessing = {\r\n            process: processScale,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(scaleProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = scaleProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateScaleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateScaleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateScaleBlock\", UpdateScaleBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the age of a particle\r\n */\r\nexport class UpdateAgeBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateAgeBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"age\", NodeParticleBlockConnectionPointTypes.Float);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the age input component\r\n     */\r\n    public get age(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateAgeBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.age.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processAge = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.age = this.age.getConnectedValue(state);\r\n        };\r\n\r\n        const ageProcessing = {\r\n            process: processAge,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(ageProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = ageProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateAgeBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateAgeBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateAgeBlock\", UpdateAgeBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide the basic update functionality for particles.\r\n */\r\nexport class BasicPositionUpdateBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new BasicPositionUpdateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BasicPositionUpdateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        const processPosition = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.direction.scaleToRef(particle._properties.directionScale, particle._properties.scaledDirection);\r\n            particle.position.addInPlace(particle._properties.scaledDirection);\r\n        };\r\n\r\n        const positionProcessing = {\r\n            process: processPosition,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(positionProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = positionProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for basicPositionUpdateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBasicPositionUpdateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BasicPositionUpdateBlock\", BasicPositionUpdateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to provide the basic update functionality for particle colors.\r\n */\r\nexport class BasicColorUpdateBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new BasicColorUpdateBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"BasicColorUpdateBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        const processColor = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            particle.colorStep.scaleToRef(system._scaledUpdateSpeed, system._scaledColorStep);\r\n            particle.color.addInPlace(system._scaledColorStep);\r\n\r\n            if (particle.color.a < 0) {\r\n                particle.color.a = 0;\r\n            }\r\n        };\r\n\r\n        const colorProcessing = {\r\n            process: processColor,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(colorProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = colorProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for basicColorUpdateBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBasicColorUpdateBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BasicColorUpdateBlock\", BasicColorUpdateBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to update the sprite cell index of a particle\r\n */\r\nexport class UpdateSpriteCellIndexBlock extends NodeParticleBlock {\r\n    /**\r\n     * Create a new UpdateSpriteCellIndexBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"cellIndex\", NodeParticleBlockConnectionPointTypes.Int);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n\r\n        this.cellIndex.acceptedConnectionPointTypes = [NodeParticleBlockConnectionPointTypes.Float];\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the cellIndex input component\r\n     */\r\n    public get cellIndex(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"UpdateSpriteCellIndexBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        if (!this.cellIndex.isConnected) {\r\n            return;\r\n        }\r\n\r\n        const processSpriteCellIndex = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n            particle.cellIndex = Math.floor(this.cellIndex.getConnectedValue(state));\r\n        };\r\n\r\n        const spriteCellIndexProcessing = {\r\n            process: processSpriteCellIndex,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(spriteCellIndexProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = spriteCellIndexProcessing;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for updateSpriteCellIndexBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterUpdateSpriteCellIndexBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.UpdateSpriteCellIndexBlock\", UpdateSpriteCellIndexBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { Vector3 } from \"../../../../Maths/math.vector.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"../../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to align the angle of a particle to its direction\r\n * We assume the sprite is facing +Y\r\n * NPE: #W5054F\r\n * PG: #H5RP91\r\n */\r\nexport class AlignAngleBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the strenght of the flow map effect\r\n     */\r\n    @editableInPropertyPage(\"alignment\", PropertyTypeForEdition.Float, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: -0, max: 2 * Math.PI })\r\n    public alignment = Math.PI / 2; // Default to 90 degrees, aligning +Y with direction\r\n\r\n    /**\r\n     * Create a new AlignAngleBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"particle\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the particle component\r\n     */\r\n    public get particle(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"AlignAngleBlock\";\r\n    }\r\n\r\n    /**\r\n     * Builds the block\r\n     * @param state defines the current build state\r\n     */\r\n    public override _build(state: NodeParticleBuildState) {\r\n        const system = this.particle.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        this.output._storedValue = system;\r\n\r\n        const tempVector3 = new Vector3();\r\n\r\n        const processAngle = (particle: Particle) => {\r\n            const cam = state.scene.activeCamera;\r\n            if (!cam) {\r\n                return;\r\n            }\r\n            const dir = particle.direction;\r\n            const view = cam.getViewMatrix();\r\n\r\n            const dirInView = Vector3.TransformNormalToRef(dir, view, tempVector3);\r\n\r\n            // Angle so sprite’s +Y aligns with projected direction\r\n            const angle = Math.atan2(dirInView.y, dirInView.x) + this.alignment;\r\n            particle.angle = angle; // radians\r\n        };\r\n\r\n        const angleProcessing = {\r\n            process: processAngle,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(angleProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = angleProcessing;\r\n        }\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.alignment = this.alignment;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.alignment !== undefined) {\r\n            this.alignment = serializationObject.alignment;\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for alignAngleBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAlignAngleBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.AlignAngleBlock\", AlignAngleBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../types\";\r\nimport { Vector2, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { Color4 } from \"core/Maths/math.color.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Trigonometry block\r\n */\r\nexport enum ParticleTrigonometryBlockOperations {\r\n    /** Cos */\r\n    Cos,\r\n    /** Sin */\r\n    Sin,\r\n    /** Abs */\r\n    Abs,\r\n    /** Exp */\r\n    Exp,\r\n    /** Exp2 */\r\n    Exp2,\r\n    /** Round */\r\n    Round,\r\n    /** Floor */\r\n    Floor,\r\n    /** Ceiling */\r\n    Ceiling,\r\n    /** Square root */\r\n    Sqrt,\r\n    /** Log */\r\n    Log,\r\n    /** Tangent */\r\n    Tan,\r\n    /** Arc tangent */\r\n    ArcTan,\r\n    /** Arc cosinus */\r\n    ArcCos,\r\n    /** Arc sinus */\r\n    ArcSin,\r\n    /** Sign */\r\n    Sign,\r\n    /** Negate */\r\n    Negate,\r\n    /** OneMinus */\r\n    OneMinus,\r\n    /** Reciprocal */\r\n    Reciprocal,\r\n    /** ToDegrees */\r\n    ToDegrees,\r\n    /** ToRadians */\r\n    ToRadians,\r\n    /** Fract */\r\n    Fract,\r\n}\r\n\r\n/**\r\n * Block used to apply trigonometry operation to floats\r\n */\r\nexport class ParticleTrigonometryBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        embedded: true,\r\n        notifiers: { rebuild: true },\r\n        options: [\r\n            { label: \"Cos\", value: ParticleTrigonometryBlockOperations.Cos },\r\n            { label: \"Sin\", value: ParticleTrigonometryBlockOperations.Sin },\r\n            { label: \"Abs\", value: ParticleTrigonometryBlockOperations.Abs },\r\n            { label: \"Exp\", value: ParticleTrigonometryBlockOperations.Exp },\r\n            { label: \"Exp2\", value: ParticleTrigonometryBlockOperations.Exp2 },\r\n            { label: \"Round\", value: ParticleTrigonometryBlockOperations.Round },\r\n            { label: \"Floor\", value: ParticleTrigonometryBlockOperations.Floor },\r\n            { label: \"Ceiling\", value: ParticleTrigonometryBlockOperations.Ceiling },\r\n            { label: \"Sqrt\", value: ParticleTrigonometryBlockOperations.Sqrt },\r\n            { label: \"Log\", value: ParticleTrigonometryBlockOperations.Log },\r\n            { label: \"Tan\", value: ParticleTrigonometryBlockOperations.Tan },\r\n            { label: \"ArcTan\", value: ParticleTrigonometryBlockOperations.ArcTan },\r\n            { label: \"ArcCos\", value: ParticleTrigonometryBlockOperations.ArcCos },\r\n            { label: \"ArcSin\", value: ParticleTrigonometryBlockOperations.ArcSin },\r\n            { label: \"Sign\", value: ParticleTrigonometryBlockOperations.Sign },\r\n            { label: \"Negate\", value: ParticleTrigonometryBlockOperations.Negate },\r\n            { label: \"OneMinus\", value: ParticleTrigonometryBlockOperations.OneMinus },\r\n            { label: \"Reciprocal\", value: ParticleTrigonometryBlockOperations.Reciprocal },\r\n            { label: \"ToDegrees\", value: ParticleTrigonometryBlockOperations.ToDegrees },\r\n            { label: \"ToRadians\", value: ParticleTrigonometryBlockOperations.ToRadians },\r\n            { label: \"Fract\", value: ParticleTrigonometryBlockOperations.Fract },\r\n        ],\r\n    })\r\n    public operation = ParticleTrigonometryBlockOperations.Cos;\r\n\r\n    /**\r\n     * Creates a new GeometryTrigonometryBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n\r\n        this._inputs[0].addExcludedConnectionPointFromAllowedTypes(\r\n            NodeParticleBlockConnectionPointTypes.Float |\r\n                NodeParticleBlockConnectionPointTypes.Int |\r\n                NodeParticleBlockConnectionPointTypes.Vector2 |\r\n                NodeParticleBlockConnectionPointTypes.Vector3 |\r\n                NodeParticleBlockConnectionPointTypes.Color4\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleTrigonometryBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        super._build(state);\r\n        let func: Nullable<(value: number) => number> = null;\r\n\r\n        switch (this.operation) {\r\n            case ParticleTrigonometryBlockOperations.Cos: {\r\n                func = (value: number) => Math.cos(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Sin: {\r\n                func = (value: number) => Math.sin(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Abs: {\r\n                func = (value: number) => Math.abs(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Exp: {\r\n                func = (value: number) => Math.exp(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Exp2: {\r\n                func = (value: number) => Math.pow(2, value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Round: {\r\n                func = (value: number) => Math.round(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Floor: {\r\n                func = (value: number) => Math.floor(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Ceiling: {\r\n                func = (value: number) => Math.ceil(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Sqrt: {\r\n                func = (value: number) => Math.sqrt(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Log: {\r\n                func = (value: number) => Math.log(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Tan: {\r\n                func = (value: number) => Math.tan(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.ArcTan: {\r\n                func = (value: number) => Math.atan(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.ArcCos: {\r\n                func = (value: number) => Math.acos(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.ArcSin: {\r\n                func = (value: number) => Math.asin(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Sign: {\r\n                func = (value: number) => Math.sign(value);\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Negate: {\r\n                func = (value: number) => -value;\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.OneMinus: {\r\n                func = (value: number) => 1 - value;\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Reciprocal: {\r\n                func = (value: number) => 1 / value;\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.ToRadians: {\r\n                func = (value: number) => (value * Math.PI) / 180;\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.ToDegrees: {\r\n                func = (value: number) => (value * 180) / Math.PI;\r\n                break;\r\n            }\r\n            case ParticleTrigonometryBlockOperations.Fract: {\r\n                func = (value: number) => {\r\n                    if (value >= 0) {\r\n                        return value - Math.floor(value);\r\n                    } else {\r\n                        return value - Math.ceil(value);\r\n                    }\r\n                };\r\n                break;\r\n            }\r\n        }\r\n        if (!func) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        switch (this.input.type) {\r\n            case NodeParticleBlockConnectionPointTypes.Int:\r\n            case NodeParticleBlockConnectionPointTypes.Float: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return func(source);\r\n                };\r\n                break;\r\n            }\r\n            case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector2(func(source.x), func(source.y));\r\n                };\r\n                break;\r\n            }\r\n            case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Vector3(func(source.x), func(source.y), func(source.z));\r\n                };\r\n                break;\r\n            }\r\n            case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                this.output._storedFunction = (state) => {\r\n                    const source = this.input.getConnectedValue(state);\r\n                    return new Color4(func(source.r), func(source.g), func(source.b), func(source.a));\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleTrigonometryBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleTrigonometryBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleTrigonometryBlock\", ParticleTrigonometryBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { Vector2ToFixed, Vector3ToFixed } from \"../../../Maths/math.vector.functions\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { Observable } from \"core/Misc/observable.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to debug values going through it\r\n */\r\nexport class ParticleDebugBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets the log entries\r\n     */\r\n    public log: string[][] = [];\r\n\r\n    /**\r\n     * Gets or sets the number of logs to keep\r\n     */\r\n    @editableInPropertyPage(\"Reference\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: false, notifiers: { rebuild: true }, min: 1, max: 100 })\r\n    public stackSize = 10;\r\n\r\n    /**\r\n     * Create a new ParticleDebugBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isDebug = true;\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.FloatGradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Vector2Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Vector3Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Color4Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.System);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleDebugBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /**\r\n     * Observable raised when data is collected\r\n     */\r\n    public onDataCollectedObservable = new Observable<ParticleDebugBlock>(undefined, true);\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        if (!this.input.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        this.log = [];\r\n        const func = (state: NodeParticleBuildState) => {\r\n            const input = this.input.getConnectedValue(state);\r\n\r\n            if (this.log.length >= this.stackSize) {\r\n                return input;\r\n            }\r\n\r\n            if (input === null || input === undefined) {\r\n                this.log.push([\"null\", \"\"]);\r\n                return input;\r\n            }\r\n\r\n            switch (this.input.type) {\r\n                case NodeParticleBlockConnectionPointTypes.Vector2:\r\n                    this.log.push([Vector2ToFixed(input, 4), input.toString()]);\r\n                    break;\r\n                case NodeParticleBlockConnectionPointTypes.Vector3:\r\n                    this.log.push([Vector3ToFixed(input, 4), input.toString()]);\r\n                    break;\r\n                case NodeParticleBlockConnectionPointTypes.Color4:\r\n                    this.log.push([`{R: ${input.r.toFixed(4)} G: ${input.g.toFixed(4)} B: ${input.b.toFixed(4)} A: ${input.a.toFixed(4)}}`, input.toString()]);\r\n                    break;\r\n                default:\r\n                    this.log.push([input.toString(), input.toString()]);\r\n                    break;\r\n            }\r\n\r\n            this.onDataCollectedObservable.notifyObservers(this);\r\n\r\n            return input;\r\n        };\r\n\r\n        if (this.output.isConnected) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.stackSize = this.stackSize;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.stackSize = serializationObject.stackSize;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        this.onDataCollectedObservable.clear();\r\n        super.dispose();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleDebugBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleDebugBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleDebugBlock\", ParticleDebugBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n/**\r\n * Block used as a pass through\r\n */\r\nexport class ParticleElbowBlock extends NodeParticleBlock {\r\n    /**\r\n     * Creates a new ParticleElbowBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleElbowBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        super._build(state);\r\n\r\n        const output = this._outputs[0];\r\n        const input = this._inputs[0];\r\n\r\n        output._storedFunction = (state) => {\r\n            return input.getConnectedValue(state);\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleElbowBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleElbowBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleElbowBlock\", ParticleElbowBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type ParticleTeleportOutBlock } from \"./particleTeleportOutBlock.pure\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to teleport a value to an endpoint\r\n */\r\nexport class ParticleTeleportInBlock extends NodeParticleBlock {\r\n    private _endpoints: ParticleTeleportOutBlock[] = [];\r\n\r\n    /** Gets the list of attached endpoints */\r\n    public get endpoints() {\r\n        return this._endpoints;\r\n    }\r\n\r\n    /**\r\n     * Create a new ParticleTeleportInBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n        this._isTeleportIn = true;\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleTeleportInBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given type\r\n     * @param type defines the potential type to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOfType(type: string): boolean {\r\n        if (this.getClassName() === type) {\r\n            return true;\r\n        }\r\n\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint.isAnAncestorOfType(type)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if the current block is an ancestor of a given block\r\n     * @param block defines the potential descendant block to check\r\n     * @returns true if block is a descendant\r\n     */\r\n    public override isAnAncestorOf(block: NodeParticleBlock): boolean {\r\n        for (const endpoint of this.endpoints) {\r\n            if (endpoint === block) {\r\n                return true;\r\n            }\r\n\r\n            if (endpoint.isAnAncestorOf(block)) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Add an enpoint to this block\r\n     * @param endpoint define the endpoint to attach to\r\n     */\r\n    public attachToEndpoint(endpoint: ParticleTeleportOutBlock) {\r\n        endpoint.detach();\r\n\r\n        this._endpoints.push(endpoint);\r\n        endpoint._entryPoint = this;\r\n        endpoint._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        endpoint._tempEntryPointUniqueId = null;\r\n        endpoint.name = \"> \" + this.name;\r\n    }\r\n\r\n    /**\r\n     * Remove enpoint from this block\r\n     * @param endpoint define the endpoint to remove\r\n     */\r\n    public detachFromEndpoint(endpoint: ParticleTeleportOutBlock) {\r\n        const index = this._endpoints.indexOf(endpoint);\r\n\r\n        if (index !== -1) {\r\n            this._endpoints.splice(index, 1);\r\n            endpoint._outputs[0]._typeConnectionSource = null;\r\n            endpoint._entryPoint = null;\r\n        }\r\n    }\r\n\r\n    public override _build() {\r\n        for (const endpoint of this._endpoints) {\r\n            endpoint.output._storedFunction = (state) => {\r\n                return this.input.getConnectedValue(state);\r\n            };\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleTeleportInBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleTeleportInBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleTeleportInBlock\", ParticleTeleportInBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../../../types\";\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type ParticleTeleportInBlock } from \"./particleTeleportInBlock.pure\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * Defines a block used to receive a value from a teleport entry point\r\n */\r\nexport class ParticleTeleportOutBlock extends NodeParticleBlock {\r\n    /** @internal */\r\n    public _entryPoint: Nullable<ParticleTeleportInBlock> = null;\r\n    /** @internal */\r\n    public _tempEntryPointUniqueId: Nullable<number> = null;\r\n\r\n    /**\r\n     * Create a new ParticleTeleportOutBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isTeleportOut = true;\r\n\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n    }\r\n\r\n    /**\r\n     * Gets the entry point\r\n     */\r\n    public get entryPoint() {\r\n        return this._entryPoint;\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleTeleportOutBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    /** Detach from entry point */\r\n    public detach() {\r\n        if (!this._entryPoint) {\r\n            return;\r\n        }\r\n        this._entryPoint.detachFromEndpoint(this);\r\n    }\r\n\r\n    public override _build() {\r\n        // Do nothing\r\n        // All work done by the emitter\r\n    }\r\n\r\n    protected override _customBuildStep(state: NodeParticleBuildState): void {\r\n        if (this.entryPoint) {\r\n            this.entryPoint.build(state);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clone the current block to a new identical block\r\n     * @returns a copy of the current block\r\n     */\r\n    public override clone() {\r\n        const clone = super.clone();\r\n\r\n        if (this.entryPoint) {\r\n            this.entryPoint.attachToEndpoint(clone as ParticleTeleportOutBlock);\r\n        }\r\n\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.entryPoint = this.entryPoint?.uniqueId ?? \"\";\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this._tempEntryPointUniqueId = serializationObject.entryPoint;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleTeleportOutBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleTeleportOutBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleTeleportOutBlock\", ParticleTeleportOutBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { NodeParticleBlock } from \"../../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../../nodeParticleBuildState\";\r\nimport { type ThinParticleSystem } from \"core/Particles/thinParticleSystem.pure\";\r\nimport { type Particle } from \"core/Particles/particle\";\r\nimport { _ConnectAtTheEnd } from \"core/Particles/Queue/executionQueue\";\r\nimport { type SystemBlock } from \"../systemBlock.pure\";\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { _TriggerSubEmitter } from \"./triggerTools\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Block used to trigger a particle system based on a condition.\r\n */\r\nexport class ParticleTriggerBlock extends NodeParticleBlock {\r\n    private _triggerCount = 0;\r\n\r\n    /**\r\n     * Gets or sets the emit rate\r\n     */\r\n    @editableInPropertyPage(\"Max simultaneous\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public limit = 5;\r\n\r\n    /**\r\n     * Gets or sets the emit rate\r\n     */\r\n    @editableInPropertyPage(\"Delay between calls (ms)\", PropertyTypeForEdition.Int, \"ADVANCED\", { embedded: true, notifiers: { rebuild: true }, min: 0 })\r\n    public delay = 250;\r\n\r\n    /**\r\n     * Create a new ParticleTriggerBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.Particle);\r\n        this.registerInput(\"condition\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"system\", NodeParticleBlockConnectionPointTypes.System);\r\n\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Particle);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleTriggerBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the condition input component\r\n     */\r\n    public get condition(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the target system input component\r\n     */\r\n    public get system(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    private _previousOne: Nullable<number> = null;\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        this._triggerCount = 0;\r\n        const system = this.input.getConnectedValue(state) as ThinParticleSystem;\r\n\r\n        const processCondition = (particle: Particle) => {\r\n            state.particleContext = particle;\r\n            state.systemContext = system;\r\n\r\n            if (this.condition.getConnectedValue(state) !== 0) {\r\n                if (this.limit === 0 || this._triggerCount < this.limit) {\r\n                    const now = new Date().getTime();\r\n                    if (this._previousOne && now - this._previousOne < this.delay) {\r\n                        return; // Skip if the delay has not passed\r\n                    }\r\n\r\n                    this._triggerCount++;\r\n                    this._previousOne = now;\r\n                    // Trigger the target particle system\r\n                    const targetSystem = this.system.getConnectedValue(state) as SystemBlock;\r\n                    if (targetSystem) {\r\n                        const clone = _TriggerSubEmitter(targetSystem, state.scene, particle.position);\r\n                        clone.onDisposeObservable.addOnce(() => {\r\n                            this._triggerCount--;\r\n                        });\r\n\r\n                        system.onDisposeObservable.addOnce(() => {\r\n                            // Clean up the cloned system when the original system is disposed\r\n                            clone.dispose();\r\n                        });\r\n                    }\r\n                }\r\n            }\r\n        };\r\n\r\n        const conditionProcessing = {\r\n            process: processCondition,\r\n            previousItem: null,\r\n            nextItem: null,\r\n        };\r\n\r\n        if (system._updateQueueStart) {\r\n            _ConnectAtTheEnd(conditionProcessing, system._updateQueueStart);\r\n        } else {\r\n            system._updateQueueStart = conditionProcessing;\r\n        }\r\n\r\n        this.output._storedValue = system;\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.limit = this.limit;\r\n        serializationObject.delay = this.delay;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        if (serializationObject.limit !== undefined) {\r\n            this.limit = serializationObject.limit;\r\n        }\r\n\r\n        if (serializationObject.delay !== undefined) {\r\n            this.delay = serializationObject.delay;\r\n        }\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this._triggerCount = 0;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleTriggerBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleTriggerBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleTriggerBlock\", ParticleTriggerBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { editableInPropertyPage, PropertyTypeForEdition } from \"core/Decorators/nodeDecorator\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\nexport enum ParticleLocalVariableBlockScope {\r\n    Particle = 0,\r\n    Loop = 1,\r\n}\r\n\r\n/**\r\n * Defines a block used to store local values\r\n * #A1OS53#5\r\n */\r\nexport class ParticleLocalVariableBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the scope used by the block\r\n     */\r\n    @editableInPropertyPage(\"Scope\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        embedded: true,\r\n        notifiers: { rebuild: true },\r\n        options: [\r\n            { label: \"Particle\", value: ParticleLocalVariableBlockScope.Particle },\r\n            { label: \"Loop\", value: ParticleLocalVariableBlockScope.Loop },\r\n        ],\r\n    })\r\n    public scope = ParticleLocalVariableBlockScope.Particle;\r\n    private _storage = new Map<number, any>();\r\n\r\n    /**\r\n     * Create a new ParticleLocalVariableBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this._isDebug = true;\r\n\r\n        this.registerInput(\"input\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.FloatGradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Vector2Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Vector3Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Color4Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.System);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleLocalVariableBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the input component\r\n     */\r\n    public get input(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        if (!this.input.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (state: NodeParticleBuildState) => {\r\n            if (!state.particleContext && !state.systemContext) {\r\n                this._storage.clear();\r\n                return null;\r\n            }\r\n\r\n            const id = (this.scope === ParticleLocalVariableBlockScope.Particle ? state.particleContext?.id : state.systemContext?.getScene()!.getFrameId()) || -1;\r\n\r\n            if (!this._storage.has(id)) {\r\n                let value = this.input.getConnectedValue(state);\r\n\r\n                if (value.clone) {\r\n                    value = value.clone(); // We clone to snapshot the value at this moment\r\n                }\r\n                this._storage.set(id, value);\r\n\r\n                if (this.scope === ParticleLocalVariableBlockScope.Particle) {\r\n                    state.particleContext!._properties.onReset = () => {\r\n                        this._storage.delete(id);\r\n                        state.particleContext!._properties.onReset = null;\r\n                    };\r\n                }\r\n                state.systemContext!.onDisposeObservable.addOnce(() => {\r\n                    this._storage.clear();\r\n                });\r\n            }\r\n\r\n            return this._storage.get(id);\r\n        };\r\n\r\n        if (this.output.isConnected) {\r\n            this.output._storedFunction = func;\r\n        } else {\r\n            this.output._storedValue = func(state);\r\n        }\r\n    }\r\n\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.scope = this.scope;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.scope = serializationObject.scope;\r\n    }\r\n\r\n    public override dispose() {\r\n        this._storage.clear();\r\n        super.dispose();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleLocalVariableBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleLocalVariableBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleLocalVariableBlock\", ParticleLocalVariableBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\n\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Number Math block\r\n */\r\nexport enum ParticleNumberMathBlockOperations {\r\n    /** Modulo */\r\n    Modulo,\r\n    /** Power */\r\n    Pow,\r\n}\r\n\r\n/**\r\n * Block used to apply math operations that only appply to numbers (int/float)\r\n */\r\nexport class ParticleNumberMathBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Modulo\", value: ParticleNumberMathBlockOperations.Modulo },\r\n            { label: \"Power\", value: ParticleNumberMathBlockOperations.Pow },\r\n        ],\r\n    })\r\n    public operation = ParticleNumberMathBlockOperations.Modulo;\r\n\r\n    private readonly _connectionObservers: Observer<NodeParticleConnectionPoint>[];\r\n\r\n    /**\r\n     * Create a new ParticleNumberMathBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        this.left.acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Int);\r\n        this.left.acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Float);\r\n        this.right.acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Int);\r\n        this.right.acceptedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Float);\r\n\r\n        const excludedConnectionPointTypes = [\r\n            NodeParticleBlockConnectionPointTypes.Vector2,\r\n            NodeParticleBlockConnectionPointTypes.Vector3,\r\n            NodeParticleBlockConnectionPointTypes.Matrix,\r\n            NodeParticleBlockConnectionPointTypes.Particle,\r\n            NodeParticleBlockConnectionPointTypes.Texture,\r\n            NodeParticleBlockConnectionPointTypes.Color4,\r\n            NodeParticleBlockConnectionPointTypes.FloatGradient,\r\n            NodeParticleBlockConnectionPointTypes.Vector2Gradient,\r\n            NodeParticleBlockConnectionPointTypes.Vector3Gradient,\r\n            NodeParticleBlockConnectionPointTypes.Color4Gradient,\r\n            NodeParticleBlockConnectionPointTypes.System,\r\n            NodeParticleBlockConnectionPointTypes.Undefined,\r\n        ] as const;\r\n\r\n        this.left.excludedConnectionPointTypes.push(...excludedConnectionPointTypes);\r\n        this.right.excludedConnectionPointTypes.push(...excludedConnectionPointTypes);\r\n\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._connectionObservers = [\r\n            this.left.onConnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.left.onDisconnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onConnectionObservable.add(() => this._updateInputOutputTypes()),\r\n            this.right.onDisconnectionObservable.add(() => this._updateInputOutputTypes()),\r\n        ];\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleNumberMathBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left input component\r\n     */\r\n    public get left(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right input component\r\n     */\r\n    public get right(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        let func: (state: NodeParticleBuildState) => any;\r\n        const left = this.left;\r\n        const right = this.right;\r\n\r\n        if (!left.isConnected || !right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        switch (this.operation) {\r\n            case ParticleNumberMathBlockOperations.Modulo: {\r\n                func = (state) => {\r\n                    return left.getConnectedValue(state) % right.getConnectedValue(state);\r\n                };\r\n                break;\r\n            }\r\n            case ParticleNumberMathBlockOperations.Pow: {\r\n                func = (state) => {\r\n                    return Math.pow(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            // We use the left type to determine if we need to cast to int\r\n            if (left.type === NodeParticleBlockConnectionPointTypes.Int) {\r\n                return func(state) | 0;\r\n            }\r\n            return func(state);\r\n        };\r\n    }\r\n\r\n    private _updateInputOutputTypes() {\r\n        // First update the output type with the initial assumption that we'll base it on the left input.\r\n        this.output._typeConnectionSource = this.left;\r\n\r\n        // If left is not connected, then instead use the type of right if it's connected.\r\n        if (!this.left.isConnected && this.right.isConnected) {\r\n            this.output._typeConnectionSource = this.right;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Release resources\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n        for (const observer of this._connectionObservers) {\r\n            observer.remove();\r\n        }\r\n        this._connectionObservers.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a JSON object\r\n     * @param serializationObject the JSON object to deserialize from\r\n     */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleNumberMathBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleNumberMathBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleNumberMathBlock\", ParticleNumberMathBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\n\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { PropertyTypeForEdition, editableInPropertyPage } from \"../../../Decorators/nodeDecorator\";\r\nimport { Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Operations supported by the Vector Math block\r\n */\r\nexport enum ParticleVectorMathBlockOperations {\r\n    /** Dot product */\r\n    Dot,\r\n    /** Distance between two vectors */\r\n    Distance,\r\n}\r\n\r\n/**\r\n * Block used to apply math operations that only apply to vectors\r\n */\r\nexport class ParticleVectorMathBlock extends NodeParticleBlock {\r\n    /**\r\n     * Gets or sets the operation applied by the block\r\n     */\r\n    @editableInPropertyPage(\"Operation\", PropertyTypeForEdition.List, \"ADVANCED\", {\r\n        notifiers: { rebuild: true },\r\n        embedded: true,\r\n        options: [\r\n            { label: \"Dot\", value: ParticleVectorMathBlockOperations.Dot },\r\n            { label: \"Distance\", value: ParticleVectorMathBlockOperations.Distance },\r\n        ],\r\n    })\r\n    public operation = ParticleVectorMathBlockOperations.Dot;\r\n\r\n    /**\r\n     * Create a new ParticleVectorMathBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeParticleBlockConnectionPointTypes.Vector3);\r\n        this.registerInput(\"right\", NodeParticleBlockConnectionPointTypes.Vector3);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.Float);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleVectorMathBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left input component\r\n     */\r\n    public get left(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right input component\r\n     */\r\n    public get right(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        let func: (state: NodeParticleBuildState) => any;\r\n        const left = this.left;\r\n        const right = this.right;\r\n\r\n        if (!left.isConnected || !right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        switch (this.operation) {\r\n            case ParticleVectorMathBlockOperations.Dot: {\r\n                func = (state) => {\r\n                    return Vector3.Dot(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n            case ParticleVectorMathBlockOperations.Distance: {\r\n                func = (state) => {\r\n                    return Vector3.Distance(left.getConnectedValue(state), right.getConnectedValue(state));\r\n                };\r\n                break;\r\n            }\r\n        }\r\n\r\n        this.output._storedFunction = (state) => {\r\n            return func(state);\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Serializes this block in a JSON representation\r\n     * @returns the serialized block object\r\n     */\r\n    public override serialize(): any {\r\n        const serializationObject = super.serialize();\r\n\r\n        serializationObject.operation = this.operation;\r\n\r\n        return serializationObject;\r\n    }\r\n\r\n    /**\r\n     * Deserializes the block from a JSON object\r\n     * @param serializationObject the JSON object to deserialize from\r\n     */\r\n    public override _deserialize(serializationObject: any) {\r\n        super._deserialize(serializationObject);\r\n\r\n        this.operation = serializationObject.operation;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleVectorMathBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleVectorMathBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleVectorMathBlock\", ParticleVectorMathBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { Color4 } from \"../../../Maths/math.color.pure\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to clamp a float\r\n */\r\nexport class ParticleClampBlock extends NodeParticleBlock {\r\n    /** Gets or sets the minimum range */\r\n    public get minimum() {\r\n        return this.min.value;\r\n    }\r\n\r\n    public set minimum(value: number) {\r\n        this.min.value = value;\r\n    }\r\n\r\n    /** Gets or sets the maximum range */\r\n    public get maximum() {\r\n        return this.max.value;\r\n    }\r\n\r\n    public set maximum(value: number) {\r\n        this.max.value = value;\r\n    }\r\n\r\n    /**\r\n     * Creates a new ParticleClampBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"min\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"max\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Texture);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.FloatGradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Vector2Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Vector3Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Color4Gradient);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.System);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleClampBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value input component\r\n     */\r\n    public get value(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the min input component\r\n     */\r\n    public get min(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the max input component\r\n     */\r\n    public get max(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(state: NodeParticleBuildState) {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (value: number, min: number, max: number) => {\r\n            return Math.max(min, Math.min(value, max));\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const value = this.value.getConnectedValue(state);\r\n            const min = this.min.isConnected ? this.min.getConnectedValue(state) : this.minimum;\r\n            const max = this.max.isConnected ? this.max.getConnectedValue(state) : this.maximum;\r\n\r\n            switch (this.value.type) {\r\n                case NodeParticleBlockConnectionPointTypes.Int:\r\n                case NodeParticleBlockConnectionPointTypes.Float: {\r\n                    return func(value, min, max);\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(value.x, min, max), func(value.y, min, max));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(value.x, min, max), func(value.y, min, max), func(value.z, min, max));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                    return new Color4(func(value.r, min, max), func(value.g, min, max), func(value.b, min, max), func(value.a, min, max));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleClampBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleClampBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleClampBlock\", ParticleClampBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../../Maths/math.color.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { type NodeParticleBuildState } from \"../nodeParticleBuildState\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to normalize lerp between 2 values\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class ParticleNLerpBlock extends NodeParticleBlock {\r\n    /**\r\n     * Creates a new ParticleNLerpBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"left\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"right\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"gradient\", NodeParticleBlockConnectionPointTypes.Float, true, 0, 0, 1);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._linkConnectionTypes(0, 1);\r\n\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleNLerpBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the left operand input component\r\n     */\r\n    public get left(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the right operand input component\r\n     */\r\n    public get right(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the gradient operand input component\r\n     */\r\n    public get gradient(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build(_state: NodeParticleBuildState) {\r\n        if (!this.left.isConnected || !this.right.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (gradient: number, left: number, right: number) => {\r\n            return (1 - gradient) * left + gradient * right;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const left = this.left.getConnectedValue(state);\r\n            const right = this.right.getConnectedValue(state);\r\n            const gradient = this.gradient.getConnectedValue(state);\r\n            switch (this.left.type) {\r\n                case NodeParticleBlockConnectionPointTypes.Int:\r\n                case NodeParticleBlockConnectionPointTypes.Float: {\r\n                    return func(gradient, left, right); // NLerp is really lerp in that case\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                    const result = new Vector2(func(gradient, left.x, right.x), func(gradient, left.y, right.y));\r\n                    result.normalize();\r\n\r\n                    return result;\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                    const result = new Vector3(func(gradient, left.x, right.x), func(gradient, left.y, right.y), func(gradient, left.z, right.z));\r\n                    result.normalize();\r\n\r\n                    return result;\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                    const result = new Color4(func(gradient, left.r, right.r), func(gradient, left.g, right.g), func(gradient, left.b, right.b), func(gradient, left.a, right.a));\r\n                    // Color4 has no normalize(), so normalize in place to match the other cases\r\n                    const len = Math.sqrt(result.r * result.r + result.g * result.g + result.b * result.b + result.a * result.a);\r\n                    if (len !== 0) {\r\n                        result.scaleInPlace(1 / len);\r\n                    }\r\n\r\n                    return result;\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleNLerpBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function RegisterParticleNLerpBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleNLerpBlock\", ParticleNLerpBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../../Maths/math.color.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to smooth step a value\r\n */\r\nexport class ParticleSmoothStepBlock extends NodeParticleBlock {\r\n    /**\r\n     * Creates a new ParticleSmoothStepBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"edge0\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerInput(\"edge1\", NodeParticleBlockConnectionPointTypes.Float, true, 1);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleSmoothStepBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the first edge operand input component\r\n     */\r\n    public get edge0(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the second edge operand input component\r\n     */\r\n    public get edge1(): NodeParticleConnectionPoint {\r\n        return this._inputs[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n\r\n        const func = (value: number, edge0: number, edge1: number) => {\r\n            const x = Math.max(0, Math.min((value - edge0) / (edge1 - edge0), 1));\r\n\r\n            // Smoothstep formula: 3x^2 - 2x^3\r\n            return x * x * (3 - 2 * x);\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const source = this.value.getConnectedValue(state);\r\n            const edge0 = this.edge0.getConnectedValue(state);\r\n            const edge1 = this.edge1.getConnectedValue(state);\r\n            switch (this.value.type) {\r\n                case NodeParticleBlockConnectionPointTypes.Int:\r\n                case NodeParticleBlockConnectionPointTypes.Float: {\r\n                    return func(source, edge0, edge1);\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(source.x, edge0, edge1), func(source.y, edge0, edge1));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(source.x, edge0, edge1), func(source.y, edge0, edge1), func(source.z, edge0, edge1));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                    return new Color4(func(source.r, edge0, edge1), func(source.g, edge0, edge1), func(source.b, edge0, edge1), func(source.a, edge0, edge1));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleSmoothStepBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleSmoothStepBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleSmoothStepBlock\", ParticleSmoothStepBlock);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Color4 } from \"../../../Maths/math.color.pure\";\r\nimport { NodeParticleBlock } from \"../nodeParticleBlock\";\r\nimport { type NodeParticleConnectionPoint } from \"../nodeParticleBlockConnectionPoint\";\r\nimport { NodeParticleBlockConnectionPointTypes } from \"../Enums/nodeParticleBlockConnectionPointTypes\";\r\nimport { RegisterClass } from \"../../../Misc/typeStore\";\r\n\r\n/**\r\n * Block used to step a value\r\n */\r\nexport class ParticleStepBlock extends NodeParticleBlock {\r\n    /**\r\n     * Creates a new ParticleStepBlock\r\n     * @param name defines the block name\r\n     */\r\n    public constructor(name: string) {\r\n        super(name);\r\n\r\n        this.registerInput(\"value\", NodeParticleBlockConnectionPointTypes.AutoDetect);\r\n        this.registerInput(\"edge\", NodeParticleBlockConnectionPointTypes.Float, true, 0);\r\n        this.registerOutput(\"output\", NodeParticleBlockConnectionPointTypes.BasedOnInput);\r\n\r\n        this._outputs[0]._typeConnectionSource = this._inputs[0];\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Matrix);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Particle);\r\n        this._inputs[0].excludedConnectionPointTypes.push(NodeParticleBlockConnectionPointTypes.Texture);\r\n    }\r\n\r\n    /**\r\n     * Gets the current class name\r\n     * @returns the class name\r\n     */\r\n    public override getClassName() {\r\n        return \"ParticleStepBlock\";\r\n    }\r\n\r\n    /**\r\n     * Gets the value operand input component\r\n     */\r\n    public get value(): NodeParticleConnectionPoint {\r\n        return this._inputs[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the edge operand input component\r\n     */\r\n    public get edge(): NodeParticleConnectionPoint {\r\n        return this._inputs[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the output component\r\n     */\r\n    public get output(): NodeParticleConnectionPoint {\r\n        return this._outputs[0];\r\n    }\r\n\r\n    public override _build() {\r\n        if (!this.value.isConnected) {\r\n            this.output._storedFunction = null;\r\n            this.output._storedValue = null;\r\n            return;\r\n        }\r\n        const func = (value: number, edge: number) => {\r\n            if (value < edge) {\r\n                return 0;\r\n            }\r\n\r\n            return 1;\r\n        };\r\n\r\n        this.output._storedFunction = (state) => {\r\n            const source = this.value.getConnectedValue(state);\r\n            const edge = this.edge.getConnectedValue(state);\r\n            switch (this.value.type) {\r\n                case NodeParticleBlockConnectionPointTypes.Int:\r\n                case NodeParticleBlockConnectionPointTypes.Float: {\r\n                    return func(source, edge);\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector2: {\r\n                    return new Vector2(func(source.x, edge), func(source.y, edge));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Vector3: {\r\n                    return new Vector3(func(source.x, edge), func(source.y, edge), func(source.z, edge));\r\n                }\r\n                case NodeParticleBlockConnectionPointTypes.Color4: {\r\n                    return new Color4(func(source.r, edge), func(source.g, edge), func(source.b, edge), func(source.a, edge));\r\n                }\r\n            }\r\n\r\n            return 0;\r\n        };\r\n\r\n        return this;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for particleStepBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterParticleStepBlock(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ParticleStepBlock\", ParticleStepBlock);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { geometryRenderingFragment } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"particlesPixelShader\";\nconst shader = `#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\nvarying vec2 vUV;varying vec4 vColor;uniform vec4 textureMask;uniform sampler2D diffuseSampler;\n#ifdef PREPASS\nuniform float geometryZeroAlphaDiscard;\n#ifdef PREPASS_POSITION\nvarying vec3 vGeometryPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vGeometryNormalW;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vGeometryNormalV;\n#endif\n#endif\n#define PREPASS_VELOCITY_ZERO\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<clipPlaneFragmentDeclaration>\n#include<imageProcessingDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#ifdef RAMPGRADIENT\nvarying vec4 remapRanges;uniform sampler2D rampSampler;\n#endif\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvec4 textureColor=texture2D(diffuseSampler,vUV);vec4 baseColor=(textureColor*textureMask+(vec4(1.,1.,1.,1.)-textureMask))*vColor;\n#ifdef PREPASS\nvec3 geometryAlbedo=toLinearSpace(baseColor.rgb);\n#endif\n#ifdef RAMPGRADIENT\nfloat alpha=baseColor.a;float remappedColorIndex=clamp((alpha-remapRanges.x)/remapRanges.y,0.0,1.0);vec4 rampColor=texture2D(rampSampler,vec2(1.0-remappedColorIndex,0.));baseColor.rgb*=rampColor.rgb;float finalAlpha=baseColor.a;baseColor.a=clamp((alpha*rampColor.a-remapRanges.z)/remapRanges.w,0.0,1.0);\n#endif\n#ifdef BLENDMULTIPLYMODE\nfloat sourceAlpha=vColor.a*textureColor.a;baseColor.rgb=baseColor.rgb*sourceAlpha+vec3(1.0)*(1.0-sourceAlpha);\n#endif\n#include<logDepthFragment>\n#include<fogFragment>(color,baseColor)\n#ifdef IMAGEPROCESSINGPOSTPROCESS\nbaseColor.rgb=toLinearSpace(baseColor.rgb);\n#else\n#ifdef IMAGEPROCESSING\nbaseColor.rgb=toLinearSpace(baseColor.rgb);baseColor=applyImageProcessing(baseColor);\n#endif\n#endif\ngl_FragColor=baseColor;\n#ifdef PREPASS\nvec4 geometryColor=gl_FragColor;if (geometryColor.a<=0.0 && geometryZeroAlphaDiscard>0.0) {discard;}\n#ifdef PREPASS_POSITION\nvec3 geometryPositionW=vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvec3 geometryPositionL=vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nfloat geometryViewDepth=vViewPos.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfloat geometryNormalizedViewDepth=vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvec3 geometryNormalV=normalize(vGeometryNormalV);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvec3 geometryNormalW=normalize(vGeometryNormalW);\n#endif\n#include<geometryRenderingFragment>\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [objectIdFunctions, prePassDeclaration, clipPlaneFragmentDeclaration, imageProcessingDeclaration, logDepthDeclaration, helperFunctions, imageProcessingFunctions, fogFragmentDeclaration, clipPlaneFragment, logDepthFragment, fogFragment, geometryRenderingFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const particlesPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"particlesVertexShader\";\nconst shader = `attribute vec3 position;attribute vec4 color;attribute float angle;attribute vec2 size;\n#ifdef ANIMATESHEET\nattribute float cellIndex;\n#endif\n#ifndef BILLBOARD\nattribute vec3 direction;\n#endif\n#ifdef BILLBOARDSTRETCHED\nattribute vec3 direction;\n#endif\n#ifdef RAMPGRADIENT\nattribute vec4 remapData;\n#endif\nattribute vec2 offset;uniform mat4 view;uniform mat4 projection;uniform vec2 translationPivot;\n#ifdef PREPASS\nuniform vec2 cameraInfo;\n#if defined(LOCAL) && defined(PREPASS_LOCAL_POSITION)\nuniform mat4 inverseEmitterWM;uniform vec3 geometryWorldOffset;\n#endif\n#ifdef PREPASS_POSITION\nvarying vec3 vGeometryPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vGeometryNormalW;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vGeometryNormalV;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vec3 vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vec3 vViewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying float vNormViewDepth;\n#endif\n#endif\n#ifdef ANIMATESHEET\nuniform vec3 particlesInfos; \n#endif\nvarying vec2 vUV;varying vec4 vColor;\n#ifdef POSITIONW_AS_VARYING\nvarying vec3 vPositionW;\n#endif\n#ifdef RAMPGRADIENT\nvarying vec4 remapRanges;\n#endif\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\nuniform mat4 invView;\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#ifdef BILLBOARD\nuniform vec3 eyePosition;\n#endif\nvec3 rotate(vec3 yaxis,vec3 rotatedCorner) {vec3 xaxis=normalize(cross(vec3(0.,1.0,0.),yaxis));vec3 zaxis=normalize(cross(yaxis,xaxis));vec3 row0=vec3(xaxis.x,xaxis.y,xaxis.z);vec3 row1=vec3(yaxis.x,yaxis.y,yaxis.z);vec3 row2=vec3(zaxis.x,zaxis.y,zaxis.z);mat3 rotMatrix= mat3(row0,row1,row2);vec3 alignedCorner=rotMatrix*rotatedCorner;return position+alignedCorner;}\n#ifdef BILLBOARDSTRETCHED\nvec3 rotateAlign(vec3 toCamera,vec3 rotatedCorner) {vec3 normalizedToCamera=normalize(toCamera);vec3 normalizedCrossDirToCamera=normalize(cross(normalize(direction),normalizedToCamera));vec3 row0=vec3(normalizedCrossDirToCamera.x,normalizedCrossDirToCamera.y,normalizedCrossDirToCamera.z);vec3 row2=vec3(normalizedToCamera.x,normalizedToCamera.y,normalizedToCamera.z);\n#ifdef BILLBOARDSTRETCHED_LOCAL\nvec3 row1=normalize(direction);\n#else\nvec3 crossProduct=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));vec3 row1=vec3(crossProduct.x,crossProduct.y,crossProduct.z);\n#endif\nmat3 rotMatrix= mat3(row0,row1,row2);vec3 alignedCorner=rotMatrix*rotatedCorner;return position+alignedCorner;}\nvec3 stretchedNormal(vec3 toCamera,vec3 stretchDirection) {vec3 normalizedToCamera=normalize(toCamera);vec3 normalizedCrossDirToCamera=normalize(cross(normalize(stretchDirection),normalizedToCamera));\n#ifdef BILLBOARDSTRETCHED_LOCAL\nvec3 row1=normalize(stretchDirection);\n#else\nvec3 row1=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\n#endif\nreturn normalize(cross(normalizedCrossDirToCamera,row1));}\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec2 cornerPos;\n#ifndef POSITIONW_AS_VARYING\nvec3 vPositionW;\n#endif\n#ifdef PREPASS\nvec3 geometryNormalW;\n#endif\ncornerPos=(vec2(offset.x-0.5,offset.y -0.5)-translationPivot)*size;\n#ifdef BILLBOARD\nvec3 rotatedCorner;\n#ifdef BILLBOARDY\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.y=0.;rotatedCorner.xz+=translationPivot;vec3 yaxis=position-eyePosition;yaxis.y=0.;vPositionW=rotate(normalize(yaxis),rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=normalize(yaxis);\n#endif\nvec3 viewPos=(view*vec4(vPositionW,1.0)).xyz;\n#elif defined(BILLBOARDSTRETCHED)\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.z=0.;rotatedCorner.xy+=translationPivot;vec3 toCamera=position-eyePosition;vPositionW=rotateAlign(toCamera,rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=stretchedNormal(toCamera,direction);\n#endif\nvec3 viewPos=(view*vec4(vPositionW,1.0)).xyz;\n#else\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.z=0.;rotatedCorner.xy+=translationPivot;vec3 viewPos=(view*vec4(position,1.0)).xyz+rotatedCorner;vPositionW=(invView*vec4(viewPos,1)).xyz;\n#ifdef PREPASS\ngeometryNormalW=normalize((invView*vec4(0.0,0.0,1.0,0.0)).xyz);\n#endif\n#endif\n#ifdef RAMPGRADIENT\nremapRanges=remapData;\n#endif\ngl_Position=projection*vec4(viewPos,1.0);\n#else\nvec3 rotatedCorner;rotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.y=0.;rotatedCorner.xz+=translationPivot;vec3 yaxis=normalize(direction);vPositionW=rotate(yaxis,rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=yaxis;\n#endif\ngl_Position=projection*view*vec4(vPositionW,1.0);\n#endif\nvColor=color;\n#ifdef ANIMATESHEET\nfloat rowOffset=floor(cellIndex*particlesInfos.z);float columnOffset=cellIndex-rowOffset/particlesInfos.z;vec2 uvScale=particlesInfos.xy;vec2 uvOffset=vec2(offset.x ,1.0-offset.y);vUV=(uvOffset+vec2(columnOffset,rowOffset))*uvScale;\n#else\nvUV=offset;\n#endif\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6) || defined(FOG)\nvec4 worldPos=vec4(vPositionW,1.0);\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<logDepthVertex>\n#ifdef PREPASS\nvec4 geometryViewPosition=view*vec4(vPositionW,1.0);\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nvec3 geometryNormalV=normalize((view*vec4(geometryNormalW,0.0)).xyz);vec3 geometryViewDirection=projection[3][3]==0.0 ? geometryViewPosition.xyz : vec3(0.0,0.0,geometryViewPosition.z);if (dot(geometryNormalV,geometryViewDirection)>0.0) {geometryNormalV=-geometryNormalV;geometryNormalW=-geometryNormalW;}\n#endif\n#ifdef PREPASS_POSITION\nvGeometryPositionW=vPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvGeometryNormalW=normalize(geometryNormalW);\n#endif\n#ifdef PREPASS_NORMAL\nvGeometryNormalV=geometryNormalV;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\n#ifdef LOCAL\nvec3 geometryRenderPosition=vPositionW;\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\ngeometryRenderPosition=position+(invView*vec4(rotatedCorner,0.0)).xyz;\n#endif\nvPosition=(inverseEmitterWM*vec4(geometryRenderPosition-geometryWorldOffset,1.0)).xyz;\n#else\nvPosition=vPositionW;\n#endif\n#endif\n#ifdef PREPASS_DEPTH\nvViewPos=geometryViewPosition.xyz;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvNormViewDepth=(geometryViewPosition.z-cameraInfo.x)/(cameraInfo.y-cameraInfo.x);\n#endif\n#endif\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneVertexDeclaration, fogVertexDeclaration, logDepthDeclaration, clipPlaneVertex, fogVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const particlesVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./meshBlendTagFragmentOutput\";\nconst name = \"geometryRenderingFragment\";\nconst shader = `#ifdef PREPASS\n#if SCENE_MRT_COUNT>0\nlet geometryCoverage=select(0.0,1.0,geometryColor.a>0.4);var fragData: array<vec4f,SCENE_MRT_COUNT>;\n#ifdef PREPASS_COLOR\nfragData[PREPASS_COLOR_INDEX]=geometryColor;\n#endif\n#ifdef PREPASS_POSITION\nfragData[PREPASS_POSITION_INDEX]=vec4f(geometryPositionW,geometryCoverage);\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nfragData[PREPASS_LOCAL_POSITION_INDEX]=vec4f(geometryPositionL,geometryCoverage);\n#endif\n#ifdef PREPASS_DEPTH\nfragData[PREPASS_DEPTH_INDEX]=vec4f(geometryViewDepth,0.0,0.0,geometryCoverage);\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfragData[PREPASS_NORMALIZED_VIEW_DEPTH_INDEX]=vec4f(geometryNormalizedViewDepth,0.0,0.0,geometryCoverage);\n#endif\n#ifdef PREPASS_SCREENSPACE_DEPTH\nfragData[PREPASS_SCREENSPACE_DEPTH_INDEX]=vec4f(fragmentInputs.position.z,0.0,0.0,geometryCoverage);\n#endif\n#ifdef PREPASS_NORMAL\nfragData[PREPASS_NORMAL_INDEX]=vec4f(geometryNormalV,geometryCoverage);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nfragData[PREPASS_WORLD_NORMAL_INDEX]=vec4f(geometryNormalW*0.5+0.5,geometryCoverage);\n#endif\n#ifdef PREPASS_ALBEDO\nfragData[PREPASS_ALBEDO_INDEX]=vec4f(geometryAlbedo,geometryCoverage);\n#endif\n#ifdef PREPASS_ALBEDO_SQRT\nfragData[PREPASS_ALBEDO_SQRT_INDEX]=vec4f(sqrt(max(geometryAlbedo,vec3f(0.0))),geometryCoverage);\n#endif\n#ifdef PREPASS_REFLECTIVITY\nfragData[PREPASS_REFLECTIVITY_INDEX]=vec4f(0.0,0.0,0.0,geometryCoverage);\n#endif\n#ifdef PREPASS_IRRADIANCE\nfragData[PREPASS_IRRADIANCE_INDEX]=vec4f(0.0,0.0,0.0,geometryCoverage);\n#endif\n#ifdef PREPASS_IRRADIANCE_LEGACY\nfragData[PREPASS_IRRADIANCE_LEGACY_INDEX]=vec4f(0.0);\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\n#ifdef PREPASS_VELOCITY_ZERO\nlet geometryMotion=vec2f(0.0);\n#else\nlet geometryMotion=0.5*(geometryCurrentPosition.xy/geometryCurrentPosition.w-geometryPreviousPosition.xy/geometryPreviousPosition.w);\n#endif\n#ifdef PREPASS_VELOCITY\nfragData[PREPASS_VELOCITY_INDEX]=vec4f(pow(abs(geometryMotion),vec2f(1.0/3.0))*sign(geometryMotion)*0.5+0.5,0.0,geometryCoverage);\n#endif\n#ifdef PREPASS_VELOCITY_LINEAR\nfragData[PREPASS_VELOCITY_LINEAR_INDEX]=vec4f(-geometryMotion,0.0,geometryCoverage);\n#endif\n#endif\n#ifdef PREPASS_OBJECT_ID\nfragData[PREPASS_OBJECT_ID_INDEX]=encodeObjectId(uniforms.objectId)*geometryCoverage;\n#endif\n#ifdef PREPASS_MESH_BLEND_TAG\nvar meshBlendTagOutput: vec4<u32>=vec4u(0u);if (geometryCoverage>0.0) {meshBlendTagOutput=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);}\n#endif\n#include<meshBlendTagFragmentOutput>[0..8]\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const geometryRenderingFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { geometryRenderingFragmentWGSL } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"particlesPixelShader\";\nconst shader = `varying vUV: vec2f;varying vColor: vec4f;uniform textureMask: vec4f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#ifdef PREPASS\nuniform geometryZeroAlphaDiscard: f32;\n#ifdef PREPASS_POSITION\nvarying vGeometryPositionW: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vGeometryNormalW: vec3f;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vGeometryNormalV: vec3f;\n#endif\n#endif\n#define PREPASS_VELOCITY_ZERO\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<clipPlaneFragmentDeclaration>\n#include<imageProcessingDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#ifdef RAMPGRADIENT\nvarying remapRanges: vec4f;var rampSamplerSampler: sampler;var rampSampler: texture_2d<f32>;\n#endif\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvar textureColor: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,input.vUV);var baseColor: vec4f=(textureColor*uniforms.textureMask+( vec4f(1.,1.,1.,1.)-uniforms.textureMask))*input.vColor;\n#ifdef PREPASS\nlet geometryAlbedo: vec3f=toLinearSpaceVec3(baseColor.rgb);\n#endif\n#ifdef RAMPGRADIENT\nvar alpha: f32=baseColor.a;var remappedColorIndex: f32=clamp((alpha-input.remapRanges.x)/input.remapRanges.y,0.0,1.0);var rampColor: vec4f=textureSample(rampSampler,rampSamplerSampler,vec2f(1.0-remappedColorIndex,0.));baseColor=vec4f(baseColor.rgb*rampColor.rgb,baseColor.a);var finalAlpha: f32=baseColor.a;baseColor.a=clamp((alpha*rampColor.a-input.remapRanges.z)/input.remapRanges.w,0.0,1.0);\n#endif\n#ifdef BLENDMULTIPLYMODE\nvar sourceAlpha: f32=input.vColor.a*textureColor.a;baseColor=vec4f(baseColor.rgb*sourceAlpha+ vec3f(1.0)*(1.0-sourceAlpha),baseColor.a);\n#endif\n#include<logDepthFragment>\n#include<fogFragment>(color,baseColor)\n#ifdef IMAGEPROCESSINGPOSTPROCESS\nbaseColor=vec4f(toLinearSpaceVec3(baseColor.rgb),baseColor.a);\n#else\n#ifdef IMAGEPROCESSING\nbaseColor=vec4f(toLinearSpaceVec3(baseColor.rgb),baseColor.a);baseColor=applyImageProcessing(baseColor);\n#endif\n#endif\n#ifdef PREPASS\nlet geometryColor: vec4f=baseColor;if (geometryColor.a<=0.0 && uniforms.geometryZeroAlphaDiscard>0.0) {discard;}\n#ifdef PREPASS_POSITION\nlet geometryPositionW: vec3f=input.vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nlet geometryPositionL: vec3f=input.vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nlet geometryViewDepth: f32=input.vViewPos.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nlet geometryNormalizedViewDepth: f32=input.vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nlet geometryNormalV: vec3f=normalize(input.vGeometryNormalV);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nlet geometryNormalW: vec3f=normalize(input.vGeometryNormalW);\n#endif\n#include<geometryRenderingFragment>\n#else\nfragmentOutputs.color=baseColor;\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [objectIdFunctionsWGSL, prePassDeclarationWGSL, clipPlaneFragmentDeclarationWGSL, imageProcessingDeclarationWGSL, logDepthDeclarationWGSL, helperFunctionsWGSL, imageProcessingFunctionsWGSL, fogFragmentDeclarationWGSL, clipPlaneFragmentWGSL, logDepthFragmentWGSL, fogFragmentWGSL, meshBlendTagFragmentOutputWGSL, geometryRenderingFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const particlesPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"particlesVertexShader\";\nconst shader = `attribute position: vec3f;attribute color: vec4f;attribute angle: f32;attribute size: vec2f;\n#ifdef ANIMATESHEET\nattribute cellIndex: f32;\n#endif\n#ifndef BILLBOARD\nattribute direction: vec3f;\n#endif\n#ifdef BILLBOARDSTRETCHED\nattribute direction: vec3f;\n#endif\n#ifdef RAMPGRADIENT\nattribute remapData: vec4f;\n#endif\nattribute offset: vec2f;uniform view: mat4x4f;uniform projection: mat4x4f;uniform translationPivot: vec2f;\n#ifdef PREPASS\nuniform cameraInfo: vec2f;\n#if defined(LOCAL) && defined(PREPASS_LOCAL_POSITION)\nuniform inverseEmitterWM: mat4x4f;uniform geometryWorldOffset: vec3f;\n#endif\n#ifdef PREPASS_POSITION\nvarying vGeometryPositionW: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vGeometryNormalW: vec3f;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vGeometryNormalV: vec3f;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vPosition: vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vViewPos: vec3f;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vNormViewDepth: f32;\n#endif\n#endif\n#ifdef ANIMATESHEET\nuniform particlesInfos: vec3f; \n#endif\nvarying vUV: vec2f;varying vColor: vec4f;\n#ifdef POSITIONW_AS_VARYING\nvarying vPositionW: vec3f;\n#endif\n#ifdef RAMPGRADIENT\nvarying remapRanges: vec4f;\n#endif\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\nuniform invView: mat4x4f;\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#ifdef BILLBOARD\nuniform eyePosition: vec3f;\n#endif\nfn rotate(yaxis: vec3f,rotatedCorner: vec3f)->vec3f {var xaxis: vec3f=normalize(cross( vec3f(0.,1.0,0.),yaxis));var zaxis: vec3f=normalize(cross(yaxis,xaxis));var row0: vec3f= vec3f(xaxis.x,xaxis.y,xaxis.z);var row1: vec3f= vec3f(yaxis.x,yaxis.y,yaxis.z);var row2: vec3f= vec3f(zaxis.x,zaxis.y,zaxis.z);var rotMatrix: mat3x3f= mat3x3f(row0,row1,row2);var alignedCorner: vec3f=rotMatrix*rotatedCorner;return vertexInputs.position+alignedCorner;}\n#ifdef BILLBOARDSTRETCHED\nfn rotateAlign(toCamera: vec3f,rotatedCorner: vec3f)->vec3f {var normalizedToCamera: vec3f=normalize(toCamera);var normalizedCrossDirToCamera: vec3f=normalize(cross(normalize(vertexInputs.direction),normalizedToCamera));var row0: vec3f= vec3f(normalizedCrossDirToCamera.x,normalizedCrossDirToCamera.y,normalizedCrossDirToCamera.z);var row2: vec3f= vec3f(normalizedToCamera.x,normalizedToCamera.y,normalizedToCamera.z);\n#ifdef BILLBOARDSTRETCHED_LOCAL\nvar row1: vec3f=normalize(vertexInputs.direction);\n#else\nvar crossProduct: vec3f=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));var row1: vec3f= vec3f(crossProduct.x,crossProduct.y,crossProduct.z);\n#endif\nvar rotMatrix: mat3x3f= mat3x3f(row0,row1,row2);var alignedCorner: vec3f=rotMatrix*rotatedCorner;return vertexInputs.position+alignedCorner;}\nfn stretchedNormal(toCamera: vec3f,stretchDirection: vec3f)->vec3f {let normalizedToCamera: vec3f=normalize(toCamera);let normalizedCrossDirToCamera: vec3f=normalize(cross(normalize(stretchDirection),normalizedToCamera));\n#ifdef BILLBOARDSTRETCHED_LOCAL\nlet row1: vec3f=normalize(stretchDirection);\n#else\nlet row1: vec3f=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\n#endif\nreturn normalize(cross(normalizedCrossDirToCamera,row1));}\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvar cornerPos: vec2f;var vPositionW: vec3f;\n#ifdef PREPASS\nvar geometryNormalW: vec3f;\n#endif\ncornerPos=( vec2f(vertexInputs.offset.x-0.5,vertexInputs.offset.y -0.5)-uniforms.translationPivot)*vertexInputs.size;\n#ifdef BILLBOARD\nvar rotatedCorner: vec3f;\n#ifdef BILLBOARDY\nrotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle)+uniforms.translationPivot.x;rotatedCorner.z=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle)+uniforms.translationPivot.y;rotatedCorner.y=0.;var yaxis: vec3f=vertexInputs.position-uniforms.eyePosition;yaxis.y=0.;vPositionW=rotate(normalize(yaxis),rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=normalize(yaxis);\n#endif\nvar viewPos: vec3f=(uniforms.view* vec4f(vPositionW,1.0)).xyz;\n#elif defined(BILLBOARDSTRETCHED)\nrotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle)+uniforms.translationPivot.x;rotatedCorner.y=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle)+uniforms.translationPivot.y;rotatedCorner.z=0.;var toCamera: vec3f=vertexInputs.position-uniforms.eyePosition;vPositionW=rotateAlign(toCamera,rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=stretchedNormal(toCamera,vertexInputs.direction);\n#endif\nvar viewPos: vec3f=(uniforms.view* vec4f(vPositionW,1.0)).xyz;\n#else\nrotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle)+uniforms.translationPivot.x;rotatedCorner.y=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle)+uniforms.translationPivot.y;rotatedCorner.z=0.;var viewPos: vec3f=(uniforms.view* vec4f(vertexInputs.position,1.0)).xyz+rotatedCorner;vPositionW=(uniforms.invView* vec4f(viewPos,1)).xyz;\n#ifdef PREPASS\ngeometryNormalW=normalize((uniforms.invView*vec4f(0.0,0.0,1.0,0.0)).xyz);\n#endif\n#endif\n#ifdef RAMPGRADIENT\nvertexOutputs.remapRanges=vertexInputs.remapData;\n#endif\nvertexOutputs.position=uniforms.projection* vec4f(viewPos,1.0);\n#else\nvar rotatedCorner: vec3f;rotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle)+uniforms.translationPivot.x;rotatedCorner.z=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle)+uniforms.translationPivot.y;rotatedCorner.y=0.;var yaxis: vec3f=normalize(vertexInputs.direction);vPositionW=rotate(yaxis,rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=yaxis;\n#endif\nvertexOutputs.position=uniforms.projection*uniforms.view* vec4f(vPositionW,1.0);\n#endif\nvertexOutputs.vColor=vertexInputs.color;\n#ifdef ANIMATESHEET\nvar rowOffset: f32=floor(vertexInputs.cellIndex*uniforms.particlesInfos.z);var columnOffset: f32=vertexInputs.cellIndex-rowOffset/uniforms.particlesInfos.z;var uvScale: vec2f=uniforms.particlesInfos.xy;var uvOffset: vec2f= vec2f(vertexInputs.offset.x ,1.0-vertexInputs.offset.y);vertexOutputs.vUV=(uvOffset+ vec2f(columnOffset,rowOffset))*uvScale;\n#else\nvertexOutputs.vUV=vertexInputs.offset;\n#endif\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6) || defined(FOG)\nvar worldPos: vec4f= vec4f(vPositionW,1.0);\n#endif\n#ifdef POSITIONW_AS_VARYING\nvertexOutputs.vPositionW=vPositionW;\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<logDepthVertex>\n#ifdef PREPASS\nlet geometryViewPosition: vec4f=uniforms.view*vec4f(vPositionW,1.0);\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nvar geometryNormalV=normalize((uniforms.view*vec4f(geometryNormalW,0.0)).xyz);let geometryViewDirection=select(vec3f(0.0,0.0,geometryViewPosition.z),geometryViewPosition.xyz,uniforms.projection[3][3]==0.0);if (dot(geometryNormalV,geometryViewDirection)>0.0) {geometryNormalV=-geometryNormalV;geometryNormalW=-geometryNormalW;}\n#endif\n#ifdef PREPASS_POSITION\nvertexOutputs.vGeometryPositionW=vPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvertexOutputs.vGeometryNormalW=normalize(geometryNormalW);\n#endif\n#ifdef PREPASS_NORMAL\nvertexOutputs.vGeometryNormalV=geometryNormalV;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\n#ifdef LOCAL\nvar geometryRenderPosition=vPositionW;\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\ngeometryRenderPosition=vertexInputs.position+(uniforms.invView*vec4f(rotatedCorner,0.0)).xyz;\n#endif\nvertexOutputs.vPosition=(uniforms.inverseEmitterWM*vec4f(geometryRenderPosition-uniforms.geometryWorldOffset,1.0)).xyz;\n#else\nvertexOutputs.vPosition=vPositionW;\n#endif\n#endif\n#ifdef PREPASS_DEPTH\nvertexOutputs.vViewPos=geometryViewPosition.xyz;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvertexOutputs.vNormViewDepth=(geometryViewPosition.z-uniforms.cameraInfo.x)/(uniforms.cameraInfo.y-uniforms.cameraInfo.x);\n#endif\n#endif\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, logDepthDeclarationWGSL, clipPlaneVertexWGSL, fogVertexWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const particlesVertexShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type PhysicsImpostor } from \"./physicsImpostor.pure\";\r\nimport { PhysicsJoint } from \"./physicsJoint\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for physicsV1PhysicsEngineComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPhysicsV1PhysicsEngineComponent(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"physicsImpostor\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._physicsImpostor;\r\n        },\r\n        set: function (this: AbstractMesh, value: Nullable<PhysicsImpostor>) {\r\n            if (this._physicsImpostor === value) {\r\n                return;\r\n            }\r\n            if (this._disposePhysicsObserver) {\r\n                this.onDisposeObservable.remove(this._disposePhysicsObserver);\r\n            }\r\n\r\n            this._physicsImpostor = value;\r\n\r\n            if (value) {\r\n                this._disposePhysicsObserver = this.onDisposeObservable.add(() => {\r\n                    // Physics\r\n                    if (this.physicsImpostor) {\r\n                        this.physicsImpostor.dispose(/*!doNotRecurse*/);\r\n                        this.physicsImpostor = null;\r\n                    }\r\n                });\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    /**\r\n     * Gets the current physics impostor\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/physics\r\n     * @returns a physics impostor or null\r\n     */\r\n    AbstractMesh.prototype.getPhysicsImpostor = function (): Nullable<PhysicsImpostor> {\r\n        return this.physicsImpostor;\r\n    };\r\n\r\n    /**\r\n     * Apply a physic impulse to the mesh\r\n     * @param force defines the force to apply\r\n     * @param contactPoint defines where to apply the force\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n     */\r\n    AbstractMesh.prototype.applyImpulse = function (force: Vector3, contactPoint: Vector3): AbstractMesh {\r\n        if (!this.physicsImpostor) {\r\n            return this;\r\n        }\r\n        this.physicsImpostor.applyImpulse(force, contactPoint);\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Creates a physic joint between two meshes\r\n     * @param otherMesh defines the other mesh to use\r\n     * @param pivot1 defines the pivot to use on this mesh\r\n     * @param pivot2 defines the pivot to use on the other mesh\r\n     * @param options defines additional options (can be plugin dependent)\r\n     * @returns the current mesh\r\n     * @see https://www.babylonjs-playground.com/#0BS5U0#0\r\n     */\r\n    AbstractMesh.prototype.setPhysicsLinkWith = function (otherMesh: Mesh, pivot1: Vector3, pivot2: Vector3, options?: any): AbstractMesh {\r\n        if (!this.physicsImpostor || !otherMesh.physicsImpostor) {\r\n            return this;\r\n        }\r\n        this.physicsImpostor.createJoint(otherMesh.physicsImpostor, PhysicsJoint.HingeJoint, {\r\n            mainPivot: pivot1,\r\n            connectedPivot: pivot2,\r\n            nativeParams: options,\r\n        });\r\n        return this;\r\n    };\r\n}\r\n","import { type Scene } from \"../../scene\";\r\nimport { type Vector3 } from \"../../Maths/math.vector\";\r\nimport { type Nullable } from \"../../types\";\r\nimport {\r\n    type IPhysicsEnginePluginV2,\r\n    type PhysicsConstraintParameters,\r\n    type PhysicsConstraintAxisLimitMode,\r\n    type PhysicsConstraintMotorType,\r\n    type ConstrainedBodyPair,\r\n    PhysicsConstraintAxis,\r\n    PhysicsConstraintType,\r\n} from \"./IPhysicsEnginePlugin\";\r\n\r\n/**\r\n * This is a holder class for the physics constraint created by the physics plugin\r\n * It holds a set of functions to control the underlying constraint\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n */\r\nexport class PhysicsConstraint {\r\n    /**\r\n     * V2 Physics plugin private data for a physics material\r\n     */\r\n    public _pluginData: any = undefined;\r\n    /**\r\n     * The V2 plugin used to create and manage this Physics Body\r\n     */\r\n    protected _physicsPlugin: IPhysicsEnginePluginV2;\r\n    protected _options: PhysicsConstraintParameters;\r\n    protected _type: PhysicsConstraintType;\r\n    /**\r\n     * @internal\r\n     * The internal options that were used to init the constraint\r\n     */\r\n    public _initOptions?: PhysicsConstraintParameters;\r\n\r\n    /**\r\n     * Constructs a new constraint for the physics constraint.\r\n     * @param type The type of constraint to create.\r\n     * @param options The options for the constraint.\r\n     * @param scene The scene the constraint belongs to.\r\n     *\r\n     * This code is useful for creating a new constraint for the physics engine. It checks if the scene has a physics engine, and if the plugin version is correct.\r\n     * If all checks pass, it initializes the constraint with the given type and options.\r\n     */\r\n    constructor(type: PhysicsConstraintType, options: PhysicsConstraintParameters, scene: Scene) {\r\n        if (!scene) {\r\n            throw new Error(\"Missing scene parameter for constraint constructor.\");\r\n        }\r\n        const physicsEngine = scene.getPhysicsEngine();\r\n        if (!physicsEngine) {\r\n            throw new Error(\"No Physics Engine available.\");\r\n        }\r\n        if (physicsEngine.getPluginVersion() != 2) {\r\n            throw new Error(\"Plugin version is incorrect. Expected version 2.\");\r\n        }\r\n        const physicsPlugin = physicsEngine.getPhysicsPlugin();\r\n        if (!physicsPlugin) {\r\n            throw new Error(\"No Physics Plugin available.\");\r\n        }\r\n\r\n        this._physicsPlugin = physicsPlugin as IPhysicsEnginePluginV2;\r\n        this._options = options;\r\n        this._type = type;\r\n    }\r\n\r\n    /**\r\n     * Gets the type of the constraint.\r\n     *\r\n     * @returns The type of the constraint.\r\n     *\r\n     */\r\n    public get type(): PhysicsConstraintType {\r\n        return this._type;\r\n    }\r\n\r\n    /**\r\n     * Retrieves the options of the physics constraint.\r\n     *\r\n     * @returns The physics constraint parameters.\r\n     *\r\n     */\r\n    public get options(): PhysicsConstraintParameters {\r\n        return this._options;\r\n    }\r\n\r\n    /**\r\n     * Enable/disable the constraint\r\n     * @param isEnabled value for the constraint\r\n     */\r\n    public set isEnabled(isEnabled: boolean) {\r\n        this._physicsPlugin.setEnabled(this, isEnabled);\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @returns true if constraint is enabled\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._physicsPlugin.getEnabled(this);\r\n    }\r\n\r\n    /**\r\n     * Enables or disables collisions for the physics engine.\r\n     *\r\n     * @param isEnabled - A boolean value indicating whether collisions should be enabled or disabled.\r\n     *\r\n     */\r\n    public set isCollisionsEnabled(isEnabled: boolean) {\r\n        this._physicsPlugin.setCollisionsEnabled(this, isEnabled);\r\n    }\r\n\r\n    /**\r\n     * Gets whether collisions are enabled for this physics object.\r\n     *\r\n     * @returns `true` if collisions are enabled, `false` otherwise.\r\n     *\r\n     */\r\n    public get isCollisionsEnabled(): boolean {\r\n        return this._physicsPlugin.getCollisionsEnabled(this);\r\n    }\r\n\r\n    /**\r\n     * Gets all bodies that are using this constraint\r\n     * @returns\r\n     */\r\n    public getBodiesUsingConstraint(): ConstrainedBodyPair[] {\r\n        return this._physicsPlugin.getBodiesUsingConstraint(this);\r\n    }\r\n\r\n    /**\r\n     * Disposes the constraint from the physics engine.\r\n     *\r\n     * This method is useful for cleaning up the physics engine when a body is no longer needed. Disposing the body will free up resources and prevent memory leaks.\r\n     */\r\n    public dispose(): void {\r\n        this._physicsPlugin.disposeConstraint(this);\r\n    }\r\n}\r\n\r\n/**\r\n * This describes a single limit used by Physics6DoFConstraint\r\n */\r\nexport class Physics6DoFLimit {\r\n    /**\r\n     * The axis ID to limit\r\n     */\r\n    axis: PhysicsConstraintAxis;\r\n    /**\r\n     * An optional minimum limit for the axis.\r\n     * Corresponds to a distance in meters for linear axes, an angle in radians for angular axes.\r\n     */\r\n    minLimit?: number;\r\n    /**\r\n     * An optional maximum limit for the axis.\r\n     * Corresponds to a distance in meters for linear axes, an angle in radians for angular axes.\r\n     */\r\n    maxLimit?: number;\r\n    /**\r\n     * The stiffness of the constraint.\r\n     */\r\n    stiffness?: number;\r\n    /**\r\n     * A constraint parameter that specifies damping.\r\n     */\r\n    damping?: number;\r\n}\r\n\r\n/**\r\n * A generic constraint, which can be used to build more complex constraints than those specified\r\n * in PhysicsConstraintType. The axis and pivot options in PhysicsConstraintParameters define the space\r\n * the constraint operates in. This constraint contains a set of limits, which restrict the\r\n * relative movement of the bodies in that coordinate system\r\n */\r\nexport class Physics6DoFConstraint extends PhysicsConstraint {\r\n    /**\r\n     * The collection of limits which this constraint will apply\r\n     */\r\n    public limits: Physics6DoFLimit[];\r\n\r\n    constructor(constraintParams: PhysicsConstraintParameters, limits: Physics6DoFLimit[], scene: Scene) {\r\n        super(PhysicsConstraintType.SIX_DOF, constraintParams, scene);\r\n        this.limits = limits;\r\n    }\r\n\r\n    /**\r\n     * Sets the friction of the given axis of the physics engine.\r\n     * @param axis - The axis of the physics engine to set the friction for.\r\n     * @param friction - The friction to set for the given axis.\r\n     *\r\n     */\r\n    public setAxisFriction(axis: PhysicsConstraintAxis, friction: number): void {\r\n        this._physicsPlugin.setAxisFriction(this, axis, friction);\r\n    }\r\n\r\n    /**\r\n     * Gets the friction of the given axis of the physics engine.\r\n     * @param axis - The axis of the physics engine.\r\n     * @returns The friction of the given axis, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisFriction(axis: PhysicsConstraintAxis): Nullable<number> {\r\n        return this._physicsPlugin.getAxisFriction(this, axis);\r\n    }\r\n\r\n    /**\r\n     * Sets the limit mode for the given axis of the constraint.\r\n     * @param axis The axis to set the limit mode for.\r\n     * @param limitMode The limit mode to set.\r\n     *\r\n     * This method is useful for setting the limit mode for a given axis of the constraint. This is important for\r\n     * controlling the behavior of the physics engine when the constraint is reached. By setting the limit mode,\r\n     * the engine can be configured to either stop the motion of the objects, or to allow them to continue\r\n     * moving beyond the constraint.\r\n     */\r\n    public setAxisMode(axis: PhysicsConstraintAxis, limitMode: PhysicsConstraintAxisLimitMode): void {\r\n        this._physicsPlugin.setAxisMode(this, axis, limitMode);\r\n    }\r\n\r\n    /**\r\n     * Gets the limit mode of the given axis of the constraint.\r\n     *\r\n     * @param axis - The axis of the constraint.\r\n     * @returns The limit mode of the given axis, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisMode(axis: PhysicsConstraintAxis): Nullable<PhysicsConstraintAxisLimitMode> {\r\n        return this._physicsPlugin.getAxisMode(this, axis);\r\n    }\r\n\r\n    /**\r\n     * Sets the minimum limit of a given axis of a constraint.\r\n     * @param axis - The axis of the constraint.\r\n     * @param minLimit - The minimum limit of the axis.\r\n     *\r\n     */\r\n    public setAxisMinLimit(axis: PhysicsConstraintAxis, minLimit: number): void {\r\n        this._physicsPlugin.setAxisMinLimit(this, axis, minLimit);\r\n    }\r\n\r\n    /**\r\n     * Gets the minimum limit of the given axis of the physics engine.\r\n     * @param axis - The axis of the physics engine.\r\n     * @returns The minimum limit of the given axis, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisMinLimit(axis: PhysicsConstraintAxis): Nullable<number> {\r\n        return this._physicsPlugin.getAxisMinLimit(this, axis);\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum limit of the given axis for the physics engine.\r\n     * @param axis - The axis to set the limit for.\r\n     * @param limit - The maximum limit of the axis.\r\n     *\r\n     * This method is useful for setting the maximum limit of the given axis for the physics engine,\r\n     * which can be used to control the movement of the physics object. This helps to ensure that the\r\n     * physics object does not move beyond the given limit.\r\n     */\r\n    public setAxisMaxLimit(axis: PhysicsConstraintAxis, limit: number): void {\r\n        this._physicsPlugin.setAxisMaxLimit(this, axis, limit);\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum limit of the given axis of the physics engine.\r\n     * @param axis - The axis of the physics engine.\r\n     * @returns The maximum limit of the given axis, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisMaxLimit(axis: PhysicsConstraintAxis): Nullable<number> {\r\n        return this._physicsPlugin.getAxisMaxLimit(this, axis);\r\n    }\r\n\r\n    /**\r\n     * Sets the motor type of the given axis of the constraint.\r\n     * @param axis - The axis of the constraint.\r\n     * @param motorType - The type of motor to use.\r\n     */\r\n    public setAxisMotorType(axis: PhysicsConstraintAxis, motorType: PhysicsConstraintMotorType): void {\r\n        this._physicsPlugin.setAxisMotorType(this, axis, motorType);\r\n    }\r\n\r\n    /**\r\n     * Gets the motor type of the specified axis of the constraint.\r\n     *\r\n     * @param axis - The axis of the constraint.\r\n     * @returns The motor type of the specified axis, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisMotorType(axis: PhysicsConstraintAxis): Nullable<PhysicsConstraintMotorType> {\r\n        return this._physicsPlugin.getAxisMotorType(this, axis);\r\n    }\r\n\r\n    /**\r\n     * Sets the target velocity of the motor associated with the given axis of the constraint.\r\n     * @param axis - The axis of the constraint.\r\n     * @param target - The target velocity of the motor.\r\n     *\r\n     * This method is useful for setting the target velocity of the motor associated with the given axis of the constraint.\r\n     */\r\n    public setAxisMotorTarget(axis: PhysicsConstraintAxis, target: number): void {\r\n        this._physicsPlugin.setAxisMotorTarget(this, axis, target);\r\n    }\r\n\r\n    /**\r\n     * Gets the target velocity of the motor associated to the given constraint axis.\r\n     * @param axis - The constraint axis associated to the motor.\r\n     * @returns The target velocity of the motor, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisMotorTarget(axis: PhysicsConstraintAxis): Nullable<number> {\r\n        return this._physicsPlugin.getAxisMotorTarget(this, axis);\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum force of the motor of the given axis of the constraint.\r\n     * @param axis - The axis of the constraint.\r\n     * @param maxForce - The maximum force of the motor.\r\n     *\r\n     */\r\n    public setAxisMotorMaxForce(axis: PhysicsConstraintAxis, maxForce: number): void {\r\n        this._physicsPlugin.setAxisMotorMaxForce(this, axis, maxForce);\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum force of the motor of the given axis of the constraint.\r\n     * @param axis - The axis of the constraint.\r\n     * @returns The maximum force of the motor, or null if the constraint hasn't been initialized yet.\r\n     *\r\n     */\r\n    public getAxisMotorMaxForce(axis: PhysicsConstraintAxis): Nullable<number> {\r\n        return this._physicsPlugin.getAxisMotorMaxForce(this, axis);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a Ball and Socket Constraint, used to simulate a joint\r\n * This class is useful for simulating a joint between two bodies in a physics engine.\r\n * It allows for the two bodies to move relative to each other in a way that mimics a ball and socket joint, such as a shoulder or hip joint.\r\n * @param pivotA - The first pivot, defined locally in the first body frame\r\n * @param pivotB - The second pivot, defined locally in the second body frame\r\n * @param axisA - The axis of the first body\r\n * @param axisB - The axis of the second body\r\n * @param scene - The scene the constraint is applied to\r\n * @returns The Ball and Socket Constraint\r\n */\r\nexport class BallAndSocketConstraint extends PhysicsConstraint {\r\n    constructor(pivotA: Vector3, pivotB: Vector3, axisA: Vector3, axisB: Vector3, scene: Scene) {\r\n        super(PhysicsConstraintType.BALL_AND_SOCKET, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a distance constraint.\r\n *\r\n * This code is useful for creating a distance constraint in a physics engine.\r\n * A distance constraint is a type of constraint that keeps two objects at a certain distance from each other.\r\n * The scene is used to add the constraint to the physics engine.\r\n * @param maxDistance distance between bodies\r\n * @param scene The scene the constraint belongs to\r\n * @returns DistanceConstraint\r\n */\r\nexport class DistanceConstraint extends PhysicsConstraint {\r\n    constructor(maxDistance: number, scene: Scene) {\r\n        super(PhysicsConstraintType.DISTANCE, { maxDistance: maxDistance }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a HingeConstraint, which is a type of PhysicsConstraint.\r\n *\r\n * This code is useful for creating a HingeConstraint, which is a type of PhysicsConstraint.\r\n * This constraint is used to simulate a hinge joint between two rigid bodies, allowing them to rotate around a single axis.\r\n * @param pivotA - The first pivot point, in world space.\r\n * @param pivotB - The second pivot point, in world space.\r\n * @param scene - The scene the constraint is used in.\r\n * @returns The new HingeConstraint.\r\n */\r\nexport class HingeConstraint extends PhysicsConstraint {\r\n    constructor(pivotA: Vector3, pivotB: Vector3, axisA: Vector3, axisB: Vector3, scene: Scene) {\r\n        super(PhysicsConstraintType.HINGE, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a SliderConstraint, which is a type of PhysicsConstraint.\r\n *\r\n * This code is useful for creating a SliderConstraint, which is a type of PhysicsConstraint.\r\n * It allows the user to specify the two pivots and two axes of the constraint in world space, as well as the scene the constraint belongs to.\r\n * This is useful for creating a constraint between two rigid bodies that allows them to move along a certain axis.\r\n * @param pivotA - The first pivot of the constraint, in world space.\r\n * @param pivotB - The second pivot of the constraint, in world space.\r\n * @param axisA - The first axis of the constraint, in world space.\r\n * @param axisB - The second axis of the constraint, in world space.\r\n * @param scene - The scene the constraint belongs to.\r\n * @returns The created SliderConstraint.\r\n */\r\nexport class SliderConstraint extends PhysicsConstraint {\r\n    constructor(pivotA: Vector3, pivotB: Vector3, axisA: Vector3, axisB: Vector3, scene: Scene) {\r\n        super(PhysicsConstraintType.SLIDER, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a LockConstraint, which is a type of PhysicsConstraint.\r\n *\r\n * This code is useful for creating a LockConstraint, which is a type of PhysicsConstraint.\r\n * It takes in two pivots and two axes in local space, as well as the scene the constraint belongs to, and creates a LockConstraint.\r\n * @param pivotA - The first pivot of the constraint in local space.\r\n * @param pivotB - The second pivot of the constraint in local space.\r\n * @param axisA - The first axis of the constraint in local space.\r\n * @param axisB - The second axis of the constraint in local space.\r\n * @param scene - The scene the constraint belongs to.\r\n * @returns The created LockConstraint.\r\n */\r\nexport class LockConstraint extends PhysicsConstraint {\r\n    constructor(pivotA: Vector3, pivotB: Vector3, axisA: Vector3, axisB: Vector3, scene: Scene) {\r\n        super(PhysicsConstraintType.LOCK, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a PrismaticConstraint, which is a type of PhysicsConstraint.\r\n *\r\n * This code is useful for creating a PrismaticConstraint, which is a type of PhysicsConstraint.\r\n * It takes in two pivots and two axes in local space, as well as the scene the constraint belongs to, and creates a PrismaticConstraint.\r\n * @param pivotA - The first pivot of the constraint in local space.\r\n * @param pivotB - The second pivot of the constraint in local space.\r\n * @param axisA - The first axis of the constraint in local space.\r\n * @param axisB - The second axis of the constraint in local space.\r\n * @param scene - The scene the constraint belongs to.\r\n * @returns The created PrismaticConstraint.\r\n */\r\nexport class PrismaticConstraint extends PhysicsConstraint {\r\n    constructor(pivotA: Vector3, pivotB: Vector3, axisA: Vector3, axisB: Vector3, scene: Scene) {\r\n        super(PhysicsConstraintType.PRISMATIC, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);\r\n    }\r\n}\r\n\r\n/**\r\n * Creates a SpringConstraint, which is a type of Physics6DoFConstraint. This constraint applies a force at the ends which is proportional\r\n * to the distance between ends, and a stiffness and damping factor. The force is calculated as (stiffness * positionError) - (damping * velocity)\r\n *\r\n * @param pivotA - The first pivot of the constraint in local space.\r\n * @param pivotB - The second pivot of the constraint in local space.\r\n * @param axisA - The first axis of the constraint in local space.\r\n * @param axisB - The second axis of the constraint in local space.\r\n * @param minDistance - The minimum distance between the two pivots.\r\n * @param maxDistance - The maximum distance between the two pivots.\r\n * @param stiffness - The stiffness of the spring.\r\n * @param damping - The damping of the spring.\r\n * @param scene - The scene the constraint belongs to.\r\n * @returns The created SpringConstraint.\r\n */\r\nexport class SpringConstraint extends Physics6DoFConstraint {\r\n    constructor(pivotA: Vector3, pivotB: Vector3, axisA: Vector3, axisB: Vector3, minDistance: number, maxDistance: number, stiffness: number, damping: number, scene: Scene) {\r\n        super({ pivotA, pivotB, axisA, axisB }, [{ axis: PhysicsConstraintAxis.LINEAR_DISTANCE, minLimit: minDistance, maxLimit: maxDistance, stiffness, damping }], scene);\r\n    }\r\n}\r\n","/**\r\n * Determines how values from the PhysicsMaterial are combined when\r\n * two objects are in contact. When each PhysicsMaterial specifies\r\n * a different combine mode for some property, the combine mode which\r\n * is used will be selected based on their order in this enum - i.e.\r\n * a value later in this list will be preferentially used.\r\n */\r\nexport const enum PhysicsMaterialCombineMode {\r\n    /**\r\n     * The final value will be the geometric mean of the two values:\r\n     * sqrt( valueA *  valueB )\r\n     */\r\n    GEOMETRIC_MEAN,\r\n    /**\r\n     * The final value will be the smaller of the two:\r\n     * min( valueA , valueB )\r\n     */\r\n    MINIMUM,\r\n    /** The final value will be the larger of the two:\r\n     * max( valueA , valueB )\r\n     */\r\n    MAXIMUM,\r\n    /** The final value will be the arithmetic mean of the two values:\r\n     * (valueA + valueB) / 2\r\n     */\r\n    ARITHMETIC_MEAN,\r\n    /**\r\n     * The final value will be the product of the two values:\r\n     * valueA * valueB\r\n     */\r\n    MULTIPLY,\r\n}\r\n\r\n/**\r\n * Physics material class\r\n * Helps setting friction and restitution that are used to compute responding forces in collision response\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsMaterial {\r\n    /**\r\n     * Sets the friction used by this material\r\n     *\r\n     * The friction determines how much an object will slow down when it is in contact with another object.\r\n     * This is important for simulating realistic physics, such as when an object slides across a surface.\r\n     *\r\n     * If not provided, a default value of 0.5 will be used.\r\n     */\r\n    friction?: number;\r\n\r\n    /**\r\n     * Sets the static friction used by this material.\r\n     *\r\n     * Static friction is the friction that must be overcome before a pair of objects can start sliding\r\n     * relative to each other; for physically-realistic behaviour, it should be at least as high as the\r\n     * normal friction value. If not provided, the friction value will be used\r\n     */\r\n    staticFriction?: number;\r\n\r\n    /**\r\n     * Sets the restitution of the physics material.\r\n     *\r\n     * The restitution is a factor which describes, the amount of energy that is retained after a collision,\r\n     * which should be a number between 0 and 1..\r\n     *\r\n     * A restitution of 0 means that no energy is retained and the objects will not bounce off each other,\r\n     * while a restitution of 1 means that all energy is retained and the objects will bounce.\r\n     *\r\n     * Note, though, due that due to the simulation implementation, an object with a restitution of 1 may\r\n     * still lose energy over time.\r\n     *\r\n     * If not provided, a default value of 0 will be used.\r\n     */\r\n    restitution?: number;\r\n\r\n    /**\r\n     * Describes how two different friction values should be combined. See PhysicsMaterialCombineMode for\r\n     * more details.\r\n     *\r\n     * If not provided, will use PhysicsMaterialCombineMode.MINIMUM\r\n     */\r\n    frictionCombine?: PhysicsMaterialCombineMode;\r\n\r\n    /**\r\n     * Describes how two different restitution values should be combined. See PhysicsMaterialCombineMode for\r\n     * more details.\r\n     *\r\n     * If not provided, will use PhysicsMaterialCombineMode.MAXIMUM\r\n     */\r\n    restitutionCombine?: PhysicsMaterialCombineMode;\r\n}\r\n","import { Vector3, Quaternion, Matrix, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type DeepImmutableObject } from \"../../types\";\r\nimport { PhysicsBody } from \"./physicsBody\";\r\nimport { PhysicsShapeCapsule, type PhysicsShape } from \"./physicsShape\";\r\nimport { PhysicsMotionType } from \"./IPhysicsEnginePlugin\";\r\nimport { type HavokPlugin } from \"./Plugins/havokPlugin\";\r\nimport { BuildArray } from \"../../Misc/arrayTools\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Observable } from \"../../Misc/observable\";\r\n\r\n/**\r\n * Shape properties for the character controller\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface CharacterShapeOptions {\r\n    /**\r\n     * optional shape used for collision detection\r\n     */\r\n    shape?: PhysicsShape;\r\n    /**\r\n     * capsule height for the capsule shape if no shape is provided\r\n     */\r\n    capsuleHeight?: number;\r\n    /**\r\n     * capsule radius for the capsule shape if no shape is provided\r\n     */\r\n    capsuleRadius?: number;\r\n}\r\n\r\n/**\r\n * Collision event data for the character controller\r\n */\r\nexport interface ICharacterControllerCollisionEvent {\r\n    /**\r\n     * The collider physics body\r\n     */\r\n    collider: PhysicsBody;\r\n    /**\r\n     * Index of the collider in instances\r\n     */\r\n    colliderIndex: number;\r\n    /**\r\n     * Separation force applied to the collider\r\n     */\r\n    impulse: Vector3;\r\n    /**\r\n     * Position where the impulse is applied\r\n     */\r\n    impulsePosition: Vector3;\r\n}\r\n\r\n/**\r\n * State of the character on the surface\r\n */\r\nexport const enum CharacterSupportedState {\r\n    UNSUPPORTED,\r\n    SLIDING,\r\n    SUPPORTED,\r\n}\r\n\r\n/**\r\n * Surface information computed by checkSupport method\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface CharacterSurfaceInfo {\r\n    /**\r\n     * Indicates whether the surface is dynamic.\r\n     * A dynamic surface is one that can change its properties over time,\r\n     * such as moving platforms or surfaces that can be affected by external forces.\r\n     * surfaceInfo.supportedState is always CharacterSupportedState.SUPPORTED when isSurfaceDynamic is true.\r\n     */\r\n    isSurfaceDynamic: boolean;\r\n    /**\r\n     * The supported state of the character on the surface.\r\n     */\r\n    supportedState: CharacterSupportedState;\r\n    /**\r\n     * The average normal vector of the surface.\r\n     * This vector is perpendicular to the surface and points outwards.\r\n     */\r\n    averageSurfaceNormal: Vector3;\r\n    /**\r\n     * The average velocity of the surface.\r\n     * This vector represents the speed and direction in which the surface is moving.\r\n     */\r\n    averageSurfaceVelocity: Vector3;\r\n    /**\r\n     * The average angular velocity of the surface.\r\n     */\r\n    averageAngularSurfaceVelocity: Vector3;\r\n}\r\n\r\ninterface IContact {\r\n    /** @internal */\r\n    position: Vector3;\r\n    /** @internal */\r\n    normal: Vector3;\r\n    /** @internal */\r\n    distance: number;\r\n    /** @internal */\r\n    fraction: number;\r\n    /** @internal */\r\n    bodyB: { body: PhysicsBody; index: number };\r\n    /** @internal */\r\n    allowedPenetration: number;\r\n}\r\n\r\ninterface ISurfaceConstraintInfo {\r\n    /** @internal */\r\n    planeNormal: Vector3;\r\n    /** @internal */\r\n    planeDistance: number;\r\n    /** @internal */\r\n    velocity: Vector3;\r\n    /** @internal */\r\n    angularVelocity: Vector3;\r\n    /** @internal */\r\n    staticFriction: number;\r\n    /** @internal */\r\n    extraUpStaticFriction: number;\r\n    /** @internal */\r\n    extraDownStaticFriction: number;\r\n    /** @internal */\r\n    dynamicFriction: number;\r\n    /** @internal */\r\n    priority: number;\r\n}\r\n\r\nconst enum SurfaceConstraintInteractionStatus {\r\n    OK,\r\n    FAILURE_3D,\r\n    FAILURE_2D,\r\n}\r\ninterface ISurfaceConstraintInteraction {\r\n    /** @internal */\r\n    touched: boolean;\r\n    /** @internal */\r\n    stopped: boolean;\r\n    /** @internal */\r\n    surfaceTime: number;\r\n    /** @internal */\r\n    penaltyDistance: number;\r\n    /** @internal */\r\n    status: SurfaceConstraintInteractionStatus;\r\n}\r\n\r\n/** @internal */\r\nclass SimplexSolverOutput {\r\n    /** @internal */\r\n    public position: Vector3;\r\n    /** @internal */\r\n    public velocity: Vector3;\r\n    /** @internal */\r\n    public deltaTime: number;\r\n    /** @internal */\r\n    public planeInteractions: ISurfaceConstraintInteraction[];\r\n}\r\n\r\n/** @internal */\r\nclass SimplexSolverActivePlanes {\r\n    /** @internal */\r\n    public index: number;\r\n    /** @internal */\r\n    public constraint: ISurfaceConstraintInfo;\r\n    /** @internal */\r\n    public interaction: ISurfaceConstraintInteraction;\r\n\r\n    /** @internal */\r\n    public copyFrom(other: SimplexSolverActivePlanes) {\r\n        this.index = other.index;\r\n        this.constraint = other.constraint;\r\n        this.interaction = other.interaction;\r\n    }\r\n}\r\n\r\n/** @internal */\r\nclass SimplexSolverInfo {\r\n    /** @internal */\r\n    public supportPlanes: Array<SimplexSolverActivePlanes> = new Array<SimplexSolverActivePlanes>(4);\r\n    /** @internal */\r\n    public numSupportPlanes: number = 0;\r\n    /** @internal */\r\n    public currentTime: number = 0;\r\n    /** @internal */\r\n    public inputConstraints: ISurfaceConstraintInfo[];\r\n    /** @internal */\r\n    public outputInteractions: ISurfaceConstraintInteraction[];\r\n    /** @internal */\r\n    public getOutput(constraint: ISurfaceConstraintInfo): ISurfaceConstraintInteraction {\r\n        return this.outputInteractions[this.inputConstraints.indexOf(constraint)]; //<todo.eoin This is O(1) in C++! Equivalent in TS?\r\n    }\r\n}\r\n\r\n/** @internal */\r\nfunction ContactFromCast(hp: HavokPlugin, cp: any /*ContactPoint*/, castPath: Vector3, hitFraction: number, keepDistance: number): IContact {\r\n    const bodyMap = (hp as any)._bodies;\r\n\r\n    const normal = Vector3.FromArray(cp[4]);\r\n    const dist = -hitFraction * castPath.dot(normal);\r\n    return {\r\n        position: Vector3.FromArray(cp[3]),\r\n        normal: normal,\r\n        distance: dist,\r\n        fraction: hitFraction,\r\n        bodyB: bodyMap.get(cp[0][0])!,\r\n        allowedPenetration: Math.min(Math.max(keepDistance - dist, 0.0), keepDistance),\r\n    };\r\n}\r\n\r\n/**\r\n * Character controller using physics\r\n */\r\nexport class PhysicsCharacterController {\r\n    private _position: Vector3;\r\n    private _orientation: Quaternion = Quaternion.Identity();\r\n    private _velocity: Vector3;\r\n    private _lastVelocity: Vector3;\r\n    private _shape: PhysicsShape;\r\n    private _body: PhysicsBody;\r\n    private _transformNode: TransformNode;\r\n    private _ownShape: boolean;\r\n    private _shapeOptions: CharacterShapeOptions;\r\n    private _manifold: IContact[] = [];\r\n    private _stepUpSavedManifold: IContact[] = [];\r\n    private _lastDisplacement: Vector3;\r\n    private _contactAngleSensitivity = 10.0;\r\n    private _lastInvDeltaTime: number;\r\n    private _scene: Scene;\r\n    private _tmpMatrix = new Matrix();\r\n    private _tmpVecs: Vector3[] = BuildArray(32, Vector3.Zero);\r\n\r\n    /**\r\n     * minimum distance to make contact\r\n     * default 0.05\r\n     */\r\n    public keepDistance: number = 0.05;\r\n    /**\r\n     * maximum distance to keep contact\r\n     * default 0.1\r\n     */\r\n    public keepContactTolerance: number = 0.1;\r\n    /**\r\n     * maximum number of raycast per integration starp\r\n     * default 10\r\n     */\r\n    public maxCastIterations: number = 10;\r\n    /**\r\n     * speed when recovery from penetration\r\n     * default 1.0\r\n     */\r\n    public penetrationRecoverySpeed = 1.0;\r\n    /**\r\n     * friction with static surfaces\r\n     * default 0\r\n     */\r\n    public staticFriction = 0;\r\n    /**\r\n     * friction with dynamic surfaces\r\n     * default 1\r\n     */\r\n    public dynamicFriction = 1;\r\n    /**\r\n     * cosine value of slope angle that can be climbed\r\n     * computed as `Math.cos(Math.PI * (angleInDegree / 180.0));`\r\n     * default 0.5 (value for a 60deg angle)\r\n     */\r\n    public maxSlopeCosine = 0.5;\r\n    /**\r\n     * Maximum height the character can automatically step up onto a walkable surface.\r\n     * When greater than 0 the controller enforces this as a strict cap on step climbing,\r\n     * independent of the collision shape's geometry:\r\n     *\r\n     *  - Obstacles whose top is at most maxStepHeight above the character's foot are\r\n     *    climbed (either rolled over naturally by the capsule, or snapped up via the\r\n     *    step-up sweep when the simplex would otherwise be blocked).\r\n     *  - Obstacles taller than maxStepHeight are blocked, even ones the capsule's\r\n     *    rounded bottom would otherwise glide over.\r\n     *\r\n     * This is enforced by demoting any \"walkable\" contact that sits more than\r\n     * maxStepHeight above the foot into an extra horizontal wall constraint, so the\r\n     * step-height limit does not depend on the capsule radius. As a documented side\r\n     * effect, slopes whose contact rises above maxStepHeight (roughly when\r\n     * `capsuleRadius * (1 - cos(slopeAngle)) > maxStepHeight`) are also treated as\r\n     * walls. Pick maxStepHeight large enough to clear the slope angles you want to\r\n     * remain walkable, or rely on `maxSlopeCosine` alone (with maxStepHeight = 0)\r\n     * when the rounded-capsule riding behavior is acceptable.\r\n     *\r\n     * Step-up only triggers against STATIC and ANIMATED bodies. Dynamic bodies fall\r\n     * through to normal contact resolution and pushing behavior.\r\n     *\r\n     * Thin walls / fences with floor behind them are not considered steppable: the\r\n     * landing must be measurably higher than the starting position along `up`.\r\n     *\r\n     * The foot is computed as `position - up * footOffset`. Override `footOffset` if\r\n     * you supply a custom collision shape whose center is not at half-height.\r\n     *\r\n     * Assumes `up` is a unit vector.\r\n     *\r\n     * default 0 (disabled)\r\n     */\r\n    public maxStepHeight = 0;\r\n    /**\r\n     * Distance from the body's `position` to the character's foot along `up`.\r\n     * Used by `maxStepHeight` to measure how high a contact sits above the foot.\r\n     * Defaults to half the capsule height passed at construction. Override when\r\n     * supplying a custom collision shape whose center is not at half-height.\r\n     */\r\n    public footOffset: number;\r\n    /**\r\n     * character maximum speed\r\n     * default 10\r\n     */\r\n    public maxCharacterSpeedForSolver = 10.0;\r\n    /**\r\n     * up vector\r\n     */\r\n    public up = new Vector3(0, 1, 0);\r\n    /**\r\n     * Strength when pushing other bodies\r\n     * default 1e38\r\n     */\r\n    public characterStrength = 1e38;\r\n\r\n    /**\r\n     * Acceleration factor. A value of 1 means reaching max velocity immediately\r\n     */\r\n    public acceleration = 0.05;\r\n\r\n    /**\r\n     * maximum acceleration in world space coordinate\r\n     */\r\n    public maxAcceleration = 50;\r\n\r\n    /**\r\n     * character mass\r\n     * default 0\r\n     */\r\n    public characterMass = 0;\r\n\r\n    /**\r\n     * Observable for trigger entered and trigger exited events\r\n     */\r\n    public onTriggerCollisionObservable = new Observable<ICharacterControllerCollisionEvent>();\r\n\r\n    private _startCollector;\r\n    private _castCollector;\r\n\r\n    // If the difference between the cast displacement and the simplex solver output position is less than this\r\n    // value (per component), do not do a second cast to check if it's possible to reach the output position.\r\n    private _displacementEps = 1e-4;\r\n\r\n    /**\r\n     * instanciate a new characterController\r\n     * @param position Initial position\r\n     * @param characterShapeOptions character physics shape options\r\n     * @param scene Scene\r\n     */\r\n    public constructor(position: Vector3, characterShapeOptions: CharacterShapeOptions, scene: Scene) {\r\n        this._position = position.clone();\r\n        this._velocity = Vector3.Zero();\r\n        this._lastVelocity = Vector3.Zero();\r\n        const r = characterShapeOptions.capsuleRadius ?? 0.6;\r\n        const h = characterShapeOptions.capsuleHeight ?? 1.8;\r\n        this.footOffset = h * 0.5;\r\n        this._tmpVecs[0].set(0, h * 0.5 - r, 0);\r\n        this._tmpVecs[1].set(0, -h * 0.5 + r, 0);\r\n        this._ownShape = !characterShapeOptions.shape;\r\n        this._shapeOptions = characterShapeOptions;\r\n        this._shape = characterShapeOptions.shape ?? new PhysicsShapeCapsule(this._tmpVecs[0], this._tmpVecs[1], r, scene);\r\n        this._transformNode = new TransformNode(\"CCTransformNode\", scene);\r\n        this._transformNode.position.copyFrom(this._position);\r\n        this._body = new PhysicsBody(this._transformNode, PhysicsMotionType.ANIMATED, false, scene);\r\n        this._body.setMassProperties({ inertia: Vector3.ZeroReadOnly });\r\n        this._body.shape = this._shape;\r\n        this._body.disablePreStep = false;\r\n        this._lastInvDeltaTime = 1.0 / 60.0;\r\n        this._lastDisplacement = Vector3.Zero();\r\n        this._scene = scene;\r\n\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const hknp = hk._hknp;\r\n\r\n        this._startCollector = hknp.HP_QueryCollector_Create(16)[1];\r\n        this._castCollector = hknp.HP_QueryCollector_Create(16)[1];\r\n    }\r\n\r\n    /**\r\n     * Dispose the character controller\r\n     */\r\n    public dispose() {\r\n        if (this._ownShape) {\r\n            this._shape.dispose();\r\n        }\r\n        this._body.dispose();\r\n        this._transformNode.dispose();\r\n\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const hknp = hk._hknp;\r\n        hknp.HP_QueryCollector_Release(this._startCollector);\r\n        hknp.HP_QueryCollector_Release(this._castCollector);\r\n    }\r\n\r\n    /**\r\n     * Get shape used for collision\r\n     */\r\n    public get shape() {\r\n        return this._shape;\r\n    }\r\n\r\n    /**\r\n     * Set shape used for collision\r\n     */\r\n    public set shape(value: PhysicsShape) {\r\n        this._body.shape = value;\r\n        if (this._ownShape) {\r\n            this._shape.dispose();\r\n        }\r\n        this._shape = value;\r\n        this._ownShape = false;\r\n    }\r\n\r\n    /**\r\n     * Get the shape options used to build the collision shape\r\n     */\r\n    public get shapeOptions(): CharacterShapeOptions {\r\n        return this._shapeOptions;\r\n    }\r\n\r\n    /**\r\n     * Set new shape options and rebuild the collision shape accordingly.\r\n     * When the options provide an explicit `shape`, it is used directly; otherwise\r\n     * a capsule is created from the `capsuleHeight` / `capsuleRadius` values. The\r\n     * resulting shape is assigned through the shape setter, which releases the\r\n     * previously owned shape.\r\n     * @param characterShapeOptions character physics shape options\r\n     * @param preserveFootPosition when true (default), the controller position is adapted so the\r\n     * world-space foot position (center - up * footOffset) is kept fixed as the height changes; when\r\n     * false, the position is left unchanged.\r\n     */\r\n    public setShapeOptions(characterShapeOptions: CharacterShapeOptions, preserveFootPosition = true) {\r\n        this._shapeOptions = characterShapeOptions;\r\n        const r = characterShapeOptions.capsuleRadius ?? 0.6;\r\n        const h = characterShapeOptions.capsuleHeight ?? 1.8;\r\n        const newFootOffset = h * 0.5;\r\n\r\n        if (preserveFootPosition) {\r\n            // Compute the current world-space foot position (center - up * footOffset), then move the\r\n            // center so the feet stay fixed for the new half-height: center = foot + up * newFootOffset.\r\n            const foot = this._tmpVecs[2];\r\n            this.up.scaleToRef(this.footOffset, foot);\r\n            this._position.subtractToRef(foot, foot);\r\n            this.up.scaleToRef(newFootOffset, this._tmpVecs[3]);\r\n            foot.addToRef(this._tmpVecs[3], this._position);\r\n            this._transformNode.position.copyFrom(this._position);\r\n        }\r\n\r\n        this.footOffset = newFootOffset;\r\n        this._tmpVecs[0].set(0, h * 0.5 - r, 0);\r\n        this._tmpVecs[1].set(0, -h * 0.5 + r, 0);\r\n        const ownShape = !characterShapeOptions.shape;\r\n        this.shape = characterShapeOptions.shape ?? new PhysicsShapeCapsule(this._tmpVecs[0], this._tmpVecs[1], r, this._scene);\r\n        this._ownShape = ownShape;\r\n    }\r\n\r\n    /**\r\n     * Character position\r\n     * @returns Character position\r\n     */\r\n    public getPosition(): Vector3 {\r\n        return this._position;\r\n    }\r\n\r\n    /**\r\n     * Teleport character to a new position\r\n     * @param position new position\r\n     */\r\n    public setPosition(position: Vector3) {\r\n        this._position.copyFrom(position);\r\n        this._transformNode.position.copyFrom(this._position);\r\n    }\r\n\r\n    /**\r\n     * Character velocity\r\n     * @returns Character velocity vector\r\n     */\r\n    public getVelocity(): Vector3 {\r\n        return this._velocity;\r\n    }\r\n\r\n    /**\r\n     * Set velocity vector\r\n     * @param velocity vector\r\n     */\r\n    public setVelocity(velocity: Vector3) {\r\n        this._velocity.copyFrom(velocity);\r\n    }\r\n\r\n    protected _validateManifold() {\r\n        const newManifold = [];\r\n        for (let i = 0; i < this._manifold.length; i++) {\r\n            if (!this._manifold[i].bodyB.body.isDisposed) {\r\n                newManifold.push(this._manifold[i]);\r\n            }\r\n        }\r\n        this._manifold = newManifold;\r\n    }\r\n\r\n    private _getPointVelocityToRef(body: { body: PhysicsBody; index: number }, pointWorld: Vector3, result: Vector3) {\r\n        //<todo does this really not exist in body interface?\r\n        const comWorld = this._tmpVecs[10];\r\n        this._getComWorldToRef(body, comWorld);\r\n        const relPos = this._tmpVecs[11];\r\n        pointWorld.subtractToRef(comWorld, relPos);\r\n        const av = this._tmpVecs[12];\r\n        body.body.getAngularVelocityToRef(av, body.index);\r\n        const arm = this._tmpVecs[13];\r\n        Vector3.CrossToRef(av, relPos, arm);\r\n        arm.addToRef(body.body.getLinearVelocity(body.index), result);\r\n    }\r\n\r\n    protected _compareContacts(contactA: IContact, contactB: IContact): number {\r\n        const angSquared = (1.0 - contactA.normal.dot(contactB.normal)) * this._contactAngleSensitivity * this._contactAngleSensitivity;\r\n        const planeDistSquared = (contactA.distance - contactB.distance) * (contactA.distance * contactB.distance);\r\n\r\n        const p1Vel = this._tmpVecs[7];\r\n        this._getPointVelocityToRef(contactA.bodyB, contactA.position, p1Vel);\r\n        const p2Vel = this._tmpVecs[8];\r\n        this._getPointVelocityToRef(contactB.bodyB, contactB.position, p2Vel);\r\n        const velocityDiff = this._tmpVecs[9];\r\n        p1Vel.subtractToRef(p2Vel, velocityDiff);\r\n        const velocityDiffSquared = velocityDiff.lengthSquared();\r\n\r\n        const fitness = angSquared * 10.0 + velocityDiffSquared * 0.1 + planeDistSquared;\r\n        return fitness;\r\n    }\r\n\r\n    protected _findContact(referenceContact: IContact, contactList: IContact[], threshold: number) {\r\n        let bestIdx = -1;\r\n        let bestFitness = threshold;\r\n        for (let i = 0; i < contactList.length; i++) {\r\n            const fitness = this._compareContacts(referenceContact, contactList[i]);\r\n            if (fitness < bestFitness) {\r\n                bestFitness = fitness;\r\n                bestIdx = i;\r\n            }\r\n        }\r\n        return bestIdx;\r\n    }\r\n\r\n    protected _updateManifold(startCollector: any /*HP_CollectorId*/, castCollector: any /*HP_CollectorId*/, castPath: Vector3): number {\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const hknp = hk._hknp;\r\n\r\n        const numProximityHits = hknp.HP_QueryCollector_GetNumHits(startCollector)[1];\r\n        if (numProximityHits > 0) {\r\n            const newContacts = [];\r\n            let minDistance = 1e38;\r\n            const bodyMap = (<any>hk)._bodies;\r\n            for (let i = 0; i < numProximityHits; i++) {\r\n                const [distance, , contactWorld] = hknp.HP_QueryCollector_GetShapeProximityResult(startCollector, i)[1];\r\n                minDistance = Math.min(minDistance, distance);\r\n                newContacts.push({\r\n                    position: Vector3.FromArray(contactWorld[3]),\r\n                    normal: Vector3.FromArray(contactWorld[4]),\r\n                    distance: distance,\r\n                    fraction: 0,\r\n                    bodyB: bodyMap.get(contactWorld[0][0])!,\r\n                    allowedPenetration: Math.min(Math.max(this.keepDistance - distance, 0.0), this.keepDistance),\r\n                });\r\n            }\r\n\r\n            for (let i = this._manifold.length - 1; i >= 0; i--) {\r\n                const currentContact = this._manifold[i];\r\n                const bestMatch = this._findContact(currentContact, newContacts, 1.1);\r\n                if (bestMatch >= 0) {\r\n                    const newAllowedPenetration = Math.min(Math.max(this.keepDistance - newContacts[bestMatch].distance, 0.0), currentContact.allowedPenetration);\r\n                    this._manifold[i] = newContacts[bestMatch];\r\n                    this._manifold[i].allowedPenetration = newAllowedPenetration;\r\n                    newContacts.splice(bestMatch, 1);\r\n                } else {\r\n                    this._manifold.splice(i, 1);\r\n                }\r\n            }\r\n\r\n            const closestContactIndex = newContacts.findIndex((c) => c.distance == minDistance);\r\n            if (closestContactIndex >= 0) {\r\n                const bestMatch = this._findContact(newContacts[closestContactIndex], this._manifold, 0.1);\r\n                if (bestMatch >= 0) {\r\n                    const newAllowedPenetration = Math.min(\r\n                        Math.max(this.keepDistance - newContacts[closestContactIndex].distance, 0.0),\r\n                        this._manifold[bestMatch].allowedPenetration\r\n                    );\r\n                    this._manifold[bestMatch] = newContacts[closestContactIndex];\r\n                    this._manifold[bestMatch].allowedPenetration = newAllowedPenetration;\r\n                } else {\r\n                    this._manifold.push(newContacts[closestContactIndex]);\r\n                }\r\n            }\r\n        } else {\r\n            // No start hits; clear manifold completely\r\n            this._manifold.length = 0;\r\n        }\r\n\r\n        let numHitBodies = 0; //< == CASTCOLLECTOR_HIT_SINGLE_BODY\r\n        // Process shape cast results if any\r\n        const numCastHits = hknp.HP_QueryCollector_GetNumHits(castCollector)[1];\r\n        if (numCastHits > 0) {\r\n            let closestHitBody = null;\r\n            for (let i = 0; i < numCastHits; i++) {\r\n                const [fraction, , hitWorld] = hknp.HP_QueryCollector_GetShapeCastResult(castCollector, i)[1];\r\n                if (closestHitBody == null) {\r\n                    const contact = ContactFromCast(hk, hitWorld, castPath, fraction, this.keepDistance);\r\n                    closestHitBody = hitWorld[0][0];\r\n                    const bestMatch = this._findContact(contact, this._manifold, 0.1);\r\n                    if (bestMatch == -1) {\r\n                        this._manifold.push(contact);\r\n                    }\r\n\r\n                    if (contact.bodyB.body.getMotionType(contact.bodyB.index) == PhysicsMotionType.STATIC) {\r\n                        // The closest body is static, so it cannot move away from CC and we don't need to look any further.\r\n                        break;\r\n                    }\r\n                } else if (closestHitBody._pluginData && hitWorld[0] != closestHitBody._pluginData.hpBodyId) {\r\n                    numHitBodies++;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Remove from the manifold contacts that are too similar as the simplex does not handle parallel planes\r\n        for (let e1 = this._manifold.length - 1; e1 >= 0; e1--) {\r\n            let e2 = e1 - 1;\r\n            for (; e2 >= 0; e2--) {\r\n                const fitness = this._compareContacts(this._manifold[e1], this._manifold[e2]);\r\n                if (fitness < 0.1) {\r\n                    break;\r\n                }\r\n            }\r\n            if (e2 >= 0) {\r\n                this._manifold.slice(e1, 1);\r\n            }\r\n        }\r\n\r\n        return numHitBodies;\r\n    }\r\n\r\n    // Store previous positions per body for velocity calculation\r\n    protected _bodyPositionTracking = new Map();\r\n\r\n    protected _createSurfaceConstraint(dt: number, contact: IContact, timeTravelled: number): ISurfaceConstraintInfo {\r\n        const constraint = {\r\n            //let distance = contact.distance - this.keepDistance;\r\n            planeNormal: contact.normal.clone(),\r\n            planeDistance: contact.distance,\r\n            staticFriction: this.staticFriction,\r\n            dynamicFriction: this.dynamicFriction,\r\n            extraUpStaticFriction: 0,\r\n            extraDownStaticFriction: 0,\r\n            velocity: Vector3.Zero(),\r\n            angularVelocity: Vector3.Zero(),\r\n            priority: 0,\r\n        };\r\n\r\n        const maxSlopeCosEps = 0.1;\r\n        const maxSlopeCosine = Math.max(this.maxSlopeCosine, maxSlopeCosEps);\r\n        const normalDotUp = contact.normal.dot(this.up);\r\n\r\n        const contactPosition = contact.position.clone();\r\n        if (normalDotUp > maxSlopeCosine) {\r\n            const com = this.getPosition();\r\n            const contactArm = this._tmpVecs[20];\r\n            contact.position.subtractToRef(com, contactArm);\r\n            const scale = contact.normal.dot(contactArm);\r\n            contactPosition.x = com.x + this.up.x * scale;\r\n            contactPosition.y = com.y + this.up.y * scale;\r\n            contactPosition.z = com.z + this.up.z * scale;\r\n        }\r\n\r\n        const motionType = contact.bodyB.body.getMotionType(contact.bodyB.index);\r\n        if (motionType != PhysicsMotionType.STATIC) {\r\n            //<todo Need hknpMotionUtil::predictPontVelocity\r\n        }\r\n\r\n        const shift = constraint.velocity.dot(constraint.planeNormal) * timeTravelled;\r\n        constraint.planeDistance -= shift;\r\n\r\n        if (motionType == PhysicsMotionType.STATIC) {\r\n            constraint.priority = 2;\r\n        } else if (motionType == PhysicsMotionType.ANIMATED) {\r\n            const bodyTransformNode = contact.bodyB.body.transformNode;\r\n            const bodyId = bodyTransformNode.uniqueId;\r\n\r\n            // Retrieve tracking data\r\n            let tracking = this._bodyPositionTracking.get(bodyId);\r\n\r\n            const currentFrameWorldMatrix = contact.bodyB.body.transformNode.getWorldMatrix();\r\n            const frameId = this._scene.getFrameId();\r\n\r\n            if (!tracking) {\r\n                // Initialize tracking\r\n                tracking = {\r\n                    prevWorldMatrix: currentFrameWorldMatrix.clone(),\r\n                    frameId: frameId,\r\n                };\r\n                this._bodyPositionTracking.set(bodyId, tracking);\r\n            } else {\r\n                // Only calculate velocity if this contact existed in the previous frame\r\n                // This avoids huge delta spikes when first making contact or after gaps\r\n                if (tracking.frameId + 1 === frameId) {\r\n                    const previousFrameWorldMatrix = tracking.prevWorldMatrix;\r\n\r\n                    const currentFrameWorldMatrixInverse = TmpVectors.Matrix[1];\r\n\r\n                    currentFrameWorldMatrix.invertToRef(currentFrameWorldMatrixInverse);\r\n\r\n                    const characterPosition = this.getPosition();\r\n                    // compute characterPosition in body local space at previous frame\r\n                    const characterLocalPosition = this._tmpVecs[21];\r\n                    Vector3.TransformCoordinatesToRef(characterPosition, currentFrameWorldMatrixInverse, characterLocalPosition);\r\n\r\n                    const characterWorldPosition = this._tmpVecs[22];\r\n                    Vector3.TransformCoordinatesToRef(characterLocalPosition, previousFrameWorldMatrix, characterWorldPosition);\r\n                    const playerDeltaPosition = this._tmpVecs[23];\r\n                    characterPosition.subtractToRef(characterWorldPosition, playerDeltaPosition);\r\n\r\n                    constraint.velocity.copyFrom(playerDeltaPosition);\r\n                    constraint.velocity.scaleInPlace(1 / dt);\r\n                    constraint.priority = 1;\r\n                }\r\n                tracking.prevWorldMatrix.copyFrom(currentFrameWorldMatrix);\r\n                tracking.frameId = frameId;\r\n            }\r\n        }\r\n\r\n        return constraint;\r\n    }\r\n\r\n    protected _addMaxSlopePlane(maxSlopeCos: number, up: Vector3, index: number, constraints: ISurfaceConstraintInfo[], allowedPenetration: number): boolean {\r\n        const verticalComponent = constraints[index].planeNormal.dot(up);\r\n        if (verticalComponent > 0.01 && verticalComponent < maxSlopeCos) {\r\n            const newConstraint = {\r\n                planeNormal: constraints[index].planeNormal.clone(),\r\n                planeDistance: constraints[index].planeDistance,\r\n                velocity: constraints[index].velocity.clone(),\r\n                angularVelocity: constraints[index].angularVelocity.clone(),\r\n                priority: constraints[index].priority,\r\n                dynamicFriction: constraints[index].dynamicFriction,\r\n                staticFriction: constraints[index].staticFriction,\r\n                extraDownStaticFriction: constraints[index].extraDownStaticFriction,\r\n                extraUpStaticFriction: constraints[index].extraUpStaticFriction,\r\n            };\r\n            const distance = newConstraint.planeDistance;\r\n            newConstraint.planeNormal.subtractInPlace(up.scale(verticalComponent));\r\n            newConstraint.planeNormal.normalize();\r\n            if (distance >= 0) {\r\n                newConstraint.planeDistance = distance * newConstraint.planeNormal.dot(constraints[index].planeNormal);\r\n            } else {\r\n                const penetrationToResolve = Math.min(0, distance + allowedPenetration);\r\n                newConstraint.planeDistance = penetrationToResolve / newConstraint.planeNormal.dot(constraints[index].planeNormal);\r\n                constraints[index].planeDistance = 0;\r\n                this._resolveConstraintPenetration(newConstraint, this.penetrationRecoverySpeed);\r\n            }\r\n            constraints.push(newConstraint);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Adds an extra horizontal wall constraint when a \"walkable\" contact sits more than\r\n     * `maxStepHeight` above the character's foot along `up`. Mirrors the structure of\r\n     * `_addMaxSlopePlane` but gates on contact height rather than slope steepness.\r\n     *\r\n     * This makes `maxStepHeight` a strict cap on step climbing independent of the\r\n     * capsule's curved bottom: without this, the rounded hemisphere produces an up-tilted\r\n     * (walkable) contact normal for any obstacle shorter than the capsule radius, and\r\n     * the simplex rides over it regardless of `maxStepHeight`.\r\n     * @param constraints constraint list being assembled for the current manifold\r\n     * @param contact source manifold contact backing `constraints[index]`\r\n     * @param index index of the constraint in `constraints` whose contact is under test\r\n     * @param allowedPenetration allowed penetration distance for this contact\r\n     * @returns true if an extra wall constraint was appended\r\n     */\r\n    protected _addStepHeightWallPlane(constraints: ISurfaceConstraintInfo[], contact: IContact, index: number, allowedPenetration: number): boolean {\r\n        const verticalComponent = constraints[index].planeNormal.dot(this.up);\r\n        // Skip near-flat (≈1) contacts (don't demote plain ground) and near-horizontal\r\n        // contacts (already wall-like — the regular constraint handles them).\r\n        if (verticalComponent <= 0.01 || verticalComponent >= 1 - 1e-3) {\r\n            return false;\r\n        }\r\n        // Height of the contact point above the character's foot, projected onto `up`.\r\n        const contactDelta = this._tmpVecs[24];\r\n        contact.position.subtractToRef(this._position, contactDelta);\r\n        const stepHeight = contactDelta.dot(this.up) + this.footOffset;\r\n        if (stepHeight <= this.maxStepHeight) {\r\n            return false;\r\n        }\r\n        const newConstraint = {\r\n            planeNormal: constraints[index].planeNormal.clone(),\r\n            planeDistance: constraints[index].planeDistance,\r\n            velocity: constraints[index].velocity.clone(),\r\n            angularVelocity: constraints[index].angularVelocity.clone(),\r\n            priority: constraints[index].priority,\r\n            dynamicFriction: constraints[index].dynamicFriction,\r\n            staticFriction: constraints[index].staticFriction,\r\n            extraDownStaticFriction: constraints[index].extraDownStaticFriction,\r\n            extraUpStaticFriction: constraints[index].extraUpStaticFriction,\r\n        };\r\n        const distance = newConstraint.planeDistance;\r\n        const stepWallVerticalProjection = TmpVectors.Vector3[0];\r\n        this.up.scaleToRef(verticalComponent, stepWallVerticalProjection);\r\n        newConstraint.planeNormal.subtractInPlace(stepWallVerticalProjection);\r\n        newConstraint.planeNormal.normalize();\r\n        if (distance >= 0) {\r\n            newConstraint.planeDistance = distance * newConstraint.planeNormal.dot(constraints[index].planeNormal);\r\n        } else {\r\n            const penetrationToResolve = Math.min(0, distance + allowedPenetration);\r\n            newConstraint.planeDistance = penetrationToResolve / newConstraint.planeNormal.dot(constraints[index].planeNormal);\r\n            constraints[index].planeDistance = 0;\r\n            this._resolveConstraintPenetration(newConstraint, this.penetrationRecoverySpeed);\r\n        }\r\n        constraints.push(newConstraint);\r\n        return true;\r\n    }\r\n\r\n    protected _resolveConstraintPenetration(constraint: ISurfaceConstraintInfo, penetrationRecoverySpeed: number) {\r\n        // If penetrating we add extra velocity to push the character back out\r\n        const eps = 1e-6;\r\n        if (constraint.planeDistance < -eps) {\r\n            constraint.planeNormal.scaleToRef(constraint.planeDistance * penetrationRecoverySpeed, this._tmpVecs[6]);\r\n            constraint.velocity.subtractInPlace(this._tmpVecs[6]);\r\n        }\r\n    }\r\n\r\n    protected _createConstraintsFromManifold(dt: number, timeTravelled: number): ISurfaceConstraintInfo[] {\r\n        const constraints = [];\r\n        for (let i = 0; i < this._manifold.length; i++) {\r\n            const surfaceConstraint = this._createSurfaceConstraint(dt, this._manifold[i], timeTravelled);\r\n            constraints.push(surfaceConstraint);\r\n            const slopeDemoted = this._addMaxSlopePlane(this.maxSlopeCosine, this.up, i, constraints, this._manifold[i].allowedPenetration);\r\n            // Step-height filter: when the contact sits above the foot by more than\r\n            // `maxStepHeight`, add an extra horizontal wall constraint so the simplex\r\n            // cannot ride over the contact via the capsule's rounded bottom. Skip when\r\n            // the slope check already added a wall for the same contact.\r\n            if (!slopeDemoted && this.maxStepHeight > 0) {\r\n                this._addStepHeightWallPlane(constraints, this._manifold[i], i, this._manifold[i].allowedPenetration);\r\n            }\r\n            this._resolveConstraintPenetration(surfaceConstraint, this.penetrationRecoverySpeed);\r\n        }\r\n        return constraints;\r\n    }\r\n\r\n    protected _simplexSolverSortInfo(info: SimplexSolverInfo) {\r\n        // simple bubble sort by (priority,velocity)\r\n        for (let i = 0; i < info.numSupportPlanes - 1; i++) {\r\n            for (let j = i + 1; j < info.numSupportPlanes; j++) {\r\n                const p0 = info.supportPlanes[i];\r\n                const p1 = info.supportPlanes[j];\r\n                if (p0.constraint.priority < p1.constraint.priority) {\r\n                    continue;\r\n                }\r\n                if (p0.constraint.priority == p1.constraint.priority) {\r\n                    const vel0 = p0.constraint.velocity.lengthSquared();\r\n                    const vel1 = p1.constraint.velocity.lengthSquared();\r\n                    if (vel0 < vel1) {\r\n                        continue;\r\n                    }\r\n                }\r\n                info.supportPlanes[i] = p1;\r\n                info.supportPlanes[j] = p0;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _simplexSolverSolve1d(info: SimplexSolverInfo, sci: ISurfaceConstraintInfo, velocityIn: Vector3, velocityOut: Vector3) {\r\n        const eps = 1e-5;\r\n        const groundVelocity = sci.velocity;\r\n        const relativeVelocity = this._tmpVecs[22];\r\n        velocityIn.subtractToRef(groundVelocity, relativeVelocity);\r\n\r\n        const planeVel = relativeVelocity.dot(sci.planeNormal);\r\n\r\n        const origVelocity2 = relativeVelocity.lengthSquared();\r\n        relativeVelocity.subtractInPlace(sci.planeNormal.scale(planeVel));\r\n        {\r\n            const vp2 = planeVel * planeVel;\r\n            // static friction is active if\r\n            //  velProjPlane * friction > |(velParallel)|\r\n            //      vplane   *     f    >         vpar\r\n            //      vp       *     f    >         vpar\r\n            //      vp2      *     f2   >         vpar2\r\n            const extraStaticFriction = relativeVelocity.dot(this.up) > 0 ? sci.extraUpStaticFriction : sci.extraDownStaticFriction;\r\n            if (extraStaticFriction > 0) {\r\n                const horizontal = this.up.cross(sci.planeNormal);\r\n                const hor2 = horizontal.lengthSquared();\r\n                let horVel = 0.0;\r\n                if (hor2 > eps) {\r\n                    horizontal.scaleInPlace(1 / Math.sqrt(hor2));\r\n\r\n                    horVel = relativeVelocity.dot(horizontal);\r\n\r\n                    // horizontal component\r\n                    {\r\n                        const horVel2 = horVel * horVel;\r\n                        const f2 = sci.staticFriction * sci.staticFriction;\r\n                        if (vp2 * f2 >= horVel2) {\r\n                            relativeVelocity.subtractInPlace(horizontal.scale(horVel));\r\n                            horVel = 0;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // vert component\r\n                {\r\n                    const vertVel2 = origVelocity2 - horVel * horVel - vp2;\r\n                    const f2 = (sci.staticFriction + extraStaticFriction) * (sci.staticFriction + extraStaticFriction);\r\n                    if (vp2 * f2 >= vertVel2) {\r\n                        if (horVel == 0.0) {\r\n                            velocityOut.copyFrom(groundVelocity);\r\n                            return;\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n                // static friction is active if\r\n                //  velProjPlane * friction > |(vel-velProjPlane)|\r\n                //      vp       *     f    >         rvProj\r\n                //\r\n                //  -> vp * f >= rvProj\r\n                //  -> vp * f >= sqrt( vel^2 - vp^2 )\r\n                //  -> vp^2 ( f^2 + 1 ) >= vel^2\r\n                const f2 = sci.staticFriction * sci.staticFriction;\r\n                if (vp2 * (1 + f2) >= origVelocity2) {\r\n                    velocityOut.copyFrom(groundVelocity);\r\n                    return;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (sci.dynamicFriction < 1) {\r\n            //  apply dynamic friction 0 = conserve input velocity 1 = clip against normal\r\n            const velOut2 = relativeVelocity.lengthSquared();\r\n            if (velOut2 >= eps) {\r\n                if (velOut2 > 1e-4 * origVelocity2) {\r\n                    let f = Math.sqrt(origVelocity2 / velOut2);\r\n                    f = sci.dynamicFriction + (1 - sci.dynamicFriction) * f;\r\n                    relativeVelocity.scaleInPlace(f);\r\n                    const p = sci.planeNormal.dot(relativeVelocity);\r\n                    relativeVelocity.subtractInPlace(sci.planeNormal.scale(p));\r\n                }\r\n            }\r\n        }\r\n        velocityOut.copyFrom(relativeVelocity);\r\n        velocityOut.addInPlace(groundVelocity);\r\n    }\r\n\r\n    protected _simplexSolverSolveTest1d(sci: ISurfaceConstraintInfo, velocityIn: Vector3): boolean {\r\n        const eps = 1e-3;\r\n        const relativeVelocity = this._tmpVecs[23];\r\n        velocityIn.subtractToRef(sci.velocity, relativeVelocity);\r\n        return relativeVelocity.dot(sci.planeNormal) < -eps;\r\n    }\r\n\r\n    protected _simplexSolverSolve2d(\r\n        info: SimplexSolverInfo,\r\n        maxSurfaceVelocity: Vector3,\r\n        sci0: ISurfaceConstraintInfo,\r\n        sci1: ISurfaceConstraintInfo,\r\n        velocityIn: Vector3,\r\n        velocityOut: Vector3\r\n    ) {\r\n        const eps = 1e-5;\r\n        const axis = sci0.planeNormal.cross(sci1.planeNormal);\r\n        const axisLen2 = axis.lengthSquared();\r\n\r\n        let solveSequentially: boolean = false;\r\n        let axisVel: Vector3 | null;\r\n\r\n        // eslint-disable-next-line no-constant-condition\r\n        while (true) {\r\n            // Check for parallel planes\r\n            if (axisLen2 <= eps || solveSequentially) {\r\n                info.getOutput(sci0).status = SurfaceConstraintInteractionStatus.FAILURE_2D;\r\n                info.getOutput(sci1).status = SurfaceConstraintInteractionStatus.FAILURE_2D;\r\n\r\n                if (sci0.priority > sci1.priority) {\r\n                    this._simplexSolverSolve1d(info, sci1, velocityIn, velocityOut);\r\n                    this._simplexSolverSolve1d(info, sci0, velocityIn, velocityOut);\r\n                } else {\r\n                    this._simplexSolverSolve1d(info, sci0, velocityIn, velocityOut);\r\n                    this._simplexSolverSolve1d(info, sci1, velocityIn, velocityOut);\r\n                }\r\n                return;\r\n            }\r\n\r\n            const invAxisLen = 1.0 / Math.sqrt(axisLen2);\r\n            axis.scaleInPlace(invAxisLen);\r\n\r\n            //  Calculate the velocity of the free axis\r\n            {\r\n                const r0 = sci0.planeNormal.cross(sci1.planeNormal);\r\n                const r1 = sci1.planeNormal.cross(axis);\r\n                const r2 = axis.cross(sci0.planeNormal);\r\n\r\n                const sVel = sci0.velocity.add(sci1.velocity);\r\n\r\n                const t = this._tmpVecs[2];\r\n                t.set(0.5 * axis.dot(sVel), sci0.planeNormal.dot(sci0.velocity), sci1.planeNormal.dot(sci1.velocity));\r\n                const m = Matrix.FromValues(r0.x, r1.x, r2.x, 0, r0.y, r1.y, r2.y, 0, r0.z, r1.z, r2.z, 0, 0, 0, 0, 1);\r\n                axisVel = Vector3.TransformNormal(t, m);\r\n                axisVel.scaleInPlace(invAxisLen);\r\n\r\n                if (Math.abs(axisVel.x) > maxSurfaceVelocity.x || Math.abs(axisVel.y) > maxSurfaceVelocity.y || Math.abs(axisVel.z) > maxSurfaceVelocity.z) {\r\n                    solveSequentially = true;\r\n                } else {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        const groundVelocity = axisVel;\r\n        const relativeVelocity = this._tmpVecs[24];\r\n        velocityIn.subtractToRef(groundVelocity, relativeVelocity);\r\n\r\n        const vel2 = relativeVelocity.lengthSquared();\r\n        const axisVert = this.up.dot(axis);\r\n        let axisProjVelocity = relativeVelocity.dot(axis);\r\n\r\n        let staticFriction = sci0.staticFriction + sci1.staticFriction;\r\n        if (axisVert * axisProjVelocity > 0) {\r\n            staticFriction += (sci0.extraUpStaticFriction + sci1.extraUpStaticFriction) * axisVert;\r\n        } else {\r\n            staticFriction += (sci0.extraDownStaticFriction + sci1.extraDownStaticFriction) * axisVert;\r\n        }\r\n        staticFriction *= 0.5;\r\n\r\n        const dynamicFriction = (sci0.dynamicFriction + sci1.dynamicFriction) * 0.5;\r\n        // static friction is active if\r\n        //  |vel-axisProjVelocity|(rv) * friction(f) > axisProjVelocity(av)\r\n        //  -> sqrt( vel2 - av2 ) * f > av\r\n        //  -> (vel2 - av2) * f2  > av2\r\n        const f2 = staticFriction * staticFriction;\r\n        const av2 = axisProjVelocity * axisProjVelocity;\r\n        if ((vel2 - av2) * f2 >= av2) {\r\n            // static friction kicks in\r\n            velocityOut.copyFrom(groundVelocity);\r\n            return;\r\n        }\r\n\r\n        if (dynamicFriction < 1) {\r\n            //  apply dynamic friction\r\n            if (axisProjVelocity * axisProjVelocity > 1e-4 * vel2) {\r\n                const tmp = 1.0 / axisProjVelocity;\r\n                const f = Math.abs(tmp) * Math.sqrt(vel2) * (1.0 - dynamicFriction) + dynamicFriction;\r\n                axisProjVelocity *= f;\r\n            }\r\n        }\r\n        velocityOut.copyFrom(groundVelocity);\r\n        velocityOut.addInPlace(axis.scale(axisProjVelocity));\r\n    }\r\n\r\n    protected _simplexSolverSolve3d(\r\n        info: SimplexSolverInfo,\r\n        maxSurfaceVelocity: Vector3,\r\n        sci0: ISurfaceConstraintInfo,\r\n        sci1: ISurfaceConstraintInfo,\r\n        sci2: ISurfaceConstraintInfo,\r\n        allowResort: boolean,\r\n        velocityIn: Vector3,\r\n        velocityOut: Vector3\r\n    ) {\r\n        const eps = 1e-5;\r\n        //  Calculate the velocity of the point axis\r\n        let pointVel: Vector3 | null;\r\n        {\r\n            const r0 = sci1.planeNormal.cross(sci2.planeNormal);\r\n            const r1 = sci2.planeNormal.cross(sci0.planeNormal);\r\n            const r2 = sci0.planeNormal.cross(sci1.planeNormal);\r\n\r\n            const det = r0.dot(sci0.planeNormal);\r\n            let solveSequentially: boolean = false;\r\n            // eslint-disable-next-line no-constant-condition\r\n            while (true) {\r\n                if (Math.abs(det) < eps || solveSequentially) {\r\n                    if (allowResort) {\r\n                        this._simplexSolverSortInfo(info);\r\n                        sci0 = info.supportPlanes[0].constraint;\r\n                        sci1 = info.supportPlanes[1].constraint;\r\n                        sci2 = info.supportPlanes[2].constraint;\r\n                    }\r\n                    info.getOutput(sci0).status = SurfaceConstraintInteractionStatus.FAILURE_3D;\r\n                    info.getOutput(sci1).status = SurfaceConstraintInteractionStatus.FAILURE_3D;\r\n                    info.getOutput(sci2).status = SurfaceConstraintInteractionStatus.FAILURE_3D;\r\n\r\n                    const oldNum = info.numSupportPlanes;\r\n                    this._simplexSolverSolve2d(info, maxSurfaceVelocity, sci0, sci1, velocityIn, velocityOut);\r\n                    if (oldNum == info.numSupportPlanes) {\r\n                        this._simplexSolverSolve2d(info, maxSurfaceVelocity, sci0, sci2, velocityIn, velocityOut);\r\n                    }\r\n                    if (oldNum == info.numSupportPlanes) {\r\n                        this._simplexSolverSolve2d(info, maxSurfaceVelocity, sci1, sci2, velocityIn, velocityOut);\r\n                    }\r\n\r\n                    return;\r\n                }\r\n\r\n                const t = this._tmpVecs[2];\r\n                t.set(sci0.planeNormal.dot(sci0.velocity), sci1.planeNormal.dot(sci1.velocity), sci2.planeNormal.dot(sci2.velocity));\r\n                const m = Matrix.FromValues(r0.x, r0.y, r0.z, 0, r1.x, r1.y, r1.z, 0, r2.x, r2.y, r2.z, 0, 0, 0, 0, 1);\r\n                pointVel = Vector3.TransformNormal(t, m);\r\n                pointVel.scaleInPlace(1 / det);\r\n                if (Math.abs(pointVel.x) > maxSurfaceVelocity.x || Math.abs(pointVel.y) > maxSurfaceVelocity.y || Math.abs(pointVel.z) > maxSurfaceVelocity.z) {\r\n                    solveSequentially = true;\r\n                } else {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        velocityOut.copyFrom(pointVel);\r\n    }\r\n\r\n    protected _simplexSolverExamineActivePlanes(info: SimplexSolverInfo, maxSurfaceVelocity: Vector3, velocityIn: Vector3, velocityOut: Vector3) {\r\n        // eslint-disable-next-line no-constant-condition\r\n        while (true) {\r\n            switch (info.numSupportPlanes) {\r\n                case 1: {\r\n                    const sci = info.supportPlanes[0].constraint;\r\n                    this._simplexSolverSolve1d(info, sci, velocityIn, velocityOut);\r\n                    return;\r\n                }\r\n                case 2: {\r\n                    const velocity = Vector3.Zero();\r\n                    this._simplexSolverSolve1d(info, info.supportPlanes[1].constraint, velocityIn, velocity);\r\n                    const plane0Used = this._simplexSolverSolveTest1d(info.supportPlanes[0].constraint, velocity);\r\n                    if (!plane0Used) {\r\n                        // Only need plane 1, so remove plane 0\r\n                        info.supportPlanes[0].copyFrom(info.supportPlanes[1]);\r\n                        info.numSupportPlanes = 1;\r\n                        velocityOut.copyFrom(velocity);\r\n                    } else {\r\n                        this._simplexSolverSolve2d(info, maxSurfaceVelocity, info.supportPlanes[0].constraint, info.supportPlanes[1].constraint, velocityIn, velocityOut);\r\n                    }\r\n                    return;\r\n                }\r\n                case 3: {\r\n                    // Try to drop both planes\r\n                    {\r\n                        const velocity = Vector3.Zero();\r\n                        this._simplexSolverSolve1d(info, info.supportPlanes[2].constraint, velocityIn, velocityOut);\r\n\r\n                        const plane0Used = this._simplexSolverSolveTest1d(info.supportPlanes[0].constraint, velocity);\r\n                        if (!plane0Used) {\r\n                            const plane1Used = this._simplexSolverSolveTest1d(info.supportPlanes[1].constraint, velocity);\r\n                            if (!plane1Used) {\r\n                                velocityOut.copyFrom(velocity);\r\n                                info.supportPlanes[0].copyFrom(info.supportPlanes[2]);\r\n                                info.numSupportPlanes = 1;\r\n                                continue;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    //  Try to drop plane 0 or 1\r\n                    {\r\n                        let droppedAPlane = false;\r\n                        for (let testPlane = 0; testPlane < 2; testPlane++) {\r\n                            const velocity = Vector3.Zero();\r\n                            this._simplexSolverSolve2d(\r\n                                info,\r\n                                maxSurfaceVelocity,\r\n                                info.supportPlanes[testPlane].constraint,\r\n                                info.supportPlanes[2].constraint,\r\n                                velocityIn,\r\n                                velocityOut\r\n                            );\r\n                            const planeUsed = this._simplexSolverSolveTest1d(info.supportPlanes[1 - testPlane].constraint, velocity);\r\n                            if (!planeUsed) {\r\n                                info.supportPlanes[0].copyFrom(info.supportPlanes[testPlane]);\r\n                                info.supportPlanes[1].copyFrom(info.supportPlanes[2]);\r\n                                info.numSupportPlanes--;\r\n                                droppedAPlane = true;\r\n                                break;\r\n                            }\r\n                        }\r\n\r\n                        if (droppedAPlane) {\r\n                            continue;\r\n                        }\r\n                    }\r\n\r\n                    // Otherwise, try and solve all three planes:\r\n                    this._simplexSolverSolve3d(\r\n                        info,\r\n                        maxSurfaceVelocity,\r\n                        info.supportPlanes[0].constraint,\r\n                        info.supportPlanes[1].constraint,\r\n                        info.supportPlanes[2].constraint,\r\n                        true,\r\n                        velocityIn,\r\n                        velocityOut\r\n                    );\r\n                    return;\r\n                }\r\n                case 4: {\r\n                    this._simplexSolverSortInfo(info);\r\n                    let droppedAPlane = false;\r\n\r\n                    for (let i = 0; i < 3; i++) {\r\n                        const velocity = Vector3.Zero();\r\n                        this._simplexSolverSolve3d(\r\n                            info,\r\n                            maxSurfaceVelocity,\r\n                            info.supportPlanes[(i + 1) % 3].constraint,\r\n                            info.supportPlanes[(i + 2) % 3].constraint,\r\n                            info.supportPlanes[3].constraint,\r\n                            false,\r\n                            velocityIn,\r\n                            velocity\r\n                        );\r\n                        const planeUsed = this._simplexSolverSolveTest1d(info.supportPlanes[i].constraint, velocity);\r\n                        if (!planeUsed) {\r\n                            info.supportPlanes[i].copyFrom(info.supportPlanes[2]);\r\n                            info.supportPlanes[2].copyFrom(info.supportPlanes[3]);\r\n                            info.numSupportPlanes = 3;\r\n                            droppedAPlane = true;\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (droppedAPlane) {\r\n                        continue;\r\n                    }\r\n\r\n                    // Nothing can be dropped so we've failed to solve\r\n                    // Now we try all 3d combinations\r\n                    {\r\n                        const velocity = velocityIn.clone();\r\n                        const sci0 = info.supportPlanes[0].constraint;\r\n                        const sci1 = info.supportPlanes[1].constraint;\r\n                        const sci2 = info.supportPlanes[2].constraint;\r\n                        const sci3 = info.supportPlanes[3].constraint;\r\n                        const oldNum = info.numSupportPlanes;\r\n                        if (oldNum == info.numSupportPlanes) {\r\n                            this._simplexSolverSolve3d(info, maxSurfaceVelocity, sci0, sci1, sci2, false, velocity, velocity);\r\n                            // eslint-disable-next-line no-dupe-else-if\r\n                        } else if (oldNum == info.numSupportPlanes) {\r\n                            this._simplexSolverSolve3d(info, maxSurfaceVelocity, sci0, sci1, sci3, false, velocity, velocity);\r\n                            // eslint-disable-next-line no-dupe-else-if\r\n                        } else if (oldNum == info.numSupportPlanes) {\r\n                            this._simplexSolverSolve3d(info, maxSurfaceVelocity, sci0, sci2, sci3, false, velocity, velocity);\r\n                            // eslint-disable-next-line no-dupe-else-if\r\n                        } else if (oldNum == info.numSupportPlanes) {\r\n                            this._simplexSolverSolve3d(info, maxSurfaceVelocity, sci1, sci2, sci3, false, velocity, velocity);\r\n                        }\r\n\r\n                        velocityOut.copyFrom(velocity);\r\n                    }\r\n\r\n                    //  Search a plane to drop\r\n                    {\r\n                        //  Search the highest penalty value\r\n                        let maxStatus = SurfaceConstraintInteractionStatus.OK;\r\n                        for (let i = 0; i < 4; i++) {\r\n                            maxStatus = Math.max(maxStatus, info.supportPlanes[i].interaction.status);\r\n                        }\r\n\r\n                        // Remove the place with the lowest priority and the highest penalty\r\n                        let i = 0;\r\n                        for (; i < 4; i++) {\r\n                            if (maxStatus == info.supportPlanes[i].interaction.status) {\r\n                                info.supportPlanes[i].copyFrom(info.supportPlanes[3]);\r\n                                break;\r\n                            }\r\n                            info.numSupportPlanes--;\r\n                        }\r\n                    }\r\n\r\n                    //  Clear penalty flags for the other planes\r\n                    for (let i = 0; i < 3; i++) {\r\n                        info.supportPlanes[i].interaction.status = SurfaceConstraintInteractionStatus.OK;\r\n                    }\r\n\r\n                    continue;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _simplexSolverSolve(\r\n        constraints: ISurfaceConstraintInfo[],\r\n        velocity: Vector3,\r\n        deltaTime: number,\r\n        minDeltaTime: number,\r\n        up: Vector3,\r\n        maxSurfaceVelocity: Vector3\r\n    ): SimplexSolverOutput {\r\n        const eps = 1e-6;\r\n        const output = new SimplexSolverOutput();\r\n        output.position = Vector3.Zero();\r\n        output.velocity = velocity.clone();\r\n        output.planeInteractions = [];\r\n        let remainingTime = deltaTime;\r\n\r\n        for (let i = 0; i < constraints.length; i++) {\r\n            output.planeInteractions.push({\r\n                touched: false,\r\n                stopped: false,\r\n                surfaceTime: 0,\r\n                penaltyDistance: 0,\r\n                status: SurfaceConstraintInteractionStatus.OK,\r\n            });\r\n        }\r\n\r\n        const info = new SimplexSolverInfo();\r\n        info.inputConstraints = constraints;\r\n        info.outputInteractions = output.planeInteractions;\r\n        info.supportPlanes[0] = new SimplexSolverActivePlanes();\r\n        info.supportPlanes[1] = new SimplexSolverActivePlanes();\r\n        info.supportPlanes[2] = new SimplexSolverActivePlanes();\r\n        info.supportPlanes[3] = new SimplexSolverActivePlanes();\r\n\r\n        while (remainingTime > 0) {\r\n            // search for a plane which collides our current direction\r\n            let hitIndex = -1;\r\n            let minCollisionTime = remainingTime;\r\n            for (let i = 0; i < constraints.length; i++) {\r\n                //  Do not search existing active planes\r\n                if (info.numSupportPlanes >= 1 && info.supportPlanes[0].index == i) {\r\n                    continue;\r\n                }\r\n                if (info.numSupportPlanes >= 2 && info.supportPlanes[1].index == i) {\r\n                    continue;\r\n                }\r\n                if (info.numSupportPlanes >= 3 && info.supportPlanes[2].index == i) {\r\n                    continue;\r\n                }\r\n                if (output.planeInteractions[i].status != SurfaceConstraintInteractionStatus.OK) {\r\n                    continue;\r\n                }\r\n\r\n                // Try to find the plane with the shortest time to move\r\n                const sci = constraints[i];\r\n                const relativeVel = this._tmpVecs[25];\r\n                output.velocity.subtractToRef(sci.velocity, relativeVel);\r\n                const relativeProjectedVel = -relativeVel.dot(sci.planeNormal);\r\n                // if projected velocity is pointing away skip it\r\n                if (relativeProjectedVel <= 0) {\r\n                    continue;\r\n                }\r\n\r\n                //  Calculate the time of impact\r\n                const relativePos = this._tmpVecs[26];\r\n                sci.velocity.scaleToRef(info.currentTime, this._tmpVecs[27]);\r\n                output.position.subtractToRef(this._tmpVecs[27], relativePos);\r\n                let projectedPos = sci.planeNormal.dot(relativePos);\r\n\r\n                // treat penetrations\r\n                const penaltyDist = output.planeInteractions[i].penaltyDistance;\r\n                if (penaltyDist < eps) {\r\n                    projectedPos = 0;\r\n                }\r\n                projectedPos += penaltyDist;\r\n\r\n                // check for new hit\r\n                if (projectedPos < minCollisionTime * relativeProjectedVel) {\r\n                    minCollisionTime = projectedPos / relativeProjectedVel;\r\n                    hitIndex = i;\r\n                }\r\n            }\r\n\r\n            //  integrate: Walk to our hitPosition we must walk more than 10 microseconds into the future to consider it valid.\r\n            const minAcceptableCollisionTime = 1e-4;\r\n            if (minCollisionTime > minAcceptableCollisionTime) {\r\n                info.currentTime += minCollisionTime;\r\n                remainingTime -= minCollisionTime;\r\n                output.position.addInPlace(output.velocity.scale(minCollisionTime));\r\n                for (let i = 0; i < info.numSupportPlanes; i++) {\r\n                    info.supportPlanes[i].interaction.surfaceTime += minCollisionTime;\r\n                    info.supportPlanes[i].interaction.touched = true;\r\n                }\r\n\r\n                output.deltaTime = info.currentTime;\r\n                if (info.currentTime > minDeltaTime) {\r\n                    return output;\r\n                }\r\n            }\r\n\r\n            //  If we have no hit than we are done\r\n            if (hitIndex < 0) {\r\n                output.deltaTime = deltaTime;\r\n                break;\r\n            }\r\n\r\n            //  Add our hit to our current list of active planes\r\n            const supportPlane = info.supportPlanes[info.numSupportPlanes++];\r\n            supportPlane.constraint = constraints[hitIndex];\r\n            supportPlane.interaction = output.planeInteractions[hitIndex];\r\n            supportPlane.interaction.penaltyDistance = (supportPlane.interaction.penaltyDistance + eps) * 2.0;\r\n            supportPlane.index = hitIndex;\r\n\r\n            // Move our character along the current set of active planes\r\n            this._simplexSolverExamineActivePlanes(info, maxSurfaceVelocity, velocity, output.velocity);\r\n        }\r\n\r\n        return output;\r\n    }\r\n\r\n    /**\r\n     * Compute a CharacterSurfaceInfo from current state and a direction\r\n     * @param deltaTime frame delta time in seconds. When using scene.deltaTime divide by 1000.0\r\n     * @param direction direction to check, usually gravity direction\r\n     * @returns a CharacterSurfaceInfo object\r\n     */\r\n    public checkSupport(deltaTime: number, direction: Vector3): CharacterSurfaceInfo {\r\n        const surfaceInfo = {\r\n            isSurfaceDynamic: false,\r\n            supportedState: CharacterSupportedState.UNSUPPORTED,\r\n            averageSurfaceNormal: Vector3.Zero(),\r\n            averageSurfaceVelocity: Vector3.Zero(),\r\n            averageAngularSurfaceVelocity: Vector3.Zero(),\r\n        };\r\n        this.checkSupportToRef(deltaTime, direction, surfaceInfo);\r\n        return surfaceInfo;\r\n    }\r\n\r\n    /**\r\n     * Compute a CharacterSurfaceInfo from current state and a direction\r\n     * @param deltaTime frame delta time in seconds. When using scene.deltaTime divide by 1000.0\r\n     * @param direction direction to check, usually gravity direction\r\n     * @param surfaceInfo output for surface info\r\n     */\r\n    public checkSupportToRef(deltaTime: number, direction: Vector3, surfaceInfo: CharacterSurfaceInfo): void {\r\n        const eps = 1e-4;\r\n\r\n        this._validateManifold();\r\n        const constraints = this._createConstraintsFromManifold(deltaTime, 0.0);\r\n        const storedVelocities: Vector3[] = [];\r\n        // Remove velocities and friction to make this a query of the static geometry\r\n        for (let i = 0; i < constraints.length; i++) {\r\n            storedVelocities.push(constraints[i].velocity.clone());\r\n            constraints[i].velocity.setAll(0);\r\n        }\r\n\r\n        const maxSurfaceVelocity = this._tmpVecs[3];\r\n        maxSurfaceVelocity.set(this.maxCharacterSpeedForSolver, this.maxCharacterSpeedForSolver, this.maxCharacterSpeedForSolver);\r\n        const output = this._simplexSolverSolve(constraints, direction, deltaTime, deltaTime, this.up, maxSurfaceVelocity);\r\n\r\n        surfaceInfo.averageSurfaceVelocity.setAll(0);\r\n        surfaceInfo.averageAngularSurfaceVelocity.setAll(0);\r\n        surfaceInfo.averageSurfaceNormal.setAll(0);\r\n        surfaceInfo.isSurfaceDynamic = false;\r\n\r\n        // If the constraints did not affect the character movement then it is unsupported and we can finish\r\n        if (output.velocity.equalsWithEpsilon(direction, eps)) {\r\n            surfaceInfo.supportedState = CharacterSupportedState.UNSUPPORTED;\r\n            return;\r\n        }\r\n\r\n        // Check how was the input velocity modified to determine if the character is supported or sliding\r\n        if (output.velocity.lengthSquared() < eps) {\r\n            surfaceInfo.supportedState = CharacterSupportedState.SUPPORTED;\r\n        } else {\r\n            output.velocity.normalize();\r\n            const angleSin = output.velocity.dot(direction);\r\n            const cosSqr = 1 - angleSin * angleSin;\r\n            if (cosSqr < this.maxSlopeCosine * this.maxSlopeCosine) {\r\n                surfaceInfo.supportedState = CharacterSupportedState.SLIDING;\r\n            } else {\r\n                surfaceInfo.supportedState = CharacterSupportedState.SUPPORTED;\r\n            }\r\n        }\r\n\r\n        // Add all supporting constraints to the ground information\r\n        let numTouching = 0;\r\n        for (let i = -0; i < constraints.length; i++) {\r\n            if (output.planeInteractions[i].touched && constraints[i].planeNormal.dot(direction) < -0.08) {\r\n                surfaceInfo.averageSurfaceNormal.addInPlace(constraints[i].planeNormal);\r\n                surfaceInfo.averageSurfaceVelocity.addInPlace(storedVelocities[i]);\r\n                surfaceInfo.averageAngularSurfaceVelocity.addInPlace(constraints[i].angularVelocity);\r\n                numTouching++;\r\n            }\r\n        }\r\n\r\n        if (numTouching > 0) {\r\n            surfaceInfo.averageSurfaceNormal.normalize();\r\n            surfaceInfo.averageSurfaceVelocity.scaleInPlace(1 / numTouching);\r\n            surfaceInfo.averageAngularSurfaceVelocity.scaleInPlace(1 / numTouching);\r\n        }\r\n\r\n        // isSurfaceDynamic update\r\n        if (surfaceInfo.supportedState == CharacterSupportedState.SUPPORTED) {\r\n            for (let i = 0; i < this._manifold.length; i++) {\r\n                const manifold = this._manifold[i];\r\n                const bodyB = manifold.bodyB;\r\n\r\n                if (this._manifold[i].normal.dot(direction) < -0.08 && bodyB.body.getMotionType(0) == PhysicsMotionType.DYNAMIC) {\r\n                    surfaceInfo.isSurfaceDynamic = true;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _castWithCollectors(startPos: Vector3, endPos: Vector3, castCollector: any /*HP_CollectorId*/, startCollector?: any /*HP_CollectorId*/) {\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const hknp = hk._hknp;\r\n\r\n        const startNative = [startPos.x, startPos.y, startPos.z];\r\n        const orientation = [this._orientation.x, this._orientation.y, this._orientation.z, this._orientation.w];\r\n        if (startCollector != null) {\r\n            const query /*: ShapeProximityInput*/ = [\r\n                this._shape._pluginData,\r\n                startNative,\r\n                orientation,\r\n                this.keepDistance + this.keepContactTolerance, // max distance\r\n                false, // should hit triggers\r\n                [this._body._pluginData.hpBodyId[0]],\r\n            ];\r\n            hknp.HP_World_ShapeProximityWithCollector(hk.world, startCollector, query);\r\n        }\r\n\r\n        {\r\n            const query /*: ShapeCastInput*/ = [\r\n                this._shape._pluginData,\r\n                orientation,\r\n                startNative,\r\n                [endPos.x, endPos.y, endPos.z],\r\n                false, // should hit triggers\r\n                [this._body._pluginData.hpBodyId[0]],\r\n            ];\r\n            hknp.HP_World_ShapeCastWithCollector(hk.world, castCollector, query);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rebuild the contact manifold from a proximity query at the given position.\r\n     * Used by step-up to validate a candidate landing without the merging logic of `_updateManifold`,\r\n     * which is not suited to a zero-length cast.\r\n     * @param position position at which to run the proximity query\r\n     */\r\n    protected _refreshManifoldAtPosition(position: Vector3): void {\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const hknp = hk._hknp;\r\n        const bodyMap = (hk as any)._bodies;\r\n\r\n        const startNative = [position.x, position.y, position.z];\r\n        const orientation = [this._orientation.x, this._orientation.y, this._orientation.z, this._orientation.w];\r\n        const query /*: ShapeProximityInput*/ = [\r\n            this._shape._pluginData,\r\n            startNative,\r\n            orientation,\r\n            this.keepDistance + this.keepContactTolerance,\r\n            false,\r\n            [this._body._pluginData.hpBodyId[0]],\r\n        ];\r\n        hknp.HP_World_ShapeProximityWithCollector(hk.world, this._startCollector, query);\r\n\r\n        this._manifold.length = 0;\r\n        const numHits = hknp.HP_QueryCollector_GetNumHits(this._startCollector)[1];\r\n        for (let i = 0; i < numHits; i++) {\r\n            const [distance, , contactWorld] = hknp.HP_QueryCollector_GetShapeProximityResult(this._startCollector, i)[1];\r\n            this._manifold.push({\r\n                position: Vector3.FromArray(contactWorld[3]),\r\n                normal: Vector3.FromArray(contactWorld[4]),\r\n                distance: distance,\r\n                fraction: 0,\r\n                bodyB: bodyMap.get(contactWorld[0][0])!,\r\n                allowedPenetration: Math.min(Math.max(this.keepDistance - distance, 0.0), this.keepDistance),\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Search the simplex solver output for a constraint that blocks horizontal motion:\r\n     * touched by the solver, non-walkable along `up`, and opposing the requested horizontal direction.\r\n     * @param simplexOutput output of `_simplexSolverSolve`\r\n     * @param constraints constraint array passed to the solver\r\n     * @param horizDir normalized horizontal direction of intent\r\n     * @returns the index of the first matching constraint, or -1\r\n     */\r\n    protected _findBlockingConstraintIndex(simplexOutput: SimplexSolverOutput, constraints: ISurfaceConstraintInfo[], horizDir: Vector3): number {\r\n        const oppositionEps = 1e-3;\r\n        const ceilingThreshold = -0.5;\r\n        const maxSlopeCosEps = 0.1;\r\n        const maxSlope = Math.max(this.maxSlopeCosine, maxSlopeCosEps);\r\n        for (let i = 0; i < constraints.length; i++) {\r\n            if (!simplexOutput.planeInteractions[i].touched) {\r\n                continue;\r\n            }\r\n            const n = constraints[i].planeNormal;\r\n            const normalDotUp = n.dot(this.up);\r\n            if (normalDotUp >= maxSlope) {\r\n                continue;\r\n            }\r\n            if (normalDotUp <= ceilingThreshold) {\r\n                continue;\r\n            }\r\n            if (n.dot(horizDir) > -oppositionEps) {\r\n                continue;\r\n            }\r\n            return i;\r\n        }\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Iterate hits in the cast collector to find the closest one.\r\n     * @returns object with fraction, normal, body and index of the closest hit; null if there were no hits\r\n     */\r\n    protected _getClosestCastHit(): { fraction: number; normal: Vector3; body: { body: PhysicsBody; index: number } | null } | null {\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const hknp = hk._hknp;\r\n        const bodyMap = (hk as any)._bodies;\r\n        const numHits = hknp.HP_QueryCollector_GetNumHits(this._castCollector)[1];\r\n        if (numHits <= 0) {\r\n            return null;\r\n        }\r\n        let bestFrac = Number.POSITIVE_INFINITY;\r\n        const bestNormal = TmpVectors.Vector3[0];\r\n        let hasBestNormal = false;\r\n        let bestBody: { body: PhysicsBody; index: number } | null = null;\r\n        for (let i = 0; i < numHits; i++) {\r\n            const [frac, , hitWorld] = hknp.HP_QueryCollector_GetShapeCastResult(this._castCollector, i)[1];\r\n            if (frac < bestFrac) {\r\n                bestFrac = frac;\r\n                Vector3.FromArrayToRef(hitWorld[4], 0, bestNormal);\r\n                hasBestNormal = true;\r\n                bestBody = bodyMap.get(hitWorld[0][0]) ?? null;\r\n            }\r\n        }\r\n        if (!hasBestNormal) {\r\n            return null;\r\n        }\r\n        return { fraction: bestFrac, normal: bestNormal.clone(), body: bestBody };\r\n    }\r\n\r\n    /**\r\n     * Attempt a step-up sweep when the character is blocked by a vertical-ish obstacle.\r\n     * Runs three shape casts (up, forward, down) and, if a valid walkable landing is found,\r\n     * commits a new position, refreshes the manifold and updates `_lastDisplacement`.\r\n     *\r\n     * Caller responsibilities on success:\r\n     * - subtract the returned time from `remainingTime`\r\n     * - skip `_resolveContacts`, the recast block and the position update for the iteration\r\n     *   (the step is a teleport, not a contact-resolution motion)\r\n     *\r\n     * @param remainingTime time budget left in the current `_integrateManifolds` iteration\r\n     * @param inputVelocity character velocity at the start of the integration call\r\n     * @param simplexOutput output of the iteration's simplex solve\r\n     * @param constraints constraint array passed to the solver\r\n     * @returns time consumed by the step on success, -1 on failure (no state mutated)\r\n     */\r\n    protected _tryStepUp(remainingTime: number, inputVelocity: Vector3, simplexOutput: SimplexSolverOutput, constraints: ISurfaceConstraintInfo[]): number {\r\n        const eps = 1e-4;\r\n        const stepHeight = this.maxStepHeight;\r\n        if (stepHeight <= 0 || remainingTime <= 0) {\r\n            return -1;\r\n        }\r\n\r\n        // 1. Intended horizontal displacement (assumes `up` is unit-length)\r\n        const upUnit = this.up;\r\n        const upDotVel = inputVelocity.dot(upUnit);\r\n        const horizVel = this._tmpVecs[28];\r\n        upUnit.scaleToRef(upDotVel, this._tmpVecs[29]);\r\n        inputVelocity.subtractToRef(this._tmpVecs[29], horizVel);\r\n        const horizVelLenSqr = horizVel.lengthSquared();\r\n        if (horizVelLenSqr < eps * eps) {\r\n            return -1;\r\n        }\r\n        const horizVelLen = Math.sqrt(horizVelLenSqr);\r\n        const horizDir = this._tmpVecs[30];\r\n        horizVel.scaleToRef(1 / horizVelLen, horizDir);\r\n        const horizDist = horizVelLen * remainingTime;\r\n        if (horizDist <= eps) {\r\n            return -1;\r\n        }\r\n\r\n        // 2. Solver must have hit a blocking, non-walkable, opposing constraint\r\n        if (this._findBlockingConstraintIndex(simplexOutput, constraints, horizDir) < 0) {\r\n            return -1;\r\n        }\r\n\r\n        // 3. Up-cast: find available head-room up to stepHeight\r\n        const upEnd = this._tmpVecs[31];\r\n        upUnit.scaleToRef(stepHeight, upEnd);\r\n        upEnd.addInPlace(this._position);\r\n        this._castWithCollectors(this._position, upEnd, this._castCollector);\r\n        const upHit = this._getClosestCastHit();\r\n        let stepClear = stepHeight;\r\n        if (upHit != null) {\r\n            if (upHit.body && upHit.body.body.getMotionType(upHit.body.index) === PhysicsMotionType.DYNAMIC) {\r\n                return -1;\r\n            }\r\n            stepClear = Math.max(0, upHit.fraction * stepHeight - this.keepDistance);\r\n        }\r\n        if (stepClear <= eps) {\r\n            return -1;\r\n        }\r\n\r\n        // 4. Forward-cast: sweep from the elevated position by the requested horizontal distance\r\n        const elevated = upUnit.scale(stepClear);\r\n        elevated.addInPlace(this._position);\r\n        const fwdEnd = horizDir.scale(horizDist);\r\n        fwdEnd.addInPlace(elevated);\r\n        this._castWithCollectors(elevated, fwdEnd, this._castCollector);\r\n        let fwdFrac = 1.0;\r\n        const fwdHit = this._getClosestCastHit();\r\n        if (fwdHit != null) {\r\n            if (fwdHit.body && fwdHit.body.body.getMotionType(fwdHit.body.index) === PhysicsMotionType.DYNAMIC) {\r\n                return -1;\r\n            }\r\n            fwdFrac = fwdHit.fraction;\r\n        }\r\n        // Backoff by keepDistance along horizDir\r\n        const fwdFracAdjusted = Math.max(0, Math.min(1, fwdFrac - this.keepDistance / horizDist));\r\n        if (fwdFracAdjusted <= eps) {\r\n            return -1;\r\n        }\r\n        const fwdEndAdjusted = horizDir.scale(horizDist * fwdFracAdjusted);\r\n        fwdEndAdjusted.addInPlace(elevated);\r\n\r\n        // 5. Down-cast: drop from forward position to find walkable landing\r\n        const downDist = stepClear + 2 * this.keepDistance;\r\n        const downEnd = upUnit.scale(-downDist);\r\n        downEnd.addInPlace(fwdEndAdjusted);\r\n        this._castWithCollectors(fwdEndAdjusted, downEnd, this._castCollector);\r\n        const downHit = this._getClosestCastHit();\r\n        if (downHit == null) {\r\n            // No ground found within reach: stepping into the void (e.g., over a fence). Reject.\r\n            return -1;\r\n        }\r\n        if (downHit.body == null) {\r\n            return -1;\r\n        }\r\n        const landingMotion = downHit.body.body.getMotionType(downHit.body.index);\r\n        if (landingMotion === PhysicsMotionType.DYNAMIC) {\r\n            return -1;\r\n        }\r\n        const maxSlopeCosEps = 0.1;\r\n        const landingNormalDotUp = downHit.normal.dot(upUnit);\r\n        if (landingNormalDotUp < Math.max(this.maxSlopeCosine, maxSlopeCosEps)) {\r\n            return -1;\r\n        }\r\n\r\n        // Landing position = downStart - upUnit * (downFrac * downDist - keepDistance)\r\n        const landingDrop = downHit.fraction * downDist - this.keepDistance;\r\n        const landingPos = TmpVectors.Vector3[0];\r\n        upUnit.scaleToRef(-landingDrop, landingPos);\r\n        landingPos.addInPlace(fwdEndAdjusted);\r\n\r\n        // Thin-wall guard: landing must be measurably higher than where we started.\r\n        const landingDelta = TmpVectors.Vector3[1];\r\n        landingPos.subtractToRef(this._position, landingDelta);\r\n        const heightDelta = landingDelta.dot(upUnit);\r\n        if (heightDelta < eps) {\r\n            return -1;\r\n        }\r\n\r\n        // 6. Snapshot manifold, refresh at landing, validate no unacceptable penetration\r\n        const savedManifold = this._stepUpSavedManifold;\r\n        savedManifold.length = this._manifold.length;\r\n        for (let i = 0; i < this._manifold.length; i++) {\r\n            savedManifold[i] = this._manifold[i];\r\n        }\r\n        this._refreshManifoldAtPosition(landingPos);\r\n        const maxSlope = Math.max(this.maxSlopeCosine, maxSlopeCosEps);\r\n        for (let i = 0; i < this._manifold.length; i++) {\r\n            const c = this._manifold[i];\r\n            if (c.normal.dot(upUnit) < maxSlope && c.distance < -this.keepDistance) {\r\n                // Penetrating a non-walkable surface at landing — reject and restore manifold\r\n                this._manifold.length = savedManifold.length;\r\n                for (let j = 0; j < savedManifold.length; j++) {\r\n                    this._manifold[j] = savedManifold[j];\r\n                }\r\n                return -1;\r\n            }\r\n        }\r\n\r\n        // 7. Commit\r\n        const displacement = landingPos.subtract(this._position);\r\n        this._lastDisplacement.copyFrom(displacement);\r\n        this._position.copyFrom(landingPos);\r\n\r\n        return remainingTime * fwdFracAdjusted;\r\n    }\r\n\r\n    protected _resolveContacts(deltaTime: number, gravity: Vector3) {\r\n        const eps = 1e-12;\r\n        //<todo object interactions out\r\n        for (let i = 0; i < this._manifold.length; i++) {\r\n            const contact = this._manifold[i];\r\n            const bodyB = this._manifold[i].bodyB;\r\n\r\n            //<todo test if bodyB is another character with a proxy body\r\n\r\n            // Skip fixed or keyframed bodies as we won't apply impulses to them\r\n            if (bodyB.body.getMotionType(bodyB.index) != PhysicsMotionType.DYNAMIC) {\r\n                continue;\r\n            }\r\n\r\n            // Calculate and apply impulse on contacted body\r\n            {\r\n                //<todo input/output for callbacks\r\n                let inputObjectMassInv: number;\r\n                let inputObjectImpulse: number;\r\n                let outputObjectImpulse = Vector3.Zero();\r\n                const outputImpulsePosition = contact.position;\r\n\r\n                // Calculate relative normal velocity of the contact point in the contacted body\r\n                const pointRelVel = this._tmpVecs[19];\r\n                this._getPointVelocityToRef(bodyB, contact.position, pointRelVel);\r\n                pointRelVel.subtractInPlace(this._velocity);\r\n                const inputProjectedVelocity = pointRelVel.dot(contact.normal);\r\n                const dampFactor = 0.9;\r\n\r\n                // Change velocity\r\n                let deltaVelocity = -inputProjectedVelocity * dampFactor;\r\n\r\n                // Apply an extra impulse if the collision is actually penetrating\r\n                if (contact.distance < 0) {\r\n                    const recoveryTau = 0.4;\r\n                    deltaVelocity += (contact.distance * recoveryTau) / deltaTime;\r\n                }\r\n\r\n                // Apply impulse if required to keep bodies apart\r\n                if (deltaVelocity < 0) {\r\n                    //  Calculate the impulse magnitude\r\n                    const invInertia = this._getInverseInertiaWorld(bodyB);\r\n                    const comWorld = this._tmpVecs[15];\r\n                    this._getComWorldToRef(bodyB, comWorld);\r\n                    const r = this._tmpVecs[16];\r\n                    contact.position.subtractToRef(comWorld, r);\r\n                    const jacAng = this._tmpVecs[17];\r\n                    Vector3.CrossToRef(r, contact.normal, jacAng);\r\n                    const rc = this._tmpVecs[18];\r\n                    Vector3.TransformNormalToRef(jacAng, invInertia, rc);\r\n                    inputObjectMassInv = rc.dot(jacAng) + this._getInvMass(bodyB);\r\n                    inputObjectImpulse = deltaVelocity / inputObjectMassInv;\r\n\r\n                    // Clamp impulse magnitude if required and apply it to the normal direction\r\n                    const maxPushImpulse = -this.characterStrength * deltaTime;\r\n                    if (inputObjectImpulse < maxPushImpulse) {\r\n                        inputObjectImpulse = maxPushImpulse;\r\n                    }\r\n                    outputObjectImpulse = contact.normal.scale(inputObjectImpulse);\r\n                }\r\n\r\n                // Add gravity\r\n                {\r\n                    // Calculate effect of gravity on the velocity of the character in the contact normal direction\r\n                    let relVelN = contact.normal.dot(gravity.scale(deltaTime));\r\n                    // If it is a separating contact subtract the separation velocity\r\n                    if (inputProjectedVelocity < 0) {\r\n                        relVelN -= inputProjectedVelocity;\r\n                    }\r\n                    // If the resulting velocity is negative an impulse is applied to stop the character from falling into\r\n                    // the contacted body\r\n                    if (relVelN < -eps) {\r\n                        outputObjectImpulse.addInPlace(contact.normal.scale(this.characterMass * relVelN));\r\n                    }\r\n                }\r\n\r\n                //<todo Fire callback to allow user to change impulse + use the info / play sounds\r\n\r\n                const triggerCollisionInfo: ICharacterControllerCollisionEvent = {\r\n                    collider: bodyB.body,\r\n                    colliderIndex: bodyB.index,\r\n                    impulse: outputObjectImpulse,\r\n                    impulsePosition: outputImpulsePosition,\r\n                };\r\n                this.onTriggerCollisionObservable.notifyObservers(triggerCollisionInfo);\r\n\r\n                bodyB.body.applyImpulse(outputObjectImpulse, outputImpulsePosition, bodyB.index);\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _getInverseInertiaWorld(body: { body: PhysicsBody; index: number }): DeepImmutableObject<Matrix> {\r\n        const mp = body.body.getMassProperties(body.index);\r\n        if (!mp.inertia || !mp.inertiaOrientation) {\r\n            return Matrix.IdentityReadOnly;\r\n        }\r\n        const invOrientation = Matrix.FromQuaternionToRef(mp.inertiaOrientation, TmpVectors.Matrix[0]).invert();\r\n        const it = TmpVectors.Matrix[1];\r\n\r\n        const ir = invOrientation.getRowToRef(0, TmpVectors.Vector4[0]);\r\n        it.setRowFromFloats(0, mp.inertia.x * ir.x, mp.inertia.x * ir.y, mp.inertia.x * ir.z, 0);\r\n        invOrientation.getRowToRef(1, ir);\r\n        it.setRowFromFloats(1, mp.inertia.y * ir.x, mp.inertia.y * ir.y, mp.inertia.y * ir.z, 0);\r\n        invOrientation.getRowToRef(2, ir);\r\n        it.setRowFromFloats(2, mp.inertia.z * ir.x, mp.inertia.z * ir.y, mp.inertia.z * ir.z, 0);\r\n        invOrientation.multiplyToRef(it, this._tmpMatrix);\r\n        return this._tmpMatrix;\r\n    }\r\n\r\n    protected _getComWorldToRef(body: { body: PhysicsBody; index: number }, result: Vector3) {\r\n        const mp = body.body.getMassProperties(body.index);\r\n        Vector3.TransformCoordinatesToRef(mp.centerOfMass!, body.body.transformNode.getWorldMatrix(), result);\r\n    }\r\n\r\n    protected _getInvMass(body: { body: PhysicsBody; index: number }): number {\r\n        return 1 / body.body.getMassProperties(body.index).mass!;\r\n    }\r\n\r\n    protected _integrateManifolds(deltaTime: number, gravity: Vector3): void {\r\n        const hk = this._scene.getPhysicsEngine()!.getPhysicsPlugin() as HavokPlugin;\r\n        const epsSqrd = 1e-8;\r\n\r\n        let newVelocity = Vector3.Zero();\r\n        let remainingTime = deltaTime;\r\n        // Snapshot of the input velocity, used to preserve user intent if a step-up succeeds\r\n        // and the loop exits without running another full solver pass.\r\n        const inputVelocity = this._velocity;\r\n        let didStepUp = false;\r\n\r\n        // Make sure that contact with bodies that have been removed since the call to checkSupport() are removed from the\r\n        // manifold\r\n        this._validateManifold();\r\n\r\n        for (let iter = 0; iter < this.maxCastIterations && remainingTime > 1e-5; iter++) {\r\n            this._castWithCollectors(this._position, this._position.add(this._lastDisplacement), this._castCollector, this._startCollector);\r\n            const updateResult = this._updateManifold(this._startCollector, this._castCollector, this._lastDisplacement);\r\n\r\n            // Create surface constraints from the manifold contacts.\r\n            const constraints = this._createConstraintsFromManifold(deltaTime, deltaTime - remainingTime);\r\n            const maxSurfaceVelocity = this._tmpVecs[3];\r\n            maxSurfaceVelocity.set(this.maxCharacterSpeedForSolver, this.maxCharacterSpeedForSolver, this.maxCharacterSpeedForSolver);\r\n            const minDeltaTime = this._velocity.lengthSquared() == 0 ? 0.0 : (0.5 * this.keepDistance) / this._velocity.length();\r\n            const solveResults = this._simplexSolverSolve(constraints, this._velocity, remainingTime, minDeltaTime, this.up, maxSurfaceVelocity);\r\n            const newDisplacement = solveResults.position;\r\n            const solverDeltaTime = solveResults.deltaTime;\r\n            newVelocity = solveResults.velocity;\r\n\r\n            // Attempt step-up at most once per integrate() call when blocked by a vertical-ish obstacle.\r\n            if (!didStepUp && this.maxStepHeight > 0) {\r\n                const timeConsumed = this._tryStepUp(remainingTime, inputVelocity, solveResults, constraints);\r\n                if (timeConsumed >= 0) {\r\n                    remainingTime -= timeConsumed;\r\n                    // Preserve original input velocity so the final `_velocity` reflects user intent\r\n                    // even if the loop exits without another solver pass.\r\n                    newVelocity = inputVelocity;\r\n                    didStepUp = true;\r\n                    // Skip the normal contact resolution / recast / integrate-position block:\r\n                    // step-up is a teleport that already updated position, manifold and lastDisplacement.\r\n                    continue;\r\n                }\r\n            }\r\n\r\n            this._resolveContacts(deltaTime, gravity);\r\n\r\n            let newContactIndex = -1;\r\n            // todo if (updateResult == hit multiple bodies) ... cast again\r\n\r\n            // If castCollector had hits on different bodies (so we're not sure if some non-closest body could be in our way) OR\r\n            // the simplex has given an output direction different from the cast guess\r\n            // we re-cast to check we can move there. There is no need to get the start points again.\r\n            if (updateResult != 0 || (newDisplacement.lengthSquared() > epsSqrd && !this._lastDisplacement.equalsWithEpsilon(newDisplacement, this._displacementEps))) {\r\n                this._castWithCollectors(this._position, this._position.add(newDisplacement), this._castCollector, this._startCollector);\r\n                const hknp = hk._hknp;\r\n                const numCastHits = hknp.HP_QueryCollector_GetNumHits(this._castCollector)[1];\r\n                // Find the first contact that isn't already in the manifold\r\n                if (numCastHits > 0) {\r\n                    //<todo sortHits()\r\n                    for (let i = 0; i < numCastHits; i++) {\r\n                        // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n                        const [fraction, _hitLocal, hitWorld] = hknp.HP_QueryCollector_GetShapeCastResult(this._castCollector, i)[1];\r\n                        const newContact = ContactFromCast(hk, hitWorld, newDisplacement, fraction, this.keepDistance);\r\n                        if (this._findContact(newContact, this._manifold, 0.1) == -1) {\r\n                            //<todo fireContactAdded\r\n                            newContactIndex = this._manifold.length;\r\n                            this._manifold.push(newContact);\r\n                            //<todo updateTriggersSeen()\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (newContactIndex >= 0) {\r\n                const newContact = this._manifold[newContactIndex];\r\n                const displacementLengthInv = 1.0 / newDisplacement.length();\r\n                const angleBetweenMovementAndSurface = newDisplacement.dot(newContact.normal) * displacementLengthInv;\r\n                const keepDistanceAlongMovement = this.keepDistance / -angleBetweenMovementAndSurface;\r\n                const distance = newContact.fraction;\r\n                let fraction = distance - keepDistanceAlongMovement * displacementLengthInv;\r\n                fraction = Math.min(Math.max(fraction, 0.0), 1.0);\r\n\r\n                const displacement = newDisplacement.scale(fraction);\r\n                this._position.addInPlace(displacement);\r\n                remainingTime -= solverDeltaTime * fraction;\r\n            } else {\r\n                this._position.addInPlace(newDisplacement);\r\n                remainingTime -= solverDeltaTime;\r\n            }\r\n            this._lastDisplacement.copyFrom(newDisplacement);\r\n        }\r\n\r\n        this._velocity.copyFrom(newVelocity);\r\n        this._transformNode.position.copyFrom(this._position);\r\n    }\r\n\r\n    /**\r\n     * Move the character with collisions\r\n     * @param displacement defines the requested displacement vector\r\n     */\r\n    public moveWithCollisions(displacement: Vector3): void {\r\n        if (this._scene.deltaTime == undefined) {\r\n            return;\r\n        }\r\n        const deltaTime = this._scene.deltaTime / 1000.0;\r\n        const invDeltaTime = 1 / deltaTime;\r\n\r\n        displacement.scaleToRef(1 / deltaTime, this._velocity);\r\n        this._lastDisplacement.copyFrom(displacement);\r\n\r\n        this._lastVelocity.copyFrom(this._velocity);\r\n        this._lastInvDeltaTime = invDeltaTime;\r\n\r\n        this._integrateManifolds(deltaTime, Vector3.ZeroReadOnly);\r\n    }\r\n\r\n    /**\r\n     * Update internal state. Must be called once per frame\r\n     * @param deltaTime frame delta time in seconds. When using scene.deltaTime divide by 1000.0\r\n     * @param surfaceInfo surface information returned by checkSupport\r\n     * @param gravity gravity applied to the character. Can be different that world gravity\r\n     */\r\n    public integrate(deltaTime: number, surfaceInfo: CharacterSurfaceInfo, gravity: Vector3) {\r\n        const invDeltaTime = 1 / deltaTime;\r\n        const remainingTime = deltaTime;\r\n\r\n        // Choose the first cast direction.  If velocity hasn't changed from the previous integrate, guess that the\r\n        // displacement will be the same as last integrate, scaled by relative step length.  Otherwise, guess based\r\n        // on current velocity.\r\n        {\r\n            const tolerance = this._displacementEps * invDeltaTime;\r\n            if (this._velocity.equalsWithEpsilon(this._lastVelocity, tolerance)) {\r\n                this._lastDisplacement.scaleInPlace(remainingTime * this._lastInvDeltaTime);\r\n            } else {\r\n                const displacementVelocity = this._velocity;\r\n                if (surfaceInfo.supportedState == CharacterSupportedState.SUPPORTED) {\r\n                    const relativeVelocity = this._tmpVecs[28];\r\n                    this._velocity.subtractToRef(surfaceInfo.averageSurfaceVelocity, relativeVelocity);\r\n                    const normalDotVelocity = surfaceInfo.averageSurfaceNormal.dot(relativeVelocity);\r\n                    if (normalDotVelocity < 0) {\r\n                        relativeVelocity.subtractInPlace(surfaceInfo.averageSurfaceNormal.scale(normalDotVelocity));\r\n                        displacementVelocity.copyFrom(relativeVelocity);\r\n                        displacementVelocity.addInPlace(surfaceInfo.averageSurfaceVelocity);\r\n                    }\r\n                }\r\n                this._lastDisplacement.copyFrom(displacementVelocity);\r\n                this._lastDisplacement.scaleInPlace(remainingTime);\r\n            }\r\n            this._lastVelocity.copyFrom(this._velocity);\r\n            this._lastInvDeltaTime = invDeltaTime;\r\n        }\r\n\r\n        this._integrateManifolds(deltaTime, gravity);\r\n    }\r\n\r\n    /**\r\n     * Helper function to calculate velocity based on surface informations and current velocity state and target\r\n     * @param deltaTime frame delta time in seconds. When using scene.deltaTime divide by 1000.0\r\n     * @param forwardWorld character forward in world coordinates\r\n     * @param surfaceNormal surface normal direction\r\n     * @param currentVelocity current velocity\r\n     * @param surfaceVelocity velocity induced by the surface\r\n     * @param desiredVelocity desired character velocity\r\n     * @param upWorld up vector in world space\r\n     * @param result resulting velocity vector\r\n     * @returns boolean true if result has been computed\r\n     */\r\n    public calculateMovementToRef(\r\n        deltaTime: number,\r\n        forwardWorld: Vector3,\r\n        surfaceNormal: Vector3,\r\n        currentVelocity: Vector3,\r\n        surfaceVelocity: Vector3,\r\n        desiredVelocity: Vector3,\r\n        upWorld: Vector3,\r\n        result: Vector3\r\n    ): boolean {\r\n        const eps = 1e-5;\r\n        let binorm = forwardWorld.cross(upWorld);\r\n        if (binorm.lengthSquared() < eps) {\r\n            return false;\r\n        }\r\n        binorm.normalize();\r\n        const tangent = binorm.cross(surfaceNormal);\r\n        tangent.normalize();\r\n        binorm = tangent.cross(surfaceNormal);\r\n        binorm.normalize();\r\n\r\n        const surfaceFrame = Matrix.FromValues(\r\n            tangent.x,\r\n            tangent.y,\r\n            tangent.z,\r\n            0,\r\n            binorm.x,\r\n            binorm.y,\r\n            binorm.z,\r\n            0,\r\n            surfaceNormal.x,\r\n            surfaceNormal.y,\r\n            surfaceNormal.z,\r\n            0,\r\n            0,\r\n            0,\r\n            0,\r\n            1\r\n        );\r\n        const invSurfaceFrame = surfaceFrame.clone().invert();\r\n\r\n        currentVelocity.subtractToRef(surfaceVelocity, this._tmpVecs[29]);\r\n        const relative = this._tmpVecs[30];\r\n        Vector3.TransformNormalToRef(this._tmpVecs[29], invSurfaceFrame, relative);\r\n\r\n        const sideVec = upWorld.cross(forwardWorld);\r\n        const fwd = desiredVelocity.dot(forwardWorld);\r\n        const side = desiredVelocity.dot(sideVec);\r\n        const len = desiredVelocity.length();\r\n\r\n        const desiredVelocitySF = this._tmpVecs[4];\r\n        desiredVelocitySF.set(-fwd, side, 0);\r\n        desiredVelocitySF.normalize();\r\n        desiredVelocitySF.scaleInPlace(len);\r\n        const diff = this._tmpVecs[5];\r\n        desiredVelocitySF.subtractToRef(relative, diff);\r\n\r\n        // Clamp it by maxAcceleration and limit it by gain.\r\n        {\r\n            const lenSq = diff.lengthSquared();\r\n            const maxVelocityDelta = this.maxAcceleration * deltaTime;\r\n            let tmp: number;\r\n            if (lenSq * this.acceleration * this.acceleration > maxVelocityDelta * maxVelocityDelta) {\r\n                tmp = maxVelocityDelta / Math.sqrt(lenSq);\r\n            } else {\r\n                tmp = this.acceleration;\r\n            }\r\n            diff.scaleInPlace(tmp);\r\n        }\r\n\r\n        relative.addInPlace(diff);\r\n\r\n        // Transform back to world space and apply\r\n        Vector3.TransformNormalToRef(relative, surfaceFrame, result);\r\n\r\n        // Add back in the surface velocity\r\n        result.addInPlace(surfaceVelocity);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Helper function to calculate velocity based on surface informations and current velocity state and target\r\n     * @param deltaTime frame delta time in seconds. When using scene.deltaTime divide by 1000.0\r\n     * @param forwardWorld character forward in world coordinates\r\n     * @param surfaceNormal surface normal direction\r\n     * @param currentVelocity current velocity\r\n     * @param surfaceVelocity velocity induced by the surface\r\n     * @param desiredVelocity desired character velocity\r\n     * @param upWorld up vector in world space\r\n     * @returns a new velocity vector\r\n     */\r\n    public calculateMovement(\r\n        deltaTime: number,\r\n        forwardWorld: Vector3,\r\n        surfaceNormal: Vector3,\r\n        currentVelocity: Vector3,\r\n        surfaceVelocity: Vector3,\r\n        desiredVelocity: Vector3,\r\n        upWorld: Vector3\r\n    ): Vector3 {\r\n        const result = new Vector3(0, 0, 0);\r\n        this.calculateMovementToRef(deltaTime, forwardWorld, surfaceNormal, currentVelocity, surfaceVelocity, desiredVelocity, upWorld, result);\r\n        return result;\r\n    }\r\n}\r\n","import { type Skeleton } from \"../../Bones/skeleton\";\r\nimport { Vector3, Matrix, TmpVectors, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { PhysicsAggregate } from \"./physicsAggregate\";\r\nimport { PhysicsConstraint } from \"./physicsConstraint\";\r\nimport { type Mesh } from \"../../Meshes/mesh\";\r\nimport { Axis, Space } from \"../../Maths/math.axis\";\r\nimport { PhysicsShapeType, PhysicsConstraintType, PhysicsMotionType } from \"./IPhysicsEnginePlugin\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Bone } from \"../../Bones/bone\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\n\r\n/**\r\n * Ragdoll bone properties\r\n * @experimental\r\n */\r\nexport class RagdollBoneProperties {\r\n    /**\r\n     * Width of the box shape\r\n     */\r\n    width?: number;\r\n    /**\r\n     * depth of the box shape\r\n     */\r\n    depth?: number;\r\n    /**\r\n     * height of the box shape\r\n     */\r\n    height?: number;\r\n    /**\r\n     * size that will be used of width, depth and height of the shape box\r\n     */\r\n    size?: number;\r\n    /**\r\n     * Type of Physics Constraint used between bones\r\n     */\r\n    joint?: number | undefined | PhysicsConstraintType;\r\n    /**\r\n     * Main rotation axis used by the constraint, in local space\r\n     */\r\n    rotationAxis?: Vector3;\r\n    /**\r\n     * Minimum rotation angle value\r\n     */\r\n    min?: number;\r\n    /**\r\n     * Maximum rotation angle value\r\n     */\r\n    max?: number;\r\n    /**\r\n     * Offset along local axis\r\n     */\r\n    boxOffset?: number;\r\n    /**\r\n     * Axis that need an offset\r\n     */\r\n    boneOffsetAxis?: Vector3;\r\n}\r\n\r\n/**\r\n * Ragdoll for Physics V2\r\n * @experimental\r\n */\r\nexport class Ragdoll {\r\n    private _skeleton: Skeleton;\r\n    private _scene: Scene;\r\n    private _rootTransformNode: Mesh | TransformNode;\r\n    private _config: any;\r\n    private _boxConfigs: Array<RagdollBoneProperties> = new Array<RagdollBoneProperties>();\r\n    private _constraints: Array<PhysicsConstraint> = new Array<PhysicsConstraint>();\r\n    private _bones: Array<Bone> = new Array<Bone>();\r\n    private _initialRotation: Array<Quaternion> = new Array<Quaternion>();\r\n    // without mesh transform, to figure out later\r\n    private _initialRotation2: Array<Quaternion> = new Array<Quaternion>();\r\n    private _boneNames: string[] = [];\r\n    private _transforms: Array<TransformNode> = new Array<TransformNode>();\r\n    private _aggregates: Array<PhysicsAggregate> = new Array<PhysicsAggregate>();\r\n    private _ragdollMode: boolean = false;\r\n    private _rootBoneName: string = \"\";\r\n    private _rootBoneIndex: number = -1;\r\n    private _mass: number = 10;\r\n    private _restitution: number = 0;\r\n    private _beforeRenderObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    /**\r\n     * Pause synchronization between physics and bone position/orientation\r\n     */\r\n    public pauseSync: boolean = false;\r\n\r\n    private _putBoxesInBoneCenter: boolean;\r\n    private _defaultJoint: number = PhysicsConstraintType.HINGE;\r\n    private _defaultJointMin: number = -90;\r\n    private _defaultJointMax: number = 90;\r\n\r\n    /**\r\n     * Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method\r\n     * @param skeleton The skeleton containing bones to be physicalized\r\n     * @param rootTransformNode The mesh or its transform used by the skeleton\r\n     * @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies\r\n     */\r\n    constructor(skeleton: Skeleton, rootTransformNode: Mesh | TransformNode, config: RagdollBoneProperties[]) {\r\n        this._skeleton = skeleton;\r\n        this._scene = skeleton.getScene();\r\n        this._rootTransformNode = rootTransformNode;\r\n        this._config = config; // initial, user defined box configs. May have several box configs jammed into 1 index.\r\n        this._boxConfigs = []; // final box configs. Every element is a separate box config (this.config may have several configs jammed into 1 index).\r\n        this._putBoxesInBoneCenter = false;\r\n        this._defaultJoint = PhysicsConstraintType.HINGE;\r\n\r\n        this._init();\r\n    }\r\n\r\n    /**\r\n     * returns an array of created constraints\r\n     * @returns array of created constraints\r\n     */\r\n    public getConstraints(): Array<PhysicsConstraint> {\r\n        return this._constraints;\r\n    }\r\n\r\n    /**\r\n     * Returns the aggregate corresponding to the ragdoll bone index\r\n     * @param index ragdoll bone aggregate index\r\n     * @returns the aggregate for the bone index for the root aggregate if index is invalid\r\n     */\r\n    public getAggregate(index: number): PhysicsAggregate {\r\n        if (index < 0 || index >= this._aggregates.length) {\r\n            return this._aggregates[this._rootBoneIndex];\r\n        }\r\n        return this._aggregates[index];\r\n    }\r\n\r\n    private _createColliders(): void {\r\n        this._rootTransformNode.computeWorldMatrix();\r\n        this._skeleton.computeAbsoluteMatrices(true);\r\n        this._skeleton.prepare(true);\r\n\r\n        const config = this._config;\r\n        for (let i = 0; i < config.length; i++) {\r\n            const boneNames = config[i].bone !== undefined ? [config[i].bone] : config[i].bones;\r\n\r\n            for (let ii = 0; ii < boneNames.length; ii++) {\r\n                const currentBone = this._skeleton.bones[this._skeleton.getBoneIndexByName(boneNames[ii])];\r\n                if (currentBone == undefined) {\r\n                    return;\r\n                }\r\n\r\n                // First define the box dimensions, so we can then use them when calling CreateBox().\r\n                const currentRagdollBoneProperties: RagdollBoneProperties = {\r\n                    width: this._config[i].width,\r\n                    depth: this._config[i].depth,\r\n                    height: this._config[i].height,\r\n                    size: this._config[i].size,\r\n                };\r\n\r\n                currentRagdollBoneProperties.width = currentRagdollBoneProperties.width ?? currentRagdollBoneProperties.size;\r\n                currentRagdollBoneProperties.depth = currentRagdollBoneProperties.depth ?? currentRagdollBoneProperties.size;\r\n                currentRagdollBoneProperties.height = currentRagdollBoneProperties.height ?? currentRagdollBoneProperties.size;\r\n                const transform = new TransformNode(boneNames[ii] + \"_transform\", this._scene);\r\n\r\n                // Define the rest of the box properties.\r\n                currentRagdollBoneProperties.joint = config[i].joint !== undefined ? config[i].joint : this._defaultJoint;\r\n                currentRagdollBoneProperties.rotationAxis = config[i].rotationAxis !== undefined ? config[i].rotationAxis : Axis.X;\r\n                currentRagdollBoneProperties.min = config[i].min !== undefined ? config[i].min : this._defaultJointMin;\r\n                currentRagdollBoneProperties.max = config[i].max !== undefined ? config[i].max : this._defaultJointMax;\r\n\r\n                // Offset value.\r\n                let boxOffset = 0;\r\n                if ((config[i].putBoxInBoneCenter !== undefined && config[i].putBoxInBoneCenter) || this._putBoxesInBoneCenter) {\r\n                    if (currentBone.length === undefined) {\r\n                        Logger.Log(\"The length property is not defined for bone \" + currentBone.name);\r\n                    }\r\n                    boxOffset = currentBone.length / 2;\r\n                } else if (config[i].boxOffset !== undefined) {\r\n                    boxOffset = config[i].boxOffset;\r\n                }\r\n                currentRagdollBoneProperties.boxOffset = boxOffset;\r\n\r\n                // Offset axis.\r\n                const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis : Axis.Y;\r\n                const boneDir = currentBone.getDirection(boneOffsetAxis, this._rootTransformNode);\r\n                currentRagdollBoneProperties.boneOffsetAxis = boneOffsetAxis;\r\n\r\n                transform.position = currentBone.getAbsolutePosition(this._rootTransformNode).add(boneDir.scale(boxOffset));\r\n\r\n                const mass = config[i].mass !== undefined ? config[i].mass : this._mass;\r\n                const restitution = config[i].restitution !== undefined ? config[i].restitution : this._restitution;\r\n                const aggregate = new PhysicsAggregate(\r\n                    transform,\r\n                    PhysicsShapeType.BOX,\r\n                    {\r\n                        mass: mass,\r\n                        restitution: restitution,\r\n                        friction: 0.6,\r\n                        extents: new Vector3(currentRagdollBoneProperties.width, currentRagdollBoneProperties.height, currentRagdollBoneProperties.depth),\r\n                    },\r\n                    this._scene\r\n                );\r\n                aggregate.body.setCollisionCallbackEnabled(true);\r\n                aggregate.body.disablePreStep = false;\r\n                aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);\r\n                this._aggregates.push(aggregate);\r\n                this._bones.push(currentBone);\r\n                this._boneNames.push(currentBone.name);\r\n                this._transforms.push(transform);\r\n                this._boxConfigs.push(currentRagdollBoneProperties);\r\n                this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD, this._rootTransformNode));\r\n                this._initialRotation2.push(currentBone.getRotationQuaternion(Space.WORLD));\r\n            }\r\n        }\r\n    }\r\n\r\n    private _initJoints(): void {\r\n        this._rootTransformNode.computeWorldMatrix();\r\n        for (let i = 0; i < this._bones.length; i++) {\r\n            // The root bone has no joints.\r\n            if (i == this._rootBoneIndex) {\r\n                continue;\r\n            }\r\n\r\n            const nearestParent = this._findNearestParent(i);\r\n\r\n            if (nearestParent == null) {\r\n                Logger.Warn(\"Couldn't find a nearest parent bone in the configs for bone called \" + this._boneNames[i]);\r\n                return;\r\n            }\r\n\r\n            const boneParentIndex = this._boneNames.indexOf(nearestParent.name);\r\n\r\n            const wmat = this._transforms[boneParentIndex].computeWorldMatrix();\r\n            const invertedWorldMat = Matrix.Invert(wmat);\r\n            const boneAbsPos = this._bones[i].getAbsolutePosition(this._rootTransformNode);\r\n            const distanceFromParentBoxToBone = Vector3.TransformCoordinates(boneAbsPos, invertedWorldMat);\r\n            const boxAbsPos = this._transforms[i].position.clone();\r\n            const myConnectedPivot = boneAbsPos.subtract(boxAbsPos);\r\n\r\n            const constraintType = this._boxConfigs[i].joint ?? this._defaultJoint;\r\n            const constraint = new PhysicsConstraint(\r\n                constraintType,\r\n                {\r\n                    pivotA: distanceFromParentBoxToBone,\r\n                    pivotB: myConnectedPivot,\r\n                    axisA: this._boxConfigs[i].rotationAxis!,\r\n                    axisB: this._boxConfigs[i].rotationAxis!,\r\n                    collision: false,\r\n                },\r\n                this._scene\r\n            );\r\n\r\n            this._aggregates[boneParentIndex].body.addConstraint(this._aggregates[i].body, constraint);\r\n            constraint.isEnabled = false;\r\n            this._constraints.push(constraint);\r\n        }\r\n    }\r\n\r\n    // set physics body orientation/position from bones\r\n    private _syncBonesToPhysics(): void {\r\n        const rootMatrix = this._rootTransformNode.getWorldMatrix();\r\n        for (let i = 0; i < this._bones.length; i++) {\r\n            // position\r\n            const transform = this._aggregates[i].transformNode;\r\n            const rootPos = this._bones[i].getAbsolutePosition();\r\n            Vector3.TransformCoordinatesToRef(rootPos, rootMatrix, transform.position);\r\n\r\n            // added offset\r\n            this._bones[i].getDirectionToRef(this._boxConfigs[i].boneOffsetAxis!, this._rootTransformNode, TmpVectors.Vector3[0]);\r\n            TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[i].boxOffset ?? 0);\r\n            transform.position.addInPlace(TmpVectors.Vector3[0]);\r\n\r\n            this._setBoneOrientationToBody(i);\r\n        }\r\n    }\r\n\r\n    private _setBoneOrientationToBody(boneIndex: number): void {\r\n        const transform = this._aggregates[boneIndex].transformNode;\r\n        const bone = this._bones[boneIndex];\r\n        this._initialRotation[boneIndex].conjugateToRef(TmpVectors.Quaternion[0]);\r\n        bone.getRotationQuaternionToRef(Space.WORLD, this._rootTransformNode, TmpVectors.Quaternion[1]);\r\n        TmpVectors.Quaternion[1].multiplyToRef(TmpVectors.Quaternion[0], transform.rotationQuaternion!);\r\n        transform.rotationQuaternion!.normalize();\r\n    }\r\n\r\n    private _syncBonesAndBoxes(): void {\r\n        if (this.pauseSync) {\r\n            return;\r\n        }\r\n\r\n        if (this._ragdollMode) {\r\n            this._setBodyOrientationToBone(this._rootBoneIndex);\r\n\r\n            const rootPos = this._aggregates[this._rootBoneIndex].body.transformNode.position;\r\n            this._rootTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n\r\n            Vector3.TransformCoordinatesToRef(rootPos, TmpVectors.Matrix[0], TmpVectors.Vector3[0]);\r\n            this._bones[this._rootBoneIndex].setAbsolutePosition(TmpVectors.Vector3[0]);\r\n\r\n            for (let i = 0; i < this._bones.length; i++) {\r\n                if (i == this._rootBoneIndex) {\r\n                    continue;\r\n                }\r\n                this._setBodyOrientationToBone(i);\r\n            }\r\n        } else {\r\n            this._syncBonesToPhysics();\r\n        }\r\n    }\r\n\r\n    private _setBodyOrientationToBone(boneIndex: number): void {\r\n        const qmesh =\r\n            this._rootTransformNode.rotationQuaternion ??\r\n            Quaternion.FromEulerAngles(this._rootTransformNode.rotation.x, this._rootTransformNode.rotation.y, this._rootTransformNode.rotation.z);\r\n        const qbind = this._initialRotation2[boneIndex];\r\n        const qphys = this._aggregates[boneIndex].body?.transformNode?.rotationQuaternion;\r\n\r\n        qmesh.multiplyToRef(qbind, TmpVectors.Quaternion[1]);\r\n        qphys?.multiplyToRef(TmpVectors.Quaternion[1], TmpVectors.Quaternion[0]);\r\n\r\n        this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this._rootTransformNode);\r\n    }\r\n\r\n    // Return true if root bone is valid/exists in this.bonesNames. false otherwise.\r\n    private _defineRootBone(): boolean {\r\n        const skeletonRoots = this._skeleton.getChildren();\r\n        if (skeletonRoots.length != 1) {\r\n            Logger.Log(\"Ragdoll creation failed: there can only be one root in the skeleton.\");\r\n            return false;\r\n        }\r\n\r\n        this._rootBoneName = skeletonRoots[0].name;\r\n        this._rootBoneIndex = this._boneNames.indexOf(this._rootBoneName);\r\n        if (this._rootBoneIndex == -1) {\r\n            // eslint-disable-next-line @typescript-eslint/restrict-plus-operands, @typescript-eslint/no-base-to-string\r\n            Logger.Log(\"Ragdoll creation failed: the array boneNames doesn't have the root bone. The root bone is \" + this._skeleton.getChildren());\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _findNearestParent(boneIndex: number): any {\r\n        let nearestParent: Nullable<Bone> | undefined = this._bones[boneIndex].getParent();\r\n        do {\r\n            if (nearestParent != null && this._boneNames.includes(nearestParent.name)) {\r\n                break;\r\n            }\r\n\r\n            nearestParent = nearestParent?.getParent();\r\n        } while (nearestParent != null);\r\n\r\n        return nearestParent;\r\n    }\r\n\r\n    private _init() {\r\n        this._createColliders();\r\n\r\n        // If this.defineRootBone() returns ... there is not root bone.\r\n        if (!this._defineRootBone()) {\r\n            return;\r\n        }\r\n\r\n        this._initJoints();\r\n        this._beforeRenderObserver = this._scene.onBeforeRenderObservable.add(() => {\r\n            this._syncBonesAndBoxes();\r\n        });\r\n        this._syncBonesToPhysics();\r\n    }\r\n\r\n    /**\r\n     * Enable ragdoll mode. Create physics objects and make them dynamic.\r\n     */\r\n    public ragdoll(): void {\r\n        this._ragdollMode = true;\r\n        // detach bones with link transform to let physics have control\r\n        for (const bone of this._skeleton.bones) {\r\n            bone.linkTransformNode(null);\r\n        }\r\n        for (let i = 0; i < this._constraints.length; i++) {\r\n            this._constraints[i].isEnabled = true;\r\n        }\r\n        for (let i = 0; i < this._aggregates.length; i++) {\r\n            this._aggregates[i].body.setMotionType(PhysicsMotionType.DYNAMIC);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose resources and remove physics objects\r\n     */\r\n    dispose(): void {\r\n        for (const aggregate of this._aggregates) {\r\n            aggregate.dispose();\r\n        }\r\n        this._aggregates.length = 0;\r\n        for (const transform of this._transforms) {\r\n            transform.dispose();\r\n        }\r\n        this._transforms.length = 0;\r\n        for (const constraint of this._constraints) {\r\n            constraint.dispose();\r\n        }\r\n        this._constraints.length = 0;\r\n\r\n        if (this._beforeRenderObserver) {\r\n            this._scene.onBeforeRenderObservable.remove(this._beforeRenderObserver);\r\n            this._beforeRenderObserver = null;\r\n        }\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Matrix, Quaternion, TmpVectors, Vector3 } from \"../../../Maths/math.vector.pure\";\r\nimport {\r\n    PhysicsShapeType,\r\n    PhysicsConstraintType,\r\n    PhysicsMotionType,\r\n    PhysicsConstraintMotorType,\r\n    PhysicsConstraintAxis,\r\n    PhysicsConstraintAxisLimitMode,\r\n    PhysicsEventType,\r\n    PhysicsPrestepType,\r\n    PhysicsActivationControl,\r\n    type PhysicsShapeParameters,\r\n    type IPhysicsEnginePluginV2,\r\n    type PhysicsMassProperties,\r\n    type IPhysicsCollisionEvent,\r\n    type IBasePhysicsCollisionEvent,\r\n    type ConstrainedBodyPair,\r\n} from \"../IPhysicsEnginePlugin\";\r\nimport { type IRaycastQuery, PhysicsRaycastResult } from \"../../physicsRaycastResult\";\r\nimport { Logger } from \"../../../Misc/logger\";\r\nimport { type PhysicsBody } from \"../physicsBody\";\r\nimport { type PhysicsConstraint, type Physics6DoFConstraint } from \"../physicsConstraint\";\r\nimport { type PhysicsMaterial, PhysicsMaterialCombineMode } from \"../physicsMaterial\";\r\nimport { PhysicsShape } from \"../physicsShape\";\r\nimport { BoundingBox } from \"../../../Culling/boundingBox\";\r\nimport { type TransformNode } from \"../../../Meshes/transformNode\";\r\nimport { Mesh } from \"../../../Meshes/mesh.pure\";\r\nimport { InstancedMesh } from \"../../../Meshes/instancedMesh.pure\";\r\nimport { type Scene } from \"../../../scene\";\r\nimport { VertexBuffer } from \"../../../Buffers/buffer.pure\";\r\nimport { BuildArray } from \"../../../Misc/arrayTools\";\r\nimport { Observable } from \"../../../Misc/observable\";\r\nimport { type Nullable, type FloatArray } from \"../../../types\";\r\nimport { type IPhysicsPointProximityQuery } from \"../../physicsPointProximityQuery\";\r\nimport { type ProximityCastResult } from \"../../proximityCastResult\";\r\nimport { type IPhysicsShapeProximityCastQuery } from \"../../physicsShapeProximityCastQuery\";\r\nimport { type IPhysicsShapeCastQuery } from \"../../physicsShapeCastQuery\";\r\nimport { type ShapeCastResult } from \"../../shapeCastResult\";\r\nimport { FloatingOriginCurrentScene } from \"../../../Materials/floatingOriginMatrixOverrides\";\r\ndeclare let HK: any;\r\n\r\n/**\r\n * Helper to keep a reference to plugin memory.\r\n * Used to avoid https://github.com/emscripten-core/emscripten/issues/7294\r\n * @internal\r\n */\r\ninterface PluginMemoryRef {\r\n    /** The offset from the beginning of the plugin's heap */\r\n    offset: number;\r\n    /** The number of identically-sized objects the buffer contains */\r\n    numObjects: number;\r\n}\r\n\r\nclass MeshAccumulator {\r\n    /**\r\n     * Constructor of the mesh accumulator\r\n     * @param mesh - The mesh used to compute the world matrix.\r\n     * @param collectIndices - use mesh indices\r\n     * @param scene - The scene used to determine the right handed system.\r\n     *\r\n     * Merge mesh and its children so whole hierarchy can be used as a mesh shape or convex hull\r\n     */\r\n    public constructor(mesh: Mesh, collectIndices: boolean, scene: Scene) {\r\n        this._isRightHanded = scene.useRightHandedSystem;\r\n        this._collectIndices = collectIndices;\r\n    }\r\n\r\n    /**\r\n     * Adds a mesh to the physics engine.\r\n     * @param mesh The mesh to add.\r\n     * @param includeChildren Whether to include the children of the mesh.\r\n     *\r\n     * This method adds a mesh to the physics engine by computing the world matrix,\r\n     * multiplying it with the body from world matrix, and then transforming the\r\n     * coordinates of the mesh's vertices. It also adds the indices of the mesh\r\n     * to the physics engine. If includeChildren is true, it will also add the\r\n     * children of the mesh to the physics engine, ignoring any children which\r\n     * have a physics impostor. This is useful for creating a physics engine\r\n     * that accurately reflects the mesh and its children.\r\n     */\r\n    public addNodeMeshes(mesh: TransformNode, includeChildren: boolean): void {\r\n        // Force absoluteScaling to be computed; we're going to use that to bake\r\n        // the scale of any parent nodes into this shape, as physics engines\r\n        // usually use rigid transforms, so can't handle arbitrary scale.\r\n        mesh.computeWorldMatrix(true);\r\n        const rootScaled = TmpVectors.Matrix[0];\r\n        Matrix.ScalingToRef(mesh.absoluteScaling.x, mesh.absoluteScaling.y, mesh.absoluteScaling.z, rootScaled);\r\n\r\n        if (mesh instanceof Mesh) {\r\n            this._addMesh(mesh, rootScaled);\r\n        } else if (mesh instanceof InstancedMesh) {\r\n            this._addMesh(mesh.sourceMesh, rootScaled);\r\n        }\r\n\r\n        if (includeChildren) {\r\n            const worldToRoot = TmpVectors.Matrix[1];\r\n            mesh.computeWorldMatrix().invertToRef(worldToRoot);\r\n            const worldToRootScaled = TmpVectors.Matrix[2];\r\n            worldToRoot.multiplyToRef(rootScaled, worldToRootScaled);\r\n\r\n            const children = mesh.getChildMeshes(false);\r\n            //  Ignore any children which have a physics body.\r\n            //  Other plugin implementations do not have this check, which appears to be\r\n            //  a bug, as otherwise, the mesh will have a duplicate collider\r\n            const transformNodes = children.filter((m: any) => !m.physicsBody);\r\n\r\n            for (const m of transformNodes) {\r\n                const childToWorld = m.computeWorldMatrix();\r\n                const childToRootScaled = TmpVectors.Matrix[3];\r\n                childToWorld.multiplyToRef(worldToRootScaled, childToRootScaled);\r\n\r\n                if (m instanceof Mesh) {\r\n                    this._addMesh(m, childToRootScaled);\r\n                } else if (m instanceof InstancedMesh) {\r\n                    this._addMesh(m.sourceMesh, childToRootScaled);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _addMesh(mesh: Mesh, meshToRoot: Matrix): void {\r\n        const vertexData = mesh.getVerticesData(VertexBuffer.PositionKind) || [];\r\n        const numVerts = vertexData.length / 3;\r\n        const indexOffset = this._vertices.length;\r\n        for (let v = 0; v < numVerts; v++) {\r\n            const pos = new Vector3(vertexData[v * 3 + 0], vertexData[v * 3 + 1], vertexData[v * 3 + 2]);\r\n            this._vertices.push(Vector3.TransformCoordinates(pos, meshToRoot));\r\n        }\r\n\r\n        if (this._collectIndices) {\r\n            const meshIndices = mesh.getIndices();\r\n            if (meshIndices) {\r\n                for (let i = 0; i < meshIndices.length; i += 3) {\r\n                    // Havok wants the correct triangle winding to enable the interior triangle optimization\r\n                    if (this._isRightHanded) {\r\n                        this._indices.push(meshIndices[i + 0] + indexOffset);\r\n                        this._indices.push(meshIndices[i + 1] + indexOffset);\r\n                        this._indices.push(meshIndices[i + 2] + indexOffset);\r\n                    } else {\r\n                        this._indices.push(meshIndices[i + 2] + indexOffset);\r\n                        this._indices.push(meshIndices[i + 1] + indexOffset);\r\n                        this._indices.push(meshIndices[i + 0] + indexOffset);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Allocate and populate the vertex positions inside the physics plugin.\r\n     *\r\n     * @param plugin - The plugin to allocate the memory in.\r\n     * @returns An array of floats, whose backing memory is inside the plugin. The array contains the\r\n     * positions of the mesh vertices, where a position is defined by three floats. You must call\r\n     * freeBuffer() on the returned array once you have finished with it, in order to free the\r\n     * memory inside the plugin..\r\n     */\r\n    public getVertices(plugin: any): PluginMemoryRef {\r\n        const nFloats = this._vertices.length * 3;\r\n        const bytesPerFloat = 4;\r\n        const nBytes = nFloats * bytesPerFloat;\r\n        const bufferBegin = plugin._malloc(nBytes);\r\n\r\n        const ret = new Float32Array(plugin.HEAPU8.buffer, bufferBegin, nFloats);\r\n        for (let i = 0; i < this._vertices.length; i++) {\r\n            ret[i * 3 + 0] = this._vertices[i].x;\r\n            ret[i * 3 + 1] = this._vertices[i].y;\r\n            ret[i * 3 + 2] = this._vertices[i].z;\r\n        }\r\n\r\n        return { offset: bufferBegin, numObjects: nFloats };\r\n    }\r\n\r\n    /**\r\n     * Releases a buffer allocated in the physics plugin.\r\n     * @param plugin - The plugin that owns the allocation.\r\n     * @param arr - The plugin memory reference to release.\r\n     */\r\n    public freeBuffer(plugin: any, arr: PluginMemoryRef): void {\r\n        plugin._free(arr.offset);\r\n    }\r\n\r\n    /**\r\n     * Allocate and populate the triangle indices inside the physics plugin\r\n     *\r\n     * @param plugin - The plugin to allocate the memory in.\r\n     * @returns A new Int32Array, whose backing memory is inside the plugin. The array contains the indices\r\n     * of the triangle positions, where a single triangle is defined by three indices. You must call\r\n     * freeBuffer() on this array once you have finished with it, to free the memory inside the plugin..\r\n     */\r\n    public getTriangles(plugin: any): PluginMemoryRef {\r\n        const bytesPerInt = 4;\r\n        const nBytes = this._indices.length * bytesPerInt;\r\n        const bufferBegin = plugin._malloc(nBytes);\r\n        const ret = new Int32Array(plugin.HEAPU8.buffer, bufferBegin, this._indices.length);\r\n        for (let i = 0; i < this._indices.length; i++) {\r\n            ret[i] = this._indices[i];\r\n        }\r\n\r\n        return { offset: bufferBegin, numObjects: this._indices.length };\r\n    }\r\n\r\n    private _isRightHanded: boolean;\r\n    private _collectIndices: boolean;\r\n    private _vertices: Vector3[] = []; /// Vertices in body space\r\n    private _indices: number[] = [];\r\n}\r\n\r\nclass BodyPluginData {\r\n    public constructor(bodyId: any) {\r\n        this.hpBodyId = bodyId;\r\n        this.userMassProps = { centerOfMass: undefined, mass: undefined, inertia: undefined, inertiaOrientation: undefined };\r\n    }\r\n\r\n    /**\r\n     * The Havok body identifier associated with this plugin body.\r\n     */\r\n    public hpBodyId: any;\r\n\r\n    /**\r\n     * Offset of the body's world transform in Havok memory.\r\n     */\r\n    public worldTransformOffset: number;\r\n\r\n    /**\r\n     * User-defined mass properties for the body.\r\n     */\r\n    public userMassProps: PhysicsMassProperties;\r\n\r\n    /**\r\n     * Reference to the world region this body belongs to.\r\n     * Used for floating origin mode to ensure consistent coordinate transformation.\r\n     * Will be undefined for non-floating-origin worlds (uses the default world).\r\n     */\r\n    public worldRegion?: PhysicsWorldRegion;\r\n}\r\n\r\n/*\r\nclass ShapePath\r\n{\r\n    public colliderId: number;\r\n    public pathData: number;\r\n}\r\n*/\r\n\r\nclass CollisionContactPoint {\r\n    /**\r\n     * Identifier of the body involved in the contact.\r\n     */\r\n    public bodyId: bigint = BigInt(0); //0,2\r\n    //public colliderId: number = 0; //2,4\r\n    //public shapePath: ShapePath = new ShapePath(); //4,8\r\n    public position: Vector3 = new Vector3(); //8,11\r\n    public normal: Vector3 = new Vector3(); //11,14\r\n    //public triIdx: number = 0; //14,15\r\n}\r\n\r\nclass CollisionEvent {\r\n    /**\r\n     * Contact point on the first body.\r\n     */\r\n    public contactOnA: CollisionContactPoint = new CollisionContactPoint(); //1\r\n    /**\r\n     * Contact point on the second body.\r\n     */\r\n    public contactOnB: CollisionContactPoint = new CollisionContactPoint();\r\n    /**\r\n     * Impulse applied by the collision.\r\n     */\r\n    public impulseApplied: number = 0;\r\n    /**\r\n     * Type of collision event reported by Havok.\r\n     */\r\n    public type: number = 0;\r\n\r\n    /**\r\n     * Reads a collision event from Havok memory into an existing event object.\r\n     * @param buffer - The Havok memory buffer to read from.\r\n     * @param offset - The byte offset of the event data.\r\n     * @param eventOut - The collision event object to update.\r\n     */\r\n    static readToRef(buffer: any, offset: number, eventOut: CollisionEvent) {\r\n        const intBuf = new Int32Array(buffer, offset);\r\n        const floatBuf = new Float32Array(buffer, offset);\r\n        const offA = 2;\r\n        eventOut.contactOnA.bodyId = BigInt(intBuf[offA]); //<todo Need to get the high+low words!\r\n        eventOut.contactOnA.position.set(floatBuf[offA + 8], floatBuf[offA + 9], floatBuf[offA + 10]);\r\n        eventOut.contactOnA.normal.set(floatBuf[offA + 11], floatBuf[offA + 12], floatBuf[offA + 13]);\r\n        const offB = 18;\r\n        eventOut.contactOnB.bodyId = BigInt(intBuf[offB]);\r\n        eventOut.contactOnB.position.set(floatBuf[offB + 8], floatBuf[offB + 9], floatBuf[offB + 10]);\r\n        eventOut.contactOnB.normal.set(floatBuf[offB + 11], floatBuf[offB + 12], floatBuf[offB + 13]);\r\n        eventOut.impulseApplied = floatBuf[offB + 13 + 3];\r\n        eventOut.type = intBuf[0];\r\n    }\r\n}\r\n\r\nclass TriggerEvent {\r\n    /**\r\n     * Identifier of the first body involved in the trigger event.\r\n     */\r\n    public bodyIdA: bigint = BigInt(0);\r\n    /**\r\n     * Identifier of the second body involved in the trigger event.\r\n     */\r\n    public bodyIdB: bigint = BigInt(0);\r\n    /**\r\n     * Type of trigger event reported by Havok.\r\n     */\r\n    public type: number = 0;\r\n\r\n    /**\r\n     * Reads a trigger event from Havok memory into an existing event object.\r\n     * @param buffer - The Havok memory buffer to read from.\r\n     * @param offset - The byte offset of the event data.\r\n     * @param eventOut - The trigger event object to update.\r\n     */\r\n    static readToRef(buffer: any, offset: number, eventOut: TriggerEvent) {\r\n        const intBuf = new Int32Array(buffer, offset);\r\n        eventOut.type = intBuf[0];\r\n        eventOut.bodyIdA = BigInt(intBuf[2]);\r\n        eventOut.bodyIdB = BigInt(intBuf[6]);\r\n    }\r\n}\r\n/**\r\n * Configuration parameters for the Havok plugin\r\n */\r\nexport interface HavokPluginParameters {\r\n    /**\r\n     * Maximum number of raycast hits to process\r\n     */\r\n    maxQueryCollectorHits?: number;\r\n    /**\r\n     * Whether to disable Havok world regions when floating origin mode is enabled.\r\n     * Set this when the application manages physics precision through its own rebasing system.\r\n     * Default is false.\r\n     */\r\n    disableWorldRegions?: boolean;\r\n    /**\r\n     * Radius of each floating origin world region.\r\n     * Bodies within this radius of a world region's origin will use that world.\r\n     * Bodies created outside existing regions will create a new region.\r\n     * Default is 100000 units.\r\n     */\r\n    floatingOriginWorldRadius?: number;\r\n}\r\n\r\n/**\r\n * Represents a physics world region with a fixed floating origin.\r\n * Bodies within a certain radius of this origin are simulated in this world.\r\n * @internal\r\n */\r\ninterface PhysicsWorldRegion {\r\n    /** The Havok world handle */\r\n    world: any;\r\n    /** The fixed floating origin for this world region (in world coordinates) */\r\n    floatingOrigin: Vector3;\r\n    /** The gravity for this world region (can be different per region for planetary scenarios) */\r\n    gravity: number[];\r\n}\r\n\r\n/**\r\n * The Havok Physics plugin\r\n */\r\nexport class HavokPlugin implements IPhysicsEnginePluginV2 {\r\n    /**\r\n     * Reference to the WASM library\r\n     */\r\n    public _hknp: any = {};\r\n    /**\r\n     * Created Havok world which physics bodies are added to (default world for non-floating-origin)\r\n     */\r\n    public world: any;\r\n    /**\r\n     * Name of the plugin\r\n     */\r\n    public name: string = \"HavokPlugin\";\r\n    /**\r\n     * We only have a single raycast in-flight right now\r\n     */\r\n    private _queryCollector;\r\n    private _multiQueryCollector: any = undefined;\r\n    private _fixedTimeStep: number = 1 / 60;\r\n    private _maxQueryCollectorHits: number = 1;\r\n    private _tmpVec3 = BuildArray(3, Vector3.Zero);\r\n    private _bodies = new Map<bigint, { body: PhysicsBody; index: number }>();\r\n    private _shapes = new Map<bigint, PhysicsShape>();\r\n    private _bodyCollisionObservable = new Map<bigint, Observable<IPhysicsCollisionEvent>>();\r\n    // Map from constraint id to the pair of bodies, where the first is the parent and the second is the child\r\n    private _constraintToBodyIdPair = new Map<bigint, [bigint, bigint]>();\r\n    private _bodyCollisionEndedObservable = new Map<bigint, Observable<IBasePhysicsCollisionEvent>>();\r\n    /**\r\n     * Array of world regions. The first region is always the default world with origin at Vector3.Zero.\r\n     * Additional regions are created as needed for floating origin mode.\r\n     */\r\n    private _worldRegions: PhysicsWorldRegion[] = [];\r\n    /**\r\n     * World regions that may have become empty while removing bodies.\r\n     * They are released after collision and trigger notifications have completed.\r\n     */\r\n    private readonly _worldRegionsPendingRelease = new Set<PhysicsWorldRegion>();\r\n    /**\r\n     * Stored gravity value to apply to new world regions.\r\n     */\r\n    private _currentGravity: number[] = [0, -9.81, 0];\r\n    /**\r\n     * Radius of each floating origin world region.\r\n     * Bodies within this radius of a world region's origin will use that world.\r\n     */\r\n    private _floatingOriginWorldRadius: number = 100000;\r\n    /**\r\n     * Whether Havok world regions are disabled.\r\n     */\r\n    private _disableWorldRegions: boolean = false;\r\n\r\n    /**\r\n     * Whether floating origin world regions are enabled for the current scene.\r\n     * @returns true when the scene uses floating origin mode and world regions are not disabled\r\n     */\r\n    private _areFloatingOriginWorldRegionsEnabled(): boolean {\r\n        return !this._disableWorldRegions && !!FloatingOriginCurrentScene.getScene()?.floatingOriginMode;\r\n    }\r\n\r\n    /**\r\n     * Finds an existing world region that contains the given world position,\r\n     * or creates a new world region centered at that position.\r\n     *\r\n     * When floatingOriginMode is enabled, we use multiple Havok worlds to maintain\r\n     * float32 precision across a large world. Each world region has its own fixed\r\n     * floating origin, and bodies within that region are simulated relative to it.\r\n     *\r\n     * @param worldPosition - The world position of the body being created\r\n     * @returns The world region to use for this body\r\n     */\r\n    private _getOrCreateWorldRegion(worldPosition: Vector3): PhysicsWorldRegion {\r\n        // Check if floating origin mode is enabled\r\n        if (!this._areFloatingOriginWorldRegionsEnabled()) {\r\n            // When floating origin mode is disabled, use the default world region\r\n            return this._worldRegions[0];\r\n        }\r\n\r\n        // Find an existing region that contains this position\r\n        for (const region of this._worldRegions) {\r\n            const distance = Vector3.Distance(worldPosition, region.floatingOrigin);\r\n            if (distance <= this._floatingOriginWorldRadius) {\r\n                return region;\r\n            }\r\n        }\r\n\r\n        // No existing region found - create a new one centered at this position\r\n        const newWorld = this._hknp.HP_World_Create()[1];\r\n\r\n        // Apply stored gravity to new world\r\n        this._hknp.HP_World_SetGravity(newWorld, this._currentGravity);\r\n\r\n        // Copy velocity limits from main world\r\n        this._hknp.HP_World_SetSpeedLimit(newWorld, this.getMaxLinearVelocity(), this.getMaxAngularVelocity());\r\n\r\n        const newRegion: PhysicsWorldRegion = {\r\n            world: newWorld,\r\n            floatingOrigin: worldPosition.clone(),\r\n            gravity: [...this._currentGravity],\r\n        };\r\n\r\n        this._worldRegions.push(newRegion);\r\n        return newRegion;\r\n    }\r\n\r\n    /**\r\n     * Checks if a body's world position has left its current region and, if so,\r\n     * moves it to the correct region (existing or newly created).\r\n     * This preserves linear and angular velocity across the transition.\r\n     *\r\n     * @param pluginData - The plugin data for the body (or instance) to check\r\n     */\r\n    private _reRegionBodyPluginData(pluginData: BodyPluginData): void {\r\n        const currentRegion = pluginData.worldRegion;\r\n        if (!currentRegion) {\r\n            return;\r\n        }\r\n\r\n        // Read the body's current local transform from Havok\r\n        const bodyTransform = this._hknp.HP_Body_GetQTransform(pluginData.hpBodyId)[1];\r\n        const localPos = bodyTransform[0];\r\n        const orientation = bodyTransform[1];\r\n\r\n        // Compute world position = local position + floating origin\r\n        const worldPos = TmpVectors.Vector3[2];\r\n        worldPos.set(localPos[0] + currentRegion.floatingOrigin._x, localPos[1] + currentRegion.floatingOrigin._y, localPos[2] + currentRegion.floatingOrigin._z);\r\n\r\n        // Check if still within the current region.\r\n        // Use a 20% hysteresis margin so that bodies near the boundary\r\n        // don't oscillate between regions every frame.\r\n        const distToCurrent = Vector3.Distance(worldPos, currentRegion.floatingOrigin);\r\n        if (distToCurrent <= this._floatingOriginWorldRadius * 1.2) {\r\n            return; // still in region (with hysteresis), nothing to do\r\n        }\r\n\r\n        // Body has left its region. Use velocity to look ahead and find the best\r\n        // region to join. This prevents creating throwaway intermediate regions\r\n        // when a fast body is heading toward an existing region (e.g. a target).\r\n        const linVel = this._hknp.HP_Body_GetLinearVelocity(pluginData.hpBodyId)[1];\r\n        const angVel = this._hknp.HP_Body_GetAngularVelocity(pluginData.hpBodyId)[1];\r\n\r\n        // Project position forward by one second of travel to find a suitable existing region.\r\n        // This is purely for region selection — the body's actual position is not changed.\r\n        const lookAheadPos = TmpVectors.Vector3[3];\r\n        lookAheadPos.set(worldPos._x + linVel[0], worldPos._y + linVel[1], worldPos._z + linVel[2]);\r\n\r\n        // Try to find the best region: first check if look-ahead position falls in an existing region\r\n        let newRegion = this._findExistingRegion(lookAheadPos);\r\n        if (!newRegion || newRegion === currentRegion) {\r\n            // Fall back to current position\r\n            newRegion = this._findExistingRegion(worldPos);\r\n        }\r\n        if (!newRegion || newRegion === currentRegion) {\r\n            // No existing region works — create one at the current position\r\n            newRegion = this._getOrCreateWorldRegion(worldPos);\r\n        }\r\n        if (newRegion === currentRegion) {\r\n            return;\r\n        }\r\n\r\n        // Remove from old world\r\n        this._hknp.HP_World_RemoveBody(currentRegion.world, pluginData.hpBodyId);\r\n\r\n        // Set transform relative to the new region's floating origin\r\n        const newOffset = newRegion.floatingOrigin;\r\n        const newLocalPos = [worldPos._x - newOffset._x, worldPos._y - newOffset._y, worldPos._z - newOffset._z];\r\n        this._hknp.HP_Body_SetQTransform(pluginData.hpBodyId, [newLocalPos, orientation]);\r\n\r\n        // Add to new world\r\n        this._hknp.HP_World_AddBody(newRegion.world, pluginData.hpBodyId, false);\r\n\r\n        // Restore velocity\r\n        this._hknp.HP_Body_SetLinearVelocity(pluginData.hpBodyId, linVel);\r\n        this._hknp.HP_Body_SetAngularVelocity(pluginData.hpBodyId, angVel);\r\n\r\n        // Update the region reference and world transform offset\r\n        pluginData.worldRegion = newRegion;\r\n        pluginData.worldTransformOffset = this._hknp.HP_Body_GetWorldTransformOffset(pluginData.hpBodyId)[1];\r\n\r\n        this._releaseWorldRegionIfEmpty(currentRegion);\r\n    }\r\n\r\n    /**\r\n     * Searches existing world regions for one that contains the given position.\r\n     * @param worldPosition - The world position to find a region for\r\n     * @returns null if no existing region contains it (does NOT create a new one).\r\n     */\r\n    private _findExistingRegion(worldPosition: Vector3): PhysicsWorldRegion | null {\r\n        if (!this._areFloatingOriginWorldRegionsEnabled()) {\r\n            return this._worldRegions[0];\r\n        }\r\n\r\n        for (const region of this._worldRegions) {\r\n            const distance = Vector3.Distance(worldPosition, region.floatingOrigin);\r\n            if (distance <= this._floatingOriginWorldRadius) {\r\n                return region;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Releases a non-default world region when it no longer contains any bodies.\r\n     * @param worldRegion - The world region to release if empty\r\n     */\r\n    private _releaseWorldRegionIfEmpty(worldRegion: PhysicsWorldRegion): void {\r\n        const regionIndex = this._worldRegions.indexOf(worldRegion);\r\n        if (regionIndex <= 0 || this._hknp.HP_World_GetNumBodies(worldRegion.world)[1] !== 0) {\r\n            return;\r\n        }\r\n\r\n        this._hknp.HP_World_Release(worldRegion.world);\r\n        this._worldRegions.splice(regionIndex, 1);\r\n    }\r\n\r\n    /**\r\n     * Releases world regions that became candidates for removal while bodies were being removed.\r\n     * This must run after collision and trigger notifications to avoid releasing a world while its native events are being read.\r\n     */\r\n    private _releasePendingWorldRegions(): void {\r\n        for (const worldRegion of this._worldRegionsPendingRelease) {\r\n            this._releaseWorldRegionIfEmpty(worldRegion);\r\n        }\r\n        this._worldRegionsPendingRelease.clear();\r\n    }\r\n\r\n    /**\r\n     * Observable for collision started and collision continued events\r\n     */\r\n    public onCollisionObservable = new Observable<IPhysicsCollisionEvent>();\r\n    /**\r\n     * Observable for collision ended events\r\n     */\r\n    public onCollisionEndedObservable = new Observable<IBasePhysicsCollisionEvent>();\r\n    /**\r\n     * Observable for trigger entered and trigger exited events\r\n     */\r\n    public onTriggerCollisionObservable = new Observable<IBasePhysicsCollisionEvent>();\r\n\r\n    public constructor(\r\n        private _useDeltaForWorldStep: boolean = true,\r\n        hpInjection: any = HK,\r\n        parameters: HavokPluginParameters = {}\r\n    ) {\r\n        if (typeof hpInjection === \"function\") {\r\n            Logger.Error(\"Havok is not ready. Please make sure you await HK() before using the plugin.\");\r\n            return;\r\n        } else {\r\n            this._hknp = hpInjection;\r\n        }\r\n\r\n        if (!this.isSupported()) {\r\n            Logger.Error(\"Havok is not available. Please make sure you included the js file.\");\r\n            return;\r\n        }\r\n        this.world = this._hknp.HP_World_Create()[1];\r\n\r\n        // Add the default world as the first region with origin at zero\r\n        this._worldRegions.push({\r\n            world: this.world,\r\n            floatingOrigin: Vector3.Zero(),\r\n            gravity: [...this._currentGravity],\r\n        });\r\n\r\n        this._queryCollector = this._hknp.HP_QueryCollector_Create(1)[1];\r\n        this.setMaxQueryCollectorHits(parameters.maxQueryCollectorHits ?? 1);\r\n        this._disableWorldRegions = parameters.disableWorldRegions ?? false;\r\n        this._floatingOriginWorldRadius = parameters.floatingOriginWorldRadius ?? 100000;\r\n    }\r\n    /**\r\n     * If this plugin is supported\r\n     * @returns true if its supported\r\n     */\r\n    public isSupported(): boolean {\r\n        return this._hknp !== undefined;\r\n    }\r\n\r\n    /**\r\n     * Sets the gravity of the physics world.\r\n     *\r\n     * @param gravity - The gravity vector to set.\r\n     * @param worldPosition - Optional world position to specify which region's gravity to set.\r\n     *                        If provided, only the region containing this position will be updated.\r\n     *                        If not provided, all regions will be updated (default behavior).\r\n     *                        This is useful for planetary scenarios where gravity direction varies by location.\r\n     */\r\n    public setGravity(gravity: Vector3, worldPosition?: Vector3): void {\r\n        const gravityArray = this._bVecToV3(gravity);\r\n\r\n        if (worldPosition) {\r\n            // Set gravity for a specific region based on world position\r\n            const region = this._getOrCreateWorldRegion(worldPosition);\r\n            region.gravity = gravityArray;\r\n            this._hknp.HP_World_SetGravity(region.world, gravityArray);\r\n        } else {\r\n            // Set gravity for all regions (default behavior)\r\n            this._currentGravity = gravityArray;\r\n            for (const region of this._worldRegions) {\r\n                region.gravity = gravityArray;\r\n                this._hknp.HP_World_SetGravity(region.world, gravityArray);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the gravity of the physics world or a specific region.\r\n     *\r\n     * @param worldPosition - Optional world position to get the gravity for that region.\r\n     *                        If not provided, returns the default gravity.\r\n     * @returns The gravity vector.\r\n     */\r\n    public getGravity(worldPosition?: Vector3): Vector3 {\r\n        if (worldPosition) {\r\n            const region = this._getOrCreateWorldRegion(worldPosition);\r\n            return new Vector3(region.gravity[0], region.gravity[1], region.gravity[2]);\r\n        }\r\n        return new Vector3(this._currentGravity[0], this._currentGravity[1], this._currentGravity[2]);\r\n    }\r\n\r\n    /**\r\n     * Sets the fixed time step for the physics engine.\r\n     *\r\n     * @param timeStep - The fixed time step to use for the physics engine.\r\n     *\r\n     */\r\n    public setTimeStep(timeStep: number): void {\r\n        this._fixedTimeStep = timeStep;\r\n    }\r\n\r\n    /**\r\n     * Gets the fixed time step used by the physics engine.\r\n     *\r\n     * @returns The fixed time step used by the physics engine.\r\n     *\r\n     */\r\n    public getTimeStep(): number {\r\n        return this._fixedTimeStep;\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum number of raycast hits to process.\r\n     *\r\n     * @param maxQueryCollectorHits - The maximum number of raycast hits to process.\r\n     */\r\n    public setMaxQueryCollectorHits(maxQueryCollectorHits: number): void {\r\n        if (maxQueryCollectorHits === this._maxQueryCollectorHits) {\r\n            return;\r\n        }\r\n\r\n        if (this._multiQueryCollector) {\r\n            this._hknp.HP_QueryCollector_Release(this._multiQueryCollector);\r\n            this._multiQueryCollector = undefined;\r\n        }\r\n\r\n        if (maxQueryCollectorHits > 1) {\r\n            this._multiQueryCollector = this._hknp.HP_QueryCollector_Create(maxQueryCollectorHits)[1];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum number of raycast hits to process.\r\n     *\r\n     * @returns The maximum number of raycast hits to process.\r\n     */\r\n    public getMaxQueryCollectorHits(): number {\r\n        return this._maxQueryCollectorHits;\r\n    }\r\n\r\n    /**\r\n     * Executes a single step of the physics engine.\r\n     *\r\n     * @param delta The time delta in seconds since the last step.\r\n     * @param physicsBodies An array of physics bodies to be simulated.\r\n     *\r\n     * This method is useful for simulating the physics engine. It sets the physics body transformation,\r\n     * steps the world, syncs the physics body, and notifies collisions. This allows for the physics engine\r\n     * to accurately simulate the physics bodies in the world.\r\n     */\r\n    public executeStep(delta: number, physicsBodies: Array<PhysicsBody>): void {\r\n        // Re-region bodies that have moved outside their current world region\r\n        // BEFORE pre-step and stepping, so the body participates in the correct\r\n        // world's step and its body buffer transform is valid when sync reads it.\r\n        if (this._areFloatingOriginWorldRegionsEnabled()) {\r\n            for (const physicsBody of physicsBodies) {\r\n                if (physicsBody._pluginDataInstances.length > 0) {\r\n                    for (const instance of physicsBody._pluginDataInstances) {\r\n                        this._reRegionBodyPluginData(instance);\r\n                    }\r\n                } else if (physicsBody._pluginData) {\r\n                    this._reRegionBodyPluginData(physicsBody._pluginData);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const physicsBody of physicsBodies) {\r\n            if (physicsBody.disablePreStep) {\r\n                continue;\r\n            }\r\n            this.setPhysicsBodyTransformation(physicsBody, physicsBody.transformNode);\r\n        }\r\n\r\n        const deltaTime = this._useDeltaForWorldStep ? delta : this._fixedTimeStep;\r\n\r\n        // Step all world regions\r\n        for (const region of this._worldRegions) {\r\n            this._hknp.HP_World_SetIdealStepTime(region.world, deltaTime);\r\n            this._hknp.HP_World_Step(region.world, deltaTime);\r\n        }\r\n\r\n        for (const physicsBody of physicsBodies) {\r\n            if (!physicsBody.disableSync) {\r\n                this.sync(physicsBody);\r\n            }\r\n        }\r\n\r\n        // Notify collisions and triggers for all world regions\r\n        for (const region of this._worldRegions) {\r\n            this._notifyCollisions(region.world);\r\n            this._notifyTriggers(region.world);\r\n        }\r\n\r\n        this._releasePendingWorldRegions();\r\n    }\r\n\r\n    /**\r\n     * Returns the version of the physics engine plugin.\r\n     *\r\n     * @returns The version of the physics engine plugin.\r\n     *\r\n     * This method is useful for determining the version of the physics engine plugin that is currently running.\r\n     */\r\n    public getPluginVersion(): number {\r\n        return 2;\r\n    }\r\n\r\n    /**\r\n     * Set the maximum allowed linear and angular velocities\r\n     * @param maxLinearVelocity maximum allowed linear velocity\r\n     * @param maxAngularVelocity maximum allowed angular velocity\r\n     */\r\n    setVelocityLimits(maxLinearVelocity: number, maxAngularVelocity: number): void {\r\n        for (const region of this._worldRegions) {\r\n            this._hknp.HP_World_SetSpeedLimit(region.world, maxLinearVelocity, maxAngularVelocity);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @returns maximum allowed linear velocity\r\n     */\r\n    getMaxLinearVelocity(): number {\r\n        const limits = this._hknp.HP_World_GetSpeedLimit(this.world);\r\n        return limits[1];\r\n    }\r\n\r\n    /**\r\n     * @returns maximum allowed angular velocity\r\n     */\r\n    getMaxAngularVelocity(): number {\r\n        const limits = this._hknp.HP_World_GetSpeedLimit(this.world);\r\n        return limits[2];\r\n    }\r\n\r\n    /**\r\n     * Initializes a physics body with the given position and orientation.\r\n     *\r\n     * @param body - The physics body to initialize.\r\n     * @param motionType - The motion type of the body.\r\n     * @param position - The position of the body.\r\n     * @param orientation - The orientation of the body.\r\n     * This code is useful for initializing a physics body with the given position and orientation.\r\n     * It creates a plugin data for the body and adds it to the world. It then converts the position\r\n     * and orientation to a transform and sets the body's transform to the given values.\r\n     */\r\n    public initBody(body: PhysicsBody, motionType: PhysicsMotionType, position: Vector3, orientation: Quaternion): void {\r\n        body._pluginData = new BodyPluginData(this._hknp.HP_Body_Create()[1]);\r\n\r\n        this._internalSetMotionType(body._pluginData, motionType);\r\n\r\n        // Get the world region for this body's position\r\n        const worldRegion = this._getOrCreateWorldRegion(position);\r\n        body._pluginData.worldRegion = worldRegion;\r\n        const offset = worldRegion.floatingOrigin;\r\n        const transform = [[position._x - offset._x, position._y - offset._y, position._z - offset._z], this._bQuatToV4(orientation)];\r\n        this._hknp.HP_Body_SetQTransform(body._pluginData.hpBodyId, transform);\r\n        this._hknp.HP_World_AddBody(worldRegion.world, body._pluginData.hpBodyId, body.startAsleep);\r\n        this._bodies.set(body._pluginData.hpBodyId[0], { body: body, index: 0 });\r\n    }\r\n\r\n    /**\r\n     * Removes a body from the world. To dispose of a body, it is necessary to remove it from the world first.\r\n     *\r\n     * @param body - The body to remove.\r\n     */\r\n    public removeBody(body: PhysicsBody): void {\r\n        if (body._pluginDataInstances && body._pluginDataInstances.length > 0) {\r\n            for (const instance of body._pluginDataInstances) {\r\n                this._bodyCollisionObservable.delete(instance.hpBodyId[0]);\r\n                this._hknp.HP_World_RemoveBody(instance.worldRegion.world, instance.hpBodyId);\r\n                this._bodies.delete(instance.hpBodyId[0]);\r\n                this._worldRegionsPendingRelease.add(instance.worldRegion);\r\n            }\r\n        }\r\n        if (body._pluginData) {\r\n            this._bodyCollisionObservable.delete(body._pluginData.hpBodyId[0]);\r\n            this._hknp.HP_World_RemoveBody(body._pluginData.worldRegion.world, body._pluginData.hpBodyId);\r\n            this._bodies.delete(body._pluginData.hpBodyId[0]);\r\n            this._worldRegionsPendingRelease.add(body._pluginData.worldRegion);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Initializes the body instances for a given physics body and mesh.\r\n     *\r\n     * @param body - The physics body to initialize.\r\n     * @param motionType - How the body will be handled by the engine\r\n     * @param mesh - The mesh to initialize.\r\n     *\r\n     * This code is useful for creating a physics body from a mesh. It creates a\r\n     * body instance for each instance of the mesh and adds it to the world. It also\r\n     * sets the position of the body instance to the position of the mesh instance.\r\n     * This allows for the physics engine to accurately simulate the mesh in the\r\n     * world.\r\n     */\r\n    public initBodyInstances(body: PhysicsBody, motionType: PhysicsMotionType, mesh: Mesh): void {\r\n        const instancesCount = mesh._thinInstanceDataStorage?.instancesCount ?? 0;\r\n        const matrixData = mesh._thinInstanceDataStorage.matrixData;\r\n        if (!matrixData) {\r\n            return; // TODO: error handling\r\n        }\r\n        this._createOrUpdateBodyInstances(body, motionType, matrixData, 0, instancesCount, false);\r\n        for (let index = 0; index < body._pluginDataInstances.length; index++) {\r\n            const bodyId = body._pluginDataInstances[index];\r\n            this._bodies.set(bodyId.hpBodyId[0], { body: body, index: index });\r\n        }\r\n    }\r\n\r\n    private _createOrUpdateBodyInstances(body: PhysicsBody, motionType: PhysicsMotionType, matrixData: Float32Array, startIndex: number, endIndex: number, update: boolean): void {\r\n        const rotation = TmpVectors.Quaternion[0];\r\n        const rotationMatrix = Matrix.Identity();\r\n        const worldPos = TmpVectors.Vector3[0];\r\n\r\n        for (let i = startIndex; i < endIndex; i++) {\r\n            // Get world position for this instance\r\n            worldPos.set(matrixData[i * 16 + 12], matrixData[i * 16 + 13], matrixData[i * 16 + 14]);\r\n\r\n            let hkbody;\r\n            let pluginData: BodyPluginData;\r\n            if (!update) {\r\n                hkbody = this._hknp.HP_Body_Create()[1];\r\n                pluginData = new BodyPluginData(hkbody);\r\n\r\n                if (body._pluginDataInstances.length) {\r\n                    // If an instance already exists, copy any user-provided mass properties\r\n                    pluginData.userMassProps = body._pluginDataInstances[0].userMassProps;\r\n                }\r\n            } else {\r\n                pluginData = body._pluginDataInstances[i];\r\n                hkbody = pluginData.hpBodyId;\r\n            }\r\n\r\n            // Get the world region for this instance's position\r\n            const worldRegion = this._getOrCreateWorldRegion(worldPos);\r\n            const offset = worldRegion.floatingOrigin;\r\n\r\n            // Subtract floating origin offset to get small coordinates for Havok (float32 precision)\r\n            const position = [worldPos._x - offset._x, worldPos._y - offset._y, worldPos._z - offset._z];\r\n\r\n            rotationMatrix.setRowFromFloats(0, matrixData[i * 16 + 0], matrixData[i * 16 + 1], matrixData[i * 16 + 2], 0);\r\n            rotationMatrix.setRowFromFloats(1, matrixData[i * 16 + 4], matrixData[i * 16 + 5], matrixData[i * 16 + 6], 0);\r\n            rotationMatrix.setRowFromFloats(2, matrixData[i * 16 + 8], matrixData[i * 16 + 9], matrixData[i * 16 + 10], 0);\r\n            Quaternion.FromRotationMatrixToRef(rotationMatrix, rotation);\r\n            const transform = [position, [rotation.x, rotation.y, rotation.z, rotation.w]];\r\n            this._hknp.HP_Body_SetQTransform(hkbody, transform);\r\n            if (!update) {\r\n                this._internalSetMotionType(pluginData, motionType);\r\n                this._internalUpdateMassProperties(pluginData);\r\n                body._pluginDataInstances.push(pluginData);\r\n                // Add to the appropriate world\r\n                pluginData.worldRegion = worldRegion;\r\n                this._hknp.HP_World_AddBody(worldRegion.world, hkbody, body.startAsleep);\r\n                pluginData.worldTransformOffset = this._hknp.HP_Body_GetWorldTransformOffset(hkbody)[1];\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the internal body instances for a given physics body to match the instances in a mesh.\r\n     * @param body the body that will be updated\r\n     * @param mesh the mesh with reference instances\r\n     */\r\n    public updateBodyInstances(body: PhysicsBody, mesh: Mesh): void {\r\n        const instancesCount = mesh._thinInstanceDataStorage?.instancesCount ?? 0;\r\n        const matrixData = mesh._thinInstanceDataStorage.matrixData;\r\n        if (!matrixData) {\r\n            return; // TODO: error handling\r\n        }\r\n        const pluginInstancesCount = body._pluginDataInstances.length;\r\n        const motionType = this.getMotionType(body);\r\n\r\n        if (instancesCount > pluginInstancesCount) {\r\n            this._createOrUpdateBodyInstances(body, motionType, matrixData, pluginInstancesCount, instancesCount, false);\r\n            const firstBodyShape = this._hknp.HP_Body_GetShape(body._pluginDataInstances[0].hpBodyId)[1];\r\n            // firstBodyShape[0] might be 0 in the case where thin instances data is set (with thinInstancesSetBuffer call) after body creation\r\n            // in that case, use the shape provided at body creation.\r\n            if (!firstBodyShape[0]) {\r\n                firstBodyShape[0] = body.shape?._pluginData[0];\r\n            }\r\n            for (let i = pluginInstancesCount; i < instancesCount; i++) {\r\n                this._hknp.HP_Body_SetShape(body._pluginDataInstances[i].hpBodyId, firstBodyShape);\r\n                this._internalUpdateMassProperties(body._pluginDataInstances[i]);\r\n                this._bodies.set(body._pluginDataInstances[i].hpBodyId[0], { body: body, index: i });\r\n            }\r\n        } else if (instancesCount < pluginInstancesCount) {\r\n            const instancesToRemove = pluginInstancesCount - instancesCount;\r\n            for (let i = 0; i < instancesToRemove; i++) {\r\n                const hkbody = body._pluginDataInstances.pop();\r\n                this._bodies.delete(hkbody.hpBodyId[0]);\r\n                this._hknp.HP_World_RemoveBody(hkbody.worldRegion.world, hkbody.hpBodyId);\r\n                this._worldRegionsPendingRelease.add(hkbody.worldRegion);\r\n                this._hknp.HP_Body_Release(hkbody.hpBodyId);\r\n            }\r\n            this._createOrUpdateBodyInstances(body, motionType, matrixData, 0, instancesCount, true);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Synchronizes the transform of a physics body with its transform node.\r\n     * @param body - The physics body to synchronize.\r\n     *\r\n     * This function is useful for keeping the physics body's transform in sync with its transform node.\r\n     * This is important for ensuring that the physics body is accurately represented in the physics engine.\r\n     */\r\n    sync(body: PhysicsBody): void {\r\n        this.syncTransform(body, body.transformNode);\r\n    }\r\n\r\n    /**\r\n     * Synchronizes the transform of a physics body with the transform of its\r\n     * corresponding transform node.\r\n     *\r\n     * @param body - The physics body to synchronize.\r\n     * @param transformNode - The destination Transform Node.\r\n     *\r\n     * This code is useful for synchronizing the position and orientation of a\r\n     * physics body with the position and orientation of its corresponding\r\n     * transform node. This is important for ensuring that the physics body and\r\n     * the transform node are in the same position and orientation in the scene.\r\n     * This is necessary for the physics engine to accurately simulate the\r\n     * physical behavior of the body.\r\n     */\r\n    syncTransform(body: PhysicsBody, transformNode: TransformNode): void {\r\n        // Get the floating origin offset - this was subtracted when positions were sent to Havok\r\n        // We need to add it back to get the correct world position\r\n\r\n        if (body._pluginDataInstances.length) {\r\n            // instances\r\n            const m = transformNode as Mesh;\r\n            const matrixData = m._thinInstanceDataStorage.matrixData;\r\n            if (!matrixData) {\r\n                return; // TODO: error handling\r\n            }\r\n            const instancesCount = body._pluginDataInstances.length;\r\n            for (let i = 0; i < instancesCount; i++) {\r\n                const pluginData = body._pluginDataInstances[i];\r\n                // Use instance's world region offset\r\n                const instanceOffset = pluginData.worldRegion.floatingOrigin;\r\n                // Get body buffer from the instance's own world region (not always the default world)\r\n                const bodyBuffer = this._hknp.HP_World_GetBodyBuffer(pluginData.worldRegion.world)[1];\r\n                const bufOffset = pluginData.worldTransformOffset;\r\n                const transformBuffer = new Float32Array(this._hknp.HEAPU8.buffer, bodyBuffer + bufOffset, 16);\r\n                const index = i * 16;\r\n\r\n                for (let mi = 0; mi < 15; mi++) {\r\n                    if ((mi & 3) != 3) {\r\n                        matrixData[index + mi] = transformBuffer[mi];\r\n                    }\r\n                }\r\n                // Add back the floating origin offset to get world position\r\n                // (Havok stores position - offset, so we add offset back)\r\n                matrixData[index + 12] += instanceOffset._x;\r\n                matrixData[index + 13] += instanceOffset._y;\r\n                matrixData[index + 14] += instanceOffset._z;\r\n                matrixData[index + 15] = 1;\r\n            }\r\n            m.thinInstanceBufferUpdated(\"matrix\");\r\n        } else {\r\n            try {\r\n                const bodyTransform = this._hknp.HP_Body_GetQTransform(body._pluginData.hpBodyId)[1];\r\n                const bodyTranslation = bodyTransform[0];\r\n                const bodyOrientation = bodyTransform[1];\r\n                const quat = TmpVectors.Quaternion[0];\r\n                // Use body's world region offset\r\n                const offset = body._pluginData.worldRegion.floatingOrigin;\r\n\r\n                quat.set(bodyOrientation[0], bodyOrientation[1], bodyOrientation[2], bodyOrientation[3]);\r\n\r\n                // Add back the floating origin offset to get world position\r\n                const worldX = bodyTranslation[0] + offset._x;\r\n                const worldY = bodyTranslation[1] + offset._y;\r\n                const worldZ = bodyTranslation[2] + offset._z;\r\n\r\n                const parent = transformNode.parent as TransformNode;\r\n                // transform position/orientation in parent space\r\n                if (parent && !parent.getWorldMatrix().isIdentity()) {\r\n                    parent.computeWorldMatrix(true);\r\n                    // Save scaling for future use\r\n                    TmpVectors.Vector3[1].copyFrom(transformNode.scaling);\r\n\r\n                    quat.normalize();\r\n                    const finalTransform = TmpVectors.Matrix[0];\r\n                    const finalTranslation = TmpVectors.Vector3[0];\r\n                    finalTranslation.copyFromFloats(worldX, worldY, worldZ);\r\n                    Matrix.ComposeToRef(transformNode.absoluteScaling, quat, finalTranslation, finalTransform);\r\n\r\n                    const parentInverseTransform = TmpVectors.Matrix[1];\r\n                    parent.getWorldMatrix().invertToRef(parentInverseTransform);\r\n\r\n                    const localTransform = TmpVectors.Matrix[2];\r\n                    finalTransform.multiplyToRef(parentInverseTransform, localTransform);\r\n                    localTransform.decomposeToTransformNode(transformNode);\r\n                    transformNode.rotationQuaternion?.normalize();\r\n                    // Keep original scaling. Re-injecting scaling can introduce discontinuity between frames. Basically, it grows or shrinks.\r\n                    transformNode.scaling.copyFrom(TmpVectors.Vector3[1]);\r\n                } else {\r\n                    transformNode.position.set(worldX, worldY, worldZ);\r\n                    if (transformNode.rotationQuaternion) {\r\n                        transformNode.rotationQuaternion.copyFrom(quat);\r\n                    } else {\r\n                        quat.toEulerAnglesToRef(transformNode.rotation);\r\n                    }\r\n                }\r\n            } catch (e) {\r\n                Logger.Error(`Syncing transform failed for node ${transformNode.name}: ${e.message}...`);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the shape of a physics body.\r\n     * @param body - The physics body to set the shape for.\r\n     * @param shape - The physics shape to set.\r\n     *\r\n     * This function is used to set the shape of a physics body. It is useful for\r\n     * creating a physics body with a specific shape, such as a box or a sphere,\r\n     * which can then be used to simulate physical interactions in a physics engine.\r\n     * This function is especially useful for meshes with multiple instances, as it\r\n     * will set the shape for each instance of the mesh.\r\n     */\r\n    public setShape(body: PhysicsBody, shape: Nullable<PhysicsShape>): void {\r\n        const shapeHandle = shape && shape._pluginData ? shape._pluginData : BigInt(0);\r\n        if (!(body.transformNode instanceof Mesh) || !body.transformNode._thinInstanceDataStorage?.matrixData) {\r\n            this._hknp.HP_Body_SetShape(body._pluginData.hpBodyId, shapeHandle);\r\n            this._internalUpdateMassProperties(body._pluginData);\r\n            return;\r\n        }\r\n        const m = body.transformNode;\r\n        const instancesCount = m._thinInstanceDataStorage?.instancesCount ?? 0;\r\n        for (let i = 0; i < instancesCount; i++) {\r\n            this._hknp.HP_Body_SetShape(body._pluginDataInstances[i].hpBodyId, shapeHandle);\r\n            this._internalUpdateMassProperties(body._pluginDataInstances[i]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a reference to the first instance of the plugin data for a physics body.\r\n     * @param body\r\n     * @param instanceIndex\r\n     * @returns a reference to the first instance\r\n     */\r\n    private _getPluginReference(body: PhysicsBody, instanceIndex?: number): BodyPluginData {\r\n        return body._pluginDataInstances?.length ? body._pluginDataInstances[instanceIndex ?? 0] : body._pluginData;\r\n    }\r\n\r\n    /**\r\n     * Gets the shape of a physics body. This will create a new shape object\r\n     *\r\n     * @param body - The physics body.\r\n     * @returns The shape of the physics body.\r\n     *\r\n     */\r\n    public getShape(body: PhysicsBody): Nullable<PhysicsShape> {\r\n        const pluginRef = this._getPluginReference(body);\r\n        const shapePluginData = this._hknp.HP_Body_GetShape(pluginRef.hpBodyId)[1];\r\n        if (shapePluginData != 0) {\r\n            const scene = body.transformNode.getScene();\r\n            return new PhysicsShape({ pluginData: shapePluginData }, scene);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Gets the type of a physics shape.\r\n     * @param shape - The physics shape to get the type for.\r\n     * @returns The type of the physics shape.\r\n     *\r\n     */\r\n    public getShapeType(shape: PhysicsShape): PhysicsShapeType {\r\n        if (shape.type) {\r\n            return shape.type;\r\n        } else {\r\n            //<todo This returns a native type!\r\n            return this._hknp.HP_Shape_GetType(shape._pluginData);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the event mask of a physics body.\r\n     * @param body - The physics body to set the event mask for.\r\n     * @param eventMask - The event mask to set.\r\n     * @param instanceIndex - The index of the instance to set the event mask for\r\n     *\r\n     * This function is useful for setting the event mask of a physics body, which is used to determine which events the body will respond to. This is important for ensuring that the physics engine is able to accurately simulate the behavior of the body in the game world.\r\n     */\r\n    public setEventMask(body: PhysicsBody, eventMask: number, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (bodyPluginData) => {\r\n                this._hknp.HP_Body_SetEventMask(bodyPluginData.hpBodyId, eventMask);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Retrieves the event mask of a physics body.\r\n     *\r\n     * @param body - The physics body to retrieve the event mask from.\r\n     * @param instanceIndex - The index of the instance to retrieve the event mask from.\r\n     * @returns The event mask of the physics body.\r\n     *\r\n     */\r\n    public getEventMask(body: PhysicsBody, instanceIndex?: number): number {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        return this._hknp.HP_Body_GetEventMask(pluginRef.hpBodyId)[1];\r\n    }\r\n\r\n    private _fromMassPropertiesTuple(massPropsTuple: any[]): PhysicsMassProperties {\r\n        return {\r\n            centerOfMass: Vector3.FromArray(massPropsTuple[0]),\r\n            mass: massPropsTuple[1],\r\n            inertia: Vector3.FromArray(massPropsTuple[2]),\r\n            inertiaOrientation: Quaternion.FromArray(massPropsTuple[3]),\r\n        };\r\n    }\r\n\r\n    private _internalUpdateMassProperties(pluginData: BodyPluginData) {\r\n        // Recompute the mass based on the shape\r\n        const newProps = this._internalComputeMassProperties(pluginData);\r\n        const massProps = pluginData.userMassProps;\r\n\r\n        // Override the computed values with any the user has set\r\n        if (massProps.centerOfMass) {\r\n            newProps[0] = massProps.centerOfMass.asArray();\r\n        }\r\n        if (massProps.mass != undefined) {\r\n            newProps[1] = massProps.mass;\r\n        }\r\n        if (massProps.inertia) {\r\n            newProps[2] = massProps.inertia.asArray();\r\n        }\r\n        if (massProps.inertiaOrientation) {\r\n            newProps[3] = massProps.inertiaOrientation.asArray();\r\n        }\r\n        this._hknp.HP_Body_SetMassProperties(pluginData.hpBodyId, newProps);\r\n    }\r\n\r\n    public _internalSetMotionType(pluginData: BodyPluginData, motionType: PhysicsMotionType): void {\r\n        switch (motionType) {\r\n            case PhysicsMotionType.STATIC:\r\n                this._hknp.HP_Body_SetMotionType(pluginData.hpBodyId, this._hknp.MotionType.STATIC);\r\n                break;\r\n            case PhysicsMotionType.ANIMATED:\r\n                this._hknp.HP_Body_SetMotionType(pluginData.hpBodyId, this._hknp.MotionType.KINEMATIC);\r\n                break;\r\n            case PhysicsMotionType.DYNAMIC:\r\n                this._hknp.HP_Body_SetMotionType(pluginData.hpBodyId, this._hknp.MotionType.DYNAMIC);\r\n                break;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * sets the motion type of a physics body.\r\n     * @param body - The physics body to set the motion type for.\r\n     * @param motionType - The motion type to set.\r\n     * @param instanceIndex - The index of the instance to set the motion type for. If undefined, the motion type of all the bodies will be set.\r\n     */\r\n    public setMotionType(body: PhysicsBody, motionType: PhysicsMotionType, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginData) => {\r\n                this._internalSetMotionType(pluginData, motionType);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the motion type of a physics body.\r\n     * @param body - The physics body to get the motion type from.\r\n     * @param instanceIndex - The index of the instance to get the motion type from. If not specified, the motion type of the first instance will be returned.\r\n     * @returns The motion type of the physics body.\r\n     */\r\n    public getMotionType(body: PhysicsBody, instanceIndex?: number): PhysicsMotionType {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const type = this._hknp.HP_Body_GetMotionType(pluginRef.hpBodyId)[1];\r\n        switch (type) {\r\n            case this._hknp.MotionType.STATIC:\r\n                return PhysicsMotionType.STATIC;\r\n            case this._hknp.MotionType.KINEMATIC:\r\n                return PhysicsMotionType.ANIMATED;\r\n            case this._hknp.MotionType.DYNAMIC:\r\n                return PhysicsMotionType.DYNAMIC;\r\n        }\r\n        throw new Error(\"Unknown motion type: \" + type);\r\n    }\r\n\r\n    /**\r\n     * sets the activation control mode of a physics body, for instance if you need the body to never sleep.\r\n     * @param body - The physics body to set the activation control mode.\r\n     * @param controlMode - The activation control mode.\r\n     */\r\n    public setActivationControl(body: PhysicsBody, controlMode: PhysicsActivationControl): void {\r\n        switch (controlMode) {\r\n            case PhysicsActivationControl.ALWAYS_ACTIVE:\r\n                this._hknp.HP_Body_SetActivationControl(body._pluginData.hpBodyId, this._hknp.ActivationControl.ALWAYS_ACTIVE);\r\n                break;\r\n            case PhysicsActivationControl.ALWAYS_INACTIVE:\r\n                this._hknp.HP_Body_SetActivationControl(body._pluginData.hpBodyId, this._hknp.ActivationControl.ALWAYS_INACTIVE);\r\n                break;\r\n            case PhysicsActivationControl.SIMULATION_CONTROLLED:\r\n                this._hknp.HP_Body_SetActivationControl(body._pluginData.hpBodyId, this._hknp.ActivationControl.SIMULATION_CONTROLLED);\r\n                break;\r\n        }\r\n    }\r\n\r\n    private _internalComputeMassProperties(pluginData: BodyPluginData): any[] {\r\n        const shapeRes = this._hknp.HP_Body_GetShape(pluginData.hpBodyId);\r\n        if (shapeRes[0] == this._hknp.Result.RESULT_OK) {\r\n            const shapeMass = this._hknp.HP_Shape_BuildMassProperties(shapeRes[1]);\r\n            if (shapeMass[0] == this._hknp.Result.RESULT_OK) {\r\n                return shapeMass[1];\r\n            }\r\n        }\r\n\r\n        // Failed; return a unit inertia\r\n        return [[0, 0, 0], 1, [1, 1, 1], [0, 0, 0, 1]];\r\n    }\r\n\r\n    /**\r\n     * Computes the mass properties of a physics body, from it's shape\r\n     *\r\n     * @param body - The physics body to copmute the mass properties of\r\n     * @param instanceIndex - The index of the instance to compute the mass properties of.\r\n     * @returns The mass properties of the physics body.\r\n     */\r\n    public computeMassProperties(body: PhysicsBody, instanceIndex?: number): PhysicsMassProperties {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const computed = this._internalComputeMassProperties(pluginRef);\r\n        return this._fromMassPropertiesTuple(computed);\r\n    }\r\n\r\n    /**\r\n     * Sets the mass properties of a physics body.\r\n     *\r\n     * @param body - The physics body to set the mass properties of.\r\n     * @param massProps - The mass properties to set.\r\n     * @param instanceIndex - The index of the instance to set the mass properties of. If undefined, the mass properties of all the bodies will be set.\r\n     * This function is useful for setting the mass properties of a physics body,\r\n     * such as its mass, inertia, and center of mass. This is important for\r\n     * accurately simulating the physics of the body in the physics engine.\r\n     *\r\n     */\r\n    public setMassProperties(body: PhysicsBody, massProps: PhysicsMassProperties, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginData) => {\r\n                pluginData.userMassProps = massProps;\r\n                this._internalUpdateMassProperties(pluginData);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n    /**\r\n     * Gets the mass properties of a physics body.\r\n     * @param body - The physics body to get the mass properties from.\r\n     * @param instanceIndex - The index of the instance to get the mass properties from. If not specified, the mass properties of the first instance will be returned.\r\n     * @returns The mass properties of the physics body.\r\n     */\r\n    public getMassProperties(body: PhysicsBody, instanceIndex?: number): PhysicsMassProperties {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const massPropsTuple = this._hknp.HP_Body_GetMassProperties(pluginRef.hpBodyId)[1];\r\n        return this._fromMassPropertiesTuple(massPropsTuple);\r\n    }\r\n\r\n    /**\r\n     * Sets the linear damping of the given body.\r\n     * @param body - The body to set the linear damping for.\r\n     * @param damping - The linear damping to set.\r\n     * @param instanceIndex - The index of the instance to set the linear damping for. If not specified, the linear damping of the first instance will be set.\r\n     *\r\n     * This method is useful for controlling the linear damping of a body in a physics engine.\r\n     * Linear damping is a force that opposes the motion of the body, and is proportional to the velocity of the body.\r\n     * This method allows the user to set the linear damping of a body, which can be used to control the motion of the body.\r\n     */\r\n    public setLinearDamping(body: PhysicsBody, damping: number, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginData) => {\r\n                this._hknp.HP_Body_SetLinearDamping(pluginData.hpBodyId, damping);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the linear damping of the given body.\r\n     * @param body - The body to get the linear damping from.\r\n     * @param instanceIndex - The index of the instance to get the linear damping from. If not specified, the linear damping of the first instance will be returned.\r\n     * @returns The linear damping of the given body.\r\n     *\r\n     * This method is useful for getting the linear damping of a body in a physics engine.\r\n     * Linear damping is a force that opposes the motion of the body and is proportional to the velocity of the body.\r\n     * It is used to simulate the effects of air resistance and other forms of friction.\r\n     */\r\n    public getLinearDamping(body: PhysicsBody, instanceIndex?: number): number {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        return this._hknp.HP_Body_GetLinearDamping(pluginRef.hpBodyId)[1];\r\n    }\r\n\r\n    /**\r\n     * Sets the angular damping of a physics body.\r\n     * @param body - The physics body to set the angular damping for.\r\n     * @param damping - The angular damping value to set.\r\n     * @param instanceIndex - The index of the instance to set the angular damping for. If not specified, the angular damping of the first instance will be set.\r\n     *\r\n     * This function is useful for controlling the angular velocity of a physics body.\r\n     * By setting the angular damping, the body's angular velocity will be reduced over time, allowing for more realistic physics simulations.\r\n     */\r\n    public setAngularDamping(body: PhysicsBody, damping: number, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginData) => {\r\n                this._hknp.HP_Body_SetAngularDamping(pluginData.hpBodyId, damping);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the angular damping of a physics body.\r\n     * @param body - The physics body to get the angular damping from.\r\n     * @param instanceIndex - The index of the instance to get the angular damping from. If not specified, the angular damping of the first instance will be returned.\r\n     * @returns The angular damping of the body.\r\n     *\r\n     * This function is useful for retrieving the angular damping of a physics body,\r\n     * which is used to control the rotational motion of the body. The angular damping is a value between 0 and 1, where 0 is no damping and 1 is full damping.\r\n     */\r\n    public getAngularDamping(body: PhysicsBody, instanceIndex?: number): number {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        return this._hknp.HP_Body_GetAngularDamping(pluginRef.hpBodyId)[1];\r\n    }\r\n\r\n    /**\r\n     * Sets the linear velocity of a physics body.\r\n     * @param body - The physics body to set the linear velocity of.\r\n     * @param linVel - The linear velocity to set.\r\n     * @param instanceIndex - The index of the instance to set the linear velocity of. If not specified, the linear velocity of the first instance will be set.\r\n     *\r\n     * This function is useful for setting the linear velocity of a physics body, which is necessary for simulating\r\n     * motion in a physics engine. The linear velocity is the speed and direction of the body's movement.\r\n     */\r\n    public setLinearVelocity(body: PhysicsBody, linVel: Vector3, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginData) => {\r\n                this._hknp.HP_Body_SetLinearVelocity(pluginData.hpBodyId, this._bVecToV3(linVel));\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the linear velocity of a physics body and stores it in a given vector.\r\n     * @param body - The physics body to get the linear velocity from.\r\n     * @param linVel - The vector to store the linear velocity in.\r\n     * @param instanceIndex - The index of the instance to get the linear velocity from. If not specified, the linear velocity of the first instance will be returned.\r\n     *\r\n     * This function is useful for retrieving the linear velocity of a physics body,\r\n     * which can be used to determine the speed and direction of the body. This\r\n     * information can be used to simulate realistic physics behavior in a game.\r\n     */\r\n    public getLinearVelocityToRef(body: PhysicsBody, linVel: Vector3, instanceIndex?: number): void {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const lv = this._hknp.HP_Body_GetLinearVelocity(pluginRef.hpBodyId)[1];\r\n        this._v3ToBvecRef(lv, linVel);\r\n    }\r\n\r\n    /*\r\n     * Apply an operation either to all instances of a body, if instanceIndex is not specified, or to a specific instance.\r\n     */\r\n    private _applyToBodyOrInstances(body: PhysicsBody, fnToApply: (pluginRef: any) => void, instanceIndex?: number): void {\r\n        if (body._pluginDataInstances?.length > 0 && instanceIndex === undefined) {\r\n            for (let i = 0; i < body._pluginDataInstances.length; i++) {\r\n                fnToApply(body._pluginDataInstances[i]);\r\n            }\r\n        } else {\r\n            fnToApply(this._getPluginReference(body, instanceIndex));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Applies an impulse to a physics body at a given location.\r\n     * @param body - The physics body to apply the impulse to.\r\n     * @param impulse - The impulse vector to apply.\r\n     * @param location - The location in world space to apply the impulse.\r\n     * @param instanceIndex - The index of the instance to apply the impulse to. If not specified, the impulse will be applied to all instances.\r\n     *\r\n     * This method is useful for applying an impulse to a physics body at a given location.\r\n     * This can be used to simulate physical forces such as explosions, collisions, and gravity.\r\n     */\r\n    public applyImpulse(body: PhysicsBody, impulse: Vector3, location: Vector3, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginRef) => {\r\n                const offset = pluginRef.worldRegion.floatingOrigin;\r\n                this._hknp.HP_Body_ApplyImpulse(pluginRef.hpBodyId, this._bVecToV3WithOffset(location, offset), this._bVecToV3(impulse));\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Applies an angular impulse(torque) to a physics body\r\n     * @param body - The physics body to apply the impulse to.\r\n     * @param angularImpulse - The torque value\r\n     * @param instanceIndex - The index of the instance to apply the impulse to. If not specified, the impulse will be applied to all instances.\r\n     */\r\n    public applyAngularImpulse(body: PhysicsBody, angularImpulse: Vector3, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginRef) => {\r\n                this._hknp.HP_Body_ApplyAngularImpulse(pluginRef.hpBodyId, this._bVecToV3(angularImpulse));\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n    /**\r\n     * Applies a force to a physics body at a given location.\r\n     * @param body - The physics body to apply the impulse to.\r\n     * @param force - The force vector to apply.\r\n     * @param location - The location in world space to apply the impulse.\r\n     * @param instanceIndex - The index of the instance to apply the force to. If not specified, the force will be applied to all instances.\r\n     *\r\n     * This method is useful for applying a force to a physics body at a given location.\r\n     * This can be used to simulate physical forces such as explosions, collisions, and gravity.\r\n     */\r\n    public applyForce(body: PhysicsBody, force: Vector3, location: Vector3, instanceIndex?: number): void {\r\n        force.scaleToRef(this.getTimeStep(), this._tmpVec3[0]);\r\n        this.applyImpulse(body, this._tmpVec3[0], location, instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Applies a torque to a physics body.\r\n     * @param body - The physics body to apply the torque to.\r\n     * @param torque - The torque vector.\r\n     * @param instanceIndex - The index of the instance to apply the torque to. If not specified, the torque will be applied to all instances.\r\n     *\r\n     * This method is useful for applying a torque to a physics body.\r\n     * This can be used to simulate rotational forces such as motors, angular momentum, and rotational dynamics.\r\n     */\r\n    public applyTorque(body: PhysicsBody, torque: Vector3, instanceIndex?: number): void {\r\n        torque.scaleToRef(this.getTimeStep(), this._tmpVec3[0]);\r\n        this.applyAngularImpulse(body, this._tmpVec3[0], instanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Sets the angular velocity of a physics body.\r\n     *\r\n     * @param body - The physics body to set the angular velocity of.\r\n     * @param angVel - The angular velocity to set.\r\n     * @param instanceIndex - The index of the instance to set the angular velocity of. If not specified, the angular velocity of the first instance will be set.\r\n     *\r\n     * This function is useful for setting the angular velocity of a physics body in a physics engine.\r\n     * This allows for more realistic simulations of physical objects, as they can be given a rotational velocity.\r\n     */\r\n    public setAngularVelocity(body: PhysicsBody, angVel: Vector3, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginRef) => {\r\n                this._hknp.HP_Body_SetAngularVelocity(pluginRef.hpBodyId, this._bVecToV3(angVel));\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the angular velocity of a body.\r\n     * @param body - The body to get the angular velocity from.\r\n     * @param angVel - The vector3 to store the angular velocity.\r\n     * @param instanceIndex - The index of the instance to get the angular velocity from. If not specified, the angular velocity of the first instance will be returned.\r\n     *\r\n     * This method is useful for getting the angular velocity of a body in a physics engine. It\r\n     * takes the body and a vector3 as parameters and stores the angular velocity of the body\r\n     * in the vector3. This is useful for getting the angular velocity of a body in order to\r\n     * calculate the motion of the body in the physics engine.\r\n     */\r\n    public getAngularVelocityToRef(body: PhysicsBody, angVel: Vector3, instanceIndex?: number): void {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const av = this._hknp.HP_Body_GetAngularVelocity(pluginRef.hpBodyId)[1];\r\n        this._v3ToBvecRef(av, angVel);\r\n    }\r\n\r\n    /**\r\n     * Sets the transformation of the given physics body to the given transform node.\r\n     * @param body The physics body to set the transformation for.\r\n     * @param node The transform node to set the transformation from.\r\n     * Sets the transformation of the given physics body to the given transform node.\r\n     *\r\n     * This function is useful for setting the transformation of a physics body to a\r\n     * transform node, which is necessary for the physics engine to accurately simulate\r\n     * the motion of the body. It also takes into account instances of the transform\r\n     * node, which is necessary for accurate simulation of multiple bodies with the\r\n     * same transformation.\r\n     */\r\n    public setPhysicsBodyTransformation(body: PhysicsBody, node: TransformNode) {\r\n        if (body.getPrestepType() == PhysicsPrestepType.TELEPORT) {\r\n            const transformNode = body.transformNode;\r\n            if (body.numInstances > 0) {\r\n                // instances\r\n                const m = transformNode as Mesh;\r\n                const matrixData = m._thinInstanceDataStorage.matrixData;\r\n                if (!matrixData) {\r\n                    return; // TODO: error handling\r\n                }\r\n                const instancesCount = body.numInstances;\r\n                this._createOrUpdateBodyInstances(body, body.getMotionType(), matrixData, 0, instancesCount, true);\r\n            } else {\r\n                // Check if the node's new world position requires a region change.\r\n                // This ensures teleports (e.g. toggling disablePreStep after moving\r\n                // the transform node) immediately land in the correct region with\r\n                // correct local coordinates, avoiding a one-frame precision glitch.\r\n                const pluginData = body._pluginData;\r\n                if (pluginData.worldRegion && this._areFloatingOriginWorldRegionsEnabled()) {\r\n                    // Get world position of the node\r\n                    const worldPos = TmpVectors.Vector3[3];\r\n                    if (node.parent) {\r\n                        node.computeWorldMatrix(true);\r\n                        worldPos.copyFrom(node.absolutePosition);\r\n                    } else {\r\n                        worldPos.copyFrom(node.position);\r\n                    }\r\n\r\n                    const currentRegion = pluginData.worldRegion;\r\n                    const distToCurrent = Vector3.Distance(worldPos, currentRegion.floatingOrigin);\r\n                    if (distToCurrent > this._floatingOriginWorldRadius * 1.2) {\r\n                        // Teleporting outside current region - re-region before setting transform\r\n                        const newRegion = this._getOrCreateWorldRegion(worldPos);\r\n                        if (newRegion !== currentRegion) {\r\n                            // Save velocity before removing from old world\r\n                            const linVel = this._hknp.HP_Body_GetLinearVelocity(pluginData.hpBodyId)[1];\r\n                            const angVel = this._hknp.HP_Body_GetAngularVelocity(pluginData.hpBodyId)[1];\r\n\r\n                            // Remove from old world, add to new world\r\n                            this._hknp.HP_World_RemoveBody(currentRegion.world, pluginData.hpBodyId);\r\n                            this._hknp.HP_World_AddBody(newRegion.world, pluginData.hpBodyId, false);\r\n\r\n                            // Restore velocity\r\n                            this._hknp.HP_Body_SetLinearVelocity(pluginData.hpBodyId, linVel);\r\n                            this._hknp.HP_Body_SetAngularVelocity(pluginData.hpBodyId, angVel);\r\n\r\n                            // Update region reference and cached world transform offset\r\n                            pluginData.worldRegion = newRegion;\r\n                            pluginData.worldTransformOffset = this._hknp.HP_Body_GetWorldTransformOffset(pluginData.hpBodyId)[1];\r\n\r\n                            this._releaseWorldRegionIfEmpty(currentRegion);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Set transform using the (possibly updated) region offset\r\n                const offset = body._pluginData.worldRegion.floatingOrigin;\r\n                this._hknp.HP_Body_SetQTransform(body._pluginData.hpBodyId, this._getTransformInfos(node, offset));\r\n            }\r\n        } else if (body.getPrestepType() == PhysicsPrestepType.ACTION) {\r\n            this.setTargetTransform(body, node.absolutePosition, node.absoluteRotationQuaternion);\r\n        } else if (body.getPrestepType() == PhysicsPrestepType.DISABLED) {\r\n            Logger.Warn(\"Prestep type is set to DISABLED. Unable to set physics body transformation.\");\r\n        } else {\r\n            Logger.Warn(\"Invalid prestep type set to physics body.\");\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set the target transformation (position and rotation) of the body, such that the body will set its velocity to reach that target\r\n     * @param body The physics body to set the target transformation for.\r\n     * @param position The target position\r\n     * @param rotation The target rotation\r\n     * @param instanceIndex The index of the instance in an instanced body\r\n     */\r\n    public setTargetTransform(body: PhysicsBody, position: Vector3, rotation: Quaternion, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginRef) => {\r\n                const offset = pluginRef.worldRegion.floatingOrigin;\r\n                this._hknp.HP_Body_SetTargetQTransform(pluginRef.hpBodyId, [this._bVecToV3WithOffset(position, offset), this._bQuatToV4(rotation)]);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Sets the gravity factor of a body\r\n     * @param body the physics body to set the gravity factor for\r\n     * @param factor the gravity factor\r\n     * @param instanceIndex the index of the instance in an instanced body\r\n     */\r\n    public setGravityFactor(body: PhysicsBody, factor: number, instanceIndex?: number): void {\r\n        this._applyToBodyOrInstances(\r\n            body,\r\n            (pluginRef) => {\r\n                this._hknp.HP_Body_SetGravityFactor(pluginRef.hpBodyId, factor);\r\n            },\r\n            instanceIndex\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Get the gravity factor of a body\r\n     * @param body the physics body to get the gravity factor from\r\n     * @param instanceIndex the index of the instance in an instanced body. If not specified, the gravity factor of the first instance will be returned.\r\n     * @returns the gravity factor\r\n     */\r\n    public getGravityFactor(body: PhysicsBody, instanceIndex?: number): number {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        return this._hknp.HP_Body_GetGravityFactor(pluginRef.hpBodyId)[1];\r\n    }\r\n\r\n    /**\r\n     * Disposes a physics body.\r\n     *\r\n     * @param body - The physics body to dispose.\r\n     *\r\n     * This method is useful for releasing the resources associated with a physics body when it is no longer needed.\r\n     * This is important for avoiding memory leaks in the physics engine.\r\n     */\r\n    public disposeBody(body: PhysicsBody): void {\r\n        if (body._pluginDataInstances && body._pluginDataInstances.length > 0) {\r\n            for (const instance of body._pluginDataInstances) {\r\n                this._hknp.HP_Body_Release(instance.hpBodyId);\r\n                instance.hpBodyId = undefined;\r\n            }\r\n        }\r\n        if (body._pluginData) {\r\n            this._hknp.HP_Body_Release(body._pluginData.hpBodyId);\r\n            body._pluginData.hpBodyId = undefined;\r\n        }\r\n    }\r\n\r\n    private _createOptionsFromGroundMesh(options: PhysicsShapeParameters) {\r\n        const mesh = options.groundMesh;\r\n        if (!mesh) {\r\n            return;\r\n        }\r\n        let pos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);\r\n        const transform = mesh.computeWorldMatrix(true);\r\n        // convert rawVerts to object space\r\n        const transformedVertices: number[] = [];\r\n        let index: number;\r\n        for (index = 0; index < pos.length; index += 3) {\r\n            Vector3.FromArrayToRef(pos, index, TmpVectors.Vector3[0]);\r\n            Vector3.TransformCoordinatesToRef(TmpVectors.Vector3[0], transform, TmpVectors.Vector3[1]);\r\n            TmpVectors.Vector3[1].toArray(transformedVertices, index);\r\n        }\r\n        pos = transformedVertices;\r\n\r\n        const arraySize = ~~(Math.sqrt(pos.length / 3) - 1);\r\n        const boundingInfo = mesh.getBoundingInfo();\r\n        const dim = Math.min(boundingInfo.boundingBox.extendSizeWorld.x, boundingInfo.boundingBox.extendSizeWorld.z);\r\n        const minX = boundingInfo.boundingBox.minimumWorld.x;\r\n        const minY = boundingInfo.boundingBox.minimumWorld.y;\r\n        const minZ = boundingInfo.boundingBox.minimumWorld.z;\r\n\r\n        const matrix = new Float32Array((arraySize + 1) * (arraySize + 1));\r\n\r\n        const elementSize = (dim * 2) / arraySize;\r\n\r\n        for (let i = 0; i < matrix.length; i++) {\r\n            matrix[i] = minY;\r\n        }\r\n        for (let i = 0; i < pos.length; i = i + 3) {\r\n            const x = Math.round((pos[i + 0] - minX) / elementSize);\r\n            const z = arraySize - Math.round((pos[i + 2] - minZ) / elementSize);\r\n            const y = pos[i + 1] - minY;\r\n\r\n            matrix[z * (arraySize + 1) + x] = y;\r\n        }\r\n\r\n        options.numHeightFieldSamplesX = arraySize + 1;\r\n        options.numHeightFieldSamplesZ = arraySize + 1;\r\n        options.heightFieldSizeX = boundingInfo.boundingBox.extendSizeWorld.x * 2;\r\n        options.heightFieldSizeZ = boundingInfo.boundingBox.extendSizeWorld.z * 2;\r\n        options.heightFieldData = matrix;\r\n    }\r\n\r\n    /**\r\n     * Initializes a physics shape with the given type and parameters.\r\n     * @param shape - The physics shape to initialize.\r\n     * @param type - The type of shape to initialize.\r\n     * @param options - The parameters for the shape.\r\n     *\r\n     * This code is useful for initializing a physics shape with the given type and parameters.\r\n     * It allows for the creation of a sphere, box, capsule, container, cylinder, mesh, and heightfield.\r\n     * Depending on the type of shape, different parameters are required.\r\n     * For example, a sphere requires a radius, while a box requires extents and a rotation.\r\n     */\r\n    public initShape(shape: PhysicsShape, type: PhysicsShapeType, options: PhysicsShapeParameters): void {\r\n        switch (type) {\r\n            case PhysicsShapeType.SPHERE:\r\n                {\r\n                    const radius = options.radius || 1;\r\n                    const center = options.center ? this._bVecToV3(options.center) : [0, 0, 0];\r\n                    shape._pluginData = this._hknp.HP_Shape_CreateSphere(center, radius)[1];\r\n                }\r\n                break;\r\n            case PhysicsShapeType.BOX:\r\n                {\r\n                    const rotation = options.rotation ? this._bQuatToV4(options.rotation) : [0, 0, 0, 1];\r\n                    const extent = options.extents ? this._bVecToV3(options.extents) : [1, 1, 1];\r\n                    const center = options.center ? this._bVecToV3(options.center) : [0, 0, 0];\r\n                    shape._pluginData = this._hknp.HP_Shape_CreateBox(center, rotation, extent)[1];\r\n                }\r\n                break;\r\n            case PhysicsShapeType.CAPSULE:\r\n                {\r\n                    const pointA = options.pointA ? this._bVecToV3(options.pointA) : [0, 0, 0];\r\n                    const pointB = options.pointB ? this._bVecToV3(options.pointB) : [0, 1, 0];\r\n                    const radius = options.radius || 0;\r\n                    shape._pluginData = this._hknp.HP_Shape_CreateCapsule(pointA, pointB, radius)[1];\r\n                }\r\n                break;\r\n            case PhysicsShapeType.CONTAINER:\r\n                {\r\n                    shape._pluginData = this._hknp.HP_Shape_CreateContainer()[1];\r\n                }\r\n                break;\r\n            case PhysicsShapeType.CYLINDER:\r\n                {\r\n                    const pointA = options.pointA ? this._bVecToV3(options.pointA) : [0, 0, 0];\r\n                    const pointB = options.pointB ? this._bVecToV3(options.pointB) : [0, 1, 0];\r\n                    const radius = options.radius || 0;\r\n                    shape._pluginData = this._hknp.HP_Shape_CreateCylinder(pointA, pointB, radius)[1];\r\n                }\r\n                break;\r\n            case PhysicsShapeType.CONVEX_HULL:\r\n            case PhysicsShapeType.MESH:\r\n                {\r\n                    const mesh = options.mesh;\r\n                    if (mesh) {\r\n                        const includeChildMeshes = !!options.includeChildMeshes;\r\n                        const needIndices = type != PhysicsShapeType.CONVEX_HULL;\r\n                        const accum = new MeshAccumulator(mesh, needIndices, mesh?.getScene());\r\n                        accum.addNodeMeshes(mesh, includeChildMeshes);\r\n\r\n                        const positions = accum.getVertices(this._hknp);\r\n                        const numVec3s = positions.numObjects / 3;\r\n\r\n                        if (type == PhysicsShapeType.CONVEX_HULL) {\r\n                            shape._pluginData = this._hknp.HP_Shape_CreateConvexHull(positions.offset, numVec3s)[1];\r\n                        } else {\r\n                            const triangles = accum.getTriangles(this._hknp);\r\n                            const numTriangles = triangles.numObjects / 3;\r\n                            shape._pluginData = this._hknp.HP_Shape_CreateMesh(positions.offset, numVec3s, triangles.offset, numTriangles)[1];\r\n                            accum.freeBuffer(this._hknp, triangles);\r\n                        }\r\n                        accum.freeBuffer(this._hknp, positions);\r\n                    } else {\r\n                        throw new Error(\"No mesh provided to create physics shape.\");\r\n                    }\r\n                }\r\n                break;\r\n            case PhysicsShapeType.HEIGHTFIELD:\r\n                {\r\n                    if (options.groundMesh) {\r\n                        // update options with datas from groundMesh\r\n                        this._createOptionsFromGroundMesh(options);\r\n                    }\r\n                    if (options.numHeightFieldSamplesX && options.numHeightFieldSamplesZ && options.heightFieldSizeX && options.heightFieldSizeZ && options.heightFieldData) {\r\n                        const totalNumHeights = options.numHeightFieldSamplesX * options.numHeightFieldSamplesZ;\r\n                        const numBytes = totalNumHeights * 4;\r\n                        const bufferBegin = this._hknp._malloc(numBytes);\r\n\r\n                        const heightBuffer = new Float32Array(this._hknp.HEAPU8.buffer, bufferBegin, totalNumHeights);\r\n                        for (let x = 0; x < options.numHeightFieldSamplesX; x++) {\r\n                            for (let z = 0; z < options.numHeightFieldSamplesZ; z++) {\r\n                                const hkBufferIndex = z * options.numHeightFieldSamplesX + x;\r\n                                const bjsBufferIndex = (options.numHeightFieldSamplesX - 1 - x) * options.numHeightFieldSamplesZ + z;\r\n                                heightBuffer[hkBufferIndex] = options.heightFieldData[bjsBufferIndex];\r\n                            }\r\n                        }\r\n\r\n                        const scaleX = options.heightFieldSizeX / (options.numHeightFieldSamplesX - 1);\r\n                        const scaleZ = options.heightFieldSizeZ / (options.numHeightFieldSamplesZ - 1);\r\n                        shape._pluginData = this._hknp.HP_Shape_CreateHeightField(\r\n                            options.numHeightFieldSamplesX,\r\n                            options.numHeightFieldSamplesZ,\r\n                            [scaleX, 1, scaleZ],\r\n                            bufferBegin\r\n                        )[1];\r\n\r\n                        this._hknp._free(bufferBegin);\r\n                    } else {\r\n                        throw new Error(\"Missing required heightfield parameters\");\r\n                    }\r\n                }\r\n                break;\r\n            default:\r\n                throw new Error(\"Unsupported Shape Type.\");\r\n                break;\r\n        }\r\n\r\n        this._shapes.set(shape._pluginData[0], shape);\r\n    }\r\n\r\n    /**\r\n     * Sets the shape filter membership mask of a body\r\n     * @param shape - The physics body to set the shape filter membership mask for.\r\n     * @param membershipMask - The shape filter membership mask to set.\r\n     */\r\n    public setShapeFilterMembershipMask(shape: PhysicsShape, membershipMask: number): void {\r\n        const collideWith = this._hknp.HP_Shape_GetFilterInfo(shape._pluginData)[1][1];\r\n        this._hknp.HP_Shape_SetFilterInfo(shape._pluginData, [membershipMask, collideWith]);\r\n    }\r\n\r\n    /**\r\n     * Gets the shape filter membership mask of a body\r\n     * @param shape - The physics body to get the shape filter membership mask from.\r\n     * @returns The shape filter membership mask of the given body.\r\n     */\r\n    public getShapeFilterMembershipMask(shape: PhysicsShape): number {\r\n        return this._hknp.HP_Shape_GetFilterInfo(shape._pluginData)[1][0];\r\n    }\r\n\r\n    /**\r\n     * Sets the shape filter collide mask of a body\r\n     * @param shape - The physics body to set the shape filter collide mask for.\r\n     * @param collideMask - The shape filter collide mask to set.\r\n     */\r\n    public setShapeFilterCollideMask(shape: PhysicsShape, collideMask: number): void {\r\n        const membership = this._hknp.HP_Shape_GetFilterInfo(shape._pluginData)[1][0];\r\n        this._hknp.HP_Shape_SetFilterInfo(shape._pluginData, [membership, collideMask]);\r\n    }\r\n\r\n    /**\r\n     * Gets the shape filter collide mask of a body\r\n     * @param shape - The physics body to get the shape filter collide mask from.\r\n     * @returns The shape filter collide mask of the given body.\r\n     */\r\n    public getShapeFilterCollideMask(shape: PhysicsShape): number {\r\n        return this._hknp.HP_Shape_GetFilterInfo(shape._pluginData)[1][1];\r\n    }\r\n\r\n    /**\r\n     * Sets the material of a physics shape.\r\n     * @param shape - The physics shape to set the material of.\r\n     * @param material - The material to set.\r\n     *\r\n     */\r\n    public setMaterial(shape: PhysicsShape, material: PhysicsMaterial): void {\r\n        const dynamicFriction = material.friction ?? 0.5;\r\n        const staticFriction = material.staticFriction ?? dynamicFriction;\r\n        const restitution = material.restitution ?? 0.0;\r\n        const frictionCombine = material.frictionCombine ?? PhysicsMaterialCombineMode.MINIMUM;\r\n        const restitutionCombine = material.restitutionCombine ?? PhysicsMaterialCombineMode.MAXIMUM;\r\n\r\n        const hpMaterial = [staticFriction, dynamicFriction, restitution, this._materialCombineToNative(frictionCombine), this._materialCombineToNative(restitutionCombine)];\r\n        this._hknp.HP_Shape_SetMaterial(shape._pluginData, hpMaterial);\r\n    }\r\n\r\n    /**\r\n     * Gets the material associated with a physics shape.\r\n     * @param shape - The shape to get the material from.\r\n     * @returns The material associated with the shape.\r\n     */\r\n    public getMaterial(shape: PhysicsShape): PhysicsMaterial {\r\n        const hkMaterial = this._hknp.HP_Shape_GetMaterial(shape._pluginData)[1];\r\n        return {\r\n            staticFriction: hkMaterial[0],\r\n            friction: hkMaterial[1],\r\n            restitution: hkMaterial[2],\r\n            frictionCombine: this._nativeToMaterialCombine(hkMaterial[3]),\r\n            restitutionCombine: this._nativeToMaterialCombine(hkMaterial[4]),\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Sets the density of a physics shape.\r\n     * @param shape - The physics shape to set the density of.\r\n     * @param density - The density to set.\r\n     *\r\n     */\r\n    public setDensity(shape: PhysicsShape, density: number): void {\r\n        this._hknp.HP_Shape_SetDensity(shape._pluginData, density);\r\n    }\r\n\r\n    /**\r\n     * Calculates the density of a given physics shape.\r\n     *\r\n     * @param shape - The physics shape to calculate the density of.\r\n     * @returns The density of the given physics shape.\r\n     *\r\n     */\r\n    public getDensity(shape: PhysicsShape): number {\r\n        return this._hknp.HP_Shape_GetDensity(shape._pluginData)[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the transform infos of a given transform node.\r\n     * This code is useful for getting the position and orientation of a given transform node.\r\n     * It first checks if the node has a rotation quaternion, and if not, it creates one from the node's rotation.\r\n     * It then creates an array containing the position and orientation of the node and returns it.\r\n     * @param node - The transform node.\r\n     * @param offset - The floating origin offset to apply.\r\n     * @returns An array containing the position and orientation of the node.\r\n     */\r\n    private _getTransformInfos(node: TransformNode, offset?: Vector3): any[] {\r\n        if (node.parent) {\r\n            node.computeWorldMatrix(true);\r\n            return [this._bVecToV3WithOffset(node.absolutePosition, offset), this._bQuatToV4(node.absoluteRotationQuaternion)];\r\n        }\r\n\r\n        let orientation = TmpVectors.Quaternion[0];\r\n        if (node.rotationQuaternion) {\r\n            orientation = node.rotationQuaternion;\r\n        } else {\r\n            const r = node.rotation;\r\n            Quaternion.FromEulerAnglesToRef(r.x, r.y, r.z, orientation);\r\n        }\r\n        const transform = [this._bVecToV3WithOffset(node.position, offset), this._bQuatToV4(orientation)];\r\n        return transform;\r\n    }\r\n\r\n    /**\r\n     * Adds a child shape to the given shape.\r\n     * @param shape - The parent shape.\r\n     * @param newChild - The child shape to add.\r\n     * @param translation - The relative translation of the child from the parent shape\r\n     * @param rotation - The relative rotation of the child from the parent shape\r\n     * @param scale - The relative scale scale of the child from the parent shaep\r\n     *\r\n     */\r\n    public addChild(shape: PhysicsShape, newChild: PhysicsShape, translation?: Vector3, rotation?: Quaternion, scale?: Vector3): void {\r\n        const transformNative = [\r\n            translation ? this._bVecToV3(translation) : [0, 0, 0],\r\n            rotation ? this._bQuatToV4(rotation) : [0, 0, 0, 1],\r\n            scale ? this._bVecToV3(scale) : [1, 1, 1],\r\n        ];\r\n        this._hknp.HP_Shape_AddChild(shape._pluginData, newChild._pluginData, transformNative);\r\n    }\r\n\r\n    /**\r\n     * Removes a child shape from a parent shape.\r\n     * @param shape - The parent shape.\r\n     * @param childIndex - The index of the child shape to remove.\r\n     *\r\n     */\r\n    public removeChild(shape: PhysicsShape, childIndex: number): void {\r\n        this._hknp.HP_Shape_RemoveChild(shape._pluginData, childIndex);\r\n    }\r\n\r\n    /**\r\n     * Returns the number of children of the given shape.\r\n     *\r\n     * @param shape - The shape to get the number of children from.\r\n     * @returns The number of children of the given shape.\r\n     *\r\n     */\r\n    public getNumChildren(shape: PhysicsShape): number {\r\n        return this._hknp.HP_Shape_GetNumChildren(shape._pluginData)[1];\r\n    }\r\n\r\n    /**\r\n     * Marks the shape as a trigger\r\n     * @param shape the shape to mark as a trigger\r\n     * @param isTrigger if the shape is a trigger\r\n     */\r\n    public setTrigger(shape: PhysicsShape, isTrigger: boolean): void {\r\n        this._hknp.HP_Shape_SetTrigger(shape._pluginData, isTrigger);\r\n    }\r\n\r\n    /**\r\n     * Calculates the bounding box of a given physics shape.\r\n     *\r\n     * @param _shape - The physics shape to calculate the bounding box for.\r\n     * @returns The calculated bounding box.\r\n     *\r\n     * This method is useful for physics engines as it allows to calculate the\r\n     * boundaries of a given shape. Knowing the boundaries of a shape is important\r\n     * for collision detection and other physics calculations.\r\n     */\r\n    public getBoundingBox(_shape: PhysicsShape): BoundingBox {\r\n        // get local AABB\r\n        const aabb = this._hknp.HP_Shape_GetBoundingBox(_shape._pluginData, [\r\n            [0, 0, 0],\r\n            [0, 0, 0, 1],\r\n        ])[1];\r\n        TmpVectors.Vector3[0].set(aabb[0][0], aabb[0][1], aabb[0][2]); // min\r\n        TmpVectors.Vector3[1].set(aabb[1][0], aabb[1][1], aabb[1][2]); // max\r\n        const boundingbox = new BoundingBox(TmpVectors.Vector3[0], TmpVectors.Vector3[1], Matrix.IdentityReadOnly);\r\n        return boundingbox;\r\n    }\r\n\r\n    /**\r\n     * Calculates the world bounding box of a given physics body.\r\n     *\r\n     * @param body - The physics body to calculate the bounding box for.\r\n     * @returns The calculated bounding box.\r\n     *\r\n     * This method is useful for physics engines as it allows to calculate the\r\n     * boundaries of a given body.\r\n     */\r\n    public getBodyBoundingBox(body: PhysicsBody): BoundingBox {\r\n        // get local AABB\r\n        const aabb = this.getBoundingBox(body.shape!);\r\n        const boundingbox = new BoundingBox(aabb.minimum, aabb.maximum, body.transformNode.getWorldMatrix());\r\n        return boundingbox;\r\n    }\r\n\r\n    /**\r\n     * Gets the geometry of a physics body.\r\n     *\r\n     * @param body - The physics body.\r\n     * @returns An object containing the positions and indices of the body's geometry.\r\n     *\r\n     */\r\n    public getBodyGeometry(body: PhysicsBody): {\r\n        positions: Float32Array | number[];\r\n        indices: Uint32Array | number[];\r\n    } {\r\n        const dataInfo = body._pluginDataInstances?.length > 0 ? body._pluginDataInstances[0] : body._pluginData;\r\n        const shape = this._hknp.HP_Body_GetShape(dataInfo.hpBodyId)[1];\r\n        const geometryRes = this._hknp.HP_Shape_CreateDebugDisplayGeometry(shape);\r\n\r\n        if (geometryRes[0] != this._hknp.Result.RESULT_OK) {\r\n            return { positions: [], indices: [] };\r\n        }\r\n\r\n        const geometryInfo = this._hknp.HP_DebugGeometry_GetInfo(geometryRes[1])[1];\r\n        const positionsInPlugin = new Float32Array(this._hknp.HEAPU8.buffer, geometryInfo[0], geometryInfo[1] * 3); // 3 floats per position\r\n        const indicesInPlugin = new Uint32Array(this._hknp.HEAPU8.buffer, geometryInfo[2], geometryInfo[3] * 3); // 3 indices per triangle\r\n\r\n        // HP_DebugGeometry_Release will free the buffer in the plugin. To avoid a\r\n        // use-after-free, we need  to make a copy of the data here.\r\n        const positions = positionsInPlugin.slice(0);\r\n        const indices = indicesInPlugin.slice(0);\r\n        this._hknp.HP_DebugGeometry_Release(geometryRes[1]);\r\n        return { positions: positions, indices: indices };\r\n    }\r\n\r\n    /**\r\n     * Releases a physics shape from the physics engine.\r\n     *\r\n     * @param shape - The physics shape to be released.\r\n     *\r\n     * This method is useful for releasing a physics shape from the physics engine, freeing up resources and preventing memory leaks.\r\n     */\r\n    public disposeShape(shape: PhysicsShape): void {\r\n        this._shapes.delete(shape._pluginData[0]);\r\n        this._hknp.HP_Shape_Release(shape._pluginData);\r\n        shape._pluginData = undefined;\r\n    }\r\n\r\n    // constraint\r\n\r\n    /**\r\n     * Initializes a physics constraint with the given parameters.\r\n     *\r\n     * @param constraint - The physics constraint to be initialized.\r\n     * @param body - The main body\r\n     * @param childBody - The child body.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to which the constraint will be applied. If not specified, no constraint will be applied.\r\n     * @param childInstanceIndex - If the child body is instanced, the index of the instance to which the constraint will be applied. If not specified, no constraint will be applied.\r\n     *\r\n     * This function is useful for setting up a physics constraint in a physics engine.\r\n     */\r\n    public initConstraint(constraint: PhysicsConstraint, body: PhysicsBody, childBody: PhysicsBody, instanceIndex?: number, childInstanceIndex?: number): void {\r\n        const type = constraint.type;\r\n        const options = constraint.options;\r\n        if (!type || !options) {\r\n            Logger.Warn(\"No constraint type or options. Constraint is invalid.\");\r\n            return;\r\n        }\r\n        if ((body._pluginDataInstances.length > 0 && instanceIndex === undefined) || (childBody._pluginDataInstances.length > 0 && childInstanceIndex === undefined)) {\r\n            Logger.Warn(\"Body is instanced but no instance index was specified. Constraint will not be applied.\");\r\n            return;\r\n        }\r\n\r\n        constraint._pluginData = constraint._pluginData ?? [];\r\n        const jointId = this._hknp.HP_Constraint_Create()[1];\r\n        constraint._pluginData.push(jointId);\r\n\r\n        // body parenting\r\n        const bodyA = this._getPluginReference(body, instanceIndex).hpBodyId;\r\n        const bodyB = this._getPluginReference(childBody, childInstanceIndex).hpBodyId;\r\n        this._hknp.HP_Constraint_SetParentBody(jointId, bodyA);\r\n        this._hknp.HP_Constraint_SetChildBody(jointId, bodyB);\r\n\r\n        this._constraintToBodyIdPair.set(jointId[0], [bodyA[0], bodyB[0]]);\r\n\r\n        // anchors\r\n        const pivotA = options.pivotA ? this._bVecToV3(options.pivotA) : this._bVecToV3(Vector3.Zero());\r\n        const axisA = options.axisA ?? new Vector3(1, 0, 0);\r\n        const perpAxisA = this._tmpVec3[0];\r\n        if (options.perpAxisA) {\r\n            perpAxisA.copyFrom(options.perpAxisA);\r\n        } else {\r\n            axisA.getNormalToRef(perpAxisA);\r\n        }\r\n        this._hknp.HP_Constraint_SetAnchorInParent(jointId, pivotA, this._bVecToV3(axisA), this._bVecToV3(perpAxisA));\r\n        const pivotB = options.pivotB ? this._bVecToV3(options.pivotB) : this._bVecToV3(Vector3.Zero());\r\n        const axisB = options.axisB ?? new Vector3(1, 0, 0);\r\n        const perpAxisB = this._tmpVec3[0];\r\n        if (options.perpAxisB) {\r\n            perpAxisB.copyFrom(options.perpAxisB);\r\n        } else {\r\n            axisB.getNormalToRef(perpAxisB);\r\n        }\r\n        this._hknp.HP_Constraint_SetAnchorInChild(jointId, pivotB, this._bVecToV3(axisB), this._bVecToV3(perpAxisB));\r\n\r\n        // Save the options that were used for initializing the constraint for debugging purposes\r\n        // Check first to avoid copying the same options multiple times\r\n        if (!constraint._initOptions) {\r\n            constraint._initOptions = {\r\n                axisA: axisA.clone(),\r\n                axisB: axisB.clone(),\r\n                perpAxisA: perpAxisA.clone(),\r\n                perpAxisB: perpAxisB.clone(),\r\n                pivotA: new Vector3(pivotA[0], pivotA[1], pivotA[2]),\r\n                pivotB: new Vector3(pivotB[0], pivotB[1], pivotB[2]),\r\n            };\r\n        }\r\n\r\n        if (type == PhysicsConstraintType.LOCK) {\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_X, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_X, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n        } else if (type == PhysicsConstraintType.DISTANCE) {\r\n            const distance = options.maxDistance || 0;\r\n            const dist3d = this._hknp.ConstraintAxis.LINEAR_DISTANCE;\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, dist3d, this._hknp.ConstraintAxisLimitMode.LIMITED);\r\n            this._hknp.HP_Constraint_SetAxisMinLimit(jointId, dist3d, distance);\r\n            this._hknp.HP_Constraint_SetAxisMaxLimit(jointId, dist3d, distance);\r\n        } else if (type == PhysicsConstraintType.HINGE) {\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_X, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n        } else if (type == PhysicsConstraintType.PRISMATIC) {\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_X, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n        } else if (type == PhysicsConstraintType.SLIDER) {\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.ANGULAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n        } else if (type == PhysicsConstraintType.BALL_AND_SOCKET) {\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_X, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Y, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._hknp.ConstraintAxis.LINEAR_Z, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n        } else if (type == PhysicsConstraintType.SIX_DOF) {\r\n            const sixdofData: Physics6DoFConstraint = <Physics6DoFConstraint>constraint;\r\n            for (const l of sixdofData.limits) {\r\n                const axId = this._constraintAxisToNative(l.axis);\r\n                if ((l.minLimit ?? -1) == 0 && (l.maxLimit ?? -1) == 0) {\r\n                    this._hknp.HP_Constraint_SetAxisMode(jointId, axId, this._hknp.ConstraintAxisLimitMode.LOCKED);\r\n                } else {\r\n                    if (l.minLimit != undefined) {\r\n                        this._hknp.HP_Constraint_SetAxisMode(jointId, axId, this._hknp.ConstraintAxisLimitMode.LIMITED);\r\n                        this._hknp.HP_Constraint_SetAxisMinLimit(jointId, axId, l.minLimit);\r\n                    }\r\n\r\n                    if (l.maxLimit != undefined) {\r\n                        this._hknp.HP_Constraint_SetAxisMode(jointId, axId, this._hknp.ConstraintAxisLimitMode.LIMITED);\r\n                        this._hknp.HP_Constraint_SetAxisMaxLimit(jointId, axId, l.maxLimit);\r\n                    }\r\n                }\r\n                if (l.stiffness) {\r\n                    this._hknp.HP_Constraint_SetAxisStiffness(jointId, axId, l.stiffness);\r\n                }\r\n                if (l.damping) {\r\n                    this._hknp.HP_Constraint_SetAxisDamping(jointId, axId, l.damping);\r\n                }\r\n            }\r\n        } else {\r\n            throw new Error(\"Unsupported Constraint Type.\");\r\n        }\r\n\r\n        const collisionEnabled = !!options.collision;\r\n        this._hknp.HP_Constraint_SetCollisionsEnabled(jointId, collisionEnabled);\r\n        this._hknp.HP_Constraint_SetEnabled(jointId, true);\r\n    }\r\n\r\n    /**\r\n     * Get a list of all the pairs of bodies that are connected by this constraint.\r\n     * @param constraint the constraint to search from\r\n     * @returns a list of parent, child pairs\r\n     */\r\n    getBodiesUsingConstraint(constraint: PhysicsConstraint): ConstrainedBodyPair[] {\r\n        const pairs: ConstrainedBodyPair[] = [];\r\n        for (const jointId of constraint._pluginData) {\r\n            const bodyIds = this._constraintToBodyIdPair.get(jointId[0]);\r\n            if (bodyIds) {\r\n                const parentBodyInfo = this._bodies.get(bodyIds[0]);\r\n                const childBodyInfo = this._bodies.get(bodyIds[1]);\r\n                if (parentBodyInfo && childBodyInfo) {\r\n                    pairs.push({ parentBody: parentBodyInfo.body, parentBodyIndex: parentBodyInfo.index, childBody: childBodyInfo.body, childBodyIndex: childBodyInfo.index });\r\n                }\r\n            }\r\n        }\r\n        return pairs;\r\n    }\r\n\r\n    /**\r\n     * Adds a constraint to the physics engine.\r\n     *\r\n     * @param body - The main body to which the constraint is applied.\r\n     * @param childBody - The body to which the constraint is applied.\r\n     * @param constraint - The constraint to be applied.\r\n     * @param instanceIndex - If this body is instanced, the index of the instance to which the constraint will be applied. If not specified, no constraint will be applied.\r\n     * @param childInstanceIndex - If the child body is instanced, the index of the instance to which the constraint will be applied. If not specified, no constraint will be applied.\r\n     */\r\n    addConstraint(body: PhysicsBody, childBody: PhysicsBody, constraint: PhysicsConstraint, instanceIndex?: number, childInstanceIndex?: number): void {\r\n        //<todo It's real weird that initConstraint() is called only after adding to a body!\r\n        this.initConstraint(constraint, body, childBody, instanceIndex, childInstanceIndex);\r\n    }\r\n\r\n    /**\r\n     * Enables or disables a constraint in the physics engine.\r\n     * @param constraint - The constraint to enable or disable.\r\n     * @param isEnabled - Whether the constraint should be enabled or disabled.\r\n     *\r\n     */\r\n    public setEnabled(constraint: PhysicsConstraint, isEnabled: boolean): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetEnabled(jointId, isEnabled);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the enabled state of the given constraint.\r\n     * @param constraint - The constraint to get the enabled state from.\r\n     * @returns The enabled state of the given constraint.\r\n     *\r\n     */\r\n    public getEnabled(constraint: PhysicsConstraint): boolean {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetEnabled(firstId)[1];\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Enables or disables collisions for the given constraint.\r\n     * @param constraint - The constraint to enable or disable collisions for.\r\n     * @param isEnabled - Whether collisions should be enabled or disabled.\r\n     *\r\n     */\r\n    public setCollisionsEnabled(constraint: PhysicsConstraint, isEnabled: boolean): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetCollisionsEnabled(jointId, isEnabled);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets whether collisions are enabled for the given constraint.\r\n     * @param constraint - The constraint to get collisions enabled for.\r\n     * @returns Whether collisions are enabled for the given constraint.\r\n     *\r\n     */\r\n    public getCollisionsEnabled(constraint: PhysicsConstraint): boolean {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetCollisionsEnabled(firstId)[1];\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Sets the friction of the given axis of the given constraint.\r\n     *\r\n     * @param constraint - The constraint to set the friction of.\r\n     * @param axis - The axis of the constraint to set the friction of.\r\n     * @param friction - The friction to set.\r\n     *\r\n     */\r\n    public setAxisFriction(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, friction: number): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisFriction(jointId, this._constraintAxisToNative(axis), friction);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the friction value of the specified axis of the given constraint.\r\n     *\r\n     * @param constraint - The constraint to get the axis friction from.\r\n     * @param axis - The axis to get the friction from.\r\n     * @returns The friction value of the specified axis.\r\n     *\r\n     */\r\n    public getAxisFriction(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetAxisFriction(firstId, this._constraintAxisToNative(axis))[1];\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the limit mode of the specified axis of the given constraint.\r\n     * @param constraint - The constraint to set the axis mode of.\r\n     * @param axis - The axis to set the limit mode of.\r\n     * @param limitMode - The limit mode to set.\r\n     */\r\n    public setAxisMode(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, limitMode: PhysicsConstraintAxisLimitMode): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisMode(jointId, this._constraintAxisToNative(axis), this._limitModeToNative(limitMode));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the axis limit mode of the given constraint.\r\n     *\r\n     * @param constraint - The constraint to get the axis limit mode from.\r\n     * @param axis - The axis to get the limit mode from.\r\n     * @returns The axis limit mode of the given constraint.\r\n     *\r\n     */\r\n    public getAxisMode(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<PhysicsConstraintAxisLimitMode> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            const mode = this._hknp.HP_Constraint_GetAxisMode(firstId, this._constraintAxisToNative(axis))[1];\r\n            return this._nativeToLimitMode(mode);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the minimum limit of the given axis of the given constraint.\r\n     * @param constraint - The constraint to set the minimum limit of.\r\n     * @param axis - The axis to set the minimum limit of.\r\n     * @param limit - The minimum limit to set.\r\n     *\r\n     */\r\n    public setAxisMinLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, limit: number): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisMinLimit(jointId, this._constraintAxisToNative(axis), limit);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the minimum limit of the specified axis of the given constraint.\r\n     * @param constraint - The constraint to get the minimum limit from.\r\n     * @param axis - The axis to get the minimum limit from.\r\n     * @returns The minimum limit of the specified axis of the given constraint.\r\n     *\r\n     */\r\n    public getAxisMinLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetAxisMinLimit(firstId, this._constraintAxisToNative(axis))[1];\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum limit of the given axis of the given constraint.\r\n     * @param constraint - The constraint to set the maximum limit of the given axis.\r\n     * @param axis - The axis to set the maximum limit of.\r\n     * @param limit - The maximum limit to set.\r\n     *\r\n     */\r\n    public setAxisMaxLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, limit: number): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisMaxLimit(jointId, this._constraintAxisToNative(axis), limit);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum limit of the given axis of the given constraint.\r\n     *\r\n     * @param constraint - The constraint to get the maximum limit from.\r\n     * @param axis - The axis to get the maximum limit from.\r\n     * @returns The maximum limit of the given axis of the given constraint.\r\n     *\r\n     */\r\n    public getAxisMaxLimit(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetAxisMaxLimit(firstId, this._constraintAxisToNative(axis))[1];\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the motor type of the given axis of the given constraint.\r\n     * @param constraint - The constraint to set the motor type of.\r\n     * @param axis - The axis of the constraint to set the motor type of.\r\n     * @param motorType - The motor type to set.\r\n     *\r\n     */\r\n    public setAxisMotorType(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, motorType: PhysicsConstraintMotorType): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisMotorType(jointId, this._constraintAxisToNative(axis), this._constraintMotorTypeToNative(motorType));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the motor type of the specified axis of the given constraint.\r\n     * @param constraint - The constraint to get the motor type from.\r\n     * @param axis - The axis of the constraint to get the motor type from.\r\n     * @returns The motor type of the specified axis of the given constraint.\r\n     *\r\n     */\r\n    public getAxisMotorType(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<PhysicsConstraintMotorType> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._nativeToMotorType(this._hknp.HP_Constraint_GetAxisMotorType(firstId, this._constraintAxisToNative(axis))[1]);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the target of an axis motor of a constraint.\r\n     *\r\n     * @param constraint - The constraint to set the axis motor target of.\r\n     * @param axis - The axis of the constraint to set the motor target of.\r\n     * @param target - The target of the axis motor.\r\n     *\r\n     */\r\n    public setAxisMotorTarget(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, target: number): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisMotorTarget(jointId, this._constraintAxisToNative(axis), target);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the target of the motor of the given axis of the given constraint.\r\n     *\r\n     * @param constraint - The constraint to get the motor target from.\r\n     * @param axis - The axis of the constraint to get the motor target from.\r\n     * @returns The target of the motor of the given axis of the given constraint.\r\n     *\r\n     */\r\n    public getAxisMotorTarget(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetAxisMotorTarget(constraint._pluginData, this._constraintAxisToNative(axis))[1];\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Sets the maximum force that can be applied by the motor of the given constraint axis.\r\n     * @param constraint - The constraint to set the motor max force for.\r\n     * @param axis - The axis of the constraint to set the motor max force for.\r\n     * @param maxForce - The maximum force that can be applied by the motor.\r\n     *\r\n     */\r\n    public setAxisMotorMaxForce(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis, maxForce: number): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetAxisMotorMaxForce(jointId, this._constraintAxisToNative(axis), maxForce);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum force of the motor of the given constraint axis.\r\n     *\r\n     * @param constraint - The constraint to get the motor maximum force from.\r\n     * @param axis - The axis of the constraint to get the motor maximum force from.\r\n     * @returns The maximum force of the motor of the given constraint axis.\r\n     *\r\n     */\r\n    public getAxisMotorMaxForce(constraint: PhysicsConstraint, axis: PhysicsConstraintAxis): Nullable<number> {\r\n        const firstId = constraint._pluginData && constraint._pluginData[0];\r\n        if (firstId) {\r\n            return this._hknp.HP_Constraint_GetAxisMotorMaxForce(firstId, this._constraintAxisToNative(axis))[1];\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Disposes a physics constraint.\r\n     *\r\n     * @param constraint - The physics constraint to dispose.\r\n     *\r\n     * This method is useful for releasing the resources associated with a physics constraint, such as\r\n     * the Havok constraint, when it is no longer needed. This is important for avoiding memory leaks.\r\n     */\r\n    public disposeConstraint(constraint: PhysicsConstraint): void {\r\n        for (const jointId of constraint._pluginData) {\r\n            this._hknp.HP_Constraint_SetEnabled(jointId, false);\r\n            this._hknp.HP_Constraint_Release(jointId);\r\n        }\r\n        constraint._pluginData.length = 0;\r\n    }\r\n\r\n    private _populateHitData(hitData: any, result: ProximityCastResult | PhysicsRaycastResult | ShapeCastResult): void {\r\n        const hitBody = this._bodies.get(hitData[0][0]);\r\n        result.body = hitBody?.body;\r\n        result.bodyIndex = hitBody?.index;\r\n        const hitShape = this._shapes.get(hitData[1][0]);\r\n        result.shape = hitShape;\r\n\r\n        const hitPos = hitData[3];\r\n        const hitNormal = hitData[4];\r\n        const hitTriangle = hitData[5];\r\n\r\n        // Add floating origin offset back to hit position using the hit body's world region offset\r\n        // If no hit body (shouldn't happen), use zero offset from default region\r\n        const offset = hitBody?.body?._pluginData?.worldRegion?.floatingOrigin ?? this._worldRegions[0].floatingOrigin;\r\n        result.setHitData({ x: hitNormal[0], y: hitNormal[1], z: hitNormal[2] }, { x: hitPos[0] + offset._x, y: hitPos[1] + offset._y, z: hitPos[2] + offset._z }, hitTriangle);\r\n    }\r\n\r\n    /**\r\n     * Performs a raycast from a given start point to a given end point and stores the result in a given PhysicsRaycastResult object.\r\n     *\r\n     * @param from - The start point of the raycast.\r\n     * @param to - The end point of the raycast.\r\n     * @param result - The PhysicsRaycastResult object (or array of PhysicsRaycastResults) to store the result of the raycast.\r\n     * @param query - The raycast query options. See [[IRaycastQuery]] for more information.\r\n     *\r\n     * Performs a raycast. It takes in two points, from and to, and a PhysicsRaycastResult object to store the result of the raycast.\r\n     * It then performs the raycast and stores the hit data in the PhysicsRaycastResult object.\r\n     * If result is an empty array, it will be populated with every detected raycast hit.\r\n     * If result is a populated array, it will only fill the PhysicsRaycastResults present in the array.\r\n     */\r\n    public raycast(from: Vector3, to: Vector3, result: PhysicsRaycastResult | Array<PhysicsRaycastResult>, query?: IRaycastQuery): void {\r\n        const queryMembership = query?.membership ?? ~0;\r\n        const queryCollideWith = query?.collideWith ?? ~0;\r\n        const shouldHitTriggers = query?.shouldHitTriggers ?? false;\r\n        const bodyToIgnore = query?.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];\r\n\r\n        const results = Array.isArray(result) ? result : [result];\r\n        for (const raycastResult of results) {\r\n            raycastResult.reset(from, to);\r\n        }\r\n\r\n        // If there are no world regions (e.g. after dispose(), which releases every world and clears the array),\r\n        // there is nothing valid to cast against. Bail out with an empty (no-hit) result rather than dereferencing\r\n        // an undefined region or using a stale worldRegion from ignoreBody that points at an already-released world.\r\n        if (this._worldRegions.length === 0) {\r\n            return;\r\n        }\r\n\r\n        // Use the ignored body's world region if available, otherwise use default region\r\n        const worldRegion = query?.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];\r\n        const offset = worldRegion.floatingOrigin;\r\n        const world = worldRegion.world;\r\n        const offsetFrom = this._bVecToV3WithOffset(from, offset);\r\n        const offsetTo = this._bVecToV3WithOffset(to, offset);\r\n\r\n        const hkQuery = [offsetFrom, offsetTo, [queryMembership, queryCollideWith], shouldHitTriggers, bodyToIgnore];\r\n        const queryCollector = results.length === 1 || !this._multiQueryCollector ? this._queryCollector : this._multiQueryCollector;\r\n        this._hknp.HP_World_CastRayWithCollector(world, queryCollector, hkQuery);\r\n\r\n        const numHits = this._hknp.HP_QueryCollector_GetNumHits(queryCollector)[1];\r\n        if (numHits <= 0) {\r\n            return;\r\n        }\r\n\r\n        if (!results.length) {\r\n            for (let i = 0; i < numHits; i++) {\r\n                const raycastResult = new PhysicsRaycastResult();\r\n                raycastResult.reset(from, to);\r\n                results.push(raycastResult);\r\n            }\r\n        }\r\n\r\n        // QueryCollector results are not sorted by distance, so we need to sort them manually\r\n        const hitDatas: Array<{ hitData: any; distance: number }> = new Array(numHits);\r\n        for (let i = 0; i < numHits; i++) {\r\n            const [, hitData] = this._hknp.HP_QueryCollector_GetCastRayResult(queryCollector, i)[1];\r\n\r\n            const hitPos = hitData[3];\r\n            // Use offsetFrom for distance calculation since hitPos is in Havok's offset space\r\n            this._tmpVec3[0].set(offsetFrom[0] - hitPos[0], offsetFrom[1] - hitPos[1], offsetFrom[2] - hitPos[2]);\r\n            const distance = this._tmpVec3[0].lengthSquared();\r\n\r\n            hitDatas[i] = {\r\n                hitData,\r\n                distance: distance,\r\n            };\r\n        }\r\n\r\n        hitDatas.sort((a, b) => a.distance - b.distance);\r\n\r\n        for (let i = 0; i < Math.min(numHits, results.length); i++) {\r\n            const raycastResult = results[i];\r\n            const hitData = hitDatas[i];\r\n\r\n            this._populateHitData(hitData.hitData, raycastResult);\r\n            raycastResult.setHitDistance(Math.sqrt(hitData.distance));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Given a point, returns the closest physics\r\n     * body to that point.\r\n     * @param query the query to perform. @see IPhysicsPointProximityQuery\r\n     * @param result contact point on the hit shape, in world space\r\n     */\r\n    public pointProximity(query: IPhysicsPointProximityQuery, result: ProximityCastResult): void {\r\n        const queryMembership = query?.collisionFilter?.membership ?? ~0;\r\n        const queryCollideWith = query?.collisionFilter?.collideWith ?? ~0;\r\n\r\n        result.reset();\r\n\r\n        const bodyToIgnore = query.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];\r\n        if (this._worldRegions.length === 0) {\r\n            return;\r\n        }\r\n        // Use the ignored body's world region if available, otherwise use default region\r\n        const worldRegion = query.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];\r\n        const offset = worldRegion.floatingOrigin;\r\n        const world = worldRegion.world;\r\n\r\n        const hkQuery = [this._bVecToV3WithOffset(query.position, offset), query.maxDistance, [queryMembership, queryCollideWith], query.shouldHitTriggers, bodyToIgnore];\r\n        this._hknp.HP_World_PointProximityWithCollector(world, this._queryCollector, hkQuery);\r\n\r\n        if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {\r\n            const [distance, hitData] = this._hknp.HP_QueryCollector_GetPointProximityResult(this._queryCollector, 0)[1];\r\n\r\n            this._populateHitData(hitData, result);\r\n            result.setHitDistance(distance);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Given a shape in a specific position and orientation, returns the closest point to that shape.\r\n     * @param query the query to perform. @see IPhysicsShapeProximityCastQuery\r\n     * @param inputShapeResult contact point on input shape, in input shape space\r\n     * @param hitShapeResult contact point on hit shape, in world space\r\n     */\r\n    public shapeProximity(query: IPhysicsShapeProximityCastQuery, inputShapeResult: ProximityCastResult, hitShapeResult: ProximityCastResult): void {\r\n        inputShapeResult.reset();\r\n        hitShapeResult.reset();\r\n        const shapeId = query.shape._pluginData;\r\n        const bodyToIgnore = query.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];\r\n        if (this._worldRegions.length === 0) {\r\n            return;\r\n        }\r\n        // Use the ignored body's world region if available, otherwise use default region\r\n        const worldRegion = query.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];\r\n        const offset = worldRegion.floatingOrigin;\r\n        const world = worldRegion.world;\r\n\r\n        const hkQuery = [shapeId, this._bVecToV3WithOffset(query.position, offset), this._bQuatToV4(query.rotation), query.maxDistance, query.shouldHitTriggers, bodyToIgnore];\r\n        this._hknp.HP_World_ShapeProximityWithCollector(world, this._queryCollector, hkQuery);\r\n\r\n        if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {\r\n            const [distance, hitInputData, hitShapeData] = this._hknp.HP_QueryCollector_GetShapeProximityResult(this._queryCollector, 0)[1];\r\n\r\n            this._populateHitData(hitInputData, inputShapeResult);\r\n            this._populateHitData(hitShapeData, hitShapeResult);\r\n\r\n            inputShapeResult.setHitDistance(distance);\r\n            hitShapeResult.setHitDistance(distance);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Given a shape in a specific orientation, cast it from the start to end position specified by the query, and return the first hit.\r\n     * @param query the query to perform. @see IPhysicsShapeCastQuery\r\n     * @param inputShapeResult contact point on input shape, in input shape space\r\n     * @param hitShapeResult contact point on hit shape, in world space\r\n     */\r\n    public shapeCast(query: IPhysicsShapeCastQuery, inputShapeResult: ShapeCastResult, hitShapeResult: ShapeCastResult): void {\r\n        inputShapeResult.reset();\r\n        hitShapeResult.reset();\r\n\r\n        const shapeId = query.shape._pluginData;\r\n        const bodyToIgnore = query.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];\r\n        if (this._worldRegions.length === 0) {\r\n            return;\r\n        }\r\n        // Use the ignored body's world region if available, otherwise use default region\r\n        const worldRegion = query.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];\r\n        const offset = worldRegion.floatingOrigin;\r\n        const world = worldRegion.world;\r\n\r\n        const hkQuery = [\r\n            shapeId,\r\n            this._bQuatToV4(query.rotation),\r\n            this._bVecToV3WithOffset(query.startPosition, offset),\r\n            this._bVecToV3WithOffset(query.endPosition, offset),\r\n            query.shouldHitTriggers,\r\n            bodyToIgnore,\r\n        ];\r\n        this._hknp.HP_World_ShapeCastWithCollector(world, this._queryCollector, hkQuery);\r\n\r\n        if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {\r\n            const [fractionAlongRay, hitInputData, hitShapeData] = this._hknp.HP_QueryCollector_GetShapeCastResult(this._queryCollector, 0)[1];\r\n\r\n            this._populateHitData(hitInputData, inputShapeResult);\r\n            this._populateHitData(hitShapeData, hitShapeResult);\r\n\r\n            inputShapeResult.setHitFraction(fractionAlongRay);\r\n            hitShapeResult.setHitFraction(fractionAlongRay);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Return the collision observable for a particular physics body.\r\n     * @param body the physics body\r\n     * @param instanceIndex - optionally, the index of the instance in the body\r\n     * @returns the collision observable for the body\r\n     */\r\n    public getCollisionObservable(body: PhysicsBody, instanceIndex?: number): Observable<IPhysicsCollisionEvent> {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const bodyId = pluginRef.hpBodyId[0];\r\n        let observable = this._bodyCollisionObservable.get(bodyId);\r\n        if (!observable) {\r\n            observable = new Observable<IPhysicsCollisionEvent>();\r\n            this._bodyCollisionObservable.set(bodyId, observable);\r\n        }\r\n        return observable;\r\n    }\r\n\r\n    /**\r\n     * Return the collision ended observable for a particular physics body.\r\n     * @param body the physics body\r\n     * @param instanceIndex - optionally, the index of the instance in the body\r\n     * @returns the collision ended observable for the body\r\n     */\r\n    public getCollisionEndedObservable(body: PhysicsBody, instanceIndex?: number): Observable<IBasePhysicsCollisionEvent> {\r\n        const pluginRef = this._getPluginReference(body, instanceIndex);\r\n        const bodyId = pluginRef.hpBodyId[0];\r\n        let observable = this._bodyCollisionEndedObservable.get(bodyId);\r\n        if (!observable) {\r\n            observable = new Observable<IBasePhysicsCollisionEvent>();\r\n            this._bodyCollisionEndedObservable.set(bodyId, observable);\r\n        }\r\n        return observable;\r\n    }\r\n\r\n    /**\r\n     * Enable collision to be reported for a body when a callback is setup on the world\r\n     * @param body the physics body\r\n     * @param enabled whether to enable or disable collision events\r\n     */\r\n    public setCollisionCallbackEnabled(body: PhysicsBody, enabled: boolean): void {\r\n        // Register for collide events by default\r\n        const collideEvents = this._hknp.EventType.COLLISION_STARTED.value | this._hknp.EventType.COLLISION_CONTINUED.value | this._hknp.EventType.COLLISION_FINISHED.value;\r\n        if (body._pluginDataInstances && body._pluginDataInstances.length) {\r\n            for (let index = 0; index < body._pluginDataInstances.length; index++) {\r\n                const bodyId = body._pluginDataInstances[index];\r\n                this._hknp.HP_Body_SetEventMask(bodyId.hpBodyId, enabled ? collideEvents : 0);\r\n            }\r\n        } else if (body._pluginData) {\r\n            this._hknp.HP_Body_SetEventMask(body._pluginData.hpBodyId, enabled ? collideEvents : 0);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enable collision ended to be reported for a body when a callback is setup on the world\r\n     * @param body the physics body\r\n     * @param enabled whether to enable or disable collision ended events\r\n     */\r\n    public setCollisionEndedCallbackEnabled(body: PhysicsBody, enabled: boolean): void {\r\n        // Register to collide ended events\r\n        const pluginRef = this._getPluginReference(body);\r\n        let currentCollideEvents = this._hknp.HP_Body_GetEventMask(pluginRef.hpBodyId)[1];\r\n        // update with the ended mask\r\n        currentCollideEvents = enabled\r\n            ? currentCollideEvents | this._hknp.EventType.COLLISION_FINISHED.value\r\n            : currentCollideEvents & ~this._hknp.EventType.COLLISION_FINISHED.value;\r\n        if (body._pluginDataInstances && body._pluginDataInstances.length) {\r\n            for (let index = 0; index < body._pluginDataInstances.length; index++) {\r\n                const bodyId = body._pluginDataInstances[index];\r\n                this._hknp.HP_Body_SetEventMask(bodyId.hpBodyId, currentCollideEvents);\r\n            }\r\n        } else if (body._pluginData) {\r\n            this._hknp.HP_Body_SetEventMask(body._pluginData.hpBodyId, currentCollideEvents);\r\n        }\r\n    }\r\n\r\n    private _notifyTriggers(world?: any) {\r\n        const targetWorld = world ?? this.world;\r\n        let eventAddress = this._hknp.HP_World_GetTriggerEvents(targetWorld)[1];\r\n        const event = new TriggerEvent();\r\n        while (eventAddress) {\r\n            TriggerEvent.readToRef(this._hknp.HEAPU8.buffer, eventAddress, event);\r\n\r\n            const bodyInfoA = this._bodies.get(event.bodyIdA);\r\n            const bodyInfoB = this._bodies.get(event.bodyIdB);\r\n\r\n            // Bodies may have been disposed between events. Check both still exist.\r\n            if (bodyInfoA && bodyInfoB) {\r\n                const triggerCollisionInfo: IBasePhysicsCollisionEvent = {\r\n                    collider: bodyInfoA.body,\r\n                    colliderIndex: bodyInfoA.index,\r\n                    collidedAgainst: bodyInfoB.body,\r\n                    collidedAgainstIndex: bodyInfoB.index,\r\n                    type: this._nativeTriggerCollisionValueToCollisionType(event.type),\r\n                };\r\n                this.onTriggerCollisionObservable.notifyObservers(triggerCollisionInfo);\r\n            }\r\n\r\n            eventAddress = this._hknp.HP_World_GetNextTriggerEvent(targetWorld, eventAddress);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Runs thru all detected collisions and filter by body\r\n     * @param world optional world to check collisions for (defaults to main world)\r\n     */\r\n    private _notifyCollisions(world?: any) {\r\n        const targetWorld = world ?? this.world;\r\n        let eventAddress = this._hknp.HP_World_GetCollisionEvents(targetWorld)[1];\r\n        const event = new CollisionEvent();\r\n        const worldAddr = Number(targetWorld);\r\n\r\n        // Find the region for this world to get the correct floating origin offset.\r\n        // All bodies in a collision share the same world, so use one offset for both.\r\n        const region = this._worldRegions.find((r) => Number(r.world) === worldAddr) ?? this._worldRegions[0];\r\n        const regionOffset = region.floatingOrigin;\r\n\r\n        while (eventAddress) {\r\n            CollisionEvent.readToRef(this._hknp.HEAPU8.buffer, eventAddress, event);\r\n            const bodyInfoA = this._bodies.get(event.contactOnA.bodyId);\r\n            const bodyInfoB = this._bodies.get(event.contactOnB.bodyId);\r\n\r\n            // Add floating origin offset back to collision contact positions.\r\n            // Both contacts are in the same world, so use the region's floating origin.\r\n            event.contactOnA.position.addInPlace(regionOffset);\r\n            event.contactOnB.position.addInPlace(regionOffset);\r\n\r\n            // Bodies may have been disposed between events. Check both still exist.\r\n            if (bodyInfoA && bodyInfoB) {\r\n                const collisionInfo: any = {\r\n                    collider: bodyInfoA.body,\r\n                    colliderIndex: bodyInfoA.index,\r\n                    collidedAgainst: bodyInfoB.body,\r\n                    collidedAgainstIndex: bodyInfoB.index,\r\n                    type: this._nativeCollisionValueToCollisionType(event.type),\r\n                };\r\n                if (collisionInfo.type === PhysicsEventType.COLLISION_FINISHED) {\r\n                    this.onCollisionEndedObservable.notifyObservers(collisionInfo);\r\n                } else {\r\n                    event.contactOnB.position.subtractToRef(event.contactOnA.position, this._tmpVec3[0]);\r\n                    const distance = Vector3.Dot(this._tmpVec3[0], event.contactOnA.normal);\r\n                    collisionInfo.point = event.contactOnA.position;\r\n                    collisionInfo.distance = distance;\r\n                    collisionInfo.impulse = event.impulseApplied;\r\n                    collisionInfo.normal = event.contactOnA.normal;\r\n                    this.onCollisionObservable.notifyObservers(collisionInfo);\r\n                }\r\n\r\n                if (this._bodyCollisionObservable.size && collisionInfo.type !== PhysicsEventType.COLLISION_FINISHED) {\r\n                    const observableA = this._bodyCollisionObservable.get(event.contactOnA.bodyId);\r\n                    const observableB = this._bodyCollisionObservable.get(event.contactOnB.bodyId);\r\n                    event.contactOnA.position.subtractToRef(event.contactOnB.position, this._tmpVec3[0]);\r\n                    const distance = Vector3.Dot(this._tmpVec3[0], event.contactOnB.normal);\r\n                    if (observableA) {\r\n                        observableA.notifyObservers(collisionInfo);\r\n                    }\r\n                    if (observableB) {\r\n                        const collisionInfoB: any = {\r\n                            collider: bodyInfoB.body,\r\n                            colliderIndex: bodyInfoB.index,\r\n                            collidedAgainst: bodyInfoA.body,\r\n                            collidedAgainstIndex: bodyInfoA.index,\r\n                            point: event.contactOnB.position,\r\n                            distance: distance,\r\n                            impulse: event.impulseApplied,\r\n                            normal: event.contactOnB.normal,\r\n                            type: this._nativeCollisionValueToCollisionType(event.type),\r\n                        };\r\n                        observableB.notifyObservers(collisionInfoB);\r\n                    }\r\n                } else if (this._bodyCollisionEndedObservable.size) {\r\n                    const observableA = this._bodyCollisionEndedObservable.get(event.contactOnA.bodyId);\r\n                    const observableB = this._bodyCollisionEndedObservable.get(event.contactOnB.bodyId);\r\n                    event.contactOnA.position.subtractToRef(event.contactOnB.position, this._tmpVec3[0]);\r\n                    const distance = Vector3.Dot(this._tmpVec3[0], event.contactOnB.normal);\r\n                    if (observableA) {\r\n                        observableA.notifyObservers(collisionInfo);\r\n                    }\r\n                    if (observableB) {\r\n                        const collisionInfoB: any = {\r\n                            collider: bodyInfoB.body,\r\n                            colliderIndex: bodyInfoB.index,\r\n                            collidedAgainst: bodyInfoA.body,\r\n                            collidedAgainstIndex: bodyInfoA.index,\r\n                            point: event.contactOnB.position,\r\n                            distance: distance,\r\n                            impulse: event.impulseApplied,\r\n                            normal: event.contactOnB.normal,\r\n                            type: this._nativeCollisionValueToCollisionType(event.type),\r\n                        };\r\n                        observableB.notifyObservers(collisionInfoB);\r\n                    }\r\n                }\r\n            }\r\n\r\n            eventAddress = this._hknp.HP_World_GetNextCollisionEvent(worldAddr, eventAddress);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the number of bodies in the world\r\n     */\r\n    public get numBodies() {\r\n        return this._hknp.HP_World_GetNumBodies(this.world)[1];\r\n    }\r\n\r\n    /**\r\n     * Dispose the world and free resources\r\n     */\r\n    public dispose(): void {\r\n        if (this._queryCollector) {\r\n            this._hknp.HP_QueryCollector_Release(this._queryCollector);\r\n            this._queryCollector = undefined;\r\n        }\r\n        if (this._multiQueryCollector) {\r\n            this._hknp.HP_QueryCollector_Release(this._multiQueryCollector);\r\n            this._multiQueryCollector = undefined;\r\n        }\r\n\r\n        // Dispose all world regions (includes the default world)\r\n        for (const region of this._worldRegions) {\r\n            if (region.world) {\r\n                this._hknp.HP_World_Release(region.world);\r\n            }\r\n        }\r\n        this._worldRegions.length = 0;\r\n        this._worldRegionsPendingRelease.clear();\r\n        this.world = undefined;\r\n    }\r\n\r\n    private _v3ToBvecRef(v: any, vec3: Vector3): void {\r\n        vec3.set(v[0], v[1], v[2]);\r\n    }\r\n\r\n    private _bVecToV3(v: any): any {\r\n        return [v._x, v._y, v._z];\r\n    }\r\n\r\n    /**\r\n     * Converts a Vector3 to Havok format with floating origin offset subtracted.\r\n     * Use this for world-space positions being sent to Havok.\r\n     * @param v - The vector to convert\r\n     * @param offset - Optional offset to use. If not provided, no offset is applied.\r\n     * @returns The converted vector\r\n     */\r\n    private _bVecToV3WithOffset(v: Vector3, offset?: Vector3): any {\r\n        if (offset) {\r\n            return [v._x - offset._x, v._y - offset._y, v._z - offset._z];\r\n        }\r\n        return [v._x, v._y, v._z];\r\n    }\r\n\r\n    private _bQuatToV4(q: Quaternion): Array<number> {\r\n        return [q._x, q._y, q._z, q._w];\r\n    }\r\n\r\n    private _constraintMotorTypeToNative(motorType: PhysicsConstraintMotorType): any {\r\n        switch (motorType) {\r\n            case PhysicsConstraintMotorType.POSITION:\r\n                return this._hknp.ConstraintMotorType.POSITION;\r\n            case PhysicsConstraintMotorType.VELOCITY:\r\n                return this._hknp.ConstraintMotorType.VELOCITY;\r\n        }\r\n        return this._hknp.ConstraintMotorType.NONE;\r\n    }\r\n\r\n    private _nativeToMotorType(motorType: any): PhysicsConstraintMotorType {\r\n        switch (motorType) {\r\n            case this._hknp.ConstraintMotorType.POSITION:\r\n                return PhysicsConstraintMotorType.POSITION;\r\n            case this._hknp.ConstraintMotorType.VELOCITY:\r\n                return PhysicsConstraintMotorType.VELOCITY;\r\n        }\r\n        return PhysicsConstraintMotorType.NONE;\r\n    }\r\n\r\n    private _materialCombineToNative(mat: PhysicsMaterialCombineMode): any {\r\n        switch (mat) {\r\n            case PhysicsMaterialCombineMode.GEOMETRIC_MEAN:\r\n                return this._hknp.MaterialCombine.GEOMETRIC_MEAN;\r\n            case PhysicsMaterialCombineMode.MINIMUM:\r\n                return this._hknp.MaterialCombine.MINIMUM;\r\n            case PhysicsMaterialCombineMode.MAXIMUM:\r\n                return this._hknp.MaterialCombine.MAXIMUM;\r\n            case PhysicsMaterialCombineMode.ARITHMETIC_MEAN:\r\n                return this._hknp.MaterialCombine.ARITHMETIC_MEAN;\r\n            case PhysicsMaterialCombineMode.MULTIPLY:\r\n                return this._hknp.MaterialCombine.MULTIPLY;\r\n        }\r\n    }\r\n\r\n    private _nativeToMaterialCombine(mat: any): PhysicsMaterialCombineMode | undefined {\r\n        switch (mat) {\r\n            case this._hknp.MaterialCombine.GEOMETRIC_MEAN:\r\n                return PhysicsMaterialCombineMode.GEOMETRIC_MEAN;\r\n            case this._hknp.MaterialCombine.MINIMUM:\r\n                return PhysicsMaterialCombineMode.MINIMUM;\r\n            case this._hknp.MaterialCombine.MAXIMUM:\r\n                return PhysicsMaterialCombineMode.MAXIMUM;\r\n            case this._hknp.MaterialCombine.ARITHMETIC_MEAN:\r\n                return PhysicsMaterialCombineMode.ARITHMETIC_MEAN;\r\n            case this._hknp.MaterialCombine.MULTIPLY:\r\n                return PhysicsMaterialCombineMode.MULTIPLY;\r\n            default:\r\n                return undefined;\r\n        }\r\n    }\r\n\r\n    private _constraintAxisToNative(axId: PhysicsConstraintAxis): any {\r\n        switch (axId) {\r\n            case PhysicsConstraintAxis.LINEAR_X:\r\n                return this._hknp.ConstraintAxis.LINEAR_X;\r\n            case PhysicsConstraintAxis.LINEAR_Y:\r\n                return this._hknp.ConstraintAxis.LINEAR_Y;\r\n            case PhysicsConstraintAxis.LINEAR_Z:\r\n                return this._hknp.ConstraintAxis.LINEAR_Z;\r\n            case PhysicsConstraintAxis.ANGULAR_X:\r\n                return this._hknp.ConstraintAxis.ANGULAR_X;\r\n            case PhysicsConstraintAxis.ANGULAR_Y:\r\n                return this._hknp.ConstraintAxis.ANGULAR_Y;\r\n            case PhysicsConstraintAxis.ANGULAR_Z:\r\n                return this._hknp.ConstraintAxis.ANGULAR_Z;\r\n            case PhysicsConstraintAxis.LINEAR_DISTANCE:\r\n                return this._hknp.ConstraintAxis.LINEAR_DISTANCE;\r\n        }\r\n    }\r\n\r\n    private _nativeToLimitMode(mode: number): PhysicsConstraintAxisLimitMode {\r\n        switch (mode) {\r\n            case this._hknp.ConstraintAxisLimitMode.FREE:\r\n                return PhysicsConstraintAxisLimitMode.FREE;\r\n            case this._hknp.ConstraintAxisLimitMode.LIMITED:\r\n                return PhysicsConstraintAxisLimitMode.LIMITED;\r\n            case this._hknp.ConstraintAxisLimitMode.LOCKED:\r\n                return PhysicsConstraintAxisLimitMode.LOCKED;\r\n        }\r\n\r\n        return PhysicsConstraintAxisLimitMode.FREE;\r\n    }\r\n\r\n    private _limitModeToNative(mode: PhysicsConstraintAxisLimitMode): any {\r\n        switch (mode) {\r\n            case PhysicsConstraintAxisLimitMode.FREE:\r\n                return this._hknp.ConstraintAxisLimitMode.FREE;\r\n            case PhysicsConstraintAxisLimitMode.LIMITED:\r\n                return this._hknp.ConstraintAxisLimitMode.LIMITED;\r\n            case PhysicsConstraintAxisLimitMode.LOCKED:\r\n                return this._hknp.ConstraintAxisLimitMode.LOCKED;\r\n        }\r\n    }\r\n\r\n    private _nativeCollisionValueToCollisionType(type: number): PhysicsEventType {\r\n        switch (type) {\r\n            case this._hknp.EventType.COLLISION_STARTED.value:\r\n                return PhysicsEventType.COLLISION_STARTED;\r\n            case this._hknp.EventType.COLLISION_FINISHED.value:\r\n                return PhysicsEventType.COLLISION_FINISHED;\r\n            case this._hknp.EventType.COLLISION_CONTINUED.value:\r\n                return PhysicsEventType.COLLISION_CONTINUED;\r\n        }\r\n\r\n        return PhysicsEventType.COLLISION_STARTED;\r\n    }\r\n\r\n    private _nativeTriggerCollisionValueToCollisionType(type: number): PhysicsEventType {\r\n        switch (type) {\r\n            case 8:\r\n                return PhysicsEventType.TRIGGER_ENTERED;\r\n            case 16:\r\n                return PhysicsEventType.TRIGGER_EXITED;\r\n        }\r\n        return PhysicsEventType.TRIGGER_ENTERED;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type PhysicsBody } from \"./physicsBody\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for physicsV2PhysicsEngineComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterPhysicsV2PhysicsEngineComponent(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(TransformNode.prototype, \"physicsBody\", {\r\n        get: function (this: TransformNode) {\r\n            return this._physicsBody;\r\n        },\r\n        set: function (this: TransformNode, value: Nullable<PhysicsBody>) {\r\n            if (this._physicsBody === value) {\r\n                return;\r\n            }\r\n            if (this._disposePhysicsObserver) {\r\n                this.onDisposeObservable.remove(this._disposePhysicsObserver);\r\n            }\r\n\r\n            this._physicsBody = value;\r\n\r\n            if (value) {\r\n                this._disposePhysicsObserver = this.onDisposeObservable.add(() => {\r\n                    // Physics\r\n                    if (this.physicsBody) {\r\n                        this.physicsBody.dispose(/*!doNotRecurse*/);\r\n                        this.physicsBody = null;\r\n                    }\r\n                });\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    /**\r\n     * Gets the current physics body\r\n     * @returns a physics body or null\r\n     */\r\n    TransformNode.prototype.getPhysicsBody = function (): Nullable<PhysicsBody> {\r\n        return this.physicsBody;\r\n    };\r\n\r\n    /**\r\n     * Apply a physic impulse to the mesh\r\n     * @param force defines the force to apply\r\n     * @param contactPoint defines where to apply the force\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n     */\r\n    TransformNode.prototype.applyImpulse = function (force: Vector3, contactPoint: Vector3): TransformNode {\r\n        if (!this.physicsBody) {\r\n            throw new Error(\"No Physics Body for TransformNode\");\r\n        }\r\n        this.physicsBody.applyImpulse(force, contactPoint);\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Apply a physic angular impulse to the mesh\r\n     * @param angularImpulse defines the torque to apply\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n     */\r\n    TransformNode.prototype.applyAngularImpulse = function (angularImpulse: Vector3): TransformNode {\r\n        if (!this.physicsBody) {\r\n            throw new Error(\"No Physics Body for TransformNode\");\r\n        }\r\n        this.physicsBody.applyAngularImpulse(angularImpulse);\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Apply a physic torque to the mesh\r\n     * @param torque defines the torque to apply\r\n     * @returns the current mesh\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine\r\n     */\r\n    TransformNode.prototype.applyTorque = function (torque: Vector3): TransformNode {\r\n        if (!this.physicsBody) {\r\n            throw new Error(\"No Physics Body for TransformNode\");\r\n        }\r\n        this.physicsBody.applyTorque(torque);\r\n        return this;\r\n    };\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { TmpVectors, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { type Mesh } from \"../Meshes/mesh\";\r\nimport { CreateSphere } from \"../Meshes/Builders/sphereBuilder.pure\";\r\nimport { CreateCylinder } from \"../Meshes/Builders/cylinderBuilder.pure\";\r\nimport { Ray } from \"../Culling/ray.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type PhysicsEngine as PhysicsEngineV1 } from \"./physicsEngine\";\r\nimport { type PhysicsEngine as PhysicsEngineV2 } from \"./v2/physicsEngine\";\r\nimport { type IPhysicsEngine } from \"./IPhysicsEngine\";\r\nimport { type PhysicsImpostor } from \"./v1/physicsImpostor\";\r\nimport { type PhysicsBody } from \"./v2/physicsBody\";\r\nimport { PhysicsMotionType } from \"./v2/IPhysicsEnginePlugin\";\r\n\r\nclass HelperTools {\r\n    /*\r\n     * Gets the hit contact point between a mesh and a ray. The method varies between\r\n     * the different plugin versions; V1 uses a mesh intersection, V2 uses the physics body instance/object center (to avoid a raycast and improve perf).\r\n     */\r\n    static GetContactPointToRef(mesh: AbstractMesh, origin: Vector3, direction: Vector3, result: Vector3, instanceIndex?: number): boolean {\r\n        const engine = mesh.getScene().getPhysicsEngine();\r\n        const pluginVersion = engine?.getPluginVersion();\r\n        if (pluginVersion === 1) {\r\n            const ray = new Ray(origin, direction);\r\n            const hit = ray.intersectsMesh(mesh);\r\n            if (hit.hit && hit.pickedPoint) {\r\n                result.copyFrom(hit.pickedPoint);\r\n                return true;\r\n            }\r\n        } else if (pluginVersion === 2) {\r\n            mesh.physicsBody!.getObjectCenterWorldToRef(result, instanceIndex);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Checks if a body will be affected by forces\r\n     * @param body the body to check\r\n     * @param instanceIndex for instanced bodies, the index of the instance to check\r\n     * @returns\r\n     */\r\n    static HasAppliedForces(body: PhysicsBody, instanceIndex?: number) {\r\n        const mesh = body.transformNode as Mesh;\r\n        return (\r\n            body.getMotionType(instanceIndex) === PhysicsMotionType.STATIC ||\r\n            (body.getMassProperties(instanceIndex)?.mass ?? 0) === 0 ||\r\n            (mesh && mesh.getTotalVertices && mesh.getTotalVertices() === 0)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Checks if a point is inside a cylinder\r\n     * @param point point to check\r\n     * @param origin cylinder origin on the bottom\r\n     * @param radius cylinder radius\r\n     * @param height cylinder height\r\n     * @returns\r\n     */\r\n    static IsInsideCylinder(point: Vector3, origin: Vector3, radius: number, height: number): boolean {\r\n        const distance = TmpVectors.Vector3[0];\r\n        point.subtractToRef(origin, distance);\r\n        return Math.abs(distance.x) <= radius && Math.abs(distance.z) <= radius && distance.y >= 0 && distance.y <= height;\r\n    }\r\n}\r\n\r\n/**\r\n * A helper for physics simulations\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\nexport class PhysicsHelper {\r\n    private _scene: Scene;\r\n    private _physicsEngine: Nullable<IPhysicsEngine>;\r\n    private _hitData: PhysicsHitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };\r\n\r\n    /**\r\n     * Initializes the Physics helper\r\n     * @param scene Babylon.js scene\r\n     */\r\n    constructor(scene: Scene) {\r\n        this._scene = scene;\r\n        this._physicsEngine = this._scene.getPhysicsEngine();\r\n\r\n        if (!this._physicsEngine) {\r\n            Logger.Warn(\"Physics engine not enabled. Please enable the physics before you can use the methods.\");\r\n            return;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Applies a radial explosion impulse\r\n     * @param origin the origin of the explosion\r\n     * @param radiusOrEventOptions the radius or the options of radial explosion\r\n     * @param strength the explosion strength\r\n     * @param falloff possible options: Constant & Linear. Defaults to Constant\r\n     * @returns A physics radial explosion event, or null\r\n     */\r\n    public applyRadialExplosionImpulse(\r\n        origin: Vector3,\r\n        radiusOrEventOptions: number | PhysicsRadialExplosionEventOptions,\r\n        strength?: number,\r\n        falloff?: PhysicsRadialImpulseFalloff\r\n    ): Nullable<PhysicsRadialExplosionEvent> {\r\n        if (!this._physicsEngine) {\r\n            Logger.Warn(\"Physics engine not enabled. Please enable the physics before you call this method.\");\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1 && (<PhysicsEngineV1>this._physicsEngine).getImpostors().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 2 && (<PhysicsEngineV2>this._physicsEngine).getBodies().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        let useCallback = false;\r\n        if (typeof radiusOrEventOptions === \"number\") {\r\n            const r = radiusOrEventOptions;\r\n            radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();\r\n            radiusOrEventOptions.radius = r;\r\n            radiusOrEventOptions.strength = strength ?? radiusOrEventOptions.strength;\r\n            radiusOrEventOptions.falloff = falloff ?? radiusOrEventOptions.falloff;\r\n        } else {\r\n            useCallback = !!(radiusOrEventOptions.affectedImpostorsCallback || radiusOrEventOptions.affectedBodiesCallback);\r\n        }\r\n\r\n        const event = new PhysicsRadialExplosionEvent(this._scene, radiusOrEventOptions);\r\n\r\n        const hitData = this._hitData;\r\n        if (this._physicsEngine.getPluginVersion() === 1) {\r\n            const affectedImpostorsWithData = Array<PhysicsAffectedImpostorWithData>();\r\n            const impostors = (<PhysicsEngineV1>this._physicsEngine).getImpostors();\r\n            for (const impostor of impostors) {\r\n                if (!event.getImpostorHitData(impostor, origin, hitData)) {\r\n                    continue;\r\n                }\r\n\r\n                impostor.applyImpulse(hitData.force, hitData.contactPoint);\r\n\r\n                if (useCallback) {\r\n                    affectedImpostorsWithData.push({\r\n                        impostor: impostor,\r\n                        hitData: this._copyPhysicsHitData(hitData),\r\n                    });\r\n                }\r\n            }\r\n\r\n            event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);\r\n        } else {\r\n            this._applicationForBodies(event, origin, hitData, useCallback, (body: PhysicsBody, hitData: PhysicsHitData) => {\r\n                body.applyImpulse(hitData.force, hitData.contactPoint, hitData.instanceIndex);\r\n            });\r\n        }\r\n\r\n        event.dispose(false);\r\n\r\n        return event;\r\n    }\r\n\r\n    /**\r\n     * Applies a radial explosion force\r\n     * @param origin the origin of the explosion\r\n     * @param radiusOrEventOptions the radius or the options of radial explosion\r\n     * @param strength the explosion strength\r\n     * @param falloff possible options: Constant & Linear. Defaults to Constant\r\n     * @returns A physics radial explosion event, or null\r\n     */\r\n    public applyRadialExplosionForce(\r\n        origin: Vector3,\r\n        radiusOrEventOptions: number | PhysicsRadialExplosionEventOptions,\r\n        strength?: number,\r\n        falloff?: PhysicsRadialImpulseFalloff\r\n    ): Nullable<PhysicsRadialExplosionEvent> {\r\n        if (!this._physicsEngine) {\r\n            Logger.Warn(\"Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.\");\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1 && (<PhysicsEngineV1>this._physicsEngine).getImpostors().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 2 && (<PhysicsEngineV2>this._physicsEngine).getBodies().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        let useCallback = false;\r\n        if (typeof radiusOrEventOptions === \"number\") {\r\n            const r = radiusOrEventOptions;\r\n            radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();\r\n            radiusOrEventOptions.radius = r;\r\n            radiusOrEventOptions.strength = strength ?? radiusOrEventOptions.strength;\r\n            radiusOrEventOptions.falloff = falloff ?? radiusOrEventOptions.falloff;\r\n        } else {\r\n            useCallback = !!(radiusOrEventOptions.affectedImpostorsCallback || radiusOrEventOptions.affectedBodiesCallback);\r\n        }\r\n\r\n        const event = new PhysicsRadialExplosionEvent(this._scene, radiusOrEventOptions);\r\n\r\n        const hitData = this._hitData;\r\n        if (this._physicsEngine.getPluginVersion() === 1) {\r\n            const affectedImpostorsWithData = Array<PhysicsAffectedImpostorWithData>();\r\n            const impostors = (<PhysicsEngineV1>this._physicsEngine).getImpostors();\r\n            for (const impostor of impostors) {\r\n                if (!event.getImpostorHitData(impostor, origin, hitData)) {\r\n                    continue;\r\n                }\r\n\r\n                impostor.applyForce(hitData.force, hitData.contactPoint);\r\n\r\n                if (useCallback) {\r\n                    affectedImpostorsWithData.push({\r\n                        impostor: impostor,\r\n                        hitData: this._copyPhysicsHitData(hitData),\r\n                    });\r\n                }\r\n            }\r\n\r\n            event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);\r\n        } else {\r\n            this._applicationForBodies(event, origin, hitData, useCallback, (body: PhysicsBody, hitData: PhysicsHitData) => {\r\n                body.applyForce(hitData.force, hitData.contactPoint, hitData.instanceIndex);\r\n            });\r\n        }\r\n\r\n        event.dispose(false);\r\n\r\n        return event;\r\n    }\r\n\r\n    private _applicationForBodies(\r\n        event: PhysicsRadialExplosionEvent,\r\n        origin: Vector3,\r\n        hitData: PhysicsHitData,\r\n        useCallback: boolean,\r\n        fnApplication: (body: PhysicsBody, hitData: PhysicsHitData, instanceIndex?: number) => void\r\n    ) {\r\n        const affectedBodiesWithData = Array<PhysicsAffectedBodyWithData>();\r\n        const bodies = (<PhysicsEngineV2>this._physicsEngine).getBodies();\r\n        for (const body of bodies) {\r\n            body.iterateOverAllInstances((body, instanceIndex) => {\r\n                if (!event.getBodyHitData(body, origin, hitData, instanceIndex)) {\r\n                    return;\r\n                }\r\n                fnApplication(body, hitData);\r\n\r\n                if (useCallback) {\r\n                    affectedBodiesWithData.push({\r\n                        body: body,\r\n                        hitData: this._copyPhysicsHitData(hitData),\r\n                    });\r\n                }\r\n            });\r\n        }\r\n\r\n        event.triggerAffectedBodiesCallback(affectedBodiesWithData);\r\n    }\r\n\r\n    /**\r\n     * Creates a gravitational field\r\n     * @param origin the origin of the gravitational field\r\n     * @param radiusOrEventOptions the radius or the options of radial gravitational field\r\n     * @param strength the gravitational field strength\r\n     * @param falloff possible options: Constant & Linear. Defaults to Constant\r\n     * @returns A physics gravitational field event, or null\r\n     */\r\n    public gravitationalField(\r\n        origin: Vector3,\r\n        radiusOrEventOptions: number | PhysicsRadialExplosionEventOptions,\r\n        strength?: number,\r\n        falloff?: PhysicsRadialImpulseFalloff\r\n    ): Nullable<PhysicsGravitationalFieldEvent> {\r\n        if (!this._physicsEngine) {\r\n            Logger.Warn(\"Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.\");\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1 && (<PhysicsEngineV1>this._physicsEngine).getImpostors().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 2 && (<PhysicsEngineV2>this._physicsEngine).getBodies().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (typeof radiusOrEventOptions === \"number\") {\r\n            const r = radiusOrEventOptions;\r\n            radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();\r\n            radiusOrEventOptions.radius = r;\r\n            radiusOrEventOptions.strength = strength ?? radiusOrEventOptions.strength;\r\n            radiusOrEventOptions.falloff = falloff ?? radiusOrEventOptions.falloff;\r\n        }\r\n\r\n        const event = new PhysicsGravitationalFieldEvent(this, this._scene, origin, radiusOrEventOptions);\r\n\r\n        event.dispose(false);\r\n\r\n        return event;\r\n    }\r\n\r\n    /**\r\n     * Creates a physics updraft event\r\n     * @param origin the origin of the updraft\r\n     * @param radiusOrEventOptions the radius or the options of the updraft\r\n     * @param strength the strength of the updraft\r\n     * @param height the height of the updraft\r\n     * @param updraftMode possible options: Center & Perpendicular. Defaults to Center\r\n     * @returns A physics updraft event, or null\r\n     */\r\n    public updraft(\r\n        origin: Vector3,\r\n        radiusOrEventOptions: number | PhysicsUpdraftEventOptions,\r\n        strength?: number,\r\n        height?: number,\r\n        updraftMode?: PhysicsUpdraftMode\r\n    ): Nullable<PhysicsUpdraftEvent> {\r\n        if (!this._physicsEngine) {\r\n            Logger.Warn(\"Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.\");\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1 && (<PhysicsEngineV1>this._physicsEngine).getImpostors().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 2 && (<PhysicsEngineV2>this._physicsEngine).getBodies().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (typeof radiusOrEventOptions === \"number\") {\r\n            const r = radiusOrEventOptions;\r\n            radiusOrEventOptions = new PhysicsUpdraftEventOptions();\r\n            radiusOrEventOptions.radius = r;\r\n            radiusOrEventOptions.strength = strength ?? radiusOrEventOptions.strength;\r\n            radiusOrEventOptions.height = height ?? radiusOrEventOptions.height;\r\n            radiusOrEventOptions.updraftMode = updraftMode ?? radiusOrEventOptions.updraftMode;\r\n        }\r\n\r\n        const event = new PhysicsUpdraftEvent(this._scene, origin, radiusOrEventOptions);\r\n\r\n        event.dispose(false);\r\n\r\n        return event;\r\n    }\r\n\r\n    /**\r\n     * Creates a physics vortex event\r\n     * @param origin the of the vortex\r\n     * @param radiusOrEventOptions the radius or the options of the vortex\r\n     * @param strength the strength of the vortex\r\n     * @param height   the height of the vortex\r\n     * @returns a Physics vortex event, or null\r\n     * A physics vortex event or null\r\n     */\r\n    public vortex(origin: Vector3, radiusOrEventOptions: number | PhysicsVortexEventOptions, strength?: number, height?: number): Nullable<PhysicsVortexEvent> {\r\n        if (!this._physicsEngine) {\r\n            Logger.Warn(\"Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.\");\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1 && (<PhysicsEngineV1>this._physicsEngine).getImpostors().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 2 && (<PhysicsEngineV2>this._physicsEngine).getBodies().length === 0) {\r\n            return null;\r\n        }\r\n\r\n        if (typeof radiusOrEventOptions === \"number\") {\r\n            const r = radiusOrEventOptions;\r\n            radiusOrEventOptions = new PhysicsVortexEventOptions();\r\n            radiusOrEventOptions.radius = r;\r\n            radiusOrEventOptions.strength = strength ?? radiusOrEventOptions.strength;\r\n            radiusOrEventOptions.height = height ?? radiusOrEventOptions.height;\r\n        }\r\n\r\n        const event = new PhysicsVortexEvent(this._scene, origin, radiusOrEventOptions);\r\n\r\n        event.dispose(false);\r\n\r\n        return event;\r\n    }\r\n\r\n    private _copyPhysicsHitData(data: PhysicsHitData): PhysicsHitData {\r\n        return { force: data.force.clone(), contactPoint: data.contactPoint.clone(), distanceFromOrigin: data.distanceFromOrigin, instanceIndex: data.instanceIndex };\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a physics radial explosion event\r\n */\r\nclass PhysicsRadialExplosionEvent {\r\n    private _sphere: Mesh; // create a sphere, so we can get the intersecting meshes inside\r\n    private _dataFetched: boolean = false; // check if the data has been fetched. If not, do cleanup\r\n\r\n    /**\r\n     * Initializes a radial explosion event\r\n     * @param _scene BabylonJS scene\r\n     * @param _options The options for the vortex event\r\n     */\r\n    constructor(\r\n        private _scene: Scene,\r\n        private _options: PhysicsRadialExplosionEventOptions\r\n    ) {\r\n        this._options = { ...new PhysicsRadialExplosionEventOptions(), ...this._options };\r\n    }\r\n\r\n    /**\r\n     * Returns the data related to the radial explosion event (sphere).\r\n     * @returns The radial explosion event data\r\n     */\r\n    public getData(): PhysicsRadialExplosionEventData {\r\n        this._dataFetched = true;\r\n\r\n        return {\r\n            sphere: this._sphere,\r\n        };\r\n    }\r\n\r\n    private _getHitData(mesh: AbstractMesh, center: Vector3, origin: Vector3, data: PhysicsHitData): boolean {\r\n        const direction = TmpVectors.Vector3[0];\r\n        direction.copyFrom(center).subtractInPlace(origin);\r\n\r\n        const contactPoint = TmpVectors.Vector3[1];\r\n        const hasContactPoint = HelperTools.GetContactPointToRef(mesh, origin, direction, contactPoint, data.instanceIndex);\r\n\r\n        if (!hasContactPoint) {\r\n            return false;\r\n        }\r\n\r\n        const distanceFromOrigin = Vector3.Distance(origin, contactPoint);\r\n        if (distanceFromOrigin > this._options.radius) {\r\n            return false;\r\n        }\r\n\r\n        const multiplier =\r\n            this._options.falloff === PhysicsRadialImpulseFalloff.Constant ? this._options.strength : this._options.strength * (1 - distanceFromOrigin / this._options.radius);\r\n\r\n        // Direction x multiplier equals force\r\n        direction.scaleInPlace(multiplier);\r\n\r\n        data.force.copyFrom(direction);\r\n        data.contactPoint.copyFrom(contactPoint);\r\n        data.distanceFromOrigin = distanceFromOrigin;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Returns the force and contact point of the body or false, if the body is not affected by the force/impulse.\r\n     * @param body A physics body where the transform node is an AbstractMesh\r\n     * @param origin the origin of the explosion\r\n     * @param data the data of the hit\r\n     * @param instanceIndex the instance index of the body\r\n     * @returns if there was a hit\r\n     */\r\n    public getBodyHitData(body: PhysicsBody, origin: Vector3, data: PhysicsHitData, instanceIndex?: number): boolean {\r\n        // No force will be applied in these cases, so we skip calculation\r\n        if (HelperTools.HasAppliedForces(body, instanceIndex)) {\r\n            return false;\r\n        }\r\n\r\n        const mesh = body.transformNode as AbstractMesh;\r\n        const bodyObjectCenter = body.getObjectCenterWorld(instanceIndex);\r\n        data.instanceIndex = instanceIndex;\r\n        return this._getHitData(mesh, bodyObjectCenter, origin, data);\r\n    }\r\n    /**\r\n     * Returns the force and contact point of the impostor or false, if the impostor is not affected by the force/impulse.\r\n     * @param impostor A physics imposter\r\n     * @param origin the origin of the explosion\r\n     * @param data the data of the hit\r\n     * @returns A physics force and contact point, or null\r\n     */\r\n    public getImpostorHitData(impostor: PhysicsImpostor, origin: Vector3, data: PhysicsHitData): boolean {\r\n        if (impostor.mass === 0) {\r\n            return false;\r\n        }\r\n\r\n        if (impostor.object.getClassName() !== \"Mesh\" && impostor.object.getClassName() !== \"InstancedMesh\") {\r\n            return false;\r\n        }\r\n\r\n        const mesh = impostor.object as AbstractMesh;\r\n        if (!this._intersectsWithSphere(mesh, origin, this._options.radius)) {\r\n            return false;\r\n        }\r\n\r\n        const impostorObjectCenter = impostor.getObjectCenter();\r\n\r\n        this._getHitData(mesh, impostorObjectCenter, origin, data);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Triggers affected impostors callbacks\r\n     * @param affectedImpostorsWithData defines the list of affected impostors (including associated data)\r\n     */\r\n    public triggerAffectedImpostorsCallback(affectedImpostorsWithData: Array<PhysicsAffectedImpostorWithData>) {\r\n        if (this._options.affectedImpostorsCallback) {\r\n            this._options.affectedImpostorsCallback(affectedImpostorsWithData);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Triggers affected bodies callbacks\r\n     * @param affectedBodiesWithData defines the list of affected bodies (including associated data)\r\n     */\r\n    public triggerAffectedBodiesCallback(affectedBodiesWithData: Array<PhysicsAffectedBodyWithData>) {\r\n        if (this._options.affectedBodiesCallback) {\r\n            this._options.affectedBodiesCallback(affectedBodiesWithData);\r\n        }\r\n    }\r\n    /**\r\n     * Disposes the sphere.\r\n     * @param force Specifies if the sphere should be disposed by force\r\n     */\r\n    public dispose(force: boolean = true) {\r\n        if (this._sphere) {\r\n            if (force) {\r\n                this._sphere.dispose();\r\n            } else {\r\n                setTimeout(() => {\r\n                    if (!this._dataFetched) {\r\n                        this._sphere.dispose();\r\n                    }\r\n                }, 0);\r\n            }\r\n        }\r\n    }\r\n\r\n    /*** Helpers ***/\r\n\r\n    private _prepareSphere(): void {\r\n        if (!this._sphere) {\r\n            this._sphere = CreateSphere(\"radialExplosionEventSphere\", this._options.sphere, this._scene);\r\n            this._sphere.isVisible = false;\r\n        }\r\n    }\r\n\r\n    private _intersectsWithSphere(mesh: AbstractMesh, origin: Vector3, radius: number): boolean {\r\n        this._prepareSphere();\r\n\r\n        this._sphere.position = origin;\r\n        this._sphere.scaling.setAll(radius * 2);\r\n        this._sphere._updateBoundingInfo();\r\n        this._sphere.computeWorldMatrix(true);\r\n\r\n        return this._sphere.intersectsMesh(mesh, true);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a gravitational field event\r\n */\r\nclass PhysicsGravitationalFieldEvent {\r\n    private _tickCallback: any;\r\n    private _sphere: Mesh;\r\n    private _dataFetched: boolean = false; // check if the has been fetched the data. If not, do cleanup\r\n\r\n    /**\r\n     * Initializes the physics gravitational field event\r\n     * @param _physicsHelper A physics helper\r\n     * @param _scene BabylonJS scene\r\n     * @param _origin The origin position of the gravitational field event\r\n     * @param _options The options for the vortex event\r\n     */\r\n    constructor(\r\n        private _physicsHelper: PhysicsHelper,\r\n        private _scene: Scene,\r\n        private _origin: Vector3,\r\n        private _options: PhysicsRadialExplosionEventOptions\r\n    ) {\r\n        this._options = { ...new PhysicsRadialExplosionEventOptions(), ...this._options };\r\n\r\n        this._tickCallback = () => this._tick();\r\n\r\n        this._options.strength = this._options.strength * -1;\r\n    }\r\n\r\n    /**\r\n     * Returns the data related to the gravitational field event (sphere).\r\n     * @returns A gravitational field event\r\n     */\r\n    public getData(): PhysicsGravitationalFieldEventData {\r\n        this._dataFetched = true;\r\n\r\n        return {\r\n            sphere: this._sphere,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Enables the gravitational field.\r\n     */\r\n    public enable() {\r\n        this._tickCallback.call(this);\r\n        this._scene.registerBeforeRender(this._tickCallback);\r\n    }\r\n\r\n    /**\r\n     * Disables the gravitational field.\r\n     */\r\n    public disable() {\r\n        this._scene.unregisterBeforeRender(this._tickCallback);\r\n    }\r\n\r\n    /**\r\n     * Disposes the sphere.\r\n     * @param force The force to dispose from the gravitational field event\r\n     */\r\n    public dispose(force: boolean = true) {\r\n        if (!this._sphere) {\r\n            return;\r\n        }\r\n        if (force) {\r\n            this._sphere.dispose();\r\n        } else {\r\n            setTimeout(() => {\r\n                if (!this._dataFetched) {\r\n                    this._sphere.dispose();\r\n                }\r\n            }, 0);\r\n        }\r\n    }\r\n\r\n    private _tick() {\r\n        // Since the params won't change, we fetch the event only once\r\n        if (this._sphere) {\r\n            this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);\r\n        } else {\r\n            const radialExplosionEvent = this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);\r\n            if (radialExplosionEvent) {\r\n                this._sphere = radialExplosionEvent.getData().sphere?.clone(\"radialExplosionEventSphereClone\");\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a physics updraft event\r\n */\r\nclass PhysicsUpdraftEvent {\r\n    private _physicsEngine: PhysicsEngineV1 | PhysicsEngineV2;\r\n    private _originTop: Vector3 = Vector3.Zero(); // the most upper part of the cylinder\r\n    private _originDirection: Vector3 = Vector3.Zero(); // used if the updraftMode is perpendicular\r\n    private _tickCallback: any;\r\n    private _cylinder: Mesh | undefined;\r\n    private _cylinderPosition: Vector3 = Vector3.Zero(); // to keep the cylinders position, because normally the origin is in the center and not on the bottom\r\n    private _dataFetched: boolean = false; // check if the has been fetched the data. If not, do cleanup\r\n    private static _HitData: PhysicsHitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };\r\n    /**\r\n     * Initializes the physics updraft event\r\n     * @param _scene BabylonJS scene\r\n     * @param _origin The origin position of the updraft\r\n     * @param _options The options for the updraft event\r\n     */\r\n    constructor(\r\n        private _scene: Scene,\r\n        private _origin: Vector3,\r\n        private _options: PhysicsUpdraftEventOptions\r\n    ) {\r\n        this._physicsEngine = this._scene.getPhysicsEngine() as PhysicsEngineV1 | PhysicsEngineV2;\r\n        this._options = { ...new PhysicsUpdraftEventOptions(), ...this._options };\r\n\r\n        this._origin.addToRef(new Vector3(0, this._options.height / 2, 0), this._cylinderPosition);\r\n        this._origin.addToRef(new Vector3(0, this._options.height, 0), this._originTop);\r\n\r\n        if (this._options.updraftMode === PhysicsUpdraftMode.Perpendicular) {\r\n            this._originDirection = this._origin.subtract(this._originTop).normalize();\r\n        }\r\n\r\n        this._tickCallback = () => this._tick();\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1) {\r\n            this._prepareCylinder();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the data related to the updraft event (cylinder).\r\n     * @returns A physics updraft event\r\n     */\r\n    public getData(): PhysicsUpdraftEventData {\r\n        this._dataFetched = true;\r\n\r\n        return {\r\n            cylinder: this._cylinder,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Enables the updraft.\r\n     */\r\n    public enable() {\r\n        this._tickCallback.call(this);\r\n        this._scene.registerBeforeRender(this._tickCallback);\r\n    }\r\n\r\n    /**\r\n     * Disables the updraft.\r\n     */\r\n    public disable() {\r\n        this._scene.unregisterBeforeRender(this._tickCallback);\r\n    }\r\n\r\n    /**\r\n     * Disposes the cylinder.\r\n     * @param force Specifies if the updraft should be disposed by force\r\n     */\r\n    public dispose(force: boolean = true) {\r\n        if (!this._cylinder) {\r\n            return;\r\n        }\r\n        if (force) {\r\n            this._cylinder.dispose();\r\n            this._cylinder = undefined;\r\n        } else {\r\n            setTimeout(() => {\r\n                if (!this._dataFetched && this._cylinder) {\r\n                    this._cylinder.dispose();\r\n                    this._cylinder = undefined;\r\n                }\r\n            }, 0);\r\n        }\r\n    }\r\n\r\n    private _getHitData(center: Vector3, data: PhysicsHitData): void {\r\n        let direction: Vector3;\r\n        if (this._options.updraftMode === PhysicsUpdraftMode.Perpendicular) {\r\n            direction = this._originDirection;\r\n        } else {\r\n            direction = center.subtract(this._originTop);\r\n        }\r\n\r\n        const distanceFromOrigin = Vector3.Distance(this._origin, center);\r\n\r\n        const multiplier = this._options.strength * -1;\r\n\r\n        const force = direction.multiplyByFloats(multiplier, multiplier, multiplier);\r\n\r\n        data.force.copyFrom(force);\r\n        data.contactPoint.copyFrom(center);\r\n        data.distanceFromOrigin = distanceFromOrigin;\r\n    }\r\n\r\n    private _getBodyHitData(body: PhysicsBody, data: PhysicsHitData, instanceIndex?: number): boolean {\r\n        if (HelperTools.HasAppliedForces(body, instanceIndex)) {\r\n            return false;\r\n        }\r\n\r\n        const center = body.getObjectCenterWorld(instanceIndex);\r\n\r\n        if (!HelperTools.IsInsideCylinder(center, this._origin, this._options.radius, this._options.height)) {\r\n            return false;\r\n        }\r\n\r\n        data.instanceIndex = instanceIndex;\r\n        this._getHitData(center, data);\r\n        return true;\r\n    }\r\n\r\n    private _getImpostorHitData(impostor: PhysicsImpostor, data: PhysicsHitData): boolean {\r\n        if (impostor.mass === 0) {\r\n            return false;\r\n        }\r\n\r\n        const impostorObject = <AbstractMesh>impostor.object;\r\n        if (!this._intersectsWithCylinder(impostorObject)) {\r\n            return false;\r\n        }\r\n\r\n        const center = impostor.getObjectCenter();\r\n        this._getHitData(center, data);\r\n        return true;\r\n    }\r\n\r\n    private _tick() {\r\n        const hitData = PhysicsUpdraftEvent._HitData;\r\n        if (this._physicsEngine.getPluginVersion() === 1) {\r\n            const impostors = (<PhysicsEngineV1>this._physicsEngine).getImpostors();\r\n            for (const impostor of impostors) {\r\n                if (!this._getImpostorHitData(impostor, hitData)) {\r\n                    continue;\r\n                }\r\n\r\n                impostor.applyForce(hitData.force, hitData.contactPoint);\r\n            }\r\n        } else {\r\n            // V2\r\n            const bodies = (<PhysicsEngineV2>this._physicsEngine).getBodies();\r\n            for (const body of bodies) {\r\n                body.iterateOverAllInstances((body, instanceIndex) => {\r\n                    if (!this._getBodyHitData(body, hitData, instanceIndex)) {\r\n                        return;\r\n                    }\r\n\r\n                    body.applyForce(hitData.force, hitData.contactPoint, hitData.instanceIndex);\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    /*** Helpers ***/\r\n\r\n    private _prepareCylinder(): void {\r\n        if (!this._cylinder) {\r\n            this._cylinder = CreateCylinder(\r\n                \"updraftEventCylinder\",\r\n                {\r\n                    height: this._options.height,\r\n                    diameter: this._options.radius * 2,\r\n                },\r\n                this._scene\r\n            );\r\n            this._cylinder.isVisible = false;\r\n        }\r\n    }\r\n\r\n    private _intersectsWithCylinder(mesh: AbstractMesh): boolean {\r\n        if (!this._cylinder) {\r\n            return false;\r\n        }\r\n        this._cylinder.position = this._cylinderPosition;\r\n        return this._cylinder.intersectsMesh(mesh, true);\r\n    }\r\n}\r\n\r\n/**\r\n * Represents a physics vortex event\r\n */\r\nclass PhysicsVortexEvent {\r\n    private _physicsEngine: PhysicsEngineV1 | PhysicsEngineV2;\r\n    private _originTop: Vector3 = Vector3.Zero(); // the most upper part of the cylinder\r\n    private _tickCallback: any;\r\n    private _cylinder: Mesh;\r\n    private _cylinderPosition: Vector3 = Vector3.Zero(); // to keep the cylinders position, because normally the origin is in the center and not on the bottom\r\n    private _dataFetched: boolean = false; // check if the has been fetched the data. If not, do cleanup\r\n    private static _OriginOnPlane: Vector3 = Vector3.Zero();\r\n    private static _HitData: PhysicsHitData = { force: new Vector3(), contactPoint: new Vector3(), distanceFromOrigin: 0 };\r\n\r\n    /**\r\n     * Initializes the physics vortex event\r\n     * @param _scene The BabylonJS scene\r\n     * @param _origin The origin position of the vortex\r\n     * @param _options The options for the vortex event\r\n     */\r\n    constructor(\r\n        private _scene: Scene,\r\n        private _origin: Vector3,\r\n        private _options: PhysicsVortexEventOptions\r\n    ) {\r\n        this._physicsEngine = this._scene.getPhysicsEngine() as PhysicsEngineV1 | PhysicsEngineV2;\r\n        this._options = { ...new PhysicsVortexEventOptions(), ...this._options };\r\n\r\n        this._origin.addToRef(new Vector3(0, this._options.height / 2, 0), this._cylinderPosition);\r\n        this._origin.addToRef(new Vector3(0, this._options.height, 0), this._originTop);\r\n\r\n        this._tickCallback = () => this._tick();\r\n\r\n        if (this._physicsEngine.getPluginVersion() === 1) {\r\n            this._prepareCylinder();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the data related to the vortex event (cylinder).\r\n     * @returns The physics vortex event data\r\n     */\r\n    public getData(): PhysicsVortexEventData {\r\n        this._dataFetched = true;\r\n\r\n        return {\r\n            cylinder: this._cylinder,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Enables the vortex.\r\n     */\r\n    public enable() {\r\n        this._tickCallback.call(this);\r\n        this._scene.registerBeforeRender(this._tickCallback);\r\n    }\r\n\r\n    /**\r\n     * Disables the vortex.\r\n     */\r\n    public disable() {\r\n        this._scene.unregisterBeforeRender(this._tickCallback);\r\n    }\r\n\r\n    /**\r\n     * Disposes the cylinder.\r\n     * @param force Specifies if the vortex should be disposed by force\r\n     */\r\n    public dispose(force: boolean = true) {\r\n        if (!this._cylinder) {\r\n            return;\r\n        }\r\n        if (force) {\r\n            this._cylinder.dispose();\r\n        } else {\r\n            setTimeout(() => {\r\n                if (!this._dataFetched) {\r\n                    this._cylinder.dispose();\r\n                }\r\n            }, 0);\r\n        }\r\n    }\r\n\r\n    private _getHitData(mesh: AbstractMesh, center: Vector3, data: PhysicsHitData): boolean {\r\n        const originOnPlane = PhysicsVortexEvent._OriginOnPlane;\r\n        originOnPlane.set(this._origin.x, center.y, this._origin.z); // the distance to the origin as if both objects were on a plane (Y-axis)\r\n        const originToImpostorDirection = TmpVectors.Vector3[0];\r\n        center.subtractToRef(originOnPlane, originToImpostorDirection);\r\n\r\n        const contactPoint = TmpVectors.Vector3[1];\r\n        const hasContactPoint = HelperTools.GetContactPointToRef(mesh, originOnPlane, originToImpostorDirection, contactPoint, data.instanceIndex);\r\n        if (!hasContactPoint) {\r\n            return false;\r\n        }\r\n        const distance = Vector3.Distance(contactPoint, originOnPlane);\r\n        const absoluteDistanceFromOrigin = distance / this._options.radius;\r\n\r\n        const directionToOrigin = TmpVectors.Vector3[2];\r\n        contactPoint.normalizeToRef(directionToOrigin);\r\n        if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {\r\n            directionToOrigin.negateInPlace();\r\n        }\r\n\r\n        let forceX: number;\r\n        let forceY: number;\r\n        let forceZ: number;\r\n\r\n        if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {\r\n            forceX = directionToOrigin.x * this._options.centripetalForceMultiplier;\r\n            forceY = directionToOrigin.y * this._options.updraftForceMultiplier;\r\n            forceZ = directionToOrigin.z * this._options.centripetalForceMultiplier;\r\n        } else {\r\n            const perpendicularDirection = Vector3.Cross(originOnPlane, center).normalize();\r\n\r\n            forceX = (perpendicularDirection.x + directionToOrigin.x) * this._options.centrifugalForceMultiplier;\r\n            forceY = this._originTop.y * this._options.updraftForceMultiplier;\r\n            forceZ = (perpendicularDirection.z + directionToOrigin.z) * this._options.centrifugalForceMultiplier;\r\n        }\r\n\r\n        const force = TmpVectors.Vector3[3];\r\n        force.set(forceX, forceY, forceZ);\r\n        force.scaleInPlace(this._options.strength);\r\n\r\n        data.force.copyFrom(force);\r\n        data.contactPoint.copyFrom(center);\r\n        data.distanceFromOrigin = absoluteDistanceFromOrigin;\r\n        return true;\r\n    }\r\n\r\n    private _getBodyHitData(body: PhysicsBody, data: PhysicsHitData, instanceIndex?: number): boolean {\r\n        if (HelperTools.HasAppliedForces(body, instanceIndex)) {\r\n            return false;\r\n        }\r\n\r\n        const bodyObject = body.transformNode as AbstractMesh;\r\n        const bodyCenter = body.getObjectCenterWorld(instanceIndex);\r\n\r\n        if (!HelperTools.IsInsideCylinder(bodyCenter, this._origin, this._options.radius, this._options.height)) {\r\n            return false;\r\n        }\r\n\r\n        data.instanceIndex = instanceIndex;\r\n        return this._getHitData(bodyObject, bodyCenter, data);\r\n    }\r\n\r\n    private _getImpostorHitData(impostor: PhysicsImpostor, data: PhysicsHitData): boolean {\r\n        if (impostor.mass === 0) {\r\n            return false;\r\n        }\r\n\r\n        if (impostor.object.getClassName() !== \"Mesh\" && impostor.object.getClassName() !== \"InstancedMesh\") {\r\n            return false;\r\n        }\r\n\r\n        const impostorObject = impostor.object as AbstractMesh;\r\n        if (!this._intersectsWithCylinder(impostorObject)) {\r\n            return false;\r\n        }\r\n\r\n        const impostorObjectCenter = impostor.getObjectCenter();\r\n        this._getHitData(impostorObject, impostorObjectCenter, data);\r\n        return true;\r\n    }\r\n\r\n    private _tick() {\r\n        const hitData = PhysicsVortexEvent._HitData;\r\n        if (this._physicsEngine.getPluginVersion() === 1) {\r\n            const impostors = (<PhysicsEngineV1>this._physicsEngine).getImpostors();\r\n            for (const impostor of impostors) {\r\n                if (!this._getImpostorHitData(impostor, hitData)) {\r\n                    continue;\r\n                }\r\n\r\n                impostor.applyForce(hitData.force, hitData.contactPoint);\r\n            }\r\n        } else {\r\n            const bodies = (<PhysicsEngineV2>this._physicsEngine).getBodies();\r\n            for (const body of bodies) {\r\n                body.iterateOverAllInstances((body: PhysicsBody, instanceIndex?: number) => {\r\n                    if (!this._getBodyHitData(body, hitData, instanceIndex)) {\r\n                        return;\r\n                    }\r\n\r\n                    body.applyForce(hitData.force, hitData.contactPoint, hitData.instanceIndex);\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    /*** Helpers ***/\r\n\r\n    private _prepareCylinder(): void {\r\n        if (!this._cylinder) {\r\n            this._cylinder = CreateCylinder(\r\n                \"vortexEventCylinder\",\r\n                {\r\n                    height: this._options.height,\r\n                    diameter: this._options.radius * 2,\r\n                },\r\n                this._scene\r\n            );\r\n            this._cylinder.isVisible = false;\r\n        }\r\n    }\r\n\r\n    private _intersectsWithCylinder(mesh: AbstractMesh): boolean {\r\n        this._cylinder.position = this._cylinderPosition;\r\n\r\n        return this._cylinder.intersectsMesh(mesh, true);\r\n    }\r\n}\r\n\r\n/**\r\n * Options for the radial explosion event\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\nexport class PhysicsRadialExplosionEventOptions {\r\n    /**\r\n     * The radius of the sphere for the radial explosion.\r\n     */\r\n    radius: number = 5;\r\n\r\n    /**\r\n     * The strength of the explosion.\r\n     */\r\n    strength: number = 10;\r\n\r\n    /**\r\n     * The strength of the force in correspondence to the distance of the affected object\r\n     */\r\n    falloff: PhysicsRadialImpulseFalloff = PhysicsRadialImpulseFalloff.Constant;\r\n\r\n    /**\r\n     * Sphere options for the radial explosion.\r\n     */\r\n    sphere: { segments: number; diameter: number } = { segments: 32, diameter: 1 };\r\n\r\n    /**\r\n     * Callback that is triggered when the radial explosion affects impostors.\r\n     */\r\n    affectedImpostorsCallback: (affectedImpostorsWithData: Array<PhysicsAffectedImpostorWithData>) => void;\r\n\r\n    /**\r\n     * Callback that is triggered when the radial explosion affects bodies.\r\n     */\r\n    affectedBodiesCallback: (affectedBodiesWithData: Array<PhysicsAffectedBodyWithData>) => void;\r\n}\r\n\r\n/**\r\n * Options for the updraft event\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\nexport class PhysicsUpdraftEventOptions {\r\n    /**\r\n     * The radius of the cylinder for the vortex\r\n     */\r\n    radius: number = 5;\r\n\r\n    /**\r\n     * The strength of the updraft.\r\n     */\r\n    strength: number = 10;\r\n\r\n    /**\r\n     * The height of the cylinder for the updraft.\r\n     */\r\n    height: number = 10;\r\n\r\n    /**\r\n     * The mode for the updraft.\r\n     */\r\n    updraftMode: PhysicsUpdraftMode = PhysicsUpdraftMode.Center;\r\n}\r\n\r\n/**\r\n * Options for the vortex event\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\nexport class PhysicsVortexEventOptions {\r\n    /**\r\n     * The radius of the cylinder for the vortex\r\n     */\r\n    radius: number = 5;\r\n\r\n    /**\r\n     * The strength of the vortex.\r\n     */\r\n    strength: number = 10;\r\n\r\n    /**\r\n     * The height of the cylinder for the vortex.\r\n     */\r\n    height: number = 10;\r\n\r\n    /**\r\n     * At which distance, relative to the radius the centripetal forces should kick in? Range: 0-1\r\n     */\r\n    centripetalForceThreshold: number = 0.7;\r\n\r\n    /**\r\n     * This multiplier determines with how much force the objects will be pushed sideways/around the vortex, when below the threshold.\r\n     */\r\n    centripetalForceMultiplier: number = 5;\r\n\r\n    /**\r\n     * This multiplier determines with how much force the objects will be pushed sideways/around the vortex, when above the threshold.\r\n     */\r\n    centrifugalForceMultiplier: number = 0.5;\r\n\r\n    /**\r\n     * This multiplier determines with how much force the objects will be pushed upwards, when in the vortex.\r\n     */\r\n    updraftForceMultiplier: number = 0.02;\r\n}\r\n\r\n/**\r\n * The strength of the force in correspondence to the distance of the affected object\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\nexport const enum PhysicsRadialImpulseFalloff {\r\n    /** Defines that impulse is constant in strength across it's whole radius */\r\n    Constant,\r\n    /** Defines that impulse gets weaker if it's further from the origin */\r\n    Linear,\r\n}\r\n\r\n/**\r\n * The strength of the force in correspondence to the distance of the affected object\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\nexport const enum PhysicsUpdraftMode {\r\n    /** Defines that the upstream forces will pull towards the top center of the cylinder */\r\n    Center,\r\n    /** Defines that once a impostor is inside the cylinder, it will shoot out perpendicular from the ground of the cylinder */\r\n    Perpendicular,\r\n}\r\n\r\n/**\r\n * Interface for a physics hit data\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsHitData {\r\n    /**\r\n     * The force applied at the contact point\r\n     */\r\n    force: Vector3;\r\n    /**\r\n     * The contact point\r\n     */\r\n    contactPoint: Vector3;\r\n    /**\r\n     * The distance from the origin to the contact point\r\n     */\r\n    distanceFromOrigin: number;\r\n    /**\r\n     * For an instanced physics body (mesh with thin instances), the index of the thin instance the hit applies to\r\n     */\r\n    instanceIndex?: number;\r\n}\r\n\r\n/**\r\n * Interface for radial explosion event data\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsRadialExplosionEventData {\r\n    /**\r\n     * A sphere used for the radial explosion event\r\n     */\r\n    sphere: Mesh;\r\n}\r\n\r\n/**\r\n * Interface for gravitational field event data\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsGravitationalFieldEventData {\r\n    /**\r\n     * A sphere mesh used for the gravitational field event\r\n     */\r\n    sphere: Mesh;\r\n}\r\n\r\n/**\r\n * Interface for updraft event data\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsUpdraftEventData {\r\n    /**\r\n     * A cylinder used for the updraft event\r\n     */\r\n    cylinder?: Mesh;\r\n}\r\n\r\n/**\r\n * Interface for vortex event data\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsVortexEventData {\r\n    /**\r\n     * A cylinder used for the vortex event\r\n     */\r\n    cylinder: Mesh;\r\n}\r\n\r\n/**\r\n * Interface for an affected physics impostor\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine#further-functionality-of-the-impostor-class\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsAffectedImpostorWithData {\r\n    /**\r\n     * The impostor affected by the effect\r\n     */\r\n    impostor: PhysicsImpostor;\r\n\r\n    /**\r\n     * The data about the hit/force from the explosion\r\n     */\r\n    hitData: PhysicsHitData;\r\n}\r\n\r\n/**\r\n * Interface for an affected physics body\r\n * @see\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface PhysicsAffectedBodyWithData {\r\n    /**\r\n     * The impostor affected by the effect\r\n     */\r\n    body: PhysicsBody;\r\n\r\n    /**\r\n     * The data about the hit/force from the explosion\r\n     */\r\n    hitData: PhysicsHitData;\r\n}\r\n","import { CastingResult } from \"./castingResult\";\r\n\r\n/**\r\n * Class representing a contact point produced in a proximity cast\r\n */\r\nexport class ProximityCastResult extends CastingResult {\r\n    protected _hitDistance: number = 0;\r\n\r\n    /**\r\n     * Gets the distance from the hit\r\n     */\r\n    get hitDistance(): number {\r\n        return this._hitDistance;\r\n    }\r\n\r\n    /**\r\n     * Sets the distance from the start point to the hit point\r\n     * @param distance\r\n     */\r\n    public setHitDistance(distance: number) {\r\n        this._hitDistance = distance;\r\n    }\r\n\r\n    /**\r\n     * Resets all the values to default\r\n     */\r\n    public override reset() {\r\n        super.reset();\r\n        this._hitDistance = 0;\r\n    }\r\n}\r\n","import { CastingResult } from \"./castingResult\";\r\n\r\n/**\r\n * Class representing a contact point produced in a shape cast\r\n */\r\nexport class ShapeCastResult extends CastingResult {\r\n    private _hitFraction: number = 0;\r\n\r\n    /**\r\n     * Gets the hit fraction along the casting ray\r\n     */\r\n    get hitFraction(): number {\r\n        return this._hitFraction;\r\n    }\r\n\r\n    /**\r\n     * Sets the hit fraction along the casting ray\r\n     * @param fraction\r\n     */\r\n    public setHitFraction(fraction: number) {\r\n        this._hitFraction = fraction;\r\n    }\r\n\r\n    /**\r\n     * Resets all the values to default\r\n     */\r\n    public override reset() {\r\n        super.reset();\r\n        this._hitFraction = 0;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type Nullable } from \"../types\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinBlackAndWhitePostProcess } from \"./thinBlackAndWhitePostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Post process used to render in black and white\r\n */\r\nexport class BlackAndWhitePostProcess extends PostProcess {\r\n    /**\r\n     * Linear about to convert he result to black and white (default: 1)\r\n     */\r\n    @serialize()\r\n    public get degree() {\r\n        return this._effectWrapper.degree;\r\n    }\r\n\r\n    public set degree(value: number) {\r\n        this._effectWrapper.degree = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"BlackAndWhitePostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"BlackAndWhitePostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinBlackAndWhitePostProcess;\r\n\r\n    /**\r\n     * Creates a black and white post process\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#black-and-white\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: AbstractEngine, reusable?: boolean) {\r\n        const localOptions = {\r\n            uniforms: ThinBlackAndWhitePostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinBlackAndWhitePostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinBlackAndWhitePostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<BlackAndWhitePostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new BlackAndWhitePostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for blackAndWhitePostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBlackAndWhitePostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BlackAndWhitePostProcess\", BlackAndWhitePostProcess);\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type PostProcess } from \"../../PostProcesses/postProcess\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n/**\r\n * This represents a set of one or more post processes in Babylon.\r\n * A post process can be used to apply a shader to a texture after it is rendered.\r\n * @example https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/postProcessRenderPipeline\r\n */\r\nexport class PostProcessRenderEffect {\r\n    private _postProcesses: { [Key: string]: Array<PostProcess> };\r\n    private _getPostProcesses: () => Nullable<PostProcess | Array<PostProcess>>;\r\n\r\n    private _singleInstance: boolean;\r\n\r\n    private _cameras: { [key: string]: Nullable<Camera> };\r\n    private _indicesForCamera: { [key: string]: number[] };\r\n\r\n    /**\r\n     * Name of the effect\r\n     * @internal\r\n     */\r\n    public _name: string;\r\n\r\n    /**\r\n     * Instantiates a post process render effect.\r\n     * A post process can be used to apply a shader to a texture after it is rendered.\r\n     * @param engine The engine the effect is tied to\r\n     * @param name The name of the effect\r\n     * @param getPostProcesses A function that returns a set of post processes which the effect will run in order to be run.\r\n     * @param singleInstance False if this post process can be run on multiple cameras. (default: true)\r\n     */\r\n    constructor(engine: AbstractEngine, name: string, getPostProcesses: () => Nullable<PostProcess | Array<PostProcess>>, singleInstance = true) {\r\n        this._name = name;\r\n        this._singleInstance = singleInstance;\r\n\r\n        this._getPostProcesses = getPostProcesses;\r\n\r\n        this._cameras = {};\r\n        this._indicesForCamera = {};\r\n\r\n        this._postProcesses = {};\r\n    }\r\n\r\n    /**\r\n     * Checks if all the post processes in the effect are supported.\r\n     */\r\n    public get isSupported(): boolean {\r\n        for (const index in this._postProcesses) {\r\n            if (Object.prototype.hasOwnProperty.call(this._postProcesses, index)) {\r\n                const pps = this._postProcesses[index];\r\n                for (let ppIndex = 0; ppIndex < pps.length; ppIndex++) {\r\n                    if (!pps[ppIndex].isSupported) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Updates the current state of the effect\r\n     * @internal\r\n     */\r\n    public _update(): void {}\r\n\r\n    /**\r\n     * Attaches the effect on cameras\r\n     * @param cameras The camera to attach to.\r\n     * @internal\r\n     */\r\n    public _attachCameras(cameras: Camera): void;\r\n    /**\r\n     * Attaches the effect on cameras\r\n     * @param cameras The camera to attach to.\r\n     * @internal\r\n     */\r\n    public _attachCameras(cameras: Camera[]): void;\r\n    /**\r\n     * Attaches the effect on cameras\r\n     * @param cameras The camera to attach to.\r\n     * @internal\r\n     */\r\n    public _attachCameras(cameras: any): void {\r\n        let cameraKey;\r\n\r\n        const cams = Tools.MakeArray(cameras || this._cameras);\r\n\r\n        if (!cams) {\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < cams.length; i++) {\r\n            const camera = cams[i];\r\n            if (!camera) {\r\n                continue;\r\n            }\r\n\r\n            const cameraName = camera.name;\r\n\r\n            if (this._singleInstance) {\r\n                cameraKey = 0;\r\n            } else {\r\n                cameraKey = cameraName;\r\n            }\r\n\r\n            if (!this._postProcesses[cameraKey]) {\r\n                const postProcess = this._getPostProcesses();\r\n                if (postProcess) {\r\n                    this._postProcesses[cameraKey] = Array.isArray(postProcess) ? postProcess : [postProcess];\r\n                }\r\n            }\r\n\r\n            if (!this._indicesForCamera[cameraName]) {\r\n                this._indicesForCamera[cameraName] = [];\r\n            }\r\n\r\n            const pps = this._postProcesses[cameraKey];\r\n            for (const postProcess of pps) {\r\n                const index = camera.attachPostProcess(postProcess);\r\n\r\n                this._indicesForCamera[cameraName].push(index);\r\n            }\r\n\r\n            if (!this._cameras[cameraName]) {\r\n                this._cameras[cameraName] = camera;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detaches the effect on cameras\r\n     * @param cameras The camera to detach from.\r\n     * @internal\r\n     */\r\n    public _detachCameras(cameras: Camera): void;\r\n    /**\r\n     * Detaches the effect on cameras\r\n     * @param cameras The camera to detach from.\r\n     * @internal\r\n     */\r\n    public _detachCameras(cameras: Camera[]): void;\r\n    /**\r\n     * Detaches the effect on cameras\r\n     * @param cameras The camera to detach from.\r\n     * @internal\r\n     */\r\n    public _detachCameras(cameras: any): void {\r\n        const cams = Tools.MakeArray(cameras || this._cameras);\r\n\r\n        if (!cams) {\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < cams.length; i++) {\r\n            const camera: Camera = cams[i];\r\n            const cameraName: string = camera.name;\r\n            const postProcesses = this._postProcesses[this._singleInstance ? 0 : cameraName];\r\n\r\n            if (postProcesses) {\r\n                for (const postProcess of postProcesses) {\r\n                    camera.detachPostProcess(postProcess);\r\n                }\r\n            }\r\n\r\n            if (this._cameras[cameraName]) {\r\n                this._cameras[cameraName] = null;\r\n            }\r\n\r\n            delete this._indicesForCamera[cameraName];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Enables the effect on given cameras\r\n     * @param cameras The camera to enable.\r\n     * @internal\r\n     */\r\n    public _enable(cameras: Camera): void;\r\n    /**\r\n     * Enables the effect on given cameras\r\n     * @param cameras The camera to enable.\r\n     * @internal\r\n     */\r\n    public _enable(cameras: Nullable<Camera[]>): void;\r\n    /**\r\n     * Enables the effect on given cameras\r\n     * @param cameras The camera to enable.\r\n     * @internal\r\n     */\r\n    public _enable(cameras: any): void {\r\n        const cams: Nullable<Array<Camera>> = Tools.MakeArray(cameras || this._cameras);\r\n\r\n        if (!cams) {\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < cams.length; i++) {\r\n            const camera = cams[i];\r\n            const cameraName = camera.name;\r\n            const cameraKey = this._singleInstance ? 0 : cameraName;\r\n\r\n            for (let j = 0; j < this._indicesForCamera[cameraName].length; j++) {\r\n                const index = this._indicesForCamera[cameraName][j];\r\n                const postProcess = camera._postProcesses[index];\r\n                if (postProcess === undefined || postProcess === null) {\r\n                    cams[i].attachPostProcess(this._postProcesses[cameraKey][j], index);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disables the effect on the given cameras\r\n     * @param cameras The camera to disable.\r\n     * @internal\r\n     */\r\n    public _disable(cameras: Camera): void;\r\n    /**\r\n     * Disables the effect on the given cameras\r\n     * @param cameras The camera to disable.\r\n     * @internal\r\n     */\r\n    public _disable(cameras: Nullable<Camera[]>): void;\r\n    /**\r\n     * Disables the effect on the given cameras\r\n     * @param cameras The camera to disable.\r\n     * @internal\r\n     */\r\n    public _disable(cameras: any): void {\r\n        const cams: Nullable<Array<Camera>> = Tools.MakeArray(cameras || this._cameras);\r\n\r\n        if (!cams) {\r\n            return;\r\n        }\r\n\r\n        for (let i = 0; i < cams.length; i++) {\r\n            const camera = cams[i];\r\n            const cameraName = camera.name;\r\n            const pps = this._postProcesses[this._singleInstance ? 0 : cameraName];\r\n            for (const postProcess of pps) {\r\n                camera.detachPostProcess(postProcess);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets a list of the post processes contained in the effect.\r\n     * @param camera The camera to get the post processes on.\r\n     * @returns The list of the post processes in the effect.\r\n     */\r\n    public getPostProcesses(camera?: Camera): Nullable<Array<PostProcess>> {\r\n        if (this._singleInstance) {\r\n            return this._postProcesses[0];\r\n        } else {\r\n            if (!camera) {\r\n                return null;\r\n            }\r\n            return this._postProcesses[camera.name];\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { ThinExtractHighlightsPostProcess } from \"./thinExtractHighlightsPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The extract highlights post process sets all pixels to black except pixels above the specified luminance threshold. Used as the first step for a bloom effect.\r\n */\r\nexport class ExtractHighlightsPostProcess extends PostProcess {\r\n    /**\r\n     * The luminance threshold, pixels below this value will be set to black.\r\n     */\r\n    @serialize()\r\n    public get threshold() {\r\n        return this._effectWrapper.threshold;\r\n    }\r\n\r\n    public set threshold(value: number) {\r\n        this._effectWrapper.threshold = value;\r\n    }\r\n\r\n    /** @internal */\r\n    public get _exposure() {\r\n        return this._effectWrapper._exposure;\r\n    }\r\n\r\n    /** @internal */\r\n    public set _exposure(value: number) {\r\n        this._effectWrapper._exposure = value;\r\n    }\r\n\r\n    /**\r\n     * Post process which has the input texture to be used when performing highlight extraction\r\n     * @internal\r\n     */\r\n    public _inputPostProcess: Nullable<PostProcess> = null;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"ExtractHighlightsPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ExtractHighlightsPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinExtractHighlightsPostProcess;\r\n\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinExtractHighlightsPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinExtractHighlightsPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinExtractHighlightsPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            this.externalTextureSamplerBinding = !!this._inputPostProcess;\r\n            if (this._inputPostProcess) {\r\n                effect.setTextureFromPostProcess(\"textureSampler\", this._inputPostProcess);\r\n            }\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for extractHighlightsPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterExtractHighlightsPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ExtractHighlightsPostProcess\", ExtractHighlightsPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { ThinBloomMergePostProcess } from \"./thinBloomMergePostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The BloomMergePostProcess merges blurred images with the original based on the values of the circle of confusion.\r\n */\r\nexport class BloomMergePostProcess extends PostProcess {\r\n    /** Weight of the bloom to be added to the original input. */\r\n    @serialize()\r\n    public get weight() {\r\n        return this._effectWrapper.weight;\r\n    }\r\n\r\n    public set weight(value: number) {\r\n        this._effectWrapper.weight = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"BloomMergePostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"BloomMergePostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinBloomMergePostProcess;\r\n\r\n    /**\r\n     * Creates a new instance of @see BloomMergePostProcess\r\n     * @param name The name of the effect.\r\n     * @param originalFromInput Post process which's input will be used for the merge.\r\n     * @param blurred Blurred highlights post process which's output will be used.\r\n     * @param weight Weight of the bloom to be added to the original input.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        originalFromInput: PostProcess,\r\n        blurred: PostProcess,\r\n        weight: number,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const blockCompilationFinal = typeof options === \"number\" ? blockCompilation : !!options.blockCompilation;\r\n        const localOptions = {\r\n            uniforms: ThinBloomMergePostProcess.Uniforms,\r\n            samplers: ThinBloomMergePostProcess.Samplers,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            ...(options as PostProcessOptions),\r\n            blockCompilation: true,\r\n        };\r\n\r\n        super(name, ThinBloomMergePostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinBloomMergePostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.weight = weight;\r\n        this.externalTextureSamplerBinding = true;\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setTextureFromPostProcess(\"textureSampler\", originalFromInput);\r\n            effect.setTextureFromPostProcessOutput(\"bloomBlur\", blurred);\r\n        });\r\n\r\n        if (!blockCompilationFinal) {\r\n            this.updateEffect();\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for bloomMergePostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBloomMergePostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.BloomMergePostProcess\", BloomMergePostProcess);\r\n}\r\n","import { PostProcessRenderEffect } from \"../PostProcesses/RenderPipeline/postProcessRenderEffect\";\r\nimport { type PostProcess } from \"./postProcess\";\r\nimport { ExtractHighlightsPostProcess } from \"./extractHighlightsPostProcess.pure\";\r\nimport { BlurPostProcess } from \"./blurPostProcess.pure\";\r\nimport { BloomMergePostProcess } from \"./bloomMergePostProcess.pure\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { ThinBloomEffect } from \"./thinBloomEffect\";\r\n\r\n/**\r\n * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras\r\n */\r\nexport class BloomEffect extends PostProcessRenderEffect {\r\n    /**\r\n     * @internal Internal\r\n     */\r\n    public _effects: Array<PostProcess> = [];\r\n\r\n    /**\r\n     * @internal Internal\r\n     */\r\n    public _downscale: ExtractHighlightsPostProcess;\r\n    private _blurX: BlurPostProcess;\r\n    private _blurY: BlurPostProcess;\r\n    private _merge: BloomMergePostProcess;\r\n\r\n    /**\r\n     * The luminance threshold to find bright areas of the image to bloom.\r\n     */\r\n    public get threshold(): number {\r\n        return this._thinBloomEffect.threshold;\r\n    }\r\n    public set threshold(value: number) {\r\n        this._thinBloomEffect.threshold = value;\r\n    }\r\n\r\n    /**\r\n     * The strength of the bloom.\r\n     */\r\n    public get weight(): number {\r\n        return this._thinBloomEffect.weight;\r\n    }\r\n    public set weight(value: number) {\r\n        this._thinBloomEffect.weight = value;\r\n    }\r\n\r\n    /**\r\n     * Specifies the size of the bloom blur kernel, relative to the final output size\r\n     */\r\n    public get kernel(): number {\r\n        return this._thinBloomEffect.kernel;\r\n    }\r\n    public set kernel(value: number) {\r\n        this._thinBloomEffect.kernel = value;\r\n    }\r\n\r\n    public get bloomScale() {\r\n        return this._thinBloomEffect.scale;\r\n    }\r\n\r\n    private _thinBloomEffect: ThinBloomEffect;\r\n\r\n    /**\r\n     * Creates a new instance of @see BloomEffect\r\n     * @param sceneOrEngine The scene or engine the effect belongs to.\r\n     * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.\r\n     * @param bloomWeight The strength of bloom.\r\n     * @param bloomKernel The size of the kernel to be used when applying the blur.\r\n     * @param pipelineTextureType The type of texture to be used when performing the post processing.\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(sceneOrEngine: Scene | AbstractEngine, bloomScale: number, bloomWeight: number, bloomKernel: number, pipelineTextureType = 0, blockCompilation = false) {\r\n        const engine = (sceneOrEngine as Scene)._renderForCamera ? (sceneOrEngine as Scene).getEngine() : (sceneOrEngine as AbstractEngine);\r\n        super(\r\n            engine,\r\n            \"bloom\",\r\n            () => {\r\n                return this._effects;\r\n            },\r\n            true\r\n        );\r\n\r\n        this._thinBloomEffect = new ThinBloomEffect(\"bloom\", engine, bloomScale, blockCompilation);\r\n\r\n        this._downscale = new ExtractHighlightsPostProcess(\"highlights\", {\r\n            size: 1.0,\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            textureType: pipelineTextureType,\r\n            blockCompilation,\r\n            effectWrapper: this._thinBloomEffect._downscale,\r\n        });\r\n\r\n        this._blurX = new BlurPostProcess(\"horizontal blur\", this._thinBloomEffect._blurX.direction, this._thinBloomEffect._blurX.kernel, {\r\n            size: bloomScale,\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            textureType: pipelineTextureType,\r\n            blockCompilation,\r\n            effectWrapper: this._thinBloomEffect._blurX,\r\n        });\r\n        this._blurX.alwaysForcePOT = true;\r\n        this._blurX.autoClear = false;\r\n\r\n        this._blurY = new BlurPostProcess(\"vertical blur\", this._thinBloomEffect._blurY.direction, this._thinBloomEffect._blurY.kernel, {\r\n            size: bloomScale,\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            textureType: pipelineTextureType,\r\n            blockCompilation,\r\n            effectWrapper: this._thinBloomEffect._blurY,\r\n        });\r\n        this._blurY.alwaysForcePOT = true;\r\n        this._blurY.autoClear = false;\r\n\r\n        this.kernel = bloomKernel;\r\n\r\n        this._effects = [this._downscale, this._blurX, this._blurY];\r\n\r\n        this._merge = new BloomMergePostProcess(\"bloomMerge\", this._downscale, this._blurY, bloomWeight, {\r\n            size: bloomScale,\r\n            samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            textureType: pipelineTextureType,\r\n            blockCompilation,\r\n            effectWrapper: this._thinBloomEffect._merge,\r\n        });\r\n        this._merge.autoClear = false;\r\n        this._effects.push(this._merge);\r\n    }\r\n\r\n    /**\r\n     * Disposes each of the internal effects for a given camera.\r\n     * @param camera The camera to dispose the effect on.\r\n     */\r\n    public disposeEffects(camera?: Camera) {\r\n        for (let effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {\r\n            this._effects[effectIndex].dispose(camera);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal Internal\r\n     */\r\n    public _updateEffects() {\r\n        for (let effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {\r\n            this._effects[effectIndex].updateEffect();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Internal\r\n     * @returns if all the contained post processes are ready.\r\n     * @internal\r\n     */\r\n    public _isReady() {\r\n        return this._thinBloomEffect.isReady();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinChromaticAberrationPostProcess } from \"./thinChromaticAberrationPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The ChromaticAberrationPostProcess separates the rgb channels in an image to produce chromatic distortion around the edges of the screen\r\n */\r\nexport class ChromaticAberrationPostProcess extends PostProcess {\r\n    /**\r\n     * The amount of separation of rgb channels (default: 30)\r\n     */\r\n    @serialize()\r\n    public get aberrationAmount() {\r\n        return this._effectWrapper.aberrationAmount;\r\n    }\r\n\r\n    public set aberrationAmount(value: number) {\r\n        this._effectWrapper.aberrationAmount = value;\r\n    }\r\n\r\n    /**\r\n     * The amount the effect will increase for pixels closer to the edge of the screen. (default: 0)\r\n     */\r\n    @serialize()\r\n    public get radialIntensity() {\r\n        return this._effectWrapper.radialIntensity;\r\n    }\r\n\r\n    public set radialIntensity(value: number) {\r\n        this._effectWrapper.radialIntensity = value;\r\n    }\r\n\r\n    /**\r\n     * The normalized direction in which the rgb channels should be separated. If set to 0,0 radial direction will be used. (default: Vector2(0.707,0.707))\r\n     */\r\n    @serialize()\r\n    public get direction() {\r\n        return this._effectWrapper.direction;\r\n    }\r\n\r\n    public set direction(value: Vector2) {\r\n        this._effectWrapper.direction = value;\r\n    }\r\n\r\n    /**\r\n     * The center position where the radialIntensity should be around. [0.5,0.5 is center of screen, 1,1 is top right corner] (default: Vector2(0.5 ,0.5))\r\n     */\r\n    @serialize()\r\n    public get centerPosition() {\r\n        return this._effectWrapper.centerPosition;\r\n    }\r\n\r\n    public set centerPosition(value: Vector2) {\r\n        this._effectWrapper.centerPosition = value;\r\n    }\r\n\r\n    /** The width of the screen to apply the effect on */\r\n    @serialize()\r\n    public get screenWidth() {\r\n        return this._effectWrapper.screenWidth;\r\n    }\r\n\r\n    public set screenWidth(value: number) {\r\n        this._effectWrapper.screenWidth = value;\r\n    }\r\n\r\n    /** The height of the screen to apply the effect on */\r\n    @serialize()\r\n    public get screenHeight() {\r\n        return this._effectWrapper.screenHeight;\r\n    }\r\n\r\n    public set screenHeight(value: number) {\r\n        this._effectWrapper.screenHeight = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"ChromaticAberrationPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ChromaticAberrationPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinChromaticAberrationPostProcess;\r\n\r\n    /**\r\n     * Creates a new instance ChromaticAberrationPostProcess\r\n     * @param name The name of the effect.\r\n     * @param screenWidth The width of the screen to apply the effect on.\r\n     * @param screenHeight The height of the screen to apply the effect on.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        screenWidth: number,\r\n        screenHeight: number,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinChromaticAberrationPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinChromaticAberrationPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinChromaticAberrationPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.screenWidth = screenWidth;\r\n        this.screenHeight = screenHeight;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<ChromaticAberrationPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new ChromaticAberrationPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.screenWidth,\r\n                    parsedPostProcess.screenHeight,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.textureType,\r\n                    false\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for chromaticAberrationPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterChromaticAberrationPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ChromaticAberrationPostProcess\", ChromaticAberrationPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { type ThinCircleOfConfusionPostProcessOptions, ThinCircleOfConfusionPostProcess } from \"./thinCircleOfConfusionPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nexport type CircleOfConfusionPostProcessOptions = ThinCircleOfConfusionPostProcessOptions & PostProcessOptions;\r\n\r\n/**\r\n * The CircleOfConfusionPostProcess computes the circle of confusion value for each pixel given required lens parameters. See https://en.wikipedia.org/wiki/Circle_of_confusion\r\n */\r\nexport class CircleOfConfusionPostProcess extends PostProcess {\r\n    /**\r\n     * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diameter of the resulting aperture can be computed by lensSize/fStop.\r\n     */\r\n    @serialize()\r\n    public get lensSize() {\r\n        return this._effectWrapper.lensSize;\r\n    }\r\n\r\n    public set lensSize(value: number) {\r\n        this._effectWrapper.lensSize = value;\r\n    }\r\n\r\n    /**\r\n     * F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)\r\n     */\r\n    @serialize()\r\n    public get fStop() {\r\n        return this._effectWrapper.fStop;\r\n    }\r\n\r\n    public set fStop(value: number) {\r\n        this._effectWrapper.fStop = value;\r\n    }\r\n\r\n    /**\r\n     * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)\r\n     */\r\n    @serialize()\r\n    public get focusDistance() {\r\n        return this._effectWrapper.focusDistance;\r\n    }\r\n\r\n    public set focusDistance(value: number) {\r\n        this._effectWrapper.focusDistance = value;\r\n    }\r\n\r\n    /**\r\n     * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)\r\n     */\r\n    @serialize()\r\n    public get focalLength() {\r\n        return this._effectWrapper.focalLength;\r\n    }\r\n\r\n    public set focalLength(value: number) {\r\n        this._effectWrapper.focalLength = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"CircleOfConfusionPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"CircleOfConfusionPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinCircleOfConfusionPostProcess;\r\n    private _depthTexture: Nullable<RenderTargetTexture> = null;\r\n\r\n    /**\r\n     * Creates a new instance CircleOfConfusionPostProcess\r\n     * @param name The name of the effect.\r\n     * @param depthTexture The depth texture of the scene to compute the circle of confusion. This must be set in order for this to function but may be set after initialization if needed.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        depthTexture: Nullable<RenderTargetTexture>,\r\n        options: number | CircleOfConfusionPostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinCircleOfConfusionPostProcess.Uniforms,\r\n            samplers: ThinCircleOfConfusionPostProcess.Samplers,\r\n            defines: typeof options === \"object\" && options.depthNotNormalized ? ThinCircleOfConfusionPostProcess.DefinesDepthNotNormalized : undefined,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinCircleOfConfusionPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinCircleOfConfusionPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this._depthTexture = depthTexture;\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            if (!this._depthTexture) {\r\n                Logger.Warn(\"No depth texture set on CircleOfConfusionPostProcess\");\r\n                return;\r\n            }\r\n\r\n            effect.setTexture(\"depthSampler\", this._depthTexture);\r\n\r\n            this._effectWrapper.camera = this._depthTexture.activeCamera!;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.\r\n     */\r\n    public set depthTexture(value: RenderTargetTexture) {\r\n        this._depthTexture = value;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for circleOfConfusionPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterCircleOfConfusionPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.CircleOfConfusionPostProcess\", CircleOfConfusionPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type Nullable } from \"../types\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinColorCorrectionPostProcess } from \"./thinColorCorrectionPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n *\r\n * This post-process allows the modification of rendered colors by using\r\n * a 'look-up table' (LUT). This effect is also called Color Grading.\r\n *\r\n * The object needs to be provided an url to a texture containing the color\r\n * look-up table: the texture must be 256 pixels wide and 16 pixels high.\r\n * Use an image editing software to tweak the LUT to match your needs.\r\n *\r\n * For an example of a color LUT, see here:\r\n * @see http://udn.epicgames.com/Three/rsrc/Three/ColorGrading/RGBTable16x1.png\r\n * For explanations on color grading, see here:\r\n * @see http://udn.epicgames.com/Three/ColorGrading.html\r\n *\r\n */\r\nexport class ColorCorrectionPostProcess extends PostProcess {\r\n    /**\r\n     * Gets the color table url used to create the LUT texture\r\n     */\r\n    @serialize()\r\n    public get colorTableUrl() {\r\n        return this._effectWrapper.colorTableUrl;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"ColorCorrectionPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ColorCorrectionPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinColorCorrectionPostProcess;\r\n\r\n    constructor(\r\n        name: string,\r\n        colorTableUrl: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean\r\n    ) {\r\n        const localOptions = {\r\n            samplers: ThinColorCorrectionPostProcess.Samplers,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        const scene = camera?.getScene() || null;\r\n\r\n        super(name, ThinColorCorrectionPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinColorCorrectionPostProcess(name, scene, colorTableUrl, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<ColorCorrectionPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new ColorCorrectionPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.colorTableUrl,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for colorCorrectionPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterColorCorrectionPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ColorCorrectionPostProcess\", ColorCorrectionPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinConvolutionPostProcess } from \"./thinConvolutionPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The ConvolutionPostProcess applies a 3x3 kernel to every pixel of the\r\n * input texture to perform effects such as edge detection or sharpening\r\n * See http://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n */\r\nexport class ConvolutionPostProcess extends PostProcess {\r\n    /** Array of 9 values corresponding to the 3x3 kernel to be applied */\r\n    @serialize()\r\n    public get kernel() {\r\n        return this._effectWrapper.kernel;\r\n    }\r\n\r\n    public set kernel(value: number[]) {\r\n        this._effectWrapper.kernel = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"ConvolutionPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ConvolutionPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinConvolutionPostProcess;\r\n\r\n    /**\r\n     * Creates a new instance ConvolutionPostProcess\r\n     * @param name The name of the effect.\r\n     * @param kernel Array of 9 values corresponding to the 3x3 kernel to be applied\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        kernel: number[],\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinConvolutionPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinConvolutionPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinConvolutionPostProcess(name, engine, kernel, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.onApply = (_effect: Effect) => {\r\n            this._effectWrapper.textureWidth = this.width;\r\n            this._effectWrapper.textureHeight = this.height;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<ConvolutionPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new ConvolutionPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.kernel,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.textureType\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n\r\n    // Statics\r\n    /**\r\n     * Edge detection 0 see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EdgeDetect0Kernel = ThinConvolutionPostProcess.EdgeDetect0Kernel;\r\n    /**\r\n     * Edge detection 1 see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EdgeDetect1Kernel = ThinConvolutionPostProcess.EdgeDetect1Kernel;\r\n    /**\r\n     * Edge detection 2 see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EdgeDetect2Kernel = ThinConvolutionPostProcess.EdgeDetect2Kernel;\r\n    /**\r\n     * Kernel to sharpen an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static SharpenKernel = ThinConvolutionPostProcess.SharpenKernel;\r\n    /**\r\n     * Kernel to emboss an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static EmbossKernel = ThinConvolutionPostProcess.EmbossKernel;\r\n    /**\r\n     * Kernel to blur an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n     */\r\n    public static GaussianKernel = ThinConvolutionPostProcess.GaussianKernel;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for convolutionPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterConvolutionPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ConvolutionPostProcess\", ConvolutionPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Vector2 } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type PostProcess, type PostProcessOptions } from \"./postProcess.pure\";\r\nimport { BlurPostProcess } from \"./blurPostProcess.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { ThinDepthOfFieldBlurPostProcess } from \"./thinDepthOfFieldBlurPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The DepthOfFieldBlurPostProcess applied a blur in a give direction.\r\n * This blur differs from the standard BlurPostProcess as it attempts to avoid blurring pixels\r\n * based on samples that have a large difference in distance than the center pixel.\r\n * See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf\r\n */\r\nexport class DepthOfFieldBlurPostProcess extends BlurPostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"DepthOfFieldBlurPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DepthOfFieldBlurPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance DepthOfFieldBlurPostProcess\r\n     * @param name The name of the effect.\r\n     * @param _scene The scene the effect belongs to (not used, you can pass null)\r\n     * @param direction The direction the blur should be applied.\r\n     * @param kernel The size of the kernel used to blur.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param circleOfConfusion The circle of confusion + depth map to be used to avoid blurring across edges\r\n     * @param imageToBlur The image to apply the blur to (default: Current rendered frame)\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        _scene: Nullable<Scene>,\r\n        direction: Vector2,\r\n        kernel: number,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        circleOfConfusion: PostProcess,\r\n        imageToBlur: Nullable<PostProcess> = null,\r\n        samplingMode = Texture.BILINEAR_SAMPLINGMODE,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false,\r\n        textureFormat = Constants.TEXTUREFORMAT_RGBA\r\n    ) {\r\n        const localOptions = {\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n            samplingMode: (samplingMode = Constants.TEXTURE_BILINEAR_SAMPLINGMODE),\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            defines: `#define DOF 1\\n`,\r\n            blockCompilation,\r\n            textureFormat,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, direction, kernel, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinDepthOfFieldBlurPostProcess(name, engine, direction, kernel, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.externalTextureSamplerBinding = !!imageToBlur;\r\n\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            if (imageToBlur != null) {\r\n                effect.setTextureFromPostProcess(\"textureSampler\", imageToBlur);\r\n            }\r\n            effect.setTextureFromPostProcessOutput(\"circleOfConfusionSampler\", circleOfConfusion);\r\n        });\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for depthOfFieldBlurPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDepthOfFieldBlurPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DepthOfFieldBlurPostProcess\", DepthOfFieldBlurPostProcess);\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type Effect } from \"../Materials/effect\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { ThinDepthOfFieldMergePostProcess } from \"./thinDepthOfFieldMergePostProcess\";\r\n\r\n/**\r\n * The DepthOfFieldMergePostProcess merges blurred images with the original based on the values of the circle of confusion.\r\n */\r\nexport class DepthOfFieldMergePostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"DepthOfFieldMergePostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DepthOfFieldMergePostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance of DepthOfFieldMergePostProcess\r\n     * @param name The name of the effect.\r\n     * @param originalFromInput Post process which's input will be used for the merge.\r\n     * @param circleOfConfusion Circle of confusion post process which's output will be used to blur each pixel.\r\n     * @param _blurSteps Blur post processes from low to high which will be mixed with the original image.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        originalFromInput: PostProcess,\r\n        circleOfConfusion: PostProcess,\r\n        private _blurSteps: Array<PostProcess>,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const blockCompilationFinal = typeof options === \"number\" ? blockCompilation : !!options.blockCompilation;\r\n        const localOptions = {\r\n            samplers: ThinDepthOfFieldMergePostProcess.Samplers,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            ...(options as PostProcessOptions),\r\n            blockCompilation: true,\r\n        };\r\n\r\n        super(name, ThinDepthOfFieldMergePostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinDepthOfFieldMergePostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.externalTextureSamplerBinding = true;\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setTextureFromPostProcess(\"textureSampler\", originalFromInput);\r\n            effect.setTextureFromPostProcessOutput(\"circleOfConfusionSampler\", circleOfConfusion);\r\n            for (let i = 0; i < _blurSteps.length; i++) {\r\n                const step = _blurSteps[i];\r\n                effect.setTextureFromPostProcessOutput(\"blurStep\" + (_blurSteps.length - i - 1), step);\r\n            }\r\n        });\r\n\r\n        if (!blockCompilationFinal) {\r\n            this.updateEffect();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the effect with the current post process compile time values and recompiles the shader.\r\n     * @param defines Define statements that should be added at the beginning of the shader. (default: null)\r\n     * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)\r\n     * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)\r\n     * @param indexParameters The index parameters to be used for babylons include syntax \"#include<kernelBlurVaryingDeclaration>[0..varyingCount]\". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n     * @param onCompiled Called when the shader has been compiled.\r\n     * @param onError Called if there is an error when compiling a shader.\r\n     */\r\n    public override updateEffect(\r\n        defines: Nullable<string> = null,\r\n        uniforms: Nullable<string[]> = null,\r\n        samplers: Nullable<string[]> = null,\r\n        indexParameters?: any,\r\n        onCompiled?: (effect: Effect) => void,\r\n        onError?: (effect: Effect, errors: string) => void\r\n    ) {\r\n        if (!defines) {\r\n            defines = \"\";\r\n            defines += \"#define BLUR_LEVEL \" + (this._blurSteps.length - 1) + \"\\n\";\r\n        }\r\n        super.updateEffect(defines, uniforms, samplers, indexParameters, onCompiled, onError);\r\n    }\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { type PostProcess } from \"./postProcess\";\r\nimport { PostProcessRenderEffect } from \"../PostProcesses/RenderPipeline/postProcessRenderEffect\";\r\nimport { CircleOfConfusionPostProcess } from \"./circleOfConfusionPostProcess.pure\";\r\nimport { DepthOfFieldBlurPostProcess } from \"./depthOfFieldBlurPostProcess.pure\";\r\nimport { DepthOfFieldMergePostProcess } from \"./depthOfFieldMergePostProcess\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type ThinDepthOfFieldEffectBlurLevel, ThinDepthOfFieldEffect } from \"./thinDepthOfFieldEffect\";\r\n\r\n/**\r\n * Specifies the level of max blur that should be applied when using the depth of field effect\r\n */\r\nexport const enum DepthOfFieldEffectBlurLevel {\r\n    /**\r\n     * Subtle blur\r\n     */\r\n    Low,\r\n    /**\r\n     * Medium blur\r\n     */\r\n    Medium,\r\n    /**\r\n     * Large blur\r\n     */\r\n    High,\r\n}\r\n\r\n/**\r\n * The depth of field effect applies a blur to objects that are closer or further from where the camera is focusing.\r\n */\r\nexport class DepthOfFieldEffect extends PostProcessRenderEffect {\r\n    private _circleOfConfusion: CircleOfConfusionPostProcess;\r\n    /**\r\n     * @internal Internal, blurs from high to low\r\n     */\r\n    public _depthOfFieldBlurX: Array<DepthOfFieldBlurPostProcess>;\r\n    private _depthOfFieldBlurY: Array<DepthOfFieldBlurPostProcess>;\r\n    private _dofMerge: Nullable<DepthOfFieldMergePostProcess>;\r\n\r\n    /**\r\n     * @internal Internal post processes in depth of field effect\r\n     */\r\n    public _effects: Array<PostProcess> = [];\r\n\r\n    /**\r\n     * The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter)\r\n     */\r\n    public set focalLength(value: number) {\r\n        this._thinDepthOfFieldEffect.focalLength = value;\r\n    }\r\n    public get focalLength() {\r\n        return this._thinDepthOfFieldEffect.focalLength;\r\n    }\r\n    /**\r\n     * F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)\r\n     */\r\n    public set fStop(value: number) {\r\n        this._thinDepthOfFieldEffect.fStop = value;\r\n    }\r\n    public get fStop() {\r\n        return this._thinDepthOfFieldEffect.fStop;\r\n    }\r\n    /**\r\n     * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)\r\n     */\r\n    public set focusDistance(value: number) {\r\n        this._thinDepthOfFieldEffect.focusDistance = value;\r\n    }\r\n    public get focusDistance() {\r\n        return this._thinDepthOfFieldEffect.focusDistance;\r\n    }\r\n    /**\r\n     * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diameter of the resulting aperture can be computed by lensSize/fStop.\r\n     */\r\n    public set lensSize(value: number) {\r\n        this._thinDepthOfFieldEffect.lensSize = value;\r\n    }\r\n    public get lensSize() {\r\n        return this._thinDepthOfFieldEffect.lensSize;\r\n    }\r\n\r\n    private _thinDepthOfFieldEffect: ThinDepthOfFieldEffect;\r\n\r\n    /**\r\n     * Creates a new instance DepthOfFieldEffect\r\n     * @param sceneOrEngine The scene or engine the effect belongs to.\r\n     * @param depthTexture The depth texture of the scene to compute the circle of confusion.This must be set in order for this to function but may be set after initialization if needed.\r\n     * @param blurLevel\r\n     * @param pipelineTextureType The type of texture to be used when performing the post processing.\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     * @param depthNotNormalized If the depth from the depth texture is already normalized or if the normalization should be done at runtime in the shader (default: false)\r\n     */\r\n    constructor(\r\n        sceneOrEngine: Scene | AbstractEngine,\r\n        depthTexture: Nullable<RenderTargetTexture>,\r\n        blurLevel: DepthOfFieldEffectBlurLevel = DepthOfFieldEffectBlurLevel.Low,\r\n        pipelineTextureType = 0,\r\n        blockCompilation = false,\r\n        depthNotNormalized = false\r\n    ) {\r\n        const engine = (sceneOrEngine as Scene)._renderForCamera ? (sceneOrEngine as Scene).getEngine() : (sceneOrEngine as AbstractEngine);\r\n        super(\r\n            engine,\r\n            \"depth of field\",\r\n            () => {\r\n                return this._effects;\r\n            },\r\n            true\r\n        );\r\n\r\n        this._thinDepthOfFieldEffect = new ThinDepthOfFieldEffect(\r\n            \"Depth of Field\",\r\n            engine,\r\n            blurLevel as unknown as ThinDepthOfFieldEffectBlurLevel,\r\n            depthNotNormalized,\r\n            blockCompilation\r\n        );\r\n\r\n        // Use R-only formats if supported to store the circle of confusion values.\r\n        // This should be more space and bandwidth efficient than using RGBA.\r\n        const circleOfConfusionTextureFormat = engine.isWebGPU || engine.version > 1 ? Constants.TEXTUREFORMAT_RED : Constants.TEXTUREFORMAT_RGBA;\r\n\r\n        // Circle of confusion value for each pixel is used to determine how much to blur that pixel\r\n        this._circleOfConfusion = new CircleOfConfusionPostProcess(\r\n            \"circleOfConfusion\",\r\n            depthTexture,\r\n            {\r\n                size: 1,\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                textureType: pipelineTextureType,\r\n                blockCompilation,\r\n                depthNotNormalized,\r\n                effectWrapper: this._thinDepthOfFieldEffect._circleOfConfusion,\r\n            },\r\n            null\r\n        );\r\n\r\n        // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur)\r\n        // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts\r\n        // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf\r\n        this._depthOfFieldBlurY = [];\r\n        this._depthOfFieldBlurX = [];\r\n\r\n        const blurCount = this._thinDepthOfFieldEffect._depthOfFieldBlurX.length;\r\n\r\n        for (let i = 0; i < blurCount; i++) {\r\n            const [thinBlurY, ratioY] = this._thinDepthOfFieldEffect._depthOfFieldBlurY[i];\r\n            const blurY = new DepthOfFieldBlurPostProcess(\r\n                \"vertical blur\",\r\n                null,\r\n                thinBlurY.direction,\r\n                thinBlurY.kernel,\r\n                {\r\n                    size: ratioY,\r\n                    samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                    engine,\r\n                    textureType: pipelineTextureType,\r\n                    blockCompilation,\r\n                    textureFormat: i == 0 ? circleOfConfusionTextureFormat : Constants.TEXTUREFORMAT_RGBA,\r\n                    effectWrapper: thinBlurY,\r\n                },\r\n                null,\r\n                this._circleOfConfusion,\r\n                i == 0 ? this._circleOfConfusion : null\r\n            );\r\n            blurY.autoClear = false;\r\n\r\n            const [thinBlurX, ratioX] = this._thinDepthOfFieldEffect._depthOfFieldBlurX[i];\r\n            const blurX = new DepthOfFieldBlurPostProcess(\r\n                \"horizontal blur\",\r\n                null,\r\n                thinBlurX.direction,\r\n                thinBlurX.kernel,\r\n                {\r\n                    size: ratioX,\r\n                    samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                    engine,\r\n                    textureType: pipelineTextureType,\r\n                    blockCompilation,\r\n                    effectWrapper: thinBlurX,\r\n                },\r\n                null,\r\n                this._circleOfConfusion,\r\n                null\r\n            );\r\n            blurX.autoClear = false;\r\n            this._depthOfFieldBlurY.push(blurY);\r\n            this._depthOfFieldBlurX.push(blurX);\r\n        }\r\n\r\n        // Set all post processes on the effect.\r\n        this._effects = [this._circleOfConfusion];\r\n        for (let i = 0; i < this._depthOfFieldBlurX.length; i++) {\r\n            this._effects.push(this._depthOfFieldBlurY[i]);\r\n            this._effects.push(this._depthOfFieldBlurX[i]);\r\n        }\r\n\r\n        // Merge blurred images with original image based on circleOfConfusion\r\n        this._dofMerge = new DepthOfFieldMergePostProcess(\r\n            \"dofMerge\",\r\n            this._circleOfConfusion,\r\n            this._circleOfConfusion,\r\n            this._depthOfFieldBlurX,\r\n            {\r\n                size: this._thinDepthOfFieldEffect._depthOfFieldBlurX[blurCount - 1][1],\r\n                samplingMode: Texture.BILINEAR_SAMPLINGMODE,\r\n                engine,\r\n                textureType: pipelineTextureType,\r\n                blockCompilation,\r\n                effectWrapper: this._thinDepthOfFieldEffect._dofMerge,\r\n            },\r\n            null\r\n        );\r\n        this._dofMerge.autoClear = false;\r\n        this._effects.push(this._dofMerge);\r\n    }\r\n\r\n    /**\r\n     * Get the current class name of the current effect\r\n     * @returns \"DepthOfFieldEffect\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"DepthOfFieldEffect\";\r\n    }\r\n\r\n    /**\r\n     * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.\r\n     */\r\n    public set depthTexture(value: RenderTargetTexture) {\r\n        this._circleOfConfusion.depthTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Disposes each of the internal effects for a given camera.\r\n     * @param camera The camera to dispose the effect on.\r\n     */\r\n    public disposeEffects(camera: Camera) {\r\n        for (let effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {\r\n            this._effects[effectIndex].dispose(camera);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal Internal\r\n     */\r\n    public _updateEffects() {\r\n        for (let effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {\r\n            this._effects[effectIndex].updateEffect();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Internal\r\n     * @returns if all the contained post processes are ready.\r\n     * @internal\r\n     */\r\n    public _isReady() {\r\n        return this._thinDepthOfFieldEffect.isReady();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\n\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * DisplayPassPostProcess which produces an output the same as it's input\r\n */\r\nexport class DisplayPassPostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"DisplayPassPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"DisplayPassPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Creates the DisplayPassPostProcess\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: AbstractEngine, reusable?: boolean) {\r\n        super(name, \"displayPass\", [\"passSampler\"], [\"passSampler\"], options, camera, samplingMode, engine, reusable);\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/displayPass.fragment\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/displayPass.fragment\")]));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<DisplayPassPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new DisplayPassPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for displayPassPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterDisplayPassPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.DisplayPassPostProcess\", DisplayPassPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\n\r\nimport { serializeAsMatrix } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinFilterPostProcess } from \"./thinFilterPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Applies a kernel filter to the image\r\n */\r\nexport class FilterPostProcess extends PostProcess {\r\n    /** The matrix to be applied to the image */\r\n    @serializeAsMatrix()\r\n    public get kernelMatrix() {\r\n        return this._effectWrapper.kernelMatrix;\r\n    }\r\n\r\n    public set kernelMatrix(value: Matrix) {\r\n        this._effectWrapper.kernelMatrix = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"FilterPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FilterPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinFilterPostProcess;\r\n\r\n    /**\r\n     *\r\n     * @param name The name of the effect.\r\n     * @param kernelMatrix The matrix to be applied to the image\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        kernelMatrix: Matrix,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinFilterPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinFilterPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinFilterPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.kernelMatrix = kernelMatrix;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<FilterPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new FilterPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.kernelMatrix,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for filterPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFilterPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.FilterPostProcess\", FilterPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinGrainPostProcess } from \"./thinGrainPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The GrainPostProcess adds noise to the image at mid luminance levels\r\n */\r\nexport class GrainPostProcess extends PostProcess {\r\n    /**\r\n     * The intensity of the grain added (default: 30)\r\n     */\r\n    @serialize()\r\n    public get intensity() {\r\n        return this._effectWrapper.intensity;\r\n    }\r\n\r\n    public set intensity(value: number) {\r\n        this._effectWrapper.intensity = value;\r\n    }\r\n\r\n    /**\r\n     * If the grain should be randomized on every frame\r\n     */\r\n    @serialize()\r\n    public get animated() {\r\n        return this._effectWrapper.animated;\r\n    }\r\n\r\n    public set animated(value: boolean) {\r\n        this._effectWrapper.animated = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"GrainPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"GrainPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinGrainPostProcess;\r\n\r\n    /**\r\n     * Creates a new instance of @see GrainPostProcess\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinGrainPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinGrainPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinGrainPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new GrainPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for grainPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGrainPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.GrainPostProcess\", GrainPostProcess);\r\n}\r\n","import { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\n/**\r\n * Extracts highlights from the image\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses\r\n */\r\nexport class HighlightsPostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"HighlightsPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"HighlightsPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Extracts highlights from the image\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of texture for the post process (default: Engine.TEXTURETYPE_UNSIGNED_BYTE)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        super(name, \"highlights\", null, null, options, camera, samplingMode, engine, reusable, null, textureType);\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/highlights.fragment\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/highlights.fragment\")]));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Nullable } from \"../types\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { type Color4 } from \"../Maths/math.color\";\r\nimport { type Camera } from \"../Cameras/camera\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport { type ColorCurves } from \"../Materials/colorCurves\";\r\nimport { type ImageProcessingConfiguration } from \"../Materials/imageProcessingConfiguration\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { _ApplyWhiteBalanceOptions, ThinImageProcessingPostProcess } from \"./thinImageProcessingPostProcess\";\r\n\r\n/**\r\n * Options used to create an `ImageProcessingPostProcess`.\r\n */\r\nexport type ImageProcessingPostProcessOptions = PostProcessOptions & {\r\n    /**\r\n     * The correlated color temperature, in Kelvin, of the illuminant to neutralize via white balance - see\r\n     * `ImageProcessingConfiguration.temperature`. Providing this (or `tint`) also enables white balance.\r\n     * Defaults to 6500 K.\r\n     */\r\n    temperature?: number;\r\n\r\n    /**\r\n     * The white balance tint offset to apply, on the green/magenta axis - see `ImageProcessingConfiguration.tint`.\r\n     * Providing this (or `temperature`) also enables white balance. Defaults to 0 (no tint offset).\r\n     */\r\n    tint?: number;\r\n};\r\n\r\n/**\r\n * ImageProcessingPostProcess\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#imageprocessing\r\n */\r\nexport class ImageProcessingPostProcess extends PostProcess {\r\n    protected get _imageProcessingConfiguration(): ImageProcessingConfiguration {\r\n        return this._effectWrapper.imageProcessingConfiguration;\r\n    }\r\n\r\n    /**\r\n     * Gets the image processing configuration used either in this material.\r\n     */\r\n    public get imageProcessingConfiguration(): ImageProcessingConfiguration {\r\n        return this._effectWrapper.imageProcessingConfiguration;\r\n    }\r\n\r\n    /**\r\n     * Sets the Default image processing configuration used either in the this material.\r\n     *\r\n     * If sets to null, the scene one is in use.\r\n     */\r\n    public set imageProcessingConfiguration(value: ImageProcessingConfiguration) {\r\n        this._effectWrapper.imageProcessingConfiguration = value;\r\n    }\r\n\r\n    /**\r\n     * If the post process is supported.\r\n     */\r\n    public override get isSupported(): boolean {\r\n        const effect = this.getEffect();\r\n        return !effect || effect.isSupported;\r\n    }\r\n\r\n    /**\r\n     * Gets Color curves setup used in the effect if colorCurvesEnabled is set to true .\r\n     */\r\n    public get colorCurves(): Nullable<ColorCurves> {\r\n        return this.imageProcessingConfiguration.colorCurves;\r\n    }\r\n    /**\r\n     * Sets Color curves setup used in the effect if colorCurvesEnabled is set to true .\r\n     */\r\n    public set colorCurves(value: Nullable<ColorCurves>) {\r\n        this.imageProcessingConfiguration.colorCurves = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the color curves effect is enabled.\r\n     */\r\n    public get colorCurvesEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.colorCurvesEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the color curves effect is enabled.\r\n     */\r\n    public set colorCurvesEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.colorCurvesEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Color grading LUT texture used in the effect if colorGradingEnabled is set to true.\r\n     */\r\n    public get colorGradingTexture(): Nullable<BaseTexture> {\r\n        return this.imageProcessingConfiguration.colorGradingTexture;\r\n    }\r\n    /**\r\n     * Sets Color grading LUT texture used in the effect if colorGradingEnabled is set to true.\r\n     */\r\n    public set colorGradingTexture(value: Nullable<BaseTexture>) {\r\n        this.imageProcessingConfiguration.colorGradingTexture = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the color grading effect is enabled.\r\n     */\r\n    public get colorGradingEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.colorGradingEnabled;\r\n    }\r\n    /**\r\n     * Gets whether the color grading effect is enabled.\r\n     */\r\n    public set colorGradingEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.colorGradingEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets exposure used in the effect.\r\n     */\r\n    public get exposure(): number {\r\n        return this.imageProcessingConfiguration.exposure;\r\n    }\r\n    /**\r\n     * Sets exposure used in the effect.\r\n     */\r\n    public set exposure(value: number) {\r\n        this.imageProcessingConfiguration.exposure = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether tonemapping is enabled or not.\r\n     */\r\n    public get toneMappingEnabled(): boolean {\r\n        return this._imageProcessingConfiguration.toneMappingEnabled;\r\n    }\r\n    /**\r\n     * Sets whether tonemapping is enabled or not\r\n     */\r\n    public set toneMappingEnabled(value: boolean) {\r\n        this._imageProcessingConfiguration.toneMappingEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the type of tone mapping effect.\r\n     */\r\n    public get toneMappingType(): number {\r\n        return this._imageProcessingConfiguration.toneMappingType;\r\n    }\r\n    /**\r\n     * Sets the type of tone mapping effect.\r\n     */\r\n    public set toneMappingType(value: number) {\r\n        this._imageProcessingConfiguration.toneMappingType = value;\r\n    }\r\n\r\n    /**\r\n     * Gets contrast used in the effect.\r\n     */\r\n    public get contrast(): number {\r\n        return this.imageProcessingConfiguration.contrast;\r\n    }\r\n    /**\r\n     * Sets contrast used in the effect.\r\n     */\r\n    public set contrast(value: number) {\r\n        this.imageProcessingConfiguration.contrast = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the white balance effect is enabled.\r\n     */\r\n    public get whiteBalanceEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.whiteBalanceEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the white balance effect is enabled.\r\n     */\r\n    public set whiteBalanceEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.whiteBalanceEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the white balance correlated color temperature, in Kelvin, used in the effect.\r\n     */\r\n    public get temperature(): number {\r\n        return this.imageProcessingConfiguration.temperature;\r\n    }\r\n    /**\r\n     * Sets the white balance correlated color temperature, in Kelvin, used in the effect.\r\n     */\r\n    public set temperature(value: number) {\r\n        this.imageProcessingConfiguration.temperature = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the white balance tint offset used in the effect.\r\n     */\r\n    public get tint(): number {\r\n        return this.imageProcessingConfiguration.tint;\r\n    }\r\n    /**\r\n     * Sets the white balance tint offset used in the effect.\r\n     */\r\n    public set tint(value: number) {\r\n        this.imageProcessingConfiguration.tint = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette stretch size.\r\n     */\r\n    public get vignetteStretch(): number {\r\n        return this.imageProcessingConfiguration.vignetteStretch;\r\n    }\r\n    /**\r\n     * Sets Vignette stretch size.\r\n     */\r\n    public set vignetteStretch(value: number) {\r\n        this.imageProcessingConfiguration.vignetteStretch = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette center X Offset.\r\n     * @deprecated use vignetteCenterX instead\r\n     */\r\n    public get vignetteCentreX(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterX;\r\n    }\r\n    /**\r\n     * Sets Vignette center X Offset.\r\n     * @deprecated use vignetteCenterX instead\r\n     */\r\n    public set vignetteCentreX(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterX = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette center Y Offset.\r\n     * @deprecated use vignetteCenterY instead\r\n     */\r\n    public get vignetteCentreY(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterY;\r\n    }\r\n    /**\r\n     * Sets Vignette center Y Offset.\r\n     * @deprecated use vignetteCenterY instead\r\n     */\r\n    public set vignetteCentreY(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterY = value;\r\n    }\r\n\r\n    /**\r\n     * Vignette center Y Offset.\r\n     */\r\n    public get vignetteCenterY(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterY;\r\n    }\r\n    public set vignetteCenterY(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterY = value;\r\n    }\r\n\r\n    /**\r\n     * Vignette center X Offset.\r\n     */\r\n    public get vignetteCenterX(): number {\r\n        return this.imageProcessingConfiguration.vignetteCenterX;\r\n    }\r\n    public set vignetteCenterX(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCenterX = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Vignette weight or intensity of the vignette effect.\r\n     */\r\n    public get vignetteWeight(): number {\r\n        return this.imageProcessingConfiguration.vignetteWeight;\r\n    }\r\n    /**\r\n     * Sets Vignette weight or intensity of the vignette effect.\r\n     */\r\n    public set vignetteWeight(value: number) {\r\n        this.imageProcessingConfiguration.vignetteWeight = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)\r\n     * if vignetteEnabled is set to true.\r\n     */\r\n    public get vignetteColor(): Color4 {\r\n        return this.imageProcessingConfiguration.vignetteColor;\r\n    }\r\n    /**\r\n     * Sets Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)\r\n     * if vignetteEnabled is set to true.\r\n     */\r\n    public set vignetteColor(value: Color4) {\r\n        this.imageProcessingConfiguration.vignetteColor = value;\r\n    }\r\n\r\n    /**\r\n     * Gets Camera field of view used by the Vignette effect.\r\n     */\r\n    public get vignetteCameraFov(): number {\r\n        return this.imageProcessingConfiguration.vignetteCameraFov;\r\n    }\r\n    /**\r\n     * Sets Camera field of view used by the Vignette effect.\r\n     */\r\n    public set vignetteCameraFov(value: number) {\r\n        this.imageProcessingConfiguration.vignetteCameraFov = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the vignette blend mode allowing different kind of effect.\r\n     */\r\n    public get vignetteBlendMode(): number {\r\n        return this.imageProcessingConfiguration.vignetteBlendMode;\r\n    }\r\n    /**\r\n     * Sets the vignette blend mode allowing different kind of effect.\r\n     */\r\n    public set vignetteBlendMode(value: number) {\r\n        this.imageProcessingConfiguration.vignetteBlendMode = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the vignette effect is enabled.\r\n     */\r\n    public get vignetteEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.vignetteEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the vignette effect is enabled.\r\n     */\r\n    public set vignetteEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.vignetteEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets intensity of the dithering effect.\r\n     */\r\n    public get ditheringIntensity(): number {\r\n        return this.imageProcessingConfiguration.ditheringIntensity;\r\n    }\r\n    /**\r\n     * Sets intensity of the dithering effect.\r\n     */\r\n    public set ditheringIntensity(value: number) {\r\n        this.imageProcessingConfiguration.ditheringIntensity = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the dithering effect is enabled.\r\n     */\r\n    public get ditheringEnabled(): boolean {\r\n        return this.imageProcessingConfiguration.ditheringEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the dithering effect is enabled.\r\n     */\r\n    public set ditheringEnabled(value: boolean) {\r\n        this.imageProcessingConfiguration.ditheringEnabled = value;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the input of the processing is in Gamma or Linear Space.\r\n     */\r\n    @serialize()\r\n    public get fromLinearSpace(): boolean {\r\n        return this._effectWrapper.fromLinearSpace;\r\n    }\r\n    /**\r\n     * Sets whether the input of the processing is in Gamma or Linear Space.\r\n     */\r\n    public set fromLinearSpace(value: boolean) {\r\n        this._effectWrapper.fromLinearSpace = value;\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinImageProcessingPostProcess;\r\n\r\n    constructor(\r\n        name: string,\r\n        options: number | ImageProcessingPostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        imageProcessingConfiguration?: ImageProcessingConfiguration\r\n    ) {\r\n        const localOptions = {\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            imageProcessingConfiguration,\r\n            scene: camera?.getScene(),\r\n            ...(options as ImageProcessingPostProcessOptions),\r\n            blockCompilation: true,\r\n        };\r\n\r\n        super(name, ThinImageProcessingPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinImageProcessingPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        // Applied here (not just inside ThinImageProcessingPostProcess's own constructor) so that `temperature`/\r\n        // `tint` are honored even when a caller supplies their own pre-built `effectWrapper`, in which case the\r\n        // thin wrapper above is never constructed and its own application of these options never runs.\r\n        _ApplyWhiteBalanceOptions(this.imageProcessingConfiguration, options);\r\n\r\n        this.onApply = () => {\r\n            this._effectWrapper.overrideAspectRatio = this.aspectRatio;\r\n        };\r\n    }\r\n\r\n    /**\r\n     *  \"ImageProcessingPostProcess\"\r\n     * @returns \"ImageProcessingPostProcess\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ImageProcessingPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _updateParameters(): void {\r\n        this._effectWrapper._updateParameters();\r\n    }\r\n    public override dispose(camera?: Camera): void {\r\n        super.dispose(camera);\r\n\r\n        if (this._imageProcessingConfiguration) {\r\n            this.imageProcessingConfiguration.applyByPostProcess = false;\r\n        }\r\n    }\r\n}\r\n","import { Constants } from \"../Engines/constants\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\n\r\n/**\r\n * Contains all parameters needed for the prepass to perform\r\n * motion blur\r\n */\r\nexport class MotionBlurConfiguration implements PrePassEffectConfiguration {\r\n    /**\r\n     * Is motion blur enabled\r\n     */\r\n    public enabled = false;\r\n\r\n    /**\r\n     * Name of the configuration\r\n     */\r\n    public name = \"motionBlur\";\r\n\r\n    /**\r\n     * Textures that should be present in the MRT for this effect to work\r\n     */\r\n    public readonly texturesRequired: number[] = [Constants.PREPASS_VELOCITY_TEXTURE_TYPE];\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type PostProcessOptions } from \"./postProcess\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { GeometryBufferRenderer } from \"../Rendering/geometryBufferRenderer.pure\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { MotionBlurConfiguration } from \"../Rendering/motionBlurConfiguration\";\r\nimport { type PrePassRenderer } from \"../Rendering/prePassRenderer.pure\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinMotionBlurPostProcess } from \"./thinMotionBlurPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The Motion Blur Post Process which blurs an image based on the objects velocity in scene.\r\n * Velocity can be affected by each object's rotation, position and scale depending on the transformation speed.\r\n * As an example, all you have to do is to create the post-process:\r\n *  var mb = new BABYLON.MotionBlurPostProcess(\r\n *      'mb', // The name of the effect.\r\n *      scene, // The scene containing the objects to blur according to their velocity.\r\n *      1.0, // The required width/height ratio to downsize to before computing the render pass.\r\n *      camera // The camera to apply the render pass to.\r\n * );\r\n * Then, all objects moving, rotating and/or scaling will be blurred depending on the transformation speed.\r\n */\r\nexport class MotionBlurPostProcess extends PostProcess {\r\n    /**\r\n     * Defines how much the image is blurred by the movement. Default value is equal to 1\r\n     */\r\n    @serialize()\r\n    public get motionStrength() {\r\n        return this._effectWrapper.motionStrength;\r\n    }\r\n\r\n    public set motionStrength(value: number) {\r\n        this._effectWrapper.motionStrength = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the number of iterations are used for motion blur quality. Default value is equal to 32\r\n     */\r\n    @serialize()\r\n    public get motionBlurSamples(): number {\r\n        return this._effectWrapper.motionBlurSamples;\r\n    }\r\n\r\n    /**\r\n     * Sets the number of iterations to be used for motion blur quality\r\n     */\r\n    public set motionBlurSamples(samples: number) {\r\n        this._effectWrapper.motionBlurSamples = samples;\r\n    }\r\n\r\n    /**\r\n     * Gets whether or not the motion blur post-process is in object based mode.\r\n     */\r\n    @serialize()\r\n    public get isObjectBased(): boolean {\r\n        return this._effectWrapper.isObjectBased;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not the motion blur post-process is in object based mode.\r\n     */\r\n    public set isObjectBased(value: boolean) {\r\n        if (this.isObjectBased === value) {\r\n            return;\r\n        }\r\n\r\n        this._effectWrapper.isObjectBased = value;\r\n        this._applyMode();\r\n    }\r\n\r\n    private _forcedGeometryBuffer: Nullable<GeometryBufferRenderer> = null;\r\n\r\n    private _forceGeometryBuffer: boolean = false;\r\n    private get _geometryBufferRenderer(): Nullable<GeometryBufferRenderer> {\r\n        if (!this._forceGeometryBuffer) {\r\n            return null;\r\n        }\r\n\r\n        return this._forcedGeometryBuffer ?? this._scene.geometryBufferRenderer;\r\n    }\r\n\r\n    private get _prePassRenderer(): Nullable<PrePassRenderer> {\r\n        if (this._forceGeometryBuffer) {\r\n            return null;\r\n        }\r\n\r\n        return this._scene.prePassRenderer;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"MotionBlurPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"MotionBlurPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinMotionBlurPostProcess;\r\n\r\n    /**\r\n     * Creates a new instance MotionBlurPostProcess\r\n     * @param name The name of the effect.\r\n     * @param scene The scene containing the objects to blur according to their velocity.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: true)\r\n     * @param forceGeometryBuffer If this post process should use geometry buffer instead of prepass (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false,\r\n        forceGeometryBuffer: boolean | GeometryBufferRenderer = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinMotionBlurPostProcess.Uniforms,\r\n            samplers: ThinMotionBlurPostProcess.Samplers,\r\n            defines: ThinMotionBlurPostProcess.Defines,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinMotionBlurPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinMotionBlurPostProcess(name, scene, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        if (forceGeometryBuffer instanceof GeometryBufferRenderer) {\r\n            this._forceGeometryBuffer = true;\r\n            this._forcedGeometryBuffer = forceGeometryBuffer;\r\n        } else {\r\n            this._forceGeometryBuffer = forceGeometryBuffer;\r\n        }\r\n\r\n        // Set up assets\r\n        if (this._forceGeometryBuffer) {\r\n            if (!this._forcedGeometryBuffer) {\r\n                scene.enableGeometryBufferRenderer();\r\n            }\r\n\r\n            if (this._geometryBufferRenderer) {\r\n                this._geometryBufferRenderer.enableVelocity = this.isObjectBased;\r\n            }\r\n        } else {\r\n            scene.enablePrePassRenderer();\r\n\r\n            if (this._prePassRenderer) {\r\n                this._prePassRenderer.markAsDirty();\r\n                this._prePassEffectConfiguration = new MotionBlurConfiguration();\r\n            }\r\n        }\r\n\r\n        this._applyMode();\r\n    }\r\n\r\n    /**\r\n     * Excludes the given skinned mesh from computing bones velocities.\r\n     * Computing bones velocities can have a cost and that cost. The cost can be saved by calling this function and by passing the skinned mesh reference to ignore.\r\n     * @param skinnedMesh The mesh containing the skeleton to ignore when computing the velocity map.\r\n     */\r\n    public excludeSkinnedMesh(skinnedMesh: AbstractMesh): void {\r\n        if (skinnedMesh.skeleton) {\r\n            let list;\r\n            if (this._geometryBufferRenderer) {\r\n                list = this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity;\r\n            } else if (this._prePassRenderer) {\r\n                list = this._prePassRenderer.excludedSkinnedMesh;\r\n            } else {\r\n                return;\r\n            }\r\n            list.push(skinnedMesh);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Removes the given skinned mesh from the excluded meshes to integrate bones velocities while rendering the velocity map.\r\n     * @param skinnedMesh The mesh containing the skeleton that has been ignored previously.\r\n     * @see excludeSkinnedMesh to exclude a skinned mesh from bones velocity computation.\r\n     */\r\n    public removeExcludedSkinnedMesh(skinnedMesh: AbstractMesh): void {\r\n        if (skinnedMesh.skeleton) {\r\n            let list;\r\n            if (this._geometryBufferRenderer) {\r\n                list = this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity;\r\n            } else if (this._prePassRenderer) {\r\n                list = this._prePassRenderer.excludedSkinnedMesh;\r\n            } else {\r\n                return;\r\n            }\r\n\r\n            const index = list.indexOf(skinnedMesh);\r\n            if (index !== -1) {\r\n                list.splice(index, 1);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the post process.\r\n     * @param camera The camera to dispose the post process on.\r\n     */\r\n    public override dispose(camera?: Camera): void {\r\n        if (this._geometryBufferRenderer && !this._forcedGeometryBuffer) {\r\n            // Clear previous transformation matrices dictionary used to compute objects velocities\r\n            this._geometryBufferRenderer._previousTransformationMatrices = {};\r\n            this._geometryBufferRenderer._previousBonesTransformationMatrices = {};\r\n            this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity = [];\r\n        }\r\n\r\n        super.dispose(camera);\r\n    }\r\n\r\n    /**\r\n     * Called on the mode changed (object based or screen based).\r\n     */\r\n    private _applyMode() {\r\n        if (!this._geometryBufferRenderer && !this._prePassRenderer) {\r\n            // We can't get a velocity or depth texture. So, work as a passthrough.\r\n            Logger.Warn(\"Multiple Render Target support needed to compute object based motion blur\");\r\n            return;\r\n        }\r\n\r\n        if (this._geometryBufferRenderer) {\r\n            this._geometryBufferRenderer.enableVelocity = this.isObjectBased;\r\n        }\r\n\r\n        if (this.isObjectBased) {\r\n            if (this._prePassRenderer && this._prePassEffectConfiguration) {\r\n                this._prePassEffectConfiguration.texturesRequired[0] = Constants.PREPASS_VELOCITY_TEXTURE_TYPE;\r\n            }\r\n\r\n            this.onApply = (effect: Effect) => this._onApplyObjectBased(effect);\r\n        } else {\r\n            if (this._prePassRenderer && this._prePassEffectConfiguration) {\r\n                this._prePassEffectConfiguration.texturesRequired[0] = Constants.PREPASS_DEPTH_TEXTURE_TYPE;\r\n            }\r\n\r\n            this.onApply = (effect: Effect) => this._onApplyScreenBased(effect);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on the effect is applied when the motion blur post-process is in object based mode.\r\n     * @param effect\r\n     */\r\n    private _onApplyObjectBased(effect: Effect): void {\r\n        this._effectWrapper.textureWidth = this.width;\r\n        this._effectWrapper.textureHeight = this.height;\r\n        if (this._geometryBufferRenderer) {\r\n            const velocityIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE);\r\n            effect.setTexture(\"velocitySampler\", this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);\r\n        } else if (this._prePassRenderer) {\r\n            const velocityIndex = this._prePassRenderer.getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE);\r\n            effect.setTexture(\"velocitySampler\", this._prePassRenderer.getRenderTarget().textures[velocityIndex]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Called on the effect is applied when the motion blur post-process is in screen based mode.\r\n     * @param effect\r\n     */\r\n    private _onApplyScreenBased(effect: Effect): void {\r\n        this._effectWrapper.textureWidth = this.width;\r\n        this._effectWrapper.textureHeight = this.height;\r\n        if (this._geometryBufferRenderer) {\r\n            const depthIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.DEPTH_TEXTURE_TYPE);\r\n            effect.setTexture(\"depthSampler\", this._geometryBufferRenderer.getGBuffer().textures[depthIndex]);\r\n        } else if (this._prePassRenderer) {\r\n            const depthIndex = this._prePassRenderer.getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE);\r\n            effect.setTexture(\"depthSampler\", this._prePassRenderer.getRenderTarget().textures[depthIndex]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<MotionBlurPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new MotionBlurPostProcess(\r\n                    parsedPostProcess.name,\r\n                    scene,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.textureType,\r\n                    false\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for motionBlurPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterMotionBlurPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.MotionBlurPostProcess\", MotionBlurPostProcess);\r\n}\r\n","import { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture.pure\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { PostProcess, type PostProcessOptions } from \"./postProcess.pure\";\r\nimport {\r\n    type IMeshBlendConfiguration,\r\n    type MeshBlendDebugMode,\r\n    MeshBlendDepthType,\r\n    type MeshBlendQuality,\r\n    type MeshBlendRadiusDefinitions,\r\n    ThinMeshBlendingPostProcess,\r\n    _ClaimMeshBlendingEffectWrapper,\r\n    _IsMeshBlendingEffectWrapperOwned,\r\n    _ReleaseMeshBlendingEffectWrapper,\r\n    _ValidateMeshBlendConfiguration,\r\n} from \"./thinMeshBlendingPostProcess\";\r\n\r\n/**\r\n * Options used to create a mesh-blending post process.\r\n */\r\nexport interface IMeshBlendingPostProcessOptions extends PostProcessOptions, IMeshBlendConfiguration {\r\n    /** Optional caller-owned thin mesh-blending effect wrapper. A wrapper can be attached to only one classic post process at a time. */\r\n    effectWrapper?: ThinMeshBlendingPostProcess;\r\n    /**\r\n     * The packed R8UI mesh-blending tag texture.\r\n     */\r\n    meshBlendTagTexture: BaseTexture;\r\n    /**\r\n     * The view-depth or screen-depth texture aligned with the packed tag texture.\r\n     */\r\n    depthTexture: BaseTexture;\r\n    /**\r\n     * Optional linear base-color/albedo geometry texture aligned with SceneColor.\r\n     *\r\n     * When omitted, shadow estimation is compiled out.\r\n     */\r\n    baseColorTexture?: BaseTexture;\r\n}\r\n\r\n/**\r\n * Visually blends SceneColor across validated contacts between opaque or alpha-tested meshes.\r\n *\r\n * This WebGL2 and WebGPU effect does not change geometry, collision queries, depth, normals, or shadow geometry.\r\n * Transparent rendering is caller-controlled. Applications assign explicit group IDs from 1 through 63;\r\n * group 0 disables blending, and surfaces with the same nonzero group are treated as one logical object.\r\n *\r\n * The classic wrapper consumes caller-owned geometry textures and does not enable, configure, or dispose\r\n * a GeometryBufferRenderer. The tag, depth, and SceneColor inputs are required; optional base color enables\r\n * shadow estimation. All provided geometry inputs must have the same physical dimensions and sample count and\r\n * are single-sampled. Overlapping transparent surfaces can make SceneColor inconsistent with the single-layer\r\n * geometry inputs; compositing transparent content after this effect remains the recommended configuration.\r\n *\r\n * Four configurable radius classes combine world-space radii with physical-pixel minimums, for both\r\n * perspective and orthographic cameras. Quality variants trade search work for seam quality. Stable search\r\n * noise is internal and frame invariant. This implementation does not use temporal accumulation or require TAA.\r\n *\r\n * The classic wrapper is runtime-only because its geometry textures are caller-owned resources. It cannot\r\n * be serialized, parsed, or cloned; use the FrameGraph/NRGE path when a serializable graph is required.\r\n * @see https://meshblend.lervik.com/\r\n * @see https://www.jacktollenaar.top/articles/meshblending.html\r\n * @see https://www.jacktollenaar.top/articles/meshblending2.html\r\n * @see https://bottosson.github.io/posts/oklab/\r\n * @see https://playground.babylonjs.com/?version=preview#XVZTSI#3\r\n * @see https://playground.babylonjs.com/?version=preview#O05LI8#6\r\n */\r\nexport class MeshBlendingPostProcess extends PostProcess {\r\n    declare protected _effectWrapper: ThinMeshBlendingPostProcess;\r\n\r\n    private _meshBlendTagTexture: BaseTexture;\r\n    private _depthTexture: BaseTexture;\r\n    private _baseColorTexture: Nullable<BaseTexture>;\r\n    private readonly _ownsEffectWrapper: boolean;\r\n\r\n    /**\r\n     * Gets the compile-time quality variant.\r\n     */\r\n    public get quality(): MeshBlendQuality {\r\n        return this._effectWrapper.quality;\r\n    }\r\n\r\n    public set quality(value: MeshBlendQuality) {\r\n        this._effectWrapper.quality = value;\r\n    }\r\n\r\n    /**\r\n     * The packed R8UI mesh-blending tag texture used by the effect.\r\n     */\r\n    public get meshBlendTagTexture(): BaseTexture {\r\n        return this._meshBlendTagTexture;\r\n    }\r\n\r\n    public set meshBlendTagTexture(value: BaseTexture) {\r\n        MeshBlendingPostProcess._ValidateMeshBlendTagTexture(value);\r\n        MeshBlendingPostProcess._ValidateInputTextureDimensions(value, this._depthTexture, this._baseColorTexture);\r\n        this._meshBlendTagTexture = value;\r\n        this._validateInputDimensions();\r\n    }\r\n\r\n    /**\r\n     * The depth texture used for position reconstruction and contact validation.\r\n     */\r\n    public get depthTexture(): BaseTexture {\r\n        return this._depthTexture;\r\n    }\r\n\r\n    public set depthTexture(value: BaseTexture) {\r\n        MeshBlendingPostProcess._ValidateDepthTexture(value, this.depthType);\r\n        MeshBlendingPostProcess._ValidateInputTextureDimensions(this._meshBlendTagTexture, value, this._baseColorTexture);\r\n        this._depthTexture = value;\r\n        this._validateInputDimensions();\r\n    }\r\n\r\n    /**\r\n     * The optional linear base-color/albedo geometry texture used by the shadow-transfer heuristic.\r\n     *\r\n     * Setting null compiles shadow estimation out.\r\n     */\r\n    public get baseColorTexture(): Nullable<BaseTexture> {\r\n        return this._baseColorTexture;\r\n    }\r\n\r\n    public set baseColorTexture(value: Nullable<BaseTexture>) {\r\n        if (value) {\r\n            MeshBlendingPostProcess._ValidateBaseColorTexture(value);\r\n        }\r\n        MeshBlendingPostProcess._ValidateInputTextureDimensions(this._meshBlendTagTexture, this._depthTexture, value);\r\n        this._baseColorTexture = value;\r\n        this._effectWrapper.hasBaseColorTexture = !!value;\r\n        this._validateInputDimensions();\r\n    }\r\n\r\n    /**\r\n     * Gets the representation stored in the depth texture.\r\n     */\r\n    public get depthType(): MeshBlendDepthType {\r\n        return this._effectWrapper.depthType;\r\n    }\r\n\r\n    public set depthType(value: MeshBlendDepthType) {\r\n        if (this._depthTexture) {\r\n            MeshBlendingPostProcess._ValidateDepthTexture(this._depthTexture, value);\r\n        }\r\n        this._effectWrapper.depthType = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the four configurable radius definitions indexed by packed radius class.\r\n     */\r\n    public get radiusClasses(): MeshBlendRadiusDefinitions {\r\n        return this._effectWrapper.radiusClasses;\r\n    }\r\n\r\n    /**\r\n     * Gets the compiled debug visualization.\r\n     */\r\n    public get debugMode(): MeshBlendDebugMode {\r\n        return this._effectWrapper.debugMode;\r\n    }\r\n\r\n    public set debugMode(value: MeshBlendDebugMode) {\r\n        this._effectWrapper.debugMode = value;\r\n    }\r\n\r\n    /** Contact-slope narrowing factor. A value of 1 disables narrowing. */\r\n    public get slopeFactor(): number {\r\n        return this._effectWrapper.slopeFactor;\r\n    }\r\n\r\n    public set slopeFactor(value: number) {\r\n        this._effectWrapper.slopeFactor = value;\r\n    }\r\n\r\n    /**\r\n     * Applies shared mesh-blending configuration.\r\n     * @param options Values to apply. Omitted values retain their current settings.\r\n     */\r\n    public configure(options?: IMeshBlendConfiguration): void {\r\n        if (options?.depthType !== undefined) {\r\n            MeshBlendingPostProcess._ValidateDepthTexture(this._depthTexture, options.depthType);\r\n        }\r\n        this._effectWrapper.configure(options);\r\n    }\r\n\r\n    /**\r\n     * Creates a mesh-blending post process.\r\n     * @param name The name of the post process.\r\n     * @param scene The scene containing the camera.\r\n     * @param camera The camera to attach the post process to.\r\n     * @param options The post-process and input-texture options.\r\n     */\r\n    constructor(name: string, scene: Scene, camera: Camera, options: IMeshBlendingPostProcessOptions) {\r\n        const sceneEngine = scene.getEngine();\r\n        if (camera.getScene() !== scene) {\r\n            throw new Error(\"MeshBlendingPostProcess: scene and camera must belong to the same scene\");\r\n        }\r\n        if (options.engine !== undefined && options.engine !== sceneEngine) {\r\n            throw new Error(\"MeshBlendingPostProcess: options.engine must match the scene engine\");\r\n        }\r\n        if (options.effectWrapper !== undefined && !(options.effectWrapper instanceof ThinMeshBlendingPostProcess)) {\r\n            throw new TypeError(\"MeshBlendingPostProcess: effectWrapper must be a ThinMeshBlendingPostProcess\");\r\n        }\r\n        if (options.effectWrapper !== undefined && options.effectWrapper.options.engine !== sceneEngine) {\r\n            throw new Error(\"MeshBlendingPostProcess: effectWrapper must use the scene engine\");\r\n        }\r\n        if (options.effectWrapper !== undefined && _IsMeshBlendingEffectWrapperOwned(options.effectWrapper)) {\r\n            throw new Error(\"MeshBlendingPostProcess: effectWrapper is already attached to another classic mesh-blending post process\");\r\n        }\r\n        const depthType = options.depthType ?? options.effectWrapper?.depthType ?? MeshBlendDepthType.View;\r\n        MeshBlendingPostProcess._ValidateInputs(options, depthType);\r\n\r\n        const ownsEffectWrapper = options.effectWrapper === undefined;\r\n        const effectWrapper = options.effectWrapper ?? new ThinMeshBlendingPostProcess(name, sceneEngine, options);\r\n        effectWrapper.hasBaseColorTexture = !!options.baseColorTexture;\r\n\r\n        super(name, ThinMeshBlendingPostProcess.FragmentUrl, {\r\n            ...options,\r\n            camera,\r\n            engine: sceneEngine,\r\n            effectWrapper,\r\n            uniforms: ThinMeshBlendingPostProcess.Uniforms,\r\n            samplers: ThinMeshBlendingPostProcess.Samplers,\r\n            textureType: options.textureType ?? Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        });\r\n\r\n        this._ownsEffectWrapper = ownsEffectWrapper;\r\n        _ClaimMeshBlendingEffectWrapper(effectWrapper, this);\r\n        this._meshBlendTagTexture = options.meshBlendTagTexture;\r\n        this._depthTexture = options.depthTexture;\r\n        this._baseColorTexture = options.baseColorTexture ?? null;\r\n\r\n        this._effectWrapper.configure(options);\r\n        this._effectWrapper.camera = camera;\r\n        this.doNotSerialize = true;\r\n        this._validateInputDimensions();\r\n\r\n        this.onApply = (effect: Effect) => {\r\n            this._validateInputDimensions(this.width, this.height, this.inputTexture.samples);\r\n            this._effectWrapper.camera = this.getCamera();\r\n            effect.setTexture(\"meshBlendTagSampler\", this._meshBlendTagTexture);\r\n            effect.setTexture(\"meshBlendDepthSampler\", this._depthTexture);\r\n            if (this._baseColorTexture) {\r\n                effect.setTexture(\"meshBlendBaseColorSampler\", this._baseColorTexture);\r\n            }\r\n        };\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"MeshBlendingPostProcess\";\r\n    }\r\n\r\n    public override dispose(camera?: Camera): void {\r\n        super.dispose(camera);\r\n        _ReleaseMeshBlendingEffectWrapper(this._effectWrapper, this);\r\n        if (this._ownsEffectWrapper) {\r\n            this._effectWrapper.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Classic mesh blending cannot be serialized because its geometry inputs are caller-owned runtime textures.\r\n     * @throws Always throws because the classic wrapper is runtime-only.\r\n     */\r\n    public override serialize(): never {\r\n        throw new Error(\"MeshBlendingPostProcess cannot be serialized; use the FrameGraph/NRGE path for serializable mesh blending\");\r\n    }\r\n\r\n    /**\r\n     * Classic mesh blending cannot be cloned because its geometry inputs are caller-owned runtime textures.\r\n     * @returns Null.\r\n     */\r\n    public override clone(): null {\r\n        return null;\r\n    }\r\n\r\n    private static _ValidateInputs(options: IMeshBlendingPostProcessOptions, depthType: MeshBlendDepthType): void {\r\n        _ValidateMeshBlendConfiguration(options);\r\n        MeshBlendingPostProcess._ValidateMeshBlendTagTexture(options.meshBlendTagTexture);\r\n        MeshBlendingPostProcess._ValidateDepthTexture(options.depthTexture, depthType);\r\n        if (options.baseColorTexture) {\r\n            MeshBlendingPostProcess._ValidateBaseColorTexture(options.baseColorTexture);\r\n        }\r\n        MeshBlendingPostProcess._ValidateInputTextureDimensions(options.meshBlendTagTexture, options.depthTexture, options.baseColorTexture);\r\n    }\r\n\r\n    private static _ValidateInputTextureDimensions(meshBlendTagTexture: BaseTexture, depthTexture: BaseTexture, baseColorTexture: Nullable<BaseTexture> | undefined): void {\r\n        const tagInternalTexture = meshBlendTagTexture.getInternalTexture();\r\n        const depthInternalTexture = depthTexture.getInternalTexture();\r\n        const baseColorInternalTexture = baseColorTexture?.getInternalTexture();\r\n        if (!tagInternalTexture || !depthInternalTexture) {\r\n            return;\r\n        }\r\n\r\n        if (\r\n            tagInternalTexture.width !== depthInternalTexture.width ||\r\n            tagInternalTexture.height !== depthInternalTexture.height ||\r\n            (baseColorInternalTexture !== null &&\r\n                baseColorInternalTexture !== undefined &&\r\n                (tagInternalTexture.width !== baseColorInternalTexture.width || tagInternalTexture.height !== baseColorInternalTexture.height))\r\n        ) {\r\n            throw new Error(\"MeshBlendingPostProcess: meshBlendTagTexture, depthTexture, and baseColorTexture when provided must have matching physical dimensions\");\r\n        }\r\n        const inputSamples = tagInternalTexture.samples || 1;\r\n        if (\r\n            (depthInternalTexture.samples || 1) !== inputSamples ||\r\n            (baseColorInternalTexture !== null && baseColorInternalTexture !== undefined && (baseColorInternalTexture.samples || 1) !== inputSamples)\r\n        ) {\r\n            throw new Error(\"MeshBlendingPostProcess: meshBlendTagTexture, depthTexture, and baseColorTexture when provided must have matching sample counts\");\r\n        }\r\n    }\r\n\r\n    private static _ValidateMeshBlendTagTexture(texture: BaseTexture): void {\r\n        const internalTexture = texture.getInternalTexture();\r\n        if (!internalTexture) {\r\n            return;\r\n        }\r\n        MeshBlendingPostProcess._Validate2DTexture(internalTexture, \"meshBlendTagTexture\");\r\n        if (internalTexture.type !== Constants.TEXTURETYPE_UNSIGNED_BYTE || internalTexture.format !== Constants.TEXTUREFORMAT_RED_INTEGER) {\r\n            throw new Error(\"MeshBlendingPostProcess: meshBlendTagTexture must use TEXTURETYPE_UNSIGNED_BYTE with TEXTUREFORMAT_RED_INTEGER\");\r\n        }\r\n        if (internalTexture.generateMipMaps || internalTexture.samplingMode !== Constants.TEXTURE_NEAREST_SAMPLINGMODE || internalTexture.samples > 1) {\r\n            throw new Error(\"MeshBlendingPostProcess: meshBlendTagTexture must use nearest sampling without mipmaps and must be single-sampled\");\r\n        }\r\n    }\r\n\r\n    private static _ValidateDepthTexture(texture: BaseTexture, depthType: MeshBlendDepthType): void {\r\n        const internalTexture = texture.getInternalTexture();\r\n        if (!internalTexture) {\r\n            return;\r\n        }\r\n        MeshBlendingPostProcess._Validate2DTexture(internalTexture, \"depthTexture\");\r\n\r\n        const validFormat =\r\n            internalTexture.format === Constants.TEXTUREFORMAT_RED ||\r\n            internalTexture.format === Constants.TEXTUREFORMAT_RG ||\r\n            internalTexture.format === Constants.TEXTUREFORMAT_RGBA;\r\n        const validType =\r\n            internalTexture.type === Constants.TEXTURETYPE_FLOAT ||\r\n            internalTexture.type === Constants.TEXTURETYPE_HALF_FLOAT ||\r\n            (depthType === MeshBlendDepthType.Screen && internalTexture.type === Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n\r\n        if (!validFormat || !validType) {\r\n            throw new Error(\r\n                `MeshBlendingPostProcess: ${depthType === MeshBlendDepthType.View ? \"view\" : \"screen\"} depthTexture must use a floating-point color format${\r\n                    depthType === MeshBlendDepthType.Screen ? \" or normalized unsigned bytes\" : \"\"\r\n                }`\r\n            );\r\n        }\r\n        if (internalTexture.generateMipMaps || internalTexture.samples > 1) {\r\n            throw new Error(\"MeshBlendingPostProcess: depthTexture must not use mipmaps and must be single-sampled\");\r\n        }\r\n    }\r\n\r\n    private static _ValidateBaseColorTexture(texture: BaseTexture): void {\r\n        const internalTexture = texture.getInternalTexture();\r\n        if (!internalTexture) {\r\n            return;\r\n        }\r\n        MeshBlendingPostProcess._Validate2DTexture(internalTexture, \"baseColorTexture\");\r\n\r\n        const validFormat = internalTexture.format === Constants.TEXTUREFORMAT_RGB || internalTexture.format === Constants.TEXTUREFORMAT_RGBA;\r\n        const validType =\r\n            internalTexture.type === Constants.TEXTURETYPE_UNSIGNED_BYTE ||\r\n            internalTexture.type === Constants.TEXTURETYPE_HALF_FLOAT ||\r\n            internalTexture.type === Constants.TEXTURETYPE_FLOAT;\r\n        if (!validFormat || !validType) {\r\n            throw new Error(\"MeshBlendingPostProcess: baseColorTexture must use a non-integer RGB or RGBA color format\");\r\n        }\r\n        if (internalTexture.generateMipMaps || internalTexture.samples > 1) {\r\n            throw new Error(\"MeshBlendingPostProcess: baseColorTexture must not use mipmaps and must be single-sampled\");\r\n        }\r\n    }\r\n\r\n    private static _Validate2DTexture(internalTexture: InternalTexture, name: string): void {\r\n        if (internalTexture.isCube || internalTexture.is3D || internalTexture.is2DArray) {\r\n            throw new Error(`MeshBlendingPostProcess: ${name} must be a 2D texture`);\r\n        }\r\n    }\r\n\r\n    private _validateInputDimensions(renderWidth?: number, renderHeight?: number, renderSamples?: number): void {\r\n        MeshBlendingPostProcess._ValidateMeshBlendTagTexture(this._meshBlendTagTexture);\r\n        MeshBlendingPostProcess._ValidateDepthTexture(this._depthTexture, this.depthType);\r\n        if (this._baseColorTexture) {\r\n            MeshBlendingPostProcess._ValidateBaseColorTexture(this._baseColorTexture);\r\n        }\r\n\r\n        const tagTexture = this._meshBlendTagTexture?.getInternalTexture();\r\n        const depthTexture = this._depthTexture?.getInternalTexture();\r\n        const baseColorTexture = this._baseColorTexture?.getInternalTexture();\r\n        if (!tagTexture || !depthTexture) {\r\n            return;\r\n        }\r\n\r\n        MeshBlendingPostProcess._ValidateInputTextureDimensions(this._meshBlendTagTexture, this._depthTexture, this._baseColorTexture);\r\n        const inputSamples = tagTexture.samples || 1;\r\n        if (renderWidth !== undefined && renderHeight !== undefined && renderWidth > 0 && renderHeight > 0) {\r\n            if (\r\n                tagTexture.width !== renderWidth ||\r\n                tagTexture.height !== renderHeight ||\r\n                (baseColorTexture !== null && baseColorTexture !== undefined && (baseColorTexture.width !== renderWidth || baseColorTexture.height !== renderHeight))\r\n            ) {\r\n                throw new Error(\r\n                    \"MeshBlendingPostProcess: SceneColor, meshBlendTagTexture, depthTexture, and baseColorTexture when provided must have matching physical dimensions\"\r\n                );\r\n            }\r\n            if ((renderSamples || 1) !== inputSamples) {\r\n                throw new Error(\"MeshBlendingPostProcess: SceneColor, meshBlendTagTexture, depthTexture, and baseColorTexture when provided must have matching sample counts\");\r\n            }\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Color3 } from \"../Maths/math.color.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type PostProcessOptions } from \"./postProcess\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * Post process which applies a refraction texture\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#refraction\r\n */\r\nexport class RefractionPostProcess extends PostProcess {\r\n    private _refTexture: Texture;\r\n    private _ownRefractionTexture = true;\r\n\r\n    /** the base color of the refraction (used to taint the rendering) */\r\n    @serialize()\r\n    public color: Color3;\r\n\r\n    /** simulated refraction depth */\r\n    @serialize()\r\n    public depth: number;\r\n\r\n    /** the coefficient of the base color (0 to remove base color tainting) */\r\n    @serialize()\r\n    public colorLevel: number;\r\n\r\n    /** Gets the url used to load the refraction texture */\r\n    @serialize()\r\n    public refractionTextureUrl: string;\r\n\r\n    /**\r\n     * Gets or sets the refraction texture\r\n     * Please note that you are responsible for disposing the texture if you set it manually\r\n     */\r\n    public get refractionTexture(): Texture {\r\n        return this._refTexture;\r\n    }\r\n\r\n    public set refractionTexture(value: Texture) {\r\n        if (this._refTexture && this._ownRefractionTexture) {\r\n            this._refTexture.dispose();\r\n        }\r\n\r\n        this._refTexture = value;\r\n        this._ownRefractionTexture = false;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"RefractionPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"RefractionPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Initializes the RefractionPostProcess\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses#refraction\r\n     * @param name The name of the effect.\r\n     * @param refractionTextureUrl Url of the refraction texture to use\r\n     * @param color the base color of the refraction (used to taint the rendering)\r\n     * @param depth simulated refraction depth\r\n     * @param colorLevel the coefficient of the base color (0 to remove base color tainting)\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        refractionTextureUrl: string,\r\n        color: Color3,\r\n        depth: number,\r\n        colorLevel: number,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean\r\n    ) {\r\n        super(name, \"refraction\", [\"baseColor\", \"depth\", \"colorLevel\"], [\"refractionSampler\"], options, camera, samplingMode, engine, reusable);\r\n\r\n        this.color = color;\r\n        this.depth = depth;\r\n        this.colorLevel = colorLevel;\r\n        this.refractionTextureUrl = refractionTextureUrl;\r\n\r\n        this.onActivateObservable.add((cam: Camera) => {\r\n            this._refTexture = this._refTexture || new Texture(refractionTextureUrl, cam.getScene());\r\n        });\r\n\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            effect.setColor3(\"baseColor\", this.color);\r\n            effect.setFloat(\"depth\", this.depth);\r\n            effect.setFloat(\"colorLevel\", this.colorLevel);\r\n\r\n            effect.setTexture(\"refractionSampler\", this._refTexture);\r\n        });\r\n    }\r\n\r\n    // Methods\r\n    /**\r\n     * Disposes of the post process\r\n     * @param camera Camera to dispose post process on\r\n     */\r\n    public override dispose(camera: Camera): void {\r\n        if (this._refTexture && this._ownRefractionTexture) {\r\n            this._refTexture.dispose();\r\n            (<any>this._refTexture) = null;\r\n        }\r\n\r\n        super.dispose(camera);\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new RefractionPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.refractionTextureUrl,\r\n                    parsedPostProcess.color,\r\n                    parsedPostProcess.depth,\r\n                    parsedPostProcess.colorLevel,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for refractionPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterRefractionPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.RefractionPostProcess\", RefractionPostProcess);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"refractionPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D refractionSampler;uniform vec3 baseColor;uniform float depth;uniform float colorLevel;void main() {float ref=1.0-texture2D(refractionSampler,vUV).r;vec2 uv=vUV-vec2(0.5);vec2 offset=uv*depth*ref;vec3 sourceColor=texture2D(textureSampler,vUV-offset).rgb;gl_FragColor=vec4(sourceColor+sourceColor*ref*colorLevel,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const refractionPixelShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../../sceneComponent\";\r\n\r\nimport { Scene } from \"../../scene.pure\";\r\nimport { type PostProcessRenderPipelineManager } from \"./postProcessRenderPipelineManager\";\r\n\r\nlet _PostProcessRenderPipelineManagerClass: typeof PostProcessRenderPipelineManager;\r\n\r\n/**\r\n * Defines the Render Pipeline scene component responsible to rendering pipelines\r\n */\r\nexport class PostProcessRenderPipelineManagerSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_POSTPROCESSRENDERPIPELINEMANAGER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER, this, this._gatherRenderTargets);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        if (this.scene._postProcessRenderPipelineManager) {\r\n            this.scene._postProcessRenderPipelineManager._rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        if (this.scene._postProcessRenderPipelineManager) {\r\n            this.scene._postProcessRenderPipelineManager.dispose();\r\n        }\r\n    }\r\n\r\n    private _gatherRenderTargets(): void {\r\n        if (this.scene._postProcessRenderPipelineManager) {\r\n            this.scene._postProcessRenderPipelineManager.update();\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for postProcessRenderPipelineManagerSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param pipelineManagerClass The PostProcessRenderPipelineManager class to use for lazy instantiation\r\n */\r\nexport function RegisterPostProcessRenderPipelineManagerSceneComponent(pipelineManagerClass?: typeof PostProcessRenderPipelineManager): void {\r\n    if (pipelineManagerClass) {\r\n        _PostProcessRenderPipelineManagerClass = pipelineManagerClass;\r\n    }\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"postProcessRenderPipelineManager\", {\r\n        get: function (this: Scene) {\r\n            if (!this._postProcessRenderPipelineManager) {\r\n                // Register the G Buffer component to the scene.\r\n                let component = this._getComponent(SceneComponentConstants.NAME_POSTPROCESSRENDERPIPELINEMANAGER) as PostProcessRenderPipelineManagerSceneComponent;\r\n                if (!component) {\r\n                    component = new PostProcessRenderPipelineManagerSceneComponent(this);\r\n                    this._addComponent(component);\r\n                }\r\n                this._postProcessRenderPipelineManager = new _PostProcessRenderPipelineManagerClass!();\r\n            }\r\n\r\n            return this._postProcessRenderPipelineManager;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type PostProcessOptions } from \"./postProcess\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinSharpenPostProcess } from \"./thinSharpenPostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The SharpenPostProcess applies a sharpen kernel to every pixel\r\n * See http://en.wikipedia.org/wiki/Kernel_(image_processing)\r\n */\r\nexport class SharpenPostProcess extends PostProcess {\r\n    /**\r\n     * How much of the original color should be applied. Setting this to 0 will display edge detection. (default: 1)\r\n     */\r\n    @serialize()\r\n    public get colorAmount() {\r\n        return this._effectWrapper.colorAmount;\r\n    }\r\n\r\n    public set colorAmount(value: number) {\r\n        this._effectWrapper.colorAmount = value;\r\n    }\r\n\r\n    /**\r\n     * How much sharpness should be applied (default: 0.3)\r\n     */\r\n    @serialize()\r\n    public get edgeAmount() {\r\n        return this._effectWrapper.edgeAmount;\r\n    }\r\n\r\n    public set edgeAmount(value: number) {\r\n        this._effectWrapper.edgeAmount = value;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"SharpenPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"SharpenPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinSharpenPostProcess;\r\n\r\n    /**\r\n     * Creates a new instance ConvolutionPostProcess\r\n     * @param name The name of the effect.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinSharpenPostProcess.Uniforms,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinSharpenPostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinSharpenPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this.onApply = (_effect: Effect) => {\r\n            this._effectWrapper.textureWidth = this.width;\r\n            this._effectWrapper.textureHeight = this.height;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new SharpenPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.textureType\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for sharpenPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterSharpenPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.SharpenPostProcess\", SharpenPostProcess);\r\n}\r\n","import { type Camera, type IReadonlyObservable, type PostProcessRenderPipeline } from \"core/index\";\r\n\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { RegisterPostProcessRenderPipelineManagerSceneComponent } from \"./postProcessRenderPipelineManagerSceneComponent.pure\";\r\n\r\n/**\r\n * PostProcessRenderPipelineManager class\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/postProcessRenderPipeline\r\n */\r\nexport class PostProcessRenderPipelineManager {\r\n    private readonly _renderPipelines: { [Key: string]: PostProcessRenderPipeline } = {};\r\n    private readonly _onNewPipelineAddedObservable = new Observable<PostProcessRenderPipeline>();\r\n    private readonly _onPipelineRemovedObservable = new Observable<PostProcessRenderPipeline>();\r\n\r\n    /**\r\n     * Initializes a PostProcessRenderPipelineManager\r\n     * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/postProcessRenderPipeline\r\n     */\r\n    constructor() {\r\n        RegisterPostProcessRenderPipelineManagerSceneComponent(PostProcessRenderPipelineManager);\r\n    }\r\n\r\n    /**\r\n     * An event triggered when a pipeline is added to the manager\r\n     */\r\n    public get onNewPipelineAddedObservable(): IReadonlyObservable<PostProcessRenderPipeline> {\r\n        return this._onNewPipelineAddedObservable;\r\n    }\r\n\r\n    /**\r\n     * An event triggered when a pipeline is removed from the manager\r\n     */\r\n    public get onPipelineRemovedObservable(): IReadonlyObservable<PostProcessRenderPipeline> {\r\n        return this._onPipelineRemovedObservable;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of supported render pipelines\r\n     */\r\n    public get supportedPipelines(): PostProcessRenderPipeline[] {\r\n        const result = [];\r\n\r\n        for (const renderPipelineName in this._renderPipelines) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderPipelines, renderPipelineName)) {\r\n                const pipeline = this._renderPipelines[renderPipelineName];\r\n                if (pipeline.isSupported) {\r\n                    result.push(pipeline);\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Adds a pipeline to the manager\r\n     * @param renderPipeline The pipeline to add\r\n     */\r\n    public addPipeline(renderPipeline: PostProcessRenderPipeline): void {\r\n        this.removePipeline(renderPipeline._name);\r\n        this._renderPipelines[renderPipeline._name] = renderPipeline;\r\n        this._onNewPipelineAddedObservable.notifyObservers(renderPipeline);\r\n    }\r\n\r\n    /**\r\n     * Remove the pipeline from the manager\r\n     * @param renderPipelineName the name of the pipeline to remove\r\n     */\r\n    public removePipeline(renderPipelineName: string): void {\r\n        const pipeline = this._renderPipelines[renderPipelineName];\r\n        if (pipeline) {\r\n            this._onPipelineRemovedObservable.notifyObservers(pipeline);\r\n            delete this._renderPipelines[renderPipelineName];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Attaches a camera to the pipeline\r\n     * @param renderPipelineName The name of the pipeline to attach to\r\n     * @param cameras the camera to attach\r\n     * @param unique if the camera can be attached multiple times to the pipeline\r\n     */\r\n    public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera[] | Camera, unique: boolean = false): void {\r\n        const renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];\r\n\r\n        if (!renderPipeline) {\r\n            return;\r\n        }\r\n\r\n        renderPipeline._attachCameras(cameras as Camera[], unique);\r\n    }\r\n\r\n    /**\r\n     * Detaches a camera from the pipeline\r\n     * @param renderPipelineName The name of the pipeline to detach from\r\n     * @param cameras the camera to detach\r\n     */\r\n    public detachCamerasFromRenderPipeline(renderPipelineName: string, cameras: Camera[] | Camera): void {\r\n        const renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];\r\n\r\n        if (!renderPipeline) {\r\n            return;\r\n        }\r\n\r\n        renderPipeline._detachCameras(cameras as Camera[]);\r\n    }\r\n\r\n    /**\r\n     * Enables an effect by name on a pipeline\r\n     * @param renderPipelineName the name of the pipeline to enable the effect in\r\n     * @param renderEffectName the name of the effect to enable\r\n     * @param cameras the cameras that the effect should be enabled on\r\n     */\r\n    public enableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: Camera[] | Camera): void {\r\n        const renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];\r\n\r\n        if (!renderPipeline) {\r\n            return;\r\n        }\r\n\r\n        renderPipeline._enableEffect(renderEffectName, cameras as Camera[]);\r\n    }\r\n\r\n    /**\r\n     * Disables an effect by name on a pipeline\r\n     * @param renderPipelineName the name of the pipeline to disable the effect in\r\n     * @param renderEffectName the name of the effect to disable\r\n     * @param cameras the cameras that the effect should be disabled on\r\n     */\r\n    public disableEffectInPipeline(renderPipelineName: string, renderEffectName: string, cameras: Camera[] | Camera): void {\r\n        const renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];\r\n\r\n        if (!renderPipeline) {\r\n            return;\r\n        }\r\n\r\n        renderPipeline._disableEffect(renderEffectName, cameras as Camera[]);\r\n    }\r\n\r\n    /**\r\n     * Updates the state of all contained render pipelines and disposes of any non supported pipelines\r\n     */\r\n    public update(): void {\r\n        for (const renderPipelineName in this._renderPipelines) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderPipelines, renderPipelineName)) {\r\n                const pipeline = this._renderPipelines[renderPipelineName];\r\n                if (!pipeline.isSupported) {\r\n                    pipeline.dispose();\r\n                    delete this._renderPipelines[renderPipelineName];\r\n                } else {\r\n                    pipeline._update();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        for (const renderPipelineName in this._renderPipelines) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderPipelines, renderPipelineName)) {\r\n                const pipeline = this._renderPipelines[renderPipelineName];\r\n                pipeline._rebuild();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of the manager and pipelines\r\n     */\r\n    public dispose(): void {\r\n        for (const renderPipelineName in this._renderPipelines) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderPipelines, renderPipelineName)) {\r\n                const pipeline = this._renderPipelines[renderPipelineName];\r\n                pipeline.dispose();\r\n            }\r\n        }\r\n    }\r\n}\r\n","import { type Nullable } from \"../../types\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { UniqueIdGenerator } from \"core/Misc/uniqueIdGenerator\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type PostProcessRenderEffect } from \"./postProcessRenderEffect\";\r\nimport { type IInspectable } from \"../../Misc/iInspectable\";\r\nimport { RegisterPostProcessRenderPipelineManagerSceneComponent } from \"./postProcessRenderPipelineManagerSceneComponent.pure\";\r\nimport { PostProcessRenderPipelineManager } from \"./postProcessRenderPipelineManager\";\r\n\r\nimport { type PrePassRenderer } from \"../../Rendering/prePassRenderer\";\r\n\r\n/**\r\n * PostProcessRenderPipeline\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/postProcessRenderPipeline\r\n */\r\nexport class PostProcessRenderPipeline {\r\n    protected _renderEffects: { [key: string]: PostProcessRenderEffect };\r\n    protected _renderEffectsForIsolatedPass: PostProcessRenderEffect[];\r\n\r\n    /**\r\n     * List of inspectable custom properties (used by the Inspector)\r\n     * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n     */\r\n    public inspectableCustomProperties: IInspectable[];\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    protected _cameras: Camera[];\r\n\r\n    /** @internal */\r\n    @serialize()\r\n    public _name: string;\r\n\r\n    /**\r\n     * Gets pipeline name\r\n     */\r\n    public get name(): string {\r\n        return this._name;\r\n    }\r\n\r\n    /**\r\n     * Gets the unique id of the post process rendering pipeline\r\n     */\r\n    public readonly uniqueId = UniqueIdGenerator.UniqueId;\r\n\r\n    /** Gets the list of attached cameras */\r\n    public get cameras() {\r\n        return this._cameras;\r\n    }\r\n\r\n    /**\r\n     * Gets the active engine\r\n     */\r\n    public get engine(): AbstractEngine {\r\n        return this._engine;\r\n    }\r\n\r\n    /**\r\n     * Initializes a PostProcessRenderPipeline\r\n     * @param _engine engine to add the pipeline to\r\n     * @param name name of the pipeline\r\n     */\r\n    constructor(\r\n        private _engine: AbstractEngine,\r\n        name: string\r\n    ) {\r\n        RegisterPostProcessRenderPipelineManagerSceneComponent(PostProcessRenderPipelineManager);\r\n        this._name = name;\r\n\r\n        this._renderEffects = {};\r\n        this._renderEffectsForIsolatedPass = new Array<PostProcessRenderEffect>();\r\n\r\n        this._cameras = [];\r\n    }\r\n\r\n    /**\r\n     * Gets the class name\r\n     * @returns \"PostProcessRenderPipeline\"\r\n     */\r\n    public getClassName(): string {\r\n        return \"PostProcessRenderPipeline\";\r\n    }\r\n\r\n    /**\r\n     * If all the render effects in the pipeline are supported\r\n     */\r\n    public get isSupported(): boolean {\r\n        for (const renderEffectName in this._renderEffects) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {\r\n                if (!this._renderEffects[renderEffectName].isSupported) {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Adds an effect to the pipeline\r\n     * @param renderEffect the effect to add\r\n     */\r\n    public addEffect(renderEffect: PostProcessRenderEffect): void {\r\n        (<any>this._renderEffects)[renderEffect._name] = renderEffect;\r\n    }\r\n\r\n    // private\r\n\r\n    /** @internal */\r\n    public _rebuild() {}\r\n\r\n    /** @internal */\r\n    public _enableEffect(renderEffectName: string, cameras: Camera): void;\r\n    /** @internal */\r\n    public _enableEffect(renderEffectName: string, cameras: Camera[]): void;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _enableEffect(renderEffectName: string, cameras: any): void {\r\n        const renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];\r\n\r\n        if (!renderEffects) {\r\n            return;\r\n        }\r\n\r\n        renderEffects._enable(Tools.MakeArray(cameras || this._cameras));\r\n    }\r\n\r\n    /** @internal */\r\n    public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;\r\n    /** @internal */\r\n    public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void {\r\n        const renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];\r\n\r\n        if (!renderEffects) {\r\n            return;\r\n        }\r\n\r\n        renderEffects._disable(Tools.MakeArray(cameras || this._cameras));\r\n    }\r\n\r\n    /** @internal */\r\n    public _attachCameras(cameras: Camera, unique: boolean): void;\r\n    /** @internal */\r\n    public _attachCameras(cameras: Camera[], unique: boolean): void;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _attachCameras(cameras: any, unique: boolean): void {\r\n        const cams = Tools.MakeArray(cameras || this._cameras);\r\n\r\n        if (!cams) {\r\n            return;\r\n        }\r\n\r\n        const indicesToDelete = [];\r\n        let i: number;\r\n        for (i = 0; i < cams.length; i++) {\r\n            const camera = cams[i];\r\n            if (!camera) {\r\n                continue;\r\n            }\r\n\r\n            if (this._cameras.indexOf(camera) === -1) {\r\n                this._cameras.push(camera);\r\n            } else if (unique) {\r\n                indicesToDelete.push(i);\r\n            }\r\n        }\r\n\r\n        for (i = 0; i < indicesToDelete.length; i++) {\r\n            cams.splice(indicesToDelete[i], 1);\r\n        }\r\n\r\n        for (const renderEffectName in this._renderEffects) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {\r\n                this._renderEffects[renderEffectName]._attachCameras(cams);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _detachCameras(cameras: Camera): void;\r\n    /** @internal */\r\n    public _detachCameras(cameras: Nullable<Camera[]>): void;\r\n    /**\r\n     * @internal\r\n     */\r\n    public _detachCameras(cameras: any): void {\r\n        const cams = Tools.MakeArray(cameras || this._cameras);\r\n\r\n        if (!cams) {\r\n            return;\r\n        }\r\n\r\n        for (const renderEffectName in this._renderEffects) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {\r\n                this._renderEffects[renderEffectName]._detachCameras(cams);\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < cams.length; i++) {\r\n            this._cameras.splice(this._cameras.indexOf(cams[i]), 1);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _update(): void {\r\n        for (const renderEffectName in this._renderEffects) {\r\n            if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {\r\n                this._renderEffects[renderEffectName]._update();\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < this._cameras.length; i++) {\r\n            if (!this._cameras[i]) {\r\n                continue;\r\n            }\r\n            const cameraName = this._cameras[i].name;\r\n            if ((<any>this._renderEffectsForIsolatedPass)[cameraName]) {\r\n                (<any>this._renderEffectsForIsolatedPass)[cameraName]._update();\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _reset(): void {\r\n        this._renderEffects = {};\r\n        this._renderEffectsForIsolatedPass = new Array<PostProcessRenderEffect>();\r\n    }\r\n\r\n    protected _enableMSAAOnFirstPostProcess(sampleCount: number): boolean {\r\n        if (!this._engine._features.supportMSAA) {\r\n            return false;\r\n        }\r\n\r\n        // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)\r\n        const effectKeys = Object.keys(this._renderEffects);\r\n        if (effectKeys.length > 0) {\r\n            const postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();\r\n            if (postProcesses) {\r\n                postProcesses[0].samples = sampleCount;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Ensures that all post processes in the pipeline are the correct size according to the\r\n     * the viewport's required size\r\n     */\r\n    protected _adaptPostProcessesToViewPort(): void {\r\n        const effectKeys = Object.keys(this._renderEffects);\r\n        for (const effectKey of effectKeys) {\r\n            const postProcesses = this._renderEffects[effectKey].getPostProcesses();\r\n            if (postProcesses) {\r\n                for (const postProcess of postProcesses) {\r\n                    postProcess.adaptScaleToCurrentViewport = true;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the required values to the prepass renderer.\r\n     * @param prePassRenderer defines the prepass renderer to setup.\r\n     * @returns true if the pre pass is needed.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {\r\n        // Do Nothing by default\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Disposes of the pipeline\r\n     */\r\n    public dispose() {\r\n        // Must be implemented by children\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../../../types\";\nimport { serialize } from \"../../../Misc/decorators\";\nimport { SerializationHelper } from \"../../../Misc/decorators.serialization\";\nimport { Observable } from \"../../../Misc/observable.pure\";\nimport { type Observer } from \"../../../Misc/observable\";\nimport { type IAnimatable } from \"../../../Animations/animatable.interface\";\nimport { Logger } from \"../../../Misc/logger\";\nimport { type Camera } from \"../../../Cameras/camera.pure\";\nimport { type ImageProcessingConfiguration } from \"../../../Materials/imageProcessingConfiguration.pure\";\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\nimport { type AbstractEngine } from \"../../../Engines/abstractEngine.pure\";\nimport { Constants } from \"../../../Engines/constants\";\nimport { type IDisposable, type Scene } from \"../../../scene.pure\";\nimport { GlowLayer } from \"../../../Layers/glowLayer.pure\";\nimport { type PostProcess } from \"../../../PostProcesses/postProcess.pure\";\nimport { SharpenPostProcess } from \"../../../PostProcesses/sharpenPostProcess.pure\";\nimport { ImageProcessingPostProcess } from \"../../../PostProcesses/imageProcessingPostProcess\";\nimport { ChromaticAberrationPostProcess } from \"../../../PostProcesses/chromaticAberrationPostProcess.pure\";\nimport { GrainPostProcess } from \"../../../PostProcesses/grainPostProcess.pure\";\nimport { FxaaPostProcess } from \"../../../PostProcesses/fxaaPostProcess.pure\";\nimport { PostProcessRenderPipeline } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipeline\";\nimport { PostProcessRenderEffect } from \"../../../PostProcesses/RenderPipeline/postProcessRenderEffect\";\nimport { DepthOfFieldEffect, DepthOfFieldEffectBlurLevel } from \"../../../PostProcesses/depthOfFieldEffect\";\nimport { BloomEffect } from \"../../../PostProcesses/bloomEffect\";\nimport { EngineStore } from \"../../../Engines/engineStore\";\nimport { TimingTools } from \"core/Misc/timingTools\";\nimport { type Animation } from \"../../../Animations/animation.pure\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\nimport { RegisterDepthRendererSceneComponent } from \"../../../Rendering/depthRendererSceneComponent.pure\";\nimport { DepthRenderer } from \"../../../Rendering/depthRenderer.pure\";\n\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**\n * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.\n * See https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/defaultRenderingPipeline\n */\nexport class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {\n    private _scene: Scene;\n    private _camerasToBeAttached: Array<Camera> = [];\n    /**\n     * ID of the sharpen post process,\n     */\n    private readonly SharpenPostProcessId = \"SharpenPostProcessEffect\";\n    /**\n     * @ignore\n     * ID of the image processing post process;\n     */\n    readonly ImageProcessingPostProcessId = \"ImageProcessingPostProcessEffect\";\n    /**\n     * @ignore\n     * ID of the Fast Approximate Anti-Aliasing post process;\n     */\n    readonly FxaaPostProcessId = \"FxaaPostProcessEffect\";\n    /**\n     * ID of the chromatic aberration post process,\n     */\n    private readonly ChromaticAberrationPostProcessId = \"ChromaticAberrationPostProcessEffect\";\n    /**\n     * ID of the grain post process\n     */\n    private readonly GrainPostProcessId = \"GrainPostProcessEffect\";\n\n    // Post-processes\n    /**\n     * Sharpen post process which will apply a sharpen convolution to enhance edges\n     */\n    public sharpen: SharpenPostProcess;\n    private _sharpenEffect: PostProcessRenderEffect;\n    private bloom: BloomEffect;\n    /**\n     * Depth of field effect, applies a blur based on how far away objects are from the focus distance.\n     */\n    public depthOfField: DepthOfFieldEffect;\n    /**\n     * The Fast Approximate Anti-Aliasing post process which attempts to remove aliasing from an image.\n     */\n    public fxaa: FxaaPostProcess;\n    /**\n     * Image post processing pass used to perform operations such as tone mapping or color grading.\n     */\n    public imageProcessing: ImageProcessingPostProcess;\n    /**\n     * Chromatic aberration post process which will shift rgb colors in the image\n     */\n    public chromaticAberration: ChromaticAberrationPostProcess;\n    private _chromaticAberrationEffect: PostProcessRenderEffect;\n    /**\n     * Grain post process which add noise to the image\n     */\n    public grain: GrainPostProcess;\n    private _grainEffect: PostProcessRenderEffect;\n    /**\n     * Glow post process which adds a glow to emissive areas of the image\n     */\n    private _glowLayer: Nullable<GlowLayer> = null;\n\n    /**\n     * Animations which can be used to tweak settings over a period of time\n     */\n    public animations: Animation[] = [];\n\n    private _imageProcessingConfigurationObserver: Nullable<Observer<ImageProcessingConfiguration>> = null;\n    // Values\n    private _sharpenEnabled: boolean = false;\n    private _bloomEnabled: boolean = false;\n    private _depthOfFieldEnabled: boolean = false;\n    private _depthOfFieldBlurLevel = DepthOfFieldEffectBlurLevel.Low;\n    private _fxaaEnabled: boolean = false;\n    private _imageProcessingEnabled: boolean = true;\n    private _defaultPipelineTextureType: number;\n    private _bloomScale: number = 0.5;\n    private _chromaticAberrationEnabled: boolean = false;\n    private _grainEnabled: boolean = false;\n\n    private _buildAllowed = true;\n\n    /**\n     * Enable or disable automatic building of the pipeline when effects are enabled and disabled.\n     * If false, you will have to manually call prepare() to update the pipeline.\n     */\n    public get automaticBuild() {\n        return this._buildAllowed;\n    }\n    public set automaticBuild(value: boolean) {\n        this._buildAllowed = value;\n    }\n\n    /**\n     * This is triggered each time the pipeline has been built.\n     */\n    public onBuildObservable = new Observable<DefaultRenderingPipeline>();\n\n    /**\n     * Gets active scene\n     */\n    public get scene(): Scene {\n        return this._scene;\n    }\n\n    /**\n     * Enable or disable the sharpen process from the pipeline\n     */\n    public set sharpenEnabled(enabled: boolean) {\n        if (this._sharpenEnabled === enabled) {\n            return;\n        }\n        this._sharpenEnabled = enabled;\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get sharpenEnabled(): boolean {\n        return this._sharpenEnabled;\n    }\n\n    private _resizeObserver: Nullable<Observer<AbstractEngine>> = null;\n    private _hardwareScaleLevel = 1.0;\n    private _bloomKernel: number = 64;\n    /**\n     * Specifies the size of the bloom blur kernel, relative to the final output size\n     */\n    @serialize()\n    public get bloomKernel(): number {\n        return this._bloomKernel;\n    }\n    public set bloomKernel(value: number) {\n        this._bloomKernel = value;\n        this.bloom.kernel = value / this._hardwareScaleLevel;\n    }\n\n    /**\n     * Specifies the weight of the bloom in the final rendering\n     */\n    @serialize()\n    private _bloomWeight: number = 0.15;\n    /**\n     * Specifies the luma threshold for the area that will be blurred by the bloom\n     */\n    @serialize()\n    private _bloomThreshold: number = 0.9;\n\n    @serialize()\n    private _hdr: boolean;\n\n    /**\n     * The strength of the bloom.\n     */\n    public set bloomWeight(value: number) {\n        if (this._bloomWeight === value) {\n            return;\n        }\n        this.bloom.weight = value;\n\n        this._bloomWeight = value;\n    }\n\n    @serialize()\n    public get bloomWeight(): number {\n        return this._bloomWeight;\n    }\n\n    /**\n     * The luminance threshold to find bright areas of the image to bloom.\n     */\n    public set bloomThreshold(value: number) {\n        if (this._bloomThreshold === value) {\n            return;\n        }\n        this.bloom.threshold = value;\n        this._bloomThreshold = value;\n    }\n\n    @serialize()\n    public get bloomThreshold(): number {\n        return this._bloomThreshold;\n    }\n\n    /**\n     * The scale of the bloom, lower value will provide better performance.\n     */\n    public set bloomScale(value: number) {\n        if (this._bloomScale === value) {\n            return;\n        }\n        this._bloomScale = value;\n\n        // recreate bloom and dispose old as this setting is not dynamic\n        this._rebuildBloom();\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get bloomScale(): number {\n        return this._bloomScale;\n    }\n\n    /**\n     * Enable or disable the bloom from the pipeline\n     */\n    public set bloomEnabled(enabled: boolean) {\n        if (this._bloomEnabled === enabled) {\n            return;\n        }\n        this._bloomEnabled = enabled;\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get bloomEnabled(): boolean {\n        return this._bloomEnabled;\n    }\n\n    private _rebuildBloom() {\n        // recreate bloom and dispose old as this setting is not dynamic\n        const oldBloom = this.bloom;\n        this.bloom = new BloomEffect(this._scene, this.bloomScale, this._bloomWeight, this.bloomKernel / this._hardwareScaleLevel, this._defaultPipelineTextureType, false);\n        this.bloom.threshold = oldBloom.threshold;\n        for (let i = 0; i < this._cameras.length; i++) {\n            oldBloom.disposeEffects(this._cameras[i]);\n        }\n    }\n\n    /**\n     * If the depth of field is enabled.\n     */\n    @serialize()\n    public get depthOfFieldEnabled(): boolean {\n        return this._depthOfFieldEnabled;\n    }\n\n    public set depthOfFieldEnabled(enabled: boolean) {\n        if (this._depthOfFieldEnabled === enabled) {\n            return;\n        }\n        this._depthOfFieldEnabled = enabled;\n\n        this._buildPipeline();\n    }\n\n    /**\n     * Blur level of the depth of field effect. (Higher blur will effect performance)\n     */\n    @serialize()\n    public get depthOfFieldBlurLevel(): DepthOfFieldEffectBlurLevel {\n        return this._depthOfFieldBlurLevel;\n    }\n\n    public set depthOfFieldBlurLevel(value: DepthOfFieldEffectBlurLevel) {\n        if (this._depthOfFieldBlurLevel === value) {\n            return;\n        }\n        this._depthOfFieldBlurLevel = value;\n\n        // recreate dof and dispose old as this setting is not dynamic\n        const oldDof = this.depthOfField;\n\n        this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false);\n        this.depthOfField.focalLength = oldDof.focalLength;\n        this.depthOfField.focusDistance = oldDof.focusDistance;\n        this.depthOfField.fStop = oldDof.fStop;\n        this.depthOfField.lensSize = oldDof.lensSize;\n\n        for (let i = 0; i < this._cameras.length; i++) {\n            oldDof.disposeEffects(this._cameras[i]);\n        }\n\n        this._buildPipeline();\n    }\n\n    /**\n     * If the anti aliasing is enabled.\n     */\n    public set fxaaEnabled(enabled: boolean) {\n        if (this._fxaaEnabled === enabled) {\n            return;\n        }\n        this._fxaaEnabled = enabled;\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get fxaaEnabled(): boolean {\n        return this._fxaaEnabled;\n    }\n\n    private _samples = 1;\n    /**\n     * MSAA sample count, setting this to 4 will provide 4x anti aliasing. (default: 1)\n     */\n    public set samples(sampleCount: number) {\n        if (this._samples === sampleCount) {\n            return;\n        }\n        this._samples = sampleCount;\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get samples(): number {\n        return this._samples;\n    }\n\n    /**\n     * If image processing is enabled.\n     */\n    public set imageProcessingEnabled(enabled: boolean) {\n        if (this._imageProcessingEnabled === enabled) {\n            return;\n        }\n\n        this._scene.imageProcessingConfiguration.isEnabled = enabled;\n    }\n\n    @serialize()\n    public get imageProcessingEnabled(): boolean {\n        return this._imageProcessingEnabled;\n    }\n\n    /**\n     * If glow layer is enabled. (Adds a glow effect to emmissive materials)\n     */\n    public set glowLayerEnabled(enabled: boolean) {\n        if (enabled && !this._glowLayer) {\n            this._glowLayer = new GlowLayer(\"\", this._scene);\n        } else if (!enabled && this._glowLayer) {\n            this._glowLayer.dispose();\n            this._glowLayer = null;\n        }\n    }\n\n    @serialize()\n    public get glowLayerEnabled(): boolean {\n        return this._glowLayer != null;\n    }\n\n    /**\n     * Gets the glow layer (or null if not defined)\n     */\n    public get glowLayer() {\n        return this._glowLayer;\n    }\n\n    /**\n     * Enable or disable the chromaticAberration process from the pipeline\n     */\n    public set chromaticAberrationEnabled(enabled: boolean) {\n        if (this._chromaticAberrationEnabled === enabled) {\n            return;\n        }\n        this._chromaticAberrationEnabled = enabled;\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get chromaticAberrationEnabled(): boolean {\n        return this._chromaticAberrationEnabled;\n    }\n    /**\n     * Enable or disable the grain process from the pipeline\n     */\n    public set grainEnabled(enabled: boolean) {\n        if (this._grainEnabled === enabled) {\n            return;\n        }\n        this._grainEnabled = enabled;\n\n        this._buildPipeline();\n    }\n\n    @serialize()\n    public get grainEnabled(): boolean {\n        return this._grainEnabled;\n    }\n\n    /**\n     * Instantiates a DefaultRenderingPipeline.\n     * @param name The rendering pipeline name (default: \"\")\n     * @param hdr If high dynamic range textures should be used (default: true)\n     * @param scene The scene linked to this pipeline (default: the last created scene)\n     * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras)\n     * @param automaticBuild If false, you will have to manually call prepare() to update the pipeline (default: true)\n     */\n    constructor(name = \"\", hdr = true, scene: Scene = EngineStore.LastCreatedScene!, cameras?: Camera[], automaticBuild = true) {\n        RegisterDepthRendererSceneComponent(DepthRenderer);\n        super(scene.getEngine(), name);\n        this._cameras = cameras || scene.cameras;\n        this._cameras = this._cameras.slice();\n        this._camerasToBeAttached = this._cameras.slice();\n\n        this._buildAllowed = automaticBuild;\n\n        // Initialize\n        this._scene = scene;\n        const caps = this._scene.getEngine().getCaps();\n        this._hdr = hdr && (caps.textureHalfFloatRender || caps.textureFloatRender);\n\n        // Misc\n        if (this._hdr) {\n            if (caps.textureHalfFloatRender) {\n                this._defaultPipelineTextureType = Constants.TEXTURETYPE_HALF_FLOAT;\n            } else if (caps.textureFloatRender) {\n                this._defaultPipelineTextureType = Constants.TEXTURETYPE_FLOAT;\n            }\n        } else {\n            this._defaultPipelineTextureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\n        }\n\n        // Attach\n        scene.postProcessRenderPipelineManager.addPipeline(this);\n\n        const engine = this._scene.getEngine();\n\n        // Create post processes before hand so they can be modified before enabled.\n        // Block compilation flag is set to true to avoid compilation prior to use, these will be updated on first use in build pipeline.\n        this.sharpen = new SharpenPostProcess(\"sharpen\", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);\n        this._sharpenEffect = new PostProcessRenderEffect(\n            engine,\n            this.SharpenPostProcessId,\n            () => {\n                return this.sharpen;\n            },\n            true\n        );\n\n        this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, true);\n\n        // To keep the bloom sizes consistent across different display densities, factor in the hardware scaling level.\n        this._hardwareScaleLevel = engine.getHardwareScalingLevel();\n        this._resizeObserver = engine.onResizeObservable.add(() => {\n            this._hardwareScaleLevel = engine.getHardwareScalingLevel();\n            this.bloomKernel = this._bloomKernel;\n        });\n\n        this.bloom = new BloomEffect(this._scene, this._bloomScale, this._bloomWeight, this.bloomKernel / this._hardwareScaleLevel, this._defaultPipelineTextureType, true);\n\n        this.chromaticAberration = new ChromaticAberrationPostProcess(\n            \"ChromaticAberration\",\n            engine.getRenderWidth(),\n            engine.getRenderHeight(),\n            1.0,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            engine,\n            false,\n            this._defaultPipelineTextureType,\n            true\n        );\n        this._chromaticAberrationEffect = new PostProcessRenderEffect(\n            engine,\n            this.ChromaticAberrationPostProcessId,\n            () => {\n                return this.chromaticAberration;\n            },\n            true\n        );\n\n        this.grain = new GrainPostProcess(\"Grain\", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);\n        this._grainEffect = new PostProcessRenderEffect(\n            engine,\n            this.GrainPostProcessId,\n            () => {\n                return this.grain;\n            },\n            true\n        );\n\n        let avoidReentrancyAtConstructionTime = true;\n\n        this._imageProcessingConfigurationObserver = this._scene.imageProcessingConfiguration.onUpdateParameters.add(() => {\n            this.bloom._downscale._exposure = this._scene.imageProcessingConfiguration.exposure;\n\n            if (this.imageProcessingEnabled !== this._scene.imageProcessingConfiguration.isEnabled) {\n                this._imageProcessingEnabled = this._scene.imageProcessingConfiguration.isEnabled;\n                // Avoid re-entrant problems by deferring the call to _buildPipeline because the call to _buildPipeline\n                // at the end of the constructor could end up triggering imageProcessingConfiguration.onUpdateParameters!\n                // Note that the pipeline could have been disposed before the deferred call was executed, but in that case\n                // _buildAllowed will have been set to false, preventing _buildPipeline from being executed.\n                if (avoidReentrancyAtConstructionTime) {\n                    TimingTools.SetImmediate(() => {\n                        this._buildPipeline();\n                    });\n                } else {\n                    this._buildPipeline();\n                }\n            }\n        });\n\n        this._buildPipeline();\n\n        avoidReentrancyAtConstructionTime = false;\n    }\n\n    /**\n     * Get the class name\n     * @returns \"DefaultRenderingPipeline\"\n     */\n    public override getClassName(): string {\n        return \"DefaultRenderingPipeline\";\n    }\n\n    /**\n     * Force the compilation of the entire pipeline.\n     */\n    public prepare(): void {\n        const previousState = this._buildAllowed;\n        this._buildAllowed = true;\n        this._buildPipeline();\n        this._buildAllowed = previousState;\n    }\n\n    private _hasCleared = false;\n    private _prevPostProcess: Nullable<PostProcess> = null;\n    private _prevPrevPostProcess: Nullable<PostProcess> = null;\n\n    private _setAutoClearAndTextureSharing(postProcess: PostProcess, skipTextureSharing = false) {\n        if (this._hasCleared) {\n            postProcess.autoClear = false;\n        } else {\n            postProcess.autoClear = true;\n            this._scene.autoClear = false;\n            this._hasCleared = true;\n        }\n\n        if (!skipTextureSharing) {\n            if (this._prevPrevPostProcess) {\n                postProcess.shareOutputWith(this._prevPrevPostProcess);\n            } else {\n                postProcess.useOwnOutput();\n            }\n\n            if (this._prevPostProcess) {\n                this._prevPrevPostProcess = this._prevPostProcess;\n            }\n            this._prevPostProcess = postProcess;\n        }\n    }\n\n    private _depthOfFieldSceneObserver: Nullable<Observer<Scene>> = null;\n    private _activeCameraChangedObserver: Nullable<Observer<Scene>> = null;\n    private _activeCamerasChangedObserver: Nullable<Observer<Scene>> = null;\n\n    private _buildPipeline() {\n        if (!this._buildAllowed) {\n            return;\n        }\n        this._scene.autoClear = true;\n\n        const engine = this._scene.getEngine();\n\n        this._disposePostProcesses();\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n            // get back cameras to be used to reattach pipeline\n            this._cameras = this._camerasToBeAttached.slice();\n        }\n        this._reset();\n        this._prevPostProcess = null;\n        this._prevPrevPostProcess = null;\n        this._hasCleared = false;\n\n        if (this.depthOfFieldEnabled) {\n            // Multi camera suport\n            if (this._cameras.length > 1) {\n                for (const camera of this._cameras) {\n                    const depthRenderer = this._scene.enableDepthRenderer(camera);\n                    depthRenderer.useOnlyInActiveCamera = true;\n                }\n\n                this._depthOfFieldSceneObserver = this._scene.onAfterRenderTargetsRenderObservable.add((scene) => {\n                    if (this._cameras.indexOf(scene.activeCamera!) > -1) {\n                        this.depthOfField.depthTexture = scene.enableDepthRenderer(scene.activeCamera).getDepthMap();\n                    }\n                });\n            } else {\n                this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);\n                const depthRenderer = this._scene.enableDepthRenderer(this._cameras[0]);\n                this.depthOfField.depthTexture = depthRenderer.getDepthMap();\n            }\n\n            if (!this.depthOfField._isReady()) {\n                this.depthOfField._updateEffects();\n            }\n            this.addEffect(this.depthOfField);\n            this._setAutoClearAndTextureSharing(this.depthOfField._effects[0], true);\n        } else {\n            this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);\n        }\n\n        if (this.bloomEnabled) {\n            if (!this.bloom._isReady()) {\n                this.bloom._updateEffects();\n            }\n            this.addEffect(this.bloom);\n            this._setAutoClearAndTextureSharing(this.bloom._effects[0], true);\n        }\n\n        if (this._imageProcessingEnabled) {\n            this.imageProcessing = new ImageProcessingPostProcess(\n                \"imageProcessing\",\n                1.0,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                engine,\n                false,\n                this._defaultPipelineTextureType,\n                this.scene.imageProcessingConfiguration\n            );\n            if (this._hdr) {\n                this.addEffect(\n                    new PostProcessRenderEffect(\n                        engine,\n                        this.ImageProcessingPostProcessId,\n                        () => {\n                            return this.imageProcessing;\n                        },\n                        true\n                    )\n                );\n                this._setAutoClearAndTextureSharing(this.imageProcessing);\n            } else {\n                this._scene.imageProcessingConfiguration.applyByPostProcess = false;\n            }\n\n            if (!this._cameras || this._cameras.length === 0) {\n                this._scene.imageProcessingConfiguration.applyByPostProcess = false;\n            }\n\n            if (!this.imageProcessing.getEffect()) {\n                this.imageProcessing._updateParameters();\n            }\n        }\n\n        if (this.sharpenEnabled) {\n            if (!this.sharpen.isReady()) {\n                this.sharpen.updateEffect();\n            }\n            this.addEffect(this._sharpenEffect);\n            this._setAutoClearAndTextureSharing(this.sharpen);\n        }\n\n        if (this.grainEnabled) {\n            if (!this.grain.isReady()) {\n                this.grain.updateEffect();\n            }\n            this.addEffect(this._grainEffect);\n            this._setAutoClearAndTextureSharing(this.grain);\n        }\n\n        if (this.chromaticAberrationEnabled) {\n            if (!this.chromaticAberration.isReady()) {\n                this.chromaticAberration.updateEffect();\n            }\n            this.addEffect(this._chromaticAberrationEffect);\n            this._setAutoClearAndTextureSharing(this.chromaticAberration);\n        }\n\n        if (this.fxaaEnabled) {\n            this.fxaa = new FxaaPostProcess(\"fxaa\", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    engine,\n                    this.FxaaPostProcessId,\n                    () => {\n                        return this.fxaa;\n                    },\n                    true\n                )\n            );\n            this._setAutoClearAndTextureSharing(this.fxaa, true);\n        }\n\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);\n        }\n\n        // In multicamera mode, the scene needs to autoclear in between cameras.\n        if ((this._scene.activeCameras && this._scene.activeCameras.length > 1) || (this._scene.activeCamera && this._cameras.indexOf(this._scene.activeCamera) === -1)) {\n            this._scene.autoClear = true;\n        }\n        // The active camera on the scene can be changed anytime\n        if (!this._activeCameraChangedObserver) {\n            this._activeCameraChangedObserver = this._scene.onActiveCameraChanged.add(() => {\n                if (this._scene.activeCamera && this._cameras.indexOf(this._scene.activeCamera) === -1) {\n                    this._scene.autoClear = true;\n                }\n            });\n        }\n        if (!this._activeCamerasChangedObserver) {\n            this._activeCamerasChangedObserver = this._scene.onActiveCamerasChanged.add(() => {\n                if (this._scene.activeCameras && this._scene.activeCameras.length > 1) {\n                    this._scene.autoClear = true;\n                }\n            });\n        }\n\n        this._adaptPostProcessesToViewPort();\n\n        if (!this._enableMSAAOnFirstPostProcess(this.samples) && this.samples > 1) {\n            Logger.Warn(\"MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0\");\n        }\n\n        this.onBuildObservable.notifyObservers(this);\n    }\n\n    private _disposePostProcesses(disposeNonRecreated = false): void {\n        for (let i = 0; i < this._cameras.length; i++) {\n            const camera = this._cameras[i];\n\n            if (this.imageProcessing) {\n                this.imageProcessing.dispose(camera);\n            }\n\n            if (this.fxaa) {\n                this.fxaa.dispose(camera);\n            }\n\n            // These are created in the constructor and should not be disposed on every pipeline change\n            if (disposeNonRecreated) {\n                if (this.sharpen) {\n                    this.sharpen.dispose(camera);\n                }\n\n                if (this.depthOfField) {\n                    this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);\n                    this.depthOfField.disposeEffects(camera);\n                }\n\n                if (this.bloom) {\n                    this.bloom.disposeEffects(camera);\n                }\n\n                if (this.chromaticAberration) {\n                    this.chromaticAberration.dispose(camera);\n                }\n\n                if (this.grain) {\n                    this.grain.dispose(camera);\n                }\n                if (this._glowLayer) {\n                    this._glowLayer.dispose();\n                }\n            }\n        }\n\n        (<any>this.imageProcessing) = null;\n        (<any>this.fxaa) = null;\n\n        if (disposeNonRecreated) {\n            (<any>this.sharpen) = null;\n            (<any>this._sharpenEffect) = null;\n            (<any>this.depthOfField) = null;\n            (<any>this.bloom) = null;\n            (<any>this.chromaticAberration) = null;\n            (<any>this._chromaticAberrationEffect) = null;\n            (<any>this.grain) = null;\n            (<any>this._grainEffect) = null;\n            this._glowLayer = null;\n        }\n    }\n\n    /**\n     * Adds a camera to the pipeline\n     * @param camera the camera to be added\n     */\n    public addCamera(camera: Camera): void {\n        this._camerasToBeAttached.push(camera);\n        this._buildPipeline();\n    }\n\n    /**\n     * Removes a camera from the pipeline\n     * @param camera the camera to remove\n     */\n    public removeCamera(camera: Camera): void {\n        const index = this._camerasToBeAttached.indexOf(camera);\n        this._camerasToBeAttached.splice(index, 1);\n        this._buildPipeline();\n    }\n\n    /**\n     * Dispose of the pipeline and stop all post processes\n     */\n    public override dispose(): void {\n        this._buildAllowed = false;\n        this.onBuildObservable.clear();\n        this._disposePostProcesses(true);\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n        this._scene._postProcessRenderPipelineManager.removePipeline(this.name);\n        this._scene.autoClear = true;\n        if (this._resizeObserver) {\n            this._scene.getEngine().onResizeObservable.remove(this._resizeObserver);\n            this._resizeObserver = null;\n        }\n\n        this._scene.onActiveCameraChanged.remove(this._activeCameraChangedObserver);\n        this._scene.onActiveCamerasChanged.remove(this._activeCamerasChangedObserver);\n\n        this._scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigurationObserver);\n        super.dispose();\n    }\n\n    /**\n     * Serialize the rendering pipeline (Used when exporting)\n     * @returns the serialized object\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n        serializationObject.customType = \"DefaultRenderingPipeline\";\n\n        return serializationObject;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parse the serialized pipeline\n * @param source Source pipeline.\n * @param scene The scene to load the pipeline to.\n * @param rootUrl The URL of the serialized pipeline.\n * @returns An instantiated pipeline from the serialized object.\n */\nexport function DefaultRenderingPipelineParse(source: any, scene: Scene, rootUrl: string): DefaultRenderingPipeline {\n    return SerializationHelper.Parse(() => new DefaultRenderingPipeline(source._name, source._hdr, scene), source, scene, rootUrl);\n}\n\n/**\n * Register side effects for defaultRenderingPipeline.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterDefaultRenderingPipeline(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    DefaultRenderingPipeline.Parse = DefaultRenderingPipelineParse;\n\n    RegisterClass(\"BABYLON.DefaultRenderingPipeline\", DefaultRenderingPipeline);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { type Camera } from \"../../../Cameras/camera.pure\";\r\nimport { type Effect } from \"../../../Materials/effect.pure\";\r\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\r\nimport { type RenderTargetTexture } from \"../../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { PostProcess } from \"../../../PostProcesses/postProcess.pure\";\r\nimport { PostProcessRenderPipeline } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipeline\";\r\nimport { PostProcessRenderEffect } from \"../../../PostProcesses/RenderPipeline/postProcessRenderEffect\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { RawTexture } from \"../../../Materials/Textures/rawTexture\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { RegisterDepthRendererSceneComponent } from \"../../../Rendering/depthRendererSceneComponent.pure\";\r\nimport { DepthRenderer } from \"../../../Rendering/depthRenderer.pure\";\r\n\r\nimport { RandomRange } from \"../../../Maths/math.scalar.functions\";\r\n\r\n/**\r\n * BABYLON.JS Chromatic Aberration GLSL Shader\r\n * Author: Olivier Guyot\r\n * Separates very slightly R, G and B colors on the edges of the screen\r\n * Inspired by Francois Tarlier & Martins Upitis\r\n */\r\nexport class LensRenderingPipeline extends PostProcessRenderPipeline {\r\n    // Lens effects can be of the following:\r\n    // - chromatic aberration (slight shift of RGB colors)\r\n    // - blur on the edge of the lens\r\n    // - lens distortion\r\n    // - depth-of-field blur & highlights enhancing\r\n    // - depth-of-field 'bokeh' effect (shapes appearing in blurred areas)\r\n    // - grain effect (noise or custom texture)\r\n\r\n    // Two additional texture samplers are needed:\r\n    // - depth map (for depth-of-field)\r\n    // - grain texture\r\n\r\n    /**\r\n     * @ignore\r\n     * The chromatic aberration PostProcess id in the pipeline\r\n     */\r\n    public LensChromaticAberrationEffect: string = \"LensChromaticAberrationEffect\";\r\n    /**\r\n     * @ignore\r\n     * The highlights enhancing PostProcess id in the pipeline\r\n     */\r\n    public HighlightsEnhancingEffect: string = \"HighlightsEnhancingEffect\";\r\n    /**\r\n     * @ignore\r\n     * The depth-of-field PostProcess id in the pipeline\r\n     */\r\n    public LensDepthOfFieldEffect: string = \"LensDepthOfFieldEffect\";\r\n\r\n    private _scene: Scene;\r\n    private _depthTexture: RenderTargetTexture;\r\n    private _grainTexture: Texture;\r\n\r\n    private _chromaticAberrationPostProcess: PostProcess;\r\n    private _highlightsPostProcess: PostProcess;\r\n    private _depthOfFieldPostProcess: PostProcess;\r\n\r\n    private _edgeBlur: number;\r\n    private _grainAmount: number;\r\n    private _chromaticAberration: number;\r\n    private _distortion: number;\r\n    private _highlightsGain: number;\r\n    private _highlightsThreshold: number;\r\n    private _dofDistance: number;\r\n    private _dofAperture: number;\r\n    private _dofDarken: number;\r\n    private _dofPentagon: boolean;\r\n    private _blurNoise: boolean;\r\n\r\n    /**\r\n     * @constructor\r\n     *\r\n     * Effect parameters are as follow:\r\n     * {\r\n     *      chromatic_aberration: number;       // from 0 to x (1 for realism)\r\n     *      edge_blur: number;                  // from 0 to x (1 for realism)\r\n     *      distortion: number;                 // from 0 to x (1 for realism), note that this will effect the pointer position precision\r\n     *      grain_amount: number;               // from 0 to 1\r\n     *      grain_texture: BABYLON.Texture;     // texture to use for grain effect; if unset, use random B&W noise\r\n     *      dof_focus_distance: number;         // depth-of-field: focus distance; unset to disable (disabled by default)\r\n     *      dof_aperture: number;               // depth-of-field: focus blur bias (default: 1)\r\n     *      dof_darken: number;                 // depth-of-field: darken that which is out of focus (from 0 to 1, disabled by default)\r\n     *      dof_pentagon: boolean;              // depth-of-field: makes a pentagon-like \"bokeh\" effect\r\n     *      dof_gain: number;                   // depth-of-field: highlights gain; unset to disable (disabled by default)\r\n     *      dof_threshold: number;              // depth-of-field: highlights threshold (default: 1)\r\n     *      blur_noise: boolean;                // add a little bit of noise to the blur (default: true)\r\n     * }\r\n     * Note: if an effect parameter is unset, effect is disabled\r\n     *\r\n     * @param name The rendering pipeline name\r\n     * @param parameters - An object containing all parameters (see above)\r\n     * @param scene The scene linked to this pipeline\r\n     * @param ratio The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)\r\n     * @param cameras The array of cameras that the rendering pipeline will be attached to\r\n     */\r\n    constructor(name: string, parameters: any, scene: Scene, ratio: number = 1.0, cameras?: Camera[]) {\r\n        RegisterDepthRendererSceneComponent(DepthRenderer);\r\n        super(scene.getEngine(), name);\r\n\r\n        this._scene = scene;\r\n\r\n        // Fetch texture samplers\r\n        this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer \"on\"\r\n        if (parameters.grain_texture) {\r\n            this._grainTexture = parameters.grain_texture;\r\n        } else {\r\n            this._createGrainTexture();\r\n        }\r\n\r\n        // save parameters\r\n        this._edgeBlur = parameters.edge_blur ? parameters.edge_blur : 0;\r\n        this._grainAmount = parameters.grain_amount ? parameters.grain_amount : 0;\r\n        this._chromaticAberration = parameters.chromatic_aberration ? parameters.chromatic_aberration : 0;\r\n        this._distortion = parameters.distortion ? parameters.distortion : 0;\r\n        this._highlightsGain = parameters.dof_gain !== undefined ? parameters.dof_gain : -1;\r\n        this._highlightsThreshold = parameters.dof_threshold ? parameters.dof_threshold : 1;\r\n        this._dofDistance = parameters.dof_focus_distance !== undefined ? parameters.dof_focus_distance : -1;\r\n        this._dofAperture = parameters.dof_aperture ? parameters.dof_aperture : 1;\r\n        this._dofDarken = parameters.dof_darken ? parameters.dof_darken : 0;\r\n        this._dofPentagon = parameters.dof_pentagon !== undefined ? parameters.dof_pentagon : true;\r\n        this._blurNoise = parameters.blur_noise !== undefined ? parameters.blur_noise : true;\r\n\r\n        // Create effects\r\n        this._createChromaticAberrationPostProcess(ratio);\r\n        this._createHighlightsPostProcess(ratio);\r\n        this._createDepthOfFieldPostProcess(ratio / 4);\r\n\r\n        // Set up pipeline\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.LensChromaticAberrationEffect,\r\n                () => {\r\n                    return this._chromaticAberrationPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.HighlightsEnhancingEffect,\r\n                () => {\r\n                    return this._highlightsPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.LensDepthOfFieldEffect,\r\n                () => {\r\n                    return this._depthOfFieldPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n\r\n        if (this._highlightsGain === -1) {\r\n            this._disableEffect(this.HighlightsEnhancingEffect, null);\r\n        }\r\n\r\n        // Finish\r\n        scene.postProcessRenderPipelineManager.addPipeline(this);\r\n        if (cameras) {\r\n            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the class name\r\n     * @returns \"LensRenderingPipeline\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"LensRenderingPipeline\";\r\n    }\r\n\r\n    // Properties\r\n\r\n    /**\r\n     * Gets associated scene\r\n     */\r\n    public get scene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the edge blur\r\n     */\r\n    public get edgeBlur(): number {\r\n        return this._edgeBlur;\r\n    }\r\n\r\n    public set edgeBlur(value: number) {\r\n        this.setEdgeBlur(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the grain amount\r\n     */\r\n    public get grainAmount(): number {\r\n        return this._grainAmount;\r\n    }\r\n\r\n    public set grainAmount(value: number) {\r\n        this.setGrainAmount(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the chromatic aberration amount\r\n     */\r\n    public get chromaticAberration(): number {\r\n        return this._chromaticAberration;\r\n    }\r\n\r\n    public set chromaticAberration(value: number) {\r\n        this.setChromaticAberration(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the depth of field aperture\r\n     */\r\n    public get dofAperture(): number {\r\n        return this._dofAperture;\r\n    }\r\n\r\n    public set dofAperture(value: number) {\r\n        this.setAperture(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the edge distortion\r\n     */\r\n    public get edgeDistortion(): number {\r\n        return this._distortion;\r\n    }\r\n\r\n    public set edgeDistortion(value: number) {\r\n        this.setEdgeDistortion(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the depth of field distortion\r\n     */\r\n    public get dofDistortion(): number {\r\n        return this._dofDistance;\r\n    }\r\n\r\n    public set dofDistortion(value: number) {\r\n        this.setFocusDistance(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the darken out of focus amount\r\n     */\r\n    public get darkenOutOfFocus(): number {\r\n        return this._dofDarken;\r\n    }\r\n\r\n    public set darkenOutOfFocus(value: number) {\r\n        this.setDarkenOutOfFocus(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if blur noise is enabled\r\n     */\r\n    public get blurNoise(): boolean {\r\n        return this._blurNoise;\r\n    }\r\n\r\n    public set blurNoise(value: boolean) {\r\n        this._blurNoise = value;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if pentagon bokeh is enabled\r\n     */\r\n    public get pentagonBokeh(): boolean {\r\n        return this._pentagonBokehIsEnabled;\r\n    }\r\n\r\n    public set pentagonBokeh(value: boolean) {\r\n        if (value) {\r\n            this.enablePentagonBokeh();\r\n        } else {\r\n            this.disablePentagonBokeh();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the highlight grain amount\r\n     */\r\n    public get highlightsGain(): number {\r\n        return this._highlightsGain;\r\n    }\r\n\r\n    public set highlightsGain(value: number) {\r\n        this.setHighlightsGain(value);\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the highlight threshold\r\n     */\r\n    public get highlightsThreshold(): number {\r\n        return this._highlightsThreshold;\r\n    }\r\n\r\n    public set highlightsThreshold(value: number) {\r\n        this.setHighlightsThreshold(value);\r\n    }\r\n\r\n    // public methods (self explanatory)\r\n    /**\r\n     * Sets the amount of blur at the edges\r\n     * @param amount blur amount\r\n     */\r\n    public setEdgeBlur(amount: number) {\r\n        this._edgeBlur = amount;\r\n    }\r\n    /**\r\n     * Sets edge blur to 0\r\n     */\r\n    public disableEdgeBlur() {\r\n        this._edgeBlur = 0;\r\n    }\r\n    /**\r\n     * Sets the amount of grain\r\n     * @param amount Amount of grain\r\n     */\r\n    public setGrainAmount(amount: number) {\r\n        this._grainAmount = amount;\r\n    }\r\n    /**\r\n     * Set grain amount to 0\r\n     */\r\n    public disableGrain() {\r\n        this._grainAmount = 0;\r\n    }\r\n    /**\r\n     * Sets the chromatic aberration amount\r\n     * @param amount amount of chromatic aberration\r\n     */\r\n    public setChromaticAberration(amount: number) {\r\n        this._chromaticAberration = amount;\r\n    }\r\n    /**\r\n     * Sets chromatic aberration amount to 0\r\n     */\r\n    public disableChromaticAberration() {\r\n        this._chromaticAberration = 0;\r\n    }\r\n    /**\r\n     * Sets the EdgeDistortion amount\r\n     * @param amount amount of EdgeDistortion\r\n     */\r\n    public setEdgeDistortion(amount: number) {\r\n        this._distortion = amount;\r\n    }\r\n    /**\r\n     * Sets edge distortion to 0\r\n     */\r\n    public disableEdgeDistortion() {\r\n        this._distortion = 0;\r\n    }\r\n    /**\r\n     * Sets the FocusDistance amount\r\n     * @param amount amount of FocusDistance\r\n     */\r\n    public setFocusDistance(amount: number) {\r\n        this._dofDistance = amount;\r\n    }\r\n    /**\r\n     * Disables depth of field\r\n     */\r\n    public disableDepthOfField() {\r\n        this._dofDistance = -1;\r\n    }\r\n    /**\r\n     * Sets the Aperture amount\r\n     * @param amount amount of Aperture\r\n     */\r\n    public setAperture(amount: number) {\r\n        this._dofAperture = amount;\r\n    }\r\n    /**\r\n     * Sets the DarkenOutOfFocus amount\r\n     * @param amount amount of DarkenOutOfFocus\r\n     */\r\n    public setDarkenOutOfFocus(amount: number) {\r\n        this._dofDarken = amount;\r\n    }\r\n\r\n    private _pentagonBokehIsEnabled = false;\r\n    /**\r\n     * Creates a pentagon bokeh effect\r\n     */\r\n    public enablePentagonBokeh() {\r\n        this._highlightsPostProcess.updateEffect(\"#define PENTAGON\\n\");\r\n        this._pentagonBokehIsEnabled = true;\r\n    }\r\n    /**\r\n     * Disables the pentagon bokeh effect\r\n     */\r\n    public disablePentagonBokeh() {\r\n        this._pentagonBokehIsEnabled = false;\r\n        this._highlightsPostProcess.updateEffect();\r\n    }\r\n    /**\r\n     * Enables noise blur\r\n     */\r\n    public enableNoiseBlur() {\r\n        this._blurNoise = true;\r\n    }\r\n    /**\r\n     * Disables noise blur\r\n     */\r\n    public disableNoiseBlur() {\r\n        this._blurNoise = false;\r\n    }\r\n    /**\r\n     * Sets the HighlightsGain amount\r\n     * @param amount amount of HighlightsGain\r\n     */\r\n    public setHighlightsGain(amount: number) {\r\n        this._highlightsGain = amount;\r\n    }\r\n    /**\r\n     * Sets the HighlightsThreshold amount\r\n     * @param amount amount of HighlightsThreshold\r\n     */\r\n    public setHighlightsThreshold(amount: number) {\r\n        if (this._highlightsGain === -1) {\r\n            this._highlightsGain = 1.0;\r\n        }\r\n        this._highlightsThreshold = amount;\r\n    }\r\n    /**\r\n     * Disables highlights\r\n     */\r\n    public disableHighlights() {\r\n        this._highlightsGain = -1;\r\n    }\r\n\r\n    /**\r\n     * Removes the internal pipeline assets and detaches the pipeline from the scene cameras\r\n     * @param disableDepthRender If the scene's depth rendering should be disabled (default: false)\r\n     */\r\n    public override dispose(disableDepthRender: boolean = false): void {\r\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);\r\n\r\n        this._scene.postProcessRenderPipelineManager.removePipeline(this._name);\r\n\r\n        (<any>this._chromaticAberrationPostProcess) = null;\r\n        (<any>this._highlightsPostProcess) = null;\r\n        (<any>this._depthOfFieldPostProcess) = null;\r\n\r\n        this._grainTexture.dispose();\r\n\r\n        if (disableDepthRender) {\r\n            this._scene.disableDepthRenderer();\r\n        }\r\n    }\r\n\r\n    // colors shifting and distortion\r\n    private _createChromaticAberrationPostProcess(ratio: number): void {\r\n        this._chromaticAberrationPostProcess = new PostProcess(\r\n            \"LensChromaticAberration\",\r\n            \"chromaticAberration\",\r\n            [\"chromatic_aberration\", \"screen_width\", \"screen_height\", \"direction\", \"radialIntensity\", \"centerPosition\"], // uniforms\r\n            [], // samplers\r\n            ratio,\r\n            null,\r\n            Texture.TRILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false\r\n        );\r\n\r\n        this._chromaticAberrationPostProcess.onApply = (effect: Effect) => {\r\n            effect.setFloat(\"chromatic_aberration\", this._chromaticAberration);\r\n            effect.setFloat(\"screen_width\", this._scene.getEngine().getRenderWidth());\r\n            effect.setFloat(\"screen_height\", this._scene.getEngine().getRenderHeight());\r\n            effect.setFloat(\"radialIntensity\", 1);\r\n            effect.setFloat2(\"direction\", 17, 17);\r\n            effect.setFloat2(\"centerPosition\", 0.5, 0.5);\r\n        };\r\n    }\r\n\r\n    // highlights enhancing\r\n    private _createHighlightsPostProcess(ratio: number): void {\r\n        this._highlightsPostProcess = new PostProcess(\r\n            \"LensHighlights\",\r\n            \"lensHighlights\",\r\n            [\"gain\", \"threshold\", \"screen_width\", \"screen_height\"], // uniforms\r\n            [], // samplers\r\n            ratio,\r\n            null,\r\n            Texture.TRILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false,\r\n            this._dofPentagon ? \"#define PENTAGON\\n\" : \"\"\r\n        );\r\n\r\n        this._highlightsPostProcess.externalTextureSamplerBinding = true;\r\n        this._highlightsPostProcess.onApply = (effect: Effect) => {\r\n            effect.setFloat(\"gain\", this._highlightsGain);\r\n            effect.setFloat(\"threshold\", this._highlightsThreshold);\r\n            effect.setTextureFromPostProcess(\"textureSampler\", this._chromaticAberrationPostProcess);\r\n            effect.setFloat(\"screen_width\", this._scene.getEngine().getRenderWidth());\r\n            effect.setFloat(\"screen_height\", this._scene.getEngine().getRenderHeight());\r\n        };\r\n    }\r\n\r\n    // colors shifting and distortion\r\n    private _createDepthOfFieldPostProcess(ratio: number): void {\r\n        this._depthOfFieldPostProcess = new PostProcess(\r\n            \"LensDepthOfField\",\r\n            \"depthOfField\",\r\n            [\r\n                \"grain_amount\",\r\n                \"blur_noise\",\r\n                \"screen_width\",\r\n                \"screen_height\",\r\n                \"distortion\",\r\n                \"dof_enabled\",\r\n                \"screen_distance\",\r\n                \"aperture\",\r\n                \"darken\",\r\n                \"edge_blur\",\r\n                \"highlights\",\r\n                \"blur_lod\",\r\n                \"near\",\r\n                \"far\",\r\n            ],\r\n            [\"depthSampler\", \"grainSampler\", \"highlightsSampler\"],\r\n            ratio,\r\n            null,\r\n            Texture.TRILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false\r\n        );\r\n\r\n        this._depthOfFieldPostProcess.externalTextureSamplerBinding = true;\r\n        this._depthOfFieldPostProcess.onApply = (effect: Effect) => {\r\n            effect.setTexture(\"depthSampler\", this._depthTexture);\r\n            effect.setTexture(\"grainSampler\", this._grainTexture);\r\n            effect.setTextureFromPostProcess(\"textureSampler\", this._highlightsPostProcess);\r\n            effect.setTextureFromPostProcess(\"highlightsSampler\", this._depthOfFieldPostProcess);\r\n\r\n            // Explicit LOD for the blur samples of textureSampler: this pass runs at a lower resolution than its\r\n            // source (textureSampler = highlights pass), so reproduce the minification an implicit lookup would\r\n            // have selected instead of forcing mip 0. Derived from the actual render-target sizes.\r\n            const sourceWidth = this._highlightsPostProcess.width;\r\n            const outputWidth = this._depthOfFieldPostProcess.width;\r\n            effect.setFloat(\"blur_lod\", sourceWidth > 0 && outputWidth > 0 ? Math.max(0, Math.log2(sourceWidth / outputWidth)) : 0);\r\n\r\n            effect.setFloat(\"grain_amount\", this._grainAmount);\r\n            effect.setBool(\"blur_noise\", this._blurNoise);\r\n\r\n            effect.setFloat(\"screen_width\", this._scene.getEngine().getRenderWidth());\r\n            effect.setFloat(\"screen_height\", this._scene.getEngine().getRenderHeight());\r\n\r\n            effect.setFloat(\"distortion\", this._distortion);\r\n\r\n            effect.setBool(\"dof_enabled\", this._dofDistance !== -1);\r\n            effect.setFloat(\"screen_distance\", 1.0 / (0.1 - 1.0 / this._dofDistance));\r\n            effect.setFloat(\"aperture\", this._dofAperture);\r\n            effect.setFloat(\"darken\", this._dofDarken);\r\n\r\n            effect.setFloat(\"edge_blur\", this._edgeBlur);\r\n\r\n            effect.setBool(\"highlights\", this._highlightsGain !== -1);\r\n\r\n            if (this._scene.activeCamera) {\r\n                effect.setFloat(\"near\", this._scene.activeCamera.minZ);\r\n                effect.setFloat(\"far\", this._scene.activeCamera.maxZ);\r\n            }\r\n        };\r\n    }\r\n\r\n    // creates a black and white random noise texture, 512x512\r\n    private _createGrainTexture(): void {\r\n        const size = 512;\r\n\r\n        const data = new Uint8Array(size * size * 4);\r\n        for (let index = 0; index < data.length;) {\r\n            const value = Math.floor(RandomRange(0.42, 0.58) * 255);\r\n            data[index++] = value;\r\n            data[index++] = value;\r\n            data[index++] = value;\r\n            data[index++] = 255;\r\n        }\r\n\r\n        const texture = RawTexture.CreateRGBATexture(data, size, size, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n        texture.name = \"LensNoiseTexture\";\r\n        texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n        texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n        this._grainTexture = texture;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"chromaticAberrationPixelShader\";\nconst shader = `uniform sampler2D textureSampler; \nuniform float chromatic_aberration;uniform float radialIntensity;uniform vec2 direction;uniform vec2 centerPosition;uniform float screen_width;uniform float screen_height;varying vec2 vUV;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec2 centered_screen_pos=vec2(vUV.x-centerPosition.x,vUV.y-centerPosition.y);vec2 directionOfEffect=direction;if(directionOfEffect.x==0. && directionOfEffect.y==0.){directionOfEffect=normalize(centered_screen_pos);}\nfloat radius2=centered_screen_pos.x*centered_screen_pos.x\n+ centered_screen_pos.y*centered_screen_pos.y;float radius=sqrt(radius2);vec3 ref_indices=vec3(-0.3,0.0,0.3);float ref_shiftX=chromatic_aberration*pow(radius,radialIntensity)*directionOfEffect.x/screen_width;float ref_shiftY=chromatic_aberration*pow(radius,radialIntensity)*directionOfEffect.y/screen_height;vec2 ref_coords_r=vec2(vUV.x+ref_indices.r*ref_shiftX,vUV.y+ref_indices.r*ref_shiftY*0.5);vec2 ref_coords_g=vec2(vUV.x+ref_indices.g*ref_shiftX,vUV.y+ref_indices.g*ref_shiftY*0.5);vec2 ref_coords_b=vec2(vUV.x+ref_indices.b*ref_shiftX,vUV.y+ref_indices.b*ref_shiftY*0.5);vec4 r=texture2D(textureSampler,ref_coords_r);vec4 g=texture2D(textureSampler,ref_coords_g);vec4 b=texture2D(textureSampler,ref_coords_b);float a=clamp(r.a+g.a+b.a,0.,1.);gl_FragColor=vec4(r.r,g.g,b.b,a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const chromaticAberrationPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lensHighlightsPixelShader\";\nconst shader = `uniform sampler2D textureSampler; \nuniform float gain;uniform float threshold;uniform float screen_width;uniform float screen_height;varying vec2 vUV;vec4 highlightColor(vec4 color) {vec4 highlight=color;float luminance=dot(highlight.rgb,vec3(0.2125,0.7154,0.0721));float lum_threshold;if (threshold>1.0) { lum_threshold=0.94+0.01*threshold; }\nelse { lum_threshold=0.5+0.44*threshold; }\nluminance=clamp((luminance-lum_threshold)*(1.0/(1.0-lum_threshold)),0.0,1.0);highlight*=luminance*gain;highlight.a=1.0;return highlight;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec4 original=texture2D(textureSampler,vUV);if (gain==-1.0) {gl_FragColor=vec4(0.0,0.0,0.0,1.0);return;}\nfloat w=2.0/screen_width;float h=2.0/screen_height;float weight=1.0;vec4 blurred=vec4(0.0,0.0,0.0,0.0);\n#ifdef PENTAGON\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.84*w,0.43*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.48*w,-1.29*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.61*w,1.51*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.55*w,-0.74*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.71*w,-0.52*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.94*w,1.59*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.40*w,-1.87*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.62*w,1.16*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.09*w,0.25*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.46*w,-1.71*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.08*w,2.42*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.85*w,-1.89*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.89*w,0.16*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.29*w,1.88*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.40*w,-2.81*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.54*w,2.26*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.60*w,-0.61*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.31*w,-1.30*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.83*w,2.53*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.12*w,-2.48*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.60*w,1.11*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.82*w,0.99*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.50*w,-2.81*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.85*w,3.33*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.94*w,-1.92*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.27*w,-0.53*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.95*w,2.48*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.23*w,-3.04*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.17*w,2.05*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.97*w,-0.04*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.25*w,-2.00*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.31*w,3.08*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.94*w,-2.59*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.37*w,0.64*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-3.13*w,1.93*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.03*w,-3.65*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.60*w,3.17*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-3.14*w,-1.19*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.00*w,-1.19*h)));\n#else\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.85*w,0.36*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.52*w,-1.14*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.46*w,1.42*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.46*w,-0.83*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.79*w,-0.42*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.11*w,1.62*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.29*w,-2.07*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.69*w,1.39*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.28*w,0.12*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.65*w,-1.69*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.08*w,2.44*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.63*w,-1.90*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.55*w,0.31*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.13*w,1.52*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.56*w,-2.61*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.38*w,2.34*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.64*w,-0.81*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.53*w,-1.21*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.06*w,2.63*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.00*w,-2.69*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.59*w,1.32*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.82*w,0.78*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.57*w,-2.50*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.54*w,2.93*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.39*w,-1.81*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.01*w,-0.28*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.04*w,2.25*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.02*w,-3.05*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.09*w,2.25*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-3.07*w,-0.25*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.44*w,-1.90*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.52*w,3.05*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.68*w,-2.61*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.01*w,0.79*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.76*w,1.46*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.05*w,-2.94*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.21*w,2.88*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.84*w,-1.30*h)));blurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.98*w,-0.96*h)));\n#endif\nblurred/=39.0;gl_FragColor=blurred;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lensHighlightsPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"depthOfFieldPixelShader\";\nconst shader = `#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,lod) texture2DLodEXT(s,c,lod)\n#else\n#define TEXTUREFUNC(s,c,lod) texture2D(s,c)\n#endif\nuniform sampler2D textureSampler;uniform sampler2D highlightsSampler;uniform sampler2D depthSampler;uniform sampler2D grainSampler;uniform float grain_amount;uniform bool blur_noise;uniform float screen_width;uniform float screen_height;uniform float distortion;uniform bool dof_enabled;uniform float screen_distance; \nuniform float aperture;uniform float darken;uniform float edge_blur;uniform bool highlights;uniform float blur_lod;uniform float near;uniform float far;varying vec2 vUV;\n#define PI 3.14159265\n#define TWOPI 6.28318530\n#define inverse_focal_length 0.1 \nvec2 centered_screen_pos;vec2 distorted_coords;float radius2;float radius;vec2 rand(vec2 co)\n{float noise1=(fract(sin(dot(co,vec2(12.9898,78.233)))*43758.5453));float noise2=(fract(sin(dot(co,vec2(12.9898,78.233)*2.0))*43758.5453));return clamp(vec2(noise1,noise2),0.0,1.0);}\nvec2 getDistortedCoords(vec2 coords) {if (distortion==0.0) { return coords; }\nvec2 direction=1.0*normalize(centered_screen_pos);vec2 dist_coords=vec2(0.5,0.5);dist_coords.x=0.5+direction.x*radius2*1.0;dist_coords.y=0.5+direction.y*radius2*1.0;float dist_amount=clamp(distortion*0.23,0.0,1.0);dist_coords=mix(coords,dist_coords,dist_amount);return dist_coords;}\nfloat sampleScreen(inout vec4 color,in vec2 offset,in float weight) {vec2 coords=distorted_coords;float angle=rand(coords*100.0).x*TWOPI;coords+=vec2(offset.x*cos(angle)-offset.y*sin(angle),offset.x*sin(angle)+offset.y*cos(angle));color+=TEXTUREFUNC(textureSampler,coords,blur_lod)*weight;return weight;}\nfloat getBlurLevel(float size) {return min(3.0,ceil(size/1.0));}\nvec4 getBlurColor(float size) {vec4 col=TEXTUREFUNC(textureSampler,distorted_coords,blur_lod);float blur_level=getBlurLevel(size);float w=(size/screen_width);float h=(size/screen_height);float total_weight=1.0;vec2 sample_coords;total_weight+=sampleScreen(col,vec2(-0.50*w,0.24*h),0.93);total_weight+=sampleScreen(col,vec2(0.30*w,-0.75*h),0.90);total_weight+=sampleScreen(col,vec2(0.36*w,0.96*h),0.87);total_weight+=sampleScreen(col,vec2(-1.08*w,-0.55*h),0.85);total_weight+=sampleScreen(col,vec2(1.33*w,-0.37*h),0.83);total_weight+=sampleScreen(col,vec2(-0.82*w,1.31*h),0.80);total_weight+=sampleScreen(col,vec2(-0.31*w,-1.67*h),0.78);total_weight+=sampleScreen(col,vec2(1.47*w,1.11*h),0.76);total_weight+=sampleScreen(col,vec2(-1.97*w,0.19*h),0.74);total_weight+=sampleScreen(col,vec2(1.42*w,-1.57*h),0.72);if (blur_level>1.0) {total_weight+=sampleScreen(col,vec2(0.01*w,2.25*h),0.70);total_weight+=sampleScreen(col,vec2(-1.62*w,-1.74*h),0.67);total_weight+=sampleScreen(col,vec2(2.49*w,0.20*h),0.65);total_weight+=sampleScreen(col,vec2(-2.07*w,1.61*h),0.63);total_weight+=sampleScreen(col,vec2(0.46*w,-2.70*h),0.61);total_weight+=sampleScreen(col,vec2(1.55*w,2.40*h),0.59);total_weight+=sampleScreen(col,vec2(-2.88*w,-0.75*h),0.56);total_weight+=sampleScreen(col,vec2(2.73*w,-1.44*h),0.54);total_weight+=sampleScreen(col,vec2(-1.08*w,3.02*h),0.52);total_weight+=sampleScreen(col,vec2(-1.28*w,-3.05*h),0.49);}\nif (blur_level>2.0) {total_weight+=sampleScreen(col,vec2(3.11*w,1.43*h),0.46);total_weight+=sampleScreen(col,vec2(-3.36*w,1.08*h),0.44);total_weight+=sampleScreen(col,vec2(1.80*w,-3.16*h),0.41);total_weight+=sampleScreen(col,vec2(0.83*w,3.65*h),0.38);total_weight+=sampleScreen(col,vec2(-3.16*w,-2.19*h),0.34);total_weight+=sampleScreen(col,vec2(3.92*w,-0.53*h),0.31);total_weight+=sampleScreen(col,vec2(-2.59*w,3.12*h),0.26);total_weight+=sampleScreen(col,vec2(-0.20*w,-4.15*h),0.22);total_weight+=sampleScreen(col,vec2(3.02*w,3.00*h),0.15);}\ncol/=total_weight; \nif (darken>0.0) {col.rgb*=clamp(0.3,1.0,1.05-size*0.5*darken);}\nreturn col;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{centered_screen_pos=vec2(vUV.x-0.5,vUV.y-0.5);radius2=centered_screen_pos.x*centered_screen_pos.x+centered_screen_pos.y*centered_screen_pos.y;radius=sqrt(radius2);distorted_coords=getDistortedCoords(vUV); \nvec2 texels_coords=vec2(vUV.x*screen_width,vUV.y*screen_height); \nfloat depth=texture2D(depthSampler,distorted_coords).r; \nfloat distance=near+(far-near)*depth; \nvec4 sharpColor=texture2D(textureSampler,distorted_coords);float coc=abs(aperture*(screen_distance*(inverse_focal_length-1.0/distance)-1.0));if (dof_enabled==false || coc<0.07) { coc=0.0; }\nfloat edge_blur_amount=0.0;if (edge_blur>0.0) {edge_blur_amount=clamp((radius*2.0-1.0+0.15*edge_blur)*1.5,0.0,1.0)*1.3;}\nfloat blur_amount=max(edge_blur_amount,coc);if (blur_amount==0.0) {gl_FragColor=sharpColor;}\nelse {gl_FragColor=getBlurColor(blur_amount*1.7);if (highlights) {gl_FragColor.rgb+=clamp(coc,0.0,1.0)*TEXTUREFUNC(highlightsSampler,distorted_coords,0.0).rgb;}\nif (blur_noise) {vec2 noise=rand(distorted_coords)*0.01*blur_amount;vec2 blurred_coord=vec2(distorted_coords.x+noise.x,distorted_coords.y+noise.y);gl_FragColor=0.04*TEXTUREFUNC(textureSampler,blurred_coord,blur_lod)+0.96*gl_FragColor;}}\nif (grain_amount>0.0) {vec4 grain_color=texture2D(grainSampler,texels_coords*0.003);gl_FragColor.rgb+=(-0.5+grain_color.rgb)*0.30*grain_amount;}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const depthOfFieldPixelShader = { name, shader };\n","import { Constants } from \"../Engines/constants\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\n\r\n/**\r\n * Contains all parameters needed for the prepass to perform\r\n * screen space subsurface scattering\r\n */\r\nexport class SSAO2Configuration implements PrePassEffectConfiguration {\r\n    /**\r\n     * Is subsurface enabled\r\n     */\r\n    public enabled = false;\r\n\r\n    /**\r\n     * Name of the configuration\r\n     */\r\n    public name = \"ssao2\";\r\n\r\n    /**\r\n     * Textures that should be present in the MRT for this effect to work\r\n     */\r\n    public readonly texturesRequired: number[] = [Constants.PREPASS_NORMAL_TEXTURE_TYPE, Constants.PREPASS_DEPTH_TEXTURE_TYPE];\r\n}\r\n","import { type IMultiRenderTargetOptions, MultiRenderTarget } from \"./multiRenderTarget.pure\";\r\nimport { type Engine } from \"../../Engines/engine\";\r\nimport { type RenderTargetTexture } from \"./renderTargetTexture\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type PostProcess } from \"../../PostProcesses/postProcess\";\r\nimport { ImageProcessingPostProcess } from \"../../PostProcesses/imageProcessingPostProcess\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * A multi render target designed to render the prepass.\r\n * Prepass is a scene component used to render information in multiple textures\r\n * alongside with the scene materials rendering.\r\n * Note : This is an internal class, and you should NOT need to instanciate this.\r\n * Only the `PrePassRenderer` should instanciate this class.\r\n * It is more likely that you need a regular `MultiRenderTarget`\r\n * @internal\r\n */\r\nexport class PrePassRenderTarget extends MultiRenderTarget {\r\n    /**\r\n     * @internal\r\n     */\r\n    public _beforeCompositionPostProcesses: PostProcess[] = [];\r\n    /**\r\n     * Image processing post process for composition\r\n     */\r\n    public imageProcessingPostProcess: ImageProcessingPostProcess;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _engine: Engine;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _scene: Scene;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _outputPostProcess: Nullable<PostProcess>;\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _internalTextureDirty = false;\r\n\r\n    /**\r\n     * Is this render target enabled for prepass rendering\r\n     */\r\n    public enabled: boolean = false;\r\n\r\n    /**\r\n     * Render target associated with this prePassRenderTarget\r\n     * If this is `null`, it means this prePassRenderTarget is associated with the scene\r\n     */\r\n    public renderTargetTexture: Nullable<RenderTargetTexture> = null;\r\n\r\n    public constructor(name: string, renderTargetTexture: Nullable<RenderTargetTexture>, size: any, count: number, scene?: Scene, options?: IMultiRenderTargetOptions) {\r\n        super(name, size, count, scene, options);\r\n\r\n        this.renderTargetTexture = renderTargetTexture;\r\n    }\r\n\r\n    /**\r\n     * Creates a composition effect for this RT\r\n     * @internal\r\n     */\r\n    public _createCompositionEffect() {\r\n        this.imageProcessingPostProcess = new ImageProcessingPostProcess(\"prePassComposition\", 1, null, undefined, this._engine);\r\n        this.imageProcessingPostProcess._updateParameters();\r\n    }\r\n\r\n    /**\r\n     * Checks that the size of this RT is still adapted to the desired render size.\r\n     * @internal\r\n     */\r\n    public _checkSize() {\r\n        const requiredWidth = this._engine.getRenderWidth(true);\r\n        const requiredHeight = this._engine.getRenderHeight(true);\r\n\r\n        const width = this.getRenderWidth();\r\n        const height = this.getRenderHeight();\r\n\r\n        if (width !== requiredWidth || height !== requiredHeight) {\r\n            this.resize({ width: requiredWidth, height: requiredHeight });\r\n\r\n            this._internalTextureDirty = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Changes the number of render targets in this MRT\r\n     * Be careful as it will recreate all the data in the new texture.\r\n     * @param count new texture count\r\n     * @param options Specifies texture types and sampling modes for new textures\r\n     * @param textureNames Specifies the names of the textures (optional)\r\n     */\r\n    public override updateCount(count: number, options?: IMultiRenderTargetOptions, textureNames?: string[]) {\r\n        super.updateCount(count, options, textureNames);\r\n        this._internalTextureDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Resets the post processes chains applied to this RT.\r\n     * @internal\r\n     */\r\n    public _resetPostProcessChain() {\r\n        this._beforeCompositionPostProcesses.length = 0;\r\n    }\r\n\r\n    /**\r\n     * Diposes this render target\r\n     */\r\n    public override dispose() {\r\n        const scene = this._scene;\r\n\r\n        super.dispose();\r\n\r\n        if (scene && scene.prePassRenderer) {\r\n            const index = scene.prePassRenderer.renderTargets.indexOf(this);\r\n\r\n            if (index !== -1) {\r\n                scene.prePassRenderer.renderTargets.splice(index, 1);\r\n            }\r\n        }\r\n\r\n        if (this.imageProcessingPostProcess) {\r\n            this.imageProcessingPostProcess.dispose();\r\n        }\r\n\r\n        if (this.renderTargetTexture) {\r\n            this.renderTargetTexture._prePassRenderTarget = null;\r\n        }\r\n\r\n        if (this._outputPostProcess) {\r\n            this._outputPostProcess.autoClear = true;\r\n            this._outputPostProcess.restoreDefaultInputTexture();\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type _InstancesBatch } from \"../Meshes/mesh.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type PrePassRenderer } from \"./prePassRenderer.pure\";\r\n\r\n/**\r\n * Defines the Geometry Buffer scene component responsible to manage a G-Buffer useful\r\n * in several rendering techniques.\r\n */\r\nexport class PrePassRendererSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_PREPASSRENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_PREPASS, this, this._beforeCameraDraw);\r\n        this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_PREPASS, this, this._afterCameraDraw);\r\n        this.scene._beforeRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_PREPASS, this, this._beforeRenderTargetDraw);\r\n        this.scene._afterRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_PREPASS, this, this._afterRenderTargetDraw);\r\n\r\n        this.scene._beforeClearStage.registerStep(SceneComponentConstants.STEP_BEFORECLEAR_PREPASS, this, this._beforeClearStage);\r\n        this.scene._beforeRenderTargetClearStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETCLEAR_PREPASS, this, this._beforeRenderTargetClearStage);\r\n\r\n        this.scene._beforeRenderingMeshStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERINGMESH_PREPASS, this, this._beforeRenderingMeshStage);\r\n        this.scene._afterRenderingMeshStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGMESH_PREPASS, this, this._afterRenderingMeshStage);\r\n    }\r\n\r\n    private _beforeRenderTargetDraw(renderTarget: RenderTargetTexture, faceIndex?: number, layer?: number) {\r\n        if (this.scene.prePassRenderer && !renderTarget.noPrePassRenderer) {\r\n            this.scene.prePassRenderer._setRenderTarget(renderTarget._prePassRenderTarget);\r\n            this.scene.prePassRenderer._beforeDraw(undefined, faceIndex, layer);\r\n        }\r\n    }\r\n\r\n    private _afterRenderTargetDraw(renderTarget: RenderTargetTexture, faceIndex?: number, layer?: number) {\r\n        if (this.scene.prePassRenderer && !renderTarget.noPrePassRenderer) {\r\n            this.scene.prePassRenderer._afterDraw(faceIndex, layer);\r\n        }\r\n    }\r\n\r\n    private _beforeRenderTargetClearStage(renderTarget: RenderTargetTexture) {\r\n        if (this.scene.prePassRenderer && !renderTarget.noPrePassRenderer) {\r\n            if (!renderTarget._prePassRenderTarget) {\r\n                renderTarget._prePassRenderTarget = this.scene.prePassRenderer._createRenderTarget(renderTarget.name + \"_prePassRTT\", renderTarget);\r\n            }\r\n            this.scene.prePassRenderer._setRenderTarget(renderTarget._prePassRenderTarget);\r\n            this.scene.prePassRenderer._clear();\r\n        }\r\n    }\r\n\r\n    private _beforeCameraDraw(camera: Camera) {\r\n        if (this.scene.prePassRenderer) {\r\n            this.scene.prePassRenderer._setRenderTarget(null);\r\n            this.scene.prePassRenderer._beforeDraw(camera);\r\n        }\r\n    }\r\n\r\n    private _afterCameraDraw() {\r\n        if (this.scene.prePassRenderer) {\r\n            this.scene.prePassRenderer._afterDraw();\r\n        }\r\n    }\r\n\r\n    private _beforeClearStage() {\r\n        if (this.scene.prePassRenderer) {\r\n            this.scene.prePassRenderer._setRenderTarget(null);\r\n            this.scene.prePassRenderer._clear();\r\n        }\r\n    }\r\n\r\n    private _beforeRenderingMeshStage(mesh: AbstractMesh, subMesh: SubMesh, batch: _InstancesBatch, effect: Nullable<Effect>) {\r\n        if (!effect) {\r\n            return;\r\n        }\r\n\r\n        // Render to MRT\r\n        const scene = mesh.getScene();\r\n        if (scene.prePassRenderer) {\r\n            scene.prePassRenderer.bindAttachmentsForEffect(effect, subMesh);\r\n        }\r\n    }\r\n\r\n    private _afterRenderingMeshStage(mesh: AbstractMesh) {\r\n        const scene = mesh.getScene();\r\n\r\n        if (scene.prePassRenderer) {\r\n            scene.prePassRenderer.restoreAttachments();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        this.scene.disablePrePassRenderer();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for prePassRendererSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param prePassRendererClass The PrePassRenderer class to register the component for\r\n */\r\nexport function RegisterPrePassRendererSceneComponent(prePassRendererClass: typeof PrePassRenderer): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"prePassRenderer\", {\r\n        get: function (this: Scene) {\r\n            return this._prePassRenderer;\r\n        },\r\n        set: function (this: Scene, value: Nullable<PrePassRenderer>) {\r\n            if (value && value.isSupported) {\r\n                this._prePassRenderer = value;\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.enablePrePassRenderer = function (): Nullable<PrePassRenderer> {\r\n        if (this._prePassRenderer) {\r\n            return this._prePassRenderer;\r\n        }\r\n\r\n        this._prePassRenderer = new prePassRendererClass(this);\r\n\r\n        if (!this._prePassRenderer.isSupported) {\r\n            this._prePassRenderer = null;\r\n            Logger.Error(\r\n                \"PrePassRenderer needs WebGL 2 support.\\n\" + \"Maybe you tried to use the following features that need the PrePassRenderer :\\n\" + \" + Subsurface Scattering\"\r\n            );\r\n        }\r\n\r\n        return this._prePassRenderer;\r\n    };\r\n\r\n    Scene.prototype.disablePrePassRenderer = function (): void {\r\n        if (!this._prePassRenderer) {\r\n            return;\r\n        }\r\n\r\n        this._prePassRenderer.dispose();\r\n        this._prePassRenderer = null;\r\n    };\r\n\r\n    prePassRendererClass._SceneComponentInitialization = (scene: Scene) => {\r\n        // Register the G Buffer component to the scene.\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_PREPASSRENDERER) as PrePassRendererSceneComponent;\r\n        if (!component) {\r\n            component = new PrePassRendererSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { PrePassRenderTarget } from \"../Materials/Textures/prePassRenderTarget\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type PostProcess } from \"../PostProcesses/postProcess.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { Color4 } from \"../Maths/math.color.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { GeometryBufferRenderer } from \"../Rendering/geometryBufferRenderer.pure\";\r\nimport { RegisterPrePassRendererSceneComponent } from \"./prePassRendererSceneComponent.pure\";\r\nimport { RegisterGeometryBufferRendererSceneComponent } from \"./geometryBufferRendererSceneComponent.pure\";\r\n\r\n/**\r\n * Renders a pre pass of the scene\r\n * This means every mesh in the scene will be rendered to a render target texture\r\n * And then this texture will be composited to the rendering canvas with post processes\r\n * It is necessary for effects like subsurface scattering or deferred shading\r\n */\r\nexport class PrePassRenderer {\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"PrePassRendererSceneComponent\");\r\n    };\r\n\r\n    /**\r\n     * To save performance, we can excluded skinned meshes from the prepass\r\n     */\r\n    public excludedSkinnedMesh: AbstractMesh[] = [];\r\n\r\n    /**\r\n     * Force material to be excluded from the prepass\r\n     * Can be useful when `useGeometryBufferFallback` is set to `true`\r\n     * and you don't want a material to show in the effect.\r\n     */\r\n    public excludedMaterials: Material[] = [];\r\n\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n\r\n    /**\r\n     * Number of textures in the multi render target texture where the scene is directly rendered\r\n     */\r\n    public mrtCount: number = 0;\r\n\r\n    private _mrtTypes: number[] = [];\r\n    private _mrtFormats: number[] = [];\r\n    private _mrtLayout: number[] = [];\r\n    private _mrtNames: string[] = [];\r\n    private _textureIndices: number[] = [];\r\n\r\n    private _multiRenderAttachments: number[];\r\n    private _defaultAttachments: number[];\r\n    private _clearAttachments: number[];\r\n    private _clearDepthAttachments: number[];\r\n    private _generateNormalsInWorldSpace = false;\r\n\r\n    /**\r\n     * Indicates if the prepass renderer is generating normals in world space or camera space (default: camera space)\r\n     */\r\n    public get generateNormalsInWorldSpace() {\r\n        return this._generateNormalsInWorldSpace;\r\n    }\r\n\r\n    public set generateNormalsInWorldSpace(value: boolean) {\r\n        if (this._generateNormalsInWorldSpace === value) {\r\n            return;\r\n        }\r\n\r\n        this._generateNormalsInWorldSpace = value;\r\n        this._markAllMaterialsAsPrePassDirty();\r\n    }\r\n\r\n    /**\r\n     * Returns the index of a texture in the multi render target texture array.\r\n     * @param type Texture type\r\n     * @returns The index\r\n     */\r\n    public getIndex(type: number): number {\r\n        return this._textureIndices[type];\r\n    }\r\n\r\n    /**\r\n     * How many samples are used for MSAA of the scene render target\r\n     */\r\n    public get samples() {\r\n        return this.defaultRT.samples;\r\n    }\r\n\r\n    public set samples(n: number) {\r\n        this.defaultRT.samples = n;\r\n    }\r\n\r\n    private _useSpecificClearForDepthTexture = false;\r\n\r\n    /**\r\n     * If set to true (default: false), the depth texture will be cleared with the depth value corresponding to the far plane (1 in normal mode, 0 in reverse depth buffer mode)\r\n     * If set to false, the depth texture is always cleared with 0.\r\n     */\r\n    public get useSpecificClearForDepthTexture() {\r\n        return this._useSpecificClearForDepthTexture;\r\n    }\r\n\r\n    public set useSpecificClearForDepthTexture(value: boolean) {\r\n        if (this._useSpecificClearForDepthTexture === value) {\r\n            return;\r\n        }\r\n\r\n        this._useSpecificClearForDepthTexture = value;\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Describes the types and formats of the textures used by the pre-pass renderer\r\n     */\r\n    public static TextureFormats = [\r\n        {\r\n            purpose: Constants.PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_IrradianceLegacy\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_POSITION_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Position\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Velocity\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Reflectivity\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_COLOR_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Color\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_DEPTH_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_R,\r\n            name: \"prePass_Depth\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_NORMAL_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Normal\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_ALBEDO_SQRT_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Albedo\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_WORLD_NORMAL_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_WorldNormal\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_LOCAL_POSITION_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_LocalPosition\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_R,\r\n            name: \"prePass_ScreenDepth\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_VelocityLinear\",\r\n        },\r\n        {\r\n            purpose: Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE,\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            name: \"prePass_Irradiance\",\r\n        },\r\n    ];\r\n\r\n    private _isDirty: boolean = true;\r\n\r\n    /**\r\n     * The render target where the scene is directly rendered\r\n     */\r\n    public defaultRT: PrePassRenderTarget;\r\n\r\n    /**\r\n     * Configuration for prepass effects\r\n     */\r\n    private _effectConfigurations: PrePassEffectConfiguration[] = [];\r\n\r\n    /**\r\n     * @returns the prepass render target for the rendering pass.\r\n     * If we are currently rendering a render target, it returns the PrePassRenderTarget\r\n     * associated with that render target. Otherwise, it returns the scene default PrePassRenderTarget\r\n     */\r\n    public getRenderTarget(): PrePassRenderTarget {\r\n        return this._currentTarget;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * Managed by the scene component\r\n     * @param prePassRenderTarget\r\n     */\r\n    public _setRenderTarget(prePassRenderTarget: Nullable<PrePassRenderTarget>): void {\r\n        if (prePassRenderTarget) {\r\n            this._currentTarget = prePassRenderTarget;\r\n        } else {\r\n            this._currentTarget = this.defaultRT;\r\n            this._engine.currentRenderPassId = this._scene.activeCamera?.renderPassId ?? this._currentTarget.renderPassId;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns true if the currently rendered prePassRenderTarget is the one\r\n     * associated with the scene.\r\n     */\r\n    public get currentRTisSceneRT(): boolean {\r\n        return this._currentTarget === this.defaultRT;\r\n    }\r\n\r\n    private _geometryBuffer: Nullable<GeometryBufferRenderer>;\r\n\r\n    /**\r\n     * Prevents the PrePassRenderer from using the GeometryBufferRenderer as a fallback\r\n     */\r\n    public doNotUseGeometryRendererFallback = true;\r\n\r\n    private _refreshGeometryBufferRendererLink() {\r\n        if (!this.doNotUseGeometryRendererFallback) {\r\n            this._geometryBuffer = this._scene.enableGeometryBufferRenderer();\r\n\r\n            if (!this._geometryBuffer) {\r\n                // Not supported\r\n                this.doNotUseGeometryRendererFallback = true;\r\n                return;\r\n            }\r\n\r\n            this._geometryBuffer._linkPrePassRenderer(this);\r\n        } else {\r\n            if (this._geometryBuffer) {\r\n                this._geometryBuffer._unlinkPrePassRenderer();\r\n            }\r\n            this._geometryBuffer = null;\r\n            this._scene.disableGeometryBufferRenderer();\r\n        }\r\n    }\r\n\r\n    private _currentTarget: PrePassRenderTarget;\r\n\r\n    /**\r\n     * All the render targets generated by prepass\r\n     */\r\n    public renderTargets: PrePassRenderTarget[] = [];\r\n\r\n    private readonly _clearColor = new Color4(0, 0, 0, 0);\r\n    private readonly _clearDepthColor = new Color4(0, 0, 0, 1); //  // sets an invalid value by default - depth in the depth texture is view.z, so 0 is not possible because view.z can't be less than camera.minZ\r\n\r\n    private _enabled: boolean = false;\r\n\r\n    private readonly _geometryBufferRenderList: AbstractMesh[] = [];\r\n    private _needsCompositionForThisPass = false;\r\n    private readonly _postProcessesSourceForThisPass: PostProcess[] = [];\r\n    private readonly _postProcessChainForThisPass: PostProcess[] = [];\r\n    private readonly _postProcessesForUpdate: PostProcess[] = [];\r\n\r\n    /**\r\n     * Indicates if the prepass is enabled\r\n     */\r\n    public get enabled() {\r\n        return this._enabled;\r\n    }\r\n\r\n    /**\r\n     * Set to true to disable gamma transform in PrePass.\r\n     * Can be useful in case you already proceed to gamma transform on a material level\r\n     * and your post processes don't need to be in linear color space.\r\n     */\r\n    public disableGammaTransform = false;\r\n\r\n    /**\r\n     * Instantiates a prepass renderer\r\n     * @param scene The scene\r\n     */\r\n    constructor(scene: Scene) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n\r\n        let type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        if (this._engine._caps.textureFloat && this._engine._caps.textureFloatLinearFiltering) {\r\n            type = Constants.TEXTURETYPE_FLOAT;\r\n        } else if (this._engine._caps.textureHalfFloat && this._engine._caps.textureHalfFloatLinearFiltering) {\r\n            type = Constants.TEXTURETYPE_HALF_FLOAT;\r\n        }\r\n\r\n        for (let i = 0; i < PrePassRenderer.TextureFormats.length; ++i) {\r\n            const format = PrePassRenderer.TextureFormats[i].format;\r\n            if (PrePassRenderer.TextureFormats[i].type === Constants.TEXTURETYPE_FLOAT) {\r\n                PrePassRenderer.TextureFormats[i].type = type;\r\n                if (\r\n                    type === Constants.TEXTURETYPE_FLOAT &&\r\n                    (format === Constants.TEXTUREFORMAT_R || format === Constants.TEXTUREFORMAT_RG || format === Constants.TEXTUREFORMAT_RGBA) &&\r\n                    !this._engine._caps.supportFloatTexturesResolve\r\n                ) {\r\n                    // We don't know in advance if the texture will be used as a resolve target, so we revert to half_float if the extension to resolve full float textures is not supported\r\n                    PrePassRenderer.TextureFormats[i].type = Constants.TEXTURETYPE_HALF_FLOAT;\r\n                }\r\n            }\r\n        }\r\n\r\n        RegisterPrePassRendererSceneComponent(PrePassRenderer);\r\n        RegisterGeometryBufferRendererSceneComponent(GeometryBufferRenderer);\r\n        PrePassRenderer._SceneComponentInitialization(this._scene);\r\n        this.defaultRT = this._createRenderTarget(\"sceneprePassRT\", null);\r\n        this._currentTarget = this.defaultRT;\r\n    }\r\n\r\n    /**\r\n     * Creates a new PrePassRenderTarget\r\n     * This should be the only way to instantiate a `PrePassRenderTarget`\r\n     * @param name Name of the `PrePassRenderTarget`\r\n     * @param renderTargetTexture RenderTarget the `PrePassRenderTarget` will be attached to.\r\n     * Can be `null` if the created `PrePassRenderTarget` is attached to the scene (default framebuffer).\r\n     * @internal\r\n     */\r\n    public _createRenderTarget(name: string, renderTargetTexture: Nullable<RenderTargetTexture>): PrePassRenderTarget {\r\n        const rt = new PrePassRenderTarget(name, renderTargetTexture, { width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() }, 0, this._scene, {\r\n            generateMipMaps: false,\r\n            generateStencilBuffer: this._engine.isStencilEnable,\r\n            defaultType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            types: [],\r\n            drawOnlyOnFirstAttachmentByDefault: true,\r\n        });\r\n\r\n        this.renderTargets.push(rt);\r\n\r\n        if (this._enabled) {\r\n            // The pre-pass renderer is already enabled, so make sure we create the render target with the correct number of textures\r\n            this._update();\r\n        }\r\n\r\n        return rt;\r\n    }\r\n\r\n    /**\r\n     * Indicates if rendering a prepass is supported\r\n     */\r\n    public get isSupported() {\r\n        return this._scene.getEngine().getCaps().drawBuffersExtension;\r\n    }\r\n\r\n    /**\r\n     * Sets the proper output textures to draw in the engine.\r\n     * @param effect The effect that is drawn. It can be or not be compatible with drawing to several output textures.\r\n     * @param subMesh Submesh on which the effect is applied\r\n     */\r\n    public bindAttachmentsForEffect(effect: Effect, subMesh: SubMesh) {\r\n        const material = subMesh.getMaterial();\r\n        const isPrePassCapable = material && material.isPrePassCapable;\r\n        const excluded = material && this.excludedMaterials.indexOf(material) !== -1;\r\n\r\n        if (this.enabled && this._currentTarget.enabled) {\r\n            if (effect._multiTarget && isPrePassCapable && !excluded) {\r\n                this._engine.bindAttachments(this._multiRenderAttachments);\r\n            } else {\r\n                if (this._engine._currentRenderTarget) {\r\n                    this._engine.bindAttachments(this._defaultAttachments);\r\n                } else {\r\n                    this._engine.restoreSingleAttachment();\r\n                }\r\n\r\n                if (this._geometryBuffer && this.currentRTisSceneRT && !excluded) {\r\n                    this._geometryBuffer.renderList!.push(subMesh.getRenderingMesh());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private _reinitializeAttachments() {\r\n        const multiRenderLayout = [];\r\n        const clearLayout = [false];\r\n        const clearDepthLayout = [false];\r\n        const defaultLayout = [true];\r\n\r\n        for (let i = 0; i < this.mrtCount; i++) {\r\n            multiRenderLayout.push(true);\r\n\r\n            if (i > 0) {\r\n                if (this._useSpecificClearForDepthTexture && this._mrtLayout[i] === Constants.PREPASS_DEPTH_TEXTURE_TYPE) {\r\n                    clearLayout.push(false);\r\n                    clearDepthLayout.push(true);\r\n                } else {\r\n                    clearLayout.push(true);\r\n                    clearDepthLayout.push(false);\r\n                }\r\n                defaultLayout.push(false);\r\n            }\r\n        }\r\n\r\n        this._multiRenderAttachments = this._engine.buildTextureLayout(multiRenderLayout);\r\n        this._clearAttachments = this._engine.buildTextureLayout(clearLayout);\r\n        this._clearDepthAttachments = this._engine.buildTextureLayout(clearDepthLayout);\r\n        this._defaultAttachments = this._engine.buildTextureLayout(defaultLayout);\r\n    }\r\n\r\n    private _resetLayout() {\r\n        for (let i = 0; i < PrePassRenderer.TextureFormats.length; i++) {\r\n            this._textureIndices[PrePassRenderer.TextureFormats[i].purpose] = -1;\r\n        }\r\n\r\n        this._textureIndices[Constants.PREPASS_COLOR_TEXTURE_TYPE] = 0;\r\n        this._mrtLayout = [Constants.PREPASS_COLOR_TEXTURE_TYPE];\r\n        this._mrtTypes = [PrePassRenderer.TextureFormats[Constants.PREPASS_COLOR_TEXTURE_TYPE].type];\r\n        this._mrtFormats = [PrePassRenderer.TextureFormats[Constants.PREPASS_COLOR_TEXTURE_TYPE].format];\r\n        this._mrtNames = [PrePassRenderer.TextureFormats[Constants.PREPASS_COLOR_TEXTURE_TYPE].name];\r\n        this.mrtCount = 1;\r\n    }\r\n\r\n    private _updateGeometryBufferLayout() {\r\n        this._refreshGeometryBufferRendererLink();\r\n\r\n        if (this._geometryBuffer) {\r\n            this._geometryBuffer._resetLayout();\r\n\r\n            const texturesActivated = [];\r\n\r\n            for (let i = 0; i < this._mrtLayout.length; i++) {\r\n                texturesActivated.push(false);\r\n            }\r\n\r\n            this._geometryBuffer._linkInternalTexture(this.defaultRT.getInternalTexture()!);\r\n\r\n            const matches = [\r\n                {\r\n                    prePassConstant: Constants.PREPASS_DEPTH_TEXTURE_TYPE,\r\n                    geometryBufferConstant: GeometryBufferRenderer.DEPTH_TEXTURE_TYPE,\r\n                },\r\n                {\r\n                    prePassConstant: Constants.PREPASS_NORMAL_TEXTURE_TYPE,\r\n                    geometryBufferConstant: GeometryBufferRenderer.NORMAL_TEXTURE_TYPE,\r\n                },\r\n                {\r\n                    prePassConstant: Constants.PREPASS_POSITION_TEXTURE_TYPE,\r\n                    geometryBufferConstant: GeometryBufferRenderer.POSITION_TEXTURE_TYPE,\r\n                },\r\n                {\r\n                    prePassConstant: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,\r\n                    geometryBufferConstant: GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE,\r\n                },\r\n                {\r\n                    prePassConstant: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,\r\n                    geometryBufferConstant: GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE,\r\n                },\r\n            ];\r\n\r\n            // replace textures in the geometryBuffer RT\r\n            for (let i = 0; i < matches.length; i++) {\r\n                const index = this._mrtLayout.indexOf(matches[i].prePassConstant);\r\n                if (index !== -1) {\r\n                    this._geometryBuffer._forceTextureType(matches[i].geometryBufferConstant, index);\r\n                    texturesActivated[index] = true;\r\n                }\r\n            }\r\n\r\n            this._geometryBuffer._setAttachments(this._engine.buildTextureLayout(texturesActivated));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Restores attachments for single texture draw.\r\n     */\r\n    public restoreAttachments() {\r\n        if (this.enabled && this._currentTarget.enabled && this._defaultAttachments) {\r\n            if (this._engine._currentRenderTarget) {\r\n                this._engine.bindAttachments(this._defaultAttachments);\r\n            } else {\r\n                this._engine.restoreSingleAttachment();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    public _beforeDraw(camera?: Camera, faceIndex?: number, layer?: number) {\r\n        // const previousEnabled = this._enabled && this._currentTarget.enabled;\r\n\r\n        if (this._isDirty) {\r\n            this._update();\r\n        }\r\n\r\n        if (!this._enabled || !this._currentTarget.enabled) {\r\n            return;\r\n        }\r\n\r\n        if (this._geometryBuffer) {\r\n            this._geometryBufferRenderList.length = 0;\r\n            if (this._geometryBuffer.renderList !== this._geometryBufferRenderList) {\r\n                this._geometryBuffer.renderList = this._geometryBufferRenderList;\r\n            }\r\n        }\r\n\r\n        this._setupOutputForThisPass(this._currentTarget, camera);\r\n    }\r\n\r\n    private _prepareFrame(prePassRenderTarget: PrePassRenderTarget, faceIndex?: number, layer?: number) {\r\n        if (prePassRenderTarget.renderTargetTexture) {\r\n            prePassRenderTarget.renderTargetTexture._prepareFrame(this._scene, faceIndex, layer, prePassRenderTarget.renderTargetTexture.useCameraPostProcesses);\r\n        } else if (this._postProcessesSourceForThisPass.length) {\r\n            this._scene.postProcessManager._prepareFrame();\r\n        } else {\r\n            this._engine.restoreDefaultFramebuffer();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets an intermediary texture between prepass and postprocesses. This texture\r\n     * will be used as input for post processes\r\n     * @param rt The render target texture to use\r\n     * @returns true if there are postprocesses that will use this texture,\r\n     * false if there is no postprocesses - and the function has no effect\r\n     */\r\n    public setCustomOutput(rt: RenderTargetTexture) {\r\n        const firstPP = this._postProcessesSourceForThisPass[0];\r\n        if (!firstPP) {\r\n            return false;\r\n        }\r\n\r\n        firstPP.inputTexture = rt.renderTarget!;\r\n\r\n        return true;\r\n    }\r\n\r\n    private _renderPostProcesses(prePassRenderTarget: PrePassRenderTarget, faceIndex?: number) {\r\n        const firstPP = this._postProcessesSourceForThisPass[0];\r\n        const outputTexture = firstPP ? firstPP.inputTexture : prePassRenderTarget.renderTargetTexture ? prePassRenderTarget.renderTargetTexture.renderTarget : null;\r\n\r\n        // Build post process chain for this prepass post draw\r\n        let postProcessChain = this._currentTarget._beforeCompositionPostProcesses;\r\n\r\n        if (this._needsCompositionForThisPass) {\r\n            postProcessChain = this._postProcessChainForThisPass;\r\n            postProcessChain.length = 0;\r\n            for (let index = 0; index < this._currentTarget._beforeCompositionPostProcesses.length; index++) {\r\n                postProcessChain.push(this._currentTarget._beforeCompositionPostProcesses[index]);\r\n            }\r\n            postProcessChain.push(this._currentTarget.imageProcessingPostProcess);\r\n        }\r\n\r\n        // Activates and renders the chain\r\n        if (postProcessChain.length) {\r\n            this._scene.postProcessManager._prepareFrame(this._currentTarget.renderTarget?.texture, postProcessChain);\r\n            this._scene.postProcessManager.directRender(postProcessChain, outputTexture, false, faceIndex);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _afterDraw(faceIndex?: number, layer?: number) {\r\n        if (this._enabled && this._currentTarget.enabled) {\r\n            this._prepareFrame(this._currentTarget, faceIndex, layer);\r\n            this._renderPostProcesses(this._currentTarget, faceIndex);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clears the current prepass render target (in the sense of settings pixels to the scene clear color value)\r\n     * @internal\r\n     */\r\n    public _clear() {\r\n        if (this._isDirty) {\r\n            this._update();\r\n        }\r\n\r\n        if (this._enabled && this._currentTarget.enabled) {\r\n            this._bindFrameBuffer();\r\n\r\n            // Clearing other attachment with 0 on all other attachments\r\n            this._engine.bindAttachments(this._clearAttachments);\r\n            this._engine.clear(this._clearColor, true, false, false);\r\n            if (this._useSpecificClearForDepthTexture) {\r\n                this._engine.bindAttachments(this._clearDepthAttachments);\r\n                this._engine.clear(this._clearDepthColor, true, false, false);\r\n            }\r\n            // Regular clear color with the scene clear color of the 1st attachment\r\n            this._engine.bindAttachments(this._defaultAttachments);\r\n        }\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    private _bindFrameBuffer() {\r\n        if (this._enabled && this._currentTarget.enabled) {\r\n            this._currentTarget._checkSize();\r\n            const internalTexture = this._currentTarget.renderTarget;\r\n            if (internalTexture) {\r\n                this._engine.bindFramebuffer(internalTexture);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _setEnabled(enabled: boolean) {\r\n        this._enabled = enabled;\r\n    }\r\n\r\n    private _setRenderTargetEnabled(prePassRenderTarget: PrePassRenderTarget, enabled: boolean) {\r\n        prePassRenderTarget.enabled = enabled;\r\n        if (!enabled) {\r\n            this._unlinkInternalTexture(prePassRenderTarget);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds an effect configuration to the prepass render target.\r\n     * If an effect has already been added, it won't add it twice and will return the configuration\r\n     * already present.\r\n     * @param cfg the effect configuration\r\n     * @returns the effect configuration now used by the prepass\r\n     */\r\n    public addEffectConfiguration(cfg: PrePassEffectConfiguration): PrePassEffectConfiguration {\r\n        // Do not add twice\r\n        for (let i = 0; i < this._effectConfigurations.length; i++) {\r\n            if (this._effectConfigurations[i].name === cfg.name) {\r\n                return this._effectConfigurations[i];\r\n            }\r\n        }\r\n\r\n        this._effectConfigurations.push(cfg);\r\n        if (cfg.clearColor) {\r\n            this._clearColor.copyFrom(cfg.clearColor);\r\n        }\r\n        return cfg;\r\n    }\r\n\r\n    /**\r\n     * Retrieves an effect configuration by name\r\n     * @param name the name of the effect configuration\r\n     * @returns the effect configuration, or null if not present\r\n     */\r\n    public getEffectConfiguration(name: string): Nullable<PrePassEffectConfiguration> {\r\n        for (let i = 0; i < this._effectConfigurations.length; i++) {\r\n            if (this._effectConfigurations[i].name === name) {\r\n                return this._effectConfigurations[i];\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    private _enable() {\r\n        const previousMrtCount = this.mrtCount;\r\n\r\n        for (let i = 0; i < this._effectConfigurations.length; i++) {\r\n            if (this._effectConfigurations[i].enabled) {\r\n                this._enableTextures(this._effectConfigurations[i].texturesRequired);\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < this.renderTargets.length; i++) {\r\n            if (this.mrtCount !== previousMrtCount || this.renderTargets[i].count !== this.mrtCount) {\r\n                this.renderTargets[i].updateCount(this.mrtCount, { types: this._mrtTypes, formats: this._mrtFormats }, this._mrtNames.concat(\"prePass_DepthBuffer\"));\r\n            }\r\n\r\n            this.renderTargets[i]._resetPostProcessChain();\r\n\r\n            for (let j = 0; j < this._effectConfigurations.length; j++) {\r\n                if (this._effectConfigurations[j].enabled) {\r\n                    // TODO : subsurface scattering has 1 scene-wide effect configuration\r\n                    // solution : do not stock postProcess on effectConfiguration, but in the prepassRenderTarget (hashmap configuration => postProcess)\r\n                    // And call createPostProcess whenever the post process does not exist in the RT\r\n                    if (!this._effectConfigurations[j].postProcess && this._effectConfigurations[j].createPostProcess) {\r\n                        this._effectConfigurations[j].createPostProcess!();\r\n                    }\r\n\r\n                    if (this._effectConfigurations[j].postProcess) {\r\n                        this.renderTargets[i]._beforeCompositionPostProcesses.push(this._effectConfigurations[j].postProcess!);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._reinitializeAttachments();\r\n        this._setEnabled(true);\r\n        this._updateGeometryBufferLayout();\r\n    }\r\n\r\n    private _disable() {\r\n        this._setEnabled(false);\r\n\r\n        for (let i = 0; i < this.renderTargets.length; i++) {\r\n            this._setRenderTargetEnabled(this.renderTargets[i], false);\r\n        }\r\n\r\n        this._resetLayout();\r\n\r\n        for (let i = 0; i < this._effectConfigurations.length; i++) {\r\n            this._effectConfigurations[i].enabled = false;\r\n        }\r\n    }\r\n\r\n    private _getPostProcessesSource(prePassRenderTarget: PrePassRenderTarget, camera?: Camera): Nullable<PostProcess>[] {\r\n        if (camera) {\r\n            return camera._postProcesses;\r\n        } else if (prePassRenderTarget.renderTargetTexture) {\r\n            if (prePassRenderTarget.renderTargetTexture.useCameraPostProcesses) {\r\n                const camera = prePassRenderTarget.renderTargetTexture.activeCamera ? prePassRenderTarget.renderTargetTexture.activeCamera : this._scene.activeCamera;\r\n                return camera ? camera._postProcesses : [];\r\n            } else if (prePassRenderTarget.renderTargetTexture.postProcesses) {\r\n                return prePassRenderTarget.renderTargetTexture.postProcesses;\r\n            } else {\r\n                return [];\r\n            }\r\n        } else {\r\n            return this._scene.activeCamera ? this._scene.activeCamera._postProcesses : [];\r\n        }\r\n    }\r\n\r\n    private _setupOutputForThisPass(prePassRenderTarget: PrePassRenderTarget, camera?: Camera) {\r\n        // Order is : draw ===> prePassRenderTarget._postProcesses ==> ipp ==> camera._postProcesses\r\n        const secondaryCamera = camera && this._scene.activeCameras && !!this._scene.activeCameras.length && this._scene.activeCameras.indexOf(camera) !== 0;\r\n        const postProcessesSource = this._getPostProcessesSource(prePassRenderTarget, camera);\r\n        this._postProcessesSourceForThisPass.length = 0;\r\n        for (let index = 0; index < postProcessesSource.length; index++) {\r\n            const postProcess = postProcessesSource[index];\r\n            if (postProcess) {\r\n                this._postProcessesSourceForThisPass.push(postProcess);\r\n            }\r\n        }\r\n        this._scene.autoClear = true;\r\n\r\n        const cameraHasImageProcessing = this._hasImageProcessing(this._postProcessesSourceForThisPass);\r\n        this._needsCompositionForThisPass = !cameraHasImageProcessing && !this.disableGammaTransform && this._needsImageProcessing() && !secondaryCamera;\r\n\r\n        const firstCameraPP = this._getFirstPostProcess(this._postProcessesSourceForThisPass);\r\n        const firstPrePassPP = prePassRenderTarget._beforeCompositionPostProcesses && prePassRenderTarget._beforeCompositionPostProcesses[0];\r\n        let firstPP = null;\r\n\r\n        // Setting the scene-wide post process configuration\r\n        this._scene.imageProcessingConfiguration.applyByPostProcess = this._needsCompositionForThisPass || cameraHasImageProcessing;\r\n\r\n        // Create composition effect if needed\r\n        if (this._needsCompositionForThisPass && !prePassRenderTarget.imageProcessingPostProcess) {\r\n            prePassRenderTarget._createCompositionEffect();\r\n        }\r\n\r\n        // Setting the prePassRenderTarget as input texture of the first PP\r\n        if (firstPrePassPP) {\r\n            firstPP = firstPrePassPP;\r\n        } else if (this._needsCompositionForThisPass) {\r\n            firstPP = prePassRenderTarget.imageProcessingPostProcess;\r\n        } else if (firstCameraPP) {\r\n            firstPP = firstCameraPP;\r\n        }\r\n\r\n        this._bindFrameBuffer();\r\n        this._linkInternalTexture(prePassRenderTarget, firstPP);\r\n    }\r\n\r\n    private _linkInternalTexture(prePassRenderTarget: PrePassRenderTarget, postProcess: Nullable<PostProcess>) {\r\n        if (postProcess) {\r\n            postProcess.autoClear = false;\r\n            postProcess.inputTexture = prePassRenderTarget.renderTarget!;\r\n        }\r\n\r\n        if (prePassRenderTarget._outputPostProcess !== postProcess) {\r\n            if (prePassRenderTarget._outputPostProcess) {\r\n                this._unlinkInternalTexture(prePassRenderTarget);\r\n            }\r\n            prePassRenderTarget._outputPostProcess = postProcess;\r\n        }\r\n\r\n        if (prePassRenderTarget._internalTextureDirty) {\r\n            this._updateGeometryBufferLayout();\r\n            prePassRenderTarget._internalTextureDirty = false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _unlinkInternalTexture(prePassRenderTarget: PrePassRenderTarget) {\r\n        if (prePassRenderTarget._outputPostProcess) {\r\n            prePassRenderTarget._outputPostProcess.autoClear = true;\r\n            prePassRenderTarget._outputPostProcess.restoreDefaultInputTexture();\r\n            prePassRenderTarget._outputPostProcess = null;\r\n        }\r\n    }\r\n\r\n    private _needsImageProcessing(): boolean {\r\n        for (let i = 0; i < this._effectConfigurations.length; i++) {\r\n            if (this._effectConfigurations[i].enabled && this._effectConfigurations[i].needsImageProcessing) {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    private _hasImageProcessing(postProcesses: Nullable<PostProcess>[]): boolean {\r\n        let isIPPAlreadyPresent = false;\r\n        if (postProcesses) {\r\n            for (let i = 0; i < postProcesses.length; i++) {\r\n                if (postProcesses[i]?.getClassName() === \"ImageProcessingPostProcess\") {\r\n                    isIPPAlreadyPresent = true;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        return isIPPAlreadyPresent;\r\n    }\r\n\r\n    /**\r\n     * Internal, gets the first post proces.\r\n     * @param postProcesses\r\n     * @returns the first post process to be run on this camera.\r\n     */\r\n    private _getFirstPostProcess(postProcesses: Nullable<PostProcess>[]): Nullable<PostProcess> {\r\n        for (let ppIndex = 0; ppIndex < postProcesses.length; ppIndex++) {\r\n            if (postProcesses[ppIndex] !== null) {\r\n                return postProcesses[ppIndex];\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Marks the prepass renderer as dirty, triggering a check if the prepass is necessary for the next rendering.\r\n     */\r\n    public markAsDirty() {\r\n        this._isDirty = true;\r\n    }\r\n\r\n    /**\r\n     * Enables a texture on the MultiRenderTarget for prepass\r\n     * @param types\r\n     */\r\n    private _enableTextures(types: number[]) {\r\n        // For velocity : enable storage of previous matrices for instances\r\n        this._scene.needsPreviousWorldMatrices = false;\r\n\r\n        for (let i = 0; i < types.length; i++) {\r\n            const type = types[i];\r\n\r\n            if (this._textureIndices[type] === -1) {\r\n                this._textureIndices[type] = this._mrtLayout.length;\r\n                this._mrtLayout.push(type);\r\n\r\n                this._mrtTypes.push(PrePassRenderer.TextureFormats[type].type);\r\n                this._mrtFormats.push(PrePassRenderer.TextureFormats[type].format);\r\n                this._mrtNames.push(PrePassRenderer.TextureFormats[type].name);\r\n                this.mrtCount++;\r\n            }\r\n\r\n            if (type === Constants.PREPASS_VELOCITY_TEXTURE_TYPE || type === Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE) {\r\n                this._scene.needsPreviousWorldMatrices = true;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Makes sure that the prepass renderer is up to date if it has been dirtified.\r\n     */\r\n    public update() {\r\n        if (this._isDirty) {\r\n            this._update();\r\n        }\r\n    }\r\n\r\n    private _update() {\r\n        this._disable();\r\n        let enablePrePass = false;\r\n        this._scene.imageProcessingConfiguration.applyByPostProcess = false;\r\n\r\n        if (this._scene._depthPeelingRenderer && this._scene.useOrderIndependentTransparency) {\r\n            this._scene._depthPeelingRenderer.setPrePassRenderer(this);\r\n            enablePrePass = true;\r\n        }\r\n\r\n        for (let i = 0; i < this._scene.materials.length; i++) {\r\n            if (this._scene.materials[i].setPrePassRenderer(this)) {\r\n                enablePrePass = true;\r\n            }\r\n        }\r\n\r\n        if (enablePrePass) {\r\n            this._setRenderTargetEnabled(this.defaultRT, true);\r\n        }\r\n\r\n        let postProcesses;\r\n\r\n        for (let i = 0; i < this.renderTargets.length; i++) {\r\n            if (this.renderTargets[i].renderTargetTexture) {\r\n                postProcesses = this._getPostProcessesSource(this.renderTargets[i]);\r\n            } else {\r\n                // When there are multiple active cameras, we have to choose one. We assume it's the first one and not scene.activeCamera, because in a number of cases,\r\n                // _update() will be called from an async method, meaning the active camera will be the last one in the list of active cameras,\r\n                // which is generally not the right camera to use for the prepass setup.\r\n                const camera = this._scene.activeCameras && this._scene.activeCameras.length > 0 ? this._scene.activeCameras[0] : this._scene.activeCamera;\r\n                if (!camera) {\r\n                    continue;\r\n                }\r\n\r\n                postProcesses = camera._postProcesses;\r\n            }\r\n\r\n            if (!postProcesses) {\r\n                continue;\r\n            }\r\n\r\n            const postProcessesSource = postProcesses;\r\n            postProcesses = this._postProcessesForUpdate;\r\n            postProcesses.length = 0;\r\n            for (let j = 0; j < postProcessesSource.length; j++) {\r\n                const postProcess = postProcessesSource[j];\r\n                if (postProcess) {\r\n                    postProcesses.push(postProcess);\r\n                }\r\n            }\r\n\r\n            if (postProcesses) {\r\n                for (let j = 0; j < postProcesses.length; j++) {\r\n                    if (postProcesses[j].setPrePassRenderer(this)) {\r\n                        this._setRenderTargetEnabled(this.renderTargets[i], true);\r\n                        enablePrePass = true;\r\n                    }\r\n                }\r\n\r\n                if (this._hasImageProcessing(postProcesses)) {\r\n                    this._scene.imageProcessingConfiguration.applyByPostProcess = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        this._markAllMaterialsAsPrePassDirty();\r\n        this._isDirty = false;\r\n\r\n        if (enablePrePass) {\r\n            this._enable();\r\n        }\r\n    }\r\n\r\n    private _markAllMaterialsAsPrePassDirty() {\r\n        const materials = this._scene.materials;\r\n\r\n        for (let i = 0; i < materials.length; i++) {\r\n            materials[i].markAsDirty(Material.PrePassDirtyFlag);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the prepass renderer.\r\n     */\r\n    public dispose() {\r\n        for (let i = this.renderTargets.length - 1; i >= 0; i--) {\r\n            this.renderTargets[i].dispose();\r\n        }\r\n\r\n        for (let i = 0; i < this._effectConfigurations.length; i++) {\r\n            if (this._effectConfigurations[i].dispose) {\r\n                this._effectConfigurations[i].dispose!();\r\n            }\r\n        }\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { Logger } from \"../../../Misc/logger\";\nimport { serialize } from \"../../../Misc/decorators\";\nimport { SerializationHelper } from \"../../../Misc/decorators.serialization\";\nimport { type Camera } from \"../../../Cameras/camera.pure\";\nimport { type Effect } from \"../../../Materials/effect.pure\";\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\nimport { PostProcess } from \"../../../PostProcesses/postProcess.pure\";\nimport { PostProcessRenderPipeline } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipeline\";\nimport { PostProcessRenderEffect } from \"../../../PostProcesses/RenderPipeline/postProcessRenderEffect\";\nimport { PassPostProcess } from \"../../../PostProcesses/passPostProcess.pure\";\nimport { type Scene } from \"../../../scene.pure\";\nimport { EngineStore } from \"../../../Engines/engineStore\";\nimport { SSAO2Configuration } from \"../../../Rendering/ssao2Configuration\";\nimport { PrePassRenderer } from \"../../../Rendering/prePassRenderer.pure\";\nimport { GeometryBufferRenderer } from \"../../../Rendering/geometryBufferRenderer.pure\";\nimport { Constants } from \"../../../Engines/constants\";\nimport { type Nullable } from \"../../../types\";\nimport { ThinSSAO2RenderingPipeline } from \"./thinSSAO2RenderingPipeline\";\nimport { ThinSSAO2PostProcess } from \"../../thinSSAO2PostProcess\";\nimport { type ISize } from \"../../../Maths/math.size\";\nimport { ThinSSAO2BlurPostProcess } from \"../../thinSSAO2BlurPostProcess\";\nimport { ThinSSAO2CombinePostProcess } from \"../../thinSSAO2CombinePostProcess\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\nimport { RegisterPostProcessRenderPipelineManagerSceneComponent } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.pure\";\nimport { PostProcessRenderPipelineManager } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManager\";\nimport { RegisterPrePassRendererSceneComponent } from \"../../../Rendering/prePassRendererSceneComponent.pure\";\nimport { RegisterGeometryBufferRendererSceneComponent } from \"../../../Rendering/geometryBufferRendererSceneComponent.pure\";\n\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**\n * Render pipeline to produce ssao effect\n */\nexport class SSAO2RenderingPipeline extends PostProcessRenderPipeline {\n    // Members\n\n    /**\n     * @ignore\n     * The PassPostProcess id in the pipeline that contains the original scene color\n     */\n    public SSAOOriginalSceneColorEffect: string = \"SSAOOriginalSceneColorEffect\";\n    /**\n     * @ignore\n     * The SSAO PostProcess id in the pipeline\n     */\n    public SSAORenderEffect: string = \"SSAORenderEffect\";\n    /**\n     * @ignore\n     * The horizontal blur PostProcess id in the pipeline\n     */\n    public SSAOBlurHRenderEffect: string = \"SSAOBlurHRenderEffect\";\n    /**\n     * @ignore\n     * The vertical blur PostProcess id in the pipeline\n     */\n    public SSAOBlurVRenderEffect: string = \"SSAOBlurVRenderEffect\";\n    /**\n     * @ignore\n     * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect)\n     */\n    public SSAOCombineRenderEffect: string = \"SSAOCombineRenderEffect\";\n\n    private _thinSSAORenderingPipeline: ThinSSAO2RenderingPipeline;\n\n    /**\n     * The output strength of the SSAO post-process. Default value is 1.0.\n     */\n    @serialize()\n    public get totalStrength() {\n        return this._thinSSAORenderingPipeline.totalStrength;\n    }\n\n    public set totalStrength(value: number) {\n        this._thinSSAORenderingPipeline.totalStrength = value;\n    }\n\n    /**\n     * Maximum depth value to still render AO. A smooth falloff makes the dimming more natural, so there will be no abrupt shading change.\n     */\n    @serialize()\n    public get maxZ() {\n        return this._thinSSAORenderingPipeline.maxZ;\n    }\n\n    public set maxZ(value: number) {\n        this._thinSSAORenderingPipeline.maxZ = value;\n    }\n\n    /**\n     * In order to save performances, SSAO radius is clamped on close geometry. This ratio changes by how much.\n     */\n    @serialize()\n    public get minZAspect() {\n        return this._thinSSAORenderingPipeline.minZAspect;\n    }\n\n    public set minZAspect(value: number) {\n        this._thinSSAORenderingPipeline.minZAspect = value;\n    }\n\n    /**\n     * Used in SSAO calculations to compensate for accuracy issues with depth values. Default 0.02.\n     *\n     * Normally you do not need to change this value, but you can experiment with it if you get a lot of in false self-occlusion on flat surfaces when using fewer than 16 samples. Useful range is normally [0..0.1] but higher values is allowed.\n     */\n    @serialize(\"epsilon\")\n    public set epsilon(n: number) {\n        this._thinSSAORenderingPipeline.epsilon = n;\n    }\n    public get epsilon(): number {\n        return this._thinSSAORenderingPipeline.epsilon;\n    }\n\n    /**\n     * Number of samples used for the SSAO calculations. Default value is 8.\n     */\n    @serialize(\"samples\")\n    public set samples(n: number) {\n        this._thinSSAORenderingPipeline.samples = n;\n    }\n    public get samples(): number {\n        return this._thinSSAORenderingPipeline.samples;\n    }\n\n    @serialize(\"textureSamples\")\n    private _textureSamples: number = 1;\n    /**\n     * Number of samples to use for antialiasing.\n     */\n    public set textureSamples(n: number) {\n        this._textureSamples = n;\n\n        if (this._prePassRenderer) {\n            this._prePassRenderer.samples = n;\n        } else {\n            this._originalColorPostProcess.samples = n;\n        }\n    }\n    public get textureSamples(): number {\n        return this._textureSamples;\n    }\n\n    private _forcedGeometryBuffer: Nullable<GeometryBufferRenderer> = null;\n    /**\n     * Force rendering the geometry through geometry buffer.\n     */\n    @serialize()\n    private _forceGeometryBuffer: boolean = false;\n    private get _geometryBufferRenderer(): Nullable<GeometryBufferRenderer> {\n        if (!this._forceGeometryBuffer) {\n            return null;\n        }\n        return this._forcedGeometryBuffer ?? this._scene.geometryBufferRenderer;\n    }\n    private get _prePassRenderer(): Nullable<PrePassRenderer> {\n        if (this._forceGeometryBuffer) {\n            return null;\n        }\n        return this._scene.prePassRenderer;\n    }\n\n    /**\n     * Ratio object used for SSAO ratio and blur ratio\n     */\n    @serialize()\n    private _ratio: any;\n\n    /*\n     * The texture type used by the different post processes created by SSAO\n     */\n    @serialize()\n    private _textureType: number;\n\n    /**\n     * The radius around the analyzed pixel used by the SSAO post-process. Default value is 2.0\n     */\n    @serialize()\n    public get radius() {\n        return this._thinSSAORenderingPipeline.radius;\n    }\n\n    public set radius(value: number) {\n        this._thinSSAORenderingPipeline.radius = value;\n    }\n\n    /**\n     * The base color of the SSAO post-process\n     * The final result is \"base + ssao\" between [0, 1]\n     */\n    @serialize()\n    public get base() {\n        return this._thinSSAORenderingPipeline.base;\n    }\n\n    public set base(value: number) {\n        this._thinSSAORenderingPipeline.base = value;\n    }\n\n    /**\n     * Skips the denoising (blur) stage of the SSAO calculations.\n     *\n     * Useful to temporarily set while experimenting with the other SSAO2 settings.\n     */\n    @serialize(\"bypassBlur\")\n    public set bypassBlur(b: boolean) {\n        this._thinSSAORenderingPipeline.bypassBlur = b;\n    }\n    public get bypassBlur(): boolean {\n        return this._thinSSAORenderingPipeline.bypassBlur;\n    }\n\n    /**\n     * Enables the configurable bilateral denoising (blurring) filter. Default is true.\n     * Set to false to instead use a legacy bilateral filter that can't be configured.\n     *\n     * The denoising filter runs after the SSAO calculations and is a very important step. Both options results in a so called bilateral being used, but the \"expensive\" one can be\n     * configured in several ways to fit your scene.\n     */\n    @serialize(\"expensiveBlur\")\n    public set expensiveBlur(b: boolean) {\n        this._thinSSAORenderingPipeline.expensiveBlur = b;\n    }\n    public get expensiveBlur(): boolean {\n        return this._thinSSAORenderingPipeline.expensiveBlur;\n    }\n\n    /**\n     * The number of samples the bilateral filter uses in both dimensions when denoising the SSAO calculations. Default value is 16.\n     *\n     * A higher value should result in smoother shadows but will use more processing time in the shaders.\n     *\n     * A high value can cause the shadows to get to blurry or create visible artifacts (bands) near sharp details in the geometry. The artifacts can sometimes be mitigated by increasing the bilateralSoften setting.\n     */\n    @serialize()\n    public get bilateralSamples(): number {\n        return this._thinSSAORenderingPipeline.bilateralSamples;\n    }\n\n    public set bilateralSamples(n: number) {\n        this._thinSSAORenderingPipeline.bilateralSamples = n;\n    }\n\n    /**\n     * Controls the shape of the denoising kernel used by the bilateral filter. Default value is 0.\n     *\n     * By default the bilateral filter acts like a box-filter, treating all samples on the same depth with equal weights. This is effective to maximize the denoising effect given a limited set of samples. However, it also often results in visible ghosting around sharp shadow regions and can spread out lines over large areas so they are no longer visible.\n     *\n     * Increasing this setting will make the filter pay less attention to samples further away from the center sample, reducing many artifacts but at the same time increasing noise.\n     *\n     * Useful value range is [0..1].\n     */\n    @serialize()\n    public get bilateralSoften(): number {\n        return this._thinSSAORenderingPipeline.bilateralSoften;\n    }\n\n    public set bilateralSoften(n: number) {\n        this._thinSSAORenderingPipeline.bilateralSoften = n;\n    }\n\n    /**\n     * How forgiving the bilateral denoiser should be when rejecting samples. Default value is 0.\n     *\n     * A higher value results in the bilateral filter being more forgiving and thus doing a better job at denoising slanted and curved surfaces, but can lead to shadows spreading out around corners or between objects that are close to each other depth wise.\n     *\n     * Useful value range is normally [0..1], but higher values are allowed.\n     */\n    @serialize()\n    public get bilateralTolerance(): number {\n        return this._thinSSAORenderingPipeline.bilateralTolerance;\n    }\n\n    public set bilateralTolerance(n: number) {\n        this._thinSSAORenderingPipeline.bilateralTolerance = n;\n    }\n\n    /**\n     *  Support test.\n     */\n    public static get IsSupported(): boolean {\n        const engine = EngineStore.LastCreatedEngine;\n        if (!engine) {\n            return false;\n        }\n        return engine._features.supportSSAO2;\n    }\n\n    /**\n     * Indicates that the combine stage should use the current camera viewport to render the SSAO result on only a portion of the output texture (default: true).\n     */\n    public get useViewportInCombineStage() {\n        return this._thinSSAORenderingPipeline.useViewportInCombineStage;\n    }\n\n    public set useViewportInCombineStage(b: boolean) {\n        this._thinSSAORenderingPipeline.useViewportInCombineStage = b;\n    }\n\n    /**\n     * Checks if all the post processes in the pipeline are ready.\n     * @returns True if all the post processes in the pipeline are ready\n     */\n    public isReady() {\n        this._syncNormalsInWorldSpace();\n        return this._thinSSAORenderingPipeline.isReady();\n    }\n\n    private _scene: Scene;\n    private _originalColorPostProcess: PassPostProcess;\n    private _ssaoPostProcess: PostProcess;\n    private _blurHPostProcess: PostProcess;\n    private _blurVPostProcess: PostProcess;\n    private _ssaoCombinePostProcess: PostProcess;\n    private _currentCameraMode = -1;\n\n    /**\n     * Gets active scene\n     */\n    public get scene(): Scene {\n        return this._scene;\n    }\n\n    /**\n     * Creates the SSAO2 rendering pipeline.\n     * @param name The rendering pipeline name\n     * @param scene The scene linked to this pipeline\n     * @param ratio The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, blurRatio: 1.0 }\n     * @param cameras The array of cameras that the rendering pipeline will be attached to\n     * @param forceGeometryBuffer Set to true if you want to use the legacy geometry buffer renderer. You can also pass an existing instance of GeometryBufferRenderer if you want to use your own geometry buffer renderer.\n     * @param textureType The texture type used by the different post processes created by SSAO (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\n     */\n    constructor(\n        name: string,\n        scene: Scene,\n        ratio: any,\n        cameras?: Camera[],\n        forceGeometryBuffer: boolean | GeometryBufferRenderer = false,\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE\n    ) {\n        RegisterPrePassRendererSceneComponent(PrePassRenderer);\n        RegisterGeometryBufferRendererSceneComponent(GeometryBufferRenderer);\n        super(scene.getEngine(), name);\n\n        this._thinSSAORenderingPipeline = new ThinSSAO2RenderingPipeline(name, scene);\n\n        this._scene = scene;\n        this._ratio = ratio;\n        this._textureType = textureType;\n        if (forceGeometryBuffer instanceof GeometryBufferRenderer) {\n            this._forceGeometryBuffer = true;\n            this._forcedGeometryBuffer = forceGeometryBuffer;\n        } else {\n            this._forceGeometryBuffer = forceGeometryBuffer;\n        }\n\n        if (!this.isSupported) {\n            Logger.Error(\"The current engine does not support SSAO 2.\");\n            return;\n        }\n\n        const ssaoRatio = this._ratio.ssaoRatio || ratio;\n        const blurRatio = this._ratio.blurRatio || ratio;\n\n        // Set up assets\n        if (this._forceGeometryBuffer) {\n            if (!this._forcedGeometryBuffer) {\n                scene.enableGeometryBufferRenderer();\n            }\n        } else {\n            scene.enablePrePassRenderer();\n        }\n        this._syncNormalsInWorldSpace();\n\n        this._originalColorPostProcess = new PassPostProcess(\"SSAOOriginalSceneColor\", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), undefined, this._textureType);\n        this._originalColorPostProcess.onBeforeRenderObservable.add(() => {\n            this._syncNormalsInWorldSpace();\n            const camera = this._scene.activeCamera;\n            this._thinSSAORenderingPipeline._ssaoPostProcess.camera = camera;\n            if (camera && this._currentCameraMode !== camera.mode) {\n                this._currentCameraMode = camera.mode;\n                this._thinSSAORenderingPipeline._ssaoPostProcess.updateEffect();\n            }\n        });\n        this._originalColorPostProcess.samples = this.textureSamples;\n        this._createSSAOPostProcess(1.0, textureType);\n        this._createBlurPostProcess(ssaoRatio, blurRatio, this._textureType);\n        this._createSSAOCombinePostProcess(blurRatio, this._textureType);\n\n        // Set up pipeline\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                this.SSAOOriginalSceneColorEffect,\n                () => {\n                    return this._originalColorPostProcess;\n                },\n                true\n            )\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                this.SSAORenderEffect,\n                () => {\n                    return this._ssaoPostProcess;\n                },\n                true\n            )\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                this.SSAOBlurHRenderEffect,\n                () => {\n                    return this._blurHPostProcess;\n                },\n                true\n            )\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                this.SSAOBlurVRenderEffect,\n                () => {\n                    return this._blurVPostProcess;\n                },\n                true\n            )\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                this.SSAOCombineRenderEffect,\n                () => {\n                    return this._ssaoCombinePostProcess;\n                },\n                true\n            )\n        );\n\n        // Finish\n        scene.postProcessRenderPipelineManager.addPipeline(this);\n        if (cameras) {\n            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);\n        }\n    }\n\n    // Public Methods\n\n    /**\n     * Get the class name\n     * @returns \"SSAO2RenderingPipeline\"\n     */\n    public override getClassName(): string {\n        return \"SSAO2RenderingPipeline\";\n    }\n\n    /**\n     * Removes the internal pipeline assets and detaches the pipeline from the scene cameras\n     * @param disableGeometryBufferRenderer Set to true if you want to disable the Geometry Buffer renderer\n     */\n    public override dispose(disableGeometryBufferRenderer: boolean = false): void {\n        for (let i = 0; i < this._scene.cameras.length; i++) {\n            const camera = this._scene.cameras[i];\n\n            this._originalColorPostProcess.dispose(camera);\n            this._ssaoPostProcess.dispose(camera);\n            this._blurHPostProcess.dispose(camera);\n            this._blurVPostProcess.dispose(camera);\n            this._ssaoCombinePostProcess.dispose(camera);\n        }\n\n        if (disableGeometryBufferRenderer && !this._forcedGeometryBuffer) {\n            this._scene.disableGeometryBufferRenderer();\n        }\n\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);\n\n        this._scene.postProcessRenderPipelineManager.removePipeline(this._name);\n\n        this._thinSSAORenderingPipeline.dispose();\n\n        super.dispose();\n    }\n\n    // Private Methods\n\n    private _syncNormalsInWorldSpace(): void {\n        const renderer = this._forceGeometryBuffer ? this._geometryBufferRenderer : this._prePassRenderer;\n        const normalsInWorldSpace = !!renderer?.generateNormalsInWorldSpace;\n        this._thinSSAORenderingPipeline._ssaoPostProcess.normalsInWorldSpace = normalsInWorldSpace;\n    }\n\n    /** @internal */\n    public override _rebuild() {\n        super._rebuild();\n    }\n\n    private _createBlurPostProcess(ssaoRatio: number, blurRatio: number, textureType: number): void {\n        this._blurHPostProcess = this._createBlurFilter(\"BlurH\", ssaoRatio, textureType, true);\n        this._blurVPostProcess = this._createBlurFilter(\"BlurV\", blurRatio, textureType, false);\n    }\n\n    private _createBlurFilter(name: string, ratio: number, textureType: number, horizontal: boolean): PostProcess {\n        const blurFilter = new PostProcess(name, ThinSSAO2BlurPostProcess.FragmentUrl, {\n            size: ratio,\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n            engine: this._scene.getEngine(),\n            textureType: this._textureType,\n            effectWrapper: horizontal ? this._thinSSAORenderingPipeline._ssaoBlurXPostProcess : this._thinSSAORenderingPipeline._ssaoBlurYPostProcess,\n        });\n\n        blurFilter.onApply = (effect: Effect) => {\n            const ratio = this._ratio.blurRatio || this._ratio;\n            const ssaoCombineSize = horizontal ? this._originalColorPostProcess.width * ratio : this._originalColorPostProcess.height * ratio;\n            const originalColorSize = horizontal ? this._originalColorPostProcess.width : this._originalColorPostProcess.height;\n\n            this._thinSSAORenderingPipeline._ssaoBlurXPostProcess.textureSize = ssaoCombineSize > 0 ? ssaoCombineSize : originalColorSize;\n            this._thinSSAORenderingPipeline._ssaoBlurYPostProcess.textureSize = ssaoCombineSize > 0 ? ssaoCombineSize : originalColorSize;\n\n            if (this._geometryBufferRenderer) {\n                effect.setTexture(\"depthSampler\", this._geometryBufferRenderer.getGBuffer().textures[0]);\n            } else if (this._prePassRenderer) {\n                effect.setTexture(\"depthSampler\", this._prePassRenderer.getRenderTarget().textures[this._prePassRenderer.getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE)]);\n            }\n        };\n\n        blurFilter.samples = this.textureSamples;\n        blurFilter.autoClear = false;\n        return blurFilter;\n    }\n\n    private _getTextureSize() {\n        const engine = this._scene.getEngine();\n        const prePassRenderer = this._prePassRenderer;\n\n        let textureSize: ISize = { width: engine.getRenderWidth(), height: engine.getRenderHeight() };\n\n        if (prePassRenderer && this._scene.activeCamera?._getFirstPostProcess() === this._ssaoPostProcess) {\n            const renderTarget = prePassRenderer.getRenderTarget();\n\n            if (renderTarget && renderTarget.textures) {\n                textureSize = renderTarget.textures[prePassRenderer.getIndex(Constants.PREPASS_COLOR_TEXTURE_TYPE)].getSize();\n            }\n        } else if (this._ssaoPostProcess.inputTexture) {\n            textureSize.width = this._ssaoPostProcess.inputTexture.width;\n            textureSize.height = this._ssaoPostProcess.inputTexture.height;\n        }\n\n        return textureSize;\n    }\n\n    private _createSSAOPostProcess(ratio: number, textureType: number): void {\n        this._ssaoPostProcess = new PostProcess(\"ssao\", ThinSSAO2PostProcess.FragmentUrl, {\n            size: ratio,\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n            engine: this._scene.getEngine(),\n            textureType,\n            effectWrapper: this._thinSSAORenderingPipeline._ssaoPostProcess,\n        });\n        this._ssaoPostProcess.autoClear = false;\n\n        this._ssaoPostProcess.onApply = (effect: Effect) => {\n            if (this._geometryBufferRenderer) {\n                effect.setTexture(\"depthSampler\", this._geometryBufferRenderer.getGBuffer().textures[0]);\n                effect.setTexture(\"normalSampler\", this._geometryBufferRenderer.getGBuffer().textures[1]);\n            } else if (this._prePassRenderer) {\n                effect.setTexture(\"depthSampler\", this._prePassRenderer.getRenderTarget().textures[this._prePassRenderer.getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE)]);\n                effect.setTexture(\"normalSampler\", this._prePassRenderer.getRenderTarget().textures[this._prePassRenderer.getIndex(Constants.PREPASS_NORMAL_TEXTURE_TYPE)]);\n            }\n\n            const textureSize = this._getTextureSize();\n\n            this._thinSSAORenderingPipeline._ssaoPostProcess.textureWidth = textureSize.width;\n            this._thinSSAORenderingPipeline._ssaoPostProcess.textureHeight = textureSize.height;\n        };\n        this._ssaoPostProcess.samples = this.textureSamples;\n\n        if (!this._forceGeometryBuffer) {\n            this._ssaoPostProcess._prePassEffectConfiguration = new SSAO2Configuration();\n        }\n    }\n\n    private _createSSAOCombinePostProcess(ratio: number, textureType: number): void {\n        this._ssaoCombinePostProcess = new PostProcess(\"ssaoCombine\", ThinSSAO2CombinePostProcess.FragmentUrl, {\n            size: ratio,\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n            engine: this._scene.getEngine(),\n            textureType,\n            effectWrapper: this._thinSSAORenderingPipeline._ssaoCombinePostProcess,\n        });\n\n        this._ssaoCombinePostProcess.onApply = (effect: Effect) => {\n            this._thinSSAORenderingPipeline._ssaoCombinePostProcess.camera = this._scene.activeCamera;\n\n            effect.setTextureFromPostProcessOutput(\"originalColor\", this._originalColorPostProcess);\n        };\n        this._ssaoCombinePostProcess.autoClear = false;\n        this._ssaoCombinePostProcess.samples = this.textureSamples;\n    }\n\n    /**\n     * Serialize the rendering pipeline (Used when exporting)\n     * @returns the serialized object\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n        serializationObject.customType = \"SSAO2RenderingPipeline\";\n\n        return serializationObject;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parse the serialized pipeline\n * @param source Source pipeline.\n * @param scene The scene to load the pipeline to.\n * @param rootUrl The URL of the serialized pipeline.\n * @returns An instantiated pipeline from the serialized object.\n */\nexport function SSAO2RenderingPipelineParse(source: any, scene: Scene, rootUrl: string): SSAO2RenderingPipeline {\n    return SerializationHelper.Parse(\n        () => new SSAO2RenderingPipeline(source._name, scene, source._ratio, undefined, source._forceGeometryBuffer, source._textureType),\n        source,\n        scene,\n        rootUrl\n    );\n}\n\n/**\n * Register side effects for ssao2RenderingPipeline.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterSsao2RenderingPipeline(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    // Eagerly register the Scene.postProcessRenderPipelineManager getter (and inject its concrete class).\n    // The base PostProcessRenderPipeline constructor also registers it, but consumers may access the manager\n    // (e.g. to subscribe to its observables) before constructing the SSAO2 pipeline, so register it as soon as\n    // the SSAO2 module is imported. Idempotent.\n    RegisterPostProcessRenderPipelineManagerSceneComponent(PostProcessRenderPipelineManager);\n\n    SSAO2RenderingPipeline.Parse = SSAO2RenderingPipelineParse;\n\n    RegisterClass(\"BABYLON.SSAO2RenderingPipeline\", SSAO2RenderingPipeline);\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Vector2, TmpVectors } from \"../../../Maths/math.vector.pure\";\r\nimport { type Camera } from \"../../../Cameras/camera.pure\";\r\nimport { type Effect } from \"../../../Materials/effect.pure\";\r\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\r\nimport { PostProcess } from \"../../../PostProcesses/postProcess.pure\";\r\nimport { PostProcessRenderPipeline } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipeline\";\r\nimport { PostProcessRenderEffect } from \"../../../PostProcesses/RenderPipeline/postProcessRenderEffect\";\r\nimport { PassPostProcess } from \"../../../PostProcesses/passPostProcess.pure\";\r\nimport { BlurPostProcess } from \"../../../PostProcesses/blurPostProcess.pure\";\r\nimport { Constants } from \"../../../Engines/constants\";\r\nimport { serialize } from \"../../../Misc/decorators\";\r\nimport { type Scene } from \"../../../scene.pure\";\r\nimport { RegisterDepthRendererSceneComponent } from \"../../../Rendering/depthRendererSceneComponent.pure\";\r\nimport { DepthRenderer } from \"../../../Rendering/depthRenderer.pure\";\r\nimport { RawTexture } from \"../../../Materials/Textures/rawTexture\";\r\nimport { RandomRange } from \"../../../Maths/math.scalar.functions\";\r\n\r\n/**\r\n * Render pipeline to produce ssao effect\r\n */\r\nexport class SSAORenderingPipeline extends PostProcessRenderPipeline {\r\n    // Members\r\n\r\n    /**\r\n     * @ignore\r\n     * The PassPostProcess id in the pipeline that contains the original scene color\r\n     */\r\n    public SSAOOriginalSceneColorEffect: string = \"SSAOOriginalSceneColorEffect\";\r\n    /**\r\n     * @ignore\r\n     * The SSAO PostProcess id in the pipeline\r\n     */\r\n    public SSAORenderEffect: string = \"SSAORenderEffect\";\r\n    /**\r\n     * @ignore\r\n     * The horizontal blur PostProcess id in the pipeline\r\n     */\r\n    public SSAOBlurHRenderEffect: string = \"SSAOBlurHRenderEffect\";\r\n    /**\r\n     * @ignore\r\n     * The vertical blur PostProcess id in the pipeline\r\n     */\r\n    public SSAOBlurVRenderEffect: string = \"SSAOBlurVRenderEffect\";\r\n    /**\r\n     * @ignore\r\n     * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect)\r\n     */\r\n    public SSAOCombineRenderEffect: string = \"SSAOCombineRenderEffect\";\r\n\r\n    /**\r\n     * The output strength of the SSAO post-process. Default value is 1.0.\r\n     */\r\n    @serialize()\r\n    public totalStrength: number = 1.0;\r\n\r\n    /**\r\n     * The radius around the analyzed pixel used by the SSAO post-process. Default value is 0.0006\r\n     */\r\n    @serialize()\r\n    public radius: number = 0.0001;\r\n\r\n    /**\r\n     * Related to fallOff, used to interpolate SSAO samples (first interpolate function input) based on the occlusion difference of each pixel\r\n     * Must not be equal to fallOff and superior to fallOff.\r\n     * Default value is 0.0075\r\n     */\r\n    @serialize()\r\n    public area: number = 0.0075;\r\n\r\n    /**\r\n     * Related to area, used to interpolate SSAO samples (second interpolate function input) based on the occlusion difference of each pixel\r\n     * Must not be equal to area and inferior to area.\r\n     * Default value is 0.000001\r\n     */\r\n    @serialize()\r\n    public fallOff: number = 0.000001;\r\n\r\n    /**\r\n     * The base color of the SSAO post-process\r\n     * The final result is \"base + ssao\" between [0, 1]\r\n     */\r\n    @serialize()\r\n    public base: number = 0.5;\r\n\r\n    private _scene: Scene;\r\n    private _randomTexture: Texture;\r\n\r\n    private _originalColorPostProcess: PassPostProcess;\r\n    private _ssaoPostProcess: PostProcess;\r\n    private _blurHPostProcess: BlurPostProcess;\r\n    private _blurVPostProcess: BlurPostProcess;\r\n    private _ssaoCombinePostProcess: PostProcess;\r\n\r\n    private _firstUpdate: boolean = true;\r\n\r\n    /**\r\n     * Gets active scene\r\n     */\r\n    public get scene(): Scene {\r\n        return this._scene;\r\n    }\r\n\r\n    /**\r\n     * @constructor\r\n     * @param name - The rendering pipeline name\r\n     * @param scene - The scene linked to this pipeline\r\n     * @param ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, combineRatio: 1.0 }\r\n     * @param cameras - The array of cameras that the rendering pipeline will be attached to\r\n     */\r\n    constructor(name: string, scene: Scene, ratio: any, cameras?: Camera[]) {\r\n        RegisterDepthRendererSceneComponent(DepthRenderer);\r\n        super(scene.getEngine(), name);\r\n\r\n        this._scene = scene;\r\n\r\n        // Set up assets\r\n        this._createRandomTexture();\r\n\r\n        const ssaoRatio = ratio.ssaoRatio || ratio;\r\n        const combineRatio = ratio.combineRatio || ratio;\r\n\r\n        this._originalColorPostProcess = new PassPostProcess(\"SSAOOriginalSceneColor\", combineRatio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);\r\n        this._createSSAOPostProcess(ssaoRatio);\r\n        this._createBlurPostProcess(ssaoRatio);\r\n        this._createSSAOCombinePostProcess(combineRatio);\r\n\r\n        // Set up pipeline\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.SSAOOriginalSceneColorEffect,\r\n                () => {\r\n                    return this._originalColorPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.SSAORenderEffect,\r\n                () => {\r\n                    return this._ssaoPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.SSAOBlurHRenderEffect,\r\n                () => {\r\n                    return this._blurHPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.SSAOBlurVRenderEffect,\r\n                () => {\r\n                    return this._blurVPostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n\r\n        this.addEffect(\r\n            new PostProcessRenderEffect(\r\n                scene.getEngine(),\r\n                this.SSAOCombineRenderEffect,\r\n                () => {\r\n                    return this._ssaoCombinePostProcess;\r\n                },\r\n                true\r\n            )\r\n        );\r\n\r\n        // Finish\r\n        scene.postProcessRenderPipelineManager.addPipeline(this);\r\n        if (cameras) {\r\n            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _attachCameras(cameras: any, unique: boolean): void {\r\n        super._attachCameras(cameras, unique);\r\n\r\n        for (const camera of this._cameras) {\r\n            this._scene.enableDepthRenderer(camera).getDepthMap(); // Force depth renderer \"on\"\r\n        }\r\n    }\r\n\r\n    // Public Methods\r\n\r\n    /**\r\n     * Get the class name\r\n     * @returns \"SSAORenderingPipeline\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"SSAORenderingPipeline\";\r\n    }\r\n\r\n    /**\r\n     * Removes the internal pipeline assets and detaches the pipeline from the scene cameras\r\n     * @param disableDepthRender - If the depth renderer should be disabled on the scene\r\n     */\r\n    public override dispose(disableDepthRender: boolean = false): void {\r\n        for (let i = 0; i < this._scene.cameras.length; i++) {\r\n            const camera = this._scene.cameras[i];\r\n\r\n            this._originalColorPostProcess.dispose(camera);\r\n            this._ssaoPostProcess.dispose(camera);\r\n            this._blurHPostProcess.dispose(camera);\r\n            this._blurVPostProcess.dispose(camera);\r\n            this._ssaoCombinePostProcess.dispose(camera);\r\n        }\r\n\r\n        this._randomTexture.dispose();\r\n\r\n        if (disableDepthRender) {\r\n            this._scene.disableDepthRenderer();\r\n        }\r\n\r\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);\r\n\r\n        this._scene.postProcessRenderPipelineManager.removePipeline(this._name);\r\n\r\n        super.dispose();\r\n    }\r\n\r\n    // Private Methods\r\n    private _createBlurPostProcess(ratio: number): void {\r\n        const size = 16;\r\n\r\n        this._blurHPostProcess = new BlurPostProcess(\r\n            \"BlurH\",\r\n            new Vector2(1, 0),\r\n            size,\r\n            ratio,\r\n            null,\r\n            Texture.BILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        );\r\n        this._blurVPostProcess = new BlurPostProcess(\r\n            \"BlurV\",\r\n            new Vector2(0, 1),\r\n            size,\r\n            ratio,\r\n            null,\r\n            Texture.BILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        );\r\n\r\n        this._blurHPostProcess.onActivateObservable.add(() => {\r\n            const dw = this._blurHPostProcess.width / this._scene.getEngine().getRenderWidth();\r\n            this._blurHPostProcess.kernel = size * dw;\r\n        });\r\n\r\n        this._blurVPostProcess.onActivateObservable.add(() => {\r\n            const dw = this._blurVPostProcess.height / this._scene.getEngine().getRenderHeight();\r\n            this._blurVPostProcess.kernel = size * dw;\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public override _rebuild() {\r\n        this._firstUpdate = true;\r\n        super._rebuild();\r\n    }\r\n\r\n    private _createSSAOPostProcess(ratio: number): void {\r\n        const numSamples = 16;\r\n        const sampleSphere = [\r\n            0.5381, 0.1856, -0.4319, 0.1379, 0.2486, 0.443, 0.3371, 0.5679, -0.0057, -0.6999, -0.0451, -0.0019, 0.0689, -0.1598, -0.8547, 0.056, 0.0069, -0.1843, -0.0146, 0.1402,\r\n            0.0762, 0.01, -0.1924, -0.0344, -0.3577, -0.5301, -0.4358, -0.3169, 0.1063, 0.0158, 0.0103, -0.5869, 0.0046, -0.0897, -0.494, 0.3287, 0.7119, -0.0154, -0.0918, -0.0533,\r\n            0.0596, -0.5411, 0.0352, -0.0631, 0.546, -0.4776, 0.2847, -0.0271,\r\n        ];\r\n        const samplesFactor = 1.0 / numSamples;\r\n\r\n        this._ssaoPostProcess = new PostProcess(\r\n            \"ssao\",\r\n            \"ssao\",\r\n            [\"sampleSphere\", \"samplesFactor\", \"randTextureTiles\", \"totalStrength\", \"radius\", \"area\", \"fallOff\", \"base\", \"range\", \"viewport\"],\r\n            [\"randomSampler\"],\r\n            ratio,\r\n            null,\r\n            Texture.BILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false,\r\n            \"#define SAMPLES \" + numSamples + \"\\n#define SSAO\"\r\n        );\r\n\r\n        this._ssaoPostProcess.externalTextureSamplerBinding = true;\r\n        this._ssaoPostProcess.onApply = (effect: Effect) => {\r\n            if (this._firstUpdate) {\r\n                effect.setArray3(\"sampleSphere\", sampleSphere);\r\n                effect.setFloat(\"samplesFactor\", samplesFactor);\r\n                effect.setFloat(\"randTextureTiles\", 4.0);\r\n            }\r\n\r\n            effect.setFloat(\"totalStrength\", this.totalStrength);\r\n            effect.setFloat(\"radius\", this.radius);\r\n            effect.setFloat(\"area\", this.area);\r\n            effect.setFloat(\"fallOff\", this.fallOff);\r\n            effect.setFloat(\"base\", this.base);\r\n\r\n            effect.setTexture(\"textureSampler\", this._scene.enableDepthRenderer(this._scene.activeCamera).getDepthMap());\r\n            effect.setTexture(\"randomSampler\", this._randomTexture);\r\n        };\r\n    }\r\n\r\n    private _createSSAOCombinePostProcess(ratio: number): void {\r\n        this._ssaoCombinePostProcess = new PostProcess(\r\n            \"ssaoCombine\",\r\n            \"ssaoCombine\",\r\n            [],\r\n            [\"originalColor\", \"viewport\"],\r\n            ratio,\r\n            null,\r\n            Texture.BILINEAR_SAMPLINGMODE,\r\n            this._scene.getEngine(),\r\n            false\r\n        );\r\n\r\n        this._ssaoCombinePostProcess.onApply = (effect: Effect) => {\r\n            effect.setVector4(\"viewport\", TmpVectors.Vector4[0].copyFromFloats(0, 0, 1.0, 1.0));\r\n            effect.setTextureFromPostProcess(\"originalColor\", this._originalColorPostProcess);\r\n        };\r\n    }\r\n\r\n    private _createRandomTexture(): void {\r\n        const size = 512;\r\n\r\n        const data = new Uint8Array(size * size * 4);\r\n        for (let index = 0; index < data.length;) {\r\n            data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n            data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n            data[index++] = Math.floor(Math.max(0.0, RandomRange(-1.0, 1.0)) * 255);\r\n            data[index++] = 255;\r\n        }\r\n\r\n        const texture = RawTexture.CreateRGBATexture(data, size, size, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);\r\n        texture.name = \"SSAORandomTexture\";\r\n        texture.wrapU = Texture.WRAP_ADDRESSMODE;\r\n        texture.wrapV = Texture.WRAP_ADDRESSMODE;\r\n        this._randomTexture = texture;\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"ssaoPixelShader\";\nconst shader = `uniform sampler2D textureSampler;varying vec2 vUV;\n#ifdef SSAO\nuniform sampler2D randomSampler;uniform float randTextureTiles;uniform float samplesFactor;uniform vec3 sampleSphere[SAMPLES];uniform float totalStrength;uniform float radius;uniform float area;uniform float fallOff;uniform float base;vec3 normalFromDepth(float depth,vec2 coords)\n{vec2 offset1=vec2(0.0,radius);vec2 offset2=vec2(radius,0.0);float depth1=texture2D(textureSampler,coords+offset1).r;float depth2=texture2D(textureSampler,coords+offset2).r;vec3 p1=vec3(offset1,depth1-depth);vec3 p2=vec3(offset2,depth2-depth);vec3 normal=cross(p1,p2);normal.z=-normal.z;return normalize(normal);}\nvoid main()\n{vec3 random=normalize(texture2D(randomSampler,vUV*randTextureTiles).rgb);float depth=texture2D(textureSampler,vUV).r;vec3 position=vec3(vUV,depth);vec3 normal=normalFromDepth(depth,vUV);float radiusDepth=radius/depth;float occlusion=0.0;vec3 ray;vec3 hemiRay;float occlusionDepth;float difference;for (int i=0; i<SAMPLES; i++)\n{ray=radiusDepth*reflect(sampleSphere[i],random);hemiRay=position+sign(dot(ray,normal))*ray;occlusionDepth=texture2D(textureSampler,clamp(hemiRay.xy,vec2(0.001,0.001),vec2(0.999,0.999))).r;difference=depth-occlusionDepth;occlusion+=step(fallOff,difference)*(1.0-smoothstep(fallOff,area,difference));}\nfloat ao=1.0-totalStrength*occlusion*samplesFactor;float result=clamp(ao+base,0.0,1.0);gl_FragColor.r=result;gl_FragColor.g=result;gl_FragColor.b=result;gl_FragColor.a=1.0;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const ssaoPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"ssaoCombinePixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform sampler2D originalColor;uniform vec4 viewport;varying vec2 vUV;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec2 uv=viewport.xy+vUV*viewport.zw;vec4 ssaoColor=texture2D(textureSampler,uv);vec4 sceneColor=texture2D(originalColor,uv);gl_FragColor=sceneColor*ssaoColor;\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const ssaoCombinePixelShader = { name, shader };\n","import { Constants } from \"../Engines/constants\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\n\r\n/**\r\n * Contains all parameters needed for the prepass to perform\r\n * screen space reflections\r\n */\r\nexport class ScreenSpaceReflectionsConfiguration implements PrePassEffectConfiguration {\r\n    /**\r\n     * Is ssr enabled\r\n     */\r\n    public enabled = false;\r\n\r\n    /**\r\n     * Name of the configuration\r\n     */\r\n    public name = \"screenSpaceReflections\";\r\n\r\n    /**\r\n     * Textures that should be present in the MRT for this effect to work\r\n     */\r\n    public readonly texturesRequired: number[] = [Constants.PREPASS_NORMAL_TEXTURE_TYPE, Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE, Constants.PREPASS_POSITION_TEXTURE_TYPE];\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type PostProcessOptions } from \"./postProcess\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { GeometryBufferRenderer } from \"../Rendering/geometryBufferRenderer.pure\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type PrePassRenderer } from \"../Rendering/prePassRenderer.pure\";\r\nimport { ScreenSpaceReflectionsConfiguration } from \"../Rendering/screenSpaceReflectionsConfiguration\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The ScreenSpaceReflectionPostProcess performs realtime reflections using only and only the available informations on the screen (positions and normals).\r\n * Basically, the screen space reflection post-process will compute reflections according the material's reflectivity.\r\n * @deprecated Use the new SSRRenderingPipeline instead.\r\n */\r\nexport class ScreenSpaceReflectionPostProcess extends PostProcess {\r\n    /**\r\n     * Gets or sets a reflection threshold mainly used to adjust the reflection's height.\r\n     */\r\n    @serialize()\r\n    public threshold: number = 1.2;\r\n    /**\r\n     * Gets or sets the current reflection strength. 1.0 is an ideal value but can be increased/decreased for particular results.\r\n     */\r\n    @serialize()\r\n    public strength: number = 1;\r\n    /**\r\n     * Gets or sets the falloff exponent used while computing fresnel. More the exponent is high, more the reflections will be discrete.\r\n     */\r\n    @serialize()\r\n    public reflectionSpecularFalloffExponent: number = 3;\r\n    /**\r\n     * Gets or sets the step size used to iterate until the effect finds the color of the reflection's pixel. Typically in interval [0.1, 1.0]\r\n     */\r\n    @serialize()\r\n    public step: number = 1.0;\r\n    /**\r\n     * Gets or sets the factor applied when computing roughness. Default value is 0.2.\r\n     */\r\n    @serialize()\r\n    public roughnessFactor: number = 0.2;\r\n\r\n    private _forceGeometryBuffer: boolean = false;\r\n    private get _geometryBufferRenderer(): Nullable<GeometryBufferRenderer> {\r\n        if (!this._forceGeometryBuffer) {\r\n            return null;\r\n        }\r\n\r\n        return this._scene.geometryBufferRenderer;\r\n    }\r\n\r\n    private get _prePassRenderer(): Nullable<PrePassRenderer> {\r\n        if (this._forceGeometryBuffer) {\r\n            return null;\r\n        }\r\n\r\n        return this._scene.prePassRenderer;\r\n    }\r\n\r\n    private _enableSmoothReflections: boolean = false;\r\n    private _reflectionSamples: number = 64;\r\n    private _smoothSteps: number = 5;\r\n    private _isSceneRightHanded: boolean;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"ScreenSpaceReflectionPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ScreenSpaceReflectionPostProcess\";\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance of ScreenSpaceReflectionPostProcess.\r\n     * @param name The name of the effect.\r\n     * @param scene The scene containing the objects to calculate reflections.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: true)\r\n     * @param forceGeometryBuffer If this post process should use geometry buffer instead of prepass (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false,\r\n        forceGeometryBuffer = false\r\n    ) {\r\n        super(\r\n            name,\r\n            \"screenSpaceReflection\",\r\n            [\"projection\", \"view\", \"threshold\", \"reflectionSpecularFalloffExponent\", \"strength\", \"stepSize\", \"roughnessFactor\"],\r\n            [\"textureSampler\", \"normalSampler\", \"positionSampler\", \"reflectivitySampler\"],\r\n            options,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            \"#define SSR_SUPPORTED\\n#define REFLECTION_SAMPLES 64\\n#define SMOOTH_STEPS 5\\n\",\r\n            textureType,\r\n            undefined,\r\n            null,\r\n            blockCompilation\r\n        );\r\n\r\n        this._forceGeometryBuffer = forceGeometryBuffer;\r\n\r\n        if (this._forceGeometryBuffer) {\r\n            // Get geometry buffer renderer and update effect\r\n            const geometryBufferRenderer = scene.enableGeometryBufferRenderer();\r\n            if (geometryBufferRenderer) {\r\n                if (geometryBufferRenderer.isSupported) {\r\n                    geometryBufferRenderer.enablePosition = true;\r\n                    geometryBufferRenderer.enableReflectivity = true;\r\n\r\n                    if (geometryBufferRenderer.generateNormalsInWorldSpace) {\r\n                        Logger.Error(\"ScreenSpaceReflectionPostProcess does not support generateNormalsInWorldSpace=true for the geometry buffer renderer!\");\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const prePassRenderer = scene.enablePrePassRenderer();\r\n            prePassRenderer?.markAsDirty();\r\n            if (prePassRenderer?.generateNormalsInWorldSpace) {\r\n                Logger.Error(\"ScreenSpaceReflectionPostProcess does not support generateNormalsInWorldSpace=true for the prepass renderer!\");\r\n            }\r\n            this._prePassEffectConfiguration = new ScreenSpaceReflectionsConfiguration();\r\n        }\r\n\r\n        this._updateEffectDefines();\r\n\r\n        // On apply, send uniforms\r\n        this.onApply = (effect: Effect) => {\r\n            const geometryBufferRenderer = this._geometryBufferRenderer;\r\n            const prePassRenderer = this._prePassRenderer;\r\n\r\n            if (!prePassRenderer && !geometryBufferRenderer) {\r\n                return;\r\n            }\r\n\r\n            if (geometryBufferRenderer) {\r\n                // Samplers\r\n                const positionIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.POSITION_TEXTURE_TYPE);\r\n                const roughnessIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE);\r\n\r\n                effect.setTexture(\"normalSampler\", geometryBufferRenderer.getGBuffer().textures[1]);\r\n                effect.setTexture(\"positionSampler\", geometryBufferRenderer.getGBuffer().textures[positionIndex]);\r\n                effect.setTexture(\"reflectivitySampler\", geometryBufferRenderer.getGBuffer().textures[roughnessIndex]);\r\n            } else if (prePassRenderer) {\r\n                // Samplers\r\n                const positionIndex = prePassRenderer.getIndex(Constants.PREPASS_POSITION_TEXTURE_TYPE);\r\n                const roughnessIndex = prePassRenderer.getIndex(Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE);\r\n                const normalIndex = prePassRenderer.getIndex(Constants.PREPASS_NORMAL_TEXTURE_TYPE);\r\n\r\n                effect.setTexture(\"normalSampler\", prePassRenderer.getRenderTarget().textures[normalIndex]);\r\n                effect.setTexture(\"positionSampler\", prePassRenderer.getRenderTarget().textures[positionIndex]);\r\n                effect.setTexture(\"reflectivitySampler\", prePassRenderer.getRenderTarget().textures[roughnessIndex]);\r\n            }\r\n\r\n            // Uniforms\r\n            const camera = scene.activeCamera;\r\n            if (!camera) {\r\n                return;\r\n            }\r\n\r\n            const viewMatrix = camera.getViewMatrix(true);\r\n            const projectionMatrix = camera.getProjectionMatrix(true);\r\n\r\n            effect.setMatrix(\"projection\", projectionMatrix);\r\n            effect.setMatrix(\"view\", viewMatrix);\r\n            effect.setFloat(\"threshold\", this.threshold);\r\n            effect.setFloat(\"reflectionSpecularFalloffExponent\", this.reflectionSpecularFalloffExponent);\r\n            effect.setFloat(\"strength\", this.strength);\r\n            effect.setFloat(\"stepSize\", this.step);\r\n            effect.setFloat(\"roughnessFactor\", this.roughnessFactor);\r\n        };\r\n\r\n        this._isSceneRightHanded = scene.useRightHandedSystem;\r\n    }\r\n\r\n    /**\r\n     * Gets whether or not smoothing reflections is enabled.\r\n     * Enabling smoothing will require more GPU power and can generate a drop in FPS.\r\n     */\r\n    @serialize()\r\n    public get enableSmoothReflections(): boolean {\r\n        return this._enableSmoothReflections;\r\n    }\r\n\r\n    /**\r\n     * Sets whether or not smoothing reflections is enabled.\r\n     * Enabling smoothing will require more GPU power and can generate a drop in FPS.\r\n     */\r\n    public set enableSmoothReflections(enabled: boolean) {\r\n        if (enabled === this._enableSmoothReflections) {\r\n            return;\r\n        }\r\n\r\n        this._enableSmoothReflections = enabled;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    /**\r\n     * Gets the number of samples taken while computing reflections. More samples count is high,\r\n     * more the post-process wil require GPU power and can generate a drop in FPS. Basically in interval [25, 100].\r\n     */\r\n    @serialize()\r\n    public get reflectionSamples(): number {\r\n        return this._reflectionSamples;\r\n    }\r\n\r\n    /**\r\n     * Sets the number of samples taken while computing reflections. More samples count is high,\r\n     * more the post-process wil require GPU power and can generate a drop in FPS. Basically in interval [25, 100].\r\n     */\r\n    public set reflectionSamples(samples: number) {\r\n        if (samples === this._reflectionSamples) {\r\n            return;\r\n        }\r\n\r\n        this._reflectionSamples = samples;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    /**\r\n     * Gets the number of samples taken while smoothing reflections. More samples count is high,\r\n     * more the post-process will require GPU power and can generate a drop in FPS.\r\n     * Default value (5.0) work pretty well in all cases but can be adjusted.\r\n     */\r\n    @serialize()\r\n    public get smoothSteps(): number {\r\n        return this._smoothSteps;\r\n    }\r\n\r\n    /*\r\n     * Sets the number of samples taken while smoothing reflections. More samples count is high,\r\n     * more the post-process will require GPU power and can generate a drop in FPS.\r\n     * Default value (5.0) work pretty well in all cases but can be adjusted.\r\n     */\r\n    public set smoothSteps(steps: number) {\r\n        if (steps === this._smoothSteps) {\r\n            return;\r\n        }\r\n\r\n        this._smoothSteps = steps;\r\n        this._updateEffectDefines();\r\n    }\r\n\r\n    private _updateEffectDefines(): void {\r\n        const defines: string[] = [];\r\n        if (this._geometryBufferRenderer || this._prePassRenderer) {\r\n            defines.push(\"#define SSR_SUPPORTED\");\r\n        }\r\n        if (this._enableSmoothReflections) {\r\n            defines.push(\"#define ENABLE_SMOOTH_REFLECTIONS\");\r\n        }\r\n        if (this._isSceneRightHanded) {\r\n            defines.push(\"#define RIGHT_HANDED_SCENE\");\r\n        }\r\n\r\n        defines.push(\"#define REFLECTION_SAMPLES \" + (this._reflectionSamples >> 0));\r\n        defines.push(\"#define SMOOTH_STEPS \" + (this._smoothSteps >> 0));\r\n\r\n        this.updateEffect(defines.join(\"\\n\"));\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new ScreenSpaceReflectionPostProcess(\r\n                    parsedPostProcess.name,\r\n                    scene,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.textureType,\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for screenSpaceReflectionPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScreenSpaceReflectionPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ScreenSpaceReflectionPostProcess\", ScreenSpaceReflectionPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { type Nullable } from \"../../../types\";\nimport { serialize, serializeAsTexture } from \"../../../Misc/decorators\";\nimport { SerializationHelper } from \"../../../Misc/decorators.serialization\";\nimport { type IAnimatable } from \"../../../Animations/animatable.interface\";\nimport { Logger } from \"../../../Misc/logger\";\nimport { Vector2, Vector3, Matrix, Vector4 } from \"../../../Maths/math.vector.pure\";\nimport { Clamp } from \"../../../Maths/math.scalar.functions\";\nimport { type Camera } from \"../../../Cameras/camera.pure\";\nimport { type Effect } from \"../../../Materials/effect.pure\";\nimport { Texture } from \"../../../Materials/Textures/texture.pure\";\nimport { PostProcess } from \"../../../PostProcesses/postProcess.pure\";\nimport { PostProcessRenderPipeline } from \"../../../PostProcesses/RenderPipeline/postProcessRenderPipeline\";\nimport { PostProcessRenderEffect } from \"../../../PostProcesses/RenderPipeline/postProcessRenderEffect\";\nimport { BlurPostProcess } from \"../../../PostProcesses/blurPostProcess.pure\";\nimport { FxaaPostProcess } from \"../../../PostProcesses/fxaaPostProcess.pure\";\nimport { type IDisposable, type Scene } from \"../../../scene.pure\";\nimport { type SpotLight } from \"../../../Lights/spotLight.pure\";\nimport { type DirectionalLight } from \"../../../Lights/directionalLight.pure\";\nimport { type GeometryBufferRenderer } from \"../../../Rendering/geometryBufferRenderer.pure\";\nimport { Constants } from \"../../../Engines/constants\";\nimport { MotionBlurPostProcess } from \"../../motionBlurPostProcess.pure\";\nimport { ScreenSpaceReflectionPostProcess } from \"../../screenSpaceReflectionPostProcess.pure\";\nimport { type Animation } from \"../../../Animations/animation.pure\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\nimport { RegisterDepthRendererSceneComponent } from \"../../../Rendering/depthRendererSceneComponent.pure\";\nimport { DepthRenderer } from \"../../../Rendering/depthRenderer.pure\";\n\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**\n * Standard rendering pipeline\n * Default pipeline should be used going forward but the standard pipeline will be kept for backwards compatibility.\n * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/standardRenderingPipeline\n */\nexport class StandardRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {\n    /**\n     * Public members\n     */\n    // Post-processes\n    /**\n     * Post-process which contains the original scene color before the pipeline applies all the effects\n     */\n    public originalPostProcess: Nullable<PostProcess>;\n    /**\n     * Post-process used to down scale an image x4\n     */\n    public downSampleX4PostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to calculate the illuminated surfaces controlled by a threshold\n     */\n    public brightPassPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process array storing all the horizontal blur post-processes used by the pipeline\n     */\n    public blurHPostProcesses: PostProcess[] = [];\n    /**\n     * Post-process array storing all the vertical blur post-processes used by the pipeline\n     */\n    public blurVPostProcesses: PostProcess[] = [];\n    /**\n     * Post-process used to add colors of 2 textures (typically brightness + real scene color)\n     */\n    public textureAdderPostProcess: Nullable<PostProcess> = null;\n\n    /**\n     * Post-process used to create volumetric lighting effect\n     */\n    public volumetricLightPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to smooth the previous volumetric light post-process on the X axis\n     */\n    public volumetricLightSmoothXPostProcess: Nullable<BlurPostProcess> = null;\n    /**\n     * Post-process used to smooth the previous volumetric light post-process on the Y axis\n     */\n    public volumetricLightSmoothYPostProcess: Nullable<BlurPostProcess> = null;\n    /**\n     * Post-process used to merge the volumetric light effect and the real scene color\n     */\n    public volumetricLightMergePostProces: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to store the final volumetric light post-process (attach/detach for debug purpose)\n     */\n    public volumetricLightFinalPostProcess: Nullable<PostProcess> = null;\n\n    /**\n     * Base post-process used to calculate the average luminance of the final image for HDR\n     */\n    public luminancePostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-processes used to create down sample post-processes in order to get\n     * the average luminance of the final image for HDR\n     * Array of length \"StandardRenderingPipeline.LuminanceSteps\"\n     */\n    public luminanceDownSamplePostProcesses: PostProcess[] = [];\n    /**\n     * Post-process used to create a HDR effect (light adaptation)\n     */\n    public hdrPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to store the final texture adder post-process (attach/detach for debug purpose)\n     */\n    public textureAdderFinalPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to store the final lens flare post-process (attach/detach for debug purpose)\n     */\n    public lensFlareFinalPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to merge the final HDR post-process and the real scene color\n     */\n    public hdrFinalPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to create a lens flare effect\n     */\n    public lensFlarePostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process that merges the result of the lens flare post-process and the real scene color\n     */\n    public lensFlareComposePostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to create a motion blur effect\n     */\n    public motionBlurPostProcess: Nullable<PostProcess> = null;\n    /**\n     * Post-process used to create a depth of field effect\n     */\n    public depthOfFieldPostProcess: Nullable<PostProcess> = null;\n    /**\n     * The Fast Approximate Anti-Aliasing post process which attempts to remove aliasing from an image.\n     */\n    public fxaaPostProcess: Nullable<FxaaPostProcess> = null;\n    /**\n     * Post-process used to simulate realtime reflections using the screen space and geometry renderer.\n     */\n    public screenSpaceReflectionPostProcess: Nullable<ScreenSpaceReflectionPostProcess> = null;\n\n    // Values\n\n    /**\n     * Represents the brightness threshold in order to configure the illuminated surfaces\n     */\n    @serialize()\n    public brightThreshold: number = 1.0;\n\n    /**\n     * Configures the blur intensity used for surexposed surfaces are highlighted surfaces (light halo)\n     */\n    @serialize()\n    public blurWidth: number = 512.0;\n    /**\n     * Sets if the blur for highlighted surfaces must be only horizontal\n     */\n    @serialize()\n    public horizontalBlur: boolean = false;\n\n    /**\n     * Gets the overall exposure used by the pipeline\n     */\n    @serialize()\n    public get exposure(): number {\n        return this._fixedExposure;\n    }\n    /**\n     * Sets the overall exposure used by the pipeline\n     */\n    public set exposure(value: number) {\n        this._fixedExposure = value;\n        this._currentExposure = value;\n    }\n\n    /**\n     * Texture used typically to simulate \"dirty\" on camera lens\n     */\n    @serializeAsTexture(\"lensTexture\")\n    public lensTexture: Nullable<Texture> = null;\n\n    /**\n     * Represents the offset coefficient based on Rayleigh principle. Typically in interval [-0.2, 0.2]\n     */\n    @serialize()\n    public volumetricLightCoefficient: number = 0.2;\n    /**\n     * The overall power of volumetric lights, typically in interval [0, 10] maximum\n     */\n    @serialize()\n    public volumetricLightPower: number = 4.0;\n    /**\n     * Used the set the blur intensity to smooth the volumetric lights\n     */\n    @serialize()\n    public volumetricLightBlurScale: number = 64.0;\n    /**\n     * Light (spot or directional) used to generate the volumetric lights rays\n     * The source light must have a shadow generate so the pipeline can get its\n     * depth map\n     */\n    public sourceLight: Nullable<SpotLight | DirectionalLight> = null;\n\n    /**\n     * For eye adaptation, represents the minimum luminance the eye can see\n     */\n    @serialize()\n    public hdrMinimumLuminance: number = 1.0;\n    /**\n     * For eye adaptation, represents the decrease luminance speed\n     */\n    @serialize()\n    public hdrDecreaseRate: number = 0.5;\n    /**\n     * For eye adaptation, represents the increase luminance speed\n     */\n    @serialize()\n    public hdrIncreaseRate: number = 0.5;\n    /**\n     * Gets whether or not the exposure of the overall pipeline should be automatically adjusted by the HDR post-process\n     */\n    @serialize()\n    public get hdrAutoExposure(): boolean {\n        return this._hdrAutoExposure;\n    }\n    /**\n     * Sets whether or not the exposure of the overall pipeline should be automatically adjusted by the HDR post-process\n     */\n    public set hdrAutoExposure(value: boolean) {\n        this._hdrAutoExposure = value;\n        if (this.hdrPostProcess) {\n            const defines = [\"#define HDR\"];\n            if (value) {\n                defines.push(\"#define AUTO_EXPOSURE\");\n            }\n            this.hdrPostProcess.updateEffect(defines.join(\"\\n\"));\n        }\n    }\n\n    /**\n     * Lens color texture used by the lens flare effect. Mandatory if lens flare effect enabled\n     */\n    @serializeAsTexture(\"lensColorTexture\")\n    public lensColorTexture: Nullable<Texture> = null;\n    /**\n     * The overall strength for the lens flare effect\n     */\n    @serialize()\n    public lensFlareStrength: number = 20.0;\n    /**\n     * Dispersion coefficient for lens flare ghosts\n     */\n    @serialize()\n    public lensFlareGhostDispersal: number = 1.4;\n    /**\n     * Main lens flare halo width\n     */\n    @serialize()\n    public lensFlareHaloWidth: number = 0.7;\n    /**\n     * Based on the lens distortion effect, defines how much the lens flare result\n     * is distorted\n     */\n    @serialize()\n    public lensFlareDistortionStrength: number = 16.0;\n    /**\n     * Configures the blur intensity used for for lens flare (halo)\n     */\n    @serialize()\n    public lensFlareBlurWidth: number = 512.0;\n    /**\n     * Lens star texture must be used to simulate rays on the flares and is available\n     * in the documentation\n     */\n    @serializeAsTexture(\"lensStarTexture\")\n    public lensStarTexture: Nullable<Texture> = null;\n    /**\n     * As the \"lensTexture\" (can be the same texture or different), it is used to apply the lens\n     * flare effect by taking account of the dirt texture\n     */\n    @serializeAsTexture(\"lensFlareDirtTexture\")\n    public lensFlareDirtTexture: Nullable<Texture> = null;\n\n    /**\n     * Represents the focal length for the depth of field effect\n     */\n    @serialize()\n    public depthOfFieldDistance: number = 10.0;\n    /**\n     * Represents the blur intensity for the blurred part of the depth of field effect\n     */\n    @serialize()\n    public depthOfFieldBlurWidth: number = 64.0;\n\n    /**\n     * Gets how much the image is blurred by the movement while using the motion blur post-process\n     */\n    @serialize()\n    public get motionStrength(): number {\n        return this._motionStrength;\n    }\n    /**\n     * Sets how much the image is blurred by the movement while using the motion blur post-process\n     */\n    public set motionStrength(strength: number) {\n        this._motionStrength = strength;\n\n        if (this._isObjectBasedMotionBlur && this.motionBlurPostProcess) {\n            (this.motionBlurPostProcess as MotionBlurPostProcess).motionStrength = strength;\n        }\n    }\n\n    /**\n     * Gets whether or not the motion blur post-process is object based or screen based.\n     */\n    @serialize()\n    public get objectBasedMotionBlur(): boolean {\n        return this._isObjectBasedMotionBlur;\n    }\n    /**\n     * Sets whether or not the motion blur post-process should be object based or screen based\n     */\n    public set objectBasedMotionBlur(value: boolean) {\n        const shouldRebuild = this._isObjectBasedMotionBlur !== value;\n        this._isObjectBasedMotionBlur = value;\n\n        if (shouldRebuild) {\n            this._buildPipeline();\n        }\n    }\n\n    /**\n     * List of animations for the pipeline (IAnimatable implementation)\n     */\n    public animations: Animation[] = [];\n\n    /**\n     * Private members\n     */\n    private _scene: Scene;\n    private _currentDepthOfFieldSource: Nullable<PostProcess> = null;\n    private _basePostProcess: Nullable<PostProcess>;\n\n    private _fixedExposure: number = 1.0;\n    private _currentExposure: number = 1.0;\n    private _hdrAutoExposure: boolean = false;\n    private _hdrCurrentLuminance: number = 1.0;\n    private _motionStrength: number = 1.0;\n    private _isObjectBasedMotionBlur: boolean = false;\n\n    private _floatTextureType: number;\n\n    private _camerasToBeAttached: Array<Camera> = [];\n\n    @serialize()\n    private _ratio: number;\n\n    // Getters and setters\n    private _bloomEnabled: boolean = false;\n    private _depthOfFieldEnabled: boolean = false;\n    private _vlsEnabled: boolean = false;\n    private _lensFlareEnabled: boolean = false;\n    private _hdrEnabled: boolean = false;\n    private _motionBlurEnabled: boolean = false;\n    private _fxaaEnabled: boolean = false;\n    private _screenSpaceReflectionsEnabled: boolean = false;\n\n    private _motionBlurSamples: number = 64.0;\n    private _volumetricLightStepsCount: number = 50.0;\n    private _samples: number = 1;\n\n    /**\n     * @ignore\n     * Specifies if the bloom pipeline is enabled\n     */\n    @serialize()\n    public get BloomEnabled(): boolean {\n        return this._bloomEnabled;\n    }\n\n    public set BloomEnabled(enabled: boolean) {\n        if (this._bloomEnabled === enabled) {\n            return;\n        }\n\n        this._bloomEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * @ignore\n     * Specifies if the depth of field pipeline is enabled\n     */\n    @serialize()\n    public get DepthOfFieldEnabled(): boolean {\n        return this._depthOfFieldEnabled;\n    }\n\n    public set DepthOfFieldEnabled(enabled: boolean) {\n        if (this._depthOfFieldEnabled === enabled) {\n            return;\n        }\n\n        this._depthOfFieldEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * @ignore\n     * Specifies if the lens flare pipeline is enabled\n     */\n    @serialize()\n    public get LensFlareEnabled(): boolean {\n        return this._lensFlareEnabled;\n    }\n\n    public set LensFlareEnabled(enabled: boolean) {\n        if (this._lensFlareEnabled === enabled) {\n            return;\n        }\n\n        this._lensFlareEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * @ignore\n     * Specifies if the HDR pipeline is enabled\n     */\n    @serialize()\n    public get HDREnabled(): boolean {\n        return this._hdrEnabled;\n    }\n\n    public set HDREnabled(enabled: boolean) {\n        if (this._hdrEnabled === enabled) {\n            return;\n        }\n\n        this._hdrEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * @ignore\n     * Specifies if the volumetric lights scattering effect is enabled\n     */\n    @serialize()\n    public get VLSEnabled(): boolean {\n        return this._vlsEnabled;\n    }\n\n    public set VLSEnabled(enabled) {\n        if (this._vlsEnabled === enabled) {\n            return;\n        }\n\n        if (enabled) {\n            const geometry = this._scene.enableGeometryBufferRenderer();\n            if (!geometry) {\n                Logger.Warn(\"Geometry renderer is not supported, cannot create volumetric lights in Standard Rendering Pipeline\");\n                return;\n            }\n        }\n\n        this._vlsEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * @ignore\n     * Specifies if the motion blur effect is enabled\n     */\n    @serialize()\n    public get MotionBlurEnabled(): boolean {\n        return this._motionBlurEnabled;\n    }\n\n    public set MotionBlurEnabled(enabled: boolean) {\n        if (this._motionBlurEnabled === enabled) {\n            return;\n        }\n\n        this._motionBlurEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * Specifies if anti-aliasing is enabled\n     */\n    @serialize()\n    public get fxaaEnabled(): boolean {\n        return this._fxaaEnabled;\n    }\n\n    public set fxaaEnabled(enabled: boolean) {\n        if (this._fxaaEnabled === enabled) {\n            return;\n        }\n\n        this._fxaaEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * Specifies if screen space reflections are enabled.\n     */\n    @serialize()\n    public get screenSpaceReflectionsEnabled(): boolean {\n        return this._screenSpaceReflectionsEnabled;\n    }\n\n    public set screenSpaceReflectionsEnabled(enabled: boolean) {\n        if (this._screenSpaceReflectionsEnabled === enabled) {\n            return;\n        }\n\n        this._screenSpaceReflectionsEnabled = enabled;\n        this._buildPipeline();\n    }\n\n    /**\n     * Specifies the number of steps used to calculate the volumetric lights\n     * Typically in interval [50, 200]\n     */\n    @serialize()\n    public get volumetricLightStepsCount(): number {\n        return this._volumetricLightStepsCount;\n    }\n\n    public set volumetricLightStepsCount(count: number) {\n        if (this.volumetricLightPostProcess) {\n            this.volumetricLightPostProcess.updateEffect(\"#define VLS\\n#define NB_STEPS \" + count.toFixed(1));\n        }\n\n        this._volumetricLightStepsCount = count;\n    }\n\n    /**\n     * Specifies the number of samples used for the motion blur effect\n     * Typically in interval [16, 64]\n     */\n    @serialize()\n    public get motionBlurSamples(): number {\n        return this._motionBlurSamples;\n    }\n\n    public set motionBlurSamples(samples: number) {\n        if (this.motionBlurPostProcess) {\n            if (this._isObjectBasedMotionBlur) {\n                (this.motionBlurPostProcess as MotionBlurPostProcess).motionBlurSamples = samples;\n            } else {\n                this.motionBlurPostProcess.updateEffect(\"#define MOTION_BLUR\\n#define MAX_MOTION_SAMPLES \" + samples.toFixed(1));\n            }\n        }\n\n        this._motionBlurSamples = samples;\n    }\n\n    /**\n     * Specifies MSAA sample count, setting this to 4 will provide 4x anti aliasing. (default: 1)\n     */\n    @serialize()\n    public get samples(): number {\n        return this._samples;\n    }\n\n    public set samples(sampleCount: number) {\n        if (this._samples === sampleCount) {\n            return;\n        }\n\n        this._samples = sampleCount;\n        this._buildPipeline();\n    }\n\n    /**\n     * Default pipeline should be used going forward but the standard pipeline will be kept for backwards compatibility.\n     * @constructor\n     * @param name The rendering pipeline name\n     * @param scene The scene linked to this pipeline\n     * @param ratio The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)\n     * @param originalPostProcess the custom original color post-process. Must be \"reusable\". Can be null.\n     * @param cameras The array of cameras that the rendering pipeline will be attached to\n     */\n    constructor(name: string, scene: Scene, ratio: number, originalPostProcess: Nullable<PostProcess> = null, cameras?: Camera[]) {\n        RegisterDepthRendererSceneComponent(DepthRenderer);\n        super(scene.getEngine(), name);\n        this._cameras = cameras || scene.cameras;\n        this._cameras = this._cameras.slice();\n        this._camerasToBeAttached = this._cameras.slice();\n\n        // Initialize\n        this._scene = scene;\n        this._basePostProcess = originalPostProcess;\n        this._ratio = ratio;\n\n        // Misc\n        this._floatTextureType = scene.getEngine().getCaps().textureFloatRender ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_HALF_FLOAT;\n\n        // Finish\n        scene.postProcessRenderPipelineManager.addPipeline(this);\n        this._buildPipeline();\n    }\n\n    private _buildPipeline(): void {\n        const ratio = this._ratio;\n        const scene = this._scene;\n\n        this._disposePostProcesses();\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n            // get back cameras to be used to reattach pipeline\n            this._cameras = this._camerasToBeAttached.slice();\n        }\n        this._reset();\n\n        // Create pass post-process\n        if (this._screenSpaceReflectionsEnabled) {\n            this.screenSpaceReflectionPostProcess = new ScreenSpaceReflectionPostProcess(\n                \"HDRPass\",\n                scene,\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                this._floatTextureType\n            );\n            this.screenSpaceReflectionPostProcess.onApplyObservable.add(() => {\n                this._currentDepthOfFieldSource = this.screenSpaceReflectionPostProcess;\n            });\n            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), \"HDRScreenSpaceReflections\", () => this.screenSpaceReflectionPostProcess, true));\n        }\n\n        if (!this._basePostProcess) {\n            this.originalPostProcess = new PostProcess(\n                \"HDRPass\",\n                \"standard\",\n                [],\n                [],\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                \"#define PASS_POST_PROCESS\",\n                this._floatTextureType\n            );\n        } else {\n            this.originalPostProcess = this._basePostProcess;\n        }\n\n        this.originalPostProcess.autoClear = !this.screenSpaceReflectionPostProcess;\n        this.originalPostProcess.onApplyObservable.add(() => {\n            this._currentDepthOfFieldSource = this.originalPostProcess;\n        });\n\n        this.addEffect(new PostProcessRenderEffect(scene.getEngine(), \"HDRPassPostProcess\", () => this.originalPostProcess, true));\n\n        if (this._bloomEnabled) {\n            // Create down sample X4 post-process\n            this._createDownSampleX4PostProcess(scene, ratio / 4);\n\n            // Create bright pass post-process\n            this._createBrightPassPostProcess(scene, ratio / 4);\n\n            // Create gaussian blur post-processes (down sampling blurs)\n            this._createBlurPostProcesses(scene, ratio / 4, 1);\n\n            // Create texture adder post-process\n            this._createTextureAdderPostProcess(scene, ratio);\n\n            // Create depth-of-field source post-process\n            this.textureAdderFinalPostProcess = new PostProcess(\n                \"HDRDepthOfFieldSource\",\n                \"standard\",\n                [],\n                [],\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                \"#define PASS_POST_PROCESS\",\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    scene.getEngine(),\n                    \"HDRBaseDepthOfFieldSource\",\n                    () => {\n                        return this.textureAdderFinalPostProcess;\n                    },\n                    true\n                )\n            );\n        }\n\n        if (this._vlsEnabled) {\n            // Create volumetric light\n            this._createVolumetricLightPostProcess(scene, ratio);\n\n            // Create volumetric light final post-process\n            this.volumetricLightFinalPostProcess = new PostProcess(\n                \"HDRVLSFinal\",\n                \"standard\",\n                [],\n                [],\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                \"#define PASS_POST_PROCESS\",\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    scene.getEngine(),\n                    \"HDRVLSFinal\",\n                    () => {\n                        return this.volumetricLightFinalPostProcess;\n                    },\n                    true\n                )\n            );\n        }\n\n        if (this._lensFlareEnabled) {\n            // Create lens flare post-process\n            this._createLensFlarePostProcess(scene, ratio);\n\n            // Create depth-of-field source post-process post lens-flare and disable it now\n            this.lensFlareFinalPostProcess = new PostProcess(\n                \"HDRPostLensFlareDepthOfFieldSource\",\n                \"standard\",\n                [],\n                [],\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                \"#define PASS_POST_PROCESS\",\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    scene.getEngine(),\n                    \"HDRPostLensFlareDepthOfFieldSource\",\n                    () => {\n                        return this.lensFlareFinalPostProcess;\n                    },\n                    true\n                )\n            );\n        }\n\n        if (this._hdrEnabled) {\n            // Create luminance\n            this._createLuminancePostProcesses(scene, this._floatTextureType);\n\n            // Create HDR\n            this._createHdrPostProcess(scene, ratio);\n\n            // Create depth-of-field source post-process post hdr and disable it now\n            this.hdrFinalPostProcess = new PostProcess(\n                \"HDRPostHDReDepthOfFieldSource\",\n                \"standard\",\n                [],\n                [],\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                \"#define PASS_POST_PROCESS\",\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    scene.getEngine(),\n                    \"HDRPostHDReDepthOfFieldSource\",\n                    () => {\n                        return this.hdrFinalPostProcess;\n                    },\n                    true\n                )\n            );\n        }\n\n        if (this._depthOfFieldEnabled) {\n            // Create gaussian blur used by depth-of-field\n            this._createBlurPostProcesses(scene, ratio / 2, 3, \"depthOfFieldBlurWidth\");\n\n            // Create depth-of-field post-process\n            this._createDepthOfFieldPostProcess(scene, ratio);\n        }\n\n        if (this._motionBlurEnabled) {\n            // Create motion blur post-process\n            this._createMotionBlurPostProcess(scene, ratio);\n        }\n\n        if (this._fxaaEnabled) {\n            // Create fxaa post-process\n            this.fxaaPostProcess = new FxaaPostProcess(\"fxaa\", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, Constants.TEXTURETYPE_UNSIGNED_BYTE);\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    scene.getEngine(),\n                    \"HDRFxaa\",\n                    () => {\n                        return this.fxaaPostProcess;\n                    },\n                    true\n                )\n            );\n        }\n\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);\n        }\n\n        if (!this._enableMSAAOnFirstPostProcess(this._samples) && this._samples > 1) {\n            Logger.Warn(\"MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0\");\n        }\n    }\n\n    // Down Sample X4 Post-Process\n    private _createDownSampleX4PostProcess(scene: Scene, ratio: number): void {\n        const downSampleX4Offsets = new Array<number>(32);\n        this.downSampleX4PostProcess = new PostProcess(\n            \"HDRDownSampleX4\",\n            \"standard\",\n            [\"dsOffsets\"],\n            [],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define DOWN_SAMPLE_X4\",\n            this._floatTextureType\n        );\n\n        this.downSampleX4PostProcess.onApply = (effect: Effect) => {\n            let id = 0;\n            const width = (<PostProcess>this.downSampleX4PostProcess).width;\n            const height = (<PostProcess>this.downSampleX4PostProcess).height;\n\n            for (let i = -2; i < 2; i++) {\n                for (let j = -2; j < 2; j++) {\n                    downSampleX4Offsets[id] = (i + 0.5) * (1.0 / width);\n                    downSampleX4Offsets[id + 1] = (j + 0.5) * (1.0 / height);\n                    id += 2;\n                }\n            }\n\n            effect.setArray2(\"dsOffsets\", downSampleX4Offsets);\n        };\n\n        // Add to pipeline\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRDownSampleX4\",\n                () => {\n                    return this.downSampleX4PostProcess;\n                },\n                true\n            )\n        );\n    }\n\n    // Brightpass Post-Process\n    private _createBrightPassPostProcess(scene: Scene, ratio: number): void {\n        const brightOffsets = new Array<number>(8);\n        this.brightPassPostProcess = new PostProcess(\n            \"HDRBrightPass\",\n            \"standard\",\n            [\"dsOffsets\", \"brightThreshold\"],\n            [],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define BRIGHT_PASS\",\n            this._floatTextureType\n        );\n\n        this.brightPassPostProcess.onApply = (effect: Effect) => {\n            const sU = 1.0 / (<PostProcess>this.brightPassPostProcess).width;\n            const sV = 1.0 / (<PostProcess>this.brightPassPostProcess).height;\n\n            brightOffsets[0] = -0.5 * sU;\n            brightOffsets[1] = 0.5 * sV;\n            brightOffsets[2] = 0.5 * sU;\n            brightOffsets[3] = 0.5 * sV;\n            brightOffsets[4] = -0.5 * sU;\n            brightOffsets[5] = -0.5 * sV;\n            brightOffsets[6] = 0.5 * sU;\n            brightOffsets[7] = -0.5 * sV;\n\n            effect.setArray2(\"dsOffsets\", brightOffsets);\n            effect.setFloat(\"brightThreshold\", this.brightThreshold);\n        };\n\n        // Add to pipeline\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRBrightPass\",\n                () => {\n                    return this.brightPassPostProcess;\n                },\n                true\n            )\n        );\n    }\n\n    // Create blur H&V post-processes\n    private _createBlurPostProcesses(scene: Scene, ratio: number, indice: number, blurWidthKey: string = \"blurWidth\"): void {\n        const engine = scene.getEngine();\n\n        const blurX = new BlurPostProcess(\n            \"HDRBlurH\" + \"_\" + indice,\n            new Vector2(1, 0),\n            (<any>this)[blurWidthKey],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            this._floatTextureType\n        );\n        const blurY = new BlurPostProcess(\n            \"HDRBlurV\" + \"_\" + indice,\n            new Vector2(0, 1),\n            (<any>this)[blurWidthKey],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            this._floatTextureType\n        );\n\n        blurX.onActivateObservable.add(() => {\n            const dw = blurX.width / engine.getRenderWidth();\n            blurX.kernel = (<any>this)[blurWidthKey] * dw;\n        });\n\n        blurY.onActivateObservable.add(() => {\n            const dw = blurY.height / engine.getRenderHeight();\n            blurY.kernel = this.horizontalBlur ? 64 * dw : (<any>this)[blurWidthKey] * dw;\n        });\n\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRBlurH\" + indice,\n                () => {\n                    return blurX;\n                },\n                true\n            )\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRBlurV\" + indice,\n                () => {\n                    return blurY;\n                },\n                true\n            )\n        );\n\n        this.blurHPostProcesses.push(blurX);\n        this.blurVPostProcesses.push(blurY);\n    }\n\n    // Create texture adder post-process\n    private _createTextureAdderPostProcess(scene: Scene, ratio: number): void {\n        this.textureAdderPostProcess = new PostProcess(\n            \"HDRTextureAdder\",\n            \"standard\",\n            [\"exposure\"],\n            [\"otherSampler\", \"lensSampler\"],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define TEXTURE_ADDER\",\n            this._floatTextureType\n        );\n        this.textureAdderPostProcess.onApply = (effect: Effect) => {\n            effect.setTextureFromPostProcess(\"otherSampler\", this._vlsEnabled ? this._currentDepthOfFieldSource : this.originalPostProcess);\n            effect.setTexture(\"lensSampler\", this.lensTexture);\n\n            effect.setFloat(\"exposure\", this._currentExposure);\n\n            this._currentDepthOfFieldSource = this.textureAdderFinalPostProcess;\n        };\n\n        // Add to pipeline\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRTextureAdder\",\n                () => {\n                    return this.textureAdderPostProcess;\n                },\n                true\n            )\n        );\n    }\n\n    private _createVolumetricLightPostProcess(scene: Scene, ratio: number): void {\n        const geometryRenderer = <GeometryBufferRenderer>scene.enableGeometryBufferRenderer();\n        geometryRenderer.enablePosition = true;\n\n        const geometry = geometryRenderer.getGBuffer();\n\n        // Base post-process\n        this.volumetricLightPostProcess = new PostProcess(\n            \"HDRVLS\",\n            \"standard\",\n            [\"shadowViewProjection\", \"cameraPosition\", \"sunDirection\", \"sunColor\", \"scatteringCoefficient\", \"scatteringPower\", \"depthValues\"],\n            [\"shadowMapSampler\", \"positionSampler\"],\n            ratio / 8,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define VLS\\n#define NB_STEPS \" + this._volumetricLightStepsCount.toFixed(1)\n        );\n\n        const depthValues = Vector2.Zero();\n\n        this.volumetricLightPostProcess.onApply = (effect: Effect) => {\n            if (this.sourceLight && this.sourceLight.getShadowGenerator() && this._scene.activeCamera) {\n                const generator = this.sourceLight.getShadowGenerator()!;\n\n                effect.setTexture(\"shadowMapSampler\", generator.getShadowMap());\n                effect.setTexture(\"positionSampler\", geometry.textures[2]);\n\n                effect.setColor3(\"sunColor\", this.sourceLight.diffuse);\n                effect.setVector3(\"sunDirection\", this.sourceLight.getShadowDirection());\n\n                effect.setVector3(\"cameraPosition\", this._scene.activeCamera.globalPosition);\n                effect.setMatrix(\"shadowViewProjection\", generator.getTransformMatrix());\n\n                effect.setFloat(\"scatteringCoefficient\", this.volumetricLightCoefficient);\n                effect.setFloat(\"scatteringPower\", this.volumetricLightPower);\n\n                depthValues.x = this.sourceLight.getDepthMinZ(this._scene.activeCamera);\n                depthValues.y = this.sourceLight.getDepthMaxZ(this._scene.activeCamera);\n                effect.setVector2(\"depthValues\", depthValues);\n            }\n        };\n\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRVLS\",\n                () => {\n                    return this.volumetricLightPostProcess;\n                },\n                true\n            )\n        );\n\n        // Smooth\n        this._createBlurPostProcesses(scene, ratio / 4, 0, \"volumetricLightBlurScale\");\n\n        // Merge\n        this.volumetricLightMergePostProces = new PostProcess(\n            \"HDRVLSMerge\",\n            \"standard\",\n            [],\n            [\"originalSampler\"],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define VLSMERGE\"\n        );\n\n        this.volumetricLightMergePostProces.onApply = (effect: Effect) => {\n            effect.setTextureFromPostProcess(\"originalSampler\", this._bloomEnabled ? this.textureAdderFinalPostProcess : this.originalPostProcess);\n\n            this._currentDepthOfFieldSource = this.volumetricLightFinalPostProcess;\n        };\n\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRVLSMerge\",\n                () => {\n                    return this.volumetricLightMergePostProces;\n                },\n                true\n            )\n        );\n    }\n\n    // Create luminance\n    private _createLuminancePostProcesses(scene: Scene, textureType: number): void {\n        // Create luminance\n        let size = Math.pow(3, StandardRenderingPipeline.LuminanceSteps);\n        this.luminancePostProcess = new PostProcess(\n            \"HDRLuminance\",\n            \"standard\",\n            [\"lumOffsets\"],\n            [],\n            { width: size, height: size },\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define LUMINANCE\",\n            textureType\n        );\n\n        const offsets: number[] = [];\n        this.luminancePostProcess.onApply = (effect: Effect) => {\n            const sU = 1.0 / (<PostProcess>this.luminancePostProcess).width;\n            const sV = 1.0 / (<PostProcess>this.luminancePostProcess).height;\n\n            offsets[0] = -0.5 * sU;\n            offsets[1] = 0.5 * sV;\n            offsets[2] = 0.5 * sU;\n            offsets[3] = 0.5 * sV;\n            offsets[4] = -0.5 * sU;\n            offsets[5] = -0.5 * sV;\n            offsets[6] = 0.5 * sU;\n            offsets[7] = -0.5 * sV;\n\n            effect.setArray2(\"lumOffsets\", offsets);\n        };\n\n        // Add to pipeline\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRLuminance\",\n                () => {\n                    return this.luminancePostProcess;\n                },\n                true\n            )\n        );\n\n        // Create down sample luminance\n        for (let i = StandardRenderingPipeline.LuminanceSteps - 1; i >= 0; i--) {\n            size = Math.pow(3, i);\n\n            let defines = \"#define LUMINANCE_DOWN_SAMPLE\\n\";\n            if (i === 0) {\n                defines += \"#define FINAL_DOWN_SAMPLER\";\n            }\n\n            const postProcess = new PostProcess(\n                \"HDRLuminanceDownSample\" + i,\n                \"standard\",\n                [\"dsOffsets\", \"halfDestPixelSize\"],\n                [],\n                { width: size, height: size },\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                defines,\n                textureType\n            );\n            this.luminanceDownSamplePostProcesses.push(postProcess);\n        }\n\n        // Create callbacks and add effects\n        let lastLuminance: Nullable<PostProcess> = this.luminancePostProcess;\n\n        for (let index = 0; index < this.luminanceDownSamplePostProcesses.length; index++) {\n            const pp = this.luminanceDownSamplePostProcesses[index];\n            const downSampleOffsets = new Array<number>(18);\n\n            pp.onApply = (effect: Effect) => {\n                if (!lastLuminance) {\n                    return;\n                }\n\n                let id = 0;\n                for (let x = -1; x < 2; x++) {\n                    for (let y = -1; y < 2; y++) {\n                        downSampleOffsets[id] = x / lastLuminance.width;\n                        downSampleOffsets[id + 1] = y / lastLuminance.height;\n                        id += 2;\n                    }\n                }\n\n                effect.setArray2(\"dsOffsets\", downSampleOffsets);\n                effect.setFloat(\"halfDestPixelSize\", 0.5 / lastLuminance.width);\n\n                if (index === this.luminanceDownSamplePostProcesses.length - 1) {\n                    lastLuminance = this.luminancePostProcess;\n                } else {\n                    lastLuminance = pp;\n                }\n            };\n\n            if (index === this.luminanceDownSamplePostProcesses.length - 1) {\n                pp.onAfterRender = () => {\n                    const pixel = scene.getEngine().readPixels(0, 0, 1, 1);\n                    const bit_shift = new Vector4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);\n                    // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\n                    pixel.then((pixel) => {\n                        const data = new Uint8Array(pixel.buffer);\n                        this._hdrCurrentLuminance = (data[0] * bit_shift.x + data[1] * bit_shift.y + data[2] * bit_shift.z + data[3] * bit_shift.w) / 100.0;\n                    });\n                };\n            }\n\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    scene.getEngine(),\n                    \"HDRLuminanceDownSample\" + index,\n                    () => {\n                        return pp;\n                    },\n                    true\n                )\n            );\n        }\n    }\n\n    // Create HDR post-process\n    private _createHdrPostProcess(scene: Scene, ratio: number): void {\n        const defines = [\"#define HDR\"];\n        if (this._hdrAutoExposure) {\n            defines.push(\"#define AUTO_EXPOSURE\");\n        }\n        this.hdrPostProcess = new PostProcess(\n            \"HDR\",\n            \"standard\",\n            [\"averageLuminance\"],\n            [\"textureAdderSampler\"],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            defines.join(\"\\n\"),\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\n        );\n\n        let outputLiminance = 1;\n        let time = 0;\n        let lastTime = 0;\n\n        this.hdrPostProcess.onApply = (effect: Effect) => {\n            effect.setTextureFromPostProcess(\"textureAdderSampler\", this._currentDepthOfFieldSource);\n\n            time += scene.getEngine().getDeltaTime();\n\n            if (outputLiminance < 0) {\n                outputLiminance = this._hdrCurrentLuminance;\n            } else {\n                const dt = (lastTime - time) / 1000.0;\n\n                if (this._hdrCurrentLuminance < outputLiminance + this.hdrDecreaseRate * dt) {\n                    outputLiminance += this.hdrDecreaseRate * dt;\n                } else if (this._hdrCurrentLuminance > outputLiminance - this.hdrIncreaseRate * dt) {\n                    outputLiminance -= this.hdrIncreaseRate * dt;\n                } else {\n                    outputLiminance = this._hdrCurrentLuminance;\n                }\n            }\n\n            if (this.hdrAutoExposure) {\n                this._currentExposure = this._fixedExposure / outputLiminance;\n            } else {\n                outputLiminance = Clamp(outputLiminance, this.hdrMinimumLuminance, 1e20);\n                effect.setFloat(\"averageLuminance\", outputLiminance);\n            }\n\n            lastTime = time;\n\n            this._currentDepthOfFieldSource = this.hdrFinalPostProcess;\n        };\n\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDR\",\n                () => {\n                    return this.hdrPostProcess;\n                },\n                true\n            )\n        );\n    }\n\n    // Create lens flare post-process\n    private _createLensFlarePostProcess(scene: Scene, ratio: number): void {\n        this.lensFlarePostProcess = new PostProcess(\n            \"HDRLensFlare\",\n            \"standard\",\n            [\"strength\", \"ghostDispersal\", \"haloWidth\", \"resolution\", \"distortionStrength\"],\n            [\"lensColorSampler\"],\n            ratio / 2,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define LENS_FLARE\",\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRLensFlare\",\n                () => {\n                    return this.lensFlarePostProcess;\n                },\n                true\n            )\n        );\n\n        this._createBlurPostProcesses(scene, ratio / 4, 2, \"lensFlareBlurWidth\");\n\n        this.lensFlareComposePostProcess = new PostProcess(\n            \"HDRLensFlareCompose\",\n            \"standard\",\n            [\"lensStarMatrix\"],\n            [\"otherSampler\", \"lensDirtSampler\", \"lensStarSampler\"],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define LENS_FLARE_COMPOSE\",\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\n        );\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRLensFlareCompose\",\n                () => {\n                    return this.lensFlareComposePostProcess;\n                },\n                true\n            )\n        );\n\n        const resolution = new Vector2(0, 0);\n\n        // Lens flare\n        this.lensFlarePostProcess.externalTextureSamplerBinding = true;\n        this.lensFlarePostProcess.onApply = (effect: Effect) => {\n            effect.setTextureFromPostProcess(\"textureSampler\", this._bloomEnabled ? this.blurHPostProcesses[0] : this.originalPostProcess);\n            effect.setTexture(\"lensColorSampler\", this.lensColorTexture);\n            effect.setFloat(\"strength\", this.lensFlareStrength);\n            effect.setFloat(\"ghostDispersal\", this.lensFlareGhostDispersal);\n            effect.setFloat(\"haloWidth\", this.lensFlareHaloWidth);\n\n            // Shift\n            resolution.x = (<PostProcess>this.lensFlarePostProcess).width;\n            resolution.y = (<PostProcess>this.lensFlarePostProcess).height;\n            effect.setVector2(\"resolution\", resolution);\n\n            effect.setFloat(\"distortionStrength\", this.lensFlareDistortionStrength);\n        };\n\n        // Compose\n        const scaleBias1 = Matrix.FromValues(2.0, 0.0, -1.0, 0.0, 0.0, 2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);\n\n        const scaleBias2 = Matrix.FromValues(0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);\n\n        this.lensFlareComposePostProcess.onApply = (effect: Effect) => {\n            if (!this._scene.activeCamera) {\n                return;\n            }\n\n            effect.setTextureFromPostProcess(\"otherSampler\", this.lensFlarePostProcess);\n            effect.setTexture(\"lensDirtSampler\", this.lensFlareDirtTexture);\n            effect.setTexture(\"lensStarSampler\", this.lensStarTexture);\n\n            // Lens start rotation matrix\n            const camerax = <Vector4>this._scene.activeCamera.getViewMatrix().getRow(0);\n            const cameraz = <Vector4>this._scene.activeCamera.getViewMatrix().getRow(2);\n            let camRot = Vector3.Dot(camerax.toVector3(), new Vector3(1.0, 0.0, 0.0)) + Vector3.Dot(cameraz.toVector3(), new Vector3(0.0, 0.0, 1.0));\n            camRot *= 4.0;\n\n            const starRotation = Matrix.FromValues(\n                Math.cos(camRot) * 0.5,\n                -Math.sin(camRot),\n                0.0,\n                0.0,\n                Math.sin(camRot),\n                Math.cos(camRot) * 0.5,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                1.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                1.0\n            );\n\n            const lensStarMatrix = scaleBias2.multiply(starRotation).multiply(scaleBias1);\n\n            effect.setMatrix(\"lensStarMatrix\", lensStarMatrix);\n\n            this._currentDepthOfFieldSource = this.lensFlareFinalPostProcess;\n        };\n    }\n\n    // Create depth-of-field post-process\n    private _createDepthOfFieldPostProcess(scene: Scene, ratio: number): void {\n        this.depthOfFieldPostProcess = new PostProcess(\n            \"HDRDepthOfField\",\n            \"standard\",\n            [\"distance\"],\n            [\"otherSampler\", \"depthSampler\"],\n            ratio,\n            null,\n            Texture.BILINEAR_SAMPLINGMODE,\n            scene.getEngine(),\n            false,\n            \"#define DEPTH_OF_FIELD\",\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\n        );\n        this.depthOfFieldPostProcess.onApply = (effect: Effect) => {\n            effect.setTextureFromPostProcess(\"otherSampler\", this._currentDepthOfFieldSource);\n            effect.setTexture(\"depthSampler\", this._getDepthTexture());\n\n            effect.setFloat(\"distance\", this.depthOfFieldDistance);\n        };\n\n        // Add to pipeline\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRDepthOfField\",\n                () => {\n                    return this.depthOfFieldPostProcess;\n                },\n                true\n            )\n        );\n    }\n\n    // Create motion blur post-process\n    private _createMotionBlurPostProcess(scene: Scene, ratio: number): void {\n        if (this._isObjectBasedMotionBlur) {\n            const mb = new MotionBlurPostProcess(\"HDRMotionBlur\", scene, ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, Constants.TEXTURETYPE_UNSIGNED_BYTE);\n            mb.motionStrength = this.motionStrength;\n            mb.motionBlurSamples = this.motionBlurSamples;\n            this.motionBlurPostProcess = mb;\n        } else {\n            this.motionBlurPostProcess = new PostProcess(\n                \"HDRMotionBlur\",\n                \"standard\",\n                [\"inverseViewProjection\", \"prevViewProjection\", \"screenSize\", \"motionScale\", \"motionStrength\"],\n                [\"depthSampler\"],\n                ratio,\n                null,\n                Texture.BILINEAR_SAMPLINGMODE,\n                scene.getEngine(),\n                false,\n                \"#define MOTION_BLUR\\n#define MAX_MOTION_SAMPLES \" + this.motionBlurSamples.toFixed(1),\n                Constants.TEXTURETYPE_UNSIGNED_BYTE\n            );\n\n            let motionScale: number = 0;\n            let prevViewProjection = Matrix.Identity();\n            const invViewProjection = Matrix.Identity();\n            let viewProjection = Matrix.Identity();\n            const screenSize = Vector2.Zero();\n\n            this.motionBlurPostProcess.onApply = (effect: Effect) => {\n                viewProjection = scene.getProjectionMatrix().multiply(scene.getViewMatrix());\n\n                viewProjection.invertToRef(invViewProjection);\n                effect.setMatrix(\"inverseViewProjection\", invViewProjection);\n\n                effect.setMatrix(\"prevViewProjection\", prevViewProjection);\n                prevViewProjection = viewProjection;\n\n                screenSize.x = (<PostProcess>this.motionBlurPostProcess).width;\n                screenSize.y = (<PostProcess>this.motionBlurPostProcess).height;\n                effect.setVector2(\"screenSize\", screenSize);\n\n                motionScale = scene.getEngine().getFps() / 60.0;\n                effect.setFloat(\"motionScale\", motionScale);\n                effect.setFloat(\"motionStrength\", this.motionStrength);\n\n                effect.setTexture(\"depthSampler\", this._getDepthTexture());\n            };\n        }\n\n        this.addEffect(\n            new PostProcessRenderEffect(\n                scene.getEngine(),\n                \"HDRMotionBlur\",\n                () => {\n                    return this.motionBlurPostProcess;\n                },\n                true\n            )\n        );\n    }\n\n    private _getDepthTexture(): Texture {\n        if (this._scene.getEngine().getCaps().drawBuffersExtension) {\n            const renderer = <GeometryBufferRenderer>this._scene.enableGeometryBufferRenderer();\n            return renderer.getGBuffer().textures[0];\n        }\n\n        return this._scene.enableDepthRenderer().getDepthMap();\n    }\n\n    private _disposePostProcesses(): void {\n        for (let i = 0; i < this._cameras.length; i++) {\n            const camera = this._cameras[i];\n\n            if (this.originalPostProcess) {\n                this.originalPostProcess.dispose(camera);\n            }\n            if (this.screenSpaceReflectionPostProcess) {\n                this.screenSpaceReflectionPostProcess.dispose(camera);\n            }\n\n            if (this.downSampleX4PostProcess) {\n                this.downSampleX4PostProcess.dispose(camera);\n            }\n            if (this.brightPassPostProcess) {\n                this.brightPassPostProcess.dispose(camera);\n            }\n            if (this.textureAdderPostProcess) {\n                this.textureAdderPostProcess.dispose(camera);\n            }\n\n            if (this.volumetricLightPostProcess) {\n                this.volumetricLightPostProcess.dispose(camera);\n            }\n            if (this.volumetricLightSmoothXPostProcess) {\n                this.volumetricLightSmoothXPostProcess.dispose(camera);\n            }\n            if (this.volumetricLightSmoothYPostProcess) {\n                this.volumetricLightSmoothYPostProcess.dispose(camera);\n            }\n            if (this.volumetricLightMergePostProces) {\n                this.volumetricLightMergePostProces.dispose(camera);\n            }\n            if (this.volumetricLightFinalPostProcess) {\n                this.volumetricLightFinalPostProcess.dispose(camera);\n            }\n\n            if (this.lensFlarePostProcess) {\n                this.lensFlarePostProcess.dispose(camera);\n            }\n            if (this.lensFlareComposePostProcess) {\n                this.lensFlareComposePostProcess.dispose(camera);\n            }\n\n            for (let j = 0; j < this.luminanceDownSamplePostProcesses.length; j++) {\n                this.luminanceDownSamplePostProcesses[j].dispose(camera);\n            }\n\n            if (this.luminancePostProcess) {\n                this.luminancePostProcess.dispose(camera);\n            }\n            if (this.hdrPostProcess) {\n                this.hdrPostProcess.dispose(camera);\n            }\n            if (this.hdrFinalPostProcess) {\n                this.hdrFinalPostProcess.dispose(camera);\n            }\n\n            if (this.depthOfFieldPostProcess) {\n                this.depthOfFieldPostProcess.dispose(camera);\n            }\n\n            if (this.motionBlurPostProcess) {\n                this.motionBlurPostProcess.dispose(camera);\n            }\n\n            if (this.fxaaPostProcess) {\n                this.fxaaPostProcess.dispose(camera);\n            }\n\n            for (let j = 0; j < this.blurHPostProcesses.length; j++) {\n                this.blurHPostProcesses[j].dispose(camera);\n            }\n\n            for (let j = 0; j < this.blurVPostProcesses.length; j++) {\n                this.blurVPostProcesses[j].dispose(camera);\n            }\n        }\n\n        this.originalPostProcess = null;\n        this.downSampleX4PostProcess = null;\n        this.brightPassPostProcess = null;\n        this.textureAdderPostProcess = null;\n        this.textureAdderFinalPostProcess = null;\n        this.volumetricLightPostProcess = null;\n        this.volumetricLightSmoothXPostProcess = null;\n        this.volumetricLightSmoothYPostProcess = null;\n        this.volumetricLightMergePostProces = null;\n        this.volumetricLightFinalPostProcess = null;\n        this.lensFlarePostProcess = null;\n        this.lensFlareComposePostProcess = null;\n        this.luminancePostProcess = null;\n        this.hdrPostProcess = null;\n        this.hdrFinalPostProcess = null;\n        this.depthOfFieldPostProcess = null;\n        this.motionBlurPostProcess = null;\n        this.fxaaPostProcess = null;\n        this.screenSpaceReflectionPostProcess = null;\n\n        this.luminanceDownSamplePostProcesses.length = 0;\n        this.blurHPostProcesses.length = 0;\n        this.blurVPostProcesses.length = 0;\n    }\n\n    /**\n     * Dispose of the pipeline and stop all post processes\n     */\n    public override dispose(): void {\n        this._disposePostProcesses();\n\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n\n        this._scene.postProcessRenderPipelineManager.removePipeline(this._name);\n\n        super.dispose();\n    }\n\n    /**\n     * Serialize the rendering pipeline (Used when exporting)\n     * @returns the serialized object\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n\n        if (this.sourceLight) {\n            serializationObject.sourceLightId = this.sourceLight.id;\n        }\n\n        if (this.screenSpaceReflectionPostProcess) {\n            serializationObject.screenSpaceReflectionPostProcess = SerializationHelper.Serialize(this.screenSpaceReflectionPostProcess);\n        }\n\n        serializationObject.customType = \"StandardRenderingPipeline\";\n\n        return serializationObject;\n    }\n\n    /**\n     * Luminance steps\n     */\n    public static LuminanceSteps: number = 6;\n}\n\nlet _Registered = false;\n\n/**\n * Parse the serialized pipeline\n * @param source Source pipeline.\n * @param scene The scene to load the pipeline to.\n * @param rootUrl The URL of the serialized pipeline.\n * @returns An instantiated pipeline from the serialized object.\n */\nexport function StandardRenderingPipelineParse(source: any, scene: Scene, rootUrl: string): StandardRenderingPipeline {\n    const p = SerializationHelper.Parse(() => new StandardRenderingPipeline(source._name, scene, source._ratio), source, scene, rootUrl);\n\n    if (source.sourceLightId) {\n        p.sourceLight = <SpotLight | DirectionalLight>scene.getLightById(source.sourceLightId);\n    }\n\n    if (source.screenSpaceReflectionPostProcess) {\n        SerializationHelper.Parse(() => p.screenSpaceReflectionPostProcess, source.screenSpaceReflectionPostProcess, scene, rootUrl);\n    }\n\n    return p;\n}\n\n/**\n * Register side effects for standardRenderingPipeline.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterStandardRenderingPipeline(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    StandardRenderingPipeline.Parse = StandardRenderingPipelineParse;\n\n    RegisterClass(\"BABYLON.StandardRenderingPipeline\", StandardRenderingPipeline);\n}\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { packingFunctions } from \"./ShadersInclude/packingFunctions\";\n\nconst name = \"standardPixelShader\";\nconst shader = `uniform sampler2D textureSampler;varying vec2 vUV;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#if defined(PASS_POST_PROCESS)\nvoid main(void)\n{vec4 color=texture2D(textureSampler,vUV);gl_FragColor=color;}\n#endif\n#if defined(DOWN_SAMPLE_X4)\nuniform vec2 dsOffsets[16];void main(void)\n{vec4 average=vec4(0.0,0.0,0.0,0.0);average=texture2D(textureSampler,vUV+dsOffsets[0]);average+=texture2D(textureSampler,vUV+dsOffsets[1]);average+=texture2D(textureSampler,vUV+dsOffsets[2]);average+=texture2D(textureSampler,vUV+dsOffsets[3]);average+=texture2D(textureSampler,vUV+dsOffsets[4]);average+=texture2D(textureSampler,vUV+dsOffsets[5]);average+=texture2D(textureSampler,vUV+dsOffsets[6]);average+=texture2D(textureSampler,vUV+dsOffsets[7]);average+=texture2D(textureSampler,vUV+dsOffsets[8]);average+=texture2D(textureSampler,vUV+dsOffsets[9]);average+=texture2D(textureSampler,vUV+dsOffsets[10]);average+=texture2D(textureSampler,vUV+dsOffsets[11]);average+=texture2D(textureSampler,vUV+dsOffsets[12]);average+=texture2D(textureSampler,vUV+dsOffsets[13]);average+=texture2D(textureSampler,vUV+dsOffsets[14]);average+=texture2D(textureSampler,vUV+dsOffsets[15]);average/=16.0;gl_FragColor=average;}\n#endif\n#if defined(BRIGHT_PASS)\nuniform vec2 dsOffsets[4];uniform float brightThreshold;void main(void)\n{vec4 average=vec4(0.0,0.0,0.0,0.0);average=texture2D(textureSampler,vUV+vec2(dsOffsets[0].x,dsOffsets[0].y));average+=texture2D(textureSampler,vUV+vec2(dsOffsets[1].x,dsOffsets[1].y));average+=texture2D(textureSampler,vUV+vec2(dsOffsets[2].x,dsOffsets[2].y));average+=texture2D(textureSampler,vUV+vec2(dsOffsets[3].x,dsOffsets[3].y));average*=0.25;float luminance=length(average.rgb);if (luminance<brightThreshold) {average=vec4(0.0,0.0,0.0,1.0);}\ngl_FragColor=average;}\n#endif\n#if defined(TEXTURE_ADDER)\nuniform sampler2D otherSampler;uniform sampler2D lensSampler;uniform float exposure;void main(void)\n{vec3 colour=texture2D(textureSampler,vUV).rgb;colour*=exposure;vec3 X=max(vec3(0.0,0.0,0.0),colour-0.004);vec3 retColor=(X*(6.2*X+0.5))/(X*(6.2*X+1.7)+0.06);colour=retColor*retColor;colour+=colour*texture2D(lensSampler,vUV).rgb;vec4 finalColor=vec4(colour.rgb,1.0)+texture2D(otherSampler,vUV);gl_FragColor=finalColor;}\n#endif\n#if defined(VLS)\n#define PI 3.1415926535897932384626433832795\nuniform mat4 shadowViewProjection;uniform mat4 lightWorld;uniform vec3 cameraPosition;uniform vec3 sunDirection;uniform vec3 sunColor;uniform vec2 depthValues;uniform float scatteringCoefficient;uniform float scatteringPower;uniform sampler2D shadowMapSampler;uniform sampler2D positionSampler;float computeScattering(float lightDotView)\n{float result=1.0-scatteringCoefficient*scatteringCoefficient;result/=(4.0*PI*pow(1.0+scatteringCoefficient*scatteringCoefficient-(2.0*scatteringCoefficient)*lightDotView,1.5));return result;}\nvoid main(void)\n{vec3 worldPos=texture2D(positionSampler,vUV).rgb;vec3 startPosition=cameraPosition;vec3 rayVector=worldPos-startPosition;float rayLength=length(rayVector);vec3 rayDirection=rayVector/rayLength;float stepLength=rayLength/NB_STEPS;vec3 stepL=rayDirection*stepLength;vec3 currentPosition=startPosition;vec3 accumFog=vec3(0.0);for (int i=0; i<int(NB_STEPS); i++)\n{vec4 worldInShadowCameraSpace=shadowViewProjection*vec4(currentPosition,1.0);float depthMetric= (worldInShadowCameraSpace.z+depthValues.x)/(depthValues.y);float shadowPixelDepth=clamp(depthMetric,0.0,1.0);worldInShadowCameraSpace.xyz/=worldInShadowCameraSpace.w;worldInShadowCameraSpace.xyz=0.5*worldInShadowCameraSpace.xyz+vec3(0.5);float shadowMapValue=texture2D(shadowMapSampler,worldInShadowCameraSpace.xy).r;if (shadowMapValue>shadowPixelDepth)\naccumFog+=sunColor*computeScattering(dot(rayDirection,sunDirection));currentPosition+=stepL;}\naccumFog/=NB_STEPS;vec3 color=accumFog*scatteringPower;gl_FragColor=vec4(color*exp(color) ,1.0);}\n#endif\n#if defined(VLSMERGE)\nuniform sampler2D originalSampler;void main(void)\n{gl_FragColor=texture2D(originalSampler,vUV)+texture2D(textureSampler,vUV);}\n#endif\n#if defined(LUMINANCE)\nuniform vec2 lumOffsets[4];void main()\n{float average=0.0;vec4 color=vec4(0.0);float maximum=-1e20;vec3 weight=vec3(0.299,0.587,0.114);for (int i=0; i<4; i++)\n{color=texture2D(textureSampler,vUV+ lumOffsets[i]);float GreyValue=dot(color.rgb,vec3(0.33,0.33,0.33));\n#ifdef WEIGHTED_AVERAGE\nfloat GreyValue=dot(color.rgb,weight);\n#endif\n#ifdef BRIGHTNESS\nfloat GreyValue=max(color.r,max(color.g,color.b));\n#endif\n#ifdef HSL_COMPONENT\nfloat GreyValue=0.5*(max(color.r,max(color.g,color.b))+min(color.r,min(color.g,color.b)));\n#endif\n#ifdef MAGNITUDE\nfloat GreyValue=length(color.rgb);\n#endif\nmaximum=max(maximum,GreyValue);average+=(0.25*log(1e-5+GreyValue));}\naverage=exp(average);gl_FragColor=vec4(average,maximum,0.0,1.0);}\n#endif\n#if defined(LUMINANCE_DOWN_SAMPLE)\nuniform vec2 dsOffsets[9];uniform float halfDestPixelSize;\n#ifdef FINAL_DOWN_SAMPLER\n#include<packingFunctions>\n#endif\nvoid main()\n{vec4 color=vec4(0.0);float average=0.0;for (int i=0; i<9; i++)\n{color=texture2D(textureSampler,vUV+vec2(halfDestPixelSize,halfDestPixelSize)+dsOffsets[i]);average+=color.r;}\naverage/=9.0;\n#ifdef FINAL_DOWN_SAMPLER\ngl_FragColor=pack(average);\n#else\ngl_FragColor=vec4(average,average,0.0,1.0);\n#endif\n}\n#endif\n#if defined(HDR)\nuniform sampler2D textureAdderSampler;uniform float averageLuminance;void main()\n{vec4 color=texture2D(textureAdderSampler,vUV);\n#ifndef AUTO_EXPOSURE\nvec4 adjustedColor=color/averageLuminance;color=adjustedColor;color.a=1.0;\n#endif\ngl_FragColor=color;}\n#endif\n#if defined(LENS_FLARE)\n#define GHOSTS 3\nuniform sampler2D lensColorSampler;uniform float strength;uniform float ghostDispersal;uniform float haloWidth;uniform vec2 resolution;uniform float distortionStrength;float hash(vec2 p)\n{float h=dot(p,vec2(127.1,311.7));return -1.0+2.0*fract(sin(h)*43758.5453123);}\nfloat noise(in vec2 p)\n{vec2 i=floor(p);vec2 f=fract(p);vec2 u=f*f*(3.0-2.0*f);return mix(mix(hash(i+vec2(0.0,0.0)),\nhash(i+vec2(1.0,0.0)),u.x),\nmix(hash(i+vec2(0.0,1.0)),\nhash(i+vec2(1.0,1.0)),u.x),u.y);}\nfloat fbm(vec2 p)\n{float f=0.0;f+=0.5000*noise(p); p*=2.02;f+=0.2500*noise(p); p*=2.03;f+=0.1250*noise(p); p*=2.01;f+=0.0625*noise(p); p*=2.04;f/=0.9375;return f;}\nvec3 pattern(vec2 uv)\n{vec2 p=-1.0+2.0*uv;float p2=dot(p,p);float f=fbm(vec2(15.0*p2))/2.0;float r=0.2+0.6*sin(12.5*length(uv-vec2(0.5)));float g=0.2+0.6*sin(20.5*length(uv-vec2(0.5)));float b=0.2+0.6*sin(17.2*length(uv-vec2(0.5)));return (1.0-f)*vec3(r,g,b);}\nfloat luminance(vec3 color)\n{return dot(color.rgb,vec3(0.2126,0.7152,0.0722));}\nvec4 textureDistorted(sampler2D tex,vec2 texcoord,vec2 direction,vec3 distortion)\n{return vec4(\ntexture2D(tex,texcoord+direction*distortion.r).r,\ntexture2D(tex,texcoord+direction*distortion.g).g,\ntexture2D(tex,texcoord+direction*distortion.b).b,\n1.0\n);}\nvoid main(void)\n{vec2 uv=-vUV+vec2(1.0);vec2 ghostDir=(vec2(0.5)-uv)*ghostDispersal;vec2 texelSize=1.0/resolution;vec3 distortion=vec3(-texelSize.x*distortionStrength,0.0,texelSize.x*distortionStrength);vec4 result=vec4(0.0);float ghostIndice=1.0;for (int i=0; i<GHOSTS; ++i)\n{vec2 offset=fract(uv+ghostDir*ghostIndice);float weight=length(vec2(0.5)-offset)/length(vec2(0.5));weight=pow(1.0-weight,10.0);result+=textureDistorted(textureSampler,offset,normalize(ghostDir),distortion)*weight*strength;ghostIndice+=1.0;}\nvec2 haloVec=normalize(ghostDir)*haloWidth;float weight=length(vec2(0.5)-fract(uv+haloVec))/length(vec2(0.5));weight=pow(1.0-weight,10.0);result+=textureDistorted(textureSampler,fract(uv+haloVec),normalize(ghostDir),distortion)*weight*strength;result*=texture2D(lensColorSampler,vec2(length(vec2(0.5)-uv)/length(vec2(0.5))));gl_FragColor=result;}\n#endif\n#if defined(LENS_FLARE_COMPOSE)\nuniform sampler2D otherSampler;uniform sampler2D lensDirtSampler;uniform sampler2D lensStarSampler;uniform mat4 lensStarMatrix;void main(void)\n{vec2 lensFlareCoords=(lensStarMatrix*vec4(vUV,1.0,1.0)).xy;vec4 lensMod=texture2D(lensDirtSampler,vUV);lensMod+=texture2D(lensStarSampler,vUV/*lensFlareCoords*/);vec4 result=texture2D(textureSampler,vUV)*lensMod;gl_FragColor=texture2D(otherSampler,vUV)+result;}\n#endif\n#if defined(DEPTH_OF_FIELD)\nuniform sampler2D otherSampler;uniform sampler2D depthSampler;uniform float distance;void main(void)\n{vec4 sharp=texture2D(otherSampler,vUV);vec4 blur=texture2D(textureSampler,vUV);float dist=clamp(texture2D(depthSampler,vUV).r*distance,0.0,1.0);float factor=0.0;if (dist<0.05)\nfactor=1.0;else if (dist<0.1)\nfactor=20.0*(0.1-dist);else if (dist<0.5)\nfactor=0.0;else\nfactor=2.0*(dist-0.5);factor=clamp(factor,0.0,0.90);gl_FragColor=mix(sharp,blur,factor);}\n#endif\n#if defined(MOTION_BLUR)\nuniform mat4 inverseViewProjection;uniform mat4 prevViewProjection;uniform vec2 screenSize;uniform float motionScale;uniform float motionStrength;uniform sampler2D depthSampler;void main(void)\n{vec2 texelSize=1.0/screenSize;float depth=texture2D(depthSampler,vUV).r;vec4 cpos=vec4(vUV*2.0-1.0,depth,1.0);cpos=cpos*inverseViewProjection;vec4 ppos=cpos*prevViewProjection;ppos.xyz/=ppos.w;ppos.xy=ppos.xy*0.5+0.5;vec2 velocity=(ppos.xy-vUV)*motionScale*motionStrength;float speed=length(velocity/texelSize);int nSamples=int(clamp(speed,1.0,MAX_MOTION_SAMPLES));vec4 result=texture2D(textureSampler,vUV);for (int i=1; i<int(MAX_MOTION_SAMPLES); ++i) {if (i>=nSamples)\nbreak;vec2 offset1=vUV+velocity*(float(i)/float(nSamples-1)-0.5);result+=texture2D(textureSampler,offset1);}\ngl_FragColor=result/float(nSamples);}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [packingFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const standardPixelShader = { name, shader };\n","import { Constants } from \"../Engines/constants\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\n\r\n/**\r\n * Contains all parameters needed for the prepass to perform\r\n * screen space reflections\r\n */\r\nexport class ScreenSpaceReflections2Configuration implements PrePassEffectConfiguration {\r\n    /**\r\n     * Is ssr enabled\r\n     */\r\n    public enabled = false;\r\n\r\n    /**\r\n     * Name of the configuration\r\n     */\r\n    public name = \"screenSpaceReflections2\";\r\n\r\n    /**\r\n     * Textures that should be present in the MRT for this effect to work\r\n     */\r\n    public readonly texturesRequired: number[] = [Constants.PREPASS_NORMAL_TEXTURE_TYPE, Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE];\r\n\r\n    /**\r\n     * @param useScreenspaceDepth If the effect should use the screenspace depth texture instead of a linear one\r\n     */\r\n    constructor(useScreenspaceDepth: boolean = false) {\r\n        this.texturesRequired.push(useScreenspaceDepth ? Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE : Constants.PREPASS_DEPTH_TEXTURE_TYPE);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { serialize } from \"../../../Misc/decorators\";\nimport { SerializationHelper } from \"../../../Misc/decorators.serialization\";\nimport { type Camera } from \"../../../Cameras/camera.pure\";\nimport { type Effect } from \"../../../Materials/effect.pure\";\nimport { PostProcess } from \"../../postProcess.pure\";\nimport { PostProcessRenderPipeline } from \"../postProcessRenderPipeline\";\nimport { PostProcessRenderEffect } from \"../postProcessRenderEffect\";\nimport { type Scene } from \"../../../scene.pure\";\nimport { ScreenSpaceReflections2Configuration } from \"../../../Rendering/screenSpaceReflections2Configuration\";\nimport { PrePassRenderer } from \"../../../Rendering/prePassRenderer.pure\";\nimport { GeometryBufferRenderer } from \"../../../Rendering/geometryBufferRenderer.pure\";\nimport { Constants } from \"../../../Engines/constants\";\nimport { type Nullable } from \"../../../types\";\nimport { type CubeTexture } from \"../../../Materials/Textures/cubeTexture.pure\";\nimport { DepthRenderer } from \"../../../Rendering/depthRenderer.pure\";\nimport { type ISize } from \"../../../Maths/math.size\";\nimport { ThinSSRRenderingPipeline } from \"./thinSSRRenderingPipeline\";\nimport { ThinSSRPostProcess } from \"core/PostProcesses/thinSSRPostProcess\";\nimport { RegisterPrePassRendererSceneComponent } from \"../../../Rendering/prePassRendererSceneComponent.pure\";\nimport { RegisterGeometryBufferRendererSceneComponent } from \"../../../Rendering/geometryBufferRendererSceneComponent.pure\";\nimport { ThinSSRBlurPostProcess } from \"core/PostProcesses/thinSSRBlurPostProcess\";\nimport { ThinSSRBlurCombinerPostProcess } from \"core/PostProcesses/thinSSRBlurCombinerPostProcess\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\n\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**\n * Render pipeline to produce Screen Space Reflections (SSR) effect\n *\n * References:\n *   Screen Space Ray Tracing:\n *     - http://casual-effects.blogspot.com/2014/08/screen-space-ray-tracing.html\n *     - https://sourceforge.net/p/g3d/code/HEAD/tree/G3D10/data-files/shader/screenSpaceRayTrace.glsl\n *     - https://github.com/kode80/kode80SSR\n *   SSR:\n *     - general tips: https://sakibsaikia.github.io/graphics/2016/12/26/Screen-Space-Reflection-in-Killing-Floor-2.html\n *     - computation of blur radius from roughness and distance: https://github.com/godotengine/godot/blob/master/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl\n *     - blur and usage of back depth buffer: https://github.com/kode80/kode80SSR\n */\nexport class SSRRenderingPipeline extends PostProcessRenderPipeline {\n    /**\n     * The SSR PostProcess effect id in the pipeline\n     */\n    public SSRRenderEffect: string = \"SSRRenderEffect\";\n    /**\n     * The blur PostProcess effect id in the pipeline\n     */\n    public SSRBlurRenderEffect: string = \"SSRBlurRenderEffect\";\n    /**\n     * The PostProcess effect id in the pipeline that combines the SSR-Blur output with the original scene color\n     */\n    public SSRCombineRenderEffect: string = \"SSRCombineRenderEffect\";\n\n    private _thinSSRRenderingPipeline: ThinSSRRenderingPipeline;\n\n    private _samples = 1;\n    /**\n     * MSAA sample count, setting this to 4 will provide 4x anti aliasing. (default: 1)\n     */\n    public set samples(sampleCount: number) {\n        if (this._samples === sampleCount) {\n            return;\n        }\n        this._samples = sampleCount;\n        if (this._ssrPostProcess) {\n            this._ssrPostProcess.samples = this.samples;\n        }\n    }\n\n    @serialize()\n    public get samples(): number {\n        return this._samples;\n    }\n\n    /**\n     * Gets or sets the maxDistance used to define how far we look for reflection during the ray-marching on the reflected ray (default: 1000).\n     * Note that this value is a view (camera) space distance (not pixels!).\n     */\n    @serialize()\n    public get maxDistance() {\n        return this._thinSSRRenderingPipeline.maxDistance;\n    }\n\n    public set maxDistance(distance: number) {\n        this._thinSSRRenderingPipeline.maxDistance = distance;\n    }\n\n    /**\n     * Gets or sets the step size used to iterate until the effect finds the color of the reflection's pixel. Should be an integer \\>= 1 as it is the number of pixels we advance at each step (default: 1).\n     * Use higher values to improve performances (but at the expense of quality).\n     */\n    @serialize()\n    public get step() {\n        return this._thinSSRRenderingPipeline.step;\n    }\n\n    public set step(step: number) {\n        this._thinSSRRenderingPipeline.step = step;\n    }\n\n    /**\n     * Gets or sets the thickness value used as tolerance when computing the intersection between the reflected ray and the scene (default: 0.5).\n     * If setting \"enableAutomaticThicknessComputation\" to true, you can use lower values for \"thickness\" (even 0), as the geometry thickness\n     * is automatically computed thank to the regular depth buffer + the backface depth buffer\n     */\n    @serialize()\n    public get thickness() {\n        return this._thinSSRRenderingPipeline.thickness;\n    }\n\n    public set thickness(thickness: number) {\n        this._thinSSRRenderingPipeline.thickness = thickness;\n    }\n\n    /**\n     * Gets or sets the current reflection strength. 1.0 is an ideal value but can be increased/decreased for particular results (default: 1).\n     */\n    @serialize()\n    public get strength() {\n        return this._thinSSRRenderingPipeline.strength;\n    }\n\n    public set strength(strength: number) {\n        this._thinSSRRenderingPipeline.strength = strength;\n    }\n\n    /**\n     * Gets or sets the falloff exponent used to compute the reflection strength. Higher values lead to fainter reflections (default: 1).\n     */\n    @serialize()\n    public get reflectionSpecularFalloffExponent() {\n        return this._thinSSRRenderingPipeline.reflectionSpecularFalloffExponent;\n    }\n\n    public set reflectionSpecularFalloffExponent(exponent: number) {\n        this._thinSSRRenderingPipeline.reflectionSpecularFalloffExponent = exponent;\n    }\n\n    /**\n     * Maximum number of steps during the ray marching process after which we consider an intersection could not be found (default: 1000).\n     * Should be an integer value.\n     */\n    @serialize()\n    public get maxSteps() {\n        return this._thinSSRRenderingPipeline.maxSteps;\n    }\n\n    public set maxSteps(steps: number) {\n        this._thinSSRRenderingPipeline.maxSteps = steps;\n    }\n\n    /**\n     * Gets or sets the factor applied when computing roughness. Default value is 0.2.\n     * When blurring based on roughness is enabled (meaning blurDispersionStrength \\> 0), roughnessFactor is used as a global roughness factor applied on all objects.\n     * If you want to disable this global roughness set it to 0.\n     */\n    @serialize()\n    public get roughnessFactor() {\n        return this._thinSSRRenderingPipeline.roughnessFactor;\n    }\n\n    public set roughnessFactor(factor: number) {\n        this._thinSSRRenderingPipeline.roughnessFactor = factor;\n    }\n\n    /**\n     * Number of steps to skip at start when marching the ray to avoid self collisions (default: 1)\n     * 1 should normally be a good value, depending on the scene you may need to use a higher value (2 or 3)\n     */\n    @serialize()\n    public get selfCollisionNumSkip() {\n        return this._thinSSRRenderingPipeline.selfCollisionNumSkip;\n    }\n\n    public set selfCollisionNumSkip(skip: number) {\n        this._thinSSRRenderingPipeline.selfCollisionNumSkip = skip;\n    }\n\n    /**\n     * Gets or sets the minimum value for one of the reflectivity component of the material to consider it for SSR (default: 0.04).\n     * If all r/g/b components of the reflectivity is below or equal this value, the pixel will not be considered reflective and SSR won't be applied.\n     */\n    @serialize()\n    public get reflectivityThreshold() {\n        return this._thinSSRRenderingPipeline.reflectivityThreshold;\n    }\n\n    public set reflectivityThreshold(threshold: number) {\n        const currentThreshold = this.reflectivityThreshold;\n\n        if (threshold === currentThreshold) {\n            return;\n        }\n\n        this._thinSSRRenderingPipeline.reflectivityThreshold = threshold;\n\n        if ((threshold === 0 && currentThreshold !== 0) || (threshold !== 0 && currentThreshold === 0)) {\n            this._buildPipeline();\n        }\n    }\n\n    /**\n     * Gets or sets the downsample factor used to reduce the size of the texture used to compute the SSR contribution (default: 0).\n     * Use 0 to render the SSR contribution at full resolution, 1 to render at half resolution, 2 to render at 1/3 resolution, etc.\n     * Note that it is used only when blurring is enabled (blurDispersionStrength \\> 0), because in that mode the SSR contribution is generated in a separate texture.\n     */\n    @serialize()\n    public get ssrDownsample() {\n        return this._thinSSRRenderingPipeline.ssrDownsample;\n    }\n\n    public set ssrDownsample(downsample: number) {\n        this._thinSSRRenderingPipeline.ssrDownsample = downsample;\n        this._buildPipeline();\n    }\n\n    /**\n     * Gets or sets the blur dispersion strength. Set this value to 0 to disable blurring (default: 0.03)\n     * The reflections are blurred based on the roughness of the surface and the distance between the pixel shaded and the reflected pixel: the higher the distance the more blurry the reflection is.\n     * blurDispersionStrength allows to increase or decrease this effect.\n     */\n    @serialize(\"blurDispersionStrength\")\n    public get blurDispersionStrength() {\n        return this._thinSSRRenderingPipeline.blurDispersionStrength;\n    }\n\n    public set blurDispersionStrength(strength: number) {\n        const currentStrength = this.blurDispersionStrength;\n\n        if (strength === currentStrength) {\n            return;\n        }\n\n        this._thinSSRRenderingPipeline.blurDispersionStrength = strength;\n\n        if ((strength === 0 && currentStrength !== 0) || (strength !== 0 && currentStrength === 0)) {\n            this._buildPipeline();\n        }\n    }\n\n    private _useBlur() {\n        return this.blurDispersionStrength > 0;\n    }\n\n    /**\n     * Gets or sets the downsample factor used to reduce the size of the textures used to blur the reflection effect (default: 0).\n     * Use 0 to blur at full resolution, 1 to render at half resolution, 2 to render at 1/3 resolution, etc.\n     */\n    @serialize(\"blurDownsample\")\n    public get blurDownsample() {\n        return this._thinSSRRenderingPipeline.blurDownsample;\n    }\n\n    public set blurDownsample(downsample: number) {\n        this._thinSSRRenderingPipeline.blurDownsample = downsample;\n        this._buildPipeline();\n    }\n\n    /**\n     * Gets or sets whether or not smoothing reflections is enabled (default: false)\n     * Enabling smoothing will require more GPU power.\n     * Note that this setting has no effect if step = 1: it's only used if step \\> 1.\n     */\n    @serialize(\"enableSmoothReflections\")\n    public get enableSmoothReflections(): boolean {\n        return this._thinSSRRenderingPipeline.enableSmoothReflections;\n    }\n\n    public set enableSmoothReflections(enabled: boolean) {\n        this._thinSSRRenderingPipeline.enableSmoothReflections = enabled;\n    }\n\n    private get _useScreenspaceDepth() {\n        return this._thinSSRRenderingPipeline.useScreenspaceDepth;\n    }\n\n    /**\n     * Gets or sets the environment cube texture used to define the reflection when the reflected rays of SSR leave the view space or when the maxDistance/maxSteps is reached.\n     */\n    @serialize(\"environmentTexture\")\n    public get environmentTexture() {\n        return this._thinSSRRenderingPipeline.environmentTexture;\n    }\n\n    public set environmentTexture(texture: Nullable<CubeTexture>) {\n        this._thinSSRRenderingPipeline.environmentTexture = texture;\n    }\n\n    /**\n     * Gets or sets the boolean defining if the environment texture is a standard cubemap (false) or a probe (true). Default value is false.\n     * Note: a probe cube texture is treated differently than an ordinary cube texture because the Y axis is reversed.\n     */\n    @serialize(\"environmentTextureIsProbe\")\n    public get environmentTextureIsProbe(): boolean {\n        return this._thinSSRRenderingPipeline.environmentTextureIsProbe;\n    }\n\n    public set environmentTextureIsProbe(isProbe: boolean) {\n        this._thinSSRRenderingPipeline.environmentTextureIsProbe = isProbe;\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the reflections should be attenuated at the screen borders (default: true).\n     */\n    @serialize(\"attenuateScreenBorders\")\n    public get attenuateScreenBorders() {\n        return this._thinSSRRenderingPipeline.attenuateScreenBorders;\n    }\n\n    public set attenuateScreenBorders(attenuate: boolean) {\n        this._thinSSRRenderingPipeline.attenuateScreenBorders = attenuate;\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the reflections should be attenuated according to the distance of the intersection (default: true).\n     */\n    @serialize(\"attenuateIntersectionDistance\")\n    public get attenuateIntersectionDistance() {\n        return this._thinSSRRenderingPipeline.attenuateIntersectionDistance;\n    }\n\n    public set attenuateIntersectionDistance(attenuate: boolean) {\n        this._thinSSRRenderingPipeline.attenuateIntersectionDistance = attenuate;\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the reflections should be attenuated according to the number of iterations performed to find the intersection (default: true).\n     */\n    @serialize(\"attenuateIntersectionIterations\")\n    public get attenuateIntersectionIterations() {\n        return this._thinSSRRenderingPipeline.attenuateIntersectionIterations;\n    }\n\n    public set attenuateIntersectionIterations(attenuate: boolean) {\n        this._thinSSRRenderingPipeline.attenuateIntersectionIterations = attenuate;\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the reflections should be attenuated when the reflection ray is facing the camera (the view direction) (default: false).\n     */\n    @serialize(\"attenuateFacingCamera\")\n    public get attenuateFacingCamera() {\n        return this._thinSSRRenderingPipeline.attenuateFacingCamera;\n    }\n\n    public set attenuateFacingCamera(attenuate: boolean) {\n        this._thinSSRRenderingPipeline.attenuateFacingCamera = attenuate;\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the backface reflections should be attenuated (default: false).\n     */\n    @serialize(\"attenuateBackfaceReflection\")\n    public get attenuateBackfaceReflection() {\n        return this._thinSSRRenderingPipeline.attenuateBackfaceReflection;\n    }\n\n    public set attenuateBackfaceReflection(attenuate: boolean) {\n        this._thinSSRRenderingPipeline.attenuateBackfaceReflection = attenuate;\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the ray should be clipped to the frustum (default: true).\n     * You can try to set this parameter to false to save some performances: it may produce some artefacts in some cases, but generally they won't really be visible\n     */\n    @serialize(\"clipToFrustum\")\n    public get clipToFrustum() {\n        return this._thinSSRRenderingPipeline.clipToFrustum;\n    }\n\n    public set clipToFrustum(clip: boolean) {\n        this._thinSSRRenderingPipeline.clipToFrustum = clip;\n    }\n\n    /**\n     * Gets or sets a boolean indicating whether the blending between the current color pixel and the reflection color should be done with a Fresnel coefficient (default: false).\n     * It is more physically accurate to use the Fresnel coefficient (otherwise it uses the reflectivity of the material for blending), but it is also more expensive when you use blur (when blurDispersionStrength \\> 0).\n     */\n    @serialize(\"useFresnel\")\n    public get useFresnel() {\n        return this._thinSSRRenderingPipeline.useFresnel;\n    }\n\n    public set useFresnel(fresnel: boolean) {\n        this._thinSSRRenderingPipeline.useFresnel = fresnel;\n        this._buildPipeline();\n    }\n\n    /**\n     * Gets or sets a boolean defining if geometry thickness should be computed automatically (default: false).\n     * When enabled, a depth renderer is created which will render the back faces of the scene to a depth texture (meaning additional work for the GPU).\n     * In that mode, the \"thickness\" property is still used as an offset to compute the ray intersection, but you can typically use a much lower\n     * value than when enableAutomaticThicknessComputation is false (it's even possible to use a value of 0 when using low values for \"step\")\n     * Note that for performance reasons, this option will only apply to the first camera to which the rendering pipeline is attached!\n     */\n    @serialize(\"enableAutomaticThicknessComputation\")\n    public get enableAutomaticThicknessComputation(): boolean {\n        return this._thinSSRRenderingPipeline.enableAutomaticThicknessComputation;\n    }\n\n    public set enableAutomaticThicknessComputation(automatic: boolean) {\n        this._thinSSRRenderingPipeline.enableAutomaticThicknessComputation = automatic;\n        this._buildPipeline();\n    }\n\n    /**\n     * Gets the depth renderer used to render the back faces of the scene to a depth texture.\n     */\n    public get backfaceDepthRenderer(): Nullable<DepthRenderer> {\n        return this._depthRenderer;\n    }\n\n    @serialize(\"backfaceDepthTextureDownsample\")\n    private _backfaceDepthTextureDownsample = 0;\n\n    /**\n     * Gets or sets the downsample factor (default: 0) used to create the backface depth texture - used only if enableAutomaticThicknessComputation = true.\n     * Use 0 to render the depth at full resolution, 1 to render at half resolution, 2 to render at 1/4 resolution, etc.\n     * Note that you will get rendering artefacts when using a value different from 0: it's a tradeoff between image quality and performances.\n     */\n    public get backfaceDepthTextureDownsample() {\n        return this._backfaceDepthTextureDownsample;\n    }\n\n    public set backfaceDepthTextureDownsample(factor: number) {\n        if (this._backfaceDepthTextureDownsample === factor) {\n            return;\n        }\n\n        this._backfaceDepthTextureDownsample = factor;\n        this._resizeDepthRenderer();\n    }\n\n    @serialize(\"backfaceForceDepthWriteTransparentMeshes\")\n    private _backfaceForceDepthWriteTransparentMeshes = true;\n\n    /**\n     * Gets or sets a boolean (default: true) indicating if the depth of transparent meshes should be written to the backface depth texture (when automatic thickness computation is enabled).\n     */\n    public get backfaceForceDepthWriteTransparentMeshes() {\n        return this._backfaceForceDepthWriteTransparentMeshes;\n    }\n\n    public set backfaceForceDepthWriteTransparentMeshes(force: boolean) {\n        if (this._backfaceForceDepthWriteTransparentMeshes === force) {\n            return;\n        }\n\n        this._backfaceForceDepthWriteTransparentMeshes = force;\n\n        if (this._depthRenderer) {\n            this._depthRenderer.forceDepthWriteTransparentMeshes = force;\n        }\n    }\n\n    @serialize(\"isEnabled\")\n    private _isEnabled = true;\n\n    /**\n     * Gets or sets a boolean indicating if the effect is enabled (default: true).\n     */\n    public get isEnabled(): boolean {\n        return this._isEnabled;\n    }\n\n    public set isEnabled(value: boolean) {\n        if (this._isEnabled === value) {\n            return;\n        }\n\n        this._isEnabled = value;\n\n        if (!value) {\n            if (this._cameras !== null) {\n                this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n                this._cameras = this._camerasToBeAttached.slice();\n            }\n        } else if (value) {\n            if (!this._isDirty) {\n                if (this._cameras !== null) {\n                    this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);\n                }\n            } else {\n                this._buildPipeline();\n            }\n        }\n    }\n\n    /**\n     * Gets or sets a boolean defining if the input color texture is in gamma space (default: true)\n     * The SSR effect works in linear space, so if the input texture is in gamma space, we must convert the texture to linear space before applying the effect\n     */\n    @serialize(\"inputTextureColorIsInGammaSpace\")\n    public get inputTextureColorIsInGammaSpace(): boolean {\n        return this._thinSSRRenderingPipeline.inputTextureColorIsInGammaSpace;\n    }\n\n    public set inputTextureColorIsInGammaSpace(gammaSpace: boolean) {\n        this._thinSSRRenderingPipeline.inputTextureColorIsInGammaSpace = gammaSpace;\n        this._buildPipeline();\n    }\n\n    /**\n     * Gets or sets a boolean defining if the output color texture generated by the SSR pipeline should be in gamma space (default: true)\n     * If you have a post-process that comes after the SSR and that post-process needs the input to be in a linear space, you must disable generateOutputInGammaSpace\n     */\n    @serialize(\"generateOutputInGammaSpace\")\n    public get generateOutputInGammaSpace(): boolean {\n        return this._thinSSRRenderingPipeline.generateOutputInGammaSpace;\n    }\n\n    public set generateOutputInGammaSpace(gammaSpace: boolean) {\n        this._thinSSRRenderingPipeline.generateOutputInGammaSpace = gammaSpace;\n        this._buildPipeline();\n    }\n\n    /**\n     * Gets or sets a boolean indicating if the effect should be rendered in debug mode (default: false).\n     * In this mode, colors have this meaning:\n     *   - blue: the ray hit the max distance (we reached maxDistance)\n     *   - red: the ray ran out of steps (we reached maxSteps)\n     *   - yellow: the ray went off screen\n     *   - green: the ray hit a surface. The brightness of the green color is proportional to the distance between the ray origin and the intersection point: A brighter green means more computation than a darker green.\n     * In the first 3 cases, the final color is calculated by mixing the skybox color with the pixel color (if environmentTexture is defined), otherwise the pixel color is not modified\n     * You should try to get as few blue/red/yellow pixels as possible, as this means that the ray has gone further than if it had hit a surface.\n     */\n    @serialize(\"debug\")\n    public get debug(): boolean {\n        return this._thinSSRRenderingPipeline.debug;\n    }\n\n    public set debug(value: boolean) {\n        this._thinSSRRenderingPipeline.debug = value;\n        this._buildPipeline();\n    }\n\n    /**\n     * Checks if all the post processes in the pipeline are ready.\n     * @returns True if all the post processes in the pipeline are ready\n     */\n    public isReady() {\n        return this._thinSSRRenderingPipeline.isReady();\n    }\n\n    /**\n     * Gets the scene the effect belongs to.\n     * @returns the scene the effect belongs to.\n     */\n    public getScene() {\n        return this._scene;\n    }\n\n    private _forceGeometryBuffer = false;\n    private get _geometryBufferRenderer(): Nullable<GeometryBufferRenderer> {\n        if (!this._forceGeometryBuffer) {\n            return null;\n        }\n\n        return this._scene.geometryBufferRenderer;\n    }\n\n    private get _prePassRenderer(): Nullable<PrePassRenderer> {\n        if (this._forceGeometryBuffer) {\n            return null;\n        }\n\n        return this._scene.prePassRenderer;\n    }\n\n    private _scene: Scene;\n    private _isDirty = false;\n    private _camerasToBeAttached: Array<Camera> = [];\n    private _textureType: number;\n    private _ssrPostProcess: Nullable<PostProcess>;\n    private _blurPostProcessX: Nullable<PostProcess>;\n    private _blurPostProcessY: Nullable<PostProcess>;\n    private _blurCombinerPostProcess: Nullable<PostProcess>;\n    private _depthRenderer: Nullable<DepthRenderer>;\n    private _depthRendererCamera: Nullable<Camera>;\n\n    /**\n     * Gets active scene\n     */\n    public get scene(): Scene {\n        return this._scene;\n    }\n\n    /**\n     * Returns true if SSR is supported by the running hardware\n     */\n    public override get isSupported(): boolean {\n        const caps = this._scene.getEngine().getCaps();\n\n        return caps.drawBuffersExtension && caps.texelFetch;\n    }\n\n    /**\n     * Constructor of the SSR rendering pipeline\n     * @param name The rendering pipeline name\n     * @param scene The scene linked to this pipeline\n     * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras)\n     * @param forceGeometryBuffer Set to true if you want to use the legacy geometry buffer renderer (default: false)\n     * @param textureType The texture type used by the different post processes created by SSR (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\n     * @param useScreenspaceDepth Indicates if the depth buffer should be linear or screenspace (default: false). This allows sharing the buffer with other effect pipelines that may require the depth to be in screenspace.\n     */\n    constructor(name: string, scene: Scene, cameras?: Camera[], forceGeometryBuffer = false, textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE, useScreenspaceDepth = false) {\n        RegisterPrePassRendererSceneComponent(PrePassRenderer);\n        RegisterGeometryBufferRendererSceneComponent(GeometryBufferRenderer);\n        super(scene.getEngine(), name);\n\n        this._thinSSRRenderingPipeline = new ThinSSRRenderingPipeline(name, scene);\n        this._thinSSRRenderingPipeline.isSSRSupported = false;\n        this._thinSSRRenderingPipeline.useScreenspaceDepth = useScreenspaceDepth;\n\n        this._cameras = cameras || scene.cameras;\n        this._cameras = this._cameras.slice();\n        this._camerasToBeAttached = this._cameras.slice();\n\n        this._scene = scene;\n        this._textureType = textureType;\n        this._forceGeometryBuffer = forceGeometryBuffer;\n\n        if (this.isSupported) {\n            this._createSSRPostProcess();\n\n            scene.postProcessRenderPipelineManager.addPipeline(this);\n\n            if (this._forceGeometryBuffer) {\n                const geometryBufferRenderer = scene.enableGeometryBufferRenderer();\n                if (geometryBufferRenderer) {\n                    geometryBufferRenderer.enableReflectivity = true;\n                    geometryBufferRenderer.useSpecificClearForDepthTexture = true;\n                    geometryBufferRenderer.enableScreenspaceDepth = this._useScreenspaceDepth;\n                    geometryBufferRenderer.enableDepth = !this._useScreenspaceDepth;\n                }\n            } else {\n                const prePassRenderer = scene.enablePrePassRenderer();\n                if (prePassRenderer) {\n                    prePassRenderer.useSpecificClearForDepthTexture = true;\n                    prePassRenderer.markAsDirty();\n                }\n            }\n\n            this._thinSSRRenderingPipeline.isSSRSupported = !!this._geometryBufferRenderer || !!this._prePassRenderer;\n\n            this._buildPipeline();\n        }\n    }\n\n    /**\n     * Get the class name\n     * @returns \"SSRRenderingPipeline\"\n     */\n    public override getClassName(): string {\n        return \"SSRRenderingPipeline\";\n    }\n\n    /**\n     * Adds a camera to the pipeline\n     * @param camera the camera to be added\n     */\n    public addCamera(camera: Camera): void {\n        this._camerasToBeAttached.push(camera);\n        this._buildPipeline();\n    }\n\n    /**\n     * Removes a camera from the pipeline\n     * @param camera the camera to remove\n     */\n    public removeCamera(camera: Camera): void {\n        const index = this._camerasToBeAttached.indexOf(camera);\n        this._camerasToBeAttached.splice(index, 1);\n        this._buildPipeline();\n    }\n\n    /**\n     * Removes the internal pipeline assets and detaches the pipeline from the scene cameras\n     * @param disableGeometryBufferRenderer if the geometry buffer renderer should be disabled\n     */\n    public override dispose(disableGeometryBufferRenderer: boolean = false): void {\n        this._disposeDepthRenderer();\n        this._disposeSSRPostProcess();\n        this._disposeBlurPostProcesses();\n\n        if (disableGeometryBufferRenderer) {\n            this._scene.disableGeometryBufferRenderer();\n        }\n\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n\n        this._scene.postProcessRenderPipelineManager.removePipeline(this._name);\n\n        this._thinSSRRenderingPipeline.dispose();\n\n        super.dispose();\n    }\n\n    private _getTextureSize() {\n        const engine = this._scene.getEngine();\n        const prePassRenderer = this._prePassRenderer;\n\n        let textureSize: ISize = { width: engine.getRenderWidth(), height: engine.getRenderHeight() };\n\n        if (prePassRenderer && this._scene.activeCamera?._getFirstPostProcess() === this._ssrPostProcess) {\n            const renderTarget = prePassRenderer.getRenderTarget();\n\n            if (renderTarget && renderTarget.textures) {\n                textureSize = renderTarget.textures[prePassRenderer.getIndex(Constants.PREPASS_COLOR_TEXTURE_TYPE)].getSize();\n            }\n        } else if (this._ssrPostProcess?.inputTexture) {\n            textureSize.width = this._ssrPostProcess.inputTexture.width;\n            textureSize.height = this._ssrPostProcess.inputTexture.height;\n        }\n\n        return textureSize;\n    }\n\n    private _buildPipeline() {\n        if (!this.isSupported) {\n            return;\n        }\n\n        if (!this._isEnabled) {\n            this._isDirty = true;\n            return;\n        }\n\n        this._isDirty = false;\n\n        const engine = this._scene.getEngine();\n\n        this._disposeDepthRenderer();\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n            // get back cameras to be used to reattach pipeline\n            this._cameras = this._camerasToBeAttached.slice();\n            if (this._cameras.length > 0) {\n                this._thinSSRRenderingPipeline.camera = this._cameras[0];\n            }\n        }\n        this._reset();\n\n        this._thinSSRRenderingPipeline.normalsAreInWorldSpace = !!(this._geometryBufferRenderer?.generateNormalsInWorldSpace ?? this._prePassRenderer?.generateNormalsInWorldSpace);\n\n        if (this.enableAutomaticThicknessComputation) {\n            const camera = this._cameras?.[0];\n\n            if (camera) {\n                this._depthRendererCamera = camera;\n                this._depthRenderer = new DepthRenderer(\n                    this._scene,\n                    undefined,\n                    undefined,\n                    this._useScreenspaceDepth,\n                    Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n                    !this._useScreenspaceDepth,\n                    \"SSRBackDepth\"\n                );\n                this._depthRenderer.reverseCulling = true; // we generate depth for the back faces\n                this._depthRenderer.forceDepthWriteTransparentMeshes = this.backfaceForceDepthWriteTransparentMeshes;\n\n                this._resizeDepthRenderer();\n\n                camera.customRenderTargets.push(this._depthRenderer.getDepthMap());\n            }\n        }\n\n        this.addEffect(\n            new PostProcessRenderEffect(\n                engine,\n                this.SSRRenderEffect,\n                () => {\n                    return this._ssrPostProcess;\n                },\n                true\n            )\n        );\n\n        this._disposeBlurPostProcesses();\n\n        if (this._useBlur()) {\n            this._createBlurAndCombinerPostProcesses();\n\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    engine,\n                    this.SSRBlurRenderEffect,\n                    () => {\n                        return [this._blurPostProcessX!, this._blurPostProcessY!];\n                    },\n                    true\n                )\n            );\n            this.addEffect(\n                new PostProcessRenderEffect(\n                    engine,\n                    this.SSRCombineRenderEffect,\n                    () => {\n                        return this._blurCombinerPostProcess;\n                    },\n                    true\n                )\n            );\n        }\n\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);\n        }\n    }\n\n    private _resizeDepthRenderer() {\n        if (!this._depthRenderer) {\n            return;\n        }\n\n        const textureSize = this._getTextureSize();\n        const depthRendererSize = this._depthRenderer.getDepthMap().getSize();\n\n        const width = Math.floor(textureSize.width / (this.backfaceDepthTextureDownsample + 1));\n        const height = Math.floor(textureSize.height / (this.backfaceDepthTextureDownsample + 1));\n\n        if (depthRendererSize.width !== width || depthRendererSize.height !== height) {\n            this._depthRenderer.getDepthMap().resize({ width, height });\n        }\n    }\n\n    private _disposeDepthRenderer() {\n        if (this._depthRenderer) {\n            if (this._depthRendererCamera) {\n                const idx = this._depthRendererCamera.customRenderTargets.indexOf(this._depthRenderer.getDepthMap()) ?? -1;\n                if (idx !== -1) {\n                    this._depthRendererCamera.customRenderTargets.splice(idx, 1);\n                }\n            }\n            this._depthRendererCamera = null;\n            this._depthRenderer.getDepthMap().dispose();\n        }\n        this._depthRenderer = null;\n    }\n\n    private _disposeBlurPostProcesses(): void {\n        for (let i = 0; i < this._cameras.length; i++) {\n            const camera = this._cameras[i];\n\n            this._blurPostProcessX?.dispose(camera);\n            this._blurPostProcessY?.dispose(camera);\n            this._blurCombinerPostProcess?.dispose(camera);\n        }\n\n        this._blurPostProcessX = null;\n        this._blurPostProcessY = null;\n        this._blurCombinerPostProcess = null;\n    }\n\n    private _disposeSSRPostProcess(): void {\n        for (let i = 0; i < this._cameras.length; i++) {\n            const camera = this._cameras[i];\n\n            this._ssrPostProcess?.dispose(camera);\n        }\n\n        this._ssrPostProcess = null;\n    }\n\n    private _createSSRPostProcess(): void {\n        this._ssrPostProcess = new PostProcess(\"ssr\", ThinSSRPostProcess.FragmentUrl, {\n            uniformNames: ThinSSRPostProcess.Uniforms,\n            samplerNames: ThinSSRPostProcess.Samplers,\n            size: 1.0,\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n            engine: this._scene.getEngine(),\n            textureType: this._textureType,\n            effectWrapper: this._thinSSRRenderingPipeline._ssrPostProcess,\n        });\n\n        this._ssrPostProcess.onApply = (effect: Effect) => {\n            this._resizeDepthRenderer();\n\n            const geometryBufferRenderer = this._geometryBufferRenderer;\n            const prePassRenderer = this._prePassRenderer;\n\n            if (!prePassRenderer && !geometryBufferRenderer) {\n                return;\n            }\n\n            if (geometryBufferRenderer) {\n                const roughnessIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE);\n\n                const normalIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE);\n                effect.setTexture(\"normalSampler\", geometryBufferRenderer.getGBuffer().textures[normalIndex]);\n                effect.setTexture(\"reflectivitySampler\", geometryBufferRenderer.getGBuffer().textures[roughnessIndex]);\n                if (this._useScreenspaceDepth) {\n                    const depthIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE);\n                    effect.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[depthIndex]);\n                } else {\n                    const depthIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.DEPTH_TEXTURE_TYPE);\n                    effect.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[depthIndex]);\n                }\n            } else if (prePassRenderer) {\n                const depthIndex = prePassRenderer.getIndex(this._useScreenspaceDepth ? Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE : Constants.PREPASS_DEPTH_TEXTURE_TYPE);\n                const roughnessIndex = prePassRenderer.getIndex(Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE);\n                const normalIndex = prePassRenderer.getIndex(Constants.PREPASS_NORMAL_TEXTURE_TYPE);\n\n                effect.setTexture(\"normalSampler\", prePassRenderer.getRenderTarget().textures[normalIndex]);\n                effect.setTexture(\"depthSampler\", prePassRenderer.getRenderTarget().textures[depthIndex]);\n                effect.setTexture(\"reflectivitySampler\", prePassRenderer.getRenderTarget().textures[roughnessIndex]);\n            }\n\n            if (this.enableAutomaticThicknessComputation && this._depthRenderer) {\n                effect.setTexture(\"backDepthSampler\", this._depthRenderer.getDepthMap());\n                effect.setFloat(\"backSizeFactor\", this.backfaceDepthTextureDownsample + 1);\n            }\n\n            const textureSize = this._getTextureSize();\n\n            this._thinSSRRenderingPipeline._ssrPostProcess.textureWidth = textureSize.width;\n            this._thinSSRRenderingPipeline._ssrPostProcess.textureHeight = textureSize.height;\n        };\n\n        this._ssrPostProcess.samples = this.samples;\n\n        if (!this._forceGeometryBuffer) {\n            this._ssrPostProcess._prePassEffectConfiguration = new ScreenSpaceReflections2Configuration(this._useScreenspaceDepth);\n        }\n    }\n\n    private _createBlurAndCombinerPostProcesses() {\n        const engine = this._scene.getEngine();\n\n        this._blurPostProcessX = new PostProcess(\"SSRblurX\", ThinSSRBlurPostProcess.FragmentUrl, {\n            uniformNames: ThinSSRBlurPostProcess.Uniforms,\n            samplerNames: ThinSSRBlurPostProcess.Samplers,\n            size: 1 / (this.ssrDownsample + 1),\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n            engine,\n            textureType: this._textureType,\n            effectWrapper: this._thinSSRRenderingPipeline._ssrBlurXPostProcess,\n        });\n        this._blurPostProcessX.autoClear = false;\n\n        this._blurPostProcessX.onApplyObservable.add(() => {\n            this._thinSSRRenderingPipeline._ssrBlurXPostProcess.textureWidth = this._blurPostProcessX?.inputTexture.width ?? this._scene.getEngine().getRenderWidth();\n            this._thinSSRRenderingPipeline._ssrBlurXPostProcess.textureHeight = 1; // not used\n        });\n\n        this._blurPostProcessY = new PostProcess(\"SSRblurY\", ThinSSRBlurPostProcess.FragmentUrl, {\n            uniformNames: ThinSSRBlurPostProcess.Uniforms,\n            samplerNames: ThinSSRBlurPostProcess.Samplers,\n            size: 1 / (this.blurDownsample + 1),\n            samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\n            engine,\n            textureType: this._textureType,\n            effectWrapper: this._thinSSRRenderingPipeline._ssrBlurYPostProcess,\n        });\n        this._blurPostProcessY.autoClear = false;\n\n        this._blurPostProcessY.onApplyObservable.add(() => {\n            this._thinSSRRenderingPipeline._ssrBlurYPostProcess.textureWidth = 1; // not used\n            this._thinSSRRenderingPipeline._ssrBlurYPostProcess.textureHeight = this._blurPostProcessY?.inputTexture.height ?? this._scene.getEngine().getRenderHeight();\n        });\n\n        this._blurCombinerPostProcess = new PostProcess(\"SSRblurCombiner\", ThinSSRBlurCombinerPostProcess.FragmentUrl, {\n            uniformNames: ThinSSRBlurCombinerPostProcess.Uniforms,\n            samplerNames: ThinSSRBlurCombinerPostProcess.Samplers,\n            size: 1 / (this.blurDownsample + 1),\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n            engine,\n            textureType: this._textureType,\n            effectWrapper: this._thinSSRRenderingPipeline._ssrBlurCombinerPostProcess,\n        });\n        this._blurCombinerPostProcess.autoClear = false;\n\n        this._blurCombinerPostProcess.onApplyObservable.add((effect) => {\n            const geometryBufferRenderer = this._geometryBufferRenderer;\n            const prePassRenderer = this._prePassRenderer;\n\n            if (!prePassRenderer && !geometryBufferRenderer) {\n                return;\n            }\n\n            if (prePassRenderer && this._scene.activeCamera?._getFirstPostProcess() === this._ssrPostProcess) {\n                const renderTarget = prePassRenderer.getRenderTarget();\n\n                if (renderTarget && renderTarget.textures) {\n                    effect.setTexture(\"mainSampler\", renderTarget.textures[prePassRenderer.getIndex(Constants.PREPASS_COLOR_TEXTURE_TYPE)]);\n                }\n            } else {\n                effect.setTextureFromPostProcess(\"mainSampler\", this._ssrPostProcess);\n            }\n\n            if (geometryBufferRenderer) {\n                const roughnessIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE);\n                effect.setTexture(\"reflectivitySampler\", geometryBufferRenderer.getGBuffer().textures[roughnessIndex]);\n                if (this.useFresnel) {\n                    effect.setTexture(\"normalSampler\", geometryBufferRenderer.getGBuffer().textures[1]);\n                    if (this._useScreenspaceDepth) {\n                        const depthIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE);\n                        effect.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[depthIndex]);\n                    } else {\n                        effect.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[0]);\n                    }\n                }\n            } else if (prePassRenderer) {\n                const roughnessIndex = prePassRenderer.getIndex(Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE);\n                effect.setTexture(\"reflectivitySampler\", prePassRenderer.getRenderTarget().textures[roughnessIndex]);\n                if (this.useFresnel) {\n                    const depthIndex = prePassRenderer.getIndex(\n                        this._useScreenspaceDepth ? Constants.PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE : Constants.PREPASS_DEPTH_TEXTURE_TYPE\n                    );\n                    const normalIndex = prePassRenderer.getIndex(Constants.PREPASS_NORMAL_TEXTURE_TYPE);\n\n                    effect.setTexture(\"normalSampler\", prePassRenderer.getRenderTarget().textures[normalIndex]);\n                    effect.setTexture(\"depthSampler\", prePassRenderer.getRenderTarget().textures[depthIndex]);\n                }\n            }\n        });\n    }\n\n    /**\n     * Serializes the rendering pipeline (Used when exporting)\n     * @returns the serialized object\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n        serializationObject.customType = \"SSRRenderingPipeline\";\n\n        return serializationObject;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parse the serialized pipeline\n * @param source Source pipeline.\n * @param scene The scene to load the pipeline to.\n * @param rootUrl The URL of the serialized pipeline.\n * @returns An instantiated pipeline from the serialized object.\n */\nexport function SSRRenderingPipelineParse(source: any, scene: Scene, rootUrl: string): SSRRenderingPipeline {\n    return SerializationHelper.Parse(() => new SSRRenderingPipeline(source._name, scene, source._ratio), source, scene, rootUrl);\n}\n\n/**\n * Register side effects for ssrRenderingPipeline.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterSsrRenderingPipeline(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    SSRRenderingPipeline.Parse = SSRRenderingPipelineParse;\n\n    RegisterClass(\"BABYLON.SSRRenderingPipeline\", SSRRenderingPipeline);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { serialize } from \"../../../Misc/decorators\";\nimport { SerializationHelper } from \"../../../Misc/decorators.serialization\";\nimport { type Camera } from \"../../../Cameras/camera.pure\";\nimport { type Effect } from \"../../../Materials/effect.pure\";\nimport { PostProcess } from \"../../postProcess.pure\";\nimport { PostProcessRenderPipeline } from \"../postProcessRenderPipeline\";\nimport { PostProcessRenderEffect } from \"../postProcessRenderEffect\";\nimport { type Scene } from \"../../../scene.pure\";\nimport { Constants } from \"../../../Engines/constants\";\nimport { type Nullable } from \"../../../types\";\nimport { PassPostProcess } from \"core/PostProcesses/passPostProcess.pure\";\nimport { type RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\nimport { ThinTAAPostProcess } from \"core/PostProcesses/thinTAAPostProcess\";\nimport { type PrePassEffectConfiguration } from \"core/Rendering/prePassEffectConfiguration\";\nimport { Logger } from \"core/Misc/logger\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\nimport { RegisterPrePassRendererSceneComponent } from \"../../../Rendering/prePassRendererSceneComponent.pure\";\nimport { PrePassRenderer } from \"../../../Rendering/prePassRenderer.pure\";\n\n/* eslint-disable @typescript-eslint/naming-convention */\n\nclass TAAEffectConfiguration implements PrePassEffectConfiguration {\n    public name = \"taa\";\n    public enabled = true;\n    public readonly texturesRequired = [Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE];\n}\n\n/**\n * Simple implementation of Temporal Anti-Aliasing (TAA).\n * This can be used to improve image quality for still pictures (screenshots for e.g.).\n * Note that TAA post-process must be the first in the camera, so TAARenderingPipeline must be created before any other pipeline/post-processing.\n */\nexport class TAARenderingPipeline extends PostProcessRenderPipeline {\n    /**\n     * The TAA PostProcess effect id in the pipeline\n     */\n    public TAARenderEffect: string = \"TAARenderEffect\";\n    /**\n     * The pass PostProcess effect id in the pipeline\n     */\n    public TAAPassEffect: string = \"TAAPassEffect\";\n\n    /**\n     * Number of accumulated samples (default: 16)\n     */\n    @serialize(\"samples\")\n    public set samples(samples: number) {\n        this._taaThinPostProcess.samples = samples;\n    }\n\n    public get samples(): number {\n        return this._taaThinPostProcess.samples;\n    }\n\n    @serialize(\"msaaSamples\")\n    private _msaaSamples = 1;\n    /**\n     * MSAA samples (default: 1)\n     */\n    public set msaaSamples(samples: number) {\n        if (this._msaaSamples === samples) {\n            return;\n        }\n\n        this._msaaSamples = samples;\n        if (this._taaPostProcess) {\n            this._taaPostProcess.samples = samples;\n        }\n    }\n\n    public get msaaSamples(): number {\n        return this._msaaSamples;\n    }\n\n    /**\n     * The factor used to blend the history frame with current frame (default: 0.05)\n     */\n    @serialize()\n    public get factor() {\n        return this._taaThinPostProcess.factor;\n    }\n\n    public set factor(value: number) {\n        this._taaThinPostProcess.factor = value;\n    }\n\n    /**\n     * Disable TAA on camera move (default: true).\n     * You generally want to keep this enabled, otherwise you will get a ghost effect when the camera moves (but if it's what you want, go for it!)\n     */\n    @serialize()\n    public get disableOnCameraMove() {\n        return this._taaThinPostProcess.disableOnCameraMove;\n    }\n\n    public set disableOnCameraMove(value: boolean) {\n        this._taaThinPostProcess.disableOnCameraMove = value;\n    }\n\n    /**\n     * Enables reprojecting the history texture with a per-pixel velocity.\n     */\n    @serialize()\n    public get reprojectHistory(): boolean {\n        return this._taaThinPostProcess.reprojectHistory;\n    }\n\n    public set reprojectHistory(reproject: boolean) {\n        if (this.reprojectHistory === reproject) {\n            return;\n        }\n        this._updateReprojection(reproject);\n    }\n\n    /**\n     * Clamps the history pixel to the min and max of the 3x3 pixels surrounding the target pixel.\n     * This can help further reduce ghosting and artifacts.\n     */\n    @serialize()\n    public get clampHistory(): boolean {\n        return this._taaThinPostProcess.clampHistory;\n    }\n\n    public set clampHistory(history: boolean) {\n        this._taaThinPostProcess.clampHistory = history;\n    }\n\n    @serialize(\"isEnabled\")\n    private _isEnabled = true;\n    /**\n     * Gets or sets a boolean indicating if the render pipeline is enabled (default: true).\n     */\n    public get isEnabled(): boolean {\n        return this._isEnabled;\n    }\n\n    public set isEnabled(value: boolean) {\n        if (this._isEnabled === value) {\n            return;\n        }\n\n        this._isEnabled = value;\n\n        this._taaThinPostProcess.disabled = !value;\n\n        if (!value) {\n            if (this._cameras !== null) {\n                this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n                this._cameras = this._camerasToBeAttached.slice();\n            }\n        } else if (value) {\n            if (!this._isDirty) {\n                if (this._cameras !== null) {\n                    this._taaThinPostProcess._reset();\n                    this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);\n                }\n            } else {\n                this._buildPipeline();\n            }\n        }\n    }\n\n    /**\n     * Gets active scene\n     */\n    public get scene(): Scene {\n        return this._scene;\n    }\n\n    private _scene: Scene;\n    private _isDirty = false;\n    private _camerasToBeAttached: Array<Camera> = [];\n    private _textureType: number;\n    private _taaPostProcess: Nullable<PostProcess>;\n    private _taaThinPostProcess: ThinTAAPostProcess;\n    private _passPostProcess: Nullable<PassPostProcess>;\n    private _ping: RenderTargetWrapper;\n    private _pong: RenderTargetWrapper;\n    private _pingpong = 0;\n\n    /**\n     * Returns true if TAA is supported by the running hardware\n     */\n    public override get isSupported(): boolean {\n        const caps = this._scene.getEngine().getCaps();\n\n        return caps.texelFetch;\n    }\n\n    /**\n     * Constructor of the TAA rendering pipeline\n     * @param name The rendering pipeline name\n     * @param scene The scene linked to this pipeline\n     * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras)\n     * @param textureType The type of texture where the scene will be rendered (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\n     */\n    constructor(name: string, scene: Scene, cameras?: Camera[], textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE) {\n        RegisterPrePassRendererSceneComponent(PrePassRenderer);\n        const engine = scene.getEngine();\n\n        super(engine, name);\n\n        this._cameras = cameras || scene.cameras;\n        this._cameras = this._cameras.slice();\n        this._camerasToBeAttached = this._cameras.slice();\n\n        this._scene = scene;\n        this._textureType = textureType;\n        this._taaThinPostProcess = new ThinTAAPostProcess(\"TAA\", this._scene);\n\n        if (this.isSupported) {\n            this._createPingPongTextures(engine.getRenderWidth(), engine.getRenderHeight());\n\n            scene.postProcessRenderPipelineManager.addPipeline(this);\n\n            this._buildPipeline();\n        }\n    }\n\n    /**\n     * Get the class name\n     * @returns \"TAARenderingPipeline\"\n     */\n    public override getClassName(): string {\n        return \"TAARenderingPipeline\";\n    }\n\n    /**\n     * Adds a camera to the pipeline\n     * @param camera the camera to be added\n     */\n    public addCamera(camera: Camera): void {\n        this._camerasToBeAttached.push(camera);\n        this._buildPipeline();\n    }\n\n    /**\n     * Removes a camera from the pipeline\n     * @param camera the camera to remove\n     */\n    public removeCamera(camera: Camera): void {\n        const index = this._camerasToBeAttached.indexOf(camera);\n        this._camerasToBeAttached.splice(index, 1);\n        this._buildPipeline();\n    }\n\n    /**\n     * Removes the internal pipeline assets and detaches the pipeline from the scene cameras\n     */\n    public override dispose(): void {\n        this._disposePostProcesses();\n\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n\n        this._scene.postProcessRenderPipelineManager.removePipeline(this._name);\n\n        this._ping.dispose();\n        this._pong.dispose();\n\n        super.dispose();\n    }\n\n    private _createPingPongTextures(width: number, height: number) {\n        const engine = this._scene.getEngine();\n\n        this._ping?.dispose();\n        this._pong?.dispose();\n\n        this._ping = engine.createRenderTargetTexture(\n            { width, height },\n            { generateMipMaps: false, generateDepthBuffer: false, type: Constants.TEXTURETYPE_HALF_FLOAT, samplingMode: Constants.TEXTURE_LINEAR_LINEAR }\n        );\n\n        this._pong = engine.createRenderTargetTexture(\n            { width, height },\n            { generateMipMaps: false, generateDepthBuffer: false, type: Constants.TEXTURETYPE_HALF_FLOAT, samplingMode: Constants.TEXTURE_LINEAR_LINEAR }\n        );\n\n        this._taaThinPostProcess.textureWidth = width;\n        this._taaThinPostProcess.textureHeight = height;\n    }\n\n    private _updateReprojection(reproject: boolean) {\n        if (reproject) {\n            if (!this._scene.enablePrePassRenderer()) {\n                Logger.Warn(\"TAA reprojection requires PrePass which is not supported\");\n                return;\n            }\n        }\n\n        this._taaThinPostProcess.reprojectHistory = reproject;\n\n        this._buildPipeline();\n    }\n\n    private _buildPipeline() {\n        if (!this.isSupported) {\n            return;\n        }\n\n        if (!this._isEnabled) {\n            this._isDirty = true;\n            return;\n        }\n\n        this._isDirty = false;\n\n        const engine = this._scene.getEngine();\n\n        this._disposePostProcesses();\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);\n            // get back cameras to be used to reattach pipeline\n            this._cameras = this._camerasToBeAttached.slice();\n        }\n        this._reset();\n\n        this._createTAAPostProcess();\n        this.addEffect(\n            new PostProcessRenderEffect(\n                engine,\n                this.TAARenderEffect,\n                () => {\n                    return this._taaPostProcess;\n                },\n                true\n            )\n        );\n\n        this._createPassPostProcess();\n        this.addEffect(\n            new PostProcessRenderEffect(\n                engine,\n                this.TAAPassEffect,\n                () => {\n                    return this._passPostProcess;\n                },\n                true\n            )\n        );\n\n        if (this._cameras !== null) {\n            this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);\n        }\n    }\n\n    private _disposePostProcesses(): void {\n        for (let i = 0; i < this._cameras.length; i++) {\n            const camera = this._cameras[i];\n\n            this._taaPostProcess?.dispose(camera);\n            this._passPostProcess?.dispose(camera);\n\n            camera.getProjectionMatrix(true); // recompute the projection matrix\n        }\n\n        this._taaPostProcess = null;\n        this._passPostProcess = null;\n    }\n\n    private _createTAAPostProcess(): void {\n        this._taaPostProcess = new PostProcess(\"TAA\", \"taa\", {\n            uniforms: [\"factor\"],\n            samplers: [\"historySampler\"],\n            size: 1.0,\n            engine: this._scene.getEngine(),\n            textureType: this._textureType,\n            effectWrapper: this._taaThinPostProcess,\n        });\n\n        if (this.reprojectHistory) {\n            this._taaPostProcess._prePassEffectConfiguration = new TAAEffectConfiguration();\n        }\n\n        this._taaPostProcess.samples = this._msaaSamples;\n\n        this._taaPostProcess.onActivateObservable.add(() => {\n            this._taaThinPostProcess.camera = this._scene.activeCamera;\n\n            if (this._taaPostProcess?.width !== this._ping.width || this._taaPostProcess?.height !== this._ping.height) {\n                const engine = this._scene.getEngine();\n                this._createPingPongTextures(engine.getRenderWidth(), engine.getRenderHeight());\n            }\n\n            this._taaThinPostProcess._updateJitter();\n\n            if (!this.reprojectHistory) {\n                this._scene.updateTransformMatrix(); // make sure the scene ubo is updated with the updated matrices\n            }\n\n            if (this._passPostProcess) {\n                this._passPostProcess.inputTexture = this._pingpong ? this._ping : this._pong;\n            }\n            this._pingpong = this._pingpong ^ 1;\n        });\n\n        this._taaPostProcess.onApplyObservable.add((effect: Effect) => {\n            effect._bindTexture(\"historySampler\", this._pingpong ? this._ping.texture : this._pong.texture);\n\n            const prePassRenderer = this._scene.prePassRenderer;\n            if (this.reprojectHistory && prePassRenderer) {\n                const renderTarget = prePassRenderer.getRenderTarget();\n                const velocityIndex = prePassRenderer.getIndex(Constants.PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE);\n                effect.setTexture(\"velocitySampler\", renderTarget.textures[velocityIndex]);\n            }\n        });\n    }\n\n    private _createPassPostProcess() {\n        const engine = this._scene.getEngine();\n\n        this._passPostProcess = new PassPostProcess(\"TAAPass\", 1, null, Constants.TEXTURE_NEAREST_NEAREST, engine);\n        this._passPostProcess.inputTexture = this._ping;\n        this._passPostProcess.autoClear = false;\n    }\n\n    /**\n     * Serializes the rendering pipeline (Used when exporting)\n     * @returns the serialized object\n     */\n    public serialize(): any {\n        const serializationObject = SerializationHelper.Serialize(this);\n        serializationObject.customType = \"TAARenderingPipeline\";\n\n        return serializationObject;\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Parse the serialized pipeline\n * @param source Source pipeline.\n * @param scene The scene to load the pipeline to.\n * @param rootUrl The URL of the serialized pipeline.\n * @returns An instantiated pipeline from the serialized object.\n */\nexport function TAARenderingPipelineParse(source: any, scene: Scene, rootUrl: string): TAARenderingPipeline {\n    return SerializationHelper.Parse(() => new TAARenderingPipeline(source._name, scene, source._ratio), source, scene, rootUrl);\n}\n\n/**\n * Register side effects for taaRenderingPipeline.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterTaaRenderingPipeline(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    TAARenderingPipeline.Parse = TAARenderingPipelineParse;\n\n    RegisterClass(\"BABYLON.TAARenderingPipeline\", TAARenderingPipeline);\n}\n","import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type Effect } from \"core/Materials/effect\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\nimport { EffectWrapper, type EffectWrapperCreationOptions } from \"core/Materials/effectRenderer.pure\";\r\nimport { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * Edge Adaptive Spatial Upsampling (EASU) post-process used by FSR 1\r\n */\r\nexport class ThinFSR1UpscalePostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader URL\r\n     */\r\n    public static readonly FragmentUrl = \"fsr1Upscale\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"con0\", \"con1\", \"con2\", \"con3\"];\r\n\r\n    /**\r\n     * Creates a new FSR 1 upscale post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine?: Nullable<AbstractEngine>, options?: EffectWrapperCreationOptions) {\r\n        engine ??= EngineStore.LastCreatedEngine!;\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinFSR1UpscalePostProcess.FragmentUrl,\r\n            uniforms: ThinFSR1UpscalePostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean | undefined, list: Promise<any>[]): void {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/fsr1Upscale.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/fsr1Upscale.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the required constant values on the effect. Plain uniforms are used (rather than a uniform\r\n     * buffer) so this works on every backend, including Babylon Native, which disables uniform buffers.\r\n     * @param effect The effect to set the constants on (typically the one provided by onApplyObservable).\r\n     * @param viewportWidth The rendered input width being upscaled\r\n     * @param viewportHeight The rendered input height being upscaled\r\n     * @param inputWidth The width of the texture containing the input viewport\r\n     * @param inputHeight The height of the texture containing the input viewport\r\n     * @param outputWidth The display width which the input image gets upscaled to\r\n     * @param outputHeight The display height which the input image gets upscaled to\r\n     */\r\n    public updateConstants(\r\n        effect: Effect,\r\n        viewportWidth: number,\r\n        viewportHeight: number,\r\n        inputWidth: number,\r\n        inputHeight: number,\r\n        outputWidth: number,\r\n        outputHeight: number\r\n    ): void {\r\n        // Code based on FsrEasuCon from FSR 1:\r\n        // https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/a21ffb8f6c13233ba336352bdff293894c706575/ffx-fsr/ffx_fsr1.h#L156\r\n        const rcpInputWidth = 1 / inputWidth;\r\n        const rcpInputHeight = 1 / inputHeight;\r\n        const rcpOutputWidth = 1 / outputWidth;\r\n        const rcpOutputHeight = 1 / outputHeight;\r\n\r\n        // Upstream FSR packs these as uints and bitcasts them in the shader; this port declares\r\n        // them as floats on both the GLSL and WGSL sides, so they are sent as floats.\r\n        effect.setFloat4(\r\n            \"con0\",\r\n            viewportWidth * rcpOutputWidth,\r\n            viewportHeight * rcpOutputHeight,\r\n            0.5 * viewportWidth * rcpOutputWidth - 0.5,\r\n            0.5 * viewportHeight * rcpOutputHeight - 0.5\r\n        );\r\n        effect.setFloat4(\"con1\", rcpInputWidth, rcpInputHeight, 1 * rcpInputWidth, -1 * rcpInputHeight);\r\n        effect.setFloat4(\"con2\", -1 * rcpInputWidth, 2 * rcpInputHeight, 1 * rcpInputWidth, 2 * rcpInputHeight);\r\n        effect.setFloat4(\"con3\", 0 * rcpInputWidth, 4 * rcpInputHeight, 0, 0);\r\n    }\r\n}\r\n","import { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type Effect } from \"core/Materials/effect\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\nimport { EffectWrapper, type EffectWrapperCreationOptions } from \"core/Materials/effectRenderer.pure\";\r\nimport { type Nullable } from \"core/types\";\r\n\r\n/**\r\n * Robust Contrast Adaptive Sharpening (RCAS) post-process used by FSR 1\r\n */\r\nexport class ThinFSR1SharpenPostProcess extends EffectWrapper {\r\n    /**\r\n     * The fragment shader URL\r\n     */\r\n    public static readonly FragmentUrl = \"fsr1Sharpen\";\r\n\r\n    /**\r\n     * The list of uniforms used by the effect\r\n     */\r\n    public static readonly Uniforms = [\"con\"];\r\n\r\n    /**\r\n     * Creates a new FSR 1 sharpen post process\r\n     * @param name Name of the effect\r\n     * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n     * @param options Options to configure the effect\r\n     */\r\n    constructor(name: string, engine?: Nullable<AbstractEngine>, options?: EffectWrapperCreationOptions) {\r\n        engine ??= EngineStore.LastCreatedEngine!;\r\n        super({\r\n            ...options,\r\n            name,\r\n            engine,\r\n            useShaderStore: true,\r\n            useAsPostProcess: true,\r\n            fragmentShader: ThinFSR1SharpenPostProcess.FragmentUrl,\r\n            uniforms: ThinFSR1SharpenPostProcess.Uniforms,\r\n        });\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean | undefined, list: Promise<any>[]): void {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(import(\"../ShadersWGSL/fsr1Sharpen.fragment\"));\r\n        } else {\r\n            list.push(import(\"../Shaders/fsr1Sharpen.fragment\"));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets the required constant value on the effect. Plain uniforms are used (rather than a uniform\r\n     * buffer) so this works on every backend, including Babylon Native, which disables uniform buffers.\r\n     * @param effect The effect to set the constant on (typically the one provided by onApplyObservable).\r\n     * @param sharpness The number of stops (halving) of the reduction of sharpness (0 = maximum sharpness)\r\n     */\r\n    public updateConstants(effect: Effect, sharpness: number): void {\r\n        // Code based on FsrRcasCon from FSR 1:\r\n        // https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/a21ffb8f6c13233ba336352bdff293894c706575/ffx-fsr/ffx_fsr1.h#L662\r\n        sharpness = Math.pow(2, -sharpness);\r\n\r\n        // Upstream FSR packs this as a uint and bitcasts it in the shader; this port declares it\r\n        // as a float on both the GLSL and WGSL sides, so it is sent as one.\r\n        // Since we haven't added the half-float shader yet, we don't need the second constant, which would require JS half-float calculation\r\n        effect.setFloat4(\"con\", sharpness, 0, 0, 0);\r\n    }\r\n}\r\n","import { type Scene } from \"core/scene\";\nimport { type Nullable } from \"core/types\";\n\nimport { PostProcessRenderEffect } from \"../postProcessRenderEffect\";\nimport { PostProcessRenderPipeline } from \"../postProcessRenderPipeline\";\nimport { PostProcess } from \"../../postProcess.pure\";\nimport { ThinFSR1UpscalePostProcess } from \"../../thinFSR1UpscalePostProcess\";\nimport { ThinFSR1SharpenPostProcess } from \"../../thinFSR1SharpenPostProcess\";\n\n/**\n * FidelityFX Super Resolution (FSR) 1 render pipeline.\n * This can be used to render the scene at a lower resolution and upscale it.\n */\nexport class FSR1RenderingPipeline extends PostProcessRenderPipeline {\n    /**\n     * AMD's recommended `scaleFactor` for an \"Ultra Quality\" preset (equal to 1.3)\n     */\n    public static readonly SCALE_ULTRA_QUALITY = 1.3;\n    /**\n     * AMD's recommended `scaleFactor` for a \"Quality\" preset (equal to 1.5)\n     */\n    public static readonly SCALE_QUALITY = 1.5;\n    /**\n     * AMD's recommended `scaleFactor` for a \"Balanced\" preset (equal to 1.7)\n     */\n    public static readonly SCALE_BALANCED = 1.7;\n    /**\n     * AMD's recommended `scaleFactor` for a \"Performance\" preset (equal to 2)\n     */\n    public static readonly SCALE_PERFORMANCE = 2;\n\n    private readonly _scene: Scene;\n\n    /**\n     * Returns true if FSR is supported by the running hardware\n     */\n    public override get isSupported(): boolean {\n        // FSR 1 needs integer texel fetch (texelFetch/textureSize) and bit-cast intrinsics.\n        // These are available on WebGPU, WebGL2 and Babylon Native (all report version >= 2 or isWebGPU),\n        // but not WebGL1. Note caps.texelFetch cannot be used here because Babylon Native reports it as\n        // false even though the underlying backend supports the required operations.\n        return this.engine.isWebGPU || this.engine.version >= 2;\n    }\n\n    private _samples = 4;\n    /**\n     * MSAA sample count (default: 4).\n     * Disabling MSAA is not recommended since aliased edges will be exaggerated by the FSR pass.\n     * Always have at least one AA solution enabled, whether that be MSAA with this setting or a post-process effect like FXAA or TAA.\n     */\n    public get samples(): number {\n        return this._samples;\n    }\n\n    public set samples(samples: number) {\n        if (this._samples === samples) {\n            return;\n        }\n        this._samples = samples;\n        if (this._upscalePostProcess) {\n            this._upscalePostProcess.samples = this._samples;\n        }\n    }\n\n    private _scaleFactor = FSR1RenderingPipeline.SCALE_QUALITY;\n    /**\n     * How much smaller to render the scene at (default: 1.5).\n     * For example, a value of 2 will render the scene at half resolution.\n     */\n    public get scaleFactor(): number {\n        return this._scaleFactor;\n    }\n\n    public set scaleFactor(factor: number) {\n        if (this._scaleFactor === factor) {\n            return;\n        }\n        this._scaleFactor = factor;\n        this._buildPipeline();\n    }\n\n    private _sharpnessStops = 0.2;\n    /**\n     * The number of stops (halving) of the reduction of sharpness (default: 0.2).\n     * A value of 0 indicates a maximum sharpness.\n     */\n    public get sharpnessStops(): number {\n        return this._sharpnessStops;\n    }\n\n    public set sharpnessStops(stops: number) {\n        if (this._sharpnessStops === stops) {\n            return;\n        }\n        this._sharpnessStops = stops;\n        // The value is applied to the effect every frame in the sharpen post-process onApply callback.\n    }\n\n    /**\n     * The FSR upscale PostProcess ID in the pipeline\n     */\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    public FSR1UpscaleEffect = \"FSR1UpscaleEffect\";\n    private readonly _thinUpscalePostProcess: ThinFSR1UpscalePostProcess;\n    private _upscalePostProcess: Nullable<PostProcess>;\n\n    /**\n     * The FSR sharpen PostProcess ID in the pipeline\n     */\n    // eslint-disable-next-line @typescript-eslint/naming-convention\n    public FSR1SharpenEffect = \"FSR1SharpenEffect\";\n    private readonly _thinSharpenPostProcess: ThinFSR1SharpenPostProcess;\n    private _sharpenPostProcess: PostProcess;\n\n    /**\n     * Creates a new FSR 1 rendering pipeline\n     * @param name The rendering pipeline name\n     * @param scene The scene linked to this pipeline\n     * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras)\n     */\n    constructor(name: string, scene: Scene, cameras = scene.cameras) {\n        super(scene.getEngine(), name);\n        this._scene = scene;\n        this._cameras = cameras.slice();\n\n        this._thinUpscalePostProcess = new ThinFSR1UpscalePostProcess(name + \"Upscale\", this.engine);\n        this._thinSharpenPostProcess = new ThinFSR1SharpenPostProcess(name + \"Sharpen\", this.engine);\n        this._createSharpenPostProcess();\n\n        if (this.isSupported) {\n            scene.postProcessRenderPipelineManager.addPipeline(this);\n            this._buildPipeline();\n        }\n    }\n\n    private _buildPipeline(): void {\n        if (!this.isSupported) {\n            return;\n        }\n        const cameras = this._cameras.slice();\n        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, cameras);\n        this._reset();\n\n        this._disposeUpscalePostProcess();\n        this._createUpscalePostProcess();\n\n        this.addEffect(new PostProcessRenderEffect(this.engine, this.FSR1UpscaleEffect, () => this._upscalePostProcess));\n        this.addEffect(new PostProcessRenderEffect(this.engine, this.FSR1SharpenEffect, () => this._sharpenPostProcess));\n\n        this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this.name, cameras);\n    }\n\n    /**\n     * Disposes of the pipeline\n     */\n    public override dispose(): void {\n        this._disposeSharpenPostProcess();\n        this._thinSharpenPostProcess.dispose();\n        this._disposeUpscalePostProcess();\n        this._thinUpscalePostProcess.dispose();\n        super.dispose();\n    }\n\n    private _createUpscalePostProcess(): void {\n        const postProcess = new PostProcess(this._thinUpscalePostProcess.name, ThinFSR1UpscalePostProcess.FragmentUrl, {\n            uniforms: ThinFSR1UpscalePostProcess.Uniforms,\n            size: 1 / this._scaleFactor,\n            engine: this.engine,\n            effectWrapper: this._thinUpscalePostProcess,\n        });\n        postProcess.samples = this._samples;\n\n        postProcess.onApplyObservable.add((effect) => {\n            this._thinUpscalePostProcess.updateConstants(\n                effect,\n                postProcess.width,\n                postProcess.height,\n                postProcess.width,\n                postProcess.height,\n                this.engine.getRenderWidth(),\n                this.engine.getRenderHeight()\n            );\n        });\n\n        this._upscalePostProcess = postProcess;\n    }\n\n    private _disposeUpscalePostProcess(): void {\n        for (const camera of this._cameras) {\n            this._upscalePostProcess?.dispose(camera);\n        }\n        this._upscalePostProcess = null;\n    }\n\n    private _createSharpenPostProcess(): void {\n        this._sharpenPostProcess = new PostProcess(this._thinSharpenPostProcess.name, ThinFSR1SharpenPostProcess.FragmentUrl, {\n            uniforms: ThinFSR1SharpenPostProcess.Uniforms,\n            engine: this.engine,\n            effectWrapper: this._thinSharpenPostProcess,\n        });\n        this._sharpenPostProcess.onApplyObservable.add((effect) => {\n            this._thinSharpenPostProcess.updateConstants(effect, this._sharpnessStops);\n        });\n    }\n\n    private _disposeSharpenPostProcess(): void {\n        for (const camera of this._cameras) {\n            this._sharpenPostProcess.dispose(camera);\n        }\n    }\n}\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"ssao2PixelShader\";\nconst shader = `precision highp float;uniform sampler2D textureSampler;varying vec2 vUV;\n#ifdef SSAO\nfloat scales[16]=float[16](\n0.1,\n0.11406250000000001,\n0.131640625,\n0.15625,\n0.187890625,\n0.2265625,\n0.272265625,\n0.325,\n0.384765625,\n0.4515625,\n0.525390625,\n0.60625,\n0.694140625,\n0.7890625,\n0.891015625,\n1.0\n);uniform float near;uniform float radius;uniform sampler2D depthSampler;uniform sampler2D randomSampler;uniform sampler2D normalSampler;uniform float randTextureTiles;uniform float samplesFactor;uniform vec3 sampleSphere[SAMPLES];uniform float totalStrength;uniform float base;\n#ifdef ORTHOGRAPHIC_CAMERA\nuniform vec4 viewport;\n#else\nuniform float xViewport;uniform float yViewport;\n#endif\nuniform mat3 depthProjection;uniform float maxZ;uniform float minZAspect;uniform vec2 texelSize;uniform mat4 projection;\n#ifdef NORMAL_WORLDSPACE\nuniform mat3 normalWorldToView;\n#endif\nvoid main()\n{vec3 random=textureLod(randomSampler,vUV*randTextureTiles,0.0).rgb;float depth=textureLod(depthSampler,vUV,0.0).r;float depthSign=sign(depth);depth=depth*depthSign;vec3 normal=normalize(textureLod(normalSampler,vUV,0.0).rgb);\n#ifdef NORMAL_WORLDSPACE\nnormal=normalize(normalWorldToView*normal);\n#endif\nfloat occlusion=0.0;float correctedRadius=min(radius,minZAspect*depth/near);\n#ifdef ORTHOGRAPHIC_CAMERA\nvec3 vViewRay=vec3(mix(viewport.x,viewport.y,vUV.x),mix(viewport.z,viewport.w,vUV.y),depthSign);\n#else\nvec3 vViewRay=vec3((vUV.x*2.0-1.0)*xViewport,(vUV.y*2.0-1.0)*yViewport,depthSign);\n#endif\nvec3 vDepthFactor=depthProjection*vec3(1.0,1.0,depth);vec3 origin=vViewRay*vDepthFactor;vec3 rvec=random*2.0-1.0;rvec.z=0.0;float dotProduct=dot(rvec,normal);rvec=1.0-abs(dotProduct)>1e-2 ? rvec : vec3(-rvec.y,0.0,rvec.x);vec3 tangent=normalize(rvec-normal*dot(rvec,normal));vec3 bitangent=cross(normal,tangent);mat3 tbn=mat3(tangent,bitangent,normal);float difference;for (int i=0; i<SAMPLES; ++i) {vec3 samplePosition=scales[(i+int(random.x*16.0)) % 16]*tbn*sampleSphere[(i+int(random.y*16.0)) % 16];samplePosition=samplePosition*correctedRadius+origin;vec4 offset=vec4(samplePosition,1.0);offset=projection*offset;offset.xyz/=offset.w;offset.xy=offset.xy*0.5+0.5;if (offset.x<0.0 || offset.y<0.0 || offset.x>1.0 || offset.y>1.0) {continue;}\nfloat sampleDepth=abs(textureLod(depthSampler,offset.xy,0.0).r);difference=depthSign*samplePosition.z-sampleDepth;float rangeCheck=1.0-smoothstep(correctedRadius*0.5,correctedRadius,difference);occlusion+=step(EPSILON,difference)*rangeCheck;}\nocclusion=occlusion*(1.0-smoothstep(maxZ*0.75,maxZ,depth));float ao=1.0-totalStrength*occlusion*samplesFactor;float result=clamp(ao+base,0.0,1.0);gl_FragColor=vec4(vec3(result),1.0);}\n#endif\n#ifdef BLUR\nuniform float outSize;uniform float soften;uniform float tolerance;uniform int samples;\n#ifndef BLUR_BYPASS\nuniform sampler2D depthSampler;\n#ifdef BLUR_LEGACY\n#define inline\nfloat blur13Bilateral(sampler2D image,vec2 uv,vec2 step) {float result=0.0;vec2 off1=vec2(1.411764705882353)*step;vec2 off2=vec2(3.2941176470588234)*step;vec2 off3=vec2(5.176470588235294)*step;float compareDepth=abs(textureLod(depthSampler,uv,0.0).r);float sampleDepth;float weight;float weightSum=30.0;result+=textureLod(image,uv,0.0).r*30.0;sampleDepth=abs(textureLod(depthSampler,uv+off1,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+= weight;result+=textureLod(image,uv+off1,0.0).r*weight;sampleDepth=abs(textureLod(depthSampler,uv-off1,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+= weight;result+=textureLod(image,uv-off1,0.0).r*weight;sampleDepth=abs(textureLod(depthSampler,uv+off2,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureLod(image,uv+off2,0.0).r*weight;sampleDepth=abs(textureLod(depthSampler,uv-off2,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureLod(image,uv-off2,0.0).r*weight;sampleDepth=abs(textureLod(depthSampler,uv+off3,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureLod(image,uv+off3,0.0).r*weight;sampleDepth=abs(textureLod(depthSampler,uv-off3,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureLod(image,uv-off3,0.0).r*weight;return result/weightSum;}\n#endif\n#endif\nvoid main()\n{float result=0.0;\n#ifdef BLUR_BYPASS\nresult=textureLod(textureSampler,vUV,0.0).r;\n#else\n#ifdef BLUR_H\nvec2 step=vec2(1.0/outSize,0.0);\n#else\nvec2 step=vec2(0.0,1.0/outSize);\n#endif\n#ifdef BLUR_LEGACY\nresult=blur13Bilateral(textureSampler,vUV,step);\n#else\nfloat compareDepth=abs(textureLod(depthSampler,vUV,0.0).r);float weightSum=0.0;for (int i=-samples; i<samples; i+=2)\n{vec2 samplePos=vUV+step*(float(i)+0.5);float sampleDepth=abs(textureLod(depthSampler,samplePos,0.0).r);float falloff=smoothstep(0.0,\nfloat(samples),\nfloat(samples)-abs(float(i))*soften);float minDivider=tolerance*0.5+0.003;float weight=falloff/( minDivider+abs(compareDepth-sampleDepth));result+=textureLod(textureSampler,samplePos,0.0).r*weight;weightSum+=weight;}\nresult/=weightSum;\n#endif\n#endif\ngl_FragColor.rgb=vec3(result);gl_FragColor.a=1.0;}\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const ssao2PixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"ssao2PixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#ifdef SSAO\nconst scales: array<f32,16>=array<f32,16>(\n0.1,\n0.11406250000000001,\n0.131640625,\n0.15625,\n0.187890625,\n0.2265625,\n0.272265625,\n0.325,\n0.384765625,\n0.4515625,\n0.525390625,\n0.60625,\n0.694140625,\n0.7890625,\n0.891015625,\n1.0\n);uniform near: f32;uniform radius: f32;var depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;var randomSamplerSampler: sampler;var randomSampler: texture_2d<f32>;var normalSamplerSampler: sampler;var normalSampler: texture_2d<f32>;uniform randTextureTiles: f32;uniform samplesFactor: f32;uniform sampleSphere: array<vec3f,SAMPLES>;uniform totalStrength: f32;uniform base: f32;\n#ifdef ORTHOGRAPHIC_CAMERA\nuniform viewport: vec4f;\n#else\nuniform xViewport: f32;uniform yViewport: f32;\n#endif\nuniform depthProjection: mat3x3f;uniform maxZ: f32;uniform minZAspect: f32;uniform texelSize: vec2f;uniform projection: mat4x4f;\n#ifdef NORMAL_WORLDSPACE\nuniform normalWorldToView: mat3x3f;\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var random: vec3f=textureSampleLevel(randomSampler,randomSamplerSampler,input.vUV*uniforms.randTextureTiles,0.0).rgb;var depth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV,0.0).r;var depthSign: f32=sign(depth);depth=depth*depthSign;var normal: vec3f=normalize(textureSampleLevel(normalSampler,normalSamplerSampler,input.vUV,0.0).rgb);\n#ifdef NORMAL_WORLDSPACE\nnormal=normalize(uniforms.normalWorldToView*normal);\n#endif\nvar occlusion: f32=0.0;var correctedRadius: f32=min(uniforms.radius,uniforms.minZAspect*depth/uniforms.near);\n#ifdef ORTHOGRAPHIC_CAMERA\nvar vViewRay: vec3f= vec3f(mix(uniforms.viewport.x,uniforms.viewport.y,input.vUV.x),mix(uniforms.viewport.z,uniforms.viewport.w,input.vUV.y),depthSign);\n#else\nvar vViewRay: vec3f= vec3f((input.vUV.x*2.0-1.0)*uniforms.xViewport,(input.vUV.y*2.0-1.0)*uniforms.yViewport,depthSign);\n#endif\nvar vDepthFactor: vec3f=uniforms.depthProjection* vec3f(1.0,1.0,depth);var origin: vec3f=vViewRay*vDepthFactor;var rvec: vec3f=random*2.0-1.0;rvec.z=0.0;var dotProduct: f32=dot(rvec,normal);rvec=select( vec3f(-rvec.y,0.0,rvec.x),rvec,1.0-abs(dotProduct)>1e-2);var tangent: vec3f=normalize(rvec-normal*dot(rvec,normal));var bitangent: vec3f=cross(normal,tangent);var tbn: mat3x3f= mat3x3f(tangent,bitangent,normal);var difference: f32;for (var i: i32=0; i<SAMPLES; i++) {var samplePosition: vec3f=scales[(i+ i32(random.x*16.0)) % 16]*tbn*uniforms.sampleSphere[(i+ i32(random.y*16.0)) % 16];samplePosition=samplePosition*correctedRadius+origin;var offset: vec4f= vec4f(samplePosition,1.0);offset=uniforms.projection*offset;offset=vec4f(offset.xyz/offset.w,offset.w);offset=vec4f(offset.xy*0.5+0.5,offset.z,offset.w);if (offset.x<0.0 || offset.y<0.0 || offset.x>1.0 || offset.y>1.0) {continue;}\nvar sampleDepth: f32=abs(textureSampleLevel(depthSampler,depthSamplerSampler,offset.xy,0.0).r);difference=depthSign*samplePosition.z-sampleDepth;var rangeCheck: f32=1.0-smoothstep(correctedRadius*0.5,correctedRadius,difference);occlusion+=step(EPSILON,difference)*rangeCheck;}\nocclusion=occlusion*(1.0-smoothstep(uniforms.maxZ*0.75,uniforms.maxZ,depth));var ao: f32=1.0-uniforms.totalStrength*occlusion*uniforms.samplesFactor;var result: f32=clamp(ao+uniforms.base,0.0,1.0);fragmentOutputs.color= vec4f( vec3f(result),1.0);}\n#else\n#ifdef BLUR\nuniform outSize: f32;uniform soften: f32;uniform tolerance: f32;uniform samples: i32;\n#ifndef BLUR_BYPASS\nvar depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;\n#ifdef BLUR_LEGACY\nfn blur13Bilateral(image: texture_2d<f32>,imageSampler: sampler,uv: vec2f,step: vec2f)->f32 {var result: f32=0.0;var off1: vec2f= vec2f(1.411764705882353)*step;var off2: vec2f= vec2f(3.2941176470588234)*step;var off3: vec2f= vec2f(5.176470588235294)*step;var compareDepth: f32=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv,0.0).r);var sampleDepth: f32;var weight: f32;var weightSum: f32=30.0;result+=textureSampleLevel(image,imageSampler,uv,0.0).r*30.0;sampleDepth=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv+off1,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+= weight;result+=textureSampleLevel(image,imageSampler,uv+off1,0.0).r*weight;sampleDepth=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv-off1,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+= weight;result+=textureSampleLevel(image,imageSampler,uv-off1,0.0).r*weight;sampleDepth=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv+off2,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureSampleLevel(image,imageSampler,uv+off2,0.0).r*weight;sampleDepth=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv-off2,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureSampleLevel(image,imageSampler,uv-off2,0.0).r*weight;sampleDepth=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv+off3,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureSampleLevel(image,imageSampler,uv+off3,0.0).r*weight;sampleDepth=abs(textureSampleLevel(depthSampler,depthSamplerSampler,uv-off3,0.0).r);weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);weightSum+=weight;result+=textureSampleLevel(image,imageSampler,uv-off3,0.0).r*weight;return result/weightSum;}\n#endif\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var result: f32=0.0;\n#ifdef BLUR_BYPASS\nresult=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0).r;\n#else\n#ifdef BLUR_H\nvar step: vec2f= vec2f(1.0/uniforms.outSize,0.0);\n#else\nvar step: vec2f= vec2f(0.0,1.0/uniforms.outSize);\n#endif\n#ifdef BLUR_LEGACY\nresult=blur13Bilateral(textureSampler,textureSamplerSampler,input.vUV,step);\n#else\nvar compareDepth: f32=abs(textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV,0.0).r);var weightSum: f32=0.0;for (var i: i32=-uniforms.samples; i<uniforms.samples; i+=2)\n{var samplePos: vec2f=input.vUV+step*( f32(i)+0.5);var sampleDepth: f32=abs(textureSampleLevel(depthSampler,depthSamplerSampler,samplePos,0.0).r);var falloff: f32=smoothstep(0.0,\nf32(uniforms.samples),\nf32(uniforms.samples)-abs( f32(i))*uniforms.soften);var minDivider: f32=uniforms.tolerance*0.5+0.003;var weight: f32=falloff/( minDivider+abs(compareDepth-sampleDepth));result+=textureSampleLevel(textureSampler,textureSamplerSampler,samplePos,0.0).r*weight;weightSum+=weight;}\nresult/=weightSum;\n#endif\n#endif\nfragmentOutputs.color=vec4f(result,result,result,1.0);}\n#endif\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const ssao2PixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"ssaoCombinePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var originalColorSampler: sampler;var originalColor: texture_2d<f32>;uniform viewport: vec4f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvar uv: vec2f=uniforms.viewport.xy+input.vUV*uniforms.viewport.zw;var ssaoColor: vec4f=textureSample(textureSampler,textureSamplerSampler,uv);var sceneColor: vec4f=textureSample(originalColor,originalColorSampler,uv);fragmentOutputs.color=sceneColor*ssaoColor;\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const ssaoCombinePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"screenSpaceRayTrace\";\nconst shader = `float distanceSquared(vec2 a,vec2 b) { a-=b; return dot(a,a); }\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nfloat linearizeDepth(float depth,float near,float far) {\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nreturn -(near*far)/(far-depth*(far-near));\n#else\nreturn (near*far)/(far-depth*(far-near));\n#endif\n}\n#endif\n/**\n\\param csOrigin Camera-space ray origin,which must be \nwithin the view volume and must have z>0.01 and project within the valid screen rectangle\n\\param csDirection Unit length camera-space ray direction\n\\param projectToPixelMatrix A projection matrix that maps to **pixel** coordinates \n(**not** [-1,+1] normalized device coordinates).\n\\param csZBuffer The camera-space Z buffer\n\\param csZBufferSize Dimensions of csZBuffer\n\\param csZThickness Camera space csZThickness to ascribe to each pixel in the depth buffer\n\\param nearPlaneZ Positive number. Doesn't have to be THE actual near plane,just a reasonable value\nfor clipping rays headed towards the camera\n\\param stride Step in horizontal or vertical pixels between samples. This is a float\nbecause integer math is slow on GPUs,but should be set to an integer>=1\n\\param jitterFraction Number between 0 and 1 for how far to bump the ray in stride units\nto conceal banding artifacts,plus the stride ray offset.\n\\param maxSteps Maximum number of iterations. Higher gives better images but may be slow\n\\param maxRayTraceDistance Maximum camera-space distance to trace before returning a miss\n\\param selfCollisionNumSkip Number of steps to skip at start when raytracing to avoid self collisions.\n1 is a reasonable value,depending on the scene you may need to set this value to 2\n\\param hitPixel Pixel coordinates of the first intersection with the scene\n\\param numIterations number of iterations performed\n\\param csHitPoint Camera space location of the ray hit\n*/\n#define inline\nbool traceScreenSpaceRay1(\nvec3 csOrigin,\nvec3 csDirection,\nmat4 projectToPixelMatrix,\nsampler2D csZBuffer,\nvec2 csZBufferSize,\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nsampler2D csZBackBuffer,\nfloat csZBackSizeFactor,\n#endif\nfloat csZThickness,\nfloat nearPlaneZ,\nfloat farPlaneZ,\nfloat stride,\nfloat jitterFraction,\nfloat maxSteps,\nfloat maxRayTraceDistance,\nfloat selfCollisionNumSkip,\nout vec2 startPixel,\nout vec2 hitPixel,\nout vec3 csHitPoint,\nout float numIterations\n#ifdef SSRAYTRACE_DEBUG\n,out vec3 debugColor\n#endif\n)\n{\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nfloat rayLength=(csOrigin.z+csDirection.z*maxRayTraceDistance)>-nearPlaneZ ? (-nearPlaneZ-csOrigin.z)/csDirection.z : maxRayTraceDistance;\n#else\nfloat rayLength=(csOrigin.z+csDirection.z*maxRayTraceDistance)<nearPlaneZ ? (nearPlaneZ-csOrigin.z)/csDirection.z : maxRayTraceDistance;\n#endif\nvec3 csEndPoint=csOrigin+csDirection*rayLength;hitPixel=vec2(-1.0,-1.0);vec4 H0=projectToPixelMatrix*vec4(csOrigin,1.0);vec4 H1=projectToPixelMatrix*vec4(csEndPoint,1.0);float k0=1.0/H0.w;float k1=1.0/H1.w;vec3 Q0=csOrigin*k0;vec3 Q1=csEndPoint*k1;vec2 P0=H0.xy*k0;vec2 P1=H1.xy*k1;\n#ifdef SSRAYTRACE_CLIP_TO_FRUSTUM\nfloat xMax=csZBufferSize.x-0.5,xMin=0.5,yMax=csZBufferSize.y-0.5,yMin=0.5;float alpha=0.0;if ((P1.y>yMax) || (P1.y<yMin)) {alpha=(P1.y-((P1.y>yMax) ? yMax : yMin))/(P1.y-P0.y);}\nif ((P1.x>xMax) || (P1.x<xMin)) {alpha=max(alpha,(P1.x-((P1.x>xMax) ? xMax : xMin))/(P1.x-P0.x));}\nP1=mix(P1,P0,alpha); k1=mix(k1,k0,alpha); Q1=mix(Q1,Q0,alpha);\n#endif\nP1+=vec2((distanceSquared(P0,P1)<0.0001) ? 0.01 : 0.0);vec2 delta=P1-P0;bool permute=false;if (abs(delta.x)<abs(delta.y)) { \npermute=true;delta=delta.yx;P0=P0.yx;P1=P1.yx; }\nfloat stepDirection=sign(delta.x);float invdx=stepDirection/delta.x;vec2 dP=vec2(stepDirection,delta.y*invdx);vec3 dQ=(Q1-Q0)*invdx;float dk=(k1-k0)*invdx;float zMin=min(csEndPoint.z,csOrigin.z);float zMax=max(csEndPoint.z,csOrigin.z);dP*=stride; dQ*=stride; dk*=stride;P0+=dP*jitterFraction; Q0+=dQ*jitterFraction; k0+=dk*jitterFraction;vec4 pqk=vec4(P0,Q0.z,k0);vec4 dPQK=vec4(dP,dQ.z,dk);startPixel=permute ? P0.yx : P0.xy;float prevZMaxEstimate=csOrigin.z;float rayZMin=prevZMaxEstimate,rayZMax=prevZMaxEstimate;float sceneZMax=rayZMax+1e4;float end=P1.x*stepDirection;bool hit=false;float stepCount;for (stepCount=0.0;stepCount<=selfCollisionNumSkip ||\n(pqk.x*stepDirection)<=end &&\nstepCount<maxSteps &&\n!hit; \npqk+=dPQK,++stepCount)\n{hitPixel=permute ? pqk.yx : pqk.xy;\n#ifndef SSRAYTRACE_CLIP_TO_FRUSTUM\nif (hitPixel.x<0.0 || hitPixel.x>=csZBufferSize.x ||\nhitPixel.y<0.0 || hitPixel.y>=csZBufferSize.y) break;\n#endif\nrayZMin=prevZMaxEstimate;rayZMax=(dPQK.z*0.5+pqk.z)/(dPQK.w*0.5+pqk.w);rayZMax=clamp(rayZMax,zMin,zMax);prevZMaxEstimate=rayZMax;\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nif (prevZMaxEstimate<-farPlaneZ) break;\n#else\nif (prevZMaxEstimate>farPlaneZ) break;\n#endif\nif (rayZMin>rayZMax) { \nfloat t=rayZMin; rayZMin=rayZMax; rayZMax=t;}\nsceneZMax=texelFetch(csZBuffer,ivec2(hitPixel),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneZMax=linearizeDepth(sceneZMax,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneZMax==0.0) sceneZMax=1e8;\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nfloat sceneBackZ=texelFetch(csZBackBuffer,ivec2(hitPixel/csZBackSizeFactor),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneBackZ=linearizeDepth(sceneBackZ,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneBackZ==0.0) sceneBackZ=-1e8;hit=(rayZMax>=sceneBackZ-csZThickness) && (rayZMin<=sceneZMax);\n#else\nhit=(rayZMax>=sceneZMax-csZThickness) && (rayZMin<=sceneZMax);\n#endif\n#else\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nfloat sceneBackZ=texelFetch(csZBackBuffer,ivec2(hitPixel/csZBackSizeFactor),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneBackZ=linearizeDepth(sceneBackZ,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneBackZ==0.0) sceneBackZ=1e8;hit=(rayZMin<=sceneBackZ+csZThickness) && (rayZMax>=sceneZMax);\n#else\nhit=(rayZMin<=sceneZMax+csZThickness) && (rayZMax>=sceneZMax);\n#endif\n#endif\n}\npqk-=dPQK;stepCount-=1.0;if (((pqk.x+dPQK.x)*stepDirection)>end || (stepCount+1.0)>=maxSteps) {hit=false;}\n#ifdef SSRAYTRACE_ENABLE_REFINEMENT\nif (stride>1.0 && hit) {pqk-=dPQK;stepCount-=1.0;float invStride=1.0/stride;dPQK*=invStride;float refinementStepCount=0.0;prevZMaxEstimate=pqk.z/pqk.w;rayZMax=prevZMaxEstimate;sceneZMax=rayZMax+1e7;for (;refinementStepCount<=1.0 ||\n(refinementStepCount<=stride*1.4) &&\n(rayZMax<sceneZMax);pqk+=dPQK,refinementStepCount+=1.0)\n{rayZMin=prevZMaxEstimate;rayZMax=(dPQK.z*0.5+pqk.z)/(dPQK.w*0.5+pqk.w);rayZMax=clamp(rayZMax,zMin,zMax);prevZMaxEstimate=rayZMax;rayZMax=max(rayZMax,rayZMin);hitPixel=permute ? pqk.yx : pqk.xy;sceneZMax=texelFetch(csZBuffer,ivec2(hitPixel),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneZMax=linearizeDepth(sceneZMax,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneZMax==0.0) sceneZMax=1e8;}\npqk-=dPQK;refinementStepCount-=1.0;stepCount+=refinementStepCount/stride;}\n#endif\nQ0.xy+=dQ.xy*stepCount;Q0.z=pqk.z;csHitPoint=Q0/pqk.w;numIterations=stepCount+1.0;\n#ifdef SSRAYTRACE_DEBUG\nif (((pqk.x+dPQK.x)*stepDirection)>end) {debugColor=vec3(0,0,1);} else if ((stepCount+1.0)>=maxSteps) {debugColor=vec3(1,0,0);} else if (!hit) {debugColor=vec3(1,1,0);} else {debugColor=vec3(0,stepCount/maxSteps,0);}\n#endif\nreturn hit;}\n/**\ntexCoord: in the [0,1] range\ndepth: depth in view space (range [znear,zfar]])\n*/\nvec3 computeViewPosFromUVDepth(vec2 texCoord,float depth,mat4 projection,mat4 invProjectionMatrix) {vec4 ndc;ndc.xy=texCoord*2.0-1.0;\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\n#ifdef ORTHOGRAPHIC_CAMERA\nndc.z=-projection[2].z*depth+projection[3].z;\n#else\nndc.z=-projection[2].z-projection[3].z/depth;\n#endif\n#else\n#ifdef ORTHOGRAPHIC_CAMERA\nndc.z=projection[2].z*depth+projection[3].z;\n#else\nndc.z=projection[2].z+projection[3].z/depth;\n#endif\n#endif\nndc.w=1.0;vec4 eyePos=invProjectionMatrix*ndc;eyePos.xyz/=eyePos.w;return eyePos.xyz;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const screenSpaceRayTrace = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { screenSpaceRayTrace } from \"./ShadersInclude/screenSpaceRayTrace\";\n\nconst name = \"screenSpaceReflection2PixelShader\";\nconst shader = `#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,lod) texture2DLodEXT(s,c,lod)\n#define TEXTURECUBEFUNC(s,c,lod) textureLod(s,c,lod)\n#else\n#define TEXTUREFUNC(s,c,bias) texture2D(s,c,bias)\n#define TEXTURECUBEFUNC(s,c,bias) textureCube(s,c,bias)\n#endif\nuniform sampler2D textureSampler;varying vec2 vUV;\n#ifdef SSR_SUPPORTED\nuniform sampler2D reflectivitySampler;uniform sampler2D normalSampler;uniform sampler2D depthSampler;\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nuniform sampler2D backDepthSampler;uniform float backSizeFactor;\n#endif\n#ifdef SSR_USE_ENVIRONMENT_CUBE\nuniform samplerCube envCubeSampler;\n#ifdef SSR_USE_LOCAL_REFLECTIONMAP_CUBIC\nuniform vec3 vReflectionPosition;uniform vec3 vReflectionSize;\n#endif\n#endif\nuniform mat4 view;uniform mat4 invView;uniform mat4 projection;uniform mat4 invProjectionMatrix;uniform mat4 projectionPixel;uniform float nearPlaneZ;uniform float farPlaneZ;uniform float stepSize;uniform float maxSteps;uniform float strength;uniform float thickness;uniform float roughnessFactor;uniform float reflectionSpecularFalloffExponent;uniform float maxDistance;uniform float selfCollisionNumSkip;uniform float reflectivityThreshold;\n#include<helperFunctions>\n#include<pbrBRDFFunctions>\n#include<screenSpaceRayTrace>\nvec3 hash(vec3 a)\n{a=fract(a*0.8);a+=dot(a,a.yxz+19.19);return fract((a.xxy+a.yxx)*a.zyx);}\nfloat computeAttenuationForIntersection(ivec2 hitPixel,vec2 hitUV,vec3 vsRayOrigin,vec3 vsHitPoint,vec3 reflectionVector,float maxRayDistance,float numIterations) {float attenuation=1.0;\n#ifdef SSR_ATTENUATE_SCREEN_BORDERS\nvec2 dCoords=smoothstep(0.2,0.6,abs(vec2(0.5,0.5)-hitUV.xy));attenuation*=clamp(1.0-(dCoords.x+dCoords.y),0.0,1.0);\n#endif\n#ifdef SSR_ATTENUATE_INTERSECTION_DISTANCE\nattenuation*=1.0-clamp(distance(vsRayOrigin,vsHitPoint)/maxRayDistance,0.0,1.0);\n#endif\n#ifdef SSR_ATTENUATE_INTERSECTION_NUMITERATIONS\nattenuation*=1.0-(numIterations/maxSteps);\n#endif\n#ifdef SSR_ATTENUATE_BACKFACE_REFLECTION\nvec3 reflectionNormal=texelFetch(normalSampler,hitPixel,0).xyz;float directionBasedAttenuation=smoothstep(-0.17,0.0,dot(reflectionNormal,-reflectionVector));attenuation*=directionBasedAttenuation;\n#endif\nreturn attenuation;}\n#endif\nvoid main()\n{\n#ifdef SSR_SUPPORTED\nvec4 colorFull=TEXTUREFUNC(textureSampler,vUV,0.0);vec3 color=colorFull.rgb;vec4 reflectivity=max(TEXTUREFUNC(reflectivitySampler,vUV,0.0),vec4(0.));\n#ifndef SSR_DISABLE_REFLECTIVITY_TEST\nif (max(reflectivity.r,max(reflectivity.g,reflectivity.b))<=reflectivityThreshold) {\n#ifdef SSR_USE_BLUR\ngl_FragColor=vec4(0.);\n#else\ngl_FragColor=colorFull;\n#endif\nreturn;}\n#endif\n#ifdef SSR_INPUT_IS_GAMMA_SPACE\ncolor=toLinearSpace(color);\n#endif\nvec2 texSize=vec2(textureSize(depthSampler,0));vec3 csNormal=texelFetch(normalSampler,ivec2(vUV*texSize),0).xyz; \n#ifdef SSR_DECODE_NORMAL\ncsNormal=csNormal*2.0-1.0;\n#endif\n#ifdef SSR_NORMAL_IS_IN_WORLDSPACE\ncsNormal=(view*vec4(csNormal,0.0)).xyz;\n#endif\nfloat depth=texelFetch(depthSampler,ivec2(vUV*texSize),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\ndepth=linearizeDepth(depth,nearPlaneZ,farPlaneZ);\n#endif\nvec3 csPosition=computeViewPosFromUVDepth(vUV,depth,projection,invProjectionMatrix);\n#ifdef ORTHOGRAPHIC_CAMERA\nvec3 csViewDirection=vec3(0.,0.,1.);\n#else\nvec3 csViewDirection=normalize(csPosition);\n#endif\nvec3 csReflectedVector=reflect(csViewDirection,csNormal);\n#ifdef SSR_USE_ENVIRONMENT_CUBE\nvec3 wReflectedVector=vec3(invView*vec4(csReflectedVector,0.0));\n#ifdef SSR_USE_LOCAL_REFLECTIONMAP_CUBIC\nvec4 worldPos=invView*vec4(csPosition,1.0);wReflectedVector=parallaxCorrectNormal(worldPos.xyz,normalize(wReflectedVector),vReflectionSize,vReflectionPosition);\n#endif\n#ifdef SSR_INVERTCUBICMAP\nwReflectedVector.y*=-1.0;\n#endif\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nwReflectedVector.z*=-1.0;\n#endif\nvec3 envColor=TEXTURECUBEFUNC(envCubeSampler,wReflectedVector,0.0).xyz;\n#ifdef SSR_ENVIRONMENT_CUBE_IS_GAMMASPACE\nenvColor=toLinearSpace(envColor);\n#endif\n#else\nvec3 envColor=color;\n#endif\nfloat reflectionAttenuation=1.0;bool rayHasHit=false;vec2 startPixel;vec2 hitPixel;vec3 hitPoint;float numIterations;\n#ifdef SSRAYTRACE_DEBUG\nvec3 debugColor;\n#endif\n#ifdef SSR_ATTENUATE_FACING_CAMERA\nreflectionAttenuation*=1.0-smoothstep(0.25,0.5,dot(-csViewDirection,csReflectedVector));\n#endif\nif (reflectionAttenuation>0.0) {\n#ifdef SSR_USE_BLUR\nvec3 jitt=vec3(0.);\n#else\nfloat roughness=1.0-reflectivity.a;vec3 jitt=mix(vec3(0.0),hash(csPosition)-vec3(0.5),roughness)*roughnessFactor; \n#endif\nvec2 uv2=vUV*texSize;float c=(uv2.x+uv2.y)*0.25;float jitter=mod(c,1.0); \nrayHasHit=traceScreenSpaceRay1(\ncsPosition,\nnormalize(csReflectedVector+jitt),\nprojectionPixel,\ndepthSampler,\ntexSize,\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nbackDepthSampler,\nbackSizeFactor,\n#endif\nthickness,\nnearPlaneZ,\nfarPlaneZ,\nstepSize,\njitter,\nmaxSteps,\nmaxDistance,\nselfCollisionNumSkip,\nstartPixel,\nhitPixel,\nhitPoint,\nnumIterations\n#ifdef SSRAYTRACE_DEBUG\n,debugColor\n#endif\n);}\n#ifdef SSRAYTRACE_DEBUG\ngl_FragColor=vec4(debugColor,1.);return;\n#endif\nvec3 F0=reflectivity.rgb;vec3 fresnel=fresnelSchlickGGX(max(dot(csNormal,-csViewDirection),0.0),F0,vec3(1.));vec3 SSR=envColor;if (rayHasHit) {vec3 reflectedColor=texelFetch(textureSampler,ivec2(hitPixel),0).rgb;\n#ifdef SSR_INPUT_IS_GAMMA_SPACE\nreflectedColor=toLinearSpace(reflectedColor);\n#endif\nreflectionAttenuation*=computeAttenuationForIntersection(ivec2(hitPixel),hitPixel/texSize,csPosition,hitPoint,csReflectedVector,maxDistance,numIterations);SSR=reflectedColor*reflectionAttenuation+(1.0-reflectionAttenuation)*envColor;}\n#ifndef SSR_BLEND_WITH_FRESNEL\nSSR*=fresnel;\n#endif\nSSR=clamp(SSR,vec3(0.0),vec3(1000.0)); \n#ifdef SSR_USE_BLUR\nfloat blur_radius=0.0;float roughness=1.0-reflectivity.a*(1.0-roughnessFactor);if (roughness>0.001) {float cone_angle=min(roughness,0.999)*3.14159265*0.5;float cone_len=distance(startPixel,hitPixel);float op_len=2.0*tan(cone_angle)*cone_len; \nfloat a=op_len;float h=cone_len;float a2=a*a;float fh2=4.0f*h*h;blur_radius=(a*(sqrt(a2+fh2)-a))/(4.0f*h);}\ngl_FragColor=vec4(SSR,blur_radius/255.0); \n#else\n#ifdef SSR_BLEND_WITH_FRESNEL\nvec3 reflectionMultiplier=clamp(pow(fresnel*strength,vec3(reflectionSpecularFalloffExponent)),0.0,1.0);\n#else\nvec3 reflectionMultiplier=clamp(pow(reflectivity.rgb*strength,vec3(reflectionSpecularFalloffExponent)),0.0,1.0);\n#endif\nvec3 colorMultiplier=1.0-reflectionMultiplier;vec3 finalColor=(color*colorMultiplier)+(SSR*reflectionMultiplier);\n#ifdef SSR_OUTPUT_IS_GAMMA_SPACE\nfinalColor=toGammaSpace(finalColor);\n#endif\ngl_FragColor=vec4(finalColor,colorFull.a);\n#endif\n#else\ngl_FragColor=TEXTUREFUNC(textureSampler,vUV,0.0);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, pbrBRDFFunctions, screenSpaceRayTrace];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const screenSpaceReflection2PixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"screenSpaceReflection2BlurPixelShader\";\nconst shader = `#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,lod) texture2DLodEXT(s,c,lod)\n#else\n#define TEXTUREFUNC(s,c,bias) texture2D(s,c,bias)\n#endif\nuniform sampler2D textureSampler;varying vec2 vUV;uniform vec2 texelOffsetScale;const float weights[8]=float[8] (0.071303,0.131514,0.189879,0.321392,0.452906, 0.584419,0.715932,0.847445);void processSample(vec2 uv,float i,vec2 stepSize,inout vec4 accumulator,inout float denominator)\n{vec2 offsetUV=stepSize*i+uv;float coefficient=weights[int(2.0-abs(i))];accumulator+=TEXTUREFUNC(textureSampler,offsetUV,0.0)*coefficient;denominator+=coefficient;}\nvoid main()\n{vec4 colorFull=TEXTUREFUNC(textureSampler,vUV,0.0);if (dot(colorFull,vec4(1.0))==0.0) {gl_FragColor=colorFull;return;}\nfloat blurRadius=colorFull.a*255.0; \nvec2 stepSize=texelOffsetScale.xy*blurRadius;vec4 accumulator=TEXTUREFUNC(textureSampler,vUV,0.0)*0.214607;float denominator=0.214607;processSample(vUV,1.0,stepSize,accumulator,denominator);processSample(vUV,1.0*0.2,stepSize,accumulator,denominator);processSample(vUV,1.0*0.4,stepSize,accumulator,denominator);processSample(vUV,1.0*0.6,stepSize,accumulator,denominator);processSample(vUV,1.0*0.8,stepSize,accumulator,denominator);processSample(vUV,1.0*1.2,stepSize,accumulator,denominator);processSample(vUV,1.0*1.4,stepSize,accumulator,denominator);processSample(vUV,1.0*1.6,stepSize,accumulator,denominator);processSample(vUV,1.0*1.8,stepSize,accumulator,denominator);processSample(vUV,1.0*2.0,stepSize,accumulator,denominator);processSample(vUV,-1.0,stepSize,accumulator,denominator);processSample(vUV,-1.0*0.2,stepSize,accumulator,denominator);processSample(vUV,-1.0*0.4,stepSize,accumulator,denominator);processSample(vUV,-1.0*0.6,stepSize,accumulator,denominator);processSample(vUV,-1.0*0.8,stepSize,accumulator,denominator);processSample(vUV,-1.0*1.2,stepSize,accumulator,denominator);processSample(vUV,-1.0*1.4,stepSize,accumulator,denominator);processSample(vUV,-1.0*1.6,stepSize,accumulator,denominator);processSample(vUV,-1.0*1.8,stepSize,accumulator,denominator);processSample(vUV,-1.0*2.0,stepSize,accumulator,denominator);gl_FragColor=vec4(accumulator.rgb/denominator,colorFull.a);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const screenSpaceReflection2BlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { screenSpaceRayTrace } from \"./ShadersInclude/screenSpaceRayTrace\";\n\nconst name = \"screenSpaceReflection2BlurCombinerPixelShader\";\nconst shader = `uniform sampler2D textureSampler; \nuniform sampler2D mainSampler;uniform sampler2D reflectivitySampler;uniform float strength;uniform float reflectionSpecularFalloffExponent;uniform float reflectivityThreshold;varying vec2 vUV;\n#include<helperFunctions>\n#ifdef SSR_BLEND_WITH_FRESNEL\n#include<pbrBRDFFunctions>\n#include<screenSpaceRayTrace>\nuniform mat4 projection;uniform mat4 invProjectionMatrix;\n#ifdef SSR_NORMAL_IS_IN_WORLDSPACE\nuniform mat4 view;\n#endif\nuniform sampler2D normalSampler;uniform sampler2D depthSampler;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nuniform float nearPlaneZ;uniform float farPlaneZ;\n#endif\n#endif\nvoid main()\n{\n#ifdef SSRAYTRACE_DEBUG\ngl_FragColor=texture2D(textureSampler,vUV);\n#else\nvec3 SSR=texture2D(textureSampler,vUV).rgb;vec4 color=texture2D(mainSampler,vUV);vec4 reflectivity=texture2D(reflectivitySampler,vUV);\n#ifndef SSR_DISABLE_REFLECTIVITY_TEST\nif (max(reflectivity.r,max(reflectivity.g,reflectivity.b))<=reflectivityThreshold) {gl_FragColor=color;return;}\n#endif\n#ifdef SSR_INPUT_IS_GAMMA_SPACE\ncolor=toLinearSpace(color);\n#endif\n#ifdef SSR_BLEND_WITH_FRESNEL\nvec2 texSize=vec2(textureSize(depthSampler,0));vec3 csNormal=texelFetch(normalSampler,ivec2(vUV*texSize),0).xyz;\n#ifdef SSR_DECODE_NORMAL\ncsNormal=csNormal*2.0-1.0;\n#endif\n#ifdef SSR_NORMAL_IS_IN_WORLDSPACE\ncsNormal=(view*vec4(csNormal,0.0)).xyz;\n#endif\nfloat depth=texelFetch(depthSampler,ivec2(vUV*texSize),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\ndepth=linearizeDepth(depth,nearPlaneZ,farPlaneZ);\n#endif\nvec3 csPosition=computeViewPosFromUVDepth(vUV,depth,projection,invProjectionMatrix);vec3 csViewDirection=normalize(csPosition);vec3 F0=reflectivity.rgb;vec3 fresnel=fresnelSchlickGGX(max(dot(csNormal,-csViewDirection),0.0),F0,vec3(1.));vec3 reflectionMultiplier=clamp(pow(fresnel*strength,vec3(reflectionSpecularFalloffExponent)),0.0,1.0);\n#else\nvec3 reflectionMultiplier=clamp(pow(reflectivity.rgb*strength,vec3(reflectionSpecularFalloffExponent)),0.0,1.0);\n#endif\nvec3 colorMultiplier=1.0-reflectionMultiplier;vec3 finalColor=(color.rgb*colorMultiplier)+(SSR*reflectionMultiplier);\n#ifdef SSR_OUTPUT_IS_GAMMA_SPACE\nfinalColor=toGammaSpace(finalColor);\n#endif\ngl_FragColor=vec4(finalColor,color.a);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, pbrBRDFFunctions, screenSpaceRayTrace];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const screenSpaceReflection2BlurCombinerPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"screenSpaceRayTrace\";\nconst shader = `fn distanceSquared(a: vec2f,b: vec2f)->f32 { \nvar temp=a-b; \nreturn dot(temp,temp); }\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nfn linearizeDepth(depth: f32,near: f32,far: f32)->f32 {\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nreturn -(near*far)/(far-depth*(far-near));\n#else\nreturn (near*far)/(far-depth*(far-near));\n#endif\n}\n#endif\n/**\n\\param csOrigin Camera-space ray origin,which must be \nwithin the view volume and must have z>0.01 and project within the valid screen rectangle\n\\param csDirection Unit length camera-space ray direction\n\\param projectToPixelMatrix A projection matrix that maps to **pixel** coordinates \n(**not** [-1,+1] normalized device coordinates).\n\\param csZBuffer The camera-space Z buffer\n\\param csZBufferSize Dimensions of csZBuffer\n\\param csZThickness Camera space csZThickness to ascribe to each pixel in the depth buffer\n\\param nearPlaneZ Positive number. Doesn't have to be THE actual near plane,just a reasonable value\nfor clipping rays headed towards the camera. Should be the actual near plane if screen-space depth is enabled.\n\\param farPlaneZ The far plane for the camera. Used when screen-space depth is enabled.\n\\param stride Step in horizontal or vertical pixels between samples. This is a var because: f32 integer math is slow on GPUs,but should be set to an integer>=1\n\\param jitterFraction Number between 0 and 1 for how far to bump the ray in stride units\nto conceal banding artifacts,plus the stride ray offset.\n\\param maxSteps Maximum number of iterations. Higher gives better images but may be slow\n\\param maxRayTraceDistance Maximum camera-space distance to trace before returning a miss\n\\param selfCollisionNumSkip Number of steps to skip at start when raytracing to avar self: voidnull collisions.\n1 is a reasonable value,depending on the scene you may need to set this value to 2\n\\param hitPixel Pixel coordinates of the first intersection with the scene\n\\param numIterations number of iterations performed\n\\param csHitPovar Camera: i32 space location of the ray hit\n*/\nfn traceScreenSpaceRay1(\ncsOrigin: vec3f,\ncsDirection: vec3f,\nprojectToPixelMatrix: mat4x4f,\ncsZBuffer: texture_2d<f32>,\ncsZBufferSize: vec2f,\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\ncsZBackBuffer: texture_2d<f32>,\ncsZBackSizeFactor: f32,\n#endif\ncsZThickness: f32,\nnearPlaneZ: f32,\nfarPlaneZ: f32,\nstride: f32,\njitterFraction: f32,\nmaxSteps: f32,\nmaxRayTraceDistance: f32,\nselfCollisionNumSkip: f32,\nstartPixel: ptr<function,vec2f>,\nhitPixel: ptr<function,vec2f>,\ncsHitPoint: ptr<function,vec3f>,\nnumIterations: ptr<function,f32>\n#ifdef SSRAYTRACE_DEBUG\n,debugColor: ptr<function,vec3f>\n#endif\n)->bool\n{\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nvar rayLength: f32=select(maxRayTraceDistance,(-nearPlaneZ-csOrigin.z)/csDirection.z,(csOrigin.z+csDirection.z*maxRayTraceDistance)>-nearPlaneZ);\n#else\nvar rayLength: f32=select(maxRayTraceDistance,(nearPlaneZ-csOrigin.z)/csDirection.z,(csOrigin.z+csDirection.z*maxRayTraceDistance)<nearPlaneZ);\n#endif\nvar csEndPoint: vec3f=csOrigin+csDirection*rayLength;*hitPixel= vec2f(-1.0,-1.0);var H0: vec4f=projectToPixelMatrix* vec4f(csOrigin,1.0);var H1: vec4f=projectToPixelMatrix* vec4f(csEndPoint,1.0);var k0: f32=1.0/H0.w;var k1: f32=1.0/H1.w;var Q0: vec3f=csOrigin*k0;var Q1: vec3f=csEndPoint*k1;var P0: vec2f=H0.xy*k0;var P1: vec2f=H1.xy*k1;\n#ifdef SSRAYTRACE_CLIP_TO_FRUSTUM\nvar xMax: f32=csZBufferSize.x-0.5;var xMin=0.5;var yMax=csZBufferSize.y-0.5;var yMin=0.5;var alpha: f32=0.0;if ((P1.y>yMax) || (P1.y<yMin)) {alpha=(P1.y-select(yMin,yMax,(P1.y>yMax)))/(P1.y-P0.y);}\nif ((P1.x>xMax) || (P1.x<xMin)) {alpha=max(alpha,(P1.x-select(xMin,xMax,(P1.x>xMax)))/(P1.x-P0.x));}\nP1=mix(P1,P0,alpha); k1=mix(k1,k0,alpha); Q1=mix(Q1,Q0,alpha);\n#endif\nP1+= vec2f(select(0.0,0.01,distanceSquared(P0,P1)<0.0001));var delta: vec2f=P1-P0;var permute: bool=false;if (abs(delta.x)<abs(delta.y)) { \npermute=true;delta=delta.yx;P0=P0.yx;P1=P1.yx; }\nvar stepDirection: f32=sign(delta.x);var invdx: f32=stepDirection/delta.x;var dP: vec2f= vec2f(stepDirection,delta.y*invdx);var dQ: vec3f=(Q1-Q0)*invdx;var dk: f32=(k1-k0)*invdx;var zMin: f32=min(csEndPoint.z,csOrigin.z);var zMax: f32=max(csEndPoint.z,csOrigin.z);dP*=stride; dQ*=stride; dk*=stride;P0+=dP*jitterFraction; Q0+=dQ*jitterFraction; k0+=dk*jitterFraction;var pqk: vec4f= vec4f(P0,Q0.z,k0);var dPQK: vec4f= vec4f(dP,dQ.z,dk);*startPixel=select(P0.xy,P0.yx,permute);var prevZMaxEstimate: f32=csOrigin.z;var rayZMin: f32=prevZMaxEstimate;var rayZMax=prevZMaxEstimate;var sceneZMax: f32=rayZMax+1e4;var end: f32=P1.x*stepDirection;var hit: bool=false;var stepCount: f32;for (stepCount=0.0;(stepCount<=selfCollisionNumSkip) ||\n((pqk.x*stepDirection)<=end &&\nstepCount<maxSteps &&\n!hit);pqk+=dPQK \n)\n{*hitPixel=select(pqk.xy,pqk.yx,permute);\n#ifndef SSRAYTRACE_CLIP_TO_FRUSTUM\nif ((*hitPixel).x<0.0 || (*hitPixel).x>=csZBufferSize.x ||\n(*hitPixel).y<0.0 || (*hitPixel).y>=csZBufferSize.y) { break; }\n#endif\nrayZMin=prevZMaxEstimate;rayZMax=(dPQK.z*0.5+pqk.z)/(dPQK.w*0.5+pqk.w);rayZMax=clamp(rayZMax,zMin,zMax);prevZMaxEstimate=rayZMax;\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nif (prevZMaxEstimate<-farPlaneZ) { break; }\n#else\nif (prevZMaxEstimate>farPlaneZ) { break; }\n#endif\nif (rayZMin>rayZMax) { \nvar t: f32=rayZMin; rayZMin=rayZMax; rayZMax=t;}\nsceneZMax=textureLoad(csZBuffer,vec2<i32>(*hitPixel),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneZMax=linearizeDepth(sceneZMax,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneZMax==0.0) { sceneZMax=1e8; }\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nvar sceneBackZ: f32=textureLoad(csZBackBuffer,vec2<i32>(*hitPixel/csZBackSizeFactor),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneBackZ=linearizeDepth(sceneBackZ,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneBackZ==0.0) { sceneBackZ=-1e8; }\nhit=(rayZMax>=sceneBackZ-csZThickness) && (rayZMin<=sceneZMax);\n#else\nhit=(rayZMax>=sceneZMax-csZThickness) && (rayZMin<=sceneZMax);\n#endif\n#else\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nvar sceneBackZ: f32=textureLoad(csZBackBuffer,vec2<i32>(*hitPixel/csZBackSizeFactor),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneBackZ=linearizeDepth(sceneBackZ,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneBackZ==0.0) { sceneBackZ=1e8; }\nhit=(rayZMin<=sceneBackZ+csZThickness) && (rayZMax>=sceneZMax);\n#else\nhit=(rayZMin<=sceneZMax+csZThickness) && (rayZMax>=sceneZMax);\n#endif\n#endif\nstepCount+=1.0;}\npqk-=dPQK;stepCount-=1.0;if (((pqk.x+dPQK.x)*stepDirection)>end || (stepCount+1.0)>=maxSteps) {hit=false;}\n#ifdef SSRAYTRACE_ENABLE_REFINEMENT\nif (stride>1.0 && hit) {pqk-=dPQK;stepCount-=1.0;var invStride: f32=1.0/stride;dPQK*=invStride;var refinementStepCount: f32=0.0;prevZMaxEstimate=pqk.z/pqk.w;rayZMax=prevZMaxEstimate;sceneZMax=rayZMax+1e7;for (;refinementStepCount<=1.0 ||\n((refinementStepCount<=stride*1.4) &&\n(rayZMax<sceneZMax));pqk+=dPQK)\n{rayZMin=prevZMaxEstimate;rayZMax=(dPQK.z*0.5+pqk.z)/(dPQK.w*0.5+pqk.w);rayZMax=clamp(rayZMax,zMin,zMax);prevZMaxEstimate=rayZMax;rayZMax=max(rayZMax,rayZMin);*hitPixel=select(pqk.xy,pqk.yx,permute);sceneZMax=textureLoad(csZBuffer,vec2<i32>(*hitPixel),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nsceneZMax=linearizeDepth(sceneZMax,nearPlaneZ,farPlaneZ);\n#endif\nif (sceneZMax==0.0) { sceneZMax=1e8; }\nrefinementStepCount+=1.0;}\npqk-=dPQK;refinementStepCount-=1.0;stepCount+=refinementStepCount/stride;}\n#endif\nQ0=vec3f(Q0.xy+dQ.xy*stepCount,pqk.z);*csHitPoint=Q0/pqk.w;*numIterations=stepCount+1.0;\n#ifdef SSRAYTRACE_DEBUG\nif (((pqk.x+dPQK.x)*stepDirection)>end) {*debugColor= vec3f(0,0,1);} else if ((stepCount+1.0)>=maxSteps) {*debugColor= vec3f(1,0,0);} else if (!hit) {*debugColor= vec3f(1,1,0);} else {*debugColor= vec3f(0,stepCount/maxSteps,0);}\n#endif\nreturn hit;}\n/**\ntexCoord: in the [0,1] range\ndepth: depth in view space (range [znear,zfar]])\n*/\nfn computeViewPosFromUVDepth(texCoord: vec2f,depth: f32,projection: mat4x4f,invProjectionMatrix: mat4x4f)->vec3f {var xy=texCoord*2.0-1.0;var z: f32;\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\n#ifdef ORTHOGRAPHIC_CAMERA\nz=-projection[2].z*depth+projection[3].z;\n#else\nz=-projection[2].z-projection[3].z/depth;\n#endif\n#else\n#ifdef ORTHOGRAPHIC_CAMERA\nz=projection[2].z*depth+projection[3].z;\n#else\nz=projection[2].z+projection[3].z/depth;\n#endif\n#endif\nvar w=1.0;var ndc=vec4f(xy,z,w);var eyePos: vec4f=invProjectionMatrix*ndc;var result=eyePos.xyz/eyePos.w;return result;}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const screenSpaceRayTraceWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { screenSpaceRayTraceWGSL } from \"./ShadersInclude/screenSpaceRayTrace\";\n\nconst name = \"screenSpaceReflection2PixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;varying vUV: vec2f;\n#ifdef SSR_SUPPORTED\nvar reflectivitySamplerSampler: sampler;var reflectivitySampler: texture_2d<f32>;var normalSampler: texture_2d<f32>;var depthSampler: texture_2d<f32>;\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nvar backDepthSampler: texture_2d<f32>;uniform backSizeFactor: f32;\n#endif\n#ifdef SSR_USE_ENVIRONMENT_CUBE\nvar envCubeSamplerSampler: sampler;var envCubeSampler: texture_cube<f32>;\n#ifdef SSR_USE_LOCAL_REFLECTIONMAP_CUBIC\nuniform vReflectionPosition: vec3f;uniform vReflectionSize: vec3f;\n#endif\n#endif\nuniform view: mat4x4f;uniform invView: mat4x4f;uniform projection: mat4x4f;uniform invProjectionMatrix: mat4x4f;uniform projectionPixel: mat4x4f;uniform nearPlaneZ: f32;uniform farPlaneZ: f32;uniform stepSize: f32;uniform maxSteps: f32;uniform strength: f32;uniform thickness: f32;uniform roughnessFactor: f32;uniform reflectionSpecularFalloffExponent: f32;uniform maxDistance: f32;uniform selfCollisionNumSkip: f32;uniform reflectivityThreshold: f32;\n#include<helperFunctions>\n#include<pbrBRDFFunctions>\n#include<screenSpaceRayTrace>\nfn hash(a: vec3f)->vec3f\n{var result=fract(a*0.8);result+=dot(result,result.yxz+19.19);return fract((result.xxy+result.yxx)*result.zyx);}\nfn computeAttenuationForIntersection(ihitPixel: vec2f,hitUV: vec2f,vsRayOrigin: vec3f,vsHitPoint: vec3f,reflectionVector: vec3f,maxRayDistance: f32,numIterations: f32)->f32 {var attenuation: f32=1.0;\n#ifdef SSR_ATTENUATE_SCREEN_BORDERS\nvar dCoords: vec2f=smoothstep(vec2f(0.2),vec2f(0.6),abs( vec2f(0.5,0.5)-hitUV.xy));attenuation*=clamp(1.0-(dCoords.x+dCoords.y),0.0,1.0);\n#endif\n#ifdef SSR_ATTENUATE_INTERSECTION_DISTANCE\nattenuation*=1.0-clamp(distance(vsRayOrigin,vsHitPoint)/maxRayDistance,0.0,1.0);\n#endif\n#ifdef SSR_ATTENUATE_INTERSECTION_NUMITERATIONS\nattenuation*=1.0-(numIterations/uniforms.maxSteps);\n#endif\n#ifdef SSR_ATTENUATE_BACKFACE_REFLECTION\nvar reflectionNormal: vec3f=texelFetch(normalSampler,hitPixel,0).xyz;var directionBasedAttenuation: f32=smoothstep(-0.17,0.0,dot(reflectionNormal,-reflectionVector));attenuation*=directionBasedAttenuation;\n#endif\nreturn attenuation;}\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#ifdef SSR_SUPPORTED\nvar colorFull: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);var color: vec3f=colorFull.rgb;var reflectivity: vec4f=max(textureSampleLevel(reflectivitySampler,reflectivitySamplerSampler,input.vUV,0.0),vec4f(0.0));\n#ifndef SSR_DISABLE_REFLECTIVITY_TEST\nif (max(reflectivity.r,max(reflectivity.g,reflectivity.b))<=uniforms.reflectivityThreshold) {\n#ifdef SSR_USE_BLUR\nfragmentOutputs.color= vec4f(0.);\n#else\nfragmentOutputs.color=colorFull;\n#endif\nreturn fragmentOutputs;}\n#endif\n#ifdef SSR_INPUT_IS_GAMMA_SPACE\ncolor=toLinearSpaceVec3(color);\n#endif\nvar texSize: vec2f= vec2f(textureDimensions(depthSampler,0));var csNormal: vec3f=textureLoad(normalSampler,vec2<i32>(input.vUV*texSize),0).xyz; \n#ifdef SSR_DECODE_NORMAL\ncsNormal=csNormal*2.0-1.0;\n#endif\n#ifdef SSR_NORMAL_IS_IN_WORLDSPACE\ncsNormal=(uniforms.view* vec4f(csNormal,0.0)).xyz;\n#endif\nvar depth: f32=textureLoad(depthSampler,vec2<i32>(input.vUV*texSize),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\ndepth=linearizeDepth(depth,uniforms.nearPlaneZ,uniforms.farPlaneZ);\n#endif\nvar csPosition: vec3f=computeViewPosFromUVDepth(input.vUV,depth,uniforms.projection,uniforms.invProjectionMatrix);\n#ifdef ORTHOGRAPHIC_CAMERA\nvar csViewDirection: vec3f= vec3f(0.,0.,1.);\n#else\nvar csViewDirection: vec3f=normalize(csPosition);\n#endif\nvar csReflectedVector: vec3f=reflect(csViewDirection,csNormal);\n#ifdef SSR_USE_ENVIRONMENT_CUBE\nvar wReflectedVector: vec3f=(uniforms.invView* vec4f(csReflectedVector,0.0)).xyz;\n#ifdef SSR_USE_LOCAL_REFLECTIONMAP_CUBIC\nvar worldPos: vec4f=uniforms.invView* vec4f(csPosition,1.0);wReflectedVector=parallaxCorrectNormal(worldPos.xyz,normalize(wReflectedVector),uniforms.vReflectionSize,uniforms.vReflectionPosition);\n#endif\n#ifdef SSR_INVERTCUBICMAP\nwReflectedVector.y*=-1.0;\n#endif\n#ifdef SSRAYTRACE_RIGHT_HANDED_SCENE\nwReflectedVector.z*=-1.0;\n#endif\nvar envColor: vec3f=textureSampleLevel(envCubeSampler,envCubeSamplerSampler,wReflectedVector,0.0).xyz;\n#ifdef SSR_ENVIRONMENT_CUBE_IS_GAMMASPACE\nenvColor=toLinearSpaceVec3(envColor);\n#endif\n#else\nvar envColor: vec3f=color;\n#endif\nvar reflectionAttenuation: f32=1.0;var rayHasHit: bool=false;var startPixel: vec2f;var hitPixel: vec2f;var hitPoint: vec3f;var numIterations: f32;\n#ifdef SSRAYTRACE_DEBUG\nvar debugColor: vec3f;\n#endif\n#ifdef SSR_ATTENUATE_FACING_CAMERA\nreflectionAttenuation*=1.0-smoothstep(0.25,0.5,dot(-csViewDirection,csReflectedVector));\n#endif\nif (reflectionAttenuation>0.0) {\n#ifdef SSR_USE_BLUR\nvar jitt: vec3f= vec3f(0.);\n#else\nvar roughness: f32=1.0-reflectivity.a;var jitt: vec3f=mix( vec3f(0.0),hash(csPosition)- vec3f(0.5),roughness)*uniforms.roughnessFactor; \n#endif\nvar uv2: vec2f=input.vUV*texSize;var c: f32=(uv2.x+uv2.y)*0.25;var jitter: f32=((c)%(1.0)); \nrayHasHit=traceScreenSpaceRay1(\ncsPosition,\nnormalize(csReflectedVector+jitt),\nuniforms.projectionPixel,\ndepthSampler,\ntexSize,\n#ifdef SSRAYTRACE_USE_BACK_DEPTHBUFFER\nbackDepthSampler,\nuniforms.backSizeFactor,\n#endif\nuniforms.thickness,\nuniforms.nearPlaneZ,\nuniforms.farPlaneZ,\nuniforms.stepSize,\njitter,\nuniforms.maxSteps,\nuniforms.maxDistance,\nuniforms.selfCollisionNumSkip,\n&startPixel,\n&hitPixel,\n&hitPoint,\n&numIterations\n#ifdef SSRAYTRACE_DEBUG\n,&debugColor\n#endif\n);}\n#ifdef SSRAYTRACE_DEBUG\nfragmentOutputs.color= vec4f(debugColor,1.);return fragmentOutputs;\n#endif\nvar F0: vec3f=reflectivity.rgb;var fresnel: vec3f=fresnelSchlickGGXVec3(max(dot(csNormal,-csViewDirection),0.0),F0, vec3f(1.));var SSR: vec3f=envColor;if (rayHasHit) {var reflectedColor: vec3f=textureLoad(textureSampler,vec2<i32>(hitPixel),0).rgb;\n#ifdef SSR_INPUT_IS_GAMMA_SPACE\nreflectedColor=toLinearSpaceVec3(reflectedColor);\n#endif\nreflectionAttenuation*=computeAttenuationForIntersection(hitPixel,hitPixel/texSize,csPosition,hitPoint,csReflectedVector,uniforms.maxDistance,numIterations);SSR=reflectedColor*reflectionAttenuation+(1.0-reflectionAttenuation)*envColor;}\n#ifndef SSR_BLEND_WITH_FRESNEL\nSSR*=fresnel;\n#endif\nSSR=clamp(SSR,vec3f(0.0),vec3f(1000.0)); \n#ifdef SSR_USE_BLUR\nvar blur_radius: f32=0.0;var roughness: f32=1.0-reflectivity.a*(1.0-uniforms.roughnessFactor);if (roughness>0.001) {var cone_angle: f32=min(roughness,0.999)*3.14159265*0.5;var cone_len: f32=distance(startPixel,hitPixel);var op_len: f32=2.0*tan(cone_angle)*cone_len; \nvar a: f32=op_len;var h: f32=cone_len;var a2: f32=a*a;var fh2: f32=4.0f*h*h;blur_radius=(a*(sqrt(a2+fh2)-a))/(4.0f*h);}\nfragmentOutputs.color= vec4f(SSR,blur_radius/255.0); \n#else\n#ifdef SSR_BLEND_WITH_FRESNEL\nvar reflectionMultiplier: vec3f=clamp(pow(fresnel*uniforms.strength, vec3f(uniforms.reflectionSpecularFalloffExponent)),vec3f(0.0),vec3f(1.0));\n#else\nvar reflectionMultiplier: vec3f=clamp(pow(reflectivity.rgb*uniforms.strength, vec3f(uniforms.reflectionSpecularFalloffExponent)),vec3f(0.0),vec3f(1.0));\n#endif\nvar colorMultiplier: vec3f=1.0-reflectionMultiplier;var finalColor: vec3f=(color*colorMultiplier)+(SSR*reflectionMultiplier);\n#ifdef SSR_OUTPUT_IS_GAMMA_SPACE\nfinalColor=toGammaSpaceVec3(finalColor);\n#endif\nfragmentOutputs.color= vec4f(finalColor,colorFull.a);\n#endif\n#else\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, pbrBRDFFunctionsWGSL, screenSpaceRayTraceWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const screenSpaceReflection2PixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"screenSpaceReflection2BlurPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;varying vUV: vec2f;uniform texelOffsetScale: vec2f;const weights: array<f32,8>=array<f32,8>(0.071303,0.131514,0.189879,0.321392,0.452906, 0.584419,0.715932,0.847445);fn processSample(uv: vec2f,i: f32,stepSize: vec2f,accumulator: ptr<function,vec4f>,denominator: ptr<function,f32>)\n{var offsetUV: vec2f=stepSize*i+uv;var coefficient: f32=weights[ i32(2.0-abs(i))];*accumulator+=textureSampleLevel(textureSampler,textureSamplerSampler,offsetUV,0.0)*coefficient;*denominator+=coefficient;}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var colorFull: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);if (dot(colorFull, vec4f(1.0))==0.0) {fragmentOutputs.color=colorFull;return fragmentOutputs;}\nvar blurRadius: f32=colorFull.a*255.0; \nvar stepSize: vec2f=uniforms.texelOffsetScale.xy*blurRadius;var accumulator: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0)*0.214607;var denominator: f32=0.214607;processSample(input.vUV,1.0,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*0.2,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*0.4,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*0.6,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*0.8,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*1.2,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*1.4,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*1.6,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*1.8,stepSize,&accumulator,&denominator);processSample(input.vUV,1.0*2.0,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*0.2,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*0.4,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*0.6,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*0.8,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*1.2,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*1.4,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*1.6,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*1.8,stepSize,&accumulator,&denominator);processSample(input.vUV,-1.0*2.0,stepSize,&accumulator,&denominator);fragmentOutputs.color= vec4f(accumulator.rgb/denominator,colorFull.a);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const screenSpaceReflection2BlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { screenSpaceRayTraceWGSL } from \"./ShadersInclude/screenSpaceRayTrace\";\n\nconst name = \"screenSpaceReflection2BlurCombinerPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>; \nvar mainSamplerSampler: sampler;var mainSampler: texture_2d<f32>;var reflectivitySamplerSampler: sampler;var reflectivitySampler: texture_2d<f32>;uniform strength: f32;uniform reflectionSpecularFalloffExponent: f32;uniform reflectivityThreshold: f32;varying vUV: vec2f;\n#include<helperFunctions>\n#ifdef SSR_BLEND_WITH_FRESNEL\n#include<pbrBRDFFunctions>\n#include<screenSpaceRayTrace>\nuniform projection: mat4x4f;uniform invProjectionMatrix: mat4x4f;\n#ifdef SSR_NORMAL_IS_IN_WORLDSPACE\nuniform view: mat4x4f;\n#endif\nvar normalSampler: texture_2d<f32>;var depthSampler: texture_2d<f32>;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\nuniform nearPlaneZ: f32;uniform farPlaneZ: f32;\n#endif\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#ifdef SSRAYTRACE_DEBUG\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);\n#else\nvar SSR: vec3f=textureSample(textureSampler,textureSamplerSampler,input.vUV).rgb;var color: vec4f=textureSample(mainSampler,textureSamplerSampler,input.vUV);var reflectivity: vec4f=textureSample(reflectivitySampler,reflectivitySamplerSampler,input.vUV);\n#ifndef SSR_DISABLE_REFLECTIVITY_TEST\nif (max(reflectivity.r,max(reflectivity.g,reflectivity.b))<=uniforms.reflectivityThreshold) {fragmentOutputs.color=color;return fragmentOutputs;}\n#endif\n#ifdef SSR_INPUT_IS_GAMMA_SPACE\ncolor=toLinearSpaceVec4(color);\n#endif\n#ifdef SSR_BLEND_WITH_FRESNEL\nvar texSize: vec2f= vec2f(textureDimensions(depthSampler,0));var csNormal: vec3f=textureLoad(normalSampler,vec2<i32>(input.vUV*texSize),0).xyz;\n#ifdef SSR_DECODE_NORMAL\ncsNormal=csNormal*2.0-1.0;\n#endif\n#ifdef SSR_NORMAL_IS_IN_WORLDSPACE\ncsNormal=(uniforms.view*vec4f(csNormal,0.0)).xyz;\n#endif\nvar depth: f32=textureLoad(depthSampler,vec2<i32>(input.vUV*texSize),0).r;\n#ifdef SSRAYTRACE_SCREENSPACE_DEPTH\ndepth=linearizeDepth(depth,uniforms.nearPlaneZ,uniforms.farPlaneZ);\n#endif\nvar csPosition: vec3f=computeViewPosFromUVDepth(input.vUV,depth,uniforms.projection,uniforms.invProjectionMatrix);var csViewDirection: vec3f=normalize(csPosition);var F0: vec3f=reflectivity.rgb;var fresnel: vec3f=fresnelSchlickGGXVec3(max(dot(csNormal,-csViewDirection),0.0),F0, vec3f(1.));var reflectionMultiplier: vec3f=clamp(pow(fresnel*uniforms.strength, vec3f(uniforms.reflectionSpecularFalloffExponent)),vec3f(0.0),vec3f(1.0));\n#else\nvar reflectionMultiplier: vec3f=clamp(pow(reflectivity.rgb*uniforms.strength, vec3f(uniforms.reflectionSpecularFalloffExponent)),vec3f(0.0),vec3f(1.0));\n#endif\nvar colorMultiplier: vec3f=1.0-reflectionMultiplier;var finalColor: vec3f=(color.rgb*colorMultiplier)+(SSR*reflectionMultiplier);\n#ifdef SSR_OUTPUT_IS_GAMMA_SPACE\nfinalColor=toGammaSpaceVec3(finalColor);\n#endif\nfragmentOutputs.color= vec4f(finalColor,color.a);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, pbrBRDFFunctionsWGSL, screenSpaceRayTraceWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const screenSpaceReflection2BlurCombinerPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"taaPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D historySampler;\n#ifdef TAA_REPROJECT_HISTORY\nuniform sampler2D velocitySampler;\n#endif\nuniform float factor;void main() {ivec2 pos=ivec2(gl_FragCoord.xy);vec4 c=texelFetch(textureSampler,pos,0);\n#ifdef TAA_REPROJECT_HISTORY\nvec4 v=texelFetch(velocitySampler,pos,0);vec4 h=texture2D(historySampler,vUV+v.xy);\n#else\nvec4 h=texelFetch(historySampler,pos,0);\n#endif\n#ifdef TAA_CLAMP_HISTORY\nvec4 cmin=vec4(1);vec4 cmax=vec4(0);for (int x=-1; x<=1; x+=1) {for (int y=-1; y<=1; y+=1) {vec4 c=texelFetch(textureSampler,pos+ivec2(x,y),0);cmin=min(cmin,c);cmax=max(cmax,c);}}\nh=clamp(h,cmin,cmax);\n#endif\ngl_FragColor=mix(h,c,factor);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const taaPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"taaPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSampler: texture_2d<f32>;var historySampler: texture_2d<f32>;\n#ifdef TAA_REPROJECT_HISTORY\nvar historySamplerSampler: sampler;var velocitySampler: texture_2d<f32>;\n#endif\nuniform factor: f32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let pos=vec2i(fragmentInputs.position.xy);let c=textureLoad(textureSampler,pos,0);\n#ifdef TAA_REPROJECT_HISTORY\nlet v=textureLoad(velocitySampler,pos,0);var h=textureSample(historySampler,historySamplerSampler,input.vUV+v.xy);\n#else\nvar h=textureLoad(historySampler,pos,0);\n#endif\n#ifdef TAA_CLAMP_HISTORY\nvar cmin=vec4f(1);var cmax=vec4f(0);for (var x=-1; x<=1; x+=1) {for (var y=-1; y<=1; y+=1) {let c=textureLoad(textureSampler,pos+vec2i(x,y),0);cmin=min(cmin,c);cmax=max(cmax,c);}}\nh=clamp(h,cmin,cmax);\n#endif\nfragmentOutputs.color= mix(h,c,uniforms.factor);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const taaPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"ffxFunctions\";\nconst shader = `float AMax3F1(float x,float y,float z) {return max(x,max(y,z));}\nvec3 AMax3F3(vec3 x,vec3 y,vec3 z) {return max(x,max(y,z));}\nfloat AMin3F1(float x,float y,float z) {return min(x,min(y,z));}\nvec3 AMin3F3(vec3 x,vec3 y,vec3 z) {return min(x,min(y,z));}\nfloat APrxLoRcpF1(float a) {return uintBitsToFloat(0x7ef07ebbu-floatBitsToUint(a));}\nfloat APrxMedRcpF1(float a) {float b=uintBitsToFloat(0x7ef19fffu-floatBitsToUint(a));return b*(-b*a+2.0);}\nfloat APrxLoRsqF1(float a) {return uintBitsToFloat(0x5f347d74u-(floatBitsToUint(a)>>1u));}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const ffxFunctions = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { ffxFunctions } from \"./ShadersInclude/ffxFunctions\";\n\nconst name = \"fsr1UpscalePixelShader\";\nconst shader = `#include<ffxFunctions>\nuniform sampler2D textureSampler;varying vec2 vUV;uniform vec4 con0;uniform vec4 con1;uniform vec4 con2;uniform vec4 con3;vec4 FsrEasuRF(vec2 p) {ivec2 texSize=textureSize(textureSampler,0);ivec2 mx=texSize-ivec2(1);ivec2 base=ivec2(floor(p*vec2(texSize)-0.5));return vec4(\ntexelFetch(textureSampler,clamp(base+ivec2(0,1),ivec2(0),mx),0).r,\ntexelFetch(textureSampler,clamp(base+ivec2(1,1),ivec2(0),mx),0).r,\ntexelFetch(textureSampler,clamp(base+ivec2(1,0),ivec2(0),mx),0).r,\ntexelFetch(textureSampler,clamp(base+ivec2(0,0),ivec2(0),mx),0).r);}\nvec4 FsrEasuGF(vec2 p) {ivec2 texSize=textureSize(textureSampler,0);ivec2 mx=texSize-ivec2(1);ivec2 base=ivec2(floor(p*vec2(texSize)-0.5));return vec4(\ntexelFetch(textureSampler,clamp(base+ivec2(0,1),ivec2(0),mx),0).g,\ntexelFetch(textureSampler,clamp(base+ivec2(1,1),ivec2(0),mx),0).g,\ntexelFetch(textureSampler,clamp(base+ivec2(1,0),ivec2(0),mx),0).g,\ntexelFetch(textureSampler,clamp(base+ivec2(0,0),ivec2(0),mx),0).g);}\nvec4 FsrEasuBF(vec2 p) {ivec2 texSize=textureSize(textureSampler,0);ivec2 mx=texSize-ivec2(1);ivec2 base=ivec2(floor(p*vec2(texSize)-0.5));return vec4(\ntexelFetch(textureSampler,clamp(base+ivec2(0,1),ivec2(0),mx),0).b,\ntexelFetch(textureSampler,clamp(base+ivec2(1,1),ivec2(0),mx),0).b,\ntexelFetch(textureSampler,clamp(base+ivec2(1,0),ivec2(0),mx),0).b,\ntexelFetch(textureSampler,clamp(base+ivec2(0,0),ivec2(0),mx),0).b);}\nvoid FsrEasuTapF(\ninout vec3 aC,\ninout float aW,\nvec2 off,\nvec2 dir,\nvec2 len,\nfloat lob,\nfloat clp,\nvec3 c \n) {vec2 v;v.x=(off.x*( dir.x))+(off.y*dir.y);v.y=(off.x*(-dir.y))+(off.y*dir.x);v*=len;float d2=v.x*v.x+v.y*v.y;d2=min(d2,clp);float wB=2.0/5.0*d2+-1.0;float wA=lob*d2+-1.0;wB*=wB;wA*=wA;wB=25.0/16.0*wB+-(25.0/16.0-1.0);float w=wB*wA;aC+=c*w;aW+=w;}\nvoid FsrEasuSetF(\ninout vec2 dir,\ninout float len,\nvec2 pp,\nbool biS,bool biT,bool biU,bool biV,\nfloat lA,float lB,float lC,float lD,float lE\n) {float w=0.0;if (biS) {w=(1.0-pp.x)*(1.0-pp.y);}\nif (biT) {w=pp.x*(1.0-pp.y);}\nif (biU) {w=(1.0-pp.x)*pp.y;}\nif (biV) {w=pp.x*pp.y;}\nfloat dc=lD-lC;float cb=lC-lB;float lenX=max(abs(dc),abs(cb));lenX=APrxLoRcpF1(lenX);float dirX=lD-lB;dir.x+=dirX*w;lenX=clamp(abs(dirX)*lenX,0.0,1.0);lenX*=lenX;len+=lenX*w;float ec=lE-lC;float ca=lC-lA;float lenY=max(abs(ec),abs(ca));lenY=APrxLoRcpF1(lenY);float dirY=lE-lA;dir.y+=dirY*w;lenY=clamp(abs(dirY)*lenY,0.0,1.0);lenY*=lenY;len+=lenY*w;}\nvec3 FsrEasuF(\nivec2 ip,\nvec4 con0,\nvec4 con1,\nvec4 con2,\nvec4 con3\n) {vec2 pp=vec2(ip)*con0.xy+con0.zw;vec2 fp=floor(pp);pp-=fp;vec2 p0=fp*con1.xy+con1.zw;vec2 p1=p0+con2.xy;vec2 p2=p0+con2.zw;vec2 p3=p0+con3.xy;vec4 bczzR=FsrEasuRF(p0);vec4 bczzG=FsrEasuGF(p0);vec4 bczzB=FsrEasuBF(p0);vec4 ijfeR=FsrEasuRF(p1);vec4 ijfeG=FsrEasuGF(p1);vec4 ijfeB=FsrEasuBF(p1);vec4 klhgR=FsrEasuRF(p2);vec4 klhgG=FsrEasuGF(p2);vec4 klhgB=FsrEasuBF(p2);vec4 zzonR=FsrEasuRF(p3);vec4 zzonG=FsrEasuGF(p3);vec4 zzonB=FsrEasuBF(p3);vec4 bczzL=bczzB*vec4(0.5)+(bczzR*vec4(0.5)+bczzG);vec4 ijfeL=ijfeB*vec4(0.5)+(ijfeR*vec4(0.5)+ijfeG);vec4 klhgL=klhgB*vec4(0.5)+(klhgR*vec4(0.5)+klhgG);vec4 zzonL=zzonB*vec4(0.5)+(zzonR*vec4(0.5)+zzonG);float bL=bczzL.x;float cL=bczzL.y;float iL=ijfeL.x;float jL=ijfeL.y;float fL=ijfeL.z;float eL=ijfeL.w;float kL=klhgL.x;float lL=klhgL.y;float hL=klhgL.z;float gL=klhgL.w;float oL=zzonL.z;float nL=zzonL.w;vec2 dir=vec2(0.0);float len=0.0;FsrEasuSetF(dir,len,pp,true, false,false,false,bL,eL,fL,gL,jL);FsrEasuSetF(dir,len,pp,false,true, false,false,cL,fL,gL,hL,kL);FsrEasuSetF(dir,len,pp,false,false,true, false,fL,iL,jL,kL,nL);FsrEasuSetF(dir,len,pp,false,false,false,true, gL,jL,kL,lL,oL);vec2 dir2=dir*dir;float dirR=dir2.x+dir2.y;bool zro=dirR<(1.0/32768.0);dirR=APrxLoRsqF1(dirR);dirR=zro ? 1.0 : dirR;dir.x=zro ? 1.0 : dir.x;dir*=vec2(dirR);len=len*0.5;len*=len;float stretch=(dir.x*dir.x+dir.y*dir.y)*APrxLoRcpF1(max(abs(dir.x),abs(dir.y)));vec2 len2=vec2(1.0+(stretch-1.0)*len,1.0+-0.5*len);float lob=0.5+((1.0/4.0-0.04)-0.5)*len;float clp=APrxLoRcpF1(lob);vec3 min4=min(AMin3F3(vec3(ijfeR.z,ijfeG.z,ijfeB.z),vec3(klhgR.w,klhgG.w,klhgB.w),vec3(ijfeR.y,ijfeG.y,ijfeB.y)),\nvec3(klhgR.x,klhgG.x,klhgB.x));vec3 max4=max(AMax3F3(vec3(ijfeR.z,ijfeG.z,ijfeB.z),vec3(klhgR.w,klhgG.w,klhgB.w),vec3(ijfeR.y,ijfeG.y,ijfeB.y)),\nvec3(klhgR.x,klhgG.x,klhgB.x));vec3 aC=vec3(0.0);float aW=0.0;FsrEasuTapF(aC,aW,vec2( 0.0,-1.0)-pp,dir,len2,lob,clp,vec3(bczzR.x,bczzG.x,bczzB.x)); \nFsrEasuTapF(aC,aW,vec2( 1.0,-1.0)-pp,dir,len2,lob,clp,vec3(bczzR.y,bczzG.y,bczzB.y)); \nFsrEasuTapF(aC,aW,vec2(-1.0, 1.0)-pp,dir,len2,lob,clp,vec3(ijfeR.x,ijfeG.x,ijfeB.x)); \nFsrEasuTapF(aC,aW,vec2( 0.0, 1.0)-pp,dir,len2,lob,clp,vec3(ijfeR.y,ijfeG.y,ijfeB.y)); \nFsrEasuTapF(aC,aW,vec2( 0.0, 0.0)-pp,dir,len2,lob,clp,vec3(ijfeR.z,ijfeG.z,ijfeB.z)); \nFsrEasuTapF(aC,aW,vec2(-1.0, 0.0)-pp,dir,len2,lob,clp,vec3(ijfeR.w,ijfeG.w,ijfeB.w)); \nFsrEasuTapF(aC,aW,vec2( 1.0, 1.0)-pp,dir,len2,lob,clp,vec3(klhgR.x,klhgG.x,klhgB.x)); \nFsrEasuTapF(aC,aW,vec2( 2.0, 1.0)-pp,dir,len2,lob,clp,vec3(klhgR.y,klhgG.y,klhgB.y)); \nFsrEasuTapF(aC,aW,vec2( 2.0, 0.0)-pp,dir,len2,lob,clp,vec3(klhgR.z,klhgG.z,klhgB.z)); \nFsrEasuTapF(aC,aW,vec2( 1.0, 0.0)-pp,dir,len2,lob,clp,vec3(klhgR.w,klhgG.w,klhgB.w)); \nFsrEasuTapF(aC,aW,vec2( 1.0, 2.0)-pp,dir,len2,lob,clp,vec3(zzonR.z,zzonG.z,zzonB.z)); \nFsrEasuTapF(aC,aW,vec2( 0.0, 2.0)-pp,dir,len2,lob,clp,vec3(zzonR.w,zzonG.w,zzonB.w)); \nreturn min(max4,max(min4,aC*vec3(1.0/aW)));}\nvoid main() {ivec2 ip=ivec2(gl_FragCoord.xy);vec3 pix=FsrEasuF(ip,con0,con1,con2,con3);gl_FragColor=vec4(pix,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [ffxFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const fsr1UpscalePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { ffxFunctions } from \"./ShadersInclude/ffxFunctions\";\n\nconst name = \"fsr1SharpenPixelShader\";\nconst shader = `#include<ffxFunctions>\n#define FSR_RCAS_LIMIT (0.25-(1.0/16.0))\nuniform sampler2D textureSampler;varying vec2 vUV;uniform vec4 con;vec3 FsrRcasLoadF(ivec2 p) {return texelFetch(textureSampler,clamp(p,ivec2(0),textureSize(textureSampler,0)-ivec2(1)),0).rgb;}\nvoid main() {ivec2 sp=ivec2(gl_FragCoord.xy);vec3 b=FsrRcasLoadF(sp+ivec2( 0,-1));vec3 d=FsrRcasLoadF(sp+ivec2(-1, 0));vec3 e=FsrRcasLoadF(sp);vec3 f=FsrRcasLoadF(sp+ivec2( 1, 0));vec3 h=FsrRcasLoadF(sp+ivec2( 0, 1));float bR=b.r; float bG=b.g; float bB=b.b;float dR=d.r; float dG=d.g; float dB=d.b;float eR=e.r; float eG=e.g; float eB=e.b;float fR=f.r; float fG=f.g; float fB=f.b;float hR=h.r; float hG=h.g; float hB=h.b;float bL=bB*0.5+(bR*0.5+bG);float dL=dB*0.5+(dR*0.5+dG);float eL=eB*0.5+(eR*0.5+eG);float fL=fB*0.5+(fR*0.5+fG);float hL=hB*0.5+(hR*0.5+hG);float nz=0.25*bL+0.25*dL+0.25*fL+0.25*hL-eL;nz=clamp(abs(nz)*APrxMedRcpF1(AMax3F1(AMax3F1(bL,dL,eL),fL,hL)-AMin3F1(AMin3F1(bL,dL,eL),fL,hL)),0.0,1.0);nz=-0.5*nz+1.0;float mn4R=min(AMin3F1(bR,dR,fR),hR);float mn4G=min(AMin3F1(bG,dG,fG),hG);float mn4B=min(AMin3F1(bB,dB,fB),hB);float mx4R=max(AMax3F1(bR,dR,fR),hR);float mx4G=max(AMax3F1(bG,dG,fG),hG);float mx4B=max(AMax3F1(bB,dB,fB),hB);vec2 peakC=vec2(1.0,-1.0*4.0);float hitMinR=min(mn4R,eR)*(1.0/(4.0*mx4R));float hitMinG=min(mn4G,eG)*(1.0/(4.0*mx4G));float hitMinB=min(mn4B,eB)*(1.0/(4.0*mx4B));float hitMaxR=(peakC.x-max(mx4R,eR))*(1.0/(4.0*mn4R+peakC.y));float hitMaxG=(peakC.x-max(mx4G,eG))*(1.0/(4.0*mn4G+peakC.y));float hitMaxB=(peakC.x-max(mx4B,eB))*(1.0/(4.0*mn4B+peakC.y));float lobeR=max(-hitMinR,hitMaxR);float lobeG=max(-hitMinG,hitMaxG);float lobeB=max(-hitMinB,hitMaxB);float lobe=max(-FSR_RCAS_LIMIT,min(AMax3F1(lobeR,lobeG,lobeB),0.0))*con.x;\n#ifdef FSR_RCAS_DENOISE\nlobe*=nz;\n#endif\nfloat rcpL=APrxMedRcpF1(4.0*lobe+1.0);float pixR=(lobe*bR+lobe*dR+lobe*hR+lobe*fR+eR)*rcpL;float pixG=(lobe*bG+lobe*dG+lobe*hG+lobe*fG+eG)*rcpL;float pixB=(lobe*bB+lobe*dB+lobe*hB+lobe*fB+eB)*rcpL;gl_FragColor=vec4(pixR,pixG,pixB,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [ffxFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const fsr1SharpenPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"ffxFunctions\";\nconst shader = `fn AMax3F1(x: f32,y: f32,z: f32)->f32 {return max(x,max(y,z));}\nfn AMax3F3(x: vec3f,y: vec3f,z: vec3f)->vec3f {return max(x,max(y,z));}\nfn AMin3F1(x: f32,y: f32,z: f32)->f32 {return min(x,min(y,z));}\nfn AMin3F3(x: vec3f,y: vec3f,z: vec3f)->vec3f {return min(x,min(y,z));}\nfn APrxLoRcpF1(a: f32)->f32 {return bitcast<f32>(u32(0x7ef07ebb)-bitcast<u32>(a));}\nfn APrxMedRcpF1(a: f32)->f32 {let b=bitcast<f32>(u32(0x7ef19fff)-bitcast<u32>(a));return b*(-b*a+f32(2.0));}\nfn APrxLoRsqF1(a: f32)->f32 {return bitcast<f32>(u32(0x5f347d74)-(bitcast<u32>(a)>>1));}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const ffxFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { ffxFunctionsWGSL } from \"./ShadersInclude/ffxFunctions\";\n\nconst name = \"fsr1UpscalePixelShader\";\nconst shader = `#include<ffxFunctions>\nvar textureSampler: texture_2d<f32>;var textureSamplerSampler: sampler;uniform con0: vec4f;uniform con1: vec4f;uniform con2: vec4f;uniform con3: vec4f;fn FsrEasuRF(p: vec2f)->vec4f {return textureGather(0,textureSampler,textureSamplerSampler,p);}\nfn FsrEasuGF(p: vec2f)->vec4f {return textureGather(1,textureSampler,textureSamplerSampler,p);}\nfn FsrEasuBF(p: vec2f)->vec4f {return textureGather(2,textureSampler,textureSamplerSampler,p);}\nfn FsrEasuTapF(\naC: ptr<function,vec3f>,\naW: ptr<function,f32>,\noff: vec2f,\ndir: vec2f,\nlen: vec2f,\nlob: f32,\nclp: f32,\nc: vec3f \n) { \nvar v: vec2f;v.x=(off.x*( dir.x))+(off.y*dir.y);v.y=(off.x*(-dir.y))+(off.y*dir.x);v*=len;var d2=v.x*v.x+v.y*v.y;d2=min(d2,clp);var wB=f32(2.0/5.0)*d2+f32(-1.0);var wA=lob*d2+(-1.0);wB*=wB;wA*=wA;wB=f32(25.0/16.0)*wB+f32(-(25.0/16.0-1.0));let w=wB*wA;*aC+=c*w;*aW+=w;}\nfn FsrEasuSetF(\ndir: ptr<function,vec2f>,\nlen: ptr<function,f32>,\npp: vec2f,\nbiS: bool,biT: bool,biU: bool,biV: bool,\nlA: f32,lB: f32,lC: f32,lD: f32,lE: f32\n) {var w=f32(0.0);if biS {w=(f32(1.0)-pp.x)*(f32(1.0)-pp.y);}\nif biT {w= pp.x *(f32(1.0)-pp.y);}\nif biU {w=(f32(1.0)-pp.x)* pp.y ;}\nif biV {w= pp.x* pp.y ;}\nlet dc=lD-lC;let cb=lC-lB;var lenX=max(abs(dc),abs(cb));lenX=APrxLoRcpF1(lenX);let dirX=lD-lB;dir.x+=dirX*w;lenX=saturate(abs(dirX)*lenX);lenX*=lenX;*len+=lenX*w;let ec=lE-lC;let ca=lC-lA;var lenY=max(abs(ec),abs(ca));lenY=APrxLoRcpF1(lenY);let dirY=lE-lA;dir.y+=dirY*w;lenY=saturate(abs(dirY)*lenY);lenY*=lenY;*len+=lenY*w;}\nfn FsrEasuF(\npix: ptr<function,vec3f>,\nip: vec2u,\ncon0: vec4f,\ncon1: vec4f,\ncon2: vec4f,\ncon3: vec4f\n) {var pp=vec2f(ip)*con0.xy+con0.zw;let fp=floor(pp);pp-=fp;let p0=fp*con1.xy+con1.zw;let p1=p0+con2.xy;let p2=p0+con2.zw;let p3=p0+con3.xy;let bczzR=FsrEasuRF(p0);let bczzG=FsrEasuGF(p0);let bczzB=FsrEasuBF(p0);let ijfeR=FsrEasuRF(p1);let ijfeG=FsrEasuGF(p1);let ijfeB=FsrEasuBF(p1);let klhgR=FsrEasuRF(p2);let klhgG=FsrEasuGF(p2);let klhgB=FsrEasuBF(p2);let zzonR=FsrEasuRF(p3);let zzonG=FsrEasuGF(p3);let zzonB=FsrEasuBF(p3);let bczzL=bczzB*vec4f(0.5)+(bczzR*vec4f(0.5)+bczzG);let ijfeL=ijfeB*vec4f(0.5)+(ijfeR*vec4f(0.5)+ijfeG);let klhgL=klhgB*vec4f(0.5)+(klhgR*vec4f(0.5)+klhgG);let zzonL=zzonB*vec4f(0.5)+(zzonR*vec4f(0.5)+zzonG);let bL=bczzL.x;let cL=bczzL.y;let iL=ijfeL.x;let jL=ijfeL.y;let fL=ijfeL.z;let eL=ijfeL.w;let kL=klhgL.x;let lL=klhgL.y;let hL=klhgL.z;let gL=klhgL.w;let oL=zzonL.z;let nL=zzonL.w;var dir=vec2f(0.0);var len=f32(0.0);FsrEasuSetF(&dir,&len,pp,true,false,false,false,bL,eL,fL,gL,jL);FsrEasuSetF(&dir,&len,pp,false,true ,false,false,cL,fL,gL,hL,kL);FsrEasuSetF(&dir,&len,pp,false,false,true ,false,fL,iL,jL,kL,nL);FsrEasuSetF(&dir,&len,pp,false,false,false,true ,gL,jL,kL,lL,oL);let dir2=dir*dir;var dirR=dir2.x+dir2.y;var zro=dirR<f32(1.0/32768.0);dirR=APrxLoRsqF1(dirR);dirR=select(dirR,f32(1.0),zro);dir.x=select(dir.x,f32(1.0),zro);dir*=vec2f(dirR);len=len*f32(0.5);len*=len;let stretch=(dir.x*dir.x+dir.y*dir.y)*APrxLoRcpF1(max(abs(dir.x),abs(dir.y)));let len2=vec2f(f32(1.0)+(stretch-f32(1.0))*len,f32(1.0)+f32(-0.5)*len);let lob=f32(0.5)+f32((1.0/4.0-0.04)-0.5)*len;let clp=APrxLoRcpF1(lob);let min4=min(AMin3F3(vec3f(ijfeR.z,ijfeG.z,ijfeB.z),vec3f(klhgR.w,klhgG.w,klhgB.w),vec3f(ijfeR.y,ijfeG.y,ijfeB.y)),\nvec3f(klhgR.x,klhgG.x,klhgB.x));let max4=max(AMax3F3(vec3f(ijfeR.z,ijfeG.z,ijfeB.z),vec3f(klhgR.w,klhgG.w,klhgB.w),vec3f(ijfeR.y,ijfeG.y,ijfeB.y)),\nvec3f(klhgR.x,klhgG.x,klhgB.x));var aC=vec3f(0.0);var aW=f32(0.0);FsrEasuTapF(&aC,&aW,vec2f( 0.0,-1.0)-pp,dir,len2,lob,clp,vec3f(bczzR.x,bczzG.x,bczzB.x)); \nFsrEasuTapF(&aC,&aW,vec2f( 1.0,-1.0)-pp,dir,len2,lob,clp,vec3f(bczzR.y,bczzG.y,bczzB.y)); \nFsrEasuTapF(&aC,&aW,vec2f(-1.0,1.0)-pp,dir,len2,lob,clp,vec3f(ijfeR.x,ijfeG.x,ijfeB.x)); \nFsrEasuTapF(&aC,&aW,vec2f( 0.0,1.0)-pp,dir,len2,lob,clp,vec3f(ijfeR.y,ijfeG.y,ijfeB.y)); \nFsrEasuTapF(&aC,&aW,vec2f( 0.0,0.0)-pp,dir,len2,lob,clp,vec3f(ijfeR.z,ijfeG.z,ijfeB.z)); \nFsrEasuTapF(&aC,&aW,vec2f(-1.0,0.0)-pp,dir,len2,lob,clp,vec3f(ijfeR.w,ijfeG.w,ijfeB.w)); \nFsrEasuTapF(&aC,&aW,vec2f( 1.0,1.0)-pp,dir,len2,lob,clp,vec3f(klhgR.x,klhgG.x,klhgB.x)); \nFsrEasuTapF(&aC,&aW,vec2f( 2.0,1.0)-pp,dir,len2,lob,clp,vec3f(klhgR.y,klhgG.y,klhgB.y)); \nFsrEasuTapF(&aC,&aW,vec2f( 2.0,0.0)-pp,dir,len2,lob,clp,vec3f(klhgR.z,klhgG.z,klhgB.z)); \nFsrEasuTapF(&aC,&aW,vec2f( 1.0,0.0)-pp,dir,len2,lob,clp,vec3f(klhgR.w,klhgG.w,klhgB.w)); \nFsrEasuTapF(&aC,&aW,vec2f( 1.0,2.0)-pp,dir,len2,lob,clp,vec3f(zzonR.z,zzonG.z,zzonB.z)); \nFsrEasuTapF(&aC,&aW,vec2f( 0.0,2.0)-pp,dir,len2,lob,clp,vec3f(zzonR.w,zzonG.w,zzonB.w)); \n*pix=min(max4,max(min4,aC*vec3f(1.0/aW)));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var pix: vec3f;let ip=vec2u(fragmentInputs.position.xy);FsrEasuF(&pix,ip,uniforms.con0,uniforms.con1,uniforms.con2,uniforms.con3);fragmentOutputs.color=vec4f(pix,1);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [ffxFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const fsr1UpscalePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { ffxFunctionsWGSL } from \"./ShadersInclude/ffxFunctions\";\n\nconst name = \"fsr1SharpenPixelShader\";\nconst shader = `#include<ffxFunctions>\n#define FSR_RCAS_LIMIT (0.25-(1.0/16.0))\nvar textureSampler: texture_2d<f32>;uniform con: vec4f;fn FsrRcasLoadF(p: vec2i)->vec4f {return textureLoad(textureSampler,clamp(p,vec2i(0),vec2i(textureDimensions(textureSampler,0))-vec2i(1)),0);}\nfn FsrRcasF(\npixR: ptr<function,f32>,\npixG: ptr<function,f32>,\npixB: ptr<function,f32>,\nip: vec2u,\ncon: vec4f \n) {let sp=vec2i(ip);let b=FsrRcasLoadF(sp+vec2i( 0,-1)).rgb;let d=FsrRcasLoadF(sp+vec2i(-1,0)).rgb;let e=FsrRcasLoadF(sp).rgb;let f=FsrRcasLoadF(sp+vec2i( 1,0)).rgb;let h=FsrRcasLoadF(sp+vec2i( 0,1)).rgb;let bR=b.r;let bG=b.g;let bB=b.b;let dR=d.r;let dG=d.g;let dB=d.b;let eR=e.r;let eG=e.g;let eB=e.b;let fR=f.r;let fG=f.g;let fB=f.b;let hR=h.r;let hG=h.g;let hB=h.b;let bL=bB*f32(0.5)+(bR*f32(0.5)+bG);let dL=dB*f32(0.5)+(dR*f32(0.5)+dG);let eL=eB*f32(0.5)+(eR*f32(0.5)+eG);let fL=fB*f32(0.5)+(fR*f32(0.5)+fG);let hL=hB*f32(0.5)+(hR*f32(0.5)+hG);var nz=f32(0.25)*bL+f32(0.25)*dL+f32(0.25)*fL+f32(0.25)*hL-eL;nz=saturate(abs(nz)*APrxMedRcpF1(AMax3F1(AMax3F1(bL,dL,eL),fL,hL)-AMin3F1(AMin3F1(bL,dL,eL),fL,hL)));nz=f32(-0.5)*nz+f32(1.0);let mn4R=min(AMin3F1(bR,dR,fR),hR);let mn4G=min(AMin3F1(bG,dG,fG),hG);let mn4B=min(AMin3F1(bB,dB,fB),hB);let mx4R=max(AMax3F1(bR,dR,fR),hR);let mx4G=max(AMax3F1(bG,dG,fG),hG);let mx4B=max(AMax3F1(bB,dB,fB),hB);let peakC=vec2f(1.0,-1.0*4.0);let hitMinR=min(mn4R,eR)*(1.0/(f32(4.0)*mx4R));let hitMinG=min(mn4G,eG)*(1.0/(f32(4.0)*mx4G));let hitMinB=min(mn4B,eB)*(1.0/(f32(4.0)*mx4B));let hitMaxR=(peakC.x-max(mx4R,eR))*(1.0/(f32(4.0)*mn4R+peakC.y));let hitMaxG=(peakC.x-max(mx4G,eG))*(1.0/(f32(4.0)*mn4G+peakC.y));let hitMaxB=(peakC.x-max(mx4B,eB))*(1.0/(f32(4.0)*mn4B+peakC.y));let lobeR=max(-hitMinR,hitMaxR);let lobeG=max(-hitMinG,hitMaxG);let lobeB=max(-hitMinB,hitMaxB);var lobe=max(f32(-FSR_RCAS_LIMIT),min(AMax3F1(lobeR,lobeG,lobeB),f32(0.0)))*con.x;\n#ifdef FSR_RCAS_DENOISE\nlobe*=nz;\n#endif\nlet rcpL=APrxMedRcpF1(f32(4.0)*lobe+f32(1.0));*pixR=(lobe*bR+lobe*dR+lobe*hR+lobe*fR+eR)*rcpL;*pixG=(lobe*bG+lobe*dG+lobe*hG+lobe*fG+eG)*rcpL;*pixB=(lobe*bB+lobe*dB+lobe*hB+lobe*fB+eB)*rcpL;return;}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var pixR: f32;var pixG: f32;var pixB: f32;let ip=vec2u(fragmentInputs.position.xy);FsrRcasF(&pixR,&pixG,&pixB,ip,uniforms.con);fragmentOutputs.color=vec4f(pixR,pixG,pixB,1);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [ffxFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const fsr1SharpenPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"sharpenPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec2 screenSize;uniform vec2 sharpnessAmounts;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec2 onePixel=vec2(1.0,1.0)/screenSize;vec4 color=texture2D(textureSampler,vUV);vec4 edgeDetection=texture2D(textureSampler,vUV+onePixel*vec2(0,-1)) +\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,0)) +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,0)) +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,1)) -\ncolor*4.0;gl_FragColor=max(vec4(color.rgb*sharpnessAmounts.y,color.a)-(sharpnessAmounts.x*vec4(edgeDetection.rgb,0)),0.);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const sharpenPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"stereoscopicInterlacePixelShader\";\nconst shader = `const vec3 TWO=vec3(2.0,2.0,2.0);varying vec2 vUV;uniform sampler2D camASampler;uniform sampler2D textureSampler;uniform vec2 stepSize;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{bool useCamA;bool useCamB;vec2 texCoord1;vec2 texCoord2;vec3 frag1;vec3 frag2;\n#ifdef IS_STEREOSCOPIC_HORIZ\nuseCamB=vUV.x>0.5;useCamA=!useCamB;texCoord1=vec2(useCamB ? (vUV.x-0.5)*2.0 : vUV.x*2.0,vUV.y);texCoord2=vec2(texCoord1.x+stepSize.x,vUV.y);\n#else\n#ifdef IS_STEREOSCOPIC_INTERLACED\nfloat rowNum=floor(vUV.y/stepSize.y);useCamA=mod(rowNum,2.0)==1.0;useCamB=mod(rowNum,2.0)==0.0;texCoord1=vec2(vUV.x,vUV.y);texCoord2=vec2(vUV.x,vUV.y);\n#else\nuseCamB=vUV.y>0.5;useCamA=!useCamB;texCoord1=vec2(vUV.x,useCamB ? (vUV.y-0.5)*2.0 : vUV.y*2.0);texCoord2=vec2(vUV.x,texCoord1.y+stepSize.y);\n#endif\n#endif\nif (useCamB){frag1=texture2D(textureSampler,texCoord1).rgb;frag2=texture2D(textureSampler,texCoord2).rgb;}else if (useCamA){frag1=texture2D(camASampler ,texCoord1).rgb;frag2=texture2D(camASampler ,texCoord2).rgb;}else {discard;}\ngl_FragColor=vec4((frag1+frag2)/TWO,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const stereoscopicInterlacePixelShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\n\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type Nullable } from \"../types\";\r\n\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { type ThinTonemapPostProcessOptions, type TonemappingOperator, ThinTonemapPostProcess } from \"./thinTonemapPostProcess\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nexport type ToneMapPostProcessOptions = ThinTonemapPostProcessOptions & PostProcessOptions;\r\n\r\n/**\r\n * Defines a post process to apply tone mapping\r\n */\r\nexport class TonemapPostProcess extends PostProcess {\r\n    /**\r\n     * Defines the required exposure adjustment\r\n     */\r\n    @serialize()\r\n    public get exposureAdjustment() {\r\n        return this._effectWrapper.exposureAdjustment;\r\n    }\r\n\r\n    public set exposureAdjustment(value: number) {\r\n        this._effectWrapper.exposureAdjustment = value;\r\n    }\r\n\r\n    /**\r\n     * Gets the operator used for tonemapping\r\n     */\r\n    @serialize()\r\n    public get operator() {\r\n        return this._effectWrapper.operator;\r\n    }\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"TonemapPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"TonemapPostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinTonemapPostProcess;\r\n\r\n    /**\r\n     * Creates a new TonemapPostProcess\r\n     * @param name defines the name of the postprocess\r\n     * @param operator defines the operator to use\r\n     * @param exposureAdjustment defines the required exposure adjustment\r\n     * @param camera defines the camera to use (can be null)\r\n     * @param samplingMode defines the required sampling mode (BABYLON.Texture.BILINEAR_SAMPLINGMODE by default)\r\n     * @param engine defines the hosting engine (can be ignore if camera is set)\r\n     * @param textureType defines the texture format to use (BABYLON.Engine.TEXTURETYPE_UNSIGNED_BYTE by default)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        operator: TonemappingOperator,\r\n        exposureAdjustment: number,\r\n        camera: Nullable<Camera> | ToneMapPostProcessOptions,\r\n        samplingMode: number = Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n        engine?: AbstractEngine,\r\n        textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        reusable?: boolean\r\n    ) {\r\n        const cameraIsCamera = camera === null || camera instanceof Camera;\r\n\r\n        const localOptions = {\r\n            operator,\r\n            exposureAdjustment,\r\n            uniforms: ThinTonemapPostProcess.Uniforms,\r\n            camera: cameraIsCamera ? camera : undefined,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n        };\r\n\r\n        if (!cameraIsCamera) {\r\n            Object.assign(localOptions, camera);\r\n        }\r\n\r\n        super(name, ThinTonemapPostProcess.FragmentUrl, {\r\n            effectWrapper: cameraIsCamera || !camera.effectWrapper ? new ThinTonemapPostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string): Nullable<TonemapPostProcess> {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new TonemapPostProcess(\r\n                    parsedPostProcess.name,\r\n                    parsedPostProcess.operator,\r\n                    parsedPostProcess.exposureAdjustment,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.textureType,\r\n                    parsedPostProcess.reusable\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for tonemapPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterTonemapPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.TonemapPostProcess\", TonemapPostProcess);\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { serializeAsVector3, serialize, serializeAsMeshReference } from \"../Misc/decorators\";\r\nimport { type SmartArray } from \"../Misc/smartArray\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Vector2, Vector3, Matrix } from \"../Maths/math.vector.pure\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect, type IEffectCreationOptions } from \"../Materials/effect.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { StandardMaterial } from \"../Materials/standardMaterial.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { CreatePlane } from \"../Meshes/Builders/planeBuilder.pure\";\r\nimport { Color4, Color3 } from \"../Maths/math.color.pure\";\r\nimport { Viewport } from \"../Maths/math.viewport\";\r\nimport { type Nullable } from \"../types\";\r\nimport { BindBonesParameters, BindMorphTargetParameters, PrepareDefinesAndAttributesForMorphTargets, PushAttributesForInstances } from \"../Materials/materialHelper.functions\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { EffectFallbacks } from \"core/Materials/effectFallbacks\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\n\r\n/**\r\n *  Inspired by https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-13-volumetric-light-scattering-post-process\r\n */\r\nexport class VolumetricLightScatteringPostProcess extends PostProcess {\r\n    // Members\r\n    private _volumetricLightScatteringRTT: RenderTargetTexture;\r\n    private _viewPort: Viewport;\r\n    private _screenCoordinates: Vector2 = Vector2.Zero();\r\n\r\n    /**\r\n     * If not undefined, the mesh position is computed from the attached node position\r\n     */\r\n    public attachedNode: { position: Vector3 };\r\n\r\n    /**\r\n     * Custom position of the mesh. Used if \"useCustomMeshPosition\" is set to \"true\"\r\n     */\r\n    @serializeAsVector3()\r\n    public customMeshPosition: Vector3 = Vector3.Zero();\r\n\r\n    /**\r\n     * Set if the post-process should use a custom position for the light source (true) or the internal mesh position (false)\r\n     */\r\n    @serialize()\r\n    public useCustomMeshPosition: boolean = false;\r\n\r\n    /**\r\n     * If the post-process should inverse the light scattering direction\r\n     */\r\n    @serialize()\r\n    public invert: boolean = true;\r\n\r\n    /**\r\n     * The internal mesh used by the post-process\r\n     */\r\n    @serializeAsMeshReference()\r\n    public mesh: Mesh;\r\n\r\n    /**\r\n     * @internal\r\n     * VolumetricLightScatteringPostProcess.useDiffuseColor is no longer used, use the mesh material directly instead\r\n     */\r\n    public get useDiffuseColor(): boolean {\r\n        Logger.Warn(\"VolumetricLightScatteringPostProcess.useDiffuseColor is no longer used, use the mesh material directly instead\");\r\n        return false;\r\n    }\r\n\r\n    public set useDiffuseColor(useDiffuseColor: boolean) {\r\n        Logger.Warn(\"VolumetricLightScatteringPostProcess.useDiffuseColor is no longer used, use the mesh material directly instead\");\r\n    }\r\n\r\n    /**\r\n     * Array containing the excluded meshes not rendered in the internal pass\r\n     */\r\n    @serialize()\r\n    public excludedMeshes: AbstractMesh[] = [];\r\n\r\n    /**\r\n     * Array containing the only meshes rendered in the internal pass.\r\n     * If this array is not empty, only the meshes from this array are rendered in the internal pass\r\n     */\r\n    @serialize()\r\n    public includedMeshes: AbstractMesh[] = [];\r\n\r\n    /**\r\n     * Controls the overall intensity of the post-process\r\n     */\r\n    @serialize()\r\n    public exposure = 0.3;\r\n\r\n    /**\r\n     * Dissipates each sample's contribution in range [0, 1]\r\n     */\r\n    @serialize()\r\n    public decay = 0.96815;\r\n\r\n    /**\r\n     * Controls the overall intensity of each sample\r\n     */\r\n    @serialize()\r\n    public weight = 0.58767;\r\n\r\n    /**\r\n     * Controls the density of each sample\r\n     */\r\n    @serialize()\r\n    public density = 0.926;\r\n\r\n    /**\r\n     * @constructor\r\n     * @param name The post-process name\r\n     * @param ratio The size of the post-process and/or internal pass (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)\r\n     * @param camera The camera that the post-process will be attached to\r\n     * @param mesh The mesh used to create the light scattering\r\n     * @param samples The post-process quality, default 100\r\n     * @param samplingMode The post-process filtering mode\r\n     * @param engine The babylon engine\r\n     * @param reusable If the post-process is reusable\r\n     * @param scene The constructor needs a scene reference to initialize internal components. If \"camera\" is null a \"scene\" must be provided\r\n     */\r\n    constructor(\r\n        name: string,\r\n        ratio: any,\r\n        camera: Nullable<Camera>,\r\n        mesh?: Mesh,\r\n        samples: number = 100,\r\n        samplingMode: number = Texture.BILINEAR_SAMPLINGMODE,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        scene?: Scene\r\n    ) {\r\n        const selectedEngine = engine ?? camera?.getScene().getEngine() ?? scene?.getEngine();\r\n        const shaderLanguage = selectedEngine?.isWebGPU && !PostProcess.ForceGLSL ? ShaderLanguage.WGSL : ShaderLanguage.GLSL;\r\n        super(\r\n            name,\r\n            \"volumetricLightScattering\",\r\n            [\"decay\", \"exposure\", \"weight\", \"meshPositionOnScreen\", \"density\"],\r\n            [\"lightScatteringSampler\"],\r\n            ratio.postProcessRatio || ratio,\r\n            camera,\r\n            samplingMode,\r\n            selectedEngine,\r\n            reusable,\r\n            \"#define NUM_SAMPLES \" + samples,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            undefined,\r\n            shaderLanguage\r\n        );\r\n        scene = camera?.getScene() ?? scene ?? this._scene; // parameter \"scene\" can be null.\r\n\r\n        engine = scene.getEngine();\r\n        this._viewPort = new Viewport(0, 0, 1, 1).toGlobal(engine.getRenderWidth(), engine.getRenderHeight());\r\n\r\n        // Configure mesh\r\n        this.mesh = mesh ?? VolumetricLightScatteringPostProcess.CreateDefaultMesh(\"VolumetricLightScatteringMesh\", scene);\r\n        // Configure\r\n        this._createPass(scene, ratio.passRatio || ratio);\r\n\r\n        this.onActivate = (camera: Camera) => {\r\n            if (!this.isSupported) {\r\n                this.dispose(camera);\r\n            }\r\n\r\n            this.onActivate = null;\r\n        };\r\n\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            this._updateMeshScreenCoordinates(scene);\r\n\r\n            effect.setTexture(\"lightScatteringSampler\", this._volumetricLightScatteringRTT);\r\n            effect.setFloat(\"exposure\", this.exposure);\r\n            effect.setFloat(\"decay\", this.decay);\r\n            effect.setFloat(\"weight\", this.weight);\r\n            effect.setFloat(\"density\", this.density);\r\n            effect.setVector2(\"meshPositionOnScreen\", this._screenCoordinates);\r\n        });\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(\r\n                Promise.all([\r\n                    import(\"../ShadersWGSL/volumetricLightScattering.fragment\"),\r\n                    import(\"../ShadersWGSL/volumetricLightScatteringPass.vertex\"),\r\n                    import(\"../ShadersWGSL/volumetricLightScatteringPass.fragment\"),\r\n                ])\r\n            );\r\n        } else {\r\n            list.push(\r\n                Promise.all([\r\n                    import(\"../Shaders/volumetricLightScattering.fragment\"),\r\n                    import(\"../Shaders/volumetricLightScatteringPass.vertex\"),\r\n                    import(\"../Shaders/volumetricLightScatteringPass.fragment\"),\r\n                ])\r\n            );\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    /**\r\n     * Returns the string \"VolumetricLightScatteringPostProcess\"\r\n     * @returns \"VolumetricLightScatteringPostProcess\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"VolumetricLightScatteringPostProcess\";\r\n    }\r\n\r\n    private _isReady(subMesh: SubMesh, useInstances: boolean): boolean {\r\n        const mesh = subMesh.getMesh();\r\n\r\n        // Render this.mesh as default\r\n        if (mesh === this.mesh && mesh.material) {\r\n            return mesh.material.isReady(mesh);\r\n        }\r\n\r\n        const renderingMaterial = mesh._internalAbstractMeshDataInfo._materialForRenderPass?.[this._scene.getEngine().currentRenderPassId];\r\n\r\n        if (renderingMaterial) {\r\n            return renderingMaterial.isReadyForSubMesh(mesh, subMesh, useInstances);\r\n        }\r\n\r\n        const defines = [];\r\n        const attribs = [VertexBuffer.PositionKind];\r\n        const material = subMesh.getMaterial();\r\n\r\n        let uv1 = false;\r\n        let uv2 = false;\r\n        const color = false;\r\n\r\n        // Alpha test\r\n        if (material) {\r\n            const needAlphaTesting = material.needAlphaTestingForMesh(mesh);\r\n            if (needAlphaTesting) {\r\n                defines.push(\"#define ALPHATEST\");\r\n            }\r\n\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                attribs.push(VertexBuffer.UVKind);\r\n                defines.push(\"#define UV1\");\r\n                uv1 = needAlphaTesting;\r\n            }\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n                attribs.push(VertexBuffer.UV2Kind);\r\n                defines.push(\"#define UV2\");\r\n                uv2 = needAlphaTesting;\r\n            }\r\n        }\r\n\r\n        // Bones\r\n        const fallbacks = new EffectFallbacks();\r\n        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n            attribs.push(VertexBuffer.MatricesIndicesKind);\r\n            attribs.push(VertexBuffer.MatricesWeightsKind);\r\n            if (mesh.numBoneInfluencers > 4) {\r\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n            }\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n            if (mesh.numBoneInfluencers > 0) {\r\n                fallbacks.addCPUSkinningFallback(0, mesh);\r\n            }\r\n\r\n            const skeleton = mesh.skeleton;\r\n            if (skeleton.isUsingTextureForMatrices) {\r\n                defines.push(\"#define BONETEXTURE\");\r\n            } else {\r\n                defines.push(\"#define BonesPerMesh \" + (skeleton.bones.length + 1));\r\n            }\r\n        } else {\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n        }\r\n\r\n        // Morph targets\r\n        const numMorphInfluencers = mesh.morphTargetManager\r\n            ? PrepareDefinesAndAttributesForMorphTargets(\r\n                  mesh.morphTargetManager,\r\n                  defines,\r\n                  attribs,\r\n                  mesh,\r\n                  true, // usePositionMorph\r\n                  false, // useNormalMorph\r\n                  false, // useTangentMorph\r\n                  uv1, // useUVMorph\r\n                  uv2, // useUV2Morph\r\n                  color // useColorMorph\r\n              )\r\n            : 0;\r\n\r\n        // Instances\r\n        if (useInstances) {\r\n            defines.push(\"#define INSTANCES\");\r\n            PushAttributesForInstances(attribs);\r\n            if (subMesh.getRenderingMesh().hasThinInstances) {\r\n                defines.push(\"#define THIN_INSTANCES\");\r\n            }\r\n        }\r\n\r\n        // Baked vertex animations\r\n        const bvaManager = mesh.bakedVertexAnimationManager;\r\n        if (bvaManager && bvaManager.isEnabled) {\r\n            defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\r\n            if (useInstances) {\r\n                attribs.push(\"bakedVertexAnimationSettingsInstanced\");\r\n            }\r\n        }\r\n\r\n        // Get correct effect\r\n        const drawWrapper = subMesh._getDrawWrapper(undefined, true)!;\r\n        const cachedDefines = drawWrapper.defines;\r\n        const join = defines.join(\"\\n\");\r\n        if (cachedDefines !== join) {\r\n            const engine = mesh.getScene().getEngine();\r\n            const uniforms = [\r\n                \"world\",\r\n                \"mBones\",\r\n                \"boneTextureInfo\",\r\n                \"viewProjection\",\r\n                \"diffuseMatrix\",\r\n                \"morphTargetInfluences\",\r\n                \"morphTargetCount\",\r\n                \"morphTargetTextureInfo\",\r\n                \"morphTargetTextureIndices\",\r\n                \"bakedVertexAnimationSettings\",\r\n                \"bakedVertexAnimationTextureSizeInverted\",\r\n                \"bakedVertexAnimationTime\",\r\n                \"bakedVertexAnimationTexture\",\r\n            ];\r\n            const samplers = [\"diffuseSampler\", \"morphTargets\", \"boneSampler\", \"bakedVertexAnimationTexture\"];\r\n\r\n            drawWrapper.setEffect(\r\n                engine.createEffect(\r\n                    \"volumetricLightScatteringPass\",\r\n                    <IEffectCreationOptions>{\r\n                        attributes: attribs,\r\n                        uniformsNames: uniforms,\r\n                        uniformBuffersNames: [],\r\n                        samplers: samplers,\r\n                        defines: join,\r\n                        fallbacks: fallbacks,\r\n                        onCompiled: null,\r\n                        onError: null,\r\n                        indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                        shaderLanguage: engine.isWebGPU && !PostProcess.ForceGLSL ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n                    },\r\n                    engine\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        return drawWrapper.effect!.isReady();\r\n    }\r\n\r\n    /**\r\n     * Sets the new light position for light scattering effect\r\n     * @param position The new custom light position\r\n     */\r\n    public setCustomMeshPosition(position: Vector3): void {\r\n        this.customMeshPosition = position;\r\n    }\r\n\r\n    /**\r\n     * Returns the light position for light scattering effect\r\n     * @returns Vector3 The custom light position\r\n     */\r\n    public getCustomMeshPosition(): Vector3 {\r\n        return this.customMeshPosition;\r\n    }\r\n\r\n    /**\r\n     * Disposes the internal assets and detaches the post-process from the camera\r\n     * @param camera The camera from which to detach the post-process\r\n     */\r\n    public override dispose(camera: Camera): void {\r\n        const rttIndex = camera.getScene().customRenderTargets.indexOf(this._volumetricLightScatteringRTT);\r\n        if (rttIndex !== -1) {\r\n            camera.getScene().customRenderTargets.splice(rttIndex, 1);\r\n        }\r\n\r\n        this._volumetricLightScatteringRTT.dispose();\r\n        super.dispose(camera);\r\n    }\r\n\r\n    /**\r\n     * Returns the render target texture used by the post-process\r\n     * @returns the render target texture used by the post-process\r\n     */\r\n    public getPass(): RenderTargetTexture {\r\n        return this._volumetricLightScatteringRTT;\r\n    }\r\n\r\n    // Private methods\r\n    private _meshExcluded(mesh: AbstractMesh) {\r\n        if ((this.includedMeshes.length > 0 && this.includedMeshes.indexOf(mesh) === -1) || (this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1)) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    private _createPass(scene: Scene, ratio: number): void {\r\n        const engine = scene.getEngine();\r\n\r\n        this._volumetricLightScatteringRTT = new RenderTargetTexture(\r\n            \"volumetricLightScatteringMap\",\r\n            { width: engine.getRenderWidth() * ratio, height: engine.getRenderHeight() * ratio },\r\n            scene,\r\n            false,\r\n            true,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        );\r\n        this._volumetricLightScatteringRTT.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._volumetricLightScatteringRTT.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._volumetricLightScatteringRTT.renderList = null;\r\n        this._volumetricLightScatteringRTT.renderParticles = false;\r\n        this._volumetricLightScatteringRTT.ignoreCameraViewport = true;\r\n\r\n        const camera = this.getCamera();\r\n        if (camera) {\r\n            camera.customRenderTargets.push(this._volumetricLightScatteringRTT);\r\n        } else {\r\n            scene.customRenderTargets.push(this._volumetricLightScatteringRTT);\r\n        }\r\n\r\n        // Custom render function for submeshes\r\n        const renderSubMesh = (subMesh: SubMesh): void => {\r\n            const renderingMesh = subMesh.getRenderingMesh();\r\n            const effectiveMesh = subMesh.getEffectiveMesh();\r\n            if (this._meshExcluded(renderingMesh)) {\r\n                return;\r\n            }\r\n\r\n            effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;\r\n\r\n            const material = subMesh.getMaterial();\r\n\r\n            if (!material) {\r\n                return;\r\n            }\r\n\r\n            const scene = renderingMesh.getScene();\r\n            const engine = scene.getEngine();\r\n\r\n            // Culling\r\n            engine.setState(material.backFaceCulling, undefined, undefined, undefined, material.cullBackFaces);\r\n\r\n            // Managing instances\r\n            const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n\r\n            if (batch.mustReturn) {\r\n                return;\r\n            }\r\n\r\n            const hardwareInstancedRendering = engine.getCaps().instancedArrays && (batch.visibleInstances[subMesh._id] !== null || renderingMesh.hasThinInstances);\r\n\r\n            if (this._isReady(subMesh, hardwareInstancedRendering)) {\r\n                const renderingMaterial = effectiveMesh._internalAbstractMeshDataInfo._materialForRenderPass?.[engine.currentRenderPassId];\r\n\r\n                let drawWrapper = subMesh._getDrawWrapper();\r\n                if (renderingMesh === this.mesh && !drawWrapper) {\r\n                    drawWrapper = material._getDrawWrapper();\r\n                }\r\n\r\n                if (!drawWrapper) {\r\n                    return;\r\n                }\r\n\r\n                const effect = drawWrapper.effect!;\r\n\r\n                engine.enableEffect(drawWrapper);\r\n                if (!hardwareInstancedRendering) {\r\n                    renderingMesh._bind(subMesh, effect, material.fillMode);\r\n                }\r\n\r\n                if (renderingMesh === this.mesh) {\r\n                    material.bind(effectiveMesh.getWorldMatrix(), renderingMesh);\r\n                } else if (renderingMaterial) {\r\n                    renderingMaterial.bindForSubMesh(effectiveMesh.getWorldMatrix(), effectiveMesh as Mesh, subMesh);\r\n                } else {\r\n                    effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\r\n\r\n                    // Alpha test\r\n                    if (material.needAlphaTestingForMesh(effectiveMesh)) {\r\n                        const alphaTexture = material.getAlphaTestTexture();\r\n\r\n                        if (alphaTexture) {\r\n                            effect.setTexture(\"diffuseSampler\", alphaTexture);\r\n                            effect.setMatrix(\"diffuseMatrix\", alphaTexture.getTextureMatrix());\r\n                        }\r\n                    }\r\n\r\n                    // Bones\r\n                    BindBonesParameters(renderingMesh, effect);\r\n\r\n                    // Morph targets\r\n                    BindMorphTargetParameters(renderingMesh, effect);\r\n                    if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\r\n                        renderingMesh.morphTargetManager._bind(effect);\r\n                    }\r\n\r\n                    // Baked vertex animations\r\n                    const bvaManager = subMesh.getMesh().bakedVertexAnimationManager;\r\n                    if (bvaManager && bvaManager.isEnabled) {\r\n                        bvaManager.bind(effect, hardwareInstancedRendering);\r\n                    }\r\n                }\r\n\r\n                if (hardwareInstancedRendering && renderingMesh.hasThinInstances) {\r\n                    effect.setMatrix(\"world\", effectiveMesh.getWorldMatrix());\r\n                }\r\n\r\n                // Draw\r\n                renderingMesh._processRendering(effectiveMesh, subMesh, effect, Material.TriangleFillMode, batch, hardwareInstancedRendering, (isInstance, world) => {\r\n                    if (!isInstance) {\r\n                        effect.setMatrix(\"world\", world);\r\n                    }\r\n                });\r\n            }\r\n        };\r\n\r\n        // Render target texture callbacks\r\n        let savedSceneClearColor: Color4;\r\n        const sceneClearColor = new Color4(0.0, 0.0, 0.0, 1.0);\r\n\r\n        this._volumetricLightScatteringRTT.onBeforeRenderObservable.add((): void => {\r\n            savedSceneClearColor = scene.clearColor;\r\n            scene.clearColor = sceneClearColor;\r\n        });\r\n\r\n        this._volumetricLightScatteringRTT.onAfterRenderObservable.add((): void => {\r\n            scene.clearColor = savedSceneClearColor;\r\n        });\r\n\r\n        this._volumetricLightScatteringRTT.customIsReadyFunction = (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => {\r\n            if ((preWarm || refreshRate === 0) && mesh.subMeshes) {\r\n                for (let i = 0; i < mesh.subMeshes.length; ++i) {\r\n                    const subMesh = mesh.subMeshes[i];\r\n                    const material = subMesh.getMaterial();\r\n                    const renderingMesh = subMesh.getRenderingMesh();\r\n\r\n                    if (!material) {\r\n                        continue;\r\n                    }\r\n\r\n                    const batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());\r\n                    const hardwareInstancedRendering = engine.getCaps().instancedArrays && (batch.visibleInstances[subMesh._id] !== null || renderingMesh.hasThinInstances);\r\n\r\n                    if (!this._isReady(subMesh, hardwareInstancedRendering)) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return true;\r\n        };\r\n\r\n        this._volumetricLightScatteringRTT.customRenderFunction = (\r\n            opaqueSubMeshes: SmartArray<SubMesh>,\r\n            alphaTestSubMeshes: SmartArray<SubMesh>,\r\n            transparentSubMeshes: SmartArray<SubMesh>,\r\n            depthOnlySubMeshes: SmartArray<SubMesh>\r\n        ): void => {\r\n            const engine = scene.getEngine();\r\n            let index: number;\r\n\r\n            if (depthOnlySubMeshes.length) {\r\n                engine.setColorWrite(false);\r\n                for (index = 0; index < depthOnlySubMeshes.length; index++) {\r\n                    renderSubMesh(depthOnlySubMeshes.data[index]);\r\n                }\r\n                engine.setColorWrite(true);\r\n            }\r\n\r\n            for (index = 0; index < opaqueSubMeshes.length; index++) {\r\n                renderSubMesh(opaqueSubMeshes.data[index]);\r\n            }\r\n\r\n            for (index = 0; index < alphaTestSubMeshes.length; index++) {\r\n                renderSubMesh(alphaTestSubMeshes.data[index]);\r\n            }\r\n\r\n            if (transparentSubMeshes.length) {\r\n                // Sort sub meshes\r\n                for (index = 0; index < transparentSubMeshes.length; index++) {\r\n                    const submesh = transparentSubMeshes.data[index];\r\n                    const boundingInfo = submesh.getBoundingInfo();\r\n\r\n                    if (boundingInfo && scene.activeCamera) {\r\n                        submesh._alphaIndex = submesh.getMesh().alphaIndex;\r\n                        submesh._distanceToCamera = boundingInfo.boundingSphere.centerWorld.subtract(scene.activeCamera.position).length();\r\n                    }\r\n                }\r\n\r\n                const sortedArray = transparentSubMeshes.data.slice(0, transparentSubMeshes.length);\r\n                sortedArray.sort((a, b) => {\r\n                    // Alpha index first\r\n                    if (a._alphaIndex > b._alphaIndex) {\r\n                        return 1;\r\n                    }\r\n                    if (a._alphaIndex < b._alphaIndex) {\r\n                        return -1;\r\n                    }\r\n\r\n                    // Then distance to camera\r\n                    if (a._distanceToCamera < b._distanceToCamera) {\r\n                        return 1;\r\n                    }\r\n                    if (a._distanceToCamera > b._distanceToCamera) {\r\n                        return -1;\r\n                    }\r\n\r\n                    return 0;\r\n                });\r\n\r\n                // Render sub meshes\r\n                engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n                for (index = 0; index < sortedArray.length; index++) {\r\n                    renderSubMesh(sortedArray[index]);\r\n                }\r\n                engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n            }\r\n        };\r\n    }\r\n\r\n    private _updateMeshScreenCoordinates(scene: Scene): void {\r\n        const transform = scene.getTransformMatrix();\r\n        let meshPosition: Vector3;\r\n\r\n        if (this.useCustomMeshPosition) {\r\n            meshPosition = this.customMeshPosition;\r\n        } else if (this.attachedNode) {\r\n            meshPosition = this.attachedNode.position;\r\n        } else {\r\n            meshPosition = this.mesh.parent ? this.mesh.getAbsolutePosition() : this.mesh.position;\r\n        }\r\n\r\n        const pos = Vector3.Project(meshPosition, Matrix.Identity(), transform, this._viewPort);\r\n\r\n        this._screenCoordinates.x = pos.x / this._viewPort.width;\r\n        this._screenCoordinates.y = pos.y / this._viewPort.height;\r\n\r\n        if (this.invert) {\r\n            this._screenCoordinates.y = 1.0 - this._screenCoordinates.y;\r\n        }\r\n    }\r\n\r\n    // Static methods\r\n    /**\r\n     * Creates a default mesh for the Volumeric Light Scattering post-process\r\n     * @param name The mesh name\r\n     * @param scene The scene where to create the mesh\r\n     * @returns the default mesh\r\n     */\r\n    public static CreateDefaultMesh(name: string, scene: Scene): Mesh {\r\n        const mesh = CreatePlane(name, { size: 1 }, scene);\r\n        mesh.billboardMode = AbstractMesh.BILLBOARDMODE_ALL;\r\n\r\n        const material = new StandardMaterial(name + \"Material\", scene);\r\n        material.emissiveColor = new Color3(1, 1, 1);\r\n\r\n        mesh.material = material;\r\n\r\n        return mesh;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for volumetricLightScatteringPostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterVolumetricLightScatteringPostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.VolumetricLightScatteringPostProcess\", VolumetricLightScatteringPostProcess);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"pointCloudVertexDeclaration\";\nconst shader = `#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const pointCloudVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { pointCloudVertexDeclaration } from \"./ShadersInclude/pointCloudVertexDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { pointCloudVertex } from \"./ShadersInclude/pointCloudVertex\";\n\nconst name = \"depthVertexShader\";\nconst shader = `attribute vec3 position;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\n#include<instancesDeclaration>\nuniform mat4 viewProjection;uniform vec2 depthValues;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;uniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#ifdef STORE_CAMERASPACE_Z\nuniform mat4 view;varying vec4 vViewPos;\n#endif\n#include<pointCloudVertexDeclaration>\nvarying float vDepthMetric;\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void)\n{vec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\n#include<clipPlaneVertex>\ngl_Position=viewProjection*worldPos;\n#ifdef STORE_CAMERASPACE_Z\nvViewPos=view*worldPos;\n#else\n#ifdef USE_REVERSE_DEPTHBUFFER\nvDepthMetric=((-gl_Position.z+depthValues.x)/(depthValues.y));\n#else\nvDepthMetric=((gl_Position.z+depthValues.x)/(depthValues.y));\n#endif\n#endif\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#include<pointCloudVertex>\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, clipPlaneVertexDeclaration, instancesDeclaration, pointCloudVertexDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex, pointCloudVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const depthVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"volumetricLightScatteringPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform sampler2D lightScatteringSampler;uniform float decay;uniform float exposure;uniform float weight;uniform float density;uniform vec2 meshPositionOnScreen;varying vec2 vUV;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec2 tc=vUV;vec2 deltaTexCoord=(tc-meshPositionOnScreen.xy);deltaTexCoord*=1.0/float(NUM_SAMPLES)*density;float illuminationDecay=1.0;vec4 color=texture2D(lightScatteringSampler,tc)*0.4;for(int i=0; i<NUM_SAMPLES; i++) {tc-=deltaTexCoord;vec4 dataSample=texture2D(lightScatteringSampler,tc)*0.4;dataSample*=illuminationDecay*weight;color+=dataSample;illuminationDecay*=decay;}\nvec4 realColor=texture2D(textureSampler,vUV);gl_FragColor=((vec4((vec3(color.r,color.g,color.b)*exposure),realColor.a))+(realColor*(1.5-0.4)));\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const volumetricLightScatteringPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"volumetricLightScatteringPassVertexShader\";\nconst shader = `attribute vec3 position;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\nuniform mat4 viewProjection;uniform vec2 depthValues;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;uniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void)\n{vec3 positionUpdated=position;\n#if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV1)\nvec2 uvUpdated=uv;\n#endif\n#if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV2)\nvec2 uv2Updated=uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, instancesDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const volumetricLightScatteringPassVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"volumetricLightScatteringPassPixelShader\";\nconst shader = `#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;\n#endif\n#if defined(ALPHATEST)\nuniform sampler2D diffuseSampler;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{\n#if defined(ALPHATEST)\nvec4 diffuseColor=texture2D(diffuseSampler,vUV);if (diffuseColor.a<0.4)\ndiscard;\n#endif\ngl_FragColor=vec4(0.0,0.0,0.0,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const volumetricLightScatteringPassPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"volumetricLightScatteringPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var lightScatteringSamplerSampler: sampler;var lightScatteringSampler: texture_2d<f32>;uniform decay: f32;uniform exposure: f32;uniform weight: f32;uniform density: f32;uniform meshPositionOnScreen: vec2f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvar tc: vec2f=input.vUV;var deltaTexCoord: vec2f=tc-uniforms.meshPositionOnScreen;deltaTexCoord*=1.0/f32(NUM_SAMPLES)*uniforms.density;var illuminationDecay: f32=1.0;var color: vec4f=textureSample(lightScatteringSampler,lightScatteringSamplerSampler,tc)*0.4;for (var i: i32=0; i<NUM_SAMPLES; i++) {tc-=deltaTexCoord;var dataSample: vec4f=textureSample(lightScatteringSampler,lightScatteringSamplerSampler,tc)*0.4;dataSample*=illuminationDecay*uniforms.weight;color+=dataSample;illuminationDecay*=uniforms.decay;}\nlet realColor: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);fragmentOutputs.color=vec4f(color.rgb*uniforms.exposure,realColor.a)+realColor*(1.5-0.4);\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const volumetricLightScatteringPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"volumetricLightScatteringPassVertexShader\";\nconst shader = `attribute position: vec3f;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;uniform depthValues: vec2f;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vUV: vec2f;uniform diffuseMatrix: mat4x4f;\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;\n#if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV1)\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV2)\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvertexOutputs.position=uniforms.viewProjection*finalWorld*vec4f(positionUpdated,1.0);\n#if defined(ALPHATEST) || defined(NEED_UV)\n#ifdef UV1\nvertexOutputs.vUV=(uniforms.diffuseMatrix*vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef UV2\nvertexOutputs.vUV=(uniforms.diffuseMatrix*vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, instancesDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const volumetricLightScatteringPassVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"volumetricLightScatteringPassPixelShader\";\nconst shader = `#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vUV: vec2f;\n#endif\n#if defined(ALPHATEST)\nvar diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#if defined(ALPHATEST)\nlet diffuseColor: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,input.vUV);if (diffuseColor.a<0.4) {discard;}\n#endif\nfragmentOutputs.color=vec4f(0.0,0.0,0.0,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const volumetricLightScatteringPassPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"vrMultiviewToSingleviewPixelShader\";\nconst shader = `precision mediump sampler2DArray;varying vec2 vUV;uniform sampler2DArray multiviewSampler;uniform int imageIndex;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{gl_FragColor=texture2D(multiviewSampler,vec3(vUV,imageIndex));}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const vrMultiviewToSingleviewPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"screenSpaceReflectionPixelShader\";\nconst shader = `uniform sampler2D textureSampler;\n#ifdef SSR_SUPPORTED\nuniform sampler2D reflectivitySampler;uniform sampler2D normalSampler;uniform sampler2D positionSampler;\n#endif\nuniform mat4 view;uniform mat4 projection;uniform float stepSize;uniform float strength;uniform float threshold;uniform float roughnessFactor;uniform float reflectionSpecularFalloffExponent;varying vec2 vUV;\n#ifdef SSR_SUPPORTED\nstruct ReflectionInfo {vec3 color;vec4 coords;};/**\n* According to specular,see https:\n*/\nvec3 fresnelSchlick(float cosTheta,vec3 F0)\n{return F0+(1.0-F0)*pow(1.0-cosTheta,5.0);}\n/**\n* Once the pixel's coordinates has been found,let's adjust (smooth) a little bit\n* by sampling multiple reflection pixels.\n*/\nReflectionInfo smoothReflectionInfo(vec3 dir,vec3 hitCoord)\n{ReflectionInfo info;info.color=vec3(0.0);vec4 projectedCoord;float sampledDepth;for(int i=0; i<SMOOTH_STEPS; i++)\n{projectedCoord=projection*vec4(hitCoord,1.0);projectedCoord.xy/=projectedCoord.w;projectedCoord.xy=0.5*projectedCoord.xy+vec2(0.5);sampledDepth=(view*texture2D(positionSampler,projectedCoord.xy)).z;float depth=sampledDepth-hitCoord.z;dir*=0.5;if(depth>0.0)\nhitCoord-=dir;else\nhitCoord+=dir;info.color+=texture2D(textureSampler,projectedCoord.xy).rgb;}\nprojectedCoord=projection*vec4(hitCoord,1.0);projectedCoord.xy/=projectedCoord.w;projectedCoord.xy=0.5*projectedCoord.xy+vec2(0.5);info.coords=vec4(projectedCoord.xy,sampledDepth,1.0);info.color+=texture2D(textureSampler,projectedCoord.xy).rgb;info.color/=float(SMOOTH_STEPS+1);return info;}\n/**\n* Tests the given world position (hitCoord) according to the given reflection vector (dir)\n* until it finds a collision (means that depth is enough close to say \"it's the pixel to sample!\").\n*/\nReflectionInfo getReflectionInfo(vec3 dir,vec3 hitCoord)\n{ReflectionInfo info;vec4 projectedCoord;float sampledDepth;dir*=stepSize;for(int i=0; i<REFLECTION_SAMPLES; i++)\n{hitCoord+=dir;projectedCoord=projection*vec4(hitCoord,1.0);projectedCoord.xy/=projectedCoord.w;projectedCoord.xy=0.5*projectedCoord.xy+vec2(0.5);sampledDepth=(view*texture2D(positionSampler,projectedCoord.xy)).z;float depth=sampledDepth-hitCoord.z;\n#ifdef RIGHT_HANDED_SCENE\ndepth*=-1.0;\n#endif\nif(((depth-dir.z)<threshold) && depth<=0.0)\n{\n#ifdef ENABLE_SMOOTH_REFLECTIONS\nreturn smoothReflectionInfo(dir,hitCoord);\n#else\ninfo.color=texture2D(textureSampler,projectedCoord.xy).rgb;info.coords=vec4(projectedCoord.xy,sampledDepth,0.0);return info;\n#endif\n}}\ninfo.color=texture2D(textureSampler,projectedCoord.xy).rgb;info.coords=vec4(projectedCoord.xy,sampledDepth,0.0);return info;}\nvec3 hash(vec3 a)\n{a=fract(a*0.8);a+=dot(a,a.yxz+19.19);return fract((a.xxy+a.yxx)*a.zyx);}\n#endif\nvoid main()\n{\n#ifdef SSR_SUPPORTED\nvec4 albedoFull=texture2D(textureSampler,vUV);vec3 albedo=albedoFull.rgb;float spec=texture2D(reflectivitySampler,vUV).r;if (spec==0.0) {gl_FragColor=albedoFull;return;}\nvec3 normal=(texture2D(normalSampler,vUV)).xyz;vec3 position=(view*texture2D(positionSampler,vUV)).xyz;vec3 reflected=normalize(reflect(normalize(position),normalize(normal)));float roughness=1.0-texture2D(reflectivitySampler,vUV).a;vec3 jitt=mix(vec3(0.0),hash(position),roughness)*roughnessFactor;ReflectionInfo info=getReflectionInfo(jitt+reflected,position);vec2 dCoords=smoothstep(0.2,0.6,abs(vec2(0.5,0.5)-info.coords.xy));float screenEdgefactor=clamp(1.0-(dCoords.x+dCoords.y),0.0,1.0);vec3 F0=vec3(0.04);F0 =mix(F0,albedo,spec);vec3 fresnel=fresnelSchlick(max(dot(normalize(normal),normalize(position)),0.0),F0);\n#ifdef RIGHT_HANDED_SCENE\nreflected.z*=-1.0;\n#endif\nfloat reflectionMultiplier=clamp(pow(spec*strength,reflectionSpecularFalloffExponent)*screenEdgefactor*reflected.z,0.0,0.9);float albedoMultiplier=1.0-reflectionMultiplier;vec3 SSR=info.color*fresnel;gl_FragColor=vec4((albedo*albedoMultiplier)+(SSR*reflectionMultiplier),albedoFull.a);\n#else\ngl_FragColor=texture2D(textureSampler,vUV);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const screenSpaceReflectionPixelShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { PostProcess } from \"./postProcess.pure\";\r\nimport { type PostProcessOptions } from \"./postProcess\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type GeometryBufferRenderer } from \"../Rendering/geometryBufferRenderer.pure\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { serialize } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { ThinScreenSpaceCurvaturePostProcess } from \"./thinScreenSpaceCurvaturePostProcess\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\n/**\r\n * The Screen Space curvature effect can help highlighting ridge and valley of a model.\r\n */\r\nexport class ScreenSpaceCurvaturePostProcess extends PostProcess {\r\n    /**\r\n     * Defines how much ridge the curvature effect displays.\r\n     */\r\n    @serialize()\r\n    public get ridge() {\r\n        return this._effectWrapper.ridge;\r\n    }\r\n\r\n    public set ridge(value: number) {\r\n        this._effectWrapper.ridge = value;\r\n    }\r\n\r\n    /**\r\n     * Defines how much valley the curvature effect displays.\r\n     */\r\n    @serialize()\r\n    public get valley() {\r\n        return this._effectWrapper.valley;\r\n    }\r\n\r\n    public set valley(value: number) {\r\n        this._effectWrapper.valley = value;\r\n    }\r\n\r\n    private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;\r\n\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"ScreenSpaceCurvaturePostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"ScreenSpaceCurvaturePostProcess\";\r\n    }\r\n\r\n    declare protected _effectWrapper: ThinScreenSpaceCurvaturePostProcess;\r\n\r\n    /**\r\n     * Creates a new instance ScreenSpaceCurvaturePostProcess\r\n     * @param name The name of the effect.\r\n     * @param scene The scene containing the objects to blur according to their velocity.\r\n     * @param options The required width/height ratio to downsize to before computing the render pass.\r\n     * @param camera The camera to apply the render pass to.\r\n     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n     * @param engine The engine which the post process will be applied. (default: current engine)\r\n     * @param reusable If the post process can be reused on the same frame. (default: false)\r\n     * @param textureType Type of textures used when performing the post process. (default: 0)\r\n     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n     */\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera>,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n        blockCompilation = false\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: ThinScreenSpaceCurvaturePostProcess.Uniforms,\r\n            samplers: ThinScreenSpaceCurvaturePostProcess.Samplers,\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            blockCompilation,\r\n            ...(options as PostProcessOptions),\r\n        };\r\n\r\n        super(name, ThinScreenSpaceCurvaturePostProcess.FragmentUrl, {\r\n            effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinScreenSpaceCurvaturePostProcess(name, engine, localOptions) : undefined,\r\n            ...localOptions,\r\n        });\r\n\r\n        this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();\r\n\r\n        if (!this._geometryBufferRenderer) {\r\n            // Geometry buffer renderer is not supported. So, work as a passthrough.\r\n            Logger.Error(\"Multiple Render Target support needed for screen space curvature post process. Please use IsSupported test first.\");\r\n        } else {\r\n            if (this._geometryBufferRenderer.generateNormalsInWorldSpace) {\r\n                Logger.Error(\"ScreenSpaceCurvaturePostProcess does not support generateNormalsInWorldSpace=true for the geometry buffer renderer!\");\r\n            }\r\n\r\n            // Geometry buffer renderer is supported.\r\n            this.onApply = (effect: Effect) => {\r\n                const normalTexture = this._geometryBufferRenderer!.getGBuffer().textures[1];\r\n                effect.setTexture(\"normalSampler\", normalTexture);\r\n            };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Support test.\r\n     */\r\n    public static get IsSupported(): boolean {\r\n        const engine = EngineStore.LastCreatedEngine;\r\n        if (!engine) {\r\n            return false;\r\n        }\r\n\r\n        return engine.getCaps().drawBuffersExtension;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n        return SerializationHelper.Parse(\r\n            () => {\r\n                return new ScreenSpaceCurvaturePostProcess(\r\n                    parsedPostProcess.name,\r\n                    scene,\r\n                    parsedPostProcess.options,\r\n                    targetCamera,\r\n                    parsedPostProcess.renderTargetSamplingMode,\r\n                    scene.getEngine(),\r\n                    parsedPostProcess.reusable,\r\n                    parsedPostProcess.textureType\r\n                );\r\n            },\r\n            parsedPostProcess,\r\n            scene,\r\n            rootUrl\r\n        );\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for screenSpaceCurvaturePostProcess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterScreenSpaceCurvaturePostProcess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(\"BABYLON.ScreenSpaceCurvaturePostProcess\", ScreenSpaceCurvaturePostProcess);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"screenSpaceCurvaturePixelShader\";\nconst shader = `precision highp float;varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D normalSampler;uniform float curvature_ridge;uniform float curvature_valley;\n#ifndef CURVATURE_OFFSET\n#define CURVATURE_OFFSET 1\n#endif\nfloat curvature_soft_clamp(float curvature,float control)\n{if (curvature<0.5/control)\nreturn curvature*(1.0-curvature*control);return 0.25/control;}\nfloat calculate_curvature(ivec2 texel,float ridge,float valley)\n{vec2 normal_up =texelFetch(normalSampler,texel+ivec2(0, CURVATURE_OFFSET),0).rb;vec2 normal_down =texelFetch(normalSampler,texel+ivec2(0,-CURVATURE_OFFSET),0).rb;vec2 normal_left =texelFetch(normalSampler,texel+ivec2(-CURVATURE_OFFSET,0),0).rb;vec2 normal_right=texelFetch(normalSampler,texel+ivec2( CURVATURE_OFFSET,0),0).rb;float normal_diff=((normal_up.g-normal_down.g)+(normal_right.r-normal_left.r));if (normal_diff<0.0)\nreturn -2.0*curvature_soft_clamp(-normal_diff,valley);return 2.0*curvature_soft_clamp(normal_diff,ridge);}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{ivec2 texel=ivec2(gl_FragCoord.xy);vec4 baseColor=texture2D(textureSampler,vUV);float curvature=calculate_curvature(texel,curvature_ridge,curvature_valley);baseColor.rgb*=curvature+1.0;gl_FragColor=baseColor;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const screenSpaceCurvaturePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurVaryingDeclaration\";\nconst shader = `varying vec2 sampleCoord{X};`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const kernelBlurVaryingDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurFragment\";\nconst shader = `#ifdef DOF\nfactor=sampleCoC(sampleCoord{X}); \ncomputedWeight=KERNEL_WEIGHT{X}*factor;sumOfWeights+=computedWeight;\n#else\ncomputedWeight=KERNEL_WEIGHT{X};\n#endif\n#ifdef PACKEDFLOAT\nblend+=unpack(texture2D(textureSampler,sampleCoord{X}))*computedWeight;\n#else\nblend+=texture2D(textureSampler,sampleCoord{X})*computedWeight;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const kernelBlurFragment = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurFragment2\";\nconst shader = `#ifdef DOF\nfactor=sampleCoC(sampleCenter+delta*KERNEL_DEP_OFFSET{X});computedWeight=KERNEL_DEP_WEIGHT{X}*factor;sumOfWeights+=computedWeight;\n#else\ncomputedWeight=KERNEL_DEP_WEIGHT{X};\n#endif\n#ifdef PACKEDFLOAT\nblend+=unpack(texture2D(textureSampler,sampleCenter+delta*KERNEL_DEP_OFFSET{X}))*computedWeight;\n#else\nblend+=texture2D(textureSampler,sampleCenter+delta*KERNEL_DEP_OFFSET{X})*computedWeight;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const kernelBlurFragment2 = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { kernelBlurVaryingDeclaration } from \"./ShadersInclude/kernelBlurVaryingDeclaration\";\nimport { packingFunctions } from \"./ShadersInclude/packingFunctions\";\nimport { kernelBlurFragment } from \"./ShadersInclude/kernelBlurFragment\";\nimport { kernelBlurFragment2 } from \"./ShadersInclude/kernelBlurFragment2\";\n\nconst name = \"kernelBlurPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform vec2 delta;varying vec2 sampleCenter;\n#ifdef DOF\nuniform sampler2D circleOfConfusionSampler;float sampleCoC(in vec2 offset) {float coc=texture2D(circleOfConfusionSampler,offset).r;return coc; }\n#endif\n#include<kernelBlurVaryingDeclaration>[0..varyingCount]\n#ifdef PACKEDFLOAT\n#include<packingFunctions>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{float computedWeight=0.0;\n#ifdef PACKEDFLOAT\nfloat blend=0.;\n#else\nvec4 blend=vec4(0.);\n#endif\n#ifdef DOF\nfloat sumOfWeights=CENTER_WEIGHT; \nfloat factor=0.0;\n#ifdef PACKEDFLOAT\nblend+=unpack(texture2D(textureSampler,sampleCenter))*CENTER_WEIGHT;\n#else\nblend+=texture2D(textureSampler,sampleCenter)*CENTER_WEIGHT;\n#endif\n#endif\n#include<kernelBlurFragment>[0..varyingCount]\n#include<kernelBlurFragment2>[0..depCount]\n#ifdef PACKEDFLOAT\ngl_FragColor=pack(blend);\n#else\ngl_FragColor=blend;\n#endif\n#ifdef DOF\ngl_FragColor/=sumOfWeights;\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [kernelBlurVaryingDeclaration, packingFunctions, kernelBlurFragment, kernelBlurFragment2];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const kernelBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurVertex\";\nconst shader = `sampleCoord{X}=sampleCenter+delta*KERNEL_OFFSET{X};`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const kernelBlurVertex = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { kernelBlurVaryingDeclaration } from \"./ShadersInclude/kernelBlurVaryingDeclaration\";\nimport { kernelBlurVertex } from \"./ShadersInclude/kernelBlurVertex\";\n\nconst name = \"kernelBlurVertexShader\";\nconst shader = `attribute vec2 position;uniform vec2 delta;varying vec2 sampleCenter;\n#include<kernelBlurVaryingDeclaration>[0..varyingCount]\nconst vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nsampleCenter=(position*madd+madd);\n#include<kernelBlurVertex>[0..varyingCount]\ngl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [kernelBlurVaryingDeclaration, kernelBlurVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const kernelBlurVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurVaryingDeclaration\";\nconst shader = `varying sampleCoord{X}: vec2f;`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const kernelBlurVaryingDeclarationWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurFragment\";\nconst shader = `#ifdef DOF\nfactor=sampleCoC(fragmentInputs.sampleCoord{X}); \ncomputedWeight=KERNEL_WEIGHT{X}*factor;sumOfWeights+=computedWeight;\n#else\ncomputedWeight=KERNEL_WEIGHT{X};\n#endif\n#ifdef PACKEDFLOAT\nblend+=unpack(textureSample(textureSampler,textureSamplerSampler,fragmentInputs.sampleCoord{X}))*computedWeight;\n#else\nblend+=textureSample(textureSampler,textureSamplerSampler,fragmentInputs.sampleCoord{X})*computedWeight;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const kernelBlurFragmentWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurFragment2\";\nconst shader = `#ifdef DOF\nfactor=sampleCoC(fragmentInputs.sampleCenter+uniforms.delta*KERNEL_DEP_OFFSET{X});computedWeight=KERNEL_DEP_WEIGHT{X}*factor;sumOfWeights+=computedWeight;\n#else\ncomputedWeight=KERNEL_DEP_WEIGHT{X};\n#endif\n#ifdef PACKEDFLOAT\nblend+=unpack(textureSample(textureSampler,textureSamplerSampler,fragmentInputs.sampleCenter+uniforms.delta*KERNEL_DEP_OFFSET{X}))*computedWeight;\n#else\nblend+=textureSample(textureSampler,textureSamplerSampler,fragmentInputs.sampleCenter+uniforms.delta*KERNEL_DEP_OFFSET{X})*computedWeight;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const kernelBlurFragment2WGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { kernelBlurVaryingDeclarationWGSL } from \"./ShadersInclude/kernelBlurVaryingDeclaration\";\nimport { packingFunctionsWGSL } from \"./ShadersInclude/packingFunctions\";\nimport { kernelBlurFragmentWGSL } from \"./ShadersInclude/kernelBlurFragment\";\nimport { kernelBlurFragment2WGSL } from \"./ShadersInclude/kernelBlurFragment2\";\n\nconst name = \"kernelBlurPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform delta: vec2f;varying sampleCenter: vec2f;\n#ifdef DOF\nvar circleOfConfusionSamplerSampler: sampler;var circleOfConfusionSampler: texture_2d<f32>;fn sampleCoC(offset: vec2f)->f32 {var coc: f32=textureSample(circleOfConfusionSampler,circleOfConfusionSamplerSampler,offset).r;return coc; }\n#endif\n#include<kernelBlurVaryingDeclaration>[0..varyingCount]\n#ifdef PACKEDFLOAT\n#include<packingFunctions>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var computedWeight: f32=0.0;\n#ifdef PACKEDFLOAT\nvar blend: f32=0.;\n#else\nvar blend: vec4f= vec4f(0.);\n#endif\n#ifdef DOF\nvar sumOfWeights: f32=CENTER_WEIGHT; \nvar factor: f32=0.0;\n#ifdef PACKEDFLOAT\nblend+=unpack(textureSample(textureSampler,textureSamplerSampler,input.sampleCenter))*CENTER_WEIGHT;\n#else\nblend+=textureSample(textureSampler,textureSamplerSampler,input.sampleCenter)*CENTER_WEIGHT;\n#endif\n#endif\n#include<kernelBlurFragment>[0..varyingCount]\n#include<kernelBlurFragment2>[0..depCount]\n#ifdef PACKEDFLOAT\nfragmentOutputs.color=pack(blend);\n#else\nfragmentOutputs.color=blend;\n#endif\n#ifdef DOF\nfragmentOutputs.color/=sumOfWeights;\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [kernelBlurVaryingDeclarationWGSL, packingFunctionsWGSL, kernelBlurFragmentWGSL, kernelBlurFragment2WGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const kernelBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"kernelBlurVertex\";\nconst shader = `vertexOutputs.sampleCoord{X}=vertexOutputs.sampleCenter+uniforms.delta*KERNEL_OFFSET{X};`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const kernelBlurVertexWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { kernelBlurVaryingDeclarationWGSL } from \"./ShadersInclude/kernelBlurVaryingDeclaration\";\nimport { kernelBlurVertexWGSL } from \"./ShadersInclude/kernelBlurVertex\";\n\nconst name = \"kernelBlurVertexShader\";\nconst shader = `attribute position: vec2f;uniform delta: vec2f;varying sampleCenter: vec2f;\n#include<kernelBlurVaryingDeclaration>[0..varyingCount]\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {const madd: vec2f= vec2f(0.5,0.5);\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.sampleCenter=(vertexInputs.position*madd+madd);\n#include<kernelBlurVertex>[0..varyingCount]\nvertexOutputs.position= vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [kernelBlurVaryingDeclarationWGSL, kernelBlurVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const kernelBlurVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"passPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{gl_FragColor=texture2D(textureSampler,vUV);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const passPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"passCubePixelShader\";\nconst shader = `varying vec2 vUV;uniform samplerCube textureSampler;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{vec2 uv=vUV*2.0-1.0;\n#ifdef POSITIVEX\ngl_FragColor=textureCube(textureSampler,vec3(1.001,uv.y,uv.x));\n#endif\n#ifdef NEGATIVEX\ngl_FragColor=textureCube(textureSampler,vec3(-1.001,uv.y,uv.x));\n#endif\n#ifdef POSITIVEY\ngl_FragColor=textureCube(textureSampler,vec3(uv.y,1.001,uv.x));\n#endif\n#ifdef NEGATIVEY\ngl_FragColor=textureCube(textureSampler,vec3(uv.y,-1.001,uv.x));\n#endif\n#ifdef POSITIVEZ\ngl_FragColor=textureCube(textureSampler,vec3(uv,1.001));\n#endif\n#ifdef NEGATIVEZ\ngl_FragColor=textureCube(textureSampler,vec3(uv,-1.001));\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const passCubePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"passPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const passPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"passCubePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_cube<f32>;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var uv: vec2f=input.vUV*2.0-1.0;\n#ifdef POSITIVEX\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,vec3f(1.001,uv.y,uv.x));\n#endif\n#ifdef NEGATIVEX\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,vec3f(-1.001,uv.y,uv.x));\n#endif\n#ifdef POSITIVEY\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,vec3f(uv.y,1.001,uv.x));\n#endif\n#ifdef NEGATIVEY\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,vec3f(uv.y,-1.001,uv.x));\n#endif\n#ifdef POSITIVEZ\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,vec3f(uv,1.001));\n#endif\n#ifdef NEGATIVEZ\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,vec3f(uv,-1.001));\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const passCubePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"vrDistortionCorrectionPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec2 LensCenter;uniform vec2 Scale;uniform vec2 ScaleIn;uniform vec4 HmdWarpParam;vec2 HmdWarp(vec2 in01) {vec2 theta=(in01-LensCenter)*ScaleIn; \nfloat rSq=theta.x*theta.x+theta.y*theta.y;vec2 rvector=theta*(HmdWarpParam.x+HmdWarpParam.y*rSq+HmdWarpParam.z*rSq*rSq+HmdWarpParam.w*rSq*rSq*rSq);return LensCenter+Scale*rvector;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec2 tc=HmdWarp(vUV);if (tc.x <0.0 || tc.x>1.0 || tc.y<0.0 || tc.y>1.0)\ngl_FragColor=vec4(0.0,0.0,0.0,0.0);else{gl_FragColor=texture2D(textureSampler,tc);}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const vrDistortionCorrectionPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"vrDistortionCorrectionPixelShader\";\nconst shader = `#define DISABLE_UNIFORMITY_ANALYSIS\nvarying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform LensCenter: vec2f;uniform Scale: vec2f;uniform ScaleIn: vec2f;uniform HmdWarpParam: vec4f;fn HmdWarp(in01: vec2f)->vec2f {var theta: vec2f=(in01-uniforms.LensCenter)*uniforms.ScaleIn; \nvar rSq: f32=theta.x*theta.x+theta.y*theta.y;var rvector: vec2f=theta*(uniforms.HmdWarpParam.x+uniforms.HmdWarpParam.y*rSq+uniforms.HmdWarpParam.z*rSq*rSq+uniforms.HmdWarpParam.w*rSq*rSq*rSq);return uniforms.LensCenter+uniforms.Scale*rvector;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var tc: vec2f=HmdWarp(input.vUV);if (tc.x <0.0 || tc.x>1.0 || tc.y<0.0 || tc.y>1.0) {fragmentOutputs.color=vec4f(0.0,0.0,0.0,0.0);}\nelse{fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,tc);}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const vrDistortionCorrectionPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\n\nconst name = \"imageProcessingPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#include<imageProcessingDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var result: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);result=vec4f(max(result.rgb,vec3f(0.)),result.a);\n#ifdef IMAGEPROCESSING\n#ifndef FROMLINEARSPACE\nresult=vec4f(toLinearSpaceVec3(result.rgb),result.a);\n#endif\nresult=applyImageProcessing(result);\n#else\n#ifdef FROMLINEARSPACE\nresult=applyImageProcessing(result);\n#endif\n#endif\nfragmentOutputs.color=result;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [imageProcessingDeclarationWGSL, helperFunctionsWGSL, imageProcessingFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const imageProcessingPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { imageProcessingDeclaration } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { imageProcessingFunctions } from \"./ShadersInclude/imageProcessingFunctions\";\n\nconst name = \"imageProcessingPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;\n#include<imageProcessingDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec4 result=texture2D(textureSampler,vUV);result.rgb=max(result.rgb,vec3(0.));\n#ifdef IMAGEPROCESSING\n#ifndef FROMLINEARSPACE\nresult.rgb=toLinearSpace(result.rgb);\n#endif\nresult=applyImageProcessing(result);\n#else\n#ifdef FROMLINEARSPACE\nresult=applyImageProcessing(result);\n#endif\n#endif\ngl_FragColor=result;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [imageProcessingDeclaration, helperFunctions, imageProcessingFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const imageProcessingPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"sharpenPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform screenSize: vec2f;uniform sharpnessAmounts: vec2f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var onePixel: vec2f= vec2f(1.0,1.0)/uniforms.screenSize;var color: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);var edgeDetection: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel*vec2f(0,-1)) +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel*vec2f(-1,0)) +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel*vec2f(1,0)) +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel*vec2f(0,1)) -\ncolor*4.0;fragmentOutputs.color=max(vec4f(color.rgb*uniforms.sharpnessAmounts.y,color.a)-(uniforms.sharpnessAmounts.x* vec4f(edgeDetection.rgb,0)),vec4f(0.));}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const sharpenPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"grainPixelShader\";\nconst shader = `#include<helperFunctions>\nuniform sampler2D textureSampler; \nuniform float intensity;uniform float animatedSeed;varying vec2 vUV;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{gl_FragColor=texture2D(textureSampler,vUV);vec2 seed=vUV*(animatedSeed);float grain=dither(seed,intensity);float lum=getLuminance(gl_FragColor.rgb);float grainAmount=(cos(-PI+(lum*PI*2.))+1.)/2.;gl_FragColor.rgb+=grain*grainAmount;gl_FragColor.rgb=max(gl_FragColor.rgb,0.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const grainPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"grainPixelShader\";\nconst shader = `#include<helperFunctions>\nvarying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform intensity: f32;uniform animatedSeed: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);var seed: vec2f=input.vUV*uniforms.animatedSeed;var grain: f32=dither(seed,uniforms.intensity);var lum: f32=getLuminance(fragmentOutputs.color.rgb);var grainAmount: f32=(cos(-PI+(lum*PI*2.))+1.)/2.;fragmentOutputs.color=vec4f(fragmentOutputs.color.rgb+grain*grainAmount,fragmentOutputs.color.a);fragmentOutputs.color=vec4f(max(fragmentOutputs.color.rgb,vec3f(0.0)),fragmentOutputs.color.a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const grainPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"chromaticAberrationPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform chromatic_aberration: f32;uniform radialIntensity: f32;uniform direction: vec2f;uniform centerPosition: vec2f;uniform screen_width: f32;uniform screen_height: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var centered_screen_pos: vec2f= vec2f(input.vUV.x-uniforms.centerPosition.x,input.vUV.y-uniforms.centerPosition.y);var directionOfEffect: vec2f=uniforms.direction;if(directionOfEffect.x==0. && directionOfEffect.y==0.){directionOfEffect=normalize(centered_screen_pos);}\nvar radius2: f32=centered_screen_pos.x*centered_screen_pos.x\n+ centered_screen_pos.y*centered_screen_pos.y;var radius: f32=sqrt(radius2);var ref_indices: vec3f= vec3f(-0.3,0.0,0.3);var ref_shiftX: f32=uniforms.chromatic_aberration*pow(radius,uniforms.radialIntensity)*directionOfEffect.x/uniforms.screen_width;var ref_shiftY: f32=uniforms.chromatic_aberration*pow(radius,uniforms.radialIntensity)*directionOfEffect.y/uniforms.screen_height;var ref_coords_r: vec2f=vec2f(input.vUV.x+ref_indices.r*ref_shiftX,input.vUV.y+ref_indices.r*ref_shiftY*0.5);var ref_coords_g: vec2f=vec2f(input.vUV.x+ref_indices.g*ref_shiftX,input.vUV.y+ref_indices.g*ref_shiftY*0.5);var ref_coords_b: vec2f=vec2f(input.vUV.x+ref_indices.b*ref_shiftX,input.vUV.y+ref_indices.b*ref_shiftY*0.5);var r=textureSample(textureSampler,textureSamplerSampler,ref_coords_r);var g=textureSample(textureSampler,textureSamplerSampler,ref_coords_g);var b=textureSample(textureSampler,textureSamplerSampler,ref_coords_b);var a=clamp(r.a+g.a+b.a,0.,1.);fragmentOutputs.color=vec4f(r.r,g.g,b.b,a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const chromaticAberrationPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"depthOfFieldMergePixelShader\";\nconst shader = `#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,lod) texture2DLodEXT(s,c,lod)\n#else\n#define TEXTUREFUNC(s,c,bias) texture2D(s,c,bias)\n#endif\nuniform sampler2D textureSampler;varying vec2 vUV;uniform sampler2D circleOfConfusionSampler;uniform sampler2D blurStep0;\n#if BLUR_LEVEL>0\nuniform sampler2D blurStep1;\n#endif\n#if BLUR_LEVEL>1\nuniform sampler2D blurStep2;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{float coc=TEXTUREFUNC(circleOfConfusionSampler,vUV,0.0).r;\n#if BLUR_LEVEL==0\nvec4 original=TEXTUREFUNC(textureSampler,vUV,0.0);vec4 blurred0=TEXTUREFUNC(blurStep0,vUV,0.0);gl_FragColor=mix(original,blurred0,coc);\n#endif\n#if BLUR_LEVEL==1\nif(coc<0.5){vec4 original=TEXTUREFUNC(textureSampler,vUV,0.0);vec4 blurred1=TEXTUREFUNC(blurStep1,vUV,0.0);gl_FragColor=mix(original,blurred1,coc/0.5);}else{vec4 blurred0=TEXTUREFUNC(blurStep0,vUV,0.0);vec4 blurred1=TEXTUREFUNC(blurStep1,vUV,0.0);gl_FragColor=mix(blurred1,blurred0,(coc-0.5)/0.5);}\n#endif\n#if BLUR_LEVEL==2\nif(coc<0.33){vec4 original=TEXTUREFUNC(textureSampler,vUV,0.0);vec4 blurred2=TEXTUREFUNC(blurStep2,vUV,0.0);gl_FragColor=mix(original,blurred2,coc/0.33);}else if(coc<0.66){vec4 blurred1=TEXTUREFUNC(blurStep1,vUV,0.0);vec4 blurred2=TEXTUREFUNC(blurStep2,vUV,0.0);gl_FragColor=mix(blurred2,blurred1,(coc-0.33)/0.33);}else{vec4 blurred0=TEXTUREFUNC(blurStep0,vUV,0.0);vec4 blurred1=TEXTUREFUNC(blurStep1,vUV,0.0);gl_FragColor=mix(blurred1,blurred0,(coc-0.66)/0.34);}\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const depthOfFieldMergePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"depthOfFieldMergePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var circleOfConfusionSamplerSampler: sampler;var circleOfConfusionSampler: texture_2d<f32>;var blurStep0Sampler: sampler;var blurStep0: texture_2d<f32>;\n#if BLUR_LEVEL>0\nvar blurStep1Sampler: sampler;var blurStep1: texture_2d<f32>;\n#endif\n#if BLUR_LEVEL>1\nvar blurStep2Sampler: sampler;var blurStep2: texture_2d<f32>;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var coc: f32=textureSampleLevel(circleOfConfusionSampler,circleOfConfusionSamplerSampler,input.vUV,0.0).r;\n#if BLUR_LEVEL==0\nvar original: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);var blurred0: vec4f=textureSampleLevel(blurStep0,blurStep0Sampler,input.vUV,0.0);fragmentOutputs.color=mix(original,blurred0,coc);\n#endif\n#if BLUR_LEVEL==1\nif(coc<0.5){var original: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);var blurred1: vec4f=textureSampleLevel(blurStep1,blurStep1Sampler,input.vUV,0.0);fragmentOutputs.color=mix(original,blurred1,coc/0.5);}else{var blurred0: vec4f=textureSampleLevel(blurStep0,blurStep0Sampler,input.vUV,0.0);var blurred1: vec4f=textureSampleLevel(blurStep1,blurStep1Sampler,input.vUV,0.0);fragmentOutputs.color=mix(blurred1,blurred0,(coc-0.5)/0.5);}\n#endif\n#if BLUR_LEVEL==2\nif(coc<0.33){var original: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);var blurred2: vec4f=textureSampleLevel(blurStep2,blurStep2Sampler,input.vUV,0.0);fragmentOutputs.color=mix(original,blurred2,coc/0.33);}else if(coc<0.66){var blurred1: vec4f=textureSampleLevel(blurStep1,blurStep1Sampler,input.vUV,0.0);var blurred2: vec4f=textureSampleLevel(blurStep2,blurStep2Sampler,input.vUV,0.0);fragmentOutputs.color=mix(blurred2,blurred1,(coc-0.33)/0.33);}else{var blurred0: vec4f=textureSampleLevel(blurStep0,blurStep0Sampler,input.vUV,0.0);var blurred1: vec4f=textureSampleLevel(blurStep1,blurStep1Sampler,input.vUV,0.0);fragmentOutputs.color=mix(blurred1,blurred0,(coc-0.66)/0.34);}\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const depthOfFieldMergePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"circleOfConfusionPixelShader\";\nconst shader = `uniform sampler2D depthSampler;varying vec2 vUV;\n#ifndef COC_DEPTH_NOT_NORMALIZED\nuniform vec2 cameraMinMaxZ;\n#endif\nuniform float focusDistance;uniform float cocPrecalculation;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{float depth=texture2D(depthSampler,vUV).r;\n#define CUSTOM_COC_DEPTH\n#ifdef COC_DEPTH_NOT_NORMALIZED\nfloat pixelDistance=depth*1000.0;\n#else\nfloat pixelDistance=(cameraMinMaxZ.x+cameraMinMaxZ.y*depth)*1000.0; \n#endif\n#define CUSTOM_COC_PIXELDISTANCE\nfloat coc=abs(cocPrecalculation*((focusDistance-pixelDistance)/pixelDistance));coc=clamp(coc,0.0,1.0);gl_FragColor=vec4(coc,coc,coc,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const circleOfConfusionPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"circleOfConfusionPixelShader\";\nconst shader = `varying vUV: vec2f;var depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;\n#ifndef COC_DEPTH_NOT_NORMALIZED\nuniform cameraMinMaxZ: vec2f;\n#endif\nuniform focusDistance: f32;uniform cocPrecalculation: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var depth: f32=textureSample(depthSampler,depthSamplerSampler,input.vUV).r;\n#define CUSTOM_COC_DEPTH\n#ifdef COC_DEPTH_NOT_NORMALIZED\nlet pixelDistance=depth*1000.0;\n#else\nlet pixelDistance: f32=(uniforms.cameraMinMaxZ.x+uniforms.cameraMinMaxZ.y*depth)*1000.0; \n#endif\n#define CUSTOM_COC_PIXELDISTANCE\nvar coc: f32=abs(uniforms.cocPrecalculation*((uniforms.focusDistance-pixelDistance)/pixelDistance));coc=clamp(coc,0.0,1.0);fragmentOutputs.color= vec4f(coc,coc,coc,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const circleOfConfusionPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"bloomMergePixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform sampler2D bloomBlur;varying vec2 vUV;uniform float bloomWeight;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{gl_FragColor=texture2D(textureSampler,vUV);vec3 blurred=texture2D(bloomBlur,vUV).rgb;gl_FragColor.rgb=gl_FragColor.rgb+(blurred.rgb*bloomWeight); }\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const bloomMergePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"bloomMergePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var bloomBlurSampler: sampler;var bloomBlur: texture_2d<f32>;uniform bloomWeight: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);var blurred: vec3f=textureSample(bloomBlur,bloomBlurSampler,input.vUV).rgb;fragmentOutputs.color=vec4f(fragmentOutputs.color.rgb+(blurred.rgb*uniforms.bloomWeight),fragmentOutputs.color.a);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const bloomMergePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"extractHighlightsPixelShader\";\nconst shader = `#include<helperFunctions>\nvarying vec2 vUV;uniform sampler2D textureSampler;uniform float threshold;uniform float exposure;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{gl_FragColor=texture2D(textureSampler,vUV);float luma=dot(LuminanceEncodeApprox,gl_FragColor.rgb*exposure);gl_FragColor.rgb=step(threshold,luma)*gl_FragColor.rgb;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const extractHighlightsPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"extractHighlightsPixelShader\";\nconst shader = `#include<helperFunctions>\nvarying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform threshold: f32;uniform exposure: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);var luma: f32=dot(LuminanceEncodeApprox,fragmentOutputs.color.rgb*uniforms.exposure);fragmentOutputs.color=vec4f(step(uniforms.threshold,luma)*fragmentOutputs.color.rgb,fragmentOutputs.color.a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const extractHighlightsPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fxaaPixelShader\";\nconst shader = `#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,l) texture2DLodEXT(s,c,l)\n#else\n#define TEXTUREFUNC(s,c,b) texture2D(s,c,b)\n#endif\nuniform sampler2D textureSampler;uniform vec2 texelSize;varying vec2 vUV;varying vec2 sampleCoordS;varying vec2 sampleCoordE;varying vec2 sampleCoordN;varying vec2 sampleCoordW;varying vec2 sampleCoordNW;varying vec2 sampleCoordSE;varying vec2 sampleCoordNE;varying vec2 sampleCoordSW;const float fxaaQualitySubpix=1.0;const float fxaaQualityEdgeThreshold=0.166;const float fxaaQualityEdgeThresholdMin=0.0833;const vec3 kLumaCoefficients=vec3(0.2126,0.7152,0.0722);\n#define FxaaLuma(rgba) dot(rgba.rgb,kLumaCoefficients)\nvoid main(){vec2 posM;posM.x=vUV.x;posM.y=vUV.y;vec4 rgbyM=TEXTUREFUNC(textureSampler,vUV,0.0);float lumaM=FxaaLuma(rgbyM);float lumaS=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordS,0.0));float lumaE=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordE,0.0));float lumaN=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordN,0.0));float lumaW=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordW,0.0));float maxSM=max(lumaS,lumaM);float minSM=min(lumaS,lumaM);float maxESM=max(lumaE,maxSM);float minESM=min(lumaE,minSM);float maxWN=max(lumaN,lumaW);float minWN=min(lumaN,lumaW);float rangeMax=max(maxWN,maxESM);float rangeMin=min(minWN,minESM);float rangeMaxScaled=rangeMax*fxaaQualityEdgeThreshold;float range=rangeMax-rangeMin;float rangeMaxClamped=max(fxaaQualityEdgeThresholdMin,rangeMaxScaled);\n#ifndef MALI\nif(range<rangeMaxClamped) \n{gl_FragColor=rgbyM;return;}\n#endif\nfloat lumaNW=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordNW,0.0));float lumaSE=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordSE,0.0));float lumaNE=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordNE,0.0));float lumaSW=FxaaLuma(TEXTUREFUNC(textureSampler,sampleCoordSW,0.0));float lumaNS=lumaN+lumaS;float lumaWE=lumaW+lumaE;float subpixRcpRange=1.0/range;float subpixNSWE=lumaNS+lumaWE;float edgeHorz1=(-2.0*lumaM)+lumaNS;float edgeVert1=(-2.0*lumaM)+lumaWE;float lumaNESE=lumaNE+lumaSE;float lumaNWNE=lumaNW+lumaNE;float edgeHorz2=(-2.0*lumaE)+lumaNESE;float edgeVert2=(-2.0*lumaN)+lumaNWNE;float lumaNWSW=lumaNW+lumaSW;float lumaSWSE=lumaSW+lumaSE;float edgeHorz4=(abs(edgeHorz1)*2.0)+abs(edgeHorz2);float edgeVert4=(abs(edgeVert1)*2.0)+abs(edgeVert2);float edgeHorz3=(-2.0*lumaW)+lumaNWSW;float edgeVert3=(-2.0*lumaS)+lumaSWSE;float edgeHorz=abs(edgeHorz3)+edgeHorz4;float edgeVert=abs(edgeVert3)+edgeVert4;float subpixNWSWNESE=lumaNWSW+lumaNESE;float lengthSign=texelSize.x;bool horzSpan=edgeHorz>=edgeVert;float subpixA=subpixNSWE*2.0+subpixNWSWNESE;if (!horzSpan)\n{lumaN=lumaW;}\nif (!horzSpan) \n{lumaS=lumaE;}\nif (horzSpan) \n{lengthSign=texelSize.y;}\nfloat subpixB=(subpixA*(1.0/12.0))-lumaM;float gradientN=lumaN-lumaM;float gradientS=lumaS-lumaM;float lumaNN=lumaN+lumaM;float lumaSS=lumaS+lumaM;bool pairN=abs(gradientN)>=abs(gradientS);float gradient=max(abs(gradientN),abs(gradientS));if (pairN)\n{lengthSign=-lengthSign;}\nfloat subpixC=clamp(abs(subpixB)*subpixRcpRange,0.0,1.0);vec2 posB;posB.x=posM.x;posB.y=posM.y;vec2 offNP;offNP.x=(!horzSpan) ? 0.0 : texelSize.x;offNP.y=(horzSpan) ? 0.0 : texelSize.y;if (!horzSpan) \n{posB.x+=lengthSign*0.5;}\nif (horzSpan)\n{posB.y+=lengthSign*0.5;}\nvec2 posN;posN.x=posB.x-offNP.x*1.5;posN.y=posB.y-offNP.y*1.5;vec2 posP;posP.x=posB.x+offNP.x*1.5;posP.y=posB.y+offNP.y*1.5;float subpixD=((-2.0)*subpixC)+3.0;float lumaEndN=FxaaLuma(TEXTUREFUNC(textureSampler,posN,0.0));float subpixE=subpixC*subpixC;float lumaEndP=FxaaLuma(TEXTUREFUNC(textureSampler,posP,0.0));if (!pairN) \n{lumaNN=lumaSS;}\nfloat gradientScaled=gradient*1.0/4.0;float lumaMM=lumaM-lumaNN*0.5;float subpixF=subpixD*subpixE;bool lumaMLTZero=lumaMM<0.0;lumaEndN-=lumaNN*0.5;lumaEndP-=lumaNN*0.5;bool doneN=abs(lumaEndN)>=gradientScaled;bool doneP=abs(lumaEndP)>=gradientScaled;if (!doneN) \n{posN.x-=offNP.x*3.0;}\nif (!doneN) \n{posN.y-=offNP.y*3.0;}\nbool doneNP=(!doneN) || (!doneP);if (!doneP) \n{posP.x+=offNP.x*3.0;}\nif (!doneP)\n{posP.y+=offNP.y*3.0;}\nif (doneNP)\n{if (!doneN) lumaEndN=FxaaLuma(TEXTUREFUNC(textureSampler,posN.xy,0.0));if (!doneP) lumaEndP=FxaaLuma(TEXTUREFUNC(textureSampler,posP.xy,0.0));if (!doneN) lumaEndN=lumaEndN-lumaNN*0.5;if (!doneP) lumaEndP=lumaEndP-lumaNN*0.5;doneN=abs(lumaEndN)>=gradientScaled;doneP=abs(lumaEndP)>=gradientScaled;if (!doneN) posN.x-=offNP.x*12.0;if (!doneN) posN.y-=offNP.y*12.0;doneNP=(!doneN) || (!doneP);if (!doneP) posP.x+=offNP.x*12.0;if (!doneP) posP.y+=offNP.y*12.0;}\nfloat dstN=posM.x-posN.x;float dstP=posP.x-posM.x;if (!horzSpan)\n{dstN=posM.y-posN.y;}\nif (!horzSpan) \n{dstP=posP.y-posM.y;}\nbool goodSpanN=(lumaEndN<0.0) != lumaMLTZero;float spanLength=(dstP+dstN);bool goodSpanP=(lumaEndP<0.0) != lumaMLTZero;float spanLengthRcp=1.0/spanLength;bool directionN=dstN<dstP;float dst=min(dstN,dstP);bool goodSpan=directionN ? goodSpanN : goodSpanP;float subpixG=subpixF*subpixF;float pixelOffset=(dst*(-spanLengthRcp))+0.5;float subpixH=subpixG*fxaaQualitySubpix;float pixelOffsetGood=goodSpan ? pixelOffset : 0.0;float pixelOffsetSubpix=max(pixelOffsetGood,subpixH);if (!horzSpan)\n{posM.x+=pixelOffsetSubpix*lengthSign;}\nif (horzSpan)\n{posM.y+=pixelOffsetSubpix*lengthSign;}\n#ifdef MALI\nif(range<rangeMaxClamped) \n{gl_FragColor=rgbyM;}\nelse\n{gl_FragColor=TEXTUREFUNC(textureSampler,posM,0.0);}\n#else\ngl_FragColor=TEXTUREFUNC(textureSampler,posM,0.0);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fxaaPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fxaaVertexShader\";\nconst shader = `attribute vec2 position;uniform vec2 texelSize;varying vec2 vUV;varying vec2 sampleCoordS;varying vec2 sampleCoordE;varying vec2 sampleCoordN;varying vec2 sampleCoordW;varying vec2 sampleCoordNW;varying vec2 sampleCoordSE;varying vec2 sampleCoordNE;varying vec2 sampleCoordSW;const vec2 madd=vec2(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvUV=(position*madd+madd);sampleCoordS=vUV+vec2( 0.0,1.0)*texelSize;sampleCoordE=vUV+vec2( 1.0,0.0)*texelSize;sampleCoordN=vUV+vec2( 0.0,-1.0)*texelSize;sampleCoordW=vUV+vec2(-1.0,0.0)*texelSize;sampleCoordNW=vUV+vec2(-1.0,-1.0)*texelSize;sampleCoordSE=vUV+vec2( 1.0,1.0)*texelSize;sampleCoordNE=vUV+vec2( 1.0,-1.0)*texelSize;sampleCoordSW=vUV+vec2(-1.0,1.0)*texelSize;gl_Position=vec4(position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fxaaVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fxaaPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform texelSize: vec2f;varying sampleCoordS: vec2f;varying sampleCoordE: vec2f;varying sampleCoordN: vec2f;varying sampleCoordW: vec2f;varying sampleCoordNW: vec2f;varying sampleCoordSE: vec2f;varying sampleCoordNE: vec2f;varying sampleCoordSW: vec2f;const fxaaQualitySubpix: f32=1.0;const fxaaQualityEdgeThreshold: f32=0.166;const fxaaQualityEdgeThresholdMin: f32=0.0833;const kLumaCoefficients: vec3f= vec3f(0.2126,0.7152,0.0722);fn FxaaLuma(rgba: vec4f)->f32 {return dot(rgba.rgb,kLumaCoefficients);} \n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var posM: vec2f;posM.x=input.vUV.x;posM.y=input.vUV.y;var rgbyM: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.0);var lumaM: f32=FxaaLuma(rgbyM);var lumaS: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordS,0.0));var lumaE: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordE,0.0));var lumaN: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordN,0.0));var lumaW: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordW,0.0));var maxSM: f32=max(lumaS,lumaM);var minSM: f32=min(lumaS,lumaM);var maxESM: f32=max(lumaE,maxSM);var minESM: f32=min(lumaE,minSM);var maxWN: f32=max(lumaN,lumaW);var minWN: f32=min(lumaN,lumaW);var rangeMax: f32=max(maxWN,maxESM);var rangeMin: f32=min(minWN,minESM);var rangeMaxScaled: f32=rangeMax*fxaaQualityEdgeThreshold;var range: f32=rangeMax-rangeMin;var rangeMaxClamped: f32=max(fxaaQualityEdgeThresholdMin,rangeMaxScaled);\n#ifndef MALI\nif(range<rangeMaxClamped) \n{fragmentOutputs.color=rgbyM;return fragmentOutputs;}\n#endif\nvar lumaNW: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordNW,0.0));var lumaSE: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordSE,0.0));var lumaNE: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordNE,0.0));var lumaSW: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,input.sampleCoordSW,0.0));var lumaNS: f32=lumaN+lumaS;var lumaWE: f32=lumaW+lumaE;var subpixRcpRange: f32=1.0/range;var subpixNSWE: f32=lumaNS+lumaWE;var edgeHorz1: f32=(-2.0*lumaM)+lumaNS;var edgeVert1: f32=(-2.0*lumaM)+lumaWE;var lumaNESE: f32=lumaNE+lumaSE;var lumaNWNE: f32=lumaNW+lumaNE;var edgeHorz2: f32=(-2.0*lumaE)+lumaNESE;var edgeVert2: f32=(-2.0*lumaN)+lumaNWNE;var lumaNWSW: f32=lumaNW+lumaSW;var lumaSWSE: f32=lumaSW+lumaSE;var edgeHorz4: f32=(abs(edgeHorz1)*2.0)+abs(edgeHorz2);var edgeVert4: f32=(abs(edgeVert1)*2.0)+abs(edgeVert2);var edgeHorz3: f32=(-2.0*lumaW)+lumaNWSW;var edgeVert3: f32=(-2.0*lumaS)+lumaSWSE;var edgeHorz: f32=abs(edgeHorz3)+edgeHorz4;var edgeVert: f32=abs(edgeVert3)+edgeVert4;var subpixNWSWNESE: f32=lumaNWSW+lumaNESE;var lengthSign: f32=uniforms.texelSize.x;var horzSpan: bool=edgeHorz>=edgeVert;var subpixA: f32=subpixNSWE*2.0+subpixNWSWNESE;if (!horzSpan)\n{lumaN=lumaW;}\nif (!horzSpan) \n{lumaS=lumaE;}\nif (horzSpan) \n{lengthSign=uniforms.texelSize.y;}\nvar subpixB: f32=(subpixA*(1.0/12.0))-lumaM;var gradientN: f32=lumaN-lumaM;var gradientS: f32=lumaS-lumaM;var lumaNN: f32=lumaN+lumaM;var lumaSS: f32=lumaS+lumaM;var pairN: bool=abs(gradientN)>=abs(gradientS);var gradient: f32=max(abs(gradientN),abs(gradientS));if (pairN)\n{lengthSign=-lengthSign;}\nvar subpixC: f32=clamp(abs(subpixB)*subpixRcpRange,0.0,1.0);var posB: vec2f;posB.x=posM.x;posB.y=posM.y;var offNP: vec2f;offNP.x=select(uniforms.texelSize.x,0.0,(!horzSpan));offNP.y=select(uniforms.texelSize.y,0.0,(horzSpan));if (!horzSpan) \n{posB.x+=lengthSign*0.5;}\nif (horzSpan)\n{posB.y+=lengthSign*0.5;}\nvar posN: vec2f;posN.x=posB.x-offNP.x*1.5;posN.y=posB.y-offNP.y*1.5;var posP: vec2f;posP.x=posB.x+offNP.x*1.5;posP.y=posB.y+offNP.y*1.5;var subpixD: f32=((-2.0)*subpixC)+3.0;var lumaEndN: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,posN,0.0));var subpixE: f32=subpixC*subpixC;var lumaEndP: f32=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,posP,0.0));if (!pairN) \n{lumaNN=lumaSS;}\nvar gradientScaled: f32=gradient*1.0/4.0;var lumaMM: f32=lumaM-lumaNN*0.5;var subpixF: f32=subpixD*subpixE;var lumaMLTZero: bool=lumaMM<0.0;lumaEndN-=lumaNN*0.5;lumaEndP-=lumaNN*0.5;var doneN: bool=abs(lumaEndN)>=gradientScaled;var doneP: bool=abs(lumaEndP)>=gradientScaled;if (!doneN) \n{posN.x-=offNP.x*3.0;}\nif (!doneN) \n{posN.y-=offNP.y*3.0;}\nvar doneNP: bool=(!doneN) || (!doneP);if (!doneP) \n{posP.x+=offNP.x*3.0;}\nif (!doneP)\n{posP.y+=offNP.y*3.0;}\nif (doneNP)\n{if (!doneN) {lumaEndN=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,posN.xy,0.0));}\nif (!doneP) {lumaEndP=FxaaLuma(textureSampleLevel(textureSampler,textureSamplerSampler,posP.xy,0.0));}\nif (!doneN) {lumaEndN=lumaEndN-lumaNN*0.5;}\nif (!doneP) {lumaEndP=lumaEndP-lumaNN*0.5;}\ndoneN=abs(lumaEndN)>=gradientScaled;doneP=abs(lumaEndP)>=gradientScaled;if (!doneN) {posN.x-=offNP.x*12.0;}\nif (!doneN) {posN.y-=offNP.y*12.0;}\ndoneNP=(!doneN) || (!doneP);if (!doneP) {posP.x+=offNP.x*12.0;}\nif (!doneP) {posP.y+=offNP.y*12.0;}}\nvar dstN: f32=posM.x-posN.x;var dstP: f32=posP.x-posM.x;if (!horzSpan)\n{dstN=posM.y-posN.y;}\nif (!horzSpan) \n{dstP=posP.y-posM.y;}\nvar goodSpanN: bool=(lumaEndN<0.0) != lumaMLTZero;var spanLength: f32=(dstP+dstN);var goodSpanP: bool=(lumaEndP<0.0) != lumaMLTZero;var spanLengthRcp: f32=1.0/spanLength;var directionN: bool=dstN<dstP;var dst: f32=min(dstN,dstP);var goodSpan: bool=select(goodSpanP,goodSpanN,directionN);var subpixG: f32=subpixF*subpixF;var pixelOffset: f32=(dst*(-spanLengthRcp))+0.5;var subpixH: f32=subpixG*fxaaQualitySubpix;var pixelOffsetGood: f32=select(0.0,pixelOffset,goodSpan);var pixelOffsetSubpix: f32=max(pixelOffsetGood,subpixH);if (!horzSpan)\n{posM.x+=pixelOffsetSubpix*lengthSign;}\nif (horzSpan)\n{posM.y+=pixelOffsetSubpix*lengthSign;}\n#ifdef MALI\nif(range<rangeMaxClamped) \n{fragmentOutputs.color=rgbyM;}\nelse\n{fragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,posM,0.0);}\n#else\nfragmentOutputs.color=textureSampleLevel(textureSampler,textureSamplerSampler,posM,0.0);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fxaaPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fxaaVertexShader\";\nconst shader = `attribute position: vec2f;uniform texelSize: vec2f;varying vUV: vec2f;varying sampleCoordS: vec2f;varying sampleCoordE: vec2f;varying sampleCoordN: vec2f;varying sampleCoordW: vec2f;varying sampleCoordNW: vec2f;varying sampleCoordSE: vec2f;varying sampleCoordNE: vec2f;varying sampleCoordSW: vec2f;const madd: vec2f= vec2f(0.5,0.5);\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvertexOutputs.vUV=(vertexInputs.position*madd+madd);vertexOutputs.sampleCoordS=vertexOutputs.vUV+ vec2f( 0.0,1.0)*uniforms.texelSize;vertexOutputs.sampleCoordE=vertexOutputs.vUV+ vec2f( 1.0,0.0)*uniforms.texelSize;vertexOutputs.sampleCoordN=vertexOutputs.vUV+ vec2f( 0.0,-1.0)*uniforms.texelSize;vertexOutputs.sampleCoordW=vertexOutputs.vUV+ vec2f(-1.0,0.0)*uniforms.texelSize;vertexOutputs.sampleCoordNW=vertexOutputs.vUV+ vec2f(-1.0,-1.0)*uniforms.texelSize;vertexOutputs.sampleCoordSE=vertexOutputs.vUV+ vec2f( 1.0,1.0)*uniforms.texelSize;vertexOutputs.sampleCoordNE=vertexOutputs.vUV+ vec2f( 1.0,-1.0)*uniforms.texelSize;vertexOutputs.sampleCoordSW=vertexOutputs.vUV+ vec2f(-1.0,1.0)*uniforms.texelSize;vertexOutputs.position=vec4f(vertexInputs.position,0.0,1.0);\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fxaaVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"blackAndWhitePixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform float degree;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{vec3 color=texture2D(textureSampler,vUV).rgb;float luminance=dot(color,vec3(0.3,0.59,0.11)); \nvec3 blackAndWhite=vec3(luminance,luminance,luminance);gl_FragColor=vec4(color-((color-blackAndWhite)*degree),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const blackAndWhitePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"blackAndWhitePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform degree: f32;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var color: vec3f=textureSample(textureSampler,textureSamplerSampler,input.vUV).rgb;var luminance: f32=dot(color, vec3f(0.3,0.59,0.11)); \nvar blackAndWhite: vec3f= vec3f(luminance,luminance,luminance);fragmentOutputs.color= vec4f(color-((color-blackAndWhite)*uniforms.degree),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const blackAndWhitePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"anaglyphPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D leftSampler;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec4 leftFrag=texture2D(leftSampler,vUV);leftFrag=vec4(1.0,leftFrag.g,leftFrag.b,1.0);vec4 rightFrag=texture2D(textureSampler,vUV);rightFrag=vec4(rightFrag.r,1.0,1.0,1.0);gl_FragColor=vec4(rightFrag.rgb*leftFrag.rgb,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const anaglyphPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"anaglyphPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var leftSamplerSampler: sampler;var leftSampler: texture_2d<f32>;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var leftFrag: vec4f=textureSample(leftSampler,leftSamplerSampler,input.vUV);leftFrag= vec4f(1.0,leftFrag.g,leftFrag.b,1.0);var rightFrag: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);rightFrag= vec4f(rightFrag.r,1.0,1.0,1.0);fragmentOutputs.color= vec4f(rightFrag.rgb*leftFrag.rgb,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const anaglyphPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"convolutionPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform vec2 screenSize;uniform float kernel[9];\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec2 onePixel=vec2(1.0,1.0)/screenSize;vec4 colorSum =\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,-1))*kernel[0] +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,-1))*kernel[1] +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,-1))*kernel[2] +\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,0))*kernel[3] +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,0))*kernel[4] +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,0))*kernel[5] +\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,1))*kernel[6] +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,1))*kernel[7] +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,1))*kernel[8];float kernelWeight =\nkernel[0] +\nkernel[1] +\nkernel[2] +\nkernel[3] +\nkernel[4] +\nkernel[5] +\nkernel[6] +\nkernel[7] +\nkernel[8];if (kernelWeight<=0.0) {kernelWeight=1.0;}\ngl_FragColor=vec4((colorSum/kernelWeight).rgb,1);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const convolutionPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"convolutionPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform screenSize: vec2f;uniform kernel: array<f32,9>;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var onePixel: vec2f= vec2f(1.0,1.0)/uniforms.screenSize;var colorSum: vec4f =\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(-1,-1))*uniforms.kernel[0] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(0,-1))*uniforms.kernel[1] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(1,-1))*uniforms.kernel[2] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(-1,0))*uniforms.kernel[3] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(0,0))*uniforms.kernel[4] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(1,0))*uniforms.kernel[5] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(-1,1))*uniforms.kernel[6] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(0,1))*uniforms.kernel[7] +\ntextureSample(textureSampler,textureSamplerSampler,input.vUV+onePixel* vec2f(1,1))*uniforms.kernel[8];var kernelWeight: f32 =\nuniforms.kernel[0] +\nuniforms.kernel[1] +\nuniforms.kernel[2] +\nuniforms.kernel[3] +\nuniforms.kernel[4] +\nuniforms.kernel[5] +\nuniforms.kernel[6] +\nuniforms.kernel[7] +\nuniforms.kernel[8];if (kernelWeight<=0.0) {kernelWeight=1.0;}\nfragmentOutputs.color= vec4f((colorSum/kernelWeight).rgb,1);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const convolutionPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"colorCorrectionPixelShader\";\nconst shader = `uniform sampler2D textureSampler; \nuniform sampler2D colorTable; \nvarying vec2 vUV;const float SLICE_COUNT=16.0; \n#define inline\nvec4 sampleAs3DTexture(sampler2D textureSampler,vec3 uv,float width) {float sliceSize=1.0/width; \nfloat slicePixelSize=sliceSize/width; \nfloat sliceInnerSize=slicePixelSize*(width-1.0); \nfloat zSlice0=min(floor(uv.z*width),width-1.0);float zSlice1=min(zSlice0+1.0,width-1.0);float xOffset=slicePixelSize*0.5+uv.x*sliceInnerSize;float s0=xOffset+(zSlice0*sliceSize);float s1=xOffset+(zSlice1*sliceSize);vec4 slice0Color=texture2D(textureSampler,vec2(s0,uv.y));vec4 slice1Color=texture2D(textureSampler,vec2(s1,uv.y));float zOffset=mod(uv.z*width,1.0);vec4 result=mix(slice0Color,slice1Color,zOffset);return result;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec4 screen_color=texture2D(textureSampler,vUV);gl_FragColor=sampleAs3DTexture(colorTable,screen_color.rgb,SLICE_COUNT);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const colorCorrectionPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"colorCorrectionPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;varying vUV: vec2f;var colorTableSampler: sampler;var colorTable: texture_2d<f32>;const SLICE_COUNT: f32=16.0; \nfn sampleAs3DTexture(uv: vec3f,width: f32)->vec4f {var sliceSize: f32=1.0/width; \nvar slicePixelSize: f32=sliceSize/width; \nvar sliceInnerSize: f32=slicePixelSize*(width-1.0); \nvar zSlice0: f32=min(floor(uv.z*width),width-1.0);var zSlice1: f32=min(zSlice0+1.0,width-1.0);var xOffset: f32=slicePixelSize*0.5+uv.x*sliceInnerSize;var s0: f32=xOffset+(zSlice0*sliceSize);var s1: f32=xOffset+(zSlice1*sliceSize);var slice0Color: vec4f=textureSample(colorTable,colorTableSampler,vec2f(s0,uv.y));var slice1Color: vec4f=textureSample(colorTable,colorTableSampler,vec2f(s1,uv.y));var zOffset: f32=((uv.z*width)%(1.0));return mix(slice0Color,slice1Color,zOffset);}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var screen_color: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);fragmentOutputs.color=sampleAs3DTexture(screen_color.rgb,SLICE_COUNT);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const colorCorrectionPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"motionBlurPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform float motionStrength;uniform float motionScale;uniform vec2 screenSize;\n#ifdef OBJECT_BASED\nuniform sampler2D velocitySampler;\n#else\nuniform sampler2D depthSampler;uniform mat4 inverseViewProjection;uniform mat4 prevViewProjection;uniform mat4 projection;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{\n#ifdef GEOMETRY_SUPPORTED\n#ifdef OBJECT_BASED\nvec2 texelSize=1.0/screenSize;vec4 velocityColor=textureLod(velocitySampler,vUV,0.0);velocityColor.rg=velocityColor.rg*2.0-vec2(1.0);vec2 signs=sign(velocityColor.rg);vec2 velocity=pow(abs(velocityColor.rg),vec2(3.0))*signs*velocityColor.a;velocity*=motionScale*motionStrength;float speed=length(velocity/texelSize);int samplesCount=int(clamp(speed,1.0,SAMPLES));velocity=normalize(velocity)*texelSize;float hlim=float(-samplesCount)*0.5+0.5;vec4 result=textureLod(textureSampler,vUV,0.0);for (int i=1; i<int(SAMPLES); ++i)\n{if (i>=samplesCount)\nbreak;vec2 offset=vUV+velocity*(hlim+float(i));result+=textureLod(textureSampler,offset,0.0);}\ngl_FragColor=result/float(samplesCount);gl_FragColor.a=1.0;\n#else\nvec4 result=textureLod(textureSampler,vUV,0.0);vec2 texelSize=1.0/screenSize;float depth=textureLod(depthSampler,vUV,0.0).r;if (depth==0.0) {gl_FragColor=result;return;}\ndepth=projection[2].z+projection[3].z/depth; \nvec4 cpos=vec4(vUV*2.0-1.0,depth,1.0);cpos=inverseViewProjection*cpos;cpos/=cpos.w;vec4 ppos=prevViewProjection*cpos;ppos/=ppos.w;ppos.xy=ppos.xy*0.5+0.5;vec2 velocity=(ppos.xy-vUV)*motionScale*motionStrength;float speed=length(velocity/texelSize);int nSamples=int(clamp(speed,1.0,SAMPLES));for (int i=1; i<int(SAMPLES); ++i) {if (i>=nSamples)\nbreak;vec2 offset1=vUV+velocity*(float(i)/float(nSamples-1)-0.5);result+=textureLod(textureSampler,offset1,0.0);}\ngl_FragColor=result/float(nSamples);\n#endif\n#else\ngl_FragColor=texture2D(textureSampler,vUV);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const motionBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"motionBlurPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform motionStrength: f32;uniform motionScale: f32;uniform screenSize: vec2f;\n#ifdef OBJECT_BASED\nvar velocitySamplerSampler: sampler;var velocitySampler: texture_2d<f32>;\n#else\nvar depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;uniform inverseViewProjection: mat4x4f;uniform prevViewProjection: mat4x4f;uniform projection: mat4x4f;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#ifdef GEOMETRY_SUPPORTED\n#ifdef OBJECT_BASED\nvar texelSize: vec2f=1.0/uniforms.screenSize;var velocityColor: vec4f=textureSampleLevel(velocitySampler,velocitySamplerSampler,input.vUV,0.0);velocityColor=vec4f(velocityColor.rg*2.0- vec2f(1.0),velocityColor.b,velocityColor.a);let signs=sign(velocityColor.rg);var velocity=pow(abs(velocityColor.rg),vec2f(3.0))*signs*velocityColor.a;velocity*=uniforms.motionScale*uniforms.motionStrength;var speed: f32=length(velocity/texelSize);var samplesCount: i32= i32(clamp(speed,1.0,SAMPLES));velocity=normalize(velocity)*texelSize;var hlim: f32= f32(-samplesCount)*0.5+0.5;var result: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler, input.vUV,0.0);for (var i: i32=1; i< i32(SAMPLES); i++)\n{if (i>=samplesCount) {break;}\nvar offset: vec2f=input.vUV+velocity*(hlim+ f32(i));result+=textureSampleLevel(textureSampler,textureSamplerSampler, offset,0.0);}\nfragmentOutputs.color=vec4f(result.rgb/ f32(samplesCount),1.0);\n#else\nvar result: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler, input.vUV,0.0);var texelSize: vec2f=1.0/uniforms.screenSize;var depth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV,0.0).r;if (depth==0.0) {fragmentOutputs.color=result;return fragmentOutputs;}\ndepth=uniforms.projection[2].z+uniforms.projection[3].z/depth; \nvar cpos: vec4f= vec4f(input.vUV*2.0-1.0,depth,1.0);cpos=uniforms.inverseViewProjection*cpos;cpos/=cpos.w;var ppos: vec4f=uniforms.prevViewProjection*cpos;ppos/=ppos.w;ppos=vec4f(ppos.xy*0.5+0.5,ppos.zw);var velocity: vec2f=(ppos.xy-input.vUV)*uniforms.motionScale*uniforms.motionStrength;var speed: f32=length(velocity/texelSize);var nSamples: i32= i32(clamp(speed,1.0,SAMPLES));for (var i: i32=1; i< i32(SAMPLES); i++) {if (i>=nSamples) {break;}\nvar offset1: vec2f=input.vUV+velocity*( f32(i)/ f32(nSamples-1)-0.5);result+=textureSampleLevel(textureSampler,textureSamplerSampler, offset1,0.0);}\nfragmentOutputs.color=result/ f32(nSamples);\n#endif\n#else\nfragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler, input.vUV);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const motionBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"filterPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform mat4 kernelMatrix;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{vec3 baseColor=texture2D(textureSampler,vUV).rgb;vec3 updatedColor=(kernelMatrix*vec4(baseColor,1.0)).rgb;gl_FragColor=vec4(updatedColor,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const filterPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"filterPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform kernelMatrix: mat4x4f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var baseColor: vec3f=textureSample(textureSampler,textureSamplerSampler,input.vUV).rgb;var updatedColor: vec3f=(uniforms.kernelMatrix* vec4f(baseColor,1.0)).rgb;fragmentOutputs.color= vec4f(updatedColor,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const filterPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"highlightsPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;const vec3 RGBLuminanceCoefficients=vec3(0.2126,0.7152,0.0722);\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{vec4 tex=texture2D(textureSampler,vUV);vec3 c=tex.rgb;float luma=dot(c.rgb,RGBLuminanceCoefficients);gl_FragColor=vec4(pow(c,vec3(25.0-luma*15.0)),tex.a); }`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const highlightsPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"highlightsPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;const RGBLuminanceCoefficients: vec3f= vec3f(0.2126,0.7152,0.0722);\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var tex: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV);var c: vec3f=tex.rgb;var luma: f32=dot(c.rgb,RGBLuminanceCoefficients);fragmentOutputs.color= vec4f(pow(c, vec3f(25.0-luma*15.0)),tex.a); }`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const highlightsPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"displayPassPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D passSampler;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{gl_FragColor=texture2D(passSampler,vUV);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const displayPassPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"displayPassPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var passSamplerSampler: sampler;var passSampler: texture_2d<f32>;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureSample(passSampler,passSamplerSampler,input.vUV);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const displayPassPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"tonemapPixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform float _ExposureAdjustment;\n#if defined(HABLE_TONEMAPPING)\nconst float A=0.15;const float B=0.50;const float C=0.10;const float D=0.20;const float E=0.02;const float F=0.30;const float W=11.2;\n#endif\nfloat Luminance(vec3 c)\n{return dot(c,vec3(0.22,0.707,0.071));}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{vec3 colour=texture2D(textureSampler,vUV).rgb;\n#if defined(REINHARD_TONEMAPPING)\nfloat lum=Luminance(colour.rgb); \nfloat lumTm=lum*_ExposureAdjustment;float scale=lumTm/(1.0+lumTm); \ncolour*=scale/lum;\n#elif defined(HABLE_TONEMAPPING)\ncolour*=_ExposureAdjustment;const float ExposureBias=2.0;vec3 x=ExposureBias*colour;vec3 curr=((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;x=vec3(W,W,W);vec3 whiteScale=1.0/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);colour=curr*whiteScale;\n#elif defined(OPTIMIZED_HEJIDAWSON_TONEMAPPING)\ncolour*=_ExposureAdjustment;vec3 X=max(vec3(0.0,0.0,0.0),colour-0.004);vec3 retColor=(X*(6.2*X+0.5))/(X*(6.2*X+1.7)+0.06);colour=retColor*retColor;\n#elif defined(PHOTOGRAPHIC_TONEMAPPING)\ncolour= vec3(1.0,1.0,1.0)-exp2(-_ExposureAdjustment*colour);\n#endif\ngl_FragColor=vec4(colour.rgb,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const tonemapPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"tonemapPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform _ExposureAdjustment: f32;\n#if defined(HABLE_TONEMAPPING)\nconst A: f32=0.15;const B: f32=0.50;const C: f32=0.10;const D: f32=0.20;const E: f32=0.02;const F: f32=0.30;const W: f32=11.2;\n#endif\nfn Luminance(c: vec3f)->f32\n{return dot(c, vec3f(0.22,0.707,0.071));}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var colour: vec3f=textureSample(textureSampler,textureSamplerSampler,input.vUV).rgb;\n#if defined(REINHARD_TONEMAPPING)\nvar lum: f32=Luminance(colour.rgb); \nvar lumTm: f32=lum*uniforms._ExposureAdjustment;var scale: f32=lumTm/(1.0+lumTm); \ncolour*=scale/lum;\n#elif defined(HABLE_TONEMAPPING)\ncolour*=uniforms._ExposureAdjustment;const ExposureBias: f32=2.0;var x: vec3f=ExposureBias*colour;var curr: vec3f=((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;x= vec3f(W,W,W);var whiteScale: vec3f=1.0/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);colour=curr*whiteScale;\n#elif defined(OPTIMIZED_HEJIDAWSON_TONEMAPPING)\ncolour*=uniforms._ExposureAdjustment;var X: vec3f=max( vec3f(0.0,0.0,0.0),colour-0.004);var retColor: vec3f=(X*(6.2*X+0.5))/(X*(6.2*X+1.7)+0.06);colour=retColor*retColor;\n#elif defined(PHOTOGRAPHIC_TONEMAPPING)\ncolour= vec3f(1.0,1.0,1.0)-exp2(-uniforms._ExposureAdjustment*colour);\n#endif\nfragmentOutputs.color= vec4f(colour.rgb,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const tonemapPixelShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { Buffer, VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { Matrix, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { type Nullable, type FloatArray, type IndicesArray } from \"../types\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { BoundingBox } from \"../Culling/boundingBox\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { MaterialHelperGeometryRendering } from \"../Materials/materialHelper.geometryrendering\";\r\nimport { ShaderMaterial } from \"../Materials/shaderMaterial.pure\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { Observable } from \"../Misc/observable.pure\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { UniformBuffer } from \"../Materials/uniformBuffer\";\r\nimport { CreateBoxVertexData } from \"../Meshes/Builders/boxBuilder.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { _RetryWithInterval } from \"../Misc/timingTools\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\nconst TempMatrix = /*#__PURE__*/ Matrix.Identity();\r\nconst TempMatrix2 = /*#__PURE__*/ new Matrix();\r\nconst TempVec1 = /*#__PURE__*/ new Vector3();\r\nconst TempVec2 = /*#__PURE__*/ new Vector3();\r\n// `Matrix.asArray` returns its internal array, so it can be directly updated\r\nconst TempMatrixArray = /*#__PURE__*/ TempMatrix.asArray();\r\n\r\n// BoundingBox copies from it, so it's safe to reuse vectors here\r\nconst DummyBoundingBox = /*#__PURE__*/ new BoundingBox(TempVec1, TempVec1);\r\n\r\n/**\r\n * Component responsible of rendering the bounding box of the meshes in a scene.\r\n * This is usually used through the mesh.showBoundingBox or the scene.forceShowBoundingBoxes properties\r\n */\r\nexport class BoundingBoxRenderer implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_BOUNDINGBOXRENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Color of the bounding box lines placed in front of an object\r\n     */\r\n    public frontColor = new Color3(1, 1, 1);\r\n    /**\r\n     * Color of the bounding box lines placed behind an object\r\n     */\r\n    public backColor = new Color3(0.1, 0.1, 0.1);\r\n    /**\r\n     * Defines if the renderer should show the back lines or not\r\n     */\r\n    public showBackLines = true;\r\n\r\n    /**\r\n     * Observable raised before rendering a bounding box\r\n     * When {@link BoundingBoxRenderer.useInstances} enabled,\r\n     * this would only be triggered once for one rendering, instead of once every bounding box.\r\n     * Events would be triggered with a dummy box to keep backwards compatibility,\r\n     * the passed bounding box has no meaning and should be ignored.\r\n     */\r\n    public onBeforeBoxRenderingObservable = new Observable<BoundingBox>();\r\n\r\n    /**\r\n     * Observable raised after rendering a bounding box\r\n     * When {@link BoundingBoxRenderer.useInstances} enabled,\r\n     * this would only be triggered once for one rendering, instead of once every bounding box.\r\n     * Events would be triggered with a dummy box to keep backwards compatibility,\r\n     * the passed bounding box has no meaning and should be ignored.\r\n     */\r\n    public onAfterBoxRenderingObservable = new Observable<BoundingBox>();\r\n\r\n    /**\r\n     * Observable raised after resources are created\r\n     */\r\n    public onResourcesReadyObservable = new Observable<BoundingBoxRenderer>();\r\n\r\n    /**\r\n     * When false, no bounding boxes will be rendered\r\n     */\r\n    public enabled = true;\r\n\r\n    /** Shader language used by the renderer */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this renderer.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public renderList = new SmartArray<BoundingBox>(32);\r\n\r\n    private _colorShader: ShaderMaterial;\r\n    private _colorShaderForOcclusionQuery: ShaderMaterial;\r\n    private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    private _indexBuffer: DataBuffer;\r\n    private _fillIndexBuffer: Nullable<DataBuffer> = null;\r\n    private _fillIndexData: Nullable<IndicesArray> = null;\r\n    private _uniformBufferFront: UniformBuffer;\r\n    private _uniformBufferBack: UniformBuffer;\r\n    private _renderPassIdForOcclusionQuery: number;\r\n    /**\r\n     * Internal buffer for instanced rendering\r\n     */\r\n    private _matrixBuffer: Nullable<Buffer> = null;\r\n    private _matrices: Nullable<Float32Array> = null;\r\n\r\n    /**\r\n     * Internal state of whether instanced rendering enabled\r\n     */\r\n    protected _useInstances = false;\r\n\r\n    /** @internal */\r\n    public _drawWrapperFront: Nullable<DrawWrapper> = null;\r\n    /** @internal */\r\n    public _drawWrapperBack: Nullable<DrawWrapper> = null;\r\n\r\n    /**\r\n     * Instantiates a new bounding box renderer in a scene.\r\n     * @param scene the scene the  renderer renders in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n\r\n        const engine = this.scene.getEngine();\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        scene._addComponent(this);\r\n        this._uniformBufferFront = new UniformBuffer(this.scene.getEngine(), undefined, undefined, \"BoundingBoxRendererFront\", true);\r\n        this._buildUniformLayout(this._uniformBufferFront);\r\n        this._uniformBufferBack = new UniformBuffer(this.scene.getEngine(), undefined, undefined, \"BoundingBoxRendererBack\", true);\r\n        this._buildUniformLayout(this._uniformBufferBack);\r\n    }\r\n\r\n    private _buildUniformLayout(ubo: UniformBuffer): void {\r\n        ubo.addUniform(\"color\", 4);\r\n        ubo.addUniform(\"world\", 16);\r\n        ubo.addUniform(\"viewProjection\", 16);\r\n        ubo.addUniform(\"viewProjectionR\", 16);\r\n        ubo.create();\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._beforeEvaluateActiveMeshStage.registerStep(SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER, this, this.reset);\r\n\r\n        this.scene._preActiveMeshStage.registerStep(SceneComponentConstants.STEP_PREACTIVEMESH_BOUNDINGBOXRENDERER, this, this._preActiveMesh);\r\n\r\n        this.scene._evaluateSubMeshStage.registerStep(SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER, this, this._evaluateSubMesh);\r\n\r\n        this.scene._afterRenderingGroupDrawStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_BOUNDINGBOXRENDERER, this, this.render);\r\n    }\r\n\r\n    /**\r\n     * Checks if the renderer is ready asynchronously.\r\n     * @param timeStep Time step in ms between retries (default is 16)\r\n     * @param maxTimeout Maximum time in ms to wait for the graph to be ready (default is 30000)\r\n     * @returns The promise that resolves when the renderer is ready\r\n     */\r\n    public async whenReadyAsync(timeStep = 16, maxTimeout = 30000): Promise<void> {\r\n        this._prepareResources();\r\n        return await new Promise((resolve) => {\r\n            _RetryWithInterval(\r\n                () => {\r\n                    return this._colorShader.isReady();\r\n                },\r\n                () => {\r\n                    resolve();\r\n                },\r\n                (err, isTimeout) => {\r\n                    if (!isTimeout) {\r\n                        Logger.Error(\"BoundingBoxRenderer: An unexpected error occurred while waiting for the renderer to be ready.\");\r\n                        if (err) {\r\n                            Logger.Error(err);\r\n                            if (err.stack) {\r\n                                Logger.Error(err.stack);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        Logger.Error(`BoundingBoxRenderer: Timeout while waiting for the renderer to be ready.`);\r\n                        if (err) {\r\n                            Logger.Error(err);\r\n                        }\r\n                    }\r\n                },\r\n                timeStep,\r\n                maxTimeout\r\n            );\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public _evaluateSubMesh(mesh: AbstractMesh, subMesh: SubMesh): void {\r\n        if (mesh.showSubMeshesBoundingBox) {\r\n            const boundingInfo = subMesh.getBoundingInfo();\r\n            if (boundingInfo !== null && boundingInfo !== undefined) {\r\n                boundingInfo.boundingBox._tag = mesh.renderingGroupId;\r\n                this.renderList.push(boundingInfo.boundingBox);\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _preActiveMesh(mesh: AbstractMesh): void {\r\n        if (mesh.showBoundingBox || this.scene.forceShowBoundingBoxes) {\r\n            const boundingInfo = mesh.getBoundingInfo();\r\n            boundingInfo.boundingBox._tag = mesh.renderingGroupId;\r\n            this.renderList.push(boundingInfo.boundingBox);\r\n        }\r\n    }\r\n\r\n    private _prepareResources(): void {\r\n        if (this._colorShader) {\r\n            return;\r\n        }\r\n\r\n        this._colorShader = new ShaderMaterial(\r\n            \"colorShader\",\r\n            this.scene,\r\n            \"boundingBoxRenderer\",\r\n            {\r\n                attributes: [VertexBuffer.PositionKind, \"world0\", \"world1\", \"world2\", \"world3\"],\r\n\r\n                uniforms: [\"world\", \"viewProjection\", \"viewProjectionR\", \"color\"],\r\n                uniformBuffers: [\"BoundingBoxRenderer\"],\r\n                shaderLanguage: this._shaderLanguage,\r\n                extraInitializationsAsync: async () => {\r\n                    if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await Promise.all([import(\"../ShadersWGSL/boundingBoxRenderer.vertex\"), import(\"../ShadersWGSL/boundingBoxRenderer.fragment\")]);\r\n                    } else {\r\n                        await Promise.all([import(\"../Shaders/boundingBoxRenderer.vertex\"), import(\"../Shaders/boundingBoxRenderer.fragment\")]);\r\n                    }\r\n                },\r\n            },\r\n            false\r\n        );\r\n        this._colorShader.setDefine(\"INSTANCES\", this._useInstances);\r\n        this._colorShader.doNotSerialize = true;\r\n\r\n        this._colorShader.reservedDataStore = {\r\n            hidden: true,\r\n        };\r\n\r\n        this._colorShaderForOcclusionQuery = new ShaderMaterial(\r\n            \"colorShaderOccQuery\",\r\n            this.scene,\r\n            \"boundingBoxRenderer\",\r\n            {\r\n                attributes: [VertexBuffer.PositionKind],\r\n                uniforms: [\"world\", \"viewProjection\", \"viewProjectionR\", \"color\"],\r\n                uniformBuffers: [\"BoundingBoxRenderer\"],\r\n                shaderLanguage: this._shaderLanguage,\r\n                extraInitializationsAsync: async () => {\r\n                    if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await Promise.all([import(\"../ShadersWGSL/boundingBoxRenderer.vertex\"), import(\"../ShadersWGSL/boundingBoxRenderer.fragment\")]);\r\n                    } else {\r\n                        await Promise.all([import(\"../Shaders/boundingBoxRenderer.vertex\"), import(\"../Shaders/boundingBoxRenderer.fragment\")]);\r\n                    }\r\n                },\r\n            },\r\n            true\r\n        );\r\n        this._colorShaderForOcclusionQuery.doNotSerialize = true;\r\n\r\n        this._colorShaderForOcclusionQuery.reservedDataStore = {\r\n            hidden: true,\r\n        };\r\n\r\n        const engine = this.scene.getEngine();\r\n        const boxdata = CreateBoxVertexData({ size: 1.0 });\r\n        this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, <FloatArray>boxdata.positions, VertexBuffer.PositionKind, false);\r\n        this._createIndexBuffer();\r\n        this._fillIndexData = boxdata.indices;\r\n        this.onResourcesReadyObservable.notifyObservers(this);\r\n    }\r\n\r\n    private _createIndexBuffer(): void {\r\n        const engine = this.scene.getEngine();\r\n        this._indexBuffer = engine.createIndexBuffer([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 7, 1, 6, 2, 5, 3, 4]);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        const vb = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (vb) {\r\n            vb._rebuild();\r\n        }\r\n        this._createIndexBuffer();\r\n\r\n        if (this._matrixBuffer) {\r\n            this._matrixBuffer._rebuild();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public reset(): void {\r\n        this.renderList.reset();\r\n    }\r\n\r\n    /**\r\n     * Render the bounding boxes of a specific rendering group\r\n     * @param renderingGroupId defines the rendering group to render\r\n     */\r\n    public render(renderingGroupId: number): void {\r\n        if (this.renderList.length === 0 || !this.enabled || !MaterialHelperGeometryRendering._BindColorAttachments(this.scene.getEngine())) {\r\n            return;\r\n        }\r\n\r\n        if (this._useInstances) {\r\n            this._renderInstanced(renderingGroupId);\r\n            return;\r\n        }\r\n\r\n        this._prepareResources();\r\n\r\n        if (!this._colorShader.isReady()) {\r\n            return;\r\n        }\r\n\r\n        const engine = this.scene.getEngine();\r\n        engine.setDepthWrite(false);\r\n\r\n        const transformMatrix = this.scene.getTransformMatrix();\r\n\r\n        for (let boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {\r\n            const boundingBox = this.renderList.data[boundingBoxIndex];\r\n            if (boundingBox._tag !== renderingGroupId) {\r\n                continue;\r\n            }\r\n\r\n            this._createWrappersForBoundingBox(boundingBox);\r\n            this.onBeforeBoxRenderingObservable.notifyObservers(boundingBox);\r\n\r\n            const min = boundingBox.minimum;\r\n            const max = boundingBox.maximum;\r\n            const diff = max.subtract(min);\r\n            const median = min.add(diff.scale(0.5));\r\n\r\n            const worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)\r\n                .multiply(Matrix.Translation(median.x, median.y, median.z))\r\n                .multiply(boundingBox.getWorldMatrix());\r\n\r\n            const useReverseDepthBuffer = engine.useReverseDepthBuffer;\r\n\r\n            if (this.showBackLines) {\r\n                const drawWrapperBack = boundingBox._drawWrapperBack ?? this._colorShader._getDrawWrapper();\r\n\r\n                this._colorShader._preBind(drawWrapperBack);\r\n\r\n                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());\r\n\r\n                // Back\r\n                if (useReverseDepthBuffer) {\r\n                    engine.setDepthFunctionToLessOrEqual();\r\n                } else {\r\n                    engine.setDepthFunctionToGreaterOrEqual();\r\n                }\r\n                this._uniformBufferBack.bindToEffect(drawWrapperBack.effect!, \"BoundingBoxRenderer\");\r\n                this._uniformBufferBack.updateColor4(\"color\", this.backColor, 1);\r\n                this._uniformBufferBack.updateMatrix(\"world\", worldMatrix);\r\n                this._uniformBufferBack.updateMatrix(\"viewProjection\", transformMatrix);\r\n                this._uniformBufferBack.update();\r\n\r\n                // Draw order\r\n                engine.drawElementsType(Material.LineListDrawMode, 0, 24);\r\n            }\r\n\r\n            const drawWrapperFront = boundingBox._drawWrapperFront ?? this._colorShader._getDrawWrapper();\r\n\r\n            this._colorShader._preBind(drawWrapperFront);\r\n\r\n            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());\r\n\r\n            // Front\r\n            if (useReverseDepthBuffer) {\r\n                engine.setDepthFunctionToGreater();\r\n            } else {\r\n                engine.setDepthFunctionToLess();\r\n            }\r\n            this._uniformBufferFront.bindToEffect(drawWrapperFront.effect!, \"BoundingBoxRenderer\");\r\n            this._uniformBufferFront.updateColor4(\"color\", this.frontColor, 1);\r\n            this._uniformBufferFront.updateMatrix(\"world\", worldMatrix);\r\n            this._uniformBufferFront.updateMatrix(\"viewProjection\", transformMatrix);\r\n            this._uniformBufferFront.update();\r\n\r\n            // Draw order\r\n            engine.drawElementsType(Material.LineListDrawMode, 0, 24);\r\n\r\n            this.onAfterBoxRenderingObservable.notifyObservers(boundingBox);\r\n        }\r\n        this._colorShader.unbind();\r\n        engine.setDepthFunctionToLessOrEqual();\r\n        engine.setDepthWrite(true);\r\n    }\r\n\r\n    private _createWrappersForBoundingBox(boundingBox: BoundingBox | BoundingBoxRenderer): void {\r\n        if (!boundingBox._drawWrapperFront) {\r\n            const engine = this.scene.getEngine();\r\n\r\n            boundingBox._drawWrapperFront = new DrawWrapper(engine);\r\n            boundingBox._drawWrapperBack = new DrawWrapper(engine);\r\n\r\n            boundingBox._drawWrapperFront.setEffect(this._colorShader.getEffect());\r\n            boundingBox._drawWrapperBack.setEffect(this._colorShader.getEffect());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * In case of occlusion queries, we can render the occlusion bounding box through this method\r\n     * @param mesh Define the mesh to render the occlusion bounding box for\r\n     */\r\n    public renderOcclusionBoundingBox(mesh: AbstractMesh): void {\r\n        const engine = this.scene.getEngine();\r\n\r\n        if (this._renderPassIdForOcclusionQuery === undefined) {\r\n            this._renderPassIdForOcclusionQuery = engine.createRenderPassId(`Render pass for occlusion query`);\r\n        }\r\n\r\n        const currentRenderPassId = engine.currentRenderPassId;\r\n\r\n        engine.currentRenderPassId = this._renderPassIdForOcclusionQuery;\r\n\r\n        this._prepareResources();\r\n\r\n        const subMesh = mesh.subMeshes[0];\r\n\r\n        if (!this._colorShaderForOcclusionQuery.isReady(mesh, undefined, subMesh) || !mesh.hasBoundingInfo) {\r\n            engine.currentRenderPassId = currentRenderPassId;\r\n            return;\r\n        }\r\n\r\n        if (!this._fillIndexBuffer) {\r\n            this._fillIndexBuffer = engine.createIndexBuffer(this._fillIndexData!);\r\n        }\r\n\r\n        const useReverseDepthBuffer = engine.useReverseDepthBuffer;\r\n\r\n        engine.setDepthWrite(false);\r\n        engine.setColorWrite(false);\r\n\r\n        const boundingBox = mesh.getBoundingInfo().boundingBox;\r\n        const min = boundingBox.minimum;\r\n        const max = boundingBox.maximum;\r\n        const diff = max.subtract(min);\r\n        const median = min.add(diff.scale(0.5));\r\n\r\n        const worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)\r\n            .multiply(Matrix.Translation(median.x, median.y, median.z))\r\n            .multiply(boundingBox.getWorldMatrix());\r\n\r\n        const drawWrapper = subMesh._drawWrapper;\r\n\r\n        this._colorShaderForOcclusionQuery._preBind(drawWrapper);\r\n\r\n        engine.bindBuffers(this._vertexBuffers, this._fillIndexBuffer, <Effect>drawWrapper.effect);\r\n\r\n        if (useReverseDepthBuffer) {\r\n            engine.setDepthFunctionToGreater();\r\n        } else {\r\n            engine.setDepthFunctionToLess();\r\n        }\r\n\r\n        this.scene.resetCachedMaterial();\r\n\r\n        this._uniformBufferFront.bindToEffect(drawWrapper.effect!, \"BoundingBoxRenderer\");\r\n        this._uniformBufferFront.updateMatrix(\"world\", worldMatrix);\r\n        this._uniformBufferFront.updateMatrix(\"viewProjection\", this.scene.getTransformMatrix());\r\n        this._uniformBufferFront.update();\r\n\r\n        engine.drawElementsType(Material.TriangleFillMode, 0, 36);\r\n\r\n        this._colorShaderForOcclusionQuery.unbind();\r\n        engine.setDepthFunctionToLessOrEqual();\r\n        engine.setDepthWrite(true);\r\n        engine.setColorWrite(true);\r\n\r\n        engine.currentRenderPassId = currentRenderPassId;\r\n    }\r\n\r\n    /**\r\n     * Sets whether to use instanced rendering.\r\n     * When not enabled, BoundingBoxRenderer renders in a loop,\r\n     * calling engine.drawElementsType for each bounding box in renderList,\r\n     * making every bounding box 1 or 2 draw call.\r\n     * When enabled, it collects bounding boxes to render,\r\n     * and render all boxes in 1 or 2 draw call.\r\n     * This could make the rendering with many bounding boxes much faster than not enabled,\r\n     * but could result in a difference in rendering result if\r\n     * {@link BoundingBoxRenderer.showBackLines} enabled,\r\n     * because drawing the black/white part of each box one after the other\r\n     * can be different from drawing the black part of all boxes and then the white part.\r\n     * Also, when enabled, events of {@link BoundingBoxRenderer.onBeforeBoxRenderingObservable}\r\n     * and {@link BoundingBoxRenderer.onAfterBoxRenderingObservable} would only be triggered once\r\n     * for one rendering, instead of once every bounding box.\r\n     * Events would be triggered with a dummy box to keep backwards compatibility,\r\n     * the passed bounding box has no meaning and should be ignored.\r\n     * @param val whether to use instanced rendering\r\n     */\r\n    public set useInstances(val: boolean) {\r\n        this._useInstances = val;\r\n        if (this._colorShader) {\r\n            this._colorShader.setDefine(\"INSTANCES\", val);\r\n        }\r\n        if (!val) {\r\n            this._cleanupInstances();\r\n        }\r\n    }\r\n\r\n    public get useInstances(): boolean {\r\n        return this._useInstances;\r\n    }\r\n\r\n    /**\r\n     * Instanced render the bounding boxes of a specific rendering group\r\n     * @param renderingGroupId defines the rendering group to render\r\n     */\r\n    private _renderInstanced(renderingGroupId: number): void {\r\n        if (this.renderList.length === 0 || !this.enabled) {\r\n            return;\r\n        }\r\n        this._prepareResources();\r\n\r\n        if (!this._colorShader.isReady()) {\r\n            return;\r\n        }\r\n\r\n        const colorShader = this._colorShader;\r\n        let matrices = this._matrices;\r\n        const expectedLength = this.renderList.length * 16;\r\n        if (!matrices || matrices.length < expectedLength || matrices.length > expectedLength * 2) {\r\n            matrices = new Float32Array(expectedLength);\r\n            this._matrices = matrices;\r\n        }\r\n\r\n        this.onBeforeBoxRenderingObservable.notifyObservers(DummyBoundingBox);\r\n\r\n        let instancesCount = 0;\r\n        const floatingOriginOffset = this.scene.floatingOriginOffset;\r\n\r\n        for (let boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {\r\n            const boundingBox = this.renderList.data[boundingBoxIndex];\r\n            if (boundingBox._tag !== renderingGroupId) {\r\n                continue;\r\n            }\r\n\r\n            const min = boundingBox.minimum;\r\n            const max = boundingBox.maximum;\r\n\r\n            const diff = max.subtractToRef(min, TempVec2);\r\n            const median = min.addToRef(diff.scaleToRef(0.5, TempVec1), TempVec1);\r\n\r\n            const m = TempMatrixArray;\r\n\r\n            // Directly update the matrix values in column-major order\r\n            m[0] = diff._x; // Scale X\r\n            m[5] = diff._y; // Scale Y\r\n            m[10] = diff._z; // Scale Z\r\n\r\n            m[12] = median._x; // Translate X\r\n            m[13] = median._y; // Translate Y\r\n            m[14] = median._z; // Translate Z\r\n\r\n            const offset = instancesCount * 16;\r\n            // Multiply into Float64 temp matrix, subtract offset in Float64, then copy to Float32 buffer\r\n            // to preserve precision at large coordinates.\r\n            const resultM = TempMatrix2.asArray();\r\n            TempMatrix.multiplyToArray(boundingBox.getWorldMatrix(), resultM, 0);\r\n            resultM[12] -= floatingOriginOffset.x;\r\n            resultM[13] -= floatingOriginOffset.y;\r\n            resultM[14] -= floatingOriginOffset.z;\r\n            TempMatrix2.copyToArray(matrices, offset);\r\n            instancesCount++;\r\n        }\r\n\r\n        const engine = this.scene.getEngine();\r\n        // keeps the original depth function and depth write\r\n        const depthFunction = engine.getDepthFunction() ?? Constants.LEQUAL;\r\n        const depthWrite = engine.getDepthWrite();\r\n        engine.setDepthWrite(false);\r\n        const matrixBuffer = this._matrixBuffer;\r\n        if (matrixBuffer?.isUpdatable() && matrixBuffer.getData() === matrices) {\r\n            matrixBuffer.update(matrices);\r\n        } else {\r\n            this._createInstanceBuffer(matrices);\r\n        }\r\n\r\n        this._createWrappersForBoundingBox(this);\r\n\r\n        const useReverseDepthBuffer = engine.useReverseDepthBuffer;\r\n        const transformMatrix = this.scene.getTransformMatrix();\r\n\r\n        if (this.showBackLines) {\r\n            const drawWrapperBack = this._drawWrapperBack ?? colorShader._getDrawWrapper();\r\n\r\n            colorShader._preBind(drawWrapperBack);\r\n\r\n            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, colorShader.getEffect());\r\n\r\n            // Back\r\n            if (useReverseDepthBuffer) {\r\n                engine.setDepthFunctionToLessOrEqual();\r\n            } else {\r\n                engine.setDepthFunctionToGreaterOrEqual();\r\n            }\r\n            const _uniformBufferBack: UniformBuffer = this._uniformBufferBack;\r\n\r\n            _uniformBufferBack.bindToEffect(drawWrapperBack.effect!, \"BoundingBoxRenderer\");\r\n            _uniformBufferBack.updateColor4(\"color\", this.backColor, 1);\r\n            _uniformBufferBack.updateMatrix(\"viewProjection\", transformMatrix);\r\n            _uniformBufferBack.update();\r\n\r\n            // Draw order\r\n            engine.drawElementsType(Material.LineListDrawMode, 0, 24, instancesCount);\r\n        }\r\n\r\n        const drawWrapperFront = colorShader._getDrawWrapper();\r\n\r\n        colorShader._preBind(drawWrapperFront);\r\n\r\n        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, colorShader.getEffect());\r\n\r\n        // Front\r\n        if (useReverseDepthBuffer) {\r\n            engine.setDepthFunctionToGreater();\r\n        } else {\r\n            engine.setDepthFunctionToLess();\r\n        }\r\n        const _uniformBufferFront: UniformBuffer = this._uniformBufferFront;\r\n        _uniformBufferFront.bindToEffect(drawWrapperFront.effect!, \"BoundingBoxRenderer\");\r\n        _uniformBufferFront.updateColor4(\"color\", this.frontColor, 1);\r\n        _uniformBufferFront.updateMatrix(\"viewProjection\", transformMatrix);\r\n        _uniformBufferFront.update();\r\n\r\n        // Draw order\r\n        engine.drawElementsType(Material.LineListDrawMode, 0, 24, instancesCount);\r\n\r\n        this.onAfterBoxRenderingObservable.notifyObservers(DummyBoundingBox);\r\n\r\n        colorShader.unbind();\r\n        engine.setDepthFunction(depthFunction);\r\n        engine.setDepthWrite(depthWrite);\r\n    }\r\n\r\n    /**\r\n     * Creates buffer for instanced rendering\r\n     * @param buffer buffer to set\r\n     */\r\n    private _createInstanceBuffer(buffer: Float32Array): void {\r\n        const vertexBuffers = this._vertexBuffers;\r\n        this._cleanupInstanceBuffer();\r\n        const matrixBuffer = new Buffer(this.scene.getEngine(), buffer, true, 16, false, true);\r\n\r\n        vertexBuffers.world0 = matrixBuffer.createVertexBuffer(\"world0\", 0, 4);\r\n        vertexBuffers.world1 = matrixBuffer.createVertexBuffer(\"world1\", 4, 4);\r\n        vertexBuffers.world2 = matrixBuffer.createVertexBuffer(\"world2\", 8, 4);\r\n        vertexBuffers.world3 = matrixBuffer.createVertexBuffer(\"world3\", 12, 4);\r\n\r\n        this._matrixBuffer = matrixBuffer;\r\n    }\r\n\r\n    /**\r\n     * Clean up buffers for instanced rendering\r\n     */\r\n    private _cleanupInstanceBuffer(): void {\r\n        const vertexBuffers = this._vertexBuffers;\r\n        if (vertexBuffers.world0) {\r\n            vertexBuffers.world0.dispose();\r\n            delete vertexBuffers.world0;\r\n        }\r\n        if (vertexBuffers.world1) {\r\n            vertexBuffers.world1.dispose();\r\n            delete vertexBuffers.world1;\r\n        }\r\n        if (vertexBuffers.world2) {\r\n            vertexBuffers.world2.dispose();\r\n            delete vertexBuffers.world2;\r\n        }\r\n        if (vertexBuffers.world3) {\r\n            vertexBuffers.world3.dispose();\r\n            delete vertexBuffers.world3;\r\n        }\r\n        this._matrices = null;\r\n        if (this._matrixBuffer) {\r\n            this._matrixBuffer.dispose();\r\n            this._matrixBuffer = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clean up resources for instanced rendering\r\n     */\r\n    private _cleanupInstances(): void {\r\n        this._cleanupInstanceBuffer();\r\n        if (this._drawWrapperFront) {\r\n            this._drawWrapperFront.dispose();\r\n            this._drawWrapperFront = null;\r\n        }\r\n        if (this._drawWrapperBack) {\r\n            this._drawWrapperBack.dispose();\r\n            this._drawWrapperBack = null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose and release the resources attached to this renderer.\r\n     */\r\n    public dispose(): void {\r\n        if (this._renderPassIdForOcclusionQuery !== undefined) {\r\n            this.scene.getEngine().releaseRenderPassId(this._renderPassIdForOcclusionQuery);\r\n            this._renderPassIdForOcclusionQuery = undefined as any;\r\n        }\r\n\r\n        if (!this._colorShader) {\r\n            return;\r\n        }\r\n\r\n        this.onBeforeBoxRenderingObservable.clear();\r\n        this.onAfterBoxRenderingObservable.clear();\r\n        this.onResourcesReadyObservable.clear();\r\n\r\n        this.renderList.dispose();\r\n\r\n        this._colorShader.dispose();\r\n        this._colorShaderForOcclusionQuery.dispose();\r\n\r\n        this._uniformBufferFront.dispose();\r\n        this._uniformBufferBack.dispose();\r\n\r\n        const buffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n        if (buffer) {\r\n            buffer.dispose();\r\n            this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n        this.scene.getEngine()._releaseBuffer(this._indexBuffer);\r\n\r\n        if (this._fillIndexBuffer) {\r\n            this.scene.getEngine()._releaseBuffer(this._fillIndexBuffer);\r\n            this._fillIndexBuffer = null;\r\n        }\r\n        this._cleanupInstances();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for boundingBoxRenderer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterBoundingBoxRenderer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"forceShowBoundingBoxes\", {\r\n        get: function (this: Scene) {\r\n            return this._forceShowBoundingBoxes || false;\r\n        },\r\n        set: function (this: Scene, value: boolean) {\r\n            this._forceShowBoundingBoxes = value;\r\n            // Lazyly creates a BB renderer if needed.\r\n            if (value) {\r\n                this.getBoundingBoxRenderer();\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.getBoundingBoxRenderer = function (): BoundingBoxRenderer {\r\n        if (!this._boundingBoxRenderer) {\r\n            this._boundingBoxRenderer = new BoundingBoxRenderer(this);\r\n        }\r\n\r\n        return this._boundingBoxRenderer;\r\n    };\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"showBoundingBox\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._showBoundingBox || false;\r\n        },\r\n        set: function (this: AbstractMesh, value: boolean) {\r\n            this._showBoundingBox = value;\r\n            // Lazyly creates a BB renderer if needed.\r\n            if (value) {\r\n                this.getScene().getBoundingBoxRenderer();\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { packingFunctions } from \"./ShadersInclude/packingFunctions\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"depthPixelShader\";\nconst shader = `#ifdef ALPHATEST\nvarying vec2 vUV;uniform sampler2D diffuseSampler;\n#endif\n#include<clipPlaneFragmentDeclaration>\nvarying float vDepthMetric;\n#ifdef PACKED\n#include<packingFunctions>\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvarying vec4 vViewPos;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\n#ifdef STORE_CAMERASPACE_Z\n#ifdef PACKED\ngl_FragColor=pack(vViewPos.z);\n#else\ngl_FragColor=vec4(vViewPos.z,0.0,0.0,1.0);\n#endif\n#else\n#ifdef NONLINEARDEPTH\n#ifdef PACKED\ngl_FragColor=pack(gl_FragCoord.z);\n#else\ngl_FragColor=vec4(gl_FragCoord.z,0.0,0.0,0.0);\n#endif\n#else\n#ifdef PACKED\ngl_FragColor=pack(vDepthMetric);\n#else\ngl_FragColor=vec4(vDepthMetric,0.0,0.0,1.0);\n#endif\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclaration, packingFunctions, clipPlaneFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const depthPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { packingFunctionsWGSL } from \"./ShadersInclude/packingFunctions\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"depthPixelShader\";\nconst shader = `#ifdef ALPHATEST\nvarying vUV: vec2f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#include<clipPlaneFragmentDeclaration>\nvarying vDepthMetric: f32;\n#ifdef PACKED\n#include<packingFunctions>\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvarying vViewPos: vec4f;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (textureSample(diffuseSampler,diffuseSamplerSampler,input.vUV).a<0.4) {discard;}\n#endif\n#ifdef STORE_CAMERASPACE_Z\n#ifdef PACKED\nfragmentOutputs.color=pack(input.vViewPos.z);\n#else\nfragmentOutputs.color= vec4f(input.vViewPos.z,0.0,0.0,1.0);\n#endif\n#else\n#ifdef NONLINEARDEPTH\n#ifdef PACKED\nfragmentOutputs.color=pack(input.position.z);\n#else\nfragmentOutputs.color= vec4f(input.position.z,0.0,0.0,0.0);\n#endif\n#else\n#ifdef PACKED\nfragmentOutputs.color=pack(input.vDepthMetric);\n#else\nfragmentOutputs.color= vec4f(input.vDepthMetric,0.0,0.0,1.0);\n#endif\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclarationWGSL, packingFunctionsWGSL, clipPlaneFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const depthPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"depthVertexShader\";\nconst shader = `attribute position: vec3f;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;uniform depthValues: vec2f;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vUV: vec2f;uniform diffuseMatrix: mat4x4f;\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#endif\n#ifdef STORE_CAMERASPACE_Z\nuniform view: mat4x4f;varying vViewPos: vec4f;\n#endif\nvarying vDepthMetric: f32;\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld* vec4f(positionUpdated,1.0);\n#include<clipPlaneVertex>\nvertexOutputs.position=uniforms.viewProjection*worldPos;\n#ifdef STORE_CAMERASPACE_Z\nvertexOutputs.vViewPos=uniforms.view*worldPos;\n#else\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric=((-vertexOutputs.position.z+uniforms.depthValues.x)/(uniforms.depthValues.y));\n#else\nvertexOutputs.vDepthMetric=((vertexOutputs.position.z+uniforms.depthValues.x)/(uniforms.depthValues.y));\n#endif\n#endif\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvertexOutputs.vUV= (uniforms.diffuseMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef UV2\nvertexOutputs.vUV= (uniforms.diffuseMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, instancesDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const depthVertexShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { type DepthPeelingRenderer } from \"./depthPeelingRenderer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type ThinDepthPeelingRenderer } from \"./thinDepthPeelingRenderer.pure\";\r\n\r\nlet _DepthPeelingRendererClass: typeof DepthPeelingRenderer;\r\n\r\n/**\r\n * Scene component to render order independent transparency with depth peeling\r\n */\r\nexport class DepthPeelingSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_DEPTHPEELINGRENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n\r\n        scene.depthPeelingRenderer = new _DepthPeelingRendererClass(scene);\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {}\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {}\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        this.scene.depthPeelingRenderer?.dispose();\r\n        this.scene.depthPeelingRenderer = null;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for depthPeelingSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param depthPeelingRendererClass The DepthPeelingRenderer class to use for instantiation\r\n */\r\nexport function RegisterDepthPeelingSceneComponent(depthPeelingRendererClass: typeof DepthPeelingRenderer): void {\r\n    _DepthPeelingRendererClass = depthPeelingRendererClass;\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    Object.defineProperty(Scene.prototype, \"depthPeelingRenderer\", {\r\n        get: function (this: Scene) {\r\n            if (!this._depthPeelingRenderer) {\r\n                let component = this._getComponent(SceneComponentConstants.NAME_DEPTHPEELINGRENDERER) as DepthPeelingSceneComponent;\r\n                if (!component) {\r\n                    component = new DepthPeelingSceneComponent(this);\r\n                    this._addComponent(component);\r\n                }\r\n            }\r\n\r\n            return this._depthPeelingRenderer;\r\n        },\r\n        set: function (this: Scene, value: ThinDepthPeelingRenderer) {\r\n            this._depthPeelingRenderer = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"useOrderIndependentTransparency\", {\r\n        get: function (this: Scene) {\r\n            return this._useOrderIndependentTransparency;\r\n        },\r\n        set: function (this: Scene, value: boolean) {\r\n            if (this._useOrderIndependentTransparency === value) {\r\n                return;\r\n            }\r\n            this._useOrderIndependentTransparency = value;\r\n            this.markAllMaterialsAsDirty(Constants.MATERIAL_AllDirtyFlag);\r\n            this.prePassRenderer?.markAsDirty();\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","/**\r\n * Implementation based on https://medium.com/@shrekshao_71662/dual-depth-peeling-implementation-in-webgl-11baa061ba4b\r\n */\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Scene } from \"../scene\";\r\nimport { ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\nimport { type PrePassRenderer } from \"./prePassRenderer\";\r\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { ThinDepthPeelingRenderer } from \"./thinDepthPeelingRenderer.pure\";\r\nimport { RegisterDepthPeelingSceneComponent } from \"./depthPeelingSceneComponent.pure\";\r\n\r\nclass DepthPeelingEffectConfiguration implements PrePassEffectConfiguration {\r\n    /**\r\n     * Is this effect enabled\r\n     */\r\n    public enabled = true;\r\n\r\n    /**\r\n     * Name of the configuration\r\n     */\r\n    public name = \"depthPeeling\";\r\n\r\n    /**\r\n     * Textures that should be present in the MRT for this effect to work\r\n     */\r\n    public readonly texturesRequired: number[] = [Constants.PREPASS_COLOR_TEXTURE_TYPE];\r\n}\r\n\r\n/**\r\n * The depth peeling renderer that performs\r\n * Order independant transparency (OIT).\r\n * This should not be instanciated directly, as it is part of a scene component\r\n */\r\nexport class DepthPeelingRenderer extends ThinDepthPeelingRenderer {\r\n    private _outputRT: RenderTargetTexture;\r\n\r\n    private _prePassEffectConfiguration: DepthPeelingEffectConfiguration;\r\n\r\n    private _blendBackTexture: InternalTexture;\r\n\r\n    /**\r\n     * Instanciates the depth peeling renderer\r\n     * @param scene Scene to attach to\r\n     * @param passCount Number of depth layers to peel\r\n     * @returns The depth peeling renderer\r\n     */\r\n    constructor(scene: Scene, passCount: number = 5) {\r\n        super(scene, passCount);\r\n\r\n        RegisterDepthPeelingSceneComponent(DepthPeelingRenderer);\r\n\r\n        //  We need a depth texture for opaque\r\n        if (!scene.enablePrePassRenderer()) {\r\n            Logger.Warn(\"Depth peeling for order independant transparency could not enable PrePass, aborting.\");\r\n            return;\r\n        }\r\n\r\n        this._prePassEffectConfiguration = new DepthPeelingEffectConfiguration();\r\n        this._createTextures();\r\n        this._createEffects(\"oitFinal\", [\"uFrontColor\", \"uBackColor\"]);\r\n    }\r\n\r\n    protected override _createTextures() {\r\n        super._createTextures();\r\n\r\n        const size = this._getTextureSize();\r\n\r\n        this._outputRT = new RenderTargetTexture(\"depthPeelingOutputRTT\", size, this._scene, false);\r\n    }\r\n\r\n    // TODO : explore again MSAA with depth peeling when\r\n    // we are able to fetch individual samples in a multisampled renderbuffer\r\n    // public set samples(value: number) {\r\n    //     for (let i = 0; i < 2; i++) {\r\n    //         this._depthMrts[i].samples = value;\r\n    //         this._colorMrts[i].samples = value;\r\n    //     }\r\n    //     this._scene.prePassRenderer!.samples = value;\r\n    // }\r\n\r\n    protected override _disposeTextures() {\r\n        for (let i = 0; i < this._thinTextures.length; i++) {\r\n            if (i === 6) {\r\n                // Do not dispose the shared texture with the prepass\r\n                continue;\r\n            }\r\n            this._thinTextures[i].dispose();\r\n        }\r\n        this._thinTextures = [];\r\n        this._outputRT.dispose();\r\n\r\n        super._disposeTextures();\r\n    }\r\n\r\n    private _updateTextures() {\r\n        if (this._depthMrts[0].getSize().width !== this._engine.getRenderWidth() || this._depthMrts[0].getSize().height !== this._engine.getRenderHeight()) {\r\n            this._disposeTextures();\r\n            this._createTextures();\r\n        }\r\n        return this._updateTextureReferences();\r\n    }\r\n\r\n    private _updateTextureReferences() {\r\n        const prePassRenderer = this._scene.prePassRenderer;\r\n\r\n        if (!prePassRenderer) {\r\n            return false;\r\n        }\r\n\r\n        // Retrieve opaque color texture\r\n        const textureIndex = prePassRenderer.getIndex(Constants.PREPASS_COLOR_TEXTURE_TYPE);\r\n        const prePassTexture = prePassRenderer.defaultRT.textures?.length ? prePassRenderer.defaultRT.textures[textureIndex].getInternalTexture() : null;\r\n\r\n        if (!prePassTexture) {\r\n            return false;\r\n        }\r\n\r\n        if (this._blendBackTexture !== prePassTexture) {\r\n            this._blendBackTexture = prePassTexture;\r\n            this._blendBackMrt.setInternalTexture(this._blendBackTexture, 0);\r\n\r\n            if (this._thinTextures[6]) {\r\n                this._thinTextures[6].dispose();\r\n            }\r\n            this._thinTextures[6] = new ThinTexture(this._blendBackTexture);\r\n\r\n            prePassRenderer.defaultRT.renderTarget!.shareDepth(this._depthMrts[0].renderTarget!);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Links to the prepass renderer\r\n     * @param prePassRenderer The scene PrePassRenderer\r\n     */\r\n    public override setPrePassRenderer(prePassRenderer: PrePassRenderer) {\r\n        prePassRenderer.addEffectConfiguration(this._prePassEffectConfiguration);\r\n    }\r\n\r\n    protected override _finalCompose(writeId: number) {\r\n        const output = this._scene.prePassRenderer?.setCustomOutput(this._outputRT);\r\n        if (output) {\r\n            this._engine.bindFramebuffer(this._outputRT.renderTarget!);\r\n        } else {\r\n            this._engine.restoreDefaultFramebuffer();\r\n        }\r\n\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        this._engine.applyStates();\r\n\r\n        this._engine.enableEffect(this._finalEffectWrapper.drawWrapper);\r\n        this._finalEffectWrapper.effect.setTexture(\"uFrontColor\", this._thinTextures[writeId * 3 + 1]);\r\n        this._finalEffectWrapper.effect.setTexture(\"uBackColor\", this._thinTextures[6]);\r\n        this._effectRenderer.render(this._finalEffectWrapper);\r\n    }\r\n\r\n    /**\r\n     * Checks if the depth peeling renderer is ready to render transparent meshes\r\n     * @returns true if the depth peeling renderer is ready to render the transparent meshes\r\n     */\r\n    public override isReady() {\r\n        return super.isReady() && this._updateTextures();\r\n    }\r\n\r\n    protected override _beforeRender() {\r\n        (this._scene.prePassRenderer! as any)._enabled = false;\r\n    }\r\n\r\n    protected override _afterRender() {\r\n        (this._scene.prePassRenderer! as any)._enabled = true;\r\n    }\r\n\r\n    protected override _noTransparentMeshes() {\r\n        this._engine.bindFramebuffer(this._colorMrts[1].renderTarget!);\r\n        this._engine.bindAttachments(this._layoutCache[1]);\r\n        this._engine.clear(this._colorCache[2], true, false, false);\r\n        this._engine.unBindFramebuffer(this._colorMrts[1].renderTarget!);\r\n\r\n        this._finalCompose(1);\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Immutable, type Nullable } from \"../types\";\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { AbstractMesh } from \"../Meshes/abstractMesh.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\n\r\nimport { Vector3, TmpVectors } from \"../Maths/math.vector.pure\";\r\nimport { type Matrix } from \"../Maths/math.vector\";\r\nimport { type IDisposable, type Scene } from \"../scene.pure\";\r\nimport { type Observer } from \"../Misc/observable.pure\";\r\nimport { Material } from \"../Materials/material.pure\";\r\nimport { MaterialHelperGeometryRendering } from \"../Materials/materialHelper.geometryrendering\";\r\nimport { ShaderMaterial } from \"../Materials/shaderMaterial.pure\";\r\nimport { Camera } from \"../Cameras/camera.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { type Node } from \"../node\";\r\nimport { type DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { LinesMesh, InstancedLinesMesh } from \"../Meshes/linesMesh.pure\";\r\n\r\n/**\r\n * FaceAdjacencies Helper class to generate edges\r\n */\r\nclass FaceAdjacencies {\r\n    public edges: number[] = [];\r\n    public p0: Vector3;\r\n    public p1: Vector3;\r\n    public p2: Vector3;\r\n    public edgesConnectedCount = 0;\r\n}\r\n\r\n/**\r\n * Defines the minimum contract an Edges renderer should follow.\r\n */\r\nexport interface IEdgesRenderer extends IDisposable {\r\n    /**\r\n     * Gets or sets a boolean indicating if the edgesRenderer is active\r\n     */\r\n    isEnabled: boolean;\r\n\r\n    /**\r\n     * Renders the edges of the attached mesh,\r\n     */\r\n    render(): void;\r\n\r\n    /**\r\n     * Checks whether or not the edges renderer is ready to render.\r\n     * @param useInstances Defines whether the instanced shader variant should be checked. If omitted, the current rendering state is used.\r\n     * @returns true if ready, otherwise false.\r\n     */\r\n    isReady(useInstances?: boolean): boolean;\r\n\r\n    /**\r\n     * List of instances to render in case the source mesh has instances\r\n     */\r\n    customInstances: SmartArray<Matrix>;\r\n}\r\n\r\n/**\r\n * Defines the additional options of the edges renderer\r\n */\r\nexport interface IEdgesRendererOptions {\r\n    /**\r\n     * Gets or sets a boolean indicating that the alternate edge finder algorithm must be used\r\n     * If not defined, the default value is true\r\n     */\r\n    useAlternateEdgeFinder?: boolean;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the vertex merger fast processing must be used.\r\n     * If not defined, the default value is true.\r\n     * You should normally leave it undefined (or set it to true), except if you see some artifacts in the edges rendering (can happen with complex geometries)\r\n     * This option is used only if useAlternateEdgeFinder = true\r\n     */\r\n    useFastVertexMerger?: boolean;\r\n\r\n    /**\r\n     * During edges processing, the vertices are merged if they are close enough: epsilonVertexMerge is the limit within which vertices are considered to be equal.\r\n     * The default value is 1e-6\r\n     * This option is used only if useAlternateEdgeFinder = true\r\n     */\r\n    epsilonVertexMerge?: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that tessellation should be applied before finding the edges. You may need to activate this option if your geometry is a bit\r\n     * unusual, like having a vertex of a triangle in-between two vertices of an edge of another triangle. It happens often when using CSG to construct meshes.\r\n     * This option is used only if useAlternateEdgeFinder = true\r\n     */\r\n    applyTessellation?: boolean;\r\n\r\n    /**\r\n     * The limit under which 3 vertices are considered to be aligned. 3 vertices PQR are considered aligned if distance(PQ) + distance(QR) - distance(PR) < epsilonVertexAligned\r\n     * The default value is 1e-6\r\n     * This option is used only if useAlternateEdgeFinder = true\r\n     */\r\n    epsilonVertexAligned?: number;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that degenerated triangles should not be processed.\r\n     * Degenerated triangles are triangles that have 2 or 3 vertices with the same coordinates\r\n     */\r\n    removeDegeneratedTriangles?: boolean;\r\n}\r\n\r\n/**\r\n * This class is used to generate edges of the mesh that could then easily be rendered in a scene.\r\n */\r\nexport class EdgesRenderer implements IEdgesRenderer {\r\n    /**\r\n     * Define the size of the edges with an orthographic camera\r\n     */\r\n    public edgesWidthScalerForOrthographic = 1000.0;\r\n\r\n    /**\r\n     * Define the size of the edges with a perspective camera\r\n     */\r\n    public edgesWidthScalerForPerspective = 50.0;\r\n\r\n    protected _source: AbstractMesh;\r\n    protected _linesPositions = new Array<number>();\r\n    protected _linesNormals = new Array<number>();\r\n    protected _linesIndices = new Array<number>();\r\n    protected _epsilon: number;\r\n    protected _indicesCount: number;\r\n    protected _drawWrapper?: DrawWrapper;\r\n\r\n    protected _lineShader: ShaderMaterial;\r\n    protected _ib: DataBuffer;\r\n    protected _buffers: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    protected _buffersForInstances: { [key: string]: Nullable<VertexBuffer> } = {};\r\n    protected _checkVerticesInsteadOfIndices = false;\r\n    protected _options: Nullable<IEdgesRendererOptions>;\r\n\r\n    private _meshRebuildObserver: Nullable<Observer<AbstractMesh>>;\r\n    private _meshDisposeObserver: Nullable<Observer<Node>>;\r\n\r\n    /** Gets or sets a boolean indicating if the edgesRenderer is active */\r\n    public isEnabled = true;\r\n\r\n    /** Gets the vertices generated by the edge renderer */\r\n    public get linesPositions(): Immutable<Array<number>> {\r\n        return this._linesPositions;\r\n    }\r\n\r\n    /** Gets the normals generated by the edge renderer */\r\n    public get linesNormals(): Immutable<Array<number>> {\r\n        return this._linesNormals;\r\n    }\r\n\r\n    /** Gets the indices generated by the edge renderer */\r\n    public get linesIndices(): Immutable<Array<number>> {\r\n        return this._linesIndices;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets the shader used to draw the lines\r\n     */\r\n    public get lineShader(): ShaderMaterial {\r\n        return this._lineShader;\r\n    }\r\n\r\n    public set lineShader(shader: ShaderMaterial) {\r\n        this._lineShader = shader;\r\n    }\r\n\r\n    /**\r\n     * List of instances to render in case the source mesh has instances\r\n     */\r\n    public customInstances = new SmartArray<Matrix>(32);\r\n\r\n    private static _GetShader(scene: Scene, shaderLanguage: ShaderLanguage): ShaderMaterial {\r\n        if (!scene._edgeRenderLineShader) {\r\n            const shader = new ShaderMaterial(\r\n                \"lineShader\",\r\n                scene,\r\n                \"line\",\r\n                {\r\n                    attributes: [\"position\", \"normal\"],\r\n                    uniforms: [\"world\", \"viewProjection\", \"color\", \"width\", \"aspectRatio\"],\r\n                    uniformBuffers: [\"Scene\", \"Mesh\"],\r\n                    shaderLanguage: shaderLanguage,\r\n                    extraInitializationsAsync: async () => {\r\n                        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n                            await Promise.all([import(\"../ShadersWGSL/line.vertex\"), import(\"../ShadersWGSL/line.fragment\")]);\r\n                        } else {\r\n                            await Promise.all([import(\"../Shaders/line.vertex\"), import(\"../Shaders/line.fragment\")]);\r\n                        }\r\n                    },\r\n                },\r\n                false\r\n            );\r\n\r\n            shader.disableDepthWrite = true;\r\n            shader.backFaceCulling = false;\r\n            shader.checkReadyOnEveryCall = scene.getEngine().isWebGPU;\r\n            shader.doNotSerialize = true;\r\n\r\n            scene._edgeRenderLineShader = shader;\r\n\r\n            scene.onDisposeObservable.add(() => {\r\n                scene._edgeRenderLineShader!.dispose();\r\n                scene._edgeRenderLineShader = null;\r\n            });\r\n        }\r\n\r\n        return scene._edgeRenderLineShader;\r\n    }\r\n\r\n    /** Shader language used*/\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Creates an instance of the EdgesRenderer. It is primarily use to display edges of a mesh.\r\n     * Beware when you use this class with complex objects as the adjacencies computation can be really long\r\n     * @param  source Mesh used to create edges\r\n     * @param  epsilon sum of angles in adjacency to check for edge\r\n     * @param  checkVerticesInsteadOfIndices bases the edges detection on vertices vs indices. Note that this parameter is not used if options.useAlternateEdgeFinder = true\r\n     * @param  generateEdgesLines - should generate Lines or only prepare resources.\r\n     * @param  options The options to apply when generating the edges\r\n     */\r\n    constructor(source: AbstractMesh, epsilon = 0.95, checkVerticesInsteadOfIndices = false, generateEdgesLines = true, options?: IEdgesRendererOptions) {\r\n        this._source = source;\r\n        this._checkVerticesInsteadOfIndices = checkVerticesInsteadOfIndices;\r\n        this._options = options ?? null;\r\n\r\n        this._epsilon = epsilon;\r\n        const engine = this._source.getScene().getEngine();\r\n        if (engine.isWebGPU) {\r\n            this._drawWrapper = new DrawWrapper(engine);\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n\r\n        this._prepareResources();\r\n        if (generateEdgesLines) {\r\n            if (options?.useAlternateEdgeFinder ?? true) {\r\n                this._generateEdgesLinesAlternate();\r\n            } else {\r\n                this._generateEdgesLines();\r\n            }\r\n        }\r\n\r\n        this._meshRebuildObserver = this._source.onRebuildObservable.add(() => {\r\n            this._rebuild();\r\n        });\r\n\r\n        this._meshDisposeObserver = this._source.onDisposeObservable.add(() => {\r\n            this.dispose();\r\n        });\r\n    }\r\n\r\n    protected _prepareResources(): void {\r\n        if (this._lineShader) {\r\n            return;\r\n        }\r\n\r\n        this._lineShader = EdgesRenderer._GetShader(this._source.getScene(), this._shaderLanguage);\r\n    }\r\n\r\n    /** @internal */\r\n    public _rebuild(): void {\r\n        let buffer = this._buffers[VertexBuffer.PositionKind];\r\n        if (buffer) {\r\n            buffer._rebuild();\r\n        }\r\n\r\n        buffer = this._buffers[VertexBuffer.NormalKind];\r\n        if (buffer) {\r\n            buffer._rebuild();\r\n        }\r\n\r\n        const scene = this._source.getScene();\r\n        const engine = scene.getEngine();\r\n        this._ib = engine.createIndexBuffer(this._linesIndices);\r\n    }\r\n\r\n    /**\r\n     * Releases the required resources for the edges renderer\r\n     */\r\n    public dispose(): void {\r\n        this._source.onRebuildObservable.remove(this._meshRebuildObserver);\r\n        this._source.onDisposeObservable.remove(this._meshDisposeObserver);\r\n\r\n        let buffer = this._buffers[VertexBuffer.PositionKind];\r\n        if (buffer) {\r\n            buffer.dispose();\r\n            this._buffers[VertexBuffer.PositionKind] = null;\r\n        }\r\n        buffer = this._buffers[VertexBuffer.NormalKind];\r\n        if (buffer) {\r\n            buffer.dispose();\r\n            this._buffers[VertexBuffer.NormalKind] = null;\r\n        }\r\n\r\n        if (this._ib) {\r\n            this._source.getScene().getEngine()._releaseBuffer(this._ib);\r\n        }\r\n\r\n        this._drawWrapper?.dispose();\r\n    }\r\n\r\n    protected _processEdgeForAdjacencies(pa: number, pb: number, p0: number, p1: number, p2: number): number {\r\n        if ((pa === p0 && pb === p1) || (pa === p1 && pb === p0)) {\r\n            return 0;\r\n        }\r\n\r\n        if ((pa === p1 && pb === p2) || (pa === p2 && pb === p1)) {\r\n            return 1;\r\n        }\r\n\r\n        if ((pa === p2 && pb === p0) || (pa === p0 && pb === p2)) {\r\n            return 2;\r\n        }\r\n\r\n        return -1;\r\n    }\r\n\r\n    protected _processEdgeForAdjacenciesWithVertices(pa: Vector3, pb: Vector3, p0: Vector3, p1: Vector3, p2: Vector3): number {\r\n        const eps = 1e-10;\r\n        if ((pa.equalsWithEpsilon(p0, eps) && pb.equalsWithEpsilon(p1, eps)) || (pa.equalsWithEpsilon(p1, eps) && pb.equalsWithEpsilon(p0, eps))) {\r\n            return 0;\r\n        }\r\n\r\n        if ((pa.equalsWithEpsilon(p1, eps) && pb.equalsWithEpsilon(p2, eps)) || (pa.equalsWithEpsilon(p2, eps) && pb.equalsWithEpsilon(p1, eps))) {\r\n            return 1;\r\n        }\r\n\r\n        if ((pa.equalsWithEpsilon(p2, eps) && pb.equalsWithEpsilon(p0, eps)) || (pa.equalsWithEpsilon(p0, eps) && pb.equalsWithEpsilon(p2, eps))) {\r\n            return 2;\r\n        }\r\n\r\n        return -1;\r\n    }\r\n\r\n    /**\r\n     * Checks if the pair of p0 and p1 is en edge\r\n     * @param faceIndex\r\n     * @param edge\r\n     * @param faceNormals\r\n     * @param  p0\r\n     * @param  p1\r\n     * @private\r\n     */\r\n    protected _checkEdge(faceIndex: number, edge: number, faceNormals: Array<Vector3>, p0: Vector3, p1: Vector3): void {\r\n        let needToCreateLine;\r\n\r\n        if (edge === undefined) {\r\n            needToCreateLine = true;\r\n        } else {\r\n            const dotProduct = Vector3.Dot(faceNormals[faceIndex], faceNormals[edge]);\r\n\r\n            needToCreateLine = dotProduct < this._epsilon;\r\n        }\r\n\r\n        if (needToCreateLine) {\r\n            this.createLine(p0, p1, this._linesPositions.length / 3);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * push line into the position, normal and index buffer\r\n     * @param p0\r\n     * @param p1\r\n     * @param offset\r\n     * @protected\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    protected createLine(p0: Vector3, p1: Vector3, offset: number) {\r\n        // Positions\r\n        this._linesPositions.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z, p1.x, p1.y, p1.z, p1.x, p1.y, p1.z);\r\n\r\n        // Normals\r\n        this._linesNormals.push(p1.x, p1.y, p1.z, -1, p1.x, p1.y, p1.z, 1, p0.x, p0.y, p0.z, -1, p0.x, p0.y, p0.z, 1);\r\n\r\n        // Indices\r\n        this._linesIndices.push(offset, offset + 1, offset + 2, offset, offset + 2, offset + 3);\r\n    }\r\n\r\n    /**\r\n     * See https://playground.babylonjs.com/#R3JR6V#1 for a visual display of the algorithm\r\n     * @param edgePoints\r\n     * @param indexTriangle\r\n     * @param indices\r\n     * @param remapVertexIndices\r\n     */\r\n    private _tessellateTriangle(edgePoints: Array<Array<[number, number]>>, indexTriangle: number, indices: Array<number>, remapVertexIndices: Array<number>): void {\r\n        const makePointList = (edgePoints: Array<[number, number]>, pointIndices: Array<number>, firstIndex: number) => {\r\n            if (firstIndex >= 0) {\r\n                pointIndices.push(firstIndex);\r\n            }\r\n\r\n            for (let i = 0; i < edgePoints.length; ++i) {\r\n                pointIndices.push(edgePoints[i][0]);\r\n            }\r\n        };\r\n\r\n        let startEdge = 0;\r\n\r\n        if (edgePoints[1].length >= edgePoints[0].length && edgePoints[1].length >= edgePoints[2].length) {\r\n            startEdge = 1;\r\n        } else if (edgePoints[2].length >= edgePoints[0].length && edgePoints[2].length >= edgePoints[1].length) {\r\n            startEdge = 2;\r\n        }\r\n\r\n        for (let e = 0; e < 3; ++e) {\r\n            if (e === startEdge) {\r\n                edgePoints[e].sort((a, b) => (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0));\r\n            } else {\r\n                edgePoints[e].sort((a, b) => (a[1] > b[1] ? -1 : a[1] < b[1] ? 1 : 0));\r\n            }\r\n        }\r\n\r\n        const mainPointIndices: Array<number> = [],\r\n            otherPointIndices: Array<number> = [];\r\n\r\n        makePointList(edgePoints[startEdge], mainPointIndices, -1);\r\n\r\n        const numMainPoints = mainPointIndices.length;\r\n\r\n        for (let i = startEdge + 2; i >= startEdge + 1; --i) {\r\n            makePointList(edgePoints[i % 3], otherPointIndices, i !== startEdge + 2 ? remapVertexIndices[indices[indexTriangle + ((i + 1) % 3)]] : -1);\r\n        }\r\n\r\n        const numOtherPoints = otherPointIndices.length;\r\n\r\n        const idxMain = 0;\r\n        const idxOther = 0;\r\n\r\n        indices.push(remapVertexIndices[indices[indexTriangle + startEdge]], mainPointIndices[0], otherPointIndices[0]);\r\n        indices.push(remapVertexIndices[indices[indexTriangle + ((startEdge + 1) % 3)]], otherPointIndices[numOtherPoints - 1], mainPointIndices[numMainPoints - 1]);\r\n\r\n        const bucketIsMain = numMainPoints <= numOtherPoints;\r\n\r\n        const bucketStep = bucketIsMain ? numMainPoints : numOtherPoints;\r\n        const bucketLimit = bucketIsMain ? numOtherPoints : numMainPoints;\r\n        const bucketIdxLimit = bucketIsMain ? numMainPoints - 1 : numOtherPoints - 1;\r\n        const winding = bucketIsMain ? 0 : 1;\r\n\r\n        let numTris = numMainPoints + numOtherPoints - 2;\r\n\r\n        let bucketIdx = bucketIsMain ? idxMain : idxOther;\r\n        let nbucketIdx = bucketIsMain ? idxOther : idxMain;\r\n        const bucketPoints = bucketIsMain ? mainPointIndices : otherPointIndices;\r\n        const nbucketPoints = bucketIsMain ? otherPointIndices : mainPointIndices;\r\n\r\n        let bucket = 0;\r\n\r\n        while (numTris-- > 0) {\r\n            if (winding) {\r\n                indices.push(bucketPoints[bucketIdx], nbucketPoints[nbucketIdx]);\r\n            } else {\r\n                indices.push(nbucketPoints[nbucketIdx], bucketPoints[bucketIdx]);\r\n            }\r\n\r\n            bucket += bucketStep;\r\n\r\n            let lastIdx;\r\n\r\n            if (bucket >= bucketLimit && bucketIdx < bucketIdxLimit) {\r\n                lastIdx = bucketPoints[++bucketIdx];\r\n                bucket -= bucketLimit;\r\n            } else {\r\n                lastIdx = nbucketPoints[++nbucketIdx];\r\n            }\r\n\r\n            indices.push(lastIdx);\r\n        }\r\n\r\n        indices[indexTriangle + 0] = indices[indices.length - 3];\r\n        indices[indexTriangle + 1] = indices[indices.length - 2];\r\n        indices[indexTriangle + 2] = indices[indices.length - 1];\r\n\r\n        indices.length = indices.length - 3;\r\n    }\r\n\r\n    private _generateEdgesLinesAlternate(): void {\r\n        const positions = this._source.getVerticesData(VertexBuffer.PositionKind);\r\n        let indices = this._source.getIndices();\r\n\r\n        if (!indices || !positions) {\r\n            return;\r\n        }\r\n\r\n        if (!Array.isArray(indices)) {\r\n            indices = Array.from(indices);\r\n        }\r\n\r\n        /**\r\n         * Find all vertices that are at the same location (with an epsilon) and remapp them on the same vertex\r\n         */\r\n        const useFastVertexMerger = this._options?.useFastVertexMerger ?? true;\r\n        const epsVertexMerge = useFastVertexMerger ? Math.round(-Math.log(this._options?.epsilonVertexMerge ?? 1e-6) / Math.log(10)) : (this._options?.epsilonVertexMerge ?? 1e-6);\r\n        const remapVertexIndices: Array<number> = [];\r\n        const uniquePositions: Array<number> = []; // list of unique index of vertices - needed for tessellation\r\n\r\n        if (useFastVertexMerger) {\r\n            const mapVertices: { [key: string]: number } = {};\r\n            for (let v1 = 0; v1 < positions.length; v1 += 3) {\r\n                const x1: number = positions[v1 + 0],\r\n                    y1: number = positions[v1 + 1],\r\n                    z1: number = positions[v1 + 2];\r\n\r\n                const key = x1.toFixed(epsVertexMerge) + \"|\" + y1.toFixed(epsVertexMerge) + \"|\" + z1.toFixed(epsVertexMerge);\r\n\r\n                if (mapVertices[key] !== undefined) {\r\n                    remapVertexIndices.push(mapVertices[key]);\r\n                } else {\r\n                    const idx = v1 / 3;\r\n                    mapVertices[key] = idx;\r\n                    remapVertexIndices.push(idx);\r\n                    uniquePositions.push(idx);\r\n                }\r\n            }\r\n        } else {\r\n            for (let v1 = 0; v1 < positions.length; v1 += 3) {\r\n                const x1 = positions[v1 + 0],\r\n                    y1 = positions[v1 + 1],\r\n                    z1 = positions[v1 + 2];\r\n                let found = false;\r\n                for (let v2 = 0; v2 < v1 && !found; v2 += 3) {\r\n                    const x2 = positions[v2 + 0],\r\n                        y2 = positions[v2 + 1],\r\n                        z2 = positions[v2 + 2];\r\n\r\n                    if (Math.abs(x1 - x2) < epsVertexMerge && Math.abs(y1 - y2) < epsVertexMerge && Math.abs(z1 - z2) < epsVertexMerge) {\r\n                        remapVertexIndices.push(v2 / 3);\r\n                        found = true;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (!found) {\r\n                    remapVertexIndices.push(v1 / 3);\r\n                    uniquePositions.push(v1 / 3);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this._options?.applyTessellation) {\r\n            /**\r\n             * Tessellate triangles if necessary:\r\n             *\r\n             *               A\r\n             *               +\r\n             *               |\\\r\n             *               | \\\r\n             *               |  \\\r\n             *             E +   \\\r\n             *              /|    \\\r\n             *             / |     \\\r\n             *            /  |      \\\r\n             *           +---+-------+ B\r\n             *           D   C\r\n             *\r\n             * For the edges to be rendered correctly, the ABC triangle has to be split into ABE and BCE, else AC is considered to be an edge, whereas only AE should be.\r\n             *\r\n             * The tessellation process looks for the vertices like E that are in-between two other vertices making of an edge and create new triangles as necessary\r\n             */\r\n\r\n            // First step: collect the triangles to tessellate\r\n            const epsVertexAligned = this._options?.epsilonVertexAligned ?? 1e-6;\r\n            const mustTesselate: Array<{ index: number; edgesPoints: Array<Array<[number, number]>> }> = []; // liste of triangles that must be tessellated\r\n\r\n            for (let index = 0; index < indices.length; index += 3) {\r\n                // loop over all triangles\r\n                let triangleToTessellate: { index: number; edgesPoints: Array<Array<[number, number]>> } | undefined;\r\n\r\n                for (let i = 0; i < 3; ++i) {\r\n                    // loop over the 3 edges of the triangle\r\n                    const p0Index = remapVertexIndices[indices[index + i]];\r\n                    const p1Index = remapVertexIndices[indices[index + ((i + 1) % 3)]];\r\n                    const p2Index = remapVertexIndices[indices[index + ((i + 2) % 3)]];\r\n\r\n                    if (p0Index === p1Index) {\r\n                        continue;\r\n                    } // degenerated triangle - don't process\r\n\r\n                    const p0x = positions[p0Index * 3 + 0],\r\n                        p0y = positions[p0Index * 3 + 1],\r\n                        p0z = positions[p0Index * 3 + 2];\r\n                    const p1x = positions[p1Index * 3 + 0],\r\n                        p1y = positions[p1Index * 3 + 1],\r\n                        p1z = positions[p1Index * 3 + 2];\r\n\r\n                    const p0p1 = Math.sqrt((p1x - p0x) * (p1x - p0x) + (p1y - p0y) * (p1y - p0y) + (p1z - p0z) * (p1z - p0z));\r\n\r\n                    for (let v = 0; v < uniquePositions.length - 1; v++) {\r\n                        // loop over all (unique) vertices and look for the ones that would be in-between p0 and p1\r\n                        const vIndex = uniquePositions[v];\r\n\r\n                        if (vIndex === p0Index || vIndex === p1Index || vIndex === p2Index) {\r\n                            continue;\r\n                        } // don't handle the vertex if it is a vertex of the current triangle\r\n\r\n                        const x = positions[vIndex * 3 + 0],\r\n                            y = positions[vIndex * 3 + 1],\r\n                            z = positions[vIndex * 3 + 2];\r\n\r\n                        const p0p = Math.sqrt((x - p0x) * (x - p0x) + (y - p0y) * (y - p0y) + (z - p0z) * (z - p0z));\r\n                        const pp1 = Math.sqrt((x - p1x) * (x - p1x) + (y - p1y) * (y - p1y) + (z - p1z) * (z - p1z));\r\n\r\n                        if (Math.abs(p0p + pp1 - p0p1) < epsVertexAligned) {\r\n                            // vertices are aligned and p in-between p0 and p1 if distance(p0, p) + distance (p, p1) ~ distance(p0, p1)\r\n                            if (!triangleToTessellate) {\r\n                                triangleToTessellate = {\r\n                                    index: index,\r\n                                    edgesPoints: [[], [], []],\r\n                                };\r\n                                mustTesselate.push(triangleToTessellate);\r\n                            }\r\n                            triangleToTessellate.edgesPoints[i].push([vIndex, p0p]);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Second step: tesselate the triangles\r\n            for (let t = 0; t < mustTesselate.length; ++t) {\r\n                const triangle = mustTesselate[t];\r\n\r\n                this._tessellateTriangle(triangle.edgesPoints, triangle.index, indices, remapVertexIndices);\r\n            }\r\n\r\n            mustTesselate.length = 0;\r\n        }\r\n\r\n        /**\r\n         * Collect the edges to render\r\n         */\r\n        const edges: { [key: string]: { normal: Vector3; done: boolean; index: number; i: number } } = {};\r\n\r\n        for (let index = 0; index < indices.length; index += 3) {\r\n            let faceNormal;\r\n            for (let i = 0; i < 3; ++i) {\r\n                let p0Index = remapVertexIndices[indices[index + i]];\r\n                let p1Index = remapVertexIndices[indices[index + ((i + 1) % 3)]];\r\n                const p2Index = remapVertexIndices[indices[index + ((i + 2) % 3)]];\r\n\r\n                if (p0Index === p1Index || ((p0Index === p2Index || p1Index === p2Index) && this._options?.removeDegeneratedTriangles)) {\r\n                    continue;\r\n                }\r\n\r\n                TmpVectors.Vector3[0].copyFromFloats(positions[p0Index * 3 + 0], positions[p0Index * 3 + 1], positions[p0Index * 3 + 2]);\r\n                TmpVectors.Vector3[1].copyFromFloats(positions[p1Index * 3 + 0], positions[p1Index * 3 + 1], positions[p1Index * 3 + 2]);\r\n                TmpVectors.Vector3[2].copyFromFloats(positions[p2Index * 3 + 0], positions[p2Index * 3 + 1], positions[p2Index * 3 + 2]);\r\n\r\n                if (!faceNormal) {\r\n                    TmpVectors.Vector3[1].subtractToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[3]);\r\n                    TmpVectors.Vector3[2].subtractToRef(TmpVectors.Vector3[1], TmpVectors.Vector3[4]);\r\n                    faceNormal = Vector3.Cross(TmpVectors.Vector3[3], TmpVectors.Vector3[4]);\r\n                    faceNormal.normalize();\r\n                }\r\n\r\n                if (p0Index > p1Index) {\r\n                    const tmp = p0Index;\r\n                    p0Index = p1Index;\r\n                    p1Index = tmp;\r\n                }\r\n\r\n                const key = p0Index + \"_\" + p1Index;\r\n                const ei = edges[key];\r\n\r\n                if (ei) {\r\n                    if (!ei.done) {\r\n                        const dotProduct = Vector3.Dot(faceNormal, ei.normal);\r\n\r\n                        if (dotProduct < this._epsilon) {\r\n                            this.createLine(TmpVectors.Vector3[0], TmpVectors.Vector3[1], this._linesPositions.length / 3);\r\n                        }\r\n\r\n                        ei.done = true;\r\n                    }\r\n                } else {\r\n                    edges[key] = { normal: faceNormal, done: false, index: index, i: i };\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const key in edges) {\r\n            const ei = edges[key];\r\n            if (!ei.done) {\r\n                // Orphaned edge - we must display it\r\n                const p0Index = remapVertexIndices[indices[ei.index + ei.i]];\r\n                const p1Index = remapVertexIndices[indices[ei.index + ((ei.i + 1) % 3)]];\r\n\r\n                TmpVectors.Vector3[0].copyFromFloats(positions[p0Index * 3 + 0], positions[p0Index * 3 + 1], positions[p0Index * 3 + 2]);\r\n                TmpVectors.Vector3[1].copyFromFloats(positions[p1Index * 3 + 0], positions[p1Index * 3 + 1], positions[p1Index * 3 + 2]);\r\n\r\n                this.createLine(TmpVectors.Vector3[0], TmpVectors.Vector3[1], this._linesPositions.length / 3);\r\n            }\r\n        }\r\n\r\n        /**\r\n         * Merge into a single mesh\r\n         */\r\n        const engine = this._source.getScene().getEngine();\r\n\r\n        this._buffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, this._linesPositions, VertexBuffer.PositionKind, false);\r\n        this._buffers[VertexBuffer.NormalKind] = new VertexBuffer(engine, this._linesNormals, VertexBuffer.NormalKind, false, false, 4);\r\n\r\n        this._buffersForInstances[VertexBuffer.PositionKind] = this._buffers[VertexBuffer.PositionKind];\r\n        this._buffersForInstances[VertexBuffer.NormalKind] = this._buffers[VertexBuffer.NormalKind];\r\n\r\n        this._ib = engine.createIndexBuffer(this._linesIndices);\r\n\r\n        this._indicesCount = this._linesIndices.length;\r\n    }\r\n\r\n    /**\r\n     * Generates lines edges from adjacencjes\r\n     * @private\r\n     */\r\n    _generateEdgesLines(): void {\r\n        const positions = this._source.getVerticesData(VertexBuffer.PositionKind);\r\n        const indices = this._source.getIndices();\r\n\r\n        if (!indices || !positions) {\r\n            return;\r\n        }\r\n\r\n        // First let's find adjacencies\r\n        const adjacencies: FaceAdjacencies[] = [];\r\n        const faceNormals: Vector3[] = [];\r\n        let index: number;\r\n        let faceAdjacencies: FaceAdjacencies;\r\n\r\n        // Prepare faces\r\n        for (index = 0; index < indices.length; index += 3) {\r\n            faceAdjacencies = new FaceAdjacencies();\r\n            const p0Index = indices[index];\r\n            const p1Index = indices[index + 1];\r\n            const p2Index = indices[index + 2];\r\n\r\n            faceAdjacencies.p0 = new Vector3(positions[p0Index * 3], positions[p0Index * 3 + 1], positions[p0Index * 3 + 2]);\r\n            faceAdjacencies.p1 = new Vector3(positions[p1Index * 3], positions[p1Index * 3 + 1], positions[p1Index * 3 + 2]);\r\n            faceAdjacencies.p2 = new Vector3(positions[p2Index * 3], positions[p2Index * 3 + 1], positions[p2Index * 3 + 2]);\r\n            const faceNormal = Vector3.Cross(faceAdjacencies.p1.subtract(faceAdjacencies.p0), faceAdjacencies.p2.subtract(faceAdjacencies.p1));\r\n\r\n            faceNormal.normalize();\r\n\r\n            faceNormals.push(faceNormal);\r\n            adjacencies.push(faceAdjacencies);\r\n        }\r\n\r\n        // Scan\r\n        for (index = 0; index < adjacencies.length; index++) {\r\n            faceAdjacencies = adjacencies[index];\r\n\r\n            for (let otherIndex = index + 1; otherIndex < adjacencies.length; otherIndex++) {\r\n                const otherFaceAdjacencies = adjacencies[otherIndex];\r\n\r\n                if (faceAdjacencies.edgesConnectedCount === 3) {\r\n                    // Full\r\n                    break;\r\n                }\r\n\r\n                if (otherFaceAdjacencies.edgesConnectedCount === 3) {\r\n                    // Full\r\n                    continue;\r\n                }\r\n\r\n                const otherP0 = indices[otherIndex * 3];\r\n                const otherP1 = indices[otherIndex * 3 + 1];\r\n                const otherP2 = indices[otherIndex * 3 + 2];\r\n\r\n                for (let edgeIndex = 0; edgeIndex < 3; edgeIndex++) {\r\n                    let otherEdgeIndex: number = 0;\r\n\r\n                    if (faceAdjacencies.edges[edgeIndex] !== undefined) {\r\n                        continue;\r\n                    }\r\n\r\n                    switch (edgeIndex) {\r\n                        case 0:\r\n                            if (this._checkVerticesInsteadOfIndices) {\r\n                                otherEdgeIndex = this._processEdgeForAdjacenciesWithVertices(\r\n                                    faceAdjacencies.p0,\r\n                                    faceAdjacencies.p1,\r\n                                    otherFaceAdjacencies.p0,\r\n                                    otherFaceAdjacencies.p1,\r\n                                    otherFaceAdjacencies.p2\r\n                                );\r\n                            } else {\r\n                                otherEdgeIndex = this._processEdgeForAdjacencies(indices[index * 3], indices[index * 3 + 1], otherP0, otherP1, otherP2);\r\n                            }\r\n                            break;\r\n                        case 1:\r\n                            if (this._checkVerticesInsteadOfIndices) {\r\n                                otherEdgeIndex = this._processEdgeForAdjacenciesWithVertices(\r\n                                    faceAdjacencies.p1,\r\n                                    faceAdjacencies.p2,\r\n                                    otherFaceAdjacencies.p0,\r\n                                    otherFaceAdjacencies.p1,\r\n                                    otherFaceAdjacencies.p2\r\n                                );\r\n                            } else {\r\n                                otherEdgeIndex = this._processEdgeForAdjacencies(indices[index * 3 + 1], indices[index * 3 + 2], otherP0, otherP1, otherP2);\r\n                            }\r\n                            break;\r\n                        case 2:\r\n                            if (this._checkVerticesInsteadOfIndices) {\r\n                                otherEdgeIndex = this._processEdgeForAdjacenciesWithVertices(\r\n                                    faceAdjacencies.p2,\r\n                                    faceAdjacencies.p0,\r\n                                    otherFaceAdjacencies.p0,\r\n                                    otherFaceAdjacencies.p1,\r\n                                    otherFaceAdjacencies.p2\r\n                                );\r\n                            } else {\r\n                                otherEdgeIndex = this._processEdgeForAdjacencies(indices[index * 3 + 2], indices[index * 3], otherP0, otherP1, otherP2);\r\n                            }\r\n                            break;\r\n                    }\r\n\r\n                    if (otherEdgeIndex === -1) {\r\n                        continue;\r\n                    }\r\n\r\n                    faceAdjacencies.edges[edgeIndex] = otherIndex;\r\n                    otherFaceAdjacencies.edges[otherEdgeIndex] = index;\r\n\r\n                    faceAdjacencies.edgesConnectedCount++;\r\n                    otherFaceAdjacencies.edgesConnectedCount++;\r\n\r\n                    if (faceAdjacencies.edgesConnectedCount === 3) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Create lines\r\n        for (index = 0; index < adjacencies.length; index++) {\r\n            // We need a line when a face has no adjacency on a specific edge or if all the adjacencies has an angle greater than epsilon\r\n            const current = adjacencies[index];\r\n\r\n            this._checkEdge(index, current.edges[0], faceNormals, current.p0, current.p1);\r\n            this._checkEdge(index, current.edges[1], faceNormals, current.p1, current.p2);\r\n            this._checkEdge(index, current.edges[2], faceNormals, current.p2, current.p0);\r\n        }\r\n\r\n        // Merge into a single mesh\r\n        const engine = this._source.getScene().getEngine();\r\n\r\n        this._buffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, this._linesPositions, VertexBuffer.PositionKind, false);\r\n        this._buffers[VertexBuffer.NormalKind] = new VertexBuffer(engine, this._linesNormals, VertexBuffer.NormalKind, false, false, 4);\r\n\r\n        this._buffersForInstances[VertexBuffer.PositionKind] = this._buffers[VertexBuffer.PositionKind];\r\n        this._buffersForInstances[VertexBuffer.NormalKind] = this._buffers[VertexBuffer.NormalKind];\r\n\r\n        this._ib = engine.createIndexBuffer(this._linesIndices);\r\n\r\n        this._indicesCount = this._linesIndices.length;\r\n    }\r\n\r\n    /**\r\n     * Checks whether or not the edges renderer is ready to render.\r\n     * @param useInstances Defines whether the instanced shader variant should be checked. If omitted, the current rendering state is used.\r\n     * @returns true if ready, otherwise false.\r\n     */\r\n    public isReady(useInstances?: boolean): boolean {\r\n        useInstances ??= (this._source.hasInstances && this.customInstances.length > 0) || this._source.hasThinInstances;\r\n        return this._lineShader.isReady(this._source, useInstances);\r\n    }\r\n\r\n    /**\r\n     * Renders the edges of the attached mesh,\r\n     */\r\n    public render(): void {\r\n        const scene = this._source.getScene();\r\n        if (!MaterialHelperGeometryRendering._BindColorAttachments(scene.getEngine())) {\r\n            if (!scene._activeMeshesFrozen) {\r\n                this.customInstances.reset();\r\n            }\r\n            return;\r\n        }\r\n        const floatingOriginOffset = scene.floatingOriginOffset;\r\n\r\n        const currentDrawWrapper = this._lineShader._getDrawWrapper();\r\n        if (this._drawWrapper) {\r\n            this._lineShader._setDrawWrapper(this._drawWrapper);\r\n        }\r\n\r\n        if (!this.isReady() || !scene.activeCamera) {\r\n            this._lineShader._setDrawWrapper(currentDrawWrapper);\r\n            return;\r\n        }\r\n\r\n        const hasInstances = this._source.hasInstances && this.customInstances.length > 0;\r\n        const useBuffersWithInstances = hasInstances || this._source.hasThinInstances;\r\n\r\n        let instanceCount = 0;\r\n\r\n        if (useBuffersWithInstances) {\r\n            this._buffersForInstances[\"world0\"] = (this._source as Mesh).getVertexBuffer(\"world0\");\r\n            this._buffersForInstances[\"world1\"] = (this._source as Mesh).getVertexBuffer(\"world1\");\r\n            this._buffersForInstances[\"world2\"] = (this._source as Mesh).getVertexBuffer(\"world2\");\r\n            this._buffersForInstances[\"world3\"] = (this._source as Mesh).getVertexBuffer(\"world3\");\r\n\r\n            if (hasInstances) {\r\n                const instanceStorage = (this._source as Mesh)._getInstanceDataStorage();\r\n                const isFrozen = (this._source as Mesh)._instanceDataStorage.isFrozen;\r\n\r\n                instanceCount = this.customInstances.length;\r\n\r\n                if (!instanceStorage.instancesData) {\r\n                    if (!this._source.getScene()._activeMeshesFrozen) {\r\n                        this.customInstances.reset();\r\n                    }\r\n                    return;\r\n                }\r\n\r\n                if (!isFrozen) {\r\n                    let offset = 0;\r\n\r\n                    for (let i = 0; i < instanceCount; ++i) {\r\n                        const instanceMatrix = this.customInstances.data[i];\r\n                        instanceMatrix.copyToArray(instanceStorage.instancesData, offset);\r\n                        // Subtract from Float64 source to preserve precision at large coordinates.\r\n                        const instanceM = instanceMatrix.asArray();\r\n                        instanceStorage.instancesData[offset + 12] = instanceM[12] - floatingOriginOffset.x;\r\n                        instanceStorage.instancesData[offset + 13] = instanceM[13] - floatingOriginOffset.y;\r\n                        instanceStorage.instancesData[offset + 14] = instanceM[14] - floatingOriginOffset.z;\r\n                        offset += 16;\r\n                    }\r\n\r\n                    instanceStorage.instancesBuffer!.updateDirectly(instanceStorage.instancesData, 0, instanceCount);\r\n                }\r\n            } else {\r\n                instanceCount = (this._source as Mesh).thinInstanceCount;\r\n            }\r\n        }\r\n\r\n        const engine = scene.getEngine();\r\n        this._lineShader._preBind();\r\n\r\n        if (this._source.edgesColor.a !== 1) {\r\n            engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n        } else {\r\n            engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n        }\r\n\r\n        // VBOs\r\n        engine.bindBuffers(useBuffersWithInstances ? this._buffersForInstances : this._buffers, this._ib, this._lineShader.getEffect());\r\n\r\n        scene.resetCachedMaterial();\r\n        this._lineShader.setColor4(\"color\", this._source.edgesColor);\r\n\r\n        if (scene.activeCamera.mode === Camera.ORTHOGRAPHIC_CAMERA) {\r\n            this._lineShader.setFloat(\"width\", this._source.edgesWidth / this.edgesWidthScalerForOrthographic);\r\n        } else {\r\n            this._lineShader.setFloat(\"width\", this._source.edgesWidth / this.edgesWidthScalerForPerspective);\r\n        }\r\n\r\n        this._lineShader.setFloat(\"aspectRatio\", engine.getAspectRatio(scene.activeCamera));\r\n        this._lineShader.bind(this._source.getWorldMatrix(), this._source);\r\n\r\n        // Draw order\r\n        engine.drawElementsType(Material.TriangleFillMode, 0, this._indicesCount, instanceCount);\r\n        this._lineShader.unbind();\r\n\r\n        if (useBuffersWithInstances) {\r\n            engine.unbindInstanceAttributes();\r\n        }\r\n\r\n        if (!this._source.getScene()._activeMeshesFrozen) {\r\n            this.customInstances.reset();\r\n        }\r\n\r\n        this._lineShader._setDrawWrapper(currentDrawWrapper);\r\n    }\r\n}\r\n\r\n/**\r\n * LineEdgesRenderer for LineMeshes to remove unnecessary triangulation\r\n */\r\nexport class LineEdgesRenderer extends EdgesRenderer {\r\n    /**\r\n     * This constructor turns off auto generating edges line in Edges Renderer to make it here.\r\n     * @param  source LineMesh used to generate edges\r\n     * @param  epsilon not important (specified angle for edge detection)\r\n     * @param  checkVerticesInsteadOfIndices not important for LineMesh\r\n     */\r\n    constructor(source: AbstractMesh, epsilon = 0.95, checkVerticesInsteadOfIndices = false) {\r\n        super(source, epsilon, checkVerticesInsteadOfIndices, false);\r\n        this._generateEdgesLines();\r\n    }\r\n\r\n    /**\r\n     * Generate edges for each line in LinesMesh. Every Line should be rendered as edge.\r\n     */\r\n    override _generateEdgesLines(): void {\r\n        const positions = this._source.getVerticesData(VertexBuffer.PositionKind);\r\n        const indices = this._source.getIndices();\r\n\r\n        if (!indices || !positions) {\r\n            return;\r\n        }\r\n\r\n        const p0 = TmpVectors.Vector3[0];\r\n        const p1 = TmpVectors.Vector3[1];\r\n        const len = indices.length - 1;\r\n        for (let i = 0, offset = 0; i < len; i += 2, offset += 4) {\r\n            Vector3.FromArrayToRef(positions, 3 * indices[i], p0);\r\n            Vector3.FromArrayToRef(positions, 3 * indices[i + 1], p1);\r\n            this.createLine(p0, p1, offset);\r\n        }\r\n\r\n        // Merge into a single mesh\r\n        const engine = this._source.getScene().getEngine();\r\n\r\n        this._buffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, this._linesPositions, VertexBuffer.PositionKind, false);\r\n        this._buffers[VertexBuffer.NormalKind] = new VertexBuffer(engine, this._linesNormals, VertexBuffer.NormalKind, false, false, 4);\r\n\r\n        this._ib = engine.createIndexBuffer(this._linesIndices);\r\n\r\n        this._indicesCount = this._linesIndices.length;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for edgesRenderer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterEdgesRenderer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    AbstractMesh.prototype.disableEdgesRendering = function (): AbstractMesh {\r\n        if (this._edgesRenderer) {\r\n            this._edgesRenderer.dispose();\r\n            this._edgesRenderer = null;\r\n        }\r\n        return this;\r\n    };\r\n\r\n    AbstractMesh.prototype.enableEdgesRendering = function (epsilon = 0.95, checkVerticesInsteadOfIndices = false, options?: IEdgesRendererOptions): AbstractMesh {\r\n        this.disableEdgesRendering();\r\n        this._edgesRenderer = new EdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices, true, options);\r\n        return this;\r\n    };\r\n\r\n    Object.defineProperty(AbstractMesh.prototype, \"edgesRenderer\", {\r\n        get: function (this: AbstractMesh) {\r\n            return this._edgesRenderer;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    LinesMesh.prototype.enableEdgesRendering = function (epsilon = 0.95, checkVerticesInsteadOfIndices = false): AbstractMesh {\r\n        this.disableEdgesRendering();\r\n        this._edgesRenderer = new LineEdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);\r\n        return this;\r\n    };\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n    InstancedLinesMesh.prototype.enableEdgesRendering = function (epsilon = 0.95, checkVerticesInsteadOfIndices = false): InstancedLinesMesh {\r\n        LinesMesh.prototype.enableEdgesRendering.apply(this, [epsilon, checkVerticesInsteadOfIndices]);\r\n        return this;\r\n    };\r\n}\r\n","import { Constants } from \"../../Engines/constants\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Matrix, Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { PostProcess, type PostProcessOptions } from \"../../PostProcesses/postProcess.pure\";\r\nimport { type IblShadowsRenderPipeline } from \"./iblShadowsRenderPipeline\";\r\nimport { type Camera } from \"../../Cameras/camera\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { GeometryBufferRenderer } from \"../../Rendering/geometryBufferRenderer.pure\";\r\nimport { ProceduralTexture, type IProceduralTextureCreationOptions } from \"core/Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type CubeTexture } from \"../../Materials/Textures/cubeTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type EventState } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Build cdf maps for IBL importance sampling during IBL shadow computation.\r\n * This should not be instantiated directly, as it is part of a scene component\r\n * @internal\r\n */\r\nexport class _IblShadowsVoxelTracingPass {\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n    private _renderPipeline: IblShadowsRenderPipeline;\r\n    private _voxelShadowOpacity: number = 1.0;\r\n    /**\r\n     * The opacity of the shadow cast from the voxel grid\r\n     */\r\n    public get voxelShadowOpacity(): number {\r\n        return this._voxelShadowOpacity;\r\n    }\r\n    /**\r\n     * The opacity of the shadow cast from the voxel grid\r\n     */\r\n    public set voxelShadowOpacity(value: number) {\r\n        this._voxelShadowOpacity = value;\r\n    }\r\n    private _sssSamples: number = 16;\r\n    private _sssStride: number = 8;\r\n    private _sssMaxDist: number = 0.05;\r\n    private _sssThickness: number = 0.5;\r\n\r\n    private _ssShadowOpacity: number = 1.0;\r\n    /**\r\n     * The opacity of the screen-space shadow\r\n     */\r\n    public get ssShadowOpacity(): number {\r\n        return this._ssShadowOpacity;\r\n    }\r\n    /**\r\n     * The opacity of the screen-space shadow\r\n     */\r\n    public set ssShadowOpacity(value: number) {\r\n        this._ssShadowOpacity = value;\r\n    }\r\n\r\n    /**\r\n     * The number of samples used in the screen space shadow pass.\r\n     */\r\n    public get sssSamples(): number {\r\n        return this._sssSamples;\r\n    }\r\n\r\n    /**\r\n     * The number of samples used in the screen space shadow pass.\r\n     */\r\n    public set sssSamples(value: number) {\r\n        this._sssSamples = value;\r\n    }\r\n\r\n    /**\r\n     * The stride used in the screen space shadow pass. This controls the distance between samples.\r\n     */\r\n    public get sssStride(): number {\r\n        return this._sssStride;\r\n    }\r\n\r\n    /**\r\n     * The stride used in the screen space shadow pass. This controls the distance between samples.\r\n     */\r\n    public set sssStride(value: number) {\r\n        this._sssStride = value;\r\n    }\r\n\r\n    /**\r\n     * The maximum distance that the screen-space shadow will be able to occlude.\r\n     */\r\n    public get sssMaxDist(): number {\r\n        return this._sssMaxDist;\r\n    }\r\n\r\n    /**\r\n     * The maximum distance that the screen-space shadow will be able to occlude.\r\n     */\r\n    public set sssMaxDist(value: number) {\r\n        this._sssMaxDist = value;\r\n    }\r\n\r\n    /**\r\n     * The thickness of the screen-space shadow\r\n     */\r\n    public get sssThickness(): number {\r\n        return this._sssThickness;\r\n    }\r\n\r\n    /**\r\n     * The thickness of the screen-space shadow\r\n     */\r\n    public set sssThickness(value: number) {\r\n        this._sssThickness = value;\r\n    }\r\n\r\n    private _outputTexture: ProceduralTexture;\r\n    private _cameraInvView: Matrix = Matrix.Identity();\r\n    private _cameraInvProj: Matrix = Matrix.Identity();\r\n    private _invWorldScaleMatrix: Matrix = Matrix.Identity();\r\n    private _frameId: number = 0;\r\n    private _sampleDirections: number = 4;\r\n    private _shadowParameters: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n    private _sssParameters: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n    private _opacityParameters: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n    private _voxelBiasParameters: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n    private _voxelNormalBias: number = 1.4;\r\n    /**\r\n     * The bias to apply to the voxel sampling in the direction of the surface normal of the geometry.\r\n     */\r\n    public get voxelNormalBias(): number {\r\n        return this._voxelNormalBias;\r\n    }\r\n    public set voxelNormalBias(value: number) {\r\n        this._voxelNormalBias = value;\r\n    }\r\n\r\n    private _voxelDirectionBias: number = 1.75;\r\n    /**\r\n     * The bias to apply to the voxel sampling in the direction of the light.\r\n     */\r\n    public get voxelDirectionBias(): number {\r\n        return this._voxelDirectionBias;\r\n    }\r\n    public set voxelDirectionBias(value: number) {\r\n        this._voxelDirectionBias = value;\r\n    }\r\n\r\n    private _enabled: boolean = true;\r\n\r\n    /**\r\n     * Is the effect enabled\r\n     */\r\n    public get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public set enabled(value: boolean) {\r\n        this._enabled = value;\r\n        // _render() already gates on `enabled`, but also disable the underlying ProceduralTexture\r\n        // directly so it can't be rendered through any other path (e.g. Babylon's generic\r\n        // per-frame ProceduralTexture refresh loop) while the pass is toggled off.\r\n        if (this._outputTexture) {\r\n            this._outputTexture.isEnabled = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * The number of directions to sample for the voxel tracing.\r\n     */\r\n    public get sampleDirections(): number {\r\n        return this._sampleDirections;\r\n    }\r\n\r\n    /**\r\n     * The number of directions to sample for the voxel tracing.\r\n     */\r\n    public set sampleDirections(value: number) {\r\n        this._sampleDirections = value;\r\n    }\r\n\r\n    /**\r\n     * The current rotation of the environment map, in radians.\r\n     */\r\n    public get envRotation(): number {\r\n        return this._envRotation;\r\n    }\r\n\r\n    /**\r\n     * The current rotation of the environment map, in radians.\r\n     */\r\n    public set envRotation(value: number) {\r\n        this._envRotation = value;\r\n    }\r\n\r\n    /** Enable the debug view for this pass */\r\n    public debugEnabled: boolean = false;\r\n\r\n    /**\r\n     * Returns the output texture of the pass.\r\n     * @returns The output texture.\r\n     */\r\n    public getOutputTexture(): ProceduralTexture {\r\n        return this._outputTexture;\r\n    }\r\n\r\n    /**\r\n     * Gets the debug pass post process. This will create the resources for the pass\r\n     * if they don't already exist.\r\n     * @returns The post process\r\n     */\r\n    public getDebugPassPP(): PostProcess {\r\n        if (!this._debugPassPP) {\r\n            this._createDebugPass();\r\n        }\r\n        return this._debugPassPP;\r\n    }\r\n\r\n    private _debugPassName: string = \"Voxel Tracing Debug Pass\";\r\n\r\n    /**\r\n     * The name of the debug pass\r\n     */\r\n    public get debugPassName(): string {\r\n        return this._debugPassName;\r\n    }\r\n\r\n    /** The default rotation of the environment map will align the shadows with the default lighting orientation */\r\n    private _envRotation: number = 0.0;\r\n\r\n    /**\r\n     * Set the matrix to use for scaling the world space to voxel space\r\n     * @param matrix The matrix to use for scaling the world space to voxel space\r\n     */\r\n    public setWorldScaleMatrix(matrix: Matrix) {\r\n        this._invWorldScaleMatrix = matrix;\r\n    }\r\n\r\n    /**\r\n     * Render the shadows in color rather than black and white.\r\n     * This is slightly more expensive than black and white shadows but can be much\r\n     * more accurate when the strongest lights in the IBL are non-white.\r\n     */\r\n    public set coloredShadows(value: boolean) {\r\n        this._coloredShadows = value;\r\n    }\r\n    public get coloredShadows(): boolean {\r\n        return this._coloredShadows;\r\n    }\r\n    private _coloredShadows: boolean = false;\r\n\r\n    /**\r\n     * Maximum number of translucent voxels a shadow ray roulettes through before it is treated as\r\n     * unoccluded. Higher values converge more accurately at extra cost. Applied via a shader define.\r\n     */\r\n    public set maxVoxelRouletteTests(value: number) {\r\n        // Becomes a shader define, so keep it a finite integer in [1, 4096]; ignore non-finite input.\r\n        if (!Number.isFinite(value)) {\r\n            return;\r\n        }\r\n        this._maxVoxelRouletteTests = Math.min(4096, Math.max(1, Math.floor(value)));\r\n    }\r\n    public get maxVoxelRouletteTests(): number {\r\n        return this._maxVoxelRouletteTests;\r\n    }\r\n    private _maxVoxelRouletteTests: number = 16;\r\n\r\n    private _debugVoxelMarchEnabled: boolean = false;\r\n    private _debugPassPP: PostProcess;\r\n    private _debugSizeParams: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n\r\n    /**\r\n     * Sets params that control the position and scaling of the debug display on the screen.\r\n     * @param x Screen X offset of the debug display (0-1)\r\n     * @param y Screen Y offset of the debug display (0-1)\r\n     * @param widthScale X scale of the debug display (0-1)\r\n     * @param heightScale Y scale of the debug display (0-1)\r\n     */\r\n    public setDebugDisplayParams(x: number, y: number, widthScale: number, heightScale: number) {\r\n        this._debugSizeParams.set(x, y, widthScale, heightScale);\r\n    }\r\n\r\n    /**\r\n     * Creates the debug post process effect for this pass\r\n     */\r\n    private _createDebugPass() {\r\n        const isWebGPU = this._engine.isWebGPU;\r\n        if (!this._debugPassPP) {\r\n            const debugOptions: PostProcessOptions = {\r\n                width: this._engine.getRenderWidth(),\r\n                height: this._engine.getRenderHeight(),\r\n                uniforms: [\"sizeParams\"],\r\n                samplers: [\"debugSampler\"],\r\n                engine: this._engine,\r\n                reusable: true,\r\n                shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n                extraInitializations: (useWebGPU: boolean, list: Promise<any>[]) => {\r\n                    if (useWebGPU) {\r\n                        list.push(import(\"../../ShadersWGSL/iblShadowDebug.fragment\"));\r\n                    } else {\r\n                        list.push(import(\"../../Shaders/iblShadowDebug.fragment\"));\r\n                    }\r\n                },\r\n            };\r\n            this._debugPassPP = new PostProcess(this.debugPassName, \"iblShadowDebug\", debugOptions);\r\n            this._debugPassPP.autoClear = false;\r\n            this._debugPassPP.onApplyObservable.add((effect) => {\r\n                // update the caustic texture with what we just rendered.\r\n                effect.setTexture(\"debugSampler\", this._outputTexture);\r\n                effect.setVector4(\"sizeParams\", this._debugSizeParams);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiates the shadow voxel-tracing pass\r\n     * @param scene Scene to attach to\r\n     * @param iblShadowsRenderPipeline The IBL shadows render pipeline\r\n     * @returns The shadow voxel-tracing pass\r\n     */\r\n    constructor(scene: Scene, iblShadowsRenderPipeline: IblShadowsRenderPipeline) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._renderPipeline = iblShadowsRenderPipeline;\r\n        this._createTextures();\r\n    }\r\n\r\n    private _createTextures() {\r\n        const defines = this._createDefines();\r\n        const isWebGPU = this._engine.isWebGPU;\r\n        const textureOptions: IProceduralTextureCreationOptions = {\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            generateDepthBuffer: false,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/iblShadowVoxelTracing.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/iblShadowVoxelTracing.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n        this._outputTexture = new ProceduralTexture(\r\n            \"voxelTracingPass\",\r\n            {\r\n                width: this._engine.getRenderWidth(),\r\n                height: this._engine.getRenderHeight(),\r\n            },\r\n            \"iblShadowVoxelTracing\",\r\n            this._scene,\r\n            textureOptions\r\n        );\r\n        this._outputTexture.refreshRate = -1;\r\n        this._outputTexture.autoClear = false;\r\n        this._outputTexture.defines = defines;\r\n        // Need to set all the textures first so that the effect gets created with the proper uniforms.\r\n        this._setBindings(this._scene.activeCamera!);\r\n        this._renderWhenGBufferReady = this._render.bind(this);\r\n        // Don't start rendering until the first vozelization is done.\r\n        this._renderPipeline.onVoxelizationCompleteObservable.addOnce(() => {\r\n            if (this._scene.geometryBufferRenderer) {\r\n                this._scene.geometryBufferRenderer.getGBuffer().onAfterRenderObservable.add(this._renderWhenGBufferReady);\r\n            }\r\n        });\r\n    }\r\n\r\n    private _createDefines(): string {\r\n        let defines = \"\";\r\n        if (this._scene.useRightHandedSystem) {\r\n            defines += \"#define RIGHT_HANDED\\n\";\r\n        }\r\n        if (this._debugVoxelMarchEnabled) {\r\n            defines += \"#define VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION 1u\\n\";\r\n        }\r\n        if (this._coloredShadows) {\r\n            defines += \"#define COLOR_SHADOWS 1u\\n\";\r\n        }\r\n        if (this._scene.geometryBufferRenderer?.normalsAreUnsigned) {\r\n            defines += \"#define WORLD_NORMAL_UNSIGNED\\n\";\r\n        }\r\n        // _maxVoxelRouletteTests is normalized to a finite integer in [1, 4096] by its setter.\r\n        defines += `#define MAX_VOXEL_ROULETTE_TESTS ${this._maxVoxelRouletteTests}\\n`;\r\n        return defines;\r\n    }\r\n\r\n    private _setBindings(camera: Camera): boolean {\r\n        this._outputTexture.defines = this._createDefines();\r\n        this._outputTexture.setMatrix(\"viewMtx\", camera.getViewMatrix());\r\n        this._outputTexture.setMatrix(\"projMtx\", camera.getProjectionMatrix());\r\n        camera.getProjectionMatrix().invertToRef(this._cameraInvProj);\r\n        camera.getViewMatrix().invertToRef(this._cameraInvView);\r\n        this._outputTexture.setMatrix(\"invProjMtx\", this._cameraInvProj);\r\n        this._outputTexture.setMatrix(\"invViewMtx\", this._cameraInvView);\r\n        this._outputTexture.setMatrix(\"wsNormalizationMtx\", this._invWorldScaleMatrix);\r\n\r\n        this._frameId++;\r\n\r\n        let rotation = 0.0;\r\n        if (this._scene.environmentTexture) {\r\n            rotation = (this._scene.environmentTexture as CubeTexture).rotationY ?? 0;\r\n        }\r\n        rotation = this._scene.useRightHandedSystem ? -(rotation + 0.5 * Math.PI) : rotation - 0.5 * Math.PI;\r\n        rotation = rotation % (2.0 * Math.PI);\r\n        this._shadowParameters.set(this._sampleDirections, this._frameId, 1.0, rotation);\r\n        this._outputTexture.setVector4(\"shadowParameters\", this._shadowParameters);\r\n        const voxelGrid = this._renderPipeline._getVoxelGridTexture();\r\n        const highestMip = Math.floor(Math.log2(voxelGrid.getSize().width));\r\n        this._voxelBiasParameters.set(this._voxelNormalBias, this._voxelDirectionBias, highestMip, 0.0);\r\n        this._outputTexture.setVector4(\"voxelBiasParameters\", this._voxelBiasParameters);\r\n\r\n        // SSS Options.\r\n        this._sssParameters.set(this._sssSamples, this._sssStride, this._sssMaxDist, this._sssThickness);\r\n        this._outputTexture.setVector4(\"sssParameters\", this._sssParameters);\r\n        this._opacityParameters.set(this._voxelShadowOpacity, this._ssShadowOpacity, 0.0, 0.0);\r\n        this._outputTexture.setVector4(\"shadowOpacity\", this._opacityParameters);\r\n        this._outputTexture.setTexture(\"voxelGridSampler\", voxelGrid);\r\n        this._outputTexture.setTexture(\"blueNoiseSampler\", this._renderPipeline._getNoiseTexture());\r\n        const cdfGenerator = this._scene.iblCdfGenerator;\r\n        if (!cdfGenerator) {\r\n            Logger.Warn(\"IBLShadowsVoxelTracingPass: Can't bind for render because iblCdfGenerator is not enabled.\");\r\n            return false;\r\n        }\r\n        this._outputTexture.setTexture(\"icdfSampler\", cdfGenerator.getIcdfTexture());\r\n        if (this._coloredShadows && this._scene.environmentTexture) {\r\n            this._outputTexture.setTexture(\"iblSampler\", this._scene.environmentTexture);\r\n        }\r\n\r\n        const geometryBufferRenderer = this._scene.geometryBufferRenderer;\r\n        if (!geometryBufferRenderer) {\r\n            Logger.Warn(\"IBLShadowsVoxelTracingPass: Can't bind for render because GeometryBufferRenderer is not enabled.\");\r\n            return false;\r\n        }\r\n        const depthIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE);\r\n        this._outputTexture.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[depthIndex]);\r\n        const wnormalIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE);\r\n        this._outputTexture.setTexture(\"worldNormalSampler\", geometryBufferRenderer.getGBuffer().textures[wnormalIndex]);\r\n        return true;\r\n    }\r\n\r\n    private _render() {\r\n        if (this.enabled && this._outputTexture.isReady() && this._outputTexture.getEffect()?.isReady()) {\r\n            if (this._setBindings(this._scene.activeCamera!)) {\r\n                this._outputTexture.render();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _renderWhenGBufferReady: Nullable<(eventData: number, eventState: EventState) => void> = null;\r\n\r\n    /**\r\n     * Called by render pipeline when canvas resized.\r\n     * @param scaleFactor The factor by which to scale the canvas size.\r\n     */\r\n    public resize(scaleFactor: number = 1.0) {\r\n        const newSize = {\r\n            width: Math.max(1.0, Math.floor(this._engine.getRenderWidth() * scaleFactor)),\r\n            height: Math.max(1.0, Math.floor(this._engine.getRenderHeight() * scaleFactor)),\r\n        };\r\n        // Don't resize if the size is the same as the current size.\r\n        if (this._outputTexture.getSize().width === newSize.width && this._outputTexture.getSize().height === newSize.height) {\r\n            return;\r\n        }\r\n        this._outputTexture.resize(newSize, false);\r\n    }\r\n\r\n    /**\r\n     * Checks if the pass is ready\r\n     * @returns true if the pass is ready\r\n     */\r\n    public isReady() {\r\n        return (\r\n            this._outputTexture.isReady() &&\r\n            !(this._debugPassPP && !this._debugPassPP.isReady()) &&\r\n            this._scene.iblCdfGenerator &&\r\n            this._scene.iblCdfGenerator.getIcdfTexture().isReady() &&\r\n            this._renderPipeline._getVoxelGridTexture().isReady()\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Disposes the associated resources\r\n     */\r\n    public dispose() {\r\n        if (this._scene.geometryBufferRenderer && this._renderWhenGBufferReady) {\r\n            const gBuffer = this._scene.geometryBufferRenderer.getGBuffer();\r\n            gBuffer.onAfterRenderObservable.removeCallback(this._renderWhenGBufferReady);\r\n        }\r\n        this._outputTexture.dispose();\r\n        if (this._debugPassPP) {\r\n            this._debugPassPP.dispose();\r\n        }\r\n    }\r\n}\r\n","import { Constants } from \"../../Engines/constants\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { PostProcess, type PostProcessOptions } from \"../../PostProcesses/postProcess.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { GeometryBufferRenderer } from \"../../Rendering/geometryBufferRenderer.pure\";\r\nimport { ProceduralTexture, type IProceduralTextureCreationOptions } from \"core/Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type IblShadowsRenderPipeline } from \"./iblShadowsRenderPipeline\";\r\nimport { type EventState } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * This should not be instanciated directly, as it is part of a scene component\r\n * @internal\r\n */\r\nexport class _IblShadowsSpatialBlurPass {\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n    private _renderPipeline: IblShadowsRenderPipeline;\r\n    private _outputTexture: ProceduralTexture;\r\n    private _worldScale: number = 1.0;\r\n    private _blurParameters: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n\r\n    private _enabled: boolean = true;\r\n\r\n    /**\r\n     * Is the effect enabled\r\n     */\r\n    public get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public set enabled(value: boolean) {\r\n        this._enabled = value;\r\n        // _render() already gates on `enabled`, but also disable the underlying ProceduralTexture\r\n        // directly so it can't be rendered through any other path (e.g. Babylon's generic\r\n        // per-frame ProceduralTexture refresh loop) while the pass is toggled off.\r\n        if (this._outputTexture) {\r\n            this._outputTexture.isEnabled = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the output texture of the pass.\r\n     * @returns The output texture.\r\n     */\r\n    public getOutputTexture(): ProceduralTexture {\r\n        return this._outputTexture;\r\n    }\r\n\r\n    /**\r\n     * Gets the debug pass post process\r\n     * @returns The post process\r\n     */\r\n    public getDebugPassPP(): PostProcess {\r\n        if (!this._debugPassPP) {\r\n            this._createDebugPass();\r\n        }\r\n        return this._debugPassPP;\r\n    }\r\n    private _debugPassName: string = \"Spatial Blur Debug Pass\";\r\n    /**\r\n     * Sets the name of the debug pass\r\n     */\r\n    public get debugPassName(): string {\r\n        return this._debugPassName;\r\n    }\r\n\r\n    /**\r\n     * The scale of the voxel grid in world space. This is used to scale the blur radius in world space.\r\n     * @param scale The scale of the voxel grid in world space.\r\n     */\r\n    public setWorldScale(scale: number) {\r\n        this._worldScale = scale;\r\n    }\r\n\r\n    /** Enable the debug view for this pass */\r\n    public debugEnabled: boolean = false;\r\n    private _debugPassPP: PostProcess;\r\n    private _debugSizeParams: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n\r\n    /**\r\n     * Sets params that control the position and scaling of the debug display on the screen.\r\n     * @param x Screen X offset of the debug display (0-1)\r\n     * @param y Screen Y offset of the debug display (0-1)\r\n     * @param widthScale X scale of the debug display (0-1)\r\n     * @param heightScale Y scale of the debug display (0-1)\r\n     */\r\n    public setDebugDisplayParams(x: number, y: number, widthScale: number, heightScale: number) {\r\n        this._debugSizeParams.set(x, y, widthScale, heightScale);\r\n    }\r\n\r\n    /**\r\n     * Creates the debug post process effect for this pass\r\n     */\r\n    private _createDebugPass() {\r\n        if (!this._debugPassPP) {\r\n            const isWebGPU = this._engine.isWebGPU;\r\n            const debugOptions: PostProcessOptions = {\r\n                width: this._engine.getRenderWidth(),\r\n                height: this._engine.getRenderHeight(),\r\n                textureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n                textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                uniforms: [\"sizeParams\"],\r\n                samplers: [\"debugSampler\"],\r\n                engine: this._engine,\r\n                reusable: false,\r\n                shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n                extraInitializations: (useWebGPU: boolean, list: Promise<any>[]) => {\r\n                    if (useWebGPU) {\r\n                        list.push(import(\"../../ShadersWGSL/iblShadowDebug.fragment\"));\r\n                    } else {\r\n                        list.push(import(\"../../Shaders/iblShadowDebug.fragment\"));\r\n                    }\r\n                },\r\n            };\r\n            this._debugPassPP = new PostProcess(this.debugPassName, \"iblShadowDebug\", debugOptions);\r\n            this._debugPassPP.autoClear = false;\r\n            this._debugPassPP.onApplyObservable.add((effect) => {\r\n                // update the caustic texture with what we just rendered.\r\n                effect.setTexture(\"debugSampler\", this._outputTexture);\r\n                effect.setVector4(\"sizeParams\", this._debugSizeParams);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instanciates the importance sampling renderer\r\n     * @param scene Scene to attach to\r\n     * @param iblShadowsRenderPipeline The IBL shadows render pipeline\r\n     * @returns The importance sampling renderer\r\n     */\r\n    constructor(scene: Scene, iblShadowsRenderPipeline: IblShadowsRenderPipeline) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._renderPipeline = iblShadowsRenderPipeline;\r\n        this._createTextures();\r\n    }\r\n\r\n    private _createTextures() {\r\n        const isWebGPU = this._engine.isWebGPU;\r\n        const textureOptions: IProceduralTextureCreationOptions = {\r\n            type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: false,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/iblShadowSpatialBlur.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/iblShadowSpatialBlur.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n        this._outputTexture = new ProceduralTexture(\r\n            \"spatialBlurPass\",\r\n            {\r\n                width: this._engine.getRenderWidth(),\r\n                height: this._engine.getRenderHeight(),\r\n            },\r\n            \"iblShadowSpatialBlur\",\r\n            this._scene,\r\n            textureOptions,\r\n            false,\r\n            false,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n        );\r\n        this._outputTexture.refreshRate = -1;\r\n        this._outputTexture.autoClear = false;\r\n\r\n        // Need to set all the textures first so that the effect gets created with the proper uniforms.\r\n        this._setBindings();\r\n\r\n        this._renderWhenGBufferReady = this._render.bind(this);\r\n        // Don't start rendering until the first vozelization is done.\r\n        this._renderPipeline.onVoxelizationCompleteObservable.addOnce(() => {\r\n            if (this._scene.geometryBufferRenderer) {\r\n                this._scene.geometryBufferRenderer.getGBuffer().onAfterRenderObservable.add(this._renderWhenGBufferReady);\r\n            }\r\n        });\r\n    }\r\n\r\n    private _setBindings(): boolean {\r\n        this._outputTexture.setTexture(\"voxelTracingSampler\", this._renderPipeline._getVoxelTracingTexture());\r\n        const iterationCount = 1;\r\n        this._blurParameters.set(iterationCount, this._worldScale, 0.0, 0.0);\r\n        this._outputTexture.setVector4(\"blurParameters\", this._blurParameters);\r\n        const geometryBufferRenderer = this._scene.geometryBufferRenderer;\r\n        if (!geometryBufferRenderer) {\r\n            return false;\r\n        }\r\n        const depthIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE);\r\n        this._outputTexture.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[depthIndex]);\r\n        const wnormalIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE);\r\n        this._outputTexture.setTexture(\"worldNormalSampler\", geometryBufferRenderer.getGBuffer().textures[wnormalIndex]);\r\n        return true;\r\n    }\r\n\r\n    private _render() {\r\n        if (this.enabled && this._outputTexture.isReady() && this._outputTexture.getEffect()?.isReady()) {\r\n            if (this._setBindings()) {\r\n                this._outputTexture.render();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _renderWhenGBufferReady: Nullable<(eventData: number, eventState: EventState) => void> = null;\r\n\r\n    /**\r\n     * Called by render pipeline when canvas resized.\r\n     * @param scaleFactor The factor by which to scale the canvas size.\r\n     */\r\n    public resize(scaleFactor: number = 1.0) {\r\n        const newSize = {\r\n            width: Math.max(1.0, Math.floor(this._engine.getRenderWidth() * scaleFactor)),\r\n            height: Math.max(1.0, Math.floor(this._engine.getRenderHeight() * scaleFactor)),\r\n        };\r\n        // Don't resize if the size is the same as the current size.\r\n        if (this._outputTexture.getSize().width === newSize.width && this._outputTexture.getSize().height === newSize.height) {\r\n            return;\r\n        }\r\n        this._outputTexture.resize(newSize, false);\r\n    }\r\n\r\n    /**\r\n     * Checks if the pass is ready\r\n     * @returns true if the pass is ready\r\n     */\r\n    public isReady() {\r\n        return this._outputTexture.isReady() && !(this._debugPassPP && !this._debugPassPP.isReady());\r\n    }\r\n\r\n    /**\r\n     * Disposes the associated resources\r\n     */\r\n    public dispose() {\r\n        if (this._scene.geometryBufferRenderer && this._renderWhenGBufferReady) {\r\n            const gBuffer = this._scene.geometryBufferRenderer.getGBuffer();\r\n            gBuffer.onAfterRenderObservable.removeCallback(this._renderWhenGBufferReady);\r\n        }\r\n        this._outputTexture.dispose();\r\n        if (this._debugPassPP) {\r\n            this._debugPassPP.dispose();\r\n        }\r\n    }\r\n}\r\n","import { Constants } from \"../../Engines/constants\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector4 } from \"../../Maths/math.vector.pure\";\r\nimport { PostProcess, type PostProcessOptions } from \"../../PostProcesses/postProcess.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { GeometryBufferRenderer } from \"../../Rendering/geometryBufferRenderer.pure\";\r\nimport { ProceduralTexture, type IProceduralTextureCreationOptions } from \"core/Materials/Textures/Procedurals/proceduralTexture.pure\";\r\nimport { type IblShadowsRenderPipeline } from \"./iblShadowsRenderPipeline\";\r\nimport { Observable, type EventState } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * This should not be instantiated directly, as it is part of a scene component\r\n * @internal\r\n */\r\nexport class _IblShadowsAccumulationPass {\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n    private _renderPipeline: IblShadowsRenderPipeline;\r\n\r\n    // First, render the accumulation pass with both position buffers, motion buffer, shadow buffer, and the previous accumulation buffer\r\n    private _outputTexture: ProceduralTexture;\r\n    private _oldAccumulationCopy: ProceduralTexture;\r\n    private _oldPositionCopy: ProceduralTexture;\r\n    private _accumulationParams: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n\r\n    /** Enable the debug view for this pass */\r\n    public debugEnabled: boolean = false;\r\n\r\n    private _enabled: boolean = true;\r\n\r\n    /**\r\n     * Is the effect enabled\r\n     */\r\n    public get enabled(): boolean {\r\n        return this._enabled;\r\n    }\r\n\r\n    public set enabled(value: boolean) {\r\n        this._enabled = value;\r\n        // _render() already gates on `enabled` for _outputTexture, but _oldAccumulationCopy and\r\n        // _oldPositionCopy have refreshRate = 1 and are rendered by Babylon's generic per-frame\r\n        // ProceduralTexture refresh loop, entirely independent of `enabled` / `_render()`. Without\r\n        // disabling them directly here, they keep rendering (and paying a real per-frame texture-view\r\n        // creation cost) every frame forever, even when the whole pass — and the rest of the IBL\r\n        // shadows pipeline — has been toggled off (e.g. no shadow casters or receivers in the scene).\r\n        if (this._outputTexture) {\r\n            this._outputTexture.isEnabled = value;\r\n        }\r\n        if (this._oldAccumulationCopy) {\r\n            this._oldAccumulationCopy.isEnabled = value;\r\n        }\r\n        if (this._oldPositionCopy) {\r\n            this._oldPositionCopy.isEnabled = value;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the output texture of the pass.\r\n     * @returns The output texture.\r\n     */\r\n    public getOutputTexture(): ProceduralTexture {\r\n        return this._outputTexture;\r\n    }\r\n\r\n    /**\r\n     * Observable that triggers when the accumulation texture is ready\r\n     */\r\n    public onReadyObservable: Observable<void> = new Observable<void>();\r\n\r\n    /**\r\n     * Gets the debug pass post process\r\n     * @returns The post process\r\n     */\r\n    public getDebugPassPP(): PostProcess {\r\n        if (!this._debugPassPP) {\r\n            this._createDebugPass();\r\n        }\r\n        return this._debugPassPP;\r\n    }\r\n\r\n    private _debugPassName: string = \"Shadow Accumulation Debug Pass\";\r\n\r\n    /**\r\n     * Gets the name of the debug pass\r\n     * @returns The name of the debug pass\r\n     */\r\n    public get debugPassName(): string {\r\n        return this._debugPassName;\r\n    }\r\n\r\n    /**\r\n     * A value that controls how much of the previous frame's accumulation to keep.\r\n     * The higher the value, the faster the shadows accumulate but the more potential ghosting you'll see.\r\n     */\r\n    public get remanence(): number {\r\n        return this._remanence;\r\n    }\r\n\r\n    /**\r\n     * A value that controls how much of the previous frame's accumulation to keep.\r\n     * The higher the value, the faster the shadows accumulate but the more potential ghosting you'll see.\r\n     */\r\n    public set remanence(value: number) {\r\n        this._remanence = value;\r\n    }\r\n    private _remanence: number = 0.9;\r\n\r\n    /**\r\n     * Reset the accumulation.\r\n     */\r\n    public get reset(): boolean {\r\n        return this._reset;\r\n    }\r\n    /**\r\n     * Reset the accumulation.\r\n     */\r\n    public set reset(value: boolean) {\r\n        this._reset = value;\r\n    }\r\n    private _reset: boolean = true;\r\n\r\n    /**\r\n     * Tell the pass that the camera is moving. This will cause the accumulation\r\n     * rate to change.\r\n     */\r\n    public set isMoving(value: boolean) {\r\n        this._isMoving = value;\r\n    }\r\n    private _isMoving: boolean = false;\r\n\r\n    private _debugPassPP: PostProcess;\r\n    private _debugSizeParams: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n\r\n    /**\r\n     * Sets params that control the position and scaling of the debug display on the screen.\r\n     * @param x Screen X offset of the debug display (0-1)\r\n     * @param y Screen Y offset of the debug display (0-1)\r\n     * @param widthScale X scale of the debug display (0-1)\r\n     * @param heightScale Y scale of the debug display (0-1)\r\n     */\r\n    public setDebugDisplayParams(x: number, y: number, widthScale: number, heightScale: number) {\r\n        this._debugSizeParams.set(x, y, widthScale, heightScale);\r\n    }\r\n\r\n    /**\r\n     * Creates the debug post process effect for this pass\r\n     */\r\n    private _createDebugPass() {\r\n        if (!this._debugPassPP) {\r\n            const isWebGPU = this._engine.isWebGPU;\r\n            const debugOptions: PostProcessOptions = {\r\n                width: this._engine.getRenderWidth(),\r\n                height: this._engine.getRenderHeight(),\r\n                textureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n                textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                uniforms: [\"sizeParams\"],\r\n                samplers: [\"debugSampler\"],\r\n                engine: this._engine,\r\n                reusable: false,\r\n                shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n                extraInitializations: (useWebGPU: boolean, list: Promise<any>[]) => {\r\n                    if (useWebGPU) {\r\n                        list.push(import(\"../../ShadersWGSL/iblShadowDebug.fragment\"));\r\n                    } else {\r\n                        list.push(import(\"../../Shaders/iblShadowDebug.fragment\"));\r\n                    }\r\n                },\r\n            };\r\n            this._debugPassPP = new PostProcess(this.debugPassName, \"iblShadowDebug\", debugOptions);\r\n            this._debugPassPP.autoClear = false;\r\n            this._debugPassPP.onApplyObservable.add((effect) => {\r\n                // update the caustic texture with what we just rendered.\r\n                effect.setTexture(\"debugSampler\", this._outputTexture);\r\n                effect.setVector4(\"sizeParams\", this._debugSizeParams);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Instantiates the accumulation pass\r\n     * @param scene Scene to attach to\r\n     * @param iblShadowsRenderPipeline The IBL shadows render pipeline\r\n     * @returns The accumulation pass\r\n     */\r\n    constructor(scene: Scene, iblShadowsRenderPipeline: IblShadowsRenderPipeline) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._renderPipeline = iblShadowsRenderPipeline;\r\n        this._createTextures();\r\n    }\r\n\r\n    private _createTextures() {\r\n        const isWebGPU = this._engine.isWebGPU;\r\n\r\n        const outputTextureOptions: IProceduralTextureCreationOptions = {\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: false,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/iblShadowAccumulation.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/iblShadowAccumulation.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n        this._outputTexture = new ProceduralTexture(\r\n            \"shadowAccumulationPass\",\r\n            {\r\n                width: this._engine.getRenderWidth(),\r\n                height: this._engine.getRenderHeight(),\r\n            },\r\n            \"iblShadowAccumulation\",\r\n            this._scene,\r\n            outputTextureOptions\r\n        );\r\n        this._outputTexture.refreshRate = -1;\r\n        this._outputTexture.autoClear = false;\r\n        this._outputTexture.onGeneratedObservable.addOnce(() => {\r\n            this.onReadyObservable.notifyObservers();\r\n        });\r\n\r\n        // Need to set all the textures first so that the effect gets created with the proper uniforms.\r\n        this._setOutputTextureBindings();\r\n\r\n        this._renderWhenGBufferReady = this._render.bind(this);\r\n        // Don't start rendering until the first vozelization is done.\r\n        this._renderPipeline.onVoxelizationCompleteObservable.addOnce(() => {\r\n            if (this._scene.geometryBufferRenderer) {\r\n                this._scene.geometryBufferRenderer.getGBuffer().onAfterRenderObservable.add(this._renderWhenGBufferReady);\r\n            }\r\n        });\r\n\r\n        // Create the accumulation texture for the previous frame.\r\n        // We'll copy the output of the accumulation pass to this texture at the start of every frame.\r\n        const accumulationOptions: IProceduralTextureCreationOptions = {\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: false,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/pass.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/pass.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n\r\n        this._oldAccumulationCopy = new ProceduralTexture(\r\n            \"oldAccumulationRT\",\r\n            { width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() },\r\n            \"pass\",\r\n            this._scene,\r\n            accumulationOptions,\r\n            false\r\n        );\r\n\r\n        this._oldAccumulationCopy.autoClear = false;\r\n        this._oldAccumulationCopy.refreshRate = 1;\r\n        this._oldAccumulationCopy.onBeforeGenerationObservable.add(this._setAccumulationCopyBindings.bind(this));\r\n        this._setAccumulationCopyBindings();\r\n\r\n        // Create the local position texture for the previous frame.\r\n        // We'll copy the previous local position texture to this texture at the start of every frame.\r\n        const localPositionOptions: IProceduralTextureCreationOptions = {\r\n            type: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            format: Constants.TEXTUREFORMAT_RGBA,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            generateDepthBuffer: false,\r\n            generateMipMaps: false,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializationsAsync: async () => {\r\n                if (isWebGPU) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/pass.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/pass.fragment\")]);\r\n                }\r\n            },\r\n        };\r\n\r\n        this._oldPositionCopy = new ProceduralTexture(\r\n            \"oldLocalPositionRT\",\r\n            { width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() },\r\n            \"pass\",\r\n            this._scene,\r\n            localPositionOptions,\r\n            false\r\n        );\r\n        this._updatePositionCopy();\r\n        this._oldPositionCopy.autoClear = false;\r\n        this._oldPositionCopy.refreshRate = 1;\r\n        this._oldPositionCopy.onBeforeGenerationObservable.add(this._updatePositionCopy.bind(this));\r\n    }\r\n\r\n    private _setOutputTextureBindings(): boolean {\r\n        const remanence = this._isMoving ? this.remanence : 0.99;\r\n        this._accumulationParams.set(remanence, this.reset ? 1.0 : 0.0, this._renderPipeline.voxelGridSize, 0.0);\r\n        this._outputTexture.setTexture(\"spatialBlurSampler\", this._renderPipeline._getSpatialBlurTexture());\r\n        this._outputTexture.setVector4(\"accumulationParameters\", this._accumulationParams);\r\n        this._outputTexture.setTexture(\"oldAccumulationSampler\", this._oldAccumulationCopy ? this._oldAccumulationCopy : this._renderPipeline._dummyTexture2d);\r\n        this._outputTexture.setTexture(\"prevPositionSampler\", this._oldPositionCopy ? this._oldPositionCopy : this._renderPipeline._dummyTexture2d);\r\n\r\n        const geometryBufferRenderer = this._scene.geometryBufferRenderer;\r\n        if (!geometryBufferRenderer) {\r\n            return false;\r\n        }\r\n        const velocityIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE);\r\n        this._outputTexture.setTexture(\"motionSampler\", geometryBufferRenderer.getGBuffer().textures[velocityIndex]);\r\n        const wPositionIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.POSITION_TEXTURE_TYPE);\r\n        this._outputTexture.setTexture(\"positionSampler\", geometryBufferRenderer.getGBuffer().textures[wPositionIndex]);\r\n\r\n        this.reset = false;\r\n        this._isMoving = false;\r\n        return true;\r\n    }\r\n\r\n    private _updatePositionCopy() {\r\n        const geometryBufferRenderer = this._scene.geometryBufferRenderer;\r\n        if (geometryBufferRenderer) {\r\n            const index = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.POSITION_TEXTURE_TYPE);\r\n            this._oldPositionCopy.setTexture(\"textureSampler\", geometryBufferRenderer.getGBuffer().textures[index]);\r\n        }\r\n    }\r\n\r\n    private _setAccumulationCopyBindings() {\r\n        this._oldAccumulationCopy.setTexture(\"textureSampler\", this._outputTexture);\r\n    }\r\n\r\n    private _render() {\r\n        if (this.enabled && this._outputTexture.isReady() && this._outputTexture.getEffect()?.isReady()) {\r\n            if (this._setOutputTextureBindings()) {\r\n                this._outputTexture.render();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _renderWhenGBufferReady: Nullable<(eventData: number, eventState: EventState) => void> = null;\r\n\r\n    /**\r\n     * Called by render pipeline when canvas resized.\r\n     * @param scaleFactor The factor by which to scale the canvas size.\r\n     */\r\n    public resize(scaleFactor: number = 1.0) {\r\n        const newSize = {\r\n            width: Math.max(1.0, Math.floor(this._engine.getRenderWidth() * scaleFactor)),\r\n            height: Math.max(1.0, Math.floor(this._engine.getRenderHeight() * scaleFactor)),\r\n        };\r\n        // Don't resize if the size is the same as the current size.\r\n        if (this._outputTexture.getSize().width === newSize.width && this._outputTexture.getSize().height === newSize.height) {\r\n            return;\r\n        }\r\n        this._outputTexture.resize(newSize, false);\r\n        this._oldAccumulationCopy.resize(newSize, false);\r\n        this._oldPositionCopy.resize({ width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() }, false);\r\n        this.reset = true;\r\n    }\r\n\r\n    private _disposeTextures() {\r\n        this._oldAccumulationCopy.dispose();\r\n        this._oldPositionCopy.dispose();\r\n        this._outputTexture.dispose();\r\n    }\r\n\r\n    /**\r\n     * Checks if the pass is ready\r\n     * @returns true if the pass is ready\r\n     */\r\n    public isReady() {\r\n        return (\r\n            this._oldAccumulationCopy &&\r\n            this._oldAccumulationCopy.isReady() &&\r\n            this._oldPositionCopy &&\r\n            this._oldPositionCopy.isReady() &&\r\n            this._outputTexture.isReady() &&\r\n            !(this._debugPassPP && !this._debugPassPP.isReady())\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Disposes the associated resources\r\n     */\r\n    public dispose() {\r\n        if (this._scene.geometryBufferRenderer && this._renderWhenGBufferReady) {\r\n            const gBuffer = this._scene.geometryBufferRenderer.getGBuffer();\r\n            gBuffer.onAfterRenderObservable.removeCallback(this._renderWhenGBufferReady);\r\n        }\r\n        this._disposeTextures();\r\n        if (this._debugPassPP) {\r\n            this._debugPassPP.dispose();\r\n        }\r\n        this.onReadyObservable.clear();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport { Matrix, Vector3, Vector4, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { type GaussianSplattingMesh } from \"../../Meshes/GaussianSplatting/gaussianSplattingMesh.pure\";\r\nimport { _IsGaussianSplattingMesh } from \"../../Meshes/GaussianSplatting/gaussianSplatting.functions\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { _IblShadowsVoxelRenderer } from \"./iblShadowsVoxelRenderer.pure\";\r\nimport { _IblShadowsVoxelTracingPass } from \"./iblShadowsVoxelTracingPass\";\r\nimport { type WebGPUEngine } from \"../../Engines/webgpuEngine.pure\";\r\nimport { PostProcess, type PostProcessOptions } from \"../../PostProcesses/postProcess.pure\";\r\nimport { _IblShadowsSpatialBlurPass } from \"./iblShadowsSpatialBlurPass\";\r\nimport { _IblShadowsAccumulationPass } from \"./iblShadowsAccumulationPass\";\r\nimport { PostProcessRenderPipeline } from \"../../PostProcesses/RenderPipeline/postProcessRenderPipeline\";\r\nimport { PostProcessRenderEffect } from \"core/PostProcesses/RenderPipeline/postProcessRenderEffect\";\r\nimport { type Camera } from \"core/Cameras/camera.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { GeometryBufferRenderer, type IGeometryBufferTextureTypeAndFormat } from \"core/Rendering/geometryBufferRenderer.pure\";\r\nimport { RegisterGeometryBufferRendererSceneComponent } from \"core/Rendering/geometryBufferRendererSceneComponent.pure\";\r\nimport { IblCdfGenerator } from \"core/Rendering/iblCdfGenerator\";\r\nimport { RegisterIblCdfGeneratorSceneComponent } from \"core/Rendering/iblCdfGeneratorSceneComponent.pure\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { RawTexture3D } from \"core/Materials/Textures/rawTexture3D\";\r\nimport { IBLShadowsPluginMaterial } from \"./iblShadowsPluginMaterial.pure\";\r\nimport { IsIBLShadowsReceiverCompatible } from \"./iblShadowsMaterialCompatibility.pure\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { Observable } from \"core/Misc/observable.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\n\r\ninterface IIblShadowsSettings {\r\n    /**\r\n     * The exponent of the resolution of the voxel shadow grid. Higher resolutions will result in sharper\r\n     * shadows but are more expensive to compute and require more memory.\r\n     * The resolution is calculated as 2 to the power of this number.\r\n     */\r\n    resolutionExp?: number;\r\n\r\n    /**\r\n     * The number of different directions to sample during the voxel tracing pass. Higher\r\n     * values will result in better quality, more stable shadows but are more expensive to compute.\r\n     */\r\n    sampleDirections?: number;\r\n\r\n    /**\r\n     * How dark the shadows are. 1.0 is full opacity, 0.0 is no shadows.\r\n     */\r\n    shadowOpacity?: number;\r\n\r\n    /**\r\n     * The global Y-axis rotation of the IBL for shadows. This should match the Y-rotation of the environment map applied to materials, skybox, etc.\r\n     */\r\n    envRotation?: number;\r\n\r\n    /**\r\n     * A factor that controls how long the shadows remain in the scene.\r\n     * 0.0 is no persistence, 1.0 is full persistence.\r\n     * This value applies only while the camera is moving. Once stationary, the pipeline\r\n     * increases remanence automatically to help the shadows converge.\r\n     */\r\n    shadowRemanence?: number;\r\n\r\n    /**\r\n     * Render the voxel grid from 3 different axis. This will result in better quality shadows with fewer\r\n     * bits of missing geometry.\r\n     */\r\n    triPlanarVoxelization?: boolean;\r\n\r\n    /**\r\n     * A size multiplier for the internal shadow render targets (default 1.0). A value of 1.0 represents full-resolution.\r\n     * Scaling this below 1.0 will result in blurry shadows and potentially more artifacts but\r\n     * could help increase performance on less powerful GPU's.\r\n     */\r\n    shadowRenderSizeFactor?: number;\r\n\r\n    /**\r\n     * Separate control for the opacity of the voxel shadows.\r\n     */\r\n    voxelShadowOpacity?: number;\r\n\r\n    /**\r\n     * Include screen-space shadows in the IBL shadow pipeline. This adds sharp shadows to small details\r\n     * but only applies close to a shadow-casting object.\r\n     */\r\n    ssShadowsEnabled?: boolean;\r\n\r\n    /**\r\n     * The number of samples used in the screen space shadow pass.\r\n     */\r\n    ssShadowSampleCount?: number;\r\n\r\n    /**\r\n     * The stride of the screen-space shadow pass. This controls the distance between samples\r\n     * in pixels.\r\n     */\r\n    ssShadowStride?: number;\r\n\r\n    /**\r\n     * A scale for the maximum distance a screen-space shadow can be cast in world-space.\r\n     * The maximum distance that screen-space shadows cast is derived from the voxel size\r\n     * and this value so shouldn't need to change if you scale your scene.\r\n     */\r\n    ssShadowDistanceScale?: number;\r\n\r\n    /**\r\n     * Screen-space shadow thickness scale. This value controls the assumed thickness of\r\n     * on-screen surfaces in world-space. It scales with the size of the shadow-casting\r\n     * region so shouldn't need to change if you scale your scene.\r\n     */\r\n    ssShadowThicknessScale?: number;\r\n\r\n    /**\r\n     * Maximum number of translucent voxels a shadow ray roulettes through before it is treated as\r\n     * unoccluded (default 16). Higher values converge more accurately through thick translucent volumes\r\n     * (e.g. dense Gaussian splats) at extra cost. Opaque voxels always block on first contact.\r\n     */\r\n    maxVoxelRouletteTests?: number;\r\n}\r\n\r\n/**\r\n * Voxel-based shadow rendering for IBL's.\r\n * This should not be instanciated directly, as it is part of a scene component\r\n */\r\nexport class IblShadowsRenderPipeline extends PostProcessRenderPipeline {\r\n    /**\r\n     * The scene that this pipeline is attached to\r\n     */\r\n    public scene: Scene;\r\n\r\n    private _allowDebugPasses: boolean = false;\r\n    private _debugPasses: { pass: PostProcess; enabled: boolean }[] = [];\r\n\r\n    private _geometryBufferRenderer: GeometryBufferRenderer;\r\n\r\n    private _shadowCastingMeshes: Mesh[] = [];\r\n\r\n    private _voxelRenderer: _IblShadowsVoxelRenderer;\r\n    private _voxelTracingPass: _IblShadowsVoxelTracingPass;\r\n    private _spatialBlurPass: _IblShadowsSpatialBlurPass;\r\n    private _accumulationPass: _IblShadowsAccumulationPass;\r\n    private _noiseTexture: Texture;\r\n    /**\r\n     * Raw texture to be used before final data is available.\r\n     * @internal\r\n     */\r\n    public _dummyTexture2d: RawTexture;\r\n    private _dummyTexture3d: RawTexture3D;\r\n    private _shadowOpacity: number = 0.8;\r\n    private _enabled: boolean = true;\r\n    private _coloredShadows: boolean = false;\r\n    private _materialsWithRenderPlugin: Material[] = [];\r\n\r\n    /**\r\n     * Observable that triggers when the shadow renderer is ready\r\n     */\r\n    public onShadowTextureReadyObservable: Observable<void> = new Observable<void>();\r\n\r\n    /**\r\n     * Observable that triggers when a new IBL is set and the importance sampling is ready\r\n     */\r\n    public onNewIblReadyObservable: Observable<void> = new Observable<void>();\r\n\r\n    /**\r\n     * Observable that triggers when the voxelization is complete\r\n     */\r\n    public onVoxelizationCompleteObservable: Observable<void> = new Observable<void>();\r\n\r\n    /**\r\n     * The current world-space size of that the voxel grid covers in the scene.\r\n     */\r\n    public voxelGridSize: number = 1.0;\r\n\r\n    /**\r\n     * Reset the shadow accumulation. This has a similar affect to lowering the remanence for a single frame.\r\n     * This is useful when making a sudden change to the IBL.\r\n     */\r\n    public resetAccumulation(): void {\r\n        this._accumulationPass.reset = true;\r\n    }\r\n\r\n    /**\r\n     * How dark the shadows appear. 1.0 is full opacity, 0.0 is no shadows.\r\n     */\r\n    public get shadowOpacity(): number {\r\n        return this._shadowOpacity;\r\n    }\r\n\r\n    public set shadowOpacity(value: number) {\r\n        this._shadowOpacity = value;\r\n        this._setPluginParameters();\r\n    }\r\n\r\n    /**\r\n     * Render the shadows in color rather than black and white.\r\n     * This is slightly more expensive than black and white shadows but can be much\r\n     * more accurate when the strongest lights in the IBL are non-white.\r\n     */\r\n    public get coloredShadows(): boolean {\r\n        return this._coloredShadows;\r\n    }\r\n\r\n    public set coloredShadows(value: boolean) {\r\n        this._coloredShadows = value;\r\n        this._voxelTracingPass.coloredShadows = value;\r\n        this._setPluginParameters();\r\n    }\r\n\r\n    private _renderSizeFactor: number = 1.0;\r\n\r\n    /**\r\n     * A multiplier for the render size of the shadows. Used for rendering lower-resolution shadows.\r\n     */\r\n    public get shadowRenderSizeFactor(): number {\r\n        return this._renderSizeFactor;\r\n    }\r\n\r\n    public set shadowRenderSizeFactor(value: number) {\r\n        this._renderSizeFactor = Math.max(Math.min(value, 1.0), 0.0);\r\n        this._voxelTracingPass.resize(value);\r\n        this._spatialBlurPass.resize(value);\r\n        this._accumulationPass.resize(value);\r\n        this._setPluginParameters();\r\n    }\r\n\r\n    /**\r\n     * How dark the voxel shadows appear. 1.0 is full opacity, 0.0 is no shadows.\r\n     */\r\n    public get voxelShadowOpacity() {\r\n        return this._voxelTracingPass?.voxelShadowOpacity;\r\n    }\r\n\r\n    public set voxelShadowOpacity(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.voxelShadowOpacity = value;\r\n    }\r\n\r\n    /**\r\n     * Maximum number of translucent voxels a shadow ray roulettes through before it is treated as\r\n     * unoccluded. Higher values converge more accurately at extra cost. Opaque voxels always block.\r\n     */\r\n    public get maxVoxelRouletteTests(): number {\r\n        return this._voxelTracingPass?.maxVoxelRouletteTests;\r\n    }\r\n\r\n    public set maxVoxelRouletteTests(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.maxVoxelRouletteTests = value;\r\n    }\r\n\r\n    /**\r\n     * How dark the screen-space shadows appear. 1.0 is full opacity, 0.0 is no shadows.\r\n     */\r\n    public get ssShadowOpacity(): number {\r\n        return this._voxelTracingPass?.ssShadowOpacity;\r\n    }\r\n\r\n    public set ssShadowOpacity(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.ssShadowOpacity = value;\r\n    }\r\n\r\n    /**\r\n     * The number of samples used in the screen space shadow pass.\r\n     */\r\n    public get ssShadowSampleCount(): number {\r\n        return this._voxelTracingPass?.sssSamples;\r\n    }\r\n\r\n    public set ssShadowSampleCount(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.sssSamples = value;\r\n    }\r\n\r\n    /**\r\n     * The stride of the screen-space shadow pass. This controls the distance between samples\r\n     * in pixels.\r\n     */\r\n    public get ssShadowStride(): number {\r\n        return this._voxelTracingPass?.sssStride;\r\n    }\r\n\r\n    public set ssShadowStride(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.sssStride = value;\r\n    }\r\n\r\n    private _sssMaxDistScale: number;\r\n\r\n    /**\r\n     * A scale for the maximum distance a screen-space shadow can be cast in world-space.\r\n     * The maximum distance that screen-space shadows cast is derived from the voxel size\r\n     * and this value so shouldn't need to change if you scale your scene\r\n     */\r\n    public get ssShadowDistanceScale(): number {\r\n        return this._sssMaxDistScale;\r\n    }\r\n\r\n    public set ssShadowDistanceScale(value: number) {\r\n        this._sssMaxDistScale = value;\r\n        this._updateSsShadowParams();\r\n    }\r\n\r\n    private _sssThicknessScale: number;\r\n\r\n    /**\r\n     * Screen-space shadow thickness scale. This value controls the assumed thickness of\r\n     * on-screen surfaces in world-space. It scales with the size of the shadow-casting\r\n     * region so shouldn't need to change if you scale your scene.\r\n     */\r\n    public get ssShadowThicknessScale(): number {\r\n        return this._sssThicknessScale;\r\n    }\r\n\r\n    public set ssShadowThicknessScale(value: number) {\r\n        this._sssThicknessScale = value;\r\n        this._updateSsShadowParams();\r\n    }\r\n\r\n    /**\r\n     * Returns the texture containing the voxel grid data\r\n     * @returns The texture containing the voxel grid data\r\n     * @internal\r\n     */\r\n    public _getVoxelGridTexture(): Texture {\r\n        const tex = this._voxelRenderer?.getVoxelGrid();\r\n        if (tex && tex.isReady()) {\r\n            return tex;\r\n        }\r\n        return this._dummyTexture3d;\r\n    }\r\n\r\n    /**\r\n     * Returns the noise texture.\r\n     * @returns The noise texture.\r\n     * @internal\r\n     */\r\n    public _getNoiseTexture(): Texture {\r\n        const tex = this._noiseTexture;\r\n        if (tex && tex.isReady()) {\r\n            return tex;\r\n        }\r\n        return this._dummyTexture2d;\r\n    }\r\n\r\n    /**\r\n     * Returns the voxel-tracing texture.\r\n     * @returns The voxel-tracing texture.\r\n     * @internal\r\n     */\r\n    public _getVoxelTracingTexture(): Texture {\r\n        const tex = this._voxelTracingPass?.getOutputTexture();\r\n        if (tex && tex.isReady()) {\r\n            return tex;\r\n        }\r\n        return this._dummyTexture2d;\r\n    }\r\n\r\n    /**\r\n     * Returns the spatial blur texture.\r\n     * @returns The spatial blur texture.\r\n     * @internal\r\n     */\r\n    public _getSpatialBlurTexture(): Texture {\r\n        const tex = this._spatialBlurPass.getOutputTexture();\r\n        if (tex && tex.isReady()) {\r\n            return tex;\r\n        }\r\n        return this._dummyTexture2d;\r\n    }\r\n\r\n    /**\r\n     * Returns the accumulated shadow texture.\r\n     * @returns The accumulated shadow texture.\r\n     * @internal\r\n     */\r\n    public _getAccumulatedTexture(): Texture {\r\n        const tex = this._accumulationPass?.getOutputTexture();\r\n        if (tex && tex.isReady()) {\r\n            return tex;\r\n        }\r\n        return this._dummyTexture2d;\r\n    }\r\n\r\n    private _gbufferDebugPass: PostProcess;\r\n    private _gbufferDebugEnabled: boolean = false;\r\n    private _gBufferDebugSizeParams: Vector4 = new Vector4(0.0, 0.0, 0.0, 0.0);\r\n\r\n    /**\r\n     * Turn on or off the debug view of the G-Buffer. This will display only the targets\r\n     * of the g-buffer that are used by the shadow pipeline.\r\n     */\r\n    public get gbufferDebugEnabled(): boolean {\r\n        return this._gbufferDebugEnabled;\r\n    }\r\n\r\n    public set gbufferDebugEnabled(enabled: boolean) {\r\n        if (enabled && !this.allowDebugPasses) {\r\n            Logger.Warn(\"Can't enable G-Buffer debug view without setting allowDebugPasses to true.\");\r\n            return;\r\n        }\r\n        this._gbufferDebugEnabled = enabled;\r\n        if (enabled) {\r\n            this._enableEffect(this._getGBufferDebugPass().name, this.cameras);\r\n        } else {\r\n            this._disableEffect(this._getGBufferDebugPass().name, this.cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Turn on or off the debug view of the CDF importance sampling data\r\n     */\r\n    public get cdfDebugEnabled(): boolean {\r\n        return this.scene.iblCdfGenerator ? this.scene.iblCdfGenerator.debugEnabled : false;\r\n    }\r\n\r\n    /**\r\n     * Turn on or off the debug view of the CDF importance sampling data\r\n     */\r\n    public set cdfDebugEnabled(enabled: boolean) {\r\n        if (!this.scene.iblCdfGenerator) {\r\n            return;\r\n        }\r\n        if (enabled && !this.allowDebugPasses) {\r\n            Logger.Warn(\"Can't enable importance sampling debug view without setting allowDebugPasses to true.\");\r\n            return;\r\n        }\r\n        if (enabled === this.scene.iblCdfGenerator.debugEnabled) {\r\n            return;\r\n        }\r\n        this.scene.iblCdfGenerator.debugEnabled = enabled;\r\n        if (enabled) {\r\n            this._enableEffect(this.scene.iblCdfGenerator.debugPassName, this.cameras);\r\n        } else {\r\n            this._disableEffect(this.scene.iblCdfGenerator.debugPassName, this.cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Display the debug view for just the shadow samples taken this frame.\r\n     */\r\n    public get voxelTracingDebugEnabled(): boolean {\r\n        return this._voxelTracingPass?.debugEnabled;\r\n    }\r\n\r\n    public set voxelTracingDebugEnabled(enabled: boolean) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        if (enabled && !this.allowDebugPasses) {\r\n            Logger.Warn(\"Can't enable voxel tracing debug view without setting allowDebugPasses to true.\");\r\n            return;\r\n        }\r\n        if (enabled === this._voxelTracingPass.debugEnabled) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.debugEnabled = enabled;\r\n        if (enabled) {\r\n            this._enableEffect(this._voxelTracingPass.debugPassName, this.cameras);\r\n        } else {\r\n            this._disableEffect(this._voxelTracingPass.debugPassName, this.cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Display the debug view for the spatial blur pass\r\n     */\r\n    public get spatialBlurPassDebugEnabled(): boolean {\r\n        return this._spatialBlurPass.debugEnabled;\r\n    }\r\n\r\n    public set spatialBlurPassDebugEnabled(enabled: boolean) {\r\n        if (!this._spatialBlurPass) {\r\n            return;\r\n        }\r\n        if (enabled && !this.allowDebugPasses) {\r\n            Logger.Warn(\"Can't enable spatial blur debug view without setting allowDebugPasses to true.\");\r\n            return;\r\n        }\r\n        if (enabled === this._spatialBlurPass.debugEnabled) {\r\n            return;\r\n        }\r\n        this._spatialBlurPass.debugEnabled = enabled;\r\n        if (enabled) {\r\n            this._enableEffect(this._spatialBlurPass.debugPassName, this.cameras);\r\n        } else {\r\n            this._disableEffect(this._spatialBlurPass.debugPassName, this.cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Display the debug view for the shadows accumulated over time.\r\n     */\r\n    public get accumulationPassDebugEnabled(): boolean {\r\n        return this._accumulationPass?.debugEnabled;\r\n    }\r\n\r\n    public set accumulationPassDebugEnabled(enabled: boolean) {\r\n        if (!this._accumulationPass) {\r\n            return;\r\n        }\r\n        if (enabled && !this.allowDebugPasses) {\r\n            Logger.Warn(\"Can't enable accumulation pass debug view without setting allowDebugPasses to true.\");\r\n            return;\r\n        }\r\n        if (enabled === this._accumulationPass.debugEnabled) {\r\n            return;\r\n        }\r\n        this._accumulationPass.debugEnabled = enabled;\r\n        if (enabled) {\r\n            this._enableEffect(this._accumulationPass.debugPassName, this.cameras);\r\n        } else {\r\n            this._disableEffect(this._accumulationPass.debugPassName, this.cameras);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add a mesh to be used for shadow-casting in the IBL shadow pipeline.\r\n     * These meshes will be written to the voxel grid.\r\n     * @param mesh A mesh or list of meshes that you want to cast shadows\r\n     */\r\n    public addShadowCastingMesh(mesh: Mesh | Mesh[]): void {\r\n        if (Array.isArray(mesh)) {\r\n            for (const m of mesh) {\r\n                if (m && this._shadowCastingMeshes.indexOf(m) === -1) {\r\n                    this._shadowCastingMeshes.push(m);\r\n                    if (_IsGaussianSplattingMesh(m)) {\r\n                        (m as GaussianSplattingMesh).needsRotationScaleTextures = true;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            if (mesh && this._shadowCastingMeshes.indexOf(mesh) === -1) {\r\n                this._shadowCastingMeshes.push(mesh);\r\n                if (_IsGaussianSplattingMesh(mesh)) {\r\n                    (mesh as GaussianSplattingMesh).needsRotationScaleTextures = true;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a mesh from the shadow-casting list. The mesh will no longer be written\r\n     * to the voxel grid and will not cast shadows.\r\n     * @param mesh The mesh or list of meshes that you don't want to cast shadows.\r\n     */\r\n    public removeShadowCastingMesh(mesh: Mesh | Mesh[]): void {\r\n        if (Array.isArray(mesh)) {\r\n            for (const m of mesh) {\r\n                const index = this._shadowCastingMeshes.indexOf(m);\r\n                if (index !== -1) {\r\n                    this._shadowCastingMeshes.splice(index, 1);\r\n                    if (_IsGaussianSplattingMesh(m)) {\r\n                        (m as GaussianSplattingMesh).needsRotationScaleTextures = false;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            const index = this._shadowCastingMeshes.indexOf(mesh);\r\n            if (index !== -1) {\r\n                this._shadowCastingMeshes.splice(index, 1);\r\n                if (_IsGaussianSplattingMesh(mesh)) {\r\n                    (mesh as GaussianSplattingMesh).needsRotationScaleTextures = false;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the list of shadow-casting meshes. This will remove all meshes from the list\r\n     */\r\n    public clearShadowCastingMeshes(): void {\r\n        for (const m of this._shadowCastingMeshes) {\r\n            if (_IsGaussianSplattingMesh(m)) {\r\n                (m as GaussianSplattingMesh).needsRotationScaleTextures = false;\r\n            }\r\n        }\r\n        this._shadowCastingMeshes.length = 0;\r\n    }\r\n\r\n    /**\r\n     * The exponent of the resolution of the voxel shadow grid. Higher resolutions will result in sharper\r\n     * shadows but are more expensive to compute and require more memory.\r\n     * The resolution is calculated as 2 to the power of this number.\r\n     */\r\n    public get resolutionExp() {\r\n        return this._voxelRenderer.voxelResolutionExp;\r\n    }\r\n\r\n    public set resolutionExp(newResolution: number) {\r\n        if (newResolution === this._voxelRenderer.voxelResolutionExp) {\r\n            return;\r\n        }\r\n        if (this._voxelRenderer.isVoxelizationInProgress()) {\r\n            Logger.Warn(\"Can't change the resolution of the voxel grid while voxelization is in progress.\");\r\n            return;\r\n        }\r\n        this._voxelRenderer.voxelResolutionExp = Math.max(1, Math.min(newResolution, 8));\r\n        this._accumulationPass.reset = true;\r\n    }\r\n\r\n    /**\r\n     * The number of different directions to sample during the voxel tracing pass\r\n     */\r\n    public get sampleDirections() {\r\n        return this._voxelTracingPass?.sampleDirections;\r\n    }\r\n\r\n    /**\r\n     * The number of different directions to sample during the voxel tracing pass\r\n     */\r\n    public set sampleDirections(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.sampleDirections = value;\r\n    }\r\n\r\n    /**\r\n     * The decree to which the shadows persist between frames. 0.0 is no persistence, 1.0 is full persistence.\r\n     **/\r\n    public get shadowRemanence(): number {\r\n        return this._accumulationPass?.remanence;\r\n    }\r\n\r\n    /**\r\n     * The decree to which the shadows persist between frames. 0.0 is no persistence, 1.0 is full persistence.\r\n     **/\r\n    public set shadowRemanence(value: number) {\r\n        if (!this._accumulationPass) {\r\n            return;\r\n        }\r\n        this._accumulationPass.remanence = value;\r\n    }\r\n\r\n    /**\r\n     * The global Y-axis rotation of the IBL for shadows. This should match the Y-rotation of the environment map applied to materials, skybox, etc.\r\n     */\r\n    public get envRotation() {\r\n        return this._voxelTracingPass?.envRotation;\r\n    }\r\n\r\n    /**\r\n     * The global Y-axis rotation of the IBL for shadows. This should match the Y-rotation of the environment map applied to materials, skybox, etc.\r\n     */\r\n    public set envRotation(value: number) {\r\n        if (!this._voxelTracingPass) {\r\n            return;\r\n        }\r\n        this._voxelTracingPass.envRotation = value;\r\n        this._accumulationPass.reset = true;\r\n    }\r\n\r\n    /**\r\n     * Allow debug passes to be enabled. Default is false.\r\n     */\r\n    public get allowDebugPasses(): boolean {\r\n        return this._allowDebugPasses;\r\n    }\r\n\r\n    /**\r\n     * Allow debug passes to be enabled. Default is false.\r\n     */\r\n    public set allowDebugPasses(value: boolean) {\r\n        if (this._allowDebugPasses === value) {\r\n            return;\r\n        }\r\n        this._allowDebugPasses = value;\r\n        if (value && this.scene.iblCdfGenerator) {\r\n            if (this.scene.iblCdfGenerator.isReady()) {\r\n                this._createDebugPasses();\r\n            } else {\r\n                this.scene.iblCdfGenerator.onGeneratedObservable.addOnce(() => {\r\n                    this._createDebugPasses();\r\n                });\r\n            }\r\n        } else {\r\n            this._disposeDebugPasses();\r\n        }\r\n    }\r\n\r\n    /**\r\n     *  Support test.\r\n     */\r\n    public static get IsSupported(): boolean {\r\n        const engine = EngineStore.LastCreatedEngine;\r\n        if (!engine) {\r\n            return false;\r\n        }\r\n        return engine._features.supportIBLShadows;\r\n    }\r\n\r\n    /**\r\n     * Toggle the shadow tracing on or off\r\n     * @param enabled Toggle the shadow tracing on or off\r\n     */\r\n    public toggleShadow(enabled: boolean) {\r\n        this._enabled = enabled;\r\n        this._voxelTracingPass.enabled = enabled;\r\n        this._spatialBlurPass.enabled = enabled;\r\n        this._accumulationPass.enabled = enabled;\r\n        for (const mat of this._materialsWithRenderPlugin) {\r\n            if (mat.pluginManager) {\r\n                const plugin = mat.pluginManager.getPlugin(IBLShadowsPluginMaterial.Name) as IBLShadowsPluginMaterial;\r\n                plugin.isEnabled = enabled;\r\n            }\r\n        }\r\n        this._setPluginParameters();\r\n    }\r\n\r\n    /**\r\n     * Trigger the scene to be re-voxelized. This should be run when any shadow-casters have been added, removed or moved.\r\n     */\r\n    public updateVoxelization() {\r\n        if (this._shadowCastingMeshes.length === 0) {\r\n            Logger.Warn(\"IBL Shadows: updateVoxelization called with no shadow-casting meshes to voxelize.\");\r\n            return;\r\n        }\r\n        this._voxelRenderer.updateVoxelGrid(this._shadowCastingMeshes);\r\n        this._voxelRenderer.onVoxelizationCompleteObservable.addOnce(() => {\r\n            this.onVoxelizationCompleteObservable.notifyObservers();\r\n        });\r\n        this._updateSsShadowParams();\r\n    }\r\n\r\n    /**\r\n     * Trigger the scene bounds of shadow-casters to be calculated. This is the world size that the voxel grid will cover and will always be a cube.\r\n     */\r\n    public updateSceneBounds() {\r\n        const bounds: { min: Vector3; max: Vector3 } = {\r\n            min: new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE),\r\n            max: new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE),\r\n        };\r\n        for (const mesh of this._shadowCastingMeshes) {\r\n            const localBounds = mesh.getHierarchyBoundingVectors(true);\r\n            bounds.min = Vector3.Minimize(bounds.min, localBounds.min);\r\n            bounds.max = Vector3.Maximize(bounds.max, localBounds.max);\r\n        }\r\n\r\n        if (this._shadowCastingMeshes.length === 0) {\r\n            Logger.Warn(\"IBL Shadows: updateSceneBounds called with no shadow-casting meshes.\");\r\n            this.voxelGridSize = 1.0;\r\n            return;\r\n        }\r\n        // If no visible geometry contributed, bounds stay at sentinel values. Keep the\r\n        // last valid invWorldScale and return silently — this is expected when all parts\r\n        // are temporarily hidden (e.g. while switching between displayed models).\r\n        if (bounds.min.x > bounds.max.x) {\r\n            return;\r\n        }\r\n        const size = bounds.max.subtract(bounds.min);\r\n        this.voxelGridSize = Math.max(size.x, size.y, size.z);\r\n        if (!isFinite(this.voxelGridSize) || this.voxelGridSize === 0) {\r\n            Logger.Warn(\"IBL Shadows: Scene size is invalid. Can't update bounds.\");\r\n            this.voxelGridSize = 1.0;\r\n            return;\r\n        }\r\n        const halfSize = this.voxelGridSize / 2.0;\r\n        const centre = bounds.max.add(bounds.min).multiplyByFloats(-0.5, -0.5, -0.5);\r\n        const invWorldScaleMatrix = Matrix.Compose(new Vector3(1.0 / halfSize, 1.0 / halfSize, 1.0 / halfSize), new Quaternion(), new Vector3(0, 0, 0));\r\n        const invTranslationMatrix = Matrix.Compose(new Vector3(1.0, 1.0, 1.0), new Quaternion(), centre);\r\n        invTranslationMatrix.multiplyToRef(invWorldScaleMatrix, invWorldScaleMatrix);\r\n        this._voxelTracingPass.setWorldScaleMatrix(invWorldScaleMatrix);\r\n        this._voxelRenderer.setWorldScaleMatrix(invWorldScaleMatrix);\r\n        // Set world scale for spatial blur.\r\n        this._spatialBlurPass.setWorldScale(halfSize * 2.0);\r\n        this._updateSsShadowParams();\r\n    }\r\n\r\n    /**\r\n     * @param name The rendering pipeline name\r\n     * @param scene The scene linked to this pipeline\r\n     * @param options Options to configure the pipeline\r\n     * @param cameras Cameras to apply the pipeline to.\r\n     */\r\n    constructor(name: string, scene: Scene, options: Partial<IIblShadowsSettings> = {}, cameras?: Camera[]) {\r\n        super(scene.getEngine(), name);\r\n        this.scene = scene;\r\n        RegisterGeometryBufferRendererSceneComponent(GeometryBufferRenderer);\r\n        RegisterIblCdfGeneratorSceneComponent(IblCdfGenerator);\r\n        this._cameras = cameras || [scene.activeCamera!];\r\n        // Create the dummy textures to be used when the pipeline is not ready\r\n        const blackPixels = new Uint8Array([0, 0, 0, 255]);\r\n        this._dummyTexture2d = new RawTexture(blackPixels, 1, 1, Constants.TEXTUREFORMAT_RGBA, scene, false);\r\n        this._dummyTexture3d = new RawTexture3D(blackPixels, 1, 1, 1, Constants.TEXTUREFORMAT_RGBA, scene, false);\r\n\r\n        // Setup the geometry buffer target formats\r\n        const textureTypesAndFormats: { [key: number]: IGeometryBufferTextureTypeAndFormat } = {};\r\n        textureTypesAndFormats[GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE] = {\r\n            textureFormat: Constants.TEXTUREFORMAT_R,\r\n            textureType: Constants.TEXTURETYPE_FLOAT,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n        };\r\n        textureTypesAndFormats[GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE] = {\r\n            textureFormat: Constants.TEXTUREFORMAT_RG,\r\n            textureType: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n        };\r\n        textureTypesAndFormats[GeometryBufferRenderer.POSITION_TEXTURE_TYPE] = {\r\n            textureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            textureType: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n        };\r\n        textureTypesAndFormats[GeometryBufferRenderer.NORMAL_TEXTURE_TYPE] = {\r\n            textureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            textureType: Constants.TEXTURETYPE_HALF_FLOAT,\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n        };\r\n        const geometryBufferRenderer = scene.enableGeometryBufferRenderer(undefined, Constants.TEXTUREFORMAT_DEPTH32_FLOAT, textureTypesAndFormats);\r\n        if (!geometryBufferRenderer) {\r\n            Logger.Error(\"Geometry buffer renderer is required for IBL shadows to work.\");\r\n            return;\r\n        }\r\n        this._geometryBufferRenderer = geometryBufferRenderer;\r\n        this._geometryBufferRenderer.enableScreenspaceDepth = true;\r\n        this._geometryBufferRenderer.enableVelocityLinear = true;\r\n        this._geometryBufferRenderer.enablePosition = true;\r\n        this._geometryBufferRenderer.enableNormal = true;\r\n        this._geometryBufferRenderer.generateNormalsInWorldSpace = true;\r\n        this.scene.enableIblCdfGenerator();\r\n        this.shadowOpacity = options.shadowOpacity ?? 0.8;\r\n        this._voxelRenderer = new _IblShadowsVoxelRenderer(\r\n            this.scene,\r\n            this,\r\n            options ? options.resolutionExp : 6,\r\n            options.triPlanarVoxelization !== undefined ? options.triPlanarVoxelization : true\r\n        );\r\n        this._voxelTracingPass = new _IblShadowsVoxelTracingPass(this.scene, this);\r\n        this._spatialBlurPass = new _IblShadowsSpatialBlurPass(this.scene, this);\r\n        this._accumulationPass = new _IblShadowsAccumulationPass(this.scene, this);\r\n        this._accumulationPass.onReadyObservable.addOnce(() => {\r\n            this.onShadowTextureReadyObservable.notifyObservers();\r\n        });\r\n        this.sampleDirections = options.sampleDirections || 2;\r\n        this.voxelShadowOpacity = options.voxelShadowOpacity ?? 1.0;\r\n        this.envRotation = options.envRotation ?? 0.0;\r\n        this.shadowRenderSizeFactor = options.shadowRenderSizeFactor || 1.0;\r\n        this.ssShadowOpacity = options.ssShadowsEnabled === undefined || options.ssShadowsEnabled ? 1.0 : 0.0;\r\n        this.ssShadowDistanceScale = options.ssShadowDistanceScale || 1.25;\r\n        this.ssShadowSampleCount = options.ssShadowSampleCount || 16;\r\n        this.ssShadowStride = options.ssShadowStride || 8;\r\n        this.ssShadowThicknessScale = options.ssShadowThicknessScale || 1.0;\r\n        this.shadowRemanence = options.shadowRemanence ?? 0.75;\r\n        this.maxVoxelRouletteTests = options.maxVoxelRouletteTests ?? 16;\r\n        this._noiseTexture = new Texture(\r\n            Tools.GetAssetUrl(\"https://assets.babylonjs.com/core/blue_noise/blue_noise_rgb.png\"),\r\n            this.scene,\r\n            false,\r\n            true,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE\r\n        );\r\n\r\n        scene.postProcessRenderPipelineManager.addPipeline(this);\r\n\r\n        this.scene.onActiveCameraChanged.add(this._listenForCameraChanges.bind(this));\r\n        this.scene.onBeforeRenderObservable.add(this._updateBeforeRender.bind(this));\r\n\r\n        this._listenForCameraChanges();\r\n        this.scene.getEngine().onResizeObservable.add(this._handleResize.bind(this));\r\n\r\n        // Assigning the shadow texture to the materials needs to be done after the RT's are created.\r\n        if (this.scene.iblCdfGenerator) {\r\n            this.scene.iblCdfGenerator.onGeneratedObservable.add(() => {\r\n                this._setPluginParameters();\r\n                this.onNewIblReadyObservable.notifyObservers();\r\n            });\r\n        }\r\n    }\r\n\r\n    private _handleResize() {\r\n        this._voxelRenderer.resize();\r\n        this._voxelTracingPass.resize(this.shadowRenderSizeFactor);\r\n        this._spatialBlurPass.resize(this.shadowRenderSizeFactor);\r\n        this._accumulationPass.resize(this.shadowRenderSizeFactor);\r\n        this._setPluginParameters();\r\n    }\r\n\r\n    private _getGBufferDebugPass(): PostProcess {\r\n        if (this._gbufferDebugPass) {\r\n            return this._gbufferDebugPass;\r\n        }\r\n        const isWebGPU = this.engine.isWebGPU;\r\n        const textureNames: string[] = [\"depthSampler\", \"normalSampler\", \"positionSampler\", \"velocitySampler\"];\r\n\r\n        const options: PostProcessOptions = {\r\n            width: this.scene.getEngine().getRenderWidth(),\r\n            height: this.scene.getEngine().getRenderHeight(),\r\n            samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            engine: this.scene.getEngine(),\r\n            textureType: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            textureFormat: Constants.TEXTUREFORMAT_RGBA,\r\n            uniforms: [\"sizeParams\"],\r\n            samplers: textureNames,\r\n            reusable: false,\r\n            shaderLanguage: isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n            extraInitializations: (useWebGPU: boolean, list: Promise<any>[]) => {\r\n                if (useWebGPU) {\r\n                    list.push(import(\"../../ShadersWGSL/iblShadowGBufferDebug.fragment\"));\r\n                } else {\r\n                    list.push(import(\"../../Shaders/iblShadowGBufferDebug.fragment\"));\r\n                }\r\n            },\r\n        };\r\n        this._gbufferDebugPass = new PostProcess(\"iblShadowGBufferDebug\", \"iblShadowGBufferDebug\", options);\r\n        if (this.engine.isWebGPU) {\r\n            this._gbufferDebugPass.samples = (this.engine as WebGPUEngine).currentSampleCount ?? 1;\r\n        }\r\n        this._gbufferDebugPass.autoClear = false;\r\n        this._gbufferDebugPass.onApplyObservable.add((effect) => {\r\n            const depthIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.SCREENSPACE_DEPTH_TEXTURE_TYPE);\r\n            effect.setTexture(\"depthSampler\", this._geometryBufferRenderer.getGBuffer().textures[depthIndex]);\r\n            const normalIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE);\r\n            effect.setTexture(\"normalSampler\", this._geometryBufferRenderer.getGBuffer().textures[normalIndex]);\r\n            const positionIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.POSITION_TEXTURE_TYPE);\r\n            effect.setTexture(\"positionSampler\", this._geometryBufferRenderer.getGBuffer().textures[positionIndex]);\r\n            const velocityIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_LINEAR_TEXTURE_TYPE);\r\n            effect.setTexture(\"velocitySampler\", this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);\r\n            effect.setVector4(\"sizeParams\", this._gBufferDebugSizeParams);\r\n            if (this.scene.activeCamera) {\r\n                effect.setFloat(\"maxDepth\", this.scene.activeCamera.maxZ);\r\n            }\r\n        });\r\n        return this._gbufferDebugPass;\r\n    }\r\n\r\n    private _createDebugPasses() {\r\n        if (this.scene.iblCdfGenerator) {\r\n            this._debugPasses = [{ pass: this.scene.iblCdfGenerator.getDebugPassPP(), enabled: this.cdfDebugEnabled }];\r\n        } else {\r\n            this._debugPasses = [];\r\n        }\r\n\r\n        this._debugPasses.push(\r\n            { pass: this._voxelTracingPass.getDebugPassPP(), enabled: this.voxelTracingDebugEnabled },\r\n            { pass: this._spatialBlurPass.getDebugPassPP(), enabled: this.spatialBlurPassDebugEnabled },\r\n            { pass: this._accumulationPass.getDebugPassPP(), enabled: this.accumulationPassDebugEnabled },\r\n            { pass: this._getGBufferDebugPass(), enabled: this.gbufferDebugEnabled }\r\n        );\r\n        for (let i = 0; i < this._debugPasses.length; i++) {\r\n            if (!this._debugPasses[i].pass) {\r\n                continue;\r\n            }\r\n            this.addEffect(\r\n                new PostProcessRenderEffect(\r\n                    this.scene.getEngine(),\r\n                    this._debugPasses[i].pass.name,\r\n                    () => {\r\n                        return this._debugPasses[i].pass;\r\n                    },\r\n                    true\r\n                )\r\n            );\r\n        }\r\n        const cameras = this.cameras.slice();\r\n        this.scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this.name, this.cameras);\r\n        this.scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this.name, cameras);\r\n        for (let i = 0; i < this._debugPasses.length; i++) {\r\n            if (!this._debugPasses[i].pass) {\r\n                continue;\r\n            }\r\n            if (this._debugPasses[i].enabled) {\r\n                this._enableEffect(this._debugPasses[i].pass.name, this.cameras);\r\n            } else {\r\n                this._disableEffect(this._debugPasses[i].pass.name, this.cameras);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _disposeEffectPasses() {\r\n        this.scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this.name, this.cameras);\r\n        this._disposeDebugPasses();\r\n        this._reset();\r\n    }\r\n\r\n    private _disposeDebugPasses() {\r\n        for (let i = 0; i < this._debugPasses.length; i++) {\r\n            this._disableEffect(this._debugPasses[i].pass.name, this.cameras);\r\n            this._debugPasses[i].pass.dispose();\r\n        }\r\n        this._debugPasses = [];\r\n    }\r\n\r\n    private _updateDebugPasses() {\r\n        let count = 0;\r\n        if (this._gbufferDebugEnabled) {\r\n            count++;\r\n        }\r\n        if (this.cdfDebugEnabled) {\r\n            count++;\r\n        }\r\n        if (this.voxelTracingDebugEnabled) {\r\n            count++;\r\n        }\r\n        if (this.spatialBlurPassDebugEnabled) {\r\n            count++;\r\n        }\r\n        if (this.accumulationPassDebugEnabled) {\r\n            count++;\r\n        }\r\n\r\n        const rows = Math.ceil(Math.sqrt(count));\r\n        const cols = Math.ceil(count / rows);\r\n        const width = 1.0 / cols;\r\n        const height = 1.0 / rows;\r\n        let x: number = 0;\r\n        let y: number = 0;\r\n        if (this.gbufferDebugEnabled) {\r\n            this._gBufferDebugSizeParams.set(x, y, cols, rows);\r\n            x -= width;\r\n            if (x <= -1) {\r\n                x = 0;\r\n                y -= height;\r\n            }\r\n        }\r\n\r\n        if (this.cdfDebugEnabled && this.scene.iblCdfGenerator) {\r\n            this.scene.iblCdfGenerator.setDebugDisplayParams(x, y, cols, rows);\r\n            x -= width;\r\n            if (x <= -1) {\r\n                x = 0;\r\n                y -= height;\r\n            }\r\n        }\r\n        if (this.voxelTracingDebugEnabled) {\r\n            this._voxelTracingPass.setDebugDisplayParams(x, y, cols, rows);\r\n            x -= width;\r\n            if (x <= -1) {\r\n                x = 0;\r\n                y -= height;\r\n            }\r\n        }\r\n        if (this.spatialBlurPassDebugEnabled) {\r\n            this._spatialBlurPass.setDebugDisplayParams(x, y, cols, rows);\r\n            x -= width;\r\n            if (x <= -1) {\r\n                x = 0;\r\n                y -= height;\r\n            }\r\n        }\r\n        if (this.accumulationPassDebugEnabled) {\r\n            this._accumulationPass.setDebugDisplayParams(x, y, cols, rows);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Update the SS shadow max distance and thickness based on the voxel grid size and resolution.\r\n     * The max distance should be just a little larger than the world size of a single voxel.\r\n     */\r\n    private _updateSsShadowParams(): void {\r\n        this._voxelTracingPass.sssMaxDist = (this._sssMaxDistScale * this.voxelGridSize) / (1 << this.resolutionExp);\r\n        this._voxelTracingPass.sssThickness = this._sssThicknessScale * 0.005 * this.voxelGridSize;\r\n    }\r\n\r\n    /**\r\n     * Apply the shadows to a material or array of materials. If no material is provided, all\r\n     * materials in the scene will be added.\r\n     * @param material Material that will be affected by the shadows. If not provided, all materials of the scene will be affected.\r\n     */\r\n    public addShadowReceivingMaterial(material?: Material | Material[]) {\r\n        if (material) {\r\n            if (Array.isArray(material)) {\r\n                for (const m of material) {\r\n                    this._addShadowSupportToMaterial(m);\r\n                }\r\n            } else {\r\n                this._addShadowSupportToMaterial(material);\r\n            }\r\n        } else {\r\n            for (const mat of this.scene.materials) {\r\n                this._addShadowSupportToMaterial(mat);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a material from the list of materials that receive shadows. If no material\r\n     * is provided, all materials in the scene will be removed.\r\n     * @param material The material or array of materials that will no longer receive shadows\r\n     */\r\n    public removeShadowReceivingMaterial(material: Material | Material[]) {\r\n        if (Array.isArray(material)) {\r\n            for (const m of material) {\r\n                const matIndex = this._materialsWithRenderPlugin.indexOf(m);\r\n                if (matIndex !== -1) {\r\n                    this._materialsWithRenderPlugin.splice(matIndex, 1);\r\n                    const plugin = m.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name)!;\r\n                    plugin.isEnabled = false;\r\n                }\r\n            }\r\n        } else {\r\n            const matIndex = this._materialsWithRenderPlugin.indexOf(material);\r\n            if (matIndex !== -1) {\r\n                this._materialsWithRenderPlugin.splice(matIndex, 1);\r\n                const plugin = material.pluginManager!.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name)!;\r\n                plugin.isEnabled = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Clear the list of materials that receive shadows. This will remove all materials from the list\r\n     */\r\n    public clearShadowReceivingMaterials() {\r\n        for (const mat of this._materialsWithRenderPlugin) {\r\n            const plugin = mat.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name);\r\n            if (plugin) {\r\n                plugin.isEnabled = false;\r\n            }\r\n        }\r\n        this._materialsWithRenderPlugin.length = 0;\r\n    }\r\n\r\n    protected _addShadowSupportToMaterial(material: Material) {\r\n        if (!IsIBLShadowsReceiverCompatible(material)) {\r\n            return;\r\n        }\r\n        let plugin = material.pluginManager?.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name);\r\n        if (!plugin) {\r\n            plugin = new IBLShadowsPluginMaterial(material);\r\n        }\r\n        if (this._materialsWithRenderPlugin.indexOf(material) !== -1) {\r\n            return;\r\n        }\r\n\r\n        if (this._enabled) {\r\n            plugin.iblShadowsTexture = this._getAccumulatedTexture().getInternalTexture()!;\r\n            plugin.shadowOpacity = this.shadowOpacity;\r\n        }\r\n\r\n        plugin.isEnabled = this._enabled;\r\n        plugin.isColored = this._coloredShadows;\r\n\r\n        this._materialsWithRenderPlugin.push(material);\r\n    }\r\n\r\n    protected _setPluginParameters() {\r\n        if (!this._enabled) {\r\n            return;\r\n        }\r\n\r\n        for (const mat of this._materialsWithRenderPlugin) {\r\n            if (mat.pluginManager) {\r\n                const plugin = mat.pluginManager.getPlugin<IBLShadowsPluginMaterial>(IBLShadowsPluginMaterial.Name)!;\r\n                plugin.iblShadowsTexture = this._getAccumulatedTexture().getInternalTexture()!;\r\n                plugin.shadowOpacity = this.shadowOpacity;\r\n                plugin.isColored = this._coloredShadows;\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateBeforeRender() {\r\n        this._updateDebugPasses();\r\n    }\r\n\r\n    private _listenForCameraChanges() {\r\n        // We want to listen for camera changes and change settings while the camera is moving.\r\n        this.scene.activeCamera?.onViewMatrixChangedObservable.add(() => {\r\n            this._accumulationPass.isMoving = true;\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Checks if the IBL shadow pipeline is ready to render shadows\r\n     * @returns true if the IBL shadow pipeline is ready to render the shadows\r\n     */\r\n    public isReady() {\r\n        return (\r\n            this._noiseTexture.isReady() &&\r\n            this._voxelRenderer.isReady() &&\r\n            this.scene.iblCdfGenerator &&\r\n            this.scene.iblCdfGenerator.isReady() &&\r\n            (!this._voxelTracingPass || this._voxelTracingPass.isReady()) &&\r\n            (!this._spatialBlurPass || this._spatialBlurPass.isReady()) &&\r\n            (!this._accumulationPass || this._accumulationPass.isReady())\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Get the class name\r\n     * @returns \"IBLShadowsRenderPipeline\"\r\n     */\r\n    public override getClassName(): string {\r\n        return \"IBLShadowsRenderPipeline\";\r\n    }\r\n\r\n    /**\r\n     * Disposes the IBL shadow pipeline and associated resources\r\n     */\r\n    public override dispose() {\r\n        const materials = this._materialsWithRenderPlugin.splice(0);\r\n        for (const mat of materials) {\r\n            this.removeShadowReceivingMaterial(mat);\r\n        }\r\n        this._disposeEffectPasses();\r\n        this._noiseTexture.dispose();\r\n        this._voxelRenderer.dispose();\r\n        this._voxelTracingPass.dispose();\r\n        this._spatialBlurPass.dispose();\r\n        this._accumulationPass.dispose();\r\n        this._dummyTexture2d.dispose();\r\n        this._dummyTexture3d.dispose();\r\n        this.onNewIblReadyObservable.clear();\r\n        this.onShadowTextureReadyObservable.clear();\r\n        this.onVoxelizationCompleteObservable.clear();\r\n        super.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"../scene.pure\";\r\nimport { SceneComponentConstants, type ISceneSerializableComponent } from \"../sceneComponent\";\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { Color3 } from \"../Maths/math.color.pure\";\r\nimport { AddParser } from \"core/Loading/Plugins/babylonFileParser.function\";\r\nimport { type SubSurfaceConfiguration } from \"./subSurfaceConfiguration\";\r\n\r\n/**\r\n * Defines the Geometry Buffer scene component responsible to manage a G-Buffer useful\r\n * in several rendering techniques.\r\n */\r\nexport class SubSurfaceSceneComponent implements ISceneSerializableComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_SUBSURFACE;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {}\r\n\r\n    /**\r\n     * Serializes the component data to the specified json object\r\n     * @param serializationObject The object to serialize to\r\n     */\r\n    public serialize(serializationObject: any): void {\r\n        if (!this.scene.subSurfaceConfiguration) {\r\n            return;\r\n        }\r\n\r\n        const ssDiffusionProfileColors = this.scene.subSurfaceConfiguration.ssDiffusionProfileColors;\r\n        serializationObject.ssDiffusionProfileColors = [];\r\n\r\n        for (let i = 0; i < ssDiffusionProfileColors.length; i++) {\r\n            serializationObject.ssDiffusionProfileColors.push({\r\n                r: ssDiffusionProfileColors[i].r,\r\n                g: ssDiffusionProfileColors[i].g,\r\n                b: ssDiffusionProfileColors[i].b,\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds all the elements from the container to the scene\r\n     */\r\n    public addFromContainer(): void {\r\n        // Nothing to do\r\n    }\r\n\r\n    /**\r\n     * Removes all the elements in the container from the scene\r\n     */\r\n    public removeFromContainer(): void {\r\n        // Make sure nothing will be serialized\r\n        if (!this.scene.prePassRenderer) {\r\n            return;\r\n        }\r\n\r\n        if (this.scene.subSurfaceConfiguration) {\r\n            this.scene.subSurfaceConfiguration.clearAllDiffusionProfiles();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do for this component\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        // Nothing to do for this component\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for subSurfaceSceneComponent.\r\n * Safe to call multiple times; only the first call has an effect.\r\n * @param subSurfaceConfigClass The SubSurfaceConfiguration class to register the component for\r\n */\r\nexport function RegisterSubSurfaceSceneComponent(subSurfaceConfigClass: typeof SubSurfaceConfiguration): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // Adds the parser to the scene parsers.\r\n    AddParser(SceneComponentConstants.NAME_SUBSURFACE, (parsedData: any, scene: Scene) => {\r\n        // Diffusion profiles\r\n        if (parsedData.ssDiffusionProfileColors !== undefined && parsedData.ssDiffusionProfileColors !== null) {\r\n            scene.enableSubSurfaceForPrePass();\r\n            if (scene.subSurfaceConfiguration) {\r\n                for (let index = 0, cache = parsedData.ssDiffusionProfileColors.length; index < cache; index++) {\r\n                    const color = parsedData.ssDiffusionProfileColors[index];\r\n                    scene.subSurfaceConfiguration.addDiffusionProfile(new Color3(color.r, color.g, color.b));\r\n                }\r\n            }\r\n        }\r\n    });\r\n\r\n    Object.defineProperty(Scene.prototype, \"subSurfaceConfiguration\", {\r\n        get: function (this: Scene) {\r\n            return this._subSurfaceConfiguration;\r\n        },\r\n        set: function (this: Scene, value: Nullable<SubSurfaceConfiguration>) {\r\n            if (value) {\r\n                if (this.enablePrePassRenderer()) {\r\n                    this._subSurfaceConfiguration = value;\r\n                }\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.enableSubSurfaceForPrePass = function (): Nullable<SubSurfaceConfiguration> {\r\n        if (this._subSurfaceConfiguration) {\r\n            return this._subSurfaceConfiguration;\r\n        }\r\n\r\n        const prePassRenderer = this.enablePrePassRenderer();\r\n        if (prePassRenderer) {\r\n            this._subSurfaceConfiguration = new subSurfaceConfigClass(this);\r\n            prePassRenderer.addEffectConfiguration(this._subSurfaceConfiguration);\r\n            return this._subSurfaceConfiguration;\r\n        }\r\n\r\n        return null;\r\n    };\r\n\r\n    Scene.prototype.disableSubSurfaceForPrePass = function (): void {\r\n        if (!this._subSurfaceConfiguration) {\r\n            return;\r\n        }\r\n\r\n        this._subSurfaceConfiguration.dispose();\r\n        this._subSurfaceConfiguration = null;\r\n    };\r\n\r\n    subSurfaceConfigClass._SceneComponentInitialization = (scene: Scene) => {\r\n        // Register the G Buffer component to the scene.\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_SUBSURFACE) as SubSurfaceSceneComponent;\r\n        if (!component) {\r\n            component = new SubSurfaceSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    };\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"../types\";\r\nimport { type Camera } from \"../Cameras/camera.pure\";\r\nimport { type Effect } from \"../Materials/effect.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { type PostProcessOptions, PostProcess } from \"./postProcess.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { type Scene } from \"../scene.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\n\r\n/**\r\n * Sub surface scattering post process\r\n */\r\nexport class SubSurfaceScatteringPostProcess extends PostProcess {\r\n    /**\r\n     * Gets a string identifying the name of the class\r\n     * @returns \"SubSurfaceScatteringPostProcess\" string\r\n     */\r\n    public override getClassName(): string {\r\n        return \"SubSurfaceScatteringPostProcess\";\r\n    }\r\n\r\n    protected override _gatherImports(useWebGPU: boolean, list: Promise<any>[]) {\r\n        if (useWebGPU) {\r\n            this._webGPUReady = true;\r\n            list.push(Promise.all([import(\"../ShadersWGSL/imageProcessing.fragment\"), import(\"../ShadersWGSL/subSurfaceScattering.fragment\")]));\r\n        } else {\r\n            list.push(Promise.all([import(\"../Shaders/imageProcessing.fragment\"), import(\"../Shaders/subSurfaceScattering.fragment\")]));\r\n        }\r\n\r\n        super._gatherImports(useWebGPU, list);\r\n    }\r\n\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        options: number | PostProcessOptions,\r\n        camera: Nullable<Camera> = null,\r\n        samplingMode?: number,\r\n        engine?: AbstractEngine,\r\n        reusable?: boolean,\r\n        textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n    ) {\r\n        const localOptions = {\r\n            uniforms: [\"texelSize\", \"viewportSize\", \"metersPerUnit\"],\r\n            samplers: [\"diffusionS\", \"diffusionD\", \"filterRadii\", \"irradianceSampler\", \"depthSampler\", \"albedoSampler\"],\r\n            size: typeof options === \"number\" ? options : undefined,\r\n            camera,\r\n            samplingMode,\r\n            engine,\r\n            reusable,\r\n            textureType,\r\n            ...(options as PostProcessOptions),\r\n            blockCompilation: true,\r\n        };\r\n\r\n        super(name, \"subSurfaceScattering\", { ...localOptions, samplingMode: samplingMode || Texture.BILINEAR_SAMPLINGMODE });\r\n        this._scene = scene;\r\n\r\n        this.updateEffect();\r\n\r\n        this.onApplyObservable.add((effect: Effect) => {\r\n            if (!scene.prePassRenderer || !scene.subSurfaceConfiguration) {\r\n                Logger.Error(\"PrePass and subsurface configuration needs to be enabled for subsurface scattering.\");\r\n                return;\r\n            }\r\n            const texelSize = this.texelSize;\r\n            effect.setFloat(\"metersPerUnit\", scene.subSurfaceConfiguration.metersPerUnit);\r\n            effect.setFloat2(\"texelSize\", texelSize.x, texelSize.y);\r\n            effect.setTexture(\r\n                \"irradianceSampler\",\r\n                scene.prePassRenderer.getRenderTarget().textures[scene.prePassRenderer.getIndex(Constants.PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE)]\r\n            );\r\n            effect.setTexture(\"depthSampler\", scene.prePassRenderer.getRenderTarget().textures[scene.prePassRenderer.getIndex(Constants.PREPASS_DEPTH_TEXTURE_TYPE)]);\r\n            effect.setTexture(\"albedoSampler\", scene.prePassRenderer.getRenderTarget().textures[scene.prePassRenderer.getIndex(Constants.PREPASS_ALBEDO_SQRT_TEXTURE_TYPE)]);\r\n            effect.setFloat2(\r\n                \"viewportSize\",\r\n                Math.tan(scene.activeCamera!.fov / 2) * scene.getEngine().getAspectRatio(scene.activeCamera!, true),\r\n                Math.tan(scene.activeCamera!.fov / 2)\r\n            );\r\n            effect.setArray3(\"diffusionS\", scene.subSurfaceConfiguration.ssDiffusionS);\r\n            effect.setArray(\"diffusionD\", scene.subSurfaceConfiguration.ssDiffusionD);\r\n            effect.setArray(\"filterRadii\", scene.subSurfaceConfiguration.ssFilterRadii);\r\n        });\r\n    }\r\n}\r\n","import { Logger } from \"../Misc/logger\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Color3, Color4 } from \"../Maths/math.color.pure\";\r\nimport { SubSurfaceScatteringPostProcess } from \"../PostProcesses/subSurfaceScatteringPostProcess.pure\";\r\nimport { SceneComponentConstants } from \"../sceneComponent\";\r\nimport { type PrePassEffectConfiguration } from \"./prePassEffectConfiguration\";\r\nimport { _WarnImport } from \"../Misc/devTools\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterSubSurfaceSceneComponent } from \"./subSurfaceSceneComponent.pure\";\r\n\r\n/**\r\n * Contains all parameters needed for the prepass to perform\r\n * screen space subsurface scattering\r\n */\r\nexport class SubSurfaceConfiguration implements PrePassEffectConfiguration {\r\n    /**\r\n     * @internal\r\n     */\r\n    public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {\r\n        throw _WarnImport(\"SubSurfaceSceneComponent\");\r\n    };\r\n\r\n    private _ssDiffusionS: number[] = [];\r\n    private _ssFilterRadii: number[] = [];\r\n    private _ssDiffusionD: number[] = [];\r\n\r\n    /**\r\n     * Post process to attach for screen space subsurface scattering\r\n     */\r\n    public postProcess: SubSurfaceScatteringPostProcess;\r\n\r\n    /**\r\n     * Diffusion profile color for subsurface scattering\r\n     */\r\n    public get ssDiffusionS() {\r\n        return this._ssDiffusionS;\r\n    }\r\n\r\n    /**\r\n     * Diffusion profile max color channel value for subsurface scattering\r\n     */\r\n    public get ssDiffusionD() {\r\n        return this._ssDiffusionD;\r\n    }\r\n\r\n    /**\r\n     * Diffusion profile filter radius for subsurface scattering\r\n     */\r\n    public get ssFilterRadii() {\r\n        return this._ssFilterRadii;\r\n    }\r\n\r\n    /**\r\n     * Is subsurface enabled\r\n     */\r\n    public enabled = false;\r\n\r\n    /**\r\n     * Does the output of this prepass need to go through imageprocessing\r\n     */\r\n    public needsImageProcessing = true;\r\n\r\n    /**\r\n     * Name of the configuration\r\n     */\r\n    public name = SceneComponentConstants.NAME_SUBSURFACE;\r\n\r\n    /**\r\n     * Diffusion profile colors for subsurface scattering\r\n     * You can add one diffusion color using `addDiffusionProfile` on `scene.prePassRenderer`\r\n     * See ...\r\n     * Note that you can only store up to 5 of them\r\n     */\r\n    public ssDiffusionProfileColors: Color3[] = [];\r\n\r\n    /**\r\n     * Defines the ratio real world => scene units.\r\n     * Used for subsurface scattering\r\n     */\r\n    public metersPerUnit: number = 1;\r\n\r\n    /**\r\n     * Textures that should be present in the MRT for this effect to work\r\n     */\r\n    public readonly texturesRequired: number[] = [\r\n        Constants.PREPASS_DEPTH_TEXTURE_TYPE,\r\n        Constants.PREPASS_ALBEDO_SQRT_TEXTURE_TYPE,\r\n        Constants.PREPASS_COLOR_TEXTURE_TYPE,\r\n        Constants.PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE,\r\n    ];\r\n\r\n    /**\r\n     * The clear color of the render targets.\r\n     * We need 1 for the alpha channel of the irradiance texture so that we early exit from the SSS post-process if the pixel should not be processed\r\n     */\r\n    public clearColor = new Color4(0, 0, 0, 1);\r\n\r\n    private _scene: Scene;\r\n\r\n    /**\r\n     * Builds a subsurface configuration object\r\n     * @param scene The scene\r\n     */\r\n    constructor(scene: Scene) {\r\n        // Adding default diffusion profile\r\n        this.addDiffusionProfile(new Color3(1, 1, 1));\r\n        this._scene = scene;\r\n\r\n        RegisterSubSurfaceSceneComponent(SubSurfaceConfiguration);\r\n        SubSurfaceConfiguration._SceneComponentInitialization(this._scene);\r\n    }\r\n\r\n    /**\r\n     * Adds a new diffusion profile.\r\n     * Useful for more realistic subsurface scattering on diverse materials.\r\n     * @param color The color of the diffusion profile. Should be the average color of the material.\r\n     * @returns The index of the diffusion profile for the material subsurface configuration\r\n     */\r\n    public addDiffusionProfile(color: Color3): number {\r\n        if (this.ssDiffusionD.length >= 5) {\r\n            // We only suppport 5 diffusion profiles\r\n            Logger.Error(\"You already reached the maximum number of diffusion profiles.\");\r\n            return 0; // default profile\r\n        }\r\n\r\n        // Do not add doubles\r\n        for (let i = 0; i < this._ssDiffusionS.length / 3; i++) {\r\n            if (this._ssDiffusionS[i * 3] === color.r && this._ssDiffusionS[i * 3 + 1] === color.g && this._ssDiffusionS[i * 3 + 2] === color.b) {\r\n                return i;\r\n            }\r\n        }\r\n\r\n        this._ssDiffusionS.push(color.r, color.g, color.b);\r\n        this._ssDiffusionD.push(Math.max(Math.max(color.r, color.b), color.g));\r\n        this._ssFilterRadii.push(this.getDiffusionProfileParameters(color));\r\n        this.ssDiffusionProfileColors.push(color);\r\n\r\n        return this._ssDiffusionD.length - 1;\r\n    }\r\n\r\n    /**\r\n     * Creates the sss post process\r\n     * @returns The created post process\r\n     */\r\n    public createPostProcess(): SubSurfaceScatteringPostProcess {\r\n        this.postProcess = new SubSurfaceScatteringPostProcess(\"subSurfaceScattering\", this._scene, {\r\n            size: 1,\r\n            engine: this._scene.getEngine(),\r\n            shaderLanguage: this._scene.getEngine().isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n        });\r\n        this.postProcess.autoClear = false;\r\n\r\n        return this.postProcess;\r\n    }\r\n\r\n    /**\r\n     * Deletes all diffusion profiles.\r\n     * Note that in order to render subsurface scattering, you should have at least 1 diffusion profile.\r\n     */\r\n    public clearAllDiffusionProfiles() {\r\n        this._ssDiffusionD = [];\r\n        this._ssDiffusionS = [];\r\n        this._ssFilterRadii = [];\r\n        this.ssDiffusionProfileColors = [];\r\n    }\r\n\r\n    /**\r\n     * Disposes this object\r\n     */\r\n    public dispose() {\r\n        this.clearAllDiffusionProfiles();\r\n        if (this.postProcess) {\r\n            this.postProcess.dispose();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * https://zero-radiance.github.io/post/sampling-diffusion/\r\n     *\r\n     * Importance sample the normalized diffuse reflectance profile for the computed value of 's'.\r\n     * ------------------------------------------------------------------------------------\r\n     * R[r, phi, s]   = s * (Exp[-r * s] + Exp[-r * s / 3]) / (8 * Pi * r)\r\n     * PDF[r, phi, s] = r * R[r, phi, s]\r\n     * CDF[r, s]      = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]\r\n     * ------------------------------------------------------------------------------------\r\n     * We importance sample the color channel with the widest scattering distance.\r\n     */\r\n    public getDiffusionProfileParameters(color: Color3) {\r\n        const cdf = 0.997;\r\n        const maxScatteringDistance = Math.max(color.r, color.g, color.b);\r\n\r\n        return this._sampleBurleyDiffusionProfile(cdf, maxScatteringDistance);\r\n    }\r\n\r\n    /**\r\n     * Performs sampling of a Normalized Burley diffusion profile in polar coordinates.\r\n     * 'u' is the random number (the value of the CDF): [0, 1).\r\n     * rcp(s) = 1 / ShapeParam = ScatteringDistance.\r\n     * Returns the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf).\r\n     * @param u\r\n     * @param rcpS\r\n     * @returns The sampled radial distance\r\n     */\r\n    private _sampleBurleyDiffusionProfile(u: number, rcpS: number) {\r\n        u = 1 - u; // Convert CDF to CCDF\r\n\r\n        const g = 1 + 4 * u * (2 * u + Math.sqrt(1 + 4 * u * u));\r\n        const n = Math.pow(g, -1.0 / 3.0); // g^(-1/3)\r\n        const p = g * n * n; // g^(+1/3)\r\n        const c = 1 + p + n; // 1 + g^(+1/3) + g^(-1/3)\r\n        const x = 3 * Math.log(c / (4 * u));\r\n\r\n        return x * rcpS;\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { VertexBuffer } from \"../Buffers/buffer.pure\";\r\nimport { type SubMesh } from \"../Meshes/subMesh.pure\";\r\nimport { Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type _InstancesBatch } from \"../Meshes/mesh\";\r\nimport { Scene } from \"../scene.pure\";\r\nimport { type AbstractEngine } from \"../Engines/abstractEngine.pure\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"../sceneComponent\";\r\n\r\nimport { DrawWrapper } from \"../Materials/drawWrapper\";\r\nimport { AddClipPlaneUniforms, BindClipPlane, PrepareStringDefinesForClipPlanes } from \"core/Materials/clipPlaneMaterialHelper\";\r\nimport { BindBonesParameters, BindMorphTargetParameters, PrepareDefinesAndAttributesForMorphTargets, PushAttributesForInstances } from \"../Materials/materialHelper.functions\";\r\nimport { EffectFallbacks } from \"core/Materials/effectFallbacks\";\r\nimport { type IEffectCreationOptions } from \"core/Materials/effect.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { MaterialHelperGeometryRendering } from \"../Materials/materialHelper.geometryrendering\";\r\n\r\n/**\r\n * This class is responsible to draw the outline/overlay of meshes.\r\n * It should not be used directly but through the available method on mesh.\r\n */\r\nexport class OutlineRenderer implements ISceneComponent {\r\n    /**\r\n     * Stencil value used to avoid outline being seen within the mesh when the mesh is transparent\r\n     */\r\n    private static _StencilReference = 0x04;\r\n    /**\r\n     * The name of the component. Each component must have a unique name.\r\n     */\r\n    public name = SceneComponentConstants.NAME_OUTLINERENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Defines a zOffset default Factor to prevent zFighting between the overlay and the mesh.\r\n     */\r\n    public zOffset = 1;\r\n\r\n    /**\r\n     * Defines a zOffset default Unit to prevent zFighting between the overlay and the mesh.\r\n     */\r\n    public zOffsetUnits = 4; // 4 to account for projection a bit by default\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the renderer is enabled\r\n     */\r\n    public enabled = true;\r\n\r\n    private _engine: AbstractEngine;\r\n    private _savedDepthWrite: boolean;\r\n    private _passIdForDrawWrapper: number[];\r\n\r\n    /** Shader language used by the Outline renderer. */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in the Outline renderer.\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a new outline renderer. (There could be only one per scene).\r\n     * @param scene Defines the scene it belongs to\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this.scene._addComponent(this);\r\n        this._passIdForDrawWrapper = [];\r\n        for (let i = 0; i < 4; ++i) {\r\n            this._passIdForDrawWrapper[i] = this._engine.createRenderPassId(`Outline Renderer (${i})`);\r\n        }\r\n\r\n        const engine = this._engine;\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Register the component to one instance of a scene.\r\n     */\r\n    public register(): void {\r\n        this.scene._beforeRenderingMeshStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE, this, this._beforeRenderingMesh);\r\n        this.scene._afterRenderingMeshStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE, this, this._afterRenderingMesh);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        // Nothing to do here.\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources.\r\n     */\r\n    public dispose(): void {\r\n        for (let i = 0; i < this._passIdForDrawWrapper.length; ++i) {\r\n            this._engine.releaseRenderPassId(this._passIdForDrawWrapper[i]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Renders the outline in the canvas.\r\n     * @param subMesh Defines the sumesh to render\r\n     * @param batch Defines the batch of meshes in case of instances\r\n     * @param useOverlay Defines if the rendering is for the overlay or the outline\r\n     * @param renderPassId Render pass id to use to render the mesh\r\n     */\r\n    public render(subMesh: SubMesh, batch: _InstancesBatch, useOverlay: boolean = false, renderPassId?: number): void {\r\n        renderPassId = renderPassId ?? this._passIdForDrawWrapper[0];\r\n\r\n        const scene = this.scene;\r\n        const engine = scene.getEngine();\r\n        if (!MaterialHelperGeometryRendering._BindColorAttachments(engine)) {\r\n            return;\r\n        }\r\n\r\n        const hardwareInstancedRendering =\r\n            engine.getCaps().instancedArrays &&\r\n            ((batch.visibleInstances[subMesh._id] !== null && batch.visibleInstances[subMesh._id] !== undefined) || subMesh.getRenderingMesh().hasThinInstances);\r\n\r\n        if (!this.isReady(subMesh, hardwareInstancedRendering, renderPassId)) {\r\n            return;\r\n        }\r\n\r\n        const ownerMesh = subMesh.getMesh();\r\n        const replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh : null;\r\n        const renderingMesh = subMesh.getRenderingMesh();\r\n        const effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;\r\n        const material = subMesh.getMaterial();\r\n\r\n        if (!material || !scene.activeCamera) {\r\n            return;\r\n        }\r\n\r\n        const drawWrapper = subMesh._getDrawWrapper(renderPassId)!;\r\n        const effect = DrawWrapper.GetEffect(drawWrapper)!;\r\n\r\n        scene.resetCachedMaterial();\r\n        engine.enableEffect(drawWrapper);\r\n\r\n        // Logarithmic depth\r\n        if ((<any>material).useLogarithmicDepth) {\r\n            effect.setFloat(\"logarithmicDepthConstant\", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));\r\n        }\r\n\r\n        effect.setFloat(\"offset\", useOverlay ? 0 : renderingMesh.outlineWidth);\r\n        effect.setColor4(\"color\", useOverlay ? renderingMesh.overlayColor : renderingMesh.outlineColor, useOverlay ? renderingMesh.overlayAlpha : material.alpha);\r\n        effect.setMatrix(\"viewProjection\", scene.getTransformMatrix());\r\n        effect.setMatrix(\"world\", effectiveMesh.getWorldMatrix());\r\n\r\n        // Bones\r\n        BindBonesParameters(renderingMesh, effect);\r\n\r\n        // Morph targets\r\n        BindMorphTargetParameters(renderingMesh, effect);\r\n        if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {\r\n            renderingMesh.morphTargetManager._bind(effect);\r\n        }\r\n\r\n        if (!hardwareInstancedRendering) {\r\n            renderingMesh._bind(subMesh, effect, material.fillMode);\r\n        }\r\n\r\n        // Baked vertex animations\r\n        const bvaManager = subMesh.getMesh().bakedVertexAnimationManager;\r\n        if (bvaManager && bvaManager.isEnabled) {\r\n            bvaManager.bind(effect, hardwareInstancedRendering);\r\n        }\r\n\r\n        // Alpha test\r\n        if (material && material.needAlphaTestingForMesh(effectiveMesh)) {\r\n            const alphaTexture = material.getAlphaTestTexture();\r\n            if (alphaTexture) {\r\n                effect.setTexture(\"diffuseSampler\", alphaTexture);\r\n                effect.setMatrix(\"diffuseMatrix\", alphaTexture.getTextureMatrix());\r\n            }\r\n        }\r\n\r\n        // Clip plane\r\n        BindClipPlane(effect, material, scene);\r\n\r\n        engine.setZOffset(-this.zOffset);\r\n        engine.setZOffsetUnits(-this.zOffsetUnits);\r\n\r\n        renderingMesh._processRendering(effectiveMesh, subMesh, effect, material.fillMode, batch, hardwareInstancedRendering, (isInstance, world) => {\r\n            effect.setMatrix(\"world\", world);\r\n        });\r\n\r\n        engine.setZOffset(0);\r\n        engine.setZOffsetUnits(0);\r\n    }\r\n\r\n    /**\r\n     * Returns whether or not the outline renderer is ready for a given submesh.\r\n     * All the dependencies e.g. submeshes, texture, effect... mus be ready\r\n     * @param subMesh Defines the submesh to check readiness for\r\n     * @param useInstances Defines whether wee are trying to render instances or not\r\n     * @param renderPassId Render pass id to use to render the mesh\r\n     * @returns true if ready otherwise false\r\n     */\r\n    public isReady(subMesh: SubMesh, useInstances: boolean, renderPassId?: number): boolean {\r\n        renderPassId = renderPassId ?? this._passIdForDrawWrapper[0];\r\n\r\n        const defines = [];\r\n        const attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];\r\n\r\n        const mesh = subMesh.getMesh();\r\n        const material = subMesh.getMaterial();\r\n\r\n        if (!material) {\r\n            return false;\r\n        }\r\n\r\n        const scene = mesh.getScene();\r\n\r\n        let uv1 = false;\r\n        let uv2 = false;\r\n        const color = false;\r\n\r\n        // Alpha test\r\n        if (material.needAlphaTestingForMesh(mesh)) {\r\n            defines.push(\"#define ALPHATEST\");\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {\r\n                attribs.push(VertexBuffer.UVKind);\r\n                defines.push(\"#define UV1\");\r\n                uv1 = true;\r\n            }\r\n            if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {\r\n                attribs.push(VertexBuffer.UV2Kind);\r\n                defines.push(\"#define UV2\");\r\n                uv2 = true;\r\n            }\r\n        }\r\n        //Logarithmic depth\r\n        if ((<any>material).useLogarithmicDepth) {\r\n            defines.push(\"#define LOGARITHMICDEPTH\");\r\n        }\r\n        // Clip planes\r\n        PrepareStringDefinesForClipPlanes(material, scene, defines);\r\n\r\n        // Bones\r\n        const fallbacks = new EffectFallbacks();\r\n        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {\r\n            attribs.push(VertexBuffer.MatricesIndicesKind);\r\n            attribs.push(VertexBuffer.MatricesWeightsKind);\r\n            if (mesh.numBoneInfluencers > 4) {\r\n                attribs.push(VertexBuffer.MatricesIndicesExtraKind);\r\n                attribs.push(VertexBuffer.MatricesWeightsExtraKind);\r\n            }\r\n            const skeleton = mesh.skeleton;\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS \" + mesh.numBoneInfluencers);\r\n            if (mesh.numBoneInfluencers > 0) {\r\n                fallbacks.addCPUSkinningFallback(0, mesh);\r\n            }\r\n\r\n            if (skeleton.isUsingTextureForMatrices) {\r\n                defines.push(\"#define BONETEXTURE\");\r\n            } else {\r\n                defines.push(\"#define BonesPerMesh \" + (skeleton.bones.length + 1));\r\n            }\r\n        } else {\r\n            defines.push(\"#define NUM_BONE_INFLUENCERS 0\");\r\n        }\r\n\r\n        // Morph targets\r\n        const numMorphInfluencers = mesh.morphTargetManager\r\n            ? PrepareDefinesAndAttributesForMorphTargets(\r\n                  mesh.morphTargetManager,\r\n                  defines,\r\n                  attribs,\r\n                  mesh,\r\n                  true, // usePositionMorph\r\n                  true, // useNormalMorph\r\n                  false, // useTangentMorph\r\n                  uv1, // useUVMorph\r\n                  uv2, // useUV2Morph\r\n                  color // useColorMorph\r\n              )\r\n            : 0;\r\n\r\n        // Instances\r\n        if (useInstances) {\r\n            defines.push(\"#define INSTANCES\");\r\n            PushAttributesForInstances(attribs);\r\n            if (subMesh.getRenderingMesh().hasThinInstances) {\r\n                defines.push(\"#define THIN_INSTANCES\");\r\n            }\r\n        }\r\n\r\n        // Baked vertex animations\r\n        const bvaManager = mesh.bakedVertexAnimationManager;\r\n        if (bvaManager && bvaManager.isEnabled) {\r\n            defines.push(\"#define BAKED_VERTEX_ANIMATION_TEXTURE\");\r\n            if (useInstances) {\r\n                attribs.push(\"bakedVertexAnimationSettingsInstanced\");\r\n            }\r\n        }\r\n\r\n        // Get correct effect\r\n        const drawWrapper = subMesh._getDrawWrapper(renderPassId, true)!;\r\n        const cachedDefines = drawWrapper.defines;\r\n        const join = defines.join(\"\\n\");\r\n\r\n        if (cachedDefines !== join) {\r\n            const uniforms = [\r\n                \"world\",\r\n                \"mBones\",\r\n                \"viewProjection\",\r\n                \"diffuseMatrix\",\r\n                \"offset\",\r\n                \"color\",\r\n                \"logarithmicDepthConstant\",\r\n                \"morphTargetInfluences\",\r\n                \"boneTextureInfo\",\r\n                \"morphTargetCount\",\r\n                \"morphTargetTextureInfo\",\r\n                \"morphTargetTextureIndices\",\r\n                \"bakedVertexAnimationSettings\",\r\n                \"bakedVertexAnimationTextureSizeInverted\",\r\n                \"bakedVertexAnimationTime\",\r\n                \"bakedVertexAnimationTexture\",\r\n            ];\r\n            const samplers = [\"diffuseSampler\", \"boneSampler\", \"morphTargets\", \"bakedVertexAnimationTexture\"];\r\n\r\n            AddClipPlaneUniforms(uniforms);\r\n\r\n            drawWrapper.setEffect(\r\n                this.scene.getEngine().createEffect(\r\n                    \"outline\",\r\n                    <IEffectCreationOptions>{\r\n                        attributes: attribs,\r\n                        uniformsNames: uniforms,\r\n                        uniformBuffersNames: [],\r\n                        samplers: samplers,\r\n                        defines: join,\r\n                        fallbacks: fallbacks,\r\n                        onCompiled: null,\r\n                        onError: null,\r\n                        indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },\r\n                        shaderLanguage: this._shaderLanguage,\r\n                        extraInitializationsAsync: async () => {\r\n                            if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                                await Promise.all([import(\"../ShadersWGSL/outline.fragment\"), import(\"../ShadersWGSL/outline.vertex\")]);\r\n                            } else {\r\n                                await Promise.all([import(\"../Shaders/outline.fragment\"), import(\"../Shaders/outline.vertex\")]);\r\n                            }\r\n                        },\r\n                    },\r\n                    this.scene.getEngine()\r\n                ),\r\n                join\r\n            );\r\n        }\r\n\r\n        return drawWrapper.effect!.isReady();\r\n    }\r\n\r\n    private _beforeRenderingMesh(mesh: Mesh, subMesh: SubMesh, batch: _InstancesBatch): void {\r\n        if (!this.enabled || (!mesh.renderOutline && !mesh.renderOverlay) || !MaterialHelperGeometryRendering._IsColorAttachmentEnabled(this._engine)) {\r\n            return;\r\n        }\r\n\r\n        // Outline - step 1\r\n        this._savedDepthWrite = this._engine.getDepthWrite();\r\n        if (mesh.renderOutline) {\r\n            const material = subMesh.getMaterial();\r\n            if (material && material.needAlphaBlendingForMesh(mesh)) {\r\n                this._engine.cacheStencilState();\r\n                // Draw only to stencil buffer for the original mesh\r\n                // The resulting stencil buffer will be used so the outline is not visible inside the mesh when the mesh is transparent\r\n                this._engine.setDepthWrite(false);\r\n                this._engine.setColorWrite(false);\r\n                this._engine.setStencilBuffer(true);\r\n                this._engine.setStencilOperationPass(Constants.REPLACE);\r\n                this._engine.setStencilFunction(Constants.ALWAYS);\r\n                this._engine.setStencilMask(OutlineRenderer._StencilReference);\r\n                this._engine.setStencilFunctionReference(OutlineRenderer._StencilReference);\r\n                this._engine.stencilStateComposer.useStencilGlobalOnly = true;\r\n                this.render(subMesh, batch, /* This sets offset to 0 */ true, this._passIdForDrawWrapper[1]);\r\n\r\n                this._engine.setColorWrite(true);\r\n                this._engine.setStencilFunction(Constants.NOTEQUAL);\r\n            }\r\n\r\n            // Draw the outline using the above stencil if needed to avoid drawing within the mesh\r\n            this._engine.setDepthWrite(false);\r\n            this.render(subMesh, batch, false, this._passIdForDrawWrapper[0]);\r\n            this._engine.setDepthWrite(this._savedDepthWrite);\r\n\r\n            if (material && material.needAlphaBlendingForMesh(mesh)) {\r\n                this._engine.stencilStateComposer.useStencilGlobalOnly = false;\r\n                this._engine.restoreStencilState();\r\n            }\r\n        }\r\n    }\r\n\r\n    private _afterRenderingMesh(mesh: Mesh, subMesh: SubMesh, batch: _InstancesBatch): void {\r\n        if (!this.enabled || (!mesh.renderOutline && !mesh.renderOverlay) || !MaterialHelperGeometryRendering._IsColorAttachmentEnabled(this._engine)) {\r\n            return;\r\n        }\r\n\r\n        // Overlay\r\n        if (mesh.renderOverlay) {\r\n            const currentMode = this._engine.getAlphaMode();\r\n            const alphaBlendState = this._engine.alphaState.alphaBlend;\r\n            this._engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n            this.render(subMesh, batch, true, this._passIdForDrawWrapper[3]);\r\n            this._engine.setAlphaMode(currentMode);\r\n            this._engine.setDepthWrite(this._savedDepthWrite);\r\n            this._engine.alphaState.setAlphaBlend(alphaBlendState);\r\n        }\r\n\r\n        // Outline - step 2\r\n        if (mesh.renderOutline && this._savedDepthWrite) {\r\n            this._engine.setDepthWrite(true);\r\n            this._engine.setColorWrite(false);\r\n            this.render(subMesh, batch, false, this._passIdForDrawWrapper[2]);\r\n            this._engine.setColorWrite(true);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for outlineRenderer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterOutlineRenderer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    /**\r\n     * Gets the outline renderer associated with the scene\r\n     * @returns a OutlineRenderer\r\n     */\r\n    Scene.prototype.getOutlineRenderer = function (): OutlineRenderer {\r\n        if (!this._outlineRenderer) {\r\n            this._outlineRenderer = new OutlineRenderer(this);\r\n        }\r\n        return this._outlineRenderer;\r\n    };\r\n\r\n    Object.defineProperty(Mesh.prototype, \"renderOutline\", {\r\n        get: function (this: Mesh) {\r\n            return this._renderOutline;\r\n        },\r\n        set: function (this: Mesh, value: boolean) {\r\n            if (value) {\r\n                // Lazy Load the component.\r\n                this.getScene().getOutlineRenderer();\r\n            }\r\n            this._renderOutline = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Object.defineProperty(Mesh.prototype, \"renderOverlay\", {\r\n        get: function (this: Mesh) {\r\n            return this._renderOverlay;\r\n        },\r\n        set: function (this: Mesh, value: boolean) {\r\n            if (value) {\r\n                // Lazy Load the component.\r\n                this.getScene().getOutlineRenderer();\r\n            }\r\n            this._renderOverlay = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n}\r\n","import { type VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { type DataBuffer } from \"core/Buffers/dataBuffer\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Defines the base object used for fluid rendering.\r\n * It is based on a list of vertices (particles)\r\n */\r\nexport abstract class FluidRenderingObject {\r\n    /**\r\n     * Uses each particle's own \"size\" vertex attribute instead\r\n     * of a single uniform size for all particles (default: false, opt-in).\r\n     */\r\n    public static UsePerParticleSizeAttribute = false;\r\n    protected _usesPerParticleSizeAttribute = false;\r\n\r\n    protected _scene: Scene;\r\n    protected _engine: AbstractEngine;\r\n    protected _effectsAreDirty: boolean;\r\n    protected _depthEffectWrapper: Nullable<EffectWrapper>;\r\n    protected _thicknessEffectWrapper: Nullable<EffectWrapper>;\r\n\r\n    /** Defines the priority of the object. Objects will be rendered in ascending order of priority */\r\n    public priority = 0;\r\n\r\n    protected _particleSize = 0.1;\r\n\r\n    /** Observable triggered when the size of the particle is changed */\r\n    public onParticleSizeChanged = new Observable<FluidRenderingObject>();\r\n\r\n    /** Gets or sets the size of the particle */\r\n    public get particleSize() {\r\n        return this._particleSize;\r\n    }\r\n\r\n    public set particleSize(size: number) {\r\n        if (size === this._particleSize) {\r\n            return;\r\n        }\r\n\r\n        this._particleSize = size;\r\n        this.onParticleSizeChanged.notifyObservers(this);\r\n    }\r\n\r\n    /** Defines the alpha value of a particle */\r\n    public particleThicknessAlpha = 0.05;\r\n\r\n    /** Indicates if the object uses instancing or not */\r\n    public get useInstancing() {\r\n        return !this.indexBuffer;\r\n    }\r\n\r\n    private _useVelocity = false;\r\n\r\n    /** Indicates if velocity of particles should be used when rendering the object. The vertex buffer set must contain a \"velocity\" buffer for this to work! */\r\n    public get useVelocity() {\r\n        return this._useVelocity;\r\n    }\r\n\r\n    public set useVelocity(use: boolean) {\r\n        if (this._useVelocity === use || !this._hasVelocity()) {\r\n            return;\r\n        }\r\n\r\n        this._useVelocity = use;\r\n        this._effectsAreDirty = true;\r\n    }\r\n\r\n    private _hasVelocity() {\r\n        return !!this.vertexBuffers?.velocity;\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex buffers\r\n     */\r\n    public abstract get vertexBuffers(): { [key: string]: VertexBuffer };\r\n\r\n    /**\r\n     * Gets the index buffer (or null if the object is using instancing)\r\n     */\r\n    public get indexBuffer(): Nullable<DataBuffer> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * @returns the name of the class\r\n     */\r\n    public getClassName(): string {\r\n        return \"FluidRenderingObject\";\r\n    }\r\n\r\n    /** Shader language used by the object */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this object\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Instantiates a fluid rendering object\r\n     * @param scene The scene the object is part of\r\n     * @param shaderLanguage The shader language to use\r\n     */\r\n    constructor(scene: Scene, shaderLanguage?: ShaderLanguage) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._effectsAreDirty = true;\r\n        this._depthEffectWrapper = null;\r\n        this._thicknessEffectWrapper = null;\r\n        this._shaderLanguage = shaderLanguage ?? (this._engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL);\r\n    }\r\n\r\n    /**\r\n     * Override to return false if this object's buffers have an incompatible \"size\" layout.\r\n     * @returns true if the per-particle size attribute is supported\r\n     */\r\n    protected _supportsPerParticleSizeAttribute(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Override to return 3 if the \"size\" attribute is laid out as (baseSize, scaleX, scaleY) instead of (width, height).\r\n     * @returns the number of components of the \"size\" attribute\r\n     */\r\n    protected _getPerParticleSizeAttributeSize(): number {\r\n        return 2;\r\n    }\r\n\r\n    /**\r\n     * Override to return true if the \"offset\" attribute is centered ([-0.5, 0.5]) instead of laid out in [0, 1].\r\n     * @returns true if the \"offset\" attribute is centered\r\n     */\r\n    protected _usesCenteredOffsetAttribute(): boolean {\r\n        return false;\r\n    }\r\n\r\n    protected _createEffects(): void {\r\n        // \"size\" is a uniform, or a per-particle attribute when UsePerParticleSizeAttribute is set (and supported).\r\n        const perParticleSize = FluidRenderingObject.UsePerParticleSizeAttribute && this._supportsPerParticleSizeAttribute();\r\n        this._usesPerParticleSizeAttribute = perParticleSize;\r\n\r\n        const baseAttributeNames = perParticleSize ? [\"position\", \"offset\", \"size\"] : [\"position\", \"offset\"];\r\n        const baseUniformNames = perParticleSize ? [\"view\", \"projection\", \"particleRadius\"] : [\"view\", \"projection\", \"particleRadius\", \"size\"];\r\n        const defines: string[] = perParticleSize ? [\"#define FLUIDRENDERING_PER_PARTICLE_SIZE\"] : [];\r\n\r\n        if (perParticleSize && this._getPerParticleSizeAttributeSize() === 3) {\r\n            defines.push(\"#define FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\");\r\n        }\r\n\r\n        if (this._usesCenteredOffsetAttribute()) {\r\n            defines.push(\"#define FLUIDRENDERING_CENTERED_OFFSET\");\r\n        }\r\n\r\n        this._effectsAreDirty = false;\r\n\r\n        const depthAttributeNames = baseAttributeNames.slice();\r\n        const depthDefines = defines.slice();\r\n\r\n        if (this.useVelocity) {\r\n            depthAttributeNames.push(\"velocity\");\r\n            depthDefines.push(\"#define FLUIDRENDERING_VELOCITY\");\r\n        }\r\n\r\n        if (this._scene.useRightHandedSystem) {\r\n            depthDefines.push(\"#define FLUIDRENDERING_RHS\");\r\n        }\r\n\r\n        this._depthEffectWrapper = new EffectWrapper({\r\n            engine: this._engine,\r\n            useShaderStore: true,\r\n            vertexShader: \"fluidRenderingParticleDepth\",\r\n            fragmentShader: \"fluidRenderingParticleDepth\",\r\n            attributeNames: depthAttributeNames,\r\n            uniformNames: baseUniformNames.slice(),\r\n            samplerNames: [],\r\n            defines: depthDefines,\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/fluidRenderingParticleDepth.vertex\"), import(\"../../ShadersWGSL/fluidRenderingParticleDepth.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/fluidRenderingParticleDepth.vertex\"), import(\"../../Shaders/fluidRenderingParticleDepth.fragment\")]);\r\n                }\r\n            },\r\n        });\r\n\r\n        this._thicknessEffectWrapper = new EffectWrapper({\r\n            engine: this._engine,\r\n            useShaderStore: true,\r\n            vertexShader: \"fluidRenderingParticleThickness\",\r\n            fragmentShader: \"fluidRenderingParticleThickness\",\r\n            attributeNames: baseAttributeNames.slice(),\r\n            uniformNames: [...baseUniformNames, \"particleAlpha\"],\r\n            samplerNames: [],\r\n            defines: defines.slice(),\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await Promise.all([import(\"../../ShadersWGSL/fluidRenderingParticleThickness.vertex\"), import(\"../../ShadersWGSL/fluidRenderingParticleThickness.fragment\")]);\r\n                } else {\r\n                    await Promise.all([import(\"../../Shaders/fluidRenderingParticleThickness.vertex\"), import(\"../../Shaders/fluidRenderingParticleThickness.fragment\")]);\r\n                }\r\n            },\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Indicates if the object is ready to be rendered\r\n     * @returns True if everything is ready for the object to be rendered, otherwise false\r\n     */\r\n    public isReady(): boolean {\r\n        if (this._effectsAreDirty) {\r\n            this._createEffects();\r\n        }\r\n\r\n        if (!this._depthEffectWrapper || !this._thicknessEffectWrapper) {\r\n            return false;\r\n        }\r\n\r\n        const depthEffect = this._depthEffectWrapper.drawWrapper.effect!;\r\n        const thicknessEffect = this._thicknessEffectWrapper.drawWrapper.effect!;\r\n\r\n        return depthEffect.isReady() && thicknessEffect.isReady();\r\n    }\r\n\r\n    /**\r\n     * Gets the number of particles (vertices) of this object\r\n     * @returns The number of particles\r\n     */\r\n    public abstract get numParticles(): number;\r\n\r\n    /**\r\n     * Render the depth texture for this object\r\n     */\r\n    public renderDepthTexture(): void {\r\n        const numParticles = this.numParticles;\r\n\r\n        if (!this._depthEffectWrapper || numParticles === 0) {\r\n            return;\r\n        }\r\n\r\n        const depthDrawWrapper = this._depthEffectWrapper.drawWrapper;\r\n        const depthEffect = depthDrawWrapper.effect!;\r\n\r\n        this._engine.enableEffect(depthDrawWrapper);\r\n        this._engine.bindBuffers(this.vertexBuffers, this.indexBuffer, depthEffect);\r\n\r\n        depthEffect.setMatrix(\"view\", this._scene.getViewMatrix());\r\n        depthEffect.setMatrix(\"projection\", this._scene.getProjectionMatrix());\r\n        if (!this._usesPerParticleSizeAttribute) {\r\n            depthEffect.setFloat2(\"size\", this._particleSize, this._particleSize);\r\n        }\r\n        depthEffect.setFloat(\"particleRadius\", this._particleSize / 2);\r\n\r\n        if (this.useInstancing) {\r\n            this._engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, numParticles);\r\n        } else {\r\n            this._engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, numParticles);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Render the thickness texture for this object\r\n     */\r\n    public renderThicknessTexture(): void {\r\n        const numParticles = this.numParticles;\r\n\r\n        if (!this._thicknessEffectWrapper || numParticles === 0) {\r\n            return;\r\n        }\r\n\r\n        const thicknessDrawWrapper = this._thicknessEffectWrapper.drawWrapper;\r\n        const thicknessEffect = thicknessDrawWrapper.effect!;\r\n\r\n        this._engine.setAlphaMode(Constants.ALPHA_ONEONE);\r\n        this._engine.setDepthWrite(false);\r\n\r\n        this._engine.enableEffect(thicknessDrawWrapper);\r\n        this._engine.bindBuffers(this.vertexBuffers, this.indexBuffer, thicknessEffect);\r\n\r\n        thicknessEffect.setMatrix(\"view\", this._scene.getViewMatrix());\r\n        thicknessEffect.setMatrix(\"projection\", this._scene.getProjectionMatrix());\r\n        thicknessEffect.setFloat(\"particleAlpha\", this.particleThicknessAlpha);\r\n        if (!this._usesPerParticleSizeAttribute) {\r\n            thicknessEffect.setFloat2(\"size\", this._particleSize, this._particleSize);\r\n        }\r\n\r\n        if (this.useInstancing) {\r\n            this._engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, numParticles);\r\n        } else {\r\n            this._engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, numParticles);\r\n        }\r\n\r\n        this._engine.setDepthWrite(true);\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n    }\r\n\r\n    /**\r\n     * Render the diffuse texture for this object\r\n     */\r\n    public renderDiffuseTexture(): void {\r\n        // do nothing by default\r\n    }\r\n\r\n    /**\r\n     * Releases the resources used by the class\r\n     */\r\n    public dispose(): void {\r\n        this._depthEffectWrapper?.dispose(false);\r\n        this._thicknessEffectWrapper?.dispose(false);\r\n        this.onParticleSizeChanged.clear();\r\n    }\r\n}\r\n","import { type VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { type DataBuffer } from \"core/Buffers/dataBuffer\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Effect } from \"core/Materials/effect\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\nimport { type IParticleSystem } from \"core/Particles/IParticleSystem\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\n\r\nimport { FluidRenderingObject } from \"./fluidRenderingObject\";\r\nimport { type ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Defines a rendering object based on a particle system\r\n */\r\nexport class FluidRenderingObjectParticleSystem extends FluidRenderingObject {\r\n    private _particleSystem: IParticleSystem;\r\n    private _originalRender: () => number;\r\n    private _blendMode: number;\r\n    private _onBeforeDrawParticleObserver: Nullable<Observer<Nullable<Effect>>>;\r\n    private _updateInAnimate: boolean;\r\n\r\n    /** Gets the particle system */\r\n    public get particleSystem() {\r\n        return this._particleSystem;\r\n    }\r\n\r\n    /**\r\n     * @returns the name of the class\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FluidRenderingObjectParticleSystem\";\r\n    }\r\n\r\n    private _useTrueRenderingForDiffuseTexture = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the diffuse texture should be generated based on the regular rendering of the particle system (default: true).\r\n     * Sometimes, generating the diffuse texture this way may be sub-optimal. In that case, you can disable this property, in which case the particle system will be\r\n     * rendered using a ALPHA_COMBINE mode instead of the one used by the particle system.\r\n     */\r\n    public get useTrueRenderingForDiffuseTexture() {\r\n        return this._useTrueRenderingForDiffuseTexture;\r\n    }\r\n\r\n    public set useTrueRenderingForDiffuseTexture(use: boolean) {\r\n        if (this._useTrueRenderingForDiffuseTexture === use) {\r\n            return;\r\n        }\r\n\r\n        this._useTrueRenderingForDiffuseTexture = use;\r\n\r\n        if (use) {\r\n            this._particleSystem.blendMode = this._blendMode;\r\n            this._particleSystem.onBeforeDrawParticlesObservable.remove(this._onBeforeDrawParticleObserver);\r\n            this._onBeforeDrawParticleObserver = null;\r\n        } else {\r\n            this._particleSystem.blendMode = -1;\r\n            this._onBeforeDrawParticleObserver = this._particleSystem.onBeforeDrawParticlesObservable.add(() => {\r\n                this._engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex buffers\r\n     */\r\n    public get vertexBuffers(): { [key: string]: VertexBuffer } {\r\n        return this._particleSystem.vertexBuffers as { [key: string]: VertexBuffer };\r\n    }\r\n\r\n    /**\r\n     * Gets the index buffer (or null if the object is using instancing)\r\n     */\r\n    public override get indexBuffer(): Nullable<DataBuffer> {\r\n        return this._particleSystem.indexBuffer;\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance of the class\r\n     * @param scene The scene the particle system is part of\r\n     * @param ps The particle system\r\n     * @param shaderLanguage The shader language to use\r\n     */\r\n    constructor(scene: Scene, ps: IParticleSystem, shaderLanguage?: ShaderLanguage) {\r\n        super(scene, shaderLanguage);\r\n\r\n        this._particleSystem = ps;\r\n\r\n        this._originalRender = ps.render.bind(ps);\r\n        this._blendMode = ps.blendMode;\r\n        this._onBeforeDrawParticleObserver = null;\r\n        this._updateInAnimate = this._particleSystem.updateInAnimate;\r\n        this._particleSystem.updateInAnimate = true;\r\n        this._particleSystem.render = () => 0;\r\n\r\n        this.particleSize = (ps.minSize + ps.maxSize) / 2;\r\n\r\n        this.useTrueRenderingForDiffuseTexture = false;\r\n    }\r\n\r\n    /**\r\n     * GPUParticleSystem stores \"size\" as (baseSize, scaleX, scaleY); ParticleSystem as (width, height).\r\n     * @returns the number of components of the \"size\" attribute\r\n     */\r\n    protected override _getPerParticleSizeAttributeSize(): number {\r\n        return this._isGPUParticleSystem ? 3 : 2;\r\n    }\r\n\r\n    /**\r\n     * GPUParticleSystem's \"offset\" quad is centered ([-0.5, 0.5]); ParticleSystem's is in [0, 1].\r\n     * @returns true if the \"offset\" attribute is centered\r\n     */\r\n    protected override _usesCenteredOffsetAttribute(): boolean {\r\n        return this._isGPUParticleSystem;\r\n    }\r\n\r\n    private get _isGPUParticleSystem(): boolean {\r\n        return this._particleSystem.getClassName() === \"GPUParticleSystem\";\r\n    }\r\n\r\n    /**\r\n     * Indicates if the object is ready to be rendered\r\n     * @returns True if everything is ready for the object to be rendered, otherwise false\r\n     */\r\n    public override isReady(): boolean {\r\n        return super.isReady() && this._particleSystem.isReady();\r\n    }\r\n\r\n    /**\r\n     * Gets the number of particles in this particle system\r\n     * @returns The number of particles\r\n     */\r\n    public get numParticles(): number {\r\n        return this._particleSystem.getActiveCount();\r\n    }\r\n\r\n    /**\r\n     * Render the diffuse texture for this object\r\n     */\r\n    public override renderDiffuseTexture(): void {\r\n        this._originalRender();\r\n    }\r\n\r\n    /**\r\n     * Releases the resources used by the class\r\n     */\r\n    public override dispose() {\r\n        super.dispose();\r\n\r\n        this._particleSystem.onBeforeDrawParticlesObservable.remove(this._onBeforeDrawParticleObserver);\r\n        this._onBeforeDrawParticleObserver = null;\r\n        this._particleSystem.render = this._originalRender;\r\n        this._particleSystem.blendMode = this._blendMode;\r\n        this._particleSystem.updateInAnimate = this._updateInAnimate;\r\n    }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-misused-promises */\r\nimport { type Camera } from \"core/Cameras/camera\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\r\nimport { Texture } from \"core/Materials/Textures/texture.pure\";\r\nimport { type ThinTexture } from \"core/Materials/Textures/thinTexture\";\r\nimport { Vector2 } from \"core/Maths/math.vector.pure\";\r\nimport { PostProcess } from \"core/PostProcesses/postProcess.pure\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/** @internal */\r\nexport class FluidRenderingTextures {\r\n    protected _name: string;\r\n    protected _scene: Scene;\r\n    protected _camera: Nullable<Camera>;\r\n    protected _engine: AbstractEngine;\r\n    protected _width: number;\r\n    protected _height: number;\r\n    protected _blurTextureSizeX: number;\r\n    protected _blurTextureSizeY: number;\r\n    protected _textureType: number;\r\n    protected _textureFormat: number;\r\n    protected _blurTextureType: number;\r\n    protected _blurTextureFormat: number;\r\n    protected _useStandardBlur: boolean;\r\n    protected _generateDepthBuffer: boolean;\r\n    protected _samples: number;\r\n    protected _postProcessRunningIndex: number;\r\n\r\n    protected _rt: Nullable<RenderTargetWrapper>;\r\n    protected _texture: Nullable<Texture>;\r\n    protected _rtBlur: Nullable<RenderTargetWrapper>;\r\n    protected _textureBlurred: Nullable<Texture>;\r\n    protected _blurPostProcesses: Nullable<PostProcess[]>;\r\n\r\n    public enableBlur = true;\r\n\r\n    public blurSizeDivisor = 1;\r\n\r\n    public blurFilterSize = 7;\r\n\r\n    private _blurNumIterations = 3;\r\n\r\n    public get blurNumIterations() {\r\n        return this._blurNumIterations;\r\n    }\r\n\r\n    public set blurNumIterations(numIterations: number) {\r\n        if (this._blurNumIterations === numIterations) {\r\n            return;\r\n        }\r\n\r\n        this._blurNumIterations = numIterations;\r\n        if (this._blurPostProcesses !== null) {\r\n            const blurX = this._blurPostProcesses[0];\r\n            const blurY = this._blurPostProcesses[1];\r\n\r\n            this._blurPostProcesses = [];\r\n            for (let i = 0; i < this._blurNumIterations * 2; ++i) {\r\n                this._blurPostProcesses[i] = i & 1 ? blurY : blurX;\r\n            }\r\n        }\r\n    }\r\n\r\n    public blurMaxFilterSize = 100;\r\n\r\n    public blurDepthScale = 10;\r\n\r\n    public particleSize = 0.02;\r\n\r\n    public onDisposeObservable: Observable<FluidRenderingTextures> = new Observable<FluidRenderingTextures>();\r\n\r\n    public get renderTarget() {\r\n        return this._rt;\r\n    }\r\n\r\n    public get renderTargetBlur() {\r\n        return this._rtBlur;\r\n    }\r\n\r\n    public get texture() {\r\n        return this._texture;\r\n    }\r\n\r\n    public get textureBlur() {\r\n        return this._textureBlurred;\r\n    }\r\n\r\n    /** Shader language used by the texture */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in the texture\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    constructor(\r\n        name: string,\r\n        scene: Scene,\r\n        width: number,\r\n        height: number,\r\n        blurTextureSizeX: number,\r\n        blurTextureSizeY: number,\r\n        textureType: number = Constants.TEXTURETYPE_FLOAT,\r\n        textureFormat: number = Constants.TEXTUREFORMAT_R,\r\n        blurTextureType: number = Constants.TEXTURETYPE_FLOAT,\r\n        blurTextureFormat: number = Constants.TEXTUREFORMAT_R,\r\n        useStandardBlur = false,\r\n        camera: Nullable<Camera> = null,\r\n        generateDepthBuffer = true,\r\n        samples = 1,\r\n        shaderLanguage?: ShaderLanguage\r\n    ) {\r\n        this._name = name;\r\n        this._scene = scene;\r\n        this._camera = camera;\r\n        this._engine = scene.getEngine();\r\n        this._width = width;\r\n        this._height = height;\r\n        this._blurTextureSizeX = blurTextureSizeX;\r\n        this._blurTextureSizeY = blurTextureSizeY;\r\n        this._textureType = textureType;\r\n        this._textureFormat = textureFormat;\r\n        this._blurTextureType = blurTextureType;\r\n        this._blurTextureFormat = blurTextureFormat;\r\n        this._useStandardBlur = useStandardBlur;\r\n        this._generateDepthBuffer = generateDepthBuffer;\r\n        this._samples = samples;\r\n        this._postProcessRunningIndex = 0;\r\n        this.enableBlur = blurTextureSizeX !== 0 && blurTextureSizeY !== 0;\r\n\r\n        this._rt = null;\r\n        this._texture = null;\r\n        this._rtBlur = null;\r\n        this._textureBlurred = null;\r\n        this._blurPostProcesses = null;\r\n\r\n        this._shaderLanguage = shaderLanguage ?? (this._engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL);\r\n    }\r\n\r\n    public initialize(): void {\r\n        this.dispose();\r\n\r\n        this._createRenderTarget();\r\n\r\n        if (this.enableBlur && this._texture) {\r\n            const [rtBlur, textureBlurred, blurPostProcesses] = this._createBlurPostProcesses(\r\n                this._texture,\r\n                this._blurTextureType,\r\n                this._blurTextureFormat,\r\n                this.blurSizeDivisor,\r\n                this._name,\r\n                this._useStandardBlur\r\n            );\r\n            this._rtBlur = rtBlur;\r\n            this._textureBlurred = textureBlurred;\r\n            this._blurPostProcesses = blurPostProcesses;\r\n        }\r\n    }\r\n\r\n    public applyBlurPostProcesses(): void {\r\n        if (this.enableBlur && this._blurPostProcesses) {\r\n            this._postProcessRunningIndex = 0;\r\n            this._scene.postProcessManager.directRender(this._blurPostProcesses, this._rtBlur, true);\r\n            this._engine.unBindFramebuffer(this._rtBlur!);\r\n        }\r\n    }\r\n\r\n    protected _createRenderTarget(): void {\r\n        this._rt = this._engine.createRenderTargetTexture(\r\n            { width: this._width, height: this._height },\r\n            {\r\n                generateMipMaps: false,\r\n                type: this._textureType,\r\n                format: this._textureFormat,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                generateDepthBuffer: this._generateDepthBuffer,\r\n                generateStencilBuffer: false,\r\n                samples: this._samples,\r\n                label: `FluidRenderingRTT-${this._name}`,\r\n            }\r\n        );\r\n\r\n        const renderTexture = this._rt.texture!;\r\n\r\n        renderTexture.incrementReferences();\r\n\r\n        this._texture = new Texture(null, this._scene);\r\n        this._texture.name = \"rtt\" + this._name;\r\n        this._texture._texture = renderTexture;\r\n        this._texture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        this._texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        this._texture.anisotropicFilteringLevel = 1;\r\n    }\r\n\r\n    protected _createBlurPostProcesses(\r\n        textureBlurSource: ThinTexture,\r\n        textureType: number,\r\n        textureFormat: number,\r\n        blurSizeDivisor: number,\r\n        debugName: string,\r\n        useStandardBlur = false\r\n    ): [RenderTargetWrapper, Texture, PostProcess[]] {\r\n        const engine = this._scene.getEngine();\r\n        const targetSize = new Vector2(Math.floor(this._blurTextureSizeX / blurSizeDivisor), Math.floor(this._blurTextureSizeY / blurSizeDivisor));\r\n        const useBilinearFiltering =\r\n            (textureType === Constants.TEXTURETYPE_FLOAT && engine.getCaps().textureFloatLinearFiltering) ||\r\n            (textureType === Constants.TEXTURETYPE_HALF_FLOAT && engine.getCaps().textureHalfFloatLinearFiltering);\r\n\r\n        const rtBlur = this._engine.createRenderTargetTexture(\r\n            { width: targetSize.x, height: targetSize.y },\r\n            {\r\n                generateMipMaps: false,\r\n                type: textureType,\r\n                format: textureFormat,\r\n                samplingMode: useBilinearFiltering ? Constants.TEXTURE_BILINEAR_SAMPLINGMODE : Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                generateDepthBuffer: false,\r\n                generateStencilBuffer: false,\r\n                samples: this._samples,\r\n                label: `FluidRenderingRTTBlur-${debugName}`,\r\n            }\r\n        );\r\n\r\n        const renderTexture = rtBlur.texture!;\r\n\r\n        renderTexture.incrementReferences();\r\n\r\n        const texture = new Texture(null, this._scene);\r\n        texture.name = \"rttBlurred\" + debugName;\r\n        texture._texture = renderTexture;\r\n        texture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n        texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n        texture.anisotropicFilteringLevel = 1;\r\n\r\n        if (useStandardBlur) {\r\n            const kernelBlurXPostprocess = new PostProcess(\r\n                \"BilateralBlurX\",\r\n                \"fluidRenderingStandardBlur\",\r\n                [\"filterSize\", \"blurDir\"],\r\n                null,\r\n                1,\r\n                null,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                engine,\r\n                true,\r\n                null,\r\n                textureType,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                textureFormat,\r\n                this._shaderLanguage,\r\n                // Keeping this issue for further discussion - extraInitialization should return Promise<void>\r\n                async () => {\r\n                    if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await import(\"../../ShadersWGSL/fluidRenderingStandardBlur.fragment\");\r\n                    } else {\r\n                        await import(\"../../Shaders/fluidRenderingStandardBlur.fragment\");\r\n                    }\r\n                }\r\n            );\r\n            kernelBlurXPostprocess.samples = this._samples;\r\n            kernelBlurXPostprocess.externalTextureSamplerBinding = true;\r\n            kernelBlurXPostprocess.onApplyObservable.add((effect) => {\r\n                if (this._postProcessRunningIndex === 0) {\r\n                    effect.setTexture(\"textureSampler\", textureBlurSource);\r\n                } else {\r\n                    effect._bindTexture(\"textureSampler\", kernelBlurXPostprocess.inputTexture.texture);\r\n                }\r\n                effect.setInt(\"filterSize\", this.blurFilterSize);\r\n                effect.setFloat2(\"blurDir\", 1 / this._blurTextureSizeX, 0);\r\n                this._postProcessRunningIndex++;\r\n            });\r\n            kernelBlurXPostprocess.onSizeChangedObservable.add(() => {\r\n                kernelBlurXPostprocess._textures.forEach((rt) => {\r\n                    rt.texture!.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n                    rt.texture!.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n                });\r\n            });\r\n            this._fixReusablePostProcess(kernelBlurXPostprocess);\r\n\r\n            const kernelBlurYPostprocess = new PostProcess(\r\n                \"BilateralBlurY\",\r\n                \"fluidRenderingStandardBlur\",\r\n                [\"filterSize\", \"blurDir\"],\r\n                null,\r\n                1,\r\n                null,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                engine,\r\n                true,\r\n                null,\r\n                textureType,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                textureFormat,\r\n                this._shaderLanguage,\r\n                async () => {\r\n                    if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await import(\"../../ShadersWGSL/fluidRenderingStandardBlur.fragment\");\r\n                    } else {\r\n                        await import(\"../../Shaders/fluidRenderingStandardBlur.fragment\");\r\n                    }\r\n                }\r\n            );\r\n            kernelBlurYPostprocess.samples = this._samples;\r\n            kernelBlurYPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setInt(\"filterSize\", this.blurFilterSize);\r\n                effect.setFloat2(\"blurDir\", 0, 1 / this._blurTextureSizeY);\r\n                this._postProcessRunningIndex++;\r\n            });\r\n            kernelBlurYPostprocess.onSizeChangedObservable.add(() => {\r\n                kernelBlurYPostprocess._textures.forEach((rt) => {\r\n                    rt.texture!.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n                    rt.texture!.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n                });\r\n            });\r\n            this._fixReusablePostProcess(kernelBlurYPostprocess);\r\n\r\n            kernelBlurXPostprocess.autoClear = false;\r\n            kernelBlurYPostprocess.autoClear = false;\r\n\r\n            const blurList = [];\r\n            for (let i = 0; i < this._blurNumIterations * 2; ++i) {\r\n                blurList[i] = i & 1 ? kernelBlurYPostprocess : kernelBlurXPostprocess;\r\n            }\r\n\r\n            return [rtBlur, texture, blurList];\r\n        } else {\r\n            const uniforms: string[] = [\"maxFilterSize\", \"blurDir\", \"projectedParticleConstant\", \"depthThreshold\"];\r\n\r\n            const kernelBlurXPostprocess = new PostProcess(\r\n                \"BilateralBlurX\",\r\n                \"fluidRenderingBilateralBlur\",\r\n                uniforms,\r\n                null,\r\n                1,\r\n                null,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                engine,\r\n                true,\r\n                null,\r\n                textureType,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                textureFormat,\r\n                this._shaderLanguage,\r\n                async () => {\r\n                    if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await import(\"../../ShadersWGSL/fluidRenderingBilateralBlur.fragment\");\r\n                    } else {\r\n                        await import(\"../../Shaders/fluidRenderingBilateralBlur.fragment\");\r\n                    }\r\n                }\r\n            );\r\n            kernelBlurXPostprocess.samples = this._samples;\r\n            kernelBlurXPostprocess.externalTextureSamplerBinding = true;\r\n            kernelBlurXPostprocess.onApplyObservable.add((effect) => {\r\n                if (this._postProcessRunningIndex === 0) {\r\n                    effect.setTexture(\"textureSampler\", textureBlurSource);\r\n                } else {\r\n                    effect._bindTexture(\"textureSampler\", kernelBlurXPostprocess.inputTexture.texture);\r\n                }\r\n                effect.setInt(\"maxFilterSize\", this.blurMaxFilterSize);\r\n                effect.setFloat2(\"blurDir\", 1 / this._blurTextureSizeX, 0);\r\n                effect.setFloat(\"projectedParticleConstant\", this._getProjectedParticleConstant());\r\n                effect.setFloat(\"depthThreshold\", this._getDepthThreshold());\r\n                this._postProcessRunningIndex++;\r\n            });\r\n            kernelBlurXPostprocess.onSizeChangedObservable.add(() => {\r\n                kernelBlurXPostprocess._textures.forEach((rt) => {\r\n                    rt.texture!.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n                    rt.texture!.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n                });\r\n            });\r\n            this._fixReusablePostProcess(kernelBlurXPostprocess);\r\n\r\n            const kernelBlurYPostprocess = new PostProcess(\r\n                \"BilateralBlurY\",\r\n                \"fluidRenderingBilateralBlur\",\r\n                uniforms,\r\n                null,\r\n                1,\r\n                null,\r\n                Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                engine,\r\n                true,\r\n                null,\r\n                textureType,\r\n                undefined,\r\n                undefined,\r\n                undefined,\r\n                textureFormat,\r\n                this._shaderLanguage,\r\n                async () => {\r\n                    if (this.shaderLanguage === ShaderLanguage.WGSL) {\r\n                        await import(\"../../ShadersWGSL/fluidRenderingBilateralBlur.fragment\");\r\n                    } else {\r\n                        await import(\"../../Shaders/fluidRenderingBilateralBlur.fragment\");\r\n                    }\r\n                }\r\n            );\r\n            kernelBlurYPostprocess.samples = this._samples;\r\n            kernelBlurYPostprocess.onApplyObservable.add((effect) => {\r\n                effect.setInt(\"maxFilterSize\", this.blurMaxFilterSize);\r\n                effect.setFloat2(\"blurDir\", 0, 1 / this._blurTextureSizeY);\r\n                effect.setFloat(\"projectedParticleConstant\", this._getProjectedParticleConstant());\r\n                effect.setFloat(\"depthThreshold\", this._getDepthThreshold());\r\n                this._postProcessRunningIndex++;\r\n            });\r\n            kernelBlurYPostprocess.onSizeChangedObservable.add(() => {\r\n                kernelBlurYPostprocess._textures.forEach((rt) => {\r\n                    rt.texture!.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n                    rt.texture!.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n                });\r\n            });\r\n            this._fixReusablePostProcess(kernelBlurYPostprocess);\r\n\r\n            kernelBlurXPostprocess.autoClear = false;\r\n            kernelBlurYPostprocess.autoClear = false;\r\n\r\n            const blurList = [];\r\n            for (let i = 0; i < this._blurNumIterations * 2; ++i) {\r\n                blurList[i] = i & 1 ? kernelBlurYPostprocess : kernelBlurXPostprocess;\r\n            }\r\n\r\n            return [rtBlur, texture, blurList];\r\n        }\r\n    }\r\n\r\n    private _fixReusablePostProcess(pp: PostProcess) {\r\n        if (!pp.isReusable()) {\r\n            return;\r\n        }\r\n\r\n        pp.onActivateObservable.add(() => {\r\n            // undo what calling activate() does which will make sure we will retrieve the right texture when getting the input for the post process\r\n            pp._currentRenderTextureInd = (pp._currentRenderTextureInd + 1) % 2;\r\n        });\r\n        pp.onApplyObservable.add(() => {\r\n            // now we can advance to the next texture\r\n            pp._currentRenderTextureInd = (pp._currentRenderTextureInd + 1) % 2;\r\n        });\r\n    }\r\n\r\n    private _getProjectedParticleConstant() {\r\n        return (this.blurFilterSize * this.particleSize * 0.05 * (this._height / 2)) / Math.tan((this._camera?.fov ?? (45 * Math.PI) / 180) / 2);\r\n    }\r\n\r\n    private _getDepthThreshold() {\r\n        return (this.particleSize / 2) * this.blurDepthScale;\r\n    }\r\n\r\n    public dispose(): void {\r\n        if (this.onDisposeObservable.hasObservers()) {\r\n            this.onDisposeObservable.notifyObservers(this);\r\n        }\r\n\r\n        this.onDisposeObservable.clear();\r\n\r\n        this._rt?.dispose();\r\n        this._rt = null;\r\n        this._texture?.dispose();\r\n        this._texture = null;\r\n        this._rtBlur?.dispose();\r\n        this._rtBlur = null;\r\n        this._textureBlurred?.dispose();\r\n        this._textureBlurred = null;\r\n        if (this._blurPostProcesses) {\r\n            this._blurPostProcesses[0].dispose();\r\n            this._blurPostProcesses[1].dispose();\r\n        }\r\n        this._blurPostProcesses = null;\r\n    }\r\n}\r\n","import { type Camera } from \"core/Cameras/camera\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { type ThinTexture } from \"core/Materials/Textures/thinTexture\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Matrix, Vector2, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { PostProcess } from \"core/PostProcesses/postProcess.pure\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\n\r\nimport { type FluidRenderingObject } from \"./fluidRenderingObject\";\r\nimport { FluidRenderingTextures } from \"./fluidRenderingTextures\";\r\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Textures that can be displayed as a debugging tool\r\n */\r\nexport const enum FluidRenderingDebug {\r\n    DepthTexture,\r\n    DepthBlurredTexture,\r\n    ThicknessTexture,\r\n    ThicknessBlurredTexture,\r\n    DiffuseTexture,\r\n    Normals,\r\n    DiffuseRendering,\r\n}\r\n\r\n/**\r\n * Class used to render an object as a fluid thanks to different render target textures (depth, thickness, diffuse)\r\n */\r\nexport class FluidRenderingTargetRenderer {\r\n    protected _scene: Scene;\r\n    protected _camera: Nullable<Camera>;\r\n    protected _engine: AbstractEngine;\r\n\r\n    protected _invProjectionMatrix: Matrix;\r\n    protected _depthClearColor: Color4;\r\n    protected _thicknessClearColor: Color4;\r\n\r\n    protected _needInitialization: boolean;\r\n\r\n    /**\r\n     * Returns true if the class needs to be reinitialized (because of changes in parameterization)\r\n     */\r\n    public get needInitialization() {\r\n        return this._needInitialization;\r\n    }\r\n\r\n    private _generateDiffuseTexture = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the diffuse texture should be generated and used for the rendering\r\n     */\r\n    public get generateDiffuseTexture() {\r\n        return this._generateDiffuseTexture;\r\n    }\r\n\r\n    public set generateDiffuseTexture(generate: boolean) {\r\n        if (this._generateDiffuseTexture === generate) {\r\n            return;\r\n        }\r\n\r\n        this._generateDiffuseTexture = generate;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    /**\r\n     * Fluid color. Not used if generateDiffuseTexture is true\r\n     */\r\n    public fluidColor = new Color3(0.085, 0.6375, 0.765);\r\n\r\n    /**\r\n     * Density of the fluid (positive number). The higher the value, the more opaque the fluid.\r\n     */\r\n    public density = 2;\r\n\r\n    /**\r\n     * Strength of the refraction (positive number, but generally between 0 and 0.3).\r\n     */\r\n    public refractionStrength = 0.1;\r\n\r\n    /**\r\n     * Strength of the fresnel effect (value between 0 and 1). Lower the value if you want to soften the specular effect\r\n     */\r\n    public fresnelClamp = 1.0;\r\n\r\n    /**\r\n     * Strength of the specular power (positive number). Increase the value to make the specular effect more concentrated\r\n     */\r\n    public specularPower = 250;\r\n\r\n    /**\r\n     * Minimum thickness of the particles (positive number). If useFixedThickness is true, minimumThickness is the thickness used\r\n     */\r\n    public minimumThickness = 0;\r\n\r\n    /**\r\n     * Direction of the light. The fluid is assumed to be lit by a directional light\r\n     */\r\n    public dirLight: Vector3 = new Vector3(-2, -1, 1).normalize();\r\n\r\n    private _debugFeature: FluidRenderingDebug = FluidRenderingDebug.DepthBlurredTexture;\r\n\r\n    /**\r\n     * Gets or sets the feature (texture) to be debugged. Not used if debug is false\r\n     */\r\n    public get debugFeature() {\r\n        return this._debugFeature;\r\n    }\r\n\r\n    public set debugFeature(feature: FluidRenderingDebug) {\r\n        if (this._debugFeature === feature) {\r\n            return;\r\n        }\r\n\r\n        this._needInitialization = true;\r\n        this._debugFeature = feature;\r\n    }\r\n\r\n    private _debug = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if we should display a specific texture (given by debugFeature) for debugging purpose\r\n     */\r\n    public get debug() {\r\n        return this._debug;\r\n    }\r\n\r\n    public set debug(debug: boolean) {\r\n        if (this._debug === debug) {\r\n            return;\r\n        }\r\n\r\n        this._debug = debug;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _environmentMap?: Nullable<BaseTexture>;\r\n\r\n    /**\r\n     * Gets or sets the environment map used for the reflection part of the shading\r\n     * If null, no map will be used. If undefined, the scene.environmentMap will be used (if defined)\r\n     */\r\n    public get environmentMap() {\r\n        return this._environmentMap;\r\n    }\r\n\r\n    public set environmentMap(map: Nullable<BaseTexture> | undefined) {\r\n        if (this._environmentMap === map) {\r\n            return;\r\n        }\r\n\r\n        this._needInitialization = true;\r\n        this._environmentMap = map;\r\n    }\r\n\r\n    private _enableBlurDepth = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the depth texture should be blurred\r\n     */\r\n    public get enableBlurDepth() {\r\n        return this._enableBlurDepth;\r\n    }\r\n\r\n    public set enableBlurDepth(enable: boolean) {\r\n        if (this._enableBlurDepth === enable) {\r\n            return;\r\n        }\r\n\r\n        this._enableBlurDepth = enable;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _blurDepthSizeDivisor = 1;\r\n\r\n    /**\r\n     * Gets or sets the depth size divisor (positive number, generally between 1 and 4), which is used as a divisor when creating the texture used for blurring the depth\r\n     * For eg. if blurDepthSizeDivisor=2, the texture used to blur the depth will be half the size of the depth texture\r\n     */\r\n    public get blurDepthSizeDivisor() {\r\n        return this._blurDepthSizeDivisor;\r\n    }\r\n\r\n    public set blurDepthSizeDivisor(scale: number) {\r\n        if (this._blurDepthSizeDivisor === scale) {\r\n            return;\r\n        }\r\n\r\n        this._blurDepthSizeDivisor = scale;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _blurDepthFilterSize = 7;\r\n\r\n    /**\r\n     * Size of the kernel used to filter the depth blur texture (positive number, generally between 1 and 20 - higher values will require more processing power from the GPU)\r\n     */\r\n    public get blurDepthFilterSize() {\r\n        return this._blurDepthFilterSize;\r\n    }\r\n\r\n    public set blurDepthFilterSize(filterSize: number) {\r\n        if (this._blurDepthFilterSize === filterSize) {\r\n            return;\r\n        }\r\n\r\n        this._blurDepthFilterSize = filterSize;\r\n        this._setBlurParameters();\r\n    }\r\n\r\n    private _blurDepthNumIterations = 3;\r\n\r\n    /**\r\n     * Number of blurring iterations used to generate the depth blur texture (positive number, generally between 1 and 10 - higher values will require more processing power from the GPU)\r\n     */\r\n    public get blurDepthNumIterations() {\r\n        return this._blurDepthNumIterations;\r\n    }\r\n\r\n    public set blurDepthNumIterations(numIterations: number) {\r\n        if (this._blurDepthNumIterations === numIterations) {\r\n            return;\r\n        }\r\n\r\n        this._blurDepthNumIterations = numIterations;\r\n        this._setBlurParameters();\r\n    }\r\n\r\n    private _blurDepthMaxFilterSize = 100;\r\n\r\n    /**\r\n     * Maximum size of the kernel used to blur the depth texture (positive number, generally between 1 and 200 - higher values will require more processing power from the GPU when the particles are larger on screen)\r\n     */\r\n    public get blurDepthMaxFilterSize() {\r\n        return this._blurDepthMaxFilterSize;\r\n    }\r\n\r\n    public set blurDepthMaxFilterSize(maxFilterSize: number) {\r\n        if (this._blurDepthMaxFilterSize === maxFilterSize) {\r\n            return;\r\n        }\r\n\r\n        this._blurDepthMaxFilterSize = maxFilterSize;\r\n        this._setBlurParameters();\r\n    }\r\n\r\n    private _blurDepthDepthScale = 10;\r\n\r\n    /**\r\n     * Depth weight in the calculation when applying the bilateral blur to generate the depth blur texture (positive number, generally between 0 and 100)\r\n     */\r\n    public get blurDepthDepthScale() {\r\n        return this._blurDepthDepthScale;\r\n    }\r\n\r\n    public set blurDepthDepthScale(scale: number) {\r\n        if (this._blurDepthDepthScale === scale) {\r\n            return;\r\n        }\r\n\r\n        this._blurDepthDepthScale = scale;\r\n        this._setBlurParameters();\r\n    }\r\n\r\n    private _enableBlurThickness = true;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the thickness texture should be blurred\r\n     */\r\n    public get enableBlurThickness() {\r\n        return this._enableBlurThickness;\r\n    }\r\n\r\n    public set enableBlurThickness(enable: boolean) {\r\n        if (this._enableBlurThickness === enable) {\r\n            return;\r\n        }\r\n\r\n        this._enableBlurThickness = enable;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _blurThicknessSizeDivisor = 1;\r\n\r\n    /**\r\n     * Gets or sets the thickness size divisor (positive number, generally between 1 and 4), which is used as a divisor when creating the texture used for blurring the thickness\r\n     * For eg. if blurThicknessSizeDivisor=2, the texture used to blur the thickness will be half the size of the thickness texture\r\n     */\r\n    public get blurThicknessSizeDivisor() {\r\n        return this._blurThicknessSizeDivisor;\r\n    }\r\n\r\n    public set blurThicknessSizeDivisor(scale: number) {\r\n        if (this._blurThicknessSizeDivisor === scale) {\r\n            return;\r\n        }\r\n\r\n        this._blurThicknessSizeDivisor = scale;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _blurThicknessFilterSize = 5;\r\n\r\n    /**\r\n     * Size of the kernel used to filter the thickness blur texture (positive number, generally between 1 and 20 - higher values will require more processing power from the GPU)\r\n     */\r\n    public get blurThicknessFilterSize() {\r\n        return this._blurThicknessFilterSize;\r\n    }\r\n\r\n    public set blurThicknessFilterSize(filterSize: number) {\r\n        if (this._blurThicknessFilterSize === filterSize) {\r\n            return;\r\n        }\r\n\r\n        this._blurThicknessFilterSize = filterSize;\r\n        this._setBlurParameters();\r\n    }\r\n\r\n    private _blurThicknessNumIterations = 1;\r\n\r\n    /**\r\n     * Number of blurring iterations used to generate the thickness blur texture (positive number, generally between 1 and 10 - higher values will require more processing power from the GPU)\r\n     */\r\n    public get blurThicknessNumIterations() {\r\n        return this._blurThicknessNumIterations;\r\n    }\r\n\r\n    public set blurThicknessNumIterations(numIterations: number) {\r\n        if (this._blurThicknessNumIterations === numIterations) {\r\n            return;\r\n        }\r\n\r\n        this._blurThicknessNumIterations = numIterations;\r\n        this._setBlurParameters();\r\n    }\r\n\r\n    private _useFixedThickness = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that a fixed thickness should be used instead of generating a thickness texture\r\n     */\r\n    public get useFixedThickness() {\r\n        return this._useFixedThickness;\r\n    }\r\n\r\n    public set useFixedThickness(use: boolean) {\r\n        if (this._useFixedThickness === use) {\r\n            return;\r\n        }\r\n\r\n        this._useFixedThickness = use;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    /** @internal */\r\n    public _bgDepthTexture: Nullable<InternalTexture>;\r\n\r\n    /** @internal */\r\n    public _onUseVelocityChanged = new Observable<FluidRenderingTargetRenderer>();\r\n\r\n    private _useVelocity = false;\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating that the velocity should be used when rendering the particles as a fluid.\r\n     * Note: the vertex buffers must contain a \"velocity\" buffer for this to work!\r\n     */\r\n    public get useVelocity() {\r\n        return this._useVelocity;\r\n    }\r\n\r\n    public set useVelocity(use: boolean) {\r\n        if (this._useVelocity === use) {\r\n            return;\r\n        }\r\n\r\n        this._useVelocity = use;\r\n        this._needInitialization = true;\r\n        this._onUseVelocityChanged.notifyObservers(this);\r\n    }\r\n\r\n    private _depthMapSize: Nullable<number> = null;\r\n\r\n    /**\r\n     * Defines the size of the depth texture.\r\n     * If null, the texture will have the size of the screen\r\n     */\r\n    public get depthMapSize() {\r\n        return this._depthMapSize;\r\n    }\r\n\r\n    public set depthMapSize(size: Nullable<number>) {\r\n        if (this._depthMapSize === size) {\r\n            return;\r\n        }\r\n\r\n        this._depthMapSize = size;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _thicknessMapSize: Nullable<number> = null;\r\n\r\n    /**\r\n     * Defines the size of the thickness texture.\r\n     * If null, the texture will have the size of the screen\r\n     */\r\n    public get thicknessMapSize() {\r\n        return this._thicknessMapSize;\r\n    }\r\n\r\n    public set thicknessMapSize(size: Nullable<number>) {\r\n        if (this._thicknessMapSize === size) {\r\n            return;\r\n        }\r\n\r\n        this._thicknessMapSize = size;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _diffuseMapSize: Nullable<number> = null;\r\n\r\n    /**\r\n     * Defines the size of the diffuse texture.\r\n     * If null, the texture will have the size of the screen\r\n     */\r\n    public get diffuseMapSize() {\r\n        return this._diffuseMapSize;\r\n    }\r\n\r\n    public set diffuseMapSize(size: Nullable<number>) {\r\n        if (this._diffuseMapSize === size) {\r\n            return;\r\n        }\r\n\r\n        this._diffuseMapSize = size;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _samples = 1;\r\n\r\n    /**\r\n     * Gets or sets the number of samples used by MSAA\r\n     * Note: changing this value in WebGL does not work because depth/stencil textures can't be created with MSAA (see https://github.com/BabylonJS/Babylon.js/issues/12444)\r\n     */\r\n    public get samples() {\r\n        return this._samples;\r\n    }\r\n\r\n    public set samples(samples: number) {\r\n        if (this._samples === samples) {\r\n            return;\r\n        }\r\n\r\n        this._samples = samples;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    private _compositeMode = false;\r\n\r\n    /**\r\n     * If compositeMode is true (default: false), when the alpha value of the background (the scene rendered without the fluid objects) is 0, the final alpha value of the pixel will be set to the thickness value.\r\n     * This way, it is possible to composite the fluid rendering on top of the HTML background.\r\n     */\r\n    public get compositeMode() {\r\n        return this._compositeMode;\r\n    }\r\n\r\n    public set compositeMode(value: boolean) {\r\n        if (this._compositeMode === value) {\r\n            return;\r\n        }\r\n\r\n        this._compositeMode = value;\r\n        this._needInitialization = true;\r\n    }\r\n\r\n    /**\r\n     * Gets the camera used for the rendering\r\n     */\r\n    public get camera() {\r\n        return this._camera;\r\n    }\r\n\r\n    /** @internal */\r\n    public _renderPostProcess: Nullable<PostProcess>;\r\n\r\n    /** @internal */\r\n    public _depthRenderTarget: Nullable<FluidRenderingTextures>;\r\n\r\n    /** @internal */\r\n    public _diffuseRenderTarget: Nullable<FluidRenderingTextures>;\r\n\r\n    /** @internal */\r\n    public _thicknessRenderTarget: Nullable<FluidRenderingTextures>;\r\n\r\n    /** Shader language used by the renderer */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this renderer\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Creates an instance of the class\r\n     * @param scene Scene used to render the fluid object into\r\n     * @param camera Camera used to render the fluid object. If not provided, use the active camera of the scene instead\r\n     * @param shaderLanguage The shader language to use\r\n     */\r\n    constructor(scene: Scene, camera?: Camera, shaderLanguage?: ShaderLanguage) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._camera = camera ?? scene.activeCamera;\r\n        this._needInitialization = true;\r\n        this._bgDepthTexture = null;\r\n\r\n        this._invProjectionMatrix = new Matrix();\r\n        this._depthClearColor = new Color4(1e6, 1e6, 1e6, 1);\r\n        this._thicknessClearColor = new Color4(0, 0, 0, 1);\r\n\r\n        this._depthRenderTarget = null;\r\n        this._diffuseRenderTarget = null;\r\n        this._thicknessRenderTarget = null;\r\n\r\n        this._renderPostProcess = null;\r\n\r\n        this._shaderLanguage = shaderLanguage ?? (this._engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL);\r\n    }\r\n\r\n    /** @internal */\r\n    public _initialize(): void {\r\n        this.dispose();\r\n\r\n        this._needInitialization = false;\r\n\r\n        const depthWidth = this._depthMapSize ?? this._engine.getRenderWidth();\r\n        const depthHeight =\r\n            this._depthMapSize !== null ? Math.round((this._depthMapSize * this._engine.getRenderHeight()) / this._engine.getRenderWidth()) : this._engine.getRenderHeight();\r\n\r\n        this._depthRenderTarget = new FluidRenderingTextures(\r\n            \"Depth\",\r\n            this._scene,\r\n            depthWidth,\r\n            depthHeight,\r\n            depthWidth,\r\n            depthHeight,\r\n            Constants.TEXTURETYPE_FLOAT,\r\n            Constants.TEXTUREFORMAT_RG,\r\n            Constants.TEXTURETYPE_FLOAT,\r\n            Constants.TEXTUREFORMAT_RG,\r\n            false,\r\n            this._camera,\r\n            true,\r\n            this._samples,\r\n            this._shaderLanguage\r\n        );\r\n\r\n        this._initializeRenderTarget(this._depthRenderTarget);\r\n\r\n        if (this.generateDiffuseTexture) {\r\n            const diffuseWidth = this._diffuseMapSize ?? this._engine.getRenderWidth();\r\n            const diffuseHeight =\r\n                this._diffuseMapSize !== null\r\n                    ? Math.round((this._diffuseMapSize * this._engine.getRenderHeight()) / this._engine.getRenderWidth())\r\n                    : this._engine.getRenderHeight();\r\n\r\n            this._diffuseRenderTarget = new FluidRenderingTextures(\r\n                \"Diffuse\",\r\n                this._scene,\r\n                diffuseWidth,\r\n                diffuseHeight,\r\n                0,\r\n                0,\r\n                Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                Constants.TEXTUREFORMAT_RGBA,\r\n                true,\r\n                this._camera,\r\n                true,\r\n                this._samples,\r\n                this._shaderLanguage\r\n            );\r\n\r\n            this._initializeRenderTarget(this._diffuseRenderTarget);\r\n        }\r\n\r\n        const thicknessWidth = this._thicknessMapSize ?? this._engine.getRenderWidth();\r\n        const thicknessHeight =\r\n            this._thicknessMapSize !== null\r\n                ? Math.round((this._thicknessMapSize * this._engine.getRenderHeight()) / this._engine.getRenderWidth())\r\n                : this._engine.getRenderHeight();\r\n\r\n        if (!this._useFixedThickness) {\r\n            this._thicknessRenderTarget = new FluidRenderingTextures(\r\n                \"Thickness\",\r\n                this._scene,\r\n                thicknessWidth,\r\n                thicknessHeight,\r\n                thicknessWidth,\r\n                thicknessHeight,\r\n                Constants.TEXTURETYPE_HALF_FLOAT,\r\n                Constants.TEXTUREFORMAT_R,\r\n                Constants.TEXTURETYPE_HALF_FLOAT,\r\n                Constants.TEXTUREFORMAT_R,\r\n                true,\r\n                this._camera,\r\n                false,\r\n                this._samples,\r\n                this._shaderLanguage\r\n            );\r\n\r\n            this._initializeRenderTarget(this._thicknessRenderTarget);\r\n        }\r\n\r\n        this._createLiquidRenderingPostProcess();\r\n    }\r\n\r\n    protected _setBlurParameters(renderTarget: Nullable<FluidRenderingTextures> = null): void {\r\n        if (renderTarget === null || renderTarget === this._depthRenderTarget) {\r\n            this._setBlurDepthParameters();\r\n        }\r\n        if (renderTarget === null || renderTarget === this._thicknessRenderTarget) {\r\n            this._setBlurThicknessParameters();\r\n        }\r\n    }\r\n\r\n    protected _setBlurDepthParameters(): void {\r\n        if (!this._depthRenderTarget) {\r\n            return;\r\n        }\r\n        this._depthRenderTarget.blurFilterSize = this.blurDepthFilterSize;\r\n        this._depthRenderTarget.blurMaxFilterSize = this.blurDepthMaxFilterSize;\r\n        this._depthRenderTarget.blurNumIterations = this.blurDepthNumIterations;\r\n        this._depthRenderTarget.blurDepthScale = this.blurDepthDepthScale;\r\n    }\r\n\r\n    protected _setBlurThicknessParameters(): void {\r\n        if (!this._thicknessRenderTarget) {\r\n            return;\r\n        }\r\n        this._thicknessRenderTarget.blurFilterSize = this.blurThicknessFilterSize;\r\n        this._thicknessRenderTarget.blurNumIterations = this.blurThicknessNumIterations;\r\n    }\r\n\r\n    protected _initializeRenderTarget(renderTarget: FluidRenderingTextures): void {\r\n        if (renderTarget !== this._diffuseRenderTarget) {\r\n            renderTarget.enableBlur = renderTarget === this._depthRenderTarget ? this.enableBlurDepth : this.enableBlurThickness;\r\n            renderTarget.blurSizeDivisor = renderTarget === this._depthRenderTarget ? this.blurDepthSizeDivisor : this.blurThicknessSizeDivisor;\r\n        }\r\n\r\n        this._setBlurParameters(renderTarget);\r\n\r\n        renderTarget.initialize();\r\n    }\r\n\r\n    protected _createLiquidRenderingPostProcess(): void {\r\n        const engine = this._scene.getEngine();\r\n\r\n        const uniformNames = [\r\n            \"viewMatrix\",\r\n            \"projectionMatrix\",\r\n            \"invProjectionMatrix\",\r\n            \"texelSize\",\r\n            \"dirLight\",\r\n            \"cameraFar\",\r\n            \"density\",\r\n            \"refractionStrength\",\r\n            \"fresnelClamp\",\r\n            \"specularPower\",\r\n        ];\r\n        const samplerNames = [\"depthSampler\"];\r\n        const defines = [];\r\n\r\n        this.dispose(true);\r\n\r\n        if (!this._camera) {\r\n            return;\r\n        }\r\n\r\n        const texture = this._depthRenderTarget!.enableBlur ? this._depthRenderTarget!.textureBlur! : this._depthRenderTarget!.texture!;\r\n        const texelSize = new Vector2(1 / texture.getSize().width, 1 / texture.getSize().height);\r\n\r\n        if (this._scene.useRightHandedSystem) {\r\n            defines.push(\"#define FLUIDRENDERING_RHS\");\r\n        }\r\n\r\n        if (this._environmentMap !== null) {\r\n            const envMap = this._environmentMap ?? this._scene.environmentTexture;\r\n            if (envMap) {\r\n                samplerNames.push(\"reflectionSampler\");\r\n                defines.push(\"#define FLUIDRENDERING_ENVIRONMENT\");\r\n            }\r\n        }\r\n\r\n        if (this._diffuseRenderTarget) {\r\n            samplerNames.push(\"diffuseSampler\");\r\n            defines.push(\"#define FLUIDRENDERING_DIFFUSETEXTURE\");\r\n        } else {\r\n            uniformNames.push(\"diffuseColor\");\r\n        }\r\n\r\n        if (this._useVelocity) {\r\n            samplerNames.push(\"velocitySampler\");\r\n            defines.push(\"#define FLUIDRENDERING_VELOCITY\");\r\n        }\r\n\r\n        if (this._useFixedThickness) {\r\n            uniformNames.push(\"thickness\");\r\n            samplerNames.push(\"bgDepthSampler\");\r\n            defines.push(\"#define FLUIDRENDERING_FIXED_THICKNESS\");\r\n        } else {\r\n            uniformNames.push(\"minimumThickness\");\r\n            samplerNames.push(\"thicknessSampler\");\r\n        }\r\n\r\n        if (this._compositeMode) {\r\n            defines.push(\"#define FLUIDRENDERING_COMPOSITE_MODE\");\r\n        }\r\n\r\n        if (this._debug) {\r\n            defines.push(\"#define FLUIDRENDERING_DEBUG\");\r\n            if (this._debugFeature === FluidRenderingDebug.Normals) {\r\n                defines.push(\"#define FLUIDRENDERING_DEBUG_SHOWNORMAL\");\r\n            } else if (this._debugFeature === FluidRenderingDebug.DiffuseRendering) {\r\n                defines.push(\"#define FLUIDRENDERING_DEBUG_DIFFUSERENDERING\");\r\n            } else {\r\n                defines.push(\"#define FLUIDRENDERING_DEBUG_TEXTURE\");\r\n                samplerNames.push(\"debugSampler\");\r\n                if (this._debugFeature === FluidRenderingDebug.DepthTexture || this._debugFeature === FluidRenderingDebug.DepthBlurredTexture) {\r\n                    defines.push(\"#define FLUIDRENDERING_DEBUG_DEPTH\");\r\n                }\r\n            }\r\n        }\r\n\r\n        this._renderPostProcess = new PostProcess(\r\n            \"FluidRendering\",\r\n            \"fluidRenderingRender\",\r\n            uniformNames,\r\n            samplerNames,\r\n            1,\r\n            null,\r\n            Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n            engine,\r\n            false,\r\n            null,\r\n            Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n            undefined,\r\n            undefined,\r\n            true,\r\n            undefined,\r\n            this._shaderLanguage,\r\n            // eslint-disable-next-line @typescript-eslint/no-misused-promises\r\n            async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await import(\"../../ShadersWGSL/fluidRenderingRender.fragment\");\r\n                } else {\r\n                    await import(\"../../Shaders/fluidRenderingRender.fragment\");\r\n                }\r\n            }\r\n        );\r\n        this._renderPostProcess.updateEffect(defines.join(\"\\n\"));\r\n\r\n        this._renderPostProcess.samples = this._samples;\r\n        const engineWebGPU = engine as WebGPUEngine;\r\n        const setTextureSampler = engineWebGPU.setTextureSampler;\r\n        this._renderPostProcess.onApplyObservable.add((effect) => {\r\n            this._invProjectionMatrix.copyFrom(this._scene.getProjectionMatrix());\r\n            this._invProjectionMatrix.invert();\r\n\r\n            if (setTextureSampler) {\r\n                setTextureSampler.call(engineWebGPU, \"textureSamplerSampler\", this._renderPostProcess!.inputTexture.texture);\r\n            }\r\n\r\n            if (!this._depthRenderTarget!.enableBlur) {\r\n                effect.setTexture(\"depthSampler\", this._depthRenderTarget!.texture);\r\n                if (setTextureSampler) {\r\n                    setTextureSampler.call(engineWebGPU, \"depthSamplerSampler\", this._depthRenderTarget!.texture?.getInternalTexture() ?? null);\r\n                }\r\n            } else {\r\n                effect.setTexture(\"depthSampler\", this._depthRenderTarget!.textureBlur);\r\n                if (setTextureSampler) {\r\n                    setTextureSampler.call(engineWebGPU, \"depthSamplerSampler\", this._depthRenderTarget!.textureBlur?.getInternalTexture() ?? null);\r\n                }\r\n            }\r\n            if (this._diffuseRenderTarget) {\r\n                if (!this._diffuseRenderTarget.enableBlur) {\r\n                    effect.setTexture(\"diffuseSampler\", this._diffuseRenderTarget.texture);\r\n                    if (setTextureSampler) {\r\n                        setTextureSampler.call(engineWebGPU, \"diffuseSamplerSampler\", this._diffuseRenderTarget.texture?.getInternalTexture() ?? null);\r\n                    }\r\n                } else {\r\n                    effect.setTexture(\"diffuseSampler\", this._diffuseRenderTarget.textureBlur);\r\n                    if (setTextureSampler) {\r\n                        setTextureSampler.call(engineWebGPU, \"diffuseSamplerSampler\", this._diffuseRenderTarget.textureBlur?.getInternalTexture() ?? null);\r\n                    }\r\n                }\r\n            } else {\r\n                effect.setColor3(\"diffuseColor\", this.fluidColor);\r\n            }\r\n            if (this._useFixedThickness) {\r\n                effect.setFloat(\"thickness\", this.minimumThickness);\r\n                effect._bindTexture(\"bgDepthSampler\", this._bgDepthTexture);\r\n                if (setTextureSampler) {\r\n                    setTextureSampler.call(engineWebGPU, \"bgDepthSamplerSampler\", this._bgDepthTexture ?? null);\r\n                }\r\n            } else {\r\n                if (!this._thicknessRenderTarget!.enableBlur) {\r\n                    effect.setTexture(\"thicknessSampler\", this._thicknessRenderTarget!.texture);\r\n                    if (setTextureSampler) {\r\n                        setTextureSampler.call(engineWebGPU, \"thicknessSamplerSampler\", this._thicknessRenderTarget!.texture?.getInternalTexture() ?? null);\r\n                    }\r\n                } else {\r\n                    effect.setTexture(\"thicknessSampler\", this._thicknessRenderTarget!.textureBlur);\r\n                    if (setTextureSampler) {\r\n                        setTextureSampler.call(engineWebGPU, \"thicknessSamplerSampler\", this._thicknessRenderTarget!.textureBlur?.getInternalTexture() ?? null);\r\n                    }\r\n                }\r\n                effect.setFloat(\"minimumThickness\", this.minimumThickness);\r\n            }\r\n\r\n            if (this._environmentMap !== null) {\r\n                const envMap = this._environmentMap ?? this._scene.environmentTexture;\r\n                if (envMap) {\r\n                    effect.setTexture(\"reflectionSampler\", envMap);\r\n                    if (setTextureSampler) {\r\n                        setTextureSampler.call(engineWebGPU, \"reflectionSamplerSampler\", envMap?.getInternalTexture() ?? null);\r\n                    }\r\n                }\r\n            }\r\n\r\n            effect.setMatrix(\"viewMatrix\", this._scene.getViewMatrix());\r\n            effect.setMatrix(\"invProjectionMatrix\", this._invProjectionMatrix);\r\n            effect.setMatrix(\"projectionMatrix\", this._scene.getProjectionMatrix());\r\n            effect.setVector2(\"texelSize\", texelSize);\r\n            effect.setFloat(\"density\", this.density);\r\n            effect.setFloat(\"refractionStrength\", this.refractionStrength);\r\n            effect.setFloat(\"fresnelClamp\", this.fresnelClamp);\r\n            effect.setFloat(\"specularPower\", this.specularPower);\r\n\r\n            effect.setVector3(\"dirLight\", this.dirLight);\r\n\r\n            effect.setFloat(\"cameraFar\", this._camera!.maxZ);\r\n\r\n            if (this._debug) {\r\n                let texture: Nullable<ThinTexture> = null;\r\n                switch (this._debugFeature) {\r\n                    case FluidRenderingDebug.DepthTexture:\r\n                        texture = this._depthRenderTarget!.texture;\r\n                        break;\r\n                    case FluidRenderingDebug.DepthBlurredTexture:\r\n                        texture = this._depthRenderTarget!.enableBlur ? this._depthRenderTarget!.textureBlur : this._depthRenderTarget!.texture;\r\n                        break;\r\n                    case FluidRenderingDebug.ThicknessTexture:\r\n                        texture = this._thicknessRenderTarget?.texture ?? null;\r\n                        break;\r\n                    case FluidRenderingDebug.ThicknessBlurredTexture:\r\n                        texture = this._thicknessRenderTarget?.enableBlur ? (this._thicknessRenderTarget?.textureBlur ?? null) : (this._thicknessRenderTarget?.texture ?? null);\r\n                        break;\r\n                    case FluidRenderingDebug.DiffuseTexture:\r\n                        if (this._diffuseRenderTarget) {\r\n                            texture = this._diffuseRenderTarget.texture;\r\n                        }\r\n                        break;\r\n                }\r\n                if (this._debugFeature !== FluidRenderingDebug.Normals) {\r\n                    effect.setTexture(\"debugSampler\", texture);\r\n                    if (setTextureSampler) {\r\n                        setTextureSampler.call(engineWebGPU, \"debugSamplerSampler\", texture?.getInternalTexture() ?? null);\r\n                    }\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /** @internal */\r\n    public _clearTargets(): void {\r\n        if (this._depthRenderTarget?.renderTarget) {\r\n            this._engine.bindFramebuffer(this._depthRenderTarget.renderTarget);\r\n            this._engine.clear(this._depthClearColor, true, true, false);\r\n            this._engine.unBindFramebuffer(this._depthRenderTarget.renderTarget);\r\n        }\r\n\r\n        if (this._diffuseRenderTarget?.renderTarget) {\r\n            this._engine.bindFramebuffer(this._diffuseRenderTarget.renderTarget);\r\n            this._engine.clear(this._thicknessClearColor, true, true, false);\r\n            this._engine.unBindFramebuffer(this._diffuseRenderTarget.renderTarget);\r\n        }\r\n\r\n        if (this._thicknessRenderTarget?.renderTarget) {\r\n            this._engine.bindFramebuffer(this._thicknessRenderTarget.renderTarget);\r\n            // we don't clear the depth buffer because it is the depth buffer that is coming from the scene and that we reuse in the thickness rendering pass\r\n            this._engine.clear(this._thicknessClearColor, true, false, false);\r\n            this._engine.unBindFramebuffer(this._thicknessRenderTarget.renderTarget);\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _render(fluidObject: FluidRenderingObject): void {\r\n        if (this._needInitialization || !fluidObject.isReady()) {\r\n            return;\r\n        }\r\n\r\n        const currentRenderTarget = this._engine._currentRenderTarget;\r\n\r\n        this._engine.setState(false, undefined, undefined, undefined, true);\r\n        this._engine.setDepthBuffer(true);\r\n        this._engine.setDepthWrite(true);\r\n        this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n        // Render the particles in the depth texture\r\n        if (this._depthRenderTarget?.renderTarget) {\r\n            this._engine.bindFramebuffer(this._depthRenderTarget.renderTarget);\r\n\r\n            fluidObject.renderDepthTexture();\r\n\r\n            this._engine.unbindInstanceAttributes();\r\n            this._engine.unBindFramebuffer(this._depthRenderTarget.renderTarget);\r\n        }\r\n\r\n        // Render the particles in the diffuse texture\r\n        if (this._diffuseRenderTarget?.renderTarget) {\r\n            this._engine.bindFramebuffer(this._diffuseRenderTarget.renderTarget);\r\n\r\n            fluidObject.renderDiffuseTexture();\r\n\r\n            this._engine.unbindInstanceAttributes();\r\n            this._engine.unBindFramebuffer(this._diffuseRenderTarget.renderTarget);\r\n        }\r\n\r\n        // Render the particles in the thickness texture\r\n        if (this._thicknessRenderTarget?.renderTarget) {\r\n            this._engine.bindFramebuffer(this._thicknessRenderTarget.renderTarget);\r\n\r\n            fluidObject.renderThicknessTexture();\r\n\r\n            this._engine.unbindInstanceAttributes();\r\n            this._engine.unBindFramebuffer(this._thicknessRenderTarget.renderTarget);\r\n        }\r\n\r\n        // Run the blur post processes\r\n        this._depthRenderTarget?.applyBlurPostProcesses();\r\n        this._diffuseRenderTarget?.applyBlurPostProcesses();\r\n        this._thicknessRenderTarget?.applyBlurPostProcesses();\r\n\r\n        if (currentRenderTarget) {\r\n            this._engine.bindFramebuffer(currentRenderTarget);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases all the resources used by the class\r\n     * @param onlyPostProcesses If true, releases only the resources used by the render post processes\r\n     */\r\n    public dispose(onlyPostProcesses = false): void {\r\n        if (!onlyPostProcesses) {\r\n            this._depthRenderTarget?.dispose();\r\n            this._depthRenderTarget = null;\r\n\r\n            this._diffuseRenderTarget?.dispose();\r\n            this._diffuseRenderTarget = null;\r\n\r\n            this._thicknessRenderTarget?.dispose();\r\n            this._thicknessRenderTarget = null;\r\n        }\r\n\r\n        if (this._renderPostProcess && this._camera) {\r\n            this._camera.detachPostProcess(this._renderPostProcess);\r\n        }\r\n        this._renderPostProcess?.dispose();\r\n        this._renderPostProcess = null;\r\n\r\n        this._onUseVelocityChanged.clear();\r\n\r\n        this._needInitialization = false;\r\n    }\r\n}\r\n","import { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer.pure\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type FloatArray, type Nullable } from \"core/types\";\r\n\r\nimport { FluidRenderingObject } from \"./fluidRenderingObject\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\n/**\r\n * Defines a rendering object based on a list of custom buffers\r\n * The list must contain at least a \"position\" buffer!\r\n */\r\nexport class FluidRenderingObjectCustomParticles extends FluidRenderingObject {\r\n    private _numParticles: number;\r\n    private _diffuseEffectWrapper: Nullable<EffectWrapper>;\r\n    private _vertexBuffers: { [key: string]: VertexBuffer };\r\n\r\n    /**\r\n     * @returns the name of the class\r\n     */\r\n    public override getClassName(): string {\r\n        return \"FluidRenderingObjectCustomParticles\";\r\n    }\r\n\r\n    /**\r\n     * Gets the vertex buffers\r\n     */\r\n    public get vertexBuffers(): { [key: string]: VertexBuffer } {\r\n        return this._vertexBuffers;\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance of the class\r\n     * @param scene The scene the particles should be rendered into\r\n     * @param buffers The list of buffers (must contain at least one \"position\" buffer!). Note that you don't have to pass all (or any!) buffers at once in the constructor, you can use the addBuffers method to add more later.\r\n     * @param numParticles Number of vertices to take into account from the buffers\r\n     * @param shaderLanguage The shader language to use\r\n     */\r\n    constructor(scene: Scene, buffers: { [key: string]: FloatArray }, numParticles: number, shaderLanguage?: ShaderLanguage) {\r\n        super(scene, shaderLanguage);\r\n\r\n        this._numParticles = numParticles;\r\n        this._diffuseEffectWrapper = null;\r\n        this._vertexBuffers = {};\r\n\r\n        this.addBuffers(buffers);\r\n    }\r\n\r\n    /**\r\n     * Add some new buffers\r\n     * @param buffers List of buffers\r\n     */\r\n    public addBuffers(buffers: { [key: string]: FloatArray }) {\r\n        for (const name in buffers) {\r\n            let stride: number | undefined;\r\n            let instanced = true;\r\n\r\n            switch (name) {\r\n                case \"velocity\":\r\n                    stride = 3;\r\n                    break;\r\n                case \"size\":\r\n                    stride = 2;\r\n                    this._effectsAreDirty = true;\r\n                    break;\r\n                case \"offset\":\r\n                    instanced = false;\r\n                    break;\r\n            }\r\n\r\n            this._vertexBuffers[name] = new VertexBuffer(this._engine, buffers[name], name, true, false, stride, instanced);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Per-particle sizing needs an actual \"size\" buffer; custom buffers are optional.\r\n     * @returns true if a \"size\" buffer was supplied\r\n     */\r\n    protected override _supportsPerParticleSizeAttribute(): boolean {\r\n        return !!this._vertexBuffers[\"size\"];\r\n    }\r\n\r\n    protected override _createEffects(): void {\r\n        super._createEffects();\r\n\r\n        const uniformNames = this._usesPerParticleSizeAttribute ? [\"view\", \"projection\"] : [\"view\", \"projection\", \"size\"];\r\n        const attributeNames = this._usesPerParticleSizeAttribute ? [\"position\", \"offset\", \"color\", \"size\"] : [\"position\", \"offset\", \"color\"];\r\n        const defines = this._usesPerParticleSizeAttribute ? [\"#define FLUIDRENDERING_PER_PARTICLE_SIZE\"] : [];\r\n\r\n        this._diffuseEffectWrapper = new EffectWrapper({\r\n            engine: this._engine,\r\n            useShaderStore: true,\r\n            vertexShader: \"fluidRenderingParticleDiffuse\",\r\n            fragmentShader: \"fluidRenderingParticleDiffuse\",\r\n            attributeNames,\r\n            uniformNames,\r\n            samplerNames: [],\r\n            defines,\r\n            shaderLanguage: this._shaderLanguage,\r\n            extraInitializationsAsync: async () => {\r\n                if (this._shaderLanguage === ShaderLanguage.WGSL) {\r\n                    await import(\"../../ShadersWGSL/fluidRenderingParticleDiffuse.fragment\");\r\n                } else {\r\n                    await import(\"../../Shaders/fluidRenderingParticleDiffuse.fragment\");\r\n                }\r\n            },\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Indicates if the object is ready to be rendered\r\n     * @returns True if everything is ready for the object to be rendered, otherwise false\r\n     */\r\n    public override isReady(): boolean {\r\n        if (!this._vertexBuffers[\"offset\"]) {\r\n            this._vertexBuffers[\"offset\"] = new VertexBuffer(this._engine, [0, 0, 1, 0, 0, 1, 1, 1], \"offset\", false, false, 2);\r\n        }\r\n\r\n        return super.isReady() && (this._diffuseEffectWrapper?.effect!.isReady() ?? false);\r\n    }\r\n\r\n    /**\r\n     * Gets the number of particles in this object\r\n     * @returns The number of particles\r\n     */\r\n    public get numParticles(): number {\r\n        return this._numParticles;\r\n    }\r\n\r\n    /**\r\n     * Sets the number of particles in this object\r\n     * @param num The number of particles to take into account\r\n     */\r\n    public setNumParticles(num: number) {\r\n        this._numParticles = num;\r\n    }\r\n\r\n    /**\r\n     * Render the diffuse texture for this object\r\n     */\r\n    public override renderDiffuseTexture(): void {\r\n        const numParticles = this.numParticles;\r\n\r\n        if (!this._diffuseEffectWrapper || numParticles === 0) {\r\n            return;\r\n        }\r\n\r\n        const diffuseDrawWrapper = this._diffuseEffectWrapper.drawWrapper;\r\n        const diffuseEffect = diffuseDrawWrapper.effect!;\r\n\r\n        this._engine.enableEffect(diffuseDrawWrapper);\r\n        this._engine.bindBuffers(this.vertexBuffers, this.indexBuffer, diffuseEffect);\r\n\r\n        diffuseEffect.setMatrix(\"view\", this._scene.getViewMatrix());\r\n        diffuseEffect.setMatrix(\"projection\", this._scene.getProjectionMatrix());\r\n        if (!this._usesPerParticleSizeAttribute) {\r\n            diffuseEffect.setFloat2(\"size\", this._particleSize, this._particleSize);\r\n        }\r\n\r\n        if (this.useInstancing) {\r\n            this._engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, numParticles);\r\n        } else {\r\n            this._engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, numParticles);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Releases the resources used by the class\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        this._diffuseEffectWrapper?.dispose();\r\n\r\n        for (const name in this._vertexBuffers) {\r\n            this._vertexBuffers[name].dispose();\r\n        }\r\n\r\n        this._vertexBuffers = {};\r\n    }\r\n}\r\n","import { Constants } from \"core/Engines/constants\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { type RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\r\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { CopyTextureToTexture } from \"core/Misc/copyTextureToTexture\";\r\n\r\n/** @internal */\r\nexport class FluidRenderingDepthTextureCopy {\r\n    private _engine: AbstractEngine;\r\n    private _depthRTWrapper: RenderTargetWrapper;\r\n    private _copyTextureToTexture: CopyTextureToTexture;\r\n\r\n    public get depthRTWrapper() {\r\n        return this._depthRTWrapper;\r\n    }\r\n\r\n    constructor(engine: AbstractEngine, width: number, height: number, samples = 1) {\r\n        this._engine = engine;\r\n        this._copyTextureToTexture = new CopyTextureToTexture(engine, true);\r\n\r\n        this._depthRTWrapper = this._engine.createRenderTargetTexture(\r\n            { width, height },\r\n            {\r\n                generateMipMaps: false,\r\n                type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n                format: Constants.TEXTUREFORMAT_R,\r\n                samplingMode: Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n                generateDepthBuffer: true,\r\n                generateStencilBuffer: false,\r\n                samples,\r\n                noColorAttachment: true,\r\n                label: \"FluidRenderingDepthTextureCopyRTT\",\r\n            }\r\n        );\r\n        const depthTexture = this._depthRTWrapper.createDepthStencilTexture(0, false, false, 1, undefined, \"FluidRenderingDepthTextureCopyRTTDepthStencil\");\r\n        depthTexture.label = `FluidDepthTextureCopy${width}x${height}x${samples}`;\r\n    }\r\n\r\n    public copy(source: InternalTexture): boolean {\r\n        return this._copyTextureToTexture.copy(source, this._depthRTWrapper);\r\n    }\r\n\r\n    public dispose() {\r\n        this._depthRTWrapper.dispose();\r\n        this._copyTextureToTexture.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Scene } from \"core/scene.pure\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { RegisterAbstractEngineTexture } from \"core/Engines/AbstractEngine/abstractEngine.texture.pure\";\r\nimport { type FloatArray, type Nullable } from \"core/types\";\r\nimport { type Observer } from \"core/Misc/observable.pure\";\r\nimport { type Camera } from \"core/Cameras/camera.pure\";\r\nimport { type IParticleSystem } from \"core/Particles/IParticleSystem\";\r\nimport { SceneComponentConstants, type ISceneComponent } from \"core/sceneComponent\";\r\n\r\nimport { type SmartArrayNoDuplicate } from \"core/Misc/smartArray\";\r\nimport { type RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type Buffer } from \"core/Buffers/buffer.pure\";\r\nimport { type FluidRenderingObject } from \"./fluidRenderingObject\";\r\nimport { FluidRenderingObjectParticleSystem } from \"./fluidRenderingObjectParticleSystem\";\r\nimport { FluidRenderingTargetRenderer } from \"./fluidRenderingTargetRenderer\";\r\nimport { FluidRenderingObjectCustomParticles } from \"./fluidRenderingObjectCustomParticles\";\r\nimport { FluidRenderingDepthTextureCopy } from \"./fluidRenderingDepthTextureCopy\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\n\r\ntype CameraMapForFluidRendering = [Array<FluidRenderingTargetRenderer>, { [key: string]: FluidRenderingDepthTextureCopy }];\r\n\r\nfunction IsParticleSystemObject(obj: FluidRenderingObject): obj is FluidRenderingObjectParticleSystem {\r\n    return !!(obj as FluidRenderingObjectParticleSystem).particleSystem;\r\n}\r\n\r\nfunction IsCustomParticlesObject(obj: FluidRenderingObject): obj is FluidRenderingObjectCustomParticles {\r\n    return !!(obj as FluidRenderingObjectCustomParticles).addBuffers;\r\n}\r\n\r\n/**\r\n * Defines the fluid renderer scene component responsible to render objects as fluids\r\n */\r\nexport class FluidRendererSceneComponent implements ISceneComponent {\r\n    /**\r\n     * The component name helpful to identify the component in the list of scene components.\r\n     */\r\n    public readonly name = SceneComponentConstants.NAME_FLUIDRENDERER;\r\n\r\n    /**\r\n     * The scene the component belongs to.\r\n     */\r\n    public scene: Scene;\r\n\r\n    /**\r\n     * Creates a new instance of the component for the given scene\r\n     * @param scene Defines the scene to register the component in\r\n     */\r\n    constructor(scene: Scene) {\r\n        this.scene = scene;\r\n    }\r\n\r\n    /**\r\n     * Registers the component in a given scene\r\n     */\r\n    public register(): void {\r\n        this.scene._gatherActiveCameraRenderTargetsStage.registerStep(\r\n            SceneComponentConstants.STEP_GATHERACTIVECAMERARENDERTARGETS_FLUIDRENDERER,\r\n            this,\r\n            this._gatherActiveCameraRenderTargets\r\n        );\r\n        this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_FLUIDRENDERER, this, this._afterCameraDraw);\r\n    }\r\n\r\n    private _gatherActiveCameraRenderTargets(_renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {\r\n        this.scene.fluidRenderer?._prepareRendering();\r\n    }\r\n\r\n    private _afterCameraDraw(camera: Camera) {\r\n        this.scene.fluidRenderer?._render(camera);\r\n    }\r\n\r\n    /**\r\n     * Rebuilds the elements related to this component in case of\r\n     * context lost for instance.\r\n     */\r\n    public rebuild(): void {\r\n        const fluidRenderer = this.scene.fluidRenderer;\r\n        if (!fluidRenderer) {\r\n            return;\r\n        }\r\n\r\n        const buffers = new Set<Buffer>();\r\n        for (let i = 0; i < fluidRenderer.renderObjects.length; ++i) {\r\n            const obj = fluidRenderer.renderObjects[i].object;\r\n            if (IsCustomParticlesObject(obj)) {\r\n                const vbuffers = obj.vertexBuffers;\r\n                for (const name in vbuffers) {\r\n                    buffers.add(vbuffers[name].getWrapperBuffer());\r\n                }\r\n            }\r\n        }\r\n\r\n        buffers.forEach((buffer) => {\r\n            buffer._rebuild();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Disposes the component and the associated resources\r\n     */\r\n    public dispose(): void {\r\n        this.scene.disableFluidRenderer();\r\n    }\r\n}\r\n\r\n/**\r\n * An object rendered as a fluid.\r\n * It consists of the object itself as well as the render target renderer (which is used to generate the textures (render target) needed for fluid rendering)\r\n */\r\nexport interface IFluidRenderingRenderObject {\r\n    /** object rendered as a fluid */\r\n    object: FluidRenderingObject;\r\n    /** target renderer used to render the fluid object */\r\n    targetRenderer: FluidRenderingTargetRenderer;\r\n}\r\n\r\n/**\r\n * Class responsible for fluid rendering.\r\n * It is implementing the method described in https://developer.download.nvidia.com/presentations/2010/gdc/Direct3D_Effects.pdf\r\n */\r\nexport class FluidRenderer {\r\n    /** @internal */\r\n    public static _SceneComponentInitialization(scene: Scene) {\r\n        let component = scene._getComponent(SceneComponentConstants.NAME_FLUIDRENDERER) as FluidRendererSceneComponent;\r\n        if (!component) {\r\n            component = new FluidRendererSceneComponent(scene);\r\n            scene._addComponent(component);\r\n        }\r\n    }\r\n\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n    private _onEngineResizeObserver: Nullable<Observer<AbstractEngine>>;\r\n    private _cameras: Map<Camera, CameraMapForFluidRendering>;\r\n\r\n    /** Retrieves all the render objects managed by the class */\r\n    public readonly renderObjects: Array<IFluidRenderingRenderObject>;\r\n\r\n    /** Retrieves all the render target renderers managed by the class */\r\n    public readonly targetRenderers: FluidRenderingTargetRenderer[];\r\n\r\n    /** Shader language used by the renderer */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /**\r\n     * Gets the shader language used in this renderer\r\n     */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Initializes the class\r\n     * @param scene Scene in which the objects are part of\r\n     */\r\n    constructor(scene: Scene) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._onEngineResizeObserver = null;\r\n        this.renderObjects = [];\r\n        this.targetRenderers = [];\r\n        this._cameras = new Map();\r\n\r\n        FluidRenderer._SceneComponentInitialization(this._scene);\r\n\r\n        this._onEngineResizeObserver = this._engine.onResizeObservable.add(() => {\r\n            this._initialize();\r\n        });\r\n\r\n        const engine = this._engine;\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Reinitializes the class\r\n     * Can be used if you change the object priority (FluidRenderingObject.priority), to make sure the objects are rendered in the right order\r\n     */\r\n    public recreate(): void {\r\n        this._sortRenderingObjects();\r\n        this._initialize();\r\n    }\r\n\r\n    /**\r\n     * Gets the render object corresponding to a particle system (null if the particle system is not rendered as a fluid)\r\n     * @param ps The particle system\r\n     * @returns the render object corresponding to this particle system if any, otherwise null\r\n     */\r\n    public getRenderObjectFromParticleSystem(ps: IParticleSystem): Nullable<IFluidRenderingRenderObject> {\r\n        const index = this._getParticleSystemIndex(ps);\r\n        return index !== -1 ? this.renderObjects[index] : null;\r\n    }\r\n\r\n    /**\r\n     * Adds a particle system to the fluid renderer.\r\n     * @param ps particle system\r\n     * @param generateDiffuseTexture True if you want to generate a diffuse texture from the particle system and use it as part of the fluid rendering (default: false)\r\n     * @param targetRenderer The target renderer used to display the particle system as a fluid. If not provided, the method will create a new one\r\n     * @param camera The camera used by the target renderer (if the target renderer is created by the method)\r\n     * @returns the render object corresponding to the particle system\r\n     */\r\n    public addParticleSystem(ps: IParticleSystem, generateDiffuseTexture?: boolean, targetRenderer?: FluidRenderingTargetRenderer, camera?: Camera): IFluidRenderingRenderObject {\r\n        const object = new FluidRenderingObjectParticleSystem(this._scene, ps, this._shaderLanguage);\r\n\r\n        object.onParticleSizeChanged.add(() => this._setParticleSizeForRenderTargets());\r\n\r\n        if (!targetRenderer) {\r\n            targetRenderer = new FluidRenderingTargetRenderer(this._scene, camera, this._shaderLanguage);\r\n            this.targetRenderers.push(targetRenderer);\r\n        }\r\n\r\n        if (!targetRenderer._onUseVelocityChanged.hasObservers()) {\r\n            targetRenderer._onUseVelocityChanged.add(() => this._setUseVelocityForRenderObject());\r\n        }\r\n\r\n        if (generateDiffuseTexture !== undefined) {\r\n            targetRenderer.generateDiffuseTexture = generateDiffuseTexture;\r\n        }\r\n\r\n        const renderObject = { object, targetRenderer };\r\n\r\n        this.renderObjects.push(renderObject);\r\n\r\n        this._sortRenderingObjects();\r\n\r\n        this._setParticleSizeForRenderTargets();\r\n\r\n        return renderObject;\r\n    }\r\n\r\n    /**\r\n     * Adds a custom particle set to the fluid renderer.\r\n     * @param buffers The list of buffers (should contain at least a \"position\" buffer!)\r\n     * @param numParticles Number of particles in each buffer\r\n     * @param generateDiffuseTexture True if you want to generate a diffuse texture from buffers and use it as part of the fluid rendering (default: false). For the texture to be generated correctly, you need a \"color\" buffer in the set!\r\n     * @param targetRenderer The target renderer used to display the particle system as a fluid. If not provided, the method will create a new one\r\n     * @param camera The camera used by the target renderer (if the target renderer is created by the method)\r\n     * @returns the render object corresponding to the custom particle set\r\n     */\r\n    public addCustomParticles(\r\n        buffers: { [key: string]: FloatArray },\r\n        numParticles: number,\r\n        generateDiffuseTexture?: boolean,\r\n        targetRenderer?: FluidRenderingTargetRenderer,\r\n        camera?: Camera\r\n    ): IFluidRenderingRenderObject {\r\n        const object = new FluidRenderingObjectCustomParticles(this._scene, buffers, numParticles, this._shaderLanguage);\r\n\r\n        object.onParticleSizeChanged.add(() => this._setParticleSizeForRenderTargets());\r\n\r\n        if (!targetRenderer) {\r\n            targetRenderer = new FluidRenderingTargetRenderer(this._scene, camera, this._shaderLanguage);\r\n            this.targetRenderers.push(targetRenderer);\r\n        }\r\n\r\n        if (!targetRenderer._onUseVelocityChanged.hasObservers()) {\r\n            targetRenderer._onUseVelocityChanged.add(() => this._setUseVelocityForRenderObject());\r\n        }\r\n\r\n        if (generateDiffuseTexture !== undefined) {\r\n            targetRenderer.generateDiffuseTexture = generateDiffuseTexture;\r\n        }\r\n\r\n        const renderObject = { object, targetRenderer };\r\n\r\n        this.renderObjects.push(renderObject);\r\n\r\n        this._sortRenderingObjects();\r\n\r\n        this._setParticleSizeForRenderTargets();\r\n\r\n        return renderObject;\r\n    }\r\n\r\n    /**\r\n     * Removes a render object from the fluid renderer\r\n     * @param renderObject the render object to remove\r\n     * @param removeUnusedTargetRenderer True to remove/dispose of the target renderer if it's not used anymore (default: true)\r\n     * @returns True if the render object has been found and released, else false\r\n     */\r\n    public removeRenderObject(renderObject: IFluidRenderingRenderObject, removeUnusedTargetRenderer = true): boolean {\r\n        const index = this.renderObjects.indexOf(renderObject);\r\n        if (index === -1) {\r\n            return false;\r\n        }\r\n\r\n        renderObject.object.dispose();\r\n\r\n        this.renderObjects.splice(index, 1);\r\n\r\n        if (removeUnusedTargetRenderer && this._removeUnusedTargetRenderers()) {\r\n            this._initialize();\r\n        } else {\r\n            this._setParticleSizeForRenderTargets();\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private _sortRenderingObjects(): void {\r\n        this.renderObjects.sort((a, b) => {\r\n            return a.object.priority < b.object.priority ? -1 : a.object.priority > b.object.priority ? 1 : 0;\r\n        });\r\n    }\r\n\r\n    private _removeUnusedTargetRenderers(): boolean {\r\n        const indexes: { [id: number]: boolean } = {};\r\n\r\n        for (let i = 0; i < this.renderObjects.length; ++i) {\r\n            const targetRenderer = this.renderObjects[i].targetRenderer;\r\n            indexes[this.targetRenderers.indexOf(targetRenderer)] = true;\r\n        }\r\n\r\n        let removed = false;\r\n        const newList: Array<FluidRenderingTargetRenderer> = [];\r\n        for (let i = 0; i < this.targetRenderers.length; ++i) {\r\n            if (!indexes[i]) {\r\n                this.targetRenderers[i].dispose();\r\n                removed = true;\r\n            } else {\r\n                newList.push(this.targetRenderers[i]);\r\n            }\r\n        }\r\n\r\n        if (removed) {\r\n            this.targetRenderers.length = 0;\r\n            this.targetRenderers.push(...newList);\r\n        }\r\n\r\n        return removed;\r\n    }\r\n\r\n    private _getParticleSystemIndex(ps: IParticleSystem): number {\r\n        for (let i = 0; i < this.renderObjects.length; ++i) {\r\n            const obj = this.renderObjects[i].object;\r\n            if (IsParticleSystemObject(obj) && obj.particleSystem === ps) {\r\n                return i;\r\n            }\r\n        }\r\n\r\n        return -1;\r\n    }\r\n\r\n    private _initialize(): void {\r\n        for (let i = 0; i < this.targetRenderers.length; ++i) {\r\n            this.targetRenderers[i].dispose();\r\n        }\r\n\r\n        const cameras: Map<Camera, CameraMapForFluidRendering> = new Map();\r\n\r\n        for (let i = 0; i < this.targetRenderers.length; ++i) {\r\n            const targetRenderer = this.targetRenderers[i];\r\n\r\n            targetRenderer._initialize();\r\n\r\n            if (targetRenderer.camera && targetRenderer._renderPostProcess) {\r\n                let list = cameras.get(targetRenderer.camera);\r\n                if (!list) {\r\n                    list = [[], {}];\r\n                    cameras.set(targetRenderer.camera, list);\r\n                }\r\n                list[0].push(targetRenderer);\r\n                targetRenderer.camera.attachPostProcess(targetRenderer._renderPostProcess, i);\r\n            }\r\n        }\r\n\r\n        let iterator = cameras.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const camera = key.value;\r\n            const list = cameras.get(camera)!;\r\n\r\n            const firstPostProcess = camera._getFirstPostProcess();\r\n            if (!firstPostProcess) {\r\n                continue;\r\n            }\r\n\r\n            const [targetRenderers, copyDepthTextures] = list;\r\n\r\n            firstPostProcess.onSizeChangedObservable.add(() => {\r\n                if (!firstPostProcess.inputTexture.depthStencilTexture) {\r\n                    firstPostProcess.inputTexture.createDepthStencilTexture(\r\n                        0,\r\n                        true,\r\n                        this._engine.isStencilEnable,\r\n                        targetRenderers[0].samples,\r\n                        this._engine.isStencilEnable ? Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 : Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n                        `PostProcessRTTDepthStencil-${firstPostProcess.name}`\r\n                    );\r\n                }\r\n                for (const targetRenderer of targetRenderers) {\r\n                    const thicknessRT = targetRenderer._thicknessRenderTarget?.renderTarget;\r\n                    const thicknessTexture = thicknessRT?.texture;\r\n                    if (thicknessRT && thicknessTexture) {\r\n                        const key = thicknessTexture.width + \"_\" + thicknessTexture.height;\r\n                        let copyDepthTexture = copyDepthTextures[key];\r\n                        if (!copyDepthTexture) {\r\n                            copyDepthTexture = copyDepthTextures[key] = new FluidRenderingDepthTextureCopy(this._engine, thicknessTexture.width, thicknessTexture.height);\r\n                        }\r\n                        copyDepthTexture.depthRTWrapper.shareDepth(thicknessRT);\r\n                    }\r\n                }\r\n            });\r\n        }\r\n\r\n        // Dispose the CopyDepthTexture instances that we don't need anymore\r\n        iterator = this._cameras.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const camera = key.value;\r\n            const list = this._cameras.get(camera)!;\r\n\r\n            const copyDepthTextures = list[1];\r\n\r\n            const list2 = cameras.get(camera);\r\n            if (!list2) {\r\n                for (const key in copyDepthTextures) {\r\n                    copyDepthTextures[key].dispose();\r\n                }\r\n            } else {\r\n                for (const key in copyDepthTextures) {\r\n                    if (!list2[1][key]) {\r\n                        copyDepthTextures[key].dispose();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        this._cameras.clear();\r\n        this._cameras = cameras;\r\n\r\n        this._setParticleSizeForRenderTargets();\r\n    }\r\n\r\n    private _setParticleSizeForRenderTargets(): void {\r\n        const particleSizes = new Map<FluidRenderingTargetRenderer, number>();\r\n\r\n        for (let i = 0; i < this.renderObjects.length; ++i) {\r\n            const renderingObject = this.renderObjects[i];\r\n            let curSize = particleSizes.get(renderingObject.targetRenderer);\r\n            if (curSize === undefined) {\r\n                curSize = 0;\r\n            }\r\n            particleSizes.set(renderingObject.targetRenderer, Math.max(curSize, renderingObject.object.particleSize));\r\n        }\r\n\r\n        particleSizes.forEach((particleSize, targetRenderer) => {\r\n            if (targetRenderer._depthRenderTarget) {\r\n                targetRenderer._depthRenderTarget.particleSize = particleSize;\r\n            }\r\n        });\r\n    }\r\n\r\n    private _setUseVelocityForRenderObject(): void {\r\n        for (const renderingObject of this.renderObjects) {\r\n            renderingObject.object.useVelocity = renderingObject.targetRenderer.useVelocity;\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _prepareRendering(): void {\r\n        for (const renderer of this.targetRenderers) {\r\n            if (renderer.needInitialization) {\r\n                this._initialize();\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    /** @internal */\r\n    public _render(forCamera?: Camera): void {\r\n        for (let i = 0; i < this.targetRenderers.length; ++i) {\r\n            if (!forCamera || this.targetRenderers[i].camera === forCamera) {\r\n                this.targetRenderers[i]._clearTargets();\r\n            }\r\n        }\r\n\r\n        const iterator = this._cameras.keys();\r\n        for (let key = iterator.next(); key.done !== true; key = iterator.next()) {\r\n            const camera = key.value;\r\n            const list = this._cameras.get(camera)!;\r\n            if (forCamera && camera !== forCamera) {\r\n                continue;\r\n            }\r\n\r\n            const firstPostProcess = camera._getFirstPostProcess();\r\n            if (!firstPostProcess) {\r\n                continue;\r\n            }\r\n\r\n            const sourceCopyDepth = firstPostProcess.inputTexture?.depthStencilTexture;\r\n            if (sourceCopyDepth) {\r\n                const [targetRenderers, copyDepthTextures] = list;\r\n                for (const targetRenderer of targetRenderers) {\r\n                    targetRenderer._bgDepthTexture = sourceCopyDepth;\r\n                }\r\n                for (const key in copyDepthTextures) {\r\n                    copyDepthTextures[key].copy(sourceCopyDepth);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (let i = 0; i < this.renderObjects.length; ++i) {\r\n            const renderingObject = this.renderObjects[i];\r\n            if (!forCamera || renderingObject.targetRenderer.camera === forCamera) {\r\n                renderingObject.targetRenderer._render(renderingObject.object);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes of all the resources used by the class\r\n     */\r\n    public dispose(): void {\r\n        this._engine.onResizeObservable.remove(this._onEngineResizeObserver);\r\n        this._onEngineResizeObserver = null;\r\n\r\n        for (let i = 0; i < this.renderObjects.length; ++i) {\r\n            this.renderObjects[i].object.dispose();\r\n        }\r\n\r\n        for (let i = 0; i < this.targetRenderers.length; ++i) {\r\n            this.targetRenderers[i].dispose();\r\n        }\r\n\r\n        this._cameras.forEach((list) => {\r\n            const copyDepthTextures = list[1];\r\n            for (const key in copyDepthTextures) {\r\n                copyDepthTextures[key].dispose();\r\n            }\r\n        });\r\n\r\n        this.renderObjects.length = 0;\r\n        this.targetRenderers.length = 0;\r\n        this._cameras.clear();\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for fluidRenderer.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFluidRenderer(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // The fluid renderer creates depth-stencil textures on its render targets via\r\n    // AbstractEngine.createDepthStencilTexture, which is only installed by the\r\n    // abstractEngine.texture registration. This module imports the pure engine\r\n    // (side-effect free), so pull the registration in here.\r\n    RegisterAbstractEngineTexture();\r\n\r\n    Object.defineProperty(Scene.prototype, \"fluidRenderer\", {\r\n        get: function (this: Scene) {\r\n            return this._fluidRenderer;\r\n        },\r\n        set: function (this: Scene, value: Nullable<FluidRenderer>) {\r\n            this._fluidRenderer = value;\r\n        },\r\n        enumerable: true,\r\n        configurable: true,\r\n    });\r\n\r\n    Scene.prototype.enableFluidRenderer = function (): Nullable<FluidRenderer> {\r\n        if (this._fluidRenderer) {\r\n            return this._fluidRenderer;\r\n        }\r\n\r\n        this._fluidRenderer = new FluidRenderer(this);\r\n\r\n        return this._fluidRenderer;\r\n    };\r\n\r\n    Scene.prototype.disableFluidRenderer = function (): void {\r\n        this._fluidRenderer?.dispose();\r\n        this._fluidRenderer = null;\r\n    };\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDepthVertexShader\";\nconst shader = `attribute vec3 position;attribute vec2 offset;uniform mat4 view;uniform mat4 projection;\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nattribute vec3 size;\n#else\nattribute vec2 size;\n#endif\n#else\nuniform vec2 size;\n#endif\nvarying vec2 uv;varying vec3 viewPos;varying float sphereRadius;\n#ifdef FLUIDRENDERING_VELOCITY\nattribute vec3 velocity;varying float velocityNorm;\n#endif\nvoid main(void) {\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nvec2 particleSize=size.yz*size.x;\n#else\nvec2 particleSize=size;\n#endif\n#ifdef FLUIDRENDERING_CENTERED_OFFSET\nvec2 fluidOffset=offset+vec2(0.5);\n#else\nvec2 fluidOffset=offset;\n#endif\nvec3 cornerPos;cornerPos.xy=(fluidOffset-vec2(0.5))*particleSize;cornerPos.z=0.0;viewPos=(view*vec4(position,1.0)).xyz;gl_Position=projection*vec4(viewPos+cornerPos,1.0);uv=fluidOffset;sphereRadius=particleSize.x/2.0;\n#ifdef FLUIDRENDERING_VELOCITY\nvelocityNorm=length(velocity);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDepthVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDepthPixelShader\";\nconst shader = `uniform mat4 projection;varying vec2 uv;varying vec3 viewPos;varying float sphereRadius;\n#ifdef FLUIDRENDERING_VELOCITY\nvarying float velocityNorm;\n#endif\nvoid main(void) {vec3 normal;normal.xy=uv*2.0-1.0;float r2=dot(normal.xy,normal.xy);if (r2>1.0) discard;normal.z=sqrt(1.0-r2);\n#ifndef FLUIDRENDERING_RHS\nnormal.z=-normal.z;\n#endif\nvec4 realViewPos=vec4(viewPos+normal*sphereRadius,1.0);vec4 clipSpacePos=projection*realViewPos;\n#ifdef WEBGPU\ngl_FragDepth=clipSpacePos.z/clipSpacePos.w;\n#else\ngl_FragDepth=(clipSpacePos.z/clipSpacePos.w)*0.5+0.5;\n#endif\n#ifdef FLUIDRENDERING_RHS\nrealViewPos.z=-realViewPos.z;\n#endif\n#ifdef FLUIDRENDERING_VELOCITY\nglFragColor=vec4(realViewPos.z,velocityNorm,0.,1.);\n#else\nglFragColor=vec4(realViewPos.z,0.,0.,1.);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDepthPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleThicknessVertexShader\";\nconst shader = `attribute vec3 position;attribute vec2 offset;uniform mat4 view;uniform mat4 projection;\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nattribute vec3 size;\n#else\nattribute vec2 size;\n#endif\n#else\nuniform vec2 size;\n#endif\nvarying vec2 uv;void main(void) {\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nvec2 particleSize=size.yz*size.x;\n#else\nvec2 particleSize=size;\n#endif\n#ifdef FLUIDRENDERING_CENTERED_OFFSET\nvec2 fluidOffset=offset+vec2(0.5);\n#else\nvec2 fluidOffset=offset;\n#endif\nvec3 cornerPos;cornerPos.xy=(fluidOffset-vec2(0.5))*particleSize;cornerPos.z=0.0;vec3 viewPos=(view*vec4(position,1.0)).xyz+cornerPos;gl_Position=projection*vec4(viewPos,1.0);uv=fluidOffset;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleThicknessVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleThicknessPixelShader\";\nconst shader = `uniform float particleAlpha;varying vec2 uv;void main(void) {vec3 normal;normal.xy=uv*2.0-1.0;float r2=dot(normal.xy,normal.xy);if (r2>1.0) discard;float thickness=sqrt(1.0-r2);glFragColor=vec4(vec3(particleAlpha*thickness),1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleThicknessPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDiffuseVertexShader\";\nconst shader = `attribute vec3 position;attribute vec2 offset;attribute vec4 color;uniform mat4 view;uniform mat4 projection;\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\nattribute vec2 size;\n#else\nuniform vec2 size;\n#endif\nvarying vec2 uv;varying vec3 diffuseColor;void main(void) {vec3 cornerPos;cornerPos.xy=vec2(offset.x-0.5,offset.y-0.5)*size;cornerPos.z=0.0;vec3 viewPos=(view*vec4(position,1.0)).xyz+cornerPos;gl_Position=projection*vec4(viewPos,1.0);uv=offset;diffuseColor=color.rgb;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDiffuseVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDiffusePixelShader\";\nconst shader = `uniform float particleAlpha;varying vec2 uv;varying vec3 diffuseColor;void main(void) {vec3 normal;normal.xy=uv*2.0-1.0;float r2=dot(normal.xy,normal.xy);if (r2>1.0) discard;glFragColor=vec4(diffuseColor,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDiffusePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingBilateralBlurPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform int maxFilterSize;uniform vec2 blurDir;uniform float projectedParticleConstant;uniform float depthThreshold;varying vec2 vUV;void main(void) {float depth=textureLod(textureSampler,vUV,0.).x;if (depth>=1e6 || depth<=0.) {glFragColor=vec4(vec3(depth),1.);return;}\nint filterSize=min(maxFilterSize,int(ceil(projectedParticleConstant/depth)));float sigma=float(filterSize)/3.0;float two_sigma2=2.0*sigma*sigma;float sigmaDepth=depthThreshold/3.0;float two_sigmaDepth2=2.0*sigmaDepth*sigmaDepth;float sum=0.;float wsum=0.;float sumVel=0.;for (int x=-filterSize; x<=filterSize; ++x) {vec2 coords=vec2(x);vec2 sampleDepthVel=textureLod(textureSampler,vUV+coords*blurDir,0.).rg;float r=dot(coords,coords);float w=exp(-r/two_sigma2);float rDepth=sampleDepthVel.r-depth;float wd=exp(-rDepth*rDepth/two_sigmaDepth2);sum+=sampleDepthVel.r*w*wd;sumVel+=sampleDepthVel.g*w*wd;wsum+=w*wd;}\nglFragColor=vec4(sum/wsum,sumVel/wsum,0.,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingBilateralBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingStandardBlurPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform int filterSize;uniform vec2 blurDir;varying vec2 vUV;void main(void) {vec4 s=textureLod(textureSampler,vUV,0.);if (s.r==0.) {glFragColor=vec4(0.,0.,0.,1.);return;}\nfloat sigma=float(filterSize)/3.0;float twoSigma2=2.0*sigma*sigma;vec4 sum=vec4(0.);float wsum=0.;for (int x=-filterSize; x<=filterSize; ++x) {vec2 coords=vec2(x);vec4 sampl=textureLod(textureSampler,vUV+coords*blurDir,0.);float w=exp(-coords.x*coords.x/twoSigma2);sum+=sampl*w;wsum+=w;}\nsum/=wsum;glFragColor=vec4(sum.rgb,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingStandardBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingRenderPixelShader\";\nconst shader = `#define DISABLE_UNIFORMITY_ANALYSIS\n#define IOR 1.333\n#define ETA 1.0/IOR\n#define F0 0.02\nuniform sampler2D textureSampler;uniform sampler2D depthSampler;\n#ifdef FLUIDRENDERING_DIFFUSETEXTURE\nuniform sampler2D diffuseSampler;\n#else\nuniform vec3 diffuseColor;\n#endif\n#ifdef FLUIDRENDERING_FIXED_THICKNESS\nuniform float thickness;uniform sampler2D bgDepthSampler;\n#else\nuniform float minimumThickness;uniform sampler2D thicknessSampler;\n#endif\n#ifdef FLUIDRENDERING_ENVIRONMENT\nuniform samplerCube reflectionSampler;\n#endif\n#if defined(FLUIDRENDERING_DEBUG) && defined(FLUIDRENDERING_DEBUG_TEXTURE)\nuniform sampler2D debugSampler;\n#endif\nuniform mat4 viewMatrix;uniform mat4 projectionMatrix;uniform mat4 invProjectionMatrix;uniform vec2 texelSize;uniform vec3 dirLight;uniform float cameraFar;uniform float density;uniform float refractionStrength;uniform float fresnelClamp;uniform float specularPower;varying vec2 vUV;vec3 computeViewPosFromUVDepth(vec2 texCoord,float depth) {vec4 ndc;ndc.xy=texCoord*2.0-1.0;\n#ifdef FLUIDRENDERING_RHS\nndc.z=-projectionMatrix[2].z+projectionMatrix[3].z/depth;\n#else\nndc.z=projectionMatrix[2].z+projectionMatrix[3].z/depth;\n#endif\nndc.w=1.0;vec4 eyePos=invProjectionMatrix*ndc;eyePos.xyz/=eyePos.w;return eyePos.xyz;}\nvec3 getViewPosFromTexCoord(vec2 texCoord) {float depth=textureLod(depthSampler,texCoord,0.).x;return computeViewPosFromUVDepth(texCoord,depth);}\nvoid main(void) {vec2 texCoord=vUV;\n#if defined(FLUIDRENDERING_DEBUG) && defined(FLUIDRENDERING_DEBUG_TEXTURE)\nvec4 color=texture2D(debugSampler,texCoord);\n#ifdef FLUIDRENDERING_DEBUG_DEPTH\nglFragColor=vec4(color.rgb/vec3(2.0),1.);if (color.r>0.999 && color.g>0.999) {glFragColor=texture2D(textureSampler,texCoord);}\n#else\nglFragColor=vec4(color.rgb,1.);if (color.r<0.001 && color.g<0.001 && color.b<0.001) {glFragColor=texture2D(textureSampler,texCoord);}\n#endif\nreturn;\n#endif\nvec2 depthVel=textureLod(depthSampler,texCoord,0.).rg;float depth=depthVel.r;\n#ifndef FLUIDRENDERING_FIXED_THICKNESS\nfloat thickness=texture2D(thicknessSampler,texCoord).x;\n#else\nfloat bgDepth=texture2D(bgDepthSampler,texCoord).x;float depthNonLinear=projectionMatrix[2].z+projectionMatrix[3].z/depth;depthNonLinear=depthNonLinear*0.5+0.5;\n#endif\nvec4 backColor=texture2D(textureSampler,texCoord);\n#ifndef FLUIDRENDERING_FIXED_THICKNESS\nif (depth>=cameraFar || depth<=0. || thickness<=minimumThickness) {\n#else\nif (depth>=cameraFar || depth<=0. || bgDepth<=depthNonLinear) {\n#endif\n#ifdef FLUIDRENDERING_COMPOSITE_MODE\nglFragColor.rgb=backColor.rgb*backColor.a;glFragColor.a=backColor.a;\n#else\nglFragColor=backColor;\n#endif\nreturn;}\nvec3 viewPos=computeViewPosFromUVDepth(texCoord,depth);vec3 ddx=getViewPosFromTexCoord(texCoord+vec2(texelSize.x,0.))-viewPos;vec3 ddy=getViewPosFromTexCoord(texCoord+vec2(0.,texelSize.y))-viewPos;vec3 ddx2=viewPos-getViewPosFromTexCoord(texCoord+vec2(-texelSize.x,0.));if (abs(ddx.z)>abs(ddx2.z)) {ddx=ddx2;}\nvec3 ddy2=viewPos-getViewPosFromTexCoord(texCoord+vec2(0.,-texelSize.y));if (abs(ddy.z)>abs(ddy2.z)) {ddy=ddy2;}\nvec3 normal=normalize(cross(ddy,ddx));\n#ifdef FLUIDRENDERING_RHS\nnormal=-normal;\n#endif\n#ifndef WEBGPU\nif(isnan(normal.x) || isnan(normal.y) || isnan(normal.z) || isinf(normal.x) || isinf(normal.y) || isinf(normal.z)) {normal=vec3(0.,0.,-1.);}\n#endif\n#if defined(FLUIDRENDERING_DEBUG) && defined(FLUIDRENDERING_DEBUG_SHOWNORMAL)\nglFragColor=vec4(normal*0.5+0.5,1.0);return;\n#endif\nvec3 rayDir=normalize(viewPos); \n#ifdef FLUIDRENDERING_DIFFUSETEXTURE\nvec3 diffuseColor=textureLod(diffuseSampler,texCoord,0.0).rgb;\n#endif\nvec3 lightDir=normalize(vec3(viewMatrix*vec4(-dirLight,0.)));vec3 H =normalize(lightDir-rayDir);float specular=pow(max(0.0,dot(H,normal)),specularPower);\n#ifdef FLUIDRENDERING_DEBUG_DIFFUSERENDERING\nfloat diffuse =max(0.0,dot(lightDir,normal))*1.0;glFragColor=vec4(vec3(0.1) /*ambient*/+vec3(0.42,0.50,1.00)*diffuse+vec3(0,0,0.2)+specular,1.);return;\n#endif\nvec3 refractionDir=refract(rayDir,normal,ETA);vec4 transmitted=textureLod(textureSampler,vec2(texCoord+refractionDir.xy*thickness*refractionStrength),0.0);\n#ifdef FLUIDRENDERING_COMPOSITE_MODE\nif (transmitted.a==0.) transmitted.a=thickness;\n#endif\nvec3 transmittance=exp(-density*thickness*(1.0-diffuseColor)); \nvec3 refractionColor=transmitted.rgb*transmittance;\n#ifdef FLUIDRENDERING_ENVIRONMENT\nvec3 reflectionDir=reflect(rayDir,normal);vec3 reflectionColor=(textureCube(reflectionSampler,reflectionDir).rgb);float fresnel=clamp(F0+(1.0-F0)*pow(1.0-dot(normal,-rayDir),5.0),0.,fresnelClamp);vec3 finalColor=mix(refractionColor,reflectionColor,fresnel)+specular;\n#else\nvec3 finalColor=refractionColor+specular;\n#endif\n#ifdef FLUIDRENDERING_VELOCITY\nfloat velocity=depthVel.g;finalColor=mix(finalColor,vec3(1.0),smoothstep(0.3,1.0,velocity/6.0));\n#endif\nglFragColor=vec4(finalColor,transmitted.a);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingRenderPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDepthVertexShader\";\nconst shader = `attribute position: vec3f;attribute offset: vec2f;uniform view: mat4x4f;uniform projection: mat4x4f;\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nattribute size: vec3f;\n#else\nattribute size: vec2f;\n#endif\n#else\nuniform size: vec2f;\n#endif\nvarying uv: vec2f;varying viewPos: vec3f;varying sphereRadius: f32;\n#ifdef FLUIDRENDERING_VELOCITY\nattribute velocity: vec3f;varying velocityNorm: f32;\n#endif\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nvar particleSize: vec2f=vertexInputs.size.yz*vertexInputs.size.x;\n#else\nvar particleSize: vec2f=vertexInputs.size;\n#endif\n#else\nvar particleSize: vec2f=uniforms.size;\n#endif\n#ifdef FLUIDRENDERING_CENTERED_OFFSET\nlet fluidOffset: vec2f=vertexInputs.offset+vec2f(0.5);\n#else\nlet fluidOffset: vec2f=vertexInputs.offset;\n#endif\nvar cornerPos: vec3f=vec3f(\n(fluidOffset-vec2f(0.5))*particleSize,\n0.0\n);vertexOutputs.viewPos=(uniforms.view*vec4f(vertexInputs.position,1.0)).xyz;vertexOutputs.position=uniforms.projection*vec4f(vertexOutputs.viewPos+cornerPos,1.0);vertexOutputs.uv=fluidOffset;vertexOutputs.sphereRadius=particleSize.x/2.0;\n#ifdef FLUIDRENDERING_VELOCITY\nvertexOutputs.velocityNorm=length(velocity);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDepthVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDepthPixelShader\";\nconst shader = `uniform projection: mat4x4f;varying uv: vec2f;varying viewPos: vec3f;varying sphereRadius: f32;\n#ifdef FLUIDRENDERING_VELOCITY\nvarying velocityNorm: f32;\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var normalxy: vec2f=input.uv*2.0-1.0;var r2: f32=dot(normalxy,normalxy);if (r2>1.0) {discard;}\nvar normal: vec3f=vec3f(normalxy,sqrt(1.0-r2));\n#ifndef FLUIDRENDERING_RHS\nnormal.z=-normal.z;\n#endif\nvar realViewPos: vec4f=vec4f(input.viewPos+normal*input.sphereRadius,1.0);var clipSpacePos: vec4f=uniforms.projection*realViewPos;fragmentOutputs.fragDepth=clipSpacePos.z/clipSpacePos.w;\n#ifdef FLUIDRENDERING_RHS\nrealViewPos.z=-realViewPos.z;\n#endif\n#ifdef FLUIDRENDERING_VELOCITY\nfragmentOutputs.color=vec4f(realViewPos.z,input.velocityNorm,0.,1.);\n#else\nfragmentOutputs.color=vec4f(realViewPos.z,0.,0.,1.);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDepthPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleThicknessVertexShader\";\nconst shader = `attribute position: vec3f;attribute offset: vec2f;uniform view: mat4x4f;uniform projection: mat4x4f;\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nattribute size: vec3f;\n#else\nattribute size: vec2f;\n#endif\n#else\nuniform size: vec2f;\n#endif\nvarying uv: vec2f;@vertex\nfn main(input: VertexInputs)->FragmentInputs {\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE_VEC3\nvar particleSize: vec2f=vertexInputs.size.yz*vertexInputs.size.x;\n#else\nvar particleSize: vec2f=vertexInputs.size;\n#endif\n#else\nvar particleSize: vec2f=uniforms.size;\n#endif\n#ifdef FLUIDRENDERING_CENTERED_OFFSET\nlet fluidOffset: vec2f=vertexInputs.offset+vec2f(0.5);\n#else\nlet fluidOffset: vec2f=vertexInputs.offset;\n#endif\nvar cornerPos: vec3f=vec3f(\n(fluidOffset-vec2f(0.5))*particleSize,\n0.0\n);var viewPos: vec3f=(uniforms.view*vec4f(vertexInputs.position,1.0)).xyz+cornerPos;vertexOutputs.position=uniforms.projection*vec4f(viewPos,1.0);vertexOutputs.uv=fluidOffset;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleThicknessVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleThicknessPixelShader\";\nconst shader = `uniform particleAlpha: f32;varying uv: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var normalxy: vec2f=input.uv*2.0-1.0;var r2: f32=dot(normalxy,normalxy);if (r2>1.0) {discard;}\nvar thickness: f32=sqrt(1.0-r2);fragmentOutputs.color=vec4f(vec3f(uniforms.particleAlpha*thickness),1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleThicknessPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDiffuseVertexShader\";\nconst shader = `attribute position: vec3f;attribute offset: vec2f;attribute color: vec4f;uniform view: mat4x4f;uniform projection: mat4x4f;\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\nattribute size: vec2f;\n#else\nuniform size: vec2f;\n#endif\nvarying uv: vec2f;varying diffuseColor: vec3f;@vertex\nfn main(input: VertexInputs)->FragmentInputs {\n#ifdef FLUIDRENDERING_PER_PARTICLE_SIZE\nvar particleSize: vec2f=vertexInputs.size;\n#else\nvar particleSize: vec2f=uniforms.size;\n#endif\nvar cornerPos: vec3f=vec3f(\nvec2f(vertexInputs.offset.x-0.5,vertexInputs.offset.y-0.5)*particleSize,\n0.0\n);var viewPos: vec3f=(uniforms.view*vec4f(vertexInputs.position,1.0)).xyz+cornerPos;vertexOutputs.position=uniforms.projection*vec4f(viewPos,1.0);vertexOutputs.uv=vertexInputs.offset;vertexOutputs.diffuseColor=vertexInputs.color.rgb;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDiffuseVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingParticleDiffusePixelShader\";\nconst shader = `uniform particleAlpha: f32;varying uv: vec2f;varying diffuseColor: vec3f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var normalxy: vec2f=input.uv*2.0-1.0;var r2: f32=dot(normalxy,normalxy);if (r2>1.0) {discard;}\nfragmentOutputs.color=vec4f(input.diffuseColor,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingParticleDiffusePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingBilateralBlurPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform maxFilterSize: i32;uniform blurDir: vec2f;uniform projectedParticleConstant: f32;uniform depthThreshold: f32;varying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var depth: f32=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.).x;if (depth>=1e6 || depth<=0.) {fragmentOutputs.color=vec4f(vec3f(depth),1.);return fragmentOutputs;}\nvar filterSize: i32=min(uniforms.maxFilterSize,i32(ceil(uniforms.projectedParticleConstant/depth)));var sigma: f32=f32(filterSize)/3.0;var two_sigma2: f32=2.0*sigma*sigma;var sigmaDepth: f32=uniforms.depthThreshold/3.0;var two_sigmaDepth2: f32=2.0*sigmaDepth*sigmaDepth;var sum: f32=0.;var wsum: f32=0.;var sumVel: f32=0.;for (var x: i32=-filterSize; x<=filterSize; x++) {var coords: vec2f=vec2f(f32(x));var sampleDepthVel: vec2f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV+coords*uniforms.blurDir,0.).rg;var r: f32=dot(coords,coords);var w: f32=exp(-r/two_sigma2);var rDepth: f32=sampleDepthVel.r-depth;var wd: f32=exp(-rDepth*rDepth/two_sigmaDepth2);sum+=sampleDepthVel.r*w*wd;sumVel+=sampleDepthVel.g*w*wd;wsum+=w*wd;}\nfragmentOutputs.color=vec4f(sum/wsum,sumVel/wsum,0.,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingBilateralBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingStandardBlurPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform filterSize: i32;uniform blurDir: vec2f;varying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var s: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.);if (s.r==0.) {fragmentOutputs.color=vec4f(0.,0.,0.,1.);return fragmentOutputs;}\nvar sigma: f32=f32(uniforms.filterSize)/3.0;var twoSigma2: f32=2.0*sigma*sigma;var sum: vec4f=vec4f(0.);var wsum: f32=0.;for (var x: i32=-uniforms.filterSize; x<=uniforms.filterSize; x++) {var coords: vec2f=vec2f(f32(x));var sampl: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV+coords*uniforms.blurDir,0.);var w: f32=exp(-coords.x*coords.x/twoSigma2);sum+=sampl*w;wsum+=w;}\nsum/=wsum;fragmentOutputs.color=vec4f(sum.rgb,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingStandardBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"fluidRenderingRenderPixelShader\";\nconst shader = `#define DISABLE_UNIFORMITY_ANALYSIS\n#define IOR 1.333\n#define ETA 1.0/IOR\n#define F0 0.02\nvar textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;\n#ifdef FLUIDRENDERING_DIFFUSETEXTURE\nvar diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#else\nuniform diffuseColor: vec3f;\n#endif\n#ifdef FLUIDRENDERING_FIXED_THICKNESS\nuniform thickness: f32;var bgDepthSamplerSampler: sampler;var bgDepthSampler: texture_2d<f32>;\n#else\nuniform minimumThickness: f32;var thicknessSamplerSampler: sampler;var thicknessSampler: texture_2d<f32>;\n#endif\n#ifdef FLUIDRENDERING_ENVIRONMENT\nvar reflectionSamplerSampler: sampler;var reflectionSampler: texture_cube<f32>;\n#endif\n#if defined(FLUIDRENDERING_DEBUG) && defined(FLUIDRENDERING_DEBUG_TEXTURE)\nvar debugSamplerSampler: sampler;var debugSampler: texture_2d<f32>;\n#endif\nuniform viewMatrix: mat4x4f;uniform projectionMatrix: mat4x4f;uniform invProjectionMatrix: mat4x4f;uniform texelSize: vec2f;uniform dirLight: vec3f;uniform cameraFar: f32;uniform density: f32;uniform refractionStrength: f32;uniform fresnelClamp: f32;uniform specularPower: f32;varying vUV: vec2f;fn computeViewPosFromUVDepth(texCoord: vec2f,depth: f32)->vec3f {var ndc: vec4f=vec4f(texCoord*2.0-1.0,0.0,1.0);\n#ifdef FLUIDRENDERING_RHS\nndc.z=-uniforms.projectionMatrix[2].z+uniforms.projectionMatrix[3].z/depth;\n#else\nndc.z=uniforms.projectionMatrix[2].z+uniforms.projectionMatrix[3].z/depth;\n#endif\nndc.w=1.0;var eyePos: vec4f=uniforms.invProjectionMatrix*ndc;return eyePos.xyz/eyePos.w;}\nfn getViewPosFromTexCoord(texCoord: vec2f)->vec3f {var depth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,texCoord,0.).x;return computeViewPosFromUVDepth(texCoord,depth);}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var texCoord: vec2f=input.vUV;\n#if defined(FLUIDRENDERING_DEBUG) && defined(FLUIDRENDERING_DEBUG_TEXTURE)\nvar color: vec4f=textureSample(debugSampler,debugSamplerSampler,texCoord);\n#ifdef FLUIDRENDERING_DEBUG_DEPTH\nfragmentOutputs.color=vec4f(color.rgb/vec3f(2.0),1.);if (color.r>0.999 && color.g>0.999) {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,texCoord);}\n#else\nfragmentOutputs.color=vec4f(color.rgb,1.);if (color.r<0.001 && color.g<0.001 && color.b<0.001) {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,texCoord);}\n#endif\nreturn fragmentOutputs;\n#endif\nvar depthVel: vec2f=textureSampleLevel(depthSampler,depthSamplerSampler,texCoord,0.).rg;var depth: f32=depthVel.r;\n#ifndef FLUIDRENDERING_FIXED_THICKNESS\nvar thickness: f32=textureSample(thicknessSampler,thicknessSamplerSampler,texCoord).x;\n#else\nvar thickness: f32=uniforms.thickness;var bgDepth: f32=textureSample(bgDepthSampler,bgDepthSamplerSampler,texCoord).x;var depthNonLinear: f32=uniforms.projectionMatrix[2].z+uniforms.projectionMatrix[3].z/depth;depthNonLinear=depthNonLinear*0.5+0.5;\n#endif\nvar backColor: vec4f=textureSample(textureSampler,textureSamplerSampler,texCoord);\n#ifndef FLUIDRENDERING_FIXED_THICKNESS\nif (depth>=uniforms.cameraFar || depth<=0. || thickness<=uniforms.minimumThickness) {\n#else\nif (depth>=uniforms.cameraFar || depth<=0. || bgDepth<=depthNonLinear) {\n#endif\n#ifdef FLUIDRENDERING_COMPOSITE_MODE\nfragmentOutputs.color=vec4f(backColor.rgb*backColor.a,backColor.a);\n#else\nfragmentOutputs.color=backColor;\n#endif\nreturn fragmentOutputs;}\nvar viewPos: vec3f=computeViewPosFromUVDepth(texCoord,depth);var ddx: vec3f=getViewPosFromTexCoord(texCoord+vec2f(uniforms.texelSize.x,0.))-viewPos;var ddy: vec3f=getViewPosFromTexCoord(texCoord+vec2f(0.,uniforms.texelSize.y))-viewPos;var ddx2: vec3f=viewPos-getViewPosFromTexCoord(texCoord+vec2f(-uniforms.texelSize.x,0.));if (abs(ddx.z)>abs(ddx2.z)) {ddx=ddx2;}\nvar ddy2: vec3f=viewPos-getViewPosFromTexCoord(texCoord+vec2f(0.,-uniforms.texelSize.y));if (abs(ddy.z)>abs(ddy2.z)) {ddy=ddy2;}\nvar normal: vec3f=normalize(cross(ddy,ddx));\n#ifdef FLUIDRENDERING_RHS\nnormal=-normal;\n#endif\n#if defined(FLUIDRENDERING_DEBUG) && defined(FLUIDRENDERING_DEBUG_SHOWNORMAL)\nfragmentOutputs.color=vec4f(normal*0.5+0.5,1.0);return fragmentOutputs;\n#endif\nvar rayDir: vec3f=normalize(viewPos); \n#ifdef FLUIDRENDERING_DIFFUSETEXTURE\nvar diffuseColor: vec3f=textureSampleLevel(diffuseSampler,diffuseSamplerSampler,texCoord,0.0).rgb;\n#else\nvar diffuseColor: vec3f=uniforms.diffuseColor;\n#endif\nvar lightDir: vec3f=normalize((uniforms.viewMatrix*vec4f(-uniforms.dirLight,0.)).xyz);var H: vec3f =normalize(lightDir-rayDir);var specular: f32 =pow(max(0.0,dot(H,normal)),uniforms.specularPower);\n#ifdef FLUIDRENDERING_DEBUG_DIFFUSERENDERING\nvar diffuse: f32 =max(0.0,dot(lightDir,normal))*1.0;fragmentOutputs.color=vec4f(vec3f(0.1) /*ambient*/+vec3f(0.42,0.50,1.00)*diffuse+vec3f(0,0,0.2)+specular,1.);return fragmentOutputs;\n#endif\nvar refractionDir: vec3f=refract(rayDir,normal,ETA);var transmitted: vec4f=textureSampleLevel(textureSampler,textureSamplerSampler,vec2f(texCoord+refractionDir.xy*thickness*uniforms.refractionStrength),0.0);\n#ifdef FLUIDRENDERING_COMPOSITE_MODE\nif (transmitted.a==0.) {transmitted.a=thickness;}\n#endif\nvar transmittance: vec3f=exp(-uniforms.density*thickness*(1.0-diffuseColor)); \nvar refractionColor: vec3f=transmitted.rgb*transmittance;\n#ifdef FLUIDRENDERING_ENVIRONMENT\nvar reflectionDir: vec3f=reflect(rayDir,normal);var reflectionColor: vec3f=(textureSample(reflectionSampler,reflectionSamplerSampler,reflectionDir).rgb);var fresnel: f32=clamp(F0+(1.0-F0)*pow(1.0-dot(normal,-rayDir),5.0),0.,uniforms.fresnelClamp);var finalColor: vec3f=mix(refractionColor,reflectionColor,fresnel)+specular;\n#else\nvar finalColor: vec3f=refractionColor+specular;\n#endif\n#ifdef FLUIDRENDERING_VELOCITY\nvar velocity: f32=depthVel.g;finalColor=mix(finalColor,vec3f(1.0),smoothstep(0.3,1.0,velocity/6.0));\n#endif\nfragmentOutputs.color=vec4f(finalColor,transmitted.a);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const fluidRenderingRenderPixelShaderWGSL = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { MultiRenderTarget } from \"core/Materials/Textures/multiRenderTarget.pure\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color.pure\";\r\nimport { Matrix, TmpVectors } from \"core/Maths/math.vector.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type WebGPURenderTargetWrapper } from \"core/Engines/WebGPU/webgpuRenderTargetWrapper\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase.pure\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { type StandardMaterial } from \"core/Materials/standardMaterial.pure\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { type SpotLight } from \"core/Lights/spotLight.pure\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial.pure\";\r\nimport { expandToProperty, serialize } from \"core/Misc/decorators\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport { type DirectionalLight } from \"core/Lights/directionalLight.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Reflective Shadow Maps were first described in http://www.klayge.org/material/3_12/GI/rsm.pdf by Carsten Dachsbacher and Marc Stamminger\r\n * The ReflectiveShadowMap class only implements the position / normal / flux texture generation part.\r\n * For the global illumination effect, see the GIRSMManager class.\r\n */\r\n\r\n/**\r\n * Class used to generate the RSM (Reflective Shadow Map) textures for a given light.\r\n * The textures are: position (in world space), normal (in world space) and flux (light intensity)\r\n */\r\nexport class ReflectiveShadowMap {\r\n    private _scene: Scene;\r\n    private _light: DirectionalLight | SpotLight;\r\n    private _lightTransformMatrix: Matrix = Matrix.Identity();\r\n    private _mrt: MultiRenderTarget;\r\n    private _textureDimensions: { width: number; height: number };\r\n    private _regularMatToMatWithPlugin: Map<Material, Material>;\r\n    private _counters: Array<{ name: string; value: number }>;\r\n\r\n    private _enable = false;\r\n\r\n    /**\r\n     * Enables or disables the RSM generation.\r\n     */\r\n    public get enable() {\r\n        return this._enable;\r\n    }\r\n\r\n    public set enable(value: boolean) {\r\n        if (this._enable === value) {\r\n            return;\r\n        }\r\n\r\n        this._enable = value;\r\n        this._customRenderTarget(value);\r\n    }\r\n\r\n    /**\r\n     * Gets the position texture generated by the RSM process.\r\n     */\r\n    public get positionWorldTexture() {\r\n        return this._mrt.textures[0];\r\n    }\r\n\r\n    /**\r\n     * Gets the normal texture generated by the RSM process.\r\n     */\r\n    public get normalWorldTexture() {\r\n        return this._mrt.textures[1];\r\n    }\r\n\r\n    /**\r\n     * Gets the flux texture generated by the RSM process.\r\n     */\r\n    public get fluxTexture() {\r\n        return this._mrt.textures[2];\r\n    }\r\n\r\n    /**\r\n     * Gets the render list used to generate the RSM textures.\r\n     */\r\n    public get renderList() {\r\n        return this._mrt.renderList;\r\n    }\r\n\r\n    /**\r\n     * Gets the light used to generate the RSM textures.\r\n     */\r\n    public get light() {\r\n        return this._light;\r\n    }\r\n\r\n    /**\r\n     * Gets or sets a boolean indicating if the light parameters should be recomputed even if the light parameters (position, direction) did not change.\r\n     * You should not set this value to true, except for debugging purpose (if you want to see changes from the inspector, for eg).\r\n     * Instead, you should call updateLightParameters() explicitely at the right time (once the light parameters changed).\r\n     */\r\n    public forceUpdateLightParameters = false;\r\n\r\n    /**\r\n     * Creates a new RSM for the given light.\r\n     * @param scene The scene\r\n     * @param light The light to use to generate the RSM textures\r\n     * @param textureDimensions The dimensions of the textures to generate. Default: \\{ width: 512, height: 512 \\}\r\n     */\r\n    constructor(scene: Scene, light: DirectionalLight | SpotLight, textureDimensions = { width: 512, height: 512 }) {\r\n        this._scene = scene;\r\n        this._light = light;\r\n        this._textureDimensions = textureDimensions;\r\n        this._regularMatToMatWithPlugin = new Map();\r\n        this._counters = [{ name: \"RSM Generation \" + light.name, value: 0 }];\r\n\r\n        this._createMultiRenderTarget();\r\n        this._recomputeLightTransformationMatrix();\r\n\r\n        this.enable = true;\r\n    }\r\n\r\n    /**\r\n     * Sets the dimensions of the textures to generate.\r\n     * @param dimensions The dimensions of the textures to generate.\r\n     */\r\n    public setTextureDimensions(dimensions: { width: number; height: number }) {\r\n        const renderList = this._mrt.renderList;\r\n\r\n        this._textureDimensions = dimensions;\r\n        this._disposeMultiRenderTarget();\r\n        this._createMultiRenderTarget();\r\n\r\n        if (renderList) {\r\n            for (const mesh of renderList) {\r\n                this._addMeshToMRT(mesh);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds the given mesh to the render list used to generate the RSM textures.\r\n     * @param mesh The mesh to add to the render list used to generate the RSM textures. If not provided, all scene meshes will be added to the render list.\r\n     */\r\n    public addMesh(mesh?: AbstractMesh) {\r\n        if (mesh) {\r\n            this._addMeshToMRT(mesh);\r\n        } else {\r\n            for (const mesh of this._scene.meshes) {\r\n                this._addMeshToMRT(mesh);\r\n            }\r\n        }\r\n        this._recomputeLightTransformationMatrix();\r\n    }\r\n\r\n    /**\r\n     * Recomputes the light transformation matrix. Call this method if you manually changed the light position / direction / etc. and you want to update the RSM textures accordingly.\r\n     * You should also call this method if you add/remove meshes to/from the render list.\r\n     */\r\n    public updateLightParameters() {\r\n        this._recomputeLightTransformationMatrix();\r\n    }\r\n\r\n    /**\r\n     * Gets the light transformation matrix used to generate the RSM textures.\r\n     */\r\n    public get lightTransformationMatrix() {\r\n        if (this.forceUpdateLightParameters) {\r\n            this.updateLightParameters();\r\n        }\r\n        return this._lightTransformMatrix;\r\n    }\r\n\r\n    /**\r\n     * Gets the GPU time spent to generate the RSM textures.\r\n     */\r\n    public get countersGPU(): Array<{ name: string; value: number }> {\r\n        return this._counters;\r\n    }\r\n\r\n    /**\r\n     * Disposes the RSM.\r\n     */\r\n    public dispose() {\r\n        this._disposeMultiRenderTarget();\r\n    }\r\n\r\n    protected _createMultiRenderTarget() {\r\n        const name = this._light.name;\r\n\r\n        const caps = this._scene.getEngine().getCaps();\r\n\r\n        const fluxTextureType = caps.rg11b10ufColorRenderable ? Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV : Constants.TEXTURETYPE_HALF_FLOAT;\r\n        const fluxTextureFormat = caps.rg11b10ufColorRenderable ? Constants.TEXTUREFORMAT_RGB : Constants.TEXTUREFORMAT_RGBA;\r\n\r\n        this._mrt = new MultiRenderTarget(\r\n            \"RSMmrt_\" + name,\r\n            this._textureDimensions,\r\n            3, // number of RTT - position / normal / flux\r\n            this._scene,\r\n            {\r\n                types: [Constants.TEXTURETYPE_HALF_FLOAT, Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV, fluxTextureType],\r\n                samplingModes: [Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURE_BILINEAR_SAMPLINGMODE],\r\n                generateMipMaps: false,\r\n                targetTypes: [Constants.TEXTURE_2D, Constants.TEXTURE_2D, Constants.TEXTURE_2D],\r\n                formats: [Constants.TEXTUREFORMAT_RGBA, Constants.TEXTUREFORMAT_RGBA, fluxTextureFormat],\r\n            },\r\n            [\"RSMPosition_\" + name, \"RSMNormal_\" + name, \"RSMFlux_\" + name]\r\n        );\r\n\r\n        this._mrt.renderList = [];\r\n        this._mrt.clearColor = new Color4(0, 0, 0, 1);\r\n        this._mrt.noPrePassRenderer = true;\r\n\r\n        let sceneUBO: UniformBuffer;\r\n        let currentSceneUBO: UniformBuffer;\r\n\r\n        const useUBO = this._scene.getEngine().supportsUniformBuffers;\r\n\r\n        if (useUBO) {\r\n            sceneUBO = this._scene.createSceneUniformBuffer(`Scene for RSM (light \"${name}\")`, { forceMono: true });\r\n        }\r\n\r\n        let shadowEnabled: boolean;\r\n\r\n        this._mrt.onBeforeBindObservable.add(() => {\r\n            currentSceneUBO = this._scene.getSceneUniformBuffer();\r\n            shadowEnabled = this._light.shadowEnabled;\r\n            this._light.shadowEnabled = false; // we render from the light point of view, so we won't have any shadow anyway!\r\n        });\r\n\r\n        this._mrt.onBeforeRenderObservable.add((faceIndex: number) => {\r\n            if (sceneUBO) {\r\n                this._scene.setSceneUniformBuffer(sceneUBO);\r\n            }\r\n            const viewMatrix = this._light.getViewMatrix(faceIndex);\r\n            const projectionMatrix = this._light.getProjectionMatrix(viewMatrix || undefined, this._mrt.renderList || undefined);\r\n            if (viewMatrix && projectionMatrix) {\r\n                this._scene.setTransformMatrix(viewMatrix, projectionMatrix);\r\n            }\r\n            if (useUBO) {\r\n                this._scene.getSceneUniformBuffer().unbindEffect();\r\n                this._scene.finalizeSceneUbo();\r\n            }\r\n        });\r\n\r\n        this._mrt.onAfterUnbindObservable.add(() => {\r\n            if (sceneUBO) {\r\n                this._scene.setSceneUniformBuffer(currentSceneUBO);\r\n            }\r\n            this._scene.updateTransformMatrix(); // restore the view/projection matrices of the active camera\r\n            this._light.shadowEnabled = shadowEnabled;\r\n            this._counters[0].value = (this._mrt.renderTarget as WebGPURenderTargetWrapper).gpuTimeInFrame?.counter.lastSecAverage ?? 0;\r\n        });\r\n\r\n        this._customRenderTarget(true);\r\n    }\r\n\r\n    protected _customRenderTarget(add: boolean) {\r\n        const idx = this._scene.customRenderTargets.indexOf(this._mrt);\r\n        if (add) {\r\n            if (idx === -1) {\r\n                this._scene.customRenderTargets.push(this._mrt);\r\n            }\r\n        } else if (idx !== -1) {\r\n            this._scene.customRenderTargets.splice(idx, 1);\r\n        }\r\n    }\r\n\r\n    protected _recomputeLightTransformationMatrix() {\r\n        const viewMatrix = this._light.getViewMatrix();\r\n        const projectionMatrix = this._light.getProjectionMatrix(viewMatrix || undefined, this._mrt.renderList || undefined);\r\n        if (viewMatrix && projectionMatrix) {\r\n            viewMatrix.multiplyToRef(projectionMatrix, this._lightTransformMatrix);\r\n        }\r\n    }\r\n\r\n    protected _addMeshToMRT(mesh: AbstractMesh) {\r\n        this._mrt.renderList?.push(mesh);\r\n\r\n        const material = mesh.material;\r\n        if (mesh.getTotalVertices() === 0 || !material) {\r\n            return;\r\n        }\r\n\r\n        let rsmMaterial = this._regularMatToMatWithPlugin.get(material);\r\n        if (!rsmMaterial) {\r\n            rsmMaterial = material.clone(\"RSMCreate_\" + material.name) || undefined;\r\n            if (rsmMaterial) {\r\n                // Disable the prepass renderer for this material\r\n                Object.defineProperty(rsmMaterial, \"canRenderToMRT\", {\r\n                    get: function () {\r\n                        return false;\r\n                    },\r\n                    enumerable: true,\r\n                    configurable: true,\r\n                });\r\n\r\n                (rsmMaterial as any).disableLighting = true;\r\n\r\n                const rsmCreatePlugin = new RSMCreatePluginMaterial(rsmMaterial);\r\n\r\n                rsmCreatePlugin.isEnabled = true;\r\n                rsmCreatePlugin.light = this._light;\r\n\r\n                this._regularMatToMatWithPlugin.set(material, rsmMaterial);\r\n            }\r\n        }\r\n\r\n        this._mrt.setMaterialForRendering(mesh, rsmMaterial);\r\n    }\r\n\r\n    protected _disposeMultiRenderTarget() {\r\n        this._customRenderTarget(false);\r\n        this._mrt.dispose();\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nclass MaterialRSMCreateDefines extends MaterialDefines {\r\n    public RSMCREATE = false;\r\n    public RSMCREATE_PROJTEXTURE = false;\r\n    public RSMCREATE_LIGHT_IS_SPOT = false;\r\n}\r\n\r\n/**\r\n * Plugin that implements the creation of the RSM textures\r\n */\r\nexport class RSMCreatePluginMaterial extends MaterialPluginBase {\r\n    private _varAlbedoName: string;\r\n    private _lightColor = new Color3();\r\n    private _hasProjectionTexture = false;\r\n\r\n    /**\r\n     * Defines the name of the plugin.\r\n     */\r\n    public static readonly Name = \"RSMCreate\";\r\n\r\n    /**\r\n     * Defines the light that should be used to generate the RSM textures.\r\n     */\r\n    @serialize()\r\n    public light: DirectionalLight | SpotLight;\r\n\r\n    private _isEnabled = false;\r\n    /**\r\n     * Defines if the plugin is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    protected _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a give shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Create a new RSMCreatePluginMaterial\r\n     * @param material Parent material of the plugin\r\n     */\r\n    constructor(material: Material | StandardMaterial | PBRBaseMaterial) {\r\n        super(material, RSMCreatePluginMaterial.Name, 300, new MaterialRSMCreateDefines());\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n\r\n        this._varAlbedoName = material instanceof PBRBaseMaterial ? \"surfaceAlbedo\" : \"baseColor.rgb\";\r\n    }\r\n\r\n    /**\r\n     * Prepares the defines used by the plugin\r\n     * @param defines the defines to prepare\r\n     */\r\n    public override prepareDefines(defines: MaterialRSMCreateDefines) {\r\n        defines.RSMCREATE = this._isEnabled;\r\n\r\n        this._hasProjectionTexture = false;\r\n\r\n        const isSpot = this.light.getTypeID() === Light.LIGHTTYPEID_SPOTLIGHT;\r\n        if (isSpot) {\r\n            const spot = this.light as SpotLight;\r\n            this._hasProjectionTexture = spot.projectionTexture ? spot.projectionTexture.isReady() : false;\r\n        }\r\n\r\n        defines.RSMCREATE_PROJTEXTURE = this._hasProjectionTexture;\r\n        defines.RSMCREATE_LIGHT_IS_SPOT = isSpot;\r\n        defines.SCENE_MRT_COUNT = 3;\r\n    }\r\n\r\n    public override getClassName() {\r\n        return \"RSMCreatePluginMaterial\";\r\n    }\r\n\r\n    public override getUniforms() {\r\n        return {\r\n            ubo: [\r\n                { name: \"rsmTextureProjectionMatrix\", size: 16, type: \"mat4\" },\r\n                { name: \"rsmSpotInfo\", size: 4, type: \"vec4\" },\r\n                { name: \"rsmLightColor\", size: 3, type: \"vec3\" },\r\n                { name: \"rsmLightPosition\", size: 3, type: \"vec3\" },\r\n            ],\r\n            fragment: `#ifdef RSMCREATE\r\n                    uniform mat4 rsmTextureProjectionMatrix;\r\n                    uniform vec4 rsmSpotInfo;\r\n                    uniform vec3 rsmLightColor;\r\n                    uniform vec3 rsmLightPosition;\r\n                #endif`,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the samplers used by the plugin\r\n     * @param samplers the list of samplers to update\r\n     */\r\n    public override getSamplers(samplers: string[]) {\r\n        samplers.push(\"rsmTextureProjectionSampler\");\r\n    }\r\n\r\n    /**\r\n     * Binds the material data for a sub mesh\r\n     * @param uniformBuffer the uniform buffer to update\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer) {\r\n        if (!this._isEnabled) {\r\n            return;\r\n        }\r\n\r\n        this.light.diffuse.scaleToRef(this.light.getScaledIntensity(), this._lightColor);\r\n        uniformBuffer.updateColor3(\"rsmLightColor\", this._lightColor);\r\n\r\n        if (this.light.getTypeID() === Light.LIGHTTYPEID_SPOTLIGHT) {\r\n            const spot = this.light as SpotLight;\r\n\r\n            if (this._hasProjectionTexture) {\r\n                uniformBuffer.updateMatrix(\"rsmTextureProjectionMatrix\", spot.projectionTextureMatrix);\r\n                uniformBuffer.setTexture(\"rsmTextureProjectionSampler\", spot.projectionTexture);\r\n            }\r\n\r\n            const normalizeDirection = TmpVectors.Vector3[0];\r\n\r\n            if (spot.computeTransformedInformation()) {\r\n                uniformBuffer.updateFloat3(\"rsmLightPosition\", this.light.transformedPosition.x, this.light.transformedPosition.y, this.light.transformedPosition.z);\r\n                spot.transformedDirection.normalizeToRef(normalizeDirection);\r\n            } else {\r\n                uniformBuffer.updateFloat3(\"rsmLightPosition\", this.light.position.x, this.light.position.y, this.light.position.z);\r\n                spot.direction.normalizeToRef(normalizeDirection);\r\n            }\r\n\r\n            uniformBuffer.updateFloat4(\"rsmSpotInfo\", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, Math.cos(spot.angle * 0.5));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets custom shader code for the plugin\r\n     * @param shaderType the type of shader (vertex or fragment)\r\n     * @param shaderLanguage the shader language\r\n     * @returns the custom shader code or null\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage: ShaderLanguage): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderType === \"vertex\") {\r\n            return null;\r\n        }\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                #ifdef RSMCREATE\r\n                    #ifdef RSMCREATE_PROJTEXTURE\r\n                        var rsmTextureProjectionSamplerSampler: sampler;\r\n                        var rsmTextureProjectionSampler: texture_2d<f32>;\r\n                    #endif\r\n                #endif\r\n            `,\r\n\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n                #ifdef RSMCREATE\r\n                    var rsmColor = ${this._varAlbedoName} * uniforms.rsmLightColor;\r\n                    #ifdef RSMCREATE_PROJTEXTURE\r\n                    {\r\n                        var strq = uniforms.rsmTextureProjectionMatrix * vec4f(fragmentInputs.vPositionW, 1.0);\r\n                        strq /= strq.w;\r\n                        rsmColor *= textureSample(rsmTextureProjectionSampler, rsmTextureProjectionSamplerSampler, strq.xy).rgb;\r\n                    }\r\n                    #endif\r\n                    #ifdef RSMCREATE_LIGHT_IS_SPOT\r\n                    {\r\n                        var cosAngle = max(0., dot(uniforms.rsmSpotInfo.xyz, normalize(fragmentInputs.vPositionW - uniforms.rsmLightPosition)));\r\n                        rsmColor = sign(cosAngle - uniforms.rsmSpotInfo.w) * rsmColor;\r\n                    }\r\n                    #endif\r\n\r\n                    #define MRT_AND_COLOR\r\n                    fragmentOutputs.fragData0 = vec4f(fragmentInputs.vPositionW, 1.);\r\n                    fragmentOutputs.fragData1 = vec4f(normalize(normalW) * 0.5 + 0.5, 1.);\r\n                    fragmentOutputs.fragData2 = vec4f(rsmColor, 1.);\r\n                #endif\r\n            `,\r\n            };\r\n        }\r\n\r\n        return {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            CUSTOM_FRAGMENT_BEGIN: `\r\n                #ifdef RSMCREATE\r\n                    #extension GL_EXT_draw_buffers : require\r\n                #endif\r\n            `,\r\n\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                #ifdef RSMCREATE\r\n                    #ifdef RSMCREATE_PROJTEXTURE\r\n                        uniform highp sampler2D rsmTextureProjectionSampler;                    \r\n                    #endif\r\n                    layout(location = 0) out highp vec4 glFragData[3];\r\n                    vec4 glFragColor;\r\n                #endif\r\n            `,\r\n\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n                #ifdef RSMCREATE\r\n                    vec3 rsmColor = ${this._varAlbedoName} * rsmLightColor;\r\n                    #ifdef RSMCREATE_PROJTEXTURE\r\n                    {\r\n                        vec4 strq = rsmTextureProjectionMatrix * vec4(vPositionW, 1.0);\r\n                        strq /= strq.w;\r\n                        rsmColor *= texture2D(rsmTextureProjectionSampler, strq.xy).rgb;\r\n                    }\r\n                    #endif\r\n                    #ifdef RSMCREATE_LIGHT_IS_SPOT\r\n                    {\r\n                        float cosAngle = max(0., dot(rsmSpotInfo.xyz, normalize(vPositionW - rsmLightPosition)));\r\n                        rsmColor = sign(cosAngle - rsmSpotInfo.w) * rsmColor;\r\n                    }\r\n                    #endif\r\n                    glFragData[0] = vec4(vPositionW, 1.);\r\n                    glFragData[1] = vec4(normalize(normalW) * 0.5 + 0.5, 1.);\r\n                    glFragData[2] = vec4(rsmColor, 1.);\r\n                #endif\r\n            `,\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for reflectiveShadowMap.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterReflectiveShadowMap(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(`BABYLON.RSMCreatePluginMaterial`, RSMCreatePluginMaterial);\r\n}\r\n","import { type ReflectiveShadowMap } from \"../reflectiveShadowMap\";\r\n\r\n/**\r\n * Class used to store the global illumination parameters for a reflective shadow map.\r\n * Instances of this class are used by the GIRSMManager class to generate global illumination for a scene.\r\n */\r\nexport class GIRSM {\r\n    /**\r\n     * The reflective shadow map used to generate the global illumination for the corresponding light.\r\n     */\r\n    public rsm: ReflectiveShadowMap;\r\n\r\n    /**\r\n     * The number of samples to use to generate the global illumination. Default value is 400.\r\n     */\r\n    public numSamples = 400;\r\n\r\n    /**\r\n     * Radius of the circle in the RSM flux texture to read samples from. Default value is 0.1.\r\n     * Valid values are between 0 and 1.\r\n     */\r\n    public radius = 0.1;\r\n\r\n    /**\r\n     * Intensity of the global illumination effect. Default value is 0.1.\r\n     */\r\n    public intensity = 0.1;\r\n\r\n    /**\r\n     * value used to correct for edge artifacts when calculating the global illumination effect. Default value is 0.1.\r\n     * Will depend on your scene.\r\n     */\r\n    public edgeArtifactCorrection = 0.1;\r\n\r\n    /**\r\n     * Defines if samples should be rotated when generating the global illumination effect. Default value is true.\r\n     * Rotating samples will improve the quality of the global illumination effect by trading banding for noise, at the cost of a bit of performance.\r\n     */\r\n    public rotateSample = true;\r\n\r\n    /**\r\n     * Noise scale factor, only used if rotateSample is true. Default value is 100.\r\n     * Will depend on your scene.\r\n     */\r\n    public noiseFactor = 100;\r\n\r\n    /**\r\n     * Defines if the full texture should be used when generating the global illumination effect. Default value is false.\r\n     * If true, values for numSamples, radius, rotateSample and noiseFactor will be ignored and the full texture will be used to generate the global illumination effect.\r\n     * Be careful to use a RSM texture size small enough to limit the number of samples! For eg. a 32x32 texture will generate 1024 samples per pixel!\r\n     */\r\n    public useFullTexture = false;\r\n\r\n    /**\r\n     * Creates a new GIRSM instance\r\n     * @param rsm The reflective shadow map\r\n     */\r\n    constructor(rsm: ReflectiveShadowMap) {\r\n        this.rsm = rsm;\r\n    }\r\n\r\n    /**\r\n     * Disposes the GIRSM\r\n     */\r\n    public dispose() {\r\n        this.rsm.dispose();\r\n    }\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { type GIRSM } from \"./giRSM\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture.pure\";\r\nimport { PostProcess } from \"core/PostProcesses/postProcess.pure\";\r\nimport { Observable } from \"core/Misc/observable.pure\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\nimport { Layer } from \"core/Layers/layer\";\r\nimport { Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { type RenderTargetWrapper } from \"core/Engines/renderTargetWrapper\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase.pure\";\r\nimport { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { type StandardMaterial } from \"core/Materials/standardMaterial.pure\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial.pure\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { type AbstractEngine } from \"core/Engines/abstractEngine.pure\";\r\nimport { GeometryBufferRenderer } from \"../geometryBufferRenderer.pure\";\r\nimport { BaseTexture } from \"core/Materials/Textures/baseTexture.pure\";\r\nimport { type WebGPURenderTargetWrapper } from \"core/Engines/WebGPU/webgpuRenderTargetWrapper\";\r\nimport { expandToProperty, serialize } from \"core/Misc/decorators\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { RegisterClass } from \"core/Misc/typeStore\";\r\n\r\n/**\r\n * Reflective Shadow Maps were first described in http://www.klayge.org/material/3_12/GI/rsm.pdf by Carsten Dachsbacher and Marc Stamminger\r\n * Further explanations and implementations can be found in:\r\n * - Jaker video explaining RSM and its implementation: https://www.youtube.com/watch?v=LJQQdBsOYPM\r\n * - C++ implementation by Luis Angel: https://github.com/imyoungmin/RSM\r\n * - Javascript implementation by Erkaman: https://github.com/Erkaman/webgl-rsm\r\n */\r\n\r\n/**\r\n * Class used to manage the global illumination contribution calculated from reflective shadow maps (RSM).\r\n */\r\nexport class GIRSMManager {\r\n    private _scene: Scene;\r\n    private _engine: AbstractEngine;\r\n    private _giRSM: GIRSM[] = [];\r\n    private _materialsWithRenderPlugin: Material[];\r\n    private _sampleTexture: RawTexture;\r\n    private _maxSamples: number;\r\n    private _blurRTT: Nullable<RenderTargetTexture> = null;\r\n    private _blurPostProcesses: Nullable<PostProcess[]> = null;\r\n    private _blurXPostprocess: Nullable<PostProcess> = null;\r\n    private _blurYPostprocess: Nullable<PostProcess> = null;\r\n    private _upsamplingXPostprocess: Nullable<PostProcess> = null;\r\n    private _upsamplingYPostprocess: Nullable<PostProcess> = null;\r\n    private _ppGlobalIllumination: PostProcess[] = [];\r\n    private _drawPhaseObserver: Observer<Scene>;\r\n    private _debugLayer: Layer;\r\n    private _counters: Array<{ name: string; value: number }>;\r\n    private _countersRTW: Array<RenderTargetWrapper[]>;\r\n    private _firstActivation = true;\r\n    private _geomBufferEnabled = false;\r\n    private _geomBufferEnablePosition = false;\r\n    private _tempMatrix = new Matrix();\r\n\r\n    private _enable = false;\r\n\r\n    /**\r\n     * Defines the default texture types and formats used by the geometry buffer renderer.\r\n     */\r\n    public static GeometryBufferTextureTypesAndFormats: { [key: number]: { textureType: number; textureFormat: number } } = {\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        0: { textureType: Constants.TEXTURETYPE_HALF_FLOAT, textureFormat: Constants.TEXTUREFORMAT_R }, // depth\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        1: { textureType: Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV, textureFormat: Constants.TEXTUREFORMAT_RGBA }, // normal\r\n        // eslint-disable-next-line @typescript-eslint/naming-convention\r\n        2: { textureType: Constants.TEXTURETYPE_HALF_FLOAT, textureFormat: Constants.TEXTUREFORMAT_RGBA }, // position\r\n    };\r\n\r\n    /**\r\n     * Enables or disables the manager. Default is false.\r\n     * If disabled, the global illumination won't be calculated and the scene will be rendered normally, without any global illumination contribution.\r\n     */\r\n    public get enable() {\r\n        return this._enable;\r\n    }\r\n\r\n    public set enable(enable: boolean) {\r\n        if (this._giRSM.length === 0) {\r\n            enable = false;\r\n        }\r\n\r\n        if (enable === this._enable) {\r\n            return;\r\n        }\r\n\r\n        this._enable = enable;\r\n        this._debugLayer.isEnabled = this._showOnlyGI && enable;\r\n        for (const mat of this._materialsWithRenderPlugin) {\r\n            if (mat.pluginManager) {\r\n                const plugin = mat.pluginManager.getPlugin(GIRSMRenderPluginMaterial.Name) as GIRSMRenderPluginMaterial;\r\n                plugin.isEnabled = enable;\r\n            }\r\n        }\r\n\r\n        this.recreateResources(!enable);\r\n    }\r\n\r\n    /**\r\n     * Defines if the global illumination calculation is paused or not.\r\n     * Use this setting to pause the global illumination calculation when you know that the scene (camera/mesh/light positions) is not changing anymore to save some GPU power.\r\n     * The scene will still be rendered with the latest global illumination contribution.\r\n     */\r\n    public pause = false;\r\n\r\n    private _enableBlur = true;\r\n\r\n    /**\r\n     * Defines if the global illumination contribution should be blurred or not (using a bilateral blur). Default is true.\r\n     */\r\n    public get enableBlur() {\r\n        return this._enableBlur;\r\n    }\r\n\r\n    public set enableBlur(enable: boolean) {\r\n        if (enable === this._enableBlur) {\r\n            return;\r\n        }\r\n\r\n        this._enableBlur = enable;\r\n        this.recreateResources();\r\n    }\r\n\r\n    private _useQualityBlur = false;\r\n\r\n    /**\r\n     * Defines if the blur should be done with a better quality but slower or not. Default is false.\r\n     */\r\n    public get useQualityBlur() {\r\n        return this._useQualityBlur;\r\n    }\r\n\r\n    public set useQualityBlur(enable: boolean) {\r\n        if (enable === this._useQualityBlur) {\r\n            return;\r\n        }\r\n\r\n        this._useQualityBlur = enable;\r\n        this.recreateResources();\r\n    }\r\n\r\n    /**\r\n     * Defines the depth threshold used by the bilateral blur post-processes (also used by the upsampling, if enabled).\r\n     * You may have to change this value, depending on your scene.\r\n     */\r\n    public blurDepthThreshold = 0.05;\r\n\r\n    /**\r\n     * Defines the normal threshold used by the bilateral blur post-processes (also used by the upsampling, if enabled).\r\n     * You may have to change this value, depending on your scene.\r\n     */\r\n    public blurNormalThreshold = 0.25;\r\n\r\n    /**\r\n     * Defines the kernel size used by the bilateral blur post-processes. Default is 12.\r\n     */\r\n    public blurKernel = 12;\r\n\r\n    private _forceFullSizeBlur = false;\r\n\r\n    /**\r\n     * Defines if the blur should be done at full resolution or not. Default is false.\r\n     * If this setting is enabled, upampling will be disabled (ignored) as it is not needed anymore.\r\n     */\r\n    public get fullSizeBlur() {\r\n        return this._forceFullSizeBlur;\r\n    }\r\n\r\n    public set fullSizeBlur(mode: boolean) {\r\n        if (this._forceFullSizeBlur === mode) {\r\n            return;\r\n        }\r\n\r\n        this._forceFullSizeBlur = mode;\r\n        this.recreateResources();\r\n    }\r\n\r\n    private _useQualityUpsampling = false;\r\n\r\n    /**\r\n     * Defines if the upsampling should be done with a better quality but slower or not. Default is false.\r\n     */\r\n    public get useQualityUpsampling() {\r\n        return this._useQualityUpsampling;\r\n    }\r\n\r\n    public set useQualityUpsampling(enable: boolean) {\r\n        if (enable === this._useQualityUpsampling) {\r\n            return;\r\n        }\r\n\r\n        this._useQualityUpsampling = enable;\r\n        this.recreateResources();\r\n    }\r\n\r\n    /**\r\n     * Defines the kernel size used by the bilateral upsampling post-processes. Default is 6.\r\n     */\r\n    public upsamplerKernel = 6;\r\n\r\n    private _showOnlyGI = false;\r\n\r\n    /**\r\n     * Defines if the debug layer should be enabled or not. Default is false.\r\n     * Use this setting for debugging purpose, to show the global illumination contribution only.\r\n     */\r\n    public get showOnlyGI() {\r\n        return this._showOnlyGI;\r\n    }\r\n\r\n    public set showOnlyGI(show) {\r\n        if (this._showOnlyGI === show) {\r\n            return;\r\n        }\r\n\r\n        this._showOnlyGI = show;\r\n        this._debugLayer.isEnabled = show;\r\n    }\r\n\r\n    private _use32BitsDepthBuffer = false;\r\n\r\n    /**\r\n     * Defines if the depth buffer used by the geometry buffer renderer should be 32 bits or not. Default is false (16 bits).\r\n     */\r\n    public get use32BitsDepthBuffer() {\r\n        return this._use32BitsDepthBuffer;\r\n    }\r\n\r\n    public set use32BitsDepthBuffer(enable: boolean) {\r\n        if (this._use32BitsDepthBuffer === enable) {\r\n            return;\r\n        }\r\n\r\n        this._use32BitsDepthBuffer = enable;\r\n        this.recreateResources();\r\n    }\r\n\r\n    private _outputDimensions: { width: number; height: number };\r\n\r\n    /**\r\n     * Sets the output dimensions of the final process. It should normally be the same as the output dimensions of the screen.\r\n     * @param dimensions The dimensions of the output texture (width and height)\r\n     */\r\n    public setOutputDimensions(dimensions: { width: number; height: number }) {\r\n        this._outputDimensions = dimensions;\r\n        this.recreateResources();\r\n    }\r\n\r\n    private _giTextureDimensions: { width: number; height: number };\r\n\r\n    /**\r\n     * Sets the dimensions of the GI texture. Try to use the smallest size possible for better performance.\r\n     * @param dimensions The dimensions of the GI texture (width and height)\r\n     */\r\n    public setGITextureDimensions(dimensions: { width: number; height: number }) {\r\n        this._giTextureDimensions = dimensions;\r\n        this.recreateResources();\r\n    }\r\n\r\n    private _giTextureType: number;\r\n\r\n    /**\r\n     * Gets or sets the texture type used by the GI texture. Default is Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV.\r\n     */\r\n    public get giTextureType() {\r\n        return this._giTextureType;\r\n    }\r\n\r\n    public set giTextureType(textureType: number) {\r\n        if (this._giTextureType === textureType) {\r\n            return;\r\n        }\r\n\r\n        this._giTextureType = textureType;\r\n        this.recreateResources();\r\n    }\r\n\r\n    /** Shader language used by the material */\r\n    protected _shaderLanguage = ShaderLanguage.GLSL;\r\n\r\n    /** Gets the shader language used in this material. */\r\n    public get shaderLanguage(): ShaderLanguage {\r\n        return this._shaderLanguage;\r\n    }\r\n\r\n    /**\r\n     * Gets the list of GIRSM used by the manager.\r\n     */\r\n    public get giRSM() {\r\n        return this._giRSM;\r\n    }\r\n\r\n    /**\r\n     * Adds a (list of) GIRSM to the manager.\r\n     * @param rsm The GIRSM (or array of GIRSM) to add to the manager\r\n     */\r\n    public addGIRSM(rsm: GIRSM | GIRSM[]) {\r\n        if (Array.isArray(rsm)) {\r\n            this._giRSM.push(...rsm);\r\n        } else {\r\n            this._giRSM.push(rsm);\r\n        }\r\n\r\n        this.recreateResources();\r\n    }\r\n\r\n    /**\r\n     * Removes a (list of) GIRSM from the manager.\r\n     * @param rsm The GIRSM (or array of GIRSM) to remove from the manager\r\n     */\r\n    public removeGIRSM(rsm: GIRSM | GIRSM[]) {\r\n        if (Array.isArray(rsm)) {\r\n            for (let i = 0; i < rsm.length; ++i) {\r\n                const idx = this._giRSM.indexOf(rsm[i]);\r\n                if (idx !== -1) {\r\n                    this._giRSM.splice(idx, 1);\r\n                }\r\n            }\r\n        } else {\r\n            const idx = this._giRSM.indexOf(rsm);\r\n            if (idx !== -1) {\r\n                this._giRSM.splice(idx, 1);\r\n            }\r\n        }\r\n\r\n        if (this._giRSM.length === 0) {\r\n            this.enable = false;\r\n        } else {\r\n            this.recreateResources();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add a material to the manager. This will enable the global illumination contribution for the material.\r\n     * @param material Material that will be affected by the global illumination contribution. If not provided, all materials of the scene will be affected.\r\n     */\r\n    public addMaterial(material?: Material) {\r\n        if (material) {\r\n            this._addGISupportToMaterial(material);\r\n        } else {\r\n            for (const mesh of this._scene.meshes) {\r\n                if (mesh.getTotalVertices() > 0 && mesh.isEnabled() && mesh.material) {\r\n                    this._addGISupportToMaterial(mesh.material);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the list of GPU counters used by the manager.\r\n     * GPU timing measurements must be enabled for the counters to be filled (engine.enableGPUTimingMeasurements = true).\r\n     * Only available with WebGPU. You will still get the list of counters with other engines but the values will always be 0.\r\n     */\r\n    public get countersGPU(): Array<{ name: string; value: number }> {\r\n        return this._counters;\r\n    }\r\n\r\n    /**\r\n     * Recreates the resources used by the manager.\r\n     * You should normally not have to call this method manually, except if you change the useFullTexture property of a GIRSM, because the manager won't track this change.\r\n     * @param disposeGeometryBufferRenderer Defines if the geometry buffer renderer should be disposed and recreated. Default is false.\r\n     */\r\n    public recreateResources(disposeGeometryBufferRenderer = false) {\r\n        if (!this._shadersLoaded) {\r\n            this._onShaderLoadedObservable.addOnce(() => {\r\n                this.recreateResources(disposeGeometryBufferRenderer);\r\n            });\r\n            return;\r\n        }\r\n\r\n        this._disposePostProcesses(disposeGeometryBufferRenderer);\r\n        this._createPostProcesses();\r\n        this._setPluginParameters();\r\n    }\r\n\r\n    /**\r\n     * Generates the sample texture used by the the global illumination calculation process.\r\n     * @param maxSamples The maximum number of samples to generate in the texture. Default value is 2048. The numSamples property of the GIRSM should be less than or equal to this value!\r\n     */\r\n    public generateSampleTexture(maxSamples: number) {\r\n        this._sampleTexture?.dispose();\r\n\r\n        this._maxSamples = maxSamples;\r\n\r\n        const data = new Float32Array(this._maxSamples * 4);\r\n        for (let i = 0; i < this._maxSamples; i++) {\r\n            const xi1 = Math.random();\r\n            const xi2 = Math.random();\r\n\r\n            const x = xi1 * Math.sin(2 * Math.PI * xi2);\r\n            const y = xi1 * Math.cos(2 * Math.PI * xi2);\r\n\r\n            data[i * 4 + 0] = x;\r\n            data[i * 4 + 1] = y;\r\n            data[i * 4 + 2] = xi1 * xi1;\r\n            data[i * 4 + 3] = 1;\r\n        }\r\n\r\n        this._sampleTexture = new RawTexture(\r\n            data,\r\n            this._maxSamples,\r\n            1,\r\n            Constants.TEXTUREFORMAT_RGBA,\r\n            this._scene,\r\n            false,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            Constants.TEXTURETYPE_FLOAT\r\n        );\r\n        this._sampleTexture.name = \"GIRSMSamples\";\r\n    }\r\n\r\n    /**\r\n     * Disposes the manager.\r\n     */\r\n    public dispose() {\r\n        this._disposePostProcesses(true);\r\n        this._debugLayer.texture?.dispose();\r\n        this._debugLayer.dispose();\r\n        this._scene.onBeforeDrawPhaseObservable.remove(this._drawPhaseObserver);\r\n        this._onShaderLoadedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Creates a new GIRSMManager\r\n     * @param scene The scene\r\n     * @param outputDimensions The dimensions of the output texture (width and height). Should normally be the same as the output dimensions of the screen.\r\n     * @param giTextureDimensions The dimensions of the GI texture (width and height). Try to use the smallest size possible for better performance.\r\n     * @param maxSamples The maximum number of samples to generate in the sample texture. Default value is 2048. The numSamples property of the GIRSM should be less than or equal to this value!\r\n     * @param giTextureType The texture type used by the GI texture. Default is Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV.\r\n     */\r\n    constructor(\r\n        scene: Scene,\r\n        outputDimensions: { width: number; height: number },\r\n        giTextureDimensions = { width: 256, height: 256 },\r\n        maxSamples = 2048,\r\n        giTextureType = Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV\r\n    ) {\r\n        this._scene = scene;\r\n        this._engine = scene.getEngine();\r\n        this._outputDimensions = outputDimensions;\r\n        this._giTextureDimensions = giTextureDimensions;\r\n        this._giTextureType = giTextureType;\r\n        this._materialsWithRenderPlugin = [];\r\n        this._maxSamples = maxSamples;\r\n        this._debugLayer = new Layer(\"debug layer\", null, this._scene, false);\r\n        this._debugLayer.isEnabled = false;\r\n        this._counters = [];\r\n        this._countersRTW = [];\r\n\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._initShaderSourceAsync();\r\n\r\n        this.generateSampleTexture(maxSamples);\r\n\r\n        this._drawPhaseObserver = this._scene.onBeforeDrawPhaseObservable.add(() => {\r\n            const currentRenderTarget = this._engine._currentRenderTarget;\r\n            let rebindCurrentRenderTarget = false;\r\n\r\n            if (this._enable && this._shadersLoaded) {\r\n                if (!this.pause && this._ppGlobalIllumination.length > 0) {\r\n                    this._scene.postProcessManager.directRender(this._ppGlobalIllumination, this._ppGlobalIllumination[0].inputTexture);\r\n                    this._engine.unBindFramebuffer(this._ppGlobalIllumination[0].inputTexture, true);\r\n\r\n                    this._engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n                    rebindCurrentRenderTarget = true;\r\n\r\n                    if (this.enableBlur && this._blurPostProcesses) {\r\n                        this._scene.postProcessManager.directRender(this._blurPostProcesses, this._blurRTT!.renderTarget, true);\r\n                        this._engine.unBindFramebuffer(this._blurRTT!.renderTarget!, true);\r\n                    }\r\n                }\r\n\r\n                for (let i = 0; i < this._counters.length; ++i) {\r\n                    const rtws = this._countersRTW[i];\r\n                    for (let t = 0; t < rtws.length; ++t) {\r\n                        if (t === 0) {\r\n                            this._counters[i].value = this.pause ? 0 : ((rtws[t] as WebGPURenderTargetWrapper).gpuTimeInFrame?.counter.lastSecAverage ?? 0);\r\n                        } else if (!this.pause) {\r\n                            this._counters[i].value += (rtws[t] as WebGPURenderTargetWrapper).gpuTimeInFrame?.counter.lastSecAverage ?? 0;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this._scene.activeCamera) {\r\n                    this._engine.setViewport(this._scene.activeCamera.viewport);\r\n                }\r\n            }\r\n\r\n            if (rebindCurrentRenderTarget && currentRenderTarget) {\r\n                this._engine.bindFramebuffer(currentRenderTarget);\r\n            }\r\n        });\r\n    }\r\n\r\n    private _shadersLoaded = false;\r\n    private _onShaderLoadedObservable = new Observable<void>();\r\n    private async _initShaderSourceAsync() {\r\n        const engine = this._engine;\r\n\r\n        if (engine.isWebGPU) {\r\n            this._shaderLanguage = ShaderLanguage.WGSL;\r\n\r\n            await Promise.all([\r\n                import(\"../../ShadersWGSL/bilateralBlur.fragment\"),\r\n                import(\"../../ShadersWGSL/bilateralBlurQuality.fragment\"),\r\n                import(\"../../ShadersWGSL/rsmGlobalIllumination.fragment\"),\r\n                import(\"../../ShadersWGSL/rsmFullGlobalIllumination.fragment\"),\r\n            ]);\r\n        } else {\r\n            await Promise.all([\r\n                import(\"../../Shaders/bilateralBlur.fragment\"),\r\n                import(\"../../Shaders/bilateralBlurQuality.fragment\"),\r\n                import(\"../../Shaders/rsmGlobalIllumination.fragment\"),\r\n                import(\"../../Shaders/rsmFullGlobalIllumination.fragment\"),\r\n            ]);\r\n        }\r\n        this._shadersLoaded = true;\r\n        this._onShaderLoadedObservable.notifyObservers();\r\n    }\r\n\r\n    protected _disposePostProcesses(disposeGeometryBufferRenderer = false) {\r\n        this._blurRTT?.dispose();\r\n        this._blurRTT = null;\r\n        this._blurPostProcesses = [];\r\n        this._blurXPostprocess?.dispose();\r\n        this._blurXPostprocess = null;\r\n        this._blurYPostprocess?.dispose();\r\n        this._blurYPostprocess = null;\r\n        this._upsamplingXPostprocess?.dispose();\r\n        this._upsamplingXPostprocess = null;\r\n        this._upsamplingYPostprocess?.dispose();\r\n        this._upsamplingYPostprocess = null;\r\n        for (const ppGlobalIllumination of this._ppGlobalIllumination) {\r\n            ppGlobalIllumination.dispose();\r\n        }\r\n        this._ppGlobalIllumination = [];\r\n        if (disposeGeometryBufferRenderer) {\r\n            if (this._geomBufferEnabled) {\r\n                this._scene.enableGeometryBufferRenderer();\r\n                this._scene.geometryBufferRenderer!.enablePosition = this._geomBufferEnablePosition;\r\n            } else {\r\n                this._scene.disableGeometryBufferRenderer();\r\n            }\r\n        }\r\n        this._counters = [];\r\n        this._countersRTW = [];\r\n    }\r\n\r\n    protected _setPluginParameters() {\r\n        if (!this._enable) {\r\n            return;\r\n        }\r\n\r\n        for (const mat of this._materialsWithRenderPlugin) {\r\n            if (mat.pluginManager) {\r\n                const plugin = mat.pluginManager.getPlugin<GIRSMRenderPluginMaterial>(GIRSMRenderPluginMaterial.Name)!;\r\n                plugin.textureGIContrib = this.enableBlur ? this._blurRTT!.renderTarget!.texture! : this._ppGlobalIllumination[0].inputTexture.texture!;\r\n                plugin.outputTextureWidth = this._outputDimensions.width;\r\n                plugin.outputTextureHeight = this._outputDimensions.height;\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _createPostProcesses() {\r\n        if (!this._enable) {\r\n            return;\r\n        }\r\n\r\n        const textureFormat = this._giTextureType === Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV ? Constants.TEXTUREFORMAT_RGB : Constants.TEXTUREFORMAT_RGBA;\r\n\r\n        if (this._firstActivation) {\r\n            this._firstActivation = false;\r\n            this._geomBufferEnabled = !!this._scene.geometryBufferRenderer;\r\n            this._geomBufferEnablePosition = this._scene.geometryBufferRenderer?.enablePosition ?? false;\r\n        }\r\n\r\n        if (!this._geomBufferEnabled) {\r\n            this._scene.disableGeometryBufferRenderer();\r\n        }\r\n\r\n        const geometryBufferRenderer = this._scene.enableGeometryBufferRenderer(\r\n            this._enableBlur ? this._outputDimensions : this._giTextureDimensions,\r\n            this._use32BitsDepthBuffer ? Constants.TEXTUREFORMAT_DEPTH32_FLOAT : Constants.TEXTUREFORMAT_DEPTH16,\r\n            GIRSMManager.GeometryBufferTextureTypesAndFormats\r\n        );\r\n\r\n        if (!geometryBufferRenderer) {\r\n            throw new Error(\"Geometry buffer renderer is not supported but is required for GIRSMManager.\");\r\n        }\r\n\r\n        geometryBufferRenderer.enablePosition = true;\r\n        if (!this._geomBufferEnabled) {\r\n            geometryBufferRenderer.generateNormalsInWorldSpace = true;\r\n        }\r\n\r\n        const decodeGeometryBufferNormals = geometryBufferRenderer.normalsAreUnsigned;\r\n        const normalsAreInWorldSpace = geometryBufferRenderer.generateNormalsInWorldSpace;\r\n\r\n        this._counters.push({ name: \"Geometry buffer renderer\", value: 0 });\r\n        this._countersRTW.push([this._scene.geometryBufferRenderer!.getGBuffer().renderTarget!]);\r\n\r\n        let defines = \"\";\r\n        if (decodeGeometryBufferNormals) {\r\n            defines += \"#define DECODE_NORMAL\\n\";\r\n        }\r\n        if (!normalsAreInWorldSpace) {\r\n            defines += \"#define TRANSFORM_NORMAL\\n\";\r\n        }\r\n\r\n        for (let i = 0; i < this._giRSM.length; ++i) {\r\n            const giRSM = this._giRSM[i];\r\n            const rsm = giRSM.rsm;\r\n\r\n            const ppGlobalIllumination = new PostProcess(\"RSMGlobalIllumination\" + i, giRSM.useFullTexture ? \"rsmFullGlobalIllumination\" : \"rsmGlobalIllumination\", {\r\n                ...this._giTextureDimensions,\r\n                uniforms: [\"rsmLightMatrix\", \"rsmInfo\", \"rsmInfo2\", \"invView\"],\r\n                samplers: [\"normalSampler\", \"rsmPositionW\", \"rsmNormalW\", \"rsmFlux\", \"rsmSamples\"],\r\n                defines,\r\n                samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n                engine: this._engine,\r\n                textureType: this._giTextureType,\r\n                textureFormat,\r\n                shaderLanguage: this._shaderLanguage,\r\n            });\r\n\r\n            this._ppGlobalIllumination.push(ppGlobalIllumination);\r\n\r\n            if (i !== 0) {\r\n                ppGlobalIllumination.shareOutputWith(this._ppGlobalIllumination[0]);\r\n                ppGlobalIllumination.alphaMode = Constants.ALPHA_ADD;\r\n            }\r\n\r\n            ppGlobalIllumination.autoClear = false;\r\n            ppGlobalIllumination.externalTextureSamplerBinding = true;\r\n            ppGlobalIllumination.onApplyObservable.add((effect) => {\r\n                effect.setTexture(\r\n                    \"textureSampler\",\r\n                    geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.POSITION_TEXTURE_TYPE)]\r\n                );\r\n                effect.setTexture(\r\n                    \"normalSampler\",\r\n                    geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE)]\r\n                );\r\n                effect.setTexture(\"rsmPositionW\", rsm.positionWorldTexture);\r\n                effect.setTexture(\"rsmNormalW\", rsm.normalWorldTexture);\r\n                effect.setTexture(\"rsmFlux\", rsm.fluxTexture);\r\n                effect.setMatrix(\"rsmLightMatrix\", rsm.lightTransformationMatrix);\r\n                if (!giRSM.useFullTexture) {\r\n                    effect.setTexture(\"rsmSamples\", this._sampleTexture);\r\n                    effect.setFloat4(\"rsmInfo\", giRSM.numSamples, giRSM.radius, giRSM.intensity, giRSM.edgeArtifactCorrection);\r\n                    effect.setFloat4(\r\n                        \"rsmInfo2\",\r\n                        giRSM.noiseFactor,\r\n                        giRSM.rotateSample ? 1 : 0,\r\n                        rsm.fluxTexture.getInternalTexture()!.width,\r\n                        rsm.fluxTexture.getInternalTexture()!.height\r\n                    );\r\n                } else {\r\n                    effect.setFloat4(\r\n                        \"rsmInfo\",\r\n                        rsm.fluxTexture.getInternalTexture()!.width,\r\n                        rsm.fluxTexture.getInternalTexture()!.height,\r\n                        giRSM.intensity,\r\n                        giRSM.edgeArtifactCorrection\r\n                    );\r\n                }\r\n                if (!normalsAreInWorldSpace) {\r\n                    this._tempMatrix.copyFrom(this._scene.activeCamera!.getViewMatrix());\r\n                    this._tempMatrix.invert();\r\n                    effect.setMatrix(\"invView\", this._tempMatrix);\r\n                }\r\n            });\r\n        }\r\n\r\n        for (const ppGlobalIllumination of this._ppGlobalIllumination) {\r\n            if (!ppGlobalIllumination.inputTexture) {\r\n                ppGlobalIllumination.resize(this._giTextureDimensions.width, this._giTextureDimensions.height);\r\n            }\r\n        }\r\n\r\n        this._counters.push({ name: \"GI generation\", value: 0 });\r\n        this._countersRTW.push([this._ppGlobalIllumination[0].inputTexture]);\r\n\r\n        if (this._enableBlur) {\r\n            const blurTextureSize = this._forceFullSizeBlur ? this._outputDimensions : this._giTextureDimensions;\r\n\r\n            this._blurRTT = new RenderTargetTexture(\"GIRSMContribution\", this._outputDimensions, this._scene, {\r\n                type: this._giTextureType,\r\n                format: textureFormat,\r\n                generateDepthBuffer: false,\r\n            });\r\n            this._blurRTT.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n            this._blurRTT.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n            this._blurRTT.updateSamplingMode(Constants.TEXTURE_NEAREST_SAMPLINGMODE);\r\n            this._blurRTT.skipInitialClear = true;\r\n\r\n            const blurRTWs: RenderTargetWrapper[] = [];\r\n\r\n            this._counters.push({ name: \"GI blur\", value: 0 });\r\n            this._countersRTW.push(blurRTWs);\r\n\r\n            // Bilateral blur\r\n            this._blurXPostprocess = new PostProcess(this._useQualityBlur ? \"BilateralBlur\" : \"BilateralBlurX\", this._useQualityBlur ? \"bilateralBlurQuality\" : \"bilateralBlur\", {\r\n                uniforms: [\"filterSize\", \"blurDir\", \"depthThreshold\", \"normalThreshold\"],\r\n                samplers: [\"depthSampler\", \"normalSampler\"],\r\n                defines: decodeGeometryBufferNormals ? \"#define DECODE_NORMAL\" : undefined,\r\n                size: blurTextureSize,\r\n                samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n                engine: this._engine,\r\n                textureType: this._giTextureType,\r\n                textureFormat,\r\n                shaderLanguage: this._shaderLanguage,\r\n            });\r\n\r\n            this._blurXPostprocess.onApplyObservable.add((effect) => {\r\n                effect._bindTexture(\"textureSampler\", this._ppGlobalIllumination[0].inputTexture.texture);\r\n                effect.setTexture(\"depthSampler\", geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.DEPTH_TEXTURE_TYPE)]);\r\n                effect.setTexture(\r\n                    \"normalSampler\",\r\n                    geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE)]\r\n                );\r\n                effect.setInt(\"filterSize\", this.blurKernel);\r\n                effect.setFloat2(\"blurDir\", 1 / this._giTextureDimensions.width, this._useQualityBlur ? 1 / this._giTextureDimensions.height : 0);\r\n                effect.setFloat(\"depthThreshold\", this.blurDepthThreshold);\r\n                effect.setFloat(\"normalThreshold\", this.blurNormalThreshold);\r\n            });\r\n\r\n            this._blurXPostprocess.externalTextureSamplerBinding = true;\r\n            this._blurXPostprocess.autoClear = false;\r\n\r\n            if (!this._useQualityBlur) {\r\n                this._blurYPostprocess = new PostProcess(\"BilateralBlurY\", \"bilateralBlur\", {\r\n                    uniforms: [\"filterSize\", \"blurDir\", \"depthThreshold\", \"normalThreshold\"],\r\n                    samplers: [\"depthSampler\", \"normalSampler\"],\r\n                    defines: decodeGeometryBufferNormals ? \"#define DECODE_NORMAL\" : undefined,\r\n                    size: blurTextureSize,\r\n                    samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n                    engine: this._engine,\r\n                    textureType: this._giTextureType,\r\n                    textureFormat,\r\n                    shaderLanguage: this._shaderLanguage,\r\n                });\r\n\r\n                this._blurYPostprocess.autoClear = false;\r\n                this._blurYPostprocess.onApplyObservable.add((effect) => {\r\n                    effect.setTexture(\r\n                        \"depthSampler\",\r\n                        geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.DEPTH_TEXTURE_TYPE)]\r\n                    );\r\n                    effect.setTexture(\r\n                        \"normalSampler\",\r\n                        geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE)]\r\n                    );\r\n                    effect.setInt(\"filterSize\", this.blurKernel);\r\n                    effect.setFloat2(\"blurDir\", 0, 1 / this._giTextureDimensions.height);\r\n                    effect.setFloat(\"depthThreshold\", this.blurDepthThreshold);\r\n                    effect.setFloat(\"normalThreshold\", this.blurNormalThreshold);\r\n                });\r\n\r\n                this._blurYPostprocess.resize(blurTextureSize.width, blurTextureSize.height);\r\n\r\n                blurRTWs.push(this._blurYPostprocess.inputTexture);\r\n            }\r\n\r\n            this._blurPostProcesses = [this._blurXPostprocess];\r\n            if (this._blurYPostprocess) {\r\n                this._blurPostProcesses.push(this._blurYPostprocess);\r\n            }\r\n\r\n            // Bilateral upsampling\r\n            const giFullDimensions = this._giTextureDimensions.width >= this._outputDimensions.width && this._giTextureDimensions.height >= this._outputDimensions.height;\r\n\r\n            if (!giFullDimensions && !this._forceFullSizeBlur) {\r\n                const upsamplingRTWs: RenderTargetWrapper[] = [];\r\n\r\n                this._counters.push({ name: \"GI upsampling\", value: 0 });\r\n                this._countersRTW.push(upsamplingRTWs);\r\n\r\n                this._upsamplingXPostprocess = new PostProcess(\r\n                    this._useQualityUpsampling ? \"BilateralUpsampling\" : \"BilateralUpsamplingX\",\r\n                    this._useQualityUpsampling ? \"bilateralBlurQuality\" : \"bilateralBlur\",\r\n                    {\r\n                        uniforms: [\"filterSize\", \"blurDir\", \"depthThreshold\", \"normalThreshold\"],\r\n                        samplers: [\"depthSampler\", \"normalSampler\"],\r\n                        defines: decodeGeometryBufferNormals ? \"#define DECODE_NORMAL\" : undefined,\r\n                        size: blurTextureSize,\r\n                        samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n                        engine: this._engine,\r\n                        textureType: this._giTextureType,\r\n                        textureFormat,\r\n                        shaderLanguage: this._shaderLanguage,\r\n                    }\r\n                );\r\n\r\n                this._upsamplingXPostprocess.autoClear = false;\r\n                this._upsamplingXPostprocess.onApplyObservable.add((effect) => {\r\n                    effect.setTexture(\r\n                        \"depthSampler\",\r\n                        geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.DEPTH_TEXTURE_TYPE)]\r\n                    );\r\n                    effect.setTexture(\r\n                        \"normalSampler\",\r\n                        geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE)]\r\n                    );\r\n                    effect.setInt(\"filterSize\", this.upsamplerKernel);\r\n                    effect.setFloat2(\"blurDir\", 1 / this._outputDimensions.width, this._useQualityUpsampling ? 1 / this._outputDimensions.height : 0);\r\n                    effect.setFloat(\"depthThreshold\", this.blurDepthThreshold);\r\n                    effect.setFloat(\"normalThreshold\", this.blurNormalThreshold);\r\n                });\r\n\r\n                this._upsamplingXPostprocess.resize(blurTextureSize.width, blurTextureSize.height);\r\n\r\n                blurRTWs.push(this._upsamplingXPostprocess.inputTexture);\r\n\r\n                if (!this.useQualityUpsampling) {\r\n                    this._upsamplingYPostprocess = new PostProcess(\"BilateralUpsamplingY\", \"bilateralBlur\", {\r\n                        uniforms: [\"filterSize\", \"blurDir\", \"depthThreshold\", \"normalThreshold\"],\r\n                        samplers: [\"depthSampler\", \"normalSampler\"],\r\n                        defines: decodeGeometryBufferNormals ? \"#define DECODE_NORMAL\" : undefined,\r\n                        size: this._outputDimensions,\r\n                        samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n                        engine: this._engine,\r\n                        textureType: this._giTextureType,\r\n                        textureFormat,\r\n                        shaderLanguage: this._shaderLanguage,\r\n                    });\r\n\r\n                    this._upsamplingYPostprocess.autoClear = false;\r\n                    this._upsamplingYPostprocess.onApplyObservable.add((effect) => {\r\n                        effect.setTexture(\r\n                            \"depthSampler\",\r\n                            geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.DEPTH_TEXTURE_TYPE)]\r\n                        );\r\n                        effect.setTexture(\r\n                            \"normalSampler\",\r\n                            geometryBufferRenderer.getGBuffer().textures[geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.NORMAL_TEXTURE_TYPE)]\r\n                        );\r\n                        effect.setInt(\"filterSize\", this.upsamplerKernel);\r\n                        effect.setFloat2(\"blurDir\", 0, 1 / this._outputDimensions.height);\r\n                        effect.setFloat(\"depthThreshold\", this.blurDepthThreshold);\r\n                        effect.setFloat(\"normalThreshold\", this.blurNormalThreshold);\r\n                    });\r\n\r\n                    this._upsamplingYPostprocess.resize(this._outputDimensions.width, this._outputDimensions.height);\r\n\r\n                    upsamplingRTWs.push(this._upsamplingYPostprocess.inputTexture);\r\n                }\r\n\r\n                upsamplingRTWs.push(this._blurRTT.renderTarget!);\r\n\r\n                this._blurPostProcesses.push(this._upsamplingXPostprocess);\r\n                if (this._upsamplingYPostprocess) {\r\n                    this._blurPostProcesses.push(this._upsamplingYPostprocess);\r\n                }\r\n            } else {\r\n                blurRTWs.push(this._blurRTT.renderTarget!);\r\n            }\r\n        }\r\n\r\n        this._debugLayer.texture?.dispose();\r\n        this._debugLayer.texture = new BaseTexture(this._scene, this._enableBlur ? this._blurRTT!.renderTarget!.texture : this._ppGlobalIllumination[0].inputTexture.texture);\r\n    }\r\n\r\n    protected _addGISupportToMaterial(material: Material) {\r\n        if (material.pluginManager?.getPlugin(GIRSMRenderPluginMaterial.Name)) {\r\n            return;\r\n        }\r\n\r\n        const plugin = new GIRSMRenderPluginMaterial(material);\r\n\r\n        if (this._enable && this._ppGlobalIllumination.length > 0) {\r\n            plugin.textureGIContrib = this._ppGlobalIllumination[0].inputTexture.texture!;\r\n            plugin.outputTextureWidth = this._outputDimensions.width;\r\n            plugin.outputTextureHeight = this._outputDimensions.height;\r\n        }\r\n\r\n        plugin.isEnabled = this._enable;\r\n\r\n        this._materialsWithRenderPlugin.push(material);\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nclass MaterialGIRSMRenderDefines extends MaterialDefines {\r\n    public RENDER_WITH_GIRSM = false;\r\n    public RSMCREATE_PROJTEXTURE = false;\r\n}\r\n\r\n/**\r\n * Plugin used to render the global illumination contribution.\r\n */\r\nexport class GIRSMRenderPluginMaterial extends MaterialPluginBase {\r\n    private _isPBR;\r\n\r\n    /**\r\n     * Defines the name of the plugin.\r\n     */\r\n    public static readonly Name = \"GIRSMRender\";\r\n\r\n    /**\r\n     * The texture containing the global illumination contribution.\r\n     */\r\n    @serialize()\r\n    public textureGIContrib: InternalTexture;\r\n\r\n    /**\r\n     * The width of the output texture.\r\n     */\r\n    @serialize()\r\n    public outputTextureWidth: number;\r\n\r\n    /**\r\n     * The height of the output texture.\r\n     */\r\n    @serialize()\r\n    public outputTextureHeight: number;\r\n\r\n    private _isEnabled = false;\r\n    /**\r\n     * Defines if the plugin is enabled in the material.\r\n     */\r\n    @serialize()\r\n    @expandToProperty(\"_markAllSubMeshesAsTexturesDirty\")\r\n    public accessor isEnabled = false;\r\n\r\n    protected _markAllSubMeshesAsTexturesDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this._internalMarkAllSubMeshesAsTexturesDirty();\r\n    }\r\n\r\n    private _internalMarkAllSubMeshesAsTexturesDirty: () => void;\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a give shader language.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return true;\r\n    }\r\n\r\n    constructor(material: Material | StandardMaterial | PBRBaseMaterial) {\r\n        super(material, GIRSMRenderPluginMaterial.Name, 310, new MaterialGIRSMRenderDefines());\r\n\r\n        this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag];\r\n\r\n        this._isPBR = material instanceof PBRBaseMaterial;\r\n    }\r\n\r\n    /**\r\n     * Prepares the defines used by the plugin\r\n     * @param defines the defines to prepare\r\n     */\r\n    public override prepareDefines(defines: MaterialGIRSMRenderDefines) {\r\n        defines.RENDER_WITH_GIRSM = this._isEnabled;\r\n    }\r\n\r\n    public override getClassName() {\r\n        return \"GIRSMRenderPluginMaterial\";\r\n    }\r\n\r\n    public override getUniforms() {\r\n        return {\r\n            ubo: [{ name: \"girsmTextureOutputSize\", size: 2, type: \"vec2\" }],\r\n            fragment: `#ifdef RENDER_WITH_GIRSM\r\n                    uniform vec2 girsmTextureOutputSize;\r\n                #endif`,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Gets the samplers used by the plugin\r\n     * @param samplers the list of samplers to update\r\n     */\r\n    public override getSamplers(samplers: string[]) {\r\n        samplers.push(\"girsmTextureGIContrib\");\r\n    }\r\n\r\n    /**\r\n     * Binds the material data for a sub mesh\r\n     * @param uniformBuffer the uniform buffer to update\r\n     */\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer) {\r\n        if (this._isEnabled) {\r\n            uniformBuffer.bindTexture(\"girsmTextureGIContrib\", this.textureGIContrib);\r\n            uniformBuffer.updateFloat2(\"girsmTextureOutputSize\", this.outputTextureWidth, this.outputTextureHeight);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets custom shader code for the plugin\r\n     * @param shaderType the type of shader (vertex or fragment)\r\n     * @param shaderLanguage the shader language\r\n     * @returns the custom shader code\r\n     */\r\n    public override getCustomCode(shaderType: string, shaderLanguage: ShaderLanguage) {\r\n        let frag: { [name: string]: string };\r\n\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            frag = {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                #ifdef RENDER_WITH_GIRSM\r\n                    var girsmTextureGIContribSampler: sampler;\r\n                    var girsmTextureGIContrib: texture_2d<f32>;\r\n\r\n                    fn computeIndirect() -> vec3f {\r\n                        var uv = fragmentInputs.position.xy / uniforms.girsmTextureOutputSize;\r\n                        return textureSample(girsmTextureGIContrib, girsmTextureGIContribSampler, uv).rgb;\r\n                    }\r\n                #endif\r\n            `,\r\n\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION: `\r\n                #ifdef RENDER_WITH_GIRSM\r\n                    finalDiffuse += computeIndirect() * surfaceAlbedo.rgb;\r\n                #endif\r\n            `,\r\n            };\r\n\r\n            if (!this._isPBR) {\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\"] = `\r\n                #ifdef RENDER_WITH_GIRSM\r\n                    color = vec4f(color.rgb + computeIndirect() * baseColor.rgb, color.a);\r\n                #endif\r\n            `;\r\n            }\r\n        } else {\r\n            frag = {\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                #ifdef RENDER_WITH_GIRSM\r\n                    uniform sampler2D girsmTextureGIContrib;\r\n\r\n                    vec3 computeIndirect() {\r\n                        vec2 uv = gl_FragCoord.xy / girsmTextureOutputSize;\r\n                        return texture2D(girsmTextureGIContrib, uv).rgb;\r\n                    }\r\n                #endif\r\n            `,\r\n\r\n                // eslint-disable-next-line @typescript-eslint/naming-convention\r\n                CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION: `\r\n                #ifdef RENDER_WITH_GIRSM\r\n                    finalDiffuse += computeIndirect() * surfaceAlbedo.rgb;\r\n                #endif\r\n            `,\r\n            };\r\n\r\n            if (!this._isPBR) {\r\n                frag[\"CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\"] = `\r\n                #ifdef RENDER_WITH_GIRSM\r\n                    color.rgb += computeIndirect() * baseColor.rgb;\r\n                #endif\r\n            `;\r\n            }\r\n        }\r\n\r\n        return shaderType === \"vertex\" ? null : frag;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for giRSMManager.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGiRSMManager(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(`BABYLON.GIRSMRenderPluginMaterial`, GIRSMRenderPluginMaterial);\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"bilateralBlurPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform sampler2D depthSampler;uniform sampler2D normalSampler;uniform int filterSize;uniform vec2 blurDir;uniform float depthThreshold;uniform float normalThreshold;varying vec2 vUV;void main(void) {vec3 color=textureLod(textureSampler,vUV,0.).rgb;float depth=textureLod(depthSampler,vUV,0.).x;if (depth>=1e6 || depth<=0.) {glFragColor=vec4(color,1.);return;}\nvec3 normal=textureLod(normalSampler,vUV,0.).rgb;\n#ifdef DECODE_NORMAL\nnormal=normal*2.0-1.0;\n#endif\nfloat sigma=float(filterSize);float two_sigma2=2.0*sigma*sigma;float sigmaDepth=depthThreshold;float two_sigmaDepth2=2.0*sigmaDepth*sigmaDepth;float sigmaNormal=normalThreshold;float two_sigmaNormal2=2.0*sigmaNormal*sigmaNormal;vec3 sum=vec3(0.);float wsum=0.;for (int x=-filterSize; x<=filterSize; ++x) {vec2 coords=vec2(x);vec3 sampleColor=textureLod(textureSampler,vUV+coords*blurDir,0.).rgb;float sampleDepth=textureLod(depthSampler,vUV+coords*blurDir,0.).r;vec3 sampleNormal=textureLod(normalSampler,vUV+coords*blurDir,0.).rgb;\n#ifdef DECODE_NORMAL\nsampleNormal=sampleNormal*2.0-1.0;\n#endif\nfloat r=dot(coords,coords);float w=exp(-r/two_sigma2);float depthDelta=abs(sampleDepth-depth);float wd=step(depthDelta,depthThreshold);vec3 normalDelta=abs(sampleNormal-normal);float wn=step(normalDelta.x+normalDelta.y+normalDelta.z,normalThreshold);sum+=sampleColor*w*wd*wn;wsum+=w*wd*wn;}\nglFragColor=vec4(sum/wsum,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const bilateralBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"bilateralBlurQualityPixelShader\";\nconst shader = `uniform sampler2D textureSampler;uniform sampler2D depthSampler;uniform sampler2D normalSampler;uniform int filterSize;uniform vec2 blurDir;uniform float depthThreshold;uniform float normalThreshold;varying vec2 vUV;void main(void) {vec3 color=textureLod(textureSampler,vUV,0.).rgb;float depth=textureLod(depthSampler,vUV,0.).x;if (depth>=1e6 || depth<=0.) {glFragColor=vec4(color,1.);return;}\nvec3 normal=textureLod(normalSampler,vUV,0.).rgb;\n#ifdef DECODE_NORMAL\nnormal=normal*2.0-1.0;\n#endif\nfloat sigma=float(filterSize);float two_sigma2=2.0*sigma*sigma;float sigmaDepth=depthThreshold;float two_sigmaDepth2=2.0*sigmaDepth*sigmaDepth;float sigmaNormal=normalThreshold;float two_sigmaNormal2=2.0*sigmaNormal*sigmaNormal;vec3 sum=vec3(0.);float wsum=0.;for (int x=-filterSize; x<=filterSize; ++x) {for (int y=-filterSize; y<=filterSize; ++y) {vec2 coords=vec2(x,y)*blurDir;vec3 sampleColor=textureLod(textureSampler,vUV+coords,0.).rgb;float sampleDepth=textureLod(depthSampler,vUV+coords,0.).r;vec3 sampleNormal=textureLod(normalSampler,vUV+coords,0.).rgb;\n#ifdef DECODE_NORMAL\nsampleNormal=sampleNormal*2.0-1.0;\n#endif\nfloat r=dot(coords,coords);float w=exp(-r/two_sigma2);float rDepth=sampleDepth-depth;float wd=exp(-rDepth*rDepth/two_sigmaDepth2);float rNormal=abs(sampleNormal.x-normal.x)+abs(sampleNormal.y-normal.y)+abs(sampleNormal.z-normal.z);float wn=exp(-rNormal*rNormal/two_sigmaNormal2);sum+=sampleColor*w*wd*wn;wsum+=w*wd*wn;}}\nglFragColor=vec4(sum/wsum,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const bilateralBlurQualityPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"rsmGlobalIlluminationPixelShader\";\nconst shader = `/**\n* The implementation is an application of the formula found in http:\n* For better results,it also adds a random (noise) rotation to the RSM samples (the noise artifacts are easier to remove than the banding artifacts).\n*/\nprecision highp float;varying vec2 vUV;uniform mat4 rsmLightMatrix;uniform vec4 rsmInfo;uniform vec4 rsmInfo2;uniform sampler2D textureSampler;uniform sampler2D normalSampler;uniform sampler2D rsmPositionW;uniform sampler2D rsmNormalW;uniform sampler2D rsmFlux;uniform sampler2D rsmSamples;\n#ifdef TRANSFORM_NORMAL\nuniform mat4 invView;\n#endif\nfloat mod289(float x){return x-floor(x*(1.0/289.0))*289.0;}\nvec4 mod289(vec4 x){return x-floor(x*(1.0/289.0))*289.0;}\nvec4 perm(vec4 x){return mod289(((x*34.0)+1.0)*x);}\nfloat noise(vec3 p){vec3 a=floor(p);vec3 d=p-a;d=d*d*(3.0-2.0*d);vec4 b=a.xxyy+vec4(0.0,1.0,0.0,1.0);vec4 k1=perm(b.xyxy);vec4 k2=perm(k1.xyxy+b.zzww);vec4 c=k2+a.zzzz;vec4 k3=perm(c);vec4 k4=perm(c+1.0);vec4 o1=fract(k3*(1.0/41.0));vec4 o2=fract(k4*(1.0/41.0));vec4 o3=o2*d.z+o1*(1.0-d.z);vec2 o4=o3.yw*d.x+o3.xz*(1.0-d.x);return o4.y*d.y+o4.x*(1.0-d.y);}\nvec3 computeIndirect(vec3 p,vec3 n) {vec3 indirectDiffuse=vec3(0.);int numSamples=int(rsmInfo.x);float radius=rsmInfo.y;float intensity=rsmInfo.z;float edgeArtifactCorrection=rsmInfo.w;vec4 texRSM=rsmLightMatrix*vec4(p,1.);texRSM.xy/=texRSM.w;texRSM.xy=texRSM.xy*0.5+0.5;float angle=noise(p*rsmInfo2.x);float c=cos(angle);float s=sin(angle);for (int i=0; i<numSamples; i++) {vec3 rsmSample=texelFetch(rsmSamples,ivec2(i,0),0).xyz;float weightSquare=rsmSample.z;if (rsmInfo2.y==1.0) rsmSample.xy=vec2(rsmSample.x*c+rsmSample.y*s,-rsmSample.x*s+rsmSample.y*c);vec2 uv=texRSM.xy+rsmSample.xy*radius;if (uv.x<0. || uv.x>1. || uv.y<0. || uv.y>1.) continue;vec3 vplPositionW=textureLod(rsmPositionW,uv,0.).xyz;vec3 vplNormalW=textureLod(rsmNormalW,uv,0.).xyz*2.0-1.0;vec3 vplFlux=textureLod(rsmFlux,uv,0.).rgb;vplPositionW-=vplNormalW*edgeArtifactCorrection; \nfloat dist2=dot(vplPositionW-p,vplPositionW-p);indirectDiffuse+=vplFlux*weightSquare*max(0.,dot(n,vplPositionW-p))*max(0.,dot(vplNormalW,p-vplPositionW))/(dist2*dist2);}\nreturn clamp(indirectDiffuse*intensity,0.0,1.0);}\nvoid main(void) \n{vec3 positionW=texture2D(textureSampler,vUV).xyz;vec3 normalW=texture2D(normalSampler,vUV).xyz;\n#ifdef DECODE_NORMAL\nnormalW=normalW*2.0-1.0;\n#endif\n#ifdef TRANSFORM_NORMAL\nnormalW=(invView*vec4(normalW,0.)).xyz;\n#endif\ngl_FragColor.rgb=computeIndirect(positionW,normalW);gl_FragColor.a=1.0;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const rsmGlobalIlluminationPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"rsmFullGlobalIlluminationPixelShader\";\nconst shader = `/**\n* The implementation is a direct application of the formula found in http:\n*/\nprecision highp float;varying vec2 vUV;uniform mat4 rsmLightMatrix;uniform vec4 rsmInfo;uniform sampler2D textureSampler;uniform sampler2D normalSampler;uniform sampler2D rsmPositionW;uniform sampler2D rsmNormalW;uniform sampler2D rsmFlux;\n#ifdef TRANSFORM_NORMAL\nuniform mat4 invView;\n#endif\nvec3 computeIndirect(vec3 p,vec3 n) {vec3 indirectDiffuse=vec3(0.);float intensity=rsmInfo.z;float edgeArtifactCorrection=rsmInfo.w;vec4 texRSM=rsmLightMatrix*vec4(p,1.);texRSM.xy/=texRSM.w;texRSM.xy=texRSM.xy*0.5+0.5;int width=int(rsmInfo.x);int height=int(rsmInfo.y);for (int j=0; j<height; j++) {for (int i=0; i<width; i++) {ivec2 uv=ivec2(i,j);vec3 vplPositionW=texelFetch(rsmPositionW,uv,0).xyz;vec3 vplNormalW=texelFetch(rsmNormalW,uv,0).xyz*2.0-1.0;vec3 vplFlux=texelFetch(rsmFlux,uv,0).rgb;vplPositionW-=vplNormalW*edgeArtifactCorrection; \nfloat dist2=dot(vplPositionW-p,vplPositionW-p);indirectDiffuse+=vplFlux*max(0.,dot(n,vplPositionW-p))*max(0.,dot(vplNormalW,p-vplPositionW))/(dist2*dist2);}}\nreturn clamp(indirectDiffuse*intensity,0.0,1.0);}\nvoid main(void) \n{vec3 positionW=texture2D(textureSampler,vUV).xyz;vec3 normalW=texture2D(normalSampler,vUV).xyz;\n#ifdef DECODE_NORMAL\nnormalW=normalW*2.0-1.0;\n#endif\n#ifdef TRANSFORM_NORMAL\nnormalW=(invView*vec4(normalW,0.)).xyz;\n#endif\ngl_FragColor.rgb=computeIndirect(positionW,normalW);gl_FragColor.a=1.0;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const rsmFullGlobalIlluminationPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"bilateralBlurPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var normalSamplerSampler: sampler;var normalSampler: texture_2d<f32>;var depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;uniform filterSize: i32;uniform blurDir: vec2f;uniform depthThreshold: f32;uniform normalThreshold: f32;varying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var color: vec3f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.).rgb;var depth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV,0.).x;if (depth>=1e6 || depth<=0.) {fragmentOutputs.color= vec4f(color,1.);return fragmentOutputs;}\nvar normal: vec3f=textureSampleLevel(normalSampler,normalSamplerSampler,input.vUV,0.).rgb;\n#ifdef DECODE_NORMAL\nnormal=normal*2.0-1.0;\n#endif\nvar sigma: f32= f32(uniforms.filterSize);var two_sigma2: f32=2.0*sigma*sigma;var sigmaDepth: f32=uniforms.depthThreshold;var two_sigmaDepth2: f32=2.0*sigmaDepth*sigmaDepth;var sigmaNormal: f32=uniforms.normalThreshold;var two_sigmaNormal2: f32=2.0*sigmaNormal*sigmaNormal;var sum: vec3f= vec3f(0.);var wsum: f32=0.;for (var x: i32=-uniforms.filterSize; x<=uniforms.filterSize; x++) {var coords=vec2f(f32(x));var sampleColor: vec3f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV+coords*uniforms.blurDir,0.).rgb;var sampleDepth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV+coords*uniforms.blurDir,0.).r;var sampleNormal: vec3f=textureSampleLevel(normalSampler,normalSamplerSampler,input.vUV+coords*uniforms.blurDir,0.).rgb;\n#ifdef DECODE_NORMAL\nsampleNormal=sampleNormal*2.0-1.0;\n#endif\nvar r: f32=dot(coords,coords);var w: f32=exp(-r/two_sigma2);var depthDelta: f32=abs(sampleDepth-depth);var wd: f32=step(depthDelta,uniforms.depthThreshold);var normalDelta: vec3f=abs(sampleNormal-normal);var wn: f32=step(normalDelta.x+normalDelta.y+normalDelta.z,uniforms.normalThreshold);sum+=sampleColor*w*wd*wn;wsum+=w*wd*wn;}\nfragmentOutputs.color= vec4f(sum/wsum,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const bilateralBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"bilateralBlurQualityPixelShader\";\nconst shader = `var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var normalSamplerSampler: sampler;var normalSampler: texture_2d<f32>;var depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;uniform filterSize: i32;uniform blurDir: vec2f;uniform depthThreshold: f32;uniform normalThreshold: f32;varying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var color: vec3f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV,0.).rgb;var depth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV,0.).x;if (depth>=1e6 || depth<=0.) {fragmentOutputs.color= vec4f(color,1.);return fragmentOutputs;}\nvar normal: vec3f=textureSampleLevel(normalSampler,normalSamplerSampler,input.vUV,0.).rgb;\n#ifdef DECODE_NORMAL\nnormal=normal*2.0-1.0;\n#endif\nvar sigma: f32= f32(uniforms.filterSize);var two_sigma2: f32=2.0*sigma*sigma;var sigmaDepth: f32=uniforms.depthThreshold;var two_sigmaDepth2: f32=2.0*sigmaDepth*sigmaDepth;var sigmaNormal: f32=uniforms.normalThreshold;var two_sigmaNormal2: f32=2.0*sigmaNormal*sigmaNormal;var sum: vec3f= vec3f(0.);var wsum: f32=0.;for (var x: i32=-uniforms.filterSize; x<=uniforms.filterSize; x++) {for (var y: i32=-uniforms.filterSize; y<=uniforms.filterSize; y++) {var coords: vec2f= vec2f(f32(x),f32(y))*uniforms.blurDir;var sampleColor: vec3f=textureSampleLevel(textureSampler,textureSamplerSampler,input.vUV+coords,0.).rgb;var sampleDepth: f32=textureSampleLevel(depthSampler,depthSamplerSampler,input.vUV+coords,0.).r;var sampleNormal: vec3f=textureSampleLevel(normalSampler,normalSamplerSampler,input.vUV+coords,0.).rgb;\n#ifdef DECODE_NORMAL\nsampleNormal=sampleNormal*2.0-1.0;\n#endif\nvar r: f32=dot(coords,coords);var w: f32=exp(-r/two_sigma2);var rDepth: f32=sampleDepth-depth;var wd: f32=exp(-rDepth*rDepth/two_sigmaDepth2);var rNormal: f32=abs(sampleNormal.x-normal.x)+abs(sampleNormal.y-normal.y)+abs(sampleNormal.z-normal.z);var wn: f32=exp(-rNormal*rNormal/two_sigmaNormal2);sum+=sampleColor*w*wd*wn;wsum+=w*wd*wn;}}\nfragmentOutputs.color= vec4f(sum/wsum,1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const bilateralBlurQualityPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"rsmGlobalIlluminationPixelShader\";\nconst shader = `/**\n* The implementation is an application of the formula found in http:\n* For better results,it also adds a random (noise) rotation to the RSM samples (the noise artifacts are easier to remove than the banding artifacts).\n*/\nvarying vUV: vec2f;uniform rsmLightMatrix: mat4x4f;uniform rsmInfo: vec4f;uniform rsmInfo2: vec4f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var normalSamplerSampler: sampler;var normalSampler: texture_2d<f32>;var rsmPositionWSampler: sampler;var rsmPositionW: texture_2d<f32>;var rsmNormalWSampler: sampler;var rsmNormalW: texture_2d<f32>;var rsmFluxSampler: sampler;var rsmFlux: texture_2d<f32>;var rsmSamples: texture_2d<f32>;\n#ifdef TRANSFORM_NORMAL\nuniform invView: mat4x4f;\n#endif\nfn mod289(x: f32)->f32{return x-floor(x*(1.0/289.0))*289.0;}\nfn mod289Vec4(x: vec4f)->vec4f {return x-floor(x*(1.0/289.0))* 289.0;}\nfn perm(x: vec4f)->vec4f {return mod289Vec4(((x*34.0)+1.0)*x) ;}\nfn noise(p: vec3f)->f32{var a: vec3f=floor(p);var d: vec3f=p-a;d=d*d*(3.0-2.0*d);var b: vec4f=a.xxyy+ vec4f(0.0,1.0,0.0,1.0);var k1: vec4f=perm(b.xyxy);var k2: vec4f=perm(k1.xyxy+b.zzww);var c: vec4f=k2+a.zzzz;var k3: vec4f=perm(c);var k4: vec4f=perm(c+1.0);var o1: vec4f=fract(k3*(1.0/41.0));var o2: vec4f=fract(k4*(1.0/41.0));var o3: vec4f=o2*d.z+o1*(1.0-d.z);var o4: vec2f=o3.yw*d.x+o3.xz*(1.0-d.x);return o4.y*d.y+o4.x*(1.0-d.y);}\nfn computeIndirect(p: vec3f,n: vec3f)->vec3f {var indirectDiffuse: vec3f= vec3f(0.);var numSamples: i32= i32(uniforms.rsmInfo.x);var radius: f32=uniforms.rsmInfo.y;var intensity: f32=uniforms.rsmInfo.z;var edgeArtifactCorrection: f32=uniforms.rsmInfo.w;var texRSM: vec4f=uniforms.rsmLightMatrix* vec4f(p,1.);texRSM=vec4f(texRSM.xy/texRSM.w,texRSM.z,texRSM.w);texRSM=vec4f(texRSM.xy*0.5+0.5,texRSM.z,texRSM.w);var angle: f32=noise(p*uniforms.rsmInfo2.x);var c: f32=cos(angle);var s: f32=sin(angle);for (var i: i32=0; i<numSamples; i++) {var rsmSample: vec3f=textureLoad(rsmSamples,vec2<i32>(i,0),0).xyz;var weightSquare: f32=rsmSample.z;if (uniforms.rsmInfo2.y==1.0){rsmSample=vec3f(rsmSample.x*c+rsmSample.y*s,-rsmSample.x*s+rsmSample.y*c,rsmSample.z);}\nvar uv: vec2f=texRSM.xy+rsmSample.xy*radius;if (uv.x<0. || uv.x>1. || uv.y<0. || uv.y>1.) {continue;}\nvar vplPositionW: vec3f=textureSampleLevel(rsmPositionW,rsmPositionWSampler,uv,0.).xyz;var vplNormalW: vec3f=textureSampleLevel(rsmNormalW,rsmNormalWSampler,uv,0.).xyz*2.0-1.0;var vplFlux: vec3f=textureSampleLevel(rsmFlux,rsmFluxSampler,uv,0.).rgb;vplPositionW-=vplNormalW*edgeArtifactCorrection; \nvar dist2: f32=dot(vplPositionW-p,vplPositionW-p);indirectDiffuse+=vplFlux*weightSquare*max(0.,dot(n,vplPositionW-p))*max(0.,dot(vplNormalW,p-vplPositionW))/(dist2*dist2);}\nreturn clamp(indirectDiffuse*intensity,vec3f(0.0),vec3f(1.0));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var positionW: vec3f=textureSample(textureSampler,textureSamplerSampler,input.vUV).xyz;var normalW: vec3f=textureSample(normalSampler,normalSamplerSampler,input.vUV).xyz;\n#ifdef DECODE_NORMAL\nnormalW=normalW*2.0-1.0;\n#endif\n#ifdef TRANSFORM_NORMAL\nnormalW=(uniforms.invView* vec4f(normalW,0.)).xyz;\n#endif\nfragmentOutputs.color=vec4f(computeIndirect(positionW,normalW),1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const rsmGlobalIlluminationPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"rsmFullGlobalIlluminationPixelShader\";\nconst shader = `/**\n* The implementation is a direct application of the formula found in http:\n*/\nvarying vUV: vec2f;uniform rsmLightMatrix: mat4x4f;uniform rsmInfo: vec4f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var normalSamplerSampler: sampler;var normalSampler: texture_2d<f32>;var rsmPositionW: texture_2d<f32>;var rsmNormalW: texture_2d<f32>;var rsmFlux: texture_2d<f32>;\n#ifdef TRANSFORM_NORMAL\nuniform invView: mat4x4f;\n#endif\nfn computeIndirect(p: vec3f,n: vec3f)->vec3f {var indirectDiffuse: vec3f= vec3f(0.);var intensity: f32=uniforms.rsmInfo.z;var edgeArtifactCorrection: f32=uniforms.rsmInfo.w;var texRSM: vec4f=uniforms.rsmLightMatrix* vec4f(p,1.);texRSM=vec4f(texRSM.xy/texRSM.w,texRSM.z,texRSM.w);texRSM=vec4f(texRSM.xy*0.5+0.5,texRSM.z,texRSM.w);var width: i32= i32(uniforms.rsmInfo.x);var height: i32= i32(uniforms.rsmInfo.y);for (var j: i32=0; j<height; j++) {for (var i: i32=0; i<width; i++) {var uv=vec2<i32>(i,j);var vplPositionW: vec3f=textureLoad(rsmPositionW,uv,0).xyz;var vplNormalW: vec3f=textureLoad(rsmNormalW,uv,0).xyz*2.0-1.0;var vplFlux: vec3f=textureLoad(rsmFlux,uv,0).rgb;vplPositionW-=vplNormalW*edgeArtifactCorrection; \nvar dist2: f32=dot(vplPositionW-p,vplPositionW-p);indirectDiffuse+=vplFlux*max(0.,dot(n,vplPositionW-p))*max(0.,dot(vplNormalW,p-vplPositionW))/(dist2*dist2);}}\nreturn clamp(indirectDiffuse*intensity,vec3f(0.0),vec3f(1.0));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var positionW: vec3f=textureSample(textureSampler,textureSamplerSampler,fragmentInputs.vUV).xyz;var normalW: vec3f=textureSample(normalSampler,normalSamplerSampler,fragmentInputs.vUV).xyz;\n#ifdef DECODE_NORMAL\nnormalW=normalW*2.0-1.0;\n#endif\n#ifdef TRANSFORM_NORMAL\nnormalW=(uniforms.invView* vec4f(normalW,0.)).xyz;\n#endif\nfragmentOutputs.color=vec4f(computeIndirect(positionW,normalW),1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const rsmFullGlobalIlluminationPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"mrtFragmentDeclaration\";\nconst shader = `#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#ifdef MESH_BLEND_TAG\n#if {X}>0\n#if MESH_BLEND_TAG_INDEX==0\nlayout(location=0) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=0) out highp vec4 glFragData0;\n#endif\n#endif\n#if {X}>1\n#if MESH_BLEND_TAG_INDEX==1\nlayout(location=1) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=1) out highp vec4 glFragData1;\n#endif\n#endif\n#if {X}>2\n#if MESH_BLEND_TAG_INDEX==2\nlayout(location=2) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=2) out highp vec4 glFragData2;\n#endif\n#endif\n#if {X}>3\n#if MESH_BLEND_TAG_INDEX==3\nlayout(location=3) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=3) out highp vec4 glFragData3;\n#endif\n#endif\n#if {X}>4\n#if MESH_BLEND_TAG_INDEX==4\nlayout(location=4) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=4) out highp vec4 glFragData4;\n#endif\n#endif\n#if {X}>5\n#if MESH_BLEND_TAG_INDEX==5\nlayout(location=5) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=5) out highp vec4 glFragData5;\n#endif\n#endif\n#if {X}>6\n#if MESH_BLEND_TAG_INDEX==6\nlayout(location=6) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=6) out highp vec4 glFragData6;\n#endif\n#endif\n#if {X}>7\n#if MESH_BLEND_TAG_INDEX==7\nlayout(location=7) out highp uvec4 meshBlendTagOutput;\n#else\nlayout(location=7) out highp vec4 glFragData7;\n#endif\n#endif\nvoid writeGeometryFragmentOutput(highp int index,highp vec4 value) {\n#if {X}>0 && MESH_BLEND_TAG_INDEX != 0\nif (index==0) { glFragData0=value; }\n#endif\n#if {X}>1 && MESH_BLEND_TAG_INDEX != 1\nif (index==1) { glFragData1=value; }\n#endif\n#if {X}>2 && MESH_BLEND_TAG_INDEX != 2\nif (index==2) { glFragData2=value; }\n#endif\n#if {X}>3 && MESH_BLEND_TAG_INDEX != 3\nif (index==3) { glFragData3=value; }\n#endif\n#if {X}>4 && MESH_BLEND_TAG_INDEX != 4\nif (index==4) { glFragData4=value; }\n#endif\n#if {X}>5 && MESH_BLEND_TAG_INDEX != 5\nif (index==5) { glFragData5=value; }\n#endif\n#if {X}>6 && MESH_BLEND_TAG_INDEX != 6\nif (index==6) { glFragData6=value; }\n#endif\n#if {X}>7 && MESH_BLEND_TAG_INDEX != 7\nif (index==7) { glFragData7=value; }\n#endif\n}\n#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX,VALUE) writeGeometryFragmentOutput(INDEX,VALUE)\n#else\nlayout(location=0) out vec4 glFragData[{X}];\n#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX,VALUE) gl_FragData[INDEX]=VALUE\n#endif\n#else\n#define WRITE_GEOMETRY_FRAGMENT_OUTPUT(INDEX,VALUE) gl_FragData[INDEX]=VALUE\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const mrtFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { mrtFragmentDeclaration } from \"./ShadersInclude/mrtFragmentDeclaration\";\nimport { bumpFragmentMainFunctions } from \"./ShadersInclude/bumpFragmentMainFunctions\";\nimport { samplerFragmentDeclaration } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { bumpFragmentFunctions } from \"./ShadersInclude/bumpFragmentFunctions\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { pbrFragmentReflectionDeclaration } from \"./ShadersInclude/pbrFragmentReflectionDeclaration\";\nimport { sceneFragmentDeclaration } from \"./ShadersInclude/sceneFragmentDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { openpbrDielectricReflectance } from \"./ShadersInclude/openpbrDielectricReflectance\";\nimport { pbrIBLFunctions } from \"./ShadersInclude/pbrIBLFunctions\";\nimport { reflectionFunction } from \"./ShadersInclude/reflectionFunction\";\nimport { openpbrGeometryInfo } from \"./ShadersInclude/openpbrGeometryInfo\";\nimport { openpbrIblFunctions } from \"./ShadersInclude/openpbrIblFunctions\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { bumpFragment } from \"./ShadersInclude/bumpFragment\";\nimport { openpbrSubsurfaceLayerData } from \"./ShadersInclude/openpbrSubsurfaceLayerData\";\nimport { openpbrTransmissionLayerData } from \"./ShadersInclude/openpbrTransmissionLayerData\";\n\nconst name = \"geometryPixelShader\";\nconst shader = `#extension GL_EXT_draw_buffers : require\n#if defined(BUMP) || !defined(NORMAL)\n#extension GL_OES_standard_derivatives : enable\n#endif\nprecision highp float;\n#ifdef BUMP\nvarying mat4 vWorldView;varying vec3 vNormalW;\n#else\nvarying vec3 vNormalV;\n#endif\nvarying vec4 vViewPos;\n#if defined(POSITION) || defined(BUMP) || defined(IRRADIANCE)\nvarying vec3 vPositionW;\n#endif\n#if defined(VELOCITY) || defined(VELOCITY_LINEAR)\nvarying vec4 vCurrentPosition;varying vec4 vPreviousPosition;\n#endif\n#ifdef NEED_UV\nvarying vec2 vUV;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;uniform vec2 vTangentSpaceParams;\n#endif\n#if defined(REFLECTIVITY)\n#if defined(ORMTEXTURE) || defined(SPECULARGLOSSINESSTEXTURE) || defined(REFLECTIVITYTEXTURE)\nuniform sampler2D reflectivitySampler;varying vec2 vReflectivityUV;\n#else\n#ifdef METALLIC_TEXTURE\nuniform sampler2D metallicSampler;varying vec2 vMetallicUV;\n#endif\n#ifdef ROUGHNESS_TEXTURE\nuniform sampler2D roughnessSampler;varying vec2 vRoughnessUV;\n#endif\n#endif\n#ifdef ALBEDOTEXTURE\nvarying vec2 vAlbedoUV;uniform sampler2D albedoSampler;\n#endif\n#ifdef REFLECTIVITYCOLOR\nuniform vec3 reflectivityColor;\n#endif\n#ifdef ALBEDOCOLOR\nuniform vec3 albedoColor;\n#endif\n#ifdef METALLIC\nuniform float metallic;\n#endif\n#if defined(ROUGHNESS) || defined(GLOSSINESS)\nuniform float glossiness;\n#endif\n#endif\n#if defined(ALPHATEST) && defined(NEED_UV)\nuniform sampler2D diffuseSampler;uniform float alphaCutOff;\n#endif\n#ifdef OBJECT_ID\nuniform float objectId;\n#include<objectIdFunctions>\n#endif\n#ifdef MESH_BLEND_TAG\nuniform int meshBlendTag;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#include<mrtFragmentDeclaration>[SCENE_MRT_COUNT]\n#include<bumpFragmentMainFunctions>\n#include<bumpFragmentFunctions>\n#include<helperFunctions>\n#ifdef IRRADIANCE\n#include<pbrFragmentReflectionDeclaration>\n#ifdef REFLECTION\n#ifdef USEIRRADIANCEMAP\n#include<__decl__sceneFragment>\nuniform mat4 reflectionMatrix;uniform vec2 vReflectionInfos;uniform vec3 vReflectionDominantDirection;\n#include<pbrBRDFFunctions>\n#include<openpbrDielectricReflectance>\n#include<pbrIBLFunctions>\n#include<reflectionFunction>\n#include<openpbrGeometryInfo>\n#include<openpbrIblFunctions>\n#elif defined(USESPHERICALFROMREFLECTIONMAP)\nvarying vec3 vEnvironmentIrradiance;\n#endif\n#ifdef IBL_SHADOW_TEXTURE\nuniform sampler2D iblShadowSampler;uniform vec2 shadowTextureSize;\n#endif\n#ifdef IRRADIANCE_SCATTER_MASK\nuniform float vSubsurfaceWeight;\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight,_SAMPLERNAME_,subsurfaceWeight)\nuniform float vSubsurfaceScatterAnisotropy;uniform float vTransmissionWeight;\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight,_SAMPLERNAME_,transmissionWeight)\nuniform float vTransmissionScatterAnisotropy;\n#endif\n#endif\n#endif\nvoid main() {\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<alphaCutOff)\ndiscard;\n#endif\nvec3 normalOutput;\n#ifdef BUMP\nvec3 normalW=normalize(vNormalW);\n#include<bumpFragment>\n#ifdef NORMAL_WORLDSPACE\nnormalOutput=normalW;\n#else\nnormalOutput=normalize(vec3(vWorldView*vec4(normalW,0.0)));\n#endif\n#elif defined(HAS_NORMAL_ATTRIBUTE)\nnormalOutput=normalize(vNormalV);\n#elif defined(POSITION)\nnormalOutput=normalize(-cross(dFdx(vPositionW),dFdy(vPositionW)));\n#endif\n#ifdef ENCODE_NORMAL\nnormalOutput=normalOutput*0.5+0.5;\n#endif\n#ifdef DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(DEPTH_INDEX,vec4(vViewPos.z/vViewPos.w,0.0,0.0,1.0));\n#endif\n#ifdef NORMAL\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(NORMAL_INDEX,vec4(normalOutput,1.0));\n#endif\n#ifdef SCREENSPACE_DEPTH\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(SCREENSPACE_DEPTH_INDEX,vec4(gl_FragCoord.z,0.0,0.0,1.0));\n#endif\n#ifdef POSITION\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(POSITION_INDEX,vec4(vPositionW,1.0));\n#endif\n#ifdef OBJECT_ID\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(OBJECT_ID_INDEX,encodeObjectId(objectId));\n#endif\n#ifdef MESH_BLEND_TAG\nmeshBlendTagOutput=uvec4(uint(meshBlendTag),0u,0u,0u);\n#endif\n#ifdef VELOCITY\nvec2 a=(vCurrentPosition.xy/vCurrentPosition.w)*0.5+0.5;vec2 b=(vPreviousPosition.xy/vPreviousPosition.w)*0.5+0.5;vec2 velocity=abs(a-b);velocity=vec2(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;WRITE_GEOMETRY_FRAGMENT_OUTPUT(VELOCITY_INDEX,vec4(velocity,0.0,1.0));\n#endif\n#ifdef VELOCITY_LINEAR\nvec2 velocity=vec2(0.5)*((vPreviousPosition.xy/vPreviousPosition.w) -\n(vCurrentPosition.xy/vCurrentPosition.w));WRITE_GEOMETRY_FRAGMENT_OUTPUT(VELOCITY_LINEAR_INDEX,vec4(velocity,0.0,1.0));\n#endif\n#ifdef REFLECTIVITY\nvec4 reflectivity=vec4(0.0,0.0,0.0,1.0);\n#ifdef METALLICWORKFLOW\nfloat metal=1.0;float roughness=1.0;\n#ifdef ORMTEXTURE\nmetal*=texture2D(reflectivitySampler,vReflectivityUV).b;roughness*=texture2D(reflectivitySampler,vReflectivityUV).g;\n#else\n#ifdef METALLIC_TEXTURE\nmetal*=texture2D(metallicSampler,vMetallicUV).r;\n#endif\n#ifdef ROUGHNESS_TEXTURE\nroughness*=texture2D(roughnessSampler,vRoughnessUV).r;\n#endif\n#endif\n#ifdef METALLIC\nmetal*=metallic;\n#endif\n#ifdef ROUGHNESS\nroughness*=(1.0-glossiness); \n#endif\nreflectivity.a-=roughness;vec3 color=vec3(1.0);\n#ifdef ALBEDOTEXTURE\ncolor=texture2D(albedoSampler,vAlbedoUV).rgb;\n#ifdef GAMMAALBEDO\ncolor=toLinearSpace(color);\n#endif\n#endif\n#ifdef ALBEDOCOLOR\ncolor*=albedoColor.xyz;\n#endif\nreflectivity.rgb=mix(vec3(0.04),color,metal);\n#else\n#if defined(SPECULARGLOSSINESSTEXTURE) || defined(REFLECTIVITYTEXTURE)\nreflectivity=texture2D(reflectivitySampler,vReflectivityUV);\n#ifdef GAMMAREFLECTIVITYTEXTURE\nreflectivity.rgb=toLinearSpace(reflectivity.rgb);\n#endif\n#else \n#ifdef REFLECTIVITYCOLOR\nreflectivity.rgb=toLinearSpace(reflectivityColor.xyz);reflectivity.a=1.0;\n#endif\n#endif\n#ifdef GLOSSINESSS\nreflectivity.a*=glossiness; \n#endif\n#endif\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(REFLECTIVITY_INDEX,reflectivity);\n#endif\n#ifdef IRRADIANCE\nvec3 irradiance=vec3(0.0);float irradiance_alpha=1.0;\n#ifdef REFLECTION\n#ifdef IRRADIANCE_SCATTER_MASK\n#ifndef BUMP\nvec2 uvOffset=vec2(0.0);\n#endif\nvec3 vSubsurfaceColor=vec3(1.0);float vSubsurfaceRadius=0.0;vec3 vSubsurfaceRadiusScale=vec3(1.0);\n#include<openpbrSubsurfaceLayerData>\nfloat vTransmissionDepth=1.0;vec3 vTransmissionColor=vec3(1.0);vec3 vTransmissionScatter=vec3(0.0);float vTransmissionDispersionScale=0.0;float vTransmissionDispersionAbbeNumber=0.0;\n#include<openpbrTransmissionLayerData>\n#endif\n#ifdef IBL_SHADOW_TEXTURE\n#ifdef COLORED_IBL_SHADOWS\nvec3 iblShadowValue=texture(iblShadowSampler,gl_FragCoord.xy/shadowTextureSize).rgb;\n#else\nvec3 iblShadowValue=vec3(texture(iblShadowSampler,gl_FragCoord.xy/shadowTextureSize).r);\n#endif\n#endif\n#if defined(USEIRRADIANCEMAP)\n#ifdef IRRADIANCE_SCATTER_MASK\nfloat bendAmount=subsurface_weight*-min(subsurface_scatter_anisotropy,0.0);bendAmount=mix(bendAmount,-min(transmission_scatter_anisotropy,0.0),transmission_weight);vec3 viewVector=normalize(vEyePosition.xyz-vPositionW.xyz);vec3 bentNormal=mix(normalOutput,viewVector,bendAmount*dot(normalOutput,viewVector));\n#else\nvec3 bentNormal=normalOutput;\n#endif\nirradiance=sampleIrradiance(\nbentNormal\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n#endif\n#endif\n,vReflectionInfos\n,vViewPos.xyz\n,1.0\n,vec3(1.0)\n);\n#elif defined(USESPHERICALFROMREFLECTIONMAP)\nirradiance=vEnvironmentIrradiance;\n#endif\n#ifdef IBL_SHADOW_TEXTURE\nirradiance*=iblShadowValue;\n#endif\n#ifdef IRRADIANCE_SCATTER_MASK\nirradiance_alpha=min(subsurface_weight+transmission_weight,1.0);\n#endif\n#endif\nWRITE_GEOMETRY_FRAGMENT_OUTPUT(IRRADIANCE_INDEX,vec4(irradiance,irradiance_alpha));\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [objectIdFunctions, clipPlaneFragmentDeclaration, mrtFragmentDeclaration, bumpFragmentMainFunctions, samplerFragmentDeclaration, bumpFragmentFunctions, helperFunctions, pbrFragmentReflectionDeclaration, sceneFragmentDeclaration, sceneUboDeclaration, pbrBRDFFunctions, openpbrDielectricReflectance, pbrIBLFunctions, reflectionFunction, openpbrGeometryInfo, openpbrIblFunctions, clipPlaneFragment, bumpFragment, openpbrSubsurfaceLayerData, openpbrTransmissionLayerData];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const geometryPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"geometryVertexDeclaration\";\nconst shader = `uniform mat4 viewProjection;uniform mat4 view;`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const geometryVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nconst name = \"geometryUboDeclaration\";\nconst shader = `#include<sceneUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const geometryUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { geometryVertexDeclaration } from \"./ShadersInclude/geometryVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { geometryUboDeclaration } from \"./ShadersInclude/geometryUboDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { harmonicsFunctions } from \"./ShadersInclude/harmonicsFunctions\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { bumpVertex } from \"./ShadersInclude/bumpVertex\";\n\nconst name = \"geometryVertexShader\";\nconst shader = `precision highp float;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\n#include<__decl__geometryVertex>\n#include<clipPlaneVertexDeclaration>\n#ifdef IRRADIANCE\n#ifdef REFLECTION\nuniform mat4 reflectionMatrix;uniform vec2 vReflectionInfos;uniform vec3 vReflectionColor;\n#ifdef USESPHERICALFROMREFLECTIONMAP\nvarying vec3 vEnvironmentIrradiance;\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;uniform vec3 vSphericalL1_1;uniform vec3 vSphericalL10;uniform vec3 vSphericalL11;uniform vec3 vSphericalL2_2;uniform vec3 vSphericalL2_1;uniform vec3 vSphericalL20;uniform vec3 vSphericalL21;uniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;uniform vec3 vSphericalY;uniform vec3 vSphericalZ;uniform vec3 vSphericalXX_ZZ;uniform vec3 vSphericalYY_ZZ;uniform vec3 vSphericalZZ;uniform vec3 vSphericalXY;uniform vec3 vSphericalYZ;uniform vec3 vSphericalZX;\n#endif\n#include<harmonicsFunctions>\n#endif\n#endif\n#endif\nattribute vec3 position;\n#ifdef HAS_NORMAL_ATTRIBUTE\nattribute vec3 normal;\n#endif\n#ifdef NEED_UV\nvarying vec2 vUV;\n#ifdef ALPHATEST\nuniform mat4 diffuseMatrix;\n#endif\n#ifdef BUMP\nuniform mat4 bumpMatrix;varying vec2 vBumpUV;\n#endif\n#ifdef REFLECTIVITY\nuniform mat4 reflectivityMatrix;uniform mat4 albedoMatrix;varying vec2 vReflectivityUV;varying vec2 vAlbedoUV;\n#endif\n#ifdef METALLIC_TEXTURE\nvarying vec2 vMetallicUV;uniform mat4 metallicMatrix;\n#endif\n#ifdef ROUGHNESS_TEXTURE\nvarying vec2 vRoughnessUV;uniform mat4 roughnessMatrix;\n#endif\n#ifdef SUBSURFACE_WEIGHT\nvarying vec2 vSubsurfaceWeightUV;uniform mat4 subsurfaceWeightMatrix;\n#endif\n#ifdef TRANSMISSION_WEIGHT\nvarying vec2 vTransmissionWeightUV;uniform mat4 transmissionWeightMatrix;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#ifdef BUMP\nvarying mat4 vWorldView;\n#endif\n#ifdef BUMP\nvarying vec3 vNormalW;\n#else\nvarying vec3 vNormalV;\n#endif\nvarying vec4 vViewPos;\n#if defined(POSITION) || defined(BUMP) || defined(IRRADIANCE)\nvarying vec3 vPositionW;\n#endif\n#if defined(VELOCITY) || defined(VELOCITY_LINEAR)\nuniform mat4 previousViewProjection;varying vec4 vCurrentPosition;varying vec4 vPreviousPosition;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void)\n{vec3 positionUpdated=position;\n#ifdef HAS_NORMAL_ATTRIBUTE\nvec3 normalUpdated=normal;\n#else\nvec3 normalUpdated=vec3(0.0,0.0,0.0);\n#endif\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#if (defined(VELOCITY) || defined(VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);vPreviousPosition=previousViewProjection*finalPreviousWorld*vec4(positionUpdated,1.0);\n#endif\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=vec4(finalWorld*vec4(positionUpdated,1.0));\n#ifdef BUMP\nvWorldView=view*finalWorld;mat3 normalWorld=mat3(finalWorld);vNormalW=normalize(normalWorld*normalUpdated);\n#else\n#ifdef NORMAL_WORLDSPACE\nvNormalV=normalize(vec3(finalWorld*vec4(normalUpdated,0.0)));\n#else\nvNormalV=normalize(vec3((view*finalWorld)*vec4(normalUpdated,0.0)));\n#endif\n#endif\nvViewPos=view*worldPos;\n#if (defined(VELOCITY) || defined(VELOCITY_LINEAR)) && defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n#if NUM_BONE_INFLUENCERS>0\nmat4 previousInfluence;previousInfluence=mPreviousBones[int(matricesIndices[0])]*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\npreviousInfluence+=mPreviousBones[int(matricesIndices[1])]*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\npreviousInfluence+=mPreviousBones[int(matricesIndices[2])]*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\npreviousInfluence+=mPreviousBones[int(matricesIndices[3])]*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[0])]*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[1])]*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[2])]*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[3])]*matricesWeightsExtra[3];\n#endif\nvPreviousPosition=previousViewProjection*finalPreviousWorld*previousInfluence*vec4(positionUpdated,1.0);\n#else\nvPreviousPosition=previousViewProjection*finalPreviousWorld*vec4(positionUpdated,1.0);\n#endif\n#endif\n#if defined(POSITION) || defined(BUMP) || defined(IRRADIANCE)\nvPositionW=worldPos.xyz/worldPos.w;\n#endif\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n#include<clipPlaneVertex>\n#ifdef NEED_UV\n#ifdef UV1\n#if defined(ALPHATEST) && defined(ALPHATEST_UV1)\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#else\nvUV=uvUpdated;\n#endif\n#ifdef BUMP_UV1\nvBumpUV=vec2(bumpMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef REFLECTIVITY_UV1\nvReflectivityUV=vec2(reflectivityMatrix*vec4(uvUpdated,1.0,0.0));\n#else\n#ifdef METALLIC_UV1\nvMetallicUV=vec2(metallicMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef ROUGHNESS_UV1\nvRoughnessUV=vec2(roughnessMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#endif\n#ifdef ALBEDO_UV1\nvAlbedoUV=vec2(albedoMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef SUBSURFACE_COLOR_UV1\nvSubsurfaceColorUV=vec2(subsurfaceColorMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef SUBSURFACE_WEIGHT_UV1\nvSubsurfaceWeightUV=vec2(subsurfaceWeightMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#endif\n#ifdef UV2\n#if defined(ALPHATEST) && defined(ALPHATEST_UV2)\nvUV=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#else\nvUV=uv2Updated;\n#endif\n#ifdef BUMP_UV2\nvBumpUV=vec2(bumpMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#ifdef REFLECTIVITY_UV2\nvReflectivityUV=vec2(reflectivityMatrix*vec4(uv2Updated,1.0,0.0));\n#else\n#ifdef METALLIC_UV2\nvMetallicUV=vec2(metallicMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#ifdef ROUGHNESS_UV2\nvRoughnessUV=vec2(roughnessMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#ifdef ALBEDO_UV2\nvAlbedoUV=vec2(albedoMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#ifdef SUBSURFACE_COLOR_UV2\nvSubsurfaceColorUV=vec2(subsurfaceColorMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#ifdef SUBSURFACE_WEIGHT_UV2\nvSubsurfaceWeightUV=vec2(subsurfaceWeightMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#endif\n#include<bumpVertex>\n#ifdef IRRADIANCE\n#ifdef REFLECTION\n#ifdef USESPHERICALFROMREFLECTIONMAP\nvec3 reflectionVector=vec3(reflectionMatrix*vec4(normalUpdated,0.0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\nvEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector)*vReflectionInfos.x;\n#endif\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, instancesDeclaration, geometryVertexDeclaration, sceneUboDeclaration, geometryUboDeclaration, clipPlaneVertexDeclaration, harmonicsFunctions, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex, bumpVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const geometryVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { bumpFragmentMainFunctionsWGSL } from \"./ShadersInclude/bumpFragmentMainFunctions\";\nimport { samplerFragmentDeclarationWGSL } from \"./ShadersInclude/samplerFragmentDeclaration\";\nimport { bumpFragmentFunctionsWGSL } from \"./ShadersInclude/bumpFragmentFunctions\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { pbrFragmentReflectionDeclarationWGSL } from \"./ShadersInclude/pbrFragmentReflectionDeclaration\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { openpbrDielectricReflectanceWGSL } from \"./ShadersInclude/openpbrDielectricReflectance\";\nimport { pbrIBLFunctionsWGSL } from \"./ShadersInclude/pbrIBLFunctions\";\nimport { reflectionFunctionWGSL } from \"./ShadersInclude/reflectionFunction\";\nimport { openpbrGeometryInfoWGSL } from \"./ShadersInclude/openpbrGeometryInfo\";\nimport { openpbrIblFunctionsWGSL } from \"./ShadersInclude/openpbrIblFunctions\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { bumpFragmentWGSL } from \"./ShadersInclude/bumpFragment\";\nimport { openpbrSubsurfaceLayerDataWGSL } from \"./ShadersInclude/openpbrSubsurfaceLayerData\";\nimport { openpbrTransmissionLayerDataWGSL } from \"./ShadersInclude/openpbrTransmissionLayerData\";\n\nconst name = \"geometryPixelShader\";\nconst shader = `#ifdef BUMP\nvarying vWorldView0: vec4f;varying vWorldView1: vec4f;varying vWorldView2: vec4f;varying vWorldView3: vec4f;varying vNormalW: vec3f;\n#else\nvarying vNormalV: vec3f;\n#endif\nvarying vViewPos: vec4f;\n#if defined(POSITION) || defined(BUMP) || defined(IRRADIANCE)\nvarying vPositionW: vec3f;\n#endif\n#if defined(VELOCITY) || defined(VELOCITY_LINEAR)\nvarying vCurrentPosition: vec4f;varying vPreviousPosition: vec4f;\n#endif\n#ifdef NEED_UV\nvarying vUV: vec2f;\n#endif\n#ifdef BUMP\nuniform vBumpInfos: vec3f;uniform vTangentSpaceParams: vec2f;\n#endif\n#if defined(REFLECTIVITY)\n#if defined(ORMTEXTURE) || defined(SPECULARGLOSSINESSTEXTURE) || defined(REFLECTIVITYTEXTURE)\nvar reflectivitySamplerSampler: sampler;var reflectivitySampler: texture_2d<f32>;varying vReflectivityUV: vec2f;\n#else\n#ifdef METALLIC_TEXTURE\nvar metallicSamplerSampler: sampler;var metallicSampler: texture_2d<f32>;varying vMetallicUV: vec2f;\n#endif\n#ifdef ROUGHNESS_TEXTURE\nvar roughnessSamplerSampler: sampler;var roughnessSampler: texture_2d<f32>;varying vRoughnessUV: vec2f;\n#endif\n#endif\n#ifdef ALBEDOTEXTURE\nvarying vAlbedoUV: vec2f;var albedoSamplerSampler: sampler;var albedoSampler: texture_2d<f32>;\n#endif\n#ifdef REFLECTIVITYCOLOR\nuniform reflectivityColor: vec3f;\n#endif\n#ifdef ALBEDOCOLOR\nuniform albedoColor: vec3f;\n#endif\n#ifdef METALLIC\nuniform metallic: f32;\n#endif\n#if defined(ROUGHNESS) || defined(GLOSSINESS)\nuniform glossiness: f32;\n#endif\n#endif\n#if defined(ALPHATEST) && defined(NEED_UV)\nvar diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;uniform alphaCutOff: f32;\n#endif\n#ifdef OBJECT_ID\nuniform objectId: f32;\n#include<objectIdFunctions>\n#endif\n#ifdef MESH_BLEND_TAG\nuniform meshBlendTag: i32;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#include<bumpFragmentMainFunctions>\n#include<bumpFragmentFunctions>\n#include<helperFunctions>\n#ifdef IRRADIANCE\n#include<pbrFragmentReflectionDeclaration>\n#ifdef REFLECTION\n#ifdef USEIRRADIANCEMAP\n#include<sceneUboDeclaration>\nuniform reflectionMatrix: mat4x4f;uniform vReflectionInfos: vec2f;uniform vReflectionDominantDirection: vec3f;\n#include<pbrBRDFFunctions>\n#include<openpbrDielectricReflectance>\n#include<pbrIBLFunctions>\n#include<reflectionFunction>\n#include<openpbrGeometryInfo>\n#include<openpbrIblFunctions>\n#elif defined(USESPHERICALFROMREFLECTIONMAP)\nvarying vEnvironmentIrradiance: vec3f;\n#endif\n#ifdef IBL_SHADOW_TEXTURE\nvar iblShadowSampler: texture_2d<f32>;var iblShadowSamplerSampler: sampler;uniform shadowTextureSize: vec2f;\n#endif\n#ifdef IRRADIANCE_SCATTER_MASK\nuniform vSubsurfaceWeight: f32;\n#include<samplerFragmentDeclaration>(_DEFINENAME_,SUBSURFACE_WEIGHT,_VARYINGNAME_,SubsurfaceWeight,_SAMPLERNAME_,subsurfaceWeight)\nuniform vSubsurfaceScatterAnisotropy: f32;uniform vTransmissionWeight: f32;\n#include<samplerFragmentDeclaration>(_DEFINENAME_,TRANSMISSION_WEIGHT,_VARYINGNAME_,TransmissionWeight,_SAMPLERNAME_,transmissionWeight)\nuniform vTransmissionScatterAnisotropy: f32;\n#endif\n#endif\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (textureSample(diffuseSampler,diffuseSamplerSampler,input.vUV).a<uniforms.alphaCutOff) {discard;}\n#endif\nvar normalOutput: vec3f;\n#ifdef BUMP\nvar normalW: vec3f=normalize(input.vNormalW);\n#include<bumpFragment>\n#ifdef NORMAL_WORLDSPACE\nnormalOutput=normalW;\n#else\nnormalOutput=normalize( (mat4x4f(input.vWorldView0,input.vWorldView1,input.vWorldView2,input.vWorldView3)* vec4f(normalW,0.0)).xyz);\n#endif\n#elif defined(HAS_NORMAL_ATTRIBUTE)\nnormalOutput=normalize(input.vNormalV);\n#elif defined(POSITION)\nnormalOutput=normalize(-cross(dpdx(input.vPositionW),dpdy(input.vPositionW)));\n#endif\n#ifdef ENCODE_NORMAL\nnormalOutput=normalOutput*0.5+0.5;\n#endif\nvar fragData: array<vec4<f32>,SCENE_MRT_COUNT>;\n#ifdef DEPTH\nfragData[DEPTH_INDEX]=vec4f(input.vViewPos.z/input.vViewPos.w,0.0,0.0,1.0);\n#endif\n#ifdef NORMAL\nfragData[NORMAL_INDEX]=vec4f(normalOutput,1.0);\n#endif\n#ifdef SCREENSPACE_DEPTH\nfragData[SCREENSPACE_DEPTH_INDEX]=vec4f(fragmentInputs.position.z,0.0,0.0,1.0);\n#endif\n#ifdef POSITION\nfragData[POSITION_INDEX]= vec4f(input.vPositionW,1.0);\n#endif\n#ifdef OBJECT_ID\nfragData[OBJECT_ID_INDEX]=encodeObjectId(uniforms.objectId);\n#endif\n#ifdef VELOCITY\nvar a: vec2f=(input.vCurrentPosition.xy/input.vCurrentPosition.w)*0.5+0.5;var b: vec2f=(input.vPreviousPosition.xy/input.vPreviousPosition.w)*0.5+0.5;var velocity: vec2f=abs(a-b);velocity= vec2f(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;fragData[VELOCITY_INDEX]= vec4f(velocity,0.0,1.0);\n#endif\n#ifdef VELOCITY_LINEAR\nvar velocity : vec2f=vec2f(0.5)*((input.vPreviousPosition.xy /\ninput.vPreviousPosition.w) -\n(input.vCurrentPosition.xy /\ninput.vCurrentPosition.w));fragData[VELOCITY_LINEAR_INDEX]=vec4f(velocity,0.0,1.0);\n#endif\n#ifdef REFLECTIVITY\nvar reflectivity: vec4f= vec4f(0.0,0.0,0.0,1.0);\n#ifdef METALLICWORKFLOW\nvar metal: f32=1.0;var roughness: f32=1.0;\n#ifdef ORMTEXTURE\nmetal*=textureSample(reflectivitySampler,reflectivitySamplerSampler,input.vReflectivityUV).b;roughness*=textureSample(reflectivitySampler,reflectivitySamplerSampler,input.vReflectivityUV).g;\n#else\n#ifdef METALLIC_TEXTURE\nmetal*=textureSample(metallicSampler,metallicSamplerSampler,input.vMetallicUV).r;\n#endif\n#ifdef ROUGHNESS_TEXTURE\nroughness*=textureSample(roughnessSampler,roughnessSamplerSampler,input.vRoughnessUV).r;\n#endif\n#endif\n#ifdef METALLIC\nmetal*=uniforms.metallic;\n#endif\n#ifdef ROUGHNESS\nroughness*=(1.0-uniforms.glossiness); \n#endif\nreflectivity=vec4f(reflectivity.rgb,reflectivity.a-roughness);var color: vec3f= vec3f(1.0);\n#ifdef ALBEDOTEXTURE\ncolor=textureSample(albedoSampler,albedoSamplerSampler,input.vAlbedoUV).rgb;\n#ifdef GAMMAALBEDO\ncolor=toLinearSpaceVec4(color);\n#endif\n#endif\n#ifdef ALBEDOCOLOR\ncolor*=uniforms.albedoColor.xyz;\n#endif\nreflectivity=vec4f(mix( vec3f(0.04),color,metal),reflectivity.a);\n#else\n#if defined(SPECULARGLOSSINESSTEXTURE) || defined(REFLECTIVITYTEXTURE)\nreflectivity=textureSample(reflectivitySampler,reflectivitySamplerSampler,input.vReflectivityUV);\n#ifdef GAMMAREFLECTIVITYTEXTURE\nreflectivity=vec4f(toLinearSpaceVec3(reflectivity.rgb),reflectivity.a);\n#endif\n#else \n#ifdef REFLECTIVITYCOLOR\nreflectivity=vec4f(toLinearSpaceVec3(uniforms.reflectivityColor.xyz),1.0);\n#endif\n#endif\n#ifdef GLOSSINESSS\nreflectivity=vec4f(reflectivity.rgb,reflectivity.a*glossiness); \n#endif\n#endif\nfragData[REFLECTIVITY_INDEX]=reflectivity;\n#endif\n#ifdef IRRADIANCE\nvar irradiance: vec3f=vec3f(0.0);var irradiance_alpha: f32=1.0;\n#ifdef REFLECTION\n#ifdef IRRADIANCE_SCATTER_MASK\n#ifndef BUMP\nlet uvOffset: vec2f=vec2f(0.0);\n#endif\nvar vSubsurfaceColor: vec3f=vec3f(1.0);var vSubsurfaceRadius: f32=0.0;var vSubsurfaceRadiusScale: vec3f=vec3f(1.0);\n#include<openpbrSubsurfaceLayerData>(uniforms.vSubsurfaceColor,vSubsurfaceColor,uniforms.vSubsurfaceRadius,vSubsurfaceRadius,uniforms.vSubsurfaceRadiusScale,vSubsurfaceRadiusScale)\nvar vTransmissionDepth: f32=1.0;var vTransmissionColor: vec3f=vec3f(1.0);var vTransmissionScatter: vec3f=vec3f(0.0);var vTransmissionDispersionScale: f32=0.0;var vTransmissionDispersionAbbeNumber: f32=0.0;\n#include<openpbrTransmissionLayerData>(uniforms.vTransmissionDispersionScale,vTransmissionDispersionScale,uniforms.vTransmissionDispersionAbbeNumber,vTransmissionDispersionAbbeNumber,uniforms.vTransmissionColor,vTransmissionColor,uniforms.vTransmissionDepth,vTransmissionDepth,uniforms.vTransmissionScatter\\\\.,vTransmissionScatter.)\n#endif\n#ifdef IBL_SHADOW_TEXTURE\n#ifdef COLORED_IBL_SHADOWS\nlet iblShadowValue: vec3f=textureSample(iblShadowSampler,iblShadowSamplerSampler,fragmentInputs.position.xy/uniforms.shadowTextureSize).rgb;\n#else\nlet iblShadowValue: vec3f=vec3f(textureSample(iblShadowSampler,iblShadowSamplerSampler,fragmentInputs.position.xy/uniforms.shadowTextureSize).r);\n#endif\n#endif\n#if defined(USEIRRADIANCEMAP)\n#ifdef IRRADIANCE_SCATTER_MASK\nlet bendAmount: f32=subsurface_weight*-min(subsurface_scatter_anisotropy,0.0);let mixedBendAmount: f32=mix(bendAmount,-min(transmission_scatter_anisotropy,0.0),transmission_weight);let viewVector: vec3f=normalize(scene.vEyePosition.xyz-input.vPositionW);let bentNormal: vec3f=mix(normalOutput,viewVector,mixedBendAmount*dot(normalOutput,viewVector));\n#else\nlet bentNormal: vec3f=normalOutput;\n#endif\nirradiance=sampleIrradiance(\nbentNormal\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\n,input.vEnvironmentIrradiance\n#endif\n#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))\n,uniforms.reflectionMatrix\n#endif\n#ifdef USEIRRADIANCEMAP\n,irradianceSampler\n,irradianceSamplerSampler\n#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION\n,uniforms.vReflectionDominantDirection\n#endif\n#endif\n#ifdef REALTIME_FILTERING\n,uniforms.vReflectionFilteringInfo\n#ifdef IBL_CDF_FILTERING\n,icdfSampler\n,icdfSamplerSampler\n#endif\n#endif\n,uniforms.vReflectionInfos\n,input.vViewPos.xyz\n,1.0\n,vec3f(1.0)\n);\n#elif defined(USESPHERICALFROMREFLECTIONMAP)\nirradiance=input.vEnvironmentIrradiance;\n#endif\n#ifdef IBL_SHADOW_TEXTURE\nirradiance*=iblShadowValue;\n#endif\n#ifdef IRRADIANCE_SCATTER_MASK\nirradiance_alpha=min(subsurface_weight+transmission_weight,1.0);\n#endif\n#endif\nfragData[IRRADIANCE_INDEX]=vec4f(irradiance,irradiance_alpha);\n#endif\n#if SCENE_MRT_COUNT>0\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==0\nfragmentOutputs.fragData0=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData0=fragData[0];\n#endif\n#endif\n#if SCENE_MRT_COUNT>1\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==1\nfragmentOutputs.fragData1=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData1=fragData[1];\n#endif\n#endif\n#if SCENE_MRT_COUNT>2\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==2\nfragmentOutputs.fragData2=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData2=fragData[2];\n#endif\n#endif\n#if SCENE_MRT_COUNT>3\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==3\nfragmentOutputs.fragData3=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData3=fragData[3];\n#endif\n#endif\n#if SCENE_MRT_COUNT>4\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==4\nfragmentOutputs.fragData4=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData4=fragData[4];\n#endif\n#endif\n#if SCENE_MRT_COUNT>5\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==5\nfragmentOutputs.fragData5=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData5=fragData[5];\n#endif\n#endif\n#if SCENE_MRT_COUNT>6\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==6\nfragmentOutputs.fragData6=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData6=fragData[6];\n#endif\n#endif\n#if SCENE_MRT_COUNT>7\n#if defined(MESH_BLEND_TAG) && MESH_BLEND_TAG_INDEX==7\nfragmentOutputs.fragData7=vec4u(u32(uniforms.meshBlendTag),0u,0u,0u);\n#else\nfragmentOutputs.fragData7=fragData[7];\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [objectIdFunctionsWGSL, clipPlaneFragmentDeclarationWGSL, bumpFragmentMainFunctionsWGSL, samplerFragmentDeclarationWGSL, bumpFragmentFunctionsWGSL, helperFunctionsWGSL, pbrFragmentReflectionDeclarationWGSL, sceneUboDeclarationWGSL, pbrBRDFFunctionsWGSL, openpbrDielectricReflectanceWGSL, pbrIBLFunctionsWGSL, reflectionFunctionWGSL, openpbrGeometryInfoWGSL, openpbrIblFunctionsWGSL, clipPlaneFragmentWGSL, bumpFragmentWGSL, openpbrSubsurfaceLayerDataWGSL, openpbrTransmissionLayerDataWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const geometryPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { harmonicsFunctionsWGSL } from \"./ShadersInclude/harmonicsFunctions\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { bumpVertexWGSL } from \"./ShadersInclude/bumpVertex\";\n\nconst name = \"geometryVertexShader\";\nconst shader = `#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\n#include<sceneUboDeclaration>\n#include<clipPlaneVertexDeclaration>\n#ifdef IRRADIANCE\n#ifdef REFLECTION\nuniform reflectionMatrix: mat4x4f;uniform vReflectionInfos: vec2f;uniform vReflectionColor: vec3f;\n#ifdef USESPHERICALFROMREFLECTIONMAP\nvarying vEnvironmentIrradiance: vec3f;\n#ifdef SPHERICAL_HARMONICS\nuniform vSphericalL00: vec3f;uniform vSphericalL1_1: vec3f;uniform vSphericalL10: vec3f;uniform vSphericalL11: vec3f;uniform vSphericalL2_2: vec3f;uniform vSphericalL2_1: vec3f;uniform vSphericalL20: vec3f;uniform vSphericalL21: vec3f;uniform vSphericalL22: vec3f;\n#else\nuniform vSphericalX: vec3f;uniform vSphericalY: vec3f;uniform vSphericalZ: vec3f;uniform vSphericalXX_ZZ: vec3f;uniform vSphericalYY_ZZ: vec3f;uniform vSphericalZZ: vec3f;uniform vSphericalXY: vec3f;uniform vSphericalYZ: vec3f;uniform vSphericalZX: vec3f;\n#endif\n#include<harmonicsFunctions>\n#endif\n#endif\n#endif\nattribute position : vec3<f32>;\n#ifdef HAS_NORMAL_ATTRIBUTE\nattribute normal: vec3f;\n#endif\n#ifdef NEED_UV\nvarying vUV: vec2f;\n#ifdef ALPHATEST\nuniform diffuseMatrix: mat4x4f;\n#endif\n#ifdef BUMP\nuniform bumpMatrix: mat4x4f;varying vBumpUV: vec2f;\n#endif\n#ifdef REFLECTIVITY\nuniform reflectivityMatrix: mat4x4f;uniform albedoMatrix: mat4x4f;varying vReflectivityUV: vec2f;varying vAlbedoUV: vec2f;\n#endif\n#ifdef METALLIC_TEXTURE\nvarying vMetallicUV: vec2f;uniform metallicMatrix: mat4x4f;\n#endif\n#ifdef ROUGHNESS_TEXTURE\nvarying vRoughnessUV: vec2f;uniform roughnessMatrix: mat4x4f;\n#endif\n#ifdef SUBSURFACE_WEIGHT\nvarying vSubsurfaceWeightUV: vec2f;uniform subsurfaceWeightMatrix: mat4x4f;\n#endif\n#ifdef TRANSMISSION_WEIGHT\nvarying vTransmissionWeightUV: vec2f;uniform transmissionWeightMatrix: mat4x4f;\n#endif\n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#endif\n#ifdef BUMP\nvarying vWorldView0: vec4f;varying vWorldView1: vec4f;varying vWorldView2: vec4f;varying vWorldView3: vec4f;\n#endif\n#ifdef BUMP\nvarying vNormalW: vec3f;\n#else\nvarying vNormalV: vec3f;\n#endif\nvarying vViewPos: vec4f;\n#if defined(POSITION) || defined(BUMP) || defined(IRRADIANCE)\nvarying vPositionW: vec3f;\n#endif\n#if defined(VELOCITY) || defined(VELOCITY_LINEAR)\nuniform previousViewProjection: mat4x4f;varying vCurrentPosition: vec4f;varying vPreviousPosition: vec4f;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;\n#ifdef HAS_NORMAL_ATTRIBUTE\nvar normalUpdated: vec3f=vertexInputs.normal;\n#else\nvar normalUpdated: vec3f=vec3f(0.0,0.0,0.0);\n#endif\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#if (defined(VELOCITY) || defined(VELOCITY_LINEAR)) && !defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=scene.viewProjection*finalWorld*vec4f(positionUpdated,1.0);vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld* vec4f(positionUpdated,1.0);\n#endif\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f= vec4f(finalWorld* vec4f(positionUpdated,1.0));\n#ifdef BUMP\nlet vWorldView=scene.view*finalWorld;vertexOutputs.vWorldView0=vWorldView[0];vertexOutputs.vWorldView1=vWorldView[1];vertexOutputs.vWorldView2=vWorldView[2];vertexOutputs.vWorldView3=vWorldView[3];let normalWorld: mat3x3f= mat3x3f(finalWorld[0].xyz,finalWorld[1].xyz,finalWorld[2].xyz);vertexOutputs.vNormalW=normalize(normalWorld*normalUpdated);\n#else\n#ifdef NORMAL_WORLDSPACE\nvertexOutputs.vNormalV=normalize((finalWorld* vec4f(normalUpdated,0.0)).xyz);\n#else\nvertexOutputs.vNormalV=normalize(((scene.view*finalWorld)* vec4f(normalUpdated,0.0)).xyz);\n#endif\n#endif\nvertexOutputs.vViewPos=scene.view*worldPos;\n#if (defined(VELOCITY) || defined(VELOCITY_LINEAR)) && defined(BONES_VELOCITY_ENABLED)\nvertexOutputs.vCurrentPosition=scene.viewProjection*finalWorld* vec4f(positionUpdated,1.0);\n#if NUM_BONE_INFLUENCERS>0\nvar previousInfluence: mat4x4f;previousInfluence=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[0])]*vertexInputs.matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[1])]*vertexInputs.matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[2])]*vertexInputs.matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndices[3])]*vertexInputs.matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[0])]*vertexInputs.matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[1])]*vertexInputs.matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[2])]*vertexInputs.matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\npreviousInfluence+=uniforms.mPreviousBones[ i32(vertexInputs.matricesIndicesExtra[3])]*vertexInputs.matricesWeightsExtra[3];\n#endif\nvertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld*previousInfluence* vec4f(positionUpdated,1.0);\n#else\nvertexOutputs.vPreviousPosition=uniforms.previousViewProjection*finalPreviousWorld* vec4f(positionUpdated,1.0);\n#endif\n#endif\n#if defined(POSITION) || defined(BUMP) || defined(IRRADIANCE)\nvertexOutputs.vPositionW=worldPos.xyz/worldPos.w;\n#endif\nvertexOutputs.position=scene.viewProjection*finalWorld* vec4f(positionUpdated,1.0);\n#include<clipPlaneVertex>\n#ifdef NEED_UV\n#ifdef UV1\n#if defined(ALPHATEST) && defined(ALPHATEST_UV1)\nvertexOutputs.vUV=(uniforms.diffuseMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#else\nvertexOutputs.vUV=uvUpdated;\n#endif\n#ifdef BUMP_UV1\nvertexOutputs.vBumpUV=(uniforms.bumpMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef REFLECTIVITY_UV1\nvertexOutputs.vReflectivityUV=(uniforms.reflectivityMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#else\n#ifdef METALLIC_UV1\nvertexOutputs.vMetallicUV=(uniforms.metallicMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef ROUGHNESS_UV1\nvertexOutputs.vRoughnessUV=(uniforms.roughnessMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef ALBEDO_UV1\nvertexOutputs.vAlbedoUV=(uniforms.albedoMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef SUBSURFACE_WEIGHT_UV1\nvertexOutputs.vSubsurfaceWeightUV=(uniforms.subsurfaceWeightMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef TRANSMISSION_WEIGHT_UV1\nvertexOutputs.vTransmissionWeightUV=(uniforms.transmissionWeightMatrix* vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef UV2\n#if defined(ALPHATEST) && defined(ALPHATEST_UV2)\nvertexOutputs.vUV=(uniforms.diffuseMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#else\nvertexOutputs.vUV=uv2Updated;\n#endif\n#ifdef BUMP_UV2\nvertexOutputs.vBumpUV=(uniforms.bumpMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#ifdef REFLECTIVITY_UV2\nvertexOutputs.vReflectivityUV=(uniforms.reflectivityMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#else\n#ifdef METALLIC_UV2\nvertexOutputs.vMetallicUV=(uniforms.metallicMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#ifdef ROUGHNESS_UV2\nvertexOutputs.vRoughnessUV=(uniforms.roughnessMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef ALBEDO_UV2\nvertexOutputs.vAlbedoUV=(uniforms.albedoMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#ifdef SUBSURFACE_WEIGHT_UV2\nvertexOutputs.vSubsurfaceWeightUV=(uniforms.subsurfaceWeightMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#ifdef TRANSMISSION_WEIGHT_UV2\nvertexOutputs.vTransmissionWeightUV=(uniforms.transmissionWeightMatrix* vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#endif\n#include<bumpVertex>\n#ifdef IRRADIANCE\n#ifdef REFLECTION\n#ifdef USESPHERICALFROMREFLECTIONMAP\nvar reflectionVector: vec3f=(uniforms.reflectionMatrix*vec4f(normalUpdated,0.0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0f;\n#endif\nvertexOutputs.vEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector)*uniforms.vReflectionInfos.x;\n#endif\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, instancesDeclarationWGSL, sceneUboDeclarationWGSL, clipPlaneVertexDeclarationWGSL, harmonicsFunctionsWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL, bumpVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const geometryVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"boundingBoxRendererFragmentDeclaration\";\nconst shader = `uniform vec4 color;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const boundingBoxRendererFragmentDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"boundingBoxRendererUboDeclaration\";\nconst shader = `#ifdef WEBGL2\nuniform vec4 color;uniform mat4 world;uniform mat4 viewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;\n#endif\n#else\nlayout(std140,column_major) uniform;uniform BoundingBoxRenderer {vec4 color;mat4 world;mat4 viewProjection;mat4 viewProjectionR;};\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const boundingBoxRendererUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { boundingBoxRendererFragmentDeclaration } from \"./ShadersInclude/boundingBoxRendererFragmentDeclaration\";\nimport { boundingBoxRendererUboDeclaration } from \"./ShadersInclude/boundingBoxRendererUboDeclaration\";\n\nconst name = \"boundingBoxRendererPixelShader\";\nconst shader = `#include<__decl__boundingBoxRendererFragment>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\ngl_FragColor=color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [boundingBoxRendererFragmentDeclaration, boundingBoxRendererUboDeclaration];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const boundingBoxRendererPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"boundingBoxRendererVertexDeclaration\";\nconst shader = `uniform mat4 world;uniform mat4 viewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;\n#endif\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const boundingBoxRendererVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { boundingBoxRendererVertexDeclaration } from \"./ShadersInclude/boundingBoxRendererVertexDeclaration\";\nimport { boundingBoxRendererUboDeclaration } from \"./ShadersInclude/boundingBoxRendererUboDeclaration\";\n\nconst name = \"boundingBoxRendererVertexShader\";\nconst shader = `attribute vec3 position;\n#include<__decl__boundingBoxRendererVertex>\n#ifdef INSTANCES\nattribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef INSTANCES\nmat4 finalWorld=mat4(world0,world1,world2,world3);vec4 worldPos=finalWorld*vec4(position,1.0);\n#else\nvec4 worldPos=world*vec4(position,1.0);\n#endif\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {gl_Position=viewProjection*worldPos;} else {gl_Position=viewProjectionR*worldPos;}\n#else\ngl_Position=viewProjection*worldPos;\n#endif\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [boundingBoxRendererVertexDeclaration, boundingBoxRendererUboDeclaration];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const boundingBoxRendererVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"boundingBoxRendererPixelShader\";\nconst shader = `uniform color: vec4f;\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nfragmentOutputs.color=uniforms.color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const boundingBoxRendererPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"boundingBoxRendererVertexShader\";\nconst shader = `attribute position: vec3f;uniform world: mat4x4f;uniform viewProjection: mat4x4f;\n#ifdef INSTANCES\nattribute world0 : vec4<f32>;attribute world1 : vec4<f32>;attribute world2 : vec4<f32>;attribute world3 : vec4<f32>;\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#ifdef INSTANCES\nvar finalWorld=mat4x4<f32>(vertexInputs.world0,vertexInputs.world1,vertexInputs.world2,vertexInputs.world3);var worldPos: vec4f=finalWorld* vec4f(vertexInputs.position,1.0);\n#else\nvar worldPos: vec4f=uniforms.world* vec4f(vertexInputs.position,1.0);\n#endif\nvertexOutputs.position=uniforms.viewProjection*worldPos;\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const boundingBoxRendererVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"linePixelShader\";\nconst shader = `#include<clipPlaneFragmentDeclaration>\nuniform vec4 color;\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<logDepthFragment>\n#include<clipPlaneFragment>\ngl_FragColor=color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclaration, logDepthDeclaration, logDepthFragment, clipPlaneFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const linePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"lineVertexDeclaration\";\nconst shader = `uniform mat4 viewProjection;\n#define ADDITIONAL_VERTEX_DECLARATION\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lineVertexDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nimport \"./sceneUboDeclaration\";\nimport \"./meshUboDeclaration\";\nconst name = \"lineUboDeclaration\";\nconst shader = `layout(std140,column_major) uniform;\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const lineUboDeclaration = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { lineVertexDeclaration } from \"./ShadersInclude/lineVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { lineUboDeclaration } from \"./ShadersInclude/lineUboDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"lineVertexShader\";\nconst shader = `#include<__decl__lineVertex>\n#include<instancesDeclaration>\n#include<clipPlaneVertexDeclaration>\nattribute vec3 position;attribute vec4 normal;uniform float width;uniform float aspectRatio;\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#include<instancesVertex>\nmat4 worldViewProjection=viewProjection*finalWorld;vec4 viewPosition=worldViewProjection*vec4(position,1.0);vec4 viewPositionNext=worldViewProjection*vec4(normal.xyz,1.0);vec2 currentScreen=viewPosition.xy/viewPosition.w;vec2 nextScreen=viewPositionNext.xy/viewPositionNext.w;currentScreen.x*=aspectRatio;nextScreen.x*=aspectRatio;vec2 dir=normalize(nextScreen-currentScreen);vec2 normalDir=vec2(-dir.y,dir.x);normalDir*=width/2.0;normalDir.x/=aspectRatio;vec4 offset=vec4(normalDir*normal.w,0.0,0.0);gl_Position=viewPosition+offset;\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6)\nvec4 worldPos=finalWorld*vec4(position,1.0);\n#include<clipPlaneVertex>\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [lineVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, lineUboDeclaration, instancesDeclaration, clipPlaneVertexDeclaration, logDepthDeclaration, instancesVertex, clipPlaneVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const lineVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"linePixelShader\";\nconst shader = `#include<clipPlaneFragmentDeclaration>\nuniform color: vec4f;\n#include<logDepthDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<logDepthFragment>\n#include<clipPlaneFragment>\nfragmentOutputs.color=uniforms.color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclarationWGSL, logDepthDeclarationWGSL, logDepthFragmentWGSL, clipPlaneFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const linePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"lineVertexShader\";\nconst shader = `#define ADDITIONAL_VERTEX_DECLARATION\n#include<instancesDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute position: vec3f;attribute normal: vec4f;uniform width: f32;uniform aspectRatio: f32;\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\n#include<instancesVertex>\nvar worldViewProjection: mat4x4f=scene.viewProjection*finalWorld;var viewPosition: vec4f=worldViewProjection* vec4f(vertexInputs.position,1.0);var viewPositionNext: vec4f=worldViewProjection* vec4f(vertexInputs.normal.xyz,1.0);var currentScreen: vec2f=viewPosition.xy/viewPosition.w;var nextScreen: vec2f=viewPositionNext.xy/viewPositionNext.w;currentScreen=vec2f(currentScreen.x*uniforms.aspectRatio,currentScreen.y);nextScreen=vec2f(nextScreen.x*uniforms.aspectRatio,nextScreen.y);var dir: vec2f=normalize(nextScreen-currentScreen);var normalDir: vec2f= vec2f(-dir.y,dir.x);normalDir*=uniforms.width/2.0;normalDir=vec2f(normalDir.x/uniforms.aspectRatio,normalDir.y);var offset: vec4f= vec4f(normalDir*vertexInputs.normal.w,0.0,0.0);vertexOutputs.position=viewPosition+offset;\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6)\nvar worldPos: vec4f=finalWorld*vec4f(vertexInputs.position,1.0);\n#include<clipPlaneVertex>\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [instancesDeclarationWGSL, clipPlaneVertexDeclarationWGSL, sceneUboDeclarationWGSL, meshUboDeclarationWGSL, logDepthDeclarationWGSL, instancesVertexWGSL, clipPlaneVertexWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const lineVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\n\nconst name = \"outlinePixelShader\";\nconst shader = `#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\nuniform vec4 color;\n#ifdef ALPHATEST\nvarying vec2 vUV;uniform sampler2D diffuseSampler;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\n#include<logDepthFragment>\ngl_FragColor=color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclaration, logDepthDeclaration, clipPlaneFragment, logDepthFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const outlinePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"outlineVertexShader\";\nconst shader = `attribute vec3 position;attribute vec3 normal;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\nuniform float offset;\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\n#ifdef ALPHATEST\nvarying vec2 vUV;uniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void)\n{vec3 positionUpdated=position;vec3 normalUpdated=normal;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\nvec3 offsetPosition=positionUpdated+(normalUpdated*offset);\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(offsetPosition,1.0);gl_Position=viewProjection*worldPos;\n#ifdef ALPHATEST\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#include<clipPlaneVertex>\n#include<logDepthVertex>\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, clipPlaneVertexDeclaration, instancesDeclaration, logDepthDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const outlineVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\n\nconst name = \"outlinePixelShader\";\nconst shader = `uniform color: vec4f;\n#ifdef ALPHATEST\nvarying vUV: vec2f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (textureSample(diffuseSampler,diffuseSamplerSampler,fragmentInputs.vUV).a<0.4) {discard;}\n#endif\n#include<logDepthFragment>\nfragmentOutputs.color=uniforms.color;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclarationWGSL, logDepthDeclarationWGSL, clipPlaneFragmentWGSL, logDepthFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const outlinePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"outlineVertexShader\";\nconst shader = `attribute position: vec3f;attribute normal: vec3f;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\nuniform offset: f32;\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;\n#ifdef ALPHATEST\nvarying vUV: vec2f;uniform diffuseMatrix: mat4x4f; \n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {var positionUpdated: vec3f=vertexInputs.position;var normalUpdated: vec3f=vertexInputs.normal;\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\nvar offsetPosition: vec3f=positionUpdated+(normalUpdated*uniforms.offset);\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld*vec4f(offsetPosition,1.0);vertexOutputs.position=uniforms.viewProjection*worldPos;\n#ifdef ALPHATEST\n#ifdef UV1\nvertexOutputs.vUV=(uniforms.diffuseMatrix*vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef UV2\nvertexOutputs.vUV=(uniforms.diffuseMatrix*vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#include<clipPlaneVertex>\n#include<logDepthVertex>\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, instancesDeclarationWGSL, logDepthDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const outlineVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"copyTexture3DLayerToTexturePixelShader\";\nconst shader = `precision highp sampler3D;uniform sampler3D textureSampler;uniform int layerNum;varying vec2 vUV;void main(void) {vec3 coord=vec3(0.0,0.0,float(layerNum));coord.xy=vec2(vUV.x,vUV.y)*vec2(textureSize(textureSampler,0).xy);vec3 color=texelFetch(textureSampler,ivec3(coord),0).rgb;gl_FragColor=vec4(color,1);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const copyTexture3DLayerToTexturePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"copyTexture3DLayerToTexturePixelShader\";\nconst shader = `var textureSampler: texture_3d<f32>;uniform layerNum: i32;varying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let coord=vec3f(vec2f(input.vUV.x,input.vUV.y)*vec2f(textureDimensions(textureSampler,0).xy),f32(uniforms.layerNum));let color=textureLoad(textureSampler,vec3i(coord),0).rgb;fragmentOutputs.color= vec4f(color,1);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const copyTexture3DLayerToTexturePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblShadowVoxelTracingPixelShader\";\nconst shader = `precision highp sampler2D;precision highp sampler3D;\n#include<helperFunctions>\nvarying vec2 vUV;\n#define DISABLE_UNIFORMITY_ANALYSIS\nuniform sampler2D depthSampler;uniform sampler2D worldNormalSampler;uniform sampler2D blueNoiseSampler;uniform sampler2D icdfSampler;uniform sampler3D voxelGridSampler;\n#ifdef COLOR_SHADOWS\nuniform samplerCube iblSampler;\n#endif\nuniform vec4 shadowParameters;\n#define SHADOWdirs shadowParameters.x\n#define SHADOWframe shadowParameters.y\n#define SHADOWenvRot shadowParameters.w\nuniform vec4 voxelBiasParameters;\n#define highestMipLevel voxelBiasParameters.z\nuniform vec4 sssParameters;\n#define SSSsamples sssParameters.x\n#define SSSstride sssParameters.y\n#define SSSmaxDistance sssParameters.z\n#define SSSthickness sssParameters.w\nuniform vec4 shadowOpacity;uniform mat4 projMtx;uniform mat4 viewMtx;uniform mat4 invProjMtx;uniform mat4 invViewMtx;uniform mat4 wsNormalizationMtx;uniform mat4 invVPMtx;\n#define GOLD 0.618034\nstruct AABB3f {vec3 m_min;vec3 m_max;};struct Ray {vec3 orig;vec3 dir;vec3 dir_rcp;float t_min;float t_max;};Ray make_ray(const vec3 origin,const vec3 direction,const float tmin,\nconst float tmax) {Ray ray;ray.orig=origin;ray.dir=direction;ray.dir_rcp=1.0f/direction;ray.t_min=tmin;ray.t_max=tmax;return ray;}\nbool ray_box_intersection(const in AABB3f aabb,const in Ray ray,\nout float distance_near,out float distance_far) {vec3 tbot=ray.dir_rcp*(aabb.m_min-ray.orig);vec3 ttop=ray.dir_rcp*(aabb.m_max-ray.orig);vec3 tmin=min(ttop,tbot);vec3 tmax=max(ttop,tbot);distance_near=max(ray.t_min,max(tmin.x,max(tmin.y,tmin.z)));distance_far=min(ray.t_max,min(tmax.x,min(tmax.y,tmax.z)));return distance_near<=distance_far;}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nstruct VoxelMarchDiagnosticInfo {float heat;ivec3 voxel_intersect_coords;};\n#endif\nuint hash(uint i) {i ^= i>>16u;i*=0x7FEB352Du;i ^= i>>15u;i*=0x846CA68Bu;i ^= i>>16u;return i;}\nfloat prngCanonical1d(float co) { return fract(sin(co*91.3458)*47453.5453); }\nfloat prngCanonical2d(vec2 co) { return fract(sin(dot(co,vec2(12.9898,78.233)))*43758.5453); }\nfloat prngCanonical3d(vec3 co) { return prngCanonical2d(co.xy+prngCanonical1d(co.z)); }\n#ifndef MAX_VOXEL_ROULETTE_TESTS\n#define MAX_VOXEL_ROULETTE_TESTS 16\n#endif\nvec3 uv_to_normal(vec2 uv) {vec3 N;vec2 uvRange=uv;float theta=uvRange.x*2.0*PI;float phi=uvRange.y*PI;N.x=cos(theta)*sin(phi);N.z=sin(theta)*sin(phi);N.y=cos(phi);return N;}\nfloat goldenSequence(const uint rstate) {return uint2float(rstate*2654435769u);}\nfloat distanceSquared(vec2 a,vec2 b) {vec2 diff=a-b;return dot(diff,diff);}\nvoid genTB(const vec3 N,out vec3 T,out vec3 B) {float s=N.z<0.0 ? -1.0 : 1.0;float a=-1.0/(s+N.z);float b=N.x*N.y*a;T=vec3(1.0+s*N.x*N.x*a,s*b,-s*N.x);B=vec3(b,s+N.y*N.y*a,-N.y);}\nint stack[24]; \n#define PUSH(i) stack[stackLevel++]=i; \n#define POP() stack[--stackLevel] \n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nbool anyHitVoxels(const Ray ray_vs,const vec3 rouletteSeed,\nout VoxelMarchDiagnosticInfo voxel_march_diagnostic_info) {\n#else\nbool anyHitVoxels(const Ray ray_vs,const vec3 rouletteSeed) {\n#endif\nvec3 invD=ray_vs.dir_rcp;vec3 D=ray_vs.dir;vec3 O=ray_vs.orig;ivec3 negD=ivec3(lessThan(D,vec3(0,0,0)));int voxel0=negD.x | negD.y<<1 | negD.z<<2;vec3 t0=-O*invD,t1=(vec3(1.0)-O)*invD;int maxLod=int(highestMipLevel);int stackLevel=0;int leafTests=0;\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nuint steps=0u;\n#endif\nPUSH(maxLod<<24);while (stackLevel>0) {int elem=POP();ivec4 Coords =\nivec4(elem & 0xFF,elem>>8 & 0xFF,elem>>16 & 0xFF,elem>>24);if (Coords.w==0) {float cellOpacity=texelFetch(voxelGridSampler,Coords.xyz,0).x;if (cellOpacity>=1.0) {\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nvoxel_march_diagnostic_info.heat=float(steps)/24.0;\n#endif\nreturn true;}\nif (leafTests>=MAX_VOXEL_ROULETTE_TESTS) {\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nvoxel_march_diagnostic_info.heat=float(steps)/24.0;\n#endif\nreturn false;}\nleafTests++;if (cellOpacity>=prngCanonical3d(vec3(Coords.xyz)+rouletteSeed)) {\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nvoxel_march_diagnostic_info.heat=float(steps)/24.0;\n#endif\nreturn true;}\ncontinue;}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\n++steps;\n#endif\nfloat invRes=exp2(float(Coords.w-maxLod));vec3 bbmin=invRes*vec3(Coords.xyz+negD);vec3 bbmax=invRes*vec3(Coords.xyz-negD+ivec3(1));vec3 mint=mix(t0,t1,bbmin);vec3 maxt=mix(t0,t1,bbmax);vec3 midt=0.5*(mint+maxt);mint.x=max(0.0,mint.x);midt.x=max(0.0,midt.x);int nodeMask=int(\nround(texelFetch(voxelGridSampler,Coords.xyz,Coords.w).x*255.0));Coords.w--;int voxelBit=voxel0;Coords.xyz=(Coords.xyz<<1)+negD;int packedCoords =\nCoords.x | Coords.y<<8 | Coords.z<<16 | Coords.w<<24;if (max(mint.x,max(mint.y,mint.z))<min(midt.x,min(midt.y,midt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(midt.x,max(mint.y,mint.z))<min(maxt.x,min(midt.y,midt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x2;packedCoords ^= 0x00100;if (max(midt.x,max(midt.y,mint.z))<min(maxt.x,min(maxt.y,midt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(mint.x,max(midt.y,mint.z))<min(midt.x,min(maxt.y,midt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x4;packedCoords ^= 0x10000;if (max(mint.x,max(midt.y,midt.z))<min(midt.x,min(maxt.y,maxt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(midt.x,max(midt.y,midt.z))<min(maxt.x,min(maxt.y,maxt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x2;packedCoords ^= 0x00100;if (max(midt.x,max(mint.y,midt.z))<min(maxt.x,min(midt.y,maxt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);voxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(mint.x,max(mint.y,midt.z))<min(midt.x,min(midt.y,maxt.z)) &&\n(1<<voxelBit & nodeMask) != 0)\nPUSH(packedCoords);}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nvoxel_march_diagnostic_info.heat=float(steps)/24.0;\n#endif\nreturn false;}\nfloat linearizeDepth(float depth,float near,float far) {return (near*far)/(far-depth*(far-near));}\nfloat screenSpaceShadow(vec3 csOrigin,vec3 csDirection,vec2 csZBufferSize,\nfloat nearPlaneZ,float farPlaneZ,float noise) {\n#ifdef RIGHT_HANDED\nfloat csZDir=-1.0;\n#else \nfloat csZDir=1.0;\n#endif\nfloat ssSamples=SSSsamples;float ssMaxDist=SSSmaxDistance;float ssStride=SSSstride;float ssThickness=SSSthickness;float rayLength =\ncsZDir*(csOrigin.z+ssMaxDist*csDirection.z)<csZDir*nearPlaneZ\n? \n(nearPlaneZ-csOrigin.z)/csDirection.z\n: ssMaxDist;vec3 csEndPoint=csOrigin+rayLength*csDirection;vec4 H0=projMtx*vec4(csOrigin,1.0);vec4 H1=projMtx*vec4(csEndPoint,1.0);vec2 Z0=vec2(csOrigin.z ,1.0)/H0.w;vec2 Z1=vec2(csEndPoint.z,1.0)/H1.w;vec2 P0=csZBufferSize*(0.5*H0.xy*Z0.y+0.5);vec2 P1=csZBufferSize*(0.5*H1.xy*Z1.y+0.5);P1+=vec2(distanceSquared(P0,P1)<0.0001 ? 0.01 : 0.0);vec2 delta=P1-P0;bool permute=false;if (abs(delta.x)<abs(delta.y)) {permute=true;P0=P0.yx;P1=P1.yx;delta=delta.yx;}\nfloat stepDirection=sign(delta.x);float invdx=stepDirection/delta.x;vec2 dP=ssStride*vec2(stepDirection,invdx*delta.y);vec2 dZ=ssStride*invdx*(Z1-Z0);float opacity=0.0;vec2 P=P0+noise*dP;vec2 Z=Z0+noise*dZ;float end=P1.x*stepDirection;float rayZMax=csZDir*Z.x/Z.y;float sceneDepth=rayZMax;Z+=dZ;for (float stepCount=0.0;opacity<1.0 && P.x*stepDirection<end && sceneDepth>0.0 && stepCount<ssSamples;stepCount++,P+=dP,\nZ+=dZ) { \nivec2 coords=ivec2(permute ? P.yx : P);sceneDepth=texelFetch(depthSampler,coords,0).x;sceneDepth=linearizeDepth(sceneDepth,nearPlaneZ,farPlaneZ);sceneDepth=csZDir*sceneDepth;if (sceneDepth<=0.0) {break;}\nfloat rayZMin=rayZMax;rayZMax=csZDir*Z.x/Z.y;opacity+=max(opacity,step(rayZMax,sceneDepth+ssThickness)*step(sceneDepth,rayZMin));}\nreturn opacity;}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nfloat voxelShadow(vec3 wsOrigin,vec3 wsDirection,vec3 wsNormal,\nvec2 DitherNoise,\nout VoxelMarchDiagnosticInfo voxel_march_diagnostic_info) {\n#else\nfloat voxelShadow(vec3 wsOrigin,vec3 wsDirection,vec3 wsNormal,\nvec2 DitherNoise) {\n#endif\nfloat vxResolution=float(textureSize(voxelGridSampler,0).x);vec3 T,B;genTB(wsDirection,T,B);vec2 DitherXY=sqrt(DitherNoise.x)*vec2(cos(2.0*PI*DitherNoise.y),\nsin(2.0*PI*DitherNoise.y));float sceneScale=wsNormalizationMtx[0][0];vec3 Dithering =\n(voxelBiasParameters.x*wsNormal+voxelBiasParameters.y*wsDirection +\nDitherXY.x*T+DitherXY.y*B) /\nvxResolution;vec3 O=0.5*wsOrigin+0.5+Dithering;Ray ray_vs=make_ray(O,wsDirection,0.0,10.0);AABB3f voxel_aabb;voxel_aabb.m_min=vec3(0);voxel_aabb.m_max=vec3(1);float near,far;if (!ray_box_intersection(voxel_aabb,ray_vs,near,far))\nreturn 0.0;ray_vs.t_min=max(ray_vs.t_min,near);ray_vs.t_max=min(ray_vs.t_max,far);vec3 rouletteSeed=vec3(DitherNoise,DitherNoise.x+DitherNoise.y)*17.0;\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nreturn anyHitVoxels(ray_vs,rouletteSeed,voxel_march_diagnostic_info) ? 1.0f : 0.0f;\n#else\nreturn anyHitVoxels(ray_vs,rouletteSeed) ? 1.0f : 0.0f;\n#endif\n}\nvoid main(void) {uint nbDirs=uint(SHADOWdirs);uint frameId=uint(SHADOWframe);float envRot=SHADOWenvRot;vec2 Resolution=vec2(textureSize(depthSampler,0));ivec2 currentPixel=ivec2(vUV*Resolution);uint GlobalIndex=(frameId*uint(Resolution.y)+uint(currentPixel.y)) *\nuint(Resolution.x) +\nuint(currentPixel.x);vec3 N=texelFetch(worldNormalSampler,currentPixel,0).xyz;\n#ifdef WORLD_NORMAL_UNSIGNED\nN=N*vec3(2.0)-vec3(1.0);\n#endif\nif (length(N)<0.01) {glFragColor=vec4(1.0,1.0,0.0,1.0);return;}\nfloat normalizedRotation=envRot/(2.0*PI);float depth=texelFetch(depthSampler,currentPixel,0).x;\n#ifndef IS_NDC_HALF_ZRANGE\ndepth=depth*2.0-1.0;\n#endif\nvec2 temp=(vec2(currentPixel)+vec2(0.5))*2.0/Resolution-vec2(1.0);vec4 VP=invProjMtx*vec4(temp.x,-temp.y,depth,1.0);VP/=VP.w;N=normalize(N);vec3 noise=texelFetch(blueNoiseSampler,currentPixel & 0xFF,0).xyz;noise.z=fract(noise.z+goldenSequence(frameId*nbDirs));\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nfloat heat=0.0f;\n#endif\nfloat shadowAccum=0.001;float specShadowAccum=0.001;float sampleWeight=0.001;\n#ifdef COLOR_SHADOWS\nvec3 totalLight=vec3(0.001);vec3 shadowedLight=vec3(0.0);\n#endif\nfor (uint i=0u; i<nbDirs; i++) {uint dirId=nbDirs*GlobalIndex+i;vec4 L;vec2 T;{vec2 r=plasticSequence(frameId*nbDirs+i);r=fract(r+vec2(2.0)*abs(noise.xy-vec2(0.5)));T.x=textureLod(icdfSampler,vec2(r.x,0.0),0.0).x;T.y=textureLod(icdfSampler,vec2(T.x,r.y),0.0).y;L=vec4(uv_to_normal(vec2(T.x-normalizedRotation,T.y)),0);\n#ifndef RIGHT_HANDED\nL.z*=-1.0;\n#endif\n}\n#ifdef COLOR_SHADOWS\nvec3 lightDir=uv_to_normal(vec2(1.0-fract(T.x+0.25),T.y));vec3 ibl=textureLod(iblSampler,lightDir,0.0).xyz;float pdf=textureLod(icdfSampler,T,0.0).z;\n#endif\nfloat cosNL=dot(N,L.xyz);float opacity=0.0;if (cosNL>0.0) {vec4 VP2=VP;VP2.y*=-1.0;vec4 unormWP=invViewMtx*VP2;vec3 WP=(wsNormalizationMtx*unormWP).xyz;vec2 vxNoise=vec2(uint2float(hash(dirId*2u)),uint2float(hash(dirId*2u+1u)));\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nVoxelMarchDiagnosticInfo voxel_march_diagnostic_info;opacity=max(opacity,shadowOpacity.x*voxelShadow(WP,L.xyz,N,vxNoise,voxel_march_diagnostic_info));heat+=voxel_march_diagnostic_info.heat;\n#else\nopacity =\nmax(opacity,shadowOpacity.x*voxelShadow(WP,L.xyz,N,vxNoise));\n#endif\nvec3 VL=(viewMtx*L).xyz;\n#ifdef RIGHT_HANDED\nfloat nearPlaneZ=-projMtx[3][2]/(projMtx[2][2]-1.0); \nfloat farPlaneZ=-projMtx[3][2]/(projMtx[2][2]+1.0);\n#else\nfloat nearPlaneZ=-projMtx[3][2]/(projMtx[2][2]+1.0); \nfloat farPlaneZ=-projMtx[3][2]/(projMtx[2][2]-1.0);\n#endif\nfloat ssShadow=shadowOpacity.y *\nscreenSpaceShadow(VP2.xyz,VL,Resolution,nearPlaneZ,farPlaneZ,\nabs(2.0*noise.z-1.0));opacity=max(opacity,ssShadow);\n#ifdef COLOR_SHADOWS\nvec3 light=pdf<1e-6 ? vec3(0.0) : vec3(cosNL)/vec3(pdf)*ibl;shadowedLight+=light*opacity;totalLight+=light;\n#else\nfloat rcos=(1.0-cosNL);shadowAccum+=(1.0-opacity*(1.0-pow(rcos,8.0)));sampleWeight+=1.0;vec3 VR=-(viewMtx*vec4(reflect(-L.xyz,N),0.0)).xyz;specShadowAccum+=max(1.0-(opacity*pow(VR.z,8.0)),0.0);\n#endif\n}\nnoise.z=fract(noise.z+GOLD);}\n#ifdef COLOR_SHADOWS\nvec3 shadow=(totalLight-shadowedLight)/totalLight;float maxShadow=max(max(shadow.x,max(shadow.y,shadow.z)),1.0);glFragColor=vec4(shadow/maxShadow,1.0);\n#else\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\ngl_FragColor=vec4(shadowAccum/float(sampleWeight),\nspecShadowAccum/float(sampleWeight),heat/float(sampleWeight),1.0);\n#else\ngl_FragColor=vec4(shadowAccum/float(sampleWeight),specShadowAccum/float(sampleWeight),0.0,1.0);\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblShadowVoxelTracingPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblShadowVoxelTracingPixelShader\";\nconst shader = `varying vUV: vec2f;\n#include<helperFunctions>\n#define DISABLE_UNIFORMITY_ANALYSIS\nvar depthSampler: texture_2d<f32>;var worldNormalSampler : texture_2d<f32>;var blueNoiseSampler: texture_2d<f32>;var icdfSamplerSampler: sampler;var icdfSampler: texture_2d<f32>;var voxelGridSamplerSampler: sampler;var voxelGridSampler: texture_3d<f32>;\n#ifdef COLOR_SHADOWS\nvar iblSamplerSampler: sampler;var iblSampler: texture_cube<f32>;\n#endif\nuniform shadowParameters: vec4f;\n#define SHADOWdirs uniforms.shadowParameters.x\n#define SHADOWframe uniforms.shadowParameters.y\n#define SHADOWenvRot uniforms.shadowParameters.w\nuniform voxelBiasParameters : vec4f;\n#define highestMipLevel uniforms.voxelBiasParameters.z\nuniform sssParameters: vec4f;\n#define SSSsamples uniforms.sssParameters.x\n#define SSSstride uniforms.sssParameters.y\n#define SSSmaxDistance uniforms.sssParameters.z\n#define SSSthickness uniforms.sssParameters.w\nuniform shadowOpacity: vec4f;uniform projMtx: mat4x4f;uniform viewMtx: mat4x4f;uniform invProjMtx: mat4x4f;uniform invViewMtx: mat4x4f;uniform wsNormalizationMtx: mat4x4f;uniform invVPMtx: mat4x4f;\n#define GOLD 0.618034\nstruct AABB3f {m_min: vec3f,\nm_max: vec3f,};struct Ray {orig: vec3f,\ndir: vec3f,\ndir_rcp: vec3f,\nt_min: f32,\nt_max: f32,};fn make_ray(origin: vec3f,direction: vec3f,tmin: f32,\ntmax: f32)->Ray {var ray: Ray;ray.orig=origin;ray.dir=direction;ray.dir_rcp=1.0f/direction;ray.t_min=tmin;ray.t_max=tmax;return ray;}\nfn ray_box_intersection(aabb: AABB3f,ray: Ray ,\ndistance_near: ptr<function,f32>,distance_far: ptr<function,f32>)->bool{var tbot: vec3f=ray.dir_rcp*(aabb.m_min-ray.orig);var ttop: vec3f=ray.dir_rcp*(aabb.m_max-ray.orig);var tmin: vec3f=min(ttop,tbot);var tmax: vec3f=max(ttop,tbot);*distance_near=max(ray.t_min,max(tmin.x,max(tmin.y,tmin.z)));*distance_far=min(ray.t_max,min(tmax.x,min(tmax.y,tmax.z)));return *distance_near<=*distance_far;}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nstruct VoxelMarchDiagnosticInfo {heat: f32,\nvoxel_intersect_coords: vec3i,};\n#endif\nfn hash(i: u32)->u32 {var temp=i ^ (i>>16u);temp*=0x7FEB352Du;temp ^= temp>>15u;temp*=0x846CA68Bu;temp ^= temp>>16u;return temp;}\nfn prngCanonical1d(co: f32)->f32 { return fract(sin(co*91.3458)*47453.5453); }\nfn prngCanonical2d(co: vec2f)->f32 { return fract(sin(dot(co,vec2f(12.9898,78.233)))*43758.5453); }\nfn prngCanonical3d(co: vec3f)->f32 { return prngCanonical2d(co.xy+prngCanonical1d(co.z)); }\n#ifndef MAX_VOXEL_ROULETTE_TESTS\n#define MAX_VOXEL_ROULETTE_TESTS 16\n#endif\nfn uv_to_normal(uv: vec2f)->vec3f {var N: vec3f;var uvRange: vec2f=uv;var theta: f32=uvRange.x*2.0*PI;var phi: f32=uvRange.y*PI;N.x=cos(theta)*sin(phi);N.z=sin(theta)*sin(phi);N.y=cos(phi);return N;}\nfn goldenSequence(rstate: u32)->f32 {return uint2float(rstate*2654435769u);}\nfn distanceSquared(a: vec2f,b: vec2f)->f32 {var diff: vec2f=a-b;return dot(diff,diff);}\nfn genTB(N: vec3f,T: ptr<function,vec3f>,B: ptr<function,vec3f>) {var s: f32=select(1.0,-1.0,N.z<0.0);var a: f32=-1.0/(s+N.z);var b: f32=N.x*N.y*a;*T= vec3f(1.0+s*N.x*N.x*a,s*b,-s*N.x);*B= vec3f(b,s+N.y*N.y*a,-N.y);}\nfn lessThan(x: vec3f,y: vec3f)->vec3<bool> {return x<y;}\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nfn anyHitVoxels(ray_vs: Ray,rouletteSeed: vec3f,\nvoxel_march_diagnostic_info: ptr<function,VoxelMarchDiagnosticInfo>)->bool {\n#else\nfn anyHitVoxels(ray_vs: Ray,rouletteSeed: vec3f)->bool {\n#endif\nvar stack=array<i32,24>(); \nvar invD: vec3f=ray_vs.dir_rcp;var D: vec3f=ray_vs.dir;var O: vec3f=ray_vs.orig;var negD=vec3i(lessThan(D, vec3f(0,0,0)));var voxel0: i32=negD.x | (negD.y<<1) | (negD.z<<2);var t0: vec3f=-O*invD;var t1=(vec3f(1.0)-O)*invD;var maxLod: i32= i32(highestMipLevel);var stackLevel: i32=0;var leafTests: i32=0;\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nvar steps: u32=0u;\n#endif\nstack[stackLevel]=maxLod<<24;stackLevel++;while (stackLevel>0) {stackLevel=stackLevel-1;var elem: i32=stack[stackLevel];var Coords: vec4i =\nvec4i(elem & 0xFF,(elem>>8) & 0xFF,(elem>>16) & 0xFF,elem>>24);if (Coords.w==0) {let cellOpacity: f32=textureLoad(voxelGridSampler,Coords.xyz,0).x;if (cellOpacity>=1.0) {\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\n*voxel_march_diagnostic_info.heat= f32(steps)/24.0;\n#endif\nreturn true;}\nif (leafTests>=MAX_VOXEL_ROULETTE_TESTS) {\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\n*voxel_march_diagnostic_info.heat= f32(steps)/24.0;\n#endif\nreturn false;}\nleafTests++;if (cellOpacity>=prngCanonical3d(vec3f(Coords.xyz)+rouletteSeed)) {\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\n*voxel_march_diagnostic_info.heat= f32(steps)/24.0;\n#endif\nreturn true;}\ncontinue;}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\n++steps;\n#endif\nvar invRes: f32=exp2(f32(Coords.w-maxLod));var bbmin: vec3f=invRes*vec3f(Coords.xyz+negD);var bbmax: vec3f=invRes*vec3f(Coords.xyz-negD+vec3i(1));var mint: vec3f=mix(t0,t1,bbmin);var maxt: vec3f=mix(t0,t1,bbmax);var midt: vec3f=0.5*(mint+maxt);mint.x=max(0.0,mint.x);midt.x=max(0.0,midt.x);var nodeMask: u32= u32(\nround(textureLoad(voxelGridSampler,Coords.xyz,Coords.w).x*255.0));Coords.w--;var voxelBit: u32=u32(voxel0);Coords=vec4i((Coords.xyz<<vec3u(1))+negD,Coords.w);var packedCoords: i32 =\nCoords.x | (Coords.y<<8) | (Coords.z<<16) | (Coords.w<<24);if (max(mint.x,max(mint.y,mint.z))<min(midt.x,min(midt.y,midt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(midt.x,max(mint.y,mint.z))<min(maxt.x,min(midt.y,midt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x2;packedCoords ^= 0x00100;if (max(midt.x,max(midt.y,mint.z))<min(maxt.x,min(maxt.y,midt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(mint.x,max(midt.y,mint.z))<min(midt.x,min(maxt.y,midt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x4;packedCoords ^= 0x10000;if (max(mint.x,max(midt.y,midt.z))<min(midt.x,min(maxt.y,maxt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(midt.x,max(midt.y,midt.z))<min(maxt.x,min(maxt.y,maxt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x2;packedCoords ^= 0x00100;if (max(midt.x,max(mint.y,midt.z))<min(maxt.x,min(midt.y,maxt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}\nvoxelBit ^= 0x1;packedCoords ^= 0x00001;if (max(mint.x,max(mint.y,midt.z))<min(midt.x,min(midt.y,maxt.z)) &&\n((1u<<voxelBit) & nodeMask) != 0) {stack[stackLevel]=packedCoords;stackLevel++;}}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\n*voxel_march_diagnostic_info.heat= f32(steps)/24.0;\n#endif\nreturn false;}\nfn linearizeDepth(depth: f32,near: f32,far: f32)->f32 {return (near*far)/(far-depth*(far-near));}\nfn screenSpaceShadow(csOrigin: vec3f,csDirection: vec3f,csZBufferSize: vec2f,\nnearPlaneZ: f32,farPlaneZ: f32,noise: f32)->f32 {\n#ifdef RIGHT_HANDED\nvar csZDir : f32=-1.0;\n#else \nvar csZDir : f32=1.0;\n#endif\nvar ssSamples: f32=SSSsamples;var ssMaxDist: f32=SSSmaxDistance;var ssStride: f32=SSSstride;var ssThickness: f32=SSSthickness;var rayLength: f32 =\nselect(ssMaxDist,(nearPlaneZ-csOrigin.z)/csDirection.z,\ncsZDir*(csOrigin.z+ssMaxDist*csDirection.z)<csZDir*nearPlaneZ);var csEndPoint: vec3f=csOrigin+rayLength*csDirection;var H0: vec4f=uniforms.projMtx*vec4f(csOrigin,1.0);var H1: vec4f=uniforms.projMtx*vec4f(csEndPoint,1.0);var Z0=vec2f(csOrigin.z ,1.0)/H0.w;var Z1=vec2f(csEndPoint.z,1.0)/H1.w;var P0=csZBufferSize*(0.5*H0.xy*Z0.y+0.5);var P1=csZBufferSize*(0.5*H1.xy*Z1.y+0.5);P1+= vec2f(select(0.0,0.01,distanceSquared(P0,P1)<0.0001));var delta: vec2f=P1-P0;var permute: bool=false;if (abs(delta.x)<abs(delta.y)) {permute=true;P0=P0.yx;P1=P1.yx;delta=delta.yx;}\nvar stepDirection: f32=sign(delta.x);var invdx: f32=stepDirection/delta.x;var dP: vec2f=ssStride* vec2f(stepDirection,invdx*delta.y);var dZ: vec2f=ssStride*invdx*(Z1-Z0);var opacity: f32=0.0;var P: vec2f=P0+noise*dP;var Z: vec2f=Z0+noise*dZ;var end: f32=P1.x*stepDirection;var rayZMax=csZDir*Z.x/Z.y;var sceneDepth=rayZMax;Z+=dZ;for (var stepCount: f32=0.0; \nopacity<1.0 && P.x*stepDirection<end && sceneDepth>0.0 && stepCount<ssSamples;stepCount+=1) { \nvar coords=vec2i(select(P,P.yx,permute));sceneDepth=textureLoad(depthSampler,coords,0).x;sceneDepth=linearizeDepth(sceneDepth,nearPlaneZ,farPlaneZ);sceneDepth=csZDir*sceneDepth;if (sceneDepth<=0.0) {break;}\nvar rayZMin: f32=rayZMax;rayZMax=csZDir*Z.x/Z.y;opacity+=max(opacity,step(rayZMax,sceneDepth+ssThickness)*step(sceneDepth,rayZMin));P+=dP;Z+=dZ;}\nreturn opacity;}\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nfn voxelShadow(wsOrigin: vec3f,wsDirection: vec3f,wsNormal: vec3f,\nDitherNoise: vec2f,\nvoxel_march_diagnostic_info: ptr<function,VoxelMarchDiagnosticInfo>)->f32 {\n#else\nfn voxelShadow(wsOrigin: vec3f,wsDirection: vec3f,wsNormal: vec3f,\nDitherNoise: vec2f)->f32 {\n#endif\nvar vxResolution: f32=f32(textureDimensions(voxelGridSampler,0).x);var T: vec3f;var B: vec3f;genTB(wsDirection,&T,&B);var DitherXY: vec2f=sqrt(DitherNoise.x)* vec2f(cos(2.0*PI*DitherNoise.y),\nsin(2.0*PI*DitherNoise.y));var Dithering : vec3f=(uniforms.voxelBiasParameters.x*wsNormal +\nuniforms.voxelBiasParameters.y*wsDirection +\nDitherXY.x*T+DitherXY.y*B) /\nvxResolution;var O: vec3f=0.5*wsOrigin+0.5+Dithering;var ray_vs=make_ray(O,wsDirection,0.0,10.0);var voxel_aabb: AABB3f;voxel_aabb.m_min=vec3f(0);voxel_aabb.m_max=vec3f(1);var near: f32=0;var far: f32=0;if (!ray_box_intersection(voxel_aabb,ray_vs,&near,&far)) {return 0.0;}\nray_vs.t_min=max(ray_vs.t_min,near);ray_vs.t_max=min(ray_vs.t_max,far);let rouletteSeed: vec3f=vec3f(DitherNoise,DitherNoise.x+DitherNoise.y)*17.0;\n#if VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nreturn select(0.0f,1.0f,anyHitVoxels(ray_vs,rouletteSeed,voxel_march_diagnostic_info));\n#else\nreturn select(0.0f,1.0f,anyHitVoxels(ray_vs,rouletteSeed));\n#endif\n}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var nbDirs=u32(SHADOWdirs);var frameId=u32(SHADOWframe);var envRot: f32=SHADOWenvRot;var Resolution: vec2f= vec2f(textureDimensions(depthSampler,0));var currentPixel=vec2i(fragmentInputs.vUV*Resolution);var GlobalIndex =\n(frameId*u32(Resolution.y)+u32(currentPixel.y))*u32(Resolution.x) +\nu32(currentPixel.x);var N : vec3f=textureLoad(worldNormalSampler,currentPixel,0).xyz;\n#ifdef WORLD_NORMAL_UNSIGNED\nN=N*vec3f(2.0)-vec3f(1.0);\n#endif\nif (length(N)<0.01) {fragmentOutputs.color=vec4f(1.0,1.0,0.0,1.0);return fragmentOutputs;}\nvar normalizedRotation: f32=envRot/(2.0*PI);var depth : f32=textureLoad(depthSampler,currentPixel,0).x;\n#ifndef IS_NDC_HALF_ZRANGE\ndepth=depth*2.0-1.0;\n#endif\nvar temp : vec2f=(vec2f(currentPixel)+vec2f(0.5))*2.0/Resolution -\nvec2f(1.0);var VP : vec4f=uniforms.invProjMtx*vec4f(temp.x,-temp.y,depth,1.0);VP/=VP.w;N=normalize(N);var noise : vec3f=textureLoad(blueNoiseSampler,currentPixel & vec2i(0xFF),0).xyz;noise.z=fract(noise.z+goldenSequence(frameId*nbDirs));\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nvar heat: f32=0.0f;\n#endif\nvar shadowAccum: f32=0.001;var specShadowAccum: f32=0.001;var sampleWeight : f32=0.001;\n#ifdef COLOR_SHADOWS\nvar totalLight: vec3f=vec3f(0.001);var shadowedLight: vec3f=vec3f(0.0);\n#endif\nfor (var i: u32=0; i<nbDirs; i++) {var dirId: u32=nbDirs*GlobalIndex+i;var L: vec4f;var T: vec2f;{var r: vec2f=plasticSequence(frameId*nbDirs+i);r=fract(r+ vec2f(2.0)*abs(noise.xy- vec2f(0.5)));T.x=textureSampleLevel(icdfSampler,icdfSamplerSampler,vec2f(r.x,0.0),0.0).x;T.y=textureSampleLevel(icdfSampler,icdfSamplerSampler,vec2f(T.x,r.y),0.0).y;L= vec4f(uv_to_normal(vec2f(T.x-normalizedRotation,T.y)),0);\n#ifndef RIGHT_HANDED\nL.z*=-1.0;\n#endif\n}\n#ifdef COLOR_SHADOWS\nvar lightDir: vec3f=uv_to_normal(vec2f(1.0-fract(T.x+0.25),T.y));var ibl: vec3f=textureSampleLevel(iblSampler,iblSamplerSampler,lightDir,0.0).xyz;var pdf: f32=textureSampleLevel(icdfSampler,icdfSamplerSampler,T,0.0).z;\n#endif\nvar cosNL: f32=dot(N,L.xyz);var opacity: f32=0.0;if (cosNL>0.0) {var VP2: vec4f=VP;VP2.y*=-1.0;var unormWP : vec4f=uniforms.invViewMtx*VP2;var WP: vec3f=(uniforms.wsNormalizationMtx*unormWP).xyz;var vxNoise: vec2f=vec2f(uint2float(hash(dirId*2)),uint2float(hash(dirId*2+1)));\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nVoxelMarchDiagnosticInfo voxel_march_diagnostic_info;opacity=max(opacity,\nuniforms.shadowOpacity.x*voxelShadow(WP,L.xyz,N,vxNoise,\nvoxel_march_diagnostic_info));heat+=voxel_march_diagnostic_info.heat;\n#else\nopacity =\nmax(opacity,uniforms.shadowOpacity.x*voxelShadow(WP,L.xyz,N,vxNoise));\n#endif\nvar VL : vec3f=(uniforms.viewMtx*L).xyz;\n#ifdef RIGHT_HANDED\nvar nearPlaneZ: f32=-2.0*uniforms.projMtx[3][2]/(uniforms.projMtx[2][2]-1.0); \nvar farPlaneZ: f32=-uniforms.projMtx[3][2]/(uniforms.projMtx[2][2]+1.0);\n#else\nvar nearPlaneZ: f32=-2.0*uniforms.projMtx[3][2]/(uniforms.projMtx[2][2]+1.0); \nvar farPlaneZ: f32=-uniforms.projMtx[3][2]/(uniforms.projMtx[2][2]-1.0);\n#endif\nvar ssShadow: f32=uniforms.shadowOpacity.y *\nscreenSpaceShadow(VP2.xyz,VL,Resolution,nearPlaneZ,farPlaneZ,\nabs(2.0*noise.z-1.0));opacity=max(opacity,ssShadow);\n#ifdef COLOR_SHADOWS\nvar light: vec3f=select(vec3f(0.0),vec3f(cosNL)/vec3f(pdf)*ibl,pdf>1e-6);shadowedLight+=light*opacity;totalLight+=light;\n#else\nvar rcos: f32=1.0-cosNL;shadowAccum+=(1.0-opacity*(1.0-pow(rcos,8.0)));sampleWeight+=1.0;var VR : vec3f=abs((uniforms.viewMtx*vec4f(reflect(-L.xyz,N),0.0)).xyz);specShadowAccum+=max(1.0-(opacity*pow(VR.z,8.0)),0.0);\n#endif\n}\nnoise.z=fract(noise.z+GOLD);}\n#ifdef COLOR_SHADOWS\nvar shadow: vec3f=(totalLight-shadowedLight)/totalLight;var maxShadow: f32=max(max(shadow.x,max(shadow.y,shadow.z)),1.0);fragmentOutputs.color=vec4f(shadow/maxShadow,1.0);\n#else\n#ifdef VOXEL_MARCH_DIAGNOSTIC_INFO_OPTION\nfragmentOutputs.color =\nvec4f(shadowAccum/sampleWeight,specShadowAccum/sampleWeight,heat/sampleWeight,1.0);\n#else\nfragmentOutputs.color=vec4f(shadowAccum/sampleWeight,specShadowAccum/sampleWeight,0.0,1.0);\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblShadowVoxelTracingPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowDebugPixelShader\";\nconst shader = `#ifdef GL_ES\nprecision mediump float;\n#endif\nvarying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D debugSampler;uniform vec4 sizeParams;\n#define offsetX sizeParams.x\n#define offsetY sizeParams.y\n#define widthScale sizeParams.z\n#define heightScale sizeParams.w\nvoid main(void) {vec2 uv =\nvec2((offsetX+vUV.x)*widthScale,(offsetY+vUV.y)*heightScale);vec4 background=texture2D(textureSampler,vUV);vec4 debugColour=texture2D(debugSampler,vUV);if (uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) {gl_FragColor.rgba=background;} else {gl_FragColor.rgb=mix(debugColour.rgb,background.rgb,0.0);gl_FragColor.a=1.0;}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowDebugPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowDebugPixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var debugSamplerSampler: sampler;var debugSampler: texture_2d<f32>;uniform sizeParams: vec4f;\n#define offsetX uniforms.sizeParams.x\n#define offsetY uniforms.sizeParams.y\n#define widthScale uniforms.sizeParams.z\n#define heightScale uniforms.sizeParams.w\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var uv: vec2f =\nvec2f((offsetX+fragmentInputs.vUV.x)*widthScale,(offsetY+fragmentInputs.vUV.y)*heightScale);var background: vec4f=textureSample(textureSampler,textureSamplerSampler,fragmentInputs.vUV);var debugColour: vec4f=textureSample(debugSampler,debugSamplerSampler,fragmentInputs.vUV);if (uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) {fragmentOutputs.color=background;} else {fragmentOutputs.color=vec4f(mix(debugColour.rgb,background.rgb,0.0),1.0);}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowDebugPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowSpatialBlurPixelShader\";\nconst shader = `#define PI 3.1415927\nvarying vUV: vec2f;var depthSampler: texture_2d<f32>;var worldNormalSampler: texture_2d<f32>;var voxelTracingSampler : texture_2d<f32>;uniform blurParameters: vec4f;\n#define stridef uniforms.blurParameters.x\n#define worldScale uniforms.blurParameters.y\nconst weights=array<f32,5>(0.0625,0.25,0.375,0.25,0.0625);const nbWeights: i32=5;fn max2(v: vec2f,w: vec2f)->vec2f {return vec2f(max(v.x,w.x),max(v.y,w.y));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var gbufferRes=vec2f(textureDimensions(depthSampler,0));var gbufferPixelCoord= vec2i(fragmentInputs.vUV*gbufferRes);var shadowRes=vec2f(textureDimensions(voxelTracingSampler,0));var shadowPixelCoord= vec2i(fragmentInputs.vUV*shadowRes);var N: vec3f=textureLoad(worldNormalSampler,gbufferPixelCoord,0).xyz;if (length(N)<0.01) {fragmentOutputs.color=vec4f(1.0,1.0,0.0,1.0);return fragmentOutputs;}\nvar depth: f32=-textureLoad(depthSampler,gbufferPixelCoord,0).x;var X: vec4f= vec4f(0.0);for(var y: i32=0; y<nbWeights; y++) {for(var x: i32=0; x<nbWeights; x++) {var gBufferCoords: vec2i=gbufferPixelCoord+i32(stridef)*vec2i(x-(nbWeights>>1),y-(nbWeights>>1));var shadowCoords: vec2i=shadowPixelCoord+i32(stridef)*vec2i(x-(nbWeights>>1),y-(nbWeights>>1));var T : vec3f=textureLoad(voxelTracingSampler,shadowCoords,0).xyz;var ddepth: f32=-textureLoad(depthSampler,gBufferCoords,0).x-depth;var dN: vec3f=textureLoad(worldNormalSampler,gBufferCoords,0).xyz-N;var w: f32=weights[x]*weights[y] *\nexp2(max(-1000.0/(worldScale*worldScale),-0.5) *\n(ddepth*ddepth) -\n1e1*dot(dN,dN));X+= vec4f(w*T.x,w*T.y,w*T.z,w);}}\nfragmentOutputs.color= vec4f(X.x/X.w,X.y/X.w,X.z/X.w,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowSpatialBlurPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowSpatialBlurPixelShader\";\nconst shader = `precision highp sampler2D;\n#define PI 3.1415927\nvarying vec2 vUV;uniform sampler2D depthSampler;uniform sampler2D worldNormalSampler;uniform sampler2D voxelTracingSampler;uniform vec4 blurParameters;\n#define stridef blurParameters.x\n#define worldScale blurParameters.y\nconst float weights[5]=float[5](0.0625,0.25,0.375,0.25,0.0625);const int nbWeights=5;vec2 max2(vec2 v,vec2 w) {return vec2(max(v.x,w.x),max(v.y,w.y));}\nvoid main(void)\n{vec2 gbufferRes=vec2(textureSize(depthSampler,0));ivec2 gbufferPixelCoord=ivec2(vUV*gbufferRes);vec2 shadowRes=vec2(textureSize(voxelTracingSampler,0));ivec2 shadowPixelCoord=ivec2(vUV*shadowRes);vec3 N=texelFetch(worldNormalSampler,gbufferPixelCoord,0).xyz;if (length(N)<0.01) {glFragColor=vec4(1.0,1.0,0.0,1.0);return;}\nfloat depth=-texelFetch(depthSampler,gbufferPixelCoord,0).x;vec4 X=vec4(0.0);for(int y=0; y<nbWeights; ++y) {for(int x=0; x<nbWeights; ++x) {ivec2 gBufferCoords=gbufferPixelCoord+int(stridef)*ivec2(x-(nbWeights>>1),y-(nbWeights>>1));ivec2 shadowCoords=shadowPixelCoord+int(stridef)*ivec2(x-(nbWeights>>1),y-(nbWeights>>1));vec4 T=texelFetch(voxelTracingSampler,shadowCoords,0);float ddepth=-texelFetch(depthSampler,gBufferCoords,0).x-depth;vec3 dN=texelFetch(worldNormalSampler,gBufferCoords,0).xyz-N;float w=weights[x]*weights[y] *\nexp2(max(-1000.0/(worldScale*worldScale),-0.5) *\n(ddepth*ddepth) -\n1e1*dot(dN,dN));X+=vec4(w*T.x,w*T.y,w*T.z,w);}}\ngl_FragColor=vec4(X.x/X.w,X.y/X.w,X.z/X.w,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowSpatialBlurPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowAccumulationPixelShader\";\nconst shader = `varying vUV: vec2f;uniform accumulationParameters: vec4f;\n#define remanence uniforms.accumulationParameters.x\n#define resetb uniforms.accumulationParameters.y\n#define sceneSize uniforms.accumulationParameters.z\nvar motionSampler: texture_2d<f32>;var positionSampler: texture_2d<f32>;var spatialBlurSampler : texture_2d<f32>;var oldAccumulationSamplerSampler: sampler;var oldAccumulationSampler: texture_2d<f32>;var prevPositionSamplerSampler: sampler;var prevPositionSampler: texture_2d<f32>;fn max2(v: vec2f,w: vec2f)->vec2f { \nreturn vec2f(max(v.x,w.x),max(v.y,w.y)); }\nfn lessThan(x: vec2f,y: vec2f)->vec2<bool> {return x<y;}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var reset: bool= bool(resetb);var gbufferRes : vec2f=vec2f(textureDimensions(positionSampler,0));var gbufferPixelCoord: vec2i= vec2i(input.vUV*gbufferRes);var shadowRes : vec2f=vec2f(textureDimensions(spatialBlurSampler,0));var shadowPixelCoord: vec2i= vec2i(input.vUV*shadowRes);var LP: vec4f=textureLoad(positionSampler,gbufferPixelCoord,0);if (0.0==LP.w) {fragmentOutputs.color=vec4f(1.0,0.0,0.0,1.0);return fragmentOutputs;}\nvar velocityColor: vec2f=textureLoad(motionSampler,gbufferPixelCoord,0).xy;var prevCoord: vec2f=input.vUV+velocityColor;var PrevLP: vec3f=textureSampleLevel(prevPositionSampler,prevPositionSamplerSampler,prevCoord,0.0).xyz;var PrevShadows: vec4f=textureSampleLevel(oldAccumulationSampler,oldAccumulationSamplerSampler,prevCoord,0.0);var newShadows : vec3f=textureLoad(spatialBlurSampler,shadowPixelCoord,0).xyz;PrevShadows.a=select(1.0,max(PrevShadows.a/(1.0+PrevShadows.a),1.0-remanence),!reset && all(lessThan(abs(prevCoord- vec2f(0.5)), vec2f(0.5))) &&\ndistance(LP.xyz,PrevLP)<5e-2*sceneSize);PrevShadows=max( vec4f(0.0),PrevShadows);fragmentOutputs.color= vec4f(mix(PrevShadows.x,newShadows.x,PrevShadows.a),\nmix(PrevShadows.y,newShadows.y,PrevShadows.a),\nmix(PrevShadows.z,newShadows.z,PrevShadows.a),PrevShadows.a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowAccumulationPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowAccumulationPixelShader\";\nconst shader = `#ifdef GL_ES\nprecision mediump float;\n#endif\nvarying vec2 vUV;uniform vec4 accumulationParameters;\n#define remanence accumulationParameters.x\n#define resetb accumulationParameters.y\n#define sceneSize accumulationParameters.z\nuniform sampler2D motionSampler;uniform sampler2D positionSampler;uniform sampler2D spatialBlurSampler;uniform sampler2D oldAccumulationSampler;uniform sampler2D prevPositionSampler;vec2 max2(vec2 v,vec2 w) { return vec2(max(v.x,w.x),max(v.y,w.y)); }\nvoid main(void) {bool reset=bool(resetb);vec2 gbufferRes=vec2(textureSize(motionSampler,0));ivec2 gbufferPixelCoord=ivec2(vUV*gbufferRes);vec2 shadowRes=vec2(textureSize(spatialBlurSampler,0));ivec2 shadowPixelCoord=ivec2(vUV*shadowRes);vec4 LP=texelFetch(positionSampler,gbufferPixelCoord,0);if (0.0==LP.w) {gl_FragColor=vec4(1.0,0.0,0.0,1.0);return;}\nvec2 velocityColor=texelFetch(motionSampler,gbufferPixelCoord,0).xy;vec2 prevCoord=vUV+velocityColor;vec3 PrevLP=texture(prevPositionSampler,prevCoord).xyz;vec4 PrevShadows=texture(oldAccumulationSampler,prevCoord);vec3 newShadows=texelFetch(spatialBlurSampler,shadowPixelCoord,0).xyz;PrevShadows.a =\n!reset && all(lessThan(abs(prevCoord-vec2(0.5)),vec2(0.5))) &&\ndistance(LP.xyz,PrevLP)<5e-2*sceneSize\n? max(PrevShadows.a/(1.0+PrevShadows.a),1.0-remanence)\n: 1.0;PrevShadows=max(vec4(0.0),PrevShadows);gl_FragColor =\nvec4(mix(PrevShadows.x,newShadows.x,PrevShadows.a),\nmix(PrevShadows.y,newShadows.y,PrevShadows.a),\nmix(PrevShadows.z,newShadows.z,PrevShadows.a),PrevShadows.a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowAccumulationPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowsCombinePixelShader\";\nconst shader = `precision highp float;varying vec2 vUV;uniform sampler2D shadowSampler;uniform sampler2D textureSampler;uniform float shadowOpacity;void main(void)\n{vec3 shadow=texture(shadowSampler,vUV).rgb;vec3 sceneColor=texture(textureSampler,vUV).rgb;float shadowValue=mix(1.0,shadow.x,shadowOpacity);gl_FragColor=vec4(sceneColor*shadowValue,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowsCombinePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowsCombinePixelShader\";\nconst shader = `varying vUV: vec2f;var shadowSamplerSampler : sampler;var shadowSampler : texture_2d<f32>;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform shadowOpacity: f32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var shadow\n: vec3f =\ntextureSample(shadowSampler,shadowSamplerSampler,input.vUV).rgb;var color\n: vec3f =\ntextureSample(textureSampler,textureSamplerSampler,input.vUV).rgb;var shadowValue: f32=mix(1.0,shadow.x,uniforms.shadowOpacity);fragmentOutputs.color=vec4f(color*shadowValue,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowsCombinePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCombineVoxelGridsPixelShader\";\nconst shader = `varying vUV: vec2f;var voxelXaxisSamplerSampler: sampler;var voxelXaxisSampler: texture_3d<f32>;var voxelYaxisSamplerSampler: sampler;var voxelYaxisSampler: texture_3d<f32>;var voxelZaxisSamplerSampler: sampler;var voxelZaxisSampler: texture_3d<f32>;uniform layer: f32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var coordZ: vec3f= vec3f(fragmentInputs.vUV.x,fragmentInputs.vUV.y,uniforms.layer);var voxelZ: f32=textureSample(voxelZaxisSampler,voxelZaxisSamplerSampler,coordZ).r;var coordX: vec3f= vec3f(1.0-uniforms.layer,fragmentInputs.vUV.y,fragmentInputs.vUV.x);var voxelX: f32=textureSample(voxelXaxisSampler,voxelXaxisSamplerSampler,coordX).r;var coordY: vec3f= vec3f(uniforms.layer,fragmentInputs.vUV.x,fragmentInputs.vUV.y);var voxelY: f32=textureSample(voxelYaxisSampler,voxelYaxisSamplerSampler,coordY).r;var voxel=max(voxelX,max(voxelY,voxelZ));fragmentOutputs.color= vec4f( vec3f(voxel),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblCombineVoxelGridsPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCombineVoxelGridsPixelShader\";\nconst shader = `precision highp float;precision highp sampler3D;varying vec2 vUV;uniform sampler3D voxelXaxisSampler;uniform sampler3D voxelYaxisSampler;uniform sampler3D voxelZaxisSampler;uniform float layer;void main(void) {vec3 coordZ=vec3(vUV.x,vUV.y,layer);float voxelZ=texture(voxelZaxisSampler,coordZ).r;vec3 coordX=vec3(1.0-layer,vUV.y,vUV.x);float voxelX=texture(voxelXaxisSampler,coordX).r;vec3 coordY=vec3(layer,vUV.x,vUV.y);float voxelY=texture(voxelYaxisSampler,coordY).r;float voxel=max(voxelX,max(voxelY,voxelZ));glFragColor=vec4(vec3(voxel),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblCombineVoxelGridsPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblGenerateVoxelMipPixelShader\";\nconst shader = `precision highp float;precision highp sampler3D;varying vec2 vUV;uniform sampler3D srcMip;uniform int layerNum;void main(void) {ivec3 Coords=ivec3(2)*ivec3(gl_FragCoord.x,gl_FragCoord.y,layerNum);uint tex =\nuint(texelFetch(srcMip,Coords+ivec3(0,0,0),0).x>0.0f ? 1u : 0u)\n<< 0u |\nuint(texelFetch(srcMip,Coords+ivec3(1,0,0),0).x>0.0f ? 1u : 0u)\n<< 1u |\nuint(texelFetch(srcMip,Coords+ivec3(0,1,0),0).x>0.0f ? 1u : 0u)\n<< 2u |\nuint(texelFetch(srcMip,Coords+ivec3(1,1,0),0).x>0.0f ? 1u : 0u)\n<< 3u |\nuint(texelFetch(srcMip,Coords+ivec3(0,0,1),0).x>0.0f ? 1u : 0u)\n<< 4u |\nuint(texelFetch(srcMip,Coords+ivec3(1,0,1),0).x>0.0f ? 1u : 0u)\n<< 5u |\nuint(texelFetch(srcMip,Coords+ivec3(0,1,1),0).x>0.0f ? 1u : 0u)\n<< 6u |\nuint(texelFetch(srcMip,Coords+ivec3(1,1,1),0).x>0.0f ? 1u : 0u)\n<< 7u;glFragColor.rgb=vec3(float(tex)/255.0f,0.0f,0.0f);glFragColor.a=1.0;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblGenerateVoxelMipPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblGenerateVoxelMipPixelShader\";\nconst shader = `varying vUV: vec2f;var srcMip: texture_3d<f32>;uniform layerNum: i32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var Coords=vec3i(2)*vec3i(vec2i(fragmentInputs.position.xy),uniforms.layerNum);var tex =\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(0,0,0),0).x>0.0f))\n<< 0u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(1,0,0),0).x>0.0f))\n<< 1u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(0,1,0),0).x>0.0f))\n<< 2u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(1,1,0),0).x>0.0f))\n<< 3u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(0,0,1),0).x>0.0f))\n<< 4u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(1,0,1),0).x>0.0f))\n<< 5u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(0,1,1),0).x>0.0f))\n<< 6u) |\n(u32(select(0u,1u,textureLoad(srcMip,Coords+vec3i(1,1,1),0).x>0.0f))\n<< 7u);fragmentOutputs.color=vec4f( f32(tex)/255.0f,0.0f,0.0f,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblGenerateVoxelMipPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowGBufferDebugPixelShader\";\nconst shader = `#ifdef GL_ES\nprecision mediump float;\n#endif\nvarying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D depthSampler;uniform sampler2D normalSampler;uniform sampler2D positionSampler;uniform sampler2D velocitySampler;uniform vec4 sizeParams;uniform float maxDepth;\n#define offsetX sizeParams.x\n#define offsetY sizeParams.y\n#define widthScale sizeParams.z\n#define heightScale sizeParams.w\nvoid main(void) {vec2 uv =\nvec2((offsetX+vUV.x)*widthScale,(offsetY+vUV.y)*heightScale);vec4 backgroundColour=texture2D(textureSampler,vUV).rgba;vec4 depth=texture2D(depthSampler,vUV);vec4 worldNormal=texture2D(normalSampler,vUV);vec4 worldPosition=texture2D(positionSampler,vUV);vec4 velocityLinear=texture2D(velocitySampler,vUV);if (uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) {gl_FragColor.rgba=backgroundColour;} else {gl_FragColor.a=1.0;if (uv.x<=0.25) {gl_FragColor.rgb=depth.rgb;gl_FragColor.a=1.0;} else if (uv.x<=0.5) {velocityLinear.rg=velocityLinear.rg*0.5+0.5;gl_FragColor.rgb=velocityLinear.rgb;} else if (uv.x<=0.75) {gl_FragColor.rgb=worldPosition.rgb;} else {gl_FragColor.rgb=worldNormal.rgb;}}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowGBufferDebugPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblShadowGBufferDebugPixelShader\";\nconst shader = `varying vUV : vec2f;var textureSamplerSampler : sampler;var textureSampler : texture_2d<f32>;var depthSamplerSampler : sampler;var depthSampler : texture_2d<f32>;var normalSamplerSampler : sampler;var normalSampler : texture_2d<f32>;var positionSamplerSampler : sampler;var positionSampler : texture_2d<f32>;var velocitySamplerSampler : sampler;var velocitySampler : texture_2d<f32>;uniform sizeParams : vec4f;\n#define offsetX uniforms.sizeParams.x\n#define offsetY uniforms.sizeParams.y\n#define widthScale uniforms.sizeParams.z\n#define heightScale uniforms.sizeParams.w\n@fragment fn main(input : FragmentInputs)->FragmentOutputs {var uv : vec2f=\nvec2f((offsetX+input.vUV.x)*widthScale,(offsetY+input.vUV.y)*heightScale);var backgroundColour: vec4f=textureSample(textureSampler,textureSamplerSampler,input.vUV).rgba;var depth : vec4f=textureSample(depthSampler,depthSamplerSampler,input.vUV);var worldNormal: vec4f=textureSample(normalSampler,normalSamplerSampler,input.vUV);var worldPosition : vec4f=textureSample(positionSampler,positionSamplerSampler,input.vUV);var velocityLinear : vec4f=textureSample(velocitySampler,velocitySamplerSampler,input.vUV);if (uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) {fragmentOutputs.color=backgroundColour;} else {if (uv.x<=0.25) {fragmentOutputs.color=vec4f(depth.rgb,1.0);} else if (uv.x<=0.5) {velocityLinear =\nvec4f(velocityLinear.r*0.5+0.5,velocityLinear.g*0.5+0.5,\nvelocityLinear.b,velocityLinear.a);fragmentOutputs.color=vec4f(velocityLinear.rgb,1.0);} else if (uv.x<=0.75) {fragmentOutputs.color=vec4f(worldPosition.rgb,1.0);} else {fragmentOutputs.color=vec4f(worldNormal.rgb,1.0);}}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblShadowGBufferDebugPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCdfxPixelShader\";\nconst shader = `#define PI 3.1415927\nvarying vUV: vec2f;var cdfy: texture_2d<f32>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var cdfyRes=textureDimensions(cdfy,0);var currentPixel=vec2u(fragmentInputs.position.xy);var cdfx: f32=0.0;for (var x: u32=1; x<=currentPixel.x; x++) {cdfx+=textureLoad(cdfy, vec2u(x-1,cdfyRes.y-1),0).x;}\nfragmentOutputs.color= vec4f( vec3f(cdfx),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblCdfxPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCdfxPixelShader\";\nconst shader = `precision highp sampler2D;\n#define PI 3.1415927\nvarying vec2 vUV;uniform sampler2D cdfy;void main(void) {ivec2 cdfyRes=textureSize(cdfy,0);ivec2 currentPixel=ivec2(gl_FragCoord.xy);float cdfx=0.0;for (int x=1; x<=currentPixel.x; x++) {cdfx+=texelFetch(cdfy,ivec2(x-1,cdfyRes.y-1),0).x;}\ngl_FragColor=vec4(vec3(cdfx),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblCdfxPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCdfyPixelShader\";\nconst shader = `varying vUV : vec2f;\n#include <helperFunctions>\n#ifdef IBL_USE_CUBE_MAP\nvar iblSourceSampler: sampler;var iblSource: texture_cube<f32>;\n#else\nvar iblSourceSampler: sampler;var iblSource: texture_2d<f32>;\n#endif\nuniform iblHeight: i32;\n#ifdef IBL_USE_CUBE_MAP\nfn fetchCube(uv: vec2f)->f32 {var direction: vec3f=equirectangularToCubemapDirection(uv);return sin(PI*uv.y) *\ndot(textureSampleLevel(iblSource,iblSourceSampler,direction,0.0)\n.rgb,\nLuminanceEncodeApprox);}\n#else\nfn fetchPanoramic(Coords: vec2i,envmapHeight: f32)->f32 {return sin(PI*(f32(Coords.y)+0.5)/envmapHeight) *\ndot(textureLoad(iblSource,Coords,0).rgb,LuminanceEncodeApprox);}\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var coords: vec2i= vec2i(fragmentInputs.position.xy);var cdfy: f32=0.0;for (var y: i32=1; y<=coords.y; y++) {\n#ifdef IBL_USE_CUBE_MAP\nvar uv: vec2f= vec2f(input.vUV.x,( f32(y-1)+0.5)/ f32(uniforms.iblHeight));cdfy+=fetchCube(uv);\n#else\ncdfy+=fetchPanoramic( vec2i(coords.x,y-1), f32(uniforms.iblHeight));\n#endif\n}\nfragmentOutputs.color= vec4f(cdfy,0.0,0.0,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblCdfyPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblCdfyPixelShader\";\nconst shader = `precision highp sampler2D;precision highp samplerCube;\n#include<helperFunctions>\n#define PI 3.1415927\nvarying vec2 vUV;\n#ifdef IBL_USE_CUBE_MAP\nuniform samplerCube iblSource;\n#else\nuniform sampler2D iblSource;\n#endif\nuniform int iblHeight;\n#ifdef IBL_USE_CUBE_MAP\nfloat fetchCube(vec2 uv) {vec3 direction=equirectangularToCubemapDirection(uv);return sin(PI*uv.y)*dot(textureCubeLodEXT(iblSource,direction,0.0).rgb,LuminanceEncodeApprox);}\n#else\nfloat fetchPanoramic(ivec2 Coords,float envmapHeight) {return sin(PI*(float(Coords.y)+0.5)/envmapHeight) *\ndot(texelFetch(iblSource,Coords,0).rgb,LuminanceEncodeApprox);}\n#endif\nvoid main(void) {ivec2 coords=ivec2(gl_FragCoord.x,gl_FragCoord.y);float cdfy=0.0;for (int y=1; y<=coords.y; y++) {\n#ifdef IBL_USE_CUBE_MAP\nvec2 uv=vec2(vUV.x,(float(y-1)+0.5)/float(iblHeight));cdfy+=fetchCube(uv);\n#else\ncdfy+=fetchPanoramic(ivec2(coords.x,y-1),float(iblHeight));\n#endif\n}\ngl_FragColor=vec4(cdfy,0.0,0.0,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblCdfyPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblIcdfPixelShader\";\nconst shader = `#include<helperFunctions>\nvarying vUV: vec2f;\n#ifdef IBL_USE_CUBE_MAP\nvar iblSourceSampler: sampler;var iblSource: texture_cube<f32>;\n#else\nvar iblSourceSampler: sampler;var iblSource: texture_2d<f32>;\n#endif\nvar scaledLuminanceSamplerSampler : sampler;var scaledLuminanceSampler : texture_2d<f32>;var cdfx: texture_2d<f32>;var cdfy: texture_2d<f32>;fn fetchLuminance(coords: vec2f)->f32 {\n#ifdef IBL_USE_CUBE_MAP\nvar direction: vec3f=equirectangularToCubemapDirection(coords);var color: vec3f=textureSampleLevel(iblSource,iblSourceSampler,direction,0.0).rgb;\n#else\nvar color: vec3f=textureSampleLevel(iblSource,iblSourceSampler,coords,0.0).rgb;\n#endif\nreturn dot(color,LuminanceEncodeApprox);}\nfn fetchCDFx(x: u32)->f32 {return textureLoad(cdfx, vec2u(x,0),0).x;}\nfn bisectx(size: u32,targetValue: f32)->f32\n{var a: u32=0;var b=size-1;while (b-a>1) {var c: u32=(a+b)>>1;if (fetchCDFx(c)<targetValue) {a=c;}\nelse {b=c;}}\nreturn mix( f32(a), f32(b),(targetValue-fetchCDFx(a))/(fetchCDFx(b)-fetchCDFx(a)))/ f32(size-1);}\nfn fetchCDFy(y: u32,invocationId: u32)->f32 {return textureLoad(cdfy, vec2u(invocationId,y),0).x;}\nfn bisecty(size: u32,targetValue: f32,invocationId: u32)->f32\n{var a: u32=0;var b=size-1;while (b-a>1) {var c=(a+b)>>1;if (fetchCDFy(c,invocationId)<targetValue) {a=c;}\nelse {b=c;}}\nreturn mix( f32(a), f32(b),(targetValue-fetchCDFy(a,invocationId))/(fetchCDFy(b,invocationId)-fetchCDFy(a,invocationId)))/ f32(size-1);}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var cdfxSize: vec2u=textureDimensions(cdfx,0);var cdfWidth: u32=cdfxSize.x;var icdfWidth: u32=cdfWidth-1;var currentPixel: vec2u= vec2u(fragmentInputs.position.xy);var outputColor: vec3f=vec3f(1.0);if (currentPixel.x==0)\n{outputColor.x= 0.0;}\nelse if (currentPixel.x==icdfWidth-1) {outputColor.x= 1.0;} else {var targetValue: f32=fetchCDFx(cdfWidth-1)*input.vUV.x;outputColor.x= bisectx(cdfWidth,targetValue);}\nvar cdfySize: vec2u=textureDimensions(cdfy,0);var cdfHeight: u32=cdfySize.y;if (currentPixel.y==0) {outputColor.y= 0.0;}\nelse if (currentPixel.y==cdfHeight-2) {outputColor.y= 1.0;} else {var targetValue: f32=fetchCDFy(cdfHeight-1,currentPixel.x)*input.vUV.y;outputColor.y= max(bisecty(cdfHeight,targetValue,currentPixel.x),0.0);}\nvar size : vec2f=vec2f(textureDimensions(scaledLuminanceSampler,0));var highestMip: f32=floor(log2(size.x));var normalization : f32=textureSampleLevel(scaledLuminanceSampler,\nscaledLuminanceSamplerSampler,\ninput.vUV,highestMip)\n.r;var pixelLuminance: f32=fetchLuminance(input.vUV);outputColor.z=pixelLuminance/(2.0*PI*normalization);fragmentOutputs.color=vec4( outputColor,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblIcdfPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblIcdfPixelShader\";\nconst shader = `precision highp sampler2D;\n#include<helperFunctions>\nvarying vec2 vUV;\n#ifdef IBL_USE_CUBE_MAP\nuniform samplerCube iblSource;\n#else\nuniform sampler2D iblSource;\n#endif\nuniform sampler2D scaledLuminanceSampler;uniform int iblWidth;uniform int iblHeight;uniform sampler2D cdfx;uniform sampler2D cdfy;float fetchLuminance(vec2 coords) {\n#ifdef IBL_USE_CUBE_MAP\nvec3 direction=equirectangularToCubemapDirection(coords);vec3 color=textureCubeLodEXT(iblSource,direction,0.0).rgb;\n#else\nvec3 color=textureLod(iblSource,coords,0.0).rgb;\n#endif\nreturn dot(color,LuminanceEncodeApprox);}\nfloat fetchCDFx(int x) { return texelFetch(cdfx,ivec2(x,0),0).x; }\nfloat bisectx(int size,float targetValue) {int a=0,b=size-1;while (b-a>1) {int c=a+b>>1;if (fetchCDFx(c)<targetValue)\na=c;else\nb=c;}\nreturn mix(float(a),float(b),\n(targetValue-fetchCDFx(a))/(fetchCDFx(b)-fetchCDFx(a))) /\nfloat(size-1);}\nfloat fetchCDFy(int y,int invocationId) {return texelFetch(cdfy,ivec2(invocationId,y),0).x;}\nfloat bisecty(int size,float targetValue,int invocationId) {int a=0,b=size-1;while (b-a>1) {int c=a+b>>1;if (fetchCDFy(c,invocationId)<targetValue)\na=c;else\nb=c;}\nreturn mix(float(a),float(b),\n(targetValue-fetchCDFy(a,invocationId)) /\n(fetchCDFy(b,invocationId)-fetchCDFy(a,invocationId))) /\nfloat(size-1);}\nvoid main(void) {ivec2 cdfxSize=textureSize(cdfx,0);int cdfWidth=cdfxSize.x;int icdfWidth=cdfWidth-1;ivec2 currentPixel=ivec2(gl_FragCoord.xy);vec3 outputColor=vec3(1.0);if (currentPixel.x==0) {outputColor.x=0.0;} else if (currentPixel.x==icdfWidth-1) {outputColor.x=1.0;} else {float targetValue=fetchCDFx(cdfWidth-1)*vUV.x;outputColor.x=bisectx(cdfWidth,targetValue);}\nivec2 cdfySize=textureSize(cdfy,0);int cdfHeight=cdfySize.y;if (currentPixel.y==0) {outputColor.y=0.0;} else if (currentPixel.y==cdfHeight-2) {outputColor.y=1.0;} else {float targetValue=fetchCDFy(cdfHeight-1,currentPixel.x)*vUV.y;outputColor.y=max(bisecty(cdfHeight,targetValue,currentPixel.x),0.0);}\nvec2 size=vec2(textureSize(scaledLuminanceSampler,0));float highestMip=floor(log2(size.x));float normalization=texture(scaledLuminanceSampler,vUV,highestMip).r;float pixelLuminance=fetchLuminance(vUV);outputColor.z=pixelLuminance/(2.0*PI*normalization);gl_FragColor=vec4(outputColor,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblIcdfPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCdfDebugPixelShader\";\nconst shader = `#define PI 3.1415927\nvarying vUV: vec2f;var cdfySampler: sampler;var cdfy: texture_2d<f32>;var cdfxSampler: sampler;var cdfx: texture_2d<f32>;var icdfSampler: sampler;var icdf: texture_2d<f32>;\n#ifdef IBL_USE_CUBE_MAP\nvar iblSourceSampler: sampler;var iblSource: texture_cube<f32>;\n#else\nvar iblSourceSampler: sampler;var iblSource: texture_2d<f32>;\n#endif\nvar textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;\n#define cdfyVSize (0.8/3.0)\n#define cdfxVSize 0.1\n#define cdfyHSize 0.5\nuniform sizeParams: vec4f;\n#ifdef IBL_USE_CUBE_MAP\nfn equirectangularToCubemapDirection(uv: vec2f)->vec3f {var longitude: f32=uv.x*2.0*PI-PI;var latitude: f32=PI*0.5-uv.y*PI;var direction: vec3f;direction.x=cos(latitude)*sin(longitude);direction.y=sin(latitude);direction.z=cos(latitude)*cos(longitude);return direction;}\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs { \nvar colour: vec3f= vec3f(0.0);var uv: vec2f =\nvec2f((uniforms.sizeParams.x+input.vUV.x)*uniforms.sizeParams.z,(uniforms.sizeParams.y+input.vUV.y)*uniforms.sizeParams.w);var backgroundColour: vec3f=textureSample(textureSampler,textureSamplerSampler,input.vUV).rgb;var cdfxWidth: u32=textureDimensions(cdfx,0).x;var cdfyHeight: u32=textureDimensions(cdfy,0).y;const iblStart: f32=1.0-cdfyVSize;const pdfStart: f32=1.0-2.0*cdfyVSize;const cdfyStart: f32=1.0-3.0*cdfyVSize;const cdfxStart: f32=1.0-3.0*cdfyVSize-cdfxVSize;const icdfxStart: f32=1.0-3.0*cdfyVSize-2.0*cdfxVSize;\n#ifdef IBL_USE_CUBE_MAP\nvar direction: vec3f=equirectangularToCubemapDirection(\n(uv- vec2f(0.0,iblStart))* vec2f(1.0,1.0/cdfyVSize));var iblColour: vec3f=textureSampleLevel(iblSource,iblSourceSampler,direction,0.0).rgb;\n#else\nvar iblColour: vec3f=textureSample(iblSource,iblSourceSampler,(uv- vec2f(0.0,iblStart)) *\nvec2f(1.0,1.0/cdfyVSize))\n.rgb;\n#endif\nvar pdfColour: vec3f =\ntextureSample(icdf,icdfSampler,(uv- vec2f(0.0,pdfStart))* vec2f(1.0,1.0/cdfyVSize)).zzz;var cdfyColour: f32 =\ntextureSample(cdfy,cdfySampler,(uv- vec2f(0.0,cdfyStart))* vec2f(2.0,1.0/cdfyVSize)).r;var icdfyColour: f32 =\ntextureSample(icdf,icdfSampler,(uv- vec2f(0.5,cdfyStart))* vec2f(2.0,1.0/cdfyVSize)).g;var cdfxColour: f32 =\ntextureSample(cdfx,cdfxSampler,(uv- vec2f(0.0,cdfxStart))* vec2f(1.0,1.0/cdfxVSize)).r;var icdfxColour: f32=textureSample(icdf,icdfSampler,(uv- vec2f(0.0,icdfxStart)) *\nvec2f(1.0,1.0/cdfxVSize)).r;if (uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) {colour=backgroundColour;} else if (uv.y>iblStart) {colour+=iblColour;} else if (uv.y>pdfStart) {colour+=pdfColour;} else if (uv.y>cdfyStart && uv.x<0.5) {colour.r+=cdfyColour/f32(cdfyHeight);} else if (uv.y>cdfyStart && uv.x>0.5) {colour.r+=icdfyColour;} else if (uv.y>cdfxStart) {colour.r+=cdfxColour/f32(cdfxWidth);} else if (uv.y>icdfxStart) {colour.r+=icdfxColour;}\nfragmentOutputs.color =vec4(mix(colour,backgroundColour,0.5),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblCdfDebugPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCdfDebugPixelShader\";\nconst shader = `precision highp samplerCube;\n#define PI 3.1415927\nvarying vec2 vUV;uniform sampler2D cdfy;uniform sampler2D cdfx;uniform sampler2D icdf;uniform sampler2D pdf;\n#ifdef IBL_USE_CUBE_MAP\nuniform samplerCube iblSource;\n#else\nuniform sampler2D iblSource;\n#endif\nuniform sampler2D textureSampler;\n#define cdfyVSize (0.8/3.0)\n#define cdfxVSize 0.1\n#define cdfyHSize 0.5\nuniform vec4 sizeParams;\n#define offsetX sizeParams.x\n#define offsetY sizeParams.y\n#define widthScale sizeParams.z\n#define heightScale sizeParams.w\n#ifdef IBL_USE_CUBE_MAP\nvec3 equirectangularToCubemapDirection(vec2 uv) {float longitude=uv.x*2.0*PI-PI;float latitude=PI*0.5-uv.y*PI;vec3 direction;direction.x=cos(latitude)*sin(longitude);direction.y=sin(latitude);direction.z=cos(latitude)*cos(longitude);return direction;}\n#endif\nvoid main(void) {vec3 colour=vec3(0.0);vec2 uv =\nvec2((offsetX+vUV.x)*widthScale,(offsetY+vUV.y)*heightScale);vec3 backgroundColour=texture2D(textureSampler,vUV).rgb;int cdfxWidth=textureSize(cdfx,0).x;int cdfyHeight=textureSize(cdfy,0).y;const float iblStart=1.0-cdfyVSize;const float pdfStart=1.0-2.0*cdfyVSize;const float cdfyStart=1.0-3.0*cdfyVSize;const float cdfxStart=1.0-3.0*cdfyVSize-cdfxVSize;const float icdfxStart=1.0-3.0*cdfyVSize-2.0*cdfxVSize;\n#ifdef IBL_USE_CUBE_MAP\nvec3 direction=equirectangularToCubemapDirection(\n(uv-vec2(0.0,iblStart))*vec2(1.0,1.0/cdfyVSize));vec3 iblColour=textureCubeLodEXT(iblSource,direction,0.0).rgb;\n#else\nvec3 iblColour=texture2D(iblSource,(uv-vec2(0.0,iblStart)) *\nvec2(1.0,1.0/cdfyVSize))\n.rgb;\n#endif\nvec3 pdfColour=texture(icdf,(uv-vec2(0.0,pdfStart)) *\nvec2(1.0,1.0/cdfyVSize)).zzz;float cdfyColour =\ntexture2D(cdfy,(uv-vec2(0.0,cdfyStart))*vec2(2.0,1.0/cdfyVSize))\n.r;float icdfyColour =\ntexture2D(icdf,(uv-vec2(0.5,cdfyStart))*vec2(2.0,1.0/cdfyVSize))\n.g;float cdfxColour =\ntexture2D(cdfx,(uv-vec2(0.0,cdfxStart))*vec2(1.0,1.0/cdfxVSize))\n.r;float icdfxColour=texture2D(icdf,(uv-vec2(0.0,icdfxStart)) *\nvec2(1.0,1.0/cdfxVSize))\n.r;if (uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) {colour=backgroundColour;} else if (uv.y>iblStart) {colour+=iblColour;} else if (uv.y>pdfStart) {colour+=pdfColour;} else if (uv.y>cdfyStart && uv.x<0.5) {colour.r+=cdfyColour/float(cdfyHeight);} else if (uv.y>cdfyStart && uv.x>0.5) {colour.r+=icdfyColour;} else if (uv.y>cdfxStart) {colour.r+=cdfxColour/float(cdfxWidth);} else if (uv.y>icdfxStart) {colour.r+=icdfxColour;}\ngl_FragColor=vec4(colour,1.0);glFragColor.rgb=mix(gl_FragColor.rgb,backgroundColour,0.5);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblCdfDebugPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblScaledLuminancePixelShader\";\nconst shader = `#include<helperFunctions>\n#ifdef IBL_USE_CUBE_MAP\nvar iblSourceSampler: sampler;var iblSource: texture_cube<f32>;\n#else\nvar iblSourceSampler: sampler;var iblSource: texture_2d<f32>;\n#endif\nuniform iblHeight: i32;uniform iblWidth: i32;fn fetchLuminance(coords: vec2f)->f32 {\n#ifdef IBL_USE_CUBE_MAP\nvar direction: vec3f=equirectangularToCubemapDirection(coords);var color: vec3f=textureSampleLevel(iblSource,iblSourceSampler,direction,0.0).rgb;\n#else\nvar color: vec3f=textureSampleLevel(iblSource,iblSourceSampler,coords,0.0).rgb;\n#endif\nreturn dot(color,LuminanceEncodeApprox);}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var deform: f32=sin(input.vUV.y*PI);var luminance: f32=fetchLuminance(input.vUV);fragmentOutputs.color=vec4f(vec3f(deform*luminance),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblScaledLuminancePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\n\nconst name = \"iblScaledLuminancePixelShader\";\nconst shader = `precision highp sampler2D;precision highp samplerCube;\n#include<helperFunctions>\nvarying vec2 vUV;\n#ifdef IBL_USE_CUBE_MAP\nuniform samplerCube iblSource;\n#else\nuniform sampler2D iblSource;\n#endif\nuniform int iblWidth;uniform int iblHeight;float fetchLuminance(vec2 coords) {\n#ifdef IBL_USE_CUBE_MAP\nvec3 direction=equirectangularToCubemapDirection(coords);vec3 color=textureCubeLodEXT(iblSource,direction,0.0).rgb;\n#else\nvec3 color=textureLod(iblSource,coords,0.0).rgb;\n#endif\nreturn dot(color,LuminanceEncodeApprox);}\nvoid main(void) {float deform=sin(vUV.y*PI);float luminance=fetchLuminance(vUV);gl_FragColor=vec4(vec3(deform*luminance),1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblScaledLuminancePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { importanceSamplingWGSL } from \"./ShadersInclude/importanceSampling\";\nimport { pbrBRDFFunctionsWGSL } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctionsWGSL } from \"./ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"iblDominantDirectionPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nvar icdfSamplerSampler: sampler;var icdfSampler: texture_2d<f32>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var lightDir: vec3f=vec3f(0.0,0.0,0.0);for(var i: u32=0u; i<NUM_SAMPLES; i++)\n{var Xi: vec2f=hammersley(i,NUM_SAMPLES);var T: vec2f;T.x=textureSampleLevel(icdfSampler,icdfSamplerSampler,vec2(Xi.x,0.0),0.0).x;T.y=textureSampleLevel(icdfSampler,icdfSamplerSampler,vec2(T.x,Xi.y),0.0).y;var Ls: vec3f=uv_to_normal(vec2f(1.0-fract(T.x+0.25),T.y));lightDir+=Ls;}\nlightDir/=vec3f(f32(NUM_SAMPLES));fragmentOutputs.color=vec4f(lightDir,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, importanceSamplingWGSL, pbrBRDFFunctionsWGSL, hdrFilteringFunctionsWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblDominantDirectionPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { importanceSampling } from \"./ShadersInclude/importanceSampling\";\nimport { pbrBRDFFunctions } from \"./ShadersInclude/pbrBRDFFunctions\";\nimport { hdrFilteringFunctions } from \"./ShadersInclude/hdrFilteringFunctions\";\n\nconst name = \"iblDominantDirectionPixelShader\";\nconst shader = `precision highp sampler2D;precision highp samplerCube;\n#include<helperFunctions>\n#include<importanceSampling>\n#include<pbrBRDFFunctions>\n#include<hdrFilteringFunctions>\nvarying vec2 vUV;uniform sampler2D icdfSampler;void main(void) {vec3 lightDir=vec3(0.0,0.0,0.0);for(uint i=0u; i<NUM_SAMPLES; ++i)\n{vec2 Xi=hammersley(i,NUM_SAMPLES);vec2 T;T.x=texture2D(icdfSampler,vec2(Xi.x,0.0)).x;T.y=texture2D(icdfSampler,vec2(T.x,Xi.y)).y;vec3 Ls=uv_to_normal(vec2(1.0-fract(T.x+0.25),T.y));lightDir+=Ls;}\nlightDir/=float(NUM_SAMPLES);gl_FragColor=vec4(lightDir,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, importanceSampling, pbrBRDFFunctions, hdrFilteringFunctions];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblDominantDirectionPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblVoxelGrid2dArrayDebugPixelShader\";\nconst shader = `precision highp sampler2DArray;varying vec2 vUV;uniform sampler2DArray voxelTexture;uniform sampler2D textureSampler;uniform int slice;void main(void) {ivec3 size=textureSize(voxelTexture,0);float dimension=sqrt(float(size.z));vec2 samplePos=fract(vUV.xy*vec2(dimension));int sampleIndex=int(floor(vUV.x*float(dimension))+floor(vUV.y*float(dimension))*dimension);glFragColor.rgb=texture(voxelTexture,vec3(samplePos.xy,sampleIndex)).rrr;glFragColor.a=1.0;glFragColor.rgb+=texture(textureSampler,vUV.xy).rgb;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const iblVoxelGrid2dArrayDebugPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblVoxelGrid2dArrayDebugPixelShader\";\nconst shader = `varying vUV: vec2f;var voxelTextureSampler: sampler;var voxelTexture: texture_3d<f32>;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;uniform slice: i32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var size: vec3u=textureDimensions(voxelTexture,0);var dimension: f32=sqrt( f32(size.z));var samplePos: vec2f=fract(input.vUV.xy* vec2f(dimension));var sampleIndex: u32= u32(floor(input.vUV.x* f32(dimension))+floor(input.vUV.y* f32(dimension))*dimension);var color=textureSample(voxelTexture,voxelTextureSampler, vec3f(samplePos.xy,sampleIndex)).rrr;color+=textureSample(textureSampler,textureSamplerSampler,input.vUV.xy).rgb;fragmentOutputs.color=vec4f(color,1.0);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblVoxelGrid2dArrayDebugPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { mrtFragmentDeclaration } from \"./ShadersInclude/mrtFragmentDeclaration\";\n\nconst name = \"iblVoxelGridPixelShader\";\nconst shader = `#extension GL_EXT_draw_buffers : require\nprecision highp float;varying vec3 vNormalizedPosition;\n#include<mrtFragmentDeclaration>[MAX_DRAW_BUFFERS]\nuniform float nearPlane;uniform float farPlane;uniform float stepSize;void main(void) {vec3 normPos=vNormalizedPosition.xyz;if (normPos.z<nearPlane || normPos.z>farPlane) {discard;}\nglFragData[0]=normPos.z<nearPlane+stepSize ? vec4(1.0) : vec4(0.0);\n#if MAX_DRAW_BUFFERS>1\nglFragData[1]=normPos.z>=nearPlane+stepSize && normPos.z<nearPlane+2.0*stepSize ? vec4(1.0) : vec4(0.0);glFragData[2]=normPos.z>=nearPlane+2.0*stepSize && normPos.z<nearPlane+3.0*stepSize ? vec4(1.0) : vec4(0.0);glFragData[3]=normPos.z>=nearPlane+3.0*stepSize && normPos.z<nearPlane+4.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>4\nglFragData[4]=normPos.z>=nearPlane+4.0*stepSize && normPos.z<nearPlane+5.0*stepSize ? vec4(1.0) : vec4(0.0);glFragData[5]=normPos.z>=nearPlane+5.0*stepSize && normPos.z<nearPlane+6.0*stepSize ? vec4(1.0) : vec4(0.0);glFragData[6]=normPos.z>=nearPlane+6.0*stepSize && normPos.z<nearPlane+7.0*stepSize ? vec4(1.0) : vec4(0.0);glFragData[7]=normPos.z>=nearPlane+7.0*stepSize && normPos.z<nearPlane+8.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>8\nglFragData[8]=normPos.z>=nearPlane+8.0*stepSize && normPos.z<nearPlane+9.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>9\nglFragData[9]=normPos.z>=nearPlane+9.0*stepSize && normPos.z<nearPlane+10.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>10\nglFragData[10]=normPos.z>=nearPlane+10.0*stepSize && normPos.z<nearPlane+11.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>11\nglFragData[11]=normPos.z>=nearPlane+11.0*stepSize && normPos.z<nearPlane+12.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>12\nglFragData[12]=normPos.z>=nearPlane+12.0*stepSize && normPos.z<nearPlane+13.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>13\nglFragData[13]=normPos.z>=nearPlane+13.0*stepSize && normPos.z<nearPlane+14.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>14\nglFragData[14]=normPos.z>=nearPlane+14.0*stepSize && normPos.z<nearPlane+15.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n#if MAX_DRAW_BUFFERS>15\nglFragData[15]=normPos.z>=nearPlane+15.0*stepSize && normPos.z<nearPlane+16.0*stepSize ? vec4(1.0) : vec4(0.0);\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [mrtFragmentDeclaration];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblVoxelGridPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"iblVoxelGridVertexShader\";\nconst shader = `attribute vec3 position;varying vec3 vNormalizedPosition;\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<instancesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\nuniform mat4 invWorldScale;uniform mat4 viewMatrix;void main(void) {vec3 positionUpdated=position;\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);gl_Position=viewMatrix*invWorldScale*worldPos;vNormalizedPosition.xyz=gl_Position.xyz*0.5+0.5;\n#ifdef IS_NDC_HALF_ZRANGE\ngl_Position.z=gl_Position.z*0.5+0.5;\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, instancesDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblVoxelGridVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"iblVoxelOpacityAtomicMax\";\nconst shader = `fn voxelOpacityAtomicMax(vidx: u32,value: u32) {let wordIdx: u32=vidx>>2u;let shift: u32=(vidx & 3u)*8u;let mask: u32=0xFFu<<shift;let shifted: u32=(value & 0xFFu)<<shift;loop {let oldWord: u32=atomicLoad(&voxelOpacityBuffer[wordIdx]);if (value<=((oldWord>>shift) & 0xFFu)) {break;}\nlet newWord: u32=(oldWord & ~mask) | shifted;if (atomicCompareExchangeWeak(&voxelOpacityBuffer[wordIdx],oldWord,newWord).exchanged) {break;}}}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const iblVoxelOpacityAtomicMaxWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { iblVoxelOpacityAtomicMaxWGSL } from \"./ShadersInclude/iblVoxelOpacityAtomicMax\";\n\nconst name = \"iblVoxelGridPixelShader\";\nconst shader = `var voxel_storage: texture_storage_3d<r8unorm,write>;\n#ifdef IBL_VOXEL_OPACITY_BUFFER\nvar<storage,read_write> voxelOpacityBuffer: array<atomic<u32>>;\n#include<iblVoxelOpacityAtomicMax>\n#endif\nvarying vNormalizedPosition: vec3f;flat varying f_swizzle: i32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var size: vec3<u32>=textureDimensions(voxel_storage);var normPos: vec3f=input.vNormalizedPosition.xyz;switch (input.f_swizzle) {case 0: {normPos=normPos.zxy;break;}\ncase 1: {normPos=normPos.yzx;break;}\ndefault: {normPos=normPos.xyz;break;}}\nlet coord: vec3<u32>=min(\nvec3<u32>(u32(normPos.x*f32(size.x)),u32(normPos.y*f32(size.y)),u32(normPos.z*f32(size.z))),\nsize-vec3<u32>(1u));\n#ifdef IBL_VOXEL_OPACITY_BUFFER\nlet vidx: u32=coord.x+coord.y*size.x+coord.z*size.x*size.y;voxelOpacityAtomicMax(vidx,255u);\n#else\ntextureStore(voxel_storage,vec3<i32>(coord),vec4f(1.0,1.0,1.0,1.0));\n#endif\nfragmentOutputs.color=vec4<f32>(vec3<f32>(normPos),1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [iblVoxelOpacityAtomicMaxWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblVoxelGridPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { vertexPullingDeclarationWGSL } from \"./ShadersInclude/vertexPullingDeclaration\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\n\nconst name = \"iblVoxelGridVertexShader\";\nconst shader = `#include <bakedVertexAnimationDeclaration>\n#include <bonesDeclaration>(attribute matricesIndices : vec4f;,,attribute matricesWeights : vec4f;,,attribute matricesIndicesExtra : vec4f;,,attribute matricesWeightsExtra : vec4f;,)\n#include <helperFunctions>\n#include <instancesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<vertexPullingDeclaration>\nuniform invWorldScale : mat4x4f;varying vNormalizedPosition : vec3f;flat varying f_swizzle : i32;fn calculateTriangleNormal(v0\n: vec3<f32>,v1\n: vec3<f32>,v2\n: vec3<f32>)\n->vec3<f32> {let edge1=v1-v0;let edge2=v2-v0;let triangleNormal=cross(edge1,edge2);let normalizedTriangleNormal=normalize(triangleNormal);return normalizedTriangleNormal;}\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#include <morphTargetsVertexGlobal>\nvar triPositions: array<vec3f,3>;var thisTriIndex : u32=vertexInputs.vertexIndex; \nfor (var i: u32=0u; i<3u; i=i+1u) {var provokingVertNum : u32=vertexInputs.vertexIndex/3*3;let vertIdx=vp_readVertexIndex(provokingVertNum+i);if (provokingVertNum+i==vertexInputs.vertexIndex) {thisTriIndex=i;}\nvar positionUpdated=vp_readPosition(uniforms.vp_position_info,vertIdx);\n#include <instancesVertex>\nlet inputPosition: vec3f=positionUpdated;\n#include <morphTargetsVertex>(vertexInputs.position\\\\),inputPosition),vertexInputs.vertexIndex,vertIdx)[0..maxSimultaneousMorphTargets]\n#if NUM_BONE_INFLUENCERS>0\nlet matrixIndex=vp_readBoneIndices(uniforms.vp_matricesIndices_info,vertIdx);let matrixWeight=vp_readBoneWeights(uniforms.vp_matricesWeights_info,vertIdx);\n#if NUM_BONE_INFLUENCERS>4\nlet matrixIndexExtra=vp_readBoneIndicesExtra(uniforms.vp_matricesIndicesExtra_info,vertIdx);let matrixWeightExtra=vp_readBoneWeightsExtra(uniforms.vp_matricesWeightsExtra_info,vertIdx);\n#endif\n#endif\n#include<bonesVertex>(vertexInputs.matricesIndices,matrixIndex,vertexInputs.matricesWeights,matrixWeight,vertexInputs.matricesIndicesExtra,matrixIndexExtra,vertexInputs.matricesWeightsExtra,matrixWeightExtra)\n#include<bakedVertexAnimation>(vertexInputs.matricesIndices,matrixIndex,vertexInputs.matricesWeights,matrixWeight,vertexInputs.matricesIndicesExtra,matrixIndexExtra,vertexInputs.matricesWeightsExtra,matrixWeightExtra)\ntriPositions[i]=(finalWorld*vec4(positionUpdated,1.0)).xyz;}\nvar N : vec3<f32>=calculateTriangleNormal(triPositions[0],triPositions[1],triPositions[2]);let worldPos=triPositions[thisTriIndex];vertexOutputs.position=uniforms.invWorldScale*vec4(worldPos,1.0);N=abs(N);if (N.x>N.y && N.x>N.z) {vertexOutputs.f_swizzle=0;vertexOutputs.position=vec4f(vertexOutputs.position.yzx,1.0);} else if (N.y>N.z) {vertexOutputs.f_swizzle=1;vertexOutputs.position=vec4f(vertexOutputs.position.zxy,1.0);} else {vertexOutputs.f_swizzle=2;vertexOutputs.position=vec4f(vertexOutputs.position.xyz,1.0);}\nvertexOutputs.vNormalizedPosition=vertexOutputs.position.xyz*0.5+0.5;vertexOutputs.position.z =\nvertexOutputs.vNormalizedPosition.z; }\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, vertexPullingDeclarationWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const iblVoxelGridVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"oitBackBlendPixelShader\";\nconst shader = `precision highp float;uniform sampler2D uBackColor;void main() {glFragColor=texelFetch(uBackColor,ivec2(gl_FragCoord.xy),0);if (glFragColor.a==0.0) { \ndiscard;}}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const oitBackBlendPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"oitFinalPixelShader\";\nconst shader = `precision highp float;uniform sampler2D uFrontColor;uniform sampler2D uBackColor;void main() {ivec2 fragCoord=ivec2(gl_FragCoord.xy);vec4 frontColor=texelFetch(uFrontColor,fragCoord,0);vec4 backColor=texelFetch(uBackColor,fragCoord,0);float alphaMultiplier=1.0-frontColor.a;glFragColor=vec4(\nfrontColor.rgb+alphaMultiplier*backColor.rgb,\nfrontColor.a+backColor.a\n);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const oitFinalPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"oitBackBlendPixelShader\";\nconst shader = `var uBackColor: texture_2d<f32>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureLoad(uBackColor,vec2i(fragmentInputs.position.xy),0);if (fragmentOutputs.color.a==0.0) {discard;}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const oitBackBlendPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"oitFinalPixelShader\";\nconst shader = `var uFrontColor: texture_2d<f32>;var uBackColor: texture_2d<f32>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var fragCoord: vec2i=vec2i(fragmentInputs.position.xy);var frontColor: vec4f=textureLoad(uFrontColor,fragCoord,0);var backColor: vec4f=textureLoad(uBackColor,fragCoord,0);var alphaMultiplier: f32=1.0-frontColor.a;fragmentOutputs.color=vec4f(\nfrontColor.rgb+alphaMultiplier*backColor.rgb,\nfrontColor.a+backColor.a\n);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const oitFinalPixelShaderWGSL = { name, shader };\n","import { Tools } from \"../Misc/tools.pure\";\n\n/**\n * A serialized smart asset entry in the asset map JSON document.\n */\nexport interface ISerializedSmartAssetEntry {\n    /** URL or path to the asset file. */\n    readonly url: string;\n\n    /** Optional loader type hint (e.g., \"gltf\", \"texture\"). */\n    readonly type?: string;\n\n    /** Optional file extension hint (e.g., \".glb\", \".png\"). */\n    readonly extension?: string;\n\n    /** Optional user-defined metadata. */\n    readonly metadata?: Record<string, unknown>;\n}\n\n/**\n * A versioned JSON document describing a smart asset map.\n * This is the on-disk format for persisting the asset table.\n *\n * Runtime object ownership is intentionally not persisted — it is rebuilt from\n * each loaded `AssetContainer` after load. Persisting it would risk staleness.\n */\nexport interface ISerializedSmartAssetMap {\n    /** Schema version. Must be 1 for the current version. */\n    readonly version: 1;\n\n    /** Map of asset keys to their serialized entries. */\n    readonly assets: Record<string, ISerializedSmartAssetEntry>;\n}\n\n/**\n * Validates and parses a serialized smart asset map document.\n * @param data - The raw data to validate (typically parsed JSON).\n * @returns The validated document.\n * @throws If the data does not conform to the expected schema.\n */\nexport function DeserializeSmartAssetMap(data: unknown): ISerializedSmartAssetMap {\n    if (!data || typeof data !== \"object\") {\n        throw new Error(\"SmartAssetSerializer: Invalid asset map — expected an object.\");\n    }\n\n    const doc = data as Record<string, unknown>;\n\n    if (doc.version !== 1) {\n        throw new Error(`SmartAssetSerializer: Unsupported asset map version \"${doc.version}\". Expected version 1.`);\n    }\n\n    if (!doc.assets || typeof doc.assets !== \"object\" || Array.isArray(doc.assets)) {\n        throw new Error(\"SmartAssetSerializer: Invalid asset map — 'assets' must be an object.\");\n    }\n\n    const assets = doc.assets as Record<string, unknown>;\n    for (const [key, entry] of Object.entries(assets)) {\n        if (!entry || typeof entry !== \"object\") {\n            throw new Error(`SmartAssetSerializer: Invalid entry for key \"${key}\" — expected an object.`);\n        }\n        const entryObj = entry as Record<string, unknown>;\n        if (typeof entryObj.url !== \"string\" || entryObj.url.length === 0) {\n            throw new Error(`SmartAssetSerializer: Invalid entry for key \"${key}\" — 'url' must be a non-empty string.`);\n        }\n    }\n\n    return data as ISerializedSmartAssetMap;\n}\n\n/**\n * Returns true for `data:`, `blob:`, or any URL with an absolute protocol.\n * @param url - The URL to inspect.\n * @returns Whether the URL is absolute or a data/blob URI.\n */\nexport function IsAbsoluteOrSpecialUrl(url: string): boolean {\n    return url.startsWith(\"data:\") || url.startsWith(\"blob:\") || Tools.IsAbsoluteUrl(url);\n}\n\n/**\n * Resolves an asset URL relative to a base URL.\n * Absolute URLs (http://, https://) and data URIs are returned as-is.\n * @param assetUrl - The asset URL to resolve.\n * @param baseUrl - The base URL to resolve against (typically the folder containing the asset map file).\n * @returns The resolved URL.\n */\nexport function ResolveAssetUrl(assetUrl: string, baseUrl: string): string {\n    if (IsAbsoluteOrSpecialUrl(assetUrl)) {\n        return assetUrl;\n    }\n    return Tools.GetFolderPath(baseUrl) + assetUrl;\n}\n\n/**\n * Makes a URL relative to a base URL by stripping the common folder prefix.\n * If the URL doesn't share a prefix with baseUrl, returns it unchanged.\n * @param url - The URL to relativize.\n * @param baseUrl - The base URL whose folder is the relativization root.\n * @returns The relativized URL, or the original if no common prefix exists.\n */\nexport function MakeRelative(url: string, baseUrl: string): string {\n    const folder = Tools.GetFolderPath(baseUrl);\n    if (url.startsWith(folder)) {\n        return url.substring(folder.length);\n    }\n    return url;\n}\n\n/**\n * Reads a JSON source from a string URL, File object, or pre-parsed object.\n * @param source - The source to read.\n * @returns A promise resolving to the parsed JSON data.\n */\nexport async function ReadJsonSourceAsync(source: string | File | object): Promise<unknown> {\n    if (typeof source === \"string\") {\n        const response = await fetch(source);\n        if (!response.ok) {\n            throw new Error(`SmartAssetSerializer: Failed to fetch \"${source}\" — HTTP ${response.status}`);\n        }\n        return await response.json();\n    }\n\n    if (source instanceof File) {\n        return await new Promise<unknown>((resolve, reject) => {\n            const reader = new FileReader();\n            reader.onload = () => {\n                try {\n                    resolve(JSON.parse(reader.result as string));\n                } catch {\n                    reject(new Error(`SmartAssetSerializer: Failed to parse JSON from file \"${source.name}\".`));\n                }\n            };\n            reader.onerror = () => reject(new Error(`SmartAssetSerializer: Failed to read file \"${source.name}\".`));\n            reader.readAsText(source);\n        });\n    }\n\n    // Already a parsed object\n    return source;\n}\n","import { type Scene } from \"../scene\";\nimport { type AssetContainer } from \"../assetContainer\";\nimport { type Node } from \"../node\";\nimport { type Material } from \"../Materials/material\";\nimport { type BaseTexture } from \"../Materials/Textures/baseTexture\";\nimport { Texture } from \"../Materials/Textures/texture.pure\";\nimport { CubeTexture } from \"../Materials/Textures/cubeTexture.pure\";\nimport { HDRCubeTexture } from \"../Materials/Textures/hdrCubeTexture.pure\";\nimport { type AnimationGroup } from \"../Animations/animationGroup\";\nimport { Observable, type Observer } from \"../Misc/observable\";\nimport { Logger } from \"../Misc/logger\";\nimport { LoadAssetContainerAsync } from \"../Loading/sceneLoader\";\nimport { GetExtensionFromUrl } from \"../Misc/urlTools\";\nimport {\n    type ISerializedSmartAssetEntry,\n    type ISerializedSmartAssetMap,\n    DeserializeSmartAssetMap,\n    IsAbsoluteOrSpecialUrl,\n    MakeRelative,\n    ResolveAssetUrl,\n    ReadJsonSourceAsync,\n} from \"./smartAssetSerializer\";\n\n// Keep this a Symbol (not a string): scene.metadata is a publicly enumerable\n// object, and routing SAM through a symbol key keeps it out of Object.values /\n// JSON.stringify so the inspector's metadata viewer doesn't recurse into the\n// manager (which holds a back-reference to the scene, creating a cycle).\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SMART_ASSET_MANAGER_KEY = /*#__PURE__*/ Symbol(\"babylonjs:smartAssetManager\");\n\n/**\n * Stateful handle for a scene's smart asset registry.\n *\n * Smart asset behavior is exposed through module-level functions rather than\n * class methods so callers can import only the operations they need.\n */\nexport type SmartAssetManager = {\n    /**\n     * The scene this manager is attached to.\n     */\n    readonly scene: Scene;\n\n    /**\n     * Fires when the smart asset registry or loaded asset state changes.\n     */\n    readonly onChangedObservable: Observable<void>;\n\n    /**\n     * Optional callback invoked when an asset cannot be found at its registered URL.\n     * Return a new URL or File to retry loading, or null to skip the asset.\n     */\n    onAssetNotFound: ((key: string, expectedUrl: string) => Promise<string | File | null>) | null;\n};\n\n/**\n * Optional registration data that helps select the correct loader when the URL\n * does not contain a usable file extension, such as blob-backed local files.\n */\ntype SmartAssetRegistrationOptions = Pick<ISerializedSmartAssetEntry, \"type\" | \"extension\" | \"metadata\">;\n\n/**\n * Optional load-time configuration. Includes the persistable {@link SmartAssetRegistrationOptions}\n * fields (type, extension, metadata) plus a transient `reloadSource` callback used by\n * {@link ReloadSmartAssetAsync} to fetch fresh bytes from disk for blob-backed assets.\n */\nexport type SmartAssetLoadOptions = SmartAssetRegistrationOptions & {\n    /**\n     * Optional callback invoked by {@link ReloadSmartAssetAsync} to obtain a fresh File\n     * for the asset. Use this when the registered URL is a `blob:` URL backed by a\n     * `FileSystemFileHandle` so Reload can re-read the underlying file from disk.\n     */\n    readonly reloadSource?: () => Promise<File>;\n};\n\ntype SmartAssetManagerInternals = {\n    urls: Map<string, string>;\n    options: Map<string, SmartAssetRegistrationOptions>;\n    containers: Map<string, AssetContainer>;\n    objectToKeyMap: WeakMap<object, string>;\n    textureKeys: Set<string>;\n    reloadSources: Map<string, () => Promise<File>>;\n    blobUrls: Map<string, string>;\n    sceneDisposeObserver: ReturnType<Scene[\"onDisposeObservable\"][\"add\"]> | null;\n};\n\n// Lazy-initialised module state. Wrapped in accessors so the module has\n// no top-level side effects and is trivially tree-shakeable: nothing\n// allocates until a SmartAssetManager is actually created.\nlet _InternalsMap: WeakMap<SmartAssetManager, SmartAssetManagerInternals> | undefined;\nfunction GetInternalsMap(): WeakMap<SmartAssetManager, SmartAssetManagerInternals> {\n    return (_InternalsMap ??= new WeakMap());\n}\n\nlet _OnCreatedObservable: Observable<SmartAssetManager> | undefined;\nfunction GetOnCreatedObservable(): Observable<SmartAssetManager> {\n    return (_OnCreatedObservable ??= new Observable());\n}\n\n/**\n * Creates a new SmartAssetManager state object and attaches it to the scene.\n *\n * Internal: callers should use {@link GetSmartAssetManager} which returns the\n * existing manager when one is already attached.\n * @param scene - The scene this manager operates on.\n * @returns The created smart asset manager state.\n */\nfunction CreateSmartAssetManager(scene: Scene): SmartAssetManager {\n    const manager: SmartAssetManager = {\n        scene,\n        onChangedObservable: new Observable<void>(),\n        onAssetNotFound: null,\n    };\n\n    const internal: SmartAssetManagerInternals = {\n        urls: new Map(),\n        options: new Map(),\n        containers: new Map(),\n        objectToKeyMap: new WeakMap(),\n        textureKeys: new Set(),\n        reloadSources: new Map(),\n        blobUrls: new Map(),\n        sceneDisposeObserver: null,\n    };\n    GetInternalsMap().set(manager, internal);\n\n    if (!scene.metadata) {\n        scene.metadata = {};\n    }\n    scene.metadata[SMART_ASSET_MANAGER_KEY] = manager;\n\n    // Auto-dispose when the scene is disposed so the manager doesn't outlive it.\n    internal.sceneDisposeObserver = scene.onDisposeObservable.add(() => DisposeSmartAssetManager(manager));\n\n    GetOnCreatedObservable().notifyObservers(manager);\n\n    return manager;\n}\n\n/**\n * Returns the SmartAssetManager attached to the given scene, creating and\n * attaching one if none exists.\n * @param scene - The scene to look up or attach a manager to.\n * @returns The existing or newly created SmartAssetManager.\n */\nexport function GetSmartAssetManager(scene: Scene): SmartAssetManager {\n    const existing = scene.metadata?.[SMART_ASSET_MANAGER_KEY] as SmartAssetManager | undefined;\n    if (existing) {\n        return existing;\n    }\n    return CreateSmartAssetManager(scene);\n}\n\n/**\n * Adds an observer that is notified whenever a SmartAssetManager is created.\n * @param callback - The callback to invoke with each newly created manager.\n * @returns The observer registration.\n */\nexport function AddSmartAssetManagerCreatedObserver(callback: (manager: SmartAssetManager) => void): Observer<SmartAssetManager> {\n    // Wrap so the EventState second-arg from Observable.add isn't passed through to the caller.\n    return GetOnCreatedObservable().add((manager) => callback(manager));\n}\n\n/**\n * Registers a smart asset entry mapping a key to a URL.\n * @param scene - The scene whose smart asset registry to update.\n * @param key - Unique string identifier for this asset.\n * @param url - URL or path to the asset file.\n * @param options - Optional loader hints and metadata for this asset.\n */\nexport function RegisterSmartAsset(scene: Scene, key: string, url: string, options?: SmartAssetRegistrationOptions): void {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    RevokeManagedBlobUrl(internal, key, url);\n    internal.urls.set(key, url);\n    TrackManagedBlobUrl(internal, key, url);\n    if (options) {\n        const existingOptions = internal.options.get(key);\n        internal.options.set(key, { ...existingOptions, ...options });\n        if (options.type === \"texture\") {\n            internal.textureKeys.add(key);\n        } else if (options.type !== undefined) {\n            internal.textureKeys.delete(key);\n        }\n    }\n    manager.onChangedObservable.notifyObservers();\n}\n\n/**\n * Removes a key from the registry. If the asset is loaded, it is unloaded first.\n * @param scene - The scene that owns the smart asset.\n * @param key - The key to remove.\n * @returns A promise that resolves when the asset has been unloaded and removed.\n */\nexport async function RemoveSmartAssetAsync(scene: Scene, key: string): Promise<void> {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    if (internal.containers.has(key)) {\n        await UnloadSmartAssetAsync(scene, key);\n    }\n    for (const tex of [...scene.textures]) {\n        if (internal.objectToKeyMap.get(tex) === key) {\n            internal.objectToKeyMap.delete(tex);\n            tex.dispose();\n        }\n    }\n    internal.urls.delete(key);\n    internal.options.delete(key);\n    internal.textureKeys.delete(key);\n    internal.reloadSources.delete(key);\n    RevokeManagedBlobUrl(internal, key);\n    manager.onChangedObservable.notifyObservers();\n}\n\n/**\n * Returns all registered key-to-URL mappings.\n * @param scene - The scene whose smart asset registry to read.\n * @returns A read-only map of keys to URLs.\n */\nexport function GetAllSmartAssets(scene: Scene): ReadonlyMap<string, string> {\n    return GetSmartAssetInternals(GetSmartAssetManager(scene)).urls;\n}\n\n/**\n * Loads a scene-file asset by key.\n * @param scene - The scene to load the asset into.\n * @param key - The key to load.\n * @param url - Optional URL. If provided, the key is registered first.\n * @param options - Optional loader hints and metadata for this asset.\n * @returns A promise resolving to the loaded AssetContainer.\n */\nexport async function LoadSmartAssetAsync(scene: Scene, key: string, url?: string, options?: SmartAssetLoadOptions): Promise<AssetContainer> {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    const previousUrl = internal.urls.get(key);\n    const { reloadSource, ...registrationOptions } = options ?? {};\n    if (url) {\n        RegisterSmartAsset(scene, key, url, registrationOptions);\n    }\n    if (reloadSource) {\n        internal.reloadSources.set(key, reloadSource);\n    }\n\n    const resolvedUrl = internal.urls.get(key);\n    if (!resolvedUrl) {\n        throw new Error(`SmartAssetManager: Key \"${key}\" is not registered. Provide a URL to auto-register.`);\n    }\n\n    const existing = internal.containers.get(key);\n    if (existing) {\n        if (url && url !== previousUrl) {\n            // URL changed — drop the stale container before fetching the new one\n            // so callers don't get a surprise cached return for an updated URL.\n            await UnloadSmartAssetAsync(scene, key);\n        } else {\n            return existing;\n        }\n    }\n\n    return await LoadSmartAssetSceneFileAsync(manager, key, resolvedUrl, internal.options.get(key)?.extension);\n}\n\n/**\n * Loads all registered assets concurrently.\n * @param scene - The scene whose registered assets to load.\n * @returns A promise resolving to loaded scene-file containers.\n */\nexport async function LoadAllSmartAssetsAsync(scene: Scene): Promise<AssetContainer[]> {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    const scenePromises: Promise<AssetContainer | null>[] = [];\n    const texturePromises: Promise<void>[] = [];\n\n    for (const [key, url] of Array.from(internal.urls)) {\n        if (internal.containers.has(key)) {\n            continue;\n        }\n        const options = internal.options.get(key);\n        if (internal.textureKeys.has(key) || options?.type === \"texture\" || IsTextureUrl(url) || IsTextureExtension(options?.extension)) {\n            const textureLoadAsync = async () => {\n                try {\n                    await LoadSmartAssetTextureAsync(scene, key);\n                } catch {\n                    Logger.Warn(`SmartAssetManager: Texture \"${key}\" could not be loaded — skipping.`);\n                }\n            };\n            texturePromises.push(textureLoadAsync());\n        } else {\n            const sceneLoadAsync = async () => {\n                try {\n                    return await LoadSmartAssetAsync(scene, key);\n                } catch {\n                    Logger.Warn(`SmartAssetManager: Asset \"${key}\" could not be loaded — skipping.`);\n                    return null;\n                }\n            };\n            scenePromises.push(sceneLoadAsync());\n        }\n    }\n\n    await Promise.all(texturePromises);\n    const results = await Promise.all(scenePromises);\n    return results.filter((r): r is AssetContainer => r !== null);\n}\n\n/**\n * Loads a standalone texture by key.\n * @param scene - The scene to load the texture into.\n * @param key - The key to load.\n * @param url - Optional URL. If provided, the key is registered first.\n * @param options - Optional loader hints and metadata for this asset.\n * @returns A promise resolving to the loaded texture.\n */\nexport async function LoadSmartAssetTextureAsync(scene: Scene, key: string, url?: string, options?: SmartAssetLoadOptions): Promise<BaseTexture> {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    const previousUrl = internal.urls.get(key);\n    const { reloadSource, ...registrationOptions } = options ?? {};\n    if (url) {\n        RegisterSmartAsset(scene, key, url, { ...registrationOptions, type: registrationOptions.type ?? \"texture\" });\n    }\n    if (reloadSource) {\n        internal.reloadSources.set(key, reloadSource);\n    }\n\n    internal.textureKeys.add(key);\n\n    // Mirror LoadSmartAssetAsync: if a tracked texture already exists for this key,\n    // return it on a same-URL call (cache hit) or dispose it before reload on URL change.\n    // Without this guard, calling LoadSmartAssetTextureAsync twice with the same URL\n    // would create duplicate Texture objects in scene.textures.\n    const existingTextures: BaseTexture[] = [];\n    for (const tex of scene.textures) {\n        if (internal.objectToKeyMap.get(tex) === key) {\n            existingTextures.push(tex);\n        }\n    }\n    if (existingTextures.length > 0) {\n        if (url && previousUrl !== undefined && url !== previousUrl) {\n            for (const tex of existingTextures) {\n                internal.objectToKeyMap.delete(tex);\n                tex.dispose();\n            }\n        } else {\n            return existingTextures[0];\n        }\n    }\n\n    const resolvedUrl = internal.urls.get(key);\n    if (!resolvedUrl) {\n        throw new Error(`SmartAssetManager: Key \"${key}\" is not registered. Provide a URL to auto-register.`);\n    }\n\n    const extensionHint = internal.options.get(key)?.extension;\n    let texture: BaseTexture;\n    try {\n        texture = await CreateAndLoadTextureAsync(manager, resolvedUrl, extensionHint);\n    } catch (error) {\n        const fallback = await ResolveNotFoundAsync(manager, key, resolvedUrl);\n        if (!fallback) {\n            throw error;\n        }\n        texture = await CreateAndLoadTextureAsync(manager, fallback.url, fallback.extensionHint ?? extensionHint);\n    }\n\n    internal.objectToKeyMap.set(texture, key);\n\n    // Surface the registry key as the texture's display name when the texture\n    // doesn't already have one. For blob/data-URL textures (e.g. user-uploaded\n    // files) the underlying `texture.name` is an opaque blob URL, so without\n    // this any UI that shows texture names (Scene Explorer, material slot\n    // pickers, override summaries) would render the blob URL instead of the\n    // user-chosen key. We never overwrite a display name the caller already set.\n    if (!texture.displayName) {\n        texture.displayName = key;\n    }\n\n    manager.onChangedObservable.notifyObservers();\n    return texture;\n}\n\n/**\n * Unloads a loaded asset while keeping the key registered.\n * @param scene - The scene whose smart asset to unload.\n * @param key - The key to unload.\n * @returns A promise that resolves once the asset has been unloaded.\n */\nexport async function UnloadSmartAssetAsync(scene: Scene, key: string): Promise<void> {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    const container = internal.containers.get(key);\n    if (container) {\n        container.removeAllFromScene();\n        container.dispose();\n        internal.containers.delete(key);\n        manager.onChangedObservable.notifyObservers();\n        return;\n    }\n\n    for (const tex of [...scene.textures]) {\n        if (internal.objectToKeyMap.get(tex) === key) {\n            internal.objectToKeyMap.delete(tex);\n            tex.dispose();\n        }\n    }\n    manager.onChangedObservable.notifyObservers();\n}\n\n/**\n * Unloads and re-loads an asset.\n * @param scene - The scene whose smart asset to reload.\n * @param key - The key to reload.\n * @returns A promise resolving to the newly loaded AssetContainer or BaseTexture.\n */\nexport async function ReloadSmartAssetAsync(scene: Scene, key: string): Promise<AssetContainer | BaseTexture> {\n    const internal = GetSmartAssetInternals(GetSmartAssetManager(scene));\n    const reloadSource = internal.reloadSources.get(key);\n    if (reloadSource) {\n        try {\n            const freshFile = await reloadSource();\n            const blobUrl = URL.createObjectURL(freshFile);\n            RegisterSmartAsset(scene, key, blobUrl, { extension: GetExtensionFromUrl(freshFile.name) || internal.options.get(key)?.extension });\n        } catch (e) {\n            Logger.Warn(`SmartAssetManager: reloadSource callback failed for \"${key}\": ${e}`);\n        }\n    }\n\n    await UnloadSmartAssetAsync(scene, key);\n\n    if (internal.textureKeys.has(key)) {\n        return await LoadSmartAssetTextureAsync(scene, key);\n    }\n    return await LoadSmartAssetAsync(scene, key);\n}\n\n/**\n * Finds which smart asset key owns a scene object.\n * @param scene - The scene whose registry to search.\n * @param object - A scene object.\n * @returns The key, or undefined if the object is not tracked.\n */\nexport function FindSmartAssetKeyForObject(scene: Scene, object: Node | Material | BaseTexture | AnimationGroup): string | undefined {\n    return GetSmartAssetInternals(GetSmartAssetManager(scene)).objectToKeyMap.get(object);\n}\n\n/**\n * Serializes the registry to a JSON-compatible document.\n * If a baseUrl is provided, asset URLs are stored relative to it for portability.\n * @param scene - The scene whose registry to serialize.\n * @param baseUrl - Optional base URL for making asset paths relative.\n * @returns A serialized asset map document.\n */\nexport function SerializeSmartAssetManagerMap(scene: Scene, baseUrl?: string): ISerializedSmartAssetMap {\n    const internal = GetSmartAssetInternals(GetSmartAssetManager(scene));\n    const assets: Record<string, ISerializedSmartAssetEntry> = {};\n\n    for (const [key, registeredUrl] of Array.from(internal.urls)) {\n        let url = registeredUrl;\n        if (baseUrl && !IsAbsoluteOrSpecialUrl(url)) {\n            url = MakeRelative(url, baseUrl);\n        }\n        const options = internal.options.get(key);\n        assets[key] = { url, ...options, ...(internal.textureKeys.has(key) ? { type: \"texture\" } : {}) };\n    }\n\n    return { version: 1, assets };\n}\n\n/**\n * Loads an asset map from a URL, File, or pre-parsed JSON object.\n * @param scene - The scene to load assets into.\n * @param source - A URL string, File object, or pre-parsed ISerializedSmartAssetMap.\n * @param rootUrl - Optional root URL for resolving relative asset paths.\n * @returns A promise that resolves after the map has been loaded and all registered assets have been attempted.\n */\nexport async function LoadSmartAssetMapAsync(scene: Scene, source: string | File | ISerializedSmartAssetMap, rootUrl?: string): Promise<void> {\n    let resolvedRootUrl = rootUrl ?? \"\";\n\n    if (typeof source === \"string\" && !rootUrl) {\n        const { Tools } = await import(\"../Misc/tools.pure\");\n        resolvedRootUrl = Tools.GetFolderPath(source);\n    }\n\n    const raw = await ReadJsonSourceAsync(source);\n    const doc = DeserializeSmartAssetMap(raw);\n\n    for (const [key, entry] of Object.entries(doc.assets)) {\n        const resolved = resolvedRootUrl ? ResolveAssetUrl(entry.url, resolvedRootUrl) : entry.url;\n        RegisterSmartAsset(scene, key, resolved, { type: entry.type, extension: entry.extension, metadata: entry.metadata });\n    }\n\n    await LoadAllSmartAssetsAsync(scene);\n}\n\n/**\n * Registers an externally loaded AssetContainer under a key.\n * @param manager - The smart asset manager state.\n * @param key - The key to associate with the container.\n * @param container - The loaded AssetContainer.\n */\nfunction TrackLoadedSmartAssetContainer(manager: SmartAssetManager, key: string, container: AssetContainer): void {\n    const internal = GetSmartAssetInternals(manager);\n    internal.containers.set(key, container);\n    TrackSmartAssetContainerObjects(manager, key, container);\n    manager.onChangedObservable.notifyObservers();\n}\n\n/**\n * Disposes the manager, unloading all assets and detaching it from its scene.\n * Safe to call multiple times; subsequent calls are no-ops. Automatically invoked when the\n * owning scene is disposed.\n * @param manager - The smart asset manager state.\n */\nexport function DisposeSmartAssetManager(manager: SmartAssetManager): void {\n    const internal = GetInternalsMap().get(manager);\n    if (!internal) {\n        return;\n    }\n    GetInternalsMap().delete(manager);\n\n    if (internal.sceneDisposeObserver) {\n        manager.scene.onDisposeObservable.remove(internal.sceneDisposeObserver);\n        internal.sceneDisposeObserver = null;\n    }\n\n    for (const container of Array.from(internal.containers.values())) {\n        container.removeAllFromScene();\n        container.dispose();\n    }\n    for (const tex of [...manager.scene.textures]) {\n        if (internal.objectToKeyMap.get(tex) !== undefined) {\n            tex.dispose();\n        }\n    }\n\n    internal.urls.clear();\n    internal.options.clear();\n    internal.textureKeys.clear();\n    internal.reloadSources.clear();\n    internal.containers.clear();\n    for (const blobUrl of Array.from(internal.blobUrls.values())) {\n        URL.revokeObjectURL(blobUrl);\n    }\n    internal.blobUrls.clear();\n\n    manager.onChangedObservable.clear();\n\n    if (manager.scene.metadata) {\n        delete manager.scene.metadata[SMART_ASSET_MANAGER_KEY];\n    }\n}\n\nfunction GetSmartAssetInternals(manager: SmartAssetManager): SmartAssetManagerInternals {\n    const internal = GetInternalsMap().get(manager);\n    if (!internal) {\n        throw new Error(\"SmartAssetManager: Unknown manager state.\");\n    }\n    return internal;\n}\n\nfunction RevokeManagedBlobUrl(internal: SmartAssetManagerInternals, key: string, replacementUrl?: string): void {\n    const blobUrl = internal.blobUrls.get(key);\n    if (!blobUrl || blobUrl === replacementUrl) {\n        return;\n    }\n    URL.revokeObjectURL(blobUrl);\n    internal.blobUrls.delete(key);\n}\n\nfunction TrackManagedBlobUrl(internal: SmartAssetManagerInternals, key: string, url: string): void {\n    if (url.startsWith(\"blob:\")) {\n        internal.blobUrls.set(key, url);\n    }\n}\n\nasync function CreateAndLoadTextureAsync(manager: SmartAssetManager, url: string, extensionHint?: string): Promise<BaseTexture> {\n    return await new Promise<BaseTexture>((resolve, reject) => {\n        const ext = (extensionHint || GetExtensionFromUrl(url)).toLowerCase();\n        const onError = (message?: string, exception?: unknown) => {\n            const err = exception instanceof Error ? exception : new Error(message ?? `SmartAssetManager: failed to load texture from \"${url}\".`);\n            reject(err);\n        };\n        let texture: BaseTexture;\n        const onLoad = () => resolve(texture);\n        if (ext === \".hdr\") {\n            // HDR equirectangular files require HDRCubeTexture — CubeTexture's .hdr\n            // loader explicitly throws \".hdr not supported in Cube.\" so we can't\n            // route HDRs through the generic CubeTexture path.\n            texture = new HDRCubeTexture(url, manager.scene, 256, false, true, false, false, onLoad, onError);\n        } else if (ext === \".env\" || ext === \".dds\") {\n            texture = new CubeTexture(url, manager.scene, null, false, null, onLoad, onError, undefined, ext === \".env\");\n        } else {\n            texture = new Texture(url, manager.scene, undefined, undefined, undefined, onLoad, onError);\n        }\n    });\n}\n\nasync function ResolveNotFoundAsync(manager: SmartAssetManager, key: string, expectedUrl: string): Promise<{ url: string; extensionHint?: string } | null> {\n    if (!manager.onAssetNotFound) {\n        return null;\n    }\n    const resolution = await manager.onAssetNotFound(key, expectedUrl);\n    if (resolution === null || resolution === undefined) {\n        return null;\n    }\n    if (typeof resolution === \"string\") {\n        RegisterSmartAsset(manager.scene, key, resolution);\n        return { url: resolution, extensionHint: GetSmartAssetInternals(manager).options.get(key)?.extension };\n    }\n    const blobUrl = URL.createObjectURL(resolution);\n    const extensionHint = GetExtensionFromUrl(resolution.name) || undefined;\n    RegisterSmartAsset(manager.scene, key, blobUrl, { extension: extensionHint });\n    return { url: blobUrl, extensionHint };\n}\n\nasync function LoadSmartAssetSceneFileAsync(manager: SmartAssetManager, key: string, url: string, extensionHint?: string): Promise<AssetContainer> {\n    const loadAsync = async (loadUrl: string, extensionHint?: string) => {\n        const container = await LoadAssetContainerAsync(loadUrl, manager.scene, { pluginExtension: extensionHint });\n        container.addAllToScene();\n        TrackLoadedSmartAssetContainer(manager, key, container);\n        return container;\n    };\n\n    try {\n        return await loadAsync(url, extensionHint);\n    } catch (error) {\n        const fallback = await ResolveNotFoundAsync(manager, key, url);\n        if (fallback) {\n            try {\n                return await loadAsync(fallback.url, fallback.extensionHint);\n            } catch (retryError) {\n                Logger.Warn(`SmartAssetManager: Asset \"${key}\" could not be loaded from fallback \"${fallback.url}\".`);\n                throw retryError;\n            }\n        }\n        Logger.Warn(`SmartAssetManager: Asset \"${key}\" could not be loaded from \"${url}\".`);\n        throw error;\n    }\n}\n\nfunction TrackSmartAssetContainerObjects(manager: SmartAssetManager, key: string, container: AssetContainer): void {\n    const internal = GetSmartAssetInternals(manager);\n\n    for (const collection of [\n        container.meshes,\n        container.transformNodes,\n        container.materials,\n        container.textures,\n        container.animationGroups,\n        container.lights,\n        container.cameras,\n    ]) {\n        for (const obj of collection) {\n            internal.objectToKeyMap.set(obj, key);\n        }\n    }\n}\n\nlet _TextureExtensions: Set<string> | undefined;\n/**\n * Returns the set of file extensions (including the leading dot) that {@link LoadAllSmartAssetsAsync}\n * treats as standalone textures.\n * @returns A read-only set of texture file extensions.\n */\nexport function GetSmartAssetTextureExtensions(): ReadonlySet<string> {\n    return (_TextureExtensions ??= new Set([\".png\", \".jpg\", \".jpeg\", \".bmp\", \".tga\", \".gif\", \".webp\", \".env\", \".hdr\", \".dds\", \".ktx\", \".ktx2\", \".basis\"]));\n}\n\n/**\n * Returns true if the URL points to a standalone texture file.\n * @param url - The URL to check.\n * @returns True if the URL has a texture file extension.\n */\nfunction IsTextureUrl(url: string): boolean {\n    return GetSmartAssetTextureExtensions().has(GetExtensionFromUrl(url));\n}\n\nfunction IsTextureExtension(extension: string | undefined): boolean {\n    return extension !== undefined && GetSmartAssetTextureExtensions().has(extension.toLowerCase());\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type IDisposable, type Scene } from \"../scene.pure\";\r\nimport { type Nullable } from \"../types\";\r\nimport { Vector2, Vector3 } from \"../Maths/math.vector.pure\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport { ShaderMaterial } from \"../Materials/shaderMaterial.pure\";\r\nimport { type Mesh } from \"../Meshes/mesh.pure\";\r\nimport { type PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport { type ISpriteJSONSprite, type ISpriteJSONAtlas } from \"./ISprites\";\r\nimport { Effect } from \"../Materials/effect.pure\";\r\n\r\nimport { CreatePlane } from \"../Meshes/Builders/planeBuilder.pure\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\nexport enum SpriteMapFrameRotationDirection {\r\n    CCW = 0,\r\n    CW = 1,\r\n}\r\n\r\n/**\r\n * Defines the basic options interface of a SpriteMap\r\n */\r\nexport interface ISpriteMapOptions {\r\n    /**\r\n     * Vector2 of the number of cells in the grid.\r\n     */\r\n    stageSize?: Vector2;\r\n\r\n    /**\r\n     * Vector2 of the size of the output plane in World Units.\r\n     */\r\n    outputSize?: Vector2;\r\n\r\n    /**\r\n     * Vector3 of the position of the output plane in World Units.\r\n     */\r\n    outputPosition?: Vector3;\r\n\r\n    /**\r\n     * Vector3 of the rotation of the output plane.\r\n     */\r\n    outputRotation?: Vector3;\r\n\r\n    /**\r\n     * number of layers that the system will reserve in resources.\r\n     */\r\n    layerCount?: number;\r\n\r\n    /**\r\n     * number of max animation frames a single cell will reserve in resources.\r\n     */\r\n    maxAnimationFrames?: number;\r\n\r\n    /**\r\n     * number cell index of the base tile when the system compiles.\r\n     */\r\n    baseTile?: number;\r\n\r\n    /**\r\n     * boolean flip the sprite after its been repositioned by the framing data.\r\n     */\r\n    flipU?: boolean;\r\n\r\n    /**\r\n     * Vector3 scalar of the global RGB values of the SpriteMap.\r\n     */\r\n    colorMultiply?: Vector3;\r\n\r\n    /**\r\n     * Rotation direction of the frame by 90 degrees.\r\n     * Applied when the the frame's \"rotated\" parameter is true.\r\n     * Default is CCW.\r\n     */\r\n    frameRotationDirection?: SpriteMapFrameRotationDirection;\r\n}\r\n\r\n/**\r\n * Defines the IDisposable interface in order to be cleanable from resources.\r\n */\r\nexport interface ISpriteMap extends IDisposable {\r\n    /**\r\n     * String name of the SpriteMap.\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * The JSON Array file from a https://www.codeandweb.com/texturepacker export.  Or similar structure.\r\n     */\r\n    atlasJSON: ISpriteJSONAtlas;\r\n\r\n    /**\r\n     * Texture of the SpriteMap.\r\n     */\r\n    spriteSheet: Texture;\r\n\r\n    /**\r\n     * The parameters to initialize the SpriteMap with.\r\n     */\r\n    options: ISpriteMapOptions;\r\n}\r\n\r\n/**\r\n * Class used to manage a grid restricted sprite deployment on an Output plane.\r\n */\r\nexport class SpriteMap implements ISpriteMap {\r\n    /** The Name of the spriteMap */\r\n    public name: string;\r\n\r\n    /** The JSON file with the frame and meta data */\r\n    public atlasJSON: ISpriteJSONAtlas;\r\n\r\n    /** The systems Sprite Sheet Texture */\r\n    public spriteSheet: Texture;\r\n\r\n    /** Arguments passed with the Constructor */\r\n    public options: ISpriteMapOptions;\r\n\r\n    /** Public Sprite Storage array, parsed from atlasJSON */\r\n    public sprites: Array<ISpriteJSONSprite>;\r\n\r\n    /** Returns the Number of Sprites in the System */\r\n    public get spriteCount(): number {\r\n        return this.sprites.length;\r\n    }\r\n\r\n    /** Returns the Position of Output Plane*/\r\n    public get position(): Vector3 {\r\n        return this._output.position;\r\n    }\r\n\r\n    /** Returns the Position of Output Plane*/\r\n    public set position(v: Vector3) {\r\n        this._output.position = v;\r\n    }\r\n\r\n    /** Returns the Rotation of Output Plane*/\r\n    public get rotation(): Vector3 {\r\n        return this._output.rotation;\r\n    }\r\n\r\n    /** Returns the Rotation of Output Plane*/\r\n    public set rotation(v: Vector3) {\r\n        this._output.rotation = v;\r\n    }\r\n\r\n    /** Sets the AnimationMap*/\r\n    public get animationMap() {\r\n        return this._animationMap;\r\n    }\r\n\r\n    /** Sets the AnimationMap*/\r\n    public set animationMap(v: RawTexture) {\r\n        const buffer = v._texture!._bufferView;\r\n        const am = this._createTileAnimationBuffer(buffer);\r\n        this._animationMap.dispose();\r\n        this._animationMap = am;\r\n        this._material.setTexture(\"animationMap\", this._animationMap);\r\n    }\r\n\r\n    /** Gets or sets a boolean indicating if the sprite map must consider scene fog when rendering */\r\n    public get fogEnabled(): boolean {\r\n        return this._material.fogEnabled;\r\n    }\r\n    public set fogEnabled(value: boolean) {\r\n        this._material.fogEnabled = value;\r\n    }\r\n\r\n    protected _useLogarithmicDepth: boolean;\r\n\r\n    /** Gets or sets a boolean indicating if the sprite map must use logarithmic depth when rendering */\r\n    public get useLogarithmicDepth(): boolean {\r\n        return this._material.useLogarithmicDepth;\r\n    }\r\n    public set useLogarithmicDepth(value: boolean) {\r\n        this._material.useLogarithmicDepth = value;\r\n    }\r\n\r\n    /** Scene that the SpriteMap was created in */\r\n    private _scene: Scene;\r\n\r\n    /** Texture Buffer of Float32 that holds tile frame data*/\r\n    private _frameMap: RawTexture;\r\n\r\n    /** Texture Buffers of Float32 that holds tileMap data*/\r\n    private _tileMaps: RawTexture[];\r\n\r\n    /** Texture Buffer of Float32 that holds Animation Data*/\r\n    private _animationMap: RawTexture;\r\n\r\n    /** Custom ShaderMaterial Central to the System*/\r\n    private _material: ShaderMaterial;\r\n\r\n    /** Custom ShaderMaterial Central to the System*/\r\n    private _output: Mesh;\r\n\r\n    /** Systems Time Ticker*/\r\n    private _time: number;\r\n\r\n    /**\r\n     * Creates a new SpriteMap\r\n     * @param name defines the SpriteMaps Name\r\n     * @param atlasJSON is the JSON file that controls the Sprites Frames and Meta\r\n     * @param spriteSheet is the Texture that the Sprites are on.\r\n     * @param options a basic deployment configuration\r\n     * @param scene The Scene that the map is deployed on\r\n     */\r\n    constructor(name: string, atlasJSON: ISpriteJSONAtlas, spriteSheet: Texture, options: ISpriteMapOptions, scene: Scene) {\r\n        this.name = name;\r\n        this.sprites = [];\r\n        this.atlasJSON = atlasJSON;\r\n        this.sprites = this.atlasJSON[\"frames\"];\r\n        this.spriteSheet = spriteSheet;\r\n\r\n        /**\r\n         * Run through the options and set what ever defaults are needed that where not declared.\r\n         */\r\n        this.options = options;\r\n        options.stageSize = options.stageSize || new Vector2(1, 1);\r\n        options.outputSize = options.outputSize || options.stageSize;\r\n        options.outputPosition = options.outputPosition || Vector3.Zero();\r\n        options.outputRotation = options.outputRotation || Vector3.Zero();\r\n        options.layerCount = options.layerCount || 1;\r\n        options.maxAnimationFrames = options.maxAnimationFrames || 0;\r\n        options.baseTile = options.baseTile || 0;\r\n        options.flipU = options.flipU || false;\r\n        options.colorMultiply = options.colorMultiply || new Vector3(1, 1, 1);\r\n\r\n        this._scene = scene;\r\n\r\n        this._frameMap = this._createFrameBuffer();\r\n\r\n        this._tileMaps = [];\r\n        for (let i = 0; i < options.layerCount; i++) {\r\n            this._tileMaps.push(this._createTileBuffer(null, i));\r\n        }\r\n\r\n        this._animationMap = this._createTileAnimationBuffer(null);\r\n\r\n        const defines = [];\r\n        defines.push(\"#define LAYERS \" + options.layerCount);\r\n\r\n        if (options?.frameRotationDirection === SpriteMapFrameRotationDirection.CW) {\r\n            defines.push(\"#define FR_CW\");\r\n        }\r\n\r\n        if (options.flipU) {\r\n            defines.push(\"#define FLIPU\");\r\n        }\r\n\r\n        defines.push(`#define MAX_ANIMATION_FRAMES ${options.maxAnimationFrames}.0`);\r\n\r\n        const shaderString: string = Effect.ShadersStore[\"spriteMapPixelShader\"];\r\n\r\n        let layerSampleString: string;\r\n        if (!scene.getEngine()._features.supportSwitchCaseInShader) {\r\n            layerSampleString = \"\";\r\n            for (let i = 0; i < options.layerCount; i++) {\r\n                layerSampleString += `if (${i} == i) { frameID = texture2D(tileMaps[${i}], (tileID + 0.5) / stageSize, 0.).x; }`;\r\n            }\r\n        } else {\r\n            layerSampleString = \"switch(i) {\";\r\n            for (let i = 0; i < options.layerCount; i++) {\r\n                layerSampleString += \"case \" + i + \" : frameID = texture(tileMaps[\" + i + \"], (tileID + 0.5) / stageSize, 0.).x;\";\r\n                layerSampleString += \"break;\";\r\n            }\r\n            layerSampleString += \"}\";\r\n        }\r\n\r\n        Effect.ShadersStore[\"spriteMap\" + this.name + \"PixelShader\"] = shaderString.replace(\"#define LAYER_ID_SWITCH\", layerSampleString);\r\n\r\n        this._material = new ShaderMaterial(\r\n            \"spriteMap:\" + this.name,\r\n            this._scene,\r\n            {\r\n                vertex: \"spriteMap\",\r\n                fragment: \"spriteMap\" + this.name,\r\n            },\r\n            {\r\n                defines,\r\n                attributes: [\"position\", \"normal\", \"uv\"],\r\n                uniforms: [\r\n                    \"world\",\r\n                    \"view\",\r\n                    \"projection\",\r\n                    \"time\",\r\n                    \"stageSize\",\r\n                    \"outputSize\",\r\n                    \"spriteMapSize\",\r\n                    \"spriteCount\",\r\n                    \"time\",\r\n                    \"colorMul\",\r\n                    \"mousePosition\",\r\n                    \"curTile\",\r\n                    \"flipU\",\r\n                ],\r\n                samplers: [\"spriteSheet\", \"frameMap\", \"tileMaps\", \"animationMap\"],\r\n                needAlphaBlending: true,\r\n            }\r\n        );\r\n\r\n        this._time = 0;\r\n\r\n        this._material.setFloat(\"spriteCount\", this.spriteCount);\r\n        this._material.setVector2(\"stageSize\", options.stageSize);\r\n        this._material.setVector2(\"outputSize\", options.outputSize);\r\n        this._material.setTexture(\"spriteSheet\", this.spriteSheet);\r\n        this._material.setVector2(\"spriteMapSize\", new Vector2(1, 1));\r\n        this._material.setVector3(\"colorMul\", options.colorMultiply);\r\n\r\n        let tickSave = 0;\r\n\r\n        const bindSpriteTexture = () => {\r\n            if (this.spriteSheet && this.spriteSheet.isReady()) {\r\n                if (this.spriteSheet._texture) {\r\n                    this._material.setVector2(\"spriteMapSize\", new Vector2(this.spriteSheet._texture.baseWidth || 1, this.spriteSheet._texture.baseHeight || 1));\r\n                    return;\r\n                }\r\n            }\r\n            if (tickSave < 100) {\r\n                setTimeout(() => {\r\n                    tickSave++;\r\n                    bindSpriteTexture();\r\n                }, 100);\r\n            }\r\n        };\r\n\r\n        bindSpriteTexture();\r\n\r\n        this._material.setVector3(\"colorMul\", options.colorMultiply);\r\n        this._material.setTexture(\"frameMap\", this._frameMap);\r\n        this._material.setTextureArray(\"tileMaps\", this._tileMaps);\r\n        this._material.setTexture(\"animationMap\", this._animationMap);\r\n        this._material.setFloat(\"time\", this._time);\r\n\r\n        this._output = CreatePlane(name + \":output\", { size: 1, updatable: true }, scene);\r\n        this._output.scaling.x = options.outputSize.x;\r\n        this._output.scaling.y = options.outputSize.y;\r\n        this.position = options.outputPosition;\r\n        this.rotation = options.outputRotation;\r\n\r\n        const obfunction = () => {\r\n            this._time += this._scene.getEngine().getDeltaTime();\r\n            this._material.setFloat(\"time\", this._time);\r\n        };\r\n\r\n        this._scene.onBeforeRenderObservable.add(obfunction);\r\n        this._output.material = this._material;\r\n    }\r\n\r\n    /**\r\n     * Returns the index of the frame for a given filename\r\n     * @param name filename of the frame\r\n     * @returns index of the frame\r\n     */\r\n    public getTileIdxByName(name: string): number {\r\n        const idx = this.atlasJSON.frames.findIndex((f) => f.filename === name);\r\n        return idx;\r\n    }\r\n\r\n    /**\r\n     * Returns tileID location\r\n     * @returns Vector2 the cell position ID\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public getTileID(): Vector2 {\r\n        const p = this.getMousePosition();\r\n        p.multiplyInPlace(this.options.stageSize || Vector2.Zero());\r\n        p.x = Math.floor(p.x);\r\n        p.y = Math.floor(p.y);\r\n        return p;\r\n    }\r\n\r\n    /**\r\n     * Gets the UV location of the mouse over the SpriteMap.\r\n     * @returns Vector2 the UV position of the mouse interaction\r\n     */\r\n    public getMousePosition(): Vector2 {\r\n        const out = this._output;\r\n        const pickinfo: Nullable<PickingInfo> = this._scene.pick(this._scene.pointerX, this._scene.pointerY, (mesh) => {\r\n            if (mesh !== out) {\r\n                return false;\r\n            }\r\n            return true;\r\n        });\r\n\r\n        if (!pickinfo || !pickinfo.hit || !pickinfo.getTextureCoordinates) {\r\n            return new Vector2(-1, -1);\r\n        }\r\n\r\n        const coords = pickinfo.getTextureCoordinates();\r\n        if (coords) {\r\n            return coords;\r\n        }\r\n\r\n        return new Vector2(-1, -1);\r\n    }\r\n\r\n    /**\r\n     * Creates the \"frame\" texture Buffer\r\n     * -------------------------------------\r\n     * Structure of frames\r\n     *  \"filename\": \"Falling-Water-2.png\",\r\n     * \"frame\": {\"x\":69,\"y\":103,\"w\":24,\"h\":32},\r\n     * \"rotated\": true,\r\n     * \"trimmed\": true,\r\n     * \"spriteSourceSize\": {\"x\":4,\"y\":0,\"w\":24,\"h\":32},\r\n     * \"sourceSize\": {\"w\":32,\"h\":32}\r\n     * @returns RawTexture of the frameMap\r\n     */\r\n    private _createFrameBuffer(): RawTexture {\r\n        const data = [];\r\n        //Do two Passes\r\n        for (let i = 0; i < this.spriteCount; i++) {\r\n            data.push(0, 0, 0, 0); //frame\r\n            data.push(0, 0, 0, 0); //spriteSourceSize\r\n            data.push(0, 0, 0, 0); //sourceSize, rotated, trimmed\r\n            data.push(0, 0, 0, 0); //Keep it pow2 cause I\"m cool like that... it helps with sampling accuracy as well. Plus then we have 4 other parameters for future stuff.\r\n        }\r\n        //Second Pass\r\n        for (let i = 0; i < this.spriteCount; i++) {\r\n            const f = this.sprites[i][\"frame\"];\r\n            const sss = this.sprites[i][\"spriteSourceSize\"];\r\n            const ss = this.sprites[i][\"sourceSize\"];\r\n            const r = this.sprites[i][\"rotated\"] ? 1 : 0;\r\n            const t = this.sprites[i][\"trimmed\"] ? 1 : 0;\r\n\r\n            //frame\r\n            data[i * 4] = f.x;\r\n            data[i * 4 + 1] = f.y;\r\n            data[i * 4 + 2] = f.w;\r\n            data[i * 4 + 3] = f.h;\r\n            //spriteSourceSize\r\n            data[i * 4 + this.spriteCount * 4] = sss.x;\r\n            data[i * 4 + 1 + this.spriteCount * 4] = sss.y;\r\n            data[i * 4 + 3 + this.spriteCount * 4] = sss.h;\r\n            //sourceSize, rotated, trimmed\r\n            data[i * 4 + this.spriteCount * 8] = ss.w;\r\n            data[i * 4 + 1 + this.spriteCount * 8] = ss.h;\r\n            data[i * 4 + 2 + this.spriteCount * 8] = r;\r\n            data[i * 4 + 3 + this.spriteCount * 8] = t;\r\n        }\r\n\r\n        const floatArray = new Float32Array(data);\r\n\r\n        const t = RawTexture.CreateRGBATexture(floatArray, this.spriteCount, 4, this._scene, false, false, Texture.NEAREST_NEAREST, Constants.TEXTURETYPE_FLOAT);\r\n\r\n        return t;\r\n    }\r\n\r\n    /**\r\n     * Creates the tileMap texture Buffer\r\n     * @param buffer normally and array of numbers, or a false to generate from scratch\r\n     * @param _layer indicates what layer for a logic trigger dealing with the baseTile.  The system uses this\r\n     * @returns RawTexture of the tileMap\r\n     */\r\n    private _createTileBuffer(buffer: any, _layer: number = 0): RawTexture {\r\n        let data = [];\r\n        const _ty = this.options.stageSize!.y || 0;\r\n        const _tx = this.options.stageSize!.x || 0;\r\n\r\n        if (!buffer) {\r\n            let bt = this.options.baseTile;\r\n            if (_layer != 0) {\r\n                bt = 0;\r\n            }\r\n\r\n            for (let y = 0; y < _ty; y++) {\r\n                for (let x = 0; x < _tx * 4; x += 4) {\r\n                    data.push(bt, 0, 0, 0);\r\n                }\r\n            }\r\n        } else {\r\n            data = buffer;\r\n        }\r\n\r\n        const floatArray = new Float32Array(data);\r\n        const t = RawTexture.CreateRGBATexture(floatArray, _tx, _ty, this._scene, false, false, Texture.NEAREST_NEAREST, Constants.TEXTURETYPE_FLOAT);\r\n\r\n        return t;\r\n    }\r\n\r\n    /**\r\n     * Modifies the data of the tileMaps\r\n     * @param _layer is the ID of the layer you want to edit on the SpriteMap\r\n     * @param pos is the iVector2 Coordinates of the Tile\r\n     * @param tile The SpriteIndex of the new Tile\r\n     */\r\n    public changeTiles(_layer: number = 0, pos: Vector2 | Vector2[], tile: number = 0): void {\r\n        const buffer = this._tileMaps[_layer]._texture!._bufferView;\r\n        if (buffer === null) {\r\n            return;\r\n        }\r\n\r\n        let p = [];\r\n        if (pos instanceof Vector2) {\r\n            p.push(pos);\r\n        } else {\r\n            p = pos;\r\n        }\r\n\r\n        const _tx = this.options.stageSize!.x || 0;\r\n\r\n        for (let i = 0; i < p.length; i++) {\r\n            const _p = p[i];\r\n            _p.x = Math.floor(_p.x);\r\n            _p.y = Math.floor(_p.y);\r\n            const id: number = _p.x * 4 + _p.y * (_tx * 4);\r\n            (buffer as any)[id] = tile;\r\n        }\r\n\r\n        const t = this._createTileBuffer(buffer);\r\n        this._tileMaps[_layer].dispose();\r\n        this._tileMaps[_layer] = t;\r\n        this._material.setTextureArray(\"tileMap\", this._tileMaps);\r\n    }\r\n\r\n    /**\r\n     * Creates the animationMap texture Buffer\r\n     * @param buffer normally and array of numbers, or a false to generate from scratch\r\n     * @returns RawTexture of the animationMap\r\n     */\r\n    private _createTileAnimationBuffer(buffer: Nullable<ArrayBufferView>): RawTexture {\r\n        const data = [];\r\n        let floatArray;\r\n        if (!buffer) {\r\n            for (let i = 0; i < this.spriteCount; i++) {\r\n                data.push(0, 0, 0, 0);\r\n                let count = 1;\r\n                while (count < (this.options.maxAnimationFrames || 4)) {\r\n                    data.push(0, 0, 0, 0);\r\n                    count++;\r\n                }\r\n            }\r\n            floatArray = new Float32Array(data);\r\n        } else {\r\n            floatArray = buffer;\r\n        }\r\n\r\n        const t = RawTexture.CreateRGBATexture(\r\n            floatArray,\r\n            this.spriteCount,\r\n            this.options.maxAnimationFrames || 4,\r\n            this._scene,\r\n            false,\r\n            false,\r\n            Texture.NEAREST_NEAREST,\r\n            Constants.TEXTURETYPE_FLOAT\r\n        );\r\n\r\n        return t;\r\n    }\r\n\r\n    /**\r\n     * Modifies the data of the animationMap\r\n     * @param cellID is the Index of the Sprite\r\n     * @param _frame is the target Animation frame\r\n     * @param toCell is the Target Index of the next frame of the animation\r\n     * @param time is a value between 0-1 that is the trigger for when the frame should change tiles\r\n     * @param speed is a global scalar of the time variable on the map.\r\n     */\r\n    public addAnimationToTile(cellID: number = 0, _frame: number = 0, toCell: number = 0, time: number = 0, speed: number = 1): void {\r\n        const buffer: any = this._animationMap._texture!._bufferView;\r\n        const id: number = cellID * 4 + this.spriteCount * 4 * _frame;\r\n        if (!buffer) {\r\n            return;\r\n        }\r\n        buffer[id] = toCell;\r\n        buffer[id + 1] = time;\r\n        buffer[id + 2] = speed;\r\n        const t = this._createTileAnimationBuffer(buffer);\r\n        this._animationMap.dispose();\r\n        this._animationMap = t;\r\n        this._material.setTexture(\"animationMap\", this._animationMap);\r\n    }\r\n\r\n    /**\r\n     * Exports the .tilemaps file\r\n     */\r\n    public saveTileMaps(): void {\r\n        let maps = \"\";\r\n        for (let i = 0; i < this._tileMaps.length; i++) {\r\n            if (i > 0) {\r\n                maps += \"\\n\\r\";\r\n            }\r\n\r\n            maps += this._tileMaps[i]._texture!._bufferView!.toString();\r\n        }\r\n        const hiddenElement = document.createElement(\"a\");\r\n        hiddenElement.href = \"data:octet/stream;charset=utf-8,\" + encodeURI(maps);\r\n        hiddenElement.target = \"_blank\";\r\n        hiddenElement.download = this.name + \".tilemaps\";\r\n        hiddenElement.click();\r\n        hiddenElement.remove();\r\n    }\r\n\r\n    /**\r\n     * Imports the .tilemaps file\r\n     * @param url of the .tilemaps file\r\n     */\r\n    public loadTileMaps(url: string): void {\r\n        const xhr = new XMLHttpRequest();\r\n        xhr.open(\"GET\", url);\r\n\r\n        const _lc = this.options.layerCount || 0;\r\n\r\n        xhr.onload = () => {\r\n            const data = xhr.response.split(\"\\n\\r\");\r\n            for (let i = 0; i < _lc; i++) {\r\n                const d = data[i].split(\",\").map(Number);\r\n                const t = this._createTileBuffer(d);\r\n                this._tileMaps[i].dispose();\r\n                this._tileMaps[i] = t;\r\n            }\r\n            this._material.setTextureArray(\"tileMap\", this._tileMaps);\r\n        };\r\n        xhr.send();\r\n    }\r\n\r\n    /**\r\n     * Release associated resources\r\n     */\r\n    public dispose(): void {\r\n        this._output.dispose();\r\n        this._material.dispose();\r\n        this._animationMap.dispose();\r\n        for (const tm of this._tileMaps) {\r\n            tm.dispose();\r\n        }\r\n        this._frameMap.dispose();\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\n\nconst name = \"spriteMapPixelShader\";\nconst shader = `#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\n#define TEXTUREFUNC(s,c,l) texture2DLodEXT(s,c,l)\n#else\n#define TEXTUREFUNC(s,c,b) texture2D(s,c,b)\n#endif\nprecision highp float;varying vec3 vPosition;varying vec2 vUV;varying vec2 tUV;uniform float time;uniform float spriteCount;uniform sampler2D spriteSheet;uniform vec2 spriteMapSize;uniform vec2 outputSize;uniform vec2 stageSize;uniform sampler2D frameMap;uniform sampler2D tileMaps[LAYERS];uniform sampler2D animationMap;uniform vec3 colorMul;\n#include<fogFragmentDeclaration>\n#include<logDepthDeclaration>\nfloat mt;const float fdStep=1.0*0.25;const float aFrameSteps=MAX_ANIMATION_FRAMES==0.0 ? 0.0 : 1.0/MAX_ANIMATION_FRAMES;mat4 getFrameData(float frameID) {float fX=frameID/spriteCount;return mat4(\nTEXTUREFUNC(frameMap,vec2(fX,0.0),0.0),\nTEXTUREFUNC(frameMap,vec2(fX,fdStep*1.0),0.0),\nTEXTUREFUNC(frameMap,vec2(fX,fdStep*2.0),0.0),\nvec4(0.0)\n);}\nvoid main() {vec4 color=vec4(0.0);vec2 tileUV=fract(tUV);vec2 tileID=floor(tUV);vec2 sheetUnits=1.0/spriteMapSize;float spriteUnits=1.0/spriteCount;vec2 stageUnits=1.0/stageSize;for(int i=0; i<LAYERS; i++) {float frameID;\n#define LAYER_ID_SWITCH\nvec4 animationData=TEXTUREFUNC(animationMap,vec2((frameID+0.5)/spriteCount,0.0),0.0);if(animationData.y>0.0) {mt=mod(time*animationData.z,1.0);for(float f=0.0; f<MAX_ANIMATION_FRAMES; f++) {if(animationData.y>mt) {frameID=animationData.x;break;}\nanimationData=TEXTUREFUNC(animationMap,vec2((frameID+0.5)/spriteCount,aFrameSteps*f),0.0);}}\nmat4 frameData=getFrameData(frameID+0.5);vec2 frameSize=(frameData[0].zw)/spriteMapSize;vec2 offset=frameData[0].xy*sheetUnits;vec2 ratio=frameData[2].xy/frameData[0].zw;\n#ifdef FR_CW\nif (frameData[2].z==1.0) {tileUV.xy=tileUV.yx;} else {tileUV.xy=fract(tUV).xy;}\n#ifdef FLIPU\ntileUV.y=1.0-tileUV.y;\n#endif\n#else\nif (frameData[2].z==1.0) {\n#ifdef FLIPU\ntileUV.y=1.0-tileUV.y;\n#endif\ntileUV.xy=tileUV.yx;} else {tileUV.xy=fract(tUV).xy;\n#ifdef FLIPU\ntileUV.y=1.0-tileUV.y;\n#endif\n}\n#endif\nvec4 nc=TEXTUREFUNC(spriteSheet,tileUV*frameSize+offset,0.0);if (i==0) {color=nc;} else {float alpha=min(color.a+nc.a,1.0);vec3 mixed=mix(color.xyz,nc.xyz,nc.a);color=vec4(mixed,alpha);}}\ncolor.xyz*=colorMul;\n#include<logDepthFragment>\n#include<fogFragment>\ngl_FragColor=color;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [fogFragmentDeclaration, logDepthDeclaration, logDepthFragment, fogFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const spriteMapPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"spriteMapVertexShader\";\nconst shader = `precision highp float;attribute vec3 position;attribute vec3 normal;attribute vec2 uv;varying vec3 vPosition;varying vec2 vUV;varying vec2 tUV;uniform float time;uniform mat4 world;uniform mat4 view;uniform mat4 projection;uniform vec2 stageSize;uniform float stageScale;\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\nvoid main() {vec4 p=vec4( position,1. );vPosition=p.xyz;vUV=uv;tUV=uv*stageSize; \nvec3 viewPos=(view*world*p).xyz; \ngl_Position=projection*vec4(viewPos,1.0); \n#ifdef FOG\nvFogDistance=viewPos;\n#endif\n#include<logDepthVertex>\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [fogVertexDeclaration, logDepthDeclaration, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const spriteMapVertexShader = { name, shader };\n","import { type SpriteManagerOptions, SpriteManager } from \"./spriteManager\";\r\nimport { type Scene } from \"../scene\";\r\nimport { Texture } from \"../Materials/Textures/texture.pure\";\r\n\r\n/**\r\n * Class used to manage multiple sprites of different sizes on the same spritesheet\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/sprites\r\n */\r\n\r\nexport class SpritePackedManager extends SpriteManager {\r\n    /**\r\n     * Creates a new sprite manager from a packed sprite sheet\r\n     * @param name defines the manager's name\r\n     * @param imgUrl defines the sprite sheet url\r\n     * @param capacity defines the maximum allowed number of sprites\r\n     * @param scene defines the hosting scene\r\n     * @param spriteJSON null otherwise a JSON object defining sprite sheet data\r\n     * @param epsilon defines the epsilon value to align texture (0.01 by default)\r\n     * @param samplingMode defines the sampling mode to use with spritesheet\r\n     * @param fromPacked set to true; do not alter\r\n     * @param options options for the sprite manager\r\n     */\r\n\r\n    constructor(\r\n        /** defines the packed manager's name */\r\n        public override name: string,\r\n        imgUrl: string,\r\n        capacity: number,\r\n        scene: Scene,\r\n        spriteJSON: string | null = null,\r\n        epsilon: number = 0.01,\r\n        samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n        options?: SpriteManagerOptions\r\n    ) {\r\n        //the cellSize parameter is not used when built from JSON which provides individual cell data, defaults to 64 if JSON load fails\r\n        super(name, imgUrl, capacity, 64, scene, epsilon, samplingMode, true, spriteJSON, options);\r\n    }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { imageProcessingCompatibility } from \"./ShadersInclude/imageProcessingCompatibility\";\nimport { geometryRenderingFragment } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"spritesPixelShader\";\nconst shader = `#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\nuniform bool alphaTest;varying vec4 vColor;\n#ifdef PREPASS\nuniform float geometryZeroAlphaDiscard;\n#ifdef PREPASS_POSITION\nvarying vec3 vPositionW;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vNormalW;\n#endif\n#endif\nvarying vec2 vUV;uniform sampler2D diffuseSampler;\n#include<fogFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#ifdef PIXEL_PERFECT\nvec2 uvPixelPerfect(vec2 uv) {vec2 res=vec2(textureSize(diffuseSampler,0));uv=uv*res;vec2 seam=floor(uv+0.5);uv=seam+clamp((uv-seam)/fwidth(uv),-0.5,0.5);return uv/res;}\n#endif\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#ifdef PIXEL_PERFECT\nvec2 uv=uvPixelPerfect(vUV);\n#else\nvec2 uv=vUV;\n#endif\nvec4 color=texture2D(diffuseSampler,uv);float fAlphaTest=float(alphaTest);if (fAlphaTest != 0.)\n{if (color.a<0.95)\ndiscard;}\ncolor*=vColor;\n#ifdef PREPASS\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvec3 geometryAlbedo=toLinearSpace(color.rgb);\n#endif\nif (fAlphaTest==0.0 && color.a==0.0 && geometryZeroAlphaDiscard>0.0) {discard;}\n#endif\n#include<logDepthFragment>\n#include<fogFragment>\ngl_FragColor=color;\n#include<imageProcessingCompatibility>\n#ifdef PREPASS\nvec4 geometryColor=gl_FragColor;\n#ifdef PREPASS_POSITION\nvec3 geometryPositionW=vPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvec3 geometryPositionL=vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nfloat geometryViewDepth=vViewPos.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfloat geometryNormalizedViewDepth=vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvec3 geometryNormalV=vNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvec3 geometryNormalW=vNormalW;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvec4 geometryCurrentPosition=vCurrentPosition;vec4 geometryPreviousPosition=vPreviousPosition;\n#endif\n#include<geometryRenderingFragment>\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [objectIdFunctions, prePassDeclaration, fogFragmentDeclaration, logDepthDeclaration, helperFunctions, logDepthFragment, fogFragment, imageProcessingCompatibility, geometryRenderingFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const spritesPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"spritesVertexShader\";\nconst shader = `attribute vec4 position;attribute vec2 options;attribute vec2 offsets;attribute vec2 inverts;attribute vec4 cellInfo;attribute vec4 color;uniform mat4 view;uniform mat4 projection;\n#ifdef PREPASS\n#if defined(PREPASS_POSITION) || defined(PREPASS_WORLD_NORMAL)\nuniform mat4 invView;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nuniform vec2 cameraInfo;\n#endif\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nuniform float spriteNormalSign;\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nattribute vec4 previousPosition;attribute vec2 previousOptions;uniform mat4 previousView;uniform mat4 previousProjection;\n#endif\nvarying vec2 vUV;varying vec4 vColor;\n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvarying vec3 vPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vec3 vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vec3 vViewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying float vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vNormalW;\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvarying vec4 vCurrentPosition;varying vec4 vPreviousPosition;\n#endif\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 viewPos=(view*vec4(position.xyz,1.0)).xyz; \nvec2 cornerPos;float angle=position.w;vec2 size=vec2(options.x,options.y);vec2 offset=offsets.xy;cornerPos=vec2(offset.x-0.5,offset.y -0.5)*size;vec3 rotatedCorner;rotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.z=0.;viewPos+=rotatedCorner;gl_Position=projection*vec4(viewPos,1.0); \n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvec4 worldPos=invView*vec4(viewPos,1.0);vPositionW=worldPos.xyz/worldPos.w;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvPosition=rotatedCorner;\n#endif\n#ifdef PREPASS_DEPTH\nvViewPos=viewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvNormViewDepth=(viewPos.z-cameraInfo.x)/(cameraInfo.y-cameraInfo.x);\n#endif\n#ifdef PREPASS_NORMAL\nvNormalV=vec3(0.0,0.0,spriteNormalSign);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvNormalW=normalize((invView*vec4(0.0,0.0,spriteNormalSign,0.0)).xyz);\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvec3 previousViewPos=(previousView*vec4(previousPosition.xyz,1.0)).xyz;vec2 previousCornerPos=vec2(offset.x-0.5,offset.y-0.5)*previousOptions;vec3 previousRotatedCorner;previousRotatedCorner.x=previousCornerPos.x*cos(previousPosition.w)-previousCornerPos.y*sin(previousPosition.w);previousRotatedCorner.y=previousCornerPos.x*sin(previousPosition.w)+previousCornerPos.y*cos(previousPosition.w);previousRotatedCorner.z=0.0;previousViewPos+=previousRotatedCorner;vCurrentPosition=gl_Position;vPreviousPosition=previousProjection*vec4(previousViewPos,1.0);\n#endif\nvColor=color;vec2 uvOffset=vec2(abs(offset.x-inverts.x),abs(1.0-offset.y-inverts.y));vec2 uvPlace=cellInfo.xy;vec2 uvSize=cellInfo.zw;vUV.x=uvPlace.x+uvSize.x*uvOffset.x;vUV.y=uvPlace.y+uvSize.y*uvOffset.y;\n#ifdef FOG\nvFogDistance=viewPos;\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [fogVertexDeclaration, logDepthDeclaration, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const spritesVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { imageProcessingCompatibilityWGSL } from \"./ShadersInclude/imageProcessingCompatibility\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { geometryRenderingFragmentWGSL } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"spritesPixelShader\";\nconst shader = `uniform alphaTest: i32;\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\nvarying vColor: vec4f;\n#ifdef PREPASS\nuniform geometryZeroAlphaDiscard: f32;\n#ifdef PREPASS_POSITION\nvarying vPositionW: vec3f;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vNormalV: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vNormalW: vec3f;\n#endif\n#endif\nvarying vUV: vec2f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#include<fogFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#ifdef PIXEL_PERFECT\nfn uvPixelPerfect(uv: vec2f)->vec2f {var res: vec2f= vec2f(textureDimensions(diffuseSampler,0));var uvTemp=uv*res;var seam: vec2f=floor(uvTemp+0.5);uvTemp=seam+clamp((uvTemp-seam)/fwidth(uvTemp),vec2f(-0.5),vec2f(0.5));return uvTemp/res;}\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#ifdef PIXEL_PERFECT\nvar uv: vec2f=uvPixelPerfect(input.vUV);\n#else\nvar uv: vec2f=input.vUV;\n#endif\nvar color: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,uv);var fAlphaTest: f32= f32(uniforms.alphaTest);if (fAlphaTest != 0.)\n{if (color.a<0.95) {discard;}}\ncolor*=input.vColor;\n#ifdef PREPASS\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvar geometryAlbedo: vec3f=toLinearSpaceVec3(color.rgb);\n#endif\nif (fAlphaTest==0.0 && color.a==0.0 && uniforms.geometryZeroAlphaDiscard>0.0) {discard;}\n#endif\n#include<logDepthFragment>\n#include<fogFragment>\n#ifdef PREPASS\n#include<imageProcessingCompatibility>(fragmentOutputs.color,color)\nvar geometryColor: vec4f=color;\n#ifdef PREPASS_POSITION\nvar geometryPositionW: vec3f=input.vPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvar geometryPositionL: vec3f=input.vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nvar geometryViewDepth: f32=input.vViewPos.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvar geometryNormalizedViewDepth: f32=input.vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvar geometryNormalV: vec3f=input.vNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvar geometryNormalW: vec3f=input.vNormalW;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvar geometryCurrentPosition: vec4f=input.vCurrentPosition;var geometryPreviousPosition: vec4f=input.vPreviousPosition;\n#endif\n#include<geometryRenderingFragment>\n#else\nfragmentOutputs.color=color;\n#include<imageProcessingCompatibility>\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [objectIdFunctionsWGSL, prePassDeclarationWGSL, fogFragmentDeclarationWGSL, logDepthDeclarationWGSL, helperFunctionsWGSL, logDepthFragmentWGSL, fogFragmentWGSL, imageProcessingCompatibilityWGSL, meshBlendTagFragmentOutputWGSL, geometryRenderingFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const spritesPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"spritesVertexShader\";\nconst shader = `attribute position: vec4f;attribute options: vec2f;attribute offsets: vec2f;attribute inverts: vec2f;attribute cellInfo: vec4f;attribute color: vec4f;uniform view: mat4x4f;uniform projection: mat4x4f;\n#ifdef PREPASS\n#if defined(PREPASS_POSITION) || defined(PREPASS_WORLD_NORMAL)\nuniform invView: mat4x4f;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nuniform cameraInfo: vec2f;\n#endif\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nuniform spriteNormalSign: f32;\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nattribute previousPosition: vec4f;attribute previousOptions: vec2f;uniform previousView: mat4x4f;uniform previousProjection: mat4x4f;\n#endif\nvarying vUV: vec2f;varying vColor: vec4f;\n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvarying vPositionW: vec3f;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vPosition: vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vViewPos: vec3f;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vNormViewDepth: f32;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vNormalV: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vNormalW: vec3f;\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvarying vCurrentPosition: vec4f;varying vPreviousPosition: vec4f;\n#endif\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvar viewPos: vec3f=(uniforms.view* vec4f(vertexInputs.position.xyz,1.0)).xyz; \nvar cornerPos: vec2f;var angle: f32=vertexInputs.position.w;var size: vec2f= vec2f(vertexInputs.options.x,vertexInputs.options.y);var offset: vec2f=vertexInputs.offsets.xy;cornerPos= vec2f(offset.x-0.5,offset.y -0.5)*size;var rotatedCorner: vec3f;rotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);rotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);rotatedCorner.z=0.;viewPos+=rotatedCorner;vertexOutputs.position=uniforms.projection*vec4f(viewPos,1.0); \n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvar worldPos: vec4f=uniforms.invView*vec4f(viewPos,1.0);vertexOutputs.vPositionW=worldPos.xyz/worldPos.w;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvertexOutputs.vPosition=rotatedCorner;\n#endif\n#ifdef PREPASS_DEPTH\nvertexOutputs.vViewPos=viewPos;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvertexOutputs.vNormViewDepth=(viewPos.z-uniforms.cameraInfo.x)/(uniforms.cameraInfo.y-uniforms.cameraInfo.x);\n#endif\n#ifdef PREPASS_NORMAL\nvertexOutputs.vNormalV=vec3f(0.0,0.0,uniforms.spriteNormalSign);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvertexOutputs.vNormalW=normalize((uniforms.invView*vec4f(0.0,0.0,uniforms.spriteNormalSign,0.0)).xyz);\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvar previousViewPos: vec3f=(uniforms.previousView*vec4f(vertexInputs.previousPosition.xyz,1.0)).xyz;var previousCornerPos: vec2f=vec2f(offset.x-0.5,offset.y-0.5)*vertexInputs.previousOptions;var previousRotatedCorner: vec3f;previousRotatedCorner.x=previousCornerPos.x*cos(vertexInputs.previousPosition.w)-previousCornerPos.y*sin(vertexInputs.previousPosition.w);previousRotatedCorner.y=previousCornerPos.x*sin(vertexInputs.previousPosition.w)+previousCornerPos.y*cos(vertexInputs.previousPosition.w);previousRotatedCorner.z=0.0;previousViewPos+=previousRotatedCorner;vertexOutputs.vCurrentPosition=vertexOutputs.position;vertexOutputs.vPreviousPosition=uniforms.previousProjection*vec4f(previousViewPos,1.0);\n#endif\nvertexOutputs.vColor=vertexInputs.color;var uvOffset: vec2f= vec2f(abs(offset.x-vertexInputs.inverts.x),abs(1.0-offset.y-vertexInputs.inverts.y));var uvPlace: vec2f=vertexInputs.cellInfo.xy;var uvSize: vec2f=vertexInputs.cellInfo.zw;vertexOutputs.vUV.x=uvPlace.x+uvSize.x*uvOffset.x;vertexOutputs.vUV.y=uvPlace.y+uvSize.y*uvOffset.y;\n#ifdef FOG\nvertexOutputs.vFogDistance=viewPos;\n#endif\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [fogVertexDeclarationWGSL, logDepthDeclarationWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const spritesVertexShaderWGSL = { name, shader };\n","import { type Nullable } from \"../types\";\r\nimport { type IDisposable } from \"../scene\";\r\n\r\n/**\r\n * States of the webXR experience\r\n */\r\nexport const enum WebXRState {\r\n    /**\r\n     * Transitioning to being in XR mode\r\n     */\r\n    ENTERING_XR,\r\n    /**\r\n     * Transitioning to non XR mode\r\n     */\r\n    EXITING_XR,\r\n    /**\r\n     * In XR mode and presenting\r\n     */\r\n    IN_XR,\r\n    /**\r\n     * Not entered XR mode\r\n     */\r\n    NOT_IN_XR,\r\n}\r\n\r\n/**\r\n * The state of the XR camera's tracking\r\n */\r\nexport const enum WebXRTrackingState {\r\n    /**\r\n     * No transformation received, device is not being tracked\r\n     */\r\n    NOT_TRACKING,\r\n    /**\r\n     * Tracking lost - using emulated position\r\n     */\r\n    TRACKING_LOST,\r\n    /**\r\n     * Transformation tracking works normally\r\n     */\r\n    TRACKING,\r\n}\r\n\r\n/**\r\n * Abstraction of the XR render target.\r\n * The type parameters default to the WebGL context/layer types, so `WebXRRenderTarget`\r\n * used without type arguments keeps the exact same shape as before. A non-WebGL backend\r\n * (e.g. a future WebGPU/XRGPUBinding target) can specialize the context and layer types.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface WebXRRenderTarget<TContext = WebGLRenderingContext, TLayer extends XRLayer = XRWebGLLayer> extends IDisposable {\r\n    /**\r\n     * xrpresent context of the canvas which can be used to display/mirror xr content\r\n     */\r\n    canvasContext: TContext;\r\n\r\n    /**\r\n     * xr layer for the canvas\r\n     */\r\n    xrLayer: Nullable<TLayer>;\r\n\r\n    /**\r\n     * Initializes an XR layer to be used as the session's baseLayer.\r\n     * @param xrSession xr session\r\n     * @returns a promise that will resolve once the XR Layer has been created\r\n     */\r\n    initializeXRLayerAsync(xrSession: XRSession): Promise<TLayer>;\r\n}\r\n","import { type IWebXRFeature, WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { Vector3, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\n\r\n// the plugin is registered at the end of the file\r\n\r\n/**\r\n * An interface for all Hit test features\r\n */\r\nexport interface IWebXRHitTestFeature<T extends IWebXRLegacyHitResult> extends IWebXRFeature {\r\n    /**\r\n     * Triggered when new babylon (transformed) hit test results are available\r\n     */\r\n    onHitTestResultObservable: Observable<T[]>;\r\n}\r\n\r\n/**\r\n * Options used for hit testing\r\n */\r\nexport interface IWebXRLegacyHitTestOptions {\r\n    /**\r\n     * Only test when user interacted with the scene. Default - hit test every frame\r\n     */\r\n    testOnPointerDownOnly?: boolean;\r\n    /**\r\n     * The node to use to transform the local results to world coordinates\r\n     */\r\n    worldParentNode?: TransformNode;\r\n}\r\n\r\n/**\r\n * Interface defining the babylon result of raycasting/hit-test\r\n */\r\nexport interface IWebXRLegacyHitResult {\r\n    /**\r\n     * Transformation matrix that can be applied to a node that will put it in the hit point location\r\n     */\r\n    transformationMatrix: Matrix;\r\n    /**\r\n     * The native hit test result\r\n     */\r\n    xrHitResult: XRHitResult | XRHitTestResult;\r\n}\r\n\r\n/**\r\n * The currently-working hit-test module.\r\n * Hit test (or Ray-casting) is used to interact with the real world.\r\n * For further information read here - https://github.com/immersive-web/hit-test\r\n */\r\nexport class WebXRHitTestLegacy extends WebXRAbstractFeature implements IWebXRHitTestFeature<IWebXRLegacyHitResult> {\r\n    // in XR space z-forward is negative\r\n    private _direction = new Vector3(0, 0, -1);\r\n    private _mat = new Matrix();\r\n    private _onSelectEnabled = false;\r\n    private _origin = new Vector3(0, 0, 0);\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.HIT_TEST;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Populated with the last native XR Hit Results\r\n     */\r\n    public lastNativeXRHitResults: XRHitResult[] = [];\r\n    /**\r\n     * Triggered when new babylon (transformed) hit test results are available\r\n     */\r\n    public onHitTestResultObservable: Observable<IWebXRLegacyHitResult[]> = new Observable();\r\n\r\n    /**\r\n     * Creates a new instance of the (legacy version) hit test feature\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param options options to use when constructing this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * [Empty Object] options to use when constructing this feature\r\n         */\r\n        public readonly options: IWebXRLegacyHitTestOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"hit-test\";\r\n        Tools.Warn(\"A newer version of this plugin is available\");\r\n    }\r\n\r\n    /**\r\n     * execute a hit test with an XR Ray\r\n     *\r\n     * @param xrSession a native xrSession that will execute this hit test\r\n     * @param xrRay the ray (position and direction) to use for ray-casting\r\n     * @param referenceSpace native XR reference space to use for the hit-test\r\n     * @param filter filter function that will filter the results\r\n     * @returns a promise that resolves with an array of native XR hit result in xr coordinates system\r\n     */\r\n    public static async XRHitTestWithRay(xrSession: XRSession, xrRay: XRRay, referenceSpace: XRReferenceSpace, filter?: (result: XRHitResult) => boolean): Promise<XRHitResult[]> {\r\n        const results = await xrSession.requestHitTest!(xrRay, referenceSpace);\r\n        const filterFunction = filter || ((result) => !!result.hitMatrix);\r\n        return results.filter(filterFunction);\r\n    }\r\n\r\n    /**\r\n     * Execute a hit test on the current running session using a select event returned from a transient input (such as touch)\r\n     * @param event the (select) event to use to select with\r\n     * @param referenceSpace the reference space to use for this hit test\r\n     * @returns a promise that resolves with an array of native XR hit result in xr coordinates system\r\n     */\r\n    public static async XRHitTestWithSelectEvent(event: XRInputSourceEvent, referenceSpace: XRReferenceSpace): Promise<XRHitResult[]> {\r\n        const targetRayPose = event.frame.getPose(event.inputSource.targetRaySpace, referenceSpace);\r\n        if (!targetRayPose) {\r\n            return [];\r\n        }\r\n        const targetRay = new XRRay(targetRayPose.transform);\r\n\r\n        return await this.XRHitTestWithRay(event.frame.session, targetRay, referenceSpace);\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n        if (this.options.testOnPointerDownOnly) {\r\n            this._xrSessionManager.session.addEventListener(\"select\", this._onSelect, false);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n        // disable select\r\n        this._onSelectEnabled = false;\r\n        this._xrSessionManager.session.removeEventListener(\"select\", this._onSelect);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this.onHitTestResultObservable.clear();\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        // make sure we do nothing if (async) not attached\r\n        if (!this.attached || this.options.testOnPointerDownOnly) {\r\n            return;\r\n        }\r\n        const pose = frame.getViewerPose(this._xrSessionManager.referenceSpace);\r\n        if (!pose) {\r\n            return;\r\n        }\r\n        Matrix.FromArrayToRef(pose.transform.matrix, 0, this._mat);\r\n        Vector3.TransformCoordinatesFromFloatsToRef(0, 0, 0, this._mat, this._origin);\r\n        Vector3.TransformCoordinatesFromFloatsToRef(0, 0, -1, this._mat, this._direction);\r\n        this._direction.subtractInPlace(this._origin);\r\n        this._direction.normalize();\r\n        const ray = new XRRay(\r\n            <DOMPointReadOnly>{ x: this._origin.x, y: this._origin.y, z: this._origin.z, w: 0 },\r\n            <DOMPointReadOnly>{ x: this._direction.x, y: this._direction.y, z: this._direction.z, w: 0 }\r\n        );\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        WebXRHitTestLegacy.XRHitTestWithRay(this._xrSessionManager.session, ray, this._xrSessionManager.referenceSpace).then(this._onHitTestResults);\r\n    }\r\n\r\n    private _onHitTestResults = (xrResults: XRHitResult[]) => {\r\n        const mats = xrResults.map((result) => {\r\n            const mat = Matrix.FromArray(result.hitMatrix);\r\n            if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                mat.toggleModelMatrixHandInPlace();\r\n            }\r\n            // if (this.options.coordinatesSpace === Space.WORLD) {\r\n            if (this.options.worldParentNode) {\r\n                mat.multiplyToRef(this.options.worldParentNode.getWorldMatrix(), mat);\r\n            }\r\n            return {\r\n                xrHitResult: result,\r\n                transformationMatrix: mat,\r\n            };\r\n        });\r\n\r\n        this.lastNativeXRHitResults = xrResults;\r\n        this.onHitTestResultObservable.notifyObservers(mats);\r\n    };\r\n\r\n    // can be done using pointerdown event, and xrSessionManager.currentFrame\r\n    private _onSelect = (event: XRInputSourceEvent) => {\r\n        if (!this._onSelectEnabled) {\r\n            return;\r\n        }\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        WebXRHitTestLegacy.XRHitTestWithSelectEvent(event, this._xrSessionManager.referenceSpace);\r\n    };\r\n}\r\n\r\n//register the plugin versions\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n    WebXRHitTestLegacy.Name,\r\n    (xrSessionManager, options) => {\r\n        return () => new WebXRHitTestLegacy(xrSessionManager, options);\r\n    },\r\n    WebXRHitTestLegacy.Version,\r\n    false\r\n);\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Matrix, Vector3, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type IWebXRHitResult } from \"./WebXRHitTest.pure\";\r\n\r\n/**\r\n * Configuration options of the anchor system\r\n */\r\nexport interface IWebXRAnchorSystemOptions {\r\n    /**\r\n     * a node that will be used to convert local to world coordinates\r\n     */\r\n    worldParentNode?: TransformNode;\r\n\r\n    /**\r\n     * If set to true a reference of the created anchors will be kept until the next session starts\r\n     * If not defined, anchors will be removed from the array when the feature is detached or the session ended.\r\n     */\r\n    doNotRemoveAnchorsOnSessionEnded?: boolean;\r\n\r\n    /**\r\n     * If set to true, all anchor arrays will be cleared when the session initializes\r\n     */\r\n    clearAnchorsOnSessionInit?: boolean;\r\n}\r\n\r\n/**\r\n * A babylon container for an XR Anchor\r\n */\r\nexport interface IWebXRAnchor {\r\n    /**\r\n     * A babylon-assigned ID for this anchor\r\n     */\r\n    id: number;\r\n    /**\r\n     * Transformation matrix to apply to an object attached to this anchor\r\n     */\r\n    transformationMatrix: Matrix;\r\n    /**\r\n     * The native anchor object\r\n     */\r\n    xrAnchor: XRAnchor;\r\n\r\n    /**\r\n     * The persistent handle associated with this anchor, if one was requested or the anchor was restored from one\r\n     */\r\n    persistentHandle?: string;\r\n\r\n    /**\r\n     * if defined, this object will be constantly updated by the anchor's position and rotation\r\n     */\r\n    attachedNode?: TransformNode;\r\n\r\n    /**\r\n     * Remove this anchor from the scene\r\n     */\r\n    remove(): void;\r\n\r\n    /**\r\n     * @internal - set to true when the anchor was removed\r\n     */\r\n    _removed: boolean;\r\n}\r\n\r\n/**\r\n * An internal interface for a future (promise based) anchor\r\n */\r\ninterface IWebXRFutureAnchor {\r\n    /**\r\n     * The native anchor\r\n     */\r\n    nativeAnchor?: XRAnchor;\r\n    /**\r\n     * Was this request submitted to the xr frame?\r\n     */\r\n    submitted: boolean;\r\n    /**\r\n     * Was this promise resolved already?\r\n     */\r\n    resolved: boolean;\r\n    /**\r\n     * A resolve function\r\n     */\r\n    resolve: (xrAnchor: IWebXRAnchor) => void;\r\n    /**\r\n     * A reject function\r\n     */\r\n    reject: (reason?: unknown) => void;\r\n    /**\r\n     * The XR Transformation of the future anchor\r\n     */\r\n    xrTransformation?: XRRigidTransform;\r\n    /**\r\n     * The persistent handle used to restore this anchor\r\n     */\r\n    persistentHandle?: string;\r\n}\r\n\r\nlet AnchorIdProvider = 0;\r\n\r\n/**\r\n * An implementation of the anchor system for WebXR.\r\n * For further information see https://github.com/immersive-web/anchors/\r\n */\r\nexport class WebXRAnchorSystem extends WebXRAbstractFeature {\r\n    private _lastFrameDetected: XRAnchorSet = new Set();\r\n\r\n    private _trackedAnchors: Array<IWebXRAnchor> = [];\r\n\r\n    private _referenceSpaceForFrameAnchors: XRReferenceSpace;\r\n\r\n    private _futureAnchors: IWebXRFutureAnchor[] = [];\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.ANCHOR_SYSTEM;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Observers registered here will be executed when a new anchor was added to the session\r\n     */\r\n    public onAnchorAddedObservable: Observable<IWebXRAnchor> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when an anchor was removed from the session\r\n     */\r\n    public onAnchorRemovedObservable: Observable<IWebXRAnchor> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when an existing anchor updates\r\n     * This can execute N times every frame\r\n     */\r\n    public onAnchorUpdatedObservable: Observable<IWebXRAnchor> = new Observable();\r\n\r\n    /**\r\n     * Set the reference space to use for anchor creation, when not using a hit test.\r\n     * Will default to the session's reference space if not defined\r\n     */\r\n    public set referenceSpaceForFrameAnchors(referenceSpace: XRReferenceSpace) {\r\n        this._referenceSpaceForFrameAnchors = referenceSpace;\r\n    }\r\n\r\n    /**\r\n     * constructs a new anchor system\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param _options configuration object for this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private _options: IWebXRAnchorSystemOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"anchors\";\r\n\r\n        if (this._options.clearAnchorsOnSessionInit) {\r\n            this._xrSessionManager.onXRSessionInit.add(() => {\r\n                this._rejectPendingPersistentAnchors(\"Persistent anchor restoration was interrupted before tracking began\");\r\n                this._trackedAnchors.length = 0;\r\n                this._futureAnchors.length = 0;\r\n                this._lastFrameDetected.clear();\r\n            });\r\n        }\r\n    }\r\n\r\n    private _tmpVector = new Vector3();\r\n    private _tmpQuaternion = new Quaternion();\r\n\r\n    private _populateTmpTransformation(position: Vector3, rotationQuaternion: Quaternion) {\r\n        this._tmpVector.copyFrom(position);\r\n        this._tmpQuaternion.copyFrom(rotationQuaternion);\r\n        if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n            this._tmpVector.z *= -1;\r\n            this._tmpQuaternion.z *= -1;\r\n            this._tmpQuaternion.w *= -1;\r\n        }\r\n        return {\r\n            position: this._tmpVector,\r\n            rotationQuaternion: this._tmpQuaternion,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Create a new anchor point using a hit test result at a specific point in the scene\r\n     * An anchor is tracked only after it is added to the trackerAnchors in xrFrame. The promise returned here does not yet guaranty that.\r\n     * Use onAnchorAddedObservable to get newly added anchors if you require tracking guaranty.\r\n     *\r\n     * @param hitTestResult The hit test result to use for this anchor creation\r\n     * @param position an optional position offset for this anchor\r\n     * @param rotationQuaternion an optional rotation offset for this anchor\r\n     * @returns A promise that fulfills when babylon has created the corresponding WebXRAnchor object and tracking has begun\r\n     */\r\n    public async addAnchorPointUsingHitTestResultAsync(\r\n        hitTestResult: IWebXRHitResult,\r\n        position: Vector3 = new Vector3(),\r\n        rotationQuaternion: Quaternion = new Quaternion()\r\n    ): Promise<IWebXRAnchor> {\r\n        // convert to XR space (right handed) if needed\r\n        this._populateTmpTransformation(position, rotationQuaternion);\r\n        // the matrix that we'll use\r\n        const m = new XRRigidTransform(\r\n            { x: this._tmpVector.x, y: this._tmpVector.y, z: this._tmpVector.z },\r\n            { x: this._tmpQuaternion.x, y: this._tmpQuaternion.y, z: this._tmpQuaternion.z, w: this._tmpQuaternion.w }\r\n        );\r\n        if (!hitTestResult.xrHitResult.createAnchor) {\r\n            this.detach();\r\n            throw new Error(\"Anchors not enabled in this environment/browser\");\r\n        } else {\r\n            try {\r\n                const nativeAnchor = await hitTestResult.xrHitResult.createAnchor(m);\r\n                return await new Promise<IWebXRAnchor>((resolve, reject) => {\r\n                    this._futureAnchors.push({\r\n                        nativeAnchor,\r\n                        resolved: false,\r\n                        submitted: true,\r\n                        xrTransformation: m,\r\n                        resolve,\r\n                        reject,\r\n                    });\r\n                });\r\n            } catch (error) {\r\n                throw new Error(String(error), { cause: error });\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Add a new anchor at a specific position and rotation\r\n     * This function will add a new anchor per default in the next available frame. Unless forced, the createAnchor function\r\n     * will be called in the next xrFrame loop to make sure that the anchor can be created correctly.\r\n     * An anchor is tracked only after it is added to the trackerAnchors in xrFrame. The promise returned here does not yet guaranty that.\r\n     * Use onAnchorAddedObservable to get newly added anchors if you require tracking guaranty.\r\n     *\r\n     * @param position the position in which to add an anchor\r\n     * @param rotationQuaternion an optional rotation for the anchor transformation\r\n     * @param forceCreateInCurrentFrame force the creation of this anchor in the current frame. Must be called inside xrFrame loop!\r\n     * @returns A promise that fulfills when babylon has created the corresponding WebXRAnchor object and tracking has begun\r\n     */\r\n    public async addAnchorAtPositionAndRotationAsync(\r\n        position: Vector3,\r\n        rotationQuaternion: Quaternion = new Quaternion(),\r\n        forceCreateInCurrentFrame = false\r\n    ): Promise<IWebXRAnchor> {\r\n        // convert to XR space (right handed) if needed\r\n        this._populateTmpTransformation(position, rotationQuaternion);\r\n        // the matrix that we'll use\r\n        const xrTransformation = new XRRigidTransform(\r\n            { x: this._tmpVector.x, y: this._tmpVector.y, z: this._tmpVector.z },\r\n            { x: this._tmpQuaternion.x, y: this._tmpQuaternion.y, z: this._tmpQuaternion.z, w: this._tmpQuaternion.w }\r\n        );\r\n        const xrAnchor =\r\n            forceCreateInCurrentFrame && this.attached && this._xrSessionManager.currentFrame\r\n                ? await this._createAnchorAtTransformationAsync(xrTransformation, this._xrSessionManager.currentFrame)\r\n                : undefined;\r\n        // add the transformation to the future anchors list\r\n        return await new Promise<IWebXRAnchor>((resolve, reject) => {\r\n            this._futureAnchors.push({\r\n                nativeAnchor: xrAnchor,\r\n                resolved: false,\r\n                submitted: false,\r\n                xrTransformation,\r\n                resolve,\r\n                reject,\r\n            });\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Get the list of anchors currently being tracked by the system\r\n     */\r\n    public get anchors(): IWebXRAnchor[] {\r\n        return this._trackedAnchors;\r\n    }\r\n\r\n    /**\r\n     * Whether the current XR session exposes all session-level persistent anchor APIs\r\n     * @returns Whether all session-level persistent anchor APIs are supported\r\n     */\r\n    public get isPersistentAnchorSupported(): boolean {\r\n        const session = this._xrSessionManager.session;\r\n        return (\r\n            !!session && session.persistentAnchors !== undefined && typeof session.restorePersistentAnchor === \"function\" && typeof session.deletePersistentAnchor === \"function\"\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Get the persistent anchor handles known to the current XR session\r\n     * @returns The persistent anchor handles\r\n     * @throws If persistent anchor enumeration is not supported by the current session\r\n     */\r\n    public get persistentAnchors(): ReadonlyArray<string> {\r\n        const persistentAnchors = this._xrSessionManager.session?.persistentAnchors;\r\n        if (persistentAnchors === undefined) {\r\n            throw new Error(\"Persistent anchor enumeration is not supported in this environment/browser\");\r\n        }\r\n        return persistentAnchors;\r\n    }\r\n\r\n    /**\r\n     * Request a persistent handle for a tracked anchor\r\n     * @param anchor The Babylon anchor to persist\r\n     * @returns A promise that resolves with the persistent handle\r\n     * @throws If requesting persistent handles is not supported by the native anchor\r\n     */\r\n    public async requestPersistentHandleAsync(anchor: IWebXRAnchor): Promise<string> {\r\n        const requestPersistentHandle = anchor.xrAnchor.requestPersistentHandle;\r\n        if (!requestPersistentHandle) {\r\n            throw new Error(\"Requesting persistent anchor handles is not supported in this environment/browser\");\r\n        }\r\n        const handle = await requestPersistentHandle.call(anchor.xrAnchor);\r\n        this._setPersistentHandle(anchor, handle);\r\n        return handle;\r\n    }\r\n\r\n    /**\r\n     * Restore a persistent anchor into the Babylon anchor lifecycle\r\n     * @param handle The persistent anchor handle to restore\r\n     * @returns A promise that resolves after the restored anchor is tracked by an XR frame\r\n     * @throws If restoring persistent anchors is not supported by the current session\r\n     */\r\n    public async restorePersistentAnchorAsync(handle: string): Promise<IWebXRAnchor> {\r\n        if (!this.attached) {\r\n            throw new Error(\"Restoring persistent anchors requires the anchor system to be attached\");\r\n        }\r\n\r\n        const session = this._xrSessionManager.session;\r\n        const restorePersistentAnchor = session?.restorePersistentAnchor;\r\n        if (!restorePersistentAnchor) {\r\n            throw new Error(\"Restoring persistent anchors is not supported in this environment/browser\");\r\n        }\r\n\r\n        const nativeAnchor = await restorePersistentAnchor.call(session, handle);\r\n        if (!this.attached || this._xrSessionManager.session !== session) {\r\n            nativeAnchor.delete();\r\n            throw new Error(\"Persistent anchor restoration was interrupted before tracking began\");\r\n        }\r\n        const existingAnchorIndex = this._findIndexInAnchorArray(nativeAnchor);\r\n        if (existingAnchorIndex !== -1) {\r\n            const existingAnchor = this._trackedAnchors[existingAnchorIndex];\r\n            existingAnchor.persistentHandle = handle;\r\n            return existingAnchor;\r\n        }\r\n\r\n        return await new Promise<IWebXRAnchor>((resolve, reject) => {\r\n            this._futureAnchors.push({\r\n                nativeAnchor,\r\n                resolved: false,\r\n                submitted: true,\r\n                persistentHandle: handle,\r\n                resolve,\r\n                reject,\r\n            });\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Restore all persistent anchors known to the current XR session\r\n     * @returns A promise that resolves after all restored anchors are tracked by an XR frame\r\n     * @throws If persistent anchor enumeration or restoration is not supported by the current session\r\n     */\r\n    public async restorePersistentAnchorsAsync(): Promise<IWebXRAnchor[]> {\r\n        return await Promise.all(this.persistentAnchors.map(async (handle) => await this.restorePersistentAnchorAsync(handle)));\r\n    }\r\n\r\n    /**\r\n     * Delete a persistent anchor from native storage\r\n     * @param handle The persistent anchor handle to delete\r\n     * @returns A promise that resolves after native persistent storage is deleted\r\n     * @throws If deleting persistent anchors is not supported by the current session\r\n     */\r\n    public async deletePersistentAnchorAsync(handle: string): Promise<void> {\r\n        const session = this._xrSessionManager.session;\r\n        const deletePersistentAnchor = session?.deletePersistentAnchor;\r\n        if (!deletePersistentAnchor) {\r\n            throw new Error(\"Deleting persistent anchors is not supported in this environment/browser\");\r\n        }\r\n\r\n        await deletePersistentAnchor.call(session, handle);\r\n        for (const anchor of this._trackedAnchors) {\r\n            if (anchor.persistentHandle === handle) {\r\n                anchor._removed = true;\r\n            }\r\n        }\r\n        for (const futureAnchor of this._futureAnchors) {\r\n            if (!futureAnchor.resolved && futureAnchor.persistentHandle === handle) {\r\n                futureAnchor.resolved = true;\r\n                futureAnchor.reject(new Error(\"The persistent anchor was deleted before tracking began\"));\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        this._rejectPendingPersistentAnchors(\"Persistent anchor restoration was interrupted before tracking began\");\r\n\r\n        if (!this._options.doNotRemoveAnchorsOnSessionEnded) {\r\n            while (this._trackedAnchors.length) {\r\n                const toRemove = this._trackedAnchors.pop();\r\n                if (toRemove && !toRemove._removed) {\r\n                    // as the xr frame loop is removed, we need to notify manually\r\n                    this.onAnchorRemovedObservable.notifyObservers(toRemove);\r\n                    toRemove._removed = true;\r\n                    // no need to call the remove fn as the anchor is already removed from the session\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this._futureAnchors.length = 0;\r\n        this.onAnchorAddedObservable.clear();\r\n        this.onAnchorRemovedObservable.clear();\r\n        this.onAnchorUpdatedObservable.clear();\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        if (!this.attached || !frame) {\r\n            return;\r\n        }\r\n\r\n        const trackedAnchors = frame.trackedAnchors;\r\n        if (trackedAnchors) {\r\n            for (const anchor of this._trackedAnchors) {\r\n                if (!anchor._removed) {\r\n                    continue;\r\n                }\r\n                const index = this._trackedAnchors.indexOf(anchor);\r\n                this._trackedAnchors.splice(index, 1);\r\n                anchor.xrAnchor.delete();\r\n                this.onAnchorRemovedObservable.notifyObservers(anchor);\r\n            }\r\n            // now check for new ones\r\n            trackedAnchors.forEach((xrAnchor) => {\r\n                const trackedAnchorIndex = this._findIndexInAnchorArray(xrAnchor);\r\n                const futureAnchor = this._findFutureAnchor(xrAnchor);\r\n                if (!this._lastFrameDetected.has(xrAnchor) || (trackedAnchorIndex === -1 && futureAnchor !== undefined)) {\r\n                    const anchor: IWebXRAnchor = {\r\n                        _removed: false,\r\n                        id: AnchorIdProvider++,\r\n                        xrAnchor: xrAnchor,\r\n                        transformationMatrix: new Matrix(),\r\n                        persistentHandle: futureAnchor?.persistentHandle,\r\n                        remove: () => {\r\n                            anchor._removed = true;\r\n                        },\r\n                    };\r\n                    this._updateAnchorWithXRFrame(xrAnchor, anchor, frame);\r\n                    this._trackedAnchors.push(anchor);\r\n                    this.onAnchorAddedObservable.notifyObservers(anchor);\r\n                    // search for the future anchor promise that matches this\r\n                    for (const pendingAnchor of this._futureAnchors) {\r\n                        if (pendingAnchor.nativeAnchor === xrAnchor && !pendingAnchor.resolved) {\r\n                            pendingAnchor.resolve(anchor);\r\n                            pendingAnchor.resolved = true;\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (trackedAnchorIndex < 0) {\r\n                        return;\r\n                    }\r\n                    const anchor = this._trackedAnchors[trackedAnchorIndex];\r\n                    this._updateAnchorWithXRFrame(xrAnchor, anchor, frame);\r\n                    if (anchor.attachedNode) {\r\n                        anchor.attachedNode.rotationQuaternion = anchor.attachedNode.rotationQuaternion || new Quaternion();\r\n                        anchor.transformationMatrix.decompose(anchor.attachedNode.scaling, anchor.attachedNode.rotationQuaternion, anchor.attachedNode.position);\r\n                    }\r\n                    this.onAnchorUpdatedObservable.notifyObservers(anchor);\r\n                }\r\n            });\r\n            this._lastFrameDetected = trackedAnchors;\r\n        }\r\n\r\n        // process future anchors\r\n        for (const futureAnchor of this._futureAnchors) {\r\n            if (!futureAnchor.resolved && !futureAnchor.submitted) {\r\n                if (!futureAnchor.xrTransformation) {\r\n                    futureAnchor.resolved = true;\r\n                    futureAnchor.reject(new Error(\"Anchor creation requires an XR transformation\"));\r\n                    continue;\r\n                }\r\n                // eslint-disable-next-line github/no-then\r\n                this._createAnchorAtTransformationAsync(futureAnchor.xrTransformation, frame).then(\r\n                    (nativeAnchor) => {\r\n                        futureAnchor.nativeAnchor = nativeAnchor;\r\n                    },\r\n                    (error) => {\r\n                        futureAnchor.resolved = true;\r\n                        futureAnchor.reject(error);\r\n                    }\r\n                );\r\n                futureAnchor.submitted = true;\r\n            }\r\n        }\r\n        for (let i = this._futureAnchors.length - 1; i >= 0; --i) {\r\n            if (this._futureAnchors[i].resolved) {\r\n                this._futureAnchors.splice(i, 1);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * avoiding using Array.find for global support.\r\n     * @param xrAnchor the plane to find in the array\r\n     * @returns the index of the anchor in the array or -1 if not found\r\n     */\r\n    private _findIndexInAnchorArray(xrAnchor: XRAnchor) {\r\n        for (let i = 0; i < this._trackedAnchors.length; ++i) {\r\n            if (this._trackedAnchors[i].xrAnchor === xrAnchor) {\r\n                return i;\r\n            }\r\n        }\r\n        return -1;\r\n    }\r\n\r\n    private _findFutureAnchor(xrAnchor: XRAnchor): IWebXRFutureAnchor | undefined {\r\n        for (const futureAnchor of this._futureAnchors) {\r\n            if (futureAnchor.nativeAnchor === xrAnchor && !futureAnchor.resolved) {\r\n                return futureAnchor;\r\n            }\r\n        }\r\n        return undefined;\r\n    }\r\n\r\n    private _setPersistentHandle(anchor: IWebXRAnchor, handle: string): void {\r\n        anchor.persistentHandle = handle;\r\n    }\r\n\r\n    private _rejectPendingPersistentAnchors(message: string): void {\r\n        for (const futureAnchor of this._futureAnchors) {\r\n            if (!futureAnchor.resolved && futureAnchor.persistentHandle !== undefined) {\r\n                futureAnchor.resolved = true;\r\n                futureAnchor.reject(new Error(message));\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateAnchorWithXRFrame(xrAnchor: XRAnchor, anchor: Partial<IWebXRAnchor>, xrFrame: XRFrame): IWebXRAnchor {\r\n        // matrix\r\n        const pose = xrFrame.getPose(xrAnchor.anchorSpace, this._xrSessionManager.referenceSpace);\r\n        if (pose) {\r\n            const mat = anchor.transformationMatrix || new Matrix();\r\n            Matrix.FromArrayToRef(pose.transform.matrix, 0, mat);\r\n            if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                mat.toggleModelMatrixHandInPlace();\r\n            }\r\n            anchor.transformationMatrix = mat;\r\n            if (!this._options.worldParentNode) {\r\n                // Logger.Warn(\"Please provide a world parent node to apply world transformation\");\r\n            } else {\r\n                mat.multiplyToRef(this._options.worldParentNode.getWorldMatrix(), mat);\r\n            }\r\n        }\r\n\r\n        return <IWebXRAnchor>anchor;\r\n    }\r\n\r\n    private async _createAnchorAtTransformationAsync(xrTransformation: XRRigidTransform, xrFrame: XRFrame) {\r\n        if (xrFrame.createAnchor) {\r\n            try {\r\n                return await xrFrame.createAnchor(xrTransformation, this._referenceSpaceForFrameAnchors ?? this._xrSessionManager.referenceSpace);\r\n            } catch (error) {\r\n                throw new Error(String(error), { cause: error });\r\n            }\r\n        } else {\r\n            this.detach();\r\n            throw new Error(\"Anchors are not enabled in your browser\");\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRAnchorSystem.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRAnchorSystem(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRAnchorSystem.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRAnchorSystem(xrSessionManager, options);\r\n        },\r\n        WebXRAnchorSystem.Version\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Vector3, Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\n\r\ndeclare const XRPlane: XRPlane;\r\n\r\n/**\r\n * Options used in the plane detector module\r\n */\r\nexport interface IWebXRPlaneDetectorOptions {\r\n    /**\r\n     * The node to use to transform the local results to world coordinates\r\n     */\r\n    worldParentNode?: TransformNode;\r\n    /**\r\n     * If set to true a reference of the created planes will be kept until the next session starts\r\n     * If not defined, planes will be removed from the array when the feature is detached or the session ended.\r\n     */\r\n    doNotRemovePlanesOnSessionEnded?: boolean;\r\n    /**\r\n     * Preferred detector configuration, not all preferred options will be supported by all platforms.\r\n     */\r\n    preferredDetectorOptions?: XRGeometryDetectorOptions;\r\n}\r\n\r\n/**\r\n * A babylon interface for a WebXR plane.\r\n * A Plane is actually a polygon, built from N points in space\r\n *\r\n * Supported in chrome 79, not supported in canary 81 ATM\r\n */\r\nexport interface IWebXRPlane {\r\n    /**\r\n     * a babylon-assigned ID for this polygon\r\n     */\r\n    id: number;\r\n    /**\r\n     * an array of vector3 points in babylon space. right/left hand system is taken into account.\r\n     */\r\n    polygonDefinition: Array<Vector3>;\r\n    /**\r\n     * A transformation matrix to apply on the mesh that will be built using the polygonDefinition\r\n     * Local vs. World are decided if worldParentNode was provided or not in the options when constructing the module\r\n     */\r\n    transformationMatrix: Matrix;\r\n    /**\r\n     * the native xr-plane object\r\n     */\r\n    xrPlane: XRPlane;\r\n    /**\r\n     * The semantic classification supplied by the XR runtime.\r\n     * This is undefined when the runtime does not expose semantic labels and null when the plane has no known classification.\r\n     */\r\n    semanticLabel?: string | null;\r\n}\r\n\r\nlet PlaneIdProvider = 0;\r\n\r\n/**\r\n * The plane detector is used to detect planes in the real world when in AR\r\n * For more information see https://github.com/immersive-web/real-world-geometry/\r\n */\r\nexport class WebXRPlaneDetector extends WebXRAbstractFeature {\r\n    private _detectedPlanes: Array<IWebXRPlane> = [];\r\n    private _enabled: boolean = false;\r\n    private _lastFrameDetected: XRPlaneSet = new Set();\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.PLANE_DETECTION;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Observers registered here will be executed when a new plane was added to the session\r\n     */\r\n    public onPlaneAddedObservable: Observable<IWebXRPlane> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when a plane is no longer detected in the session\r\n     */\r\n    public onPlaneRemovedObservable: Observable<IWebXRPlane> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when an existing plane updates (for example - expanded)\r\n     * This can execute N times every frame\r\n     */\r\n    public onPlaneUpdatedObservable: Observable<IWebXRPlane> = new Observable();\r\n\r\n    /**\r\n     * construct a new Plane Detector\r\n     * @param _xrSessionManager an instance of xr Session manager\r\n     * @param _options configuration to use when constructing this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private _options: IWebXRPlaneDetectorOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"plane-detection\";\r\n        if (this._xrSessionManager.session) {\r\n            this._init();\r\n        } else {\r\n            this._xrSessionManager.onXRSessionInit.addOnce(() => {\r\n                this._init();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        if (!this._options.doNotRemovePlanesOnSessionEnded) {\r\n            while (this._detectedPlanes.length) {\r\n                const toRemove = this._detectedPlanes.pop();\r\n                if (toRemove) {\r\n                    this.onPlaneRemovedObservable.notifyObservers(toRemove);\r\n                }\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this.onPlaneAddedObservable.clear();\r\n        this.onPlaneRemovedObservable.clear();\r\n        this.onPlaneUpdatedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Check if the needed objects are defined.\r\n     * This does not mean that the feature is enabled, but that the objects needed are well defined.\r\n     * @returns true if the initial compatibility test passed\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return typeof XRPlane !== \"undefined\";\r\n    }\r\n\r\n    /**\r\n     * Requests that the active XR session capture or refresh the current room layout.\r\n     * Detected room planes are reported through the existing plane observables.\r\n     * @see https://immersive-web.github.io/plane-detection/#dom-xrsession-initiateroomcapture\r\n     * @returns A promise that resolves when the native room capture request completes.\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async initiateRoomCapture(): Promise<void> {\r\n        const session = this._xrSessionManager.session;\r\n        if (!this._xrSessionManager.inXRSession || !session) {\r\n            throw new Error(\"WebXR room capture requires an active XR session.\");\r\n        }\r\n        if (typeof session.initiateRoomCapture !== \"function\") {\r\n            throw new Error(\"XRSession.initiateRoomCapture is not supported by this XR runtime.\");\r\n        }\r\n        return await session.initiateRoomCapture();\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        if (!this.attached || !this._enabled || !frame) {\r\n            return;\r\n        }\r\n\r\n        const detectedPlanes = frame.detectedPlanes || frame.worldInformation?.detectedPlanes;\r\n        if (detectedPlanes) {\r\n            // remove all planes that are not currently detected in the frame\r\n            for (let planeIdx = 0; planeIdx < this._detectedPlanes.length; planeIdx++) {\r\n                const plane = this._detectedPlanes[planeIdx];\r\n                if (!detectedPlanes.has(plane.xrPlane)) {\r\n                    this._detectedPlanes.splice(planeIdx--, 1);\r\n                    this.onPlaneRemovedObservable.notifyObservers(plane);\r\n                }\r\n            }\r\n\r\n            // now check for new ones\r\n            detectedPlanes.forEach((xrPlane) => {\r\n                if (!this._lastFrameDetected.has(xrPlane)) {\r\n                    const newPlane: Partial<IWebXRPlane> = {\r\n                        id: PlaneIdProvider++,\r\n                        xrPlane: xrPlane,\r\n                        polygonDefinition: [],\r\n                    };\r\n                    const plane = this._updatePlaneWithXRPlane(xrPlane, newPlane, frame);\r\n                    this._detectedPlanes.push(plane);\r\n                    this.onPlaneAddedObservable.notifyObservers(plane);\r\n                } else {\r\n                    // updated?\r\n                    if (xrPlane.lastChangedTime === this._xrSessionManager.currentTimestamp) {\r\n                        const index = this._findIndexInPlaneArray(xrPlane);\r\n                        const plane = this._detectedPlanes[index];\r\n                        this._updatePlaneWithXRPlane(xrPlane, plane, frame);\r\n                        this.onPlaneUpdatedObservable.notifyObservers(plane);\r\n                    }\r\n                }\r\n            });\r\n            this._lastFrameDetected = detectedPlanes;\r\n        }\r\n    }\r\n\r\n    private _init() {\r\n        const internalInit = () => {\r\n            this._enabled = true;\r\n            if (this._detectedPlanes.length) {\r\n                this._detectedPlanes.length = 0;\r\n            }\r\n        };\r\n\r\n        // Only supported by BabylonNative\r\n        if (!!this._xrSessionManager.isNative && !!this._options.preferredDetectorOptions && !!this._xrSessionManager.session.trySetPreferredPlaneDetectorOptions) {\r\n            this._xrSessionManager.session.trySetPreferredPlaneDetectorOptions(this._options.preferredDetectorOptions);\r\n        }\r\n\r\n        if (!this._xrSessionManager.session.updateWorldTrackingState) {\r\n            internalInit();\r\n            return;\r\n        }\r\n        this._xrSessionManager.session.updateWorldTrackingState({ planeDetectionState: { enabled: true } });\r\n        internalInit();\r\n    }\r\n\r\n    private _updatePlaneWithXRPlane(xrPlane: XRPlane, plane: Partial<IWebXRPlane>, xrFrame: XRFrame): IWebXRPlane {\r\n        plane.semanticLabel = xrPlane.semanticLabel;\r\n        plane.polygonDefinition = xrPlane.polygon.map((xrPoint) => {\r\n            const rightHandedSystem = this._xrSessionManager.scene.useRightHandedSystem ? 1 : -1;\r\n            return new Vector3(xrPoint.x, xrPoint.y, xrPoint.z * rightHandedSystem);\r\n        });\r\n        // matrix\r\n        const pose = xrFrame.getPose(xrPlane.planeSpace, this._xrSessionManager.referenceSpace);\r\n        if (pose) {\r\n            const mat = plane.transformationMatrix || new Matrix();\r\n            Matrix.FromArrayToRef(pose.transform.matrix, 0, mat);\r\n            if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                mat.toggleModelMatrixHandInPlace();\r\n            }\r\n            plane.transformationMatrix = mat;\r\n            if (this._options.worldParentNode) {\r\n                mat.multiplyToRef(this._options.worldParentNode.getWorldMatrix(), mat);\r\n            }\r\n        }\r\n\r\n        return <IWebXRPlane>plane;\r\n    }\r\n\r\n    /**\r\n     * avoiding using Array.find for global support.\r\n     * @param xrPlane the plane to find in the array\r\n     * @returns the index of the plane in the array or -1 if not found\r\n     */\r\n    private _findIndexInPlaneArray(xrPlane: XRPlane) {\r\n        for (let i = 0; i < this._detectedPlanes.length; ++i) {\r\n            if (this._detectedPlanes[i].xrPlane === xrPlane) {\r\n                return i;\r\n            }\r\n        }\r\n        return -1;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRPlaneDetector.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRPlaneDetector(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRPlaneDetector.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRPlaneDetector(xrSessionManager, options);\r\n        },\r\n        WebXRPlaneDetector.Version\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\n\r\n/**\r\n * Options interface for the background remover plugin\r\n */\r\nexport interface IWebXRBackgroundRemoverOptions {\r\n    /**\r\n     * Further background meshes to disable when entering AR\r\n     */\r\n    backgroundMeshes?: AbstractMesh[];\r\n    /**\r\n     * flags to configure the removal of the environment helper.\r\n     * If not set, the entire background will be removed. If set, flags should be set as well.\r\n     */\r\n    environmentHelperRemovalFlags?: {\r\n        /**\r\n         * Should the skybox be removed (default false)\r\n         */\r\n        skyBox?: boolean;\r\n        /**\r\n         * Should the ground be removed (default false)\r\n         */\r\n        ground?: boolean;\r\n    };\r\n    /**\r\n     * don't disable the environment helper\r\n     */\r\n    ignoreEnvironmentHelper?: boolean;\r\n}\r\n\r\n/**\r\n * A module that will automatically disable background meshes when entering AR and will enable them when leaving AR.\r\n */\r\nexport class WebXRBackgroundRemover extends WebXRAbstractFeature {\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.BACKGROUND_REMOVER;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * registered observers will be triggered when the background state changes\r\n     */\r\n    public onBackgroundStateChangedObservable: Observable<boolean> = new Observable();\r\n\r\n    /**\r\n     * constructs a new background remover module\r\n     * @param _xrSessionManager the session manager for this module\r\n     * @param options read-only options to be used in this module\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * [Empty Object] read-only options to be used in this module\r\n         */\r\n        public readonly options: IWebXRBackgroundRemoverOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        this._setBackgroundState(false);\r\n        return super.attach();\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        this._setBackgroundState(true);\r\n        return super.detach();\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this.onBackgroundStateChangedObservable.clear();\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame) {\r\n        // no-op\r\n    }\r\n\r\n    private _setBackgroundState(newState: boolean) {\r\n        const scene = this._xrSessionManager.scene;\r\n        if (!this.options.ignoreEnvironmentHelper) {\r\n            if (this.options.environmentHelperRemovalFlags) {\r\n                if (this.options.environmentHelperRemovalFlags.skyBox) {\r\n                    const backgroundSkybox = scene.getMeshByName(\"BackgroundSkybox\");\r\n                    if (backgroundSkybox) {\r\n                        backgroundSkybox.setEnabled(newState);\r\n                    }\r\n                }\r\n                if (this.options.environmentHelperRemovalFlags.ground) {\r\n                    const backgroundPlane = scene.getMeshByName(\"BackgroundPlane\");\r\n                    if (backgroundPlane) {\r\n                        backgroundPlane.setEnabled(newState);\r\n                    }\r\n                }\r\n            } else {\r\n                const backgroundHelper = scene.getMeshByName(\"BackgroundHelper\");\r\n                if (backgroundHelper) {\r\n                    backgroundHelper.setEnabled(newState);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this.options.backgroundMeshes) {\r\n            for (const mesh of this.options.backgroundMeshes) {\r\n                mesh.setEnabled(newState);\r\n            }\r\n        }\r\n\r\n        this.onBackgroundStateChangedObservable.notifyObservers(newState);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRBackgroundRemover.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRBackgroundRemover(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRBackgroundRemover.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRBackgroundRemover(xrSessionManager, options);\r\n        },\r\n        WebXRBackgroundRemover.Version,\r\n        true\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Vector3, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type WebXRInputSource } from \"../webXRInputSource\";\r\nimport { PhysicsImpostor } from \"../../Physics/v1/physicsImpostor.pure\";\r\nimport { type WebXRInput } from \"../webXRInput\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder.pure\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { PhysicsAggregate } from \"../../Physics/v2/physicsAggregate\";\r\nimport { type PhysicsBody } from \"../../Physics/v2/physicsBody\";\r\nimport { PhysicsMotionType, PhysicsShapeType } from \"../../Physics/v2/IPhysicsEnginePlugin\";\r\n\r\n/**\r\n * Options for the controller physics feature\r\n */\r\nexport class IWebXRControllerPhysicsOptions {\r\n    /**\r\n     * Should the headset get its own impostor\r\n     */\r\n    enableHeadsetImpostor?: boolean;\r\n    /**\r\n     * Optional parameters for the headset impostor\r\n     */\r\n    headsetImpostorParams?: {\r\n        /**\r\n         * The type of impostor to create. Default is sphere\r\n         */\r\n        impostorType: number;\r\n        /**\r\n         * the size of the impostor. Defaults to 10cm\r\n         */\r\n        impostorSize?: number | { width: number; height: number; depth: number };\r\n        /**\r\n         * Friction definitions\r\n         */\r\n        friction?: number;\r\n        /**\r\n         * Restitution\r\n         */\r\n        restitution?: number;\r\n    };\r\n    /**\r\n     * The physics properties of the future impostors\r\n     */\r\n    physicsProperties?: {\r\n        /**\r\n         * If set to true, a mesh impostor will be created when the controller mesh was loaded\r\n         * Note that this requires a physics engine that supports mesh impostors!\r\n         */\r\n        useControllerMesh?: boolean;\r\n        /**\r\n         * The type of impostor to create. Default is sphere\r\n         */\r\n        impostorType?: number;\r\n        /**\r\n         * the size of the impostor. Defaults to 10cm\r\n         */\r\n        impostorSize?: number | { width: number; height: number; depth: number };\r\n        /**\r\n         * Friction definitions\r\n         */\r\n        friction?: number;\r\n        /**\r\n         * Restitution\r\n         */\r\n        restitution?: number;\r\n    };\r\n    /**\r\n     * the xr input to use with this pointer selection\r\n     */\r\n    public xrInput: WebXRInput;\r\n}\r\n\r\n/**\r\n * Add physics impostor to your webxr controllers,\r\n * including naive calculation of their linear and angular velocity\r\n */\r\nexport class WebXRControllerPhysics extends WebXRAbstractFeature {\r\n    private _attachController = (xrController: WebXRInputSource) => {\r\n        if (this._controllers[xrController.uniqueId]) {\r\n            // already attached\r\n            return;\r\n        }\r\n        if (!this._xrSessionManager.scene.isPhysicsEnabled()) {\r\n            Logger.Warn(\"physics engine not enabled, skipped. Please add this controller manually.\");\r\n        }\r\n\r\n        if (this._physicsVersion === 2) {\r\n            this._attachControllerV2(xrController);\r\n        } else {\r\n            this._attachControllerV1(xrController);\r\n        }\r\n    };\r\n\r\n    private _attachControllerV1 = (xrController: WebXRInputSource) => {\r\n        // if no motion controller available, create impostors!\r\n        if (this._options.physicsProperties!.useControllerMesh && xrController.inputSource.gamepad) {\r\n            xrController.onMotionControllerInitObservable.addOnce((motionController) => {\r\n                if (!motionController._doNotLoadControllerMesh) {\r\n                    motionController.onModelLoadedObservable.addOnce(() => {\r\n                        const impostor = new PhysicsImpostor(motionController.rootMesh!, PhysicsImpostor.MeshImpostor, {\r\n                            mass: 0,\r\n                            ...this._options.physicsProperties,\r\n                        });\r\n\r\n                        const controllerMesh = xrController.grip || xrController.pointer;\r\n                        this._controllers[xrController.uniqueId] = {\r\n                            xrController,\r\n                            impostor,\r\n                            oldPos: controllerMesh.position.clone(),\r\n                            oldRotation: controllerMesh.rotationQuaternion!.clone(),\r\n                        };\r\n                    });\r\n                } else {\r\n                    // This controller isn't using a model, create impostors instead\r\n                    this._createPhysicsImpostor(xrController);\r\n                }\r\n            });\r\n        } else {\r\n            this._createPhysicsImpostor(xrController);\r\n        }\r\n    };\r\n\r\n    private _attachControllerV2 = (xrController: WebXRInputSource) => {\r\n        // if no motion controller available, create physics aggregates!\r\n        if (this._options.physicsProperties!.useControllerMesh && xrController.inputSource.gamepad) {\r\n            xrController.onMotionControllerInitObservable.addOnce((motionController) => {\r\n                if (!motionController._doNotLoadControllerMesh) {\r\n                    motionController.onModelLoadedObservable.addOnce(() => {\r\n                        const shapeType = this._mapImpostorTypeToShapeType(PhysicsImpostor.MeshImpostor);\r\n                        const aggregate = new PhysicsAggregate(\r\n                            motionController.rootMesh!,\r\n                            shapeType,\r\n                            {\r\n                                mass: 0,\r\n                                friction: this._options.physicsProperties?.friction ?? 0.2,\r\n                                restitution: this._options.physicsProperties?.restitution ?? 0.2,\r\n                            },\r\n                            this._xrSessionManager.scene\r\n                        );\r\n\r\n                        aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);\r\n\r\n                        const controllerMesh = xrController.grip || xrController.pointer;\r\n                        this._controllers[xrController.uniqueId] = {\r\n                            xrController,\r\n                            physicsAggregate: aggregate,\r\n                            physicsBody: aggregate.body,\r\n                            isPhysicsV2: true,\r\n                            oldPos: controllerMesh.position.clone(),\r\n                            oldRotation: controllerMesh.rotationQuaternion!.clone(),\r\n                        };\r\n                    });\r\n                } else {\r\n                    // This controller isn't using a model, create physics aggregate instead\r\n                    this._createPhysicsAggregate(xrController);\r\n                }\r\n            });\r\n        } else {\r\n            this._createPhysicsAggregate(xrController);\r\n        }\r\n    };\r\n\r\n    private _mapImpostorTypeToShapeType(impostorType: number): PhysicsShapeType {\r\n        // Map v1 PhysicsImpostor types to v2 PhysicsShapeType\r\n        switch (impostorType) {\r\n            case PhysicsImpostor.SphereImpostor:\r\n                return PhysicsShapeType.SPHERE;\r\n            case PhysicsImpostor.BoxImpostor:\r\n                return PhysicsShapeType.BOX;\r\n            case PhysicsImpostor.CapsuleImpostor:\r\n                return PhysicsShapeType.CAPSULE;\r\n            case PhysicsImpostor.CylinderImpostor:\r\n                return PhysicsShapeType.CYLINDER;\r\n            case PhysicsImpostor.MeshImpostor:\r\n                return PhysicsShapeType.MESH;\r\n            case PhysicsImpostor.ConvexHullImpostor:\r\n                return PhysicsShapeType.CONVEX_HULL;\r\n            default:\r\n                Logger.Warn(`Unsupported impostor type ${impostorType} for v2 physics, defaulting to SPHERE`);\r\n                return PhysicsShapeType.SPHERE;\r\n        }\r\n    }\r\n\r\n    private _createPhysicsImpostor(xrController: WebXRInputSource) {\r\n        const impostorType: number = this._options.physicsProperties!.impostorType || PhysicsImpostor.SphereImpostor;\r\n        const impostorSize: number | { width: number; height: number; depth: number } = this._options.physicsProperties!.impostorSize || 0.1;\r\n        const impostorMesh = CreateSphere(\"impostor-mesh-\" + xrController.uniqueId, {\r\n            diameterX: typeof impostorSize === \"number\" ? impostorSize : impostorSize.width,\r\n            diameterY: typeof impostorSize === \"number\" ? impostorSize : impostorSize.height,\r\n            diameterZ: typeof impostorSize === \"number\" ? impostorSize : impostorSize.depth,\r\n        });\r\n        impostorMesh.isVisible = this._debugMode;\r\n        impostorMesh.isPickable = false;\r\n        impostorMesh.rotationQuaternion = new Quaternion();\r\n        const controllerMesh = xrController.grip || xrController.pointer;\r\n        impostorMesh.position.copyFrom(controllerMesh.position);\r\n        impostorMesh.rotationQuaternion.copyFrom(controllerMesh.rotationQuaternion!);\r\n        const impostor = new PhysicsImpostor(impostorMesh, impostorType, {\r\n            mass: 0,\r\n            ...this._options.physicsProperties,\r\n        });\r\n        this._controllers[xrController.uniqueId] = {\r\n            xrController,\r\n            impostor,\r\n            impostorMesh,\r\n        };\r\n    }\r\n\r\n    private _createPhysicsAggregate(xrController: WebXRInputSource) {\r\n        const impostorType: number = this._options.physicsProperties!.impostorType || PhysicsImpostor.SphereImpostor;\r\n        const impostorSize: number | { width: number; height: number; depth: number } = this._options.physicsProperties!.impostorSize || 0.1;\r\n        const impostorMesh = CreateSphere(\"impostor-mesh-\" + xrController.uniqueId, {\r\n            diameterX: typeof impostorSize === \"number\" ? impostorSize : impostorSize.width,\r\n            diameterY: typeof impostorSize === \"number\" ? impostorSize : impostorSize.height,\r\n            diameterZ: typeof impostorSize === \"number\" ? impostorSize : impostorSize.depth,\r\n        });\r\n        impostorMesh.isVisible = this._debugMode;\r\n        impostorMesh.isPickable = false;\r\n        impostorMesh.rotationQuaternion = new Quaternion();\r\n        const controllerMesh = xrController.grip || xrController.pointer;\r\n        impostorMesh.position.copyFrom(controllerMesh.position);\r\n        impostorMesh.rotationQuaternion.copyFrom(controllerMesh.rotationQuaternion!);\r\n\r\n        const shapeType = this._mapImpostorTypeToShapeType(impostorType);\r\n        const aggregate = new PhysicsAggregate(\r\n            impostorMesh,\r\n            shapeType,\r\n            {\r\n                mass: 0,\r\n                friction: this._options.physicsProperties?.friction ?? 0.2,\r\n                restitution: this._options.physicsProperties?.restitution ?? 0.2,\r\n            },\r\n            this._xrSessionManager.scene\r\n        );\r\n\r\n        aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);\r\n\r\n        this._controllers[xrController.uniqueId] = {\r\n            xrController,\r\n            physicsAggregate: aggregate,\r\n            physicsBody: aggregate.body,\r\n            isPhysicsV2: true,\r\n            impostorMesh,\r\n        };\r\n    }\r\n\r\n    private _controllers: {\r\n        [id: string]: {\r\n            xrController: WebXRInputSource;\r\n            impostorMesh?: AbstractMesh;\r\n            impostor?: PhysicsImpostor;\r\n            physicsAggregate?: PhysicsAggregate;\r\n            physicsBody?: PhysicsBody;\r\n            isPhysicsV2?: boolean;\r\n            oldPos?: Vector3;\r\n            oldSpeed?: Vector3;\r\n            oldRotation?: Quaternion;\r\n        };\r\n    } = {};\r\n    private _debugMode = false;\r\n    private _delta: number = 0;\r\n    private _headsetImpostor?: PhysicsImpostor;\r\n    private _headsetMesh?: AbstractMesh;\r\n    private _headsetAggregateV2?: PhysicsAggregate;\r\n    private _lastTimestamp: number = 0;\r\n    private _physicsVersion: 1 | 2 = 1;\r\n    private _tmpQuaternion: Quaternion = new Quaternion();\r\n    private _tmpVector: Vector3 = new Vector3();\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.PHYSICS_CONTROLLERS;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the webxr specs version\r\n     */\r\n    public static readonly Version = 2;\r\n\r\n    /**\r\n     * Construct a new Controller Physics Feature\r\n     * @param _xrSessionManager the corresponding xr session manager\r\n     * @param _options options to create this feature with\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private readonly _options: IWebXRControllerPhysicsOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        if (!this._options.physicsProperties) {\r\n            this._options.physicsProperties = {};\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     * enable debugging - will show console outputs and the impostor mesh\r\n     */\r\n    public _enablePhysicsDebug() {\r\n        this._debugMode = true;\r\n        const keys = Object.keys(this._controllers);\r\n        for (const controllerId of keys) {\r\n            const controllerData = this._controllers[controllerId];\r\n            if (controllerData.impostorMesh) {\r\n                controllerData.impostorMesh.isVisible = true;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Manually add a controller (if no xrInput was provided or physics engine was not enabled)\r\n     * @param xrController the controller to add\r\n     */\r\n    public addController(xrController: WebXRInputSource) {\r\n        this._attachController(xrController);\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        // Detect physics version\r\n        const physicsEngine = this._xrSessionManager.scene.getPhysicsEngine();\r\n        if (physicsEngine) {\r\n            this._physicsVersion = (physicsEngine.getPluginVersion() as 1 | 2) || 1;\r\n        } else {\r\n            // Default to v1 if no physics engine (warning will be shown later)\r\n            this._physicsVersion = 1;\r\n        }\r\n\r\n        if (!this._options.xrInput) {\r\n            return true;\r\n        }\r\n\r\n        for (const controller of this._options.xrInput.controllers) {\r\n            this._attachController(controller);\r\n        }\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\r\n        this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\r\n            // REMOVE the controller\r\n            this._detachController(controller.uniqueId);\r\n        });\r\n\r\n        if (this._options.enableHeadsetImpostor) {\r\n            if (this._physicsVersion === 2) {\r\n                this._enableHeadsetPhysicsV2();\r\n            } else {\r\n                this._enableHeadsetPhysicsV1();\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        const keys = Object.keys(this._controllers);\r\n        for (const controllerId of keys) {\r\n            this._detachController(controllerId);\r\n        }\r\n\r\n        if (this._headsetMesh) {\r\n            this._headsetMesh.dispose();\r\n        }\r\n\r\n        // Dispose v2 aggregate if present\r\n        if (this._headsetAggregateV2) {\r\n            this._headsetAggregateV2.dispose();\r\n            this._headsetAggregateV2 = undefined;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Get the headset impostor, if enabled\r\n     * @returns the impostor\r\n     */\r\n    public getHeadsetImpostor() {\r\n        return this._headsetImpostor;\r\n    }\r\n\r\n    /**\r\n     * Get the physics impostor of a specific controller.\r\n     * The impostor is not attached to a mesh because a mesh for each controller is not obligatory\r\n     * @param controller the controller or the controller id of which to get the impostor\r\n     * @returns the impostor or null\r\n     */\r\n    public getImpostorForController(controller: WebXRInputSource | string): Nullable<PhysicsImpostor> {\r\n        const id = typeof controller === \"string\" ? controller : controller.uniqueId;\r\n        if (this._controllers[id]) {\r\n            return this._controllers[id].impostor || null;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the physics aggregate for a controller (v2 only)\r\n     * @param controller the controller or the controller id\r\n     * @returns the aggregate or null\r\n     */\r\n    public getPhysicsAggregateForController(controller: WebXRInputSource | string): Nullable<PhysicsAggregate> {\r\n        const id = typeof controller === \"string\" ? controller : controller.uniqueId;\r\n        if (this._controllers[id]) {\r\n            return this._controllers[id].physicsAggregate || null;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the physics body for a controller (v2 only)\r\n     * @param controller the controller or the controller id\r\n     * @returns the physics body or null\r\n     */\r\n    public getPhysicsBodyForController(controller: WebXRInputSource | string): Nullable<PhysicsBody> {\r\n        const id = typeof controller === \"string\" ? controller : controller.uniqueId;\r\n        if (this._controllers[id]) {\r\n            return this._controllers[id].physicsBody || null;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Get the headset physics aggregate (v2 only)\r\n     * @returns the physics aggregate or null\r\n     */\r\n    public getHeadsetPhysicsAggregate(): Nullable<PhysicsAggregate> {\r\n        return this._headsetAggregateV2 || null;\r\n    }\r\n\r\n    /**\r\n     * Update the physics properties provided in the constructor\r\n     * @param newProperties the new properties object\r\n     * @param newProperties.impostorType\r\n     * @param newProperties.impostorSize\r\n     * @param newProperties.friction\r\n     * @param newProperties.restitution\r\n     */\r\n    public setPhysicsProperties(newProperties: {\r\n        impostorType?: number;\r\n        impostorSize?: number | { width: number; height: number; depth: number };\r\n        friction?: number;\r\n        restitution?: number;\r\n    }) {\r\n        this._options.physicsProperties = {\r\n            ...this._options.physicsProperties,\r\n            ...newProperties,\r\n        };\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: any): void {\r\n        this._delta = this._xrSessionManager.currentTimestamp - this._lastTimestamp;\r\n        this._lastTimestamp = this._xrSessionManager.currentTimestamp;\r\n\r\n        if (this._physicsVersion === 2) {\r\n            this._onXRFrameV2();\r\n        } else {\r\n            this._onXRFrameV1();\r\n        }\r\n    }\r\n\r\n    private _onXRFrameV1(): void {\r\n        if (this._headsetMesh && this._headsetImpostor) {\r\n            this._headsetMesh.position.copyFrom(this._options.xrInput.xrCamera.globalPosition);\r\n            this._headsetMesh.rotationQuaternion!.copyFrom(this._options.xrInput.xrCamera.absoluteRotation);\r\n            if (this._options.xrInput.xrCamera._lastXRViewerPose?.linearVelocity) {\r\n                const lv = this._options.xrInput.xrCamera._lastXRViewerPose.linearVelocity;\r\n                this._tmpVector.set(lv.x, lv.y, lv.z);\r\n                this._headsetImpostor.setLinearVelocity(this._tmpVector);\r\n            }\r\n            if (this._options.xrInput.xrCamera._lastXRViewerPose?.angularVelocity) {\r\n                const av = this._options.xrInput.xrCamera._lastXRViewerPose.angularVelocity;\r\n                this._tmpVector.set(av.x, av.y, av.z);\r\n                this._headsetImpostor.setAngularVelocity(this._tmpVector);\r\n            }\r\n        }\r\n        const keys = Object.keys(this._controllers);\r\n        for (const controllerId of keys) {\r\n            const controllerData = this._controllers[controllerId];\r\n            const controllerMesh = controllerData.xrController.grip || controllerData.xrController.pointer;\r\n            const comparedPosition = controllerData.oldPos || controllerData.impostorMesh!.position;\r\n            if (controllerData.xrController._lastXRPose?.linearVelocity) {\r\n                const lv = controllerData.xrController._lastXRPose.linearVelocity;\r\n                this._tmpVector.set(lv.x, lv.y, lv.z);\r\n                controllerData.impostor!.setLinearVelocity(this._tmpVector);\r\n            } else {\r\n                controllerMesh.position.subtractToRef(comparedPosition, this._tmpVector);\r\n                this._tmpVector.scaleInPlace(1000 / this._delta);\r\n                controllerData.impostor!.setLinearVelocity(this._tmpVector);\r\n            }\r\n            comparedPosition.copyFrom(controllerMesh.position);\r\n            if (this._debugMode) {\r\n                Logger.Log([this._tmpVector, \"linear\"]);\r\n            }\r\n\r\n            const comparedQuaternion = controllerData.oldRotation || controllerData.impostorMesh!.rotationQuaternion!;\r\n            if (controllerData.xrController._lastXRPose?.angularVelocity) {\r\n                const av = controllerData.xrController._lastXRPose.angularVelocity;\r\n                this._tmpVector.set(av.x, av.y, av.z);\r\n                controllerData.impostor!.setAngularVelocity(this._tmpVector);\r\n            } else {\r\n                if (!comparedQuaternion.equalsWithEpsilon(controllerMesh.rotationQuaternion!)) {\r\n                    // roughly based on this - https://www.gamedev.net/forums/topic/347752-quaternion-and-angular-velocity/\r\n                    comparedQuaternion.conjugateInPlace().multiplyToRef(controllerMesh.rotationQuaternion!, this._tmpQuaternion);\r\n                    const len = Math.sqrt(\r\n                        this._tmpQuaternion.x * this._tmpQuaternion.x + this._tmpQuaternion.y * this._tmpQuaternion.y + this._tmpQuaternion.z * this._tmpQuaternion.z\r\n                    );\r\n                    this._tmpVector.set(this._tmpQuaternion.x, this._tmpQuaternion.y, this._tmpQuaternion.z);\r\n                    // define a better epsilon\r\n                    if (len < 0.001) {\r\n                        this._tmpVector.scaleInPlace(2);\r\n                    } else {\r\n                        const angle = 2 * Math.atan2(len, this._tmpQuaternion.w);\r\n                        this._tmpVector.scaleInPlace(angle / (len * (this._delta / 1000)));\r\n                    }\r\n                    controllerData.impostor!.setAngularVelocity(this._tmpVector);\r\n                }\r\n            }\r\n            comparedQuaternion.copyFrom(controllerMesh.rotationQuaternion!);\r\n            if (this._debugMode) {\r\n                Logger.Log([this._tmpVector, this._tmpQuaternion, \"angular\"]);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _onXRFrameV2(): void {\r\n        if (this._headsetMesh && this._headsetAggregateV2) {\r\n            this._headsetMesh.position.copyFrom(this._options.xrInput.xrCamera.globalPosition);\r\n            this._headsetMesh.rotationQuaternion!.copyFrom(this._options.xrInput.xrCamera.absoluteRotation);\r\n            if (this._options.xrInput.xrCamera._lastXRViewerPose?.linearVelocity) {\r\n                const lv = this._options.xrInput.xrCamera._lastXRViewerPose.linearVelocity;\r\n                this._tmpVector.set(lv.x, lv.y, lv.z);\r\n                this._headsetAggregateV2.body.setLinearVelocity(this._tmpVector);\r\n            }\r\n            if (this._options.xrInput.xrCamera._lastXRViewerPose?.angularVelocity) {\r\n                const av = this._options.xrInput.xrCamera._lastXRViewerPose.angularVelocity;\r\n                this._tmpVector.set(av.x, av.y, av.z);\r\n                this._headsetAggregateV2.body.setAngularVelocity(this._tmpVector);\r\n            }\r\n        }\r\n        const keys = Object.keys(this._controllers);\r\n        for (const controllerId of keys) {\r\n            const controllerData = this._controllers[controllerId];\r\n            if (!controllerData.isPhysicsV2) {\r\n                continue;\r\n            }\r\n\r\n            const controllerMesh = controllerData.xrController.grip || controllerData.xrController.pointer;\r\n            const comparedPosition = controllerData.oldPos || controllerData.impostorMesh!.position;\r\n            if (controllerData.xrController._lastXRPose?.linearVelocity) {\r\n                const lv = controllerData.xrController._lastXRPose.linearVelocity;\r\n                this._tmpVector.set(lv.x, lv.y, lv.z);\r\n                controllerData.physicsBody!.setLinearVelocity(this._tmpVector);\r\n            } else {\r\n                controllerMesh.position.subtractToRef(comparedPosition, this._tmpVector);\r\n                this._tmpVector.scaleInPlace(1000 / this._delta);\r\n                controllerData.physicsBody!.setLinearVelocity(this._tmpVector);\r\n            }\r\n            comparedPosition.copyFrom(controllerMesh.position);\r\n            if (this._debugMode) {\r\n                Logger.Log([this._tmpVector, \"linear\"]);\r\n            }\r\n\r\n            const comparedQuaternion = controllerData.oldRotation || controllerData.impostorMesh!.rotationQuaternion!;\r\n            if (controllerData.xrController._lastXRPose?.angularVelocity) {\r\n                const av = controllerData.xrController._lastXRPose.angularVelocity;\r\n                this._tmpVector.set(av.x, av.y, av.z);\r\n                controllerData.physicsBody!.setAngularVelocity(this._tmpVector);\r\n            } else {\r\n                if (!comparedQuaternion.equalsWithEpsilon(controllerMesh.rotationQuaternion!)) {\r\n                    // roughly based on this - https://www.gamedev.net/forums/topic/347752-quaternion-and-angular-velocity/\r\n                    comparedQuaternion.conjugateInPlace().multiplyToRef(controllerMesh.rotationQuaternion!, this._tmpQuaternion);\r\n                    const len = Math.sqrt(\r\n                        this._tmpQuaternion.x * this._tmpQuaternion.x + this._tmpQuaternion.y * this._tmpQuaternion.y + this._tmpQuaternion.z * this._tmpQuaternion.z\r\n                    );\r\n                    this._tmpVector.set(this._tmpQuaternion.x, this._tmpQuaternion.y, this._tmpQuaternion.z);\r\n                    // define a better epsilon\r\n                    if (len < 0.001) {\r\n                        this._tmpVector.scaleInPlace(2);\r\n                    } else {\r\n                        const angle = 2 * Math.atan2(len, this._tmpQuaternion.w);\r\n                        this._tmpVector.scaleInPlace(angle / (len * (this._delta / 1000)));\r\n                    }\r\n                    controllerData.physicsBody!.setAngularVelocity(this._tmpVector);\r\n                }\r\n            }\r\n            comparedQuaternion.copyFrom(controllerMesh.rotationQuaternion!);\r\n            if (this._debugMode) {\r\n                Logger.Log([this._tmpVector, this._tmpQuaternion, \"angular\"]);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _enableHeadsetPhysicsV1(): void {\r\n        const params = this._options.headsetImpostorParams || {\r\n            impostorType: PhysicsImpostor.SphereImpostor,\r\n            restitution: 0.8,\r\n            impostorSize: 0.3,\r\n        };\r\n        const impostorSize = params.impostorSize || 0.3;\r\n        this._headsetMesh = CreateSphere(\"headset-mesh\", {\r\n            diameterX: typeof impostorSize === \"number\" ? impostorSize : impostorSize.width,\r\n            diameterY: typeof impostorSize === \"number\" ? impostorSize : impostorSize.height,\r\n            diameterZ: typeof impostorSize === \"number\" ? impostorSize : impostorSize.depth,\r\n        });\r\n        this._headsetMesh.rotationQuaternion = new Quaternion();\r\n        this._headsetMesh.isVisible = false;\r\n        this._headsetImpostor = new PhysicsImpostor(this._headsetMesh, params.impostorType, { mass: 0, ...params });\r\n    }\r\n\r\n    private _enableHeadsetPhysicsV2(): void {\r\n        const params = this._options.headsetImpostorParams || {\r\n            impostorType: PhysicsImpostor.SphereImpostor,\r\n            restitution: 0.8,\r\n            impostorSize: 0.3,\r\n        };\r\n        const impostorSize = params.impostorSize || 0.3;\r\n        this._headsetMesh = CreateSphere(\"headset-mesh\", {\r\n            diameterX: typeof impostorSize === \"number\" ? impostorSize : impostorSize.width,\r\n            diameterY: typeof impostorSize === \"number\" ? impostorSize : impostorSize.height,\r\n            diameterZ: typeof impostorSize === \"number\" ? impostorSize : impostorSize.depth,\r\n        });\r\n        this._headsetMesh.rotationQuaternion = new Quaternion();\r\n        this._headsetMesh.isVisible = false;\r\n\r\n        const shapeType = this._mapImpostorTypeToShapeType(params.impostorType);\r\n        this._headsetAggregateV2 = new PhysicsAggregate(\r\n            this._headsetMesh,\r\n            shapeType,\r\n            {\r\n                mass: 0,\r\n                friction: params.friction ?? 0.2,\r\n                restitution: params.restitution ?? 0.8,\r\n            },\r\n            this._xrSessionManager.scene\r\n        );\r\n\r\n        this._headsetAggregateV2.body.setMotionType(PhysicsMotionType.ANIMATED);\r\n        this._headsetAggregateV2.body.disableSync = true;\r\n    }\r\n\r\n    private _detachController(xrControllerUniqueId: string) {\r\n        const controllerData = this._controllers[xrControllerUniqueId];\r\n        if (!controllerData) {\r\n            return;\r\n        }\r\n        if (controllerData.impostorMesh) {\r\n            controllerData.impostorMesh.dispose();\r\n        }\r\n\r\n        // Dispose v2 aggregate if present\r\n        if (controllerData.physicsAggregate) {\r\n            controllerData.physicsAggregate.dispose();\r\n        }\r\n\r\n        // remove from the map\r\n        delete this._controllers[xrControllerUniqueId];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRControllerPhysics.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRControllerPhysics(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRControllerPhysics.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRControllerPhysics(xrSessionManager, options);\r\n        },\r\n        WebXRControllerPhysics.Version,\r\n        true\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Vector3, Matrix, Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type IWebXRLegacyHitTestOptions, type IWebXRLegacyHitResult, type IWebXRHitTestFeature } from \"./WebXRHitTestLegacy\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * Options used for hit testing (version 2)\r\n */\r\nexport interface IWebXRHitTestOptions extends IWebXRLegacyHitTestOptions {\r\n    /**\r\n     * Do not create a permanent hit test. Will usually be used when only\r\n     * transient inputs are needed.\r\n     */\r\n    disablePermanentHitTest?: boolean;\r\n    /**\r\n     * Enable transient (for example touch-based) hit test inspections\r\n     */\r\n    enableTransientHitTest?: boolean;\r\n    /**\r\n     * Override the default transient hit test profile (generic-touchscreen).\r\n     */\r\n    transientHitTestProfile?: string;\r\n    /**\r\n     * Offset ray for the permanent hit test\r\n     */\r\n    offsetRay?: Vector3;\r\n    /**\r\n     * Offset ray for the transient hit test\r\n     */\r\n    transientOffsetRay?: Vector3;\r\n    /**\r\n     * Instead of using viewer space for hit tests, use the reference space defined in the session manager\r\n     */\r\n    useReferenceSpace?: boolean;\r\n\r\n    /**\r\n     * Override the default entity type(s) of the hit-test result\r\n     */\r\n    entityTypes?: XRHitTestTrackableType[];\r\n}\r\n\r\n/**\r\n * Interface defining the babylon result of hit-test\r\n */\r\nexport interface IWebXRHitResult extends IWebXRLegacyHitResult {\r\n    /**\r\n     * The input source that generated this hit test (if transient)\r\n     */\r\n    inputSource?: XRInputSource;\r\n    /**\r\n     * Is this a transient hit test\r\n     */\r\n    isTransient?: boolean;\r\n    /**\r\n     * Position of the hit test result\r\n     */\r\n    position: Vector3;\r\n    /**\r\n     * Rotation of the hit test result\r\n     */\r\n    rotationQuaternion: Quaternion;\r\n\r\n    /**\r\n     * The native hit test result\r\n     */\r\n    xrHitResult: XRHitTestResult;\r\n}\r\n\r\n/**\r\n * The currently-working hit-test module.\r\n * Hit test (or Ray-casting) is used to interact with the real world.\r\n * For further information read here - https://github.com/immersive-web/hit-test\r\n *\r\n * Tested on chrome (mobile) 80.\r\n */\r\nexport class WebXRHitTest extends WebXRAbstractFeature implements IWebXRHitTestFeature<IWebXRHitResult> {\r\n    private _tmpMat: Matrix = new Matrix();\r\n    private _tmpPos: Vector3 = new Vector3();\r\n    private _tmpQuat: Quaternion = new Quaternion();\r\n    private _transientXrHitTestSource: Nullable<XRTransientInputHitTestSource>;\r\n    // in XR space z-forward is negative\r\n    private _xrHitTestSource: Nullable<XRHitTestSource>;\r\n    private _initHitTestSource = (referenceSpace: XRReferenceSpace) => {\r\n        if (!referenceSpace) {\r\n            return;\r\n        }\r\n        const offsetRay = new XRRay(this.options.offsetRay || {});\r\n        const hitTestOptions: XRHitTestOptionsInit = {\r\n            space: this.options.useReferenceSpace ? referenceSpace : this._xrSessionManager.viewerReferenceSpace,\r\n            offsetRay: offsetRay,\r\n        };\r\n        if (this.options.entityTypes) {\r\n            hitTestOptions.entityTypes = this.options.entityTypes;\r\n        }\r\n        if (!hitTestOptions.space) {\r\n            Logger.Warn(\"waiting for viewer reference space to initialize\");\r\n            return;\r\n        }\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n        this._xrSessionManager.session.requestHitTestSource!(hitTestOptions).then((hitTestSource) => {\r\n            if (this._xrHitTestSource) {\r\n                this._xrHitTestSource.cancel();\r\n            }\r\n            this._xrHitTestSource = hitTestSource;\r\n        });\r\n    };\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.HIT_TEST;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 2;\r\n\r\n    /**\r\n     * When set to true, each hit test will have its own position/rotation objects\r\n     * When set to false, position and rotation objects will be reused for each hit test. It is expected that\r\n     * the developers will clone them or copy them as they see fit.\r\n     */\r\n    public autoCloneTransformation: boolean = false;\r\n    /**\r\n     * Triggered when new babylon (transformed) hit test results are available\r\n     * Note - this will be called when results come back from the device. It can be an empty array!!\r\n     */\r\n    public onHitTestResultObservable: Observable<IWebXRHitResult[]> = new Observable();\r\n    /**\r\n     * Use this to temporarily pause hit test checks.\r\n     */\r\n    public paused: boolean = false;\r\n\r\n    /**\r\n     * Creates a new instance of the hit test feature\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param options options to use when constructing this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * [Empty Object] options to use when constructing this feature\r\n         */\r\n        public readonly options: IWebXRHitTestOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"hit-test\";\r\n        Logger.Warn(\"Hit test is an experimental and unstable feature.\");\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        // Feature enabled, but not available\r\n        if (!this._xrSessionManager.session.requestHitTestSource) {\r\n            return false;\r\n        }\r\n\r\n        if (!this.options.disablePermanentHitTest) {\r\n            if (this._xrSessionManager.referenceSpace) {\r\n                this._initHitTestSource(this._xrSessionManager.referenceSpace);\r\n            }\r\n            this._xrSessionManager.onXRReferenceSpaceChanged.add(this._initHitTestSource);\r\n        }\r\n        if (this.options.enableTransientHitTest) {\r\n            const offsetRay = new XRRay(this.options.transientOffsetRay || {});\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            this._xrSessionManager.session.requestHitTestSourceForTransientInput!({\r\n                profile: this.options.transientHitTestProfile || \"generic-touchscreen\",\r\n                offsetRay,\r\n                entityTypes: this.options.entityTypes,\r\n                // eslint-disable-next-line github/no-then\r\n            }).then((hitSource) => {\r\n                this._transientXrHitTestSource = hitSource;\r\n            });\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n        if (this._xrHitTestSource) {\r\n            this._xrHitTestSource.cancel();\r\n            this._xrHitTestSource = null;\r\n        }\r\n        this._xrSessionManager.onXRReferenceSpaceChanged.removeCallback(this._initHitTestSource);\r\n        if (this._transientXrHitTestSource) {\r\n            this._transientXrHitTestSource.cancel();\r\n            this._transientXrHitTestSource = null;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this.onHitTestResultObservable.clear();\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        // make sure we do nothing if (async) not attached\r\n        if (!this.attached || this.paused) {\r\n            return;\r\n        }\r\n\r\n        if (this._xrHitTestSource) {\r\n            const results = frame.getHitTestResults(this._xrHitTestSource);\r\n            this._processWebXRHitTestResult(results);\r\n        }\r\n        if (this._transientXrHitTestSource) {\r\n            const hitTestResultsPerInputSource = frame.getHitTestResultsForTransientInput(this._transientXrHitTestSource);\r\n\r\n            for (const resultsPerInputSource of hitTestResultsPerInputSource) {\r\n                this._processWebXRHitTestResult(resultsPerInputSource.results, resultsPerInputSource.inputSource);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _processWebXRHitTestResult(hitTestResults: readonly XRHitTestResult[], inputSource?: XRInputSource) {\r\n        const results: IWebXRHitResult[] = [];\r\n        for (const hitTestResult of hitTestResults) {\r\n            const pose = hitTestResult.getPose(this._xrSessionManager.referenceSpace);\r\n            if (!pose) {\r\n                continue;\r\n            }\r\n            const pos = pose.transform.position;\r\n            const quat = pose.transform.orientation;\r\n            this._tmpPos.set(pos.x, pos.y, pos.z).scaleInPlace(this._xrSessionManager.worldScalingFactor);\r\n            this._tmpQuat.set(quat.x, quat.y, quat.z, quat.w);\r\n            Matrix.FromFloat32ArrayToRefScaled(pose.transform.matrix, 0, 1, this._tmpMat);\r\n            if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                this._tmpPos.z *= -1;\r\n                this._tmpQuat.z *= -1;\r\n                this._tmpQuat.w *= -1;\r\n                this._tmpMat.toggleModelMatrixHandInPlace();\r\n            }\r\n\r\n            const result: IWebXRHitResult = {\r\n                position: this.autoCloneTransformation ? this._tmpPos.clone() : this._tmpPos,\r\n                rotationQuaternion: this.autoCloneTransformation ? this._tmpQuat.clone() : this._tmpQuat,\r\n                transformationMatrix: this.autoCloneTransformation ? this._tmpMat.clone() : this._tmpMat,\r\n                inputSource: inputSource,\r\n                isTransient: !!inputSource,\r\n                xrHitResult: hitTestResult,\r\n            };\r\n            results.push(result);\r\n        }\r\n\r\n        this.onHitTestResultObservable.notifyObservers(results);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRHitTest.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRHitTest(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin versions\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRHitTest.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRHitTest(xrSessionManager, options);\r\n        },\r\n        WebXRHitTest.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\n\r\n/**\r\n * A babylon interface for a \"WebXR\" feature point.\r\n * Represents the position and confidence value of a given feature point.\r\n */\r\nexport interface IWebXRFeaturePoint {\r\n    /**\r\n     * Represents the position of the feature point in world space.\r\n     */\r\n    position: Vector3;\r\n    /**\r\n     * Represents the confidence value of the feature point in world space. 0 being least confident, and 1 being most confident.\r\n     */\r\n    confidenceValue: number;\r\n}\r\n\r\n/**\r\n * The feature point system is used to detect feature points from real world geometry.\r\n * This feature is currently experimental and only supported on BabylonNative, and should not be used in the browser.\r\n * The newly introduced API can be seen in webxr.nativeextensions.d.ts and described in FeaturePoints.md.\r\n */\r\nexport class WebXRFeaturePointSystem extends WebXRAbstractFeature {\r\n    private _enabled: boolean = false;\r\n    private _featurePointCloud: Array<IWebXRFeaturePoint> = [];\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.FEATURE_POINTS;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n    /**\r\n     * Observers registered here will be executed whenever new feature points are added (on XRFrame while the session is tracking).\r\n     * Will notify the observers about which feature points have been added.\r\n     */\r\n    public readonly onFeaturePointsAddedObservable: Observable<number[]> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed whenever a feature point has been updated (on XRFrame while the session is tracking).\r\n     * Will notify the observers about which feature points have been updated.\r\n     */\r\n    public readonly onFeaturePointsUpdatedObservable: Observable<number[]> = new Observable();\r\n    /**\r\n     * The current feature point cloud maintained across frames.\r\n     */\r\n    public get featurePointCloud(): Array<IWebXRFeaturePoint> {\r\n        return this._featurePointCloud;\r\n    }\r\n\r\n    /**\r\n     * construct the feature point system\r\n     * @param _xrSessionManager an instance of xr Session manager\r\n     */\r\n    constructor(_xrSessionManager: WebXRSessionManager) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"bjsfeature-points\";\r\n        if (this._xrSessionManager.session) {\r\n            this._init();\r\n        } else {\r\n            this._xrSessionManager.onXRSessionInit.addOnce(() => {\r\n                this._init();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        this.featurePointCloud.length = 0;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        this._featurePointCloud.length = 0;\r\n        this.onFeaturePointsUpdatedObservable.clear();\r\n        this.onFeaturePointsAddedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * On receiving a new XR frame if this feature is attached notify observers new feature point data is available.\r\n     * @param frame\r\n     */\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        if (!this.attached || !this._enabled || !frame) {\r\n            return;\r\n        }\r\n\r\n        const featurePointRawData: number[] | undefined = frame.featurePointCloud;\r\n        if (!featurePointRawData || featurePointRawData.length === 0) {\r\n            return;\r\n        } else {\r\n            if (featurePointRawData.length % 5 !== 0) {\r\n                throw new Error(\"Received malformed feature point cloud of length: \" + featurePointRawData.length);\r\n            }\r\n\r\n            const numberOfFeaturePoints: number = featurePointRawData.length / 5;\r\n            const updatedFeaturePoints = [];\r\n            const addedFeaturePoints = [];\r\n            for (let i = 0; i < numberOfFeaturePoints; i++) {\r\n                const rawIndex: number = i * 5;\r\n                const id = featurePointRawData[rawIndex + 4];\r\n\r\n                // IDs should be durable across frames and strictly increasing from 0 up, so use them as indexing into the feature point array.\r\n                if (!this._featurePointCloud[id]) {\r\n                    this._featurePointCloud[id] = { position: new Vector3(), confidenceValue: 0 };\r\n                    addedFeaturePoints.push(id);\r\n                } else {\r\n                    updatedFeaturePoints.push(id);\r\n                }\r\n\r\n                // Set the feature point values.\r\n                this._featurePointCloud[id].position.x = featurePointRawData[rawIndex];\r\n                this._featurePointCloud[id].position.y = featurePointRawData[rawIndex + 1];\r\n                this._featurePointCloud[id].position.z = featurePointRawData[rawIndex + 2];\r\n                this._featurePointCloud[id].confidenceValue = featurePointRawData[rawIndex + 3];\r\n            }\r\n\r\n            // Signal observers that feature points have been added if necessary.\r\n            if (addedFeaturePoints.length > 0) {\r\n                this.onFeaturePointsAddedObservable.notifyObservers(addedFeaturePoints);\r\n            }\r\n\r\n            // Signal observers that feature points have been updated if necessary.\r\n            if (updatedFeaturePoints.length > 0) {\r\n                this.onFeaturePointsUpdatedObservable.notifyObservers(updatedFeaturePoints);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Initializes the feature. If the feature point feature is not available for this environment do not mark the feature as enabled.\r\n     */\r\n    private _init() {\r\n        if (!this._xrSessionManager.session.trySetFeaturePointCloudEnabled || !this._xrSessionManager.session.trySetFeaturePointCloudEnabled(true)) {\r\n            // fail silently\r\n            return;\r\n        }\r\n\r\n        this._enabled = true;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRFeaturePointSystem.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRFeaturePointSystem(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRFeaturePointSystem.Name,\r\n        (xrSessionManager) => {\r\n            return () => new WebXRFeaturePointSystem(xrSessionManager);\r\n        },\r\n        WebXRFeaturePointSystem.Version\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Matrix, Quaternion } from \"../../Maths/math\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Options used in the mesh detector module\r\n */\r\nexport interface IWebXRMeshDetectorOptions {\r\n    /**\r\n     * The node to use to transform the local results to world coordinates\r\n     */\r\n    worldParentNode?: TransformNode;\r\n    /**\r\n     * If set to true a reference of the created meshes will be kept until the next session starts\r\n     * If not defined, meshes will be removed from the array when the feature is detached or the session ended.\r\n     */\r\n    doNotRemoveMeshesOnSessionEnded?: boolean;\r\n    /**\r\n     * Preferred detector configuration, not all preferred options will be supported by all platforms.\r\n     * Babylon native only!\r\n     */\r\n    preferredDetectorOptions?: XRGeometryDetectorOptions;\r\n    /**\r\n     * If set to true, WebXRMeshDetector will convert coordinate systems for meshes.\r\n     * If not defined, mesh conversions from right handed to left handed coordinate systems won't be conducted.\r\n     * Right handed mesh data will be available through IWebXRVertexData.xrMesh.\r\n     */\r\n    convertCoordinateSystems?: boolean;\r\n\r\n    /**\r\n     * If set to true, the feature will generate meshes for the detected data.\r\n     * Note that this might be time consuming, as the mesh's vertex data will be updated on every change.\r\n     * Setting this to true will also set convertCoordinateSystems to true.\r\n     * Note - the meshes will NOT be disposed automatically when the feature is detached or the session ended.\r\n     */\r\n    generateMeshes?: boolean;\r\n}\r\n\r\n/**\r\n * A babylon interface for a XR mesh's vertex data.\r\n */\r\nexport interface IWebXRVertexData {\r\n    /**\r\n     * A babylon-assigned ID for this mesh\r\n     */\r\n    id: number;\r\n    /**\r\n     * Data required for constructing a mesh in Babylon.js.\r\n     */\r\n    xrMesh: XRMesh;\r\n    /**\r\n     * The semantic classification supplied by the XR runtime.\r\n     * This is undefined when the runtime does not expose semantic labels and null when the mesh has no known classification.\r\n     */\r\n    semanticLabel?: string | null;\r\n    /**\r\n     * The node to use to transform the local results to world coordinates.\r\n     * WorldParentNode will only exist if it was declared in the IWebXRMeshDetectorOptions.\r\n     */\r\n    worldParentNode?: TransformNode;\r\n    /**\r\n     * An array of vertex positions in babylon space. right/left hand system is taken into account.\r\n     * Positions will only be calculated if convertCoordinateSystems is set to true in the IWebXRMeshDetectorOptions.\r\n     */\r\n    positions?: Float32Array;\r\n    /**\r\n     * An array of indices in babylon space. Indices have a counterclockwise winding order.\r\n     * Indices will only be populated if convertCoordinateSystems is set to true in the IWebXRMeshDetectorOptions.\r\n     */\r\n    indices?: Uint32Array;\r\n    /**\r\n     * An array of vertex normals in babylon space. right/left hand system is taken into account.\r\n     * Normals will not be calculated if convertCoordinateSystems is undefined in the IWebXRMeshDetectorOptions.\r\n     * Different platforms may or may not support mesh normals when convertCoordinateSystems is set to true.\r\n     */\r\n    normals?: Float32Array;\r\n    /**\r\n     * A transformation matrix to apply on the mesh that will be built using the meshDefinition.\r\n     * Local vs. World are decided if worldParentNode was provided or not in the options when constructing the module.\r\n     * TransformationMatrix will only be calculated if convertCoordinateSystems is set to true in the IWebXRMeshDetectorOptions.\r\n     */\r\n    transformationMatrix?: Matrix;\r\n\r\n    /**\r\n     * If generateMeshes is set to true in the IWebXRMeshDetectorOptions, this will be the generated mesh.\r\n     * This mesh will be updated with the vertex data provided and not regenerated every time.\r\n     */\r\n    mesh?: Mesh;\r\n}\r\n\r\nlet MeshIdProvider = 0;\r\n\r\n/**\r\n * The mesh detector is used to detect meshes in the real world when in AR\r\n */\r\nexport class WebXRMeshDetector extends WebXRAbstractFeature {\r\n    private _detectedMeshes: Map<XRMesh, IWebXRVertexData> = new Map<XRMesh, IWebXRVertexData>();\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.MESH_DETECTION;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Observers registered here will be executed when a new mesh was added to the session\r\n     */\r\n    public onMeshAddedObservable: Observable<IWebXRVertexData> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when a mesh is no longer detected in the session\r\n     */\r\n    public onMeshRemovedObservable: Observable<IWebXRVertexData> = new Observable();\r\n    /**\r\n     * Observers registered here will be executed when an existing mesh updates\r\n     */\r\n    public onMeshUpdatedObservable: Observable<IWebXRVertexData> = new Observable();\r\n\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private _options: IWebXRMeshDetectorOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"mesh-detection\";\r\n        if (this._options.generateMeshes) {\r\n            this._options.convertCoordinateSystems = true;\r\n        }\r\n        if (this._xrSessionManager.session) {\r\n            this._init();\r\n        } else {\r\n            this._xrSessionManager.onXRSessionInit.addOnce(() => {\r\n                this._init();\r\n            });\r\n        }\r\n    }\r\n\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        // Only supported by BabylonNative\r\n        if (!!this._xrSessionManager.isNative && !!this._xrSessionManager.session.trySetMeshDetectorEnabled) {\r\n            this._xrSessionManager.session.trySetMeshDetectorEnabled(false);\r\n        }\r\n\r\n        if (!this._options.doNotRemoveMeshesOnSessionEnded) {\r\n            this._detectedMeshes.forEach((mesh) => {\r\n                this.onMeshRemovedObservable.notifyObservers(mesh);\r\n            });\r\n\r\n            this._detectedMeshes.clear();\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this.onMeshAddedObservable.clear();\r\n        this.onMeshRemovedObservable.clear();\r\n        this.onMeshUpdatedObservable.clear();\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        // TODO remove try catch\r\n        try {\r\n            if (!this.attached || !frame) {\r\n                return;\r\n            }\r\n\r\n            // babylon native XR and webxr support\r\n            const detectedMeshes = frame.detectedMeshes || frame.worldInformation?.detectedMeshes;\r\n            if (detectedMeshes) {\r\n                const toRemove = new Set<XRMesh>();\r\n                this._detectedMeshes.forEach((vertexData, xrMesh) => {\r\n                    if (!detectedMeshes.has(xrMesh)) {\r\n                        toRemove.add(xrMesh);\r\n                    }\r\n                });\r\n                toRemove.forEach((xrMesh) => {\r\n                    const vertexData = this._detectedMeshes.get(xrMesh);\r\n                    if (vertexData) {\r\n                        this.onMeshRemovedObservable.notifyObservers(vertexData);\r\n                        this._detectedMeshes.delete(xrMesh);\r\n                    }\r\n                });\r\n\r\n                // now check for new ones\r\n                detectedMeshes.forEach((xrMesh) => {\r\n                    if (!this._detectedMeshes.has(xrMesh)) {\r\n                        const partialVertexData: Partial<IWebXRVertexData> = {\r\n                            id: MeshIdProvider++,\r\n                            xrMesh: xrMesh,\r\n                        };\r\n                        const vertexData = this._updateVertexDataWithXRMesh(xrMesh, partialVertexData, frame);\r\n                        this._detectedMeshes.set(xrMesh, vertexData);\r\n                        this.onMeshAddedObservable.notifyObservers(vertexData);\r\n                    } else {\r\n                        // updated?\r\n                        if (xrMesh.lastChangedTime === this._xrSessionManager.currentTimestamp) {\r\n                            const vertexData = this._detectedMeshes.get(xrMesh);\r\n                            if (vertexData) {\r\n                                this._updateVertexDataWithXRMesh(xrMesh, vertexData, frame);\r\n                                this.onMeshUpdatedObservable.notifyObservers(vertexData);\r\n                            }\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n        } catch (error) {\r\n            Logger.Log(error.stack);\r\n        }\r\n    }\r\n\r\n    private _init() {\r\n        // Only supported by BabylonNative\r\n        if (this._xrSessionManager.isNative) {\r\n            if (this._xrSessionManager.session.trySetMeshDetectorEnabled) {\r\n                this._xrSessionManager.session.trySetMeshDetectorEnabled(true);\r\n            }\r\n\r\n            if (!!this._options.preferredDetectorOptions && !!this._xrSessionManager.session.trySetPreferredMeshDetectorOptions) {\r\n                this._xrSessionManager.session.trySetPreferredMeshDetectorOptions(this._options.preferredDetectorOptions);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _updateVertexDataWithXRMesh(xrMesh: XRMesh, mesh: Partial<IWebXRVertexData>, xrFrame: XRFrame): IWebXRVertexData {\r\n        mesh.xrMesh = xrMesh;\r\n        mesh.semanticLabel = xrMesh.semanticLabel;\r\n        mesh.worldParentNode = this._options.worldParentNode;\r\n        const positions = xrMesh.vertices || xrMesh.positions;\r\n\r\n        if (this._options.convertCoordinateSystems) {\r\n            if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                mesh.positions = new Float32Array(positions.length);\r\n                for (let i = 0; i < positions.length; i += 3) {\r\n                    mesh.positions[i] = positions[i];\r\n                    mesh.positions[i + 1] = positions[i + 1];\r\n                    mesh.positions[i + 2] = -1 * positions[i + 2];\r\n                }\r\n\r\n                if (xrMesh.normals) {\r\n                    mesh.normals = new Float32Array(xrMesh.normals.length);\r\n                    for (let i = 0; i < xrMesh.normals.length; i += 3) {\r\n                        mesh.normals[i] = xrMesh.normals[i];\r\n                        mesh.normals[i + 1] = xrMesh.normals[i + 1];\r\n                        mesh.normals[i + 2] = -1 * xrMesh.normals[i + 2];\r\n                    }\r\n                }\r\n            } else {\r\n                mesh.positions = positions;\r\n                mesh.normals = xrMesh.normals;\r\n            }\r\n\r\n            // WebXR should provide indices in a counterclockwise winding order regardless of coordinate system handedness\r\n            mesh.indices = xrMesh.indices;\r\n\r\n            // matrix\r\n            const pose = xrFrame.getPose(xrMesh.meshSpace, this._xrSessionManager.referenceSpace);\r\n            if (pose) {\r\n                const mat = mesh.transformationMatrix || new Matrix();\r\n                Matrix.FromArrayToRef(pose.transform.matrix, 0, mat);\r\n                if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                    mat.toggleModelMatrixHandInPlace();\r\n                }\r\n                mesh.transformationMatrix = mat;\r\n                if (this._options.worldParentNode) {\r\n                    mat.multiplyToRef(this._options.worldParentNode.getWorldMatrix(), mat);\r\n                }\r\n            }\r\n\r\n            if (this._options.generateMeshes) {\r\n                if (!mesh.mesh) {\r\n                    const generatedMesh = new Mesh(\"xr mesh \" + mesh.id, this._xrSessionManager.scene);\r\n                    generatedMesh.rotationQuaternion = new Quaternion();\r\n                    generatedMesh.setVerticesData(VertexBuffer.PositionKind, mesh.positions);\r\n                    if (mesh.normals) {\r\n                        generatedMesh.setVerticesData(VertexBuffer.NormalKind, mesh.normals);\r\n                    } else {\r\n                        generatedMesh.createNormals(true);\r\n                    }\r\n                    generatedMesh.setIndices(mesh.indices, undefined, true);\r\n                    mesh.mesh = generatedMesh;\r\n                } else {\r\n                    const generatedMesh = mesh.mesh;\r\n                    generatedMesh.updateVerticesData(VertexBuffer.PositionKind, mesh.positions);\r\n                    if (mesh.normals) {\r\n                        generatedMesh.updateVerticesData(VertexBuffer.NormalKind, mesh.normals);\r\n                    } else {\r\n                        generatedMesh.createNormals(true);\r\n                    }\r\n                    generatedMesh.updateIndices(mesh.indices);\r\n                }\r\n                mesh.transformationMatrix?.decompose(mesh.mesh.scaling, mesh.mesh.rotationQuaternion!, mesh.mesh.position);\r\n            }\r\n        }\r\n\r\n        return <IWebXRVertexData>mesh;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRMeshDetector.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRMeshDetector(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRMeshDetector.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRMeshDetector(xrSessionManager, options);\r\n        },\r\n        WebXRMeshDetector.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Logger } from \"../../Misc/logger\";\r\n\r\n/**\r\n * Options interface for the background remover plugin\r\n */\r\nexport interface IWebXRImageTrackingOptions {\r\n    /**\r\n     * A required array with images to track\r\n     */\r\n    images: {\r\n        /**\r\n         * The source of the image. can be a URL or an image bitmap\r\n         */\r\n        src: string | ImageBitmap;\r\n        /**\r\n         * The estimated width in the real world (in meters)\r\n         */\r\n        estimatedRealWorldWidth: number; // In meters!\r\n    }[];\r\n}\r\n\r\n/**\r\n * An object representing an image tracked by the system\r\n */\r\nexport interface IWebXRTrackedImage {\r\n    /**\r\n     * The ID of this image (which is the same as the position in the array that was used to initialize the feature)\r\n     */\r\n    id: number;\r\n    /**\r\n     * Is the transformation provided emulated. If it is, the system \"guesses\" its real position. Otherwise it can be considered as exact position.\r\n     */\r\n    emulated?: boolean;\r\n    /**\r\n     * Just in case it is needed - the image bitmap that is being tracked\r\n     */\r\n    originalBitmap: ImageBitmap;\r\n    /**\r\n     * The native XR result image tracking result, untouched\r\n     */\r\n    xrTrackingResult?: XRImageTrackingResult;\r\n    /**\r\n     * Width in real world (meters)\r\n     */\r\n    realWorldWidth?: number;\r\n    /**\r\n     * A transformation matrix of this current image in the current reference space.\r\n     */\r\n    transformationMatrix: Matrix;\r\n    /**\r\n     * The width/height ratio of this image. can be used to calculate the size of the detected object/image\r\n     */\r\n    ratio?: number;\r\n}\r\n\r\n/**\r\n * Enum that describes the state of the image trackability score status for this session.\r\n */\r\nenum ImageTrackingScoreStatus {\r\n    // AR Session has not yet assessed image trackability scores.\r\n    NotReceived,\r\n    // A request to retrieve trackability scores has been sent, but no response has been received.\r\n    Waiting,\r\n    // Image trackability scores have been received for this session\r\n    Received,\r\n}\r\n\r\n/**\r\n * Image tracking for immersive AR sessions.\r\n * Providing a list of images and their estimated widths will enable tracking those images in the real world.\r\n */\r\nexport class WebXRImageTracking extends WebXRAbstractFeature {\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.IMAGE_TRACKING;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * This will be triggered if the underlying system deems an image untrackable.\r\n     * The index is the index of the image from the array used to initialize the feature.\r\n     */\r\n    public onUntrackableImageFoundObservable: Observable<number> = new Observable();\r\n    /**\r\n     * An image was deemed trackable, and the system will start tracking it.\r\n     */\r\n    public onTrackableImageFoundObservable: Observable<IWebXRTrackedImage> = new Observable();\r\n    /**\r\n     * The image was found and its state was updated.\r\n     */\r\n    public onTrackedImageUpdatedObservable: Observable<IWebXRTrackedImage> = new Observable();\r\n\r\n    private _trackableScoreStatus: ImageTrackingScoreStatus = ImageTrackingScoreStatus.NotReceived;\r\n    private _trackedImages: IWebXRTrackedImage[] = [];\r\n\r\n    private _originalTrackingRequest: XRTrackedImageInit[];\r\n\r\n    /**\r\n     * constructs the image tracking feature\r\n     * @param _xrSessionManager the session manager for this module\r\n     * @param options read-only options to be used in this module\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * read-only options to be used in this module\r\n         */\r\n        public readonly options: IWebXRImageTrackingOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"image-tracking\";\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        return super.attach();\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        return super.detach();\r\n    }\r\n\r\n    /**\r\n     * Get a tracked image by its ID.\r\n     *\r\n     * @param id the id of the image to load (position in the init array)\r\n     * @returns a trackable image, if exists in this location\r\n     */\r\n    public getTrackedImageById(id: number): Nullable<IWebXRTrackedImage> {\r\n        return this._trackedImages[id] || null;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        for (const trackedImage of this._trackedImages) {\r\n            trackedImage.originalBitmap.close();\r\n        }\r\n        this._trackedImages.length = 0;\r\n        this.onTrackableImageFoundObservable.clear();\r\n        this.onUntrackableImageFoundObservable.clear();\r\n        this.onTrackedImageUpdatedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Extends the session init object if needed\r\n     * @returns augmentation object fo the xr session init object.\r\n     */\r\n    public async getXRSessionInitExtension(): Promise<Partial<XRSessionInit>> {\r\n        if (!this.options.images || !this.options.images.length) {\r\n            return {};\r\n        }\r\n        const promises = this.options.images.map(async (image) => {\r\n            if (typeof image.src === \"string\") {\r\n                return await this._xrSessionManager.scene.getEngine()._createImageBitmapFromSource(image.src);\r\n            } else {\r\n                return image.src;\r\n            }\r\n        });\r\n\r\n        try {\r\n            const images = await Promise.all(promises);\r\n\r\n            this._originalTrackingRequest = images.map((image, idx) => {\r\n                return {\r\n                    image,\r\n                    widthInMeters: this.options.images[idx].estimatedRealWorldWidth,\r\n                };\r\n            });\r\n\r\n            return {\r\n                trackedImages: this._originalTrackingRequest,\r\n            };\r\n        } catch (ex) {\r\n            Logger.Error(\"Error loading images for tracking, WebXRImageTracking disabled for this session.\");\r\n            return {};\r\n        }\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame) {\r\n        if (!_xrFrame.getImageTrackingResults || this._trackableScoreStatus === ImageTrackingScoreStatus.Waiting) {\r\n            return;\r\n        }\r\n\r\n        // Image tracking scores may be generated a few frames after the XR Session initializes.\r\n        // If we haven't received scores yet, then kick off the task to check scores and return immediately.\r\n        if (this._trackableScoreStatus === ImageTrackingScoreStatus.NotReceived) {\r\n            // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n            this._checkScoresAsync();\r\n            return;\r\n        }\r\n\r\n        const imageTrackedResults = _xrFrame.getImageTrackingResults();\r\n        for (const result of imageTrackedResults) {\r\n            let changed = false;\r\n            const imageIndex = result.index;\r\n\r\n            const imageObject = this._trackedImages[imageIndex];\r\n            if (!imageObject) {\r\n                // something went wrong!\r\n                continue;\r\n            }\r\n\r\n            imageObject.xrTrackingResult = result;\r\n            if (imageObject.realWorldWidth !== result.measuredWidthInMeters) {\r\n                imageObject.realWorldWidth = result.measuredWidthInMeters;\r\n                changed = true;\r\n            }\r\n\r\n            // Get the pose of the image relative to a reference space.\r\n            const pose = _xrFrame.getPose(result.imageSpace, this._xrSessionManager.referenceSpace);\r\n\r\n            if (pose) {\r\n                const mat = imageObject.transformationMatrix;\r\n                Matrix.FromArrayToRef(pose.transform.matrix, 0, mat);\r\n                if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                    mat.toggleModelMatrixHandInPlace();\r\n                }\r\n                changed = true;\r\n            }\r\n\r\n            const state = result.trackingState;\r\n            const emulated = state === \"emulated\";\r\n\r\n            if (imageObject.emulated !== emulated) {\r\n                imageObject.emulated = emulated;\r\n                changed = true;\r\n            }\r\n            if (changed) {\r\n                this.onTrackedImageUpdatedObservable.notifyObservers(imageObject);\r\n            }\r\n        }\r\n    }\r\n\r\n    private async _checkScoresAsync(): Promise<void> {\r\n        if (!this._xrSessionManager.session.getTrackedImageScores || this._trackableScoreStatus !== ImageTrackingScoreStatus.NotReceived) {\r\n            return;\r\n        }\r\n\r\n        this._trackableScoreStatus = ImageTrackingScoreStatus.Waiting;\r\n        const imageScores = await this._xrSessionManager.session.getTrackedImageScores();\r\n        if (!imageScores || imageScores.length === 0) {\r\n            this._trackableScoreStatus = ImageTrackingScoreStatus.NotReceived;\r\n            return;\r\n        }\r\n\r\n        // check the scores for all\r\n        for (let idx = 0; idx < imageScores.length; ++idx) {\r\n            if (imageScores[idx] == \"untrackable\") {\r\n                this.onUntrackableImageFoundObservable.notifyObservers(idx);\r\n            } else {\r\n                const originalBitmap = this._originalTrackingRequest[idx].image;\r\n                const imageObject: IWebXRTrackedImage = {\r\n                    id: idx,\r\n                    originalBitmap,\r\n                    transformationMatrix: new Matrix(),\r\n                    ratio: originalBitmap.width / originalBitmap.height,\r\n                };\r\n                this._trackedImages[idx] = imageObject;\r\n                this.onTrackableImageFoundObservable.notifyObservers(imageObject);\r\n            }\r\n        }\r\n\r\n        this._trackableScoreStatus = imageScores.length > 0 ? ImageTrackingScoreStatus.Received : ImageTrackingScoreStatus.NotReceived;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRImageTracking.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRImageTracking(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRImageTracking.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRImageTracking(xrSessionManager, options);\r\n        },\r\n        WebXRImageTracking.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\n\r\n/**\r\n * Options for DOM Overlay feature\r\n */\r\nexport interface IWebXRDomOverlayOptions {\r\n    /**\r\n     * DOM Element or document query selector string for overlay.\r\n     *\r\n     * NOTE: UA may make this element background transparent in XR.\r\n     */\r\n    element: Element | string;\r\n    /**\r\n     * Supress XR Select events on container element (DOM blocks interaction to scene).\r\n     */\r\n    supressXRSelectEvents?: boolean;\r\n}\r\n\r\n/**\r\n * Type of DOM overlay provided by UA.\r\n */\r\ntype WebXRDomOverlayType =\r\n    /**\r\n     * Covers the entire physical screen for a screen-based device, for example handheld AR\r\n     */\r\n    | \"screen\"\r\n    /**\r\n     * Appears as a floating rectangle in space\r\n     */\r\n    | \"floating\"\r\n    /**\r\n     * Follows the user’s head movement consistently, appearing similar to a HUD\r\n     */\r\n    | \"head-locked\";\r\n\r\n/**\r\n * DOM Overlay Feature\r\n *\r\n * @since 5.0.0\r\n */\r\nexport class WebXRDomOverlay extends WebXRAbstractFeature {\r\n    /**\r\n     * Type of overlay - non-null when available\r\n     */\r\n    private _domOverlayType: Nullable<WebXRDomOverlayType> = null;\r\n\r\n    /**\r\n     * Event Listener to supress \"beforexrselect\" events.\r\n     */\r\n    private _beforeXRSelectListener: Nullable<EventListenerOrEventListenerObject> = null;\r\n\r\n    /**\r\n     * Element used for overlay\r\n     */\r\n    private _element: Nullable<Element> = null;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.DOM_OVERLAY;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Creates a new instance of the dom-overlay feature\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param options options to use when constructing this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * options to use when constructing this feature\r\n         */\r\n        public readonly options: IWebXRDomOverlayOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"dom-overlay\";\r\n\r\n        // https://immersive-web.github.io/dom-overlays/\r\n        Logger.Warn(\"dom-overlay is an experimental and unstable feature.\");\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        // Feature not available\r\n        if (!this._xrSessionManager.session.domOverlayState || this._xrSessionManager.session.domOverlayState.type === null) {\r\n            return false;\r\n        }\r\n\r\n        this._domOverlayType = this._xrSessionManager.session.domOverlayState.type;\r\n\r\n        if (this._element !== null && this.options.supressXRSelectEvents === true) {\r\n            this._beforeXRSelectListener = (ev) => {\r\n                ev.preventDefault();\r\n            };\r\n            this._element.addEventListener(\"beforexrselect\", this._beforeXRSelectListener);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * The type of DOM overlay (null when not supported).  Provided by UA and remains unchanged for duration of session.\r\n     */\r\n    public get domOverlayType(): Nullable<WebXRDomOverlayType> {\r\n        return this._domOverlayType;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        if (this._element !== null && this._beforeXRSelectListener) {\r\n            this._element.removeEventListener(\"beforexrselect\", this._beforeXRSelectListener);\r\n        }\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame): void {\r\n        /* empty */\r\n    }\r\n\r\n    /**\r\n     * Extends the session init object if needed\r\n     * @returns augmentation object for the xr session init object.\r\n     */\r\n    public async getXRSessionInitExtension(): Promise<Partial<XRSessionInit>> {\r\n        if (this.options.element === undefined) {\r\n            Logger.Warn('\"element\" option must be provided to attach xr-dom-overlay feature.');\r\n            return {};\r\n        } else if (typeof this.options.element === \"string\") {\r\n            const selectedElement = document.querySelector(this.options.element);\r\n            if (selectedElement === null) {\r\n                Logger.Warn(`element not found '${this.options.element}' (not requesting xr-dom-overlay)`);\r\n                return {};\r\n            }\r\n            this._element = selectedElement;\r\n        } else {\r\n            this._element = this.options.element;\r\n        }\r\n\r\n        return {\r\n            domOverlay: {\r\n                root: this._element,\r\n            },\r\n        };\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRDOMOverlay.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRDOMOverlay(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRDomOverlay.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRDomOverlay(xrSessionManager, options);\r\n        },\r\n        WebXRDomOverlay.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type Observer } from \"../../Misc/observable.pure\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebXRInput } from \"../webXRInput\";\r\nimport { type WebXRInputSource } from \"../webXRInputSource\";\r\nimport { WebXRControllerComponent, type IWebXRMotionControllerAxesValue, type IWebXRMotionControllerComponentChangesValues } from \"../motionController/webXRControllerComponent\";\r\n\r\nimport { Matrix, Quaternion, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type MotionControllerComponentType } from \"../motionController/webXRAbstractMotionController\";\r\nimport { Logger } from \"../../Misc/logger\";\r\n\r\n/**\r\n * The options container for the controller movement module\r\n */\r\nexport interface IWebXRControllerMovementOptions {\r\n    /**\r\n     * Override default behaviour and provide your own movement controls\r\n     */\r\n    customRegistrationConfigurations?: WebXRControllerMovementRegistrationConfiguration[];\r\n    /**\r\n     * Is movement enabled\r\n     */\r\n    movementEnabled?: boolean;\r\n    /**\r\n     * Camera direction follows view pose and movement by default will move independently of the viewer's pose.\r\n     */\r\n    movementOrientationFollowsViewerPose: boolean;\r\n    /**\r\n     * Movement speed factor (default is 1.0)\r\n     */\r\n    movementSpeed?: number;\r\n    /**\r\n     * Minimum threshold the controller's thumbstick/touchpad must pass before being recognized for movement (avoids jitter/unintentional movement)\r\n     */\r\n    movementThreshold?: number;\r\n    /**\r\n     * Is rotation enabled\r\n     */\r\n    rotationEnabled?: boolean;\r\n    /**\r\n     * Minimum threshold the controller's thumstick/touchpad must pass before being recognized for rotation (avoids jitter/unintentional rotation)\r\n     */\r\n    rotationThreshold?: number;\r\n    /**\r\n     * Movement speed factor (default is 1.0)\r\n     */\r\n    rotationSpeed?: number;\r\n    /**\r\n     * Babylon XR Input class for controller\r\n     */\r\n    xrInput: WebXRInput;\r\n\r\n    /**\r\n     * If movement orientation should follow controller orientation instead of viewer pose.\r\n     * Make sure to set movementOrientationFollowsViewerPose to false, otherwise it will be ignored.\r\n     */\r\n    movementOrientationFollowsController: boolean;\r\n\r\n    /**\r\n     * If orientation follows the controller, this is the preferred handedness to use for forward movement.\r\n     * If not set (or handedness not found), the handedness will be selected by the controller triggering the movement.\r\n     * Note that this only works if movementOrientationFollowsController is true.\r\n     */\r\n    orientationPreferredHandedness?: XRHandedness;\r\n}\r\n\r\n/**\r\n * Feature context is used in handlers and on each XR frame to control the camera movement/direction.\r\n */\r\nexport type WebXRControllerMovementFeatureContext = {\r\n    movementEnabled: boolean;\r\n    movementOrientationFollowsViewerPose: boolean;\r\n    movementOrientationFollowsController: boolean;\r\n    orientationPreferredHandedness?: XRHandedness;\r\n    movementSpeed: number;\r\n    movementThreshold: number;\r\n    rotationEnabled: boolean;\r\n    rotationSpeed: number;\r\n    rotationThreshold: number;\r\n};\r\n\r\n/**\r\n * Current state of Movements shared across components and handlers.\r\n */\r\nexport type WebXRControllerMovementState = {\r\n    moveX: number;\r\n    moveY: number;\r\n    rotateX: number;\r\n    rotateY: number;\r\n};\r\n\r\n/**\r\n * Button of Axis Handler must be specified.\r\n */\r\nexport type WebXRControllerMovementRegistrationConfiguration = {\r\n    /**\r\n     * handlers are filtered to these types only\r\n     */\r\n    allowedComponentTypes?: MotionControllerComponentType[];\r\n    /**\r\n     * For registering movement to specific hand only.  Useful if your app has a \"main hand\" and \"off hand\" for determining the functionality of a controller.\r\n     */\r\n    forceHandedness?: XRHandedness;\r\n    /**\r\n     * For main component only (useful for buttons and may not trigger axis changes).\r\n     */\r\n    mainComponentOnly?: boolean;\r\n    /**\r\n     * Additional predicate to apply to controllers to restrict a handler being added.\r\n     */\r\n    componentSelectionPredicate?: (xrController: WebXRInputSource) => Nullable<WebXRControllerComponent>;\r\n} & (\r\n    | {\r\n          /**\r\n           * Called when axis changes occur.\r\n           */\r\n          axisChangedHandler: (\r\n              axes: IWebXRMotionControllerAxesValue,\r\n              movementState: WebXRControllerMovementState,\r\n              featureContext: WebXRControllerMovementFeatureContext,\r\n              xrInput: WebXRInput\r\n          ) => void;\r\n      }\r\n    | {\r\n          /**\r\n           * Called when the button state changes.\r\n           */\r\n          buttonChangedHandler: (\r\n              pressed: IWebXRMotionControllerComponentChangesValues<boolean>,\r\n              movementState: WebXRControllerMovementState,\r\n              featureContext: WebXRControllerMovementFeatureContext,\r\n              xrInput: WebXRInput\r\n          ) => void;\r\n      }\r\n);\r\n\r\ntype RegisteredComponent = {\r\n    registrationConfiguration: WebXRControllerMovementRegistrationConfiguration;\r\n    component: WebXRControllerComponent;\r\n    onAxisChangedObserver?: Nullable<Observer<IWebXRMotionControllerAxesValue>>;\r\n    onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n};\r\n\r\n/**\r\n * This is a movement feature to be used with WebXR-enabled motion controllers.\r\n * When enabled and attached, the feature will allow a user to move around and rotate in the scene using\r\n * the input of the attached controllers.\r\n */\r\nexport class WebXRControllerMovement extends WebXRAbstractFeature {\r\n    private _controllers: {\r\n        [controllerUniqueId: string]: {\r\n            xrController: WebXRInputSource;\r\n            registeredComponents: RegisteredComponent[];\r\n        };\r\n    } = {};\r\n\r\n    private _currentRegistrationConfigurations: WebXRControllerMovementRegistrationConfiguration[] = [];\r\n    // Feature configuration is synchronized - this is passed to all handlers (reduce GC pressure).\r\n    private _featureContext: WebXRControllerMovementFeatureContext;\r\n    // forward direction for movement, which may differ from viewer pose.\r\n    private _movementDirection: Quaternion = new Quaternion();\r\n    private _movementState: WebXRControllerMovementState;\r\n    private _xrInput: WebXRInput;\r\n\r\n    // unused\r\n    private _tmpRotationMatrix: Matrix = Matrix.Identity();\r\n    private _tmpTranslationDirection: Vector3 = new Vector3();\r\n    private _tmpMovementTranslation: Vector3 = new Vector3();\r\n    private _tempCacheQuaternion: Quaternion = new Quaternion();\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.MOVEMENT;\r\n\r\n    /**\r\n     * Standard controller configurations.\r\n     */\r\n    public static readonly REGISTRATIONS: { [key: string]: WebXRControllerMovementRegistrationConfiguration[] } = {\r\n        default: [\r\n            {\r\n                allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],\r\n                forceHandedness: \"left\",\r\n                axisChangedHandler: (axes: IWebXRMotionControllerAxesValue, movementState: WebXRControllerMovementState, featureContext: WebXRControllerMovementFeatureContext) => {\r\n                    movementState.rotateX = Math.abs(axes.x) > featureContext.rotationThreshold ? axes.x : 0;\r\n                    movementState.rotateY = Math.abs(axes.y) > featureContext.rotationThreshold ? axes.y : 0;\r\n                },\r\n            },\r\n            {\r\n                allowedComponentTypes: [WebXRControllerComponent.THUMBSTICK_TYPE, WebXRControllerComponent.TOUCHPAD_TYPE],\r\n                forceHandedness: \"right\",\r\n                axisChangedHandler: (axes: IWebXRMotionControllerAxesValue, movementState: WebXRControllerMovementState, featureContext: WebXRControllerMovementFeatureContext) => {\r\n                    movementState.moveX = Math.abs(axes.x) > featureContext.movementThreshold ? axes.x : 0;\r\n                    movementState.moveY = Math.abs(axes.y) > featureContext.movementThreshold ? axes.y : 0;\r\n                },\r\n            },\r\n        ],\r\n    };\r\n\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the webxr specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Current movement direction.  Will be null before XR Frames have been processed.\r\n     */\r\n    public get movementDirection(): Quaternion {\r\n        return this._movementDirection;\r\n    }\r\n\r\n    /**\r\n     * Is movement enabled\r\n     */\r\n    public get movementEnabled(): boolean {\r\n        return this._featureContext.movementEnabled;\r\n    }\r\n\r\n    /**\r\n     * Sets whether movement is enabled or not\r\n     * @param enabled is movement enabled\r\n     */\r\n    public set movementEnabled(enabled: boolean) {\r\n        this._featureContext.movementEnabled = enabled;\r\n    }\r\n\r\n    /**\r\n     * If movement follows viewer pose\r\n     */\r\n    public get movementOrientationFollowsViewerPose(): boolean {\r\n        return this._featureContext.movementOrientationFollowsViewerPose;\r\n    }\r\n\r\n    /**\r\n     * Sets whether movement follows viewer pose\r\n     * @param followsPose is movement should follow viewer pose\r\n     */\r\n    public set movementOrientationFollowsViewerPose(followsPose: boolean) {\r\n        this._featureContext.movementOrientationFollowsViewerPose = followsPose;\r\n    }\r\n\r\n    /**\r\n     * Gets movement speed\r\n     */\r\n    public get movementSpeed(): number {\r\n        return this._featureContext.movementSpeed;\r\n    }\r\n\r\n    /**\r\n     * Sets movement speed\r\n     * @param movementSpeed movement speed\r\n     */\r\n    public set movementSpeed(movementSpeed: number) {\r\n        this._featureContext.movementSpeed = movementSpeed;\r\n    }\r\n\r\n    /**\r\n     * Gets minimum threshold the controller's thumbstick/touchpad must pass before being recognized for movement (avoids jitter/unintentional movement)\r\n     */\r\n    public get movementThreshold(): number {\r\n        return this._featureContext.movementThreshold;\r\n    }\r\n\r\n    /**\r\n     * Sets minimum threshold the controller's thumbstick/touchpad must pass before being recognized for movement (avoids jitter/unintentional movement)\r\n     * @param movementThreshold new threshold\r\n     */\r\n    public set movementThreshold(movementThreshold: number) {\r\n        this._featureContext.movementThreshold = movementThreshold;\r\n    }\r\n\r\n    /**\r\n     * Is rotation enabled\r\n     */\r\n    public get rotationEnabled(): boolean {\r\n        return this._featureContext.rotationEnabled;\r\n    }\r\n\r\n    /**\r\n     * Sets whether rotation is enabled or not\r\n     * @param enabled is rotation enabled\r\n     */\r\n    public set rotationEnabled(enabled: boolean) {\r\n        this._featureContext.rotationEnabled = enabled;\r\n    }\r\n\r\n    /**\r\n     * Gets rotation speed factor\r\n     */\r\n    public get rotationSpeed(): number {\r\n        return this._featureContext.rotationSpeed;\r\n    }\r\n\r\n    /**\r\n     * Sets rotation speed factor (1.0 is default)\r\n     * @param rotationSpeed new rotation speed factor\r\n     */\r\n    public set rotationSpeed(rotationSpeed: number) {\r\n        this._featureContext.rotationSpeed = rotationSpeed;\r\n    }\r\n\r\n    /**\r\n     * Gets minimum threshold the controller's thumbstick/touchpad must pass before being recognized for rotation (avoids jitter/unintentional rotation)\r\n     */\r\n    public get rotationThreshold(): number {\r\n        return this._featureContext.rotationThreshold;\r\n    }\r\n\r\n    /**\r\n     * Sets minimum threshold the controller's thumbstick/touchpad must pass before being recognized for rotation (avoids jitter/unintentional rotation)\r\n     * @param threshold new threshold\r\n     */\r\n    public set rotationThreshold(threshold: number) {\r\n        this._featureContext.rotationThreshold = threshold;\r\n    }\r\n    /**\r\n     * constructs a new movement controller system\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param options configuration object for this feature\r\n     */\r\n    constructor(_xrSessionManager: WebXRSessionManager, options: IWebXRControllerMovementOptions) {\r\n        super(_xrSessionManager);\r\n\r\n        if (!options || options.xrInput === undefined) {\r\n            Logger.Error('WebXRControllerMovement feature requires \"xrInput\" option.');\r\n            return;\r\n        }\r\n\r\n        if (Array.isArray(options.customRegistrationConfigurations)) {\r\n            this._currentRegistrationConfigurations = options.customRegistrationConfigurations;\r\n        } else {\r\n            this._currentRegistrationConfigurations = WebXRControllerMovement.REGISTRATIONS.default;\r\n        }\r\n\r\n        // synchronized from feature setter properties\r\n        this._featureContext = {\r\n            movementEnabled: options.movementEnabled ?? true,\r\n            movementOrientationFollowsViewerPose: options.movementOrientationFollowsViewerPose ?? true,\r\n            movementOrientationFollowsController: options.movementOrientationFollowsController ?? false,\r\n            orientationPreferredHandedness: options.orientationPreferredHandedness,\r\n            movementSpeed: options.movementSpeed ?? 1,\r\n            movementThreshold: options.movementThreshold ?? 0.25,\r\n            rotationEnabled: options.rotationEnabled ?? true,\r\n            rotationSpeed: options.rotationSpeed ?? 1.0,\r\n            rotationThreshold: options.rotationThreshold ?? 0.25,\r\n        };\r\n\r\n        this._movementState = {\r\n            moveX: 0,\r\n            moveY: 0,\r\n            rotateX: 0,\r\n            rotateY: 0,\r\n        };\r\n\r\n        this._xrInput = options.xrInput;\r\n    }\r\n\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        for (const controller of this._xrInput.controllers) {\r\n            this._attachController(controller);\r\n        }\r\n        this._addNewAttachObserver(this._xrInput.onControllerAddedObservable, this._attachController);\r\n        this._addNewAttachObserver(this._xrInput.onControllerRemovedObservable, (controller: WebXRInputSource) => {\r\n            // REMOVE the controller\r\n            this._detachController(controller.uniqueId);\r\n        });\r\n\r\n        return true;\r\n    }\r\n\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n        const keys = Object.keys(this._controllers);\r\n\r\n        for (const controllerId of keys) {\r\n            this._detachController(controllerId);\r\n        }\r\n\r\n        this._controllers = {};\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Occurs on every XR frame.\r\n     * @param _xrFrame\r\n     */\r\n    protected _onXRFrame(_xrFrame: XRFrame) {\r\n        if (!this.attached) {\r\n            return;\r\n        }\r\n\r\n        if (this._movementState.rotateX !== 0 && this._featureContext.rotationEnabled) {\r\n            // smooth rotation\r\n            const deltaMillis = this._xrSessionManager.scene.getEngine().getDeltaTime();\r\n            const rotationY = deltaMillis * 0.001 * this._featureContext.rotationSpeed * this._movementState.rotateX * (this._xrSessionManager.scene.useRightHandedSystem ? -1 : 1);\r\n\r\n            if (this._featureContext.movementOrientationFollowsViewerPose) {\r\n                this._xrInput.xrCamera.cameraRotation.y += rotationY;\r\n                Quaternion.RotationYawPitchRollToRef(rotationY, 0, 0, this._tempCacheQuaternion);\r\n                this._xrInput.xrCamera.rotationQuaternion.multiplyToRef(this._tempCacheQuaternion, this._movementDirection);\r\n            } else if (this._featureContext.movementOrientationFollowsController) {\r\n                this._xrInput.xrCamera.cameraRotation.y += rotationY;\r\n                // get the correct controller\r\n                const handedness = this._featureContext.orientationPreferredHandedness || \"right\";\r\n                const key =\r\n                    Object.keys(this._controllers).find((key) => this._controllers[key]?.xrController?.inputSource.handedness === handedness) || Object.keys(this._controllers)[0];\r\n                const controller = this._controllers[key];\r\n                Quaternion.RotationYawPitchRollToRef(rotationY, 0, 0, this._tempCacheQuaternion);\r\n                (controller?.xrController.pointer.rotationQuaternion || Quaternion.Identity()).multiplyToRef(this._tempCacheQuaternion, this._movementDirection);\r\n            } else {\r\n                // movement orientation direction does not affect camera.  We use rotation speed multiplier\r\n                // otherwise need to implement inertia and constraints for same feel as TargetCamera.\r\n\r\n                Quaternion.RotationYawPitchRollToRef(rotationY * 3.0, 0, 0, this._tempCacheQuaternion);\r\n                this._movementDirection.multiplyInPlace(this._tempCacheQuaternion);\r\n            }\r\n        } else if (this._featureContext.movementOrientationFollowsViewerPose) {\r\n            this._movementDirection.copyFrom(this._xrInput.xrCamera.rotationQuaternion);\r\n        } else if (this._featureContext.movementOrientationFollowsController) {\r\n            // get the correct controller\r\n            const handedness = this._featureContext.orientationPreferredHandedness || \"right\";\r\n            const key =\r\n                Object.keys(this._controllers).find((key) => this._controllers[key]?.xrController.inputSource.handedness === handedness) || Object.keys(this._controllers)[0];\r\n            const controller = this._controllers[key];\r\n            this._movementDirection.copyFrom(controller?.xrController.pointer.rotationQuaternion || Quaternion.Identity());\r\n        }\r\n\r\n        if ((this._movementState.moveX || this._movementState.moveY) && this._featureContext.movementEnabled) {\r\n            Matrix.FromQuaternionToRef(this._movementDirection, this._tmpRotationMatrix);\r\n            this._tmpTranslationDirection.set(this._movementState.moveX, 0, this._movementState.moveY * (this._xrSessionManager.scene.useRightHandedSystem ? 1.0 : -1.0));\r\n            // move according to forward direction based on camera speed\r\n            Vector3.TransformCoordinatesToRef(this._tmpTranslationDirection, this._tmpRotationMatrix, this._tmpMovementTranslation);\r\n            this._tmpMovementTranslation.scaleInPlace(this._xrInput.xrCamera._computeLocalCameraSpeed() * this._featureContext.movementSpeed);\r\n\r\n            this._xrInput.xrCamera.cameraDirection.addInPlace(this._tmpMovementTranslation);\r\n        }\r\n    }\r\n\r\n    private _attachController = (xrController: WebXRInputSource) => {\r\n        if (this._controllers[xrController.uniqueId]) {\r\n            // already attached\r\n            return;\r\n        }\r\n\r\n        this._controllers[xrController.uniqueId] = {\r\n            xrController,\r\n            registeredComponents: [],\r\n        };\r\n        const controllerData = this._controllers[xrController.uniqueId];\r\n\r\n        // movement controller only available to gamepad-enabled input sources.\r\n        if (controllerData.xrController.inputSource.targetRayMode === \"tracked-pointer\" && controllerData.xrController.inputSource.gamepad) {\r\n            // motion controller support\r\n            const initController = () => {\r\n                if (xrController.motionController) {\r\n                    for (const registration of this._currentRegistrationConfigurations) {\r\n                        let component: Nullable<WebXRControllerComponent> = null;\r\n\r\n                        if (registration.allowedComponentTypes) {\r\n                            for (const componentType of registration.allowedComponentTypes) {\r\n                                const componentOfType = xrController.motionController.getComponentOfType(componentType);\r\n                                if (componentOfType !== null) {\r\n                                    component = componentOfType;\r\n                                    break;\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        if (registration.mainComponentOnly) {\r\n                            const mainComponent = xrController.motionController.getMainComponent();\r\n                            if (mainComponent === null) {\r\n                                continue;\r\n                            }\r\n                            component = mainComponent;\r\n                        }\r\n\r\n                        if (typeof registration.componentSelectionPredicate === \"function\") {\r\n                            // if does not match we do want to ignore a previously found component\r\n                            component = registration.componentSelectionPredicate(xrController);\r\n                        }\r\n\r\n                        if (component && registration.forceHandedness) {\r\n                            if (xrController.inputSource.handedness !== registration.forceHandedness) {\r\n                                continue; // do not register\r\n                            }\r\n                        }\r\n\r\n                        if (component === null) {\r\n                            continue; // do not register\r\n                        }\r\n\r\n                        const registeredComponent: RegisteredComponent = {\r\n                            registrationConfiguration: registration,\r\n                            component,\r\n                        };\r\n                        controllerData.registeredComponents.push(registeredComponent);\r\n\r\n                        if (\"axisChangedHandler\" in registration) {\r\n                            registeredComponent.onAxisChangedObserver = component.onAxisValueChangedObservable.add((axesData) => {\r\n                                registration.axisChangedHandler(axesData, this._movementState, this._featureContext, this._xrInput);\r\n                            });\r\n                        }\r\n\r\n                        if (\"buttonChangedHandler\" in registration) {\r\n                            registeredComponent.onButtonChangedObserver = component.onButtonStateChangedObservable.add((component) => {\r\n                                if (component.changes.pressed) {\r\n                                    registration.buttonChangedHandler(component.changes.pressed, this._movementState, this._featureContext, this._xrInput);\r\n                                }\r\n                            });\r\n                        }\r\n                    }\r\n                }\r\n            };\r\n\r\n            if (xrController.motionController) {\r\n                initController();\r\n            } else {\r\n                xrController.onMotionControllerInitObservable.addOnce(() => {\r\n                    initController();\r\n                });\r\n            }\r\n        }\r\n    };\r\n\r\n    private _detachController(xrControllerUniqueId: string) {\r\n        const controllerData = this._controllers[xrControllerUniqueId];\r\n        if (!controllerData) {\r\n            return;\r\n        }\r\n\r\n        for (const registeredComponent of controllerData.registeredComponents) {\r\n            if (registeredComponent.onAxisChangedObserver) {\r\n                registeredComponent.component.onAxisValueChangedObservable.remove(registeredComponent.onAxisChangedObserver);\r\n            }\r\n            if (registeredComponent.onButtonChangedObserver) {\r\n                registeredComponent.component.onButtonStateChangedObservable.remove(registeredComponent.onButtonChangedObserver);\r\n            }\r\n        }\r\n\r\n        // remove from the map\r\n        delete this._controllers[xrControllerUniqueId];\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRControllerMovement.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRControllerMovement(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRControllerMovement.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRControllerMovement(xrSessionManager, options);\r\n        },\r\n        WebXRControllerMovement.Version,\r\n        true\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebGLHardwareTexture } from \"../../Engines/WebGL/webGLHardwareTexture\";\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { Color3 } from \"../../Maths/math.color.pure\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { DirectionalLight } from \"../../Lights/directionalLight.pure\";\r\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { SphericalHarmonics, SphericalPolynomial } from \"../../Maths/sphericalPolynomial.pure\";\r\nimport { LightConstants } from \"../../Lights/lightConstants\";\r\nimport { HDRFiltering } from \"core/Materials/Textures/Filtering/hdrFiltering\";\r\nimport { type ThinEngine } from \"core/Engines\";\r\nimport { WebXRGraphicsBindingType, type WebXRWebGLGraphicsBinding } from \"../webXRGraphicsBinding\";\r\n\r\nconst WebGPUReflectionWarning =\r\n    \"WebXR Light Estimation reflection cube maps are unavailable with WebGPU XR because they are exposed only by XRWebGLBinding; light direction, intensity, and spherical harmonics remain enabled.\";\r\n\r\n/**\r\n * Options for Light Estimation feature\r\n */\r\nexport interface IWebXRLightEstimationOptions {\r\n    /**\r\n     * Disable the cube map reflection feature. In this case only light direction and color will be updated\r\n     */\r\n    disableCubeMapReflection?: boolean;\r\n    /**\r\n     * Should the scene's env texture be set to the cube map reflection texture\r\n     * Note that this doesn't work is disableCubeMapReflection if set to false\r\n     */\r\n    setSceneEnvironmentTexture?: boolean;\r\n    /**\r\n     * How often should the cubemap update in ms.\r\n     * If not set the cubemap will be updated every time the underlying system updates the environment texture.\r\n     */\r\n    cubeMapPollInterval?: number;\r\n    /**\r\n     * How often should the light estimation properties update in ms.\r\n     * If not set the light estimation properties will be updated on every frame (depending on the underlying system)\r\n     */\r\n    lightEstimationPollInterval?: number;\r\n    /**\r\n     * Should a directional light source be created.\r\n     * If created, this light source will be updated whenever the light estimation values change\r\n     */\r\n    createDirectionalLightSource?: boolean;\r\n    /**\r\n     * The scale factor to multiply the intensity of the directional light by. Defaults to 1.0.\r\n     */\r\n    directionalLightIntensityFactor?: number;\r\n    /**\r\n     * Define the format to be used for the light estimation texture.\r\n     */\r\n    reflectionFormat?: XRReflectionFormat;\r\n    /**\r\n     * Should the light estimation's needed vectors be constructed on each frame.\r\n     * Use this when you use those vectors and don't want their values to change outside of the light estimation feature\r\n     */\r\n    disableVectorReuse?: boolean;\r\n\r\n    /**\r\n     * disable applying the spherical polynomial to the cube map texture\r\n     */\r\n    disableSphericalPolynomial?: boolean;\r\n\r\n    /**\r\n     * disable prefiltering the cube map texture\r\n     */\r\n    disablePreFiltering?: boolean;\r\n}\r\n\r\n/**\r\n * An interface describing the result of a light estimation\r\n */\r\nexport interface IWebXRLightEstimation {\r\n    /**\r\n     * The intensity of the light source\r\n     */\r\n    lightIntensity: number;\r\n    /**\r\n     * Color of light source\r\n     */\r\n    lightColor: Color3;\r\n    /**\r\n     * The direction from the light source\r\n     */\r\n    lightDirection: Vector3;\r\n    /**\r\n     * Spherical harmonics coefficients of the light source\r\n     */\r\n    sphericalHarmonics: SphericalHarmonics;\r\n}\r\n\r\n/**\r\n * Light Estimation Feature\r\n *\r\n * @since 5.0.0\r\n */\r\nexport class WebXRLightEstimation extends WebXRAbstractFeature {\r\n    private _reflectionCubeMap: Nullable<BaseTexture> = null;\r\n    private _xrLightEstimate: Nullable<XRLightEstimate> = null;\r\n    private _xrLightProbe: Nullable<XRLightProbe> = null;\r\n    private _reflectionCubeMapEnabled = false;\r\n    private _webGPUReflectionWarningEmitted = false;\r\n    private _lightDirection: Vector3 = Vector3.Up().negateInPlace();\r\n    private _lightColor: Color3 = Color3.White();\r\n    private _intensity: number = 1;\r\n    private _sphericalHarmonics: SphericalHarmonics = new SphericalHarmonics();\r\n    private _cubeMapPollTime = Date.now();\r\n    private _lightEstimationPollTime = Date.now();\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.LIGHT_ESTIMATION;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * ARCore's reflection cube map size is 16x16.\r\n     * Once other systems support this feature we will need to change this to be dynamic.\r\n     * see https://github.com/immersive-web/lighting-estimation/blob/main/lighting-estimation-explainer.md#cube-map-open-questions\r\n     */\r\n    private _reflectionCubeMapTextureSize: number = 16;\r\n\r\n    private _hdrFilter: HDRFiltering;\r\n\r\n    /**\r\n     * If createDirectionalLightSource is set to true this light source will be created automatically.\r\n     * Otherwise this can be set with an external directional light source.\r\n     * This light will be updated whenever the light estimation values change.\r\n     */\r\n    public directionalLight: Nullable<DirectionalLight> = null;\r\n\r\n    /**\r\n     * The scale factor to multiply the intensity of the directional light by. Defaults to 1.0.\r\n     */\r\n    public directionalLightIntensityFactor: number = 1.0;\r\n\r\n    /**\r\n     * This observable will notify when the reflection cube map is updated.\r\n     */\r\n    public onReflectionCubeMapUpdatedObservable: Observable<BaseTexture> = new Observable();\r\n\r\n    /**\r\n     * Creates a new instance of the light estimation feature\r\n     * @param _xrSessionManager an instance of WebXRSessionManager\r\n     * @param options options to use when constructing this feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        /**\r\n         * options to use when constructing this feature\r\n         */\r\n        public readonly options: IWebXRLightEstimationOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"light-estimation\";\r\n\r\n        if (this.options.createDirectionalLightSource) {\r\n            this.directionalLight = new DirectionalLight(\"light estimation directional\", this._lightDirection, this._xrSessionManager.scene);\r\n            this.directionalLight.position = new Vector3(0, 8, 0);\r\n            // intensity will be set later\r\n            this.directionalLight.intensity = 0;\r\n            this.directionalLight.falloffType = LightConstants.FALLOFF_GLTF;\r\n        }\r\n\r\n        this.directionalLightIntensityFactor = this.options.directionalLightIntensityFactor ?? 1.0;\r\n\r\n        this._hdrFilter = new HDRFiltering(this._xrSessionManager.scene.getEngine() as ThinEngine);\r\n\r\n        // https://immersive-web.github.io/lighting-estimation/\r\n        Logger.Warn(\"light-estimation is an experimental and unstable feature.\");\r\n    }\r\n\r\n    /**\r\n     * While the estimated cube map is expected to update over time to better reflect the user's environment as they move around those changes are unlikely to happen with every XRFrame.\r\n     * Since creating and processing the cube map is potentially expensive, especially if mip maps are needed, you can listen to the onReflectionCubeMapUpdatedObservable to determine\r\n     * when it has been updated.\r\n     */\r\n    public get reflectionCubeMapTexture(): Nullable<BaseTexture> {\r\n        return this._reflectionCubeMap;\r\n    }\r\n\r\n    /**\r\n     * The most recent light estimate.  Available starting on the first frame where the device provides a light probe.\r\n     */\r\n    public get xrLightingEstimate(): Nullable<IWebXRLightEstimation> {\r\n        if (this._xrLightEstimate) {\r\n            return {\r\n                lightColor: this._lightColor,\r\n                lightDirection: this._lightDirection,\r\n                lightIntensity: this._intensity,\r\n                sphericalHarmonics: this._sphericalHarmonics,\r\n            };\r\n        }\r\n        return this._xrLightEstimate;\r\n    }\r\n\r\n    private _getXRWebGLBinding(): WebXRWebGLGraphicsBinding {\r\n        const graphicsBinding = this._xrSessionManager._getGraphicsBinding();\r\n        if (graphicsBinding.bindingType !== WebXRGraphicsBindingType.WebGL) {\r\n            throw new Error(\"Expected a WebGL graphics binding for WebXR Light Estimation reflections.\");\r\n        }\r\n        return graphicsBinding;\r\n    }\r\n\r\n    /**\r\n     * Event Listener for \"reflectionchange\" events.\r\n     */\r\n    private _updateReflectionCubeMap = (): void => {\r\n        if (!this._xrLightProbe) {\r\n            return;\r\n        }\r\n        // check poll time, do not update if it has not been long enough\r\n        if (this.options.cubeMapPollInterval) {\r\n            const now = Date.now();\r\n            if (now - this._cubeMapPollTime < this.options.cubeMapPollInterval) {\r\n                return;\r\n            }\r\n            this._cubeMapPollTime = now;\r\n        }\r\n        const graphicsBinding = this._getXRWebGLBinding();\r\n        const lp = graphicsBinding.binding.getReflectionCubeMap(this._xrLightProbe);\r\n        if (lp && this._reflectionCubeMap) {\r\n            if (!this._reflectionCubeMap._texture) {\r\n                const internalTexture = new InternalTexture(this._xrSessionManager.scene.getEngine(), InternalTextureSource.Unknown);\r\n                internalTexture.isCube = true;\r\n                internalTexture.invertY = false;\r\n                internalTexture._useSRGBBuffer = this.options.reflectionFormat === \"srgba8\";\r\n                internalTexture.format = Constants.TEXTUREFORMAT_RGBA;\r\n                internalTexture.generateMipMaps = true;\r\n                internalTexture.type = this.options.reflectionFormat !== \"srgba8\" ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n                internalTexture.samplingMode = Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR;\r\n                internalTexture.width = this._reflectionCubeMapTextureSize;\r\n                internalTexture.height = this._reflectionCubeMapTextureSize;\r\n                internalTexture._cachedWrapU = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n                internalTexture._cachedWrapV = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n                internalTexture._hardwareTexture = new WebGLHardwareTexture(lp, graphicsBinding.context);\r\n                this._reflectionCubeMap._texture = internalTexture;\r\n            } else {\r\n                this._reflectionCubeMap._texture._hardwareTexture?.set(lp);\r\n                this._reflectionCubeMap._texture.getEngine().resetTextureCache();\r\n            }\r\n            this._reflectionCubeMap._texture.isReady = true;\r\n            if (!this.options.disablePreFiltering) {\r\n                this._xrLightProbe.removeEventListener(\"reflectionchange\", this._updateReflectionCubeMap);\r\n                // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n                this._hdrFilter.prefilter(this._reflectionCubeMap).then(() => {\r\n                    this._xrSessionManager.scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n                    this.onReflectionCubeMapUpdatedObservable.notifyObservers(this._reflectionCubeMap!);\r\n                    this._xrLightProbe!.addEventListener(\"reflectionchange\", this._updateReflectionCubeMap);\r\n                });\r\n            } else {\r\n                this._xrSessionManager.scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n\r\n                this.onReflectionCubeMapUpdatedObservable.notifyObservers(this._reflectionCubeMap);\r\n            }\r\n        }\r\n    };\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        const isWebGPU = this._xrSessionManager.scene.getEngine().isWebGPU;\r\n        this._reflectionCubeMapEnabled = !this.options.disableCubeMapReflection && !isWebGPU;\r\n        if (!this.options.disableCubeMapReflection && isWebGPU && !this._webGPUReflectionWarningEmitted) {\r\n            Logger.Warn(WebGPUReflectionWarning);\r\n            this._webGPUReflectionWarningEmitted = true;\r\n        }\r\n\r\n        const reflectionFormat = this.options.reflectionFormat ?? (this._xrSessionManager.session.preferredReflectionFormat || \"srgba8\");\r\n        this.options.reflectionFormat = reflectionFormat;\r\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n        this._xrSessionManager.session\r\n            .requestLightProbe({\r\n                reflectionFormat,\r\n            })\r\n            // eslint-disable-next-line github/no-then\r\n            .then((xrLightProbe: XRLightProbe) => {\r\n                this._xrLightProbe = xrLightProbe;\r\n                if (this._reflectionCubeMapEnabled) {\r\n                    if (!this._reflectionCubeMap) {\r\n                        this._reflectionCubeMap = new BaseTexture(this._xrSessionManager.scene);\r\n                        this._reflectionCubeMap._isCube = true;\r\n                        this._reflectionCubeMap.coordinatesMode = Constants.TEXTURE_CUBIC_MODE;\r\n                        if (this.options.setSceneEnvironmentTexture) {\r\n                            this._xrSessionManager.scene.environmentTexture = this._reflectionCubeMap;\r\n                        }\r\n                    }\r\n                    this._xrLightProbe.addEventListener(\"reflectionchange\", this._updateReflectionCubeMap);\r\n                }\r\n            });\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * detach this feature.\r\n     * Will usually be called by the features manager\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override detach(): boolean {\r\n        const detached = super.detach();\r\n\r\n        if (this._xrLightProbe !== null) {\r\n            if (this._reflectionCubeMapEnabled) {\r\n                this._xrLightProbe.removeEventListener(\"reflectionchange\", this._updateReflectionCubeMap);\r\n            }\r\n            this._xrLightProbe = null;\r\n        }\r\n\r\n        this._xrLightEstimate = null;\r\n\r\n        return detached;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        this.onReflectionCubeMapUpdatedObservable.clear();\r\n\r\n        if (this.directionalLight) {\r\n            this.directionalLight.dispose();\r\n            this.directionalLight = null;\r\n        }\r\n\r\n        if (this._reflectionCubeMap !== null) {\r\n            if (this._reflectionCubeMap._texture) {\r\n                this._reflectionCubeMap._texture.dispose();\r\n            }\r\n            this._reflectionCubeMap.dispose();\r\n            this._reflectionCubeMap = null;\r\n        }\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame): void {\r\n        if (this._xrLightProbe !== null) {\r\n            if (this.options.lightEstimationPollInterval) {\r\n                const now = Date.now();\r\n                if (now - this._lightEstimationPollTime < this.options.lightEstimationPollInterval) {\r\n                    return;\r\n                }\r\n                this._lightEstimationPollTime = now;\r\n            }\r\n            this._xrLightEstimate = _xrFrame.getLightEstimate(this._xrLightProbe);\r\n            if (this._xrLightEstimate) {\r\n                this._intensity = Math.max(\r\n                    1.0,\r\n                    this._xrLightEstimate.primaryLightIntensity.x,\r\n                    this._xrLightEstimate.primaryLightIntensity.y,\r\n                    this._xrLightEstimate.primaryLightIntensity.z\r\n                );\r\n\r\n                const rhsFactor = this._xrSessionManager.scene.useRightHandedSystem ? 1.0 : -1.0;\r\n\r\n                // recreate the vector caches, so that the last one provided to the user will persist\r\n                if (this.options.disableVectorReuse) {\r\n                    this._lightDirection = new Vector3();\r\n                    this._lightColor = new Color3();\r\n                    if (this.directionalLight) {\r\n                        this.directionalLight.direction = this._lightDirection;\r\n                        this.directionalLight.diffuse = this._lightColor;\r\n                    }\r\n                }\r\n\r\n                this._lightDirection.copyFromFloats(\r\n                    this._xrLightEstimate.primaryLightDirection.x,\r\n                    this._xrLightEstimate.primaryLightDirection.y,\r\n                    this._xrLightEstimate.primaryLightDirection.z * rhsFactor\r\n                );\r\n                this._lightColor.copyFromFloats(\r\n                    this._xrLightEstimate.primaryLightIntensity.x / this._intensity,\r\n                    this._xrLightEstimate.primaryLightIntensity.y / this._intensity,\r\n                    this._xrLightEstimate.primaryLightIntensity.z / this._intensity\r\n                );\r\n                this._sphericalHarmonics.updateFromFloatsArray(this._xrLightEstimate.sphericalHarmonicsCoefficients);\r\n                if (this._reflectionCubeMap && !this.options.disableSphericalPolynomial) {\r\n                    this._reflectionCubeMap.sphericalPolynomial = this._reflectionCubeMap.sphericalPolynomial || new SphericalPolynomial();\r\n                    this._reflectionCubeMap.sphericalPolynomial?.updateFromHarmonics(this._sphericalHarmonics);\r\n                }\r\n\r\n                // direction from instead of direction to\r\n                this._lightDirection.negateInPlace();\r\n                // set the values after calculating them\r\n                if (this.directionalLight) {\r\n                    this.directionalLight.direction.copyFrom(this._lightDirection);\r\n                    this.directionalLight.intensity = Math.min(this._intensity, 1.0) * this.directionalLightIntensityFactor;\r\n                    this.directionalLight.diffuse.copyFrom(this._lightColor);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRLightEstimation.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRLightEstimation(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRLightEstimation.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRLightEstimation(xrSessionManager, options);\r\n        },\r\n        WebXRLightEstimation.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Vector3, TmpVectors } from \"../../Maths/math.vector.pure\";\r\nimport { Ray } from \"../../Culling/ray.pure\";\r\nimport { type Nullable } from \"../../types\";\r\n\r\n/**\r\n * The WebXR Eye Tracking feature grabs eye data from the device and provides it in an easy-access format.\r\n * Currently only enabled for BabylonNative applications.\r\n */\r\nexport class WebXREyeTracking extends WebXRAbstractFeature {\r\n    private _latestEyeSpace: Nullable<XRSpace>;\r\n    private _gazeRay: Nullable<Ray>;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.EYE_TRACKING;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * This observable will notify registered observers when eye tracking starts\r\n     */\r\n    public readonly onEyeTrackingStartedObservable: Observable<Ray> = new Observable();\r\n    /**\r\n     * This observable will notify registered observers when eye tracking ends\r\n     */\r\n    public readonly onEyeTrackingEndedObservable: Observable<void> = new Observable();\r\n    /**\r\n     * This observable will notify registered observers on each frame that has valid tracking\r\n     */\r\n    public readonly onEyeTrackingFrameUpdateObservable: Observable<Ray> = new Observable();\r\n\r\n    /**\r\n     * Creates a new instance of the XR eye tracking feature.\r\n     * @param _xrSessionManager An instance of WebXRSessionManager.\r\n     */\r\n    constructor(_xrSessionManager: WebXRSessionManager) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"eye-tracking\";\r\n        if (this._xrSessionManager.session) {\r\n            this._init();\r\n        } else {\r\n            this._xrSessionManager.onXRSessionInit.addOnce(() => {\r\n                this._init();\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n\r\n        this._xrSessionManager.session.removeEventListener(\"eyetrackingstart\", this._eyeTrackingStartListener);\r\n        this._xrSessionManager.session.removeEventListener(\"eyetrackingend\", this._eyeTrackingEndListener);\r\n\r\n        this.onEyeTrackingStartedObservable.clear();\r\n        this.onEyeTrackingEndedObservable.clear();\r\n        this.onEyeTrackingFrameUpdateObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * Returns whether the gaze data is valid or not\r\n     * @returns true if the data is valid\r\n     */\r\n    public get isEyeGazeValid(): boolean {\r\n        return !!this._gazeRay;\r\n    }\r\n\r\n    /**\r\n     * Get a reference to the gaze ray. This data is valid while eye tracking persists, and will be set to null when gaze data is no longer available\r\n     * @returns a reference to the gaze ray if it exists and is valid, returns null otherwise.\r\n     */\r\n    public getEyeGaze(): Nullable<Ray> {\r\n        return this._gazeRay;\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame) {\r\n        if (!this.attached || !frame) {\r\n            return;\r\n        }\r\n\r\n        if (this._latestEyeSpace && this._gazeRay) {\r\n            const pose = frame.getPose(this._latestEyeSpace, this._xrSessionManager.referenceSpace);\r\n            if (pose) {\r\n                this._gazeRay.origin.set(pose.transform.position.x, pose.transform.position.y, pose.transform.position.z).scaleInPlace(this._xrSessionManager.worldScalingFactor);\r\n                const quat = pose.transform.orientation;\r\n                TmpVectors.Quaternion[0].set(quat.x, quat.y, quat.z, quat.w);\r\n\r\n                if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n                    this._gazeRay.origin.z *= -1;\r\n                    TmpVectors.Quaternion[0].z *= -1;\r\n                    TmpVectors.Quaternion[0].w *= -1;\r\n\r\n                    Vector3.LeftHandedForwardReadOnly.rotateByQuaternionToRef(TmpVectors.Quaternion[0], this._gazeRay.direction);\r\n                } else {\r\n                    Vector3.RightHandedForwardReadOnly.rotateByQuaternionToRef(TmpVectors.Quaternion[0], this._gazeRay.direction);\r\n                }\r\n\r\n                this.onEyeTrackingFrameUpdateObservable.notifyObservers(this._gazeRay);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _eyeTrackingStartListener = (event: XREyeTrackingSourceEvent) => {\r\n        this._latestEyeSpace = event.gazeSpace;\r\n        this._gazeRay = new Ray(Vector3.Zero(), Vector3.Forward());\r\n        this.onEyeTrackingStartedObservable.notifyObservers(this._gazeRay);\r\n    };\r\n\r\n    private _eyeTrackingEndListener = () => {\r\n        this._latestEyeSpace = null;\r\n        this._gazeRay = null;\r\n        this.onEyeTrackingEndedObservable.notifyObservers();\r\n    };\r\n\r\n    private _init() {\r\n        // Only supported by BabylonNative\r\n        if (this._xrSessionManager.isNative) {\r\n            this._xrSessionManager.session.addEventListener(\"eyetrackingstart\", this._eyeTrackingStartListener);\r\n            this._xrSessionManager.session.addEventListener(\"eyetrackingend\", this._eyeTrackingEndListener);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXREyeTracking.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXREyeTracking(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXREyeTracking.Name,\r\n        (xrSessionManager) => {\r\n            return () => new WebXREyeTracking(xrSessionManager);\r\n        },\r\n        WebXREyeTracking.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine.pure\";\r\nimport { TmpVectors, Vector2, Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type WebXRCamera } from \"../webXRCamera\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\n\r\nclass CircleBuffer {\r\n    private _samples: Array<Vector2> = [];\r\n    private _idx: number = 0;\r\n\r\n    constructor(numSamples: number, initializer?: () => Vector2) {\r\n        for (let idx = 0; idx < numSamples; ++idx) {\r\n            this._samples.push(initializer ? initializer() : Vector2.Zero());\r\n        }\r\n    }\r\n\r\n    public get length() {\r\n        return this._samples.length;\r\n    }\r\n\r\n    public push(x: number, y: number) {\r\n        this._idx = (this._idx + this._samples.length - 1) % this._samples.length;\r\n        this.at(0).copyFromFloats(x, y);\r\n    }\r\n\r\n    public at(idx: number) {\r\n        if (idx >= this._samples.length) {\r\n            throw new Error(\"Index out of bounds\");\r\n        }\r\n        return this._samples[(this._idx + idx) % this._samples.length];\r\n    }\r\n}\r\n\r\ninterface IDetectedStep {\r\n    leftApex: Vector2;\r\n    rightApex: Vector2;\r\n    currentPosition: Vector2;\r\n    currentStepDirection: \"left\" | \"right\";\r\n}\r\n\r\nclass FirstStepDetector {\r\n    private _samples = new CircleBuffer(20);\r\n    private _entropy = 0;\r\n\r\n    public onFirstStepDetected: Observable<IDetectedStep> = new Observable<IDetectedStep>();\r\n\r\n    public update(posX: number, posY: number, forwardX: number, forwardY: number) {\r\n        this._samples.push(posX, posY);\r\n        const origin = this._samples.at(0);\r\n\r\n        this._entropy *= this._entropyDecayFactor;\r\n        this._entropy += Vector2.Distance(origin, this._samples.at(1));\r\n        if (this._entropy > this._entropyThreshold) {\r\n            return;\r\n        }\r\n\r\n        let samePointIdx;\r\n        for (samePointIdx = this._samePointCheckStartIdx; samePointIdx < this._samples.length; ++samePointIdx) {\r\n            if (Vector2.DistanceSquared(origin, this._samples.at(samePointIdx)) < this._samePointSquaredDistanceThreshold) {\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (samePointIdx === this._samples.length) {\r\n            return;\r\n        }\r\n\r\n        let apexDistSquared = -1;\r\n        let apexIdx = 0;\r\n        for (let distSquared, idx = 1; idx < samePointIdx; ++idx) {\r\n            distSquared = Vector2.DistanceSquared(origin, this._samples.at(idx));\r\n            if (distSquared > apexDistSquared) {\r\n                apexIdx = idx;\r\n                apexDistSquared = distSquared;\r\n            }\r\n        }\r\n\r\n        if (apexDistSquared < this._apexSquaredDistanceThreshold) {\r\n            return;\r\n        }\r\n\r\n        const apex = this._samples.at(apexIdx);\r\n        const axis = apex.subtract(origin);\r\n        axis.normalize();\r\n\r\n        const vec = TmpVectors.Vector2[0];\r\n        let dot;\r\n        let sample;\r\n        let sumSquaredProjectionDistances = 0;\r\n        for (let idx = 1; idx < samePointIdx; ++idx) {\r\n            sample = this._samples.at(idx);\r\n            sample.subtractToRef(origin, vec);\r\n            dot = Vector2.Dot(axis, vec);\r\n            sumSquaredProjectionDistances += vec.lengthSquared() - dot * dot;\r\n        }\r\n\r\n        if (sumSquaredProjectionDistances > samePointIdx * this._squaredProjectionDistanceThreshold) {\r\n            return;\r\n        }\r\n\r\n        const forwardVec = TmpVectors.Vector3[0];\r\n        forwardVec.set(forwardX, forwardY, 0);\r\n        const axisVec = TmpVectors.Vector3[1];\r\n        axisVec.set(axis.x, axis.y, 0);\r\n        const isApexLeft = Vector3.Cross(forwardVec, axisVec).z > 0;\r\n        const leftApex = origin.clone();\r\n        const rightApex = origin.clone();\r\n        apex.subtractToRef(origin, axis);\r\n        if (isApexLeft) {\r\n            axis.scaleAndAddToRef(this._axisToApexShrinkFactor, leftApex);\r\n            axis.scaleAndAddToRef(this._axisToApexExtendFactor, rightApex);\r\n        } else {\r\n            axis.scaleAndAddToRef(this._axisToApexExtendFactor, leftApex);\r\n            axis.scaleAndAddToRef(this._axisToApexShrinkFactor, rightApex);\r\n        }\r\n        this.onFirstStepDetected.notifyObservers({\r\n            leftApex: leftApex,\r\n            rightApex: rightApex,\r\n            currentPosition: origin,\r\n            currentStepDirection: isApexLeft ? \"right\" : \"left\",\r\n        });\r\n    }\r\n\r\n    public reset() {\r\n        for (let idx = 0; idx < this._samples.length; ++idx) {\r\n            this._samples.at(idx).copyFromFloats(0, 0);\r\n        }\r\n    }\r\n\r\n    private get _samePointCheckStartIdx() {\r\n        return Math.floor(this._samples.length / 3);\r\n    }\r\n\r\n    private get _samePointSquaredDistanceThreshold() {\r\n        return 0.03 * 0.03;\r\n    }\r\n\r\n    private get _apexSquaredDistanceThreshold() {\r\n        return 0.09 * 0.09;\r\n    }\r\n\r\n    private get _squaredProjectionDistanceThreshold() {\r\n        return 0.03 * 0.03;\r\n    }\r\n\r\n    private get _axisToApexShrinkFactor() {\r\n        return 0.8;\r\n    }\r\n\r\n    private get _axisToApexExtendFactor() {\r\n        return -1.6;\r\n    }\r\n\r\n    private get _entropyDecayFactor() {\r\n        return 0.93;\r\n    }\r\n\r\n    private get _entropyThreshold() {\r\n        return 0.4;\r\n    }\r\n}\r\n\r\nclass WalkingTracker {\r\n    private _leftApex = new Vector2();\r\n    private _rightApex = new Vector2();\r\n    private _currentPosition = new Vector2();\r\n    private _axis = new Vector2();\r\n    private _axisLength = -1;\r\n    private _forward = new Vector2();\r\n    private _steppingLeft = false;\r\n    private _t = -1;\r\n    private _maxT = -1;\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _maxTPosition = new Vector2();\r\n    private _vitality = 0;\r\n\r\n    public onMovement = new Observable<{ deltaT: number }>();\r\n    public onFootfall = new Observable<{ foot: \"left\" | \"right\" }>();\r\n\r\n    constructor(leftApex: Vector2, rightApex: Vector2, currentPosition: Vector2, currentStepDirection: \"left\" | \"right\") {\r\n        this._reset(leftApex, rightApex, currentPosition, currentStepDirection === \"left\");\r\n    }\r\n\r\n    private _reset(leftApex: Vector2, rightApex: Vector2, currentPosition: Vector2, steppingLeft: boolean) {\r\n        this._leftApex.copyFrom(leftApex);\r\n        this._rightApex.copyFrom(rightApex);\r\n        this._steppingLeft = steppingLeft;\r\n\r\n        if (this._steppingLeft) {\r\n            this._leftApex.subtractToRef(this._rightApex, this._axis);\r\n            this._forward.copyFromFloats(-this._axis.y, this._axis.x);\r\n        } else {\r\n            this._rightApex.subtractToRef(this._leftApex, this._axis);\r\n            this._forward.copyFromFloats(this._axis.y, -this._axis.x);\r\n        }\r\n        this._axisLength = this._axis.length();\r\n        this._forward.scaleInPlace(1 / this._axisLength);\r\n\r\n        this._updateTAndVitality(currentPosition.x, currentPosition.y);\r\n        this._maxT = this._t;\r\n        this._maxTPosition.copyFrom(currentPosition);\r\n\r\n        this._vitality = 1;\r\n    }\r\n\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    private _updateTAndVitality(x: number, y: number) {\r\n        this._currentPosition.copyFromFloats(x, y);\r\n\r\n        if (this._steppingLeft) {\r\n            this._currentPosition.subtractInPlace(this._rightApex);\r\n        } else {\r\n            this._currentPosition.subtractInPlace(this._leftApex);\r\n        }\r\n        const priorT = this._t;\r\n        const dot = Vector2.Dot(this._currentPosition, this._axis);\r\n        this._t = dot / (this._axisLength * this._axisLength);\r\n        const projDistSquared = this._currentPosition.lengthSquared() - (dot / this._axisLength) * (dot / this._axisLength);\r\n\r\n        // TODO: Extricate the magic.\r\n        this._vitality *= 0.92 - 100 * Math.max(projDistSquared - 0.0016, 0) + Math.max(this._t - priorT, 0);\r\n    }\r\n\r\n    public update(x: number, y: number) {\r\n        if (this._vitality < this._vitalityThreshold) {\r\n            return false;\r\n        }\r\n\r\n        const priorT = this._t;\r\n        this._updateTAndVitality(x, y);\r\n\r\n        if (this._t > this._maxT) {\r\n            this._maxT = this._t;\r\n            this._maxTPosition.copyFromFloats(x, y);\r\n        }\r\n\r\n        if (this._vitality < this._vitalityThreshold) {\r\n            return false;\r\n        }\r\n\r\n        if (this._t > priorT) {\r\n            this.onMovement.notifyObservers({ deltaT: this._t - priorT });\r\n\r\n            if (priorT < 0.5 && this._t >= 0.5) {\r\n                this.onFootfall.notifyObservers({ foot: this._steppingLeft ? \"left\" : \"right\" });\r\n            }\r\n        }\r\n\r\n        if (this._t < 0.95 * this._maxT) {\r\n            this._currentPosition.copyFromFloats(x, y);\r\n            if (this._steppingLeft) {\r\n                this._leftApex.copyFrom(this._maxTPosition);\r\n            } else {\r\n                this._rightApex.copyFrom(this._maxTPosition);\r\n            }\r\n            this._reset(this._leftApex, this._rightApex, this._currentPosition, !this._steppingLeft);\r\n        }\r\n\r\n        if (this._axisLength < 0.03) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    private get _vitalityThreshold() {\r\n        return 0.1;\r\n    }\r\n\r\n    get forward() {\r\n        return this._forward;\r\n    }\r\n}\r\n\r\nclass Walker {\r\n    private _engine: AbstractEngine;\r\n    private _detector = new FirstStepDetector();\r\n    private _walker: Nullable<WalkingTracker> = null;\r\n    private _movement = new Vector2();\r\n    private _millisecondsSinceLastUpdate: number = Walker._MillisecondsPerUpdate;\r\n\r\n    private static get _MillisecondsPerUpdate(): number {\r\n        // 15 FPS\r\n        return 1000 / 15;\r\n    }\r\n\r\n    public movementThisFrame: Vector3 = Vector3.Zero();\r\n\r\n    constructor(engine: AbstractEngine) {\r\n        this._engine = engine;\r\n        this._detector.onFirstStepDetected.add((event) => {\r\n            if (!this._walker) {\r\n                this._walker = new WalkingTracker(event.leftApex, event.rightApex, event.currentPosition, event.currentStepDirection);\r\n                this._walker.onFootfall.add(() => {\r\n                    Logger.Log(\"Footfall!\");\r\n                });\r\n                this._walker.onMovement.add((event) => {\r\n                    this._walker!.forward.scaleAndAddToRef(0.024 * event.deltaT, this._movement);\r\n                });\r\n            }\r\n        });\r\n    }\r\n\r\n    public update(position: Vector3, forward: Vector3) {\r\n        forward.y = 0;\r\n        forward.normalize();\r\n\r\n        // Enforce reduced framerate\r\n        this._millisecondsSinceLastUpdate += this._engine.getDeltaTime();\r\n        if (this._millisecondsSinceLastUpdate >= Walker._MillisecondsPerUpdate) {\r\n            this._millisecondsSinceLastUpdate -= Walker._MillisecondsPerUpdate;\r\n            this._detector.update(position.x, position.z, forward.x, forward.z);\r\n            if (this._walker) {\r\n                const updated = this._walker.update(position.x, position.z);\r\n                if (!updated) {\r\n                    this._walker = null;\r\n                }\r\n            }\r\n            this._movement.scaleInPlace(0.85);\r\n        }\r\n\r\n        this.movementThisFrame.set(this._movement.x, 0, this._movement.y);\r\n    }\r\n}\r\n\r\n/**\r\n * Options for the walking locomotion feature.\r\n */\r\nexport interface IWebXRWalkingLocomotionOptions {\r\n    /**\r\n     * The target to be moved by walking locomotion. This should be the transform node\r\n     * which is the root of the XR space (i.e., the WebXRCamera's parent node). However,\r\n     * for simple cases and legacy purposes, articulating the WebXRCamera itself is also\r\n     * supported as a deprecated feature.\r\n     */\r\n    locomotionTarget: WebXRCamera | TransformNode;\r\n}\r\n\r\n/**\r\n * A module that will enable VR locomotion by detecting when the user walks in place.\r\n */\r\nexport class WebXRWalkingLocomotion extends WebXRAbstractFeature {\r\n    /**\r\n     * The module's name.\r\n     */\r\n    public static get Name(): string {\r\n        return WebXRFeatureName.WALKING_LOCOMOTION;\r\n    }\r\n\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number has no external basis.\r\n     */\r\n    public static get Version(): number {\r\n        return 1;\r\n    }\r\n\r\n    private _sessionManager: WebXRSessionManager;\r\n    private _up: Vector3 = new Vector3();\r\n    private _forward: Vector3 = new Vector3();\r\n    private _position: Vector3 = new Vector3();\r\n    private _movement: Vector3 = new Vector3();\r\n    private _walker: Nullable<Walker>;\r\n\r\n    private _locomotionTarget: WebXRCamera | TransformNode;\r\n    private _isLocomotionTargetWebXRCamera: boolean;\r\n\r\n    /**\r\n     * The target to be articulated by walking locomotion.\r\n     * When the walking locomotion feature detects walking in place, this element's\r\n     * X and Z coordinates will be modified to reflect locomotion. This target should\r\n     * be either the XR space's origin (i.e., the parent node of the WebXRCamera) or\r\n     * the WebXRCamera itself. Note that the WebXRCamera path will modify the position\r\n     * of the WebXRCamera directly and is thus discouraged.\r\n     */\r\n    public get locomotionTarget(): WebXRCamera | TransformNode {\r\n        return this._locomotionTarget;\r\n    }\r\n\r\n    /**\r\n     * The target to be articulated by walking locomotion.\r\n     * When the walking locomotion feature detects walking in place, this element's\r\n     * X and Z coordinates will be modified to reflect locomotion. This target should\r\n     * be either the XR space's origin (i.e., the parent node of the WebXRCamera) or\r\n     * the WebXRCamera itself. Note that the WebXRCamera path will modify the position\r\n     * of the WebXRCamera directly and is thus discouraged.\r\n     */\r\n    public set locomotionTarget(locomotionTarget: WebXRCamera | TransformNode) {\r\n        this._locomotionTarget = locomotionTarget;\r\n        this._isLocomotionTargetWebXRCamera = this._locomotionTarget.getClassName() === \"WebXRCamera\";\r\n    }\r\n\r\n    /**\r\n     * Construct a new Walking Locomotion feature.\r\n     * @param sessionManager manager for the current XR session\r\n     * @param options creation options, prominently including the vector target for locomotion\r\n     */\r\n    public constructor(sessionManager: WebXRSessionManager, options: IWebXRWalkingLocomotionOptions) {\r\n        super(sessionManager);\r\n        this._sessionManager = sessionManager;\r\n        this.locomotionTarget = options.locomotionTarget;\r\n        if (this._isLocomotionTargetWebXRCamera) {\r\n            Logger.Warn(\r\n                \"Using walking locomotion directly on a WebXRCamera may have unintended interactions with other XR techniques. Using an XR space parent is highly recommended\"\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether this feature is compatible with the current WebXR session.\r\n     * Walking locomotion is only compatible with \"immersive-vr\" sessions.\r\n     * @returns true if compatible, false otherwise\r\n     */\r\n    public override isCompatible(): boolean {\r\n        return this._sessionManager.sessionMode === undefined || this._sessionManager.sessionMode === \"immersive-vr\";\r\n    }\r\n\r\n    /**\r\n     * Attaches the feature.\r\n     * Typically called automatically by the features manager.\r\n     * @returns true if attach succeeded, false otherwise\r\n     */\r\n    public override attach(): boolean {\r\n        if (!this.isCompatible() || !super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        this._walker = new Walker(this._sessionManager.scene.getEngine());\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Detaches the feature.\r\n     * Typically called automatically by the features manager.\r\n     * @returns true if detach succeeded, false otherwise\r\n     */\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n\r\n        this._walker = null;\r\n        return true;\r\n    }\r\n\r\n    protected _onXRFrame(frame: XRFrame): void {\r\n        const pose = frame.getViewerPose(this._sessionManager.baseReferenceSpace);\r\n        if (!pose) {\r\n            return;\r\n        }\r\n\r\n        const handednessScalar = this.locomotionTarget.getScene().useRightHandedSystem ? 1 : -1;\r\n\r\n        const m = pose.transform.matrix;\r\n        this._up.copyFromFloats(m[4], m[5], handednessScalar * m[6]);\r\n        this._forward.copyFromFloats(m[8], m[9], handednessScalar * m[10]);\r\n        this._position.copyFromFloats(m[12], m[13], handednessScalar * m[14]);\r\n\r\n        // Compute the nape position\r\n        this._forward.scaleAndAddToRef(0.05, this._position);\r\n        this._up.scaleAndAddToRef(-0.05, this._position);\r\n        this._walker!.update(this._position, this._forward);\r\n        this._movement.copyFrom(this._walker!.movementThisFrame);\r\n        if (!this._isLocomotionTargetWebXRCamera) {\r\n            Vector3.TransformNormalToRef(this._movement, this.locomotionTarget.getWorldMatrix(), this._movement);\r\n        }\r\n        this.locomotionTarget.position.addInPlace(this._movement);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRWalkingLocomotion.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRWalkingLocomotion(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRWalkingLocomotion.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRWalkingLocomotion(xrSessionManager, options);\r\n        },\r\n        WebXRWalkingLocomotion.Version,\r\n        false\r\n    );\r\n}\r\n","import { type InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { type RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { type Viewport } from \"core/Maths/math.viewport\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { type WebXRLayerType, WebXRLayerWrapper, type WebXRSpatialLayerType, type WebXRSupportedLayerType } from \"core/XR/webXRLayerWrapper\";\r\nimport { WebXRLayerRenderTargetTextureProvider } from \"core/XR/webXRRenderTargetTextureProvider\";\r\nimport { WebXRWebGLRenderTargetTextureProvider } from \"core/XR/webXRWebGLRenderTargetTextureProvider\";\r\nimport { type WebXRSessionManager } from \"core/XR/webXRSessionManager\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode.pure\";\r\n\r\n/**\r\n * The non-projection composition layers that can be positioned in an XR space.\r\n */\r\nexport type WebXRSpatialLayer = XRQuadLayer | XRCylinderLayer | XREquirectLayer | XRCubeLayer;\r\n\r\nexport type { WebXRSpatialLayerType } from \"core/XR/webXRLayerWrapper\";\r\n\r\n/**\r\n * Wraps an XR composition layer and creates its Babylon render target provider.\r\n * @typeParam LayerT the concrete WebXR composition layer type\r\n * @see https://playground.babylonjs.com/#TODARD#0\r\n */\r\nexport class WebXRCompositionLayerWrapper<\r\n    LayerT extends XRCompositionLayer = XRCompositionLayer,\r\n    LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType,\r\n> extends WebXRLayerWrapper<LayerTypeT> {\r\n    /**\r\n     * Whether this layer receives its content directly from an HTML media element.\r\n     */\r\n    public readonly isMediaLayer: boolean = false;\r\n\r\n    /**\r\n     * Whether Babylon should acquire subimages and expose render target textures for this layer.\r\n     */\r\n    public readonly usesRenderTargetProvider: boolean = true;\r\n\r\n    /**\r\n     * Whether the native layer exposes compositor opacity control.\r\n     */\r\n    public get isOpacitySupported(): boolean {\r\n        return \"opacity\" in this.layer;\r\n    }\r\n\r\n    /**\r\n     * Gets the compositor opacity applied to this layer.\r\n     * @returns The native opacity in the range 0 to 1.\r\n     * @throws If opacity is not supported by the active XR runtime.\r\n     */\r\n    public get opacity(): number {\r\n        this._assertControlSupported(\"opacity\");\r\n        return this.layer.opacity!;\r\n    }\r\n\r\n    /**\r\n     * Sets the compositor opacity applied to this layer.\r\n     * The native runtime clamps the value to the range 0 to 1.\r\n     * @param value The desired opacity.\r\n     * @throws If opacity is not supported by the active XR runtime.\r\n     */\r\n    public set opacity(value: number) {\r\n        this._assertControlSupported(\"opacity\");\r\n        this.layer.opacity = value;\r\n    }\r\n\r\n    /**\r\n     * Whether the native layer exposes compositor quality hints.\r\n     */\r\n    public get isQualitySupported(): boolean {\r\n        return \"quality\" in this.layer;\r\n    }\r\n\r\n    /**\r\n     * Gets the compositor quality hint applied to this layer.\r\n     * @returns The current native layer quality hint.\r\n     * @throws If quality hints are not supported by the active XR runtime.\r\n     */\r\n    public get quality(): XRLayerQuality {\r\n        this._assertControlSupported(\"quality\");\r\n        return this.layer.quality!;\r\n    }\r\n\r\n    /**\r\n     * Sets the compositor quality hint applied to this layer.\r\n     * @param value The desired quality hint.\r\n     * @throws If quality hints are not supported by the active XR runtime, or the native runtime rejects the value.\r\n     */\r\n    public set quality(value: XRLayerQuality) {\r\n        this._assertControlSupported(\"quality\");\r\n        this.layer.quality = value;\r\n    }\r\n\r\n    /**\r\n     * Whether the native layer exposes mono-presentation control.\r\n     */\r\n    public get isForceMonoPresentationSupported(): boolean {\r\n        return \"forceMonoPresentation\" in this.layer;\r\n    }\r\n\r\n    /**\r\n     * Gets whether the compositor presents the left-eye layer configuration to both eyes.\r\n     * @returns Whether mono presentation is forced.\r\n     * @throws If mono presentation control is not supported by the active XR runtime.\r\n     */\r\n    public get forceMonoPresentation(): boolean {\r\n        this._assertControlSupported(\"forceMonoPresentation\");\r\n        return this.layer.forceMonoPresentation!;\r\n    }\r\n\r\n    /**\r\n     * Sets whether the compositor presents the left-eye layer configuration to both eyes.\r\n     * Applications should continue rendering both eyes when this is enabled.\r\n     * @param value Whether to force mono presentation.\r\n     * @throws If mono presentation control is not supported by the active XR runtime.\r\n     */\r\n    public set forceMonoPresentation(value: boolean) {\r\n        this._assertControlSupported(\"forceMonoPresentation\");\r\n        this.layer.forceMonoPresentation = value;\r\n    }\r\n\r\n    constructor(\r\n        public override getWidth: () => number,\r\n        public override getHeight: () => number,\r\n        public override readonly layer: LayerT,\r\n        public override readonly layerType: LayerTypeT,\r\n        /**\r\n         * Whether the layer renders both views into a texture array.\r\n         */\r\n        public readonly isMultiview: boolean,\r\n        public createRTTProvider: (xrSessionManager: WebXRSessionManager) => WebXRLayerRenderTargetTextureProvider<LayerTypeT>,\r\n        public _originalInternalTexture: Nullable<InternalTexture> = null,\r\n        private readonly _destroyLayerOnDispose = false,\r\n        /**\r\n         * Whether the layer can only be rendered when its native `needsRedraw` flag is set.\r\n         */\r\n        public readonly isStatic = false\r\n    ) {\r\n        super(getWidth, getHeight, layer, layerType, createRTTProvider);\r\n    }\r\n\r\n    private _assertControlSupported(control: \"opacity\" | \"quality\" | \"forceMonoPresentation\"): void {\r\n        if (!(control in this.layer)) {\r\n            throw new Error(`XRCompositionLayer.${control} is not supported by this XR runtime.`);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the Babylon render-target resources and destroys the native layer when this wrapper owns it.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        if (this._destroyLayerOnDispose) {\r\n            this.layer.destroy();\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Wraps a positionable XR composition layer and synchronizes it with a Babylon transform node.\r\n * The node's scaling does not affect the physical dimensions of the layer.\r\n * @typeParam LayerT the concrete positionable WebXR layer type\r\n */\r\nexport class WebXRSpatialLayerWrapper<\r\n    LayerT extends WebXRSpatialLayer = WebXRSpatialLayer,\r\n    LayerTypeT extends WebXRSpatialLayerType = WebXRSpatialLayerType,\r\n> extends WebXRCompositionLayerWrapper<LayerT, LayerTypeT> {\r\n    private readonly _currentPosition = new Vector3();\r\n    private readonly _currentRotation = new Quaternion();\r\n    private readonly _lastPosition = new Vector3(Number.NaN, Number.NaN, Number.NaN);\r\n    private readonly _lastRotation = new Quaternion(Number.NaN, Number.NaN, Number.NaN, Number.NaN);\r\n\r\n    constructor(\r\n        getWidth: () => number,\r\n        getHeight: () => number,\r\n        layer: LayerT,\r\n        layerType: LayerTypeT,\r\n        isMultiview: boolean,\r\n        isStatic: boolean,\r\n        /**\r\n         * Whether the layer should follow changes to the session manager's reference space.\r\n         */\r\n        public readonly usesSessionReferenceSpace: boolean,\r\n        createRTTProvider: (xrSessionManager: WebXRSessionManager) => WebXRLayerRenderTargetTextureProvider<LayerTypeT>,\r\n        /**\r\n         * The Babylon node whose world position and rotation are applied to the native layer.\r\n         */\r\n        public readonly transformNode: TransformNode,\r\n        private readonly _ownsTransformNode: boolean\r\n    ) {\r\n        super(getWidth, getHeight, layer, layerType, isMultiview, createRTTProvider, null, true, isStatic);\r\n    }\r\n\r\n    /**\r\n     * Synchronizes the native layer with the current world transform of the Babylon node.\r\n     * @param useRightHandedSystem whether the Babylon scene uses right-handed coordinates\r\n     * @param worldScalingFactor the number of Babylon scene units represented by one meter\r\n     */\r\n    public updateFromTransformNode(useRightHandedSystem: boolean, worldScalingFactor: number): void {\r\n        this.transformNode.computeWorldMatrix(true).decompose(undefined, this._currentRotation, this._currentPosition);\r\n        this._currentPosition.scaleInPlace(1 / worldScalingFactor);\r\n\r\n        if (!useRightHandedSystem) {\r\n            this._currentPosition.z *= -1;\r\n            this._currentRotation.z *= -1;\r\n            this._currentRotation.w *= -1;\r\n        }\r\n\r\n        if (this._currentPosition.equals(this._lastPosition) && this._currentRotation.equals(this._lastRotation)) {\r\n            return;\r\n        }\r\n\r\n        this._lastPosition.copyFrom(this._currentPosition);\r\n        this._lastRotation.copyFrom(this._currentRotation);\r\n\r\n        const orientation = {\r\n            x: this._currentRotation.x,\r\n            y: this._currentRotation.y,\r\n            z: this._currentRotation.z,\r\n            w: this._currentRotation.w,\r\n        };\r\n        if (this.layerType === \"XRCubeLayer\") {\r\n            (this.layer as XRCubeLayer).orientation =\r\n                typeof DOMPointReadOnly === \"undefined\" ? (orientation as DOMPointReadOnly) : new DOMPointReadOnly(orientation.x, orientation.y, orientation.z, orientation.w);\r\n        } else {\r\n            (this.layer as XRQuadLayer | XRCylinderLayer | XREquirectLayer).transform = new XRRigidTransform(\r\n                {\r\n                    x: this._currentPosition.x,\r\n                    y: this._currentPosition.y,\r\n                    z: this._currentPosition.z,\r\n                },\r\n                orientation\r\n            );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Disposes the native layer wrapper and its Babylon transform node when the node was created by Babylon.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        if (this._ownsTransformNode) {\r\n            this.transformNode.dispose();\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Wraps an XRMediaBinding layer.\r\n * @typeParam LayerT the concrete media layer type\r\n */\r\nexport class WebXRMediaLayerWrapper<\r\n    LayerT extends Exclude<WebXRSpatialLayer, XRCubeLayer> = Exclude<WebXRSpatialLayer, XRCubeLayer>,\r\n    LayerTypeT extends Exclude<WebXRSpatialLayerType, \"XRCubeLayer\"> = Exclude<WebXRSpatialLayerType, \"XRCubeLayer\">,\r\n> extends WebXRSpatialLayerWrapper<LayerT, LayerTypeT> {\r\n    /**\r\n     * Media layers receive their contents directly from the user agent.\r\n     */\r\n    public override readonly isMediaLayer: boolean = true;\r\n    /**\r\n     * Media layers are populated directly by the user agent.\r\n     */\r\n    public override readonly usesRenderTargetProvider: boolean = false;\r\n\r\n    /**\r\n     * Creates a wrapper for a media-backed spatial layer.\r\n     * @param getWidth returns the current video width\r\n     * @param getHeight returns the current video height\r\n     * @param layer the native media composition layer\r\n     * @param layerType the concrete spatial layer type\r\n     * @param transformNode the Babylon transform synchronized with the native layer\r\n     * @param ownsTransformNode whether the wrapper should dispose the transform node\r\n     * @param usesSessionReferenceSpace whether the layer should follow session reference-space changes\r\n     */\r\n    constructor(\r\n        getWidth: () => number,\r\n        getHeight: () => number,\r\n        layer: LayerT,\r\n        layerType: LayerTypeT,\r\n        transformNode: TransformNode,\r\n        ownsTransformNode: boolean,\r\n        usesSessionReferenceSpace: boolean\r\n    ) {\r\n        super(\r\n            getWidth,\r\n            getHeight,\r\n            layer,\r\n            layerType,\r\n            false,\r\n            false,\r\n            usesSessionReferenceSpace,\r\n            (sessionManager) => new WebXRNoRenderTargetTextureProvider(sessionManager, this),\r\n            transformNode,\r\n            ownsTransformNode\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Wraps a native cube layer and exposes its raw subimage.\r\n * Cube layers require six face uploads or render passes and therefore do not use Babylon's 2D composition-layer render target provider.\r\n */\r\nexport class WebXRCubeLayerWrapper extends WebXRSpatialLayerWrapper<XRCubeLayer, \"XRCubeLayer\"> {\r\n    /**\r\n     * Cube layers are populated through raw cubemap or array-layer access.\r\n     */\r\n    public override readonly usesRenderTargetProvider: boolean = false;\r\n\r\n    constructor(\r\n        getWidth: () => number,\r\n        getHeight: () => number,\r\n        layer: XRCubeLayer,\r\n        isStatic: boolean,\r\n        usesSessionReferenceSpace: boolean,\r\n        private readonly _binding: XRWebGLBinding | XRGPUBinding,\r\n        transformNode: TransformNode,\r\n        ownsTransformNode: boolean\r\n    ) {\r\n        super(\r\n            getWidth,\r\n            getHeight,\r\n            layer,\r\n            \"XRCubeLayer\",\r\n            false,\r\n            isStatic,\r\n            usesSessionReferenceSpace,\r\n            (sessionManager) => new WebXRNoRenderTargetTextureProvider(sessionManager, this),\r\n            transformNode,\r\n            ownsTransformNode\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Gets the compositor-owned cube subimage for the current frame.\r\n     * WebGL callers must populate all six cubemap faces. WebGPU callers must render to six consecutive array layers beginning at the descriptor's base array layer.\r\n     * @param frame the current XR frame\r\n     * @param eye the eye to retrieve for stereo cube layers\r\n     * @returns the raw WebGL or WebGPU cube subimage\r\n     */\r\n    public getSubImage(frame: XRFrame, eye?: XREye): XRWebGLSubImage | XRGPUSubImage {\r\n        return this._binding.getSubImage(this.layer, frame, eye);\r\n    }\r\n}\r\n\r\n/**\r\n * Composition layers that are populated outside Babylon do not expose render targets.\r\n * @internal\r\n */\r\nclass WebXRNoRenderTargetTextureProvider<LayerTypeT extends WebXRSupportedLayerType> extends WebXRLayerRenderTargetTextureProvider<LayerTypeT> {\r\n    /**\r\n     * Creates a no-render-target provider.\r\n     * @param sessionManager the current XR session manager\r\n     * @param layerWrapper the composition layer wrapper\r\n     */\r\n    constructor(sessionManager: WebXRSessionManager, layerWrapper: WebXRCompositionLayerWrapper<XRCompositionLayer, LayerTypeT>) {\r\n        super(sessionManager.scene, layerWrapper);\r\n    }\r\n\r\n    /**\r\n     * Media layers do not expose a viewport.\r\n     * @param _viewport unused viewport\r\n     * @param _view unused XR view\r\n     * @returns always `false`\r\n     */\r\n    public trySetViewportForView(_viewport: Viewport, _view: XRView): boolean {\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Media layers do not expose render target textures.\r\n     * @param _eye unused XR eye\r\n     * @returns always `null`\r\n     */\r\n    public getRenderTargetTextureForEye(_eye: XREye): Nullable<RenderTargetTexture> {\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * Media layers do not expose render target textures.\r\n     * @param _view unused XR view\r\n     * @returns always `null`\r\n     */\r\n    public getRenderTargetTextureForView(_view: XRView): Nullable<RenderTargetTexture> {\r\n        return null;\r\n    }\r\n}\r\n\r\n/**\r\n * Provides render target textures and other important rendering information for a given XRCompositionLayer.\r\n * @internal\r\n */\r\nexport class WebXRCompositionLayerRenderTargetTextureProvider<\r\n    LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType,\r\n> extends WebXRWebGLRenderTargetTextureProvider<LayerTypeT> {\r\n    protected _lastSubImages = new Map<XREye, XRWebGLSubImage>();\r\n    private _compositionLayer: XRCompositionLayer;\r\n    /**\r\n     * Fires every time a new render target texture is created (either for eye, for view, or for the entire frame)\r\n     */\r\n    public onRenderTargetTextureCreatedObservable = new Observable<{ texture: RenderTargetTexture; eye?: XREye }>();\r\n\r\n    constructor(\r\n        protected readonly _xrSessionManager: WebXRSessionManager,\r\n        protected readonly _xrWebGLBinding: XRWebGLBinding,\r\n        public override readonly layerWrapper: WebXRCompositionLayerWrapper<XRCompositionLayer, LayerTypeT>\r\n    ) {\r\n        super(_xrSessionManager.scene, layerWrapper);\r\n        this._compositionLayer = layerWrapper.layer;\r\n    }\r\n\r\n    protected _getRenderTargetForSubImage(subImage: XRWebGLSubImage, eye: XREye = \"none\") {\r\n        const lastSubImage = this._lastSubImages.get(eye);\r\n        const eyeIndex = eye == \"right\" ? 1 : 0;\r\n\r\n        const colorTextureWidth = subImage.colorTextureWidth ?? subImage.textureWidth;\r\n        const colorTextureHeight = subImage.colorTextureHeight ?? subImage.textureHeight;\r\n\r\n        if (!this._renderTargetTextures[eyeIndex] || lastSubImage?.textureWidth !== colorTextureWidth || lastSubImage?.textureHeight !== colorTextureHeight) {\r\n            let depthStencilTexture;\r\n            const depthStencilTextureWidth = subImage.depthStencilTextureWidth ?? colorTextureWidth;\r\n            const depthStencilTextureHeight = subImage.depthStencilTextureHeight ?? colorTextureHeight;\r\n            if (colorTextureWidth === depthStencilTextureWidth || colorTextureHeight === depthStencilTextureHeight) {\r\n                depthStencilTexture = subImage.depthStencilTexture;\r\n            }\r\n\r\n            this._renderTargetTextures[eyeIndex] = this._createRenderTargetTexture(\r\n                colorTextureWidth,\r\n                colorTextureHeight,\r\n                null,\r\n                subImage.colorTexture,\r\n                depthStencilTexture,\r\n                this.layerWrapper.isMultiview\r\n            );\r\n\r\n            this._framebufferDimensions = {\r\n                framebufferWidth: colorTextureWidth,\r\n                framebufferHeight: colorTextureHeight,\r\n            };\r\n            this.onRenderTargetTextureCreatedObservable.notifyObservers({ texture: this._renderTargetTextures[eyeIndex], eye });\r\n        }\r\n\r\n        this._lastSubImages.set(eye, subImage);\r\n        return this._renderTargetTextures[eyeIndex];\r\n    }\r\n    private _getSubImageForEye(eye?: XREye): Nullable<XRWebGLSubImage> {\r\n        const currentFrame = this._xrSessionManager.currentFrame;\r\n        if (currentFrame) {\r\n            return this._xrWebGLBinding.getSubImage(this._compositionLayer, currentFrame, eye);\r\n        }\r\n        return null;\r\n    }\r\n    public getRenderTargetTextureForEye(eye?: XREye): Nullable<RenderTargetTexture> {\r\n        const subImage = this._getSubImageForEye(eye);\r\n        if (subImage) {\r\n            return this._getRenderTargetForSubImage(subImage, eye);\r\n        }\r\n        return null;\r\n    }\r\n    public getRenderTargetTextureForView(view?: XRView): Nullable<RenderTargetTexture> {\r\n        return this.getRenderTargetTextureForEye(view?.eye);\r\n    }\r\n\r\n    protected _setViewportForSubImage(viewport: Viewport, subImage: XRWebGLSubImage) {\r\n        const textureWidth = subImage.colorTextureWidth ?? subImage.textureWidth;\r\n        const textureHeight = subImage.colorTextureHeight ?? subImage.textureHeight;\r\n        const xrViewport = subImage.viewport;\r\n        viewport.x = xrViewport.x / textureWidth;\r\n        viewport.y = xrViewport.y / textureHeight;\r\n        viewport.width = xrViewport.width / textureWidth;\r\n        viewport.height = xrViewport.height / textureHeight;\r\n    }\r\n\r\n    public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n        const subImage = this._lastSubImages.get(view.eye) || this._getSubImageForEye(view.eye);\r\n        if (subImage) {\r\n            this._setViewportForSubImage(viewport, subImage);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n}\r\n","import { type WebXRSessionManager } from \"core/XR/webXRSessionManager\";\r\nimport { WebXRCompositionLayerRenderTargetTextureProvider, WebXRCompositionLayerWrapper } from \"./WebXRCompositionLayer\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { type RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { type Viewport } from \"core/Maths/math.viewport\";\r\n\r\n/**\r\n * Wraps xr projection layers.\r\n * @internal\r\n */\r\nexport class WebXRProjectionLayerWrapper extends WebXRCompositionLayerWrapper {\r\n    constructor(\r\n        public override readonly layer: XRProjectionLayer,\r\n        isMultiview: boolean,\r\n        xrGLBinding: XRWebGLBinding\r\n    ) {\r\n        super(\r\n            () => layer.textureWidth,\r\n            () => layer.textureHeight,\r\n            layer,\r\n            \"XRProjectionLayer\",\r\n            isMultiview,\r\n            (sessionManager) => new WebXRProjectionLayerRenderTargetTextureProvider(sessionManager, xrGLBinding, this)\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Provides render target textures and other important rendering information for a given XRProjectionLayer.\r\n * @internal\r\n */\r\nclass WebXRProjectionLayerRenderTargetTextureProvider extends WebXRCompositionLayerRenderTargetTextureProvider {\r\n    private readonly _projectionLayer: XRProjectionLayer;\r\n\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        _xrWebGLBinding: XRWebGLBinding,\r\n        public override readonly layerWrapper: WebXRProjectionLayerWrapper\r\n    ) {\r\n        super(_xrSessionManager, _xrWebGLBinding, layerWrapper);\r\n        this._projectionLayer = layerWrapper.layer;\r\n    }\r\n\r\n    private _getSubImageForView(view: XRView): XRWebGLSubImage {\r\n        return this._xrWebGLBinding.getViewSubImage(this._projectionLayer, view);\r\n    }\r\n\r\n    public override getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n        return this._getRenderTargetForSubImage(this._getSubImageForView(view), view.eye);\r\n    }\r\n\r\n    public override getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\r\n        const lastSubImage = this._lastSubImages.get(eye);\r\n        if (lastSubImage) {\r\n            return this._getRenderTargetForSubImage(lastSubImage, eye);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public override trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n        const subImage = this._lastSubImages.get(view.eye) || this._getSubImageForView(view);\r\n        if (subImage) {\r\n            this._setViewportForSubImage(viewport, subImage);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport const DefaultXRProjectionLayerInit: XRProjectionLayerInit = {\r\n    textureType: \"texture\",\r\n    colorFormat: 0x1908 /* WebGLRenderingContext.RGBA */,\r\n    depthFormat: 0x88f0 /* WebGLRenderingContext.DEPTH24_STENCIL8 */,\r\n    scaleFactor: 1.0,\r\n    clearOnAccess: false,\r\n};\r\n","import { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\n\n/**\n * A render target texture for a WebXR layer that renders into a specific array layer of its underlying\n * texture (e.g. one layer per eye of a layered projection-layer texture array).\n *\n * The array-layer index is kept here, in the XR area, rather than on the general-purpose\n * {@link RenderTargetTexture}. It mirrors how {@link MultiviewRenderTarget} keeps its XR-specific bind\n * behavior in a subclass that overrides {@link _bindFrameBuffer}: the scene binds a camera's\n * `outputRenderTarget` with no arguments, so the target itself must know which layer to bind.\n * @internal\n */\nexport class WebXRLayerRenderTargetTexture extends RenderTargetTexture {\n    /**\n     * The array layer index this render target binds when the scene binds it with no explicit layer.\n     * Defaults to 0. Set per eye by the WebGPU XR layer provider so each eye renders into its own layer.\n     */\n    public layerIndex = 0;\n\n    /**\n     * @internal\n     * @param faceIndex face index to bind to if this is a cubetexture\n     * @param layer defines the index of the texture to bind in the array; defaults to {@link layerIndex}\n     */\n    public override _bindFrameBuffer(faceIndex: number = 0, layer: number = this.layerIndex) {\n        super._bindFrameBuffer(faceIndex, layer);\n    }\n}\n","import { Constants } from \"../Engines/constants\";\nimport { type WebGPUEngine } from \"../Engines/webgpuEngine\";\nimport { type WebGPURenderTargetWrapper } from \"../Engines/WebGPU/webgpuRenderTargetWrapper\";\nimport { type InternalTexture } from \"../Materials/Textures/internalTexture\";\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\nimport { Color4 } from \"../Maths/math.color.pure\";\nimport { type Nullable } from \"../types\";\nimport { WebXRLayerRenderTargetTexture } from \"./webXRLayerRenderTargetTexture\";\nimport { type WebXRLayerType, type WebXRLayerWrapper, type WebXRSupportedLayerType } from \"./webXRLayerWrapper\";\nimport { WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\nimport { type WebXRSessionManager } from \"./webXRSessionManager\";\n\n/**\n * Maps a WebGPU depth/stencil {@link GPUTextureFormat} to the matching Babylon `TEXTUREFORMAT_*` constant.\n *\n * The engine reads `InternalTexture.format` (a Babylon constant) when it builds the render pass depth\n * attachment for a render target, so a depth texture wrapped from an external `GPUTexture` must carry the\n * correct Babylon format or the depth attachment pipeline format will not match the sub-image's texture.\n * @param format the WebGPU depth/stencil format requested when the layer was created\n * @returns the matching Babylon texture format constant\n */\nfunction GetBabylonDepthFormat(format: GPUTextureFormat): number {\n    switch (format) {\n        case \"depth16unorm\":\n            return Constants.TEXTUREFORMAT_DEPTH16;\n        case \"depth24plus\":\n            return Constants.TEXTUREFORMAT_DEPTH24;\n        case \"depth24plus-stencil8\":\n            return Constants.TEXTUREFORMAT_DEPTH24_STENCIL8;\n        case \"depth32float\":\n            return Constants.TEXTUREFORMAT_DEPTH32_FLOAT;\n        case \"depth32float-stencil8\":\n            return Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8;\n        case \"stencil8\":\n            return Constants.TEXTUREFORMAT_STENCIL8;\n        default:\n            // Fall back to a combined depth/stencil format, which is the projection layer default.\n            return Constants.TEXTUREFORMAT_DEPTH24_STENCIL8;\n    }\n}\n\n/**\n * Provides render target textures for WebGPU-backed XR layers. Owns all WebGPU-specific texture wrapping\n * (via {@link WebGPUEngine.wrapWebGPUTexture} / {@link WebGPUEngine.updateWrappedWebGPUTexture}) so the base\n * provider can stay graphics-API-agnostic. Mirrors {@link WebXRWebGLRenderTargetTextureProvider} for the\n * WebGPU (XRGPUBinding) backend.\n * @internal\n */\nexport abstract class WebXRWebGPURenderTargetTextureProvider<\n    LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType,\n> extends WebXRLayerRenderTargetTextureProvider<LayerTypeT> {\n    private readonly _transparentClearColor = new Color4(0, 0, 0, 0);\n\n    constructor(\n        protected readonly _xrSessionManager: WebXRSessionManager,\n        layerWrapper: WebXRLayerWrapper<LayerTypeT>\n    ) {\n        super(_xrSessionManager.scene, layerWrapper);\n    }\n\n    private get _webgpuEngine(): WebGPUEngine {\n        return this._engine as WebGPUEngine;\n    }\n\n    private _wrapColorTexture(texture: GPUTexture): InternalTexture {\n        return this._webgpuEngine.wrapWebGPUTexture(texture);\n    }\n\n    private _wrapDepthTexture(texture: GPUTexture, depthStencilFormat: GPUTextureFormat): InternalTexture {\n        const internalTexture = this._webgpuEngine.wrapWebGPUTexture(texture);\n        // The engine derives the color attachment format automatically from the wrapped hardware texture,\n        // but the depth attachment format is read from the Babylon InternalTexture.format, which\n        // wrapWebGPUTexture does not set. Assign it here from the format the layer was created with.\n        internalTexture.format = GetBabylonDepthFormat(depthStencilFormat);\n        return internalTexture;\n    }\n\n    /**\n     * Builds the render target shell as a {@link WebXRLayerRenderTargetTexture} for the single-view path so\n     * each eye can bind its own array layer of a layered projection-layer texture. Multiview is not yet\n     * supported on this WebGPU path and is delegated to the base implementation.\n     * @param width the width of the render target\n     * @param height the height of the render target\n     * @param multiview whether the render target should be a multiview render target\n     * @returns the created (but not yet registered) render target texture\n     */\n    protected override _createRenderTargetTextureShell(width: number, height: number, multiview: boolean): RenderTargetTexture {\n        if (multiview) {\n            return super._createRenderTargetTextureShell(width, height, multiview);\n        }\n        const renderTargetTexture = new WebXRLayerRenderTargetTexture(\"XR renderTargetTexture\", { width, height }, this._scene);\n        renderTargetTexture.renderTarget!._samples = renderTargetTexture.samples;\n        // The projection-layer texture is presented directly by the XR compositor (top-left origin, never\n        // re-sampled by Babylon), so opt this target out of the engine's render-target Y-flip / winding\n        // compensation and render it upright, matching the WebXR/WebGPU spec's plain render pass.\n        (renderTargetTexture.renderTarget as WebGPURenderTargetWrapper)._disableEngineYFlip = true;\n        return renderTargetTexture;\n    }\n\n    /**\n     * Wraps the sub-image's color (and optional depth/stencil) GPUTextures and builds a new render target\n     * texture around them. Use this on first creation and whenever the sub-image texture size changes.\n     * @param width the width of the render target\n     * @param height the height of the render target\n     * @param colorTexture the sub-image color GPUTexture\n     * @param depthStencilTexture the sub-image depth/stencil GPUTexture, if any\n     * @param depthStencilFormat the WebGPU depth/stencil format the layer was created with, if depth is provided\n     * @param multiview whether the render target should be a multiview render target\n     * @returns the created render target texture\n     */\n    protected _createRenderTargetTextureFromGPUTextures(\n        width: number,\n        height: number,\n        colorTexture: GPUTexture,\n        depthStencilTexture: Nullable<GPUTexture>,\n        depthStencilFormat: GPUTextureFormat | undefined,\n        multiview: boolean\n    ): WebXRLayerRenderTargetTexture {\n        const color = this._wrapColorTexture(colorTexture);\n        const depth = depthStencilTexture && depthStencilFormat ? this._wrapDepthTexture(depthStencilTexture, depthStencilFormat) : null;\n        // Single-view (the only path here) always builds a WebXRLayerRenderTargetTexture via the shell override above.\n        const renderTargetTexture = this._createRenderTargetTextureInternal(width, height, color, depth, multiview) as WebXRLayerRenderTargetTexture;\n        this._attachPerEyeClearObserver(renderTargetTexture);\n        return renderTargetTexture;\n    }\n\n    /**\n     * Ensures this render target is cleared every frame, including for the right eye.\n     *\n     * `Scene._clearFrameBuffer` skips clearing the right rig camera's framebuffer (`!camera.isRightCamera`).\n     * That is a valid optimization for WebGL2 stereo, where both eyes render into a single side-by-side\n     * texture and the left eye's full clear already covers the whole texture. WebGPU projection layers give\n     * each eye its OWN render target (a distinct array layer rendered in a separate render pass), so the\n     * right eye's color and — critically — depth would never be cleared, leaving its depth test to reject\n     * every fragment (a black right eye). The scene notifies `onClearObservable` regardless of\n     * `camera.isRightCamera`, so this observer clears both eyes' targets. WebGL providers never attach it,\n     * so the WebGL path is unchanged.\n     *\n     * Color is cleared at most once per ENGINE FRAME, not once per `Scene.render`. The distinction matters:\n     * more than one scene can render the same XR camera within a single XR frame. `UtilityLayerRenderer`\n     * (used by controller pointer selection and near interaction) renders a second scene through the same\n     * rig cameras, and every `Scene.render` resets `RenderTargetTexture._cleared` for those cameras' targets\n     * (`Scene._checkCameraRenderTarget`), so a `_cleared`-based guard is defeated and each eye is re-cleared\n     * after it was drawn — presenting a clear-colored frame with the geometry gone. `AbstractEngine.frameId`\n     * only advances in `endFrame`, once per XR frame, so unlike `_cleared` it cannot be reset by another\n     * scene rendering the same camera.\n     *\n     * In immersive AR, color is cleared to transparent when `WebXRExperienceHelper` disables\n     * `Scene.autoClear`. WebGL XR framebuffers are cleared to transparent by the user agent, but WebGPU render\n     * passes require the application to request that clear explicitly. Skipping it leaves pixels from prior\n     * frames in passthrough regions, producing trails behind moving objects.\n     *\n     * Depth and stencil are still cleared on every notification, matching the previous behavior and the\n     * expectations of overlay scenes that draw on top of the main scene.\n     * @param renderTargetTexture the per-eye render target to clear each frame\n     */\n    private _attachPerEyeClearObserver(renderTargetTexture: RenderTargetTexture): void {\n        let lastColorClearedFrameId = -1;\n        renderTargetTexture.onClearObservable.add((engine) => {\n            // Honor skipInitialClear so this observer preserves the default clear semantics it replaces.\n            if (renderTargetTexture.skipInitialClear) {\n                return;\n            }\n            const scene = renderTargetTexture.getScene();\n            const isImmersiveAR = this._xrSessionManager.sessionMode === \"immersive-ar\";\n            // When autoClear is disabled the scene does not clear render targets; match that so this observer\n            // does not force a clear the user opted out of. Immersive AR is the exception: the experience\n            // helper disables autoClear because WebGL XR is cleared by the user agent, while WebGPU is not.\n            if (scene && !scene.autoClear && !isImmersiveAR) {\n                return;\n            }\n            const clearColor = engine.frameId !== lastColorClearedFrameId;\n            const color = isImmersiveAR && scene && !scene.autoClear ? this._transparentClearColor : (renderTargetTexture.clearColor ?? scene?.clearColor ?? null);\n            engine.clear(color, clearColor, true, true);\n            if (clearColor) {\n                lastColorClearedFrameId = engine.frameId;\n            }\n            // Kept in sync so anything else reading the flag still sees this target as cleared this frame.\n            renderTargetTexture._cleared = true;\n        });\n    }\n\n    /**\n     * Repoints the wrapped color/depth textures of an existing render target at the current frame's\n     * GPUTextures, preserving the RenderTargetTexture / InternalTexture identity held by the XR camera's\n     * `outputRenderTarget`. The sub-image textures are only valid for the current frame and may rotate from\n     * a compositor pool, so this must run every frame. The new GPUTextures must have the same dimensions as\n     * the wrapped ones (guaranteed by the caller's size-change branch, which rebuilds instead).\n     * @param renderTargetTexture the render target whose wrapped textures should be repointed\n     * @param colorTexture the current frame's color GPUTexture\n     * @param depthStencilTexture the current frame's depth/stencil GPUTexture, if any\n     */\n    protected _updateRenderTargetTextureFromGPUTextures(renderTargetTexture: RenderTargetTexture, colorTexture: GPUTexture, depthStencilTexture: Nullable<GPUTexture>): void {\n        const color = renderTargetTexture._texture;\n        if (color) {\n            this._webgpuEngine.updateWrappedWebGPUTexture(color, colorTexture);\n        }\n        const depth = renderTargetTexture.renderTarget?._depthStencilTexture;\n        if (depth && depthStencilTexture) {\n            this._webgpuEngine.updateWrappedWebGPUTexture(depth, depthStencilTexture);\n        }\n    }\n}\n","import { type RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\nimport { type Viewport } from \"core/Maths/math.viewport\";\nimport { Observable } from \"core/Misc/observable\";\nimport { type WebXRLayerRenderTargetTexture } from \"core/XR/webXRLayerRenderTargetTexture\";\nimport { type WebXRLayerType, type WebXRSupportedLayerType } from \"core/XR/webXRLayerWrapper\";\nimport { type WebXRLayerRenderTargetTextureProvider } from \"core/XR/webXRRenderTargetTextureProvider\";\nimport { WebXRWebGPURenderTargetTextureProvider } from \"core/XR/webXRWebGPURenderTargetTextureProvider\";\nimport { type WebXRSessionManager } from \"core/XR/webXRSessionManager\";\nimport { type Nullable } from \"core/types\";\nimport { WebXRCompositionLayerWrapper } from \"./WebXRCompositionLayer\";\n\n/**\n * Wraps xr composition layers for the WebGPU (XRGPUBinding) backend.\n * Mirrors {@link WebXRCompositionLayerWrapper} for WebGPU.\n * @internal\n */\nexport class WebXRWebGPUCompositionLayerWrapper extends WebXRCompositionLayerWrapper {\n    constructor(\n        getWidth: () => number,\n        getHeight: () => number,\n        layer: XRCompositionLayer,\n        layerType: WebXRLayerType,\n        isMultiview: boolean,\n        createRTTProvider: (xrSessionManager: WebXRSessionManager) => WebXRLayerRenderTargetTextureProvider\n    ) {\n        super(getWidth, getHeight, layer, layerType, isMultiview, createRTTProvider);\n    }\n}\n\n/**\n * Provides render target textures and other important rendering information for a given XRCompositionLayer\n * on the WebGPU backend. Mirrors {@link WebXRCompositionLayerRenderTargetTextureProvider}, but wraps\n * {@link XRGPUSubImage} GPUTextures instead of WebGL textures.\n * @internal\n */\nexport class WebXRWebGPUCompositionLayerRenderTargetTextureProvider<\n    LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType,\n> extends WebXRWebGPURenderTargetTextureProvider<LayerTypeT> {\n    protected _lastSubImages = new Map<XREye, XRGPUSubImage>();\n    /**\n     * Per-eye render targets, indexed by eye (0 = left/none, 1 = right). Kept separate from the base\n     * `_renderTargetTextures` registry: that array is an append-only owned list (each entry is disposed once\n     * on provider dispose), whereas this map is a mutable per-eye slot. Reusing `_renderTargetTextures` as\n     * both would let a rebuilt eye target both stay in the registry (leaking / double-disposing the old one)\n     * and grow the registry unboundedly on repeated size changes.\n     */\n    protected _renderTargetTexturesByEye: WebXRLayerRenderTargetTexture[] = [];\n    private _compositionLayer: XRCompositionLayer;\n    /**\n     * Fires every time a new render target texture is created (either for eye, for view, or for the entire frame)\n     */\n    public onRenderTargetTextureCreatedObservable = new Observable<{ texture: RenderTargetTexture; eye?: XREye }>();\n\n    constructor(\n        _xrSessionManager: WebXRSessionManager,\n        protected readonly _xrGPUBinding: XRGPUBinding,\n        public override readonly layerWrapper: WebXRCompositionLayerWrapper<XRCompositionLayer, LayerTypeT>,\n        protected readonly _depthStencilFormat?: GPUTextureFormat\n    ) {\n        super(_xrSessionManager, layerWrapper);\n        this._compositionLayer = layerWrapper.layer;\n    }\n\n    protected _getRenderTargetForSubImage(subImage: XRGPUSubImage, eye: XREye = \"none\") {\n        const lastSubImage = this._lastSubImages.get(eye);\n        const eyeIndex = eye == \"right\" ? 1 : 0;\n\n        const colorTexture = subImage.colorTexture;\n        const colorTextureWidth = colorTexture.width;\n        const colorTextureHeight = colorTexture.height;\n\n        const depthStencilTexture = subImage.depthStencilTexture ?? null;\n\n        const existingRenderTarget = this._renderTargetTexturesByEye[eyeIndex];\n        const sizeChanged = !existingRenderTarget || lastSubImage?.colorTexture.width !== colorTextureWidth || lastSubImage?.colorTexture.height !== colorTextureHeight;\n\n        if (sizeChanged) {\n            if (existingRenderTarget) {\n                // A previous target for this eye exists (the sub-image size changed, e.g. a scale-factor or\n                // display-config change). Dispose it and remove it from the owned registry before creating the\n                // replacement so the registry does not accumulate stale entries or double-dispose on teardown.\n                this._destroyRenderTargetTexture(existingRenderTarget);\n            }\n            this._renderTargetTexturesByEye[eyeIndex] = this._createRenderTargetTextureFromGPUTextures(\n                colorTextureWidth,\n                colorTextureHeight,\n                colorTexture,\n                depthStencilTexture,\n                this._depthStencilFormat,\n                this.layerWrapper.isMultiview\n            );\n\n            this._framebufferDimensions = {\n                framebufferWidth: colorTextureWidth,\n                framebufferHeight: colorTextureHeight,\n            };\n            this.onRenderTargetTextureCreatedObservable.notifyObservers({ texture: this._renderTargetTexturesByEye[eyeIndex], eye });\n        } else {\n            // Same size: repoint the wrapped textures at this frame's GPUTextures, preserving the\n            // RenderTargetTexture / InternalTexture identity held by the XR camera's outputRenderTarget.\n            this._updateRenderTargetTextureFromGPUTextures(existingRenderTarget, colorTexture, depthStencilTexture);\n        }\n\n        this._lastSubImages.set(eye, subImage);\n\n        // The projection-layer color/depth textures may be a texture ARRAY with one layer per eye\n        // (depthOrArrayLayers > 1). The sub-image's view descriptor carries the authoritative array-layer\n        // index for this eye, so route it into the render target's bind so each eye renders into its own\n        // layer. For non-layered textures this is 0 (unchanged behavior).\n        const renderTargetTexture = this._renderTargetTexturesByEye[eyeIndex];\n        renderTargetTexture.layerIndex = subImage.getViewDescriptor().baseArrayLayer ?? 0;\n\n        return renderTargetTexture;\n    }\n\n    private _getSubImageForEye(eye?: XREye): Nullable<XRGPUSubImage> {\n        const currentFrame = this._xrSessionManager.currentFrame;\n        if (currentFrame) {\n            return this._xrGPUBinding.getSubImage(this._compositionLayer, currentFrame, eye);\n        }\n        return null;\n    }\n\n    public getRenderTargetTextureForEye(eye?: XREye): Nullable<RenderTargetTexture> {\n        const subImage = this._getSubImageForEye(eye);\n        if (subImage) {\n            return this._getRenderTargetForSubImage(subImage, eye);\n        }\n        return null;\n    }\n\n    public getRenderTargetTextureForView(view?: XRView): Nullable<RenderTargetTexture> {\n        return this.getRenderTargetTextureForEye(view?.eye);\n    }\n\n    protected _setViewportForSubImage(viewport: Viewport, subImage: XRGPUSubImage) {\n        const textureWidth = subImage.colorTexture.width;\n        const textureHeight = subImage.colorTexture.height;\n        const xrViewport = subImage.viewport;\n        viewport.x = xrViewport.x / textureWidth;\n        viewport.y = xrViewport.y / textureHeight;\n        viewport.width = xrViewport.width / textureWidth;\n        viewport.height = xrViewport.height / textureHeight;\n    }\n\n    public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\n        const subImage = this._lastSubImages.get(view.eye) || this._getSubImageForEye(view.eye);\n        if (subImage) {\n            this._setViewportForSubImage(viewport, subImage);\n            return true;\n        }\n        return false;\n    }\n}\n","import { type WebXRSessionManager } from \"core/XR/webXRSessionManager\";\nimport { WebXRWebGPUCompositionLayerRenderTargetTextureProvider, WebXRWebGPUCompositionLayerWrapper } from \"./WebXRWebGPUCompositionLayer\";\nimport { type Nullable } from \"core/types\";\nimport { type RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\nimport { type Viewport } from \"core/Maths/math.viewport\";\n\n/**\n * Wraps xr projection layers for the WebGPU (XRGPUBinding) backend.\n * Mirrors {@link WebXRProjectionLayerWrapper} for WebGPU.\n * @internal\n */\nexport class WebXRWebGPUProjectionLayerWrapper extends WebXRWebGPUCompositionLayerWrapper {\n    constructor(\n        public override readonly layer: XRProjectionLayer,\n        isMultiview: boolean,\n        xrGPUBinding: XRGPUBinding,\n        depthStencilFormat?: GPUTextureFormat\n    ) {\n        super(\n            () => layer.textureWidth,\n            () => layer.textureHeight,\n            layer,\n            \"XRProjectionLayer\",\n            isMultiview,\n            (sessionManager) => new WebXRWebGPUProjectionLayerRenderTargetTextureProvider(sessionManager, xrGPUBinding, this, depthStencilFormat)\n        );\n    }\n}\n\n/**\n * Provides render target textures and other important rendering information for a given XRProjectionLayer\n * on the WebGPU backend.\n * @internal\n */\nclass WebXRWebGPUProjectionLayerRenderTargetTextureProvider extends WebXRWebGPUCompositionLayerRenderTargetTextureProvider {\n    private readonly _projectionLayer: XRProjectionLayer;\n\n    constructor(\n        _xrSessionManager: WebXRSessionManager,\n        _xrGPUBinding: XRGPUBinding,\n        public override readonly layerWrapper: WebXRWebGPUProjectionLayerWrapper,\n        depthStencilFormat?: GPUTextureFormat\n    ) {\n        super(_xrSessionManager, _xrGPUBinding, layerWrapper, depthStencilFormat);\n        this._projectionLayer = layerWrapper.layer;\n    }\n\n    private _getSubImageForView(view: XRView): XRGPUSubImage {\n        return this._xrGPUBinding.getViewSubImage(this._projectionLayer, view);\n    }\n\n    public override getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\n        return this._getRenderTargetForSubImage(this._getSubImageForView(view), view.eye);\n    }\n\n    public override getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\n        const lastSubImage = this._lastSubImages.get(eye);\n        if (lastSubImage) {\n            return this._getRenderTargetForSubImage(lastSubImage, eye);\n        }\n        return null;\n    }\n\n    public override trySetViewportForView(viewport: Viewport, view: XRView): boolean {\n        const subImage = this._lastSubImages.get(view.eye) || this._getSubImageForView(view);\n        if (subImage) {\n            this._setViewportForSubImage(viewport, subImage);\n            return true;\n        }\n        return false;\n    }\n}\n\n/**\n * The default depth/stencil format used for a WebGPU projection layer.\n * Mirrors the WebGL default (DEPTH24_STENCIL8).\n * @internal\n */\nexport const DefaultXRGPUProjectionLayerDepthStencilFormat: GPUTextureFormat = \"depth24plus-stencil8\";\n\n/**\n * Builds the default XRGPUProjectionLayerInit for a WebGPU projection layer.\n * The color format must be the binding's preferred color format, so it is provided by the caller.\n * @param colorFormat the preferred color format reported by the XRGPUBinding\n * @param depthStencilFormat the depth/stencil format to request (defaults to depth24plus-stencil8)\n * @returns the projection layer init to pass to XRGPUBinding.createProjectionLayer\n * @internal\n */\nexport function CreateDefaultXRGPUProjectionLayerInit(\n    colorFormat: GPUTextureFormat,\n    depthStencilFormat: GPUTextureFormat = DefaultXRGPUProjectionLayerDepthStencilFormat\n): XRGPUProjectionLayerInit {\n    return {\n        colorFormat,\n        depthStencilFormat,\n        // GPUTextureUsage.RENDER_ATTACHMENT (0x10) — the spec default, stated explicitly here.\n        textureUsage: 0x10,\n        scaleFactor: 1.0,\n    };\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type WebXRLayerWrapper, type WebXRSupportedLayerType } from \"../webXRLayerWrapper\";\r\nimport { type WebXRLayerRenderTargetTextureProvider } from \"../webXRRenderTargetTextureProvider\";\r\nimport { WebXRWebGLLayerWrapper } from \"../webXRWebGLLayer\";\r\nimport { WebXRProjectionLayerWrapper, DefaultXRProjectionLayerInit } from \"./Layers/WebXRProjectionLayer\";\r\nimport {\r\n    WebXRCompositionLayerRenderTargetTextureProvider,\r\n    WebXRCompositionLayerWrapper,\r\n    WebXRCubeLayerWrapper,\r\n    WebXRMediaLayerWrapper,\r\n    WebXRSpatialLayerWrapper,\r\n    type WebXRSpatialLayer,\r\n    type WebXRSpatialLayerType,\r\n} from \"./Layers/WebXRCompositionLayer\";\r\nimport { WebXRWebGPUProjectionLayerWrapper, CreateDefaultXRGPUProjectionLayerInit } from \"./Layers/WebXRWebGPUProjectionLayer\";\r\nimport { WebXRWebGPUCompositionLayerRenderTargetTextureProvider } from \"./Layers/WebXRWebGPUCompositionLayer\";\r\nimport { IsWebGPUXRSupported, WebXRGraphicsBindingType } from \"../webXRGraphicsBinding\";\r\nimport { type ThinTexture } from \"../../Materials/Textures/thinTexture\";\r\nimport { type RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { type DynamicTexture } from \"../../Materials/Textures/dynamicTexture.pure\";\r\nimport { Color4 } from \"../../Maths/math.color.pure\";\r\nimport { type LensFlareSystem } from \"../../LensFlares/lensFlareSystem\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observer } from \"../../Misc/observable.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { type WebXRFallbackLayerWrapper, type IWebXRFallbackLayerDimensions } from \"./Layers/WebXRFallbackLayer\";\r\n\r\nexport { WebXRCompositionLayerWrapper, WebXRCubeLayerWrapper, WebXRMediaLayerWrapper, WebXRSpatialLayerWrapper } from \"./Layers/WebXRCompositionLayer\";\r\nexport type { WebXRSpatialLayer, WebXRSpatialLayerType } from \"./Layers/WebXRCompositionLayer\";\r\nexport type { IWebXRFallbackLayerDimensions, WebXRFallbackLayerWrapper } from \"./Layers/WebXRFallbackLayer\";\r\n\r\nconst DefaultXRWebGLLayerInit: XRWebGLLayerInit = {};\r\nconst WebGPUQuadLayerCreateWarning =\r\n    \"WebGPU XR quad layers are unavailable because XRGPUBinding.createQuadLayer is not supported; the requested quad layer was skipped and projection rendering remains active.\";\r\nconst WebGPUQuadLayerSubImageWarning =\r\n    \"WebGPU XR quad layers are unavailable because XRGPUBinding.getSubImage is not supported; the requested quad layer was skipped and projection rendering remains active.\";\r\n\r\ntype WebXRGraphicsLayerInit = XRLayerInit & { textureType?: XRTextureType };\r\ntype WebXRGPUGraphicsLayerInit = XRGPULayerInit;\r\n\r\n/**\r\n * Configuration options of the layers feature\r\n */\r\nexport interface IWebXRLayersOptions {\r\n    /**\r\n     * Whether to try initializing the base projection layer as a multiview render target, if multiview is supported.\r\n     * Defaults to false.\r\n     */\r\n    preferMultiviewOnInit?: boolean;\r\n\r\n    /**\r\n     * Optional configuration for the base projection layer.\r\n     */\r\n    projectionLayerInit?: Partial<XRProjectionLayerInit>;\r\n}\r\n\r\n/**\r\n * Common options for creating a graphics-backed WebXR composition layer.\r\n * @typeParam TWebGLInit the WebGL layer initialization dictionary\r\n * @typeParam TWebGPUInit the WebGPU layer initialization dictionary\r\n */\r\nexport interface IWebXRCompositionLayerCreationOptions<TWebGLInit, TWebGPUInit> {\r\n    /**\r\n     * Initialization values shared with the WebGL Layers API.\r\n     * Babylon supplies the current reference space and projection-layer pixel dimensions when omitted.\r\n     */\r\n    layerInit?: Partial<TWebGLInit>;\r\n    /**\r\n     * WebGPU-specific initialization overrides.\r\n     * Shared spatial and layout values are copied from `layerInit` before these overrides are applied.\r\n     */\r\n    gpuLayerInit?: Partial<TWebGPUInit>;\r\n    /**\r\n     * A Babylon node whose world position and rotation will be synchronized with the layer.\r\n     * Babylon creates and owns a node when this is omitted.\r\n     */\r\n    transformNode?: TransformNode;\r\n    /**\r\n     * Uses a Babylon mesh when the requested native layer factory is unavailable.\r\n     * Import `@babylonjs/core/XR/features/WebXRLayersFallback` to enable this optional fallback.\r\n     * Fallback is disabled by default.\r\n     */\r\n    fallbackMode?: \"none\" | \"mesh\";\r\n    /**\r\n     * A texture to display on the fallback mesh.\r\n     * Required when `fallbackMode` is `\"mesh\"`.\r\n     */\r\n    fallbackTexture?: BaseTexture;\r\n}\r\n\r\n/**\r\n * Common options for creating an XRMediaBinding layer.\r\n * @typeParam InitT the media layer initialization dictionary\r\n */\r\nexport interface IWebXRMediaLayerCreationOptions<InitT> {\r\n    /**\r\n     * Initialization values for the media layer.\r\n     * Babylon supplies the current reference space when omitted.\r\n     */\r\n    layerInit?: Partial<InitT>;\r\n    /**\r\n     * A Babylon node whose world position and rotation will be synchronized with the layer.\r\n     * Babylon creates and owns a node when this is omitted.\r\n     */\r\n    transformNode?: TransformNode;\r\n    /**\r\n     * Uses a Babylon mesh and VideoTexture when XRMediaBinding is unavailable.\r\n     * Import `@babylonjs/core/XR/features/WebXRLayersFallback` to enable this optional fallback.\r\n     * Fallback is disabled by default.\r\n     */\r\n    fallbackMode?: \"none\" | \"mesh\";\r\n}\r\n\r\n/**\r\n * Selects whether a layer is created from a graphics binding or directly from a media element.\r\n */\r\nexport type WebXRLayerSource = \"graphics\" | \"media\";\r\n\r\n/**\r\n * The result of creating a spatial WebXR layer.\r\n * Native wrappers expose an XR composition layer, while fallback wrappers expose a Babylon mesh.\r\n * @typeParam LayerT the native layer type\r\n */\r\nexport type WebXRLayerCreationResult<LayerT extends WebXRSpatialLayer, LayerTypeT extends WebXRSpatialLayerType = WebXRSpatialLayerType> =\r\n    WebXRSpatialLayerWrapper<LayerT, LayerTypeT> | WebXRFallbackLayerWrapper;\r\n\r\n/**\r\n * Data supplied to an optional WebXR mesh-fallback implementation.\r\n * @internal\r\n */\r\nexport interface IWebXRFallbackLayerCreationContext {\r\n    scene: WebXRSessionManager[\"scene\"];\r\n    isWebGPU: boolean;\r\n    layerType: WebXRSpatialLayerType;\r\n    transformNode: TransformNode;\r\n    ownsTransformNode: boolean;\r\n    dimensions: IWebXRFallbackLayerDimensions;\r\n    worldScalingFactor: number;\r\n    texture?: BaseTexture;\r\n    video?: HTMLVideoElement;\r\n}\r\n\r\nlet _FallbackLayerFactory: Nullable<(context: IWebXRFallbackLayerCreationContext) => Nullable<WebXRFallbackLayerWrapper>> = null;\r\n\r\n/**\r\n * Registers the optional mesh-fallback implementation without making its rendering dependencies part of projection-only bundles.\r\n * @param factory creates a fallback wrapper\r\n * @internal\r\n */\r\nexport function _RegisterWebXRFallbackLayerFactory(factory: (context: IWebXRFallbackLayerCreationContext) => Nullable<WebXRFallbackLayerWrapper>): void {\r\n    _FallbackLayerFactory = factory;\r\n}\r\n\r\n/**\r\n * Exposes the WebXR Layers API.\r\n */\r\nexport class WebXRLayers extends WebXRAbstractFeature {\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.LAYERS;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n    /**\r\n     * Already-created layers\r\n     */\r\n    private _existingLayers: WebXRLayerWrapper<WebXRSupportedLayerType>[] = [];\r\n    private _fallbackLayers: WebXRFallbackLayerWrapper[] = [];\r\n\r\n    private _glContext: WebGLRenderingContext | WebGL2RenderingContext;\r\n    private _xrWebGLBinding: XRWebGLBinding;\r\n    private _isWebGPU = false;\r\n    private _xrGPUBinding?: XRGPUBinding;\r\n    private _xrMediaBinding?: XRMediaBinding;\r\n    private _isMultiviewEnabled = false;\r\n    private _projectionLayerInitialized = false;\r\n\r\n    private _compositionLayerTextureMapping: WeakMap<XRCompositionLayer, ThinTexture> = new WeakMap();\r\n    private _layerToRTTProviderMapping: WeakMap<XRCompositionLayer, WebXRLayerRenderTargetTextureProvider<WebXRSupportedLayerType>> = new WeakMap();\r\n    private _layerCleanupFunctions = new WeakMap<WebXRLayerWrapper<WebXRSupportedLayerType>, () => void>();\r\n\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        private readonly _options: IWebXRLayersOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"layers\";\r\n    }\r\n\r\n    /**\r\n     * Whether the active XR session exposes its compositor layer limit.\r\n     */\r\n    public get isMaxRenderLayersSupported(): boolean {\r\n        return this.maxRenderLayers !== null;\r\n    }\r\n\r\n    /**\r\n     * Gets the maximum number of native layers accepted in the active session's render-state `layers` array.\r\n     * The projection layer counts toward this limit. Fallback mesh layers do not.\r\n     * @returns The native layer limit, or `null` when the runtime does not expose it.\r\n     * @see https://playground.babylonjs.com/#TODARD#0\r\n     */\r\n    public get maxRenderLayers(): Nullable<number> {\r\n        const maxRenderLayers = this._xrSessionManager.session?.maxRenderLayers;\r\n        return typeof maxRenderLayers === \"number\" ? maxRenderLayers : null;\r\n    }\r\n\r\n    /**\r\n     * Attach this feature.\r\n     * Will usually be called by the features manager.\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n\r\n        const engine = this._xrSessionManager.scene.getEngine();\r\n        this._existingLayers.length = 0;\r\n        this._isWebGPU = engine.isWebGPU;\r\n\r\n        if (this._isWebGPU) {\r\n            const binding = this._xrSessionManager._getGraphicsBinding();\r\n            if (binding.bindingType !== WebXRGraphicsBindingType.WebGPU) {\r\n                throw new Error(\"Expected a WebGPU graphics binding for a WebGPU engine.\");\r\n            }\r\n            this._xrGPUBinding = binding.binding;\r\n            // Multiview is not yet supported on the WebGPU XR path; force single-view (two sub-images).\r\n            this._isMultiviewEnabled = false;\r\n            this._createWebGPUProjectionLayer();\r\n        } else {\r\n            const binding = this._xrSessionManager._getGraphicsBinding();\r\n            if (binding.bindingType !== WebXRGraphicsBindingType.WebGL) {\r\n                throw new Error(\"Expected a WebGL graphics binding for a WebGL engine.\");\r\n            }\r\n            this._glContext = binding.context;\r\n            this._xrWebGLBinding = binding.binding;\r\n\r\n            const projectionLayerInit = { ...DefaultXRProjectionLayerInit, ...this._options.projectionLayerInit };\r\n            this._isMultiviewEnabled = this._options.preferMultiviewOnInit && engine.getCaps().multiview;\r\n            this.createProjectionLayer(projectionLayerInit /*, projectionLayerMultiview*/);\r\n        }\r\n        this._projectionLayerInitialized = true;\r\n        this._addNewAttachObserver(this._xrSessionManager.onXRReferenceSpaceChanged, (referenceSpace) => {\r\n            for (const layer of this._existingLayers) {\r\n                if (layer instanceof WebXRSpatialLayerWrapper && layer.usesSessionReferenceSpace) {\r\n                    layer.layer.space = referenceSpace;\r\n                }\r\n            }\r\n        });\r\n\r\n        return true;\r\n    }\r\n\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n        for (const layer of this._existingLayers) {\r\n            this._layerCleanupFunctions.get(layer)?.();\r\n            layer.dispose();\r\n        }\r\n        this._existingLayers.length = 0;\r\n        for (const layer of this._fallbackLayers) {\r\n            layer.dispose();\r\n        }\r\n        this._fallbackLayers.length = 0;\r\n        this._xrMediaBinding = undefined;\r\n        this._projectionLayerInitialized = false;\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Creates a new XRWebGLLayer.\r\n     * @param params an object providing configuration options for the new XRWebGLLayer\r\n     * @returns the XRWebGLLayer\r\n     */\r\n    public createXRWebGLLayer(params = DefaultXRWebGLLayerInit): WebXRWebGLLayerWrapper {\r\n        const layer = new XRWebGLLayer(this._xrSessionManager.session, this._glContext, params);\r\n        return new WebXRWebGLLayerWrapper(layer);\r\n    }\r\n\r\n    private _validateLayerInit(params: XRProjectionLayerInit | WebXRGraphicsLayerInit, multiview = this._isMultiviewEnabled, allowTextureArrayWithoutMultiview = false): void {\r\n        // check if we are in session\r\n        if (!this._xrSessionManager.inXRSession) {\r\n            throw new Error(\"Cannot create a layer outside of a WebXR session. Make sure the session has started before creating layers.\");\r\n        }\r\n        if (multiview && params.textureType !== \"texture-array\") {\r\n            throw new Error(\"Projection layers can only be made multiview if they use texture arrays. Set the textureType parameter to 'texture-array'.\");\r\n        }\r\n\r\n        // TODO (rgerd): Support RTT's that are bound to sub-images in the texture array.\r\n        if (!multiview && params.textureType === \"texture-array\" && !allowTextureArrayWithoutMultiview) {\r\n            throw new Error(\"We currently only support multiview rendering when the textureType parameter is set to 'texture-array'.\");\r\n        }\r\n    }\r\n\r\n    private _extendXRLayerInit<T extends XRProjectionLayerInit | WebXRGraphicsLayerInit>(params: T, multiview = this._isMultiviewEnabled): T {\r\n        if (multiview) {\r\n            params.textureType = \"texture-array\";\r\n        }\r\n        return params;\r\n    }\r\n\r\n    private _getProjectionLayerDimensions(): { width: number; height: number } {\r\n        const projectionLayer = this._existingLayers.find((layer) => layer.layerType === \"XRProjectionLayer\");\r\n        if (!projectionLayer) {\r\n            throw new Error(\"A projection layer must be created before adding WebXR composition layers.\");\r\n        }\r\n        return {\r\n            width: projectionLayer.getWidth(),\r\n            height: projectionLayer.getHeight(),\r\n        };\r\n    }\r\n\r\n    private _createTransformNode(\r\n        layerType: WebXRSpatialLayerType,\r\n        transformNode: TransformNode | undefined,\r\n        transform?: XRRigidTransform,\r\n        orientation?: DOMPointReadOnly\r\n    ): { node: TransformNode; ownsNode: boolean } {\r\n        if (transformNode) {\r\n            return { node: transformNode, ownsNode: false };\r\n        }\r\n\r\n        const node = new TransformNode(`WebXR ${layerType}`, this._xrSessionManager.scene);\r\n        node.rotationQuaternion = new Quaternion();\r\n        const sourcePosition = transform?.position;\r\n        const sourceOrientation = transform?.orientation ?? orientation;\r\n        if (sourcePosition) {\r\n            const worldScalingFactor = this._xrSessionManager.worldScalingFactor;\r\n            node.position.set(sourcePosition.x * worldScalingFactor, sourcePosition.y * worldScalingFactor, sourcePosition.z * worldScalingFactor);\r\n        }\r\n        if (sourceOrientation) {\r\n            node.rotationQuaternion.set(sourceOrientation.x, sourceOrientation.y, sourceOrientation.z, sourceOrientation.w);\r\n        }\r\n        if (!this._xrSessionManager.scene.useRightHandedSystem) {\r\n            node.position.z *= -1;\r\n            node.rotationQuaternion.z *= -1;\r\n            node.rotationQuaternion.w *= -1;\r\n        }\r\n        return { node, ownsNode: true };\r\n    }\r\n\r\n    private _createFallbackLayer(\r\n        layerType: WebXRSpatialLayerType,\r\n        transformNode: TransformNode | undefined,\r\n        transform: XRRigidTransform | undefined,\r\n        orientation: DOMPointReadOnly | undefined,\r\n        dimensions: IWebXRFallbackLayerDimensions,\r\n        texture?: BaseTexture,\r\n        video?: HTMLVideoElement\r\n    ): Nullable<WebXRFallbackLayerWrapper> {\r\n        if (!_FallbackLayerFactory) {\r\n            Logger.Warn(\"WebXR mesh fallbacks require importing `@babylonjs/core/XR/features/WebXRLayersFallback`.\");\r\n            return null;\r\n        }\r\n\r\n        const transformInfo = this._createTransformNode(layerType, transformNode, transform, orientation);\r\n        const wrapper = _FallbackLayerFactory({\r\n            scene: this._xrSessionManager.scene,\r\n            isWebGPU: this._isWebGPU,\r\n            layerType,\r\n            transformNode: transformInfo.node,\r\n            ownsTransformNode: transformInfo.ownsNode,\r\n            dimensions,\r\n            worldScalingFactor: this._xrSessionManager.worldScalingFactor,\r\n            texture,\r\n            video,\r\n        });\r\n        if (wrapper) {\r\n            this._fallbackLayers.push(wrapper);\r\n        } else if (transformInfo.ownsNode) {\r\n            transformInfo.node.dispose();\r\n        }\r\n        return wrapper;\r\n    }\r\n\r\n    private _createGraphicsLayer<\r\n        LayerT extends WebXRSpatialLayer,\r\n        LayerTypeT extends WebXRSpatialLayerType,\r\n        TWebGLInit extends WebXRGraphicsLayerInit,\r\n        TWebGPUInit extends WebXRGPUGraphicsLayerInit,\r\n    >(\r\n        layerType: LayerTypeT,\r\n        factoryName: string,\r\n        factorySupported: boolean,\r\n        options: IWebXRCompositionLayerCreationOptions<TWebGLInit, TWebGPUInit>,\r\n        createWebGLLayer: (binding: XRWebGLBinding, init: TWebGLInit) => LayerT,\r\n        createWebGPULayer: (binding: XRGPUBinding, init: TWebGPUInit) => LayerT,\r\n        copyWebGPUSpecificInit: (webGLInit: TWebGLInit, webGPUInit: TWebGPUInit) => void\r\n    ): Nullable<WebXRSpatialLayerWrapper<LayerT, LayerTypeT>> {\r\n        if (!this._xrSessionManager.inXRSession) {\r\n            throw new Error(\"Cannot create a layer outside of a WebXR session. Make sure the session has started before creating layers.\");\r\n        }\r\n        if (!factorySupported) {\r\n            if (options.fallbackMode !== \"mesh\") {\r\n                Logger.Warn(`${layerType} is unavailable because ${factoryName} is not supported; the requested layer was skipped and projection rendering remains active.`);\r\n            }\r\n            return null;\r\n        }\r\n        if (this._isWebGPU && typeof this._xrGPUBinding?.getSubImage !== \"function\") {\r\n            if (options.fallbackMode !== \"mesh\") {\r\n                Logger.Warn(\r\n                    `${layerType} is unavailable because XRGPUBinding.getSubImage is not supported; the requested layer was skipped and projection rendering remains active.`\r\n                );\r\n            }\r\n            return null;\r\n        }\r\n\r\n        this._validateLayerCount(this._existingLayers.length + 1);\r\n        const dimensions = this._getProjectionLayerDimensions();\r\n        const defaultViewPixelWidth = layerType === \"XRCubeLayer\" ? Math.min(dimensions.width, dimensions.height) : dimensions.width;\r\n        const defaultViewPixelHeight = layerType === \"XRCubeLayer\" ? defaultViewPixelWidth : dimensions.height;\r\n        const populatedParams = {\r\n            space: this._xrSessionManager.referenceSpace,\r\n            viewPixelWidth: defaultViewPixelWidth,\r\n            viewPixelHeight: defaultViewPixelHeight,\r\n            clearOnAccess: true,\r\n            textureType: \"texture\",\r\n            layout: \"mono\",\r\n            ...options.layerInit,\r\n        } as TWebGLInit;\r\n        if (layerType === \"XRCubeLayer\" && populatedParams.viewPixelWidth !== populatedParams.viewPixelHeight) {\r\n            throw new Error(\"WebXR cube layer faces must have equal pixel width and height.\");\r\n        }\r\n        this._validateLayerInit(populatedParams, false, layerType === \"XRCubeLayer\");\r\n\r\n        let layer: LayerT;\r\n        let effectiveParams: TWebGLInit | TWebGPUInit = populatedParams;\r\n        let depthStencilFormat: GPUTextureFormat | undefined;\r\n        if (this._isWebGPU) {\r\n            const binding = this._xrGPUBinding!;\r\n            const gpuParams = {\r\n                colorFormat: binding.getPreferredColorFormat(),\r\n                textureUsage: 0x10,\r\n                space: populatedParams.space,\r\n                viewPixelWidth: populatedParams.viewPixelWidth,\r\n                viewPixelHeight: populatedParams.viewPixelHeight,\r\n                layout: populatedParams.layout,\r\n                mipLevels: populatedParams.mipLevels,\r\n                isStatic: populatedParams.isStatic,\r\n            } as TWebGPUInit;\r\n            copyWebGPUSpecificInit(populatedParams, gpuParams);\r\n            Object.assign(gpuParams, options.gpuLayerInit);\r\n            if (layerType === \"XRCubeLayer\" && gpuParams.viewPixelWidth !== gpuParams.viewPixelHeight) {\r\n                throw new Error(\"WebXR cube layer faces must have equal pixel width and height.\");\r\n            }\r\n            effectiveParams = gpuParams;\r\n            depthStencilFormat = gpuParams.depthStencilFormat;\r\n            layer = createWebGPULayer(binding, gpuParams);\r\n        } else {\r\n            layer = createWebGLLayer(this._xrWebGLBinding, populatedParams);\r\n        }\r\n\r\n        const transform = \"transform\" in effectiveParams ? (effectiveParams.transform as XRRigidTransform | undefined) : undefined;\r\n        const orientation = \"orientation\" in effectiveParams ? (effectiveParams.orientation as DOMPointReadOnly | undefined) : undefined;\r\n        const usesSessionReferenceSpace = options.layerInit?.space === undefined && (!this._isWebGPU || options.gpuLayerInit?.space === undefined);\r\n        const transformInfo = this._createTransformNode(layerType, options.transformNode, transform, orientation);\r\n        let wrapper: WebXRSpatialLayerWrapper<LayerT, LayerTypeT>;\r\n        if (layerType === \"XRCubeLayer\") {\r\n            wrapper = new WebXRCubeLayerWrapper(\r\n                () => effectiveParams.viewPixelWidth,\r\n                () => effectiveParams.viewPixelHeight,\r\n                layer as XRCubeLayer,\r\n                !!effectiveParams.isStatic,\r\n                usesSessionReferenceSpace,\r\n                this._isWebGPU ? this._xrGPUBinding! : this._xrWebGLBinding,\r\n                transformInfo.node,\r\n                transformInfo.ownsNode\r\n            ) as unknown as WebXRSpatialLayerWrapper<LayerT, LayerTypeT>;\r\n        } else if (this._isWebGPU) {\r\n            const binding = this._xrGPUBinding!;\r\n            wrapper = new WebXRSpatialLayerWrapper(\r\n                () => effectiveParams.viewPixelWidth,\r\n                () => effectiveParams.viewPixelHeight,\r\n                layer,\r\n                layerType,\r\n                false,\r\n                !!effectiveParams.isStatic,\r\n                usesSessionReferenceSpace,\r\n                (sessionManager) => new WebXRWebGPUCompositionLayerRenderTargetTextureProvider(sessionManager, binding, wrapper, depthStencilFormat),\r\n                transformInfo.node,\r\n                transformInfo.ownsNode\r\n            );\r\n        } else {\r\n            wrapper = new WebXRSpatialLayerWrapper(\r\n                () => effectiveParams.viewPixelWidth,\r\n                () => effectiveParams.viewPixelHeight,\r\n                layer,\r\n                layerType,\r\n                false,\r\n                !!effectiveParams.isStatic,\r\n                usesSessionReferenceSpace,\r\n                (sessionManager) => new WebXRCompositionLayerRenderTargetTextureProvider(sessionManager, this._xrWebGLBinding, wrapper),\r\n                transformInfo.node,\r\n                transformInfo.ownsNode\r\n            );\r\n        }\r\n\r\n        if (wrapper.usesRenderTargetProvider) {\r\n            const rttProvider = wrapper.createRenderTargetTextureProvider(this._xrSessionManager);\r\n            this._layerToRTTProviderMapping.set(layer, rttProvider);\r\n        }\r\n        this.addXRSessionLayer(wrapper);\r\n        return wrapper;\r\n    }\r\n\r\n    private _createMediaLayer<\r\n        LayerT extends XRQuadLayer | XRCylinderLayer | XREquirectLayer,\r\n        LayerTypeT extends Exclude<WebXRSpatialLayerType, \"XRCubeLayer\">,\r\n        InitT extends XRMediaLayerInit & { transform?: XRRigidTransform },\r\n    >(\r\n        layerType: LayerTypeT,\r\n        factoryName: string,\r\n        video: HTMLVideoElement,\r\n        options: IWebXRMediaLayerCreationOptions<InitT>,\r\n        createLayer: (binding: XRMediaBinding, video: HTMLVideoElement, init: InitT) => LayerT\r\n    ): Nullable<WebXRMediaLayerWrapper<LayerT, LayerTypeT>> {\r\n        if (!this._xrSessionManager.inXRSession) {\r\n            throw new Error(\"Cannot create a layer outside of a WebXR session. Make sure the session has started before creating layers.\");\r\n        }\r\n        if (typeof XRMediaBinding === \"undefined\") {\r\n            if (options.fallbackMode !== \"mesh\") {\r\n                Logger.Warn(`${layerType} media layers are unavailable because XRMediaBinding is not supported; the requested layer was skipped.`);\r\n            }\r\n            return null;\r\n        }\r\n\r\n        this._xrMediaBinding ??= new XRMediaBinding(this._xrSessionManager.session);\r\n        const mediaBinding = this._xrMediaBinding;\r\n        const factory = mediaBinding[factoryName as \"createQuadLayer\" | \"createCylinderLayer\" | \"createEquirectLayer\"];\r\n        if (typeof factory !== \"function\") {\r\n            if (options.fallbackMode !== \"mesh\") {\r\n                Logger.Warn(`${layerType} media layers are unavailable because XRMediaBinding.${factoryName} is not supported; the requested layer was skipped.`);\r\n            }\r\n            return null;\r\n        }\r\n\r\n        this._validateLayerCount(this._existingLayers.length + 1);\r\n        const populatedParams = {\r\n            space: this._xrSessionManager.referenceSpace,\r\n            layout: \"mono\",\r\n            ...options.layerInit,\r\n        } as InitT;\r\n        const layer = createLayer(mediaBinding, video, populatedParams);\r\n        const transform = \"transform\" in populatedParams ? populatedParams.transform : undefined;\r\n        const transformInfo = this._createTransformNode(layerType, options.transformNode, transform);\r\n        const wrapper = new WebXRMediaLayerWrapper(\r\n            () => video.videoWidth,\r\n            () => video.videoHeight,\r\n            layer,\r\n            layerType,\r\n            transformInfo.node,\r\n            transformInfo.ownsNode,\r\n            options.layerInit?.space === undefined\r\n        );\r\n        this.addXRSessionLayer(wrapper);\r\n        return wrapper;\r\n    }\r\n\r\n    /**\r\n     * Creates a new XRProjectionLayer.\r\n     * @param params an object providing configuration options for the new XRProjectionLayer.\r\n     * @param multiview whether the projection layer should render with multiview. Will be tru automatically if the extension initialized with multiview.\r\n     * @returns the projection layer\r\n     */\r\n    public createProjectionLayer(params = DefaultXRProjectionLayerInit, multiview = this._isMultiviewEnabled): WebXRProjectionLayerWrapper {\r\n        const extendedParams = this._extendXRLayerInit(params, multiview);\r\n        this._validateLayerInit(extendedParams, multiview);\r\n        this._validateLayerCount(this._existingLayers.length + 1);\r\n\r\n        const projLayer = this._xrWebGLBinding.createProjectionLayer(extendedParams);\r\n        const layer = new WebXRProjectionLayerWrapper(projLayer, multiview, this._xrWebGLBinding);\r\n        this.addXRSessionLayer(layer);\r\n        return layer;\r\n    }\r\n\r\n    /**\r\n     * Creates the base projection layer for the WebGPU (XRGPUBinding) backend.\r\n     * Single-view only for now (multiview is deferred); the color format is the binding's preferred format.\r\n     * @returns the WebGPU projection layer wrapper\r\n     */\r\n    private _createWebGPUProjectionLayer(): WebXRWebGPUProjectionLayerWrapper {\r\n        if (!this._xrSessionManager.inXRSession) {\r\n            throw new Error(\"Cannot create a layer outside of a WebXR session. Make sure the session has started before creating layers.\");\r\n        }\r\n        this._validateLayerCount(this._existingLayers.length + 1);\r\n        const binding = this._xrGPUBinding!;\r\n        const init = CreateDefaultXRGPUProjectionLayerInit(binding.getPreferredColorFormat());\r\n        const projLayer = binding.createProjectionLayer(init);\r\n        const layer = new WebXRWebGPUProjectionLayerWrapper(projLayer, false, binding, init.depthStencilFormat);\r\n        this.addXRSessionLayer(layer);\r\n        return layer;\r\n    }\r\n\r\n    /**\r\n     * Creates a graphics-backed quad layer and adds it to the current XR session.\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created layer wrapper, or `null` when the active graphics binding does not support quad layers\r\n     */\r\n    public createQuadLayer(\r\n        options: IWebXRCompositionLayerCreationOptions<XRQuadLayerInit, XRGPUQuadLayerInit> = {}\r\n    ): Nullable<WebXRLayerCreationResult<XRQuadLayer, \"XRQuadLayer\">> {\r\n        const factorySupported = this._isWebGPU ? typeof this._xrGPUBinding?.createQuadLayer === \"function\" : typeof this._xrWebGLBinding.createQuadLayer === \"function\";\r\n        const factoryName = this._isWebGPU ? \"XRGPUBinding.createQuadLayer\" : \"XRWebGLBinding.createQuadLayer\";\r\n        const nativeLayer = this._createGraphicsLayer(\r\n            \"XRQuadLayer\",\r\n            factoryName,\r\n            factorySupported,\r\n            options,\r\n            (binding, init) => binding.createQuadLayer(init),\r\n            (binding, init) => binding.createQuadLayer(init),\r\n            (webGLInit, webGPUInit) => {\r\n                webGPUInit.transform = webGLInit.transform;\r\n                webGPUInit.width = webGLInit.width;\r\n                webGPUInit.height = webGLInit.height;\r\n            }\r\n        );\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\r\n            \"XRQuadLayer\",\r\n            options.transformNode,\r\n            options.layerInit?.transform,\r\n            undefined,\r\n            { width: options.layerInit?.width, height: options.layerInit?.height },\r\n            options.fallbackTexture\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a graphics-backed cylinder layer and adds it to the current XR session.\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created layer wrapper, or `null` when the active graphics binding does not support cylinder layers\r\n     */\r\n    public createCylinderLayer(\r\n        options: IWebXRCompositionLayerCreationOptions<XRCylinderLayerInit, XRGPUCylinderLayerInit> = {}\r\n    ): Nullable<WebXRLayerCreationResult<XRCylinderLayer, \"XRCylinderLayer\">> {\r\n        const factorySupported = this._isWebGPU ? typeof this._xrGPUBinding?.createCylinderLayer === \"function\" : typeof this._xrWebGLBinding.createCylinderLayer === \"function\";\r\n        const factoryName = this._isWebGPU ? \"XRGPUBinding.createCylinderLayer\" : \"XRWebGLBinding.createCylinderLayer\";\r\n        const nativeLayer = this._createGraphicsLayer(\r\n            \"XRCylinderLayer\",\r\n            factoryName,\r\n            factorySupported,\r\n            options,\r\n            (binding, init) => binding.createCylinderLayer(init),\r\n            (binding, init) => binding.createCylinderLayer(init),\r\n            (webGLInit, webGPUInit) => {\r\n                webGPUInit.transform = webGLInit.transform;\r\n                webGPUInit.radius = webGLInit.radius;\r\n                webGPUInit.centralAngle = webGLInit.centralAngle;\r\n                webGPUInit.aspectRatio = webGLInit.aspectRatio;\r\n            }\r\n        );\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\r\n            \"XRCylinderLayer\",\r\n            options.transformNode,\r\n            options.layerInit?.transform,\r\n            undefined,\r\n            {\r\n                radius: options.layerInit?.radius,\r\n                centralAngle: options.layerInit?.centralAngle,\r\n                aspectRatio: options.layerInit?.aspectRatio,\r\n            },\r\n            options.fallbackTexture\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a graphics-backed equirectangular layer and adds it to the current XR session.\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created layer wrapper, or `null` when the active graphics binding does not support equirectangular layers\r\n     */\r\n    public createEquirectLayer(\r\n        options: IWebXRCompositionLayerCreationOptions<XREquirectLayerInit, XRGPUEquirectLayerInit> = {}\r\n    ): Nullable<WebXRLayerCreationResult<XREquirectLayer, \"XREquirectLayer\">> {\r\n        const factorySupported = this._isWebGPU ? typeof this._xrGPUBinding?.createEquirectLayer === \"function\" : typeof this._xrWebGLBinding.createEquirectLayer === \"function\";\r\n        const factoryName = this._isWebGPU ? \"XRGPUBinding.createEquirectLayer\" : \"XRWebGLBinding.createEquirectLayer\";\r\n        const nativeLayer = this._createGraphicsLayer(\r\n            \"XREquirectLayer\",\r\n            factoryName,\r\n            factorySupported,\r\n            options,\r\n            (binding, init) => binding.createEquirectLayer(init),\r\n            (binding, init) => binding.createEquirectLayer(init),\r\n            (webGLInit, webGPUInit) => {\r\n                webGPUInit.transform = webGLInit.transform;\r\n                webGPUInit.radius = webGLInit.radius;\r\n                webGPUInit.centralHorizontalAngle = webGLInit.centralHorizontalAngle;\r\n                webGPUInit.upperVerticalAngle = webGLInit.upperVerticalAngle;\r\n                webGPUInit.lowerVerticalAngle = webGLInit.lowerVerticalAngle;\r\n            }\r\n        );\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\r\n            \"XREquirectLayer\",\r\n            options.transformNode,\r\n            options.layerInit?.transform,\r\n            undefined,\r\n            {\r\n                radius: options.layerInit?.radius,\r\n                centralHorizontalAngle: options.layerInit?.centralHorizontalAngle,\r\n                upperVerticalAngle: options.layerInit?.upperVerticalAngle,\r\n                lowerVerticalAngle: options.layerInit?.lowerVerticalAngle,\r\n            },\r\n            options.fallbackTexture\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a graphics-backed cube layer and adds it to the current XR session.\r\n     * Cube layers synchronize only the rotation of their transform node because the WebXR API does not support cube-layer translation.\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created layer wrapper, or `null` when the active graphics binding does not support cube layers\r\n     */\r\n    public createCubeLayer(options: IWebXRCompositionLayerCreationOptions<XRCubeLayerInit, XRGPUCubeLayerInit> = {}): Nullable<WebXRCubeLayerWrapper | WebXRFallbackLayerWrapper> {\r\n        const factorySupported = this._isWebGPU ? typeof this._xrGPUBinding?.createCubeLayer === \"function\" : typeof this._xrWebGLBinding.createCubeLayer === \"function\";\r\n        const factoryName = this._isWebGPU ? \"XRGPUBinding.createCubeLayer\" : \"XRWebGLBinding.createCubeLayer\";\r\n        const nativeLayer = this._createGraphicsLayer(\r\n            \"XRCubeLayer\",\r\n            factoryName,\r\n            factorySupported,\r\n            options,\r\n            (binding, init) => binding.createCubeLayer(init),\r\n            (binding, init) => binding.createCubeLayer(init),\r\n            (webGLInit, webGPUInit) => {\r\n                webGPUInit.orientation = webGLInit.orientation;\r\n            }\r\n        ) as Nullable<WebXRCubeLayerWrapper>;\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\"XRCubeLayer\", options.transformNode, undefined, options.layerInit?.orientation, {}, options.fallbackTexture);\r\n    }\r\n\r\n    /**\r\n     * Creates a video-backed quad layer and adds it to the current XR session.\r\n     * @see https://playground.babylonjs.com/#D35HOL#0\r\n     * @param video the video element presented by the XR compositor\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created media layer wrapper, or `null` when XRMediaBinding is unavailable\r\n     */\r\n    public createMediaQuadLayer(\r\n        video: HTMLVideoElement,\r\n        options: IWebXRMediaLayerCreationOptions<XRMediaQuadLayerInit> = {}\r\n    ): Nullable<WebXRLayerCreationResult<XRQuadLayer, \"XRQuadLayer\">> {\r\n        const nativeLayer = this._createMediaLayer(\"XRQuadLayer\", \"createQuadLayer\", video, options, (binding, media, init) => binding.createQuadLayer(media, init));\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\r\n            \"XRQuadLayer\",\r\n            options.transformNode,\r\n            options.layerInit?.transform,\r\n            undefined,\r\n            { width: options.layerInit?.width, height: options.layerInit?.height },\r\n            undefined,\r\n            video\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a video-backed cylinder layer and adds it to the current XR session.\r\n     * @param video the video element presented by the XR compositor\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created media layer wrapper, or `null` when XRMediaBinding is unavailable\r\n     */\r\n    public createMediaCylinderLayer(\r\n        video: HTMLVideoElement,\r\n        options: IWebXRMediaLayerCreationOptions<XRMediaCylinderLayerInit> = {}\r\n    ): Nullable<WebXRLayerCreationResult<XRCylinderLayer, \"XRCylinderLayer\">> {\r\n        const nativeLayer = this._createMediaLayer(\"XRCylinderLayer\", \"createCylinderLayer\", video, options, (binding, media, init) => binding.createCylinderLayer(media, init));\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\r\n            \"XRCylinderLayer\",\r\n            options.transformNode,\r\n            options.layerInit?.transform,\r\n            undefined,\r\n            {\r\n                radius: options.layerInit?.radius,\r\n                centralAngle: options.layerInit?.centralAngle,\r\n                aspectRatio: options.layerInit?.aspectRatio,\r\n            },\r\n            undefined,\r\n            video\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Creates a video-backed equirectangular layer and adds it to the current XR session.\r\n     * @param video the video element presented by the XR compositor\r\n     * @param options initialization and transform-node options for the layer\r\n     * @returns the created media layer wrapper, or `null` when XRMediaBinding is unavailable\r\n     */\r\n    public createMediaEquirectLayer(\r\n        video: HTMLVideoElement,\r\n        options: IWebXRMediaLayerCreationOptions<XRMediaEquirectLayerInit> = {}\r\n    ): Nullable<WebXRLayerCreationResult<XREquirectLayer, \"XREquirectLayer\">> {\r\n        const nativeLayer = this._createMediaLayer(\"XREquirectLayer\", \"createEquirectLayer\", video, options, (binding, media, init) => binding.createEquirectLayer(media, init));\r\n        if (nativeLayer || options.fallbackMode !== \"mesh\") {\r\n            return nativeLayer;\r\n        }\r\n        return this._createFallbackLayer(\r\n            \"XREquirectLayer\",\r\n            options.transformNode,\r\n            options.layerInit?.transform,\r\n            undefined,\r\n            {\r\n                radius: options.layerInit?.radius,\r\n                centralHorizontalAngle: options.layerInit?.centralHorizontalAngle,\r\n                upperVerticalAngle: options.layerInit?.upperVerticalAngle,\r\n                lowerVerticalAngle: options.layerInit?.lowerVerticalAngle,\r\n            },\r\n            undefined,\r\n            video\r\n        );\r\n    }\r\n\r\n    private _createQuadLayer(\r\n        options: { params: Partial<XRQuadLayerInit> } = { params: {} },\r\n        babylonTexture?: ThinTexture\r\n    ): Nullable<WebXRSpatialLayerWrapper<XRQuadLayer, \"XRQuadLayer\">> {\r\n        if (this._isWebGPU) {\r\n            const binding = this._xrGPUBinding!;\r\n            if (typeof binding.createQuadLayer !== \"function\") {\r\n                Logger.Warn(WebGPUQuadLayerCreateWarning);\r\n                return null;\r\n            }\r\n            if (typeof binding.getSubImage !== \"function\") {\r\n                Logger.Warn(WebGPUQuadLayerSubImageWarning);\r\n                return null;\r\n            }\r\n        }\r\n\r\n        const wrapper = this.createQuadLayer({ layerInit: options.params });\r\n        if (!wrapper || wrapper.layer === null) {\r\n            return null;\r\n        }\r\n        const quadLayer = wrapper.layer;\r\n        quadLayer.width = this._isMultiviewEnabled ? 1 : 2;\r\n        quadLayer.height = 1;\r\n\r\n        if (babylonTexture) {\r\n            this._compositionLayerTextureMapping.set(quadLayer, babylonTexture);\r\n        }\r\n        return wrapper;\r\n    }\r\n\r\n    /**\r\n     * @experimental\r\n     * This will support full screen ADT when used with WebXR Layers. This API might change in the future.\r\n     * Note that no interaction will be available with the ADT when using this method\r\n     * @param texture the texture to display in the layer\r\n     * @param options optional parameters for the layer\r\n     * @returns a composition layer containing the texture, or null when WebGPU quad layers are unavailable\r\n     */\r\n    public addFullscreenAdvancedDynamicTexture(\r\n        texture: DynamicTexture,\r\n        options: { distanceFromHeadset: number } = { distanceFromHeadset: 1.5 }\r\n    ): Nullable<WebXRCompositionLayerWrapper> {\r\n        const wrapper = this._createQuadLayer(\r\n            {\r\n                params: {\r\n                    space: this._xrSessionManager.viewerReferenceSpace,\r\n                    textureType: \"texture\",\r\n                    layout: \"mono\",\r\n                },\r\n            },\r\n            texture\r\n        );\r\n        if (!wrapper) {\r\n            return null;\r\n        }\r\n\r\n        const distance = Math.max(0.1, options.distanceFromHeadset);\r\n        const z = this._xrSessionManager.scene.useRightHandedSystem ? -distance : distance;\r\n        wrapper.transformNode.position.set(0, 0, z * this._xrSessionManager.worldScalingFactor);\r\n\r\n        const rttProvider = this._layerToRTTProviderMapping.get(wrapper.layer);\r\n        if (\r\n            !rttProvider ||\r\n            (!(rttProvider instanceof WebXRCompositionLayerRenderTargetTextureProvider) && !(rttProvider instanceof WebXRWebGPUCompositionLayerRenderTargetTextureProvider))\r\n        ) {\r\n            throw new Error(\"Could not find the RTT provider for the layer\");\r\n        }\r\n        const babylonLayer = this._xrSessionManager.scene.layers.find((babylonLayer) => {\r\n            return babylonLayer.texture === texture;\r\n        });\r\n        if (!babylonLayer) {\r\n            throw new Error(\"Could not find the babylon layer for the texture\");\r\n        }\r\n        const renderTargetTextures = new Set<RenderTargetTexture>();\r\n        const beforeRenderObservers: Observer<Scene>[] = [];\r\n        const previousRenderOnlyInRenderTargetTextures = babylonLayer.renderOnlyInRenderTargetTextures;\r\n        let cleanedUp = false;\r\n        const renderTargetCreatedObserver = rttProvider.onRenderTargetTextureCreatedObservable.add((data) => {\r\n            if (data.eye && data.eye === \"right\") {\r\n                return;\r\n            }\r\n            data.texture.clearColor = new Color4(0, 0, 0, 0);\r\n            babylonLayer.renderTargetTextures.push(data.texture);\r\n            renderTargetTextures.add(data.texture);\r\n            babylonLayer.renderOnlyInRenderTargetTextures = true;\r\n            // for stereo (not for gui) it should be onBeforeCameraRenderObservable\r\n            beforeRenderObservers.push(\r\n                this._xrSessionManager.scene.onBeforeRenderObservable.add(() => {\r\n                    data.texture.render();\r\n                })\r\n            );\r\n        });\r\n        const cleanup = () => {\r\n            if (cleanedUp) {\r\n                return;\r\n            }\r\n            cleanedUp = true;\r\n            rttProvider.onRenderTargetTextureCreatedObservable.remove(renderTargetCreatedObserver);\r\n            for (const observer of beforeRenderObservers) {\r\n                this._xrSessionManager.scene.onBeforeRenderObservable.remove(observer);\r\n            }\r\n            for (const renderTargetTexture of renderTargetTextures) {\r\n                const index = babylonLayer.renderTargetTextures.indexOf(renderTargetTexture);\r\n                if (index !== -1) {\r\n                    babylonLayer.renderTargetTextures.splice(index, 1);\r\n                }\r\n            }\r\n            babylonLayer.renderOnlyInRenderTargetTextures = previousRenderOnlyInRenderTargetTextures;\r\n            this._layerCleanupFunctions.delete(wrapper);\r\n        };\r\n        this._layerCleanupFunctions.set(wrapper, cleanup);\r\n        this._xrSessionManager.onXRSessionEnded.addOnce(cleanup);\r\n        return wrapper;\r\n    }\r\n\r\n    /**\r\n     * @experimental\r\n     * This functions allows you to add a lens flare system to the XR scene.\r\n     * Note - this will remove the lens flare system from the scene and add it to the XR scene.\r\n     * This feature is experimental and might change in the future.\r\n     * @param flareSystem the flare system to add\r\n     * @returns a composition layer containing the flare system, or null when WebGPU quad layers are unavailable\r\n     */\r\n    protected _addLensFlareSystem(flareSystem: LensFlareSystem): Nullable<WebXRCompositionLayerWrapper> {\r\n        const wrapper = this._createQuadLayer({\r\n            params: {\r\n                space: this._xrSessionManager.viewerReferenceSpace,\r\n                textureType: \"texture\",\r\n                layout: \"mono\",\r\n            },\r\n        });\r\n        if (!wrapper) {\r\n            return null;\r\n        }\r\n\r\n        const layer = wrapper.layer;\r\n        layer.width = 2;\r\n        layer.height = 1;\r\n        const distance = 10;\r\n        const z = this._xrSessionManager.scene.useRightHandedSystem ? -distance : distance;\r\n        wrapper.transformNode.position.set(0, 0, z * this._xrSessionManager.worldScalingFactor);\r\n\r\n        // get the rtt wrapper\r\n        const rttProvider = this._layerToRTTProviderMapping.get(layer);\r\n        if (\r\n            !rttProvider ||\r\n            (!(rttProvider instanceof WebXRCompositionLayerRenderTargetTextureProvider) && !(rttProvider instanceof WebXRWebGPUCompositionLayerRenderTargetTextureProvider))\r\n        ) {\r\n            throw new Error(\"Could not find the RTT provider for the layer\");\r\n        }\r\n        // render the flare system to the rtt\r\n        rttProvider.onRenderTargetTextureCreatedObservable.add((data) => {\r\n            data.texture.clearColor = new Color4(0, 0, 0, 0);\r\n            data.texture.customRenderFunction = () => {\r\n                flareSystem.render();\r\n            };\r\n\r\n            // add to the scene's render targets\r\n            // this._xrSessionManager.scene.onBeforeCameraRenderObservable.add(() => {\r\n            //     data.texture.render();\r\n            // });\r\n        });\r\n        // remove the lens flare system from the scene\r\n        this._xrSessionManager.onXRSessionInit.add(() => {\r\n            this._xrSessionManager.scene.lensFlareSystems.splice(this._xrSessionManager.scene.lensFlareSystems.indexOf(flareSystem), 1);\r\n        });\r\n        // add it back when the session ends\r\n        this._xrSessionManager.onXRSessionEnded.add(() => {\r\n            this._xrSessionManager.scene.lensFlareSystems.push(flareSystem);\r\n        });\r\n\r\n        return wrapper;\r\n    }\r\n\r\n    /**\r\n     * Add a new layer to the already-existing list of layers\r\n     * @param wrappedLayer the new layer to add to the existing ones\r\n     */\r\n    public addXRSessionLayer(wrappedLayer: WebXRLayerWrapper<WebXRSupportedLayerType>) {\r\n        this._validateLayerCount(this._existingLayers.length + 1);\r\n        this._existingLayers.push(wrappedLayer);\r\n        this.setXRSessionLayers(this._existingLayers);\r\n    }\r\n\r\n    /**\r\n     * Removes a non-projection layer from the current XR session.\r\n     * @param wrappedLayer the layer wrapper to remove\r\n     * @param dispose whether to dispose the wrapper and destroy its native composition layer\r\n     * @returns whether the layer was present and removed\r\n     */\r\n    public removeXRSessionLayer(wrappedLayer: WebXRLayerWrapper<WebXRSupportedLayerType>, dispose = true): boolean {\r\n        const index = this._existingLayers.indexOf(wrappedLayer);\r\n        if (index === -1) {\r\n            return false;\r\n        }\r\n        if (wrappedLayer.layerType === \"XRProjectionLayer\") {\r\n            Logger.Warn(\"The active projection layer cannot be removed from WebXRLayers.\");\r\n            return false;\r\n        }\r\n\r\n        this._existingLayers.splice(index, 1);\r\n        this._layerCleanupFunctions.get(wrappedLayer)?.();\r\n        if (wrappedLayer instanceof WebXRCompositionLayerWrapper) {\r\n            this._layerToRTTProviderMapping.delete(wrappedLayer.layer);\r\n            this._compositionLayerTextureMapping.delete(wrappedLayer.layer);\r\n        }\r\n        this.setXRSessionLayers(this._existingLayers);\r\n        if (dispose) {\r\n            wrappedLayer.dispose();\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Removes either a native spatial layer or a fallback layer created by this feature.\r\n     * @param wrappedLayer the native or fallback layer wrapper to remove\r\n     * @param dispose whether to dispose resources owned by the wrapper\r\n     * @returns whether the wrapper was present and removed\r\n     */\r\n    public removeLayer(wrappedLayer: WebXRLayerCreationResult<WebXRSpatialLayer>, dispose = true): boolean {\r\n        if (wrappedLayer.layer === null) {\r\n            const index = this._fallbackLayers.indexOf(wrappedLayer);\r\n            if (index === -1) {\r\n                return false;\r\n            }\r\n            this._fallbackLayers.splice(index, 1);\r\n            if (dispose) {\r\n                wrappedLayer.dispose();\r\n            }\r\n            return true;\r\n        }\r\n        return this.removeXRSessionLayer(wrappedLayer, dispose);\r\n    }\r\n\r\n    /**\r\n     * Sets the layers to be used by the XR session.\r\n     * Note that you must call this function with any layers you wish to render to\r\n     * since it adds them to the XR session's render state\r\n     * (replacing any layers that were added in a previous call to setXRSessionLayers or updateRenderState).\r\n     * This method also sets up the session manager's render target texture provider\r\n     * as the first layer in the array, which feeds the WebXR camera(s) attached to the session.\r\n     * @param wrappedLayers An array of WebXRLayerWrapper, usually returned from the WebXRLayers createLayer functions.\r\n     */\r\n    public setXRSessionLayers(wrappedLayers: Array<WebXRLayerWrapper<WebXRSupportedLayerType>> = this._existingLayers): void {\r\n        this._validateLayerCount(wrappedLayers.length);\r\n        // this._existingLayers = wrappedLayers;\r\n        const renderStateInit: XRRenderStateInit = { ...this._xrSessionManager.session.renderState };\r\n        // Clear out the layer-related fields.\r\n        renderStateInit.baseLayer = undefined;\r\n        renderStateInit.layers = wrappedLayers.map((wrappedLayer) => wrappedLayer.layer);\r\n        this._xrSessionManager.updateRenderState(renderStateInit);\r\n        if (!this._projectionLayerInitialized) {\r\n            this._xrSessionManager._setBaseLayerWrapper(wrappedLayers.length > 0 ? (wrappedLayers.at(0)! as WebXRLayerWrapper) : null);\r\n        }\r\n    }\r\n\r\n    private _validateLayerCount(layerCount: number): void {\r\n        const maxRenderLayers = this.maxRenderLayers;\r\n        if (maxRenderLayers !== null && layerCount > maxRenderLayers) {\r\n            const layerLabel = maxRenderLayers === 1 ? \"layer\" : \"layers\";\r\n            throw new Error(`The XR session supports at most ${maxRenderLayers} render ${layerLabel}, but ${layerCount} were provided.`);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Checks whether the active runtime exposes the factory needed for a layer type.\r\n     * This is a capability check only; creation can still fail when an initialization dictionary is invalid.\r\n     * @param layerType the concrete WebXR layer type\r\n     * @param source whether to check a graphics-backed or media-backed layer\r\n     * @returns whether the requested factory is available\r\n     */\r\n    public isLayerTypeSupported(layerType: WebXRSpatialLayerType | \"XRProjectionLayer\", source: WebXRLayerSource = \"graphics\"): boolean {\r\n        if (source === \"media\") {\r\n            if (layerType === \"XRProjectionLayer\" || layerType === \"XRCubeLayer\" || typeof XRMediaBinding === \"undefined\") {\r\n                return false;\r\n            }\r\n            switch (layerType) {\r\n                case \"XRQuadLayer\":\r\n                    return typeof XRMediaBinding.prototype.createQuadLayer === \"function\";\r\n                case \"XRCylinderLayer\":\r\n                    return typeof XRMediaBinding.prototype.createCylinderLayer === \"function\";\r\n                case \"XREquirectLayer\":\r\n                    return typeof XRMediaBinding.prototype.createEquirectLayer === \"function\";\r\n            }\r\n        }\r\n\r\n        if (this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            if (typeof XRGPUBinding === \"undefined\") {\r\n                return false;\r\n            }\r\n            switch (layerType) {\r\n                case \"XRProjectionLayer\":\r\n                    return typeof XRGPUBinding.prototype.createProjectionLayer === \"function\";\r\n                case \"XRQuadLayer\":\r\n                    return typeof XRGPUBinding.prototype.createQuadLayer === \"function\";\r\n                case \"XRCylinderLayer\":\r\n                    return typeof XRGPUBinding.prototype.createCylinderLayer === \"function\";\r\n                case \"XREquirectLayer\":\r\n                    return typeof XRGPUBinding.prototype.createEquirectLayer === \"function\";\r\n                case \"XRCubeLayer\":\r\n                    return typeof XRGPUBinding.prototype.createCubeLayer === \"function\";\r\n            }\r\n        }\r\n\r\n        if (typeof XRWebGLBinding === \"undefined\") {\r\n            return false;\r\n        }\r\n        switch (layerType) {\r\n            case \"XRProjectionLayer\":\r\n                return typeof XRWebGLBinding.prototype.createProjectionLayer === \"function\";\r\n            case \"XRQuadLayer\":\r\n                return typeof XRWebGLBinding.prototype.createQuadLayer === \"function\";\r\n            case \"XRCylinderLayer\":\r\n                return typeof XRWebGLBinding.prototype.createCylinderLayer === \"function\";\r\n            case \"XREquirectLayer\":\r\n                return typeof XRWebGLBinding.prototype.createEquirectLayer === \"function\";\r\n            case \"XRCubeLayer\":\r\n                return typeof XRWebGLBinding.prototype.createCubeLayer === \"function\";\r\n        }\r\n    }\r\n\r\n    public override isCompatible(): boolean {\r\n        if (this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            return IsWebGPUXRSupported();\r\n        }\r\n        // Native WebGL continues to use NativeXRRenderTarget instead of WebXR Layers.\r\n        if (this._xrSessionManager.isNative) {\r\n            return false;\r\n        }\r\n        return typeof XRWebGLBinding !== \"undefined\" && !!XRWebGLBinding.prototype.createProjectionLayer;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached.\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame): void {\r\n        for (let i = 0; i < this._fallbackLayers.length; ++i) {\r\n            this._fallbackLayers[i].updateFromTransformNode(this._xrSessionManager.worldScalingFactor);\r\n        }\r\n\r\n        const layers = this._existingLayers;\r\n        for (let i = 0; i < layers.length; ++i) {\r\n            const layer = layers[i];\r\n            if (layer instanceof WebXRSpatialLayerWrapper) {\r\n                layer.updateFromTransformNode(this._xrSessionManager.scene.useRightHandedSystem, this._xrSessionManager.worldScalingFactor);\r\n            }\r\n            if (layer.layerType === \"XRProjectionLayer\" || !(layer instanceof WebXRCompositionLayerWrapper) || !layer.usesRenderTargetProvider) {\r\n                continue;\r\n            }\r\n            if (layer.isStatic && !layer.layer.needsRedraw) {\r\n                continue;\r\n            }\r\n\r\n            const rttProvider = this._layerToRTTProviderMapping.get(layer.layer);\r\n            if (!rttProvider) {\r\n                continue;\r\n            }\r\n            if (layer.layer.layout === \"mono\") {\r\n                rttProvider.getRenderTargetTextureForEye(\"none\");\r\n            } else {\r\n                const pose = _xrFrame.getViewerPose(this._xrSessionManager.referenceSpace);\r\n                if (pose) {\r\n                    const views = pose.views;\r\n                    for (let j = 0; j < views.length; ++j) {\r\n                        rttProvider.getRenderTargetTextureForView(views[j]);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRLayers.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRLayers(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRLayers.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRLayers(xrSessionManager, options);\r\n        },\r\n        WebXRLayers.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { RawTexture } from \"../../Materials/Textures/rawTexture\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Texture } from \"../../Materials/Textures/texture.pure\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { WebGLHardwareTexture } from \"../../Engines/WebGL/webGLHardwareTexture\";\r\nimport { type InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { type ThinEngine } from \"../../Engines/thinEngine.pure\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase.pure\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport { type Material } from \"core/Materials/material.pure\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { type UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial.pure\";\r\nimport { RegisterMaterialPlugin, UnregisterMaterialPlugin } from \"core/Materials/materialPluginManager.pure\";\r\nimport { type Camera } from \"core/Cameras/camera.pure\";\r\nimport { Matrix } from \"core/Maths/math.vector.pure\";\r\nimport { type Engine } from \"core/Engines/engine.pure\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\nimport { WebXRGraphicsBindingType } from \"../webXRGraphicsBinding\";\r\n\r\nexport type WebXRDepthUsage = \"cpu\" | \"gpu\";\r\nexport type WebXRDepthDataFormat = \"ushort\" | \"float\" | \"luminance-alpha\";\r\n\r\ninterface IWebXRDepthSensingSession extends XRSession {\r\n    readonly depthActive?: boolean;\r\n    pauseDepthSensing?: () => Promise<void>;\r\n    resumeDepthSensing?: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Options for Depth Sensing feature\r\n */\r\nexport interface IWebXRDepthSensingOptions {\r\n    /**\r\n     *  The desired depth sensing usage for the session\r\n     */\r\n    usagePreference: WebXRDepthUsage[];\r\n    /**\r\n     * The desired depth sensing data format for the session\r\n     */\r\n    dataFormatPreference: WebXRDepthDataFormat[];\r\n\r\n    /**\r\n     * Depth sensing will be enabled on all materials per default, if the GPU variant is enabled.\r\n     * If you just want to use the texture or the CPU variant instead set this to true.\r\n     */\r\n    disableDepthSensingOnMaterials?: boolean;\r\n\r\n    /**\r\n     * If set to true the occluded pixels will not be discarded but the pixel color will be changed based on the occlusion factor\r\n     * Enabling this will lead to worse performance but slightly better outcome.\r\n     * It is possible we will change this in the future to look even better.\r\n     */\r\n    useToleranceFactorForDepthSensing?: boolean;\r\n\r\n    /**\r\n     * If set to true the texture will be set to be used for visualization.\r\n     * In this case it will probably NOT work correctly on the materials.\r\n     * So be aware that, for the time being, you can only use one or the other.\r\n     */\r\n    prepareTextureForVisualization?: boolean;\r\n}\r\n\r\ntype GetDepthInMetersType = (x: number, y: number) => number;\r\n\r\nclass DepthSensingMaterialDefines extends MaterialDefines {\r\n    /**\r\n     * Is the feature enabled\r\n     */\r\n    DEPTH_SENSING = false;\r\n\r\n    /**\r\n     * Is the texture type provided as a texture array\r\n     */\r\n    DEPTH_SENSING_TEXTURE_ARRAY = false;\r\n\r\n    /**\r\n     * Is the texture type provided as Alpha-Luminance (unpacked differently on the shader)\r\n     */\r\n    DEPTH_SENSING_TEXTURE_AL = false;\r\n\r\n    /**\r\n     * Should the shader discard the pixel if the depth is less than the asset depth\r\n     * Will lead to better performance. the other variant is to change the color based on a tolerance factor\r\n     */\r\n    DEPTH_SENSING_DISCARD = true;\r\n}\r\n\r\nlet IsPluginEnabled = false;\r\nlet DepthTexture: Nullable<RawTexture> = null;\r\nlet DepthTextureRight: Nullable<RawTexture> = null;\r\nlet AlphaLuminanceTexture = false;\r\nconst ScreenSize = { width: 512, height: 512 };\r\nconst ShaderViewport = { x: 0, y: 0, width: 1, height: 1 };\r\nlet GlobalRawValueToMeters = 1;\r\nlet GlobalRawValueToMetersRight = 1;\r\nlet GlobalDepthAvailableLeft = 0;\r\nlet GlobalDepthAvailableRight = 0;\r\nlet GlobalWorldScale = 1;\r\nlet ViewIndex = 0;\r\nlet EnableDiscard = true;\r\nconst UvTransform = /*#__PURE__*/ Matrix.Identity();\r\nconst UvTransformRight = /*#__PURE__*/ Matrix.Identity();\r\nconst RightView = /*#__PURE__*/ Matrix.Identity();\r\nconst ManagedMaterialPlugins: WebXRDepthSensingMaterialPlugin[] = [];\r\nconst WebGPUGPUDepthWarning =\r\n    \"WebXR Depth Sensing is unavailable with WebGPU XR when the session negotiates gpu-optimized depth because XRGPUBinding has no environment-depth equivalent; request cpu-optimized depth to use the feature.\";\r\n\r\ninterface IWebXRCPUDepthViewState {\r\n    available: boolean;\r\n    height: number;\r\n    rawValueToMeters: number;\r\n    texture: Nullable<RawTexture>;\r\n    uvTransform: Matrix;\r\n    visualizationDepthBuffer: Nullable<Float32Array>;\r\n    width: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nclass WebXRDepthSensingMaterialPlugin extends MaterialPluginBase {\r\n    private _varColorName: string;\r\n    private _isEnabled = false;\r\n\r\n    /** @internal */\r\n    protected _markAllDefinesAsDirty(): void {\r\n        this._enable(this._isEnabled);\r\n        this.markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets whether the mesh debug plugin is enabled in the material.\r\n     */\r\n    public get isEnabled(): boolean {\r\n        return this._isEnabled;\r\n    }\r\n    /**\r\n     * Sets whether the mesh debug plugin is enabled in the material.\r\n     * @param value enabled\r\n     */\r\n    public set isEnabled(value: boolean) {\r\n        if (this._isEnabled === value) {\r\n            return;\r\n        }\r\n        this._isEnabled = value;\r\n        this._markAllDefinesAsDirty();\r\n    }\r\n\r\n    /**\r\n     * Gets a boolean indicating that the plugin is compatible with a given shader language.\r\n     * @param shaderLanguage The shader language to use.\r\n     * @returns true if the plugin is compatible with the shader language\r\n     */\r\n    public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n        switch (shaderLanguage) {\r\n            case ShaderLanguage.GLSL:\r\n            case ShaderLanguage.WGSL:\r\n                return true;\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    constructor(material: Material) {\r\n        super(material, \"DepthSensing\", 222, new DepthSensingMaterialDefines());\r\n        this._varColorName = material instanceof PBRBaseMaterial ? \"finalColor\" : \"color\";\r\n        this.doNotSerialize = true;\r\n        ManagedMaterialPlugins.push(this);\r\n    }\r\n\r\n    /**\r\n     * Prepare the defines\r\n     * @param defines the defines\r\n     */\r\n    public override prepareDefines(defines: DepthSensingMaterialDefines) {\r\n        defines.DEPTH_SENSING = !!DepthTexture && IsPluginEnabled;\r\n        defines.DEPTH_SENSING_TEXTURE_ARRAY = DepthTexture?.is2DArray ?? false;\r\n        defines.DEPTH_SENSING_TEXTURE_AL = AlphaLuminanceTexture;\r\n        defines.DEPTH_SENSING_DISCARD = EnableDiscard;\r\n    }\r\n\r\n    public override getUniforms(shaderLanguage = ShaderLanguage.GLSL) {\r\n        const ubo = [\r\n            { name: \"ds_invScreenSize\", size: 2, type: \"vec2\" },\r\n            { name: \"ds_rawValueToMeters\", size: 1, type: \"float\" },\r\n            { name: \"ds_viewIndex\", size: 1, type: \"float\" },\r\n            { name: \"ds_shaderViewport\", size: 4, type: \"vec4\" },\r\n            { name: \"ds_uvTransform\", size: 16, type: \"mat4\" },\r\n        ];\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            ubo.push(\r\n                { name: \"ds_rawValueToMetersRight\", size: 1, type: \"float\" },\r\n                { name: \"ds_depthAvailableLeft\", size: 1, type: \"float\" },\r\n                { name: \"ds_depthAvailableRight\", size: 1, type: \"float\" },\r\n                { name: \"ds_worldScale\", size: 1, type: \"float\" },\r\n                { name: \"ds_viewDepthSign\", size: 1, type: \"float\" },\r\n                { name: \"ds_uvTransformRight\", size: 16, type: \"mat4\" },\r\n                { name: \"ds_viewRight\", size: 16, type: \"mat4\" }\r\n            );\r\n        }\r\n        return {\r\n            // first, define the UBO with the correct type and size.\r\n            ubo,\r\n            // now, on the fragment shader, add the uniform itself in case uniform buffers are not supported by the engine\r\n            fragment:\r\n                shaderLanguage === ShaderLanguage.GLSL\r\n                    ? `#ifdef DEPTH_SENSING\r\n                uniform vec2 ds_invScreenSize;\r\n                uniform float ds_rawValueToMeters;\r\n                uniform float ds_viewIndex;\r\n                uniform vec4 ds_shaderViewport;\r\n                uniform mat4 ds_uvTransform;\r\n                #endif\r\n                `\r\n                    : \"\",\r\n        };\r\n    }\r\n\r\n    public override getSamplers(samplers: string[]): void {\r\n        samplers.push(\"ds_depthSampler\");\r\n        samplers.push(\"ds_depthSamplerRight\");\r\n    }\r\n\r\n    public override bindForSubMesh(uniformBuffer: UniformBuffer) {\r\n        if (IsPluginEnabled && DepthTexture) {\r\n            const isWGSL = this._material.shaderLanguage === ShaderLanguage.WGSL;\r\n            uniformBuffer.updateFloat2(\"ds_invScreenSize\", 1 / ScreenSize.width, 1 / ScreenSize.height);\r\n            uniformBuffer.updateFloat(\"ds_rawValueToMeters\", GlobalRawValueToMeters);\r\n            uniformBuffer.updateFloat(\"ds_viewIndex\", ViewIndex);\r\n            uniformBuffer.updateFloat4(\"ds_shaderViewport\", ShaderViewport.x, ShaderViewport.y, ShaderViewport.width, ShaderViewport.height);\r\n            uniformBuffer.setTexture(\"ds_depthSampler\", DepthTexture);\r\n            uniformBuffer.updateMatrix(\"ds_uvTransform\", UvTransform);\r\n            if (isWGSL) {\r\n                uniformBuffer.updateFloat(\"ds_rawValueToMetersRight\", GlobalRawValueToMetersRight);\r\n                uniformBuffer.updateFloat(\"ds_depthAvailableLeft\", GlobalDepthAvailableLeft);\r\n                uniformBuffer.updateFloat(\"ds_depthAvailableRight\", GlobalDepthAvailableRight);\r\n                uniformBuffer.updateFloat(\"ds_worldScale\", GlobalWorldScale);\r\n                uniformBuffer.updateFloat(\"ds_viewDepthSign\", this._material.getScene().useRightHandedSystem ? -1 : 1);\r\n                uniformBuffer.setTexture(\"ds_depthSamplerRight\", DepthTextureRight);\r\n                uniformBuffer.updateMatrix(\"ds_uvTransformRight\", UvTransformRight);\r\n                uniformBuffer.updateMatrix(\"ds_viewRight\", RightView);\r\n            }\r\n        }\r\n    }\r\n\r\n    public override getClassName() {\r\n        return \"DepthSensingMaterialPlugin\";\r\n    }\r\n\r\n    public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n        if (shaderLanguage === ShaderLanguage.WGSL) {\r\n            return shaderType === \"vertex\"\r\n                ? {\r\n                      CUSTOM_VERTEX_MAIN_BEGIN: `\r\n                #ifdef DEPTH_SENSING\r\n                #ifdef MULTIVIEW\r\n                    vertexOutputs.ds_viewIndexMultiview = f32(gl_ViewID_OVR);\r\n                #endif\r\n                #endif\r\n                `,\r\n                      CUSTOM_VERTEX_DEFINITIONS: `\r\n                #ifdef DEPTH_SENSING\r\n                #ifdef MULTIVIEW\r\n                    varying ds_viewIndexMultiview: f32;\r\n                #endif\r\n                #endif\r\n                `,\r\n                  }\r\n                : {\r\n                      CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                    #ifdef DEPTH_SENSING\r\n                        #ifdef DEPTH_SENSING_TEXTURE_ARRAY\r\n                            var ds_depthSampler: texture_2d_array<f32>;\r\n                        #else\r\n                            var ds_depthSampler: texture_2d<f32>;\r\n                        #endif\r\n                        var ds_depthSamplerSampler: sampler;\r\n                        #if defined(MULTIVIEW) && !defined(DEPTH_SENSING_TEXTURE_ARRAY)\r\n                            var ds_depthSamplerRight: texture_2d<f32>;\r\n                            var ds_depthSamplerRightSampler: sampler;\r\n                        #endif\r\n                        #ifdef MULTIVIEW\r\n                            varying ds_viewIndexMultiview: f32;\r\n                        #endif\r\n                    #endif\r\n                  `,\r\n                      CUSTOM_FRAGMENT_MAIN_BEGIN: `\r\n#ifdef DEPTH_SENSING\r\n    #ifdef MULTIVIEW\r\n        let ds_viewIndexSet: f32 = fragmentInputs.ds_viewIndexMultiview;\r\n        let ds_compensation: vec2f = vec2f(0.0, 0.0);\r\n    #else\r\n        let ds_viewIndexSet: f32 = uniforms.ds_viewIndex;\r\n        let ds_compensation: vec2f = vec2f(ds_viewIndexSet, 0.0);\r\n    #endif\r\n    let ds_baseUvBottomLeft: vec2f = (fragmentInputs.position.xy * uniforms.ds_invScreenSize - uniforms.ds_shaderViewport.xy) / uniforms.ds_shaderViewport.zw;\r\n    let ds_baseUv: vec2f = vec2f(ds_baseUvBottomLeft.x, 1.0 - ds_baseUvBottomLeft.y);\r\n    var ds_depthSample: vec4f = vec4f(0.0);\r\n    var ds_rawValueToMetersSet: f32 = uniforms.ds_rawValueToMeters;\r\n    #if defined(MULTIVIEW) && !defined(DEPTH_SENSING_TEXTURE_ARRAY)\r\n        var ds_depthAvailable: f32 = uniforms.ds_depthAvailableLeft;\r\n        if (ds_viewIndexSet < 0.5) {\r\n            if (ds_depthAvailable > 0.5) {\r\n                let ds_depthUv: vec2f = (uniforms.ds_uvTransform * vec4f(ds_baseUv, 0.0, 1.0)).xy;\r\n                ds_depthSample = textureSampleLevel(ds_depthSampler, ds_depthSamplerSampler, ds_depthUv, 0.0);\r\n            }\r\n        } else {\r\n            ds_depthAvailable = uniforms.ds_depthAvailableRight;\r\n            if (ds_depthAvailable > 0.5) {\r\n                let ds_depthUv: vec2f = (uniforms.ds_uvTransformRight * vec4f(ds_baseUv, 0.0, 1.0)).xy;\r\n                ds_depthSample = textureSampleLevel(ds_depthSamplerRight, ds_depthSamplerRightSampler, ds_depthUv, 0.0);\r\n            }\r\n            ds_rawValueToMetersSet = uniforms.ds_rawValueToMetersRight;\r\n        }\r\n    #else\r\n        let ds_depthAvailable: f32 = 1.0;\r\n        #ifdef DEPTH_SENSING_TEXTURE_ARRAY\r\n            let ds_uv: vec2f = ds_baseUv - ds_compensation;\r\n            let ds_depthUv: vec2f = (uniforms.ds_uvTransform * vec4f(ds_uv, 0.0, 1.0)).xy;\r\n            ds_depthSample = textureSample(ds_depthSampler, ds_depthSamplerSampler, ds_depthUv, i32(ds_viewIndexSet));\r\n        #else\r\n            let ds_depthUv: vec2f = (uniforms.ds_uvTransform * vec4f(ds_baseUv, 0.0, 1.0)).xy;\r\n            ds_depthSample = textureSample(ds_depthSampler, ds_depthSamplerSampler, ds_depthUv);\r\n        #endif\r\n    #endif\r\n    var ds_cameraDepth: f32;\r\n    #ifdef DEPTH_SENSING_TEXTURE_AL\r\n        let ds_alphaLuminance: vec2f = ds_depthSample.ra;\r\n        ds_cameraDepth = dot(ds_alphaLuminance, vec2f(255.0, 256.0 * 255.0));\r\n    #else\r\n        ds_cameraDepth = ds_depthSample.r;\r\n    #endif\r\n\r\n    ds_cameraDepth = ds_cameraDepth * ds_rawValueToMetersSet;\r\n\r\n    var ds_viewPosition: vec4f = scene.view * vec4f(fragmentInputs.vPositionW, 1.0);\r\n    #ifdef MULTIVIEW\r\n        if (ds_viewIndexSet >= 0.5) {\r\n            ds_viewPosition = uniforms.ds_viewRight * vec4f(fragmentInputs.vPositionW, 1.0);\r\n        }\r\n    #endif\r\n    let ds_assetDepth: f32 = (ds_viewPosition.z * uniforms.ds_viewDepthSign) / uniforms.ds_worldScale;\r\n    #ifdef DEPTH_SENSING_DISCARD\r\n    if (ds_depthAvailable > 0.5 && ds_cameraDepth > 0.0 && ds_cameraDepth < ds_assetDepth) {\r\n        discard;\r\n    }\r\n    #endif\r\n#endif\r\n                  `,\r\n                      CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#ifdef DEPTH_SENSING\r\n    #ifndef DEPTH_SENSING_DISCARD\r\n        if (ds_depthAvailable > 0.5 && ds_cameraDepth > 0.0) {\r\n            let ds_depthTolerancePerM: f32 = 0.005;\r\n            let ds_occlusion: f32 = clamp(1.0 - 0.5 * (ds_cameraDepth - ds_assetDepth) / (ds_depthTolerancePerM * ds_assetDepth) +\r\n                0.5, 0.0, 1.0);\r\n            ${this._varColorName} *= (1.0 - ds_occlusion);\r\n        }\r\n    #endif\r\n#endif\r\n                  `,\r\n                  };\r\n        }\r\n\r\n        return shaderType === \"vertex\"\r\n            ? {\r\n                  CUSTOM_VERTEX_MAIN_BEGIN: `\r\n                #ifdef DEPTH_SENSING\r\n                #ifdef MULTIVIEW\r\n                    ds_viewIndexMultiview = float(gl_ViewID_OVR);\r\n                #endif\r\n                #endif\r\n                `,\r\n                  CUSTOM_VERTEX_DEFINITIONS: `\r\n                #ifdef DEPTH_SENSING\r\n                #ifdef MULTIVIEW\r\n                    varying float ds_viewIndexMultiview;\r\n                #endif\r\n                #endif\r\n                `,\r\n              }\r\n            : {\r\n                  CUSTOM_FRAGMENT_DEFINITIONS: `\r\n                    #ifdef DEPTH_SENSING\r\n                        #ifdef DEPTH_SENSING_TEXTURE_ARRAY\r\n                            uniform highp sampler2DArray ds_depthSampler;\r\n                        #else\r\n                            uniform sampler2D ds_depthSampler;\r\n                        #endif\r\n                        #ifdef MULTIVIEW\r\n                            varying float ds_viewIndexMultiview;\r\n                        #endif\r\n                    #endif\r\n                  `,\r\n                  CUSTOM_FRAGMENT_MAIN_BEGIN: `\r\n#ifdef DEPTH_SENSING\r\n    #ifdef MULTIVIEW\r\n        float ds_viewIndexSet = ds_viewIndexMultiview;\r\n        vec2 ds_compensation = vec2(0.0, 0.0);\r\n    #else\r\n        float ds_viewIndexSet = ds_viewIndex;\r\n        vec2 ds_compensation = vec2(ds_viewIndexSet, 0.0);\r\n    #endif\r\n    vec2 ds_baseUv = gl_FragCoord.xy * ds_invScreenSize;\r\n    #ifdef DEPTH_SENSING_TEXTURE_ARRAY\r\n        vec2 ds_uv = ds_baseUv - ds_compensation;\r\n        vec3 ds_depthUv = vec3((ds_uvTransform * vec4(ds_uv, 0.0, 1.0)).xy, ds_viewIndexSet);\r\n    #else\r\n        vec2 ds_depthUv = (ds_uvTransform * vec4(ds_baseUv.x, 1.0 - ds_baseUv.y, 0.0, 1.0)).xy;\r\n    #endif\r\n    #ifdef DEPTH_SENSING_TEXTURE_AL\r\n        // from alpha-luminance - taken from the explainer\r\n        vec2 ds_alphaLuminance = texture(ds_depthSampler, ds_depthUv).ra;\r\n        float ds_cameraDepth = dot(ds_alphaLuminance, vec2(255.0, 256.0 * 255.0));\r\n    #else\r\n        float ds_cameraDepth = texture(ds_depthSampler, ds_depthUv).r;\r\n    #endif\r\n\r\n    ds_cameraDepth = ds_cameraDepth * ds_rawValueToMeters;\r\n\r\n    float ds_assetDepth = gl_FragCoord.z;\r\n    #ifdef DEPTH_SENSING_DISCARD\r\n    if(ds_cameraDepth < ds_assetDepth) {\r\n        discard;\r\n    }\r\n    #endif\r\n#endif  \r\n                  `,\r\n                  CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#ifdef DEPTH_SENSING\r\n    #ifndef DEPTH_SENSING_DISCARD\r\n        const float ds_depthTolerancePerM = 0.005;\r\n        float ds_occlusion = clamp(1.0 - 0.5 * (ds_cameraDepth - ds_assetDepth) / (ds_depthTolerancePerM * ds_assetDepth) +\r\n            0.5, 0.0, 1.0);\r\n        ${this._varColorName} *= (1.0 - ds_occlusion);\r\n    #endif\r\n#endif                  \r\n                  `,\r\n              };\r\n    }\r\n\r\n    public override dispose(_forceDisposeTextures?: boolean): void {\r\n        const index = ManagedMaterialPlugins.indexOf(this);\r\n        if (index !== -1) {\r\n            ManagedMaterialPlugins.splice(index, 1);\r\n        }\r\n        super.dispose(_forceDisposeTextures);\r\n    }\r\n}\r\n\r\n/**\r\n * WebXR Feature for WebXR Depth Sensing Module\r\n * @since 5.49.1\r\n */\r\nexport class WebXRDepthSensing extends WebXRAbstractFeature {\r\n    private _width: Nullable<number> = null;\r\n    private _height: Nullable<number> = null;\r\n    private _rawValueToMeters: Nullable<number> = null;\r\n    private _textureType: Nullable<string> = null;\r\n    private _normDepthBufferFromNormView: Nullable<XRRigidTransform> = null;\r\n    private _cachedDepthBuffer: Nullable<ArrayBuffer> = null;\r\n    private _cachedWebGLTexture: Nullable<WebGLTexture> = null;\r\n    private _cachedDepthImageTexture: Nullable<RawTexture> = null;\r\n    private _cachedDepthImageTextureWrapsExternalTexture = false;\r\n    private _cpuDepthViewStates: IWebXRCPUDepthViewState[] = [];\r\n    private _disableAutoAttachBeforeWebGPUGPUDepth = false;\r\n    private _disabledForWebGPUGPUDepth = false;\r\n    private _onCameraObserver: Nullable<Observer<Camera>> = null;\r\n    private _onSessionEndedObserver: Nullable<Observer<any>> = null;\r\n\r\n    /**\r\n     * Width of depth data. If depth data is not exist, returns null.\r\n     */\r\n    public get width(): Nullable<number> {\r\n        return this._width;\r\n    }\r\n\r\n    /**\r\n     * Height of depth data. If depth data is not exist, returns null.\r\n     */\r\n    public get height(): Nullable<number> {\r\n        return this._height;\r\n    }\r\n\r\n    /**\r\n     * Scale factor by which the raw depth values must be multiplied in order to get the depths in meters.\r\n     */\r\n    public get rawValueToMeters(): Nullable<number> {\r\n        return this._rawValueToMeters;\r\n    }\r\n\r\n    /**\r\n     * An XRRigidTransform that needs to be applied when indexing into the depth buffer.\r\n     */\r\n    public get normDepthBufferFromNormView(): Nullable<XRRigidTransform> {\r\n        return this._normDepthBufferFromNormView;\r\n    }\r\n\r\n    /**\r\n     * Describes which depth-sensing usage (\"cpu\" or \"gpu\") is used.\r\n     */\r\n    public get depthUsage(): WebXRDepthUsage {\r\n        switch (this._xrSessionManager.session.depthUsage) {\r\n            case \"cpu-optimized\":\r\n                return \"cpu\";\r\n            case \"gpu-optimized\":\r\n                return \"gpu\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Describes which depth sensing data format (\"ushort\" or \"float\") is used.\r\n     */\r\n    public get depthDataFormat(): WebXRDepthDataFormat {\r\n        switch (this._xrSessionManager.session.depthDataFormat) {\r\n            case \"luminance-alpha\":\r\n                return \"ushort\";\r\n            case \"float32\":\r\n                return \"float\";\r\n            case \"unsigned-short\":\r\n                return \"ushort\";\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Whether depth sensing is currently active for the XR session.\r\n     * Returns false when there is no active session or the runtime does not expose the active state.\r\n     * @see https://immersive-web.github.io/depth-sensing/\r\n     * @see https://playground.babylonjs.com/#SU7NUW#0\r\n     */\r\n    public get isDepthSensingActive(): boolean {\r\n        const session: IWebXRDepthSensingSession | undefined = this._xrSessionManager.session;\r\n        return this._xrSessionManager.inXRSession && session?.depthActive === true;\r\n    }\r\n\r\n    /**\r\n     * Pauses depth sensing for the active XR session.\r\n     * @returns A promise that resolves when the native pause operation completes.\r\n     * @throws If there is no active XR session or pausing depth sensing is not supported by the runtime.\r\n     * @see https://immersive-web.github.io/depth-sensing/\r\n     */\r\n    public async pauseDepthSensingAsync(): Promise<void> {\r\n        const session: IWebXRDepthSensingSession | undefined = this._xrSessionManager.session;\r\n        if (!this._xrSessionManager.inXRSession || !session) {\r\n            throw new Error(\"Pausing WebXR depth sensing requires an active XR session.\");\r\n        }\r\n        if (typeof session.pauseDepthSensing !== \"function\") {\r\n            throw new Error(\"XRSession.pauseDepthSensing is not supported by this XR runtime.\");\r\n        }\r\n        return await session.pauseDepthSensing();\r\n    }\r\n\r\n    /**\r\n     * Resumes depth sensing for the active XR session.\r\n     * @returns A promise that resolves when the native resume operation completes.\r\n     * @throws If there is no active XR session or resuming depth sensing is not supported by the runtime.\r\n     * @see https://immersive-web.github.io/depth-sensing/\r\n     */\r\n    public async resumeDepthSensingAsync(): Promise<void> {\r\n        const session: IWebXRDepthSensingSession | undefined = this._xrSessionManager.session;\r\n        if (!this._xrSessionManager.inXRSession || !session) {\r\n            throw new Error(\"Resuming WebXR depth sensing requires an active XR session.\");\r\n        }\r\n        if (typeof session.resumeDepthSensing !== \"function\") {\r\n            throw new Error(\"XRSession.resumeDepthSensing is not supported by this XR runtime.\");\r\n        }\r\n        return await session.resumeDepthSensing();\r\n    }\r\n\r\n    /**\r\n     * Latest cached InternalTexture which containing depth buffer information.\r\n     * This can be used when the depth usage is \"gpu\".\r\n     * @deprecated This will be removed in the future. Use latestDepthImageTexture\r\n     */\r\n    public get latestInternalTexture(): Nullable<InternalTexture> {\r\n        if (!this._cachedWebGLTexture) {\r\n            return null;\r\n        }\r\n\r\n        return this._getInternalTextureFromDepthInfo();\r\n    }\r\n\r\n    /**\r\n     * cached depth buffer\r\n     */\r\n    public get latestDepthBuffer(): Nullable<ArrayBufferView> {\r\n        if (!this._cachedDepthBuffer) {\r\n            return null;\r\n        }\r\n\r\n        return this.depthDataFormat === \"float\" ? new Float32Array(this._cachedDepthBuffer) : new Uint16Array(this._cachedDepthBuffer);\r\n    }\r\n\r\n    /**\r\n     * Event that notify when `DepthInformation.getDepthInMeters` is available.\r\n     * `getDepthInMeters` method needs active XRFrame (not available for cached XRFrame)\r\n     */\r\n    public onGetDepthInMetersAvailable: Observable<GetDepthInMetersType> = new Observable<GetDepthInMetersType>();\r\n\r\n    /**\r\n     * Latest cached Texture of depth image which is made from the depth buffer data.\r\n     */\r\n    public get latestDepthImageTexture(): Nullable<RawTexture> {\r\n        return this._cachedDepthImageTexture;\r\n    }\r\n\r\n    /**\r\n     * XRWebGLBinding which is used for acquiring WebGLDepthInformation\r\n     */\r\n    private _glBinding?: XRWebGLBinding;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.DEPTH_SENSING;\r\n\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Creates a new instance of the depth sensing feature\r\n     * @param _xrSessionManager the WebXRSessionManager\r\n     * @param options options for WebXR Depth Sensing Feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        public readonly options: IWebXRDepthSensingOptions\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"depth-sensing\";\r\n\r\n        // https://immersive-web.github.io/depth-sensing/\r\n        if (!this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            Logger.Warn(\"depth-sensing is an experimental and unstable feature.\");\r\n        }\r\n        EnableDiscard = !options.useToleranceFactorForDepthSensing;\r\n\r\n        RegisterMaterialPlugin(\"WebXRDepthSensingMaterialPlugin\", (material) => new WebXRDepthSensingMaterialPlugin(material));\r\n        this._onSessionEndedObserver = this._xrSessionManager.onXRSessionEnded.add(() => {\r\n            if (this._disabledForWebGPUGPUDepth) {\r\n                this._disabledForWebGPUGPUDepth = false;\r\n                this.disableAutoAttach = this._disableAutoAttachBeforeWebGPUGPUDepth;\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * attach this feature\r\n     * Will usually be called by the features manager\r\n     * @param force should attachment be forced (even when already attached)\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(force?: boolean): boolean {\r\n        const engine = this._xrSessionManager.scene.getEngine();\r\n        const depthUsage = this._xrSessionManager.session.depthUsage;\r\n        const depthDataFormat = this._xrSessionManager.session.depthDataFormat;\r\n\r\n        if (engine.isWebGPU && depthUsage === \"gpu-optimized\") {\r\n            if (this._disabledForWebGPUGPUDepth) {\r\n                this.disableAutoAttach = true;\r\n                return false;\r\n            }\r\n            this._disableAutoAttachBeforeWebGPUGPUDepth = this._autoAttachPolicyBeforeAttach ?? this.disableAutoAttach;\r\n            this._disabledForWebGPUGPUDepth = true;\r\n            return this._disableAutoAttach(WebGPUGPUDepthWarning);\r\n        }\r\n\r\n        if (depthUsage == null || depthDataFormat == null) {\r\n            return false;\r\n        }\r\n\r\n        if (!super.attach(force)) {\r\n            return false;\r\n        }\r\n\r\n        if (!engine.isWebGPU) {\r\n            const graphicsBinding = this._xrSessionManager._getGraphicsBinding();\r\n            if (graphicsBinding.bindingType !== WebXRGraphicsBindingType.WebGL) {\r\n                throw new Error(\"Expected a WebGL graphics binding for WebXR Depth Sensing.\");\r\n            }\r\n            this._glBinding = graphicsBinding.binding;\r\n        }\r\n\r\n        IsPluginEnabled = !this.options.disableDepthSensingOnMaterials;\r\n        if (IsPluginEnabled) {\r\n            for (const plugin of ManagedMaterialPlugins) {\r\n                plugin.isEnabled = true;\r\n            }\r\n            this._onCameraObserver = this._xrSessionManager.scene.onBeforeCameraRenderObservable.add((camera) => {\r\n                if (!IsPluginEnabled) {\r\n                    return;\r\n                }\r\n                // make sure this is a webxr camera\r\n                if (camera.outputRenderTarget) {\r\n                    const viewport = camera.rigCameras.length > 0 ? camera.rigCameras[0].viewport : camera.viewport;\r\n                    ScreenSize.width = camera.outputRenderTarget.getRenderWidth() / (!engine.isWebGPU && camera.rigParent ? camera.rigParent.rigCameras.length || 1 : 1);\r\n                    ScreenSize.height = camera.outputRenderTarget.getRenderHeight();\r\n                    ShaderViewport.x = viewport.x;\r\n                    ShaderViewport.y = viewport.y;\r\n                    ShaderViewport.width = viewport.width;\r\n                    ShaderViewport.height = viewport.height;\r\n                    GlobalWorldScale = this._xrSessionManager.worldScalingFactor;\r\n\r\n                    // find the viewIndex\r\n                    if (camera.rigParent) {\r\n                        const viewIndex = camera.rigParent.rigCameras.indexOf(camera);\r\n                        ViewIndex = viewIndex === -1 ? 0 : viewIndex;\r\n                        if (engine.isWebGPU && this.depthUsage === \"cpu\") {\r\n                            this._bindCPUDepthView(ViewIndex, false);\r\n                        }\r\n                    } else if (camera._renderingMultiview && engine.isWebGPU && this.depthUsage === \"cpu\") {\r\n                        ViewIndex = 0;\r\n                        const rightCamera = camera.rigCameras[1];\r\n                        if (rightCamera) {\r\n                            RightView.copyFrom(rightCamera.getViewMatrix());\r\n                        }\r\n                        this._bindCPUDepthView(0, true);\r\n                    }\r\n                }\r\n            });\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    public override detach() {\r\n        IsPluginEnabled = false;\r\n        DepthTexture = null;\r\n        DepthTextureRight = null;\r\n        this._cachedWebGLTexture = null;\r\n        this._cachedDepthBuffer = null;\r\n        this._width = null;\r\n        this._height = null;\r\n        this._rawValueToMeters = null;\r\n        this._textureType = null;\r\n        this._normDepthBufferFromNormView = null;\r\n        let cachedTextureDisposed = false;\r\n        for (const viewState of this._cpuDepthViewStates) {\r\n            viewState.texture?.dispose();\r\n            cachedTextureDisposed ||= viewState.texture === this._cachedDepthImageTexture;\r\n        }\r\n        this._cpuDepthViewStates.length = 0;\r\n        if (!cachedTextureDisposed) {\r\n            if (this._cachedDepthImageTextureWrapsExternalTexture && this._cachedDepthImageTexture?._texture) {\r\n                this._cachedDepthImageTexture._texture._hardwareTexture = null;\r\n            }\r\n            this._cachedDepthImageTexture?.dispose();\r\n        }\r\n        this._cachedDepthImageTexture = null;\r\n        this._cachedDepthImageTextureWrapsExternalTexture = false;\r\n        for (const plugin of ManagedMaterialPlugins) {\r\n            plugin.isEnabled = false;\r\n        }\r\n        if (this._onCameraObserver) {\r\n            this._xrSessionManager.scene.onBeforeCameraRenderObservable.remove(this._onCameraObserver);\r\n            this._onCameraObserver = null;\r\n        }\r\n        return super.detach();\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        if (this._onSessionEndedObserver) {\r\n            this._xrSessionManager.onXRSessionEnded.remove(this._onSessionEndedObserver);\r\n            this._onSessionEndedObserver = null;\r\n        }\r\n        super.dispose();\r\n        UnregisterMaterialPlugin(\"WebXRDepthSensingMaterialPlugin\");\r\n        this.onGetDepthInMetersAvailable.clear();\r\n        // cleanup\r\n        if (this._onCameraObserver) {\r\n            this._xrSessionManager.scene.onBeforeCameraRenderObservable.remove(this._onCameraObserver);\r\n        }\r\n        for (const plugin of ManagedMaterialPlugins) {\r\n            plugin.dispose();\r\n        }\r\n        ManagedMaterialPlugins.length = 0;\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame): void {\r\n        const referenceSPace = this._xrSessionManager.referenceSpace;\r\n        const depthUsage = this.depthUsage;\r\n        if (depthUsage === \"cpu\") {\r\n            for (const viewState of this._cpuDepthViewStates) {\r\n                viewState.available = false;\r\n            }\r\n        }\r\n        const pose = _xrFrame.getViewerPose(referenceSPace);\r\n        if (pose == null) {\r\n            if (depthUsage === \"cpu\") {\r\n                this._clearCPUDepthBinding();\r\n            }\r\n            return;\r\n        }\r\n        for (let viewIndex = 0; viewIndex < pose.views.length; viewIndex++) {\r\n            const view = pose.views[viewIndex];\r\n            switch (depthUsage) {\r\n                case \"cpu\":\r\n                    this._updateDepthInformationAndTextureCPUDepthUsage(_xrFrame, view, viewIndex, this.depthDataFormat);\r\n                    break;\r\n                case \"gpu\":\r\n                    if (!this._glBinding) {\r\n                        break;\r\n                    }\r\n                    this._updateDepthInformationAndTextureWebGLDepthUsage(this._glBinding, view, this.depthDataFormat);\r\n                    break;\r\n                default:\r\n                    Logger.Error(\"Unknown depth usage\");\r\n                    this.detach();\r\n                    break;\r\n            }\r\n        }\r\n        if (depthUsage === \"cpu\" && !this._cpuDepthViewStates.some((viewState) => viewState.available)) {\r\n            this._clearCPUDepthBinding();\r\n        }\r\n    }\r\n\r\n    private _updateDepthInformationAndTextureCPUDepthUsage(frame: XRFrame, view: XRView, viewIndex: number, dataFormat: WebXRDepthDataFormat): void {\r\n        const depthInfo = frame.getDepthInformation(view);\r\n        if (depthInfo == null) {\r\n            return;\r\n        }\r\n\r\n        const { data, width, height, rawValueToMeters, getDepthInMeters, normDepthBufferFromNormView } = depthInfo as XRCPUDepthInformation;\r\n        let viewState = this._cpuDepthViewStates[viewIndex];\r\n        if (!viewState) {\r\n            viewState = {\r\n                available: true,\r\n                height,\r\n                rawValueToMeters,\r\n                texture: null,\r\n                uvTransform: Matrix.Identity(),\r\n                visualizationDepthBuffer: null,\r\n                width,\r\n            };\r\n            this._cpuDepthViewStates[viewIndex] = viewState;\r\n        }\r\n\r\n        const textureSizeChanged = viewState.width !== width || viewState.height !== height;\r\n        this._width = width;\r\n        this._height = height;\r\n        this._rawValueToMeters = rawValueToMeters;\r\n        this._normDepthBufferFromNormView = normDepthBufferFromNormView;\r\n        this._cachedDepthBuffer = data;\r\n        AlphaLuminanceTexture = dataFormat === \"luminance-alpha\";\r\n        viewState.height = height;\r\n        viewState.available = true;\r\n        viewState.rawValueToMeters = rawValueToMeters;\r\n        viewState.uvTransform.fromArray(normDepthBufferFromNormView.matrix);\r\n        viewState.width = width;\r\n\r\n        // to avoid Illegal Invocation error, bind `this`\r\n        this.onGetDepthInMetersAvailable.notifyObservers(getDepthInMeters.bind(depthInfo));\r\n\r\n        if (!viewState.texture || textureSizeChanged) {\r\n            viewState.texture?.dispose();\r\n            viewState.texture = RawTexture.CreateRTexture(\r\n                null,\r\n                width,\r\n                height,\r\n                this._xrSessionManager.scene,\r\n                false,\r\n                false,\r\n                Texture.NEAREST_SAMPLINGMODE,\r\n                Constants.TEXTURETYPE_FLOAT\r\n            );\r\n        }\r\n        this._cachedDepthImageTextureWrapsExternalTexture = false;\r\n        this._cachedDepthImageTexture = viewState.texture;\r\n\r\n        let depthValues: Float32Array | Uint16Array | null = null;\r\n        switch (dataFormat) {\r\n            case \"ushort\":\r\n            case \"luminance-alpha\":\r\n                depthValues = new Uint16Array(data);\r\n                break;\r\n            case \"float\":\r\n                depthValues = new Float32Array(data);\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n        if (depthValues) {\r\n            let uploadData: Float32Array;\r\n            if (this.options.prepareTextureForVisualization) {\r\n                if (!viewState.visualizationDepthBuffer || viewState.visualizationDepthBuffer.length !== depthValues.length) {\r\n                    viewState.visualizationDepthBuffer = new Float32Array(depthValues.length);\r\n                }\r\n                uploadData = viewState.visualizationDepthBuffer;\r\n                for (let index = 0; index < depthValues.length; index++) {\r\n                    uploadData[index] = depthValues[index] * rawValueToMeters;\r\n                }\r\n            } else {\r\n                uploadData = depthValues instanceof Float32Array ? depthValues : Float32Array.from(depthValues);\r\n            }\r\n            viewState.texture.update(uploadData);\r\n        }\r\n\r\n        if (!this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            const hadDepthTexture = !!DepthTexture;\r\n            DepthTexture = viewState.texture;\r\n            DepthTextureRight = null;\r\n            GlobalDepthAvailableLeft = 1;\r\n            GlobalDepthAvailableRight = 0;\r\n            GlobalRawValueToMeters = viewState.rawValueToMeters;\r\n            UvTransform.copyFrom(viewState.uvTransform);\r\n            if (!hadDepthTexture) {\r\n                this._xrSessionManager.scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n            }\r\n        }\r\n    }\r\n\r\n    private _clearCPUDepthBinding(): void {\r\n        if (DepthTexture) {\r\n            DepthTexture = null;\r\n            DepthTextureRight = null;\r\n            this._xrSessionManager.scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n        }\r\n    }\r\n\r\n    private _bindCPUDepthView(viewIndex: number, multiview: boolean): void {\r\n        const leftViewState = this._cpuDepthViewStates[0];\r\n        const rightViewState = multiview ? this._cpuDepthViewStates[1] : null;\r\n        const viewState = multiview\r\n            ? leftViewState?.available && leftViewState.texture\r\n                ? leftViewState\r\n                : rightViewState?.available && rightViewState.texture\r\n                  ? rightViewState\r\n                  : null\r\n            : this._cpuDepthViewStates[viewIndex];\r\n        if (!viewState?.available || !viewState.texture) {\r\n            this._clearCPUDepthBinding();\r\n            return;\r\n        }\r\n\r\n        const hadDepthTexture = !!DepthTexture;\r\n        if (multiview && leftViewState?.available && leftViewState.texture) {\r\n            GlobalDepthAvailableLeft = 1;\r\n            DepthTexture = leftViewState.texture;\r\n            GlobalRawValueToMeters = leftViewState.rawValueToMeters;\r\n            UvTransform.copyFrom(leftViewState.uvTransform);\r\n        } else {\r\n            GlobalDepthAvailableLeft = multiview ? 0 : 1;\r\n            DepthTexture = viewState.texture;\r\n            GlobalRawValueToMeters = viewState.rawValueToMeters;\r\n            UvTransform.copyFrom(viewState.uvTransform);\r\n        }\r\n        if (multiview && rightViewState?.available && rightViewState.texture) {\r\n            GlobalDepthAvailableRight = 1;\r\n            DepthTextureRight = rightViewState.texture;\r\n            GlobalRawValueToMetersRight = rightViewState.rawValueToMeters;\r\n            UvTransformRight.copyFrom(rightViewState.uvTransform);\r\n        } else {\r\n            GlobalDepthAvailableRight = 0;\r\n            DepthTextureRight = viewState.texture;\r\n            GlobalRawValueToMetersRight = viewState.rawValueToMeters;\r\n            UvTransformRight.copyFrom(viewState.uvTransform);\r\n        }\r\n\r\n        if (!hadDepthTexture) {\r\n            this._xrSessionManager.scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n        }\r\n    }\r\n\r\n    private _updateDepthInformationAndTextureWebGLDepthUsage(webglBinding: XRWebGLBinding, view: XRView, dataFormat: WebXRDepthDataFormat): void {\r\n        const depthInfo = webglBinding.getDepthInformation(view);\r\n        if (depthInfo === null) {\r\n            return;\r\n        }\r\n        const { texture, width, height, textureType, rawValueToMeters, normDepthBufferFromNormView } = depthInfo as XRWebGLDepthInformation;\r\n\r\n        GlobalRawValueToMeters = rawValueToMeters;\r\n        AlphaLuminanceTexture = dataFormat === \"luminance-alpha\";\r\n        UvTransform.fromArray(normDepthBufferFromNormView.matrix);\r\n\r\n        if (this._cachedWebGLTexture) {\r\n            return;\r\n        }\r\n\r\n        this._width = width;\r\n        this._height = height;\r\n        this._cachedWebGLTexture = texture;\r\n        this._textureType = textureType;\r\n\r\n        const scene = this._xrSessionManager.scene;\r\n        const internalTexture = this._getInternalTextureFromDepthInfo();\r\n\r\n        if (!this._cachedDepthImageTexture) {\r\n            this._cachedDepthImageTexture = RawTexture.CreateRTexture(\r\n                null,\r\n                width,\r\n                height,\r\n                scene,\r\n                false,\r\n                true,\r\n                Texture.NEAREST_SAMPLINGMODE,\r\n                dataFormat === \"float\" ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n            );\r\n            this._cachedDepthImageTexture._texture?.dispose();\r\n        }\r\n\r\n        this._cachedDepthImageTexture._texture = internalTexture;\r\n        this._cachedDepthImageTextureWrapsExternalTexture = true;\r\n        DepthTexture = this._cachedDepthImageTexture;\r\n        this._xrSessionManager.scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n    }\r\n\r\n    /**\r\n     * Extends the session init object if needed\r\n     * @returns augmentation object for the xr session init object.\r\n     */\r\n    public async getXRSessionInitExtension(): Promise<Partial<XRSessionInit>> {\r\n        const isDepthUsageDeclared = this.options.usagePreference != null && this.options.usagePreference.length !== 0;\r\n        const isDataFormatDeclared = this.options.dataFormatPreference != null && this.options.dataFormatPreference.length !== 0;\r\n\r\n        return await new Promise((resolve) => {\r\n            if (isDepthUsageDeclared && isDataFormatDeclared) {\r\n                const usages: XRDepthUsage[] = this.options.usagePreference.map((usage) => {\r\n                    switch (usage) {\r\n                        case \"cpu\":\r\n                            return \"cpu-optimized\";\r\n                        case \"gpu\":\r\n                            return \"gpu-optimized\";\r\n                    }\r\n                });\r\n                const dataFormats: XRDepthDataFormat[] = this.options.dataFormatPreference.map((format) => {\r\n                    switch (format) {\r\n                        case \"luminance-alpha\":\r\n                            return \"luminance-alpha\";\r\n                        case \"float\":\r\n                            return \"float32\";\r\n                        case \"ushort\":\r\n                            return \"unsigned-short\";\r\n                    }\r\n                });\r\n\r\n                resolve({\r\n                    depthSensing: {\r\n                        usagePreference: usages,\r\n                        dataFormatPreference: dataFormats,\r\n                    },\r\n                });\r\n            } else {\r\n                resolve({});\r\n            }\r\n        });\r\n    }\r\n\r\n    private _getInternalTextureFromDepthInfo(): InternalTexture {\r\n        const engine = this._xrSessionManager.scene.getEngine();\r\n        const dataFormat = this.depthDataFormat;\r\n        const textureType = this._textureType;\r\n        if (!this._width || !this._height || !this._cachedWebGLTexture) {\r\n            throw new Error(\"Depth information is not available\");\r\n        }\r\n        const internalTexture = (engine as Engine).wrapWebGLTexture(\r\n            this._cachedWebGLTexture,\r\n            false,\r\n            Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n            this._width || 256,\r\n            this._height || 256\r\n        );\r\n        internalTexture.isCube = false;\r\n        internalTexture.invertY = false;\r\n        internalTexture._useSRGBBuffer = false;\r\n        internalTexture.format = dataFormat === \"luminance-alpha\" ? Constants.TEXTUREFORMAT_LUMINANCE_ALPHA : Constants.TEXTUREFORMAT_RGBA;\r\n        internalTexture.generateMipMaps = false;\r\n        internalTexture.type =\r\n            dataFormat === \"float\" ? Constants.TEXTURETYPE_FLOAT : dataFormat === \"ushort\" ? Constants.TEXTURETYPE_UNSIGNED_SHORT : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n        internalTexture._cachedWrapU = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n        internalTexture._cachedWrapV = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n        internalTexture._hardwareTexture = new WebGLHardwareTexture(this._cachedWebGLTexture, (engine as ThinEngine)._gl);\r\n        internalTexture.is2DArray = textureType === \"texture-array\";\r\n\r\n        return internalTexture;\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRDepthSensing.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRDepthSensing(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    RegisterClass(`BABYLON.DepthSensingMaterialPlugin`, WebXRDepthSensingMaterialPlugin);\r\n\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRDepthSensing.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRDepthSensing(xrSessionManager, options);\r\n        },\r\n        WebXRDepthSensing.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Engine } from \"../../Engines/engine.pure\";\r\nimport { type WebGLRenderTargetWrapper } from \"../../Engines/WebGL/webGLRenderTargetWrapper\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type IWebXRRenderTargetTextureProvider } from \"../webXRRenderTargetTextureProvider\";\r\nimport { type Viewport } from \"../../Maths/math.viewport\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Matrix } from \"../../Maths/math.vector.pure\";\r\nimport { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { ShaderMaterial } from \"../../Materials/shaderMaterial.pure\";\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Material } from \"../../Materials/material.pure\";\r\nimport { type Observer } from \"../../Misc/observable.pure\";\r\nimport { WebXRGraphicsBindingType } from \"../webXRGraphicsBinding\";\r\n\r\nconst _WebGPUUnavailableWarning =\r\n    \"WebXR Space Warp is unavailable with WebGPU XR because this runtime does not expose usable motion-vector/depth sub-images; the feature was disabled.\";\r\n\r\n/**\r\n * Used for Space Warp render process\r\n */\r\nexport class XRSpaceWarpRenderTarget extends RenderTargetTexture {\r\n    private _velocityMaterial: ShaderMaterial;\r\n    private _originalPairing: Array<[AbstractMesh, Nullable<Material>]> = [];\r\n    private _previousWorldMatrices: Array<Matrix> = [];\r\n    private _previousTransforms: Matrix[] = [Matrix.Identity(), Matrix.Identity()];\r\n\r\n    /**\r\n     * Creates a Space Warp render target\r\n     * @param motionVectorTexture WebGLTexture provided by WebGLSubImage\r\n     * @param depthStencilTexture WebGLTexture provided by WebGLSubImage\r\n     * @param scene scene used with the render target\r\n     * @param size the size of the render target (used for each view)\r\n     */\r\n    constructor(motionVectorTexture: WebGLTexture, depthStencilTexture: WebGLTexture, scene?: Scene, size: number | { width: number; height: number } | { ratio: number } = 512) {\r\n        super(\"spacewarp rtt\", size, scene, false, true, Constants.TEXTURETYPE_HALF_FLOAT, false, undefined, false, false, true, undefined, true);\r\n        this._renderTarget = (this.getScene()!.getEngine() as Engine).createMultiviewRenderTargetTexture(\r\n            this.getRenderWidth(),\r\n            this.getRenderHeight(),\r\n            motionVectorTexture,\r\n            depthStencilTexture\r\n        );\r\n        (this._renderTarget as WebGLRenderTargetWrapper)._disposeOnlyFramebuffers = true;\r\n        this._texture = this._renderTarget.texture!;\r\n        this._texture.isMultiview = true;\r\n        this._texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n\r\n        if (scene) {\r\n            this._velocityMaterial = new ShaderMaterial(\r\n                \"velocity shader material\",\r\n                scene,\r\n                {\r\n                    vertex: \"velocity\",\r\n                    fragment: \"velocity\",\r\n                },\r\n                {\r\n                    uniforms: [\"world\", \"previousWorld\", \"viewProjection\", \"viewProjectionR\", \"previousViewProjection\", \"previousViewProjectionR\"],\r\n                }\r\n            );\r\n            this._velocityMaterial._materialHelperNeedsPreviousMatrices = true;\r\n            this._velocityMaterial.onBindObservable.add((mesh) => {\r\n                // mesh. getWorldMatrix can be incorrect under rare conditions (e.g. when using a effective mesh in the render function).\r\n                // If the case arise that will require changing it we will need to change the bind process in the material class to also provide the world matrix as a parameter\r\n                this._previousWorldMatrices[mesh.uniqueId] = this._previousWorldMatrices[mesh.uniqueId] || mesh.getWorldMatrix();\r\n                this._velocityMaterial.getEffect().setMatrix(\"previousWorld\", this._previousWorldMatrices[mesh.uniqueId]);\r\n                this._previousWorldMatrices[mesh.uniqueId] = mesh.getWorldMatrix();\r\n                // now set the scene's previous matrix\r\n                this._velocityMaterial.getEffect().setMatrix(\"previousViewProjection\", this._previousTransforms[0]);\r\n                // multiview for sure\r\n                this._velocityMaterial.getEffect().setMatrix(\"previousViewProjectionR\", this._previousTransforms[1]);\r\n\r\n                // store the previous (current, to be exact) transforms\r\n                this._previousTransforms[0].copyFrom(scene.getTransformMatrix());\r\n                this._previousTransforms[1].copyFrom(scene._transformMatrixR);\r\n            });\r\n            this._velocityMaterial.freeze();\r\n        }\r\n    }\r\n\r\n    public override render(useCameraPostProcess: boolean = false, dumpForDebug: boolean = false): void {\r\n        // Swap to use velocity material\r\n        this._originalPairing.length = 0;\r\n        const scene = this.getScene();\r\n        // set the velocity material to render the velocity RTT\r\n        if (scene && this._velocityMaterial) {\r\n            scene.getActiveMeshes().forEach((mesh) => {\r\n                this._originalPairing.push([mesh, mesh.material]);\r\n                mesh.material = this._velocityMaterial;\r\n            });\r\n        }\r\n\r\n        super.render(useCameraPostProcess, dumpForDebug);\r\n\r\n        // Restore original materials\r\n        for (const tuple of this._originalPairing) {\r\n            tuple[0].material = tuple[1];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public override _bindFrameBuffer() {\r\n        if (!this._renderTarget) {\r\n            return;\r\n        }\r\n        (this.getScene()!.getEngine() as Engine).bindSpaceWarpFramebuffer(this._renderTarget);\r\n    }\r\n\r\n    /**\r\n     * Gets the number of views the corresponding to the texture (eg. a SpaceWarpRenderTarget will have > 1)\r\n     * @returns the view count\r\n     */\r\n    public override getViewCount() {\r\n        return 2;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this._velocityMaterial.dispose();\r\n        this._previousTransforms.length = 0;\r\n        this._previousWorldMatrices.length = 0;\r\n        this._originalPairing.length = 0;\r\n    }\r\n}\r\n\r\n/**\r\n * WebXR Space Warp Render Target Texture Provider\r\n */\r\nexport class WebXRSpaceWarpRenderTargetTextureProvider implements IWebXRRenderTargetTextureProvider {\r\n    protected _lastSubImages = new Map<XRView, XRWebGLSubImage>();\r\n    protected _renderTargetTextures = new Map<XREye, RenderTargetTexture>();\r\n    protected _framebufferDimensions: Nullable<{ framebufferWidth: number; framebufferHeight: number }>;\r\n    protected _engine: Engine;\r\n\r\n    constructor(\r\n        protected readonly _scene: Scene,\r\n        protected readonly _xrSessionManager: WebXRSessionManager,\r\n        protected readonly _xrWebGLBinding: XRWebGLBinding\r\n    ) {\r\n        this._engine = _scene.getEngine() as Engine;\r\n    }\r\n\r\n    private _getSubImageForView(view: XRView): XRWebGLSubImage {\r\n        const layerWrapper = this._xrSessionManager._getBaseLayerWrapper();\r\n        if (!layerWrapper) {\r\n            throw new Error(\"For Space Warp, the base layer should be a WebXR Projection Layer.\");\r\n        }\r\n        if (layerWrapper.layerType !== \"XRProjectionLayer\") {\r\n            throw new Error('For Space Warp, the base layer type should \"XRProjectionLayer\".');\r\n        }\r\n        const layer = layerWrapper.layer as XRProjectionLayer;\r\n        return this._xrWebGLBinding.getViewSubImage(layer, view);\r\n    }\r\n\r\n    protected _setViewportForSubImage(viewport: Viewport, subImage: XRWebGLSubImage) {\r\n        viewport.x = 0;\r\n        viewport.y = 0;\r\n        viewport.width = subImage.motionVectorTextureWidth!;\r\n        viewport.height = subImage.motionVectorTextureHeight!;\r\n    }\r\n\r\n    protected _createRenderTargetTexture(\r\n        width: number,\r\n        height: number,\r\n        framebuffer: Nullable<WebGLFramebuffer>,\r\n        motionVectorTexture: WebGLTexture,\r\n        depthStencilTexture: WebGLTexture\r\n    ): RenderTargetTexture {\r\n        if (!this._engine) {\r\n            throw new Error(\"Engine is disposed\");\r\n        }\r\n\r\n        const textureSize = { width, height };\r\n\r\n        // Create render target texture from the internal texture\r\n        const renderTargetTexture = new XRSpaceWarpRenderTarget(motionVectorTexture, depthStencilTexture, this._scene, textureSize);\r\n        const renderTargetWrapper = renderTargetTexture.renderTarget as WebGLRenderTargetWrapper;\r\n        if (framebuffer) {\r\n            renderTargetWrapper._framebuffer = framebuffer;\r\n        }\r\n\r\n        // Create internal texture\r\n        renderTargetWrapper._colorTextureArray = motionVectorTexture;\r\n        renderTargetWrapper._depthStencilTextureArray = depthStencilTexture;\r\n\r\n        renderTargetTexture.disableRescaling();\r\n        renderTargetTexture.renderListPredicate = () => true;\r\n\r\n        return renderTargetTexture;\r\n    }\r\n\r\n    protected _getRenderTargetForSubImage(subImage: XRWebGLSubImage, view: XRView) {\r\n        const lastSubImage = this._lastSubImages.get(view);\r\n        let renderTargetTexture = this._renderTargetTextures.get(view.eye);\r\n\r\n        const width = subImage.motionVectorTextureWidth!;\r\n        const height = subImage.motionVectorTextureHeight!;\r\n\r\n        if (!renderTargetTexture || lastSubImage?.textureWidth !== width || lastSubImage?.textureHeight != height) {\r\n            renderTargetTexture = this._createRenderTargetTexture(width, height, null, subImage.motionVectorTexture!, subImage.depthStencilTexture!);\r\n            this._renderTargetTextures.set(view.eye, renderTargetTexture);\r\n\r\n            this._framebufferDimensions = {\r\n                framebufferWidth: width,\r\n                framebufferHeight: height,\r\n            };\r\n        }\r\n\r\n        this._lastSubImages.set(view, subImage);\r\n\r\n        return renderTargetTexture;\r\n    }\r\n\r\n    public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n        const subImage = this._lastSubImages.get(view) || this._getSubImageForView(view);\r\n        if (subImage) {\r\n            this._setViewportForSubImage(viewport, subImage);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * Access the motion vector (which will turn on Space Warp)\r\n     * @param view the view to access the motion vector texture for\r\n     */\r\n    public accessMotionVector(view: XRView): void {\r\n        const subImage = this._getSubImageForView(view);\r\n        if (subImage) {\r\n            // Meta Quest Browser uses accessing these textures as a sign for turning on Space Warp\r\n            subImage.motionVectorTexture;\r\n            subImage.depthStencilTexture;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the render target texture for the specified eye\r\n     * @param _eye the eye to get the render target texture for\r\n     * @returns the render target texture or null\r\n     */\r\n    public getRenderTargetTextureForEye(_eye: XREye): Nullable<RenderTargetTexture> {\r\n        return null;\r\n    }\r\n\r\n    public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n        const subImage = this._getSubImageForView(view);\r\n        if (subImage) {\r\n            return this._getRenderTargetForSubImage(subImage, view);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public dispose() {\r\n        this._renderTargetTextures.forEach((rtt) => rtt.dispose());\r\n        this._renderTargetTextures.clear();\r\n    }\r\n}\r\n\r\n/**\r\n * the WebXR Space Warp feature.\r\n */\r\nexport class WebXRSpaceWarp extends WebXRAbstractFeature {\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.SPACE_WARP;\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * The space warp provider\r\n     */\r\n    public spaceWarpRTTProvider: Nullable<WebXRSpaceWarpRenderTargetTextureProvider>;\r\n    private _xrWebGLBinding: XRWebGLBinding;\r\n    private _renderTargetTexture: Nullable<RenderTargetTexture>;\r\n    private _onAfterRenderObserver: Nullable<Observer<Scene>> = null;\r\n\r\n    /**\r\n     * constructor for the space warp feature\r\n     * @param _xrSessionManager the xr session manager for this feature\r\n     */\r\n    constructor(_xrSessionManager: WebXRSessionManager) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"space-warp\";\r\n    }\r\n\r\n    /**\r\n     * Attach this feature.\r\n     * Will usually be called by the features manager.\r\n     *\r\n     * @returns true if successful.\r\n     */\r\n    public override attach(): boolean {\r\n        if (this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            return this._disableAutoAttach(_WebGPUUnavailableWarning);\r\n        }\r\n\r\n        if (!super.attach()) {\r\n            return false;\r\n        }\r\n        this._xrSessionManager.scene.needsPreviousWorldMatrices = true;\r\n\r\n        const graphicsBinding = this._xrSessionManager._getGraphicsBinding();\r\n        if (graphicsBinding.bindingType !== WebXRGraphicsBindingType.WebGL) {\r\n            throw new Error(\"Expected a WebGL graphics binding for WebXR Space Warp.\");\r\n        }\r\n        this._xrWebGLBinding = graphicsBinding.binding;\r\n\r\n        this.spaceWarpRTTProvider = new WebXRSpaceWarpRenderTargetTextureProvider(this._xrSessionManager.scene, this._xrSessionManager, this._xrWebGLBinding);\r\n\r\n        this._onAfterRenderObserver = this._xrSessionManager.scene.onAfterRenderObservable.add(() => this._onAfterRender());\r\n\r\n        return true;\r\n    }\r\n\r\n    public override detach(): boolean {\r\n        this._xrSessionManager.scene.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n        return super.detach();\r\n    }\r\n\r\n    private _onAfterRender(): void {\r\n        if (this.attached && this._renderTargetTexture) {\r\n            this._renderTargetTexture.render(false, false);\r\n        }\r\n    }\r\n\r\n    public override dependsOn: string[] = [WebXRFeatureName.LAYERS];\r\n\r\n    public override isCompatible(): boolean {\r\n        if (this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            return this._disableAutoAttach(_WebGPUUnavailableWarning);\r\n        }\r\n        return this._xrSessionManager.scene.getEngine().getCaps().colorBufferHalfFloat || false;\r\n    }\r\n\r\n    public override dispose(): void {\r\n        super.dispose();\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame): void {\r\n        const pose = _xrFrame.getViewerPose(this._xrSessionManager.referenceSpace);\r\n        if (!pose) {\r\n            return;\r\n        }\r\n\r\n        // get the first view to which we will create a texture (or update it)\r\n        const view = pose.views[0];\r\n        this._renderTargetTexture = this._renderTargetTexture || this.spaceWarpRTTProvider!.getRenderTargetTextureForView(view);\r\n        this.spaceWarpRTTProvider!.accessMotionVector(view);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRSpaceWarp.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRSpaceWarp(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    //register the plugin\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRSpaceWarp.Name,\r\n        (xrSessionManager) => {\r\n            return () => new WebXRSpaceWarp(xrSessionManager);\r\n        },\r\n        WebXRSpaceWarp.Version,\r\n        false\r\n    );\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"velocityPixelShader\";\nconst shader = `precision highp float;\n#define CUSTOM_FRAGMENT_BEGIN\nvarying vec4 clipPos;varying vec4 previousClipPos;\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nhighp vec4 motionVector=( clipPos/clipPos.w-previousClipPos/previousClipPos.w );gl_FragColor=motionVector;\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const velocityPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\n\nconst name = \"velocityVertexShader\";\nconst shader = `#define CUSTOM_VERTEX_BEGIN\n#define VELOCITY\nattribute vec3 position;\n#include<instancesDeclaration>\nuniform mat4 viewProjection;uniform mat4 previousViewProjection;\n#ifdef MULTIVIEW\nuniform mat4 viewProjectionR;uniform mat4 previousViewProjectionR;\n#endif\nvarying vec4 clipPos;varying vec4 previousClipPos;\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#include<instancesVertex>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);vec4 previousWorldPos=finalPreviousWorld*vec4(positionUpdated,1.0);\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR==0u) {clipPos=viewProjection*worldPos;previousClipPos=previousViewProjection*previousWorldPos;gl_Position=clipPos;} else {clipPos=viewProjectionR*worldPos;previousClipPos=previousViewProjectionR*previousWorldPos;gl_Position=clipPos;}\n#elif\nclipPos=viewProjection*worldPos;previousClipPos=previousViewProjection*previousWorldPos;gl_Position=clipPos;\n#endif\n#define CUSTOM_VERTEX_MAIN_END\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [instancesDeclaration, instancesVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const velocityVertexShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { WebGLHardwareTexture } from \"../../Engines/WebGL/webGLHardwareTexture\";\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { WebXRGraphicsBindingType } from \"../webXRGraphicsBinding\";\r\n\r\n/**\r\n * Options for raw camera access\r\n */\r\nexport interface IWebXRRawCameraAccessOptions {\r\n    /**\r\n     * Keep the created textures and metadata when detaching the feature.\r\n     */\r\n    doNotDisposeOnDetach?: boolean;\r\n}\r\n\r\n/**\r\n * WebXR Feature for WebXR raw camera access\r\n * @since 6.31.0\r\n * @see https://immersive-web.github.io/raw-camera-access/\r\n */\r\nexport class WebXRRawCameraAccess extends WebXRAbstractFeature {\r\n    private _cachedInternalTextures: InternalTexture[] = [];\r\n    /**\r\n     * This is an array of camera views\r\n     * Note that mostly the array will contain a single view\r\n     * If you want to know the order of the views, use the `viewIndex` array\r\n     */\r\n    public texturesData: BaseTexture[] = [];\r\n    /**\r\n     * If needed, this array will contain the eye definition of each texture in `texturesArray`\r\n     */\r\n    public viewIndex: string[] = [];\r\n\r\n    /**\r\n     * If needed, this array will contain the camera's intrinsics\r\n     * You can use this data to convert from camera space to screen space and vice versa\r\n     */\r\n    public cameraIntrinsics: {\r\n        u0: number;\r\n        v0: number;\r\n        ax: number;\r\n        ay: number;\r\n        gamma: number;\r\n        width: number;\r\n        height: number;\r\n        viewportX: number;\r\n        viewportY: number;\r\n    }[] = [];\r\n\r\n    /**\r\n     * An observable that will notify when the camera's textures are updated\r\n     */\r\n    public onTexturesUpdatedObservable: Observable<BaseTexture[]> = new Observable();\r\n\r\n    private _glBinding?: XRWebGLBinding;\r\n    private _glContext: WebGLRenderingContext;\r\n\r\n    /**\r\n     * The module's name\r\n     */\r\n    public static readonly Name = WebXRFeatureName.RAW_CAMERA_ACCESS;\r\n\r\n    /**\r\n     * The (Babylon) version of this module.\r\n     * This is an integer representing the implementation version.\r\n     * This number does not correspond to the WebXR specs version\r\n     */\r\n    public static readonly Version = 1;\r\n\r\n    /**\r\n     * Creates a new instance of the feature\r\n     * @param _xrSessionManager the WebXRSessionManager\r\n     * @param options options for the Feature\r\n     */\r\n    constructor(\r\n        _xrSessionManager: WebXRSessionManager,\r\n        public readonly options: IWebXRRawCameraAccessOptions = {}\r\n    ) {\r\n        super(_xrSessionManager);\r\n        this.xrNativeFeatureName = \"camera-access\";\r\n    }\r\n\r\n    public override attach(force?: boolean): boolean {\r\n        if (this._xrSessionManager.scene.getEngine().isWebGPU) {\r\n            return this._disableAutoAttach(\r\n                \"WebXR Raw Camera Access is unavailable with WebGPU XR because camera images are exposed only by XRWebGLBinding; the feature was disabled.\"\r\n            );\r\n        }\r\n\r\n        if (!super.attach(force)) {\r\n            return false;\r\n        }\r\n\r\n        const graphicsBinding = this._xrSessionManager._getGraphicsBinding();\r\n        if (graphicsBinding.bindingType !== WebXRGraphicsBindingType.WebGL) {\r\n            throw new Error(\"Expected a WebGL graphics binding for WebXR Raw Camera Access.\");\r\n        }\r\n        this._glContext = graphicsBinding.context;\r\n        this._glBinding = graphicsBinding.binding;\r\n\r\n        return true;\r\n    }\r\n\r\n    public override detach(): boolean {\r\n        if (!super.detach()) {\r\n            return false;\r\n        }\r\n        this._glBinding = undefined;\r\n        if (!this.options.doNotDisposeOnDetach) {\r\n            for (const t of this._cachedInternalTextures) {\r\n                t.dispose();\r\n            }\r\n            for (const t of this.texturesData) {\r\n                t.dispose();\r\n            }\r\n            this._cachedInternalTextures.length = 0;\r\n            this.texturesData.length = 0;\r\n            this.cameraIntrinsics.length = 0;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Dispose this feature and all of the resources attached\r\n     */\r\n    public override dispose(): void {\r\n        super.dispose();\r\n        this.onTexturesUpdatedObservable.clear();\r\n    }\r\n\r\n    /**\r\n     * @see https://github.com/immersive-web/raw-camera-access/blob/main/explainer.md\r\n     * @param view the XRView to update\r\n     * @param index the index of the view in the views array\r\n     */\r\n    private _updateCameraIntrinsics(view: XRView, index: number): void {\r\n        const cameraViewport = {\r\n            width: view.camera!.width,\r\n            height: view.camera!.height,\r\n            x: 0,\r\n            y: 0,\r\n        };\r\n        const p = view.projectionMatrix;\r\n\r\n        // Principal point in pixels (typically at or near the center of the viewport)\r\n        const u0 = ((1 - p[8]) * cameraViewport.width) / 2 + cameraViewport.x;\r\n        const v0 = ((1 - p[9]) * cameraViewport.height) / 2 + cameraViewport.y;\r\n\r\n        // Focal lengths in pixels (these are equal for square pixels)\r\n        const ax = (cameraViewport.width / 2) * p[0];\r\n        const ay = (cameraViewport.height / 2) * p[5];\r\n\r\n        // Skew factor in pixels (nonzero for rhomboid pixels)\r\n        const gamma = (cameraViewport.width / 2) * p[4];\r\n        this.cameraIntrinsics[index] = {\r\n            u0,\r\n            v0,\r\n            ax,\r\n            ay,\r\n            gamma,\r\n            width: cameraViewport.width,\r\n            height: cameraViewport.height,\r\n            viewportX: cameraViewport.x,\r\n            viewportY: cameraViewport.y,\r\n        };\r\n    }\r\n\r\n    private _updateInternalTextures(view: XRView, index = 0): boolean {\r\n        if (!view.camera) {\r\n            return false;\r\n        }\r\n        this.viewIndex[index] = view.eye;\r\n        const lp = this._glBinding?.getCameraImage(view.camera);\r\n\r\n        if (!this._cachedInternalTextures[index]) {\r\n            const internalTexture = new InternalTexture(this._xrSessionManager.scene.getEngine(), InternalTextureSource.Unknown, true);\r\n            internalTexture.invertY = false;\r\n            internalTexture.format = Constants.TEXTUREFORMAT_RGBA;\r\n            internalTexture.generateMipMaps = true;\r\n            internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            internalTexture.samplingMode = Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR;\r\n            internalTexture.width = view.camera.width;\r\n            internalTexture.height = view.camera.height;\r\n            internalTexture._cachedWrapU = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n            internalTexture._cachedWrapV = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n            internalTexture._hardwareTexture = new WebGLHardwareTexture(lp, this._glContext);\r\n            this._cachedInternalTextures[index] = internalTexture;\r\n            // create the base texture\r\n            const texture = new BaseTexture(this._xrSessionManager.scene);\r\n            texture.name = `WebXR Raw Camera Access (${index})`;\r\n            texture._texture = this._cachedInternalTextures[index];\r\n            this.texturesData[index] = texture;\r\n            // get the camera intrinsics\r\n            this._updateCameraIntrinsics(view, index);\r\n        } else {\r\n            // make sure the webgl texture is updated. Should happen automatically\r\n            this._cachedInternalTextures[index]._hardwareTexture?.set(lp);\r\n        }\r\n        this._cachedInternalTextures[index].isReady = true;\r\n        return true;\r\n    }\r\n\r\n    protected _onXRFrame(_xrFrame: XRFrame): void {\r\n        const referenceSPace = this._xrSessionManager.referenceSpace;\r\n\r\n        const pose = _xrFrame.getViewerPose(referenceSPace);\r\n        if (!pose || !pose.views) {\r\n            return;\r\n        }\r\n        let updated = true;\r\n        for (let index = 0; index < pose.views.length; index++) {\r\n            const view = pose.views[index];\r\n            updated = updated && this._updateInternalTextures(view, index);\r\n        }\r\n        if (updated) {\r\n            this.onTexturesUpdatedObservable.notifyObservers(this.texturesData);\r\n        }\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRRawCameraAccess.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRRawCameraAccess(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    WebXRFeaturesManager.AddWebXRFeature(\r\n        WebXRRawCameraAccess.Name,\r\n        (xrSessionManager, options) => {\r\n            return () => new WebXRRawCameraAccess(xrSessionManager, options);\r\n        },\r\n        WebXRRawCameraAccess.Version,\r\n        false\r\n    );\r\n}\r\n","/** This file must only contain pure code and pure imports */\n\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\nimport { Matrix, Quaternion, Vector3 } from \"../../Maths/math.vector.pure\";\nimport { type Nullable } from \"../../types\";\nimport { type IDisposable, type Scene } from \"../../scene.pure\";\nimport { Observable } from \"../../Misc/observable.pure\";\nimport { type Observer } from \"../../Misc/observable\";\nimport { TransformNode } from \"../../Meshes/transformNode.pure\";\nimport { type Node } from \"../../node\";\nimport { Logger } from \"../../Misc/logger\";\nimport { type Bone } from \"../../Bones/bone.pure\";\n\n/**\n * All 83 body joint names as defined by the WebXR Body Tracking specification.\n * @see https://immersive-web.github.io/body-tracking/#xrbody-interface\n */\nexport const enum WebXRBodyJoint {\n    /** The center of the hips / pelvis */\n    HIPS = \"hips\",\n    /** Lower spine (lumbar) */\n    SPINE_LOWER = \"spine-lower\",\n    /** Middle spine (thoracic) */\n    SPINE_MIDDLE = \"spine-middle\",\n    /** Upper spine */\n    SPINE_UPPER = \"spine-upper\",\n    /** Chest */\n    CHEST = \"chest\",\n    /** Neck */\n    NECK = \"neck\",\n    /** Head */\n    HEAD = \"head\",\n\n    // ── Left Arm ──────────────────────────────────────────────\n    /** Left shoulder */\n    LEFT_SHOULDER = \"left-shoulder\",\n    /** Left scapula */\n    LEFT_SCAPULA = \"left-scapula\",\n    /** Left upper arm */\n    LEFT_ARM_UPPER = \"left-arm-upper\",\n    /** Left forearm (lower arm) */\n    LEFT_ARM_LOWER = \"left-arm-lower\",\n    /** Left hand wrist twist (forearm twist) */\n    LEFT_HAND_WRIST_TWIST = \"left-hand-wrist-twist\",\n\n    // ── Right Arm ─────────────────────────────────────────────\n    /** Right shoulder */\n    RIGHT_SHOULDER = \"right-shoulder\",\n    /** Right scapula */\n    RIGHT_SCAPULA = \"right-scapula\",\n    /** Right upper arm */\n    RIGHT_ARM_UPPER = \"right-arm-upper\",\n    /** Right forearm (lower arm) */\n    RIGHT_ARM_LOWER = \"right-arm-lower\",\n    /** Right hand wrist twist (forearm twist) */\n    RIGHT_HAND_WRIST_TWIST = \"right-hand-wrist-twist\",\n\n    // ── Left Hand ─────────────────────────────────────────────\n    /** Left palm center */\n    LEFT_HAND_PALM = \"left-hand-palm\",\n    /** Left wrist */\n    LEFT_HAND_WRIST = \"left-hand-wrist\",\n    /** Left thumb metacarpal */\n    LEFT_HAND_THUMB_METACARPAL = \"left-hand-thumb-metacarpal\",\n    /** Left thumb proximal phalanx */\n    LEFT_HAND_THUMB_PHALANX_PROXIMAL = \"left-hand-thumb-phalanx-proximal\",\n    /** Left thumb distal phalanx */\n    LEFT_HAND_THUMB_PHALANX_DISTAL = \"left-hand-thumb-phalanx-distal\",\n    /** Left thumb tip */\n    LEFT_HAND_THUMB_TIP = \"left-hand-thumb-tip\",\n    /** Left index finger metacarpal */\n    LEFT_HAND_INDEX_METACARPAL = \"left-hand-index-metacarpal\",\n    /** Left index finger proximal phalanx */\n    LEFT_HAND_INDEX_PHALANX_PROXIMAL = \"left-hand-index-phalanx-proximal\",\n    /** Left index finger intermediate phalanx */\n    LEFT_HAND_INDEX_PHALANX_INTERMEDIATE = \"left-hand-index-phalanx-intermediate\",\n    /** Left index finger distal phalanx */\n    LEFT_HAND_INDEX_PHALANX_DISTAL = \"left-hand-index-phalanx-distal\",\n    /** Left index finger tip */\n    LEFT_HAND_INDEX_TIP = \"left-hand-index-tip\",\n    /** Left middle finger metacarpal */\n    LEFT_HAND_MIDDLE_METACARPAL = \"left-hand-middle-metacarpal\",\n    /** Left middle finger proximal phalanx */\n    LEFT_HAND_MIDDLE_PHALANX_PROXIMAL = \"left-hand-middle-phalanx-proximal\",\n    /** Left middle finger intermediate phalanx */\n    LEFT_HAND_MIDDLE_PHALANX_INTERMEDIATE = \"left-hand-middle-phalanx-intermediate\",\n    /** Left middle finger distal phalanx */\n    LEFT_HAND_MIDDLE_PHALANX_DISTAL = \"left-hand-middle-phalanx-distal\",\n    /** Left middle finger tip */\n    LEFT_HAND_MIDDLE_TIP = \"left-hand-middle-tip\",\n    /** Left ring finger metacarpal */\n    LEFT_HAND_RING_METACARPAL = \"left-hand-ring-metacarpal\",\n    /** Left ring finger proximal phalanx */\n    LEFT_HAND_RING_PHALANX_PROXIMAL = \"left-hand-ring-phalanx-proximal\",\n    /** Left ring finger intermediate phalanx */\n    LEFT_HAND_RING_PHALANX_INTERMEDIATE = \"left-hand-ring-phalanx-intermediate\",\n    /** Left ring finger distal phalanx */\n    LEFT_HAND_RING_PHALANX_DISTAL = \"left-hand-ring-phalanx-distal\",\n    /** Left ring finger tip */\n    LEFT_HAND_RING_TIP = \"left-hand-ring-tip\",\n    /** Left little finger metacarpal */\n    LEFT_HAND_LITTLE_METACARPAL = \"left-hand-little-metacarpal\",\n    /** Left little finger proximal phalanx */\n    LEFT_HAND_LITTLE_PHALANX_PROXIMAL = \"left-hand-little-phalanx-proximal\",\n    /** Left little finger intermediate phalanx */\n    LEFT_HAND_LITTLE_PHALANX_INTERMEDIATE = \"left-hand-little-phalanx-intermediate\",\n    /** Left little finger distal phalanx */\n    LEFT_HAND_LITTLE_PHALANX_DISTAL = \"left-hand-little-phalanx-distal\",\n    /** Left little finger tip */\n    LEFT_HAND_LITTLE_TIP = \"left-hand-little-tip\",\n\n    // ── Right Hand ────────────────────────────────────────────\n    /** Right palm center */\n    RIGHT_HAND_PALM = \"right-hand-palm\",\n    /** Right wrist */\n    RIGHT_HAND_WRIST = \"right-hand-wrist\",\n    /** Right thumb metacarpal */\n    RIGHT_HAND_THUMB_METACARPAL = \"right-hand-thumb-metacarpal\",\n    /** Right thumb proximal phalanx */\n    RIGHT_HAND_THUMB_PHALANX_PROXIMAL = \"right-hand-thumb-phalanx-proximal\",\n    /** Right thumb distal phalanx */\n    RIGHT_HAND_THUMB_PHALANX_DISTAL = \"right-hand-thumb-phalanx-distal\",\n    /** Right thumb tip */\n    RIGHT_HAND_THUMB_TIP = \"right-hand-thumb-tip\",\n    /** Right index finger metacarpal */\n    RIGHT_HAND_INDEX_METACARPAL = \"right-hand-index-metacarpal\",\n    /** Right index finger proximal phalanx */\n    RIGHT_HAND_INDEX_PHALANX_PROXIMAL = \"right-hand-index-phalanx-proximal\",\n    /** Right index finger intermediate phalanx */\n    RIGHT_HAND_INDEX_PHALANX_INTERMEDIATE = \"right-hand-index-phalanx-intermediate\",\n    /** Right index finger distal phalanx */\n    RIGHT_HAND_INDEX_PHALANX_DISTAL = \"right-hand-index-phalanx-distal\",\n    /** Right index finger tip */\n    RIGHT_HAND_INDEX_TIP = \"right-hand-index-tip\",\n    /** Right middle finger metacarpal */\n    RIGHT_HAND_MIDDLE_METACARPAL = \"right-hand-middle-metacarpal\",\n    /** Right middle finger proximal phalanx */\n    RIGHT_HAND_MIDDLE_PHALANX_PROXIMAL = \"right-hand-middle-phalanx-proximal\",\n    /** Right middle finger intermediate phalanx */\n    RIGHT_HAND_MIDDLE_PHALANX_INTERMEDIATE = \"right-hand-middle-phalanx-intermediate\",\n    /** Right middle finger distal phalanx */\n    RIGHT_HAND_MIDDLE_PHALANX_DISTAL = \"right-hand-middle-phalanx-distal\",\n    /** Right middle finger tip */\n    RIGHT_HAND_MIDDLE_TIP = \"right-hand-middle-tip\",\n    /** Right ring finger metacarpal */\n    RIGHT_HAND_RING_METACARPAL = \"right-hand-ring-metacarpal\",\n    /** Right ring finger proximal phalanx */\n    RIGHT_HAND_RING_PHALANX_PROXIMAL = \"right-hand-ring-phalanx-proximal\",\n    /** Right ring finger intermediate phalanx */\n    RIGHT_HAND_RING_PHALANX_INTERMEDIATE = \"right-hand-ring-phalanx-intermediate\",\n    /** Right ring finger distal phalanx */\n    RIGHT_HAND_RING_PHALANX_DISTAL = \"right-hand-ring-phalanx-distal\",\n    /** Right ring finger tip */\n    RIGHT_HAND_RING_TIP = \"right-hand-ring-tip\",\n    /** Right little finger metacarpal */\n    RIGHT_HAND_LITTLE_METACARPAL = \"right-hand-little-metacarpal\",\n    /** Right little finger proximal phalanx */\n    RIGHT_HAND_LITTLE_PHALANX_PROXIMAL = \"right-hand-little-phalanx-proximal\",\n    /** Right little finger intermediate phalanx */\n    RIGHT_HAND_LITTLE_PHALANX_INTERMEDIATE = \"right-hand-little-phalanx-intermediate\",\n    /** Right little finger distal phalanx */\n    RIGHT_HAND_LITTLE_PHALANX_DISTAL = \"right-hand-little-phalanx-distal\",\n    /** Right little finger tip */\n    RIGHT_HAND_LITTLE_TIP = \"right-hand-little-tip\",\n\n    // ── Left Leg / Foot ───────────────────────────────────────\n    /** Left upper leg (thigh) */\n    LEFT_UPPER_LEG = \"left-upper-leg\",\n    /** Left lower leg (shin) */\n    LEFT_LOWER_LEG = \"left-lower-leg\",\n    /** Left foot ankle twist */\n    LEFT_FOOT_ANKLE_TWIST = \"left-foot-ankle-twist\",\n    /** Left foot ankle */\n    LEFT_FOOT_ANKLE = \"left-foot-ankle\",\n    /** Left foot subtalar */\n    LEFT_FOOT_SUBTALAR = \"left-foot-subtalar\",\n    /** Left foot transverse */\n    LEFT_FOOT_TRANSVERSE = \"left-foot-transverse\",\n    /** Left foot ball */\n    LEFT_FOOT_BALL = \"left-foot-ball\",\n\n    // ── Right Leg / Foot ──────────────────────────────────────\n    /** Right upper leg (thigh) */\n    RIGHT_UPPER_LEG = \"right-upper-leg\",\n    /** Right lower leg (shin) */\n    RIGHT_LOWER_LEG = \"right-lower-leg\",\n    /** Right foot ankle twist */\n    RIGHT_FOOT_ANKLE_TWIST = \"right-foot-ankle-twist\",\n    /** Right foot ankle */\n    RIGHT_FOOT_ANKLE = \"right-foot-ankle\",\n    /** Right foot subtalar */\n    RIGHT_FOOT_SUBTALAR = \"right-foot-subtalar\",\n    /** Right foot transverse */\n    RIGHT_FOOT_TRANSVERSE = \"right-foot-transverse\",\n    /** Right foot ball */\n    RIGHT_FOOT_BALL = \"right-foot-ball\",\n}\n\n/**\n * The ordered array of all 83 body joints, matching the iteration order defined\n * by the WebXR Body Tracking specification.\n * @see https://immersive-web.github.io/body-tracking/#xrbody-interface\n */\nconst BodyJointReferenceArray: WebXRBodyJoint[] = [\n    // Torso / spine\n    WebXRBodyJoint.HIPS,\n    WebXRBodyJoint.SPINE_LOWER,\n    WebXRBodyJoint.SPINE_MIDDLE,\n    WebXRBodyJoint.SPINE_UPPER,\n    WebXRBodyJoint.CHEST,\n    WebXRBodyJoint.NECK,\n    WebXRBodyJoint.HEAD,\n\n    // Left arm\n    WebXRBodyJoint.LEFT_SHOULDER,\n    WebXRBodyJoint.LEFT_SCAPULA,\n    WebXRBodyJoint.LEFT_ARM_UPPER,\n    WebXRBodyJoint.LEFT_ARM_LOWER,\n    WebXRBodyJoint.LEFT_HAND_WRIST_TWIST,\n\n    // Right arm\n    WebXRBodyJoint.RIGHT_SHOULDER,\n    WebXRBodyJoint.RIGHT_SCAPULA,\n    WebXRBodyJoint.RIGHT_ARM_UPPER,\n    WebXRBodyJoint.RIGHT_ARM_LOWER,\n    WebXRBodyJoint.RIGHT_HAND_WRIST_TWIST,\n\n    // Left hand\n    WebXRBodyJoint.LEFT_HAND_PALM,\n    WebXRBodyJoint.LEFT_HAND_WRIST,\n    WebXRBodyJoint.LEFT_HAND_THUMB_METACARPAL,\n    WebXRBodyJoint.LEFT_HAND_THUMB_PHALANX_PROXIMAL,\n    WebXRBodyJoint.LEFT_HAND_THUMB_PHALANX_DISTAL,\n    WebXRBodyJoint.LEFT_HAND_THUMB_TIP,\n    WebXRBodyJoint.LEFT_HAND_INDEX_METACARPAL,\n    WebXRBodyJoint.LEFT_HAND_INDEX_PHALANX_PROXIMAL,\n    WebXRBodyJoint.LEFT_HAND_INDEX_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.LEFT_HAND_INDEX_PHALANX_DISTAL,\n    WebXRBodyJoint.LEFT_HAND_INDEX_TIP,\n    WebXRBodyJoint.LEFT_HAND_MIDDLE_METACARPAL,\n    WebXRBodyJoint.LEFT_HAND_MIDDLE_PHALANX_PROXIMAL,\n    WebXRBodyJoint.LEFT_HAND_MIDDLE_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.LEFT_HAND_MIDDLE_PHALANX_DISTAL,\n    WebXRBodyJoint.LEFT_HAND_MIDDLE_TIP,\n    WebXRBodyJoint.LEFT_HAND_RING_METACARPAL,\n    WebXRBodyJoint.LEFT_HAND_RING_PHALANX_PROXIMAL,\n    WebXRBodyJoint.LEFT_HAND_RING_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.LEFT_HAND_RING_PHALANX_DISTAL,\n    WebXRBodyJoint.LEFT_HAND_RING_TIP,\n    WebXRBodyJoint.LEFT_HAND_LITTLE_METACARPAL,\n    WebXRBodyJoint.LEFT_HAND_LITTLE_PHALANX_PROXIMAL,\n    WebXRBodyJoint.LEFT_HAND_LITTLE_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.LEFT_HAND_LITTLE_PHALANX_DISTAL,\n    WebXRBodyJoint.LEFT_HAND_LITTLE_TIP,\n\n    // Right hand\n    WebXRBodyJoint.RIGHT_HAND_PALM,\n    WebXRBodyJoint.RIGHT_HAND_WRIST,\n    WebXRBodyJoint.RIGHT_HAND_THUMB_METACARPAL,\n    WebXRBodyJoint.RIGHT_HAND_THUMB_PHALANX_PROXIMAL,\n    WebXRBodyJoint.RIGHT_HAND_THUMB_PHALANX_DISTAL,\n    WebXRBodyJoint.RIGHT_HAND_THUMB_TIP,\n    WebXRBodyJoint.RIGHT_HAND_INDEX_METACARPAL,\n    WebXRBodyJoint.RIGHT_HAND_INDEX_PHALANX_PROXIMAL,\n    WebXRBodyJoint.RIGHT_HAND_INDEX_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.RIGHT_HAND_INDEX_PHALANX_DISTAL,\n    WebXRBodyJoint.RIGHT_HAND_INDEX_TIP,\n    WebXRBodyJoint.RIGHT_HAND_MIDDLE_METACARPAL,\n    WebXRBodyJoint.RIGHT_HAND_MIDDLE_PHALANX_PROXIMAL,\n    WebXRBodyJoint.RIGHT_HAND_MIDDLE_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.RIGHT_HAND_MIDDLE_PHALANX_DISTAL,\n    WebXRBodyJoint.RIGHT_HAND_MIDDLE_TIP,\n    WebXRBodyJoint.RIGHT_HAND_RING_METACARPAL,\n    WebXRBodyJoint.RIGHT_HAND_RING_PHALANX_PROXIMAL,\n    WebXRBodyJoint.RIGHT_HAND_RING_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.RIGHT_HAND_RING_PHALANX_DISTAL,\n    WebXRBodyJoint.RIGHT_HAND_RING_TIP,\n    WebXRBodyJoint.RIGHT_HAND_LITTLE_METACARPAL,\n    WebXRBodyJoint.RIGHT_HAND_LITTLE_PHALANX_PROXIMAL,\n    WebXRBodyJoint.RIGHT_HAND_LITTLE_PHALANX_INTERMEDIATE,\n    WebXRBodyJoint.RIGHT_HAND_LITTLE_PHALANX_DISTAL,\n    WebXRBodyJoint.RIGHT_HAND_LITTLE_TIP,\n\n    // Left leg / foot\n    WebXRBodyJoint.LEFT_UPPER_LEG,\n    WebXRBodyJoint.LEFT_LOWER_LEG,\n    WebXRBodyJoint.LEFT_FOOT_ANKLE_TWIST,\n    WebXRBodyJoint.LEFT_FOOT_ANKLE,\n    WebXRBodyJoint.LEFT_FOOT_SUBTALAR,\n    WebXRBodyJoint.LEFT_FOOT_TRANSVERSE,\n    WebXRBodyJoint.LEFT_FOOT_BALL,\n\n    // Right leg / foot\n    WebXRBodyJoint.RIGHT_UPPER_LEG,\n    WebXRBodyJoint.RIGHT_LOWER_LEG,\n    WebXRBodyJoint.RIGHT_FOOT_ANKLE_TWIST,\n    WebXRBodyJoint.RIGHT_FOOT_ANKLE,\n    WebXRBodyJoint.RIGHT_FOOT_SUBTALAR,\n    WebXRBodyJoint.RIGHT_FOOT_TRANSVERSE,\n    WebXRBodyJoint.RIGHT_FOOT_BALL,\n];\n\n/**\n * Reverse lookup: {@link WebXRBodyJoint} → index in {@link BodyJointReferenceArray}.\n * Used for O(1) name-based access where previously `indexOf` was called in hot paths.\n */\nconst BodyJointNameToIndex: ReadonlyMap<WebXRBodyJoint, number> = /*#__PURE__*/ new Map<WebXRBodyJoint, number>(BodyJointReferenceArray.map((j, i) => [j, i]));\n\n/**\n * The total number of joints in the body tracking spec.\n * The XRBody size attribute MUST return this value.\n */\nconst BODY_JOINT_COUNT = 83;\n\n/**\n * Parent index for each joint in {@link BodyJointReferenceArray} order.\n * -1 means \"root\" (no parent).  Used to convert world-space XR poses to\n * local-space transforms suitable for skeleton bones.\n *\n * Hierarchy follows the WebXR Body Tracking specification and standard\n * humanoid anatomy.\n */\n// prettier-ignore\nexport const BodyJointParentIndex: number[] = [\n    //  0: hips (root)\n    -1,\n    //  1: spine-lower → hips\n    0,\n    //  2: spine-middle → spine-lower\n    1,\n    //  3: spine-upper → spine-middle\n    2,\n    //  4: chest → spine-upper\n    3,\n    //  5: neck → chest\n    4,\n    //  6: head → neck\n    5,\n\n    // Left arm (7-11)\n    4,   //  7: left-shoulder → chest\n    7,   //  8: left-scapula → left-shoulder\n    8,   //  9: left-arm-upper → left-scapula\n    9,   // 10: left-arm-lower → left-arm-upper\n    10,  // 11: left-hand-wrist-twist → left-arm-lower\n\n    // Right arm (12-16)\n    4,   // 12: right-shoulder → chest\n    12,  // 13: right-scapula → right-shoulder\n    13,  // 14: right-arm-upper → right-scapula\n    14,  // 15: right-arm-lower → right-arm-upper\n    15,  // 16: right-hand-wrist-twist → right-arm-lower\n\n    // Left hand (17-42)\n    11,  // 17: left-hand-palm → left-hand-wrist-twist\n    11,  // 18: left-hand-wrist → left-hand-wrist-twist\n    18,  // 19: left-hand-thumb-metacarpal → left-hand-wrist\n    19,  // 20: left-hand-thumb-phalanx-proximal\n    20,  // 21: left-hand-thumb-phalanx-distal\n    21,  // 22: left-hand-thumb-tip\n    18,  // 23: left-hand-index-metacarpal → left-hand-wrist\n    23,  // 24: left-hand-index-phalanx-proximal\n    24,  // 25: left-hand-index-phalanx-intermediate\n    25,  // 26: left-hand-index-phalanx-distal\n    26,  // 27: left-hand-index-tip\n    18,  // 28: left-hand-middle-metacarpal → left-hand-wrist\n    28,  // 29: left-hand-middle-phalanx-proximal\n    29,  // 30: left-hand-middle-phalanx-intermediate\n    30,  // 31: left-hand-middle-phalanx-distal\n    31,  // 32: left-hand-middle-tip\n    18,  // 33: left-hand-ring-metacarpal → left-hand-wrist\n    33,  // 34: left-hand-ring-phalanx-proximal\n    34,  // 35: left-hand-ring-phalanx-intermediate\n    35,  // 36: left-hand-ring-phalanx-distal\n    36,  // 37: left-hand-ring-tip\n    18,  // 38: left-hand-little-metacarpal → left-hand-wrist\n    38,  // 39: left-hand-little-phalanx-proximal\n    39,  // 40: left-hand-little-phalanx-intermediate\n    40,  // 41: left-hand-little-phalanx-distal\n    41,  // 42: left-hand-little-tip\n\n    // Right hand (43-68)\n    16,  // 43: right-hand-palm → right-hand-wrist-twist\n    16,  // 44: right-hand-wrist → right-hand-wrist-twist\n    44,  // 45: right-hand-thumb-metacarpal → right-hand-wrist\n    45,  // 46: right-hand-thumb-phalanx-proximal\n    46,  // 47: right-hand-thumb-phalanx-distal\n    47,  // 48: right-hand-thumb-tip\n    44,  // 49: right-hand-index-metacarpal → right-hand-wrist\n    49,  // 50: right-hand-index-phalanx-proximal\n    50,  // 51: right-hand-index-phalanx-intermediate\n    51,  // 52: right-hand-index-phalanx-distal\n    52,  // 53: right-hand-index-tip\n    44,  // 54: right-hand-middle-metacarpal → right-hand-wrist\n    54,  // 55: right-hand-middle-phalanx-proximal\n    55,  // 56: right-hand-middle-phalanx-intermediate\n    56,  // 57: right-hand-middle-phalanx-distal\n    57,  // 58: right-hand-middle-tip\n    44,  // 59: right-hand-ring-metacarpal → right-hand-wrist\n    59,  // 60: right-hand-ring-phalanx-proximal\n    60,  // 61: right-hand-ring-phalanx-intermediate\n    61,  // 62: right-hand-ring-phalanx-distal\n    62,  // 63: right-hand-ring-tip\n    44,  // 64: right-hand-little-metacarpal → right-hand-wrist\n    64,  // 65: right-hand-little-phalanx-proximal\n    65,  // 66: right-hand-little-phalanx-intermediate\n    66,  // 67: right-hand-little-phalanx-distal\n    67,  // 68: right-hand-little-tip\n\n    // Left leg / foot (69-75)\n    0,   // 69: left-upper-leg → hips\n    69,  // 70: left-lower-leg → left-upper-leg\n    70,  // 71: left-foot-ankle-twist → left-lower-leg\n    71,  // 72: left-foot-ankle → left-foot-ankle-twist\n    72,  // 73: left-foot-subtalar → left-foot-ankle\n    73,  // 74: left-foot-transverse → left-foot-subtalar\n    74,  // 75: left-foot-ball → left-foot-transverse\n\n    // Right leg / foot (76-82)\n    0,   // 76: right-upper-leg → hips\n    76,  // 77: right-lower-leg → right-upper-leg\n    77,  // 78: right-foot-ankle-twist → right-lower-leg\n    78,  // 79: right-foot-ankle → right-foot-ankle-twist\n    79,  // 80: right-foot-subtalar → right-foot-ankle\n    80,  // 81: right-foot-transverse → right-foot-subtalar\n    81,  // 82: right-foot-ball → right-foot-transverse\n];\n\n/**\n * Logical body parts for convenient grouping of joints.\n */\nexport const enum BodyPart {\n    /** Torso / spine (hips through head) */\n    TORSO = \"torso\",\n    /** Left arm (shoulder through wrist twist) */\n    LEFT_ARM = \"left-arm\",\n    /** Right arm (shoulder through wrist twist) */\n    RIGHT_ARM = \"right-arm\",\n    /** Left hand (palm through finger tips) */\n    LEFT_HAND = \"left-hand\",\n    /** Right hand (palm through finger tips) */\n    RIGHT_HAND = \"right-hand\",\n    /** Left leg (upper leg through foot ball) */\n    LEFT_LEG = \"left-leg\",\n    /** Right leg (upper leg through foot ball) */\n    RIGHT_LEG = \"right-leg\",\n}\n\n/**\n * Which body joints belong to each body part.\n */\nconst BodyPartsDefinition: { [key in BodyPart]: WebXRBodyJoint[] } = {\n    [BodyPart.TORSO]: [\n        WebXRBodyJoint.HIPS,\n        WebXRBodyJoint.SPINE_LOWER,\n        WebXRBodyJoint.SPINE_MIDDLE,\n        WebXRBodyJoint.SPINE_UPPER,\n        WebXRBodyJoint.CHEST,\n        WebXRBodyJoint.NECK,\n        WebXRBodyJoint.HEAD,\n    ],\n    [BodyPart.LEFT_ARM]: [\n        WebXRBodyJoint.LEFT_SHOULDER,\n        WebXRBodyJoint.LEFT_SCAPULA,\n        WebXRBodyJoint.LEFT_ARM_UPPER,\n        WebXRBodyJoint.LEFT_ARM_LOWER,\n        WebXRBodyJoint.LEFT_HAND_WRIST_TWIST,\n    ],\n    [BodyPart.RIGHT_ARM]: [\n        WebXRBodyJoint.RIGHT_SHOULDER,\n        WebXRBodyJoint.RIGHT_SCAPULA,\n        WebXRBodyJoint.RIGHT_ARM_UPPER,\n        WebXRBodyJoint.RIGHT_ARM_LOWER,\n        WebXRBodyJoint.RIGHT_HAND_WRIST_TWIST,\n    ],\n    [BodyPart.LEFT_HAND]: [\n        WebXRBodyJoint.LEFT_HAND_PALM,\n        WebXRBodyJoint.LEFT_HAND_WRIST,\n        WebXRBodyJoint.LEFT_HAND_THUMB_METACARPAL,\n        WebXRBodyJoint.LEFT_HAND_THUMB_PHALANX_PROXIMAL,\n        WebXRBodyJoint.LEFT_HAND_THUMB_PHALANX_DISTAL,\n        WebXRBodyJoint.LEFT_HAND_THUMB_TIP,\n        WebXRBodyJoint.LEFT_HAND_INDEX_METACARPAL,\n        WebXRBodyJoint.LEFT_HAND_INDEX_PHALANX_PROXIMAL,\n        WebXRBodyJoint.LEFT_HAND_INDEX_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.LEFT_HAND_INDEX_PHALANX_DISTAL,\n        WebXRBodyJoint.LEFT_HAND_INDEX_TIP,\n        WebXRBodyJoint.LEFT_HAND_MIDDLE_METACARPAL,\n        WebXRBodyJoint.LEFT_HAND_MIDDLE_PHALANX_PROXIMAL,\n        WebXRBodyJoint.LEFT_HAND_MIDDLE_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.LEFT_HAND_MIDDLE_PHALANX_DISTAL,\n        WebXRBodyJoint.LEFT_HAND_MIDDLE_TIP,\n        WebXRBodyJoint.LEFT_HAND_RING_METACARPAL,\n        WebXRBodyJoint.LEFT_HAND_RING_PHALANX_PROXIMAL,\n        WebXRBodyJoint.LEFT_HAND_RING_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.LEFT_HAND_RING_PHALANX_DISTAL,\n        WebXRBodyJoint.LEFT_HAND_RING_TIP,\n        WebXRBodyJoint.LEFT_HAND_LITTLE_METACARPAL,\n        WebXRBodyJoint.LEFT_HAND_LITTLE_PHALANX_PROXIMAL,\n        WebXRBodyJoint.LEFT_HAND_LITTLE_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.LEFT_HAND_LITTLE_PHALANX_DISTAL,\n        WebXRBodyJoint.LEFT_HAND_LITTLE_TIP,\n    ],\n    [BodyPart.RIGHT_HAND]: [\n        WebXRBodyJoint.RIGHT_HAND_PALM,\n        WebXRBodyJoint.RIGHT_HAND_WRIST,\n        WebXRBodyJoint.RIGHT_HAND_THUMB_METACARPAL,\n        WebXRBodyJoint.RIGHT_HAND_THUMB_PHALANX_PROXIMAL,\n        WebXRBodyJoint.RIGHT_HAND_THUMB_PHALANX_DISTAL,\n        WebXRBodyJoint.RIGHT_HAND_THUMB_TIP,\n        WebXRBodyJoint.RIGHT_HAND_INDEX_METACARPAL,\n        WebXRBodyJoint.RIGHT_HAND_INDEX_PHALANX_PROXIMAL,\n        WebXRBodyJoint.RIGHT_HAND_INDEX_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.RIGHT_HAND_INDEX_PHALANX_DISTAL,\n        WebXRBodyJoint.RIGHT_HAND_INDEX_TIP,\n        WebXRBodyJoint.RIGHT_HAND_MIDDLE_METACARPAL,\n        WebXRBodyJoint.RIGHT_HAND_MIDDLE_PHALANX_PROXIMAL,\n        WebXRBodyJoint.RIGHT_HAND_MIDDLE_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.RIGHT_HAND_MIDDLE_PHALANX_DISTAL,\n        WebXRBodyJoint.RIGHT_HAND_MIDDLE_TIP,\n        WebXRBodyJoint.RIGHT_HAND_RING_METACARPAL,\n        WebXRBodyJoint.RIGHT_HAND_RING_PHALANX_PROXIMAL,\n        WebXRBodyJoint.RIGHT_HAND_RING_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.RIGHT_HAND_RING_PHALANX_DISTAL,\n        WebXRBodyJoint.RIGHT_HAND_RING_TIP,\n        WebXRBodyJoint.RIGHT_HAND_LITTLE_METACARPAL,\n        WebXRBodyJoint.RIGHT_HAND_LITTLE_PHALANX_PROXIMAL,\n        WebXRBodyJoint.RIGHT_HAND_LITTLE_PHALANX_INTERMEDIATE,\n        WebXRBodyJoint.RIGHT_HAND_LITTLE_PHALANX_DISTAL,\n        WebXRBodyJoint.RIGHT_HAND_LITTLE_TIP,\n    ],\n    [BodyPart.LEFT_LEG]: [\n        WebXRBodyJoint.LEFT_UPPER_LEG,\n        WebXRBodyJoint.LEFT_LOWER_LEG,\n        WebXRBodyJoint.LEFT_FOOT_ANKLE_TWIST,\n        WebXRBodyJoint.LEFT_FOOT_ANKLE,\n        WebXRBodyJoint.LEFT_FOOT_SUBTALAR,\n        WebXRBodyJoint.LEFT_FOOT_TRANSVERSE,\n        WebXRBodyJoint.LEFT_FOOT_BALL,\n    ],\n    [BodyPart.RIGHT_LEG]: [\n        WebXRBodyJoint.RIGHT_UPPER_LEG,\n        WebXRBodyJoint.RIGHT_LOWER_LEG,\n        WebXRBodyJoint.RIGHT_FOOT_ANKLE_TWIST,\n        WebXRBodyJoint.RIGHT_FOOT_ANKLE,\n        WebXRBodyJoint.RIGHT_FOOT_SUBTALAR,\n        WebXRBodyJoint.RIGHT_FOOT_TRANSVERSE,\n        WebXRBodyJoint.RIGHT_FOOT_BALL,\n    ],\n};\n\n/**\n * A dictionary mapping each {@link WebXRBodyJoint} to a bone name in a rigged body mesh.\n *\n * When you supply a rigged mesh to {@link WebXRTrackedBody.setBodyMesh}, provide\n * a mapping so the feature knows which skeleton bone to drive for each joint.\n *\n * @example\n * ```typescript\n * const rigMapping: XRBodyMeshRigMapping = {\n *   \"hips\": \"Bip01_Pelvis\",\n *   \"spine-lower\": \"Bip01_Spine\",\n *   \"head\": \"Bip01_Head\",\n *   // …remaining joints…\n * };\n * ```\n */\nexport type XRBodyMeshRigMapping = { [jointName in WebXRBodyJoint]?: string };\n\n// ────────────────────────────────────────────────────────────────────────────\n// Configuration\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Configuration options for the WebXR body tracking feature.\n */\nexport interface IWebXRBodyTrackingOptions {\n    /**\n     * A pre-existing rigged body mesh to drive with tracked joint poses.\n     * If provided, skeleton bones will be linked to tracked joints automatically.\n     * The mesh should contain a skeleton whose bones can be mapped via `rigMapping`.\n     */\n    bodyMesh?: AbstractMesh;\n\n    /**\n     * A mapping from {@link WebXRBodyJoint} names to skeleton bone names.\n     * Required when the skeleton's bone names do not match the WebXR joint names.\n     * If omitted and a body mesh is provided, the feature assumes bones are\n     * named identically to the WebXR joint names (e.g. `\"hips\"`, `\"left-arm-upper\"`, etc.).\n     */\n    rigMapping?: XRBodyMeshRigMapping;\n\n    /**\n     * Scale factor applied to the local-space position of every joint.\n     *\n     * This uniformly scales the distances between parent and child joints,\n     * allowing you to fit XR body tracking data to meshes that are larger or\n     * smaller than the tracked user.\n     *\n     * - `1.0` (default): no scaling — real-world proportions.\n     * - `> 1.0`: stretches the skeleton (makes it taller / wider).\n     * - `< 1.0`: compresses the skeleton.\n     *\n     * Only affects local joint offsets, not the root (hips) position.\n     */\n    jointScaleFactor?: number;\n\n    /**\n     * Preserve bind-pose local translations for mapped bones and only retarget rotations.\n     *\n     * When `false` (default), mapped bones are translated directly to the tracked joint\n     * positions. This reproduces the tracked skeleton exactly, but can distort avatars whose\n     * proportions differ from the tracked user.\n     *\n     * When `true`, mapped child bones keep their bind-pose local translation offsets while\n     * still using the tracked joint rotations. This is the typical retargeting mode for\n     * driving arbitrary skinned characters without forcing them to the tracked skeleton's\n     * segment lengths.\n     */\n    preserveBindPoseBonePositions?: boolean;\n\n    /**\n     * Apply a per-bone orientation offset so the avatar bone basis matches the XR joint basis.\n     *\n     * When enabled, WebXR joint rotations are corrected using the bone's bind-space child axis.\n     * This is useful for rigs whose bone local axes do not match the anatomical axes used by\n     * the WebXR body-tracking joint orientations.\n     */\n    useBoneOrientationOffsets?: boolean;\n\n    /**\n     * Rotation applied in each tracked joint's local frame to re-base the\n     * XR joint axes. Some runtimes (e.g., some Meta Quest builds) emit body\n     * joint poses whose +Z axis points along the bone (parent → child), while\n     * most avatar rigs expect +Y along the bone. Setting this to\n     * `Quaternion.RotationAxis(Vector3.Right(), -Math.PI / 2)` converts\n     * \"+Z-along-bone\" joint data to \"+Y-along-bone\" before retargeting.\n     *\n     * Applied as a pre-multiply on each joint's world matrix:\n     * `M' = R × M`, which, under Babylon's row-vector convention\n     * (`v_world = v_local × M`), effectively re-bases the joint-local axes.\n     *\n     * Default `undefined` = identity (no re-basing).\n     */\n    jointLocalRotationOffset?: Quaternion;\n\n    /**\n     * Per–XR-joint override for the \"aim child\" joint used when\n     * {@link useBoneOrientationOffsets} is enabled.\n     *\n     * By default the aim direction for a mapped bone is computed against its\n     * nearest mapped descendant in the skeleton. For rigs whose XR-mapped\n     * spine chain has very short segments (e.g. WebXR's `hips`→`spine-lower`\n     * is typically only ~1 cm), the aim direction becomes noise-dominated and\n     * can produce a large incorrect rotation for the parent bone.\n     *\n     * Use this map to redirect a specific XR joint's aim target to a farther\n     * XR joint whose relative position is stable. Both the source and target\n     * joint must be present in {@link rigMapping} (i.e. mapped to a bone on the\n     * skeleton).\n     *\n     * Example for a Mixamo-style rig where hips, spine, spine1, spine2 and\n     * neck are all mapped:\n     * ```ts\n     * aimChildOverrides: {\n     *   [WebXRBodyJoint.HIPS]: WebXRBodyJoint.SPINE_UPPER,   // skip spine-lower/middle\n     *   [WebXRBodyJoint.SPINE_LOWER]: WebXRBodyJoint.NECK,   // long stable segment\n     *   [WebXRBodyJoint.SPINE_MIDDLE]: WebXRBodyJoint.NECK,\n     * }\n     * ```\n     */\n    aimChildOverrides?: Partial<Record<WebXRBodyJoint, WebXRBodyJoint>>;\n\n    /**\n     * Convenience flag for Mixamo-rigged characters.\n     *\n     * When set to `true`, the feature automatically applies:\n     * - {@link MixamoRigMapping} as the `rigMapping` (skipping any explicit\n     *   `rigMapping` you provide).\n     * - {@link MixamoAimChildOverrides} as `aimChildOverrides` (skipping any\n     *   explicit `aimChildOverrides` you provide).\n     * - Turns on {@link useBoneOrientationOffsets} by default (you can still\n     *   override to `false`).\n     *\n     * The Mixamo `mixamorig:` bone-name prefix is detected automatically by\n     * inspecting the skeleton, so the same mapping works regardless of whether\n     * the bones have been renamed to strip the prefix (common when re-exporting).\n     */\n    isMixamoModel?: boolean;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// Built-in rig mappings\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Default rig mapping for Mixamo-rigged humanoid characters.\n *\n * Maps each supported {@link WebXRBodyJoint} to the corresponding Mixamo bone\n * name, **without** the `mixamorig:` prefix. When the feature applies this\n * mapping, it auto-detects whether the skeleton uses the `mixamorig:` prefix\n * and prepends it as needed, so the same table works for both prefixed and\n * unprefixed exports.\n *\n * @example\n * ```ts\n * xr.featuresManager.enableFeature(WebXRFeatureName.BODY_TRACKING, \"latest\", {\n *     bodyMesh: myMixamoMesh,\n *     isMixamoModel: true,\n * });\n * ```\n *\n * Or, if you want to extend or customize it:\n * ```ts\n * import { MixamoRigMapping } from \"@babylonjs/core\";\n * const rigMapping: XRBodyMeshRigMapping = { ...MixamoRigMapping, [WebXRBodyJoint.NECK]: \"MyNeckBone\" };\n * ```\n */\nexport const MixamoRigMapping: XRBodyMeshRigMapping = {\n    [WebXRBodyJoint.HIPS]: \"Hips\",\n    [WebXRBodyJoint.SPINE_LOWER]: \"Spine\",\n    [WebXRBodyJoint.SPINE_MIDDLE]: \"Spine1\",\n    [WebXRBodyJoint.SPINE_UPPER]: \"Spine2\",\n    [WebXRBodyJoint.NECK]: \"Neck\",\n    [WebXRBodyJoint.HEAD]: \"Head\",\n\n    [WebXRBodyJoint.LEFT_SHOULDER]: \"LeftShoulder\",\n    [WebXRBodyJoint.LEFT_ARM_UPPER]: \"LeftArm\",\n    [WebXRBodyJoint.LEFT_ARM_LOWER]: \"LeftForeArm\",\n    [WebXRBodyJoint.LEFT_HAND_WRIST]: \"LeftHand\",\n\n    [WebXRBodyJoint.RIGHT_SHOULDER]: \"RightShoulder\",\n    [WebXRBodyJoint.RIGHT_ARM_UPPER]: \"RightArm\",\n    [WebXRBodyJoint.RIGHT_ARM_LOWER]: \"RightForeArm\",\n    [WebXRBodyJoint.RIGHT_HAND_WRIST]: \"RightHand\",\n\n    [WebXRBodyJoint.LEFT_UPPER_LEG]: \"LeftUpLeg\",\n    [WebXRBodyJoint.LEFT_LOWER_LEG]: \"LeftLeg\",\n    [WebXRBodyJoint.LEFT_FOOT_ANKLE]: \"LeftFoot\",\n    [WebXRBodyJoint.LEFT_FOOT_BALL]: \"LeftToeBase\",\n\n    [WebXRBodyJoint.RIGHT_UPPER_LEG]: \"RightUpLeg\",\n    [WebXRBodyJoint.RIGHT_LOWER_LEG]: \"RightLeg\",\n    [WebXRBodyJoint.RIGHT_FOOT_ANKLE]: \"RightFoot\",\n    [WebXRBodyJoint.RIGHT_FOOT_BALL]: \"RightToeBase\",\n};\n\n/**\n * Default aim-child overrides for Mixamo-rigged humanoids.\n *\n * Redirects the short / noisy XR spine segments to longer, stable ones so that\n * {@link IWebXRBodyTrackingOptions.useBoneOrientationOffsets} produces clean\n * torso rotations. In WebXR data, `hips`→`spine-lower` is typically only ~1 cm\n * apart — too short to give a stable aim direction — so we reroute Mixamo's\n * Hips/Spine/Spine1 bones to aim at `spine-upper` / `neck` instead.\n */\nexport const MixamoAimChildOverrides: Partial<Record<WebXRBodyJoint, WebXRBodyJoint>> = {\n    [WebXRBodyJoint.HIPS]: WebXRBodyJoint.SPINE_UPPER,\n    [WebXRBodyJoint.SPINE_LOWER]: WebXRBodyJoint.NECK,\n    [WebXRBodyJoint.SPINE_MIDDLE]: WebXRBodyJoint.NECK,\n    // Hands have no mapped finger descendants on a typical Mixamo rig. Aim\n    // them at the tracked Middle-finger metacarpal joint to give the wrist\n    // a real orientation reference instead of relying on Meta's raw wrist\n    // rotation (which tends to flop around when the cameras can't resolve\n    // the hand pose).\n    [WebXRBodyJoint.LEFT_HAND_WRIST]: WebXRBodyJoint.LEFT_HAND_MIDDLE_METACARPAL,\n    [WebXRBodyJoint.RIGHT_HAND_WRIST]: WebXRBodyJoint.RIGHT_HAND_MIDDLE_METACARPAL,\n};\n\nconst HandTwistReferenceJoints: Partial<Record<WebXRBodyJoint, { first: WebXRBodyJoint; second: WebXRBodyJoint }>> = {\n    [WebXRBodyJoint.LEFT_HAND_WRIST]: {\n        first: WebXRBodyJoint.LEFT_HAND_INDEX_METACARPAL,\n        second: WebXRBodyJoint.LEFT_HAND_LITTLE_METACARPAL,\n    },\n    [WebXRBodyJoint.RIGHT_HAND_WRIST]: {\n        first: WebXRBodyJoint.RIGHT_HAND_INDEX_METACARPAL,\n        second: WebXRBodyJoint.RIGHT_HAND_LITTLE_METACARPAL,\n    },\n};\n\n/**\n * Resolve the Mixamo rig mapping for a given body mesh, auto-detecting the\n * `mixamorig:` bone-name prefix. Falls back to the unprefixed names.\n * @param bodyMesh The rigged Mixamo body mesh.\n * @returns An {@link XRBodyMeshRigMapping} whose bone names include the\n *          detected prefix (if any).\n * @internal\n */\nexport function _ResolveMixamoRigMapping(bodyMesh: AbstractMesh): XRBodyMeshRigMapping {\n    let skeleton = bodyMesh.skeleton;\n    if (!skeleton) {\n        for (const child of bodyMesh.getChildMeshes()) {\n            if (child.skeleton) {\n                skeleton = child.skeleton;\n                break;\n            }\n        }\n    }\n    let prefix = \"\";\n    if (skeleton) {\n        // Look for the Hips bone to determine whether bones use the mixamorig: prefix.\n        if (skeleton.getBoneIndexByName(\"mixamorig:Hips\") !== -1) {\n            prefix = \"mixamorig:\";\n        } else if (skeleton.getBoneIndexByName(\"Hips\") === -1) {\n            // Neither prefixed nor unprefixed Hips was found — try to auto-detect\n            // the prefix by scanning bone names.\n            for (const b of skeleton.bones) {\n                const match = /^(.*?)Hips$/.exec(b.name);\n                if (match) {\n                    prefix = match[1];\n                    break;\n                }\n            }\n        }\n    }\n    if (!prefix) {\n        return MixamoRigMapping;\n    }\n    const resolved: XRBodyMeshRigMapping = {};\n    for (const key of Object.keys(MixamoRigMapping) as WebXRBodyJoint[]) {\n        resolved[key] = prefix + MixamoRigMapping[key]!;\n    }\n    return resolved;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// WebXRTrackedBody — runtime representation of a tracked body\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * Represents a tracked body during a WebXR session.\n *\n * This class manages the bridge between the WebXR body pose data and the\n * Babylon.js scene graph.  It creates a set of {@link TransformNode}s — one per\n * body joint — whose transforms are updated every frame from the XR runtime.\n * When a rigged body mesh is attached, its skeleton bones are linked to these\n * transform nodes, causing the mesh to follow the user's body automatically.\n *\n * Coordinate-system handling:\n * - WebXR delivers poses in a right-handed system.\n * - By default, Babylon.js uses a left-handed system.\n * - The class converts the data in-place (negating the Z components of every\n *   4 × 4 joint matrix) before decomposing into Babylon transforms.\n * - If the mesh was authored in a right-handed tool (the common case for glTF),\n *   the bone transforms are un-flipped so the skeleton interprets them correctly.\n */\nexport class WebXRTrackedBody implements IDisposable {\n    /**\n     * Fired when the body mesh is changed via {@link setBodyMesh}.\n     */\n    public readonly onBodyMeshSetObservable = new Observable<WebXRTrackedBody>();\n\n    private _scene: Scene;\n\n    /**\n     * One {@link TransformNode} per joint.  These receive the WebXR matrix data\n     * every frame and serve as link targets for skeleton bones.\n     */\n    private _jointTransforms = new Array<TransformNode>(BODY_JOINT_COUNT);\n\n    /**\n     * Flat Float32Array that receives transform matrices directly from the\n     * WebXR API (via `fillPoses`). 16 floats per joint × 83 joints = 1 328 floats.\n     */\n    private _jointTransformMatrices = new Float32Array(BODY_JOINT_COUNT * 16);\n\n    /**\n     * Copy of the raw RHS XR matrices (before LHS conversion).\n     * Used to compute bone-local transforms for glTF skeletons that\n     * operate in RHS space.\n     */\n    private _jointTransformMatricesRHS = new Float32Array(BODY_JOINT_COUNT * 16);\n\n    /**\n     * Cached array of XRBodySpace objects extracted from the XRBody, kept in the\n     * same order as {@link BodyJointReferenceArray}.\n     */\n    private _jointSpaces: (XRBodySpace | undefined)[] = new Array(BODY_JOINT_COUNT);\n\n    /** Temporary matrix: this joint's XR world-space matrix. */\n    private _tempJointMatrix = new Matrix();\n\n    /** Temporary matrix: parent joint's XR world-space matrix. */\n    private _tempParentMatrix = new Matrix();\n\n    /** Temporary matrix: computed bone-local matrix. */\n    private _tempLocalMatrix = new Matrix();\n\n    /** Temporary vector for scale extracted from decompose. */\n    private _tempScaleVector = new Vector3();\n\n    /** Temporary quaternion for decompose. */\n    private _tempRotQuat = new Quaternion();\n\n    /** Temporary position vector for decompose. */\n    private _tempPosVec = new Vector3();\n\n    /** Temporary quaternion for alternate rotation calculations. */\n    private _tempRotQuat2 = new Quaternion();\n\n    /** Temporary vector for desired child direction. */\n    private _tempDirection = new Vector3();\n\n    /** Temporary vector for joint-local child direction. */\n    private _tempLocalDirection = new Vector3();\n\n    /** Cached desired final positions for mapped joints. */\n    private _desiredFinalPositions = Array.from({ length: BODY_JOINT_COUNT }, () => new Vector3());\n\n    /**\n     * For each joint index, the joint index of the nearest mapped SKELETON\n     * ancestor bone.  -1 when the bone has no mapped ancestor (root level).\n     * Precomputed in {@link setBodyMesh} by walking the skeleton hierarchy.\n     */\n    private _jointParentJointIdx: number[] = new Array(BODY_JOINT_COUNT).fill(-1);\n\n    /** Tracks which joint indices have a linked bone (for step 4b). */\n    private _jointHasBone: boolean[] = new Array(BODY_JOINT_COUNT).fill(false);\n\n    /** Bone → XR joint index lookup, built in {@link setBodyMesh}. */\n    private _boneToJointIdx = new Map<Bone, number>();\n\n    /** Original bind-pose local matrices for mapped bones. */\n    private _mappedBoneBindLocals = new Map<Bone, Matrix>();\n\n    /** Nearest mapped child bone for each mapped bone. */\n    private _mappedChildBones = new Map<Bone, Bone>();\n\n    /** Bind-space local child direction for each mapped bone. */\n    private _bindLocalAimDirections = new Map<Bone, Vector3>();\n\n    /** Bind-space local hand-plane normal used to correct wrist/hand twist from tracked finger positions. */\n    private _bindLocalTwistNormals = new Map<Bone, Vector3>();\n\n    /**\n     * XR joint index to aim each mapped bone at. This can be a mapped joint\n     * (same as `_boneToJointIdx.get(aimChildBone)`) or an **unmapped** XR\n     * joint whose tracked position is nonetheless useful for aim correction —\n     * e.g. `LEFT_HAND_MIDDLE_METACARPAL` for `mixamorig:LeftHand`, which has\n     * no mapped finger descendant but whose tracked position still defines\n     * \"where the hand is pointing\".\n     */\n    private _boneAimTargetJointIdx = new Map<Bone, number>();\n\n    /** Per-bone pair of tracked joints that define the hand plane used for twist correction. */\n    private _boneTwistReferenceJointIdx = new Map<Bone, { first: number; second: number }>();\n\n    /**\n     * Per-mapped-bone bind-pose world rotation in mesh-local space\n     * (decomposed from `bone.getFinalMatrix()` at bind time). Used by the\n     * delta-from-bind retarget path (axis-convention-invariant).\n     */\n    private _bindBoneWorldRotMeshLocal = new Map<Bone, Quaternion>();\n\n    /**\n     * Bind-pose tracked joint rotation in mesh-local space per mapped joint.\n     * Captured on the first tracked frame (or on demand via\n     * {@link captureTrackedBind}). `null` until captured.\n     */\n    private _trackedBindDesiredFinalRot: Nullable<Quaternion[]> = null;\n\n    /** Bind-pose tracked joint position (mesh-local), captured alongside rotation. */\n    private _trackedBindDesiredFinalPos: Nullable<Vector3[]> = null;\n\n    /** True once a tracked-bind snapshot has been taken. */\n    private _hasTrackedBind = false;\n\n    /**\n     * When `true` (default), the first tracked frame after the feature\n     * attaches is used as the \"rest\" pose for delta-from-bind retargeting.\n     * Set to `false` to require an explicit {@link captureTrackedBind} call.\n     */\n    public autoCaptureBindOnFirstFrame = true;\n\n    /** Scratch quaternion for retarget delta composition. */\n    private _tempDeltaQuat = new Quaternion();\n    private _tempBoneWorldRot = new Quaternion();\n    private _tempParentNewWorldRotInv = new Quaternion();\n    private _tempTrackedCurRot = new Quaternion();\n    private _tempTrackedCurPos = new Vector3();\n    private _tempBindLocalScale = new Vector3();\n    private _tempBindLocalPos = new Vector3();\n    /**\n     * Per-bone cache of the current frame's computed world rotation.\n     * Entries are pooled across frames (values are reused via `copyFrom`)\n     * to avoid allocating a fresh Quaternion per mapped bone per frame.\n     * A bone is considered \"populated this frame\" iff it has been visited\n     * by the current retarget pass (tracked via `_computedBoneNewWorldRotFrameId`).\n     */\n    private _computedBoneNewWorldRot = new Map<Bone, Quaternion>();\n    /** Per-bone marker: frame id at which the pooled rotation above was last set. */\n    private _computedBoneNewWorldRotFrameId = new Map<Bone, number>();\n    private _currentRetargetFrameId = 0;\n    /** Scratch quaternion reused for the parent-world accumulation loop. */\n    private _tempParentAccumRot = new Quaternion();\n    /** Scratch quaternion reused for the parent-world intermediate product. */\n    private _tempParentAccumTmp = new Quaternion();\n\n    /** Scratch vectors reused by hand twist correction. */\n    private _tempTwistFirst = new Vector3();\n    private _tempTwistSecond = new Vector3();\n    private _tempTwistNormal = new Vector3();\n    private _tempCurrentTwistNormal = new Vector3();\n    private _tempProjectedTwistNormal = new Vector3();\n    private _tempProjectedDesiredTwistNormal = new Vector3();\n    private _tempTwistAimAxis = new Vector3();\n    private _tempTwistCross = new Vector3();\n\n    /** The skeleton reference for iterating bones in parent-first order. */\n    private _skeleton: Nullable<import(\"../../Bones/skeleton\").Skeleton> = null;\n\n    /** Cached inverse of the skeleton mesh's world matrix. */\n    private _meshWorldMatrixInverse = new Matrix();\n\n    /** Cached inverse of the skeleton mesh pose matrix when initial skinning is used. */\n    private _initialSkinMatrixInverse = new Matrix();\n\n    /**\n     * Pre-allocated desiredFinal matrices (one per joint slot).\n     * `desiredFinal[i] = strip(xrWorld[i] × inv(meshWorld))` — the bone's\n     * target skeleton-space final matrix with parasitic scale removed.\n     */\n    private _desiredFinals: Matrix[] = [];\n\n    /**\n     * Standalone TransformNodes created for unmapped skinned bones.\n     * These TNs are initialized to the bone's bind-pose local and linked\n     * so that `prepare()` reads deterministic values rather than the\n     * original glTF scene-graph TNs (which we don't control).\n     */\n    private _unmappedBoneNodes: { bone: Bone; standaloneNode: TransformNode }[] = [];\n\n    /** The mesh that owns the skeleton (used for world-matrix inverse). */\n    private _skeletonMesh: Nullable<AbstractMesh> = null;\n\n    /** The body mesh root (topmost parent), used to parent the mesh to the camera. */\n    private _bodyMeshRoot: Nullable<Node> = null;\n\n    /** The rigged body mesh, if any. */\n    private _bodyMesh: Nullable<AbstractMesh> = null;\n\n    /** Scale factor for local joint offsets. */\n    private _jointScaleFactor: number;\n\n    /** Whether mapped bones should keep their bind-pose local translations. */\n    private readonly _preserveBindPoseBonePositions: boolean;\n\n    /** Whether mapped bones should correct WebXR joint rotations using bind-space orientation offsets. */\n    private readonly _useBoneOrientationOffsets: boolean;\n\n    /** Per–XR-joint override mapping for aim children (used with _useBoneOrientationOffsets). */\n    private _aimChildOverrides: Partial<Record<WebXRBodyJoint, WebXRBodyJoint>> | undefined;\n\n    /**\n     * Runtime-mutable rotation applied in each tracked joint's local frame to\n     * re-base XR joint axes (e.g., \"+Z-along-bone\" → \"+Y-along-bone\").\n     * `null` = identity / disabled.\n     */\n    public jointLocalRotationOffset: Nullable<Quaternion> = null;\n\n    /** Cached 4×4 matrix form of {@link jointLocalRotationOffset} for the fast path. */\n    private _jointLocalRotationOffsetMatrix = new Matrix();\n\n    /** Temporary matrix used when applying {@link jointLocalRotationOffset}. */\n    private _tempOffsetAppliedMatrix = new Matrix();\n\n    /**\n     * When true, bypass skeleton.prepare() and write skin matrices directly.\n     * This is a diagnostic flag to help isolate rendering issues. When the\n     * standard pipeline (TN → bone → prepare → skin matrices) produces\n     * unexpected results, enabling this writes `absInvBind × final` directly\n     * into the skeleton's transform matrix buffer.\n     * @internal\n     */\n    public _directSkinWrite = false;\n\n    /**\n     * Debug info string from the last `updateFromXRFrame` call.\n     * Useful for diagnosing tracking failures on-device.\n     * @internal\n     */\n    public _lastDebugInfo: string = \"TB:not called\";\n\n    /**\n     * Get the current body mesh (if any).\n     */\n    public get bodyMesh(): Nullable<AbstractMesh> {\n        return this._bodyMesh;\n    }\n\n    /**\n     * Get or set the scale factor for local joint offsets.\n     * @see {@link IWebXRBodyTrackingOptions.jointScaleFactor}\n     */\n    public get jointScaleFactor(): number {\n        return this._jointScaleFactor;\n    }\n\n    public set jointScaleFactor(value: number) {\n        this._jointScaleFactor = value;\n    }\n\n    /**\n     * Returns the array of transform nodes representing each body joint.\n     * The order matches {@link WebXRBodyTracking.AllBodyJoints}; use\n     * {@link getJointTransform} or {@link getBodyPartTransforms} for\n     * name-based lookup.\n     *\n     * Note: when a body mesh is attached, these transform nodes are also\n     * used as the skeleton's link targets for mapped joints. In that case\n     * the values held by mapped-joint nodes are skeleton-local (parent bone's\n     * frame), not XR world-space. Unmapped-joint nodes always hold world-space\n     * pose. If you need world-space poses for every joint regardless of\n     * mapping, sample the bone matrices directly via the attached skeleton.\n     */\n    public get jointTransforms(): readonly TransformNode[] {\n        return this._jointTransforms;\n    }\n\n    /**\n     * Get the transform node for a specific body joint.\n     * @param jointName The name of the body joint (from {@link WebXRBodyJoint}).\n     * @returns The transform node corresponding to that joint, or `undefined` if not found.\n     */\n    public getJointTransform(jointName: WebXRBodyJoint): TransformNode | undefined {\n        const idx = BodyJointNameToIndex.get(jointName);\n        return idx !== undefined ? this._jointTransforms[idx] : undefined;\n    }\n\n    /**\n     * Get all joint transform nodes that belong to a given body part.\n     * @param part The body part to query.\n     * @param result Optional pre-allocated array to fill (avoids per-call allocation).\n     *   The array is cleared and populated with the results.\n     * @returns An array of TransformNodes for that body part.\n     */\n    public getBodyPartTransforms(part: BodyPart, result?: TransformNode[]): TransformNode[] {\n        const joints = BodyPartsDefinition[part];\n        if (!result) {\n            result = new Array<TransformNode>(joints.length);\n        } else {\n            result.length = joints.length;\n        }\n        for (let i = 0; i < joints.length; i++) {\n            result[i] = this._jointTransforms[BodyJointNameToIndex.get(joints[i])!];\n        }\n        return result;\n    }\n\n    /**\n     * Construct a new tracked body instance.\n     * @param scene The Babylon.js scene.\n     * @param bodyMesh Optional rigged body mesh to attach immediately.\n     * @param rigMapping Optional mapping from WebXR joint names to skeleton bone names.\n     * @param jointScaleFactor Scale factor for local joint offsets (default 1.0).\n     * @param preserveBindPoseBonePositions Whether mapped bones should keep bind-pose local translations.\n     * @param useBoneOrientationOffsets Whether mapped bones should correct XR joint rotations using bind-space offsets.\n     * @param aimChildOverrides Per–XR-joint override for the aim child used with `useBoneOrientationOffsets`.\n     * @param jointLocalRotationOffset Optional rotation re-basing each XR joint's local frame (e.g. Z-along-bone → Y-along-bone).\n     */\n    constructor(\n        scene: Scene,\n        bodyMesh?: AbstractMesh,\n        rigMapping?: XRBodyMeshRigMapping,\n        jointScaleFactor: number = 1.0,\n        preserveBindPoseBonePositions: boolean = false,\n        useBoneOrientationOffsets: boolean = false,\n        aimChildOverrides?: Partial<Record<WebXRBodyJoint, WebXRBodyJoint>>,\n        jointLocalRotationOffset?: Quaternion\n    ) {\n        this._scene = scene;\n        this._jointScaleFactor = jointScaleFactor;\n        this._preserveBindPoseBonePositions = preserveBindPoseBonePositions;\n        this._useBoneOrientationOffsets = useBoneOrientationOffsets;\n        this._aimChildOverrides = aimChildOverrides;\n        if (jointLocalRotationOffset) {\n            this.jointLocalRotationOffset = jointLocalRotationOffset.clone();\n        }\n\n        // Initialize a TransformNode for every body joint.\n        for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n            this._jointTransforms[i] = new TransformNode(BodyJointReferenceArray[i], this._scene);\n            this._jointTransforms[i].rotationQuaternion = new Quaternion();\n        }\n\n        if (bodyMesh) {\n            this.setBodyMesh(bodyMesh, rigMapping);\n        }\n    }\n\n    /**\n     * Attach (or replace) a rigged body mesh.\n     *\n     * The mesh's skeleton bones are linked to the internal transform nodes\n     * that receive WebXR tracking data each frame.  If the mesh has a skeleton,\n     * the `rigMapping` (or a direct name match) is used to bind each bone.\n     *\n     * @param bodyMesh The rigged mesh to drive.\n     * @param rigMapping An optional mapping from {@link WebXRBodyJoint} to bone name.\n     *   If omitted, bones are expected to be named after the WebXR joint names.\n     */\n    public setBodyMesh(bodyMesh: AbstractMesh, rigMapping?: XRBodyMeshRigMapping): void {\n        this._bodyMesh = bodyMesh;\n\n        // Walk up to find the mesh root for parenting.\n        this._bodyMeshRoot = this._bodyMesh;\n        while (this._bodyMeshRoot.parent) {\n            this._bodyMeshRoot = this._bodyMeshRoot.parent;\n        }\n\n        // Disable frustum culling on the body mesh and its children so\n        // the mesh is never culled while the user is in XR.\n        bodyMesh.alwaysSelectAsActiveMesh = true;\n        for (const child of bodyMesh.getChildMeshes()) {\n            child.alwaysSelectAsActiveMesh = true;\n        }\n\n        // Bind skeleton bones via linkTransformNode so that skeleton.prepare()\n        // copies TransformNode data → bone local at the correct time (after\n        // animations, before final matrix computation).\n        // We also precompute which joints have bones and their nearest mapped\n        // skeleton ancestor so we can write bone-local data onto the nodes.\n        this._jointHasBone.fill(false);\n        this._jointParentJointIdx.fill(-1);\n        this._boneToJointIdx.clear();\n        this._mappedBoneBindLocals.clear();\n        this._mappedChildBones.clear();\n        this._bindLocalAimDirections.clear();\n        this._bindLocalTwistNormals.clear();\n        this._boneAimTargetJointIdx.clear();\n        this._boneTwistReferenceJointIdx.clear();\n        this._bindBoneWorldRotMeshLocal.clear();\n        this._computedBoneNewWorldRot.clear();\n        this._computedBoneNewWorldRotFrameId.clear();\n        this._trackedBindDesiredFinalRot = null;\n        this._trackedBindDesiredFinalPos = null;\n        this._hasTrackedBind = false;\n        this._skeleton = null;\n        for (const { standaloneNode } of this._unmappedBoneNodes) {\n            standaloneNode.dispose();\n        }\n        this._unmappedBoneNodes = [];\n        this._skeletonMesh = null;\n        let skeleton = this._bodyMesh.skeleton;\n        let skeletonMesh: AbstractMesh | null = this._bodyMesh.skeleton ? this._bodyMesh : null;\n        if (!skeleton) {\n            for (const child of this._bodyMesh.getChildMeshes()) {\n                if (child.skeleton) {\n                    skeleton = child.skeleton;\n                    skeletonMesh = child;\n                    break;\n                }\n            }\n        }\n        if (skeleton) {\n            this._skeletonMesh = skeletonMesh;\n            this._skeleton = skeleton;\n\n            skeleton.prepare(true);\n            const bindPoseFinals = new Map<Bone, Matrix>();\n            for (const bone of skeleton.bones) {\n                bindPoseFinals.set(bone, bone.getFinalMatrix().clone());\n            }\n\n            // Step A: link transform nodes to bones\n            for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                const jointName = BodyJointReferenceArray[i];\n                const boneName = rigMapping ? rigMapping[jointName] : jointName;\n                if (!boneName) {\n                    continue;\n                }\n                const boneIdx = skeleton.getBoneIndexByName(boneName);\n                if (boneIdx !== -1) {\n                    const bone = skeleton.bones[boneIdx];\n                    // Initialize the joint's TransformNode to the bone's current\n                    // (bind-pose) local transform BEFORE linking, so the mesh\n                    // stays in its bind pose until the first XR frame arrives.\n                    // Without this the TN defaults (identity rotation, zero\n                    // position, unit scale) would be copied into the bone's\n                    // local on the next skeleton.prepare() and collapse the mesh.\n                    const jointTransform = this._jointTransforms[i];\n                    bone.getLocalMatrix().decompose(jointTransform.scaling, jointTransform.rotationQuaternion!, jointTransform.position);\n                    bone.linkTransformNode(jointTransform);\n                    this._jointHasBone[i] = true;\n                    this._boneToJointIdx.set(bone, i);\n                    this._mappedBoneBindLocals.set(bone, bone.getLocalMatrix().clone());\n                }\n            }\n\n            const findMappedChildBone = (bone: Bone): Bone | null => {\n                for (const child of bone.children) {\n                    if (this._boneToJointIdx.has(child)) {\n                        return child;\n                    }\n                    const descendant = findMappedChildBone(child);\n                    if (descendant) {\n                        return descendant;\n                    }\n                }\n                return null;\n            };\n\n            const bindWorldPositions = new Map<Bone, Vector3>();\n            const bindWorldRotations = new Map<Bone, Quaternion>();\n\n            for (const bone of skeleton.bones) {\n                const bindFinal = bindPoseFinals.get(bone);\n                if (!bindFinal) {\n                    continue;\n                }\n                bindFinal.decompose(this._tempScaleVector, this._tempRotQuat, this._tempPosVec);\n                bindWorldPositions.set(bone, this._tempPosVec.clone());\n                bindWorldRotations.set(bone, this._tempRotQuat.clone());\n                // Persist bone bind-pose world rotation for delta-from-bind retarget.\n                if (this._boneToJointIdx.has(bone)) {\n                    this._bindBoneWorldRotMeshLocal.set(bone, this._tempRotQuat.clone());\n                }\n            }\n\n            const findBestUnmappedDescendantForJoint = (bone: Bone, targetJointName: WebXRBodyJoint): Bone | null => {\n                const tokens = targetJointName\n                    .toLowerCase()\n                    .split(/[_\\-\\s]+/)\n                    .filter((t) => t.length >= 4 && t !== \"left\" && t !== \"right\" && t !== \"hand\" && t !== \"foot\" && t !== \"joint\" && t !== \"body\");\n                let bestDescendant: Bone | null = null;\n                let bestScore = 0;\n                const walk = (b: Bone): void => {\n                    for (const child of b.children) {\n                        if (!this._boneToJointIdx.has(child)) {\n                            const lname = child.name.toLowerCase();\n                            let score = 0;\n                            for (const t of tokens) {\n                                if (lname.indexOf(t) !== -1) {\n                                    score++;\n                                }\n                            }\n                            if (score > bestScore) {\n                                bestScore = score;\n                                bestDescendant = child;\n                            }\n                            walk(child);\n                        }\n                    }\n                };\n                walk(bone);\n                return bestScore > 0 ? bestDescendant : null;\n            };\n\n            for (const bone of Array.from(this._boneToJointIdx.keys())) {\n                // Prefer an explicit override (XR-joint → XR-joint) when provided.\n                const selfJointIdx = this._boneToJointIdx.get(bone)!;\n                const selfJointName = BodyJointReferenceArray[selfJointIdx] as WebXRBodyJoint;\n                const overrideTargetJointName = this._aimChildOverrides?.[selfJointName];\n                let childBone: Bone | null = null;\n                let overrideTargetJointIdx = -1;\n                if (overrideTargetJointName) {\n                    overrideTargetJointIdx = BodyJointNameToIndex.get(overrideTargetJointName) ?? -1;\n                    const overrideBoneName = rigMapping ? rigMapping[overrideTargetJointName] : overrideTargetJointName;\n                    if (overrideBoneName) {\n                        const overrideBoneIdx = skeleton.getBoneIndexByName(overrideBoneName);\n                        if (overrideBoneIdx !== -1) {\n                            const candidate = skeleton.bones[overrideBoneIdx];\n                            if (this._boneToJointIdx.has(candidate)) {\n                                childBone = candidate;\n                            }\n                        }\n                    }\n                }\n\n                // Case A: override target is a MAPPED bone → use bind positions\n                //   of both bones (as before).\n                if (childBone) {\n                    const boneBindPos = bindWorldPositions.get(bone);\n                    const childBindPos = bindWorldPositions.get(childBone);\n                    const bindWorldRotation = bindWorldRotations.get(bone);\n                    if (boneBindPos && childBindPos && bindWorldRotation) {\n                        childBindPos.subtractToRef(boneBindPos, this._tempDirection);\n                        if (this._tempDirection.lengthSquared() > 1e-8) {\n                            this._tempDirection.normalize();\n                            Quaternion.InverseToRef(bindWorldRotation, this._tempRotQuat2);\n                            this._tempDirection.rotateByQuaternionToRef(this._tempRotQuat2, this._tempLocalDirection);\n                            if (this._tempLocalDirection.lengthSquared() > 1e-8) {\n                                this._tempLocalDirection.normalize();\n                                this._mappedChildBones.set(bone, childBone);\n                                this._bindLocalAimDirections.set(bone, this._tempLocalDirection.clone());\n                                this._boneAimTargetJointIdx.set(bone, this._boneToJointIdx.get(childBone)!);\n                            }\n                        }\n                    }\n                    continue;\n                }\n\n                // Case B: override target is an UNMAPPED XR joint (e.g.\n                //   hand → middle metacarpal). Try to resolve it to a real\n                //   unmapped descendant bone by name match so we can compute\n                //   bind-local aim from the rig's own bind pose (the tracked\n                //   bind pose of the user doesn't necessarily match the rig's\n                //   bind orientation — using it would introduce a constant\n                //   offset).\n                if (overrideTargetJointIdx !== -1 && overrideTargetJointName) {\n                    this._boneAimTargetJointIdx.set(bone, overrideTargetJointIdx);\n                    const twistReferences = HandTwistReferenceJoints[selfJointName];\n                    if (twistReferences) {\n                        const firstIdx = BodyJointNameToIndex.get(twistReferences.first);\n                        const secondIdx = BodyJointNameToIndex.get(twistReferences.second);\n                        if (firstIdx !== undefined && secondIdx !== undefined) {\n                            this._boneTwistReferenceJointIdx.set(bone, { first: firstIdx, second: secondIdx });\n                        }\n                    }\n\n                    const descendant = findBestUnmappedDescendantForJoint(bone, overrideTargetJointName);\n                    if (descendant) {\n                        const boneBindPos = bindWorldPositions.get(bone);\n                        // Walk up: descendant's bind world position isn't in\n                        // bindWorldPositions (only mapped bones were added).\n                        // Compute it from the final matrix captured at bind.\n                        const descBindFinal = bindPoseFinals.get(descendant);\n                        const bindWorldRotation = bindWorldRotations.get(bone);\n                        if (boneBindPos && descBindFinal && bindWorldRotation) {\n                            descBindFinal.decompose(undefined, undefined, this._tempPosVec);\n                            this._tempPosVec.subtractToRef(boneBindPos, this._tempDirection);\n                            if (this._tempDirection.lengthSquared() > 1e-8) {\n                                this._tempDirection.normalize();\n                                Quaternion.InverseToRef(bindWorldRotation, this._tempRotQuat2);\n                                this._tempDirection.rotateByQuaternionToRef(this._tempRotQuat2, this._tempLocalDirection);\n                                if (this._tempLocalDirection.lengthSquared() > 1e-8) {\n                                    this._tempLocalDirection.normalize();\n                                    this._bindLocalAimDirections.set(bone, this._tempLocalDirection.clone());\n                                }\n                            }\n                        }\n\n                        if (twistReferences && boneBindPos && descBindFinal && bindWorldRotation) {\n                            const firstDescendant = findBestUnmappedDescendantForJoint(bone, twistReferences.first);\n                            const secondDescendant = findBestUnmappedDescendantForJoint(bone, twistReferences.second);\n                            const firstBindFinal = firstDescendant ? bindPoseFinals.get(firstDescendant) : null;\n                            const secondBindFinal = secondDescendant ? bindPoseFinals.get(secondDescendant) : null;\n                            if (firstBindFinal && secondBindFinal) {\n                                descBindFinal.decompose(undefined, undefined, this._tempPosVec);\n                                firstBindFinal.decompose(undefined, undefined, this._tempTwistFirst);\n                                secondBindFinal.decompose(undefined, undefined, this._tempTwistSecond);\n                                this._storeBindLocalTwistNormalFromPositions(bone, boneBindPos, this._tempPosVec, this._tempTwistFirst, this._tempTwistSecond, bindWorldRotation);\n                            }\n                        }\n                    }\n                    // If we couldn't find a descendant, bind aim will be\n                    // computed from tracked-bind positions later (fallback).\n                    continue;\n                }\n\n                // Case C: no override → auto-detect a mapped descendant.\n                const autoChild = findMappedChildBone(bone);\n                if (!autoChild) {\n                    continue;\n                }\n                const boneBindPos = bindWorldPositions.get(bone);\n                const childBindPos = bindWorldPositions.get(autoChild);\n                const bindWorldRotation = bindWorldRotations.get(bone);\n                if (!boneBindPos || !childBindPos || !bindWorldRotation) {\n                    continue;\n                }\n                childBindPos.subtractToRef(boneBindPos, this._tempDirection);\n                if (this._tempDirection.lengthSquared() < 1e-8) {\n                    continue;\n                }\n                this._tempDirection.normalize();\n                Quaternion.InverseToRef(bindWorldRotation, this._tempRotQuat2);\n                this._tempDirection.rotateByQuaternionToRef(this._tempRotQuat2, this._tempLocalDirection);\n                if (this._tempLocalDirection.lengthSquared() < 1e-8) {\n                    continue;\n                }\n                this._tempLocalDirection.normalize();\n                this._mappedChildBones.set(bone, autoChild);\n                this._bindLocalAimDirections.set(bone, this._tempLocalDirection.clone());\n                this._boneAimTargetJointIdx.set(bone, this._boneToJointIdx.get(autoChild)!);\n            }\n\n            // Step B: for each mapped bone, walk UP the skeleton hierarchy\n            // to find the nearest ancestor bone that is also mapped to an\n            // XR joint.  This lets us compute correct bone-local transforms\n            // even when unmapped bones exist between two mapped ones.\n            for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                if (!this._jointHasBone[i]) {\n                    continue;\n                }\n                const bone = skeleton.bones[skeleton.getBoneIndexByName((rigMapping ? rigMapping[BodyJointReferenceArray[i]] : BodyJointReferenceArray[i])!)];\n                let ancestor = bone.getParent();\n                while (ancestor) {\n                    const pIdx = this._boneToJointIdx.get(ancestor as Bone);\n                    if (pIdx !== undefined) {\n                        this._jointParentJointIdx[i] = pIdx;\n                        break;\n                    }\n                    ancestor = ancestor.getParent();\n                }\n            }\n\n            // Step C: pre-allocate desiredFinal matrices and compute\n            // bind-pose finals (via skeleton.prepare) for unmapped bone setup.\n            if (this._desiredFinals.length === 0) {\n                for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                    this._desiredFinals.push(new Matrix());\n                }\n            }\n            skeleton.prepare(true);\n\n            // Step D: create standalone TNs for unmapped skinned bones.\n            // Bones that influence vertices (_index >= 0) but aren't mapped to\n            // any XR joint need standalone TNs so prepare() reads bind-pose\n            // locals rather than the original glTF scene-graph TNs (which we\n            // don't control).  During tracking, these bones keep their\n            // bind-pose local and chain naturally with tracked parent finals —\n            // their vertices follow the parent bone's motion.\n            this._unmappedBoneNodes = [];\n            for (const bone of skeleton.bones) {\n                if (this._boneToJointIdx.has(bone)) {\n                    continue; // mapped — handled by body tracking\n                }\n                const boneIndex = bone._index;\n                if (boneIndex === -1 || boneIndex === null) {\n                    continue; // unskinned (e.g. Armature)\n                }\n                // This bone influences vertices but isn't tracked by an XR joint.\n                // Create a standalone TN with the bind-pose local so the bone\n                // keeps its offset from its parent and follows parent motion.\n                const tn = new TransformNode(`_xrUnmapped_${bone.name}`, skeleton.getScene());\n                tn.rotationQuaternion = new Quaternion();\n                // Initialize TN with the current (bind-pose) local\n                bone.getLocalMatrix().decompose(tn.scaling, tn.rotationQuaternion, tn.position);\n                bone.linkTransformNode(tn);\n                this._unmappedBoneNodes.push({ bone, standaloneNode: tn });\n            }\n        }\n\n        this.onBodyMeshSetObservable.notifyObservers(this);\n    }\n\n    /**\n     * Update joint transforms from the current XR frame.\n     *\n     * This method is called once per frame by the feature class.  Internally it:\n     * 1. Extracts all XRBodySpaces from the XRBody.\n     * 2. Fills the transform-matrix buffer via `fillPoses()` (or per-joint fallback).\n     * 3. Converts from WebXR right-handed to Babylon left-handed coordinates.\n     * 4. Decomposes each matrix into the corresponding TransformNode.\n     * 5. Parents the body mesh root to the XR camera so it tracks correctly.\n     *\n     * @param xrFrame The current XRFrame.\n     * @param referenceSpace The XRReferenceSpace to resolve poses against.\n     * @param xrCameraParent The parent node of the XR camera (used for parenting).\n     * @returns `true` if valid tracking data was processed, `false` otherwise.\n     */\n    public updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace, xrCameraParent: Nullable<Node>): boolean {\n        const body: XRBody | undefined = xrFrame.body;\n        if (!body) {\n            this._lastDebugInfo = \"no body\";\n            return false;\n        }\n\n        // ── Step 1: collect the body spaces in order ──────────────────────\n        // Some UAs expose joints as direct properties on the body object in\n        // addition to (or instead of) the Map-like .get() accessor — mirror\n        // the same double-lookup hand tracking uses.\n        const anyBody: any = body;\n        let validSpaceCount = 0;\n        for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n            const jointName = BodyJointReferenceArray[i];\n            const space = anyBody[jointName] || body.get(jointName);\n            this._jointSpaces[i] = space;\n            if (space) {\n                validSpaceCount++;\n            }\n        }\n\n        if (validSpaceCount === 0) {\n            this._lastDebugInfo = \"0 spaces\";\n            if (this._bodyMesh) {\n                this._bodyMesh.isVisible = false;\n            }\n            return false;\n        }\n\n        // ── Step 2: fill matrices (prefer batch API, fall back to per-joint) ──\n        let trackingSuccessful = false;\n        let fillPosesError = \"\";\n\n        // Only use fillPoses when ALL joint spaces resolved — the batch API\n        // does not tolerate undefined entries.  Wrap in try/catch because\n        // fillPoses may not accept body-tracking spaces on every UA.\n        if (validSpaceCount === BODY_JOINT_COUNT && xrFrame.fillPoses) {\n            try {\n                trackingSuccessful = xrFrame.fillPoses(this._jointSpaces as XRSpace[], referenceSpace, this._jointTransformMatrices);\n                if (!trackingSuccessful) {\n                    fillPosesError = \"returned false\";\n                }\n            } catch (e) {\n                fillPosesError = \"\" + e;\n                trackingSuccessful = false;\n            }\n        }\n\n        // Fallback: query each joint individually via getPose().\n        // Lenient — skips missing joints and succeeds as long as at least\n        // one joint returned valid data.\n        let getPoseCount = 0;\n        let getPoseNullCount = 0;\n        if (!trackingSuccessful) {\n            let anyJointTracked = false;\n            for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                const space = this._jointSpaces[i];\n                if (!space) {\n                    continue;\n                }\n                const pose = xrFrame.getPose(space, referenceSpace);\n                if (pose) {\n                    this._jointTransformMatrices.set(pose.transform.matrix, i * 16);\n                    anyJointTracked = true;\n                    getPoseCount++;\n                } else {\n                    getPoseNullCount++;\n                }\n            }\n            trackingSuccessful = anyJointTracked;\n        }\n\n        this._lastDebugInfo = \"spaces:\" + validSpaceCount + \" fillPoses:\" + fillPosesError + \" getPose:\" + getPoseCount + \"/\" + getPoseNullCount + \" ok:\" + trackingSuccessful;\n\n        if (!trackingSuccessful) {\n            if (this._bodyMesh) {\n                this._bodyMesh.isVisible = false;\n            }\n            return false;\n        }\n\n        this._processTrackedJointMatrices(xrCameraParent);\n        return true;\n    }\n\n    /**\n     * Replay a pre-captured joint matrix set through the retargeting\n     * pipeline as if it had just been delivered by an XR frame.\n     *\n     * Useful for headset-less testing: call with a snapshot captured via\n     * {@link snapshotFrame} (the `jointMatricesRHS` array, or `jointMatricesLHS`\n     * already flipped). The matrices are assumed to be RHS unless\n     * `isAlreadyLhs=true`, in which case the RHS→LHS flip step is skipped.\n     *\n     * @param rawMatrices Float32Array of BODY_JOINT_COUNT × 16 (= 1328) floats.\n     * @param isAlreadyLhs Set to `true` if matrices are already LHS-converted.\n     */\n    public replayRawJointMatrices(rawMatrices: Float32Array | number[], isAlreadyLhs: boolean = false): void {\n        const src = rawMatrices instanceof Float32Array ? rawMatrices : new Float32Array(rawMatrices);\n        const expectedLen = BODY_JOINT_COUNT * 16;\n        if (src.length !== expectedLen) {\n            Logger.Warn(\"WebXR Body Tracking: replayRawJointMatrices expected \" + expectedLen + \" floats, got \" + src.length);\n            return;\n        }\n        this._jointTransformMatrices.set(src);\n        this._processTrackedJointMatrices(null, /*skipRhsToLhs*/ isAlreadyLhs);\n    }\n\n    /**\n     * Run steps 2.5 → 5 of the retargeting pipeline using whatever is\n     * currently in `_jointTransformMatrices` (as if the WebXR API just\n     * filled it for the current frame).\n     * @param xrCameraParent Parent node of the XR camera (used to parent the body mesh root during live XR).\n     * @param skipRhsToLhs If true, skip the RHS→LHS flip (matrices are already in the scene's handedness).\n     */\n    private _processTrackedJointMatrices(xrCameraParent: Nullable<Node>, skipRhsToLhs: boolean = false): void {\n        // ── Step 2.5: re-base joint local axes (optional) ────────────────\n        // If jointLocalRotationOffset is set, right-multiply every joint's\n        // world matrix by its 4×4 form. Under Babylon's row-vector convention\n        // (`v_world = v_local × M`), `M_new = R × M` re-bases the joint-local\n        // frame so that what used to be along `R⁻¹·x` is now along `x`.\n        // Typical use: convert \"+Z-along-bone\" XR data to \"+Y-along-bone\" via\n        // `Quaternion.RotationAxis(Vector3.Right(), -Math.PI / 2)`.\n        if (this.jointLocalRotationOffset) {\n            Matrix.FromQuaternionToRef(this.jointLocalRotationOffset, this._jointLocalRotationOffsetMatrix);\n            for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                const o = i * 16;\n                Matrix.FromArrayToRef(this._jointTransformMatrices, o, this._tempJointMatrix);\n                this._jointLocalRotationOffsetMatrix.multiplyToRef(this._tempJointMatrix, this._tempOffsetAppliedMatrix);\n                this._tempOffsetAppliedMatrix.copyToArray(this._jointTransformMatrices, o);\n            }\n        }\n\n        // ── Step 3: RHS → LHS coordinate conversion ──────────────────────\n        // WebXR delivers right-handed matrices.  When Babylon is running in\n        // its default left-handed mode we negate the Z-related components of\n        // every column-major 4 × 4 matrix in-place.\n        //\n        // Column-major layout (indices 0-15):\n        //   [ m00  m10  m20  m30 ]     indices 0  1  2  3\n        //   [ m01  m11  m21  m31 ]     indices 4  5  6  7\n        //   [ m02  m12  m22  m32 ]     indices 8  9  10 11\n        //   [ m03  m13  m23  m33 ]     indices 12 13 14 15\n        //\n        // Negated indices: 2, 6, 8, 9, 14  (third row + translation Z)\n        // Always keep a copy of the pre-flip (raw RHS) matrices so that\n        // `snapshotFrame()` always has them available, regardless of the\n        // scene handedness or the `skipRhsToLhs` flag.\n        this._jointTransformMatricesRHS.set(this._jointTransformMatrices);\n        if (!skipRhsToLhs && !this._scene.useRightHandedSystem) {\n            for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                const o = i * 16;\n                this._jointTransformMatrices[o + 2] *= -1;\n                this._jointTransformMatrices[o + 6] *= -1;\n                this._jointTransformMatrices[o + 8] *= -1;\n                this._jointTransformMatrices[o + 9] *= -1;\n                this._jointTransformMatrices[o + 14] *= -1;\n            }\n        }\n\n        // ── Step 4: decompose world-space matrices into TransformNodes ─────\n        // For unmapped joints, TransformNodes hold world-space pose for\n        // consumers (e.g., debug boxes).  For mapped joints (linked to\n        // skeleton bones), we overwrite with bone-local data in step 4b.\n        for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n            if (!this._jointHasBone[i]) {\n                const jointTransform = this._jointTransforms[i];\n                Matrix.FromArrayToRef(this._jointTransformMatrices, i * 16, this._tempJointMatrix);\n                this._tempJointMatrix.decompose(undefined, jointTransform.rotationQuaternion!, jointTransform.position);\n            }\n        }\n\n        // ── Step 4b: compute bone-local transforms via desiredFinals ──────\n        // For every mapped joint we compute the target skeleton-space final:\n        //   desiredFinal = strip(xrWorld × inv(meshWorld))\n        // All desiredFinals are in the same space (skeleton space), so\n        // locals derived from them have consistent units and scale.\n        // We then iterate ALL skeleton bones in array order (parents first)\n        // and compute each bone's local as:\n        //   mapped bone:   local = desiredFinal × inv(parentBone.final)\n        //   unmapped bone: local unchanged (bind-pose), chain with parent final\n        if (this._skeletonMesh && this._skeleton) {\n            this._skeletonMesh.getWorldMatrix().invertToRef(this._meshWorldMatrixInverse);\n            const scaleFactor = this._jointScaleFactor;\n            const useInitialSkinMatrix = this._skeleton.needInitialSkinMatrix;\n            const useBoneOrientationOffsets = this._useBoneOrientationOffsets;\n            const computedWorldRotations = useBoneOrientationOffsets ? new Map<Bone, Quaternion>() : null;\n\n            if (useInitialSkinMatrix) {\n                this._skeletonMesh.getPoseMatrix().invertToRef(this._initialSkinMatrixInverse);\n            }\n\n            // Pass 1: compute desiredFinals for all mapped joints.\n            for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n                if (!this._jointHasBone[i]) {\n                    continue;\n                }\n                Matrix.FromArrayToRef(this._jointTransformMatrices, i * 16, this._tempJointMatrix);\n                this._tempJointMatrix.multiplyToRef(this._meshWorldMatrixInverse, this._desiredFinals[i]);\n                // Strip parasitic scale from inv(meshWorld) to ±1.\n                this._desiredFinals[i].decompose(this._tempScaleVector, this._tempRotQuat, this._tempPosVec);\n                this._tempScaleVector.set(Math.sign(this._tempScaleVector.x) || 1, Math.sign(this._tempScaleVector.y) || 1, Math.sign(this._tempScaleVector.z) || 1);\n                Matrix.ComposeToRef(this._tempScaleVector, this._tempRotQuat, this._tempPosVec, this._desiredFinals[i]);\n                this._desiredFinalPositions[i].copyFrom(this._tempPosVec);\n            }\n\n            // Pass 1b: compute mesh-local positions for any UNMAPPED XR joints\n            // that are referenced as aim targets (e.g. hand → middle metacarpal).\n            // Rotations are not needed for these joints — only positions.\n            // Use Map.forEach to avoid allocating an array and to stay within the ES5\n            // target's iteration rules.\n            this._boneAimTargetJointIdx.forEach((targetIdx) => {\n                if (this._jointHasBone[targetIdx]) {\n                    return; // position already filled above.\n                }\n                Matrix.FromArrayToRef(this._jointTransformMatrices, targetIdx * 16, this._tempJointMatrix);\n                this._tempJointMatrix.multiplyToRef(this._meshWorldMatrixInverse, this._tempLocalMatrix);\n                this._tempLocalMatrix.decompose(undefined, undefined, this._desiredFinalPositions[targetIdx]);\n            });\n            this._boneTwistReferenceJointIdx.forEach((twistReferences) => {\n                if (!this._jointHasBone[twistReferences.first]) {\n                    Matrix.FromArrayToRef(this._jointTransformMatrices, twistReferences.first * 16, this._tempJointMatrix);\n                    this._tempJointMatrix.multiplyToRef(this._meshWorldMatrixInverse, this._tempLocalMatrix);\n                    this._tempLocalMatrix.decompose(undefined, undefined, this._desiredFinalPositions[twistReferences.first]);\n                }\n                if (!this._jointHasBone[twistReferences.second]) {\n                    Matrix.FromArrayToRef(this._jointTransformMatrices, twistReferences.second * 16, this._tempJointMatrix);\n                    this._tempJointMatrix.multiplyToRef(this._meshWorldMatrixInverse, this._tempLocalMatrix);\n                    this._tempLocalMatrix.decompose(undefined, undefined, this._desiredFinalPositions[twistReferences.second]);\n                }\n            });\n\n            // Auto-capture bind on first frame when enabled.\n            if (!this._hasTrackedBind && this.autoCaptureBindOnFirstFrame) {\n                this._captureTrackedBindFromDesiredFinals();\n            }\n\n            if (this._hasTrackedBind && this._trackedBindDesiredFinalRot && this._trackedBindDesiredFinalPos) {\n                // ── Pass 2 (primary): delta-from-bind retargeting ─────────\n                // Axis-convention-invariant. For every mapped bone:\n                //   deltaMeshLocalRot[j] = trackedBindDesiredRot[j]⁻¹ × trackedCurrentDesiredRot[j]\n                //   newBoneWorldRot[b]   = bindBoneWorldRot[b] × deltaMeshLocalRot[j(b)]\n                //   newBoneLocalRot[b]   = newBoneWorldRot[b] × newBoneParentWorldRot[b]⁻¹\n                this._retargetDeltaFromBind(scaleFactor);\n                // Unmapped bones: chain bind-pose local × parent final.\n                for (const bone of this._skeleton.bones) {\n                    if (this._boneToJointIdx.has(bone)) {\n                        continue;\n                    }\n                    const parentBone = bone.getParent();\n                    if (parentBone) {\n                        bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\n                    } else {\n                        bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\n                    }\n                }\n            } else {\n                // ── Pass 2 (fallback): direct retarget ─────────────────────\n                // Used before a tracked bind has been captured (e.g. during\n                // the first frame with autoCaptureBindOnFirstFrame=false).\n                this._retargetDirect(useInitialSkinMatrix, useBoneOrientationOffsets, scaleFactor, computedWorldRotations);\n            }\n\n            // ── Step 4c (diagnostic): direct skin matrix write ───────────\n            // When _directSkinWrite is enabled, write absInvBind × final\n            // directly into the skeleton's transform matrix buffer, bypassing\n            // the normal TN → bone → prepare() → skin matrix pipeline.\n            if (this._directSkinWrite) {\n                const skinMatrices = this._skeleton.getTransformMatrices(this._skeletonMesh);\n                if (skinMatrices) {\n                    for (const bone of this._skeleton.bones) {\n                        const bIdx = bone._index;\n                        if (bIdx === -1 || bIdx === null) {\n                            continue;\n                        }\n                        const mappedIndex = bIdx;\n                        bone.getAbsoluteInverseBindMatrix().multiplyToArray(bone.getFinalMatrix(), skinMatrices, mappedIndex * 16);\n                    }\n                }\n            }\n        }\n\n        // ── Step 5: parent the mesh to the XR camera ─────────────────────\n        if (this._bodyMesh) {\n            this._bodyMesh.isVisible = true;\n            if (this._bodyMeshRoot && xrCameraParent) {\n                this._bodyMeshRoot.parent = xrCameraParent;\n            }\n        }\n    }\n\n    /**\n     * Capture the current tracked-joint desired-final rotations and positions\n     * as the \"rest pose\" for delta-from-bind retargeting.\n     *\n     * Delta-from-bind is the production retarget path: every subsequent\n     * frame is interpreted as a rotation delta from this snapshot, which\n     * makes retargeting invariant to the XR-joint axis convention and to\n     * any skeletal-proportion differences between the tracked user and the\n     * avatar.\n     *\n     * Call this after the user assumes a known rest pose (e.g. T-pose,\n     * A-pose, arms-at-sides). By default the feature auto-captures on the\n     * first tracked frame — disable via {@link autoCaptureBindOnFirstFrame}.\n     */\n    public captureTrackedBind(): void {\n        this._captureTrackedBindFromDesiredFinals();\n    }\n\n    /**\n     * Clear any captured bind, reverting subsequent frames to the fallback\n     * direct-retarget path (or re-triggering auto-capture on the next frame).\n     */\n    public clearTrackedBind(): void {\n        this._hasTrackedBind = false;\n    }\n\n    private _computeNormalFromJointPositions(origin: Vector3, aimTarget: Vector3, first: Vector3, second: Vector3, result: Vector3, aimAxisResult: Vector3): boolean {\n        aimTarget.subtractToRef(origin, aimAxisResult);\n        if (aimAxisResult.lengthSquared() < 1e-8) {\n            return false;\n        }\n        aimAxisResult.normalize();\n\n        first.subtractToRef(second, this._tempTwistCross);\n        if (this._tempTwistCross.lengthSquared() < 1e-8) {\n            return false;\n        }\n        this._tempTwistCross.normalize();\n\n        Vector3.CrossToRef(aimAxisResult, this._tempTwistCross, result);\n        if (result.lengthSquared() < 1e-8) {\n            return false;\n        }\n        result.normalize();\n        return true;\n    }\n\n    private _projectOnPlaneToRef(vector: Vector3, planeNormal: Vector3, result: Vector3): boolean {\n        const dot = Vector3.Dot(vector, planeNormal);\n        result.copyFrom(planeNormal).scaleInPlace(-dot).addInPlace(vector);\n        if (result.lengthSquared() < 1e-8) {\n            return false;\n        }\n        result.normalize();\n        return true;\n    }\n\n    private _storeBindLocalTwistNormalFromPositions(bone: Bone, origin: Vector3, aimTarget: Vector3, first: Vector3, second: Vector3, bindWorldRotation: Quaternion): void {\n        if (!this._computeNormalFromJointPositions(origin, aimTarget, first, second, this._tempTwistNormal, this._tempTwistAimAxis)) {\n            return;\n        }\n        Quaternion.InverseToRef(bindWorldRotation, this._tempRotQuat2);\n        this._tempTwistNormal.rotateByQuaternionToRef(this._tempRotQuat2, this._tempLocalDirection);\n        if (this._tempLocalDirection.lengthSquared() < 1e-8) {\n            return;\n        }\n        this._tempLocalDirection.normalize();\n        this._bindLocalTwistNormals.set(bone, this._tempLocalDirection.clone());\n    }\n\n    /** Internal: copy current desiredFinals into the tracked-bind slots. */\n    private _captureTrackedBindFromDesiredFinals(): void {\n        if (!this._trackedBindDesiredFinalRot) {\n            this._trackedBindDesiredFinalRot = Array.from({ length: BODY_JOINT_COUNT }, () => new Quaternion());\n            this._trackedBindDesiredFinalPos = Array.from({ length: BODY_JOINT_COUNT }, () => new Vector3());\n        }\n        for (let i = 0; i < BODY_JOINT_COUNT; i++) {\n            if (!this._jointHasBone[i]) {\n                continue;\n            }\n            this._desiredFinals[i].decompose(undefined, this._tempRotQuat, this._tempPosVec);\n            this._trackedBindDesiredFinalRot[i].copyFrom(this._tempRotQuat);\n            this._trackedBindDesiredFinalPos![i].copyFrom(this._tempPosVec);\n        }\n\n        // Also capture positions for aim-target joints that aren't mapped\n        // (e.g. hand's middle metacarpal). These are only needed for the\n        // positional aim-correction reference.\n        for (const targetIdx of Array.from(this._boneAimTargetJointIdx.values())) {\n            if (this._jointHasBone[targetIdx]) {\n                continue;\n            }\n            this._trackedBindDesiredFinalPos![targetIdx].copyFrom(this._desiredFinalPositions[targetIdx]);\n        }\n\n        for (const twistReferences of Array.from(this._boneTwistReferenceJointIdx.values())) {\n            if (!this._jointHasBone[twistReferences.first]) {\n                this._trackedBindDesiredFinalPos![twistReferences.first].copyFrom(this._desiredFinalPositions[twistReferences.first]);\n            }\n            if (!this._jointHasBone[twistReferences.second]) {\n                this._trackedBindDesiredFinalPos![twistReferences.second].copyFrom(this._desiredFinalPositions[twistReferences.second]);\n            }\n        }\n\n        // For any bone whose aim target is UNMAPPED and therefore wasn't\n        // resolved at setBodyMesh time, compute its bind-local aim direction\n        // now — using tracked bind positions for both endpoints and the\n        // bone's bind-world rotation as the frame.\n        for (const [bone, targetIdx] of Array.from(this._boneAimTargetJointIdx)) {\n            if (this._bindLocalAimDirections.has(bone)) {\n                continue;\n            }\n            const selfJointIdx = this._boneToJointIdx.get(bone);\n            const bindWorldRot = this._bindBoneWorldRotMeshLocal.get(bone);\n            if (selfJointIdx === undefined || !bindWorldRot) {\n                continue;\n            }\n            this._trackedBindDesiredFinalPos![targetIdx].subtractToRef(this._trackedBindDesiredFinalPos![selfJointIdx], this._tempDirection);\n            if (this._tempDirection.lengthSquared() < 1e-8) {\n                continue;\n            }\n            this._tempDirection.normalize();\n            Quaternion.InverseToRef(bindWorldRot, this._tempRotQuat2);\n            this._tempDirection.rotateByQuaternionToRef(this._tempRotQuat2, this._tempLocalDirection);\n            if (this._tempLocalDirection.lengthSquared() < 1e-8) {\n                continue;\n            }\n            this._tempLocalDirection.normalize();\n            this._bindLocalAimDirections.set(bone, this._tempLocalDirection.clone());\n        }\n\n        for (const [bone, twistReferences] of Array.from(this._boneTwistReferenceJointIdx)) {\n            if (this._bindLocalTwistNormals.has(bone)) {\n                continue;\n            }\n            const selfJointIdx = this._boneToJointIdx.get(bone);\n            const targetIdx = this._boneAimTargetJointIdx.get(bone);\n            const bindWorldRot = this._bindBoneWorldRotMeshLocal.get(bone);\n            if (selfJointIdx === undefined || targetIdx === undefined || !bindWorldRot) {\n                continue;\n            }\n            this._storeBindLocalTwistNormalFromPositions(\n                bone,\n                this._trackedBindDesiredFinalPos![selfJointIdx],\n                this._trackedBindDesiredFinalPos![targetIdx],\n                this._trackedBindDesiredFinalPos![twistReferences.first],\n                this._trackedBindDesiredFinalPos![twistReferences.second],\n                bindWorldRot\n            );\n        }\n\n        this._hasTrackedBind = true;\n    }\n\n    /**\n     * Delta-from-bind retarget: axis-convention-invariant.\n     *\n     * For each mapped bone in skeleton order (parents first):\n     *   let j = joint mapped to this bone\n     *   deltaMeshLocalRot  = bindTracked[j]⁻¹ × currentTracked[j]     (right-side in row-vector)\n     *   newBoneWorldRot    = bindBoneWorldRot × deltaMeshLocalRot\n     *   newBoneLocalRot    = newBoneWorldRot × parentNewBoneWorldRot⁻¹\n     *\n     * Positions: root bone receives tracked world delta (so the avatar\n     * translates with the user). All other mapped bones keep their rig's\n     * bind-pose local translation to preserve segment lengths.\n     * @param scaleFactor Additional scale applied to joint local positions.\n     */\n    private _retargetDeltaFromBind(scaleFactor: number): void {\n        if (!this._skeleton || !this._trackedBindDesiredFinalRot || !this._trackedBindDesiredFinalPos) {\n            return;\n        }\n        // Bump the frame id so pooled per-bone rotations are treated as stale.\n        // The Quaternion instances themselves are reused across frames (no allocations).\n        this._currentRetargetFrameId++;\n\n        for (const bone of this._skeleton.bones) {\n            const parentBone = bone.getParent();\n            const jointIdx = this._boneToJointIdx.get(bone);\n\n            if (jointIdx === undefined) {\n                // Unmapped bones are handled by the caller.\n                continue;\n            }\n\n            const jointTransform = this._jointTransforms[jointIdx];\n            const bindBoneWorldRot = this._bindBoneWorldRotMeshLocal.get(bone);\n            if (!bindBoneWorldRot) {\n                continue;\n            }\n\n            // Current tracked rotation/position in mesh-local (already in _desiredFinals).\n            this._desiredFinals[jointIdx].decompose(undefined, this._tempTrackedCurRot, this._tempTrackedCurPos);\n\n            // Babylon Quaternion multiplication is column-vector Hamilton:\n            //   worldQ = parentWorldQ.multiply(localQ)   (== parent * local)\n            //\n            // World-frame delta joint rotation:\n            //   deltaWorld = curJointWorld * bindJointWorld⁻¹\n            Quaternion.InverseToRef(this._trackedBindDesiredFinalRot[jointIdx], this._tempRotQuat2);\n            this._tempTrackedCurRot.multiplyToRef(this._tempRotQuat2, this._tempDeltaQuat);\n\n            // Apply world delta to bone's bind world rotation:\n            //   newBoneWorld = deltaWorld * boneBindWorld\n            this._tempDeltaQuat.multiplyToRef(bindBoneWorldRot, this._tempBoneWorldRot);\n            this._tempBoneWorldRot.normalize();\n\n            // ── Aim correction (positional) ─────────────────────────────\n            // Meta's emitted rotation for some joints (notably the\n            // forearm, LEFT/RIGHT_ARM_LOWER) is unreliable: the cameras\n            // frequently report a rotation that makes the forearm bone\n            // align with the upper arm, so the elbow \"raises\" but the\n            // forearm does not bend when the user lifts/rotates a hand.\n            //\n            // The tracked *positions*, however, are accurate. We re-aim\n            // the bone so that the bind-time local aim axis (bone →\n            // child bone) ends up pointing along the live (childJoint −\n            // selfJoint) direction in mesh-local space. This is a single\n            // shortest-arc rotation applied to the world rotation before\n            // it is chained into children.\n            if (this._useBoneOrientationOffsets) {\n                const targetIdx = this._boneAimTargetJointIdx.get(bone);\n                const bindLocalAim = this._bindLocalAimDirections.get(bone);\n                if (bindLocalAim && targetIdx !== undefined) {\n                    // Desired aim direction in mesh-local (tracked positions).\n                    this._desiredFinalPositions[targetIdx].subtractToRef(this._desiredFinalPositions[jointIdx], this._tempDirection);\n                    if (this._tempDirection.lengthSquared() > 1e-8) {\n                        this._tempDirection.normalize();\n                        // Current aim direction in mesh-local: rotate bind-local aim by newBoneWorld.\n                        bindLocalAim.rotateByQuaternionToRef(this._tempBoneWorldRot, this._tempLocalDirection);\n                        if (this._tempLocalDirection.lengthSquared() > 1e-8) {\n                            this._tempLocalDirection.normalize();\n                            // Correction: shortest-arc rotation taking current aim → desired aim.\n                            Quaternion.FromUnitVectorsToRef(this._tempLocalDirection, this._tempDirection, this._tempRotQuat2);\n                            // Apply correction in world space (pre-multiply column-vector).\n                            this._tempRotQuat2.multiplyToRef(this._tempBoneWorldRot, this._tempDeltaQuat);\n                            this._tempBoneWorldRot.copyFrom(this._tempDeltaQuat);\n                            this._tempBoneWorldRot.normalize();\n                        }\n                    }\n                }\n\n                const twistReferences = this._boneTwistReferenceJointIdx.get(bone);\n                const bindLocalTwistNormal = this._bindLocalTwistNormals.get(bone);\n                if (twistReferences && bindLocalTwistNormal && targetIdx !== undefined) {\n                    if (\n                        this._computeNormalFromJointPositions(\n                            this._desiredFinalPositions[jointIdx],\n                            this._desiredFinalPositions[targetIdx],\n                            this._desiredFinalPositions[twistReferences.first],\n                            this._desiredFinalPositions[twistReferences.second],\n                            this._tempTwistNormal,\n                            this._tempTwistAimAxis\n                        )\n                    ) {\n                        // Rotate bind-space twist normal by the current world orientation,\n                        // then rotate around the aimed axis to match the tracked hand plane.\n                        bindLocalTwistNormal.rotateByQuaternionToRef(this._tempBoneWorldRot, this._tempCurrentTwistNormal);\n                        if (\n                            this._projectOnPlaneToRef(this._tempCurrentTwistNormal, this._tempTwistAimAxis, this._tempProjectedTwistNormal) &&\n                            this._projectOnPlaneToRef(this._tempTwistNormal, this._tempTwistAimAxis, this._tempProjectedDesiredTwistNormal)\n                        ) {\n                            const dot = Vector3.Dot(this._tempProjectedTwistNormal, this._tempProjectedDesiredTwistNormal);\n                            if (dot < -0.9999) {\n                                Quaternion.RotationAxisToRef(this._tempTwistAimAxis, Math.PI, this._tempRotQuat2);\n                            } else {\n                                Quaternion.FromUnitVectorsToRef(this._tempProjectedTwistNormal, this._tempProjectedDesiredTwistNormal, this._tempRotQuat2);\n                            }\n                            this._tempRotQuat2.multiplyToRef(this._tempBoneWorldRot, this._tempDeltaQuat);\n                            this._tempBoneWorldRot.copyFrom(this._tempDeltaQuat);\n                            this._tempBoneWorldRot.normalize();\n                        }\n                    }\n                }\n            }\n\n            // Store for children's parent lookup (reuse pooled quaternion).\n            let pooled = this._computedBoneNewWorldRot.get(bone);\n            if (!pooled) {\n                pooled = new Quaternion();\n                this._computedBoneNewWorldRot.set(bone, pooled);\n            }\n            pooled.copyFrom(this._tempBoneWorldRot);\n            this._computedBoneNewWorldRotFrameId.set(bone, this._currentRetargetFrameId);\n\n            // Parent's new world rotation: either the directly-computed\n            // mapped parent's rotation, or the closest mapped ancestor's\n            // rotation chained through any unmapped intermediates' bind\n            // local rotations.\n            let parentNewWorldRot: Quaternion | null = null;\n            if (parentBone) {\n                const directMapped =\n                    this._computedBoneNewWorldRotFrameId.get(parentBone) === this._currentRetargetFrameId ? this._computedBoneNewWorldRot.get(parentBone) : undefined;\n                if (directMapped) {\n                    parentNewWorldRot = directMapped;\n                } else {\n                    // Walk up to nearest mapped ancestor. Chain any\n                    // unmapped intermediates' bind local rotations:\n                    //   effectiveParentWorld = mappedAncestorNewWorld * child1Local * child2Local * ... * parentBoneLocal\n                    // (column-vector composition).\n                    const accum = this._tempParentAccumRot;\n                    accum.set(0, 0, 0, 1);\n                    let cursor: Bone | null = parentBone;\n                    while (cursor) {\n                        const mapped = this._computedBoneNewWorldRotFrameId.get(cursor) === this._currentRetargetFrameId ? this._computedBoneNewWorldRot.get(cursor) : undefined;\n                        if (mapped) {\n                            // mapped * accum, where accum is the local chain below.\n                            mapped.multiplyToRef(accum, this._tempParentAccumTmp);\n                            accum.copyFrom(this._tempParentAccumTmp);\n                            parentNewWorldRot = accum;\n                            break;\n                        }\n                        cursor.getLocalMatrix().decompose(undefined, this._tempRotQuat2, undefined);\n                        // accum = localCursor * accum (column-vector: cursor's local applied to child chain)\n                        this._tempRotQuat2.multiplyToRef(accum, this._tempParentAccumTmp);\n                        accum.copyFrom(this._tempParentAccumTmp);\n                        cursor = cursor.getParent();\n                    }\n                }\n            }\n\n            // newBoneLocal = parentNewWorldInv * newBoneWorld\n            if (parentNewWorldRot) {\n                Quaternion.InverseToRef(parentNewWorldRot, this._tempParentNewWorldRotInv);\n                this._tempParentNewWorldRotInv.multiplyToRef(this._tempBoneWorldRot, jointTransform.rotationQuaternion!);\n            } else {\n                jointTransform.rotationQuaternion!.copyFrom(this._tempBoneWorldRot);\n            }\n            jointTransform.rotationQuaternion!.normalize();\n\n            // Position/scale: preserve rig's bind-local values. Root bone\n            // additionally receives the tracked-position delta so the avatar\n            // translates with the user.\n            const bindLocal = this._mappedBoneBindLocals.get(bone);\n            if (bindLocal) {\n                bindLocal.decompose(this._tempBindLocalScale, undefined, this._tempBindLocalPos);\n                jointTransform.scaling.copyFrom(this._tempBindLocalScale);\n                jointTransform.position.copyFrom(this._tempBindLocalPos);\n            }\n\n            if (!parentNewWorldRot) {\n                // Root: add tracked mesh-local position delta to bind local.\n                const bindTrackedPos = this._trackedBindDesiredFinalPos[jointIdx];\n                jointTransform.position.addInPlace(this._tempTrackedCurPos).subtractInPlace(bindTrackedPos);\n            }\n\n            if (scaleFactor !== 1.0) {\n                jointTransform.position.scaleInPlace(scaleFactor);\n            }\n\n            // Compose and chain final.\n            Matrix.ComposeToRef(jointTransform.scaling, jointTransform.rotationQuaternion!, jointTransform.position, this._tempLocalMatrix);\n            if (parentBone) {\n                this._tempLocalMatrix.multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\n            } else {\n                bone.getFinalMatrix().copyFrom(this._tempLocalMatrix);\n            }\n        }\n    }\n\n    /**\n     * Legacy direct-retarget path (pre-bind-capture). Kept as fallback.\n     * @param useInitialSkinMatrix Skeleton needs initial-skin-matrix chaining for the root.\n     * @param useBoneOrientationOffsets Apply aim-direction correction per mapped bone.\n     * @param scaleFactor Additional scale applied to joint local positions.\n     * @param computedWorldRotations Optional map used by the aim-correction path for parent lookups.\n     */\n    private _retargetDirect(useInitialSkinMatrix: boolean, useBoneOrientationOffsets: boolean, scaleFactor: number, computedWorldRotations: Nullable<Map<Bone, Quaternion>>): void {\n        if (!this._skeleton || !this._skeletonMesh) {\n            return;\n        }\n        for (const bone of this._skeleton.bones) {\n            const parentBone = bone.getParent();\n            const jointIdx = this._boneToJointIdx.get(bone);\n\n            if (jointIdx !== undefined) {\n                const jointTransform = this._jointTransforms[jointIdx];\n                if (parentBone) {\n                    parentBone.getFinalMatrix().invertToRef(this._tempParentMatrix);\n                    this._desiredFinals[jointIdx].multiplyToRef(this._tempParentMatrix, this._tempLocalMatrix);\n                } else {\n                    if (useInitialSkinMatrix) {\n                        this._desiredFinals[jointIdx].multiplyToRef(this._initialSkinMatrixInverse, this._tempLocalMatrix);\n                    } else {\n                        this._tempLocalMatrix.copyFrom(this._desiredFinals[jointIdx]);\n                    }\n                }\n                this._tempLocalMatrix.decompose(jointTransform.scaling, jointTransform.rotationQuaternion!, jointTransform.position);\n\n                if (useBoneOrientationOffsets) {\n                    const childBone = this._mappedChildBones.get(bone);\n                    const bindLocalAimDirection = this._bindLocalAimDirections.get(bone);\n                    const childJointIdx = childBone ? this._boneToJointIdx.get(childBone) : undefined;\n\n                    if (bindLocalAimDirection && childJointIdx !== undefined) {\n                        this._desiredFinalPositions[childJointIdx].subtractToRef(this._desiredFinalPositions[jointIdx], this._tempDirection);\n                        if (this._tempDirection.lengthSquared() > 1e-8) {\n                            this._tempDirection.normalize();\n                            this._desiredFinals[jointIdx].decompose(this._tempScaleVector, this._tempRotQuat, this._tempPosVec);\n                            Quaternion.InverseToRef(this._tempRotQuat, this._tempRotQuat2);\n                            this._tempDirection.rotateByQuaternionToRef(this._tempRotQuat2, this._tempLocalDirection);\n                            if (this._tempLocalDirection.lengthSquared() > 1e-8) {\n                                this._tempLocalDirection.normalize();\n                                Quaternion.FromUnitVectorsToRef(bindLocalAimDirection, this._tempLocalDirection, this._tempRotQuat2);\n                                this._tempRotQuat.multiplyToRef(this._tempRotQuat2, this._tempRotQuat);\n\n                                if (parentBone) {\n                                    const parentWorldRotation = computedWorldRotations?.get(parentBone);\n                                    if (parentWorldRotation) {\n                                        Quaternion.InverseToRef(parentWorldRotation, this._tempRotQuat2);\n                                        this._tempRotQuat.multiplyToRef(this._tempRotQuat2, jointTransform.rotationQuaternion!);\n                                    } else {\n                                        jointTransform.rotationQuaternion!.copyFrom(this._tempRotQuat);\n                                    }\n                                } else if (useInitialSkinMatrix) {\n                                    this._skeletonMesh.getPoseMatrix().decompose(this._tempScaleVector, this._tempRotQuat2, this._tempPosVec);\n                                    Quaternion.InverseToRef(this._tempRotQuat2, this._tempRotQuat2);\n                                    this._tempRotQuat.multiplyToRef(this._tempRotQuat2, jointTransform.rotationQuaternion!);\n                                } else {\n                                    jointTransform.rotationQuaternion!.copyFrom(this._tempRotQuat);\n                                }\n                                jointTransform.rotationQuaternion!.normalize();\n                            }\n                        }\n                    }\n                }\n\n                if (this._preserveBindPoseBonePositions) {\n                    const bindLocal = this._mappedBoneBindLocals.get(bone);\n                    if (bindLocal) {\n                        bindLocal.decompose(this._tempScaleVector, this._tempRotQuat, this._tempPosVec);\n                        jointTransform.scaling.copyFrom(this._tempScaleVector);\n                        if (parentBone) {\n                            jointTransform.position.copyFrom(this._tempPosVec);\n                        }\n                    }\n                }\n\n                if (scaleFactor !== 1.0) {\n                    jointTransform.position.scaleInPlace(scaleFactor);\n                }\n\n                Matrix.ComposeToRef(jointTransform.scaling, jointTransform.rotationQuaternion!, jointTransform.position, this._tempLocalMatrix);\n                if (parentBone) {\n                    this._tempLocalMatrix.multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\n                } else {\n                    bone.getFinalMatrix().copyFrom(this._tempLocalMatrix);\n                }\n\n                if (computedWorldRotations) {\n                    bone.getFinalMatrix().decompose(this._tempScaleVector, this._tempRotQuat, this._tempPosVec);\n                    computedWorldRotations.set(bone, this._tempRotQuat.clone());\n                }\n            } else {\n                // Unmapped bone: chain bind-pose local × parent final.\n                if (parentBone) {\n                    bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\n                } else {\n                    bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\n                }\n            }\n        }\n    }\n\n    /**\n     * Capture a snapshot of the current frame's raw XR joint matrices and\n     * skeleton metadata.  Returns a JSON string that can be used offline to\n     * replay / debug bone-local computation without a headset.\n     *\n     * The snapshot includes:\n     * - `jointMatricesRHS` – 83 × 16 raw RHS matrices (before LHS conversion)\n     * - `jointMatricesLHS` – 83 × 16 LHS-converted matrices (after step 3)\n     * - `meshWorldMatrix` – 16 floats, the skeleton mesh's world matrix (if any)\n     * - `jointHasBone` – boolean[83], which joints are mapped to bones\n     * - `jointParentJointIdx` – number[83], mapped ancestor for each joint\n     * - `useRightHandedSystem` – scene handedness setting\n     * - `jointNames` – the 83 joint names in order\n     *\n     * @returns A JSON string with the snapshot data.\n     */\n    public snapshotFrame(): string {\n        const data = {\n            jointMatricesRHS: Array.from(this._jointTransformMatricesRHS).map((x) => +x.toFixed(3)), // round for readability\n            jointMatricesLHS: Array.from(this._jointTransformMatrices).map((x) => +x.toFixed(3)),\n            meshWorldMatrix: this._skeletonMesh ? Array.from(this._skeletonMesh.getWorldMatrix().toArray()).map((x) => +x.toFixed(3)) : null,\n            jointHasBone: Array.from(this._jointHasBone),\n            jointParentJointIdx: Array.from(this._jointParentJointIdx),\n            useRightHandedSystem: this._scene.useRightHandedSystem,\n            jointNames: BodyJointReferenceArray.slice(),\n        };\n        return JSON.stringify(data);\n    }\n\n    /**\n     * Capture a snapshot and copy it to the system clipboard.\n     * Logs to the console on success or failure.\n     * @returns A promise that resolves when the copy completes.\n     */\n    public async snapshotFrameToClipboardAsync(): Promise<void> {\n        const json = this.snapshotFrame();\n        // compress the string by removing whitespace (makes it less human-readable but more compact for clipboard)\n        // also remove 0. padding from numbers (e.g. \"0.123\" → \".123\") to further reduce size, since the leading zero is not needed for parsing.\n        const compressed = json.replace(/\\s+/g, \"\").replace(/:0\\.(\\d+)/g, \":.$1\");\n        try {\n            await navigator.clipboard.writeText(compressed);\n            Logger.Log(\"WebXR Body Tracking: snapshot copied to clipboard (\" + compressed.length + \" chars)\");\n        } catch (e) {\n            Logger.Warn(\"WebXR Body Tracking: clipboard write failed: \" + e + \" — logging snapshot to console instead\");\n            // eslint-disable-next-line no-console\n            console.log(compressed);\n        }\n    }\n\n    /**\n     * Dispose of this tracked body and its resources.\n     * @param disposeMesh If `true`, the body mesh and its skeleton are disposed as well.\n     */\n    public dispose(disposeMesh = false): void {\n        if (this._bodyMesh) {\n            if (disposeMesh) {\n                this._bodyMesh.skeleton?.dispose();\n                this._bodyMesh.dispose(false, true);\n            } else {\n                this._bodyMesh.isVisible = false;\n            }\n        }\n        for (const transform of this._jointTransforms) {\n            transform.dispose();\n        }\n        this._jointTransforms.length = 0;\n        for (const { standaloneNode } of this._unmappedBoneNodes) {\n            standaloneNode.dispose();\n        }\n        this._unmappedBoneNodes = [];\n        this._boneToJointIdx.clear();\n        this._skeleton = null;\n        this._jointHasBone.fill(false);\n        this._jointParentJointIdx.fill(-1);\n        this._skeletonMesh = null;\n        this.onBodyMeshSetObservable.clear();\n    }\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// WebXRBodyTracking — the feature class\n// ────────────────────────────────────────────────────────────────────────────\n\n/**\n * WebXR Body Tracking feature.\n *\n * This feature tracks the user's full-body pose using the\n * [WebXR Body Tracking Module](https://immersive-web.github.io/body-tracking/),\n * which exposes 83 articulated joints covering the torso, arms, hands, legs and feet.\n *\n * ## Quick Start\n *\n * ```typescript\n * // Enable body tracking when creating the default XR experience:\n * const xr = await scene.createDefaultXRExperienceAsync();\n * const bodyTracking = xr.baseExperience.featuresManager.enableFeature(\n *     WebXRFeatureName.BODY_TRACKING,\n *     \"latest\",\n *     {\n *         bodyMesh: myRiggedBodyMesh,\n *         rigMapping: {\n *             \"hips\": \"Bip01_Pelvis\",\n *             \"spine-lower\": \"Bip01_Spine\",\n *             // … one entry per joint you want to drive …\n *         },\n *     } as IWebXRBodyTrackingOptions,\n * );\n *\n * // React to tracking changes:\n * bodyTracking.onBodyTrackingStartedObservable.add((trackedBody) => {\n *     console.log(\"Body tracking started\");\n * });\n * bodyTracking.onBodyTrackingFrameUpdateObservable.add((trackedBody) => {\n *     // The tracked body's joint transforms are already up-to-date.\n * });\n * ```\n *\n * ## How It Works\n *\n * 1. The feature requests the `\"body-tracking\"` native WebXR feature at session start.\n * 2. Each frame, if `XRFrame.body` is available, joint poses are filled into a\n *    flat Float32Array via the batch `fillPoses()` API (with a per-joint fallback).\n * 3. The 4 × 4 matrices are converted from WebXR right-handed coordinates to\n *    Babylon.js left-handed coordinates in-place (unless the scene is RHS).\n * 4. Each matrix is decomposed and written to a TransformNode; skeleton bones\n *    linked to those nodes animate the rigged mesh automatically.\n *\n * ## Coordinate System\n *\n * WebXR data arrives in a **right-handed** coordinate system.  Babylon.js\n * defaults to **left-handed**.  The conversion is handled automatically:\n * - Joint matrices are flipped in-place (Z-negation of specific matrix elements).\n * - For meshes authored in a right-handed tool (glTF, Blender, etc.), the bone\n *   data is un-flipped so the skeleton interprets poses correctly.\n * - If you use `scene.useRightHandedSystem = true`, no conversion is applied.\n *\n * @see https://immersive-web.github.io/body-tracking/\n */\nexport class WebXRBodyTracking extends WebXRAbstractFeature {\n    /**\n     * The module's name, used when enabling the feature on the features manager.\n     * Value: `\"xr-body-tracking\"`.\n     */\n    public static readonly Name = WebXRFeatureName.BODY_TRACKING;\n    /**\n     * The (Babylon) version of this module.\n     * This is an integer representing the implementation version.\n     * This number does not correspond to the WebXR specs version.\n     */\n    public static readonly Version = 1;\n\n    /**\n     * Observable fired when body tracking starts (i.e. the first frame where\n     * `XRFrame.body` returns valid data).\n     */\n    public readonly onBodyTrackingStartedObservable: Observable<WebXRTrackedBody> = new Observable();\n\n    /**\n     * Observable fired when body tracking is lost (i.e. `XRFrame.body` becomes\n     * `null` or returns no valid poses after previously tracking).\n     */\n    public readonly onBodyTrackingEndedObservable: Observable<void> = new Observable();\n\n    /**\n     * Observable fired every frame that has valid body tracking data.\n     * At the point of notification, all joint transforms are up-to-date.\n     */\n    public readonly onBodyTrackingFrameUpdateObservable: Observable<WebXRTrackedBody> = new Observable();\n\n    /**\n     * Observable fired when the body mesh has been set via {@link setBodyMesh}\n     * or during initial configuration.\n     */\n    public readonly onBodyMeshSetObservable: Observable<WebXRTrackedBody> = new Observable();\n\n    /** The current tracked body, or null when not tracking. */\n    private _trackedBody: Nullable<WebXRTrackedBody> = null;\n\n    /** True while we have an active body tracking session. */\n    private _isTracking = false;\n\n    /** Observer for world scale changes, so the body mesh can be rescaled. */\n    private _worldScaleObserver: Nullable<Observer<{ previousScaleFactor: number; newScaleFactor: number }>> = null;\n\n    /**\n     * Debug info from the feature-level frame loop.\n     * Shows why `_onXRFrame` did or did not call `updateFromXRFrame`.\n     * @internal\n     */\n    public _lastFrameDebugInfo: string = \"not called\";\n\n    /**\n     * Get the currently tracked body, if any.\n     */\n    public get trackedBody(): Nullable<WebXRTrackedBody> {\n        return this._trackedBody;\n    }\n\n    /**\n     * Returns `true` while body tracking data is actively being received.\n     */\n    public get isTracking(): boolean {\n        return this._isTracking;\n    }\n\n    /**\n     * Construct a new WebXRBodyTracking feature.\n     * @param _xrSessionManager The XR session manager.\n     * @param options Configuration options.\n     */\n    constructor(\n        _xrSessionManager: WebXRSessionManager,\n        /** Configuration options for the body tracking feature. */\n        public readonly options: IWebXRBodyTrackingOptions = {}\n    ) {\n        super(_xrSessionManager);\n        this.xrNativeFeatureName = \"body-tracking\";\n    }\n\n    /**\n     * Attach a rigged body mesh (or replace the current one) at any time.\n     *\n     * This is a convenience method that forwards to the underlying\n     * {@link WebXRTrackedBody.setBodyMesh}.  The body does not need to be\n     * already tracking for this to work — the mesh will be applied once\n     * tracking begins.\n     *\n     * @param bodyMesh The rigged mesh to drive.\n     * @param rigMapping Optional mapping from {@link WebXRBodyJoint} names to bone names.\n     */\n    public setBodyMesh(bodyMesh: AbstractMesh, rigMapping?: XRBodyMeshRigMapping): void {\n        // Store on options so it is picked up on (re-)attach.\n        this.options.bodyMesh = bodyMesh;\n        this.options.rigMapping = rigMapping;\n        if (this._trackedBody) {\n            this._trackedBody.setBodyMesh(bodyMesh, rigMapping);\n            this.onBodyMeshSetObservable.notifyObservers(this._trackedBody);\n        }\n    }\n\n    // ── Attach / Detach ──────────────────────────────────────────────────\n\n    /**\n     * Attach the feature.\n     * Called by the features manager when the XR session initialises.\n     *\n     * Body tracking is a draft WebXR spec.  Some UAs (e.g. Meta Quest) provide\n     * body data on `XRFrame.body` but do not list `\"body-tracking\"` in\n     * `session.enabledFeatures`.  To handle this, we temporarily clear\n     * {@link xrNativeFeatureName} before calling the base `attach()` so the\n     * enabled-features check is skipped, then restore it afterwards.\n     * @returns `true` if attachment succeeded.\n     */\n    public override attach(): boolean {\n        // Temporarily clear the native feature name so super.attach() does\n        // not reject when \"body-tracking\" is absent from enabledFeatures.\n        // The actual data availability is checked every frame in _onXRFrame.\n        const nativeName = this.xrNativeFeatureName;\n        this.xrNativeFeatureName = \"\";\n        const attached = super.attach();\n        this.xrNativeFeatureName = nativeName;\n        if (!attached) {\n            this._lastFrameDebugInfo = \"super.attach() returned false\";\n            return false;\n        }\n\n        // Create the tracked body container (transform nodes etc.).\n        try {\n            let rigMapping = this.options.rigMapping;\n            let aimChildOverrides = this.options.aimChildOverrides;\n            let useBoneOrientationOffsets = this.options.useBoneOrientationOffsets;\n            if (this.options.isMixamoModel && this.options.bodyMesh) {\n                rigMapping = rigMapping ?? _ResolveMixamoRigMapping(this.options.bodyMesh);\n                aimChildOverrides = aimChildOverrides ?? MixamoAimChildOverrides;\n                useBoneOrientationOffsets = useBoneOrientationOffsets ?? true;\n            }\n            this._trackedBody = new WebXRTrackedBody(\n                this._xrSessionManager.scene,\n                this.options.bodyMesh,\n                rigMapping,\n                this.options.jointScaleFactor ?? 1.0,\n                this.options.preserveBindPoseBonePositions ?? false,\n                useBoneOrientationOffsets ?? false,\n                aimChildOverrides,\n                this.options.jointLocalRotationOffset\n            );\n        } catch (e) {\n            this._lastFrameDebugInfo = \"ATTACH ERROR: \" + e;\n            Logger.Warn(\"WebXR Body Tracking: failed to create tracked body: \" + e);\n            return false;\n        }\n\n        // Observe world-scale changes to rescale the body mesh.\n        if (this.options.bodyMesh) {\n            this.options.bodyMesh.scaling.setAll(this._xrSessionManager.worldScalingFactor);\n            this._worldScaleObserver = this._xrSessionManager.onWorldScaleFactorChangedObservable.add((factors) => {\n                if (this.options.bodyMesh) {\n                    this.options.bodyMesh.scaling.scaleInPlace(factors.newScaleFactor / factors.previousScaleFactor);\n                }\n            });\n        }\n\n        this._lastFrameDebugInfo = \"attached OK, waiting for frames\";\n        return true;\n    }\n\n    /**\n     * Detach the feature.\n     * Called by the features manager when the XR session ends.\n     * @returns `true` if detachment succeeded.\n     */\n    public override detach(): boolean {\n        if (!super.detach()) {\n            return false;\n        }\n\n        if (this._isTracking) {\n            this._isTracking = false;\n            this.onBodyTrackingEndedObservable.notifyObservers();\n        }\n\n        if (this._trackedBody) {\n            this._trackedBody.dispose();\n            this._trackedBody = null;\n        }\n\n        if (this._worldScaleObserver) {\n            this._xrSessionManager.onWorldScaleFactorChangedObservable.remove(this._worldScaleObserver);\n            this._worldScaleObserver = null;\n        }\n\n        return true;\n    }\n\n    /**\n     * Dispose this feature and all resources.\n     */\n    public override dispose(): void {\n        super.dispose();\n        this.onBodyTrackingStartedObservable.clear();\n        this.onBodyTrackingEndedObservable.clear();\n        this.onBodyTrackingFrameUpdateObservable.clear();\n        this.onBodyMeshSetObservable.clear();\n    }\n\n    // ── Frame loop ───────────────────────────────────────────────────────\n\n    /**\n     * Called every XR frame by the base class.\n     * Reads body joint data from the XR runtime and updates transforms.\n     * @param xrFrame The current XRFrame.\n     */\n    protected _onXRFrame(xrFrame: XRFrame): void {\n        try {\n            if (!this._trackedBody) {\n                this._lastFrameDebugInfo = \"no trackedBody\";\n                return;\n            }\n\n            const body: XRBody | undefined = xrFrame.body;\n            if (!body) {\n                this._lastFrameDebugInfo = \"no xrFrame.body (hasBody prop:\" + (\"body\" in xrFrame) + \")\";\n                // Tracking lost this frame.\n                if (this._isTracking) {\n                    this._isTracking = false;\n                    this.onBodyTrackingEndedObservable.notifyObservers();\n                }\n                return;\n            }\n\n            this._lastFrameDebugInfo = \"body.size:\" + body.size + \" calling update\";\n\n            const success = this._trackedBody.updateFromXRFrame(xrFrame, this._xrSessionManager.referenceSpace, this._xrSessionManager.scene.activeCamera?.parent ?? null);\n\n            this._lastFrameDebugInfo = \"body.size:\" + body.size + \" update:\" + success + \" | \" + this._trackedBody._lastDebugInfo;\n\n            if (!success) {\n                if (this._isTracking) {\n                    this._isTracking = false;\n                    this.onBodyTrackingEndedObservable.notifyObservers();\n                }\n                return;\n            }\n\n            // Detect tracking start / continuation.\n            if (!this._isTracking) {\n                this._isTracking = true;\n                this.onBodyTrackingStartedObservable.notifyObservers(this._trackedBody);\n            }\n\n            this.onBodyTrackingFrameUpdateObservable.notifyObservers(this._trackedBody);\n        } catch (e) {\n            // Catch absolutely everything so we never break the XR render loop.\n            this._lastFrameDebugInfo = \"EXCEPTION: \" + e;\n            Logger.Warn(\"WebXR Body Tracking: error in _onXRFrame: \" + e);\n        }\n    }\n\n    /**\n     * Returns the complete ordered list of body joint names tracked by this feature.\n     * Useful for iterating over all joints or building UI.\n     */\n    public static get AllBodyJoints(): readonly WebXRBodyJoint[] {\n        return BodyJointReferenceArray;\n    }\n\n    /**\n     * Capture a single-frame snapshot of all 83 joints and copy it to the\n     * clipboard.  Call this from a playground button or the console while\n     * wearing the headset:\n     *\n     * ```typescript\n     * bodyTracking.snapshotFrameToClipboard();\n     * ```\n     *\n     * The JSON can later be loaded offline to replay the bone-local\n     * computation without a headset.\n     * @returns A promise that resolves when the copy completes, or rejects\n     *   if no body is currently tracked.\n     */\n    public async snapshotFrameToClipboardAsync(): Promise<void> {\n        if (!this._trackedBody) {\n            Logger.Warn(\"WebXR Body Tracking: no tracked body to snapshot\");\n            return;\n        }\n        return await this._trackedBody.snapshotFrameToClipboardAsync();\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for webXRBodyTracking.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterWebXRBodyTracking(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    // ────────────────────────────────────────────────────────────────────────────\n    // Feature registration\n    // ────────────────────────────────────────────────────────────────────────────\n\n    // Register the feature so it can be enabled via the features manager:\n    //   featuresManager.enableFeature(WebXRFeatureName.BODY_TRACKING, \"latest\", options);\n    WebXRFeaturesManager.AddWebXRFeature(\n        WebXRBodyTracking.Name,\n        (xrSessionManager, options) => {\n            return () => new WebXRBodyTracking(xrSessionManager, options);\n        },\n        WebXRBodyTracking.Version,\n        false\n    );\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { Observable } from \"../../Misc/observable.pure\";\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"../webXRFeaturesManager\";\nimport { type WebXRSessionManager } from \"../webXRSessionManager\";\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\n\ninterface IWebXRTrackedSourcesSession extends XRSession {\n    readonly trackedSources: XRInputSourceArray;\n}\n\nfunction IsTrackedSourcesSession(session: XRSession): session is IWebXRTrackedSourcesSession {\n    return \"trackedSources\" in session;\n}\n\n/**\n * Exposes input sources that the XR runtime continues tracking while they are not active input sources.\n *\n * Tracked sources are intentionally kept separate from `XRSession.inputSources` and Babylon's normal\n * WebXR input/controller pipeline.\n * @see https://immersive-web.github.io/webxr/#dom-xrsession-trackedsources\n * @see https://playground.babylonjs.com/#JRBQVL#0\n */\nexport class WebXRTrackedSources extends WebXRAbstractFeature {\n    private readonly _trackedSources: XRInputSource[] = [];\n    private _trackedSourcesSession: IWebXRTrackedSourcesSession | null = null;\n\n    /**\n     * The module's name.\n     */\n    public static readonly Name = WebXRFeatureName.TRACKED_SOURCES;\n\n    /**\n     * The Babylon version of this module.\n     *\n     * This number does not correspond to the WebXR specification version.\n     */\n    public static readonly Version = 1;\n\n    /**\n     * Notifies observers when a source enters the feature's current tracked source set.\n     */\n    public readonly onTrackedSourceAddedObservable: Observable<XRInputSource> = new Observable();\n\n    /**\n     * Notifies observers when a source leaves the feature's current tracked source set, including on detach.\n     */\n    public readonly onTrackedSourceRemovedObservable: Observable<XRInputSource> = new Observable();\n\n    /**\n     * Creates a WebXR tracked sources feature.\n     * @param _xrSessionManager The WebXR session manager.\n     */\n    constructor(_xrSessionManager: WebXRSessionManager) {\n        super(_xrSessionManager);\n        this.xrNativeFeatureName = \"tracked-sources\";\n    }\n\n    /**\n     * Gets a copy of the sources currently reported by `XRSession.trackedSources`.\n     *\n     * These sources are not added to `XRSession.inputSources` or Babylon's controller collection.\n     */\n    public get trackedSources(): ReadonlyArray<XRInputSource> {\n        return this._trackedSources.slice();\n    }\n\n    /**\n     * Attaches the feature to the active XR session.\n     * @param force Whether to reattach when the feature is already attached.\n     * @returns `true` when attachment succeeds; otherwise `false`.\n     */\n    public override attach(force?: boolean): boolean {\n        const session = this._xrSessionManager.session;\n        if (!session || !IsTrackedSourcesSession(session)) {\n            return this._disableAutoAttach(\"XRSession.trackedSources is not supported by this XR runtime.\");\n        }\n\n        if (!super.attach(force)) {\n            return false;\n        }\n\n        this._trackedSourcesSession = session;\n        session.addEventListener(\"trackedsourceschange\", this._onTrackedSourcesChanged);\n        this._synchronizeTrackedSources();\n        return true;\n    }\n\n    /**\n     * Detaches the feature and clears its tracked source state.\n     * @returns `true` when detachment succeeds; otherwise `false`.\n     */\n    public override detach(): boolean {\n        if (!super.detach()) {\n            return false;\n        }\n\n        this._trackedSourcesSession?.removeEventListener(\"trackedsourceschange\", this._onTrackedSourcesChanged);\n        this._trackedSourcesSession = null;\n        this._clearTrackedSources();\n        return true;\n    }\n\n    /**\n     * Disposes the feature and clears its observables.\n     */\n    public override dispose(): void {\n        super.dispose();\n        this.onTrackedSourceAddedObservable.clear();\n        this.onTrackedSourceRemovedObservable.clear();\n    }\n\n    protected override _onXRFrame(): void {}\n\n    private _onTrackedSourcesChanged = (): void => {\n        this._synchronizeTrackedSources();\n    };\n\n    private _synchronizeTrackedSources(): void {\n        const session = this._trackedSourcesSession;\n        if (!this.attached || !session) {\n            return;\n        }\n\n        for (let index = 0; index < this._trackedSources.length;) {\n            const trackedSource = this._trackedSources[index];\n            let isStillTracked = false;\n            for (const nativeTrackedSource of session.trackedSources) {\n                if (nativeTrackedSource === trackedSource) {\n                    isStillTracked = true;\n                    break;\n                }\n            }\n\n            if (isStillTracked) {\n                index++;\n            } else {\n                this._trackedSources.splice(index, 1);\n                this.onTrackedSourceRemovedObservable.notifyObservers(trackedSource);\n            }\n        }\n\n        for (const trackedSource of session.trackedSources) {\n            if (this._trackedSources.indexOf(trackedSource) === -1) {\n                this._trackedSources.push(trackedSource);\n                this.onTrackedSourceAddedObservable.notifyObservers(trackedSource);\n            }\n        }\n\n        let index = 0;\n        for (const trackedSource of session.trackedSources) {\n            this._trackedSources[index++] = trackedSource;\n        }\n    }\n\n    private _clearTrackedSources(): void {\n        while (this._trackedSources.length > 0) {\n            const trackedSource = this._trackedSources.shift();\n            if (trackedSource) {\n                this.onTrackedSourceRemovedObservable.notifyObservers(trackedSource);\n            }\n        }\n    }\n}\n\nlet _Registered = false;\n\n/**\n * Registers the WebXR tracked sources feature.\n *\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterWebXRTrackedSources(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    WebXRFeaturesManager.AddWebXRFeature(\n        WebXRTrackedSources.Name,\n        (xrSessionManager) => {\n            return () => new WebXRTrackedSources(xrSessionManager);\n        },\n        WebXRTrackedSources.Version\n    );\n}\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    WebXRAbstractMotionController,\r\n    type IMotionControllerLayoutMap,\r\n    type IMinimalMotionControllerObject,\r\n    type MotionControllerHandedness,\r\n} from \"./webXRAbstractMotionController\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { WebXRMotionControllerManager } from \"./webXRMotionControllerManager.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n/**\r\n * A generic hand controller class that supports select and a secondary grasp\r\n */\r\nexport class WebXRGenericHandController extends WebXRAbstractMotionController {\r\n    public profileId = \"generic-hand-select-grasp\";\r\n\r\n    /**\r\n     * Create a new hand controller object, without loading a controller model\r\n     * @param scene the scene to use to create this controller\r\n     * @param gamepadObject the corresponding gamepad object\r\n     * @param handedness the handedness of the controller\r\n     */\r\n    constructor(scene: Scene, gamepadObject: IMinimalMotionControllerObject, handedness: MotionControllerHandedness) {\r\n        // Don't load the controller model - for now, hands have no real model.\r\n        super(scene, GenericHandSelectGraspProfile[handedness], gamepadObject, handedness, true);\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        return {\r\n            filename: \"generic.babylon\",\r\n            path: \"https://controllers.babylonjs.com/generic/\",\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        return true;\r\n    }\r\n\r\n    protected _processLoadedModel(_meshes: AbstractMesh[]): void {\r\n        // no-op\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        // no-op\r\n    }\r\n\r\n    protected _updateModel(): void {\r\n        // no-op\r\n    }\r\n}\r\n\r\n// https://github.com/immersive-web/webxr-input-profiles/blob/main/packages/registry/profiles/generic/generic-hand-select-grasp.json\r\nconst GenericHandSelectGraspProfile: IMotionControllerLayoutMap = {\r\n    left: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr-standard-trigger\",\r\n                visualResponses: {},\r\n            },\r\n            grasp: {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"grasp\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"generic-hand-select-grasp-left\",\r\n        assetPath: \"left.glb\",\r\n    },\r\n    right: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr-standard-trigger\",\r\n                visualResponses: {},\r\n            },\r\n            grasp: {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"grasp\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"generic-hand-select-grasp-right\",\r\n        assetPath: \"right.glb\",\r\n    },\r\n    none: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr-standard-trigger\",\r\n                visualResponses: {},\r\n            },\r\n            grasp: {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"grasp\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"generic-hand-select-grasp-none\",\r\n        assetPath: \"none.glb\",\r\n    },\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRGenericHandController.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRGenericHandController(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the profiles\r\n    WebXRMotionControllerManager.RegisterController(\"generic-hand-select-grasp\", (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXRGenericHandController(scene, <any>xrInput.gamepad, xrInput.handedness);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    WebXRAbstractMotionController,\r\n    type IMinimalMotionControllerObject,\r\n    type MotionControllerHandedness,\r\n    type IMotionControllerLayoutMap,\r\n} from \"./webXRAbstractMotionController\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { SceneLoader } from \"../../Loading/sceneLoader\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { WebXRMotionControllerManager } from \"./webXRMotionControllerManager.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * The motion controller class for all microsoft mixed reality controllers\r\n */\r\nexport class WebXRMicrosoftMixedRealityController extends WebXRAbstractMotionController {\r\n    // use this in the future - https://github.com/immersive-web/webxr-input-profiles/tree/master/packages/assets/profiles/microsoft\r\n    protected readonly _mapping = {\r\n        defaultButton: {\r\n            valueNodeName: \"VALUE\",\r\n            unpressedNodeName: \"UNPRESSED\",\r\n            pressedNodeName: \"PRESSED\",\r\n        },\r\n        defaultAxis: {\r\n            valueNodeName: \"VALUE\",\r\n            minNodeName: \"MIN\",\r\n            maxNodeName: \"MAX\",\r\n        },\r\n        buttons: {\r\n            \"xr-standard-trigger\": {\r\n                rootNodeName: \"SELECT\",\r\n                componentProperty: \"button\",\r\n                states: [\"default\", \"touched\", \"pressed\"],\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                rootNodeName: \"GRASP\",\r\n                componentProperty: \"state\",\r\n                states: [\"pressed\"],\r\n            },\r\n            \"xr-standard-touchpad\": {\r\n                rootNodeName: \"TOUCHPAD_PRESS\",\r\n                labelAnchorNodeName: \"squeeze-label\",\r\n                touchPointNodeName: \"TOUCH\", // TODO - use this for visual feedback\r\n            },\r\n            \"xr-standard-thumbstick\": {\r\n                rootNodeName: \"THUMBSTICK_PRESS\",\r\n                componentProperty: \"state\",\r\n                states: [\"pressed\"],\r\n            },\r\n        },\r\n        axes: {\r\n            \"xr-standard-touchpad\": {\r\n                \"x-axis\": {\r\n                    rootNodeName: \"TOUCHPAD_TOUCH_X\",\r\n                },\r\n                \"y-axis\": {\r\n                    rootNodeName: \"TOUCHPAD_TOUCH_Y\",\r\n                },\r\n            },\r\n            \"xr-standard-thumbstick\": {\r\n                \"x-axis\": {\r\n                    rootNodeName: \"THUMBSTICK_X\",\r\n                },\r\n                \"y-axis\": {\r\n                    rootNodeName: \"THUMBSTICK_Y\",\r\n                },\r\n            },\r\n        },\r\n    };\r\n\r\n    /**\r\n     * The base url used to load the left and right controller models\r\n     */\r\n    public static MODEL_BASE_URL: string = \"https://controllers.babylonjs.com/microsoft/\";\r\n    /**\r\n     * The name of the left controller model file\r\n     */\r\n    public static MODEL_LEFT_FILENAME: string = \"left.glb\";\r\n    /**\r\n     * The name of the right controller model file\r\n     */\r\n    public static MODEL_RIGHT_FILENAME: string = \"right.glb\";\r\n\r\n    public profileId = \"microsoft-mixed-reality\";\r\n\r\n    constructor(scene: Scene, gamepadObject: IMinimalMotionControllerObject, handedness: MotionControllerHandedness) {\r\n        super(scene, MixedRealityProfile[handedness], gamepadObject, handedness);\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        let filename: string;\r\n        if (this.handedness === \"left\") {\r\n            filename = WebXRMicrosoftMixedRealityController.MODEL_LEFT_FILENAME;\r\n        } else {\r\n            // Right is the default if no hand is specified\r\n            filename = WebXRMicrosoftMixedRealityController.MODEL_RIGHT_FILENAME;\r\n        }\r\n\r\n        const device = \"default\";\r\n        const path = WebXRMicrosoftMixedRealityController.MODEL_BASE_URL + device + \"/\";\r\n        return {\r\n            filename,\r\n            path,\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        const glbLoaded = SceneLoader.IsPluginForExtensionAvailable(\".glb\");\r\n        if (!glbLoaded) {\r\n            Logger.Warn(\"glTF / glb loaded was not registered, using generic controller instead\");\r\n        }\r\n        return glbLoaded;\r\n    }\r\n\r\n    protected _processLoadedModel(_meshes: AbstractMesh[]): void {\r\n        if (!this.rootMesh) {\r\n            return;\r\n        }\r\n\r\n        // Button Meshes\r\n        const ids = this.getComponentIds();\r\n        for (let i = 0; i < ids.length; i++) {\r\n            const id = ids[i];\r\n            if (this.disableAnimation) {\r\n                continue;\r\n            }\r\n            if (id && this.rootMesh) {\r\n                const buttonMap = (<any>this._mapping.buttons)[id];\r\n                const buttonMeshName = buttonMap.rootNodeName;\r\n                if (!buttonMeshName) {\r\n                    Logger.Log(\"Skipping unknown button at index: \" + i + \" with mapped name: \" + id);\r\n                    continue;\r\n                }\r\n\r\n                const buttonMesh = this._getChildByName(this.rootMesh, buttonMeshName);\r\n                if (!buttonMesh) {\r\n                    Logger.Warn(\"Missing button mesh with name: \" + buttonMeshName);\r\n                    continue;\r\n                }\r\n\r\n                buttonMap.valueMesh = this._getImmediateChildByName(buttonMesh, this._mapping.defaultButton.valueNodeName);\r\n                buttonMap.pressedMesh = this._getImmediateChildByName(buttonMesh, this._mapping.defaultButton.pressedNodeName);\r\n                buttonMap.unpressedMesh = this._getImmediateChildByName(buttonMesh, this._mapping.defaultButton.unpressedNodeName);\r\n\r\n                if (buttonMap.valueMesh && buttonMap.pressedMesh && buttonMap.unpressedMesh) {\r\n                    const comp = this.getComponent(id);\r\n                    if (comp) {\r\n                        comp.onButtonStateChangedObservable.add(\r\n                            (component) => {\r\n                                this._lerpTransform(buttonMap, component.value);\r\n                            },\r\n                            undefined,\r\n                            true\r\n                        );\r\n                    }\r\n                } else {\r\n                    // If we didn't find the mesh, it simply means this button won't have transforms applied as mapped button value changes.\r\n                    Logger.Warn(\"Missing button submesh under mesh with name: \" + buttonMeshName);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Axis Meshes\r\n        for (const id of ids) {\r\n            const comp = this.getComponent(id);\r\n            if (!comp.isAxes()) {\r\n                continue;\r\n            }\r\n\r\n            const axisArray = [\"x-axis\", \"y-axis\"];\r\n\r\n            for (const axis of axisArray) {\r\n                if (!this.rootMesh) {\r\n                    continue;\r\n                }\r\n                const axisMap = (<any>this._mapping.axes)[id][axis];\r\n\r\n                const axisMesh = this._getChildByName(this.rootMesh, axisMap.rootNodeName);\r\n                if (!axisMesh) {\r\n                    Logger.Warn(\"Missing axis mesh with name: \" + axisMap.rootNodeName);\r\n                    continue;\r\n                }\r\n\r\n                axisMap.valueMesh = this._getImmediateChildByName(axisMesh, this._mapping.defaultAxis.valueNodeName);\r\n                axisMap.minMesh = this._getImmediateChildByName(axisMesh, this._mapping.defaultAxis.minNodeName);\r\n                axisMap.maxMesh = this._getImmediateChildByName(axisMesh, this._mapping.defaultAxis.maxNodeName);\r\n\r\n                if (axisMap.valueMesh && axisMap.minMesh && axisMap.maxMesh) {\r\n                    if (comp) {\r\n                        comp.onAxisValueChangedObservable.add(\r\n                            (axisValues) => {\r\n                                const value = axis === \"x-axis\" ? axisValues.x : axisValues.y;\r\n                                this._lerpTransform(axisMap, value, true);\r\n                            },\r\n                            undefined,\r\n                            true\r\n                        );\r\n                    }\r\n                } else {\r\n                    // If we didn't find the mesh, it simply means this button won't have transforms applied as mapped button value changes.\r\n                    Logger.Warn(\"Missing axis submesh under mesh with name: \" + axisMap.rootNodeName);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        this.rootMesh = new Mesh(this.profileId + \" \" + this.handedness, this.scene);\r\n        this.rootMesh.isPickable = false;\r\n        let rootMesh;\r\n        // Find the root node in the loaded glTF scene, and attach it as a child of 'parentMesh'\r\n        for (let i = 0; i < meshes.length; i++) {\r\n            const mesh = meshes[i];\r\n\r\n            mesh.isPickable = false;\r\n\r\n            if (!mesh.parent) {\r\n                // Handle root node, attach to the new parentMesh\r\n                rootMesh = mesh;\r\n            }\r\n        }\r\n\r\n        if (rootMesh) {\r\n            rootMesh.setParent(this.rootMesh);\r\n        }\r\n\r\n        if (!this.scene.useRightHandedSystem) {\r\n            this.rootMesh.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);\r\n        }\r\n    }\r\n\r\n    protected _updateModel(): void {\r\n        // no-op. model is updated using observables.\r\n    }\r\n}\r\n\r\n// https://github.com/immersive-web/webxr-input-profiles/blob/master/packages/registry/profiles/microsoft/microsoft-mixed-reality.json\r\nconst MixedRealityProfile: IMotionControllerLayoutMap = {\r\n    left: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {\r\n                    xr_standard_trigger_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_trigger_pressed_value\",\r\n                        minNodeName: \"xr_standard_trigger_pressed_min\",\r\n                        maxNodeName: \"xr_standard_trigger_pressed_max\",\r\n                    },\r\n                },\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {\r\n                    xr_standard_squeeze_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_squeeze_pressed_value\",\r\n                        minNodeName: \"xr_standard_squeeze_pressed_min\",\r\n                        maxNodeName: \"xr_standard_squeeze_pressed_max\",\r\n                    },\r\n                },\r\n            },\r\n            \"xr-standard-touchpad\": {\r\n                type: \"touchpad\",\r\n                gamepadIndices: {\r\n                    button: 2,\r\n                    xAxis: 0,\r\n                    yAxis: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_touchpad\",\r\n                visualResponses: {\r\n                    xr_standard_touchpad_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_pressed_value\",\r\n                        minNodeName: \"xr_standard_touchpad_pressed_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_pressed_max\",\r\n                    },\r\n                    xr_standard_touchpad_xaxis_pressed: {\r\n                        componentProperty: \"xAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_xaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_touchpad_xaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_xaxis_pressed_max\",\r\n                    },\r\n                    xr_standard_touchpad_yaxis_pressed: {\r\n                        componentProperty: \"yAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_yaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_touchpad_yaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_yaxis_pressed_max\",\r\n                    },\r\n                    xr_standard_touchpad_xaxis_touched: {\r\n                        componentProperty: \"xAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_xaxis_touched_value\",\r\n                        minNodeName: \"xr_standard_touchpad_xaxis_touched_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_xaxis_touched_max\",\r\n                    },\r\n                    xr_standard_touchpad_yaxis_touched: {\r\n                        componentProperty: \"yAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_yaxis_touched_value\",\r\n                        minNodeName: \"xr_standard_touchpad_yaxis_touched_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_yaxis_touched_max\",\r\n                    },\r\n                    xr_standard_touchpad_axes_touched: {\r\n                        componentProperty: \"state\",\r\n                        states: [\"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"visibility\",\r\n                        valueNodeName: \"xr_standard_touchpad_axes_touched_value\",\r\n                    },\r\n                },\r\n                touchPointNodeName: \"xr_standard_touchpad_axes_touched_value\",\r\n            },\r\n            \"xr-standard-thumbstick\": {\r\n                type: \"thumbstick\",\r\n                gamepadIndices: {\r\n                    button: 3,\r\n                    xAxis: 2,\r\n                    yAxis: 3,\r\n                },\r\n                rootNodeName: \"xr_standard_thumbstick\",\r\n                visualResponses: {\r\n                    xr_standard_thumbstick_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_thumbstick_pressed_value\",\r\n                        minNodeName: \"xr_standard_thumbstick_pressed_min\",\r\n                        maxNodeName: \"xr_standard_thumbstick_pressed_max\",\r\n                    },\r\n                    xr_standard_thumbstick_xaxis_pressed: {\r\n                        componentProperty: \"xAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_thumbstick_xaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_thumbstick_xaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_thumbstick_xaxis_pressed_max\",\r\n                    },\r\n                    xr_standard_thumbstick_yaxis_pressed: {\r\n                        componentProperty: \"yAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_thumbstick_yaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_thumbstick_yaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_thumbstick_yaxis_pressed_max\",\r\n                    },\r\n                },\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"microsoft-mixed-reality-left\",\r\n        assetPath: \"left.glb\",\r\n    },\r\n    right: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {\r\n                    xr_standard_trigger_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_trigger_pressed_value\",\r\n                        minNodeName: \"xr_standard_trigger_pressed_min\",\r\n                        maxNodeName: \"xr_standard_trigger_pressed_max\",\r\n                    },\r\n                },\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {\r\n                    xr_standard_squeeze_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_squeeze_pressed_value\",\r\n                        minNodeName: \"xr_standard_squeeze_pressed_min\",\r\n                        maxNodeName: \"xr_standard_squeeze_pressed_max\",\r\n                    },\r\n                },\r\n            },\r\n            \"xr-standard-touchpad\": {\r\n                type: \"touchpad\",\r\n                gamepadIndices: {\r\n                    button: 2,\r\n                    xAxis: 0,\r\n                    yAxis: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_touchpad\",\r\n                visualResponses: {\r\n                    xr_standard_touchpad_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_pressed_value\",\r\n                        minNodeName: \"xr_standard_touchpad_pressed_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_pressed_max\",\r\n                    },\r\n                    xr_standard_touchpad_xaxis_pressed: {\r\n                        componentProperty: \"xAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_xaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_touchpad_xaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_xaxis_pressed_max\",\r\n                    },\r\n                    xr_standard_touchpad_yaxis_pressed: {\r\n                        componentProperty: \"yAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_yaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_touchpad_yaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_yaxis_pressed_max\",\r\n                    },\r\n                    xr_standard_touchpad_xaxis_touched: {\r\n                        componentProperty: \"xAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_xaxis_touched_value\",\r\n                        minNodeName: \"xr_standard_touchpad_xaxis_touched_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_xaxis_touched_max\",\r\n                    },\r\n                    xr_standard_touchpad_yaxis_touched: {\r\n                        componentProperty: \"yAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_touchpad_yaxis_touched_value\",\r\n                        minNodeName: \"xr_standard_touchpad_yaxis_touched_min\",\r\n                        maxNodeName: \"xr_standard_touchpad_yaxis_touched_max\",\r\n                    },\r\n                    xr_standard_touchpad_axes_touched: {\r\n                        componentProperty: \"state\",\r\n                        states: [\"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"visibility\",\r\n                        valueNodeName: \"xr_standard_touchpad_axes_touched_value\",\r\n                    },\r\n                },\r\n                touchPointNodeName: \"xr_standard_touchpad_axes_touched_value\",\r\n            },\r\n            \"xr-standard-thumbstick\": {\r\n                type: \"thumbstick\",\r\n                gamepadIndices: {\r\n                    button: 3,\r\n                    xAxis: 2,\r\n                    yAxis: 3,\r\n                },\r\n                rootNodeName: \"xr_standard_thumbstick\",\r\n                visualResponses: {\r\n                    xr_standard_thumbstick_pressed: {\r\n                        componentProperty: \"button\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_thumbstick_pressed_value\",\r\n                        minNodeName: \"xr_standard_thumbstick_pressed_min\",\r\n                        maxNodeName: \"xr_standard_thumbstick_pressed_max\",\r\n                    },\r\n                    xr_standard_thumbstick_xaxis_pressed: {\r\n                        componentProperty: \"xAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_thumbstick_xaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_thumbstick_xaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_thumbstick_xaxis_pressed_max\",\r\n                    },\r\n                    xr_standard_thumbstick_yaxis_pressed: {\r\n                        componentProperty: \"yAxis\",\r\n                        states: [\"default\", \"touched\", \"pressed\"],\r\n                        valueNodeProperty: \"transform\",\r\n                        valueNodeName: \"xr_standard_thumbstick_yaxis_pressed_value\",\r\n                        minNodeName: \"xr_standard_thumbstick_yaxis_pressed_min\",\r\n                        maxNodeName: \"xr_standard_thumbstick_yaxis_pressed_max\",\r\n                    },\r\n                },\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"microsoft-mixed-reality-right\",\r\n        assetPath: \"right.glb\",\r\n    },\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRMicrosoftMixedRealityController.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRMicrosoftMixedRealityController(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the profile\r\n    WebXRMotionControllerManager.RegisterController(\"windows-mixed-reality\", (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXRMicrosoftMixedRealityController(scene, <any>xrInput.gamepad, xrInput.handedness);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    WebXRAbstractMotionController,\r\n    type IMinimalMotionControllerObject,\r\n    type MotionControllerHandedness,\r\n    type IMotionControllerLayoutMap,\r\n} from \"./webXRAbstractMotionController\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { WebXRMotionControllerManager } from \"./webXRMotionControllerManager.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * The motion controller class for oculus touch (quest, rift).\r\n * This class supports legacy mapping as well the standard xr mapping\r\n */\r\nexport class WebXROculusTouchMotionController extends WebXRAbstractMotionController {\r\n    private _modelRootNode: AbstractMesh;\r\n\r\n    /**\r\n     * The base url used to load the left and right controller models\r\n     */\r\n    public static MODEL_BASE_URL: string = \"https://controllers.babylonjs.com/oculus/\";\r\n    /**\r\n     * The name of the left controller model file\r\n     */\r\n    public static MODEL_LEFT_FILENAME: string = \"left.babylon\";\r\n    /**\r\n     * The name of the right controller model file\r\n     */\r\n    public static MODEL_RIGHT_FILENAME: string = \"right.babylon\";\r\n    /**\r\n     * Base Url for the Quest controller model.\r\n     */\r\n    public static QUEST_MODEL_BASE_URL: string = \"https://controllers.babylonjs.com/oculusQuest/\";\r\n\r\n    public profileId = \"oculus-touch\";\r\n\r\n    constructor(\r\n        scene: Scene,\r\n        gamepadObject: IMinimalMotionControllerObject,\r\n        handedness: MotionControllerHandedness,\r\n        _legacyMapping: boolean = false,\r\n        private _forceLegacyControllers: boolean = false\r\n    ) {\r\n        super(scene, OculusTouchLayouts[handedness], gamepadObject, handedness);\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        let filename: string;\r\n        if (this.handedness === \"left\") {\r\n            filename = WebXROculusTouchMotionController.MODEL_LEFT_FILENAME;\r\n        } else {\r\n            // Right is the default if no hand is specified\r\n            filename = WebXROculusTouchMotionController.MODEL_RIGHT_FILENAME;\r\n        }\r\n\r\n        const path = this._isQuest() ? WebXROculusTouchMotionController.QUEST_MODEL_BASE_URL : WebXROculusTouchMotionController.MODEL_BASE_URL;\r\n        return {\r\n            filename,\r\n            path,\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        return true;\r\n    }\r\n\r\n    protected _processLoadedModel(_meshes: AbstractMesh[]): void {\r\n        const isQuest = this._isQuest();\r\n        const triggerDirection = this.handedness === \"right\" ? -1 : 1;\r\n\r\n        const ids = this.getComponentIds();\r\n\r\n        for (const id of ids) {\r\n            const comp = id && this.getComponent(id);\r\n            if (comp) {\r\n                comp.onButtonStateChangedObservable.add(\r\n                    (component) => {\r\n                        if (!this.rootMesh || this.disableAnimation) {\r\n                            return;\r\n                        }\r\n\r\n                        switch (id) {\r\n                            case \"xr-standard-trigger\": // index trigger\r\n                                if (!isQuest) {\r\n                                    (<AbstractMesh>this._modelRootNode.getChildren()[3]).rotation.x = -component.value * 0.2;\r\n                                    (<AbstractMesh>this._modelRootNode.getChildren()[3]).position.y = -component.value * 0.005;\r\n                                    (<AbstractMesh>this._modelRootNode.getChildren()[3]).position.z = -component.value * 0.005;\r\n                                }\r\n                                return;\r\n                            case \"xr-standard-squeeze\": // secondary trigger\r\n                                if (!isQuest) {\r\n                                    (<AbstractMesh>this._modelRootNode.getChildren()[4]).position.x = triggerDirection * component.value * 0.0035;\r\n                                }\r\n                                return;\r\n                            case \"xr-standard-thumbstick\": // thumbstick\r\n                                return;\r\n                            case \"a-button\":\r\n                            case \"x-button\":\r\n                                if (!isQuest) {\r\n                                    if (component.pressed) {\r\n                                        (<AbstractMesh>this._modelRootNode.getChildren()[1]).position.y = -0.001;\r\n                                    } else {\r\n                                        (<AbstractMesh>this._modelRootNode.getChildren()[1]).position.y = 0;\r\n                                    }\r\n                                }\r\n                                return;\r\n                            case \"b-button\":\r\n                            case \"y-button\":\r\n                                if (!isQuest) {\r\n                                    if (component.pressed) {\r\n                                        (<AbstractMesh>this._modelRootNode.getChildren()[2]).position.y = -0.001;\r\n                                    } else {\r\n                                        (<AbstractMesh>this._modelRootNode.getChildren()[2]).position.y = 0;\r\n                                    }\r\n                                }\r\n                                return;\r\n                        }\r\n                    },\r\n                    undefined,\r\n                    true\r\n                );\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        this.rootMesh = new Mesh(this.profileId + \" \" + this.handedness, this.scene);\r\n        if (!this.scene.useRightHandedSystem) {\r\n            this.rootMesh.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);\r\n        }\r\n\r\n        for (const mesh of meshes) {\r\n            mesh.isPickable = false;\r\n        }\r\n        if (this._isQuest()) {\r\n            this._modelRootNode = meshes[0];\r\n        } else {\r\n            this._modelRootNode = meshes[1];\r\n            this.rootMesh.position.y = 0.034;\r\n            this.rootMesh.position.z = 0.052;\r\n        }\r\n        this._modelRootNode.parent = this.rootMesh;\r\n    }\r\n\r\n    protected _updateModel(): void {\r\n        // no-op. model is updated using observables.\r\n    }\r\n\r\n    /**\r\n     * Is this the new type of oculus touch. At the moment both have the same profile and it is impossible to differentiate\r\n     * between the touch and touch 2.\r\n     * @returns true if this is the new type of oculus touch controllers.\r\n     */\r\n    private _isQuest() {\r\n        // this is SADLY the only way to currently check. Until proper profiles will be available.\r\n        return !!navigator.userAgent.match(/Quest/gi) && !this._forceLegacyControllers;\r\n    }\r\n}\r\n\r\nconst OculusTouchLayouts: IMotionControllerLayoutMap = {\r\n    left: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-thumbstick\": {\r\n                type: \"thumbstick\",\r\n                gamepadIndices: {\r\n                    button: 3,\r\n                    xAxis: 2,\r\n                    yAxis: 3,\r\n                },\r\n                rootNodeName: \"xr_standard_thumbstick\",\r\n                visualResponses: {},\r\n            },\r\n            \"x-button\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"x_button\",\r\n                visualResponses: {},\r\n            },\r\n            \"y-button\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 5,\r\n                },\r\n                rootNodeName: \"y_button\",\r\n                visualResponses: {},\r\n            },\r\n            thumbrest: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 6,\r\n                },\r\n                rootNodeName: \"thumbrest\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"oculus-touch-v2-left\",\r\n        assetPath: \"left.glb\",\r\n    },\r\n    right: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-thumbstick\": {\r\n                type: \"thumbstick\",\r\n                gamepadIndices: {\r\n                    button: 3,\r\n                    xAxis: 2,\r\n                    yAxis: 3,\r\n                },\r\n                rootNodeName: \"xr_standard_thumbstick\",\r\n                visualResponses: {},\r\n            },\r\n            \"a-button\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"a_button\",\r\n                visualResponses: {},\r\n            },\r\n            \"b-button\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 5,\r\n                },\r\n                rootNodeName: \"b_button\",\r\n                visualResponses: {},\r\n            },\r\n            thumbrest: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 6,\r\n                },\r\n                rootNodeName: \"thumbrest\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"oculus-touch-v2-right\",\r\n        assetPath: \"right.glb\",\r\n    },\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXROculusTouchMotionController.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXROculusTouchMotionController(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the profile\r\n    WebXRMotionControllerManager.RegisterController(\"oculus-touch\", (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXROculusTouchMotionController(scene, <any>xrInput.gamepad, xrInput.handedness);\r\n    });\r\n\r\n    WebXRMotionControllerManager.RegisterController(\"oculus-touch-legacy\", (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXROculusTouchMotionController(scene, <any>xrInput.gamepad, xrInput.handedness, true);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    WebXRAbstractMotionController,\r\n    type IMotionControllerLayoutMap,\r\n    type IMinimalMotionControllerObject,\r\n    type MotionControllerHandedness,\r\n} from \"./webXRAbstractMotionController\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { WebXRMotionControllerManager } from \"./webXRMotionControllerManager.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n/**\r\n * Oculus hand controller class that supports microgestures\r\n */\r\nexport class WebXROculusHandController extends WebXRAbstractMotionController {\r\n    public profileId = \"oculus-hand\";\r\n\r\n    /**\r\n     * Create a new hand controller object, without loading a controller model\r\n     * @param scene the scene to use to create this controller\r\n     * @param gamepadObject the corresponding gamepad object\r\n     * @param handedness the handedness of the controller\r\n     */\r\n    constructor(scene: Scene, gamepadObject: IMinimalMotionControllerObject, handedness: MotionControllerHandedness) {\r\n        // Don't load the controller model - for now, hands have no real model.\r\n        super(scene, OculusHandProfile[handedness], gamepadObject, handedness, true);\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        return {\r\n            filename: \"generic.babylon\",\r\n            path: \"https://controllers.babylonjs.com/generic/\",\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        return true;\r\n    }\r\n\r\n    protected _processLoadedModel(_meshes: AbstractMesh[]): void {\r\n        // no-op\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        // no-op\r\n    }\r\n\r\n    protected _updateModel(): void {\r\n        // no-op\r\n    }\r\n}\r\n\r\n// https://github.com/immersive-web/webxr-input-profiles/blob/main/packages/registry/profiles/oculus/oculus-hand.json\r\nconst OculusHandProfile: IMotionControllerLayoutMap = {\r\n    left: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr-standard-trigger\",\r\n                visualResponses: {},\r\n            },\r\n            menu: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"menu\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-left\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 5,\r\n                },\r\n                rootNodeName: \"swipe-left\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-right\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 6,\r\n                },\r\n                rootNodeName: \"swipe-right\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-forward\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 7,\r\n                },\r\n                rootNodeName: \"swipe-forward\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-backward\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 8,\r\n                },\r\n                rootNodeName: \"swipe-backward\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"tap-thumb\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 9,\r\n                },\r\n                rootNodeName: \"tap-thumb\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"oculus-hand-left\",\r\n        assetPath: \"left.glb\",\r\n    },\r\n    right: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr-standard-trigger\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-left\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 5,\r\n                },\r\n                rootNodeName: \"swipe-left\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-right\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 6,\r\n                },\r\n                rootNodeName: \"swipe-right\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-forward\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 7,\r\n                },\r\n                rootNodeName: \"swipe-forward\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-backward\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 8,\r\n                },\r\n                rootNodeName: \"swipe-backward\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"tap-thumb\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 9,\r\n                },\r\n                rootNodeName: \"tap-thumb\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"oculus-hand-right\",\r\n        assetPath: \"right.glb\",\r\n    },\r\n    none: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr-standard-trigger\",\r\n                visualResponses: {},\r\n            },\r\n            menu: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"menu\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-left\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 5,\r\n                },\r\n                rootNodeName: \"swipe-left\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-right\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 6,\r\n                },\r\n                rootNodeName: \"swipe-right\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-forward\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 7,\r\n                },\r\n                rootNodeName: \"swipe-forward\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"swipe-backward\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 8,\r\n                },\r\n                rootNodeName: \"swipe-backward\",\r\n                visualResponses: {},\r\n            },\r\n            // eslint-disable-next-line @typescript-eslint/naming-convention\r\n            \"tap-thumb\": {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 9,\r\n                },\r\n                rootNodeName: \"tap-thumb\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"oculus-hand-none\",\r\n        assetPath: \"none.glb\",\r\n    },\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXROculusHandController.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXROculusHandController(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the profiles\r\n    WebXRMotionControllerManager.RegisterController(\"oculus-hand\", (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXROculusHandController(scene, <any>xrInput.gamepad, xrInput.handedness);\r\n    });\r\n}\r\n","/** This file must only contain pure code and pure imports */\r\n\r\nimport {\r\n    WebXRAbstractMotionController,\r\n    type IMotionControllerLayoutMap,\r\n    type IMinimalMotionControllerObject,\r\n    type MotionControllerHandedness,\r\n} from \"./webXRAbstractMotionController\";\r\n\r\nimport { type AbstractMesh } from \"../../Meshes/abstractMesh.pure\";\r\nimport { Mesh } from \"../../Meshes/mesh.pure\";\r\nimport { Quaternion } from \"../../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { WebXRMotionControllerManager } from \"./webXRMotionControllerManager.pure\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\n/**\r\n * The motion controller class for the standard HTC-Vive controllers\r\n */\r\nexport class WebXRHTCViveMotionController extends WebXRAbstractMotionController {\r\n    private _modelRootNode: AbstractMesh;\r\n\r\n    /**\r\n     * The base url used to load the left and right controller models\r\n     */\r\n    public static MODEL_BASE_URL: string = \"https://controllers.babylonjs.com/vive/\";\r\n    /**\r\n     * File name for the controller model.\r\n     */\r\n    public static MODEL_FILENAME: string = \"wand.babylon\";\r\n\r\n    public profileId = \"htc-vive\";\r\n\r\n    /**\r\n     * Create a new Vive motion controller object\r\n     * @param scene the scene to use to create this controller\r\n     * @param gamepadObject the corresponding gamepad object\r\n     * @param handedness the handedness of the controller\r\n     */\r\n    constructor(scene: Scene, gamepadObject: IMinimalMotionControllerObject, handedness: MotionControllerHandedness) {\r\n        super(scene, HTCViveLayout[handedness], gamepadObject, handedness);\r\n    }\r\n\r\n    protected _getFilenameAndPath(): { filename: string; path: string } {\r\n        const filename = WebXRHTCViveMotionController.MODEL_FILENAME;\r\n        const path = WebXRHTCViveMotionController.MODEL_BASE_URL;\r\n\r\n        return {\r\n            filename,\r\n            path,\r\n        };\r\n    }\r\n\r\n    protected _getModelLoadingConstraints(): boolean {\r\n        return true;\r\n    }\r\n\r\n    protected _processLoadedModel(_meshes: AbstractMesh[]): void {\r\n        const ids = this.getComponentIds();\r\n\r\n        for (const id of ids) {\r\n            const comp = id && this.getComponent(id);\r\n            if (comp) {\r\n                comp.onButtonStateChangedObservable.add(\r\n                    (component) => {\r\n                        if (!this.rootMesh || this.disableAnimation) {\r\n                            return;\r\n                        }\r\n\r\n                        switch (id) {\r\n                            case \"xr-standard-trigger\":\r\n                                (<AbstractMesh>this._modelRootNode.getChildren()[6]).rotation.x = -component.value * 0.15;\r\n                                return;\r\n                            case \"xr-standard-touchpad\":\r\n                                return;\r\n                            case \"xr-standard-squeeze\":\r\n                                return;\r\n                        }\r\n                    },\r\n                    undefined,\r\n                    true\r\n                );\r\n            }\r\n        }\r\n    }\r\n\r\n    protected _setRootMesh(meshes: AbstractMesh[]): void {\r\n        this.rootMesh = new Mesh(this.profileId + \" \" + this.handedness, this.scene);\r\n\r\n        for (const mesh of meshes) {\r\n            mesh.isPickable = false;\r\n        }\r\n        this._modelRootNode = meshes[1];\r\n        this._modelRootNode.parent = this.rootMesh;\r\n        if (!this.scene.useRightHandedSystem) {\r\n            this.rootMesh.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);\r\n        }\r\n    }\r\n\r\n    protected _updateModel(): void {\r\n        // no-op. model is updated using observables.\r\n    }\r\n}\r\n\r\n// WebXRMotionControllerManager.RegisterController(\"htc-vive-legacy\", (xrInput: XRInputSource, scene: Scene) => {\r\n//     return new WebXRHTCViveMotionController(scene, <any>(xrInput.gamepad), xrInput.handedness, true);\r\n// });\r\n\r\nconst HTCViveLayout: IMotionControllerLayoutMap = {\r\n    left: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-touchpad\": {\r\n                type: \"touchpad\",\r\n                gamepadIndices: {\r\n                    button: 2,\r\n                    xAxis: 0,\r\n                    yAxis: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_touchpad\",\r\n                visualResponses: {},\r\n            },\r\n            menu: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"menu\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"htc_vive_none\",\r\n        assetPath: \"none.glb\",\r\n    },\r\n    right: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-touchpad\": {\r\n                type: \"touchpad\",\r\n                gamepadIndices: {\r\n                    button: 2,\r\n                    xAxis: 0,\r\n                    yAxis: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_touchpad\",\r\n                visualResponses: {},\r\n            },\r\n            menu: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"menu\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"htc_vive_none\",\r\n        assetPath: \"none.glb\",\r\n    },\r\n    none: {\r\n        selectComponentId: \"xr-standard-trigger\",\r\n        components: {\r\n            \"xr-standard-trigger\": {\r\n                type: \"trigger\",\r\n                gamepadIndices: {\r\n                    button: 0,\r\n                },\r\n                rootNodeName: \"xr_standard_trigger\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-squeeze\": {\r\n                type: \"squeeze\",\r\n                gamepadIndices: {\r\n                    button: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_squeeze\",\r\n                visualResponses: {},\r\n            },\r\n            \"xr-standard-touchpad\": {\r\n                type: \"touchpad\",\r\n                gamepadIndices: {\r\n                    button: 2,\r\n                    xAxis: 0,\r\n                    yAxis: 1,\r\n                },\r\n                rootNodeName: \"xr_standard_touchpad\",\r\n                visualResponses: {},\r\n            },\r\n            menu: {\r\n                type: \"button\",\r\n                gamepadIndices: {\r\n                    button: 4,\r\n                },\r\n                rootNodeName: \"menu\",\r\n                visualResponses: {},\r\n            },\r\n        },\r\n        gamepadMapping: \"xr-standard\",\r\n        rootNodeName: \"htc-vive-none\",\r\n        assetPath: \"none.glb\",\r\n    },\r\n};\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for webXRHTCViveMotionController.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterWebXRHTCViveMotionController(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // register the profile\r\n    WebXRMotionControllerManager.RegisterController(\"htc-vive\", (xrInput: XRInputSource, scene: Scene) => {\r\n        return new WebXRHTCViveMotionController(scene, <any>xrInput.gamepad, xrInput.handedness);\r\n    });\r\n}\r\n","import { RegisterNativeTypeAsync } from \"../../Engines/thinNativeEngine.pure\";\r\n/** This file must only contain pure code and pure imports */\r\n\r\n/** @internal */\r\ninterface INativeXRFrame extends XRFrame {\r\n    // Native-only helper functions\r\n    getPoseData: (space: XRSpace, baseSpace: XRReferenceSpace, vectorBuffer: ArrayBufferLike, matrixBuffer: ArrayBufferLike) => XRPose;\r\n    _imageTrackingResults?: XRImageTrackingResult[];\r\n}\r\n\r\n/** @internal */\r\nexport class NativeXRFrame implements XRFrame {\r\n    private readonly _xrTransform = new XRRigidTransform();\r\n    private readonly _xrPose: XRPose = {\r\n        transform: this._xrTransform,\r\n        emulatedPosition: false,\r\n    };\r\n    // Enough space for position, orientation\r\n    private readonly _xrPoseVectorData = new Float32Array(4 + 4);\r\n\r\n    public get session(): XRSession {\r\n        return this._nativeImpl.session;\r\n    }\r\n\r\n    constructor(private _nativeImpl: INativeXRFrame) {}\r\n\r\n    public getPose(space: XRSpace, baseSpace: XRReferenceSpace): XRPose | undefined {\r\n        if (!this._nativeImpl.getPoseData(space, baseSpace, this._xrPoseVectorData.buffer, this._xrTransform.matrix.buffer)) {\r\n            return undefined;\r\n        }\r\n        const position = this._xrTransform.position as DOMPoint;\r\n        position.x = this._xrPoseVectorData[0];\r\n        position.y = this._xrPoseVectorData[1];\r\n        position.z = this._xrPoseVectorData[2];\r\n        position.w = this._xrPoseVectorData[3];\r\n\r\n        const orientation = this._xrTransform.orientation as DOMPoint;\r\n        orientation.x = this._xrPoseVectorData[4];\r\n        orientation.y = this._xrPoseVectorData[5];\r\n        orientation.z = this._xrPoseVectorData[6];\r\n        orientation.w = this._xrPoseVectorData[7];\r\n        return this._xrPose;\r\n    }\r\n\r\n    public readonly fillPoses = this._nativeImpl.fillPoses!.bind(this._nativeImpl);\r\n\r\n    public readonly getViewerPose = this._nativeImpl.getViewerPose.bind(this._nativeImpl);\r\n\r\n    public readonly getHitTestResults = this._nativeImpl.getHitTestResults.bind(this._nativeImpl);\r\n\r\n    public readonly getHitTestResultsForTransientInput = () => {\r\n        throw new Error(\"XRFrame.getHitTestResultsForTransientInput not supported on native.\");\r\n    };\r\n\r\n    public get trackedAnchors(): XRAnchorSet | undefined {\r\n        return this._nativeImpl.trackedAnchors;\r\n    }\r\n\r\n    public readonly createAnchor = this._nativeImpl.createAnchor!.bind(this._nativeImpl);\r\n\r\n    public get worldInformation(): XRWorldInformation | undefined {\r\n        return this._nativeImpl.worldInformation;\r\n    }\r\n\r\n    public get detectedPlanes(): XRPlaneSet | undefined {\r\n        return this._nativeImpl.detectedPlanes;\r\n    }\r\n\r\n    public readonly getJointPose = this._nativeImpl.getJointPose!.bind(this._nativeImpl);\r\n\r\n    public readonly fillJointRadii = this._nativeImpl.fillJointRadii!.bind(this._nativeImpl);\r\n\r\n    public readonly getLightEstimate = () => {\r\n        throw new Error(\"XRFrame.getLightEstimate not supported on native.\");\r\n    };\r\n\r\n    public get featurePointCloud(): number[] | undefined {\r\n        return this._nativeImpl.featurePointCloud;\r\n    }\r\n\r\n    public readonly getImageTrackingResults = (): XRImageTrackingResult[] => {\r\n        return this._nativeImpl._imageTrackingResults ?? [];\r\n    };\r\n\r\n    public getDepthInformation(view: XRView): XRCPUDepthInformation | undefined {\r\n        throw new Error(\"This function is not available in Babylon Native\");\r\n        // return this._nativeImpl.getDepthInformation(view);\r\n    }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for nativeXRFrame.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterNativeXRFrame(): void {\r\n    if (_Registered) {\r\n        return;\r\n    }\r\n    _Registered = true;\r\n\r\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n    RegisterNativeTypeAsync(\"NativeXRFrame\", NativeXRFrame);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable @typescript-eslint/no-restricted-imports */\r\nimport * as BABYLON from \"core/index\";\r\nimport * as DebugImport from \"core/Debug/index\";\r\nimport { RegisterMathColor } from \"core/Maths/math.color.pure\";\r\nimport { RegisterMathVector } from \"core/Maths/math.vector.pure\";\r\n\r\ndeclare let global: any;\r\n\r\n/**\r\n * Legacy support, defining window.BABYLON (global variable).\r\n *\r\n * This is the entry point for the UMD module.\r\n * The entry point for a future ESM package should be index.ts\r\n */\r\nconst GlobalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\r\nfunction RegisterLegacyGlobal(): void {\r\n    if (typeof GlobalObject === \"undefined\") {\r\n        return;\r\n    }\r\n\r\n    GlobalObject.BABYLON = GlobalObject.BABYLON || {};\r\n    const BABYLONGLOBAL = GlobalObject.BABYLON;\r\n    if (!BABYLONGLOBAL.Debug) {\r\n        BABYLONGLOBAL.Debug = BABYLONGLOBAL.Debug || {};\r\n\r\n        for (const key in DebugImport) {\r\n            if (!BABYLONGLOBAL.Debug[key]) {\r\n                BABYLONGLOBAL.Debug[key] = (<any>DebugImport)[key];\r\n            }\r\n        }\r\n    }\r\n    for (const key in BABYLON) {\r\n        if (!BABYLONGLOBAL[key]) {\r\n            BABYLONGLOBAL[key] = (<any>BABYLON)[key];\r\n        }\r\n    }\r\n}\r\n\r\nfunction RegisterLegacyRuntime(): void {\r\n    RegisterMathColor();\r\n    RegisterMathVector();\r\n    RegisterLegacyGlobal();\r\n}\r\n\r\nRegisterLegacyRuntime();\r\n\r\nexport * from \"core/index\";\r\nexport const Debug = {\r\n    AxesViewer: BABYLON.AxesViewer,\r\n    BoneAxesViewer: BABYLON.BoneAxesViewer,\r\n    PhysicsViewer: BABYLON.PhysicsViewer,\r\n    SkeletonViewer: BABYLON.SkeletonViewer,\r\n};\r\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lod3DPixelShader\";\nconst shader = `precision highp float;precision highp sampler3D;const float GammaEncodePowerApprox=1.0/2.2;varying vec2 vUV;uniform sampler3D textureSampler;uniform float lod;uniform float slice;uniform int gamma;void main(void)\n{ivec3 textureCoordinates=ivec3(vUV*vec2(textureSize(textureSampler,0).xy),int(slice));gl_FragColor=texelFetch(textureSampler,textureCoordinates,int(lod));if (gamma==0) {gl_FragColor.rgb=pow(gl_FragColor.rgb,vec3(GammaEncodePowerApprox));}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const lod3DPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"lod3DPixelShader\";\nconst shader = `const GammaEncodePowerApprox=1.0/2.2;varying vUV: vec2f;var textureSampler: texture_3d<f32>;uniform lod: f32;uniform slice: f32;uniform gamma: i32;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let textureSize=textureDimensions(textureSampler,0);let textureCoordinates=vec3i(vec2i(fragmentInputs.vUV*vec2f(textureSize.xy)),i32(uniforms.slice));fragmentOutputs.color=textureLoad(textureSampler,textureCoordinates,i32(uniforms.lod));if (uniforms.gamma==0) {fragmentOutputs.color=vec4f(pow(fragmentOutputs.color.rgb,vec3f(GammaEncodePowerApprox)),fragmentOutputs.color.a);}}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const lod3DPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { packingFunctionsWGSL } from \"./ShadersInclude/packingFunctions\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { gaussianSplattingFragmentDeclarationWGSL } from \"./ShadersInclude/gaussianSplattingFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { geometryRenderingFragmentWGSL } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"gaussianSplattingPixelShader\";\nconst shader = `#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#define PREPASS_CUSTOM_VARYINGS\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#ifdef GPUPICKER_PACK_DEPTH\n#include<packingFunctions>\n#endif\nvarying vColor: vec4f;varying vPosition: vec2f;\n#ifdef PREPASS\nuniform geometryZeroAlphaDiscard: f32;\n#ifdef PREPASS_POSITION\nvarying vGeometryPositionW: vec3f;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vGeometryPositionL: vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vGeometryViewDepth: f32;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vGeometryNormalizedViewDepth: f32;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vGeometryNormalV: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vGeometryNormalW: vec3f;\n#endif\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvarying vGeometryAlbedo: vec3f;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvarying vGeometryCurrentPosition: vec4f;varying vGeometryPreviousPosition: vec4f;\n#endif\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#include<gaussianSplattingFragmentDeclaration>\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvar finalColor: vec4f=gaussianColor(input.vColor,input.vPosition);\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\nif (finalColor.a<=0.0 && uniforms.geometryZeroAlphaDiscard>0.0) {discard;}\nlet geometryColor=finalColor;\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nlet geometryAlbedo=input.vGeometryAlbedo;\n#endif\n#ifdef PREPASS_POSITION\nlet geometryPositionW=input.vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nlet geometryPositionL=input.vGeometryPositionL;\n#endif\n#ifdef PREPASS_DEPTH\nlet geometryViewDepth=input.vGeometryViewDepth;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nlet geometryNormalizedViewDepth=input.vGeometryNormalizedViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nlet geometryNormalV=input.vGeometryNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nlet geometryNormalW=input.vGeometryNormalW;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nlet geometryCurrentPosition=input.vGeometryCurrentPosition;let geometryPreviousPosition=input.vGeometryPreviousPosition;\n#endif\n#include<geometryRenderingFragment>\n#elif defined(GPUPICKER_DEPTH)\nfragmentOutputs.fragData0=finalColor;\n#ifdef GPUPICKER_PACK_DEPTH\nfragmentOutputs.fragData1=pack(fragmentInputs.position.z);\n#else\nfragmentOutputs.fragData1=vec4f(fragmentInputs.position.z,0.0,0.0,1.0);\n#endif\n#else\nfragmentOutputs.color=finalColor;\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclarationWGSL, logDepthDeclarationWGSL, fogFragmentDeclarationWGSL, objectIdFunctionsWGSL, prePassDeclarationWGSL, packingFunctionsWGSL, logDepthFragmentWGSL, fogFragmentWGSL, gaussianSplattingFragmentDeclarationWGSL, clipPlaneFragmentWGSL, meshBlendTagFragmentOutputWGSL, geometryRenderingFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { gaussianSplattingWGSL } from \"./ShadersInclude/gaussianSplatting\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"gaussianSplattingVertexShader\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\n#include<helperFunctions>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\nattribute splatIndex0: vec4f;attribute splatIndex1: vec4f;attribute splatIndex2: vec4f;attribute splatIndex3: vec4f;attribute position: vec3f;uniform invViewport: vec2f;uniform dataTextureSize: vec2f;uniform focal: vec2f;uniform kernelSize: f32;uniform minPixelSize: f32;uniform eyePosition: vec3f;uniform alpha: f32;\n#ifdef PREPASS\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nuniform previousWorld: mat4x4f;uniform previousViewProjection: mat4x4f;\n#if IS_COMPOUND\nuniform previousPartWorld: array<mat4x4<f32>,MAX_PART_COUNT>;\n#endif\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nuniform geometryDepthRange: vec2f;\n#endif\n#endif\n#if IS_COMPOUND\nuniform partWorld: array<mat4x4<f32>,MAX_PART_COUNT>;uniform partVisibility: array<f32,MAX_PART_COUNT>;\n#endif\nvar covariancesATexture: texture_2d<f32>;var covariancesBTexture: texture_2d<f32>;var centersTexture: texture_2d<f32>;var colorsTexture: texture_2d<f32>;\n#ifdef USE_SOG\nvar sogQuatsTexture: texture_2d<f32>;uniform sogMeansMin: vec3f;uniform sogMeansMax: vec3f;\n#ifdef USE_SOG_V2\nvar sogCodebookTexture: texture_2d<f32>;\n#else\nuniform sogScalesMin: vec3f;uniform sogScalesMax: vec3f;uniform sogSh0Min: vec4f;uniform sogSh0Max: vec4f;uniform sogShnMin: f32;uniform sogShnMax: f32;\n#endif\n#if SH_DEGREE>0\nvar sogShNCentroidsTexture: texture_2d<f32>;var sogShNLabelsTexture: texture_2d<f32>;uniform sogShCoeffCount: f32;\n#endif\n#endif\n#if SH_DEGREE>0 && !defined(USE_SOG)\nvar shTexture0: texture_2d<u32>;\n#endif\n#if SH_DEGREE>1 && !defined(USE_SOG)\nvar shTexture1: texture_2d<u32>;\n#endif\n#if SH_DEGREE>2 && !defined(USE_SOG)\nvar shTexture2: texture_2d<u32>;\n#endif\n#if SH_DEGREE>3 && !defined(USE_SOG)\nvar shTexture3: texture_2d<u32>;var shTexture4: texture_2d<u32>;\n#endif\n#if IS_COMPOUND\nvar partIndicesTexture: texture_2d<f32>;\n#endif\nvarying vColor: vec4f;varying vPosition: vec2f;\n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvarying vGeometryPositionW: vec3f;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vGeometryPositionL: vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vGeometryViewDepth: f32;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vGeometryNormalizedViewDepth: f32;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vGeometryNormalV: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vGeometryNormalW: vec3f;\n#endif\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvarying vGeometryAlbedo: vec3f;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvarying vGeometryCurrentPosition: vec4f;varying vGeometryPreviousPosition: vec4f;\n#endif\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n#include<gaussianSplatting>\n@vertex\nfn main(input : VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nlet splatIndex: f32=getSplatIndex(i32(vertexInputs.position.z+0.5),vertexInputs.splatIndex0,vertexInputs.splatIndex1,vertexInputs.splatIndex2,vertexInputs.splatIndex3);var splat: Splat=readSplat(splatIndex,uniforms.dataTextureSize);var covA: vec3f=splat.covA.xyz;var covB: vec3f=vec3f(splat.covA.w,splat.covB.xy);\n#if IS_COMPOUND\nlet splatWorld: mat4x4f=getPartWorld(splat.partIndex);\n#else\nlet splatWorld: mat4x4f=mesh.world;\n#endif\nlet worldPos: vec4f=splatWorld*vec4f(splat.center.xyz,1.0);vertexOutputs.vPosition=vertexInputs.position.xy;\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvertexOutputs.vGeometryAlbedo=splat.color.xyz;\n#endif\n#if SH_DEGREE>0\nlet worldRot: mat3x3f= mat3x3f(splatWorld[0].xyz,splatWorld[1].xyz,splatWorld[2].xyz);let normWorldRot: mat3x3f=inverseMat3(worldRot);var eyeToSplatLocalSpace: vec3f=normalize(normWorldRot*(worldPos.xyz-uniforms.eyePosition.xyz));\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n{let _row3=textureLoad(dbgPartData,vec2i(i32(splat.partIndex),3),0);\n#if SH_DEGREE>3\nlet _so4=textureLoad(dbgPartData,vec2i(i32(splat.partIndex),4),0).x;\n#else\nlet _so4: f32=1.0;\n#endif\nvertexOutputs.vColor=vec4f(_row3.x*splat.color.xyz+computeSHWeighted(splat,eyeToSplatLocalSpace,_row3.y,_row3.z,_row3.w,_so4),splat.color.w*uniforms.alpha);}\n#elif defined(GS_DBG_ENABLED) && GS_DBG_SH_DC==0\nvertexOutputs.vColor=vec4f(computeSH(splat,eyeToSplatLocalSpace),splat.color.w*uniforms.alpha);\n#else\nvertexOutputs.vColor=vec4f(splat.color.xyz+computeSH(splat,eyeToSplatLocalSpace),splat.color.w*uniforms.alpha);\n#endif\n#else\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n{let _shDc=textureLoad(dbgPartData,vec2i(i32(splat.partIndex),3),0).x;vertexOutputs.vColor=vec4f(_shDc*splat.color.xyz,splat.color.w*uniforms.alpha);}\n#elif defined(GS_DBG_ENABLED) && GS_DBG_SH_DC==0\nvertexOutputs.vColor=vec4f(0.0,0.0,0.0,splat.color.w*uniforms.alpha);\n#else\nvertexOutputs.vColor=vec4f(splat.color.xyz,splat.color.w*uniforms.alpha);\n#endif\n#endif\n#if IS_COMPOUND\nvertexOutputs.vColor.w*=uniforms.partVisibility[splat.partIndex];\n#endif\nvar scale: vec2f=vec2f(1.,1.);\n#define CUSTOM_VERTEX_UPDATE\nvertexOutputs.position=gaussianSplatting(vertexInputs.position.xy,worldPos.xyz,scale,covA,covB,splatWorld,scene.view,scene.projection,uniforms.focal,uniforms.invViewport,uniforms.kernelSize,uniforms.minPixelSize);\n#ifdef PREPASS\n#if defined(PREPASS_POSITION) || defined(PREPASS_LOCAL_POSITION) || defined(PREPASS_DEPTH) || defined(PREPASS_NORMALIZED_VIEW_DEPTH) || defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nlet geometrySplatViewPosition=(scene.view*worldPos).xyz;let viewRotation=mat3x3f(scene.view[0].xyz,scene.view[1].xyz,scene.view[2].xyz);\n#endif\n#if defined(PREPASS_POSITION) || defined(PREPASS_LOCAL_POSITION) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvar geometryPlaneViewPosition=scene.inverseProjection*vertexOutputs.position;geometryPlaneViewPosition/=geometryPlaneViewPosition.w;let geometryPlanePositionW=worldPos.xyz+transpose(viewRotation)*(geometryPlaneViewPosition.xyz-geometrySplatViewPosition);\n#if defined(PREPASS_LOCAL_POSITION) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nlet splatWorldRotation=mat3x3f(splatWorld[0].xyz,splatWorld[1].xyz,splatWorld[2].xyz);let geometryPlanePositionL=splat.center.xyz+inverseMat3(splatWorldRotation)*(geometryPlanePositionW-worldPos.xyz);\n#endif\n#endif\n#ifdef PREPASS_POSITION\nvertexOutputs.vGeometryPositionW=geometryPlanePositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvertexOutputs.vGeometryPositionL=geometryPlanePositionL;\n#endif\n#ifdef PREPASS_DEPTH\nvertexOutputs.vGeometryViewDepth=geometrySplatViewPosition.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvertexOutputs.vGeometryNormalizedViewDepth=(geometrySplatViewPosition.z-uniforms.geometryDepthRange.x)/(uniforms.geometryDepthRange.y-uniforms.geometryDepthRange.x);\n#endif\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nlet geometryNormalV=vec3f(0.0,0.0,select(-1.0,1.0,geometrySplatViewPosition.z<0.0));let geometryNormalW=normalize(transpose(viewRotation)*geometryNormalV);\n#ifdef PREPASS_NORMAL\nvertexOutputs.vGeometryNormalV=geometryNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvertexOutputs.vGeometryNormalW=geometryNormalW;\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvertexOutputs.vGeometryCurrentPosition=vertexOutputs.position;\n#if IS_COMPOUND\nvertexOutputs.vGeometryPreviousPosition=uniforms.previousViewProjection*uniforms.previousPartWorld[splat.partIndex]*vec4f(geometryPlanePositionL,1.0);\n#else\nvertexOutputs.vGeometryPreviousPosition=uniforms.previousViewProjection*uniforms.previousWorld*vec4f(geometryPlanePositionL,1.0);\n#endif\n#endif\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, helperFunctionsWGSL, clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, logDepthDeclarationWGSL, gaussianSplattingWGSL, clipPlaneVertexWGSL, fogVertexWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { fogFragmentDeclaration } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { objectIdFunctions } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclaration } from \"./ShadersInclude/prePassDeclaration\";\nimport { packingFunctions } from \"./ShadersInclude/packingFunctions\";\nimport { logDepthFragment } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragment } from \"./ShadersInclude/fogFragment\";\nimport { gaussianSplattingFragmentDeclaration } from \"./ShadersInclude/gaussianSplattingFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\nimport { geometryRenderingFragment } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"gaussianSplattingPixelShader\";\nconst shader = `#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#define PREPASS_CUSTOM_VARYINGS\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#if defined(GPUPICKER_DEPTH) && !defined(PREPASS)\nlayout(location=0) out highp vec4 glFragData[2];\n#endif\n#ifdef GPUPICKER_PACK_DEPTH\n#include<packingFunctions>\n#endif\nvarying vec4 vColor;varying vec2 vPosition;\n#ifdef PREPASS\nuniform float geometryZeroAlphaDiscard;\n#ifdef PREPASS_POSITION\nvarying vec3 vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vec3 vGeometryPositionL;\n#endif\n#ifdef PREPASS_DEPTH\nvarying float vGeometryViewDepth;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying float vGeometryNormalizedViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vGeometryNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vGeometryNormalW;\n#endif\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvarying vec3 vGeometryAlbedo;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvarying vec4 vGeometryCurrentPosition;varying vec4 vGeometryPreviousPosition;\n#endif\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n#include<gaussianSplattingFragmentDeclaration>\nvoid main () {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvec4 finalColor=gaussianColor(vColor);\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\n#ifdef PREPASS\nif (finalColor.a<=0.0 && geometryZeroAlphaDiscard>0.0) {discard;}\nvec4 geometryColor=finalColor;\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvec3 geometryAlbedo=vGeometryAlbedo;\n#endif\n#ifdef PREPASS_POSITION\nvec3 geometryPositionW=vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvec3 geometryPositionL=vGeometryPositionL;\n#endif\n#ifdef PREPASS_DEPTH\nfloat geometryViewDepth=vGeometryViewDepth;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nfloat geometryNormalizedViewDepth=vGeometryNormalizedViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvec3 geometryNormalV=vGeometryNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvec3 geometryNormalW=vGeometryNormalW;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvec4 geometryCurrentPosition=vGeometryCurrentPosition;vec4 geometryPreviousPosition=vGeometryPreviousPosition;\n#endif\n#include<geometryRenderingFragment>\n#elif defined(GPUPICKER_DEPTH)\nglFragData[0]=finalColor;\n#ifdef GPUPICKER_PACK_DEPTH\nglFragData[1]=pack(gl_FragCoord.z);\n#else\nglFragData[1]=vec4(gl_FragCoord.z,0.0,0.0,1.0);\n#endif\n#else\ngl_FragColor=finalColor;\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclaration, logDepthDeclaration, fogFragmentDeclaration, objectIdFunctions, prePassDeclaration, packingFunctions, logDepthFragment, fogFragment, gaussianSplattingFragmentDeclaration, clipPlaneFragment, geometryRenderingFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { gaussianSplattingVertexDeclaration } from \"./ShadersInclude/gaussianSplattingVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { gaussianSplattingUboDeclaration } from \"./ShadersInclude/gaussianSplattingUboDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclaration } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclaration } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { gaussianSplatting } from \"./ShadersInclude/gaussianSplatting\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertex } from \"./ShadersInclude/fogVertex\";\nimport { logDepthVertex } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"gaussianSplattingVertexShader\";\nconst shader = `#include<__decl__gaussianSplattingVertex>\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\nuniform vec2 invViewport;uniform vec2 dataTextureSize;uniform vec2 focal;uniform float kernelSize;uniform float minPixelSize;uniform vec3 eyePosition;uniform float alpha;\n#ifdef PREPASS\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nuniform mat4 previousWorld;uniform mat4 previousViewProjection;\n#if IS_COMPOUND\nuniform mat4 previousPartWorld[MAX_PART_COUNT];\n#endif\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nuniform vec2 geometryDepthRange;\n#endif\n#endif\n#if IS_COMPOUND\nuniform mat4 partWorld[MAX_PART_COUNT];uniform float partVisibility[MAX_PART_COUNT];\n#endif\nuniform sampler2D covariancesATexture;uniform sampler2D covariancesBTexture;uniform sampler2D centersTexture;uniform sampler2D colorsTexture;\n#ifdef USE_SOG\nuniform sampler2D sogQuatsTexture;uniform vec3 sogMeansMin;uniform vec3 sogMeansMax;\n#ifdef USE_SOG_V2\nuniform sampler2D sogCodebookTexture; \n#else\nuniform vec3 sogScalesMin;uniform vec3 sogScalesMax;uniform vec4 sogSh0Min;uniform vec4 sogSh0Max;uniform float sogShnMin;uniform float sogShnMax;\n#endif\n#if SH_DEGREE>0\nuniform sampler2D sogShNCentroidsTexture;uniform sampler2D sogShNLabelsTexture;uniform float sogShCoeffCount;\n#endif\n#endif\n#if SH_DEGREE>0 && !defined(USE_SOG)\nuniform highp usampler2D shTexture0;\n#endif\n#if SH_DEGREE>1 && !defined(USE_SOG)\nuniform highp usampler2D shTexture1;\n#endif\n#if SH_DEGREE>2 && !defined(USE_SOG)\nuniform highp usampler2D shTexture2;\n#endif\n#if SH_DEGREE>3 && !defined(USE_SOG)\nuniform highp usampler2D shTexture3;uniform highp usampler2D shTexture4;\n#endif\n#if IS_COMPOUND\nuniform sampler2D partIndicesTexture;\n#endif\nvarying vec4 vColor;varying vec2 vPosition;\n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvarying vec3 vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vec3 vGeometryPositionL;\n#endif\n#ifdef PREPASS_DEPTH\nvarying float vGeometryViewDepth;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying float vGeometryNormalizedViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vec3 vGeometryNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vec3 vGeometryNormalW;\n#endif\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvarying vec3 vGeometryAlbedo;\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvarying vec4 vGeometryCurrentPosition;varying vec4 vGeometryPreviousPosition;\n#endif\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n#include<gaussianSplatting>\nvoid main () {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nfloat splatIndex=getSplatIndex(int(position.z+0.5));Splat splat=readSplat(splatIndex);vec3 covA=splat.covA.xyz;vec3 covB=vec3(splat.covA.w,splat.covB.xy);\n#if IS_COMPOUND\nmat4 splatWorld=getPartWorld(splat.partIndex);\n#else\nmat4 splatWorld=world;\n#endif\nvec4 worldPos=splatWorld*vec4(splat.center.xyz,1.0);vColor=splat.color;vPosition=position.xy;\n#if defined(PREPASS_ALBEDO) || defined(PREPASS_ALBEDO_SQRT)\nvGeometryAlbedo=splat.color.xyz;\n#endif\n#if SH_DEGREE>0\nmat3 worldRot=mat3(splatWorld);mat3 normWorldRot=inverseMat3(worldRot);vec3 eyeToSplatLocalSpace=normalize(normWorldRot*(worldPos.xyz-eyePosition));\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n{vec4 _row3=texelFetch(dbgPartData,ivec2(int(splat.partIndex),3),0);\n#if SH_DEGREE>3\nfloat _so4=texelFetch(dbgPartData,ivec2(int(splat.partIndex),4),0).x;\n#else\nfloat _so4=1.0;\n#endif\nvColor.xyz=_row3.x*splat.color.xyz+computeSHWeighted(splat,eyeToSplatLocalSpace,_row3.y,_row3.z,_row3.w,_so4);}\n#elif defined(GS_DBG_ENABLED) && GS_DBG_SH_DC==0\nvColor.xyz=computeSH(splat,eyeToSplatLocalSpace);\n#else\nvColor.xyz=splat.color.xyz+computeSH(splat,eyeToSplatLocalSpace);\n#endif\n#else\n#if defined(GS_DBG_ENABLED) && IS_COMPOUND\n{float _shDc=texelFetch(dbgPartData,ivec2(int(splat.partIndex),3),0).x;vColor.xyz=_shDc*splat.color.xyz;}\n#elif defined(GS_DBG_ENABLED) && GS_DBG_SH_DC==0\nvColor.xyz=vec3(0.0);\n#endif\n#endif\nvColor.w*=alpha;\n#if IS_COMPOUND\nvColor.w*=partVisibility[splat.partIndex];\n#endif\nvec2 scale=vec2(1.,1.);\n#define CUSTOM_VERTEX_UPDATE\ngl_Position=gaussianSplatting(position.xy,worldPos.xyz,scale,covA,covB,splatWorld,view,projection);\n#ifdef PREPASS\n#if defined(PREPASS_POSITION) || defined(PREPASS_LOCAL_POSITION) || defined(PREPASS_DEPTH) || defined(PREPASS_NORMALIZED_VIEW_DEPTH) || defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvec3 geometrySplatViewPosition=(view*worldPos).xyz;\n#endif\n#if defined(PREPASS_POSITION) || defined(PREPASS_LOCAL_POSITION) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvec4 geometryPlaneViewPosition=inverseProjection*gl_Position;geometryPlaneViewPosition/=geometryPlaneViewPosition.w;vec3 geometryPlanePositionW=worldPos.xyz+transpose(mat3(view))*(geometryPlaneViewPosition.xyz-geometrySplatViewPosition);\n#if defined(PREPASS_LOCAL_POSITION) || defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvec3 geometryPlanePositionL=splat.center.xyz+inverseMat3(mat3(splatWorld))*(geometryPlanePositionW-worldPos.xyz);\n#endif\n#endif\n#ifdef PREPASS_POSITION\nvGeometryPositionW=geometryPlanePositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvGeometryPositionL=geometryPlanePositionL;\n#endif\n#ifdef PREPASS_DEPTH\nvGeometryViewDepth=geometrySplatViewPosition.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvGeometryNormalizedViewDepth=(geometrySplatViewPosition.z-geometryDepthRange.x)/(geometryDepthRange.y-geometryDepthRange.x);\n#endif\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nvec3 geometryNormalV=vec3(0.0,0.0,geometrySplatViewPosition.z<0.0 ? 1.0 : -1.0);vec3 geometryNormalW=normalize(transpose(mat3(view))*geometryNormalV);\n#ifdef PREPASS_NORMAL\nvGeometryNormalV=geometryNormalV;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvGeometryNormalW=geometryNormalW;\n#endif\n#endif\n#if defined(PREPASS_VELOCITY) || defined(PREPASS_VELOCITY_LINEAR)\nvGeometryCurrentPosition=gl_Position;\n#if IS_COMPOUND\nvGeometryPreviousPosition=previousViewProjection*previousPartWorld[splat.partIndex]*vec4(geometryPlanePositionL,1.0);\n#else\nvGeometryPreviousPosition=previousViewProjection*previousWorld*vec4(geometryPlanePositionL,1.0);\n#endif\n#endif\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [gaussianSplattingVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, gaussianSplattingUboDeclaration, clipPlaneVertexDeclaration, fogVertexDeclaration, logDepthDeclaration, helperFunctions, gaussianSplatting, clipPlaneVertex, fogVertex, logDepthVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\nimport { gaussianSplattingWGSL } from \"./ShadersInclude/gaussianSplatting\";\n\nconst name = \"gaussianSplattingVoxelVertexShader\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute splatIndex0: vec4f;attribute splatIndex1: vec4f;attribute splatIndex2: vec4f;attribute splatIndex3: vec4f;attribute position: vec3f;uniform dataTextureSize: vec2f;uniform alpha: f32;uniform invWorldScale: mat4x4f;uniform viewMatrix: mat4x4f;\n#if IS_COMPOUND\nuniform partWorld: array<mat4x4<f32>,MAX_PART_COUNT>;uniform partVisibility: array<f32,MAX_PART_COUNT>;\n#endif\nvar rotationsATexture: texture_2d<f32>;var rotationsBTexture: texture_2d<f32>;var rotationScaleTexture: texture_2d<f32>;var centersTexture: texture_2d<f32>;var colorsTexture: texture_2d<f32>;\n#if IS_COMPOUND\nvar partIndicesTexture: texture_2d<f32>;\n#endif\nvarying vNormalizedPosition: vec3f;varying vNormalizedCenterPosition: vec3f;varying vAlpha: f32;varying vPatchPosition: vec2f;\n#include<gaussianSplatting>\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {let splatIndex: f32=getSplatIndex(\ni32(vertexInputs.position.z+0.5),\nvertexInputs.splatIndex0,vertexInputs.splatIndex1,\nvertexInputs.splatIndex2,vertexInputs.splatIndex3\n);var splat: Splat=readSplat(splatIndex,uniforms.dataTextureSize);\n#if IS_COMPOUND\nif (uniforms.partVisibility[splat.partIndex]==0.0) {vertexOutputs.position=vec4f(2.0,2.0,2.0,1.0);return vertexOutputs;}\nlet splatWorld: mat4x4f=getPartWorld(splat.partIndex);\n#else\nlet splatWorld: mat4x4f=mesh.world;\n#endif\nlet quadPos: vec2f=vertexInputs.position.xy;let worldPos: vec4f=computeVoxelSplatWorldPos(splat.rotationA,splat.rotationB,splat.rotationScale,splat.center.xyz,splatWorld,uniforms.viewMatrix,uniforms.invWorldScale,quadPos);vertexOutputs.vNormalizedPosition=(uniforms.invWorldScale*worldPos).xyz*0.5+0.5;let clipPos: vec4f=uniforms.viewMatrix*uniforms.invWorldScale*worldPos;vertexOutputs.position=vec4f(clipPos.x,clipPos.y,clipPos.z*0.5+0.5,1.0);vertexOutputs.vNormalizedCenterPosition=(uniforms.invWorldScale*splatWorld*vec4f(splat.center.xyz,1.0)).xyz*0.5+0.5;vertexOutputs.vAlpha=splat.color.w*uniforms.alpha;\n#if IS_COMPOUND\nvertexOutputs.vAlpha*=uniforms.partVisibility[splat.partIndex];\n#endif\nvertexOutputs.vPatchPosition=quadPos;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL, gaussianSplattingWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingVoxelVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { iblVoxelOpacityAtomicMaxWGSL } from \"./ShadersInclude/iblVoxelOpacityAtomicMax\";\n\nconst name = \"gaussianSplattingVoxelPixelShader\";\nconst shader = `var voxel_storage: texture_storage_3d<r8unorm,write>;var<storage,read_write> voxelOpacityBuffer: array<atomic<u32>>;\n#include<iblVoxelOpacityAtomicMax>\nvarying vNormalizedPosition: vec3f;varying vNormalizedCenterPosition: vec3f;varying vAlpha: f32;varying vPatchPosition: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let normPos: vec3f=input.vNormalizedPosition;let size: vec3<u32>=textureDimensions(voxel_storage);let stepSize: f32=1.0/f32(size.x);let diff: vec3f=abs(input.vNormalizedCenterPosition-normPos);let distToCenter: f32=max(max(diff.x,diff.y),diff.z);let gaussian: f32=exp(-dot(input.vPatchPosition,input.vPatchPosition));let shadowingOpacity: f32=clamp(\nselect(gaussian,1.0,distToCenter<stepSize)*input.vAlpha,\n0.0,1.0\n);if (shadowingOpacity<=0.0) {discard;}\nlet coord: vec3<u32>=min(\nvec3<u32>(u32(normPos.x*f32(size.x)),u32(normPos.y*f32(size.y)),u32(normPos.z*f32(size.z))),\nsize-vec3<u32>(1u));let vidx: u32=coord.x+coord.y*size.x+coord.z*size.x*size.y;voxelOpacityAtomicMax(vidx,u32(shadowingOpacity*255.0+0.5));fragmentOutputs.color=vec4f(0.0,0.0,0.0,0.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [iblVoxelOpacityAtomicMaxWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingVoxelPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { gaussianSplattingVertexDeclaration } from \"./ShadersInclude/gaussianSplattingVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\nimport { gaussianSplattingUboDeclaration } from \"./ShadersInclude/gaussianSplattingUboDeclaration\";\nimport { gaussianSplatting } from \"./ShadersInclude/gaussianSplatting\";\n\nconst name = \"gaussianSplattingVoxelVertexShader\";\nconst shader = `#include<__decl__gaussianSplattingVertex>\nuniform vec2 dataTextureSize;uniform float alpha;uniform mat4 invWorldScale;uniform mat4 viewMatrix;uniform sampler2D rotationsATexture;uniform sampler2D rotationsBTexture;uniform sampler2D rotationScaleTexture;uniform sampler2D centersTexture;uniform sampler2D colorsTexture;\n#if IS_COMPOUND\nuniform mat4 partWorld[MAX_PART_COUNT];uniform float partVisibility[MAX_PART_COUNT];uniform sampler2D partIndicesTexture;\n#endif\nvarying vec3 vNormalizedPosition;varying vec3 vNormalizedCenterPosition;varying float vAlpha;varying vec2 vPatchPosition;\n#include<gaussianSplatting>\nvoid main(void) {float splatIndex=getSplatIndex(int(position.z+0.5));Splat splat=readSplat(splatIndex);\n#if IS_COMPOUND\nif (partVisibility[splat.partIndex]==0.0) {gl_Position=vec4(2.0,2.0,2.0,1.0);return;}\nmat4 splatWorld=getPartWorld(splat.partIndex);\n#else\nmat4 splatWorld=world;\n#endif\nvec4 worldPos=computeVoxelSplatWorldPos(splat.rotationA,splat.rotationB,splat.rotationScale,splat.center.xyz,splatWorld,viewMatrix,invWorldScale,position.xy);gl_Position=viewMatrix*invWorldScale*worldPos;vNormalizedPosition=gl_Position.xyz*0.5+0.5;vec4 viewCenterPos=viewMatrix*invWorldScale*splatWorld*vec4(splat.center.xyz,1.0);vNormalizedCenterPosition=viewCenterPos.xyz*0.5+0.5;vAlpha=splat.color.w*alpha;\n#if IS_COMPOUND\nvAlpha*=partVisibility[splat.partIndex];\n#endif\nvPatchPosition=position.xy;}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [gaussianSplattingVertexDeclaration, sceneUboDeclaration, meshUboDeclaration, gaussianSplattingUboDeclaration, gaussianSplatting];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gaussianSplattingVoxelVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"gaussianSplattingVoxelPixelShader\";\nconst shader = `precision highp float;layout(location=0) out highp float glFragData[MAX_DRAW_BUFFERS];varying vec3 vNormalizedPosition;varying vec3 vNormalizedCenterPosition;varying float vAlpha;varying vec2 vPatchPosition;uniform float nearPlane;uniform float farPlane;uniform float stepSize;float max3(vec3 v) { return max(max(v.x,v.y),v.z); }\nvoid main(void) {vec3 normPos=vNormalizedPosition.xyz;if (normPos.z<nearPlane || normPos.z>farPlane) {discard;}\nfloat distToCenter=max3(abs(vNormalizedCenterPosition-normPos));float shadowingOpacity=clamp((distToCenter<stepSize ? 1.0 : exp(-dot(vPatchPosition,vPatchPosition)))*vAlpha,0.0,1.0);if (shadowingOpacity<=0.0) {discard;}\nglFragData[0]=normPos.z<nearPlane+stepSize ? shadowingOpacity : 0.0;glFragData[1]=normPos.z>=nearPlane+stepSize && normPos.z<nearPlane+2.0*stepSize ? shadowingOpacity : 0.0;glFragData[2]=normPos.z>=nearPlane+2.0*stepSize && normPos.z<nearPlane+3.0*stepSize ? shadowingOpacity : 0.0;glFragData[3]=normPos.z>=nearPlane+3.0*stepSize && normPos.z<nearPlane+4.0*stepSize ? shadowingOpacity : 0.0;\n#if MAX_DRAW_BUFFERS>4\nglFragData[4]=normPos.z>=nearPlane+4.0*stepSize && normPos.z<nearPlane+5.0*stepSize ? shadowingOpacity : 0.0;glFragData[5]=normPos.z>=nearPlane+5.0*stepSize && normPos.z<nearPlane+6.0*stepSize ? shadowingOpacity : 0.0;\n#if MAX_DRAW_BUFFERS>6\nglFragData[6]=normPos.z>=nearPlane+6.0*stepSize && normPos.z<nearPlane+7.0*stepSize ? shadowingOpacity : 0.0;glFragData[7]=normPos.z>=nearPlane+7.0*stepSize && normPos.z<nearPlane+8.0*stepSize ? shadowingOpacity : 0.0;\n#endif\n#endif\n}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const gaussianSplattingVoxelPixelShader = { name, shader };\n","/** This file must only contain pure code and pure imports */\n\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\nimport { FlowGraphEventBlock } from \"core/FlowGraph/flowGraphEventBlock\";\nimport { type PointerInfo } from \"core/Events/pointerEvents\";\nimport { type IPointerEvent } from \"core/Events/deviceInputEvents\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { _IsDescendantOf } from \"core/FlowGraph/utils\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Vector3 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { type Nullable } from \"core/types\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the pointer down event block.\n */\nexport interface IFlowGraphPointerDownEventBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Should this block stop propagation of the event to other listeners.\n     */\n    stopPropagation?: boolean;\n\n    /**\n     * Optional mesh to filter events to. If set, the block only fires when the pointer\n     * is pressed on this mesh or a descendant of it. If not set, fires on any pointer down.\n     */\n    targetMesh?: AbstractMesh;\n}\n\n/**\n * A pointer down event block.\n * This block fires when a pointer is pressed (mouse button down / touch start).\n * Optionally filters to a specific mesh via the `targetMesh` input.\n */\nexport class FlowGraphPointerDownEventBlock extends FlowGraphEventBlock {\n    /**\n     * Optional input connection: restrict firing to this mesh (and its descendants).\n     * Leave disconnected to fire on any pointer down.\n     */\n    public readonly targetMesh: FlowGraphDataConnection<AbstractMesh>;\n\n    /**\n     * Output connection: The id of the pointer that triggered the event.\n     */\n    public readonly pointerId: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: The mesh that was picked (if any).\n     */\n    public readonly pickedMesh: FlowGraphDataConnection<Nullable<AbstractMesh>>;\n\n    /**\n     * Output connection: The world-space point that was picked (if any).\n     */\n    public readonly pickedPoint: FlowGraphDataConnection<Nullable<Vector3>>;\n\n    /** @internal */\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.PointerDown;\n\n    /**\n     * Creates a new FlowGraphPointerDownEventBlock.\n     * @param config optional configuration\n     */\n    public constructor(config?: IFlowGraphPointerDownEventBlockConfiguration) {\n        super(config);\n        this.targetMesh = this.registerDataInput(\"targetMesh\", RichTypeAny, config?.targetMesh);\n        this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\n        this.pickedMesh = this.registerDataOutput(\"pickedMesh\", RichTypeAny);\n        this.pickedPoint = this.registerDataOutput(\"pickedPoint\", RichTypeAny);\n    }\n\n    /** @internal */\n    public override _executeEvent(context: FlowGraphContext, pointerInfo: PointerInfo): boolean {\n        const mesh = this.targetMesh.getValue(context);\n        const pickedMesh = pointerInfo.pickInfo?.pickedMesh;\n\n        // If a target mesh is set, only fire when that mesh (or a descendant) is picked.\n        if (mesh && !(pickedMesh === mesh || (pickedMesh && _IsDescendantOf(pickedMesh, mesh)))) {\n            return true;\n        }\n\n        this.pointerId.setValue((pointerInfo.event as IPointerEvent).pointerId, context);\n        this.pickedMesh.setValue(pickedMesh ?? null, context);\n        this.pickedPoint.setValue(pointerInfo.pickInfo?.pickedPoint ?? null, context);\n        this._execute(context);\n        return !this.config?.stopPropagation;\n    }\n\n    /** @internal */\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /** @internal */\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /**\n     * @returns the class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PointerDownEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPointerDownEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPointerDownEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PointerDownEvent, FlowGraphPointerDownEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\nimport { FlowGraphEventBlock } from \"core/FlowGraph/flowGraphEventBlock\";\nimport { type PointerInfo } from \"core/Events/pointerEvents\";\nimport { type IPointerEvent } from \"core/Events/deviceInputEvents\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { _IsDescendantOf } from \"core/FlowGraph/utils\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Vector3 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { type Nullable } from \"core/types\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the pointer up event block.\n */\nexport interface IFlowGraphPointerUpEventBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Should this block stop propagation of the event to other listeners.\n     */\n    stopPropagation?: boolean;\n\n    /**\n     * Optional mesh to filter events to. If set, the block only fires when the pointer\n     * is released over this mesh or a descendant of it. If not set, fires on any pointer up.\n     */\n    targetMesh?: AbstractMesh;\n}\n\n/**\n * A pointer up event block.\n * This block fires when a pointer is released (mouse button up / touch end).\n * Optionally filters to a specific mesh via the `targetMesh` input.\n */\nexport class FlowGraphPointerUpEventBlock extends FlowGraphEventBlock {\n    /**\n     * Optional input connection: restrict firing to this mesh (and its descendants).\n     * Leave disconnected to fire on any pointer up.\n     */\n    public readonly targetMesh: FlowGraphDataConnection<AbstractMesh>;\n\n    /**\n     * Output connection: The id of the pointer that triggered the event.\n     */\n    public readonly pointerId: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: The mesh that was picked (if any).\n     */\n    public readonly pickedMesh: FlowGraphDataConnection<Nullable<AbstractMesh>>;\n\n    /**\n     * Output connection: The world-space point that was picked (if any).\n     */\n    public readonly pickedPoint: FlowGraphDataConnection<Nullable<Vector3>>;\n\n    /** @internal */\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.PointerUp;\n\n    /**\n     * Creates a new FlowGraphPointerUpEventBlock.\n     * @param config optional configuration\n     */\n    public constructor(config?: IFlowGraphPointerUpEventBlockConfiguration) {\n        super(config);\n        this.targetMesh = this.registerDataInput(\"targetMesh\", RichTypeAny, config?.targetMesh);\n        this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\n        this.pickedMesh = this.registerDataOutput(\"pickedMesh\", RichTypeAny);\n        this.pickedPoint = this.registerDataOutput(\"pickedPoint\", RichTypeAny);\n    }\n\n    /** @internal */\n    public override _executeEvent(context: FlowGraphContext, pointerInfo: PointerInfo): boolean {\n        const mesh = this.targetMesh.getValue(context);\n        const pickedMesh = pointerInfo.pickInfo?.pickedMesh;\n\n        // If a target mesh is set, only fire when that mesh (or a descendant) is picked.\n        if (mesh && !(pickedMesh === mesh || (pickedMesh && _IsDescendantOf(pickedMesh, mesh)))) {\n            return true;\n        }\n\n        this.pointerId.setValue((pointerInfo.event as IPointerEvent).pointerId, context);\n        this.pickedMesh.setValue(pickedMesh ?? null, context);\n        this.pickedPoint.setValue(pointerInfo.pickInfo?.pickedPoint ?? null, context);\n        this._execute(context);\n        return !this.config?.stopPropagation;\n    }\n\n    /** @internal */\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /** @internal */\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /**\n     * @returns the class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PointerUpEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPointerUpEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPointerUpEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PointerUpEvent, FlowGraphPointerUpEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\nimport { FlowGraphEventBlock } from \"core/FlowGraph/flowGraphEventBlock\";\nimport { type PointerInfo } from \"core/Events/pointerEvents\";\nimport { type IPointerEvent } from \"core/Events/deviceInputEvents\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration } from \"core/FlowGraph/flowGraphBlock\";\nimport { _IsDescendantOf } from \"core/FlowGraph/utils\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Vector3 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphEventType } from \"core/FlowGraph/flowGraphEventType\";\nimport { type Nullable } from \"core/types\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Configuration for the pointer move event block.\n */\nexport interface IFlowGraphPointerMoveEventBlockConfiguration extends IFlowGraphBlockConfiguration {\n    /**\n     * Should this block stop propagation of the event to other listeners.\n     */\n    stopPropagation?: boolean;\n\n    /**\n     * Optional mesh to filter events to. If set, the block only fires when the pointer\n     * is moving over this mesh or a descendant of it. If not set, fires on any pointer move.\n     */\n    targetMesh?: AbstractMesh;\n}\n\n/**\n * A pointer move event block.\n * This block fires when the pointer moves.\n * Optionally filters to a specific mesh via the `targetMesh` input.\n */\nexport class FlowGraphPointerMoveEventBlock extends FlowGraphEventBlock {\n    /**\n     * Optional input connection: restrict firing to when the pointer is over this mesh (and its descendants).\n     * Leave disconnected to fire on any pointer move.\n     */\n    public readonly targetMesh: FlowGraphDataConnection<AbstractMesh>;\n\n    /**\n     * Output connection: The id of the pointer that triggered the event.\n     */\n    public readonly pointerId: FlowGraphDataConnection<number>;\n\n    /**\n     * Output connection: The mesh currently under the pointer (if any).\n     */\n    public readonly meshUnderPointer: FlowGraphDataConnection<Nullable<AbstractMesh>>;\n\n    /**\n     * Output connection: The world-space point under the pointer (if any).\n     */\n    public readonly pickedPoint: FlowGraphDataConnection<Nullable<Vector3>>;\n\n    /** @internal */\n    public override readonly type: FlowGraphEventType = FlowGraphEventType.PointerMove;\n\n    /**\n     * Creates a new FlowGraphPointerMoveEventBlock.\n     * @param config optional configuration\n     */\n    public constructor(config?: IFlowGraphPointerMoveEventBlockConfiguration) {\n        super(config);\n        this.targetMesh = this.registerDataInput(\"targetMesh\", RichTypeAny, config?.targetMesh);\n        this.pointerId = this.registerDataOutput(\"pointerId\", RichTypeNumber);\n        this.meshUnderPointer = this.registerDataOutput(\"meshUnderPointer\", RichTypeAny);\n        this.pickedPoint = this.registerDataOutput(\"pickedPoint\", RichTypeAny);\n    }\n\n    /** @internal */\n    public override _executeEvent(context: FlowGraphContext, pointerInfo: PointerInfo): boolean {\n        const mesh = this.targetMesh.getValue(context);\n        const pickedMesh = pointerInfo.pickInfo?.pickedMesh;\n\n        // If a target mesh is set, only fire when that mesh (or a descendant) is under the pointer.\n        if (mesh && !(pickedMesh === mesh || (pickedMesh && _IsDescendantOf(pickedMesh, mesh)))) {\n            return true;\n        }\n\n        this.pointerId.setValue((pointerInfo.event as IPointerEvent).pointerId, context);\n        this.meshUnderPointer.setValue(pickedMesh ?? null, context);\n        this.pickedPoint.setValue(pointerInfo.pickInfo?.pickedPoint ?? null, context);\n        this._execute(context);\n        return !this.config?.stopPropagation;\n    }\n\n    /** @internal */\n    public override _preparePendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /** @internal */\n    public override _cancelPendingTasks(_context: FlowGraphContext): void {\n        // no-op\n    }\n\n    /**\n     * @returns the class name of the block.\n     */\n    public override getClassName(): string {\n        return FlowGraphBlockNames.PointerMoveEvent;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphPointerMoveEventBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphPointerMoveEventBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.PointerMoveEvent, FlowGraphPointerMoveEventBlock);\n}\n","/** This file must only contain pure code and pure imports */\n\nimport { type FlowGraphContext } from \"../../flowGraphContext\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"../../flowGraphBlock\";\nimport { type FlowGraphDataConnection } from \"../../flowGraphDataConnection.pure\";\nimport { RichTypeAny } from \"../../flowGraphRichTypes.pure\";\nimport { FlowGraphBlockNames } from \"../flowGraphBlockNames\";\nimport { type Nullable } from \"../../../types\";\nimport { RegisterClass } from \"../../../Misc/typeStore\";\n\n/**\n * Maximum number of log entries stored by the debug block.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst MAX_LOG_ENTRIES = 100;\n\n/**\n * A passthrough block used to debug data values flowing through connections.\n * Spliced into a data connection to observe the value passing through it.\n */\nexport class FlowGraphDebugBlock extends FlowGraphBlock {\n    /**\n     * Input connection: The value to observe.\n     */\n    public readonly input: FlowGraphDataConnection<any>;\n\n    /**\n     * Output connection: The same value, passed through unchanged.\n     */\n    public readonly output: FlowGraphDataConnection<any>;\n\n    /**\n     * Log of values that have passed through this block.\n     * Each entry is a [displayString, tooltipString] tuple.\n     */\n    public log: string[][] = [];\n\n    /**\n     * Whether this block is a debug block.\n     * Used by the editor to identify debug blocks.\n     */\n    public readonly _isDebug: boolean = true;\n\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(config);\n        this.input = this.registerDataInput(\"input\", RichTypeAny);\n        this.output = this.registerDataOutput(\"output\", RichTypeAny);\n    }\n\n    /**\n     * @internal\n     */\n    public override _updateOutputs(context: FlowGraphContext): void {\n        const value = this.input.getValue(context);\n        this.output.setValue(value, context);\n        this._logValue(value);\n    }\n\n    /**\n     * Format and store a value in the log.\n     * @param value\n     */\n    private _logValue(value: Nullable<any>): void {\n        if (value === null || value === undefined) {\n            this.log.push([\"null\", \"null\"]);\n        } else {\n            const formatted = FlowGraphDebugBlock._FormatValue(value);\n            this.log.push([formatted, String(value)]);\n        }\n        if (this.log.length > MAX_LOG_ENTRIES) {\n            this.log.shift();\n        }\n    }\n\n    /**\n     * Type-aware value formatting.\n     * @param value the value to format\n     * @returns a human-readable string\n     */\n    private static _FormatValue(value: any): string {\n        if (typeof value === \"number\") {\n            return Number.isInteger(value) ? value.toString() : value.toFixed(4);\n        }\n        if (typeof value === \"boolean\" || typeof value === \"string\") {\n            return String(value);\n        }\n        // Vector-like objects with x, y, z, w\n        if (value && typeof value === \"object\") {\n            if (\"w\" in value && \"x\" in value && \"y\" in value && \"z\" in value) {\n                return `(${value.x.toFixed(3)}, ${value.y.toFixed(3)}, ${value.z.toFixed(3)}, ${value.w.toFixed(3)})`;\n            }\n            if (\"z\" in value && \"x\" in value && \"y\" in value) {\n                return `(${value.x.toFixed(3)}, ${value.y.toFixed(3)}, ${value.z.toFixed(3)})`;\n            }\n            if (\"x\" in value && \"y\" in value) {\n                return `(${value.x.toFixed(3)}, ${value.y.toFixed(3)})`;\n            }\n            // Color3/Color4 with r, g, b\n            if (\"r\" in value && \"g\" in value && \"b\" in value) {\n                const a = \"a\" in value ? `, ${value.a.toFixed(3)}` : \"\";\n                return `(${value.r.toFixed(3)}, ${value.g.toFixed(3)}, ${value.b.toFixed(3)}${a})`;\n            }\n            if (typeof value.toString === \"function\" && value.toString !== Object.prototype.toString) {\n                return value.toString();\n            }\n        }\n        try {\n            const str = JSON.stringify(value);\n            return str.length > 64 ? str.substring(0, 61) + \"...\" : str;\n        } catch {\n            return String(value);\n        }\n    }\n\n    public override getClassName(): string {\n        return FlowGraphBlockNames.DebugBlock;\n    }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphDebugBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphDebugBlock(): void {\n    if (_Registered) {\n        return;\n    }\n    _Registered = true;\n\n    RegisterClass(FlowGraphBlockNames.DebugBlock, FlowGraphDebugBlock);\n}\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"oitFinalSimpleBlendPixelShader\";\nconst shader = `var uFrontColor: texture_2d<f32>;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {var fragCoord: vec2i=vec2i(fragmentInputs.position.xy);var frontColor: vec4f=textureLoad(uFrontColor,fragCoord,0);fragmentOutputs.color=frontColor;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const oitFinalSimpleBlendPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"oitFinalSimpleBlendPixelShader\";\nconst shader = `precision highp float;uniform sampler2D uFrontColor;void main() {ivec2 fragCoord=ivec2(gl_FragCoord.xy);vec4 frontColor=texelFetch(uFrontColor,fragCoord,0);glFragColor=frontColor;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const oitFinalSimpleBlendPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclarationWGSL } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclarationWGSL } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclarationWGSL } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclarationWGSL } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobalWGSL } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertexWGSL } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertexWGSL } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertexWGSL } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimationWGSL } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"selectionVertexShader\";\nconst shader = `attribute position: vec3f;\n#ifdef INSTANCES\nattribute instanceSelectionId: f32;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\n#include<instancesDeclaration>\nuniform viewProjection: mat4x4f;\n#ifdef STORE_CAMERASPACE_Z\nuniform view: mat4x4f;\n#else\nuniform depthValues: vec2f;\n#endif\n#ifdef INSTANCES\nflat varying vSelectionId: f32;\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvarying vViewPosZ: f32;\n#else\nvarying vDepthMetric: f32;\n#endif\n#ifdef ALPHATEST\nvarying vUV: vec2f;uniform diffuseMatrix: mat4x4f; \n#ifdef UV1\nattribute uv: vec2f;\n#endif\n#ifdef UV2\nattribute uv2: vec2f;\n#endif\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvar positionUpdated: vec3f=vertexInputs.position;\n#ifdef UV1\nvar uvUpdated: vec2f=vertexInputs.uv;\n#endif\n#ifdef UV2\nvar uv2Updated: vec2f=vertexInputs.uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvar worldPos: vec4f=finalWorld*vec4f(positionUpdated,1.0);vertexOutputs.position=uniforms.viewProjection*worldPos;\n#ifdef ALPHATEST\n#ifdef UV1\nvertexOutputs.vUV=(uniforms.diffuseMatrix*vec4f(uvUpdated,1.0,0.0)).xy;\n#endif\n#ifdef UV2\nvertexOutputs.vUV=(uniforms.diffuseMatrix*vec4f(uv2Updated,1.0,0.0)).xy;\n#endif\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvertexOutputs.vViewPosZ=(uniforms.view*worldPos).z;\n#else\n#ifdef USE_REVERSE_DEPTHBUFFER\nvertexOutputs.vDepthMetric=((-vertexOutputs.position.z+uniforms.depthValues.x)/(uniforms.depthValues.y));\n#else\nvertexOutputs.vDepthMetric=((vertexOutputs.position.z+uniforms.depthValues.x)/(uniforms.depthValues.y));\n#endif\n#endif\n#ifdef INSTANCES\nvertexOutputs.vSelectionId=vertexInputs.instanceSelectionId;\n#endif\n#include<clipPlaneVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [bonesDeclarationWGSL, bakedVertexAnimationDeclarationWGSL, morphTargetsVertexGlobalDeclarationWGSL, morphTargetsVertexDeclarationWGSL, clipPlaneVertexDeclarationWGSL, instancesDeclarationWGSL, morphTargetsVertexGlobalWGSL, morphTargetsVertexWGSL, instancesVertexWGSL, bonesVertexWGSL, bakedVertexAnimationWGSL, clipPlaneVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const selectionVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"selectionPixelShader\";\nconst shader = `#ifdef INSTANCES\nflat varying vSelectionId: f32;\n#else\nuniform selectionId: f32;\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvarying vViewPosZ: f32;\n#else\nvarying vDepthMetric: f32;\n#endif\n#ifdef ALPHATEST\nvarying vUV: vec2f;var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (textureSample(diffuseSampler,diffuseSamplerSampler,fragmentInputs.vUV).a<0.4) {discard;}\n#endif\n#ifdef INSTANCES\nvar id: f32=fragmentInputs.vSelectionId;\n#else\nvar id: f32=uniforms.selectionId;\n#endif\n#ifdef STORE_CAMERASPACE_Z\nfragmentOutputs.color=vec4(id,fragmentInputs.vViewPosZ,0.0,1.0);\n#else\nfragmentOutputs.color=vec4(id,fragmentInputs.vDepthMetric,0.0,1.0);\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclarationWGSL, clipPlaneFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const selectionPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"selectionOutlinePixelShader\";\nconst shader = `var maskSamplerSampler: sampler;var maskSampler: texture_2d<f32>;\n#ifdef OUTLINELAYER_DEPTH_OCCLUSION\nvar depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;\n#endif\nvarying vUV: vec2f;uniform screenSize: vec2f;uniform outlineColor: vec3f;uniform outlineThickness: f32;\n#ifdef OUTLINELAYER_DEPTH_OCCLUSION\nuniform occlusionStrength: f32;uniform occlusionThreshold: f32;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nlet texelSize: vec2f=1.0/uniforms.screenSize;let sampleOffset: vec2f=texelSize*uniforms.outlineThickness;\n#if defined(OUTLINELAYER_SAMPLING_TRIDIRECTIONAL) || defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet maskTopCenter: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(0.0,sampleOffset.y),0.0).rg;let maskTopRight: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+sampleOffset,0.0).rg;let maskMiddleCenter: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV,0.0).rg;let maskMiddleRight: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(sampleOffset.x,0.0),0.0).rg;\n#endif\n#if defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet maskTopLeft: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(-sampleOffset.x,sampleOffset.y),0.0).rg;let maskMiddleLeft: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(-sampleOffset.x,0.0),0.0).rg;let maskBottomRight: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(sampleOffset.x,-sampleOffset.y),0.0).rg;let maskBottomCenter: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(0.0,-sampleOffset.y),0.0).rg;let maskBottomLeft: vec2f=textureSampleLevel(maskSampler,maskSamplerSampler,fragmentInputs.vUV+vec2f(-sampleOffset.x,-sampleOffset.y),0.0).rg;\n#endif\n#ifdef OUTLINELAYER_SAMPLING_TRIDIRECTIONAL\nlet gradient: vec3f=vec3f(\nmaskMiddleCenter.r-maskMiddleRight.r,\nmaskMiddleCenter.r-maskTopCenter.r,\nmaskMiddleCenter.r-maskTopRight.r\n);let edgeStrength: f32=length(gradient);\n#elif defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet gradientX: f32 =\n(maskTopLeft.r+2.0*maskMiddleLeft.r+maskBottomLeft.r) -\n(maskTopRight.r+2.0*maskMiddleRight.r+maskBottomRight.r);let gradientY: f32 =\n(maskBottomLeft.r+2.0*maskBottomCenter.r+maskBottomRight.r) -\n(maskTopLeft.r+2.0*maskTopCenter.r+maskTopRight.r);let edgeStrength: f32=length(vec2f(gradientX,gradientY));\n#endif\nlet outlineMask: f32=step(0.5,edgeStrength); \nvar finalOutlineMask: f32=outlineMask;\n#ifdef OUTLINELAYER_DEPTH_OCCLUSION\nif (outlineMask>0.0) {\n#if defined(OUTLINELAYER_SAMPLING_TRIDIRECTIONAL) || defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet depthTopCenter: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(0.0,sampleOffset.y),0.0).r;let depthTopRight: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+sampleOffset,0.0).r;let depthMiddleCenter: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV,0.0).r;let depthMiddleRight: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(sampleOffset.x,0.0),0.0).r;\n#endif\n#if defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet depthTopLeft: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(-sampleOffset.x,sampleOffset.y),0.0).r;let depthMiddleLeft: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(-sampleOffset.x,0.0),0.0).r;let depthBottomRight: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(sampleOffset.x,-sampleOffset.y),0.0).r;let depthBottomCenter: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(0.0,-sampleOffset.y),0.0).r;let depthBottomLeft: f32=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV+vec2f(-sampleOffset.x,-sampleOffset.y),0.0).r;\n#endif\n#if defined(OUTLINELAYER_SAMPLING_TRIDIRECTIONAL) || defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet occlusionTopCenter: f32=step(uniforms.occlusionThreshold,abs(maskTopCenter.g-depthTopCenter));let occlusionTopRight: f32=step(uniforms.occlusionThreshold,abs(maskTopRight.g-depthTopRight));let occlusionMiddleCenter: f32=step(uniforms.occlusionThreshold,abs(maskMiddleCenter.g-depthMiddleCenter));let occlusionMiddleRight: f32=step(uniforms.occlusionThreshold,abs(maskMiddleRight.g-depthMiddleRight));\n#endif\n#if defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nlet occlusionTopLeft: f32=step(uniforms.occlusionThreshold,abs(maskTopLeft.g-depthTopLeft));let occlusionMiddleLeft: f32=step(uniforms.occlusionThreshold,abs(maskMiddleLeft.g-depthMiddleLeft));let occlusionBottomRight: f32=step(uniforms.occlusionThreshold,abs(maskBottomRight.g-depthBottomRight));let occlusionBottomCenter: f32=step(uniforms.occlusionThreshold,abs(maskBottomCenter.g-depthBottomCenter));let occlusionBottomLeft: f32=step(uniforms.occlusionThreshold,abs(maskBottomLeft.g-depthBottomLeft));\n#endif\nvar occlusionFactor: f32=occlusionMiddleCenter;\n#ifdef OUTLINELAYER_SAMPLING_TRIDIRECTIONAL\nocclusionFactor=min(occlusionFactor,occlusionTopCenter);occlusionFactor=min(occlusionFactor,occlusionTopRight);occlusionFactor=min(occlusionFactor,occlusionMiddleRight);\n#elif defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nocclusionFactor=min(occlusionFactor,occlusionTopCenter);occlusionFactor=min(occlusionFactor,occlusionTopRight);occlusionFactor=min(occlusionFactor,occlusionTopLeft);occlusionFactor=min(occlusionFactor,occlusionMiddleRight);occlusionFactor=min(occlusionFactor,occlusionMiddleLeft);occlusionFactor=min(occlusionFactor,occlusionBottomRight);occlusionFactor=min(occlusionFactor,occlusionBottomCenter);occlusionFactor=min(occlusionFactor,occlusionBottomLeft);\n#endif\nfinalOutlineMask*=1.0-uniforms.occlusionStrength*occlusionFactor;}\n#endif\nfragmentOutputs.color=vec4f(uniforms.outlineColor,finalOutlineMask);\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const selectionOutlinePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { bonesDeclaration } from \"./ShadersInclude/bonesDeclaration\";\nimport { bakedVertexAnimationDeclaration } from \"./ShadersInclude/bakedVertexAnimationDeclaration\";\nimport { morphTargetsVertexGlobalDeclaration } from \"./ShadersInclude/morphTargetsVertexGlobalDeclaration\";\nimport { morphTargetsVertexDeclaration } from \"./ShadersInclude/morphTargetsVertexDeclaration\";\nimport { clipPlaneVertexDeclaration } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { instancesDeclaration } from \"./ShadersInclude/instancesDeclaration\";\nimport { morphTargetsVertexGlobal } from \"./ShadersInclude/morphTargetsVertexGlobal\";\nimport { morphTargetsVertex } from \"./ShadersInclude/morphTargetsVertex\";\nimport { instancesVertex } from \"./ShadersInclude/instancesVertex\";\nimport { bonesVertex } from \"./ShadersInclude/bonesVertex\";\nimport { bakedVertexAnimation } from \"./ShadersInclude/bakedVertexAnimation\";\nimport { clipPlaneVertex } from \"./ShadersInclude/clipPlaneVertex\";\n\nconst name = \"selectionVertexShader\";\nconst shader = `attribute vec3 position;\n#ifdef INSTANCES\nattribute float instanceSelectionId;\n#endif\n#include<bonesDeclaration>\n#include<bakedVertexAnimationDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<clipPlaneVertexDeclaration>\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\n#ifdef STORE_CAMERASPACE_Z\nuniform mat4 view;\n#else\nuniform vec2 depthValues;\n#endif\n#ifdef INSTANCES\nflat varying float vSelectionId;\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvarying float vViewPosZ;\n#else\nvarying float vDepthMetric;\n#endif\n#ifdef ALPHATEST\nvarying vec2 vUV;uniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#ifdef UV2\nvec2 uv2Updated=uv2;\n#endif\n#include<morphTargetsVertexGlobal>\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#include<bakedVertexAnimation>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);gl_Position=viewProjection*worldPos;\n#ifdef ALPHATEST\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2Updated,1.0,0.0));\n#endif\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvViewPosZ=(view*worldPos).z;\n#else\n#ifdef USE_REVERSE_DEPTHBUFFER\nvDepthMetric=((-gl_Position.z+depthValues.x)/(depthValues.y));\n#else\nvDepthMetric=((gl_Position.z+depthValues.x)/(depthValues.y));\n#endif\n#endif\n#ifdef INSTANCES\nvSelectionId=instanceSelectionId;\n#endif\n#include<clipPlaneVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [bonesDeclaration, bakedVertexAnimationDeclaration, morphTargetsVertexGlobalDeclaration, morphTargetsVertexDeclaration, clipPlaneVertexDeclaration, instancesDeclaration, morphTargetsVertexGlobal, morphTargetsVertex, instancesVertex, bonesVertex, bakedVertexAnimation, clipPlaneVertex];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const selectionVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneFragmentDeclaration } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { clipPlaneFragment } from \"./ShadersInclude/clipPlaneFragment\";\n\nconst name = \"selectionPixelShader\";\nconst shader = `#ifdef INSTANCES\nflat varying float vSelectionId;\n#else\nuniform float selectionId;\n#endif\n#ifdef STORE_CAMERASPACE_Z\nvarying float vViewPosZ;\n#else\nvarying float vDepthMetric;\n#endif\n#ifdef ALPHATEST\nvarying vec2 vUV;uniform sampler2D diffuseSampler;\n#endif\n#include<clipPlaneFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\n#ifdef INSTANCES\nfloat id=vSelectionId;\n#else\nfloat id=selectionId;\n#endif\n#ifdef STORE_CAMERASPACE_Z\ngl_FragColor=vec4(id,vViewPosZ,0.0,1.0);\n#else\ngl_FragColor=vec4(id,vDepthMetric,0.0,1.0);\n#endif\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [clipPlaneFragmentDeclaration, clipPlaneFragment];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const selectionPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"selectionOutlinePixelShader\";\nconst shader = `uniform sampler2D maskSampler;\n#ifdef OUTLINELAYER_DEPTH_OCCLUSION\nuniform sampler2D depthSampler;\n#endif\nvarying vec2 vUV;uniform vec2 screenSize;uniform vec3 outlineColor;uniform float outlineThickness;\n#ifdef OUTLINELAYER_DEPTH_OCCLUSION\nuniform float occlusionStrength;uniform float occlusionThreshold;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec2 texelSize=1.0/screenSize;vec2 sampleOffset=texelSize*outlineThickness;\n#if defined(OUTLINELAYER_SAMPLING_TRIDIRECTIONAL) || defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nvec2 maskTopCenter=texture2D(maskSampler,vUV+vec2(0.0,sampleOffset.y)).rg;vec2 maskTopRight=texture2D(maskSampler,vUV+sampleOffset).rg;vec2 maskMiddleCenter=texture2D(maskSampler,vUV).rg;vec2 maskMiddleRight=texture2D(maskSampler,vUV+vec2(sampleOffset.x,0.0)).rg;\n#endif\n#if defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nvec2 maskTopLeft=texture2D(maskSampler,vUV+vec2(-sampleOffset.x,sampleOffset.y)).rg;vec2 maskMiddleLeft=texture2D(maskSampler,vUV+vec2(-sampleOffset.x,0.0)).rg;vec2 maskBottomRight=texture2D(maskSampler,vUV+vec2(sampleOffset.x,-sampleOffset.y)).rg;vec2 maskBottomCenter=texture2D(maskSampler,vUV+vec2(0.0,-sampleOffset.y)).rg;vec2 maskBottomLeft=texture2D(maskSampler,vUV+vec2(-sampleOffset.x,-sampleOffset.y)).rg;\n#endif\n#ifdef OUTLINELAYER_SAMPLING_TRIDIRECTIONAL\nvec3 gradient=vec3(\nmaskMiddleCenter.r-maskMiddleRight.r,\nmaskMiddleCenter.r-maskTopCenter.r,\nmaskMiddleCenter.r-maskTopRight.r\n);float edgeStrength=length(gradient);\n#elif defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nfloat gradientX =\n(maskTopLeft.r+2.0*maskMiddleLeft.r+maskBottomLeft.r) -\n(maskTopRight.r+2.0*maskMiddleRight.r+maskBottomRight.r);float gradientY =\n(maskBottomLeft.r+2.0*maskBottomCenter.r+maskBottomRight.r) -\n(maskTopLeft.r+2.0*maskTopCenter.r+maskTopRight.r);float edgeStrength=length(vec2(gradientX,gradientY));\n#endif\nfloat outlineMask=step(0.5,edgeStrength); \nfloat finalOutlineMask=outlineMask;\n#ifdef OUTLINELAYER_DEPTH_OCCLUSION\nif (outlineMask>0.0) {\n#if defined(OUTLINELAYER_SAMPLING_TRIDIRECTIONAL) || defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nfloat depthTopCenter=texture2D(depthSampler,vUV+vec2(0.0,sampleOffset.y)).r;float depthTopRight=texture2D(depthSampler,vUV+sampleOffset).r;float depthMiddleCenter=texture2D(depthSampler,vUV).r;float depthMiddleRight=texture2D(depthSampler,vUV+vec2(sampleOffset.x,0.0)).r;\n#endif\n#if defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nfloat depthTopLeft=texture2D(depthSampler,vUV+vec2(-sampleOffset.x,sampleOffset.y)).r;float depthMiddleLeft=texture2D(depthSampler,vUV+vec2(-sampleOffset.x,0.0)).r;float depthBottomRight=texture2D(depthSampler,vUV+vec2(sampleOffset.x,-sampleOffset.y)).r;float depthBottomCenter=texture2D(depthSampler,vUV+vec2(0.0,-sampleOffset.y)).r;float depthBottomLeft=texture2D(depthSampler,vUV+vec2(-sampleOffset.x,-sampleOffset.y)).r;\n#endif\n#if defined(OUTLINELAYER_SAMPLING_TRIDIRECTIONAL) || defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nfloat occlusionTopCenter=step(occlusionThreshold,abs(maskTopCenter.g-depthTopCenter));float occlusionTopRight=step(occlusionThreshold,abs(maskTopRight.g-depthTopRight));float occlusionMiddleCenter=step(occlusionThreshold,abs(maskMiddleCenter.g-depthMiddleCenter));float occlusionMiddleRight=step(occlusionThreshold,abs(maskMiddleRight.g-depthMiddleRight));\n#endif\n#if defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nfloat occlusionTopLeft=step(occlusionThreshold,abs(maskTopLeft.g-depthTopLeft));float occlusionMiddleLeft=step(occlusionThreshold,abs(maskMiddleLeft.g-depthMiddleLeft));float occlusionBottomRight=step(occlusionThreshold,abs(maskBottomRight.g-depthBottomRight));float occlusionBottomCenter=step(occlusionThreshold,abs(maskBottomCenter.g-depthBottomCenter));float occlusionBottomLeft=step(occlusionThreshold,abs(maskBottomLeft.g-depthBottomLeft));\n#endif\nfloat occlusionFactor=occlusionMiddleCenter;\n#ifdef OUTLINELAYER_SAMPLING_TRIDIRECTIONAL\nocclusionFactor=min(occlusionFactor,occlusionTopCenter);occlusionFactor=min(occlusionFactor,occlusionTopRight);occlusionFactor=min(occlusionFactor,occlusionMiddleRight);\n#elif defined(OUTLINELAYER_SAMPLING_OCTADIRECTIONAL)\nocclusionFactor=min(occlusionFactor,occlusionTopCenter);occlusionFactor=min(occlusionFactor,occlusionTopRight);occlusionFactor=min(occlusionFactor,occlusionTopLeft);occlusionFactor=min(occlusionFactor,occlusionMiddleRight);occlusionFactor=min(occlusionFactor,occlusionMiddleLeft);occlusionFactor=min(occlusionFactor,occlusionBottomRight);occlusionFactor=min(occlusionFactor,occlusionBottomCenter);occlusionFactor=min(occlusionFactor,occlusionBottomLeft);\n#endif\nfinalOutlineMask*=1.0-occlusionStrength*occlusionFactor;}\n#endif\ngl_FragColor=vec4(outlineColor,finalOutlineMask);\n#define CUSTOM_FRAGMENT_MAIN_END\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const selectionOutlinePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshBlendingPixelShader\";\nconst shader = `#define DISABLE_UNIFORMITY_ANALYSIS\nvarying vUV: vec2f;var textureSampler: texture_2d<f32>;var meshBlendTagSampler: texture_2d<u32>;var meshBlendDepthSampler: texture_2d<f32>;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nvar meshBlendBaseColorSampler: texture_2d<f32>;\n#endif\nvar meshBlendBlueNoiseSampler: texture_2d<f32>;uniform projection: mat4x4f;uniform inverseProjection: mat4x4f;uniform inverseView: mat4x4f;uniform blendWorldRadii: vec4f;uniform minimumProjectedRadii: vec4f;uniform meshBlendIsOrthographic: f32;uniform slopeFactor: f32;\n#ifndef MESH_BLEND_DIRECTION_COUNT\n#define MESH_BLEND_DIRECTION_COUNT 3\n#define MESH_BLEND_RADIAL_SAMPLE_COUNT 3\n#define MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT 2\n#define MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT 4\n#define MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT 8\n#define MESH_BLEND_RADIUS_SCALE 0.9\n#define MESH_BLEND_JITTER_FACTOR 0.5\n#define MESH_BLEND_COLOR_INTERPOLATION_OKLAB\n#endif\n#define MESH_BLEND_TWO_PI 6.283185307179586\n#define MESH_BLEND_EPSILON 0.00001\n#define MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE 0.2\n#define MESH_BLEND_TINY_OBJECT_PROBE_COUNT 8\n#define MESH_BLEND_MIN_SLOPE_SCALE 0.25\n#define MESH_BLEND_BOUNDARY_SEPARATION_FACTOR 0.75\n#define MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE 3.0\n#define MESH_BLEND_FOREGROUND_DEPTH_FACTOR 0.35\n#define MESH_BLEND_FOREGROUND_LATERAL_FACTOR 2.0\n#define MESH_BLEND_TARGET_SPAN_FACTOR 1.5\n#define MESH_BLEND_TOTAL_SPAN_FACTOR 2.5\n#define MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT 0.35\n#define MESH_BLEND_NEAR_SEAM_MAX_DISTANCE 1.25\n#define MESH_BLEND_NEAR_SEAM_COLOR_DELTA 0.02\n#define MESH_BLEND_BASE_LUMINANCE_EPSILON 0.00001\n#define MESH_BLEND_TARGET_DARKER_RATIO 0.65\n#define MESH_BLEND_TARGET_NON_DARK_RATIO 0.9\n#define MESH_BLEND_SHADOW_DIFFERENCE_LOW 0.15\n#define MESH_BLEND_SHADOW_DIFFERENCE_HIGH 0.5\n#define MESH_BLEND_SHADOW_MIN_ATTENUATION 0.25\n#define MESH_BLEND_REJECTION_NONE 0\n#define MESH_BLEND_REJECTION_NO_CANDIDATE 1\n#define MESH_BLEND_REJECTION_NO_CONTINUATION 2\n#define MESH_BLEND_REJECTION_INVALID_DEPTH 3\n#define MESH_BLEND_REJECTION_DEPTH_SEPARATION 4\n#define MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND 5\n#define MESH_BLEND_REJECTION_PHYSICAL_SPAN 6\n#define MESH_BLEND_REJECTION_CONTACT_ANGLE 7\nstruct MeshBlendTag {groupId: u32,\nradiusClass: u32,};struct MeshBlendCandidate {targetGroupId: u32,\nradiusClass: u32,\ndirection: vec2f,\ndistancePixels: f32,\nsearchRadiusPixels: f32,\nscore: f32,\nvalid: bool,};struct MeshBlendResult {candidate: MeshBlendCandidate,\ntargetPixel: vec2i,\ntargetFarPixel: vec2i,\ncurrentViewPosition: vec3f,\neffectiveRadiusPixels: f32,\nfade: f32,\ntinyObjectRadiusRatio: f32,\nrejectionReason: i32,\nstageReached: i32,\nvalid: bool,\ncontinuationFound: bool,\nusedFallback: bool,\ntinyObjectRadiusReduced: bool,};struct MeshBlendTargetColorSamples {fartherColor: vec4f,\nboundaryPlusOneColor: vec4f,\nboundaryPlusTwoColor: vec4f,\nconservativeNearColor: vec4f,\ntargetColor: vec4f,\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nfartherBaseColor: vec3f,\nconservativeNearBaseColor: vec3f,\n#endif\nonePixelEdge: bool,};struct MeshBlendColorEvaluation {samples: MeshBlendTargetColorSamples,\ncurrentColor: vec4f,\nblendedColor: vec4f,\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nworldPosition: vec3f,\n#endif\nshadowAttenuation: f32,\nadjustedFade: f32,\nnearSeamCorrected: bool,};fn clampPixel(pixel: vec2i,renderSize: vec2i)->vec2i {return clamp(pixel,vec2i(0),renderSize-vec2i(1));}\nfn isPixelInBounds(pixel: vec2i,renderSize: vec2i)->bool {return pixel.x>=0 && pixel.y>=0 && pixel.x<renderSize.x && pixel.y<renderSize.y;}\nfn pixelToUv(pixel: vec2i,renderSize: vec2i)->vec2f {return (vec2f(clampPixel(pixel,renderSize))+vec2f(0.5))/vec2f(renderSize);}\nfn loadMeshBlendTag(pixel: vec2i,renderSize: vec2i)->MeshBlendTag {let packedTag: u32=textureLoad(meshBlendTagSampler,clampPixel(pixel,renderSize),0).r;var tag: MeshBlendTag;tag.groupId=packedTag & 0x3fu;tag.radiusClass=packedTag>>6u;return tag;}\nfn loadMeshBlendDepth(pixel: vec2i,renderSize: vec2i)->f32 {return textureLoad(meshBlendDepthSampler,clampPixel(pixel,renderSize),0).r;}\nfn classValue(values: vec4f,index: u32)->f32 {if (index==0u) {return values.x;}\nif (index==1u) {return values.y;}\nif (index==2u) {return values.z;}\nreturn values.w;}\nfn meshBlendDepthToNdc(depth: f32)->f32 {\n#ifdef MESH_BLEND_DEPTH_SCREEN\n#ifdef IS_NDC_HALF_ZRANGE\nreturn depth;\n#else\nreturn depth*2.0-1.0;\n#endif\n#else\nlet projectedDepth: vec4f=uniforms.projection*vec4f(0.0,0.0,depth,1.0);return projectedDepth.z/projectedDepth.w;\n#endif\n}\nfn reconstructMeshBlendViewPosition(pixel: vec2i,renderSize: vec2i,depth: f32)->vec3f {let ndcXY: vec2f=pixelToUv(pixel,renderSize)*2.0-1.0;let viewPosition: vec4f=uniforms.inverseProjection*vec4f(ndcXY,meshBlendDepthToNdc(depth),1.0);return viewPosition.xyz/viewPosition.w;}\nfn reconstructMeshBlendWorldPosition(viewPosition: vec3f)->vec3f {return (uniforms.inverseView*vec4f(viewPosition,1.0)).xyz;}\nfn isFiniteMeshBlendValue(value: f32)->bool {return (bitcast<u32>(value) & 0x7f800000u) != 0x7f800000u;}\nfn isValidMeshBlendPosition(position: vec3f)->bool {return isFiniteMeshBlendValue(position.x) && isFiniteMeshBlendValue(position.y) && isFiniteMeshBlendValue(position.z);}\nfn meshBlendProjectionScale(renderHeight: f32)->f32 {return max(0.5*renderHeight*abs(uniforms.projection[1][1]),MESH_BLEND_EPSILON);}\nfn searchRadiusForClass(radiusClass: u32,viewDepth: f32,renderHeight: f32)->f32 {let projectionScale: f32=meshBlendProjectionScale(renderHeight);var projectedWorldRadius: f32=classValue(uniforms.blendWorldRadii,radiusClass)*projectionScale;if (uniforms.meshBlendIsOrthographic<0.5) {projectedWorldRadius/=max(viewDepth,MESH_BLEND_EPSILON);}\nlet scaledRadius: f32=max(projectedWorldRadius,classValue(uniforms.minimumProjectedRadii,radiusClass))*MESH_BLEND_RADIUS_SCALE;return select(0.0,max(1.0,scaledRadius),scaledRadius>0.0);}\nfn worldUnitsPerPixel(viewDepth: f32,renderHeight: f32)->f32 {let unitsPerPixel: f32=1.0/meshBlendProjectionScale(renderHeight);if (uniforms.meshBlendIsOrthographic>0.5) {return unitsPerPixel;}\nreturn unitsPerPixel*max(viewDepth,MESH_BLEND_EPSILON);}\nfn calculateSlopeScale(oppositeFacing: f32)->f32 {if (uniforms.slopeFactor<=1.0) {return 1.0;}\nreturn MESH_BLEND_MIN_SLOPE_SCALE +\n(1.0-MESH_BLEND_MIN_SLOPE_SCALE)*pow(clamp(oppositeFacing,0.0,1.0),uniforms.slopeFactor-1.0);}\nfn loadStableBlueNoise(pixel: vec2i)->vec2f {let noiseSize: vec2i=vec2i(textureDimensions(meshBlendBlueNoiseSampler,0));let wrappedPixel: vec2i=vec2i(pixel.x % noiseSize.x,pixel.y % noiseSize.y);return textureLoad(meshBlendBlueNoiseSampler,wrappedPixel,0).rg;}\nfn directionAt(index: i32,rotation: f32,sectorAngle: f32,direction0: vec2f,direction1: vec2f,direction2: vec2f)->vec2f {\n#if MESH_BLEND_DIRECTION_COUNT==3\nif (index==0) {return direction0;}\nif (index==1) {return direction1;}\nreturn direction2;\n#else\nlet angle: f32=rotation+sectorAngle*f32(index);return vec2f(cos(angle),sin(angle));\n#endif\n}\nfn invalidCandidate()->MeshBlendCandidate {var candidate: MeshBlendCandidate;candidate.targetGroupId=0u;candidate.radiusClass=0u;candidate.direction=vec2f(0.0);candidate.distancePixels=0.0;candidate.searchRadiusPixels=0.0;candidate.score=-1.0;candidate.valid=false;return candidate;}\nfn invalidBlendResult()->MeshBlendResult {var result: MeshBlendResult;result.candidate=invalidCandidate();result.targetPixel=vec2i(0);result.targetFarPixel=vec2i(0);result.currentViewPosition=vec3f(0.0);result.effectiveRadiusPixels=0.0;result.fade=0.0;result.tinyObjectRadiusRatio=1.0;result.rejectionReason=MESH_BLEND_REJECTION_NO_CANDIDATE;result.stageReached=1;result.valid=false;result.continuationFound=false;result.usedFallback=false;result.tinyObjectRadiusReduced=false;return result;}\nfn findInitialCandidate(\npixel: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\ncurrentSearchRadius: f32,\nviewDepth: f32,\nignoredGroupId: u32,\nrandomValues: vec2f,\nrotation: f32,\nsectorAngle: f32,\ndirection0: vec2f,\ndirection1: vec2f,\ndirection2: vec2f\n)->MeshBlendCandidate {var best: MeshBlendCandidate=invalidCandidate();let radialJitter: f32=mix(0.5,randomValues.y,MESH_BLEND_JITTER_FACTOR);for (var radialIndex: i32=0; radialIndex<MESH_BLEND_RADIAL_SAMPLE_COUNT; radialIndex++) {let normalizedDistance: f32=(f32(radialIndex)+radialJitter)/f32(MESH_BLEND_RADIAL_SAMPLE_COUNT);let distancePixels: f32=max(1.0,ceil(normalizedDistance*normalizedDistance*normalizedDistance*currentSearchRadius));for (var directionIndex: i32=0; directionIndex<MESH_BLEND_DIRECTION_COUNT; directionIndex++) {let direction: vec2f=directionAt(directionIndex,rotation,sectorAngle,direction0,direction1,direction2);let samplePixel: vec2i=pixel+vec2i(round(direction*distancePixels));let candidateTag: MeshBlendTag=loadMeshBlendTag(samplePixel,renderSize);if (candidateTag.groupId==0u || candidateTag.groupId==currentTag.groupId || candidateTag.groupId==ignoredGroupId) {continue;}\nlet seamRadiusClass: u32=min(currentTag.radiusClass,candidateTag.radiusClass);let candidateSearchRadius: f32=searchRadiusForClass(seamRadiusClass,viewDepth,f32(renderSize.y));if (distancePixels>candidateSearchRadius) {continue;}\nlet score: f32=1.0-clamp(distancePixels/max(candidateSearchRadius,MESH_BLEND_EPSILON),0.0,1.0);if (score>best.score) {best.targetGroupId=candidateTag.groupId;best.radiusClass=seamRadiusClass;best.direction=direction;best.distancePixels=distancePixels;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}\nif (best.valid) {break;}}\nreturn best;}\nfn refineCandidateDirection(pixel: vec2i,renderSize: vec2i,candidate: MeshBlendCandidate,randomValues: vec2f)->MeshBlendCandidate {var refinedCandidate: MeshBlendCandidate=candidate;if (refinedCandidate.distancePixels<=2.0) {return refinedCandidate;}\nlet centerAngle: f32=atan2(refinedCandidate.direction.y,refinedCandidate.direction.x);let angularHalfWidth: f32=(MESH_BLEND_TWO_PI/f32(MESH_BLEND_DIRECTION_COUNT))*MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE;let stepSize: f32=max(1.0,refinedCandidate.distancePixels/f32(MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT+1));for (var sampleIndex: i32=0; sampleIndex<MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT; sampleIndex++) {let sampleRandom: f32=fract(randomValues.y+randomValues.x*0.754877666+f32(sampleIndex)*0.618033989);let angle: f32=centerAngle+mix(-angularHalfWidth,angularHalfWidth,sampleRandom);let direction: vec2f=vec2f(cos(angle),sin(angle));var testDistance: f32=refinedCandidate.distancePixels-stepSize;for (var stepIndex: i32=0; stepIndex<MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT; stepIndex++) {if (testDistance<=0.0) {break;}\nlet samplePixel: vec2i=pixel+vec2i(round(direction*testDistance));let sampleTag: MeshBlendTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != refinedCandidate.targetGroupId) {break;}\nrefinedCandidate.direction=direction;refinedCandidate.distancePixels=testDistance;testDistance-=stepSize;}}\nreturn refinedCandidate;}\nfn refineExactBoundary(pixel: vec2i,renderSize: vec2i,candidate: MeshBlendCandidate)->MeshBlendCandidate {var refinedCandidate: MeshBlendCandidate=candidate;var distancePixels: f32=refinedCandidate.distancePixels;for (var sampleIndex: i32=0; sampleIndex<MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT; sampleIndex++) {distancePixels-=1.0;if (distancePixels<=0.0) {break;}\nlet samplePixel: vec2i=pixel+vec2i(round(refinedCandidate.direction*distancePixels));let sampleTag: MeshBlendTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != refinedCandidate.targetGroupId) {break;}\nrefinedCandidate.distancePixels=distancePixels;}\nreturn refinedCandidate;}\nfn hasTargetContinuation(\npixel: vec2i,\nrenderSize: vec2i,\ncandidate: MeshBlendCandidate,\ncontinuationPixel: ptr<function,vec2i>\n)->bool {let continuationDistance: f32=max(candidate.distancePixels*2.0,candidate.distancePixels+1.0);*continuationPixel=pixel+vec2i(round(candidate.direction*continuationDistance));if (!isPixelInBounds(*continuationPixel,renderSize)) {return false;}\nreturn loadMeshBlendTag(*continuationPixel,renderSize).groupId==candidate.targetGroupId;}\nfn applyTargetRadiusClass(\ntargetPixel: vec2i,\nrenderSize: vec2i,\nviewDepth: f32,\ncandidate: ptr<function,MeshBlendCandidate>\n)->bool {let targetTag: MeshBlendTag=loadMeshBlendTag(targetPixel,renderSize);(*candidate).radiusClass=min((*candidate).radiusClass,targetTag.radiusClass);(*candidate).searchRadiusPixels=min(\n(*candidate).searchRadiusPixels,\nsearchRadiusForClass((*candidate).radiusClass,viewDepth,f32(renderSize.y))\n);return (*candidate).distancePixels<=(*candidate).searchRadiusPixels;}\n#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\nfn findImmediateNeighborCandidate(\npixel: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\nviewDepth: f32,\nignoredGroupId: u32,\npreferredGroupId: u32\n)->MeshBlendCandidate {var best: MeshBlendCandidate=invalidCandidate();for (var neighborIndex: i32=0; neighborIndex<4; neighborIndex++) {var offset: vec2i;if (neighborIndex==0) {offset=vec2i(1,0);} else if (neighborIndex==1) {offset=vec2i(-1,0);} else if (neighborIndex==2) {offset=vec2i(0,1);} else {offset=vec2i(0,-1);}\nlet neighborTag: MeshBlendTag=loadMeshBlendTag(pixel+offset,renderSize);if (neighborTag.groupId==0u || neighborTag.groupId==currentTag.groupId || neighborTag.groupId==ignoredGroupId) {continue;}\nlet seamRadiusClass: u32=min(currentTag.radiusClass,neighborTag.radiusClass);let candidateSearchRadius: f32=searchRadiusForClass(seamRadiusClass,viewDepth,f32(renderSize.y));if (candidateSearchRadius<1.0) {continue;}\nvar score: f32=1.0-1.0/max(candidateSearchRadius,1.0);if (neighborTag.groupId==preferredGroupId) {score+=1.0;}\nif (score>best.score) {best.targetGroupId=neighborTag.groupId;best.radiusClass=seamRadiusClass;best.direction=vec2f(offset);best.distancePixels=1.0;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}\nreturn best;}\n#endif\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nfn reduceRadiusForTinyObject(\npixel: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\ncandidate: MeshBlendCandidate,\nradiusReduced: ptr<function,bool>\n)->f32 {var measuredThickness: f32=candidate.searchRadiusPixels;var foundOppositeBoundary: bool=false;for (var probeIndex: i32=1; probeIndex<=MESH_BLEND_TINY_OBJECT_PROBE_COUNT; probeIndex++) {let probeDistance: f32=max(1.0,candidate.searchRadiusPixels*f32(probeIndex)/f32(MESH_BLEND_TINY_OBJECT_PROBE_COUNT));let oppositeTag: MeshBlendTag=loadMeshBlendTag(pixel-vec2i(round(candidate.direction*probeDistance)),renderSize);if (oppositeTag.groupId != currentTag.groupId) {measuredThickness=probeDistance;foundOppositeBoundary=true;break;}}\nvar outsideDirectionCount: i32=0;for (var neighborIndex: i32=0; neighborIndex<4; neighborIndex++) {var direction: vec2f;if (neighborIndex==0) {direction=vec2f(1.0,0.0);} else if (neighborIndex==1) {direction=vec2f(-1.0,0.0);} else if (neighborIndex==2) {direction=vec2f(0.0,1.0);} else {direction=vec2f(0.0,-1.0);}\nlet radiusTag: MeshBlendTag=loadMeshBlendTag(pixel+vec2i(round(direction*candidate.searchRadiusPixels)),renderSize);if (radiusTag.groupId != currentTag.groupId) {outsideDirectionCount++;}}\n*radiusReduced=foundOppositeBoundary && outsideDirectionCount>=3;if (!*radiusReduced) {return candidate.searchRadiusPixels;}\nlet thicknessRadius: f32=max(1.0,measuredThickness*1.25);return max(candidate.distancePixels,min(candidate.searchRadiusPixels,thicknessRadius));}\n#endif\nfn validateMeshBlendContact(\npixelA: vec2i,\npixelE: vec2i,\npixelB: vec2i,\npixelC: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\ncandidate: MeshBlendCandidate,\nallowMissingContinuation: bool,\nnarrowedSearchRadius: ptr<function,f32>,\ncurrentViewPosition: ptr<function,vec3f>\n)->i32 {*currentViewPosition=vec3f(0.0);let tagE: MeshBlendTag=loadMeshBlendTag(pixelE,renderSize);let tagB: MeshBlendTag=loadMeshBlendTag(pixelB,renderSize);let tagC: MeshBlendTag=loadMeshBlendTag(pixelC,renderSize);if (\ntagE.groupId != currentTag.groupId ||\ntagB.groupId != candidate.targetGroupId ||\n(!allowMissingContinuation && tagC.groupId != candidate.targetGroupId)\n) {return MESH_BLEND_REJECTION_NO_CONTINUATION;}\nlet depthA: f32=loadMeshBlendDepth(pixelA,renderSize);let depthE: f32=loadMeshBlendDepth(pixelE,renderSize);let depthB: f32=loadMeshBlendDepth(pixelB,renderSize);let depthC: f32=loadMeshBlendDepth(pixelC,renderSize);let positionA: vec3f=reconstructMeshBlendViewPosition(pixelA,renderSize,depthA);let positionE: vec3f=reconstructMeshBlendViewPosition(pixelE,renderSize,depthE);let positionB: vec3f=reconstructMeshBlendViewPosition(pixelB,renderSize,depthB);let positionC: vec3f=reconstructMeshBlendViewPosition(pixelC,renderSize,depthC);if (!isValidMeshBlendPosition(positionA) || !isValidMeshBlendPosition(positionE) || !isValidMeshBlendPosition(positionB) || !isValidMeshBlendPosition(positionC)) {return MESH_BLEND_REJECTION_INVALID_DEPTH;}\n*currentViewPosition=positionA;let viewDepth: f32=abs(positionA.z);let unitsPerPixel: f32=worldUnitsPerPixel(viewDepth,f32(renderSize.y));let effectiveWorldRadius: f32=candidate.searchRadiusPixels*unitsPerPixel;let pixelTolerance: f32=unitsPerPixel*MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE;let boundarySpan: vec3f=positionB-positionE;let boundarySeparation: f32=length(boundarySpan);if (boundarySeparation>effectiveWorldRadius*MESH_BLEND_BOUNDARY_SEPARATION_FACTOR+pixelTolerance) {return MESH_BLEND_REJECTION_DEPTH_SEPARATION;}\nlet boundaryDepthDelta: f32=abs(abs(positionB.z)-abs(positionE.z));let boundaryLateralSpan: f32=length(boundarySpan.xy);if (\nboundaryDepthDelta>max(effectiveWorldRadius*MESH_BLEND_FOREGROUND_DEPTH_FACTOR,pixelTolerance) &&\nboundaryDepthDelta>boundaryLateralSpan*MESH_BLEND_FOREGROUND_LATERAL_FACTOR\n) {return MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND;}\nlet targetSpan: f32=distance(positionB,positionC);let totalSpan: f32=distance(positionA,positionC);if (\ntargetSpan>effectiveWorldRadius*MESH_BLEND_TARGET_SPAN_FACTOR+pixelTolerance ||\ntotalSpan>effectiveWorldRadius*MESH_BLEND_TOTAL_SPAN_FACTOR+pixelTolerance\n) {return MESH_BLEND_REJECTION_PHYSICAL_SPAN;}\nlet currentDirection: vec3f=positionA-positionB;let targetDirection: vec3f=positionC-positionB;let currentLength: f32=length(currentDirection);let targetLength: f32=length(targetDirection);var oppositeFacing: f32=1.0;if (currentLength>MESH_BLEND_EPSILON && targetLength>MESH_BLEND_EPSILON) {oppositeFacing=-dot(currentDirection/currentLength,targetDirection/targetLength);}\n*narrowedSearchRadius=candidate.searchRadiusPixels*calculateSlopeScale(oppositeFacing);if (candidate.distancePixels>*narrowedSearchRadius) {return MESH_BLEND_REJECTION_CONTACT_ANGLE;}\nreturn MESH_BLEND_REJECTION_NONE;}\nfn calculateMeshBlendFade(distancePixels: f32,searchRadiusPixels: f32)->f32 {let boundaryDistance: f32=max(distancePixels-0.5,0.0);let normalizedDistance: f32=clamp(boundaryDistance/max(searchRadiusPixels,MESH_BLEND_EPSILON),0.0,1.0);let inverseDistance: f32=1.0-normalizedDistance;let fade: f32=mix(inverseDistance*inverseDistance,inverseDistance,clamp(inverseDistance-0.75,0.0,1.0));return fade*0.5;}\nfn evaluateMeshBlend(\npixel: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\ncurrentSearchRadius: f32,\nviewDepth: f32,\nignoredGroupId: u32,\nrandomValues: vec2f,\nrotation: f32,\nsectorAngle: f32,\ndirection0: vec2f,\ndirection1: vec2f,\ndirection2: vec2f\n)->MeshBlendResult {var result: MeshBlendResult=invalidBlendResult();var candidate: MeshBlendCandidate=findInitialCandidate(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\nviewDepth,\nignoredGroupId,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);result.candidate=candidate;if (!candidate.valid) {return result;}\nresult.stageReached=2;candidate=refineCandidateDirection(pixel,renderSize,candidate,randomValues);candidate=refineExactBoundary(pixel,renderSize,candidate);result.candidate=candidate;result.stageReached=3;let refinedTargetPixel: vec2i=clampPixel(pixel+vec2i(round(candidate.direction*candidate.distancePixels)),renderSize);if (!applyTargetRadiusClass(refinedTargetPixel,renderSize,viewDepth,&candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.candidate=candidate;var continuationPixel: vec2i;var continuationFound: bool=hasTargetContinuation(pixel,renderSize,candidate,&continuationPixel);if (!continuationFound) {\n#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\nlet fallbackCandidate: MeshBlendCandidate=findImmediateNeighborCandidate(\npixel,\nrenderSize,\ncurrentTag,\nviewDepth,\nignoredGroupId,\ncandidate.targetGroupId\n);if (!fallbackCandidate.valid) {result.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;}\ncandidate=fallbackCandidate;result.candidate=candidate;result.usedFallback=true;continuationFound=hasTargetContinuation(pixel,renderSize,candidate,&continuationPixel);\n#else\nresult.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;\n#endif\n}\nresult.continuationFound=continuationFound;result.stageReached=4;if (continuationFound && !applyTargetRadiusClass(continuationPixel,renderSize,viewDepth,&candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.candidate=candidate;let originalSearchRadius: f32=candidate.searchRadiusPixels;\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nvar tinyObjectRadiusReduced: bool=false;candidate.searchRadiusPixels=reduceRadiusForTinyObject(pixel,renderSize,currentTag,candidate,&tinyObjectRadiusReduced);result.tinyObjectRadiusReduced=tinyObjectRadiusReduced;result.stageReached=5;\n#endif\nresult.candidate=candidate;result.effectiveRadiusPixels=candidate.searchRadiusPixels;result.tinyObjectRadiusRatio=candidate.searchRadiusPixels/max(originalSearchRadius,MESH_BLEND_EPSILON);let pixelB: vec2i=clampPixel(pixel+vec2i(round(candidate.direction*candidate.distancePixels)),renderSize);let pixelE: vec2i=clampPixel(pixel+vec2i(round(candidate.direction*max(candidate.distancePixels-2.0,0.0))),renderSize);var pixelC: vec2i=pixelB;if (continuationFound) {pixelC=continuationPixel;}\nvar narrowedSearchRadius: f32=candidate.searchRadiusPixels;var currentViewPosition: vec3f=vec3f(0.0);result.rejectionReason=validateMeshBlendContact(\npixel,\npixelE,\npixelB,\npixelC,\nrenderSize,\ncurrentTag,\ncandidate,\nresult.usedFallback && !continuationFound,\n&narrowedSearchRadius,\n&currentViewPosition\n);result.currentViewPosition=currentViewPosition;result.stageReached=6;result.effectiveRadiusPixels=narrowedSearchRadius;if (result.rejectionReason != MESH_BLEND_REJECTION_NONE) {return result;}\nresult.fade=calculateMeshBlendFade(candidate.distancePixels,narrowedSearchRadius);if (result.fade<=0.0) {result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.targetPixel=pixelB;result.targetFarPixel=pixelB;if (continuationFound) {result.targetFarPixel=continuationPixel;}\nresult.stageReached=7;result.valid=true;return result;}\nfn meshBlendLinearToSrgbChannel(value: f32)->f32 {if (value<=0.0031308) {return value*12.92;}\nreturn 1.055*pow(value,1.0/2.4)-0.055;}\nfn meshBlendSrgbToLinearChannel(value: f32)->f32 {if (value<=0.04045) {return value/12.92;}\nreturn pow((value+0.055)/1.055,2.4);}\nfn meshBlendLinearToSrgb(color: vec3f)->vec3f {return vec3f(\nmeshBlendLinearToSrgbChannel(color.r),\nmeshBlendLinearToSrgbChannel(color.g),\nmeshBlendLinearToSrgbChannel(color.b)\n);}\nfn meshBlendSrgbToLinear(color: vec3f)->vec3f {return vec3f(\nmeshBlendSrgbToLinearChannel(color.r),\nmeshBlendSrgbToLinearChannel(color.g),\nmeshBlendSrgbToLinearChannel(color.b)\n);}\nfn meshBlendSignedCubeRoot(value: f32)->f32 {return sign(value)*pow(abs(value),1.0/3.0);}\nfn meshBlendLinearSrgbToOklab(color: vec3f)->vec3f {let longResponse: f32=0.4122214708*color.r+0.5363325363*color.g+0.0514459929*color.b;let mediumResponse: f32=0.2119034982*color.r+0.6806995451*color.g+0.1073969566*color.b;let shortResponse: f32=0.0883024619*color.r+0.2817188376*color.g+0.6299787005*color.b;let longRoot: f32=meshBlendSignedCubeRoot(longResponse);let mediumRoot: f32=meshBlendSignedCubeRoot(mediumResponse);let shortRoot: f32=meshBlendSignedCubeRoot(shortResponse);return vec3f(\n0.2104542553*longRoot+0.7936177850*mediumRoot-0.0040720468*shortRoot,\n1.9779984951*longRoot-2.4285922050*mediumRoot+0.4505937099*shortRoot,\n0.0259040371*longRoot+0.7827717662*mediumRoot-0.8086757660*shortRoot\n);}\nfn meshBlendOklabToLinearSrgb(color: vec3f)->vec3f {let longRoot: f32=color.x+0.3963377774*color.y+0.2158037573*color.z;let mediumRoot: f32=color.x-0.1055613458*color.y-0.0638541728*color.z;let shortRoot: f32=color.x-0.0894841775*color.y-1.2914855480*color.z;let longResponse: f32=longRoot*longRoot*longRoot;let mediumResponse: f32=mediumRoot*mediumRoot*mediumRoot;let shortResponse: f32=shortRoot*shortRoot*shortRoot;return vec3f(\n4.0767416621*longResponse-3.3077115913*mediumResponse+0.2309699292*shortResponse,\n-1.2684380046*longResponse+2.6097574011*mediumResponse-0.3413193965*shortResponse,\n-0.0041960863*longResponse-0.7034186147*mediumResponse+1.7076147010*shortResponse\n);}\nfn interpolateMeshBlendColor(currentColor: vec3f,targetColor: vec3f,factor: f32)->vec3f {\n#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB\nreturn meshBlendSrgbToLinear(mix(meshBlendLinearToSrgb(currentColor),meshBlendLinearToSrgb(targetColor),factor));\n#else\nreturn meshBlendOklabToLinearSrgb(mix(meshBlendLinearSrgbToOklab(currentColor),meshBlendLinearSrgbToOklab(targetColor),factor));\n#endif\n}\nfn meshBlendLuminance(srgbColor: vec3f)->f32 {return dot(srgbColor,vec3f(0.2126,0.7152,0.0722));}\nfn constructMeshBlendTargetColorSamples(renderSize: vec2i,result: MeshBlendResult)->MeshBlendTargetColorSamples {var samples: MeshBlendTargetColorSamples;let boundaryPlusOnePixel: vec2i=clampPixel(result.targetPixel+vec2i(round(result.candidate.direction)),renderSize);let boundaryPlusTwoPixel: vec2i=clampPixel(result.targetPixel+vec2i(round(result.candidate.direction*2.0)),renderSize);let boundaryPlusOneTag: MeshBlendTag=loadMeshBlendTag(boundaryPlusOnePixel,renderSize);let boundaryPlusTwoTag: MeshBlendTag=loadMeshBlendTag(boundaryPlusTwoPixel,renderSize);samples.fartherColor=textureLoad(textureSampler,result.targetFarPixel,0);samples.boundaryPlusOneColor=textureLoad(textureSampler,boundaryPlusOnePixel,0);samples.boundaryPlusTwoColor=textureLoad(textureSampler,boundaryPlusTwoPixel,0);\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.fartherBaseColor=textureLoad(meshBlendBaseColorSampler,result.targetFarPixel,0).rgb;let boundaryPlusOneBaseColor: vec3f=textureLoad(meshBlendBaseColorSampler,boundaryPlusOnePixel,0).rgb;let boundaryPlusTwoBaseColor: vec3f=textureLoad(meshBlendBaseColorSampler,boundaryPlusTwoPixel,0).rgb;\n#endif\nsamples.onePixelEdge=boundaryPlusOneTag.groupId != result.candidate.targetGroupId;if (samples.onePixelEdge) {samples.conservativeNearColor=samples.fartherColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=samples.fartherBaseColor;\n#endif\nsamples.targetColor=samples.fartherColor;return samples;}\nlet secondNearSampleIsTarget: bool=boundaryPlusTwoTag.groupId==result.candidate.targetGroupId;let firstNearLuminance: f32=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusOneColor.rgb));let secondNearLuminance: f32=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusTwoColor.rgb));let useSecondNearSample: bool=secondNearSampleIsTarget && secondNearLuminance<firstNearLuminance;if (useSecondNearSample) {samples.conservativeNearColor=samples.boundaryPlusTwoColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=boundaryPlusTwoBaseColor;\n#endif\n} else {samples.conservativeNearColor=samples.boundaryPlusOneColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=boundaryPlusOneBaseColor;\n#endif\n}\nsamples.targetColor=mix(samples.fartherColor,samples.conservativeNearColor,MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT);return samples;}\nfn applyMeshBlendNearSeamCorrection(\npixel: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\nresult: MeshBlendResult,\nsamples: MeshBlendTargetColorSamples,\ncurrentColor: vec4f,\ncorrected: ptr<function,bool>\n)->vec4f {*corrected=false;if (!samples.onePixelEdge || result.candidate.distancePixels>MESH_BLEND_NEAR_SEAM_MAX_DISTANCE) {return currentColor;}\nlet oppositePixel: vec2i=clampPixel(pixel-vec2i(round(result.candidate.direction)),renderSize);let oppositeTag: MeshBlendTag=loadMeshBlendTag(oppositePixel,renderSize);if (oppositeTag.groupId != currentTag.groupId) {return currentColor;}\nlet oppositeColor: vec4f=textureLoad(textureSampler,oppositePixel,0);let currentTargetDistance: f32=distance(currentColor.rgb,samples.targetColor.rgb);let oppositeTargetDistance: f32=distance(oppositeColor.rgb,samples.targetColor.rgb);if (currentTargetDistance+MESH_BLEND_NEAR_SEAM_COLOR_DELTA>=oppositeTargetDistance) {return currentColor;}\n*corrected=true;return oppositeColor;}\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nfn estimateMeshBlendShadow(renderedLinear: vec3f,baseColorLinear: vec3f)->f32 {let renderedLuminance: f32=meshBlendLuminance(meshBlendLinearToSrgb(renderedLinear));let baseLuminance: f32=meshBlendLuminance(meshBlendLinearToSrgb(baseColorLinear));if (baseLuminance<=MESH_BLEND_BASE_LUMINANCE_EPSILON) {return 1.0;}\nreturn renderedLuminance/baseLuminance;}\nfn calculateMeshBlendShadowAttenuation(currentColor: vec3f,samples: MeshBlendTargetColorSamples)->f32 {let fartherShadow: f32=estimateMeshBlendShadow(samples.fartherColor.rgb,samples.fartherBaseColor);let nearShadow: f32=estimateMeshBlendShadow(samples.conservativeNearColor.rgb,samples.conservativeNearBaseColor);let shadowDifference: f32=abs(fartherShadow-nearShadow);let shadowMismatch: f32=smoothstep(MESH_BLEND_SHADOW_DIFFERENCE_LOW,MESH_BLEND_SHADOW_DIFFERENCE_HIGH,shadowDifference);let currentLuminance: f32=meshBlendLuminance(meshBlendLinearToSrgb(currentColor));let targetLuminance: f32=meshBlendLuminance(meshBlendLinearToSrgb(samples.targetColor.rgb));let targetToCurrentRatio: f32=targetLuminance/max(currentLuminance,MESH_BLEND_BASE_LUMINANCE_EPSILON);let targetIsNotDark: f32=smoothstep(MESH_BLEND_TARGET_DARKER_RATIO,MESH_BLEND_TARGET_NON_DARK_RATIO,targetToCurrentRatio);return mix(1.0,MESH_BLEND_SHADOW_MIN_ATTENUATION,shadowMismatch*targetIsNotDark);}\n#endif\nfn evaluateMeshBlendColor(\npixel: vec2i,\nrenderSize: vec2i,\ncurrentTag: MeshBlendTag,\nresult: MeshBlendResult\n)->MeshBlendColorEvaluation {var evaluation: MeshBlendColorEvaluation;evaluation.samples=constructMeshBlendTargetColorSamples(renderSize,result);\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nevaluation.worldPosition=reconstructMeshBlendWorldPosition(result.currentViewPosition);\n#endif\nlet currentSceneColor: vec4f=textureLoad(textureSampler,pixel,0);var nearSeamCorrected: bool=false;evaluation.currentColor=applyMeshBlendNearSeamCorrection(\npixel,\nrenderSize,\ncurrentTag,\nresult,\nevaluation.samples,\ncurrentSceneColor,\n&nearSeamCorrected\n);evaluation.nearSeamCorrected=nearSeamCorrected;evaluation.shadowAttenuation=1.0;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nevaluation.shadowAttenuation=calculateMeshBlendShadowAttenuation(evaluation.currentColor.rgb,evaluation.samples);\n#endif\nevaluation.adjustedFade=result.fade*evaluation.shadowAttenuation;evaluation.blendedColor=vec4f(\ninterpolateMeshBlendColor(evaluation.currentColor.rgb,evaluation.samples.targetColor.rgb,evaluation.adjustedFade),\nmix(evaluation.currentColor.a,evaluation.samples.targetColor.a,evaluation.adjustedFade)\n);return evaluation;}\nfn radiusClassDebugColor(radiusClass: u32)->vec3f {if (radiusClass==0u) {return vec3f(0.15,0.55,1.0);}\nif (radiusClass==1u) {return vec3f(0.15,0.9,0.35);}\nif (radiusClass==2u) {return vec3f(1.0,0.65,0.1);}\nreturn vec3f(0.95,0.2,0.65);}\nfn validationDebugColor(rejectionReason: i32,narrowedRadiusRatio: f32)->vec3f {if (rejectionReason==MESH_BLEND_REJECTION_NONE) {return mix(vec3f(0.1,0.55,1.0),vec3f(0.2,1.0,0.25),narrowedRadiusRatio);}\nif (rejectionReason==MESH_BLEND_REJECTION_NO_CANDIDATE) {return vec3f(0.12);}\nif (rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {return vec3f(0.75,0.1,0.85);}\nif (rejectionReason==MESH_BLEND_REJECTION_INVALID_DEPTH) {return vec3f(1.0,0.0,1.0);}\nif (rejectionReason==MESH_BLEND_REJECTION_DEPTH_SEPARATION) {return vec3f(1.0,0.1,0.1);}\nif (rejectionReason==MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND) {return vec3f(1.0,0.4,0.05);}\nif (rejectionReason==MESH_BLEND_REJECTION_PHYSICAL_SPAN) {return vec3f(1.0,0.9,0.05);}\nreturn vec3f(0.05,0.8,1.0);}\nfn processingStageDebugColor(stageReached: i32)->vec3f {if (stageReached<=0) {return vec3f(0.03);}\nif (stageReached==1) {return vec3f(0.1,0.15,0.45);}\nif (stageReached==2) {return vec3f(0.1,0.35,0.7);}\nif (stageReached==3) {return vec3f(0.05,0.65,0.8);}\nif (stageReached==4) {return vec3f(0.1,0.8,0.55);}\nif (stageReached==5) {return vec3f(0.45,0.9,0.25);}\nif (stageReached==6) {return vec3f(0.95,0.75,0.1);}\nreturn vec3f(0.15,1.0,0.25);}\nfn candidateDebugColor(result: MeshBlendResult)->vec3f {if (!result.candidate.valid) {return vec3f(0.04);}\nlet normalizedDistance: f32=clamp(\nresult.candidate.distancePixels/max(result.candidate.searchRadiusPixels,MESH_BLEND_EPSILON),\n0.0,\n1.0\n);return vec3f(result.candidate.direction*0.5+0.5,1.0-normalizedDistance);}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let renderSize: vec2i=vec2i(textureDimensions(meshBlendDepthSampler,0));let pixel: vec2i=clampPixel(vec2i(floor(input.vUV*vec2f(renderSize))),renderSize);let currentTag: MeshBlendTag=loadMeshBlendTag(pixel,renderSize);\n#ifdef MESH_BLEND_DEBUG_PACKED_TAG\nlet groupVariation: f32=0.45+0.55*fract(f32(currentTag.groupId)*0.61803398875);let tagColor: vec3f=radiusClassDebugColor(currentTag.radiusClass)*groupVariation;if (currentTag.groupId==0u) {fragmentOutputs.color=vec4f(0.0,0.0,0.0,1.0);} else {fragmentOutputs.color=vec4f(tagColor,1.0);}\nreturn fragmentOutputs;\n#endif\nif (currentTag.groupId==0u) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nfragmentOutputs.color=vec4f(0.0,0.0,0.0,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\nfragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);\n#else\nfragmentOutputs.color=textureLoad(textureSampler,pixel,0);\n#endif\nreturn fragmentOutputs;}\nlet sizingDepth: f32=loadMeshBlendDepth(pixel,renderSize);let sizingPosition: vec3f=reconstructMeshBlendViewPosition(pixel,renderSize,sizingDepth);if (!isValidMeshBlendPosition(sizingPosition)) {\n#ifdef MESH_BLEND_DEBUG_REJECTION_REASON\nfragmentOutputs.color=vec4f(validationDebugColor(MESH_BLEND_REJECTION_INVALID_DEPTH,0.0),1.0);\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\nfragmentOutputs.color=vec4f(0.45,0.1,0.1,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\nfragmentOutputs.color=vec4f(0.4,0.05,0.4,1.0);\n#else\nfragmentOutputs.color=textureLoad(textureSampler,pixel,0);\n#endif\nreturn fragmentOutputs;}\nlet currentViewDepth: f32=abs(sizingPosition.z);let currentSearchRadius: f32=searchRadiusForClass(currentTag.radiusClass,currentViewDepth,f32(renderSize.y));if (currentSearchRadius<1.0) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nfragmentOutputs.color=vec4f(radiusClassDebugColor(currentTag.radiusClass)*0.25,1.0);\n#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)\nfragmentOutputs.color=vec4f(validationDebugColor(MESH_BLEND_REJECTION_PHYSICAL_SPAN,0.0),1.0);\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\nfragmentOutputs.color=vec4f(0.2,0.2,0.65,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\nfragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);\n#else\nfragmentOutputs.color=textureLoad(textureSampler,pixel,0);\n#endif\nreturn fragmentOutputs;}\nlet randomValues: vec2f=loadStableBlueNoise(pixel);let sectorAngle: f32=MESH_BLEND_TWO_PI/f32(MESH_BLEND_DIRECTION_COUNT);var rotation: f32;\n#ifdef MESH_BLEND_FULL_RANDOM_ROTATION\nrotation=randomValues.x*sectorAngle;\n#else\nrotation=floor(randomValues.x*8.0)*0.125*sectorAngle;\n#endif\nlet direction0: vec2f=vec2f(cos(rotation),sin(rotation));let direction1: vec2f=vec2f(cos(rotation+sectorAngle),sin(rotation+sectorAngle));let direction2: vec2f=vec2f(cos(rotation+sectorAngle*2.0),sin(rotation+sectorAngle*2.0));let primaryResult: MeshBlendResult=evaluateMeshBlend(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\ncurrentViewDepth,\n0u,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);var secondaryResult: MeshBlendResult=invalidBlendResult();\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (primaryResult.valid) {secondaryResult=evaluateMeshBlend(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\ncurrentViewDepth,\nprimaryResult.candidate.targetGroupId,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);}\n#endif\n#ifdef MESH_BLEND_DEBUG_CANDIDATE_DIRECTION_DISTANCE\nfragmentOutputs.color=vec4f(candidateDebugColor(primaryResult),1.0);return fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_CONTINUATION)\nif (!primaryResult.candidate.valid) {fragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);} else if (primaryResult.rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {fragmentOutputs.color=vec4f(0.85,0.05,0.7,1.0);} else if (primaryResult.usedFallback) {fragmentOutputs.color=vec4f(1.0,0.75,0.05,1.0);} else {fragmentOutputs.color=vec4f(0.1,0.9,0.25,1.0);}\nreturn fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_TINY_OBJECT)\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nif (!primaryResult.candidate.valid) {fragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);} else {let radiusColor: vec3f=mix(vec3f(1.0,0.1,0.05),vec3f(0.1,0.65,1.0),primaryResult.tinyObjectRadiusRatio);if (primaryResult.tinyObjectRadiusReduced) {fragmentOutputs.color=vec4f(radiusColor,1.0);} else {fragmentOutputs.color=vec4f(radiusColor*0.45,1.0);}}\n#else\nfragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);\n#endif\nreturn fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_MULTI_TARGET)\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {fragmentOutputs.color=vec4f(0.95,0.95,1.0,1.0);} else if (secondaryResult.candidate.valid) {fragmentOutputs.color=vec4f(0.8,0.15,0.75,1.0);} else if (primaryResult.valid) {fragmentOutputs.color=vec4f(0.1,0.45,0.95,1.0);} else {fragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);}\n#else\nif (primaryResult.valid) {fragmentOutputs.color=vec4f(0.1,0.45,0.95,1.0);} else {fragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);}\n#endif\nreturn fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)\nvar narrowedRadiusRatio: f32=0.0;if (primaryResult.candidate.valid) {narrowedRadiusRatio=primaryResult.effectiveRadiusPixels/max(primaryResult.candidate.searchRadiusPixels,MESH_BLEND_EPSILON);}\nfragmentOutputs.color=vec4f(validationDebugColor(primaryResult.rejectionReason,narrowedRadiusRatio),1.0);return fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\nvar stageReached: i32=primaryResult.stageReached;\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nstageReached=max(stageReached,secondaryResult.stageReached);\n#endif\nfragmentOutputs.color=vec4f(processingStageDebugColor(stageReached),1.0);return fragmentOutputs;\n#endif\nif (!primaryResult.valid) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nvar debugRadiusClass: u32=currentTag.radiusClass;if (primaryResult.candidate.valid) {debugRadiusClass=primaryResult.candidate.radiusClass;}\nfragmentOutputs.color=vec4f(radiusClassDebugColor(debugRadiusClass)*0.25,1.0);\n#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR) || defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION) || defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION) || defined(MESH_BLEND_DEBUG_WORLD_POSITION)\nfragmentOutputs.color=vec4f(0.04,0.04,0.04,1.0);\n#else\nfragmentOutputs.color=textureLoad(textureSampler,pixel,0);\n#endif\nreturn fragmentOutputs;}\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nvar debugFade: f32=primaryResult.fade;\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {debugFade=min(0.5,primaryResult.fade+secondaryResult.fade);}\n#endif\nlet classColor: vec3f=radiusClassDebugColor(primaryResult.candidate.radiusClass)*0.25;fragmentOutputs.color=vec4f(mix(classColor,vec3f(1.0),clamp(debugFade*2.0,0.0,1.0)),1.0);return fragmentOutputs;\n#else\nlet primaryColorEvaluation: MeshBlendColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,primaryResult);\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nfragmentOutputs.color=vec4f(fract(primaryColorEvaluation.worldPosition*0.1),1.0);return fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR)\nlet targetSampleIndex: i32=(pixel.x/4) % 4;if (targetSampleIndex==0) {fragmentOutputs.color=primaryColorEvaluation.samples.fartherColor;} else if (targetSampleIndex==1) {fragmentOutputs.color=primaryColorEvaluation.samples.boundaryPlusOneColor;} else if (targetSampleIndex==2) {fragmentOutputs.color=primaryColorEvaluation.samples.boundaryPlusTwoColor;} else {fragmentOutputs.color=primaryColorEvaluation.samples.targetColor;}\nreturn fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION)\nvar nearSeamCorrectionDebug: f32=0.0;if (primaryColorEvaluation.nearSeamCorrected) {nearSeamCorrectionDebug=1.0;}\nfragmentOutputs.color=vec4f(\n1.0-primaryColorEvaluation.shadowAttenuation,\nprimaryColorEvaluation.shadowAttenuation,\nnearSeamCorrectionDebug,\n1.0\n);return fragmentOutputs;\n#elif defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION)\n#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB\nlet interpolationModeColor: vec3f=vec3f(1.0,0.4,0.05);\n#else\nlet interpolationModeColor: vec3f=vec3f(0.1,0.75,1.0);\n#endif\nlet interpolationStage: f32=mix(0.35,1.0,clamp(primaryColorEvaluation.adjustedFade*2.0,0.0,1.0));fragmentOutputs.color=vec4f(interpolationModeColor*interpolationStage,1.0);return fragmentOutputs;\n#else\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {let secondaryColorEvaluation: MeshBlendColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,secondaryResult);let totalBoundaryDistance: f32=max(\nprimaryResult.candidate.distancePixels+secondaryResult.candidate.distancePixels,\nMESH_BLEND_EPSILON\n);let primaryRelativeProximity: f32=secondaryResult.candidate.distancePixels/totalBoundaryDistance;let secondaryRelativeProximity: f32=primaryResult.candidate.distancePixels/totalBoundaryDistance;let primaryWeight: f32=primaryColorEvaluation.adjustedFade*primaryRelativeProximity;let secondaryWeight: f32=secondaryColorEvaluation.adjustedFade*secondaryRelativeProximity;let combinedWeight: f32=primaryWeight+secondaryWeight;if (combinedWeight<=MESH_BLEND_EPSILON) {fragmentOutputs.color=textureLoad(textureSampler,pixel,0);return fragmentOutputs;}\nfragmentOutputs.color =\n(primaryColorEvaluation.blendedColor*primaryWeight+secondaryColorEvaluation.blendedColor*secondaryWeight)/combinedWeight;return fragmentOutputs;}\n#endif\nfragmentOutputs.color=primaryColorEvaluation.blendedColor;\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const meshBlendingPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"meshBlendingPixelShader\";\nconst shader = `precision highp float;precision highp int;varying vec2 vUV;uniform sampler2D textureSampler;uniform highp usampler2D meshBlendTagSampler;uniform sampler2D meshBlendDepthSampler;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nuniform sampler2D meshBlendBaseColorSampler;\n#endif\nuniform sampler2D meshBlendBlueNoiseSampler;uniform mat4 projection;uniform mat4 inverseProjection;uniform mat4 inverseView;uniform vec4 blendWorldRadii;uniform vec4 minimumProjectedRadii;uniform float meshBlendIsOrthographic;uniform float slopeFactor;\n#ifndef MESH_BLEND_DIRECTION_COUNT\n#define MESH_BLEND_DIRECTION_COUNT 3\n#define MESH_BLEND_RADIAL_SAMPLE_COUNT 3\n#define MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT 2\n#define MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT 4\n#define MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT 8\n#define MESH_BLEND_RADIUS_SCALE 0.9\n#define MESH_BLEND_JITTER_FACTOR 0.5\n#define MESH_BLEND_COLOR_INTERPOLATION_OKLAB\n#endif\n#define MESH_BLEND_TWO_PI 6.283185307179586\n#define MESH_BLEND_EPSILON 0.00001\n#define MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE 0.2\n#define MESH_BLEND_TINY_OBJECT_PROBE_COUNT 8\n#define MESH_BLEND_MIN_SLOPE_SCALE 0.25\n#define MESH_BLEND_BOUNDARY_SEPARATION_FACTOR 0.75\n#define MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE 3.0\n#define MESH_BLEND_FOREGROUND_DEPTH_FACTOR 0.35\n#define MESH_BLEND_FOREGROUND_LATERAL_FACTOR 2.0\n#define MESH_BLEND_TARGET_SPAN_FACTOR 1.5\n#define MESH_BLEND_TOTAL_SPAN_FACTOR 2.5\n#define MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT 0.35\n#define MESH_BLEND_NEAR_SEAM_MAX_DISTANCE 1.25\n#define MESH_BLEND_NEAR_SEAM_COLOR_DELTA 0.02\n#define MESH_BLEND_BASE_LUMINANCE_EPSILON 0.00001\n#define MESH_BLEND_TARGET_DARKER_RATIO 0.65\n#define MESH_BLEND_TARGET_NON_DARK_RATIO 0.9\n#define MESH_BLEND_SHADOW_DIFFERENCE_LOW 0.15\n#define MESH_BLEND_SHADOW_DIFFERENCE_HIGH 0.5\n#define MESH_BLEND_SHADOW_MIN_ATTENUATION 0.25\n#define MESH_BLEND_REJECTION_NONE 0\n#define MESH_BLEND_REJECTION_NO_CANDIDATE 1\n#define MESH_BLEND_REJECTION_NO_CONTINUATION 2\n#define MESH_BLEND_REJECTION_INVALID_DEPTH 3\n#define MESH_BLEND_REJECTION_DEPTH_SEPARATION 4\n#define MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND 5\n#define MESH_BLEND_REJECTION_PHYSICAL_SPAN 6\n#define MESH_BLEND_REJECTION_CONTACT_ANGLE 7\nstruct MeshBlendTag {uint groupId;uint radiusClass;};struct MeshBlendCandidate {uint targetGroupId;uint radiusClass;vec2 direction;float distancePixels;float searchRadiusPixels;float score;bool valid;};struct MeshBlendResult {MeshBlendCandidate candidate;ivec2 targetPixel;ivec2 targetFarPixel;vec3 currentViewPosition;float effectiveRadiusPixels;float fade;float tinyObjectRadiusRatio;int rejectionReason;int stageReached;bool valid;bool continuationFound;bool usedFallback;bool tinyObjectRadiusReduced;};struct MeshBlendTargetColorSamples {vec4 fartherColor;vec4 boundaryPlusOneColor;vec4 boundaryPlusTwoColor;vec4 conservativeNearColor;vec4 targetColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nvec3 fartherBaseColor;vec3 conservativeNearBaseColor;\n#endif\nbool onePixelEdge;};struct MeshBlendColorEvaluation {MeshBlendTargetColorSamples samples;vec4 currentColor;vec4 blendedColor;\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nvec3 worldPosition;\n#endif\nfloat shadowAttenuation;float adjustedFade;bool nearSeamCorrected;};ivec2 clampPixel(ivec2 pixel,ivec2 renderSize) {return clamp(pixel,ivec2(0),renderSize-ivec2(1));}\nbool isPixelInBounds(ivec2 pixel,ivec2 renderSize) {return pixel.x>=0 && pixel.y>=0 && pixel.x<renderSize.x && pixel.y<renderSize.y;}\nvec2 pixelToUv(ivec2 pixel,ivec2 renderSize) {return (vec2(clampPixel(pixel,renderSize))+vec2(0.5))/vec2(renderSize);}\nMeshBlendTag loadMeshBlendTag(ivec2 pixel,ivec2 renderSize) {uint packedTag=texelFetch(meshBlendTagSampler,clampPixel(pixel,renderSize),0).r;MeshBlendTag tag;tag.groupId=packedTag & 0x3fu;tag.radiusClass=packedTag>>6u;return tag;}\nfloat loadMeshBlendDepth(ivec2 pixel,ivec2 renderSize) {return texelFetch(meshBlendDepthSampler,clampPixel(pixel,renderSize),0).r;}\nfloat classValue(vec4 values,uint index) {if (index==0u) {return values.x;}\nif (index==1u) {return values.y;}\nif (index==2u) {return values.z;}\nreturn values.w;}\nfloat meshBlendDepthToNdc(float depth) {\n#ifdef MESH_BLEND_DEPTH_SCREEN\n#ifdef IS_NDC_HALF_ZRANGE\nreturn depth;\n#else\nreturn depth*2.0-1.0;\n#endif\n#else\nvec4 projectedDepth=projection*vec4(0.0,0.0,depth,1.0);return projectedDepth.z/projectedDepth.w;\n#endif\n}\nvec3 reconstructMeshBlendViewPosition(ivec2 pixel,ivec2 renderSize,float depth) {vec2 ndcXY=pixelToUv(pixel,renderSize)*2.0-1.0;vec4 viewPosition=inverseProjection*vec4(ndcXY,meshBlendDepthToNdc(depth),1.0);return viewPosition.xyz/viewPosition.w;}\nvec3 reconstructMeshBlendWorldPosition(vec3 viewPosition) {return (inverseView*vec4(viewPosition,1.0)).xyz;}\nbool isValidMeshBlendPosition(vec3 position) {return !any(isnan(position)) && !any(isinf(position));}\nfloat meshBlendProjectionScale(float renderHeight) {return max(0.5*renderHeight*abs(projection[1][1]),MESH_BLEND_EPSILON);}\nfloat searchRadiusForClass(uint radiusClass,float viewDepth,float renderHeight) {float projectionScale=meshBlendProjectionScale(renderHeight);float projectedWorldRadius=classValue(blendWorldRadii,radiusClass)*projectionScale;if (meshBlendIsOrthographic<0.5) {projectedWorldRadius/=max(viewDepth,MESH_BLEND_EPSILON);}\nfloat scaledRadius=max(projectedWorldRadius,classValue(minimumProjectedRadii,radiusClass))*MESH_BLEND_RADIUS_SCALE;return scaledRadius>0.0 ? max(1.0,scaledRadius) : 0.0;}\nfloat worldUnitsPerPixel(float viewDepth,float renderHeight) {float unitsPerPixel=1.0/meshBlendProjectionScale(renderHeight);return meshBlendIsOrthographic>0.5 ? unitsPerPixel : unitsPerPixel*max(viewDepth,MESH_BLEND_EPSILON);}\nfloat calculateSlopeScale(float oppositeFacing) {if (slopeFactor<=1.0) {return 1.0;}\nreturn MESH_BLEND_MIN_SLOPE_SCALE +\n(1.0-MESH_BLEND_MIN_SLOPE_SCALE)*pow(clamp(oppositeFacing,0.0,1.0),slopeFactor-1.0);}\nvec2 loadStableBlueNoise(ivec2 pixel) {ivec2 noiseSize=textureSize(meshBlendBlueNoiseSampler,0);ivec2 wrappedPixel=ivec2(pixel.x % noiseSize.x,pixel.y % noiseSize.y);return texelFetch(meshBlendBlueNoiseSampler,wrappedPixel,0).rg;}\nvec2 directionAt(int index,float rotation,float sectorAngle,vec2 direction0,vec2 direction1,vec2 direction2) {\n#if MESH_BLEND_DIRECTION_COUNT==3\nif (index==0) {return direction0;}\nif (index==1) {return direction1;}\nreturn direction2;\n#else\nfloat angle=rotation+sectorAngle*float(index);return vec2(cos(angle),sin(angle));\n#endif\n}\nMeshBlendCandidate invalidCandidate() {MeshBlendCandidate candidate;candidate.targetGroupId=0u;candidate.radiusClass=0u;candidate.direction=vec2(0.0);candidate.distancePixels=0.0;candidate.searchRadiusPixels=0.0;candidate.score=-1.0;candidate.valid=false;return candidate;}\nMeshBlendResult invalidBlendResult() {MeshBlendResult result;result.candidate=invalidCandidate();result.targetPixel=ivec2(0);result.targetFarPixel=ivec2(0);result.currentViewPosition=vec3(0.0);result.effectiveRadiusPixels=0.0;result.fade=0.0;result.tinyObjectRadiusRatio=1.0;result.rejectionReason=MESH_BLEND_REJECTION_NO_CANDIDATE;result.stageReached=1;result.valid=false;result.continuationFound=false;result.usedFallback=false;result.tinyObjectRadiusReduced=false;return result;}\nMeshBlendCandidate findInitialCandidate(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nfloat currentSearchRadius,\nfloat viewDepth,\nuint ignoredGroupId,\nvec2 randomValues,\nfloat rotation,\nfloat sectorAngle,\nvec2 direction0,\nvec2 direction1,\nvec2 direction2\n) {MeshBlendCandidate best=invalidCandidate();float radialJitter=mix(0.5,randomValues.y,MESH_BLEND_JITTER_FACTOR);for (int radialIndex=0; radialIndex<MESH_BLEND_RADIAL_SAMPLE_COUNT; ++radialIndex) {float normalizedDistance=(float(radialIndex)+radialJitter)/float(MESH_BLEND_RADIAL_SAMPLE_COUNT);float distancePixels=max(1.0,ceil(normalizedDistance*normalizedDistance*normalizedDistance*currentSearchRadius));for (int directionIndex=0; directionIndex<MESH_BLEND_DIRECTION_COUNT; ++directionIndex) {vec2 direction=directionAt(directionIndex,rotation,sectorAngle,direction0,direction1,direction2);ivec2 samplePixel=pixel+ivec2(round(direction*distancePixels));MeshBlendTag candidateTag=loadMeshBlendTag(samplePixel,renderSize);if (candidateTag.groupId==0u || candidateTag.groupId==currentTag.groupId || candidateTag.groupId==ignoredGroupId) {continue;}\nuint seamRadiusClass=min(currentTag.radiusClass,candidateTag.radiusClass);float candidateSearchRadius=searchRadiusForClass(seamRadiusClass,viewDepth,float(renderSize.y));if (distancePixels>candidateSearchRadius) {continue;}\nfloat score=1.0-clamp(distancePixels/max(candidateSearchRadius,MESH_BLEND_EPSILON),0.0,1.0);if (score>best.score) {best.targetGroupId=candidateTag.groupId;best.radiusClass=seamRadiusClass;best.direction=direction;best.distancePixels=distancePixels;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}\nif (best.valid) {break;}}\nreturn best;}\nMeshBlendCandidate refineCandidateDirection(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate,vec2 randomValues) {if (candidate.distancePixels<=2.0) {return candidate;}\nfloat centerAngle=atan(candidate.direction.y,candidate.direction.x);float angularHalfWidth=(MESH_BLEND_TWO_PI/float(MESH_BLEND_DIRECTION_COUNT))*MESH_BLEND_DIRECTION_REFINEMENT_SECTOR_SCALE;float stepSize=max(1.0,candidate.distancePixels/float(MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT+1));for (int sampleIndex=0; sampleIndex<MESH_BLEND_DIRECTION_REFINEMENT_SAMPLE_COUNT; ++sampleIndex) {float sampleRandom=fract(randomValues.y+randomValues.x*0.754877666+float(sampleIndex)*0.618033989);float angle=centerAngle+mix(-angularHalfWidth,angularHalfWidth,sampleRandom);vec2 direction=vec2(cos(angle),sin(angle));float testDistance=candidate.distancePixels-stepSize;for (int stepIndex=0; stepIndex<MESH_BLEND_DIRECTION_REFINEMENT_STEP_COUNT; ++stepIndex) {if (testDistance<=0.0) {break;}\nivec2 samplePixel=pixel+ivec2(round(direction*testDistance));MeshBlendTag sampleTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != candidate.targetGroupId) {break;}\ncandidate.direction=direction;candidate.distancePixels=testDistance;testDistance-=stepSize;}}\nreturn candidate;}\nMeshBlendCandidate refineExactBoundary(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate) {float distancePixels=candidate.distancePixels;for (int sampleIndex=0; sampleIndex<MESH_BLEND_EXACT_EDGE_SAMPLE_COUNT; ++sampleIndex) {distancePixels-=1.0;if (distancePixels<=0.0) {break;}\nivec2 samplePixel=pixel+ivec2(round(candidate.direction*distancePixels));MeshBlendTag sampleTag=loadMeshBlendTag(samplePixel,renderSize);if (sampleTag.groupId != candidate.targetGroupId) {break;}\ncandidate.distancePixels=distancePixels;}\nreturn candidate;}\nbool hasTargetContinuation(ivec2 pixel,ivec2 renderSize,MeshBlendCandidate candidate,out ivec2 continuationPixel) {float continuationDistance=max(candidate.distancePixels*2.0,candidate.distancePixels+1.0);continuationPixel=pixel+ivec2(round(candidate.direction*continuationDistance));if (!isPixelInBounds(continuationPixel,renderSize)) {return false;}\nreturn loadMeshBlendTag(continuationPixel,renderSize).groupId==candidate.targetGroupId;}\nbool applyTargetRadiusClass(ivec2 targetPixel,ivec2 renderSize,float viewDepth,inout MeshBlendCandidate candidate) {MeshBlendTag targetTag=loadMeshBlendTag(targetPixel,renderSize);candidate.radiusClass=min(candidate.radiusClass,targetTag.radiusClass);candidate.searchRadiusPixels=min(candidate.searchRadiusPixels,searchRadiusForClass(candidate.radiusClass,viewDepth,float(renderSize.y)));return candidate.distancePixels<=candidate.searchRadiusPixels;}\n#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\nMeshBlendCandidate findImmediateNeighborCandidate(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nfloat viewDepth,\nuint ignoredGroupId,\nuint preferredGroupId\n) {MeshBlendCandidate best=invalidCandidate();for (int neighborIndex=0; neighborIndex<4; ++neighborIndex) {ivec2 offset;if (neighborIndex==0) {offset=ivec2(1,0);} else if (neighborIndex==1) {offset=ivec2(-1,0);} else if (neighborIndex==2) {offset=ivec2(0,1);} else {offset=ivec2(0,-1);}\nMeshBlendTag neighborTag=loadMeshBlendTag(pixel+offset,renderSize);if (neighborTag.groupId==0u || neighborTag.groupId==currentTag.groupId || neighborTag.groupId==ignoredGroupId) {continue;}\nuint seamRadiusClass=min(currentTag.radiusClass,neighborTag.radiusClass);float candidateSearchRadius=searchRadiusForClass(seamRadiusClass,viewDepth,float(renderSize.y));if (candidateSearchRadius<1.0) {continue;}\nfloat score=1.0-1.0/max(candidateSearchRadius,1.0);if (neighborTag.groupId==preferredGroupId) {score+=1.0;}\nif (score>best.score) {best.targetGroupId=neighborTag.groupId;best.radiusClass=seamRadiusClass;best.direction=vec2(offset);best.distancePixels=1.0;best.searchRadiusPixels=candidateSearchRadius;best.score=score;best.valid=true;}}\nreturn best;}\n#endif\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nfloat reduceRadiusForTinyObject(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendCandidate candidate,\nout bool radiusReduced\n) {float measuredThickness=candidate.searchRadiusPixels;bool foundOppositeBoundary=false;for (int probeIndex=1; probeIndex<=MESH_BLEND_TINY_OBJECT_PROBE_COUNT; ++probeIndex) {float probeDistance=max(1.0,candidate.searchRadiusPixels*float(probeIndex)/float(MESH_BLEND_TINY_OBJECT_PROBE_COUNT));MeshBlendTag oppositeTag=loadMeshBlendTag(pixel-ivec2(round(candidate.direction*probeDistance)),renderSize);if (oppositeTag.groupId != currentTag.groupId) {measuredThickness=probeDistance;foundOppositeBoundary=true;break;}}\nint outsideDirectionCount=0;for (int neighborIndex=0; neighborIndex<4; ++neighborIndex) {vec2 direction;if (neighborIndex==0) {direction=vec2(1.0,0.0);} else if (neighborIndex==1) {direction=vec2(-1.0,0.0);} else if (neighborIndex==2) {direction=vec2(0.0,1.0);} else {direction=vec2(0.0,-1.0);}\nMeshBlendTag radiusTag=loadMeshBlendTag(pixel+ivec2(round(direction*candidate.searchRadiusPixels)),renderSize);if (radiusTag.groupId != currentTag.groupId) {outsideDirectionCount++;}}\nradiusReduced=foundOppositeBoundary && outsideDirectionCount>=3;if (!radiusReduced) {return candidate.searchRadiusPixels;}\nfloat thicknessRadius=max(1.0,measuredThickness*1.25);return max(candidate.distancePixels,min(candidate.searchRadiusPixels,thicknessRadius));}\n#endif\nint validateMeshBlendContact(\nivec2 pixelA,\nivec2 pixelE,\nivec2 pixelB,\nivec2 pixelC,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendCandidate candidate,\nbool allowMissingContinuation,\nout float narrowedSearchRadius,\nout vec3 currentViewPosition\n) {currentViewPosition=vec3(0.0);MeshBlendTag tagE=loadMeshBlendTag(pixelE,renderSize);MeshBlendTag tagB=loadMeshBlendTag(pixelB,renderSize);MeshBlendTag tagC=loadMeshBlendTag(pixelC,renderSize);if (\ntagE.groupId != currentTag.groupId ||\ntagB.groupId != candidate.targetGroupId ||\n(!allowMissingContinuation && tagC.groupId != candidate.targetGroupId)\n) {return MESH_BLEND_REJECTION_NO_CONTINUATION;}\nfloat depthA=loadMeshBlendDepth(pixelA,renderSize);float depthE=loadMeshBlendDepth(pixelE,renderSize);float depthB=loadMeshBlendDepth(pixelB,renderSize);float depthC=loadMeshBlendDepth(pixelC,renderSize);vec3 positionA=reconstructMeshBlendViewPosition(pixelA,renderSize,depthA);vec3 positionE=reconstructMeshBlendViewPosition(pixelE,renderSize,depthE);vec3 positionB=reconstructMeshBlendViewPosition(pixelB,renderSize,depthB);vec3 positionC=reconstructMeshBlendViewPosition(pixelC,renderSize,depthC);if (!isValidMeshBlendPosition(positionA) || !isValidMeshBlendPosition(positionE) || !isValidMeshBlendPosition(positionB) || !isValidMeshBlendPosition(positionC)) {return MESH_BLEND_REJECTION_INVALID_DEPTH;}\ncurrentViewPosition=positionA;float viewDepth=abs(positionA.z);float unitsPerPixel=worldUnitsPerPixel(viewDepth,float(renderSize.y));float effectiveWorldRadius=candidate.searchRadiusPixels*unitsPerPixel;float pixelTolerance=unitsPerPixel*MESH_BLEND_BOUNDARY_PIXEL_TOLERANCE;vec3 boundarySpan=positionB-positionE;float boundarySeparation=length(boundarySpan);if (boundarySeparation>effectiveWorldRadius*MESH_BLEND_BOUNDARY_SEPARATION_FACTOR+pixelTolerance) {return MESH_BLEND_REJECTION_DEPTH_SEPARATION;}\nfloat boundaryDepthDelta=abs(abs(positionB.z)-abs(positionE.z));float boundaryLateralSpan=length(boundarySpan.xy);if (\nboundaryDepthDelta>max(effectiveWorldRadius*MESH_BLEND_FOREGROUND_DEPTH_FACTOR,pixelTolerance) &&\nboundaryDepthDelta>boundaryLateralSpan*MESH_BLEND_FOREGROUND_LATERAL_FACTOR\n) {return MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND;}\nfloat targetSpan=distance(positionB,positionC);float totalSpan=distance(positionA,positionC);if (\ntargetSpan>effectiveWorldRadius*MESH_BLEND_TARGET_SPAN_FACTOR+pixelTolerance ||\ntotalSpan>effectiveWorldRadius*MESH_BLEND_TOTAL_SPAN_FACTOR+pixelTolerance\n) {return MESH_BLEND_REJECTION_PHYSICAL_SPAN;}\nvec3 currentDirection=positionA-positionB;vec3 targetDirection=positionC-positionB;float currentLength=length(currentDirection);float targetLength=length(targetDirection);float oppositeFacing=1.0;if (currentLength>MESH_BLEND_EPSILON && targetLength>MESH_BLEND_EPSILON) {oppositeFacing=-dot(currentDirection/currentLength,targetDirection/targetLength);}\nnarrowedSearchRadius=candidate.searchRadiusPixels*calculateSlopeScale(oppositeFacing);if (candidate.distancePixels>narrowedSearchRadius) {return MESH_BLEND_REJECTION_CONTACT_ANGLE;}\nreturn MESH_BLEND_REJECTION_NONE;}\nfloat calculateMeshBlendFade(float distancePixels,float searchRadiusPixels) {float boundaryDistance=max(distancePixels-0.5,0.0);float normalizedDistance=clamp(boundaryDistance/max(searchRadiusPixels,MESH_BLEND_EPSILON),0.0,1.0);float inverseDistance=1.0-normalizedDistance;float fade=mix(inverseDistance*inverseDistance,inverseDistance,clamp(inverseDistance-0.75,0.0,1.0));return fade*0.5;}\nMeshBlendResult evaluateMeshBlend(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nfloat currentSearchRadius,\nfloat viewDepth,\nuint ignoredGroupId,\nvec2 randomValues,\nfloat rotation,\nfloat sectorAngle,\nvec2 direction0,\nvec2 direction1,\nvec2 direction2\n) {MeshBlendResult result=invalidBlendResult();MeshBlendCandidate candidate=findInitialCandidate(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\nviewDepth,\nignoredGroupId,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);result.candidate=candidate;if (!candidate.valid) {return result;}\nresult.stageReached=2;candidate=refineCandidateDirection(pixel,renderSize,candidate,randomValues);candidate=refineExactBoundary(pixel,renderSize,candidate);result.candidate=candidate;result.stageReached=3;ivec2 refinedTargetPixel=clampPixel(pixel+ivec2(round(candidate.direction*candidate.distancePixels)),renderSize);if (!applyTargetRadiusClass(refinedTargetPixel,renderSize,viewDepth,candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.candidate=candidate;ivec2 continuationPixel;bool continuationFound=hasTargetContinuation(pixel,renderSize,candidate,continuationPixel);if (!continuationFound) {\n#ifdef MESH_BLEND_FOUR_NEIGHBOR_FALLBACK\nMeshBlendCandidate fallbackCandidate=findImmediateNeighborCandidate(\npixel,\nrenderSize,\ncurrentTag,\nviewDepth,\nignoredGroupId,\ncandidate.targetGroupId\n);if (!fallbackCandidate.valid) {result.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;}\ncandidate=fallbackCandidate;result.candidate=candidate;result.usedFallback=true;continuationFound=hasTargetContinuation(pixel,renderSize,candidate,continuationPixel);\n#else\nresult.rejectionReason=MESH_BLEND_REJECTION_NO_CONTINUATION;return result;\n#endif\n}\nresult.continuationFound=continuationFound;result.stageReached=4;if (continuationFound && !applyTargetRadiusClass(continuationPixel,renderSize,viewDepth,candidate)) {result.candidate=candidate;result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.candidate=candidate;float originalSearchRadius=candidate.searchRadiusPixels;\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\ncandidate.searchRadiusPixels=reduceRadiusForTinyObject(pixel,renderSize,currentTag,candidate,result.tinyObjectRadiusReduced);result.stageReached=5;\n#endif\nresult.candidate=candidate;result.effectiveRadiusPixels=candidate.searchRadiusPixels;result.tinyObjectRadiusRatio=candidate.searchRadiusPixels/max(originalSearchRadius,MESH_BLEND_EPSILON);ivec2 pixelB=clampPixel(pixel+ivec2(round(candidate.direction*candidate.distancePixels)),renderSize);ivec2 pixelE=clampPixel(pixel+ivec2(round(candidate.direction*max(candidate.distancePixels-2.0,0.0))),renderSize);ivec2 pixelC=continuationFound ? continuationPixel : pixelB;float narrowedSearchRadius=candidate.searchRadiusPixels;result.rejectionReason=validateMeshBlendContact(\npixel,\npixelE,\npixelB,\npixelC,\nrenderSize,\ncurrentTag,\ncandidate,\nresult.usedFallback && !continuationFound,\nnarrowedSearchRadius,\nresult.currentViewPosition\n);result.stageReached=6;result.effectiveRadiusPixels=narrowedSearchRadius;if (result.rejectionReason != MESH_BLEND_REJECTION_NONE) {return result;}\nresult.fade=calculateMeshBlendFade(candidate.distancePixels,narrowedSearchRadius);if (result.fade<=0.0) {result.rejectionReason=MESH_BLEND_REJECTION_PHYSICAL_SPAN;return result;}\nresult.targetPixel=pixelB;result.targetFarPixel=continuationFound ? continuationPixel : pixelB;result.stageReached=7;result.valid=true;return result;}\nfloat meshBlendLinearToSrgbChannel(float value) {return value<=0.0031308 ? value*12.92 : 1.055*pow(value,1.0/2.4)-0.055;}\nfloat meshBlendSrgbToLinearChannel(float value) {return value<=0.04045 ? value/12.92 : pow((value+0.055)/1.055,2.4);}\nvec3 meshBlendLinearToSrgb(vec3 color) {return vec3(\nmeshBlendLinearToSrgbChannel(color.r),\nmeshBlendLinearToSrgbChannel(color.g),\nmeshBlendLinearToSrgbChannel(color.b)\n);}\nvec3 meshBlendSrgbToLinear(vec3 color) {return vec3(\nmeshBlendSrgbToLinearChannel(color.r),\nmeshBlendSrgbToLinearChannel(color.g),\nmeshBlendSrgbToLinearChannel(color.b)\n);}\nfloat meshBlendSignedCubeRoot(float value) {return sign(value)*pow(abs(value),1.0/3.0);}\nvec3 meshBlendLinearSrgbToOklab(vec3 color) {float longResponse=0.4122214708*color.r+0.5363325363*color.g+0.0514459929*color.b;float mediumResponse=0.2119034982*color.r+0.6806995451*color.g+0.1073969566*color.b;float shortResponse=0.0883024619*color.r+0.2817188376*color.g+0.6299787005*color.b;float longRoot=meshBlendSignedCubeRoot(longResponse);float mediumRoot=meshBlendSignedCubeRoot(mediumResponse);float shortRoot=meshBlendSignedCubeRoot(shortResponse);return vec3(\n0.2104542553*longRoot+0.7936177850*mediumRoot-0.0040720468*shortRoot,\n1.9779984951*longRoot-2.4285922050*mediumRoot+0.4505937099*shortRoot,\n0.0259040371*longRoot+0.7827717662*mediumRoot-0.8086757660*shortRoot\n);}\nvec3 meshBlendOklabToLinearSrgb(vec3 color) {float longRoot=color.x+0.3963377774*color.y+0.2158037573*color.z;float mediumRoot=color.x-0.1055613458*color.y-0.0638541728*color.z;float shortRoot=color.x-0.0894841775*color.y-1.2914855480*color.z;float longResponse=longRoot*longRoot*longRoot;float mediumResponse=mediumRoot*mediumRoot*mediumRoot;float shortResponse=shortRoot*shortRoot*shortRoot;return vec3(\n4.0767416621*longResponse-3.3077115913*mediumResponse+0.2309699292*shortResponse,\n-1.2684380046*longResponse+2.6097574011*mediumResponse-0.3413193965*shortResponse,\n-0.0041960863*longResponse-0.7034186147*mediumResponse+1.7076147010*shortResponse\n);}\nvec3 interpolateMeshBlendColor(vec3 currentColor,vec3 targetColor,float factor) {\n#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB\nreturn meshBlendSrgbToLinear(mix(meshBlendLinearToSrgb(currentColor),meshBlendLinearToSrgb(targetColor),factor));\n#else\nreturn meshBlendOklabToLinearSrgb(mix(meshBlendLinearSrgbToOklab(currentColor),meshBlendLinearSrgbToOklab(targetColor),factor));\n#endif\n}\nfloat meshBlendLuminance(vec3 srgbColor) {return dot(srgbColor,vec3(0.2126,0.7152,0.0722));}\nMeshBlendTargetColorSamples constructMeshBlendTargetColorSamples(ivec2 renderSize,MeshBlendResult result) {MeshBlendTargetColorSamples samples;ivec2 boundaryPlusOnePixel=clampPixel(result.targetPixel+ivec2(round(result.candidate.direction)),renderSize);ivec2 boundaryPlusTwoPixel=clampPixel(result.targetPixel+ivec2(round(result.candidate.direction*2.0)),renderSize);MeshBlendTag boundaryPlusOneTag=loadMeshBlendTag(boundaryPlusOnePixel,renderSize);MeshBlendTag boundaryPlusTwoTag=loadMeshBlendTag(boundaryPlusTwoPixel,renderSize);samples.fartherColor=texelFetch(textureSampler,result.targetFarPixel,0);samples.boundaryPlusOneColor=texelFetch(textureSampler,boundaryPlusOnePixel,0);samples.boundaryPlusTwoColor=texelFetch(textureSampler,boundaryPlusTwoPixel,0);\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.fartherBaseColor=texelFetch(meshBlendBaseColorSampler,result.targetFarPixel,0).rgb;vec3 boundaryPlusOneBaseColor=texelFetch(meshBlendBaseColorSampler,boundaryPlusOnePixel,0).rgb;vec3 boundaryPlusTwoBaseColor=texelFetch(meshBlendBaseColorSampler,boundaryPlusTwoPixel,0).rgb;\n#endif\nsamples.onePixelEdge=boundaryPlusOneTag.groupId != result.candidate.targetGroupId;if (samples.onePixelEdge) {samples.conservativeNearColor=samples.fartherColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=samples.fartherBaseColor;\n#endif\nsamples.targetColor=samples.fartherColor;return samples;}\nbool secondNearSampleIsTarget=boundaryPlusTwoTag.groupId==result.candidate.targetGroupId;float firstNearLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusOneColor.rgb));float secondNearLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.boundaryPlusTwoColor.rgb));bool useSecondNearSample=secondNearSampleIsTarget && secondNearLuminance<firstNearLuminance;samples.conservativeNearColor=useSecondNearSample ? samples.boundaryPlusTwoColor : samples.boundaryPlusOneColor;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nsamples.conservativeNearBaseColor=useSecondNearSample ? boundaryPlusTwoBaseColor : boundaryPlusOneBaseColor;\n#endif\nsamples.targetColor=mix(samples.fartherColor,samples.conservativeNearColor,MESH_BLEND_NEAR_EDGE_TARGET_WEIGHT);return samples;}\nvec4 applyMeshBlendNearSeamCorrection(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendResult result,\nMeshBlendTargetColorSamples samples,\nvec4 currentColor,\nout bool corrected\n) {corrected=false;if (!samples.onePixelEdge || result.candidate.distancePixels>MESH_BLEND_NEAR_SEAM_MAX_DISTANCE) {return currentColor;}\nivec2 oppositePixel=clampPixel(pixel-ivec2(round(result.candidate.direction)),renderSize);MeshBlendTag oppositeTag=loadMeshBlendTag(oppositePixel,renderSize);if (oppositeTag.groupId != currentTag.groupId) {return currentColor;}\nvec4 oppositeColor=texelFetch(textureSampler,oppositePixel,0);float currentTargetDistance=distance(currentColor.rgb,samples.targetColor.rgb);float oppositeTargetDistance=distance(oppositeColor.rgb,samples.targetColor.rgb);if (currentTargetDistance+MESH_BLEND_NEAR_SEAM_COLOR_DELTA>=oppositeTargetDistance) {return currentColor;}\ncorrected=true;return oppositeColor;}\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nfloat estimateMeshBlendShadow(vec3 renderedLinear,vec3 baseColorLinear) {float renderedLuminance=meshBlendLuminance(meshBlendLinearToSrgb(renderedLinear));float baseLuminance=meshBlendLuminance(meshBlendLinearToSrgb(baseColorLinear));if (baseLuminance<=MESH_BLEND_BASE_LUMINANCE_EPSILON) {return 1.0;}\nreturn renderedLuminance/baseLuminance;}\nfloat calculateMeshBlendShadowAttenuation(vec3 currentColor,MeshBlendTargetColorSamples samples) {float fartherShadow=estimateMeshBlendShadow(samples.fartherColor.rgb,samples.fartherBaseColor);float nearShadow=estimateMeshBlendShadow(samples.conservativeNearColor.rgb,samples.conservativeNearBaseColor);float shadowDifference=abs(fartherShadow-nearShadow);float shadowMismatch=smoothstep(MESH_BLEND_SHADOW_DIFFERENCE_LOW,MESH_BLEND_SHADOW_DIFFERENCE_HIGH,shadowDifference);float currentLuminance=meshBlendLuminance(meshBlendLinearToSrgb(currentColor));float targetLuminance=meshBlendLuminance(meshBlendLinearToSrgb(samples.targetColor.rgb));float targetToCurrentRatio=targetLuminance/max(currentLuminance,MESH_BLEND_BASE_LUMINANCE_EPSILON);float targetIsNotDark=smoothstep(MESH_BLEND_TARGET_DARKER_RATIO,MESH_BLEND_TARGET_NON_DARK_RATIO,targetToCurrentRatio);return mix(1.0,MESH_BLEND_SHADOW_MIN_ATTENUATION,shadowMismatch*targetIsNotDark);}\n#endif\nMeshBlendColorEvaluation evaluateMeshBlendColor(\nivec2 pixel,\nivec2 renderSize,\nMeshBlendTag currentTag,\nMeshBlendResult result\n) {MeshBlendColorEvaluation evaluation;evaluation.samples=constructMeshBlendTargetColorSamples(renderSize,result);\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\nevaluation.worldPosition=reconstructMeshBlendWorldPosition(result.currentViewPosition);\n#endif\nvec4 currentSceneColor=texelFetch(textureSampler,pixel,0);evaluation.currentColor=applyMeshBlendNearSeamCorrection(\npixel,\nrenderSize,\ncurrentTag,\nresult,\nevaluation.samples,\ncurrentSceneColor,\nevaluation.nearSeamCorrected\n);evaluation.shadowAttenuation=1.0;\n#ifdef MESH_BLEND_SHADOW_ESTIMATION\nevaluation.shadowAttenuation=calculateMeshBlendShadowAttenuation(evaluation.currentColor.rgb,evaluation.samples);\n#endif\nevaluation.adjustedFade=result.fade*evaluation.shadowAttenuation;evaluation.blendedColor=vec4(\ninterpolateMeshBlendColor(evaluation.currentColor.rgb,evaluation.samples.targetColor.rgb,evaluation.adjustedFade),\nmix(evaluation.currentColor.a,evaluation.samples.targetColor.a,evaluation.adjustedFade)\n);return evaluation;}\nvec3 radiusClassDebugColor(uint radiusClass) {if (radiusClass==0u) {return vec3(0.15,0.55,1.0);}\nif (radiusClass==1u) {return vec3(0.15,0.9,0.35);}\nif (radiusClass==2u) {return vec3(1.0,0.65,0.1);}\nreturn vec3(0.95,0.2,0.65);}\nvec3 validationDebugColor(int rejectionReason,float narrowedRadiusRatio) {if (rejectionReason==MESH_BLEND_REJECTION_NONE) {return mix(vec3(0.1,0.55,1.0),vec3(0.2,1.0,0.25),narrowedRadiusRatio);}\nif (rejectionReason==MESH_BLEND_REJECTION_NO_CANDIDATE) {return vec3(0.12);}\nif (rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {return vec3(0.75,0.1,0.85);}\nif (rejectionReason==MESH_BLEND_REJECTION_INVALID_DEPTH) {return vec3(1.0,0.0,1.0);}\nif (rejectionReason==MESH_BLEND_REJECTION_DEPTH_SEPARATION) {return vec3(1.0,0.1,0.1);}\nif (rejectionReason==MESH_BLEND_REJECTION_FOREGROUND_BACKGROUND) {return vec3(1.0,0.4,0.05);}\nif (rejectionReason==MESH_BLEND_REJECTION_PHYSICAL_SPAN) {return vec3(1.0,0.9,0.05);}\nreturn vec3(0.05,0.8,1.0);}\nvec3 processingStageDebugColor(int stageReached) {if (stageReached<=0) {return vec3(0.03);}\nif (stageReached==1) {return vec3(0.1,0.15,0.45);}\nif (stageReached==2) {return vec3(0.1,0.35,0.7);}\nif (stageReached==3) {return vec3(0.05,0.65,0.8);}\nif (stageReached==4) {return vec3(0.1,0.8,0.55);}\nif (stageReached==5) {return vec3(0.45,0.9,0.25);}\nif (stageReached==6) {return vec3(0.95,0.75,0.1);}\nreturn vec3(0.15,1.0,0.25);}\nvec3 candidateDebugColor(MeshBlendResult result) {if (!result.candidate.valid) {return vec3(0.04);}\nfloat normalizedDistance=clamp(\nresult.candidate.distancePixels/max(result.candidate.searchRadiusPixels,MESH_BLEND_EPSILON),\n0.0,\n1.0\n);return vec3(result.candidate.direction*0.5+0.5,1.0-normalizedDistance);}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {ivec2 renderSize=textureSize(meshBlendDepthSampler,0);ivec2 pixel=clampPixel(ivec2(floor(vUV*vec2(renderSize))),renderSize);MeshBlendTag currentTag=loadMeshBlendTag(pixel,renderSize);\n#ifdef MESH_BLEND_DEBUG_PACKED_TAG\nfloat groupVariation=0.45+0.55*fract(float(currentTag.groupId)*0.61803398875);vec3 tagColor=radiusClassDebugColor(currentTag.radiusClass)*groupVariation;gl_FragColor=currentTag.groupId==0u ? vec4(0.0,0.0,0.0,1.0) : vec4(tagColor,1.0);return;\n#endif\nif (currentTag.groupId==0u) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\ngl_FragColor=vec4(0.0,0.0,0.0,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\nfloat sizingDepth=loadMeshBlendDepth(pixel,renderSize);vec3 sizingPosition=reconstructMeshBlendViewPosition(pixel,renderSize,sizingDepth);if (!isValidMeshBlendPosition(sizingPosition)) {\n#ifdef MESH_BLEND_DEBUG_REJECTION_REASON\ngl_FragColor=vec4(validationDebugColor(MESH_BLEND_REJECTION_INVALID_DEPTH,0.0),1.0);\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\ngl_FragColor=vec4(0.45,0.1,0.1,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\ngl_FragColor=vec4(0.4,0.05,0.4,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\nfloat currentViewDepth=abs(sizingPosition.z);float currentSearchRadius=searchRadiusForClass(currentTag.radiusClass,currentViewDepth,float(renderSize.y));if (currentSearchRadius<1.0) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\ngl_FragColor=vec4(radiusClassDebugColor(currentTag.radiusClass)*0.25,1.0);\n#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)\ngl_FragColor=vec4(validationDebugColor(MESH_BLEND_REJECTION_PHYSICAL_SPAN,0.0),1.0);\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\ngl_FragColor=vec4(0.2,0.2,0.65,1.0);\n#elif defined(MESH_BLEND_DEBUG_ENABLED)\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\nvec2 randomValues=loadStableBlueNoise(pixel);float sectorAngle=MESH_BLEND_TWO_PI/float(MESH_BLEND_DIRECTION_COUNT);float rotation;\n#ifdef MESH_BLEND_FULL_RANDOM_ROTATION\nrotation=randomValues.x*sectorAngle;\n#else\nrotation=floor(randomValues.x*8.0)*0.125*sectorAngle;\n#endif\nvec2 direction0=vec2(cos(rotation),sin(rotation));vec2 direction1=vec2(cos(rotation+sectorAngle),sin(rotation+sectorAngle));vec2 direction2=vec2(cos(rotation+sectorAngle*2.0),sin(rotation+sectorAngle*2.0));MeshBlendResult primaryResult=evaluateMeshBlend(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\ncurrentViewDepth,\n0u,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);MeshBlendResult secondaryResult=invalidBlendResult();\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (primaryResult.valid) {secondaryResult=evaluateMeshBlend(\npixel,\nrenderSize,\ncurrentTag,\ncurrentSearchRadius,\ncurrentViewDepth,\nprimaryResult.candidate.targetGroupId,\nrandomValues,\nrotation,\nsectorAngle,\ndirection0,\ndirection1,\ndirection2\n);}\n#endif\n#ifdef MESH_BLEND_DEBUG_CANDIDATE_DIRECTION_DISTANCE\ngl_FragColor=vec4(candidateDebugColor(primaryResult),1.0);return;\n#elif defined(MESH_BLEND_DEBUG_CONTINUATION)\nif (!primaryResult.candidate.valid) {gl_FragColor=vec4(0.04,0.04,0.04,1.0);} else if (primaryResult.rejectionReason==MESH_BLEND_REJECTION_NO_CONTINUATION) {gl_FragColor=vec4(0.85,0.05,0.7,1.0);} else if (primaryResult.usedFallback) {gl_FragColor=vec4(1.0,0.75,0.05,1.0);} else {gl_FragColor=vec4(0.1,0.9,0.25,1.0);}\nreturn;\n#elif defined(MESH_BLEND_DEBUG_TINY_OBJECT)\n#ifdef MESH_BLEND_TINY_OBJECT_SAFEGUARD\nif (!primaryResult.candidate.valid) {gl_FragColor=vec4(0.04,0.04,0.04,1.0);} else {vec3 radiusColor=mix(vec3(1.0,0.1,0.05),vec3(0.1,0.65,1.0),primaryResult.tinyObjectRadiusRatio);gl_FragColor=vec4(primaryResult.tinyObjectRadiusReduced ? radiusColor : radiusColor*0.45,1.0);}\n#else\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#endif\nreturn;\n#elif defined(MESH_BLEND_DEBUG_MULTI_TARGET)\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {gl_FragColor=vec4(0.95,0.95,1.0,1.0);} else if (secondaryResult.candidate.valid) {gl_FragColor=vec4(0.8,0.15,0.75,1.0);} else if (primaryResult.valid) {gl_FragColor=vec4(0.1,0.45,0.95,1.0);} else {gl_FragColor=vec4(0.04,0.04,0.04,1.0);}\n#else\ngl_FragColor=primaryResult.valid ? vec4(0.1,0.45,0.95,1.0) : vec4(0.04,0.04,0.04,1.0);\n#endif\nreturn;\n#elif defined(MESH_BLEND_DEBUG_REJECTION_REASON)\nfloat narrowedRadiusRatio=primaryResult.candidate.valid\n? primaryResult.effectiveRadiusPixels/max(primaryResult.candidate.searchRadiusPixels,MESH_BLEND_EPSILON)\n: 0.0;gl_FragColor=vec4(validationDebugColor(primaryResult.rejectionReason,narrowedRadiusRatio),1.0);return;\n#elif defined(MESH_BLEND_DEBUG_STAGE_WORK)\nint stageReached=primaryResult.stageReached;\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nstageReached=max(stageReached,secondaryResult.stageReached);\n#endif\ngl_FragColor=vec4(processingStageDebugColor(stageReached),1.0);return;\n#endif\nif (!primaryResult.valid) {\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nuint debugRadiusClass=primaryResult.candidate.valid ? primaryResult.candidate.radiusClass : currentTag.radiusClass;gl_FragColor=vec4(radiusClassDebugColor(debugRadiusClass)*0.25,1.0);\n#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR) || defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION) || defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION) || defined(MESH_BLEND_DEBUG_WORLD_POSITION)\ngl_FragColor=vec4(0.04,0.04,0.04,1.0);\n#else\ngl_FragColor=texelFetch(textureSampler,pixel,0);\n#endif\nreturn;}\n#ifdef MESH_BLEND_DEBUG_SEAM_FADE\nfloat debugFade=primaryResult.fade;\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {debugFade=min(0.5,primaryResult.fade+secondaryResult.fade);}\n#endif\nvec3 classColor=radiusClassDebugColor(primaryResult.candidate.radiusClass)*0.25;gl_FragColor=vec4(mix(classColor,vec3(1.0),clamp(debugFade*2.0,0.0,1.0)),1.0);return;\n#else\nMeshBlendColorEvaluation primaryColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,primaryResult);\n#ifdef MESH_BLEND_DEBUG_WORLD_POSITION\ngl_FragColor=vec4(fract(primaryColorEvaluation.worldPosition*0.1),1.0);return;\n#elif defined(MESH_BLEND_DEBUG_TARGET_COLOR)\nint targetSampleIndex=(pixel.x/4) % 4;if (targetSampleIndex==0) {gl_FragColor=primaryColorEvaluation.samples.fartherColor;} else if (targetSampleIndex==1) {gl_FragColor=primaryColorEvaluation.samples.boundaryPlusOneColor;} else if (targetSampleIndex==2) {gl_FragColor=primaryColorEvaluation.samples.boundaryPlusTwoColor;} else {gl_FragColor=primaryColorEvaluation.samples.targetColor;}\nreturn;\n#elif defined(MESH_BLEND_DEBUG_SHADOW_ATTENUATION)\ngl_FragColor=vec4(\n1.0-primaryColorEvaluation.shadowAttenuation,\nprimaryColorEvaluation.shadowAttenuation,\nprimaryColorEvaluation.nearSeamCorrected ? 1.0 : 0.0,\n1.0\n);return;\n#elif defined(MESH_BLEND_DEBUG_COLOR_INTERPOLATION)\n#ifdef MESH_BLEND_COLOR_INTERPOLATION_SRGB\nvec3 interpolationModeColor=vec3(1.0,0.4,0.05);\n#else\nvec3 interpolationModeColor=vec3(0.1,0.75,1.0);\n#endif\nfloat interpolationStage=mix(0.35,1.0,clamp(primaryColorEvaluation.adjustedFade*2.0,0.0,1.0));gl_FragColor=vec4(interpolationModeColor*interpolationStage,1.0);return;\n#else\n#ifdef MESH_BLEND_MULTI_TARGET_SECONDARY_BLEND\nif (secondaryResult.valid) {MeshBlendColorEvaluation secondaryColorEvaluation=evaluateMeshBlendColor(pixel,renderSize,currentTag,secondaryResult);float totalBoundaryDistance=max(\nprimaryResult.candidate.distancePixels+secondaryResult.candidate.distancePixels,\nMESH_BLEND_EPSILON\n);float primaryRelativeProximity=secondaryResult.candidate.distancePixels/totalBoundaryDistance;float secondaryRelativeProximity=primaryResult.candidate.distancePixels/totalBoundaryDistance;float primaryWeight=primaryColorEvaluation.adjustedFade*primaryRelativeProximity;float secondaryWeight=secondaryColorEvaluation.adjustedFade*secondaryRelativeProximity;float combinedWeight=primaryWeight+secondaryWeight;if (combinedWeight<=MESH_BLEND_EPSILON) {gl_FragColor=texelFetch(textureSampler,pixel,0);return;}\ngl_FragColor=(primaryColorEvaluation.blendedColor*primaryWeight+secondaryColorEvaluation.blendedColor*secondaryWeight)/combinedWeight;return;}\n#endif\ngl_FragColor=primaryColorEvaluation.blendedColor;\n#endif\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const meshBlendingPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"screenSpaceCurvaturePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var normalSampler: texture_2d<f32>;uniform curvature_ridge: f32;uniform curvature_valley: f32;\n#ifndef CURVATURE_OFFSET\n#define CURVATURE_OFFSET 1\n#endif\nfn curvature_soft_clamp(curvature: f32,control: f32)->f32\n{if (curvature<0.5/control) {return curvature*(1.0-curvature*control);}\nreturn 0.25/control;}\nfn calculate_curvature(texel: vec2i,ridge: f32,valley: f32)->f32\n{let normal_up =textureLoad(normalSampler,texel+vec2i(0, CURVATURE_OFFSET),0).rb;let normal_down =textureLoad(normalSampler,texel+vec2i(0,-CURVATURE_OFFSET),0).rb;let normal_left =textureLoad(normalSampler,texel+vec2i(-CURVATURE_OFFSET,0),0).rb;let normal_right=textureLoad(normalSampler,texel+vec2i( CURVATURE_OFFSET,0),0).rb;let normal_diff=((normal_up.g-normal_down.g)+(normal_right.r-normal_left.r));if (normal_diff<0.0) {return -2.0*curvature_soft_clamp(-normal_diff,valley);}\nreturn 2.0*curvature_soft_clamp(normal_diff,ridge);}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs\n{let texel=vec2i(fragmentInputs.position.xy);let baseColor=textureSample(textureSampler,textureSamplerSampler,fragmentInputs.vUV);let curvature=calculate_curvature(texel,uniforms.curvature_ridge,uniforms.curvature_valley);fragmentOutputs.color=vec4f(baseColor.rgb*(curvature+1.0),baseColor.a);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const screenSpaceCurvaturePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"volumetricLightingBlendVolumePixelShader\";\nconst shader = `varying vUV: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var depthSampler: texture_2d<f32>;uniform invProjection: mat4x4<f32>;uniform outputTextureSize: vec2f;\n#ifdef USE_EXTINCTION\nuniform extinction: vec3f;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {fragmentOutputs.color=textureSample(textureSampler,textureSamplerSampler,input.vUV);\n#ifdef USE_EXTINCTION\nlet depth=textureLoad(depthSampler,vec2u(fragmentInputs.position.xy),0).r;let ndc=vec4f((fragmentInputs.position.xy/uniforms.outputTextureSize)*2.-1.,depth,1.0);var viewPos=uniforms.invProjection*ndc;viewPos=viewPos/viewPos.w;let eyeDist=length(viewPos);fragmentOutputs.color2=vec4f(exp(-uniforms.extinction*eyeDist),1.0);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const volumetricLightingBlendVolumePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"volumetricLightingBlendVolumePixelShader\";\nconst shader = `varying vec2 vUV;uniform sampler2D textureSampler;uniform sampler2D depthSampler;uniform mat4 invProjection;uniform vec2 outputTextureSize;\n#ifdef USE_EXTINCTION\nuniform vec3 extinction;\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {gl_FragColor=texture2D(textureSampler,vUV);\n#ifdef USE_EXTINCTION\nfloat depth=texelFetch(depthSampler,ivec2(gl_FragCoord.xy),0).r;vec4 ndc=vec4((gl_FragCoord.xy/outputTextureSize)*2.-1.,depth*2.-1.,1.0);vec4 viewPos=invProjection*ndc;viewPos=viewPos/viewPos.w;float eyeDist=length(viewPos);gl_FragColor2=vec4(exp(-extinction*eyeDist),1.0);\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const volumetricLightingBlendVolumePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\n\nconst name = \"volumetricLightingRenderVolumeVertexShader\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nattribute position : vec3f;varying vWorldPos: vec4f;@vertex\nfn main(input : VertexInputs)->FragmentInputs {let worldPos=mesh.world*vec4f(vertexInputs.position,1.0);vertexOutputs.vWorldPos=worldPos;vertexOutputs.position=scene.viewProjection*worldPos;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const volumetricLightingRenderVolumeVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneUboDeclarationWGSL } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshUboDeclarationWGSL } from \"./ShadersInclude/meshUboDeclaration\";\n\nconst name = \"volumetricLightingRenderVolumePixelShader\";\nconst shader = `#include<sceneUboDeclaration>\n#include<meshUboDeclaration>\nuniform invViewProjection: mat4x4<f32>;uniform lightDir: vec3f; \nuniform outputTextureSize: vec2f;uniform extinctionPhaseG: vec4f;uniform lightPower: vec3f;uniform textureRatio: vec2f;var depthTexture: texture_2d<f32>;varying vWorldPos: vec4f;fn henyeyGreenstein(g: f32,cosTheta: f32)->f32 {let denom=1+g*g-2*g*cosTheta;return 1.0/(4.0*3.14159265)*(1.0-g*g)/(denom*sqrt(max(denom,0.0)));}\nfn integrateDirectional(eyeDist: f32,viewDir: vec3f,lightDir: vec3f)->vec3f {let phaseG=uniforms.extinctionPhaseG.w;\n#ifdef USE_EXTINCTION\nlet extinction=uniforms.extinctionPhaseG.xyz;return henyeyGreenstein(phaseG,dot(viewDir,lightDir))*(vec3f(1.0)-exp(-extinction*eyeDist))/extinction;\n#else\nreturn vec3f(henyeyGreenstein(phaseG,dot(viewDir,lightDir)))*vec3f(eyeDist);\n#endif\n}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let depth=textureLoad(depthTexture,vec2u(fragmentInputs.position.xy*uniforms.textureRatio),0).r;var worldPos=fragmentInputs.vWorldPos;if (fragmentInputs.position.z>depth) {let ndc=vec4f((fragmentInputs.position.xy/uniforms.outputTextureSize)*2.-1.,depth,1.0);worldPos=uniforms.invViewProjection*ndc;worldPos=worldPos/worldPos.w;}\nvar viewDir=worldPos.xyz-scene.vEyePosition.xyz;let eyeDist=length(viewDir);viewDir=viewDir/eyeDist;let fSign=select(-1.0,1.0,fragmentInputs.frontFacing);let integral=integrateDirectional(eyeDist,-viewDir,uniforms.lightDir);fragmentOutputs.color=vec4f(uniforms.lightPower*integral*fSign,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [sceneUboDeclarationWGSL, meshUboDeclarationWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const volumetricLightingRenderVolumePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneVertexDeclaration } from \"./ShadersInclude/sceneVertexDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\nimport { meshVertexDeclaration } from \"./ShadersInclude/meshVertexDeclaration\";\nimport { meshUboDeclaration } from \"./ShadersInclude/meshUboDeclaration\";\n\nconst name = \"volumetricLightingRenderVolumeVertexShader\";\nconst shader = `#include<__decl__sceneVertex>\n#include<__decl__meshVertex>\nattribute vec3 position;varying vec4 vWorldPos;void main(void) {vec4 worldPos=world*vec4(position,1.0);vWorldPos=worldPos;gl_Position=viewProjection*worldPos;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [sceneVertexDeclaration, sceneUboDeclaration, meshVertexDeclaration, meshUboDeclaration];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const volumetricLightingRenderVolumeVertexShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { sceneFragmentDeclaration } from \"./ShadersInclude/sceneFragmentDeclaration\";\nimport { sceneUboDeclaration } from \"./ShadersInclude/sceneUboDeclaration\";\n\nconst name = \"volumetricLightingRenderVolumePixelShader\";\nconst shader = `#include<__decl__sceneFragment>\nuniform mat4 invViewProjection;uniform vec3 lightDir; \nuniform vec2 outputTextureSize;uniform vec4 extinctionPhaseG;uniform vec3 lightPower;uniform vec2 textureRatio;uniform sampler2D depthTexture;varying vec4 vWorldPos;float henyeyGreenstein(float g,float cosTheta) {float denom=1.0+g*g-2.0*g*cosTheta;return 1.0/(4.0*3.14159265)*(1.0-g*g)/(denom*sqrt(max(denom,0.0)));}\nvec3 integrateDirectional(float eyeDist,vec3 viewDir,vec3 lightDir) {float phaseG=extinctionPhaseG.w;\n#ifdef USE_EXTINCTION\nvec3 extinction=extinctionPhaseG.xyz;return henyeyGreenstein(phaseG,dot(viewDir,lightDir))*(vec3(1.0)-exp(-extinction*eyeDist))/extinction;\n#else\nreturn vec3(henyeyGreenstein(phaseG,dot(viewDir,lightDir)))*vec3(eyeDist);\n#endif\n}\nvoid main(void) {float depth=texelFetch(depthTexture,ivec2(gl_FragCoord.xy*textureRatio),0).r;vec4 worldPos=vWorldPos;if (gl_FragCoord.z>depth) {vec4 ndc=vec4((gl_FragCoord.xy/outputTextureSize)*2.0-1.0,depth*2.0-1.0,1.0);worldPos=invViewProjection*ndc;worldPos=worldPos/worldPos.w;}\nvec3 viewDir=worldPos.xyz-vEyePosition.xyz;float eyeDist=length(viewDir);viewDir=viewDir/eyeDist;float fSign=gl_FrontFacing ? 1.0 : -1.0;vec3 integral=integrateDirectional(eyeDist,-viewDir,lightDir);gl_FragColor=vec4(lightPower*integral*fSign,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [sceneFragmentDeclaration, sceneUboDeclaration];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const volumetricLightingRenderVolumePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"iblCopyVoxelBufferToGridComputeShader\";\nconst shader = `@group(0) @binding(0) var<storage,read> voxelOpacityBuffer: array<u32>;@group(0) @binding(1) var voxelGridTarget: texture_storage_3d<r8unorm,write>;@compute @workgroup_size(4,4,4)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {let size: vec3<u32>=textureDimensions(voxelGridTarget);if (id.x>=size.x || id.y>=size.y || id.z>=size.z) {return;}\nlet res: u32=size.x;let vidx: u32=id.x+id.y*res+id.z*res*res;let word: u32=voxelOpacityBuffer[vidx>>2u];let byteVal: u32=(word>>((vidx & 3u)*8u)) & 0xFFu;let opacity: f32=f32(byteVal)/255.0;textureStore(voxelGridTarget,vec3<i32>(id),vec4f(opacity,0.0,0.0,1.0));}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const iblCopyVoxelBufferToGridComputeShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"noisePixelShader\";\nconst shader = `uniform brightness: f32;uniform persistence: f32;uniform timeScale: f32;varying vUV: vec2f;fn hash22(input: vec2f)->vec2f {var p=vec2f(dot(input,vec2f(127.1,311.7)),dot(input,vec2f(269.5,183.3)));p=-vec2f(1.0)+2.0*fract(sin(p)*43758.5453123);return sin(p*6.283+uniforms.timeScale);}\nfn interpolationNoise(p: vec2f)->f32 {let pi=floor(p);let pf=p-pi;let w=pf*pf*(vec2f(3.0)-2.0*pf);let f00=dot(hash22(pi+vec2f(0.0,0.0)),pf-vec2f(0.0,0.0));let f01=dot(hash22(pi+vec2f(0.0,1.0)),pf-vec2f(0.0,1.0));let f10=dot(hash22(pi+vec2f(1.0,0.0)),pf-vec2f(1.0,0.0));let f11=dot(hash22(pi+vec2f(1.0,1.0)),pf-vec2f(1.0,1.0));let xm1=mix(f00,f10,w.x);let xm2=mix(f01,f11,w.x);return mix(xm1,xm2,w.y);}\nfn perlinNoise2D(x: f32,y: f32)->f32 {var sum=0.0;var frequency=0.0;var amplitude=0.0;for (var i=0; i<OCTAVES; i++) {frequency=pow(2.0,f32(i));amplitude=pow(uniforms.persistence,f32(i));sum=sum+interpolationNoise(vec2f(x*frequency,y*frequency))*amplitude;}\nreturn sum;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let x=abs(input.vUV.x);let y=abs(input.vUV.y);let noise=uniforms.brightness+(1.0-uniforms.brightness)*perlinNoise2D(x,y);fragmentOutputs.color=vec4f(noise,noise,noise,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const noisePixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"noisePixelShader\";\nconst shader = `uniform float brightness;uniform float persistence;uniform float timeScale;varying vec2 vUV;vec2 hash22(vec2 p)\n{p=p*mat2(127.1,311.7,269.5,183.3);p=-1.0+2.0*fract(sin(p)*43758.5453123);return sin(p*6.283+timeScale);}\nfloat interpolationNoise(vec2 p)\n{vec2 pi=floor(p);vec2 pf=p-pi;vec2 w=pf*pf*(3.-2.*pf);float f00=dot(hash22(pi+vec2(.0,.0)),pf-vec2(.0,.0));float f01=dot(hash22(pi+vec2(.0,1.)),pf-vec2(.0,1.));float f10=dot(hash22(pi+vec2(1.0,0.)),pf-vec2(1.0,0.));float f11=dot(hash22(pi+vec2(1.0,1.)),pf-vec2(1.0,1.));float xm1=mix(f00,f10,w.x);float xm2=mix(f01,f11,w.x);float ym=mix(xm1,xm2,w.y); \nreturn ym;}\nfloat perlinNoise2D(float x,float y)\n{float sum=0.0;float frequency=0.0;float amplitude=0.0;for(int i=0; i<OCTAVES; i++)\n{frequency=pow(2.0,float(i));amplitude=pow(persistence,float(i));sum=sum+interpolationNoise(vec2(x*frequency,y*frequency))*amplitude;}\nreturn sum;}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void)\n{float x=abs(vUV.x);float y=abs(vUV.y);float noise=brightness+(1.0-brightness)*perlinNoise2D(x,y);gl_FragColor=vec4(noise,noise,noise,1.0);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const noisePixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"textureMergerPixelShader\";\nconst shader = `#ifdef USE_TEXTURE0\nvar inputTexture0Sampler: sampler;var inputTexture0: texture_2d<f32>;\n#endif\n#ifdef USE_TEXTURE1\nvar inputTexture1Sampler: sampler;var inputTexture1: texture_2d<f32>;\n#endif\n#ifdef USE_TEXTURE2\nvar inputTexture2Sampler: sampler;var inputTexture2: texture_2d<f32>;\n#endif\n#ifdef USE_TEXTURE3\nvar inputTexture3Sampler: sampler;var inputTexture3: texture_2d<f32>;\n#endif\n#ifdef RED_FROM_TEXTURE\nuniform redTextureIndex: i32;uniform redSourceChannel: i32;\n#else\nuniform redConstantValue: f32;\n#endif\n#ifdef GREEN_FROM_TEXTURE\nuniform greenTextureIndex: i32;uniform greenSourceChannel: i32;\n#else\nuniform greenConstantValue: f32;\n#endif\n#ifdef BLUE_FROM_TEXTURE\nuniform blueTextureIndex: i32;uniform blueSourceChannel: i32;\n#else\nuniform blueConstantValue: f32;\n#endif\n#ifdef ALPHA_FROM_TEXTURE\nuniform alphaTextureIndex: i32;uniform alphaSourceChannel: i32;\n#else\nuniform alphaConstantValue: f32;\n#endif\nvarying vUV: vec2f;\n#if defined(RED_FROM_TEXTURE) || defined(GREEN_FROM_TEXTURE) || defined(BLUE_FROM_TEXTURE) || defined(ALPHA_FROM_TEXTURE)\nfn sampleTexture(textureIndex: i32,uv: vec2f)->vec4f {switch (textureIndex) {\n#ifdef USE_TEXTURE0\ncase 0: {return textureSample(inputTexture0,inputTexture0Sampler,uv);}\n#endif\n#ifdef USE_TEXTURE1\ncase 1: {return textureSample(inputTexture1,inputTexture1Sampler,uv);}\n#endif\n#ifdef USE_TEXTURE2\ncase 2: {return textureSample(inputTexture2,inputTexture2Sampler,uv);}\n#endif\n#ifdef USE_TEXTURE3\ncase 3: {return textureSample(inputTexture3,inputTexture3Sampler,uv);}\n#endif\ndefault: {return vec4f(0.0,0.0,0.0,1.0); }}}\nfn extractChannel(color: vec4f,channelIndex: i32)->f32 {switch (channelIndex) {case 0: {return color.r; }\ncase 1: {return color.g; }\ncase 2: {return color.b; }\ndefault: {return color.a; }}}\n#endif\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let uv: vec2f=input.vUV;\n#ifdef RED_FROM_TEXTURE\nlet redSample: vec4f=sampleTexture(uniforms.redTextureIndex,uv);let r: f32=extractChannel(redSample,uniforms.redSourceChannel);\n#else\nlet r: f32=uniforms.redConstantValue;\n#endif\n#ifdef GREEN_FROM_TEXTURE\nlet greenSample: vec4f=sampleTexture(uniforms.greenTextureIndex,uv);let g: f32=extractChannel(greenSample,uniforms.greenSourceChannel);\n#else\nlet g: f32=uniforms.greenConstantValue;\n#endif\n#ifdef BLUE_FROM_TEXTURE\nlet blueSample: vec4f=sampleTexture(uniforms.blueTextureIndex,uv);let b: f32=extractChannel(blueSample,uniforms.blueSourceChannel);\n#else\nlet b: f32=uniforms.blueConstantValue;\n#endif\n#ifdef ALPHA_FROM_TEXTURE\nlet alphaSample: vec4f=sampleTexture(uniforms.alphaTextureIndex,uv);let a: f32=extractChannel(alphaSample,uniforms.alphaSourceChannel);\n#else\nlet a: f32=uniforms.alphaConstantValue;\n#endif\nfragmentOutputs.color=vec4f(r,g,b,a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const textureMergerPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"textureMergerPixelShader\";\nconst shader = `#ifdef USE_TEXTURE0\nuniform sampler2D inputTexture0;\n#endif\n#ifdef USE_TEXTURE1\nuniform sampler2D inputTexture1;\n#endif\n#ifdef USE_TEXTURE2\nuniform sampler2D inputTexture2;\n#endif\n#ifdef USE_TEXTURE3\nuniform sampler2D inputTexture3;\n#endif\n#ifdef RED_FROM_TEXTURE\nuniform int redTextureIndex;uniform int redSourceChannel;\n#else\nuniform float redConstantValue;\n#endif\n#ifdef GREEN_FROM_TEXTURE\nuniform int greenTextureIndex;uniform int greenSourceChannel;\n#else\nuniform float greenConstantValue;\n#endif\n#ifdef BLUE_FROM_TEXTURE\nuniform int blueTextureIndex;uniform int blueSourceChannel;\n#else\nuniform float blueConstantValue;\n#endif\n#ifdef ALPHA_FROM_TEXTURE\nuniform int alphaTextureIndex;uniform int alphaSourceChannel;\n#else\nuniform float alphaConstantValue;\n#endif\nvarying vec2 vUV;\n#if defined(RED_FROM_TEXTURE) || defined(GREEN_FROM_TEXTURE) || defined(BLUE_FROM_TEXTURE) || defined(ALPHA_FROM_TEXTURE)\nvec4 sampleTexture(int textureIndex,vec2 uv) {switch (textureIndex) {\n#ifdef USE_TEXTURE0\ncase 0:\nreturn texture2D(inputTexture0,uv);\n#endif\n#ifdef USE_TEXTURE1\ncase 1:\nreturn texture2D(inputTexture1,uv);\n#endif\n#ifdef USE_TEXTURE2\ncase 2:\nreturn texture2D(inputTexture2,uv);\n#endif\n#ifdef USE_TEXTURE3\ncase 3:\nreturn texture2D(inputTexture3,uv);\n#endif\ndefault:\nreturn vec4(0.0,0.0,0.0,1.0); }}\nfloat extractChannel(vec4 color,int channelIndex) {switch (channelIndex) {case 0:\nreturn color.r; \ncase 1:\nreturn color.g; \ncase 2:\nreturn color.b; \ndefault:\nreturn color.a; }}\n#endif\nvoid main() {vec2 uv=vUV;\n#ifdef RED_FROM_TEXTURE\nvec4 redSample=sampleTexture(redTextureIndex,uv);float r=extractChannel(redSample,redSourceChannel);\n#else\nfloat r=redConstantValue;\n#endif\n#ifdef GREEN_FROM_TEXTURE\nvec4 greenSample=sampleTexture(greenTextureIndex,uv);float g=extractChannel(greenSample,greenSourceChannel);\n#else\nfloat g=greenConstantValue;\n#endif\n#ifdef BLUE_FROM_TEXTURE\nvec4 blueSample=sampleTexture(blueTextureIndex,uv);float b=extractChannel(blueSample,blueSourceChannel);\n#else\nfloat b=blueConstantValue;\n#endif\n#ifdef ALPHA_FROM_TEXTURE\nvec4 alphaSample=sampleTexture(alphaTextureIndex,uv);float a=extractChannel(alphaSample,alphaSourceChannel);\n#else\nfloat a=alphaConstantValue;\n#endif\ngl_FragColor=vec4(r,g,b,a);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const textureMergerPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"textureProcessorPixelShader\";\nconst shader = `#ifdef OPERAND_A_TEXTURE\nvar textureASampler: sampler;var textureA: texture_2d<f32>;\n#endif\n#ifdef OPERAND_B_TEXTURE\nvar textureBSampler: sampler;var textureB: texture_2d<f32>;\n#endif\n#if defined(OP_LERP) && defined(LERP_T_TEXTURE)\nvar textureTSampler: sampler;var textureT: texture_2d<f32>;\n#endif\n#ifdef OPERAND_A_MATRIX\nuniform textureAMatrix: mat4x4f;\n#endif\n#ifdef OPERAND_B_MATRIX\nuniform textureBMatrix: mat4x4f;\n#endif\n#if defined(OP_LERP) && defined(LERP_T_MATRIX)\nuniform textureTMatrix: mat4x4f;\n#endif\n#if !defined(OPERAND_A_TEXTURE) || defined(OPERAND_A_FACTOR)\nuniform factorA: vec4f;\n#endif\n#if !defined(OPERAND_B_TEXTURE) || defined(OPERAND_B_FACTOR)\nuniform factorB: vec4f;\n#endif\n#if defined(OP_LERP) && (!defined(LERP_T_TEXTURE) || defined(LERP_T_FACTOR))\nuniform factorT: vec4f;\n#endif\nvarying vUV: vec2f;@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let uv: vec2f=input.vUV;\n#ifdef OPERAND_A_TEXTURE\n#ifdef OPERAND_A_MATRIX\nvar a: vec4f=textureSample(textureA,textureASampler,(uniforms.textureAMatrix*vec4f(uv,0.0,1.0)).xy);\n#else\nvar a: vec4f=textureSample(textureA,textureASampler,uv);\n#endif\n#ifdef OPERAND_A_SRGB\na=vec4f(mix(a.rgb/vec3f(12.92),pow((a.rgb+vec3f(0.055))/vec3f(1.055),vec3f(2.4)),step(vec3f(0.04045),a.rgb)),a.a);\n#endif\n#ifdef OPERAND_A_CHANNEL_R\na=vec4f(a.rrr,a.a);\n#elif defined(OPERAND_A_CHANNEL_G)\na=vec4f(a.ggg,a.a);\n#elif defined(OPERAND_A_CHANNEL_B)\na=vec4f(a.bbb,a.a);\n#elif defined(OPERAND_A_CHANNEL_A)\na=a.aaaa;\n#endif\n#ifdef OPERAND_A_FACTOR\na*=uniforms.factorA;\n#endif\n#else\nlet a: vec4f=uniforms.factorA;\n#endif\n#ifdef OPERAND_B_TEXTURE\n#ifdef OPERAND_B_MATRIX\nvar b: vec4f=textureSample(textureB,textureBSampler,(uniforms.textureBMatrix*vec4f(uv,0.0,1.0)).xy);\n#else\nvar b: vec4f=textureSample(textureB,textureBSampler,uv);\n#endif\n#ifdef OPERAND_B_SRGB\nb=vec4f(mix(b.rgb/vec3f(12.92),pow((b.rgb+vec3f(0.055))/vec3f(1.055),vec3f(2.4)),step(vec3f(0.04045),b.rgb)),b.a);\n#endif\n#ifdef OPERAND_B_CHANNEL_R\nb=vec4f(b.rrr,b.a);\n#elif defined(OPERAND_B_CHANNEL_G)\nb=vec4f(b.ggg,b.a);\n#elif defined(OPERAND_B_CHANNEL_B)\nb=vec4f(b.bbb,b.a);\n#elif defined(OPERAND_B_CHANNEL_A)\nb=b.aaaa;\n#endif\n#ifdef OPERAND_B_FACTOR\nb*=uniforms.factorB;\n#endif\n#else\nlet b: vec4f=uniforms.factorB;\n#endif\n#ifdef OP_CHANNEL_MAX\nvar _cmax: f32=max(max(a.r,a.g),a.b);\n#ifdef CHANNEL_MAX_INCLUDE_ALPHA\n_cmax=max(_cmax,a.a);var result: vec4f=vec4f(_cmax,_cmax,_cmax,_cmax);\n#else\nvar result: vec4f=vec4f(_cmax,_cmax,_cmax,a.a);\n#endif\n#elif defined(OP_INVERT)\nvar _ir: f32=a.r; var _ig: f32=a.g; var _ib: f32=a.b; var _ia: f32=a.a;\n#ifdef INVERT_R\n_ir=1.0-_ir;\n#endif\n#ifdef INVERT_G\n_ig=1.0-_ig;\n#endif\n#ifdef INVERT_B\n_ib=1.0-_ib;\n#endif\n#ifdef INVERT_A\n_ia=1.0-_ia;\n#endif\nvar result: vec4f=vec4f(_ir,_ig,_ib,_ia);\n#elif defined(OP_LERP)\n#ifdef LERP_T_TEXTURE\n#ifdef LERP_T_MATRIX\nvar t: vec4f=textureSample(textureT,textureTSampler,(uniforms.textureTMatrix*vec4f(uv,0.0,1.0)).xy);\n#else\nvar t: vec4f=textureSample(textureT,textureTSampler,uv);\n#endif\n#ifdef LERP_T_SRGB\nt=vec4f(mix(t.rgb/vec3f(12.92),pow((t.rgb+vec3f(0.055))/vec3f(1.055),vec3f(2.4)),step(vec3f(0.04045),t.rgb)),t.a);\n#endif\n#ifdef LERP_T_CHANNEL_R\nt=vec4f(t.rrr,t.a);\n#elif defined(LERP_T_CHANNEL_G)\nt=vec4f(t.ggg,t.a);\n#elif defined(LERP_T_CHANNEL_B)\nt=vec4f(t.bbb,t.a);\n#elif defined(LERP_T_CHANNEL_A)\nt=t.aaaa;\n#endif\n#ifdef LERP_T_FACTOR\nt*=uniforms.factorT;\n#endif\n#else\nlet t: vec4f=uniforms.factorT;\n#endif\nvar result: vec4f=mix(a,b,t);\n#elif defined(OP_MAX)\nvar result: vec4f=max(a,b);\n#else\nvar result: vec4f=a*b;\n#endif\n#if defined(OUTPUT_MASK_R_ZERO) || defined(OUTPUT_MASK_G_ZERO) || defined(OUTPUT_MASK_B_ZERO) || defined(OUTPUT_MASK_A_ONE)\nvar _omr: f32=result.r; var _omg: f32=result.g; var _omb: f32=result.b; var _oma: f32=result.a;\n#ifdef OUTPUT_MASK_R_ZERO\n_omr=0.0;\n#endif\n#ifdef OUTPUT_MASK_G_ZERO\n_omg=0.0;\n#endif\n#ifdef OUTPUT_MASK_B_ZERO\n_omb=0.0;\n#endif\n#ifdef OUTPUT_MASK_A_ONE\n_oma=1.0;\n#endif\nresult=vec4f(_omr,_omg,_omb,_oma);\n#endif\n#ifdef OUTPUT_SRGB\nresult=vec4f(mix(result.rgb*vec3f(12.92),pow(result.rgb,vec3f(1.0/2.4))*vec3f(1.055)-vec3f(0.055),step(vec3f(0.0031308),result.rgb)),result.a);\n#endif\nfragmentOutputs.color=result;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n\n/** @internal */\nexport const textureProcessorPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\n\nconst name = \"textureProcessorPixelShader\";\nconst shader = `#ifdef OPERAND_A_TEXTURE\nuniform sampler2D textureA;\n#endif\n#ifdef OPERAND_B_TEXTURE\nuniform sampler2D textureB;\n#endif\n#if defined(OP_LERP) && defined(LERP_T_TEXTURE)\nuniform sampler2D textureT;\n#endif\n#ifdef OPERAND_A_MATRIX\nuniform mat4 textureAMatrix;\n#endif\n#ifdef OPERAND_B_MATRIX\nuniform mat4 textureBMatrix;\n#endif\n#if defined(OP_LERP) && defined(LERP_T_MATRIX)\nuniform mat4 textureTMatrix;\n#endif\n#if !defined(OPERAND_A_TEXTURE) || defined(OPERAND_A_FACTOR)\nuniform vec4 factorA;\n#endif\n#if !defined(OPERAND_B_TEXTURE) || defined(OPERAND_B_FACTOR)\nuniform vec4 factorB;\n#endif\n#if defined(OP_LERP) && (!defined(LERP_T_TEXTURE) || defined(LERP_T_FACTOR))\nuniform vec4 factorT;\n#endif\nvarying vec2 vUV;void main() {vec2 uv=vUV;\n#ifdef OPERAND_A_TEXTURE\n#ifdef OPERAND_A_MATRIX\nvec4 a=texture2D(textureA,(textureAMatrix*vec4(uv,0.0,1.0)).xy);\n#else\nvec4 a=texture2D(textureA,uv);\n#endif\n#ifdef OPERAND_A_SRGB\na.rgb=mix(a.rgb/12.92,pow((a.rgb+0.055)/1.055,vec3(2.4)),step(vec3(0.04045),a.rgb));\n#endif\n#ifdef OPERAND_A_CHANNEL_R\na=vec4(a.rrr,a.a);\n#elif defined(OPERAND_A_CHANNEL_G)\na=vec4(a.ggg,a.a);\n#elif defined(OPERAND_A_CHANNEL_B)\na=vec4(a.bbb,a.a);\n#elif defined(OPERAND_A_CHANNEL_A)\na=a.aaaa;\n#endif\n#ifdef OPERAND_A_FACTOR\na*=factorA;\n#endif\n#else\nvec4 a=factorA;\n#endif\n#ifdef OPERAND_B_TEXTURE\n#ifdef OPERAND_B_MATRIX\nvec4 b=texture2D(textureB,(textureBMatrix*vec4(uv,0.0,1.0)).xy);\n#else\nvec4 b=texture2D(textureB,uv);\n#endif\n#ifdef OPERAND_B_SRGB\nb.rgb=mix(b.rgb/12.92,pow((b.rgb+0.055)/1.055,vec3(2.4)),step(vec3(0.04045),b.rgb));\n#endif\n#ifdef OPERAND_B_CHANNEL_R\nb=vec4(b.rrr,b.a);\n#elif defined(OPERAND_B_CHANNEL_G)\nb=vec4(b.ggg,b.a);\n#elif defined(OPERAND_B_CHANNEL_B)\nb=vec4(b.bbb,b.a);\n#elif defined(OPERAND_B_CHANNEL_A)\nb=b.aaaa;\n#endif\n#ifdef OPERAND_B_FACTOR\nb*=factorB;\n#endif\n#else\nvec4 b=factorB;\n#endif\n#ifdef OP_CHANNEL_MAX\nfloat _cmax=max(max(a.r,a.g),a.b);\n#ifdef CHANNEL_MAX_INCLUDE_ALPHA\n_cmax=max(_cmax,a.a);vec4 result=vec4(_cmax,_cmax,_cmax,_cmax);\n#else\nvec4 result=vec4(_cmax,_cmax,_cmax,a.a);\n#endif\n#elif defined(OP_INVERT)\nfloat _ir=a.r; float _ig=a.g; float _ib=a.b; float _ia=a.a;\n#ifdef INVERT_R\n_ir=1.0-_ir;\n#endif\n#ifdef INVERT_G\n_ig=1.0-_ig;\n#endif\n#ifdef INVERT_B\n_ib=1.0-_ib;\n#endif\n#ifdef INVERT_A\n_ia=1.0-_ia;\n#endif\nvec4 result=vec4(_ir,_ig,_ib,_ia);\n#elif defined(OP_LERP)\n#ifdef LERP_T_TEXTURE\n#ifdef LERP_T_MATRIX\nvec4 t=texture2D(textureT,(textureTMatrix*vec4(uv,0.0,1.0)).xy);\n#else\nvec4 t=texture2D(textureT,uv);\n#endif\n#ifdef LERP_T_SRGB\nt.rgb=mix(t.rgb/12.92,pow((t.rgb+0.055)/1.055,vec3(2.4)),step(vec3(0.04045),t.rgb));\n#endif\n#ifdef LERP_T_CHANNEL_R\nt=vec4(t.rrr,t.a);\n#elif defined(LERP_T_CHANNEL_G)\nt=vec4(t.ggg,t.a);\n#elif defined(LERP_T_CHANNEL_B)\nt=vec4(t.bbb,t.a);\n#elif defined(LERP_T_CHANNEL_A)\nt=t.aaaa;\n#endif\n#ifdef LERP_T_FACTOR\nt*=factorT;\n#endif\n#else\nvec4 t=factorT;\n#endif\nvec4 result=mix(a,b,t);\n#elif defined(OP_MAX)\nvec4 result=max(a,b);\n#else\nvec4 result=a*b;\n#endif\n#ifdef OUTPUT_MASK_R_ZERO\nresult.r=0.0;\n#endif\n#ifdef OUTPUT_MASK_G_ZERO\nresult.g=0.0;\n#endif\n#ifdef OUTPUT_MASK_B_ZERO\nresult.b=0.0;\n#endif\n#ifdef OUTPUT_MASK_A_ONE\nresult.a=1.0;\n#endif\n#ifdef OUTPUT_SRGB\nresult.rgb=mix(result.rgb*12.92,pow(result.rgb,vec3(1.0/2.4))*1.055-0.055,step(vec3(0.0031308),result.rgb));\n#endif\ngl_FragColor=result;}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\n\n/** @internal */\nexport const textureProcessorPixelShader = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { clipPlaneVertexDeclarationWGSL } from \"./ShadersInclude/clipPlaneVertexDeclaration\";\nimport { fogVertexDeclarationWGSL } from \"./ShadersInclude/fogVertexDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { clipPlaneVertexWGSL } from \"./ShadersInclude/clipPlaneVertex\";\nimport { fogVertexWGSL } from \"./ShadersInclude/fogVertex\";\nimport { logDepthVertexWGSL } from \"./ShadersInclude/logDepthVertex\";\n\nconst name = \"gpuRenderParticlesVertexShader\";\nconst shader = `uniform view: mat4x4f;uniform projection: mat4x4f;uniform translationPivot: vec2f;uniform worldOffset: vec3f;\n#ifdef LOCAL\nuniform emitterWM: mat4x4f;\n#endif\n#ifdef PREPASS\nuniform cameraInfo: vec2f;\n#ifdef LOCAL\nuniform inverseEmitterWM: mat4x4f;\n#endif\n#ifdef PREPASS_POSITION\nvarying vGeometryPositionW: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vGeometryNormalW: vec3f;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vGeometryNormalV: vec3f;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nvarying vPosition: vec3f;\n#endif\n#ifdef PREPASS_DEPTH\nvarying vViewPos: vec3f;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvarying vNormViewDepth: f32;\n#endif\n#endif\nattribute position: vec3f;attribute age: f32;attribute life: f32;attribute size: vec3f;\n#if !defined(BILLBOARD) || defined(BILLBOARDSTRETCHED_LOCAL)\nattribute initialDirection: vec3f;\n#endif\n#ifdef BILLBOARDSTRETCHED\nattribute direction: vec3f;\n#endif\nattribute angle: f32;\n#ifdef ANIMATESHEET\nattribute cellIndex: f32;\n#endif\nattribute offset: vec2f;attribute uv: vec2f;varying vUV: vec2f;varying vColor: vec4f;varying vPositionW: vec3f;\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\nuniform invView: mat4x4f;\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<logDepthDeclaration>\n#ifdef COLORGRADIENTS\nvar colorGradientSamplerSampler: sampler;var colorGradientSampler: texture_2d<f32>;\n#ifdef COLORGRADIENTS_COLOR2\nattribute seed: vec4f;\n#endif\n#else\nuniform colorDead: vec4f;attribute color: vec4f;\n#endif\n#ifdef ANIMATESHEET\nuniform sheetInfos: vec3f;\n#endif\n#ifdef BILLBOARD\nuniform eyePosition: vec3f;\n#endif\nfn particleBasePosition()->vec3f {\n#ifdef LOCAL\nreturn (uniforms.emitterWM*vec4f(vertexInputs.position,1.0)).xyz+uniforms.worldOffset;\n#else\nreturn vertexInputs.position+uniforms.worldOffset;\n#endif\n}\nfn rotate(yaxis: vec3f,rotatedCorner: vec3f)->vec3f {let xaxis: vec3f=normalize(cross(vec3f(0.0,1.0,0.0),yaxis));let zaxis: vec3f=normalize(cross(yaxis,xaxis));let rotMatrix: mat3x3f=mat3x3f(xaxis,yaxis,zaxis);return particleBasePosition()+rotMatrix*rotatedCorner;}\n#ifdef BILLBOARDSTRETCHED\nfn rotateAlign(toCamera: vec3f,rotatedCorner: vec3f)->vec3f {\n#ifdef BILLBOARDSTRETCHED_LOCAL\nlet stretchDirection: vec3f=vertexInputs.initialDirection;\n#else\nlet stretchDirection: vec3f=vertexInputs.direction;\n#endif\nlet normalizedToCamera: vec3f=normalize(toCamera);let normalizedCrossDirToCamera: vec3f=normalize(cross(normalize(stretchDirection),normalizedToCamera));\n#ifdef BILLBOARDSTRETCHED_LOCAL\nlet row1: vec3f=normalize(stretchDirection);\n#else\nlet row1: vec3f=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\n#endif\nlet rotMatrix: mat3x3f=mat3x3f(normalizedCrossDirToCamera,row1,normalizedToCamera);return particleBasePosition()+rotMatrix*rotatedCorner;}\nfn stretchedNormal(toCamera: vec3f,stretchDirection: vec3f)->vec3f {let normalizedToCamera: vec3f=normalize(toCamera);let normalizedCrossDirToCamera: vec3f=normalize(cross(normalize(stretchDirection),normalizedToCamera));\n#ifdef BILLBOARDSTRETCHED_LOCAL\nlet row1: vec3f=normalize(stretchDirection);\n#else\nlet row1: vec3f=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\n#endif\nreturn normalize(cross(normalizedCrossDirToCamera,row1));}\n#endif\n@vertex\nfn main(input: VertexInputs)->FragmentInputs {\n#ifdef PREPASS\nvar geometryNormalW: vec3f;\n#endif\n#ifdef EMITRATECTRL\nlet shouldCullParticle: bool=vertexInputs.life>0.0 && vertexInputs.age>=vertexInputs.life;\n#endif\n#ifdef ANIMATESHEET\nlet rowOffset: f32=floor(vertexInputs.cellIndex/uniforms.sheetInfos.z);let columnOffset: f32=vertexInputs.cellIndex-rowOffset*uniforms.sheetInfos.z;let uvScale: vec2f=uniforms.sheetInfos.xy;let uvOffset: vec2f=vec2f(vertexInputs.uv.x,1.0-vertexInputs.uv.y);vertexOutputs.vUV=(uvOffset+vec2f(columnOffset,rowOffset))*uvScale;\n#else\nvertexOutputs.vUV=vertexInputs.uv;\n#endif\nlet ratio: f32=min(1.0,vertexInputs.age/vertexInputs.life);\n#ifdef COLORGRADIENTS\n#ifdef COLORGRADIENTS_COLOR2\nlet vColor1: vec4f=textureSampleLevel(colorGradientSampler,colorGradientSamplerSampler,vec2f(ratio,0.25),0.0);let vColor2: vec4f=textureSampleLevel(colorGradientSampler,colorGradientSamplerSampler,vec2f(ratio,0.75),0.0);vertexOutputs.vColor=mix(vColor1,vColor2,vertexInputs.seed.x);\n#else\nvertexOutputs.vColor=textureSampleLevel(colorGradientSampler,colorGradientSamplerSampler,vec2f(ratio,0.0),0.0);\n#endif\n#else\nvertexOutputs.vColor=vertexInputs.color*vec4f(1.0-ratio)+uniforms.colorDead*vec4f(ratio);\n#endif\nlet cornerPos: vec2f=(vertexInputs.offset-uniforms.translationPivot)*vertexInputs.size.yz*vertexInputs.size.x;\n#ifdef BILLBOARD\nvar rotatedCorner: vec4f;rotatedCorner.w=0.0;\n#ifdef BILLBOARDY\nrotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle);rotatedCorner.z=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle);rotatedCorner.y=0.0;rotatedCorner.x+=uniforms.translationPivot.x;rotatedCorner.z+=uniforms.translationPivot.y;var yaxis: vec3f=vertexInputs.position+uniforms.worldOffset-uniforms.eyePosition;yaxis.y=0.0;vertexOutputs.vPositionW=rotate(normalize(yaxis),rotatedCorner.xyz);\n#ifdef PREPASS\ngeometryNormalW=normalize(yaxis);\n#endif\nlet viewPosition: vec4f=uniforms.view*vec4f(vertexOutputs.vPositionW,1.0);\n#elif defined(BILLBOARDSTRETCHED)\nrotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle);rotatedCorner.y=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle);rotatedCorner.z=0.0;rotatedCorner.x+=uniforms.translationPivot.x;rotatedCorner.y+=uniforms.translationPivot.y;let toCamera: vec3f=vertexInputs.position+uniforms.worldOffset-uniforms.eyePosition;vertexOutputs.vPositionW=rotateAlign(toCamera,rotatedCorner.xyz);\n#ifdef PREPASS\n#ifdef BILLBOARDSTRETCHED_LOCAL\ngeometryNormalW=stretchedNormal(toCamera,vertexInputs.initialDirection);\n#else\ngeometryNormalW=stretchedNormal(toCamera,vertexInputs.direction);\n#endif\n#endif\nlet viewPosition: vec4f=uniforms.view*vec4f(vertexOutputs.vPositionW,1.0);\n#else\nrotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle);rotatedCorner.y=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle);rotatedCorner.z=0.0;rotatedCorner.x+=uniforms.translationPivot.x;rotatedCorner.y+=uniforms.translationPivot.y;let viewPosition: vec4f=uniforms.view*vec4f(particleBasePosition(),1.0)+rotatedCorner;vertexOutputs.vPositionW=(uniforms.invView*viewPosition).xyz;\n#ifdef PREPASS\ngeometryNormalW=normalize((uniforms.invView*vec4f(0.0,0.0,1.0,0.0)).xyz);\n#endif\n#endif\n#else\nvar rotatedCorner: vec3f;rotatedCorner.x=cornerPos.x*cos(vertexInputs.angle)-cornerPos.y*sin(vertexInputs.angle);rotatedCorner.y=0.0;rotatedCorner.z=cornerPos.x*sin(vertexInputs.angle)+cornerPos.y*cos(vertexInputs.angle);rotatedCorner.x+=uniforms.translationPivot.x;rotatedCorner.z+=uniforms.translationPivot.y;let yaxis: vec3f=normalize(vertexInputs.initialDirection);vertexOutputs.vPositionW=rotate(yaxis,rotatedCorner);\n#ifdef PREPASS\ngeometryNormalW=yaxis;\n#endif\nlet viewPosition: vec4f=uniforms.view*vec4f(vertexOutputs.vPositionW,1.0);\n#endif\nvertexOutputs.position=uniforms.projection*viewPosition;\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4) || defined(CLIPPLANE5) || defined(CLIPPLANE6) || defined(FOG)\nlet worldPos: vec4f=vec4f(vertexOutputs.vPositionW,1.0);\n#endif\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<logDepthVertex>\n#ifdef PREPASS\nlet geometryViewPosition: vec4f=uniforms.view*vec4f(vertexOutputs.vPositionW,1.0);\n#if defined(PREPASS_NORMAL) || defined(PREPASS_WORLD_NORMAL)\nvar geometryNormalV=normalize((uniforms.view*vec4f(geometryNormalW,0.0)).xyz);let geometryViewDirection=select(vec3f(0.0,0.0,geometryViewPosition.z),geometryViewPosition.xyz,uniforms.projection[3][3]==0.0);if (dot(geometryNormalV,geometryViewDirection)>0.0) {geometryNormalV=-geometryNormalV;geometryNormalW=-geometryNormalW;}\n#endif\n#ifdef PREPASS_POSITION\nvertexOutputs.vGeometryPositionW=vertexOutputs.vPositionW;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvertexOutputs.vGeometryNormalW=normalize(geometryNormalW);\n#endif\n#ifdef PREPASS_NORMAL\nvertexOutputs.vGeometryNormalV=geometryNormalV;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\n#ifdef LOCAL\nvar geometryRenderPosition=vertexOutputs.vPositionW;\n#if defined(BILLBOARD) && !defined(BILLBOARDY) && !defined(BILLBOARDSTRETCHED)\ngeometryRenderPosition=particleBasePosition()+(uniforms.invView*vec4f(rotatedCorner.xyz,0.0)).xyz;\n#endif\nvertexOutputs.vPosition=(uniforms.inverseEmitterWM*vec4f(geometryRenderPosition-uniforms.worldOffset,1.0)).xyz;\n#else\nvertexOutputs.vPosition=vertexOutputs.vPositionW;\n#endif\n#endif\n#ifdef PREPASS_DEPTH\nvertexOutputs.vViewPos=geometryViewPosition.xyz;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nvertexOutputs.vNormViewDepth=(geometryViewPosition.z-uniforms.cameraInfo.x)/(uniforms.cameraInfo.y-uniforms.cameraInfo.x);\n#endif\n#endif\n#ifdef EMITRATECTRL\nif (shouldCullParticle) {vertexOutputs.position=vec4f(0.0,0.0,2.0,1.0);vertexOutputs.vColor=vec4f(0.0);vertexOutputs.vUV=vec2f(0.0);vertexOutputs.vPositionW=vec3f(0.0);\n#ifdef PREPASS\n#ifdef PREPASS_POSITION\nvertexOutputs.vGeometryPositionW=vec3f(0.0);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvertexOutputs.vGeometryNormalW=vec3f(0.0);\n#endif\n#ifdef PREPASS_NORMAL\nvertexOutputs.vGeometryNormalV=vec3f(0.0);\n#endif\n#endif\n}\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [clipPlaneVertexDeclarationWGSL, fogVertexDeclarationWGSL, logDepthDeclarationWGSL, clipPlaneVertexWGSL, fogVertexWGSL, logDepthVertexWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gpuRenderParticlesVertexShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { objectIdFunctionsWGSL } from \"./ShadersInclude/objectIdFunctions\";\nimport { prePassDeclarationWGSL } from \"./ShadersInclude/prePassDeclaration\";\nimport { clipPlaneFragmentDeclarationWGSL } from \"./ShadersInclude/clipPlaneFragmentDeclaration\";\nimport { imageProcessingDeclarationWGSL } from \"./ShadersInclude/imageProcessingDeclaration\";\nimport { logDepthDeclarationWGSL } from \"./ShadersInclude/logDepthDeclaration\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { imageProcessingFunctionsWGSL } from \"./ShadersInclude/imageProcessingFunctions\";\nimport { fogFragmentDeclarationWGSL } from \"./ShadersInclude/fogFragmentDeclaration\";\nimport { clipPlaneFragmentWGSL } from \"./ShadersInclude/clipPlaneFragment\";\nimport { logDepthFragmentWGSL } from \"./ShadersInclude/logDepthFragment\";\nimport { fogFragmentWGSL } from \"./ShadersInclude/fogFragment\";\nimport { meshBlendTagFragmentOutputWGSL } from \"./ShadersInclude/meshBlendTagFragmentOutput\";\nimport { geometryRenderingFragmentWGSL } from \"./ShadersInclude/geometryRenderingFragment\";\n\nconst name = \"gpuRenderParticlesPixelShader\";\nconst shader = `var diffuseSamplerSampler: sampler;var diffuseSampler: texture_2d<f32>;varying vUV: vec2f;varying vColor: vec4f;\n#ifdef PREPASS\nuniform geometryZeroAlphaDiscard: f32;\n#ifdef PREPASS_POSITION\nvarying vGeometryPositionW: vec3f;\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nvarying vGeometryNormalW: vec3f;\n#endif\n#ifdef PREPASS_NORMAL\nvarying vGeometryNormalV: vec3f;\n#endif\n#endif\n#define PREPASS_VELOCITY_ZERO\n#include<prePassDeclaration>[SCENE_MRT_COUNT]\n#include<clipPlaneFragmentDeclaration>\n#include<imageProcessingDeclaration>\n#include<logDepthDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#include<fogFragmentDeclaration>\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {\n#include<clipPlaneFragment>\nlet textureColor: vec4f=textureSample(diffuseSampler,diffuseSamplerSampler,input.vUV);var baseColor: vec4f=textureColor*input.vColor;\n#ifdef PREPASS\nlet geometryAlbedo: vec3f=toLinearSpaceVec3(baseColor.rgb);\n#endif\n#ifdef BLENDMULTIPLYMODE\nlet alpha: f32=input.vColor.a*textureColor.a;baseColor=vec4f(baseColor.rgb*alpha+vec3f(1.0)*(1.0-alpha),baseColor.a);\n#endif\n#include<logDepthFragment>\n#include<fogFragment>(color,baseColor)\n#ifdef IMAGEPROCESSINGPOSTPROCESS\nbaseColor=vec4f(toLinearSpaceVec3(baseColor.rgb),baseColor.a);\n#else\n#ifdef IMAGEPROCESSING\nbaseColor=vec4f(toLinearSpaceVec3(baseColor.rgb),baseColor.a);baseColor=applyImageProcessing(baseColor);\n#endif\n#endif\n#ifdef PREPASS\nlet geometryColor: vec4f=baseColor;if (geometryColor.a<=0.0 && uniforms.geometryZeroAlphaDiscard>0.0) {discard;}\n#ifdef PREPASS_POSITION\nlet geometryPositionW: vec3f=input.vGeometryPositionW;\n#endif\n#ifdef PREPASS_LOCAL_POSITION\nlet geometryPositionL: vec3f=input.vPosition;\n#endif\n#ifdef PREPASS_DEPTH\nlet geometryViewDepth: f32=input.vViewPos.z;\n#endif\n#ifdef PREPASS_NORMALIZED_VIEW_DEPTH\nlet geometryNormalizedViewDepth: f32=input.vNormViewDepth;\n#endif\n#ifdef PREPASS_NORMAL\nlet geometryNormalV: vec3f=normalize(input.vGeometryNormalV);\n#endif\n#ifdef PREPASS_WORLD_NORMAL\nlet geometryNormalW: vec3f=normalize(input.vGeometryNormalW);\n#endif\n#include<geometryRenderingFragment>\n#else\nfragmentOutputs.color=baseColor;\n#endif\n}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [objectIdFunctionsWGSL, prePassDeclarationWGSL, clipPlaneFragmentDeclarationWGSL, imageProcessingDeclarationWGSL, logDepthDeclarationWGSL, helperFunctionsWGSL, imageProcessingFunctionsWGSL, fogFragmentDeclarationWGSL, clipPlaneFragmentWGSL, logDepthFragmentWGSL, fogFragmentWGSL, meshBlendTagFragmentOutputWGSL, geometryRenderingFragmentWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const gpuRenderParticlesPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fibonacci\";\nconst shader = `fn rcp(x: f32)->f32\n{return 1./x;}\nconst GOLDEN_RATIO=1.618033988749895;fn Golden2dSeq(i: u32,n: f32)->vec2f\n{return vec2f(f32(i)/n+(0.5/n),fract(f32(i)*rcp(GOLDEN_RATIO)));}\nfn SampleDiskGolden(i: u32,sampleCount: u32)->vec2f\n{let f=Golden2dSeq(i,f32(sampleCount));return vec2f(sqrt(f.x),TWO_PI*f.y);}\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const fibonacciWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"diffusionProfile\";\nconst shader = `uniform diffusionS: array<vec3f,5>;uniform diffusionD: array<f32,5>;uniform filterRadii: array<f32,5>;\n`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStoreWGSL[name]) {\n    ShaderStore.IncludesShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const diffusionProfileWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctionsWGSL } from \"./ShadersInclude/helperFunctions\";\nimport { fibonacciWGSL } from \"./ShadersInclude/fibonacci\";\nimport { subSurfaceScatteringFunctionsWGSL } from \"./ShadersInclude/subSurfaceScatteringFunctions\";\nimport { diffusionProfileWGSL } from \"./ShadersInclude/diffusionProfile\";\n\nconst name = \"subSurfaceScatteringPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<fibonacci>\n#include<subSurfaceScatteringFunctions>\n#include<diffusionProfile>\nvarying vUV: vec2f;uniform texelSize: vec2f;var textureSamplerSampler: sampler;var textureSampler: texture_2d<f32>;var irradianceSamplerSampler: sampler;var irradianceSampler: texture_2d<f32>;var depthSamplerSampler: sampler;var depthSampler: texture_2d<f32>;var albedoSamplerSampler: sampler;var albedoSampler: texture_2d<f32>;uniform viewportSize: vec2f;uniform metersPerUnit: f32;const LOG2_E=1.4426950408889634;const SSS_PIXELS_PER_SAMPLE=4.;const _SssSampleBudget=40u;\n#define SSS_BILATERAL_FILTER true\nfn EvalBurleyDiffusionProfile(r: f32,S: vec3f)->vec3f\n{let exp_13=exp2(((LOG2_E*(-1.0/3.0))*r)*S); \nlet expSum=exp_13*(1.+exp_13*exp_13); \nreturn (S*rcp(8.*PI))*expSum; }\nfn SampleBurleyDiffusionProfile(u_: f32,rcpS: f32)->vec2f\n{let u=1.-u_; \nlet g=1.+(4.*u)*(2.*u+sqrt(1.+(4.*u)*u));let n=exp2(log2(g)*(-1.0/3.0)); \nlet p=(g*n)*n; \nlet c=1.+p+n; \nlet d=(3./LOG2_E*2.)+(3./LOG2_E)*log2(u); \nlet x=(3./LOG2_E)*log2(c)-d; \nlet rcpExp=((c*c)*c)*rcp((4.*u)*((c*c)+(4.*u)*(4.*u)));let r=x*rcpS;let rcpPdf=(8.*PI*rcpS)*rcpExp; \nreturn vec2f(r,rcpPdf);}\nfn ComputeBilateralWeight(xy2: f32,z_: f32,mmPerUnit: f32,S: vec3f,rcpPdf: f32)->vec3f\n{\n#ifndef SSS_BILATERAL_FILTER\nlet z=0.;\n#else\nlet z=z_;\n#endif\nlet r=sqrt(xy2+(z*mmPerUnit)*(z*mmPerUnit));let area=rcpPdf;\n#ifdef SSS_CLAMP_ARTIFACT\nreturn clamp(EvalBurleyDiffusionProfile(r,S)*area,vec3f(0.0),vec3f(1.0));\n#else\nreturn EvalBurleyDiffusionProfile(r,S)*area;\n#endif\n}\nfn EvaluateSample(i: u32,n: u32,S: vec3f,d: f32,centerPosVS: vec3f,mmPerUnit: f32,pixelsPerMm: f32,\nphase: f32,totalIrradiance: ptr<function,vec3f>,totalWeight: ptr<function,vec3f>)\n{let scale =rcp(f32(n));let offset=rcp(f32(n))*0.5;let sinPhase=sin(phase);let cosPhase=cos(phase);let bdp=SampleBurleyDiffusionProfile(f32(i)*scale+offset,d);let r=bdp.x;let rcpPdf=bdp.y;let phi=SampleDiskGolden(i,n).y;let sinPhi=sin(phi);let cosPhi=cos(phi);let sinPsi=cosPhase*sinPhi+sinPhase*cosPhi; \nlet cosPsi=cosPhase*cosPhi-sinPhase*sinPhi; \nlet vec=r*vec2f(cosPsi,sinPsi);let position=fragmentInputs.vUV+round((pixelsPerMm*r)*vec2(cosPsi,sinPsi))*uniforms.texelSize;let xy2 =r*r;let textureRead=textureSampleLevel(irradianceSampler,irradianceSamplerSampler,position,0.);let viewZ=textureSampleLevel(depthSampler,depthSamplerSampler,position,0.).r;let irradiance =textureRead.rgb;if (testLightingForSSS(textureRead.a))\n{let relZ=viewZ-centerPosVS.z;let weight=ComputeBilateralWeight(xy2,relZ,mmPerUnit,S,rcpPdf);*totalIrradiance+=weight*irradiance;*totalWeight +=weight;}\nelse\n{}}\n#define CUSTOM_FRAGMENT_DEFINITIONS\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let irradianceAndDiffusionProfile =textureSampleLevel(irradianceSampler,irradianceSamplerSampler,fragmentInputs.vUV,0.);let centerIrradiance=irradianceAndDiffusionProfile.rgb;let diffusionProfileIndex=u32(round(irradianceAndDiffusionProfile.a*255.));var centerDepth =0.;let inputColor=textureSampleLevel(textureSampler,textureSamplerSampler,fragmentInputs.vUV,0.);let passedStencilTest=testLightingForSSS(irradianceAndDiffusionProfile.a);if (passedStencilTest)\n{centerDepth=textureSampleLevel(depthSampler,depthSamplerSampler,fragmentInputs.vUV,0.).r;}\nif (!passedStencilTest) { \nfragmentOutputs.color=inputColor;return fragmentOutputs;}\nlet distScale =1.;let S =uniforms.diffusionS[diffusionProfileIndex];let d =uniforms.diffusionD[diffusionProfileIndex];let filterRadius=uniforms.filterRadii[diffusionProfileIndex];let centerPosNDC=fragmentInputs.vUV;let cornerPosNDC=fragmentInputs.vUV+0.5*uniforms.texelSize;let centerPosVS =vec3f(centerPosNDC*uniforms.viewportSize,1.0)*centerDepth; \nlet cornerPosVS =vec3f(cornerPosNDC*uniforms.viewportSize,1.0)*centerDepth; \nlet mmPerUnit =1000.*(uniforms.metersPerUnit*rcp(distScale));let unitsPerMm=rcp(mmPerUnit);let unitsPerPixel=2.*abs(cornerPosVS.x-centerPosVS.x);let pixelsPerMm =rcp(unitsPerPixel)*unitsPerMm;let filterArea =PI*square(filterRadius*pixelsPerMm);let sampleCount =u32(filterArea*rcp(SSS_PIXELS_PER_SAMPLE));let sampleBudget=_SssSampleBudget;let albedo =textureSampleLevel(albedoSampler,albedoSamplerSampler,fragmentInputs.vUV,0.).rgb;if (distScale==0. || sampleCount<1)\n{\n#ifdef DEBUG_SSS_SAMPLES\nlet green=vec3f(0.,1.,0.);fragmentOutputs.color=vec4f(green,1.0);return fragmentOutputs;\n#endif\nfragmentOutputs.color=vec4f(inputColor.rgb+albedo*centerIrradiance,1.0);return fragmentOutputs;}\n#ifdef DEBUG_SSS_SAMPLES\nlet red =vec3f(1.,0.,0.);let blue=vec3f(0.,0.,1.);fragmentOutputs.color=vec4f(mix(blue,red,clamp(f32(sampleCount)/f32(sampleBudget),0.0,1.0)),1.0);return fragmentOutputs;\n#endif\nlet phase=0.;let n=min(sampleCount,sampleBudget);var totalIrradiance=vec3f(0.);var totalWeight =vec3f(0.);for (var i=0u; i<n; i++)\n{EvaluateSample(i,n,S,d,centerPosVS,mmPerUnit,pixelsPerMm,\nphase,&totalIrradiance,&totalWeight);}\ntotalWeight=max(totalWeight,vec3f(HALF_MIN));fragmentOutputs.color=vec4f(inputColor.rgb+albedo*max(totalIrradiance/totalWeight,vec3f(0.0)),1.);}\n`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n    ShaderStore.ShadersStoreWGSL[name] = shader;\n}\nconst includes = [helperFunctionsWGSL, fibonacciWGSL, subSurfaceScatteringFunctionsWGSL, diffusionProfileWGSL];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStoreWGSL[inc.name]) {\n        ShaderStore.IncludesShadersStoreWGSL[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const subSurfaceScatteringPixelShaderWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"fibonacci\";\nconst shader = `#define rcp(x) 1./x\n#define GOLDEN_RATIO 1.618033988749895\nvec2 Golden2dSeq(int i,float n)\n{return vec2(float(i)/n+(0.5/n),fract(float(i)*rcp(GOLDEN_RATIO)));}\nvec2 SampleDiskGolden(int i,int sampleCount)\n{vec2 f=Golden2dSeq(i,float(sampleCount));return vec2(sqrt(f.x),TWO_PI*f.y);}`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const fibonacci = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\nconst name = \"diffusionProfile\";\nconst shader = `uniform vec3 diffusionS[5];uniform float diffusionD[5];uniform float filterRadii[5];`;\n// Sideeffect\nif (!ShaderStore.IncludesShadersStore[name]) {\n    ShaderStore.IncludesShadersStore[name] = shader;\n}\n/** @internal */\nexport const diffusionProfile = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../Engines/shaderStore\";\nimport { helperFunctions } from \"./ShadersInclude/helperFunctions\";\nimport { fibonacci } from \"./ShadersInclude/fibonacci\";\nimport { subSurfaceScatteringFunctions } from \"./ShadersInclude/subSurfaceScatteringFunctions\";\nimport { diffusionProfile } from \"./ShadersInclude/diffusionProfile\";\n\nconst name = \"subSurfaceScatteringPixelShader\";\nconst shader = `#include<helperFunctions>\n#include<fibonacci>\n#include<subSurfaceScatteringFunctions>\n#include<diffusionProfile>\nvarying vec2 vUV;uniform vec2 texelSize;uniform sampler2D textureSampler;uniform sampler2D irradianceSampler;uniform sampler2D depthSampler;uniform sampler2D albedoSampler;uniform vec2 viewportSize;uniform float metersPerUnit;const float LOG2_E=1.4426950408889634;const float SSS_PIXELS_PER_SAMPLE=4.;const int _SssSampleBudget=40;\n#define rcp(x) 1./x\n#define Sq(x) x*x\n#define SSS_BILATERAL_FILTER true\nvec3 EvalBurleyDiffusionProfile(float r,vec3 S)\n{vec3 exp_13=exp2(((LOG2_E*(-1.0/3.0))*r)*S); \nvec3 expSum=exp_13*(1.+exp_13*exp_13); \nreturn (S*rcp((8.*PI)))*expSum; }\nvec2 SampleBurleyDiffusionProfile(float u,float rcpS)\n{u=1.-u; \nfloat g=1.+(4.*u)*(2.*u+sqrt(1.+(4.*u)*u));float n=exp2(log2(g)*(-1.0/3.0)); \nfloat p=(g*n)*n; \nfloat c=1.+p+n; \nfloat d=(3./LOG2_E*2.)+(3./LOG2_E)*log2(u); \nfloat x=(3./LOG2_E)*log2(c)-d; \nfloat rcpExp=((c*c)*c)*rcp(((4.*u)*((c*c)+(4.*u)*(4.*u))));float r=x*rcpS;float rcpPdf=(8.*PI*rcpS)*rcpExp; \nreturn vec2(r,rcpPdf);}\nvec3 ComputeBilateralWeight(float xy2,float z,float mmPerUnit,vec3 S,float rcpPdf)\n{\n#ifndef SSS_BILATERAL_FILTER\nz=0.;\n#endif\nfloat r=sqrt(xy2+(z*mmPerUnit)*(z*mmPerUnit));float area=rcpPdf;\n#if SSS_CLAMP_ARTIFACT\nreturn clamp(EvalBurleyDiffusionProfile(r,S)*area,0.0,1.0);\n#else\nreturn EvalBurleyDiffusionProfile(r,S)*area;\n#endif\n}\nvoid EvaluateSample(int i,int n,vec3 S,float d,vec3 centerPosVS,float mmPerUnit,float pixelsPerMm,\nfloat phase,inout vec3 totalIrradiance,inout vec3 totalWeight)\n{float scale =rcp(float(n));float offset=rcp(float(n))*0.5;float sinPhase,cosPhase;sinPhase=sin(phase);cosPhase=cos(phase);vec2 bdp=SampleBurleyDiffusionProfile(float(i)*scale+offset,d);float r=bdp.x;float rcpPdf=bdp.y;float phi=SampleDiskGolden(i,n).y;float sinPhi,cosPhi;sinPhi=sin(phi);cosPhi=cos(phi);float sinPsi=cosPhase*sinPhi+sinPhase*cosPhi; \nfloat cosPsi=cosPhase*cosPhi-sinPhase*sinPhi; \nvec2 vec=r*vec2(cosPsi,sinPsi);vec2 position; \nfloat xy2;position=vUV+round((pixelsPerMm*r)*vec2(cosPsi,sinPsi))*texelSize;xy2 =r*r;vec4 textureSample=texture2D(irradianceSampler,position);float viewZ=texture2D(depthSampler,position).r;vec3 irradiance =textureSample.rgb;if (testLightingForSSS(textureSample.a))\n{float relZ=viewZ-centerPosVS.z;vec3 weight=ComputeBilateralWeight(xy2,relZ,mmPerUnit,S,rcpPdf);totalIrradiance+=weight*irradiance;totalWeight +=weight;}\nelse\n{}}\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) \n{vec4 irradianceAndDiffusionProfile =texture2D(irradianceSampler,vUV);vec3 centerIrradiance=irradianceAndDiffusionProfile.rgb;int diffusionProfileIndex=int(round(irradianceAndDiffusionProfile.a*255.));float centerDepth =0.;vec4 inputColor=texture2D(textureSampler,vUV);bool passedStencilTest=testLightingForSSS(irradianceAndDiffusionProfile.a);if (passedStencilTest)\n{centerDepth=texture2D(depthSampler,vUV).r;}\nif (!passedStencilTest) { \ngl_FragColor=inputColor;return;}\nfloat distScale =1.;vec3 S =diffusionS[diffusionProfileIndex];float d =diffusionD[diffusionProfileIndex];float filterRadius=filterRadii[diffusionProfileIndex];vec2 centerPosNDC=vUV;vec2 cornerPosNDC=vUV+0.5*texelSize;vec3 centerPosVS =vec3(centerPosNDC*viewportSize,1.0)*centerDepth; \nvec3 cornerPosVS =vec3(cornerPosNDC*viewportSize,1.0)*centerDepth; \nfloat mmPerUnit =1000.*(metersPerUnit*rcp(distScale));float unitsPerMm=rcp(mmPerUnit);float unitsPerPixel=2.*abs(cornerPosVS.x-centerPosVS.x);float pixelsPerMm =rcp(unitsPerPixel)*unitsPerMm;float filterArea =PI*Sq(filterRadius*pixelsPerMm);int sampleCount =int(filterArea*rcp(SSS_PIXELS_PER_SAMPLE));int sampleBudget=_SssSampleBudget;int texturingMode=0;vec3 albedo =texture2D(albedoSampler,vUV).rgb;if (distScale==0. || sampleCount<1)\n{\n#ifdef DEBUG_SSS_SAMPLES\nvec3 green=vec3(0.,1.,0.);gl_FragColor=vec4(green,1.0);return;\n#endif\ngl_FragColor=vec4(inputColor.rgb+albedo*centerIrradiance,1.0);return;}\n#ifdef DEBUG_SSS_SAMPLES\nvec3 red =vec3(1.,0.,0.);vec3 blue=vec3(0.,0.,1.);gl_FragColor=vec4(mix(blue,red,clamp(float(sampleCount)/float(sampleBudget),0.0,1.0)),1.0);return;\n#endif\nfloat phase=0.;int n=min(sampleCount,sampleBudget);vec3 centerWeight =vec3(0.); \nvec3 totalIrradiance=vec3(0.);vec3 totalWeight =vec3(0.);for (int i=0; i<n; i++)\n{EvaluateSample(i,n,S,d,centerPosVS,mmPerUnit,pixelsPerMm,\nphase,totalIrradiance,totalWeight);}\ntotalWeight=max(totalWeight,HALF_MIN);gl_FragColor=vec4(inputColor.rgb+albedo*max(totalIrradiance/totalWeight,vec3(0.0)),1.);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n    ShaderStore.ShadersStore[name] = shader;\n}\nconst includes = [helperFunctions, fibonacci, subSurfaceScatteringFunctions, diffusionProfile];\nfor (const inc of includes) {\n    if (!ShaderStore.IncludesShadersStore[inc.name]) {\n        ShaderStore.IncludesShadersStore[inc.name] = inc.shader;\n    }\n}\n\n/** @internal */\nexport const subSurfaceScatteringPixelShader = { name, shader };\n"],"names":["Symbol","metadata","Object","defineProperty","configurable","writable","value","Constants","AUTOSAMPLERSUFFIX","DISABLEUA","ALPHA_DISABLE","ALPHA_ADD","ALPHA_COMBINE","ALPHA_SUBTRACT","ALPHA_MULTIPLY","ALPHA_MAXIMIZED","ALPHA_ONEONE","ALPHA_PREMULTIPLIED","ALPHA_PREMULTIPLIED_PORTERDUFF","ALPHA_INTERPOLATE","ALPHA_SCREENMODE","ALPHA_ONEONE_ONEONE","ALPHA_ALPHATOCOLOR","ALPHA_REVERSEONEMINUS","ALPHA_SRC_DSTONEMINUSSRCALPHA","ALPHA_ONEONE_ONEZERO","ALPHA_EXCLUSION","ALPHA_LAYER_ACCUMULATE","ALPHA_MIN","ALPHA_MAX","ALPHA_DUAL_SRC0_ADD_SRC1xDST","ALPHA_REPLACE_COLOR","ALPHA_EQUATION_ADD","ALPHA_EQUATION_SUBSTRACT","ALPHA_EQUATION_REVERSE_SUBTRACT","ALPHA_EQUATION_MAX","ALPHA_EQUATION_MIN","ALPHA_EQUATION_DARKEN","DELAYLOADSTATE_NONE","DELAYLOADSTATE_LOADED","DELAYLOADSTATE_LOADING","DELAYLOADSTATE_NOTLOADED","NEVER","ALWAYS","LESS","EQUAL","LEQUAL","GREATER","GEQUAL","NOTEQUAL","KEEP","ZERO","REPLACE","INCR","DECR","INVERT","INCR_WRAP","DECR_WRAP","TEXTURE_CLAMP_ADDRESSMODE","TEXTURE_WRAP_ADDRESSMODE","TEXTURE_MIRROR_ADDRESSMODE","TEXTURE_REPETITION_NONE","TEXTURE_REPETITION_NOISE_BLEND","TEXTURE_REPETITION_HEX_TILING","TEXTURE_REPETITION_TILE_RANDOMIZATION","TEXTURE_REPETITION_VORONOI_BOMBING","TEXTURE_CREATIONFLAG_STORAGE","TEXTUREFORMAT_ALPHA","TEXTUREFORMAT_LUMINANCE","TEXTUREFORMAT_LUMINANCE_ALPHA","TEXTUREFORMAT_RGB","TEXTUREFORMAT_RGBA","TEXTUREFORMAT_RED","TEXTUREFORMAT_R","TEXTUREFORMAT_R16_UNORM","TEXTUREFORMAT_RG16_UNORM","TEXTUREFORMAT_RGB16_UNORM","TEXTUREFORMAT_RGBA16_UNORM","TEXTUREFORMAT_R16_SNORM","TEXTUREFORMAT_RG16_SNORM","TEXTUREFORMAT_RGB16_SNORM","TEXTUREFORMAT_RGBA16_SNORM","TEXTUREFORMAT_RG","TEXTUREFORMAT_RED_INTEGER","TEXTUREFORMAT_R_INTEGER","TEXTUREFORMAT_RG_INTEGER","TEXTUREFORMAT_RGB_INTEGER","TEXTUREFORMAT_RGBA_INTEGER","TEXTUREFORMAT_BGRA","TEXTUREFORMAT_DEPTH24_STENCIL8","TEXTUREFORMAT_DEPTH32_FLOAT","TEXTUREFORMAT_DEPTH16","TEXTUREFORMAT_DEPTH24","TEXTUREFORMAT_DEPTH24UNORM_STENCIL8","TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8","TEXTUREFORMAT_STENCIL8","TEXTUREFORMAT_UNDEFINED","TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM","TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT","TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1","TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT","TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x4","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_5x5","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x5","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_6x6","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x5","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x6","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_8x8","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x5","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x6","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x8","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_10x10","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x10","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_12x12","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR","TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL","TEXTUREFORMAT_COMPRESSED_RGB8_ETC2","TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2","TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2","TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2","TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC","TEXTURETYPE_UNSIGNED_BYTE","TEXTURETYPE_UNSIGNED_INT","TEXTURETYPE_FLOAT","TEXTURETYPE_HALF_FLOAT","TEXTURETYPE_BYTE","TEXTURETYPE_SHORT","TEXTURETYPE_UNSIGNED_SHORT","TEXTURETYPE_INT","TEXTURETYPE_UNSIGNED_INTEGER","TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4","TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1","TEXTURETYPE_UNSIGNED_SHORT_5_6_5","TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV","TEXTURETYPE_UNSIGNED_INT_24_8","TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV","TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV","TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV","TEXTURETYPE_UNDEFINED","TEXTURE_2D","TEXTURE_2D_ARRAY","TEXTURE_CUBE_MAP","TEXTURE_CUBE_MAP_ARRAY","TEXTURE_3D","TEXTURE_NEAREST_SAMPLINGMODE","TEXTURE_NEAREST_NEAREST","TEXTURE_BILINEAR_SAMPLINGMODE","TEXTURE_LINEAR_LINEAR","TEXTURE_TRILINEAR_SAMPLINGMODE","TEXTURE_LINEAR_LINEAR_MIPLINEAR","TEXTURE_NEAREST_NEAREST_MIPNEAREST","TEXTURE_NEAREST_LINEAR_MIPNEAREST","TEXTURE_NEAREST_LINEAR_MIPLINEAR","TEXTURE_NEAREST_LINEAR","TEXTURE_NEAREST_NEAREST_MIPLINEAR","TEXTURE_LINEAR_NEAREST_MIPNEAREST","TEXTURE_LINEAR_NEAREST_MIPLINEAR","TEXTURE_LINEAR_LINEAR_MIPNEAREST","TEXTURE_LINEAR_NEAREST","TEXTURE_EXPLICIT_MODE","TEXTURE_SPHERICAL_MODE","TEXTURE_PLANAR_MODE","TEXTURE_CUBIC_MODE","TEXTURE_PROJECTION_MODE","TEXTURE_SKYBOX_MODE","TEXTURE_INVCUBIC_MODE","TEXTURE_EQUIRECTANGULAR_MODE","TEXTURE_FIXED_EQUIRECTANGULAR_MODE","TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE","TEXTURE_FILTERING_QUALITY_OFFLINE","TEXTURE_FILTERING_QUALITY_HIGH","TEXTURE_FILTERING_QUALITY_MEDIUM","TEXTURE_FILTERING_QUALITY_LOW","SCALEMODE_FLOOR","SCALEMODE_NEAREST","SCALEMODE_CEILING","MATERIAL_TextureDirtyFlag","MATERIAL_LightDirtyFlag","MATERIAL_FresnelDirtyFlag","MATERIAL_AttributesDirtyFlag","MATERIAL_MiscDirtyFlag","MATERIAL_PrePassDirtyFlag","MATERIAL_ImageProcessingDirtyFlag","MATERIAL_AllDirtyFlag","MATERIAL_TriangleFillMode","MATERIAL_WireFrameFillMode","MATERIAL_PointFillMode","MATERIAL_PointListDrawMode","MATERIAL_LineListDrawMode","MATERIAL_LineLoopDrawMode","MATERIAL_LineStripDrawMode","MATERIAL_TriangleStripDrawMode","MATERIAL_TriangleFanDrawMode","MATERIAL_ClockWiseSideOrientation","MATERIAL_CounterClockWiseSideOrientation","MATERIAL_DIFFUSE_MODEL_E_OREN_NAYAR","MATERIAL_DIFFUSE_MODEL_BURLEY","MATERIAL_DIFFUSE_MODEL_LAMBERT","MATERIAL_DIFFUSE_MODEL_LEGACY","MATERIAL_DIELECTRIC_SPECULAR_MODEL_GLTF","MATERIAL_DIELECTRIC_SPECULAR_MODEL_OPENPBR","MATERIAL_CONDUCTOR_SPECULAR_MODEL_GLTF","MATERIAL_CONDUCTOR_SPECULAR_MODEL_OPENPBR","ACTION_NothingTrigger","ACTION_OnPickTrigger","ACTION_OnLeftPickTrigger","ACTION_OnRightPickTrigger","ACTION_OnCenterPickTrigger","ACTION_OnPickDownTrigger","ACTION_OnDoublePickTrigger","ACTION_OnPickUpTrigger","ACTION_OnPickOutTrigger","ACTION_OnLongPressTrigger","ACTION_OnPointerOverTrigger","ACTION_OnPointerOutTrigger","ACTION_OnEveryFrameTrigger","ACTION_OnIntersectionEnterTrigger","ACTION_OnIntersectionExitTrigger","ACTION_OnKeyDownTrigger","ACTION_OnKeyUpTrigger","PARTICLES_BILLBOARDMODE_Y","PARTICLES_BILLBOARDMODE_ALL","PARTICLES_BILLBOARDMODE_STRETCHED","PARTICLES_BILLBOARDMODE_STRETCHED_LOCAL","MESHES_CULLINGSTRATEGY_STANDARD","MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY","MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION","MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY","SCENELOADER_NO_LOGGING","SCENELOADER_MINIMAL_LOGGING","SCENELOADER_SUMMARY_LOGGING","SCENELOADER_DETAILED_LOGGING","PREPASS_IRRADIANCE_LEGACY_TEXTURE_TYPE","PREPASS_POSITION_TEXTURE_TYPE","PREPASS_VELOCITY_TEXTURE_TYPE","PREPASS_REFLECTIVITY_TEXTURE_TYPE","PREPASS_COLOR_TEXTURE_TYPE","PREPASS_DEPTH_TEXTURE_TYPE","PREPASS_NORMAL_TEXTURE_TYPE","PREPASS_ALBEDO_SQRT_TEXTURE_TYPE","PREPASS_WORLD_NORMAL_TEXTURE_TYPE","PREPASS_LOCAL_POSITION_TEXTURE_TYPE","PREPASS_SCREENSPACE_DEPTH_TEXTURE_TYPE","PREPASS_VELOCITY_LINEAR_TEXTURE_TYPE","PREPASS_ALBEDO_TEXTURE_TYPE","PREPASS_NORMALIZED_VIEW_DEPTH_TEXTURE_TYPE","PREPASS_IRRADIANCE_TEXTURE_TYPE","PREPASS_OBJECT_ID_TEXTURE_TYPE","PREPASS_MESH_BLEND_TAG_TEXTURE_TYPE","BUFFER_CREATIONFLAG_READ","BUFFER_CREATIONFLAG_WRITE","BUFFER_CREATIONFLAG_READWRITE","BUFFER_CREATIONFLAG_UNIFORM","BUFFER_CREATIONFLAG_VERTEX","BUFFER_CREATIONFLAG_INDEX","BUFFER_CREATIONFLAG_STORAGE","BUFFER_CREATIONFLAG_INDIRECT","RENDERPASS_MAIN","INPUT_ALT_KEY","INPUT_CTRL_KEY","INPUT_META_KEY1","INPUT_META_KEY2","INPUT_META_KEY3","INPUT_SHIFT_KEY","SNAPSHOTRENDERING_STANDARD","SNAPSHOTRENDERING_FAST","PERSPECTIVE_CAMERA","ORTHOGRAPHIC_CAMERA","FOVMODE_VERTICAL_FIXED","FOVMODE_HORIZONTAL_FIXED","RIG_MODE_NONE","RIG_MODE_STEREOSCOPIC_ANAGLYPH","RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL","RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED","RIG_MODE_STEREOSCOPIC_OVERUNDER","RIG_MODE_STEREOSCOPIC_INTERLACED","RIG_MODE_VR","RIG_MODE_CUSTOM","MAX_SUPPORTED_UV_SETS","GL_ALPHA_EQUATION_ADD","GL_ALPHA_EQUATION_MIN","GL_ALPHA_EQUATION_MAX","GL_ALPHA_EQUATION_SUBTRACT","GL_ALPHA_EQUATION_REVERSE_SUBTRACT","GL_ALPHA_FUNCTION_SRC","GL_ALPHA_FUNCTION_ONE_MINUS_SRC_COLOR","GL_ALPHA_FUNCTION_SRC_ALPHA","GL_ALPHA_FUNCTION_ONE_MINUS_SRC_ALPHA","GL_ALPHA_FUNCTION_DST_ALPHA","GL_ALPHA_FUNCTION_ONE_MINUS_DST_ALPHA","GL_ALPHA_FUNCTION_DST_COLOR","GL_ALPHA_FUNCTION_ONE_MINUS_DST_COLOR","GL_ALPHA_FUNCTION_SRC_ALPHA_SATURATED","GL_ALPHA_FUNCTION_CONSTANT_COLOR","GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_COLOR","GL_ALPHA_FUNCTION_CONSTANT_ALPHA","GL_ALPHA_FUNCTION_ONE_MINUS_CONSTANT_ALPHA","GL_ALPHA_FUNCTION_SRC1_COLOR","GL_ALPHA_FUNCTION_ONE_MINUS_SRC1_COLOR","GL_ALPHA_FUNCTION_SRC1_ALPHA","GL_ALPHA_FUNCTION_ONE_MINUS_SRC1_ALPHA","SnippetUrl","FOGMODE_NONE","FOGMODE_EXP","FOGMODE_EXP2","FOGMODE_LINEAR","BYTE","UNSIGNED_BYTE","SHORT","UNSIGNED_SHORT","INT","UNSIGNED_INT","FLOAT","HALF_FLOAT","PositionKind","NormalKind","TangentKind","UVKind","UV2Kind","UV3Kind","UV4Kind","UV5Kind","UV6Kind","ColorKind","ColorInstanceKind","MatricesIndicesKind","MatricesWeightsKind","MatricesIndicesExtraKind","MatricesWeightsExtraKind","ANIMATIONTYPE_FLOAT","ANIMATIONTYPE_VECTOR3","ANIMATIONTYPE_QUATERNION","ANIMATIONTYPE_MATRIX","ANIMATIONTYPE_COLOR3","ANIMATIONTYPE_COLOR4","ANIMATIONTYPE_VECTOR2","ANIMATIONTYPE_SIZE","ShadowMinZ","ShadowMaxZ","OUTLINELAYER_SAMPLING_TRIDIRECTIONAL","this","actions","isRecursive","disposeWhenUnowned","HasTriggers","t","AbstractActionManager","Triggers","prototype","hasOwnProperty","call","HasPickTriggers","tAsInt","parseInt","trigger","IsWeakRefSupported","WeakRef","EventState","mask","skipNextObservers","target","currentTarget","initialize","Observer","constructor","callback","scope","_willBeUnregistered","unregisterOnNextCall","_remove","remove","defer","Observable","FromPromise","promise","observable","then","ret","notifyObservers","catch","onErrorObservable","err","observers","_observers","onObserverAdded","notifyIfTriggered","Array","_numObserversMarkedAsDeleted","_hasNotified","_onObserverAdded","insertFirst","unregisterOnFirstCall","observer","unshift","push","notifyObserver","_lastNotifiedValue","observableWeakRef","deref","addOnce","add","undefined","indexOf","removeCallback","index","length","_deferUnregister","setTimeout","updateCounter","splice","makeObserverTopPriority","makeObserverBottomPriority","eventData","state","_eventState","lastReturnValue","userInfo","obs","apply","clear","o","pop","cleanLastNotifiedState","clone","result","slice","hasSpecificMask","ToGammaSpace","ToLinearSpace","PHI","Math","sqrt","BuildArray","size","itemBuilder","a","i","observedArrayFunctions","unObserveFunctions","name","oldFunction","object","functionName","newFunction","previousLength","returnValue","arguments","next","previous","ObserveArrayFunction","array","unObserveFunction","PerformanceConfigurator","SetMatrixPrecision","use64bits","MatrixTrackPrecisionChange","MatrixUse64Bits","MatrixTrackedMatrices","m","matrix","values","_m","MatrixCurrentType","Float32Array","EngineStore","Instances","LastCreatedScene","_LastCreatedScene","ExtractAsInt$1","toString","replace","WithinEpsilon","b","epsilon","abs","OutsideRange","num","min","max","RandomRange","random","Lerp","amount","start","end","LerpAngle","Repeat","Clamp$1","InverseLerp","Hermite","value1","tangent1","value2","tangent2","squared","cubed","Hermite1stDerivative","time","t2","angle","PI","floor","ToHex","str","toUpperCase","ILog2","log2","NaN","n","Normalize","Denormalize","normalized","DeltaAngle","current","PingPong","tx","SmoothStep$1","from","to","MoveTowards","maxDelta","sign","MoveTowardsAngle","RangeToPercent","number","PercentToRange","percent","HighestCommonFactor","r","OnEnginesDisposedObservable","UseFallbackTexture","m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m10","m11","m12","m13","m14","m15","mat","asArray","MarkAsDirty","updateFlag","MatrixManagement","_UpdateFlagSeed","IdentityMatrixToRef","SetMatrixData","TranslationMatrixToRef","x","y","z","ScalingMatrixToRef","output","offset","otherM","tm0","tm1","tm2","tm3","tm4","tm5","tm6","tm7","tm8","tm9","tm10","tm11","tm12","tm13","tm14","tm15","om0","om1","om2","om3","om4","om5","om6","om7","om8","om9","om10","om11","om12","om13","om14","om15","MultiplyMatricesToRef","MultiplyMatricesToArray","CopyMatrixToRef","CopyMatrixToArray","source","InvertMatrixToRef","InvertMatrixToArray","m00","m01","m02","m03","m20","m21","m22","m23","m30","m31","m32","m33","det_22_33","det_21_33","det_21_32","det_20_33","det_20_32","det_20_31","cofact_00","cofact_01","cofact_02","cofact_03","det","detInv","det_12_33","det_11_33","det_11_32","det_10_33","det_10_32","det_10_31","det_12_23","det_11_23","det_11_22","det_10_23","det_10_22","det_10_21","cofact_10","cofact_11","cofact_12","cofact_13","cofact_20","cofact_21","cofact_22","cofact_23","cofact_30","cofact_31","cofact_32","cofact_33","RegisteredTypes","RegisterClass","className","type","GetClass","fqdn","GetClassName","obj","key","includes","ExtractAsInt","Vector2","getClassName","hash","toArray","FromArrayToRef","copyFrom","copyFromFloats","v","otherVector","addInPlace","addInPlaceFromFloats","addVector3","subtract","subtractInPlace","multiplyInPlace","multiply","multiplyByFloats","divide","minimizeInPlace","other","minimizeInPlaceFromFloats","maximizeInPlace","maximizeInPlaceFromFloats","subtractFromFloats","negate","negateInPlace","negateToRef","scaleInPlace","scale","equals","Epsilon","fract","fractToRef","rotateToRef","cos","sin","lengthSquared","normalizeFromLength","len","normalizeToNew","normalizeToRef","scaleToRef","dot","ref","ZeroReadOnly","_ZeroReadOnly","FromArray","CatmullRom","value3","value4","ClampToRef","Clamp","part1","part2","part3","part4","Hermite1stDerivativeToRef","LerpToRef","Dot","left","right","vector","NormalizeToRef","Transform","transformation","TransformToRef","PointInTriangle","p","p0","p1","p2","s","Distance","DistanceSquared","Center","CenterToRef","DistanceOfPointFromSegment","segB","l2","segA","proj","_V8PerformanceHack","Zero","_x","_isDirty","_y","_z","Vector3","toQuaternion","Quaternion","RotationYawPitchRoll","subtractToRef","subtractFromFloatsToRef","getNormalToRef","radius","theta","acos","phi","set","vx","vy","vz","qy","qz","ty","qx","qw","tz","q","applyRotationQuaternionToRef","projectOnPlane","plane","origin","projectOnPlaneToRef","normal","d","V","normalize","denom","setAll","Infinity","scaledV","addToRef","equalsWithEpsilon","equalsToFloats","absX","absY","absZ","isNonUniform","hasAZeroComponent","reorderInPlace","order","toLowerCase","tem","MathTmp","quaternion","toRotationMatrix","TransformCoordinatesToRef","Matrix","rotateByQuaternionAroundPointToRef","point","rotateByQuaternionToRef","cross","CrossToRef","GetClipFactor","vector0","vector1","axis","d0","GetAngleBetweenVectors","v0","v1","isNaN","GetAngleBetweenVectorsOnPlane","vNormal","forward","NormalizeRadians","atan2","PitchYawRollToMoveBetweenPointsToRef","diff","TmpVectors","pow","SlerpToRef","slerp","vector0Dir","vector1Dir","vector0Length","vector1Length","scale0","scale1","omega","invSin","goal","lerpTime","deltaTime","FromFloatArray","FromFloatArrayToRef","FromFloatsToRef","One","Up","UpReadOnly","_UpReadOnly","DownReadOnly","_DownReadOnly","RightReadOnly","_RightReadOnly","LeftReadOnly","_LeftReadOnly","LeftHandedForwardReadOnly","_LeftHandedForwardReadOnly","RightHandedForwardReadOnly","_RightHandedForwardReadOnly","LeftHandedBackwardReadOnly","_LeftHandedBackwardReadOnly","RightHandedBackwardReadOnly","_RightHandedBackwardReadOnly","OneReadOnly","_OneReadOnly","Down","Forward","rightHandedSystem","Backward","Right","Left","Random","RandomToRef","TransformCoordinatesFromFloatsToRef","rx","ry","rz","rw","TransformNormalToRef","TransformNormalFromFloatsToRef","CheckExtends","Cross","Project","world","transform","viewport","ProjectToRef","_a","cw","width","ch","height","cx","cy","viewportMatrix","isNDCHalfZRange","LastCreatedEngine","zScale","zOffset","multiplyToRef","Reflect","inDirection","ReflectToRef","tmp","viewportWidth","viewportHeight","Unproject","IdentityReadOnly","view","projection","UnprojectToRef","UnprojectFloatsToRef","screenSource","sourceX","sourceZ","Minimize","Maximize","ProjectOnTriangleToRef","p1p0","p2p0","p2p1","p1p0L","p2p0L","p2p1L","vectorp0","nl","l","cosA","projVector","v2","projP","s0","s1","s2","edge","e0","e1","tmp2","tmp3","e0proj","e0projL","cosG","triProj","RotationFromAxis","axis1","axis3","rotation","RotationFromAxisToRef","axis2","quat","RotationQuaternionFromAxisToRef","w","_w","Vector4","divideToRef","reference","toVector3","TransformCoordinates","TransformNormal","otherQuaternion","isApprox","q1","_other","ReferenceError","_result","divideInPlace","floorToRef","conjugateInPlace","invert","conjugate","toEulerAngles","toEulerAnglesToRef","zAxisY","limit","sqw","sqz","sqx","sqy","asin","toAlphaBetaGammaToRef","sinHalfBeta","gamma","gammaPlusAlpha","gammaMinusAlpha","alpha","beta","FromQuaternionToRef","fromRotationMatrix","FromRotationMatrixToRef","toAxisAngle","toAxisAngleToRef","sinHalfAngle","cosHalfAngle","FromRotationMatrix","data","trace","AreClose","quat0","quat1","SmoothToRef","Inverse","InverseToRef","Identity","IsIdentity","RotationAxis","RotationAxisToRef","sinByLength","FromEulerAngles","RotationYawPitchRollToRef","FromEulerAnglesToRef","FromEulerVector","vec","FromUnitVectorsToRef","vecFrom","vecTo","yaw","pitch","roll","halfRoll","halfPitch","halfYaw","sinRoll","cosRoll","sinPitch","cosPitch","sinYaw","cosYaw","RotationAlphaBetaGamma","RotationAlphaBetaGammaToRef","halfGammaPlusAlpha","halfGammaMinusAlpha","halfBeta","RotationQuaternionFromAxis","rotMat","FromLookDirectionLH","up","FromLookDirectionLHToRef","FromLookDirectionRH","FromLookDirectionRHToRef","LookDirectionRHToRef","num2","num3","num4","flag","num5","num6","Use64Bits","markAsUpdated","_isIdentity","_isIdentity3x2","_isIdentityDirty","_isIdentity3x2Dirty","_updateIdentityStatus","isIdentity","isIdentityDirty","isIdentity3x2","isIdentity3x2Dirty","isIdentityAs3x2","determinant","floats","reset","FromValuesToRef","resultM","addToSelf","args","invertToRef","IdentityToRef","addAtIndex","multiplyAtIndex","setTranslationFromFloats","addTranslationFromFloats","setTranslation","vector3","removeRotationAndScaling","copyToArray","multiplyToArray","om","node","rotationQuaternion","decompose","scaling","position","translation","preserveScalingNode","useAbsoluteScaling","signX","absoluteScaling","signY","signZ","sx","sy","sz","rowVector","setRowFromFloats","row","transpose","TransposeToRef","transposeToRef","scaleAndAddToRef","getRotationMatrix","toggleModelMatrixHandInPlace","toggleProjectionMatrixHandInPlace","_convertProjectionToHalfZRangeInPlace","mtxConvertNDCToHalfZRange","FromFloat32ArrayToRefScaled","_IdentityReadOnly","initialM11","initialM12","initialM13","initialM14","initialM21","initialM22","initialM23","initialM24","initialM31","initialM32","initialM33","initialM34","initialM41","initialM42","initialM43","initialM44","FromValues","Compose","ComposeToRef","x2","y2","z2","xx","xy","xz","yy","yz","zz","wx","wy","wz","identity","zero","RotationX","RotationXToRef","Invert","c","RotationY","RotationYToRef","RotationZ","RotationZToRef","c1","RotationAlignToRef","useYAxisForCoplanar","k","Scaling","ScalingToRef","Translation","TranslationToRef","startValue","gradient","endValue","startM","endM","DecomposeLerp","DecomposeLerpToRef","startScale","startRotation","startTranslation","endScale","endRotation","endTranslation","resultScale","resultRotation","resultTranslation","LookAtLH","eye","LookAtLHToRef","xAxis","yAxis","zAxis","xSquareLength","ex","ey","ez","LookAtRH","LookAtRHToRef","LookDirectionLH","LookDirectionLHToRef","back","LookDirectionRH","OrthoLH","znear","zfar","halfZRange","OrthoLHToRef","OrthoOffCenterLH","bottom","top","OrthoOffCenterLHToRef","i0","i1","ObliqueOffCenterLHToRef","distance","OrthoOffCenterRH","OrthoOffCenterRHToRef","ObliqueOffCenterRHToRef","PerspectiveLH","projectionPlaneTilt","rot","tan","PerspectiveFovLH","aspect","reverseDepthBufferMode","PerspectiveFovLHToRef","fov","isVerticalFovFixed","f","PerspectiveFovReverseLHToRef","PerspectiveFovRH","PerspectiveFovRHToRef","PerspectiveFovReverseRHToRef","GetFinalMatrix","zmin","zmax","GetAsMatrix2x2","arr","GetAsMatrix3x3","Transpose","mm","rm0","rm1","rm2","rm3","rm4","rm5","rm6","rm7","rm8","rm9","rm10","rm11","rm12","rm13","rm14","rm15","rm","Reflection","ReflectionToRef","temp","temp2","temp3","FromXYZAxesToRef","xaxis","yaxis","zaxis","zw","zx","yw","xw","BuildTuple","_Registered","_Registered$a7","defineProperties","dimension","rank","ColorChannelToLinearSpace","color","ColorChannelToLinearSpaceExact","ColorChannelToGammaSpace","ColorChannelToGammaSpaceExact","Color3","g","toColor4","Color4","toLuminance","otherColor","clampToRef","toHexString","intR","round","intG","intB","fromHexString","hex","substring","toHSVToRef","h","dm","toLinearSpace","exact","convertedColor","toGammaSpace","HSVtoRGBToRef","hue","chroma","saturation","FromHSV","FromHexString","FromInts","Black","Red","Green","Blue","BlackReadOnly","_BlackReadOnly","White","Purple","Magenta","Yellow","Gray","Teal","fromArray","returnAsColor3","intA","color3","colors","count","colors4","newIndex","TmpColors","_Registered$a6","Action","triggerOptions","condition","onBeforeExecuteObservable","parameter","_triggerParameter","_nextActiveAction","_condition","_prepare","setTriggerParameter","_evaluateConditionForCurrentFrame","_evaluationId","currentRenderId","_currentResult","isValid","_executeCurrent","evt","execute","skipToNextActiveAction","_child","_actionManager","action","_getProperty","propertyPath","_getEffectiveTarget","serialize","_serialize","parent","serializationObject","children","properties","serializedAction","serializedCondition","_SerializeValueAsString","_GetTargetProperty","targetType","_isMesh","_isLight","_isCamera","_isMaterial","_isScene","_Registered$a5","ActionEvent","additionalData","pointerX","pointerY","meshUnderPointer","sourceEvent","scene","getScene","CreateNewFromSprite","prim","pointerPos","Condition","actionManager","ValueCondition","IsEqual","_IsEqual","IsDifferent","_IsDifferent","IsGreater","_IsGreater","IsLesser","_IsLesser","super","operator","_target","_effectiveTarget","_property","check","GetOperatorName","PredicateCondition","predicate","StateCondition","_Registered$a4","_CheckLimit","message","entry","Logger","_LogLimitOutputs","MessageLimitReached","level","_AddLogEntry","_LogCache","OnNewCacheEntry","padStr","date","Date","getHours","getMinutes","getSeconds","msg","isArray","formattedMessage","_FormatMessage","_Levels","optionals","logFunc","_GenerateLimitMessage","LogCache","ClearLogCache","errorsCount","LogLevels","Log","_LogDisabled","Warn","Error","levels","MessageLogLevel","WarningLogLevel","ErrorLogLevel","_LogEnabled","bind","NoneLogLevel","AllLogLevel","console","log","warn","error","SwitchBooleanAction","SetStateAction","SetValueAction","markAsDirty","IncrementValueAction","PlayAnimationAction","loop","beginAnimation","String","StopAnimationAction","stopAnimation","DoNothingAction","CombineAction","enableChildrenConditions","combine","ExecuteCodeAction","func","SetParentAction","_parent","invertParentWorldMatrix","getWorldMatrix","_Registered$a3","CloneValue","destinationObject","shallowCopyValues","assign","DeepCopier","destination","doNotCopyList","mustCopyList","props","propNames","prop","getPrototypeOf","GetAllPropertyNames","endsWith","sourceValue","typeOfSourceValue","Uint8Array","clonedValue","e","WarnedMap","_WarnImport","warnOnce","_StubWarnedMap","_MissingSideEffect","methodName","stub","_IsSideEffectImplemented","fn","__isSideEffectStub","_MissingSideEffectProperty","propName","get","enumerable","ActionManager","_scene","actionManagers","dispose","sceneIndex","ownerMeshes","filter","ownerMesh","hasSpecificTriggers","triggers","hasSpecificTriggers2","triggerA","triggerB","hasSpecificTrigger","parameterPredicate","getTriggerParameter","hasPointerTriggers","OnPickTrigger","OnPointerOutTrigger","hasPickTriggers","OnPickUpTrigger","OnEveryFrameTrigger","_registeredActions","processTrigger","OnKeyDownTrigger","keyCode","lowerCase","unicode","charCode","fromCharCode","split","root","triggerObject","GetTriggerName","Node","DeepCopy","mesh","_meshId","id","RegisterAction","RegisterCondition","RegisterDirectActions","parseParameter","parseFloat","floatValue","effectiveTarget","traverse","parsedAction","combineArray","detached","parameters","j","NothingTrigger","getMaterialByName","getNodeByName","getSoundByName","param","newAction","params","internalClassType","instantiate","nothing","registerAction","parsedActions","triggerParams","getMeshByName","getMeshById","OnLeftPickTrigger","OnRightPickTrigger","OnCenterPickTrigger","OnPickDownTrigger","OnDoublePickTrigger","OnPickOutTrigger","OnLongPressTrigger","OnPointerOverTrigger","OnIntersectionEnterTrigger","OnIntersectionExitTrigger","PlaySoundAction","_sound","sound","play","StopSoundAction","stop","_Registered$a2","__rest","getOwnPropertySymbols","propertyIsEnumerable","__esDecorate","ctor","descriptorIn","decorators","contextIn","initializers","extraInitializers","accept","kind","descriptor","getOwnPropertyDescriptor","done","context","access","addInitializer","TypeError","_","init","thisArg","useValue","__awaiter","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","rejected","__classPrivateFieldGet","receiver","has","__classPrivateFieldSet","create","SuppressedError","AnimationRange","__bjsSerializableKey","_mergedStoreCache","WeakMap","HasOwn","MetadataSymbol","metadataSymbol","GetMetadataSymbol","GetDirectStoreFromMetadata","GetConstructor","cached","chain","meta","initialStore","property","store","generateSerializableMember","sourceName","_value","propertyKey","targetKey","setCallback","generateExpandMember","ApplyNativeOverride","originalMethod","resolveNative","wrapper","_native","resolvedFunc","nativeFunc","addAccessorsForMaterialProperty","sourceKey","_b","nativeOverride","jsFunc","AndOrNotEvaluator","Eval","query","_HandleParenthesisContent","evaluateCallback","parenthesisContent","or","ori","_SimplifyNegation","trim","and","andj","booleanString","Tags","EnableFor","_tags","hasTags","HasTags","addTags","tagsString","AddTagsTo","removeTags","RemoveTagsFrom","matchesTagsQuery","tagsQuery","MatchesQuery","DisableFor","tags","GetTags","asString","tagsArray","tag","join","_AddTagTo","match","_RemoveTagFrom","CopySource","creationFunction","instanciate","options","classStore","propertyDescriptor","sourceProperty","propertyType","SerializationHelper","AllowLoadingUniqueId","cloneTexturesOnlyOnce","uniqueId","textureMap","isRenderTarget","AppendSerializedAnimations","animations","animationIndex","animation","Serialize","entity","serializedProperties","targetPropertyName","ParseProperties","rootUrl","dest","_TextureParser","_FresnelParametersParser","getLastMeshById","_ColorCurvesParser","_ImageProcessingConfigurationParser","getCameraById","Parse","Clone","Instanciate","_doNotSerialize","_isDisposed","_sceneRootNodesIndex","_isEnabled","_isParentEnabled","_isReady","_onEffectiveEnabledStateChangedObservable","_onClonedObservable","_inheritVisibility","_isVisible","constructorFunc","_NodeConstructors","Construct","accessibilityTag","_accessibilityTag","onAccessibilityTagChangedObservable","doNotSerialize","_parentNode","_nodeDataStorage","isDisposed","_children","_addToSceneRootNodes","previousParentNode","_removeFromSceneRootNodes","_syncParentEnabledState","inheritVisibility","isVisible","_serializeAsParent","parentId","rootNodes","lastIdx","animationPropertiesOverride","_animationPropertiesOverride","onDispose","_onDisposeObserver","onDisposeObservable","onEnabledStateChangedObservable","_onEnabledStateChangedObservable","_c","onClonedObservable","isPure","_InternalNodeDataInfo","__runInitializers","_name_initializers","_name_extraInitializers","_id_initializers","_id_extraInitializers","_uniqueId_initializers","_uniqueId_extraInitializers","_state_initializers","_internalMetadata","_metadata_extraInitializers","reservedDataStore","_parentContainer","_ranges","_currentRenderId","_cache","_worldMatrixDeterminantIsDirty","_isNode","_behaviors","getUniqueId","getEngine","behavior","attachImmediately","attach","detach","behaviors","getBehaviorByName","getRenderId","computeWorldMatrix","_worldMatrix","_getWorldMatrixDeterminant","_worldMatrixDeterminant","worldMatrixFromCache","_initCache","force","isSynchronized","_updateCache","_getActionManagerForTrigger","_initialCall","_isSynchronized","_markSyncedWithParent","_parentUpdateId","_childUpdateId","isSynchronizedWithParent","isReady","_completeCheck","Number","MAX_VALUE","isEnabled","checkAncestors","_hasEffectiveEnabledStateObservers","hasObservers","notify","wasEnabled","notifyEffective","wasEffectivelyEnabled","isDescendantOf","ancestor","_getDescendants","directDescendantsOnly","item","results","cullingStrategy","getDescendants","onReady","getAnimationByName","_AnimationRangeFactory","nAnimations","createRange","deleteFrames","deleteRange","doNotCloneChildren","newParent","directDescendants","child","animationRanges","speedRatio","onAnimationEnd","range","getAnimationRange","serializationRanges","localRange","doNotRecurse","nodes","disposeMaterialAndTextures","ParseAnimationRanges","parsedNode","ranges","createAnimationRange","incrementRenderId","boundingInfo","getBoundingInfo","boundingBox","minimumWorld","maximumWorld","includeDescendants","descendants","descendant","childMesh","getTotalVertices","minBox","maxBox","_metadata","_name_decorators","_id_decorators","_uniqueId_decorators","_state_decorators","_metadata_decorators","static","private","_state_extraInitializers","_name","_from","_to","Size","getHashCode","src","surface","otherSize","_xhr","XMLHttpRequest","_requestURL","IsCustomRequestAvailable","keys","WebRequest","CustomRequestHeaders","CustomRequestModifiers","_CleanUrl","url","SkipRequestModificationForBabylonCDN","_CollectCustomizations","baseHeaders","headers","_ShouldSkipRequestModifications","val","setRequestHeader","modifier","newUrl","method","resolvedUrl","fetch","body","request","responseType","addEventListener","readyState","status","responseHeaders","Headers","contentType","getResponseHeader","Response","response","statusText","ok","arrayBuffer","requestURL","open","send","onprogress","responseURL","responseText","timeout","listener","removeEventListener","abort","modifiedUrl","_StaticOffsetValueQuaternion","freeze","_StaticOffsetValueVector3","_StaticOffsetValueVector2","_StaticOffsetValueSize","_StaticOffsetValueColor3","_StaticOffsetValueColor4","EvaluateAnimationState","repeatCount","loopMode","Animation","_PrepareAnimation","targetProperty","framePerSecond","totalFrame","easingFunction","dataType","isFinite","frame","setKeys","setEasingFunction","runtimeAnimations","_runtimeAnimations","hasRunningRuntimeAnimations","runtimeAnimation","isStopped","enableBlending","_easingFunction","_events","blendingSpeed","_coreAnimation","targetPropertyPath","ANIMATIONLOOPMODE_CYCLE","_UniqueIdGenerator","fullDetails","_keys","first","addEvent","event","sort","removeEvents","getRange","nKeys","floatInterpolateFunctionWithTangents","outTangent","inTangent","Slerp","quaternionInterpolateFunctionWithTangents","vector3InterpolateFunctionWithTangents","vector2InterpolateFunctionWithTangents","color3InterpolateFunctionWithTangents","color4InterpolateFunctionWithTangents","_getKeyValue","evaluate","currentFrame","_interpolate","highLimitValue","_key","keysLength","searchClosestKeyOnly","startKey","endKey","interpolation","useTangent","ease","frameDelta","floatInterpolateFunction","ANIMATIONLOOPMODE_CONSTANT","ANIMATIONLOOPMODE_YOYO","ANIMATIONLOOPMODE_RELATIVE","ANIMATIONLOOPMODE_RELATIVE_FROM_CURRENT","quatValue","quaternionInterpolateFunction","vec3Value","vector3InterpolateFunction","vec2Value","vector2InterpolateFunction","sizeInterpolateFunction","color3Value","color3InterpolateFunction","color4Value","color4InterpolateFunction","AllowMatricesInterpolation","matrixInterpolateFunction","workValue","AllowMatrixDecomposeForInterpolation","cloneKeys","dontClone","lockedTangent","newKey","loopBehavior","getKeys","animationKey","_UniversalLerp","referenceFrameOrOptions","referenceFrame","cloneOriginalAnimation","cloneOriginal","clonedAnimationName","clonedName","sourceAnimation","firstKey","lastKey","endIndex","valueStore","referenceValue","referencePosition","referenceQuaternion","referenceScaling","keyPosition","keyQuaternion","keyScaling","rangeValue","fromFrame","toFrame","startIndex","createKeyForFrame","updatedKeys","startFrame","clippedKeys","animationType","AnimationCreateAndStartAnimation","beginDirectAnimation","AnimationCreateAndStartHierarchyAnimation","beginDirectHierarchyAnimation","AnimationCreateMergeAndStartAnimation","AnimationTransitionTo","targetValue","host","frameRate","transition","duration","stopCurrent","customKeys","endFrame","AnimationParse","parsedAnimation","_inTangent","_outTangent","keyData","JSON","parse","serializedAnimation","snippetUrl","snippet","jsonPayload","outputs","snippetId","InheritOriginalValueFromActiveAnimations","AnimationParseFromSnippetAsync","_Registered$a1","ParseFromFileAsync","AnimationParseFromFileAsync","ParseFromSnippetAsync","CreateFromSnippetAsync","AnimationCreateFromSnippetAsync","CreateAnimation","AnimationCreateAnimation","CreateAndStartAnimation","CreateAndStartHierarchyAnimation","CreateMergeAndStartAnimation","MakeAnimationAdditive","AnimationMakeAnimationAdditive","TransitionTo","Node$2","InterpolateValueAction","stopOtherAnimations","onInterpolationDone","onInterpolationDoneObservable","_Registered$a0","RuntimeAnimation","_currentFrame","_evaluatedFrom","_playbackFrom","_evaluatedTo","_playbackTo","_evaluatedProgress","_playbackProgress","_evaluatedSyncRoot","_playbackSyncRoot","_evaluatedJump","_playbackJumped","weight","_weight","currentValue","_currentValue","targetPath","_targetPath","_currentActiveTarget","isAdditive","_host","_originalValue","_originalBlendValue","_offsetsCache","_highLimitsCache","_stopped","_blendingFactor","_directTarget","_absoluteFrameOffset","_previousElapsedTime","_yoyoDirection","_previousAbsoluteFrame","_playbackFrames","_playbackSyncMasterPlayed","_playbackSyncMasterFrame","_coreRuntimeAnimation","_animation","_animationState","_getCorrectLoopMode","_minFrame","_preparePath","_getOriginalValues","_targetIsArray","_activeTargets","getEvents","events","_clone","_enableBlending","targetIndex","restoreOriginal","_setValue","isDone","setValue","originalValue","activeAnimatables","_activeAnimatables","animIndex","rtIndex","rtAnim","getLocalMatrix","_registerTargetForLateAnimationBinding","_registeredForLateAnimationBindings","pushNoDuplicate","_lateAnimationHolders","totalWeight","totalAdditiveWeight","additiveAnimations","writes","_animationWriteCount","write","additive","blendingFactor","carried","_prepareForSpeedRatioChange","newSpeedRatio","newAbsoluteFrame","animate","elapsedTimeSinceAnimationStart","frameRange","offsetValue","_maxFrame","absoluteFrame","yoyoLoop","yoyoMode","direction","keyOffset","fromValue","toValue","syncRoot","frames","syncFrames","syncJumped","syncRange","masterFrame","hostNormalizedFrame","master","getAnimations","phase","masterEvaluated","cycles","onlyOnce","IsWindowObjectExist","window","IsNavigatorAvailable","navigator","IsDocumentAvailable","document","GetDOMTextContent","element","firstChild","nodeType","textContent","nextSibling","DomManagement","PrecisionDate","Now","performance","now","Animatable","_syncRoot","_speedRatio","_goToFrame","goToFrame","elapsedTime","_localDelayOffset","_animationTime","playOrder","loopAnimation","onAnimationLoop","_pausedDelay","_paused","_previousWeight","_frameToSyncFromJump","disposeOnEnd","animationStarted","onAnimationEndObservable","onAnimationLoopObservable","appendAnimations","syncWith","newRuntimeAnimation","_onLoop","getAnimationByTargetProperty","getRuntimeAnimationByTargetProperty","disableBlending","fps","delay","_manualJumpDelay","useWeight","paused","pause","restart","_raiseOnAnimationEnd","animationName","targetMask","useGlobalSplice","skipOnAnimationEnd","idx","_animate","running","isRunning","ProcessLateAnimationBindingsForMatrices","holder","normalizer","finalPosition","finalScaling","finalQuaternion","originalAnimation","skipOverride","currentPosition","currentScaling","currentQuaternion","ProcessLateAnimationBindingsForQuaternions","refQuaternion","cumulativeQuaternion","quaternions","weights","cumulativeAmount","RegisterTargetForLateAnimationBinding","sceneClass","boneClass","sourceRange","rangeName","sourceBoneLength","sourceParent","getParent","parentScalingReqd","rescaleAsRequired","parentRatio","dimensionsScalingReqd","skelDimensionsRatio","orig","origTranslation","sourceKeys","getTranslation","destKeys","frameOffset","_animationWrites","kept","_animationStepWriteCount","_animationStepEvaluated","animationsEnabled","_pendingData","_animationTimeLast","customDeltaTime","useConstantAnimationDeltaTime","animationTimeScale","animatables","animationTime","animatable","path","matrixDecomposeMode","finalValue","originalAnimationIsLoopRelativeFromCurrent","ProcessLateAnimationBindings","sortActiveAnimatables","beginWeightedAnimation","returnedAnimatable","shouldRunTargetAnimations","getAnimatables","beginHierarchyAnimation","getAnimatableByTarget","getAllAnimatablesByTarget","stopAllAnimations","group","animationGroups","_b$9","ProcessPausedAnimatables","_matrix","_compose","_localMatrix","_needToCompose","_markAsDirtyAndDecompose","skeleton","_index","_scalingDeterminant","_needToDecompose","_waitingTransformNodeUniqueId","_skeleton","localMatrix","_restMatrix","restMatrix","_bindMatrix","bindMatrix","_absoluteMatrix","_absoluteBindMatrix","_absoluteInverseBindMatrix","bones","setParent","parentBone","_updateAbsoluteBindMatrices","getSkeleton","updateAbsoluteBindMatrices","getBaseMatrix","getBindMatrix","getRestPose","getRestMatrix","setRestMatrix","setRestPose","getBindPose","setBindMatrix","updateMatrix","setBindPose","_finalMatrix","getFinalMatrix","_linkedTransformNode","localScaling","localRotation","localPosition","getInvertedAbsoluteTransform","getAbsoluteInverseBindMatrix","getAbsoluteMatrix","computeAbsoluteMatrices","getAbsoluteTransform","linkTransformNode","transformNode","_numBonesWithLinkedTransformNode","_decompose","_localPosition","newPosition","_markAsDirtyAndCompose","getRotation","newRotation","setRotation","_localRotation","setRotationQuaternion","getScale","newScaling","setScale","_localScaling","updateLocalMatrix","updateChildren","_markAsDirty","_updatePosition","tNode","translationMode","lm","space","tmat","Bone","_TmpMats","tvec","_TmpVecs","setPosition","scaleChildren","scaleMat","cm","setYawPitchRoll","_TmpQuat","rotMatInv","_getAbsoluteInverseMatrixUnscaledToRef","_rotateWithMatrix","rmat","setAxisAngle","setRotationMatrix","rotMat2","lmat","lx","ly","lz","parentScale","parentScaleInv","scaleMatrix","getPosition","pos","getPositionToRef","getAbsolutePosition","getPoseMatrix","poseMatrix","getDirection","localAxis","getDirectionToRef","tMat","getRotationToRef","getRotationQuaternionToRef","getRotationQuaternion","amat","getRotationMatrixToRef","getAbsolutePositionFromLocal","getAbsolutePositionFromLocalToRef","getLocalPositionFromAbsolute","getLocalPositionFromAbsoluteToRef","_a$a","copyAnimationRange","RetryStrategy","maxRetries","baseInterval","retryIndex","BaseError","_setPrototypeOf","setPrototypeOf","proto","RuntimeError","errorCode","innerError","AbortError","suffix","StartsWith","startsWith","Decode","buffer","TextDecoder","decode","byteLength","EncodeArrayBufferToBase64","ArrayBuffer","isView","byteOffset","bytes","toBase64","keyStr","chr1","chr2","chr3","enc1","enc2","enc3","enc4","charAt","JsEncodeArrayBufferToBase64","DecodeBase64ToString","base64Data","atob","DecodeBase64ToBinary","fromBase64","decodedString","bufferLength","bufferView","charCodeAt","JsDecodeBase64ToBinary","StringTools","EndsWith","EngineFunctionContext","_ConcatenateShader","defines","shaderVersion","offlineProvider","useArrayBuffer","onError","injectedLoadFile","loadFileFn","loadFile","onSuccess","onProgress","_GetGlobalDefines","useReverseDepthBuffer","useExactSrgbConversions","sizeOrDstBuffer","sizeInBytes","copyBuffer","Int8Array","Int16Array","Uint16Array","Int32Array","Uint32Array","_d","_e","_f","_g","line","processor","lineProcessor","isFragment","processingContext","attributeKeyword","attributeKeywordName","varyingKeyword","varyingFragmentKeywordName","varyingVertexKeywordName","attributeProcessor","preprocessors","varyingCheck","varyingProcessor","uniformRegexp","test","lookForClosingBracketForUniformBuffer","uniformProcessor","uniformBufferRegexp","uniformBufferProcessor","textureProcessor","textureRegexp","endOfUniformBufferProcessor","process","preProcessorsFromCode","additionalDefineKey","additionalDefineValue","_lines","currentLine","lineIndex","canRead","lines","trimmedLine","semicolonIndex","subLine","ShaderCodeTestNode","ShaderCodeNode","testExpression","isTrue","postfixToInfix","postfix","stack","ShaderDefineExpression","_OperatorPriority","_InfixToPostfixCache","infix","cacheItem","accessTime","stackIdx","pushOperand","operand","_Stack","peek","token","InfixToPostfixCacheLimitSize","ClearCache","InfixToPostfixCacheCleanupSize","delete","sortedCache","Map","define","not","ShaderDefineOrOperator","leftOperand","rightOperand","ShaderDefineAndOperator","testValue","RegexSe","RegexSeRevert","RegexShaderInclude","RegexShaderDecl","RegexLightX","RegexX","ReusableMatches","MoveCursorRegex","Initialize","initializeShaders","preProcessShaderCode","sourceCode","ProcessIncludes","codeWithIncludes","processCodeAfterIncludes","migratedCode","engine","preparedSourceCode","noPrecision","shouldUseHighPrecisionShader","ProcessPrecision","shaderLanguage","parseGLES3","preProcessor","postProcessor","drawBuffersExtensionDisabled","getCaps","drawBuffersExtension","needShaderCodeInlining","inlineShaderCode","ProcessShaderConversion","Finalize","vertexCode","fragmentCode","finalizeShaders","ExtractOperation","expression","ShaderDefineIsDefinedOperator","operators","indexOperator","ShaderDefineArithmeticOperator","BuildExpression","command","infixToPostfix","BuildSubExpression","MoveCursorWithinIf","cursor","rootNode","ifNode","MoveCursor","first5","elseNode","elifNode","matches","exec","newRootNode","ShaderCodeConditionNode","newNode","EvaluatePreProcessors","ShaderCodeCursor","version","platformName","parts","keepProcessing","includeFile","includeShaderUrl","_FunctionContainer","includesShadersStore","fileContent","includeContent","splits","RegExp","indexString","indexSplits","maxIndex","sourceIncludeContent","indexParameters","minIndex","newParts","part","splitPart","ImmediateQueue","TimingTools","functionsToCall","RunWithCondition","int","clearInterval","maxTimeout","additionalStringOnTimeout","Tables","floatView","baseTable","shiftTable","mantissaTable","exponentTable","offsetTable","uint32View","tables","GenerateTables","FromHalfFloat","dataView","getInt8","getUint8","getInt16","getUint16","getInt32","getUint32","getFloat32","setInt8","setUint8","setInt16","setUint16","ToHalfFloat","setInt32","setUint32","setFloat32","componentType","byteStride","componentCount","oldValues","newValues","stride","componentIndex","DataView","componentByteLength","GetTypeByteLength","componentByteOffset","GetFloatValue","SetFloatValue","GetFloatData","totalVertices","forceCopy","tightlyPackedByteStride","copy","EnumerateFloatValues","BYTES_PER_ELEMENT","typeByteLength","GetTypedArrayConstructor","adjustedByteOffset","dst","rowBytes","subarray","CopyFloatData","input","floatData","AreIndices32Bits","indices","CreateAlignedTypedArray","elementCount","byteSize","GetBlobBufferSource","unsharedBuffer","Base64DataUrlRegEx","LoadFileError","ErrorCodes","file","RequestFileError","ReadFileError","FileToolsOptions","DefaultRetryStrategy","ExponentialBackoff","BaseUrl","CorsBehavior","PreprocessUrl","ScriptBaseUrl","ScriptPreprocessUrl","SetCorsBehavior","crossOrigin","LoadImageConfiguration","LoadImage","onLoad","mimeType","imageBitmapOptions","HTMLImageElement","_features","forceBitmapOverHTMLImageElement","Blob","blob","reason","usingObjectURL","URL","createObjectURL","CleanUrl","onErrorHandler","exception","inputText","imgBmp","revokeObjectURL","img","Image","getRequiredSize","handlersList","unloadHandlersList","handler","blockedURI","disposition","cspException","effectiveDirective","originalPolicy","loadHandlersList","fromBlob","fromData","noOfflineSupport","LoadFile","_request","enableTexturesOffline","loadImage","textureName","decodeURIComponent","FilesInputStore","FilesToLoad","blobURL","ReadFile","reader","FileReader","fileRequest","onCompleteObservable","readAsArrayBuffer","readAsText","fileOrUrl","onOpened","fileName","TestBase64DataUrl","DecodeBase64UrlToString","loadUrl","aborted","requestFile","onReadyStateChange","retryHandle","unbindEvents","onLoadEnd","DONE","clearTimeout","retryLoop","handleError","retryStrategy","waitTime","enableSceneOffline","loadFromOfflineSupport","GetMimeType","lastDot","lastIndexOf","IsFileURL","location","protocol","uri","DecodeBase64UrlToBinary","exports","FileTools","_injectLTSFileTools","IsBase64DataUrl","RequestFile","_Registered$9$","InstantiationTools","Instantiate","RegisteredExternalClasses","internalClass","globalThis","RandomGUID","GUID","IsExponentOfTwo","Mix","CeilingPOT","FloorPOT","GetExponentOfTwo","mode","pot","NearestPOT","_a$9","Tools","CDNBaseUrl","AssetBaseUrl","strategy","classes","fallbackTexture","FallbackTexture","u","pixels","SetImmediate","fround","GetFilename","GetFolderPath","returnUnchangedIfNoSlash","ToDegrees","ToRadians","SmoothAngleChange","newAngle","previousAngleRad","newAngleRad","smoothFactor","MakeArray","allowsNullUndefined","GetPointerPrefix","PointerEvent","SetReferrerPolicyBehavior","referrerPolicy","FileToolLoadImage","FileToolsLoadFile","GetAssetUrl","baseUrl","_DefaultAssetsUrl","GetBabylonScriptURL","scriptUrl","forceAbsoluteUrl","_DefaultCdnUrl","versionedBase","IsAbsoluteUrl","GetAbsoluteUrl","scriptId","LoadScript","LoadScriptAsync","_LoadScriptNative","_scriptId","useModule","Function","_LoadScriptWeb","importScripts","head","getElementsByTagName","createElement","script","setAttribute","innerText","onload","onerror","appendChild","ReadFileAsDataURL","progressCallback","readAsDataURL","fileToLoad","FileToolsReadFile","FileAsURL","fileBlob","content","decimals","toFixed","IsEmpty","RegisterTopRootEvents","windowElement","UnregisterTopRootEvents","DumpFramebuffer","width_1","height_1","engine_1","successCallback_1","successCallback","quality","DumpData","invertY","toArrayBuffer","DumpDataAsync","data_1","_IsOffScreenCanvas","canvas","convertToBlob","toBlob","binStr","toDataURL","getFullYear","getMonth","getDate","Download","newWindow","EncodeScreenshotCanvasData","onloadend","base64data","base64Image","ToBlob","DownloadBlob","style","display","href","download","parentElement","removeChild","CreateScreenshot","camera","forceDownload","CreateScreenshotUsingRenderTarget","samples","antialiasing","renderSprites","enableStencilBuffer","useLayerMask","customizeTexture","CreateScreenshotUsingRenderTargetAsync","RandomId","IsBase64","DecodeBase64","PerformanceUserMarkLogLevel","PerformanceConsoleLogLevel","StartPerformanceCounter","_StartPerformanceCounterDisabled","EndPerformanceCounter","_EndPerformanceCounterDisabled","disablePerformanceLogging","enablePerformanceLogging","_StartMarkNative","_EndMarkNative","_StartPerformanceConsole","_EndPerformanceConsole","_StartUserMark","_EndUserMark","counterName","_Performance","mark","measure","timeEnd","startPerformanceCounter","_NativePerformanceCounterHandles","handle","endPerformanceCounter","isType","First","el","getFullClassName","moduleName","classObj","IsSafari","userAgent","module","UseCustomRequestHeaders","_CdnVersion","PerformanceNoneLogLevel","AsyncLoop","iterations","_done","_fn","_successCallback","executeNext","breakLoop","Run","syncedIterations","breakFunction","ceil","iteration","_Registered$9_","SmartArray","capacity","_id","_GlobalId","forEach","compareFn","concat","_duplicateId","__smartArrayFlags","concatWithNoDuplicate","_count","_data","curVal","cur","res","PlanckianLocusTable","MinTemperatureKelvin","MaxTintMagnitude","temperatureKelvin","low","high","mid","mired","lowMired","lowU","lowV","lowT","highMired","highU","highV","highT","uv","isothermLow","isothermHigh","isotherm","clampedTint","tint","InverseBradfordMatrix","BradfordMatrix","ClampedAdaptationRatio","destComponent","sourceComponent","BradfordAdapt","sourceWhiteXYZ","sourceLMS","destLMS","StandardD65Xyz","RgbToXyzD65","TemperatureTintToXyz","XyzToRgbD65","ReferenceWhiteXyz","GetWhiteBalanceMatrix","adapt","finalMatrix","PrepareUniformsForColorCurves","uniformsList","_dirty","_tempColor","_globalCurve","_highlightsCurve","_midtonesCurve","_shadowsCurve","_positiveCurve","_negativeCurve","_globalHue","_globalDensity","__globalDensity_initializers","_globalSaturation","__globalDensity_extraInitializers","__globalSaturation_initializers","_globalExposure","__globalSaturation_extraInitializers","_highlightsHue","__highlightsHue_initializers","_highlightsDensity","__highlightsDensity_initializers","_highlightsSaturation","__highlightsDensity_extraInitializers","__highlightsSaturation_initializers","_highlightsExposure","__highlightsSaturation_extraInitializers","_midtonesHue","_midtonesDensity","__midtonesDensity_initializers","_midtonesSaturation","__midtonesDensity_extraInitializers","__midtonesSaturation_initializers","_midtonesExposure","__midtonesSaturation_extraInitializers","__midtonesExposure_initializers","_shadowsHue","__midtonesExposure_extraInitializers","_shadowsDensity","_shadowsSaturation","_shadowsExposure","globalHue","globalDensity","globalSaturation","globalExposure","highlightsHue","highlightsDensity","highlightsSaturation","highlightsExposure","midtonesHue","midtonesDensity","midtonesSaturation","midtonesExposure","shadowsHue","shadowsDensity","shadowsSaturation","shadowsExposure","_getColorGradingDataToRef","density","exposure","_Clamp","_ApplyColorGradingSliderNonlinear","_FromHSBToRef","brightness","_bind","effect","positiveUniform","neutralUniform","negativeUniform","setFloat4","__globalHue_decorators","__globalDensity_decorators","__globalSaturation_decorators","__globalExposure_decorators","__highlightsHue_decorators","__highlightsDensity_decorators","__highlightsSaturation_decorators","__highlightsExposure_decorators","__midtonesHue_decorators","__midtonesDensity_decorators","__midtonesSaturation_decorators","__midtonesExposure_decorators","__globalHue_initializers","__globalHue_extraInitializers","__globalExposure_initializers","__highlightsHue_extraInitializers","__highlightsExposure_extraInitializers","__midtonesHue_initializers","__midtonesHue_extraInitializers","_Registered$9Z","ColorCurvesParse","ColorCurves","ColorCurvesBind","colorCurves","Bind","PrepareUniformsForImageProcessing","uniforms","WHITEBALANCE","EXPOSURE","CONTRAST","COLORGRADING","VIGNETTE","COLORCURVES","DITHER","PrepareSamplersForImageProcessing","samplersList","_colorCurves_initializers","_colorCurvesEnabled","__colorCurvesEnabled_initializers","_colorGradingTexture","__colorCurvesEnabled_extraInitializers","__colorGradingTexture_initializers","_colorGradingEnabled","__colorGradingTexture_extraInitializers","__colorGradingEnabled_initializers","_colorGradingWithGreenDepth","__colorGradingEnabled_extraInitializers","_exposure","__colorGradingBGR_extraInitializers","__exposure_initializers","_toneMappingEnabled","__exposure_extraInitializers","__toneMappingEnabled_initializers","_toneMappingType","__toneMappingEnabled_extraInitializers","TONEMAPPING_STANDARD","_contrast","__toneMappingType_extraInitializers","__contrast_initializers","_whiteBalanceEnabled","__contrast_extraInitializers","__whiteBalanceEnabled_initializers","_temperature","__whiteBalanceEnabled_extraInitializers","_tint","__temperature_extraInitializers","__tint_initializers","_whiteBalanceMatrix","__tint_extraInitializers","_whiteBalanceMatrixTemperature","_whiteBalanceMatrixTint","vignetteStretch","_vignetteStretch_initializers","vignetteCenterX","_vignetteStretch_extraInitializers","_vignetteCenterX_initializers","vignetteCenterY","_vignetteCenterX_extraInitializers","_vignetteCenterY_initializers","vignetteWeight","_vignetteCenterY_extraInitializers","_vignetteWeight_initializers","vignetteColor","_vignetteWeight_extraInitializers","_vignetteColor_initializers","vignetteCameraFov","_vignetteBlendMode","_vignetteCameraFov_extraInitializers","VIGNETTEMODE_MULTIPLY","_vignetteEnabled","__vignetteBlendMode_extraInitializers","_ditheringEnabled","__vignetteEnabled_extraInitializers","_applyByPostProcess","__skipFinalColorClamp_extraInitializers","__applyByPostProcess_extraInitializers","__isEnabled_initializers","outputTextureWidth","__isEnabled_extraInitializers","_outputTextureWidth_initializers","outputTextureHeight","_outputTextureWidth_extraInitializers","_outputTextureHeight_initializers","onUpdateParameters","_outputTextureHeight_extraInitializers","colorCurvesEnabled","_updateParameters","colorGradingTexture","colorGradingEnabled","colorGradingWithGreenDepth","colorGradingBGR","_colorGradingBGR","toneMappingEnabled","toneMappingType","contrast","whiteBalanceEnabled","temperature","vignetteCentreY","vignetteCentreX","vignetteBlendMode","vignetteEnabled","ditheringEnabled","ditheringIntensity","_ditheringIntensity","skipFinalColorClamp","_skipFinalColorClamp","applyByPostProcess","forPostProcess","TONEMAPPING","COLORGRADING3D","IMAGEPROCESSING","SKIPFINALCOLORCLAMP","IMAGEPROCESSINGPOSTPROCESS","VIGNETTEBLENDMODEMULTIPLY","_VIGNETTEMODE_MULTIPLY","VIGNETTEBLENDMODEOPAQUE","TONEMAPPING_KHR_PBR_NEUTRAL","TONEMAPPING_ACES","is3D","SAMPLER3DGREENDEPTH","SAMPLER3DBGRMAP","setMatrix3x3","_getWhiteBalanceMatrix","inverseWidth","getRenderWidth","inverseHeight","getRenderHeight","setFloat2","setFloat","aspectRatio","overrideAspectRatio","vignetteScaleY","vignetteScaleX","vignetteScaleGeometricMean","vignettePower","setTexture","textureSize","getSize","VIGNETTEMODE_OPAQUE","_VIGNETTEMODE_OPAQUE","_colorCurves_decorators","serializeAsColorCurves","__colorGradingTexture_decorators","serializeAsTexture","__colorGradingEnabled_decorators","__colorGradingWithGreenDepth_decorators","__colorGradingBGR_decorators","__exposure_decorators","__toneMappingEnabled_decorators","__toneMappingType_decorators","__contrast_decorators","__whiteBalanceEnabled_decorators","__temperature_decorators","__tint_decorators","_vignetteStretch_decorators","_vignetteCenterX_decorators","_vignetteCenterY_decorators","_vignetteWeight_decorators","_vignetteColor_decorators","serializeAsColor4","_vignetteCameraFov_decorators","__vignetteBlendMode_decorators","__vignetteEnabled_decorators","__ditheringEnabled_decorators","__ditheringIntensity_decorators","__skipFinalColorClamp_decorators","__applyByPostProcess_decorators","__isEnabled_decorators","_outputTextureWidth_decorators","_outputTextureHeight_decorators","_colorCurves_extraInitializers","__colorCurvesEnabled_decorators","__colorGradingWithGreenDepth_extraInitializers","_vignetteColor_extraInitializers","__vignetteBlendMode_initializers","__ditheringEnabled_extraInitializers","__ditheringIntensity_extraInitializers","__skipFinalColorClamp_initializers","PrepareUniforms","_Registered$9Y","parsed","ImageProcessingConfiguration","ImageProcessingConfigurationParse","UniformBuffer","dynamic","forceNoUniformBuffer","trackUBOsInFrame","_valueCache","_engine","_noUBO","supportsUniformBuffers","_dynamic","_uniformLocations","_uniformSizes","_uniformArraySizes","_uniformLocationPointer","_needSync","_dataGeneration","_trackUBOsInFrame","trackUbosInFrame","_buffers","_bufferIndex","_bufferUpdatedLastFrame","_createBufferOnWrite","_currentFrameId","_resetOwnerSlots","updateMatrix3x3","_updateMatrix3x3ForEffect","updateMatrix2x2","_updateMatrix2x2ForEffect","updateFloat","_updateFloatForEffect","updateFloat2","_updateFloat2ForEffect","updateFloat3","_updateFloat3ForEffect","updateFloat4","_updateFloat4ForEffect","updateFloatArray","_updateFloatArrayForEffect","updateArray","_updateArrayForEffect","updateIntArray","_updateIntArrayForEffect","updateUIntArray","_updateUIntArrayForEffect","_updateMatrixForEffect","updateMatrices","_updateMatricesForEffect","updateVector3","_updateVector3ForEffect","updateVector4","_updateVector4ForEffect","updateColor3","_updateColor3ForEffect","updateColor4","_updateColor4ForEffect","updateDirectColor4","_updateDirectColor4ForEffect","updateInt","_updateIntForEffect","updateInt2","_updateInt2ForEffect","updateInt3","_updateInt3ForEffect","updateInt4","_updateInt4ForEffect","updateUInt","_updateUIntForEffect","updateUInt2","_updateUInt2ForEffect","updateUInt3","_updateUInt3ForEffect","updateUInt4","_updateUInt4ForEffect","_uniformBuffers","_updateMatrix3x3ForUniform","_updateMatrix2x2ForUniform","_updateFloatForUniform","_updateFloat2ForUniform","_updateFloat3ForUniform","_updateFloat4ForUniform","_updateFloatArrayForUniform","_updateArrayForUniform","_updateIntArrayForUniform","_updateUIntArrayForUniform","_updateMatrixForUniform","_updateMatricesForUniform","_updateVector3ForUniform","_updateVector4ForUniform","_updateColor3ForUniform","_updateColor4ForUniform","_updateDirectColor4ForUniform","_updateIntForUniform","_updateInt2ForUniform","_updateInt3ForUniform","_updateInt4ForUniform","_updateUIntForUniform","_updateUInt2ForUniform","_updateUInt3ForUniform","_updateUInt4ForUniform","useUbo","isSync","_bufferData","_buffer","_uniformNames","alignment","oldPointer","strideSize","arraySize","_fillAlignment","addMatrix","addUniform","addFloat2","addColor3","addColor4","addMatrix3x3","addMatrix2x2","_rebuild","names","createDynamicUniformBuffer","_getNamesDebug","createUniformBuffer","checkUbosContentBeforeUpload","_rebuildAfterContextLost","_ownerListsBySlot","list","_removeOwnerBacklink","_slotByOwner","_slotFrameId","_ownerCount","_freeSlots","_slotGeneration","_numBuffers","_indexBuffer","currentEffect","_currentEffect","_buffersEqual","buf1","buf2","_copyBuffer","update","bindUniformBuffer","updateUniformBuffer","owner","_checkNewFrame","_takeFreeSlot","_uniformBuffersWithOwnedSlot","owned","shadow","takeOwnership","_createNewBuffer","frameId","uniformName","changed","uniformBufferHardCheckMatrix","arraySizes","countToFour","baseStride","FloatRound","cache","_TempBuffer","updateUniform","setMatrix2x2","setFloat3","setFloatArray2","setFloatArray3","setFloatArray4","setFloatArray","updateUniformArray","setArray","setIntArray","_TempBufferInt32View","setUIntArray","_TempBufferUInt32View","setMatrix","_cacheMatrix","setMatrices","setVector3","setVector4","setColor3","setColor4","setDirectColor4","setInt","setInt2","setInt3","setInt4","setUInt","setUInt2","setUInt3","setUInt4","texture","textures","setTextureArray","_bindTexture","bindToEffect","_currentEffectName","unbindEffect","setDataBuffer","dataBuffer","uniformBuffers","_releaseBuffer","_MAX_UNIFORM_SIZE","DataBuffer","underlyingResource","is32Bits","_Counter","ShaderStore","GetShadersRepository","ShadersRepository","ShadersRepositoryWGSL","GetShadersStore","ShadersStore","ShadersStoreWGSL","GetIncludesShadersStore","IncludesShadersStore","IncludesShadersStoreWGSL","vertexCompilationError","fragmentCompilationError","programLinkError","isAsync","isParallelCompiled","program","_isRenderingStateCompiled","_handlesSpectorRebuildCallback","onCompiled","setEngine","_fillEffectInformation","uniformBuffersNames","uniformsNames","samplerList","samplers","attributesNames","attributes","bindUniformBlock","uniform","_uniforms","getUniform","attr","getAttributes","_cacheFloat2","_cacheFloat3","_cacheFloat4","setIntArray2","setIntArray3","setIntArray4","setUIntArray2","setUIntArray3","setUIntArray4","setArray2","setArray3","setArray4","matrices","setVector2","vector2","vector4","color4","vertexShader","_getShaderSource","fragmentShader","StateObject","SingleStateObject","_webGLVersion","cachedPipelines","TEXTURE_BINDING_3D","parallelShaderCompile","getExtension","deleteStateObject","stateObject","getStateObject","_createShaderProgramInjection","_createShaderProgram","pipelineContext","CompileRawShader","_contextWasLost","transformFeedbackVaryings","validateShaderPrograms","CompileShader","_transformFeedbackVaryings","shaderProgram","createProgram","attachShader","linkProgram","_finalizePipelineContext","gl","getProgramParameter","LINK_STATUS","getShaderParameter","getShaderInfoLog","getProgramInfoLog","validateProgram","VALIDATE_STATUS","programValidationError","deleteShader","shader","createShader","VERTEX_SHADER","FRAGMENT_SHADER","tempError","NO_ERROR","getError","isContextLost","shaderSource","resetCachedPipeline","pipeline","cachedPipeline","LoadShader","_loadFileInjection","HTMLElement","shaderStore","optionalKey","shaderUrl","_LoadFile","Effect","EngineShaderStore","repo","onBindObservable","_onBindObservable","_shaderLanguage","onBind","onCompileObservable","_samplers","_compilationError","_fallbacks","_vertexSourceCodeOverride","_fragmentSourceCodeOverride","_disableParallelShaderCompilation","_rawFragmentSourceCode","_processCodeAfterIncludes","_processFinalCode","_onReleaseEffectsObserver","baseName","pipelineName","attributesNamesOrOptions","uniformsNamesOrEngine","_attributesNames","_uniformsNames","_samplerList","fallbacks","_indexParameters","_multiTarget","disableParallelShaderCompilation","_uniformBuffersNamesList","_uniformBuffersNames","processFinalCode","extraInitializationsAsync","existingPipelineContext","shaderPlatformName","getCachedPipeline","_gl","_attributeLocationByName","_UniqueIdSeed","_pipelineContext","__SPECTOR_rebuildProgram","_rebuildProgram","asyncError","_processCompilationErrors","onReleaseEffectsObservable","shaderProcessor","keepExistingPipelineContext","shaderProcessingContext","_processingContext","_getShaderProcessingContext","processorOptions","onFinalCodeReady","effectContext","vertexSource","hostDocument","getHostDocument","vertexElement","getElementById","vertex","fragmentSource","fragmentElement","fragment","shaderCodes","shadersLoaded","migratedVertexCode","codeBeforeMigration","_vertexSourceCodeBeforeMigration","migratedFragmentCode","_fragmentSourceCodeBeforeMigration","finalShaders","finalCode","vertexSourceCode","spectorName","fragmentSourceCode","_rawVertexSourceCode","_ProcessShaderCode","_shouldUseHighPrecisionShader","_getShaderProcessor","shadersRepository","_vertexSourceCode","_fragmentSourceCode","_prepareEffect","_isReadyInternal","getAttributeLocation","_attributes","getAttributeLocationByName","getAttributesCount","_allFallbacksProcessed","executeWhenCompiled","_checkIsReady","previousPipelineContext","_getVertexShaderCode","_getFragmentShaderCode","vertexSourceCodeBeforeMigration","fragmentSourceCodeBeforeMigration","rawVertexSourceCode","rawFragmentSourceCode","shaderNameOrContent","addGlobalDefines","createAsRaw","scenes","markAllMaterialsAsDirty","_onRenderingStateCompiled","bindSamplers","unBindMesh","AutomaticallyClearCodeCache","clearCodeCache","overrides","createPipelineContext","_preparePipelineContext","_executeWhenRenderingStateIsCompiled","disableParallelShaderCompile","disableParallelCompilation","rebuildRebind","onRenderingStateCompiled","_deletePipelineContext","_preparePipelineContextAsync","regexp","errorLine","code","lineNumber","LogShaderCodeOnCompilationError","lineErrorVertex","lineErrorFragment","_getShaderCodeAndErrorLine","notifyErrors","onEffectErrorObservable","errors","hasMoreFallbacks","reduce","isSupported","channel","exName","initialPos","currentExName","channelIndex","bufferName","_BaseCache","useUBOBindingCache","bindUniformBufferBase","blockName","setBool","bool","setQuaternion","_refCount","PersistentMode","_releaseEffect","RegisterShader","pixelShader","ResetCache","DepthCullingState","_isDepthTestDirty","_isDepthMaskDirty","_isDepthFuncDirty","_isCullFaceDirty","_isCullDirty","_isZOffsetDirty","isDirty","_isFrontFaceDirty","_zOffset","zOffsetUnits","_zOffsetUnits","cullFace","_cullFace","cull","_cull","depthFunc","_depthFunc","depthMask","_depthMask","depthTest","_depthTest","frontFace","_frontFace","enable","CULL_FACE","disable","DEPTH_TEST","POLYGON_OFFSET_FILL","polygonOffset","StencilStateComposer","_isStencilTestDirty","_isStencilMaskDirty","_isStencilFuncDirty","_isStencilOpDirty","_func","backFunc","_backFunc","funcRef","_funcRef","funcMask","_funcMask","opStencilFail","_opStencilFail","opDepthFail","_opDepthFail","opStencilDepthPass","_opStencilDepthPass","backOpStencilFail","_backOpStencilFail","backOpDepthFail","_backOpDepthFail","backOpStencilDepthPass","_backOpStencilDepthPass","_mask","enabled","_enabled","stencilMaterial","stencilGlobal","stencilMaterialEnabled","useStencilGlobalOnly","STENCIL_TEST","stencilMask","stencilFuncSeparate","FRONT","BACK","stencilOpSeparate","StencilState","stencilFunc","stencilBackFunc","stencilFuncRef","stencilFuncMask","stencilOpStencilFail","stencilOpDepthFail","stencilOpStencilDepthPass","stencilBackOpStencilFail","stencilBackOpDepthFail","stencilBackOpStencilDepthPass","stencilTest","AlphaState","_supportBlendParametersPerTarget","_blendFunctionParameters","_blendEquationParameters","_blendConstants","_isBlendConstantsDirty","_alphaBlend","fill","_numTargetEnabled","_isAlphaBlendDirty","_isBlendFunctionParametersDirty","_isBlendEquationParametersDirty","_blendDisabledTargetsMask","_numTargets","alphaBlend","setAlphaBlend","setAlphaBlendConstants","setAlphaBlendFunctionParameters","dstRGBFactor","srcAlphaFactor","dstAlphaFactor","srcRGBFactor","setAlphaEquationParameters","rgbEquation","alphaEquation","numTargets","blendDisabledTargetsMask","blendColor","BLEND","blendFuncSeparate","blendEquationSeparate","gl2","disableIndexed","enableIndexed","blendFuncSeparateIndexed","blendEquationSeparateIndexed","setAlphaMode","equation","TextureSampler","wrapU","_cachedWrapU","wrapV","_cachedWrapV","wrapR","_cachedWrapR","anisotropicFilteringLevel","_cachedAnisotropicFilteringLevel","comparisonFunction","_comparisonFunction","useMipMaps","_useMipMaps","samplingMode","setParameters","compareSampler","InternalTextureSource","InternalTexture","generateMipMaps","_uniqueId","_setUniqueId","_source","delayAllocation","isCube","is2DArray","isMultiview","mipLevelCount","format","onLoadedObservable","onRebuildCallback","depth","baseWidth","baseHeight","baseDepth","_autoMSAAManagement","_hardwareTexture","_createHardwareTexture","_references","updateSize","updateTextureDimensions","_size","_cachedCoordinatesMode","proxyInternalTexture","_swapAndDie","proxy","swapAndSetIsReady","_extension","_useSRGBBuffer","createRawTexture","_bufferView","_compression","_creationFlags","_bufferViewArray","mipLevel","mipData","updateRawTexture","createRawTexture3D","createRawTexture2DArray","updateRawTexture2DArray","createDynamicTexture","_dynamicTextureSource","updateDynamicTexture","_premulAlpha","createCubeTexture","_files","createRawCubeTexture","_originalFormat","createPrefilteredCubeTexture","_lodGenerationScale","_lodGenerationOffset","_sphericalPolynomial","setUsage","swapAll","_isRGBD","_lodTextureHigh","_lodTextureMid","_lodTextureLow","_irradianceTexture","_releaseTexture","requester","requestAnimationFrame","AbstractEngine","_frameId","isWebGPU","_isWebGPU","_shaderProcessor","_alphaMode","_alphaEquation","_shaderPlatformName","_clearEmptyResources","_emptyTexture","_emptyCubeTexture","_emptyTexture3D","_emptyTexture2DArray","_useReverseDepthBuffer","useReverse","_depthCullingState","setColorWrite","_colorWrite","_colorWriteChanged","depthCullingState","alphaState","_alphaState","stencilState","_stencilState","stencilStateComposer","_stencilStateComposer","currentState","_internalTexturesCache","internalTexture","_renderTargetWrapperCache","renderTargetWrapper","some","_rebuildEffects","_compiledEffects","wipeCaches","onContextRestoredObservable","initEngine","_rebuildGraphicsResources","_flagContextRestored","snapshotRendering","snapshotRenderingMode","emptyTexture","emptyTexture3D","emptyTexture2DArray","emptyCubeTexture","faceData","cubeData","framebufferDimensionsObject","dimensions","_framebufferDimensionsObject","activeRenderLoops","_activeRenderLoops","renderFunction","_cancelFrame","customAnimationFrameRequester","_frameHandler","cancelAnimationFrame","requestID","handlerToCancel","beginFrame","onBeginFrameObservable","onEndFrameObservable","maxFPS","_maxFPS","_minFrameTime","timestamp","_lastFrameTime","_renderAccumulator","_processFrame","_isOverFrameTime","shouldRender","renderEvenInBackground","_windowIsBackground","_renderFrame","_renderLoop","_queueNewFrameForRenderLoop","_renderViews","_queueNewFrame","bindedRenderFunction","QueueNewFrame","_boundRenderFunction","getHostWindow","runRenderLoop","getDepthBuffer","setDepthBuffer","setZOffset","getZOffset","setZOffsetUnits","getZOffsetUnits","_renderingCanvas","ownerDocument","defaultView","compatibilityMode","_compatibilityMode","_rebuildTextures","_virtualScenes","rtWrapper","currentViewport","_cachedViewport","requiredWidth","requiredHeight","_viewport","createCanvasImage","createCanvasPath2D","Path2D","description","_caps","_createTextureBase","noMipmap","prepareTexture","prepareTextureProcess","fallback","forcedExtension","loaderOptions","useSRGBBuffer","isBase64","label","originalUrl","_transformTextureUrl","_originalUrl","extension","GetCompatibleTextureLoader","addPendingData","onLoadObserver","onInternalError","removePendingData","loaderPromise","callbackAsync","loadData","loadMipmap","isCompressed","loadFailed","processBufferAsync","_loadFile","decoding","close","_FileToolsLoadImage","needsInvertingBitmap","imageOrientation","uniformBuffer","highPrecisionShaderSupported","_highPrecisionShadersAllowed","clearInternalTexturesCache","resetTextureCache","_boundTexturesCache","_currentTextureChannel","NpmPackage","Version","_audioContext","_audioDestination","setHardwareScalingLevel","_hardwareScalingLevel","resize","doNotHandleContextLost","_doNotHandleContextLost","isStencilEnable","_isStencilEnable","_creationOptions","_badDesktopOS","_enableGPUDebugMarkers","onCanvasBlurObservable","onCanvasFocusObservable","onNewSceneAddedObservable","onResizeObservable","onCanvasPointerOutObservable","disablePerformanceMonitorInBackground","hostInformation","isMobile","isFullscreen","enableOfflineSupport","disableManifestCheck","disableContextMenu","currentRenderPassId","isPointerLock","onBeforeTextureInitObservable","skipFrameRender","onBeforeShaderCompilationObservable","onAfterShaderCompilationObservable","_storageBuffers","onContextLostObservable","premultipliedAlpha","_fps","_timeStep","startTime","useLargeWorldRendering","useHighPrecisionMatrix","antialias","deterministicLockstep","lockstepMaxSteps","timeStep","stencil","audioContext","_h","audioEngineOptions","audioDestination","_j","_k","canvasTabIndex","_l","devicePixelRatio","adaptToDeviceRatio","limitDeviceRatio","_lastDevicePixelRatio","changeRatio","boundingRect","getBoundingClientRect","clientWidth","clientHeight","innerWidth","innerHeight","setSize","forceSetSize","camIndex","cameras","compression","creationFlags","textureType","_sharedInit","_checkForMobile","currentUa","createVideoElement","constraints","_drawCalls","addCount","numDrawCalls","_deltaTime","_deterministicLockstep","_lockstepMaxSteps","getTimeStep","_createImageBitmapFromSource","createImageBitmap","image","resizeImageBitmap","getFontOffset","font","_CreateCanvas","OffscreenCanvas","_activeRequests","_FileToolsLoadFile","releaseEffects","postProcesses","releaseComputeEffects","_onReleaseRenderPassObservable","DefaultLoadingScreenFactory","engineIndex","_mimeType","IsWrapper","getPipelineContext","_RenderPassIdCounter","_RescalePostProcessFactory","CollisionsEpsilon","regex","VaryingRegex$1","attribute","VaryingRegex","varying","hasOutput","search","hasDualSourceBlending","outputDeclaration","hasDrawBuffersExtension","resource","WebGLHardwareTexture","_webGLTexture","_MSAARenderBuffers","_context","existingTexture","createTexture","hardwareTexture","addMSAARenderBuffer","releaseMSAARenderBuffers","deleteRenderbuffer","deleteTexture","IsDepthTexture","IsIntegerTextureFormat","IsUnsignedIntegerTextureType","HasStencilAspect","BufferPointer","ThinEngine","webGLVersion","disableUniformBuffers","needPOTTextures","forcePOTTextures","_supportsHardwareTextureRescaling","snapshotRenderingReset","canvasOrContext","_integerMRTAttachmentsMask","_vertexAttribArraysEnabled","_uintIndicesCurrentlySet","_dummyFramebuffer","_currentBufferPointers","_currentInstanceLocations","_currentInstanceBuffers","_vaoRecordInProgress","_mustWipeVertexAttributes","_nextFreeTextureSlots","_maxSimultaneousTextures","_unpackFlipYCached","enableUnpackFlipYCached","_boundUniforms","getContext","preserveDrawingBuffer","xrCompatible","_setupMobileChecks","ua","ExceptionList","targets","capture","captureConstraint","constraint","disableVertexArrayObjects","_maxMSAASamplesOverride","_onContextLost","preventDefault","_onContextRestored","_restoreEngineAfterContextLost","_initGLContext","powerPreference","disableWebGL2Support","deleteQuery","cause","renderbufferStorageMultisample","getContextAttributes","pixelStorei","UNPACK_COLORSPACE_CONVERSION_WEBGL","NONE","useHighPrecisionFloats","maxVertexAttribs","versionToLog","areAllEffectsReady","maxTexturesImageUnits","getParameter","MAX_TEXTURE_IMAGE_UNITS","maxCombinedTexturesImageUnits","maxVertexTextureImageUnits","maxTextureSize","MAX_TEXTURE_SIZE","maxSamples","maxCubemapTextureSize","maxRenderTextureSize","MAX_VERTEX_ATTRIBS","maxVaryingVectors","MAX_VARYING_VECTORS","maxFragmentUniformVectors","maxVertexUniformVectors","MAX_VERTEX_UNIFORM_VECTORS","shaderFloatPrecision","standardDerivatives","maxAnisotropy","astc","bptc","s3tc_srgb","pvrtc","etc1","etc2","textureAnisotropicFilterExtension","uintIndices","fragmentDepthSupported","timerQuery","supportOcclusionQuery","canUseTimestampForTimerQuery","maxMSAASamples","colorBufferFloat","blendFloat","supportFloatTexturesResolve","rg11b10ufColorRenderable","colorBufferHalfFloat","textureFloat","textureHalfFloat","textureHalfFloatRender","textureFloatLinearFiltering","textureFloatRender","textureHalfFloatLinearFiltering","vertexArrayObject","instancedArrays","textureLOD","texelFetch","blendMinMax","multiview","oculusMultiview","depthTextureExtension","canUseGLInstanceID","canUseGLVertexID","supportComputeShaders","supportSRGBBuffers","supportTransformFeedbacks","textureMaxLevel","texture2DArrayMaxLayerCount","MAX_ARRAY_TEXTURE_LAYERS","disableMorphTargetTexture","textureNorm16","blendParametersPerTarget","dualSourceBlending","supportReadWriteStorageTextures","_glVersion","VERSION","rendererInfo","_glRenderer","_glVendor","UNMASKED_VENDOR_WEBGL","VENDOR","RENDERER","HALF_FLOAT_OES","RGBA16F","RGBA32F","DEPTH24_STENCIL8","getQuery","getQueryEXT","TIMESTAMP_EXT","QUERY_COUNTER_BITS_EXT","MAX_TEXTURE_MAX_ANISOTROPY_EXT","_canRenderToFloatFramebuffer","R16_EXT","RG16_EXT","RGB16_EXT","RGBA16_EXT","R16_SNORM_EXT","RG16_SNORM_EXT","RGB16_SNORM_EXT","RGBA16_SNORM_EXT","oesDrawBuffersIndexed","blendEquationSeparateiOES","blendEquationIndexed","blendEquationiOES","blendFuncSeparateiOES","blendFuncIndexed","blendFunciOES","colorMaskIndexed","colorMaskiOES","disableiOES","enableiOES","COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR","COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR","COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT","COMPRESSED_SRGB_S3TC_DXT1_EXT","COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT","COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT","COMPRESSED_SRGB8_ETC2","COMPRESSED_SRGB8_ALPHA8_ETC2_EAC","MAX_SAMPLES","maxDrawBuffers","MAX_DRAW_BUFFERS","drawBuffers","drawBuffersWEBGL","MAX_DRAW_BUFFERS_WEBGL","DRAW_FRAMEBUFFER","FRAMEBUFFER","UNSIGNED_INT_24_8","UNSIGNED_INT_24_8_WEBGL","vertexArrayObjectExtension","createVertexArray","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","instanceExtension","drawArraysInstanced","drawArraysInstancedANGLE","drawElementsInstanced","drawElementsInstancedANGLE","vertexAttribDivisor","vertexAttribDivisorANGLE","vertexhighp","getShaderPrecisionFormat","HIGH_FLOAT","fragmenthighp","precision","vertexmedp","MEDIUM_FLOAT","fragmentmedp","blendMinMaxExtension","MAX","MAX_EXT","MIN","MIN_EXT","_glSRGBExtensionValues","SRGB","WebGL2RenderingContext","SRGB8","SRGB8_ALPHA8","sRGBExtension","SRGB_EXT","SRGB_ALPHA_EXT","forceSRGBBufferSupportState","slot","supportRenderAndCopyToLodForFloatTextures","supportDepthStencilTexture","supportShadowSamplers","allowTexturePrefiltering","supportCSM","basisNeedsPOT","support3DTextures","needTypeSuffixInShaderConstants","supportMSAA","supportSSAO2","supportIBLShadows","supportExtendedTextureFormats","supportSwitchCaseInShader","supportSyncTextureRead","needToAlwaysBindUniformBuffers","supportRenderPasses","supportSpriteInstancing","forceVertexBufferStrideAndOffsetMultiple4Bytes","_checkNonFloatVertexBuffersDontRecreatePipelineContext","_prepareWorkingCanvas","_workingCanvas","_workingContext","getInfo","getGlInfo","vendor","renderer","extractDriverInfo","glInfo","useScreen","_currentRenderTarget","framebufferWidth","drawingBufferWidth","framebufferHeight","drawingBufferHeight","applyStates","backBuffer","setBackBufferColor","textureFormat","_TempClearColorUint32","clearBufferuiv","COLOR","_TempClearColorInt32","clearBufferiv","clearColor","COLOR_BUFFER_BIT","clearDepth","DEPTH_BUFFER_BIT","clearStencil","stencilClearValue","STENCIL_BUFFER_BIT","_clearColorAttachment","attachmentIndex","unsigned","_TempClearColorFloat32","clearBufferfv","_viewportCached","_badOS","flushFramebuffer","performanceMonitor","webglRtWrapper","_resolveAndGenerateMipMapsFramebuffer","_bindUnboundFramebuffer","_framebuffer","framebufferTextureLayer","COLOR_ATTACHMENT0","lodLevel","layer","_currentLOD","framebufferTexture2D","TEXTURE_CUBE_MAP_POSITIVE_X","faceIndex","_depthStencilTexture","depthStencilTexture","_depthStencilTextureWithStencil","DEPTH_STENCIL_ATTACHMENT","DEPTH_ATTACHMENT","attachment","_MSAAFramebuffer","forceFullscreenViewport","setViewport","cullBackFaces","culling","reverseSide","CW","CCW","disableGenerateMipMaps","disableAutomaticMSAAResolve","isMulti","resolveMultiFramebuffer","resolveFramebuffer","generateMipMapsMultiFramebuffer","generateMipMapsFramebuffer","framebuffer","_currentFramebuffer","bindFramebuffer","_currentFrameBufferIsDefaultFrameBuffer","_getTextureTarget","_bindTextureDirectly","generateMipmap","onBeforeUnbind","generateMipmaps","bufferBits","_generateDepthBuffer","resolveMSAADepth","_generateStencilBuffer","resolveMSAAStencil","READ_FRAMEBUFFER","blitFramebuffer","NEAREST","flush","restoreDefaultFramebuffer","unBindFramebuffer","_resetVertexBufferBinding","bindArrayBuffer","_cachedVertexBuffers","createVertexBuffer","_updatable","_label","_createVertexBuffer","STATIC_DRAW","vbo","createBuffer","bufferData","ARRAY_BUFFER","usage","references","createDynamicVertexBuffer","DYNAMIC_DRAW","_resetIndexBufferBinding","bindIndexBuffer","_cachedIndexBuffer","WebGLDataBuffer","_normalizeIndexData","ELEMENT_ARRAY_BUFFER","updatable","_unbindVertexArrayObject","_bindBuffer","uniformLocation","getUniformBlockIndex","uniformBlockBinding","_currentBoundBuffer","bindBuffer","updateArrayBuffer","bufferSubData","indx","pointer","active","vertexAttribIPointer","vertexAttribPointer","_bindIndexBufferWithCache","indexBuffer","_bindVertexBuffersAttributes","vertexBuffers","overrideVertexBuffers","unbindAllAttributes","ai","vertexBuffer","enableVertexAttribArray","getBuffer","_vertexAttribPointer","getIsInstanced","getInstanceDivisor","vao","bindVertexArrayObject","_cachedVertexArrayObject","bindBuffersDirectly","vertexDeclaration","vertexStrideSize","_cachedEffectForVertexBuffers","attributesCount","bindBuffers","unbindInstanceAttributes","boundBuffer","ul","instancesBuffer","offsetLocation","releaseVertexArrayObject","deleteBuffer","updateAndBindInstancesBuffer","offsetLocations","bindInstancesBuffer","computeStride","attributesInfo","attributeSize","attributeName","attributeType","divisor","disableInstanceAttributeByName","attributeLocation","disableInstanceAttribute","shouldClean","disableAttributeByIndex","disableVertexAttribArray","indexStart","indexCount","drawElementsType","useTriangles","instancesCount","drawPointClouds","verticesStart","verticesCount","drawArraysType","drawMode","_drawMode","indexFormat","mult","drawElements","_reportDrawCall","fillMode","drawArrays","TRIANGLES","POINTS","LINES","LINE_LOOP","LINE_STRIP","TRIANGLE_STRIP","TRIANGLE_FAN","webGLPipelineContext","_currentProgram","_setProgram","deleteProgram","_getGlobalDefines","vertexToken","fragmentToken","globalDefines","isOptions","fullDefines","compiledEffect","getShaderSource","createRawShaderProgram","createShaderProgram","WebGLPipelineContext","createMaterialContext","createDrawContext","createRawShaderProgramInjection","createShaderProgramInjection","loadFileInjection","webGLRenderingState","COMPLETION_STATUS_KHR","oldHandler","getUniforms","getUniformLocation","getAttribLocation","uniform1i","uniform2i","uniform3i","uniform4i","uniform1iv","uniform2iv","uniform3iv","uniform4iv","uniform1ui","uniform2ui","uniform3ui","uniform4ui","uniform1uiv","uniform2uiv","uniform3uiv","uniform4uiv","uniform1fv","uniform2fv","uniform3fv","uniform4fv","uniformMatrix4fv","uniformMatrix3fv","uniformMatrix2fv","uniform1f","uniform2f","uniform3f","uniform4f","_applyColorWriteState","colorMask","bruteForce","preventCacheWipeBetweenFrames","_resetAlphaMode","UNPACK_PREMULTIPLY_ALPHA_WEBGL","_getSamplingParameters","magFilter","minFilter","LINEAR_MIPMAP_NEAREST","LINEAR","hasMipMaps","LINEAR_MIPMAP_LINEAR","NEAREST_MIPMAP_LINEAR","NEAREST_MIPMAP_NEAREST","mag","_createTexture","createMipMaps","createMSAATexture","isDepthTexture","hasStencil","layers","filters","sizedFormat","_getInternalFormatFromDepthTextureFormat","internalFormat","DEPTH_STENCIL","DEPTH_COMPONENT","_getInternalFormat","texImage3D","face","texImage2D","texParameteri","TEXTURE_MAG_FILTER","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","TEXTURE_COMPARE_FUNC","TEXTURE_COMPARE_MODE","COMPARE_REF_TO_TEXTURE","renderBuffer","_setupFramebufferDepthAttachments","_createRenderBuffer","_getRGBABufferInternalSizedFormat","_prepareWebGLTexture","potWidth","potHeight","continuationCallback","isPot","_getTexImageParametersForCreateTexture","tip","drawImage","_rescaleTexture","babylonFormat","onComplete","_unpackFlipY","UNPACK_FLIP_Y_WEBGL","_getUnpackAlignement","UNPACK_ALIGNMENT","_setTextureParameterInteger","_getTextureWrapMode","TEXTURE_WRAP_R","_uploadCompressedDataToTextureDirectly","lod","webGLHardwareTexture","texStorage2D","memoryAllocated","compressedTexSubImage2D","compressedTexImage2D","_uploadDataToTextureDirectly","imageData","babylonInternalFormat","useTextureWidthAndHeight","lodMaxWidth","LOG2E","lodMaxHeight","updateTextureData","xOffset","yOffset","targetForBinding","texSubImage2D","_uploadArrayBufferViewToTexture","bindTarget","_prepareWebGLTextureContinuation","processFunction","hasDepth","STENCIL_INDEX8","DEPTH_COMPONENT16","DEPTH_COMPONENT24","DEPTH_COMPONENT32F","DEPTH32F_STENCIL8","_getWebGLTextureTypeFromDepthTextureFormat","FLOAT_32_UNSIGNED_INT_24_8_REV","generateStencilBuffer","generateDepthBuffer","depthTextureFormat","dontBindRenderBufferToFrameBuffer","STENCIL_ATTACHMENT","msInternalFormat","unbindBuffer","createRenderbuffer","_updateRenderBuffer","bindRenderbuffer","RENDERBUFFER","renderbufferStorage","framebufferRenderbuffer","unbindAllTextures","_deleteTexture","release","useProgram","getSamplers","_activeChannel","activeTexture","TEXTURE0","wasPreviouslyBound","isTextureForRendering","_associatedChannel","forTextureDataUpdate","_activateCurrentTexture","bindTexture","_bindSamplerUniformToChannel","_setTexture","sourceSlot","_currentState","REPEAT","video","getInternalTexture","videoInternalTexture","delayLoad","isPartOfTextureArray","needToBind","coordinatesMode","textureWrapMode","_setAnisotropicLevel","_textureUnits","anisotropicFilterExtension","_setTextureParameterFloat","TEXTURE_MAX_ANISOTROPY_EXT","texParameterf","deleteFramebuffer","loseContextOnDispose","loseContext","attachContextLostEvent","attachContextRestoredEvent","_canRenderToFramebuffer","_canRenderToHalfFloatFramebuffer","RGBA","_getWebGLTextureType","fb","createFramebuffer","checkFramebufferStatus","successful","FRAMEBUFFER_COMPLETE","readFormat","readType","readPixels","UNSIGNED_SHORT_4_4_4_4","UNSIGNED_SHORT_5_5_5_1","UNSIGNED_SHORT_5_6_5","UNSIGNED_INT_2_10_10_10_REV","UNSIGNED_INT_10F_11F_11F_REV","UNSIGNED_INT_5_9_9_9_REV","ALPHA","LUMINANCE","LUMINANCE_ALPHA","RED","RG","RGB","RED_INTEGER","RG_INTEGER","RGB_INTEGER","RGBA_INTEGER","R8_SNORM","RG8_SNORM","RGB8_SNORM","R8I","RG8I","RGB8I","RGBA8I","R8","RG8","RGB8","RGBA8","R8UI","RG8UI","RGB8UI","RGBA8UI","R16I","RG16I","RGB16I","R16UI","RG16UI","RGB16UI","R32I","RG32I","RGB32I","R32UI","RG32UI","RGB32UI","R32F","RG32F","RGB32F","R16F","RG16F","RGB16F","RGB565","R11F_G11F_B10F","RGB9_E5","RGBA4","RGB5_A1","RGB10_A2","RGB10_A2UI","hasAlpha","flushRenderer","numChannels","dataLength","IsSupportedAsync","IsSupported","_HasMajorPerformanceCaveat","_IsSupported","tempcanvas","WebGLRenderingContext","HasMajorPerformanceCaveat","failIfMajorPerformanceCaveat","_Registered$9X","updateDynamicVertexBuffer","Buffer","postponeInternalCreation","instanced","useBytes","_isAlreadyOwned","RegisterEngineDynamicBuffer","_instanced","_divisor","VertexBuffer","getStrideSize","updateDirectly","vertexCount","_increaseReferences","instanceDivisor","_instanceDivisor","isInstanced","_computeHashCode","_maxVerticesCount","getData","updatableOrOptions","takeBufferOwnership","_ownsBuffer","_kind","vertexData","VertexBufferGetDataType","VertexBufferDeduceStride","_alignBuffer","hashCode","_GetTypeHashIndex","isUpdatable","getFloatData","VertexBufferGetTypeByteLength","VertexBufferForEach","_Registered$9W","DeduceStride","GetDataType","ForEach","VertexBufferGetFloatData","hit","pickedPoint","thinInstanceIndex","ray","originMesh","aimTransform","gripTransform","useWorldCoordinates","useVerticesNormals","pickedMesh","isVerticesDataPresent","tmp0","tmp1","getVerticesData","normal0","normals","faceId","bu","normal1","bv","normal2","positions","vertex1","vertex2","vertex3","p1p2","p3p2","thinMatrixData","_thinInstanceDataStorage","matrixData","tm","wm","nonUniformScaling","transformNormalToWorld","normalForDirectionChecking","getTextureCoordinates","uvSet","getIndices","uvs","uv0","uv1","uv2","PostProcessManager","_vertexBuffers","_activePostProcesses","onBeforeRenderObservable","vertices","_buildIndexBuffer","createIndexBuffer","_getActivePostProcesses","activePostProcesses","postProcess","vb","_prepareFrame","sourceTexture","activeCamera","postProcessesEnabled","activate","numPostsProcesses","targetTexture","doNotBindFrambuffer","_debugInsertMarker","pp","_prepareBuffers","onAfterRenderObservable","setDepthWrite","_postProcesses","_outputTexture","doNotPresent","TempFinalMat","TempMat1","TempMat2","FloatingOriginCurrentScene","refArray","worldArray","viewMatrix","OffsetWorldToRef","eyeAtCamera","GetFullOffsetView","viewArray","OffsetViewProjectionToRef","OffsetViewToRef","GetOffsetTransformMatrices","viewMatrices","projectionMatrices","resultArray","cascadeIndex","GetFullOffsetViewProjectionToRef","projectionMatrix","viewProjection","floatingOriginOffset","OffsetWorldViewToRef","getViewMatrix","getProjectionMatrix","OffsetWorldViewProjectionToRef","getTransformMatrix","lowercaseUniformName","UniformBufferInternal","EffectInternal","OriginalUpdateMatrixForUniform","OriginalSetMatrix","_updateMatrixForUniformOverride","_setMatrixOverride","GetOffsetMatrix","RenderingGroup","opaqueSortCompareFn","_opaqueSortCompareFn","PainterSortCompare","_renderOpaque","_renderOpaqueSorted","alphaTestSortCompareFn","_alphaTestSortCompareFn","_renderAlphaTest","_renderAlphaTestSorted","transparentSortCompareFn","_transparentSortCompareFn","defaultTransparentSortCompare","_renderTransparent","_renderTransparentSorted","_transparentSubMeshes","_alphaTestSubMeshes","_depthOnlySubMeshes","_particleSystems","_edgesRenderers","SmartArrayNoDuplicate","disableDepthPrePass","customRenderFunction","renderParticles","activeMeshes","renderDepthOnlyMeshes","renderOpaqueMeshes","renderAlphaTestMeshes","renderTransparentMeshes","customRenderTransparentSubMeshes","_opaqueSubMeshes","_renderSprites","_renderParticles","onBeforeTransparentRendering","useOrderIndependentTransparency","excludedMeshes","depthPeelingRenderer","render","edgesRendererIndex","setStencilBuffer","subMeshes","_RenderSorted","sortCompareFn","transparent","subMesh","subIndex","globalPosition","_ZeroVector","_alphaIndex","getMesh","_distanceToCamera","boundingSphere","centerWorld","cameraPosition","sortedArray","_activeMeshesFrozenButKeepClipping","isInFrustum","_frustumPlanes","getMaterial","material","needDepthPrePass","backToFrontSortCompare","meshA","meshB","prepare","prepareSprites","_empty","_spriteManagers","_renderingGroup","_edgesRenderer","dispatchSprites","spriteManager","dispatchParticles","particleSystem","onBeforeParticlesRenderingObservable","particleIndex","layerMask","emitter","_activeParticles","onAfterParticlesRenderingObservable","spritesEnabled","onBeforeSpritesRenderingObservable","onAfterSpritesRenderingObservable","RenderingGroupInfo","RenderingManager","_disableDepthPrePass","_renderingGroups","maintainStateBetweenFrames","_maintainStateBetweenFrames","restoreDispachedFlags","meshes","_wasDispatched","spriteManagers","particleSystems","_useSceneAutoClearSetup","_autoClearDepthStencil","_customOpaqueSortCompareFn","_customAlphaTestSortCompareFn","_customTransparentSortCompareFn","_renderingGroupInfo","MIN_RENDERINGGROUPS","MAX_RENDERINGGROUPS","autoClear","renderingGroups","getRenderingGroup","renderingGroupId","_clearDepthStencilBuffer","_depthStencilBufferAlreadyCleaned","info","spriteManagersToRender","manager","renderingGroup","renderingGroupMask","AUTOCLEAR","getAutoClearDepthStencilSetup","_beforeRenderingGroupDrawStage","_afterRenderingGroupDrawStage","onAfterRenderingGroupObservable","resetSprites","freeRenderingGroups","dispatch","setRenderingOrder","setRenderingAutoClearDepthStencil","autoClearDepthStencil","SceneComponentConstants","NAME_EFFECTLAYER","NAME_LAYER","NAME_LENSFLARESYSTEM","NAME_BOUNDINGBOXRENDERER","NAME_PARTICLESYSTEM","NAME_GAMEPAD","NAME_SIMPLIFICATIONQUEUE","NAME_GEOMETRYBUFFERRENDERER","NAME_PREPASSRENDERER","NAME_DEPTHRENDERER","NAME_DEPTHPEELINGRENDERER","NAME_POSTPROCESSRENDERPIPELINEMANAGER","NAME_SPRITE","NAME_SUBSURFACE","NAME_OUTLINERENDERER","NAME_PROCEDURALTEXTURE","NAME_SHADOWGENERATOR","NAME_OCTREE","NAME_PHYSICSENGINE","NAME_AUDIO","NAME_FLUIDRENDERER","NAME_IBLCDFGENERATOR","NAME_CLUSTEREDLIGHTING","STEP_ISREADYFORMESH_EFFECTLAYER","STEP_ISREADYFORMESH_DEPTHRENDERER","STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER","STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER","STEP_PREACTIVEMESH_BOUNDINGBOXRENDERER","STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER","STEP_BEFORECAMERADRAW_PREPASS","STEP_BEFORECAMERADRAW_EFFECTLAYER","STEP_BEFORECAMERADRAW_LAYER","STEP_BEFORERENDERTARGETDRAW_PREPASS","STEP_BEFORERENDERTARGETDRAW_LAYER","STEP_BEFORERENDERINGMESH_PREPASS","STEP_BEFORERENDERINGMESH_OUTLINE","STEP_AFTERRENDERINGMESH_PREPASS","STEP_AFTERRENDERINGMESH_OUTLINE","STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW","STEP_AFTERRENDERINGGROUPDRAW_BOUNDINGBOXRENDERER","STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE","STEP_BEFORECLEAR_PROCEDURALTEXTURE","STEP_BEFORECLEAR_PREPASS","STEP_BEFORERENDERTARGETCLEAR_PREPASS","STEP_AFTERRENDERTARGETDRAW_PREPASS","STEP_AFTERRENDERTARGETDRAW_LAYER","STEP_AFTERCAMERADRAW_PREPASS","STEP_AFTERCAMERADRAW_EFFECTLAYER","STEP_AFTERCAMERADRAW_LENSFLARESYSTEM","STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW","STEP_AFTERCAMERADRAW_LAYER","STEP_AFTERCAMERADRAW_FLUIDRENDERER","STEP_AFTERCAMERAPOSTPROCESS_LAYER","STEP_AFTERRENDERTARGETPOSTPROCESS_LAYER","STEP_AFTERRENDER_AUDIO","STEP_GATHERRENDERTARGETS_DEPTHRENDERER","STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER","STEP_GATHERRENDERTARGETS_SHADOWGENERATOR","STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER","STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER","STEP_GATHERACTIVECAMERARENDERTARGETS_FLUIDRENDERER","STEP_GATHERACTIVECAMERARENDERTARGETS_CLUSTEREDLIGHTING","STEP_POINTERMOVE_SPRITE","STEP_POINTERDOWN_SPRITE","STEP_POINTERUP_SPRITE","Stage","items","Create","component","PointerEventTypes","POINTERDOWN","POINTERUP","POINTERMOVE","POINTERWHEEL","POINTERPICK","POINTERTAP","POINTERDOUBLETAP","PointerInfoBase","PointerInfoPre","localX","localY","originalPickingInfo","skipOnPointerObservable","PointerInfo","pickInfo","_pickInfo","_generatePickInfo","inputManager","_inputManager","_pickMove","_setRayOnPointerInfo","KeyboardEventTypes","KEYDOWN","KEYUP","KeyboardInfo","KeyboardInfoPre","skipOnKeyboardObservable","DeviceType","PointerInput","NativePointerInput","DualShockInput","DualSenseInput","XboxInput","SwitchInput","DeviceInputEventType","EventConstants","DOM_DELTA_PIXEL","DOM_DELTA_LINE","DeviceEventFactory","deviceType","deviceSlot","inputIndex","deviceInputSystem","elementToAttachTo","pointerId","Keyboard","MouseWheelY","MouseWheelZ","_CreateWheelEvent","_CreatePointerEvent","_CreateMouseEvent","Mouse","pointerType","Touch","buttons","pollInput","LeftClick","RightClick","MiddleClick","Move","button","deltaMode","deltaX","deltaY","MouseWheelX","deltaZ","_CreateEvent","Horizontal","movementX","movementY","offsetX","offsetY","_CheckNonCharacterKeys","clientX","clientY","_CreateKeyboardEvent","isKeyboardActive","isDeviceAvailable","altKey","ctrlKey","metaKey","shiftKey","onDeviceConnected","onDeviceDisconnected","onInputChanged","_nativeInput","DeviceInputSystem","CreateDeviceEvent","_createDummyNativeInput","MAX_POINTER_INPUTS","WebDeviceInputSystem","_inputs","_keyboardActive","_pointerActive","_pointerMacOsChromeOutEvent","_eventsAttached","_mouseId","_isUsingFirefox","_isUsingChromium","_maxTouchPoints","_gamepadDisconnectedEvent","_eventPrefix","_onDeviceConnected","_onDeviceDisconnected","_enableEvents","_usingMacOs","_metaKeys","_onEngineViewChanged","device","DualShock","DualSense","_updateDevice","_onInputChanged","_elementToAttachTo","_disableEvents","inputElement","getInputElement","inputs","deviceSlotKey","tabIndex","_handleKeyActions","_handlePointerActions","_handleGamepadActions","_checkForConnectedDevices","_keyboardBlurEvent","_keyboardDownEvent","_pointerMoveEvent","_pointerUpEvent","_wheelEventName","_pointerWheelEvent","_gamepadConnectedEvent","_pointerInputClearObserver","getGamepads","gamepads","gamepad","_addGamePad","_addPointerDevice","_getGamepadDeviceType","_gamepads","_registerDevice","axes","currentX","currentY","numberOfInputs","kbKey","deviceEvent","_keyboardUpEvent","maxTouchPoints","_activeTouchIds","_getPointerType","_usingSafari","_pointerDownEvent","previousHorizontal","previousVertical","Vertical","pointerLockElement","setPointerCapture","shouldProcessPointerUp","hasPointerCapture","releasePointerCapture","BrowserForward","_pointerCancelTouch","onmousewheel","passiveSupported","noop","wheelDelta","_pointerCancelEvent","_pointerLeaveEvent","_pointerBlurEvent","gp","valueOf","deviceName","Xbox","Switch","Generic","touches","DeviceSource","onInputChangedObservable","_deviceInputSystem","getInput","InternalDeviceSourceManager","_registeredManagers","_devices","_addDevice","unregisterManager","numberOfDeviceTypes","deviceSource","_removeDevice","NativeDeviceInputSystem","getDeviceSource","_firstDevice","_deviceSourceManager","devices","onDeviceConnectedObservable","onDeviceDisconnectedObservable","registerManager","_updateFirstDevices","_singleClick","_doubleClick","_hasSwiped","_ignore","singleClick","doubleClick","hasSwiped","ignore","InputManager","_alreadyAttached","_meshPickProceed","_currentPickResult","_previousPickResult","_activePointerIdsCount","_doubleClickOccured","_isSwiping","_swipeButtonPressed","_skipPointerTap","_isMultiTouchGesture","_pointerX","_pointerY","_startingPointerPosition","_previousStartingPointerPosition","_startingPointerTime","_previousStartingPointerTime","_pointerCaptures","_meshUnderPointerId","_movePointerInfo","_latestPointerMoveEvents","_cameraObserverCount","_delayedClicks","_pointerOverMesh","unTranslatedPointer","_unTranslatedPointerX","_unTranslatedPointerY","canvasRect","getInputElementClientRect","_processPointerMove","pickResult","doNotHandleCursors","defaultCursor","_setCursorAndPointerOverMesh","isMeshPicked","pointerInfo","onPointerMove","onPointerObservable","_ImportHelper","_IsPickingAvailable","createPickingRay","onPointerPick","_checkPrePointerObservable","pi","nearInteractionPickingInfo","onPrePointerObservable","pick","pointerMovePredicate","pointerMoveFastCheck","cameraToUseForPointers","pointerMoveTrianglePredicate","_updateMeshUnderPointer","constantlyUpdateMeshUnderPointer","skipPointerMovePicking","_ensurePointerMovePredicate","unTranslatedPointerX","unTranslatedPointerY","_isPointerMovePickable","isPickable","enablePointerMoveEvents","setPointerOverMesh","hoverCursor","pointerEventInit","_processPointerDown","_pickedDownMesh","LongPressDelay","_isPointerSwiping","CreateNew","_pointerDownStage","onPointerDown","doubleTap","_ClickInfo","clickInfo","_processPointerUp","_pickedUpMesh","doubleClickActionManager","pickedDownActionManager","onPointerUp","isPointerCaptured","attachControl","attachUp","attachDown","attachMove","detachControl","_alreadyAttachedTo","_initActionManager","skipPointerUpPicking","_checkForPicking","pointerUpPredicate","pointerUpFastCheck","pointerUpTrianglePredicate","act","DoubleClickDelay","btn","_previousButtonPressed","checkPicking","obs1","obs2","checkSingleClickImmediately","ExclusiveDoubleClickMode","HasSpecificTrigger","cb","needToIgnoreNext","delayedClick","timeoutId","_delayedSimpleClick","checkDoubleClick","_onPointerMove","_updatePointerPosition","DragMovementThreshold","_verifyPointerLock","PickingInfo","freeIndex","_activePointerIds","prevEvt","preventDefaultOnPointerDown","focus","pointerDownPredicate","skipPointerDownPicking","pointerDownFastCheck","pointerDownTrianglePredicate","_onPointerUp","pointerIdIndex","preventDefaultOnPointerUp","_onKeyDown","onPreKeyboardObservable","onKeyboardObservable","CreateNewFromScene","_onKeyUp","_originMouseEvent","BrowserBack","_onPointerDown","_internalAbstractMeshDataInfo","_pointerOverDisableMeshTesting","underPointerMesh","onMeshUnderPointerUpdatedObservable","_invalidateMesh","PerfCounter","_min","_max","average","_average","lastSecAverage","_lastSecAverage","_current","total","_totalAccumulated","_totalValueCount","_startMonitoringTime","_hasResult","_hasCurrentValue","_lastSecAccumulated","_lastSecTime","_lastSecValueCount","Enabled","newCount","fetchResult","_fetchResult","beginMonitoring","endMonitoring","newFrame","fetchNewFrame","currentTime","Plane","norm","magnitude","invertedMatrix","normalX","normalY","normalZ","finalD","dotCoordinate","point1","point2","point3","x1","y1","z1","pyth","invPyth","isFrontFacingTo","signedDistanceTo","FromPoints","copyFromPoints","FromPositionAndNormal","FromPositionAndNormalToRef","SignedDistanceToPlaneFromPositionAndNormal","Frustum","GetPlanes","frustumPlanes","GetPlanesToRef","GetNearPlaneToRef","frustumPlane","GetFarPlaneToRef","GetLeftPlaneToRef","GetRightPlaneToRef","GetTopPlaneToRef","GetBottomPlaneToRef","IsPointInFrustum","UniqueIdGenerator","UniqueId","_UniqueIdCounter","LightConstants","shadowEnabled","renderPriority","FALLOFF_DEFAULT","FALLOFF_PHYSICAL","FALLOFF_GLTF","FALLOFF_STANDARD","LIGHTMAP_DEFAULT","LIGHTMAP_SPECULAR","LIGHTMAP_SHADOWSONLY","INTENSITYMODE_AUTOMATIC","INTENSITYMODE_LUMINOUSPOWER","INTENSITYMODE_LUMINOUSINTENSITY","INTENSITYMODE_ILLUMINANCE","INTENSITYMODE_LUMINANCE","LIGHTTYPEID_POINTLIGHT","LIGHTTYPEID_DIRECTIONALLIGHT","LIGHTTYPEID_SPOTLIGHT","LIGHTTYPEID_HEMISPHERICLIGHT","LIGHTTYPEID_RECT_AREALIGHT","_29","_30","_31","_32","_33","_34","_35","_36","_37","_38","_39","_40","_41","_42","_43","_44","_45","_46","_47","_48","_49","_50","_51","_52","_53","_54","_55","_56","_57","_58","_59","_60","_61","_62","_63","_64","_65","_66","_67","_68","_69","_70","_71","_72","_73","_74","_75","_76","_77","_78","_79","_80","_81","TempVect1","TempVect2","ScenePerformancePriority","DefaultMaterialFactory","CollisionCoordinatorFactory","_clearColor","onClearColorChangedObservable","imageProcessingConfiguration","_imageProcessingConfiguration","performancePriority","_performancePriority","skipFrustumClipping","_renderingManager","onScenePerformancePriorityChangedObservable","forceWireframe","_forceWireframe","_skipFrustumClipping","forcePointsCloud","_forcePointsCloud","environmentTexture","_environmentTexture","onEnvironmentTextureChangedObservable","lights","transformNodes","skeletons","beforeRender","_onBeforeRenderObserver","afterRender","_onAfterRenderObserver","beforeCameraRender","_onBeforeCameraRenderObserver","onBeforeCameraRenderObservable","afterCameraRender","_onAfterCameraRenderObserver","onAfterCameraRenderObservable","_pointerPickingConfiguration","_forcedViewPosition","bindEyePosition","variableName","isVector3","eyePosition","_eyePosition","invertNormal","useRightHandedSystem","_mirroredCameraPosition","eyePos","offsetEyePos","finalizeSceneUbo","ubo","getSceneUniformBuffer","_useRightHandedSystem","setStepId","newStepId","_currentStepId","_currentInternalStep","fogEnabled","_fogEnabled","fogMode","_fogMode","prePass","prePassRenderer","defaultRT","shadowsEnabled","_shadowsEnabled","lightsEnabled","_lightsEnabled","activeCameras","_activeCameras","_unObserveActiveCameras","_ObserveArray","onActiveCamerasChanged","_activeCamera","onActiveCameraChanged","_hasDefaultMaterial","Scene","_OriginalDefaultMaterialFactory","defaultMaterial","_defaultMaterial","texturesEnabled","_texturesEnabled","frameGraph","_frameGraph","_currentCustomRenderFunction","_renderWithFrameGraph","skeletonsEnabled","_skeletonsEnabled","collisionCoordinator","_collisionCoordinator","renderingManager","_transientComponents","register","_addComponent","_components","serializableComponent","addFromContainer","_serializableComponents","_getComponent","_blockEntityCollection","autoClearDepthAndStencil","ambientColor","environmentIntensity","iblIntensity","multiMaterials","materials","morphTargetManagers","geometries","objectRenderers","effectLayers","sounds","lensFlareSystems","proceduralTextures","disableOfflineSupportExceptionRules","onAfterRenderCameraObservable","onBeforeAnimationsObservable","onAfterAnimationsObservable","onBeforeDrawPhaseObservable","onAfterDrawPhaseObservable","onReadyObservable","onBeforeActiveMeshesEvaluationObservable","onAfterActiveMeshesEvaluationObservable","onDataLoadedObservable","onNewCameraAddedObservable","onCameraRemovedObservable","onNewLightAddedObservable","onLightRemovedObservable","onNewGeometryAddedObservable","onGeometryRemovedObservable","onNewTransformNodeAddedObservable","onTransformNodeRemovedObservable","onNewMeshAddedObservable","onMeshRemovedObservable","onNewSkeletonAddedObservable","onSkeletonRemovedObservable","onNewParticleSystemAddedObservable","onParticleSystemRemovedObservable","onNewAnimationGroupAddedObservable","onAnimationGroupRemovedObservable","onNewMaterialAddedObservable","onNewMultiMaterialAddedObservable","onMaterialRemovedObservable","onMultiMaterialRemovedObservable","onNewTextureAddedObservable","onTextureRemovedObservable","onNewFrameGraphAddedObservable","onFrameGraphRemovedObservable","onNewObjectRendererAddedObservable","onObjectRendererRemovedObservable","onNewPostProcessAddedObservable","onPostProcessRemovedObservable","onNewEffectLayerAddedObservable","onEffectLayerRemovedObservable","onBeforeRenderTargetsRenderObservable","onAfterRenderTargetsRenderObservable","onBeforeStepObservable","onAfterStepObservable","onBeforeRenderingGroupObservable","onMeshImportedObservable","onAnimationFileImportedObservable","PointerPickingConfiguration","_timeAccumulator","fogColor","fogDensity","fogStart","fogEnd","collisionsEnabled","renderTargetsEnabled","dumpNextRenderTargets","customRenderTargets","probesEnabled","_renderId","_renderingMeshEvaluationDepth","_intermediateRendering","_defaultFrameBufferCleared","_viewUpdateFlag","_toBeDisposed","_isDisposing","_isReadyChecks","dispatchAllSubMeshesOfActiveMeshes","_activeMeshes","_processedMaterials","_renderTargets","_activeParticleSystems","_activeSkeletons","_transformMatrix","requireLightSorting","_beforeCameraUpdateStage","_beforeClearStage","_beforeRenderTargetClearStage","_gatherRenderTargetsStage","_gatherActiveCameraRenderTargetsStage","_isReadyForMeshStage","_beforeEvaluateActiveMeshStage","_evaluateSubMeshStage","_preActiveMeshStage","_cameraDrawRenderTargetStage","_beforeCameraDrawStage","_beforeRenderTargetDrawStage","_beforeRenderingMeshStage","_afterRenderingMeshStage","_afterCameraDrawStage","_afterCameraPostProcessStage","_afterRenderTargetDrawStage","_afterRenderTargetPostProcessStage","_afterRenderStage","_pointerMoveStage","_pointerUpStage","_geometriesByUniqueId","_defaultMeshCandidates","_defaultSubMeshCandidates","onReadyTimeoutObservable","onReadyTimeoutDuration","_timeoutChecksStartTime","_floatingOriginScene","_skipEvaluateActiveMeshesCompletely","_allowPostProcessClearColor","_getFloatingOriginScene","_blockMaterialDirtyMechanism","_perfCollector","defaultCameraLayerMask","fullOptions","defaultRenderableLayerMask","virtual","useFloatingOrigin","OverrideMatrixFunctions","_uid","postProcessManager","setDefaultCandidateProviders","useGeometryUniqueIdsMap","useMaterialMeshMap","useClonedMeshMap","getActiveMeshCandidates","_getDefaultMeshCandidates","getActiveSubMeshCandidates","_getDefaultSubMeshCandidates","getIntersectingSubMeshCandidates","localRay","getCollidingSubMeshCandidates","collider","_cachedMaterial","_cachedEffect","_cachedVisibility","isCachedMaterialInvalid","visibility","_totalVertices","totalVerticesPerfCounter","getActiveIndices","_activeIndices","totalActiveIndicesPerfCounter","getActiveParticles","activeParticlesPerfCounter","getActiveBones","_activeBones","activeBonesPerfCounter","getAnimationRatio","_animationRatio","setSceneUniformBuffer","createSceneUniformBuffer","simulatePointerMove","simulatePointerDown","simulatePointerUp","renderPassId","checkRenderTargets","_materialsRenderTargets","hardwareInstancedRendering","hasThinInstances","hasRenderTargetTextures","getRenderTargetTextures","isReadyForRendering","proceduralTexturesEnabled","proceduralTexture","effectLayer","isLayerReady","resetCachedMaterial","registerBeforeRender","unregisterBeforeRender","registerAfterRender","unregisterAfterRender","execFunc","executeOnceBeforeRender","_executeOnceBeforeRender","wasLoading","isLoading","getWaitingItemsCount","addIsReadyCheck","isReadyCheck","executeWhenReady","_executeWhenReadyTimeoutId","whenReadyAsync","_clearReadynessChecksData","resetLastAnimationTimeFrame","_viewMatrix","_projectionMatrix","_inverseProjectionMatrix","_multiviewSceneUboIsActive","viewR","projectionR","_multiviewSceneUbo","viewL","_projectionUpdateFlag","projectionL","_updateMultiviewUbo","_sceneUbo","trackUBOsInFrameOrOptions","sceneUbo","floatingOriginMode","addMesh","newMesh","recursive","_resyncLightSources","getChildMeshes","toRemove","removeMesh","addTransformNode","newTransformNode","_indexInSceneTransformNodesArray","removeTransformNode","lastNode","_executeActiveContainerCleanup","_removeLightSource","sortLightsByPriority","index2","removeMaterial","_indexInSceneMaterialArray","lastMaterial","frameGraphs","addLight","newLight","lightSources","CompareLightsPriority","addCamera","newCamera","addSkeleton","newSkeleton","addParticleSystem","newParticleSystem","addAnimation","newAnimation","addAnimationGroup","newAnimationGroup","addMultiMaterial","newMultiMaterial","addMaterial","newMaterial","addMorphTargetManager","newMorphTargetManager","addGeometry","newGeometry","addActionManager","newActionManager","addTexture","newTexture","addFrameGraph","newFrameGraph","addObjectRenderer","objectRenderer","addPostProcess","newPostProcess","addEffectLayer","newEffectLayer","getCameraByName","getAnimationGroupByName","_getMaterial","allowMultiMaterials","getMaterialByUniqueId","getMaterialById","getLastMaterialById","getTextureByUniqueId","getTextureByName","getCameraByUniqueId","getBoneById","skeletonIndex","boneIndex","getBoneByName","getLightByName","getLightById","getLightByUniqueId","getParticleSystemById","getGeometryById","_getGeometryByUniqueId","getFrameGraphByName","pushGeometry","geometry","removeGeometry","lastGeometry","getMeshesById","getTransformNodeById","getTransformNodeByUniqueId","getTransformNodesById","getMeshByUniqueId","getLastTransformNodeById","getLastEntryById","light","getTransformNodeByName","getLastSkeletonById","getSkeletonByUniqueId","getSkeletonById","getSkeletonByName","getMorphTargetManagerById","getMorphTargetById","managerIndex","morphTargetManager","getTarget","getMorphTargetByName","getPostProcessByName","postProcessIndex","uid","addExternalData","_externalData","StringDictionary","getExternalData","getOrAddExternalDataWithFactory","factory","getOrAddWithFactory","initialMesh","forcePush","freeProcessedMaterials","blockfreeActiveMeshesAndRenderingGroups","_preventFreeActiveMeshesAndRenderingGroups","freeActiveMeshes","renderList","_isInRenderingMeshEvaluation","freezeActiveMeshes","skipEvaluateActiveMeshes","freezeMeshes","keepFrustumCulling","objectRendererTasks","getTasksByClassName","task","_freezeActiveMeshes","_freezeActiveMeshesCancel","_RetryWithInterval","notCancelled","_isFrozen","_activeMeshesFrozen","unfreezeActiveMeshes","isTimeout","errMsg","updateTransformMatrix","_evaluateActiveMeshes","_freeze","_isActive","_unfreezeActiveMeshes","_unFreeze","container","_softwareSkinnedMeshes","psLength","currentLOD","isBlocked","_meshesForIntersections","meshToRender","customLODSelector","getLOD","billboardMode","_preActivate","alwaysSelectAsActiveMesh","_activate","_actAsRegularMesh","_onlyForInstances","_activeMesh","_postActivate","particlesEnabled","isStarted","computeBonesUsingShaders","applySkeleton","sourceMesh","hasInstances","isAnInstance","_evaluateSubMesh","leftCamera","_rigCameras","rightCamera","setTransformMatrix","_bindFrameBuffer","_useCurrentFrameBuffer","_multiviewTexture","outputRenderTarget","_clearFrameBuffer","_renderingMultiview","rtt","onClearObservable","skipInitialClear","isRightCamera","_cleared","_clear","_skipRendering","bindFrameBuffer","softwareSkinnedMeshIndex","rigParent","needRebind","currentBoundingBoxMeshList","boundingBoxRenderer","renderIndex","renderTarget","_shouldRender","hasSpecialRenderTargetCamera","fastSnapshotMode","_finalizeFrame","isIntermediate","_processSubCameras","_createMultiviewUbo","_renderForCamera","_useMultiviewToSingleView","_renderMultiviewToSingleView","_checkIntersections","actionIndex","otherMesh","areIntersecting","intersectsMesh","currentIntersectionInProgress","_intersectionsInProgress","parameterMesh","isDeterministicLockStep","MinDeltaTime","getDeltaTime","MaxDeltaTime","defaultFrameTime","defaultFPS","stepsTaken","maxSubSteps","getLockstepMaxSteps","internalSteps","physicsEnabled","_advancePhysicsEngineStep","isRigCamera","rigCameras","resetDrawCache","passId","updateCameras","_ignoreAnimations","forceUpdateWorldMatrix","_renderWithFrameGraphAfterBeforeRender","currentActiveCamera","findMainCamera","customIndex","_renderRenderTarget","_wasActiveLastFrame","useCameraPostProcess","dumpForDebug","ignoreAnimations","renderingMeshEvaluationDepth","_checkCameraRenderTarget","_registerTransientComponents","cameraIndex","cameraRigMode","freezeMaterials","unfreezeMaterials","unfreeze","importedMeshesFiles","activeRequests","_disposeList","ResetMatrixFunctions","itemsCopy","clearCachedVertexData","meshIndex","clearCachedData","cleanCachedTextureBuffer","baseTexture","getWorldExtends","filterPredicate","infiniteDistance","cameraViewSpace","createPickingRayToRef","enableDistantPicking","createPickingRayInCameraSpace","createPickingRayInCameraSpaceToRef","fastCheck","trianglePredicate","pickWithRay","multiPick","multiPickWithRay","getPointerOverMesh","_rebuildGeometries","rebuild","system","spriteMgr","_getByTags","listByTags","getMeshesByTags","getCamerasByTags","getLightsByTags","getMaterialByTags","getTransformNodesByTags","_forceBlockMaterialDirtyMechanism","blockMaterialDirtyMechanism","useOfflineSupport","_delayedFileRequests","requestToClear","_requestFile","_readFile","getPerfCollector","setActiveCameraByID","setActiveCameraById","getMaterialByID","getLastMaterialByID","getTextureByUniqueID","getCameraByID","getCameraByUniqueID","getBoneByID","getLightByID","getLightByUniqueID","getParticleSystemByID","getGeometryByID","getMeshByID","getMeshByUniqueID","getLastMeshByID","getMeshesByID","getTransformNodeByID","getTransformNodeByUniqueID","getTransformNodesByID","getNodeByID","getNodeById","getLastEntryByID","getLastSkeletonByID","_Registered$9V","_b$8","_c$6","_e$4","_f$4","_g$2","_h$2","_k$1","createOrUpdateSelectionOctree","_l$1","_o","createDefaultLight","_o$1","createDefaultCamera","_p","createDefaultCameraOrLight","_r","createDefaultSkybox","_q","_s","createDefaultEnvironment","_t","createDefaultVRExperience","_s$1","_u","createDefaultXRExperienceAsync","_t$1","_v","getGlowLayerByName","_u$1","getHighlightLayerByName","_v$1","getSelectionOutlineLayerByName","_w$1","removeLensFlareSystem","addLensFlareSystem","_y$1","_0","getLensFlareSystemByName","_1","getLensFlareSystemByID","_2","getLensFlareSystemById","_1$1","_3","getPhysicsEngine","_4","enablePhysics","_3$1","_5","disablePhysicsEngine","_4$1","_5$1","isPhysicsEnabled","_6","deleteCompoundImpostor","_7","removeReflectionProbe","_8","addReflectionProbe","_9","getBoundingBoxRenderer","_10","enableDepthRenderer","_11","disableDepthRenderer","_12","enableFluidRenderer","_13","disableFluidRenderer","_14","enableGeometryBufferRenderer","_15","disableGeometryBufferRenderer","_16","enableIblCdfGenerator","_17","disableIblCdfGenerator","_18","getOutlineRenderer","_19","enablePrePassRenderer","_20","disablePrePassRenderer","_21","enableSubSurfaceForPrePass","_22","disableSubSurfaceForPrePass","_23","pickSprite","_24","pickSpriteWithRay","_25","multiPickSprite","_26","multiPickSpriteWithRay","_27","setPointerOverSprite","_28","getPointerOverSprite","_Registered$9U","AddAnimationExtensions","Orientation","BezierCurve","Interpolate","f0","f1","f2","refinedT","refinedT2","Angle","radians","_radians","BetweenTwoPoints","delta","BetweenTwoVectors","product","cosVal","FromRadians","FromDegrees","degrees","Arc2","endPoint","startPoint","midPoint","startToMid","midToEnd","centerPoint","startAngle","a1","a2","a3","orientation","Path2","_points","_length","closed","addLineTo","newPoint","previousPoint","addArcTo","midX","midY","endX","endY","numberOfSegments","arc","increment","currentAngle","addQuadraticCurveTo","controlX","controlY","val0","val1","val2","addBezierCurveTo","originTangentX","originTangentY","destinationTangentX","destinationTangentY","val3","edgeLow","edgeHigh","edgeDx","edgeDy","perpEdge","isInside","lastPoint","area","normalizedLengthPosition","lengthPosition","bToA","previousOffset","nextOffset","dir","localOffset","Path3D","firstNormal","raw","alignTangentsWithPath","_curve","_distances","_tangents","_normals","_pointAtData","previousPointArrayIndex","subPosition","interpolateReady","interpolationMatrix","_raw","_alignTangentsWithPath","_compute","_binormals","_updatePointAtData","getTangentAt","interpolated","getNormalAt","getBinormalAt","getDistanceAt","getPreviousPointIndexAt","getSubPositionAt","getClosestPositionTo","smallestDistance","tangent","subLength","closestPosition","_start","curvePoints","getCurve","getPointAt","slicePoints","_getFirstNonNullVector","tg0","pp0","prev","prevNor","prevBinor","_getLastNonNullVector","curTang","nNVector","nLVector","_normalVector","vt","va","tgl","_updateInterpolationMatrix","_setPointAtData","interpolateTNB","currentPoint","currentLength","targetLength","parentIndex","tangentFrom","normalFrom","binormalFrom","tangentTo","normalTo","binormalTo","quatFrom","quatTo","Curve3","CreateQuadraticBezier","nbPoints","bez","CreateCubicBezier","v3","CreateHermiteSpline","t1","nSeg","hermite","CreateCatmullRomSpline","points","catmullRom","pointsCount","totalPoints","ArcThru3Points","second","third","steps","fullCircle","vec1","vec2","vec3","len4","len1Sq","len2Sq","len3Sq","len4Sq","center","dStep","_computeLength","curve","continuedPoints","getPoints","_easingMode","EasingFunction","EASINGMODE_EASEIN","setEasingMode","easingMode","easeInCore","EASINGMODE_EASEOUT","EASINGMODE_EASEINOUT","CircleEase","BackEase","amplitude","BounceEase","bounciness","bounces","num9","num15","num65","num13","num8","num7","CubicEase","ElasticEase","springiness","oscillations","exp","ExponentialEase","exponent","PowerEase","power","QuadraticEase","QuarticEase","QuinticEase","SineEase","BezierCurveEase","AnimationEvent","TargetedAnimation","targetId","targetUniqueId","AnimationGroup","syncWithMask","forceUpdate","_numActiveAnimatables","_animatables","disabled","retainsTarget","_targetedAnimations","targetedAnimation","_isStarted","isPlaying","_isPaused","_retainedCurrentFrame","_updateVirtualFrame","_virtualFrameStart","_virtualFrameStartTime","_loopAnimation","_isAdditive","setWeightForAllAnimatables","targetedAnimations","_playOrder","_blendingSpeed","getLength","_virtualFrame","_virtualFrameRate","_virtualFrameDirection","_virtualFrameInitial","_virtualFrameEnd","_virtualSamplingObserver","_usesVirtualSampling","_isStopping","onAnimationGroupLoopObservable","onAnimationGroupEndObservable","onAnimationGroupPauseObservable","onAnimationGroupPlayObservable","_animationLoopFlags","RegisterAnimatable","addTargetedAnimation","removeTargetedAnimation","_processLoop","_animationLoopCount","startWithVirtualTimeline","effectiveFrom","effectiveTo","effectiveSamplingFrom","useVirtualTimeline","_mapVirtualFrame","effectiveSamplingTo","samplingFrom","samplingTo","_shouldStart","_checkAnimationGroupEnded","_sampleVirtualTimeline","_goToFrameWithMask","_removeVirtualSamplingObserver","curIndex","syncAllAnimationsWith","getRetainedCurrentFrame","isVirtualFrameReached","getVirtualCurrentFrame","isValidVirtualStopFrame","setVirtualCurrentFrame","elapsedSeconds","_isTargetRetainedByMask","maximum","removeAnimationGroup","newName","cloneAnimationKeys","newGroup","targetAnimation","cloneAnimations","targetConverter","targetedAnimationIndex","AnimationGroupMergeAnimationGroups","disposeSource","animationGroup","mergedAnimationGroup","parsedAnimationGroup","animationGroupInternal","targetLookup","AnimationGroupMakeAnimationAdditive","sourceAnimationGroup","cloneOriginalAnimationGroup","clonedAnimationGroupName","AnimationGroupClipKeys","fromKey","toKey","dontCloneAnimations","AnimationGroupClipKeysInPlace","AnimationGroupClipInPlace","AnimationGroupClipFrames","AnimationGroupClipFramesInPlace","useFrame","newKeys","_Registered$9T","MergeAnimationGroups","AnimationGroupParse","ClipKeys","ClipKeysInPlace","ClipFrames","ClipFramesInPlace","ClipInPlace","AnimationKeyInterpolation","AnimationGroupMaskMode","_e$3","_f$3","_g$1","_h$1","PathCursor","_path","_onchange","getPoint","getPointAtLengthPosition","moveAhead","moveBack","_ensureLimits","_raiseOnChange","onchange","AnimationGroupMask","Set","addTargetName","_targetNames","removeTargetName","mergeRuntimeAnimations","mainAnimatable","mainRuntimeAnimation","mainAnimation","_classSuper","_billboardMode","useBillboardPosition","BILLBOARDMODE_USE_POSITION","_infiniteDistance","_forward","_up","_position","__position_initializers","_rotation","__position_extraInitializers","__rotation_initializers","_rotationQuaternion","__rotation_extraInitializers","__rotationQuaternion_initializers","_scaling","__rotationQuaternion_extraInitializers","__scaling_initializers","_transformToBoneReferal","__scaling_extraInitializers","_isAbsoluteSynced","__billboardMode_initializers","BILLBOARDMODE_NONE","scalingDeterminant","__billboardMode_extraInitializers","_scalingDeterminant_initializers","_scalingDeterminant_extraInitializers","__infiniteDistance_initializers","ignoreNonUniformScaling","__infiniteDistance_extraInitializers","_ignoreNonUniformScaling_initializers","_usePivotMatrix","_absolutePosition","_absoluteScaling","_absoluteRotationQuaternion","_postMultiplyPivotMatrix","onAfterWorldMatrixUpdateObservable","_markAsDirtyInternal","customMarkAsDirty","_right","updatePoseMatrix","_poseMatrix","localMatrixUpdated","absolutePosition","_syncAbsoluteScalingAndRotation","absoluteRotationQuaternion","setPivotMatrix","postMultiplyPivotMatrix","_pivotMatrix","pivotMatrixUpdated","_pivotMatrixInverse","onNewNodeCreated","getChildTransformNodes","instantiateHierarchy","newWorldMatrix","_afterComputeWorldMatrix","_isWorldMatrixFrozen","unfreezeWorldMatrix","isWorldMatrixFrozen","absolutePositionX","absolutePositionY","absolutePositionZ","invLocalWorldMatrix","locallyTranslate","lookAt","targetPoint","yawCor","pitchCor","rollCor","dv","_LookAtVectorCache","rotationMatrix","parentRotationMatrix","quaternionRotation","getPivotPoint","getPivotPointToRef","getAbsolutePivotPoint","getAbsolutePivotPointToRef","preserveScalingSign","updatePivot","quatRotation","invParentMatrix","composedMatrix","currentRotation","_TmpRotation","addChild","_nonUniformScaling","_updateNonUniformScalingState","attachToBone","bone","affectedTransformNode","_currentParentWhenAttachingToBone","detachFromBone","resetToPreviousParent","parentWorldMatrix","_RotationAxisCache","tmpVector","finalScale","finalTranslation","finalRotation","translationMatrix","translationMatrixInv","displacementVector","setAbsolutePosition","tempV3","getPositionExpressedInLocalSpace","setPositionWithLocalVector","addRotation","accumulation","isWorldMatrixCameraDependent","_TmpScaling","_TmpTranslation","reIntegrateRotationIntoRotationQuaternion","camInObjSpace","BILLBOARDMODE_ALL","eulerAngles","BILLBOARDMODE_X","BILLBOARDMODE_Y","BILLBOARDMODE_Z","storedTranslation","_TmpRHRestore","isRH","isNonUniformWithinEpsilon","independentOfChildren","getChildren","bakedMatrix","tmpRotationQuaternion","registerAfterWorldMatrixUpdate","unregisterAfterWorldMatrixUpdate","currentSerializationObject","freezeWorldMatrix","serializeAnimationRanges","ignoreRotation","storedRotation","storedRotationQuaternion","boundingVectors","getHierarchyBoundingVectors","sizeVec","maxDimension","serializeAsVector3","__billboardMode_decorators","__infiniteDistance_decorators","_ignoreNonUniformScaling_decorators","_reIntegrateRotationIntoRotationQuaternion_decorators","__position_decorators","__rotation_decorators","__rotationQuaternion_decorators","__scaling_decorators","_scalingDeterminant_decorators","_ignoreNonUniformScaling_extraInitializers","BillboardUseParentOrientation","TransformNodeParse","parsedTransformNode","TransformNode","setPreTransformMatrix","pivotMatrix","setEnabled","_waitingParentId","parentInstanceIndex","_waitingParentInstanceIndex","_waitingFreezeWorldMatrix","autoAnimate","autoAnimateFrom","autoAnimateTo","autoAnimateLoop","autoAnimateSpeed","_TransformNodeRegistered","inlineScheduler","coroutine","onStep","createYieldingScheduler","yieldAfterMS","runCoroutine","scheduler","abortSignal","reschedule","stepResult","resume","makeSyncFunction","coroutineFactory","runCoroutineSync","runCoroutineAsync","getPhysicsBody","applyImpulse","_b$7","applyAngularImpulse","_c$5","_d$5","applyTorque","subMeshId","_internalSubMeshId","BoundingBox","worldMatrix","vectors","extendSize","extendSizeWorld","directions","vectorsWorld","minimum","_drawWrapperBack","reConstruct","minX","minY","minZ","maxX","maxY","maxZ","_update","factor","tmpVectors","_TmpVector3","newRadius","minWorld","maxWorld","IsInFrustum","IsCompletelyInFrustum","intersectsPoint","pointX","pointY","pointZ","IntersectsSphere","sphere","radiusWorld","intersectsMinMax","myMin","myMax","myMinX","myMinY","myMinZ","myMaxX","myMaxY","myMaxZ","_drawWrapperFront","Intersects","box0","box1","minPoint","maxPoint","sphereCenter","sphereRadius","canReturnFalse","BoundingSphere","tempVector","isCenterInFrustum","squareDistance","sphere0","sphere1","radiusSum","CreateFromCenterAndRadius","_Result0","_Result1","ComputeBoxExtents","box","BoundingInfo","_isLocked","isLocked","centerOn","extend","encapsulate","toEncapsulate","invw","diagonalLength","isCompletelyInFrustum","_checkCollision","_canDoCollision","intersects","extractMinAndMaxIndexed","extractMinAndMax","_static_extractMinAndMaxIndexed_decorators","_static_extractMinAndMax_decorators","_staticExtraInitializers","MathHelpers","bias","FixFlippedFaces","inside","tmpVectorA","tmpVectorB","tmpVectorC","tmpVectorAB","tmpVectorAC","tmpVectorNormal","avgX","avgY","avgZ","tmpVectorAvgNormal","DrawWrapper","GetEffect","_wasPreviouslyReady","_forceRebindOnNextCall","_wasPreviouslyUsingInstances","materialContext","resetContext","drawContext","_releaseUniformBufferSlots","immediate","_b$6","SubMesh","_mainDrawWrapperOverride","_getDrawWrapper","createIfNotExisting","drawWrapper","_drawWrappers","_mesh","disposeWrapper","_drawWrapperOverride","_setMainDrawWrapperOverride","setEffect","_removeDrawWrapper","materialIndex","renderingMesh","createBoundingBox","addToMesh","_linesIndexCount","_currentMaterial","_trianglePlanes","refreshBoundingInfo","IsGlobal","getTotalIndices","_boundingInfo","setBoundingInfo","_renderingMesh","getReplacementMesh","getEffectiveMesh","rootMaterial","getMaterialForRenderPass","getDefaultMaterial","_isMultiMaterial","effectiveMaterial","getSubMaterial","_lastColliderWorldVertices","boundingBias","updateBoundingInfo","enableAlphaMode","_getLinesIndexBuffer","_linesIndexBuffer","adjustedIndexCount","linesIndices","canIntersects","intersectsBox","checkStopper","_intersectLines","intersectionThreshold","_intersectUnIndexedLines","_unIndexed","_intersectUnIndexedTriangles","_intersectTriangles","intersectionSegment","intersectInfo","IntersectionInfo","indexA","indexB","indexC","intersectsTriangle","currentIntersectInfo","newRenderingMesh","CreateFromIndices","minVertexIndex","maxVertexIndex","vertexIndex","_a$6","projectToRef","VertexDataMaterialInfo","_applyTo","_applyToCoroutine","tangents","uvs2","uvs3","uvs4","uvs5","uvs6","matricesIndices","matricesWeights","matricesIndicesExtra","matricesWeightsExtra","updateMesh","updateGeometry","meshOrGeometry","setVerticesData","hasVertexAlpha","setIndices","materialInfos","matInfo","updateExtends","makeItUnique","updateVerticesData","_TransformVector3Coordinates","coordinates","coordinate","transformedCoordinate","_TransformVector3Normals","transformedNormal","_TransformVector4Normals","_FlipFaces","flip","splitBasedOnMaterialID","materialInfo","newMaterialInfo","merge","use32BitsIndices","forceCloneIndices","mergeMaterialIds","enableCompletion","vertexDatas","others","map","_mergeCoroutine","_validate","indexOffset","vertexOffset","currentMaterialInfo","vertexDataList","matInfoA","matInfoB","vertexDataSource","totalIndices","indexSum","indicesOffset","positionsOffset","_MergeElement","nonNullOthers","sumLen","elements","transformRange","ret32","MeshInvalidPositionsError","positionsElementCount","getElementCount","validateElementCount","matricesIndicesExpanded","matricesIndicesExtraExpanded","materialInfoSerializationObject","ExtractFromMesh","_ExtractFrom","copyWhenShared","ExtractFromGeometry","getVertexBuffer","newColors","CreateRibbon","CreateBox","CreateTiledBox","CreateTiledPlane","CreateSphere","CreateCylinder","CreateTorus","CreateLineSystem","CreateDashedLines","CreateGround","CreateTiledGround","CreateGroundFromHeightMap","CreatePlane","CreateDisc","CreatePolygon","polygon","sideOrientation","fUV","fColors","frontUVs","backUVs","wrap","CreateIcoSphere","CreatePolyhedron","CreateCapsule","subdivisions","tessellation","capSubdivisions","CreateTorusKnot","p1p2x","p1p2y","p1p2z","p3p2x","p3p2y","p3p2z","faceNormalx","faceNormaly","faceNormalz","v1x","v1y","v1z","v2x","v2y","v2z","v3x","v3y","v3z","computeFacetNormals","computeFacetPositions","computeFacetPartitioning","computeDepthSort","faceNormalSign","ratio","distanceTo","facetNormals","facetPositions","facetPartitioning","depthSort","xSubRatio","ySubRatio","zSubRatio","subSq","subDiv","X","bbSize","Y","Z","nbFaces","ox","bInfo","oy","oz","b1x","b1y","b1z","b2x","b2y","b2z","b3x","b3y","b3z","blockIdxV1","blockIdxV2","blockIdxV3","blockIdxV4","dsf","depthSortedFacets","ind","sqDistance","_ComputeSides","li","ln","DEFAULTSIDE","lp","lu","parsedVertexData","CheckColors4","materialInfoFromJSON","ImportVertexData","setAllVerticesData","_static__TransformVector3Coordinates_decorators","_static__TransformVector3Normals_decorators","_static__TransformVector4Normals_decorators","_static__FlipFaces_decorators","FRONTSIDE","BACKSIDE","DOUBLESIDE","_checkCollisions","_collisionMask","_collisionGroup","_surroundingMeshes","_collider","_oldPositionForCollisions","_diffPositionForCollisions","_collisionResponse","_d$4","Space","BakedVertexAnimationModulo","ReadBakedVertexAnimationMatrixToRef","Axis","Coordinate","facetNb","partitioningBBoxRatio","facetDataEnabled","facetParameters","facetDepthSort","facetDepthSortEnabled","_hasVertexAlpha","_useVertexColors","_numBoneInfluencers","_applyFog","_receiveShadows","_facetData","_FacetDataStorage","_visibility","_layerMask","_computeBonesUsingShaders","_isActiveIntermediate","_onlyForInstancesIntermediate","_collisionRetryCount","_morphTargetManager","_renderingGroupId","_meshBlendingTag","_bakedVertexAnimationManager","_material","_positions","_meshCollisionData","_MeshCollisionData","_enableDistantPicking","_rawBoundingInfo","_sideOrientationHint","partitioningSubdivisions","nb","mustDepthSortFacets","facetDepthSortFrom","collisionRetryCount","retryCount","isFacetDataEnabled","_syncGeometryWithMorphTargetManager","bakedVertexAnimationManager","_markSubMeshesAsAttributesDirty","rawBoundingInfo","onCollide","_onCollideObserver","onCollideObservable","onCollisionPositionChange","_onCollisionPositionChangeObserver","onCollisionPositionChangeObservable","oldValue","_markSubMeshesAsDirty","markAsMiscDirty","markAsPrePassDirty","pointerOverDisableMeshTesting","meshBlendingTag","isInteger","RangeError","_setMaterial","meshMap","onMaterialChangedObservable","_unBindEffect","_materialForRenderPass","currentMaterial","receiveShadows","_markSubMeshesAsLightDirty","_markSubMeshesAsMiscDirty","useVertexColors","numBoneInfluencers","applyFog","collisionMask","collisionResponse","collisionGroup","surroundingMeshes","_lightSources","needInitialSkinMatrix","_unregisterMeshWithPoseMatrix","_registerMeshWithPoseMatrix","_bonesTransformMatrices","_waitingSkeletonUniqueId","alphaIndex","DefaultIsPickable","isNearPickable","showSubMeshesBoundingBox","isBlocker","useOctreeForCollisions","doNotSyncBoundingInfo","ellipsoid","edgesWidth","_masterMesh","_waitingData","lods","_transformMatrixTexture","onRebuildObservable","collisionId","collidedMesh","_uniformBuffer","_buildUniformLayout","transferToEffect","_isGaussianSplatting","_getEffectiveParent","initialCall","_releaseRenderPassId","_occlusionQuery","canAffectMesh","_resyncLightSource","isIn","removed","markAllAsDirty","markAsLightDirty","markAsAttributesDirty","_boundingInfoIsDirty","_updateBoundingInfo","hasBoundingInfo","buildBoundingInfo","normalizeToUnitCube","useBones","_preActivateForIntermediateRendering","renderId","intermediateRendering","movePOV","amountRight","amountUp","amountForward","calcMovePOV","rotMatrix","translationDelta","definedFacingForward","defForwardMult","rotatePOV","flipBack","twirlClockwise","tiltRight","calcRotatePOV","_refreshBoundingInfoDirect","_ApplySkeleton","skeletonMatrices","matricesIndicesData","matricesWeightsData","matricesIndicesExtraData","matricesWeightsExtraData","tempMatrix","matWeightIdx","inf","transformFromFloatsToRef","ApplySkeleton","getVertexData","_vertexData","copyVerticesData","_outputData","applyMorph","applyBakedVertexAnimation","getTargetData","getPositions","getNormals","getTangents","getUVs","getUV2s","getColors","targetCount","influence","targetData","ApplyMorph","bakedVertexAnimationApplied","needExtras","animationSettings","textureData","totalFrames","normalizedTime","frameCorrection","numOfFrames","frameNum","GetBakedVertexAnimationFrame","textureFrameOffset","ApplyBakedVertexAnimation","bakedVertexAnimationSettings","animationParameters","getTransformMatrices","positionIndex","dataIndex","_getData","updatePositionsArray","_updateSubMeshesBoundingInfo","precise","otherBoundingInfo","checkCollisions","collisionEnabled","moveWithCollisions","displacement","ellipsoidOffset","coordinator","createCollider","_radius","getNewPosition","_onCollisionPositionChange","slideOnCollide","_generatePointsArray","_lastColliderTransformMatrix","transformMatrix","_collide","_shouldConvertRHS","_processCollisionsForSubMeshes","_collideForSubMesh","collisionsScalingMatrix","collisionsTransformMatrix","onlyBoundingInfo","worldToUse","skipBoundingInfo","pickingInfo","anySubmeshSupportIntersect","worldOrigin","subMeshFaceId","releaseSubMeshes","includedOnlyMeshes","getShadowGenerators","generators","iterator","shadowMap","disableFacetData","_initFacetData","depthSortedIndices","needs32bits","depthSortedFacet","facetDepthSortOrigin","bbSizeMax","getFacetLocalNormals","getFacetLocalPositions","getFacetLocalPartitioning","VertexData","ComputeNormals","facetDepthSortFunction","sind","updateIndices","facetData","updateFacetData","getFacetPosition","localPos","getFacetNormal","localNorm","getFacetsAtLocalCoordinates","getClosestFacetAtCoordinates","projected","checkFace","facing","invMat","invVect","getClosestFacetAtLocalCoordinates","closest","tmpx","tmpy","tmpz","t0","projx","projy","facetsInBlock","tmpDistance","fib","shortest","projz","getFacetDataParameters","gpuMemoryOnly","OptimizeIndices","mesh_vertexData_functions","upDirection","axisX","axisZ","disableEdgesRendering","enableEdgesRendering","checkVerticesInsteadOfIndices","getConnectedParticleSystems","_static__ApplySkeleton_decorators","OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE","CULLINGSTRATEGY_STANDARD","CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY","CULLINGSTRATEGY_OPTIMISTIC_INCLUSION","CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY","_Registered$9S","AbstractMesh","createOrUpdateSubmeshesOctree","_a$5","getPhysicsImpostor","_c$4","_f$2","setPhysicsLinkWith","AnimatorAvatar","mapMorphTargetNameToMorphTarget","_mapMorphTargetNameToMorphTarget","_buildMorphTargetMap","_disposeResources","setAvatarName","showWarnings","_collectMesh","meshName","numMaxInfluencers","nameOrTransformNode","isName","_isTransformNode","findBoneFromLinkedTransformNodeName","findBoneFromLinkedTransformNode","getBoneIndexByName","avatarSkeletonStates","_captureAvatarSkeletonStates","_computeBoneWorldMatrices","mapNodeNames","localOptions","lstSourceTransformNodes","sourceTransformNodeNameToNode","ta","tn","initialTransformations","animationGroupName","mapTransformNodeToRootNode","lstAnims","_retargetMorphTarget","sourceTransformNode","targetBone","findBoneByTransformNode","sourceTransformNodeName","findBoneByName","_retargetTransformNodeToBone","checkHierarchy","retargetAnimationKeys","_retargetAnimationKeys","fixAnimations","_fixAnimationGroup","fixGroundReference","fixRootPosition","_findVerticalAxis","rootNodeName","groundReferenceNodeName","groundReferenceVerticalAxis","verticalAxis","sourceRootTransformNode","targetRootTransformNodeOrBone","targetRootPositionAnimation","sourceGroundReferenceTransformNode","targetGroundReferenceTransformNodeOrBone","proportionRatio","_fixRootPosition","_resetStates","fixGroundReferenceDynamicRefNode","_fixGroundReference","_restoreAvatarSkeletonStates","iterator2","returnToRest","morphTarget","_checkParentHierarchy","targetTransformNode","targetWorldMatrix","targetParentWorldMatrix","targetParentInverseWorldMatrix","sourceInverseWorld","sourceParentWorld","localMat","curQuat","nextQuat","rootTransformNode","boneName","transformNodeNameToNode","remappedGroundReferenceNodeName","remappedRootNodeName","_getRootNodeName","sourceRootGroundReferenceDiff","targetRootGroundReferenceDiff","sourceDiff","targetDiff","transformNodeStates","boneMatrices","linkedNode","states","sourceWorldPosition","targetWorldPosition","targetNodeInverseParentWorldMatrix","diffGroundReferences","groundReferenceOffset","targetRootToGroundReferenceDiff","targetRootToGroundReferenceOffset","targetNodeName","targetBoneWorldPosition","targetRootToBoneDiff","rootToBoneOffset","RootMotionSource","ClockChannel","channels","best","last","candidate","span","covers","ClockBeats","otherPosition","DeducedDirectionSnapAngle","SceneRootMotions","RootMotionClip","_sourceGroup","_group","controller","_controller","_rootNode","characterNode","_characterNode","contactNodes","_contactNodes","upAxis","_upAxis","_fromFrame","_toFrame","travelDirection","_travelDirection","cycleOffset","_cycleOffset","cycleDistance","cycleRotation","_cycleRotation","extractsRotation","_turns","_duration","averageSpeed","characterHeight","_characterHeight","_lateralDrift","_channels","_sampleCount","_restoredPosition","_clockIndex","_sampleBlend","_lastOffset","_rangeStart","_rangeCycle","_cyclesOffset","_planarStep","_yawQuaternion","_yawMatrix","_extractLateral","extractLateralMotion","_directionSnapAngle","directionSnapAngle","refuseAnimatedReceiver","_resolveNode","_findRootNode","anchor","_firstAnimatedNode","character","_topmostAncestor","playedFrom","playedTo","clockNode","clock","anchorChannels","anchorClock","_clockNode","samplesPerSecond","_measureHeight","minimumTravel","minimumTurn","rootChannels","extractRotation","WrapAngle","measured","_measureRootTravel","_removesRootTravel","_measureContactTravel","pivot","_rootTravelAt","_pivots","_track","_clockProperty","_clockAnimation","_sampleAt","blend","track","getRotationAtFrame","removeClip","_findClock","_clockAnimatable","_clockRuntime","_foundAnimatable","runtimes","runtime","_forgetPlayback","_syncRuntime","_lastProgress","_parked","_staleRuntime","_staleProgress","_motionBetween","lastProgress","progress","lastCycle","cycle","lastFrame","startYaw","startOffset","lastYaw","_motionInRange","stepYaw","cyclesYaw","_cyclePower","_rotateAboutUp","getOffsetAtFrame","turn","halfSine","rise","_horizontal","_measureRootYaw","_rotationInCharacter","wrapped","forced","_positionInCharacter","_frameAt","net","turning","_project","contacts","explicitContacts","base","IsJoint","lowest","POSITIVE_INFINITY","ground","keptPositions","keptLowest","tolerance","unturned","travelled","heading","pathLength","tracking","sum","grounded","chosen","before","after","score","walk","straightness","_snapTravelDirection","CloneAnimation","removesTravel","motionMatrix","rootMatrix","parentMatrix","yawQuaternion","scratchPosition","scratchRotation","inPlaceAt","_matrixToCharacter","_twist","tracked","getTranslationToRef","travel","inPlaceKeys","previousRotation","previousEuler","euler","original","inCharacter","rate","findIndex","rotationChannel","staticKeys","bestCount","highest","sample","defaultAngle","bestDot","referenceConjugate","turnedFirst","turnedSecond","local","FromEulerVectorToRef","linked","getTransformNode","RootMotionController","clips","_clips","deltaPosition","_deltaPosition","deltaRotation","_deltaRotation","applyToCharacter","onRootMotionObservable","_frameDelta","_frameYaw","_clipDelta","_sceneRootMotion","SceneRootMotion","Get","clip","addClip","refresh","_writers","moved","animated","writers","found","_accumulate","syncRuntime","deltaYaw","parentDelta","mirrored","turned","_effectiveWeight","additives","direct","blending","currentWeights","currentBlending","currentAdditive","share","weighted","lastDirect","sceneRootMotion","_controllers","_writersByNode","_observer","entries","find","getEasingFunction","Viewport","renderWidth","renderHeight","_Registered$9R","getRenderPassNames","_renderPassNames","getCurrentRenderPassName","upVector","_upVector","fovMode","getAspectRatio","halfWidth","halfHeight","orthoRight","orthoLeft","orthoTop","orthoBottom","_orthoLeft","rigCamera","_orthoRight","_orthoBottom","_orthoTop","setFocalLength","sensorSize","atan","inertia","_baseInertia","_mode","hasMoved","_hasMoved","RegisterAbstractEngineRenderPass","__upVector_initializers","oblique","__upVector_extraInitializers","_fov_initializers","_fov_extraInitializers","_projectionPlaneTilt_initializers","_projectionPlaneTilt_extraInitializers","_minZ_initializers","_minZ_extraInitializers","_maxZ_initializers","_maxZ_extraInitializers","_layerMask_initializers","_layerMask_extraInitializers","_fovMode_initializers","_fovMode_extraInitializers","_cameraRigMode_initializers","interaxialDistance","_cameraRigMode_extraInitializers","_interaxialDistance_initializers","isStereoscopicSideBySide","_interaxialDistance_extraInitializers","_isStereoscopicSideBySide_initializers","ignoreCameraMaxZ","_isStereoscopicSideBySide_extraInitializers","_ignoreCameraMaxZ_initializers","_ignoreCameraMaxZ_extraInitializers","onViewMatrixChangedObservable","onProjectionMatrixChangedObservable","onAfterCheckInputsObservable","onRestoreStateObservable","_computedViewMatrix","_doNotComputeProjectionMatrix","_refreshFrustumPlanes","_isRightCamera","setActiveOnSceneIfNoneActive","createRenderPassId","storeState","_stateStored","hasStateStored","_restoreStateValues","_storedFov","restoreState","absoluteRotation","_globalPosition","completeCheck","obliqueAngle","obliqueLength","obliqueOffset","ignoreParentClass","_isSynchronizedViewMatrix","_isSynchronizedProjectionMatrix","_ignored","_noPreventDefault","_updateRigCameras","_checkInputs","rigPostProcess","_rigPostProcess","_getFirstPostProcess","ppIndex","firstPostProcess","markTextureDirty","cam","getEffectName","attachPostProcess","insertAt","isReusable","_cascadePostProcessesToRigCams","_getViewMatrix","updateCache","_cameraRigParams","vrPreViewMatrix","freezeProjectionMatrix","unfreezeProjectionMatrix","reverseDepth","_computeObliqueDistance","getTransformationMatrix","_updateFrustumPlanes","checkRigCameras","getForwardRay","getForwardRayToRef","refRay","removeCamera","releaseRenderPassId","isLeftCamera","_isLeftCamera","setCameraRigMode","rigParams","createRigCamera","_setRigMode","vrMetrics","vrWorkMatrix","vrHMatrix","setCameraRigParameter","stereoHalfAngle","_setupInputs","GetConstructorFromName","_absoluteRotation","interaxial_distance","_CreateDefaultParsedCamera","_calculateHandednessMultiplier","handednessMultiplier","__upVector_decorators","_get_orthoLeft_decorators","_get_orthoRight_decorators","_get_orthoBottom_decorators","_get_orthoTop_decorators","_fov_decorators","_projectionPlaneTilt_decorators","_minZ_decorators","_maxZ_decorators","_get_inertia_decorators","_get_mode_decorators","_layerMask_decorators","_fovMode_decorators","_cameraRigMode_decorators","_interaxialDistance_decorators","_isStereoscopicSideBySide_decorators","_ignoreCameraMaxZ_decorators","_instanceExtraInitializers","CameraParse","parsedCamera","construct","Camera","setTarget","_CameraRegistered","SceneLoaderFlags","ForceFullSceneLoadingForIncremental","_ForceFullSceneLoadingForIncremental","ShowLoadingScreen","_ShowLoadingScreen","loggingLevel","_LoggingLevel","CleanBoneMatrixWeights","_CleanBoneMatrixWeights","useOpenGLOrientationForUV","UseOpenGLOrientationForUV","Geometry","_boundingBias","CreateGeometryForMesh","applyToMesh","_meshes","delayLoadState","_indexBufferIsUpdatable","useBoundingInfoFromGeometry","_indices","_vertexArrayObjects","_extend","buffers","getWrapperBuffer","applyToGeometry","_notifyUpdate","setVerticesBuffer","removeVerticesData","_disposeVertexArrayObjects","disposeExistingBuffer","getKind","numOfMeshes","_updateExtend","_createGlobalSubMesh","isUnIndexed","synchronizeInstances","indexToBind","overrideVertexArrayObjects","vbs","getVertexBuffers","vaos","recordVertexArrayObject","_delayInfo","needToUpdateSubMeshes","setIndexBuffer","_totalIndices","dontForceSubMeshRecreation","getIndexBuffer","releaseForMesh","shouldDispose","_invalidateInstanceVertexArrayObject","_geometry","previousGeometry","_applyToMesh","onGeometryUpdated","onLoaded","_queueLoad","delayLoadingFile","_delayLoadingFunction","tIndices","tTemp","tPositions","tNormals","_resetPointsArrayCache","_positionsCache","arrayIdx","numElements","bufferDataByteSize","GetTypedArrayData","newVb","_toNumberArray","vbName","serializeVerticeData","isVertexBufferUpdatable","positionsUpdatable","normalsUpdatable","tangentsUpdatable","uvsUpdatable","uvs2Updatable","uvs3Updatable","uvs4Updatable","uvs5Updatable","uvs6Updatable","colorsUpdatable","matricesIndicesUpdatable","matricesWeightsUpdatable","_loadedUniqueId","parsedGeometry","geometryUniqueId","geometryId","_GetGeometryByLoadedUniqueId","binaryInfo","_binaryInfo","positionsAttrDesc","positionsData","normalsAttrDesc","normalsData","tangetsAttrDesc","tangentsData","uvsAttrDesc","uvsData","uvs2AttrDesc","uvs2Data","uvs3AttrDesc","uvs3Data","uvs4AttrDesc","uvs4Data","uvs5AttrDesc","uvs5Data","uvs6AttrDesc","uvs6Data","colorsAttrDesc","colorsData","matricesIndicesAttrDesc","floatIndices","matricesIndicesExtraAttrDesc","matricesWeightsAttrDesc","indicesAttrDesc","indicesData","subMeshesAttrDesc","subMeshesData","AddToMesh","_isExpanded","matricesIndex","matricesIndicesExtraUpdatable","_CleanMatricesWeights","parsedSubMesh","_shouldGenerateFlatShading","convertToFlatShadedMesh","noInfluenceBoneIndex","skeletonId","influencers","numBoneInfluencer","firstZeroWeight","mweight","boundingBoxMinimum","boundingBoxMaximum","hasUVs","hasUVs2","hasUVs3","hasUVs4","hasUVs5","hasUVs6","hasColors","hasMatricesIndices","hasMatricesWeights","_get_func_decorators","_get_backFunc_decorators","_get_funcRef_decorators","_get_funcMask_decorators","_get_opStencilFail_decorators","_get_opDepthFail_decorators","_get_opStencilDepthPass_decorators","_get_backOpStencilFail_decorators","_get_backOpDepthFail_decorators","_get_backOpStencilDepthPass_decorators","_get_mask_decorators","_get_enabled_decorators","AddClipPlaneUniforms","clipPlane","primaryHolder","secondaryHolder","clipPlane2","clipPlane3","clipPlane4","clipPlane5","clipPlane6","SetClipPlane","MaterialFlags","DiffuseTextureEnabled","_DiffuseTextureEnabled","MarkAllMaterialsAsDirty","BaseWeightTextureEnabled","_BaseWeightTextureEnabled","BaseDiffuseRoughnessTextureEnabled","_BaseDiffuseRoughnessTextureEnabled","DetailTextureEnabled","_DetailTextureEnabled","DecalMapEnabled","_DecalMapEnabled","AmbientTextureEnabled","_AmbientTextureEnabled","OpacityTextureEnabled","_OpacityTextureEnabled","ReflectionTextureEnabled","_ReflectionTextureEnabled","EmissiveTextureEnabled","_EmissiveTextureEnabled","SpecularTextureEnabled","_SpecularTextureEnabled","BumpTextureEnabled","_BumpTextureEnabled","LightmapTextureEnabled","_LightmapTextureEnabled","RefractionTextureEnabled","_RefractionTextureEnabled","ColorGradingTextureEnabled","_ColorGradingTextureEnabled","FresnelEnabled","_FresnelEnabled","ClearCoatTextureEnabled","_ClearCoatTextureEnabled","ClearCoatBumpTextureEnabled","_ClearCoatBumpTextureEnabled","ClearCoatTintTextureEnabled","_ClearCoatTintTextureEnabled","SheenTextureEnabled","_SheenTextureEnabled","AnisotropicTextureEnabled","_AnisotropicTextureEnabled","ThicknessTextureEnabled","_ThicknessTextureEnabled","RefractionIntensityTextureEnabled","_RefractionIntensityTextureEnabled","TranslucencyIntensityTextureEnabled","_TranslucencyIntensityTextureEnabled","TranslucencyColorTextureEnabled","_TranslucencyColorTextureEnabled","IridescenceTextureEnabled","_IridescenceTextureEnabled","BindLogDepth","LN2","TempFogColor","TmpMorphInfluencers","NUM_MORPH_INFLUENCERS","NORMAL","TANGENT","UV","UV2","linearSpace","toLinearSpaceToRef","PrepareDefinesAndAttributesForMorphTargets","attribs","usePositionMorph","useNormalMorph","useTangentMorph","useUVMorph","useUV2Morph","useColorMorph","numMorphInfluencers","numInfluencers","PrepareAttributesForMorphTargets","PrepareAttributesForMorphTargetsInfluencers","maxAttributesCount","isUsingTextureForTargets","supportsPositions","supportsNormals","supportsTangents","supportsUVs","supportsUV2s","supportsColors","PushAttributesForInstances","needsPreviousMatrices","BindMorphTargetParameters","abstractMesh","influences","BindIBLParameters","reflectionColor","reflectionTexture","realTimeFiltering","supportTextureInfo","supportLocalProjection","usePBR","supportSH","useColor","reflectionBlur","getReflectionTextureMatrix","boundingBoxSize","cubeTexture","boundingBoxPosition","USEIRRADIANCEMAP","polynomials","sphericalPolynomial","USESPHERICALFROMREFLECTIONMAP","SPHERICAL_HARMONICS","preScaledHarmonics","l00","l1_1","l10","l11","l2_2","l2_1","l20","l21","l22","USE_IRRADIANCE_DOMINANT_DIRECTION","irradianceTexture","_dominantDirection","lodGenerationScale","lodGenerationOffset","BindIBLSamplers","LODBASEDMICROSFURACE","cdfGenerator","iblCdfGenerator","getIcdfTexture","PrepareDefinesForMergedUV","_needUVs","optimizeUVAllocation","getTextureMatrix","coordinatesIndex","PrepareAttributesForBakedVertexAnimation","BindBonesParameters","prePassConfiguration","_bonesComputationForcedToCPU","getUniformIndex","boneTexture","getTransformMatrixTexture","_textureWidth","_textureHeight","getIndex","previousBones","BindLightProperties","lightIndex","BindLight","useSpecular","_bindLight","_LightBudgetWarnedEngines","GetSupportedSimultaneousLights","maxSimultaneousLights","maxUniformBuffersPerShaderStage","supported","BindLights","PrepareAttributesForBones","addCPUSkinningFallback","PrepareAttributesForInstances","INSTANCESCOLOR","HandleFallbacksForShadows","lightFallbackRank","addFallback","GetFogState","_areMiscDirty","useLogarithmicDepth","pointsCloud","alphaTest","applyDecalAfterDetail","useVertexPulling","setVertexOutputInvariant","AreLightsTexturesReady","disableLighting","areLightTexturesReady","PrepareDefinesForLights","specularSupported","_areLightsDirty","_needNormals","needNormals","needRebuild","lightmapMode","specularEnabled","requestedSimultaneousLights","requested","lightsInUse","warned","WarnAboutClampedLights","PrepareDefinesForLight","maxLightCount","caps","PrepareDefinesForIBL","realTimeFilteringQuality","forceSHInVertex","isReadyOrNotBlocking","REFLECTION","GAMMAREFLECTION","gammaSpace","RGBDREFLECTION","isRGBD","LODINREFLECTIONALPHA","lodLevelInAlpha","LINEARSPECULARREFLECTION","linearSpecularLOD","NUM_SAMPLES","REALTIME_FILTERING","IBL_CDF_FILTERING","INVERTCUBICMAP","REFLECTIONMAP_3D","REFLECTIONMAP_OPPOSITEZ","invertZ","REFLECTIONMAP_CUBIC","REFLECTIONMAP_EXPLICIT","REFLECTIONMAP_PLANAR","REFLECTIONMAP_PROJECTION","REFLECTIONMAP_SKYBOX","REFLECTIONMAP_SPHERICAL","REFLECTIONMAP_EQUIRECTANGULAR","REFLECTIONMAP_EQUIRECTANGULAR_FIXED","REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED","USE_LOCAL_REFLECTIONMAP_CUBIC","USESPHERICALINVERTEX","falloffType","specular","equalsFloats","getShadowGenerator","shadowGenerator","getShadowMap","prepareDefines","useInstances","useClipPlane","useThinInstances","PrepareDefinesForCamera","PrepareDefinesForClipPlanes","getColorWrite","markAsUnprocessed","_BoneUniformBudgetCheckedSignature","_BoneUniformBudgetWarnedSkeletons","WeakSet","PrepareDefinesForBones","isUsingTextureForMatrices","materialSupportsBoneTexture","nonExcluded","excludedSkinnedMesh","signature","boneUniformVectors","reservedVertexUniforms","available","PrepareDefinesForMorphTargets","hasUV2s","hasTangents","hasNormals","hasPositions","PrepareDefinesForBakedVertexAnimation","PrepareDefinesForAttributes","useVertexColor","useMorphTargets","useVertexAlpha","useBakedVertexAnimation","_areAttributesDirty","_uvs","hasVertexColors","PrepareDefinesForMultiview","previousMultiview","MULTIVIEW","getViewCount","PrepareDefinesForOIT","needAlphaBlending","previousDefine","ORDER_INDEPENDENT_TRANSPARENCY","previousDefine16Bits","ORDER_INDEPENDENT_TRANSPARENCY_16BITS","PrepareDefinesForPrePass","canRenderToMRT","previousPrePass","PREPASS","_arePrePassDirty","texturesList","SCENE_MRT_COUNT","mrtCount","PREPASS_NORMAL_WORLDSPACE","generateNormalsInWorldSpace","PREPASS_COLOR","PREPASS_COLOR_INDEX","markAsImageProcessingDirty","wasOrtho","wasPersp","isOrtho","isPersp","projectedLightTexture","uniformBuffersList","updateOnlyBuffersList","iesLightTexture","clusteredLightTextures","rectAreaLightTexture","clusteredLightStorageBuffer","PrepareUniformsAndSamplersForIBL","useSH","iblUniforms","uniformsListOrOptions","PrepareUniformsAndSamplersForLight","PrepareUniformLayoutForIBL","_useVertexPulling","MiscDirtyFlag","_supportGlowLayer","_alpha","PrePassDirtyFlag","backFaceCulling","_backFaceCulling","TextureDirtyFlag","textureRepetitionMode","clamped","_textureRepetitionMode","_cullBackFaces","blockDirtyMechanism","_blockDirtyMechanism","markDirty","atomicMaterialsUpdate","_eventInfo","_callbackPluginEventHasRenderTargetTextures","_onBindObserver","onUnBindObservable","_onUnBindObservable","onEffectCreatedObservable","_onEffectCreatedObservable","alphaMode","alphaModes","_needDepthPrePass","checkReadyOnEveryCall","isPrePassCapable","wireframe","_fillMode","WireFrameFillMode","LineListDrawMode","LineLoopDrawMode","TriangleFillMode","PointFillMode","_useLogarithmicDepth","_markAllSubMeshesAsMiscDirty","isVertexOutputInvariant","_isVertexOutputInvariant","_drawWrapper","_setDrawWrapper","doNotAdd","forceGLSL","customShaderNameResolve","shadowDepthWrapper","_forceGLSL","_checkReadyOnEveryCall_initializers","checkReadyOnlyOnce","_checkReadyOnEveryCall_extraInitializers","_checkReadyOnlyOnce_initializers","_checkReadyOnlyOnce_extraInitializers","__alpha_initializers","inspectableCustomProperties","__alpha_extraInitializers","__backFaceCulling_initializers","__backFaceCulling_extraInitializers","__textureRepetitionMode_initializers","textureRepetitionHexTilingParams","__textureRepetitionMode_extraInitializers","_textureRepetitionHexTilingParams_initializers","_textureRepetitionHexTilingParams_extraInitializers","__cullBackFaces_initializers","__cullBackFaces_extraInitializers","_sideOrientation_initializers","_sideOrientation_extraInitializers","_storeEffectOnSubMeshes","__alphaMode_initializers","__alphaMode_extraInitializers","__needDepthPrePass_initializers","disableDepthWrite","__needDepthPrePass_extraInitializers","_disableDepthWrite_initializers","disableColorWrite","_disableDepthWrite_extraInitializers","_disableColorWrite_initializers","forceDepthWrite","_disableColorWrite_extraInitializers","_forceDepthWrite_initializers","depthFunction","_forceDepthWrite_extraInitializers","_depthFunction_initializers","separateCullingPass","_depthFunction_extraInitializers","_separateCullingPass_initializers","_separateCullingPass_extraInitializers","__fogEnabled_initializers","pointSize","__fogEnabled_extraInitializers","_pointSize_initializers","_pointSize_extraInitializers","_zOffset_initializers","_zOffset_extraInitializers","_zOffsetUnits_initializers","_zOffsetUnits_extraInitializers","MaterialStencilState","__isVertexOutputInvariant_initializers","ForceVertexOutputInvariant","_materialContext","__isVertexOutputInvariant_extraInitializers","_useUBO","_cachedDepthWriteState","_cachedColorWriteState","_uniformBufferLayoutBuilt","_callbackPluginEventFillRenderTargetTextures","_transparencyMode","setScene","_dirtyCallbacks","_markAllSubMeshesAsTexturesDirty","_markAllSubMeshesAsLightsDirty","_markAllSubMeshesAsFresnelDirty","_markAllSubMeshesAsAttributesDirty","_markAllSubMeshesAsPrePassDirty","_markAllSubMeshesAsAllDirty","_createUniformBuffer","OnEventObservable","isFrozen","isReadyForSubMesh","materialDefines","_callbackPluginEventIsReadyForSubMesh","getEffect","_getEffectiveOrientation","transparencyMode","_markAllSubMeshesAsTexturesAndMiscDirty","_hasTransparencyMode","_transparencyModeIsBlend","MATERIAL_ALPHABLEND","MATERIAL_ALPHATESTANDBLEND","_transparencyModeIsTest","MATERIAL_ALPHATEST","_disableAlphaBlending","MATERIAL_OPAQUE","needAlphaBlendingForMesh","needAlphaTesting","needAlphaTestingForMesh","getAlphaTestTexture","forceMaterialDirty","AllDirtyFlag","overrideOrientation","reverse","ClockWiseSideOrientation","effectiveDrawWrapper","enableEffect","setState","buildUniformLayout","_callbackPluginEventGeneric","bindForSubMesh","_callbackPluginEventBindForSubMesh","bindOnlyWorldMatrix","bindView","_needToBindSceneUbo","bindViewProjection","getInverseProjectionMatrix","_afterBind","BindSceneUniformBuffer","getDepthWrite","setDepthFunction","_cachedDepthFunctionState","getActiveTextures","activeTextures","hasTexture","targetMaterial","_serializePlugins","pluginManager","plugin","_plugins","getPlugin","targetPlugin","copyTo","getBindedMeshes","meshId","forceCompilation","currentHotSwapingState","allowShaderHotSwapping","checkReady","clipPlaneState","allDone","lastError","tempSubMesh","allFallbacksProcessed","getCompilationError","ImageProcessingDirtyFlag","_DirtyCallbackArray","_ImageProcessingDirtyCallBack","_TextureDirtyCallBack","LightDirtyFlag","_LightsDirtyCallBack","FresnelDirtyFlag","_FresnelDirtyCallBack","AttributesDirtyFlag","_AttributeDirtyCallBack","_MiscDirtyCallBack","_PrePassDirtyCallBack","_markAllSubMeshesAsDirty","_RunDirtyCallBacks","_AllDirtyCallBack","_markAllSubMeshesAsImageProcessingDirty","_markAllSubMeshesAsFresnelAndMiscDirty","_FresnelAndMiscDirtyCallBack","_TextureAndMiscDirtyCallBack","notBoundToMesh","forceDisposeTextures","_disposeMeshResources","materialForRenderPass","drawWrappers","renderPassIndex","_releaseVertexArrayObject","plugins","parsedMaterial","customType","overloadedAlbedo","BABYLON","LegacyPBRMaterial","pluginData","pluginClassName","pluginClassType","_checkReadyOnEveryCall_decorators","_checkReadyOnlyOnce_decorators","__cullBackFaces_decorators","_sideOrientation_decorators","__alphaMode_decorators","__needDepthPrePass_decorators","_disableDepthWrite_decorators","_disableColorWrite_decorators","_forceDepthWrite_decorators","_depthFunction_decorators","__fogEnabled_decorators","_pointSize_decorators","_zOffset_decorators","_zOffsetUnits_decorators","_get_pointsCloud_decorators","_get_fillMode_decorators","_get_useLogarithmicDepth_decorators","__isVertexOutputInvariant_decorators","_get_transparencyMode_decorators","_metadata_initializers","__alpha_decorators","__backFaceCulling_decorators","__textureRepetitionMode_decorators","_textureRepetitionHexTilingParams_decorators","_separateCullingPass_decorators","PointListDrawMode","LineStripDrawMode","TriangleStripDrawMode","TriangleFanDrawMode","CounterClockWiseSideOrientation","MATERIAL_NORMALBLENDMETHOD_WHITEOUT","MATERIAL_NORMALBLENDMETHOD_RNM","LIGHTFALLOFF_PHYSICAL","LIGHTFALLOFF_GLTF","LIGHTFALLOFF_STANDARD","markAsTexturesDirty","markAsFresnelDirty","provider","maxObjectId","objectId","GeometryRenderingTextureClearType","Material","MaterialHelperGeometryRendering","_Configurations","previousWorldMatrices","previousViewProjection","currentViewProjection","lastUpdateFrameId","reverseCulling","objectIdIsRedFormat","_PrepareConfiguration","attachments","colorAttachments","configuration","_attachments","_colorAttachments","_mrtCount","GeometryTextureDescriptions","defineIndex","_defines","_PrepareStringDefines","_BindAttachmentsForEffect","bindAttachments","_RestoreAttachments","_BindColorAttachments","_IsColorAttachmentEnabled","_BindZeroAlphaDiscard","getAlphaMode","discard","AddUniformsAndSamplers","geometryTextureDescription","defineName","numMRT","setStateCullFaceType","objectIdProvider","_GetGeometryRenderingObjectId","meshBlendTag","_GetGeometryRenderingMeshBlendTag","meshBlendTagProvider","currentWorldMatrices","_currentWorldMatrices","worldMatrixFrameIds","_worldMatrixFrameIds","clearType","MultiMaterial","subMaterials","_subMaterials","_hookArray","_waitingSubMaterialsUniqueIds","oldPush","oldSplice","deleteCount","deleted","subMaterial","cloneChildren","materialsUniqueIds","matIndex","subMat","forceDisposeChildren","forceDisposeEffect","_Registered$9Q","MultiMaterialParseMultiMaterial","parsedMultiMaterial","multiMaterial","subMatId","ParseMultiMaterial","MeshLODLevel","distanceOrScreenCoverage","_CreationDataStorage","instancesBufferSize","renderPasses","worldMatrices","_useLODScreenCoverage","_effectiveMaterial","_forcedInstanceCount","_overrideRenderingFillMode","MeshCreationOptions","clonePhysicsImpostor","cloneThinInstances","Mesh","useLODScreenCoverage","_internalMeshDataInfo","_sortLODLevels","_sourcePositions","_sourceNormals","_onBeforeRenderObservable","onBeforeBindObservable","_onBeforeBindObservable","_onAfterRenderObservable","onBetweenPassObservable","_onBetweenPassObservable","onBeforeDrawObservable","_onBeforeDrawObservable","onBeforeDraw","_onBeforeDrawObserver","instances","forcedInstanceCount","_sideOrientation","_effectiveSideOrientation","overrideMaterialSideOrientation","overrideRenderingFillMode","cloneMeshMap","worldMatrixInstancedBuffer","instanceDataStorage","_instanceDataStorage","useMonoDataStorageRenderPass","dataStorageRenderPass","instancesData","previousWorldMatrixInstancedBuffer","instancesPreviousData","manualUpdateOfWorldMatrixInstancedBuffer","manualUpdate","manualUpdateOfPreviousWorldMatrixInstancedBuffer","previousManualUpdate","forceWorldMatrixInstancedBufferUpdate","forceMatrixUpdates","_originalBuilderSideOrientation","getPivotMatrix","physicsEngine","getPluginVersion","getImpostorForPhysicsObject","impostor","physicsImpostor","physicsBody","thinInstanceSetBuffer","matrixBuffer","matrixBufferSize","_userThinInstanceBuffersStorage","userThinInstance","strides","sizes","_InstanceDataStorage","_InstanceDataStorageRenderPass","_onBeforeDraw","isInstance","parentOrOptions","_copySource","onMeshReadyObservable","_checkReadinessObserver","_onMeshReadyObserverAdded","instance","doNotInstantiate","createInstance","ib","hasLODLevels","_LODLevels","getLODLevels","sortingOrderFactor","addLODLevel","getLODLevelAtDistance","internalDataInfo","removeLODLevel","bSphere","distanceToCamera","compareValue","compareSign","screenArea","meshArea","onLODLevelSelection","_checkDelayState","bypassInstanceData","_userInstancedBuffersStorage","getVerticesDataKinds","kinds","forceInstanceSupport","renderPassIds","areNormalsFrozen","_areNormalsFrozen","freezeNormals","unfreezeNormals","overridenInstanceCount","_getInstanceDataStorage","sceneRenderId","_preActivateId","visibleInstances","intermediateDefaultRenderId","defaultRenderId","selfDefaultRenderId","previousRenderId","thinInstanceRefreshBoundingInfo","edgesShareWithInstances","edgesRenderer","customInstances","applySkeletonOrOptions","needToRecreate","submesh","subdivide","subdivisionSize","makeGeometryUnique","positionFunction","computeNormals","oldGeometry","toLeftHanded","allowInstancedRendering","_getRenderingFillMode","_bindDirect","vertexArrayObjects","_draw","currentMaterialContext","isReplacementMode","batchCacheReplacementModeInFrozenMode","renderSelf","previousBatch","isInIntermediateRendering","_isInIntermediateRendering","onlyForInstances","batchCache","mustReturn","visibleInstanceCount","instanceStorage","batch","instancesPreviousBuffer","needUpdateBuffer","needsPreviousWorldMatrices","masterMeshPreviousWorldMatrix","worldM","INSTANCEDMESH_SORT_TRANSPARENT","getRenderingMesh","instanceIndex","instanceMesh","_previousWorldMatrix","matrixM","vertexAndArrayObjectBuffers","_processInstancedBuffers","_currentDrawContext","useInstancing","currentInstancesBufferSize","bufferSize","_updateInstancedBuffers","previousMatrixData","previousMatrixBuffer","_thinInstanceCreateMatrixBuffer","_processRendering","_renderWithInstances","instanceCount","visibleInstancesForSubMesh","dataStorage","_disposeInstanceDataStorageRenderPass","renderPassStorage","passVBOs","_getInstancesRenderList","effectiveMeshReplacement","checkFrustumCulling","directRender","numActiveCameras","canCheckOcclusionQuery","_occlusionDataStorage","occlusionForRenderPassId","_checkOcclusionQuery","occlusionCheckOnly","forceRenderingWhenOccluded","oldCameraMaxZ","oldCamera","effectiveMesh","mainDeterminant","_normalizeSkinWeightsAndExtra","_normalizeSkinFourWeights","numWeights","recip","skinned","valid","report","numberNotSorted","missingWeights","maxUsedWeights","numberNotNormalized","numInfluences","usedWeightCounts","lastWeight","usedWeights","numBones","numBadBoneIndices","load","getBinaryData","_loadDelayedFileAsync","_syncSubMeshes","submeshes","flipFaces","bakeIndependentlyOfChildren","forceUnique","bakeTransformIntoVertices","cloneOptions","_disposeThinInstanceSpecificData","applyDisplacementMap","maxHeight","uvOffset","uvScale","heightMapWidth","heightMapHeight","createCanvas","getImageData","applyDisplacementMapFromBuffer","minHeight","p3","flipNormalGeneration","localIndex","normalsCount","flattenNormals","separateVertices","newData","_getFlattenedNormals","setPositions","setNormals","setTangents","setUVs","setColors","synchronize","previousOne","previousSubmeshes","meshBoundingInfo","_convertToUnIndexedMesh","convertToUnIndexedMesh","flipNormals","currentIndices","segments","numberPerEdge","tempIndices","deltaNormal","deltaUV","side","uvPtr","normalsPtr","positionPtr","currentUVs","currentPositions","currentColors","currentMatrixIndices","currentMatrixWeights","currentMatrixIndicesExtra","currentMatrixWeightsExtra","matrixIndices","matrixWeights","matrixIndicesExtra","pstring","indexPtr","ptr","facet","uniquePositions","matrixWeightsExtra","_instancedMeshFactory","_PhysicsImpostorParser","physicObject","jsonObject","optimizeIndices","vectorPositions","dupes","SyncAsyncForLoop","realPos","testedPosition","againstPosition","originalSubMeshes","pickable","materialUniqueId","materialId","morphTargetManagerId","skeletonUniqueId","physicsMass","physicsFriction","physicsRestitution","getParam","serializationInstance","thinInstances","enablePicking","thinInstanceEnablePicking","overlayAlpha","overlayColor","uv2s","parsedMesh","skipImportGeometry","_LinesMeshParser","_GroundMeshParser","_GoldbergMeshParser","_GreasedLineMeshParser","_TrailMeshParser","_isCompound","_GaussianSplattingCompoundMeshParser","_GaussianSplattingMeshParser","_GaussianSplattingPartProxyMeshParser","showBoundingBox","renderOverlay","_ImportGeometry","_waitingMaterialId","_waitingMorphTargetManagerId","_waitingSkeletonId","lodMeshIds","ids","distances","lodDistances","coverages","lodCoverages","parsedInstance","setPositionsForCPUSkinning","setNormalsForCPUSkinning","_softwareSkinningFrameId","getFrameId","tempVector3","MinMax","minVector","maxVector","meshesOrMinMaxVector","minMaxVector","MergeMeshes","allow32BitsIndices","meshSubclass","subdivideWithSubMeshes","_MergeMeshesCoroutine","multiMultiMaterials","Boolean","materialArray","indiceArray","currentsideOrientation","accumulator","materialIndexArray","writeIdx","readIdx","previousIndice","currentIndice","getVertexDataFromMesh","sourceVertexData","sourceTransform","meshVertexDatas","mergeCoroutine","mergeCoroutineStep","applyToCoroutine","applyToCoroutineStep","_indexInSourceMeshInstanceArray","setMaterialByID","setMaterialById","_instance","CreateHemisphere","_tessellation","_subdivisions","CreateLines","_earcutInjection","ExtrudePolygon","ExtrudeShape","ExtrudeShapeCustom","_ribbonCloseArray","_ribbonClosePath","_cap","CreateLathe","_precision","_minHeight","_maxHeight","_onReady","_alphaFilter","CreateTube","CreateDecal","_angle","ExtendToGoldberg","NO_CAP","CAP_START","CAP_END","CAP_ALL","NO_FLIP","FLIP_TILE","ROTATE_TILE","FLIP_ROW","ROTATE_ROW","FLIP_N_ROTATE_TILE","FLIP_N_ROTATE_ROW","CENTER","LEFT","RIGHT","TOP","BOTTOM","_GreasedLineRibbonMeshParser","_Registered$9P","registerInstancedBuffer","_a$4","simplify","_b$4","thinInstanceAdd","_c$3","thinInstanceAddSelf","_d$3","thinInstanceRegisterAttribute","_e$1","_f$1","thinInstanceSetMatrixAt","thinInstanceSetAttributeAt","thinInstanceGetWorldMatrices","thinInstanceBufferUpdated","thinInstancePartialBufferUpdate","getEmittedParticleSystems","getHierarchyEmittedParticleSystems","InstancedMesh","addInstance","_sourceMesh","getAnimationRanges","_billboardWorldMatrix","tempMaster","sourceMeshLODLevels","newSourceMesh","removeInstance","newSourcedMesh","_Registered$9O","instancedBuffers","usePerPassStorage","perPassVertexBuffers","expectedSize","_range","_inverseSquaredRange","intensityMode","_intensityMode","_computePhotometricScale","_Light_renderPriority_accessor_storage","_shadowEnabled","_markMeshesAsLightDirty","_includedOnlyMeshes","_hookArrayForIncludedOnly","_excludedMeshes","_hookArrayForExcluded","excludeWithLayerMask","_excludeWithLayerMask","_resyncMeshes","includeOnlyWithLayerMask","_includeOnlyWithLayerMask","_lightmapMode","_faceIndex","_renderList","diffuse","_diffuse_initializers","_diffuse_extraInitializers","_specular_initializers","_specular_extraInitializers","_falloffType_initializers","intensity","_falloffType_extraInitializers","_intensity_initializers","_photometricScale","_renderPriority","__renderPriority_initializers","__renderPriority_extraInitializers","_renderPriority_initializers","_renderPriority_extraInitializers","__shadowEnabled_initializers","__shadowEnabled_extraInitializers","__excludeWithLayerMask_extraInitializers","__includeOnlyWithLayerMask_extraInitializers","__lightmapMode_initializers","_shadowGenerators","__lightmapMode_extraInitializers","_excludedMeshesIds","_includedOnlyMeshesIds","_currentViewDepth","dontAddToScene","iAsString","needUpdate","_lastUseSpecular","scaledIntensity","getScaledIntensity","bindShadowLight","getTypeID","removeLight","clonedLight","excludedMeshesIds","includedOnlyMeshesIds","parsedLight","_clusteredContainer","photometricMode","lightTypeID","photometricScale","apexAngleRadians","_reorderLightsInScene","_diffuse_decorators","serializeAsColor3","_specular_decorators","_falloffType_decorators","_intensity_decorators","_get_range_decorators","_get_intensityMode_decorators","_get_radius_decorators","expandToProperty","__lightmapMode_decorators","_renderPriority_decorators","__renderPriority_decorators","__shadowEnabled_decorators","__excludeWithLayerMask_decorators","__excludeWithLayerMask_initializers","__includeOnlyWithLayerMask_decorators","reflectionProbes","KeepAssets","AbstractAssetContainer","AssetContainer","_wasAddedToScene","_topologicalSort","nodesUidMap","dependencyGraph","dependsOn","dependedBy","nodeId","masterMesh","childId","leaves","nodeToVisit","shift","dependedByVisitedNodeId","dependedByVisitedNode","dependsOnDependedByVisitedNode","visitList","sortedNodes","addedIds","_addNodeAndDescendantsToList","_isNodeInContainer","Light","_isValidHierarchy","instantiateModelsToScene","nameFunction","cloneMaterials","conversionMap","storeMap","InstantiatedEntries","alreadySwappedSkeletons","alreadySwappedMaterials","nodesToSort","idsOnSortList","onNewCreated","clonedMesh","oldMorphTargetManager","oldTarget","newTarget","onClone","replicatedParentId","replicatedParent","sourceMaterial","swap","multi","instancedNode","replicatedSourceId","canInstance","replicatedNode","addAllToScene","addToScene","_onContextRestoredObserver","addedNodes","nodeSet","addedNode","removeAllFromScene","removeFromScene","removeFromContainer","removeSkeleton","removeAnimation","removeMultiMaterial","removeMorphTargetManager","removeActionManager","removeTexture","reflectionProbe","_moveAssets","sourceAssets","targetAssets","keepAssets","asset","move","keepAsset","moveAllFromScene","rootMesh","_targetConverter","nodesInAC","getNodes","nodeInAC","nodeInScene","animationInScene","animationInAC","animationWithSameProperty","animationsWithSameProperty","animationGroupInAC","newAnimationGroups","populateRootNodes","nodesToVisit","visitedNodes","getMaterialsByTags","Analyser","SMOOTHING","FFT_SIZE","BARGRAPHAMPLITUDE","DEBUGCANVASPOS","DEBUGCANVASSIZE","_audioEngine","audioEngine","canUseWebAudio","_webAudioAnalyser","createAnalyser","minDecibels","maxDecibels","_byteFreqs","frequencyBinCount","_byteTime","_floatFreqs","getFrequencyBinCount","getByteFrequencyData","smoothingTimeConstant","fftSize","getByteTimeDomainData","getFloatFrequencyData","drawDebugCanvas","_debugCanvas","_debugCanvasContext","_registerFunc","workingArray","fillStyle","barWidth","fillRect","stopDebugCanvas","connectAudioNodes","inputAudioNode","connect","outputAudioNode","disconnect","OnAudioEngineV2CreatedObservable","LastCreatedAudioEngine","AudioEngineV2","onNodeAddedObservable","_onNodeAddedObservable","onNodeRemovedObservable","_onNodeRemovedObservable","_onDisposeObservable","_mainBuses","_sounds","_nodes","_defaultMainBus","_parameterRampDuration","parameterRampDuration","defaultMainBus","_soundsArray","nodeIt","_disposeSoundsArray","unlockAsync","resumeAsync","_addMainBus","mainBus","_addNode","_removeMainBus","_removeNode","_GetAudioEngine","CreateAudioBusAsync","createBusAsync","CreateMainAudioBusAsync","createMainBusAsync","CreateMicrophoneSoundSourceAsync","createMicrophoneSoundSourceAsync","CreateSoundAsync","createSoundAsync","CreateSoundBufferAsync","source_1","createSoundBufferAsync","CreateSoundSourceAsync","createSoundSourceAsync","CreateStreamingSoundAsync","createStreamingSoundAsync","_SpatialAudioListenerDefaults","_HasSpatialAudioListenerOptions","listenerEnabled","listenerMinUpdateTime","listenerPosition","listenerRotation","listenerRotationQuaternion","AbstractSpatialAudioListener","_attachmentType","_sceneNode","_useBoundingBox","_spatialAudioNode","spatialAudioNode","isAttached","sceneNode","useBoundingBox","attachmentType","updatesPosition","_updateRotation","panningEnabled","_attacherComponent","_SpatialAudioAttacherComponent","setOptions","minUpdateTime","autoUpdate","_autoUpdate","_lastUpdateTime","skipUpdate","_FileExtensionRegex","CurveLength","TmpLineValues","TmpCurveValues","ExpCurve","LogCurve","_GetUrlForStreaming","_rampEndTime","_param","_targetValue","isRamping","setTargetValue","cancelScheduledValues","shape","setValueAtTime","setValueCurveAtTime","normalizedCurve","GetExpCurve","log10","GetLogCurve","_GetAudioParamCurveValues","TmpQuaternion","TmpQuaternion$2","TmpVector1","TmpVector2","forwardX","forwardY","forwardZ","positionX","positionY","positionZ","upX","upY","_SpatialWebAudioListener","_SpatialWebAudioListenerFallback","_lastPosition","_lastRotation","_listener","_updaterComponent","_SpatialWebAudioUpdaterComponent","_setWebAudioPosition","_lastRotationQuaternion","TmpMatrix$3","_setWebAudioOrientation","_forwardX","_WebAudioParameterComponent","_forwardY","_forwardZ","_positionX","_positionY","_positionZ","_upX","_upY","_upZ","upZ","_AbstractSpatialWebAudioListener","setOrientation","AudioNodeType","AbstractAudioNode","_upstreamNodes","_downstreamNodes","_disconnect","_connect","_onDisconnect","_onConnect","onNameChangedObservable","oldName","_MainAudioOut","_setGainNode","GainNode","_volume","_gainNode","_destinationNode","_inNode","volume","gainNode","gain","_button","_style","_onStateChanged","_hide","_show","offsetTop","createTextNode","stateChangedObservable","CreateAudioEngineAsync","_WebAudioEngine","_initAsync","FormatMimeTypes","aac","ac3","flac","m4a","mp3","mp4","ogg","wav","webm","_audioContextStarted","_invalidFormats","_isUpdating","_listenerAutoUpdate","_listenerMinUpdateTime","_pauseCalled","_resumeOnInteraction","_resumeOnPause","_resumeOnPauseRetryInterval","_resumeOnPauseTimerId","_resumePromise","_silentHtmlAudio","_unmuteUI","_updateObservable","_validFormats","isReadyPromise","_resolveIsReadyPromise","userGestureObservable","_initAudioContextAsync","_onAudioContextStateChange","_mainOut","_WebAudioMainOut","_onUserGestureAsync","_disableIOSRingerSwitchWorkaround","audio","controls","preload","_startUpdating","listenerAutoUpdate","disableIOSRingerSwitchWorkaround","_isUsingOfflineAudioContext","OfflineAudioContext","AudioContext","disableDefaultUI","_WebAudioUnmuteUI","defaultUIParentElement","resumeOnInteraction","resumeOnPause","resumeOnPauseRetryInterval","_CreateSpatialAudioListener","mainOut","_unmuteUIEnabled","bus","webAudioBus","webAudioMainBus","mediaStream","mediaDevices","getUserMedia","MediaStreamAudioSourceNode","outBusAutoDefault","mediaStreamSinkEnabled","stopMediaStreamTracksOnDispose","name_1","webAudioStaticSound","_WebAudioStaticSound","soundBuffer","_WebAudioStaticSoundBuffer","soundSource","webAudioSoundSource","_WebAudioStreamingSound","flagInvalidFormat","Audio","canPlayType","suspend","setVolume","_addSound","_removeSound","_onSoundPlaybackStateChanged","_addUpdateObserver","_removeUpdateObserver","AudioEngine","masterGain","_masterGain","_v2","useCustomUnlockedButton","_useCustomUnlockedButton","_triggerRunningStateAsync","hostElement","_tryToRun","WarnedWebAudioUnsupported","isMP3supported","isOGGsupported","unlocked","onAudioUnlockedObservable","onAudioLockedObservable","_outNode","mainBusOutNode","isFormatValid","_resumeAudioContextAsync","once","passive","signal","AbortSignal","getGlobalVolume","newVolume","connectToAnalyser","analyser","_connectedAnalyser","_Registered$9N","AudioEngineFactory","SoundTrack","_isInitialized","soundCollection","_options","soundTracks","_outputAudioNode","createGain","_initializeSoundTrackAudioGraph","connectToSoundTrackAudioNode","soundTrackId","mainSoundTrack","removeSound","switchPanningModelToHRTF","switchPanningModelToEqualPower","BabylonFileParsers","IndividualBabylonFileParsers","AddParser","parser","GetParser","AddIndividualParser","GetIndividualParser","jsonData","parserName","AudioSceneComponent","audioEnabled","_audioEnabled","headphone","_headphone","audioPositioningRefreshRate","audioListenerPositionProvider","audioListenerRotationProvider","_cachedCameraDirection","_cachedCameraPosition","_lastCheck","_invertMatrixTemp","_cameraDirectionTemp","registerStep","_afterRender","soundtrack","soundId","autoplay","addSound","_mainSoundTrack","scIndex","disableAudio","enableAudio","isPaused","switchAudioModeForHeadphones","switchAudioModeForNormalSpeakers","listeningCamera","_CameraDirection","useCustomAttenuation","updateDistanceFromListener","_Registered$9M","soundClass","loadedSounds","loadedSound","parsedData","parsedSound","compo","mainTrack","sdIndex","_SceneComponentInitialization","_SpatialAudioDefaults","coneInnerAngle","coneOuterAngle","coneOuterVolume","distanceModel","maxDistance","minDistance","panningModel","rolloffFactor","_HasSpatialAudioOptions","spatialEnabled","spatialAutoUpdate","spatialConeInnerAngle","spatialConeOuterAngle","spatialConeOuterVolume","spatialDistanceModel","spatialMaxDistance","spatialMinDistance","spatialMinUpdateTime","spatialOrientation","spatialPanningEnabled","spatialPanningModel","spatialPosition","spatialRolloffFactor","spatialRotation","spatialRotationQuaternion","AbstractSpatialAudio","disconnectAll","it","_VolumeAudioDefaults","_VolumeAudioSubNode","_AbstractAudioSubNode","subGraph","getSubNode","_AudioAnalyzerDefaults","EmptyByteTimeDomainData","EmptyFloatTimeDomainData","_HasAudioAnalyzerOptions","analyzerEnabled","analyzerFFTSize","analyzerMinDecibels","analyzerMaxDecibels","analyzerSmoothing","AbstractAudioAnalyzer","_AudioAnalyzerSubNode","smoothing","_SetAudioAnalyzerProperty","callOnSubNode","EmptyByteFrequencyData","EmptyFloatFrequencyData","_fftSize","_maxDecibels","_minDecibels","_smoothing","_subGraph","_GetAudioAnalyzerSubNode","removeSubNodeAsync","subNode","createAndAddSubNodeAsync","enableAsync","getFloatTimeDomainData","_analyzer","_AudioAnalyzer","_GetVolumeAudioSubNode","_GetVolumeAudioProperty","AbstractSoundSource","AbstractAudioOutNode","_spatialAutoUpdate","_spatialMinUpdateTime","_outBus","_spatial","_onOutBusDisposed","outBus","spatial","_initSpatialProperty","_createSpatialProperty","_isSpatial","_StereoAudioDefaults","_HasStereoAudioOptions","stereoEnabled","stereoPan","AbstractStereoAudio","_StereoAudioSubNode","pan","_pan","_SetStereoAudioProperty","_SpatialAudioSubNode","_SetSpatialAudioProperty","TmpQuaternion$1","D2r$1","R2d$1","_lastOrientation","_inputNode","_attenuationNode","_attenuation","PannerNode","_orientationX","orientationX","_orientationY","orientationY","_orientationZ","_connectActiveInput","coneOuterGain","_updateAttenuation","refDistance","_panningEnabled","rotated","TmpMatrix$2","attenuation","clampedDistance","StereoPannerNode","_createSubNodePromises","_subNodes","_onSubNodeDisposed","_onSubNodesChanged","_createSubNodePromisesResolvedAsync","_createSubNode","subNodes","all","_addSubNode","_byteFrequencyData","_byteTimeDomainData","_floatFrequencyData","_floatTimeDomainData","_analyzerNode","AnalyserNode","_clearArrays","_outputNode","_owner","hasAnalyzerOptions","analyzerNode","volumeNode","inNode","_WebAudioAnalyzerSubNode","_CreateAudioAnalyzerSubNodeAsync","_VolumeWebAudioSubNode","_CreateVolumeAudioSubNodeAsync","_WebAudioBaseSubGraph","hasSpatialOptions","_super","initAsync","_GetSpatialAudioSubNode","hasStereoOptions","_GetStereoAudioSubNode","_SpatialWebAudioSubNode","_CreateSpatialAudioSubNodeAsync","_StereoWebAudioSubNode","_CreateStereoAudioSubNodeAsync","spatialNode","stereoNode","inSubNode","_coneInnerAngle","_coneOuterAngle","_coneOuterVolume","_distanceModel","_maxDistance","_minDistance","_panningModel","_orientation","attachedNode","_rolloffFactor","webAudioNode","_stereo","_webAudioNode","_mediaStreamAudioElement","_stopMediaStreamTracksOnDispose","_attachMediaStreamSink","_WebAudioSoundSource","_SubGraph","mediaElement","muted","srcObject","_startMediaStreamSinkAsync","_StereoAudio","getTracks","_SpatialWebAudio","_WebAudioBusAndSoundSubGraph","_newestInstance","_privateInstances","_state","_instances","onEndedObservable","onStateChangedObservable","_onInstanceStateChanged","activeInstancesCount","_getNewestInstance","maxInstances","_beforePlay","_onInstanceEnded","_afterPlay","_setState","_stopExcessInstances","startedInstances","numberOfInstancesToStop","AbstractSound","loopStart","loopEnd","playbackRate","StaticSoundBufferId","StaticSoundBuffer","_AbstractSoundInstance","_StaticSoundInstance","AudioBuffer","cloneAsync","cloneBuffer","_WebAudioStaticSoundInstance","_audioBuffer","_initFromUrlAsync","_initFromUrlsAsync","skipCodecCheck","_initFromArrayBufferAsync","channelCount","numberOfChannels","sampleRate","audioBuffer","copyToChannel","getChannelData","decodeAudioData","FetchAsync","_LoadArrayBufferFromUrlAsync","at","_enginePlayTime","_enginePauseTime","_isConnected","_pitch","_playbackRate","_sourceNode","_onEnded","_deinitSourceNode","_onEngineStateChanged","_volumeNode","_initSourceNode","timeSinceLastStart","sourceNode","elapsed","timeToLoopEnd","wasStarted","engineStopTime","AudioBufferSourceNode","detune","_preloadedInstances","preloadCount","preloadCompletedCount","preloadInstanceAsync","_createInstance","_addPreloadedInstance","preloadedPromise","_removePreloadedInstance","onInstanceStateChanged","_StreamingSoundInstance","_rejectPreloadedPromise","_resolvePreloadedPromise","preloadInstancesAsync","_WebAudioStreamingSoundInstance","_currentTimeChangedWhilePaused","_isReadyPromise","_rejectIsReadyPromise","_onCanPlayThrough","_mediaElement","_onError","_onUserGesture","_initFromUrl","_initFromUrls","HTMLMediaElement","_initFromMediaElement","_play","_stop","currentSrc","urls","_playWhenReady","TmpRampOptions","TmpPlayOptions","TmpStopOptions","D2r","R2d","Sound","_soundV2","_optionsV2","_initSpatial","spatialSound","newValue","_onReadyObservable","_localDirection","_isReadyToPlay","_isDirectional","_isOutputConnected","_url","_onReadyToPlay","_readyToPlayCallback","_onended","onended","RegisterAudioSceneComponent","_customAttenuationFunction","currentVolume","currentDistance","optionsV2","streaming","audioEngineV2","createSoundV2","streamingOptionsV2","urlOrArrayBuffer","_connectedTransformNode","setAudioBuffer","setPlaybackRate","updated","_updateSpatialParameters","soundTrackAudioNode","outputNode","setDirectionalCone","directionalConeInnerAngle","directionalConeOuterAngle","setLocalDirectionToMesh","newLocalDirection","_updateDirection","getDistanceToCamera","setAttenuationFunction","newPlaybackRate","getPlaybackRate","_onRegisterAfterWorldMatrixUpdate","currentOptions","clonedSound","getAudioBuffer","getSoundGain","connectedMeshId","isDirectional","localDirectionToMesh","sourceSound","soundName","soundUrl","newSound","setBufferAndRun","soundPosition","connectedMesh","attachToMesh","_Registered$9L","WeightedSound","weightSum","invWeightSum","_weights","_currentIndex","randomValue","AbstractAudioBus","MainAudioBus","AudioParameterRampShape","SoundState","SpatialAudioAttachmentType","_WebAudioBus","_WebAudioMainBus","_BakedVertexAnimationManager_texture_accessor_storage","_BakedVertexAnimationManager_isEnabled_accessor_storage","_texture","_texture_initializers","_texture_extraInitializers","_isEnabled_initializers","_isEnabled_extraInitializers","_animationParameters_initializers","_time_extraInitializers","setAnimationParameters","speedFramesPerSecond","vatMap","_texture_decorators","_isEnabled_decorators","_animationParameters_decorators","_time_decorators","_animationParameters_extraInitializers","ThinTexture","_wrapU","_wrapV","shareDepth","_cachedSize","_initialSamplingMode","_IsRenderTargetWrapper","_cachedBaseSize","updateTextureSamplingMode","releaseInternalTexture","_b$3","_hasAlpha","getAlphaFromRGB","_getAlphaFromRGB","_coordinatesIndex","_coordinatesMode","_isCube","_gammaSpace","_linearSpecularLOD","isBlocking","loadingError","_loadingError","errorObject","_errorObject","sceneOrEngine","displayName","_displayName_initializers","__hasAlpha_initializers","__hasAlpha_extraInitializers","__getAlphaFromRGB_initializers","__getAlphaFromRGB_extraInitializers","_level_initializers","_level_extraInitializers","__coordinatesIndex_initializers","__coordinatesIndex_extraInitializers","_optimizeUVAllocation_initializers","_optimizeUVAllocation_extraInitializers","__coordinatesMode_initializers","__coordinatesMode_extraInitializers","_wrapR_initializers","_invertZ_initializers","_invertZ_extraInitializers","_lodLevelInAlpha_initializers","_lodLevelInAlpha_extraInitializers","_forceSerialize","_IsScene","getRefractionTextureMatrix","canRescale","_getFromCache","_getEngine","correctedUseSRGBBuffer","texturesCache","getLoadedTexturesCache","texturesCacheEntry","sampling","incrementReferences","_fromContextLost","noDataConversion","maxWidth","_readTexturePixels","_readPixelsSync","_readTexturePixelsSync","allowEmptyName","WhenAllReady","numRemaining","onLoadObservable","_displayName_decorators","__getAlphaFromRGB_decorators","__coordinatesIndex_decorators","__coordinatesMode_decorators","_get_wrapU_decorators","_get_wrapV_decorators","_wrapR_decorators","_anisotropicFilteringLevel_decorators","_get_isCube_decorators","_get_is3D_decorators","_get_is2DArray_decorators","_get_gammaSpace_decorators","_invertZ_decorators","_lodLevelInAlpha_decorators","_get_lodGenerationOffset_decorators","_get_lodGenerationScale_decorators","_get_linearSpecularLOD_decorators","_get_irradianceTexture_decorators","_isRenderTarget_decorators","__hasAlpha_decorators","_level_decorators","_optimizeUVAllocation_decorators","_wrapR_extraInitializers","_anisotropicFilteringLevel_initializers","_anisotropicFilteringLevel_extraInitializers","GenerateBase64StringFromPixelData","npixels","ctx","createImageData","putImageData","canvas2","ctx2","translate","GenerateBase64StringFromTextureAsync","texture_1","_a$3","BaseTexture","forceSphericalPolynomialsRecompute","CopyTools","GenerateBase64StringFromTexture","_CreateVideoTexture","TRILINEAR_SAMPLINGMODE","settings","_noMipmap","_isBlocking","_invertY","_url_initializers","uOffset","_url_extraInitializers","_uOffset_initializers","vOffset","_uOffset_extraInitializers","_vOffset_initializers","uScale","_vOffset_extraInitializers","_uScale_initializers","vScale","_uScale_extraInitializers","_vScale_initializers","uAng","_vScale_extraInitializers","_uAng_initializers","vAng","_uAng_extraInitializers","_vAng_initializers","wAng","_vAng_extraInitializers","_wAng_initializers","uRotationCenter","_wAng_extraInitializers","_uRotationCenter_initializers","vRotationCenter","_uRotationCenter_extraInitializers","_vRotationCenter_initializers","wRotationCenter","_vRotationCenter_extraInitializers","_wRotationCenter_initializers","homogeneousRotationInUVTransform","_wRotationCenter_extraInitializers","_homogeneousRotationInUVTransform_initializers","_rowGenerationMatrix","_cachedTextureMatrix","_projectionModeMatrix","_t0","_t1","_t2","_cachedUOffset","_cachedVOffset","_cachedUScale","_cachedVScale","_cachedUAng","_cachedVAng","_cachedWAng","_cachedReflectionProjectionMatrixId","_cachedURotationCenter","_cachedVRotationCenter","_cachedWRotationCenter","_cachedHomogeneousRotationInUVTransform","_cachedIdentity3x2","_cachedReflectionTextureMatrix","_cachedReflectionUOffset","_cachedReflectionVOffset","_cachedReflectionUScale","_cachedReflectionVScale","_deleteBuffer","_format","_delayedOnLoad","_delayedOnError","noMipmapOrOptions","_loaderOptions","_forcedExtension","_invertVScale","errorHandler","OnTextureLoadErrorObservable","loadObserver","useDelayedTextureLoading","updateURL","existingOnLoad","_prepareRowForTextureGeneration","uBase","previousIdentity3x2","_cachedReflectionCoordinatesMode","PROJECTION_MODE","flagMaterialsAsTextureDirty","savedName","SerializeBuffers","_SerializeInternalTextureUniqueId","base64String","ForceSerializeBuffers","internalTextureUniqueId","internalTextureLabel","parsedTexture","parsedCustomTexture","updateSamplingMode","_samplingMode","_CubeTextureParser","hasInternalTextureUniqueId","mirrorPlane","_CreateMirror","renderTargetSize","mirrorTexture","_waitingRenderList","renderTargetTexture","probe","_CreateRenderTargetTexture","isVideo","noPrefixBase64String","UseSerializedUrlIfAny","CreateFromBase64String","LoadFromDataString","_url_decorators","_uOffset_decorators","_vOffset_decorators","_uScale_decorators","_vScale_decorators","_uAng_decorators","_vAng_decorators","_wAng_decorators","_uRotationCenter_decorators","_vRotationCenter_decorators","_wRotationCenter_decorators","_homogeneousRotationInUVTransform_decorators","_get_isBlocking_decorators","jsonTexture","MIRROR_ADDRESSMODE","_Registered$9K","Texture","RawTexture","waitDataToBeReady","CLAMP_ADDRESSMODE","_waitingForData","updateMipLevel","rawTexture","CreateLuminanceTexture","CreateLuminanceAlphaTexture","CreateAlphaTexture","CreateRGBTexture","CreateRGBATexture","CreateRGBAStorageTexture","CreateRTexture","CreateRStorageTexture","Skeleton","useTextureToStoreBoneMatrices","_useTextureToStoreBoneMatrices","_canUseTextureForBones","_meshesWithPoseMatrix","_identity","_absoluteTransformIsDirty","onBeforeComputeObservable","engineCaps","_transformMatrices","nBones","boneDict","sourceBones","dimensionsAtRest","sourceBone","getHighestFrame","sceneAnimatables","rangeAnimatable","sceneAnimatable","_computeTransformMatrices","targetMatrix","initialSkinMatrix","mappedIndex","_computeTextureSize","requiredElementCount","requiredTextureWidth","requiredTextureHeight","dontCheckFrameId","requiredTransformBufferElementCount","needsUpdate","_synchronizedWithMesh","meshTextureSize","meshTextureElementCount","serializedBone","parentBoneIndex","rest","linkedTransformNodeId","linkedTransformNodeUniqueId","parsedSkeleton","parsedBone","parsedBoneIndex","_hasWaitingData","_waitingTransformNodeId","computeAbsoluteTransforms","visited","_sortBones","setCurrentPoseAsRest","_Registered$9J","createDepthStencilTexture","_createDepthStencilCubeTexture","_createDepthStencilTexture","ObjectRenderer","_unObserveRenderList","_renderListHasChanged","disableImageProcessing","_disableImageProcessing","_sceneUBOs","_renderPassIds","currentRefreshId","_currentRefreshId","setMaterialForRendering","numPasses","setMaterialForRenderPass","_checkReadiness","_prepareRenderingManager","_functionName","newLength","particleSystemList","spriteManagerList","getCustomRenderList","renderMeshes","forceLayerMaskCheck","enableBoundingBoxRendering","enableOutlineRendering","dontSetTransformationMatrix","onBeforeRenderingManagerRenderObservable","onAfterRenderingManagerRenderObservable","onInitRenderingObservable","onFinishRenderingObservable","onFastPathRenderObservable","_refreshRate","_currentApplyByPostProcessSetting","_activeBoundingBoxes","_currentSceneCamera","doNotChangeAspectRatio","enableClusteredLights","_createRenderPassId","LIGHTTYPEID_CLUSTERED_CONTAINER","_updateBatches","_currentSceneUBOIndex","_sceneUBOIsMultiview","activeRenderTarget","_createSceneUBO","resetRefreshCounter","refreshRate","prepareRenderList","renderListPredicate","sceneMeshes","_currentSceneUBO","_getSceneUBO","_defaultRenderListPrepared","finishRender","passIndex","outlineRenderer","currentRenderList","outlineRendererIsEnabled","defaultRenderList","getActiveMeshes","defaultRenderListLength","currentRenderListLength","customIsReadyFunction","checkLayerMask","winterIsComing","currentFrameId","isMasked","cameraForLOD","meshToRenderAndFrameId","_preActiveMesh","_prepareSkeleton","newRenderer","renderListLength","removeObjectRenderer","REFRESHRATE_RENDER_ONCE","REFRESHRATE_RENDER_ONEVERYFRAME","RenderTargetTexture","_objectRenderer","_prePassEnabled","_prePassRenderTarget","onAfterUnbind","_onAfterUnbindObserver","onAfterUnbindObservable","onBeforeRender","onAfterRender","onClear","_onClearObserver","_renderTarget","renderTargetOptions","_renderTargetOptions","_onRatioRescale","_sizeRatio","_initialSizeParameter","_boundingBoxSize","colorAttachment","existingObjectRenderer","noColorAttachment","ignoreCameraViewport","_samples","_canRescale","_dontDisposeObjectRenderer","_disableEngineStages","_dumpToolsLoading","_processSizeParameter","getRenderLayers","_currentFaceIndex","_currentLayer","_doNotChangeAspectRatio","_debugPushGroup","_debugPopGroup","saveGenerateMipMaps","_postProcessManager","_currentUseCameraPostProcess","_currentDumpForDebug","_dumpTools","_resizeObserver","_generateMipMaps","NEAREST_SAMPLINGMODE","createRenderTargetCubeTexture","getRenderSize","_textureMatrix","createRenderTargetTexture","bilinearFiltering","generateStencil","_bestReflectionRenderTargetDimension","setSamples","clearPostProcesses","removePostProcess","disableRescaling","newSize","wasCube","_render","dumpTools_pure","initRender","useCameraPostProcesses","_renderToTarget","renderDimension","curved","_unbindFrameBuffer","generateMipMapsForCubemap","releaseTextures","_onBeforeRenderingManagerRenderObserver","_onAfterRenderingManagerRenderObserver","_onFastPathRenderObserver","REFRESHRATE_RENDER_ONEVERYTWOFRAMES","_Registered$9I","RegisterAbstractEngineTexture","setDepthStencilTexture","DefaultOptions","EffectRenderer","_fullscreenViewport","_indexBufferLength","applyEffectWrapper","effectWrapper","onApplyObservable","_savedStateDepthTest","_savedStateStencilTest","draw","_isRenderTargetTexture","outputTexture","out","restoreStates","EffectWrapper","RegisterShaderCodeProcessing","effectWrapperName","customShaderCodeProcessing","_CustomShaderCodeProcessing","_webGPUReady","_importPromises","creationOptions","uniformNames","samplerNames","attributeNames","useShaderStore","vertexUrl","blockCompilation","extraInitializations","useAsPostProcess","allowEmptySourceTexture","_shaderPath","_postConstructor","importPromises","useWebGPU","ForceGLSL","_gatherImports","postprocess_vertex","postprocess_vertex$1","updateEffect","defineCustomBindings","newUniforms","newSamplers","waitImportsLoaded","_shadersLoaded","createEffect","fragmentUrl","shaderType","noDefaultBindings","_GetShaderCodeProcessing","bindCustomBindings","postProcessName","_effectWrapper","_fragmentUrl","onActivate","_onActivateObserver","onActivateObservable","onSizeChanged","_onSizeChangedObserver","onSizeChangedObservable","onApply","_onApplyObserver","inputTexture","_textures","_currentRenderTextureInd","_forcedOutputTexture","restoreDefaultInputTexture","_camera","texelSize","_shareOutputWithPostProcess","_texelSize","_width_initializers","_width_extraInitializers","_height_initializers","nodeMaterialSource","_height_extraInitializers","renderTargetSamplingMode","_renderTargetSamplingMode_initializers","_renderTargetSamplingMode_extraInitializers","_clearColor_initializers","_clearColor_extraInitializers","_autoClear_initializers","forceAutoClearInAlphaMode","_autoClear_extraInitializers","_forceAutoClearInAlphaMode_initializers","alphaConstants","_forceAutoClearInAlphaMode_extraInitializers","_alphaConstants_initializers","_alphaConstants_extraInitializers","enablePixelPerfectMode","_enablePixelPerfectMode_initializers","_enablePixelPerfectMode_extraInitializers","_forceFullscreenViewport_initializers","_forceFullscreenViewport_extraInitializers","scaleMode","_scaleMode_initializers","alwaysForcePOT","_scaleMode_extraInitializers","_alwaysForcePOT_extraInitializers","__samples_initializers","adaptScaleToCurrentViewport","__samples_extraInitializers","_adaptScaleToCurrentViewport_initializers","_adaptScaleToCurrentViewport_extraInitializers","_reusable","externalTextureSamplerBinding","_textureCache","_scaleRatio","RegisterPostProcess","reusable","_useExistingThinPostProcess","_textureType","_textureFormat","_vertexUrl","_parameters","_disposeTextures","_postProcessDefines","_createRenderTargetTexture","postProcessChannel","textureOptions","tex","lastUsedRenderId","_flushTextureCache","currentlyUsed","needMipMaps","forceDepthStencil","firstPP","_getTarget","cameraOrScene","maxSize","desiredWidth","desiredHeight","updateRenderTargetTextureSampleCount","setAlphaConstants","_disposeTextureCache","setPrePassRenderer","_prePassEffectConfiguration","addEffectConfiguration","getCamera","cameraId","postProcessType","parsedPostProcess","_Parse","targetCamera","_get_name_decorators","_width_decorators","_height_decorators","_renderTargetSamplingMode_decorators","_clearColor_decorators","_autoClear_decorators","_forceAutoClearInAlphaMode_decorators","_get_alphaMode_decorators","_alphaConstants_decorators","_enablePixelPerfectMode_decorators","_forceFullscreenViewport_decorators","_scaleMode_decorators","__samples_decorators","_adaptScaleToCurrentViewport_decorators","_alwaysForcePOT_decorators","_Registered$9H","postProcessInput","setTextureFromPostProcess","setTextureFromPostProcessOutput","PostProcess","ThinPassPostProcess","pass_fragment","pass_fragment$1","FragmentUrl","ThinPassCubePostProcess","passCube_fragment","passCube_fragment$1","_face","PassPostProcess","_get_face_decorators","_Registered$9G","useBilinearMode","passPostProcess","BILINEAR_SAMPLINGMODE","disposeFramebufferObjects","encodedTexture","GetTextureDataAsync","forceRTT","WhenTextureReadyAsync","is3DTexture","textureWidth","textureHeight","targetWidth","IsCompressedTextureFormat","targetHeight","face_1","lod_1","sourceInternalTexture","lodPostProcess","lod3D_fragment","lodCube_fragment","lod_fragment","lod3D_fragment$1","lodCube_fragment$1","lod_fragment$1","NEAREST_NEAREST_MIPNEAREST","faceDefines","NEAREST_NEAREST","ReadPixelsUsingRTT","data2","pixelCount","expectedLength","normalizedData","pixel","c0","TextureTools","CreateResizedCopy","ApplyPostProcess","VertexAnimationBaker","meshOrSkeleton","bakeVertexDataSync","halfFloat","floatsPerFrame","frameIdx","frameCount","textureIndex","_executeAnimationFrameAsync","frameIndex","_reject","textureFromBakedVertexData","boneCount","serializeBakedVertexDataToObject","stringify","json","loadBakedVertexDataFromObject","_zoomStopsAnimation","_idleRotationSpeed","_idleRotationWaitTime","_idleRotationSpinupTime","targetAlpha","_attachedCamera","_isPointerDown","_lastInteractionTime","_cameraRotationSpeed","_lastFrameRadius","zoomStopsAnimation","idleRotationSpeed","speed","idleRotationWaitTime","idleRotationSpinupTime","rotationInProgress","_onPrePointerObservableObserver","pointerInfoPre","_onAfterCheckInputsObserver","_reachTargetAlpha","dt","_applyUserInteraction","timeToRotation","customTime","_userIsZooming","inertialRadiusOffset","_shouldAnimationStopForInteraction","zoomHasHitLimit","_userIsMoving","inertialAlphaOffset","inertialBetaOffset","inertialPanningX","inertialPanningY","transitionDuration","lowerRadiusTransitionRange","upperRadiusTransitionRange","_radiusIsAnimating","_radiusBounceTransition","autoTransitionRange","_autoTransitionRange","_onMeshTargetChangedObserver","onMeshTargetChangedObservable","diagonal","_isRadiusAtLimit","_applyBoundRadiusAnimation","radiusLimit","BouncingBehavior","EasingMode","_cachedWheelPrecision","wheelPrecision","radiusDelta","_clearAnimationLocks","onTargetFramingAnimationEndObservable","FramingBehavior","FitFrustumSidesMode","_radiusScale","_positionScale","_defaultElevation","_elevationReturnTime","_elevationReturnWaitTime","_framingTime","autoCorrectCameraLimitsAndSensibility","_betaIsAnimating","radiusScale","positionScale","defaultElevation","elevation","elevationReturnTime","elevationReturnWaitTime","framingTime","zoomOnMesh","_maintainCameraAboveGround","focusOnOriginXZ","zoomOnBoundingInfo","zoomOnMeshHierarchy","zoomOnMeshesHierarchy","zoomTarget","zoomTargetY","_vectorTransition","_calculateLowerRadiusFromModelBoundingSphere","lowerRadiusLimit","panningSensibility","_radiusTransition","useInputToRestoreState","upperRadiusLimit","timeSinceInteraction","defaultBeta","limitBeta","_betaTransition","isUserIsMoving","IgnoreBoundsSizeMode","InterpolatingBehavior","isInterpolating","remainingDurationMs","remaining","remainingFrames","_FrameRate","_promiseResolve","_onPropertyAnimationEnd","propertyName","updateProperties","animatePropertiesAsync","easingFn","updateAnimation","GetAnimationType","IsMatrixLike","IsVector3Like","IsVector2Like","IsColor3Like","IsColor4Like","IsSizeLike","_updateCameraClipPlanes","horizonDist","planetRadius","altitude","rotatedDirection","AttachToBoxBehavior","_ui","distanceAwayFromFace","distanceAwayFromBottomOfFace","FaceDirectionInfo","_tmpMatrix","_tmpVector","_zeroVector","_lookAtTmpMatrix","_faceVectors","targetDirection","_lookAtToRef","cameraPos","devicePosition","_closestFace","facingUp","_onRenderObserver","FadeInOutBehavior","fadeInDelay","fadeOutDelay","_ownerNode","fadeInTime","fadeOutTime","_millisecondsPerFrame","_hovered","_hoverValue","_delay","_time","_detachObserver","_setAllVisibility","_attachObserver","ownerNode","fadeIn","fadeOut","PickingCustomization","Ray","intersectsBoxMinMax","intersectionTreshold","newMinimum","newMaximum","inv","maxValue","intersectsSphere","rr","vertex0","edge1","edge2","pvec","invdet","qvec","bw","intersectsPlane","result1","result2","_tmpRay","_comparePickingInfo","pickingInfoA","pickingInfoB","sega","segb","threshold","rsegb","_Rayl","discriminant","sN","sD","tN","tD","sc","_Smallnum","qtc","tc","qsc","dP","_RayDistant","unprojectRayToRef","CreateNewFromTo","CreateFromToToRef","sourceY","nearScreenSource","farScreenSource","nearVec3","farVec3","CreatePickingRayToRef","cameraViewport","levelInv","getHardwareScalingLevel","CreatePickingRayInCameraSpaceToRef","toGlobal","InternalPickForMesh","rayFunction","InternalPickForMeshWithRay","GetThinInstancePickingIntersectionThreshold","ThinInstanceIntersectsRawBoundingInfo","InternalPick","computeWorldMatrixForCamera","currentCamera","picker","internalPickerForMesh","useFastPath","forceCompute","thinInstanceIntersectionThreshold","GetThinInstanceRawBoundingInfo","thinMatrix","combinedWorld","thinInstanceCount","thinInstanceRay","thinInstanceRawBoundingInfo","InternalMultiPick","pickingInfos","PickWithBoundingInfo","_tempPickingRay","CreatePickingRay","Pick","PickWithRay","_pickWithRayInverseMatrix","_cachedRayForTransform","MultiPick","GetForwardRay","GetForwardRayToRef","worldForward","cameraClass","_Registered$9F","AddRayExtensions","CreatePickingRayInCameraSpace","pickWithBoundingInfo","MultiPickWithRay","PivotTools","_RemoveAndStorePivotPoint","_OldPivotPoint","_PivotPostMultiplyPivotMatrix","_PivotTranslation","_PivotTmpVector","_PivotCached","_RestorePivotPoint","setPivotPoint","CreatePlaneVertexData","_GetDefaultSideOrientation","sourcePlane","setDirection","_FeaturesWithSpecificDisableWarning","_Registered$9E","PointerDragBehavior","currentDraggingPointerID","currentDraggingPointerId","onEnabledObservable","_useAlternatePickedPointAboveMaxDragAngleDragSpeed","_activeDragButton","maxDragAngle","dragButtons","_useAlternatePickedPointAboveMaxDragAngle","dragging","dragDeltaRatio","_debugMode","_moving","onDragObservable","onDragStartObservable","onDragEndObservable","moveAttached","startAndReleaseDragOnPointerEvents","detachCameraControls","useObjectOrientationForDragging","allowOtherButtonsDuringDrag","_alternatePickedPoint","_worldDragAxis","_targetPosition","_attachedToElement","_startDragRay","_lastPointerRay","_pointA","_pointC","_localAxis","_lookAt","optionCount","dragAxis","dragPlaneNormal","isNearGrabbable","_PlaneScene","lastDragPosition","pickPredicate","_pointerObserver","_activePointerInfo","_startDrag","releaseDrag","_AnyMouseId","MouseEvent","_moveDrag","_beforeRenderObserver","validateDrag","needMatrixUpdate","dragPlanePoint","arcRotateCamera","noPreventDefault","_useCtrlForPanning","_panningMouseButton","fromRay","startPickedPoint","lastRay","_updateDragPlanePosition","_pickWithRayOnDragPlane","updateDragPlane","additionalTransformNode","dragLength","_dragDelta","dragDistance","_dragPlane","planeNormal","planePosition","MultiPointerScaleBehavior","_startDistance","_initialScale","_targetScale","_sceneRenderObserver","_dragBehaviorA","_dragBehaviorB","_getCurrentDistance","dragBehaviors","addBehavior","change","removeBehavior","_virtualMeshesInfo","_tmpQuaternion","_dragType","DRAG","DRAG_WITH_CONTROLLER","NEAR_DRAG","_dragging","draggableMeshes","zDragFactor","currentDraggingPointerIds","allowMultiPointer","isMoving","_pointerCamera","_VirtualScene","dragMesh","pivotMesh","moving","startingPivotPosition","startingPivotOrientation","startingPosition","startingOrientation","lastOriginPosition","_resetVirtualMeshesPosition","_pointerUpdate2D","originDragDifference","virtualMeshesInfo","localOriginDragDifference","_applyZOffset","controllerGripTransform","controllerAimTransform","cameraForwardVec","originDragDirection","controllerDragDistance","cameraToDrag","controllerToDrag","controllerToDragDistance","minDistanceFromControllerToDragMesh","zOffsetScaling","BaseSixDofDragBehavior","_createVirtualMeshInfo","isXRPointer","isNearXRPointer","attachedToElement","_targetDragStart","registeredPointerIndex","_reattachCameraControls","_targetDragEnd","_pointerUpdateXR","_targetDrag","_targetOrientation","_targetScaling","_startingPosition","_startingOrientation","_startingScaling","onPositionChangedObservable","rotateDraggedObject","rotateAroundYOnly","rotateWithMotionController","disableMovement","faceCameraOnDragStart","_virtualTransformNode","deltaToAdd","deltaToAddTransformed","parentRotationMatrixInverse","rotationToApply","parentRotationInverse","invertInPlace","transformationLocalOrigin","worldDeltaPosition","worldDeltaRotation","_twoPointersPositionUpdated","startingPosition0","startingPosition1","startingCenter","startingVector","currentPosition0","currentPosition1","currentCenter","currentVector","oldParent","positionOffset","pointerCount","worldPivot","toCamera","_onePointerPositionUpdated","previousFaceCameraFlag","_attachedMesh","_attachPointLocalOffset","_workingPosition","_workingQuaternion","_lastTick","_hit","hitNormalOffset","interpolatePose","keepOrientationVertical","maxStickingDistance","updateAttachPoint","_addObservables","_removeObservables","_getTargetPose","pickedNormal","getNormal","worldTarget","_getAttachPointOffsetToRef","findAndUpdateTarget","subPicking","intersectsMeshes","pose","storedQuat","boundingMinMax","invWorld","worldOffset","interpolatedPosition","tick","_updateTransformToGoal","_onBeforeRender","_tmpVectors","_tmpInvertView","_tmpForward","_tmpNodeForward","_tmpPosition","_recenterNextUpdate","ignoreCameraPitchAndRoll","pitchOffset","maxViewVerticalDegrees","maxViewHorizontalDegrees","orientToCameraDeadzoneDegrees","ignoreDistanceClamp","ignoreAngleClamp","verticalMaxDistance","defaultDistance","maximumDistance","minimumDistance","useFixedVerticalOffset","fixedVerticalOffset","followedCamera","_followedCamera","recenter","_distanceClamp","currentToTarget","moveToDefault","_length2D","currentDistance2D","_applyVerticalClamp","invertView","_toOrientationQuatToRef","angularClamped","rotationQuat","minMaxAngle","_angleBetweenVectorAndPlane","toFollowed","leashToFollow","_applyPitchOffset","nodeForward","_angularClamp","distanceClamped","_orientationClamp","currentDirection","_updateLeashing","feature","WebXRFeatureName","ANCHOR_SYSTEM","BACKGROUND_REMOVER","HIT_TEST","MESH_DETECTION","PHYSICS_CONTROLLERS","PLANE_DETECTION","POINTER_SELECTION","TELEPORTATION","FEATURE_POINTS","HAND_TRACKING","IMAGE_TRACKING","NEAR_INTERACTION","DOM_OVERLAY","MOVEMENT","LIGHT_ESTIMATION","EYE_TRACKING","WALKING_LOCOMOTION","LAYERS","DEPTH_SENSING","SPACE_WARP","RAW_CAMERA_ACCESS","BODY_TRACKING","TRACKED_SOURCES","WebXRFeaturesManager","_xrSessionManager","onXRSessionInit","features","getEnabledFeatures","featureName","attached","featureImplementation","disableAutoAttach","attachFeature","onXRSessionEnded","detachFeature","constructorFunction","_AvailableFeatures","latest","stable","ConstructFeature","xrSessionManager","GetAvailableFeatures","GetAvailableVersions","_autoAttachPolicyBeforeAttach","disableAutoAttachBeforeAttach","intentionallyDisabledDuringAttach","disableFeature","Name","moduleOptions","attachIfPossible","required","versionToLoad","GetStableVersionOfFeature","GetLatestVersionOfFeature","conflictingFeature","_ConflictingFeatures","constructFunction","constructed","dependentsFound","every","_ConsumeWebXRFeatureSpecificDisableWarning","isCompatible","emittedSpecificDisableWarning","getEnabledFeature","enabledFeatures","xrNativeFeatureName","nativeName","xrSessionInit","requiredFeatures","optionalFeatures","getXRSessionInitExtension","extended","HandConstraintZone","HandConstraintOrientation","HandConstraintVisibility","HandConstraintBehavior","_node","_zoneAxis","handConstraintVisibility","palmUpStrictness","gazeProximityRadius","targetOffset","targetZone","zoneOrientationMode","nodeOrientationMode","handedness","_getHandPose","hand","_handTracking","getHandByHandedness","pinkyMetacarpal","getJointMesh","middleMetacarpal","wrist","handPose","lastTick","nearInteraction","excludedControllerId","zoneOffset","cameraLookAtQuaternion","targetPosition","targetRotation","_setVisibility","palmVisible","cameraForward","gaze","gazeVisible","_eyeTracking","getEyeGaze","gazeToBehavior","projectedDistance","projectedSquared","palmDirection","linkToXRExperience","xr","featuresManager","BoneIKController","maxAngle","_maxAngle","_setMaxAngle","poleTargetPosition","poleTargetLocalOffset","poleAngle","slerpAmount","_bone1Quat","_bone1Mat","_bone2Ang","_rightHandedSystem","_bendAxis","_slerping","_adjustRoll","_notEnoughInformation","bone1","_bone1","_bone2","bonePos","boneScale1","boneScale2","_bone1Length","_bone2Length","pos1","pos2","pos3","targetMesh","poleTargetMesh","poleTargetBone","bendAxis","ang","_maxReach","poleTarget","mat1","mat2","tmpQuat","getAbsolutePositionToRef","acosa","acosb","angA","angB","angC","_tmpVec","_updateLinkedTransformRotation","BoneLookController","minYaw","_minYaw","_minYawSin","_minYawCos","_maxYaw","_midYawConstraint","_getAngleDiff","_yawRange","maxYaw","_maxYawSin","_maxYawCos","minPitch","_minPitch","_minPitchTan","maxPitch","_maxPitch","_maxPitchTan","upAxisSpace","adjustYaw","adjustPitch","adjustRoll","_boneQuat","_firstFrameSkipped","_fowardAxis","useAbsoluteValueForYaw","yawAxis","pitchAxis","newYawAxis","newPitchAxis","newRollAxis","_transformYawPitch","_transformYawPitchInv","_tmpMat1","_tmpMat2","checkYaw","checkPitch","spaceMat","spaceMatInv","forwardAxis","rightAxis","xzlen","localTarget","newPitch","yawCheck","newYaw","_isAngleBetween","boneFwd","boneRotMat","boneYaw","_getAngleBetween","angBtwMax","boneScaling","ang1","ang2","angDiff","ab","CreateRibbonVertexData","closeArray","closePath","invertUV","defaultOffset","pathArray","customUV","customColors","us","vs","uTotalDistance","minlg","lg","ar1","ar2","idc","closePathCorr","closeArrayCorr","vectlg","dist","path1","path2","vTotalDistance","l1","shft","path1nb","indexFirst","indexLast","positions32","normals32","uvs32","_idx","ns","si","pathPoint","_creationDataStorage","colorIndex","ribbon","_Registered$9D","CreateDiscVertexData","vertexNb","disc","_Registered$9C","generateOctree","_subdivisionsX","_subdivisionsY","subdivisionsX","subdivisionsY","optimize","chunksCount","octreeBlocksSize","getHeightAtCoordinates","tmpVect","_minX","_maxX","_minZ","_maxZ","_heightQuads","_initHeightQuads","_computeHeightQuads","_getFacetAt","getNormalAtCoordinatesToRef","tmpMat","updateCoordinateHeights","col","_width","_height","quad","slope","facet1","facet2","v4","v1v2","v1v3","v1v4","norm1","norm2","cd","d1","d2","GroundMesh","_Registered$9B","CreateGroundVertexData","CreateTiledGroundVertexData","xmin","xmax","tileRow","rowLength","square","zTileMax","zTileMin","xTileMax","xTileMin","tileCol","applyTile","tileSize","CreateGroundFromHeightMapVertexData","alphaFilter","bufferWidth","bufferHeight","heightBuffer","idx1","idx2","idx3","isVisibleIdx1","isVisibleIdx2","isVisibleIdx3","idx4","_setReady","tiledGround","passHeightBufferInCallback","onBufferLoaded","colorFilter","_Registered$9A","CreateBoxVertexData","topBaseAt","bottomBaseAt","topIndex","bottomIndex","basePositions","topFaceBase","bottomFaceBase","topFaceOrder","bottomFaceOrder","flat","scaleArray","currentIndex","faceUV","faceColors","totalColors","CreateSegmentedBoxVertexData","widthSegments","heightSegments","depthSegments","bottomPlane","topPlane","negXPlane","posXPlane","negZPlane","posZPlane","_Registered$9z","CreateTiledPlaneVertexData","flipTile","pattern","tileWidth","tileHeight","alignH","alignHorizontal","alignV","alignVertical","tilesX","tilesY","adjustX","adjustY","startX","startY","uvBase","partialBottomRow","partialTopRow","partialLeftCol","partialRightCol","uvPart","uvBaseBR","uvBaseTR","uvBaseLC","uvBaseRC","_Registered$9y","CreateTiledBoxVertexData","halfDepth","faceVertexData","baseAlignV","facePositions","faceNormals","newFaceUV","op","final","nn","_Registered$9x","RegisterTiledPlaneBuilder","CreateSphereVertexData","diameterX","diameter","diameterY","diameterZ","dedupTopBottomIndices","totalZRotationSteps","totalYRotationSteps","zRotationStep","normalizedZ","angleZ","yRotationStep","normalizedY","angleY","rotationZ","rotationY","afterRotZ","complete","firstIndex","_Registered$9w","diameterTop","diameterBottom","hasRings","enclose","cap","surfaceNb","angleStep","ringVertex","ringNormal","ringFirstVertex","ringFirstNormal","quadNormal","ringIdx","cs","i2","i3","createCylinderCap","isTop","circleVector","vbase","textureScale","textureCoordinate","cylinder","CreateCylinderVertexData","_Registered$9v","CreateTorusVertexData","thickness","outerAngle","innerAngle","dx","dy","nextI","nextJ","torus","_Registered$9u","CreateTorusKnotVertexData","tube","radialSegments","tubularSegments","getPos","cu","su","quOverP","tang","bitan","jNext","torusKnot","_Registered$9t","_currentRank","_maxRank","currentDefines","currentFallbacks","PushMaterial","storeEffectOnSubMeshes","_normalMatrix","_activeEffect","_isReadyForSubMesh","normalMatrix","_mustRebind","_VertexPullingMetadataCache","BindVertexPullingUniforms","OnCreatedEffectParameters","ShaderMaterial","_internalTextures","_textureArrays","_externalTextures","_floats","_ints","_uints","_floatsArrays","_colors3","_colors3Arrays","_colors4","_colors4Arrays","_vectors2","_vectors3","_vectors4","_quaternions","_quaternionsArrays","_matrices","_matrixArrays","_matrices3x3","_matrices2x2","_vectors2Arrays","_vectors3Arrays","_vectors4Arrays","_textureSamplers","_cachedWorldViewMatrix","_cachedWorldViewProjectionMatrix","_multiview","_vertexPullingMetadata","_materialHelperNeedsPreviousMatrices","shaderPath","externalTextures","samplerObjects","storageBuffers","_checkUniform","setInternalTexture","setExternalTexture","setFloats","setColor3Array","setColor4Array","setQuaternionArray","float32Array","setUniformBuffer","setTextureSampler","sampler","setStorageBuffer","trimEnd","existingDefineIdx","defineToAdd","EffectFallbacks","bvaManager","PrepareStringDefinesForClipPlanes","PrepareVertexPullingUniforms","shaderName","previousEffect","previousDefines","maxSimultaneousMorphTargets","effectOverride","useSceneUBO","getMeshUniformBuffer","mustRebind","getCachedMaterial","_transformMatrixR","BindClipPlane","BindFogParameters","engineWebGPU","propValue","textureArrays","ints","uints","floatsArrays","colors3","colors3Arrays","colors4Arrays","vectors2","vectors3","vectors4","matrixArray","matrices3x3","matrices2x2","vectors2Arrays","vectors3Arrays","vectors4Arrays","quaternionsArrays","ShaderMaterialParse","textureArray","matrixArrayAccess","ShaderMaterialParseFromFileAsync","scene_1","snippetId_1","shaderMaterial","ShaderMaterialParseFromSnippetAsync","_Registered$9s","ShaderMaterialCreateFromSnippetAsync","_c$2","_d$2","LinesMesh","_color4","color_vertex","color_fragment","color_vertex$1","color_fragment$1","_ownsMaterial","_setInternalMaterial","_subMesh","colorEffect","_isShaderMaterial","doNotDisposeMaterial","createOptions","InstancedLinesMesh","_Registered$9r","CreateLineSystemVertexData","vertexColors","dashSize","gapSize","dashNb","curvect","curshft","dashshft","vertexColor","lineColors","lineSystem","nbSeg","updateMeshPositions","dashedLines","CreateDashedLinesVertexData","_a$2","_b$2","LinesBuilder","_Registered$9q","originalPoints","IndexedVector2","lmin","lmax","Polygon","Rectangle","ymin","ymax","Circle","numberOfSides","StartingAt","PolygonMeshBuilder","_addToepoint","_epoints","contours","earcut","PolygonPoints","_outlinepoints","_holes","_eholes","bjsEarcut","earcutInjection","addHole","hole","holepoints","build","smoothingThreshold","buildVertexData","computeBounds","bounds","totalCount","positionscount","_addSide","vc","vp","vn","vcNorm","vnNorm","vpNorm","dotp","dotn","ulength","CreatePolygonVertexData","wrp","disp","distX","distZ","totalLen","cumulate","holes","polygonTriangulation","hNb","hPoint","PolygonBuilder","_Registered$9p","closeShape","capFunction","ExtrudeShapeGeneric","adjustFrame","tmpVector3","rotationFunction","ribbonCloseArray","ribbonClosePath","scaleVectorFunction","scaleFunction","path3D","shapePaths","rotateFunction","custom","binormals","getBinormals","getDistances","rotate","scl","shapePath","scaleRatio","planed","pointCap","barycenter","capPath","scaleVector","storage","extrusionPathArray","extrudedGeneric","rbCA","rbCP","updtbl","_Registered$9o","pi2","paths","_Registered$9n","radiusFunction","radiusFunctionFinal","circlePath","rad","circlePaths","pathIndex","tubePathArray","_Registered$9m","polyhedra","sizeX","sizeY","sizeZ","nbfaces","faceIdx","indexes","fl","polyhedron","CreatePolyhedronVertexData","_Registered$9l","CreateIcoSphereVertexData","radiusX","radiusY","radiusZ","icoVertices","verticesUnaliasId","icoVertexuv","island","faceVertexPos","faceVertexUv","v012","vId","posX0","posX1","posInterp","vertexNormal","centroidX0","c2","centroidX1","uvX0","uvX1","uvInterp","interpVertex","_Registered$9k","XpAxis","XnAxis","YpAxis","YnAxis","ZpAxis","ZnAxis","vertexIdx","vertexIdxForBones","localPositionOverride","localNormalOverride","matrixIndicesOverride","matrixWeightsOverride","DecalVertex","hasSkeleton","hasMorphTargets","useLocalComputation","getPositionData","getNormalsData","localPositions","localNormals","matIndices","matWeights","matIndicesExtra","matWeightsExtra","cameraWorldTarget","extractDecalVector3","vertexId","indexId","captureUVS","clipSize","clipFactor","emptyArray","mat0Index","v0Indices","v0Weights","mat1Index","v1Indices","v1Weights","sumw","v0LocalPositionX","v0LocalPositionY","v0LocalPositionZ","v1LocalPositionX","v1LocalPositionY","v1LocalPositionZ","v0LocalNormalX","v0LocalNormalY","v0LocalNormalZ","interpNormalX","interpNormalY","interpNormalZ","clipResult","nV1","nV2","nV3","v1Out","v2Out","v3Out","clipVertices","nV4","sourceMeshAsMesh","numMatrices","thinInstanceMatrix","ofst","decalWorldMatrix","inverseDecalWorldMatrix","meshWorldMatrix","oneFaceVertices","faceVertices","vIndex","currentVertexDataIndex","decal","_Registered$9j","CreateCapsuleVertexData","capDetail","radiusTop","radiusBottom","heightMinusCaps","thetaLength","capsTopSegments","topCapSubdivisions","capsBottomSegments","bottomCapSubdivisions","indexArray","cosAlpha","sinAlpha","coneLength","vl","indexRow","sinTheta","sinA","cosTheta","coneHeight","i4","vDat","capsule","_Registered$9i","_IsoVector","rotateNeg60About","toCartesianOrigin","isoGridSize","IDATA","PolyhedronData","vecToidx","n1","fr","O","A","oVec","aVec","bVec","oaVec","abVec","obVec","idxR","isoId","isoIdR","verts","closestTo","vDist","vertByDist","edgematch","B","matchIdx","calcCoeffs","thirdR3","LSQD","coau","cobu","coav","cobv","createInnerFacets","innerFacets","edgeVecsABOB","pointR","prevR","nextR","rotate60About","maxPrev","maxLeftPrev","vertexTypes","isoVecsABOB","rotateNeg120","isoVecsOBOA","rotate120","isoVecsBAOA","faceNb","geodesicData","F","oidx","aidx","bidx","OA","OB","mapped","cartesian","tempVec","vert","primVert","distFromO","distFromA","distFromB","vertData","distFrom","category","GeodesicData","innerToData","primTri","mapABOBtoDATA","mapOBOAtoDATA","mapBAOAtoDATA","nearTo","near","nearIndex","sharedNodes","poleNodes","faces","adjVerts","dualFaces","toGoldbergPolyhedronData","goldbergPolyhedronData","verticesNb","cz","adjacentFaces","setOrder","BuildGeodesicData","mapABOBtoOBOA","mapABOBtoBAOA","orderData","CreateGeodesic","_PrimaryIsoTriangle","goldbergData","faceCenters","faceZaxis","faceXaxis","faceYaxis","nbSharedFaces","nbUnsharedFaces","nbFacesAtPole","relatedGoldbergFace","poleOrShared","fromPole","_changeGoldbergFaceColors","colorRange","newCols","uvRange","points5","points6","newUVs","_changeGoldbergFaceUVs","placeOnGoldbergFaceAt","goldberg","GoldbergMesh","_Registered$9h","CreateGoldbergVertexData","ba","ca","pdata","vCoord","CreateGoldberg","ShapePath","resolution","_paths","_tempPaths","_resolution","_currentPath","quadraticCurveTo","cpx","cpy","cpx1","cpy1","cpx2","cpy2","extractHoles","CreateShapePath","char","fontData","glyph","glyphs","outline","moveTo","lineTo","bezierCurveTo","ha","CreateTextShapePaths","chars","text","lineHeight","yMax","yMin","underlineThickness","letterIndex","holeVectors","shapeVectors","localHolesCopy","isPointInside","holePoints","perLetterFaceUV","perLetterFaceColors","bbox","MeshBuilder","CreateSkeletonFromTransformNodeHierarchy","createMesh","boneIndices","boneWeights","boneMesh","boneMeshSize","boneMeshNumVertices","boneMeshPositions","boneMeshIndices","boneMeshNormals","mapNameToBone","currentVertexIndex","StorageBuffer","_create","_bufferSize","createStorageBuffer","clearStorageBuffer","updateStorageBuffer","readFromStorageBuffer","noDelay","_Registered$9g","_alignedBuffer","alignedByteStride","alignedSize","totalLength","sourceData","alignedData","sourceDataAsFloat","numComponents","sourceOffset","IsLittleEndian","wheelPrecisionX","_wheelPrecisionX_initializers","wheelPrecisionY","_wheelPrecisionX_extraInitializers","_wheelPrecisionY_initializers","wheelPrecisionZ","_wheelPrecisionY_extraInitializers","_wheelPrecisionZ_initializers","onChangedObservable","_wheelPrecisionZ_extraInitializers","_wheelDeltaX","_wheelDeltaY","_wheelDeltaZ","_ffMultiplier","_normalize","BackCompatCameraNoPreventDefault","platformScale","_addCameraPointerObserver","_wheel","_removeCameraPointerObserver","checkInputs","wheelDeltaX","wheelDeltaY","wheelDeltaZ","getSimpleName","_wheelPrecisionX_decorators","_wheelPrecisionY_decorators","_wheelPrecisionZ_decorators","_currentMousePointerIdDown","_buttons_initializers","_pointerInput","_buttons_extraInitializers","previousPinchSquaredDistance","previousMultiTouchPanPosition","_pointB","_altKey","_ctrlKey","_metaKey","_shiftKey","_buttonsPressed","isTouch","srcElement","onTouch","onDoubleTap","ed","distY","pinchSquaredDistance","multiTouchPanPosition","onMultiTouch","onButtonUp","onButtonDown","_onLostFocus","onLostFocus","onContextMenu","_contextMenuBind","hostWindow","_evt","_buttons_decorators","CameraInputTypes","CameraInputsManager","_addCheckInputs","inputToRemove","rebuildInputCheck","removeByType","inputType","attachInput","attachElement","ForceAttachControlToAlwaysPreventDefault","detachElement","serializedCamera","inputsmgr","parsedInputs","parsedinput","StickValues","Gamepad","isConnected","browserGamepad","leftStickX","leftStickY","rightStickX","rightStickY","_leftStick","_invertLeftStickY","GAMEPAD","_leftStickAxisX","_leftStickAxisY","_rightStickAxisX","_rightStickAxisY","_rightStick","onleftstickchanged","_onleftstickchanged","onrightstickchanged","_onrightstickchanged","leftStick","rightStick","GENERIC","XBOX","POSE_ENABLED","DUALSHOCK","GenericPad","onbuttondown","_onbuttondown","onbuttonup","_onbuttonup","onButtonDownObservable","onButtonUpObservable","_buttons","_setButtonValue","buttonIndex","gamepadRotationSensibility","_gamepadRotationSensibility_initializers","gamepadMoveSensibility","_gamepadRotationSensibility_extraInitializers","_gamepadMoveSensibility_initializers","_yAxisScale","_gamepadMoveSensibility_extraInitializers","invertYAxis","gamepadManager","_onGamepadConnectedObserver","onGamepadDisconnectedObservable","onGamepadConnectedObservable","_onGamepadDisconnectedObserver","rsValues","normalizedRX","movement","activeInput","rotationAccumulatedPixels","normalizedRY","lsValues","normalizedLY","zoomAccumulatedPixels","_gamepadRotationSensibility_decorators","_gamepadMoveSensibility_decorators","keysUp","_keysUp_initializers","keysDown","_keysUp_extraInitializers","_keysDown_initializers","keysLeft","_keysDown_extraInitializers","_keysLeft_initializers","keysRight","_keysLeft_extraInitializers","_keysRight_initializers","keysReset","_keysRight_extraInitializers","_keysReset_initializers","keysZoomIn","_keysReset_extraInitializers","_keysZoomIn_initializers","keysZoomOut","_keysZoomIn_extraInitializers","_keysZoomOut_initializers","_keysZoomOut_extraInitializers","_panningSensibility_initializers","zoomingSensibility","_panningSensibility_extraInitializers","_zoomingSensibility_initializers","angularSpeed","_zoomingSensibility_extraInitializers","_angularSpeed_initializers","_useAltToZoom","_angularSpeed_extraInitializers","_rotateDirection","_panDirection","useAltToZoom","_applyUseAltToZoomToInputMap","getEntry","modifiers","alt","inputMap","addEntry","interaction","_onCanvasBlurObserver","_onKeyboardObserver","_ctrlPressed","_altPressed","_keyboardModifiers","ctrl","rotateDirection","panDirection","rotateSensitivity","resolveInteraction","_keyboardConditions","panSensitivity","resolved","sensitivity","zoomSens","handlers","zoom","_keysUp_decorators","_keysDown_decorators","_keysLeft_decorators","_keysRight_decorators","_keysReset_decorators","_keysZoomIn_decorators","_keysZoomOut_decorators","_panningSensibility_decorators","_zoomingSensibility_decorators","_angularSpeed_decorators","_get_useAltToZoom_decorators","_wheelPrecision_initializers","zoomToMouseLocation","_wheelPrecision_extraInitializers","_zoomToMouseLocation_initializers","wheelDeltaPercentage","_zoomToMouseLocation_extraInitializers","_wheelDeltaPercentage_initializers","customComputeDeltaFromMouseWheel","_wheelDeltaPercentage_extraInitializers","_viewOffset","_globalOffset","_inertialPanning","_zoomToMouseRadiusOffset","_computeDeltaFromMouseWheelLegacyEvent","mouseWheelDelta","currentAccumulated","estimatedTargetRadius","targetInertia","wheelEntry","_hitPlane","_updateHitPlane","_zoomToMouse","decay","getFrameIndependentDecay","_zeroIfClose","targetScreenOffset","_cameraTransformMatrix","inputScale","getFrameIndependentInputScale","lowerLimit","inertiaComp","upperLimit","directionToZoomLocation","_wheelPrecision_decorators","_zoomToMouseLocation_decorators","_wheelDeltaPercentage_decorators","pinchZoom","_pinchZoom_initializers","multiTouchPanning","_pinchZoom_extraInitializers","_multiTouchPanning_initializers","multiTouchPanAndZoom","_multiTouchPanning_extraInitializers","_multiTouchPanAndZoom_initializers","_isPinching","_multiTouchPanAndZoom_extraInitializers","_twoFingerActivityCount","_shouldStartPinchZoom","_computePinchZoom","_pinchSquaredDistance","_computeMultiTouchPanning","_previousMultiTouchPanPosition","_multiTouchPanPosition","_pinchZoom_decorators","_multiTouchPanning_decorators","_multiTouchPanAndZoom_decorators","angularSensibilityX","_angularSensibilityX_initializers","angularSensibilityY","_angularSensibilityX_extraInitializers","_angularSensibilityY_initializers","pinchPrecision","_angularSensibilityY_extraInitializers","_pinchPrecision_initializers","pinchDeltaPercentage","_pinchPrecision_extraInitializers","_pinchDeltaPercentage_initializers","useNaturalPinchZoom","_pinchDeltaPercentage_extraInitializers","_useNaturalPinchZoom_initializers","_useNaturalPinchZoom_extraInitializers","_pointerLockConditions","_pointerConditions","_pointerModifiers","moveDeltaX","panEntry","panScale","panAccumulatedPixels","moveDeltaY","MinimumRadiusForPinch","_activeEntry","rotateScaleX","sensitivityX","rotateScaleY","sensitivityY","pointA","pointB","pinchToPanMaxDistance","_angularSensibilityX_decorators","_angularSensibilityY_decorators","_pinchPrecision_decorators","_pinchDeltaPercentage_decorators","_useNaturalPinchZoom_decorators","_c$1","_d$1","ArcRotateCameraInputsManager","addMouseWheel","ArcRotateCameraMouseWheelInput","addPointers","ArcRotateCameraPointersInput","addKeyboard","ArcRotateCameraKeyboardMoveInput","addVRDeviceOrientation","_a$1","_b$1","addGamepad","ArcRotateCameraVRDeviceOrientationInput","alphaCorrection","gammaCorrection","_gamma","_deviceOrientationHandler","_onOrientationEvent","DeviceOrientationEvent","requestPermission","_Registered$9f","keysForward","_keysForward_initializers","keysBackward","_keysForward_extraInitializers","_keysBackward_initializers","_keysBackward_extraInitializers","translateEntry","localDirection","_transformedDirection","cameraDirection","_keysForward_decorators","_keysBackward_decorators","buttonsYaw","buttonsPitch","buttonsRoll","activeButton","angularSensibility","_angularSensibility_initializers","_angularSensibility_extraInitializers","rollCorrect","restoreRoll","_rollObserver","_previousPosition","touchEnabled","_onMouseMove","_rotateCamera","rotationChange","bankedTurnLimit","_angularSensibility_decorators","keysHeightOffsetIncr","_keysHeightOffsetIncr_initializers","keysHeightOffsetDecr","_keysHeightOffsetIncr_extraInitializers","_keysHeightOffsetDecr_initializers","keysHeightOffsetModifierAlt","_keysHeightOffsetDecr_extraInitializers","_keysHeightOffsetModifierAlt_initializers","keysHeightOffsetModifierCtrl","_keysHeightOffsetModifierAlt_extraInitializers","_keysHeightOffsetModifierCtrl_initializers","keysHeightOffsetModifierShift","_keysHeightOffsetModifierCtrl_extraInitializers","_keysHeightOffsetModifierShift_initializers","keysRotationOffsetIncr","_keysHeightOffsetModifierShift_extraInitializers","_keysRotationOffsetIncr_initializers","keysRotationOffsetDecr","_keysRotationOffsetIncr_extraInitializers","_keysRotationOffsetDecr_initializers","keysRotationOffsetModifierAlt","_keysRotationOffsetDecr_extraInitializers","_keysRotationOffsetModifierAlt_initializers","keysRotationOffsetModifierCtrl","_keysRotationOffsetModifierAlt_extraInitializers","_keysRotationOffsetModifierCtrl_initializers","keysRotationOffsetModifierShift","_keysRotationOffsetModifierCtrl_extraInitializers","_keysRotationOffsetModifierShift_initializers","keysRadiusIncr","_keysRotationOffsetModifierShift_extraInitializers","_keysRadiusIncr_initializers","keysRadiusDecr","_keysRadiusIncr_extraInitializers","_keysRadiusDecr_initializers","keysRadiusModifierAlt","_keysRadiusDecr_extraInitializers","_keysRadiusModifierAlt_initializers","keysRadiusModifierCtrl","_keysRadiusModifierAlt_extraInitializers","_keysRadiusModifierCtrl_initializers","keysRadiusModifierShift","_keysRadiusModifierCtrl_extraInitializers","_keysRadiusModifierShift_initializers","heightSensibility","_keysRadiusModifierShift_extraInitializers","_heightSensibility_initializers","rotationSensibility","_heightSensibility_extraInitializers","_rotationSensibility_initializers","radiusSensibility","_rotationSensibility_extraInitializers","_radiusSensibility_initializers","_radiusSensibility_extraInitializers","_shiftPressed","_modifierHeightOffset","heightOffset","_modifierRotationOffset","rotationOffset","_modifierRadius","_keysHeightOffsetIncr_decorators","_keysHeightOffsetDecr_decorators","_keysHeightOffsetModifierAlt_decorators","_keysHeightOffsetModifierCtrl_decorators","_keysHeightOffsetModifierShift_decorators","_keysRotationOffsetIncr_decorators","_keysRotationOffsetDecr_decorators","_keysRotationOffsetModifierAlt_decorators","_keysRotationOffsetModifierCtrl_decorators","_keysRotationOffsetModifierShift_decorators","_keysRadiusIncr_decorators","_keysRadiusDecr_decorators","_keysRadiusModifierAlt_decorators","_keysRadiusModifierCtrl_decorators","_keysRadiusModifierShift_decorators","_heightSensibility_decorators","_rotationSensibility_decorators","_radiusSensibility_decorators","axisControlRadius","_axisControlRadius_initializers","axisControlHeight","_axisControlRadius_extraInitializers","_axisControlHeight_initializers","axisControlRotation","_axisControlHeight_extraInitializers","_axisControlRotation_initializers","_axisControlRotation_extraInitializers","_axisControlRadius_decorators","_axisControlHeight_decorators","_axisControlRotation_decorators","axisXControlRadius","_axisXControlRadius_initializers","axisXControlHeight","_axisXControlRadius_extraInitializers","_axisXControlHeight_initializers","axisXControlRotation","_axisXControlHeight_extraInitializers","_axisXControlRotation_initializers","axisYControlRadius","_axisXControlRotation_extraInitializers","_axisYControlRadius_initializers","axisYControlHeight","_axisYControlRadius_extraInitializers","_axisYControlHeight_initializers","axisYControlRotation","_axisYControlHeight_extraInitializers","_axisYControlRotation_initializers","axisPinchControlRadius","_axisYControlRotation_extraInitializers","_axisPinchControlRadius_initializers","axisPinchControlHeight","_axisPinchControlRadius_extraInitializers","_axisPinchControlHeight_initializers","axisPinchControlRotation","_axisPinchControlHeight_extraInitializers","_axisPinchControlRotation_initializers","_warningCounter","_warning","pinchDelta","warningEnable","_axisXControlRadius_decorators","_axisXControlHeight_decorators","_axisXControlRotation_decorators","_axisYControlRadius_decorators","_axisYControlHeight_decorators","_axisYControlRotation_decorators","_axisPinchControlRadius_decorators","_axisPinchControlHeight_decorators","_axisPinchControlRotation_decorators","keysUpward","_keysUpward_initializers","_keysUpward_extraInitializers","keysDownward","_keysDownward_initializers","_keysDownward_extraInitializers","rotationSpeed","_rotationSpeed_initializers","keysRotateLeft","_rotationSpeed_extraInitializers","_keysRotateLeft_initializers","keysRotateRight","_keysRotateLeft_extraInitializers","_keysRotateRight_initializers","keysRotateUp","_keysRotateRight_extraInitializers","_keysRotateUp_initializers","keysRotateDown","_keysRotateUp_extraInitializers","_keysRotateDown_initializers","_keysRotateDown_extraInitializers","rotateEntry","cameraRotation","_getLocalRotation","rotateGain","_keysUpward_decorators","_keysDownward_decorators","_rotationSpeed_decorators","_keysRotateLeft_decorators","_keysRotateRight_decorators","_keysRotateUp_decorators","_keysRotateDown_decorators","_currentActiveButton","onPointerMovedObservable","_allowCameraRotation","_activePointerId","_applyPointerRotation","_CameraProperty","_moveRelative","_rotateRelative","_moveScene","_wheelXAction","MoveRelative","_wheelXActionCoordinate","_wheelYAction","_wheelYActionCoordinate","_wheelZAction","_wheelZActionCoordinate","wheelXMoveRelative","wheelYMoveRelative","wheelZMoveRelative","wheelXRotateRelative","RotateRelative","wheelYRotateRelative","wheelZRotateRelative","wheelXMoveScene","MoveScene","wheelYMoveScene","wheelZMoveScene","cameraTransformMatrix","transformedDirection","_updateCameraProperty","cameraProperty","_set_wheelXMoveRelative_decorators","_set_wheelYMoveRelative_decorators","_set_wheelZMoveRelative_decorators","_set_wheelXRotateRelative_decorators","_set_wheelYRotateRelative_decorators","_set_wheelZRotateRelative_decorators","_set_wheelXMoveScene_decorators","_set_wheelYMoveScene_decorators","_set_wheelZMoveScene_decorators","allowMouse","touchAngularSensibility","_touchAngularSensibility_initializers","touchMoveSensibility","_touchAngularSensibility_extraInitializers","_touchMoveSensibility_initializers","singleFingerRotate","_touchMoveSensibility_extraInitializers","_offsetX","_offsetY","_pointerPressed","_isSafari","previousPosition","isMouseEvent","rotateCamera","_computeLocalCameraSpeed","moveSensitivity","_cameraRotationMatrix","_touchAngularSensibility_decorators","_touchMoveSensibility_decorators","FreeCameraInputsManager","_mouseInput","_mouseWheelInput","FreeCameraKeyboardMoveInput","addMouse","removeMouse","removeMouseWheel","addTouch","FreeCameraTouchInput","addDeviceOrientation","addVirtualJoystick","FreeCameraDeviceOrientationInput","rej","gotValue","eventHandler","_screenOrientationAngle","_screenQuaternion","_beta","_onDeviceOrientationChangedObservable","_orientationChanged","screen","_deviceOrientation","_constantTransform","_Registered$9e","_deviceOrientationInput","gamepadAngularSensibility","_gamepadAngularSensibility_initializers","_gamepadAngularSensibility_extraInitializers","deadzoneDelta","_cameraTransform","_deltaTransform","_vector3","_vector2","_gamepadAngularSensibility_decorators","JoystickAxis","VirtualJoystick","_GetDefaultOptions","puckSize","containerSize","puckImage","containerImage","alwaysVisible","limitToContainer","leftJoystick","customizations","_released","_leftJoystick","_axisTargetedByLeftAndRight","_axisTargetedByUpAndDown","reverseLeftRight","_touches","_joystickSensibility","_inversedSensibility","_VjCanvasWidth","_VjCanvasHeight","Canvas","_HalfWidth","_onResize","backgroundColor","zIndex","_VjCanvasContext","strokeStyle","lineWidth","pressed","setPuckImage","setContainerImage","_AlwaysVisibleSticks","_joystickPointerPos","_joystickPointerStartPos","_deltaJoystickVector","_onPointerDownHandlerRef","_onPointerMoveHandlerRef","_onPointerUpHandlerRef","_drawVirtualJoystick","setJoystickSensibility","newJoystickSensibility","positionOnScreenCondition","_joystickPointerId","_joystickPosition","_joystickPreviousPointerPos","_GlobalJoystickIndex","_action","prevX","prevY","deltaJoystickX","deltaJoystickY","_clearPreviousDraw","touch","clearRect","setJoystickColor","newColor","_joystickColor","_joystickContainerSize","_clearContainerSize","_clearContainerSizeOffset","_joystickPuckSize","_clearPuckSize","_clearPuckSizeOffset","clearPosition","_alwaysVisible","setActionOnTouch","urlPath","_containerImage","_puckImage","jp","beginPath","stroke","_drawPuck","_drawContainer","releaseCanvas","FreeCameraVirtualJoystickInput","_leftjoystick","_rightjoystick","cameraTransform","transformedDeltaPosition","setAxisForUpDown","setAxisForLeftRight","reverseUpDown","_Registered$9d","Vector2ToFixed","decimalCount","Vector3Dot","Vector3LengthSquared","Vector3Length","Vector3DistanceSquared","Vector3Distance","Vector3FromFloatsToRef","Vector3ScaleToRef","Vector3ScaleInPlace","Vector3SubtractToRef","Vector4Dot","Vector4ToFixed","OrbitCameraPointersInput","_initialPinchSquaredDistance","pinchToPanMax","doubleTapAnimationDurationMs","doubleTapEasingFunction","getEntries","sens","sensX","sensY","previousDistance","canvasX","_pinchCentroid","canvasY","distanceToPoint","zoomDistance","clampedZoom","clampZoomDistance","zoomToPoint","zoomAlongLookAt","flyToPointAsync","cumulativeDelta","GeospatialCameraMouseWheelInput","BaseCameraMouseWheelInput","isArrowKey","hardwareScaling","centerX","centerY","_get_rotationSensitivity_decorators","_get_panSensitivity_decorators","_get_zoomSensitivity_decorators","rotationSensitivity","zoomSensitivity","_cameraPosition","_behavior","zoomSpeed","panSpeed","rotationXSpeed","rotationYSpeed","_zoomSpeedMultiplier","_panSpeedMultiplier","zoomInertia","panInertia","rotationInertia","zoomDeltaCurrentFrame","panDeltaCurrentFrame","rotationDeltaCurrentFrame","_zoomVelocity","_panVelocity","referenceFrameRate","_rotationVelocity","_prevFrameTimeMs","deltaTimeMs","_calculateCurrentVelocity","effectiveDeltaMs","resetRotationVelocity","resetPanVelocity","resetZoomVelocity","effectiveDt","_getEffectiveDeltaMs","referenceFrameDurationMs","oneMinusInertia","velocityRef","pixelDelta","inertialDecayFactor","inputVelocity","frameIndependentDecay","InputMapper","createDefaultEntries","_createDefaultEntries","resetInputMap","currentConditions","_entryMatches","_entryConditionsMatch","conditions","_entrySpecificity","insertIndex","_entryCoversAllConditionsOf","condValue","entryMods","modKey","_matchModifiers","touchCount","_entryModifiersMatch","entryModifiers","currentModifiers","conditionsModifiers","TargetCameraMovement","CameraMovement","_createDefaultInputMap","TmpMatrix$1","_targetInertia","updateUpVectorFromRotation","_updateUpVectorFromRotation_initializers","_updateUpVectorFromRotation_extraInitializers","_rotation_initializers","_rotation_extraInitializers","_speed_initializers","noRotationConstraint","_speed_extraInitializers","invertRotation","inverseRotationSpeed","_panningEpsilon","_rotationEpsilon","lockedTarget","_lockedTarget_initializers","_currentTarget","_lockedTarget_extraInitializers","_initialFocalDistance","_transformedReferencePoint","_deferredPositionUpdate","_deferredRotationQuaternionUpdate","_deferredRotationUpdate","_deferredUpdated","_deferOnly","_cachedRotationZ","_cachedQuaternionRotationZ","localForward","_getLockedTargetPosition","_storedPosition","_storedRotation","_storedRotationQuaternion","lockedTargetPosition","getFps","_referencePoint","_decideIfNeedsToMove","hasPanInput","computeCurrentFrameDeltas","inertialPanningLimit","directionMultiplier","needToMove","needToRotate","_updateCameraRotationMatrix","_rotateUpVectorWithCameraRotationMatrix","_computeViewMatrix","camLeft","camRight","leftSign","rightSign","_getRigCamPositionAndTarget","_TargetFocalPoint","newFocalTarget","_TargetTransformMatrix","halfSpace","_RigCamTransformMatrix","_updateUpVectorFromRotation_decorators","_rotation_decorators","_lockedTarget_decorators","serializeAsMeshReference","_speed_decorators","_Registered$9c","AddNodeConstructor","TargetCamera","mouse","keyboard","_ellipsoid_initializers","_ellipsoid_extraInitializers","_ellipsoidOffset_initializers","_ellipsoidOffset_extraInitializers","_checkCollisions_initializers","applyGravity","_checkCollisions_extraInitializers","_applyGravity_initializers","_applyGravity_extraInitializers","_needMoveForGravity","_oldPosition","_diffPosition","_newPosition","_collideWithWorld","actualDisplacement","gravity","needMoveForGravity","_ellipsoid_decorators","_ellipsoidOffset_decorators","_checkCollisions_decorators","_applyGravity_decorators","_Registered$9b","FreeCamera","TouchCamera","_Registered$9a","ComputeBeta","verticalOffset","CheckNaN","targetHost","_targetHost","_upToYMatrix","_yToUpMatrix","setMatUp","_inertialAlphaOffset","_inertialBetaOffset","_inertialRadiusOffset","panningInertia","_panningInertia","_inertia","pointers","mousewheel","_useCtrlForPanningInternal","keyboardEntry","pointerEntry","_panningMouseButtonInternal","_isInterpolating","bouncingBehavior","_bouncingBehavior","useBouncingBehavior","framingBehavior","_framingBehavior","useFramingBehavior","autoRotationBehavior","_autoRotationBehavior","useAutoRotationBehavior","_alpha_initializers","_alpha_extraInitializers","_beta_initializers","_beta_extraInitializers","_radius_initializers","overrideCloneAlphaBetaRadius","_radius_extraInitializers","_overrideCloneAlphaBetaRadius_initializers","_overrideCloneAlphaBetaRadius_extraInitializers","__target_initializers","__targetHost_extraInitializers","lowerAlphaLimit","_lowerAlphaLimit_initializers","upperAlphaLimit","_lowerAlphaLimit_extraInitializers","_upperAlphaLimit_initializers","lowerBetaLimit","_upperAlphaLimit_extraInitializers","_lowerBetaLimit_initializers","upperBetaLimit","_lowerBetaLimit_extraInitializers","_upperBetaLimit_initializers","_upperBetaLimit_extraInitializers","_lowerRadiusLimit_initializers","_lowerRadiusLimit_extraInitializers","_upperRadiusLimit_initializers","lowerTargetYLimit","_upperRadiusLimit_extraInitializers","_lowerTargetYLimit_initializers","_lowerTargetYLimit_extraInitializers","_inertialPanningX_initializers","_inertialPanningX_extraInitializers","_inertialPanningY_initializers","_inertialPanningY_extraInitializers","_pinchToPanMaxDistance_initializers","panningDistanceLimit","_pinchToPanMaxDistance_extraInitializers","_panningDistanceLimit_initializers","panningOriginTarget","_panningDistanceLimit_extraInitializers","_panningOriginTarget_initializers","_panningOriginTarget_extraInitializers","zoomOnFactor","_zoomOnFactor_initializers","_zoomOnFactor_extraInitializers","_targetScreenOffset_initializers","allowUpsideDown","_targetScreenOffset_extraInitializers","_allowUpsideDown_initializers","_allowUpsideDown_extraInitializers","_useInputToRestoreState_initializers","restoreStateInterpolationFactor","_useInputToRestoreState_extraInitializers","_restoreStateInterpolationFactor_initializers","panningAxis","collisionRadius","_collisionVelocity","_computationVector","_goalAlpha","_goalBeta","_goalRadius","_goalTarget","_goalTargetScreenOffset","cosa","sina","cosb","sinb","_getTargetPosition","_collisionTriggered","_targetBoundingCenter","_storedAlpha","_storedBeta","_storedRadius","_storedTarget","_storedTargetScreenOffset","stopInterpolation","interpolationFactor","_currentInterpolationFactor","ignored","useCtrlForPanning","panningMouseButton","_reset","_applyRotationAndZoomDelta","alphaOffset","radiusOffset","directionModifier","adjustedAlpha","betaOffset","_applyPanDelta","panX","panY","mapPanning","hasUserInteractions","rotDelta","zoomDelta","panDelta","goalTarget","goalRadius","goalRotation","newAlphaBetaGamma","goalAlphaBetaGamma","goalTargetScreenOffset","_checkLimits","rebuildAnglesAndRadius","previousAlpha","alphaCorrectionTurns","cloneAlphaBetaRadius","toBoundingCenter","allowSamePosition","doNotUpdateMaxZ","orthoExtent","focusOn","meshesOrMinMaxVectorAndDistance","alphaShift","rigCam","frustumSlopeY","distanceForHorizontalFrustum","frustumSlopeX","distanceForVerticalFrustum","_alpha_decorators","_beta_decorators","_radius_decorators","__targetHost_decorators","_get_inertialAlphaOffset_decorators","_get_inertialBetaOffset_decorators","_get_inertialRadiusOffset_decorators","_lowerAlphaLimit_decorators","_upperAlphaLimit_decorators","_lowerBetaLimit_decorators","_upperBetaLimit_decorators","_lowerRadiusLimit_decorators","_upperRadiusLimit_decorators","_lowerTargetYLimit_decorators","_inertialPanningX_decorators","_inertialPanningY_decorators","_pinchToPanMaxDistance_decorators","_panningDistanceLimit_decorators","_panningOriginTarget_decorators","_get_panningInertia_decorators","_get_zoomToMouseLocation_decorators","_zoomOnFactor_decorators","_targetScreenOffset_decorators","serializeAsVector2","_allowUpsideDown_decorators","_useInputToRestoreState_decorators","_restoreStateInterpolationFactor_decorators","_overrideCloneAlphaBetaRadius_decorators","__target_decorators","__target_extraInitializers","__targetHost_initializers","_Registered$99","ArcRotateCamera","DeviceOrientationCamera","_tmpDragQuaternion","_disablePointerInputWhenUsingDeviceOrientation","_dragFactor","_quaternionCache","_initialQuaternion","disablePointerInputWhenUsingDeviceOrientation","enableHorizontalDragging","dragFactor","axisName","_Registered$98","FlyCameraInputsManager","FlyCameraKeyboardInput","FlyCameraMouseInput","_trackRoll","bankedTurn","bankedTurnMultiplier","newPos","updatePosition","_Registered$97","FlyCamera","FollowCameraInputsManager","FollowCameraKeyboardMoveInput","FollowCameraMouseWheelInput","FollowCameraPointersInput","_rotationOffset_initializers","lowerRotationOffsetLimit","_rotationOffset_extraInitializers","_lowerRotationOffsetLimit_initializers","upperRotationOffsetLimit","_lowerRotationOffsetLimit_extraInitializers","_upperRotationOffsetLimit_initializers","_upperRotationOffsetLimit_extraInitializers","_heightOffset_initializers","lowerHeightOffsetLimit","_heightOffset_extraInitializers","_lowerHeightOffsetLimit_initializers","upperHeightOffsetLimit","_lowerHeightOffsetLimit_extraInitializers","_upperHeightOffsetLimit_initializers","cameraAcceleration","_upperHeightOffsetLimit_extraInitializers","_cameraAcceleration_initializers","maxCameraSpeed","_cameraAcceleration_extraInitializers","_maxCameraSpeed_initializers","cameraTarget","yRotation","targetX","targetZ","dz","_follow","_rotationOffset_decorators","_lowerRotationOffsetLimit_decorators","_upperRotationOffsetLimit_decorators","_heightOffset_decorators","_lowerHeightOffsetLimit_decorators","_upperHeightOffsetLimit_decorators","_cameraAcceleration_decorators","_maxCameraSpeed_decorators","ArcFollowCamera","_cartesianCoordinates","setMeshTarget","_meshTarget","_Registered$96","FollowCamera","UniversalCamera","_Registered$95","GamepadCamera","_Registered$94","ThinAnaglyphPostProcess","anaglyph_fragment","anaglyph_fragment$1","Samplers","AnaglyphPostProcess","_passedProcess","_Registered$93","_SetStereoscopicAnaglyphRigMode","AnaglyphArcRotateCamera","_Registered$92","AnaglyphFreeCamera","_Registered$91","AnaglyphGamepadCamera","_Registered$90","AnaglyphUniversalCamera","_Registered$8$","StereoscopicInterlacePostProcessI","isStereoscopicHoriz","isStereoscopicInterlaced","_stepSize","StereoscopicInterlacePostProcess","isCrossEye","StereoscopicArcRotateCamera","_SetStereoscopicRigMode","_Registered$8_","StereoscopicFreeCamera","_Registered$8Z","StereoscopicGamepadCamera","_Registered$8Y","StereoscopicUniversalCamera","_Registered$8X","StereoscopicScreenUniversalCamera","distanceBetweenEyes","_distanceBetweenEyes","distanceToProjectionPlane","_distanceToProjectionPlane","_updateCamera","VirtualJoysticksCamera","_Registered$8W","compensateDistortion","multiviewEnabled","hResolution","vResolution","aspectRatioFov","postProcessScaleFactor","vScreenSize","eyeToScreenDistance","leftHMatrix","hScreenSize","lensSeparationDistance","rightHMatrix","leftPreViewMatrix","interpupillaryDistance","rightPreViewMatrix","GetDefault","VRCameraMetrics","vScreenCenter","distortionK","chromaAbCorrection","lensCenterOffset","VRDistortionCorrectionPostProcess","isRightEye","_isRightEye","_distortionFactors","_postProcessScaleFactor","_lensCenterOffset","_scaleIn","_scaleFactor","_lensCenter","vrDistortionCorrection_fragment","vrDistortionCorrection_fragment$1","MultiviewRenderTarget","createMultiviewRenderTargetTexture","bindMultiviewFramebuffer","PerformanceMonitor","frameSampleSize","_rollingFrameTime","RollingAverage","sampleFrame","timeMs","_lastFrameTimeMs","averageFrameTime","averageFrameTimeVariance","variance","instantaneousFrameTime","history","averageFPS","instantaneousFPS","isSaturated","bottomValue","_pos","_m2","_wrapPosition","_CommonInit","commonEngine","_onCanvasContextMenu","_onCanvasFocus","_onCanvasBlur","_onBlur","_onFocus","ev","_onCanvasPointerOut","doNotHandleTouchAction","touchAction","webkitTapHighlightColor","DisableTouchAction","getRenderingCanvas","getAudioContext","getAudioDestination","_onFullscreenChange","_pointerLockRequested","RequestPointerlock","_onPointerLockChange","OfflineProviderFactory","block","verticalAlign","div","fontAscent","fontHeight","whiteSpace","descent","IsValidFontOffset","GetFontOffsetFromDom","domFontOffset","metrics","measureText","ascent","actualBoundingBoxAscent","fontBoundingBoxAscent","actualBoundingBoxDescent","fontBoundingBoxDescent","disposableCanvas","GetFontOffsetFromCanvas","canvasFontOffset","GetCssPixelFontSize","GetFallbackFontOffset","imageBitmap","imageSource","ResizeImageBitmap","RequestFullscreen","requestFunction","requestFullscreen","webkitRequestFullscreen","ExitFullscreen","anyDoc","exitFullscreen","webkitCancelFullScreen","requestPointerLock","ExitPointerlock","exitPointerLock","_Registered$8V","viewportOwner","getScreenAspectRatio","Engine","_measureFps","_performanceMonitor","RegisterAbstractEngineDom","_rescalePostProcess","CreateImageBitmapFromSource","switchFullscreen","enterFullscreen","RASTERIZER_DISCARD","setDirectViewport","enableScissor","disableScissor","shaders","getAttachedShaders","_rebuildBuffers","GetFontOffset","enterPointerlock","exitPointerlock","transformFeedback","deleteTransformFeedback","bindTransformFeedback","setTranformFeedbackVaryings","_releaseRenderTargetWrapper","hostingScene","copyTexImage2D","webGLRtWrapper","savedSamples","isMSAA","_depthStencilBuffer","previousFramebuffer","_uploadImageToTexture","updateTextureComparisonFunction","deleteInstancesBuffer","sync","flags","intervalms","WAIT_FAILED","TIMEOUT_EXPIRED","_readPixelsAsync","outputBuffer","buf","PIXEL_PACK_BUFFER","STREAM_READ","fenceSync","SYNC_GPU_COMMANDS_COMPLETE","_clientWaitAsync","deleteSync","getBufferSubData","_CommonDispose","_Registered$8U","CurrentCreateSceneUniformBuffer","colorTexture","texStorage3D","_colorTextureArray","_depthStencilTextureArray","setTextures","multiviewTexture","ext","framebufferTextureMultisampleMultiviewOVR","framebufferTextureMultiviewOVR","bindSpaceWarpFramebuffer","_spaceWarpTexture","spaceWarpTexture","CreateMultiviewUbo","forceMono","_resizeOrCreateMultiviewTexture","VRMultiviewToSingleviewPostProcess","scaleFactor","RegisterEngineMultiview","_SetVrRigMode","vrCameraMetrics","_getVRProjectionMatrix","VRDeviceOrientationArcRotateCamera","_Registered$8T","VRDeviceOrientationFreeCamera","_Registered$8S","VRDeviceOrientationGamepadCamera","_Registered$8R","AddUniforms","currentRTisSceneRT","_lastUpdateFrameId","MaterialDefines","externalProperties","_setDefaultValue","markAsProcessed","_areTexturesDirty","_areFresnelDirty","_areLightsDisposed","_areImageProcessingDirty","disposed","_externalProperties","isEqual","cloneTo","default","defValue","ImageProcessingDefinesMixin","RxOption","MaterialPluginManager","_activePlugins","_activePluginsForExtraEvents","_addPlugin","_MaterialPluginClassToMainDefine","_MaterialPluginCounter","_handlePluginEvent","priority","_codeInjectionPoints","defineNamesFromPlugins","collectDefines","_collectPointNames","getCustomCode","_activatePlugin","_handlePluginEventIsReadyForSubMesh","_callbackPluginEventPrepareDefinesBeforeAttributes","_handlePluginEventPrepareDefinesBeforeAttributes","_callbackPluginEventPrepareDefines","_handlePluginEventPrepareDefines","_handlePluginEventBindForSubMesh","registerForExtraEvents","_handlePluginEventHasRenderTargetTextures","_handlePluginEventFillRenderTargetTextures","_callbackPluginEventHardBindForSubMesh","_handlePluginEventHardBindForSubMesh","prepareDefinesBeforeAttributes","hardBindForSubMesh","fillRenderTargetTextures","renderTargets","defineNames","_defineNamesFromPlugins","fallbackRank","addFallbacks","_uniformList","_uboList","customCode","_injectCustomCode","_uboDeclaration","_vertexDeclaration","_fragmentDeclaration","externalUniforms","getUniformBuffersNames","pointName","existingCallback","resolveIncludes","injectedCode","regexFlags","matchOption","newCode","ReplaceRegExpSubstitutions","fullPointName","Plugins","Inited","MaterialObserver","_MaterialPluginManagerRegistered","UnregisterAllMaterialPlugins","RegisterMaterialPlugin","pluginName","existing","_factory","UnregisterMaterialPlugin","group0","group1","_pluginManager","addToPluginList","_priority_initializers","_priority_extraInitializers","_resolveIncludes_initializers","_resolveIncludes_extraInitializers","_registerForExtraEvents_initializers","_registerForExtraEvents_extraInitializers","_pluginDefineNames","_enable","markAllDefinesAsDirty","_forceDisposeTextures","_shaderType","_activeTextures","currentRank","_ubos","_priority_decorators","_resolveIncludes_decorators","_registerForExtraEvents_decorators","_Registered$8Q","MaterialPluginBase","DETAIL","DETAILDIRECTUV","DETAIL_NORMALBLENDMETHOD","_DetailMapConfiguration_normalBlendMethod_accessor_storage","_DetailMapConfiguration_isEnabled_accessor_storage","_DetailMapConfiguration_texture_accessor_storage","normalBlendMethod","_internalMarkAllSubMeshesAsTexturesDirty","MaterialDetailMapDefines","diffuseBlendLevel","_diffuseBlendLevel_initializers","roughnessBlendLevel","_diffuseBlendLevel_extraInitializers","_roughnessBlendLevel_initializers","bumpLevel","_normalBlendMethod","_bumpLevel_extraInitializers","_normalBlendMethod_initializers","_normalBlendMethod_extraInitializers","BindTextureMatrix","_diffuseBlendLevel_decorators","_roughnessBlendLevel_decorators","_bumpLevel_decorators","_normalBlendMethod_decorators","_roughnessBlendLevel_extraInitializers","_ShaderImportLoader","loadWebGL","_webGL","loaded","loadPromise","_webGPU","loadWebGPU","getLoadCallback","_loadAsync","ownsLoad","_completeLoad","UVDefinesMixin","MAINUV1","MAINUV2","MAINUV3","MAINUV4","MAINUV5","MAINUV6","UV1","UV3","UV4","UV5","UV6","PrepassDefinesMixin","PREPASS_IRRADIANCE_LEGACY","PREPASS_IRRADIANCE_LEGACY_INDEX","PREPASS_IRRADIANCE","PREPASS_IRRADIANCE_INDEX","PREPASS_ALBEDO","PREPASS_ALBEDO_INDEX","PREPASS_ALBEDO_SQRT","PREPASS_ALBEDO_SQRT_INDEX","PREPASS_DEPTH","PREPASS_DEPTH_INDEX","PREPASS_SCREENSPACE_DEPTH","PREPASS_SCREENSPACE_DEPTH_INDEX","PREPASS_NORMALIZED_VIEW_DEPTH","PREPASS_NORMALIZED_VIEW_DEPTH_INDEX","PREPASS_NORMAL","PREPASS_NORMAL_INDEX","PREPASS_WORLD_NORMAL","PREPASS_WORLD_NORMAL_INDEX","PREPASS_POSITION","PREPASS_POSITION_INDEX","PREPASS_LOCAL_POSITION","PREPASS_LOCAL_POSITION_INDEX","PREPASS_VELOCITY","PREPASS_VELOCITY_INDEX","PREPASS_VELOCITY_LINEAR","PREPASS_VELOCITY_LINEAR_INDEX","PREPASS_REFLECTIVITY","PREPASS_REFLECTIVITY_INDEX","PREPASS_OBJECT_ID","PREPASS_OBJECT_ID_INDEX","PREPASS_OBJECT_ID_R8","PREPASS_MESH_BLEND_TAG","PREPASS_MESH_BLEND_TAG_INDEX","ImageProcessingMixin","parentMeta","_attachImageProcessingConfiguration","_imageProcessingObserver","cameraColorCurvesEnabled","cameraColorGradingEnabled","cameraToneMappingEnabled","cameraExposure","cameraContrast","cameraColorGradingTexture","cameraColorCurves","onCreatedEffectParameters$3","StandardMaterialDefinesBase","StandardMaterialDefines","DIFFUSE","DIFFUSEDIRECTUV","BAKED_VERTEX_ANIMATION_TEXTURE","AMBIENT","AMBIENTDIRECTUV","OPACITY","OPACITYDIRECTUV","OPACITYRGB","EMISSIVE","EMISSIVEDIRECTUV","SPECULAR","SPECULARDIRECTUV","BUMP","BUMPDIRECTUV","PARALLAX","PARALLAX_RHS","PARALLAXOCCLUSION","SPECULAROVERALPHA","CLIPPLANE","CLIPPLANE2","CLIPPLANE3","CLIPPLANE4","CLIPPLANE5","CLIPPLANE6","ALPHATEST","DEPTHPREPASS","ALPHAFROMDIFFUSE","POINTSIZE","FOG","SPECULARTERM","DIFFUSEFRESNEL","OPACITYFRESNEL","REFLECTIONFRESNEL","REFRACTIONFRESNEL","EMISSIVEFRESNEL","FRESNEL","VERTEXCOLOR","VERTEXALPHA","NUM_BONE_INFLUENCERS","BonesPerMesh","BONETEXTURE","BONES_VELOCITY_ENABLED","INSTANCES","THIN_INSTANCES","GLOSSINESS","ROUGHNESS","EMISSIVEASILLUMINATION","LINKEMISSIVEWITHDIFFUSE","REFLECTIONFRESNELFROMSPECULAR","LIGHTMAP","LIGHTMAPDIRECTUV","OBJECTSPACE_NORMALMAP","USELIGHTMAPASSHADOWMAP","USE_LOCAL_REFRACTIONMAP_CUBIC","LOGARITHMICDEPTH","REFRACTION","REFRACTIONMAP_3D","REFLECTIONOVERALPHA","TWOSIDEDLIGHTING","SHADOWFLOAT","MORPHTARGETS","MORPHTARGETS_POSITION","MORPHTARGETS_NORMAL","MORPHTARGETS_TANGENT","MORPHTARGETS_UV","MORPHTARGETS_UV2","MORPHTARGETS_COLOR","MORPHTARGETTEXTURE_HASPOSITIONS","MORPHTARGETTEXTURE_HASNORMALS","MORPHTARGETTEXTURE_HASTANGENTS","MORPHTARGETTEXTURE_HASUVS","MORPHTARGETTEXTURE_HASUV2S","MORPHTARGETTEXTURE_HASCOLORS","MORPHTARGETS_TEXTURE","NONUNIFORMSCALING","PREMULTIPLYALPHA","ALPHATEST_AFTERALLALPHACOMPUTATIONS","ALPHABLEND","RGBDLIGHTMAP","RGBDREFRACTION","CAMERA_ORTHOGRAPHIC","CAMERA_PERSPECTIVE","AREALIGHTSUPPORTED","USE_VERTEX_PULLING","VERTEX_PULLING_USE_INDEX_BUFFER","VERTEX_PULLING_INDEX_BUFFER_32BITS","RIGHT_HANDED","CLUSTLIGHT_SLICES","CLUSTLIGHT_BATCH","IS_REFLECTION_LINEAR","IS_REFRACTION_LINEAR","DECAL_AFTER_DETAIL","TEXTURE_REPETITION_MODE","StandardMaterialBase","_StandardMaterial_ambientTexture_accessor_storage","_StandardMaterial_opacityTexture_accessor_storage","_StandardMaterial_reflectionTexture_accessor_storage","_StandardMaterial_emissiveTexture_accessor_storage","_StandardMaterial_specularTexture_accessor_storage","_StandardMaterial_bumpTexture_accessor_storage","_StandardMaterial_lightmapTexture_accessor_storage","_StandardMaterial_refractionTexture_accessor_storage","_StandardMaterial_useAlphaFromDiffuseTexture_accessor_storage","_StandardMaterial_useEmissiveAsIllumination_accessor_storage","_StandardMaterial_linkEmissiveWithDiffuse_accessor_storage","_StandardMaterial_useSpecularOverAlpha_accessor_storage","_StandardMaterial_useReflectionOverAlpha_accessor_storage","_StandardMaterial_disableLighting_accessor_storage","_StandardMaterial_useObjectSpaceNormalMap_accessor_storage","_StandardMaterial_useParallax_accessor_storage","_StandardMaterial_useParallaxOcclusion_accessor_storage","_StandardMaterial_roughness_accessor_storage","_StandardMaterial_useLightmapAsShadowmap_accessor_storage","_StandardMaterial_diffuseFresnelParameters_accessor_storage","_StandardMaterial_opacityFresnelParameters_accessor_storage","_StandardMaterial_reflectionFresnelParameters_accessor_storage","_StandardMaterial_refractionFresnelParameters_accessor_storage","_StandardMaterial_emissiveFresnelParameters_accessor_storage","_StandardMaterial_useReflectionFresnelFromSpecular_accessor_storage","_StandardMaterial_useGlossinessFromSpecularMapAlpha_accessor_storage","_StandardMaterial_maxSimultaneousLights_accessor_storage","_StandardMaterial_invertNormalMapX_accessor_storage","_StandardMaterial_invertNormalMapY_accessor_storage","_StandardMaterial_twoSidedLighting_accessor_storage","_StandardMaterial_applyDecalMapAfterDetailMap_accessor_storage","diffuseTexture","_StandardMaterial_diffuseTexture_accessor_storage","ambientTexture","opacityTexture","emissiveTexture","specularTexture","bumpTexture","lightmapTexture","refractionTexture","useAlphaFromDiffuseTexture","useEmissiveAsIllumination","linkEmissiveWithDiffuse","useSpecularOverAlpha","useReflectionOverAlpha","useObjectSpaceNormalMap","useParallax","useParallaxOcclusion","roughness","useLightmapAsShadowmap","diffuseFresnelParameters","opacityFresnelParameters","reflectionFresnelParameters","refractionFresnelParameters","emissiveFresnelParameters","useReflectionFresnelFromSpecular","useGlossinessFromSpecularMapAlpha","invertNormalMapX","invertNormalMapY","twoSidedLighting","applyDecalMapAfterDetailMap","_diffuseTexture","__diffuseTexture_initializers","__diffuseTexture_extraInitializers","_diffuseTexture_initializers","_ambientTexture","_diffuseTexture_extraInitializers","__ambientTexture_initializers","__ambientTexture_extraInitializers","_ambientTexture_initializers","_opacityTexture","_ambientTexture_extraInitializers","__opacityTexture_initializers","__opacityTexture_extraInitializers","_opacityTexture_initializers","_reflectionTexture","_opacityTexture_extraInitializers","__reflectionTexture_initializers","__reflectionTexture_extraInitializers","_reflectionTexture_initializers","_emissiveTexture","_reflectionTexture_extraInitializers","__emissiveTexture_initializers","__emissiveTexture_extraInitializers","_emissiveTexture_initializers","_specularTexture","_emissiveTexture_extraInitializers","__specularTexture_initializers","__specularTexture_extraInitializers","_specularTexture_initializers","_bumpTexture","_specularTexture_extraInitializers","__bumpTexture_initializers","__bumpTexture_extraInitializers","_bumpTexture_initializers","_lightmapTexture","_bumpTexture_extraInitializers","__lightmapTexture_initializers","__lightmapTexture_extraInitializers","_lightmapTexture_initializers","_refractionTexture","_lightmapTexture_extraInitializers","__refractionTexture_initializers","__refractionTexture_extraInitializers","_refractionTexture_initializers","_refractionTexture_extraInitializers","_ambientColor_initializers","diffuseColor","_ambientColor_extraInitializers","_diffuseColor_initializers","specularColor","_diffuseColor_extraInitializers","_specularColor_initializers","emissiveColor","_specularColor_extraInitializers","_emissiveColor_initializers","specularPower","_emissiveColor_extraInitializers","_specularPower_initializers","_useAlphaFromDiffuseTexture","_specularPower_extraInitializers","__useAlphaFromDiffuseTexture_initializers","__useAlphaFromDiffuseTexture_extraInitializers","_useEmissiveAsIllumination","_useAlphaFromDiffuseTexture_extraInitializers","__useEmissiveAsIllumination_initializers","__useEmissiveAsIllumination_extraInitializers","_useEmissiveAsIllumination_initializers","_linkEmissiveWithDiffuse","_useEmissiveAsIllumination_extraInitializers","__linkEmissiveWithDiffuse_initializers","__linkEmissiveWithDiffuse_extraInitializers","_linkEmissiveWithDiffuse_initializers","_useSpecularOverAlpha","_linkEmissiveWithDiffuse_extraInitializers","__useSpecularOverAlpha_initializers","__useSpecularOverAlpha_extraInitializers","_useReflectionOverAlpha","_useSpecularOverAlpha_extraInitializers","__useReflectionOverAlpha_initializers","__useReflectionOverAlpha_extraInitializers","_useReflectionOverAlpha_initializers","_disableLighting","_useReflectionOverAlpha_extraInitializers","__disableLighting_initializers","__disableLighting_extraInitializers","_useObjectSpaceNormalMap","_disableLighting_extraInitializers","__useObjectSpaceNormalMap_initializers","__useObjectSpaceNormalMap_extraInitializers","_useObjectSpaceNormalMap_initializers","_useParallax","_useObjectSpaceNormalMap_extraInitializers","__useParallax_initializers","__useParallax_extraInitializers","_useParallaxOcclusion","_useParallax_extraInitializers","__useParallaxOcclusion_initializers","__useParallaxOcclusion_extraInitializers","_useParallaxOcclusion_initializers","parallaxScaleBias","_useParallaxOcclusion_extraInitializers","_roughness","_parallaxScaleBias_extraInitializers","__roughness_initializers","__roughness_extraInitializers","_roughness_initializers","indexOfRefraction","_roughness_extraInitializers","_indexOfRefraction_initializers","invertRefractionY","_indexOfRefraction_extraInitializers","_invertRefractionY_initializers","alphaCutOff","_invertRefractionY_extraInitializers","_alphaCutOff_initializers","_useLightmapAsShadowmap","_alphaCutOff_extraInitializers","__useLightmapAsShadowmap_initializers","_diffuseFresnelParameters","_useLightmapAsShadowmap_extraInitializers","__diffuseFresnelParameters_initializers","__diffuseFresnelParameters_extraInitializers","_diffuseFresnelParameters_initializers","_opacityFresnelParameters","_diffuseFresnelParameters_extraInitializers","__opacityFresnelParameters_initializers","__opacityFresnelParameters_extraInitializers","_opacityFresnelParameters_initializers","_reflectionFresnelParameters","_opacityFresnelParameters_extraInitializers","__reflectionFresnelParameters_initializers","__reflectionFresnelParameters_extraInitializers","_reflectionFresnelParameters_initializers","_refractionFresnelParameters","_reflectionFresnelParameters_extraInitializers","__refractionFresnelParameters_initializers","__refractionFresnelParameters_extraInitializers","_refractionFresnelParameters_initializers","_emissiveFresnelParameters","_refractionFresnelParameters_extraInitializers","__emissiveFresnelParameters_initializers","__emissiveFresnelParameters_extraInitializers","_useReflectionFresnelFromSpecular","_emissiveFresnelParameters_extraInitializers","__useReflectionFresnelFromSpecular_initializers","__useReflectionFresnelFromSpecular_extraInitializers","_useGlossinessFromSpecularMapAlpha","_useReflectionFresnelFromSpecular_extraInitializers","__useGlossinessFromSpecularMapAlpha_initializers","__useGlossinessFromSpecularMapAlpha_extraInitializers","_useGlossinessFromSpecularMapAlpha_initializers","_maxSimultaneousLights","_useGlossinessFromSpecularMapAlpha_extraInitializers","__maxSimultaneousLights_initializers","__maxSimultaneousLights_extraInitializers","_maxSimultaneousLights_initializers","_invertNormalMapX","_maxSimultaneousLights_extraInitializers","__invertNormalMapX_initializers","__invertNormalMapX_extraInitializers","_invertNormalMapX_initializers","_invertNormalMapY","_invertNormalMapX_extraInitializers","__invertNormalMapY_initializers","__invertNormalMapY_extraInitializers","_invertNormalMapY_initializers","_twoSidedLighting","_invertNormalMapY_extraInitializers","__twoSidedLighting_initializers","__twoSidedLighting_extraInitializers","_applyDecalMapAfterDetailMap","_twoSidedLighting_extraInitializers","__applyDecalMapAfterDetailMap_initializers","__applyDecalMapAfterDetailMap_extraInitializers","_applyDecalMapAfterDetailMap_initializers","_applyDecalMapAfterDetailMap_extraInitializers","_globalAmbientColor","_cacheHasRenderTargetTextures","PrePassConfiguration","_shouldUseAlphaFromDiffuseTexture","_hasAlphaChannel","oit","forceWasNotReadyPreviously","lightDisposed","PrepareSamplers","PrepareUniformsAndSamplersList","csnrOptions","multiTarget","_ShaderLoader","onCreatedEffectParameters","hexParams","toNormalMatrix","bindOnlyNormalMatrix","leftColor","rightColor","opacityParts","_ParsePlugins","_emissiveColor_decorators","_useParallaxOcclusion_decorators","_roughness_decorators","_indexOfRefraction_decorators","_invertRefractionY_decorators","_applyDecalMapAfterDetailMap_decorators","_diffuseTexture_decorators","_ambientTexture_decorators","_opacityTexture_decorators","_reflectionTexture_decorators","_emissiveTexture_decorators","_specularTexture_decorators","_bumpTexture_decorators","_lightmapTexture_decorators","_refractionTexture_decorators","_useAlphaFromDiffuseTexture_decorators","_useAlphaFromDiffuseTexture_initializers","_useEmissiveAsIllumination_decorators","_linkEmissiveWithDiffuse_decorators","_useSpecularOverAlpha_decorators","_useReflectionOverAlpha_decorators","_disableLighting_decorators","_disableLighting_initializers","_useObjectSpaceNormalMap_decorators","_useParallax_decorators","_useParallax_initializers","_useLightmapAsShadowmap_decorators","_diffuseFresnelParameters_decorators","_opacityFresnelParameters_decorators","_reflectionFresnelParameters_decorators","_refractionFresnelParameters_decorators","_emissiveFresnelParameters_decorators","_emissiveFresnelParameters_initializers","_useReflectionFresnelFromSpecular_decorators","_useGlossinessFromSpecularMapAlpha_decorators","_maxSimultaneousLights_decorators","_invertNormalMapX_decorators","_invertNormalMapY_decorators","_twoSidedLighting_decorators","_twoSidedLighting_initializers","__diffuseTexture_decorators","__ambientTexture_decorators","__opacityTexture_decorators","__reflectionTexture_decorators","__emissiveTexture_decorators","__specularTexture_decorators","__bumpTexture_decorators","__lightmapTexture_decorators","__refractionTexture_decorators","_ambientColor_decorators","_diffuseColor_decorators","_specularColor_decorators","_specularPower_decorators","__useAlphaFromDiffuseTexture_decorators","__useEmissiveAsIllumination_decorators","__linkEmissiveWithDiffuse_decorators","__useSpecularOverAlpha_decorators","__useReflectionOverAlpha_decorators","__disableLighting_decorators","__useObjectSpaceNormalMap_decorators","__useParallax_decorators","__useParallaxOcclusion_decorators","_parallaxScaleBias_decorators","__roughness_decorators","_alphaCutOff_decorators","__useLightmapAsShadowmap_decorators","__useLightmapAsShadowmap_extraInitializers","__diffuseFresnelParameters_decorators","__opacityFresnelParameters_decorators","__reflectionFresnelParameters_decorators","__refractionFresnelParameters_decorators","__emissiveFresnelParameters_decorators","__useReflectionFresnelFromSpecular_decorators","__useGlossinessFromSpecularMapAlpha_decorators","__maxSimultaneousLights_decorators","__invertNormalMapX_decorators","__invertNormalMapY_decorators","__twoSidedLighting_decorators","_Registered$8P","RegisterImageProcessingConfiguration","StandardMaterial","_Registered$8O","forceBindTexture","premulAlpha","glformat","canvasOrSize","isScene","sceneOrOptions","RegisterEnginesExtensionsEngineDynamicTexture","_canvas","_ownCanvas","optionsAsSize","_recreate","scaleTo","allowGPUOptimization","drawText","fillColor","textSize","fontSize","fillText","DynamicTexture","_IsCanvasElement","WebXRLayerWrapper","renderTargetTextureProvider","_rttWrapper","isFixedFoveationSupported","layerType","fixedFoveation","_createRenderTargetTextureProvider","getWidth","getHeight","WebXRLayerRenderTargetTextureProvider","layerWrapper","_renderTargetTextures","_createRenderTargetTextureShell","_destroyRenderTargetTexture","_framebufferDimensions","WebXRWebGLRenderTargetTextureProvider","_createInternalTexture","WebXRWebGLLayerWrapper","sessionManager","WebXRWebGLLayerRenderTargetTextureProvider","_layer","xrViewport","getViewport","getRenderTargetTextureForEye","layerWidth","layerHeight","_rtt","WebXRManagedOutputCanvasOptions","GetDefaults","defaults","canvasOptions","framebufferScaleFactor","newCanvasCssStyle","WebXRManagedOutputCanvas","xrLayer","_xrLayerWrapper","onXRLayerInitObservable","_setManagedOutputCanvas","canvasElement","cssText","_addCanvas","_removeCanvas","_makeCanvasCompatible","makeXRCompatible","createLayer","_createXRLayer","xrSession","XRWebGLLayer","canvasContext","_setCanvasSize","contains","_originalCanvasSize","offsetWidth","offsetHeight","_createXRCompatibleRenderingContext","NativeXRLayerWrapper","NativeXRLayerRenderTargetTextureProvider","_nativeRTTProvider","getNativeRenderTargetProvider","session","_nativeLayer","trySetViewportForView","getRenderTargetForEye","NativeXRRenderTarget","_nativeRenderTarget","getWebXRRenderTarget","initializeXRLayerAsync","WebGPUXRNotSupportedErrorMessage","WebGPUXREngineNotCompatibleErrorMessage","IsWebGPUXRSupported","XRGPUBinding","createProjectionLayer","getViewSubImage","getPreferredColorFormat","XRGPUSubImage","getViewDescriptor","WebXRGraphicsBindingType","WebXRWebGLGraphicsBinding","bindingType","binding","XRWebGLBinding","CreateFromEngine","WebXRWebGPUGraphicsBinding","_device","WebXRSessionManager","worldScalingFactor","_worldScalingFactor","onWorldScaleFactorChangedObservable","previousScaleFactor","newScaleFactor","_graphicsBinding","_sessionCleanup","currentTimestamp","defaultHeightCompensation","onXRFrameObservable","onXRReferenceSpaceChanged","onXRReferenceSpaceInitialized","onXRReady","inXRFrameLoop","inXRSession","_onEngineDisposedObserver","referenceSpace","_referenceSpace","newReferenceSpace","_referenceSpaceInitialized","sessionMode","_sessionMode","exitXRAsync","_baseLayerRTTProvider","getRenderTargetTextureForView","viewIndex","_getCurrentXRView","requestViewportScale","recommendedViewportScale","getViewerPose","views","_getGraphicsBinding","_xrNavigator","native","IsWebGPUXREngineCompatible","requestSession","xrSessionMode","isNotSupportedError","sessionCleanupComplete","isNative","_baseLayerWrapper","cleanupSession","sessionEnded","IsSessionSupportedAsync","resetReferenceSpace","baseReferenceSpace","xrFrame","getFramebufferDimensions","setReferenceSpaceTypeAsync","referenceSpaceType","viewerReferenceSpace","requestReferenceSpace","rejectionReason","XRRigidTransform","getOffsetReferenceSpace","heightCompensation","updateRenderState","baseLayerWrapper","createRenderTargetTextureProvider","baseLayer","_setBaseLayerWrapper","functionToUse","isSessionSupported","supportsSession","supportedFrameRates","updateTargetFrameRate","runInXRFrame","ignoreIfNotInSession","Xbox360Button","Xbox360Dpad","Xbox360Pad","_leftTrigger","onPadUpObservable","_buttonA","_buttonB","_buttonX","_buttonY","_buttonBack","_buttonStart","_buttonLb","_buttonRb","_buttonLeftStick","_buttonRightStick","_dPadUp","_dPadDown","_dPadLeft","_dPadRight","_isXboxOnePad","xboxOne","onlefttriggerchanged","_onlefttriggerchanged","onrighttriggerchanged","_onrighttriggerchanged","leftTrigger","rightTrigger","_rightTrigger","ondpaddown","_ondpaddown","ondpadup","_ondpadup","buttonType","_setDpadValue","onPadDownObservable","buttonA","buttonB","buttonX","buttonY","buttonStart","buttonBack","buttonLB","buttonRB","buttonLeftStick","buttonRightStick","dPadUp","dPadDown","dPadLeft","dPadRight","DualShockButton","DualShockDpad","DualShockPad","_buttonCross","_buttonCircle","_buttonSquare","_buttonTriangle","_buttonShare","_buttonOptions","_buttonL1","_buttonR1","buttonCross","buttonCircle","buttonSquare","buttonTriangle","buttonOptions","buttonShare","buttonL1","buttonR1","GamepadSystemSceneComponent","_gamepadManager","_Registered$8N","gamepadManagerClass","FreeCameraGamepadInput","ArcRotateCameraGamepadInput","GamepadManager","_babylonGamepads","_isMonitoring","_hostWindow","RegisterGamepadSceneComponent","_gamepadEventSupported","_gamepadSupport","_onGamepadConnectedEvent","newGamepad","_addNewGamepad","_startMonitoringGamepads","_onGamepadDisconnectedEvent","disconnectedGamepad","_updateGamepadObjects","getGamepadByType","_oneGamepadConnected","_stopMonitoringGamepads","dualShock","_checkGamepadsStatus","_loggedErrors","gazeTrackerToClone","_activePointer","_gazeTracker","bakeCurrentTransformIntoVertices","targetMat","_getForwardRay","_selectionPointerDown","_pointerDownOnMeshAsked","_currentHit","_selectionPointerUp","_activatePointer","_deactivatePointer","_updatePointerDistance","_interactionsEnabled","_teleportationEnabled","VRExperienceHelperGazer","_IdCounter","VRExperienceHelperCameraGazer","_getCamera","OnAfterEnteringVRObservableEvent","VRExperienceHelper","onEnteringVR","onEnteringVRObservable","onExitingVR","onExitingVRObservable","teleportationTarget","_teleportationTarget","_isDefaultTeleportationTarget","gazeTrackerMesh","_cameraGazer","displayGaze","_displayGaze","displayLaserPointer","_displayLaserPointer","deviceOrientationCamera","_deviceOrientationCamera","currentVRCamera","vrDeviceOrientationCamera","_vrDeviceOrientationCamera","vrButton","_btnVR","_teleportationRequestInitiated","_fullscreenVRpresenting","enableGazeEvenWhenNoPointerLock","exitVROnDoubleTap","onAfterEnteringVRObservable","_useCustomVRButton","_teleportActive","_floorMeshesCollection","_teleportationMode","TELEPORTATIONMODE_CONSTANTTIME","_teleportationTime","_teleportationSpeed","_rotationAllowed","_teleportBackwardsVector","_teleportationFillColor","_teleportationBorderColor","_rotationAngle","_haloCenter","_padSensibilityUp","_padSensibilityDown","_pickedLaserColor","_pickedGazeColor","onNewMeshSelected","onNewMeshPicked","onBeforeCameraTeleport","onAfterCameraTeleport","onSelectedMeshUnselected","teleportationEnabled","_teleportationInitialized","updateGazeTrackerScale","updateGazeTrackerColor","updateControllerLaserColor","requestPointerLockOnFullScreen","xrTestDone","_moveButtonToBottomRight","fullscreenElement","_inputElement","exitVR","_updateButtonVisibility","_cachedAngularSensibility","_beforeRender","_onNewGamepadConnected","stickValues","_checkTeleportWithRay","_checkTeleportBackwards","_checkRotate","buttonPressed","_workingVector","_workingMatrix","webVROptions","useXR","createFallbackVRDeviceOrientationFreeCamera","createDeviceOrientationCamera","laserToggle","_defaultHeight","_existingCamera","floorMeshes","baseExperience","pointerSelection","_hasEnteredVR","_completeVRInit","vrDeviceOrientationCameraMetrics","title","css","SVGSVGElement","isInVRMode","enterVR","_displayVRButton","_circleEase","enableTeleportation","rect","_btnVRDisplayed","enterXRAsync","success","enableInteractions","_floorMeshName","_isTeleportationFloor","raySelectionPredicate","addFloorMesh","floorMesh","removeFloorMesh","vrTeleportationOptions","floorMeshName","teleportation","waitForXr","teleportationMode","teleportationTime","teleportationSpeed","_teleportationEasing","_createTeleportationCircles","gazer","teleportCamera","_dpadPressed","_rotationLeftAsked","_rotationRightAsked","_teleportationBackRequestInitiated","_raySelectionPredicate","dynamicTexture","teleportationCircleMaterial","animationInnerCircle","_hideTeleportationTarget","animationRotation","animationRotationKeys","animationPp","vignetteWeightKeys","animationPp2","vignetteStretchKeys","_postProcessMove","TELEPORTATIONMODE_CONSTANTSPEED","animationCameraTeleportation","animationCameraTeleportationKeys","midFrame","setLaserColor","pickedColor","setGazeColor","changeLaserColor","changeGazeColor","parentNode","_onVrDisplayPresentChangeBind","GeospatialCameraInputsManager","GeospatialCameraPointersInput","GeospatialCameraKeyboardInput","GeospatialLimits","_radiusMin","pitchMax","yawMax","_planetRadius","radiusMax","radiusMin","_radiusMax","currentRadius","distanceToTarget","maxZoomIn","maxZoomOut","getEffectivePitchMax","pitchDisabledRadiusScale","fullPitchRadius","noPitchRadius","pitchMin","clampedT","GeospatialCameraMovement","limits","_cameraCenter","_cameraLookAt","zoomToCursor","_hitPointRadius","_dragPlaneNormal","_dragPlaneOriginPointEcef","_dragPlaneHitPointLocal","_previousDragPlaneHitPointLocal","screenX","screenY","startDrag","handleDrag","stopDrag","toCursor","handleZoom","_recalculateDragPlaneHitPoint","ComputeLocalBasisToRefs","calculateUpVectorFromPointToRef","localToEcef","localToEcefResult","ecefToLocal","maxDragDelta","deltaLength","centerRadius","cameraCenter","upAtCenter","sineOfSphericalLat","cosOfSphericalLat","latitudeDampeningScale","latitudeDampening","zoomTargetDistance","isDragging","computedPerFrameZoomPickPoint","lookPickResult","pickAlongVector","ClampCenterFromPolesInPlace","sineOfSphericalLatitudeLimit","centerMagnitude","sineOfClampedSphericalLat","sineSphericalLat","cosineOfClampedSphericalLat","newX","longitude","newY","newZ","refEast","refNorth","refUp","worldPos","worldNorth","_tempPosition","_tempCenter","_lookAtVector","_flyToTargets","_center","_yaw","__center_extraInitializers","__yaw_extraInitializers","__pitch_initializers","__pitch_extraInitializers","__radius_initializers","_tempVect","__radius_extraInitializers","_tempEast","_tempNorth","_tempUp","_wasCenterMovingLastFrame","_limits","_flyingBehavior","_resetToDefault","_setOrientation","effectivePitchMax","horiz","perFrameCollisionOffset","_getCollisionOffset","_isViewMatrixDirty","updateFlyToDestination","targetYaw","targetRadius","targetCenter","_flyToAsync","targetPitch","targetYaw_1","targetPitch_1","targetRadius_1","targetCenter_1","flightDurationMs","centerHopScale","overrideAnimationFunction","newCenter","hopOffset","distanceScale","_getCenterAndRadiusFromZoomToPoint","flyToAsync","durationMs","_recalculateCenter","restingAltitude","_applyGeocentricRotation","directionToTarget","newCenterResult","newRadiusClamped","_applyZoom","_clampZoomDelta","isCenterMoving","shouldRecalculateCenterAfterMove","forceRecalculate","centerToOrigin","yawPitch","collisionOffset","__center_decorators","__yaw_decorators","__pitch_decorators","__radius_decorators","__center_initializers","ComputeLookAtFromYawPitchToRef","east","north","clampedCosPitch","lookHorizontal","scaledUp","currentYaw","_Registered$8M","GeospatialCamera","GetLowestRoot","maxR","sqrtD","r1","r2","_collisionPoint","_planeIntersectionPoint","_tempVector","_tempVector2","_tempVector3","_tempVector4","_edge","_baseToVertex","_destinationPoint","_slidePlaneNormal","_basePointWorld","_velocityWorld","_normalizedVelocity","slidePlaneNormal","_initialize","_velocity","_velocitySquaredLength","_basePoint","_velocityWorldLength","_epsilon","collisionFound","pa","pb","pc","vecMin","vecMax","boxMax","boxMin","_testTriangle","trianglePlaneArray","hasMaterial","hostMesh","trianglePlane","signedDistToTrianglePlane","Collider","DoubleSidedCheck","normalDotVelocity","embeddedInPlane","_checkPointInTriangle","lowestRoot","edgeSquaredLength","edgeDotVelocity","edgeDotBaseToVertex","distToCollisionSquared","intersectionPoint","_nearestDistanceSquared","_nearestDistance","pts","indexEnd","invertTriangles","triangleStrip","vel","_displacementVector","_scaledPosition","_scaledVelocity","_finalPosition","maximumRetry","excludedMesh","onNewPosition","collisionIndex","_retry","_initialVelocity","_initialPosition","closeDistance","velocity","_Registered$8L","DefaultCollisionCoordinator","_Registered$8K","_UnsignedIntegerClearColor","_SignedIntegerClearColor","restoreSingleAttachment","restoreSingleAttachmentForRenderTarget","buildTextureLayout","textureStatus","backBufferLayout","hasIntegerAttachment","clearValue","integerMRTAttachmentsMask","unBindMultiColorAttachmentFramebuffer","generateDepthTexture","textureCount","defaultType","defaultSamplingMode","defaultFormat","defaultTarget","types","samplingModes","useSRGBBuffers","formats","layerIndex","labels","dontCreateTextures","_createHardwareRenderTargetWrapper","targetTypes","layerCounts","currentFramebuffer","useStencilTexture","layerCount","isWebGL2","internalSizedFormat","webGLTextureType","depthTexture","depthTextureType","glDepthTextureInternalFormat","glDepthTextureFormat","glDepthTextureType","glDepthTextureAttachment","initializeBuffers","setLayerAndFaceIndices","updateMultipleRenderTargetTextureSampleCount","colorRenderbuffer","depthFormat","readBuffer","MultiRenderTarget","textureNames","drawOnlyOnFirstAttachmentByDefault","RegisterEnginesExtensionsEngineMultiRender","_textureNames","_multiRenderTargetOptions","_drawOnlyOnFirstAttachmentByDefault","_createInternalTextures","_createTextures","_initTypes","mapMainInternalTexture2Index","mapInternalTexture2MainIndex","internalTextures","mainIndex","fromContextLost","_createInternaTextureIndexMapping","releaseInternalTextures","forceFullRebuild","_releaseTextures","createMultipleRenderTarget","disposePrevious","setLayerAndFaceIndex","faceIndices","layerIndices","updateCount","doNotDisposeInternalTextures","standalone","baseMaterial","_baseMaterial","doNotInjectCode","_subMeshToEffect","_subMeshToDepthWrapper","MapMap","_deleteDepthWrapperEffect","depthWrapper","mainDrawWrapper","passIdForDrawWrapper","_makeEffect","_onEffectCreatedObserver","origEffectAndRenderPassId","origEffect","origRenderPassId","originalDefines","depthDefines","vertexNormalBiasCode","remappedVariables","vertexMetricCode","fragmentSoftTransparentShadow","vertexExtraDeclartion","hasLocationForSoftTransparentShadow","hasLocationForFragment","fragmentCodeToInjectAtEnd","fragmentBlockCode","getAttributesNames","getIndexParameters","maxUniformVectors","maxFromUniforms","GetPartIndexVaryingDeclaration","GaussianSplattingMaterialDefinesBase","GaussianSplattingMaterialDefines","USE_SOG_V2","GaussianSplattingMaterial","kernelSize","KernelSize","minPixelSize","MinPixelSize","_inverseProjection","_geometryProjectionUpdateFlag","_partMotionHistory","_renderPassObserver","_voxelMissingTextureWarned","_voxelPartWorldData","_voxelPartVisibilityData","_MakeGaussianSplattingShadowDepthWrapper","compensation","_compensation","_BindViewportAndFocal","invViewportWidth","hasDefine","needsNewDefines","gsMesh","shDegree","isCompound","GetGaussianSplattingMaxPartCount","partCount","MAX_PART_COUNT","useSog","_Attribs","_Uniforms","_Samplers","_UniformBuffers","gaussianSplatting_fragment$1","gaussianSplatting_vertex$1","gaussianSplatting_fragment","gaussianSplatting_vertex","setSourceMesh","gsMaterial","_gaussianSplattingSourceMesh","numberOfRigs","covariancesATexture","covariancesBTexture","centersTexture","colorsTexture","_BindSogUniforms","shTextures","bindExtraEffectUniforms","GetConfiguration","currentPartWorldMatrices","getWorldMatrixForPart","previousPartWorldData","consecutiveFrame","sogParams","rotationsATexture","codebookTexture","meansMin","meansMax","scalesMin","scalesMax","sh0Min","sh0Max","shnMin","shnMax","shCoeffCount","needsRotationScaleTextures","rotationsBTexture","rotationScaleTexture","partIndicesTexture","partWorldDataLength","partWorldData","partVisibilityData","partVisibility","makeVoxelRenderingMaterial","compoundMesh","_VoxelUniforms","_VoxelSamplers","gaussianSplattingVoxel_vertex$1","gaussianSplattingVoxel_fragment$1","gaussianSplattingVoxel_vertex","gaussianSplattingVoxel_fragment","_bindVoxelEffectUniforms","makeDepthRenderingMaterial","alphaBlendedDepth","getSourceMesh","_BindEffectUniforms","ShadowDepthWrapper","Compensation","_Registered$8J","GaussianSplattingGpuPickingMaterialPlugin","maxPartCount","GPUPICKER_DEPTH","GPUPICKER_PACK_DEPTH","_pickingColor","_partPickingColors","_partVisibility","_defaultPartVisibility","_enableDepthPicking","_enablePackedDepthPicking","_maxPartCount","enableDepthPicking","enablePackedDepthPicking","EncodeIdToColor","partMeshIds","setPartActive","activeParts","_getCustomCodeWGSL","_getCustomCodeGLSL","CUSTOM_VERTEX_DEFINITIONS","CUSTOM_FRAGMENT_DEFINITIONS","_Registered$8I","_IsGaussianSplattingMesh","IsGaussianSplattingClassName","GPUMultiPickReadbackStrategy","_pickingTexture","_idMap","_thinIdMap","_meshUniqueIdToPickerId","_idWarningIssued","_cachedScene","_pickingMaterialCache","_pickableMeshes","_meshMaterialMap","_readbuffer","_depthReadbuffer","_depthTextureType","_isDepthTexturePacked","_useDepthPicking","_isUsingDepthPickingRenderTarget","_meshRenderingCount","_renderWarningIssued","_renderPickingTexture","_sceneBeforeRenderObserver","_pickingTextureClearObserver","_pickingTextureAfterRenderObserver","_nextFreeId","_gsPickingMaterials","_pickingInProgress","pickingInProgress","defaultRenderMaterials","pickableMeshes","clearPickingList","addPickingList","_createColorPickingRenderTarget","pickingTexture","_clearPickingMaterials","cachedMaterial","_AttributeName","picking_fragment","picking_vertex","picking_fragment$1","picking_vertex$1","GPUPicker","_materialBindCallback","_gsCompoundRenderMeshes","rttSizeW","rttSizeH","_createRenderTarget","newPickableMeshes","pickableMeshOffset","_getPickingMaterial","gsCompoundGroups","compound","compoundSplatMesh","partEntries","globalIndex","pickId","nextFreeId","gsPickingMaterial","_createGaussianSplattingPickingMaterial","instanceIdData","thinId","currentMeshId","instancesForPick","pickableMeshIndex","globalInstanceIndex","partIndex","_isPartProxyActiveForPicking","_MaxPickingId","pickAsync","y_1","disposeWhenDone","scaleX","scaleY","_getRenderInfo","adjustedX","_prepareForPicking","adjustedY","invertedY","pickingRegion","_getPickingRenderRegion","_preparePickingBuffer","_waitForPickingMaterialsReadyAsync","_addPickingTextureToRenderTargets","_executePickingAsync","multiPickAsync","xy_1","thinInstanceIndexes","pickedPoints","processedXY","hasInBoundsPoint","inBoundsPointCount","depthPadding","_DepthPixelRadius","regionLeft","regionRight","regionTop","regionBottom","partialCutH","useIndividualReadback","_shouldUseIndividualMultiPickReadback","_executeMultiPickingAsync","adjustedX1","adjustedY1","adjustedX2","adjustedY2","_executeBoxPickingAsync","inputElementClientRect","readbackStrategy","maxIndividualReadbackCount","_MaxMultiPickIndividualReadbackCount","individualReadbackAreaRatio","_MultiPickIndividualReadbackAreaRatio","readArea","requiredBufferSize","readBufferW","readBufferH","_updateRenderList","_enableScissor","_disableScissor","_removePickingTextureFromRenderTargets","_checkRenderStatus","colorId","depthPickingInfo","_getDepthPickingInfoAsync","pickedMeshes","pointBottomY","_readTexturePixelsAsync","_getMeshFromReadBuffer","readX","readY","_getMeshFromMultiplePoints","_readDepthTexturePixelsAsync","depthPixels","_getDepthPickingInfoFromBuffer","pickedPixelCoordinates","scanBufferX","scanX","scanBufferY","readW","readH","scanH","bufferX","bufferY","_getColorIdFromReadBuffer","_getReadBufferOffset","scanMaxY","scissorY","attempt","previousRenderPassId","allReady","readWidth","readHeight","requiredByteLength","bufferLeft","bufferBottom","centerBufferX","centerBufferY","centerDepth","_getDepthFromBuffer","closestDistanceSquared","distanceSquared","viewportTop","centerViewportX","centerViewportY","fallbackNormal","bestOffsetA","bestOffsetB","bestDepthDelta","offsets","_DepthNeighborOffsets","depthNeighbors","epsilonSquared","_getDepthPointFromBufferToRef","depthDelta","neighborA","neighborB","toA","toB","viewportX","viewportY","Uint8ClampedArray","setPickingList","name$ae","shader$ae","name$ad","shader$ad","includes$29","inc","name$ac","shader$ac","name$ab","shader$ab","name$aa","shader$aa","name$a9","shader$a9","name$a8","shader$a8","name$a7","shader$a7","name$a6","shader$a6","name$a5","shader$a5","name$a4","shader$a4","name$a3","shader$a3","name$a2","shader$a2","includes$28","bakedVertexAnimationDeclaration","morphTargetsVertexGlobalDeclaration$1","morphTargetsVertexDeclaration$1","instancesDeclaration","morphTargetsVertexGlobal$1","morphTargetsVertex$1","instancesVertex","bonesVertex$1","bakedVertexAnimation","name$a1","shader$a1","name$a0","shader$a0","includes$27","name$9$","shader$9$","name$9_","shader$9_","name$9Z","shader$9Z","name$9Y","shader$9Y","name$9X","shader$9X","name$9W","shader$9W","name$9V","shader$9V","name$9U","shader$9U","name$9T","shader$9T","name$9S","shader$9S","name$9R","shader$9R","includes$26","bakedVertexAnimationDeclarationWGSL","morphTargetsVertexGlobalDeclarationWGSL","morphTargetsVertexDeclarationWGSL","instancesDeclarationWGSL","morphTargetsVertexGlobalWGSL","morphTargetsVertexWGSL","instancesVertexWGSL","bonesVertexWGSL","bakedVertexAnimationWGSL","ComputeEffect","computeSource","_useExplicitComputePipelineLayout","_rawComputeSourceCode","_entryPoint","entryPoint","useExplicitComputePipelineLayout","_shaderStore","_shaderRepository","_includeShaderStore","computeElement","compute","_loadShader","computeCode","ApplyPreProcessing","PreProcess","migratedComputeCode","_computeSourceCode","migratedCommputeCode","_computeSourceCodeOverride","_getComputeShaderCode","rawComputeSourceCode","createComputePipelineContext","_prepareComputePipelineContext","_executeWhenComputeStateIsCompiled","messages","numErrors","_deleteComputePipelineContext","_releaseComputeEffect","computeShader","_gpuTimeInFrameId","counter","_addDuration","_bindings","_contextIsDirty","fastMode","_fastMode_initializers","_fastMode_extraInitializers","triggerContextRebuild","enableGPUTimingMeasurements","gpuTimeInFrame","WebGPUPerfCounter","bindingsMapping","createComputeContext","bindSampler","indexInGroupEntries","setVideoTexture","externalTexture","_BufferIsDataBuffer","_effect","_cachedDefines","createComputeEffect","_checkContext","computeDispatch","dispatchIndirect","computeDispatchIndirect","z_1","bindings","serializedData","_fastMode_decorators","_Registered$8H","ComputeShaderParse","ComputeShader","setStorageTexture","BoundingInfoHelper","ComputeShaderBoundingHelper","computeShaderBoundingHelper_pure","boundingInfo_compute","_platform","TransformFeedbackBoundingHelper","transformFeedbackBoundingHelper_pure","gpuTransform_vertex","gpuTransform_fragment","processAsync","registerMeshListAsync","batchProcess","processMeshList","_initializePlatformAsync","fetchResultsForMeshListAsync","_effects","_meshListCounter","_processMeshList","computeEffect","computeEffectOptions","targetBuffer","bindTransformFeedbackBuffer","setRasterizerState","beginTransformFeedback","endTransformFeedback","readTransformFeedbackBuffer","_refreshBoundingInfo","bb","_Min","_Max","_meshList","name$9Q","shader$9Q","includes$25","name$9P","shader$9P","_computeShadersCache","_positionBuffers","_indexBuffers","_weightBuffers","_indexExtraBuffers","_weightExtraBuffers","_morphTargetInfluenceBuffers","_morphTargetTextureIndexBuffers","_uboIndex","_processedMeshes","_computeShaders","_uniqueComputeShaders","_resultBuffers","_getComputeShader","hasBones","hasMorphs","positionBuffer","resultBuffer","boneSampler","weightBuffer","indexExtraBuffer","weightExtraBuffer","morphTargets","morphTargetInfluences","morphTargetTextureIndices","addFloat3","storageUnit","dataArray","_prepareStorage","_disposeForMeshList","maxNumInfluencers","computeShaderWithoutMorph","computeShaderWithMorph","_getUBO","resultDataSize","resultData","NEGATIVE_INFINITY","_extractDataAndLink","uboNeedsUpdate","_morphTargetTextureIndices","_textureVertexStride","readFromMultipleStorageBuffers","resultDataOffset","minmax","_disposeCache","name$9O","shader$9O","OctreeBlock","maxDepth","creationFunc","_boundingVectors","_capacity","_depth","_maxDepth","_creationFunc","_minPoint","_maxPoint","blocks","createInnerBlocks","removeEntry","entryIndex","addEntries","selection","allowDuplicate","select","intersectsRay","_CreateBlocks","worldMin","worldMax","maxBlockCapacity","currentDepth","localMin","blockSize","localMax","Octree","dynamicContent","_maxBlockCapacity","_selectionContent","OctreeSceneComponent","checksIsEnabled","_tempRay","sceneOctree","_selectionOctree","_submeshesOctree","useOctreeForRenderingSelection","useOctreeForPicking","_Registered$8G","maxCapacity","CreationFuncForMeshes","worldExtends","CreationFuncForSubMeshes","groundColor","_groundColor_initializers","setDirectionToTarget","normalizeDirection","lightDataUniformName","prepareLightSpecificDefines","_groundColor_decorators","_direction_decorators","_Registered$8F","HemisphericLight","UtilityLayerRenderer","getRenderCamera","getRigParentIfPossible","_renderCamera","activeCam","originalScene","setRenderCamera","_getSharedGizmoLight","_sharedGizmoLight","utilityLayerScene","DefaultUtilityLayer","_CreateDefaultUtilityLayerFromScene","_DefaultUtilityLayer","DefaultKeepDepthUtilityLayer","_CreateDefaultKeepUtilityLayerFromScene","_DefaultKeepDepthUtilityLayer","handleEvents","manualRender","_lastPointerEvents","pickUtilitySceneFirst","onlyCheckPointerDownEvents","processAllEvents","pickingEnabled","prePointerInfo","pointerEvent","scenePick","previousActiveCamera","utilityScenePick","getNearPickDataForScene","originalScenePick","_notifyObservers","onPointerOutObservable","mainSceneTrackerPredicate","_originalPointerObserver","_sceneDisposeObserver","oldScene","_afterRenderObserver","GizmoCoordinatesMode","DebugLayerTab","GizmoAnchorPoint","Gizmo","isHovered","_isHovered","attachedMesh","_attachedNode","_rootMesh","_attachedNodeChanged","_customMeshSet","_additionalTransformNode","updateGizmoRotationToMatchAttachedMesh","_updateGizmoRotationToMatchAttachedMesh","updateGizmoPositionToMatchAttachedMesh","_updateGizmoPositionToMatchAttachedMesh","anchorPoint","_anchorPoint","updateScale","_updateScale","gizmoLayer","_customRotationQuaternion","_rightHandtoLeftHandMatrix","customRotationQuaternion","effectiveNode","getRow","PreserveScaling","offsetToCamera","camForward","isUsingPivotMatrix","isUsingPostMultiplyPivotMatrix","_matrixChanged","worldMatrixUc","parentInv","matrixToDecompose","_handlePivotMatrixInverse","UseAbsoluteScaling","invPivotMatrix","invParent","boneLocalMatrix","nodeLocalMatrix","gizmoMeshes","GizmoAxisPointerObserver","gizmoAxisCache","activeDragButton","forcePointerUp","dragBehavior","disableMaterial","colliderMeshes","hoverMaterial","pointerObserver","coloredMaterial","_coloredMaterial","_hoverMaterial","_disableMaterial","_CreateArrow","isCollider","arrow","_CreateArrowInstance","snapDistance","onSnapObservable","hoverColor","disableColor","AxisDragGizmo","_gizmoMesh","additionalInverseMatrix","matrixChanged","currentSnapDragDistance","dragSteps","tmpSnapEvent","addToAxisCache","_setGizmoMeshMaterial","newState","mats","matl","AxesViewer","scaleLines","_scaleLines","_xAxis","_scaleLinesFactor","_yAxis","_zAxis","lineThickness","redColoredMaterial","greenColoredMaterial","blueColoredMaterial","_SetRenderingGroupId","axesViewer","BoneAxesViewer","DebugLayer","onPropertyChangedObservable","BJSINSPECTOR","Inspector","OnPropertyChangedObservable","_onPropertyChangedObservable","onSelectionChangedObservable","OnSelectionChangeObservable","_onSelectionChangedObservable","_getGlobalInspector","_debugLayer","hide","_createInspector","config","OnSelectionChangedObservable","userOptions","Config","Show","lineContainerTitles","MarkLineContainerTitleForHighlighting","MarkMultipleLineContainerTitlesForHighlighting","IsVisible","waitAndCheck","INSPECTOR","Hide","openedPanes","_OpenedPane","setAsActiveScene","_SetNewScene","popupSceneExplorer","PopupSceneExplorer","popupInspector","PopupInspector","popupEmbed","PopupEmbed","LoadBabylonScript","inspectorUrl","InspectorURL","overlay","showExplorer","showInspector","embedMode","handleResize","enablePopup","_Registered$8E","PhysicsJoint","jointData","nativeParams","_physicsJoint","physicsJoint","newJoint","physicsPlugin","_physicsPlugin","DistanceJoint","HingeJoint","BallAndSocketJoint","WheelJoint","SliderJoint","PrismaticJoint","UniversalJoint","Hinge2Joint","PointToPointJoint","SpringJoint","LockJoint","updateDistanceJoint","MotorEnabledJoint","setMotor","maxForce","setLimit","targetSpeed","motorIndex","PhysicsImpostor","mass","_physicsEngine","getPhysicsPlugin","getBodyMass","setMass","friction","getBodyFriction","setBodyFriction","restitution","getBodyRestitution","setBodyRestitution","pressure","setBodyPressure","getBodyPressure","stiffness","getBodyStiffness","setBodyStiffness","velocityIterations","getBodyVelocityIterations","setBodyVelocityIterations","positionIterations","getBodyPositionIterations","setBodyPositionIterations","_pluginData","_bodyUpdateRequired","_onBeforePhysicsStepCallbacks","_onPhysicsCollideCallbacks","soft","_tmpQuat","_tmpQuat2","beforeStep","_deltaRotationConjugated","getParentsRotation","disableBidirectionalTransformation","setPhysicsBodyTransformation","afterStep","_onAfterPhysicsStepCallbacks","onCollideEvent","getImpostorWithPhysicsBody","otherImpostor","callbacks","otherImpostors","impulse","fixedPoints","margin","damping","ignoreParent","_init","removeImpostor","_getPhysicsParent","addImpostor","_physicsBody","removePhysicsBody","resetUpdateFlags","getObjectExtents","DEFAULT_OBJECT_SIZE","getObjectCenter","paramName","setParam","setBodyMass","getLinearVelocity","setLinearVelocity","getAngularVelocity","setAngularVelocity","executeNativeFunction","registerBeforePhysicsStep","registerAfterPhysicsStep","registerOnPhysicsCollide","collideAgainst","collidedAgainstList","unregisterOnPhysicsCollide","cbDef","sameList","applyForce","contactPoint","joint","addJoint","_joints","addAnchor","noCollisionBetweenLinkedBodies","appendAnchor","addHook","appendHook","sleep","sleepBody","wakeUp","wakeUpBody","newObject","removeJoint","setDeltaPosition","setDeltaRotation","getBoxSizeToRef","getRadius","jointPivot","distToJoint","adjustRotation","tempQuat","syncImpostorWithBone","boneAxis","boneDir","IDENTITY_QUATERNION","NoImpostor","SphereImpostor","BoxImpostor","PlaneImpostor","MeshImpostor","CapsuleImpostor","CylinderImpostor","ParticleImpostor","HeightmapImpostor","ConvexHullImpostor","CustomImpostor","RopeImpostor","ClothImpostor","_Registered$8D","PhysicsViewer","_numConstraints","_ownUtilityLayer","_debugMeshMeshes","_constraintAxesSize","_constraintAngularSize","physicEngine","_physicsEnginePlugin","utilityLayer","_utilityLayer","_updateDebugMeshes","_updateDebugMeshesV1","_updateDebugMeshesV2","_numMeshes","_impostors","hideImpostor","syncMeshWithImpostor","_numBodies","_bodies","hideBody","_bodyMeshes","syncTransform","_numInertiaBodies","_inertiaBodies","hideInertia","_inertiaMeshes","_updateDebugInertia","inertiaMatrixRef","transformMatrixRef","finalMatrixRef","_pluginDataInstances","inertiaAsMesh","inertiaMesh","inertiaMeshMatrixData","bodyTransformMatrixData","getMassProperties","_getMeshDebugInertiaMatrixToRef","parentTransform","decomposeToTransformNode","_updateDebugConstraints","_constraints","_constraintMeshes","_updateDebugConstraint","_makeScalingUnitInPlace","parentingMesh","_initOptions","pivotA","pivotB","axisA","axisB","perpAxisA","perpAxisB","parentCoordSystemNode","parentConstraintMesh","childCoordSystemNode","parentBody","parentBodyIndex","childBody","childBodyIndex","childTransform","_getTransformFromBodyToRef","parentTransformNode","childTransformNode","showImpostor","_getDebugMesh","debugMesh","_renderFunction","showBody","_getDebugBodyMesh","showInertia","_getDebugInertiaMesh","_inertiaRenderFunction","_updateInertiaMeshes","showConstraint","_getDebugConstraintMesh","_constraintRenderFunction","hideConstraint","_getDebugMaterial","_debugMaterial","_getDebugInertiaMaterial","_debugInertiaMaterial","axisNumber","_getDebugBoxMesh","_debugBoxMesh","_getDebugSphereMesh","_debugSphereMesh","_getDebugCapsuleMesh","_debugCapsuleMesh","_getDebugCylinderMesh","_debugCylinderMesh","_getDebugMeshMesh","wireframeOver","bi","childMeshes","getGeometry","instanceBuffer","massProps","inertiaOrientation","inertiaLocal","centerOfMass","betaSqrd","gammaSqrd","alphaSqrd","extents","inertiaBoxMesh","matrixRef","edgesColor","tnode","_createAngularConstraintMesh","minLimit","maxLimit","arcAngle","_getDebugAxisColoredMaterial","parentScaling","_createCage","cage","transparentMaterial","bodiesUsingConstraint","getBodiesUsingConstraint","parentedConstraintMeshes","parentOfPair","rotTransformParent","rotTransformChild","translateTransformParent","translateTransformChild","parentAxes","childAxes","constraintAxisAngular","lockCount","angularLinear","constraintAxisValue","getAxisMode","limited","getAxisMinLimit","getAxisMaxLimit","axisIndex","axisMode","PhysicsEngine$1","PhysicsEngine","DefaultPluginFactory","_subTimeStep","_uniqueIdCounter","setGravity","setTimeStep","newTimeStep","setSubTimeStep","subTimeStep","getPhysicsPluginName","generatePhysicsBody","mainImpostor","connectedImpostor","impostorJoint","generateJoint","matchingJoints","isBodyInitRequired","executeStep","raycast","raycastToRef","_hasHit","_hitNormal","_hitPoint","_triangleIndex","hitPoint","hitNormal","hasHit","triangleIndex","setHitData","bodyIndex","CastingResult","_hitDistance","_rayFromWorld","_rayToWorld","hitDistance","hitNormalWorld","hitPointWorld","rayFromWorld","rayToWorld","setHitDistance","calculateHitDistance","_physicsBodies","maxLinearVelocity","setVelocityLimits","maxAngularVelocity","getMaxLinearVelocity","getMaxAngularVelocity","_step","addBody","PhysicsRaycastResult","PhysicsEngineSceneComponent","onBeforePhysicsObservable","getDeterministicFrameTime","onAfterPhysicsObservable","_Registered$8C","subTime","getSubTimeStep","_physicsTimeAccumulator","RayHelper","helper","show","_renderPoints","_renderLine","meshSpaceDirection","meshSpaceOrigin","_attachedToMesh","_meshSpaceDirection","_meshSpaceOrigin","_updateToMesh","_onAfterStepObserver","detachFromMesh","SkeletonViewer","colorBase","colorZero","colorQuarter","colorHalf","colorFull","targetBoneIndex","colorMap","colorMapBuffer","_CreateBoneMapColorBuffer","tempGrad","grad","createLinearGradient","addColorStop","rUnit","_ready","ready","_debugMesh","debugLocalAxesMesh","_localAxes","displayMode","DISPLAY_LINES","DISPLAY_SPHERE_AND_SPURS","autoUpdateBonesMatrices","_obs","pauseAnimations","displayOptions","midStep","midStepFactor","sphereBaseSize","sphereScaleUnit","sphereFactor","spurFollowsChild","showLocalAxes","localAxesSize","useAllBones","_boneIndices","initialMeshBoneIndices","initialMeshBoneWeights","_bindObs","_displayLinesUpdate","DISPLAY_SPHERES","_buildSpheresAndSpurs","_buildLocalAxes","meshMat","tmat2","_getLinesForBonesWithLength","meshPos","_debugLines","_getBonePosition","_getLinesForBonesNoLength","boneNum","childBone","_revert","animationState","childPoint","up0","spur","numVertices","mwk","mik","_getBoundingSphereForBone","bIndex","bWeight","spheres","spurs","longestBoneLength","boneAbsoluteBindPoseTransform","bc","childAbsoluteBindPoseTransform","distanceFromParent","spheresOnly","_createSpur","_stepsOut","targetScene","red","green","blue","boneOrigin","boneAxisX","boneAxisY","boneAxisZ","linePoints","changeDisplayMode","changeDisplayOptions","option","FindMainCamera","FindMainObjectRenderer","findMainObjectRenderer","CreateUtilityLayerRenderer","frameFraph","FrameGraphUtils","gizmoLayerRenderObserver","DirectionalLightFrustumViewer","transparency","_transparency","_lightHelperFrustumMeshes","showLines","_showLines","showPlanes","_showPlanes","_oldDirection","_light","_inverseViewMatrix","_createGeometry","_removeMeshesFromFrameGraph","_addMeshesToFrameGraph","_visible","objectList","_oldAutoCalc","autoCalcShadowZBounds","_oldMinZ","shadowMinZ","_oldMaxZ","shadowMaxZ","_oldOrthoLeft","_oldOrthoRight","_oldOrthoTop","_oldOrthoBottom","_getInvertViewMatrix","invLightView","_nearLinesPoints","_farLinesPoints","_trLinesPoints","_brLinesPoints","_tlLinesPoints","_blLinesPoints","_nearPlaneVertices","updateVerticesDataDirectly","_farPlaneVertices","_rightPlaneVertices","_leftPlaneVertices","_topPlaneVertices","_bottomPlaneVertices","nearLines","farLines","trLines","brLines","tlLines","blLines","makePlane","ExtractBetweenMarkers","markerOpen","markerClose","waitForChar","currPos","currChar","openMarkers","nextChar","IsIdentifierChar","RemoveComments","inComments","FindBackward","EscapeRegExp","mainFuncDecl","startingCode","endingCode","lastClosingCurly","_sourceCode","debug","_numMaxIterations","numMaxIterations","_functionDescr","inlineToken","processCode","_collectFunctions","_processInlining","inlineTokenIndex","funcParamsStartIndex","funcNameMatch","ShaderCodeInliner","_RegexpFindFunctionNameAndType","funcParamsEndIndex","funcName","funcType","SkipWhitespaces","funcBodyStartIndex","funcBodyEndIndex","funcParams","paramNames","funcBody","callIndex","partBefore","partAfter","_replaceFunctionCallsByCode","functionCallIndex","callParamsStartIndex","callParamsEndIndex","splitParameterCall","startParamIdx","curIdx","callParams","retParamName","injectDeclarationIndex","partBetween","doAgain","_replaceNames","sources","destinations","sourceLen","_nativeProcessingContext","remappedAttributeNames","injectInVertexMain","vertexBufferKindToNumberOfComponents","newType","_isFragment","InjectStartingAndEndingCode","NativeDataStream","DEFAULT_BUFFER_SIZE","_uint32s","_int32s","_float32s","_nativeDataStream","_flush","writeUint32","_flushIfNecessary","writeInt32","writeFloat32","writeNativeData","writeBoolean","writeBuffer","NativePipelineContext","compilationError","isCompiled","vertexBufferKindToType","RenderTargetWrapper","disposeExisting","depthStencilTextureWithStencil","_isMulti","_faceIndices","_layerIndices","resolveMSAATextures","resolveMSAAColors","depthReadOnly","stencilReadOnly","_depthStencilTextureLabel","_shareDepth","rtw","lastTextureSource","internalTexture2Index","optionsMRT","_cloneRenderTargetWrapper","bilinear","_swapRenderTargetWrapper","disposeOnlyFramebuffers","NativeRenderTargetWrapper","__framebuffer","_releaseFramebufferObjects","_framebuffers","__framebuffers","framebuffers","_framebufferDepthStencil","__framebufferDepthStencil","framebufferDepthStencil","_createMultiRenderTargetFramebuffer","NativeHardwareTexture","_nativeTexture","TEXTURE_FORMAT_D16","TEXTURE_FORMAT_D24","TEXTURE_FORMAT_D24S8","TEXTURE_FORMAT_BC7","TEXTURE_FORMAT_BC6H","TEXTURE_FORMAT_BC3","TEXTURE_FORMAT_BC2","TEXTURE_FORMAT_BC1","TEXTURE_FORMAT_ASTC4x4","TEXTURE_FORMAT_ASTC5x4","TEXTURE_FORMAT_ASTC5x5","TEXTURE_FORMAT_ASTC6x5","TEXTURE_FORMAT_ASTC6x6","TEXTURE_FORMAT_ASTC8x5","TEXTURE_FORMAT_ASTC8x6","TEXTURE_FORMAT_ASTC8x8","TEXTURE_FORMAT_ASTC10x5","TEXTURE_FORMAT_ASTC10x6","TEXTURE_FORMAT_ASTC10x8","TEXTURE_FORMAT_ASTC10x10","TEXTURE_FORMAT_ASTC12x10","TEXTURE_FORMAT_ASTC12x12","TEXTURE_FORMAT_ETC1","TEXTURE_FORMAT_ETC2","TEXTURE_FORMAT_ETC2A","TEXTURE_FORMAT_RGB8","TEXTURE_FORMAT_RGB8S","TEXTURE_FORMAT_RGB8I","TEXTURE_FORMAT_RGBA8","TEXTURE_FORMAT_RGBA32F","TEXTURE_FORMAT_RGBA16F","TEXTURE_FORMAT_RGBA8S","TEXTURE_FORMAT_RGBA16I","TEXTURE_FORMAT_RGBA16U","TEXTURE_FORMAT_RGBA32I","TEXTURE_FORMAT_R8","TEXTURE_FORMAT_R32F","TEXTURE_FORMAT_R16F","TEXTURE_FORMAT_R8S","TEXTURE_FORMAT_R16S","TEXTURE_FORMAT_R16U","TEXTURE_FORMAT_R32I","TEXTURE_FORMAT_RG8","TEXTURE_FORMAT_RG32F","TEXTURE_FORMAT_RG16F","TEXTURE_FORMAT_RG8S","TEXTURE_FORMAT_RG16S","TEXTURE_FORMAT_RG16U","TEXTURE_FORMAT_RG32I","UnsupportedTextureError","wrapMode","ADDRESS_MODE_WRAP","ADDRESS_MODE_CLAMP","ADDRESS_MODE_MIRROR","_warnedUnsupportedAlphaModes","_getFallbackAlphaMode","unsupportedName","fallbackName","ATTRIB_TYPE_INT8","ATTRIB_TYPE_UINT8","ATTRIB_TYPE_INT16","ATTRIB_TYPE_UINT16","VertexBufferKindForNonFloatProcessing","currentVertexBuffer","currentVertexBufferType","vertexBufferType","IsSignedType","_processShaderCodeAsync","_timeElapsedQueryEnded","self","__native","onNativeObjectInitialized","nativeObject","AcquireNativeObjectAsync","typeName","NativeDataBuffer","CommandBufferEncoder","_pending","_isCommandBufferScopeActive","_commandStream","_createNativeDataStream","setCommandDataStream","beginCommandScope","endCommandScope","_submit","startEncodingCommand","encodeCommandArgAsUInt32","commandArg","encodeCommandArgAsUInt32s","writeUint32Array","encodeCommandArgAsInt32","encodeCommandArgAsInt32s","writeInt32Array","encodeCommandArgAsFloat32","encodeCommandArgAsFloat32s","writeFloat32Array","encodeCommandArgAsNativeData","finishEncodingCommand","submitCommands","remappedAttributesNames","_initializeNativeEngine","RegisterBufferAlign","nonFloatVertexBuffers","_commandBufferEncoder","_frameStats","gpuTimeNs","_boundBuffersVertexArray","_currentDepthTest","DEPTH_TEST_LEQUAL","_depthTestEnabled","_stencilTest","_stencilMask","_stencilFunc","_stencilFuncRef","_stencilFuncMask","_stencilOpStencilFail","_stencilOpDepthFail","_stencilOpStencilDepthPass","_cachedCulling","_cachedReverseSide","_cachedCullBackFaces","_cachedZOffset","_cachedZOffsetUnits","_fillModeWarningDisplayed","PROTOCOL_VERSION","ThinNativeEngine","setRenderResetCallback","renderResetCallback","setDeviceLostCallback","CAPS_LIMITS_MAX_TEXTURE_SIZE","CAPS_LIMITS_MAX_TEXTURE_LAYERS","acc","getDepthFunction","currentDepthFunction","NativeShaderProcessor","_wrapSceneRenderWithCommandScope","originalRender","endException","renderException","_deleteVertexArray","COMMAND_SETSCISSOR","COMMAND_UNBINDFRAMEBUFFER","COMMAND_CLEAR","updateable","nativeIndexBuffer","nativeVertexBuffer","_recordVertexArrayObject","_checkedNonFloatVertexBuffers","checkNonFloatVertexBuffers","recordIndexBuffer","vertexArray","recordVertexBuffer","effectiveByteOffset","effectiveByteStride","getNativeAttribType","nativePipelineContext","nativeShaderProcessingContext","origAttributeName","_checkSupportedFillMode","_flushDepthTestState","COMMAND_DRAWINDEXEDINSTANCED","COMMAND_DRAWINDEXED","COMMAND_DRAWINSTANCED","COMMAND_DRAW","_rebuildRebind","NativeShaderProcessingContext","vertexInliner","fragmentInliner","createProgramAsync","sci","COMMAND_SETPROGRAM","COMMAND_DELETEPROGRAM","COMMAND_SETVIEWPORT","cullBack","COMMAND_SETSTATE","toJSON","COMMAND_SETZOFFSET","COMMAND_SETZOFFSETUNITS","_encodeDepthTest","COMMAND_SETDEPTHTEST","DEPTH_TEST_ALWAYS","_depthWrite","DEPTH_TEST_NEVER","DEPTH_TEST_GREATER","DEPTH_TEST_GEQUAL","DEPTH_TEST_NOTEQUAL","DEPTH_TEST_EQUAL","DEPTH_TEST_LESS","nativeDepthFunc","COMMAND_SETDEPTHWRITE","COMMAND_SETCOLORWRITE","applyStencil","_setStencil","opFail","STENCIL_OP_FAIL_S_KEEP","STENCIL_OP_FAIL_S_ZERO","STENCIL_OP_FAIL_S_REPLACE","STENCIL_OP_FAIL_S_INCR","STENCIL_OP_FAIL_S_DECR","STENCIL_OP_FAIL_S_INVERT","STENCIL_OP_FAIL_S_INCRSAT","STENCIL_OP_FAIL_S_DECRSAT","getNativeStencilOpFail","depthFail","STENCIL_OP_FAIL_Z_KEEP","STENCIL_OP_FAIL_Z_ZERO","STENCIL_OP_FAIL_Z_REPLACE","STENCIL_OP_FAIL_Z_INCR","STENCIL_OP_FAIL_Z_DECR","STENCIL_OP_FAIL_Z_INVERT","STENCIL_OP_FAIL_Z_INCRSAT","STENCIL_OP_FAIL_Z_DECRSAT","getNativeStencilDepthFail","opPass","STENCIL_OP_PASS_Z_KEEP","STENCIL_OP_PASS_Z_ZERO","STENCIL_OP_PASS_Z_REPLACE","STENCIL_OP_PASS_Z_INCR","STENCIL_OP_PASS_Z_DECR","STENCIL_OP_PASS_Z_INVERT","STENCIL_OP_PASS_Z_INCRSAT","STENCIL_OP_PASS_Z_DECRSAT","getNativeStencilDepthPass","STENCIL_TEST_LESS","STENCIL_TEST_LEQUAL","STENCIL_TEST_EQUAL","STENCIL_TEST_GEQUAL","STENCIL_TEST_GREATER","STENCIL_TEST_NOTEQUAL","STENCIL_TEST_NEVER","STENCIL_TEST_ALWAYS","getNativeStencilFunc","stencilOpFail","depthOpFail","depthOpPass","COMMAND_SETSTENCIL","setStencilOperationPass","operation","setStencilMask","setStencilFunction","setStencilFunctionReference","setStencilFunctionMask","setStencilOperationFail","setStencilOperationDepthFail","noDepthWriteChange","nativeMode","getNativeAlphaMode","COMMAND_SETBLENDMODE","COMMAND_SETINT","COMMAND_SETINTARRAY","COMMAND_SETINTARRAY2","COMMAND_SETINTARRAY3","COMMAND_SETINTARRAY4","COMMAND_SETFLOATARRAY","COMMAND_SETFLOATARRAY2","COMMAND_SETFLOATARRAY3","COMMAND_SETFLOATARRAY4","COMMAND_SETMATRICES","COMMAND_SETMATRIX3X3","COMMAND_SETMATRIX2X2","COMMAND_SETFLOAT","COMMAND_SETFLOAT2","COMMAND_SETFLOAT3","COMMAND_SETFLOAT4","getCanvasTexture","COMMAND_COPYTEXTURE","createVideo","webGLTexture","updateVideoTexture","_getUseSRGBBuffer","getNativeSamplingMode","_setTextureSampling","nativeTexture","loadRawTexture2DArray","getNativeTextureFormat","loadRawTexture","loadTexture","getTextureWidth","getTextureHeight","getTextureLayerCount","newWidth","newHeight","newLayerCount","oldLayerCount","createFrameBuffer","nativeRTWrapper","initializeTexture","hasMips","nativeTextureFormat","colorHandles","expectedCount","createMultiFrameBuffer","clearAttachments","_rtWrapper","_disableGenerateMipMaps","_initializeBuffers","updateDynamicIndexBuffer","byteView","_unsetNativeTexture","_setTextureWrapMode","getNativeAddressMode","_updateAnisotropicLevel","COMMAND_SETTEXTURESAMPLING","addressModeU","addressModeV","addressModeW","COMMAND_SETTEXTUREWRAPMODE","COMMAND_SETTEXTURE","COMMAND_UNSETTEXTURE","COMMAND_SETTEXTUREANISOTROPICLEVEL","_setNativeTexture","COMMAND_DISCARDALLTEXTURES","COMMAND_DELETEINDEXBUFFER","COMMAND_DELETEVERTEXBUFFER","rawBuffer","startTimeQuery","_gpuFrameTimeToken","_TimeToken","populateFrameStats","_Registered$8B","alphaBlendDisabled","_Registered$8A","alphaToCoverageState","alphaToCoverageContext","mainPassSampleCount","setAlphaToCoverage","SAMPLE_ALPHA_TO_COVERAGE","mainPassSampleCountContext","SAMPLES","_Registered$8z","rgbaData","rgbData","MakeCreateRawTextureFunction","updateRawTexture3D","internalType","internalSizedFomat","compressedTexImage3D","s3tc","updateRawCubeTexture","needConversion","ConvertRGBtoRGBATextureData","createRawCubeTextureFromUrl","mipmapGenerator","faceDataArraysResult","faceDataArrays","mipSize","mipFaceData","internalCallbackAsync","MakeUpdateRawTextureFunction","_Registered$8y","dummy","allocateAndCopyTypedBuffer","_Registered$8x","internalOptions","_setCubeMapTextureParams","maxLevel","TEXTURE_MAX_LEVEL","_maxLodLevel","files","createPolynomials","lodScale","lodOffset","createCubeTextureBase","imgs","TEXTURE_CUBE_MAP_POSITIVE_Y","TEXTURE_CUBE_MAP_POSITIVE_Z","TEXTURE_CUBE_MAP_NEGATIVE_X","TEXTURE_CUBE_MAP_NEGATIVE_Y","TEXTURE_CUBE_MAP_NEGATIVE_Z","texelFormat","unbind","currentFb","getMSAARenderBuffer","_disposeOnlyFramebuffers","currentFrameBuffer","depthbuffer","faceIndexOrLayer","_bindTextureRenderTarget","_Registered$8w","WebGLRenderTargetWrapper","msaaRenderBuffer","_setupDepthStencilTexture","samplingParameters","_Registered$8v","_Registered$8u","PositionNormalVertex","PositionNormalTextureVertex","SH3ylmBasisConstants","applySH3","SH3ylmBasisTrigonometricTerms","SHCosKernelConvolution","preScaled","colorVector","deltaSolidAngle","preScaleForRendering","updateFromArray","SphericalHarmonics","FromPolynomial","polynomial","_harmonics","updateFromHarmonics","harmonics","FromHarmonics","SphericalPolynomial","sp","_Registered$8t","DDSTools","dds_pure","minLODIndex","maxLODIndex","lodIndex","mipmapIndex","glTextureFromLod","isDDS","UploadDDSLevels","lodTexture","_Registered$8s","UNIFORM_BUFFER","bindBufferBase","_Registered$8r","displayLoadingUI","loadingScreen","hideLoadingUI","_loadingScreen","loadingUIText","loadingUIBackgroundColor","_Registered$8q","setDepthFunctionToGreater","setDepthFunctionToGreaterOrEqual","setDepthFunctionToLess","setDepthFunctionToLessOrEqual","getAlphaEquation","_Registered$8p","getStencilBuffer","getStencilMask","getStencilFunction","getStencilBackFunction","getStencilFunctionReference","getStencilFunctionMask","setStencilBackFunction","getStencilOperationFail","getStencilBackOperationFail","getStencilOperationDepthFail","getStencilBackOperationDepthFail","getStencilOperationPass","getStencilBackOperationPass","setStencilBackOperationFail","setStencilBackOperationDepthFail","setStencilBackOperationPass","cacheStencilState","_cachedStencilBuffer","_cachedStencilFunction","_cachedStencilMask","_cachedStencilOperationPass","_cachedStencilOperationFail","_cachedStencilOperationDepthFail","_cachedStencilReference","restoreStencilState","_Registered$8o","RegisterFileTools","RegisteredTextureLoaders","registerTextureLoader","loaderFactory","unregisterTextureLoader","iesTextureLoader","_IESTextureLoader","ddsTextureLoader","_DDSTextureLoader","basisTextureLoader","_BasisTextureLoader","envTextureLoader","_ENVTextureLoader","hdrTextureLoader","_HDRTextureLoader","ktxTextureLoader","_KTXTextureLoader","tgaTextureLoader","_TGATextureLoader","exrTextureLoader","_ExrTextureLoader","registered","_Registered$8n","_GetCompatibleTextureLoader","_Registered$8m","SCISSOR_TEST","scissor","NullEngine","enableMultiview","NullEngineOptions","renderingCanvas","theCurrentGlobal","global","_elements","_offset","_location","_blockName","urlArg","GetExtensionFromUrl","urlWithoutUriParams","_Registered$8l","_partialLoadFile","loadedFiles","onfinish","onErrorCallBack","_internalCount","_cascadeLoadFiles","_cascadeLoadImgs","loadedImages","_partialLoadImg","tokenPendingData","beforeLoadCubeDataCallback","imageHandler","originalRootUrl","localOnError","loader","onLoadData","loadCubeData","supportCascades","images","_Registered$8k","_gpuFrameTime","_Registered$8j","createQuery","isOcclusionQueryVisible","getQueryResult","isOcclusionQueryInProgress","__occlusionDataStorage","_OcclusionDataStorage","isOccluded","occlusionQueryAlgorithmType","occlusionType","occlusionRetryCount","checkOnly","OCCLUSION_TYPE_NONE","isQueryResultAvailable","occlusionInternalRetryCounter","OCCLUSION_TYPE_OPTIMISTIC","occlusionBoundingBoxRenderer","beginOcclusionQuery","renderOcclusionBoundingBox","endOcclusionQuery","_Registered$8i","setAlphaEquation","EngineView","_Registered$8h","OnAfterViewRenderObservable","OnBeforeViewRenderObservable","registerView","clearBeforeCopy","masterCanvas","newView","unRegisterView","_renderViewStep","previewCamera","previewCameras","activeView","customResize","dimsChanged","inputElementView","_Registered$8g","TransformTextureUrl","_excludedCompressedTextures","strRegExPattern","lastQuestionMark","querystring","_textureFormatInUse","texturesSupported","setCompressedTextureExclusions","skippedFiles","setTextureFormatToUse","formatsAvailable","len1","len2","_Registered$8f","groupName","_Registered$8e","getQueryParameter","QUERY_RESULT_AVAILABLE","QUERY_RESULT","glAlgorithm","_getGlAlgorithmType","algorithmType","beginQuery","endQuery","_createTimeQuery","createQueryEXT","_deleteTimeQuery","deleteQueryEXT","_getTimeQueryResult","getQueryObjectEXT","QUERY_RESULT_EXT","_getTimeQueryAvailability","QUERY_RESULT_AVAILABLE_EXT","GPU_DISJOINT_EXT","_startTimeQuery","queryCounterEXT","_currentNonTimestampToken","_timeElapsedQuery","beginQueryEXT","TIME_ELAPSED_EXT","endTimeQuery","_endTimeQuery","endQueryEXT","disjoint","timeStart","captureGPUFrameTime","_captureGPUFrameTime","gpuFrameTime","getGPUFrameTimeCounter","_onBeginFrameObserver","_onEndFrameObserver","ANY_SAMPLES_PASSED_CONSERVATIVE","ANY_SAMPLES_PASSED","_Registered$8d","createTransformFeedback","TRANSFORM_FEEDBACK","usePoints","INTERLEAVED_ATTRIBS","TRANSFORM_FEEDBACK_BUFFER","_Registered$8c","_isDisabled","_videoTextureSupported","videoWidth","videoHeight","_Registered$8b","updateTextureArrayLayerFromImageSource","premultiplyAlpha","glFormat","texSubImage3D","ComputeBindingType","_Registered$8a","areAllComputeEffectsReady","computeSourceCode","_rebuildComputeEffects","VALIDATION_UINT_32","VALIDATION_INT_32","VALIDATION_FLOAT_32","VALIDATION_UINT_32_ARRAY","VALIDATION_INT_32_ARRAY","VALIDATION_FLOAT_32_ARRAY","VALIDATION_NATIVE_DATA","VALIDATION_BOOLEAN","_Registered$89","VALIDATION_ENABLED","ValidatedNativeDataStream","RGBDTextureTools","ExpandRGBDTexture","expandTexture","expandRgbdTextureAsync","isWebGpu","rgbdDecode_fragment","rgbdDecode_fragment$1","rgbdPostProcess","expandedTexture","EncodeTextureToRGBD","internalTexture_1","outputTextureType","rgbdEncode_fragment","rgbdEncode_fragment$1","ResourcesPromise","resources","thinEngineClass","thinEngine_pure","Dispose","passPixelShader","dumpEngine","_CreateDumpResourcesAsync","_GetDumpResourcesAsync","pixelData","_static_EncodeImageAsync_decorators","EncodeImageAsync","EncodingHelper","HTMLCanvasElement","_Registered$88","DefaultEnvironmentTextureImageType","MagicBytes","manifestString","manifest","binaryDataPosition","normalizeEnvInfo","imageType","sphericalPolynomialPromise","_sphericalPolynomialPromise","cubeWidth","specularTextures","mipmapsCount","_GetTextureEncodedDataAsync","faceWidth","imageQuality","disableIrradianceTexture","diffuseTextures","irradiance","CreateEnvTextureIrradiance","mipmaps","dominantDirection","infoString","infoBuffer","infoView","strLen","totalSize","finalBuffer","finalBufferView","faceDataFloat","tempTexture","rgbdEncodedData","imageEncodedData","polynmials","CreateRadianceImageDataArrayBufferViews","specularInfo","imageInfo","promises","radianceImageData","irradianceImageData","CreateIrradianceImageDataArrayBufferViews","UploadIrradianceLevelsAsync","ImageBitmap","generateNonLODTextures","lodTextures","imageData_1","size_1","mainTexture","_UploadLevelsAsync","canGenerateNonLODTextures","cubeRtt","mipSlices","colorSpaceConversion","_OnImageReadyAsync","UploadEnvSpherical","irradianceInfo","_UpdateRGBDAsync","UploadRadianceLevelsAsync","_internalTexture","proxyPromise","_bufferViewArrayArray","EnvironmentTextureTools","GetEnvInfo","CreateEnvTextureAsync","UploadEnvLevelsAsync","hardware","nativeEngine","fallbackSize","_Registered$87","loadCubeTextureWithMips","SyncCubeTextureSizeFromNative","NotifyCubeTextureLoaded","onloaddata","loadCubeTexture","singleUrl","sourceLabel","loadContainerBufferAsync","ApplySphericalPolynomialFromNative","_loadFileAsync","ComputeNumMipmapLevels","IsHardwareTexture","IsInternalTexture","IsImageBitmap","IsImageBitmapArray","sampleCount","_currentRenderPass","_debugMarkersPendingEncoderPops","_timestampQuery","gpuTimeInFrameForMainPass","_currentPassIsMainPass","_endCurrentRenderPass","_debugPopBeforeEndOfEncoder","currentPassIndex","_snapshotRendering","endRenderPass","_bundleList","run","endPass","_timestampIndex","_debugPendingPop","_generateMipmaps","commandEncoder","_renderEncoder","gpuHardwareTexture","mipmapCount","WebGPUTextureHelper","_textureHelper","generateCubeMipmaps","groups","_debugMarkersPassGroups","_debugMarkersEncoderGroups","popDebugGroup","pushDebugGroup","_showGPUDebugMarkersLog","currentRenderPass","PowerPreference","FeatureName","BufferMapState","BufferUsage","MapMode","TextureDimension","TextureUsage","TextureViewDimension","TextureAspect","AddressMode","FilterMode","MipmapFilterMode","CompareFunction","ShaderStage","BufferBindingType","SamplerBindingType","TextureSampleType","StorageTextureAccess","CompilationMessageType","PipelineErrorReason","PrimitiveTopology","FrontFace","CullMode","ColorWrite","BlendFactor","BlendOperation","StencilOperation","IndexFormat","VertexFormat","VertexStepMode","ComputePassTimestampLocation","RenderPassTimestampLocation","LoadOp","StoreOp","QueryType","CanvasAlphaMode","CanvasToneMappingMode","DeviceLostReason","ErrorFilter","TextureFormat","AutoLayoutMode","WebGPUHardwareTexture","_webgpuTexture","_webgpuMSAATexture","_createMSAATexture","releaseMSAATextures","releaseTexture","_originalFormatIsRGB","originalFormat","textureUsages","textureAdditionalUsages","viewForWriting","_textureSource","viewDimension","arrayLayerCount","GetDepthFormatOnly","HasDepthAndStencilAspects","createView","baseArrayLayer","baseMipLevel","createViewForWriting","saveNumMipMaps","destroy","_copyInvertYTempTexture","invertYPreMultiplyAlphaWithOfstVertexSource","PipelineType","VideoPipelineType","shadersForPipelineType","invertYPreMultiplyAlphaVertexSource","renderableTextureFormatToIndex","r8unorm","r8uint","r8sint","r16uint","r16sint","r16float","rg8unorm","rg8uint","rg8sint","r32uint","r32sint","r32float","rg16uint","rg16sint","rg16float","rgba8unorm","rgba8uint","rgba8sint","bgra8unorm","rgb10a2uint","rg32uint","rg32sint","rg32float","rgba16uint","rgba16sint","rgba16float","rgba32uint","rgba32sint","rgba32float","stencil8","depth16unorm","depth24plus","depth32float","r16unorm","rg16unorm","rgba16unorm","r16snorm","rg16snorm","rgba16snorm","bufferManager","enabledExtensions","_pipelines","_compiledShaders","_videoPipelines","_videoCompiledShaders","_deferredReleaseTextures","_bufferManager","_mipmapSampler","createSampler","_videoSampler","_ubCopyWithOfst","Uniform","CopyDst","_getPipeline","_getVideoPipeline","MipMap","InvertYPremultiplyAlpha","Clear","InvertYPremultiplyAlphaWithOfst","ResolveDepth","pipelineAndBGL","modules","pureMode","vertexModule","createShaderModule","fragmentModule","layout","topology","stripIndexFormat","getBindGroupLayout","DontInvertY","InvertY","setCommandEncoder","encoder","_commandEncoderForCreation","copyVideoToTexture","useOwnCommandEncoder","createCommandEncoder","webgpuHardwareTexture","loadOp","storeOp","passEncoder","beginRenderPass","renderPassDescriptor","bindGroupLayout","importExternalTexture","bindGroup","setPipeline","setBindGroup","useRect","rectWidth","gpuTexture","gpuOrHdwTexture","setRawData","ofstX","ofstY","rectHeight","_copyInvertYRenderPassDescr","_copyInvertYBindGroupWithOfst","_copyInvertYBindGroup","createBindGroup","copyTextureToTexture","depthOrArrayLayers","hasMipmaps","additionalUsages","GetSample","renderAttachmentFlag","isCompressedFormat","IsCompressedFormat","maxNumMipLevels","effectiveMipLevelCount","usages","updateTexture","imageBitmaps","updateCubeTextures","_mipmapGenRenderPassDescr","_mipmapGenBindGroup","createGPUTextureForInternalTexture","gpuTextureWrapper","isStorageTexture","GetWebGPUTextureFormat","resolveMSAADepthTexture","msaaTexture","blockInformation","GetBlockInformationFromFormat","textureCopyView","textureExtent","bytesPerRow","MapWrite","CopySrc","getMappedRange","unmap","copyBufferToTexture","rowsPerImage","queue","submit","finish","releaseBuffer","writeTexture","dontUseRect","invertYPreMultiplyAlpha","copyExternalImageToTexture","flipY","updateMipLevelCountForInternalTexture","bytesPerRowAligned","gpuBuffer","createRawBuffer","MapRead","copyTextureToBuffer","readDataFromBuffer","GetTextureTypeFromFormat","destroyDeferredTextures","StatePosition","alphaBlendEquationToIndex","stencilOpToIndex","colorStates","WebGPUCacheRenderPipeline","emptyVertexBuffer","_depthBiasClamp","mrtTextureCount","_states","VertexState","maxVertexAttributes","_statesLength","_stateDirtyLowestIndex","_emptyVertexBuffer","_mrtFormats","_parameter","_kMaxVertexBufferStride","maxVertexBufferArrayStride","resetDepthCullingState","setClampDepth","_webgpuColorFormat","setColorFormat","setMRT","setAlphaBlendEnabled","setAlphaBlendFactors","setWriteMask","setDepthStencilFormat","setStencilEnabled","resetStencilState","setBuffers","_setTextureState","colorFormats","_mrtAttachments","_lookupRenderPipeline","textureState","_setShaderStage","_setRasterizationState","_setColorStates","_setDepthStencilState","_setVertexState","lastStateDirtyLowestIndex","NumCacheHitWithoutHash","_getRenderPipeline","NumCacheHitWithHash","getRenderPipeline","_GetTopology","_createRenderPipeline","NumCacheMiss","_NumPipelineCreationCurrentFrame","_setRenderPipeline","NumPipelineCreationLastFrame","_alphaToCoverageEnabled","setFrontFace","setCullEnabled","_cullEnabled","setCullFace","clampDepth","_clampDepth","setDepthCullingState","cullEnabled","depthTestEnabled","depthWriteEnabled","depthCompare","_depthWriteEnabled","_depthCompare","setDepthBiasSlopeScale","setDepthBias","depthBias","_depthBias","DepthBias","depthBiasSlopeScale","_depthBiasSlopeScale","DepthBiasSlopeScale","_colorFormat","setMRTAttachments","mrtAttachments","_mrtEnabledMask","MRTAttachments","mrtTextureArray","gpuWrapper","numAlphaBlendTargetsEnabled","_alphaBlendEnabled","_numAlphaBlendTargetsEnabled","factors","operations","_alphaBlendFuncParams","_alphaBlendEqParams","_writeMask","_webgpuDepthStencilFormat","_depthStencilFormat","setDepthTestEnabled","setDepthWriteEnabled","_stencilEnabled","_stencilFrontCompare","setStencilDepthFailOp","_stencilFrontDepthFailOp","setStencilPassOp","_stencilFrontPassOp","setStencilFailOp","_stencilFrontFailOp","_stencilBackCompare","setStencilBackDepthFailOp","_stencilBackDepthFailOp","setStencilBackPassOp","_stencilBackPassOp","setStencilBackFailOp","_stencilBackFailOp","setStencilReadMask","_stencilReadMask","StencilReadMask","setStencilWriteMask","_stencilWriteMask","StencilWriteMask","setStencilState","stencilEnabled","compare","depthFailOp","passOp","failOp","readMask","writeMask","backCompare","backDepthFailOp","backPassOp","backFailOp","_overrideVertexBuffers","compareFunction","_GetVertexInputDescriptorFormat","srcFactor","_GetAphaBlendFactor","dstFactor","_GetAphaBlendOperation","_getColorBlendState","_shaderId","rasterizationState","_rasterizationState","RasterizationState","colorStateIndex","index0","index1","index3","indexEq0","indexEq1","eq0","eq1","alphaBlendFactorToIndex","ColorStates1","depthStencilState","_depthStencilState","DepthStencilState","currStateLen","newNumStates","webgpuPipelineContext","attributeNamesFromEffect","locations","attributeLocationsFromEffect","currentGPUBuffer","numVertexBuffers","LogErrorIfNoVertexBuffer","_validOffsetRange","formatSize","canMergeWithCurrentBuffer","_CanMergeVertexBuffer","vid","descriptorOffset","offsetState","_textureState","TextureStage","_createPipelineLayout","_createPipelineLayoutWithTextureStage","bindGroupLayouts","bindGroupLayoutEntries","setDefinition","createBindGroupLayout","createPipelineLayout","bitVal","bindGroupLayoutEntryInfo","textureInfo","availableTextures","samplerInfo","autoBindSampler","availableSamplers","sampleType","samplerType","groupIndex","bindingIndex","descriptors","currentGPUAttributes","invalidOffsetRange","vertexBufferDescriptor","arrayStride","stepMode","shaderLocation","inputStateDescriptor","_getVertexInputDescriptor","pipelineLayout","descr","_getAphaBlendState","colorBlend","isIntegerFormat","stencilFront","_GetCompareFunction","_GetStencilOpFunction","stencilBack","topologyIsTriangle","depthStencilFormatHasStencil","primitiveState","cullMode","stages","vertexStage","primitive","fragmentStage","multisample","depthStencil","stencilReadMask","stencilWriteMask","depthBiasClamp","createRenderPipeline","_buildRenderPipelineDescriptor","preWarmPipeline","capturedParam","_Registered$86","_cacheRenderPipeline","pipelineCache","pipelinePrototype","buildRenderPipelineDescriptor","alphaToCoverageEnabled","_Registered$85","ThinWebGPUEngine","computePipeline","_bindGroups","bindGroupEntriesExist","_bindGroupEntries","_cacheSampler","getSampler","webgpuBuffer","cacheSampler","WebGPUComputeContext","_addUniformToLeftOverUBO","uniformType","preProcessors","_getArraySize","_webgpuProcessingContext","leftOverUniforms","WebGPUShaderProcessor","availableUBO","availableBuffers","getNextFreeUBOBinding","_addBufferBindingDescription","_generateLeftOverUBOCode","nameInArrayOfTexture","storageTexture","bufferNames","_preCreateBindGroupEntries","bindGroupEntries","storageTextureAccess","multisampled","isTextureArray","isVertex","uniformBufferInfo","bufferType","LeftOvertUBOName","InternalsUBOName","float","ivec2","uvec2","ivec3","uvec3","vec4","ivec4","uvec4","mat3","i32","u32","f32","mat2x2","mat3x3","mat4x4","mat2x2f","mat3x3f","mat4x4f","vec2i","vec3i","vec4i","vec2u","vec3u","vec4u","vec2f","vec3f","vec4f","vec2h","vec3h","vec4h","_SamplerFunctionByWebGLSamplerType","sampler2D","sampler2DArray","sampler2DShadow","sampler2DArrayShadow","samplerCube","sampler3D","_TextureTypeByWebGLSamplerType","samplerCubeArray","_GpuTextureViewDimensionByWebGPUTextureType","textureCube","textureCubeArray","texture2D","texture2DArray","texture3D","_SamplerTypeByWebGLSamplerType","_IsComparisonSamplerByWebGPUSamplerType","samplerShadow","samplerArrayShadow","_leftOverUniformsByName","foundSamplers","leftOverUniform","UniformSizes","WebGPUShaderProcessingContext","KnownUBOs","_SimplifiedKnownBindings","_SimplifiedKnownUBOs","_KnownUBOs","_attributeNextLocation","_varyingNextLocation","freeGroupIndex","freeBindingIndex","availableVaryings","availableAttributes","orderedAttributes","_findStartingGroupBinding","knownUBOs","TypeToLocationSize","arrayLength","_getNextFreeBinding","bindingCount","Light0","Light1","Light2","Light3","Light4","Light5","Light6","Light7","Light8","Light9","Light10","Light11","Light12","Light13","Light14","Light15","Light16","Light17","Light18","Light19","Light20","Light21","Light22","Light23","Light24","Light25","Light26","Light27","Light28","Light29","Light30","Light31","Internals","_missingVaryings","_textureArrayProcessing","_vertexIsGLES3","_fragmentIsGLES3","startArray","endArray","lengthInString","ubDeclaration","alreadyInjected","_preProcessors","interpolationQualifier","varyingType","isComparisonSampler","samplerBindingType","samplerName","samplerGroupIndex","samplerBindingIndex","samplerFunction","layouts","textureSetIndex","textureBindingIndex","_addSamplerBindingDescription","_addTextureBindingDescription","textureDimension","knownUBO","hasFragCoord","injectCode","fragCoordCode","iindex","uniformBufferDescription","_applyTextureArrayProcessing","decl","leftOverUBO","_buildLeftOverUBO","_collectBindingNames","gpuTextureViewDimensionByWebGPUTextureFunction","texture_1d","texture_2d","texture_2d_array","texture_3d","texture_cube","texture_cube_array","texture_multisampled_2d","texture_depth_2d","texture_depth_2d_array","texture_depth_cube","texture_depth_cube_array","texture_depth_multisampled_2d","texture_storage_1d","texture_storage_2d","texture_storage_2d_array","texture_storage_3d","texture_external","_attributesInputWGSL","_attributesWGSL","_attributesConversionCodeWGSL","_hasNonFloatAttribute","_varyingsWGSL","_varyingNamesWGSL","_stridedUniformArrays","interpolationType","interpolationSampling","isArrayOfTexture","textureFunc","storageTextureFormat","commaIndex","defineList","_convertDefinesToConst","_processSamplers","_processCustomBuffers","_processStridedUniformArrays","vertexInputs","vertexOutputs","vertexMainStartingCode","vertexMainEndingCode","needDiagnosticOff","fragmentInputs","mainBodyStart","scanCode","expr","rhs","detectIntVec","declScope","typed","inited","regexRoot","indexLocation","fragmentOutputs","fragDataOutputType","hasFragDepth","saveIndex","builtInName_frag_depth","fragmentStartingCode","stridedArrays","stridedArrayType","samplerRegexp","suffixLessLength","insertPart","lastIndex","instantiateBufferRegexp","decoration","structName","bufferInfo","uniformArrayName","engineId","WebGPUBufferManager","_IsGPUBuffer","_FlagsToString","_deferredReleaseBuffers","viewOrSize","mappedAtCreation","alignedLength","verticesBufferDescriptor","labelId","setSubData","dstByteOffset","srcByteOffset","startPre","originalByteLength","tmpBuffer","destArray","srcData","destroyBuffer","floatFormat","mapAsync","copyArrayBuffer","_getHalfFloatAsFloatRGBAArrayBuffer","offset2","destroyDeferredBuffers","FilterToBits","ComparisonFunctionToBits","WebGPUCacheSampler","anisotropy","_GetSamplerFilterDescriptor","mipmapFilter","lodMinClamp","lodMaxClamp","anisotropyEnabled","_GetSamplerWrappingDescriptor","_GetWrappingMode","filterDescriptor","GetCompareFunction","bypassCache","_GetSamplerDescriptor","GetSamplerHashCode","gpuSampler","childCountNodes","childCoundPipeline","countNode","countPipeline","WebGPUCacheRenderPipelineTree","GetNodeCounts","counts","_Cache","nodeCount","pipelineCount","_GetPipelines","pipelines","curPath","curPathLen","nnode","GetPipelines","NodeState","_nodeStack","WebGPUStencilStateComposer","setStencilCompare","setStencilBackCompare","WebGPUDepthCullingState","setDepthCompare","ExternalTexture","IsExternalTexture","_video","HAVE_CURRENT_DATA","WebGPUMaterialContext","_numExternalTextures","hasFloatOrDepthTextures","_numFloatOrDepthTextures","updateId","samplerCache","currentHashCode","textureCache","currentTextureId","isFloatOrDepthTexture","isExternalTexture","WebGPUDrawContext","materialContextUpdateId","_materialContextUpdateId","resetIsDirty","enableIndirectDraw","_enableIndirectDraw","_enableIndirectDrawInCompatMode","_useInstancing","indirectDrawBuffer","Indirect","Storage","_indirectDrawData","use","_currentInstanceCount","enableIndirectDrawInCompatMode","_dummyIndexBuffer","_vertexPullingEnabled","fastBundle","bindGroups","indexOrVertexCount","firstIndexOrVertex","effectiveBuffer","setBuffer","_releaseOwnerSlot","TextureIdStart","WebGPUCacheBindGroups","Statistics","totalCreated","NumBindGroupsCreatedTotal","lastFrameCreated","NumBindGroupsCreatedLastFrame","lookupLastFrame","NumBindGroupsLookupLastFrame","noLookupLastFrame","NumBindGroupsNoLookupLastFrame","WebGPUBindGroupCacheNode","_NumBindGroupsCreatedCurrentFrame","_NumBindGroupsLookupCurrentFrame","_NumBindGroupsNoLookupCurrentFrame","cacheIsDisabled","forceBindGroupCreation","nextNode","uboId","samplerHashCode","textureId","entryInfo","bindingInfo","dbgSanityChecks","groupLayout","viewsForTexture","WebGPUCacheTextureView","_GetKey","swizzle","WebGPUClearQuad","_depthTextureFormat","_bundleCache","_keyTemp","clearQuad_vertex","clearQuad_fragment","renderPass2","bundleKey","bundle","renderPass","depthStencilFormatIndex","isRTTPass","createRenderBundleEncoder","depthStencilFormat","_clearReverseDepthValue","_clearDepthValue","bufferInternals","_ubInvertY","_ubDontInvertY","bufferLeftOver","WebGPURenderItemViewport","WebGPURenderItemScissor","setScissorRect","WebGPURenderItemStencilRef","setStencilReference","WebGPURenderItemBlendColor","setBlendConstant","WebGPURenderItemBeginOcclusionQuery","WebGPURenderItemEndOcclusionQuery","bundles","executeBundles","cloned","WebGPURenderItemBundles","isEmpty","_listLength","_bundleEncoder","_list","addBundle","_currentItemIsBundle","_currentBundleList","_finishBundle","getBundleEncoder","WebGPUBundleList","WebGPUQuerySet","querySet","_querySet","canUseMultipleBuffers","_dstBuffers","_canUseMultipleBuffers","createQuerySet","_queryBuffer","QueryResolve","_getBuffer","firstQuery","queryCount","encoderResult","resolveQuerySet","readValues","arrayBuf","BigUint64Array","readValue","readTwoValuesAndSubtract","WebGPUTimestampQuery","gpuFrameTimeCounter","_gpuFrameTimeCounter","_measureDurationState","_measureDuration","WebGPUDurationMeasure","startPass","timestampWrites","gpuPerfCounter","stopPass","duration_","querySetLabel","writeTimestamp","beginningOfPassWriteIndex","endOfPassWriteIndex","WebGPUOcclusionQuery","hasQueries","_currentTotalIndices","_availableIndices","_queryFrameId","_getCurrentRenderPassWrapper","occlusionQuerySet","canBegin","startCount","incrementCount","_frameQuerySetIsDirty","_frameLastBuffer","_countIncrement","_allocateNewIndices","_retrieveQueryBuffer","_lastBuffer","numIndices","_delayQuerySetDispose","WebGPUTintWASM","_Twgsl","twgslOptions","_TwgslDefaultOptions","twgsl","jsPath","wasmPath","LoadBabylonScriptAsync","convertSpirV2WGSL","disableUniformityAnalysis","ccode","DisableUniformityAnalysis","ShowWGSLShaderCode","renderingMode","bundleList","_record","_playBundleListIndex","_allBundleLists","_recordingInvalidated","_skipNextRenderPass","showDebugLogs","record","_log","_modeSaved","handleRenderPassRestart","WebGPUExternalTexture","ViewDescriptorSwapChainAntialiasing","ViewDescriptorSwapChain","TempColor4","TempColor4SignedInteger","WebGPUEngine","disableCacheSamplers","disableCacheRenderPipelines","disableCacheBindGroups","_cacheBindGroups","gpu","supportedExtensions","_adapterSupportedExtensions","_deviceEnabledExtensions","supportedLimits","_adapterSupportedLimits","currentLimits","_deviceLimits","_adapterInfo","architecture","currentSampleCount","_mainPassSampleCount","CreateAsync","glslangOptions","_uploadEncoderDescriptor","_clearStencilValue","_defaultSampleCount","_glslang","_tintWASM","_glslangAndTintAreFullyLoaded","subgroupMinSize","subgroupMaxSize","isFallbackAdapter","_counters","numEnableEffects","numEnableDrawWrapper","numBundleCreationNonCompatMode","numBundleReuseNonCompatMode","countersLastFrame","numMaxUncapturedErrors","_mainRenderPassWrapper","colorAttachmentViewDescriptor","colorAttachmentDepthSlice","depthAttachmentViewDescriptor","colorAttachmentGPUTextures","_rttRenderPassWrapper","_currentVertexBuffers","_currentOverrideVertexBuffers","_currentIndexBuffer","_colorWriteLocal","_forceEnableEffect","_internalFrameCounter","_useOwnerKeyedUniformBufferSlots","_viewportsCurrent","_scissorsCurrent","_scissorCached","_stencilRefsCurrent","_blendColorsCurrent","deviceDescriptor","enableGPUDebugMarkers","swapChainFormat","getPreferredCanvasFormat","WebGPUShaderProcessorGLSL","_shaderProcessorWGSL","WebGPUShaderProcessorWGSL","prepareGlslangAndTintAsync","_workingGlslangAndTintPromise","glslang","initTwgsl","_twgslOptions","_InstanceId","_glslangOptions","_adapter","adapter","enableAllFeatures","requestedExtensions","validExtensions","setMaximumLimits","requiredLimits","requestDevice","numUncapturedErrors","lost","_initializeLimits","_cacheTextureViews","WebGPUSnapshotRendering","_snapshotRenderingMode","WebGPUConstants.BufferUsage","frameCounter","_renderEncoderDescriptor","_uploadEncoder","_clearQuad","_defaultDrawContext","_defaultMaterialContext","_currentMaterialContext","_initializeContextAndSwapChain","_initializeMainAttachments","_initGlslangAsync","_GlslangDefaultOptions","textureFormatsTier1","maxSampledTexturesPerShaderStage","maxTextureDimension2D","maxInterStageShaderVariables","maxUniformBufferBindingSize","maxTextureArrayLayers","wgslLanguageFeatures","_configureContext","_setColorFormat","bufferDataUpdate","mainColorAttachments","mainTextureDescriptor","_mainTextureExtends","_mainTexture","_setDepthTextureFormat","_depthTexture","depthTextureDescriptor","depthClearValue","depthLoadOp","depthStoreOp","stencilLoadOp","stencilStoreOp","depthStencilAttachment","mainDepthAttachment","_startMainRenderPass","configure","storageBuffer","cleanScenes","uboList","_occlusionQueryActive","_startRenderTargetRenderPass","_mustUpdateViewport","_applyViewport","addItem","_getCurrentRenderPass","_mustUpdateScissor","_applyScissor","_scissorIsActive","_mustUpdateBlendColor","hasScissor","_clearFullQuad","_applyStencilRef","Vertex","Index","_createBuffer","compileGLSL","_compileRawShaderToSpirV","disableUniformityAnalysisInVertex","disableUniformityAnalysisInFragment","_compileRawPipelineStageDescriptor","_createPipelineStageDescriptor","_compilePipelineStageDescriptor","_compileShaderToSpirV","_getWGSLShader","WebGPUPipelineContext","webGpuContext","dbgShowShaderCode","rawVertex","rawFragment","gpuPipelineContext","dbgShowEmptyEnableEffectCalls","dbgLogIfNotDrawWrapper","webGPUPipelineContext","delayGPUTextureCreation","wrapWebGLTexture","updateWrappedWebGLTexture","updateTextureWrappingMode","_setInternalTexture","availableTexture","setSampler","unused","bitmap","gpuTextureFormat","_commandBuffers","_fromEndFrame","_debugPushAfterStartOfEncoder","useMSAA","gpuDepthStencilWrapper","depthStencilView","getMSAATexture","gpuMSAATexture","gpuDepthStencilTexture","getView","depthTextureHasStencil","depthTextureHasDepth","HasDepthAspect","clearColorForIntegerRt","clearColorForSignedIntegerRt","mustClearColor","setClearStates","mustClearDepth","_defaultAttachments","mrtTexture","gpuMRTWrapper","gpuMRTTexture","depthSlice","getBaseArrayLayer","viewDescriptor","msaaViewDescriptor","isRtInteger","isRtUnsignedInteger","colorTextureView","colorMSAATextureView","resolveTarget","mustClearStencil","_resetRenderPassStates","swapChainTexture","getCurrentTexture","saveCrt","resolveColors","unbindOnly","invertYRenderTarget","_disableEngineYFlip","_applyRenderPassChanges","mustUpdateStencilRef","mustUpdateBlendColor","_applyBlendColor","setVertexPulling","_updateOwnerKeyed","setIndirectData","textureIsDepth","getBindGroups","setVertexBuffer","nonCompatMode","drawType","drawIndexedIndirect","drawIndirect","drawIndexed","createRenderPipelineAsync","colorFormat","prevAlphaMode","depthWrite","createExternalTexture","clearBuffer","readFromBuffer","copyBufferToBuffer","_readFromGPUBuffer","_Registered$84","declarationPattern","bindingPattern","groupPattern","_GetInternalTexture","computeToken","_compiledComputeEffects","WebGPUComputePipelineContext","_computeDispatch","contextPipeline","computeContext","explicitLayout","existingIndex","_GetComputeTextureSampleType","_GetComputeTextureViewDimension","_GetComputeStorageBufferType","_GetComputePipelineLayout","createComputePipeline","stage","ComputePassDescriptor","beginComputePass","computePass","dispatchWorkgroupsIndirect","dispatchWorkgroups","webGPUPipelineContextCompute","rawCompute","_createComputePipelineStageDescriptor","getCompilationInfo","compilationMessages","lineNum","column","linePos","_Registered$83","_Registered$82","debugCommands","insertDebugMarker","_Registered$81","_Registered$80","defaultAttachments","mipmapsCreationOnly","creationFlag","_Registered$7$","_Registered$7_","mipWidth","mipHeight","allFaces","_Registered$7Z","WebGPURenderTargetWrapper","_Registered$7Y","GetTypeForDepthTexture","_Registered$7X","_Registered$7W","_Registered$7V","_Registered$7U","name$9N","shader$9N","name$9M","shader$9M","name$9L","shader$9L","name$9K","shader$9K","name$9J","shader$9J","name$9I","shader$9I","name$9H","shader$9H","NativeEngine","_adaptToDeviceRatio","_Registered$7T","derivedCtor","baseCtor","getOwnPropertyNames","EngineFactory","ClipboardEventTypes","COPY","CUT","PASTE","ClipboardInfo","GetTypeFromCharacter","FlowGraphInteger","_toInt","imul","ClassName","FromValue","_Registered$7S","FlowGraphMatrix2D","transformVectorToRef","otherMatrix","thisMatrix","inverse","invDet","FlowGraphMatrix3D","_DefaultEventDataParseCounts","IsVectorClassName","serializedReference","classMatches","candidates","IsMatrixClassName","intermediateValue","GetSceneNodeFromSerializedReference","flipHandedness","ParseVector","ags","ag","_GetDefaultEventDataParseCount","FlowGraphAssetType","FlowGraphAction","useIndexAsUniqueId","assetsContext","logToConsole","payload","getItemsOfType","enableLogging","_enableLogging","logger","FlowGraphLogger","_userVariables","_variableTypes","_executionVariables","_globalContextVariables","_connectionValues","_pendingBlocks","_executionId","onNodeExecutedObservable","onBreakpointHitObservable","breakpointPredicate","_pendingActivation","_stepMode","_skipBreakpointForBlockId","treatDataAsRightHanded","_configuration","hasVariable","addLogItem","GetFlowGraphAssetWithType","userVariables","setVariableType","getVariableType","variableTypes","_getEventReference","hostResolver","decodeIndexReference","collection","getObjectReference","hint","_getUniqueIdPrefixedName","defaultValue","possibleValue","_hasGlobalContextVariable","_setExecutionVariable","_hasExecutionVariable","_deleteExecutionVariable","_hasConnectionValue","connectionPoint","connectionPointId","_setConnectionValueByKey","hasPendingBlocks","_cancelPendingTasks","_setGlobalContextVariable","framePayload","timeSinceStart","_executeOnTick","executionId","pendingActivation","continueExecution","pending","stepExecution","_clearPendingActivation","valueSerializationFunction","_assetsContext","FlowGraphConnectionType","FlowGraphConnection","_ownerBlock","_connectedPoint","connectedPointIds","_connectionType","connectionType","_isSingularConnection","removeFromLocal","indexLocal","indexConnected","disconnectFromAll","disconnectFrom","deserialize","FlowGraphDataConnection","ownerBlock","richType","_defaultValue","_optional","_lastValue","dataTransformer","onValueChangedObservable","optional","isDisabled","_getConnectionValue","_setConnectionValue","_reresolveDefaultValueForScene","connectTo","_notifyExecuteNode","_updateOutputs","_getValueOrDefault","typeTransformer","getValue","defaultValueSerializationFunction","_Registered$7R","FlowGraphBlock","dataInputs","dataOutputs","registerDataInput","registerDataOutput","getDataInput","getDataOutput","_valueSerializeFunction","serializedInput","serializedOutput","_lastActivationTime","_shouldBreak","_increaseExecutionId","_execute","_lastExecutionTime","connectedPoint","_activateSignal","_Registered$7Q","FlowGraphSignalConnection","FlowGraphExecutionBlock","signalInputs","signalOutputs","in","_registerSignalOutput","_registerSignalInput","_unregisterSignalInput","_unregisterSignalOutput","getSignalInput","getSignalOutput","signalInput","signalOutput","FlowGraphExecutionBlockWithOutSignal","FlowGraphAsyncExecutionBlock","_eventsSignalOutputs","eventName","_getExecutionVariable","_resetAfterCanceled","_preparePendingTasks","_addPendingBlock","_removePendingBlock","_IsMacPlatform","platform","_IsDescendantOf","mesh1","mesh2","_GetClassNameOf","_AreSameVectorOrQuaternionClass","className2","isNumeric","validIfNaN","getNumericValue","FlowGraphSceneEventCoordinator","onEventTriggeredObservable","sceneReadyTriggered","_pointerUnderMeshState","_onBlurHandler","pressedKeys","_startingTime","_sceneReadyObserver","_sceneOnBeforeRenderObserver","_meshPickedObserver","_pointerDownObserver","_pointerUpObserver","_pointerMoveObserver","previousState","over","keyboardInfo","stillHeld","_COMMAND_OR_CTRL_CODES","_meshUnderPointerObserver","_keyDownObserver","_keyUpObserver","FlowGraphEventBlock","initPriority","filtered","eventKey","FlowGraphValidationSeverity","NumericLikeTypes","VectorLikeTypes","ColorLikeTypes","_AreTypesCompatible","sourceType","issues","issuesByBlock","addIssue","issue","flowGraph","visitAllBlocks","allBlocks","eventBlocks","_eventBlocks","_GetEventBlocks","severity","connectionName","_IsEventBlock","inSignal","srcType","tgtType","reachableIds","blockMap","reportedCycleBlocks","dfs","connected","dep","depColor","errorCount","warningCount","allKnownBlocks","dataIssue","signalIssue","FlowGraphState","FlowGraphTypes","FLOWGRAPHEDITOR","FlowGraphEditor","_coordinator","sceneEventCoordinator","_sceneEventCoordinator","_BJSFLOWGRAPHEDITOR","_getGlobalFlowGraphEditor","SceneReady","SceneDispose","SceneBeforeRender","MeshPick","PointerDown","PointerUp","PointerMove","PointerOver","PointerOut","KeyDown","KeyUp","SceneAfterRender","NoTrigger","_allBlocks","_executionContexts","_attachEventObserver","_eventObserver","propagationStops","_getContextualOrder","eventBlock","stoppedTarget","shouldContinue","_beginEventDispatch","eventState","_executeEvent","_endEventDispatch","propagationStopped","_notifyOnTick","_detachEventObserver","FlowGraphContext","contextCount","removeContext","_clearPendingBlocks","addBlock","eIdx","signalIn","signalOut","addEventBlock","_startPendingTasks","createContext","_startPendingEvents","meshPickOrder","block1","_getReferencedMesh","block2","visitor","idsAddedToVisitList","dataIn","connection","ValidateFlowGraphWithBlockList","valueSerializeFunction","seen","serializeBlock","serializedBlock","executionContexts","serializedContext","editorUrl","flowGraphEditorConfig","_createFlowGraphEditor","additionalConfig","attachToLiveScene","editorConfig","RichType","RichTypeAny","RichTypeString","RichTypeNumber","RichTypeBoolean","RichTypeVector2","RichTypeVector3","RichTypeVector4","RichTypeMatrix","RichTypeMatrix2D","RichTypeMatrix3D","RichTypeColor3","RichTypeColor4","RichTypeQuaternion","RichTypeFlowGraphInteger","getRichTypeFromValue","anyValue","flowGraphType","_Registered$7P","FlowGraphDefaultEventReferencePrefix","GetDefaultEventReference","FlowGraphCoordinator","OnFlowGraphAddedObservable","_OnFlowGraphAddedObservable","OnFlowGraphRemovedObservable","_OnFlowGraphRemovedObservable","dispatchEventsSynchronously","_flowGraphs","_customEventsMap","_eventExecutionCounter","_executeOnNextFrame","_eventUniqueId","_eventDispatchStack","_attachToScene","_disposeObserver","executeOnNextFrame","coordinators","SceneCoordinators","_detachFromScene","_setScene","updateGraphs","previousScene","graph","graphName","FlowGraph","serializedGraph","flowGraphs","async","MaxEventTypeExecutionPerFrame","eventId","decodeEventReference","GetDefaultEventReferenceKey","stopImmediate","encode","encodeEventReference","MaxEventsPerType","CustomBlocks","ShortNameToFullKey","addToBlockFactory","fullKey","_IsFlowGraphBlockConstructor","modulePromise","exportName","animationGroup_pure","RegisterAnimationGroup","_LoadBlock","flowGraphPlayAnimationBlock_pure","flowGraphStopAnimationBlock_pure","flowGraphPauseAnimationBlock_pure","flowGraphInterpolationBlock_pure","flowGraphSceneReadyEventBlock_pure","flowGraphSceneTickEventBlock_pure","flowGraphSendCustomEventBlock_pure","flowGraphReceiveCustomEventBlock_pure","flowGraphStopEventPropagationBlock_pure","flowGraphMeshPickEventBlock_pure","flowGraphMathBlocks_pure","flowGraphVectorMathBlocks_pure","flowGraphMatrixMathBlocks_pure","flowGraphBranchBlock_pure","flowGraphSetDelayBlock_pure","flowGraphCancelDelayBlock_pure","flowGraphCounterBlock_pure","flowGraphDebounceBlock_pure","flowGraphThrottleBlock_pure","flowGraphDoNBlock_pure","flowGraphFlipFlopBlock_pure","flowGraphForLoopBlock_pure","flowGraphMultiGateBlock_pure","flowGraphSequenceBlock_pure","flowGraphSwitchBlock_pure","flowGraphWaitAllBlock_pure","flowGraphWhileLoopBlock_pure","flowGraphConsoleLogBlock_pure","flowGraphConditionalDataBlock_pure","flowGraphConstantBlock_pure","flowGraphTransformCoordinatesSystemBlock_pure","flowGraphGetAssetBlock_pure","flowGraphGetPropertyBlock_pure","flowGraphSetPropertyBlock_pure","flowGraphGetVariableBlock_pure","flowGraphSetVariableBlock_pure","flowGraphJsonPointerParserBlock_pure","flowGraphMathCombineExtractBlocks_pure","flowGraphTypeToTypeBlocks_pure","flowGraphEasingBlock_pure","flowGraphBezierCurveEasingBlock_pure","flowGraphPointerOverEventBlock_pure","flowGraphPointerOutEventBlock_pure","flowGraphPointerDownEventBlock_pure","flowGraphPointerUpEventBlock_pure","flowGraphKeyDownEventBlock_pure","flowGraphKeyUpEventBlock_pure","flowGraphIsKeyPressedBlock_pure","flowGraphContextBlock_pure","flowGraphArrayIndexBlock_pure","flowGraphCodeExecutionBlock","FlowGraphCodeExecutionBlock","flowGraphIndexOfBlock_pure","flowGraphFunctionReferenceBlock_pure","flowGraphDataSwitchBlock_pure","flowGraphPhysicsCollisionEventBlock_pure","flowGraphApplyForceBlock_pure","flowGraphApplyImpulseBlock_pure","flowGraphSetLinearVelocityBlock_pure","flowGraphSetAngularVelocityBlock_pure","flowGraphSetPhysicsMotionTypeBlock_pure","flowGraphGetLinearVelocityBlock_pure","flowGraphGetAngularVelocityBlock_pure","flowGraphPlaySoundBlock_pure","flowGraphStopSoundBlock_pure","flowGraphPauseSoundBlock_pure","flowGraphSetSoundVolumeBlock_pure","flowGraphSoundEndedEventBlock_pure","flowGraphGetSoundVolumeBlock_pure","flowGraphIsSoundPlayingBlock_pure","serializedEventData","serializedEntry","getRichTypeByFlowGraphType","valueParseFunction","assetsContainer","flowGraphPayload","ApplyCoordinatorSerializationSettings","serializedObject","_defaultValues","GetDataOutConnectionByUniqueId","dataOut","GetSignalInConnectionByUniqueId","defaultValueParseFunction","ParseFlowGraphAsync","pathConverter","GetSerializedFlowGraphFromSnippetAsync","ParseCoordinatorAsync","parsedGraphs","activeGraphIndex","resolvedClasses","classFactory","blockFactory","ParseFlowGraph","dataInMap","dataOutMap","signalInMap","signalOutMap","connectIfNeeded","connectedConnection","serializedConnection","ParseFlowGraphContext","rightHanded","ac","anim","ps","classType","ParseFlowGraphBlockWithClassType","parseOptions","parsedConfig","customValueParseFunction","defaultParseCount","customParsedEventData","delegatedToDefault","ParseCustomEventData","needsPathConverter","dataInput","dataOutput","ParseGraphConnectionWithClassType","ParseGraphDataConnection","ParseRichType","_separator","currentObject","getVariable","getPropertyName","FlowGraphPathConverterComponent","templateInfos","templateSet","collect","conn","templatedInputs","getAccessor","placeholder","substitution","ResolveTemplateSubstitution","finalPath","convert","template","AssertNonNegativeInt","ExtractRefSubstitution","placeholders","segment","GetPlaceholderIndex","placeholderIndex","GetPlaceholderParentSegment","refValue","templateSegments","refSegments","ActiveDelayIndicesKey","MarkDelayActive","_getGlobalContextVariable","GetActiveDelaySet","FlowGraphConsoleLogBlock","messageTemplate","_getTemplateMatches","typeValue","logType","messageValue","_getMessageValue","messageObj","replacements","_serializeValue","serialized","parameterStart","_Registered$7O","FlowGraphBranchBlock","onTrue","onFalse","_Registered$7N","FlowGraphDoNBlock","maxExecutions","executionCount","callingSignal","currentCountValue","_Registered$7M","FlowGraphForLoopBlock","initialIndex","executionFlow","completed","maxIterations","maxLoopIterations","MaxLoopIterations","truncated","incrementIndexWhenLoopDone","_Registered$7L","FlowGraphThrottleBlock","lastRemainingTime","durationValue","_reportError","durationInMs","remainingTime","_Registered$7K","FlowGraphMultiGateBlock","outputSignals","setNumberOfOutputSignals","outputSignalCount","isLoop","indexesUsed","isRandom","unusedIndexes","used","numberOutputSignals","flow","nextIndex","_getNextIndex","_Registered$7J","FlowGraphSwitchBlock","_caseToOutputFlow","caseValue","_callingSignal","selectionValue","case","outputFlow","_getOutputFlowForCase","newCase","cases","removeCase","caseToRemove","_Registered$7I","FlowGraphWaitAllBlock","inFlows","_cachedActivationState","inputSignalCount","_getCurrentActivationState","activationState","contextActivationState","remainingInputs","inputFlows","_Registered$7H","FlowGraphCallCounterBlock","countValue","_Registered$7G","FlowGraphWhileLoopBlock","conditionValue","doWhile","MaxLoopCount","_Registered$7F","FlowGraphDebounceBlock","currentCount","_Registered$7E","FlowGraphFlipFlopBlock","onOn","onOff","_Registered$7D","FlowGraphSequenceBlock","executionSignals","_Registered$7C","TimerState","observableParameters","contextObservable","timer","completeRate","breakCondition","onAborted","onEnded","onTick","AdvancedTimer","onEachCountObservable","onTimerAbortedObservable","onTimerEndedObservable","_breakOnNextTick","_timer","_startTime","_timeToEnd","shouldBreak","_breakCondition","_contextObservable","_observableParameters","clearObservables","timeToEnd","_tick","FlowGraphSetDelayBlock","cancel","lastDelayIndex","timers","_updateGlobalTimers","globalTimers","MarkDelayInactive","IsDelayActive","MaxParallelDelayCount","_Registered$7B","FlowGraphCancelDelayBlock","delayIndex","_Registered$7A","RemoveFlowGraphAnimationGroupObservers","observerSets","groupEnd","animationEnd","animationLoop","groupLoop","FlowGraphPlayAnimationBlock","currentAnimationGroup","_tryPreparePendingTasks","interpolationAnimationsArray","animationGroupToUse","isInterpolation","animationsArray","interpolationAnimations","interpolationTarget","rawTo","providedSpeed","easing","bezier","_checkInterpolationDuplications","currentlyRunningAnimationGroups","_stopAnimationGroup","_onAnimationGroupEnd","getCurrentFrame","_removeFromCurrentlyRunning","animToCheck","_cleanupAfterExternalStop","_Registered$7z","FlowGraphStopAnimationBlock","stopAtFrame","animationToStopValue","pendingStopAnimations","useVirtualStopAt","stopTime","activateDone","_stopAnimation","currentlyRunning","suppressAnimationEnd","virtualStopFrame","remainingIndex","_Registered$7y","FlowGraphPauseAnimationBlock","animationToPause","_Registered$7x","FlowGraphInterpolationBlock","keyFrames","getRichTypeByAnimationType","numberOfKeyFrames","keyFramesCount","initialValue","customBuildAnimation","_Registered$7w","EasingFunctionType","FlowGraphEasingBlock","_easingFunctions","CreateEasingFunction","_Registered$7v","InteractivityBezierCurveEase","fx0","fx1","fx2","lowerBound","upperBound","u2","derivative","newtonU","_SolveCssCubicBezier","FlowGraphBezierCurveEasingBlock","controlPoint1","controlPoint2","_Registered$7u","FlowGraphApplyForceBlock","forceVec","locationVec","_Registered$7t","FlowGraphApplyImpulseBlock","impulseVec","_Registered$7s","FlowGraphSetLinearVelocityBlock","_Registered$7r","FlowGraphSetAngularVelocityBlock","_Registered$7q","FlowGraphSetPhysicsMotionTypeBlock","motionType","setMotionType","_Registered$7p","FlowGraphPlaySoundBlock","soundValue","vol","loopVal","_Registered$7o","FlowGraphStopSoundBlock","_Registered$7n","FlowGraphPauseSoundBlock","_Registered$7m","FlowGraphSetSoundVolumeBlock","_Registered$7l","FlowGraphConditionalDataBlock","_Registered$7k","FlowGraphGetVariableBlock","variableNameValue","variable","_Registered$7j","FlowGraphSetVariableBlock","variables","_saveVariable","animationUniqueId","setVariable","_Registered$7i","FlowGraphTransformCoordinatesSystemBlock","sourceSystem","destinationSystem","inputCoordinates","outputCoordinates","sourceSystemValue","destinationSystemValue","destinationWorld","destinationWorldInverse","outputCoordinatesValue","inputCoordinatesValue","sourceToDestination","_Registered$7h","CacheExecIdName","CacheExecIdName$1","FlowGraphCachedOperationBlock","outputRichType","_outputRichType","_getInvalidOutputValue","cachedExecutionId","cachedValue","CacheName","_doOperation","calculatedValue","_setInvalid","FlowGraphGetPropertyBlock","customGetFunction","getter","_getPropertyValue","_Registered$7g","FlowGraphSetPropertyBlock","customSetFunction","_stopRunningAnimations","setFunction","_setPropertyValue","_Registered$7f","FlowGraphConstantBlock","_Registered$7e","FlowGraphGetAssetBlock","_Registered$7d","FlowGraphDataSwitchBlock","_inputCases","treatCasesAsIntegers","outputValue","_getOutputValueForCase","_Registered$7c","FlowGraphIsKeyPressedBlock","withShift","withCtrl","withAlt","withMeta","withCommandOrCtrl","isPressed","_Registered$7b","FlowGraphBinaryOperationBlock","leftRichType","rightRichType","resultRichType","_operation","_className","FlowGraphConstantOperationBlock","FlowGraphUnaryOperationBlock","inputRichType","FlowGraphTernaryOperationBlock","t1Type","t2Type","t3Type","FlowGraphAddBlock","_polymorphicAdd","aClassName","bClassName","preventIntegerFloatArithmetic","FlowGraphSubtractBlock","_polymorphicSubtract","FlowGraphMultiplyBlock","_polymorphicMultiply","aM","FlowGraphDivideBlock","_polymorphicDivide","aClone","FlowGraphRandomBlock","_random","seed","_seed","_getRandomValue","FlowGraphEBlock","E","FlowGraphPiBlock","FlowGraphTauBlock","FlowGraphInfBlock","FlowGraphNaNBlock","FlowGraphAbsBlock","_polymorphicAbs","ComponentWiseUnaryOperation","FlowGraphSignBlock","_polymorphicSign","FlowGraphTruncBlock","_polymorphicTrunc","trunc","FlowGraphFloorBlock","_polymorphicFloor","FlowGraphCeilBlock","_polymorphicCeiling","FlowGraphRoundBlock","_polymorphicRound","roundHalfAwayFromZero","FlowGraphFractionBlock","_polymorphicFraction","FlowGraphNegationBlock","_polymorphicNeg","FlowGraphModuloBlock","_polymorphicRemainder","ComponentWiseBinaryOperation","FlowGraphMinBlock","_polymorphicMin","FlowGraphMaxBlock","_polymorphicMax","FlowGraphClampBlock","_polymorphicClamp","ComponentWiseTernaryOperation","Saturate","FlowGraphSaturateBlock","_polymorphicSaturate","FlowGraphMathInterpolationBlock","_polymorphicInterpolate","FlowGraphMathSlerpBlock","FlowGraphMathSmoothStepBlock","_polymorphicSmoothStep","SmoothStep","FlowGraphEqualityBlock","_polymorphicEq","isFourComponent","_AreSameMatrixClass","_AreSameIntegerClass","ComparisonOperators","FlowGraphLessThanBlock","_polymorphicLessThan","FlowGraphLessThanOrEqualBlock","_polymorphicLessThanOrEqual","FlowGraphGreaterThanBlock","_polymorphicGreaterThan","FlowGraphGreaterThanOrEqualBlock","_polymorphicGreaterThanOrEqual","FlowGraphIsNanBlock","_polymorphicIsNan","FlowGraphIsInfinityBlock","_polymorphicIsInf","FlowGraphDegToRadBlock","_polymorphicDegToRad","_degToRad","FlowGraphRadToDegBlock","_polymorphicRadToDeg","_radToDeg","FlowGraphSinBlock","_polymorphicSin","FlowGraphCosBlock","_polymorphicCos","FlowGraphTanBlock","_polymorphicTan","FlowGraphAsinBlock","_polymorphicAsin","FlowGraphAcosBlock","_polymorphicAcos","FlowGraphAtanBlock","_polymorphicAtan","FlowGraphAtan2Block","_polymorphicAtan2","FlowGraphSinhBlock","_polymorphicSinh","sinh","FlowGraphCoshBlock","_polymorphicCosh","cosh","FlowGraphTanhBlock","_polymorphicTanh","tanh","FlowGraphAsinhBlock","_polymorphicAsinh","asinh","FlowGraphAcoshBlock","_polymorphicAcosh","acosh","FlowGraphAtanhBlock","_polymorphicAtanh","atanh","FlowGraphExpBlock","_polymorphicExp","FlowGraphLogBlock","_polymorphicLog","FlowGraphLog2Block","_polymorphicLog2","FlowGraphLog10Block","_polymorphicLog10","FlowGraphSquareRootBlock","_polymorphicSqrt","FlowGraphCubeRootBlock","_polymorphicCubeRoot","cbrt","FlowGraphPowerBlock","_polymorphicPow","FlowGraphBitwiseNotBlock","valueType","FlowGraphBitwiseAndBlock","FlowGraphBitwiseOrBlock","FlowGraphBitwiseXorBlock","FlowGraphBitwiseLeftShiftBlock","FlowGraphBitwiseRightShiftBlock","FlowGraphLeadingZerosBlock","clz32","FlowGraphTrailingZerosBlock","FlowGraphOneBitsCounterBlock","CountOnes","FlowGraphRGBToOkLChBlock","long","medium","lRoot","mRoot","sRoot","short","okA","hypot","okB","RgbToOkLch","FlowGraphRGBFromOkLChBlock","lPrime","mPrime","sPrime","OkLchToRgb","_Registered$7a","FlowGraphMathCombineBlock","FlowGraphMathExtractBlock","numberOfOutputs","FlowGraphCombineVector2Block","FlowGraphCombineVector3Block","FlowGraphCombineVector4Block","FlowGraphCombineMatrixBlock","FlowGraphCombineMatrix2DBlock","columnMajor","inputIsColumnMajor","FlowGraphCombineMatrix3DBlock","FlowGraphExtractVector2Block","FlowGraphExtractVector3Block","FlowGraphExtractVector4Block","FlowGraphExtractMatrixBlock","FlowGraphExtractMatrix2DBlock","FlowGraphExtractMatrix3DBlock","_Registered$79","FlowGraphTransposeBlock","matrixType","FlowGraphDeterminantBlock","FlowGraphInvertMatrixBlock","_matrixType","FlowGraphMatrixMultiplicationBlock","FlowGraphMatrixDecomposeBlock","cachedPosition","cachedRotation","cachedScaling","cachedIsValid","degenerateOutputs","keepComponents","scaleZ","areScalesFinite","isTranslationFinite","keepDegenerateComponents","normalizedDeterminant","outScaling","outRotation","outPosition","FlowGraphMatrixComposeBlock","cachedMatrix","_Registered$78","SlerpEpsilon","GetAnyPerpendicularVector","QuaternionEulerAngleOrders","AxisCacheName","AngleCacheName","FlowGraphLengthBlock","_polymorphicLength","FlowGraphNormalizeBlock","_polymorphicNormalize","nanVector","FlowGraphDotBlock","_polymorphicDot","FlowGraphCrossBlock","FlowGraphRotate2DBlock","FlowGraphRotate3DBlock","applyRotationQuaternion","transformVector","FlowGraphTransformBlock","vectorType","TransformVector","FlowGraphTransformCoordinatesBlock","FlowGraphConjugateBlock","FlowGraphAngleBetweenBlock","GetAngleBetweenQuaternions","q2","FlowGraphQuaternionFromAxisAngleBlock","FlowGraphAxisAngleFromQuaternionBlock","cachedAxis","cachedAngle","FlowGraphQuaternionFromDirectionsBlock","axisScale","GetQuaternionFromDirectionsToRef","GetQuaternionFromDirections","FlowGraphQuaternionFromUpForwardBlock","GetQuaternionFromUpForward","FlowGraphVectorSlerpBlock","_polymorphicSlerp","lengthA","lengthB","aHatX","aHatY","bHatX","bHatY","cosCTheta","sinCTheta","GetVector2Slerp","lerp","aHat","bHat","rotationAxis","GetVector3Slerp","FlowGraphQuaternionFromAnglesBlock","GetQuaternionFromEulerAngles","_order","_Registered$77","FlowGraphJsonPointerParserBlock","setterFunction","getterFunction","generateAnimationsFunction","_getInterpolationAnimationPropertyInfo","templateComponent","jsonPointer","accessorContainer","ToColor","_propertyName","FromColor","animationData","babylonAnimation","expectedValue","_Registered$76","FlowGraphBooleanToFloat","FlowGraphBooleanToInt","FlowGraphFloatToBoolean","FlowGraphIntToBoolean","FlowGraphIntToFloat","FlowGraphFloatToInt","roundingMode","_Registered$75","FlowGraphContextBlock","_Registered$74","FlowGraphArrayIndexBlock","rawIndex","decoded","referenceCollection","_Registered$73","executionFunction","FlowGraphIndexOfBlock","_Registered$72","FlowGraphFunctionReferenceBlock","contextValue","_Registered$71","FlowGraphGetLinearVelocityBlock","getLinearVelocityToRef","_Registered$70","FlowGraphGetAngularVelocityBlock","getAngularVelocityToRef","_Registered$6$","FlowGraphGetPhysicsMassPropertiesBlock","_Registered$6_","FlowGraphGetSoundVolumeBlock","_Registered$6Z","FlowGraphIsSoundPlayingBlock","_Registered$6Y","FlowGraphMeshPickEventBlock","vectorDefault","useNaNDefaults","pickOrigin","pointerIdDefault","pickedInfo","stopPropagation","resetToDefaultValue","_Registered$6X","EventKey$1","eventRef","getEventReference","_Registered$6W","FlowGraphSceneReadyEventBlock","GetFlowGraphCustomEventKey","encodeURIComponent","typeKey","incoming","_getEventDataDefault","eventObserver","getCustomEventObservable","_payload","_Registered$6V","FlowGraphReceiveCustomEventBlock","FlowGraphStopEventPropagationBlock","stopEventPropagation","_Registered$6U","FlowGraphSendCustomEventBlock","port","notifyCustomEvent","_Registered$6T","EventKey","_Registered$6S","FlowGraphSceneTickEventBlock","FlowGraphPointerOutEventBlock","meshOutOfPointer","_Registered$6R","FlowGraphPointerOverEventBlock","skipEvent","_Registered$6Q","FlowGraphPhysicsCollisionEventBlock","otherBody","setCollisionCallbackEnabled","getCollisionObservable","_onCollision","collidedAgainst","subscribedBody","_Registered$6P","FlowGraphSoundEndedEventBlock","subscribedSound","_Registered$6O","FlowGraphKeyboardEventBlock","keyValue","commandOrCtrl","filterKey","FlowGraphKeyDownEventBlock","isRepeat","repeat","ignoreRepeat","_Registered$6N","FlowGraphKeyUpEventBlock","_Registered$6M","FlowGraphBlockNames","NodeRenderGraphBlockConnectionPointTypes","NodeRenderGraphConnectionPointCompatibilityStates","NodeRenderGraphConnectionPointDirection","_direction","IsTextureHandle","IsShadowGenerator","mapSize","IsShadowLight","setShadowProjectionMatrix","_type","AutoDetect","isInput","_linkedConnectionSource","_defaultConnectionPointType","BasedOnInput","typeConnectionSource","_typeConnectionSource","hasEndpoints","sourceBlock","connectedBlocks","_endpoints","endpoints","innerType","_isMainLinkSource","createCustomInputBlock","_acceptedConnectionPointType","needDualDirectionValidation","acceptedConnectionPointTypes","excludedConnectionPointTypes","onConnectionObservable","onDisconnectionObservable","isExposedOnFrame","exposedPortPosition","checkCompatibilityState","otherBlock","targetBlock","isAnAncestorOf","ignoreConstraints","endpoint","bitmask","All","inputName","targetBlockId","targetConnectionName","_frameGraphTask","_outputs","_isInput","isTeleportOut","_isTeleportOut","isTeleportIn","_isTeleportIn","isDebug","_isDebug","isUnique","_isUnique","_inputRename","_outputRename","isAnAncestorOfType","getDescendantOfPredicate","_additionalConstructionParameters","visibleOnFrame","_comments_extraInitializers","isOptional","NodeRenderGraphConnectionPoint","additionalAllowedTypes","registerInput","dependencies","getInputByName","TextureAllButBackBuffer","ResourceContainer","ShadowGenerator","ObjectList","ShadowLight","_propagateInputValueToOutput","inputConnectionPoint","outputConnectionPoint","buildId","_notConnectedNonOptionalInputs","verbose","_buildBlock","dependenciesConnectedPoint","addTask","_getConnectedTextures","targetConnectedPoint","textureHandles","inputIndex0","inputIndex1","looseCoupling","getOutputByName","comments","additionalConstructionParameters","_deserialize","_deserializePortDisplayNamesAndExposedOnFrame","serializedInputs","serializedOutputs","_dumpPropertiesCode","_codeVariableName","alreadyDumped","codeString","connectedOutput","connectedBlock","_dumpCodeForOutputConnections","_dumpCode","uniqueNames","nameAsVariableName","blockType","onBuildObservable","_comments_decorators","_parentTask","setInitializeFunc","_initFunc","setExecuteFunc","_executeFunc","_isValid","_dispose","FrameGraphObjectListPass","FrameGraphPass","IsObjectListPass","pass","setObjectList","_objectList","parentTask","FrameGraphRenderPass","IsRenderPass","setRenderTarget","renderTargetDepth","_renderTargetDepth","frameGraphRenderTarget","_frameGraphRenderTarget","_dependencies","renderTargetHandle","setRenderTargetDepth","addDependencies","dependency","setOutputLayerAndFaceIndices","createRenderTarget","bindRenderTarget","FrameGraphTask","_disabled","passes","_passes","passesDisabled","_passesDisabled","onTexturesAllocatedObservable","onBeforeTaskExecute","onAfterTaskExecute","outputDepthTexture","handles","textureManager","getTextureFromHandle","outputObjectList","disabledOutputTexture","disabledOutputTextureHandle","disabledOutputDepthTexture","disabledOutputObjectList","_checkSameRenderTarget","isHistoryTexture","isBackbuffer","copyTexture","passDisabled","NodeRenderGraphOutputBlock","NodeRenderGraphBlock","_addDependenciesInput","addAcceptedConnectionPointTypes","TextureAll","FrameGraphCopyToBackbufferColorTask","textureConnectedPoint","_Registered$6L","ConversionMode","CopyTextureToTexture","_lodLevel","_textureIsInternal","_isDepthTexture","_conversion","_initShaderSourceAsync","sameSizeCopy","copyTextureToTexture_fragment","copyTextureToTexture_fragment$1","conversion","engineDepthFunc","engineDepthMask","_renderer","_textureManager","enableDebugMarkers","renderUnmanaged","currentRenderTarget","setDepthStates","SamplingModeHasMipMapFiltering","FrameGraphRenderContext","FrameGraphContext","_IsObjectRenderer","_renderTargetIsBound","_effectRenderer","_effectRendererBack","_copyTexture","_copyDepthTexture","_isBackbuffer","isBackbufferColor","isBackbufferDepthStencil","_applyRenderTarget","bindTextureHandle","_historyTextures","historyEntry","effectRenderer","drawBackFace","saveStates","noViewport","customBindings","forceCopyToBackbuffer","applyFullScreenEffect","applyImmediately","textureSizeIsObject","getDimensionsFromTextureSize","FrameGraphRenderTarget","_isBackBuffer","_renderTargetWrapper","textureHandle","textureDescription","getTextureDescription","creationOptionsForTexture","FrameGraphTextureNamespace","FrameGraphPassType","FrameGraphTextureManager","_debugTextures","_isRecordingTask","showDebugLogsForTextureAllcationOptimization","_backBufferTextureEntry","_backBufferDepthStencilTextureEntry","_backBufferTextureOverriden","_addSystemTextures","textureEntry","refHandle","checkAllTextures","historyTexture","sizeIsPercentage","CloneTextureOptions","preserveHistoryTextureFlag","getTextureCreationOptions","getAbsoluteDimensions","getTextureHandleOrCreateTexture","newTextureName","finalEntry","finalHandle","historyGetWriteTexture","importTexture","_freeEntry","_createHandleForTexture","External","Task","Graph","createDanglingHandle","danglingHandle","namespace","screenWidth","screenHeight","backbufferColorTextureSize","getTextureAbsoluteDimensions","handleOrCreationOptions","optimizedSize","outputWidth","outputHeight","aliasHandle","blockInfo","_GetTextureBlockInformation","textureByteSize","backBufferTextureOverriden","textureCreationOptions","depthStencilTextureCreationOptions","firstTask","lastTask","textureDescriptionHash","_createTextureDescriptionHash","resetBackBufferTextures","setBackBufferTextures","hasHistoryTextures","tasks","_optimizeTextureAllocation","refEntry","aliasEntry","internalTextureCreationOptions","_createDebugTexture","releaseAll","lifespan","currentTexture","textureDebug","pongCreationOptions","pongTexture","_computeTextureLifespan","textureHash","textureLifespan","cacheEntries","cacheEntryFound","cacheEntry","sourceHandle","lifespanArray","overlapped","_computeTextureLifespanForPasses","_updateLifespan","taskIndex","collectDependencies","passOrderNum","preserveLabels","FrameGraph","_tasks","_linkedNodeRenderGraph","debugTextures","_initAsyncPromises","_currentProcessedTask","_whenReadyAsyncCancel","optimizeTextureAllocation","pausedExecution","engine_multiRender_pure","RegisterEnginesWebGPUExtensionsEngineMultiRender","engine_multiRender_pure$1","_passContext","_renderContext","getTaskByName","getTasksByClassNames","getTasksByType","taskType","taskClassName","addPass","whenTaskDisabled","_addPass","Normal","addRenderPass","Render","addObjectListPass","passType","buildAsync","waitForReadiness","_importPromise","_whenAsynchronousInitializationDoneAsync","_allocateTextures","_checkTask","_initializePasses","firstNotReadyTask","taskIsReady","_updateHistoryTextures","mainObjectRenderer","isMainObjectRenderer","fallbackRenderer","removeFrameGraph","editableInPropertyPage","propStore","__bjsPropStoreKey","PropertyTypeForEdition","GetEditableProperties","currentMeta","Undefined","_storedValue","_isExternal_extraInitializers","registerOutput","setDefaultValue","TextureMeshBlendTag","TextureViewDepth","TextureScreenDepth","TextureNormalizedViewDepth","TextureViewNormal","TextureWorldNormal","TextureAlbedo","TextureReflectivity","TextureLocalPosition","TextureWorldPosition","TextureVelocity","TextureLinearVelocity","TextureIrradiance","TextureAlbedoSqrt","TextureObjectId","TextureDepthStencilAttachment","isExternal","getInternalTextureFromValue","TextureBackBuffer","TextureBackBufferDepthStencilAttachment","isBackBuffer","isBackBufferDepthStencilAttachment","isCamera","getTypedValue","isObjectList","isShadowLight","textureCreateOptions","codes","isAnyTexture","_isExternal_decorators","_Registered$6K","NodeRenderGraphInputBlock","_layerAndFaceIndicesUpdated","_outputLayerAndFaceIndices","_updateLayerAndFaceIndices","FrameGraphClearTextureTask","FrameGraphTaskMultiRenderTarget","convertColorToLinearSpace","stencilValue","skipCreationOfDisabledPasses","targetTextures","resolveDanglingHandle","targetDescription","depthDescription","textureSamples","depthSamples","addExcludedConnectionPointFromAllowedTypes","outputDepth","embedded","_get_clearStencil_decorators","_get_color_decorators","_get_clearColor_decorators","_get_convertColorToLinearSpace_decorators","_get_clearDepth_decorators","_Registered$6J","NodeRenderGraphClearBlock","NodeRenderGraphConnectionPointCustomObject","_blockType","ThinDepthPeelingRenderer","passCount","_passCount","_createRenderPassIds","useRenderPasses","_useRenderPasses","usePasses","addExcludedMesh","removeExcludedMesh","blendOutput","_blendOutput","_depthMrts","_thinTextures","_colorMrts","_currentPingPongState","_layoutCacheFormat","_layoutCache","_candidateSubMeshes","_excludedSubMeshes","_colorCache","_DEPTH_CLEAR_VALUE","_MIN_DEPTH","_MAX_DEPTH","_createEffects","_releaseRenderPassIds","_getTextureSize","_blendBackMrt","optionsArray","frontColorTexture","backColorTexture","finalEffectFragmentShaderName","_blendBackEffectWrapper","oitBackBlend_fragment","oitBackBlend_fragment$1","_blendBackEffectWrapperPingPong","_finalEffectWrapper","finalEffectSamplerNames","oitFinalSimpleBlend_fragment$1","oitFinalSimpleBlend_fragment","_prePassRenderer","_renderSubMeshes","transparentSubMeshes","mapMaterialContext","previousShaderHotSwapping","previousBFC","firstDraw","newMaterialContext","writeId","_noTransparentMeshes","readId","blendBackEffectWrapper","_finalCompose","FrameGraphObjectRendererTask","_renderMeshes","_renderDepthOnlyMeshes","_renderOpaqueMeshes","_renderAlphaTestMeshes","_renderTransparentMeshes","useOITForTransparentMeshes","_useOITForTransparentMeshes","_renderTransparentMeshesWithOIT","_oitRenderer","_rtForOrderIndependentTransparency","oitPassCount","_forceLayerMaskCheck","_enableBoundingBoxRendering","_enableOutlineRendering","shadowGenerators","disableShadows","_externalObjectRenderer","_getTargetHandles","depthEnabled","_checkTextureCompatibility","_resolveDanglingHandles","_setLightsForShadow","_prepareRendering","currentOITRenderer","_depthPeelingRenderer","additionalExecute","_checkParameters","outputTextureDescription","depthTextureDescription","lightsForShadow","shadowGeneratorTask","getLight","saveOIT","_useOrderIndependentTransparency","TextureAllButBackBufferDepthStencil","_createFrameGraphObject","renderInLinearSpace","_saveState","_restoreState","_createFrameGraphObjectWithState","objects","shadowGeneratorsConnectedPoint","_get_isMainObjectRenderer_decorators","_get_depthTest_decorators","_get_depthWrite_decorators","_get_renderMeshes_decorators","_get_renderDepthOnlyMeshes_decorators","_get_renderOpaqueMeshes_decorators","_get_renderAlphaTestMeshes_decorators","_get_renderTransparentMeshes_decorators","_get_useOITForTransparentMeshes_decorators","_get_oitPassCount_decorators","_get_renderParticles_decorators","_get_renderSprites_decorators","_get_forceLayerMaskCheck_decorators","_get_enableBoundingBoxRendering_decorators","_get_enableOutlineRendering_decorators","_get_disableShadows_decorators","_get_renderInLinearSpace_decorators","_get_doNotChangeAspectRatio_decorators","_get_enableClusteredLights_decorators","_get_resolveMSAAColors_decorators","_get_resolveMSAADepth_decorators","NodeRenderGraphObjectRendererBlock","NodeRenderGraphBaseObjectRendererBlock","_Registered$6I","errorObservable","notConnectedInput","errorMessage","FrameGraphCullObjectsTask","NodeRenderGraphCullObjectsBlock","_Registered$6H","NODERENDERGRAPHEDITOR","NodeRenderGraphEditor","_buildId","_BuildIdGenerator","BJSNODERENDERGRAPHEDITOR","_getGlobalNodeRenderGraphEditor","editorData","attachedBlocks","onBeforeBuildObservable","outputBlock","comment","_comment_initializers","_comment_extraInitializers","autoConfigure","rebuildGraphOnEngineResize","autoFillExternalInputs","getBlockByPredicate","updateCameraToUseForPointers","rebuildGraph","inputBlocks","getInputBlocks","currentAutoFill","nodeRenderGraphEditorConfig","nodeEditorConfig","customBlockDescriptions","CustomBlockDescriptions","dontBuildFrameGraph","setAsSceneFrameGraph","_initializeBlock","NodeRenderGraphBuildState","_autoFillExternalInputs","objectRendererBlocks","getBlocksByPredicate","emitErrors","onBuildErrorObservable","allInputs","shadowLights","attachedBlockIndex","parsedBlock","teleportOut","_tempEntryPointUniqueId","attachToEndpoint","blockIndex","_restoreConnections","outputNodeId","blockId","outputPoint","inputPoint","_gatherBlocks","mainRendering","parseSerializedObject","selectedBlocks","renderGraph","nodeRenderGraphOptions","setToDefault","skipBuild","nodeRenderGraph","CreateDefaultAsync","_comment_decorators","FrameGraphComputeShaderTask","_cs","_ubo","dispatchSize","_notSupported","uBuffer","uboEntry","indirectDispatch","NodeRenderGraphComputeShaderBlock","computeShaderPath","computeShaderOptions","_createTask","shaderOptions","_Registered$6G","NodeRenderGraphElbowBlock","_Registered$6F","customIsReady","funcDisabled","NodeRenderGraphExecuteBlock","FrameGraphExecuteTask","_Registered$6E","_needProjectionMatrixCompute","_setPosition","_setDirection","_shadowMinZ","forceProjectionMatrixCompute","_shadowMaxZ","transformedPosition","getDepthScale","getShadowDirection","needCube","getDepthMinZ","getDepthMaxZ","customProjectionMatrixBuilder","_setDefaultShadowProjectionMatrix","lightDirection","lightPosition","computeTransformedInformation","lightTarget","_get_position_decorators","_get_direction_decorators","_get_shadowMinZ_decorators","_get_shadowMaxZ_decorators","shadowFrustumSize","_shadowFrustumSize","shadowOrthoScale","_shadowOrthoScale","autoUpdateExtends","_autoUpdateExtends_initializers","__orthoLeft_initializers","__orthoLeft_extraInitializers","__orthoRight_initializers","MIN_VALUE","__orthoRight_extraInitializers","__orthoTop_initializers","__orthoBottom_extraInitializers","_setDefaultFixedFrustumShadowProjectionMatrix","_setDefaultAutoExtendShadowProjectionMatrix","transferToNodeMaterialEffect","_get_shadowFrustumSize_decorators","_get_shadowOrthoScale_decorators","_autoUpdateExtends_decorators","__orthoBottom_decorators","_autoUpdateExtends_extraInitializers","_autoCalcShadowZBounds_decorators","_autoCalcShadowZBounds_initializers","_autoCalcShadowZBounds_extraInitializers","__orthoLeft_decorators","__orthoRight_decorators","__orthoTop_decorators","__orthoTop_extraInitializers","_Registered$6D","DirectionalLight","TmpVec3","LightingVolume","_shadowGenerator","sg","_updateGeometry","_createFallbackTextures","_setComputeShaderInputs","tesselation","_tesselation","frequency","_frequency","_firstUpdate","firstUpdate","_setComputeShaderFastMode","_cs2","_buildFullVolume","_readPixelPromise","_readPixelAbortController","_numFrames","_currentLightDirection","_needFullUpdateUBO","_uBuffer","_createComputeShader","_currentShadowDepthTexture","_needUpdateGeometry","_fullUpdateUBO","_fallbackReadPixelAsync","_fallbackTexture","_storageBuffer","_depthCopy","AbortController","abortController","throwIfAborted","shadowMapDepthTexture","depthValues","numTesselation","startPos","halfTesselation","invViewProjMatrix","posIndex","stepY","invViewMatrix","vertexNumber","_createIndices","webGPUEngine","stepX","startFarIndices","rightFaceStartIndex","leftFaceStartIndex","bottomFaceStartIndex","topFaceStartIndex","iy","ix","FrameGraphLightingVolumeTask","lightingVolume","outputMeshLightingVolume","_get_tesselation_decorators","_get_frequency_decorators","_Registered$6C","NodeRenderGraphLightingVolumeBlock","NodeRenderGraphResourceContainerBlock","resource0","resource1","resource2","resource3","resource4","resource5","resource6","resource7","_Registered$6B","ThinGlowBlurPostProcess","kernel","Uniforms","glowBlurPostProcess_fragment","glowBlurPostProcess_fragment$1","ThinEffectLayer","currentMesh","_materialForRendering","_effectIntensity","dontCheckIfReady","_additionalImportShadersAsync","neutralColor","disableBoundingBoxesFromEffectLayer","onBeforeRenderLayerObservable","onBeforeComposeObservable","onBeforeRenderMeshToEffect","onAfterRenderMeshToEffect","onAfterComposeObservable","onBeforeBlurObservable","onAfterBlurObservable","_dontCheckIfReady","_generateIndexBuffer","_generateVertexBuffer","_useInstances","needStencil","_createMergeEffect","_numInternalDraws","mainTextureRatio","mainTextureFixedSize","mainTextureType","mainTextureFormat","alphaBlendingMode","_createObjectRenderer","hasBoundingBoxRenderer","boundingBoxRendererEnabled","preWarm","_setEmissiveTextureAndColor","_emissiveTextureAndColor","opaqueSubMeshes","alphaTestSubMeshes","depthOnlySubMeshes","_renderSubMesh","previousAlphaMode","renderingMaterial","_glowModeEnabled","needAlphaTest","needAlphaBlendFromDiffuse","_useAlphaFromAlbedoTexture","cachedDefines","_importShadersAsync","_internalIsSubMeshReady","glowMapGeneration_vertex","glowMapGeneration_fragment","glowMapGeneration_vertex$1","glowMapGeneration_fragment$1","numDraws","_mergeDrawWrapper","_disposeMergeEffects","_internalIsLayerReady","_internalCompose","_internalHasMesh","hasMesh","_internalShouldRender","_shouldRenderMesh","_internalCanRenderMesh","replacementMesh","_canRenderMesh","_isSubMeshReady","currentDepthWrite","currentColorWrite","textureMatrix","_useMeshMaterial","ThinBlurPostProcess","kernelBlur_fragment","kernelBlur_vertex","kernelBlur_fragment$1","kernelBlur_vertex$1","blockCompilationFinal","VertexUrl","_packedFloat","_staticDefines","_idealKernel","_kernel","packedFloat","centerIndex","linearSamplingWeights","linearSamplingOffsets","linearSamplingMap","sharedCell","weightLinear","offsetLinear","maxVaryingRows","freeVaryingVec2","varyingCount","_glslFloat","depCount","idealKernel","sigma","decimalFigures","ThinGlowLayer","ldrMerge","blurKernelSize","effectiveKernel","_getEffectiveBlurKernelSize","_horizontalBlurPostprocess1","_verticalBlurPostprocess1","_horizontalBlurPostprocess2","_verticalBlurPostprocess2","_intensity","_renderPassId","_createTextureAndPostProcesses","glowMapMerge_fragment","glowMapMerge_vertex","glowMapMerge_fragment$1","glowMapMerge_vertex$1","EffectName","excludeByDefault","bindTexturesForCompose","previousStencilBuffer","textureLevel","customEmissiveTextureSelector","customEmissiveColorSelector","emissiveIntensity","_addCustomEffectDefines","addIncludedOnlyMesh","removeIncludedOnlyMesh","setExcludedByDefault","_meshesUsingTheirOwnMaterials","referenceMeshToUseItsOwnMaterial","_disposeMesh","unReferenceMeshFromUsingItsOwnMaterial","FrameGraphPostProcessTask","_postProcessDrawWrapper","sourceSamplingMode","outputDepthAttachmentTexture","additionalBindings","sourceTextureCreationOptions","depthAttachmentTexture","sourceSize","_sourceWidth","_sourceHeight","_outputWidth","_outputHeight","setTextureSamplingMode","FrameGraphBlurTask","thinPostProcess","FrameGraphBaseLayerBlurType","FrameGraphGlowBlurTask","FrameGraphBaseLayerTask","_blurX","_blurY","_clearLayerTextureTask","_objectRendererForLayerTask","objectRendererForLayer","numBlurPasses","_blurType","_setRenderTargetDepth","_notifyBlurObservable","_setObjectList","_onBeforeBlurTask","_onAfterBlurTask","_onBeforeObservableObserver","_onBeforeObservableObserver2","_onAfterObservableObserver","_onAfterRenderingGroupObserver","colorLayerOutput","layerTexture","targetTextureCreationOptions","fixedTextureSize","textureDepthCreationOptions","depthLayerOutput","objectRendererTask","onBeforeBlurPass","onAfterBlurPass","blurTextureType","blurTextureSizeRatio","blurPasses","blurXTextureHandle","blurYTextureHandle","clearTaskPass","objectRendererForLayerTaskPass","_clearAfterRenderingGroupObserver","additionalComposeBindings","saveDepthStates","compose","restoreDepthStates","FrameGraphGlowLayerTask","layerTextureRatio","layerTextureFixedSize","layerTextureType","_get_ldrMerge_decorators","_get_layerTextureRatio_decorators","_get_layerTextureFixedSize_decorators","_get_layerTextureType_decorators","_get_blurKernelSize_decorators","_get_intensity_decorators","_Registered$6A","NodeRenderGraphGlowLayerBlock","ThinHighlightLayer","blurHorizontalSize","_horizontalBlurPostprocess","blurVerticalSize","_verticalBlurPostprocess","stencilReference","_instanceGlowingMeshStencilReference","numStencilBits","innerGlow","outerGlow","_mainObjectRendererRenderPassId","isStroke","_downSamplePostprocess","highlightLayerMesh","glowEmissiveOnly","beforeBind","meshExcluded","meshHighlight","observerHighlight","_defaultStencilReference","observerDefault","meshHighlightToCheck","removeAllMeshes","NormalMeshStencilReference","NeutralColor","GlowingMeshStencilReference","FrameGraphHighlightLayerTask","depthTextureCreationOptions","_get_blurTextureSizeRatio_decorators","_get_isStroke_decorators","_get_blurHorizontalSize_decorators","_get_blurVerticalSize_decorators","_Registered$6z","NodeRenderGraphHighlightLayerBlock","ThinSelectionOutlineLayer","occlusionStrength","_occlusionStrength","wasUsingComposeDepthOcclusion","_shouldUseComposeDepthOcclusion","useDepthOcclusion","_useDepthOcclusion","outlineColor","outlineThickness","occlusionThreshold","_selection","_instancedBufferSources","RegisterAbstractEngineStates","storeCameraSpaceZ","outlineMethod","alphaTestTexture","hasUV1","InstanceSelectionIdAttributeName","selection_vertex$1","selection_fragment$1","selectionOutline_fragment$1","selection_vertex","selection_fragment","selectionOutline_fragment","OUTLINELAYER_SAMPLING_OCTADIRECTIONAL","alphaTexture","selectionId","_meshUniqueIdToSelectionId","previousDepthBuffer","previousDepthWrite","clearSelection","_cleanUpInstanceSelectionId","_nextSelectionId","nextId","meshOrGroup","lodLevels","selectionIdData","FrameGraphSelectionOutlineLayerTask","_layerTextureDimensions","_get_outlineColor_decorators","_get_outlineThickness_decorators","_get_occlusionStrength_decorators","_get_occlusionThreshold_decorators","_get_useDepthOcclusion_decorators","_Registered$6y","NodeRenderGraphSelectionOutlineLayerBlock","FrameGraphAnaglyphTask","leftTexture","_get_sourceSamplingMode_decorators","_useCurrentViewport","_useFullScreenViewport","_setViewport","useCurrentViewport","useFullScreenViewport","_get_depthReadOnly_decorators","_get_stencilReadOnly_decorators","_get_disableColorWrite_decorators","_get_drawBackFace_decorators","_get_useCurrentViewport_decorators","_get_useFullScreenViewport_decorators","_get_viewport_decorators","NodeRenderGraphAnaglyphPostProcessBlock","NodeRenderGraphBaseWithPropertiesPostProcessBlock","_finalizeInputOutputRegistering","_Registered$6x","ThinBlackAndWhitePostProcess","blackAndWhite_fragment","blackAndWhite_fragment$1","degree","FrameGraphBlackAndWhiteTask","_get_degree_decorators","_Registered$6w","NodeRenderGraphBlackAndWhitePostProcessBlock","ThinBloomMergePostProcess","bloomMerge_fragment","bloomMerge_fragment$1","blurTexture","ThinExtractHighlightsPostProcess","extractHighlights_fragment","extractHighlights_fragment$1","ThinBloomEffect","_downscale","_merge","FrameGraphExtractHighlightsTask","FrameGraphBloomTask","hdr","bloomScale","_defaultPipelineTextureType","bloom","FrameGraphBloomMergeTask","sourceTextureDescription","downscaleTextureHandle","_get_bloomScale_decorators","_get_hdr_decorators","_get_threshold_decorators","_get_weight_decorators","_get_kernel_decorators","_Registered$6v","NodeRenderGraphBloomPostProcessBlock","_Registered$6u","NodeRenderGraphBlurPostProcessBlock","ThinChromaticAberrationPostProcess","chromaticAberration_fragment","chromaticAberration_fragment$1","aberrationAmount","radialIntensity","centerPosition","FrameGraphChromaticAberrationTask","_get_aberrationAmount_decorators","_get_radialIntensity_decorators","_Registered$6t","NodeRenderGraphChromaticAberrationPostProcessBlock","ThinCircleOfConfusionPostProcess","circleOfConfusion_fragment","circleOfConfusion_fragment$1","depthNotNormalized","DefinesDepthNotNormalized","lensSize","fStop","focusDistance","focalLength","cocPrecalculation","FrameGraphCircleOfConfusionTask","depthSamplingMode","geomViewDepth","_get_depthSamplingMode_decorators","_get_lensSize_decorators","_get_fStop_decorators","_get_focusDistance_decorators","_get_focalLength_decorators","_Registered$6s","NodeRenderGraphCircleOfConfusionPostProcessBlock","ThinColorCorrectionPostProcess","colorCorrection_fragment","colorCorrection_fragment$1","_colorTableTexture","colorTableUrl","FrameGraphColorCorrectionTask","_get_colorTableUrl_decorators","_Registered$6r","NodeRenderGraphColorCorrectionPostProcessBlock","ThinConvolutionPostProcess","convolution_fragment","convolution_fragment$1","EdgeDetect0Kernel","EdgeDetect1Kernel","EdgeDetect2Kernel","SharpenKernel","EmbossKernel","GaussianKernel","FrameGraphConvolutionTask","kernelIndex","_Registered$6q","NodeRenderGraphConvolutionPostProcessBlock","ThinDepthOfFieldBlurPostProcess","ThinDepthOfFieldMergePostProcess","depthOfFieldMerge_fragment","depthOfFieldMerge_fragment$1","ThinDepthOfFieldEffectBlurLevel","ThinDepthOfFieldEffect","_circleOfConfusion","blurCount","_depthOfFieldBlurY","blurLevel","adjustedKernelSize","_depthOfFieldBlurX","_dofMerge","blurSteps","circleOfConfusionTexture","circleOfConfusionSamplingMode","FrameGraphDepthOfFieldTask","depthOfField","FrameGraphDepthOfFieldBlurTask","FrameGraphDepthOfFieldMergeTask","circleOfConfusionTextureFormat","circleOfConfusionTextureHandle","_get_blurLevel_decorators","_Registered$6p","NodeRenderGraphDepthOfFieldPostProcessBlock","_Registered$6o","NodeRenderGraphExtractHighlightsPostProcessBlock","ThinFilterPostProcess","filter_fragment","filter_fragment$1","kernelMatrix","FrameGraphFilterTask","_get_kernelMatrix_decorators","_Registered$6n","NodeRenderGraphFilterPostProcessBlock","ThinFXAAPostProcess","_GetDefines","fxaa_fragment","fxaa_vertex","fxaa_fragment$1","fxaa_vertex$1","FrameGraphFXAATask","NodeRenderGraphFXAAPostProcessBlock","_Registered$6m","ThinGrainPostProcess","grain_fragment","grain_fragment$1","FrameGraphGrainTask","_get_animated_decorators","_Registered$6l","NodeRenderGraphGrainPostProcessBlock","_ApplyWhiteBalanceOptions","ThinImageProcessingPostProcess","imageProcessing_fragment$1","imageProcessing_fragment","doNotBuild","fromLinearSpace","_fromLinearSpace","FROMLINEARSPACE","FrameGraphImageProcessingTask","_get_contrast_decorators","_get_exposure_decorators","_get_toneMappingEnabled_decorators","_get_toneMappingType_decorators","_get_vignetteEnabled_decorators","_get_vignetteWeight_decorators","_get_vignetteStretch_decorators","_get_vignetteCameraFov_decorators","_get_vignetteCenterX_decorators","_get_vignetteCenterY_decorators","_get_vignetteColor_decorators","_get_vignetteBlendMode_decorators","_get_ditheringEnabled_decorators","_get_ditheringIntensity_decorators","_Registered$6k","NodeRenderGraphImageProcessingPostProcessBlock","ThinMotionBlurPostProcess","motionBlur_fragment","motionBlur_fragment$1","Defines","_invViewProjection","_previousViewProjection","motionStrength","_motionBlurSamples","_isObjectBased","_applyMode","motionBlurSamples","_updateEffect","isObjectBased","FrameGraphMotionBlurTask","velocityTexture","geomVelocity","_get_motionStrength_decorators","_get_motionBlurSamples_decorators","_get_isObjectBased_decorators","_Registered$6j","NodeRenderGraphMotionBlurPostProcessBlock","PackMeshBlendingTag","groupId","radiusClass","MeshBlendingRadiusClass","ExtraLarge","UnpackMeshBlendingTag","_TextureSize","_BlueNoiseData","_FillBlueNoiseChannel","whiteNoise","highPassNoise","rankedIndices","_HashPixel","previousY","nextY","previousX","nextX","neighborAverage","MeshBlendQuality","MeshBlendDebugMode","MeshBlendDepthType","_MeshBlendingEffectWrapperOwners","_ClaimMeshBlendingEffectWrapper","_ValidateWorldRadius","_ValidateMinimumProjectedRadius","_CreateValidatedRadiusDefinition","worldRadius","minimumProjectedRadius","validatedWorldRadius","validatedMinimumProjectedRadius","definition","CreateDefaultMeshBlendRadiusDefinitions","_MeshBlendLinearToSrgbChannel","_MeshBlendSrgbToLinearChannel","_LinearSrgbToMeshBlendOklab","longRoot","mediumRoot","shortRoot","_MeshBlendOklabToLinearSrgb","currentColor","targetColor","_GetMeshBlendQualitySettings","colorInterpolation","_MeshBlendQualitySettings","directionCount","radialSampleCount","directionRefinementSampleCount","directionRefinementStepCount","exactEdgeSampleCount","fullRandomRotation","searchJitterFactor","immediateFourNeighborFallback","tinyObjectSafeguard","multiTargetSecondaryBlend","_ProjectMeshBlendWorldRadiusToPixels","viewDepth","renderTargetHeight","projectionYScale","isOrthographic","projectionScale","projectedRadius","scaledRadius","_GetMeshBlendQualityRadiusScale","_CalculateMeshBlendFade","distancePixels","searchRadiusPixels","boundaryDistance","inverseDistance","radiusPixels","_CalculateMeshBlendSlopeScale","oppositeFacing","slopeFactor","Low","Medium","High","Cinematic","_GetMeshBlendQualityDefine","_ValidateDepthType","Screen","_BuildMeshBlendDefines","debugMode","depthType","hasBaseColorTexture","customDefines","_ValidateDebugMode","_GetMeshBlendQualityDefines","_ValidateRadiusDefinition","_ValidateMeshBlendConfiguration","radiusClasses","ThinMeshBlendingPostProcess","meshBlending_fragment$1","meshBlending_fragment","_slopeFactor","_quality","_updateEffectDefines","_depthType","_hasBaseColorTexture","resolvedEngine","_IsMeshBlendingSupported","Off","View","_inverseView","_cachedProjection","_cachedView","_customDefines","_applyConfiguration","_stableBlueNoiseTexture","_GetMeshBlendBlueNoiseData","WRAP_ADDRESSMODE","_CreateMeshBlendBlueNoiseTexture","previousQuality","previousDebugMode","previousDepthType","_CopyRadiusDefinitions","WorldPosition","_ReleaseMeshBlendingEffectWrapper","meshBlendTagTexture","meshBlendTagCreationOptions","meshBlendTagType","_GetTextureType","meshBlendTagFormat","_GetTextureFormat","meshBlendTagSamples","_Is2DTexture","depthCreationOptions","validDepthFormat","validDepthType","baseColorSamples","baseColorTexture","baseColorCreationOptions","baseColorType","baseColorFormat","validBaseColorFormat","validBaseColorType","sourceCreationOptions","sourceFormat","sourceSamples","validSourceFormat","validSourceType","meshBlendTagSize","depthSize","baseColorSize","targetCreationOptions","targetFormat","targetSamples","validTargetFormat","validTargetType","targetSize","_setRadiusValue","geomDepth","FrameGraphMeshBlendingTask","smallWorldRadius","smallMinimumProjectedRadius","mediumWorldRadius","mediumMinimumProjectedRadius","largeWorldRadius","largeMinimumProjectedRadius","extraLargeWorldRadius","extraLargeMinimumProjectedRadius","geomAlbedo","geomMeshBlendTag","resolvedRadiusClasses","_get_quality_decorators","_get_slopeFactor_decorators","_get_debugMode_decorators","CandidateDirectionDistance","StageWork","Continuation","MultiTarget","TargetColor","ShadowAttenuation","ColorInterpolation","_get_smallWorldRadius_decorators","_get_smallMinimumProjectedRadius_decorators","_get_mediumWorldRadius_decorators","_get_mediumMinimumProjectedRadius_decorators","_get_largeWorldRadius_decorators","_get_largeMinimumProjectedRadius_decorators","_get_extraLargeWorldRadius_decorators","_get_extraLargeMinimumProjectedRadius_decorators","_Registered$6i","NodeRenderGraphMeshBlendingPostProcessBlock","FrameGraphPassTask","FrameGraphPassCubeTask","NodeRenderGraphPassPostProcessBlock","NodeRenderGraphPassCubePostProcessBlock","_Registered$6h","ThinSharpenPostProcess","sharpen_fragment","sharpen_fragment$1","colorAmount","edgeAmount","FrameGraphSharpenTask","_get_colorAmount_decorators","_get_edgeAmount_decorators","_Registered$6g","NodeRenderGraphSharpenPostProcessBlock","ThinScreenSpaceCurvaturePostProcess","screenSpaceCurvature_fragment","screenSpaceCurvature_fragment$1","ridge","valley","FrameGraphScreenSpaceCurvatureTask","normalTexture","geomViewNormal","_get_ridge_decorators","_get_valley_decorators","_Registered$6f","NodeRenderGraphScreenSpaceCurvaturePostProcessBlock","ThinSSAO2PostProcess","ssao2_fragment","ssao2_fragment$1","_sampleSphere","_generateHemisphere","normalsInWorldSpace","_normalsInWorldSpace","_getDefinesForSSAO","totalStrength","minZAspect","_normalWorldToViewMatrix","_normalWorldToView","_bits","_createRandomTexture","PERSPECTIVE_DEPTH_PROJECTION","viewportSize","ORTHO_DEPTH_PROJECTION","normalWorldToView","_randomTexture","randVector","_radicalInverseVdC","_hammersley","numSamples","_hemisphereSampleUniform","rand","ThinSSAO2BlurPostProcess","isHorizontal","_bypassBlur","bilateralSamples","bilateralSoften","bilateralTolerance","_expensiveBlur","_isHorizontal","_getDefinesForBlur","expensiveBlur","bypassBlur","_getSamplersForBlur","bilateral","ThinSSAO2CombinePostProcess","ssaoCombine_fragment","ssaoCombine_fragment$1","useViewportInCombineStage","ThinSSAO2RenderingPipeline","_ssaoPostProcess","_ssaoCombinePostProcess","_ssaoBlurXPostProcess","_ssaoBlurYPostProcess","_currentCameraMode","FrameGraphSSAO2BlurTask","FrameGraphSSAO2RenderingPipelineTask","_ssaoCombine","ssao","_ssao","_ssaoBlurX","_ssaoBlurY","ratioSSAO","ratioBlur","FrameGraphSSAO2Task","ssaoTextureHandle","geomNormal","_get_textureType_decorators","_get_ratioSSAO_decorators","_get_ratioBlur_decorators","_get_samples_decorators","_get_totalStrength_decorators","_get_base_decorators","_get_maxZ_decorators","_get_minZAspect_decorators","_get_epsilon_decorators","_get_useViewportInCombineStage_decorators","_get_bypassBlur_decorators","_get_expensiveBlur_decorators","_get_bilateralSamples_decorators","_get_bilateralSoften_decorators","_get_bilateralTolerance_decorators","_Registered$6e","NodeRenderGraphSSAO2PostProcessBlock","Trs","TrsWebGPU","ThinSSRPostProcess","screenSpaceReflection2_fragment","screenSpaceReflection2_fragment$1","reflectivityThreshold","_reflectivityThreshold","useBlur","_useBlur","blur","enableSmoothReflections","_enableSmoothReflections","environmentTextureIsProbe","_environmentTextureIsProbe","isProbe","attenuateScreenBorders","_attenuateScreenBorders","attenuate","attenuateIntersectionDistance","_attenuateIntersectionDistance","attenuateIntersectionIterations","_attenuateIntersectionIterations","attenuateFacingCamera","_attenuateFacingCamera","attenuateBackfaceReflection","_attenuateBackfaceReflection","clipToFrustum","_clipToFrustum","useFresnel","_useFresnel","fresnel","enableAutomaticThicknessComputation","_enableAutomaticThicknessComputation","automatic","inputTextureColorIsInGammaSpace","_inputTextureColorIsInGammaSpace","generateOutputInGammaSpace","_generateOutputInGammaSpace","_debug","useScreenspaceDepth","_useScreenspaceDepth","normalsAreInWorldSpace","_normalsAreInWorldSpace","normalsAreUnsigned","_normalsAreUnsigned","isSSRSupported","strength","reflectionSpecularFalloffExponent","maxSteps","roughnessFactor","selfCollisionNumSkip","ThinSSRBlurPostProcess","screenSpaceReflection2Blur_fragment","screenSpaceReflection2Blur_fragment$1","blurStrength","ThinSSRBlurCombinerPostProcess","screenSpaceReflection2BlurCombiner_fragment","screenSpaceReflection2BlurCombiner_fragment$1","ThinSSRRenderingPipeline","_ssrPostProcess","_ssrBlurCombinerPostProcess","skip","blurDispersionStrength","_ssrBlurXPostProcess","_ssrBlurYPostProcess","ssrDownsample","blurDownsample","reflectivityTexture","backDepthTexture","FrameGraphSSRRenderingPipelineTask","_ssrBlurCombiner","ssr","_ssr","_ssrBlurX","_ssrBlurY","FrameGraphSSRTask","FrameGraphSSRBlurTask","ssrTextureHandle","geomBackDepth","geomReflectivity","geomBackDepthOwnerBlock","_get_debug_decorators","_get_strength_decorators","_get_reflectionSpecularFalloffExponent_decorators","_get_reflectivityThreshold_decorators","_get_thickness_decorators","_get_step_decorators","_get_enableSmoothReflections_decorators","_get_maxSteps_decorators","_get_maxDistance_decorators","_get_roughnessFactor_decorators","_get_selfCollisionNumSkip_decorators","_get_ssrDownsample_decorators","_get_clipToFrustum_decorators","_get_enableAutomaticThicknessComputation_decorators","_get_useFresnel_decorators","_get_blurDispersionStrength_decorators","_get_blurDownsample_decorators","_get_attenuateScreenBorders_decorators","_get_attenuateIntersectionDistance_decorators","_get_attenuateIntersectionIterations_decorators","_get_attenuateFacingCamera_decorators","_get_attenuateBackfaceReflection_decorators","_get_inputTextureColorIsInGammaSpace_decorators","_get_generateOutputInGammaSpace_decorators","_Registered$6d","NodeRenderGraphSSRPostProcessBlock","Halton2DSequence","baseX","baseY","_curIndex","_sequence","_numSamples","_baseX","_baseY","_generateSequence","regenerate","setDimensions","_halton","fraction","TAA_JITTER","TAAJitterMaterialPlugin","_manager","_materialPlugins","_updateMaterial","TAAJitterMaterialDefines","jitter","TAAMaterialManager","_getPlugin","ThinTAAPostProcess","taa_fragment","taa_fragment$1","_hs","_taaMaterialManager","reprojectHistory","_reprojectHistory","reproject","clampHistory","_clampHistory","clamp","disableOnCameraMove","_nextJitterOffset","_updateProjectionMatrix","projMat","FrameGraphTAATask","_onBeforeRenderSceneObserver","_updateJitter","_initRenderingObserver","renderTextureSize","pingPongTextureCreationOptions","pingPongHandle","disableTAA","_get_factor_decorators","_get_reprojectHistory_decorators","_get_clampHistory_decorators","_get_disableOnCameraMove_decorators","_get_disableTAA_decorators","_Registered$6b","NodeRenderGraphTAAPostProcessBlock","TonemappingOperator","ThinTonemapPostProcess","tonemap_fragment","tonemap_fragment$1","exposureAdjustment","FrameGraphTonemapTask","_get_operator_decorators","_get_exposureAdjustment_decorators","_Registered$6a","NodeRenderGraphTonemapPostProcessBlock","VolumetricLightingBlendVolumeThinPostProcess","volumetricLightingBlendVolume_fragment$1","volumetricLightingBlendVolume_fragment","enableExtinction","extinction","_invProjection","FrameGraphVolumetricLightingBlendVolumeTask","InvViewProjectionMatrix","FrameGraphVolumetricLightingTask","_renderLightingVolumeTask","_blendLightingVolumeTask","phaseG","_extinctionPhaseG","_renderLightingVolumeMaterial","lightPower","_lightPower","_clearLightingVolumeTextureTask","volumetricLightingRenderVolume_vertex$1","volumetricLightingRenderVolume_fragment$1","volumetricLightingRenderVolume_vertex","volumetricLightingRenderVolume_fragment","lightingVolumeMesh","lightingVolumeTexture","targetTextureSize","volumeTextureSize","_get_phaseG_decorators","_get_enableExtinction_decorators","_get_extinction_decorators","_get_lightPower_decorators","_Registered$69","NodeRenderGraphVolumetricLightingBlock","_set_kernel_decorators","_set_packedFloat_decorators","_Registered$68","BlurPostProcess","ShadowGeneratorSceneComponent","_gatherRenderTargets","_Registered$67","shadowGeneratorClass","parsedShadowGenerator","_CascadedShadowGeneratorParser","_bias","normalBias","_normalBias","blurBoxOffset","_blurBoxOffset","_disposeBlurPostProcesses","blurScale","_blurScale","blurKernel","_blurKernel","useKernelBlur","_useKernelBlur","depthScale","_depthScale","_validateFilter","_filter","FILTER_BLUREXPONENTIALSHADOWMAP","useExponentialShadowMap","FILTER_BLURCLOSEEXPONENTIALSHADOWMAP","useCloseExponentialShadowMap","FILTER_PCF","FILTER_PCSS","usePoissonSampling","_applyFilterValues","FILTER_POISSONSAMPLING","FILTER_NONE","FILTER_EXPONENTIALSHADOWMAP","useBlurExponentialShadowMap","FILTER_CLOSEEXPONENTIALSHADOWMAP","useBlurCloseExponentialShadowMap","usePercentageCloserFiltering","filteringQuality","_filteringQuality","useContactHardeningShadow","contactHardeningLightSizeUVRatio","_contactHardeningLightSizeUVRatio","darkness","_darkness","setDarkness","transparencyShadow","_transparencyShadow","setTransparencyShadow","_shadowMap","getShadowMapForRendering","_shadowMap2","CLASSNAME","addShadowCaster","removeShadowCaster","_mapSize","recreateShadowMap","useFloat32TextureType","_usefullFloatFirst","useRedTextureFormat","_useRedTextureType","usefullFloatFirst","useRedTextureType","onBeforeShadowMapRenderObservable","onAfterShadowMapRenderObservable","onBeforeShadowMapRenderMeshObservable","onAfterShadowMapRenderMeshObservable","QUALITY_HIGH","enableSoftTransparentShadow","useOpacityTextureForTransparentShadow","forceBackFacesOnly","_lightDirection","_cachedPosition","_cachedDirection","_currentFaceIndexCache","_defaultTextureMatrix","RegisterShadowGeneratorSceneComponent","_initializeGenerator","_initializeShadowMap","noPrePassRenderer","_createTargetRenderTexture","_storedUniqueId","customAllowRendering","isTransparent","_blurPostProcesses","clearZero","clearOne","shadowMap_fragment","shadowMap_vertex","depthBoxBlur_fragment","shadowMapFragmentSoftTransparentShadow$1","shadowMap_fragment$1","shadowMap_vertex$1","depthBoxBlur_fragment$1","shadowMapFragmentSoftTransparentShadow$2","_kernelBlurXPostprocess","_kernelBlurYPostprocess","_boxBlurPostprocess","_renderForShadowMap","_renderSubMeshForShadowMap","useRHS","detNeg","reverseSideOrientation","_bindCustomEffectForRenderSubMeshForShadowMap","worldOverride","_isReadyCustomDefines","_prepareShadowDefines","subMeshEffect","useNormal","DEFAULT_ALPHA_CUTOFF","customShaderOptions","attrib","_initializeBlurRTTAndPostProcesses","QUALITY_LOW","QUALITY_MEDIUM","lightMatrix","shadowMapForRendering","getDarkness","frustumEdgeFalloff","needProjectionMatrixCompute","_disposeRTTandPostProcesses","_disposeSceneUBOs","lightId","constr","renderSet","useVarianceShadowMap","useBlurVarianceShadowMap","_get_mapSize_decorators","_get_useFloat32TextureType_decorators","_get_useRedTextureFormat_decorators","_get_bias_decorators","_get_normalBias_decorators","_get_darkness_decorators","_get_filter_decorators","_get_filteringQuality_decorators","_get_transparencyShadow_decorators","_get_enableSoftTransparentShadow_decorators","_get_useOpacityTextureForTransparentShadow_decorators","DepthRendererSceneComponent","_gatherActiveCameraRenderTargets","_isReadyForMesh","_depthRenderer","depthRenderer","useOnlyInActiveCamera","getDepthMap","_Registered$66","depthRendererClass","storeNonLinearDepth","force32bitsFloat","existingRenderTargetTexture","supportFullfloat","DepthRenderer","_alphaBlendedDepth","_alphaBlendedDepthMaterialCache","_depthMap","cachedAlphaBlendedDepth","forceDepthWriteTransparentMeshes","_storeNonLinearDepth","_storeCameraSpaceZ","isPacked","RegisterDepthRendererSceneComponent","cameraIsOrtho","renderSubMesh","depth_vertex$1","depth_fragment$1","depth_vertex","depth_fragment","_ensureGaussianSplattingDepthMaterial","currentPassId","keysToDelete","DepthTextureType","ThinMinMaxReducerPostProcess","minmaxRedux_fragment","minmaxRedux_fragment$1","BufferFloat","BufferUint8","ThinMinMaxReducer","depthRedux","_depthRedux","_recreatePostProcesses","onAfterReductionPerformed","reductionSteps","setTextureDimensions","isFloat","disposeAll","reductionInitial","reduction","MinMaxReducer","_thinMinMaxReducer","_forceFullscreenViewport","_activated","_reductionSteps","_sourceTexture","setSourceTexture","deactivate","reductionStep","readMinMax","activated","_disposePostProcesses","DepthReducer","_depthRendererId","UpDir","ZeroVec","Tmpv1","Tmpv2","TmpMatrix","CascadedShadowGenerator","numCascades","_numCascades","MIN_CASCADES_COUNT","MAX_CASCADES_COUNT","_recreateSceneUBOs","freezeShadowCastersBoundingInfo","_freezeShadowCastersBoundingInfo","_freezeShadowCastersBoundingInfoObservable","_computeShadowCastersBoundingInfo","_scbiMin","_scbiMax","_shadowCastersBoundingInfo","shadowCastersBoundingInfo","setMinMaxDistance","_breaksAreDirty","_cascadeMinExtents","_cascadeMaxExtents","dbg","depthClamp","_depthClamp","cascadeBlendPercentage","_cascadeBlendPercentage","lambda","_lambda","cascadeNum","_viewMatrices","_projectionMatrices","setDepthRenderer","_depthReducer","autoCalcDepthBounds","_autoCalcDepthBounds","splitFrustum","_splitFrustum","far","cameraRange","_cascades","prevBreakDistance","breakDistance","_viewSpaceFrustumsZ","_frustumLengths","_computeMatrices","_computeFrustumInWorldSpace","_computeCascadeFrustum","castersViewMinZ","castersViewMaxZ","viewMaxZ","viewMinZ","_transformMatricesAsArray","prevSplitDist","splitDist","cameraInfiniteFarPlane","saveCameraMaxZ","cornerIndexOffset","cornerIndex","_FrustumCornersNdcSpace","invViewProj","_frustumCornersWorldSpace","_frustumCenter","lightCameraPos","usefulFloatFirst","penumbraDarkness","DEFAULT_CASCADES_COUNT","stabilizeCascades","_tempTransformMatricesAsArray","_lightSizeUVCorrection","_depthCorrection","_shadowCameraPos","getCascadeViewMatrix","getCascadeProjectionMatrix","getCascadeTransformMatrix","_Registered$65","FrameGraphShadowGeneratorTask","_createShadowGenerator","_updateShadowMap","_useFloat32TextureType","_useRedTextureFormat","_enableSoftTransparentShadow","_useOpacityTextureForTransparentShadow","_createShadowGeneratorInstance","shadowTextureHandle","FrameGraphCascadedShadowGeneratorTask","IsCascadedShadowGenerator","_stabilizeCascades","_currentAutoCalcDepthBoundsCounter","_autoCalcDepthBoundsRefreshRate","autoCalcDepthBoundsRefreshRate","p2z","p3z","zNear","zFar","minMaxTexture","_get_numCascades_decorators","_get_stabilizeCascades_decorators","_get_lambda_decorators","_get_cascadeBlendPercentage_decorators","_get_depthClamp_decorators","_get_autoCalcDepthBounds_decorators","_get_autoCalcDepthBoundsRefreshRate_decorators","_Registered$64","NodeRenderGraphCascadedShadowGeneratorBlock","ClearColors","FrameGraphGeometryRendererTask","_reverseCulling","_objectIdProvider","_meshBlendTagProvider","dontRenderWhenMaterialDepthWriteIsDisabled","textureDescriptions","_clearAttachmentsLayout","_allAttachmentsLayout","_colorAttachmentsLayout","geometryIrradianceTexture","geometryViewDepthTexture","geometryNormViewDepthTexture","geometryScreenDepthTexture","geometryViewNormalTexture","geometryWorldNormalTexture","geometryLocalPositionTexture","geometryWorldPositionTexture","geometryAlbedoTexture","geometryReflectivityTexture","geometryVelocityTexture","geometryLinearVelocityTexture","geometryObjectIdTexture","geometryMeshBlendTagTexture","excludedSkinnedMeshFromVelocityTexture","excludeSkinnedMeshFromVelocityTexture","skinnedMesh","removeExcludedSkinnedMeshFromVelocityTexture","_buildClearAttachmentsLayout","_registerForRenderPassId","outputTextureHandles","targetTextureCount","_getTargetTextureCount","needPreviousWorldMatrices","DeleteConfiguration","_targetTextures","objectIdDescription","isSupportedFormat","meshBlendTagIndex","attachmentCount","geomTextureDimensions","baseHandle","clearColorAttachments","clearAttachmentsLayout","allAttachmentsLayout","geometryDescription","layoutClearType","CreateConfiguration","sizeInPercentage","geomIrradiance","geomNormViewDepth","geomScreenDepth","geomWorldNormal","geomLocalPosition","geomWorldPosition","geomLinearVelocity","geomObjectId","textureActivation","textureFormats","irradianceFormat","viewDepthFormat","normalizedViewDepthFormat","screenDepthFormat","viewNormalFormat","worldNormalFormat","localPositionFormat","worldPositionFormat","albedoFormat","reflectivityFormat","velocityFormat","linearVelocityFormat","textureTypes","irradianceType","viewDepthType","normalizedViewDepthType","screenDepthType","viewNormalType","worldNormalType","localPositionType","worldPositionType","albedoType","reflectivityType","velocityType","linearVelocityType","bufferTypes","_get_width_decorators","_get_height_decorators","_get_sizeInPercentage_decorators","_get_reverseCulling_decorators","_get_dontRenderWhenMaterialDepthWriteIsDisabled_decorators","_get_disableDepthPrePass_decorators","_irradianceFormat_decorators","_irradianceType_decorators","_viewDepthFormat_decorators","_viewDepthType_decorators","_normalizedViewDepthFormat_decorators","_normalizedViewDepthType_decorators","_screenDepthFormat_decorators","_screenDepthType_decorators","_viewNormalFormat_decorators","_viewNormalType_decorators","_worldNormalFormat_decorators","_worldNormalType_decorators","_localPositionFormat_decorators","_localPositionType_decorators","_worldPositionFormat_decorators","_worldPositionType_decorators","_albedoFormat_decorators","_albedoType_decorators","_reflectivityFormat_decorators","_reflectivityType_decorators","_velocityFormat_decorators","_velocityType_decorators","_linearVelocityFormat_decorators","_linearVelocityType_decorators","_irradianceFormat_initializers","_irradianceType_extraInitializers","_viewDepthFormat_initializers","_viewDepthType_initializers","_viewDepthType_extraInitializers","_normalizedViewDepthFormat_initializers","_normalizedViewDepthType_initializers","_normalizedViewDepthType_extraInitializers","_screenDepthFormat_initializers","_screenDepthType_extraInitializers","_viewNormalFormat_initializers","_viewNormalType_initializers","_viewNormalType_extraInitializers","_worldNormalFormat_initializers","_worldNormalType_initializers","_worldNormalType_extraInitializers","_localPositionFormat_initializers","_localPositionType_extraInitializers","_worldPositionFormat_initializers","_worldPositionType_initializers","_albedoFormat_initializers","_albedoType_initializers","_albedoType_extraInitializers","_reflectivityFormat_initializers","_reflectivityType_initializers","_velocityFormat_initializers","_velocityType_initializers","_linearVelocityFormat_initializers","_Registered$63","NodeRenderGraphGeometryRendererBlock","InstanceNumber","textureProperty","oo","GetEnvironmentBRDFTexture","loadBRDFTexture","GetEnvironmentFuzzBRDFTexture","GetOpenPBREnvironmentBRDFTexture","BRDFTextureTools","BRDF_V_HEIGHT_CORRELATED","MS_BRDF_ENERGY_CONSERVATION","SPECULAR_GLOSSINESS_ENERGY_CONSERVATION","MIX_IBL_RADIANCE_WITH_IRRADIANCE","LEGACY_SPECULAR_ENERGY_CONSERVATION","BASE_DIFFUSE_MODEL","DIELECTRIC_SPECULAR_MODEL","CONDUCTOR_SPECULAR_MODEL","_PBRBRDFConfiguration_useSmithVisibilityHeightCorrelated_accessor_storage","_PBRBRDFConfiguration_useSphericalHarmonics_accessor_storage","_PBRBRDFConfiguration_useSpecularGlossinessInputEnergyConservation_accessor_storage","_PBRBRDFConfiguration_mixIblRadianceWithIrradiance_accessor_storage","_PBRBRDFConfiguration_useLegacySpecularEnergyConservation_accessor_storage","_PBRBRDFConfiguration_baseDiffuseModel_accessor_storage","_PBRBRDFConfiguration_dielectricSpecularModel_accessor_storage","_PBRBRDFConfiguration_conductorSpecularModel_accessor_storage","useEnergyConservation","_PBRBRDFConfiguration_useEnergyConservation_accessor_storage","useSmithVisibilityHeightCorrelated","useSphericalHarmonics","useSpecularGlossinessInputEnergyConservation","mixIblRadianceWithIrradiance","useLegacySpecularEnergyConservation","baseDiffuseModel","dielectricSpecularModel","conductorSpecularModel","_internalMarkAllSubMeshesAsMiscDirty","MaterialBRDFDefines","_useEnergyConservation_initializers","_useSmithVisibilityHeightCorrelated_initializers","DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED","_useSphericalHarmonics_initializers","_useSpecularGlossinessInputEnergyConservation_initializers","DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION","_mixIblRadianceWithIrradiance_initializers","_useLegacySpecularEnergyConservation_initializers","DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION","_baseDiffuseModel_initializers","_dielectricSpecularModel_initializers","DEFAULT_DIELECTRIC_SPECULAR_MODEL","_conductorSpecularModel_extraInitializers","_useSmithVisibilityHeightCorrelated","_useEnergyConservation","_useSphericalHarmonics","_useSpecularGlossinessInputEnergyConservation","_mixIblRadianceWithIrradiance","_useLegacySpecularEnergyConservation","_baseDiffuseModel","_dielectricSpecularModel","_conductorSpecularModel","_useEnergyConservation_decorators","_useSmithVisibilityHeightCorrelated_decorators","_useSphericalHarmonics_decorators","_useSpecularGlossinessInputEnergyConservation_decorators","_mixIblRadianceWithIrradiance_decorators","_useLegacySpecularEnergyConservation_decorators","_baseDiffuseModel_decorators","_dielectricSpecularModel_decorators","_conductorSpecularModel_decorators","_useEnergyConservation_extraInitializers","_useSmithVisibilityHeightCorrelated_extraInitializers","_useSphericalHarmonics_extraInitializers","_useSpecularGlossinessInputEnergyConservation_extraInitializers","_mixIblRadianceWithIrradiance_extraInitializers","_useLegacySpecularEnergyConservation_extraInitializers","_baseDiffuseModel_extraInitializers","DEFAULT_USE_ENERGY_CONSERVATION","DEFAULT_USE_SPHERICAL_HARMONICS","DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE","DEFAULT_DIFFUSE_MODEL","CLEARCOAT","CLEARCOAT_DEFAULTIOR","CLEARCOAT_TEXTURE","CLEARCOAT_TEXTURE_ROUGHNESS","CLEARCOAT_TEXTUREDIRECTUV","CLEARCOAT_TEXTURE_ROUGHNESSDIRECTUV","CLEARCOAT_BUMP","CLEARCOAT_BUMPDIRECTUV","CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE","CLEARCOAT_REMAP_F0","CLEARCOAT_TINT","CLEARCOAT_TINT_TEXTURE","CLEARCOAT_TINT_TEXTUREDIRECTUV","CLEARCOAT_TINT_GAMMATEXTURE","_PBRClearCoatConfiguration_indexOfRefraction_accessor_storage","_PBRClearCoatConfiguration_texture_accessor_storage","_PBRClearCoatConfiguration_useRoughnessFromMainTexture_accessor_storage","_PBRClearCoatConfiguration_textureRoughness_accessor_storage","_PBRClearCoatConfiguration_remapF0OnInterfaceChange_accessor_storage","_PBRClearCoatConfiguration_bumpTexture_accessor_storage","_PBRClearCoatConfiguration_isTintEnabled_accessor_storage","_PBRClearCoatConfiguration_tintTexture_accessor_storage","_PBRClearCoatConfiguration_isEnabled_accessor_storage","useRoughnessFromMainTexture","textureRoughness","remapF0OnInterfaceChange","isTintEnabled","tintTexture","MaterialClearCoatDefines","_DefaultIndexOfRefraction","_useRoughnessFromMainTexture","_useRoughnessFromMainTexture_initializers","_textureRoughness","_useRoughnessFromMainTexture_extraInitializers","_textureRoughness_initializers","_remapF0OnInterfaceChange","_textureRoughness_extraInitializers","_remapF0OnInterfaceChange_initializers","_remapF0OnInterfaceChange_extraInitializers","_isTintEnabled","_isTintEnabled_initializers","tintColor","_isTintEnabled_extraInitializers","_tintColor_initializers","tintColorAtDistance","_tintColor_extraInitializers","_tintColorAtDistance_initializers","tintThickness","_tintColorAtDistance_extraInitializers","_tintThickness_initializers","_tintTexture","_tintThickness_extraInitializers","_tintTexture_extraInitializers","disableBumpMap","_disableBumpMap","_indexOfRefraction","eta","_useRoughnessFromMainTexture_decorators","_textureRoughness_decorators","_remapF0OnInterfaceChange_decorators","_isTintEnabled_decorators","_tintColor_decorators","_tintColorAtDistance_decorators","_tintThickness_decorators","_tintTexture_decorators","_tintTexture_initializers","_intensity_extraInitializers","IRIDESCENCE","IRIDESCENCE_TEXTURE","IRIDESCENCE_TEXTUREDIRECTUV","IRIDESCENCE_THICKNESS_TEXTURE","IRIDESCENCE_THICKNESS_TEXTUREDIRECTUV","_PBRIridescenceConfiguration_texture_accessor_storage","_PBRIridescenceConfiguration_thicknessTexture_accessor_storage","_PBRIridescenceConfiguration_isEnabled_accessor_storage","thicknessTexture","MaterialIridescenceDefines","minimumThickness","_minimumThickness_initializers","_DefaultMinimumThickness","maximumThickness","_minimumThickness_extraInitializers","_maximumThickness_initializers","_DefaultMaximumThickness","_maximumThickness_extraInitializers","_thicknessTexture","_thicknessTexture_extraInitializers","_minimumThickness_decorators","_maximumThickness_decorators","_thicknessTexture_decorators","ANISOTROPIC","ANISOTROPIC_TEXTURE","ANISOTROPIC_TEXTUREDIRECTUV","ANISOTROPIC_LEGACY","_PBRAnisotropicConfiguration_texture_accessor_storage","_PBRAnisotropicConfiguration_legacy_accessor_storage","_PBRAnisotropicConfiguration_isEnabled_accessor_storage","legacy","MaterialAnisotropicDefines","_direction_initializers","_direction_extraInitializers","_legacy","_legacy_extraInitializers","_legacy_decorators","_legacy_initializers","SHEEN","SHEEN_TEXTURE","SHEEN_GAMMATEXTURE","SHEEN_TEXTURE_ROUGHNESS","SHEEN_TEXTUREDIRECTUV","SHEEN_TEXTURE_ROUGHNESSDIRECTUV","SHEEN_LINKWITHALBEDO","SHEEN_ROUGHNESS","SHEEN_ALBEDOSCALING","SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE","_PBRSheenConfiguration_linkSheenWithAlbedo_accessor_storage","_PBRSheenConfiguration_texture_accessor_storage","_PBRSheenConfiguration_useRoughnessFromMainTexture_accessor_storage","_PBRSheenConfiguration_roughness_accessor_storage","_PBRSheenConfiguration_textureRoughness_accessor_storage","_PBRSheenConfiguration_albedoScaling_accessor_storage","_PBRSheenConfiguration_isEnabled_accessor_storage","linkSheenWithAlbedo","albedoScaling","MaterialSheenDefines","_linkSheenWithAlbedo","_linkSheenWithAlbedo_initializers","_linkSheenWithAlbedo_extraInitializers","_color_initializers","_color_extraInitializers","_albedoScaling","_albedoScaling_extraInitializers","_linkSheenWithAlbedo_decorators","_color_decorators","_albedoScaling_decorators","_albedoScaling_initializers","SUBSURFACE","SS_REFRACTION","SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS","SS_TRANSLUCENCY","SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS","SS_SCATTERING","SS_DISPERSION","SS_THICKNESSANDMASK_TEXTURE","SS_THICKNESSANDMASK_TEXTUREDIRECTUV","SS_HAS_THICKNESS","SS_REFRACTIONINTENSITY_TEXTURE","SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV","SS_TRANSLUCENCYINTENSITY_TEXTURE","SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV","SS_TRANSLUCENCYCOLOR_TEXTURE","SS_TRANSLUCENCYCOLOR_TEXTUREDIRECTUV","SS_TRANSLUCENCYCOLOR_TEXTURE_GAMMA","SS_REFRACTIONMAP_3D","SS_REFRACTIONMAP_OPPOSITEZ","SS_LODINREFRACTIONALPHA","SS_GAMMAREFRACTION","SS_RGBDREFRACTION","SS_LINEARSPECULARREFRACTION","SS_LINKREFRACTIONTOTRANSPARENCY","SS_ALBEDOFORREFRACTIONTINT","SS_ALBEDOFORTRANSLUCENCYTINT","SS_USE_LOCAL_REFRACTIONMAP_CUBIC","SS_USE_THICKNESS_AS_DEPTH","SS_USE_GLTF_TEXTURES","SS_APPLY_ALBEDO_AFTER_SUBSURFACE","SS_TRANSLUCENCY_LEGACY","_PBRSubSurfaceConfiguration_isTranslucencyEnabled_accessor_storage","_PBRSubSurfaceConfiguration_isDispersionEnabled_accessor_storage","_PBRSubSurfaceConfiguration_isScatteringEnabled_accessor_storage","_PBRSubSurfaceConfiguration_useAlbedoToTintRefraction_accessor_storage","_PBRSubSurfaceConfiguration_useAlbedoToTintTranslucency_accessor_storage","_PBRSubSurfaceConfiguration_thicknessTexture_accessor_storage","_PBRSubSurfaceConfiguration_refractionTexture_accessor_storage","_PBRSubSurfaceConfiguration_indexOfRefraction_accessor_storage","_PBRSubSurfaceConfiguration_invertRefractionY_accessor_storage","_PBRSubSurfaceConfiguration_linkRefractionWithTransparency_accessor_storage","_PBRSubSurfaceConfiguration_useMaskFromThicknessTexture_accessor_storage","_PBRSubSurfaceConfiguration_refractionIntensityTexture_accessor_storage","_PBRSubSurfaceConfiguration_translucencyIntensityTexture_accessor_storage","_PBRSubSurfaceConfiguration_translucencyColorTexture_accessor_storage","_PBRSubSurfaceConfiguration_useGltfStyleTextures_accessor_storage","isRefractionEnabled","_PBRSubSurfaceConfiguration_isRefractionEnabled_accessor_storage","isTranslucencyEnabled","isDispersionEnabled","isScatteringEnabled","scatteringDiffusionProfile","subSurfaceConfiguration","ssDiffusionProfileColors","_scatteringDiffusionProfileIndex","addDiffusionProfile","useAlbedoToTintRefraction","useAlbedoToTintTranslucency","volumeIndexOfRefraction","_volumeIndexOfRefraction","linkRefractionWithTransparency","useMaskFromThicknessTexture","refractionIntensityTexture","translucencyIntensityTexture","translucencyColorTexture","useGltfStyleTextures","legacyTransluceny","legacyTranslucency","_isRefractionEnabled","_isTranslucencyEnabled","_isScatteringEnabled","_markScenePrePassDirty","_internalMarkScenePrePassDirty","MaterialSubSurfaceDefines","_isRefractionEnabled_initializers","_isRefractionEnabled_extraInitializers","_isTranslucencyEnabled_initializers","_isDispersionEnabled","_isTranslucencyEnabled_extraInitializers","_isDispersionEnabled_initializers","_isDispersionEnabled_extraInitializers","_isScatteringEnabled_initializers","_isScatteringEnabled_extraInitializers","__scatteringDiffusionProfileIndex_initializers","refractionIntensity","__scatteringDiffusionProfileIndex_extraInitializers","_refractionIntensity_initializers","translucencyIntensity","_refractionIntensity_extraInitializers","_translucencyIntensity_initializers","_useAlbedoToTintRefraction","_translucencyIntensity_extraInitializers","_useAlbedoToTintRefraction_initializers","_useAlbedoToTintTranslucency","_useAlbedoToTintRefraction_extraInitializers","_useAlbedoToTintTranslucency_initializers","_useAlbedoToTintTranslucency_extraInitializers","_thicknessTexture_initializers","__volumeIndexOfRefraction_initializers","_invertRefractionY","__volumeIndexOfRefraction_extraInitializers","_linkRefractionWithTransparency","_linkRefractionWithTransparency_initializers","_linkRefractionWithTransparency_extraInitializers","useThicknessAsDepth","_useThicknessAsDepth_initializers","_useThicknessAsDepth_extraInitializers","dispersion","_dispersion_initializers","diffusionDistance","_dispersion_extraInitializers","_diffusionDistance_initializers","_useMaskFromThicknessTexture","_diffusionDistance_extraInitializers","_useMaskFromThicknessTexture_initializers","_refractionIntensityTexture","_useMaskFromThicknessTexture_extraInitializers","_refractionIntensityTexture_initializers","_translucencyIntensityTexture","_refractionIntensityTexture_extraInitializers","_translucencyIntensityTexture_initializers","translucencyColor","_translucencyIntensityTexture_extraInitializers","_translucencyColor_initializers","_translucencyColorTexture","_translucencyColor_extraInitializers","_translucencyColorTexture_initializers","_useGltfStyleTextures","_translucencyColorTexture_extraInitializers","_useGltfStyleTextures_initializers","applyAlbedoAfterSubSurface","_useGltfStyleTextures_extraInitializers","_applyAlbedoAfterSubSurface_initializers","DEFAULT_APPLY_ALBEDO_AFTERSUBSURFACE","_applyAlbedoAfterSubSurface_extraInitializers","_legacyTranslucency_initializers","DEFAULT_LEGACY_TRANSLUCENCY","_legacyTranslucency_extraInitializers","_getRefractionTexture","thicknessScale","lodBasedMicrosurface","refractionIor","disableAlphaBlending","_isRefractionEnabled_decorators","_isTranslucencyEnabled_decorators","_isDispersionEnabled_decorators","_isScatteringEnabled_decorators","__scatteringDiffusionProfileIndex_decorators","_refractionIntensity_decorators","_translucencyIntensity_decorators","_useAlbedoToTintRefraction_decorators","_useAlbedoToTintTranslucency_decorators","__volumeIndexOfRefraction_decorators","_linkRefractionWithTransparency_decorators","_useThicknessAsDepth_decorators","_dispersion_decorators","_diffusionDistance_decorators","_useMaskFromThicknessTexture_decorators","_refractionIntensityTexture_decorators","_translucencyIntensityTexture_decorators","_translucencyColor_decorators","_translucencyColorTexture_decorators","_useGltfStyleTextures_decorators","_applyAlbedoAfterSubSurface_decorators","_legacyTranslucency_decorators","onCreatedEffectParameters$2","PBRMaterialDefinesBase","PBRMaterialDefines","PBR","ALBEDO","GAMMAALBEDO","ALBEDODIRECTUV","BASE_WEIGHT","BASE_WEIGHTDIRECTUV","BASE_DIFFUSE_ROUGHNESS","BASE_DIFFUSE_ROUGHNESSDIRECTUV","AMBIENTINGRAYSCALE","ALPHAFROMALBEDO","ALPHATESTVALUE","RADIANCEOVERALPHA","ALPHAFRESNEL","LINEARALPHAFRESNEL","GAMMAEMISSIVE","REFLECTIVITY","REFLECTIVITY_GAMMA","REFLECTIVITYDIRECTUV","MICROSURFACEFROMREFLECTIVITYMAP","MICROSURFACEAUTOMATIC","MICROSURFACEMAP","MICROSURFACEMAPDIRECTUV","METALLICWORKFLOW","ROUGHNESSSTOREINMETALMAPALPHA","ROUGHNESSSTOREINMETALMAPGREEN","METALLNESSSTOREINMETALMAPBLUE","AOSTOREINMETALMAPRED","METALLIC_REFLECTANCE","METALLIC_REFLECTANCE_GAMMA","METALLIC_REFLECTANCEDIRECTUV","METALLIC_REFLECTANCE_USE_ALPHA_ONLY","REFLECTANCE","REFLECTANCE_GAMMA","REFLECTANCEDIRECTUV","ENVIRONMENTBRDF","ENVIRONMENTBRDF_RGBD","NORMALXYSCALE","GAMMALIGHTMAP","RADIANCEOCCLUSION","HORIZONOCCLUSION","USEPHYSICALLIGHTFALLOFF","USEGLTFLIGHTFALLOFF","MIRRORED","FORCENORMALFORWARD","SPECULARAA","UNLIT","DEBUGMODE","PBRBaseMaterialBase","_realTimeFiltering","_realTimeFilteringQuality","_PBRBaseMaterial_debugMode_accessor_storage","_directIntensity","_emissiveIntensity","_environmentIntensity","_specularIntensity","_lightingInfos","_albedoTexture","_baseWeightTexture","_baseDiffuseRoughnessTexture","_ambientTextureStrength","_ambientTextureImpactOnAnalyticalLights","DEFAULT_AO_ON_ANALYTICAL_LIGHTS","_reflectivityTexture","_metallicTexture","_metallic","_metallicF0Factor","_metallicReflectanceColor","_useOnlyMetallicFromMetallicReflectanceTexture","_metallicReflectanceTexture","_reflectanceTexture","_microSurfaceTexture","_ambientColor","_albedoColor","_baseWeight","_baseDiffuseRoughness","_reflectivityColor","_reflectionColor","_emissiveColor","_microSurface","_useHorizonOcclusion","_useRadianceOcclusion","_useMicroSurfaceFromReflectivityMapAlpha","_useRoughnessFromMetallicTextureAlpha","_useRoughnessFromMetallicTextureGreen","_useMetallnessFromMetallicTextureBlue","_useAmbientOcclusionFromMetallicTextureRed","_useAmbientInGrayScale","_useAutoMicroSurfaceFromReflectivityMap","_lightFalloff","_useRadianceOverAlpha","_parallaxScaleBias","_alphaCutOff","_useAlphaFresnel","_useLinearAlphaFresnel","_environmentBRDFTexture","_forceIrradianceInFragment","_forceNormalForward","_enableSpecularAntiAliasing","_unlit","_breakShaderLoadedCheck","_debugMode_initializers","debugLimit","_debugMode_extraInitializers","debugFactor","brdf","PBRBRDFConfiguration","clearCoat","iridescence","PBRIridescenceConfiguration","PBRAnisotropicConfiguration","sheen","PBRSheenConfiguration","subSurface","PBRSubSurfaceConfiguration","PBRMATERIAL_OPAQUE","_shouldUseAlphaFromAlbedoTexture","PBRMATERIAL_ALPHATEST","_getReflectionTexture","createNormals","isMetallicWorkflow","_prepareDefines","AddSamplers","useSHInFragment","PrepareDefinesForMisc","ior","outsideIOR","environmentBRDFTexture","_debugMode_decorators","PBRMATERIAL_ALPHABLEND","PBRMATERIAL_ALPHATESTANDBLEND","PBRBaseMaterial","RENDER_WITH_IBL_SHADOWS","COLORED_IBL_SHADOWS","iblShadowsTexture","_iblShadowsTexture","isColored","_isColored","_IBLShadowsPluginMaterial_isEnabled_accessor_storage","MaterialIBLShadowsRenderDefines","shadowOpacity","_shadowOpacity_initializers","_shadowOpacity_extraInitializers","_isOpenPBRMaterial","frag","_shadowOpacity_decorators","GeometryBufferRendererSceneComponent","_geometryBufferRenderer","getGBuffer","_Registered$61","geometryBufferRendererClass","textureTypesAndFormats","_enableMeshBlendTag","_enableObjectId","_linkedWithPrePass","_multiRenderTarget","_unlinkPrePassRenderer","_createRenderTargets","_resetLayout","_enableDepth","_enableNormal","_enablePosition","_enableReflectivity","_enableVelocity","_enableVelocityLinear","_enableScreenspaceDepth","_enableIrradiance","_attachmentsFromPrePass","_forceTextureType","geometryBufferType","GeometryBufferRenderer","POSITION_TEXTURE_TYPE","_positionIndex","VELOCITY_TEXTURE_TYPE","_velocityIndex","VELOCITY_LINEAR_TEXTURE_TYPE","_velocityLinearIndex","REFLECTIVITY_TEXTURE_TYPE","_reflectivityIndex","DEPTH_TEXTURE_TYPE","_depthIndex","NORMAL_TEXTURE_TYPE","_normalIndex","SCREENSPACE_DEPTH_TEXTURE_TYPE","_screenspaceDepthIndex","IRRADIANCE_TEXTURE_TYPE","_irradianceIndex","OBJECT_ID_TEXTURE_TYPE","_objectIdIndex","MESH_BLEND_TAG_TEXTURE_TYPE","_meshBlendTagIndex","_setAttachments","enableDepth","enableNormal","enablePosition","enableVelocity","_previousTransformationMatrices","enableVelocityLinear","enableReflectivity","enableScreenspaceDepth","enableIrradiance","enableObjectId","_assignRenderTargetIndices","enableMeshBlendingTag","_ratioOrDimensions","ratioOrDimensions","_previousBonesTransformationMatrices","excludedSkinnedMeshesFromVelocity","_clearDepthColor","generateIrradianceWithScatterMask","_useUbo","_depthFormat","RegisterGeometryBufferRendererSceneComponent","geometry_vertex","geometry_fragment","geometry_vertex$1","geometry_fragment$1","needUv","geometryNormalTexture","metallicRoughnessTexture","metallicWorkflow","metallic","baseColor","specularGlossinessTexture","glossiness","metallicTexture","albedoTexture","albedoColor","microSurface","openpbrMaterial","baseMetalnessTexture","specularRoughnessTexture","subsurfaceWeight","subsurfaceWeightTexture","transmissionWeight","transmissionWeightTexture","iblDefines","realtime","realtimeQuality","realtimeFiltering","realtimeFilteringQuality","postProcessRenderPipelineManager","supportedPipelines","iblShadowsPipeline","_getAccumulatedTexture","coloredShadows","buffersCount","_textureTypesAndFormats","textureTypesAndFormat","_getRenderTargetDimensions","typeAndFormat","layoutAttachmentsAll","layoutAttachmentsAllButDepth","layoutAttachmentsDepthOnly","attachmentsAll","attachmentsAllButDepth","attachmentsDepthOnly","useSpecificClearForDepthTexture","bonesTransformations","_copyBonesTransformationMatrices","reflectivityColor","baseMetalness","specularRoughness","shadowTexture","transmissionScatterAnisotropy","subsurfaceScatterAnisotropy","_Registered$60","onCreatedEffectParameters$1","_GetComponentCount","populateVectorFromLinkedProperties","destinationSize","linkedProperties","propKey","targetUniformComponentOffset","_tmpArray","componentNum","firstLinkedKey","Property","targetUniformComponentNum","targetUniformName","requiredDefine","Sampler","samplerPrefix","samplerInfoName","samplerMatrixName","textureDefine","OpenPBRMaterialDefinesBase","OpenPBRMaterialDefinesWithEnvLighting","EnvironmentLightingDefinesMixin","OpenPBRMaterialDefines","LIGHTCOUNT","ALPHA_FROM_BASE_COLOR_TEXTURE","SPECULAR_ROUGHNESS_FROM_METALNESS_TEXTURE_GREEN","BASE_METALNESS_FROM_METALNESS_TEXTURE_BLUE","SPECULAR_WEIGHT_IN_ALPHA","SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE","SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE","COAT_ROUGHNESS_FROM_GREEN_CHANNEL","COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE","USE_GLTF_STYLE_ANISOTROPY","THIN_FILM_THICKNESS_FROM_THIN_FILM_TEXTURE","FUZZ_ROUGHNESS_FROM_TEXTURE_ALPHA","SUBSURFACE_WEIGHT_FROM_TEXTURE_ALPHA","GEOMETRY_THICKNESS_FROM_GREEN_CHANNEL","FUZZENVIRONMENTBRDF","ANISOTROPIC_OPENPBR","ANISOTROPIC_BASE","ANISOTROPIC_COAT","FUZZ_IBL_SAMPLES","REFRACTION_HIGH_QUALITY_BLUR","FUZZ","THIN_FILM","DISPERSION","SCATTERING","USE_IRRADIANCE_TEXTURE_FOR_SCATTERING","SSS_SAMPLE_COUNT","USE_IRRADIANCE_TEXTURE_FOR_SCATTERING_GBUFFER","TRANSMISSION_SLAB","TRANSMISSION_SLAB_VOLUME","SUBSURFACE_SLAB","GEOMETRY_THIN_WALLED","REFRACTED_BACKGROUND","REFRACTED_LIGHTS","REFRACTED_ENVIRONMENT","REFRACTED_ENVIRONMENT_OPPOSITEZ","REFRACTED_ENVIRONMENT_LOCAL_CUBE","OpenPBRMaterialBase","_OpenPBRMaterial_baseWeightTexture_accessor_storage","_OpenPBRMaterial_baseColor_accessor_storage","_OpenPBRMaterial_baseColorTexture_accessor_storage","_OpenPBRMaterial_baseDiffuseRoughness_accessor_storage","_OpenPBRMaterial_baseDiffuseRoughnessTexture_accessor_storage","_OpenPBRMaterial_baseMetalness_accessor_storage","_OpenPBRMaterial_baseMetalnessTexture_accessor_storage","_OpenPBRMaterial_specularWeight_accessor_storage","_OpenPBRMaterial_specularWeightTexture_accessor_storage","_OpenPBRMaterial_specularColor_accessor_storage","_OpenPBRMaterial_specularColorTexture_accessor_storage","_OpenPBRMaterial_specularRoughness_accessor_storage","_OpenPBRMaterial_specularRoughnessTexture_accessor_storage","_OpenPBRMaterial_specularRoughnessAnisotropy_accessor_storage","_OpenPBRMaterial_specularRoughnessAnisotropyTexture_accessor_storage","_OpenPBRMaterial_specularIor_accessor_storage","_OpenPBRMaterial_transmissionWeight_accessor_storage","_OpenPBRMaterial_transmissionWeightTexture_accessor_storage","_OpenPBRMaterial_transmissionColor_accessor_storage","_OpenPBRMaterial_transmissionColorTexture_accessor_storage","_OpenPBRMaterial_transmissionDepth_accessor_storage","_OpenPBRMaterial_transmissionDepthTexture_accessor_storage","_OpenPBRMaterial_transmissionScatter_accessor_storage","_OpenPBRMaterial_transmissionScatterTexture_accessor_storage","_OpenPBRMaterial_transmissionScatterAnisotropy_accessor_storage","_OpenPBRMaterial_transmissionDispersionScale_accessor_storage","_OpenPBRMaterial_transmissionDispersionScaleTexture_accessor_storage","_OpenPBRMaterial_transmissionDispersionAbbeNumber_accessor_storage","_OpenPBRMaterial_subsurfaceWeight_accessor_storage","_OpenPBRMaterial_subsurfaceWeightTexture_accessor_storage","_OpenPBRMaterial_subsurfaceColor_accessor_storage","_OpenPBRMaterial_subsurfaceColorTexture_accessor_storage","_OpenPBRMaterial_subsurfaceRadius_accessor_storage","_OpenPBRMaterial_subsurfaceRadiusScale_accessor_storage","_OpenPBRMaterial_subsurfaceRadiusScaleTexture_accessor_storage","_OpenPBRMaterial_subsurfaceScatterAnisotropy_accessor_storage","_OpenPBRMaterial_coatWeight_accessor_storage","_OpenPBRMaterial_coatWeightTexture_accessor_storage","_OpenPBRMaterial_coatColor_accessor_storage","_OpenPBRMaterial_coatColorTexture_accessor_storage","_OpenPBRMaterial_coatRoughness_accessor_storage","_OpenPBRMaterial_coatRoughnessTexture_accessor_storage","_OpenPBRMaterial_coatRoughnessAnisotropy_accessor_storage","_OpenPBRMaterial_coatRoughnessAnisotropyTexture_accessor_storage","_OpenPBRMaterial_coatIor_accessor_storage","_OpenPBRMaterial_coatDarkening_accessor_storage","_OpenPBRMaterial_coatDarkeningTexture_accessor_storage","_OpenPBRMaterial_fuzzWeight_accessor_storage","_OpenPBRMaterial_fuzzWeightTexture_accessor_storage","_OpenPBRMaterial_fuzzColor_accessor_storage","_OpenPBRMaterial_fuzzColorTexture_accessor_storage","_OpenPBRMaterial_fuzzRoughness_accessor_storage","_OpenPBRMaterial_fuzzRoughnessTexture_accessor_storage","_OpenPBRMaterial_geometryThinWalled_accessor_storage","_OpenPBRMaterial_geometryNormalTexture_accessor_storage","_OpenPBRMaterial_geometryTangent_accessor_storage","_OpenPBRMaterial_geometryTangentTexture_accessor_storage","_OpenPBRMaterial_geometryCoatNormalTexture_accessor_storage","_OpenPBRMaterial_geometryCoatTangent_accessor_storage","_OpenPBRMaterial_geometryCoatTangentTexture_accessor_storage","_OpenPBRMaterial_geometryOpacity_accessor_storage","_OpenPBRMaterial_geometryOpacityTexture_accessor_storage","_OpenPBRMaterial_geometryThickness_accessor_storage","_OpenPBRMaterial_geometryThicknessTexture_accessor_storage","_OpenPBRMaterial_emissionLuminance_accessor_storage","_OpenPBRMaterial_emissionColor_accessor_storage","_OpenPBRMaterial_emissionColorTexture_accessor_storage","_OpenPBRMaterial_thinFilmWeight_accessor_storage","_OpenPBRMaterial_thinFilmWeightTexture_accessor_storage","_OpenPBRMaterial_thinFilmThickness_accessor_storage","_OpenPBRMaterial_thinFilmThicknessMin_accessor_storage","_OpenPBRMaterial_thinFilmThicknessTexture_accessor_storage","_OpenPBRMaterial_thinFilmIor_accessor_storage","_OpenPBRMaterial_ambientOcclusionTexture_accessor_storage","_OpenPBRMaterial_directIntensity_accessor_storage","_OpenPBRMaterial_environmentIntensity_accessor_storage","_OpenPBRMaterial_useSpecularWeightFromTextureAlpha_accessor_storage","_OpenPBRMaterial_forceAlphaTest_accessor_storage","_OpenPBRMaterial_alphaCutOff_accessor_storage","_OpenPBRMaterial_useAmbientOcclusionFromMetallicTextureRed_accessor_storage","_OpenPBRMaterial_useAmbientInGrayScale_accessor_storage","_OpenPBRMaterial_useObjectSpaceNormalMap_accessor_storage","_OpenPBRMaterial_useParallax_accessor_storage","_OpenPBRMaterial_useParallaxOcclusion_accessor_storage","_OpenPBRMaterial_parallaxScaleBias_accessor_storage","_OpenPBRMaterial_disableLighting_accessor_storage","_OpenPBRMaterial_forceIrradianceInFragment_accessor_storage","_OpenPBRMaterial_maxSimultaneousLights_accessor_storage","_OpenPBRMaterial_invertNormalMapX_accessor_storage","_OpenPBRMaterial_invertNormalMapY_accessor_storage","_OpenPBRMaterial_twoSidedLighting_accessor_storage","_OpenPBRMaterial_useAlphaFresnel_accessor_storage","_OpenPBRMaterial_useLinearAlphaFresnel_accessor_storage","_OpenPBRMaterial_environmentBRDFTexture_accessor_storage","_OpenPBRMaterial_forceNormalForward_accessor_storage","_OpenPBRMaterial_enableSpecularAntiAliasing_accessor_storage","_OpenPBRMaterial_useHorizonOcclusion_accessor_storage","_OpenPBRMaterial_useRadianceOcclusion_accessor_storage","_OpenPBRMaterial_unlit_accessor_storage","_OpenPBRMaterial_applyDecalMapAfterDetailMap_accessor_storage","_OpenPBRMaterial_debugMode_accessor_storage","baseWeight","_OpenPBRMaterial_baseWeight_accessor_storage","baseWeightTexture","baseDiffuseRoughness","baseDiffuseRoughnessTexture","specularWeight","specularWeightTexture","specularColorTexture","specularRoughnessAnisotropy","specularRoughnessAnisotropyTexture","specularIor","transmissionColor","transmissionColorTexture","transmissionDepth","transmissionDepthTexture","transmissionScatter","transmissionScatterTexture","transmissionDispersionScale","transmissionDispersionScaleTexture","transmissionDispersionAbbeNumber","subsurfaceColor","subsurfaceColorTexture","subsurfaceRadius","subsurfaceRadiusScale","subsurfaceRadiusScaleTexture","coatWeight","coatWeightTexture","coatColor","coatColorTexture","coatRoughness","coatRoughnessTexture","coatRoughnessAnisotropy","coatRoughnessAnisotropyTexture","coatIor","coatDarkening","coatDarkeningTexture","fuzzWeight","fuzzWeightTexture","fuzzColor","fuzzColorTexture","fuzzRoughness","fuzzRoughnessTexture","geometryThinWalled","geometryTangent","geometryTangentAngle","geometryTangentTexture","geometryCoatNormalTexture","geometryCoatTangent","geometryCoatTangentAngle","geometryCoatTangentTexture","geometryOpacity","geometryOpacityTexture","geometryThickness","geometryThicknessTexture","emissionLuminance","emissionColor","emissionColorTexture","thinFilmWeight","thinFilmWeightTexture","thinFilmThickness","thinFilmThicknessMin","thinFilmThicknessTexture","thinFilmIor","ambientOcclusionTexture","sssQuality","_sssQuality","sssIrradianceTexture","_sssIrradianceTexture","sssDepthTexture","_sssDepthTexture","directIntensity","useSpecularWeightFromTextureAlpha","forceAlphaTest","useAmbientOcclusionFromMetallicTextureRed","useAmbientInGrayScale","hasTransparency","hasScattering","usePhysicalLightFalloff","useGLTFLightFalloff","forceIrradianceInFragment","useAlphaFresnel","useLinearAlphaFresnel","forceNormalForward","enableSpecularAntiAliasing","useHorizonOcclusion","useRadianceOcclusion","unlit","backgroundRefractionTexture","_backgroundRefractionTexture","refractionHighQualityBlur","_refractionHighQualityBlur","fuzzSampleNumber","_fuzzSampleNumber","_baseWeight_extraInitializers","_baseColor","_baseColor_extraInitializers","_baseColorTexture","_baseColorTexture_extraInitializers","_baseDiffuseRoughness_extraInitializers","_baseDiffuseRoughnessTexture_extraInitializers","_baseMetalness","_baseMetalness_extraInitializers","_baseMetalnessTexture","_specularWeight","_specularWeight_extraInitializers","_specularWeightTexture","_specularColor","_specularColorTexture","_specularColorTexture_extraInitializers","_specularRoughness","_specularRoughness_extraInitializers","_specularRoughnessTexture","_specularRoughnessTexture_extraInitializers","_specularRoughnessAnisotropy","_specularRoughnessAnisotropy_extraInitializers","_specularRoughnessAnisotropyTexture","_specularRoughnessAnisotropyTexture_extraInitializers","_specularIor","_specularIor_extraInitializers","_transmissionWeight","_transmissionWeight_extraInitializers","_transmissionWeightTexture","_transmissionColor","_transmissionColor_extraInitializers","_transmissionColorTexture","_transmissionDepth","_transmissionDepth_extraInitializers","_transmissionDepthTexture","_transmissionDepthTexture_extraInitializers","_transmissionScatter","_transmissionScatter_extraInitializers","_transmissionScatterTexture","_transmissionScatterTexture_extraInitializers","_transmissionScatterAnisotropy","_transmissionScatterAnisotropy_extraInitializers","_transmissionDispersionScale","_transmissionDispersionScale_extraInitializers","_transmissionDispersionScaleTexture","_transmissionDispersionScaleTexture_extraInitializers","_transmissionDispersionAbbeNumber","_transmissionDispersionAbbeNumber_extraInitializers","_subsurfaceWeight","_subsurfaceWeight_extraInitializers","_subsurfaceWeightTexture","_subsurfaceColor","_subsurfaceColor_extraInitializers","_subsurfaceColorTexture","_subsurfaceRadius","_subsurfaceRadius_extraInitializers","_subsurfaceRadiusScale","_subsurfaceRadiusScale_extraInitializers","_subsurfaceRadiusScaleTexture","_subsurfaceRadiusScaleTexture_extraInitializers","_subsurfaceScatterAnisotropy","_subsurfaceScatterAnisotropy_extraInitializers","_coatWeight","_coatWeight_extraInitializers","_coatWeightTexture","_coatColor","_coatColor_extraInitializers","_coatColorTexture","_coatColorTexture_extraInitializers","_coatRoughness","_coatRoughness_extraInitializers","_coatRoughnessTexture","_coatRoughnessTexture_extraInitializers","_coatRoughnessAnisotropy","_coatRoughnessAnisotropy_extraInitializers","_coatRoughnessAnisotropyTexture","_coatRoughnessAnisotropyTexture_extraInitializers","_coatIor","_coatIor_extraInitializers","_coatDarkening","_coatDarkening_extraInitializers","_coatDarkeningTexture","_coatDarkeningTexture_extraInitializers","useCoatRoughnessFromWeightTexture","_fuzzWeight","_fuzzWeight_extraInitializers","_fuzzWeightTexture","_fuzzColor","_fuzzColor_extraInitializers","_fuzzColorTexture","_fuzzColorTexture_extraInitializers","_fuzzRoughness","_fuzzRoughness_extraInitializers","_fuzzRoughnessTexture","_fuzzRoughnessTexture_extraInitializers","_geometryThinWalled","_geometryThinWalled_extraInitializers","_geometryNormalTexture","_geometryTangent","_geometryTangent_extraInitializers","_geometryTangentTexture","_geometryTangentTexture_extraInitializers","_geometryCoatNormalTexture","_geometryCoatTangent","_geometryCoatTangent_extraInitializers","_geometryCoatTangentTexture","_geometryCoatTangentTexture_extraInitializers","_geometryOpacity","_geometryOpacity_extraInitializers","_geometryOpacityTexture","_geometryOpacityTexture_extraInitializers","_geometryThickness","_geometryThickness_extraInitializers","_geometryThicknessTexture","_emissionLuminance","_emissionLuminance_extraInitializers","_emissionColor","_emissionColor_extraInitializers","_emissionColorTexture","_thinFilmWeight","_thinFilmWeight_extraInitializers","_thinFilmWeightTexture","_thinFilmWeightTexture_extraInitializers","_thinFilmThickness","_thinFilmThickness_extraInitializers","_thinFilmThicknessMin","_thinFilmThicknessMin_extraInitializers","_thinFilmThicknessTexture","_thinFilmThicknessTexture_extraInitializers","_thinFilmIor","_thinFilmIor_extraInitializers","_ambientOcclusionTexture","_ambientOcclusionTexture_extraInitializers","SSS_QUALITY_MEDIUM","_uniformsList","_uniformsArray","_samplersList","_samplerDefines","_directIntensity_initializers","_directIntensity_extraInitializers","_useSpecularWeightFromTextureAlpha_initializers","_forceAlphaTest_initializers","_useAmbientOcclusionFromMetallicTextureRed_extraInitializers","_useAmbientInGrayScale_initializers","_parallaxScaleBias_initializers","_forceIrradianceInFragment_initializers","_useAlphaFresnel_initializers","_useAlphaFresnel_extraInitializers","_useLinearAlphaFresnel_initializers","_environmentBRDFTexture_initializers","_environmentBRDFTexture_extraInitializers","_forceNormalForward_initializers","_enableSpecularAntiAliasing_extraInitializers","_useHorizonOcclusion_initializers","_useRadianceOcclusion_initializers","_useRadianceOcclusion_extraInitializers","_unlit_initializers","_unlit_extraInitializers","_radianceTexture","_useSpecularWeightFromAlpha","_useSpecularWeightFromSpecularColorTexture","_useSpecularRoughnessAnisotropyFromTangentTexture","_useCoatRoughnessAnisotropyFromTangentTexture","_useCoatRoughnessFromGreenChannel","_useGltfStyleAnisotropy","_useFuzzRoughnessFromTextureAlpha","_useSubsurfaceWeightFromTextureAlpha","_useAlphaFromBaseColorTexture","_useMetallicFromMetallicTextureBlue","_useThinFilmThicknessFromTextureGreen","_useGeometryThicknessFromGreenChannel","_environmentFuzzBRDFTexture","_noiseTextures","_propertyList","samplerKey","_shouldUseAlphaFromBaseColorTexture","radianceTexture","_getRadianceTexture","uniformsArray","renderTargetWidth","openPBREnvironmentBRDFTexture","environmentFuzzBRDFTexture","usingGBuffer","geometryBufferRenderer","irradianceTextureIndex","getTextureIndex","depthIndex","_ambientOcclusionTexture_decorators","_directIntensity_decorators","_environmentIntensity_decorators","_useSpecularWeightFromTextureAlpha_decorators","_forceAlphaTest_decorators","_useAmbientOcclusionFromMetallicTextureRed_decorators","_useAmbientInGrayScale_decorators","_get_usePhysicalLightFalloff_decorators","_get_useGLTFLightFalloff_decorators","_forceIrradianceInFragment_decorators","_useAlphaFresnel_decorators","_environmentBRDFTexture_decorators","_forceNormalForward_decorators","_enableSpecularAntiAliasing_decorators","_useHorizonOcclusion_decorators","_useRadianceOcclusion_decorators","_unlit_decorators","_baseWeight_decorators","_baseWeight_initializers","_baseWeightTexture_decorators","_baseWeightTexture_extraInitializers","_baseColor_decorators","_baseColor_initializers","_baseColorTexture_decorators","_baseColorTexture_initializers","_baseDiffuseRoughness_decorators","_baseDiffuseRoughness_initializers","_baseDiffuseRoughnessTexture_decorators","_baseDiffuseRoughnessTexture_initializers","_baseMetalness_decorators","_baseMetalness_initializers","_baseMetalnessTexture_decorators","_baseMetalnessTexture_initializers","_baseMetalnessTexture_extraInitializers","_specularWeight_decorators","_specularWeight_initializers","_specularWeightTexture_decorators","_specularWeightTexture_extraInitializers","_specularColorTexture_decorators","_specularColorTexture_initializers","_specularRoughness_decorators","_specularRoughness_initializers","_specularRoughnessTexture_decorators","_specularRoughnessTexture_initializers","_specularRoughnessAnisotropy_decorators","_specularRoughnessAnisotropy_initializers","_specularRoughnessAnisotropyTexture_decorators","_specularRoughnessAnisotropyTexture_initializers","_specularIor_decorators","_specularIor_initializers","_transmissionWeight_decorators","_transmissionWeight_initializers","_transmissionWeightTexture_decorators","_transmissionWeightTexture_extraInitializers","_transmissionColor_decorators","_transmissionColor_initializers","_transmissionColorTexture_decorators","_transmissionColorTexture_extraInitializers","_transmissionDepth_decorators","_transmissionDepth_initializers","_transmissionDepthTexture_decorators","_transmissionDepthTexture_initializers","_transmissionScatter_decorators","_transmissionScatter_initializers","_transmissionScatterTexture_decorators","_transmissionScatterTexture_initializers","_transmissionScatterAnisotropy_decorators","_transmissionScatterAnisotropy_initializers","_transmissionDispersionScale_decorators","_transmissionDispersionScale_initializers","_transmissionDispersionScaleTexture_decorators","_transmissionDispersionScaleTexture_initializers","_transmissionDispersionAbbeNumber_decorators","_transmissionDispersionAbbeNumber_initializers","_subsurfaceWeight_decorators","_subsurfaceWeight_initializers","_subsurfaceWeightTexture_decorators","_subsurfaceWeightTexture_extraInitializers","_subsurfaceColor_decorators","_subsurfaceColor_initializers","_subsurfaceColorTexture_decorators","_subsurfaceColorTexture_initializers","_subsurfaceColorTexture_extraInitializers","_subsurfaceRadius_decorators","_subsurfaceRadius_initializers","_subsurfaceRadiusScale_decorators","_subsurfaceRadiusScale_initializers","_subsurfaceRadiusScaleTexture_decorators","_subsurfaceRadiusScaleTexture_initializers","_subsurfaceScatterAnisotropy_decorators","_subsurfaceScatterAnisotropy_initializers","_coatWeight_decorators","_coatWeight_initializers","_coatWeightTexture_decorators","_coatWeightTexture_extraInitializers","_coatColor_decorators","_coatColor_initializers","_coatColorTexture_decorators","_coatColorTexture_initializers","_coatRoughness_decorators","_coatRoughness_initializers","_coatRoughnessTexture_decorators","_coatRoughnessTexture_initializers","_coatRoughnessAnisotropy_decorators","_coatRoughnessAnisotropy_initializers","_coatRoughnessAnisotropyTexture_decorators","_coatRoughnessAnisotropyTexture_initializers","_coatIor_decorators","_coatIor_initializers","_coatDarkening_decorators","_coatDarkening_initializers","_coatDarkeningTexture_decorators","_fuzzWeight_decorators","_fuzzWeight_initializers","_fuzzWeightTexture_decorators","_fuzzWeightTexture_extraInitializers","_fuzzColor_decorators","_fuzzColor_initializers","_fuzzColorTexture_decorators","_fuzzColorTexture_initializers","_fuzzRoughness_decorators","_fuzzRoughness_initializers","_fuzzRoughnessTexture_decorators","_fuzzRoughnessTexture_initializers","_geometryThinWalled_decorators","_geometryThinWalled_initializers","_geometryNormalTexture_decorators","_geometryNormalTexture_initializers","_geometryNormalTexture_extraInitializers","_geometryTangent_decorators","_geometryTangent_initializers","_geometryTangentTexture_decorators","_geometryTangentTexture_initializers","_geometryCoatNormalTexture_decorators","_geometryCoatNormalTexture_initializers","_geometryCoatTangent_decorators","_geometryCoatTangent_initializers","_geometryCoatTangentTexture_decorators","_geometryOpacity_decorators","_geometryOpacity_initializers","_geometryOpacityTexture_decorators","_geometryOpacityTexture_initializers","_geometryThickness_decorators","_geometryThickness_initializers","_geometryThicknessTexture_decorators","_geometryThicknessTexture_extraInitializers","_emissionLuminance_decorators","_emissionLuminance_initializers","_emissionColor_decorators","_emissionColor_initializers","_emissionColorTexture_decorators","_emissionColorTexture_initializers","_emissionColorTexture_extraInitializers","_thinFilmWeight_decorators","_thinFilmWeight_initializers","_thinFilmWeightTexture_decorators","_thinFilmWeightTexture_initializers","_thinFilmThickness_decorators","_thinFilmThickness_initializers","_thinFilmThicknessMin_decorators","_thinFilmThicknessMin_initializers","_thinFilmThicknessTexture_decorators","_thinFilmThicknessTexture_initializers","_thinFilmIor_decorators","_thinFilmIor_initializers","_environmentIntensity_initializers","_environmentIntensity_extraInitializers","_useSpecularWeightFromTextureAlpha_extraInitializers","_useAmbientOcclusionFromMetallicTextureRed_initializers","_useAmbientInGrayScale_extraInitializers","_useLinearAlphaFresnel_decorators","_useLinearAlphaFresnel_extraInitializers","_enableSpecularAntiAliasing_initializers","_useHorizonOcclusion_extraInitializers","SSS_QUALITY_HIGH","_Registered$5$","OpenPBRMaterial","IsIBLShadowsReceiverCompatible","ThinCustomPostProcess","FrameGraphIblShadowsAccumulationTask","remanence","_remanence","voxelGridSize","_accumulationParams","iblShadowAccumulation_fragment$1","iblShadowAccumulation_fragment","positionTexture","outputSize","positionSize","sharedTextureOptions","outputCreationOptions","previousAccumulationCreationOptions","previousPositionCreationOptions","_previousAccumulationTexture","_previousPositionTexture","voxelizationTask","copyPositionToPreviousPass","copyAccumulationToPreviousPass","outputMarkerPass","FrameGraphIblShadowsSpatialBlurTask","_blurParameters","iblShadowSpatialBlur_fragment$1","iblShadowSpatialBlur_fragment","FrameGraphIblShadowsTracingTask","sampleDirections","_sampleDirections","ssShadowSampleCount","_ssShadowSampleCount","ssShadowStride","_ssShadowStride","voxelShadowOpacity","ssShadowOpacity","ssShadowThicknessScale","envRotation","voxelNormalBias","voxelDirectionBias","worldScaleMatrix","_shadowParameters","_sssParameters","_opacityParameters","_voxelBiasParameters","_cameraInvView","_cameraInvProj","_cameraInvViewProjection","_coloredShadows","_currentDefines","iblShadowVoxelTracing_fragment","iblShadowVoxelTracing_fragment$1","_updateDefines","voxelGridTexture","icdfTexture","blueNoiseTexture","highestMip","gridSize","resExp","resolutionExp","sssMaxDist","ssShadowDistanceScale","sssThickness","defineString","ProceduralTextureSceneComponent","_beforeClear","proceduralIndex","onGenerated","onGeneratedObservable","onBeforeGenerationObservable","__generateMipMaps_initializers","__size_initializers","__size_extraInitializers","_fallbackTextureUsed","_contentUpdateId","skipSceneRegistration","_fullEngine","setFragment","_createRtWrapper","_createIndexBuffer","_setEffect","getContent","_contentData","_getDefines","_fragment","procedural_vertex$1","procedural_vertex","viewPort","numLayers","__generateMipMaps_decorators","__size_decorators","_get_refreshRate_decorators","__generateMipMaps_extraInitializers","_Registered$5_","ProceduralTexture","_IblShadowsVoxelRenderer","getVoxelGrid","_voxelGrid","_triPlanarVoxelization","_combinedVoxelGridPT","_voxelGridZaxis","getRT","_voxelGridRT","triPlanarVoxelization","_disposeVoxelTextures","setWorldScaleMatrix","_invWorldScaleMatrix","_voxelizationInProgress","voxelResolutionExp","_voxelResolutionExp","_voxelResolution","iblShadowsRenderPipeline","_voxelMrtsXaxis","_voxelMrtsYaxis","_voxelMrtsZaxis","_useOpacityBuffer","_voxelClearColor","onVoxelizationCompleteObservable","_gsVoxelMaterialCache","_sortSettleWaitFrames","_copyMipLayer","_mipArray","rawMaxDrawBuffers","cappedMaxDrawBuffers","_maxDrawBuffers","_copyMipEffectRenderer","_copyMipEffectWrapper","copyTexture3DLayerToTexture_fragment","copyTexture3DLayerToTexture_fragment$1","_copyMipSourceTexture","_generateMipMap","mipTarget","_copyMipMaps","_copyMipMap","voxelGrid","rt","previousColorWrite","sourceDepth","bindSize","destinationMipDepth","layersToCopy","destinationTexture","previousGenerateMipMaps","_computeNumberOfSlabs","voxelAxisOptions","numSlabs","voxelCombinedOptions","iblCombineVoxelGrids_fragment$1","iblCombineVoxelGrids_fragment","_voxelGridXaxis","_voxelGridYaxis","_createVoxelMRTs","generateVoxelMipOptions","iblGenerateVoxelMip_fragment","iblGenerateVoxelMip_fragment$1","mipIdx","mipDim","_createVoxelMaterials","_ensureVoxelOpacityAccumulator","_voxelOpacityBuffer","iblCopyVoxelBufferToGrid_compute","voxelOpacityBuffer","voxelGridTarget","_copyVoxelOpacityBufferToGrid","_copyBufferToGridCompute","voxelRT","mrtArray","mrtIndex","mrt","_stopVoxelization","mip","_voxelMaterial","iblVoxelGrid_fragment","iblVoxelGrid_vertex","iblVoxelGrid_fragment$1","iblVoxelGrid_vertex$1","mipReady","_removeVoxelRTs","rts","rtIdx","updateVoxelGrid","includedMeshes","registerAfterRenderObservable","_HasGaussianSplatting","useBuffer","setDefine","_addRTsForRender","_renderVoxelGridBound","_renderVoxelGrid","gsSortPending","_isDepthSortSettled","rttReady","gsVoxelMat","_installVoxelMixedCustomRender","sm","gsVoxelMaterial","_preBind","_VOXEL_VIEW_MATRICES","axisIdx","_isInstance","processBucket","renderGsSplat","slabSize","mrts","renderBucket","bucket","voxelMaterial","nearPlane","farPlane","stepSize","_addGsMeshToVoxelRT","FrameGraphIblShadowsVoxelizationTask","_resolutionExp","_voxelRenderer","dirty","_voxelizationCompleteObserver","_frameCounter","outputVoxelGridTexture","requestVoxelizationUpdate","_updateWorldScaleMatrix","_ensureVoxelRenderer","_updateOutputTextureHandlesFromRenderer","voxelRTInternalTexture","_voxelRTTextureHandle","shouldRefreshFromRate","isVoxelizationInProgress","processVoxelization","_detachVoxelizationObserver","_voxelRendererResolutionExp","_voxelRendererTriPlanar","_attachVoxelizationObserver","localBounds","halfSize","centerOffset","invWorldScaleMatrix","voxelInternalTexture","_voxelGridTextureHandle","_rotationY","setReflectionTextureMatrix","extensions","_boundingBoxPosition_initializers","_boundingBoxPosition_extraInitializers","__files_initializers","__files_extraInitializers","__forcedExtension_initializers","_extensions","__forcedExtension_extraInitializers","__extensions_initializers","__textureMatrix_initializers","_textureMatrixRefraction","__textureMatrix_extraInitializers","__textureMatrixRefraction_initializers","__textureMatrixRefraction_extraInitializers","RegisterAbstractEngineCubeTexture","CUBIC_MODE","extensionsOrOptions","_createPolynomials","_lodScale","_lodOffset","prefiltered","sphericalPolynomialTargetSize","isEnv","_prefiltered","isBasis","_loadTexture","trans","oldTexture","onLoadProcessing","savedIrradianceTexture","newCubeTexture","_boundingBoxPosition_decorators","__textureMatrixRefraction_decorators","serializeAsMatrix","_get_boundingBoxSize_decorators","_set_rotationY_decorators","__files_decorators","__forcedExtension_decorators","__extensions_decorators","__extensions_extraInitializers","__textureMatrix_decorators","_Registered$5Z","CubeTextureCreateFromImages","rootUrlKey","CubeTexture","CubeTextureCreateFromPrefilteredData","CreateFromImages","CreateFromPrefilteredData","CubeTextureParse","IblCdfGeneratorSceneComponent","_newIblObserver","_updateIblSource","removeIsReadyCheck","iblSource","_Registered$5Y","iblCdfGeneratorClass","_iblCdfGenerator","IblCdfGenerator","_iblSource","_clearIblSourceReadinessObservers","recreateFromObservedSourceIfReady","_isIblSourceReady","_recreateAssetsFromNewIbl","_iblSourceLoadUnsubscribe","_iblSourceReadyRetryObserver","_debugPass","_createDebugPass","_icdfPT","_dummyTexture","setDebugDisplayParams","widthScale","heightScale","_debugSizeParams","debugPassName","_debugPassName","getDebugPassPP","debugEnabled","blackPixels","RegisterIblCdfGeneratorSceneComponent","cdfOptions","iblCdfx_fragment$1","iblCdfy_fragment$1","iblScaledLuminance_fragment$1","iblCdfx_fragment","iblCdfy_fragment","iblScaledLuminance_fragment","icdfOptions","iblIcdf_fragment$1","iblDominantDirection_fragment$1","iblIcdf_fragment","iblDominantDirection_fragment","_cdfyPT","_cdfxPT","_scaledLuminancePT","scaledLuminanceType","_dominantDirectionPT","onTextureChangedObservable","iblCdfDebug_fragment$1","iblCdfDebug_fragment","debugOptions","debugEffect","renderWhenReady","findDominantDirection","_cachedDominantDirection","FrameGraphIblShadowsRendererTask","_voxelizationTask","_tracingTask","_spatialBlurTask","_accumulationTask","_dependenciesResolved","_applyMaterialPluginParameters","_setCamera","updateSceneBounds","resetAccumulation","shadowRemanence","_shadowOpacity","_getAccumulationOutputTexture","onOutputTextureReadyObservable","_outputTextureReadyObservable","updateVoxelization","sceneMaterial","_addShadowReceivingMaterialInternal","_materialsWithRenderPlugin","IBLShadowsPluginMaterial","addShadowCastingMesh","objectMeshes","removeShadowCastingMesh","_lastImportedIcdfTexture","_lastImportedEnvironmentTexture","_lastImportedBlueNoiseTexture","_disposeObservers","_lastNotifiedOutputTexture","_observedEnvironmentTexture","_observedEnvironmentTextureUnsubscribe","_cameraViewChangedObserver","_cdfTextureChangedObserver","_cdfGeneratedObserver","_environmentTextureChangedObserver","_beforeRenderDependencyObserver","_beforeRenderOutputReadyObserver","_blueNoiseLoadObserver","_texturesAllocatedObserver","_onEnvironmentTextureLoaded","_tryEnableShadowsTasks","_blueNoiseTexture","_disposeDependencyObservers","env","currentEnvironmentTexture","_notifyIfOutputTextureReady","accumulationTexture","_getEnvironmentTextureInternal","icdfChanged","environmentChanged","blueNoiseChanged","blueNoiseInternalTexture","_observeEnvironmentTexture","_get_sampleDirections_decorators","_get_coloredShadows_decorators","_get_voxelShadowOpacity_decorators","_get_ssShadowOpacity_decorators","_get_ssShadowSampleCount_decorators","_get_voxelDirectionBias_decorators","_get_envRotation_decorators","_get_shadowRemanence_decorators","_get_shadowOpacity_decorators","_get_triPlanarVoxelization_decorators","_get_ssShadowStride_decorators","_get_ssShadowDistanceScale_decorators","_get_ssShadowThicknessScale_decorators","_get_voxelNormalBias_decorators","_get_resolutionExp_decorators","_Registered$5X","NodeRenderGraphIblShadowsRendererBlock","NodeRenderGraphShadowGeneratorBlock","NodeRenderGraphBaseShadowGeneratorBlock","_Registered$5W","FrameGraphUtilityLayerRendererTask","_get_handleEvents_decorators","_Registered$5V","NodeRenderGraphUtilityLayerRendererBlock","detachFromEndpoint","_Registered$5U","NodeRenderGraphTeleportInBlock","NodeRenderGraphTeleportOutBlock","_customBuildStep","_Registered$5T","FrameGraphCopyToTextureTask","targetIsDepthTexture","_get_lodLevel_decorators","_Registered$5S","NodeRenderGraphCopyTextureBlock","FrameGraphGenerateMipMapsTask","NodeRenderGraphGenerateMipmapsBlock","_Registered$5R","FrameGraphCustomPostProcessTask","FrameGraphObjectList","uniformScaling","dragScale","incrementalSnap","_incrementalStartupValue","arrowMesh","arrowTail","_createGizmoMesh","nodePosition","linePosition","lineScale","dragStrength","snapped","currentSnapDragDistanceIncremental","currentSnap","AxisScaleGizmo","MinimumAbsoluteScale","maxScale","increaseGizmoMesh","uniformScaleGizmo","resetGizmoMesh","meshCache","getAxisCache","parentMesh","setCustomMesh","useGizmoMaterial","DragOperation","BoundingBoxGizmo","axisFactor","scaleBoxes","_scaleBoxesParent","zeroAxisCount","_axisFactor","scaleDragSpeed","_scaleDragSpeed","_hoverColoredMaterial","pointerDragBehavior","_pointerDragBehavior","setColor","_boundingDimensions","_renderObserver","_rotateAnchorsDragBehaviors","_scaleBoxesDragBehaviors","_tmpRotationMatrix","_incrementalAnchorStartupValue","_isCenterScaleModeActive","_centerScaleKeyObserver","ignoreChildren","includeChildPredicate","rotationSphereSize","scaleBoxSize","fixedDragMeshScreenSize","fixedDragMeshBoundsSize","fixedDragMeshScreenSizeDistanceFactor","scalingSnapDistance","rotationSnapDistance","onHoverStartObservable","onHoverEndObservable","onScaleBoxDragObservable","onScaleBoxDragEndObservable","onRotationSphereDragObservable","onRotationSphereDragEndObservable","scalePivot","_dragMesh","_lineBoundingBox","_rotateAnchorsParent","rotateAnchorsDragBehavior","startingTurnDirection","totalTurnAmountOfDrag","previousProjectDist","computeAxis","dragAxisIndex","dragOperation","originalParent","toSub","worldDragDirection","_anchorMesh","projectDist","_updateDummy","_selectNode","_unhoverMeshOnTouchUp","_getCornerMesh","scaleBoxesDragBehavior","totalRelativeDragDistance","previousScale","initialAnchorCenter","initialBoxPosition","initialMeshAbsolutePosition","relativeDragDistance","deltaScale","fullScale","updateBoundingBox","scaleMultiplier","totalScale","newAnchorScale","pointerIds","_existingMeshScale","_updateRotationAnchors","_updateScaleBoxes","_cornerMesh","boxZ","boxY","boxX","_hasInvalidNonUniformScaling","selectedMesh","getScaleBoxes","rotateAnchors","distanceFromCamera","homogeneousScaling","enableMesh","enableDragBehavior","MakeNotPickableAndWrapInBoundingBox","makeNotPickable","oldPos","oldRot","rotationColor","_rotationShaderMaterial","_angles","_rotationDisplayPlane","PlaneRotationGizmo","_RotationGizmoVertexShader","_RotationGizmoFragmentShader","MaxDragAngle","planeNormalTowardsCamera","localPlaneNormalTowardsCamera","amountToRotate","nodeScale","nodeQuaternion","nodeTranslation","attachedNodeTransform","nodeTranslationForOperation","newVector","originalVector","cameraFlipped","camVec","quaternionCoefficient","rotationMesh","RotationGizmo","_meshAttached","_nodeAttached","_checkBillboardTransform","gizmos","yGizmo","zGizmo","gizmo","_sensitivity","xGizmo","useEulerRotation","gizmoManager","_observables","_gizmoAxisCache","xColor","xOptions","yColor","yOptions","zColor","zOptions","_CreatePlane","dragPlane","PlaneDragGizmo","tmpVector2","currentSnapDragDistanceArray","axisDistance","PositionGizmo","xPlaneGizmo","yPlaneGizmo","zPlaneGizmo","_planarGizmoEnabled","planarGizmoEnabled","_snapDistance","_incrementalSnap","_createUniformScaleMesh","_uniformScalingMesh","_octahedron","msh","GizmoManager","keepDepthUtilityLayer","_defaultKeepDepthUtilityLayer","_defaultUtilityLayer","hovered","positionGizmo","rotationGizmo","scaleGizmo","boundingBoxGizmo","onAttachedToNodeObservable","_gizmosEnabled","_pointerObservers","_boundingBoxColor","_thickness","boundingBoxDragBehavior","SixDofDragBehavior","attachableMeshes","attachableNodes","usePointerToAttachGizmos","attachToMeshPointerObserver","_attachToMeshPointerObserver","gizmoAxisPointerObserver","enableAutoPicking","clearGizmoOnEmptyPointerEvent","boundingBoxGizmoEnabled","onAttachedToMeshObservable","attachToNode","positionGizmoEnabled","_setAdditionalTransformNode","rotationGizmoEnabled","scaleGizmoEnabled","ScaleGizmo","halfSphere","merged","_Registered$5Q","iesProfileTexture","_iesProfileTexture","_cosHalfAngle","_projectionTextureProjectionLightDirty","_computeAngleValues","_innerAngle","shadowAngleScale","_shadowAngleScale","projectionTextureMatrix","_projectionTextureMatrix","projectionTextureLightNear","_projectionTextureLightNear","projectionTextureLightFar","_projectionTextureLightFar","projectionTextureUpDirection","_projectionTextureUpDirection","_projectionTextureViewLightDirty","projectionTexture","_projectionTexture","_projectionTextureDirty","_IsProceduralTexture","_IsTexture","projectionTextureProjectionLightMatrix","_projectionTextureProjectionLightMatrix","_exponent_extraInitializers","__projectionTexture_initializers","__projectionTexture_extraInitializers","_projectionTextureViewTargetVector","_projectionTextureViewLightMatrix","_projectionTextureScalingMatrix","_computeProjectionTextureViewLightMatrix","_computeProjectionTextureProjectionLightMatrix","lightFar","lightNear","_computeProjectionTextureMatrix","_lightAngleScale","_lightAngleOffset","_get_angle_decorators","_get_innerAngle_decorators","_get_shadowAngleScale_decorators","_exponent_decorators","_get_projectionTextureLightNear_decorators","_get_projectionTextureLightFar_decorators","__projectionTexture_decorators","_get_projectionTextureUpDirection_decorators","_exponent_initializers","_Registered$5P","SpotLight","LightGizmo","_cachedForward","onClickedObservable","_attachedMeshParent","_lightMesh","_CreateHemisphericLightMesh","_CreateDirectionalLightMesh","_CreateSpotLightMesh","_CreatePointLightMesh","gizmoLight","lightGizmo","_getMeshForward","hemisphere","_CreateLightLines","_Scale","arrowHead","linePivot","CameraGizmo","gizmoColor","frustumLinesColor","_frustumLinesColor","displayFrustum","_cameraLinesMesh","_cameraMesh","linesColor","_CreateCameraFrustum","_CreateCameraMesh","cyl1","cyl2","cyl3","SpatialAudioGizmo","_soundSource","utilityScene","_audioMesh","_CreateSpeakerMesh","picked","spatialAudioGizmo","worldRotation","worldPosition","cone","MirrorTexture","blurRatio","_blurRatio","_preparePostProcesses","adaptiveBlurKernel","_adaptiveBlurKernel","_autoComputeBlurKernel","blurKernelX","blurKernelY","_blurKernelX","_blurKernelY","dw","dh","_updateGammaSpace","_mirrorMatrix","saveClipPlane","_imageProcessingConfigChangeObserver","_sceneUBO","_Registered$5O","BackgroundMaterialDefinesBase","BackgroundMaterialDefines","GAMMADIFFUSE","DIFFUSEHASALPHA","REFLECTIONBLUR","REFLECTIONFALLOFF","TEXTURELODSUPPORT","USERGBCOLOR","USEHIGHLIGHTANDSHADOWCOLORS","BACKMAT_SHADOWONLY","NOISE","REFLECTIONBGR","BackgroundMaterialBase","_BackgroundMaterial_reflectionTexture_accessor_storage","_BackgroundMaterial_reflectionBlur_accessor_storage","_BackgroundMaterial_diffuseTexture_accessor_storage","_BackgroundMaterial_shadowLights_accessor_storage","_BackgroundMaterial_shadowLevel_accessor_storage","_BackgroundMaterial_sceneCenter_accessor_storage","_BackgroundMaterial_opacityFresnel_accessor_storage","_BackgroundMaterial_reflectionFresnel_accessor_storage","_BackgroundMaterial_reflectionFalloffDistance_accessor_storage","_BackgroundMaterial_reflectionAmount_accessor_storage","_BackgroundMaterial_reflectionReflectance0_accessor_storage","_BackgroundMaterial_reflectionReflectance90_accessor_storage","_BackgroundMaterial_useRGBColor_accessor_storage","_BackgroundMaterial_enableNoise_accessor_storage","_BackgroundMaterial_maxSimultaneousLights_accessor_storage","_BackgroundMaterial_shadowOnly_accessor_storage","_BackgroundMaterial_enableGroundProjection_accessor_storage","primaryColor","_BackgroundMaterial_primaryColor_accessor_storage","_perceptualColor","__perceptualColor","_computePrimaryColorFromPerceptualColor","primaryColorShadowLevel","_primaryColorShadowLevel","_computePrimaryColors","primaryColorHighlightLevel","_primaryColorHighlightLevel","shadowLevel","sceneCenter","opacityFresnel","reflectionFresnel","reflectionFalloffDistance","reflectionAmount","reflectionReflectance0","reflectionReflectance90","reflectionStandardFresnelWeight","reflectionWeight","StandardReflectance0","StandardReflectance90","useRGBColor","enableNoise","fovMultiplier","_fovMultiplier","shadowOnly","enableGroundProjection","_primaryColor","__primaryColor_initializers","__primaryColor_extraInitializers","_primaryColor_initializers","_primaryColor_extraInitializers","___perceptualColor_initializers","__primaryColorShadowLevel_initializers","__primaryColorShadowLevel_extraInitializers","__primaryColorHighlightLevel_initializers","__primaryColorHighlightLevel_extraInitializers","_reflectionBlur","__reflectionBlur_extraInitializers","_reflectionBlur_initializers","_reflectionBlur_extraInitializers","_shadowLights","_shadowLights_initializers","_shadowLevel","_shadowLights_extraInitializers","__shadowLevel_extraInitializers","_shadowLevel_initializers","_sceneCenter","_shadowLevel_extraInitializers","__sceneCenter_initializers","__sceneCenter_extraInitializers","_sceneCenter_initializers","_opacityFresnel","_sceneCenter_extraInitializers","__opacityFresnel_extraInitializers","_opacityFresnel_initializers","_reflectionFresnel","_opacityFresnel_extraInitializers","__reflectionFresnel_extraInitializers","_reflectionFresnel_initializers","_reflectionFalloffDistance","_reflectionFresnel_extraInitializers","__reflectionFalloffDistance_extraInitializers","_reflectionFalloffDistance_initializers","_reflectionAmount","_reflectionFalloffDistance_extraInitializers","__reflectionAmount_extraInitializers","_reflectionAmount_initializers","_reflectionReflectance0","_reflectionAmount_extraInitializers","__reflectionReflectance0_extraInitializers","_reflectionReflectance90","_reflectionReflectance0_extraInitializers","__reflectionReflectance90_extraInitializers","_reflectionReflectance90_initializers","_useRGBColor","_reflectionReflectance90_extraInitializers","__useRGBColor_extraInitializers","_useRGBColor_initializers","_enableNoise","_useRGBColor_extraInitializers","__enableNoise_extraInitializers","_enableNoise_initializers","_enableNoise_extraInitializers","useEquirectangularFOV","_shadowOnly","__shadowOnly_extraInitializers","_shadowOnly_initializers","switchToBGR","_shadowOnly_extraInitializers","_enableGroundProjection","_enableGroundProjection_initializers","projectedGroundRadius","_enableGroundProjection_extraInitializers","_projectedGroundRadius_initializers","_projectedGroundHeight_extraInitializers","_reflectionControls","_white","_primaryShadowColor","EQUIRECTANGULAR_RELFECTION_FOV","PROJECTED_GROUND","_primaryHighlightColor","projectedGroundHeight","_primaryColor_decorators","___perceptualColor_decorators","__primaryColorShadowLevel_decorators","__primaryColorHighlightLevel_decorators","_reflectionBlur_decorators","_shadowLights_decorators","_shadowLevel_decorators","_sceneCenter_decorators","_opacityFresnel_decorators","_reflectionFresnel_decorators","_reflectionFalloffDistance_decorators","_reflectionAmount_decorators","_reflectionReflectance0_decorators","_reflectionReflectance90_decorators","_useRGBColor_decorators","_enableNoise_decorators","_shadowOnly_decorators","_enableGroundProjection_decorators","_projectedGroundRadius_decorators","_projectedGroundHeight_decorators","__primaryColor_decorators","___perceptualColor_extraInitializers","__reflectionBlur_decorators","__reflectionBlur_initializers","__shadowLevel_decorators","__shadowLevel_initializers","__sceneCenter_decorators","__opacityFresnel_decorators","__opacityFresnel_initializers","__reflectionFresnel_decorators","__reflectionFresnel_initializers","__reflectionFalloffDistance_decorators","__reflectionAmount_decorators","__reflectionAmount_initializers","__reflectionReflectance0_decorators","__reflectionReflectance90_decorators","__reflectionReflectance90_initializers","__useRGBColor_decorators","__useRGBColor_initializers","__enableNoise_decorators","__enableNoise_initializers","__shadowOnly_decorators","__shadowOnly_initializers","_projectedGroundRadius_extraInitializers","_Registered$5N","BackgroundMaterial","EnvironmentHelper","createGround","groundSize","groundTexture","_GroundTextureCDNUrl","groundOpacity","enableGroundShadow","groundShadowLevel","enableGroundMirror","groundMirrorSizeRatio","groundMirrorBlurKernel","groundMirrorAmount","groundMirrorFresnelWeight","groundMirrorFallOffDistance","groundMirrorTextureType","groundYBias","createSkybox","skyboxSize","skyboxTexture","_SkyboxTextureCDNUrl","skyboxColor","backgroundYRotation","sizeAuto","rootPosition","setupImageProcessing","_EnvironmentTextureCDNUrl","skybox","_skybox","_skyboxTexture","skyboxMaterial","_skyboxMaterial","_ground","_groundTexture","groundMirror","_groundMirror","groundMirrorRenderList","groundMaterial","_groundMaterial","_errorHandler","_setupBackground","_setupImageProcessing","updateOptions","newOptions","setMainColor","_setupEnvironmentTexture","sceneSize","_setupGround","_setupGroundMaterial","_setupGroundDiffuseTexture","_setupGroundMirrorTexture","_setupMirrorInGroundMaterial","_setupSkybox","_setupSkyboxMaterial","_setupSkyboxReflectionTexture","_getSceneSize","sceneDiagonal","sceneExtends","sceneDiagonalLength","wrapping","gammaGround","SKYBOX_MODE","TextureDome","_useDirectMapping","FIXED_EQUIRECTANGULAR_MIRRORED_MODE","_changeTextureMode","_textureMode","textureMode","halfDome","_halfDome","_halfDomeMask","crossEye","_crossEye","MODE_MONOSCOPIC","onLoadErrorObservable","clickToPlay","autoPlay","useDirectMapping","faceForward","_initTexture","textureUrlOrElement","rightOffset","leftOffset","MODE_TOPBOTTOM","PhotoDome","photoTexture","imageMode","urlsOrElement","_PBRMaterial_emissiveIntensity_accessor_storage","_PBRMaterial_environmentIntensity_accessor_storage","_PBRMaterial_specularIntensity_accessor_storage","_PBRMaterial_disableBumpMap_accessor_storage","_PBRMaterial_albedoTexture_accessor_storage","_PBRMaterial_baseWeightTexture_accessor_storage","_PBRMaterial_baseDiffuseRoughnessTexture_accessor_storage","_PBRMaterial_ambientTexture_accessor_storage","_PBRMaterial_ambientTextureStrength_accessor_storage","_PBRMaterial_ambientTextureImpactOnAnalyticalLights_accessor_storage","_PBRMaterial_opacityTexture_accessor_storage","_PBRMaterial_reflectionTexture_accessor_storage","_PBRMaterial_emissiveTexture_accessor_storage","_PBRMaterial_reflectivityTexture_accessor_storage","_PBRMaterial_metallicTexture_accessor_storage","_PBRMaterial_metallic_accessor_storage","_PBRMaterial_roughness_accessor_storage","_PBRMaterial_metallicF0Factor_accessor_storage","_PBRMaterial_metallicReflectanceColor_accessor_storage","_PBRMaterial_useOnlyMetallicFromMetallicReflectanceTexture_accessor_storage","_PBRMaterial_metallicReflectanceTexture_accessor_storage","_PBRMaterial_reflectanceTexture_accessor_storage","_PBRMaterial_microSurfaceTexture_accessor_storage","_PBRMaterial_bumpTexture_accessor_storage","_PBRMaterial_lightmapTexture_accessor_storage","_PBRMaterial_ambientColor_accessor_storage","_PBRMaterial_albedoColor_accessor_storage","_PBRMaterial_baseWeight_accessor_storage","_PBRMaterial_baseDiffuseRoughness_accessor_storage","_PBRMaterial_reflectivityColor_accessor_storage","_PBRMaterial_reflectionColor_accessor_storage","_PBRMaterial_emissiveColor_accessor_storage","_PBRMaterial_microSurface_accessor_storage","_PBRMaterial_useLightmapAsShadowmap_accessor_storage","_PBRMaterial_useAlphaFromAlbedoTexture_accessor_storage","_PBRMaterial_forceAlphaTest_accessor_storage","_PBRMaterial_alphaCutOff_accessor_storage","_PBRMaterial_useSpecularOverAlpha_accessor_storage","_PBRMaterial_useMicroSurfaceFromReflectivityMapAlpha_accessor_storage","_PBRMaterial_useRoughnessFromMetallicTextureAlpha_accessor_storage","_PBRMaterial_useRoughnessFromMetallicTextureGreen_accessor_storage","_PBRMaterial_useMetallnessFromMetallicTextureBlue_accessor_storage","_PBRMaterial_useAmbientOcclusionFromMetallicTextureRed_accessor_storage","_PBRMaterial_useAmbientInGrayScale_accessor_storage","_PBRMaterial_useAutoMicroSurfaceFromReflectivityMap_accessor_storage","_PBRMaterial_useRadianceOverAlpha_accessor_storage","_PBRMaterial_useObjectSpaceNormalMap_accessor_storage","_PBRMaterial_useParallax_accessor_storage","_PBRMaterial_useParallaxOcclusion_accessor_storage","_PBRMaterial_parallaxScaleBias_accessor_storage","_PBRMaterial_disableLighting_accessor_storage","_PBRMaterial_forceIrradianceInFragment_accessor_storage","_PBRMaterial_maxSimultaneousLights_accessor_storage","_PBRMaterial_invertNormalMapX_accessor_storage","_PBRMaterial_invertNormalMapY_accessor_storage","_PBRMaterial_twoSidedLighting_accessor_storage","_PBRMaterial_useAlphaFresnel_accessor_storage","_PBRMaterial_useLinearAlphaFresnel_accessor_storage","_PBRMaterial_environmentBRDFTexture_accessor_storage","_PBRMaterial_forceNormalForward_accessor_storage","_PBRMaterial_enableSpecularAntiAliasing_accessor_storage","_PBRMaterial_useHorizonOcclusion_accessor_storage","_PBRMaterial_useRadianceOcclusion_accessor_storage","_PBRMaterial_unlit_accessor_storage","_PBRMaterial_applyDecalMapAfterDetailMap_accessor_storage","_PBRMaterial_directIntensity_accessor_storage","specularIntensity","ambientTextureStrength","ambientTextureImpactOnAnalyticalLights","metallicF0Factor","metallicReflectanceColor","useOnlyMetallicFromMetallicReflectanceTexture","metallicReflectanceTexture","reflectanceTexture","microSurfaceTexture","useAlphaFromAlbedoTexture","useMicroSurfaceFromReflectivityMapAlpha","useRoughnessFromMetallicTextureAlpha","useRoughnessFromMetallicTextureGreen","useMetallnessFromMetallicTextureBlue","useAutoMicroSurfaceFromReflectivityMap","useRadianceOverAlpha","_emissiveIntensity_initializers","_specularIntensity_initializers","_specularIntensity_extraInitializers","_disableBumpMap_extraInitializers","_albedoTexture_initializers","_albedoTexture_extraInitializers","_baseWeightTexture_initializers","_ambientTextureStrength_initializers","_ambientTextureStrength_extraInitializers","_ambientTextureImpactOnAnalyticalLights_extraInitializers","_reflectivityTexture_initializers","_reflectivityTexture_extraInitializers","_metallicTexture_extraInitializers","_metallic_extraInitializers","_metallicF0Factor_initializers","_metallicF0Factor_extraInitializers","_metallicReflectanceColor_extraInitializers","_useOnlyMetallicFromMetallicReflectanceTexture_initializers","_useOnlyMetallicFromMetallicReflectanceTexture_extraInitializers","_metallicReflectanceTexture_extraInitializers","_reflectanceTexture_extraInitializers","_microSurfaceTexture_extraInitializers","_albedoColor_initializers","_albedoColor_extraInitializers","_reflectivityColor_initializers","_reflectivityColor_extraInitializers","_reflectionColor_initializers","_microSurface_extraInitializers","_useAlphaFromAlbedoTexture_initializers","_forceAlphaTest_extraInitializers","_useMicroSurfaceFromReflectivityMapAlpha_extraInitializers","_useRoughnessFromMetallicTextureAlpha_initializers","_useRoughnessFromMetallicTextureAlpha_extraInitializers","_useRoughnessFromMetallicTextureGreen_initializers","_useRoughnessFromMetallicTextureGreen_extraInitializers","_useMetallnessFromMetallicTextureBlue_initializers","_useAutoMicroSurfaceFromReflectivityMap_initializers","_useAutoMicroSurfaceFromReflectivityMap_extraInitializers","_useRadianceOverAlpha_initializers","_emissiveIntensity_decorators","_specularIntensity_decorators","_disableBumpMap_decorators","_albedoTexture_decorators","_ambientTextureStrength_decorators","_ambientTextureImpactOnAnalyticalLights_decorators","_reflectivityTexture_decorators","_metallicTexture_decorators","_metallic_decorators","_metallicF0Factor_decorators","_metallicReflectanceColor_decorators","_useOnlyMetallicFromMetallicReflectanceTexture_decorators","_metallicReflectanceTexture_decorators","_reflectanceTexture_decorators","_microSurfaceTexture_decorators","_albedoColor_decorators","_reflectivityColor_decorators","_reflectionColor_decorators","_microSurface_decorators","_useAlphaFromAlbedoTexture_decorators","_useMicroSurfaceFromReflectivityMapAlpha_decorators","_useRoughnessFromMetallicTextureAlpha_decorators","_useRoughnessFromMetallicTextureGreen_decorators","_useMetallnessFromMetallicTextureBlue_decorators","_useAutoMicroSurfaceFromReflectivityMap_decorators","_useRadianceOverAlpha_decorators","_emissiveIntensity_extraInitializers","_disableBumpMap_initializers","_ambientTextureImpactOnAnalyticalLights_initializers","_metallicReflectanceColor_initializers","_microSurface_initializers","_useLightmapAsShadowmap_initializers","_useAlphaFromAlbedoTexture_extraInitializers","_useSpecularOverAlpha_initializers","_useMicroSurfaceFromReflectivityMapAlpha_initializers","_useMetallnessFromMetallicTextureBlue_extraInitializers","_useRadianceOverAlpha_extraInitializers","_Registered$5M","PBRMaterial","RegisterPbrMaterial","WebXRCamera","_firstFrame","_xrSessionInitObserver","_xrFrameObserver","_referenceQuaternion","_referencedPosition","_trackingState","_updateDepthNearFar","onXRCameraInitializedObservable","onTrackingStateChanged","compensateOnFirstFrame","_updateFromXRSession","_updateReferenceSpace","trackingState","_setTrackingState","realWorldHeight","basePose","_updateNumberOfRigCameras","setTransformationFromNonVRCamera","otherCamera","resetToBaseReferenceSpace","_onWorldScaleFactorChanged","_lastXRViewerPose","depthFar","depthNear","xrRenderState","currentRig","needsHalfZConversion","viewCount","removedCamera","referencedMat","poseMat","transformMat","_ScaleReadOnly","WebXRExperienceHelper","_nonVRCamera","_spectatorCamera","_originalSceneAutoClear","_supported","_spectatorMode","_lastTimestamp","_spectatorStateChangedObserver","_spectatorXRFrameObserver","_spectatorAfterRenderObserver","onInitialXRPoseSetObservable","_clearSpectatorObservers","referenceSpaceType_1","sessionCreationOptions","_extendXRSessionInitObject","sceneStateChanged","initializeSessionAsync","_nonXRToXRCamera","sessionEndedObserver","isSessionStarting","enableSpectatorMode","_switchSpectatorMode","disableSpecatatorMode","preferredCameraIndex","updateSpectatorCamera","onStateChanged","WebXRControllerComponent","_buttonIndex","_axesIndices","_axes","_changes","_hasChanges","_pressed","_touched","onAxisValueChangedObservable","onButtonStateChangedObservable","changes","hasChanges","touched","isAxes","isButton","nativeController","buttonUpdated","axesUpdate","SceneLoaderAnimationGroupLoadingMode","BUTTON_TYPE","SQUEEZE_TYPE","THUMBSTICK_TYPE","TOUCHPAD_TYPE","onPluginActivatedObservable","registeredPlugins","showingLoadingScreen","getDefaultPlugin","returnDefault","createLoadError","fileInfo","rawData","formatErrorMessage","SceneLoaderError","getErrorMessage","toLoadError","toAsyncPlugin","importMesh","loadAssetContainer","invoke","pluginError","meshesNames","runSync","loadAsync","reportScene","wrapProgress","directLoad","sceneFilename","pluginExtension","queryStringPosition","dotPosition","getFilenameExtension","registeredPlugin","getPluginForExtension","canDirectLoad","getPluginForDirectLoad","fileExtension","headerValues","header","_FetchAsync","registeredPluginKey","getPluginForMimeType","pluginOptions","createPlugin","pluginFactory","createdPlugin","isBinary","pluginDisposed","onDisposeObserver","rejectAndCleanup","cleanup","dataCallback","manifestChecked","errorCallback","canUseOfflineSupport","exceptionFound","GetFileInfo","sceneSource","filename","RegisterSceneLoaderPlugin","registerSceneLoaderPlugin","GetRegisteredSceneLoaderPluginMetadata","pluginMap","extensionRegistration","pluginMetadata","meshNames","importMeshCoreAsync","loadingToken","progressHandler","loadDataAsync","rewriteRootURL","importMeshAsync","loadingPluginName","loadSceneCoreAsync","rootUrl_1","appendSceneCoreAsync","LoadSceneAsync","AppendSceneAsync","loadAssetContainerCoreAsync","asyncPlugin","loadAssetContainerAsync","assetContainer","LoadAssetContainerAsync","importAnimationsCoreAsync","overwriteAnimations","animationGroupLoadingMode","startingIndexForNewAnimatables","mergeAnimationsTo","ImportAnimationsAsync","SceneLoader","GetDefaultPlugin","IsPluginForExtensionAvailable","isPluginForExtensionAvailable","RegisterPlugin","reportLegacyLoadError","Load","appendedScene","assets","NO_LOGGING","MINIMAL_LOGGING","SUMMARY_LOGGING","DETAILED_LOGGING","WebXRAbstractMotionController","gamepadObject","_doNotLoadControllerMesh","_controllerCache","_initComponent","componentDef","components","gamepadIndices","_modelReady","disableAnimation","getComponentIds","getComponent","onModelLoadedObservable","getAllComponentsOfType","selectComponentId","useGeneric","_getModelLoadingConstraints","loadingParams","_getFilenameAndPath","meshesLoaded","_getGenericParentMesh","_setRootMesh","_processLoadedModel","ImportMesh","updateModel","handness","_getHapticActuator","hapticActuatorIndex","effects","playHapticEffectAsync","parameters_1","actuator","effectType","playEffect","resetHapticActuatorAsync","pulse","duration_1","hapticActuators","vibrationActuator","actuators","_lerpTransform","axisMap","axisValue","fixValueCoordinates","minMesh","maxMesh","valueMesh","lerpValue","_updateModel","profileId","WebXRProfiledMotionController","_profile","xrInput","controllerCache","_repositoryUrl","_buttonMeshMapping","_touchDots","visResKey","assetPath","glbLoaded","componentInLayout","mainMesh","_getChildByName","visualResponses","visResponse","visualResponseKey","valueNodeProperty","minNodeName","maxNodeName","nameOfMesh","touchPointNodeName","valueNodeName","_xrFrame","componentProperty","GenericTriggerLayout","WebXRGenericTriggerMotionController","ProfileId","gamepadMapping","none","ControllerCache","WebXRMotionControllerManager","ClearProfilesCache","_ProfilesList","_ProfileLoadingPromises","DefaultFallbacks","RegisterFallbacksForProfileId","FindFallbackWithProfileId","returnArray","_Fallbacks","forceProfile","profileArray","windowsMRIdx","UseOnlineRepository","firstFunction","PrioritizeOnlineRepository","_LoadProfileFromRepositoryAsync","_LoadProfilesFromAvailableControllersAsync","secondFunction","_AvailableControllers","LoadFileAsync","BaseRepositoryUrl","ClearControllerCache","UpdateProfilesList","profilesList","profileToLoad","profile","DisableControllerCache","constructionFunction","_Registered$5L","RegisterController","IdCount","WebXRInputSource","inputSource","_disposed","onMeshLoadedObservable","onMotionControllerInitObservable","gripSpace","grip","GetMotionControllerWithXRInput","forceControllerProfile","motionController","disableMotionControllerAnimation","getWorldPointerRayToRef","gripIfAvailable","updateFromXRFrame","xrCamera","getPose","targetRaySpace","WebXRInput","controllers","_currentXRSession","onControllerAddedObservable","onControllerRemovedObservable","_onInputSourcesChange","_addAndRemoveControllers","added","_sessionInitObserver","customControllersRepositoryURL","disableOnlineControllerRepository","addInputs","controllerOptions","forceInputProfile","doNotLoadControllerMesh","doNotLoadControllerMeshes","disableControllerAnimation","keepControllers","removedControllers","removeInputs","_frameObserver","_sessionEndedObserver","WebXRAbstractFeature","_xrNativeFeatureName","_attached","_disableAutoAttachWarningEmitted","_removeOnDetach","onFeatureAttachObservable","onFeatureDetachObservable","_addNewAttachObserver","_onXRFrame","_disableAutoAttach","warning","WebXRControllerPointerSelection","_attachController","xrController","laserPointer","selectionMesh","tmpRay","disabledByNearInteraction","_attachedController","enablePointerSelectionOnAllControllers","preferredHandedness","targetRayMode","_attachTrackedPointerRayMode","_attachGazeMode","_tmpVectorForPickCompare","disablePointerLighting","disableSelectionMeshLighting","displaySelectionMesh","laserPointerPickedColor","laserPointerDefaultColor","selectionMeshDefaultColor","selectionMeshPickedColor","_identityMatrix","_screenCoordinatesRef","_viewportRef","lookAndPickMode","_detachController","gazeCamera","webXRCamera","_generateNewMeshPair","controllerId","getMeshUnderPointer","attachedControllerId","setAttachedController","prevControllerData","pointerDownTriggered","finalPointerUpTriggered","_augmentPointerInit","controllerData","forceGripIfAvailable","controllerGlobalPosition","maxPointerDistance","toGlobalToRef","screenCoordinates","_utilityLayerScene","pickNormal","_convertNormalToDirectionOfRay","deltaFighting","customUtilityLayerScene","timeToSelect","sceneToRenderTo","useUtilityLayer","discMesh","downTriggered","onFrameObserver","_pickingMoved","oldPick","disablePointerUpOnTouchOut","forceGazeMode","overrideButtonId","selectionComponent","getMainComponent","onButtonChangedObserver","prevController","selectStartListener","selectEndListener","eventListeners","selectend","selectstart","xrControllerUniqueId","customLasterPointerMeshGenerator","laserPointerMaterial","customSelectionMeshGenerator","newPick","gazeModePointerMovedFactor","_laserPointer","_Registered$5K","AddWebXRFeature","NodeMaterialBlockConnectionPointTypes","NodeMaterialBlockTargets","supportUniformBuffers","constants","functions","prePassOutput","_builtCompilationString","compilationString","sharedData","nodeMaterial","fSuffix","Fragment","WebGLShaderProcessor","finalize","emitComments","isFragmentMode","entryPointString","_customEntryHeader","varyingInitializationsFragment","_constantDeclaration","functionCode","_varyingTransfer","_injectAtEnd","varyingDeclaration","varyingDeclarationFragment","_samplerDeclaration","_uniformDeclaration","_attributeDeclaration","prePassDeclaration","extensionName","_injectAtTop","_repeatableContentAnchor","_repeatableContentAnchorIndex","prefix","formatConfig","formatVariablename","variableNames","_emit2DSampler","annotation","unsignedSampler","unsignedSamplerPrefix","precisionDecl","_emitCubeSampler","Float","Int","_emitExtension","_emitFunction","repeatKey","includeName","substitutionVars","replaceStrings","replaceString","_emitFunctionFromInclude","storeKey","removeAttributes","removeUniforms","removeVaryings","removeIfDef","_registerTempVariable","temps","notDefine","_emitVaryingFromString","varyings","_getShaderType","emitCode","forFragment","_emitDefineStart","_emitDefineEnd","_emitUniformFromString","getUniformAnnotation","trueStatement","falseStatement","_emitFloat","_declareOutput","isConst","_declareLocalVar","associatedVariableName","isVarPrivate","_samplerFunc","_samplerLODFunc","_samplerCubeFunc","_convertVariableDeclarationToWGSL","_convertVariableConstructorsToWGSL","_convertOutParametersToWGSL","_convertTernaryOperandsToWGSL","trueCase","falseCase","_convertConstToWGSL","_convertInnerFunctionsToWGSL","formattedParams","_convertTernaryOperandsToGLSL","textureBlocks","bindableBlocks","forcedBindableBlocks","blocksWithFallbacks","blocksWithDefines","repeatableContentBlocks","dynamicUniformBlocks","blockingBlocks","animatedInputs","hints","needWorldViewMatrix","needWorldViewProjectionMatrix","checks","emitVertex","emitFragment","notConnectedNonOptionalInputs","customErrors","raiseBuildError","allowEmptyVertexProgram","customError","NodeMaterialConnectionPointCompatibilityStates","NodeMaterialConnectionPointDirection","NodeMaterialConnectionPoint","type1","type2","isInactive","_isInactive","_connectedPointBackingField","_connectedPointTypeChangedObserver","_updateTypeDependentState","onTypeChangedObservable","_notifyTypeChanged","_typeConnectionSourceBackingField","_typeConnectionSourceTypeChangedObserver","_defaultConnectionPointTypeBackingField","_linkedConnectionSourceBackingField","_linkedConnectionSourceTypeChangedObserver","declarationVariableName","_enforceAssociatedVariableName","_associatedVariableName","_redirectedSource","_prioritizeVertex","VertexAndFragment","isConnectedToInputBlock","connectInputBlock","isDirectlyConnectedToVertexOutput","Neutral","isConnectedInVertexShader","isConnectedInFragmentShader","_preventBubbleUp","_isTypeChangeObservableNotifying","AreEquivalentTypes","canConnectTo","previousType","_isFinalOutputAndActive","_isFinalOutput","_hasPrecedence","codeIsReady","_codeIsReady","validateBlockName","isFinalMerger","_isFinalMerger","_isLoop","isFinalOutput","_originalTargetIsNeutral","_setInitialTarget","_writeVariable","_writeFloat","stringVersion","getFirstAvailableInput","forOutput","getFirstAvailableOutput","forBlock","notFound","getSiblingOutput","willBeGeneratedIntoVertexShaderFromFragmentShader","activeBlocks","localBlockIsFragment","_vertexState","otherBlockWasGeneratedInVertexShader","_buildTarget","isAttribute","_noContextSwitch","reservedNames","reservedName","_getFreeVariableName","_processBuild","_forPostBuild","_terminalBlocks","visibleInInspector","onCodeIsReadyObservable","FragmentOutputBlockColorSpace","_useLogarithmicDepth_extraInitializers","rgb","additionalColor","colorSpace","convertToGammaSpace","Gamma","convertToLinearSpace","Linear","NoColorSpace","_excludeVariableName","helperFunctions$2","objectIdFunctions$2","helperFunctions$1","objectIdFunctions$1","rgba","glow","_getOutputString","indexDefine","_linearDefineName","_gammaDefineName","_additionalColorDefineName","_useAdditionalColor","_getFreeDefineName","outputString","aValue","fragDepth","uniformP","uniformPrefix","_writePrePassOutput","_useLogarithmicDepth_decorators","_get_colorSpace_decorators","notifiers","_Registered$5J","FragmentOutputBlock","NodeMaterialModes","NodeMaterialSystemValues","AnimatedInputBlockTypes","remapAttributeName","particle_uv","particle_color","particle_texturemask","postprocess_uv","attributeInFragmentOnly","particle_positionw","attributeAsUniform","attributeDefine","uv3","uv4","uv5","uv6","uv7","uv8","InputBlock","NodeMaterialBlock","isUniform","isSystemValue","World","WorldView","WorldViewProjection","ViewProjection","Projection","DeltaTime","_animationType","None","setAsAttribute","setAsSystemValue","isBoolean","valueCallback","_valueCallback","_prefix","isUndefined","isVarying","_systemValue","systemValue","_emitDefine","_emitConstant","toGammaSpaceToRef","isConstant","_emit","alreadyDeclared","_transmitWorld","worldView","worldViewProjection","_transmit","CameraPosition","CameraForward","FogColor","CameraParameters","hasOriginBottomLeft","MaterialAlpha","valueString","matrixMode","groupInInspector","wellKnownValue","_Registered$5I","ScreenSizeBlock","_varName","varName","writeOutputs","_Registered$5H","SfeModeDefine","SmartFilterFragmentOutputBlock","_generateInputBlockAnnotation","_generateScreenSizeBlockAnnotation","inputBlock","screenUv","getInputBlockByPredicate","_getMainUvName","_Registered$5G","transformAsDirection","complementW","complementZ","otherAsInput","xyz","transformName","_get_transformAsDirection_decorators","_Registered$5F","TransformBlock","VertexOutputBlock","nodeList","_isLogarithmicDepthEnabled","_Registered$5E","CurrentScreenBlock","_samplerName","_injectVertexCode","uvInput","_mainUVName","_writeTextureRead","_writeOutput","vertexMode","textureReadFunc","complement","_tempTextureRead","_Registered$5D","ParticleTextureBlock","additionalFilteringInfo","_generateTextureSample","_Registered$5C","ParticleRampGradientBlock","rampColor","varyingString","_Registered$5B","ParticleBlendMultiplyBlock","alphaColor","_Registered$5A","VectorMergerBlock","xSwizzle","ySwizzle","zSwizzle","wSwizzle","xyzwIn","xyzIn","xyIn","zwIn","xyzw","xyzOut","xyOut","zwOut","_buildSwizzle","xInput","yInput","zInput","wInput","xyInput","zwInput","xyzInput","xyzwInput","v4Output","v3Output","v2Output","v2CompOutput","_Registered$5z","_sourceRange_initializers","sourceMin","sourceMax","targetMin","targetMax","targetRange","_targetRange_decorators","_sourceRange_decorators","_sourceRange_extraInitializers","_Registered$5y","RemapBlock","BaseMathBlock","_linkConnectionTypes","_connectionObservers","_updateInputOutputTypes","MultiplyBlock","_Registered$5x","ColorGradient","color1","color2","getColorToRef","Color3Gradient","FactorGradient","factor1","factor2","getFactor","GradientHelper","gradients","updateFunc","gradientIndex","currentGradient","nextGradient","BoxParticleEmitter","direction1","direction2","minEmitBox","maxEmitBox","startDirectionFunction","directionToUpdate","particle","isLocal","randX","randY","randZ","startPositionFunction","positionToUpdate","newOne","uboOrEffect","getEffectDefines","PointParticleEmitter","HemisphericParticleEmitter","radiusRange","directionRandomizer","randRadius","SphereParticleEmitter","SphereDirectedParticleEmitter","CylinderParticleEmitter","inverseWorldMatrix","yPos","radiusDistribution","positionRadius","xPos","zPos","CylinderDirectedParticleEmitter","_particle","ConeParticleEmitter","_buildHeight","heightRange","emitFromSpawnPointOnly","applyToShader","ConeDirectedParticleEmitter","_storedNormal","useMeshNormalsForDirection","randomFaceIndex","faceIndexA","faceIndexB","faceIndexC","vertexA","vertexB","vertexC","randomVertex","MeshParticleEmitter","BaseParticleSystem","targetStopDuration","_targetStopDuration","isNodeGenerated","noiseTexture","_noiseTexture","attractors","_attractors","addAttractor","attractor","_isAnimationSheetEnabled","_animationSheetEnabled","isAnimationSheetEnabled","_hasTargetStopDurationDependantGradient","_startSizeGradients","_emitRateGradients","_lifeTimeGradients","blendMode","BLENDMODE_ADD","BLENDMODE_ONEONE","BLENDMODE_STANDARD","BLENDMODE_MULTIPLY","BLENDMODE_SUBTRACT","_dragGradients","_limitVelocityGradients","_colorGradients","_sizeGradients","_colorRemapGradients","_alphaRemapGradients","_angularSpeedGradients","_velocityGradients","addEmitRateGradient","particleEmitterType","isBillboardBased","_isBillboardBased","factorGradients","newGradient","factorGradient","valueGradient","emitRate","manualEmitCount","disposeOnStop","minEmitPower","maxEmitPower","minLifeTime","maxLifeTime","minSize","minScaleX","maxScaleX","minScaleY","maxScaleY","minInitialRotation","maxInitialRotation","minAngularSpeed","maxAngularSpeed","customShader","preventAutoStart","preWarmStepOffset","spriteCellChangeSpeed","startSpriteCellID","endSpriteCellID","spriteCellWidth","spriteCellHeight","spriteCellLoop","translationPivot","beginAnimationOnStart","beginAnimationFrom","beginAnimationTo","beginAnimationLoop","limitVelocityDamping","colorDead","_imageProcessingConfigurationDefines","ImageProcessingConfigurationDefines","particleEmitter","CreatePointEmitter","CreateHemisphericEmitter","CreateSphereEmitter","CreateDirectedSphereEmitter","createCylinderEmitter","CreateCylinderEmitter","createDirectedCylinderEmitter","CreateDirectedCylinderEmitter","CreateConeEmitter","createDirectedConeEmitter","CreateDirectedConeEmitter","createBoxEmitter","createMeshEmitter","CreateMeshEmitter","BLENDMODE_MULTIPLYADD","_Registered$5w","ColorSplitterBlock","inputsAreExclusive","rgbIn","rgbOut","rgbOutput","rOutput","gOutput","bOutput","aOutput","_Registered$5v","TrigonometryBlockOperations","Cos","Sin","Abs","Exp","Exp2","Round","Floor","Ceiling","Sqrt","Tan","ArcTan","ArcCos","ArcSin","Fract","Sign","Radians","Degrees","_operation_decorators","_Registered$5u","TrigonometryBlock","NodeMaterialDefinesBase","NodeMaterialDefines","POSITIONW_AS_VARYING","markAsUnprocessedIfDirty","NodeMaterialBase","buildIsInProgress","_buildIsInProgress","NODEEDITOR","NodeEditor","DefaultShaderLanguage","_buildWasSuccessful","_optimizers","_animationFrame","ignoreAlpha","_ignoreAlpha_initializers","_ignoreAlpha_extraInitializers","_vertexOutputNodes","_fragmentOutputNodes","__mode_initializers","__mode_extraInitializers","_forceAlphaBlending_extraInitializers","UseNativeShaderLanguageOfEngine","optimizer","addOutputNode","_addVertexOutputNode","_addFragmentOutputNode","removeOutputNode","_removeVertexOutputNode","_removeFragmentOutputNode","forceAlphaBlending","_sharedData","_preparationId","nodesToProcessForOtherBuildState","_attachBlock","_processInitializeOnLink","loopBlock","loopID","teleport","_resetDualBlocks","updateBuildId","_vertexCompilationState","Particle","SFE","_fragmentCompilationState","needToPurgeList","fragmentOutputNodes","NodeMaterialBuildStateSharedData","vertexNodes","fragmentNodes","vertexOutputNode","fragmentOutputNode","waitingNodeCount","_finishBuildProcess","noError","prePassTextureInputs","_prepareDefinesForAttributes","oldNormal","oldTangent","oldColor","uvChanged","oldUV","PrepareDefines","prePassTextureOutputs","prePassOutputBlock","screenDepth","viewNormal","worldNormal","reflectivity","velocityLinear","prePassTextureBlocks","getAllTextureBlocks","prePassTexturesRequired","cfg","getEffectConfiguration","needsImageProcessing","texturesRequired","prePassTexture","createPostProcess","_createEffectForPostProcess","createEffectForPostProcess","deferredPostProcess","tempName","_processDefines","currentVertexCode","_checkInternals","refreshEffect","_createEffectForParticles","particleSystemDefinesJoined","particleSystemDefines","fillDefines","setCustomEffect","particleSystemDefinesJoinedCurrent","createEffectForParticles","buildObserver","initializeDefines","replaceRepeatableContent","updateUniformsAndSamples","mergedUniforms","mergedSamplers","provideFallbacks","compiledShaders","processingDefines","getProcessedShaderAsync","tb","getTextureBlocks","NodeMaterialBlockIsTextureBlock","_createNodeEditor","BJSNODEMATERIALEDITOR","_getGlobalNodeMaterialEditor","positionInput","worldInput","viewProjectionInput","worldPosdMultipliedByViewProjection","vertexOutput","pixelColor","fragmentOutput","const1","vmerger","currentScreen","textureUrl","Time","vectorMerger","rampGradient","cSplitter","blendMultiply","NodeMaterialParseFromFileAsync","vertexBlocks","fragmentBlocks","outputNodes","_IsDefaultImageProcessingConfiguration","_DefaultImageProcessingConfigurationSerialized","previousImageProcessingConfiguration","previousImageProcessingObserver","hasSerializedImageProcessingConfiguration","useParsedConfiguration","parsedImageProcessingConfiguration","urlRewriter","ParseAlphaMode","shareEffect","textureReadyPromises","textureResolve","textureReject","_ErrorFromReason","_ignoreAlpha_decorators","_forceAlphaBlending_decorators","__mode_decorators","NodeMaterialParse","NodeMaterial","errorObserver","url_1","finalName","_WaitForBuildAsync","NodeMaterialCreateDefault","waitForTextureReadyness","whenTexturesReadyAsync","_WaitForBuildAndTexturesAsync","_Registered$5t","_BlockIsTextureBlock","NodeMaterialParseFromSnippetAsync","CreateDefault","ControllerOrbAnimationState","WebXRNearControllerMode","LocalTempVectors","WebXRNearInteraction","touchCollisionMesh","touchCollisionMeshFunction","hydrateCollisionMeshFunction","_generateNewTouchPointMesh","nearInteractionTargetMesh","stalePick","currentAnimationState","DEHYDRATED","grabRay","hoverInteraction","grabInteraction","pickedPointVisualCue","_worldScaleObserver","_generateVisualCue","enableNearInteractionOnAllControllers","_attachNearInteractionMode","_farInteractionFeature","alwaysHideSelectionMesh","_hoverRadius","_pickRadius","_controllerPickRadius","_nearGrabLengthScale","nearInteractionControllerMode","farInteractionFeature","setFarInteractionFeature","_nearPickPredicate","_nearGrabPredicate","HOVER","TOUCH","handData","xrIndexTip","indexTipPose","getJointPose","axisRHSMultiplier","_processTouchPoint","controllerPose","populateNearInteractionInfo","nearInteractionInfo","nearInteractionAtOrigin","utilitySceneHoverPick","_pickWithSphere","_nearInteractionPredicate","hoverPickInfo","accuratePickInfo","utilitySceneNearPick","nearPick","_setPointerSelectionDisabledByPointerId","_handleTransitionAnimation","_isControllerReadyForNearInteraction","_getPointerSelectionDisabledByPointerId","grabCheck","disableSwitchOnClick","squeezeComponent","onSqueezeButtonChangedObserver","meshCreationScene","worldScale","motionControllerOrbMaterial","parsePromise","motionControllerTouchMaterialSnippetUrl","hoverSizeVec","touchSize","touchSizeVec","hydrateTransitionSize","hydrateTransitionSizeVec","touchHoverTransitionSize","touchHoverTransitionSizeVec","hoverTouchTransitionSize","touchKeys","releaseKeys","hydrateKeys","dehydrateKeys","releaseAction","hydrateAction","dehydrateAction","isHydration","sceneToUse","_controllerAvailablePredicate","WebXRNearInteractionPickMeshWithSphere","tmpVec","tmpDistanceSurfaceToCenter","intersectionInfo","worldToMesh","tmpDistanceSphereToCenter","_Registered$5s","WebXREnterExitUIButton","WebXREnterExitUIOptions","WebXREnterExitUI","_activeButton","_enterXRWithButtonIndexAsync","ignoreSessionGrantedEvent","_onSessionGranted","hostname","customButtons","hmdBtn","_updateButtons","renderCanvas","_helper","supportedPromises","isSessionSupportedAsync","onclick","ui","setHelperAsync","prevTitle","classList","activeButtonChangedObservable","WebXRMotionControllerTeleportation","rotationEnabled","_rotationEnabled","teleportationTargetMesh","_snappedToPoint","_cachedColor4White","skipNextTeleportation","backwardsMovementEnabled","backwardsTeleportationDistance","parabolicCheckRadius","parabolicRayEnabled","straightRayEnabled","rotationAngle","onTargetMeshPositionUpdatedObservable","onBeforeCameraTeleportRotation","onAfterCameraTeleportRotation","teleportationState","backwards","rotating","baseRotation","blocked","initialHit","mainComponentUsed","initMotionController","movementController","getComponentOfType","mainComponent","teleportationComponent","setAndStartTimer","timeToTeleport","_currentTeleportationControllerId","_teleportForward","timeToTeleportStart","teleportLocal","onAxisChangedObserver","axesData","_floorMeshes","_setTargetMeshVisibility","breakObserver","_createDefaultTargetMesh","_snapToPositions","snapPositions","_blockedRayColor","blockedRayColor","snapPointsOnly","snapToPoints","addBlockerMesh","pickBlockerMeshes","addSnapPoint","newSnapPoint","removeBlockerMesh","removeFloorMeshByName","snapPointToRemove","setSelectionFeature","selectionFeature","_selectionFeature","hitPossible","controlSelectionFeature","blockerMeshesPredicate","blockAllPickableMeshes","floorMeshPicked","_showParabolicPath","_setTargetMeshPosition","_buildParabolicRay","_disposeBezierCurve","defaultTargetMeshOptions","teleportationFillColor","teleportationBorderColor","torusArrowMaterial","torusConeMaterial","_teleportationRingMaterial","realPosition","snapToPositionRadius","closestPoint","closestDistance","radiusSquared","snapPosition","_findClosestSnapPointWithRadius","visible","_quadraticBezierCurve","horizontalLengthSq","horizontalLength","effectiveRadius","quadraticBezierVectors","generateRayPathMesh","colorsArray","_Registered$5r","RegisterRay","PhysicsConstraintAxisLimitMode","PhysicsConstraintAxis","PhysicsConstraintType","PhysicsShapeType","PhysicsConstraintMotorType","PhysicsEventType","PhysicsMotionType","PhysicsPrestepType","PhysicsActivationControl","HandPart","PhysicsBody","disablePreStep","_prestepType","DISABLED","TELEPORT","startsAsleep","_collisionCBEnabled","_collisionEndedCBEnabled","disableSync","_shape","initBodyInstances","initBody","_nodeDisposeObserver","getMotionType","startAsleep","clonedBody","setMassProperties","setLinearDamping","getLinearDamping","setAngularDamping","getAngularDamping","updateBodyInstances","numInstances","setShape","getBodyBoundingBox","eventMask","setEventMask","getEventMask","setPrestepType","prestepType","computeMassProperties","linVel","angVel","angularImpulse","torque","getBodyGeometry","getCollisionEndedObservable","setCollisionEndedCallbackEnabled","getObjectCenterWorld","getObjectCenterWorldToRef","addConstraint","childInstanceIndex","syncWithBone","setGravityFactor","getGravityFactor","setTargetTransform","removeBody","disposeBody","PhysicsShape","_isTrigger","getShapeType","initShape","filterMembershipMask","setShapeFilterMembershipMask","membershipMask","getShapeFilterMembershipMask","filterCollideMask","collideMask","setShapeFilterCollideMask","getShapeFilterCollideMask","setMaterial","setDensity","getDensity","newChild","childToWorld","parentToWorld","childToParent","childIndex","getNumChildren","getBoundingBox","isTrigger","setTrigger","disposeShape","PhysicsShapeSphere","centerLocal","he","PhysicsShapeCapsule","boundsLocal","pointFromCenter","PhysicsShapeCylinder","PhysicsShapeBox","PhysicsShapeConvexHull","PhysicsShapeMesh","PhysicsShapeContainer","PhysicsShapeHeightField","heightFieldSizeX","heightFieldSizeZ","numHeightFieldSamplesX","numHeightFieldSamplesZ","heightFieldData","PhysicsShapeGroundMesh","groundMesh","PhysicsAggregate","_addSizeOptions","_disposeShapeWhenDisposed","isTriggerShape","_getObjectBoundingBox","getRawBoundingInfo","capRadius","_hasVertices","WebXRHandJoint","HandPartsDefinition","thumb","WebXRHand","handMesh","_handMesh","_jointMeshes","HandJointReferenceArray","jointName","rigMapping","_leftHandedMeshes","_jointsInvisible","_jointScaleFactor","onHandMeshSetObservable","_jointTransforms","_jointTransformMatrices","_jointSpaces","_tempJointMatrix","_jointRadii","_handMeshRoot","jointIdx","setHandMesh","handMeshSkeleton","jointBoneIdx","anyHand","trackingSuccessful","fillPoses","fillJointRadii","jointPose","jointTransform","scaledJointRadius","jointMesh","disposeMeshes","originalMesh","jointMeshes","keepOriginalVisible","trackedMeshes","newInstance","onHandJointMeshGenerated","returnedMesh","impostorType","shapeType","aggregate","WebXRHandTracking","_RightHandGLB","_LeftHandGLB","defaulrHandGLBUrl","DEFAULT_HAND_MODEL_BASE_URL","ImportMeshAsync","DEFAULT_HAND_MODEL_RIGHT_FILENAME","DEFAULT_HAND_MODEL_LEFT_FILENAME","handShader","handColors","fingerColor","tipFresnel","handMeshes","getBlockByName","handNodes","_getBaseLayerWrapper","hd","handGLB","disableHandShader","riggedMeshes","_GenerateDefaultHandMeshRigMapping","XRHand","getHandByControllerId","_attachedHands","_trackingHands","_handResources","rigMappings","onHandAddedObservable","onHandRemovedObservable","webxrHand","meshesUseLeftHandedCoordinates","invisible","_detachHandById","anyJointMeshOptions","disableDefaultMeshes","disableDefaultHandMesh","customMeshes","leftHandedSystemMeshes","leftRigMapping","rightRigMapping","rigMappingTuple","rigMappingTuples","legacyRigMapping","modelJointName","customRigMappings","_originalMesh","_ICOSPHERE_PARAMS","_GenerateTrackedJointMeshes","defaultHandMeshes","scalingFactors","_attachHand","_detachHand","disposeMesh","disposeOnSessionEnd","trackedMesh","DEFAULT_HAND_MODEL_SHADER_URL","_Registered$5q","WebXRDefaultExperienceOptions","WebXRDefaultExperience","RegisterWebXRControllerPointerSelection","RegisterWebXRControllerTeleportation","RegisterWebXRNearInteraction","RegisterWebXRHandTracking","uiOptions","enterExitUI","xrHelper","pointerSelectionOptions","enableFeature","useStablePlugins","teleportationOptions","nearInteractionOptions","handSupportOptions","outputCanvasOptions","_Registered$5p","worldSize","worldCenter","createArcRotateCamera","freeCamera","attachCameraControls","pbr","setGlobalEnvTexture","hdrSkyboxMaterial","hdrSkybox","removeAttribute","onUserActionRequestedObservable","_onUserActionRequestedObservable","_processError","_errorFound","_handlePlay","otherReason","_externalTexture","_snapshotRenderingObserver","_stillImageCaptured","_displayingPosterTexture","_settings","_createInternalTextureOnEvent","__settings_extraInitializers","_currentSrc","__currentSrc_initializers","__currentSrc_extraInitializers","_isVideo_initializers","_updateInternalTexture","_resizeInternalTexture","poster","independentVideoSource","onplaying","oldMuted","_updateWhileSnapshotRendering","autoUpdateTexture","_getName","_getVideo","ownerScene","videoHasEnoughData","HTMLVideoElement","RemoveSource","_resetSnapshotRenderingIfFast","CreateFromStreamAsync","stream","opacity","onPlaying","videoTexture","audioConstaints","tracks","CreateFromWebCam","__currentSrc_decorators","_isVideo_decorators","__settings_decorators","_Registered$5o","VideoTexture","VideoDome","videoMode","tempOptions","_textureObserver","CubicBezierCurve","shaderCompilationTimeCounter","_shaderCompilationTime","captureShaderCompilationTime","_captureShaderCompilationTime","_onBeforeShaderCompilationObserver","_onAfterShaderCompilationObserver","activeMeshesEvaluationTimeCounter","_activeMeshesEvaluationTime","captureActiveMeshesEvaluationTime","_captureActiveMeshesEvaluationTime","_onBeforeActiveMeshesEvaluationObserver","_onAfterActiveMeshesEvaluationObserver","renderTargetsRenderTimeCounter","_renderTargetsRenderTime","captureRenderTargetsRenderTime","_captureRenderTargetsRenderTime","_onBeforeRenderTargetsRenderObserver","_onAfterRenderTargetsRenderObserver","particlesRenderTimeCounter","_particlesRenderTime","captureParticlesRenderTime","_captureParticlesRenderTime","_onBeforeParticlesRenderingObserver","_onAfterParticlesRenderingObserver","spritesRenderTimeCounter","_spritesRenderTime","captureSpritesRenderTime","_captureSpritesRenderTime","_onBeforeSpritesRenderingObserver","_onAfterSpritesRenderingObserver","physicsTimeCounter","_physicsTime","capturePhysicsTime","_capturePhysicsTime","_onBeforePhysicsObserver","_onAfterPhysicsObserver","animationsTimeCounter","_animationsTime","captureAnimationsTime","_captureAnimationsTime","_onAfterAnimationsObserver","frameTimeCounter","_frameTime","captureFrameTime","_captureFrameTime","interFrameTimeCounter","_interFrameTime","captureInterFrameTime","_captureInterFrameTime","renderTimeCounter","_renderTime","captureRenderTime","_captureRenderTime","_onBeforeDrawPhaseObserver","_removeRenderTimeObservers","cameraRenderTimeCounter","_cameraRenderTime","captureCameraRenderTime","_captureCameraRenderTime","drawCallsCounter","_onAfterDrawPhaseObserver","_onBeforeAnimationsObserver","_removeRenderTargetsObservers","EffectLayerSceneComponent","_renderEffects","_needStencil","_previousStencilState","_renderMainTexture","_drawRenderingGroup","_setStencilBack","_drawCamera","removeEffectLayer","_Registered$5n","effectLayerClass","_thinEffectLayer","getEffectIntensity","setEffectIntensity","_effectLayerOptions","_mainTextureCreatedSize","_maxSize","_mainTextureDesiredSize","onBeforeRenderMainTextureObservable","_internalThinEffectLayer","thinEffectLayer","_internalRender","RegisterEffectLayerSceneComponent","_setMainTextureSize","_createMainTexture","_arePostProcessAndMergeReady","_disposeTextureAndPostProcesses","_shouldRenderEmissiveTextureForMesh","parsedEffectLayer","_get_neutralColor_decorators","_get_isEnabled_decorators","_get_camera_decorators","serializeAsCameraReference","_get_renderingGroupId_decorators","_get_disableBoundingBoxesFromEffectLayer_decorators","__options_initializers","blurTextureWidth","blurTextureHeight","_blurTexture1","blurTextureWidth2","blurTextureHeight2","_blurTexture2","thinBlurPostProcesses1","thinBlurPostProcesses2","thinBlurPostProcesses3","thinBlurPostProcesses4","_postProcesses1","_postProcesses2","mainTextureSamples","internalTexture2","parsedGlowLayer","__options_decorators","DefaultBlurKernelSize","_Registered$5m","GlowLayer","GlowBlurPostProcess","_blurTexture","parsedHightlightLayer","hl","highlightedMesh","_get_innerGlow_decorators","_get_outerGlow_decorators","_get_numStencilBits_decorators","_Registered$5l","HighlightLayer","_enableDepthRenderer","mainTextureDesiredSize","addSelection","selectionMap","meshUniqueIdToSelectionId","meshIds","parsedSelectionOutlineLayer","selectionOutlineLayer","outlinedMeshes","_Registered$5k","SelectionOutlineLayer","LayerSceneComponent","_drawCameraForegroundWithoutPostProcessing","_drawRenderTargetForegroundWithoutPostProcessing","_drawCameraPredicate","isBackground","applyPostProcess","cameraLayerMask","renderOnlyInRenderTargetTextures","_drawCameraBackground","_drawCameraForegroundWithPostProcessing","_drawRenderTargetPredicate","renderTargetTextures","_drawRenderTargetBackground","_drawRenderTargetForegroundWithPostProcessing","Layer","_applyPostProcess","imgUrl","layerComponent","_previousDefines","layer_vertex","layer_fragment","layer_vertex$1","layer_fragment$1","name$9G","shader$9G","name$9F","shader$9F","name$9E","shader$9E","name$9D","shader$9D","includes$24","clipPlaneFragmentDeclaration$1","clipPlaneFragment$1","name$9C","shader$9C","name$9B","shader$9B","name$9A","shader$9A","includes$23","clipPlaneVertexDeclaration$1","clipPlaneVertex$1","name$9z","shader$9z","name$9y","shader$9y","name$9x","shader$9x","includes$22","clipPlaneFragmentDeclarationWGSL","clipPlaneFragmentWGSL","name$9w","shader$9w","name$9v","shader$9v","name$9u","shader$9u","includes$21","clipPlaneVertexDeclarationWGSL","clipPlaneVertexWGSL","name$9t","shader$9t","name$9s","shader$9s","name$9r","shader$9r","name$9q","shader$9q","name$9p","shader$9p","name$9o","shader$9o","name$9n","shader$9n","includes$20","name$9m","shader$9m","name$9l","shader$9l","includes$1$","name$9k","shader$9k","LensFlare","AddFlare","_system","_onShadersLoaded","lensFlares","LensFlareSystemSceneComponent","lensFlareSystem","lensFlaresEnabled","_Registered$5j","lensFlareSystemClass","parsedLensFlareSystem","lf","newLensFlareSystem","borderLimit","viewportBorder","RegisterLensFlareSystemSceneComponent","LensFlareSystem","_emitter","lensFlare_fragment","lensFlare_vertex","lensFlare_fragment$1","lensFlare_vertex$1","setEmitter","newEmitter","computeEffectivePosition","globalViewport","getEmitterPosition","meshesSelectionPredicate","awayX","awayY","away","flare","emitterId","flares","parsedFlare","getEmitter","name$9j","shader$9j","name$9i","shader$9i","name$9h","shader$9h","name$9g","shader$9g","name$9f","shader$9f","name$9e","shader$9e","name$9d","shader$9d","name$9c","shader$9c","includes$1_","bayerDitherFunctionsWGSL","shadowMapFragmentExtraDeclarationWGSL","shadowMapFragmentWGSL","name$9b","shader$9b","name$9a","shader$9a","name$99","shader$99","name$98","shader$98","includes$1Z","helperFunctionsWGSL","sceneUboDeclarationWGSL","meshUboDeclarationWGSL","shadowMapVertexExtraDeclarationWGSL","shadowMapVertexNormalBiasWGSL","shadowMapVertexMetricWGSL","name$97","shader$97","name$96","shader$96","name$95","shader$95","name$94","shader$94","name$93","shader$93","name$92","shader$92","includes$1Y","bayerDitherFunctions","shadowMapFragmentExtraDeclaration","shadowMapFragment","name$91","shader$91","shader$90","name$90","name$8$","shader$8$","name$8_","shader$8_","name$8Z","shader$8Z","name$8Y","shader$8Y","name$8X","shader$8X","name$8W","shader$8W","name$8V","shader$8V","name$8U","shader$8U","includes$1X","helperFunctions","sceneVertexDeclaration","meshVertexDeclaration","shadowMapVertexDeclaration","sceneUboDeclaration","meshUboDeclaration","shadowMapUboDeclaration","shadowMapVertexExtraDeclaration","shadowMapVertexNormalBias","shadowMapVertexMetric","name$8T","shader$8T","name$8S","shader$8S","shadowAngle","_shadowAngle","previousNeedCube","_get_shadowAngle_decorators","_Registered$5i","PointLight","_position_extraInitializers","_ltcTextures","LTC1","LTC2","ltc1","ltc2","ltcEncoded","pixelIndex","CreateSceneLTCTextures","transferTexturesToEffect","_position_decorators","emissionTexture","_emissionTextureTexture","_pointTransformedPosition","_pointTransformedWidth","_pointTransformedHeight","_serializeEmissionTexture","serializedEmissionTexture","referencedTexture","_BuildEmbeddedEmissionTexture","_BuildEmbeddedEmissionTextureAsync","base64Promise","_onParsed","_computeTransformedInformation","_Registered$5h","RectAreaLight","ClusteredLightingSceneComponent","_Registered$5g","clusteredLightContainerClass","BakedVertexAnimationSettingsInstancedKind","ApplyBoundingBiasToMinAndMax","UpdateTransformedMinAndMaxToRef","globalMinimum","globalMaximum","corner","transformed","UpdateTransformedDataMinAndMaxToRef","_Registered$5f","_thinInstanceInitializeUserStorage","_thinInstanceUpdateBufferSize","staticBuffer","splatInstancesBuffer","thinInstanceAllowAutomaticStaticBufferRecreation","_thinInstanceRecreateBuffer","dataOrLength","forceRefreshParentInfo","bakedVertexAnimationSettingsData","bakedVertexAnimationSettingsStride","HasCpuReadableBakedVertexAnimationData","rawMinimum","rawMaximum","localMinimum","localMaximum","settingsOffset","positionData","ExtractMinAndMaxToRef","UpdateRawBoundingVectors","TryUpdateBakedVertexAnimationThinInstanceBoundingInfo","kindIsMatrix","currentSize","_GetEngineBatchSize","IsLightSupported","_batchSize","_lights","horizontalTiles","_horizontalTiles","horizontal","_tileMaskBatches","verticalTiles","_verticalTiles","vertical","depthSlices","_depthSlices","slices","maxRange","_maxRange","_minInverseSquaredRange","_sortedLights","_lightDataRenderId","_sliceScale","_lastBoundLightIndex","RegisterEnginesExtensionsEngineRawTexture","RegisterEnginesExtensionsEngineRenderTarget","RegisterEnginesExtensionsEngineRenderTargetTexture","RegisterThinInstanceMesh","_proxyMaterial","lightProxy_vertex","lightProxy_fragment","lightProxy_vertex$1","lightProxy_fragment$1","_proxyMesh","_sliceRanges","RegisterClusteredLightingSceneComponent","batches","_tileMaskTexture","maxLights","_lightDataBuffer","_lightDataTexture","_tileMaskBuffer","_getSliceIndex","_sliceBias","viewPosition","logFarNear","minSlice","off","computed","inverseSquaredRange","spotLight","firstSlice","lastSlice","sortedLights","sortedIndex","hscale","vscale","clusteredLights","parsedChildLights","parsedChildLight","childLight","_get_horizontalTiles_decorators","_get_verticalTiles_decorators","_get_depthSlices_decorators","_get_maxRange_decorators","_Registered$5e","ClusteredLightContainer","name$8R","shader$8R","name$8Q","shader$8Q","name$8P","shader$8P","includes$1W","clusteredLightingFunctions","name$8O","shader$8O","name$8N","shader$8N","name$8M","shader$8M","includes$1V","clusteredLightingFunctionsWGSL","LineToArray","dataPointer","targetArray","InterpolateCandelaValues","phiIndex","thetaIndex","startTheta","endTheta","startPhi","numberOfHorizontalAngles","horizontalAngles","numberOfVerticalAngles","verticalAngles","endPhi","deltaTheta","deltaPhi","nextThetaIndex","candelaValues","numberOfLights","lumensPerLamp","photometricType","unitsType","ReadArray","maxCandela","name$8L","DefaultLoadingScreen","_loadingText","_loadingDivBackgroundColor","_resizeLoadingUI","_isLoading","loadingDiv","_isCanvasLayoutChanged","previousCanvasRect","canvasPositioning","getComputedStyle","currentCanvasRect","scrollX","scrollY","_loadingDivToRenderingCanvasMap","pointerEvents","gridTemplateRows","gridTemplateColumns","justifyItems","_loadingTextDiv","marginTop","fontFamily","textAlign","innerHTML","imgBack","DefaultLogoUrl","svgSupport","gridColumn","gridRow","imageSpinnerContainer","imgSpinner","DefaultSpinnerUrl","transformOrigin","logoSize","loadingSize","canvases","clonedLoadingDiv","cloneNode","completedTransitions","onTransitionEnd","_Registered$5d","RegisterAbstractEngineLoadingScreen","FileFaceOrientation","worldAxisForNormal","worldAxisForFileX","worldAxisForFileY","CubeMapToSphericalPolynomialTools","rawTargetSize","_sphericalPolynomialTargetSize","_NearestPow2Floor","useMip","rightPromise","leftPromise","upPromise","downPromise","frontPromise","backPromise","down","front","effectiveSize","needsCpuDownsample","_DownsampleFace","cubeInfo","ConvertCubeMapToSphericalPolynomial","_AreaElement","dstLength","dstSize","avg","srcSize","invArea","sy0","sy1","sx0","sx1","dstIdx","downsampled","sphericalHarmonics","du","minUV","halfTexel","fileFace","_FileFaces","worldDirection","MAX_HDRI_VALUE","PRESERVE_CLAMPED_COLORS","currentMax","totalSolidAngle","correctionFactor","convertIncidentRadianceToIrradiance","convertIrradianceToLambertianRadiance","HDRFiltering","hdrScale","intTexture","hdrFiltering_vertex","hdrFiltering_fragment","hdrFiltering_vertex$1","hdrFiltering_fragment$1","_createEffect","whenCompiledAsync","_prefilterInternal","HDRIrradianceFiltering","useCdf","irradianceSize","_cdfGenerator","hdrIrradianceFiltering_vertex","hdrIrradianceFiltering_fragment","hdrIrradianceFiltering_vertex$1","hdrIrradianceFiltering_fragment$1","EnvCubeTexture","_generateHarmonics","_prefilterOnLoad","prefilterOnLoad","_prefilterIrradianceOnLoad","prefilterIrradianceOnLoad","_prefilterUsingCdf","prefilterUsingCdf","_supersample","supersample","generateHarmonics","_onLoad","previousOnLoad","previousOnError","hdrFiltering","prefilterPendingToken","hdrIrradianceFiltering","prefilter","innerScene","prefilterUnavailable","byteArray","shortArray","dataFace","useInGammaSpace","PanoramaToCubeMapTools","ConvertPanoramaToCubemap","inputWidth","inputHeight","FACE_FRONT","CreateCubemapTexture","FACE_BACK","FACE_LEFT","FACE_RIGHT","FACE_UP","FACE_DOWN","texSize","sampleFactor","sampleFactorSqr","rotDX1","rotDX2","fy","xv1","xv2","CalcProjectionSpherical","vDir","px","py","inputY","Rgbe2float","float32array","mantissa","Ldexp","ReadStringLine","uint8array","endOfHeader","findFormat","dataPosition","hdrInfo","RGBE_ReadHeader","numScanlines","scanlineWidth","scanLineArrayBuffer","ReadRGBEPixelsNotRLE","scanLineArray","ReadRGBEPixelsRLE","HDRCubeTexture","GetCubeMapTextureData","_instantiateClone","_Registered$5c","_influence","onInfluenceChanged","_uv2s","_colors","_onDataLayoutChanged","_morphTargetManager_initializers","_morphTargetManager_extraInitializers","hadPositions","hadNormals","hadTangents","hadUVs","setUV2s","hadUV2s","hadColors","FromMesh","_morphTargetManager_decorators","RawTexture2DArray","MorphTargetManager","areUpdatesFrozen","_blockCounter","_syncActiveTargets","_forceUpdateWhenUnfrozen","_targets","_targetInfluenceChangedObservers","_targetDataLayoutChangedObservers","_supportsPositions","_supportsNormals","_supportsTangents","_supportsUVs","_supportsUV2s","_supportsColors","_vertexCount","_tempInfluences","_canUseTextureForTargets","_mustSynchronize","optimizeInfluencers","enablePositionMorphing","enableNormalMorphing","enableTangentMorphing","enableUVMorphing","enableUV2Morphing","enableColorMorphing","_numMaxInfluencers","_useTextureToStoreTargets","_influencesAreDirty","_needUpdateInfluences","ConstantTargetCountForTextureMode","_influences","useTextureToStoreTargets","EnableTextureStorage","getActiveTarget","getTargetByName","addTarget","_targetStoreTexture","wasUsingTextureForTargets","influenceCount","MaxActiveMorphTargetsInVertexAttributeMode","morph","MorphTarget","useFloat","_add","__attachedMesh_initializers","_position_initializers","_renderTargetTexture","currentApplyByPostProcess","_invertYAxis","lookAtFunction","perspectiveFunction","isReflectionProbe","__attachedMesh_decorators","__attachedMesh_extraInitializers","_Registered$5b","ReflectionProbeParse","parsedReflectionProbe","rp","ReflectionProbe","newReflectionProbe","ThinSprite","_animationStarted","fromIndex","_fromIndex","toIndex","_toIndex","_animationSceneId","_onBaseAnimationEnd","playAnimation","cellIndex","Sprite","useAlphaForPicking","_onAnimationEnd","_endAnimation","disposeWhenFinishedAnimating","sprites","cellRef","invertU","invertV","parsedSprite","sprite","SpriteSceneComponent","_tempSpritePickingRay","_spritePredicate","_pointerMove","_pointerUp","originalPointerInfo","_pickSpriteButKeepRay","_pointerOverSprite","_pointerDown","_pickedDownSprite","pickedSprite","spritePickResult","_Registered$5a","_onNewSpriteManagerAddedObservable","onNewSpriteManagerAddedObservable","_onSpriteManagerRemovedObservable","onSpriteManagerRemovedObservable","_internalPickSprites","spriteIndex","_internalMultiPickSprites","multiIntersects","SpriteRenderer","pixelPerfect","_pixelPerfect","autoResetAlpha","_useVAO","_previousVertexData","_previousBuffer","_vertexBuffersWithPrevious","_drawCaches","rendererOptions","_vertexBufferSize","spriteData","_spriteBuffer","inverts","cellInfo","sprites_vertex","sprites_fragment","sprites_vertex$1","sprites_fragment$1","_getDrawCache","drawWrapperBase","_disposeDrawCaches","mainCache","_drawWrapperBase","_drawWrapperDepth","drawWrapperDepth","variantKey","geometryConfiguration","geometryDefines","usesGeometryRendering","_disposeDrawCache","usesVelocity","joinedDefines","usesObjectId","usesMeshBlendTag","_ensurePreviousVertexBuffer","effectOptions","usesInverseView","usesNormals","usesNormalizedDepth","cameraHistories","releasedCache","_disposePreviousVertexBufferIfUnused","_disposePreviousVertexBuffer","_bindVertexBuffers","cameraKey","previousView","currentView","previousProjection","currentProjection","spriteHistory","previousZ","currentZ","previousAngle","previousWidth","currentWidth","previousHeight","currentHeight","_animateSprite","_animationFrameId","drawCache","shouldRenderFog","noSprite","baseSize","getBaseSize","cameraHistory","_prepareSpriteHistory","_appendSpriteVertex","customSpriteUpdate","_updateSpriteHistory","arrayOffset","rowSize","cellWidth","_xOffset","_yOffset","cellHeight","_xSize","_ySize","writeHistory","previousArrayOffset","SpriteManager","_spriteRenderer","_textureContent","_disableDepthWrite","spriteRenderer","_packedAndReady","_customUpdate","_spriteMap","_cellData","RegisterSpriteSceneComponent","_fromPacked","fromPacked","spriteRendererOptions","cellSize","_makePacked","spriteJSON","celldata","frametemp","spritemap","ownKeys","re","jsonUrl","contactPointU","contactPointV","currentSprite","cameraSpacePosition","cameraView","activeRay","pickedRay","_checkTextureAlpha","serializeTexture","parsedManager","CannonJSPlugin","_useDeltaForWorldStep","cannonInjection","CANNON","_physicsMaterials","_fixedTimeStep","_physicsBodiesToRemoveAfterStep","_minus90X","_plus90X","_tmpDeltaPosition","_tmpUnityRotation","BJSCANNON","_extendNamespace","broadphase","NaiveBroadphase","solver","_cannonRaycastResult","RaycastResult","_raycastResult","impostors","_removeMarkedPhysicsBodiesFromWorld","worldPoint","Vec3","_createShape","oldBody","nativeOptions","bodyCreationObject","Body","addShape","_processChildMeshes","_updatePhysicsBodyTransformation","meshChildren","mainRotation","conjugateToRef","processMesh","childImpostor","pPosition","mainBody","connectedBody","constraintData","mainPivot","connectedPivot","mainAxis","connectedAxis","collideConnected","collision","HingeConstraint","DistanceConstraint","springData","Spring","restLength","localAnchorA","localAnchorB","LockConstraint","PointToPointConstraint","forceApplicationCallback","removeConstraint","unregisterAfterPhysicsStep","_addMaterial","currentMat","impostorExtents","Sphere","_checkWithEpsilon","numSegments","setFromAxisAngle","transformAllPoints","Box","rawVerts","rawFaces","oldPosition","oldRotation","oldQuaternion","transformedVertices","oldPosition2","oldRotation2","oldQuaternion2","_createHeightmap","pointDepth","dim","elementSize","loc","Heightfield","oldPivot","setTransformationFromPhysicsBody","angularVelocity","updateMassProperties","enableMotor","setMotorSpeed","minForce","motorEquation","shapes","boundingSphereRadius","halfExtents","step_tmp1","timeSinceLastCalled","internalStep","h_div_dt","interpvelo","bodies","STATIC","sleepState","SLEEPING","vsub","vadd","interpolatedQuaternion","raycastClosest","_Registered$59","OimoJSPlugin","oimoInjection","OIMO","_tmpImpostorsArray","_tmpPositionVector","BJSOIMO","contact","touching","body1","sleeping","body2","collidingImpostor","invScale","bodyConfig","posShape","rotShape","addToArray","checkWithEpsilon","globalQuaternion","radToDeg","removeRigidBody","nativeJointData","axe1","axe2","getQuaternion","syncShapes","awake","linearVelocity","staticBody","setupMass","limitMotor","motor","rotationalLimitMotor2","rotationalLimitMotor1","rotationalLimitMotor","AmmoJSPlugin","ammoInjection","Ammo","overlappingPairCache","bjsAMMO","_maxSteps","_tmpContactCallbackResult","_tmpContactPoint","_tmpContactNormal","_tmpVec3","_collisionConfiguration","btSoftBodyRigidBodyCollisionConfiguration","_dispatcher","btCollisionDispatcher","_overlappingPairCache","btDbvtBroadphase","_solver","btSequentialImpulseConstraintSolver","_softBodySolver","btDefaultSoftBodySolver","btSoftRigidDynamicsWorld","_tmpAmmoConcreteContactResultCallback","ConcreteContactResultCallback","addSingleResult","wrapPointer","btManifoldPoint","getPositionWorldOnA","m_normalWorldOnB","_tmpContactImpulse","getAppliedImpulse","_tmpContactDistance","getDistance","_tmpAmmoTransform","btTransform","setIdentity","_tmpAmmoQuaternion","btQuaternion","_tmpAmmoVectorA","btVector3","_tmpAmmoVectorB","_tmpAmmoVectorC","_tmpAmmoVectorD","getWorldInfo","set_m_gravity","setFixedTimeStep","fixedTimeStep","setMaxSteps","_isImpostorInContact","contactTest","_isImpostorPairInContact","impostorA","impostorB","contactPairTest","_stepSimulation","stepSimulation","_afterSoftStep","collideCallback","isActive","_ropeStep","_softbodyOrClothStep","bodyVertices","get_m_nodes","nbVertices","nodePositions","get_m_x","_isFromLine","normalDirection","vertexPositions","vertexNormals","nx","ny","nz","nodeNormals","get_m_n","localTranslation","colShape","get_m_cfg","set_collisions","set_kDP","castObject","setMargin","setActivationState","_DISABLE_DEACTIVATION_FLAG","addSoftBody","toDispose","SoftbodyImpostor","localInertia","startTransform","calculateLocalInertia","setOrigin","myMotionState","btDefaultMotionState","rbInfo","btRigidBodyConstructionInfo","setCollisionFlags","getCollisionFlags","_KINEMATIC_FLAG","getChildShape","_DISABLE_COLLISION_FLAG","addRigidBody","removeSoftBody","btPoint2PointConstraint","btHingeConstraint","btTriangleMesh","topLevelObject","triangleCount","topLevelQuaternion","faceCount","triPoints","addTriangle","_addMeshVerts","_softVertexData","newPoints","newNorms","_createSoftbody","btCompoundShape","triNorms","softBody","btSoftBodyHelpers","CreateFromTriMesh","setX","setY","setZ","_createCloth","segs","CreatePatch","_createRope","pathVectors","ropeBody","CreateRope","onCreateCustomShape","btConvexHullShape","addPoint","_addHullVerts","childrenAdded","parentMat","getOrigin","addChildShape","btSphereShape","radii","btMultiSphereShape","setLocalScaling","btCapsuleShape","btCylinderShape","btBoxShape","onCreateCustomMeshImpostor","triMesh","btBvhTriangleMeshShape","onCreateCustomConvexHullImpostor","convexHull","_createCustom","getMotionState","setWorldTransform","motionState","setTotalMass","setMassProps","set_kDF","setFriction","setRestitution","set_kPR","get_m_materials","set_m_kLST","set_viterations","set_piterations","forceActivationState","enableAngularMotor","getWorldTransform","_tmpAmmoVectorRCA","rayCallback","ClosestRayResultCallback","_tmpAmmoVectorRCB","rayTest","get_m_hitNormalWorld","get_m_hitPointWorld","_BabylonLoaderRegistered","BabylonFileLoaderConfiguration","LoaderInjectedPhysicsEngine","TempMaterialIndexContainer","TempMorphTargetManagerIndexContainer","TempSkeletonIndexContainer","producer","exporter_version","LoadDetailLevels","lodmeshes","mastermesh","lodid","lodmesh","wasenabled","FindParent","parentEntry","TempIndexContainer","FindMaterial","LoadAssetContainerFromSerializedScene","serializedScene","LoadAssetContainer","savedObservables","isPBR","environmentTextureType","hdrSize","environmentTextureSize","hdrTexture","environmentTexturePrefilterOnLoad","environmentTextureRotationY","compressedTexture","environmentTextureForcedExtension","skyboxScale","skyboxBlurLevel","mmat","parsedTarget","TempMorphTargetIndexContainer","addedGeometry","partProxies","proxies","partProxy","_waitingParsedUniqueId","nodeMap","parsedTargetAnimation","isMorphTarget","parsedSpriteManager","multimat","currentTransformNode","excludedIndex","includedOnlyIndex","includedOnlyMesh","logOperation","_Registered$58","RegisterTexture","ParseMaterialByPredicate","IsDescendantOf","hierarchyIds","loadedTransformNodes","parsedJSONTransformNode","parsedIdToNodeMap","loadedSkeletonsIds","loadedMaterialsIds","loadedMaterialsUniqueIds","geoms","geometryType","geom","parsedGeometryData","materialFound","loadSubMaterial","multimatIndex","multimatCache","skeletonCache","loadedMorphTargetManagerIds","morphTargetManagerIndex","parsedParticleSystem","physicsGravity","activeCameraID","name$8K","shader$8K","name$8J","shader$8J","name$8I","shader$8I","name$8H","shader$8H","name$8G","shader$8G","name$8F","shader$8F","name$8E","shader$8E","name$8D","shader$8D","includes$1U","backgroundUboDeclarationWGSL","bonesDeclarationWGSL","fogVertexDeclarationWGSL","lightVxUboDeclarationWGSL","logDepthDeclarationWGSL","fogVertexWGSL","shadowsVertexWGSL","logDepthVertexWGSL","name$8C","shader$8C","name$8B","shader$8B","name$8A","shader$8A","name$8z","shader$8z","name$8y","shader$8y","name$8x","shader$8x","name$8w","shader$8w","name$8v","shader$8v","name$8u","shader$8u","name$8t","shader$8t","name$8s","shader$8s","name$8r","shader$8r","name$8q","shader$8q","name$8p","shader$8p","includes$1T","reflectionFunctionWGSL","imageProcessingDeclarationWGSL","lightUboDeclarationWGSL","ltcHelperFunctionsWGSL","clusteredLightingComputeWGSL","lightsFragmentFunctionsWGSL","shadowsFragmentFunctionsWGSL","imageProcessingFunctionsWGSL","fogFragmentDeclarationWGSL","intersectionFunctionsWGSL","lightFragmentWGSL","logDepthFragmentWGSL","fogFragmentWGSL","name$8o","shader$8o","name$8n","shader$8n","name$8m","shader$8m","name$8l","shader$8l","name$8k","shader$8k","name$8j","shader$8j","name$8i","shader$8i","name$8h","shader$8h","name$8g","shader$8g","name$8f","shader$8f","includes$1S","backgroundUboDeclaration","bonesDeclaration$1","fogVertexDeclaration","lightVxFragmentDeclaration","lightVxUboDeclaration","logDepthDeclaration","fogVertex","shadowsVertex","logDepthVertex","name$8e","shader$8e","name$8d","shader$8d","name$8c","shader$8c","name$8b","shader$8b","name$8a","shader$8a","name$89","shader$89","name$88","shader$88","name$87","shader$87","name$86","shader$86","name$85","shader$85","name$84","shader$84","name$83","shader$83","name$82","shader$82","name$81","shader$81","name$80","shader$80","includes$1R","reflectionFunction","imageProcessingDeclaration","lightFragmentDeclaration","lightUboDeclaration","ltcHelperFunctions","lightsFragmentFunctions","shadowsFragmentFunctions","imageProcessingFunctions","fogFragmentDeclaration","intersectionFunctions","lightFragment","logDepthFragment","fogFragment","FresnelParameters","newFresnelParameters","otherFresnelParameters","_Registered$57","FresnelParametersParse","parsedFresnelParameters","MaterialHelper","PrepareDefinesForFrameBoundValues","OcclusionMaterial","name$7$","shader$7$","includes$1Q","name$7_","shader$7_","name$7Z","shader$7Z","includes$1P","vertexColorMixing","_Registered$56","_sphericalPolynomialComputed","ConvertCubeMapTextureToSphericalPolynomial","_PBRBaseSimpleMaterial_disableLighting_accessor_storage","_PBRBaseSimpleMaterial_environmentTexture_accessor_storage","_PBRBaseSimpleMaterial_invertNormalMapX_accessor_storage","_PBRBaseSimpleMaterial_invertNormalMapY_accessor_storage","_PBRBaseSimpleMaterial_normalTexture_accessor_storage","_PBRBaseSimpleMaterial_emissiveColor_accessor_storage","_PBRBaseSimpleMaterial_emissiveTexture_accessor_storage","_PBRBaseSimpleMaterial_occlusionStrength_accessor_storage","_PBRBaseSimpleMaterial_occlusionTexture_accessor_storage","_PBRBaseSimpleMaterial_alphaCutOff_accessor_storage","_PBRBaseSimpleMaterial_lightmapTexture_accessor_storage","_PBRBaseSimpleMaterial_useLightmapAsShadowmap_accessor_storage","_PBRBaseSimpleMaterial_maxSimultaneousLights_accessor_storage","occlusionTexture","doubleSided","_environmentTexture_extraInitializers","_normalTexture_initializers","_normalTexture_extraInitializers","_occlusionStrength_initializers","_occlusionStrength_extraInitializers","_occlusionTexture_extraInitializers","_environmentTexture_decorators","_normalTexture_decorators","_occlusionStrength_decorators","_occlusionTexture_decorators","_get_doubleSided_decorators","_environmentTexture_initializers","_occlusionTexture_initializers","_PBRMetallicRoughnessMaterial_baseTexture_accessor_storage","_PBRMetallicRoughnessMaterial_metallic_accessor_storage","_PBRMetallicRoughnessMaterial_roughness_accessor_storage","_PBRMetallicRoughnessMaterial_metallicRoughnessTexture_accessor_storage","_PBRMetallicRoughnessMaterial_baseColor_accessor_storage","_baseTexture_extraInitializers","_metallicRoughnessTexture_extraInitializers","_baseTexture_decorators","_metallicRoughnessTexture_decorators","_baseTexture_initializers","_Registered$55","PBRMetallicRoughnessMaterial","_PBRSpecularGlossinessMaterial_diffuseTexture_accessor_storage","_PBRSpecularGlossinessMaterial_specularColor_accessor_storage","_PBRSpecularGlossinessMaterial_glossiness_accessor_storage","_PBRSpecularGlossinessMaterial_specularGlossinessTexture_accessor_storage","_PBRSpecularGlossinessMaterial_diffuseColor_accessor_storage","_glossiness_initializers","_specularGlossinessTexture_extraInitializers","_glossiness_decorators","_specularGlossinessTexture_decorators","_glossiness_extraInitializers","_Registered$54","PBRSpecularGlossinessMaterial","name$7Y","shader$7Y","name$7X","shader$7X","name$7W","shader$7W","name$7V","shader$7V","name$7U","shader$7U","name$7T","shader$7T","name$7S","shader$7S","name$7R","shader$7R","name$7Q","shader$7Q","name$7P","shader$7P","name$7O","shader$7O","name$7N","shader$7N","name$7M","shader$7M","name$7L","shader$7L","name$7K","shader$7K","name$7J","shader$7J","includes$1O","pbrUboDeclarationWGSL","uvAttributeDeclarationWGSL","mainUVVaryingDeclarationWGSL","pbrBRDFFunctionsWGSL","prePassVertexDeclarationWGSL","samplerVertexDeclarationWGSL","harmonicsFunctionsWGSL","bumpVertexDeclarationWGSL","vertexPullingDeclarationWGSL","vertexPullingVertexWGSL","prePassVertexWGSL","uvVariableDeclarationWGSL","samplerVertexImplementationWGSL","bumpVertexWGSL","vertexColorMixingWGSL","name$7I","shader$7I","name$7H","shader$7H","name$7G","shader$7G","name$7F","shader$7F","name$7E","shader$7E","name$7D","shader$7D","name$7C","shader$7C","name$7B","shader$7B","name$7A","shader$7A","name$7z","shader$7z","name$7y","shader$7y","name$7x","shader$7x","name$7w","shader$7w","name$7v","shader$7v","name$7u","shader$7u","name$7t","shader$7t","name$7s","shader$7s","name$7r","shader$7r","name$7q","shader$7q","name$7p","shader$7p","name$7o","shader$7o","name$7n","shader$7n","name$7m","shader$7m","name$7l","shader$7l","name$7k","shader$7k","name$7j","shader$7j","name$7i","shader$7i","name$7h","shader$7h","name$7g","shader$7g","name$7f","shader$7f","name$7e","shader$7e","name$7d","shader$7d","name$7c","shader$7c","name$7b","shader$7b","name$7a","shader$7a","name$79","shader$79","name$78","shader$78","name$77","shader$77","name$76","shader$76","name$75","shader$75","name$74","shader$74","name$73","shader$73","name$72","shader$72","name$71","shader$71","name$70","shader$70","name$6$","shader$6$","name$6_","shader$6_","name$6Z","shader$6Z","includes$1N","prePassDeclarationWGSL","oitDeclarationWGSL","pbrFragmentExtraDeclarationWGSL","samplerFragmentDeclarationWGSL","samplerFragmentAlternateDeclarationWGSL","pbrFragmentReflectionDeclarationWGSL","pbrFragmentSamplersDeclarationWGSL","textureRepetitionFunctionsWGSL","subSurfaceScatteringFunctionsWGSL","importanceSamplingWGSL","pbrHelperFunctionsWGSL","pbrDirectLightingSetupFunctionsWGSL","pbrDirectLightingFalloffFunctionsWGSL","hdrFilteringFunctionsWGSL","pbrBlockReflectance0WGSL","pbrClusteredLightingFunctionsWGSL","pbrDirectLightingFunctionsWGSL","pbrIBLFunctionsWGSL","bumpFragmentMainFunctionsWGSL","bumpFragmentFunctionsWGSL","decalFragmentWGSL","pbrBlockAlbedoOpacityWGSL","pbrBlockReflectivityWGSL","pbrBlockAmbientOcclusionWGSL","pbrBlockAlphaFresnelWGSL","pbrBlockAnisotropicWGSL","pbrBlockReflectionWGSL","pbrBlockSheenWGSL","pbrBlockClearcoatWGSL","pbrBlockIridescenceWGSL","pbrBlockSubSurfaceWGSL","pbrBlockNormalGeometricWGSL","bumpFragmentWGSL","pbrBlockNormalFinalWGSL","depthPrePassWGSL","pbrBlockLightmapInitWGSL","pbrBlockGeometryInfoWGSL","pbrBlockReflectanceWGSL","pbrBlockDirectLightingWGSL","pbrBlockFinalLitComponentsWGSL","pbrBlockFinalUnlitComponentsWGSL","pbrBlockFinalColorCompositionWGSL","pbrBlockImageProcessingWGSL","meshBlendTagFragmentOutputWGSL","pbrBlockPrePassWGSL","oitFragmentWGSL","pbrDebugWGSL","name$6Y","shader$6Y","name$6X","shader$6X","name$6W","shader$6W","name$6V","shader$6V","name$6U","shader$6U","name$6T","shader$6T","name$6S","shader$6S","name$6R","shader$6R","name$6Q","shader$6Q","name$6P","shader$6P","name$6O","shader$6O","name$6N","shader$6N","name$6M","shader$6M","name$6L","shader$6L","name$6K","shader$6K","includes$1M","pbrVertexDeclaration","pbrUboDeclaration","uvAttributeDeclaration","mainUVVaryingDeclaration","pbrBRDFFunctions","prePassVertexDeclaration","samplerVertexDeclaration","harmonicsFunctions","bumpVertexDeclaration","prePassVertex","uvVariableDeclaration","samplerVertexImplementation","bumpVertex","name$6J","shader$6J","name$6I","shader$6I","name$6H","shader$6H","name$6G","shader$6G","name$6F","shader$6F","name$6E","shader$6E","name$6D","shader$6D","name$6C","shader$6C","name$6B","shader$6B","name$6A","shader$6A","name$6z","shader$6z","name$6y","shader$6y","name$6x","shader$6x","name$6w","shader$6w","name$6v","shader$6v","name$6u","shader$6u","name$6t","shader$6t","name$6s","shader$6s","name$6r","shader$6r","name$6q","shader$6q","name$6p","shader$6p","name$6o","shader$6o","name$6n","shader$6n","name$6m","shader$6m","name$6l","shader$6l","name$6k","shader$6k","name$6j","shader$6j","name$6i","shader$6i","name$6h","shader$6h","name$6g","shader$6g","name$6f","shader$6f","name$6e","shader$6e","name$6d","shader$6d","name$6c","shader$6c","name$6b","shader$6b","name$6a","shader$6a","name$69","shader$69","name$68","shader$68","name$67","shader$67","name$66","shader$66","name$65","shader$65","name$64","shader$64","name$63","shader$63","name$62","shader$62","name$61","shader$61","name$60","shader$60","name$5$","shader$5$","name$5_","shader$5_","name$5Z","shader$5Z","name$5Y","shader$5Y","includes$1L","oitDeclaration","decalFragmentDeclaration","pbrFragmentDeclaration","pbrFragmentExtraDeclaration","samplerFragmentDeclaration","samplerFragmentAlternateDeclaration","pbrFragmentReflectionDeclaration","pbrFragmentSamplersDeclaration","textureRepetitionFunctions","subSurfaceScatteringFunctions","importanceSampling","pbrHelperFunctions","pbrDirectLightingSetupFunctions","pbrDirectLightingFalloffFunctions","hdrFilteringFunctions","pbrDirectLightingFunctions","pbrIBLFunctions","bumpFragmentMainFunctions","bumpFragmentFunctions","decalFragment","pbrBlockAlbedoOpacity","pbrBlockReflectivity","pbrBlockAmbientOcclusion","pbrBlockAlphaFresnel","pbrBlockAnisotropic","pbrBlockReflection","pbrBlockSheen","pbrBlockClearcoat","pbrBlockIridescence","pbrBlockSubSurface","pbrBlockReflectance0","pbrClusteredLightingFunctions","pbrBlockNormalGeometric","bumpFragment","pbrBlockNormalFinal","depthPrePass","pbrBlockLightmapInit","pbrBlockGeometryInfo","pbrBlockReflectance","pbrBlockDirectLighting","pbrBlockFinalLitComponents","pbrBlockFinalUnlitComponents","pbrBlockFinalColorComposition","pbrBlockImageProcessing","pbrBlockPrePass","oitFragment","pbrDebug","name$5X","shader$5X","name$5W","shader$5W","name$5V","shader$5V","name$5U","shader$5U","includes$1K","openpbrUboDeclarationWGSL","openpbrNormalMapVertexDeclarationWGSL","openpbrNormalMapVertexWGSL","name$5T","shader$5T","name$5S","shader$5S","name$5R","shader$5R","name$5Q","shader$5Q","name$5P","shader$5P","name$5O","shader$5O","name$5N","shader$5N","name$5M","shader$5M","name$5L","shader$5L","name$5K","shader$5K","name$5J","shader$5J","name$5I","shader$5I","name$5H","shader$5H","name$5G","shader$5G","name$5F","shader$5F","name$5E","shader$5E","name$5D","shader$5D","name$5C","shader$5C","name$5B","shader$5B","name$5A","shader$5A","name$5z","shader$5z","name$5y","shader$5y","name$5x","shader$5x","name$5w","shader$5w","includes$1J","openpbrFragmentSamplersDeclarationWGSL","openpbrNormalMapFragmentMainFunctionsWGSL","openpbrNormalMapFragmentFunctionsWGSL","openpbrDielectricReflectanceWGSL","openpbrConductorReflectanceWGSL","openpbrAmbientOcclusionFunctionsWGSL","openpbrGeometryInfoWGSL","openpbrIblFunctionsWGSL","openpbrVolumeFunctionsWGSL","openpbrNormalMapFragmentWGSL","openpbrBlockNormalFinalWGSL","openpbrBaseLayerDataWGSL","openpbrTransmissionLayerDataWGSL","openpbrSubsurfaceLayerDataWGSL","openpbrCoatLayerDataWGSL","openpbrThinFilmLayerDataWGSL","openpbrFuzzLayerDataWGSL","openpbrAmbientOcclusionDataWGSL","openpbrBackgroundTransmissionWGSL","openpbrEnvironmentLightingWGSL","openpbrDirectLightingInitWGSL","openpbrDirectLightingWGSL","openpbrBlockPrePassWGSL","name$5v","shader$5v","name$5u","shader$5u","name$5t","shader$5t","name$5s","shader$5s","name$5r","shader$5r","includes$1I","decalVertexDeclaration","openpbrVertexDeclaration","openpbrUboDeclaration","openpbrNormalMapVertexDeclaration","openpbrNormalMapVertex","name$5q","shader$5q","name$5p","shader$5p","name$5o","shader$5o","name$5n","shader$5n","name$5m","shader$5m","name$5l","shader$5l","name$5k","shader$5k","name$5j","shader$5j","name$5i","shader$5i","name$5h","shader$5h","name$5g","shader$5g","name$5f","shader$5f","name$5e","shader$5e","name$5d","shader$5d","name$5c","shader$5c","name$5b","shader$5b","name$5a","shader$5a","name$59","shader$59","name$58","shader$58","name$57","shader$57","name$56","shader$56","name$55","shader$55","name$54","shader$54","name$53","shader$53","name$52","shader$52","name$51","shader$51","includes$1H","sceneFragmentDeclaration","openpbrFragmentDeclaration","openpbrFragmentSamplersDeclaration","openpbrNormalMapFragmentMainFunctions","openpbrNormalMapFragmentFunctions","openpbrDielectricReflectance","openpbrConductorReflectance","openpbrAmbientOcclusionFunctions","openpbrGeometryInfo","openpbrIblFunctions","openpbrVolumeFunctions","openpbrNormalMapFragment","openpbrBlockNormalFinal","openpbrBaseLayerData","openpbrTransmissionLayerData","openpbrSubsurfaceLayerData","openpbrCoatLayerData","openpbrThinFilmLayerData","openpbrFuzzLayerData","openpbrAmbientOcclusionData","openpbrBackgroundTransmission","openpbrEnvironmentLighting","openpbrDirectLightingInit","openpbrDirectLighting","openpbrBlockPrePass","ShaderLanguage","ColorGradingTexture","_triggerOnLoad","_load3dlTexture","tempData","pixelIndexW","pixelIndexH","pixelIndexSlice","maxColor","_NoneEmptyLineRegex","words","pixelStorageIndex","toLocaleLowerCase","_Registered$53","ColorGradingTextureParse","EquiRectangularCubeTexture","_loadImage","loadTextureCallback","_FacesMapping","_getFloat32ArrayFromArrayBuffer","floatImageData","USHORT_RANGE","HUF_DECBITS","HUF_ENCSIZE","CompressionCodes","LineOrders","uintBuffer","endOffset","stringValue","ParseInt32","ParseUint32","ParseUint8","ParseUint16","ParseUint8Array","ParseInt64","getBigInt64","ParseFloat32","ParseFloat16","ParseFixedLengthString","pixelType","pLinear","xSampling","ySampling","ParseChlist","redX","redY","greenX","greenY","blueX","blueY","whiteX","whiteY","ParseChromaticities","ParseCompression","xMin","xMax","ParseBox2i","lineOrder","ParseLineOrder","ParseV2f","ParseV3f","ParseRational","ParseTimecode","Predictor","InterleaveScalar","GetExrHeader","specData","singleTile","longName","deepFormat","multiPart","headerData","keepReading","ParseNullTerminatedString","attributeValue","ParseValue","spec","ReverseLutFromBitmap","lut","GetBits","nBits","lc","GetChar","GetCode","po","rlc","outBuffer","outBufferOffset","outBufferEndOffset","gc","HufTableBuffer","HufLength","HufCode","nCompressed","nRaw","initialInOffset","im","iM","freq","hdec","lit","HufClearDecTable","ni","hcode","gb","zerun","nc","HufCanonicalCodeTable","HufUnpackEncTable","hdecod","pl","plOffset","HufBuildDecTable","encodingTable","decodingTable","no","outOffset","inOffsetEnd","HUF_DECSIZE","gCode","HufDecode","UInt16","ls","Int16","hs","mx","w14","oy1","oy2","ox1","ox2","i00","i01","i10","i11","p01","p10","Wdec14","p11","Wdec16","ApplyLut","nData","DecodeRunLength","decoder","UncompressRLE","compressed","viewer","UncompressZIP","fflate","UncompressPXR","unzlibSync","tmpBufferEnd","writePtr","UncompressPIZ","inDataView","inOffset","scanlineBlockSize","outBufferEnd","pizChannelData","minNonZero","maxNonZero","Wav2Decode","tmpOffset","cp","EXROutputType","dataWindow","channelLineOffsets","scanOrder","bytesPerLine","outLineWidth","inputSize","uncompress","outputChannels","decodeChannels","blockCount","NO_COMPRESSION","UncompressRAW","RLE_COMPRESSION","ZIPS_COMPRESSION","ExrLoaderGlobalConfiguration","FFLATEUrl","ZIP_COMPRESSION","PIZ_COMPRESSION","PXR24_COMPRESSION","fillAlpha","R","G","outputType","HalfFloat","DecodeFloat32","scanlineBlockIdx","lineY","scanY","trueY","lineOffset","outLineOffset","channelID","lOff","cOff","outIndex","DefaultOutputType","ScanData","EXRCubeTexture","exrData","ReadExrDataAsync","_Registered$52","HtmlElementTexture","RegisterEnginesExtensionsEngineVideoTexture","_DefaultOptions","_isVideo","getVideoPlaybackQuality","wasReady","videoElement","_HasWarnedAboutMissingApi","apiName","_HasWarnedAboutSvgFallback","_HasWarnedAboutUploadFailure","copyElementImageToTexture","texElementImage2D","UploadHtmlElementToTexture","_WarnMissingApi","swidth","sheight","_WarnUploadFailure","_UploadHtmlElementToWebGPUTexture","_UseLegacyTexElementImage2D","_CallTexElementImage2D","_UploadHtmlElementToWebGLTexture","HtmlTexture","_paintHandler","_ownsHost","_originalParent","_originalNextSibling","_addedInert","_useSvgFallback","useSvgFallback","changedElements","hasAttribute","requestUpdate","canvasHost","requestPaint","IsHtmlInCanvasUploadSupported","_updateFromSvgFallback","XMLSerializer","svgUrl","_buildSvgDataUrl","_WarnSvgFallback","serializeToString","svg","insertBefore","elementWidth","elementHeight","HtmlInteractionManager","_projectedCenter","_projectedX","_projectedY","_corner","_restoreInertOnDispose","_element","_setTransform","dpr","ComputeOverlayCssTransform","_previousTransform","GetElementPixelFromUv","HtmlRaycastInteractionManager","_rectCache","_rectCacheValid","_mutationObserver","targetElement","_containHandler","_ContainedEventTypes","_invalidateRectCache","ResizeObserver","observe","MutationObserver","childList","characterData","subtree","_onPointer","domName","_PointerTypeToDomEvent","_isBackFace","_getRect","_dispatch","toSurface","_resolveTarget","bubbles","cancelable","dispatchEvent","_PointerToMouseEvent","mouseName","_downTarget","advanced","_InstalledModule","IsHtmlInCanvasSupportedNatively","captureElementImage","InstallHtmlInCanvasPolyfill","polyfillModule","_BabylonUMDDynamicImportUnsupported","specifier","_ImportPolyfill","moduleSpecifier","installHtmlInCanvasPolyfill","uninstallHtmlInCanvasPolyfill","DDSD_MIPMAPCOUNT","DDPF_LUMINANCE","FOURCC_DXT1","FourCCToInt32","FOURCC_DXT3","FOURCC_DXT5","FOURCC_DX10","GetDDSInfo","extendedHeader","headerLengthInt","fourCC","dxgiFormat","isFourCC","isRGB","isLuminance","dataOffset","srcPos","StoreLODInAlphaChannel","_GetHalfFloatRGBAArrayBuffer","_GetFloatRGBAArrayBuffer","rOffset","gOffset","bOffset","aOffset","_ExtractLongWordOrder","loadMipmaps","currentFace","destTypeMustBeFilterable","sphericalPolynomialFaces","internalCompressedFormat","blockBytes","computeFormats","bpp","startFace","floatArray","_GetFloatAsUIntRGBAArrayBuffer","_GetHalfFloatAsUIntRGBAArrayBuffer","_GetHalfFloatAsFloatRGBAArrayBuffer","floatAvailable","halfFloatAvailable","destType","dataGetter","dataGetterPolynomial","_GetFloatAsHalfFloatRGBAArrayBuffer","_GetRGBArrayBuffer","_GetRGBAArrayBuffer","unpackAlignment","unpaddedRowSize","_GetLuminanceArrayBuffer","RegisterBaseTexturePolynomial","SourceTextureFormat","TranscodeTarget","EngineFormat","KhronosTextureContainer","facesExpected","isInvalid","IsValid","dataSize","headerDataView","littleEndian","glType","glTypeSize","glInternalFormat","glBaseInternalFormat","pixelWidth","pixelHeight","pixelDepth","numberOfArrayElements","numberOfFaces","numberOfMipmapLevels","loadType","COMPRESSED_2D","uploadLevels","_upload2DCompressedLevels","TEX_2D","COMPRESSED_3D","HEADER_LEN","bytesOfKeyValueData","imageSize","identifier","WorkerPool","workers","_pendingActions","worker","workerPromise","idle","terminate","_workerInfos","_executeOnIdleWorker","workerInfo","nextAction","AutoReleaseWorkerPool","maxWorkers","createWorkerAsync","_maxWorkers","_createWorkerAsync","idleTimeElapsedBeforeRelease","applyConfig","binariesAndModulesContainer","jsDecoderModule","KTX2DECODER","wasmBaseUrl","KTX2DecoderModule","Transcoder","WasmBaseUrl","wasmUASTCToASTC","LiteTranscoder_UASTC_ASTC","WasmModuleURL","wasmUASTCToBC7","LiteTranscoder_UASTC_BC7","wasmUASTCToRGBA_UNORM","LiteTranscoder_UASTC_RGBA_UNORM","wasmUASTCToRGBA_SRGB","LiteTranscoder_UASTC_RGBA_SRGB","wasmUASTCToR8_UNORM","LiteTranscoder_UASTC_R8_UNORM","wasmUASTCToRG8_UNORM","LiteTranscoder_UASTC_RG8_UNORM","jsMSCTranscoder","MSCTranscoder","JSModuleURL","wasmMSCTranscoder","wasmZSTDDecoder","ZSTDDecoder","WasmBinary","JSModule","workerFunction$1","ktx2Decoder","onmessage","wasmBinaries","KTX2Decoder","postMessage","DefaultDecoderOptions","mipmap","decodedData","onMessage","_useRGBAIfOnlyBC1BC3AvailableWhenUASTC","_ktx2DecoderOptions","useRGBAIfASTCBC7NotAvailableWhenUASTC","_useRGBAIfASTCBC7NotAvailableWhenUASTC","useRGBAIfOnlyBC1BC3AvailableWhenUASTC","forceRGBA","_forceRGBA","forceR8","_forceR8","forceRG8","_forceRG8","bypassTranscoders","_bypassTranscoders","_getKTX2DecoderOptions","transcodeFormat","BC1_RGB","BC3_RGBA","RGBA32","engineFormat","roundToMultiple4","KhronosTextureContainer2","GetDefaultNumWorkers","hardwareConcurrency","_Initialize","_WorkerPoolPromise","_DecoderModulePromise","URLConfig","numWorkers","Worker","workerContent","initializeWebWorker$2","workerBlobUrl","_KTX2DecoderModule","LoadBinariesFromCurrentThread","WASMMemoryManager","numWorkersOrOptions","workerPool","workerPoolOption","numberOfWorkers","DefaultNumWorkers","_decodeAsync","dataCopy","compressedTexturesCaps","transcodedFormat","isInGammaSpace","transcoderName","isUncompressedFormat","ktx","mappedFormat","MapSRGBToLinear","_uploadAsync","GetTGAHeader","id_length","colormap_type","image_type","colormap_index","colormap_length","colormap_size","pixel_size","use_rle","use_pal","use_grey","palettes","x_start","y_start","x_step","y_step","x_end","pixel_data","pixel_total","y_end","TGATools","colormap","UploadContent","pixelsDataRGB32","RGBE_ReadPixels","pixelsDataRGBA32","BASIS_FORMATS","workerFunction","transcoderModulePromise","TranscodeLevel","loadedFile","imageIndex","levelIndex","convertToRgb565","transcodeImage","blockWidth","blockHeight","blockY","blockX","dstI","ConvertDxtToRgb565","getImageWidth","getImageHeight","wasmBinary","BASIS","imgData","BasisFile","basisFile","getHasAlpha","imageCount","getNumImages","levelCount","getNumLevels","levelInfo","ignoreSupportedFormats","supportedCompressionFormats","bc7","GetSupportedTranscodeFormat","needsConversion","startTranscoding","loadSingleImage","mipCount","loadMipmapLevels","transcodedPixels","BasisFileInfo","BasisTranscodeConfiguration","BasisToolsOptions","basisFormat","cTFETC1","cTFBC1","cTFBC4","cTFASTC_4x4","cTFETC2","cTFBC7","WorkerPromise","LocalWorker","ActionId","CreateWorkerAsync","initHandler","moduleUrl","initializeWebWorker$1","SetBasisTranscoderWorker","TranscodeAsync","actionId","messageHandler","dataViewCopy","transcodeResult","rootImage","BindTexture","BasisTools","GetInternalFormatFromBasisFormat","_Registered$51","hasMipmap","LoadTextureFromTranscodeResult","LoadIESData","TexturePackerFrame","TexturePacker","uvsIn","uvsOut","LAYOUT_STRIP","LAYOUT_COLNUM","colnum","updateInputMeshes","disposeSources","_expecting","fillBlanks","customFillColor","frameSize","paddingRatio","_paddingValue","paddingMode","SUBUV_WRAP","SUBUV_COLOR","paddingColor","sets","_createFrames","dtSize","_calculateSize","dtUnits","doneCount","expecting","meshLength","sKeys","setName","dtx","padding","tcs","_calculateMeshUVFrames","tcx","_getFrameOffset","iDat","setTransform","cellOffsets","updateDt","sqrtCount","cols","rowCnt","pOffset","_updateMeshUV","_updateTextureReferences","uvStep","yStep","xStep","frameID","uvIn","uvOut","toCount","setMeshToFrame","updateMaterial","forceCompilationAsync","doneCheck","pack","oKeys","opt","click","updateFromJSON","LAYOUT_POWER2","SUBUV_EXTEND","CustomProceduralTexture","texturePath","skipJson","_texturePath","_loadJson","noConfigFile","configFileUrl","xhr","_config","updateShaderUniforms","updateTextures","refreshrate","sampler2Ds","sample2Dname","textureRelativeUrl","_NoiseProceduralTextureGlslShaderPromise","_NoiseProceduralTextureWgslShaderPromise","noise_fragment$1","noise_fragment","NoiseProceduralTexture","_EnsureNoiseProceduralTextureShaderAsync","animationSpeedFactor","_updateShaderUniforms","persistence","octaves","_Registered$50","RawCubeTexture","updateRGBDAsync","UploadImageToTexture2DArrayLayer","khronosTextureContainer2","baseLevel","expectedLayerByteLength","allSettled","firstRejection","bitmaps","uploadOptions","RawTexture3D","RefractionTexture","refractionPlane","IsTextureInput","IsConstantInput","textureInputs","sourceChannel","textureInputMap","usedTextures","channelName","outputTextureOptions","textureMerger_fragment$1","textureMerger_fragment","CopyTextureTransform","constantValue","CreateTextureInput","CreateConstantInput","CreateRGBAConfiguration","CreateTextureOperand","_ResolveOutputSize","operands","maxDim","_HasNonIdentityTransform","_AllTransformsMatch","includeTransform","TextureChannel","_BuildInvertDefines","ChannelMask","_BuildOutputChannelMaskDefines","_ApplyOutputChannelMask","_BuildOperandDefines","bakeTransform","_ChannelDefine","_BuildLerpBlendDefines","_SetOperandUniforms","pt","factorName","_EvalConstant","outputOptions","outputColorSpace","TextureColorSpace","textureProcessor_fragment$1","textureProcessor_fragment","_MultiplyConstants","outputChannelMask","allTextures","canPropagate","_CreateProcessorTexture","_RenderAsync","_CopyTextureMetadata","_MaxConstants","_LerpConstants","_SetLerpBlendUniforms","InvertTextureAsync","input_1","ExtractMaxChannelAsync","includeAlpha","swizzled","MultiplyTexturesAsync","CreateFactorOperand","ThinRenderTargetTexture","name$50","shader$50","name$4$","shader$4$","name$4_","shader$4_","name$4Z","shader$4Z","includes$1G","name$4Y","shader$4Y","name$4X","shader$4X","includes$1F","name$4W","shader$4W","name$4V","shader$4V","includes$1E","name$4U","shader$4U","name$4T","shader$4T","includes$1D","NodeMaterialBlockConnectionPointMode","NodeMaterialConnectionPointCustomObject","GaussianSplattingBlock","splatPosition","splatScale","splatVertex","SH","gaussianSplattingVertexDeclaration$2","gaussianSplatting$2","gaussianSplattingVertexDeclaration$1","gaussianSplatting$1","sh","splatScaleParameter","addF","_Registered$4$","GaussianBlock","splatColor","clipPlaneFragmentDeclaration","logDepthDeclaration$2","fogFragmentDeclaration$2","gaussianSplattingFragmentDeclaration$2","clipPlaneFragmentDeclaration$2","logDepthDeclaration$1","fogFragmentDeclaration$1","gaussianSplattingFragmentDeclaration$1","tempSplatColor","_Registered$4_","SplatReaderBlock","splatIndex","BindEffect","splatVariablename","_Registered$4Z","ImageSourceBlock","_GetDefaultTexture","_DefaultTextureByEngine","_nodeMaterial","affect","_emit2DArraySampler","ignoreTexture","_Registered$4Y","SmartFilterTextureBlock","_firstInit","isMainInput","hasImageSource","_postBuildBlock","_Registered$4X","AddBlock","_Registered$4W","SetToDefaultGaussianSplatting","splatReader","gs","gaussian","GaussianSplatting","SetToDefaultSFE","BonesBlock","bonesDeclaration","bonesVertex","bonesDeclaration$2","bonesVertex$2","matricesIndicesInput","matricesWeightsInput","influenceVariablename","_emitCodeFromInclude","_Registered$4V","InstancesBlock","world0","world1","world2","world3","instanceID","world0Input","world1Input","world2Input","world3Input","mat4","floatCast","_Registered$4U","MorphTargetsBlock","positionOutput","normalOutput","tangentOutput","uvOutput","uv2Output","colorOutput","morphTargetsVertex","morphTargetsVertexDeclaration","morphTargetsVertexGlobal","morphTargetsVertexGlobalDeclaration","morphTargetsVertex$2","morphTargetsVertexDeclaration$2","morphTargetsVertexGlobal$2","morphTargetsVertexGlobalDeclaration$2","normalInput","tangentInput","uv2Input","colorInput","vertexShaderState","supportPositions","supportNormals","supportTangents","supportUVs","supportUV2s","supportColors","injectionCode","uniformsPrefix","_Registered$4T","LightInformationBlock","shadowBias","shadowNormalBias","shadowDepthScale","shadowDepthRange","_forcePrepareDefines","_lightDataUniformName","_lightColorUniformName","_lightShadowUniformName","shadowLight","_lightShadowExtraUniformName","_lightTypeDefineName","uniformAdd","_Registered$4S","imageProcessingDeclaration$2","imageProcessingFunctions$2","imageProcessingDeclaration$1","imageProcessingFunctions$1","overrideText","isVec4Input","convertInputToLinearSpace","_convertInputToLinearSpace_decorators","_Registered$4R","ImageProcessingBlock","TBNBlock","TBN","row0","row1","row2","normalAvailable","tangentAvailable","useTBNBlock","tbn","_Registered$4Q","_tangentSpaceParameterName","_tangentCorrectionFactorName","worldTangent","normalMapColor","viewDirection","parallaxScale","parallaxHeight","bumpFragment$2","bumpFragmentMainFunctions$2","bumpFragmentFunctions$2","bumpFragment$1","bumpFragmentMainFunctions$1","bumpFragmentFunctions$1","normalSamplerName","invertX","_worldMatrixName","strengthInput","fragmentInputsPrefix","replaceForParallaxInfos","replaceForBumpInfos","tangentReplaceString","normalMatrixReplaceString","replaceString0","searchExp0","replaceString1","searchExp1","normalRead","uvForPerturbNormal","tempOutput","_invertX_decorators","_invertY_decorators","_invertX_initializers","_invertX_extraInitializers","_invertY_extraInitializers","_Registered$4P","PerturbNormalBlock","DiscardBlock","cutoff","_Registered$4O","FrontFacingBlock","_generateTernary","_Registered$4N","DerivativeBlock","dpdx","dpdy","_Registered$4M","FragCoordBlock","coord","_Registered$4L","ScreenSpaceBlock","worldViewProjectionInput","worldViewProjectionName","tempVariableName","_Registered$4K","TwirlBlock","centerInput","offsetInput","tempDelta","tempAngle","tempX","tempY","tempResult","_Registered$4J","generateInWorldSpace","_generateInWorldSpace_initializers","automaticNormalizationNormal","_generateInWorldSpace_extraInitializers","_automaticNormalizationNormal_initializers","fPrefix","startCode","endCode","automaticNormalizationTangent","heightToNormal","_babylonSLtoWGSL","_generateInWorldSpace_decorators","_automaticNormalizationNormal_decorators","_automaticNormalizationTangent_decorators","_automaticNormalizationNormal_extraInitializers","_Registered$4I","HeightToNormalBlock","FragDepthBlock","_Registered$4H","ShadowMapBlock","shadowMapVertexMetric$2","packingFunctions","shadowMapFragment$2","shadowMapVertexMetric$1","packingFunctions$2","shadowMapFragment$1","_Registered$4G","PrePassOutputBlock","_getFragData","_Registered$4F","_area_initializers","_fallOff_extraInitializers","screenSize","occlusion","_randomSamplerName","depthSource","_area_decorators","_fallOff_decorators","_area_extraInitializers","_Registered$4E","AmbientOcclusionBlock","FogBlock","viewInput","fogColorInput","_fogParameters","prefix1","prefix2","tempFogVariablename","_fogDistanceName","_Registered$4D","_OnGenerateOnlyFragmentCodeChanged","that","generateOnlyFragmentCode","_setTarget","_generateOnlyFragmentCode_extraInitializers","glossPower","diffuseOutput","specularOutput","lightFragment$2","lightUboDeclaration$2","lightVxUboDeclaration$2","lightsFragmentFunctions$2","shadowsFragmentFunctions$2","shadowsVertex$2","lightFragmentDeclaration$1","lightFragment$1","lightUboDeclaration$1","lightVxUboDeclaration$1","lightVxFragmentDeclaration$1","lightsFragmentFunctions$1","shadowsFragmentFunctions$1","shadowsVertex$1","cameraPositionInput","_lightId","onlyUpdateBuffersList","counters","worldPosVaryingName","_injectUBODeclaration","isWGSL","accessor","worldPosVariableName","onValidation","LightBlock","_Registered$4C","TextureBlock","fragmentOnly","_fragmentOnly","defaultTexture","_isSourcePrePass","_IsPrePassTextureBlock","_imageSource","getSamplerName","_convertToGammaSpace","_convertToLinearSpace","disableLevelMultiplication","parentBlock","_isTiedToFragment","_mainUVDefineName","_isMixed","_defineName","toGamma","toLinear","_textureInfoName","_textureTransformName","_transformedUVName","_getVaryingName","automaticPrefix","coords","uvName","is2DArrayTexture","_samplerLodSuffix","_getUVW","_generateTextureLookup","_generateConversionCode","_Registered$4B","_onGenerateOnlyFragmentCodeChanged","reflectionFunction$2","reflectionFunction$1","_getTexture","_define3DName","_defineLocalCubicName","_defineExplicitName","_defineSkyboxName","_defineSphericalName","_definePlanarName","_defineProjectionName","_defineEquirectangularName","_defineEquirectangularFixedName","_defineMirroredEquirectangularFixedName","_reflectionMatrixName","_cubeSamplerName","_2DSamplerName","_reflectionPositionName","_reflectionSizeName","handleVertexSide","_defineCubicName","_defineOppositeZ","_worldPositionNameInFragmentOnlyMode","_positionUVWName","_directionWname","_reflectionColorName","_reflectionVectorName","_reflectionCoordsName","reflectionMatrix","positionUVW","vEyePosition","worldNormalVarName","doNotEmitInvertZ","onlyReflectionVector","handleFragmentSideCodeReflectionColor","colorType","swizzleLookupTexture","lodVarName","_generateTextureSampleCubeLOD","_generateTextureSampleCube","_generateTextureSampleLOD","IgnoreTexturesAtLoadTime","ReflectionTextureBaseBlock","_Registered$4A","handleFragmentSideInits","normalWUnit","handleFragmentSideCodeReflectionCoords","_Registered$4z","ReflectionTextureBlock","useNonLinearDepth","_useNonLinearDepth_initializers","_useNonLinearDepth_extraInitializers","_storeCameraSpaceZ_initializers","_force32itsFloat_extraInitializers","force32itsFloat","_useNonLinearDepth_decorators","activatePreviewCommand","sceneDepthBlock","retVal","_storeCameraSpaceZ_decorators","_force32itsFloat_decorators","_Registered$4y","SceneDepthBlock","DepthSourceBlock","_Registered$4x","ClipPlanesBlock","clipPlaneFragment","clipPlaneVertex","clipPlaneVertexDeclaration","clipPlaneFragment$2","clipPlaneVertex$2","clipPlaneVertexDeclaration$2","useClipPlane1","useClipPlane2","useClipPlane3","useClipPlane4","useClipPlane5","useClipPlane6","_Registered$4w","PrePassTextureBlock","_positionSamplerName","_localPositionSamplerName","_depthSamplerName","_screenSpaceDepthSamplerName","_normalSamplerName","_worldNormalSamplerName","positionSamplerName","localPositionSamplerName","worldNormalSamplerName","depthSamplerName","linearDepthSamplerName","prepassPositionSampler","prepassDepthSampler","prepassNormalSampler","prepassWorldNormalSampler","prepassLocalPositionSampler","sceneRT","_Registered$4v","isConnectedToUniform","_Registered$4u","NodeMaterialTeleportInBlock","NodeMaterialTeleportOutBlock","firstConnected","firstTarget","_Registered$4t","ScaleBlock","_Registered$4s","cast","_maximum_decorators","_minimum_decorators","_minimum_initializers","_minimum_extraInitializers","_Registered$4r","ClampBlock","CrossBlock","_Registered$4q","CustomBlock","_deserializeOptions","_code","rexp","_getGLType","_inputSamplers","hasInput","inParameters","outParameters","_findInputByName","typeFromInput","inLinkedConnectionTypes","input1","input2","_Registered$4p","DotBlock","_Registered$4o","NormalizeBlock","_Registered$4n","ColorMergerBlock","rSwizzle","gSwizzle","bSwizzle","aSwizzle","rInput","gInput","bInput","aInput","rgbInput","color4Output","color3Output","_Registered$4m","VectorSplitterBlock","xyzOutput","xyOutput","zwOutput","xOutput","yOutput","zOutput","wOutput","_Registered$4l","LerpBlock","_Registered$4k","DivideBlock","_Registered$4j","SubtractBlock","_Registered$4i","StepBlock","_Registered$4h","OneMinusBlock","_Registered$4g","ViewDirectionBlock","_Registered$4f","FresnelBlock","fresnelFunction$2","fresnelFunction$1","viewDirectionInput","biasInput","powerInput","_Registered$4e","MaxBlock","_Registered$4d","MinBlock","_Registered$4c","DistanceBlock","_Registered$4b","LengthBlock","_Registered$4a","NegateBlock","_Registered$49","PowBlock","_Registered$48","RandomNumberBlock","_Registered$47","ArcTan2Block","_Registered$46","SmoothStepBlock","edge0","_Registered$45","ReciprocalBlock","_Registered$44","ReplaceColorBlock","replacement","_Registered$43","PosterizeBlock","_Registered$42","WaveBlockKind","_kind_decorators","_Registered$41","WaveBlock","GradientBlockColorStep","_color","colorStepsUpdated","colorSteps","tempColor","tempPosition","_writeColorConstant","gradientSource","previousStep","colorStep","_Registered$40","GradientBlock","NLerpBlock","_Registered$3$","functionString","_babylonSLtoGLSL","tempVariable","manhattanDistance","_manhattanDistance_decorators","_Registered$3_","WorleyNoise3DBlock","SimplexPerlin3DBlock","_Registered$3Z","NormalBlendBlock","normalMap0","normalMap1","input0","stepR","stepG","_Registered$3Y","Rotate2dBlock","angleInput","_Registered$3X","ReflectBlock","incident","_Registered$3W","RefractBlock","_Registered$3V","DesaturateBlock","colorName","tempMin","tempMax","tempMerge","_Registered$3U","reflectionBlock","_vReflectionMicrosurfaceInfosName","_vReflectionInfosName","_Registered$3T","SheenBlock","AnisotropyBlock","worldPositionConnectionPoint","worldNormalConnectionPoint","generateTBNSpace","_generateTBNSpace","_Registered$3S","_initReflectionBlockShaderSourceAsync","harmonicsFunctions$2","harmonicsFunctions$1","_forceIrradianceInFragment_extraInitializers","cameraPositionConnectionPoint","viewConnectionPoint","reflection","_defineLODReflectionAlpha","_defineLinearSpecularReflection","_iblIntensityName","_vReflectionFilteringInfoName","reflectionVectorName","_vEnvironmentIrradianceName","normalVarName","computeReflectionCoordsFunc","_Registered$3R","ReflectionBlock","tintAtDistance","clearcoat","intensityInput","PBRClearCoatConfiguration","mainPBRBlock","perturbedNormalBlock","perturbedNormal","worldPositionVarName","_GetInitializationCode","ccBlock","worldPosVarName","vTBNAvailable","normalShading","_Registered$3Q","ClearCoatBlock","IridescenceBlock","indexOfRefractionInput","thicknessInput","iridescenceBlock","intensityName","_Registered$3P","refraction","_defineLODRefractionAlpha","_defineLinearSpecularRefraction","_refractionMatrixName","indexOfRefractionConnectionPoint","_vRefractionInfosName","_vRefractionMicrosurfaceInfosName","_vRefractionFilteringInfoName","_Registered$3O","RefractionBlock","translucencyDiffusionDist","subsurface","translucencyEnabled","ssBlock","translucencyDiffusionDistance","refractionBlock","refractionTintAtDistance","refractionView","getCode","_Registered$3N","SubSurfaceBlock","ambientClr","diffuseDir","specularDir","clearcoatDir","sheenDir","diffuseInd","specularInd","clearcoatInd","sheenInd","lighting","lightFalloff","_lightFalloff_initializers","useAlphaTest","_lightFalloff_extraInitializers","_useAlphaTest_initializers","alphaTestCutoff","_useAlphaTest_extraInitializers","_alphaTestCutoff_initializers","useAlphaBlending","_alphaTestCutoff_extraInitializers","_useAlphaBlending_initializers","_useAlphaBlending_extraInitializers","_realTimeFiltering_initializers","_realTimeFiltering_extraInitializers","_realTimeFilteringQuality_initializers","_realTimeFilteringQuality_extraInitializers","_forceNormalForward_extraInitializers","_generateOnlyFragmentCode_initializers","_debugLimit_initializers","_debugFactor_extraInitializers","pbr_vertex$1","pbr_fragment$1","pbr_vertex","pbr_fragment","ambientOcc","alphaTestCutOffString","_environmentBrdfSamplerName","ambientScene","_invertNormalName","metallicF90","_vMetallicReflectanceFactorsName","worldNormalVaryingName","ao","_baseDiffuseRoughnessName","worldPosVarName4","_vNormalWName","_getAlbedoOpacityCode","_getAmbientOcclusionCode","anisotropyBlock","sheenBlock","clearcoatBlock","isTangentConnectedToPerturbNormal","isTangentConnectedToAnisotropy","subsurfaceBlock","aoDirectLightIntensity","aoColor","MapOutputToVariable","remap","_lightFalloff_decorators","_alphaTestCutoff_decorators","_useAlphaBlending_decorators","_realTimeFiltering_decorators","_realTimeFilteringQuality_decorators","PBRMetallicRoughnessBlock","_debugFactor_decorators","_useAlphaTest_decorators","_generateOnlyFragmentCode_decorators","_debugLimit_decorators","_debugLimit_extraInitializers","_Registered$3M","ModBlock","_Registered$3L","MatrixBuilderBlock","row3","row0Input","row1Input","row2Input","row3Input","_Registered$3K","ConditionalBlockConditions","true","minInput","false","maxInput","Equal","NotEqual","LessThan","LessOrEqual","GreaterThan","GreaterOrEqual","Xor","Or","And","_condition_decorators","_Registered$3J","ConditionalBlock","chaos","offsetZ","fractalBrownianString","fbmNewName","localVariable","seedType","chaosValue","_octaves_decorators","_Registered$3I","CloudBlock","VoronoiNoiseBlock","cells","tempCells","_Registered$3H","ElbowBlock","_Registered$3G","_getImageSourceBlock","imageSourceBlock","projectAsCube","_projectAsCube_initializers","_projectAsCube_extraInitializers","hideSourceZ","sharpness","_textureInfoName2","samplerYName","samplerZName","uvx","uvy","uvz","vecSpecifier","_projectAsCube_decorators","_Registered$3F","TriPlanarBlock","BiPlanarBlock","ma","mi","me","dpdxFunc","dpdyFunc","_getTextureGrad","_Registered$3E","MatrixDeterminantBlock","_Registered$3D","MatrixTransposeBlock","_Registered$3C","MeshAttributeExistsBlockTypes","_attributeType_decorators","_Registered$3B","MeshAttributeExistsBlock","CurveBlockTypes","_duplicateEntry","_duplicateEntryDirect","registeredFunction","registeredFunctionName","EaseInOutQuad","_duplicateVector","EaseOutCubic","EaseInOutCubic","EaseOutQuart","EaseInOutQuart","EaseOutQuint","EaseInOutQuint","EaseInExpo","EaseOutExpo","EaseInOutExpo","EaseInCirc","EaseOutCirc","EaseInOutCirc","EaseInBack","EaseOutBack","EaseInOutBack","EaseInElastic","EaseOutElastic","EaseInOutElastic","curveType","_type_decorators","EaseInSine","EaseInOutSine","EaseInQuad","EaseInCubic","EaseInQuart","EaseInQuint","_Registered$3A","CurveBlock","ColorConverterBlock","hslIn","hslOut","hslInput","rbgOutput","hslOutput","rgb2hsl","hue2rgb","hsl2rgb","_Registered$3z","iterationsInput","indexName","castFloat","_iterations_decorators","_Registered$3y","LoopBlock","StorageReadBlock","_Registered$3x","StorageWriteBlock","_Registered$3w","MatrixSplitterBlock","col0","col1","col2","col3","_exportColumn","columnIndex","_Registered$3v","shader$4S","name$4S","name$4R","shader$4R","name$4Q","shader$4Q","name$4P","shader$4P","name$4O","shader$4O","name$4N","shader$4N","_renderAlpha_extraInitializers","_forcedActive","renderAlpha","_renderAlpha_decorators","_Registered$3u","NodeMaterialDebugBlock","PannerBlock","timeInput","_Registered$3t","NodeMaterialOptimizer","name$4M","shader$4M","name$4L","shader$4L","MaterialPluginEvent","GlslShaderLoadPromise","WgslShaderLoadPromise","DepthPrePassInjectionPoint","DitheredTileFadeMaterialPlugin","_ValidateNewPlugin","_meshBounds","_thinInstanceFadeBuffers","_generation","_shaderIncludeReady","_loadShaderIncludeAsync","_ValidateMaterial","setFadeBounds","_validateMesh","_validateBound","_updateInstancedFadeBounds","explicitBounds","resetFade","setThinInstanceFadeBounds","_validateThinInstanceIndex","_ensureThinInstanceBuffer","commitThinInstanceFadeBounds","setThinInstanceFadeBoundsBuffer","attributeData","attributeOffset","_getInstanceAttributeName","resetThinInstanceFade","GetOrCreate","_shaderIncludeError","_ensureInstancedBuffer","instanceAttributeName","RegisterInstancedMesh","requiredLength","existingBuffer","configured","bayerDitherFunctions$2","_LoadWgslShaderIncludeAsync","bayerDitherFunctions$1","_LoadGlslShaderIncludeAsync","_LoadShaderIncludeAsync","DECAL","DECALDIRECTUV","DECAL_SMOOTHALPHA","GAMMADECAL","_DecalMapConfiguration_smoothAlpha_accessor_storage","_DecalMapConfiguration_isEnabled_accessor_storage","smoothAlpha","DecalMapDefines","_smoothAlpha","_smoothAlpha_initializers","_smoothAlpha_extraInitializers","decalMap","_smoothAlpha_decorators","_Registered$3s","DecalMapConfiguration","createPBRAnisotropicPlugin","createPBRBRDFPlugin","createPBRClearCoatPlugin","createPBRIridescencePlugin","createPBRSheenPlugin","createPBRSubSurfacePlugin","DetailMapConfiguration","GreasedLineMaterialDefaults","DEFAULT_COLOR","DEFAULT_WIDTH_ATTENUATED","GreasedLineTools","vectorPoints","flatMap","floatArrayStride","OmitZeroLengthPredicate","fileredPoints","OmitDuplicatesPredicate","_SearchInPoints","MeshesToLines","ii","vi1","vi2","vi3","pointsFromPredicate","ToVector3Array","inputArray","subInputArray","subArray","ToNumberArray","GetPointsCountInfo","GetLineLengthArray","pointsLength","SegmentizeSegmentByCount","segmentCount","dividedLinePoints","segmentVector","nextPoint","what","segmentLength","subLines","GetLineSegments","seg","GetLineLength","SegmentizeLineBySegmentLength","GetMinMaxSegmentLength","sorted","GetPositionOnLineByVisibility","lineSegments","lineLength","visbility","localSpace","lengthVisibilityRatio","sumSegmentLengths","segmentIndex","lineSegmentsLength","GetCircleLinePoints","segmentAngle","GetBezierLinePoints","GetArrowCap","widthUp","widthDown","widthStartUp","widthStartDown","widths","GetPointsFromText","includeInner","allPoints","points2d","p2d","Color3toRGBAUint8","colorTable","colorsSampling","PrepareEmptyColorsTexture","EmptyColorsTexture","BooleanToNumber","GREASED_LINE_HAS_COLOR","GREASED_LINE_SIZE_ATTENUATION","GREASED_LINE_COLOR_DISTRIBUTION_TYPE_LINE","GREASED_LINE_RIGHT_HANDED_COORDINATE_SYSTEM","GREASED_LINE_CAMERA_FACING","GREASED_LINE_USE_OFFSETS","GreasedLinePluginMaterial","MaterialGreasedLineDefines","useColors","colorDistributionType","cameraFacing","GREASED_LINE_MATERIAL_NAME","_cameraFacing","useDash","dashRatio","dashOffset","sizeAttenuation","DEFAULT_WIDTH","_sizeAttenuation","colorMode","_colorsDistributionType","dashCount","CreateColorsTexture","DisposeEmptyColorsTexture","_isGLSL","resolutionLineWidth","_aspect","dashOptions","_dashArray","colorModeVisibilityColorsWidthUseColors","GetCustomCode$1","GetCustomCode","origColorsCount","lazy","forceNewTexture","colorArray","updateLazy","_dashCount","doNotMarkDirty","colorsDistributionType","greasedLineMaterialOptions","_Registered$3r","GreasedLineUseOffsetsSimpleMaterialDefine","GreasedLineSimpleMaterial","greasedLine_vertex","greasedLine_fragment","greasedLine_vertex$1","greasedLine_fragment$1","_colorsTexture","_setColorModeAndColorDistributionType","_colorMode","_useColors","_colorsSampling","_useDash","_dashOffset","_dashRatio","GreasedLineMeshMaterialType","GreasedLineMeshColorMode","GreasedLineMeshColorDistributionType","defaultMaterialColors","MeshDebugMode","DBG_MODE","DBG_MULTIPLY","DBG_ENABLED","_MeshDebugPluginMaterial_multiply_accessor_storage","_MeshDebugPluginMaterial_mode_accessor_storage","_markAllDefinesAsDirty","MeshDebugDefines","_materialColor","__materialColor_initializers","__materialColor_extraInitializers","_mode_initializers","_multiply","_mode_extraInitializers","_multiply_initializers","shadedDiffuseColor","_multiply_extraInitializers","_shadedDiffuseColor_initializers","shadedSpecularColor","_shadedDiffuseColor_extraInitializers","_shadedSpecularColor_initializers","shadedSpecularPower","_shadedSpecularColor_extraInitializers","_shadedSpecularPower_initializers","wireframeThickness","_shadedSpecularPower_extraInitializers","_wireframeThickness_initializers","wireframeTrianglesColor","_wireframeThickness_extraInitializers","_wireframeTrianglesColor_initializers","wireframeVerticesColor","_wireframeTrianglesColor_extraInitializers","_wireframeVerticesColor_initializers","_wireframeVerticesColor_extraInitializers","_vertexColor_initializers","vertexRadius","_vertexColor_extraInitializers","_vertexRadius_initializers","_vertexRadius_extraInitializers","_uvScale_initializers","uvPrimaryColor","_uvScale_extraInitializers","_uvPrimaryColor_initializers","_uvSecondaryColor_extraInitializers","uvSecondaryColor","MaterialColors","_PluginCount","CUSTOM_VERTEX_MAIN_END","CUSTOM_FRAGMENT_MAIN_END","Reset","PrepareMeshForTrianglesAndVerticesMode","returnRollback","rollback","newIndices1","newIndices2","__materialColor_decorators","_mode_decorators","_multiply_decorators","_shadedDiffuseColor_decorators","_shadedSpecularColor_decorators","_shadedSpecularPower_decorators","_wireframeThickness_decorators","_wireframeTrianglesColor_decorators","_wireframeVerticesColor_decorators","_vertexColor_decorators","_vertexRadius_decorators","_uvScale_decorators","_uvPrimaryColor_decorators","_uvSecondaryColor_decorators","_uvPrimaryColor_extraInitializers","_Registered$3q","MeshDebugPluginMaterial","name$4K","name$4J","shader$4J","name$4I","includes$1C","gaussianSplattingUboDeclaration","gaussianSplatting","name$4H","includes$1B","gaussianSplattingFragmentDeclarationWGSL","name$4G","includes$1A","gaussianSplattingWGSL","_onIsEnabledChanged","partColors","_partColors","_partColorArray","updatePartColors","_Registered$3p","GaussianSplattingSolidColorMaterialPlugin","GS_DBG_SH_ORDER4","GaussianSplattingDebugMaterialPlugin","GaussianSplattingDebugDefines","_clippingBox","_opacityCulling","_sizeCulling","_opacityScale","_opacitySaturate","_shDc","_shOrder1","_shOrder2","_shOrder3","_partCount","_partClippingBoxes","_partOpacityCullings","_partSizeCullings","_partOpacityScales","_partOpacitySaturates","_partShDcs","_partShOrder1s","_partShOrder2s","_partShOrder3s","_dbgPartDataTexture","_textureDirty","_partArrays","_partShOrder4s","_isAnyFeatureActive","_shOrder4","_markDirty","setPartOptions","clippingBox","opacityCulling","sizeCulling","opacityScale","opacitySaturate","shDc","shOrder1","shOrder2","shOrder3","shOrder4","clearPartOptions","shiftPartOptions","removedIndex","GS_DBG_ENABLED","GS_DBG_CLIP","GS_DBG_CULL_OPACITY","GS_DBG_CULL_SIZE","GS_DBG_OPACITY_SCALE","GS_DBG_OPACITY_SATURATE","GS_DBG_SH_DC","GS_DBG_SH_ORDER1","GS_DBG_SH_ORDER2","GS_DBG_SH_ORDER3","r0","r3","opCull","szCull","sat","r4","_updateOrCreateTexture","_Registered$3o","name$4F","shader$4F","name$4E","shader$4E","name$4D","shader$4D","name$4C","shader$4C","name$4B","shader$4B","includes$1z","defaultFragmentDeclaration","defaultUboDeclaration","objectIdFunctions","fresnelFunction","defaultFragmentAlpha","name$4A","shader$4A","name$4z","shader$4z","name$4y","shader$4y","includes$1y","defaultVertexDeclaration","pointCloudVertex","name$4x","shader$4x","name$4w","shader$4w","name$4v","shader$4v","includes$1x","defaultUboDeclarationWGSL","objectIdFunctionsWGSL","fresnelFunctionWGSL","defaultFragmentAlphaWGSL","name$4u","shader$4u","name$4t","shader$4t","includes$1w","lightVxFragmentDeclarationWGSL","name$4s","shader$4s","name$4r","shader$4r","includes$1v","name$4q","shader$4q","name$4p","shader$4p","includes$1u","name$4o","shader$4o","name$4n","shader$4n","_Registered$3n","_decalMap","_Registered$3m","_Registered$3l","HCF","Scalar","TwoPi","Log2","Polar","polar","toVector2ToRef","FromVector2ToRef","FromVector2","Spherical","spherical","toVector3ToRef","FromVector3ToRef","FromVector3","HalfPi","DegreesToRadians","Wgs84Ellipsoid","semiMajorAxis","flattening","firstEccentricitySquared","semiMinorAxis","secondEccentricitySquared","EllipsoidFromSemiMajorAxisAndInverseFlattening","lat","lon","LatLonToNormalToRef","latLon","cosLat","EcefFromLatLonAltToRef","latLonAlt","NPlusAltTimesCosLat","N","sinLat","pointIndex","barycentric","GetVertexElementData","GetTransformedPosition","GetHotSpotToRef","hotSpotQuery","resPosition","resNormal","pointC","segmentA","segmentB","EncodeMesh","encoderModule","meshBuilder","encodedNativeBuffer","positionAttribute","dracoName","positionVerticesCount","Encoder","AddFacesToMesh","addAttributeMap","mb","AddFloatAttribute","AddUInt32Attribute","AddUInt16Attribute","AddUInt8Attribute","AddInt32Attribute","AddInt16Attribute","AddInt8Attribute","addAttribute","attributeIDs","quantizationBits","SetAttributeQuantization","SetEncodingMethod","encodeSpeed","decodeSpeed","SetSpeedOptions","encodedLength","EncodeMeshToDracoBuffer","encodedData","GetValue","attributeIds","EncoderWorkerFunction","encoderPromise","initEncoderObject","DracoEncoderModule","encodedMeshData","DecodeMesh","onIndicesData","onAttributeData","decoderModule","DecoderBuffer","Init","GetEncodedGeometryType","DecodeBufferToMesh","error_msg","num_faces","_malloc","GetTrianglesUInt32Array","HEAPF32","_free","POINT_CLOUD","pointCloud","DecodeBufferToPointCloud","numPoints","num_points","data_type","byte_stride","byte_offset","DT_FLOAT32","typedArrayConstructor","heap","DT_INT8","HEAP8","DT_INT16","HEAP16","DT_INT32","HEAP32","DT_UINT8","HEAPU8","DT_UINT16","HEAPU16","DT_UINT32","HEAPU32","numValues","GetAttributeDataArrayForAllPoints","GetAttributeByUniqueId","processAttribute","dracoAttributeTypes","POSITION","TEX_COORD","GetAttributeId","GetAttribute","DecoderWorkerFunction","decoderPromise","initDecoderObject","DracoDecoderModule","_GetDefaultNumWorkers","_IsConfigurationAvailable","DracoCodec","_workerPoolPromise","wasmBinaryProvided","useWorkers","codecInfo","wasmUrl","wasmBinaryUrl","WebAssembly","wasmBinaryPromise","fallbackUrl","_getWorkerContent","initializeWebWorker","_isModuleAvailable","jsModule","_createModuleAsync","_modulePromise","DracoDecoder","DefaultAvailable","DefaultConfiguration","_Default","ResetDefault","skipDispose","decodeMeshToMeshDataAsync","gltfNormalizedOverride","resultIndices","resultAttributes","meshData","DracoCompression","Configuration","DecoderAvailable","_decoder","decodeMeshToGeometryAsync","_decodeMeshToGeometryForGltfAsync","NumberOfWorkers","WorkerTimeout","MeshoptCompression","Default","MeshoptDecoder","_decoderModulePromise","deepMerge","isRecord","pVal","oVal","GetDracoAttributeName","DefaultEncoderOptions","DracoEncoder","mergedOptions","transferList","PrepareIndicesForDraco","excludedAttributes","PrepareAttributesForDraco","_encodeAsync","CurrentCSGMeshId","vertColor","interpolate","CSGPlane","coplanarFront","coplanarBack","polygonType","EPSILON","ti","vi","vj","tj","poly","CSGPolygon","shared","Node$1","polygons","_plane","_front","_back","_polygons","clipPolygons","splitPolygon","bsp","clipTo","allPolygons","FromVertexData","vertColors","csg","_FromPolygons","absolute","meshPosition","meshRotation","meshScaling","meshRotationQuaternion","invertWinding","sml","il","indexIndices","sourcePosition","sourceNormal","CSG","union","copyTransformAttributes","intersect","onAfterPolygonProcessing","polygonIndices","verticeDict","onBeforePolygonProcessing","jl","localVertex","areUvsDifferent","areColorsDifferent","localNormal","keepSubMeshes","subMeshDict","subMeshObj","materialMaxIndex","materialIndexOffset","toMesh","buildMeshGeometry","_GetShader","_meshUVSpaceRendererShader","_GetMaskShader","_meshUVSpaceRendererMaskShader","_IsRenderTargetTexture","_textureCreatedInternally","_configureUserCreatedTexture","_maskTexture","_finalPostProcess","meshUVSpaceRenderer_vertex","meshUVSpaceRenderer_fragment","meshUVSpaceRendererMasker_vertex","meshUVSpaceRendererMasker_fragment","meshUVSpaceRendererFinaliser_vertex","meshUVSpaceRendererFinaliser_fragment","meshUVSpaceRenderer_vertex$1","meshUVSpaceRenderer_fragment$1","meshUVSpaceRendererMasker_vertex$1","meshUVSpaceRendererMasker_fragment$1","meshUVSpaceRendererFinaliser_vertex$1","meshUVSpaceRendererFinaliser_fragment$1","_configureUserCreatedRTT","_createDiffuseRTT","textureIsReady","MeshUVSpaceRenderer","maskIsReady","postProcessIsReady","checkIsReady","_createProjectionMatrix","renderTexture","uvEdgeBlending","_createMaskTexture","_createPostProcess","projWorldMatrix","inverseProjWorldMatrix","projMatrix","screenMatrix","_sectionPolygonPointsCount","_running","diameterOrOptions","_segments","sections","_doNotTaper","doNotTaper","_autoStart","autoStart","_sectionVectors","_sectionNormalVectors","_createMesh","meshCenter","_generator","_updateSectionVectors","newGenerator","TrailMesh","generatorId","_diameter","_Registered$3k","SimplicationQueueSceneComponent","_beforeCameraUpdate","_simplificationQueue","_Registered$3j","simplificationQueueClass","simplificationType","simplificationQueue","parallelProcessing","SimplificationSettings","optimizeMesh","SimplificationType","SimplificationQueue","RegisterMeshSimplificationSceneComponent","_simplificationArray","runSimplification","setting","simplifier","_getSimplifier","runDecimation","DecimationTriangle","_vertices","deletePending","borderFactor","DecimationVertex","isBorder","QuadraticMatrix","triangleStart","originalOffsets","a11","a12","a13","a21","a22","a23","a31","a32","a33","addArrayInPlace","DataFromNumbers","Reference","triangleId","QuadraticErrorSimplification","syncIterations","aggressiveness","decimationIterations","boundingBoxEpsilon","_initWithMesh","_runDecimation","_reconstructedMesh","submeshIndex","_triangles","iterationFunction","_updateMesh","tIdx","deleted0","deleted1","_calculateError","delTr","_isFlipped","uniqueArray","deletedT","tStart","deletedTriangles","_updateTriangles","tCount","findInVertices","positionToSearch","vertexReferences","triangle","originalOffset","newTriangles","newPositionData","newNormalData","newUVsData","newColorsData","normalData","startingIndex","startingVertex","submeshesArray","newIndicesArray","originalIndices","originalSubmesh","deletedArray","origVertex","newDeleted","_identifyBorder","vCount","ofs","vv","identifyBorders","newTrianglesVector","newReferences","_vertexError","pointResult","border","qDet","error1","error2","error3","extent","meshExtents","maxLength","minPositions","maxPositions","needsExtra","weightsExtra","indicesExtra","perBoneExtents","skinnedMeshExtents","updateExtents","meshCorners","skinnedMeshCorners","GetExtentCorners","perBoneCorners","inverseBindMatrix","corners","maxExtents","updateMaxExtents","animationStep","uvIndexToKind","unreferencedUVSets","unreferencedUVSet","_Registered$3i","tmpDist","_projectOnUnIndexedTrianglesToRef","_projectOnTrianglesToRef","Lattice","resolutionX","_resolutionX","resolutionY","_resolutionY","resolutionZ","_resolutionZ","_cellSize","_localPos","_lerpVector0","_lerpVector1","_lerpVector2","_lerpVector3","_lerpVector4","_allocateData","updateInternals","deform","j0","k0","j1","ii0","jj0","kk0","ii1","jj1","p000","p100","p010","p110","p001","kk1","p101","p011","p00","p111","_lerpVector5","deformedPos","LatticePluginMaterial","lattice","_lattice","_latticeData","control","_latticeDataTexture","_prepareCode","CUSTOM_VERTEX_UPDATE_POSITION","GreasedLineRibbonPointsMode","GreasedLineRibbonFacesMode","GreasedLineRibbonAutoDirectionMode","_lazy","_vertexPositions","_colorPointers","colorPointers","_widths","defaulValue","pointCount","countDiff","_setPoints","_updateColorPointers","_createVertexBuffers","smoothShading","greasedLineMaterial","addPoints","setPoints","_offsets","_offsetsBuffer","_createOffsetsBuffer","_widthsBuffer","_colorPointersBuffer","pointsCopy","ConvertPoints","pointsOptions","_updateWidths","_initGreasedLine","_createLineOptions","ribbonOptions","lineOptions","offsetBuffer","GreasedLineMesh","GreasedLineBaseMesh","_previousAndSide","_nextAndCounters","colorPointer","jj","indiceOffset","vertexPositionsLen","indicesLength","uvLength","previousAndSideLength","maxLineLength","tempBuffer","vertexPositionsArr","indicesArr","uvArr","previousAndSide","nextAndCounters","vertexPositionsOffset","previousAndSideOffset","nextAndCountersOffset","lengthArray","baseOffset","baseIndicesOffset","currVertexPositionsOffsetLength","_CompareV3","sidesLength","lengthRatio","uvOffsetBase","deepCopiedLineOptions","intersections","findAllIntersections","intersection","_boundingSphere","_V_START","_V_END","_V_OFFSET_START","_V_OFFSET_END","iFloored","firstOnly","positionIdx1","positionIdx2","arrayIdx1","arrayIdx2","previousAndSideBuffer","nextAndCountersBuffer","widthBuffer","colorPointersBuffer","_Registered$3h","GreasedLineRibbonMesh","_slopes","_ribbonWidths","_pathsOptions","_pathOptions","hasPathOptions","pathCount","isFlatLine","slopes","pathOptions","pointsMode","_updateWidthsWithValue","directionPlanes","subPoints","_preprocess","directionsAutoMode","_GetDirectionPlanesFromDirectionsOption","_ConvertToRibbonPath","numOfPaths","facesMode","lastIndice","ribbonVertexData","_CreateRibbonVertexData","pathArrayCopy","pathCopy","_calculateSegmentLengths","pathArrayLength","previousCounters","_vSegmentLengths","_vTotalLengths","_uSegmentLengths","_uTotalLengths","widthLower","widthUpper","_CalculateSlopes","ribbonInfo","directionPlane","pointVectors","fatDirection","_GetDirectionFromPoints","DIRECTION_XZ","directionTemp","applyRotationQuaternionInPlace","_RightHandedForwardReadOnlyQuaternion","_LeftHandedForwardReadOnlyQuaternion","previousDirection","DIRECTION_XY","DIRECTION_YZ","pathOptionsCloned","pathsOptions","positionsLength","uLength","points1","points2","countersBuffer","slopesBuffer","widthsBuffer","_LeftReadOnlyQuaternion","_Registered$3g","GreasedLineMeshColorDistribution","GreasedLineMeshWidthDistribution","CreateGreasedLineMaterial","materialType","widthDistribution","materialOptions","createAndAssignMaterial","colorDistribution","GetPointsCount","CompleteGreasedLineWidthTable","CompleteGreasedLineColorTable","initialGreasedLineOptions","currentWidths","newWidths","initialMaterialOptions","isLazy","widthsDistribution","defaultWidthUpper","defaultWidthLower","missingCount","widthsData","halfCount","widthL","widthU","widthsectorLength","defaultColor","colorSectorLength","Manifold","ManifoldPromise","ManifoldMesh","FirstID","UniqueResolveID","windowAsAny","windowString","_LoadScriptModuleResolve","CSG2","numProp","_numProp","manifold","vertexStructure","_manifold","_vertexStructure","_process","printDebug","genus","surfaceArea","toVertexData","rebuildNormals","normalComponent","manifoldMesh","triVerts","strideIndex","vertProperties","centerMesh","runOriginalID","runIndex","nextID","getMaterialByUniqueID","materialToUse","_ProcessData","structure","sourceNormals","uvKindToPropertyName","sourceUV","sourceColors","sourceVertices","sourceIndices","_Construct","ignoreWorldMatrix","isMultiMaterial","originalIDs","starts","effectiveOrientation","IsCSG2Ready","manifoldUrl","manifoldInstance","manifoldMeshInstance","_LoadScriptModuleAsync","reserveIDs","GetByteIndex","bitIndex","BitArray","_byteArray","byteIndex","bitMask","GetBitMask","vertexToFaceMap","deepFirstSearchStack","startFaceIndex","currentFaceIndex","neighbors","neighborFaceIndex","sortedFaces","PositionShift","roundedNumber","HashFromVector","HashFromNumber","SetTriangle","itemSize","vec0","ToNonIndexed","newPositions","newNormals","newVertexData","ReadVector","ProcessFlatAttribute","uv01","uv12","uv20","newVertexCount","newIndices","flatData","Flat","attributeList","GatherAttributes","origPositions","flatPositions","hashToIndex","existingNeighbors","flatOpposites","existingEdges","addNeighbor","posHash","neighborHash","addOpposite","addEdgePoint","edgeHash","h0","h1","h2","_vertex","subdivideAttribute","existingAttribute","flattenedAttribute","flatVertexCount","positionHash","positionsArr","startWeight","preserveEdges","edgeSet","hasPair","heavy","neighborIndices","neighborIndex","_temp","opposites","oppositeIndex","smoothData","newArray","Subdivide","uvSmooth","modified","flatOnly","Smooth","NodeGeometryBlockConnectionPointTypes","NodeGeometryConnectionPointCompatibilityStates","NodeGeometryConnectionPointDirection","_resetCounters","_callCount","_executionCount","callCount","_storedFunction","valueMin","buildExecutionTime","_buildExecutionTime","_isReadyState","valueMax","NodeGeometryConnectionPoint","GeometryOutputBlock","NodeGeometryBlock","currentVertexData","getConnectedValue","_Registered$3f","NodeGeometryContextualSources","_rotationMatrix","_scalingMatrix","_positionMatrix","_scalingRotationMatrix","_geometryContext","_executionContext","_instancingContext","_geometryContextStack","_executionContextStack","_instancingContextStack","geometryContext","executionContext","instancingContext","pushGeometryContext","pushExecutionContext","pushInstancingContext","restoreGeometryContext","restoreExecutionContext","restoreInstancingContext","getContextualValue","noContextualData","getExecutionIndex","getOverridePositionsContextualValue","getOverrideNormalsContextualValue","Colors","Tangents","getOverrideUVs1ContextualValue","VertexID","InstanceID","getInstanceIndex","GeometryID","CollectionID","collectionId","clonePositionIndex","additionalVertexData","_instantiateWithMatrix","_instantiateWithPositionAndMatrix","GeometryInputBlock","isContextual","_contextualSource","contextualValue","Positions","Normals","LatticeID","FaceID","LoopID","displayInInspector","_Registered$3e","_evaluateContext_extraInitializers","subdivisionsZ","sizeInput","widthInput","heightInput","depthInput","evaluateContext","_evaluateContext_decorators","_Registered$3d","BoxBlock","NODEGEOMETRYEDITOR","NodeGeometryEditor","BJSNODEGEOMETRYEDITOR","_getGlobalNodeGeometryEditor","nodeGeometryEditorConfig","NodeGeometryBuildState","nodeGeometry","dataBlock","getExecutionFaceIndex","_evaluateContext_initializers","_epsilon_initializers","selector","newIndicesMap","uvIndex","checkIndex","optimizeFaces","_epsilon_decorators","_optimizeFaces_decorators","_Registered$3c","GeometryOptimizeBlock","_Registered$3b","PlaneBlock","_cachedVertexData","reverseWindingOrder","isUsingCachedData","cleanData","serializedCachedData","cachedVertexData","_serializedCachedData_decorators","_Registered$3a","MeshBlock","radiusInput","_Registered$39","IcoSphereBlock","diameterInput","_Registered$38","SphereBlock","_Registered$37","GridBlock","_Registered$36","TorusBlock","_Registered$35","CylinderBlock","_Registered$34","CapsuleBlock","_Registered$33","DiscBlock","NullBlock","_Registered$32","PointListBlock","_Registered$31","activeIndex","remappedA","remappedB","remappedC","_remapVector3Data","_remapVector4Data","_remapVector2Data","_Registered$30","SetPositionsBlock","_Registered$2$","SetNormalsBlock","tempVector2","textureCoordinateIndex","_textureCoordinateIndex_decorators","_Registered$2_","SetUVsBlock","tempVector4","_Registered$2Z","SetColorsBlock","_Registered$2Y","SetTangentsBlock","MathBlockOperations","Add","leftIsScalar","isScalar","rightIsScalar","Subtract","Multiply","Divide","Min","scalar","Max","_Registered$2X","MathBlock","MapRangeBlock","fromMin","fromMax","toMin","toMax","_Registered$2W","ConditionBlockTests","_test_initializers","ifTrue","ifFalse","_test_decorators","_test_extraInitializers","_Registered$2V","ConditionBlock","RandomBlockLocks","_currentLockId","_lockMode_extraInitializers","lockMode","lockId","Once","_lockMode_decorators","_Registered$2U","RandomBlock","NoiseBlock","_negateIf","_noiseGrad","_fade","_hashBitRotate","_hash","kx","ky","kz","_mix","v5","v6","v7","fx","fz","_perlinNoise","_perlinSigned","noise","fscale","amp","maxamp","_perlin","rmd","sum2","_Registered$2T","geometry0","geometry1","geometry2","geometry3","geometry4","_Registered$2S","MergeGeometryBlock","geometry5","geometry6","geometry7","geometry8","geometry9","_storeGeometry","availables","_Registered$2R","GeometryCollectionBlock","_Registered$2Q","CleanGeometryBlock","GeometryElbowBlock","_Registered$2P","ComputeNormalsBlock","_Registered$2O","VectorConverterBlock","xIn","yIn","zIn","wIn","xyzwOut","xOut","yOut","zOut","wOut","xyzwOutput","_Registered$2N","NormalizeVectorBlock","_Registered$2M","_Registered$2L","SetMaterialIDBlock","_indexVector3","_currentControl","_resolutionX_initializers","_resolutionX_extraInitializers","_resolutionY_initializers","_currentIndexX","_currentIndexY","_currentIndexZ","getExecutionLoopIndex","latticeControl","_resolutionZ_decorators","_resolutionX_decorators","_resolutionY_decorators","_resolutionY_extraInitializers","_Registered$2K","LatticeBlock","GeometryTrigonometryBlockOperations","Negate","OneMinus","Reciprocal","_Registered$2J","GeometryTrigonometryBlock","_translationMatrix","_backPivotMatrix","_Registered$2I","GeometryTransformBlock","RotationXBlock","_Registered$2H","RotationYBlock","_Registered$2G","RotationZBlock","_Registered$2F","ScalingBlock","scaleInput","_Registered$2E","AlignBlock","_Registered$2D","TranslationBlock","translationInput","_Registered$2C","_indexTranslation","_currentLoopIndex","alreadyDone","removeDuplicatedPositions","instanceGeometry","adaptInput","_instantiate","main","_removeDuplicatedPositions_decorators","_Registered$2B","InstantiateOnVerticesBlock","_currentPosition","_currentUV","_vertex0","_vertex1","_vertex2","_tempVector0","_tempVector1","_uv0","_uv1","_uv2","instancePerFace","accumulatedCount","totalDone","countPerFace","faceID0","faceID1","faceID2","faceDispatchCount","_Registered$2A","InstantiateOnFacesBlock","candidatesCells","gridMode","cellX","cellY","cellZ","_getIndexinGrid","candidateIndex","_getValueOnGrid","intersectionCount","_gridMode_decorators","_Registered$2z","InstantiateOnVolumeBlock","InstantiateBlock","InstantiateBaseBlock","iterationCount","_Registered$2y","InstantiateLinearBlock","transformOffset","scaleOffset","_Registered$2x","InstantiateRadialBlock","angleStart","angleEnd","radiusMatrix","angleQuat","_Registered$2w","IntFloatConverterBlock","floatIn","intIn","floatOut","intOut","_Registered$2v","DebugBlock","Vector3ToFixed","_Registered$2u","GeometryInfoBlock","facesCount","_currentVertexData","_Registered$2t","MappingTypes","tempDirection","Cylindrical","mapping","_mapping_decorators","Cubic","_Registered$2s","MappingBlock","MatrixComposeBlock","matrix0","matrix1","_Registered$2r","_Registered$2q","TeleportInBlock","TeleportOutBlock","_Registered$2p","GeometryTextureBlock","loadTextureFromData","_prepareImgToLoadAsync","imageFile","extractFromTextureAsync","_Registered$2o","clampCoordinates","_clampCoordinates_initializers","_repeatClamp","_lerp","x0","y0","c00","_getPixel","c10","c01","_clampCoordinates_decorators","_interpolation_decorators","_Registered$2n","GeometryTextureFetchBlock","BoundingBlock","_Registered$2m","BooleanGeometryOperations","_csg2LoadingPromise","InitializeCSG2Async","_operation_initializers","Intersect","useOldCSGEngine","_operation_extraInitializers","_useOldCSGEngine_initializers","vertexData0","vertexData1","boolCSG","csg0","csg1","Union","_useOldCSGEngine_decorators","_Registered$2l","BooleanGeometryBlock","GeometryArcTan2Block","_Registered$2k","GeometryLerpBlock","_Registered$2j","GeometryNLerpBlock","_Registered$2i","GeometryStepBlock","_Registered$2h","GeometrySmoothStepBlock","_Registered$2g","GeometryModBlock","_Registered$2f","GeometryPowBlock","_Registered$2e","_Registered$2d","GeometryClampBlock","GeometryCrossBlock","_Registered$2c","GeometryCurveBlockTypes","EaseOutSine","EaseOutQuad","_Registered$2b","GeometryCurveBlock","GeometryDesaturateBlock","_Registered$2a","GeometryPosterizeBlock","stepVector","_Registered$29","GeometryReplaceColorBlock","_Registered$28","GeometryDistanceBlock","_Registered$27","GeometryDotBlock","_Registered$26","GeometryLengthBlock","_Registered$25","GeometryRotate2dBlock","_Registered$24","GeometryInterceptorBlock","onInterceptionObservable","customFunction","_Registered$23","GeometryEaseBlockTypes","_get_type_decorators","_Registered$22","GeometryEaseBlock","Aggregations","aggregation","_aggregation_initializers","Sum","_aggregation_decorators","_aggregation_extraInitializers","_Registered$21","AggregatorBlock","_flatOnly_initializers","loopWeight","_loopWeight_decorators","_flatOnly_decorators","_flatOnly_extraInitializers","_Registered$20","SubdivideBlock","ExtrudeGeometryCap","inputGeometry","depthValue","faceNormal","bottomPositions","topPositions","edgeCount","triIdx","triIndex","boundaryEdges","minV","inOrder","maxV","orderedAb","sideIndices","aTop","bTop","capStart","CapStart","finalIndices","capEnd","finalPositions","finalUVs","finalColors","finalTangents","uvSets","uvData","finalUV","_cap_decorators","CapEnd","CapAll","_Registered$1$","ExtrudeGeometryBlock","PositionEpsilon","OutputPositionEpsilon","NormalEpsilon","TriangleAreaEpsilon","_Quantize","quantized","_PositionKey","_VectorKey","_OutputQuantize","_OutputPositionKey","_EdgeKey","_GetVertexAttributes","_InterpolateAttributes","_GetMaterialIndex","_IsFlatFace","cornerNormals","_IsBevelPolygonPoint","_GetCapPointPosition","_GetCapPointNormal","_GetCapPointAttributes","_GetCapPointMaterialIndex","_ClonePolygonPoint","_InterpolatePolygonPoint","_NormalizeNormalOrFallback","_InterpolateSegmentNormal","denominator","tMax","tMin","minNormal","maxNormal","_InterpolateSegmentPoint","_InterpolateSegmentAttributes","minAttributes","maxAttributes","_ClipPolygonAgainstEdge","edgeStart","inward","previousInside","currentInside","_SlerpDirections","_AddUniqueNormal","_InsertPointOnPolygonBoundary","bestEdgeIndex","bestDistanceSquared","bestProjection","edgeLengthSquared","insertedPoint","_BuildMergedBoundaryPolygon","edgeUseCounts","key0","key1","edgeKey","edgeUseCount","adjacency","adjacency0","adjacency1","orderedKeys","previousKey","currentKey","nextKey","weldedPositionMap","originalToWelded","weldedPositions","weldedIndex","edges","vertexFaces","averageCornerNormal","faceList","edgeIndex","_BuildTopology","_CloneVertexData","selectedEdges","selectedVertices","selectedEdgeCountPerVertex","shortestSelectedEdgeLength","face0","face1","bevelAmount","faceClipEdges","visitedFaces","groupNormal","edgeFace","clipEdges","addedClipEdges","edgeDirection","_BuildCoplanarFaceClipEdges","attributeDescriptors","addDescriptor","_BuildAttributeDescriptors","attributeLength","outputPositions","outputNormals","outputNormalContributions","outputVertexAttributes","outputIndices","outputTriangleMaterialIndices","outputVertexBuckets","outputVertexGroups","faceEdgeSegments","capPoints","preparedFaces","edgeIntervals","normalizedNormal","vertexAttributes","canonicalIndex","outputIndex","smoothingGroup","_AttributesMatch","normalContributions","outputX","outputY","outputZ","addCapPoint","_AverageAttributes","_AddUniquePoint","targetNormal","n0","n2","p0Attributes","p1Attributes","p2Attributes","vn1","vn2","va1","va2","getOrCreateVertex","centerAttributes","centerNormal","useFlatNormals","isFlat","selectedFaceEdges","clipEdge","selectedFaceEdge","edgeLength","pointsOnLine","orientedEdgeStart","segment0","segment1","tEnd","preparedFace","interval","emittedMergedFaces","preparedFacesByPlane","planeKey","mergedPolygon","addFacePolygon","faceNormal0","faceNormal1","segment0Start","segment1Start","segment0End","segment1End","segment0StartNormal","segment1StartNormal","segment0EndNormal","segment1EndNormal","segment0StartAttributes","segment1StartAttributes","segment0EndAttributes","segment1EndAttributes","startProfilePoints","endProfilePoints","startProfileNormals","endProfileNormals","startProfileAttributes","endProfileAttributes","profileAmount","profileNormal","startNormal","endNormal","startAttributes","endAttributes","centerStart","centerEnd","normalTarget","incidentNormals","vertexPosition","cornerCapPoints","cornerAttributes","averageNormal","bitangent","cross12","_SolveThreePlaneIntersection","rows","rowIndex","rowAmount","columnAmount","nextRow","targetNormal0","targetNormal1","targetNormal2","secondTargetNormal0","secondTargetNormal1","secondTargetNormal2","secondTargetNormal","verticesWithSphericalPatch","addSphericalCornerPatch","incidentFaces","sortedPoints","da","db","polygonPoints","addPatchTriangle","point0","bestIndex","bestScore","centerMaterialIndex","point0Position","point1Position","_AssignAttributeOutputs","materialResult","materialOrder","materialIndices","groupedIndices","_BuildMaterialInfoResult","_BevelVertexData","_Registered$1_","BevelBlock","depthMix","partIndices","sortSourceIndices","sortDepths","sortKeys","sortCounts","partMatrices","intervals","sortRequestId","rangeVersion","globalWorldMatrix","useCountingSort","activeIntervals","emptySplatIndex","renderSplatCount","totalSplats","rangeIndex","camDot","computeDepthCoeffs","perf","sortStart","logSortPerformance","depthCoeffs","partLen","co","depthSign","coeff","writeIndex","minDepth","inconsistentSnapshot","rangeWords","gather","sourceIndex","rawPart","compareBits","bucketCount","maxKey","outIndices","vertexCountPadded","floatMix","sortError","IsNative","Native","UnpackUnorm","bits","Unpack111011","Unpack8888","UnpackRot","PLYType","PLYValue","GaussianSplattingMeshBase","_GetSplatDataBytes","_GetSplatDataFloats","floatSize","_BuildSplatRangeData","rangePairs","rangeCount","disableDepthSort","_disableDepthSort","_worker","_sortIsDirty","_instantiateWorker","viewDirectionFactor","_shDegree","maxDegree","_maxShDegree","maxShDegree","_splatIndex","renderedSplatCount","_activeSplatRanges","_activeSplatRenderCount","setSplatIndexRanges","_setSplatIndexRanges","rangeData","_activeSplatRangeKey","_activeRangeVersion","_postIntervalsToWorker","_ensureDepthMixSize","_postToWorker","_updateSplatIndexBuffer","_readyToDisplay","_canPostToWorker","paddedCount","_depthMix","BigInt64Array","_setExternalWorkBuffer","centers","covariancesA","covariancesB","splatPositions","rotationTextures","_covariancesATexture","_covariancesBTexture","_centersTexture","_splatPositions","_shTextures","_rotationsATexture","_rotationsBTexture","_rotationScaleTexture","_needsRotationScaleTextures","splatsData","_keepInRam","_splatsData","shData","_shData","splatSizeRange","_splatSizeMin","_splatSizeMax","updateData","_useSog","_sogParams","meansTextureL","meansTextureU","scalesTexture","quatsTexture","sh0Texture","shCentroidsTexture","shLabelsTexture","_textureSize","cameraViewInfo","_MakeSplatGeometryForMesh","originPositions","originIndices","_BatchSize","keepInRam","_modelViewProjectionMatrix","_hasRenderedOnce","_mrtAtlas","_shMrtAtlas","_useShMrtAtlas","_shMrtAtlasTextureCount","_rotMrtAtlas","_useRotMrtAtlas","_rotationDataA","_rotationDataB","_rotationScaleData","_alwaysRetainSplatsData","_flipY","_delayedTextureUpdate","_useRGBACovariants","_tmpCovariances","_cachedBoundingMin","onPartCountChangedObservable","onPartRemovedObservable","_onBeforeAtlasRebuildObservable","_onAfterAtlasRebuildObservable","viewUpdateThreshold","_DefaultViewUpdateThreshold","_loadingPromise","lineStart","lineCount","_getTextureDataUpdateEngine","_gsInterFrameYield","_timeoutId","_innerRafId","_AcquireGsInterFrameYield","loadFileAsync","gaussianSplattingMaterial","_cameraViewInfos","cameraViewInfos","canRenderWithPendingRefresh","sortBufferMissing","sortRefreshPending","worldMatrixDirty","splatIndexBufferSet","sortAppliedId","_isSortStateDirty","_getCameraDirection","cameraViewMatrix","cameraProjectionMatrix","cameraViewProjectionMatrix","modelMatrix","modelViewMatrix","worldMatrixOnly","previousWorld","sortWorldMatrix","sortCameraForward","sortCameraPosition","outdated","frameIdLastUpdate","activeViewInfos","cameraMesh","hidden","newViewInfos","hasSortFunction","hasNativeSort","_sortRequestId","UseCountingSort","LogSortPerformance","sortSplats","renderPassMaterial","ubuf","headerEndIndex","chunkElement","chunkCount","rowVertexOffset","rowChunkOffset","double","uint","ushort","uint16","uchar","ElementMode","chunkMode","vertexProperties","chunkProperties","_ValueNameToEnum","_TypeNameToEnum","headerEnd","_RowOutputLength","shBuffer","shCoefficientCount","rowVertexLength","rowChunkLength","_GetCompressedChunks","compressedChunks","currentChunk","minScale","minColor","propertyIndex","_GetSplat","rowOutputLength","chunkIndex","plySH","getFloat64","compressedChunk","_SH_C0","shIndex","compressedValue","clampedValue","shDim","ConvertPLYWithSHToSplat","useCoroutine","ParseHeader","_PlyConversionBatchSize","shIndexRead","splatCount","AllocateShBuffers","shIndexWrite","shValue","ConvertPLYToSplat","updateDataAsync","splat","gaussianSplattingMesh","shTexture","_ReleaseGsInterFrameYield","newGS","_copyTextures","binfo","_makeEmptySplat","covA","covB","covBSItemSize","srcIndex","dstIndex","dstArrayIndex","matrixRotation","matrixScale","fBuffer","rotLength","rotDataA","rotDataB","rotScaleData","covariances","covIndex","c3","c4","c5","det3d","splatSize","_onUpdateTextures","_onIndexDataReceived","_partIndices","_textureLength","_onIncrementalUpdateStart","updateEngine","covType","_createShMrtAtlas","_createRotMrtAtlas","rotType","createTextureFromData","createTextureFromDataU8","createEmptyTextureU32","createTextureFromDataF16","firstTime","_useMrtAtlas","textureSizeChanged","needsMrtConversion","growingMrtAtlas","shTex","_updateShTextureData","_setDelayedTextureUpdate","_updateTextureFromData","requiredShTextureCount","previousVertexCount","_cachedBoundingMax","_notifyWorkerNewData","_postWorkerPositionsRange","splatOffset","floatOffset","_writeStreamingSplats","globalOffset","_makeSplat","gi","runEnd","_updateTextureFromDataRect","runLen","textureLength","incremental","_canReuseCachedData","firstNewLine","oldPositions","_updateTextures","lineCountUpdate","updateLine","batchEndLine","uploadStartLine","uploadStartTexel","batchEndTexel","splatIdx","_updateSubTextures","firstNewTexel","_SplatBatchSize","paddedEnd","_updateData","paddedVertexCount","previousIndex","expectedByteLength","uploadData","padded","startTexel","availableTexelCount","texelCount","viewTexelCount","fullRowCount","fullRowTexelCount","partialRowOffset","texelStart","covAView","covBView","colorsView","centersView","rotAView","rotBView","rotScaleView","GaussianSplattingSortWorker","_onWorkerCreated","renderedPadded","indexMix","_appendSourceToArrays","dstOffset","srcCount","srcRaw","texIdx","transformedQuaternion","floatIndex","bytesEach","ProgressiveUpdateAmount","GaussianSplattingPartProxyMesh","_partIndex","proxiedMesh","splatsDataOffset","shDataOffset","_disabledVisibility","_splatsDataOffset","_shDataOffset","_minimum","_maximum","_applyBoundingInfo","setWorldMatrixForPart","setPartVisibility","getPartVisibility","updateBoundingInfoFromPartData","updatePartIndex","newPartIndex","updatePartMetadata","compoundSplatMeshId","_Registered$1Z","_GaussianSplattingBytesPerSplat","_GaussianSplattingBytesPerShTexel","_partIndicesTexture","_part0LocalMin","_part0LocalMax","_rebuilding","_partSplatRanges","_streamingStates","_budgetDemands","_budgetAlloc","_budgetSettled","_tombstonedPartIndices","_partWorldData","_partProxies","_updateBoundingInfoFromProxies","compoundWorld","invCompoundWorld","wMin","wMax","lMin","lMax","_budgetObserver","_lodBudgetParticipants","_partMatrices","GaussianSplattingSortWorkerCommand","_ensurePartIndicesTexture","_partVisibilityData","splatBudget","_splatBudget","budget","_updateBudgetCoordination","registerLodBudgetParticipant","participant","setBudgetAllocation","proxied","_apportionBudget","participants","demands","alloc","settled","getBudgetDemand","streamable","activeCount","progressed","defaultMatrix","setPartSplatRanges","_refreshPartRangeUnion","hasOverride","collected","override","GaussianSplattingMesh","_CoalesceSplatRanges","lastEnd","existingSize","partIndicesView","_appendPartSourceToArrays","splatByteOffset","splatByteLength","shByteOffset","shByteLength","splatBytes","existingVertexCount","mergedSplatsData","mergedShData","existingShByteLength","otherShByteLength","proxyMeshes","assignedPartIndices","_isReservedEmpty","splatCountA","streamingShDegree","_streamingShDegree","staticHasSH","hasSH","shDegreeNew","nextPartIndex","partIndicesA","assignedSplatsDataOffsets","part0Count","uBufA","fBufA","rebuildOffset","_createRetainedPartSource","srcUBufs","srcFBufs","partStarts","cumOffset","partIdx","uBuf","fBuf","_retainMergedPartData","needsWorkerGate","byteStart","byteEnd","partWorldMatrix","disposeOthers","proxyMesh","_hasStreamingPart","_addPartsInternal","disposeOther","shTextureCount","needsRotationScale","needsRot","removedState","atlasWidth","specs","alignedBase","frontPad","regionSplats","oldProxy","newBase","_resetForRebuild","_refreshStreamingShState","newProxy","newProxies","localRanges","workerAfterRebuild","_tombstonePart","survivors","proxyIndex","oldIndex","isSafeInteger","expectedShTextureCount","alignedCapacity","projectedSplats","boundsMin","reservedSource","boundsMax","applyBounds","assertLive","assertLocalRange","mrtAtlas","shMrtAtlas","rotMrtAtlas","isDepthSortSettled","globalRanges","encoding","compressedIndices","runs","CompressPartIndices","parsedShData","parsedPartIndices","ParsePartIndices","serializedPart","_ParseInternal","_Registered$1Y","GaussianSplattingCompoundMesh","addPart","addParts","removePart","_Registered$1X","_partCountObservers","_applyAllTo","_partRemovedObservers","GetSplatSizeRange","name$4m","shader$4m","includes$1t","name$4l","shader$4l","includes$1s","name$4k","shader$4k","includes$1r","name$4j","shader$4j","shader$4i","name$4i","shader$4h","name$4h","name$4g","shader$4g","shader$4f","name$4f","name$4e","shader$4e","includes$1q","name$4d","shader$4d","name$4c","shader$4c","name$4b","shader$4b","name$4a","shader$4a","name$49","shader$49","AssetTaskState","AbstractAssetTask","_isCompleted","_taskState","isCompleted","taskState","_setErrorObject","_onDoneCallback","_onErrorCallback","runTask","AssetsProgressEvent","remainingCount","ContainerAssetTask","loadedContainer","loadedMeshes","loadedParticleSystems","loadedSkeletons","MeshAssetTask","AnimationAssetTask","startingIndexForNewAnimationGroups","loadedAnimatables","loadedAnimationGroups","ImportAnimations","TextFileAssetTask","BinaryFileAssetTask","ImageAssetTask","TextureAssetTask","CubeTextureAssetTask","HDRCubeTextureAssetTask","EquiRectangularCubeTextureAssetTask","superSample","AssetsManager","_waitingTasksCount","_totalTasksCount","onTaskSuccessObservable","onTaskErrorObservable","onTasksDoneObservable","onProgressObservable","useDefaultLoadingScreen","autoHideLoadingUI","addContainerTask","taskName","addMeshTask","addTextureTask","addCubeTextureTask","addEquiRectangularCubeTextureAssetTask","currentTasks","onFinish","onTaskError","_formatTaskErrorMessage","_decreaseWaitingTasksCount","onTaskSuccess","_runTask","remainingTasks","Deferred","_resolve","MeshExploder","_meshesOrigins","_toCenterVectors","_scaledDirection","_centerPosition","_centerMesh","_setCenterMesh","centerMeshIndex","totalCenters","averageCenter","distanceToCenter","shortestToCenter","meshArray","explode","FilesInput","sceneLoadedCallback","additionalRenderLoopLogicCallback","textureLoadingCallback","startingProcessingFilesCallback","onReloadCallback","useAppend","dontInjectRenderLoop","onProcessFilesErrorCallback","sceneFile","AppendAsync","_currentScene","LoadAsync","_sceneFileToLoad","_filesToLoad","_fileSelectionGeneration","_reloadGeneration","_sceneLoadedCallback","_progressCallback","_additionalRenderLoopLogicCallback","_textureLoadingCallback","_startingProcessingFilesCallback","_onReloadCallback","_errorCallback","elementToMonitor","_elementToMonitor","_dragEnterHandler","_drag","_dragOverHandler","_dropHandler","_drop","filesToLoad","cancelActiveLoad","_restoreCurrentScene","eventDrop","loadFiles","_traverseFolder","folder","relativePath","fullPath","isFile","correctName","completeEntry","isDirectory","readNextBatch","_processFiles","webkitRelativePath","onProcessFileCallback","dataTransferItems","dataTransfer","folders","getAsEntry","webkitGetAsEntry","getAsFile","fileSelectionGeneration","_processLoadedFiles","_processReload","reload","sceneFileToLoad","reloadGeneration","stopRenderLoop","MultiObserver","Watch","observables","_Registered$1W","lastReturnedValue","SceneOptimization","getDescription","TextureOptimization","maximumSize","HardwareScalingOptimization","_currentScale","maximumScale","_directionOffset","ShadowsOptimization","isInImprovementMode","PostProcessesOptimization","LensFlaresOptimization","CustomOptimization","onGetDescription","ParticlesOptimization","RenderTargetsOptimization","UpdateSelectionTree","MergeMeshesOptimization","_UpdateSelectionTree","updateSelectionTree","globalPool","globalLength","currentPool","_canBeMerged","sceneAsAny","SceneOptimizerOptions","targetFrameRate","trackerDuration","optimizations","addOptimization","optimization","addCustomOptimization","SceneOptimizer","_improvementMode","currentPriorityLevel","_currentPriorityLevel","currentFrameRate","_currentFrameRate","_targetFrameRate","_trackerDuration","autoGeneratePriorities","improvementMode","_isRunning","onSuccessObservable","onNewOptimizationAppliedObservable","onFailureObservable","optim","_checkCurrentState","noOptimizationApplied","onFailure","ModerateDegradationAllowed","SerializedGeometries","SerializeGeometry","serializationGeometries","SerializeMesh","serializationScene","FinalizeSingleNode","serializeMaterial","submaterial","boxes","cylinders","toruses","grounds","planes","torusKnots","SceneSerializer","_Serialize","checkSyncReadSupported","animationGroupIndex","getGeometries","_CollectPromises","toSerialize","withParents","withChildren","name$48","shader$48","name$47","shader$47","name$46","shader$46","name$45","shader$45","VideoRecorder","targetCanvas","captureStream","isRecording","_isRecording","audioTracks","addTrack","_mediaRecorder","ondataavailable","_handleDataAvailable","_handleError","onstop","_handleStop","maxDuration","stopRecording","_fileName","_recordedChunks","recordChunckSize","superBuffer","FxaaPostProcess","_Registered$1V","screenshotCanvas","useFill","clearWithSceneColor","GetScreenshotSize","useRenderTarget","mainObjectRendererTask","getCreationOptions","renderContext","srcWidth","srcHeight","destWidth","destHeight","save","restore","CreateScreenshotWithResizeAsync","camera_1","customDumpData","timeoutInMilliseconds","timeoutErrorCallback","finalWidth","finalHeight","originalGetRenderWidth","dumpDataFunc","originalCamera","originalCameras","originalOutputRenderTarget","currentMeshList","originalSpritesEnabled","originalGetRenderHeight","fxaaPostProcess","renderToTexture","automaticDownload","numberOfFramesToRender","currentTaskListLength","outputTextureHandle","numberOfFrames","currentParallelShaderCompile","ScreenshotTools","CreateScreenshotAsync","_Registered$1U","InspectableType","DataReader","readAsync","_dataView","_dataByteOffset","readUint32","readUint8Array","skipBytes","name$44","shader$44","name$43","shader$43","SubEmitterType","DataStorage","_GetStorage","localStorage","setItem","removeItem","inMemoryStorage","getItem","ReadString","WriteString","_Storage","ReadBoolean","WriteBoolean","ReadNumber","WriteNumber","ReadJson","WriteJson","currentDrag2","currentColorGradient","currentSizeGradient","currentAngularSpeedGradient","currentVelocityGradient","currentLimitVelocityGradient","currentDragGradient","randomCellOffset","randomNoiseCoordinates1","randomNoiseCoordinates2","initialColor","lifeTime","age","_properties","_Count","_updateCellInfoFromSystem","updateCellIndex","offsetAge","changeSpeed","spriteRandomStartCell","initialEndSpriteCellId","initialStartSpriteCellId","initialSpriteCellLoop","subEmitter","emitterMesh","inheritDirection","_inheritedVelocityOffset","_inheritParticleInfoToSubEmitters","attachedSubEmitters","_inheritParticleInfoToSubEmitter","onReset","initialDirection","currentColor1","currentColor2","currentSize1","currentSize2","currentAngularSpeed1","currentAngularSpeed2","currentVelocity1","currentVelocity2","currentLimitVelocity1","currentLimitVelocity2","currentDrag1","remapData","_CreateColorData","_CreateColorDeadData","_colorDiff","_CreateColorGradientsData","_ProcessColorGradients","_ratio","colorGradients","_ProcessColor","_scaledUpdateSpeed","_scaledColorStep","_ProcessAngularSpeed","_CreateDirectionData","_emitterWorldMatrix","_emitterInverseWorldMatrix","_CreateVelocityGradients","_CreateLimitVelocityGradients","directionScale","limitVelocity","scaledDirection","_CreateIsLocalData","_ProcessPosition","_CreateDragData","drag","_CreateNoiseData","_ProcessNoise","noiseTextureData","_noiseTextureData","noiseTextureSize","_noiseTextureSize","fetchedColorR","_fetchR","fetchedColorG","fetchedColorB","scaledForce","noiseStrength","_tempScaledUpdateSpeed","_ProcessGravity","_scaledGravity","_CreateSizeData","_CreateSizeGradientsData","_CreateStartSizeGradientsData","_actualFrame","GetCurrentGradient","_currentStartSizeGradient","_currentStartSize1","_currentStartSize2","_CreateRampData","_ProcessRemapGradients","_CreateLifeGradientsData","factorGradient1","factorGradient2","lifeTime1","lifeTime2","_emitPower","_CreateLifetimeData","_CreateEmitPowerData","_CreateAngleData","_CreateAngleGradientsData","_CreateSheetData","activeOne","previousItem","nextItem","_ConnectAfter","_ConnectAtTheEnd","_RemoveFromQueue","ThinParticleSystem","_startDirectionFunction","_directionCreation","_CreateCustomDirectionData","_startPositionFunction","_positionCreation","_CreateCustomPositionData","_CreatePositionData","useRampGradients","_useRampGradients","_rampCreation","_gravityProcessing","_remapGradientProcessing","_isLocal","_isLocalCreation","particles","_particles","_sheetCreation","_colorDeadCreation","getActiveCount","isAlive","_customWrappers","onBeforeDrawParticlesObservable","_onBeforeDrawParticlesObservable","vertexShaderName","_noiseCreation","_noiseProcessing","_positionProcessing","customEffect","noUpdateQueue","RegisterEnginesExtensionsEngineAlpha","onStoppedObservable","_stockParticles","_newPartsExcess","_useFixedCapacityForSnapshot","_fixedCapacityHighWaterMark","_started","updateInAnimate","_rawTextureWidth","_updateQueueStart","_startSizeCreation","_createQueueStart","lastParticle","defaultProjectionMatrix","_vertexArrayObject","_lifeTimeCreation","_emitPowerCreation","_sizeCreation","_angleCreation","_colorCreation","_colorProcessing","_angularSpeedProcessing","_directionProcessing","_ProcessDirection","sameParticleArray","previousAge","oldDiff","currentQueueItem","_emitFromParticle","_serializeTexture","_syncLifeTimeCreation","_syncStartSizeCreation","addLifeTimeGradient","_addFactorGradient","_removeFactorGradient","addSizeGradient","_sizeGradientProcessing","_ProcessSizeGradients","_ConnectBefore","addColorRemapGradient","addAlphaRemapGradient","addAngularSpeedGradient","_angularSpeedGradientProcessing","_ProcessAngularSpeedGradients","addVelocityGradient","_velocityCreation","_velocityGradientProcessing","_ProcessVelocityGradients","addLimitVelocityGradient","_limitVelocityCreation","_limitVelocityGradientProcessing","_ProcessLimitVelocityGradients","addDragGradient","_dragCreation","_dragGradientProcessing","_ProcessDragGradients","addStartSizeGradient","_rampGradients","_rampGradientsTexture","tmpColor","_syncRampGradientTexture","_createRampGradientTexture","addRampGradient","removeRampGradient","_removeGradientAndTexture","addColorGradient","colorGradient","removeColorGradient","_resetEffect","_vertexBuffer","vertexSize","cellIndexBuffer","directionBuffer","rampDataBuffer","_linesIndexBufferUseInstancing","indicesWireframe","_alive","startDelay","_currentEmitRateGradient","_currentEmitRate1","_currentEmitRate2","preWarmCycles","noiseTextureAsProcedural","onStartedObservable","stopSubEmitters","_postStop","_createParticle","emitterPosition","updateFunction","_createNewOnes","newParticles","attributeNamesOrOptions","_GetEffectCreationOptions","effectCreationOption","fillImageProcessing","fillUniformsAttributesAndSamplerNames","_GetAttributeNamesOrOptions","customWrapper","geometryRendering","releasedWrappers","geometryRenderingConfiguration","renderOffset","_calculateEmitRate","_appendParticleVertices","_clearFixedCapacitySnapshotData","_appendParticleVertex","particles_vertex","particles_fragment","particles_vertex$1","particles_fragment$1","particleTexture","_getWrapper","textureMask","_bindGeometryRendering","_setEngineBasedOnBlendMode","rendered","outparticles","disposeTexture","_onDispose","disposeAttachedSubEmitters","disposeEndSubEmitters","SubEmitter","_disposeEmitterOnDispose","inheritedVelocityAmount","_ParseParticleSystem","doNotStart","_isSubEmitter","EmptyGeneratorFunc","CustomParticleEmitter","particlePositionGenerator","particleDestinationGenerator","particleDirectionGenerator","diffVector","Force","ScaledForce","ScaledForce$1","ToAttractor","ToAttractor$1","Force$1","ParticleTextureSettingKeys","_flowMap","_blockReference","_attractorUpdate","_subEmitters","templateIndex","subSystem","activeSubSystems","flowMap","_flowMapUpdate","_processParticle","flowMapStrength","removeAttractor","canStart","_prepareSubEmitterInternalArray","subEmitters","ParticleSystem","_stopSubEmitters","_removeFromRoot","_rootParticleSystem","textureSettings","updateSpeed","rampGradients","colorRemapGradients","colorRemapGradient","alphaRemapGradients","alphaRemapGradient","sizeGradients","sizeGradient","angularSpeedGradients","angularSpeedGradient","velocityGradients","velocityGradient","dragGradients","dragGradient","emitRateGradients","emitRateGradient","startSizeGradients","startSizeGradient","lifeTimeGradients","lifeTimeGradient","limitVelocityGradients","limitVelocityGradient","emitterType","_rootUrl","cell","cellArray","sub","newAttractor","Attractor","subs","getCapacity","getColorGradients","serializedGradient","getRampGradients","getColorRemapGradients","getAlphaRemapGradients","getSizeGradients","getAngularSpeedGradients","getVelocityGradients","getDragGradients","getEmitRateGradients","getStartSizeGradients","getLifeTimeGradients","getLimitVelocityGradients","cloneTexture","clonedTexture","serialization","BILLBOARDMODE_STRETCHED","_Registered$1T","_trackedScene","_savedJSON","getDelta","currentForceSerializeBuffers","newJSON","deltaJSON","_compareCollections","_compareArray","originalUniqueIds","originalObject","originalUniqueId","currentObjects","_compareObjects","__state","deleteId","currentUniqueId","originalObjet","aDifferenceWasFound","diffFound","allGenerators","ApplyDelta","anyScene","_ApplyDeltaForEntity","GetShadowGeneratorById","_ApplyPropertiesToEntity","finder","addNew","targetEntity","Levenshtein","Alphabet","characters","_characterToIdx","_insertionCosts","_deletionCosts","_substitutionCosts","Deserialize","alphabet","charToInsertionCost","charsToSubstitutionCost","charToDeletionCost","outerIdx","innerIdx","getInsertionCost","getDeletionCost","Sequence","_characters","sequence","_MAX_SEQUENCE_LENGTH","_alphabet","getCharacterIdx","_Distance","aChars","bChars","aLength","bLength","costMatrix","_CostMatrix","aIdx","bIdx","_InsertionCost","_DeletionCost","_SubstitutionCost","getSubstitutionCost","Trajectory","trajectory","_segmentLength","getT","resampleAtTargetResolution","targetResolution","resampled","tokens","tokenization","segmentDir","_TransformSegmentDirToRef","_TokenizeSegment","priorVec","fromVec","toVec","_ForwardDir","_InverseFromVec","_UpDir","_LookMatrix","_FromToVec","_BestMatch","_Score","_BestScore","Vector3Alphabet","Generate","alphabetSize","startingStepSize","endingStepSize","fixedValues","distSq","scratch","TrajectoryDescriptor","_sequences","CreateFromTrajectory","vector3Alphabet","levenshteinAlphabet","CreateFromTokenizationPyramid","_GetTokenizationPyramid","pyramid","_FINEST_DESCRIPTOR_RESOLUTION","tokenize","totalDistance","TrajectoryClass","_descriptors","desc","centroidIdx","_centroidIdx","averageDistance","_averageDistance","described","_refreshDescription","getMatchCost","_MIN_AVERAGE_DISTANCE","TrajectoryClassifier","maximumAllowableMatchCost","_maximumAllowableMatchCost","_levenshteinAlphabet","nameToDescribedTrajectory","classifier","_vector3Alphabet","_nameToDescribedTrajectory","vecs","charIdxs","trajectorySet","classification","classifyTrajectory","allowableMatches","trajectoryClass","bestIdx","bestMatch","getMatchMinimumDistance","Reflector","_webSocket","_SERVER_PREFIX","serverMessage","_handleServerMessage","_handleClientMessage","onclose","SerializeAsync","PressureObserverWrapper","onPressureChanged","IsAvailable","PressureObserver","knownSources","unobserve","DynamicFloat32Array","itemCapacity","_view","_itemLength","itemLength","_growArray","newCapacity","InitialArraySize","TimestampColHeader","NumPointsColHeader","CarriageReturnRegex","PerformanceViewerCollector","SliceDataOffset","NumberOfPointsOffset","_enabledStrategyCallbacks","_collectDataAtFrame","_startingTimestamp","numberOfIndices","datasets","startingIndices","previousStartingIndex","_strategies","datasetObservable","_datasetMeta","_eventRestoreSet","_customEventObservable","addCollectionStrategies","strategyCallback","afterRenderObserver","eventVal","stringObserver","sendEvent","_restoreStringEvents","registerEvent","strategyCallbacks","_getHexColorFromId","metadataObservable","toStr","preserveStringEventsRestore","_hasLoadedData","hasLoadedData","keepDatasetMeta","numPointsIndex","parsedDatasets","firstLine","idCategoryMap","dataLines","csvContent","toISOString","shouldPreserve","DefaultDisposeImpl","PerfCollectionStrategy","FpsStrategy","ThermalStrategy","_PressureStrategy","PowerSupplyStrategy","TotalMeshesStrategy","ActiveMeshesStrategy","ActiveIndicesStrategy","ActiveFacesStrategy","ActiveBonesStrategy","ActiveParticlesStrategy","DrawCallsStrategy","drawCalls","onBeforeAnimationsObserver","onAfterRenderObserver","TotalLightsStrategy","TotalVerticesStrategy","TotalMaterialsStrategy","TotalTexturesStrategy","AbsoluteFpsStrategy","sceneInstrumentation","SceneInstrumentation","MeshesSelectionStrategy","timeTaken","onBeforeActiveMeshesObserver","onAfterActiveMeshesObserver","RenderTargetsStrategy","onBeforeRenderTargetsObserver","onAfterRenderTargetsObserver","ParticlesStrategy","onBeforeParticlesObserver","onAfterParticlesObserver","SpritesStrategy","onBeforeSpritesObserver","onAfterSpritesObserver","AnimationsStrategy","onAfterAnimationsObserver","PhysicsStrategy","onBeforePhysicsObserver","onAfterPhysicsObserver","RenderStrategy","onBeforeDrawPhaseObserver","onAfterDrawPhaseObserver","FrameTotalStrategy","InterFrameStrategy","GpuFrameTimeStrategy","engineInstrumentation","EngineInstrumentation","_Registered$1S","SnapshotRenderingHelper","_disableRenderingRefCount","_currentPerformancePriorityMode","_isEnabling","_enableCancelFunctions","_disableCancelFunctions","_particleSystemBillboardFlags","fixMeshes","_fastSnapshotRenderingEnabled","disableSnapshotRendering","enableSnapshotRendering","ubLeftOver","imanager","_spriteRendererUpdateEffects","_updateFixedCapacityParticleSystem","debugMessage","_pendingCurrentPerformancePriorityMode","targetFrameId","_executeAtFrame","callbackWhenSceneReady","morphTargetsNumMaxInfluences","updateInstancedMeshes","_updateInstancedMesh","updateMeshesForEffectLayer","_onBeforeRenderObserverUpdateLayer","_updateMeshMatricesForRenderPassId","_onResizeObserver","sceneTransformationMatrix","_spriteRendererDirectMatrixUpdate","fixParticleSystem","_particleSystemUpdateEffects","defaultViewMatrix","perPass","_particleSystemDirectMatrixUpdate","billboard","billboardAll","_Registered$1R","_coroutineScheduler","schedulerAndDispose","coroutines","onSteps","onErrors","CreateObservableScheduler","_coroutineSchedulerDispose","cancelAllCoroutines","AreaLightTextureTools","_kernelLibrary","_blurSize","_scalingRange","_alphaFactor","_generateGaussianKernel","areaLightTextureProcessing_fragment","areaLightTextureProcessing_fragment$1","oldWrapU","oldWrapV","_scaleImageDownAsync","_applyProgressiveBlurAsync","kernelHalfSize","_mirrorIndex","kernelLibrary","marginStart","marginEnd","targetKernel","kernelData","_transposeImage","srcBase","dstBase","rourcePixel","_applyGaussianBlurRange","wasProbeProvided","meshesToConsider","meshesFilter","dumpTexture","pixelDataPromise","name$42","_currentOperation","lockAsync","wrappedFunc","newOperation","locks","deferred","acquiredLocks","lock","Lazy","name$41","shader$41","includes$1p","name$40","shader$40","includes$1o","name$3$","shader$3$","includes$1n","name$3_","shader$3_","includes$1m","name$3Z","shader$3Z","includes$1l","name$3Y","shader$3Y","includes$1k","name$3X","shader$3X","name$3W","shader$3W","RecastJSPlugin","recastInjection","Recast","bjsRECAST","_maximumSubStepCount","_timeFactor","_tempVec1","_tempVec2","setWorkerURL","workerURL","setMaximumSubStepCount","newStepCount","timeFactor","createNavMesh","tri","navMesh","NavMesh","meshIndices","meshPositions","thinMatrices","tmpMatrix","matrixIndex","completion","rc","rcConfig","borderSize","walkableSlopeAngle","walkableHeight","walkableClimb","walkableRadius","maxEdgeLen","maxSimplificationError","minRegionArea","mergeRegionArea","maxVertsPerPoly","detailSampleDist","detailSampleMaxError","createDebugNavMesh","debugNavMesh","getDebugNavMesh","getTriangleCount","getTriangle","getClosestPoint","maxRadius","getRandomPointAround","moveAlong","_convertNavPathPoints","navPath","getPointCount","computePath","computePathSmooth","createCrowd","maxAgents","maxAgentRadius","RecastJSCrowd","setDefaultQueryExtent","getDefaultQueryExtent","nDataBytes","dataPtr","dataHeap","NavmeshData","navmeshData","getNavmeshData","arrView","freeNavmeshData","addCylinderObstacle","addBoxObstacle","removeObstacle","obstacle","getRandomSeed","_getRandomSeed","setRandomSeed","_setRandomSeed","recastCrowd","transforms","agents","reachRadii","_agentDestinationArmed","_agentDestination","onReachTargetObservable","bjsRECASTPlugin","Crowd","getNavMesh","dtCrowdAgentParams","agentParams","maxAcceleration","maxSpeed","collisionQueryRange","pathOptimizationRange","separationWeight","updateFlags","obstacleAvoidanceType","queryFilterType","userData","agentIndex","addAgent","reachRadius","agentPos","getAgentPosition","agentVel","getAgentVelocity","pathTargetPos","getAgentNextTargetPath","getAgentState","overOffmeshConnection","agentGoto","agentTeleport","getAgentParameters","setAgentParameters","removeAgent","maxStepCount","getMaximumSubStepCount","agentPosition","groundY","ceilingY","distanceXZSquared","getCorners","Database","_enableSceneOffline","_enableTexturesOffline","_idbFactory","indexedDB","_currentSceneUrl","_ReturnFullUrlLocation","urlToScene","_db","_manifestVersionFound","_mustUpdateResources","_hasReachedQuota","IDBStorageEnabled","callbackManifestChecked","_checkManifestFile","noManifestFile","createManifestURL","pathname","timeStampUsed","manifestURL","_ValidateXHRData","manifestFile","_IsUaSupportingBlobStorage","retryManifestURL","_isSupported","onblocked","onsuccess","onupgradeneeded","createObjectStore","keyPath","completeURL","saveAndLoadImage","_saveImageIntoDB","_loadImageFromDB","notInDBCallback","transaction","onabort","oncomplete","blobTextureURL","objectStore","getRequest","generateBlobUrl","put","addRequest","versionLoaded","_loadVersionFromDB","_saveVersionIntoDB","updateInDBCallback","newVersion","progressCallBack","completeUrl","_saveFile","sceneLoaded","_checkVersionFromDB","saveAndLoadFile","targetStore","numberToLoad","lengthComputable","loadArrayBuffer","fileData","newFile","sceneUrl","tgaHeader","ddsHeader","_ParseURL","urlWithoutHash","_Registered$1Q","UniformBufferEffectCommonAccessor","_isUbo","_renderVAO","_renderVAOEffects","_updateVAO","RegisterEngineTransformFeedback","_baseUniformsNamesLength","_updateEffectOptions","contextLost","_renderVertexBuffers","isUpdateBufferCreated","_colorGradientsTexture","_needsInitialDirection","maxAttractors","createVertexBuffers","updateBuffer","renderVertexBuffers","_createUpdateVAO","renderEffect","createParticleBuffer","preUpdateParticleBuffer","updateParticleBuffer","currentActiveCount","_randomTexture2","_sizeGradientsTexture","_angularSpeedGradientsTexture","_velocityGradientsTexture","_limitVelocityGradientsTexture","_dragGradientsTexture","_meshPositionTexture","_meshNormalTexture","releaseVertexBuffers","updateVertexBuffers","_Registered$1P","WebGL2ParticleSystem","name$3V","name$3U","_bufferComputeShader","alignDataInBuffer","_updateComputeShader","particlesIn","particlesOut","randomTexture","randomTexture2","_simParamsComputeShader","bindDrawBuffers","_Registered$1O","ComputeShaderParticleSystem","name$3T","GPUParticleSystem","BILLBOARDMODE_STRETCHED_LOCAL","maxActiveParticleCount","_maxActiveParticleCount","activeParticleCount","isUpdateBufferReady","_currentActiveCount","_releaseBuffers","_targetIndex","_writePointer","_emitIndex","_emitCount","_accumulatedCount","_refreshColorGradient","reorder","_hasColorGradientColor2","structural","_gradientFamilyNeedsResync","_refreshFactorGradient","hadGradients","removeStartSizeGradient","removeLifeTimeGradient","_currentRenderingCameraUniqueId","_renderShadersLoaded","_lifeTimeGradientMin","_lifeTimeGradientMax","emitRateControl","_preWarmDone","isGPU","_meshEmitterMeshId","randomTextureSize","optionsAsNumber","_randomTextureSize","spriteSource","_attributesStrideSize","_buffer0","usingCustomEmitter","numDummies","bufferData1","_buffer1","bufferData2","_sourceBuffer","_targetBuffer","_cachedUpdateDefines","_createColorGradientTexture","_createSizeGradientTexture","_createAngularSpeedGradientTexture","_createVelocityGradientTexture","_createLimitVelocityGradientTexture","_createDragGradientTexture","_createMeshEmitterTextures","gpuRenderParticles_vertex","gpuRenderParticles_fragment","emitterWM","hasColorGradients","isBillboardStretched","isBillboardStretchedLocal","hasColorGradientColor2","_timeDelta","cg","ng","_rebakeFactorGradientTexture","_bakeFactorGradientData","_createFactorGradientTexture","_disposeMeshEmitterTextures","_meshTriangleCount","_meshTextureWidth","_meshEmitterUsedNormals","meshEmitter","useNormals","totalTexels","maxTexSize","texWidth","texHeight","posData","normData","_bakeColorGradientData","rowOffset","_rebakeColorGradientTexture","_recreateUpdateEffect","_rebuildingAfterContextLost","depthWriteState","_updateBuffer","_startSizeGradientFactor","forceUpdateOnly","effectiveEmitRate","steadyStateCount","growth","intPart","checkUpdateEffect","releaseBuffers","rvb","sourceRampGradients","sourceColorRemapGradients","sourceAlphaRemapGradients","gpuOptions","sourceFlowMap","flowTexture","attractorData","name$3S","shader$3S","name$3R","shader$3R","name$3Q","includes$1j","clipPlaneFragmentDeclaration2","geometryRenderingFragment","name$3P","shader$3P","name$3O","includes$1i","_emitterNodeIsOwned","systems","emitterNode","_emitterNode","_emitterCreationOptions","BaseAssetsUrl","setEmitterAsSphere","ParticleHelper","useGPU","ExportSet","ParticleSystemSet","_Registered$1N","individualParser","allSamplers","vertexName","fragmentName","SolidParticle","particleId","indiceIndex","model","shapeId","idxInShape","sps","modelBoundingInfo","translateFromPivot","alive","_ind","_stillInvisible","_model","_modelBoundingInfo","_bSphereOnly","ModelShape","shapeID","shapeUV","posFunction","vtxFunction","_indicesLength","_shapeUV","_shapeColors","_positionFunction","_vertexFunction","DepthSortedParticle","indLength","SolidParticleVertex","SolidParticleSystem","nbParticles","recomputeNormals","vars","_bSphereRadiusFactor","_pickable","_isVisibilityBoxLocked","_depthSort","_expandable","_shapeCounter","_copy","_computeParticleColor","_computeParticleTexture","_computeParticleRotation","_computeParticleVertex","_computeBoundingBox","_autoFixFaceOrientation","_depthSortParticles","_mustUnrotateFixedNormals","_particlesIntersect","_needs32Bits","_isNotBuilt","_lastParticleId","_idxOfId","_multimaterialEnabled","_useModelMaterial","_depthSortFunction","_materialSortFunction","_autoUpdateSubMeshes","_recomputeInvisibles","enableDepthSort","enableMultiMaterial","useModelMaterial","expandable","particleIntersection","boundingSphereOnly","bSphereRadiusFactor","computeBoundingBox","autoFixFaceOrientation","pickedBySubMesh","pickedParticles","depthSortedParticles","_multimaterial","_materials","_materialIndexesById","_tmpVertex","_indices32","_positions32","_uvs32","_colors32","_sortParticlesByMaterial","_normals32","_fixedNormal32","_unrotateFixedNormals","lind","pickedData","setMultiMaterial","uvKind","meshInd","meshUV","_getUVKind","meshCol","meshNor","_normalizeMeshVertexColors","totalFacets","facetPos","facetNor","facetInd","facetUV","facetCol","sizeO","fi","_posToShape","_uvsToShapeUV","shapeInd","shapeCol","_setDefaultMaterial","currentPos","currentInd","_meshBuilder","shapeNor","modelShape","tmpNormal","invertedRotMatrix","_resetCopy","storeApart","materialIndexesById","matIdx","tmpVertex","tmpUV","tmpRotated","pivotBackTranslation","scaledPivot","someVertexFunction","vertexFunction","copyUvs","idxpos","idxind","colorBuffer","rgbIndex","rgbaIndex","shapeNormals","shapeColors","bbInfo","posfunc","vtxfunc","_insertNewParticle","rebuildMesh","_rebuildParticle","removeParticles","currentNb","firstRemaining","shiftPos","shifInd","particlesLength","modelIndices","modelNormals","modelColors","modelUVs","insertParticlesFromArray","solidParticleArray","currentShapeId","noNor","newPart","currentCopy","_addParticle","beforeUpdateParticles","colors32","indices32","fixedNormal32","depthSortParticles","tempVectors","camAxisX","camAxisY","camAxisZ","camInvertedPosition","tmpVector0","colidx","uvidx","vpos","particleRotationMatrix","particlePosition","particleRotation","particleScaling","dsp","getParticleById","parentGlobalPosition","rotatedY","rotatedX","rotatedZ","particleGlobalPosition","rotMatrixValues","iu","iv","updateParticleVertex","vertexX","vertexY","vertexZ","pz","normalx","normaly","normalz","rotatedx","rotatedy","rotatedz","bBox","modelBoundingInfoVectors","scaledX","scaledY","scaledZ","minBbox","maxBbox","bSphereCenter","halfDiag","bSphereMinBbox","bSphereMaxBbox","vbp","dspl","sid","sortedParticle","particleIdx","faceInd","particleInd","computeSubMeshes","_materialIndexes","_indicesByMaterial","pickedParticle","getParticlesByShapeIdToRef","sortedPart","indicesByMaterial","materialIndexes","vcount","subMeshIndex","lastMatIndex","_setMaterialIndexesById","refreshVisibleSize","setVisibilityBox","vis","isAlwaysVisible","isVisibilityBoxLocked","computeParticleRotation","computeParticleColor","computeParticleTexture","computeParticleVertex","multimaterialEnabled","_filterUniqueMaterialId","multimaterial","autoUpdateSubMeshes","initParticles","recycleParticle","updateParticle","afterUpdateParticles","buildMesh","setParticles","started","stopped","CloudPoint","idxInGroup","pcs","_pcs","isSphere","PointsGroup","groupID","PointColor","PointsCloudSystem","_promises","_groups","_groupCounter","_buildMeshAsync","ec","_getColorIndicesForCoord","pointsGroup","_groupImageData","colorIndices","greenIndex","blueIndex","redForCoord","greenForCoord","blueForCoord","alphaForCoord","_setPointsColorOrUV","isVolume","colorFromTexture","uvSetIndex","place","meshMatrix","idxPoints","id0","id1","id2","v0X","v0Y","v0Z","v1X","v1Y","v1Z","v2X","v2Y","uv0X","uv0Y","uv1X","uv1Y","uv2X","uvec0","uvec1","col0X","col0Y","col0Z","col0A","col1X","col1Y","col1Z","col1A","col2X","col2Y","col2Z","colvec0","colvec1","lamda","facetPoint","uvPoint","biNorm","facetPlaneVec","gap","colPoint","deltaS","deltaV","hsvCol","v2Z","uv2Y","col2A","statedColor","colPoint3","pointColors","_groupDensity","mu","_groupImgWidth","_groupImgHeight","toHSV","_colorFromTexture","textureList","_textureNb","dataPromise","_calculateDensity","cumulativeAreas","nbFacets","remainingPoints","cumulativeArea","facetPointsWithFraction","floored","facetPoints","pointFunction","_randomUnitVector","addSurfacePoints","colorWith","colored","addVolumePoints","pindex","cindex","uindex","FlowVector","ScaledFlowVector","ScreenPos","FlowMap","flowable","flowMapSamplePosOrTransformationMatrix","localStrength","processFlowable","flowCanvas","flowCtx","flowImageData","flowMapImage","NodeParticleBlockConnectionPointTypes","NodeParticleConnectionPointCompatibilityStates","NodeParticleConnectionPointDirection","_typeConnectionSourceTranslation","isSystem","_isSystem","NodeParticleConnectionPoint","_build","NodeParticleContextualSources","NodeParticleSystemSources","particleContext","systemContext","nextGradientIndex","registerBuildPromise","_buildPromises","Position","Direction","DirectionScale","ScaledDirection","Color","InitialColor","ColorDead","Age","Lifetime","Scale","AgeGradient","SpriteCellEnd","SpriteCellIndex","SpriteCellStart","InitialDirection","ColorStep","LocalPositionUpdated","emitterWorldMatrix","emitterInverseWorldMatrix","Delta","Emitter","_TriggerSubEmitter","NodeParticleBuildState","createSystem","_blendMode_initializers","_blendMode_extraInitializers","_capacity_initializers","_capacity_extraInitializers","_manualEmitCount_initializers","_manualEmitCount_extraInitializers","_startDelay_initializers","_startDelay_extraInitializers","_updateSpeed_initializers","_updateSpeed_extraInitializers","_preWarmCycles_initializers","_preWarmCycles_extraInitializers","_preWarmStepOffset_initializers","_preWarmStepOffset_extraInitializers","_isBillboardBased_initializers","billBoardMode","_isBillboardBased_extraInitializers","_billBoardMode_initializers","_billBoardMode_extraInitializers","_isLocal_initializers","_isLocal_extraInitializers","_disposeOnStop_initializers","doNoStart","_disposeOnStop_extraInitializers","_doNoStart_initializers","_internalId","_renderingGroupId_extraInitializers","System","onStart","onEnd","onStartSystem","onEndSystem","_blendMode_decorators","_preWarmStepOffset_decorators","_isBillboardBased_decorators","_billBoardMode_decorators","_isLocal_decorators","_disposeOnStop_decorators","_renderingGroupId_decorators","_capacity_decorators","_manualEmitCount_decorators","_startDelay_decorators","_updateSpeed_decorators","_preWarmCycles_decorators","_doNoStart_decorators","_Registered$1M","SystemBlock","ParticleInputBlock","NodeParticleBlock","isSystemSource","_systemSource","systemSource","getSystemValue","_Registered$1L","ParticleTextureSourceBlock","_cachedData","_textureDataUrl","textureDataUrl","_clonedTextures","textureOutput","resolveReady","settle","extractProceduralTextureContentAsync","internalErrorObserver","textureErrorObserver","textureContent","fail","loadObservable","extractTextureContentAsync","erroredTexture","sourceScene","sourceEngine","targetEngine","_copyTextureProperties","_Registered$1K","UpdatePositionBlock","positionProcessing","_Registered$1J","ParticleMathBlockOperations","FloatGradient","Color4Gradient","Vector2Gradient","Vector3Gradient","_Registered$1I","ParticleMathBlock","_CreateLocalPositionData","BoxShapeBlock","_Registered$1H","ColorDiff","CreateParticleBlock","emitPower","_Registered$1G","systemBlocks","_systemBlocks","BJSNODEPARTICLEEDITOR","_getGlobalNodeParticleEditor","NODEPARTICLEEDITOR","NodeParticleEditor","_createNodeParticleEditor","buildPromises","updatePositionBlock","positionBlock","directionBlock","emitterShape","createParticleBlock","textureBlock","nodeParticleSet","nodeParticle","ParticleConverterBlock","colorIn","colorOut","_Registered$1F","ParticleFloatToIntBlockOperations","Ceil","Truncate","_Registered$1E","ParticleFloatToIntBlock","ParticleGradientBlock","_entryCount","_manageExtendedInputs","_reduce","nextEntry","nextValue","nextReference","currentReference","_Registered$1D","_reference_decorators","_Registered$1C","ParticleGradientValueBlock","ParticleRandomBlockLocks","_oncePerParticleMap","OncePerParticle","PerSystem","PerParticle","_Registered$1B","ParticleRandomBlock","ParticleLerpBlock","_Registered$1A","ParticleVectorLengthBlock","_Registered$1z","ParticleConditionBlockTests","_Registered$1y","ParticleConditionBlock","_calculateHeight","_emitFromSpawnPointOnly_decorators","_Registered$1x","ConeShapeBlock","CylinderShapeBlock","_Registered$1w","CustomShapeBlock","_Registered$1v","_serializedCachedData_initializers","_serializedCachedData_extraInitializers","_useMeshNormalsForDirection_initializers","useMeshColorForColor","_useMeshNormalsForDirection_extraInitializers","_useMeshColorForColor_initializers","worldSpace","_useMeshNormalsForDirection_decorators","_useMeshColorForColor_decorators","_worldSpace_decorators","_useMeshColorForColor_extraInitializers","_Registered$1u","MeshShapeBlock","PointShapeBlock","_Registered$1t","_start_initializers","_start_extraInitializers","_end_initializers","_end_extraInitializers","_spriteCellChangeSpeed_initializers","_spriteCellChangeSpeed_extraInitializers","_loop_initializers","randomStartCell","_spriteCellChangeSpeed_decorators","_loop_decorators","_randomStartCell_decorators","_start_decorators","_end_decorators","_loop_extraInitializers","_Registered$1s","SetupSpriteSheetBlock","isHemispheric","_isHemispheric_decorators","_Registered$1r","SphereShapeBlock","UpdateAngleBlock","angleProcessing","_Registered$1q","BasicSpriteUpdateBlock","spriteProcessing","_Registered$1p","UpdateAttractorBlock","attractorProcessing","attractorPosition","_Registered$1o","UpdateColorBlock","colorProcessing","_Registered$1n","UpdateDirectionBlock","directionProcessing","_Registered$1m","UpdateFlowMapBlock","flowMapTexture","flowMapProcessing","_Registered$1l","UpdateNoiseBlock","noiseTextureBlock","lastFrameId","noiseProcessing","_Registered$1k","UpdateSizeBlock","sizeProcessing","_Registered$1j","particleSystemsList","nodeParticleSystemSet","NodeParticleSystemSet","_ExtractDatafromParticleSystemAsync","createdParticle","oldSystem","timeToStopTimeRatioBlockGroupOutput","_CreateGradientBlockGroup","randomLifetimeBlock","_CreateAndConnectInput","_CreateParticleLifetimeBlockGroup","randomEmitPowerBlock","_CreateParticleEmitPowerBlockGroup","sizeGradientValue0Output","_CreateParticleInitialValueFromGradient","randomSizeBlock","_CreateParticleSizeBlockGroup","randomScaleBlock","multiplyScaleBlock","gradientBlockGroupOutput","_CreateParticleScaleBlockGroup","randomRotationBlock","_CreateParticleAngleBlockGroup","colorGradientValue0Output","randomStepBlock","lerpColorBlock","shapeBlock","spriteSheetBlock","_SpriteSheetBlock","inputParticle","updatedParticle","colorCalculation","ageToLifeTimeRatioBlockGroupOutput","_CreateAgeToLifeTimeRatioBlockGroup","addColorBlock","_CreateAndConnectContextualSource","ScaledColorStep","_BasicColorUpdateBlockGroup","colorUpdateBlock","maxAlphaBlock","decomposeColorBlock","composeColorBlock","_ClampUpdateColorAlpha","_UpdateParticleColorBlockGroup","angularSpeedCalculation","_UpdateParticleAngularSpeedGradientBlockGroup","randomAngularSpeedBlock","_UpdateParticleAngularSpeedBlockGroup","addAngle","updateAngle","_UpdateParticleAngleBlockGroup","multiplyScaleByVelocity","velocityValueOutput","multiplyDirection","_UpdateParticleVelocityGradientBlockGroup","oneMinusDragBlock","_UpdateParticleDragGradientBlockGroup","addPositionBlock","_UpdateParticlePositionBlockGroup","outputParticle","attractorBlock","_UpdateParticleAttractorBlockGroup","flowMapTextureBlock","updateFlowMapBlock","_UpdateParticleFlowMapBlockGroup","velocityLimitGradients","currentSpeedBlock","damped","compareSpeed","velocityLimitValueOutput","updateDirection","_UpdateParticleVelocityLimitGradientBlockGroup","noiseUpdate","_CreateTextureBlock","_UpdateParticleNoiseBlockGroup","sizeValueOutput","updateSizeBlock","_UpdateParticleSizeGradientBlockGroup","addDirectionBlock","_UpdateParticleGravityBlockGroup","updateSpriteCell","_UpdateParticleSpriteCellBlockGroup","newSystem","getCustomEffect","effectName","_SystemCustomShader","emitGradients","_CreateTimeToStopTimeRatioBlockGroup","roundBlock","gradientValue","_SystemEmitRateValue","targetStopDurationBlockOutput","_SystemTargetStopDuration","updateParticleOutput","newSet","gradientStep","randomBlock","sizeBlock","multiplyBlock","_CreateAndConnectSystemSource","targetToConnectTo","inputBlockName","contextSource","contextualBlockName","systemBlockName","targetStopDurationInputBlock","clampMin","clampMax","initialValues","gradientValues","gradientValueBlock","gradientBlock","_CreateGradientValueBlockGroup","randomLockMode","UpdateScaleBlock","scaleProcessing","_Registered$1i","UpdateAgeBlock","ageProcessing","_Registered$1h","BasicPositionUpdateBlock","_Registered$1g","BasicColorUpdateBlock","_Registered$1f","UpdateSpriteCellIndexBlock","spriteCellIndexProcessing","_Registered$1e","dirInView","_alignment_decorators","_Registered$1d","AlignAngleBlock","ParticleTrigonometryBlockOperations","_Registered$1c","ParticleTrigonometryBlock","stackSize","_stackSize_initializers","onDataCollectedObservable","_stackSize_extraInitializers","_stackSize_decorators","_Registered$1b","ParticleDebugBlock","ParticleElbowBlock","_Registered$1a","_Registered$19","ParticleTeleportInBlock","ParticleTeleportOutBlock","_Registered$18","_triggerCount","_limit_initializers","_limit_extraInitializers","_delay_initializers","_previousOne","conditionProcessing","targetSystem","_delay_decorators","_limit_decorators","_Registered$17","ParticleTriggerBlock","ParticleLocalVariableBlockScope","_scope_initializers","_storage","_scope_extraInitializers","_scope_decorators","Loop","_Registered$16","ParticleLocalVariableBlock","ParticleNumberMathBlockOperations","Modulo","Pow","_Registered$15","ParticleNumberMathBlock","ParticleVectorMathBlockOperations","_Registered$14","ParticleVectorMathBlock","_Registered$13","ParticleClampBlock","ParticleNLerpBlock","_Registered$12","ParticleSmoothStepBlock","_Registered$11","ParticleStepBlock","_Registered$10","name$3N","shader$3N","includes$1h","name$3M","shader$3M","includes$1g","name$3L","shader$3L","name$3K","shader$3K","includes$1f","geometryRenderingFragmentWGSL","name$3J","shader$3J","includes$1e","_Registered$$","_physicsImpostor","_disposePhysicsObserver","pivot1","pivot2","createJoint","PhysicsConstraint","getEnabled","isCollisionsEnabled","setCollisionsEnabled","getCollisionsEnabled","disposeConstraint","Physics6DoFLimit","constraintParams","setAxisFriction","getAxisFriction","limitMode","setAxisMode","setAxisMinLimit","setAxisMaxLimit","motorType","setAxisMotorType","getAxisMotorType","setAxisMotorTarget","getAxisMotorTarget","setAxisMotorMaxForce","getAxisMotorMaxForce","BallAndSocketConstraint","SliderConstraint","PrismaticConstraint","Physics6DoFConstraint","PhysicsMaterialCombineMode","CharacterSupportedState","SurfaceConstraintInteractionStatus","RagdollBoneProperties","Ragdoll","_boxConfigs","_bones","_initialRotation2","_boneNames","_transforms","_aggregates","_ragdollMode","_rootBoneName","_rootBoneIndex","_mass","_restitution","pauseSync","_defaultJoint","_defaultJointMin","_defaultJointMax","_rootTransformNode","_putBoxesInBoneCenter","getAggregate","boneNames","currentBone","currentRagdollBoneProperties","boxOffset","putBoxInBoneCenter","boneOffsetAxis","_initialRotation","nearestParent","_findNearestParent","boneParentIndex","wmat","invertedWorldMat","boneAbsPos","distanceFromParentBoxToBone","boxAbsPos","myConnectedPivot","constraintType","rootPos","_setBoneOrientationToBody","_syncBonesAndBoxes","_setBodyOrientationToBone","_syncBonesToPhysics","qmesh","qbind","qphys","skeletonRoots","_defineRootBone","_initJoints","ragdoll","SimplexSolverOutput","getOutput","outputInteractions","inputConstraints","ContactFromCast","hp","castPath","hitFraction","keepDistance","bodyMap","bodyB","allowedPenetration","PhysicsCharacterController","_stepUpSavedManifold","_contactAngleSensitivity","_tmpVecs","keepContactTolerance","maxCastIterations","penetrationRecoverySpeed","staticFriction","dynamicFriction","maxSlopeCosine","maxStepHeight","maxCharacterSpeedForSolver","characterStrength","acceleration","characterMass","_bodyPositionTracking","characterShapeOptions","capsuleRadius","capsuleHeight","footOffset","_ownShape","_shapeOptions","_transformNode","_body","_lastInvDeltaTime","_lastDisplacement","hknp","_hknp","_startCollector","HP_QueryCollector_Create","_castCollector","HP_QueryCollector_Release","shapeOptions","foot","newFootOffset","ownShape","setVelocity","newManifold","comWorld","_getComWorldToRef","pointWorld","relPos","av","arm","contactB","angSquared","contactA","planeDistSquared","p1Vel","_getPointVelocityToRef","p2Vel","velocityDiff","_findContact","referenceContact","contactList","bestFitness","fitness","_compareContacts","startCollector","castCollector","hk","numProximityHits","HP_QueryCollector_GetNumHits","newContacts","contactWorld","HP_QueryCollector_GetShapeProximityResult","currentContact","newAllowedPenetration","closestContactIndex","numCastHits","closestHitBody","hitWorld","HP_QueryCollector_GetShapeCastResult","hpBodyId","numHitBodies","e2","_createSurfaceConstraint","timeTravelled","planeDistance","extraUpStaticFriction","extraDownStaticFriction","normalDotUp","contactPosition","com","contactArm","bodyId","currentFrameWorldMatrix","previousFrameWorldMatrix","prevWorldMatrix","currentFrameWorldMatrixInverse","characterLocalPosition","characterPosition","characterWorldPosition","playerDeltaPosition","_addMaxSlopePlane","maxSlopeCos","verticalComponent","newConstraint","penetrationToResolve","_resolveConstraintPenetration","_addStepHeightWallPlane","contactDelta","stepWallVerticalProjection","surfaceConstraint","numSupportPlanes","supportPlanes","velocityIn","velocityOut","eps","groundVelocity","relativeVelocity","planeVel","origVelocity2","extraStaticFriction","hor2","horVel","horVel2","vp2","vertVel2","velOut2","maxSurfaceVelocity","sci0","sci1","axisLen2","solveSequentially","_simplexSolverSolve1d","invAxisLen","sVel","axisVel","vel2","axisProjVelocity","axisVert","av2","sci2","allowResort","pointVel","oldNum","_simplexSolverSolve2d","_simplexSolverSolveTest1d","droppedAPlane","testPlane","_simplexSolverSolve3d","_simplexSolverSortInfo","sci3","maxStatus","minDeltaTime","planeInteractions","surfaceTime","penaltyDistance","SimplexSolverInfo","SimplexSolverActivePlanes","hitIndex","minCollisionTime","relativeVel","relativeProjectedVel","relativePos","penaltyDist","projectedPos","supportPlane","_simplexSolverExamineActivePlanes","checkSupport","surfaceInfo","isSurfaceDynamic","supportedState","averageSurfaceNormal","averageSurfaceVelocity","averageAngularSurfaceVelocity","_validateManifold","_createConstraintsFromManifold","storedVelocities","_simplexSolverSolve","angleSin","numTouching","endPos","startNative","HP_World_ShapeProximityWithCollector","HP_World_ShapeCastWithCollector","numHits","simplexOutput","horizDir","maxSlope","bestFrac","bestNormal","hasBestNormal","bestBody","frac","stepHeight","upUnit","upDotVel","horizVel","horizVelLenSqr","horizVelLen","horizDist","_findBlockingConstraintIndex","upEnd","upHit","_getClosestCastHit","stepClear","elevated","fwdEnd","_castWithCollectors","fwdHit","fwdFrac","fwdFracAdjusted","fwdEndAdjusted","downDist","downEnd","downHit","landingDrop","landingPos","landingDelta","savedManifold","_refreshManifoldAtPosition","inputObjectMassInv","inputObjectImpulse","outputObjectImpulse","pointRelVel","inputProjectedVelocity","recoveryTau","deltaVelocity","invInertia","_getInverseInertiaWorld","jacAng","_getInvMass","maxPushImpulse","relVelN","triggerCollisionInfo","colliderIndex","impulsePosition","outputImpulsePosition","onTriggerCollisionObservable","mp","invOrientation","ir","getRowToRef","newVelocity","iter","solveResults","newDisplacement","solverDeltaTime","didStepUp","timeConsumed","_tryStepUp","_resolveContacts","updateResult","_displacementEps","_hitLocal","newContact","newContactIndex","displacementLengthInv","angleBetweenMovementAndSurface","keepDistanceAlongMovement","invDeltaTime","_lastVelocity","_integrateManifolds","integrate","displacementVelocity","forwardWorld","surfaceNormal","currentVelocity","surfaceVelocity","desiredVelocity","upWorld","binorm","surfaceFrame","invSurfaceFrame","relative","sideVec","fwd","desiredVelocitySF","lenSq","maxVelocityDelta","MeshAccumulator","collectIndices","_isRightHanded","_collectIndices","rootScaled","_addMesh","includeChildren","worldToRoot","worldToRootScaled","childToRootScaled","meshToRoot","numVerts","nFloats","nBytes","bufferBegin","numObjects","freeBuffer","BodyPluginData","userMassProps","contactOnA","CollisionContactPoint","contactOnB","impulseApplied","readToRef","eventOut","intBuf","floatBuf","BigInt","offA","offB","bodyIdA","bodyIdB","HavokPlugin","_disableWorldRegions","_worldRegions","region","floatingOrigin","_floatingOriginWorldRadius","newWorld","newRegion","_currentGravity","_reRegionBodyPluginData","currentRegion","worldRegion","bodyTransform","HP_Body_GetQTransform","HP_Body_GetLinearVelocity","lookAheadPos","_findExistingRegion","_getOrCreateWorldRegion","newOffset","newLocalPos","HP_Body_SetLinearVelocity","worldTransformOffset","HP_Body_GetWorldTransformOffset","_releaseWorldRegionIfEmpty","regionIndex","HP_World_GetNumBodies","HP_World_Release","_releasePendingWorldRegions","_worldRegionsPendingRelease","_multiQueryCollector","_maxQueryCollectorHits","_shapes","_constraintToBodyIdPair","_bodyCollisionEndedObservable","onCollisionObservable","onCollisionEndedObservable","hpInjection","_queryCollector","setMaxQueryCollectorHits","maxQueryCollectorHits","floatingOriginWorldRadius","_bVecToV3","gravityArray","HP_World_SetGravity","_areFloatingOriginWorldRegionsEnabled","physicsBodies","HP_World_SetIdealStepTime","HP_World_Step","_notifyCollisions","_notifyTriggers","HP_World_SetSpeedLimit","HP_World_GetSpeedLimit","HP_Body_Create","_bQuatToV4","HP_Body_SetQTransform","HP_World_AddBody","_bodyCollisionObservable","HP_World_RemoveBody","_createOrUpdateBodyInstances","hkbody","_internalSetMotionType","_internalUpdateMassProperties","pluginInstancesCount","firstBodyShape","HP_Body_SetShape","instancesToRemove","HP_Body_Release","bodyBuffer","HP_World_GetBodyBuffer","bufOffset","transformBuffer","instanceOffset","bodyTranslation","bodyOrientation","worldX","worldY","worldZ","finalTransform","parentInverseTransform","localTransform","shapeHandle","pluginRef","_getPluginReference","shapePluginData","HP_Body_GetShape","HP_Shape_GetType","_applyToBodyOrInstances","bodyPluginData","HP_Body_SetEventMask","HP_Body_GetEventMask","massPropsTuple","newProps","_internalComputeMassProperties","HP_Body_SetMassProperties","HP_Body_SetMotionType","MotionType","KINEMATIC","DYNAMIC","HP_Body_GetMotionType","controlMode","HP_Body_SetActivationControl","ActivationControl","ALWAYS_ACTIVE","ALWAYS_INACTIVE","SIMULATION_CONTROLLED","shapeRes","Result","RESULT_OK","shapeMass","HP_Shape_BuildMassProperties","_fromMassPropertiesTuple","HP_Body_GetMassProperties","HP_Body_SetLinearDamping","HP_Body_GetLinearDamping","HP_Body_SetAngularDamping","HP_Body_GetAngularDamping","lv","_v3ToBvecRef","fnToApply","HP_Body_ApplyImpulse","_bVecToV3WithOffset","HP_Body_ApplyAngularImpulse","HP_Body_SetAngularVelocity","HP_Body_GetAngularVelocity","getPrestepType","_getTransformInfos","ACTION","HP_Body_SetTargetQTransform","HP_Body_SetGravityFactor","HP_Body_GetGravityFactor","_createOptionsFromGroundMesh","HP_Shape_CreateSphere","HP_Shape_CreateBox","HP_Shape_CreateCapsule","HP_Shape_CreateContainer","HP_Shape_CreateCylinder","includeChildMeshes","accum","addNodeMeshes","numVec3s","HP_Shape_CreateConvexHull","triangles","numTriangles","HP_Shape_CreateMesh","totalNumHeights","numBytes","hkBufferIndex","bjsBufferIndex","HP_Shape_CreateHeightField","collideWith","HP_Shape_SetFilterInfo","HP_Shape_GetFilterInfo","membership","frictionCombine","restitutionCombine","hpMaterial","_materialCombineToNative","HP_Shape_SetMaterial","hkMaterial","HP_Shape_GetMaterial","_nativeToMaterialCombine","HP_Shape_SetDensity","HP_Shape_GetDensity","transformNative","HP_Shape_AddChild","HP_Shape_RemoveChild","HP_Shape_GetNumChildren","HP_Shape_SetTrigger","aabb","HP_Shape_GetBoundingBox","dataInfo","geometryRes","HP_Shape_CreateDebugDisplayGeometry","geometryInfo","HP_DebugGeometry_GetInfo","positionsInPlugin","indicesInPlugin","HP_DebugGeometry_Release","HP_Shape_Release","HP_Constraint_Create","bodyA","HP_Constraint_SetParentBody","jointId","HP_Constraint_SetChildBody","HP_Constraint_SetAnchorInParent","HP_Constraint_SetAxisMode","ConstraintAxis","LINEAR_X","ConstraintAxisLimitMode","LOCKED","LINEAR_Y","LINEAR_Z","ANGULAR_X","ANGULAR_Y","ANGULAR_Z","dist3d","LINEAR_DISTANCE","LIMITED","HP_Constraint_SetAxisMinLimit","HP_Constraint_SetAxisMaxLimit","sixdofData","axId","HP_Constraint_SetAxisStiffness","HP_Constraint_SetAxisDamping","HP_Constraint_SetCollisionsEnabled","HP_Constraint_SetEnabled","pairs","bodyIds","parentBodyInfo","childBodyInfo","initConstraint","firstId","HP_Constraint_GetEnabled","HP_Constraint_GetCollisionsEnabled","HP_Constraint_SetAxisFriction","_constraintAxisToNative","HP_Constraint_GetAxisFriction","_limitModeToNative","HP_Constraint_GetAxisMode","_nativeToLimitMode","HP_Constraint_GetAxisMinLimit","HP_Constraint_GetAxisMaxLimit","HP_Constraint_SetAxisMotorType","_constraintMotorTypeToNative","_nativeToMotorType","HP_Constraint_GetAxisMotorType","HP_Constraint_SetAxisMotorTarget","HP_Constraint_GetAxisMotorTarget","HP_Constraint_SetAxisMotorMaxForce","HP_Constraint_GetAxisMotorMaxForce","HP_Constraint_Release","hitBody","hitData","hitShape","hitPos","hitTriangle","queryMembership","queryCollideWith","shouldHitTriggers","bodyToIgnore","ignoreBody","raycastResult","offsetFrom","hkQuery","queryCollector","HP_World_CastRayWithCollector","hitDatas","HP_QueryCollector_GetCastRayResult","_populateHitData","collisionFilter","HP_World_PointProximityWithCollector","HP_QueryCollector_GetPointProximityResult","inputShapeResult","hitShapeResult","hitInputData","hitShapeData","startPosition","endPosition","fractionAlongRay","setHitFraction","collideEvents","EventType","COLLISION_STARTED","COLLISION_CONTINUED","COLLISION_FINISHED","currentCollideEvents","targetWorld","eventAddress","HP_World_GetTriggerEvents","TriggerEvent","bodyInfoA","bodyInfoB","collidedAgainstIndex","_nativeTriggerCollisionValueToCollisionType","HP_World_GetNextTriggerEvent","CollisionEvent","regionOffset","worldAddr","collisionInfo","_nativeCollisionValueToCollisionType","observableA","observableB","collisionInfoB","HP_World_GetNextCollisionEvent","numBodies","ConstraintMotorType","VELOCITY","MaterialCombine","GEOMETRIC_MEAN","MINIMUM","MAXIMUM","ARITHMETIC_MEAN","MULTIPLY","FREE","_Registered$_","HelperTools","GetContactPointToRef","pluginVersion","IsInsideCylinder","PhysicsHelper","_hitData","distanceFromOrigin","applyRadialExplosionImpulse","radiusOrEventOptions","falloff","getImpostors","getBodies","useCallback","PhysicsRadialExplosionEventOptions","affectedImpostorsCallback","affectedBodiesCallback","PhysicsRadialExplosionEvent","affectedImpostorsWithData","getImpostorHitData","_copyPhysicsHitData","triggerAffectedImpostorsCallback","_applicationForBodies","applyRadialExplosionForce","fnApplication","affectedBodiesWithData","iterateOverAllInstances","getBodyHitData","triggerAffectedBodiesCallback","gravitationalField","updraft","updraftMode","PhysicsUpdraftEventOptions","vortex","PhysicsVortexEventOptions","_dataFetched","_sphere","HasAppliedForces","bodyObjectCenter","_getHitData","impostorObjectCenter","_prepareSphere","PhysicsGravitationalFieldEvent","_physicsHelper","_origin","_tickCallback","radialExplosionEvent","PhysicsUpdraftEvent","_originTop","_originDirection","_cylinderPosition","_prepareCylinder","_cylinder","multiplier","_getImpostorHitData","impostorObject","_HitData","_getBodyHitData","_intersectsWithCylinder","PhysicsVortexEvent","originOnPlane","_OriginOnPlane","originToImpostorDirection","absoluteDistanceFromOrigin","directionToOrigin","forceX","forceY","forceZ","centripetalForceThreshold","centripetalForceMultiplier","updraftForceMultiplier","perpendicularDirection","centrifugalForceMultiplier","bodyObject","bodyCenter","PhysicsRadialImpulseFalloff","PhysicsUpdraftMode","_hitFraction","_Registered$Z","BlackAndWhitePostProcess","PostProcessRenderEffect","getPostProcesses","singleInstance","_singleInstance","_getPostProcesses","_cameras","_indicesForCamera","pps","_attachCameras","cams","cameraName","_detachCameras","detachPostProcess","_disable","_inputPostProcess","_Registered$Y","ExtractHighlightsPostProcess","originalFromInput","blurred","_Registered$X","BloomMergePostProcess","BloomEffect","_thinBloomEffect","bloomWeight","bloomKernel","pipelineTextureType","disposeEffects","effectIndex","_updateEffects","_get_centerPosition_decorators","_get_screenWidth_decorators","_get_screenHeight_decorators","_Registered$W","ChromaticAberrationPostProcess","_Registered$V","CircleOfConfusionPostProcess","_Registered$U","ColorCorrectionPostProcess","_Registered$T","ConvolutionPostProcess","DepthOfFieldBlurPostProcess","imageToBlur","circleOfConfusion","_Registered$S","DepthOfFieldMergePostProcess","_blurSteps","DepthOfFieldEffectBlurLevel","DepthOfFieldEffect","_thinDepthOfFieldEffect","thinBlurY","ratioY","blurY","thinBlurX","ratioX","blurX","DisplayPassPostProcess","displayPass_fragment","displayPass_fragment$1","_Registered$R","_Registered$Q","FilterPostProcess","_Registered$P","GrainPostProcess","HighlightsPostProcess","highlights_fragment","highlights_fragment$1","_get_fromLinearSpace_decorators","_forcedGeometryBuffer","forceGeometryBuffer","_forceGeometryBuffer","MotionBlurConfiguration","excludeSkinnedMesh","removeExcludedSkinnedMesh","_onApplyObjectBased","_onApplyScreenBased","velocityIndex","getRenderTarget","_Registered$O","MotionBlurPostProcess","MeshBlendingPostProcess","_meshBlendTagTexture","_ValidateMeshBlendTagTexture","_ValidateInputTextureDimensions","_validateInputDimensions","_ValidateDepthTexture","_ValidateBaseColorTexture","sceneEngine","_ValidateInputs","ownsEffectWrapper","_ownsEffectWrapper","tagInternalTexture","depthInternalTexture","baseColorInternalTexture","inputSamples","_Validate2DTexture","validFormat","validType","tagTexture","renderSamples","_refTexture","_ownRefractionTexture","refractionTextureUrl","colorLevel","_refractionTextureUrl_extraInitializers","_depth_decorators","_colorLevel_decorators","_refractionTextureUrl_decorators","_depth_initializers","_depth_extraInitializers","_colorLevel_initializers","_colorLevel_extraInitializers","_Registered$N","RefractionPostProcess","name$3I","_PostProcessRenderPipelineManagerClass","_Registered$M","SharpenPostProcess","PostProcessRenderPipelineManagerSceneComponent","_postProcessRenderPipelineManager","_Registered$L","pipelineManagerClass","PostProcessRenderPipelineManager","_renderPipelines","_onNewPipelineAddedObservable","_onPipelineRemovedObservable","RegisterPostProcessRenderPipelineManagerSceneComponent","onNewPipelineAddedObservable","onPipelineRemovedObservable","renderPipelineName","addPipeline","renderPipeline","removePipeline","unique","renderEffectName","_enableEffect","_disableEffect","__name_initializers","__name_extraInitializers","_renderEffectsForIsolatedPass","renderEffects","indicesToDelete","effectKeys","effectKey","__name_decorators","automaticBuild","_buildAllowed","sharpenEnabled","_sharpenEnabled","_buildPipeline","_bloomKernel","_hardwareScaleLevel","_bloomWeight","bloomThreshold","_bloomThreshold","_bloomScale","_rebuildBloom","bloomEnabled","_bloomEnabled","oldBloom","depthOfFieldEnabled","_depthOfFieldEnabled","depthOfFieldBlurLevel","_depthOfFieldBlurLevel","oldDof","fxaaEnabled","_fxaaEnabled","imageProcessingEnabled","_imageProcessingEnabled","glowLayerEnabled","_glowLayer","glowLayer","chromaticAberrationEnabled","_chromaticAberrationEnabled","grainEnabled","_grainEnabled","_camerasToBeAttached","SharpenPostProcessId","ImageProcessingPostProcessId","FxaaPostProcessId","ChromaticAberrationPostProcessId","GrainPostProcessId","__bloomWeight_initializers","__bloomWeight_extraInitializers","__bloomThreshold_initializers","_hdr","__bloomThreshold_extraInitializers","__hdr_initializers","__hdr_extraInitializers","_hasCleared","_prevPostProcess","_prevPrevPostProcess","_depthOfFieldSceneObserver","_activeCameraChangedObserver","_activeCamerasChangedObserver","sharpen","_sharpenEffect","chromaticAberration","_chromaticAberrationEffect","grain","_grainEffect","avoidReentrancyAtConstructionTime","_imageProcessingConfigurationObserver","_setAutoClearAndTextureSharing","skipTextureSharing","shareOutputWith","useOwnOutput","addEffect","imageProcessing","ImageProcessingPostProcess","fxaa","attachCamerasToRenderPipeline","_adaptPostProcessesToViewPort","_enableMSAAOnFirstPostProcess","disposeNonRecreated","detachCamerasFromRenderPipeline","_get_sharpenEnabled_decorators","_get_bloomKernel_decorators","__bloomWeight_decorators","__bloomThreshold_decorators","__hdr_decorators","_get_bloomWeight_decorators","_get_bloomThreshold_decorators","_get_bloomEnabled_decorators","_get_depthOfFieldEnabled_decorators","_get_depthOfFieldBlurLevel_decorators","_get_fxaaEnabled_decorators","_get_imageProcessingEnabled_decorators","_get_glowLayerEnabled_decorators","_get_chromaticAberrationEnabled_decorators","_get_grainEnabled_decorators","_Registered$K","DefaultRenderingPipelineParse","DefaultRenderingPipeline","LensRenderingPipeline","PostProcessRenderPipeline","LensChromaticAberrationEffect","HighlightsEnhancingEffect","LensDepthOfFieldEffect","_pentagonBokehIsEnabled","grain_texture","_grainTexture","_createGrainTexture","_edgeBlur","edge_blur","_grainAmount","grain_amount","_chromaticAberration","chromatic_aberration","_distortion","distortion","_highlightsGain","dof_gain","_highlightsThreshold","dof_threshold","_dofDistance","dof_focus_distance","_dofAperture","dof_aperture","_dofDarken","dof_darken","_dofPentagon","dof_pentagon","_createChromaticAberrationPostProcess","_createHighlightsPostProcess","_chromaticAberrationPostProcess","_highlightsPostProcess","_depthOfFieldPostProcess","edgeBlur","setEdgeBlur","grainAmount","setGrainAmount","setChromaticAberration","dofAperture","setAperture","edgeDistortion","setEdgeDistortion","dofDistortion","setFocusDistance","darkenOutOfFocus","setDarkenOutOfFocus","blurNoise","_blurNoise","pentagonBokeh","enablePentagonBokeh","disablePentagonBokeh","highlightsGain","setHighlightsGain","highlightsThreshold","setHighlightsThreshold","disableEdgeBlur","disableGrain","disableChromaticAberration","disableEdgeDistortion","disableDepthOfField","enableNoiseBlur","disableNoiseBlur","disableHighlights","disableDepthRender","sourceWidth","name$3H","shader$3H","name$3G","name$3F","PrePassRenderTarget","_beforeCompositionPostProcesses","_internalTextureDirty","_createCompositionEffect","imageProcessingPostProcess","_resetPostProcessChain","_outputPostProcess","PrePassRendererSceneComponent","_setRenderTarget","_beforeDraw","_afterDraw","_beforeCameraDraw","_afterCameraDraw","bindAttachmentsForEffect","restoreAttachments","_Registered$J","prePassRendererClass","PrePassRenderer","_generateNormalsInWorldSpace","_markAllMaterialsAsPrePassDirty","_textureIndices","_useSpecificClearForDepthTexture","prePassRenderTarget","_refreshGeometryBufferRendererLink","doNotUseGeometryRendererFallback","_geometryBuffer","_linkPrePassRenderer","excludedMaterials","_mrtTypes","_mrtLayout","_mrtNames","_effectConfigurations","_geometryBufferRenderList","_needsCompositionForThisPass","_postProcessesSourceForThisPass","_postProcessChainForThisPass","_postProcessesForUpdate","disableGammaTransform","TextureFormats","RegisterPrePassRendererSceneComponent","excluded","_multiRenderAttachments","multiRenderLayout","clearLayout","clearDepthLayout","defaultLayout","_clearAttachments","_clearDepthAttachments","purpose","texturesActivated","_linkInternalTexture","prePassConstant","geometryBufferConstant","_setupOutputForThisPass","postProcessChain","_renderPostProcesses","_checkSize","_setEnabled","_setRenderTargetEnabled","_unlinkInternalTexture","previousMrtCount","_enableTextures","_reinitializeAttachments","_updateGeometryBufferLayout","secondaryCamera","postProcessesSource","_getPostProcessesSource","cameraHasImageProcessing","_hasImageProcessing","_needsImageProcessing","firstCameraPP","firstPrePassPP","isIPPAlreadyPresent","enablePrePass","_thinSSAORenderingPipeline","_textureSamples","_originalColorPostProcess","SSAOOriginalSceneColorEffect","SSAORenderEffect","SSAOBlurHRenderEffect","SSAOBlurVRenderEffect","SSAOCombineRenderEffect","__textureSamples_initializers","__textureSamples_extraInitializers","__forceGeometryBuffer_initializers","__forceGeometryBuffer_extraInitializers","__ratio_initializers","__ratio_extraInitializers","__textureType_initializers","__textureType_extraInitializers","ssaoRatio","_syncNormalsInWorldSpace","_createSSAOPostProcess","_createBlurPostProcess","_blurHPostProcess","_blurVPostProcess","_createBlurFilter","blurFilter","ssaoCombineSize","originalColorSize","SSAO2Configuration","__textureSamples_decorators","__forceGeometryBuffer_decorators","__ratio_decorators","__textureType_decorators","_set_expensiveBlur_decorators","_set_epsilon_decorators","_set_samples_decorators","_set_bypassBlur_decorators","_Registered$I","SSAO2RenderingPipelineParse","SSAO2RenderingPipeline","_totalStrength_initializers","_totalStrength_extraInitializers","fallOff","_fallOff_initializers","_base_initializers","_base_extraInitializers","combineRatio","sampleSphere","_createSSAOCombinePostProcess","_totalStrength_decorators","_base_decorators","name$3E","name$3D","shader$3D","_threshold_initializers","_threshold_extraInitializers","_strength_initializers","_strength_extraInitializers","_reflectionSpecularFalloffExponent_initializers","_reflectionSpecularFalloffExponent_extraInitializers","_step_initializers","_step_extraInitializers","_roughnessFactor_initializers","_roughnessFactor_extraInitializers","_reflectionSamples","_smoothSteps","ScreenSpaceReflectionsConfiguration","roughnessIndex","normalIndex","_isSceneRightHanded","reflectionSamples","smoothSteps","_threshold_decorators","_strength_decorators","_reflectionSpecularFalloffExponent_decorators","_step_decorators","_roughnessFactor_decorators","_get_reflectionSamples_decorators","_get_smoothSteps_decorators","_Registered$H","ScreenSpaceReflectionPostProcess","_fixedExposure","_currentExposure","hdrAutoExposure","_hdrAutoExposure","hdrPostProcess","_motionStrength","_isObjectBasedMotionBlur","motionBlurPostProcess","objectBasedMotionBlur","shouldRebuild","BloomEnabled","DepthOfFieldEnabled","LensFlareEnabled","_lensFlareEnabled","HDREnabled","_hdrEnabled","VLSEnabled","_vlsEnabled","MotionBlurEnabled","_motionBlurEnabled","screenSpaceReflectionsEnabled","_screenSpaceReflectionsEnabled","volumetricLightStepsCount","_volumetricLightStepsCount","volumetricLightPostProcess","originalPostProcess","downSampleX4PostProcess","brightPassPostProcess","blurHPostProcesses","blurVPostProcesses","textureAdderPostProcess","volumetricLightSmoothXPostProcess","volumetricLightSmoothYPostProcess","volumetricLightMergePostProces","volumetricLightFinalPostProcess","luminancePostProcess","luminanceDownSamplePostProcesses","textureAdderFinalPostProcess","lensFlareFinalPostProcess","hdrFinalPostProcess","lensFlarePostProcess","lensFlareComposePostProcess","depthOfFieldPostProcess","brightThreshold","_brightThreshold_initializers","blurWidth","_brightThreshold_extraInitializers","_blurWidth_initializers","horizontalBlur","_blurWidth_extraInitializers","_horizontalBlur_initializers","lensTexture","_horizontalBlur_extraInitializers","_lensTexture_initializers","volumetricLightCoefficient","_lensTexture_extraInitializers","_volumetricLightCoefficient_initializers","volumetricLightPower","_volumetricLightCoefficient_extraInitializers","_volumetricLightPower_initializers","volumetricLightBlurScale","_volumetricLightPower_extraInitializers","_volumetricLightBlurScale_initializers","sourceLight","_volumetricLightBlurScale_extraInitializers","hdrMinimumLuminance","_hdrMinimumLuminance_initializers","hdrDecreaseRate","_hdrMinimumLuminance_extraInitializers","_hdrDecreaseRate_initializers","hdrIncreaseRate","_hdrDecreaseRate_extraInitializers","_hdrIncreaseRate_initializers","lensColorTexture","_hdrIncreaseRate_extraInitializers","_lensColorTexture_initializers","lensFlareStrength","_lensColorTexture_extraInitializers","_lensFlareStrength_initializers","lensFlareGhostDispersal","_lensFlareStrength_extraInitializers","_lensFlareGhostDispersal_initializers","lensFlareHaloWidth","_lensFlareGhostDispersal_extraInitializers","_lensFlareHaloWidth_initializers","lensFlareDistortionStrength","_lensFlareHaloWidth_extraInitializers","_lensFlareDistortionStrength_initializers","lensFlareBlurWidth","_lensFlareDistortionStrength_extraInitializers","_lensFlareBlurWidth_initializers","lensStarTexture","_lensFlareBlurWidth_extraInitializers","_lensStarTexture_initializers","lensFlareDirtTexture","_lensStarTexture_extraInitializers","_lensFlareDirtTexture_initializers","depthOfFieldDistance","_lensFlareDirtTexture_extraInitializers","_depthOfFieldDistance_initializers","depthOfFieldBlurWidth","_depthOfFieldDistance_extraInitializers","_depthOfFieldBlurWidth_initializers","_depthOfFieldBlurWidth_extraInitializers","_currentDepthOfFieldSource","_hdrCurrentLuminance","_basePostProcess","screenSpaceReflectionPostProcess","_floatTextureType","_createDepthOfFieldPostProcess","_createMotionBlurPostProcess","_createDownSampleX4PostProcess","downSampleX4Offsets","_createBrightPassPostProcess","brightOffsets","sU","sV","_createBlurPostProcesses","indice","blurWidthKey","_createTextureAdderPostProcess","_createVolumetricLightPostProcess","geometryRenderer","LuminanceSteps","downSampleOffsets","lastLuminance","bit_shift","_createHdrPostProcess","outputLiminance","lastTime","scaleBias1","scaleBias2","camerax","cameraz","camRot","starRotation","lensStarMatrix","_getDepthTexture","motionScale","invViewProjection","prevViewProjection","sourceLightId","_brightThreshold_decorators","_blurWidth_decorators","_horizontalBlur_decorators","_lensTexture_decorators","_volumetricLightCoefficient_decorators","_volumetricLightPower_decorators","_volumetricLightBlurScale_decorators","_hdrMinimumLuminance_decorators","_hdrDecreaseRate_decorators","_hdrIncreaseRate_decorators","_lensColorTexture_decorators","_lensFlareStrength_decorators","_lensFlareGhostDispersal_decorators","_lensFlareHaloWidth_decorators","_lensFlareDistortionStrength_decorators","_lensFlareDirtTexture_decorators","_depthOfFieldDistance_decorators","_depthOfFieldBlurWidth_decorators","_get_objectBasedMotionBlur_decorators","_get_BloomEnabled_decorators","_get_DepthOfFieldEnabled_decorators","_get_LensFlareEnabled_decorators","_get_HDREnabled_decorators","_get_VLSEnabled_decorators","_get_MotionBlurEnabled_decorators","_get_screenSpaceReflectionsEnabled_decorators","_get_volumetricLightStepsCount_decorators","_get_hdrAutoExposure_decorators","_lensFlareBlurWidth_decorators","_lensStarTexture_decorators","_Registered$G","StandardRenderingPipelineParse","StandardRenderingPipeline","name$3C","includes$1d","ScreenSpaceReflections2Configuration","_thinSSRRenderingPipeline","currentThreshold","downsample","currentStrength","backfaceDepthRenderer","backfaceDepthTextureDownsample","_backfaceDepthTextureDownsample","_resizeDepthRenderer","backfaceForceDepthWriteTransparentMeshes","_backfaceForceDepthWriteTransparentMeshes","SSRRenderEffect","SSRBlurRenderEffect","SSRCombineRenderEffect","__backfaceDepthTextureDownsample_initializers","__backfaceDepthTextureDownsample_extraInitializers","__backfaceForceDepthWriteTransparentMeshes_extraInitializers","_createSSRPostProcess","_disposeDepthRenderer","_disposeSSRPostProcess","_depthRendererCamera","_createBlurAndCombinerPostProcesses","_blurPostProcessX","_blurPostProcessY","_blurCombinerPostProcess","depthRendererSize","_get_environmentTexture_decorators","_get_environmentTextureIsProbe_decorators","__backfaceDepthTextureDownsample_decorators","__backfaceForceDepthWriteTransparentMeshes_decorators","__backfaceForceDepthWriteTransparentMeshes_initializers","_Registered$F","SSRRenderingPipelineParse","SSRRenderingPipeline","_taaThinPostProcess","msaaSamples","_msaaSamples","_taaPostProcess","_updateReprojection","TAARenderEffect","TAAPassEffect","__msaaSamples_initializers","__msaaSamples_extraInitializers","_pingpong","_createPingPongTextures","_ping","_pong","_createTAAPostProcess","_createPassPostProcess","_passPostProcess","TAAEffectConfiguration","__msaaSamples_decorators","_Registered$E","TAARenderingPipelineParse","TAARenderingPipeline","ThinFSR1UpscalePostProcess","fsr1Upscale_fragment","fsr1Upscale_fragment$1","rcpInputWidth","rcpInputHeight","rcpOutputWidth","rcpOutputHeight","ThinFSR1SharpenPostProcess","fsr1Sharpen_fragment","fsr1Sharpen_fragment$1","FSR1RenderingPipeline","_upscalePostProcess","sharpnessStops","_sharpnessStops","stops","SCALE_QUALITY","FSR1UpscaleEffect","FSR1SharpenEffect","_thinUpscalePostProcess","_thinSharpenPostProcess","_createSharpenPostProcess","_disposeUpscalePostProcess","_createUpscalePostProcess","_disposeSharpenPostProcess","updateConstants","_sharpenPostProcess","SCALE_ULTRA_QUALITY","SCALE_BALANCED","name$3B","shader$3B","name$3A","shader$3A","name$3z","shader$3z","name$3y","shader$3y","name$3x","shader$3x","includes$1c","screenSpaceRayTrace","name$3w","shader$3w","name$3v","shader$3v","includes$1b","name$3u","shader$3u","name$3t","shader$3t","includes$1a","screenSpaceRayTraceWGSL","name$3s","shader$3s","name$3r","shader$3r","includes$19","name$3q","shader$3q","name$3p","shader$3p","name$3o","shader$3o","name$3n","shader$3n","includes$18","name$3m","shader$3m","includes$17","name$3l","shader$3l","name$3k","shader$3k","includes$16","name$3j","shader$3j","includes$15","name$3i","shader$3i","name$3h","cameraIsCamera","_Registered$D","TonemapPostProcess","useDiffuseColor","selectedEngine","postProcessRatio","_screenCoordinates","customMeshPosition","_customMeshPosition_initializers","useCustomMeshPosition","_customMeshPosition_extraInitializers","_useCustomMeshPosition_initializers","_useCustomMeshPosition_extraInitializers","_invert_initializers","_invert_extraInitializers","_mesh_initializers","_mesh_extraInitializers","_excludedMeshes_initializers","_excludedMeshes_extraInitializers","_includedMeshes_initializers","_includedMeshes_extraInitializers","_exposure_initializers","_exposure_extraInitializers","_decay_initializers","_decay_extraInitializers","_weight_initializers","_density_extraInitializers","_createPass","passRatio","_updateMeshScreenCoordinates","_volumetricLightScatteringRTT","volumetricLightScattering_fragment","volumetricLightScatteringPass_vertex","volumetricLightScatteringPass_fragment","volumetricLightScattering_fragment$1","volumetricLightScatteringPass_vertex$1","volumetricLightScatteringPass_fragment$1","setCustomMeshPosition","rttIndex","_meshExcluded","savedSceneClearColor","sceneClearColor","_viewPort","CreateDefaultMesh","_customMeshPosition_decorators","_useCustomMeshPosition_decorators","_invert_decorators","_mesh_decorators","_excludedMeshes_decorators","_includedMeshes_decorators","_exposure_decorators","_decay_decorators","_weight_decorators","_density_decorators","_weight_extraInitializers","_Registered$C","VolumetricLightScatteringPostProcess","name$3g","shader$3g","name$3f","shader$3f","includes$14","pointCloudVertexDeclaration","name$3e","shader$3e","name$3d","shader$3d","includes$13","name$3c","shader$3c","name$3b","shader$3b","name$3a","shader$3a","includes$12","name$39","shader$39","name$38","name$37","_Registered$B","ScreenSpaceCurvaturePostProcess","name$36","shader$36","shader$35","name$35","name$34","shader$34","name$33","shader$33","name$32","shader$32","includes$11","packingFunctions$1","kernelBlurFragment","kernelBlurFragment2","shader$31","name$31","name$30","shader$30","includes$10","kernelBlurVertex","shader$2$","name$2$","name$2_","shader$2_","name$2Z","shader$2Z","name$2Y","shader$2Y","includes$$","packingFunctionsWGSL","kernelBlurFragmentWGSL","kernelBlurFragment2WGSL","shader$2X","name$2X","name$2W","shader$2W","includes$_","kernelBlurVertexWGSL","name$2V","shader$2V","name$2U","shader$2U","name$2T","shader$2T","name$2S","shader$2S","name$2R","shader$2R","name$2Q","shader$2Q","name$2P","shader$2P","includes$Z","name$2O","shader$2O","includes$Y","name$2N","shader$2N","name$2M","shader$2M","includes$X","name$2L","shader$2L","includes$W","name$2K","shader$2K","name$2J","shader$2J","name$2I","shader$2I","name$2H","shader$2H","name$2G","shader$2G","name$2F","shader$2F","name$2E","shader$2E","name$2D","shader$2D","includes$V","name$2C","shader$2C","includes$U","name$2B","shader$2B","name$2A","shader$2A","name$2z","shader$2z","name$2y","shader$2y","name$2x","shader$2x","name$2w","shader$2w","name$2v","shader$2v","name$2u","shader$2u","name$2t","shader$2t","name$2s","shader$2s","name$2r","shader$2r","name$2q","shader$2q","name$2p","shader$2p","name$2o","shader$2o","name$2n","shader$2n","name$2m","shader$2m","name$2l","shader$2l","name$2k","shader$2k","name$2j","shader$2j","name$2i","shader$2i","name$2h","shader$2h","name$2g","shader$2g","TempMatrix","TempMatrix2","TempVec1","TempVec2","TempMatrixArray","DummyBoundingBox","BoundingBoxRenderer","frontColor","backColor","showBackLines","onBeforeBoxRenderingObservable","onAfterBoxRenderingObservable","onResourcesReadyObservable","_fillIndexBuffer","_fillIndexData","_matrixBuffer","_uniformBufferFront","_uniformBufferBack","_colorShader","_tag","_prepareResources","boundingBoxRenderer_vertex","boundingBoxRenderer_fragment","boundingBoxRenderer_vertex$1","boundingBoxRenderer_fragment$1","_colorShaderForOcclusionQuery","boxdata","_renderInstanced","boundingBoxIndex","_createWrappersForBoundingBox","median","drawWrapperBack","drawWrapperFront","_renderPassIdForOcclusionQuery","_cleanupInstances","colorShader","_createInstanceBuffer","_cleanupInstanceBuffer","_Registered$A","_forceShowBoundingBoxes","_boundingBoxRenderer","_showBoundingBox","name$2f","shader$2f","includes$T","name$2e","shader$2e","includes$S","name$2d","shader$2d","includes$R","_DepthPeelingRendererClass","DepthPeelingSceneComponent","_Registered$z","RegisterDepthPeelingSceneComponent","depthPeelingRendererClass","DepthPeelingRenderer","DepthPeelingEffectConfiguration","_outputRT","_blendBackTexture","setCustomOutput","edgesConnectedCount","linesPositions","_linesPositions","linesNormals","_linesNormals","_linesIndices","lineShader","_lineShader","_edgeRenderLineShader","line_vertex","line_fragment","line_vertex$1","line_fragment$1","edgesWidthScalerForOrthographic","edgesWidthScalerForPerspective","_buffersForInstances","_checkVerticesInsteadOfIndices","generateEdgesLines","useAlternateEdgeFinder","_generateEdgesLinesAlternate","_generateEdgesLines","_meshRebuildObserver","_meshDisposeObserver","EdgesRenderer","_ib","_checkEdge","needToCreateLine","createLine","remapVertexIndices","makePointList","edgePoints","pointIndices","startEdge","mainPointIndices","otherPointIndices","numMainPoints","indexTriangle","numOtherPoints","bucketIsMain","bucketStep","bucketLimit","bucketIdxLimit","winding","numTris","bucketIdx","bucketPoints","nbucketPoints","nbucketIdx","useFastVertexMerger","epsVertexMerge","epsilonVertexMerge","mapVertices","applyTessellation","epsVertexAligned","epsilonVertexAligned","mustTesselate","triangleToTessellate","p0Index","p1Index","p2Index","p0x","p0y","p0z","p1x","p1y","p1z","p0p1","p0p","pp1","edgesPoints","_tessellateTriangle","removeDegeneratedTriangles","ei","_indicesCount","adjacencies","faceAdjacencies","FaceAdjacencies","otherIndex","otherFaceAdjacencies","otherP0","otherP1","otherP2","otherEdgeIndex","_processEdgeForAdjacenciesWithVertices","_processEdgeForAdjacencies","currentDrawWrapper","useBuffersWithInstances","instanceMatrix","instanceM","LineEdgesRenderer","_Registered$y","_IblShadowsVoxelTracingPass","_voxelShadowOpacity","_ssShadowOpacity","sssSamples","_sssSamples","sssStride","_sssStride","_sssMaxDist","_sssThickness","_voxelNormalBias","_voxelDirectionBias","_envRotation","_debugPassPP","_maxVoxelRouletteTests","maxVoxelRouletteTests","iblShadowDebug_fragment","iblShadowDebug_fragment$1","_debugVoxelMarchEnabled","_renderWhenGBufferReady","_renderPipeline","_createDefines","_setBindings","_getVoxelGridTexture","_getNoiseTexture","wnormalIndex","_IblShadowsSpatialBlurPass","setWorldScale","_worldScale","_getVoxelTracingTexture","_IblShadowsAccumulationPass","_oldAccumulationCopy","_oldPositionCopy","_isMoving","_setOutputTextureBindings","accumulationOptions","_setAccumulationCopyBindings","localPositionOptions","_updatePositionCopy","_getSpatialBlurTexture","_dummyTexture2d","wPositionIndex","IblShadowsRenderPipeline","_accumulationPass","_setPluginParameters","_voxelTracingPass","shadowRenderSizeFactor","_renderSizeFactor","_spatialBlurPass","_sssMaxDistScale","_updateSsShadowParams","_sssThicknessScale","_dummyTexture3d","getOutputTexture","gbufferDebugEnabled","_gbufferDebugEnabled","_getGBufferDebugPass","cdfDebugEnabled","voxelTracingDebugEnabled","spatialBlurPassDebugEnabled","accumulationPassDebugEnabled","_shadowCastingMeshes","clearShadowCastingMeshes","newResolution","allowDebugPasses","_allowDebugPasses","_createDebugPasses","_disposeDebugPasses","toggleShadow","centre","_debugPasses","onShadowTextureReadyObservable","onNewIblReadyObservable","_gBufferDebugSizeParams","ssShadowsEnabled","_listenForCameraChanges","_updateBeforeRender","_handleResize","_gbufferDebugPass","iblShadowGBufferDebug_fragment","iblShadowGBufferDebug_fragment$1","_disposeEffectPasses","_addShadowSupportToMaterial","_updateDebugPasses","removeShadowReceivingMaterial","SubSurfaceSceneComponent","clearAllDiffusionProfiles","_Registered$x","subSurfaceConfigClass","_subSurfaceConfiguration","SubSurfaceScatteringPostProcess","subSurfaceScattering_fragment$1","subSurfaceScattering_fragment","metersPerUnit","ssDiffusionS","ssDiffusionD","ssFilterRadii","SubSurfaceConfiguration","_ssDiffusionS","_ssDiffusionD","_ssFilterRadii","RegisterSubSurfaceSceneComponent","getDiffusionProfileParameters","maxScatteringDistance","_sampleBurleyDiffusionProfile","rcpS","OutlineRenderer","_passIdForDrawWrapper","_afterRenderingMesh","useOverlay","outlineWidth","outline_fragment","outline_vertex","outline_fragment$1","outline_vertex$1","renderOutline","_savedDepthWrite","_StencilReference","currentMode","alphaBlendState","_Registered$w","_outlineRenderer","_renderOutline","_renderOverlay","particleSize","_particleSize","onParticleSizeChanged","useVelocity","_useVelocity","_hasVelocity","_effectsAreDirty","particleThicknessAlpha","_depthEffectWrapper","_thicknessEffectWrapper","_supportsPerParticleSizeAttribute","_getPerParticleSizeAttributeSize","_usesCenteredOffsetAttribute","perParticleSize","FluidRenderingObject","UsePerParticleSizeAttribute","baseAttributeNames","baseUniformNames","depthAttributeNames","fluidRenderingParticleDepth_vertex","fluidRenderingParticleDepth_fragment","fluidRenderingParticleDepth_vertex$1","fluidRenderingParticleDepth_fragment$1","fluidRenderingParticleThickness_vertex","fluidRenderingParticleThickness_fragment","fluidRenderingParticleThickness_vertex$1","fluidRenderingParticleThickness_fragment$1","depthEffect","thicknessEffect","renderDepthTexture","numParticles","depthDrawWrapper","_usesPerParticleSizeAttribute","renderThicknessTexture","thicknessDrawWrapper","_particleSystem","useTrueRenderingForDiffuseTexture","_useTrueRenderingForDiffuseTexture","_blendMode","_onBeforeDrawParticleObserver","_originalRender","_updateInAnimate","_isGPUParticleSystem","FluidRenderingTextures","blurNumIterations","_blurNumIterations","numIterations","_rt","renderTargetBlur","_rtBlur","textureBlur","_textureBlurred","blurTextureSizeX","blurTextureSizeY","blurTextureFormat","useStandardBlur","enableBlur","blurSizeDivisor","blurFilterSize","blurMaxFilterSize","blurDepthScale","_blurTextureSizeX","_blurTextureSizeY","_blurTextureType","_blurTextureFormat","_useStandardBlur","_postProcessRunningIndex","rtBlur","textureBlurred","blurPostProcesses","textureBlurSource","debugName","useBilinearFiltering","fluidRenderingStandardBlur_fragment","fluidRenderingStandardBlur_fragment$1","kernelBlurXPostprocess","_fixReusablePostProcess","kernelBlurYPostprocess","blurList","fluidRenderingBilateralBlur_fragment","fluidRenderingBilateralBlur_fragment$1","_getProjectedParticleConstant","_getDepthThreshold","FluidRenderingDebug","FluidRenderingTargetRenderer","needInitialization","_needInitialization","generateDiffuseTexture","_generateDiffuseTexture","generate","debugFeature","_debugFeature","environmentMap","_environmentMap","enableBlurDepth","_enableBlurDepth","blurDepthSizeDivisor","_blurDepthSizeDivisor","blurDepthFilterSize","_blurDepthFilterSize","filterSize","_setBlurParameters","blurDepthNumIterations","_blurDepthNumIterations","blurDepthMaxFilterSize","_blurDepthMaxFilterSize","maxFilterSize","blurDepthDepthScale","_blurDepthDepthScale","enableBlurThickness","_enableBlurThickness","blurThicknessSizeDivisor","_blurThicknessSizeDivisor","blurThicknessFilterSize","_blurThicknessFilterSize","blurThicknessNumIterations","_blurThicknessNumIterations","useFixedThickness","_useFixedThickness","_onUseVelocityChanged","depthMapSize","_depthMapSize","thicknessMapSize","_thicknessMapSize","diffuseMapSize","_diffuseMapSize","compositeMode","_compositeMode","fluidColor","refractionStrength","fresnelClamp","dirLight","_bgDepthTexture","_invProjectionMatrix","_depthClearColor","_thicknessClearColor","_depthRenderTarget","_diffuseRenderTarget","_thicknessRenderTarget","_renderPostProcess","depthWidth","depthHeight","_initializeRenderTarget","diffuseWidth","diffuseHeight","thicknessWidth","thicknessHeight","_createLiquidRenderingPostProcess","_setBlurDepthParameters","_setBlurThicknessParameters","fluidRenderingRender_fragment","fluidRenderingRender_fragment$1","envMap","fluidObject","renderDiffuseTexture","applyBlurPostProcesses","onlyPostProcesses","FluidRenderingObjectCustomParticles","_numParticles","_diffuseEffectWrapper","addBuffers","fluidRenderingParticleDiffuse_fragment","fluidRenderingParticleDiffuse_fragment$1","setNumParticles","diffuseDrawWrapper","diffuseEffect","FluidRenderingDepthTextureCopy","depthRTWrapper","_depthRTWrapper","_copyTextureToTexture","IsParticleSystemObject","IsCustomParticlesObject","FluidRendererSceneComponent","fluidRenderer","renderObjects","vbuffers","_onEngineResizeObserver","targetRenderers","FluidRenderer","_sortRenderingObjects","_getParticleSystemIndex","FluidRenderingObjectParticleSystem","_setParticleSizeForRenderTargets","targetRenderer","_setUseVelocityForRenderObject","renderObject","addCustomParticles","removeUnusedTargetRenderer","_removeUnusedTargetRenderers","newList","copyDepthTextures","thicknessRT","copyDepthTexture","list2","particleSizes","renderingObject","curSize","forCamera","_clearTargets","sourceCopyDepth","_Registered$v","_fluidRenderer","name$2c","shader$2c","name$2b","shader$2b","name$2a","shader$2a","shader$29","name$29","name$28","shader$28","shader$27","name$27","name$26","shader$26","name$25","shader$25","name$24","shader$24","name$23","shader$23","name$22","shader$22","name$21","shader$21","name$20","shader$20","name$1$","shader$1$","name$1_","shader$1_","name$1Z","shader$1Z","name$1Y","shader$1Y","name$1X","shader$1X","ReflectiveShadowMap","_customRenderTarget","positionWorldTexture","_mrt","normalWorldTexture","fluxTexture","textureDimensions","_lightTransformMatrix","forceUpdateLightParameters","_textureDimensions","_regularMatToMatWithPlugin","_createMultiRenderTarget","_recomputeLightTransformationMatrix","_disposeMultiRenderTarget","_addMeshToMRT","lightTransformationMatrix","updateLightParameters","countersGPU","fluxTextureType","fluxTextureFormat","sceneUBO","currentSceneUBO","useUBO","rsmMaterial","rsmCreatePlugin","RSMCreatePluginMaterial","RSMCREATE","RSMCREATE_PROJTEXTURE","RSMCREATE_LIGHT_IS_SPOT","_RSMCreatePluginMaterial_isEnabled_accessor_storage","MaterialRSMCreateDefines","_lightColor","_hasProjectionTexture","_light_initializers","_light_extraInitializers","_varAlbedoName","isSpot","spot","_light_decorators","_Registered$u","GIRSM","rsm","edgeArtifactCorrection","rotateSample","noiseFactor","useFullTexture","GIRSMManager","_giRSM","GIRSMRenderPluginMaterial","recreateResources","_enableBlur","useQualityBlur","_useQualityBlur","fullSizeBlur","_forceFullSizeBlur","useQualityUpsampling","_useQualityUpsampling","showOnlyGI","_showOnlyGI","use32BitsDepthBuffer","_use32BitsDepthBuffer","setOutputDimensions","_outputDimensions","setGITextureDimensions","_giTextureDimensions","giTextureType","_giTextureType","giRSM","addGIRSM","removeGIRSM","_addGISupportToMaterial","disposeGeometryBufferRenderer","_createPostProcesses","_onShaderLoadedObservable","_sampleTexture","_maxSamples","xi1","xi2","_drawPhaseObserver","outputDimensions","giTextureDimensions","_blurRTT","_blurXPostprocess","_blurYPostprocess","_upsamplingXPostprocess","_upsamplingYPostprocess","_ppGlobalIllumination","_firstActivation","_geomBufferEnabled","_geomBufferEnablePosition","_tempMatrix","blurDepthThreshold","blurNormalThreshold","upsamplerKernel","generateSampleTexture","rebindCurrentRenderTarget","rtws","_countersRTW","bilateralBlur_fragment","bilateralBlurQuality_fragment","rsmGlobalIllumination_fragment","rsmFullGlobalIllumination_fragment","bilateralBlur_fragment$1","bilateralBlurQuality_fragment$1","rsmGlobalIllumination_fragment$1","rsmFullGlobalIllumination_fragment$1","ppGlobalIllumination","textureGIContrib","GeometryBufferTextureTypesAndFormats","decodeGeometryBufferNormals","blurTextureSize","blurRTWs","upsamplingRTWs","RENDER_WITH_GIRSM","_GIRSMRenderPluginMaterial_isEnabled_accessor_storage","MaterialGIRSMRenderDefines","_textureGIContrib_initializers","_textureGIContrib_extraInitializers","_isPBR","_textureGIContrib_decorators","_Registered$t","name$1W","shader$1W","name$1V","shader$1V","name$1U","shader$1U","name$1T","shader$1T","name$1S","shader$1S","name$1R","shader$1R","name$1Q","shader$1Q","name$1P","shader$1P","name$1O","shader$1O","name$1N","shader$1N","includes$Q","mrtFragmentDeclaration","shader$1M","name$1M","shader$1L","name$1L","name$1K","shader$1K","includes$P","geometryVertexDeclaration","geometryUboDeclaration","name$1J","shader$1J","includes$O","name$1I","shader$1I","includes$N","shader$1H","name$1H","name$1G","shader$1G","name$1F","shader$1F","includes$M","boundingBoxRendererUboDeclaration","name$1E","shader$1E","name$1D","shader$1D","includes$L","name$1C","shader$1C","name$1B","shader$1B","name$1A","shader$1A","includes$K","name$1z","shader$1z","name$1y","shader$1y","name$1x","shader$1x","includes$J","lineUboDeclaration","name$1w","shader$1w","includes$I","name$1v","shader$1v","includes$H","name$1u","shader$1u","includes$G","name$1t","shader$1t","includes$F","name$1s","shader$1s","includes$E","name$1r","shader$1r","includes$D","shader$1q","name$1q","name$1p","shader$1p","name$1o","shader$1o","includes$C","name$1n","shader$1n","includes$B","name$1m","shader$1m","name$1l","shader$1l","name$1k","shader$1k","name$1j","shader$1j","name$1i","shader$1i","name$1h","shader$1h","name$1g","shader$1g","name$1f","shader$1f","name$1e","shader$1e","shader$1d","name$1d","name$1c","shader$1c","name$1b","shader$1b","name$1a","shader$1a","name$19","shader$19","name$18","shader$18","name$17","shader$17","name$16","shader$16","name$15","shader$15","includes$A","name$14","shader$14","includes$z","name$13","shader$13","includes$y","name$12","shader$12","name$11","shader$11","name$10","shader$10","includes$x","name$$","shader$$","includes$w","name$_","shader$_","includes$v","name$Z","shader$Z","includes$u","shader$Y","name$Y","name$X","shader$X","name$W","shader$W","includes$t","name$V","shader$V","includes$s","name$U","shader$U","name$T","shader$T","includes$r","name$S","shader$S","includes$q","name$R","shader$R","name$Q","shader$Q","name$P","shader$P","name$O","shader$O","DeserializeSmartAssetMap","doc","entryObj","IsAbsoluteOrSpecialUrl","ResolveAssetUrl","assetUrl","MakeRelative","File","SMART_ASSET_MANAGER_KEY","_InternalsMap","_OnCreatedObservable","_TextureExtensions","onAssetNotFound","internal","containers","objectToKeyMap","textureKeys","reloadSources","blobUrls","sceneDisposeObserver","GetInternalsMap","blobUrl","DisposeSmartAssetManager","GetOnCreatedObservable","CreateSmartAssetManager","GetSmartAssetManager","RevokeManagedBlobUrl","TrackManagedBlobUrl","existingOptions","GetSmartAssetInternals","UnloadSmartAssetAsync","GetAllSmartAssets","previousUrl","reloadSource","registrationOptions","RegisterSmartAsset","extensionHint","TrackSmartAssetContainerObjects","TrackLoadedSmartAssetContainer","ResolveNotFoundAsync","retryError","LoadSmartAssetSceneFileAsync","scenePromises","texturePromises","IsTextureUrl","IsTextureExtension","textureLoadAsync","LoadSmartAssetTextureAsync","sceneLoadAsync","LoadSmartAssetAsync","existingTextures","CreateAndLoadTextureAsync","freshFile","FindSmartAssetKeyForObject","SerializeSmartAssetManagerMap","registeredUrl","resolvedRootUrl","tools_pure","ReadJsonSourceAsync","LoadAllSmartAssetsAsync","replacementUrl","expectedUrl","GetSmartAssetTextureExtensions","SpriteMapFrameRotationDirection","spriteCount","_output","animationMap","_animationMap","am","_createTileAnimationBuffer","atlasJSON","spriteSheet","stageSize","outputPosition","outputRotation","maxAnimationFrames","baseTile","flipU","colorMultiply","_frameMap","_createFrameBuffer","_tileMaps","_createTileBuffer","frameRotationDirection","shaderString","layerSampleString","tickSave","bindSpriteTexture","getTileID","getMousePosition","pickinfo","sss","ss","_ty","_tx","bt","changeTiles","tile","cellID","_frame","toCell","maps","hiddenElement","encodeURI","loadTileMaps","_lc","name$N","includes$p","name$M","includes$o","SpritePackedManager","name$L","shader$L","includes$n","imageProcessingCompatibility","name$K","shader$K","includes$m","name$J","shader$J","includes$l","imageProcessingCompatibilityWGSL","name$I","shader$I","includes$k","WebXRState","WebXRTrackingState","WebXRHitTestLegacy","_mat","_onSelectEnabled","lastNativeXRHitResults","onHitTestResultObservable","_onHitTestResults","xrResults","hitMatrix","worldParentNode","xrHitResult","transformationMatrix","_onSelect","XRHitTestWithSelectEvent","requestHitTest","xrRay","filterFunction","targetRayPose","targetRay","XRHitTestWithRay","testOnPointerDownOnly","AnchorIdProvider","WebXRAnchorSystem","referenceSpaceForFrameAnchors","_referenceSpaceForFrameAnchors","_lastFrameDetected","_trackedAnchors","_futureAnchors","onAnchorAddedObservable","onAnchorRemovedObservable","onAnchorUpdatedObservable","clearAnchorsOnSessionInit","_rejectPendingPersistentAnchors","_populateTmpTransformation","hitTestResult","createAnchor","nativeAnchor","submitted","xrTransformation","xrAnchor","forceCreateInCurrentFrame","_createAnchorAtTransformationAsync","anchors","isPersistentAnchorSupported","persistentAnchors","restorePersistentAnchor","deletePersistentAnchor","requestPersistentHandle","existingAnchorIndex","_findIndexInAnchorArray","existingAnchor","persistentHandle","restorePersistentAnchorAsync","_removed","futureAnchor","doNotRemoveAnchorsOnSessionEnded","trackedAnchors","trackedAnchorIndex","_updateAnchorWithXRFrame","pendingAnchor","_findFutureAnchor","_setPersistentHandle","anchorSpace","_Registered$s","PlaneIdProvider","WebXRPlaneDetector","_detectedPlanes","onPlaneAddedObservable","onPlaneRemovedObservable","onPlaneUpdatedObservable","doNotRemovePlanesOnSessionEnded","XRPlane","initiateRoomCapture","detectedPlanes","worldInformation","planeIdx","xrPlane","_findIndexInPlaneArray","_updatePlaneWithXRPlane","newPlane","polygonDefinition","internalInit","preferredDetectorOptions","trySetPreferredPlaneDetectorOptions","updateWorldTrackingState","planeDetectionState","semanticLabel","xrPoint","planeSpace","_Registered$r","WebXRBackgroundRemover","onBackgroundStateChangedObservable","_setBackgroundState","ignoreEnvironmentHelper","environmentHelperRemovalFlags","skyBox","backgroundSkybox","backgroundPlane","backgroundHelper","backgroundMeshes","_Registered$q","IWebXRControllerPhysicsOptions","WebXRControllerPhysics","_createPhysicsImpostor","physicsProperties","impostorSize","impostorMesh","controllerMesh","physicsAggregate","isPhysicsV2","_physicsVersion","_attachControllerV2","_attachControllerV1","useControllerMesh","_createPhysicsAggregate","_mapImpostorTypeToShapeType","_delta","_enablePhysicsDebug","addController","enableHeadsetImpostor","_enableHeadsetPhysicsV2","_enableHeadsetPhysicsV1","_headsetMesh","_headsetAggregateV2","_headsetImpostor","getImpostorForController","getPhysicsAggregateForController","getPhysicsBodyForController","getHeadsetPhysicsAggregate","newProperties","_onXRFrameV2","_onXRFrameV1","comparedPosition","_lastXRPose","comparedQuaternion","headsetImpostorParams","_Registered$p","WebXRHitTest","_tmpMat","_tmpPos","_initHitTestSource","offsetRay","XRRay","hitTestOptions","useReferenceSpace","entityTypes","requestHitTestSource","hitTestSource","_xrHitTestSource","autoCloneTransformation","disablePermanentHitTest","enableTransientHitTest","requestHitTestSourceForTransientInput","transientHitTestProfile","hitSource","_transientXrHitTestSource","getHitTestResults","_processWebXRHitTestResult","hitTestResultsPerInputSource","resultsPerInputSource","hitTestResults","isTransient","_Registered$o","WebXRFeaturePointSystem","featurePointCloud","_featurePointCloud","onFeaturePointsAddedObservable","onFeaturePointsUpdatedObservable","featurePointRawData","numberOfFeaturePoints","updatedFeaturePoints","addedFeaturePoints","confidenceValue","_Registered$n","MeshIdProvider","_detectedMeshes","onMeshAddedObservable","onMeshUpdatedObservable","generateMeshes","convertCoordinateSystems","trySetMeshDetectorEnabled","doNotRemoveMeshesOnSessionEnded","detectedMeshes","xrMesh","lastChangedTime","_updateVertexDataWithXRMesh","partialVertexData","trySetPreferredMeshDetectorOptions","meshSpace","generatedMesh","WebXRMeshDetector","_Registered$m","ImageTrackingScoreStatus","WebXRImageTracking","onUntrackableImageFoundObservable","onTrackableImageFoundObservable","onTrackedImageUpdatedObservable","_trackableScoreStatus","NotReceived","_trackedImages","trackedImage","originalBitmap","_originalTrackingRequest","widthInMeters","estimatedRealWorldWidth","trackedImages","getImageTrackingResults","Waiting","_checkScoresAsync","imageTrackedResults","imageObject","realWorldWidth","measuredWidthInMeters","imageSpace","emulated","getTrackedImageScores","imageScores","Received","_Registered$l","WebXRDomOverlay","_domOverlayType","_beforeXRSelectListener","domOverlayState","supressXRSelectEvents","domOverlayType","selectedElement","querySelector","_Registered$k","WebXRControllerMovement","movementDirection","_movementDirection","movementEnabled","_featureContext","movementOrientationFollowsViewerPose","followsPose","movementSpeed","movementThreshold","rotationThreshold","_tmpTranslationDirection","_tmpMovementTranslation","_tempCacheQuaternion","registeredComponents","initController","registration","_currentRegistrationConfigurations","allowedComponentTypes","componentOfType","componentSelectionPredicate","forceHandedness","registeredComponent","registrationConfiguration","axisChangedHandler","_movementState","_xrInput","buttonChangedHandler","customRegistrationConfigurations","REGISTRATIONS","movementOrientationFollowsController","orientationPreferredHandedness","moveX","moveY","rotateX","rotateY","movementState","featureContext","_Registered$j","WebXRLightEstimation","_reflectionCubeMap","_xrLightEstimate","_xrLightProbe","_reflectionCubeMapEnabled","_webGPUReflectionWarningEmitted","_sphericalHarmonics","_cubeMapPollTime","_lightEstimationPollTime","_reflectionCubeMapTextureSize","directionalLight","directionalLightIntensityFactor","onReflectionCubeMapUpdatedObservable","cubeMapPollInterval","graphicsBinding","_getXRWebGLBinding","getReflectionCubeMap","reflectionFormat","disablePreFiltering","_hdrFilter","_updateReflectionCubeMap","createDirectionalLightSource","reflectionCubeMapTexture","xrLightingEstimate","lightColor","lightIntensity","disableCubeMapReflection","preferredReflectionFormat","requestLightProbe","xrLightProbe","setSceneEnvironmentTexture","lightEstimationPollInterval","getLightEstimate","primaryLightIntensity","disableVectorReuse","primaryLightDirection","rhsFactor","updateFromFloatsArray","sphericalHarmonicsCoefficients","_Registered$i","WebXREyeTracking","onEyeTrackingStartedObservable","onEyeTrackingEndedObservable","onEyeTrackingFrameUpdateObservable","_latestEyeSpace","gazeSpace","_gazeRay","_eyeTrackingEndListener","isEyeGazeValid","_Registered$h","CircleBuffer","initializer","_entropy","onFirstStepDetected","posX","posY","_entropyDecayFactor","_entropyThreshold","samePointIdx","_samePointCheckStartIdx","_samePointSquaredDistanceThreshold","apexDistSquared","apexIdx","distSquared","_apexSquaredDistanceThreshold","apex","sumSquaredProjectionDistances","_squaredProjectionDistanceThreshold","forwardVec","axisVec","isApexLeft","leftApex","rightApex","_axisToApexShrinkFactor","_axisToApexExtendFactor","currentStepDirection","WalkingTracker","_leftApex","_rightApex","_axis","_axisLength","_steppingLeft","_maxTPosition","_vitality","onMovement","onFootfall","steppingLeft","_updateTAndVitality","_maxT","priorT","projDistSquared","_vitalityThreshold","deltaT","Walker","_detector","FirstStepDetector","_walker","_movement","_millisecondsSinceLastUpdate","_MillisecondsPerUpdate","movementThisFrame","WebXRWalkingLocomotion","locomotionTarget","_locomotionTarget","_isLocomotionTargetWebXRCamera","_sessionManager","handednessScalar","_Registered$g","WebXRCompositionLayerWrapper","isOpacitySupported","_assertControlSupported","isQualitySupported","isForceMonoPresentationSupported","forceMonoPresentation","createRTTProvider","_originalInternalTexture","_destroyLayerOnDispose","isStatic","isMediaLayer","usesRenderTargetProvider","WebXRSpatialLayerWrapper","usesSessionReferenceSpace","_ownsTransformNode","_currentRotation","DOMPointReadOnly","WebXRMediaLayerWrapper","ownsTransformNode","WebXRNoRenderTargetTextureProvider","_binding","getSubImage","_eye","_xrWebGLBinding","_lastSubImages","onRenderTargetTextureCreatedObservable","_compositionLayer","lastSubImage","eyeIndex","colorTextureWidth","subImage","colorTextureHeight","depthStencilTextureWidth","depthStencilTextureHeight","_getSubImageForEye","_getRenderTargetForSubImage","xrGLBinding","WebXRProjectionLayerRenderTargetTextureProvider","_projectionLayer","_getSubImageForView","DefaultXRProjectionLayerInit","clearOnAccess","WebXRWebGPURenderTargetTextureProvider","_transparentClearColor","_webgpuEngine","wrapWebGPUTexture","GetBabylonDepthFormat","WebXRLayerRenderTargetTexture","_wrapColorTexture","_attachPerEyeClearObserver","lastColorClearedFrameId","isImmersiveAR","updateWrappedWebGPUTexture","WebXRWebGPUCompositionLayerWrapper","WebXRWebGPUCompositionLayerRenderTargetTextureProvider","_xrGPUBinding","_renderTargetTexturesByEye","existingRenderTarget","_updateRenderTargetTextureFromGPUTextures","_createRenderTargetTextureFromGPUTextures","_setViewportForSubImage","WebXRWebGPUProjectionLayerWrapper","xrGPUBinding","WebXRWebGPUProjectionLayerRenderTargetTextureProvider","DefaultXRWebGLLayerInit","_FallbackLayerFactory","_RegisterWebXRFallbackLayerFactory","_existingLayers","_fallbackLayers","_isMultiviewEnabled","_projectionLayerInitialized","_compositionLayerTextureMapping","_layerToRTTProviderMapping","_layerCleanupFunctions","isMaxRenderLayersSupported","maxRenderLayers","_createWebGPUProjectionLayer","_glContext","projectionLayerInit","_xrMediaBinding","createXRWebGLLayer","_getProjectionLayerDimensions","projectionLayer","ownsNode","sourceOrientation","transformInfo","_createTransformNode","fallbackMode","factoryName","defaultViewPixelWidth","defaultViewPixelHeight","populatedParams","viewPixelWidth","viewPixelHeight","layerInit","_validateLayerInit","effectiveParams","gpuParams","textureUsage","mipLevels","copyWebGPUSpecificInit","gpuLayerInit","createWebGPULayer","createWebGLLayer","WebXRCubeLayerWrapper","WebXRCompositionLayerRenderTargetTextureProvider","rttProvider","XRMediaBinding","mediaBinding","_validateLayerCount","extendedParams","_extendXRLayerInit","projLayer","WebXRProjectionLayerWrapper","factorySupported","createQuadLayer","_createGraphicsLayer","webGLInit","webGPUInit","nativeLayer","_createFallbackLayer","createCylinderLayer","centralAngle","createEquirectLayer","centralHorizontalAngle","upperVerticalAngle","lowerVerticalAngle","createCubeLayer","_createMediaLayer","media","_createQuadLayer","babylonTexture","quadLayer","addFullscreenAdvancedDynamicTexture","distanceFromHeadset","babylonLayer","beforeRenderObservers","previousRenderOnlyInRenderTargetTextures","cleanedUp","renderTargetCreatedObserver","_addLensFlareSystem","flareSystem","wrappedLayer","setXRSessionLayers","removeLayer","removeXRSessionLayer","wrappedLayers","renderStateInit","isLayerTypeSupported","updateFromTransformNode","needsRedraw","WebXRLayers","_Registered$f","DEPTH_SENSING_TEXTURE_ARRAY","DEPTH_SENSING_TEXTURE_AL","DEPTH_SENSING_DISCARD","IsPluginEnabled","DepthTexture","DepthTextureRight","AlphaLuminanceTexture","ScreenSize","ShaderViewport","GlobalRawValueToMeters","GlobalRawValueToMetersRight","GlobalDepthAvailableLeft","GlobalDepthAvailableRight","GlobalWorldScale","ViewIndex","EnableDiscard","UvTransform","UvTransformRight","RightView","ManagedMaterialPlugins","DepthSensingMaterialDefines","_varColorName","WebXRDepthSensing","rawValueToMeters","_rawValueToMeters","normDepthBufferFromNormView","_normDepthBufferFromNormView","depthUsage","depthDataFormat","isDepthSensingActive","depthActive","pauseDepthSensing","resumeDepthSensing","latestInternalTexture","_getInternalTextureFromDepthInfo","latestDepthBuffer","_cachedDepthBuffer","latestDepthImageTexture","_cachedDepthImageTexture","_cachedWebGLTexture","_cachedDepthImageTextureWrapsExternalTexture","_cpuDepthViewStates","_disableAutoAttachBeforeWebGPUGPUDepth","_disabledForWebGPUGPUDepth","_onCameraObserver","_onSessionEndedObserver","onGetDepthInMetersAvailable","useToleranceFactorForDepthSensing","WebXRDepthSensingMaterialPlugin","_glBinding","disableDepthSensingOnMaterials","_bindCPUDepthView","viewState","cachedTextureDisposed","referenceSPace","_updateDepthInformationAndTextureCPUDepthUsage","_updateDepthInformationAndTextureWebGLDepthUsage","_clearCPUDepthBinding","depthInfo","getDepthInformation","uvTransform","visualizationDepthBuffer","dataFormat","getDepthInMeters","prepareTextureForVisualization","hadDepthTexture","leftViewState","rightViewState","webglBinding","isDepthUsageDeclared","usagePreference","dataFormatPreference","isDataFormatDeclared","depthSensing","_Registered$e","_WebGPUUnavailableWarning","XRSpaceWarpRenderTarget","motionVectorTexture","_originalPairing","_previousWorldMatrices","_previousTransforms","_velocityMaterial","tuple","motionVectorTextureWidth","motionVectorTextureHeight","WebXRSpaceWarp","spaceWarpRTTProvider","WebXRSpaceWarpRenderTargetTextureProvider","_onAfterRender","accessMotionVector","_Registered$d","name$H","name$G","includes$j","WebXRRawCameraAccess","_cachedInternalTextures","texturesData","cameraIntrinsics","onTexturesUpdatedObservable","_updateCameraIntrinsics","u0","ax","ay","getCameraImage","_updateInternalTextures","_Registered$c","WebXRBodyJoint","BodyJointNameToIndex","BodyJointReferenceArray","BODY_JOINT_COUNT","BodyPart","MixamoRigMapping","hips","neck","MixamoAimChildOverrides","_ResolveMixamoRigMapping","bodyMesh","WebXRTrackedBody","_bodyMesh","jointScaleFactor","jointTransforms","getBodyPartTransforms","joints","BodyPartsDefinition","preserveBindPoseBonePositions","useBoneOrientationOffsets","aimChildOverrides","jointLocalRotationOffset","onBodyMeshSetObservable","_jointTransformMatricesRHS","_desiredFinalPositions","_bindLocalTwistNormals","_boneTwistReferenceJointIdx","_bindBoneWorldRotMeshLocal","_hasTrackedBind","_tempDeltaQuat","_tempBoneWorldRot","_tempParentNewWorldRotInv","_tempTrackedCurRot","_tempTrackedCurPos","_tempBindLocalScale","_tempBindLocalPos","_computedBoneNewWorldRotFrameId","_tempTwistFirst","_tempTwistSecond","_tempTwistNormal","_tempCurrentTwistNormal","_tempProjectedTwistNormal","_tempProjectedDesiredTwistNormal","_tempTwistAimAxis","_initialSkinMatrixInverse","_desiredFinals","_tempOffsetAppliedMatrix","_directSkinWrite","_lastDebugInfo","_preserveBindPoseBonePositions","_useBoneOrientationOffsets","setBodyMesh","_bodyMeshRoot","_jointHasBone","_jointParentJointIdx","_boneToJointIdx","_mappedBoneBindLocals","_mappedChildBones","_bindLocalAimDirections","_boneAimTargetJointIdx","_computedBoneNewWorldRot","_trackedBindDesiredFinalRot","_trackedBindDesiredFinalPos","standaloneNode","_unmappedBoneNodes","_skeletonMesh","skeletonMesh","bindPoseFinals","boneIdx","findMappedChildBone","bindWorldPositions","bindWorldRotations","bindFinal","_tempScaleVector","_tempRotQuat","_tempPosVec","findBestUnmappedDescendantForJoint","targetJointName","bestDescendant","lname","selfJointIdx","selfJointName","overrideTargetJointName","_aimChildOverrides","overrideTargetJointIdx","overrideBoneName","overrideBoneIdx","boneBindPos","childBindPos","bindWorldRotation","_tempDirection","_tempRotQuat2","_tempLocalDirection","HandTwistReferenceJoints","twistReferences","firstIdx","secondIdx","descBindFinal","firstDescendant","secondDescendant","firstBindFinal","secondBindFinal","_storeBindLocalTwistNormalFromPositions","autoChild","pIdx","xrCameraParent","anyBody","validSpaceCount","fillPosesError","getPoseCount","getPoseNullCount","anyJointTracked","replayRawJointMatrices","rawMatrices","isAlreadyLhs","_processTrackedJointMatrices","_jointLocalRotationOffsetMatrix","skipRhsToLhs","_meshWorldMatrixInverse","useInitialSkinMatrix","targetIdx","_tempLocalMatrix","autoCaptureBindOnFirstFrame","_captureTrackedBindFromDesiredFinals","_retargetDirect","computedWorldRotations","skinMatrices","clearTrackedBind","_computeNormalFromJointPositions","aimAxisResult","aimTarget","_tempTwistCross","bindWorldRot","_retargetDeltaFromBind","_currentRetargetFrameId","bindBoneWorldRot","bindLocalAim","bindLocalTwistNormal","_projectOnPlaneToRef","pooled","parentNewWorldRot","directMapped","_tempParentAccumRot","_tempParentAccumTmp","bindLocal","bindTrackedPos","_tempParentMatrix","bindLocalAimDirection","childJointIdx","parentWorldRotation","snapshotFrame","jointMatricesRHS","jointMatricesLHS","jointHasBone","jointParentJointIdx","jointNames","clipboard","writeText","WebXRBodyTracking","trackedBody","_trackedBody","isTracking","_isTracking","onBodyTrackingStartedObservable","onBodyTrackingEndedObservable","onBodyTrackingFrameUpdateObservable","_lastFrameDebugInfo","isMixamoModel","AllBodyJoints","snapshotFrameToClipboardAsync","_Registered$b","WebXRTrackedSources","_trackedSources","_trackedSourcesSession","onTrackedSourceAddedObservable","onTrackedSourceRemovedObservable","_onTrackedSourcesChanged","_synchronizeTrackedSources","trackedSources","IsTrackedSourcesSession","trackedSource","nativeTrackedSource","isStillTracked","_Registered$a","WebXRGenericHandController","GenericHandSelectGraspProfile","grasp","_Registered$9","defaultButton","unpressedNodeName","pressedNodeName","defaultAxis","labelAnchorNodeName","WebXRMicrosoftMixedRealityController","MODEL_LEFT_FILENAME","MODEL_RIGHT_FILENAME","MODEL_BASE_URL","buttonMap","_mapping","buttonMeshName","buttonMesh","_getImmediateChildByName","pressedMesh","unpressedMesh","comp","axisArray","axisMesh","axisValues","xr_standard_trigger_pressed","xr_standard_squeeze_pressed","xr_standard_touchpad_pressed","xr_standard_touchpad_xaxis_pressed","xr_standard_touchpad_yaxis_pressed","xr_standard_touchpad_xaxis_touched","xr_standard_touchpad_yaxis_touched","xr_standard_touchpad_axes_touched","xr_standard_thumbstick_pressed","xr_standard_thumbstick_xaxis_pressed","xr_standard_thumbstick_yaxis_pressed","_Registered$8","WebXROculusTouchMotionController","_legacyMapping","_forceLegacyControllers","OculusTouchLayouts","_isQuest","QUEST_MODEL_BASE_URL","isQuest","triggerDirection","_modelRootNode","thumbrest","_Registered$7","WebXROculusHandController","OculusHandProfile","menu","_Registered$6","WebXRHTCViveMotionController","HTCViveLayout","MODEL_FILENAME","_Registered$5","NativeXRFrame","_nativeImpl","_xrTransform","_xrPose","emulatedPosition","_xrPoseVectorData","getHitTestResultsForTransientInput","_imageTrackingResults","baseSpace","getPoseData","_Registered$4","RegisterNativeTypeAsync","GlobalObject","RegisterMathColor","RegisterMathVector","BABYLONGLOBAL","Debug","DebugImport","BABYLON$1","RegisterLegacyGlobal","BABYLON.PhysicsViewer","name$F","shader$F","name$E","shader$E","name$D","shader$D","includes$i","name$C","shader$C","includes$h","name$B","shader$B","includes$g","gaussianSplattingFragmentDeclaration","name$A","shader$A","includes$f","name$z","shader$z","includes$e","name$y","shader$y","includes$d","name$x","shader$x","includes$c","name$w","shader$w","FlowGraphPointerDownEventBlock","_Registered$3","FlowGraphPointerUpEventBlock","_Registered$2","FlowGraphPointerMoveEventBlock","_Registered$1","FlowGraphDebugBlock","_logValue","formatted","_FormatValue","name$v","shader$v","shader$u","name$u","name$t","shader$t","includes$b","name$s","shader$s","includes$a","name$r","shader$r","name$q","shader$q","includes$9","name$p","shader$p","includes$8","name$o","shader$o","name$n","shader$n","name$m","shader$m","name$l","shader$l","name$k","shader$k","name$j","shader$j","name$i","shader$i","includes$7","name$h","shader$h","includes$6","name$g","shader$g","includes$5","name$f","shader$f","includes$4","name$e","shader$e","name$d","shader$d","name$c","shader$c","name$b","shader$b","name$a","shader$a","name$9","shader$9","name$8","shader$8","name$7","shader$7","includes$3","name$6","shader$6","includes$2","name$5","shader$5","shader$4","name$4","name$3","shader$3","includes$1","fibonacciWGSL","diffusionProfileWGSL","name$2","shader$2","shader$1","name$1","fibonacci","diffusionProfile"],"mappings":"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ClBA,GAAkB,KAClBA,GAAkB,6CAClBA,GAAkB,uCAClBA,GAAkB,6CAClBA,GAAkB,KAClBA,GAAkB,6CAClBA,GAAkB,uCAClBA,GAAkB,6CAClBA,GAAkB,KAClBA,GAAkB,6CAClBA,GAAkB,uCAClBA,GAAkB,6CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,oEAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,mDAClBA,GAAkB,4CAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,uCAClBA,GAAkB,yCAClBA,GAAkB,yCAClBA,GAAkB,KAClBA,GAAkB,8DAClBA,GAAkB,8DAClBA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AA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,MAAA,KAAA,QACAA,EAAAA,EAAA,MAAA,KAAA,QACAA,EAAAA,EAAA,MAAA,KAAA,QACAA,EAAAA,EAAA,MAAA,KAAA,QACAA,EAAAA,EAAA,MAAA,KAAA,QACAA,EAAAA,EAAA,MAAA,KAAA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","x_google_ignoreList":[22]}